From 85e103ff570031f7b957481d62458032750839db Mon Sep 17 00:00:00 2001 From: plumedbot Date: Thu, 22 Feb 2024 21:58:57 +0000 Subject: [PATCH] Update to plumed/plumed2@9cb8ceb --- .nojekyll | 0 README.md | 12 + coverage-libs/amber.png | Bin 0 -> 141 bytes .../asmjit/arch.cpp.func-sort-c.html | 81 + coverage-libs/asmjit/arch.cpp.func.html | 81 + coverage-libs/asmjit/arch.cpp.gcov.html | 264 + coverage-libs/asmjit/arch.h.func-sort-c.html | 73 + coverage-libs/asmjit/arch.h.func.html | 73 + coverage-libs/asmjit/arch.h.gcov.html | 305 + .../asmjit/assembler.cpp.func-sort-c.html | 145 + coverage-libs/asmjit/assembler.cpp.func.html | 145 + coverage-libs/asmjit/assembler.cpp.gcov.html | 550 + .../asmjit/assembler.h.func-sort-c.html | 73 + coverage-libs/asmjit/assembler.h.func.html | 73 + coverage-libs/asmjit/assembler.h.gcov.html | 260 + .../asmjit/codebuilder.cpp.func-sort-c.html | 205 + .../asmjit/codebuilder.cpp.func.html | 205 + .../asmjit/codebuilder.cpp.gcov.html | 687 + .../asmjit/codebuilder.h.func-sort-c.html | 73 + coverage-libs/asmjit/codebuilder.h.func.html | 73 + coverage-libs/asmjit/codebuilder.h.gcov.html | 1021 + .../asmjit/codecompiler.cpp.func-sort-c.html | 217 + .../asmjit/codecompiler.cpp.func.html | 217 + .../asmjit/codecompiler.cpp.gcov.html | 676 + .../asmjit/codecompiler.h.func-sort-c.html | 73 + coverage-libs/asmjit/codecompiler.h.func.html | 73 + coverage-libs/asmjit/codecompiler.h.gcov.html | 844 + .../asmjit/codeemitter.cpp.func-sort-c.html | 197 + .../asmjit/codeemitter.cpp.func.html | 197 + .../asmjit/codeemitter.cpp.gcov.html | 339 + .../asmjit/codeemitter.h.func-sort-c.html | 73 + coverage-libs/asmjit/codeemitter.h.func.html | 73 + coverage-libs/asmjit/codeemitter.h.gcov.html | 605 + .../asmjit/codeholder.cpp.func-sort-c.html | 173 + coverage-libs/asmjit/codeholder.cpp.func.html | 173 + coverage-libs/asmjit/codeholder.cpp.gcov.html | 800 + .../asmjit/codeholder.h.func-sort-c.html | 73 + coverage-libs/asmjit/codeholder.h.func.html | 73 + coverage-libs/asmjit/codeholder.h.gcov.html | 854 + .../asmjit/constpool.cpp.func-sort-c.html | 105 + coverage-libs/asmjit/constpool.cpp.func.html | 105 + coverage-libs/asmjit/constpool.cpp.gcov.html | 614 + .../asmjit/constpool.h.func-sort-c.html | 73 + coverage-libs/asmjit/constpool.h.func.html | 73 + coverage-libs/asmjit/constpool.h.gcov.html | 363 + .../asmjit/cpuinfo.cpp.func-sort-c.html | 85 + coverage-libs/asmjit/cpuinfo.cpp.func.html | 85 + coverage-libs/asmjit/cpuinfo.cpp.gcov.html | 777 + .../asmjit/cpuinfo.h.func-sort-c.html | 73 + coverage-libs/asmjit/cpuinfo.h.func.html | 73 + coverage-libs/asmjit/cpuinfo.h.gcov.html | 479 + .../asmjit/func.cpp.func-sort-c.html | 101 + coverage-libs/asmjit/func.cpp.func.html | 101 + coverage-libs/asmjit/func.cpp.gcov.html | 289 + coverage-libs/asmjit/func.h.func-sort-c.html | 73 + coverage-libs/asmjit/func.h.func.html | 73 + coverage-libs/asmjit/func.h.gcov.html | 1404 + .../asmjit/globals.cpp.func-sort-c.html | 85 + coverage-libs/asmjit/globals.cpp.func.html | 85 + coverage-libs/asmjit/globals.cpp.gcov.html | 221 + .../asmjit/globals.h.func-sort-c.html | 73 + coverage-libs/asmjit/globals.h.func.html | 73 + coverage-libs/asmjit/globals.h.gcov.html | 447 + coverage-libs/asmjit/index-sort-f.html | 604 + coverage-libs/asmjit/index-sort-l.html | 604 + coverage-libs/asmjit/index.html | 604 + .../asmjit/inst.cpp.func-sort-c.html | 81 + coverage-libs/asmjit/inst.cpp.func.html | 81 + coverage-libs/asmjit/inst.cpp.gcov.html | 180 + coverage-libs/asmjit/inst.h.func-sort-c.html | 73 + coverage-libs/asmjit/inst.h.func.html | 73 + coverage-libs/asmjit/inst.h.gcov.html | 214 + .../asmjit/logging.cpp.func-sort-c.html | 173 + coverage-libs/asmjit/logging.cpp.func.html | 173 + coverage-libs/asmjit/logging.cpp.gcov.html | 601 + .../asmjit/logging.h.func-sort-c.html | 73 + coverage-libs/asmjit/logging.h.func.html | 73 + coverage-libs/asmjit/logging.h.gcov.html | 394 + .../asmjit/moved_string.h.func-sort-c.html | 73 + coverage-libs/asmjit/moved_string.h.func.html | 73 + coverage-libs/asmjit/moved_string.h.gcov.html | 395 + .../asmjit/operand.h.func-sort-c.html | 73 + coverage-libs/asmjit/operand.h.func.html | 73 + coverage-libs/asmjit/operand.h.gcov.html | 1676 + .../asmjit/osutils.cpp.func-sort-c.html | 93 + coverage-libs/asmjit/osutils.cpp.func.html | 93 + coverage-libs/asmjit/osutils.cpp.gcov.html | 331 + .../asmjit/osutils.h.func-sort-c.html | 73 + coverage-libs/asmjit/osutils.h.func.html | 73 + coverage-libs/asmjit/osutils.h.gcov.html | 284 + .../asmjit/regalloc.cpp.func-sort-c.html | 125 + coverage-libs/asmjit/regalloc.cpp.func.html | 125 + coverage-libs/asmjit/regalloc.cpp.gcov.html | 697 + .../asmjit/regalloc_p.h.func-sort-c.html | 73 + coverage-libs/asmjit/regalloc_p.h.func.html | 73 + coverage-libs/asmjit/regalloc_p.h.gcov.html | 674 + .../asmjit/runtime.cpp.func-sort-c.html | 121 + coverage-libs/asmjit/runtime.cpp.func.html | 121 + coverage-libs/asmjit/runtime.cpp.gcov.html | 250 + .../asmjit/runtime.h.func-sort-c.html | 73 + coverage-libs/asmjit/runtime.h.func.html | 73 + coverage-libs/asmjit/runtime.h.gcov.html | 304 + .../asmjit/string.cpp.func-sort-c.html | 129 + coverage-libs/asmjit/string.cpp.func.html | 129 + coverage-libs/asmjit/string.cpp.gcov.html | 456 + coverage-libs/asmjit/utils.h.func-sort-c.html | 73 + coverage-libs/asmjit/utils.h.func.html | 73 + coverage-libs/asmjit/utils.h.gcov.html | 1464 + .../asmjit/vmem.cpp.func-sort-c.html | 129 + coverage-libs/asmjit/vmem.cpp.func.html | 129 + coverage-libs/asmjit/vmem.cpp.gcov.html | 1180 + .../asmjit/x86assembler.cpp.func-sort-c.html | 101 + .../asmjit/x86assembler.cpp.func.html | 101 + .../asmjit/x86assembler.cpp.gcov.html | 4722 +++ .../asmjit/x86assembler.h.func-sort-c.html | 73 + coverage-libs/asmjit/x86assembler.h.func.html | 73 + coverage-libs/asmjit/x86assembler.h.gcov.html | 202 + .../asmjit/x86builder.cpp.func-sort-c.html | 93 + coverage-libs/asmjit/x86builder.cpp.func.html | 93 + coverage-libs/asmjit/x86builder.cpp.gcov.html | 169 + .../asmjit/x86compiler.cpp.func-sort-c.html | 101 + .../asmjit/x86compiler.cpp.func.html | 101 + .../asmjit/x86compiler.cpp.gcov.html | 479 + .../asmjit/x86compiler.h.func-sort-c.html | 81 + coverage-libs/asmjit/x86compiler.h.func.html | 81 + coverage-libs/asmjit/x86compiler.h.gcov.html | 399 + .../asmjit/x86emitter.h.func-sort-c.html | 73 + coverage-libs/asmjit/x86emitter.h.func.html | 73 + coverage-libs/asmjit/x86emitter.h.gcov.html | 5226 +++ .../asmjit/x86inst.cpp.func-sort-c.html | 81 + coverage-libs/asmjit/x86inst.cpp.func.html | 81 + coverage-libs/asmjit/x86inst.cpp.gcov.html | 3830 ++ .../asmjit/x86inst.h.func-sort-c.html | 73 + coverage-libs/asmjit/x86inst.h.func.html | 73 + coverage-libs/asmjit/x86inst.h.gcov.html | 2624 ++ .../asmjit/x86instimpl.cpp.func-sort-c.html | 85 + .../asmjit/x86instimpl.cpp.func.html | 85 + .../asmjit/x86instimpl.cpp.gcov.html | 834 + .../asmjit/x86internal.cpp.func-sort-c.html | 129 + .../asmjit/x86internal.cpp.func.html | 129 + .../asmjit/x86internal.cpp.gcov.html | 1459 + .../asmjit/x86logging.cpp.func-sort-c.html | 105 + coverage-libs/asmjit/x86logging.cpp.func.html | 105 + coverage-libs/asmjit/x86logging.cpp.gcov.html | 787 + .../asmjit/x86misc.h.func-sort-c.html | 73 + coverage-libs/asmjit/x86misc.h.func.html | 73 + coverage-libs/asmjit/x86misc.h.gcov.html | 494 + .../asmjit/x86operand.h.func-sort-c.html | 73 + coverage-libs/asmjit/x86operand.h.func.html | 73 + coverage-libs/asmjit/x86operand.h.gcov.html | 1210 + .../asmjit/x86regalloc.cpp.func-sort-c.html | 189 + .../asmjit/x86regalloc.cpp.func.html | 189 + .../asmjit/x86regalloc.cpp.gcov.html | 4165 +++ .../asmjit/x86regalloc_p.h.func-sort-c.html | 73 + .../asmjit/x86regalloc_p.h.func.html | 73 + .../asmjit/x86regalloc_p.h.gcov.html | 811 + .../asmjit/zone.cpp.func-sort-c.html | 161 + coverage-libs/asmjit/zone.cpp.func.html | 161 + coverage-libs/asmjit/zone.cpp.gcov.html | 936 + coverage-libs/asmjit/zone.h.func-sort-c.html | 81 + coverage-libs/asmjit/zone.h.func.html | 81 + coverage-libs/asmjit/zone.h.gcov.html | 1234 + coverage-libs/blas/blas.cpp.func-sort-c.html | 217 + coverage-libs/blas/blas.cpp.func.html | 217 + coverage-libs/blas/blas.cpp.gcov.html | 3767 ++ coverage-libs/blas/index-sort-f.html | 94 + coverage-libs/blas/index-sort-l.html | 94 + coverage-libs/blas/index.html | 94 + coverage-libs/emerald.png | Bin 0 -> 141 bytes coverage-libs/gcov.css | 519 + coverage-libs/glass.png | Bin 0 -> 167 bytes coverage-libs/index-sort-f.html | 144 + coverage-libs/index-sort-l.html | 144 + coverage-libs/index.html | 144 + coverage-libs/lapack/index-sort-f.html | 94 + coverage-libs/lapack/index-sort-l.html | 94 + coverage-libs/lapack/index.html | 94 + .../lapack/lapack.cpp.func-sort-c.html | 797 + coverage-libs/lapack/lapack.cpp.func.html | 797 + coverage-libs/lapack/lapack.cpp.gcov.html | 31100 ++++++++++++++++ .../CompiledExpression.cpp.func-sort-c.html | 149 + .../lepton/CompiledExpression.cpp.func.html | 149 + .../lepton/CompiledExpression.cpp.gcov.html | 586 + .../CompiledExpression.h.func-sort-c.html | 73 + .../lepton/CompiledExpression.h.func.html | 73 + .../lepton/CompiledExpression.h.gcov.html | 241 + .../lepton/Exception.h.func-sort-c.html | 89 + coverage-libs/lepton/Exception.h.func.html | 89 + coverage-libs/lepton/Exception.h.gcov.html | 170 + .../ExpressionProgram.cpp.func-sort-c.html | 121 + .../lepton/ExpressionProgram.cpp.func.html | 121 + .../lepton/ExpressionProgram.cpp.gcov.html | 221 + .../ExpressionTreeNode.cpp.func-sort-c.html | 133 + .../lepton/ExpressionTreeNode.cpp.func.html | 133 + .../lepton/ExpressionTreeNode.cpp.gcov.html | 264 + .../lepton/Operation.cpp.func-sort-c.html | 301 + coverage-libs/lepton/Operation.cpp.func.html | 301 + coverage-libs/lepton/Operation.cpp.gcov.html | 747 + .../lepton/Operation.h.func-sort-c.html | 1233 + coverage-libs/lepton/Operation.h.func.html | 1233 + coverage-libs/lepton/Operation.h.gcov.html | 1379 + .../ParsedExpression.cpp.func-sort-c.html | 157 + .../lepton/ParsedExpression.cpp.func.html | 157 + .../lepton/ParsedExpression.cpp.gcov.html | 528 + .../ParsedExpression.h.func-sort-c.html | 73 + .../lepton/ParsedExpression.h.func.html | 73 + .../lepton/ParsedExpression.h.gcov.html | 242 + .../lepton/Parser.cpp.func-sort-c.html | 113 + coverage-libs/lepton/Parser.cpp.func.html | 113 + coverage-libs/lepton/Parser.cpp.gcov.html | 585 + coverage-libs/lepton/index-sort-f.html | 184 + coverage-libs/lepton/index-sort-l.html | 184 + coverage-libs/lepton/index.html | 184 + .../molfile/Gromacs.h.func-sort-c.html | 217 + coverage-libs/molfile/Gromacs.h.func.html | 217 + coverage-libs/molfile/Gromacs.h.gcov.html | 2090 ++ .../molfile/crdplugin.cpp.func-sort-c.html | 109 + coverage-libs/molfile/crdplugin.cpp.func.html | 109 + coverage-libs/molfile/crdplugin.cpp.gcov.html | 339 + .../molfile/dcdplugin.cpp.func-sort-c.html | 149 + coverage-libs/molfile/dcdplugin.cpp.func.html | 149 + coverage-libs/molfile/dcdplugin.cpp.gcov.html | 1394 + .../molfile/endianswap.h.func-sort-c.html | 89 + coverage-libs/molfile/endianswap.h.func.html | 89 + coverage-libs/molfile/endianswap.h.gcov.html | 294 + .../molfile/fastio.h.func-sort-c.html | 101 + coverage-libs/molfile/fastio.h.func.html | 101 + coverage-libs/molfile/fastio.h.gcov.html | 760 + .../gromacsplugin.cpp.func-sort-c.html | 165 + .../molfile/gromacsplugin.cpp.func.html | 165 + .../molfile/gromacsplugin.cpp.gcov.html | 937 + coverage-libs/molfile/index-sort-f.html | 174 + coverage-libs/molfile/index-sort-l.html | 174 + coverage-libs/molfile/index.html | 174 + .../molfile/pdbplugin.cpp.func-sort-c.html | 129 + coverage-libs/molfile/pdbplugin.cpp.func.html | 129 + coverage-libs/molfile/pdbplugin.cpp.gcov.html | 725 + .../molfile/periodic_table.h.func-sort-c.html | 89 + .../molfile/periodic_table.h.func.html | 89 + .../molfile/periodic_table.h.gcov.html | 325 + .../molfile/readpdb.h.func-sort-c.html | 105 + coverage-libs/molfile/readpdb.h.func.html | 105 + coverage-libs/molfile/readpdb.h.gcov.html | 524 + coverage-libs/ruby.png | Bin 0 -> 141 bytes coverage-libs/snow.png | Bin 0 -> 141 bytes coverage-libs/updown.png | Bin 0 -> 117 bytes coverage-libs/xdrfile/index-sort-f.html | 114 + coverage-libs/xdrfile/index-sort-l.html | 114 + coverage-libs/xdrfile/index.html | 114 + .../xdrfile/xdrfile.cpp.func-sort-c.html | 397 + coverage-libs/xdrfile/xdrfile.cpp.func.html | 397 + coverage-libs/xdrfile/xdrfile.cpp.gcov.html | 2725 ++ .../xdrfile/xdrfile_trr.cpp.func-sort-c.html | 101 + .../xdrfile/xdrfile_trr.cpp.func.html | 101 + .../xdrfile/xdrfile_trr.cpp.gcov.html | 606 + .../xdrfile/xdrfile_xtc.cpp.func-sort-c.html | 93 + .../xdrfile/xdrfile_xtc.cpp.func.html | 93 + .../xdrfile/xdrfile_xtc.cpp.gcov.html | 242 + ...ActionWithInputMatrix.cpp.func-sort-c.html | 137 + .../ActionWithInputMatrix.cpp.func.html | 137 + .../ActionWithInputMatrix.cpp.gcov.html | 231 + .../ActionWithInputMatrix.h.func-sort-c.html | 81 + .../adjmat/ActionWithInputMatrix.h.func.html | 81 + .../adjmat/ActionWithInputMatrix.h.gcov.html | 149 + .../AdjacencyMatrixBase.cpp.func-sort-c.html | 117 + .../adjmat/AdjacencyMatrixBase.cpp.func.html | 117 + .../adjmat/AdjacencyMatrixBase.cpp.gcov.html | 274 + .../AdjacencyMatrixBase.h.func-sort-c.html | 81 + .../adjmat/AdjacencyMatrixBase.h.func.html | 81 + .../adjmat/AdjacencyMatrixBase.h.gcov.html | 182 + ...AdjacencyMatrixVessel.cpp.func-sort-c.html | 133 + .../AdjacencyMatrixVessel.cpp.func.html | 133 + .../AdjacencyMatrixVessel.cpp.gcov.html | 231 + .../AlignedMatrixBase.cpp.func-sort-c.html | 97 + .../adjmat/AlignedMatrixBase.cpp.func.html | 97 + .../adjmat/AlignedMatrixBase.cpp.gcov.html | 194 + .../ClusterAnalysisBase.cpp.func-sort-c.html | 133 + .../adjmat/ClusterAnalysisBase.cpp.func.html | 133 + .../adjmat/ClusterAnalysisBase.cpp.gcov.html | 183 + .../ClusterAnalysisBase.h.func-sort-c.html | 77 + .../adjmat/ClusterAnalysisBase.h.func.html | 77 + .../adjmat/ClusterAnalysisBase.h.gcov.html | 137 + .../ClusterDiameter.cpp.func-sort-c.html | 97 + coverage/adjmat/ClusterDiameter.cpp.func.html | 97 + coverage/adjmat/ClusterDiameter.cpp.gcov.html | 207 + .../ClusterDistribution.cpp.func-sort-c.html | 93 + .../adjmat/ClusterDistribution.cpp.func.html | 93 + .../adjmat/ClusterDistribution.cpp.gcov.html | 237 + .../ClusterProperties.cpp.func-sort-c.html | 93 + .../adjmat/ClusterProperties.cpp.func.html | 93 + .../adjmat/ClusterProperties.cpp.gcov.html | 198 + .../adjmat/ClusterSize.cpp.func-sort-c.html | 97 + coverage/adjmat/ClusterSize.cpp.func.html | 97 + coverage/adjmat/ClusterSize.cpp.gcov.html | 190 + .../ClusterWithSurface.cpp.func-sort-c.html | 125 + .../adjmat/ClusterWithSurface.cpp.func.html | 125 + .../adjmat/ClusterWithSurface.cpp.gcov.html | 270 + .../ClusteringBase.cpp.func-sort-c.html | 105 + coverage/adjmat/ClusteringBase.cpp.func.html | 105 + coverage/adjmat/ClusteringBase.cpp.gcov.html | 160 + .../adjmat/ClusteringBase.h.func-sort-c.html | 77 + coverage/adjmat/ClusteringBase.h.func.html | 77 + coverage/adjmat/ClusteringBase.h.gcov.html | 147 + .../ContactAlignedMatrix.cpp.func-sort-c.html | 93 + .../adjmat/ContactAlignedMatrix.cpp.func.html | 93 + .../adjmat/ContactAlignedMatrix.cpp.gcov.html | 200 + .../adjmat/ContactMatrix.cpp.func-sort-c.html | 97 + coverage/adjmat/ContactMatrix.cpp.func.html | 97 + coverage/adjmat/ContactMatrix.cpp.gcov.html | 227 + .../adjmat/DFSClustering.cpp.func-sort-c.html | 93 + coverage/adjmat/DFSClustering.cpp.func.html | 93 + coverage/adjmat/DFSClustering.cpp.gcov.html | 238 + .../adjmat/DumpGraph.cpp.func-sort-c.html | 97 + coverage/adjmat/DumpGraph.cpp.func.html | 97 + coverage/adjmat/DumpGraph.cpp.gcov.html | 191 + .../adjmat/HbondMatrix.cpp.func-sort-c.html | 101 + coverage/adjmat/HbondMatrix.cpp.func.html | 101 + coverage/adjmat/HbondMatrix.cpp.gcov.html | 309 + .../MatrixColumnSums.cpp.func-sort-c.html | 89 + .../adjmat/MatrixColumnSums.cpp.func.html | 89 + .../adjmat/MatrixColumnSums.cpp.gcov.html | 199 + .../adjmat/MatrixRowSums.cpp.func-sort-c.html | 89 + coverage/adjmat/MatrixRowSums.cpp.func.html | 89 + coverage/adjmat/MatrixRowSums.cpp.gcov.html | 185 + .../adjmat/OutputCluster.cpp.func-sort-c.html | 105 + coverage/adjmat/OutputCluster.cpp.func.html | 105 + coverage/adjmat/OutputCluster.cpp.gcov.html | 310 + .../adjmat/SMACMatrix.cpp.func-sort-c.html | 93 + coverage/adjmat/SMACMatrix.cpp.func.html | 93 + coverage/adjmat/SMACMatrix.cpp.gcov.html | 232 + coverage/adjmat/Sprint.cpp.func-sort-c.html | 93 + coverage/adjmat/Sprint.cpp.func.html | 93 + coverage/adjmat/Sprint.cpp.gcov.html | 306 + .../TopologyMatrix.cpp.func-sort-c.html | 105 + coverage/adjmat/TopologyMatrix.cpp.func.html | 105 + coverage/adjmat/TopologyMatrix.cpp.gcov.html | 401 + coverage/adjmat/index-sort-f.html | 344 + coverage/adjmat/index-sort-l.html | 344 + coverage/adjmat/index.html | 344 + coverage/amber.png | Bin 0 -> 141 bytes .../AnalysisBase.cpp.func-sort-c.html | 97 + coverage/analysis/AnalysisBase.cpp.func.html | 97 + coverage/analysis/AnalysisBase.cpp.gcov.html | 159 + .../analysis/AnalysisBase.h.func-sort-c.html | 149 + coverage/analysis/AnalysisBase.h.func.html | 149 + coverage/analysis/AnalysisBase.h.gcov.html | 257 + .../analysis/Average.cpp.func-sort-c.html | 113 + coverage/analysis/Average.cpp.func.html | 113 + coverage/analysis/Average.cpp.gcov.html | 227 + .../AverageVessel.cpp.func-sort-c.html | 97 + coverage/analysis/AverageVessel.cpp.func.html | 97 + coverage/analysis/AverageVessel.cpp.gcov.html | 140 + .../analysis/AverageVessel.h.func-sort-c.html | 77 + coverage/analysis/AverageVessel.h.func.html | 77 + coverage/analysis/AverageVessel.h.gcov.html | 128 + .../analysis/Committor.cpp.func-sort-c.html | 93 + coverage/analysis/Committor.cpp.func.html | 93 + coverage/analysis/Committor.cpp.gcov.html | 268 + .../DataCollectionObject.cpp.func-sort-c.html | 89 + .../DataCollectionObject.cpp.func.html | 89 + .../DataCollectionObject.cpp.gcov.html | 140 + .../DataCollectionObject.h.func-sort-c.html | 77 + .../analysis/DataCollectionObject.h.func.html | 77 + .../analysis/DataCollectionObject.h.gcov.html | 156 + ...anDissimilarityMatrix.cpp.func-sort-c.html | 105 + ...EuclideanDissimilarityMatrix.cpp.func.html | 105 + ...EuclideanDissimilarityMatrix.cpp.gcov.html | 223 + ...FarthestPointSampling.cpp.func-sort-c.html | 89 + .../FarthestPointSampling.cpp.func.html | 89 + .../FarthestPointSampling.cpp.gcov.html | 168 + .../analysis/Histogram.cpp.func-sort-c.html | 125 + coverage/analysis/Histogram.cpp.func.html | 125 + coverage/analysis/Histogram.cpp.gcov.html | 612 + ...LandmarkSelectionBase.cpp.func-sort-c.html | 97 + .../LandmarkSelectionBase.cpp.func.html | 97 + .../LandmarkSelectionBase.cpp.gcov.html | 163 + .../LandmarkSelectionBase.h.func-sort-c.html | 97 + .../LandmarkSelectionBase.h.func.html | 97 + .../LandmarkSelectionBase.h.gcov.html | 170 + .../LandmarkStaged.cpp.func-sort-c.html | 89 + .../analysis/LandmarkStaged.cpp.func.html | 89 + .../analysis/LandmarkStaged.cpp.gcov.html | 212 + .../OutputColvarFile.cpp.func-sort-c.html | 93 + .../analysis/OutputColvarFile.cpp.func.html | 93 + .../analysis/OutputColvarFile.cpp.gcov.html | 203 + .../OutputPDBFile.cpp.func-sort-c.html | 93 + coverage/analysis/OutputPDBFile.cpp.func.html | 93 + coverage/analysis/OutputPDBFile.cpp.gcov.html | 176 + ...ntDissimilarityMatrix.cpp.func-sort-c.html | 93 + .../PrintDissimilarityMatrix.cpp.func.html | 93 + .../PrintDissimilarityMatrix.cpp.gcov.html | 159 + .../ReadAnalysisFrames.cpp.func-sort-c.html | 105 + .../analysis/ReadAnalysisFrames.cpp.func.html | 105 + .../analysis/ReadAnalysisFrames.cpp.gcov.html | 233 + .../ReadAnalysisFrames.h.func-sort-c.html | 101 + .../analysis/ReadAnalysisFrames.h.func.html | 101 + .../analysis/ReadAnalysisFrames.h.gcov.html | 183 + ...adDissimilarityMatrix.cpp.func-sort-c.html | 125 + .../ReadDissimilarityMatrix.cpp.func.html | 125 + .../ReadDissimilarityMatrix.cpp.gcov.html | 244 + .../ReselectLandmarks.cpp.func-sort-c.html | 89 + .../analysis/ReselectLandmarks.cpp.func.html | 89 + .../analysis/ReselectLandmarks.cpp.gcov.html | 151 + .../SelectRandomFrames.cpp.func-sort-c.html | 89 + .../analysis/SelectRandomFrames.cpp.func.html | 89 + .../analysis/SelectRandomFrames.cpp.gcov.html | 157 + .../SelectWithStride.cpp.func-sort-c.html | 89 + .../analysis/SelectWithStride.cpp.func.html | 89 + .../analysis/SelectWithStride.cpp.gcov.html | 139 + .../WhamHistogram.cpp.func-sort-c.html | 85 + coverage/analysis/WhamHistogram.cpp.func.html | 85 + coverage/analysis/WhamHistogram.cpp.gcov.html | 199 + .../analysis/WhamWeights.cpp.func-sort-c.html | 85 + coverage/analysis/WhamWeights.cpp.func.html | 85 + coverage/analysis/WhamWeights.cpp.gcov.html | 184 + coverage/analysis/index-sort-f.html | 334 + coverage/analysis/index-sort-l.html | 334 + coverage/analysis/index.html | 334 + coverage/annfunc/ANN.cpp.func-sort-c.html | 97 + coverage/annfunc/ANN.cpp.func.html | 97 + coverage/annfunc/ANN.cpp.gcov.html | 474 + coverage/annfunc/index-sort-f.html | 94 + coverage/annfunc/index-sort-l.html | 94 + coverage/annfunc/index.html | 94 + coverage/bias/ABMD.cpp.func-sort-c.html | 89 + coverage/bias/ABMD.cpp.func.html | 89 + coverage/bias/ABMD.cpp.gcov.html | 263 + coverage/bias/Bias.cpp.func-sort-c.html | 89 + coverage/bias/Bias.cpp.func.html | 89 + coverage/bias/Bias.cpp.gcov.html | 170 + coverage/bias/Bias.h.func-sort-c.html | 85 + coverage/bias/Bias.h.func.html | 85 + coverage/bias/Bias.h.gcov.html | 160 + coverage/bias/BiasValue.cpp.func-sort-c.html | 89 + coverage/bias/BiasValue.cpp.func.html | 89 + coverage/bias/BiasValue.cpp.gcov.html | 194 + .../ExtendedLagrangian.cpp.func-sort-c.html | 93 + .../bias/ExtendedLagrangian.cpp.func.html | 93 + .../bias/ExtendedLagrangian.cpp.gcov.html | 339 + coverage/bias/External.cpp.func-sort-c.html | 89 + coverage/bias/External.cpp.func.html | 89 + coverage/bias/External.cpp.gcov.html | 257 + coverage/bias/LWalls.cpp.func-sort-c.html | 89 + coverage/bias/LWalls.cpp.func.html | 89 + coverage/bias/LWalls.cpp.gcov.html | 225 + coverage/bias/MaxEnt.cpp.func-sort-c.html | 117 + coverage/bias/MaxEnt.cpp.func.html | 117 + coverage/bias/MaxEnt.cpp.gcov.html | 561 + coverage/bias/MetaD.cpp.func-sort-c.html | 185 + coverage/bias/MetaD.cpp.func.html | 185 + coverage/bias/MetaD.cpp.gcov.html | 2381 ++ .../bias/MovingRestraint.cpp.func-sort-c.html | 89 + coverage/bias/MovingRestraint.cpp.func.html | 89 + coverage/bias/MovingRestraint.cpp.gcov.html | 343 + coverage/bias/PBMetaD.cpp.func-sort-c.html | 133 + coverage/bias/PBMetaD.cpp.func.html | 133 + coverage/bias/PBMetaD.cpp.gcov.html | 1391 + coverage/bias/Restraint.cpp.func-sort-c.html | 89 + coverage/bias/Restraint.cpp.func.html | 89 + coverage/bias/Restraint.cpp.gcov.html | 204 + .../bias/ReweightBase.cpp.func-sort-c.html | 89 + coverage/bias/ReweightBase.cpp.func.html | 89 + coverage/bias/ReweightBase.cpp.gcov.html | 130 + coverage/bias/ReweightBase.h.func-sort-c.html | 97 + coverage/bias/ReweightBase.h.func.html | 97 + coverage/bias/ReweightBase.h.gcov.html | 130 + .../bias/ReweightBias.cpp.func-sort-c.html | 89 + coverage/bias/ReweightBias.cpp.func.html | 89 + coverage/bias/ReweightBias.cpp.gcov.html | 175 + .../bias/ReweightMetad.cpp.func-sort-c.html | 89 + coverage/bias/ReweightMetad.cpp.func.html | 89 + coverage/bias/ReweightMetad.cpp.gcov.html | 172 + ...htTemperaturePressure.cpp.func-sort-c.html | 89 + .../ReweightTemperaturePressure.cpp.func.html | 89 + .../ReweightTemperaturePressure.cpp.gcov.html | 341 + .../bias/ReweightWham.cpp.func-sort-c.html | 105 + coverage/bias/ReweightWham.cpp.func.html | 105 + coverage/bias/ReweightWham.cpp.gcov.html | 254 + coverage/bias/UWalls.cpp.func-sort-c.html | 89 + coverage/bias/UWalls.cpp.func.html | 89 + coverage/bias/UWalls.cpp.gcov.html | 224 + coverage/bias/index-sort-f.html | 274 + coverage/bias/index-sort-l.html | 274 + coverage/bias/index.html | 274 + .../cltools/Benchmark.cpp.func-sort-c.html | 113 + coverage/cltools/Benchmark.cpp.func.html | 113 + coverage/cltools/Benchmark.cpp.gcov.html | 270 + .../cltools/Completion.cpp.func-sort-c.html | 101 + coverage/cltools/Completion.cpp.func.html | 101 + coverage/cltools/Completion.cpp.gcov.html | 212 + coverage/cltools/Driver.cpp.func-sort-c.html | 121 + coverage/cltools/Driver.cpp.func.html | 121 + coverage/cltools/Driver.cpp.gcov.html | 1256 + .../cltools/DriverDouble.cpp.func-sort-c.html | 85 + coverage/cltools/DriverDouble.cpp.func.html | 85 + coverage/cltools/DriverDouble.cpp.gcov.html | 114 + .../cltools/DriverFloat.cpp.func-sort-c.html | 89 + coverage/cltools/DriverFloat.cpp.func.html | 89 + coverage/cltools/DriverFloat.cpp.gcov.html | 119 + .../cltools/GenExample.cpp.func-sort-c.html | 109 + coverage/cltools/GenExample.cpp.func.html | 109 + coverage/cltools/GenExample.cpp.gcov.html | 428 + coverage/cltools/GenJson.cpp.func-sort-c.html | 101 + coverage/cltools/GenJson.cpp.func.html | 101 + coverage/cltools/GenJson.cpp.gcov.html | 257 + .../cltools/GenTemplate.cpp.func-sort-c.html | 101 + coverage/cltools/GenTemplate.cpp.func.html | 101 + coverage/cltools/GenTemplate.cpp.gcov.html | 179 + coverage/cltools/Info.cpp.func-sort-c.html | 101 + coverage/cltools/Info.cpp.func.html | 101 + coverage/cltools/Info.cpp.gcov.html | 200 + coverage/cltools/Manual.cpp.func-sort-c.html | 101 + coverage/cltools/Manual.cpp.func.html | 101 + coverage/cltools/Manual.cpp.gcov.html | 178 + .../cltools/PdbRenumber.cpp.func-sort-c.html | 101 + coverage/cltools/PdbRenumber.cpp.func.html | 101 + coverage/cltools/PdbRenumber.cpp.gcov.html | 275 + .../cltools/SimpleMD.cpp.func-sort-c.html | 153 + coverage/cltools/SimpleMD.cpp.func.html | 153 + coverage/cltools/SimpleMD.cpp.gcov.html | 685 + .../cltools/SumHills.cpp.func-sort-c.html | 105 + coverage/cltools/SumHills.cpp.func.html | 105 + coverage/cltools/SumHills.cpp.gcov.html | 702 + coverage/cltools/index-sort-f.html | 234 + coverage/cltools/index-sort-l.html | 234 + coverage/cltools/index.html | 234 + coverage/cltools/kT.cpp.func-sort-c.html | 101 + coverage/cltools/kT.cpp.func.html | 101 + coverage/cltools/kT.cpp.gcov.html | 164 + coverage/cltools/pesmd.cpp.func-sort-c.html | 101 + coverage/cltools/pesmd.cpp.func.html | 101 + coverage/cltools/pesmd.cpp.gcov.html | 389 + coverage/colvar/Angle.cpp.func-sort-c.html | 89 + coverage/colvar/Angle.cpp.func.html | 89 + coverage/colvar/Angle.cpp.gcov.html | 225 + coverage/colvar/Cell.cpp.func-sort-c.html | 89 + coverage/colvar/Cell.cpp.func.html | 89 + coverage/colvar/Cell.cpp.gcov.html | 186 + coverage/colvar/Constant.cpp.func-sort-c.html | 89 + coverage/colvar/Constant.cpp.func.html | 89 + coverage/colvar/Constant.cpp.gcov.html | 209 + .../colvar/ContactMap.cpp.func-sort-c.html | 93 + coverage/colvar/ContactMap.cpp.func.html | 93 + coverage/colvar/ContactMap.cpp.gcov.html | 404 + .../colvar/Coordination.cpp.func-sort-c.html | 89 + coverage/colvar/Coordination.cpp.func.html | 89 + coverage/colvar/Coordination.cpp.gcov.html | 231 + .../CoordinationBase.cpp.func-sort-c.html | 105 + .../colvar/CoordinationBase.cpp.func.html | 105 + .../colvar/CoordinationBase.cpp.gcov.html | 284 + coverage/colvar/DHEnergy.cpp.func-sort-c.html | 89 + coverage/colvar/DHEnergy.cpp.func.html | 89 + coverage/colvar/DHEnergy.cpp.gcov.html | 220 + coverage/colvar/DRMSD.cpp.func-sort-c.html | 89 + coverage/colvar/DRMSD.cpp.func.html | 89 + coverage/colvar/DRMSD.cpp.gcov.html | 269 + coverage/colvar/Dimer.cpp.func-sort-c.html | 93 + coverage/colvar/Dimer.cpp.func.html | 93 + coverage/colvar/Dimer.cpp.gcov.html | 395 + coverage/colvar/Dipole.cpp.func-sort-c.html | 89 + coverage/colvar/Dipole.cpp.func.html | 89 + coverage/colvar/Dipole.cpp.gcov.html | 235 + coverage/colvar/Distance.cpp.func-sort-c.html | 89 + coverage/colvar/Distance.cpp.func.html | 89 + coverage/colvar/Distance.cpp.gcov.html | 306 + coverage/colvar/EEFSolv.cpp.func-sort-c.html | 105 + coverage/colvar/EEFSolv.cpp.func.html | 105 + coverage/colvar/EEFSolv.cpp.gcov.html | 1254 + coverage/colvar/ERMSD.cpp.func-sort-c.html | 89 + coverage/colvar/ERMSD.cpp.func.html | 89 + coverage/colvar/ERMSD.cpp.gcov.html | 291 + coverage/colvar/Energy.cpp.func-sort-c.html | 93 + coverage/colvar/Energy.cpp.func.html | 93 + coverage/colvar/Energy.cpp.gcov.html | 202 + coverage/colvar/ExtraCV.cpp.func-sort-c.html | 85 + coverage/colvar/ExtraCV.cpp.func.html | 85 + coverage/colvar/ExtraCV.cpp.gcov.html | 155 + coverage/colvar/Fake.cpp.func-sort-c.html | 89 + coverage/colvar/Fake.cpp.func.html | 89 + coverage/colvar/Fake.cpp.gcov.html | 200 + coverage/colvar/GHBFIX.cpp.func-sort-c.html | 89 + coverage/colvar/GHBFIX.cpp.func.html | 89 + coverage/colvar/GHBFIX.cpp.gcov.html | 294 + coverage/colvar/Gyration.cpp.func-sort-c.html | 89 + coverage/colvar/Gyration.cpp.func.html | 89 + coverage/colvar/Gyration.cpp.gcov.html | 447 + .../colvar/MultiRMSD.cpp.func-sort-c.html | 89 + coverage/colvar/MultiRMSD.cpp.func.html | 89 + coverage/colvar/MultiRMSD.cpp.gcov.html | 286 + coverage/colvar/PCARMSD.cpp.func-sort-c.html | 93 + coverage/colvar/PCARMSD.cpp.func.html | 93 + coverage/colvar/PCARMSD.cpp.gcov.html | 343 + coverage/colvar/PathMSD.cpp.func-sort-c.html | 85 + coverage/colvar/PathMSD.cpp.func.html | 85 + coverage/colvar/PathMSD.cpp.gcov.html | 206 + .../colvar/PathMSDBase.cpp.func-sort-c.html | 105 + coverage/colvar/PathMSDBase.cpp.func.html | 105 + coverage/colvar/PathMSDBase.cpp.gcov.html | 414 + .../colvar/PathMSDBase.h.func-sort-c.html | 73 + coverage/colvar/PathMSDBase.h.func.html | 73 + coverage/colvar/PathMSDBase.h.gcov.html | 178 + coverage/colvar/Position.cpp.func-sort-c.html | 89 + coverage/colvar/Position.cpp.func.html | 89 + coverage/colvar/Position.cpp.gcov.html | 254 + .../ProjectionOnAxis.cpp.func-sort-c.html | 89 + .../colvar/ProjectionOnAxis.cpp.func.html | 89 + .../colvar/ProjectionOnAxis.cpp.gcov.html | 246 + .../colvar/PropertyMap.cpp.func-sort-c.html | 85 + coverage/colvar/PropertyMap.cpp.func.html | 85 + coverage/colvar/PropertyMap.cpp.gcov.html | 229 + .../colvar/Puckering.cpp.func-sort-c.html | 97 + coverage/colvar/Puckering.cpp.func.html | 97 + coverage/colvar/Puckering.cpp.gcov.html | 497 + coverage/colvar/RMSD.cpp.func-sort-c.html | 89 + coverage/colvar/RMSD.cpp.func.html | 89 + coverage/colvar/RMSD.cpp.gcov.html | 314 + coverage/colvar/Template.cpp.func-sort-c.html | 89 + coverage/colvar/Template.cpp.func.html | 89 + coverage/colvar/Template.cpp.gcov.html | 191 + coverage/colvar/Torsion.cpp.func-sort-c.html | 89 + coverage/colvar/Torsion.cpp.func.html | 89 + coverage/colvar/Torsion.cpp.gcov.html | 272 + coverage/colvar/Volume.cpp.func-sort-c.html | 89 + coverage/colvar/Volume.cpp.func.html | 89 + coverage/colvar/Volume.cpp.gcov.html | 162 + coverage/colvar/index-sort-f.html | 394 + coverage/colvar/index-sort-l.html | 394 + coverage/colvar/index.html | 394 + coverage/config/Config.inc.func-sort-c.html | 173 + coverage/config/Config.inc.func.html | 173 + coverage/config/Config.inc.gcov.html | 273 + .../config/ConfigInstall.inc.func-sort-c.html | 173 + coverage/config/ConfigInstall.inc.func.html | 173 + coverage/config/ConfigInstall.inc.gcov.html | 273 + coverage/config/index-sort-f.html | 104 + coverage/config/index-sort-l.html | 104 + coverage/config/index.html | 104 + coverage/core/Action.cpp.func-sort-c.html | 217 + coverage/core/Action.cpp.func.html | 217 + coverage/core/Action.cpp.gcov.html | 422 + coverage/core/Action.h.func-sort-c.html | 221 + coverage/core/Action.h.func.html | 221 + coverage/core/Action.h.gcov.html | 563 + .../core/ActionAnyorder.cpp.func-sort-c.html | 85 + coverage/core/ActionAnyorder.cpp.func.html | 85 + coverage/core/ActionAnyorder.cpp.gcov.html | 115 + .../core/ActionAnyorder.h.func-sort-c.html | 81 + coverage/core/ActionAnyorder.h.func.html | 81 + coverage/core/ActionAnyorder.h.gcov.html | 125 + .../core/ActionAtomistic.cpp.func-sort-c.html | 173 + coverage/core/ActionAtomistic.cpp.func.html | 173 + coverage/core/ActionAtomistic.cpp.gcov.html | 437 + .../core/ActionAtomistic.h.func-sort-c.html | 109 + coverage/core/ActionAtomistic.h.func.html | 109 + coverage/core/ActionAtomistic.h.gcov.html | 373 + .../ActionForInterface.cpp.func-sort-c.html | 89 + .../core/ActionForInterface.cpp.func.html | 89 + .../core/ActionForInterface.cpp.gcov.html | 126 + .../ActionForInterface.h.func-sort-c.html | 101 + coverage/core/ActionForInterface.h.func.html | 101 + coverage/core/ActionForInterface.h.gcov.html | 167 + .../core/ActionPilot.cpp.func-sort-c.html | 97 + coverage/core/ActionPilot.cpp.func.html | 97 + coverage/core/ActionPilot.cpp.gcov.html | 132 + coverage/core/ActionPilot.h.func-sort-c.html | 73 + coverage/core/ActionPilot.h.func.html | 73 + coverage/core/ActionPilot.h.gcov.html | 135 + .../core/ActionRegister.cpp.func-sort-c.html | 117 + coverage/core/ActionRegister.cpp.func.html | 117 + coverage/core/ActionRegister.cpp.gcov.html | 219 + .../core/ActionRegister.h.func-sort-c.html | 3433 ++ coverage/core/ActionRegister.h.func.html | 3433 ++ coverage/core/ActionRegister.h.gcov.html | 209 + coverage/core/ActionSet.cpp.func-sort-c.html | 85 + coverage/core/ActionSet.cpp.func.html | 85 + coverage/core/ActionSet.cpp.gcov.html | 119 + coverage/core/ActionSet.h.func-sort-c.html | 209 + coverage/core/ActionSet.h.func.html | 209 + coverage/core/ActionSet.h.gcov.html | 224 + .../core/ActionSetup.cpp.func-sort-c.html | 85 + coverage/core/ActionSetup.cpp.func.html | 85 + coverage/core/ActionSetup.cpp.gcov.html | 125 + coverage/core/ActionSetup.h.func-sort-c.html | 81 + coverage/core/ActionSetup.h.func.html | 81 + coverage/core/ActionSetup.h.gcov.html | 125 + .../core/ActionShortcut.cpp.func-sort-c.html | 97 + coverage/core/ActionShortcut.cpp.func.html | 97 + coverage/core/ActionShortcut.cpp.gcov.html | 144 + .../core/ActionShortcut.h.func-sort-c.html | 85 + coverage/core/ActionShortcut.h.func.html | 85 + coverage/core/ActionShortcut.h.gcov.html | 133 + .../core/ActionToGetData.cpp.func-sort-c.html | 101 + coverage/core/ActionToGetData.cpp.func.html | 101 + coverage/core/ActionToGetData.cpp.gcov.html | 160 + .../core/ActionToGetData.h.func-sort-c.html | 81 + coverage/core/ActionToGetData.h.func.html | 81 + coverage/core/ActionToGetData.h.gcov.html | 135 + .../core/ActionToPutData.cpp.func-sort-c.html | 141 + coverage/core/ActionToPutData.cpp.func.html | 141 + coverage/core/ActionToPutData.cpp.gcov.html | 258 + .../core/ActionToPutData.h.func-sort-c.html | 97 + coverage/core/ActionToPutData.h.func.html | 97 + coverage/core/ActionToPutData.h.gcov.html | 173 + .../ActionWithArguments.cpp.func-sort-c.html | 129 + .../core/ActionWithArguments.cpp.func.html | 129 + .../core/ActionWithArguments.cpp.gcov.html | 400 + .../ActionWithArguments.h.func-sort-c.html | 97 + coverage/core/ActionWithArguments.h.func.html | 97 + coverage/core/ActionWithArguments.h.gcov.html | 214 + .../core/ActionWithValue.cpp.func-sort-c.html | 193 + coverage/core/ActionWithValue.cpp.func.html | 193 + coverage/core/ActionWithValue.cpp.gcov.html | 363 + .../core/ActionWithValue.h.func-sort-c.html | 105 + coverage/core/ActionWithValue.h.func.html | 105 + coverage/core/ActionWithValue.h.gcov.html | 320 + ...ActionWithVirtualAtom.cpp.func-sort-c.html | 101 + .../core/ActionWithVirtualAtom.cpp.func.html | 101 + .../core/ActionWithVirtualAtom.cpp.gcov.html | 193 + .../ActionWithVirtualAtom.h.func-sort-c.html | 97 + .../core/ActionWithVirtualAtom.h.func.html | 97 + .../core/ActionWithVirtualAtom.h.gcov.html | 197 + coverage/core/CLTool.cpp.func-sort-c.html | 113 + coverage/core/CLTool.cpp.func.html | 113 + coverage/core/CLTool.cpp.gcov.html | 293 + coverage/core/CLTool.h.func-sort-c.html | 133 + coverage/core/CLTool.h.func.html | 133 + coverage/core/CLTool.h.gcov.html | 242 + coverage/core/CLToolMain.cpp.func-sort-c.html | 93 + coverage/core/CLToolMain.cpp.func.html | 93 + coverage/core/CLToolMain.cpp.gcov.html | 368 + .../core/CLToolRegister.cpp.func-sort-c.html | 113 + coverage/core/CLToolRegister.cpp.func.html | 113 + coverage/core/CLToolRegister.cpp.gcov.html | 202 + coverage/core/Colvar.cpp.func-sort-c.html | 97 + coverage/core/Colvar.cpp.func.html | 97 + coverage/core/Colvar.cpp.gcov.html | 143 + coverage/core/Colvar.h.func-sort-c.html | 89 + coverage/core/Colvar.h.func.html | 89 + coverage/core/Colvar.h.gcov.html | 193 + .../DataPassingObject.cpp.func-sort-c.html | 189 + coverage/core/DataPassingObject.cpp.func.html | 189 + coverage/core/DataPassingObject.cpp.gcov.html | 271 + .../core/DataPassingObject.h.func-sort-c.html | 73 + coverage/core/DataPassingObject.h.func.html | 73 + coverage/core/DataPassingObject.h.gcov.html | 163 + .../DataPassingTools.cpp.func-sort-c.html | 105 + coverage/core/DataPassingTools.cpp.func.html | 105 + coverage/core/DataPassingTools.cpp.gcov.html | 149 + .../core/DataPassingTools.h.func-sort-c.html | 81 + coverage/core/DataPassingTools.h.func.html | 81 + coverage/core/DataPassingTools.h.gcov.html | 131 + .../DomainDecomposition.cpp.func-sort-c.html | 205 + .../core/DomainDecomposition.cpp.func.html | 205 + .../core/DomainDecomposition.cpp.gcov.html | 553 + .../DomainDecomposition.h.func-sort-c.html | 85 + coverage/core/DomainDecomposition.h.func.html | 85 + coverage/core/DomainDecomposition.h.gcov.html | 189 + .../ExchangePatterns.cpp.func-sort-c.html | 101 + coverage/core/ExchangePatterns.cpp.func.html | 101 + coverage/core/ExchangePatterns.cpp.gcov.html | 149 + .../core/FlexibleBin.cpp.func-sort-c.html | 101 + coverage/core/FlexibleBin.cpp.func.html | 101 + coverage/core/FlexibleBin.cpp.gcov.html | 413 + coverage/core/GREX.cpp.func-sort-c.html | 97 + coverage/core/GREX.cpp.func.html | 97 + coverage/core/GREX.cpp.gcov.html | 292 + .../core/GenericMolInfo.cpp.func-sort-c.html | 145 + coverage/core/GenericMolInfo.cpp.func.html | 145 + coverage/core/GenericMolInfo.cpp.gcov.html | 445 + .../core/GenericMolInfo.h.func-sort-c.html | 81 + coverage/core/GenericMolInfo.h.func.html | 81 + coverage/core/GenericMolInfo.h.gcov.html | 163 + coverage/core/Group.cpp.func-sort-c.html | 89 + coverage/core/Group.cpp.func.html | 89 + coverage/core/Group.cpp.gcov.html | 315 + coverage/core/Group.h.func-sort-c.html | 81 + coverage/core/Group.h.func.html | 81 + coverage/core/Group.h.gcov.html | 118 + coverage/core/PbcAction.cpp.func-sort-c.html | 97 + coverage/core/PbcAction.cpp.func.html | 97 + coverage/core/PbcAction.cpp.gcov.html | 157 + coverage/core/PbcAction.h.func-sort-c.html | 77 + coverage/core/PbcAction.h.func.html | 77 + coverage/core/PbcAction.h.gcov.html | 136 + coverage/core/PlumedMain.cpp.func-sort-c.html | 301 + coverage/core/PlumedMain.cpp.func.html | 301 + coverage/core/PlumedMain.cpp.gcov.html | 1492 + coverage/core/PlumedMain.h.func-sort-c.html | 73 + coverage/core/PlumedMain.h.func.html | 73 + coverage/core/PlumedMain.h.gcov.html | 654 + ...PlumedMainInitializer.cpp.func-sort-c.html | 137 + .../core/PlumedMainInitializer.cpp.func.html | 137 + .../core/PlumedMainInitializer.cpp.gcov.html | 567 + coverage/core/TargetDist.cpp.func-sort-c.html | 85 + coverage/core/TargetDist.cpp.func.html | 85 + coverage/core/TargetDist.cpp.gcov.html | 148 + coverage/core/Value.cpp.func-sort-c.html | 169 + coverage/core/Value.cpp.func.html | 169 + coverage/core/Value.cpp.gcov.html | 313 + coverage/core/Value.h.func-sort-c.html | 109 + coverage/core/Value.h.func.html | 109 + coverage/core/Value.h.gcov.html | 476 + coverage/core/WithCmd.h.func-sort-c.html | 97 + coverage/core/WithCmd.h.func.html | 97 + coverage/core/WithCmd.h.gcov.html | 144 + coverage/core/index-sort-f.html | 644 + coverage/core/index-sort-l.html | 644 + coverage/core/index.html | 644 + .../BondOrientation.cpp.func-sort-c.html | 93 + .../BondOrientation.cpp.func.html | 93 + .../BondOrientation.cpp.gcov.html | 212 + .../CubicHarmonicBase.cpp.func-sort-c.html | 89 + .../CubicHarmonicBase.cpp.func.html | 89 + .../CubicHarmonicBase.cpp.gcov.html | 227 + .../CubicHarmonicBase.h.func-sort-c.html | 77 + .../CubicHarmonicBase.h.func.html | 77 + .../CubicHarmonicBase.h.gcov.html | 128 + ...EnvironmentSimilarity.cpp.func-sort-c.html | 101 + .../EnvironmentSimilarity.cpp.func.html | 101 + .../EnvironmentSimilarity.cpp.gcov.html | 645 + .../Fccubic.cpp.func-sort-c.html | 89 + .../crystallization/Fccubic.cpp.func.html | 89 + .../crystallization/Fccubic.cpp.gcov.html | 210 + .../Gradient.cpp.func-sort-c.html | 93 + .../crystallization/Gradient.cpp.func.html | 93 + .../crystallization/Gradient.cpp.gcov.html | 244 + .../Gradient.h.func-sort-c.html | 77 + coverage/crystallization/Gradient.h.func.html | 77 + coverage/crystallization/Gradient.h.gcov.html | 136 + .../GradientVessel.cpp.func-sort-c.html | 113 + .../GradientVessel.cpp.func.html | 113 + .../GradientVessel.cpp.gcov.html | 269 + ...nterMolecularTorsions.cpp.func-sort-c.html | 101 + .../InterMolecularTorsions.cpp.func.html | 101 + .../InterMolecularTorsions.cpp.gcov.html | 270 + .../LocalSteinhardt.h.func-sort-c.html | 109 + .../LocalSteinhardt.h.func.html | 109 + .../LocalSteinhardt.h.gcov.html | 139 + .../MoleculeOrientation.cpp.func-sort-c.html | 101 + .../MoleculeOrientation.cpp.func.html | 101 + .../MoleculeOrientation.cpp.gcov.html | 228 + .../MoleculePlane.cpp.func-sort-c.html | 93 + .../MoleculePlane.cpp.func.html | 93 + .../MoleculePlane.cpp.gcov.html | 227 + .../OrientationSphere.cpp.func-sort-c.html | 89 + .../OrientationSphere.cpp.func.html | 89 + .../OrientationSphere.cpp.gcov.html | 208 + .../OrientationSphere.h.func-sort-c.html | 81 + .../OrientationSphere.h.func.html | 81 + .../OrientationSphere.h.gcov.html | 130 + .../PolymerAngles.cpp.func-sort-c.html | 89 + .../PolymerAngles.cpp.func.html | 89 + .../PolymerAngles.cpp.gcov.html | 179 + .../crystallization/Q3.cpp.func-sort-c.html | 85 + coverage/crystallization/Q3.cpp.func.html | 85 + coverage/crystallization/Q3.cpp.gcov.html | 300 + .../crystallization/Q4.cpp.func-sort-c.html | 85 + coverage/crystallization/Q4.cpp.func.html | 85 + coverage/crystallization/Q4.cpp.gcov.html | 292 + .../crystallization/Q6.cpp.func-sort-c.html | 85 + coverage/crystallization/Q6.cpp.func.html | 85 + coverage/crystallization/Q6.cpp.gcov.html | 295 + .../crystallization/SMAC.cpp.func-sort-c.html | 93 + coverage/crystallization/SMAC.cpp.func.html | 93 + coverage/crystallization/SMAC.cpp.gcov.html | 284 + .../SimpleCubic.cpp.func-sort-c.html | 89 + .../crystallization/SimpleCubic.cpp.func.html | 89 + .../crystallization/SimpleCubic.cpp.gcov.html | 193 + .../Steinhardt.cpp.func-sort-c.html | 97 + .../crystallization/Steinhardt.cpp.func.html | 97 + .../crystallization/Steinhardt.cpp.gcov.html | 252 + .../Tetrahedral.cpp.func-sort-c.html | 89 + .../crystallization/Tetrahedral.cpp.func.html | 89 + .../crystallization/Tetrahedral.cpp.gcov.html | 204 + .../VectorMean.cpp.func-sort-c.html | 113 + .../crystallization/VectorMean.cpp.func.html | 113 + .../crystallization/VectorMean.cpp.gcov.html | 190 + .../VectorMultiColvar.cpp.func-sort-c.html | 109 + .../VectorMultiColvar.cpp.func.html | 109 + .../VectorMultiColvar.cpp.gcov.html | 193 + .../VectorMultiColvar.h.func-sort-c.html | 89 + .../VectorMultiColvar.h.func.html | 89 + .../VectorMultiColvar.h.gcov.html | 162 + .../VectorSum.cpp.func-sort-c.html | 113 + .../crystallization/VectorSum.cpp.func.html | 113 + .../crystallization/VectorSum.cpp.gcov.html | 191 + coverage/crystallization/index-sort-f.html | 344 + coverage/crystallization/index-sort-l.html | 344 + coverage/crystallization/index.html | 344 + ...ltiDimensionalScaling.cpp.func-sort-c.html | 89 + ...sicalMultiDimensionalScaling.cpp.func.html | 89 + ...sicalMultiDimensionalScaling.cpp.gcov.html | 287 + ...ionalityReductionBase.cpp.func-sort-c.html | 101 + .../DimensionalityReductionBase.cpp.func.html | 101 + .../DimensionalityReductionBase.cpp.gcov.html | 212 + ...nsionalityReductionBase.h.func-sort-c.html | 81 + .../DimensionalityReductionBase.h.func.html | 81 + .../DimensionalityReductionBase.h.gcov.html | 151 + .../OutputPCAProjections.cpp.func-sort-c.html | 93 + .../dimred/OutputPCAProjections.cpp.func.html | 93 + .../dimred/OutputPCAProjections.cpp.gcov.html | 188 + coverage/dimred/PCA.cpp.func-sort-c.html | 97 + coverage/dimred/PCA.cpp.func.html | 97 + coverage/dimred/PCA.cpp.gcov.html | 355 + coverage/dimred/PCA.h.func-sort-c.html | 85 + coverage/dimred/PCA.h.func.html | 85 + coverage/dimred/PCA.h.gcov.html | 135 + ...jectNonLandmarkPoints.cpp.func-sort-c.html | 109 + .../ProjectNonLandmarkPoints.cpp.func.html | 109 + .../ProjectNonLandmarkPoints.cpp.gcov.html | 214 + coverage/dimred/SMACOF.cpp.func-sort-c.html | 81 + coverage/dimred/SMACOF.cpp.func.html | 81 + coverage/dimred/SMACOF.cpp.gcov.html | 170 + .../dimred/SketchMap.cpp.func-sort-c.html | 85 + coverage/dimred/SketchMap.cpp.func.html | 85 + coverage/dimred/SketchMap.cpp.gcov.html | 182 + .../dimred/SketchMapBase.cpp.func-sort-c.html | 97 + coverage/dimred/SketchMapBase.cpp.func.html | 97 + coverage/dimred/SketchMapBase.cpp.gcov.html | 243 + .../dimred/SketchMapBase.h.func-sort-c.html | 85 + coverage/dimred/SketchMapBase.h.func.html | 85 + coverage/dimred/SketchMapBase.h.gcov.html | 170 + .../SketchMapConjGrad.cpp.func-sort-c.html | 89 + .../dimred/SketchMapConjGrad.cpp.func.html | 89 + .../dimred/SketchMapConjGrad.cpp.gcov.html | 147 + .../SketchMapPointwise.cpp.func-sort-c.html | 89 + .../dimred/SketchMapPointwise.cpp.func.html | 89 + .../dimred/SketchMapPointwise.cpp.gcov.html | 203 + .../dimred/SketchMapRead.cpp.func-sort-c.html | 117 + coverage/dimred/SketchMapRead.cpp.func.html | 117 + coverage/dimred/SketchMapRead.cpp.gcov.html | 273 + .../SketchMapSmacof.cpp.func-sort-c.html | 93 + coverage/dimred/SketchMapSmacof.cpp.func.html | 93 + coverage/dimred/SketchMapSmacof.cpp.gcov.html | 187 + .../dimred/SmacoffMDS.cpp.func-sort-c.html | 89 + coverage/dimred/SmacoffMDS.cpp.func.html | 89 + coverage/dimred/SmacoffMDS.cpp.gcov.html | 159 + coverage/dimred/index-sort-f.html | 244 + coverage/dimred/index-sort-l.html | 244 + coverage/dimred/index.html | 244 + coverage/drr/DRR.cpp.func-sort-c.html | 173 + coverage/drr/DRR.cpp.func.html | 173 + coverage/drr/DRR.cpp.gcov.html | 635 + coverage/drr/DRR.h.func-sort-c.html | 129 + coverage/drr/DRR.h.func.html | 129 + coverage/drr/DRR.h.gcov.html | 435 + ...cReferenceRestraining.cpp.func-sort-c.html | 109 + .../DynamicReferenceRestraining.cpp.func.html | 109 + .../DynamicReferenceRestraining.cpp.gcov.html | 969 + .../drr/colvar_UIestimator.h.func-sort-c.html | 209 + coverage/drr/colvar_UIestimator.h.func.html | 209 + coverage/drr/colvar_UIestimator.h.gcov.html | 932 + coverage/drr/drrtool.cpp.func-sort-c.html | 121 + coverage/drr/drrtool.cpp.func.html | 121 + coverage/drr/drrtool.cpp.gcov.html | 345 + coverage/drr/index-sort-f.html | 134 + coverage/drr/index-sort-l.html | 134 + coverage/drr/index.html | 134 + coverage/eds/EDS.cpp.func-sort-c.html | 153 + coverage/eds/EDS.cpp.func.html | 153 + coverage/eds/EDS.cpp.gcov.html | 1251 + coverage/eds/index-sort-f.html | 94 + coverage/eds/index-sort-l.html | 94 + coverage/eds/index.html | 94 + coverage/emerald.png | Bin 0 -> 141 bytes coverage/fisst/FISST.cpp.func-sort-c.html | 149 + coverage/fisst/FISST.cpp.func.html | 149 + coverage/fisst/FISST.cpp.gcov.html | 736 + coverage/fisst/index-sort-f.html | 104 + coverage/fisst/index-sort-l.html | 104 + coverage/fisst/index.html | 104 + .../legendre_rule_fast.cpp.func-sort-c.html | 101 + .../fisst/legendre_rule_fast.cpp.func.html | 101 + .../fisst/legendre_rule_fast.cpp.gcov.html | 642 + .../function/Combine.cpp.func-sort-c.html | 89 + coverage/function/Combine.cpp.func.html | 89 + coverage/function/Combine.cpp.gcov.html | 233 + coverage/function/Custom.cpp.func-sort-c.html | 89 + coverage/function/Custom.cpp.func.html | 89 + coverage/function/Custom.cpp.gcov.html | 375 + .../function/Ensemble.cpp.func-sort-c.html | 89 + coverage/function/Ensemble.cpp.func.html | 89 + coverage/function/Ensemble.cpp.gcov.html | 340 + .../FuncPathGeneral.cpp.func-sort-c.html | 97 + .../function/FuncPathGeneral.cpp.func.html | 97 + .../function/FuncPathGeneral.cpp.gcov.html | 418 + .../function/FuncPathMSD.cpp.func-sort-c.html | 93 + coverage/function/FuncPathMSD.cpp.func.html | 93 + coverage/function/FuncPathMSD.cpp.gcov.html | 445 + .../FuncSumHills.cpp.func-sort-c.html | 121 + coverage/function/FuncSumHills.cpp.func.html | 121 + coverage/function/FuncSumHills.cpp.gcov.html | 715 + .../function/Function.cpp.func-sort-c.html | 97 + coverage/function/Function.cpp.func.html | 97 + coverage/function/Function.cpp.gcov.html | 149 + coverage/function/Function.h.func-sort-c.html | 81 + coverage/function/Function.h.func.html | 81 + coverage/function/Function.h.gcov.html | 150 + .../LocalEnsemble.cpp.func-sort-c.html | 89 + coverage/function/LocalEnsemble.cpp.func.html | 89 + coverage/function/LocalEnsemble.cpp.gcov.html | 228 + .../function/Piecewise.cpp.func-sort-c.html | 89 + coverage/function/Piecewise.cpp.func.html | 89 + coverage/function/Piecewise.cpp.gcov.html | 235 + coverage/function/Sort.cpp.func-sort-c.html | 89 + coverage/function/Sort.cpp.func.html | 89 + coverage/function/Sort.cpp.gcov.html | 184 + coverage/function/Stats.cpp.func-sort-c.html | 89 + coverage/function/Stats.cpp.func.html | 89 + coverage/function/Stats.cpp.gcov.html | 316 + coverage/function/Target.cpp.func-sort-c.html | 89 + coverage/function/Target.cpp.func.html | 89 + coverage/function/Target.cpp.gcov.html | 236 + coverage/function/index-sort-f.html | 214 + coverage/function/index-sort-l.html | 214 + coverage/function/index.html | 214 + coverage/funnel/FPS.cpp.func-sort-c.html | 89 + coverage/funnel/FPS.cpp.func.html | 89 + coverage/funnel/FPS.cpp.gcov.html | 396 + coverage/funnel/Funnel.cpp.func-sort-c.html | 93 + coverage/funnel/Funnel.cpp.func.html | 93 + coverage/funnel/Funnel.cpp.gcov.html | 529 + coverage/funnel/index-sort-f.html | 104 + coverage/funnel/index-sort-l.html | 104 + coverage/funnel/index.html | 104 + coverage/gcov.css | 519 + coverage/generic/Debug.cpp.func-sort-c.html | 93 + coverage/generic/Debug.cpp.func.html | 93 + coverage/generic/Debug.cpp.gcov.html | 217 + .../generic/DumpAtoms.cpp.func-sort-c.html | 109 + coverage/generic/DumpAtoms.cpp.func.html | 109 + coverage/generic/DumpAtoms.cpp.gcov.html | 390 + .../DumpDerivatives.cpp.func-sort-c.html | 109 + .../generic/DumpDerivatives.cpp.func.html | 109 + .../generic/DumpDerivatives.cpp.gcov.html | 210 + .../generic/DumpForces.cpp.func-sort-c.html | 109 + coverage/generic/DumpForces.cpp.func.html | 109 + coverage/generic/DumpForces.cpp.gcov.html | 196 + .../DumpMassCharge.cpp.func-sort-c.html | 113 + coverage/generic/DumpMassCharge.cpp.func.html | 113 + coverage/generic/DumpMassCharge.cpp.gcov.html | 263 + .../DumpProjections.cpp.func-sort-c.html | 113 + .../generic/DumpProjections.cpp.func.html | 113 + .../generic/DumpProjections.cpp.gcov.html | 197 + .../EffectiveEnergyDrift.cpp.func-sort-c.html | 109 + .../EffectiveEnergyDrift.cpp.func.html | 109 + .../EffectiveEnergyDrift.cpp.gcov.html | 448 + .../generic/EndPlumed.cpp.func-sort-c.html | 89 + coverage/generic/EndPlumed.cpp.func.html | 89 + coverage/generic/EndPlumed.cpp.gcov.html | 157 + .../FitToTemplate.cpp.func-sort-c.html | 97 + coverage/generic/FitToTemplate.cpp.func.html | 97 + coverage/generic/FitToTemplate.cpp.gcov.html | 460 + coverage/generic/Flush.cpp.func-sort-c.html | 93 + coverage/generic/Flush.cpp.func.html | 93 + coverage/generic/Flush.cpp.gcov.html | 168 + coverage/generic/Include.cpp.func-sort-c.html | 93 + coverage/generic/Include.cpp.func.html | 93 + coverage/generic/Include.cpp.gcov.html | 256 + coverage/generic/Plumed.cpp.func-sort-c.html | 117 + coverage/generic/Plumed.cpp.func.html | 117 + coverage/generic/Plumed.cpp.gcov.html | 493 + coverage/generic/Print.cpp.func-sort-c.html | 113 + coverage/generic/Print.cpp.func.html | 113 + coverage/generic/Print.cpp.gcov.html | 257 + .../RandomExchanges.cpp.func-sort-c.html | 89 + .../generic/RandomExchanges.cpp.func.html | 89 + .../generic/RandomExchanges.cpp.gcov.html | 179 + coverage/generic/Read.cpp.func-sort-c.html | 117 + coverage/generic/Read.cpp.func.html | 117 + coverage/generic/Read.cpp.gcov.html | 332 + .../generic/ResetCell.cpp.func-sort-c.html | 93 + coverage/generic/ResetCell.cpp.func.html | 93 + coverage/generic/ResetCell.cpp.gcov.html | 284 + coverage/generic/Time.cpp.func-sort-c.html | 97 + coverage/generic/Time.cpp.func.html | 97 + coverage/generic/Time.cpp.gcov.html | 156 + .../generic/UpdateIf.cpp.func-sort-c.html | 113 + coverage/generic/UpdateIf.cpp.func.html | 113 + coverage/generic/UpdateIf.cpp.gcov.html | 235 + .../WholeMolecules.cpp.func-sort-c.html | 93 + coverage/generic/WholeMolecules.cpp.func.html | 93 + coverage/generic/WholeMolecules.cpp.gcov.html | 345 + .../generic/WrapAround.cpp.func-sort-c.html | 93 + coverage/generic/WrapAround.cpp.func.html | 93 + coverage/generic/WrapAround.cpp.gcov.html | 333 + coverage/generic/index-sort-f.html | 284 + coverage/generic/index-sort-l.html | 284 + coverage/generic/index.html | 284 + coverage/glass.png | Bin 0 -> 167 bytes .../ActionWithGrid.cpp.func-sort-c.html | 101 + .../gridtools/ActionWithGrid.cpp.func.html | 101 + .../gridtools/ActionWithGrid.cpp.gcov.html | 187 + .../ActionWithInputGrid.cpp.func-sort-c.html | 97 + .../ActionWithInputGrid.cpp.func.html | 97 + .../ActionWithInputGrid.cpp.gcov.html | 157 + .../ActionWithInputGrid.h.func-sort-c.html | 89 + .../gridtools/ActionWithInputGrid.h.func.html | 89 + .../gridtools/ActionWithInputGrid.h.gcov.html | 146 + .../ActionWithIntegral.cpp.func-sort-c.html | 93 + .../ActionWithIntegral.cpp.func.html | 93 + .../ActionWithIntegral.cpp.gcov.html | 139 + .../ActionWithIntegral.h.func-sort-c.html | 81 + .../gridtools/ActionWithIntegral.h.func.html | 81 + .../gridtools/ActionWithIntegral.h.gcov.html | 137 + .../AverageOnGrid.cpp.func-sort-c.html | 89 + .../gridtools/AverageOnGrid.cpp.func.html | 89 + .../gridtools/AverageOnGrid.cpp.gcov.html | 146 + .../AverageOnGrid.h.func-sort-c.html | 85 + coverage/gridtools/AverageOnGrid.h.func.html | 85 + coverage/gridtools/AverageOnGrid.h.gcov.html | 126 + .../ContourFindingBase.cpp.func-sort-c.html | 85 + .../ContourFindingBase.cpp.func.html | 85 + .../ContourFindingBase.cpp.gcov.html | 121 + .../ContourFindingBase.h.func-sort-c.html | 85 + .../gridtools/ContourFindingBase.h.func.html | 85 + .../gridtools/ContourFindingBase.h.gcov.html | 140 + .../ConvertToFES.cpp.func-sort-c.html | 121 + coverage/gridtools/ConvertToFES.cpp.func.html | 121 + coverage/gridtools/ConvertToFES.cpp.gcov.html | 220 + .../gridtools/DumpCube.cpp.func-sort-c.html | 89 + coverage/gridtools/DumpCube.cpp.func.html | 89 + coverage/gridtools/DumpCube.cpp.gcov.html | 202 + .../gridtools/DumpGrid.cpp.func-sort-c.html | 89 + coverage/gridtools/DumpGrid.cpp.func.html | 89 + coverage/gridtools/DumpGrid.cpp.gcov.html | 273 + .../FindContour.cpp.func-sort-c.html | 109 + coverage/gridtools/FindContour.cpp.func.html | 109 + coverage/gridtools/FindContour.cpp.gcov.html | 322 + .../FindContourSurface.cpp.func-sort-c.html | 109 + .../FindContourSurface.cpp.func.html | 109 + .../FindContourSurface.cpp.gcov.html | 340 + .../FindSphericalContour.cpp.func-sort-c.html | 93 + .../FindSphericalContour.cpp.func.html | 93 + .../FindSphericalContour.cpp.gcov.html | 261 + .../FourierTransform.cpp.func-sort-c.html | 101 + .../gridtools/FourierTransform.cpp.func.html | 101 + .../gridtools/FourierTransform.cpp.gcov.html | 329 + .../GridPrintingBase.cpp.func-sort-c.html | 93 + .../gridtools/GridPrintingBase.cpp.func.html | 93 + .../gridtools/GridPrintingBase.cpp.gcov.html | 182 + .../GridPrintingBase.h.func-sort-c.html | 81 + .../gridtools/GridPrintingBase.h.func.html | 81 + .../gridtools/GridPrintingBase.h.gcov.html | 127 + .../gridtools/GridSearch.h.func-sort-c.html | 81 + coverage/gridtools/GridSearch.h.func.html | 81 + coverage/gridtools/GridSearch.h.gcov.html | 187 + .../gridtools/GridToXYZ.cpp.func-sort-c.html | 89 + coverage/gridtools/GridToXYZ.cpp.func.html | 89 + coverage/gridtools/GridToXYZ.cpp.gcov.html | 185 + .../gridtools/GridVessel.cpp.func-sort-c.html | 229 + coverage/gridtools/GridVessel.cpp.func.html | 229 + coverage/gridtools/GridVessel.cpp.gcov.html | 603 + .../gridtools/GridVessel.h.func-sort-c.html | 105 + coverage/gridtools/GridVessel.h.func.html | 105 + coverage/gridtools/GridVessel.h.gcov.html | 364 + .../HistogramOnGrid.cpp.func-sort-c.html | 121 + .../gridtools/HistogramOnGrid.cpp.func.html | 121 + .../gridtools/HistogramOnGrid.cpp.gcov.html | 292 + .../HistogramOnGrid.h.func-sort-c.html | 77 + .../gridtools/HistogramOnGrid.h.func.html | 77 + .../gridtools/HistogramOnGrid.h.gcov.html | 148 + .../IntegrateGrid.cpp.func-sort-c.html | 89 + .../gridtools/IntegrateGrid.cpp.func.html | 89 + .../gridtools/IntegrateGrid.cpp.gcov.html | 139 + .../InterpolateGrid.cpp.func-sort-c.html | 97 + .../gridtools/InterpolateGrid.cpp.func.html | 97 + .../gridtools/InterpolateGrid.cpp.gcov.html | 188 + coverage/gridtools/index-sort-f.html | 344 + coverage/gridtools/index-sort-l.html | 344 + coverage/gridtools/index.html | 344 + coverage/index-sort-f.html | 484 + coverage/index-sort-l.html | 484 + coverage/index.html | 484 + .../isdb/CS2Backbone.cpp.func-sort-c.html | 165 + coverage/isdb/CS2Backbone.cpp.func.html | 165 + coverage/isdb/CS2Backbone.cpp.gcov.html | 1921 + coverage/isdb/Caliber.cpp.func-sort-c.html | 105 + coverage/isdb/Caliber.cpp.func.html | 105 + coverage/isdb/Caliber.cpp.gcov.html | 424 + coverage/isdb/EMMI.cpp.func-sort-c.html | 229 + coverage/isdb/EMMI.cpp.func.html | 229 + coverage/isdb/EMMI.cpp.gcov.html | 1824 + coverage/isdb/EMMIVox.cpp.func-sort-c.html | 177 + coverage/isdb/EMMIVox.cpp.func.html | 177 + coverage/isdb/EMMIVox.cpp.gcov.html | 1655 + .../isdb/FretEfficiency.cpp.func-sort-c.html | 89 + coverage/isdb/FretEfficiency.cpp.func.html | 89 + coverage/isdb/FretEfficiency.cpp.gcov.html | 232 + coverage/isdb/Jcoupling.cpp.func-sort-c.html | 93 + coverage/isdb/Jcoupling.cpp.func.html | 93 + coverage/isdb/Jcoupling.cpp.gcov.html | 471 + .../isdb/Metainference.cpp.func-sort-c.html | 181 + coverage/isdb/Metainference.cpp.func.html | 181 + coverage/isdb/Metainference.cpp.gcov.html | 1879 + .../MetainferenceBase.cpp.func-sort-c.html | 185 + coverage/isdb/MetainferenceBase.cpp.func.html | 185 + coverage/isdb/MetainferenceBase.cpp.gcov.html | 1637 + .../isdb/MetainferenceBase.h.func-sort-c.html | 117 + coverage/isdb/MetainferenceBase.h.func.html | 117 + coverage/isdb/MetainferenceBase.h.gcov.html | 463 + coverage/isdb/NOE.cpp.func-sort-c.html | 93 + coverage/isdb/NOE.cpp.func.html | 93 + coverage/isdb/NOE.cpp.gcov.html | 351 + coverage/isdb/PRE.cpp.func-sort-c.html | 93 + coverage/isdb/PRE.cpp.func.html | 93 + coverage/isdb/PRE.cpp.gcov.html | 417 + coverage/isdb/RDC.cpp.func-sort-c.html | 97 + coverage/isdb/RDC.cpp.func.html | 97 + coverage/isdb/RDC.cpp.gcov.html | 598 + coverage/isdb/Rescale.cpp.func-sort-c.html | 121 + coverage/isdb/Rescale.cpp.func.html | 121 + coverage/isdb/Rescale.cpp.gcov.html | 590 + coverage/isdb/SAXS.cpp.func-sort-c.html | 165 + coverage/isdb/SAXS.cpp.func.html | 165 + coverage/isdb/SAXS.cpp.gcov.html | 7939 ++++ coverage/isdb/Select.cpp.func-sort-c.html | 89 + coverage/isdb/Select.cpp.func.html | 89 + coverage/isdb/Select.cpp.gcov.html | 193 + coverage/isdb/Selector.cpp.func-sort-c.html | 89 + coverage/isdb/Selector.cpp.func.html | 89 + coverage/isdb/Selector.cpp.gcov.html | 169 + coverage/isdb/Shadow.cpp.func-sort-c.html | 93 + coverage/isdb/Shadow.cpp.func.html | 93 + coverage/isdb/Shadow.cpp.gcov.html | 301 + coverage/isdb/index-sort-f.html | 254 + coverage/isdb/index-sort-l.html | 254 + coverage/isdb/index.html | 254 + coverage/logmfd/LogMFD.cpp.func-sort-c.html | 125 + coverage/logmfd/LogMFD.cpp.func.html | 125 + coverage/logmfd/LogMFD.cpp.gcov.html | 1317 + coverage/logmfd/index-sort-f.html | 94 + coverage/logmfd/index-sort-l.html | 94 + coverage/logmfd/index.html | 94 + coverage/main/index-sort-f.html | 94 + coverage/main/index-sort-l.html | 94 + coverage/main/index.html | 94 + coverage/main/main.cpp.func-sort-c.html | 77 + coverage/main/main.cpp.func.html | 77 + coverage/main/main.cpp.gcov.html | 148 + .../LWalls.cpp.func-sort-c.html | 89 + coverage/manyrestraints/LWalls.cpp.func.html | 89 + coverage/manyrestraints/LWalls.cpp.gcov.html | 185 + .../ManyRestraintsBase.cpp.func-sort-c.html | 97 + .../ManyRestraintsBase.cpp.func.html | 97 + .../ManyRestraintsBase.cpp.gcov.html | 173 + .../ManyRestraintsBase.h.func-sort-c.html | 97 + .../ManyRestraintsBase.h.func.html | 97 + .../ManyRestraintsBase.h.gcov.html | 153 + .../UWalls.cpp.func-sort-c.html | 89 + coverage/manyrestraints/UWalls.cpp.func.html | 89 + coverage/manyrestraints/UWalls.cpp.gcov.html | 189 + coverage/manyrestraints/index-sort-f.html | 124 + coverage/manyrestraints/index-sort-l.html | 124 + coverage/manyrestraints/index.html | 124 + .../mapping/AdaptivePath.cpp.func-sort-c.html | 105 + coverage/mapping/AdaptivePath.cpp.func.html | 105 + coverage/mapping/AdaptivePath.cpp.gcov.html | 336 + coverage/mapping/Mapping.cpp.func-sort-c.html | 121 + coverage/mapping/Mapping.cpp.func.html | 121 + coverage/mapping/Mapping.cpp.gcov.html | 289 + coverage/mapping/Mapping.h.func-sort-c.html | 93 + coverage/mapping/Mapping.h.func.html | 93 + coverage/mapping/Mapping.h.gcov.html | 224 + coverage/mapping/PCAVars.cpp.func-sort-c.html | 113 + coverage/mapping/PCAVars.cpp.func.html | 113 + coverage/mapping/PCAVars.cpp.gcov.html | 536 + coverage/mapping/Path.cpp.func-sort-c.html | 85 + coverage/mapping/Path.cpp.func.html | 85 + coverage/mapping/Path.cpp.gcov.html | 242 + .../mapping/PathBase.cpp.func-sort-c.html | 101 + coverage/mapping/PathBase.cpp.func.html | 101 + coverage/mapping/PathBase.cpp.gcov.html | 162 + ...athReparameterization.cpp.func-sort-c.html | 93 + .../PathReparameterization.cpp.func.html | 93 + .../PathReparameterization.cpp.gcov.html | 223 + .../mapping/PathTools.cpp.func-sort-c.html | 101 + coverage/mapping/PathTools.cpp.func.html | 101 + coverage/mapping/PathTools.cpp.gcov.html | 388 + .../mapping/PropertyMap.cpp.func-sort-c.html | 85 + coverage/mapping/PropertyMap.cpp.func.html | 85 + coverage/mapping/PropertyMap.cpp.gcov.html | 206 + .../mapping/SpathVessel.cpp.func-sort-c.html | 109 + coverage/mapping/SpathVessel.cpp.func.html | 109 + coverage/mapping/SpathVessel.cpp.gcov.html | 164 + ...igonometricPathVessel.cpp.func-sort-c.html | 113 + .../TrigonometricPathVessel.cpp.func.html | 113 + .../TrigonometricPathVessel.cpp.gcov.html | 306 + .../mapping/ZpathVessel.cpp.func-sort-c.html | 109 + coverage/mapping/ZpathVessel.cpp.func.html | 109 + coverage/mapping/ZpathVessel.cpp.gcov.html | 151 + coverage/mapping/index-sort-f.html | 204 + coverage/mapping/index-sort-l.html | 204 + coverage/mapping/index.html | 204 + coverage/maze/Loss.cpp.func-sort-c.html | 89 + coverage/maze/Loss.cpp.func.html | 89 + coverage/maze/Loss.cpp.gcov.html | 191 + coverage/maze/Loss.h.func-sort-c.html | 85 + coverage/maze/Loss.h.func.html | 85 + coverage/maze/Loss.h.gcov.html | 163 + coverage/maze/Member.h.func-sort-c.html | 81 + coverage/maze/Member.h.func.html | 81 + coverage/maze/Member.h.gcov.html | 143 + coverage/maze/Memetic.cpp.func-sort-c.html | 89 + coverage/maze/Memetic.cpp.func.html | 89 + coverage/maze/Memetic.cpp.gcov.html | 359 + coverage/maze/Memetic.h.func-sort-c.html | 153 + coverage/maze/Memetic.h.func.html | 153 + coverage/maze/Memetic.h.gcov.html | 883 + coverage/maze/Optimizer.cpp.func-sort-c.html | 113 + coverage/maze/Optimizer.cpp.func.html | 113 + coverage/maze/Optimizer.cpp.gcov.html | 587 + coverage/maze/Optimizer.h.func-sort-c.html | 77 + coverage/maze/Optimizer.h.func.html | 77 + coverage/maze/Optimizer.h.gcov.html | 434 + .../maze/Optimizer_Bias.cpp.func-sort-c.html | 97 + coverage/maze/Optimizer_Bias.cpp.func.html | 97 + coverage/maze/Optimizer_Bias.cpp.gcov.html | 511 + ...andom_Acceleration_MD.cpp.func-sort-c.html | 89 + .../maze/Random_Acceleration_MD.cpp.func.html | 89 + .../maze/Random_Acceleration_MD.cpp.gcov.html | 280 + coverage/maze/Random_MT.cpp.func-sort-c.html | 97 + coverage/maze/Random_MT.cpp.func.html | 97 + coverage/maze/Random_MT.cpp.gcov.html | 158 + coverage/maze/Random_MT.h.func-sort-c.html | 89 + coverage/maze/Random_MT.h.func.html | 89 + coverage/maze/Random_MT.h.gcov.html | 233 + .../maze/Random_Walk.cpp.func-sort-c.html | 89 + coverage/maze/Random_Walk.cpp.func.html | 89 + coverage/maze/Random_Walk.cpp.gcov.html | 201 + .../Simulated_Annealing.cpp.func-sort-c.html | 93 + .../maze/Simulated_Annealing.cpp.func.html | 93 + .../maze/Simulated_Annealing.cpp.gcov.html | 352 + coverage/maze/Steered_MD.cpp.func-sort-c.html | 89 + coverage/maze/Steered_MD.cpp.func.html | 89 + coverage/maze/Steered_MD.cpp.gcov.html | 253 + coverage/maze/Tools.h.func-sort-c.html | 89 + coverage/maze/Tools.h.func.html | 89 + coverage/maze/Tools.h.gcov.html | 257 + coverage/maze/index-sort-f.html | 234 + coverage/maze/index-sort-l.html | 234 + coverage/maze/index.html | 234 + .../FusionPoreExpansionP.cpp.func-sort-c.html | 89 + .../FusionPoreExpansionP.cpp.func.html | 89 + .../FusionPoreExpansionP.cpp.gcov.html | 682 + ...FusionPoreNucleationP.cpp.func-sort-c.html | 89 + .../FusionPoreNucleationP.cpp.func.html | 89 + .../FusionPoreNucleationP.cpp.gcov.html | 884 + .../MemFusionP.cpp.func-sort-c.html | 89 + .../membranefusion/MemFusionP.cpp.func.html | 89 + .../membranefusion/MemFusionP.cpp.gcov.html | 685 + coverage/membranefusion/index-sort-f.html | 114 + coverage/membranefusion/index-sort-l.html | 114 + coverage/membranefusion/index.html | 114 + .../ActionVolume.cpp.func-sort-c.html | 93 + .../multicolvar/ActionVolume.cpp.func.html | 93 + .../multicolvar/ActionVolume.cpp.gcov.html | 161 + .../ActionVolume.h.func-sort-c.html | 77 + coverage/multicolvar/ActionVolume.h.func.html | 77 + coverage/multicolvar/ActionVolume.h.gcov.html | 164 + .../AlphaBeta.cpp.func-sort-c.html | 93 + coverage/multicolvar/AlphaBeta.cpp.func.html | 93 + coverage/multicolvar/AlphaBeta.cpp.gcov.html | 281 + .../multicolvar/Angles.cpp.func-sort-c.html | 97 + coverage/multicolvar/Angles.cpp.func.html | 97 + coverage/multicolvar/Angles.cpp.gcov.html | 297 + .../AtomValuePack.cpp.func-sort-c.html | 89 + .../multicolvar/AtomValuePack.cpp.func.html | 89 + .../multicolvar/AtomValuePack.cpp.gcov.html | 177 + .../AtomValuePack.h.func-sort-c.html | 101 + .../multicolvar/AtomValuePack.h.func.html | 101 + .../multicolvar/AtomValuePack.h.gcov.html | 292 + .../multicolvar/Bridge.cpp.func-sort-c.html | 93 + coverage/multicolvar/Bridge.cpp.func.html | 93 + coverage/multicolvar/Bridge.cpp.gcov.html | 232 + ...edMultiColvarFunction.cpp.func-sort-c.html | 117 + .../BridgedMultiColvarFunction.cpp.func.html | 117 + .../BridgedMultiColvarFunction.cpp.gcov.html | 200 + ...dgedMultiColvarFunction.h.func-sort-c.html | 121 + .../BridgedMultiColvarFunction.h.func.html | 121 + .../BridgedMultiColvarFunction.h.gcov.html | 224 + .../CatomPack.cpp.func-sort-c.html | 77 + coverage/multicolvar/CatomPack.cpp.func.html | 77 + coverage/multicolvar/CatomPack.cpp.gcov.html | 109 + .../multicolvar/CatomPack.h.func-sort-c.html | 81 + coverage/multicolvar/CatomPack.h.func.html | 81 + coverage/multicolvar/CatomPack.h.gcov.html | 155 + .../CenterOfMultiColvar.cpp.func-sort-c.html | 89 + .../CenterOfMultiColvar.cpp.func.html | 89 + .../CenterOfMultiColvar.cpp.gcov.html | 298 + .../CoordinationNumbers.cpp.func-sort-c.html | 93 + .../CoordinationNumbers.cpp.func.html | 93 + .../CoordinationNumbers.cpp.gcov.html | 261 + .../multicolvar/Density.cpp.func-sort-c.html | 109 + coverage/multicolvar/Density.cpp.func.html | 109 + coverage/multicolvar/Density.cpp.gcov.html | 182 + .../DihedralCorrelation.cpp.func-sort-c.html | 93 + .../DihedralCorrelation.cpp.func.html | 93 + .../DihedralCorrelation.cpp.gcov.html | 251 + .../DistanceFromContour.cpp.func-sort-c.html | 113 + .../DistanceFromContour.cpp.func.html | 113 + .../DistanceFromContour.cpp.gcov.html | 419 + .../Distances.cpp.func-sort-c.html | 93 + coverage/multicolvar/Distances.cpp.func.html | 93 + coverage/multicolvar/Distances.cpp.gcov.html | 288 + .../DumpMultiColvar.cpp.func-sort-c.html | 113 + .../multicolvar/DumpMultiColvar.cpp.func.html | 113 + .../multicolvar/DumpMultiColvar.cpp.gcov.html | 258 + .../FilterBetween.cpp.func-sort-c.html | 89 + .../multicolvar/FilterBetween.cpp.func.html | 89 + .../multicolvar/FilterBetween.cpp.gcov.html | 272 + .../FilterLessThan.cpp.func-sort-c.html | 89 + .../multicolvar/FilterLessThan.cpp.func.html | 89 + .../multicolvar/FilterLessThan.cpp.gcov.html | 240 + .../FilterMoreThan.cpp.func-sort-c.html | 89 + .../multicolvar/FilterMoreThan.cpp.func.html | 89 + .../multicolvar/FilterMoreThan.cpp.gcov.html | 257 + .../InPlaneDistances.cpp.func-sort-c.html | 93 + .../InPlaneDistances.cpp.func.html | 93 + .../InPlaneDistances.cpp.gcov.html | 224 + .../LocalAverage.cpp.func-sort-c.html | 101 + .../multicolvar/LocalAverage.cpp.func.html | 101 + .../multicolvar/LocalAverage.cpp.gcov.html | 407 + .../MultiColvarBase.cpp.func-sort-c.html | 237 + .../multicolvar/MultiColvarBase.cpp.func.html | 237 + .../multicolvar/MultiColvarBase.cpp.gcov.html | 1165 + .../MultiColvarBase.h.func-sort-c.html | 113 + .../multicolvar/MultiColvarBase.h.func.html | 113 + .../multicolvar/MultiColvarBase.h.gcov.html | 351 + .../MultiColvarCombine.cpp.func-sort-c.html | 93 + .../MultiColvarCombine.cpp.func.html | 93 + .../MultiColvarCombine.cpp.gcov.html | 172 + .../MultiColvarDensity.cpp.func-sort-c.html | 109 + .../MultiColvarDensity.cpp.func.html | 109 + .../MultiColvarDensity.cpp.gcov.html | 374 + .../MultiColvarFilter.cpp.func-sort-c.html | 97 + .../MultiColvarFilter.cpp.func.html | 97 + .../MultiColvarFilter.cpp.gcov.html | 171 + .../MultiColvarFilter.h.func-sort-c.html | 77 + .../multicolvar/MultiColvarFilter.h.func.html | 77 + .../multicolvar/MultiColvarFilter.h.gcov.html | 140 + .../MultiColvarProduct.cpp.func-sort-c.html | 93 + .../MultiColvarProduct.cpp.func.html | 93 + .../MultiColvarProduct.cpp.gcov.html | 166 + .../NumberOfLinks.cpp.func-sort-c.html | 97 + .../multicolvar/NumberOfLinks.cpp.func.html | 97 + .../multicolvar/NumberOfLinks.cpp.gcov.html | 252 + .../multicolvar/Torsions.cpp.func-sort-c.html | 97 + coverage/multicolvar/Torsions.cpp.func.html | 97 + coverage/multicolvar/Torsions.cpp.gcov.html | 212 + .../VolumeAround.cpp.func-sort-c.html | 93 + .../multicolvar/VolumeAround.cpp.func.html | 93 + .../multicolvar/VolumeAround.cpp.gcov.html | 231 + ...VolumeBetweenContours.cpp.func-sort-c.html | 93 + .../VolumeBetweenContours.cpp.func.html | 93 + .../VolumeBetweenContours.cpp.gcov.html | 223 + .../VolumeCavity.cpp.func-sort-c.html | 109 + .../multicolvar/VolumeCavity.cpp.func.html | 109 + .../multicolvar/VolumeCavity.cpp.gcov.html | 487 + .../VolumeGradientBase.cpp.func-sort-c.html | 105 + .../VolumeGradientBase.cpp.func.html | 105 + .../VolumeGradientBase.cpp.gcov.html | 230 + .../VolumeGradientBase.h.func-sort-c.html | 77 + .../VolumeGradientBase.h.func.html | 77 + .../VolumeGradientBase.h.gcov.html | 171 + .../VolumeInCylinder.cpp.func-sort-c.html | 93 + .../VolumeInCylinder.cpp.func.html | 93 + .../VolumeInCylinder.cpp.gcov.html | 237 + .../VolumeInSphere.cpp.func-sort-c.html | 93 + .../multicolvar/VolumeInSphere.cpp.func.html | 93 + .../multicolvar/VolumeInSphere.cpp.gcov.html | 200 + .../VolumeTetrapore.cpp.func-sort-c.html | 109 + .../multicolvar/VolumeTetrapore.cpp.func.html | 109 + .../multicolvar/VolumeTetrapore.cpp.gcov.html | 522 + .../multicolvar/XAngle.cpp.func-sort-c.html | 97 + coverage/multicolvar/XAngle.cpp.func.html | 97 + coverage/multicolvar/XAngle.cpp.gcov.html | 254 + .../XDistances.cpp.func-sort-c.html | 93 + coverage/multicolvar/XDistances.cpp.func.html | 93 + coverage/multicolvar/XDistances.cpp.gcov.html | 318 + .../XYDistances.cpp.func-sort-c.html | 93 + .../multicolvar/XYDistances.cpp.func.html | 93 + .../multicolvar/XYDistances.cpp.gcov.html | 246 + .../XYTorsion.cpp.func-sort-c.html | 101 + coverage/multicolvar/XYTorsion.cpp.func.html | 101 + coverage/multicolvar/XYTorsion.cpp.gcov.html | 311 + coverage/multicolvar/index-sort-f.html | 524 + coverage/multicolvar/index-sort-l.html | 524 + coverage/multicolvar/index.html | 524 + coverage/opes/ECVcustom.cpp.func-sort-c.html | 117 + coverage/opes/ECVcustom.cpp.func.html | 117 + coverage/opes/ECVcustom.cpp.gcov.html | 315 + coverage/opes/ECVlinear.cpp.func-sort-c.html | 113 + coverage/opes/ECVlinear.cpp.func.html | 113 + coverage/opes/ECVlinear.cpp.gcov.html | 345 + .../opes/ECVmultiThermal.cpp.func-sort-c.html | 113 + coverage/opes/ECVmultiThermal.cpp.func.html | 113 + coverage/opes/ECVmultiThermal.cpp.gcov.html | 345 + .../ECVmultiThermalBaric.cpp.func-sort-c.html | 121 + .../opes/ECVmultiThermalBaric.cpp.func.html | 121 + .../opes/ECVmultiThermalBaric.cpp.gcov.html | 607 + .../ECVumbrellasFile.cpp.func-sort-c.html | 113 + coverage/opes/ECVumbrellasFile.cpp.func.html | 113 + coverage/opes/ECVumbrellasFile.cpp.gcov.html | 372 + .../ECVumbrellasLine.cpp.func-sort-c.html | 113 + coverage/opes/ECVumbrellasLine.cpp.func.html | 113 + coverage/opes/ECVumbrellasLine.cpp.gcov.html | 378 + .../opes/ExpansionCVs.cpp.func-sort-c.html | 113 + coverage/opes/ExpansionCVs.cpp.func.html | 113 + coverage/opes/ExpansionCVs.cpp.gcov.html | 299 + coverage/opes/ExpansionCVs.h.func-sort-c.html | 85 + coverage/opes/ExpansionCVs.h.func.html | 85 + coverage/opes/ExpansionCVs.h.gcov.html | 149 + .../opes/OPESexpanded.cpp.func-sort-c.html | 125 + coverage/opes/OPESexpanded.cpp.func.html | 125 + coverage/opes/OPESexpanded.cpp.gcov.html | 1021 + coverage/opes/OPESmetad.cpp.func-sort-c.html | 185 + coverage/opes/OPESmetad.cpp.func.html | 185 + coverage/opes/OPESmetad.cpp.gcov.html | 1829 + coverage/opes/index-sort-f.html | 184 + coverage/opes/index-sort-l.html | 184 + coverage/opes/index.html | 184 + .../pamm/HBPammHydrogens.cpp.func-sort-c.html | 93 + coverage/pamm/HBPammHydrogens.cpp.func.html | 93 + coverage/pamm/HBPammHydrogens.cpp.gcov.html | 268 + .../pamm/HBPammMatrix.cpp.func-sort-c.html | 93 + coverage/pamm/HBPammMatrix.cpp.func.html | 93 + coverage/pamm/HBPammMatrix.cpp.gcov.html | 225 + .../pamm/HBPammObject.cpp.func-sort-c.html | 85 + coverage/pamm/HBPammObject.cpp.func.html | 85 + coverage/pamm/HBPammObject.cpp.gcov.html | 153 + coverage/pamm/HBPammObject.h.func-sort-c.html | 73 + coverage/pamm/HBPammObject.h.func.html | 73 + coverage/pamm/HBPammObject.h.gcov.html | 128 + coverage/pamm/PAMM.cpp.func-sort-c.html | 105 + coverage/pamm/PAMM.cpp.func.html | 105 + coverage/pamm/PAMM.cpp.gcov.html | 329 + coverage/pamm/PammObject.cpp.func-sort-c.html | 89 + coverage/pamm/PammObject.cpp.func.html | 89 + coverage/pamm/PammObject.cpp.gcov.html | 180 + coverage/pamm/PammObject.h.func-sort-c.html | 73 + coverage/pamm/PammObject.h.func.html | 73 + coverage/pamm/PammObject.h.gcov.html | 159 + coverage/pamm/index-sort-f.html | 154 + coverage/pamm/index-sort-l.html | 154 + coverage/pamm/index.html | 154 + coverage/piv/PIV.cpp.func-sort-c.html | 93 + coverage/piv/PIV.cpp.func.html | 93 + coverage/piv/PIV.cpp.gcov.html | 1340 + coverage/piv/index-sort-f.html | 94 + coverage/piv/index-sort-l.html | 94 + coverage/piv/index.html | 94 + .../pytorch/PytorchModel.cpp.func-sort-c.html | 93 + coverage/pytorch/PytorchModel.cpp.func.html | 93 + coverage/pytorch/PytorchModel.cpp.gcov.html | 321 + coverage/pytorch/index-sort-f.html | 94 + coverage/pytorch/index-sort-l.html | 94 + coverage/pytorch/index.html | 94 + .../ArgumentOnlyDistance.cpp.func-sort-c.html | 93 + .../ArgumentOnlyDistance.cpp.func.html | 93 + .../ArgumentOnlyDistance.cpp.gcov.html | 130 + .../ArgumentOnlyDistance.h.func-sort-c.html | 81 + .../ArgumentOnlyDistance.h.func.html | 81 + .../ArgumentOnlyDistance.h.gcov.html | 122 + coverage/reference/DRMSD.cpp.func-sort-c.html | 117 + coverage/reference/DRMSD.cpp.func.html | 117 + coverage/reference/DRMSD.cpp.gcov.html | 194 + .../reference/Direction.cpp.func-sort-c.html | 121 + coverage/reference/Direction.cpp.func.html | 121 + coverage/reference/Direction.cpp.gcov.html | 151 + .../reference/Direction.h.func-sort-c.html | 77 + coverage/reference/Direction.h.func.html | 77 + coverage/reference/Direction.h.gcov.html | 128 + .../DotProductDistance.cpp.func-sort-c.html | 101 + .../DotProductDistance.cpp.func.html | 101 + .../DotProductDistance.cpp.gcov.html | 135 + .../EuclideanDistance.cpp.func-sort-c.html | 93 + .../reference/EuclideanDistance.cpp.func.html | 93 + .../reference/EuclideanDistance.cpp.gcov.html | 117 + .../IntermolecularDRMSD.cpp.func-sort-c.html | 101 + .../IntermolecularDRMSD.cpp.func.html | 101 + .../IntermolecularDRMSD.cpp.gcov.html | 145 + .../IntramolecularDRMSD.cpp.func-sort-c.html | 101 + .../IntramolecularDRMSD.cpp.func.html | 101 + .../IntramolecularDRMSD.cpp.gcov.html | 143 + .../MahalanobisDistance.cpp.func-sort-c.html | 93 + .../MahalanobisDistance.cpp.func.html | 93 + .../MahalanobisDistance.cpp.gcov.html | 118 + .../MetricRegister.cpp.func-sort-c.html | 93 + .../reference/MetricRegister.cpp.func.html | 93 + .../reference/MetricRegister.cpp.gcov.html | 135 + .../MetricRegister.h.func-sort-c.html | 113 + coverage/reference/MetricRegister.h.func.html | 113 + coverage/reference/MetricRegister.h.gcov.html | 191 + .../MultiDomainRMSD.cpp.func-sort-c.html | 125 + .../reference/MultiDomainRMSD.cpp.func.html | 125 + .../reference/MultiDomainRMSD.cpp.gcov.html | 286 + ...izedEuclideanDistance.cpp.func-sort-c.html | 93 + .../NormalizedEuclideanDistance.cpp.func.html | 93 + .../NormalizedEuclideanDistance.cpp.gcov.html | 118 + .../OptimalRMSD.cpp.func-sort-c.html | 121 + coverage/reference/OptimalRMSD.cpp.func.html | 121 + coverage/reference/OptimalRMSD.cpp.gcov.html | 195 + .../reference/RMSDBase.cpp.func-sort-c.html | 89 + coverage/reference/RMSDBase.cpp.func.html | 89 + coverage/reference/RMSDBase.cpp.gcov.html | 119 + .../ReferenceArguments.cpp.func-sort-c.html | 117 + .../ReferenceArguments.cpp.func.html | 117 + .../ReferenceArguments.cpp.gcov.html | 281 + .../ReferenceArguments.h.func-sort-c.html | 89 + .../reference/ReferenceArguments.h.func.html | 89 + .../reference/ReferenceArguments.h.gcov.html | 197 + .../ReferenceAtoms.cpp.func-sort-c.html | 97 + .../reference/ReferenceAtoms.cpp.func.html | 97 + .../reference/ReferenceAtoms.cpp.gcov.html | 202 + .../ReferenceAtoms.h.func-sort-c.html | 93 + coverage/reference/ReferenceAtoms.h.func.html | 93 + coverage/reference/ReferenceAtoms.h.gcov.html | 240 + ...eferenceConfiguration.cpp.func-sort-c.html | 125 + .../ReferenceConfiguration.cpp.func.html | 125 + .../ReferenceConfiguration.cpp.gcov.html | 208 + .../ReferenceConfiguration.h.func-sort-c.html | 121 + .../ReferenceConfiguration.h.func.html | 121 + .../ReferenceConfiguration.h.gcov.html | 250 + .../ReferenceValuePack.cpp.func-sort-c.html | 101 + .../ReferenceValuePack.cpp.func.html | 101 + .../ReferenceValuePack.cpp.gcov.html | 172 + .../ReferenceValuePack.h.func-sort-c.html | 93 + .../reference/ReferenceValuePack.h.func.html | 93 + .../reference/ReferenceValuePack.h.gcov.html | 305 + .../reference/SimpleRMSD.cpp.func-sort-c.html | 117 + coverage/reference/SimpleRMSD.cpp.func.html | 117 + coverage/reference/SimpleRMSD.cpp.gcov.html | 163 + .../SingleDomainRMSD.cpp.func-sort-c.html | 97 + .../reference/SingleDomainRMSD.cpp.func.html | 97 + .../reference/SingleDomainRMSD.cpp.gcov.html | 179 + .../SingleDomainRMSD.h.func-sort-c.html | 81 + .../reference/SingleDomainRMSD.h.func.html | 81 + .../reference/SingleDomainRMSD.h.gcov.html | 128 + coverage/reference/index-sort-f.html | 354 + coverage/reference/index-sort-l.html | 354 + coverage/reference/index.html | 354 + coverage/ruby.png | Bin 0 -> 141 bytes .../s2cm/S2ContactModel.cpp.func-sort-c.html | 105 + coverage/s2cm/S2ContactModel.cpp.func.html | 105 + coverage/s2cm/S2ContactModel.cpp.gcov.html | 402 + coverage/s2cm/index-sort-f.html | 94 + coverage/s2cm/index-sort-l.html | 94 + coverage/s2cm/index.html | 94 + coverage/sasa/index-sort-f.html | 104 + coverage/sasa/index-sort-l.html | 104 + coverage/sasa/index.html | 104 + coverage/sasa/sasa_HASEL.cpp.func-sort-c.html | 125 + coverage/sasa/sasa_HASEL.cpp.func.html | 125 + coverage/sasa/sasa_HASEL.cpp.gcov.html | 1089 + coverage/sasa/sasa_LCPO.cpp.func-sort-c.html | 125 + coverage/sasa/sasa_LCPO.cpp.func.html | 125 + coverage/sasa/sasa_LCPO.cpp.gcov.html | 1157 + .../AlphaRMSD.cpp.func-sort-c.html | 85 + .../AlphaRMSD.cpp.func.html | 85 + .../AlphaRMSD.cpp.gcov.html | 234 + .../AntibetaRMSD.cpp.func-sort-c.html | 85 + .../AntibetaRMSD.cpp.func.html | 85 + .../AntibetaRMSD.cpp.gcov.html | 286 + .../ParabetaRMSD.cpp.func-sort-c.html | 85 + .../ParabetaRMSD.cpp.func.html | 85 + .../ParabetaRMSD.cpp.gcov.html | 320 + ...econdaryStructureRMSD.cpp.func-sort-c.html | 129 + .../SecondaryStructureRMSD.cpp.func.html | 129 + .../SecondaryStructureRMSD.cpp.gcov.html | 345 + .../SecondaryStructureRMSD.h.func-sort-c.html | 85 + .../SecondaryStructureRMSD.h.func.html | 85 + .../SecondaryStructureRMSD.h.gcov.html | 187 + coverage/secondarystructure/index-sort-f.html | 134 + coverage/secondarystructure/index-sort-l.html | 134 + coverage/secondarystructure/index.html | 134 + coverage/setup/Load.cpp.func-sort-c.html | 85 + coverage/setup/Load.cpp.func.html | 85 + coverage/setup/Load.cpp.gcov.html | 200 + coverage/setup/Restart.cpp.func-sort-c.html | 85 + coverage/setup/Restart.cpp.func.html | 85 + coverage/setup/Restart.cpp.gcov.html | 202 + coverage/setup/Units.cpp.func-sort-c.html | 85 + coverage/setup/Units.cpp.func.html | 85 + coverage/setup/Units.cpp.gcov.html | 275 + coverage/setup/index-sort-f.html | 114 + coverage/setup/index-sort-l.html | 114 + coverage/setup/index.html | 114 + coverage/small_vector/index-sort-f.html | 94 + coverage/small_vector/index-sort-l.html | 94 + coverage/small_vector/index.html | 94 + .../small_vector.h.func-sort-c.html | 153 + .../small_vector/small_vector.h.func.html | 153 + .../small_vector/small_vector.h.gcov.html | 6560 ++++ coverage/snow.png | Bin 0 -> 141 bytes coverage/tools/Angle.cpp.func-sort-c.html | 81 + coverage/tools/Angle.cpp.func.html | 81 + coverage/tools/Angle.cpp.gcov.html | 145 + coverage/tools/AtomNumber.h.func-sort-c.html | 81 + coverage/tools/AtomNumber.h.func.html | 81 + coverage/tools/AtomNumber.h.gcov.html | 229 + .../BiasRepresentation.cpp.func-sort-c.html | 149 + .../tools/BiasRepresentation.cpp.func.html | 149 + .../tools/BiasRepresentation.cpp.gcov.html | 364 + .../Brent1DRootSearch.h.func-sort-c.html | 109 + coverage/tools/Brent1DRootSearch.h.func.html | 109 + coverage/tools/Brent1DRootSearch.h.gcov.html | 197 + coverage/tools/Citations.cpp.func-sort-c.html | 89 + coverage/tools/Citations.cpp.func.html | 89 + coverage/tools/Citations.cpp.gcov.html | 133 + coverage/tools/Citations.h.func-sort-c.html | 73 + coverage/tools/Citations.h.func.html | 73 + coverage/tools/Citations.h.gcov.html | 151 + .../tools/Communicator.cpp.func-sort-c.html | 217 + coverage/tools/Communicator.cpp.func.html | 217 + coverage/tools/Communicator.cpp.gcov.html | 395 + .../tools/Communicator.h.func-sort-c.html | 321 + coverage/tools/Communicator.h.func.html | 321 + coverage/tools/Communicator.h.gcov.html | 329 + .../ConjugateGradient.h.func-sort-c.html | 85 + coverage/tools/ConjugateGradient.h.func.html | 85 + coverage/tools/ConjugateGradient.h.gcov.html | 143 + coverage/tools/DLLoader.cpp.func-sort-c.html | 101 + coverage/tools/DLLoader.cpp.func.html | 101 + coverage/tools/DLLoader.cpp.gcov.html | 193 + coverage/tools/DynamicList.h.func-sort-c.html | 125 + coverage/tools/DynamicList.h.func.html | 125 + coverage/tools/DynamicList.h.gcov.html | 456 + coverage/tools/ERMSD.cpp.func-sort-c.html | 93 + coverage/tools/ERMSD.cpp.func.html | 93 + coverage/tools/ERMSD.cpp.gcov.html | 380 + coverage/tools/ERMSD.h.func-sort-c.html | 73 + coverage/tools/ERMSD.h.func.html | 73 + coverage/tools/ERMSD.h.gcov.html | 150 + coverage/tools/Exception.cpp.func-sort-c.html | 97 + coverage/tools/Exception.cpp.func.html | 97 + coverage/tools/Exception.cpp.gcov.html | 233 + coverage/tools/Exception.h.func-sort-c.html | 621 + coverage/tools/Exception.h.func.html | 621 + coverage/tools/Exception.h.gcov.html | 480 + coverage/tools/FileBase.cpp.func-sort-c.html | 133 + coverage/tools/FileBase.cpp.func.html | 133 + coverage/tools/FileBase.cpp.gcov.html | 252 + coverage/tools/FileBase.h.func-sort-c.html | 73 + coverage/tools/FileBase.h.func.html | 73 + coverage/tools/FileBase.h.gcov.html | 229 + coverage/tools/ForwardDecl.h.func-sort-c.html | 121 + coverage/tools/ForwardDecl.h.func.html | 121 + coverage/tools/ForwardDecl.h.gcov.html | 132 + coverage/tools/Grid.cpp.func-sort-c.html | 381 + coverage/tools/Grid.cpp.func.html | 381 + coverage/tools/Grid.cpp.gcov.html | 1205 + coverage/tools/Grid.h.func-sort-c.html | 109 + coverage/tools/Grid.h.func.html | 109 + coverage/tools/Grid.h.gcov.html | 432 + .../tools/HistogramBead.cpp.func-sort-c.html | 117 + coverage/tools/HistogramBead.cpp.func.html | 117 + coverage/tools/HistogramBead.cpp.gcov.html | 342 + .../tools/HistogramBead.h.func-sort-c.html | 81 + coverage/tools/HistogramBead.h.func.html | 81 + coverage/tools/HistogramBead.h.gcov.html | 191 + coverage/tools/IFile.cpp.func-sort-c.html | 173 + coverage/tools/IFile.cpp.func.html | 173 + coverage/tools/IFile.cpp.gcov.html | 372 + coverage/tools/IFile.h.func-sort-c.html | 73 + coverage/tools/IFile.h.func.html | 73 + coverage/tools/IFile.h.gcov.html | 194 + .../KernelFunctions.cpp.func-sort-c.html | 113 + coverage/tools/KernelFunctions.cpp.func.html | 113 + coverage/tools/KernelFunctions.cpp.gcov.html | 532 + .../tools/KernelFunctions.h.func-sort-c.html | 77 + coverage/tools/KernelFunctions.h.func.html | 77 + coverage/tools/KernelFunctions.h.gcov.html | 174 + coverage/tools/Keywords.cpp.func-sort-c.html | 237 + coverage/tools/Keywords.cpp.func.html | 237 + coverage/tools/Keywords.cpp.gcov.html | 740 + coverage/tools/Keywords.h.func-sort-c.html | 81 + coverage/tools/Keywords.h.func.html | 81 + coverage/tools/Keywords.h.gcov.html | 261 + .../LatticeReduction.cpp.func-sort-c.html | 113 + coverage/tools/LatticeReduction.cpp.func.html | 113 + coverage/tools/LatticeReduction.cpp.gcov.html | 292 + coverage/tools/LinkCells.cpp.func-sort-c.html | 113 + coverage/tools/LinkCells.cpp.func.html | 113 + coverage/tools/LinkCells.cpp.gcov.html | 253 + coverage/tools/LinkCells.h.func-sort-c.html | 73 + coverage/tools/LinkCells.h.func.html | 73 + coverage/tools/LinkCells.h.gcov.html | 176 + .../tools/LoopUnroller.h.func-sort-c.html | 281 + coverage/tools/LoopUnroller.h.func.html | 281 + coverage/tools/LoopUnroller.h.gcov.html | 237 + coverage/tools/Matrix.h.func-sort-c.html | 117 + coverage/tools/Matrix.h.func.html | 117 + coverage/tools/Matrix.h.gcov.html | 491 + ...rixSquareBracketsAccess.h.func-sort-c.html | 157 + .../MatrixSquareBracketsAccess.h.func.html | 157 + .../MatrixSquareBracketsAccess.h.gcov.html | 215 + .../tools/Minimise1DBrent.h.func-sort-c.html | 121 + coverage/tools/Minimise1DBrent.h.func.html | 121 + coverage/tools/Minimise1DBrent.h.gcov.html | 272 + .../tools/MinimiseBase.h.func-sort-c.html | 145 + coverage/tools/MinimiseBase.h.func.html | 145 + coverage/tools/MinimiseBase.h.gcov.html | 192 + .../tools/MolDataClass.cpp.func-sort-c.html | 93 + coverage/tools/MolDataClass.cpp.func.html | 93 + coverage/tools/MolDataClass.cpp.gcov.html | 664 + .../tools/MultiValue.cpp.func-sort-c.html | 109 + coverage/tools/MultiValue.cpp.func.html | 109 + coverage/tools/MultiValue.cpp.gcov.html | 197 + coverage/tools/MultiValue.h.func-sort-c.html | 89 + coverage/tools/MultiValue.h.func.html | 89 + coverage/tools/MultiValue.h.gcov.html | 318 + .../tools/NeighborList.cpp.func-sort-c.html | 137 + coverage/tools/NeighborList.cpp.func.html | 137 + coverage/tools/NeighborList.cpp.gcov.html | 371 + .../tools/NeighborList.h.func-sort-c.html | 73 + coverage/tools/NeighborList.h.func.html | 73 + coverage/tools/NeighborList.h.gcov.html | 189 + coverage/tools/OFile.cpp.func-sort-c.html | 193 + coverage/tools/OFile.cpp.func.html | 193 + coverage/tools/OFile.cpp.gcov.html | 513 + coverage/tools/OFile.h.func-sort-c.html | 501 + coverage/tools/OFile.h.func.html | 501 + coverage/tools/OFile.h.gcov.html | 363 + coverage/tools/OpenMP.cpp.func-sort-c.html | 89 + coverage/tools/OpenMP.cpp.func.html | 89 + coverage/tools/OpenMP.cpp.gcov.html | 159 + coverage/tools/OpenMP.h.func-sort-c.html | 85 + coverage/tools/OpenMP.h.func.html | 85 + coverage/tools/OpenMP.h.gcov.html | 149 + coverage/tools/PDB.cpp.func-sort-c.html | 249 + coverage/tools/PDB.cpp.func.html | 249 + coverage/tools/PDB.cpp.gcov.html | 827 + coverage/tools/Pbc.cpp.func-sort-c.html | 125 + coverage/tools/Pbc.cpp.func.html | 125 + coverage/tools/Pbc.cpp.gcov.html | 368 + coverage/tools/Pbc.h.func-sort-c.html | 73 + coverage/tools/Pbc.h.func.html | 73 + coverage/tools/Pbc.h.gcov.html | 225 + .../tools/PlumedHandle.cpp.func-sort-c.html | 105 + coverage/tools/PlumedHandle.cpp.func.html | 105 + coverage/tools/PlumedHandle.cpp.gcov.html | 185 + coverage/tools/RMSD.cpp.func-sort-c.html | 393 + coverage/tools/RMSD.cpp.func.html | 393 + coverage/tools/RMSD.cpp.gcov.html | 1549 + coverage/tools/RMSD.h.func-sort-c.html | 109 + coverage/tools/RMSD.h.func.html | 109 + coverage/tools/RMSD.h.gcov.html | 453 + coverage/tools/Random.cpp.func-sort-c.html | 117 + coverage/tools/Random.cpp.func.html | 117 + coverage/tools/Random.cpp.gcov.html | 246 + coverage/tools/Random.h.func-sort-c.html | 73 + coverage/tools/Random.h.func.html | 73 + coverage/tools/Random.h.gcov.html | 149 + .../tools/RootFindingBase.h.func-sort-c.html | 97 + coverage/tools/RootFindingBase.h.func.html | 97 + coverage/tools/RootFindingBase.h.gcov.html | 154 + coverage/tools/Stopwatch.cpp.func-sort-c.html | 85 + coverage/tools/Stopwatch.cpp.func.html | 85 + coverage/tools/Stopwatch.cpp.gcov.html | 155 + coverage/tools/Stopwatch.h.func-sort-c.html | 113 + coverage/tools/Stopwatch.h.func.html | 113 + coverage/tools/Stopwatch.h.gcov.html | 486 + .../tools/Subprocess.cpp.func-sort-c.html | 137 + coverage/tools/Subprocess.cpp.func.html | 137 + coverage/tools/Subprocess.cpp.gcov.html | 257 + coverage/tools/Subprocess.h.func-sort-c.html | 81 + coverage/tools/Subprocess.h.func.html | 81 + coverage/tools/Subprocess.h.gcov.html | 219 + .../SwitchingFunction.cpp.func-sort-c.html | 117 + .../tools/SwitchingFunction.cpp.func.html | 117 + .../tools/SwitchingFunction.cpp.gcov.html | 627 + coverage/tools/Tensor.cpp.func-sort-c.html | 77 + coverage/tools/Tensor.cpp.func.html | 77 + coverage/tools/Tensor.cpp.gcov.html | 116 + coverage/tools/Tensor.h.func-sort-c.html | 345 + coverage/tools/Tensor.h.func.html | 345 + coverage/tools/Tensor.h.gcov.html | 646 + coverage/tools/Tools.cpp.func-sort-c.html | 301 + coverage/tools/Tools.cpp.func.html | 301 + coverage/tools/Tools.cpp.gcov.html | 597 + coverage/tools/Tools.h.func-sort-c.html | 281 + coverage/tools/Tools.h.func.html | 281 + coverage/tools/Tools.h.gcov.html | 587 + coverage/tools/Torsion.cpp.func-sort-c.html | 81 + coverage/tools/Torsion.cpp.func.html | 81 + coverage/tools/Torsion.cpp.gcov.html | 157 + coverage/tools/Tree.cpp.func-sort-c.html | 85 + coverage/tools/Tree.cpp.func.html | 85 + coverage/tools/Tree.cpp.gcov.html | 194 + coverage/tools/Tree.h.func-sort-c.html | 73 + coverage/tools/Tree.h.func.html | 73 + coverage/tools/Tree.h.gcov.html | 129 + .../tools/TypesafePtr.cpp.func-sort-c.html | 85 + coverage/tools/TypesafePtr.cpp.func.html | 85 + coverage/tools/TypesafePtr.cpp.gcov.html | 134 + coverage/tools/TypesafePtr.h.func-sort-c.html | 293 + coverage/tools/TypesafePtr.h.func.html | 293 + coverage/tools/TypesafePtr.h.gcov.html | 473 + coverage/tools/Units.cpp.func-sort-c.html | 117 + coverage/tools/Units.cpp.func.html | 117 + coverage/tools/Units.cpp.gcov.html | 235 + coverage/tools/Units.h.func-sort-c.html | 73 + coverage/tools/Units.h.func.html | 73 + coverage/tools/Units.h.gcov.html | 244 + coverage/tools/Vector.h.func-sort-c.html | 333 + coverage/tools/Vector.h.func.html | 333 + coverage/tools/Vector.h.gcov.html | 420 + coverage/tools/h36.cpp.func-sort-c.html | 121 + coverage/tools/h36.cpp.func.html | 121 + coverage/tools/h36.cpp.gcov.html | 412 + coverage/tools/index-sort-f.html | 804 + coverage/tools/index-sort-l.html | 804 + coverage/tools/index.html | 804 + coverage/updown.png | Bin 0 -> 117 bytes coverage/vatom/Center.cpp.func-sort-c.html | 89 + coverage/vatom/Center.cpp.func.html | 89 + coverage/vatom/Center.cpp.gcov.html | 396 + coverage/vatom/FixedAtom.cpp.func-sort-c.html | 89 + coverage/vatom/FixedAtom.cpp.func.html | 89 + coverage/vatom/FixedAtom.cpp.gcov.html | 227 + coverage/vatom/Ghost.cpp.func-sort-c.html | 89 + coverage/vatom/Ghost.cpp.func.html | 89 + coverage/vatom/Ghost.cpp.gcov.html | 263 + coverage/vatom/index-sort-f.html | 114 + coverage/vatom/index-sort-l.html | 114 + coverage/vatom/index.html | 114 + .../ves/BF_Chebyshev.cpp.func-sort-c.html | 89 + coverage/ves/BF_Chebyshev.cpp.func.html | 89 + coverage/ves/BF_Chebyshev.cpp.gcov.html | 233 + coverage/ves/BF_Combined.cpp.func-sort-c.html | 93 + coverage/ves/BF_Combined.cpp.func.html | 93 + coverage/ves/BF_Combined.cpp.gcov.html | 279 + coverage/ves/BF_Cosine.cpp.func-sort-c.html | 93 + coverage/ves/BF_Cosine.cpp.func.html | 93 + coverage/ves/BF_Cosine.cpp.gcov.html | 229 + .../ves/BF_CubicBsplines.cpp.func-sort-c.html | 89 + coverage/ves/BF_CubicBsplines.cpp.func.html | 89 + coverage/ves/BF_CubicBsplines.cpp.gcov.html | 278 + coverage/ves/BF_Custom.cpp.func-sort-c.html | 93 + coverage/ves/BF_Custom.cpp.func.html | 93 + coverage/ves/BF_Custom.cpp.gcov.html | 446 + coverage/ves/BF_Fourier.cpp.func-sort-c.html | 93 + coverage/ves/BF_Fourier.cpp.func.html | 93 + coverage/ves/BF_Fourier.cpp.gcov.html | 233 + .../ves/BF_Gaussians.cpp.func-sort-c.html | 89 + coverage/ves/BF_Gaussians.cpp.func.html | 89 + coverage/ves/BF_Gaussians.cpp.gcov.html | 266 + coverage/ves/BF_Legendre.cpp.func-sort-c.html | 89 + coverage/ves/BF_Legendre.cpp.func.html | 89 + coverage/ves/BF_Legendre.cpp.gcov.html | 249 + coverage/ves/BF_Powers.cpp.func-sort-c.html | 89 + coverage/ves/BF_Powers.cpp.func.html | 89 + coverage/ves/BF_Powers.cpp.gcov.html | 222 + coverage/ves/BF_Sine.cpp.func-sort-c.html | 93 + coverage/ves/BF_Sine.cpp.func.html | 93 + coverage/ves/BF_Sine.cpp.gcov.html | 228 + coverage/ves/BF_Wavelets.cpp.func-sort-c.html | 93 + coverage/ves/BF_Wavelets.cpp.func.html | 93 + coverage/ves/BF_Wavelets.cpp.gcov.html | 495 + .../ves/BasisFunctions.cpp.func-sort-c.html | 157 + coverage/ves/BasisFunctions.cpp.func.html | 157 + coverage/ves/BasisFunctions.cpp.gcov.html | 482 + .../ves/BasisFunctions.h.func-sort-c.html | 105 + coverage/ves/BasisFunctions.h.func.html | 105 + coverage/ves/BasisFunctions.h.gcov.html | 394 + coverage/ves/CoeffsBase.cpp.func-sort-c.html | 201 + coverage/ves/CoeffsBase.cpp.func.html | 201 + coverage/ves/CoeffsBase.cpp.gcov.html | 594 + coverage/ves/CoeffsBase.h.func-sort-c.html | 81 + coverage/ves/CoeffsBase.h.func.html | 81 + coverage/ves/CoeffsBase.h.gcov.html | 336 + .../ves/CoeffsMatrix.cpp.func-sort-c.html | 389 + coverage/ves/CoeffsMatrix.cpp.func.html | 389 + coverage/ves/CoeffsMatrix.cpp.gcov.html | 792 + coverage/ves/CoeffsMatrix.h.func-sort-c.html | 73 + coverage/ves/CoeffsMatrix.h.func.html | 73 + coverage/ves/CoeffsMatrix.h.gcov.html | 288 + .../ves/CoeffsVector.cpp.func-sort-c.html | 469 + coverage/ves/CoeffsVector.cpp.func.html | 469 + coverage/ves/CoeffsVector.cpp.gcov.html | 972 + coverage/ves/CoeffsVector.h.func-sort-c.html | 73 + coverage/ves/CoeffsVector.h.func.html | 73 + coverage/ves/CoeffsVector.h.gcov.html | 317 + ...ermiSwitchingFunction.cpp.func-sort-c.html | 109 + .../ves/FermiSwitchingFunction.cpp.func.html | 109 + .../ves/FermiSwitchingFunction.cpp.gcov.html | 219 + ...ridIntegrationWeights.cpp.func-sort-c.html | 85 + .../ves/GridIntegrationWeights.cpp.func.html | 85 + .../ves/GridIntegrationWeights.cpp.gcov.html | 185 + ...idLinearInterpolation.cpp.func-sort-c.html | 109 + .../ves/GridLinearInterpolation.cpp.func.html | 109 + .../ves/GridLinearInterpolation.cpp.gcov.html | 312 + ...GridLinearInterpolation.h.func-sort-c.html | 77 + .../ves/GridLinearInterpolation.h.func.html | 77 + .../ves/GridLinearInterpolation.h.gcov.html | 159 + .../ves/GridProjWeights.h.func-sort-c.html | 89 + coverage/ves/GridProjWeights.h.func.html | 89 + coverage/ves/GridProjWeights.h.gcov.html | 127 + ...nearBasisSetExpansion.cpp.func-sort-c.html | 217 + .../ves/LinearBasisSetExpansion.cpp.func.html | 217 + .../ves/LinearBasisSetExpansion.cpp.gcov.html | 694 + ...LinearBasisSetExpansion.h.func-sort-c.html | 85 + .../ves/LinearBasisSetExpansion.h.func.html | 85 + .../ves/LinearBasisSetExpansion.h.gcov.html | 327 + ...MD_LinearExpansionPES.cpp.func-sort-c.html | 109 + .../ves/MD_LinearExpansionPES.cpp.func.html | 109 + .../ves/MD_LinearExpansionPES.cpp.gcov.html | 758 + coverage/ves/Opt_Adam.cpp.func-sort-c.html | 89 + coverage/ves/Opt_Adam.cpp.func.html | 89 + coverage/ves/Opt_Adam.cpp.gcov.html | 273 + .../Opt_BachAveragedSGD.cpp.func-sort-c.html | 89 + .../ves/Opt_BachAveragedSGD.cpp.func.html | 89 + .../ves/Opt_BachAveragedSGD.cpp.gcov.html | 379 + coverage/ves/Opt_Dummy.cpp.func-sort-c.html | 89 + coverage/ves/Opt_Dummy.cpp.func.html | 89 + coverage/ves/Opt_Dummy.cpp.gcov.html | 198 + .../Opt_RobbinsMonroSGD.cpp.func-sort-c.html | 89 + .../ves/Opt_RobbinsMonroSGD.cpp.func.html | 89 + .../ves/Opt_RobbinsMonroSGD.cpp.gcov.html | 173 + coverage/ves/Optimizer.cpp.func-sort-c.html | 201 + coverage/ves/Optimizer.cpp.func.html | 201 + coverage/ves/Optimizer.cpp.gcov.html | 1338 + coverage/ves/Optimizer.h.func-sort-c.html | 113 + coverage/ves/Optimizer.h.func.html | 113 + coverage/ves/Optimizer.h.gcov.html | 431 + .../OutputBasisFunctions.cpp.func-sort-c.html | 89 + .../ves/OutputBasisFunctions.cpp.func.html | 89 + .../ves/OutputBasisFunctions.cpp.gcov.html | 313 + .../ves/OutputFesBias.cpp.func-sort-c.html | 93 + coverage/ves/OutputFesBias.cpp.func.html | 93 + coverage/ves/OutputFesBias.cpp.gcov.html | 307 + ...putTargetDistribution.cpp.func-sort-c.html | 89 + .../OutputTargetDistribution.cpp.func.html | 89 + .../OutputTargetDistribution.cpp.gcov.html | 303 + coverage/ves/TD_Chi.cpp.func-sort-c.html | 85 + coverage/ves/TD_Chi.cpp.func.html | 85 + coverage/ves/TD_Chi.cpp.gcov.html | 230 + .../ves/TD_ChiSquared.cpp.func-sort-c.html | 85 + coverage/ves/TD_ChiSquared.cpp.func.html | 85 + coverage/ves/TD_ChiSquared.cpp.gcov.html | 229 + coverage/ves/TD_Custom.cpp.func-sort-c.html | 101 + coverage/ves/TD_Custom.cpp.func.html | 101 + coverage/ves/TD_Custom.cpp.gcov.html | 372 + .../ves/TD_Exponential.cpp.func-sort-c.html | 85 + coverage/ves/TD_Exponential.cpp.func.html | 85 + coverage/ves/TD_Exponential.cpp.gcov.html | 206 + ...iallyModifiedGaussian.cpp.func-sort-c.html | 89 + ...xponentiallyModifiedGaussian.cpp.func.html | 89 + ...xponentiallyModifiedGaussian.cpp.gcov.html | 301 + coverage/ves/TD_Gaussian.cpp.func-sort-c.html | 93 + coverage/ves/TD_Gaussian.cpp.func.html | 93 + coverage/ves/TD_Gaussian.cpp.gcov.html | 392 + ...neralizedExtremeValue.cpp.func-sort-c.html | 89 + .../TD_GeneralizedExtremeValue.cpp.func.html | 89 + .../TD_GeneralizedExtremeValue.cpp.gcov.html | 254 + .../TD_GeneralizedNormal.cpp.func-sort-c.html | 89 + .../ves/TD_GeneralizedNormal.cpp.func.html | 89 + .../ves/TD_GeneralizedNormal.cpp.gcov.html | 304 + coverage/ves/TD_Grid.cpp.func-sort-c.html | 85 + coverage/ves/TD_Grid.cpp.func.html | 85 + coverage/ves/TD_Grid.cpp.gcov.html | 295 + .../TD_LinearCombination.cpp.func-sort-c.html | 113 + .../ves/TD_LinearCombination.cpp.func.html | 113 + .../ves/TD_LinearCombination.cpp.gcov.html | 354 + .../TD_Multicanonical.cpp.func-sort-c.html | 97 + coverage/ves/TD_Multicanonical.cpp.func.html | 97 + coverage/ves/TD_Multicanonical.cpp.gcov.html | 551 + ...ultithermalMultibaric.cpp.func-sort-c.html | 97 + .../TD_MultithermalMultibaric.cpp.func.html | 97 + .../TD_MultithermalMultibaric.cpp.gcov.html | 534 + ...TD_ProductCombination.cpp.func-sort-c.html | 113 + .../ves/TD_ProductCombination.cpp.func.html | 113 + .../ves/TD_ProductCombination.cpp.gcov.html | 341 + ...D_ProductDistribution.cpp.func-sort-c.html | 113 + .../ves/TD_ProductDistribution.cpp.func.html | 113 + .../ves/TD_ProductDistribution.cpp.gcov.html | 302 + coverage/ves/TD_Uniform.cpp.func-sort-c.html | 89 + coverage/ves/TD_Uniform.cpp.func.html | 89 + coverage/ves/TD_Uniform.cpp.gcov.html | 382 + coverage/ves/TD_VonMises.cpp.func-sort-c.html | 93 + coverage/ves/TD_VonMises.cpp.func.html | 93 + coverage/ves/TD_VonMises.cpp.gcov.html | 316 + .../ves/TD_WellTempered.cpp.func-sort-c.html | 97 + coverage/ves/TD_WellTempered.cpp.func.html | 97 + coverage/ves/TD_WellTempered.cpp.gcov.html | 241 + .../ves/TargetDistModifer.h.func-sort-c.html | 77 + coverage/ves/TargetDistModifer.h.func.html | 77 + coverage/ves/TargetDistModifer.h.gcov.html | 130 + .../TargetDistribution.cpp.func-sort-c.html | 177 + coverage/ves/TargetDistribution.cpp.func.html | 177 + coverage/ves/TargetDistribution.cpp.gcov.html | 465 + .../ves/TargetDistribution.h.func-sort-c.html | 97 + coverage/ves/TargetDistribution.h.func.html | 97 + coverage/ves/TargetDistribution.h.gcov.html | 286 + coverage/ves/VesBias.cpp.func-sort-c.html | 253 + coverage/ves/VesBias.cpp.func.html | 253 + coverage/ves/VesBias.cpp.gcov.html | 830 + coverage/ves/VesBias.h.func-sort-c.html | 173 + coverage/ves/VesBias.h.func.html | 173 + coverage/ves/VesBias.h.gcov.html | 492 + coverage/ves/VesDeltaF.cpp.func-sort-c.html | 105 + coverage/ves/VesDeltaF.cpp.func.html | 105 + coverage/ves/VesDeltaF.cpp.gcov.html | 792 + .../VesLinearExpansion.cpp.func-sort-c.html | 157 + coverage/ves/VesLinearExpansion.cpp.func.html | 157 + coverage/ves/VesLinearExpansion.cpp.gcov.html | 634 + coverage/ves/VesTools.cpp.func-sort-c.html | 81 + coverage/ves/VesTools.cpp.func.html | 81 + coverage/ves/VesTools.cpp.gcov.html | 171 + coverage/ves/VesTools.h.func-sort-c.html | 93 + coverage/ves/VesTools.h.func.html | 93 + coverage/ves/VesTools.h.gcov.html | 217 + .../ves/WaveletCoeffs.cpp.func-sort-c.html | 77 + coverage/ves/WaveletCoeffs.cpp.func.html | 77 + coverage/ves/WaveletCoeffs.cpp.gcov.html | 1059 + coverage/ves/WaveletGrid.cpp.func-sort-c.html | 105 + coverage/ves/WaveletGrid.cpp.func.html | 105 + coverage/ves/WaveletGrid.cpp.gcov.html | 331 + coverage/ves/index-sort-f.html | 724 + coverage/ves/index-sort-l.html | 724 + coverage/ves/index.html | 724 + .../ActionWithAveraging.cpp.func-sort-c.html | 129 + .../ActionWithAveraging.cpp.func.html | 129 + .../ActionWithAveraging.cpp.gcov.html | 278 + .../ActionWithAveraging.h.func-sort-c.html | 101 + .../ActionWithAveraging.h.func.html | 101 + .../ActionWithAveraging.h.gcov.html | 213 + ...ActionWithInputVessel.cpp.func-sort-c.html | 97 + .../ActionWithInputVessel.cpp.func.html | 97 + .../ActionWithInputVessel.cpp.gcov.html | 165 + .../ActionWithInputVessel.h.func-sort-c.html | 77 + .../ActionWithInputVessel.h.func.html | 77 + .../ActionWithInputVessel.h.gcov.html | 147 + .../ActionWithVessel.cpp.func-sort-c.html | 177 + .../vesselbase/ActionWithVessel.cpp.func.html | 177 + .../vesselbase/ActionWithVessel.cpp.gcov.html | 472 + .../ActionWithVessel.h.func-sort-c.html | 97 + .../vesselbase/ActionWithVessel.h.func.html | 97 + .../vesselbase/ActionWithVessel.h.gcov.html | 368 + .../vesselbase/AltMin.cpp.func-sort-c.html | 109 + coverage/vesselbase/AltMin.cpp.func.html | 109 + coverage/vesselbase/AltMin.cpp.gcov.html | 154 + .../AveragingVessel.cpp.func-sort-c.html | 101 + .../vesselbase/AveragingVessel.cpp.func.html | 101 + .../vesselbase/AveragingVessel.cpp.gcov.html | 141 + .../AveragingVessel.h.func-sort-c.html | 81 + .../vesselbase/AveragingVessel.h.func.html | 81 + .../vesselbase/AveragingVessel.h.gcov.html | 178 + .../vesselbase/Between.cpp.func-sort-c.html | 109 + coverage/vesselbase/Between.cpp.func.html | 109 + coverage/vesselbase/Between.cpp.gcov.html | 156 + .../BridgeVessel.cpp.func-sort-c.html | 125 + .../vesselbase/BridgeVessel.cpp.func.html | 125 + .../vesselbase/BridgeVessel.cpp.gcov.html | 270 + .../BridgeVessel.h.func-sort-c.html | 73 + coverage/vesselbase/BridgeVessel.h.func.html | 73 + coverage/vesselbase/BridgeVessel.h.gcov.html | 168 + .../FunctionVessel.cpp.func-sort-c.html | 101 + .../vesselbase/FunctionVessel.cpp.func.html | 101 + .../vesselbase/FunctionVessel.cpp.gcov.html | 181 + .../FunctionVessel.h.func-sort-c.html | 73 + .../vesselbase/FunctionVessel.h.func.html | 73 + .../vesselbase/FunctionVessel.h.gcov.html | 143 + .../vesselbase/Highest.cpp.func-sort-c.html | 105 + coverage/vesselbase/Highest.cpp.func.html | 105 + coverage/vesselbase/Highest.cpp.gcov.html | 139 + .../vesselbase/Histogram.cpp.func-sort-c.html | 97 + coverage/vesselbase/Histogram.cpp.func.html | 97 + coverage/vesselbase/Histogram.cpp.gcov.html | 140 + .../vesselbase/LessThan.cpp.func-sort-c.html | 109 + coverage/vesselbase/LessThan.cpp.func.html | 109 + coverage/vesselbase/LessThan.cpp.gcov.html | 143 + .../vesselbase/Lowest.cpp.func-sort-c.html | 105 + coverage/vesselbase/Lowest.cpp.func.html | 105 + coverage/vesselbase/Lowest.cpp.gcov.html | 139 + coverage/vesselbase/Max.cpp.func-sort-c.html | 109 + coverage/vesselbase/Max.cpp.func.html | 109 + coverage/vesselbase/Max.cpp.gcov.html | 159 + coverage/vesselbase/Mean.cpp.func-sort-c.html | 105 + coverage/vesselbase/Mean.cpp.func.html | 105 + coverage/vesselbase/Mean.cpp.gcov.html | 143 + coverage/vesselbase/Min.cpp.func-sort-c.html | 109 + coverage/vesselbase/Min.cpp.func.html | 109 + coverage/vesselbase/Min.cpp.gcov.html | 159 + .../vesselbase/Moments.cpp.func-sort-c.html | 117 + coverage/vesselbase/Moments.cpp.func.html | 117 + coverage/vesselbase/Moments.cpp.gcov.html | 268 + .../vesselbase/MoreThan.cpp.func-sort-c.html | 105 + coverage/vesselbase/MoreThan.cpp.func.html | 105 + coverage/vesselbase/MoreThan.cpp.gcov.html | 153 + .../OrderingVessel.cpp.func-sort-c.html | 89 + .../vesselbase/OrderingVessel.cpp.func.html | 89 + .../vesselbase/OrderingVessel.cpp.gcov.html | 148 + .../OrderingVessel.h.func-sort-c.html | 77 + .../vesselbase/OrderingVessel.h.func.html | 77 + .../vesselbase/OrderingVessel.h.gcov.html | 127 + .../ShortcutVessel.cpp.func-sort-c.html | 85 + .../vesselbase/ShortcutVessel.cpp.func.html | 85 + .../vesselbase/ShortcutVessel.cpp.gcov.html | 124 + .../ShortcutVessel.h.func-sort-c.html | 93 + .../vesselbase/ShortcutVessel.h.func.html | 93 + .../vesselbase/ShortcutVessel.h.gcov.html | 127 + .../StoreDataVessel.cpp.func-sort-c.html | 133 + .../vesselbase/StoreDataVessel.cpp.func.html | 133 + .../vesselbase/StoreDataVessel.cpp.gcov.html | 256 + .../StoreDataVessel.h.func-sort-c.html | 101 + .../vesselbase/StoreDataVessel.h.func.html | 101 + .../vesselbase/StoreDataVessel.h.gcov.html | 287 + coverage/vesselbase/Sum.cpp.func-sort-c.html | 105 + coverage/vesselbase/Sum.cpp.func.html | 105 + coverage/vesselbase/Sum.cpp.gcov.html | 139 + .../ValueVessel.cpp.func-sort-c.html | 89 + coverage/vesselbase/ValueVessel.cpp.func.html | 89 + coverage/vesselbase/ValueVessel.cpp.gcov.html | 149 + .../vesselbase/ValueVessel.h.func-sort-c.html | 77 + coverage/vesselbase/ValueVessel.h.func.html | 77 + coverage/vesselbase/ValueVessel.h.gcov.html | 151 + .../vesselbase/Vessel.cpp.func-sort-c.html | 117 + coverage/vesselbase/Vessel.cpp.func.html | 117 + coverage/vesselbase/Vessel.cpp.gcov.html | 227 + coverage/vesselbase/Vessel.h.func-sort-c.html | 113 + coverage/vesselbase/Vessel.h.func.html | 113 + coverage/vesselbase/Vessel.h.gcov.html | 322 + .../VesselRegister.cpp.func-sort-c.html | 101 + .../vesselbase/VesselRegister.cpp.func.html | 101 + .../vesselbase/VesselRegister.cpp.gcov.html | 157 + coverage/vesselbase/index-sort-f.html | 434 + coverage/vesselbase/index-sort-l.html | 434 + coverage/vesselbase/index.html | 434 + coverage/wrapper/Plumed.h.func-sort-c.html | 1089 + coverage/wrapper/Plumed.h.func.html | 1089 + coverage/wrapper/Plumed.h.gcov.html | 4478 +++ coverage/wrapper/index-sort-f.html | 94 + coverage/wrapper/index-sort-l.html | 94 + coverage/wrapper/index.html | 94 + index.html | 14 + 2237 files changed, 513721 insertions(+) create mode 100644 .nojekyll create mode 100644 README.md create mode 100644 coverage-libs/amber.png create mode 100644 coverage-libs/asmjit/arch.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/arch.cpp.func.html create mode 100644 coverage-libs/asmjit/arch.cpp.gcov.html create mode 100644 coverage-libs/asmjit/arch.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/arch.h.func.html create mode 100644 coverage-libs/asmjit/arch.h.gcov.html create mode 100644 coverage-libs/asmjit/assembler.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/assembler.cpp.func.html create mode 100644 coverage-libs/asmjit/assembler.cpp.gcov.html create mode 100644 coverage-libs/asmjit/assembler.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/assembler.h.func.html create mode 100644 coverage-libs/asmjit/assembler.h.gcov.html create mode 100644 coverage-libs/asmjit/codebuilder.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/codebuilder.cpp.func.html create mode 100644 coverage-libs/asmjit/codebuilder.cpp.gcov.html create mode 100644 coverage-libs/asmjit/codebuilder.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/codebuilder.h.func.html create mode 100644 coverage-libs/asmjit/codebuilder.h.gcov.html create mode 100644 coverage-libs/asmjit/codecompiler.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/codecompiler.cpp.func.html create mode 100644 coverage-libs/asmjit/codecompiler.cpp.gcov.html create mode 100644 coverage-libs/asmjit/codecompiler.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/codecompiler.h.func.html create mode 100644 coverage-libs/asmjit/codecompiler.h.gcov.html create mode 100644 coverage-libs/asmjit/codeemitter.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/codeemitter.cpp.func.html create mode 100644 coverage-libs/asmjit/codeemitter.cpp.gcov.html create mode 100644 coverage-libs/asmjit/codeemitter.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/codeemitter.h.func.html create mode 100644 coverage-libs/asmjit/codeemitter.h.gcov.html create mode 100644 coverage-libs/asmjit/codeholder.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/codeholder.cpp.func.html create mode 100644 coverage-libs/asmjit/codeholder.cpp.gcov.html create mode 100644 coverage-libs/asmjit/codeholder.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/codeholder.h.func.html create mode 100644 coverage-libs/asmjit/codeholder.h.gcov.html create mode 100644 coverage-libs/asmjit/constpool.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/constpool.cpp.func.html create mode 100644 coverage-libs/asmjit/constpool.cpp.gcov.html create mode 100644 coverage-libs/asmjit/constpool.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/constpool.h.func.html create mode 100644 coverage-libs/asmjit/constpool.h.gcov.html create mode 100644 coverage-libs/asmjit/cpuinfo.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/cpuinfo.cpp.func.html create mode 100644 coverage-libs/asmjit/cpuinfo.cpp.gcov.html create mode 100644 coverage-libs/asmjit/cpuinfo.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/cpuinfo.h.func.html create mode 100644 coverage-libs/asmjit/cpuinfo.h.gcov.html create mode 100644 coverage-libs/asmjit/func.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/func.cpp.func.html create mode 100644 coverage-libs/asmjit/func.cpp.gcov.html create mode 100644 coverage-libs/asmjit/func.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/func.h.func.html create mode 100644 coverage-libs/asmjit/func.h.gcov.html create mode 100644 coverage-libs/asmjit/globals.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/globals.cpp.func.html create mode 100644 coverage-libs/asmjit/globals.cpp.gcov.html create mode 100644 coverage-libs/asmjit/globals.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/globals.h.func.html create mode 100644 coverage-libs/asmjit/globals.h.gcov.html create mode 100644 coverage-libs/asmjit/index-sort-f.html create mode 100644 coverage-libs/asmjit/index-sort-l.html create mode 100644 coverage-libs/asmjit/index.html create mode 100644 coverage-libs/asmjit/inst.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/inst.cpp.func.html create mode 100644 coverage-libs/asmjit/inst.cpp.gcov.html create mode 100644 coverage-libs/asmjit/inst.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/inst.h.func.html create mode 100644 coverage-libs/asmjit/inst.h.gcov.html create mode 100644 coverage-libs/asmjit/logging.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/logging.cpp.func.html create mode 100644 coverage-libs/asmjit/logging.cpp.gcov.html create mode 100644 coverage-libs/asmjit/logging.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/logging.h.func.html create mode 100644 coverage-libs/asmjit/logging.h.gcov.html create mode 100644 coverage-libs/asmjit/moved_string.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/moved_string.h.func.html create mode 100644 coverage-libs/asmjit/moved_string.h.gcov.html create mode 100644 coverage-libs/asmjit/operand.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/operand.h.func.html create mode 100644 coverage-libs/asmjit/operand.h.gcov.html create mode 100644 coverage-libs/asmjit/osutils.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/osutils.cpp.func.html create mode 100644 coverage-libs/asmjit/osutils.cpp.gcov.html create mode 100644 coverage-libs/asmjit/osutils.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/osutils.h.func.html create mode 100644 coverage-libs/asmjit/osutils.h.gcov.html create mode 100644 coverage-libs/asmjit/regalloc.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/regalloc.cpp.func.html create mode 100644 coverage-libs/asmjit/regalloc.cpp.gcov.html create mode 100644 coverage-libs/asmjit/regalloc_p.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/regalloc_p.h.func.html create mode 100644 coverage-libs/asmjit/regalloc_p.h.gcov.html create mode 100644 coverage-libs/asmjit/runtime.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/runtime.cpp.func.html create mode 100644 coverage-libs/asmjit/runtime.cpp.gcov.html create mode 100644 coverage-libs/asmjit/runtime.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/runtime.h.func.html create mode 100644 coverage-libs/asmjit/runtime.h.gcov.html create mode 100644 coverage-libs/asmjit/string.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/string.cpp.func.html create mode 100644 coverage-libs/asmjit/string.cpp.gcov.html create mode 100644 coverage-libs/asmjit/utils.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/utils.h.func.html create mode 100644 coverage-libs/asmjit/utils.h.gcov.html create mode 100644 coverage-libs/asmjit/vmem.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/vmem.cpp.func.html create mode 100644 coverage-libs/asmjit/vmem.cpp.gcov.html create mode 100644 coverage-libs/asmjit/x86assembler.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86assembler.cpp.func.html create mode 100644 coverage-libs/asmjit/x86assembler.cpp.gcov.html create mode 100644 coverage-libs/asmjit/x86assembler.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86assembler.h.func.html create mode 100644 coverage-libs/asmjit/x86assembler.h.gcov.html create mode 100644 coverage-libs/asmjit/x86builder.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86builder.cpp.func.html create mode 100644 coverage-libs/asmjit/x86builder.cpp.gcov.html create mode 100644 coverage-libs/asmjit/x86compiler.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86compiler.cpp.func.html create mode 100644 coverage-libs/asmjit/x86compiler.cpp.gcov.html create mode 100644 coverage-libs/asmjit/x86compiler.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86compiler.h.func.html create mode 100644 coverage-libs/asmjit/x86compiler.h.gcov.html create mode 100644 coverage-libs/asmjit/x86emitter.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86emitter.h.func.html create mode 100644 coverage-libs/asmjit/x86emitter.h.gcov.html create mode 100644 coverage-libs/asmjit/x86inst.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86inst.cpp.func.html create mode 100644 coverage-libs/asmjit/x86inst.cpp.gcov.html create mode 100644 coverage-libs/asmjit/x86inst.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86inst.h.func.html create mode 100644 coverage-libs/asmjit/x86inst.h.gcov.html create mode 100644 coverage-libs/asmjit/x86instimpl.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86instimpl.cpp.func.html create mode 100644 coverage-libs/asmjit/x86instimpl.cpp.gcov.html create mode 100644 coverage-libs/asmjit/x86internal.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86internal.cpp.func.html create mode 100644 coverage-libs/asmjit/x86internal.cpp.gcov.html create mode 100644 coverage-libs/asmjit/x86logging.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86logging.cpp.func.html create mode 100644 coverage-libs/asmjit/x86logging.cpp.gcov.html create mode 100644 coverage-libs/asmjit/x86misc.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86misc.h.func.html create mode 100644 coverage-libs/asmjit/x86misc.h.gcov.html create mode 100644 coverage-libs/asmjit/x86operand.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86operand.h.func.html create mode 100644 coverage-libs/asmjit/x86operand.h.gcov.html create mode 100644 coverage-libs/asmjit/x86regalloc.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86regalloc.cpp.func.html create mode 100644 coverage-libs/asmjit/x86regalloc.cpp.gcov.html create mode 100644 coverage-libs/asmjit/x86regalloc_p.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/x86regalloc_p.h.func.html create mode 100644 coverage-libs/asmjit/x86regalloc_p.h.gcov.html create mode 100644 coverage-libs/asmjit/zone.cpp.func-sort-c.html create mode 100644 coverage-libs/asmjit/zone.cpp.func.html create mode 100644 coverage-libs/asmjit/zone.cpp.gcov.html create mode 100644 coverage-libs/asmjit/zone.h.func-sort-c.html create mode 100644 coverage-libs/asmjit/zone.h.func.html create mode 100644 coverage-libs/asmjit/zone.h.gcov.html create mode 100644 coverage-libs/blas/blas.cpp.func-sort-c.html create mode 100644 coverage-libs/blas/blas.cpp.func.html create mode 100644 coverage-libs/blas/blas.cpp.gcov.html create mode 100644 coverage-libs/blas/index-sort-f.html create mode 100644 coverage-libs/blas/index-sort-l.html create mode 100644 coverage-libs/blas/index.html create mode 100644 coverage-libs/emerald.png create mode 100644 coverage-libs/gcov.css create mode 100644 coverage-libs/glass.png create mode 100644 coverage-libs/index-sort-f.html create mode 100644 coverage-libs/index-sort-l.html create mode 100644 coverage-libs/index.html create mode 100644 coverage-libs/lapack/index-sort-f.html create mode 100644 coverage-libs/lapack/index-sort-l.html create mode 100644 coverage-libs/lapack/index.html create mode 100644 coverage-libs/lapack/lapack.cpp.func-sort-c.html create mode 100644 coverage-libs/lapack/lapack.cpp.func.html create mode 100644 coverage-libs/lapack/lapack.cpp.gcov.html create mode 100644 coverage-libs/lepton/CompiledExpression.cpp.func-sort-c.html create mode 100644 coverage-libs/lepton/CompiledExpression.cpp.func.html create mode 100644 coverage-libs/lepton/CompiledExpression.cpp.gcov.html create mode 100644 coverage-libs/lepton/CompiledExpression.h.func-sort-c.html create mode 100644 coverage-libs/lepton/CompiledExpression.h.func.html create mode 100644 coverage-libs/lepton/CompiledExpression.h.gcov.html create mode 100644 coverage-libs/lepton/Exception.h.func-sort-c.html create mode 100644 coverage-libs/lepton/Exception.h.func.html create mode 100644 coverage-libs/lepton/Exception.h.gcov.html create mode 100644 coverage-libs/lepton/ExpressionProgram.cpp.func-sort-c.html create mode 100644 coverage-libs/lepton/ExpressionProgram.cpp.func.html create mode 100644 coverage-libs/lepton/ExpressionProgram.cpp.gcov.html create mode 100644 coverage-libs/lepton/ExpressionTreeNode.cpp.func-sort-c.html create mode 100644 coverage-libs/lepton/ExpressionTreeNode.cpp.func.html create mode 100644 coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html create mode 100644 coverage-libs/lepton/Operation.cpp.func-sort-c.html create mode 100644 coverage-libs/lepton/Operation.cpp.func.html create mode 100644 coverage-libs/lepton/Operation.cpp.gcov.html create mode 100644 coverage-libs/lepton/Operation.h.func-sort-c.html create mode 100644 coverage-libs/lepton/Operation.h.func.html create mode 100644 coverage-libs/lepton/Operation.h.gcov.html create mode 100644 coverage-libs/lepton/ParsedExpression.cpp.func-sort-c.html create mode 100644 coverage-libs/lepton/ParsedExpression.cpp.func.html create mode 100644 coverage-libs/lepton/ParsedExpression.cpp.gcov.html create mode 100644 coverage-libs/lepton/ParsedExpression.h.func-sort-c.html create mode 100644 coverage-libs/lepton/ParsedExpression.h.func.html create mode 100644 coverage-libs/lepton/ParsedExpression.h.gcov.html create mode 100644 coverage-libs/lepton/Parser.cpp.func-sort-c.html create mode 100644 coverage-libs/lepton/Parser.cpp.func.html create mode 100644 coverage-libs/lepton/Parser.cpp.gcov.html create mode 100644 coverage-libs/lepton/index-sort-f.html create mode 100644 coverage-libs/lepton/index-sort-l.html create mode 100644 coverage-libs/lepton/index.html create mode 100644 coverage-libs/molfile/Gromacs.h.func-sort-c.html create mode 100644 coverage-libs/molfile/Gromacs.h.func.html create mode 100644 coverage-libs/molfile/Gromacs.h.gcov.html create mode 100644 coverage-libs/molfile/crdplugin.cpp.func-sort-c.html create mode 100644 coverage-libs/molfile/crdplugin.cpp.func.html create mode 100644 coverage-libs/molfile/crdplugin.cpp.gcov.html create mode 100644 coverage-libs/molfile/dcdplugin.cpp.func-sort-c.html create mode 100644 coverage-libs/molfile/dcdplugin.cpp.func.html create mode 100644 coverage-libs/molfile/dcdplugin.cpp.gcov.html create mode 100644 coverage-libs/molfile/endianswap.h.func-sort-c.html create mode 100644 coverage-libs/molfile/endianswap.h.func.html create mode 100644 coverage-libs/molfile/endianswap.h.gcov.html create mode 100644 coverage-libs/molfile/fastio.h.func-sort-c.html create mode 100644 coverage-libs/molfile/fastio.h.func.html create mode 100644 coverage-libs/molfile/fastio.h.gcov.html create mode 100644 coverage-libs/molfile/gromacsplugin.cpp.func-sort-c.html create mode 100644 coverage-libs/molfile/gromacsplugin.cpp.func.html create mode 100644 coverage-libs/molfile/gromacsplugin.cpp.gcov.html create mode 100644 coverage-libs/molfile/index-sort-f.html create mode 100644 coverage-libs/molfile/index-sort-l.html create mode 100644 coverage-libs/molfile/index.html create mode 100644 coverage-libs/molfile/pdbplugin.cpp.func-sort-c.html create mode 100644 coverage-libs/molfile/pdbplugin.cpp.func.html create mode 100644 coverage-libs/molfile/pdbplugin.cpp.gcov.html create mode 100644 coverage-libs/molfile/periodic_table.h.func-sort-c.html create mode 100644 coverage-libs/molfile/periodic_table.h.func.html create mode 100644 coverage-libs/molfile/periodic_table.h.gcov.html create mode 100644 coverage-libs/molfile/readpdb.h.func-sort-c.html create mode 100644 coverage-libs/molfile/readpdb.h.func.html create mode 100644 coverage-libs/molfile/readpdb.h.gcov.html create mode 100644 coverage-libs/ruby.png create mode 100644 coverage-libs/snow.png create mode 100644 coverage-libs/updown.png create mode 100644 coverage-libs/xdrfile/index-sort-f.html create mode 100644 coverage-libs/xdrfile/index-sort-l.html create mode 100644 coverage-libs/xdrfile/index.html create mode 100644 coverage-libs/xdrfile/xdrfile.cpp.func-sort-c.html create mode 100644 coverage-libs/xdrfile/xdrfile.cpp.func.html create mode 100644 coverage-libs/xdrfile/xdrfile.cpp.gcov.html create mode 100644 coverage-libs/xdrfile/xdrfile_trr.cpp.func-sort-c.html create mode 100644 coverage-libs/xdrfile/xdrfile_trr.cpp.func.html create mode 100644 coverage-libs/xdrfile/xdrfile_trr.cpp.gcov.html create mode 100644 coverage-libs/xdrfile/xdrfile_xtc.cpp.func-sort-c.html create mode 100644 coverage-libs/xdrfile/xdrfile_xtc.cpp.func.html create mode 100644 coverage-libs/xdrfile/xdrfile_xtc.cpp.gcov.html create mode 100644 coverage/adjmat/ActionWithInputMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ActionWithInputMatrix.cpp.func.html create mode 100644 coverage/adjmat/ActionWithInputMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/ActionWithInputMatrix.h.func-sort-c.html create mode 100644 coverage/adjmat/ActionWithInputMatrix.h.func.html create mode 100644 coverage/adjmat/ActionWithInputMatrix.h.gcov.html create mode 100644 coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html create mode 100644 coverage/adjmat/AdjacencyMatrixBase.cpp.func.html create mode 100644 coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html create mode 100644 coverage/adjmat/AdjacencyMatrixBase.h.func-sort-c.html create mode 100644 coverage/adjmat/AdjacencyMatrixBase.h.func.html create mode 100644 coverage/adjmat/AdjacencyMatrixBase.h.gcov.html create mode 100644 coverage/adjmat/AdjacencyMatrixVessel.cpp.func-sort-c.html create mode 100644 coverage/adjmat/AdjacencyMatrixVessel.cpp.func.html create mode 100644 coverage/adjmat/AdjacencyMatrixVessel.cpp.gcov.html create mode 100644 coverage/adjmat/AlignedMatrixBase.cpp.func-sort-c.html create mode 100644 coverage/adjmat/AlignedMatrixBase.cpp.func.html create mode 100644 coverage/adjmat/AlignedMatrixBase.cpp.gcov.html create mode 100644 coverage/adjmat/ClusterAnalysisBase.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ClusterAnalysisBase.cpp.func.html create mode 100644 coverage/adjmat/ClusterAnalysisBase.cpp.gcov.html create mode 100644 coverage/adjmat/ClusterAnalysisBase.h.func-sort-c.html create mode 100644 coverage/adjmat/ClusterAnalysisBase.h.func.html create mode 100644 coverage/adjmat/ClusterAnalysisBase.h.gcov.html create mode 100644 coverage/adjmat/ClusterDiameter.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ClusterDiameter.cpp.func.html create mode 100644 coverage/adjmat/ClusterDiameter.cpp.gcov.html create mode 100644 coverage/adjmat/ClusterDistribution.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ClusterDistribution.cpp.func.html create mode 100644 coverage/adjmat/ClusterDistribution.cpp.gcov.html create mode 100644 coverage/adjmat/ClusterProperties.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ClusterProperties.cpp.func.html create mode 100644 coverage/adjmat/ClusterProperties.cpp.gcov.html create mode 100644 coverage/adjmat/ClusterSize.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ClusterSize.cpp.func.html create mode 100644 coverage/adjmat/ClusterSize.cpp.gcov.html create mode 100644 coverage/adjmat/ClusterWithSurface.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ClusterWithSurface.cpp.func.html create mode 100644 coverage/adjmat/ClusterWithSurface.cpp.gcov.html create mode 100644 coverage/adjmat/ClusteringBase.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ClusteringBase.cpp.func.html create mode 100644 coverage/adjmat/ClusteringBase.cpp.gcov.html create mode 100644 coverage/adjmat/ClusteringBase.h.func-sort-c.html create mode 100644 coverage/adjmat/ClusteringBase.h.func.html create mode 100644 coverage/adjmat/ClusteringBase.h.gcov.html create mode 100644 coverage/adjmat/ContactAlignedMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ContactAlignedMatrix.cpp.func.html create mode 100644 coverage/adjmat/ContactAlignedMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/ContactMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/ContactMatrix.cpp.func.html create mode 100644 coverage/adjmat/ContactMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/DFSClustering.cpp.func-sort-c.html create mode 100644 coverage/adjmat/DFSClustering.cpp.func.html create mode 100644 coverage/adjmat/DFSClustering.cpp.gcov.html create mode 100644 coverage/adjmat/DumpGraph.cpp.func-sort-c.html create mode 100644 coverage/adjmat/DumpGraph.cpp.func.html create mode 100644 coverage/adjmat/DumpGraph.cpp.gcov.html create mode 100644 coverage/adjmat/HbondMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/HbondMatrix.cpp.func.html create mode 100644 coverage/adjmat/HbondMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/MatrixColumnSums.cpp.func-sort-c.html create mode 100644 coverage/adjmat/MatrixColumnSums.cpp.func.html create mode 100644 coverage/adjmat/MatrixColumnSums.cpp.gcov.html create mode 100644 coverage/adjmat/MatrixRowSums.cpp.func-sort-c.html create mode 100644 coverage/adjmat/MatrixRowSums.cpp.func.html create mode 100644 coverage/adjmat/MatrixRowSums.cpp.gcov.html create mode 100644 coverage/adjmat/OutputCluster.cpp.func-sort-c.html create mode 100644 coverage/adjmat/OutputCluster.cpp.func.html create mode 100644 coverage/adjmat/OutputCluster.cpp.gcov.html create mode 100644 coverage/adjmat/SMACMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/SMACMatrix.cpp.func.html create mode 100644 coverage/adjmat/SMACMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/Sprint.cpp.func-sort-c.html create mode 100644 coverage/adjmat/Sprint.cpp.func.html create mode 100644 coverage/adjmat/Sprint.cpp.gcov.html create mode 100644 coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html create mode 100644 coverage/adjmat/TopologyMatrix.cpp.func.html create mode 100644 coverage/adjmat/TopologyMatrix.cpp.gcov.html create mode 100644 coverage/adjmat/index-sort-f.html create mode 100644 coverage/adjmat/index-sort-l.html create mode 100644 coverage/adjmat/index.html create mode 100644 coverage/amber.png create mode 100644 coverage/analysis/AnalysisBase.cpp.func-sort-c.html create mode 100644 coverage/analysis/AnalysisBase.cpp.func.html create mode 100644 coverage/analysis/AnalysisBase.cpp.gcov.html create mode 100644 coverage/analysis/AnalysisBase.h.func-sort-c.html create mode 100644 coverage/analysis/AnalysisBase.h.func.html create mode 100644 coverage/analysis/AnalysisBase.h.gcov.html create mode 100644 coverage/analysis/Average.cpp.func-sort-c.html create mode 100644 coverage/analysis/Average.cpp.func.html create mode 100644 coverage/analysis/Average.cpp.gcov.html create mode 100644 coverage/analysis/AverageVessel.cpp.func-sort-c.html create mode 100644 coverage/analysis/AverageVessel.cpp.func.html create mode 100644 coverage/analysis/AverageVessel.cpp.gcov.html create mode 100644 coverage/analysis/AverageVessel.h.func-sort-c.html create mode 100644 coverage/analysis/AverageVessel.h.func.html create mode 100644 coverage/analysis/AverageVessel.h.gcov.html create mode 100644 coverage/analysis/Committor.cpp.func-sort-c.html create mode 100644 coverage/analysis/Committor.cpp.func.html create mode 100644 coverage/analysis/Committor.cpp.gcov.html create mode 100644 coverage/analysis/DataCollectionObject.cpp.func-sort-c.html create mode 100644 coverage/analysis/DataCollectionObject.cpp.func.html create mode 100644 coverage/analysis/DataCollectionObject.cpp.gcov.html create mode 100644 coverage/analysis/DataCollectionObject.h.func-sort-c.html create mode 100644 coverage/analysis/DataCollectionObject.h.func.html create mode 100644 coverage/analysis/DataCollectionObject.h.gcov.html create mode 100644 coverage/analysis/EuclideanDissimilarityMatrix.cpp.func-sort-c.html create mode 100644 coverage/analysis/EuclideanDissimilarityMatrix.cpp.func.html create mode 100644 coverage/analysis/EuclideanDissimilarityMatrix.cpp.gcov.html create mode 100644 coverage/analysis/FarthestPointSampling.cpp.func-sort-c.html create mode 100644 coverage/analysis/FarthestPointSampling.cpp.func.html create mode 100644 coverage/analysis/FarthestPointSampling.cpp.gcov.html create mode 100644 coverage/analysis/Histogram.cpp.func-sort-c.html create mode 100644 coverage/analysis/Histogram.cpp.func.html create mode 100644 coverage/analysis/Histogram.cpp.gcov.html create mode 100644 coverage/analysis/LandmarkSelectionBase.cpp.func-sort-c.html create mode 100644 coverage/analysis/LandmarkSelectionBase.cpp.func.html create mode 100644 coverage/analysis/LandmarkSelectionBase.cpp.gcov.html create mode 100644 coverage/analysis/LandmarkSelectionBase.h.func-sort-c.html create mode 100644 coverage/analysis/LandmarkSelectionBase.h.func.html create mode 100644 coverage/analysis/LandmarkSelectionBase.h.gcov.html create mode 100644 coverage/analysis/LandmarkStaged.cpp.func-sort-c.html create mode 100644 coverage/analysis/LandmarkStaged.cpp.func.html create mode 100644 coverage/analysis/LandmarkStaged.cpp.gcov.html create mode 100644 coverage/analysis/OutputColvarFile.cpp.func-sort-c.html create mode 100644 coverage/analysis/OutputColvarFile.cpp.func.html create mode 100644 coverage/analysis/OutputColvarFile.cpp.gcov.html create mode 100644 coverage/analysis/OutputPDBFile.cpp.func-sort-c.html create mode 100644 coverage/analysis/OutputPDBFile.cpp.func.html create mode 100644 coverage/analysis/OutputPDBFile.cpp.gcov.html create mode 100644 coverage/analysis/PrintDissimilarityMatrix.cpp.func-sort-c.html create mode 100644 coverage/analysis/PrintDissimilarityMatrix.cpp.func.html create mode 100644 coverage/analysis/PrintDissimilarityMatrix.cpp.gcov.html create mode 100644 coverage/analysis/ReadAnalysisFrames.cpp.func-sort-c.html create mode 100644 coverage/analysis/ReadAnalysisFrames.cpp.func.html create mode 100644 coverage/analysis/ReadAnalysisFrames.cpp.gcov.html create mode 100644 coverage/analysis/ReadAnalysisFrames.h.func-sort-c.html create mode 100644 coverage/analysis/ReadAnalysisFrames.h.func.html create mode 100644 coverage/analysis/ReadAnalysisFrames.h.gcov.html create mode 100644 coverage/analysis/ReadDissimilarityMatrix.cpp.func-sort-c.html create mode 100644 coverage/analysis/ReadDissimilarityMatrix.cpp.func.html create mode 100644 coverage/analysis/ReadDissimilarityMatrix.cpp.gcov.html create mode 100644 coverage/analysis/ReselectLandmarks.cpp.func-sort-c.html create mode 100644 coverage/analysis/ReselectLandmarks.cpp.func.html create mode 100644 coverage/analysis/ReselectLandmarks.cpp.gcov.html create mode 100644 coverage/analysis/SelectRandomFrames.cpp.func-sort-c.html create mode 100644 coverage/analysis/SelectRandomFrames.cpp.func.html create mode 100644 coverage/analysis/SelectRandomFrames.cpp.gcov.html create mode 100644 coverage/analysis/SelectWithStride.cpp.func-sort-c.html create mode 100644 coverage/analysis/SelectWithStride.cpp.func.html create mode 100644 coverage/analysis/SelectWithStride.cpp.gcov.html create mode 100644 coverage/analysis/WhamHistogram.cpp.func-sort-c.html create mode 100644 coverage/analysis/WhamHistogram.cpp.func.html create mode 100644 coverage/analysis/WhamHistogram.cpp.gcov.html create mode 100644 coverage/analysis/WhamWeights.cpp.func-sort-c.html create mode 100644 coverage/analysis/WhamWeights.cpp.func.html create mode 100644 coverage/analysis/WhamWeights.cpp.gcov.html create mode 100644 coverage/analysis/index-sort-f.html create mode 100644 coverage/analysis/index-sort-l.html create mode 100644 coverage/analysis/index.html create mode 100644 coverage/annfunc/ANN.cpp.func-sort-c.html create mode 100644 coverage/annfunc/ANN.cpp.func.html create mode 100644 coverage/annfunc/ANN.cpp.gcov.html create mode 100644 coverage/annfunc/index-sort-f.html create mode 100644 coverage/annfunc/index-sort-l.html create mode 100644 coverage/annfunc/index.html create mode 100644 coverage/bias/ABMD.cpp.func-sort-c.html create mode 100644 coverage/bias/ABMD.cpp.func.html create mode 100644 coverage/bias/ABMD.cpp.gcov.html create mode 100644 coverage/bias/Bias.cpp.func-sort-c.html create mode 100644 coverage/bias/Bias.cpp.func.html create mode 100644 coverage/bias/Bias.cpp.gcov.html create mode 100644 coverage/bias/Bias.h.func-sort-c.html create mode 100644 coverage/bias/Bias.h.func.html create mode 100644 coverage/bias/Bias.h.gcov.html create mode 100644 coverage/bias/BiasValue.cpp.func-sort-c.html create mode 100644 coverage/bias/BiasValue.cpp.func.html create mode 100644 coverage/bias/BiasValue.cpp.gcov.html create mode 100644 coverage/bias/ExtendedLagrangian.cpp.func-sort-c.html create mode 100644 coverage/bias/ExtendedLagrangian.cpp.func.html create mode 100644 coverage/bias/ExtendedLagrangian.cpp.gcov.html create mode 100644 coverage/bias/External.cpp.func-sort-c.html create mode 100644 coverage/bias/External.cpp.func.html create mode 100644 coverage/bias/External.cpp.gcov.html create mode 100644 coverage/bias/LWalls.cpp.func-sort-c.html create mode 100644 coverage/bias/LWalls.cpp.func.html create mode 100644 coverage/bias/LWalls.cpp.gcov.html create mode 100644 coverage/bias/MaxEnt.cpp.func-sort-c.html create mode 100644 coverage/bias/MaxEnt.cpp.func.html create mode 100644 coverage/bias/MaxEnt.cpp.gcov.html create mode 100644 coverage/bias/MetaD.cpp.func-sort-c.html create mode 100644 coverage/bias/MetaD.cpp.func.html create mode 100644 coverage/bias/MetaD.cpp.gcov.html create mode 100644 coverage/bias/MovingRestraint.cpp.func-sort-c.html create mode 100644 coverage/bias/MovingRestraint.cpp.func.html create mode 100644 coverage/bias/MovingRestraint.cpp.gcov.html create mode 100644 coverage/bias/PBMetaD.cpp.func-sort-c.html create mode 100644 coverage/bias/PBMetaD.cpp.func.html create mode 100644 coverage/bias/PBMetaD.cpp.gcov.html create mode 100644 coverage/bias/Restraint.cpp.func-sort-c.html create mode 100644 coverage/bias/Restraint.cpp.func.html create mode 100644 coverage/bias/Restraint.cpp.gcov.html create mode 100644 coverage/bias/ReweightBase.cpp.func-sort-c.html create mode 100644 coverage/bias/ReweightBase.cpp.func.html create mode 100644 coverage/bias/ReweightBase.cpp.gcov.html create mode 100644 coverage/bias/ReweightBase.h.func-sort-c.html create mode 100644 coverage/bias/ReweightBase.h.func.html create mode 100644 coverage/bias/ReweightBase.h.gcov.html create mode 100644 coverage/bias/ReweightBias.cpp.func-sort-c.html create mode 100644 coverage/bias/ReweightBias.cpp.func.html create mode 100644 coverage/bias/ReweightBias.cpp.gcov.html create mode 100644 coverage/bias/ReweightMetad.cpp.func-sort-c.html create mode 100644 coverage/bias/ReweightMetad.cpp.func.html create mode 100644 coverage/bias/ReweightMetad.cpp.gcov.html create mode 100644 coverage/bias/ReweightTemperaturePressure.cpp.func-sort-c.html create mode 100644 coverage/bias/ReweightTemperaturePressure.cpp.func.html create mode 100644 coverage/bias/ReweightTemperaturePressure.cpp.gcov.html create mode 100644 coverage/bias/ReweightWham.cpp.func-sort-c.html create mode 100644 coverage/bias/ReweightWham.cpp.func.html create mode 100644 coverage/bias/ReweightWham.cpp.gcov.html create mode 100644 coverage/bias/UWalls.cpp.func-sort-c.html create mode 100644 coverage/bias/UWalls.cpp.func.html create mode 100644 coverage/bias/UWalls.cpp.gcov.html create mode 100644 coverage/bias/index-sort-f.html create mode 100644 coverage/bias/index-sort-l.html create mode 100644 coverage/bias/index.html create mode 100644 coverage/cltools/Benchmark.cpp.func-sort-c.html create mode 100644 coverage/cltools/Benchmark.cpp.func.html create mode 100644 coverage/cltools/Benchmark.cpp.gcov.html create mode 100644 coverage/cltools/Completion.cpp.func-sort-c.html create mode 100644 coverage/cltools/Completion.cpp.func.html create mode 100644 coverage/cltools/Completion.cpp.gcov.html create mode 100644 coverage/cltools/Driver.cpp.func-sort-c.html create mode 100644 coverage/cltools/Driver.cpp.func.html create mode 100644 coverage/cltools/Driver.cpp.gcov.html create mode 100644 coverage/cltools/DriverDouble.cpp.func-sort-c.html create mode 100644 coverage/cltools/DriverDouble.cpp.func.html create mode 100644 coverage/cltools/DriverDouble.cpp.gcov.html create mode 100644 coverage/cltools/DriverFloat.cpp.func-sort-c.html create mode 100644 coverage/cltools/DriverFloat.cpp.func.html create mode 100644 coverage/cltools/DriverFloat.cpp.gcov.html create mode 100644 coverage/cltools/GenExample.cpp.func-sort-c.html create mode 100644 coverage/cltools/GenExample.cpp.func.html create mode 100644 coverage/cltools/GenExample.cpp.gcov.html create mode 100644 coverage/cltools/GenJson.cpp.func-sort-c.html create mode 100644 coverage/cltools/GenJson.cpp.func.html create mode 100644 coverage/cltools/GenJson.cpp.gcov.html create mode 100644 coverage/cltools/GenTemplate.cpp.func-sort-c.html create mode 100644 coverage/cltools/GenTemplate.cpp.func.html create mode 100644 coverage/cltools/GenTemplate.cpp.gcov.html create mode 100644 coverage/cltools/Info.cpp.func-sort-c.html create mode 100644 coverage/cltools/Info.cpp.func.html create mode 100644 coverage/cltools/Info.cpp.gcov.html create mode 100644 coverage/cltools/Manual.cpp.func-sort-c.html create mode 100644 coverage/cltools/Manual.cpp.func.html create mode 100644 coverage/cltools/Manual.cpp.gcov.html create mode 100644 coverage/cltools/PdbRenumber.cpp.func-sort-c.html create mode 100644 coverage/cltools/PdbRenumber.cpp.func.html create mode 100644 coverage/cltools/PdbRenumber.cpp.gcov.html create mode 100644 coverage/cltools/SimpleMD.cpp.func-sort-c.html create mode 100644 coverage/cltools/SimpleMD.cpp.func.html create mode 100644 coverage/cltools/SimpleMD.cpp.gcov.html create mode 100644 coverage/cltools/SumHills.cpp.func-sort-c.html create mode 100644 coverage/cltools/SumHills.cpp.func.html create mode 100644 coverage/cltools/SumHills.cpp.gcov.html create mode 100644 coverage/cltools/index-sort-f.html create mode 100644 coverage/cltools/index-sort-l.html create mode 100644 coverage/cltools/index.html create mode 100644 coverage/cltools/kT.cpp.func-sort-c.html create mode 100644 coverage/cltools/kT.cpp.func.html create mode 100644 coverage/cltools/kT.cpp.gcov.html create mode 100644 coverage/cltools/pesmd.cpp.func-sort-c.html create mode 100644 coverage/cltools/pesmd.cpp.func.html create mode 100644 coverage/cltools/pesmd.cpp.gcov.html create mode 100644 coverage/colvar/Angle.cpp.func-sort-c.html create mode 100644 coverage/colvar/Angle.cpp.func.html create mode 100644 coverage/colvar/Angle.cpp.gcov.html create mode 100644 coverage/colvar/Cell.cpp.func-sort-c.html create mode 100644 coverage/colvar/Cell.cpp.func.html create mode 100644 coverage/colvar/Cell.cpp.gcov.html create mode 100644 coverage/colvar/Constant.cpp.func-sort-c.html create mode 100644 coverage/colvar/Constant.cpp.func.html create mode 100644 coverage/colvar/Constant.cpp.gcov.html create mode 100644 coverage/colvar/ContactMap.cpp.func-sort-c.html create mode 100644 coverage/colvar/ContactMap.cpp.func.html create mode 100644 coverage/colvar/ContactMap.cpp.gcov.html create mode 100644 coverage/colvar/Coordination.cpp.func-sort-c.html create mode 100644 coverage/colvar/Coordination.cpp.func.html create mode 100644 coverage/colvar/Coordination.cpp.gcov.html create mode 100644 coverage/colvar/CoordinationBase.cpp.func-sort-c.html create mode 100644 coverage/colvar/CoordinationBase.cpp.func.html create mode 100644 coverage/colvar/CoordinationBase.cpp.gcov.html create mode 100644 coverage/colvar/DHEnergy.cpp.func-sort-c.html create mode 100644 coverage/colvar/DHEnergy.cpp.func.html create mode 100644 coverage/colvar/DHEnergy.cpp.gcov.html create mode 100644 coverage/colvar/DRMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/DRMSD.cpp.func.html create mode 100644 coverage/colvar/DRMSD.cpp.gcov.html create mode 100644 coverage/colvar/Dimer.cpp.func-sort-c.html create mode 100644 coverage/colvar/Dimer.cpp.func.html create mode 100644 coverage/colvar/Dimer.cpp.gcov.html create mode 100644 coverage/colvar/Dipole.cpp.func-sort-c.html create mode 100644 coverage/colvar/Dipole.cpp.func.html create mode 100644 coverage/colvar/Dipole.cpp.gcov.html create mode 100644 coverage/colvar/Distance.cpp.func-sort-c.html create mode 100644 coverage/colvar/Distance.cpp.func.html create mode 100644 coverage/colvar/Distance.cpp.gcov.html create mode 100644 coverage/colvar/EEFSolv.cpp.func-sort-c.html create mode 100644 coverage/colvar/EEFSolv.cpp.func.html create mode 100644 coverage/colvar/EEFSolv.cpp.gcov.html create mode 100644 coverage/colvar/ERMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/ERMSD.cpp.func.html create mode 100644 coverage/colvar/ERMSD.cpp.gcov.html create mode 100644 coverage/colvar/Energy.cpp.func-sort-c.html create mode 100644 coverage/colvar/Energy.cpp.func.html create mode 100644 coverage/colvar/Energy.cpp.gcov.html create mode 100644 coverage/colvar/ExtraCV.cpp.func-sort-c.html create mode 100644 coverage/colvar/ExtraCV.cpp.func.html create mode 100644 coverage/colvar/ExtraCV.cpp.gcov.html create mode 100644 coverage/colvar/Fake.cpp.func-sort-c.html create mode 100644 coverage/colvar/Fake.cpp.func.html create mode 100644 coverage/colvar/Fake.cpp.gcov.html create mode 100644 coverage/colvar/GHBFIX.cpp.func-sort-c.html create mode 100644 coverage/colvar/GHBFIX.cpp.func.html create mode 100644 coverage/colvar/GHBFIX.cpp.gcov.html create mode 100644 coverage/colvar/Gyration.cpp.func-sort-c.html create mode 100644 coverage/colvar/Gyration.cpp.func.html create mode 100644 coverage/colvar/Gyration.cpp.gcov.html create mode 100644 coverage/colvar/MultiRMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/MultiRMSD.cpp.func.html create mode 100644 coverage/colvar/MultiRMSD.cpp.gcov.html create mode 100644 coverage/colvar/PCARMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/PCARMSD.cpp.func.html create mode 100644 coverage/colvar/PCARMSD.cpp.gcov.html create mode 100644 coverage/colvar/PathMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/PathMSD.cpp.func.html create mode 100644 coverage/colvar/PathMSD.cpp.gcov.html create mode 100644 coverage/colvar/PathMSDBase.cpp.func-sort-c.html create mode 100644 coverage/colvar/PathMSDBase.cpp.func.html create mode 100644 coverage/colvar/PathMSDBase.cpp.gcov.html create mode 100644 coverage/colvar/PathMSDBase.h.func-sort-c.html create mode 100644 coverage/colvar/PathMSDBase.h.func.html create mode 100644 coverage/colvar/PathMSDBase.h.gcov.html create mode 100644 coverage/colvar/Position.cpp.func-sort-c.html create mode 100644 coverage/colvar/Position.cpp.func.html create mode 100644 coverage/colvar/Position.cpp.gcov.html create mode 100644 coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html create mode 100644 coverage/colvar/ProjectionOnAxis.cpp.func.html create mode 100644 coverage/colvar/ProjectionOnAxis.cpp.gcov.html create mode 100644 coverage/colvar/PropertyMap.cpp.func-sort-c.html create mode 100644 coverage/colvar/PropertyMap.cpp.func.html create mode 100644 coverage/colvar/PropertyMap.cpp.gcov.html create mode 100644 coverage/colvar/Puckering.cpp.func-sort-c.html create mode 100644 coverage/colvar/Puckering.cpp.func.html create mode 100644 coverage/colvar/Puckering.cpp.gcov.html create mode 100644 coverage/colvar/RMSD.cpp.func-sort-c.html create mode 100644 coverage/colvar/RMSD.cpp.func.html create mode 100644 coverage/colvar/RMSD.cpp.gcov.html create mode 100644 coverage/colvar/Template.cpp.func-sort-c.html create mode 100644 coverage/colvar/Template.cpp.func.html create mode 100644 coverage/colvar/Template.cpp.gcov.html create mode 100644 coverage/colvar/Torsion.cpp.func-sort-c.html create mode 100644 coverage/colvar/Torsion.cpp.func.html create mode 100644 coverage/colvar/Torsion.cpp.gcov.html create mode 100644 coverage/colvar/Volume.cpp.func-sort-c.html create mode 100644 coverage/colvar/Volume.cpp.func.html create mode 100644 coverage/colvar/Volume.cpp.gcov.html create mode 100644 coverage/colvar/index-sort-f.html create mode 100644 coverage/colvar/index-sort-l.html create mode 100644 coverage/colvar/index.html create mode 100644 coverage/config/Config.inc.func-sort-c.html create mode 100644 coverage/config/Config.inc.func.html create mode 100644 coverage/config/Config.inc.gcov.html create mode 100644 coverage/config/ConfigInstall.inc.func-sort-c.html create mode 100644 coverage/config/ConfigInstall.inc.func.html create mode 100644 coverage/config/ConfigInstall.inc.gcov.html create mode 100644 coverage/config/index-sort-f.html create mode 100644 coverage/config/index-sort-l.html create mode 100644 coverage/config/index.html create mode 100644 coverage/core/Action.cpp.func-sort-c.html create mode 100644 coverage/core/Action.cpp.func.html create mode 100644 coverage/core/Action.cpp.gcov.html create mode 100644 coverage/core/Action.h.func-sort-c.html create mode 100644 coverage/core/Action.h.func.html create mode 100644 coverage/core/Action.h.gcov.html create mode 100644 coverage/core/ActionAnyorder.cpp.func-sort-c.html create mode 100644 coverage/core/ActionAnyorder.cpp.func.html create mode 100644 coverage/core/ActionAnyorder.cpp.gcov.html create mode 100644 coverage/core/ActionAnyorder.h.func-sort-c.html create mode 100644 coverage/core/ActionAnyorder.h.func.html create mode 100644 coverage/core/ActionAnyorder.h.gcov.html create mode 100644 coverage/core/ActionAtomistic.cpp.func-sort-c.html create mode 100644 coverage/core/ActionAtomistic.cpp.func.html create mode 100644 coverage/core/ActionAtomistic.cpp.gcov.html create mode 100644 coverage/core/ActionAtomistic.h.func-sort-c.html create mode 100644 coverage/core/ActionAtomistic.h.func.html create mode 100644 coverage/core/ActionAtomistic.h.gcov.html create mode 100644 coverage/core/ActionForInterface.cpp.func-sort-c.html create mode 100644 coverage/core/ActionForInterface.cpp.func.html create mode 100644 coverage/core/ActionForInterface.cpp.gcov.html create mode 100644 coverage/core/ActionForInterface.h.func-sort-c.html create mode 100644 coverage/core/ActionForInterface.h.func.html create mode 100644 coverage/core/ActionForInterface.h.gcov.html create mode 100644 coverage/core/ActionPilot.cpp.func-sort-c.html create mode 100644 coverage/core/ActionPilot.cpp.func.html create mode 100644 coverage/core/ActionPilot.cpp.gcov.html create mode 100644 coverage/core/ActionPilot.h.func-sort-c.html create mode 100644 coverage/core/ActionPilot.h.func.html create mode 100644 coverage/core/ActionPilot.h.gcov.html create mode 100644 coverage/core/ActionRegister.cpp.func-sort-c.html create mode 100644 coverage/core/ActionRegister.cpp.func.html create mode 100644 coverage/core/ActionRegister.cpp.gcov.html create mode 100644 coverage/core/ActionRegister.h.func-sort-c.html create mode 100644 coverage/core/ActionRegister.h.func.html create mode 100644 coverage/core/ActionRegister.h.gcov.html create mode 100644 coverage/core/ActionSet.cpp.func-sort-c.html create mode 100644 coverage/core/ActionSet.cpp.func.html create mode 100644 coverage/core/ActionSet.cpp.gcov.html create mode 100644 coverage/core/ActionSet.h.func-sort-c.html create mode 100644 coverage/core/ActionSet.h.func.html create mode 100644 coverage/core/ActionSet.h.gcov.html create mode 100644 coverage/core/ActionSetup.cpp.func-sort-c.html create mode 100644 coverage/core/ActionSetup.cpp.func.html create mode 100644 coverage/core/ActionSetup.cpp.gcov.html create mode 100644 coverage/core/ActionSetup.h.func-sort-c.html create mode 100644 coverage/core/ActionSetup.h.func.html create mode 100644 coverage/core/ActionSetup.h.gcov.html create mode 100644 coverage/core/ActionShortcut.cpp.func-sort-c.html create mode 100644 coverage/core/ActionShortcut.cpp.func.html create mode 100644 coverage/core/ActionShortcut.cpp.gcov.html create mode 100644 coverage/core/ActionShortcut.h.func-sort-c.html create mode 100644 coverage/core/ActionShortcut.h.func.html create mode 100644 coverage/core/ActionShortcut.h.gcov.html create mode 100644 coverage/core/ActionToGetData.cpp.func-sort-c.html create mode 100644 coverage/core/ActionToGetData.cpp.func.html create mode 100644 coverage/core/ActionToGetData.cpp.gcov.html create mode 100644 coverage/core/ActionToGetData.h.func-sort-c.html create mode 100644 coverage/core/ActionToGetData.h.func.html create mode 100644 coverage/core/ActionToGetData.h.gcov.html create mode 100644 coverage/core/ActionToPutData.cpp.func-sort-c.html create mode 100644 coverage/core/ActionToPutData.cpp.func.html create mode 100644 coverage/core/ActionToPutData.cpp.gcov.html create mode 100644 coverage/core/ActionToPutData.h.func-sort-c.html create mode 100644 coverage/core/ActionToPutData.h.func.html create mode 100644 coverage/core/ActionToPutData.h.gcov.html create mode 100644 coverage/core/ActionWithArguments.cpp.func-sort-c.html create mode 100644 coverage/core/ActionWithArguments.cpp.func.html create mode 100644 coverage/core/ActionWithArguments.cpp.gcov.html create mode 100644 coverage/core/ActionWithArguments.h.func-sort-c.html create mode 100644 coverage/core/ActionWithArguments.h.func.html create mode 100644 coverage/core/ActionWithArguments.h.gcov.html create mode 100644 coverage/core/ActionWithValue.cpp.func-sort-c.html create mode 100644 coverage/core/ActionWithValue.cpp.func.html create mode 100644 coverage/core/ActionWithValue.cpp.gcov.html create mode 100644 coverage/core/ActionWithValue.h.func-sort-c.html create mode 100644 coverage/core/ActionWithValue.h.func.html create mode 100644 coverage/core/ActionWithValue.h.gcov.html create mode 100644 coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html create mode 100644 coverage/core/ActionWithVirtualAtom.cpp.func.html create mode 100644 coverage/core/ActionWithVirtualAtom.cpp.gcov.html create mode 100644 coverage/core/ActionWithVirtualAtom.h.func-sort-c.html create mode 100644 coverage/core/ActionWithVirtualAtom.h.func.html create mode 100644 coverage/core/ActionWithVirtualAtom.h.gcov.html create mode 100644 coverage/core/CLTool.cpp.func-sort-c.html create mode 100644 coverage/core/CLTool.cpp.func.html create mode 100644 coverage/core/CLTool.cpp.gcov.html create mode 100644 coverage/core/CLTool.h.func-sort-c.html create mode 100644 coverage/core/CLTool.h.func.html create mode 100644 coverage/core/CLTool.h.gcov.html create mode 100644 coverage/core/CLToolMain.cpp.func-sort-c.html create mode 100644 coverage/core/CLToolMain.cpp.func.html create mode 100644 coverage/core/CLToolMain.cpp.gcov.html create mode 100644 coverage/core/CLToolRegister.cpp.func-sort-c.html create mode 100644 coverage/core/CLToolRegister.cpp.func.html create mode 100644 coverage/core/CLToolRegister.cpp.gcov.html create mode 100644 coverage/core/Colvar.cpp.func-sort-c.html create mode 100644 coverage/core/Colvar.cpp.func.html create mode 100644 coverage/core/Colvar.cpp.gcov.html create mode 100644 coverage/core/Colvar.h.func-sort-c.html create mode 100644 coverage/core/Colvar.h.func.html create mode 100644 coverage/core/Colvar.h.gcov.html create mode 100644 coverage/core/DataPassingObject.cpp.func-sort-c.html create mode 100644 coverage/core/DataPassingObject.cpp.func.html create mode 100644 coverage/core/DataPassingObject.cpp.gcov.html create mode 100644 coverage/core/DataPassingObject.h.func-sort-c.html create mode 100644 coverage/core/DataPassingObject.h.func.html create mode 100644 coverage/core/DataPassingObject.h.gcov.html create mode 100644 coverage/core/DataPassingTools.cpp.func-sort-c.html create mode 100644 coverage/core/DataPassingTools.cpp.func.html create mode 100644 coverage/core/DataPassingTools.cpp.gcov.html create mode 100644 coverage/core/DataPassingTools.h.func-sort-c.html create mode 100644 coverage/core/DataPassingTools.h.func.html create mode 100644 coverage/core/DataPassingTools.h.gcov.html create mode 100644 coverage/core/DomainDecomposition.cpp.func-sort-c.html create mode 100644 coverage/core/DomainDecomposition.cpp.func.html create mode 100644 coverage/core/DomainDecomposition.cpp.gcov.html create mode 100644 coverage/core/DomainDecomposition.h.func-sort-c.html create mode 100644 coverage/core/DomainDecomposition.h.func.html create mode 100644 coverage/core/DomainDecomposition.h.gcov.html create mode 100644 coverage/core/ExchangePatterns.cpp.func-sort-c.html create mode 100644 coverage/core/ExchangePatterns.cpp.func.html create mode 100644 coverage/core/ExchangePatterns.cpp.gcov.html create mode 100644 coverage/core/FlexibleBin.cpp.func-sort-c.html create mode 100644 coverage/core/FlexibleBin.cpp.func.html create mode 100644 coverage/core/FlexibleBin.cpp.gcov.html create mode 100644 coverage/core/GREX.cpp.func-sort-c.html create mode 100644 coverage/core/GREX.cpp.func.html create mode 100644 coverage/core/GREX.cpp.gcov.html create mode 100644 coverage/core/GenericMolInfo.cpp.func-sort-c.html create mode 100644 coverage/core/GenericMolInfo.cpp.func.html create mode 100644 coverage/core/GenericMolInfo.cpp.gcov.html create mode 100644 coverage/core/GenericMolInfo.h.func-sort-c.html create mode 100644 coverage/core/GenericMolInfo.h.func.html create mode 100644 coverage/core/GenericMolInfo.h.gcov.html create mode 100644 coverage/core/Group.cpp.func-sort-c.html create mode 100644 coverage/core/Group.cpp.func.html create mode 100644 coverage/core/Group.cpp.gcov.html create mode 100644 coverage/core/Group.h.func-sort-c.html create mode 100644 coverage/core/Group.h.func.html create mode 100644 coverage/core/Group.h.gcov.html create mode 100644 coverage/core/PbcAction.cpp.func-sort-c.html create mode 100644 coverage/core/PbcAction.cpp.func.html create mode 100644 coverage/core/PbcAction.cpp.gcov.html create mode 100644 coverage/core/PbcAction.h.func-sort-c.html create mode 100644 coverage/core/PbcAction.h.func.html create mode 100644 coverage/core/PbcAction.h.gcov.html create mode 100644 coverage/core/PlumedMain.cpp.func-sort-c.html create mode 100644 coverage/core/PlumedMain.cpp.func.html create mode 100644 coverage/core/PlumedMain.cpp.gcov.html create mode 100644 coverage/core/PlumedMain.h.func-sort-c.html create mode 100644 coverage/core/PlumedMain.h.func.html create mode 100644 coverage/core/PlumedMain.h.gcov.html create mode 100644 coverage/core/PlumedMainInitializer.cpp.func-sort-c.html create mode 100644 coverage/core/PlumedMainInitializer.cpp.func.html create mode 100644 coverage/core/PlumedMainInitializer.cpp.gcov.html create mode 100644 coverage/core/TargetDist.cpp.func-sort-c.html create mode 100644 coverage/core/TargetDist.cpp.func.html create mode 100644 coverage/core/TargetDist.cpp.gcov.html create mode 100644 coverage/core/Value.cpp.func-sort-c.html create mode 100644 coverage/core/Value.cpp.func.html create mode 100644 coverage/core/Value.cpp.gcov.html create mode 100644 coverage/core/Value.h.func-sort-c.html create mode 100644 coverage/core/Value.h.func.html create mode 100644 coverage/core/Value.h.gcov.html create mode 100644 coverage/core/WithCmd.h.func-sort-c.html create mode 100644 coverage/core/WithCmd.h.func.html create mode 100644 coverage/core/WithCmd.h.gcov.html create mode 100644 coverage/core/index-sort-f.html create mode 100644 coverage/core/index-sort-l.html create mode 100644 coverage/core/index.html create mode 100644 coverage/crystallization/BondOrientation.cpp.func-sort-c.html create mode 100644 coverage/crystallization/BondOrientation.cpp.func.html create mode 100644 coverage/crystallization/BondOrientation.cpp.gcov.html create mode 100644 coverage/crystallization/CubicHarmonicBase.cpp.func-sort-c.html create mode 100644 coverage/crystallization/CubicHarmonicBase.cpp.func.html create mode 100644 coverage/crystallization/CubicHarmonicBase.cpp.gcov.html create mode 100644 coverage/crystallization/CubicHarmonicBase.h.func-sort-c.html create mode 100644 coverage/crystallization/CubicHarmonicBase.h.func.html create mode 100644 coverage/crystallization/CubicHarmonicBase.h.gcov.html create mode 100644 coverage/crystallization/EnvironmentSimilarity.cpp.func-sort-c.html create mode 100644 coverage/crystallization/EnvironmentSimilarity.cpp.func.html create mode 100644 coverage/crystallization/EnvironmentSimilarity.cpp.gcov.html create mode 100644 coverage/crystallization/Fccubic.cpp.func-sort-c.html create mode 100644 coverage/crystallization/Fccubic.cpp.func.html create mode 100644 coverage/crystallization/Fccubic.cpp.gcov.html create mode 100644 coverage/crystallization/Gradient.cpp.func-sort-c.html create mode 100644 coverage/crystallization/Gradient.cpp.func.html create mode 100644 coverage/crystallization/Gradient.cpp.gcov.html create mode 100644 coverage/crystallization/Gradient.h.func-sort-c.html create mode 100644 coverage/crystallization/Gradient.h.func.html create mode 100644 coverage/crystallization/Gradient.h.gcov.html create mode 100644 coverage/crystallization/GradientVessel.cpp.func-sort-c.html create mode 100644 coverage/crystallization/GradientVessel.cpp.func.html create mode 100644 coverage/crystallization/GradientVessel.cpp.gcov.html create mode 100644 coverage/crystallization/InterMolecularTorsions.cpp.func-sort-c.html create mode 100644 coverage/crystallization/InterMolecularTorsions.cpp.func.html create mode 100644 coverage/crystallization/InterMolecularTorsions.cpp.gcov.html create mode 100644 coverage/crystallization/LocalSteinhardt.h.func-sort-c.html create mode 100644 coverage/crystallization/LocalSteinhardt.h.func.html create mode 100644 coverage/crystallization/LocalSteinhardt.h.gcov.html create mode 100644 coverage/crystallization/MoleculeOrientation.cpp.func-sort-c.html create mode 100644 coverage/crystallization/MoleculeOrientation.cpp.func.html create mode 100644 coverage/crystallization/MoleculeOrientation.cpp.gcov.html create mode 100644 coverage/crystallization/MoleculePlane.cpp.func-sort-c.html create mode 100644 coverage/crystallization/MoleculePlane.cpp.func.html create mode 100644 coverage/crystallization/MoleculePlane.cpp.gcov.html create mode 100644 coverage/crystallization/OrientationSphere.cpp.func-sort-c.html create mode 100644 coverage/crystallization/OrientationSphere.cpp.func.html create mode 100644 coverage/crystallization/OrientationSphere.cpp.gcov.html create mode 100644 coverage/crystallization/OrientationSphere.h.func-sort-c.html create mode 100644 coverage/crystallization/OrientationSphere.h.func.html create mode 100644 coverage/crystallization/OrientationSphere.h.gcov.html create mode 100644 coverage/crystallization/PolymerAngles.cpp.func-sort-c.html create mode 100644 coverage/crystallization/PolymerAngles.cpp.func.html create mode 100644 coverage/crystallization/PolymerAngles.cpp.gcov.html create mode 100644 coverage/crystallization/Q3.cpp.func-sort-c.html create mode 100644 coverage/crystallization/Q3.cpp.func.html create mode 100644 coverage/crystallization/Q3.cpp.gcov.html create mode 100644 coverage/crystallization/Q4.cpp.func-sort-c.html create mode 100644 coverage/crystallization/Q4.cpp.func.html create mode 100644 coverage/crystallization/Q4.cpp.gcov.html create mode 100644 coverage/crystallization/Q6.cpp.func-sort-c.html create mode 100644 coverage/crystallization/Q6.cpp.func.html create mode 100644 coverage/crystallization/Q6.cpp.gcov.html create mode 100644 coverage/crystallization/SMAC.cpp.func-sort-c.html create mode 100644 coverage/crystallization/SMAC.cpp.func.html create mode 100644 coverage/crystallization/SMAC.cpp.gcov.html create mode 100644 coverage/crystallization/SimpleCubic.cpp.func-sort-c.html create mode 100644 coverage/crystallization/SimpleCubic.cpp.func.html create mode 100644 coverage/crystallization/SimpleCubic.cpp.gcov.html create mode 100644 coverage/crystallization/Steinhardt.cpp.func-sort-c.html create mode 100644 coverage/crystallization/Steinhardt.cpp.func.html create mode 100644 coverage/crystallization/Steinhardt.cpp.gcov.html create mode 100644 coverage/crystallization/Tetrahedral.cpp.func-sort-c.html create mode 100644 coverage/crystallization/Tetrahedral.cpp.func.html create mode 100644 coverage/crystallization/Tetrahedral.cpp.gcov.html create mode 100644 coverage/crystallization/VectorMean.cpp.func-sort-c.html create mode 100644 coverage/crystallization/VectorMean.cpp.func.html create mode 100644 coverage/crystallization/VectorMean.cpp.gcov.html create mode 100644 coverage/crystallization/VectorMultiColvar.cpp.func-sort-c.html create mode 100644 coverage/crystallization/VectorMultiColvar.cpp.func.html create mode 100644 coverage/crystallization/VectorMultiColvar.cpp.gcov.html create mode 100644 coverage/crystallization/VectorMultiColvar.h.func-sort-c.html create mode 100644 coverage/crystallization/VectorMultiColvar.h.func.html create mode 100644 coverage/crystallization/VectorMultiColvar.h.gcov.html create mode 100644 coverage/crystallization/VectorSum.cpp.func-sort-c.html create mode 100644 coverage/crystallization/VectorSum.cpp.func.html create mode 100644 coverage/crystallization/VectorSum.cpp.gcov.html create mode 100644 coverage/crystallization/index-sort-f.html create mode 100644 coverage/crystallization/index-sort-l.html create mode 100644 coverage/crystallization/index.html create mode 100644 coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func-sort-c.html create mode 100644 coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html create mode 100644 coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html create mode 100644 coverage/dimred/DimensionalityReductionBase.cpp.func-sort-c.html create mode 100644 coverage/dimred/DimensionalityReductionBase.cpp.func.html create mode 100644 coverage/dimred/DimensionalityReductionBase.cpp.gcov.html create mode 100644 coverage/dimred/DimensionalityReductionBase.h.func-sort-c.html create mode 100644 coverage/dimred/DimensionalityReductionBase.h.func.html create mode 100644 coverage/dimred/DimensionalityReductionBase.h.gcov.html create mode 100644 coverage/dimred/OutputPCAProjections.cpp.func-sort-c.html create mode 100644 coverage/dimred/OutputPCAProjections.cpp.func.html create mode 100644 coverage/dimred/OutputPCAProjections.cpp.gcov.html create mode 100644 coverage/dimred/PCA.cpp.func-sort-c.html create mode 100644 coverage/dimred/PCA.cpp.func.html create mode 100644 coverage/dimred/PCA.cpp.gcov.html create mode 100644 coverage/dimred/PCA.h.func-sort-c.html create mode 100644 coverage/dimred/PCA.h.func.html create mode 100644 coverage/dimred/PCA.h.gcov.html create mode 100644 coverage/dimred/ProjectNonLandmarkPoints.cpp.func-sort-c.html create mode 100644 coverage/dimred/ProjectNonLandmarkPoints.cpp.func.html create mode 100644 coverage/dimred/ProjectNonLandmarkPoints.cpp.gcov.html create mode 100644 coverage/dimred/SMACOF.cpp.func-sort-c.html create mode 100644 coverage/dimred/SMACOF.cpp.func.html create mode 100644 coverage/dimred/SMACOF.cpp.gcov.html create mode 100644 coverage/dimred/SketchMap.cpp.func-sort-c.html create mode 100644 coverage/dimred/SketchMap.cpp.func.html create mode 100644 coverage/dimred/SketchMap.cpp.gcov.html create mode 100644 coverage/dimred/SketchMapBase.cpp.func-sort-c.html create mode 100644 coverage/dimred/SketchMapBase.cpp.func.html create mode 100644 coverage/dimred/SketchMapBase.cpp.gcov.html create mode 100644 coverage/dimred/SketchMapBase.h.func-sort-c.html create mode 100644 coverage/dimred/SketchMapBase.h.func.html create mode 100644 coverage/dimred/SketchMapBase.h.gcov.html create mode 100644 coverage/dimred/SketchMapConjGrad.cpp.func-sort-c.html create mode 100644 coverage/dimred/SketchMapConjGrad.cpp.func.html create mode 100644 coverage/dimred/SketchMapConjGrad.cpp.gcov.html create mode 100644 coverage/dimred/SketchMapPointwise.cpp.func-sort-c.html create mode 100644 coverage/dimred/SketchMapPointwise.cpp.func.html create mode 100644 coverage/dimred/SketchMapPointwise.cpp.gcov.html create mode 100644 coverage/dimred/SketchMapRead.cpp.func-sort-c.html create mode 100644 coverage/dimred/SketchMapRead.cpp.func.html create mode 100644 coverage/dimred/SketchMapRead.cpp.gcov.html create mode 100644 coverage/dimred/SketchMapSmacof.cpp.func-sort-c.html create mode 100644 coverage/dimred/SketchMapSmacof.cpp.func.html create mode 100644 coverage/dimred/SketchMapSmacof.cpp.gcov.html create mode 100644 coverage/dimred/SmacoffMDS.cpp.func-sort-c.html create mode 100644 coverage/dimred/SmacoffMDS.cpp.func.html create mode 100644 coverage/dimred/SmacoffMDS.cpp.gcov.html create mode 100644 coverage/dimred/index-sort-f.html create mode 100644 coverage/dimred/index-sort-l.html create mode 100644 coverage/dimred/index.html create mode 100644 coverage/drr/DRR.cpp.func-sort-c.html create mode 100644 coverage/drr/DRR.cpp.func.html create mode 100644 coverage/drr/DRR.cpp.gcov.html create mode 100644 coverage/drr/DRR.h.func-sort-c.html create mode 100644 coverage/drr/DRR.h.func.html create mode 100644 coverage/drr/DRR.h.gcov.html create mode 100644 coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html create mode 100644 coverage/drr/DynamicReferenceRestraining.cpp.func.html create mode 100644 coverage/drr/DynamicReferenceRestraining.cpp.gcov.html create mode 100644 coverage/drr/colvar_UIestimator.h.func-sort-c.html create mode 100644 coverage/drr/colvar_UIestimator.h.func.html create mode 100644 coverage/drr/colvar_UIestimator.h.gcov.html create mode 100644 coverage/drr/drrtool.cpp.func-sort-c.html create mode 100644 coverage/drr/drrtool.cpp.func.html create mode 100644 coverage/drr/drrtool.cpp.gcov.html create mode 100644 coverage/drr/index-sort-f.html create mode 100644 coverage/drr/index-sort-l.html create mode 100644 coverage/drr/index.html create mode 100644 coverage/eds/EDS.cpp.func-sort-c.html create mode 100644 coverage/eds/EDS.cpp.func.html create mode 100644 coverage/eds/EDS.cpp.gcov.html create mode 100644 coverage/eds/index-sort-f.html create mode 100644 coverage/eds/index-sort-l.html create mode 100644 coverage/eds/index.html create mode 100644 coverage/emerald.png create mode 100644 coverage/fisst/FISST.cpp.func-sort-c.html create mode 100644 coverage/fisst/FISST.cpp.func.html create mode 100644 coverage/fisst/FISST.cpp.gcov.html create mode 100644 coverage/fisst/index-sort-f.html create mode 100644 coverage/fisst/index-sort-l.html create mode 100644 coverage/fisst/index.html create mode 100644 coverage/fisst/legendre_rule_fast.cpp.func-sort-c.html create mode 100644 coverage/fisst/legendre_rule_fast.cpp.func.html create mode 100644 coverage/fisst/legendre_rule_fast.cpp.gcov.html create mode 100644 coverage/function/Combine.cpp.func-sort-c.html create mode 100644 coverage/function/Combine.cpp.func.html create mode 100644 coverage/function/Combine.cpp.gcov.html create mode 100644 coverage/function/Custom.cpp.func-sort-c.html create mode 100644 coverage/function/Custom.cpp.func.html create mode 100644 coverage/function/Custom.cpp.gcov.html create mode 100644 coverage/function/Ensemble.cpp.func-sort-c.html create mode 100644 coverage/function/Ensemble.cpp.func.html create mode 100644 coverage/function/Ensemble.cpp.gcov.html create mode 100644 coverage/function/FuncPathGeneral.cpp.func-sort-c.html create mode 100644 coverage/function/FuncPathGeneral.cpp.func.html create mode 100644 coverage/function/FuncPathGeneral.cpp.gcov.html create mode 100644 coverage/function/FuncPathMSD.cpp.func-sort-c.html create mode 100644 coverage/function/FuncPathMSD.cpp.func.html create mode 100644 coverage/function/FuncPathMSD.cpp.gcov.html create mode 100644 coverage/function/FuncSumHills.cpp.func-sort-c.html create mode 100644 coverage/function/FuncSumHills.cpp.func.html create mode 100644 coverage/function/FuncSumHills.cpp.gcov.html create mode 100644 coverage/function/Function.cpp.func-sort-c.html create mode 100644 coverage/function/Function.cpp.func.html create mode 100644 coverage/function/Function.cpp.gcov.html create mode 100644 coverage/function/Function.h.func-sort-c.html create mode 100644 coverage/function/Function.h.func.html create mode 100644 coverage/function/Function.h.gcov.html create mode 100644 coverage/function/LocalEnsemble.cpp.func-sort-c.html create mode 100644 coverage/function/LocalEnsemble.cpp.func.html create mode 100644 coverage/function/LocalEnsemble.cpp.gcov.html create mode 100644 coverage/function/Piecewise.cpp.func-sort-c.html create mode 100644 coverage/function/Piecewise.cpp.func.html create mode 100644 coverage/function/Piecewise.cpp.gcov.html create mode 100644 coverage/function/Sort.cpp.func-sort-c.html create mode 100644 coverage/function/Sort.cpp.func.html create mode 100644 coverage/function/Sort.cpp.gcov.html create mode 100644 coverage/function/Stats.cpp.func-sort-c.html create mode 100644 coverage/function/Stats.cpp.func.html create mode 100644 coverage/function/Stats.cpp.gcov.html create mode 100644 coverage/function/Target.cpp.func-sort-c.html create mode 100644 coverage/function/Target.cpp.func.html create mode 100644 coverage/function/Target.cpp.gcov.html create mode 100644 coverage/function/index-sort-f.html create mode 100644 coverage/function/index-sort-l.html create mode 100644 coverage/function/index.html create mode 100644 coverage/funnel/FPS.cpp.func-sort-c.html create mode 100644 coverage/funnel/FPS.cpp.func.html create mode 100644 coverage/funnel/FPS.cpp.gcov.html create mode 100644 coverage/funnel/Funnel.cpp.func-sort-c.html create mode 100644 coverage/funnel/Funnel.cpp.func.html create mode 100644 coverage/funnel/Funnel.cpp.gcov.html create mode 100644 coverage/funnel/index-sort-f.html create mode 100644 coverage/funnel/index-sort-l.html create mode 100644 coverage/funnel/index.html create mode 100644 coverage/gcov.css create mode 100644 coverage/generic/Debug.cpp.func-sort-c.html create mode 100644 coverage/generic/Debug.cpp.func.html create mode 100644 coverage/generic/Debug.cpp.gcov.html create mode 100644 coverage/generic/DumpAtoms.cpp.func-sort-c.html create mode 100644 coverage/generic/DumpAtoms.cpp.func.html create mode 100644 coverage/generic/DumpAtoms.cpp.gcov.html create mode 100644 coverage/generic/DumpDerivatives.cpp.func-sort-c.html create mode 100644 coverage/generic/DumpDerivatives.cpp.func.html create mode 100644 coverage/generic/DumpDerivatives.cpp.gcov.html create mode 100644 coverage/generic/DumpForces.cpp.func-sort-c.html create mode 100644 coverage/generic/DumpForces.cpp.func.html create mode 100644 coverage/generic/DumpForces.cpp.gcov.html create mode 100644 coverage/generic/DumpMassCharge.cpp.func-sort-c.html create mode 100644 coverage/generic/DumpMassCharge.cpp.func.html create mode 100644 coverage/generic/DumpMassCharge.cpp.gcov.html create mode 100644 coverage/generic/DumpProjections.cpp.func-sort-c.html create mode 100644 coverage/generic/DumpProjections.cpp.func.html create mode 100644 coverage/generic/DumpProjections.cpp.gcov.html create mode 100644 coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html create mode 100644 coverage/generic/EffectiveEnergyDrift.cpp.func.html create mode 100644 coverage/generic/EffectiveEnergyDrift.cpp.gcov.html create mode 100644 coverage/generic/EndPlumed.cpp.func-sort-c.html create mode 100644 coverage/generic/EndPlumed.cpp.func.html create mode 100644 coverage/generic/EndPlumed.cpp.gcov.html create mode 100644 coverage/generic/FitToTemplate.cpp.func-sort-c.html create mode 100644 coverage/generic/FitToTemplate.cpp.func.html create mode 100644 coverage/generic/FitToTemplate.cpp.gcov.html create mode 100644 coverage/generic/Flush.cpp.func-sort-c.html create mode 100644 coverage/generic/Flush.cpp.func.html create mode 100644 coverage/generic/Flush.cpp.gcov.html create mode 100644 coverage/generic/Include.cpp.func-sort-c.html create mode 100644 coverage/generic/Include.cpp.func.html create mode 100644 coverage/generic/Include.cpp.gcov.html create mode 100644 coverage/generic/Plumed.cpp.func-sort-c.html create mode 100644 coverage/generic/Plumed.cpp.func.html create mode 100644 coverage/generic/Plumed.cpp.gcov.html create mode 100644 coverage/generic/Print.cpp.func-sort-c.html create mode 100644 coverage/generic/Print.cpp.func.html create mode 100644 coverage/generic/Print.cpp.gcov.html create mode 100644 coverage/generic/RandomExchanges.cpp.func-sort-c.html create mode 100644 coverage/generic/RandomExchanges.cpp.func.html create mode 100644 coverage/generic/RandomExchanges.cpp.gcov.html create mode 100644 coverage/generic/Read.cpp.func-sort-c.html create mode 100644 coverage/generic/Read.cpp.func.html create mode 100644 coverage/generic/Read.cpp.gcov.html create mode 100644 coverage/generic/ResetCell.cpp.func-sort-c.html create mode 100644 coverage/generic/ResetCell.cpp.func.html create mode 100644 coverage/generic/ResetCell.cpp.gcov.html create mode 100644 coverage/generic/Time.cpp.func-sort-c.html create mode 100644 coverage/generic/Time.cpp.func.html create mode 100644 coverage/generic/Time.cpp.gcov.html create mode 100644 coverage/generic/UpdateIf.cpp.func-sort-c.html create mode 100644 coverage/generic/UpdateIf.cpp.func.html create mode 100644 coverage/generic/UpdateIf.cpp.gcov.html create mode 100644 coverage/generic/WholeMolecules.cpp.func-sort-c.html create mode 100644 coverage/generic/WholeMolecules.cpp.func.html create mode 100644 coverage/generic/WholeMolecules.cpp.gcov.html create mode 100644 coverage/generic/WrapAround.cpp.func-sort-c.html create mode 100644 coverage/generic/WrapAround.cpp.func.html create mode 100644 coverage/generic/WrapAround.cpp.gcov.html create mode 100644 coverage/generic/index-sort-f.html create mode 100644 coverage/generic/index-sort-l.html create mode 100644 coverage/generic/index.html create mode 100644 coverage/glass.png create mode 100644 coverage/gridtools/ActionWithGrid.cpp.func-sort-c.html create mode 100644 coverage/gridtools/ActionWithGrid.cpp.func.html create mode 100644 coverage/gridtools/ActionWithGrid.cpp.gcov.html create mode 100644 coverage/gridtools/ActionWithInputGrid.cpp.func-sort-c.html create mode 100644 coverage/gridtools/ActionWithInputGrid.cpp.func.html create mode 100644 coverage/gridtools/ActionWithInputGrid.cpp.gcov.html create mode 100644 coverage/gridtools/ActionWithInputGrid.h.func-sort-c.html create mode 100644 coverage/gridtools/ActionWithInputGrid.h.func.html create mode 100644 coverage/gridtools/ActionWithInputGrid.h.gcov.html create mode 100644 coverage/gridtools/ActionWithIntegral.cpp.func-sort-c.html create mode 100644 coverage/gridtools/ActionWithIntegral.cpp.func.html create mode 100644 coverage/gridtools/ActionWithIntegral.cpp.gcov.html create mode 100644 coverage/gridtools/ActionWithIntegral.h.func-sort-c.html create mode 100644 coverage/gridtools/ActionWithIntegral.h.func.html create mode 100644 coverage/gridtools/ActionWithIntegral.h.gcov.html create mode 100644 coverage/gridtools/AverageOnGrid.cpp.func-sort-c.html create mode 100644 coverage/gridtools/AverageOnGrid.cpp.func.html create mode 100644 coverage/gridtools/AverageOnGrid.cpp.gcov.html create mode 100644 coverage/gridtools/AverageOnGrid.h.func-sort-c.html create mode 100644 coverage/gridtools/AverageOnGrid.h.func.html create mode 100644 coverage/gridtools/AverageOnGrid.h.gcov.html create mode 100644 coverage/gridtools/ContourFindingBase.cpp.func-sort-c.html create mode 100644 coverage/gridtools/ContourFindingBase.cpp.func.html create mode 100644 coverage/gridtools/ContourFindingBase.cpp.gcov.html create mode 100644 coverage/gridtools/ContourFindingBase.h.func-sort-c.html create mode 100644 coverage/gridtools/ContourFindingBase.h.func.html create mode 100644 coverage/gridtools/ContourFindingBase.h.gcov.html create mode 100644 coverage/gridtools/ConvertToFES.cpp.func-sort-c.html create mode 100644 coverage/gridtools/ConvertToFES.cpp.func.html create mode 100644 coverage/gridtools/ConvertToFES.cpp.gcov.html create mode 100644 coverage/gridtools/DumpCube.cpp.func-sort-c.html create mode 100644 coverage/gridtools/DumpCube.cpp.func.html create mode 100644 coverage/gridtools/DumpCube.cpp.gcov.html create mode 100644 coverage/gridtools/DumpGrid.cpp.func-sort-c.html create mode 100644 coverage/gridtools/DumpGrid.cpp.func.html create mode 100644 coverage/gridtools/DumpGrid.cpp.gcov.html create mode 100644 coverage/gridtools/FindContour.cpp.func-sort-c.html create mode 100644 coverage/gridtools/FindContour.cpp.func.html create mode 100644 coverage/gridtools/FindContour.cpp.gcov.html create mode 100644 coverage/gridtools/FindContourSurface.cpp.func-sort-c.html create mode 100644 coverage/gridtools/FindContourSurface.cpp.func.html create mode 100644 coverage/gridtools/FindContourSurface.cpp.gcov.html create mode 100644 coverage/gridtools/FindSphericalContour.cpp.func-sort-c.html create mode 100644 coverage/gridtools/FindSphericalContour.cpp.func.html create mode 100644 coverage/gridtools/FindSphericalContour.cpp.gcov.html create mode 100644 coverage/gridtools/FourierTransform.cpp.func-sort-c.html create mode 100644 coverage/gridtools/FourierTransform.cpp.func.html create mode 100644 coverage/gridtools/FourierTransform.cpp.gcov.html create mode 100644 coverage/gridtools/GridPrintingBase.cpp.func-sort-c.html create mode 100644 coverage/gridtools/GridPrintingBase.cpp.func.html create mode 100644 coverage/gridtools/GridPrintingBase.cpp.gcov.html create mode 100644 coverage/gridtools/GridPrintingBase.h.func-sort-c.html create mode 100644 coverage/gridtools/GridPrintingBase.h.func.html create mode 100644 coverage/gridtools/GridPrintingBase.h.gcov.html create mode 100644 coverage/gridtools/GridSearch.h.func-sort-c.html create mode 100644 coverage/gridtools/GridSearch.h.func.html create mode 100644 coverage/gridtools/GridSearch.h.gcov.html create mode 100644 coverage/gridtools/GridToXYZ.cpp.func-sort-c.html create mode 100644 coverage/gridtools/GridToXYZ.cpp.func.html create mode 100644 coverage/gridtools/GridToXYZ.cpp.gcov.html create mode 100644 coverage/gridtools/GridVessel.cpp.func-sort-c.html create mode 100644 coverage/gridtools/GridVessel.cpp.func.html create mode 100644 coverage/gridtools/GridVessel.cpp.gcov.html create mode 100644 coverage/gridtools/GridVessel.h.func-sort-c.html create mode 100644 coverage/gridtools/GridVessel.h.func.html create mode 100644 coverage/gridtools/GridVessel.h.gcov.html create mode 100644 coverage/gridtools/HistogramOnGrid.cpp.func-sort-c.html create mode 100644 coverage/gridtools/HistogramOnGrid.cpp.func.html create mode 100644 coverage/gridtools/HistogramOnGrid.cpp.gcov.html create mode 100644 coverage/gridtools/HistogramOnGrid.h.func-sort-c.html create mode 100644 coverage/gridtools/HistogramOnGrid.h.func.html create mode 100644 coverage/gridtools/HistogramOnGrid.h.gcov.html create mode 100644 coverage/gridtools/IntegrateGrid.cpp.func-sort-c.html create mode 100644 coverage/gridtools/IntegrateGrid.cpp.func.html create mode 100644 coverage/gridtools/IntegrateGrid.cpp.gcov.html create mode 100644 coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html create mode 100644 coverage/gridtools/InterpolateGrid.cpp.func.html create mode 100644 coverage/gridtools/InterpolateGrid.cpp.gcov.html create mode 100644 coverage/gridtools/index-sort-f.html create mode 100644 coverage/gridtools/index-sort-l.html create mode 100644 coverage/gridtools/index.html create mode 100644 coverage/index-sort-f.html create mode 100644 coverage/index-sort-l.html create mode 100644 coverage/index.html create mode 100644 coverage/isdb/CS2Backbone.cpp.func-sort-c.html create mode 100644 coverage/isdb/CS2Backbone.cpp.func.html create mode 100644 coverage/isdb/CS2Backbone.cpp.gcov.html create mode 100644 coverage/isdb/Caliber.cpp.func-sort-c.html create mode 100644 coverage/isdb/Caliber.cpp.func.html create mode 100644 coverage/isdb/Caliber.cpp.gcov.html create mode 100644 coverage/isdb/EMMI.cpp.func-sort-c.html create mode 100644 coverage/isdb/EMMI.cpp.func.html create mode 100644 coverage/isdb/EMMI.cpp.gcov.html create mode 100644 coverage/isdb/EMMIVox.cpp.func-sort-c.html create mode 100644 coverage/isdb/EMMIVox.cpp.func.html create mode 100644 coverage/isdb/EMMIVox.cpp.gcov.html create mode 100644 coverage/isdb/FretEfficiency.cpp.func-sort-c.html create mode 100644 coverage/isdb/FretEfficiency.cpp.func.html create mode 100644 coverage/isdb/FretEfficiency.cpp.gcov.html create mode 100644 coverage/isdb/Jcoupling.cpp.func-sort-c.html create mode 100644 coverage/isdb/Jcoupling.cpp.func.html create mode 100644 coverage/isdb/Jcoupling.cpp.gcov.html create mode 100644 coverage/isdb/Metainference.cpp.func-sort-c.html create mode 100644 coverage/isdb/Metainference.cpp.func.html create mode 100644 coverage/isdb/Metainference.cpp.gcov.html create mode 100644 coverage/isdb/MetainferenceBase.cpp.func-sort-c.html create mode 100644 coverage/isdb/MetainferenceBase.cpp.func.html create mode 100644 coverage/isdb/MetainferenceBase.cpp.gcov.html create mode 100644 coverage/isdb/MetainferenceBase.h.func-sort-c.html create mode 100644 coverage/isdb/MetainferenceBase.h.func.html create mode 100644 coverage/isdb/MetainferenceBase.h.gcov.html create mode 100644 coverage/isdb/NOE.cpp.func-sort-c.html create mode 100644 coverage/isdb/NOE.cpp.func.html create mode 100644 coverage/isdb/NOE.cpp.gcov.html create mode 100644 coverage/isdb/PRE.cpp.func-sort-c.html create mode 100644 coverage/isdb/PRE.cpp.func.html create mode 100644 coverage/isdb/PRE.cpp.gcov.html create mode 100644 coverage/isdb/RDC.cpp.func-sort-c.html create mode 100644 coverage/isdb/RDC.cpp.func.html create mode 100644 coverage/isdb/RDC.cpp.gcov.html create mode 100644 coverage/isdb/Rescale.cpp.func-sort-c.html create mode 100644 coverage/isdb/Rescale.cpp.func.html create mode 100644 coverage/isdb/Rescale.cpp.gcov.html create mode 100644 coverage/isdb/SAXS.cpp.func-sort-c.html create mode 100644 coverage/isdb/SAXS.cpp.func.html create mode 100644 coverage/isdb/SAXS.cpp.gcov.html create mode 100644 coverage/isdb/Select.cpp.func-sort-c.html create mode 100644 coverage/isdb/Select.cpp.func.html create mode 100644 coverage/isdb/Select.cpp.gcov.html create mode 100644 coverage/isdb/Selector.cpp.func-sort-c.html create mode 100644 coverage/isdb/Selector.cpp.func.html create mode 100644 coverage/isdb/Selector.cpp.gcov.html create mode 100644 coverage/isdb/Shadow.cpp.func-sort-c.html create mode 100644 coverage/isdb/Shadow.cpp.func.html create mode 100644 coverage/isdb/Shadow.cpp.gcov.html create mode 100644 coverage/isdb/index-sort-f.html create mode 100644 coverage/isdb/index-sort-l.html create mode 100644 coverage/isdb/index.html create mode 100644 coverage/logmfd/LogMFD.cpp.func-sort-c.html create mode 100644 coverage/logmfd/LogMFD.cpp.func.html create mode 100644 coverage/logmfd/LogMFD.cpp.gcov.html create mode 100644 coverage/logmfd/index-sort-f.html create mode 100644 coverage/logmfd/index-sort-l.html create mode 100644 coverage/logmfd/index.html create mode 100644 coverage/main/index-sort-f.html create mode 100644 coverage/main/index-sort-l.html create mode 100644 coverage/main/index.html create mode 100644 coverage/main/main.cpp.func-sort-c.html create mode 100644 coverage/main/main.cpp.func.html create mode 100644 coverage/main/main.cpp.gcov.html create mode 100644 coverage/manyrestraints/LWalls.cpp.func-sort-c.html create mode 100644 coverage/manyrestraints/LWalls.cpp.func.html create mode 100644 coverage/manyrestraints/LWalls.cpp.gcov.html create mode 100644 coverage/manyrestraints/ManyRestraintsBase.cpp.func-sort-c.html create mode 100644 coverage/manyrestraints/ManyRestraintsBase.cpp.func.html create mode 100644 coverage/manyrestraints/ManyRestraintsBase.cpp.gcov.html create mode 100644 coverage/manyrestraints/ManyRestraintsBase.h.func-sort-c.html create mode 100644 coverage/manyrestraints/ManyRestraintsBase.h.func.html create mode 100644 coverage/manyrestraints/ManyRestraintsBase.h.gcov.html create mode 100644 coverage/manyrestraints/UWalls.cpp.func-sort-c.html create mode 100644 coverage/manyrestraints/UWalls.cpp.func.html create mode 100644 coverage/manyrestraints/UWalls.cpp.gcov.html create mode 100644 coverage/manyrestraints/index-sort-f.html create mode 100644 coverage/manyrestraints/index-sort-l.html create mode 100644 coverage/manyrestraints/index.html create mode 100644 coverage/mapping/AdaptivePath.cpp.func-sort-c.html create mode 100644 coverage/mapping/AdaptivePath.cpp.func.html create mode 100644 coverage/mapping/AdaptivePath.cpp.gcov.html create mode 100644 coverage/mapping/Mapping.cpp.func-sort-c.html create mode 100644 coverage/mapping/Mapping.cpp.func.html create mode 100644 coverage/mapping/Mapping.cpp.gcov.html create mode 100644 coverage/mapping/Mapping.h.func-sort-c.html create mode 100644 coverage/mapping/Mapping.h.func.html create mode 100644 coverage/mapping/Mapping.h.gcov.html create mode 100644 coverage/mapping/PCAVars.cpp.func-sort-c.html create mode 100644 coverage/mapping/PCAVars.cpp.func.html create mode 100644 coverage/mapping/PCAVars.cpp.gcov.html create mode 100644 coverage/mapping/Path.cpp.func-sort-c.html create mode 100644 coverage/mapping/Path.cpp.func.html create mode 100644 coverage/mapping/Path.cpp.gcov.html create mode 100644 coverage/mapping/PathBase.cpp.func-sort-c.html create mode 100644 coverage/mapping/PathBase.cpp.func.html create mode 100644 coverage/mapping/PathBase.cpp.gcov.html create mode 100644 coverage/mapping/PathReparameterization.cpp.func-sort-c.html create mode 100644 coverage/mapping/PathReparameterization.cpp.func.html create mode 100644 coverage/mapping/PathReparameterization.cpp.gcov.html create mode 100644 coverage/mapping/PathTools.cpp.func-sort-c.html create mode 100644 coverage/mapping/PathTools.cpp.func.html create mode 100644 coverage/mapping/PathTools.cpp.gcov.html create mode 100644 coverage/mapping/PropertyMap.cpp.func-sort-c.html create mode 100644 coverage/mapping/PropertyMap.cpp.func.html create mode 100644 coverage/mapping/PropertyMap.cpp.gcov.html create mode 100644 coverage/mapping/SpathVessel.cpp.func-sort-c.html create mode 100644 coverage/mapping/SpathVessel.cpp.func.html create mode 100644 coverage/mapping/SpathVessel.cpp.gcov.html create mode 100644 coverage/mapping/TrigonometricPathVessel.cpp.func-sort-c.html create mode 100644 coverage/mapping/TrigonometricPathVessel.cpp.func.html create mode 100644 coverage/mapping/TrigonometricPathVessel.cpp.gcov.html create mode 100644 coverage/mapping/ZpathVessel.cpp.func-sort-c.html create mode 100644 coverage/mapping/ZpathVessel.cpp.func.html create mode 100644 coverage/mapping/ZpathVessel.cpp.gcov.html create mode 100644 coverage/mapping/index-sort-f.html create mode 100644 coverage/mapping/index-sort-l.html create mode 100644 coverage/mapping/index.html create mode 100644 coverage/maze/Loss.cpp.func-sort-c.html create mode 100644 coverage/maze/Loss.cpp.func.html create mode 100644 coverage/maze/Loss.cpp.gcov.html create mode 100644 coverage/maze/Loss.h.func-sort-c.html create mode 100644 coverage/maze/Loss.h.func.html create mode 100644 coverage/maze/Loss.h.gcov.html create mode 100644 coverage/maze/Member.h.func-sort-c.html create mode 100644 coverage/maze/Member.h.func.html create mode 100644 coverage/maze/Member.h.gcov.html create mode 100644 coverage/maze/Memetic.cpp.func-sort-c.html create mode 100644 coverage/maze/Memetic.cpp.func.html create mode 100644 coverage/maze/Memetic.cpp.gcov.html create mode 100644 coverage/maze/Memetic.h.func-sort-c.html create mode 100644 coverage/maze/Memetic.h.func.html create mode 100644 coverage/maze/Memetic.h.gcov.html create mode 100644 coverage/maze/Optimizer.cpp.func-sort-c.html create mode 100644 coverage/maze/Optimizer.cpp.func.html create mode 100644 coverage/maze/Optimizer.cpp.gcov.html create mode 100644 coverage/maze/Optimizer.h.func-sort-c.html create mode 100644 coverage/maze/Optimizer.h.func.html create mode 100644 coverage/maze/Optimizer.h.gcov.html create mode 100644 coverage/maze/Optimizer_Bias.cpp.func-sort-c.html create mode 100644 coverage/maze/Optimizer_Bias.cpp.func.html create mode 100644 coverage/maze/Optimizer_Bias.cpp.gcov.html create mode 100644 coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html create mode 100644 coverage/maze/Random_Acceleration_MD.cpp.func.html create mode 100644 coverage/maze/Random_Acceleration_MD.cpp.gcov.html create mode 100644 coverage/maze/Random_MT.cpp.func-sort-c.html create mode 100644 coverage/maze/Random_MT.cpp.func.html create mode 100644 coverage/maze/Random_MT.cpp.gcov.html create mode 100644 coverage/maze/Random_MT.h.func-sort-c.html create mode 100644 coverage/maze/Random_MT.h.func.html create mode 100644 coverage/maze/Random_MT.h.gcov.html create mode 100644 coverage/maze/Random_Walk.cpp.func-sort-c.html create mode 100644 coverage/maze/Random_Walk.cpp.func.html create mode 100644 coverage/maze/Random_Walk.cpp.gcov.html create mode 100644 coverage/maze/Simulated_Annealing.cpp.func-sort-c.html create mode 100644 coverage/maze/Simulated_Annealing.cpp.func.html create mode 100644 coverage/maze/Simulated_Annealing.cpp.gcov.html create mode 100644 coverage/maze/Steered_MD.cpp.func-sort-c.html create mode 100644 coverage/maze/Steered_MD.cpp.func.html create mode 100644 coverage/maze/Steered_MD.cpp.gcov.html create mode 100644 coverage/maze/Tools.h.func-sort-c.html create mode 100644 coverage/maze/Tools.h.func.html create mode 100644 coverage/maze/Tools.h.gcov.html create mode 100644 coverage/maze/index-sort-f.html create mode 100644 coverage/maze/index-sort-l.html create mode 100644 coverage/maze/index.html create mode 100644 coverage/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html create mode 100644 coverage/membranefusion/FusionPoreExpansionP.cpp.func.html create mode 100644 coverage/membranefusion/FusionPoreExpansionP.cpp.gcov.html create mode 100644 coverage/membranefusion/FusionPoreNucleationP.cpp.func-sort-c.html create mode 100644 coverage/membranefusion/FusionPoreNucleationP.cpp.func.html create mode 100644 coverage/membranefusion/FusionPoreNucleationP.cpp.gcov.html create mode 100644 coverage/membranefusion/MemFusionP.cpp.func-sort-c.html create mode 100644 coverage/membranefusion/MemFusionP.cpp.func.html create mode 100644 coverage/membranefusion/MemFusionP.cpp.gcov.html create mode 100644 coverage/membranefusion/index-sort-f.html create mode 100644 coverage/membranefusion/index-sort-l.html create mode 100644 coverage/membranefusion/index.html create mode 100644 coverage/multicolvar/ActionVolume.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/ActionVolume.cpp.func.html create mode 100644 coverage/multicolvar/ActionVolume.cpp.gcov.html create mode 100644 coverage/multicolvar/ActionVolume.h.func-sort-c.html create mode 100644 coverage/multicolvar/ActionVolume.h.func.html create mode 100644 coverage/multicolvar/ActionVolume.h.gcov.html create mode 100644 coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/AlphaBeta.cpp.func.html create mode 100644 coverage/multicolvar/AlphaBeta.cpp.gcov.html create mode 100644 coverage/multicolvar/Angles.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Angles.cpp.func.html create mode 100644 coverage/multicolvar/Angles.cpp.gcov.html create mode 100644 coverage/multicolvar/AtomValuePack.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/AtomValuePack.cpp.func.html create mode 100644 coverage/multicolvar/AtomValuePack.cpp.gcov.html create mode 100644 coverage/multicolvar/AtomValuePack.h.func-sort-c.html create mode 100644 coverage/multicolvar/AtomValuePack.h.func.html create mode 100644 coverage/multicolvar/AtomValuePack.h.gcov.html create mode 100644 coverage/multicolvar/Bridge.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Bridge.cpp.func.html create mode 100644 coverage/multicolvar/Bridge.cpp.gcov.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.cpp.func.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.cpp.gcov.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.h.func-sort-c.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.h.func.html create mode 100644 coverage/multicolvar/BridgedMultiColvarFunction.h.gcov.html create mode 100644 coverage/multicolvar/CatomPack.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/CatomPack.cpp.func.html create mode 100644 coverage/multicolvar/CatomPack.cpp.gcov.html create mode 100644 coverage/multicolvar/CatomPack.h.func-sort-c.html create mode 100644 coverage/multicolvar/CatomPack.h.func.html create mode 100644 coverage/multicolvar/CatomPack.h.gcov.html create mode 100644 coverage/multicolvar/CenterOfMultiColvar.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/CenterOfMultiColvar.cpp.func.html create mode 100644 coverage/multicolvar/CenterOfMultiColvar.cpp.gcov.html create mode 100644 coverage/multicolvar/CoordinationNumbers.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/CoordinationNumbers.cpp.func.html create mode 100644 coverage/multicolvar/CoordinationNumbers.cpp.gcov.html create mode 100644 coverage/multicolvar/Density.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Density.cpp.func.html create mode 100644 coverage/multicolvar/Density.cpp.gcov.html create mode 100644 coverage/multicolvar/DihedralCorrelation.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/DihedralCorrelation.cpp.func.html create mode 100644 coverage/multicolvar/DihedralCorrelation.cpp.gcov.html create mode 100644 coverage/multicolvar/DistanceFromContour.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/DistanceFromContour.cpp.func.html create mode 100644 coverage/multicolvar/DistanceFromContour.cpp.gcov.html create mode 100644 coverage/multicolvar/Distances.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Distances.cpp.func.html create mode 100644 coverage/multicolvar/Distances.cpp.gcov.html create mode 100644 coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/DumpMultiColvar.cpp.func.html create mode 100644 coverage/multicolvar/DumpMultiColvar.cpp.gcov.html create mode 100644 coverage/multicolvar/FilterBetween.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/FilterBetween.cpp.func.html create mode 100644 coverage/multicolvar/FilterBetween.cpp.gcov.html create mode 100644 coverage/multicolvar/FilterLessThan.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/FilterLessThan.cpp.func.html create mode 100644 coverage/multicolvar/FilterLessThan.cpp.gcov.html create mode 100644 coverage/multicolvar/FilterMoreThan.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/FilterMoreThan.cpp.func.html create mode 100644 coverage/multicolvar/FilterMoreThan.cpp.gcov.html create mode 100644 coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/InPlaneDistances.cpp.func.html create mode 100644 coverage/multicolvar/InPlaneDistances.cpp.gcov.html create mode 100644 coverage/multicolvar/LocalAverage.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/LocalAverage.cpp.func.html create mode 100644 coverage/multicolvar/LocalAverage.cpp.gcov.html create mode 100644 coverage/multicolvar/MultiColvarBase.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarBase.cpp.func.html create mode 100644 coverage/multicolvar/MultiColvarBase.cpp.gcov.html create mode 100644 coverage/multicolvar/MultiColvarBase.h.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarBase.h.func.html create mode 100644 coverage/multicolvar/MultiColvarBase.h.gcov.html create mode 100644 coverage/multicolvar/MultiColvarCombine.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarCombine.cpp.func.html create mode 100644 coverage/multicolvar/MultiColvarCombine.cpp.gcov.html create mode 100644 coverage/multicolvar/MultiColvarDensity.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarDensity.cpp.func.html create mode 100644 coverage/multicolvar/MultiColvarDensity.cpp.gcov.html create mode 100644 coverage/multicolvar/MultiColvarFilter.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarFilter.cpp.func.html create mode 100644 coverage/multicolvar/MultiColvarFilter.cpp.gcov.html create mode 100644 coverage/multicolvar/MultiColvarFilter.h.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarFilter.h.func.html create mode 100644 coverage/multicolvar/MultiColvarFilter.h.gcov.html create mode 100644 coverage/multicolvar/MultiColvarProduct.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/MultiColvarProduct.cpp.func.html create mode 100644 coverage/multicolvar/MultiColvarProduct.cpp.gcov.html create mode 100644 coverage/multicolvar/NumberOfLinks.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/NumberOfLinks.cpp.func.html create mode 100644 coverage/multicolvar/NumberOfLinks.cpp.gcov.html create mode 100644 coverage/multicolvar/Torsions.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/Torsions.cpp.func.html create mode 100644 coverage/multicolvar/Torsions.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeAround.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeAround.cpp.func.html create mode 100644 coverage/multicolvar/VolumeAround.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeBetweenContours.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeBetweenContours.cpp.func.html create mode 100644 coverage/multicolvar/VolumeBetweenContours.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeCavity.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeCavity.cpp.func.html create mode 100644 coverage/multicolvar/VolumeCavity.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeGradientBase.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeGradientBase.cpp.func.html create mode 100644 coverage/multicolvar/VolumeGradientBase.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeGradientBase.h.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeGradientBase.h.func.html create mode 100644 coverage/multicolvar/VolumeGradientBase.h.gcov.html create mode 100644 coverage/multicolvar/VolumeInCylinder.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeInCylinder.cpp.func.html create mode 100644 coverage/multicolvar/VolumeInCylinder.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeInSphere.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeInSphere.cpp.func.html create mode 100644 coverage/multicolvar/VolumeInSphere.cpp.gcov.html create mode 100644 coverage/multicolvar/VolumeTetrapore.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/VolumeTetrapore.cpp.func.html create mode 100644 coverage/multicolvar/VolumeTetrapore.cpp.gcov.html create mode 100644 coverage/multicolvar/XAngle.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/XAngle.cpp.func.html create mode 100644 coverage/multicolvar/XAngle.cpp.gcov.html create mode 100644 coverage/multicolvar/XDistances.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/XDistances.cpp.func.html create mode 100644 coverage/multicolvar/XDistances.cpp.gcov.html create mode 100644 coverage/multicolvar/XYDistances.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/XYDistances.cpp.func.html create mode 100644 coverage/multicolvar/XYDistances.cpp.gcov.html create mode 100644 coverage/multicolvar/XYTorsion.cpp.func-sort-c.html create mode 100644 coverage/multicolvar/XYTorsion.cpp.func.html create mode 100644 coverage/multicolvar/XYTorsion.cpp.gcov.html create mode 100644 coverage/multicolvar/index-sort-f.html create mode 100644 coverage/multicolvar/index-sort-l.html create mode 100644 coverage/multicolvar/index.html create mode 100644 coverage/opes/ECVcustom.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVcustom.cpp.func.html create mode 100644 coverage/opes/ECVcustom.cpp.gcov.html create mode 100644 coverage/opes/ECVlinear.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVlinear.cpp.func.html create mode 100644 coverage/opes/ECVlinear.cpp.gcov.html create mode 100644 coverage/opes/ECVmultiThermal.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVmultiThermal.cpp.func.html create mode 100644 coverage/opes/ECVmultiThermal.cpp.gcov.html create mode 100644 coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVmultiThermalBaric.cpp.func.html create mode 100644 coverage/opes/ECVmultiThermalBaric.cpp.gcov.html create mode 100644 coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVumbrellasFile.cpp.func.html create mode 100644 coverage/opes/ECVumbrellasFile.cpp.gcov.html create mode 100644 coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html create mode 100644 coverage/opes/ECVumbrellasLine.cpp.func.html create mode 100644 coverage/opes/ECVumbrellasLine.cpp.gcov.html create mode 100644 coverage/opes/ExpansionCVs.cpp.func-sort-c.html create mode 100644 coverage/opes/ExpansionCVs.cpp.func.html create mode 100644 coverage/opes/ExpansionCVs.cpp.gcov.html create mode 100644 coverage/opes/ExpansionCVs.h.func-sort-c.html create mode 100644 coverage/opes/ExpansionCVs.h.func.html create mode 100644 coverage/opes/ExpansionCVs.h.gcov.html create mode 100644 coverage/opes/OPESexpanded.cpp.func-sort-c.html create mode 100644 coverage/opes/OPESexpanded.cpp.func.html create mode 100644 coverage/opes/OPESexpanded.cpp.gcov.html create mode 100644 coverage/opes/OPESmetad.cpp.func-sort-c.html create mode 100644 coverage/opes/OPESmetad.cpp.func.html create mode 100644 coverage/opes/OPESmetad.cpp.gcov.html create mode 100644 coverage/opes/index-sort-f.html create mode 100644 coverage/opes/index-sort-l.html create mode 100644 coverage/opes/index.html create mode 100644 coverage/pamm/HBPammHydrogens.cpp.func-sort-c.html create mode 100644 coverage/pamm/HBPammHydrogens.cpp.func.html create mode 100644 coverage/pamm/HBPammHydrogens.cpp.gcov.html create mode 100644 coverage/pamm/HBPammMatrix.cpp.func-sort-c.html create mode 100644 coverage/pamm/HBPammMatrix.cpp.func.html create mode 100644 coverage/pamm/HBPammMatrix.cpp.gcov.html create mode 100644 coverage/pamm/HBPammObject.cpp.func-sort-c.html create mode 100644 coverage/pamm/HBPammObject.cpp.func.html create mode 100644 coverage/pamm/HBPammObject.cpp.gcov.html create mode 100644 coverage/pamm/HBPammObject.h.func-sort-c.html create mode 100644 coverage/pamm/HBPammObject.h.func.html create mode 100644 coverage/pamm/HBPammObject.h.gcov.html create mode 100644 coverage/pamm/PAMM.cpp.func-sort-c.html create mode 100644 coverage/pamm/PAMM.cpp.func.html create mode 100644 coverage/pamm/PAMM.cpp.gcov.html create mode 100644 coverage/pamm/PammObject.cpp.func-sort-c.html create mode 100644 coverage/pamm/PammObject.cpp.func.html create mode 100644 coverage/pamm/PammObject.cpp.gcov.html create mode 100644 coverage/pamm/PammObject.h.func-sort-c.html create mode 100644 coverage/pamm/PammObject.h.func.html create mode 100644 coverage/pamm/PammObject.h.gcov.html create mode 100644 coverage/pamm/index-sort-f.html create mode 100644 coverage/pamm/index-sort-l.html create mode 100644 coverage/pamm/index.html create mode 100644 coverage/piv/PIV.cpp.func-sort-c.html create mode 100644 coverage/piv/PIV.cpp.func.html create mode 100644 coverage/piv/PIV.cpp.gcov.html create mode 100644 coverage/piv/index-sort-f.html create mode 100644 coverage/piv/index-sort-l.html create mode 100644 coverage/piv/index.html create mode 100644 coverage/pytorch/PytorchModel.cpp.func-sort-c.html create mode 100644 coverage/pytorch/PytorchModel.cpp.func.html create mode 100644 coverage/pytorch/PytorchModel.cpp.gcov.html create mode 100644 coverage/pytorch/index-sort-f.html create mode 100644 coverage/pytorch/index-sort-l.html create mode 100644 coverage/pytorch/index.html create mode 100644 coverage/reference/ArgumentOnlyDistance.cpp.func-sort-c.html create mode 100644 coverage/reference/ArgumentOnlyDistance.cpp.func.html create mode 100644 coverage/reference/ArgumentOnlyDistance.cpp.gcov.html create mode 100644 coverage/reference/ArgumentOnlyDistance.h.func-sort-c.html create mode 100644 coverage/reference/ArgumentOnlyDistance.h.func.html create mode 100644 coverage/reference/ArgumentOnlyDistance.h.gcov.html create mode 100644 coverage/reference/DRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/DRMSD.cpp.func.html create mode 100644 coverage/reference/DRMSD.cpp.gcov.html create mode 100644 coverage/reference/Direction.cpp.func-sort-c.html create mode 100644 coverage/reference/Direction.cpp.func.html create mode 100644 coverage/reference/Direction.cpp.gcov.html create mode 100644 coverage/reference/Direction.h.func-sort-c.html create mode 100644 coverage/reference/Direction.h.func.html create mode 100644 coverage/reference/Direction.h.gcov.html create mode 100644 coverage/reference/DotProductDistance.cpp.func-sort-c.html create mode 100644 coverage/reference/DotProductDistance.cpp.func.html create mode 100644 coverage/reference/DotProductDistance.cpp.gcov.html create mode 100644 coverage/reference/EuclideanDistance.cpp.func-sort-c.html create mode 100644 coverage/reference/EuclideanDistance.cpp.func.html create mode 100644 coverage/reference/EuclideanDistance.cpp.gcov.html create mode 100644 coverage/reference/IntermolecularDRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/IntermolecularDRMSD.cpp.func.html create mode 100644 coverage/reference/IntermolecularDRMSD.cpp.gcov.html create mode 100644 coverage/reference/IntramolecularDRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/IntramolecularDRMSD.cpp.func.html create mode 100644 coverage/reference/IntramolecularDRMSD.cpp.gcov.html create mode 100644 coverage/reference/MahalanobisDistance.cpp.func-sort-c.html create mode 100644 coverage/reference/MahalanobisDistance.cpp.func.html create mode 100644 coverage/reference/MahalanobisDistance.cpp.gcov.html create mode 100644 coverage/reference/MetricRegister.cpp.func-sort-c.html create mode 100644 coverage/reference/MetricRegister.cpp.func.html create mode 100644 coverage/reference/MetricRegister.cpp.gcov.html create mode 100644 coverage/reference/MetricRegister.h.func-sort-c.html create mode 100644 coverage/reference/MetricRegister.h.func.html create mode 100644 coverage/reference/MetricRegister.h.gcov.html create mode 100644 coverage/reference/MultiDomainRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/MultiDomainRMSD.cpp.func.html create mode 100644 coverage/reference/MultiDomainRMSD.cpp.gcov.html create mode 100644 coverage/reference/NormalizedEuclideanDistance.cpp.func-sort-c.html create mode 100644 coverage/reference/NormalizedEuclideanDistance.cpp.func.html create mode 100644 coverage/reference/NormalizedEuclideanDistance.cpp.gcov.html create mode 100644 coverage/reference/OptimalRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/OptimalRMSD.cpp.func.html create mode 100644 coverage/reference/OptimalRMSD.cpp.gcov.html create mode 100644 coverage/reference/RMSDBase.cpp.func-sort-c.html create mode 100644 coverage/reference/RMSDBase.cpp.func.html create mode 100644 coverage/reference/RMSDBase.cpp.gcov.html create mode 100644 coverage/reference/ReferenceArguments.cpp.func-sort-c.html create mode 100644 coverage/reference/ReferenceArguments.cpp.func.html create mode 100644 coverage/reference/ReferenceArguments.cpp.gcov.html create mode 100644 coverage/reference/ReferenceArguments.h.func-sort-c.html create mode 100644 coverage/reference/ReferenceArguments.h.func.html create mode 100644 coverage/reference/ReferenceArguments.h.gcov.html create mode 100644 coverage/reference/ReferenceAtoms.cpp.func-sort-c.html create mode 100644 coverage/reference/ReferenceAtoms.cpp.func.html create mode 100644 coverage/reference/ReferenceAtoms.cpp.gcov.html create mode 100644 coverage/reference/ReferenceAtoms.h.func-sort-c.html create mode 100644 coverage/reference/ReferenceAtoms.h.func.html create mode 100644 coverage/reference/ReferenceAtoms.h.gcov.html create mode 100644 coverage/reference/ReferenceConfiguration.cpp.func-sort-c.html create mode 100644 coverage/reference/ReferenceConfiguration.cpp.func.html create mode 100644 coverage/reference/ReferenceConfiguration.cpp.gcov.html create mode 100644 coverage/reference/ReferenceConfiguration.h.func-sort-c.html create mode 100644 coverage/reference/ReferenceConfiguration.h.func.html create mode 100644 coverage/reference/ReferenceConfiguration.h.gcov.html create mode 100644 coverage/reference/ReferenceValuePack.cpp.func-sort-c.html create mode 100644 coverage/reference/ReferenceValuePack.cpp.func.html create mode 100644 coverage/reference/ReferenceValuePack.cpp.gcov.html create mode 100644 coverage/reference/ReferenceValuePack.h.func-sort-c.html create mode 100644 coverage/reference/ReferenceValuePack.h.func.html create mode 100644 coverage/reference/ReferenceValuePack.h.gcov.html create mode 100644 coverage/reference/SimpleRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/SimpleRMSD.cpp.func.html create mode 100644 coverage/reference/SimpleRMSD.cpp.gcov.html create mode 100644 coverage/reference/SingleDomainRMSD.cpp.func-sort-c.html create mode 100644 coverage/reference/SingleDomainRMSD.cpp.func.html create mode 100644 coverage/reference/SingleDomainRMSD.cpp.gcov.html create mode 100644 coverage/reference/SingleDomainRMSD.h.func-sort-c.html create mode 100644 coverage/reference/SingleDomainRMSD.h.func.html create mode 100644 coverage/reference/SingleDomainRMSD.h.gcov.html create mode 100644 coverage/reference/index-sort-f.html create mode 100644 coverage/reference/index-sort-l.html create mode 100644 coverage/reference/index.html create mode 100644 coverage/ruby.png create mode 100644 coverage/s2cm/S2ContactModel.cpp.func-sort-c.html create mode 100644 coverage/s2cm/S2ContactModel.cpp.func.html create mode 100644 coverage/s2cm/S2ContactModel.cpp.gcov.html create mode 100644 coverage/s2cm/index-sort-f.html create mode 100644 coverage/s2cm/index-sort-l.html create mode 100644 coverage/s2cm/index.html create mode 100644 coverage/sasa/index-sort-f.html create mode 100644 coverage/sasa/index-sort-l.html create mode 100644 coverage/sasa/index.html create mode 100644 coverage/sasa/sasa_HASEL.cpp.func-sort-c.html create mode 100644 coverage/sasa/sasa_HASEL.cpp.func.html create mode 100644 coverage/sasa/sasa_HASEL.cpp.gcov.html create mode 100644 coverage/sasa/sasa_LCPO.cpp.func-sort-c.html create mode 100644 coverage/sasa/sasa_LCPO.cpp.func.html create mode 100644 coverage/sasa/sasa_LCPO.cpp.gcov.html create mode 100644 coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/AlphaRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/AlphaRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/AntibetaRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/ParabetaRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.h.func.html create mode 100644 coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html create mode 100644 coverage/secondarystructure/index-sort-f.html create mode 100644 coverage/secondarystructure/index-sort-l.html create mode 100644 coverage/secondarystructure/index.html create mode 100644 coverage/setup/Load.cpp.func-sort-c.html create mode 100644 coverage/setup/Load.cpp.func.html create mode 100644 coverage/setup/Load.cpp.gcov.html create mode 100644 coverage/setup/Restart.cpp.func-sort-c.html create mode 100644 coverage/setup/Restart.cpp.func.html create mode 100644 coverage/setup/Restart.cpp.gcov.html create mode 100644 coverage/setup/Units.cpp.func-sort-c.html create mode 100644 coverage/setup/Units.cpp.func.html create mode 100644 coverage/setup/Units.cpp.gcov.html create mode 100644 coverage/setup/index-sort-f.html create mode 100644 coverage/setup/index-sort-l.html create mode 100644 coverage/setup/index.html create mode 100644 coverage/small_vector/index-sort-f.html create mode 100644 coverage/small_vector/index-sort-l.html create mode 100644 coverage/small_vector/index.html create mode 100644 coverage/small_vector/small_vector.h.func-sort-c.html create mode 100644 coverage/small_vector/small_vector.h.func.html create mode 100644 coverage/small_vector/small_vector.h.gcov.html create mode 100644 coverage/snow.png create mode 100644 coverage/tools/Angle.cpp.func-sort-c.html create mode 100644 coverage/tools/Angle.cpp.func.html create mode 100644 coverage/tools/Angle.cpp.gcov.html create mode 100644 coverage/tools/AtomNumber.h.func-sort-c.html create mode 100644 coverage/tools/AtomNumber.h.func.html create mode 100644 coverage/tools/AtomNumber.h.gcov.html create mode 100644 coverage/tools/BiasRepresentation.cpp.func-sort-c.html create mode 100644 coverage/tools/BiasRepresentation.cpp.func.html create mode 100644 coverage/tools/BiasRepresentation.cpp.gcov.html create mode 100644 coverage/tools/Brent1DRootSearch.h.func-sort-c.html create mode 100644 coverage/tools/Brent1DRootSearch.h.func.html create mode 100644 coverage/tools/Brent1DRootSearch.h.gcov.html create mode 100644 coverage/tools/Citations.cpp.func-sort-c.html create mode 100644 coverage/tools/Citations.cpp.func.html create mode 100644 coverage/tools/Citations.cpp.gcov.html create mode 100644 coverage/tools/Citations.h.func-sort-c.html create mode 100644 coverage/tools/Citations.h.func.html create mode 100644 coverage/tools/Citations.h.gcov.html create mode 100644 coverage/tools/Communicator.cpp.func-sort-c.html create mode 100644 coverage/tools/Communicator.cpp.func.html create mode 100644 coverage/tools/Communicator.cpp.gcov.html create mode 100644 coverage/tools/Communicator.h.func-sort-c.html create mode 100644 coverage/tools/Communicator.h.func.html create mode 100644 coverage/tools/Communicator.h.gcov.html create mode 100644 coverage/tools/ConjugateGradient.h.func-sort-c.html create mode 100644 coverage/tools/ConjugateGradient.h.func.html create mode 100644 coverage/tools/ConjugateGradient.h.gcov.html create mode 100644 coverage/tools/DLLoader.cpp.func-sort-c.html create mode 100644 coverage/tools/DLLoader.cpp.func.html create mode 100644 coverage/tools/DLLoader.cpp.gcov.html create mode 100644 coverage/tools/DynamicList.h.func-sort-c.html create mode 100644 coverage/tools/DynamicList.h.func.html create mode 100644 coverage/tools/DynamicList.h.gcov.html create mode 100644 coverage/tools/ERMSD.cpp.func-sort-c.html create mode 100644 coverage/tools/ERMSD.cpp.func.html create mode 100644 coverage/tools/ERMSD.cpp.gcov.html create mode 100644 coverage/tools/ERMSD.h.func-sort-c.html create mode 100644 coverage/tools/ERMSD.h.func.html create mode 100644 coverage/tools/ERMSD.h.gcov.html create mode 100644 coverage/tools/Exception.cpp.func-sort-c.html create mode 100644 coverage/tools/Exception.cpp.func.html create mode 100644 coverage/tools/Exception.cpp.gcov.html create mode 100644 coverage/tools/Exception.h.func-sort-c.html create mode 100644 coverage/tools/Exception.h.func.html create mode 100644 coverage/tools/Exception.h.gcov.html create mode 100644 coverage/tools/FileBase.cpp.func-sort-c.html create mode 100644 coverage/tools/FileBase.cpp.func.html create mode 100644 coverage/tools/FileBase.cpp.gcov.html create mode 100644 coverage/tools/FileBase.h.func-sort-c.html create mode 100644 coverage/tools/FileBase.h.func.html create mode 100644 coverage/tools/FileBase.h.gcov.html create mode 100644 coverage/tools/ForwardDecl.h.func-sort-c.html create mode 100644 coverage/tools/ForwardDecl.h.func.html create mode 100644 coverage/tools/ForwardDecl.h.gcov.html create mode 100644 coverage/tools/Grid.cpp.func-sort-c.html create mode 100644 coverage/tools/Grid.cpp.func.html create mode 100644 coverage/tools/Grid.cpp.gcov.html create mode 100644 coverage/tools/Grid.h.func-sort-c.html create mode 100644 coverage/tools/Grid.h.func.html create mode 100644 coverage/tools/Grid.h.gcov.html create mode 100644 coverage/tools/HistogramBead.cpp.func-sort-c.html create mode 100644 coverage/tools/HistogramBead.cpp.func.html create mode 100644 coverage/tools/HistogramBead.cpp.gcov.html create mode 100644 coverage/tools/HistogramBead.h.func-sort-c.html create mode 100644 coverage/tools/HistogramBead.h.func.html create mode 100644 coverage/tools/HistogramBead.h.gcov.html create mode 100644 coverage/tools/IFile.cpp.func-sort-c.html create mode 100644 coverage/tools/IFile.cpp.func.html create mode 100644 coverage/tools/IFile.cpp.gcov.html create mode 100644 coverage/tools/IFile.h.func-sort-c.html create mode 100644 coverage/tools/IFile.h.func.html create mode 100644 coverage/tools/IFile.h.gcov.html create mode 100644 coverage/tools/KernelFunctions.cpp.func-sort-c.html create mode 100644 coverage/tools/KernelFunctions.cpp.func.html create mode 100644 coverage/tools/KernelFunctions.cpp.gcov.html create mode 100644 coverage/tools/KernelFunctions.h.func-sort-c.html create mode 100644 coverage/tools/KernelFunctions.h.func.html create mode 100644 coverage/tools/KernelFunctions.h.gcov.html create mode 100644 coverage/tools/Keywords.cpp.func-sort-c.html create mode 100644 coverage/tools/Keywords.cpp.func.html create mode 100644 coverage/tools/Keywords.cpp.gcov.html create mode 100644 coverage/tools/Keywords.h.func-sort-c.html create mode 100644 coverage/tools/Keywords.h.func.html create mode 100644 coverage/tools/Keywords.h.gcov.html create mode 100644 coverage/tools/LatticeReduction.cpp.func-sort-c.html create mode 100644 coverage/tools/LatticeReduction.cpp.func.html create mode 100644 coverage/tools/LatticeReduction.cpp.gcov.html create mode 100644 coverage/tools/LinkCells.cpp.func-sort-c.html create mode 100644 coverage/tools/LinkCells.cpp.func.html create mode 100644 coverage/tools/LinkCells.cpp.gcov.html create mode 100644 coverage/tools/LinkCells.h.func-sort-c.html create mode 100644 coverage/tools/LinkCells.h.func.html create mode 100644 coverage/tools/LinkCells.h.gcov.html create mode 100644 coverage/tools/LoopUnroller.h.func-sort-c.html create mode 100644 coverage/tools/LoopUnroller.h.func.html create mode 100644 coverage/tools/LoopUnroller.h.gcov.html create mode 100644 coverage/tools/Matrix.h.func-sort-c.html create mode 100644 coverage/tools/Matrix.h.func.html create mode 100644 coverage/tools/Matrix.h.gcov.html create mode 100644 coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html create mode 100644 coverage/tools/MatrixSquareBracketsAccess.h.func.html create mode 100644 coverage/tools/MatrixSquareBracketsAccess.h.gcov.html create mode 100644 coverage/tools/Minimise1DBrent.h.func-sort-c.html create mode 100644 coverage/tools/Minimise1DBrent.h.func.html create mode 100644 coverage/tools/Minimise1DBrent.h.gcov.html create mode 100644 coverage/tools/MinimiseBase.h.func-sort-c.html create mode 100644 coverage/tools/MinimiseBase.h.func.html create mode 100644 coverage/tools/MinimiseBase.h.gcov.html create mode 100644 coverage/tools/MolDataClass.cpp.func-sort-c.html create mode 100644 coverage/tools/MolDataClass.cpp.func.html create mode 100644 coverage/tools/MolDataClass.cpp.gcov.html create mode 100644 coverage/tools/MultiValue.cpp.func-sort-c.html create mode 100644 coverage/tools/MultiValue.cpp.func.html create mode 100644 coverage/tools/MultiValue.cpp.gcov.html create mode 100644 coverage/tools/MultiValue.h.func-sort-c.html create mode 100644 coverage/tools/MultiValue.h.func.html create mode 100644 coverage/tools/MultiValue.h.gcov.html create mode 100644 coverage/tools/NeighborList.cpp.func-sort-c.html create mode 100644 coverage/tools/NeighborList.cpp.func.html create mode 100644 coverage/tools/NeighborList.cpp.gcov.html create mode 100644 coverage/tools/NeighborList.h.func-sort-c.html create mode 100644 coverage/tools/NeighborList.h.func.html create mode 100644 coverage/tools/NeighborList.h.gcov.html create mode 100644 coverage/tools/OFile.cpp.func-sort-c.html create mode 100644 coverage/tools/OFile.cpp.func.html create mode 100644 coverage/tools/OFile.cpp.gcov.html create mode 100644 coverage/tools/OFile.h.func-sort-c.html create mode 100644 coverage/tools/OFile.h.func.html create mode 100644 coverage/tools/OFile.h.gcov.html create mode 100644 coverage/tools/OpenMP.cpp.func-sort-c.html create mode 100644 coverage/tools/OpenMP.cpp.func.html create mode 100644 coverage/tools/OpenMP.cpp.gcov.html create mode 100644 coverage/tools/OpenMP.h.func-sort-c.html create mode 100644 coverage/tools/OpenMP.h.func.html create mode 100644 coverage/tools/OpenMP.h.gcov.html create mode 100644 coverage/tools/PDB.cpp.func-sort-c.html create mode 100644 coverage/tools/PDB.cpp.func.html create mode 100644 coverage/tools/PDB.cpp.gcov.html create mode 100644 coverage/tools/Pbc.cpp.func-sort-c.html create mode 100644 coverage/tools/Pbc.cpp.func.html create mode 100644 coverage/tools/Pbc.cpp.gcov.html create mode 100644 coverage/tools/Pbc.h.func-sort-c.html create mode 100644 coverage/tools/Pbc.h.func.html create mode 100644 coverage/tools/Pbc.h.gcov.html create mode 100644 coverage/tools/PlumedHandle.cpp.func-sort-c.html create mode 100644 coverage/tools/PlumedHandle.cpp.func.html create mode 100644 coverage/tools/PlumedHandle.cpp.gcov.html create mode 100644 coverage/tools/RMSD.cpp.func-sort-c.html create mode 100644 coverage/tools/RMSD.cpp.func.html create mode 100644 coverage/tools/RMSD.cpp.gcov.html create mode 100644 coverage/tools/RMSD.h.func-sort-c.html create mode 100644 coverage/tools/RMSD.h.func.html create mode 100644 coverage/tools/RMSD.h.gcov.html create mode 100644 coverage/tools/Random.cpp.func-sort-c.html create mode 100644 coverage/tools/Random.cpp.func.html create mode 100644 coverage/tools/Random.cpp.gcov.html create mode 100644 coverage/tools/Random.h.func-sort-c.html create mode 100644 coverage/tools/Random.h.func.html create mode 100644 coverage/tools/Random.h.gcov.html create mode 100644 coverage/tools/RootFindingBase.h.func-sort-c.html create mode 100644 coverage/tools/RootFindingBase.h.func.html create mode 100644 coverage/tools/RootFindingBase.h.gcov.html create mode 100644 coverage/tools/Stopwatch.cpp.func-sort-c.html create mode 100644 coverage/tools/Stopwatch.cpp.func.html create mode 100644 coverage/tools/Stopwatch.cpp.gcov.html create mode 100644 coverage/tools/Stopwatch.h.func-sort-c.html create mode 100644 coverage/tools/Stopwatch.h.func.html create mode 100644 coverage/tools/Stopwatch.h.gcov.html create mode 100644 coverage/tools/Subprocess.cpp.func-sort-c.html create mode 100644 coverage/tools/Subprocess.cpp.func.html create mode 100644 coverage/tools/Subprocess.cpp.gcov.html create mode 100644 coverage/tools/Subprocess.h.func-sort-c.html create mode 100644 coverage/tools/Subprocess.h.func.html create mode 100644 coverage/tools/Subprocess.h.gcov.html create mode 100644 coverage/tools/SwitchingFunction.cpp.func-sort-c.html create mode 100644 coverage/tools/SwitchingFunction.cpp.func.html create mode 100644 coverage/tools/SwitchingFunction.cpp.gcov.html create mode 100644 coverage/tools/Tensor.cpp.func-sort-c.html create mode 100644 coverage/tools/Tensor.cpp.func.html create mode 100644 coverage/tools/Tensor.cpp.gcov.html create mode 100644 coverage/tools/Tensor.h.func-sort-c.html create mode 100644 coverage/tools/Tensor.h.func.html create mode 100644 coverage/tools/Tensor.h.gcov.html create mode 100644 coverage/tools/Tools.cpp.func-sort-c.html create mode 100644 coverage/tools/Tools.cpp.func.html create mode 100644 coverage/tools/Tools.cpp.gcov.html create mode 100644 coverage/tools/Tools.h.func-sort-c.html create mode 100644 coverage/tools/Tools.h.func.html create mode 100644 coverage/tools/Tools.h.gcov.html create mode 100644 coverage/tools/Torsion.cpp.func-sort-c.html create mode 100644 coverage/tools/Torsion.cpp.func.html create mode 100644 coverage/tools/Torsion.cpp.gcov.html create mode 100644 coverage/tools/Tree.cpp.func-sort-c.html create mode 100644 coverage/tools/Tree.cpp.func.html create mode 100644 coverage/tools/Tree.cpp.gcov.html create mode 100644 coverage/tools/Tree.h.func-sort-c.html create mode 100644 coverage/tools/Tree.h.func.html create mode 100644 coverage/tools/Tree.h.gcov.html create mode 100644 coverage/tools/TypesafePtr.cpp.func-sort-c.html create mode 100644 coverage/tools/TypesafePtr.cpp.func.html create mode 100644 coverage/tools/TypesafePtr.cpp.gcov.html create mode 100644 coverage/tools/TypesafePtr.h.func-sort-c.html create mode 100644 coverage/tools/TypesafePtr.h.func.html create mode 100644 coverage/tools/TypesafePtr.h.gcov.html create mode 100644 coverage/tools/Units.cpp.func-sort-c.html create mode 100644 coverage/tools/Units.cpp.func.html create mode 100644 coverage/tools/Units.cpp.gcov.html create mode 100644 coverage/tools/Units.h.func-sort-c.html create mode 100644 coverage/tools/Units.h.func.html create mode 100644 coverage/tools/Units.h.gcov.html create mode 100644 coverage/tools/Vector.h.func-sort-c.html create mode 100644 coverage/tools/Vector.h.func.html create mode 100644 coverage/tools/Vector.h.gcov.html create mode 100644 coverage/tools/h36.cpp.func-sort-c.html create mode 100644 coverage/tools/h36.cpp.func.html create mode 100644 coverage/tools/h36.cpp.gcov.html create mode 100644 coverage/tools/index-sort-f.html create mode 100644 coverage/tools/index-sort-l.html create mode 100644 coverage/tools/index.html create mode 100644 coverage/updown.png create mode 100644 coverage/vatom/Center.cpp.func-sort-c.html create mode 100644 coverage/vatom/Center.cpp.func.html create mode 100644 coverage/vatom/Center.cpp.gcov.html create mode 100644 coverage/vatom/FixedAtom.cpp.func-sort-c.html create mode 100644 coverage/vatom/FixedAtom.cpp.func.html create mode 100644 coverage/vatom/FixedAtom.cpp.gcov.html create mode 100644 coverage/vatom/Ghost.cpp.func-sort-c.html create mode 100644 coverage/vatom/Ghost.cpp.func.html create mode 100644 coverage/vatom/Ghost.cpp.gcov.html create mode 100644 coverage/vatom/index-sort-f.html create mode 100644 coverage/vatom/index-sort-l.html create mode 100644 coverage/vatom/index.html create mode 100644 coverage/ves/BF_Chebyshev.cpp.func-sort-c.html create mode 100644 coverage/ves/BF_Chebyshev.cpp.func.html create mode 100644 coverage/ves/BF_Chebyshev.cpp.gcov.html create mode 100644 coverage/ves/BF_Combined.cpp.func-sort-c.html create mode 100644 coverage/ves/BF_Combined.cpp.func.html create mode 100644 coverage/ves/BF_Combined.cpp.gcov.html create mode 100644 coverage/ves/BF_Cosine.cpp.func-sort-c.html create mode 100644 coverage/ves/BF_Cosine.cpp.func.html create mode 100644 coverage/ves/BF_Cosine.cpp.gcov.html create mode 100644 coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html create mode 100644 coverage/ves/BF_CubicBsplines.cpp.func.html create mode 100644 coverage/ves/BF_CubicBsplines.cpp.gcov.html create mode 100644 coverage/ves/BF_Custom.cpp.func-sort-c.html create mode 100644 coverage/ves/BF_Custom.cpp.func.html create mode 100644 coverage/ves/BF_Custom.cpp.gcov.html create mode 100644 coverage/ves/BF_Fourier.cpp.func-sort-c.html create mode 100644 coverage/ves/BF_Fourier.cpp.func.html create mode 100644 coverage/ves/BF_Fourier.cpp.gcov.html create mode 100644 coverage/ves/BF_Gaussians.cpp.func-sort-c.html create mode 100644 coverage/ves/BF_Gaussians.cpp.func.html create mode 100644 coverage/ves/BF_Gaussians.cpp.gcov.html create mode 100644 coverage/ves/BF_Legendre.cpp.func-sort-c.html create mode 100644 coverage/ves/BF_Legendre.cpp.func.html create mode 100644 coverage/ves/BF_Legendre.cpp.gcov.html create mode 100644 coverage/ves/BF_Powers.cpp.func-sort-c.html create mode 100644 coverage/ves/BF_Powers.cpp.func.html create mode 100644 coverage/ves/BF_Powers.cpp.gcov.html create mode 100644 coverage/ves/BF_Sine.cpp.func-sort-c.html create mode 100644 coverage/ves/BF_Sine.cpp.func.html create mode 100644 coverage/ves/BF_Sine.cpp.gcov.html create mode 100644 coverage/ves/BF_Wavelets.cpp.func-sort-c.html create mode 100644 coverage/ves/BF_Wavelets.cpp.func.html create mode 100644 coverage/ves/BF_Wavelets.cpp.gcov.html create mode 100644 coverage/ves/BasisFunctions.cpp.func-sort-c.html create mode 100644 coverage/ves/BasisFunctions.cpp.func.html create mode 100644 coverage/ves/BasisFunctions.cpp.gcov.html create mode 100644 coverage/ves/BasisFunctions.h.func-sort-c.html create mode 100644 coverage/ves/BasisFunctions.h.func.html create mode 100644 coverage/ves/BasisFunctions.h.gcov.html create mode 100644 coverage/ves/CoeffsBase.cpp.func-sort-c.html create mode 100644 coverage/ves/CoeffsBase.cpp.func.html create mode 100644 coverage/ves/CoeffsBase.cpp.gcov.html create mode 100644 coverage/ves/CoeffsBase.h.func-sort-c.html create mode 100644 coverage/ves/CoeffsBase.h.func.html create mode 100644 coverage/ves/CoeffsBase.h.gcov.html create mode 100644 coverage/ves/CoeffsMatrix.cpp.func-sort-c.html create mode 100644 coverage/ves/CoeffsMatrix.cpp.func.html create mode 100644 coverage/ves/CoeffsMatrix.cpp.gcov.html create mode 100644 coverage/ves/CoeffsMatrix.h.func-sort-c.html create mode 100644 coverage/ves/CoeffsMatrix.h.func.html create mode 100644 coverage/ves/CoeffsMatrix.h.gcov.html create mode 100644 coverage/ves/CoeffsVector.cpp.func-sort-c.html create mode 100644 coverage/ves/CoeffsVector.cpp.func.html create mode 100644 coverage/ves/CoeffsVector.cpp.gcov.html create mode 100644 coverage/ves/CoeffsVector.h.func-sort-c.html create mode 100644 coverage/ves/CoeffsVector.h.func.html create mode 100644 coverage/ves/CoeffsVector.h.gcov.html create mode 100644 coverage/ves/FermiSwitchingFunction.cpp.func-sort-c.html create mode 100644 coverage/ves/FermiSwitchingFunction.cpp.func.html create mode 100644 coverage/ves/FermiSwitchingFunction.cpp.gcov.html create mode 100644 coverage/ves/GridIntegrationWeights.cpp.func-sort-c.html create mode 100644 coverage/ves/GridIntegrationWeights.cpp.func.html create mode 100644 coverage/ves/GridIntegrationWeights.cpp.gcov.html create mode 100644 coverage/ves/GridLinearInterpolation.cpp.func-sort-c.html create mode 100644 coverage/ves/GridLinearInterpolation.cpp.func.html create mode 100644 coverage/ves/GridLinearInterpolation.cpp.gcov.html create mode 100644 coverage/ves/GridLinearInterpolation.h.func-sort-c.html create mode 100644 coverage/ves/GridLinearInterpolation.h.func.html create mode 100644 coverage/ves/GridLinearInterpolation.h.gcov.html create mode 100644 coverage/ves/GridProjWeights.h.func-sort-c.html create mode 100644 coverage/ves/GridProjWeights.h.func.html create mode 100644 coverage/ves/GridProjWeights.h.gcov.html create mode 100644 coverage/ves/LinearBasisSetExpansion.cpp.func-sort-c.html create mode 100644 coverage/ves/LinearBasisSetExpansion.cpp.func.html create mode 100644 coverage/ves/LinearBasisSetExpansion.cpp.gcov.html create mode 100644 coverage/ves/LinearBasisSetExpansion.h.func-sort-c.html create mode 100644 coverage/ves/LinearBasisSetExpansion.h.func.html create mode 100644 coverage/ves/LinearBasisSetExpansion.h.gcov.html create mode 100644 coverage/ves/MD_LinearExpansionPES.cpp.func-sort-c.html create mode 100644 coverage/ves/MD_LinearExpansionPES.cpp.func.html create mode 100644 coverage/ves/MD_LinearExpansionPES.cpp.gcov.html create mode 100644 coverage/ves/Opt_Adam.cpp.func-sort-c.html create mode 100644 coverage/ves/Opt_Adam.cpp.func.html create mode 100644 coverage/ves/Opt_Adam.cpp.gcov.html create mode 100644 coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html create mode 100644 coverage/ves/Opt_BachAveragedSGD.cpp.func.html create mode 100644 coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html create mode 100644 coverage/ves/Opt_Dummy.cpp.func-sort-c.html create mode 100644 coverage/ves/Opt_Dummy.cpp.func.html create mode 100644 coverage/ves/Opt_Dummy.cpp.gcov.html create mode 100644 coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html create mode 100644 coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html create mode 100644 coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html create mode 100644 coverage/ves/Optimizer.cpp.func-sort-c.html create mode 100644 coverage/ves/Optimizer.cpp.func.html create mode 100644 coverage/ves/Optimizer.cpp.gcov.html create mode 100644 coverage/ves/Optimizer.h.func-sort-c.html create mode 100644 coverage/ves/Optimizer.h.func.html create mode 100644 coverage/ves/Optimizer.h.gcov.html create mode 100644 coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html create mode 100644 coverage/ves/OutputBasisFunctions.cpp.func.html create mode 100644 coverage/ves/OutputBasisFunctions.cpp.gcov.html create mode 100644 coverage/ves/OutputFesBias.cpp.func-sort-c.html create mode 100644 coverage/ves/OutputFesBias.cpp.func.html create mode 100644 coverage/ves/OutputFesBias.cpp.gcov.html create mode 100644 coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html create mode 100644 coverage/ves/OutputTargetDistribution.cpp.func.html create mode 100644 coverage/ves/OutputTargetDistribution.cpp.gcov.html create mode 100644 coverage/ves/TD_Chi.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_Chi.cpp.func.html create mode 100644 coverage/ves/TD_Chi.cpp.gcov.html create mode 100644 coverage/ves/TD_ChiSquared.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_ChiSquared.cpp.func.html create mode 100644 coverage/ves/TD_ChiSquared.cpp.gcov.html create mode 100644 coverage/ves/TD_Custom.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_Custom.cpp.func.html create mode 100644 coverage/ves/TD_Custom.cpp.gcov.html create mode 100644 coverage/ves/TD_Exponential.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_Exponential.cpp.func.html create mode 100644 coverage/ves/TD_Exponential.cpp.gcov.html create mode 100644 coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html create mode 100644 coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html create mode 100644 coverage/ves/TD_Gaussian.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_Gaussian.cpp.func.html create mode 100644 coverage/ves/TD_Gaussian.cpp.gcov.html create mode 100644 coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html create mode 100644 coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html create mode 100644 coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_GeneralizedNormal.cpp.func.html create mode 100644 coverage/ves/TD_GeneralizedNormal.cpp.gcov.html create mode 100644 coverage/ves/TD_Grid.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_Grid.cpp.func.html create mode 100644 coverage/ves/TD_Grid.cpp.gcov.html create mode 100644 coverage/ves/TD_LinearCombination.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_LinearCombination.cpp.func.html create mode 100644 coverage/ves/TD_LinearCombination.cpp.gcov.html create mode 100644 coverage/ves/TD_Multicanonical.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_Multicanonical.cpp.func.html create mode 100644 coverage/ves/TD_Multicanonical.cpp.gcov.html create mode 100644 coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_MultithermalMultibaric.cpp.func.html create mode 100644 coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html create mode 100644 coverage/ves/TD_ProductCombination.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_ProductCombination.cpp.func.html create mode 100644 coverage/ves/TD_ProductCombination.cpp.gcov.html create mode 100644 coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_ProductDistribution.cpp.func.html create mode 100644 coverage/ves/TD_ProductDistribution.cpp.gcov.html create mode 100644 coverage/ves/TD_Uniform.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_Uniform.cpp.func.html create mode 100644 coverage/ves/TD_Uniform.cpp.gcov.html create mode 100644 coverage/ves/TD_VonMises.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_VonMises.cpp.func.html create mode 100644 coverage/ves/TD_VonMises.cpp.gcov.html create mode 100644 coverage/ves/TD_WellTempered.cpp.func-sort-c.html create mode 100644 coverage/ves/TD_WellTempered.cpp.func.html create mode 100644 coverage/ves/TD_WellTempered.cpp.gcov.html create mode 100644 coverage/ves/TargetDistModifer.h.func-sort-c.html create mode 100644 coverage/ves/TargetDistModifer.h.func.html create mode 100644 coverage/ves/TargetDistModifer.h.gcov.html create mode 100644 coverage/ves/TargetDistribution.cpp.func-sort-c.html create mode 100644 coverage/ves/TargetDistribution.cpp.func.html create mode 100644 coverage/ves/TargetDistribution.cpp.gcov.html create mode 100644 coverage/ves/TargetDistribution.h.func-sort-c.html create mode 100644 coverage/ves/TargetDistribution.h.func.html create mode 100644 coverage/ves/TargetDistribution.h.gcov.html create mode 100644 coverage/ves/VesBias.cpp.func-sort-c.html create mode 100644 coverage/ves/VesBias.cpp.func.html create mode 100644 coverage/ves/VesBias.cpp.gcov.html create mode 100644 coverage/ves/VesBias.h.func-sort-c.html create mode 100644 coverage/ves/VesBias.h.func.html create mode 100644 coverage/ves/VesBias.h.gcov.html create mode 100644 coverage/ves/VesDeltaF.cpp.func-sort-c.html create mode 100644 coverage/ves/VesDeltaF.cpp.func.html create mode 100644 coverage/ves/VesDeltaF.cpp.gcov.html create mode 100644 coverage/ves/VesLinearExpansion.cpp.func-sort-c.html create mode 100644 coverage/ves/VesLinearExpansion.cpp.func.html create mode 100644 coverage/ves/VesLinearExpansion.cpp.gcov.html create mode 100644 coverage/ves/VesTools.cpp.func-sort-c.html create mode 100644 coverage/ves/VesTools.cpp.func.html create mode 100644 coverage/ves/VesTools.cpp.gcov.html create mode 100644 coverage/ves/VesTools.h.func-sort-c.html create mode 100644 coverage/ves/VesTools.h.func.html create mode 100644 coverage/ves/VesTools.h.gcov.html create mode 100644 coverage/ves/WaveletCoeffs.cpp.func-sort-c.html create mode 100644 coverage/ves/WaveletCoeffs.cpp.func.html create mode 100644 coverage/ves/WaveletCoeffs.cpp.gcov.html create mode 100644 coverage/ves/WaveletGrid.cpp.func-sort-c.html create mode 100644 coverage/ves/WaveletGrid.cpp.func.html create mode 100644 coverage/ves/WaveletGrid.cpp.gcov.html create mode 100644 coverage/ves/index-sort-f.html create mode 100644 coverage/ves/index-sort-l.html create mode 100644 coverage/ves/index.html create mode 100644 coverage/vesselbase/ActionWithAveraging.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/ActionWithAveraging.cpp.func.html create mode 100644 coverage/vesselbase/ActionWithAveraging.cpp.gcov.html create mode 100644 coverage/vesselbase/ActionWithAveraging.h.func-sort-c.html create mode 100644 coverage/vesselbase/ActionWithAveraging.h.func.html create mode 100644 coverage/vesselbase/ActionWithAveraging.h.gcov.html create mode 100644 coverage/vesselbase/ActionWithInputVessel.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/ActionWithInputVessel.cpp.func.html create mode 100644 coverage/vesselbase/ActionWithInputVessel.cpp.gcov.html create mode 100644 coverage/vesselbase/ActionWithInputVessel.h.func-sort-c.html create mode 100644 coverage/vesselbase/ActionWithInputVessel.h.func.html create mode 100644 coverage/vesselbase/ActionWithInputVessel.h.gcov.html create mode 100644 coverage/vesselbase/ActionWithVessel.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/ActionWithVessel.cpp.func.html create mode 100644 coverage/vesselbase/ActionWithVessel.cpp.gcov.html create mode 100644 coverage/vesselbase/ActionWithVessel.h.func-sort-c.html create mode 100644 coverage/vesselbase/ActionWithVessel.h.func.html create mode 100644 coverage/vesselbase/ActionWithVessel.h.gcov.html create mode 100644 coverage/vesselbase/AltMin.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/AltMin.cpp.func.html create mode 100644 coverage/vesselbase/AltMin.cpp.gcov.html create mode 100644 coverage/vesselbase/AveragingVessel.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/AveragingVessel.cpp.func.html create mode 100644 coverage/vesselbase/AveragingVessel.cpp.gcov.html create mode 100644 coverage/vesselbase/AveragingVessel.h.func-sort-c.html create mode 100644 coverage/vesselbase/AveragingVessel.h.func.html create mode 100644 coverage/vesselbase/AveragingVessel.h.gcov.html create mode 100644 coverage/vesselbase/Between.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/Between.cpp.func.html create mode 100644 coverage/vesselbase/Between.cpp.gcov.html create mode 100644 coverage/vesselbase/BridgeVessel.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/BridgeVessel.cpp.func.html create mode 100644 coverage/vesselbase/BridgeVessel.cpp.gcov.html create mode 100644 coverage/vesselbase/BridgeVessel.h.func-sort-c.html create mode 100644 coverage/vesselbase/BridgeVessel.h.func.html create mode 100644 coverage/vesselbase/BridgeVessel.h.gcov.html create mode 100644 coverage/vesselbase/FunctionVessel.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/FunctionVessel.cpp.func.html create mode 100644 coverage/vesselbase/FunctionVessel.cpp.gcov.html create mode 100644 coverage/vesselbase/FunctionVessel.h.func-sort-c.html create mode 100644 coverage/vesselbase/FunctionVessel.h.func.html create mode 100644 coverage/vesselbase/FunctionVessel.h.gcov.html create mode 100644 coverage/vesselbase/Highest.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/Highest.cpp.func.html create mode 100644 coverage/vesselbase/Highest.cpp.gcov.html create mode 100644 coverage/vesselbase/Histogram.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/Histogram.cpp.func.html create mode 100644 coverage/vesselbase/Histogram.cpp.gcov.html create mode 100644 coverage/vesselbase/LessThan.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/LessThan.cpp.func.html create mode 100644 coverage/vesselbase/LessThan.cpp.gcov.html create mode 100644 coverage/vesselbase/Lowest.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/Lowest.cpp.func.html create mode 100644 coverage/vesselbase/Lowest.cpp.gcov.html create mode 100644 coverage/vesselbase/Max.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/Max.cpp.func.html create mode 100644 coverage/vesselbase/Max.cpp.gcov.html create mode 100644 coverage/vesselbase/Mean.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/Mean.cpp.func.html create mode 100644 coverage/vesselbase/Mean.cpp.gcov.html create mode 100644 coverage/vesselbase/Min.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/Min.cpp.func.html create mode 100644 coverage/vesselbase/Min.cpp.gcov.html create mode 100644 coverage/vesselbase/Moments.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/Moments.cpp.func.html create mode 100644 coverage/vesselbase/Moments.cpp.gcov.html create mode 100644 coverage/vesselbase/MoreThan.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/MoreThan.cpp.func.html create mode 100644 coverage/vesselbase/MoreThan.cpp.gcov.html create mode 100644 coverage/vesselbase/OrderingVessel.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/OrderingVessel.cpp.func.html create mode 100644 coverage/vesselbase/OrderingVessel.cpp.gcov.html create mode 100644 coverage/vesselbase/OrderingVessel.h.func-sort-c.html create mode 100644 coverage/vesselbase/OrderingVessel.h.func.html create mode 100644 coverage/vesselbase/OrderingVessel.h.gcov.html create mode 100644 coverage/vesselbase/ShortcutVessel.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/ShortcutVessel.cpp.func.html create mode 100644 coverage/vesselbase/ShortcutVessel.cpp.gcov.html create mode 100644 coverage/vesselbase/ShortcutVessel.h.func-sort-c.html create mode 100644 coverage/vesselbase/ShortcutVessel.h.func.html create mode 100644 coverage/vesselbase/ShortcutVessel.h.gcov.html create mode 100644 coverage/vesselbase/StoreDataVessel.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/StoreDataVessel.cpp.func.html create mode 100644 coverage/vesselbase/StoreDataVessel.cpp.gcov.html create mode 100644 coverage/vesselbase/StoreDataVessel.h.func-sort-c.html create mode 100644 coverage/vesselbase/StoreDataVessel.h.func.html create mode 100644 coverage/vesselbase/StoreDataVessel.h.gcov.html create mode 100644 coverage/vesselbase/Sum.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/Sum.cpp.func.html create mode 100644 coverage/vesselbase/Sum.cpp.gcov.html create mode 100644 coverage/vesselbase/ValueVessel.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/ValueVessel.cpp.func.html create mode 100644 coverage/vesselbase/ValueVessel.cpp.gcov.html create mode 100644 coverage/vesselbase/ValueVessel.h.func-sort-c.html create mode 100644 coverage/vesselbase/ValueVessel.h.func.html create mode 100644 coverage/vesselbase/ValueVessel.h.gcov.html create mode 100644 coverage/vesselbase/Vessel.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/Vessel.cpp.func.html create mode 100644 coverage/vesselbase/Vessel.cpp.gcov.html create mode 100644 coverage/vesselbase/Vessel.h.func-sort-c.html create mode 100644 coverage/vesselbase/Vessel.h.func.html create mode 100644 coverage/vesselbase/Vessel.h.gcov.html create mode 100644 coverage/vesselbase/VesselRegister.cpp.func-sort-c.html create mode 100644 coverage/vesselbase/VesselRegister.cpp.func.html create mode 100644 coverage/vesselbase/VesselRegister.cpp.gcov.html create mode 100644 coverage/vesselbase/index-sort-f.html create mode 100644 coverage/vesselbase/index-sort-l.html create mode 100644 coverage/vesselbase/index.html create mode 100644 coverage/wrapper/Plumed.h.func-sort-c.html create mode 100644 coverage/wrapper/Plumed.h.func.html create mode 100644 coverage/wrapper/Plumed.h.gcov.html create mode 100644 coverage/wrapper/index-sort-f.html create mode 100644 coverage/wrapper/index-sort-l.html create mode 100644 coverage/wrapper/index.html create mode 100644 index.html diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/README.md b/README.md new file mode 100644 index 000000000000..85c51c62824c --- /dev/null +++ b/README.md @@ -0,0 +1,12 @@ +Coverage scan for PLUMED master +----------------------------- + +This repository hosts the coverage scan for [PLUMED](http://www.plumed.org) master, +git revision [9cb8ceb](https://github.com/plumed/plumed2/commit/9cb8ceb). + +Coverage scan done on [GiHub actions](http://github.com/plumed/plumed2/actions) on Thu Feb 22 21:58:47 UTC 2024. + +To browse the scan you should go [here](http://plumed.github.io/coverage-master). + +You can also download a full copy of the scan for offline access +at [this link](http://github.com/plumed/coverage-master/archive/gh-pages.zip). diff --git a/coverage-libs/amber.png b/coverage-libs/amber.png new file mode 100644 index 0000000000000000000000000000000000000000..2cab170d8359081983a4e343848dfe06bc490f12 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^G2tW}LqE04T&+ z;1OBOz`!j8!i<;h*8KqrvZOouIx;Y9?C1WI$O`1M1^9%x{(levWG + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:254062.5 %
Date:2024-02-22 21:58:47Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit8ArchInfo4initEjj70
_ZN4PLMD6asmjit9ArchUtils15typeIdToRegInfoEjRjRNS0_7RegInfoE23788
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.cpp.func.html b/coverage-libs/asmjit/arch.cpp.func.html new file mode 100644 index 000000000000..2d09c3a6b3bf --- /dev/null +++ b/coverage-libs/asmjit/arch.cpp.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:254062.5 %
Date:2024-02-22 21:58:47Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit8ArchInfo4initEjj70
_ZN4PLMD6asmjit9ArchUtils15typeIdToRegInfoEjRjRNS0_7RegInfoE23788
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.cpp.gcov.html b/coverage-libs/asmjit/arch.cpp.gcov.html new file mode 100644 index 000000000000..9475ed73ae44 --- /dev/null +++ b/coverage-libs/asmjit/arch.cpp.gcov.html @@ -0,0 +1,264 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:254062.5 %
Date:2024-02-22 21:58:47Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./arch.h"
+      34             : 
+      35             : #if defined(ASMJIT_BUILD_X86)
+      36             : #include "./x86operand.h"
+      37             : #endif // ASMJIT_BUILD_X86
+      38             : 
+      39             : // [Api-Begin]
+      40             : #include "./asmjit_apibegin.h"
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace asmjit {
+      44             : 
+      45             : // ============================================================================
+      46             : // [asmjit::ArchInfo]
+      47             : // ============================================================================
+      48             : 
+      49             : static const uint32_t archInfoTable[] = {
+      50             :   // <-------------+---------------------+-----------------------+-------+
+      51             :   //               | Type                | SubType               | GPInfo|
+      52             :   // <-------------+---------------------+-----------------------+-------+
+      53             :   ASMJIT_PACK32_4x8(ArchInfo::kTypeNone  , ArchInfo::kSubTypeNone, 0,  0),
+      54             :   ASMJIT_PACK32_4x8(ArchInfo::kTypeX86   , ArchInfo::kSubTypeNone, 4,  8),
+      55             :   ASMJIT_PACK32_4x8(ArchInfo::kTypeX64   , ArchInfo::kSubTypeNone, 8, 16),
+      56             :   ASMJIT_PACK32_4x8(ArchInfo::kTypeX32   , ArchInfo::kSubTypeNone, 8, 16),
+      57             :   ASMJIT_PACK32_4x8(ArchInfo::kTypeA32   , ArchInfo::kSubTypeNone, 4, 16),
+      58             :   ASMJIT_PACK32_4x8(ArchInfo::kTypeA64   , ArchInfo::kSubTypeNone, 8, 32)
+      59             : };
+      60             : 
+      61          70 : ASMJIT_FAVOR_SIZE void ArchInfo::init(uint32_t type, uint32_t subType) noexcept {
+      62          70 :   uint32_t index = type < ASMJIT_ARRAY_SIZE(archInfoTable) ? type : uint32_t(0);
+      63             : 
+      64             :   // Make sure the `archInfoTable` array is correctly indexed.
+      65          70 :   _signature = archInfoTable[index];
+      66             :   ASMJIT_ASSERT(_type == index);
+      67             : 
+      68             :   // Even if the architecture is not known we setup its type and sub-type,
+      69             :   // however, such architecture is not really useful.
+      70          70 :   _type = type;
+      71          70 :   _subType = subType;
+      72          70 : }
+      73             : 
+      74             : // ============================================================================
+      75             : // [asmjit::ArchUtils]
+      76             : // ============================================================================
+      77             : 
+      78       23788 : ASMJIT_FAVOR_SIZE Error ArchUtils::typeIdToRegInfo(uint32_t archType, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept {
+      79       23788 :   uint32_t typeId = typeIdInOut;
+      80             : 
+      81             :   // Zero the signature so it's clear in case that typeId is not invalid.
+      82       23788 :   regInfo._signature = 0;
+      83             : 
+      84             : #if defined(ASMJIT_BUILD_X86)
+      85       23788 :   if (ArchInfo::isX86Family(archType)) {
+      86             :     // Passed RegType instead of TypeId?
+      87       23788 :     if (typeId <= Reg::kRegMax)
+      88           0 :       typeId = x86OpData.archRegs.regTypeToTypeId[typeId];
+      89             : 
+      90       23788 :     if (ASMJIT_UNLIKELY(!TypeId::isValid(typeId)))
+      91             :       return DebugUtils::errored(kErrorInvalidTypeId);
+      92             : 
+      93             :     // First normalize architecture dependent types.
+      94       23788 :     if (TypeId::isAbstract(typeId)) {
+      95        7268 :       if (typeId == TypeId::kIntPtr)
+      96        7268 :         typeId = (archType == ArchInfo::kTypeX86) ? TypeId::kI32 : TypeId::kI64;
+      97             :       else
+      98           0 :         typeId = (archType == ArchInfo::kTypeX86) ? TypeId::kU32 : TypeId::kU64;
+      99             :     }
+     100             : 
+     101             :     // Type size helps to construct all kinds of registers. If the size is zero
+     102             :     // then the TypeId is invalid.
+     103             :     uint32_t size = TypeId::sizeOf(typeId);
+     104       23788 :     if (ASMJIT_UNLIKELY(!size))
+     105             :       return DebugUtils::errored(kErrorInvalidTypeId);
+     106             : 
+     107       23788 :     if (ASMJIT_UNLIKELY(typeId == TypeId::kF80))
+     108             :       return DebugUtils::errored(kErrorInvalidUseOfF80);
+     109             : 
+     110             :     uint32_t regType = 0;
+     111             : 
+     112       23788 :     switch (typeId) {
+     113             :       case TypeId::kI8:
+     114             :       case TypeId::kU8:
+     115             :         regType = X86Reg::kRegGpbLo;
+     116             :         break;
+     117             : 
+     118           0 :       case TypeId::kI16:
+     119             :       case TypeId::kU16:
+     120             :         regType = X86Reg::kRegGpw;
+     121           0 :         break;
+     122             : 
+     123           0 :       case TypeId::kI32:
+     124             :       case TypeId::kU32:
+     125             :         regType = X86Reg::kRegGpd;
+     126           0 :         break;
+     127             : 
+     128        7268 :       case TypeId::kI64:
+     129             :       case TypeId::kU64:
+     130        7268 :         if (archType == ArchInfo::kTypeX86)
+     131             :           return DebugUtils::errored(kErrorInvalidUseOfGpq);
+     132             : 
+     133             :         regType = X86Reg::kRegGpq;
+     134             :         break;
+     135             : 
+     136             :       // F32 and F64 are always promoted to use vector registers.
+     137           0 :       case TypeId::kF32:
+     138             :         typeId = TypeId::kF32x1;
+     139             :         regType = X86Reg::kRegXmm;
+     140           0 :         break;
+     141             : 
+     142           0 :       case TypeId::kF64:
+     143             :         typeId = TypeId::kF64x1;
+     144             :         regType = X86Reg::kRegXmm;
+     145           0 :         break;
+     146             : 
+     147             :       // Mask registers {k}.
+     148           0 :       case TypeId::kMask8:
+     149             :       case TypeId::kMask16:
+     150             :       case TypeId::kMask32:
+     151             :       case TypeId::kMask64:
+     152             :         regType = X86Reg::kRegK;
+     153           0 :         break;
+     154             : 
+     155             :       // MMX registers.
+     156           0 :       case TypeId::kMmx32:
+     157             :       case TypeId::kMmx64:
+     158             :         regType = X86Reg::kRegMm;
+     159           0 :         break;
+     160             : 
+     161             :       // XMM|YMM|ZMM registers.
+     162       16520 :       default:
+     163       16520 :         if (size <= 16)
+     164             :           regType = X86Reg::kRegXmm;
+     165           0 :         else if (size == 32)
+     166             :           regType = X86Reg::kRegYmm;
+     167             :         else
+     168             :           regType = X86Reg::kRegZmm;
+     169             :         break;
+     170             :     }
+     171             : 
+     172       23788 :     typeIdInOut = typeId;
+     173       23788 :     regInfo._signature = x86OpData.archRegs.regInfo[regType].getSignature();
+     174       23788 :     return kErrorOk;
+     175             :   }
+     176             : #endif // ASMJIT_BUILD_X86
+     177             : 
+     178             :   return DebugUtils::errored(kErrorInvalidArch);
+     179             : }
+     180             : 
+     181             : } // asmjit namespace
+     182             : } // namespace PLMD
+     183             : 
+     184             : // [Api-End]
+     185             : #include "./asmjit_apiend.h"
+     186             : #pragma GCC diagnostic pop
+     187             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.h.func-sort-c.html b/coverage-libs/asmjit/arch.h.func-sort-c.html new file mode 100644 index 000000000000..e2264f4c9031 --- /dev/null +++ b/coverage-libs/asmjit/arch.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6875.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.h.func.html b/coverage-libs/asmjit/arch.h.func.html new file mode 100644 index 000000000000..76c358376ca5 --- /dev/null +++ b/coverage-libs/asmjit/arch.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6875.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/arch.h.gcov.html b/coverage-libs/asmjit/arch.h.gcov.html new file mode 100644 index 000000000000..d05c8be156f8 --- /dev/null +++ b/coverage-libs/asmjit/arch.h.gcov.html @@ -0,0 +1,305 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/arch.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - arch.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6875.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_arch_h
+      21             : #define __PLUMED_asmjit_arch_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_ARCH_H
+      33             : #define _ASMJIT_BASE_ARCH_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./globals.h"
+      37             : #include "./operand.h"
+      38             : 
+      39             : // [Api-Begin]
+      40             : #include "./asmjit_apibegin.h"
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace asmjit {
+      44             : 
+      45             : //! \addtogroup asmjit_base
+      46             : //! \{
+      47             : 
+      48             : // ============================================================================
+      49             : // [asmjit::ArchInfo]
+      50             : // ============================================================================
+      51             : 
+      52             : class ArchInfo {
+      53             : public:
+      54             :   //! Architecture type.
+      55             :   ASMJIT_ENUM(Type) {
+      56             :     kTypeNone  = 0,                      //!< No/Unknown architecture.
+      57             : 
+      58             :     // X86 architectures.
+      59             :     kTypeX86   = 1,                      //!< X86 architecture (32-bit).
+      60             :     kTypeX64   = 2,                      //!< X64 architecture (64-bit) (AMD64).
+      61             :     kTypeX32   = 3,                      //!< X32 architecture (DEAD-END).
+      62             : 
+      63             :     // ARM architectures.
+      64             :     kTypeA32   = 4,                      //!< ARM 32-bit architecture (AArch32/ARM/THUMB).
+      65             :     kTypeA64   = 5,                      //!< ARM 64-bit architecture (AArch64).
+      66             : 
+      67             :     //! Architecture detected at compile-time (architecture of the host).
+      68             :     kTypeHost  = ASMJIT_ARCH_X86   ? kTypeX86 :
+      69             :                  ASMJIT_ARCH_X64   ? kTypeX64 :
+      70             :                  ASMJIT_ARCH_ARM32 ? kTypeA32 :
+      71             :                  ASMJIT_ARCH_ARM64 ? kTypeA64 : kTypeNone
+      72             :   };
+      73             : 
+      74             :   //! Architecture sub-type or execution mode.
+      75             :   ASMJIT_ENUM(SubType) {
+      76             :     kSubTypeNone         = 0,            //!< Default mode (or no specific mode).
+      77             : 
+      78             :     // X86 sub-types.
+      79             :     kSubTypeX86_AVX      = 1,            //!< Code generation uses AVX         by default (VEC instructions).
+      80             :     kSubTypeX86_AVX2     = 2,            //!< Code generation uses AVX2        by default (VEC instructions).
+      81             :     kSubTypeX86_AVX512   = 3,            //!< Code generation uses AVX-512F    by default (+32 vector regs).
+      82             :     kSubTypeX86_AVX512VL = 4,            //!< Code generation uses AVX-512F-VL by default (+VL extensions).
+      83             : 
+      84             :     // ARM sub-types.
+      85             :     kSubTypeA32_Thumb    = 8,            //!< THUMB|THUMB2 sub-type (only ARM in 32-bit mode).
+      86             : 
+      87             : #if   (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64) && defined(__AVX512VL__)
+      88             :     kSubTypeHost = kSubTypeX86_AVX512VL
+      89             : #elif (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64) && defined(__AVX512F__)
+      90             :     kSubTypeHost = kSubTypeX86_AVX512
+      91             : #elif (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64) && defined(__AVX2__)
+      92             :     kSubTypeHost = kSubTypeX86_AVX2
+      93             : #elif (ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64) && defined(__AVX__)
+      94             :     kSubTypeHost = kSubTypeX86_AVX
+      95             : #elif (ASMJIT_ARCH_ARM32) && (defined(_M_ARMT) || defined(__thumb__) || defined(__thumb2__))
+      96             :     kSubTypeHost = kSubTypeA32_Thumb
+      97             : #else
+      98             :     kSubTypeHost = 0
+      99             : #endif
+     100             :   };
+     101             : 
+     102             :   // --------------------------------------------------------------------------
+     103             :   // [Utilities]
+     104             :   // --------------------------------------------------------------------------
+     105             : 
+     106       31580 :   static ASMJIT_INLINE bool isX86Family(uint32_t archType) noexcept { return archType >= kTypeX86 && archType <= kTypeX32; }
+     107             :   static ASMJIT_INLINE bool isArmFamily(uint32_t archType) noexcept { return archType >= kTypeA32 && archType <= kTypeA64; }
+     108             : 
+     109             :   // --------------------------------------------------------------------------
+     110             :   // [Construction / Destruction]
+     111             :   // --------------------------------------------------------------------------
+     112             : 
+     113        7890 :   ASMJIT_INLINE ArchInfo() noexcept : _signature(0) {}
+     114             :   ASMJIT_INLINE ArchInfo(const ArchInfo& other) noexcept = default;
+     115             :   explicit ASMJIT_INLINE ArchInfo(uint32_t type, uint32_t subType = kSubTypeNone) noexcept { init(type, subType); }
+     116             : 
+     117             :   ASMJIT_INLINE static ArchInfo host() noexcept { return ArchInfo(kTypeHost, kSubTypeHost); }
+     118             : 
+     119             :   // --------------------------------------------------------------------------
+     120             :   // [Init / Reset]
+     121             :   // --------------------------------------------------------------------------
+     122             : 
+     123             :   ASMJIT_INLINE bool isInitialized() const noexcept { return _type != kTypeNone; }
+     124             : 
+     125             :   ASMJIT_API void init(uint32_t type, uint32_t subType = kSubTypeNone) noexcept;
+     126        1948 :   ASMJIT_INLINE void reset() noexcept { _signature = 0; }
+     127             : 
+     128             :   // --------------------------------------------------------------------------
+     129             :   // [Accessors]
+     130             :   // --------------------------------------------------------------------------
+     131             : 
+     132             :   //! Get if the architecture is 32-bit.
+     133           0 :   ASMJIT_INLINE bool is32Bit() const noexcept { return _gpSize == 4; }
+     134             :   //! Get if the architecture is 64-bit.
+     135           0 :   ASMJIT_INLINE bool is64Bit() const noexcept { return _gpSize == 8; }
+     136             : 
+     137             :   //! Get architecture type, see \ref Type.
+     138       31580 :   ASMJIT_INLINE uint32_t getType() const noexcept { return _type; }
+     139             : 
+     140             :   //! Get architecture sub-type, see \ref SubType.
+     141             :   //!
+     142             :   //! X86 & X64
+     143             :   //! ---------
+     144             :   //!
+     145             :   //! Architecture subtype describe the highest instruction-set level that can
+     146             :   //! be used.
+     147             :   //!
+     148             :   //! ARM32
+     149             :   //! -----
+     150             :   //!
+     151             :   //! Architecture mode means the instruction encoding to be used when generating
+     152             :   //! machine code, thus mode can be used to force generation of THUMB and THUMB2
+     153             :   //! encoding or regular ARM encoding.
+     154             :   //!
+     155             :   //! ARM64
+     156             :   //! -----
+     157             :   //!
+     158             :   //! No meaning yet.
+     159             :   ASMJIT_INLINE uint32_t getSubType() const noexcept { return _subType; }
+     160             : 
+     161             :   //! Get if the architecture is X86, X64, or X32.
+     162        3896 :   ASMJIT_INLINE bool isX86Family() const noexcept { return isX86Family(_type); }
+     163             :   //! Get if the architecture is ARM32 or ARM64.
+     164             :   ASMJIT_INLINE bool isArmFamily() const noexcept { return isArmFamily(_type); }
+     165             : 
+     166             :   //! Get a size of a general-purpose register.
+     167        1948 :   ASMJIT_INLINE uint32_t getGpSize() const noexcept { return _gpSize; }
+     168             :   //! Get number of general-purpose registers.
+     169             :   ASMJIT_INLINE uint32_t getGpCount() const noexcept { return _gpCount; }
+     170             : 
+     171             :   // --------------------------------------------------------------------------
+     172             :   // [Operator Overload]
+     173             :   // --------------------------------------------------------------------------
+     174             : 
+     175             :   ASMJIT_INLINE ArchInfo& operator=(const ArchInfo& other) noexcept = default;
+     176             :   ASMJIT_INLINE bool operator==(const ArchInfo& other) const noexcept { return _signature == other._signature; }
+     177             :   ASMJIT_INLINE bool operator!=(const ArchInfo& other) const noexcept { return _signature != other._signature; }
+     178             : 
+     179             :   // --------------------------------------------------------------------------
+     180             :   // [Members]
+     181             :   // --------------------------------------------------------------------------
+     182             : 
+     183             :   union {
+     184             :     struct {
+     185             :       uint8_t _type;                     //!< Architecture type.
+     186             :       uint8_t _subType;                  //!< Architecture sub-type.
+     187             :       uint8_t _gpSize;                   //!< Default size of a general purpose register.
+     188             :       uint8_t _gpCount;                  //!< Count of all general purpose registers.
+     189             :     };
+     190             :     uint32_t _signature;                 //!< Architecture signature (32-bit int).
+     191             :   };
+     192             : };
+     193             : 
+     194             : // ============================================================================
+     195             : // [asmjit::ArchRegs]
+     196             : // ============================================================================
+     197             : 
+     198             : //! Information about all architecture registers.
+     199             : struct ArchRegs {
+     200             :   //! Register information and signatures indexed by \ref Reg::Type.
+     201             :   RegInfo regInfo[Reg::kRegMax + 1];
+     202             :   //! Count (maximum) of registers per \ref Reg::Type.
+     203             :   uint8_t regCount[Reg::kRegMax + 1];
+     204             :   //! Converts RegType to TypeId, see \ref TypeId::Id.
+     205             :   uint8_t regTypeToTypeId[Reg::kRegMax + 1];
+     206             : };
+     207             : 
+     208             : // ============================================================================
+     209             : // [asmjit::ArchUtils]
+     210             : // ============================================================================
+     211             : 
+     212             : struct ArchUtils {
+     213             :   ASMJIT_API static Error typeIdToRegInfo(uint32_t archType, uint32_t& typeIdInOut, RegInfo& regInfo) noexcept;
+     214             : };
+     215             : 
+     216             : //! \}
+     217             : 
+     218             : } // asmjit namespace
+     219             : } // namespace PLMD
+     220             : 
+     221             : // [Api-End]
+     222             : #include "./asmjit_apiend.h"
+     223             : 
+     224             : // [Guard]
+     225             : #endif // _ASMJIT_BASE_ARCH_H
+     226             : #pragma GCC diagnostic pop
+     227             : #endif // __PLUMED_HAS_ASMJIT
+     228             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.cpp.func-sort-c.html b/coverage-libs/asmjit/assembler.cpp.func-sort-c.html new file mode 100644 index 000000000000..1a205ab71bb6 --- /dev/null +++ b/coverage-libs/asmjit/assembler.cpp.func-sort-c.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4017423.0 %
Date:2024-02-22 21:58:47Functions:61833.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9Assembler10embedLabelERKNS0_5LabelE0
_ZN4PLMD6asmjit9Assembler11_emitFailedEjjjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit9Assembler13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit9Assembler14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit9Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit9Assembler5embedEPKvj0
_ZN4PLMD6asmjit9Assembler7commentEPKcm0
_ZN4PLMD6asmjit9Assembler8_emitLogEjjRKNS0_8Operand_ES4_S4_S4_jjPh0
_ZN4PLMD6asmjit9Assembler8newLabelEv0
_ZN4PLMD6asmjit9Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit9Assembler9setOffsetEm0
_ZN4PLMD6asmjit9AssemblerD0Ev0
_ZN4PLMD6asmjit9Assembler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit9AssemblerC2Ev1948
_ZN4PLMD6asmjit9AssemblerD2Ev1948
_ZN4PLMD6asmjit9Assembler4bindERKNS0_5LabelE3896
_ZN4PLMD6asmjit9Assembler4syncEv3896
_ZN4PLMD6asmjit9Assembler12_emitOpArrayEjPKNS0_8Operand_Em48362
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.cpp.func.html b/coverage-libs/asmjit/assembler.cpp.func.html new file mode 100644 index 000000000000..a6d76d66e077 --- /dev/null +++ b/coverage-libs/asmjit/assembler.cpp.func.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4017423.0 %
Date:2024-02-22 21:58:47Functions:61833.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9Assembler10embedLabelERKNS0_5LabelE0
_ZN4PLMD6asmjit9Assembler11_emitFailedEjjjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit9Assembler12_emitOpArrayEjPKNS0_8Operand_Em48362
_ZN4PLMD6asmjit9Assembler13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit9Assembler14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit9Assembler4bindERKNS0_5LabelE3896
_ZN4PLMD6asmjit9Assembler4syncEv3896
_ZN4PLMD6asmjit9Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit9Assembler5embedEPKvj0
_ZN4PLMD6asmjit9Assembler7commentEPKcm0
_ZN4PLMD6asmjit9Assembler8_emitLogEjjRKNS0_8Operand_ES4_S4_S4_jjPh0
_ZN4PLMD6asmjit9Assembler8newLabelEv0
_ZN4PLMD6asmjit9Assembler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit9Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit9Assembler9setOffsetEm0
_ZN4PLMD6asmjit9AssemblerC2Ev1948
_ZN4PLMD6asmjit9AssemblerD0Ev0
_ZN4PLMD6asmjit9AssemblerD2Ev1948
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.cpp.gcov.html b/coverage-libs/asmjit/assembler.cpp.gcov.html new file mode 100644 index 000000000000..82e6ca360f06 --- /dev/null +++ b/coverage-libs/asmjit/assembler.cpp.gcov.html @@ -0,0 +1,550 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4017423.0 %
Date:2024-02-22 21:58:47Functions:61833.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./assembler.h"
+      34             : #include "./constpool.h"
+      35             : #include "./utils.h"
+      36             : #include "./vmem.h"
+      37             : 
+      38             : // [Api-Begin]
+      39             : #include "./asmjit_apibegin.h"
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace asmjit {
+      43             : 
+      44             : // ============================================================================
+      45             : // [asmjit::Assembler - Construction / Destruction]
+      46             : // ============================================================================
+      47             : 
+      48        1948 : Assembler::Assembler() noexcept
+      49             :   : CodeEmitter(kTypeAssembler),
+      50        1948 :     _section(nullptr),
+      51        1948 :     _bufferData(nullptr),
+      52        1948 :     _bufferEnd(nullptr),
+      53        1948 :     _bufferPtr(nullptr),
+      54        1948 :     _op4(),
+      55        1948 :     _op5() {}
+      56             : 
+      57        1948 : Assembler::~Assembler() noexcept {
+      58        1948 :   if (_code) sync();
+      59        1948 : }
+      60             : 
+      61             : // ============================================================================
+      62             : // [asmjit::Assembler - Events]
+      63             : // ============================================================================
+      64             : 
+      65        1948 : Error Assembler::onAttach(CodeHolder* code) noexcept {
+      66             :   // Attach to the end of the .text section.
+      67        1948 :   _section = code->_sections[0];
+      68        1948 :   uint8_t* p = _section->_buffer._data;
+      69             : 
+      70        1948 :   _bufferData = p;
+      71        1948 :   _bufferEnd  = p + _section->_buffer._capacity;
+      72        1948 :   _bufferPtr  = p + _section->_buffer._length;
+      73             : 
+      74             :   _op4.reset();
+      75             :   _op5.reset();
+      76             : 
+      77        1948 :   return Base::onAttach(code);
+      78             : }
+      79             : 
+      80           0 : Error Assembler::onDetach(CodeHolder* code) noexcept {
+      81           0 :   _section    = nullptr;
+      82           0 :   _bufferData = nullptr;
+      83           0 :   _bufferEnd  = nullptr;
+      84           0 :   _bufferPtr  = nullptr;
+      85             : 
+      86             :   _op4.reset();
+      87             :   _op5.reset();
+      88             : 
+      89           0 :   return Base::onDetach(code);
+      90             : }
+      91             : 
+      92             : // ============================================================================
+      93             : // [asmjit::Assembler - Code-Generation]
+      94             : // ============================================================================
+      95             : 
+      96           0 : Error Assembler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) {
+      97           0 :   _op4 = o4;
+      98           0 :   _op5 = o5;
+      99           0 :   _options |= kOptionOp4Op5Used;
+     100           0 :   return _emit(instId, o0, o1, o2, o3);
+     101             : }
+     102             : 
+     103       48362 : Error Assembler::_emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount) {
+     104             :   const Operand_* op = opArray;
+     105       48362 :   switch (opCount) {
+     106        1948 :     case 0: return _emit(instId, _none, _none, _none, _none);
+     107        3888 :     case 1: return _emit(instId, op[0], _none, _none, _none);
+     108       42406 :     case 2: return _emit(instId, op[0], op[1], _none, _none);
+     109         120 :     case 3: return _emit(instId, op[0], op[1], op[2], _none);
+     110           0 :     case 4: return _emit(instId, op[0], op[1], op[2], op[3]);
+     111             : 
+     112           0 :     case 5:
+     113           0 :       _op4 = op[4];
+     114             :       _op5.reset();
+     115           0 :       _options |= kOptionOp4Op5Used;
+     116           0 :       return _emit(instId, op[0], op[1], op[2], op[3]);
+     117             : 
+     118           0 :     case 6:
+     119           0 :       _op4 = op[4];
+     120           0 :       _op5 = op[5];
+     121           0 :       _options |= kOptionOp4Op5Used;
+     122           0 :       return _emit(instId, op[0], op[1], op[2], op[3]);
+     123             : 
+     124             :     default:
+     125             :       return DebugUtils::errored(kErrorInvalidArgument);
+     126             :   }
+     127             : }
+     128             : 
+     129             : // ============================================================================
+     130             : // [asmjit::Assembler - Sync]
+     131             : // ============================================================================
+     132             : 
+     133        3896 : void Assembler::sync() noexcept {
+     134             :   ASMJIT_ASSERT(_code != nullptr);                       // Only called by CodeHolder, so we must be attached.
+     135             :   ASMJIT_ASSERT(_section != nullptr);                    // One section must always be active, no matter what.
+     136             :   ASMJIT_ASSERT(_bufferData == _section->_buffer._data); // `_bufferStart` is a shortcut to `_section->buffer.data`.
+     137             : 
+     138             :   // Update only if the current offset is greater than the section length.
+     139        3896 :   size_t offset = (size_t)(_bufferPtr - _bufferData);
+     140        3896 :   if (_section->getBuffer().getLength() < offset)
+     141        1948 :     _section->_buffer._length = offset;
+     142        3896 : }
+     143             : 
+     144             : // ============================================================================
+     145             : // [asmjit::Assembler - Code-Buffer]
+     146             : // ============================================================================
+     147             : 
+     148           0 : Error Assembler::setOffset(size_t offset) {
+     149           0 :   if (_lastError) return _lastError;
+     150             : 
+     151           0 :   size_t length = std::max(_section->getBuffer().getLength(), getOffset());
+     152           0 :   if (ASMJIT_UNLIKELY(offset > length))
+     153           0 :     return setLastError(DebugUtils::errored(kErrorInvalidArgument));
+     154             : 
+     155             :   // If the `Assembler` generated any code the `_bufferPtr` may be higher than
+     156             :   // the section length stored in `CodeHolder` as it doesn't update it each
+     157             :   // time it generates machine code. This is the same as calling `sync()`.
+     158           0 :   if (_section->_buffer._length < length)
+     159           0 :     _section->_buffer._length = length;
+     160             : 
+     161           0 :   _bufferPtr = _bufferData + offset;
+     162           0 :   return kErrorOk;
+     163             : }
+     164             : 
+     165             : // ============================================================================
+     166             : // [asmjit::Assembler - Comment]
+     167             : // ============================================================================
+     168             : 
+     169           0 : Error Assembler::comment(const char* s, size_t len) {
+     170           0 :   if (_lastError) return _lastError;
+     171             : 
+     172             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     173           0 :   if (_globalOptions & kOptionLoggingEnabled) {
+     174           0 :     Logger* logger = _code->getLogger();
+     175             :     logger->log(s, len);
+     176             :     logger->log("\n", 1);
+     177           0 :     return kErrorOk;
+     178             :   }
+     179             : #else
+     180             :   ASMJIT_UNUSED(s);
+     181             :   ASMJIT_UNUSED(len);
+     182             : #endif
+     183             : 
+     184             :   return kErrorOk;
+     185             : }
+     186             : 
+     187             : // ============================================================================
+     188             : // [asmjit::Assembler - Building Blocks]
+     189             : // ============================================================================
+     190             : 
+     191           0 : Label Assembler::newLabel() {
+     192           0 :   uint32_t id = 0;
+     193           0 :   if (!_lastError) {
+     194             :     ASMJIT_ASSERT(_code != nullptr);
+     195           0 :     Error err = _code->newLabelId(id);
+     196           0 :     if (ASMJIT_UNLIKELY(err)) setLastError(err);
+     197             :   }
+     198           0 :   return Label(id);
+     199             : }
+     200             : 
+     201           0 : Label Assembler::newNamedLabel(const char* name, size_t nameLength, uint32_t type, uint32_t parentId) {
+     202           0 :   uint32_t id = 0;
+     203           0 :   if (!_lastError) {
+     204             :     ASMJIT_ASSERT(_code != nullptr);
+     205           0 :     Error err = _code->newNamedLabelId(id, name, nameLength, type, parentId);
+     206           0 :     if (ASMJIT_UNLIKELY(err)) setLastError(err);
+     207             :   }
+     208           0 :   return Label(id);
+     209             : }
+     210             : 
+     211        3896 : Error Assembler::bind(const Label& label) {
+     212        3896 :   if (_lastError) return _lastError;
+     213             :   ASMJIT_ASSERT(_code != nullptr);
+     214             : 
+     215        3896 :   LabelEntry* le = _code->getLabelEntry(label);
+     216        3896 :   if (ASMJIT_UNLIKELY(!le))
+     217           0 :     return setLastError(DebugUtils::errored(kErrorInvalidLabel));
+     218             : 
+     219             :   // Label can be bound only once.
+     220        3896 :   if (ASMJIT_UNLIKELY(le->isBound()))
+     221           0 :     return setLastError(DebugUtils::errored(kErrorLabelAlreadyBound));
+     222             : 
+     223             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     224        3896 :   if (_globalOptions & kOptionLoggingEnabled) {
+     225             :     StringBuilderTmp<256> sb;
+     226           0 :     if (le->hasName())
+     227           0 :       sb.setFormat("%s:", le->getName());
+     228             :     else
+     229           0 :       sb.setFormat("L%u:", Operand::unpackId(label.getId()));
+     230             : 
+     231             :     size_t binSize = 0;
+     232           0 :     if (!_code->_logger->hasOption(Logger::kOptionBinaryForm))
+     233             :       binSize = Globals::kInvalidIndex;
+     234             : 
+     235           0 :     Logging::formatLine(sb, nullptr, binSize, 0, 0, getInlineComment());
+     236           0 :     _code->_logger->log(sb.getData(), sb.getLength());
+     237             :   }
+     238             : #endif // !ASMJIT_DISABLE_LOGGING
+     239             : 
+     240             :   Error err = kErrorOk;
+     241             :   size_t pos = getOffset();
+     242             : 
+     243        3896 :   LabelLink* link = le->_links;
+     244             :   LabelLink* prev = nullptr;
+     245             : 
+     246        3896 :   while (link) {
+     247           0 :     intptr_t offset = link->offset;
+     248           0 :     uint32_t relocId = link->relocId;
+     249             : 
+     250           0 :     if (relocId != RelocEntry::kInvalidId) {
+     251             :       // Adjust relocation data.
+     252           0 :       RelocEntry* re = _code->_relocations[relocId];
+     253           0 :       re->_data += static_cast<uint64_t>(pos);
+     254             :     }
+     255             :     else {
+     256             :       // Not using relocId, this means that we are overwriting a real
+     257             :       // displacement in the CodeBuffer.
+     258           0 :       int32_t patchedValue = static_cast<int32_t>(
+     259           0 :         static_cast<intptr_t>(pos) - offset + link->rel);
+     260             : 
+     261             :       // Size of the value we are going to patch. Only BYTE/DWORD is allowed.
+     262           0 :       uint32_t size = _bufferData[offset];
+     263           0 :       if (size == 4)
+     264             :         Utils::writeI32u(_bufferData + offset, static_cast<int32_t>(patchedValue));
+     265           0 :       else if (size == 1 && Utils::isInt8(patchedValue))
+     266           0 :         _bufferData[offset] = static_cast<uint8_t>(patchedValue & 0xFF);
+     267             :       else
+     268             :         err = DebugUtils::errored(kErrorInvalidDisplacement);
+     269             :     }
+     270             : 
+     271           0 :     prev = link->prev;
+     272           0 :     _code->_unresolvedLabelsCount--;
+     273           0 :     _code->_baseHeap.release(link, sizeof(LabelLink));
+     274             : 
+     275             :     link = prev;
+     276             :   }
+     277             : 
+     278             :   // Set as bound.
+     279        3896 :   le->_sectionId = _section->getId();
+     280        3896 :   le->_offset = pos;
+     281        3896 :   le->_links = nullptr;
+     282             :   resetInlineComment();
+     283             : 
+     284        3896 :   if (err != kErrorOk)
+     285           0 :     return setLastError(err);
+     286             : 
+     287             :   return kErrorOk;
+     288             : }
+     289             : 
+     290           0 : Error Assembler::embed(const void* data, uint32_t size) {
+     291           0 :   if (_lastError) return _lastError;
+     292             : 
+     293           0 :   if (getRemainingSpace() < size) {
+     294           0 :     Error err = _code->growBuffer(&_section->_buffer, size);
+     295           0 :     if (ASMJIT_UNLIKELY(err != kErrorOk)) return setLastError(err);
+     296             :   }
+     297             : 
+     298           0 :   ::memcpy(_bufferPtr, data, size);
+     299           0 :   _bufferPtr += size;
+     300             : 
+     301             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     302           0 :   if (_globalOptions & kOptionLoggingEnabled)
+     303           0 :     _code->_logger->logBinary(data, size);
+     304             : #endif // !ASMJIT_DISABLE_LOGGING
+     305             : 
+     306             :   return kErrorOk;
+     307             : }
+     308             : 
+     309           0 : Error Assembler::embedLabel(const Label& label) {
+     310           0 :   if (_lastError) return _lastError;
+     311             :   ASMJIT_ASSERT(_code != nullptr);
+     312             : 
+     313             :   RelocEntry* re;
+     314           0 :   LabelEntry* le = _code->getLabelEntry(label);
+     315             : 
+     316           0 :   if (ASMJIT_UNLIKELY(!le))
+     317           0 :     return setLastError(DebugUtils::errored(kErrorInvalidLabel));
+     318             : 
+     319             :   Error err;
+     320             :   uint32_t gpSize = getGpSize();
+     321             : 
+     322           0 :   if (getRemainingSpace() < gpSize) {
+     323           0 :     err = _code->growBuffer(&_section->_buffer, gpSize);
+     324           0 :     if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     325             :   }
+     326             : 
+     327             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     328           0 :   if (_globalOptions & kOptionLoggingEnabled)
+     329           0 :     _code->_logger->logf(gpSize == 4 ? ".dd L%u\n" : ".dq L%u\n", Operand::unpackId(label.getId()));
+     330             : #endif // !ASMJIT_DISABLE_LOGGING
+     331             : 
+     332           0 :   err = _code->newRelocEntry(&re, RelocEntry::kTypeRelToAbs, gpSize);
+     333           0 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     334             : 
+     335           0 :   re->_sourceSectionId = _section->getId();
+     336           0 :   re->_sourceOffset = static_cast<uint64_t>(getOffset());
+     337             : 
+     338           0 :   if (le->isBound()) {
+     339           0 :     re->_targetSectionId = le->getSectionId();
+     340           0 :     re->_data = static_cast<uint64_t>(static_cast<int64_t>(le->getOffset()));
+     341             :   }
+     342             :   else {
+     343           0 :     LabelLink* link = _code->newLabelLink(le, _section->getId(), getOffset(), 0);
+     344           0 :     if (ASMJIT_UNLIKELY(!link))
+     345           0 :       return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     346           0 :     link->relocId = re->getId();
+     347             :   }
+     348             : 
+     349             :   // Emit dummy DWORD/QWORD depending on the address size.
+     350           0 :   ::memset(_bufferPtr, 0, gpSize);
+     351           0 :   _bufferPtr += gpSize;
+     352             : 
+     353           0 :   return kErrorOk;
+     354             : }
+     355             : 
+     356           0 : Error Assembler::embedConstPool(const Label& label, const ConstPool& pool) {
+     357           0 :   if (_lastError) return _lastError;
+     358             : 
+     359           0 :   if (!isLabelValid(label))
+     360             :     return DebugUtils::errored(kErrorInvalidLabel);
+     361             : 
+     362           0 :   ASMJIT_PROPAGATE(align(kAlignData, static_cast<uint32_t>(pool.getAlignment())));
+     363           0 :   ASMJIT_PROPAGATE(bind(label));
+     364             : 
+     365             :   size_t size = pool.getSize();
+     366           0 :   if (getRemainingSpace() < size) {
+     367           0 :     Error err = _code->growBuffer(&_section->_buffer, size);
+     368           0 :     if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     369             :   }
+     370             : 
+     371           0 :   uint8_t* p = _bufferPtr;
+     372           0 :   pool.fill(p);
+     373             : 
+     374             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     375           0 :   if (_globalOptions & kOptionLoggingEnabled)
+     376           0 :     _code->_logger->logBinary(p, size);
+     377             : #endif // !ASMJIT_DISABLE_LOGGING
+     378             : 
+     379           0 :   _bufferPtr += size;
+     380           0 :   return kErrorOk;
+     381             : }
+     382             : 
+     383             : // ============================================================================
+     384             : // [asmjit::Assembler - Emit-Helpers]
+     385             : // ============================================================================
+     386             : 
+     387             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     388           0 : void Assembler::_emitLog(
+     389             :   uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3,
+     390             :   uint32_t relSize, uint32_t imLen, uint8_t* afterCursor) {
+     391             : 
+     392           0 :   Logger* logger = _code->getLogger();
+     393             :   ASMJIT_ASSERT(logger != nullptr);
+     394             :   ASMJIT_ASSERT(options & CodeEmitter::kOptionLoggingEnabled);
+     395             : 
+     396             :   StringBuilderTmp<256> sb;
+     397             :   uint32_t logOptions = logger->getOptions();
+     398             : 
+     399           0 :   uint8_t* beforeCursor = _bufferPtr;
+     400           0 :   intptr_t emittedSize = (intptr_t)(afterCursor - beforeCursor);
+     401             : 
+     402             :   sb.appendString(logger->getIndentation());
+     403             : 
+     404             :   Operand_ opArray[6];
+     405             :   opArray[0].copyFrom(o0);
+     406             :   opArray[1].copyFrom(o1);
+     407             :   opArray[2].copyFrom(o2);
+     408             :   opArray[3].copyFrom(o3);
+     409             : 
+     410           0 :   if (options & kOptionOp4Op5Used) {
+     411             :     opArray[4].copyFrom(_op4);
+     412             :     opArray[5].copyFrom(_op5);
+     413             :   }
+     414             :   else {
+     415             :     opArray[4].reset();
+     416             :     opArray[5].reset();
+     417             :   }
+     418             : 
+     419           0 :   Logging::formatInstruction(
+     420             :     sb, logOptions,
+     421             :     this, getArchType(),
+     422           0 :     Inst::Detail(instId, options, _extraReg), opArray, 6);
+     423             : 
+     424           0 :   if ((logOptions & Logger::kOptionBinaryForm) != 0)
+     425           0 :     Logging::formatLine(sb, _bufferPtr, emittedSize, relSize, imLen, getInlineComment());
+     426             :   else
+     427           0 :     Logging::formatLine(sb, nullptr, Globals::kInvalidIndex, 0, 0, getInlineComment());
+     428             : 
+     429             :   logger->log(sb.getData(), sb.getLength());
+     430           0 : }
+     431             : 
+     432           0 : Error Assembler::_emitFailed(
+     433             :   Error err,
+     434             :   uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+     435             : 
+     436             :   StringBuilderTmp<256> sb;
+     437           0 :   sb.appendString(DebugUtils::errorAsString(err));
+     438             :   sb.appendString(": ");
+     439             : 
+     440             :   Operand_ opArray[6];
+     441             :   opArray[0].copyFrom(o0);
+     442             :   opArray[1].copyFrom(o1);
+     443             :   opArray[2].copyFrom(o2);
+     444             :   opArray[3].copyFrom(o3);
+     445             : 
+     446           0 :   if (options & kOptionOp4Op5Used) {
+     447             :     opArray[4].copyFrom(_op4);
+     448             :     opArray[5].copyFrom(_op5);
+     449             :   }
+     450             :   else {
+     451             :     opArray[4].reset();
+     452             :     opArray[5].reset();
+     453             :   }
+     454             : 
+     455           0 :   Logging::formatInstruction(
+     456             :     sb, 0,
+     457             :     this, getArchType(),
+     458           0 :     Inst::Detail(instId, options, _extraReg), opArray, 6);
+     459             : 
+     460             :   resetOptions();
+     461             :   resetExtraReg();
+     462             :   resetInlineComment();
+     463           0 :   return setLastError(err, sb.getData());
+     464             : }
+     465             : #endif
+     466             : 
+     467             : } // asmjit namespace
+     468             : } // namespace PLMD
+     469             : 
+     470             : // [Api-End]
+     471             : #include "./asmjit_apiend.h"
+     472             : #pragma GCC diagnostic pop
+     473             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.h.func-sort-c.html b/coverage-libs/asmjit/assembler.h.func-sort-c.html new file mode 100644 index 000000000000..84747f06689d --- /dev/null +++ b/coverage-libs/asmjit/assembler.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:1250.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.h.func.html b/coverage-libs/asmjit/assembler.h.func.html new file mode 100644 index 000000000000..d1d090af2db9 --- /dev/null +++ b/coverage-libs/asmjit/assembler.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:1250.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/assembler.h.gcov.html b/coverage-libs/asmjit/assembler.h.gcov.html new file mode 100644 index 000000000000..9a3ecdb78e20 --- /dev/null +++ b/coverage-libs/asmjit/assembler.h.gcov.html @@ -0,0 +1,260 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/assembler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:1250.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_assembler_h
+      21             : #define __PLUMED_asmjit_assembler_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_ASSEMBLER_H
+      33             : #define _ASMJIT_BASE_ASSEMBLER_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./codeemitter.h"
+      37             : #include "./codeholder.h"
+      38             : #include "./operand.h"
+      39             : #include "./simdtypes.h"
+      40             : 
+      41             : // [Api-Begin]
+      42             : #include "./asmjit_apibegin.h"
+      43             : 
+      44             : namespace PLMD {
+      45             : namespace asmjit {
+      46             : 
+      47             : //! \addtogroup asmjit_base
+      48             : //! \{
+      49             : 
+      50             : // ============================================================================
+      51             : // [asmjit::Assembler]
+      52             : // ============================================================================
+      53             : 
+      54             : //! Base assembler.
+      55             : //!
+      56             : //! This class implements a base interface that is used by architecture
+      57             : //! specific assemblers.
+      58             : //!
+      59             : //! \sa CodeCompiler.
+      60             : class ASMJIT_VIRTAPI Assembler : public CodeEmitter {
+      61             : public:
+      62             :   ASMJIT_NONCOPYABLE(Assembler)
+      63             :   typedef CodeEmitter Base;
+      64             : 
+      65             :   // --------------------------------------------------------------------------
+      66             :   // [Construction / Destruction]
+      67             :   // --------------------------------------------------------------------------
+      68             : 
+      69             :   //! Create a new `Assembler` instance.
+      70             :   ASMJIT_API Assembler() noexcept;
+      71             :   //! Destroy the `Assembler` instance.
+      72             :   ASMJIT_API virtual ~Assembler() noexcept;
+      73             : 
+      74             :   // --------------------------------------------------------------------------
+      75             :   // [Events]
+      76             :   // --------------------------------------------------------------------------
+      77             : 
+      78             :   ASMJIT_API Error onAttach(CodeHolder* code) noexcept override;
+      79             :   ASMJIT_API Error onDetach(CodeHolder* code) noexcept override;
+      80             : 
+      81             :   // --------------------------------------------------------------------------
+      82             :   // [Code-Generation]
+      83             :   // --------------------------------------------------------------------------
+      84             : 
+      85             :   using CodeEmitter::_emit;
+      86             : 
+      87             :   ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) override;
+      88             :   ASMJIT_API Error _emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount) override;
+      89             : 
+      90             :   // --------------------------------------------------------------------------
+      91             :   // [Code-Buffer]
+      92             :   // --------------------------------------------------------------------------
+      93             : 
+      94             :   //! Called by \ref CodeHolder::sync().
+      95             :   ASMJIT_API virtual void sync() noexcept;
+      96             : 
+      97             :   //! Get the capacity of the current CodeBuffer.
+      98             :   ASMJIT_INLINE size_t getBufferCapacity() const noexcept { return (size_t)(_bufferEnd - _bufferData); }
+      99             :   //! Get the number of remaining bytes in the current CodeBuffer.
+     100           0 :   ASMJIT_INLINE size_t getRemainingSpace() const noexcept { return (size_t)(_bufferEnd - _bufferPtr); }
+     101             : 
+     102             :   //! Get the current position in the CodeBuffer.
+     103        5844 :   ASMJIT_INLINE size_t getOffset() const noexcept { return (size_t)(_bufferPtr - _bufferData); }
+     104             :   //! Set the current position in the CodeBuffer to `offset`.
+     105             :   //!
+     106             :   //! NOTE: The `offset` cannot be outside of the buffer length (even if it's
+     107             :   //! within buffer's capacity).
+     108             :   ASMJIT_API Error setOffset(size_t offset);
+     109             : 
+     110             :   //! Get start of the CodeBuffer of the current section.
+     111             :   ASMJIT_INLINE uint8_t* getBufferData() const noexcept { return _bufferData; }
+     112             :   //! Get end (first invalid byte) of the current section.
+     113             :   ASMJIT_INLINE uint8_t* getBufferEnd() const noexcept { return _bufferEnd; }
+     114             :   //! Get pointer in the CodeBuffer of the current section.
+     115             :   ASMJIT_INLINE uint8_t* getBufferPtr() const noexcept { return _bufferPtr; }
+     116             : 
+     117             :   // --------------------------------------------------------------------------
+     118             :   // [Code-Generation]
+     119             :   // --------------------------------------------------------------------------
+     120             : 
+     121             :   ASMJIT_API Label newLabel() override;
+     122             :   ASMJIT_API Label newNamedLabel(
+     123             :     const char* name,
+     124             :     size_t nameLength = Globals::kInvalidIndex,
+     125             :     uint32_t type = Label::kTypeGlobal,
+     126             :     uint32_t parentId = 0) override;
+     127             :   ASMJIT_API Error bind(const Label& label) override;
+     128             :   ASMJIT_API Error embed(const void* data, uint32_t size) override;
+     129             :   ASMJIT_API Error embedLabel(const Label& label) override;
+     130             :   ASMJIT_API Error embedConstPool(const Label& label, const ConstPool& pool) override;
+     131             :   ASMJIT_API Error comment(const char* s, size_t len = Globals::kInvalidIndex) override;
+     132             : 
+     133             :   // --------------------------------------------------------------------------
+     134             :   // [Emit-Helpers]
+     135             :   // --------------------------------------------------------------------------
+     136             : 
+     137             : protected:
+     138             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     139             :   void _emitLog(
+     140             :     uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3,
+     141             :     uint32_t relSize, uint32_t imLen, uint8_t* afterCursor);
+     142             : 
+     143             :   Error _emitFailed(
+     144             :     Error err,
+     145             :     uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3);
+     146             : #else
+     147             :   ASMJIT_INLINE Error _emitFailed(
+     148             :     uint32_t err,
+     149             :     uint32_t instId, uint32_t options, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+     150             : 
+     151             :     resetOptions();
+     152             :     resetInlineComment();
+     153             :     return setLastError(err);
+     154             :   }
+     155             : #endif
+     156             : 
+     157             :   // --------------------------------------------------------------------------
+     158             :   // [Members]
+     159             :   // --------------------------------------------------------------------------
+     160             : 
+     161             : public:
+     162             :   SectionEntry* _section;                //!< Current section where the assembling happens.
+     163             :   uint8_t* _bufferData;                  //!< Start of the CodeBuffer of the current section.
+     164             :   uint8_t* _bufferEnd;                   //!< End (first invalid byte) of the current section.
+     165             :   uint8_t* _bufferPtr;                   //!< Pointer in the CodeBuffer of the current section.
+     166             : 
+     167             :   Operand_ _op4;                         //!< 5th operand data, used only temporarily.
+     168             :   Operand_ _op5;                         //!< 6th operand data, used only temporarily.
+     169             : };
+     170             : 
+     171             : //! \}
+     172             : 
+     173             : } // asmjit namespace
+     174             : } // namespace PLMD
+     175             : 
+     176             : // [Api-End]
+     177             : #include "./asmjit_apiend.h"
+     178             : 
+     179             : // [Guard]
+     180             : #endif // _ASMJIT_BASE_ASSEMBLER_H
+     181             : #pragma GCC diagnostic pop
+     182             : #endif // __PLUMED_HAS_ASMJIT
+     183             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.cpp.func-sort-c.html b/coverage-libs/asmjit/codebuilder.cpp.func-sort-c.html new file mode 100644 index 000000000000..0ea13b449683 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.cpp.func-sort-c.html @@ -0,0 +1,205 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6025723.3 %
Date:2024-02-22 21:58:47Functions:103330.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11CodeBuilder10deletePassEPNS0_6CBPassE0
_ZN4PLMD6asmjit11CodeBuilder10embedLabelERKNS0_5LabelE0
_ZN4PLMD6asmjit11CodeBuilder10getCBLabelEPPNS0_7CBLabelEj0
_ZN4PLMD6asmjit11CodeBuilder10removeNodeEPNS0_6CBNodeE0
_ZN4PLMD6asmjit11CodeBuilder11newDataNodeEPKvj0
_ZN4PLMD6asmjit11CodeBuilder11removeNodesEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder12newAlignNodeEjj0
_ZN4PLMD6asmjit11CodeBuilder12newConstPoolEv0
_ZN4PLMD6asmjit11CodeBuilder13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit11CodeBuilder14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit11CodeBuilder14newCommentNodeEPKcm0
_ZN4PLMD6asmjit11CodeBuilder4bindERKNS0_5LabelE0
_ZN4PLMD6asmjit11CodeBuilder5alignEjj0
_ZN4PLMD6asmjit11CodeBuilder5embedEPKvj0
_ZN4PLMD6asmjit11CodeBuilder7commentEPKcm0
_ZN4PLMD6asmjit11CodeBuilder8addAfterEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder8newLabelEv0
_ZN4PLMD6asmjit11CodeBuilder8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeBuilder9addBeforeEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilderD0Ev0
_ZN4PLMD6asmjit6CBPassD0Ev0
_ZN4PLMD6asmjit6CBPassD2Ev0
_ZNK4PLMD6asmjit11CodeBuilder13getPassByNameEPKc0
_ZN4PLMD6asmjit11CodeBuilder12newLabelNodeEv1948
_ZN4PLMD6asmjit11CodeBuilder7addPassEPNS0_6CBPassE1948
_ZN4PLMD6asmjit11CodeBuilder8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11CodeBuilder9serializeEPNS0_11CodeEmitterE1948
_ZN4PLMD6asmjit11CodeBuilderC2Ev1948
_ZN4PLMD6asmjit11CodeBuilderD2Ev1948
_ZN4PLMD6asmjit6CBPassC2EPKc1948
_ZN4PLMD6asmjit11CodeBuilder17registerLabelNodeEPNS0_7CBLabelE3896
_ZN4PLMD6asmjit11CodeBuilder9setCursorEPNS0_6CBNodeE3896
_ZN4PLMD6asmjit11CodeBuilder7addNodeEPNS0_6CBNodeE56154
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.cpp.func.html b/coverage-libs/asmjit/codebuilder.cpp.func.html new file mode 100644 index 000000000000..1a2e07e4451b --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.cpp.func.html @@ -0,0 +1,205 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6025723.3 %
Date:2024-02-22 21:58:47Functions:103330.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11CodeBuilder10deletePassEPNS0_6CBPassE0
_ZN4PLMD6asmjit11CodeBuilder10embedLabelERKNS0_5LabelE0
_ZN4PLMD6asmjit11CodeBuilder10getCBLabelEPPNS0_7CBLabelEj0
_ZN4PLMD6asmjit11CodeBuilder10removeNodeEPNS0_6CBNodeE0
_ZN4PLMD6asmjit11CodeBuilder11newDataNodeEPKvj0
_ZN4PLMD6asmjit11CodeBuilder11removeNodesEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder12newAlignNodeEjj0
_ZN4PLMD6asmjit11CodeBuilder12newConstPoolEv0
_ZN4PLMD6asmjit11CodeBuilder12newLabelNodeEv1948
_ZN4PLMD6asmjit11CodeBuilder13newNamedLabelEPKcmjj0
_ZN4PLMD6asmjit11CodeBuilder14embedConstPoolERKNS0_5LabelERKNS0_9ConstPoolE0
_ZN4PLMD6asmjit11CodeBuilder14newCommentNodeEPKcm0
_ZN4PLMD6asmjit11CodeBuilder17registerLabelNodeEPNS0_7CBLabelE3896
_ZN4PLMD6asmjit11CodeBuilder4bindERKNS0_5LabelE0
_ZN4PLMD6asmjit11CodeBuilder5alignEjj0
_ZN4PLMD6asmjit11CodeBuilder5embedEPKvj0
_ZN4PLMD6asmjit11CodeBuilder7addNodeEPNS0_6CBNodeE56154
_ZN4PLMD6asmjit11CodeBuilder7addPassEPNS0_6CBPassE1948
_ZN4PLMD6asmjit11CodeBuilder7commentEPKcm0
_ZN4PLMD6asmjit11CodeBuilder8addAfterEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder8newLabelEv0
_ZN4PLMD6asmjit11CodeBuilder8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11CodeBuilder8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeBuilder9addBeforeEPNS0_6CBNodeES3_0
_ZN4PLMD6asmjit11CodeBuilder9serializeEPNS0_11CodeEmitterE1948
_ZN4PLMD6asmjit11CodeBuilder9setCursorEPNS0_6CBNodeE3896
_ZN4PLMD6asmjit11CodeBuilderC2Ev1948
_ZN4PLMD6asmjit11CodeBuilderD0Ev0
_ZN4PLMD6asmjit11CodeBuilderD2Ev1948
_ZN4PLMD6asmjit6CBPassC2EPKc1948
_ZN4PLMD6asmjit6CBPassD0Ev0
_ZN4PLMD6asmjit6CBPassD2Ev0
_ZNK4PLMD6asmjit11CodeBuilder13getPassByNameEPKc0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.cpp.gcov.html b/coverage-libs/asmjit/codebuilder.cpp.gcov.html new file mode 100644 index 000000000000..2f70fd986089 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.cpp.gcov.html @@ -0,0 +1,687 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:6025723.3 %
Date:2024-02-22 21:58:47Functions:103330.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Guard]
+      33             : #include "./asmjit_build.h"
+      34             : #if !defined(ASMJIT_DISABLE_BUILDER)
+      35             : 
+      36             : // [Dependencies]
+      37             : #include "./codebuilder.h"
+      38             : 
+      39             : // [Api-Begin]
+      40             : #include "./asmjit_apibegin.h"
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace asmjit {
+      44             : 
+      45             : // ============================================================================
+      46             : // [asmjit::CodeBuilder - Construction / Destruction]
+      47             : // ============================================================================
+      48             : 
+      49        1948 : CodeBuilder::CodeBuilder() noexcept
+      50             :   : CodeEmitter(kTypeBuilder),
+      51        1948 :     _cbBaseZone(32768 - Zone::kZoneOverhead),
+      52        1948 :     _cbDataZone(16384 - Zone::kZoneOverhead),
+      53        1948 :     _cbPassZone(32768 - Zone::kZoneOverhead),
+      54        1948 :     _cbHeap(&_cbBaseZone),
+      55             :     _cbPasses(),
+      56             :     _cbLabels(),
+      57        1948 :     _firstNode(nullptr),
+      58        1948 :     _lastNode(nullptr),
+      59        1948 :     _cursor(nullptr),
+      60        1948 :     _position(0),
+      61        1948 :     _nodeFlags(0) {}
+      62        1948 : CodeBuilder::~CodeBuilder() noexcept {}
+      63             : 
+      64             : // ============================================================================
+      65             : // [asmjit::CodeBuilder - Events]
+      66             : // ============================================================================
+      67             : 
+      68        1948 : Error CodeBuilder::onAttach(CodeHolder* code) noexcept {
+      69        1948 :   return Base::onAttach(code);
+      70             : }
+      71             : 
+      72           0 : Error CodeBuilder::onDetach(CodeHolder* code) noexcept {
+      73             :   _cbPasses.reset();
+      74             :   _cbLabels.reset();
+      75           0 :   _cbHeap.reset(&_cbBaseZone);
+      76             : 
+      77           0 :   _cbBaseZone.reset(false);
+      78           0 :   _cbDataZone.reset(false);
+      79           0 :   _cbPassZone.reset(false);
+      80             : 
+      81           0 :   _position = 0;
+      82           0 :   _nodeFlags = 0;
+      83             : 
+      84           0 :   _firstNode = nullptr;
+      85           0 :   _lastNode = nullptr;
+      86           0 :   _cursor = nullptr;
+      87             : 
+      88           0 :   return Base::onDetach(code);
+      89             : }
+      90             : 
+      91             : // ============================================================================
+      92             : // [asmjit::CodeBuilder - Node-Factory]
+      93             : // ============================================================================
+      94             : 
+      95           0 : Error CodeBuilder::getCBLabel(CBLabel** pOut, uint32_t id) noexcept {
+      96           0 :   if (_lastError) return _lastError;
+      97             :   ASMJIT_ASSERT(_code != nullptr);
+      98             : 
+      99           0 :   size_t index = Operand::unpackId(id);
+     100           0 :   if (ASMJIT_UNLIKELY(index >= _code->getLabelsCount()))
+     101             :     return DebugUtils::errored(kErrorInvalidLabel);
+     102             : 
+     103           0 :   if (index >= _cbLabels.getLength())
+     104           0 :     ASMJIT_PROPAGATE(_cbLabels.resize(&_cbHeap, index + 1));
+     105             : 
+     106           0 :   CBLabel* node = _cbLabels[index];
+     107           0 :   if (!node) {
+     108             :     node = newNodeT<CBLabel>(id);
+     109           0 :     if (ASMJIT_UNLIKELY(!node))
+     110             :       return DebugUtils::errored(kErrorNoHeapMemory);
+     111           0 :     _cbLabels[index] = node;
+     112             :   }
+     113             : 
+     114           0 :   *pOut = node;
+     115           0 :   return kErrorOk;
+     116             : }
+     117             : 
+     118        3896 : Error CodeBuilder::registerLabelNode(CBLabel* node) noexcept {
+     119        3896 :   if (_lastError) return _lastError;
+     120             :   ASMJIT_ASSERT(_code != nullptr);
+     121             : 
+     122             :   // Don't call setLastError() from here, we are noexcept and we are called
+     123             :   // by `newLabelNode()` and `newFuncNode()`, which are noexcept as well.
+     124             :   uint32_t id;
+     125        3896 :   ASMJIT_PROPAGATE(_code->newLabelId(id));
+     126        3896 :   size_t index = Operand::unpackId(id);
+     127             : 
+     128             :   // We just added one label so it must be true.
+     129             :   ASMJIT_ASSERT(_cbLabels.getLength() < index + 1);
+     130        3896 :   ASMJIT_PROPAGATE(_cbLabels.resize(&_cbHeap, index + 1));
+     131             : 
+     132        3896 :   _cbLabels[index] = node;
+     133        3896 :   node->_id = id;
+     134        3896 :   return kErrorOk;
+     135             : }
+     136             : 
+     137        1948 : CBLabel* CodeBuilder::newLabelNode() noexcept {
+     138             :   CBLabel* node = newNodeT<CBLabel>();
+     139        1948 :   if (!node || registerLabelNode(node) != kErrorOk)
+     140           0 :     return nullptr;
+     141             :   return node;
+     142             : }
+     143             : 
+     144           0 : CBAlign* CodeBuilder::newAlignNode(uint32_t mode, uint32_t alignment) noexcept {
+     145           0 :   return newNodeT<CBAlign>(mode, alignment);
+     146             : }
+     147             : 
+     148           0 : CBData* CodeBuilder::newDataNode(const void* data, uint32_t size) noexcept {
+     149           0 :   if (size > CBData::kInlineBufferSize) {
+     150           0 :     void* cloned = _cbDataZone.alloc(size);
+     151           0 :     if (!cloned) return nullptr;
+     152             : 
+     153           0 :     if (data) ::memcpy(cloned, data, size);
+     154             :     data = cloned;
+     155             :   }
+     156             : 
+     157           0 :   return newNodeT<CBData>(const_cast<void*>(data), size);
+     158             : }
+     159             : 
+     160           0 : CBConstPool* CodeBuilder::newConstPool() noexcept {
+     161             :   CBConstPool* node = newNodeT<CBConstPool>();
+     162           0 :   if (!node || registerLabelNode(node) != kErrorOk)
+     163           0 :     return nullptr;
+     164             :   return node;
+     165             : }
+     166             : 
+     167           0 : CBComment* CodeBuilder::newCommentNode(const char* s, size_t len) noexcept {
+     168           0 :   if (s) {
+     169           0 :     if (len == Globals::kInvalidIndex) len = ::strlen(s);
+     170           0 :     if (len > 0) {
+     171           0 :       s = static_cast<char*>(_cbDataZone.dup(s, len, true));
+     172           0 :       if (!s) return nullptr;
+     173             :     }
+     174             :   }
+     175             : 
+     176           0 :   return newNodeT<CBComment>(s);
+     177             : }
+     178             : 
+     179             : // ============================================================================
+     180             : // [asmjit::CodeBuilder - Code-Emitter]
+     181             : // ============================================================================
+     182             : 
+     183           0 : Label CodeBuilder::newLabel() {
+     184             :   uint32_t id = kInvalidValue;
+     185             : 
+     186           0 :   if (!_lastError) {
+     187             :     CBLabel* node = newNodeT<CBLabel>(id);
+     188           0 :     if (ASMJIT_UNLIKELY(!node)) {
+     189           0 :       setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     190             :     }
+     191             :     else {
+     192           0 :       Error err = registerLabelNode(node);
+     193           0 :       if (ASMJIT_UNLIKELY(err))
+     194           0 :         setLastError(err);
+     195             :       else
+     196             :         id = node->getId();
+     197             :     }
+     198             :   }
+     199             : 
+     200           0 :   return Label(id);
+     201             : }
+     202             : 
+     203           0 : Label CodeBuilder::newNamedLabel(const char* name, size_t nameLength, uint32_t type, uint32_t parentId) {
+     204           0 :   uint32_t id = kInvalidValue;
+     205             : 
+     206           0 :   if (!_lastError) {
+     207             :     CBLabel* node = newNodeT<CBLabel>(id);
+     208           0 :     if (ASMJIT_UNLIKELY(!node)) {
+     209           0 :       setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     210             :     }
+     211             :     else {
+     212           0 :       Error err = _code->newNamedLabelId(id, name, nameLength, type, parentId);
+     213           0 :       if (ASMJIT_UNLIKELY(err))
+     214           0 :         setLastError(err);
+     215             :       else
+     216           0 :         id = node->getId();
+     217             :     }
+     218             :   }
+     219             : 
+     220           0 :   return Label(id);
+     221             : }
+     222             : 
+     223           0 : Error CodeBuilder::bind(const Label& label) {
+     224           0 :   if (_lastError) return _lastError;
+     225             : 
+     226             :   CBLabel* node;
+     227             :   Error err = getCBLabel(&node, label);
+     228           0 :   if (ASMJIT_UNLIKELY(err))
+     229           0 :     return setLastError(err);
+     230             : 
+     231           0 :   addNode(node);
+     232           0 :   return kErrorOk;
+     233             : }
+     234             : 
+     235           0 : Error CodeBuilder::align(uint32_t mode, uint32_t alignment) {
+     236           0 :   if (_lastError) return _lastError;
+     237             : 
+     238           0 :   CBAlign* node = newAlignNode(mode, alignment);
+     239           0 :   if (ASMJIT_UNLIKELY(!node))
+     240           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     241             : 
+     242           0 :   addNode(node);
+     243           0 :   return kErrorOk;
+     244             : }
+     245             : 
+     246           0 : Error CodeBuilder::embed(const void* data, uint32_t size) {
+     247           0 :   if (_lastError) return _lastError;
+     248             : 
+     249           0 :   CBData* node = newDataNode(data, size);
+     250           0 :   if (ASMJIT_UNLIKELY(!node))
+     251           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     252             : 
+     253           0 :   addNode(node);
+     254           0 :   return kErrorOk;
+     255             : }
+     256             : 
+     257           0 : Error CodeBuilder::embedLabel(const Label& label) {
+     258           0 :   if (_lastError) return _lastError;
+     259             : 
+     260             :   CBLabelData* node = newNodeT<CBLabelData>(label.getId());
+     261           0 :   if (ASMJIT_UNLIKELY(!node))
+     262           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     263             : 
+     264           0 :   addNode(node);
+     265           0 :   return kErrorOk;
+     266             : }
+     267             : 
+     268           0 : Error CodeBuilder::embedConstPool(const Label& label, const ConstPool& pool) {
+     269           0 :   if (_lastError) return _lastError;
+     270             : 
+     271           0 :   if (!isLabelValid(label))
+     272           0 :     return setLastError(DebugUtils::errored(kErrorInvalidLabel));
+     273             : 
+     274           0 :   ASMJIT_PROPAGATE(align(kAlignData, static_cast<uint32_t>(pool.getAlignment())));
+     275           0 :   ASMJIT_PROPAGATE(bind(label));
+     276             : 
+     277           0 :   CBData* node = newDataNode(nullptr, static_cast<uint32_t>(pool.getSize()));
+     278           0 :   if (ASMJIT_UNLIKELY(!node))
+     279           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     280             : 
+     281           0 :   pool.fill(node->getData());
+     282           0 :   addNode(node);
+     283           0 :   return kErrorOk;
+     284             : }
+     285             : 
+     286           0 : Error CodeBuilder::comment(const char* s, size_t len) {
+     287           0 :   if (_lastError) return _lastError;
+     288             : 
+     289           0 :   CBComment* node = newCommentNode(s, len);
+     290           0 :   if (ASMJIT_UNLIKELY(!node))
+     291           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     292             : 
+     293           0 :   addNode(node);
+     294           0 :   return kErrorOk;
+     295             : }
+     296             : 
+     297             : // ============================================================================
+     298             : // [asmjit::CodeBuilder - Node-Management]
+     299             : // ============================================================================
+     300             : 
+     301       56154 : CBNode* CodeBuilder::addNode(CBNode* node) noexcept {
+     302             :   ASMJIT_ASSERT(node);
+     303             :   ASMJIT_ASSERT(node->_prev == nullptr);
+     304             :   ASMJIT_ASSERT(node->_next == nullptr);
+     305             : 
+     306       56154 :   if (!_cursor) {
+     307        1948 :     if (!_firstNode) {
+     308        1948 :       _firstNode = node;
+     309        1948 :       _lastNode = node;
+     310             :     }
+     311             :     else {
+     312           0 :       node->_next = _firstNode;
+     313           0 :       _firstNode->_prev = node;
+     314           0 :       _firstNode = node;
+     315             :     }
+     316             :   }
+     317             :   else {
+     318             :     CBNode* prev = _cursor;
+     319       54206 :     CBNode* next = _cursor->_next;
+     320             : 
+     321       54206 :     node->_prev = prev;
+     322       54206 :     node->_next = next;
+     323             : 
+     324       54206 :     prev->_next = node;
+     325       54206 :     if (next)
+     326       50310 :       next->_prev = node;
+     327             :     else
+     328        3896 :       _lastNode = node;
+     329             :   }
+     330             : 
+     331       56154 :   _cursor = node;
+     332       56154 :   return node;
+     333             : }
+     334             : 
+     335           0 : CBNode* CodeBuilder::addAfter(CBNode* node, CBNode* ref) noexcept {
+     336             :   ASMJIT_ASSERT(node);
+     337             :   ASMJIT_ASSERT(ref);
+     338             : 
+     339             :   ASMJIT_ASSERT(node->_prev == nullptr);
+     340             :   ASMJIT_ASSERT(node->_next == nullptr);
+     341             : 
+     342             :   CBNode* prev = ref;
+     343           0 :   CBNode* next = ref->_next;
+     344             : 
+     345           0 :   node->_prev = prev;
+     346           0 :   node->_next = next;
+     347             : 
+     348           0 :   prev->_next = node;
+     349           0 :   if (next)
+     350           0 :     next->_prev = node;
+     351             :   else
+     352           0 :     _lastNode = node;
+     353             : 
+     354           0 :   return node;
+     355             : }
+     356             : 
+     357           0 : CBNode* CodeBuilder::addBefore(CBNode* node, CBNode* ref) noexcept {
+     358             :   ASMJIT_ASSERT(node != nullptr);
+     359             :   ASMJIT_ASSERT(node->_prev == nullptr);
+     360             :   ASMJIT_ASSERT(node->_next == nullptr);
+     361             :   ASMJIT_ASSERT(ref != nullptr);
+     362             : 
+     363           0 :   CBNode* prev = ref->_prev;
+     364             :   CBNode* next = ref;
+     365             : 
+     366           0 :   node->_prev = prev;
+     367           0 :   node->_next = next;
+     368             : 
+     369           0 :   next->_prev = node;
+     370           0 :   if (prev)
+     371           0 :     prev->_next = node;
+     372             :   else
+     373           0 :     _firstNode = node;
+     374             : 
+     375           0 :   return node;
+     376             : }
+     377             : 
+     378             : static ASMJIT_INLINE void CodeBuilder_nodeRemoved(CodeBuilder* self, CBNode* node_) noexcept {
+     379           0 :   if (node_->isJmpOrJcc()) {
+     380             :     CBJump* node = static_cast<CBJump*>(node_);
+     381             :     CBLabel* label = node->getTarget();
+     382             : 
+     383           0 :     if (label) {
+     384             :       // Disconnect.
+     385           0 :       CBJump** pPrev = &label->_from;
+     386             :       for (;;) {
+     387             :         ASMJIT_ASSERT(*pPrev != nullptr);
+     388             : 
+     389           0 :         CBJump* current = *pPrev;
+     390           0 :         if (!current) break;
+     391             : 
+     392           0 :         if (current == node) {
+     393           0 :           *pPrev = node->_jumpNext;
+     394           0 :           break;
+     395             :         }
+     396             : 
+     397           0 :         pPrev = &current->_jumpNext;
+     398           0 :       }
+     399             : 
+     400             :       label->subNumRefs();
+     401             :     }
+     402             :   }
+     403             : }
+     404             : 
+     405           0 : CBNode* CodeBuilder::removeNode(CBNode* node) noexcept {
+     406           0 :   CBNode* prev = node->_prev;
+     407           0 :   CBNode* next = node->_next;
+     408             : 
+     409           0 :   if (_firstNode == node)
+     410           0 :     _firstNode = next;
+     411             :   else
+     412           0 :     prev->_next = next;
+     413             : 
+     414           0 :   if (_lastNode == node)
+     415           0 :     _lastNode  = prev;
+     416             :   else
+     417           0 :     next->_prev = prev;
+     418             : 
+     419           0 :   node->_prev = nullptr;
+     420           0 :   node->_next = nullptr;
+     421             : 
+     422           0 :   if (_cursor == node)
+     423           0 :     _cursor = prev;
+     424             :   CodeBuilder_nodeRemoved(this, node);
+     425             : 
+     426           0 :   return node;
+     427             : }
+     428             : 
+     429           0 : void CodeBuilder::removeNodes(CBNode* first, CBNode* last) noexcept {
+     430           0 :   if (first == last) {
+     431           0 :     removeNode(first);
+     432           0 :     return;
+     433             :   }
+     434             : 
+     435           0 :   CBNode* prev = first->_prev;
+     436           0 :   CBNode* next = last->_next;
+     437             : 
+     438           0 :   if (_firstNode == first)
+     439           0 :     _firstNode = next;
+     440             :   else
+     441           0 :     prev->_next = next;
+     442             : 
+     443           0 :   if (_lastNode == last)
+     444           0 :     _lastNode  = prev;
+     445             :   else
+     446           0 :     next->_prev = prev;
+     447             : 
+     448             :   CBNode* node = first;
+     449             :   for (;;) {
+     450             :     CBNode* next = node->getNext();
+     451             :     ASMJIT_ASSERT(next != nullptr);
+     452             : 
+     453           0 :     node->_prev = nullptr;
+     454           0 :     node->_next = nullptr;
+     455             : 
+     456           0 :     if (_cursor == node)
+     457           0 :       _cursor = prev;
+     458             :     CodeBuilder_nodeRemoved(this, node);
+     459             : 
+     460           0 :     if (node == last)
+     461             :       break;
+     462             :     node = next;
+     463             :   }
+     464             : }
+     465             : 
+     466        3896 : CBNode* CodeBuilder::setCursor(CBNode* node) noexcept {
+     467        3896 :   CBNode* old = _cursor;
+     468        3896 :   _cursor = node;
+     469        3896 :   return old;
+     470             : }
+     471             : 
+     472             : // ============================================================================
+     473             : // [asmjit::CodeBuilder - Passes]
+     474             : // ============================================================================
+     475             : 
+     476           0 : ASMJIT_FAVOR_SIZE CBPass* CodeBuilder::getPassByName(const char* name) const noexcept {
+     477           0 :   for (size_t i = 0, len = _cbPasses.getLength(); i < len; i++) {
+     478           0 :     CBPass* pass = _cbPasses[i];
+     479           0 :     if (::strcmp(pass->getName(), name) == 0)
+     480           0 :       return pass;
+     481             :   }
+     482             : 
+     483             :   return nullptr;
+     484             : }
+     485             : 
+     486        1948 : ASMJIT_FAVOR_SIZE Error CodeBuilder::addPass(CBPass* pass) noexcept {
+     487        1948 :   if (ASMJIT_UNLIKELY(pass == nullptr)) {
+     488             :     // Since this is directly called by `addPassT()` we treat `null` argument
+     489             :     // as out-of-memory condition. Otherwise it would be API misuse.
+     490             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     491             :   }
+     492        1948 :   else if (ASMJIT_UNLIKELY(pass->_cb)) {
+     493             :     // Kind of weird, but okay...
+     494           0 :     if (pass->_cb == this)
+     495           0 :       return kErrorOk;
+     496             :     return DebugUtils::errored(kErrorInvalidState);
+     497             :   }
+     498             : 
+     499        1948 :   ASMJIT_PROPAGATE(_cbPasses.append(&_cbHeap, pass));
+     500        1948 :   pass->_cb = this;
+     501        1948 :   return kErrorOk;
+     502             : }
+     503             : 
+     504           0 : ASMJIT_FAVOR_SIZE Error CodeBuilder::deletePass(CBPass* pass) noexcept {
+     505           0 :   if (ASMJIT_UNLIKELY(pass == nullptr))
+     506             :     return DebugUtils::errored(kErrorInvalidArgument);
+     507             : 
+     508           0 :   if (pass->_cb != nullptr) {
+     509           0 :     if (pass->_cb != this)
+     510             :       return DebugUtils::errored(kErrorInvalidState);
+     511             : 
+     512             :     size_t index = _cbPasses.indexOf(pass);
+     513             :     ASMJIT_ASSERT(index != Globals::kInvalidIndex);
+     514             : 
+     515           0 :     pass->_cb = nullptr;
+     516             :     _cbPasses.removeAt(index);
+     517             :   }
+     518             : 
+     519           0 :   pass->~CBPass();
+     520           0 :   return kErrorOk;
+     521             : }
+     522             : 
+     523             : // ============================================================================
+     524             : // [asmjit::CodeBuilder - Serialization]
+     525             : // ============================================================================
+     526             : 
+     527        1948 : Error CodeBuilder::serialize(CodeEmitter* dst) {
+     528             :   Error err = kErrorOk;
+     529             :   CBNode* node_ = getFirstNode();
+     530             : 
+     531             :   do {
+     532             :     dst->setInlineComment(node_->getInlineComment());
+     533             : 
+     534       56154 :     switch (node_->getType()) {
+     535           0 :       case CBNode::kNodeAlign: {
+     536             :         CBAlign* node = static_cast<CBAlign*>(node_);
+     537           0 :         err = dst->align(node->getMode(), node->getAlignment());
+     538           0 :         break;
+     539             :       }
+     540             : 
+     541           0 :       case CBNode::kNodeData: {
+     542             :         CBData* node = static_cast<CBData*>(node_);
+     543           0 :         err = dst->embed(node->getData(), node->getSize());
+     544           0 :         break;
+     545             :       }
+     546             : 
+     547        3896 :       case CBNode::kNodeFunc:
+     548             :       case CBNode::kNodeLabel: {
+     549             :         CBLabel* node = static_cast<CBLabel*>(node_);
+     550        3896 :         err = dst->bind(node->getLabel());
+     551        3896 :         break;
+     552             :       }
+     553             : 
+     554           0 :       case CBNode::kNodeLabelData: {
+     555             :         CBLabelData* node = static_cast<CBLabelData*>(node_);
+     556           0 :         err = dst->embedLabel(node->getLabel());
+     557           0 :         break;
+     558             :       }
+     559             : 
+     560           0 :       case CBNode::kNodeConstPool: {
+     561             :         CBConstPool* node = static_cast<CBConstPool*>(node_);
+     562           0 :         err = dst->embedConstPool(node->getLabel(), node->getConstPool());
+     563           0 :         break;
+     564             :       }
+     565             : 
+     566             :       case CBNode::kNodeInst:
+     567             :       case CBNode::kNodeFuncCall: {
+     568             :         CBInst* node = node_->as<CBInst>();
+     569             :         dst->setOptions(node->getOptions());
+     570             :         dst->setExtraReg(node->getExtraReg());
+     571       48362 :         err = dst->emitOpArray(node->getInstId(), node->getOpArray(), node->getOpCount());
+     572       48362 :         break;
+     573             :       }
+     574             : 
+     575           0 :       case CBNode::kNodeComment: {
+     576             :         CBComment* node = static_cast<CBComment*>(node_);
+     577           0 :         err = dst->comment(node->getInlineComment());
+     578           0 :         break;
+     579             :       }
+     580             : 
+     581             :       default:
+     582             :         break;
+     583             :     }
+     584             : 
+     585       56154 :     if (err) break;
+     586             :     node_ = node_->getNext();
+     587       56154 :   } while (node_);
+     588             : 
+     589        1948 :   return err;
+     590             : }
+     591             : 
+     592             : // ============================================================================
+     593             : // [asmjit::CBPass]
+     594             : // ============================================================================
+     595             : 
+     596        1948 : CBPass::CBPass(const char* name) noexcept
+     597        1948 :   : _cb(nullptr),
+     598        1948 :     _name(name) {}
+     599           0 : CBPass::~CBPass() noexcept {}
+     600             : 
+     601             : } // asmjit namespace
+     602             : } // namespace PLMD
+     603             : 
+     604             : // [Api-End]
+     605             : #include "./asmjit_apiend.h"
+     606             : 
+     607             : // [Guard]
+     608             : #endif // !ASMJIT_DISABLE_BUILDER
+     609             : #pragma GCC diagnostic pop
+     610             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.h.func-sort-c.html b/coverage-libs/asmjit/codebuilder.h.func-sort-c.html new file mode 100644 index 000000000000..c83075f291a5 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:509453.2 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.h.func.html b/coverage-libs/asmjit/codebuilder.h.func.html new file mode 100644 index 000000000000..bf64f2b95e37 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:509453.2 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codebuilder.h.gcov.html b/coverage-libs/asmjit/codebuilder.h.gcov.html new file mode 100644 index 000000000000..b86511d48325 --- /dev/null +++ b/coverage-libs/asmjit/codebuilder.h.gcov.html @@ -0,0 +1,1021 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codebuilder.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codebuilder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:509453.2 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_codebuilder_h
+      21             : #define __PLUMED_asmjit_codebuilder_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_CODEBUILDER_H
+      33             : #define _ASMJIT_BASE_CODEBUILDER_H
+      34             : 
+      35             : #include "./asmjit_build.h"
+      36             : #if !defined(ASMJIT_DISABLE_BUILDER)
+      37             : 
+      38             : // [Dependencies]
+      39             : #include "./assembler.h"
+      40             : #include "./codeholder.h"
+      41             : #include "./constpool.h"
+      42             : #include "./inst.h"
+      43             : #include "./operand.h"
+      44             : #include "./utils.h"
+      45             : #include "./zone.h"
+      46             : 
+      47             : // [Api-Begin]
+      48             : #include "./asmjit_apibegin.h"
+      49             : 
+      50             : namespace PLMD {
+      51             : namespace asmjit {
+      52             : 
+      53             : // ============================================================================
+      54             : // [Forward Declarations]
+      55             : // ============================================================================
+      56             : 
+      57             : class CBNode;
+      58             : class CBPass;
+      59             : 
+      60             : class CBAlign;
+      61             : class CBComment;
+      62             : class CBConstPool;
+      63             : class CBData;
+      64             : class CBInst;
+      65             : class CBJump;
+      66             : class CBLabel;
+      67             : class CBLabelData;
+      68             : class CBSentinel;
+      69             : 
+      70             : //! \addtogroup asmjit_base
+      71             : //! \{
+      72             : 
+      73             : // ============================================================================
+      74             : // [asmjit::CodeBuilder]
+      75             : // ============================================================================
+      76             : 
+      77             : class ASMJIT_VIRTAPI CodeBuilder : public CodeEmitter {
+      78             : public:
+      79             :   ASMJIT_NONCOPYABLE(CodeBuilder)
+      80             :   typedef CodeEmitter Base;
+      81             : 
+      82             :   // --------------------------------------------------------------------------
+      83             :   // [Construction / Destruction]
+      84             :   // --------------------------------------------------------------------------
+      85             : 
+      86             :   //! Create a new `CodeBuilder` instance.
+      87             :   ASMJIT_API CodeBuilder() noexcept;
+      88             :   //! Destroy the `CodeBuilder` instance.
+      89             :   ASMJIT_API virtual ~CodeBuilder() noexcept;
+      90             : 
+      91             :   // --------------------------------------------------------------------------
+      92             :   // [Events]
+      93             :   // --------------------------------------------------------------------------
+      94             : 
+      95             :   ASMJIT_API virtual Error onAttach(CodeHolder* code) noexcept override;
+      96             :   ASMJIT_API virtual Error onDetach(CodeHolder* code) noexcept override;
+      97             : 
+      98             :   // --------------------------------------------------------------------------
+      99             :   // [Accessors]
+     100             :   // --------------------------------------------------------------------------
+     101             : 
+     102             :   //! Get a vector of CBPass objects that will be executed by `process()`.
+     103             :   ASMJIT_INLINE const ZoneVector<CBPass*>& getPasses() const noexcept { return _cbPasses; }
+     104             : 
+     105             :   //! Get a vector of CBLabel nodes.
+     106             :   //!
+     107             :   //! NOTE: If a label of some index is not associated with `CodeBuilder` it
+     108             :   //! would be null, so always check for nulls if you iterate over the vector.
+     109             :   ASMJIT_INLINE const ZoneVector<CBLabel*>& getLabels() const noexcept { return _cbLabels; }
+     110             : 
+     111             :   //! Get the first node.
+     112        3896 :   ASMJIT_INLINE CBNode* getFirstNode() const noexcept { return _firstNode; }
+     113             :   //! Get the last node.
+     114             :   ASMJIT_INLINE CBNode* getLastNode() const noexcept { return _lastNode; }
+     115             : 
+     116             :   // --------------------------------------------------------------------------
+     117             :   // [Node-Management]
+     118             :   // --------------------------------------------------------------------------
+     119             : 
+     120             :   //! \internal
+     121             :   template<typename T>
+     122        3896 :   ASMJIT_INLINE T* newNodeT() noexcept { return new(_cbHeap.alloc(sizeof(T))) T(this); }
+     123             : 
+     124             :   //! \internal
+     125             :   template<typename T, typename P0>
+     126           0 :   ASMJIT_INLINE T* newNodeT(P0 p0) noexcept { return new(_cbHeap.alloc(sizeof(T))) T(this, p0); }
+     127             : 
+     128             :   //! \internal
+     129             :   template<typename T, typename P0, typename P1>
+     130        1948 :   ASMJIT_INLINE T* newNodeT(P0 p0, P1 p1) noexcept { return new(_cbHeap.alloc(sizeof(T))) T(this, p0, p1); }
+     131             : 
+     132             :   //! \internal
+     133             :   template<typename T, typename P0, typename P1, typename P2>
+     134           0 :   ASMJIT_INLINE T* newNodeT(P0 p0, P1 p1, P2 p2) noexcept { return new(_cbHeap.alloc(sizeof(T))) T(this, p0, p1, p2); }
+     135             : 
+     136             :   ASMJIT_API Error registerLabelNode(CBLabel* node) noexcept;
+     137             :   //! Get `CBLabel` by `id`.
+     138             :   ASMJIT_API Error getCBLabel(CBLabel** pOut, uint32_t id) noexcept;
+     139             :   //! Get `CBLabel` by `label`.
+     140           0 :   ASMJIT_INLINE Error getCBLabel(CBLabel** pOut, const Label& label) noexcept { return getCBLabel(pOut, label.getId()); }
+     141             : 
+     142             :   //! Create a new \ref CBLabel node.
+     143             :   ASMJIT_API CBLabel* newLabelNode() noexcept;
+     144             :   //! Create a new \ref CBAlign node.
+     145             :   ASMJIT_API CBAlign* newAlignNode(uint32_t mode, uint32_t alignment) noexcept;
+     146             :   //! Create a new \ref CBData node.
+     147             :   ASMJIT_API CBData* newDataNode(const void* data, uint32_t size) noexcept;
+     148             :   //! Create a new \ref CBConstPool node.
+     149             :   ASMJIT_API CBConstPool* newConstPool() noexcept;
+     150             :   //! Create a new \ref CBComment node.
+     151             :   ASMJIT_API CBComment* newCommentNode(const char* s, size_t len) noexcept;
+     152             : 
+     153             :   // --------------------------------------------------------------------------
+     154             :   // [Code-Emitter]
+     155             :   // --------------------------------------------------------------------------
+     156             : 
+     157             :   ASMJIT_API virtual Label newLabel() override;
+     158             :   ASMJIT_API virtual Label newNamedLabel(const char* name, size_t nameLength = Globals::kInvalidIndex, uint32_t type = Label::kTypeGlobal, uint32_t parentId = kInvalidValue) override;
+     159             :   ASMJIT_API virtual Error bind(const Label& label) override;
+     160             :   ASMJIT_API virtual Error align(uint32_t mode, uint32_t alignment) override;
+     161             :   ASMJIT_API virtual Error embed(const void* data, uint32_t size) override;
+     162             :   ASMJIT_API virtual Error embedLabel(const Label& label) override;
+     163             :   ASMJIT_API virtual Error embedConstPool(const Label& label, const ConstPool& pool) override;
+     164             :   ASMJIT_API virtual Error comment(const char* s, size_t len = Globals::kInvalidIndex) override;
+     165             : 
+     166             :   // --------------------------------------------------------------------------
+     167             :   // [Node-Management]
+     168             :   // --------------------------------------------------------------------------
+     169             : 
+     170             :   //! Add `node` after the current and set current to `node`.
+     171             :   ASMJIT_API CBNode* addNode(CBNode* node) noexcept;
+     172             :   //! Insert `node` after `ref`.
+     173             :   ASMJIT_API CBNode* addAfter(CBNode* node, CBNode* ref) noexcept;
+     174             :   //! Insert `node` before `ref`.
+     175             :   ASMJIT_API CBNode* addBefore(CBNode* node, CBNode* ref) noexcept;
+     176             :   //! Remove `node`.
+     177             :   ASMJIT_API CBNode* removeNode(CBNode* node) noexcept;
+     178             :   //! Remove multiple nodes.
+     179             :   ASMJIT_API void removeNodes(CBNode* first, CBNode* last) noexcept;
+     180             : 
+     181             :   //! Get current node.
+     182             :   //!
+     183             :   //! \note If this method returns null it means that nothing has been
+     184             :   //! emitted yet.
+     185        1948 :   ASMJIT_INLINE CBNode* getCursor() const noexcept { return _cursor; }
+     186             :   //! Set the current node without returning the previous node.
+     187        9440 :   ASMJIT_INLINE void _setCursor(CBNode* node) noexcept { _cursor = node; }
+     188             :   //! Set the current node to `node` and return the previous one.
+     189             :   ASMJIT_API CBNode* setCursor(CBNode* node) noexcept;
+     190             : 
+     191             :   // --------------------------------------------------------------------------
+     192             :   // [Passes]
+     193             :   // --------------------------------------------------------------------------
+     194             : 
+     195             :   template<typename T>
+     196        1948 :   ASMJIT_INLINE T* newPassT() noexcept { return new(_cbBaseZone.alloc(sizeof(T))) T(); }
+     197             :   template<typename T, typename P0>
+     198             :   ASMJIT_INLINE T* newPassT(P0 p0) noexcept { return new(_cbBaseZone.alloc(sizeof(T))) T(p0); }
+     199             :   template<typename T, typename P0, typename P1>
+     200             :   ASMJIT_INLINE T* newPassT(P0 p0, P1 p1) noexcept { return new(_cbBaseZone.alloc(sizeof(T))) T(p0, p1); }
+     201             : 
+     202             :   template<typename T>
+     203        1948 :   ASMJIT_INLINE Error addPassT() noexcept { return addPass(newPassT<T>()); }
+     204             :   template<typename T, typename P0>
+     205             :   ASMJIT_INLINE Error addPassT(P0 p0) noexcept { return addPass(newPassT<P0>(p0)); }
+     206             :   template<typename T, typename P0, typename P1>
+     207             :   ASMJIT_INLINE Error addPassT(P0 p0, P1 p1) noexcept { return addPass(newPassT<P0, P1>(p0, p1)); }
+     208             : 
+     209             :   //! Get a `CBPass` by name.
+     210             :   ASMJIT_API CBPass* getPassByName(const char* name) const noexcept;
+     211             :   //! Add `pass` to the list of passes.
+     212             :   ASMJIT_API Error addPass(CBPass* pass) noexcept;
+     213             :   //! Remove `pass` from the list of passes and delete it.
+     214             :   ASMJIT_API Error deletePass(CBPass* pass) noexcept;
+     215             : 
+     216             :   // --------------------------------------------------------------------------
+     217             :   // [Serialization]
+     218             :   // --------------------------------------------------------------------------
+     219             : 
+     220             :   ASMJIT_API virtual Error serialize(CodeEmitter* dst);
+     221             : 
+     222             :   // --------------------------------------------------------------------------
+     223             :   // [Members]
+     224             :   // --------------------------------------------------------------------------
+     225             : 
+     226             :   Zone _cbBaseZone;                      //!< Base zone used to allocate nodes and `CBPass`.
+     227             :   Zone _cbDataZone;                      //!< Data zone used to allocate data and names.
+     228             :   Zone _cbPassZone;                      //!< Zone passed to `CBPass::process()`.
+     229             :   ZoneHeap _cbHeap;                      //!< ZoneHeap that uses `_cbBaseZone`.
+     230             : 
+     231             :   ZoneVector<CBPass*> _cbPasses;         //!< Array of `CBPass` objects.
+     232             :   ZoneVector<CBLabel*> _cbLabels;        //!< Maps label indexes to `CBLabel` nodes.
+     233             : 
+     234             :   CBNode* _firstNode;                    //!< First node of the current section.
+     235             :   CBNode* _lastNode;                     //!< Last node of the current section.
+     236             :   CBNode* _cursor;                       //!< Current node (cursor).
+     237             : 
+     238             :   uint32_t _position;                    //!< Flow-id assigned to each new node.
+     239             :   uint32_t _nodeFlags;                   //!< Flags assigned to each new node.
+     240             : };
+     241             : 
+     242             : // ============================================================================
+     243             : // [asmjit::CBPass]
+     244             : // ============================================================================
+     245             : 
+     246             : //! `CodeBuilder` pass used to  code transformations, analysis, and lowering.
+     247             : class ASMJIT_VIRTAPI CBPass {
+     248             : public:
+     249             :   ASMJIT_NONCOPYABLE(CBPass);
+     250             : 
+     251             :   // --------------------------------------------------------------------------
+     252             :   // [Construction / Destruction]
+     253             :   // --------------------------------------------------------------------------
+     254             : 
+     255             :   ASMJIT_API CBPass(const char* name) noexcept;
+     256             :   ASMJIT_API virtual ~CBPass() noexcept;
+     257             : 
+     258             :   // --------------------------------------------------------------------------
+     259             :   // [Interface]
+     260             :   // --------------------------------------------------------------------------
+     261             : 
+     262             :   //! Process the code stored in CodeBuffer `cb`.
+     263             :   //!
+     264             :   //! This is the only function that is called by the `CodeBuilder` to process
+     265             :   //! the code. It passes the CodeBuilder itself (`cb`) and also a zone memory
+     266             :   //! allocator `zone`, which will be reset after the `process()` returns. The
+     267             :   //! allocator should be used for all allocations as it's fast and everything
+     268             :   //! it allocates will be released at once when `process()` returns.
+     269             :   virtual Error process(Zone* zone) noexcept = 0;
+     270             : 
+     271             :   // --------------------------------------------------------------------------
+     272             :   // [Accessors]
+     273             :   // --------------------------------------------------------------------------
+     274             : 
+     275        1948 :   ASMJIT_INLINE const CodeBuilder* cb() const noexcept { return _cb; }
+     276           0 :   ASMJIT_INLINE const char* getName() const noexcept { return _name; }
+     277             : 
+     278             :   // --------------------------------------------------------------------------
+     279             :   // [Members]
+     280             :   // --------------------------------------------------------------------------
+     281             : 
+     282             :   CodeBuilder* _cb;                      //!< CodeBuilder this pass is assigned to.
+     283             :   const char* _name;                     //!< Name of the pass.
+     284             : };
+     285             : 
+     286             : // ============================================================================
+     287             : // [asmjit::CBNode]
+     288             : // ============================================================================
+     289             : 
+     290             : //! Node (CodeBuilder).
+     291             : //!
+     292             : //! Every node represents a building-block used by \ref CodeBuilder. It can be
+     293             : //! instruction, data, label, comment, directive, or any other high-level
+     294             : //! representation that can be transformed to the building blocks mentioned.
+     295             : //! Every class that inherits \ref CodeBuilder can define its own nodes that it
+     296             : //! can lower to basic nodes.
+     297             : class CBNode {
+     298             : public:
+     299             :   ASMJIT_NONCOPYABLE(CBNode)
+     300             : 
+     301             :   // --------------------------------------------------------------------------
+     302             :   // [Type]
+     303             :   // --------------------------------------------------------------------------
+     304             : 
+     305             :   //! Type of \ref CBNode.
+     306             :   ASMJIT_ENUM(NodeType) {
+     307             :     kNodeNone       = 0,                 //!< Invalid node (internal, don't use).
+     308             : 
+     309             :     // [CodeBuilder]
+     310             :     kNodeInst       = 1,                 //!< Node is \ref CBInst or \ref CBJump.
+     311             :     kNodeData       = 2,                 //!< Node is \ref CBData.
+     312             :     kNodeAlign      = 3,                 //!< Node is \ref CBAlign.
+     313             :     kNodeLabel      = 4,                 //!< Node is \ref CBLabel.
+     314             :     kNodeLabelData  = 5,                 //!< Node is \ref CBLabelData.
+     315             :     kNodeConstPool  = 6,                 //!< Node is \ref CBConstPool.
+     316             :     kNodeComment    = 7,                 //!< Node is \ref CBComment.
+     317             :     kNodeSentinel   = 8,                 //!< Node is \ref CBSentinel.
+     318             : 
+     319             :     // [CodeCompiler]
+     320             :     kNodeFunc       = 16,                //!< Node is \ref CCFunc (considered as \ref CBLabel by \ref CodeBuilder).
+     321             :     kNodeFuncExit   = 17,                //!< Node is \ref CCFuncRet.
+     322             :     kNodeFuncCall   = 18,                //!< Node is \ref CCFuncCall.
+     323             :     kNodePushArg    = 19,                //!< Node is \ref CCPushArg.
+     324             :     kNodeHint       = 20,                //!< Node is \ref CCHint.
+     325             : 
+     326             :     // [UserDefined]
+     327             :     kNodeUser       = 32                 //!< First id of a user-defined node.
+     328             :   };
+     329             : 
+     330             :   // --------------------------------------------------------------------------
+     331             :   // [Flags]
+     332             :   // --------------------------------------------------------------------------
+     333             : 
+     334             :   ASMJIT_ENUM(Flags) {
+     335             :     //! The node has been translated by the CodeCompiler.
+     336             :     kFlagIsTranslated = 0x0001,
+     337             :     //! If the node can be safely removed (has no effect).
+     338             :     kFlagIsRemovable = 0x0004,
+     339             :     //! If the node is informative only and can be safely removed.
+     340             :     kFlagIsInformative = 0x0008,
+     341             : 
+     342             :     //! If the `CBInst` is a jump.
+     343             :     kFlagIsJmp = 0x0010,
+     344             :     //! If the `CBInst` is a conditional jump.
+     345             :     kFlagIsJcc = 0x0020,
+     346             : 
+     347             :     //! If the `CBInst` is an unconditional jump or conditional jump that is
+     348             :     //! likely to be taken.
+     349             :     kFlagIsTaken = 0x0040,
+     350             : 
+     351             :     //! If the `CBNode` will return from a function.
+     352             :     //!
+     353             :     //! This flag is used by both `CBSentinel` and `CCFuncRet`.
+     354             :     kFlagIsRet = 0x0080,
+     355             : 
+     356             :     //! Whether the instruction is special.
+     357             :     kFlagIsSpecial = 0x0100,
+     358             : 
+     359             :     //! Whether the instruction is an FPU instruction.
+     360             :     kFlagIsFp = 0x0200
+     361             :   };
+     362             : 
+     363             :   // --------------------------------------------------------------------------
+     364             :   // [Construction / Destruction]
+     365             :   // --------------------------------------------------------------------------
+     366             : 
+     367             :   //! Create a new \ref CBNode - always use \ref CodeBuilder to allocate nodes.
+     368       56154 :   ASMJIT_INLINE CBNode(CodeBuilder* cb, uint32_t type) noexcept {
+     369       56154 :     _prev = nullptr;
+     370       56154 :     _next = nullptr;
+     371       54206 :     _type = static_cast<uint8_t>(type);
+     372        7792 :     _opCount = 0;
+     373       56154 :     _flags = static_cast<uint16_t>(cb->_nodeFlags);
+     374       56154 :     _position = cb->_position;
+     375       56154 :     _inlineComment = nullptr;
+     376       50610 :     _passData = nullptr;
+     377             :   }
+     378             :   //! Destroy the `CBNode` instance (NEVER CALLED).
+     379             :   ASMJIT_INLINE ~CBNode() noexcept {}
+     380             : 
+     381             :   // --------------------------------------------------------------------------
+     382             :   // [Accessors]
+     383             :   // --------------------------------------------------------------------------
+     384             : 
+     385             :   template<typename T>
+     386             :   ASMJIT_INLINE T* as() noexcept { return static_cast<T*>(this); }
+     387             :   template<typename T>
+     388             :   ASMJIT_INLINE const T* as() const noexcept { return static_cast<const T*>(this); }
+     389             : 
+     390             :   //! Get previous node in the compiler stream.
+     391       73404 :   ASMJIT_INLINE CBNode* getPrev() const noexcept { return _prev; }
+     392             :   //! Get next node in the compiler stream.
+     393      144906 :   ASMJIT_INLINE CBNode* getNext() const noexcept { return _next; }
+     394             : 
+     395             :   //! Get the node type, see \ref Type.
+     396      251416 :   ASMJIT_INLINE uint32_t getType() const noexcept { return _type; }
+     397             :   //! Get the node flags.
+     398       31158 :   ASMJIT_INLINE uint32_t getFlags() const noexcept { return _flags; }
+     399             : 
+     400             :   //! Get whether the instruction has flag `flag`.
+     401      171098 :   ASMJIT_INLINE bool hasFlag(uint32_t flag) const noexcept { return (static_cast<uint32_t>(_flags) & flag) != 0; }
+     402             :   //! Set node flags to `flags`.
+     403       31158 :   ASMJIT_INLINE void setFlags(uint32_t flags) noexcept { _flags = static_cast<uint16_t>(flags); }
+     404             :   //! Add instruction `flags`.
+     405        1948 :   ASMJIT_INLINE void orFlags(uint32_t flags) noexcept { _flags |= static_cast<uint16_t>(flags); }
+     406             :   //! And instruction `flags`.
+     407             :   ASMJIT_INLINE void andFlags(uint32_t flags) noexcept { _flags &= static_cast<uint16_t>(flags); }
+     408             :   //! Clear instruction `flags`.
+     409             :   ASMJIT_INLINE void andNotFlags(uint32_t flags) noexcept { _flags &= ~static_cast<uint16_t>(flags); }
+     410             : 
+     411             :   //! Get whether the node has been translated.
+     412             :   ASMJIT_INLINE bool isTranslated() const noexcept { return hasFlag(kFlagIsTranslated); }
+     413             : 
+     414             :   //! Get whether the node is removable if it's in unreachable code block.
+     415             :   ASMJIT_INLINE bool isRemovable() const noexcept { return hasFlag(kFlagIsRemovable); }
+     416             :   //! Get whether the node is informative only (comment, hint).
+     417             :   ASMJIT_INLINE bool isInformative() const noexcept { return hasFlag(kFlagIsInformative); }
+     418             : 
+     419             :   //! Whether the node is `CBLabel`.
+     420           0 :   ASMJIT_INLINE bool isLabel() const noexcept { return _type == kNodeLabel; }
+     421             :   //! Whether the `CBInst` node is an unconditional jump.
+     422             :   ASMJIT_INLINE bool isJmp() const noexcept { return hasFlag(kFlagIsJmp); }
+     423             :   //! Whether the `CBInst` node is a conditional jump.
+     424             :   ASMJIT_INLINE bool isJcc() const noexcept { return hasFlag(kFlagIsJcc); }
+     425             :   //! Whether the `CBInst` node is a conditional/unconditional jump.
+     426             :   ASMJIT_INLINE bool isJmpOrJcc() const noexcept { return hasFlag(kFlagIsJmp | kFlagIsJcc); }
+     427             :   //! Whether the `CBInst` node is a return.
+     428             :   ASMJIT_INLINE bool isRet() const noexcept { return hasFlag(kFlagIsRet); }
+     429             : 
+     430             :   //! Get whether the node is `CBInst` and the instruction is special.
+     431             :   ASMJIT_INLINE bool isSpecial() const noexcept { return hasFlag(kFlagIsSpecial); }
+     432             :   //! Get whether the node is `CBInst` and the instruction uses x87-FPU.
+     433             :   ASMJIT_INLINE bool isFp() const noexcept { return hasFlag(kFlagIsFp); }
+     434             : 
+     435           0 :   ASMJIT_INLINE bool hasPosition() const noexcept { return _position != 0; }
+     436             :   //! Get flow index.
+     437           0 :   ASMJIT_INLINE uint32_t getPosition() const noexcept { return _position; }
+     438             :   //! Set flow index.
+     439       40598 :   ASMJIT_INLINE void setPosition(uint32_t position) noexcept { _position = position; }
+     440             : 
+     441             :   //! Get if the node has an inline comment.
+     442           0 :   ASMJIT_INLINE bool hasInlineComment() const noexcept { return _inlineComment != nullptr; }
+     443             :   //! Get an inline comment string.
+     444       56154 :   ASMJIT_INLINE const char* getInlineComment() const noexcept { return _inlineComment; }
+     445             :   //! Set an inline comment string to `s`.
+     446           0 :   ASMJIT_INLINE void setInlineComment(const char* s) noexcept { _inlineComment = s; }
+     447             :   //! Set an inline comment string to null.
+     448             :   ASMJIT_INLINE void resetInlineComment() noexcept { _inlineComment = nullptr; }
+     449             : 
+     450             :   //! Get if the node has associated work-data.
+     451      112054 :   ASMJIT_INLINE bool hasPassData() const noexcept { return _passData != nullptr; }
+     452             :   //! Get work-data - data used during processing & transformations.
+     453             :   template<typename T>
+     454      330596 :   ASMJIT_INLINE T* getPassData() const noexcept { return (T*)_passData; }
+     455             :   //! Set work-data to `data`.
+     456             :   template<typename T>
+     457       40598 :   ASMJIT_INLINE void setPassData(T* data) noexcept { _passData = (void*)data; }
+     458             :   //! Reset work-data to null.
+     459             :   ASMJIT_INLINE void resetPassData() noexcept { _passData = nullptr; }
+     460             : 
+     461             :   // --------------------------------------------------------------------------
+     462             :   // [Members]
+     463             :   // --------------------------------------------------------------------------
+     464             : 
+     465             :   CBNode* _prev;                         //!< Previous node.
+     466             :   CBNode* _next;                         //!< Next node.
+     467             : 
+     468             :   uint8_t _type;                         //!< Node type, see \ref NodeType.
+     469             :   uint8_t _opCount;                      //!< Count of operands or zero.
+     470             :   uint16_t _flags;                       //!< Flags, different meaning for every type of the node.
+     471             :   uint32_t _position;                    //!< Flow index.
+     472             : 
+     473             :   const char* _inlineComment;            //!< Inline comment or null if not used.
+     474             :   void* _passData;                       //!< Data used exclusively by the current `CBPass`.
+     475             : };
+     476             : 
+     477             : // ============================================================================
+     478             : // [asmjit::CBInst]
+     479             : // ============================================================================
+     480             : 
+     481             : //! Instruction (CodeBuilder).
+     482             : //!
+     483             : //! Wraps an instruction with its options and operands.
+     484             : class CBInst : public CBNode {
+     485             : public:
+     486             :   ASMJIT_NONCOPYABLE(CBInst)
+     487             : 
+     488             :   // --------------------------------------------------------------------------
+     489             :   // [Construction / Destruction]
+     490             :   // --------------------------------------------------------------------------
+     491             : 
+     492             :   //! Create a new `CBInst` instance.
+     493             :   ASMJIT_INLINE CBInst(CodeBuilder* cb, uint32_t instId, uint32_t options, Operand* opArray, uint32_t opCount) noexcept
+     494       48362 :     : CBNode(cb, kNodeInst) {
+     495             : 
+     496             :     orFlags(kFlagIsRemovable);
+     497       48362 :     _instDetail.instId = static_cast<uint16_t>(instId);
+     498       48362 :     _instDetail.options = options;
+     499             : 
+     500       48362 :     _opCount = static_cast<uint8_t>(opCount);
+     501       48362 :     _opArray = opArray;
+     502             : 
+     503             :     _updateMemOp();
+     504             :   }
+     505             : 
+     506             :   //! Destroy the `CBInst` instance (NEVER CALLED).
+     507             :   ASMJIT_INLINE ~CBInst() noexcept {}
+     508             : 
+     509             :   // --------------------------------------------------------------------------
+     510             :   // [Accessors]
+     511             :   // --------------------------------------------------------------------------
+     512             : 
+     513           0 :   ASMJIT_INLINE Inst::Detail& getInstDetail() noexcept { return _instDetail; }
+     514           0 :   ASMJIT_INLINE const Inst::Detail& getInstDetail() const noexcept { return _instDetail; }
+     515             : 
+     516             :   //! Get the instruction id, see \ref Inst::Id.
+     517       79520 :   ASMJIT_INLINE uint32_t getInstId() const noexcept { return _instDetail.instId; }
+     518             :   //! Set the instruction id to `instId`, see \ref Inst::Id.
+     519             :   ASMJIT_INLINE void setInstId(uint32_t instId) noexcept { _instDetail.instId = instId; }
+     520             : 
+     521             :   //! Whether the instruction is either a jump or a conditional jump likely to be taken.
+     522             :   ASMJIT_INLINE bool isTaken() const noexcept { return hasFlag(kFlagIsTaken); }
+     523             : 
+     524             :   //! Get emit options.
+     525       79254 :   ASMJIT_INLINE uint32_t getOptions() const noexcept { return _instDetail.options; }
+     526             :   //! Set emit options.
+     527           0 :   ASMJIT_INLINE void setOptions(uint32_t options) noexcept { _instDetail.options = options; }
+     528             :   //! Add emit options.
+     529             :   ASMJIT_INLINE void addOptions(uint32_t options) noexcept { _instDetail.options |= options; }
+     530             :   //! Mask emit options.
+     531             :   ASMJIT_INLINE void andOptions(uint32_t options) noexcept { _instDetail.options &= options; }
+     532             :   //! Clear emit options.
+     533           0 :   ASMJIT_INLINE void delOptions(uint32_t options) noexcept { _instDetail.options &= ~options; }
+     534             : 
+     535             :   //! Get if the node has an extra register operand.
+     536             :   ASMJIT_INLINE bool hasExtraReg() const noexcept { return _instDetail.hasExtraReg(); }
+     537             :   //! Get extra register operand.
+     538             :   ASMJIT_INLINE RegOnly& getExtraReg() noexcept { return _instDetail.extraReg; }
+     539             :   //! \overload
+     540             :   ASMJIT_INLINE const RegOnly& getExtraReg() const noexcept { return _instDetail.extraReg; }
+     541             :   //! Set extra register operand to `reg`.
+     542             :   ASMJIT_INLINE void setExtraReg(const Reg& reg) noexcept { _instDetail.extraReg.init(reg); }
+     543             :   //! Set extra register operand to `reg`.
+     544             :   ASMJIT_INLINE void setExtraReg(const RegOnly& reg) noexcept { _instDetail.extraReg.init(reg); }
+     545             :   //! Reset extra register operand.
+     546             :   ASMJIT_INLINE void resetExtraReg() noexcept { _instDetail.extraReg.reset(); }
+     547             : 
+     548             :   //! Get operands count.
+     549       48362 :   ASMJIT_INLINE uint32_t getOpCount() const noexcept { return _opCount; }
+     550             :   //! Get operands list.
+     551      112326 :   ASMJIT_INLINE Operand* getOpArray() noexcept { return _opArray; }
+     552             :   //! \overload
+     553           0 :   ASMJIT_INLINE const Operand* getOpArray() const noexcept { return _opArray; }
+     554             : 
+     555             :   //! Get whether the instruction contains a memory operand.
+     556       40910 :   ASMJIT_INLINE bool hasMemOp() const noexcept { return _memOpIndex != 0xFF; }
+     557             :   //! Get memory operand.
+     558             :   //!
+     559             :   //! NOTE: Can only be called if the instruction has such operand,
+     560             :   //! see `hasMemOp()`.
+     561             :   ASMJIT_INLINE Mem* getMemOp() const noexcept {
+     562             :     ASMJIT_ASSERT(hasMemOp());
+     563             :     return static_cast<Mem*>(&_opArray[_memOpIndex]);
+     564             :   }
+     565             :   //! \overload
+     566             :   template<typename T>
+     567             :   ASMJIT_INLINE T* getMemOp() const noexcept {
+     568             :     ASMJIT_ASSERT(hasMemOp());
+     569       14528 :     return static_cast<T*>(&_opArray[_memOpIndex]);
+     570             :   }
+     571             : 
+     572             :   //! Set memory operand index, `0xFF` means no memory operand.
+     573       54462 :   ASMJIT_INLINE void setMemOpIndex(uint32_t index) noexcept { _memOpIndex = static_cast<uint8_t>(index); }
+     574             :   //! Reset memory operand index to `0xFF` (no operand).
+     575             :   ASMJIT_INLINE void resetMemOpIndex() noexcept { _memOpIndex = 0xFF; }
+     576             : 
+     577             :   // --------------------------------------------------------------------------
+     578             :   // [Utils]
+     579             :   // --------------------------------------------------------------------------
+     580             : 
+     581             :   ASMJIT_INLINE void _updateMemOp() noexcept {
+     582             :     Operand* opArray = getOpArray();
+     583             :     uint32_t opCount = getOpCount();
+     584             : 
+     585             :     uint32_t i;
+     586      118624 :     for (i = 0; i < opCount; i++)
+     587       84790 :       if (opArray[i].isMem())
+     588       14528 :         goto Update;
+     589             :     i = 0xFF;
+     590             : 
+     591       48362 : Update:
+     592             :     setMemOpIndex(i);
+     593             :   }
+     594             : 
+     595             :   // --------------------------------------------------------------------------
+     596             :   // [Members]
+     597             :   // --------------------------------------------------------------------------
+     598             : 
+     599             :   Inst::Detail _instDetail;              //!< Instruction id, options, and extra register.
+     600             :   uint8_t _memOpIndex;                   //!< \internal
+     601             :   uint8_t _reserved[7];                  //!< \internal
+     602             :   Operand* _opArray;                     //!< Instruction operands.
+     603             : };
+     604             : 
+     605             : // ============================================================================
+     606             : // [asmjit::CBInstEx]
+     607             : // ============================================================================
+     608             : 
+     609             : struct CBInstEx : public CBInst {
+     610             :   Operand _op4;
+     611             :   Operand _op5;
+     612             : };
+     613             : 
+     614             : // ============================================================================
+     615             : // [asmjit::CBJump]
+     616             : // ============================================================================
+     617             : 
+     618             : //! Asm jump (conditional or direct).
+     619             : //!
+     620             : //! Extension of `CBInst` node, which stores more information about the jump.
+     621             : class CBJump : public CBInst {
+     622             : public:
+     623             :   ASMJIT_NONCOPYABLE(CBJump)
+     624             : 
+     625             :   // --------------------------------------------------------------------------
+     626             :   // [Construction / Destruction]
+     627             :   // --------------------------------------------------------------------------
+     628             : 
+     629             :   ASMJIT_INLINE CBJump(CodeBuilder* cb, uint32_t instId, uint32_t options, Operand* opArray, uint32_t opCount) noexcept
+     630           0 :     : CBInst(cb, instId, options, opArray, opCount),
+     631           0 :       _target(nullptr),
+     632           0 :       _jumpNext(nullptr) {}
+     633             :   ASMJIT_INLINE ~CBJump() noexcept {}
+     634             : 
+     635             :   // --------------------------------------------------------------------------
+     636             :   // [Accessors]
+     637             :   // --------------------------------------------------------------------------
+     638             : 
+     639           0 :   ASMJIT_INLINE CBLabel* getTarget() const noexcept { return _target; }
+     640           0 :   ASMJIT_INLINE CBJump* getJumpNext() const noexcept { return _jumpNext; }
+     641             : 
+     642             :   // --------------------------------------------------------------------------
+     643             :   // [Members]
+     644             :   // --------------------------------------------------------------------------
+     645             : 
+     646             :   CBLabel* _target;                     //!< Target node.
+     647             :   CBJump* _jumpNext;                    //!< Next jump to the same target in a single linked-list.
+     648             : };
+     649             : 
+     650             : // ============================================================================
+     651             : // [asmjit::CBData]
+     652             : // ============================================================================
+     653             : 
+     654             : //! Asm data (CodeBuilder).
+     655             : //!
+     656             : //! Wraps `.data` directive. The node contains data that will be placed at the
+     657             : //! node's position in the assembler stream. The data is considered to be RAW;
+     658             : //! no analysis nor byte-order conversion is performed on RAW data.
+     659             : class CBData : public CBNode {
+     660             : public:
+     661             :   ASMJIT_NONCOPYABLE(CBData)
+     662             :   enum { kInlineBufferSize = static_cast<int>(64 - sizeof(CBNode) - 4) };
+     663             : 
+     664             :   // --------------------------------------------------------------------------
+     665             :   // [Construction / Destruction]
+     666             :   // --------------------------------------------------------------------------
+     667             : 
+     668             :   //! Create a new `CBData` instance.
+     669           0 :   ASMJIT_INLINE CBData(CodeBuilder* cb, void* data, uint32_t size) noexcept : CBNode(cb, kNodeData) {
+     670           0 :     if (size <= kInlineBufferSize) {
+     671           0 :       if (data) ::memcpy(_buf, data, size);
+     672             :     }
+     673             :     else {
+     674           0 :       _externalPtr = static_cast<uint8_t*>(data);
+     675             :     }
+     676           0 :     _size = size;
+     677             :   }
+     678             : 
+     679             :   //! Destroy the `CBData` instance (NEVER CALLED).
+     680             :   ASMJIT_INLINE ~CBData() noexcept {}
+     681             : 
+     682             :   // --------------------------------------------------------------------------
+     683             :   // [Accessors]
+     684             :   // --------------------------------------------------------------------------
+     685             : 
+     686             :   //! Get size of the data.
+     687           0 :   uint32_t getSize() const noexcept { return _size; }
+     688             :   //! Get pointer to the data.
+     689           0 :   uint8_t* getData() const noexcept { return _size <= kInlineBufferSize ? const_cast<uint8_t*>(_buf) : _externalPtr; }
+     690             : 
+     691             :   // --------------------------------------------------------------------------
+     692             :   // [Members]
+     693             :   // --------------------------------------------------------------------------
+     694             : 
+     695             :   union {
+     696             :     struct {
+     697             :       uint8_t _buf[kInlineBufferSize];   //!< Embedded data buffer.
+     698             :       uint32_t _size;                    //!< Size of the data.
+     699             :     };
+     700             :     struct {
+     701             :       uint8_t* _externalPtr;             //!< Pointer to external data.
+     702             :     };
+     703             :   };
+     704             : };
+     705             : 
+     706             : // ============================================================================
+     707             : // [asmjit::CBAlign]
+     708             : // ============================================================================
+     709             : 
+     710             : //! Align directive (CodeBuilder).
+     711             : //!
+     712             : //! Wraps `.align` directive.
+     713             : class CBAlign : public CBNode {
+     714             : public:
+     715             :   ASMJIT_NONCOPYABLE(CBAlign)
+     716             : 
+     717             :   // --------------------------------------------------------------------------
+     718             :   // [Construction / Destruction]
+     719             :   // --------------------------------------------------------------------------
+     720             : 
+     721             :   //! Create a new `CBAlign` instance.
+     722             :   ASMJIT_INLINE CBAlign(CodeBuilder* cb, uint32_t mode, uint32_t alignment) noexcept
+     723           0 :     : CBNode(cb, kNodeAlign),
+     724           0 :       _mode(mode),
+     725           0 :       _alignment(alignment) {}
+     726             :   //! Destroy the `CBAlign` instance (NEVER CALLED).
+     727             :   ASMJIT_INLINE ~CBAlign() noexcept {}
+     728             : 
+     729             :   // --------------------------------------------------------------------------
+     730             :   // [Accessors]
+     731             :   // --------------------------------------------------------------------------
+     732             : 
+     733             :   //! Get align mode.
+     734           0 :   ASMJIT_INLINE uint32_t getMode() const noexcept { return _mode; }
+     735             :   //! Set align mode.
+     736             :   ASMJIT_INLINE void setMode(uint32_t mode) noexcept { _mode = mode; }
+     737             : 
+     738             :   //! Get align offset in bytes.
+     739           0 :   ASMJIT_INLINE uint32_t getAlignment() const noexcept { return _alignment; }
+     740             :   //! Set align offset in bytes to `offset`.
+     741             :   ASMJIT_INLINE void setAlignment(uint32_t alignment) noexcept { _alignment = alignment; }
+     742             : 
+     743             :   // --------------------------------------------------------------------------
+     744             :   // [Members]
+     745             :   // --------------------------------------------------------------------------
+     746             : 
+     747             :   uint32_t _mode;                        //!< Align mode, see \ref AlignMode.
+     748             :   uint32_t _alignment;                   //!< Alignment (in bytes).
+     749             : };
+     750             : 
+     751             : // ============================================================================
+     752             : // [asmjit::CBLabel]
+     753             : // ============================================================================
+     754             : 
+     755             : //! Label (CodeBuilder).
+     756             : class CBLabel : public CBNode {
+     757             : public:
+     758             :   ASMJIT_NONCOPYABLE(CBLabel)
+     759             : 
+     760             :   // --------------------------------------------------------------------------
+     761             :   // [Construction / Destruction]
+     762             :   // --------------------------------------------------------------------------
+     763             : 
+     764             :   //! Create a new `CBLabel` instance.
+     765             :   ASMJIT_INLINE CBLabel(CodeBuilder* cb, uint32_t id = kInvalidValue) noexcept
+     766        3896 :     : CBNode(cb, kNodeLabel),
+     767        3896 :       _id(id),
+     768        3896 :       _numRefs(0),
+     769        3896 :       _from(nullptr) {}
+     770             :   //! Destroy the `CBLabel` instance (NEVER CALLED).
+     771             :   ASMJIT_INLINE ~CBLabel() noexcept {}
+     772             : 
+     773             :   // --------------------------------------------------------------------------
+     774             :   // [Accessors]
+     775             :   // --------------------------------------------------------------------------
+     776             : 
+     777             :   //! Get the label id.
+     778           0 :   ASMJIT_INLINE uint32_t getId() const noexcept { return _id; }
+     779             :   //! Get the label as `Label` operand.
+     780        3896 :   ASMJIT_INLINE Label getLabel() const noexcept { return Label(_id); }
+     781             : 
+     782             :   //! Get first jmp instruction.
+     783           0 :   ASMJIT_INLINE CBJump* getFrom() const noexcept { return _from; }
+     784             : 
+     785             :   //! Get number of jumps to this target.
+     786           0 :   ASMJIT_INLINE uint32_t getNumRefs() const noexcept { return _numRefs; }
+     787             :   //! Set number of jumps to this target.
+     788             :   ASMJIT_INLINE void setNumRefs(uint32_t i) noexcept { _numRefs = i; }
+     789             : 
+     790             :   //! Add number of jumps to this target.
+     791           0 :   ASMJIT_INLINE void addNumRefs(uint32_t i = 1) noexcept { _numRefs += i; }
+     792             :   //! Subtract number of jumps to this target.
+     793           0 :   ASMJIT_INLINE void subNumRefs(uint32_t i = 1) noexcept { _numRefs -= i; }
+     794             : 
+     795             :   // --------------------------------------------------------------------------
+     796             :   // [Members]
+     797             :   // --------------------------------------------------------------------------
+     798             : 
+     799             :   uint32_t _id;                          //!< Label id.
+     800             :   uint32_t _numRefs;                     //!< Count of jumps here.
+     801             :   CBJump* _from;                         //!< Linked-list of nodes that can jump here.
+     802             : };
+     803             : 
+     804             : // ============================================================================
+     805             : // [asmjit::CBLabelData]
+     806             : // ============================================================================
+     807             : 
+     808             : class CBLabelData : public CBNode {
+     809             : public:
+     810             :   ASMJIT_NONCOPYABLE(CBLabelData)
+     811             : 
+     812             :   // --------------------------------------------------------------------------
+     813             :   // [Construction / Destruction]
+     814             :   // --------------------------------------------------------------------------
+     815             : 
+     816             :   //! Create a new `CBLabelData` instance.
+     817             :   ASMJIT_INLINE CBLabelData(CodeBuilder* cb, uint32_t id = kInvalidValue) noexcept
+     818           0 :     : CBNode(cb, kNodeLabelData),
+     819           0 :       _id(id) {}
+     820             : 
+     821             :   //! Destroy the `CBLabelData` instance (NEVER CALLED).
+     822             :   ASMJIT_INLINE ~CBLabelData() noexcept {}
+     823             : 
+     824             :   // --------------------------------------------------------------------------
+     825             :   // [Interface]
+     826             :   // --------------------------------------------------------------------------
+     827             : 
+     828             :   //! Get the label id.
+     829             :   ASMJIT_INLINE uint32_t getId() const noexcept { return _id; }
+     830             :   //! Get the label as `Label` operand.
+     831           0 :   ASMJIT_INLINE Label getLabel() const noexcept { return Label(_id); }
+     832             : 
+     833             :   // --------------------------------------------------------------------------
+     834             :   // [Members]
+     835             :   // --------------------------------------------------------------------------
+     836             : 
+     837             :   uint32_t _id;
+     838             : };
+     839             : 
+     840             : // ============================================================================
+     841             : // [asmjit::CBConstPool]
+     842             : // ============================================================================
+     843             : 
+     844             : class CBConstPool : public CBLabel {
+     845             : public:
+     846             :   ASMJIT_NONCOPYABLE(CBConstPool)
+     847             : 
+     848             :   // --------------------------------------------------------------------------
+     849             :   // [Construction / Destruction]
+     850             :   // --------------------------------------------------------------------------
+     851             : 
+     852             :   //! Create a new `CBConstPool` instance.
+     853             :   ASMJIT_INLINE CBConstPool(CodeBuilder* cb, uint32_t id = kInvalidValue) noexcept
+     854           0 :     : CBLabel(cb, id),
+     855           0 :       _constPool(&cb->_cbBaseZone) { _type = kNodeConstPool; }
+     856             : 
+     857             :   //! Destroy the `CBConstPool` instance (NEVER CALLED).
+     858             :   ASMJIT_INLINE ~CBConstPool() noexcept {}
+     859             : 
+     860             :   // --------------------------------------------------------------------------
+     861             :   // [Interface]
+     862             :   // --------------------------------------------------------------------------
+     863             : 
+     864           0 :   ASMJIT_INLINE ConstPool& getConstPool() noexcept { return _constPool; }
+     865             :   ASMJIT_INLINE const ConstPool& getConstPool() const noexcept { return _constPool; }
+     866             : 
+     867             :   //! Get whether the constant-pool is empty.
+     868             :   ASMJIT_INLINE bool isEmpty() const noexcept { return _constPool.isEmpty(); }
+     869             :   //! Get the size of the constant-pool in bytes.
+     870             :   ASMJIT_INLINE size_t getSize() const noexcept { return _constPool.getSize(); }
+     871             :   //! Get minimum alignment.
+     872             :   ASMJIT_INLINE size_t getAlignment() const noexcept { return _constPool.getAlignment(); }
+     873             : 
+     874             :   //! See \ref ConstPool::add().
+     875             :   ASMJIT_INLINE Error add(const void* data, size_t size, size_t& dstOffset) noexcept {
+     876           0 :     return _constPool.add(data, size, dstOffset);
+     877             :   }
+     878             : 
+     879             :   // --------------------------------------------------------------------------
+     880             :   // [Members]
+     881             :   // --------------------------------------------------------------------------
+     882             : 
+     883             :   ConstPool _constPool;
+     884             : };
+     885             : 
+     886             : // ============================================================================
+     887             : // [asmjit::CBComment]
+     888             : // ============================================================================
+     889             : 
+     890             : //! Comment (CodeBuilder).
+     891             : class CBComment : public CBNode {
+     892             : public:
+     893             :   ASMJIT_NONCOPYABLE(CBComment)
+     894             : 
+     895             :   // --------------------------------------------------------------------------
+     896             :   // [Construction / Destruction]
+     897             :   // --------------------------------------------------------------------------
+     898             : 
+     899             :   //! Create a new `CBComment` instance.
+     900             :   ASMJIT_INLINE CBComment(CodeBuilder* cb, const char* comment) noexcept : CBNode(cb, kNodeComment) {
+     901             :     orFlags(kFlagIsRemovable | kFlagIsInformative);
+     902           0 :     _inlineComment = comment;
+     903             :   }
+     904             : 
+     905             :   //! Destroy the `CBComment` instance (NEVER CALLED).
+     906             :   ASMJIT_INLINE ~CBComment() noexcept {}
+     907             : };
+     908             : 
+     909             : // ============================================================================
+     910             : // [asmjit::CBSentinel]
+     911             : // ============================================================================
+     912             : 
+     913             : //! Sentinel (CodeBuilder).
+     914             : //!
+     915             : //! Sentinel is a marker that is completely ignored by the code builder. It's
+     916             : //! used to remember a position in a code as it never gets removed by any pass.
+     917             : class CBSentinel : public CBNode {
+     918             : public:
+     919             :   ASMJIT_NONCOPYABLE(CBSentinel)
+     920             : 
+     921             :   // --------------------------------------------------------------------------
+     922             :   // [Construction / Destruction]
+     923             :   // --------------------------------------------------------------------------
+     924             : 
+     925             :   //! Create a new `CBSentinel` instance.
+     926             :   ASMJIT_INLINE CBSentinel(CodeBuilder* cb) noexcept : CBNode(cb, kNodeSentinel) {}
+     927             :   //! Destroy the `CBSentinel` instance (NEVER CALLED).
+     928             :   ASMJIT_INLINE ~CBSentinel() noexcept {}
+     929             : };
+     930             : 
+     931             : //! \}
+     932             : 
+     933             : } // asmjit namespace
+     934             : } // namespace PLMD
+     935             : 
+     936             : // [Api-End]
+     937             : #include "./asmjit_apiend.h"
+     938             : 
+     939             : // [Guard]
+     940             : #endif // !ASMJIT_DISABLE_BUILDER
+     941             : #endif // _ASMJIT_BASE_CODEBUILDER_H
+     942             : #pragma GCC diagnostic pop
+     943             : #endif // __PLUMED_HAS_ASMJIT
+     944             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.cpp.func-sort-c.html b/coverage-libs/asmjit/codecompiler.cpp.func-sort-c.html new file mode 100644 index 000000000000..cafb0bb55b94 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.cpp.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8923937.2 %
Date:2024-02-22 21:58:47Functions:153641.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12CodeCompiler11newHintNodeERNS0_3RegEjj0
_ZN4PLMD6asmjit12CodeCompiler11setPriorityERNS0_3RegEj0
_ZN4PLMD6asmjit12CodeCompiler14setSaveOnUnuseERNS0_3RegEb0
_ZN4PLMD6asmjit12CodeCompiler4saveERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5_hintERNS0_3RegEjj0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegERKS2_0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegEj0
_ZN4PLMD6asmjit12CodeCompiler5spillERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5unuseERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler6renameERNS0_3RegEPKcz0
_ZN4PLMD6asmjit12CodeCompiler6setArgEjRKNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKc0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12CodeCompiler9_newConstERNS0_3MemEjPKvm0
_ZN4PLMD6asmjit12CodeCompiler9_newStackERNS0_3MemEjjPKc0
_ZN4PLMD6asmjit12CodeCompilerD0Ev0
_ZNK4PLMD6asmjit12CodeCompiler11getPriorityERNS0_3RegE0
_ZNK4PLMD6asmjit12CodeCompiler14getSaveOnUnuseERNS0_3RegE0
_ZN4PLMD6asmjit10CCFuncCall7_setRetEjRKNS0_8Operand_E1648
_ZN4PLMD6asmjit12CodeCompiler7addCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1648
_ZN4PLMD6asmjit12CodeCompiler7newCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1648
_ZN4PLMD6asmjit10CCFuncCall7_setArgEjRKNS0_8Operand_E1870
_ZN4PLMD6asmjit12CodeCompiler6addRetERKNS0_8Operand_ES4_1948
_ZN4PLMD6asmjit12CodeCompiler6newRetERKNS0_8Operand_ES4_1948
_ZN4PLMD6asmjit12CodeCompiler7addFuncEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit12CodeCompiler7addFuncERKNS0_13FuncSignatureE1948
_ZN4PLMD6asmjit12CodeCompiler7endFuncEv1948
_ZN4PLMD6asmjit12CodeCompiler7newFuncERKNS0_13FuncSignatureE1948
_ZN4PLMD6asmjit12CodeCompiler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12CodeCompilerC2Ev1948
_ZN4PLMD6asmjit12CodeCompilerD2Ev1948
_ZN4PLMD6asmjit12CodeCompiler10newVirtRegEjjPKc23788
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKc23788
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.cpp.func.html b/coverage-libs/asmjit/codecompiler.cpp.func.html new file mode 100644 index 000000000000..5e688b3ed5fa --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.cpp.func.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8923937.2 %
Date:2024-02-22 21:58:47Functions:153641.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CCFuncCall7_setArgEjRKNS0_8Operand_E1870
_ZN4PLMD6asmjit10CCFuncCall7_setRetEjRKNS0_8Operand_E1648
_ZN4PLMD6asmjit12CodeCompiler10newVirtRegEjjPKc23788
_ZN4PLMD6asmjit12CodeCompiler11newHintNodeERNS0_3RegEjj0
_ZN4PLMD6asmjit12CodeCompiler11setPriorityERNS0_3RegEj0
_ZN4PLMD6asmjit12CodeCompiler14setSaveOnUnuseERNS0_3RegEb0
_ZN4PLMD6asmjit12CodeCompiler4saveERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5_hintERNS0_3RegEjj0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegERKS2_0
_ZN4PLMD6asmjit12CodeCompiler5allocERNS0_3RegEj0
_ZN4PLMD6asmjit12CodeCompiler5spillERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler5unuseERNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler6addRetERKNS0_8Operand_ES4_1948
_ZN4PLMD6asmjit12CodeCompiler6newRetERKNS0_8Operand_ES4_1948
_ZN4PLMD6asmjit12CodeCompiler6renameERNS0_3RegEPKcz0
_ZN4PLMD6asmjit12CodeCompiler6setArgEjRKNS0_3RegE0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKc0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegERKS2_PKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKc23788
_ZN4PLMD6asmjit12CodeCompiler7_newRegERNS0_3RegEjPKcP13__va_list_tag0
_ZN4PLMD6asmjit12CodeCompiler7addCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1648
_ZN4PLMD6asmjit12CodeCompiler7addFuncEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit12CodeCompiler7addFuncERKNS0_13FuncSignatureE1948
_ZN4PLMD6asmjit12CodeCompiler7endFuncEv1948
_ZN4PLMD6asmjit12CodeCompiler7newCallEjRKNS0_8Operand_ERKNS0_13FuncSignatureE1648
_ZN4PLMD6asmjit12CodeCompiler7newFuncERKNS0_13FuncSignatureE1948
_ZN4PLMD6asmjit12CodeCompiler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12CodeCompiler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12CodeCompiler9_newConstERNS0_3MemEjPKvm0
_ZN4PLMD6asmjit12CodeCompiler9_newStackERNS0_3MemEjjPKc0
_ZN4PLMD6asmjit12CodeCompilerC2Ev1948
_ZN4PLMD6asmjit12CodeCompilerD0Ev0
_ZN4PLMD6asmjit12CodeCompilerD2Ev1948
_ZNK4PLMD6asmjit12CodeCompiler11getPriorityERNS0_3RegE0
_ZNK4PLMD6asmjit12CodeCompiler14getSaveOnUnuseERNS0_3RegE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.cpp.gcov.html b/coverage-libs/asmjit/codecompiler.cpp.gcov.html new file mode 100644 index 000000000000..b2edfccc732f --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.cpp.gcov.html @@ -0,0 +1,676 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8923937.2 %
Date:2024-02-22 21:58:47Functions:153641.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Guard]
+      33             : #include "./asmjit_build.h"
+      34             : #if !defined(ASMJIT_DISABLE_COMPILER)
+      35             : 
+      36             : // [Dependencies]
+      37             : #include "./assembler.h"
+      38             : #include "./codecompiler.h"
+      39             : #include "./cpuinfo.h"
+      40             : #include "./logging.h"
+      41             : #include "./regalloc_p.h"
+      42             : #include "./utils.h"
+      43             : #include <stdarg.h>
+      44             : 
+      45             : // [Api-Begin]
+      46             : #include "./asmjit_apibegin.h"
+      47             : 
+      48             : namespace PLMD {
+      49             : namespace asmjit {
+      50             : 
+      51             : // ============================================================================
+      52             : // [Constants]
+      53             : // ============================================================================
+      54             : 
+      55             : static const char noName[1] = { '\0' };
+      56             : 
+      57             : // ============================================================================
+      58             : // [asmjit::CCFuncCall - Arg / Ret]
+      59             : // ============================================================================
+      60             : 
+      61        1870 : bool CCFuncCall::_setArg(uint32_t i, const Operand_& op) noexcept {
+      62        1870 :   if ((i & ~kFuncArgHi) >= _funcDetail.getArgCount())
+      63             :     return false;
+      64             : 
+      65        1870 :   _args[i] = op;
+      66        1870 :   return true;
+      67             : }
+      68             : 
+      69        1648 : bool CCFuncCall::_setRet(uint32_t i, const Operand_& op) noexcept {
+      70        1648 :   if (i >= 2)
+      71             :     return false;
+      72             : 
+      73        1648 :   _ret[i] = op;
+      74        1648 :   return true;
+      75             : }
+      76             : 
+      77             : // ============================================================================
+      78             : // [asmjit::CodeCompiler - Construction / Destruction]
+      79             : // ============================================================================
+      80             : 
+      81        1948 : CodeCompiler::CodeCompiler() noexcept
+      82             :   : CodeBuilder(),
+      83        1948 :     _func(nullptr),
+      84        1948 :     _vRegZone(4096 - Zone::kZoneOverhead),
+      85             :     _vRegArray(),
+      86        1948 :     _localConstPool(nullptr),
+      87        1948 :     _globalConstPool(nullptr) {
+      88             : 
+      89        1948 :   _type = kTypeCompiler;
+      90        1948 : }
+      91        1948 : CodeCompiler::~CodeCompiler() noexcept {}
+      92             : 
+      93             : // ============================================================================
+      94             : // [asmjit::CodeCompiler - Events]
+      95             : // ============================================================================
+      96             : 
+      97        1948 : Error CodeCompiler::onAttach(CodeHolder* code) noexcept {
+      98        1948 :   return Base::onAttach(code);
+      99             : }
+     100             : 
+     101           0 : Error CodeCompiler::onDetach(CodeHolder* code) noexcept {
+     102           0 :   _func = nullptr;
+     103             : 
+     104           0 :   _localConstPool = nullptr;
+     105           0 :   _globalConstPool = nullptr;
+     106             : 
+     107             :   _vRegArray.reset();
+     108           0 :   _vRegZone.reset(false);
+     109             : 
+     110           0 :   return Base::onDetach(code);
+     111             : }
+     112             : 
+     113             : // ============================================================================
+     114             : // [asmjit::CodeCompiler - Node-Factory]
+     115             : // ============================================================================
+     116             : 
+     117           0 : CCHint* CodeCompiler::newHintNode(Reg& r, uint32_t hint, uint32_t value) noexcept {
+     118           0 :   if (!r.isVirtReg()) return nullptr;
+     119             : 
+     120             :   VirtReg* vr = getVirtReg(r);
+     121           0 :   return newNodeT<CCHint>(vr, hint, value);
+     122             : }
+     123             : 
+     124             : // ============================================================================
+     125             : // [asmjit::CodeCompiler - Func]
+     126             : // ============================================================================
+     127             : 
+     128        1948 : CCFunc* CodeCompiler::newFunc(const FuncSignature& sign) noexcept {
+     129             :   Error err;
+     130             : 
+     131             :   CCFunc* func = newNodeT<CCFunc>();
+     132        1948 :   if (!func) goto _NoMemory;
+     133             : 
+     134        1948 :   err = registerLabelNode(func);
+     135        1948 :   if (ASMJIT_UNLIKELY(err)) {
+     136             :     // TODO: Calls setLastError, maybe rethink noexcept?
+     137           0 :     setLastError(err);
+     138           0 :     return nullptr;
+     139             :   }
+     140             : 
+     141             :   // Create helper nodes.
+     142        1948 :   func->_exitNode = newLabelNode();
+     143        1948 :   func->_end = newNodeT<CBSentinel>();
+     144             : 
+     145        1948 :   if (!func->_exitNode || !func->_end)
+     146           0 :     goto _NoMemory;
+     147             : 
+     148             :   // Function prototype.
+     149        1948 :   err = func->getDetail().init(sign);
+     150        1948 :   if (err != kErrorOk) {
+     151           0 :     setLastError(err);
+     152           0 :     return nullptr;
+     153             :   }
+     154             : 
+     155             :   // If the CodeInfo guarantees higher alignment honor it.
+     156        1948 :   if (_codeInfo.getStackAlignment() > func->_funcDetail._callConv.getNaturalStackAlignment())
+     157             :     func->_funcDetail._callConv.setNaturalStackAlignment(_codeInfo.getStackAlignment());
+     158             : 
+     159             :   // Allocate space for function arguments.
+     160        1948 :   func->_args = nullptr;
+     161        1948 :   if (func->getArgCount() != 0) {
+     162           0 :     func->_args = _cbHeap.allocT<VirtReg*>(func->getArgCount() * sizeof(VirtReg*));
+     163           0 :     if (!func->_args) goto _NoMemory;
+     164             : 
+     165           0 :     ::memset(func->_args, 0, func->getArgCount() * sizeof(VirtReg*));
+     166             :   }
+     167             : 
+     168             :   return func;
+     169             : 
+     170           0 : _NoMemory:
+     171           0 :   setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     172           0 :   return nullptr;
+     173             : }
+     174             : 
+     175        1948 : CCFunc* CodeCompiler::addFunc(CCFunc* func) {
+     176             :   ASMJIT_ASSERT(_func == nullptr);
+     177        1948 :   _func = func;
+     178             : 
+     179        1948 :   addNode(func);                 // Function node.
+     180             :   CBNode* cursor = getCursor();  // {CURSOR}.
+     181        1948 :   addNode(func->getExitNode());  // Function exit label.
+     182        1948 :   addNode(func->getEnd());       // Function end marker.
+     183             : 
+     184             :   _setCursor(cursor);
+     185        1948 :   return func;
+     186             : }
+     187             : 
+     188        1948 : CCFunc* CodeCompiler::addFunc(const FuncSignature& sign) {
+     189        1948 :   CCFunc* func = newFunc(sign);
+     190             : 
+     191        1948 :   if (!func) {
+     192           0 :     setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     193           0 :     return nullptr;
+     194             :   }
+     195             : 
+     196        1948 :   return addFunc(func);
+     197             : }
+     198             : 
+     199        1948 : CBSentinel* CodeCompiler::endFunc() {
+     200             :   CCFunc* func = getFunc();
+     201        1948 :   if (!func) {
+     202             :     // TODO:
+     203             :     return nullptr;
+     204             :   }
+     205             : 
+     206             :   // Add the local constant pool at the end of the function (if exists).
+     207        1948 :   if (_localConstPool) {
+     208           0 :     setCursor(func->getEnd()->getPrev());
+     209           0 :     addNode(_localConstPool);
+     210           0 :     _localConstPool = nullptr;
+     211             :   }
+     212             : 
+     213             :   // Mark as finished.
+     214        1948 :   func->_isFinished = true;
+     215        1948 :   _func = nullptr;
+     216             : 
+     217             :   CBSentinel* end = func->getEnd();
+     218        1948 :   setCursor(end);
+     219        1948 :   return end;
+     220             : }
+     221             : 
+     222             : // ============================================================================
+     223             : // [asmjit::CodeCompiler - Ret]
+     224             : // ============================================================================
+     225             : 
+     226        1948 : CCFuncRet* CodeCompiler::newRet(const Operand_& o0, const Operand_& o1) noexcept {
+     227        1948 :   CCFuncRet* node = newNodeT<CCFuncRet>(o0, o1);
+     228        1948 :   if (!node) {
+     229           0 :     setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     230           0 :     return nullptr;
+     231             :   }
+     232             :   return node;
+     233             : }
+     234             : 
+     235        1948 : CCFuncRet* CodeCompiler::addRet(const Operand_& o0, const Operand_& o1) noexcept {
+     236        1948 :   CCFuncRet* node = newRet(o0, o1);
+     237        1948 :   if (!node) return nullptr;
+     238        1948 :   return static_cast<CCFuncRet*>(addNode(node));
+     239             : }
+     240             : 
+     241             : // ============================================================================
+     242             : // [asmjit::CodeCompiler - Call]
+     243             : // ============================================================================
+     244             : 
+     245        1648 : CCFuncCall* CodeCompiler::newCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept {
+     246             :   Error err;
+     247             :   uint32_t nArgs;
+     248             : 
+     249        1648 :   CCFuncCall* node = _cbHeap.allocT<CCFuncCall>(sizeof(CCFuncCall) + sizeof(Operand));
+     250        1648 :   Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CCFuncCall));
+     251             : 
+     252        1648 :   if (ASMJIT_UNLIKELY(!node))
+     253           0 :     goto _NoMemory;
+     254             : 
+     255        1648 :   opArray[0].copyFrom(o0);
+     256             :   new (node) CCFuncCall(this, instId, 0, opArray, 1);
+     257             : 
+     258        1648 :   if ((err = node->getDetail().init(sign)) != kErrorOk) {
+     259           0 :     setLastError(err);
+     260           0 :     return nullptr;
+     261             :   }
+     262             : 
+     263             :   // If there are no arguments skip the allocation.
+     264        1648 :   if ((nArgs = sign.getArgCount()) == 0)
+     265             :     return node;
+     266             : 
+     267        1648 :   node->_args = static_cast<Operand*>(_cbHeap.alloc(nArgs * sizeof(Operand)));
+     268        1648 :   if (!node->_args) goto _NoMemory;
+     269             : 
+     270             :   ::memset(node->_args, 0, nArgs * sizeof(Operand));
+     271        1648 :   return node;
+     272             : 
+     273           0 : _NoMemory:
+     274           0 :   setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     275           0 :   return nullptr;
+     276             : }
+     277             : 
+     278        1648 : CCFuncCall* CodeCompiler::addCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept {
+     279        1648 :   CCFuncCall* node = newCall(instId, o0, sign);
+     280        1648 :   if (!node) return nullptr;
+     281        1648 :   return static_cast<CCFuncCall*>(addNode(node));
+     282             : }
+     283             : 
+     284             : // ============================================================================
+     285             : // [asmjit::CodeCompiler - Vars]
+     286             : // ============================================================================
+     287             : 
+     288           0 : Error CodeCompiler::setArg(uint32_t argIndex, const Reg& r) {
+     289             :   CCFunc* func = getFunc();
+     290             : 
+     291           0 :   if (!func)
+     292           0 :     return setLastError(DebugUtils::errored(kErrorInvalidState));
+     293             : 
+     294           0 :   if (!isVirtRegValid(r))
+     295           0 :     return setLastError(DebugUtils::errored(kErrorInvalidVirtId));
+     296             : 
+     297             :   VirtReg* vr = getVirtReg(r);
+     298             :   func->setArg(argIndex, vr);
+     299             : 
+     300           0 :   return kErrorOk;
+     301             : }
+     302             : 
+     303             : // ============================================================================
+     304             : // [asmjit::CodeCompiler - Hint]
+     305             : // ============================================================================
+     306             : 
+     307           0 : Error CodeCompiler::_hint(Reg& r, uint32_t hint, uint32_t value) {
+     308           0 :   if (!r.isVirtReg()) return kErrorOk;
+     309             : 
+     310           0 :   CCHint* node = newHintNode(r, hint, value);
+     311           0 :   if (!node) return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     312             : 
+     313           0 :   addNode(node);
+     314           0 :   return kErrorOk;
+     315             : }
+     316             : 
+     317             : // ============================================================================
+     318             : // [asmjit::CodeCompiler - Vars]
+     319             : // ============================================================================
+     320             : 
+     321       23788 : VirtReg* CodeCompiler::newVirtReg(uint32_t typeId, uint32_t signature, const char* name) noexcept {
+     322             :   size_t index = _vRegArray.getLength();
+     323       23788 :   if (ASMJIT_UNLIKELY(index > Operand::kPackedIdCount))
+     324             :     return nullptr;
+     325             : 
+     326             :   VirtReg* vreg;
+     327       29036 :   if (_vRegArray.willGrow(&_cbHeap, 1) != kErrorOk || !(vreg = _vRegZone.allocZeroedT<VirtReg>()))
+     328           0 :     return nullptr;
+     329             : 
+     330       23788 :   vreg->_id = Operand::packId(static_cast<uint32_t>(index));
+     331       23788 :   vreg->_regInfo._signature = signature;
+     332       23788 :   vreg->_name = noName;
+     333             : 
+     334             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     335       23788 :   if (name && name[0] != '\0')
+     336           0 :     vreg->_name = static_cast<char*>(_cbDataZone.dup(name, ::strlen(name), true));
+     337             : #endif // !ASMJIT_DISABLE_LOGGING
+     338             : 
+     339       23788 :   vreg->_size = TypeId::sizeOf(typeId);
+     340       23788 :   vreg->_typeId = typeId;
+     341       23788 :   vreg->_alignment = static_cast<uint8_t>(std::min<uint32_t>(vreg->_size, 64));
+     342       23788 :   vreg->_priority = 10;
+     343             : 
+     344             :   // The following are only used by `RAPass`.
+     345       23788 :   vreg->_raId = kInvalidValue;
+     346       23788 :   vreg->_state = VirtReg::kStateNone;
+     347       23788 :   vreg->_physId = Globals::kInvalidRegId;
+     348             : 
+     349             :   _vRegArray.appendUnsafe(vreg);
+     350       23788 :   return vreg;
+     351             : }
+     352             : 
+     353       23788 : Error CodeCompiler::_newReg(Reg& out, uint32_t typeId, const char* name) {
+     354             :   RegInfo regInfo;
+     355             : 
+     356       23788 :   Error err = ArchUtils::typeIdToRegInfo(getArchType(), typeId, regInfo);
+     357       23788 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     358             : 
+     359       23788 :   VirtReg* vReg = newVirtReg(typeId, regInfo.getSignature(), name);
+     360       23788 :   if (ASMJIT_UNLIKELY(!vReg)) {
+     361             :     out.reset();
+     362           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     363             :   }
+     364             : 
+     365             :   out._initReg(regInfo.getSignature(), vReg->getId());
+     366       23788 :   return kErrorOk;
+     367             : }
+     368             : 
+     369           0 : Error CodeCompiler::_newReg(Reg& out, uint32_t typeId, const char* nameFmt, va_list ap) {
+     370             :   StringBuilderTmp<256> sb;
+     371             :   sb.appendFormatVA(nameFmt, ap);
+     372           0 :   return _newReg(out, typeId, sb.getData());
+     373             : }
+     374             : 
+     375           0 : Error CodeCompiler::_newReg(Reg& out, const Reg& ref, const char* name) {
+     376             :   RegInfo regInfo;
+     377             :   uint32_t typeId;
+     378             : 
+     379           0 :   if (isVirtRegValid(ref)) {
+     380             :     VirtReg* vRef = getVirtReg(ref);
+     381           0 :     typeId = vRef->getTypeId();
+     382             : 
+     383             :     // NOTE: It's possible to cast one register type to another if it's the
+     384             :     // same register kind. However, VirtReg always contains the TypeId that
+     385             :     // was used to create the register. This means that in some cases we may
+     386             :     // end up having different size of `ref` and `vRef`. In such case we
+     387             :     // adjust the TypeId to match the `ref` register type instead of the
+     388             :     // original register type, which should be the expected behavior.
+     389             :     uint32_t typeSize = TypeId::sizeOf(typeId);
+     390             :     uint32_t refSize = ref.getSize();
+     391             : 
+     392           0 :     if (typeSize != refSize) {
+     393           0 :       if (TypeId::isInt(typeId)) {
+     394             :         // GP register - change TypeId to match `ref`, but keep sign of `vRef`.
+     395           0 :         switch (refSize) {
+     396           0 :           case  1: typeId = TypeId::kI8  | (typeId & 1); break;
+     397           0 :           case  2: typeId = TypeId::kI16 | (typeId & 1); break;
+     398           0 :           case  4: typeId = TypeId::kI32 | (typeId & 1); break;
+     399           0 :           case  8: typeId = TypeId::kI64 | (typeId & 1); break;
+     400           0 :           default: typeId = TypeId::kVoid; break;
+     401             :         }
+     402             :       }
+     403           0 :       else if (TypeId::isMmx(typeId)) {
+     404             :         // MMX register - always use 64-bit.
+     405           0 :         typeId = TypeId::kMmx64;
+     406             :       }
+     407           0 :       else if (TypeId::isMask(typeId)) {
+     408             :         // Mask register - change TypeId to match `ref` size.
+     409           0 :         switch (refSize) {
+     410           0 :           case  1: typeId = TypeId::kMask8; break;
+     411           0 :           case  2: typeId = TypeId::kMask16; break;
+     412           0 :           case  4: typeId = TypeId::kMask32; break;
+     413           0 :           case  8: typeId = TypeId::kMask64; break;
+     414           0 :           default: typeId = TypeId::kVoid; break;
+     415             :         }
+     416             :       }
+     417             :       else {
+     418             :         // VEC register - change TypeId to match `ref` size, keep vector metadata.
+     419             :         uint32_t elementTypeId = TypeId::elementOf(typeId);
+     420             : 
+     421           0 :         switch (refSize) {
+     422           0 :           case 16: typeId = TypeId::_kVec128Start + (elementTypeId - TypeId::kI8); break;
+     423           0 :           case 32: typeId = TypeId::_kVec256Start + (elementTypeId - TypeId::kI8); break;
+     424           0 :           case 64: typeId = TypeId::_kVec512Start + (elementTypeId - TypeId::kI8); break;
+     425           0 :           default: typeId = TypeId::kVoid; break;
+     426             :         }
+     427             :       }
+     428             : 
+     429           0 :       if (typeId == TypeId::kVoid)
+     430           0 :         return setLastError(DebugUtils::errored(kErrorInvalidState));
+     431             :     }
+     432             :   }
+     433             :   else {
+     434           0 :     typeId = ref.getType();
+     435             :   }
+     436             : 
+     437           0 :   Error err = ArchUtils::typeIdToRegInfo(getArchType(), typeId, regInfo);
+     438           0 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     439             : 
+     440           0 :   VirtReg* vReg = newVirtReg(typeId, regInfo.getSignature(), name);
+     441           0 :   if (ASMJIT_UNLIKELY(!vReg)) {
+     442             :     out.reset();
+     443           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     444             :   }
+     445             : 
+     446             :   out._initReg(regInfo.getSignature(), vReg->getId());
+     447           0 :   return kErrorOk;
+     448             : }
+     449             : 
+     450           0 : Error CodeCompiler::_newReg(Reg& out, const Reg& ref, const char* nameFmt, va_list ap) {
+     451             :   StringBuilderTmp<256> sb;
+     452             :   sb.appendFormatVA(nameFmt, ap);
+     453           0 :   return _newReg(out, ref, sb.getData());
+     454             : }
+     455             : 
+     456           0 : Error CodeCompiler::_newStack(Mem& out, uint32_t size, uint32_t alignment, const char* name) {
+     457           0 :   if (size == 0)
+     458           0 :     return setLastError(DebugUtils::errored(kErrorInvalidArgument));
+     459             : 
+     460             :   if (alignment == 0) alignment = 1;
+     461             :   if (!Utils::isPowerOf2(alignment))
+     462           0 :     return setLastError(DebugUtils::errored(kErrorInvalidArgument));
+     463             : 
+     464             :   if (alignment > 64) alignment = 64;
+     465             : 
+     466           0 :   VirtReg* vReg = newVirtReg(0, 0, name);
+     467           0 :   if (ASMJIT_UNLIKELY(!vReg)) {
+     468             :     out.reset();
+     469           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     470             :   }
+     471             : 
+     472           0 :   vReg->_size = size;
+     473           0 :   vReg->_isStack = true;
+     474           0 :   vReg->_alignment = static_cast<uint8_t>(alignment);
+     475             : 
+     476             :   // Set the memory operand to GPD/GPQ and its id to VirtReg.
+     477           0 :   out = Mem(Init, _nativeGpReg.getType(), vReg->getId(), Reg::kRegNone, kInvalidValue, 0, 0, Mem::kSignatureMemRegHomeFlag);
+     478           0 :   return kErrorOk;
+     479             : }
+     480             : 
+     481           0 : Error CodeCompiler::_newConst(Mem& out, uint32_t scope, const void* data, size_t size) {
+     482             :   CBConstPool** pPool;
+     483           0 :   if (scope == kConstScopeLocal)
+     484           0 :     pPool = &_localConstPool;
+     485           0 :   else if (scope == kConstScopeGlobal)
+     486           0 :     pPool = &_globalConstPool;
+     487             :   else
+     488           0 :     return setLastError(DebugUtils::errored(kErrorInvalidArgument));
+     489             : 
+     490           0 :   if (!*pPool && !(*pPool = newConstPool()))
+     491           0 :     return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     492             : 
+     493           0 :   CBConstPool* pool = *pPool;
+     494             :   size_t off;
+     495             : 
+     496             :   Error err = pool->add(data, size, off);
+     497           0 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     498             : 
+     499           0 :   out = Mem(Init,
+     500             :     Label::kLabelTag,             // Base type.
+     501             :     pool->getId(),                // Base id.
+     502             :     0,                            // Index type.
+     503             :     kInvalidValue,                // Index id.
+     504             :     static_cast<int32_t>(off),    // Offset.
+     505             :     static_cast<uint32_t>(size),  // Size.
+     506             :     0);                           // Flags.
+     507           0 :   return kErrorOk;
+     508             : }
+     509             : 
+     510           0 : Error CodeCompiler::alloc(Reg& reg) {
+     511           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     512           0 :   return _hint(reg, CCHint::kHintAlloc, kInvalidValue);
+     513             : }
+     514             : 
+     515           0 : Error CodeCompiler::alloc(Reg& reg, uint32_t physId) {
+     516           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     517           0 :   return _hint(reg, CCHint::kHintAlloc, physId);
+     518             : }
+     519             : 
+     520           0 : Error CodeCompiler::alloc(Reg& reg, const Reg& physReg) {
+     521           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     522           0 :   return _hint(reg, CCHint::kHintAlloc, physReg.getId());
+     523             : }
+     524             : 
+     525           0 : Error CodeCompiler::save(Reg& reg) {
+     526           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     527           0 :   return _hint(reg, CCHint::kHintSave, kInvalidValue);
+     528             : }
+     529             : 
+     530           0 : Error CodeCompiler::spill(Reg& reg) {
+     531           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     532           0 :   return _hint(reg, CCHint::kHintSpill, kInvalidValue);
+     533             : }
+     534             : 
+     535           0 : Error CodeCompiler::unuse(Reg& reg) {
+     536           0 :   if (!reg.isVirtReg()) return kErrorOk;
+     537           0 :   return _hint(reg, CCHint::kHintUnuse, kInvalidValue);
+     538             : }
+     539             : 
+     540           0 : uint32_t CodeCompiler::getPriority(Reg& reg) const {
+     541           0 :   if (!reg.isVirtReg()) return 0;
+     542           0 :   return getVirtRegById(reg.getId())->getPriority();
+     543             : }
+     544             : 
+     545           0 : void CodeCompiler::setPriority(Reg& reg, uint32_t priority) {
+     546           0 :   if (!reg.isVirtReg()) return;
+     547             :   if (priority > 255) priority = 255;
+     548             : 
+     549             :   VirtReg* vreg = getVirtRegById(reg.getId());
+     550           0 :   if (vreg) vreg->_priority = static_cast<uint8_t>(priority);
+     551             : }
+     552             : 
+     553           0 : bool CodeCompiler::getSaveOnUnuse(Reg& reg) const {
+     554           0 :   if (!reg.isVirtReg()) return false;
+     555             : 
+     556             :   VirtReg* vreg = getVirtRegById(reg.getId());
+     557           0 :   return static_cast<bool>(vreg->_saveOnUnuse);
+     558             : }
+     559             : 
+     560           0 : void CodeCompiler::setSaveOnUnuse(Reg& reg, bool value) {
+     561           0 :   if (!reg.isVirtReg()) return;
+     562             : 
+     563             :   VirtReg* vreg = getVirtRegById(reg.getId());
+     564           0 :   if (!vreg) return;
+     565             : 
+     566           0 :   vreg->_saveOnUnuse = value;
+     567             : }
+     568             : 
+     569           0 : void CodeCompiler::rename(Reg& reg, const char* fmt, ...) {
+     570           0 :   if (!reg.isVirtReg()) return;
+     571             : 
+     572             :   VirtReg* vreg = getVirtRegById(reg.getId());
+     573           0 :   if (!vreg) return;
+     574             : 
+     575           0 :   vreg->_name = noName;
+     576           0 :   if (fmt && fmt[0] != '\0') {
+     577             :     char buf[64];
+     578             : 
+     579             :     va_list ap;
+     580           0 :     va_start(ap, fmt);
+     581             : 
+     582             :     vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap);
+     583           0 :     buf[ASMJIT_ARRAY_SIZE(buf) - 1] = '\0';
+     584             : 
+     585           0 :     vreg->_name = static_cast<char*>(_cbDataZone.dup(buf, ::strlen(buf), true));
+     586           0 :     va_end(ap);
+     587             :   }
+     588             : }
+     589             : 
+     590             : } // asmjit namespace
+     591             : } // namespace PLMD
+     592             : 
+     593             : // [Api-End]
+     594             : #include "./asmjit_apiend.h"
+     595             : 
+     596             : // [Guard]
+     597             : #endif // !ASMJIT_DISABLE_COMPILER
+     598             : #pragma GCC diagnostic pop
+     599             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.h.func-sort-c.html b/coverage-libs/asmjit/codecompiler.h.func-sort-c.html new file mode 100644 index 000000000000..f8d68593d8ec --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:416464.1 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.h.func.html b/coverage-libs/asmjit/codecompiler.h.func.html new file mode 100644 index 000000000000..1fbfb773d520 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:416464.1 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codecompiler.h.gcov.html b/coverage-libs/asmjit/codecompiler.h.gcov.html new file mode 100644 index 000000000000..e29ce81e9b04 --- /dev/null +++ b/coverage-libs/asmjit/codecompiler.h.gcov.html @@ -0,0 +1,844 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codecompiler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codecompiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:416464.1 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_codecompiler_h
+      21             : #define __PLUMED_asmjit_codecompiler_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_CODECOMPILER_H
+      33             : #define _ASMJIT_BASE_CODECOMPILER_H
+      34             : 
+      35             : #include "./asmjit_build.h"
+      36             : #if !defined(ASMJIT_DISABLE_COMPILER)
+      37             : 
+      38             : // [Dependencies]
+      39             : #include "./assembler.h"
+      40             : #include "./codebuilder.h"
+      41             : #include "./constpool.h"
+      42             : #include "./func.h"
+      43             : #include "./operand.h"
+      44             : #include "./utils.h"
+      45             : #include "./zone.h"
+      46             : 
+      47             : // [Api-Begin]
+      48             : #include "./asmjit_apibegin.h"
+      49             : 
+      50             : namespace PLMD {
+      51             : namespace asmjit {
+      52             : 
+      53             : // ============================================================================
+      54             : // [Forward Declarations]
+      55             : // ============================================================================
+      56             : 
+      57             : struct VirtReg;
+      58             : struct TiedReg;
+      59             : struct RAState;
+      60             : struct RACell;
+      61             : 
+      62             : //! \addtogroup asmjit_base
+      63             : //! \{
+      64             : 
+      65             : // ============================================================================
+      66             : // [asmjit::ConstScope]
+      67             : // ============================================================================
+      68             : 
+      69             : //! Scope of the constant.
+      70             : ASMJIT_ENUM(ConstScope) {
+      71             :   //! Local constant, always embedded right after the current function.
+      72             :   kConstScopeLocal = 0,
+      73             :   //! Global constant, embedded at the end of the currently compiled code.
+      74             :   kConstScopeGlobal = 1
+      75             : };
+      76             : 
+      77             : // ============================================================================
+      78             : // [asmjit::VirtReg]
+      79             : // ============================================================================
+      80             : 
+      81             : //! Virtual register data (CodeCompiler).
+      82             : struct VirtReg {
+      83             :   //! A state of a virtual register (used during register allocation).
+      84             :   ASMJIT_ENUM(State) {
+      85             :     kStateNone = 0,                      //!< Not allocated, not used.
+      86             :     kStateReg = 1,                       //!< Allocated in register.
+      87             :     kStateMem = 2                        //!< Allocated in memory or spilled.
+      88             :   };
+      89             : 
+      90             :   // --------------------------------------------------------------------------
+      91             :   // [Accessors]
+      92             :   // --------------------------------------------------------------------------
+      93             : 
+      94             :   //! Get the virtual-register id.
+      95       32216 :   ASMJIT_INLINE uint32_t getId() const noexcept { return _id; }
+      96             :   //! Get virtual-register's name.
+      97           0 :   ASMJIT_INLINE const char* getName() const noexcept { return _name; }
+      98             : 
+      99             :   //! Get a physical register type.
+     100             :   ASMJIT_INLINE uint32_t getType() const noexcept { return _regInfo.getType(); }
+     101             :   //! Get a physical register kind.
+     102             :   ASMJIT_INLINE uint32_t getKind() const noexcept { return _regInfo.getKind(); }
+     103             :   //! Get a physical register size.
+     104             :   ASMJIT_INLINE uint32_t getRegSize() const noexcept { return _regInfo.getSize(); }
+     105             :   //! Get a register signature of this virtual register.
+     106             :   ASMJIT_INLINE uint32_t getSignature() const noexcept { return _regInfo.getSignature(); }
+     107             : 
+     108             :   //! Get a register's type-id, see \ref TypeId.
+     109        9084 :   ASMJIT_INLINE uint32_t getTypeId() const noexcept { return _typeId; }
+     110             : 
+     111             :   //! Get virtual-register's size.
+     112       25896 :   ASMJIT_INLINE uint32_t getSize() const noexcept { return _size; }
+     113             :   //! Get virtual-register's alignment.
+     114           0 :   ASMJIT_INLINE uint32_t getAlignment() const noexcept { return _alignment; }
+     115             : 
+     116             :   //! Get the virtual-register  priority, used by compiler to decide which variable to spill.
+     117           0 :   ASMJIT_INLINE uint32_t getPriority() const noexcept { return _priority; }
+     118             :   //! Set the virtual-register  priority.
+     119             :   ASMJIT_INLINE void setPriority(uint32_t priority) noexcept {
+     120             :     ASMJIT_ASSERT(priority <= 0xFF);
+     121             :     _priority = static_cast<uint8_t>(priority);
+     122             :   }
+     123             : 
+     124             :   //! Get variable state, only used by `RAPass`.
+     125        4972 :   ASMJIT_INLINE uint32_t getState() const noexcept { return _state; }
+     126             :   //! Set variable state, only used by `RAPass`.
+     127             :   ASMJIT_INLINE void setState(uint32_t state) {
+     128             :     ASMJIT_ASSERT(state <= 0xFF);
+     129           0 :     _state = static_cast<uint8_t>(state);
+     130       24746 :   }
+     131             : 
+     132             :   //! Get register index.
+     133      181634 :   ASMJIT_INLINE uint32_t getPhysId() const noexcept { return _physId; }
+     134             :   //! Set register index.
+     135             :   ASMJIT_INLINE void setPhysId(uint32_t physId) {
+     136             :     ASMJIT_ASSERT(physId <= Globals::kInvalidRegId);
+     137         656 :     _physId = static_cast<uint8_t>(physId);
+     138             :   }
+     139             :   //! Reset register index.
+     140             :   ASMJIT_INLINE void resetPhysId() {
+     141       50052 :     _physId = static_cast<uint8_t>(Globals::kInvalidRegId);
+     142             :   }
+     143             : 
+     144             :   //! Get home registers mask.
+     145       26412 :   ASMJIT_INLINE uint32_t getHomeMask() const { return _homeMask; }
+     146             :   //! Add a home register index to the home registers mask.
+     147        4424 :   ASMJIT_INLINE void addHomeId(uint32_t physId) { _homeMask |= Utils::mask(physId); }
+     148             : 
+     149       27940 :   ASMJIT_INLINE bool isFixed() const noexcept { return static_cast<bool>(_isFixed); }
+     150             : 
+     151             :   //! Get whether the VirtReg is only memory allocated on the stack.
+     152       10104 :   ASMJIT_INLINE bool isStack() const noexcept { return static_cast<bool>(_isStack); }
+     153             : 
+     154             :   //! Get whether to save variable when it's unused (spill).
+     155             :   ASMJIT_INLINE bool saveOnUnuse() const noexcept { return static_cast<bool>(_saveOnUnuse); }
+     156             : 
+     157             :   //! Get whether the variable was changed.
+     158       10462 :   ASMJIT_INLINE bool isModified() const noexcept { return static_cast<bool>(_modified); }
+     159             :   //! Set whether the variable was changed.
+     160       88836 :   ASMJIT_INLINE void setModified(bool modified) noexcept { _modified = modified; }
+     161             : 
+     162             :   //! Get home memory offset.
+     163             :   ASMJIT_INLINE int32_t getMemOffset() const noexcept { return _memOffset; }
+     164             :   //! Set home memory offset.
+     165             :   ASMJIT_INLINE void setMemOffset(int32_t offset) noexcept { _memOffset = offset; }
+     166             : 
+     167             :   //! Get home memory cell.
+     168        8428 :   ASMJIT_INLINE RACell* getMemCell() const noexcept { return _memCell; }
+     169             :   //! Set home memory cell.
+     170             :   ASMJIT_INLINE void setMemCell(RACell* cell) noexcept { _memCell = cell; }
+     171             : 
+     172             :   // --------------------------------------------------------------------------
+     173             :   // [Members]
+     174             :   // --------------------------------------------------------------------------
+     175             : 
+     176             :   uint32_t _id;                          //!< Virtual register id.
+     177             :   RegInfo _regInfo;                      //!< Physical register info & signature.
+     178             :   const char* _name;                     //!< Virtual name (user provided).
+     179             :   uint32_t _size;                        //!< Virtual size (can be smaller than `regInfo._size`).
+     180             :   uint8_t _typeId;                       //!< Type-id.
+     181             :   uint8_t _alignment;                    //!< Register's natural alignment (for spilling).
+     182             :   uint8_t _priority;                     //!< Allocation priority (hint for RAPass that can be ignored).
+     183             :   uint8_t _isFixed : 1;                  //!< True if this is a fixed register, never reallocated.
+     184             :   uint8_t _isStack : 1;                  //!< True if the virtual register is only used as a stack.
+     185             :   uint8_t _isMaterialized : 1;           //!< Register is constant that is easily created by a single instruction.
+     186             :   uint8_t _saveOnUnuse : 1;              //!< Save on unuse (at end of the variable scope).
+     187             : 
+     188             :   // -------------------------------------------------------------------------
+     189             :   // The following members are used exclusively by RAPass. They are initialized
+     190             :   // when the VirtReg is created and then changed during RAPass.
+     191             :   // -------------------------------------------------------------------------
+     192             : 
+     193             :   uint32_t _raId;                        //!< Register allocator work-id (used by RAPass).
+     194             :   int32_t _memOffset;                    //!< Home memory offset.
+     195             :   uint32_t _homeMask;                    //!< Mask of all registers variable has been allocated to.
+     196             : 
+     197             :   uint8_t _state;                        //!< Variable state (connected with actual `RAState)`.
+     198             :   uint8_t _physId;                       //!< Actual register index (only used by `RAPass)`, during translate.
+     199             :   uint8_t _modified;                     //!< Whether variable was changed (connected with actual `RAState)`.
+     200             : 
+     201             :   RACell* _memCell;                      //!< Home memory cell, used by `RAPass` (initially nullptr).
+     202             : 
+     203             :   //! Temporary link to TiedReg* used by the `RAPass` used in
+     204             :   //! various phases, but always set back to nullptr when finished.
+     205             :   //!
+     206             :   //! This temporary data is designed to be used by algorithms that need to
+     207             :   //! store some data into variables themselves during compilation. But it's
+     208             :   //! expected that after variable is compiled & translated the data is set
+     209             :   //! back to zero/null. Initial value is nullptr.
+     210             :   TiedReg* _tied;
+     211             : };
+     212             : 
+     213             : // ============================================================================
+     214             : // [asmjit::CCHint]
+     215             : // ============================================================================
+     216             : 
+     217             : //! Hint for register allocator (CodeCompiler).
+     218             : class CCHint : public CBNode {
+     219             : public:
+     220             :   ASMJIT_NONCOPYABLE(CCHint)
+     221             : 
+     222             :   //! Hint type.
+     223             :   ASMJIT_ENUM(Hint) {
+     224             :     //! Alloc to physical reg.
+     225             :     kHintAlloc = 0,
+     226             :     //! Spill to memory.
+     227             :     kHintSpill = 1,
+     228             :     //! Save if modified.
+     229             :     kHintSave = 2,
+     230             :     //! Save if modified and mark it as unused.
+     231             :     kHintSaveAndUnuse = 3,
+     232             :     //! Mark as unused.
+     233             :     kHintUnuse = 4
+     234             :   };
+     235             : 
+     236             :   // --------------------------------------------------------------------------
+     237             :   // [Construction / Destruction]
+     238             :   // --------------------------------------------------------------------------
+     239             : 
+     240             :   //! Create a new `CCHint` instance.
+     241           0 :   ASMJIT_INLINE CCHint(CodeBuilder* cb, VirtReg* vreg, uint32_t hint, uint32_t value) noexcept : CBNode(cb, kNodeHint) {
+     242             :     orFlags(kFlagIsRemovable | kFlagIsInformative);
+     243           0 :     _vreg = vreg;
+     244           0 :     _hint = hint;
+     245           0 :     _value = value;
+     246             :   }
+     247             : 
+     248             :   //! Destroy the `CCHint` instance (NEVER CALLED).
+     249             :   ASMJIT_INLINE ~CCHint() noexcept {}
+     250             : 
+     251             :   // --------------------------------------------------------------------------
+     252             :   // [Accessors]
+     253             :   // --------------------------------------------------------------------------
+     254             : 
+     255             :   //! Get variable.
+     256           0 :   ASMJIT_INLINE VirtReg* getVReg() const noexcept { return _vreg; }
+     257             : 
+     258             :   //! Get hint it, see \ref Hint.
+     259           0 :   ASMJIT_INLINE uint32_t getHint() const noexcept { return _hint; }
+     260             :   //! Set hint it, see \ref Hint.
+     261             :   ASMJIT_INLINE void setHint(uint32_t hint) noexcept { _hint = hint; }
+     262             : 
+     263             :   //! Get hint value.
+     264           0 :   ASMJIT_INLINE uint32_t getValue() const noexcept { return _value; }
+     265             :   //! Set hint value.
+     266             :   ASMJIT_INLINE void setValue(uint32_t value) noexcept { _value = value; }
+     267             : 
+     268             :   // --------------------------------------------------------------------------
+     269             :   // [Members]
+     270             :   // --------------------------------------------------------------------------
+     271             : 
+     272             :   //! Variable.
+     273             :   VirtReg* _vreg;
+     274             :   //! Hint id.
+     275             :   uint32_t _hint;
+     276             :   //! Value.
+     277             :   uint32_t _value;
+     278             : };
+     279             : 
+     280             : // ============================================================================
+     281             : // [asmjit::CCFunc]
+     282             : // ============================================================================
+     283             : 
+     284             : //! Function entry (CodeCompiler).
+     285             : class CCFunc : public CBLabel {
+     286             : public:
+     287             :   ASMJIT_NONCOPYABLE(CCFunc)
+     288             : 
+     289             :   // --------------------------------------------------------------------------
+     290             :   // [Construction / Destruction]
+     291             :   // --------------------------------------------------------------------------
+     292             : 
+     293             :   //! Create a new `CCFunc` instance.
+     294             :   //!
+     295             :   //! Always use `CodeCompiler::addFunc()` to create \ref CCFunc.
+     296             :   ASMJIT_INLINE CCFunc(CodeBuilder* cb) noexcept
+     297        1948 :     : CBLabel(cb),
+     298        1948 :       _funcDetail(),
+     299        1948 :       _frameInfo(),
+     300        1948 :       _exitNode(nullptr),
+     301        1948 :       _end(nullptr),
+     302        1948 :       _args(nullptr),
+     303        1948 :       _isFinished(false) {
+     304             : 
+     305        1948 :     _type = kNodeFunc;
+     306             :   }
+     307             : 
+     308             :   //! Destroy the `CCFunc` instance (NEVER CALLED).
+     309             :   ASMJIT_INLINE ~CCFunc() noexcept {}
+     310             : 
+     311             :   // --------------------------------------------------------------------------
+     312             :   // [Accessors]
+     313             :   // --------------------------------------------------------------------------
+     314             : 
+     315             :   //! Get function exit `CBLabel`.
+     316        7792 :   ASMJIT_INLINE CBLabel* getExitNode() const noexcept { return _exitNode; }
+     317             :   //! Get function exit label.
+     318             :   ASMJIT_INLINE Label getExitLabel() const noexcept { return _exitNode->getLabel(); }
+     319             : 
+     320             :   //! Get "End of Func" sentinel.
+     321        7792 :   ASMJIT_INLINE CBSentinel* getEnd() const noexcept { return _end; }
+     322             : 
+     323             :   //! Get function declaration.
+     324        1948 :   ASMJIT_INLINE FuncDetail& getDetail() noexcept { return _funcDetail; }
+     325             :   //! Get function declaration.
+     326           0 :   ASMJIT_INLINE const FuncDetail& getDetail() const noexcept { return _funcDetail; }
+     327             : 
+     328             :   //! Get function declaration.
+     329        1948 :   ASMJIT_INLINE FuncFrameInfo& getFrameInfo() noexcept { return _frameInfo; }
+     330             :   //! Get function declaration.
+     331             :   ASMJIT_INLINE const FuncFrameInfo& getFrameInfo() const noexcept { return _frameInfo; }
+     332             : 
+     333             :   //! Get arguments count.
+     334             :   ASMJIT_INLINE uint32_t getArgCount() const noexcept { return _funcDetail.getArgCount(); }
+     335             :   //! Get returns count.
+     336             :   ASMJIT_INLINE uint32_t getRetCount() const noexcept { return _funcDetail.getRetCount(); }
+     337             : 
+     338             :   //! Get arguments list.
+     339           0 :   ASMJIT_INLINE VirtReg** getArgs() const noexcept { return _args; }
+     340             : 
+     341             :   //! Get argument at `i`.
+     342             :   ASMJIT_INLINE VirtReg* getArg(uint32_t i) const noexcept {
+     343             :     ASMJIT_ASSERT(i < getArgCount());
+     344           0 :     return _args[i];
+     345             :   }
+     346             : 
+     347             :   //! Set argument at `i`.
+     348             :   ASMJIT_INLINE void setArg(uint32_t i, VirtReg* vreg) noexcept {
+     349             :     ASMJIT_ASSERT(i < getArgCount());
+     350           0 :     _args[i] = vreg;
+     351             :   }
+     352             : 
+     353             :   //! Reset argument at `i`.
+     354             :   ASMJIT_INLINE void resetArg(uint32_t i) noexcept {
+     355             :     ASMJIT_ASSERT(i < getArgCount());
+     356             :     _args[i] = nullptr;
+     357             :   }
+     358             : 
+     359             :   ASMJIT_INLINE uint32_t getAttributes() const noexcept { return _frameInfo.getAttributes(); }
+     360             :   ASMJIT_INLINE void addAttributes(uint32_t attrs) noexcept { _frameInfo.addAttributes(attrs); }
+     361             : 
+     362             :   // --------------------------------------------------------------------------
+     363             :   // [Members]
+     364             :   // --------------------------------------------------------------------------
+     365             : 
+     366             :   FuncDetail _funcDetail;                //!< Function detail.
+     367             :   FuncFrameInfo _frameInfo;              //!< Function frame information.
+     368             : 
+     369             :   CBLabel* _exitNode;                    //!< Function exit.
+     370             :   CBSentinel* _end;                      //!< Function end.
+     371             : 
+     372             :   VirtReg** _args;                       //!< Arguments array as `VirtReg`.
+     373             : 
+     374             :   //! Function was finished by `Compiler::endFunc()`.
+     375             :   uint8_t _isFinished;
+     376             : };
+     377             : 
+     378             : // ============================================================================
+     379             : // [asmjit::CCFuncRet]
+     380             : // ============================================================================
+     381             : 
+     382             : //! Function return (CodeCompiler).
+     383             : class CCFuncRet : public CBNode {
+     384             : public:
+     385             :   ASMJIT_NONCOPYABLE(CCFuncRet)
+     386             : 
+     387             :   // --------------------------------------------------------------------------
+     388             :   // [Construction / Destruction]
+     389             :   // --------------------------------------------------------------------------
+     390             : 
+     391             :   //! Create a new `CCFuncRet` instance.
+     392        1948 :   ASMJIT_INLINE CCFuncRet(CodeBuilder* cb, const Operand_& o0, const Operand_& o1) noexcept : CBNode(cb, kNodeFuncExit) {
+     393             :     orFlags(kFlagIsRet);
+     394        1948 :     _ret[0].copyFrom(o0);
+     395        1948 :     _ret[1].copyFrom(o1);
+     396             :   }
+     397             : 
+     398             :   //! Destroy the `CCFuncRet` instance (NEVER CALLED).
+     399             :   ASMJIT_INLINE ~CCFuncRet() noexcept {}
+     400             : 
+     401             :   // --------------------------------------------------------------------------
+     402             :   // [Accessors]
+     403             :   // --------------------------------------------------------------------------
+     404             : 
+     405             :   //! Get the first return operand.
+     406             :   ASMJIT_INLINE Operand& getFirst() noexcept { return static_cast<Operand&>(_ret[0]); }
+     407             :   //! \overload
+     408             :   ASMJIT_INLINE const Operand& getFirst() const noexcept { return static_cast<const Operand&>(_ret[0]); }
+     409             : 
+     410             :   //! Get the second return operand.
+     411             :   ASMJIT_INLINE Operand& getSecond() noexcept { return static_cast<Operand&>(_ret[1]); }
+     412             :    //! \overload
+     413             :   ASMJIT_INLINE const Operand& getSecond() const noexcept { return static_cast<const Operand&>(_ret[1]); }
+     414             : 
+     415             :   // --------------------------------------------------------------------------
+     416             :   // [Members]
+     417             :   // --------------------------------------------------------------------------
+     418             : 
+     419             :   //! Return operands.
+     420             :   Operand_ _ret[2];
+     421             : };
+     422             : 
+     423             : // ============================================================================
+     424             : // [asmjit::CCFuncCall]
+     425             : // ============================================================================
+     426             : 
+     427             : //! Function call (CodeCompiler).
+     428             : class CCFuncCall : public CBInst {
+     429             : public:
+     430             :   ASMJIT_NONCOPYABLE(CCFuncCall)
+     431             : 
+     432             :   // --------------------------------------------------------------------------
+     433             :   // [Construction / Destruction]
+     434             :   // --------------------------------------------------------------------------
+     435             : 
+     436             :   //! Create a new `CCFuncCall` instance.
+     437             :   ASMJIT_INLINE CCFuncCall(CodeBuilder* cb, uint32_t instId, uint32_t options, Operand* opArray, uint32_t opCount) noexcept
+     438        1648 :     : CBInst(cb, instId, options, opArray, opCount),
+     439        1648 :       _funcDetail(),
+     440        1648 :       _args(nullptr) {
+     441             : 
+     442        1648 :     _type = kNodeFuncCall;
+     443             :     _ret[0].reset();
+     444             :     _ret[1].reset();
+     445             :     orFlags(kFlagIsRemovable);
+     446             :   }
+     447             : 
+     448             :   //! Destroy the `CCFuncCall` instance (NEVER CALLED).
+     449             :   ASMJIT_INLINE ~CCFuncCall() noexcept {}
+     450             : 
+     451             :   // --------------------------------------------------------------------------
+     452             :   // [Signature]
+     453             :   // --------------------------------------------------------------------------
+     454             : 
+     455             :   //! Set function signature.
+     456             :   ASMJIT_INLINE Error setSignature(const FuncSignature& sign) noexcept {
+     457             :     return _funcDetail.init(sign);
+     458             :   }
+     459             : 
+     460             :   // --------------------------------------------------------------------------
+     461             :   // [Accessors]
+     462             :   // --------------------------------------------------------------------------
+     463             : 
+     464             :   //! Get function declaration.
+     465             :   ASMJIT_INLINE FuncDetail& getDetail() noexcept { return _funcDetail; }
+     466             :   //! Get function declaration.
+     467             :   ASMJIT_INLINE const FuncDetail& getDetail() const noexcept { return _funcDetail; }
+     468             : 
+     469             :   //! Get target operand.
+     470             :   ASMJIT_INLINE Operand& getTarget() noexcept { return static_cast<Operand&>(_opArray[0]); }
+     471             :   //! \overload
+     472             :   ASMJIT_INLINE const Operand& getTarget() const noexcept { return static_cast<const Operand&>(_opArray[0]); }
+     473             : 
+     474             :   //! Get return at `i`.
+     475             :   ASMJIT_INLINE Operand& getRet(uint32_t i = 0) noexcept {
+     476             :     ASMJIT_ASSERT(i < 2);
+     477             :     return static_cast<Operand&>(_ret[i]);
+     478             :   }
+     479             :   //! \overload
+     480             :   ASMJIT_INLINE const Operand& getRet(uint32_t i = 0) const noexcept {
+     481             :     ASMJIT_ASSERT(i < 2);
+     482             :     return static_cast<const Operand&>(_ret[i]);
+     483             :   }
+     484             : 
+     485             :   //! Get argument at `i`.
+     486             :   ASMJIT_INLINE Operand& getArg(uint32_t i) noexcept {
+     487             :     ASMJIT_ASSERT(i < kFuncArgCountLoHi);
+     488             :     return static_cast<Operand&>(_args[i]);
+     489             :   }
+     490             :   //! \overload
+     491             :   ASMJIT_INLINE const Operand& getArg(uint32_t i) const noexcept {
+     492             :     ASMJIT_ASSERT(i < kFuncArgCountLoHi);
+     493             :     return static_cast<const Operand&>(_args[i]);
+     494             :   }
+     495             : 
+     496             :   //! Set argument at `i` to `op`.
+     497             :   ASMJIT_API bool _setArg(uint32_t i, const Operand_& op) noexcept;
+     498             :   //! Set return at `i` to `op`.
+     499             :   ASMJIT_API bool _setRet(uint32_t i, const Operand_& op) noexcept;
+     500             : 
+     501             :   //! Set argument at `i` to `reg`.
+     502        1438 :   ASMJIT_INLINE bool setArg(uint32_t i, const Reg& reg) noexcept { return _setArg(i, reg); }
+     503             :   //! Set argument at `i` to `imm`.
+     504         210 :   ASMJIT_INLINE bool setArg(uint32_t i, const Imm& imm) noexcept { return _setArg(i, imm); }
+     505             : 
+     506             :   //! Set return at `i` to `var`.
+     507        1648 :   ASMJIT_INLINE bool setRet(uint32_t i, const Reg& reg) noexcept { return _setRet(i, reg); }
+     508             : 
+     509             :   // --------------------------------------------------------------------------
+     510             :   // [Members]
+     511             :   // --------------------------------------------------------------------------
+     512             : 
+     513             :   FuncDetail _funcDetail;                //!< Function detail.
+     514             :   Operand_ _ret[2];                      //!< Return.
+     515             :   Operand_* _args;                       //!< Arguments.
+     516             : };
+     517             : 
+     518             : // ============================================================================
+     519             : // [asmjit::CCPushArg]
+     520             : // ============================================================================
+     521             : 
+     522             : //! Push argument before a function call (CodeCompiler).
+     523             : class CCPushArg : public CBNode {
+     524             : public:
+     525             :   ASMJIT_NONCOPYABLE(CCPushArg)
+     526             : 
+     527             :   // --------------------------------------------------------------------------
+     528             :   // [Construction / Destruction]
+     529             :   // --------------------------------------------------------------------------
+     530             : 
+     531             :   //! Create a new `CCPushArg` instance.
+     532             :   ASMJIT_INLINE CCPushArg(CodeBuilder* cb, CCFuncCall* call, VirtReg* src, VirtReg* cvt) noexcept
+     533           0 :     : CBNode(cb, kNodePushArg),
+     534           0 :       _call(call),
+     535           0 :       _src(src),
+     536           0 :       _cvt(cvt),
+     537           0 :       _args(0) {
+     538             :     orFlags(kFlagIsRemovable);
+     539             :   }
+     540             : 
+     541             :   //! Destroy the `CCPushArg` instance.
+     542             :   ASMJIT_INLINE ~CCPushArg() noexcept {}
+     543             : 
+     544             :   // --------------------------------------------------------------------------
+     545             :   // [Accessors]
+     546             :   // --------------------------------------------------------------------------
+     547             : 
+     548             :   //! Get the associated function-call.
+     549           0 :   ASMJIT_INLINE CCFuncCall* getCall() const noexcept { return _call; }
+     550             :   //! Get source variable.
+     551           0 :   ASMJIT_INLINE VirtReg* getSrcReg() const noexcept { return _src; }
+     552             :   //! Get conversion variable.
+     553           0 :   ASMJIT_INLINE VirtReg* getCvtReg() const noexcept { return _cvt; }
+     554             : 
+     555             :   // --------------------------------------------------------------------------
+     556             :   // [Members]
+     557             :   // --------------------------------------------------------------------------
+     558             : 
+     559             :   CCFuncCall* _call;                     //!< Associated `CCFuncCall`.
+     560             :   VirtReg* _src;                         //!< Source variable.
+     561             :   VirtReg* _cvt;                         //!< Temporary variable used for conversion (or null).
+     562             :   uint32_t _args;                        //!< Affected arguments bit-array.
+     563             : };
+     564             : 
+     565             : // ============================================================================
+     566             : // [asmjit::CodeCompiler]
+     567             : // ============================================================================
+     568             : 
+     569             : //! Code emitter that uses virtual registers and performs register allocation.
+     570             : //!
+     571             : //! Compiler is a high-level code-generation tool that provides register
+     572             : //! allocation and automatic handling of function calling conventions. It was
+     573             : //! primarily designed for merging multiple parts of code into a function
+     574             : //! without worrying about registers and function calling conventions.
+     575             : //!
+     576             : //! CodeCompiler can be used, with a minimum effort, to handle 32-bit and 64-bit
+     577             : //! code at the same time.
+     578             : //!
+     579             : //! CodeCompiler is based on CodeBuilder and contains all the features it
+     580             : //! provides. It means that the code it stores can be modified (removed, added,
+     581             : //! injected) and analyzed. When the code is finalized the compiler can emit
+     582             : //! the code into an Assembler to translate the abstract representation into a
+     583             : //! machine code.
+     584             : class ASMJIT_VIRTAPI CodeCompiler : public CodeBuilder {
+     585             : public:
+     586             :   ASMJIT_NONCOPYABLE(CodeCompiler)
+     587             :   typedef CodeBuilder Base;
+     588             : 
+     589             :   // --------------------------------------------------------------------------
+     590             :   // [Construction / Destruction]
+     591             :   // --------------------------------------------------------------------------
+     592             : 
+     593             :   //! Create a new `CodeCompiler` instance.
+     594             :   ASMJIT_API CodeCompiler() noexcept;
+     595             :   //! Destroy the `CodeCompiler` instance.
+     596             :   ASMJIT_API virtual ~CodeCompiler() noexcept;
+     597             : 
+     598             :   // --------------------------------------------------------------------------
+     599             :   // [Events]
+     600             :   // --------------------------------------------------------------------------
+     601             : 
+     602             :   ASMJIT_API virtual Error onAttach(CodeHolder* code) noexcept override;
+     603             :   ASMJIT_API virtual Error onDetach(CodeHolder* code) noexcept override;
+     604             : 
+     605             :   // --------------------------------------------------------------------------
+     606             :   // [Node-Factory]
+     607             :   // --------------------------------------------------------------------------
+     608             : 
+     609             :   //! \internal
+     610             :   //!
+     611             :   //! Create a new `CCHint`.
+     612             :   ASMJIT_API CCHint* newHintNode(Reg& reg, uint32_t hint, uint32_t value) noexcept;
+     613             : 
+     614             :   // --------------------------------------------------------------------------
+     615             :   // [Func]
+     616             :   // --------------------------------------------------------------------------
+     617             : 
+     618             :   //! Get the current function.
+     619        1948 :   ASMJIT_INLINE CCFunc* getFunc() const noexcept { return _func; }
+     620             : 
+     621             :   //! Create a new `CCFunc`.
+     622             :   ASMJIT_API CCFunc* newFunc(const FuncSignature& sign) noexcept;
+     623             :   //! Add a function `node` to the stream.
+     624             :   ASMJIT_API CCFunc* addFunc(CCFunc* func);
+     625             :   //! Add a new function.
+     626             :   ASMJIT_API CCFunc* addFunc(const FuncSignature& sign);
+     627             :   //! Emit a sentinel that marks the end of the current function.
+     628             :   ASMJIT_API CBSentinel* endFunc();
+     629             : 
+     630             :   // --------------------------------------------------------------------------
+     631             :   // [Ret]
+     632             :   // --------------------------------------------------------------------------
+     633             : 
+     634             :   //! Create a new `CCFuncRet`.
+     635             :   ASMJIT_API CCFuncRet* newRet(const Operand_& o0, const Operand_& o1) noexcept;
+     636             :   //! Add a new `CCFuncRet`.
+     637             :   ASMJIT_API CCFuncRet* addRet(const Operand_& o0, const Operand_& o1) noexcept;
+     638             : 
+     639             :   // --------------------------------------------------------------------------
+     640             :   // [Call]
+     641             :   // --------------------------------------------------------------------------
+     642             : 
+     643             :   //! Create a new `CCFuncCall`.
+     644             :   ASMJIT_API CCFuncCall* newCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept;
+     645             :   //! Add a new `CCFuncCall`.
+     646             :   ASMJIT_API CCFuncCall* addCall(uint32_t instId, const Operand_& o0, const FuncSignature& sign) noexcept;
+     647             : 
+     648             :   // --------------------------------------------------------------------------
+     649             :   // [Args]
+     650             :   // --------------------------------------------------------------------------
+     651             : 
+     652             :   //! Set a function argument at `argIndex` to `reg`.
+     653             :   ASMJIT_API Error setArg(uint32_t argIndex, const Reg& reg);
+     654             : 
+     655             :   // --------------------------------------------------------------------------
+     656             :   // [Hint]
+     657             :   // --------------------------------------------------------------------------
+     658             : 
+     659             :   //! Emit a new hint (purely informational node).
+     660             :   ASMJIT_API Error _hint(Reg& reg, uint32_t hint, uint32_t value);
+     661             : 
+     662             :   // --------------------------------------------------------------------------
+     663             :   // [VirtReg / Stack]
+     664             :   // --------------------------------------------------------------------------
+     665             : 
+     666             :   //! Create a new virtual register representing the given `vti` and `signature`.
+     667             :   //!
+     668             :   //! This function accepts either register type representing a machine-specific
+     669             :   //! register, like `X86Reg`, or RegTag representation, which represents
+     670             :   //! machine independent register, and from the machine-specific register
+     671             :   //! is deduced.
+     672             :   ASMJIT_API VirtReg* newVirtReg(uint32_t typeId, uint32_t signature, const char* name) noexcept;
+     673             : 
+     674             :   ASMJIT_API Error _newReg(Reg& out, uint32_t typeId, const char* name);
+     675             :   ASMJIT_API Error _newReg(Reg& out, uint32_t typeId, const char* nameFmt, va_list ap);
+     676             : 
+     677             :   ASMJIT_API Error _newReg(Reg& out, const Reg& ref, const char* name);
+     678             :   ASMJIT_API Error _newReg(Reg& out, const Reg& ref, const char* nameFmt, va_list ap);
+     679             : 
+     680             :   ASMJIT_API Error _newStack(Mem& out, uint32_t size, uint32_t alignment, const char* name);
+     681             :   ASMJIT_API Error _newConst(Mem& out, uint32_t scope, const void* data, size_t size);
+     682             : 
+     683             :   // --------------------------------------------------------------------------
+     684             :   // [VirtReg]
+     685             :   // --------------------------------------------------------------------------
+     686             : 
+     687             :   //! Get whether the virtual register `r` is valid.
+     688             :   ASMJIT_INLINE bool isVirtRegValid(const Reg& reg) const noexcept {
+     689             :     return isVirtRegValid(reg.getId());
+     690             :   }
+     691             :   //! \overload
+     692             :   ASMJIT_INLINE bool isVirtRegValid(uint32_t id) const noexcept {
+     693       12200 :     size_t index = Operand::unpackId(id);
+     694             :     return index < _vRegArray.getLength();
+     695             :   }
+     696             : 
+     697             :   //! Get \ref VirtReg associated with the given `r`.
+     698             :   ASMJIT_INLINE VirtReg* getVirtReg(const Reg& reg) const noexcept {
+     699             :     return getVirtRegById(reg.getId());
+     700             :   }
+     701             :   //! Get \ref VirtReg associated with the given `id`.
+     702             :   ASMJIT_INLINE VirtReg* getVirtRegById(uint32_t id) const noexcept {
+     703             :     ASMJIT_ASSERT(id != kInvalidValue);
+     704      116314 :     size_t index = Operand::unpackId(id);
+     705             : 
+     706             :     ASMJIT_ASSERT(index < _vRegArray.getLength());
+     707      128514 :     return _vRegArray[index];
+     708             :   }
+     709             : 
+     710             :   //! Get an array of all virtual registers managed by CodeCompiler.
+     711             :   ASMJIT_INLINE const ZoneVector<VirtReg*>& getVirtRegArray() const noexcept { return _vRegArray; }
+     712             : 
+     713             :   //! Alloc a virtual register `reg`.
+     714             :   ASMJIT_API Error alloc(Reg& reg);
+     715             :   //! Alloc a virtual register `reg` using `physId` as a register id.
+     716             :   ASMJIT_API Error alloc(Reg& reg, uint32_t physId);
+     717             :   //! Alloc a virtual register `reg` using `ref` as a register operand.
+     718             :   ASMJIT_API Error alloc(Reg& reg, const Reg& ref);
+     719             :   //! Spill a virtual register `reg`.
+     720             :   ASMJIT_API Error spill(Reg& reg);
+     721             :   //! Save a virtual register `reg` if the status is `modified` at this point.
+     722             :   ASMJIT_API Error save(Reg& reg);
+     723             :   //! Unuse a virtual register `reg`.
+     724             :   ASMJIT_API Error unuse(Reg& reg);
+     725             : 
+     726             :   //! Get priority of a virtual register `reg`.
+     727             :   ASMJIT_API uint32_t getPriority(Reg& reg) const;
+     728             :   //! Set priority of variable `reg` to `priority`.
+     729             :   ASMJIT_API void setPriority(Reg& reg, uint32_t priority);
+     730             : 
+     731             :   //! Get save-on-unuse `reg` property.
+     732             :   ASMJIT_API bool getSaveOnUnuse(Reg& reg) const;
+     733             :   //! Set save-on-unuse `reg` property to `value`.
+     734             :   ASMJIT_API void setSaveOnUnuse(Reg& reg, bool value);
+     735             : 
+     736             :   //! Rename variable `reg` to `name`.
+     737             :   //!
+     738             :   //! NOTE: Only new name will appear in the logger.
+     739             :   ASMJIT_API void rename(Reg& reg, const char* fmt, ...);
+     740             : 
+     741             :   // --------------------------------------------------------------------------
+     742             :   // [Members]
+     743             :   // --------------------------------------------------------------------------
+     744             : 
+     745             :   CCFunc* _func;                         //!< Current function.
+     746             : 
+     747             :   Zone _vRegZone;                        //!< Allocates \ref VirtReg objects.
+     748             :   ZoneVector<VirtReg*> _vRegArray;       //!< Stores array of \ref VirtReg pointers.
+     749             : 
+     750             :   CBConstPool* _localConstPool;          //!< Local constant pool, flushed at the end of each function.
+     751             :   CBConstPool* _globalConstPool;         //!< Global constant pool, flushed at the end of the compilation.
+     752             : };
+     753             : 
+     754             : //! \}
+     755             : 
+     756             : } // asmjit namespace
+     757             : } // namespace PLMD
+     758             : 
+     759             : // [Api-End]
+     760             : #include "./asmjit_apiend.h"
+     761             : 
+     762             : // [Guard]
+     763             : #endif // !ASMJIT_DISABLE_COMPILER
+     764             : #endif // _ASMJIT_BASE_CODECOMPILER_H
+     765             : #pragma GCC diagnostic pop
+     766             : #endif // __PLUMED_HAS_ASMJIT
+     767             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.cpp.func-sort-c.html b/coverage-libs/asmjit/codeemitter.cpp.func-sort-c.html new file mode 100644 index 000000000000..7362029d8806 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.cpp.func-sort-c.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:329533.7 %
Date:2024-02-22 21:58:47Functions:93129.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11CodeEmitter12_emitOpArrayEjPKNS0_8Operand_Em0
_ZN4PLMD6asmjit11CodeEmitter12setLastErrorEjPKc0
_ZN4PLMD6asmjit11CodeEmitter14getLabelByNameEPKcmj0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEji0
_ZN4PLMD6asmjit11CodeEmitter4emitEjl0
_ZN4PLMD6asmjit11CodeEmitter8commentfEPKcz0
_ZN4PLMD6asmjit11CodeEmitter8commentvEPKcP13__va_list_tag0
_ZN4PLMD6asmjit11CodeEmitter8finalizeEv0
_ZN4PLMD6asmjit11CodeEmitter8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeEmitterD0Ev0
_ZNK4PLMD6asmjit11CodeEmitter12isLabelValidEj0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_120
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_Ei932
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_El932
_ZN4PLMD6asmjit11CodeEmitter4emitEj1948
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_E2240
_ZN4PLMD6asmjit11CodeEmitter8onAttachEPNS0_10CodeHolderE3896
_ZN4PLMD6asmjit11CodeEmitterC2Ej3896
_ZN4PLMD6asmjit11CodeEmitterD2Ev3896
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_40542
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.cpp.func.html b/coverage-libs/asmjit/codeemitter.cpp.func.html new file mode 100644 index 000000000000..1f8dbd49ab58 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.cpp.func.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:329533.7 %
Date:2024-02-22 21:58:47Functions:93129.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11CodeEmitter12_emitOpArrayEjPKNS0_8Operand_Em0
_ZN4PLMD6asmjit11CodeEmitter12setLastErrorEjPKc0
_ZN4PLMD6asmjit11CodeEmitter14getLabelByNameEPKcmj0
_ZN4PLMD6asmjit11CodeEmitter4emitEj1948
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_E2240
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_40542
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_120
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_S4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_i0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_ES4_l0
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_Ei932
_ZN4PLMD6asmjit11CodeEmitter4emitEjRKNS0_8Operand_El932
_ZN4PLMD6asmjit11CodeEmitter4emitEji0
_ZN4PLMD6asmjit11CodeEmitter4emitEjl0
_ZN4PLMD6asmjit11CodeEmitter8commentfEPKcz0
_ZN4PLMD6asmjit11CodeEmitter8commentvEPKcP13__va_list_tag0
_ZN4PLMD6asmjit11CodeEmitter8finalizeEv0
_ZN4PLMD6asmjit11CodeEmitter8onAttachEPNS0_10CodeHolderE3896
_ZN4PLMD6asmjit11CodeEmitter8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit11CodeEmitterC2Ej3896
_ZN4PLMD6asmjit11CodeEmitterD0Ev0
_ZN4PLMD6asmjit11CodeEmitterD2Ev3896
_ZNK4PLMD6asmjit11CodeEmitter12isLabelValidEj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.cpp.gcov.html b/coverage-libs/asmjit/codeemitter.cpp.gcov.html new file mode 100644 index 000000000000..10c88b8e113e --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.cpp.gcov.html @@ -0,0 +1,339 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:329533.7 %
Date:2024-02-22 21:58:47Functions:93129.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./assembler.h"
+      34             : #include "./utils.h"
+      35             : #include "./vmem.h"
+      36             : 
+      37             : #if defined(ASMJIT_BUILD_X86)
+      38             : #include "./x86inst.h"
+      39             : #endif // ASMJIT_BUILD_X86
+      40             : 
+      41             : #if defined(ASMJIT_BUILD_ARM)
+      42             : #include "./arminst.h"
+      43             : #endif // ASMJIT_BUILD_ARM
+      44             : 
+      45             : // [Api-Begin]
+      46             : #include "./asmjit_apibegin.h"
+      47             : 
+      48             : namespace PLMD {
+      49             : namespace asmjit {
+      50             : 
+      51             : // ============================================================================
+      52             : // [asmjit::CodeEmitter - Construction / Destruction]
+      53             : // ============================================================================
+      54             : 
+      55        3896 : CodeEmitter::CodeEmitter(uint32_t type) noexcept
+      56             :   : _codeInfo(),
+      57        3896 :     _code(nullptr),
+      58        3896 :     _nextEmitter(nullptr),
+      59        3896 :     _type(static_cast<uint8_t>(type)),
+      60        3896 :     _destroyed(false),
+      61        3896 :     _finalized(false),
+      62        3896 :     _reserved(false),
+      63        3896 :     _lastError(kErrorNotInitialized),
+      64        3896 :     _privateData(0),
+      65        3896 :     _globalHints(0),
+      66        3896 :     _globalOptions(kOptionMaybeFailureCase),
+      67        3896 :     _options(0),
+      68        3896 :     _extraReg(),
+      69        3896 :     _inlineComment(nullptr),
+      70        3896 :     _none(),
+      71             :     _nativeGpReg(),
+      72        3896 :     _nativeGpArray(nullptr) {}
+      73             : 
+      74        3896 : CodeEmitter::~CodeEmitter() noexcept {
+      75        3896 :   if (_code) {
+      76        3896 :     _destroyed = true;
+      77        3896 :     _code->detach(this);
+      78             :   }
+      79        3896 : }
+      80             : 
+      81             : // ============================================================================
+      82             : // [asmjit::CodeEmitter - Events]
+      83             : // ============================================================================
+      84             : 
+      85        3896 : Error CodeEmitter::onAttach(CodeHolder* code) noexcept {
+      86             :   _codeInfo = code->getCodeInfo();
+      87        3896 :   _lastError = kErrorOk;
+      88             : 
+      89        3896 :   _globalHints = code->getGlobalHints();
+      90        3896 :   _globalOptions = code->getGlobalOptions();
+      91             : 
+      92        3896 :   return kErrorOk;
+      93             : }
+      94             : 
+      95           0 : Error CodeEmitter::onDetach(CodeHolder* code) noexcept {
+      96             :   _codeInfo.reset();
+      97           0 :   _finalized = false;
+      98           0 :   _lastError = kErrorNotInitialized;
+      99             : 
+     100           0 :   _privateData = 0;
+     101           0 :   _globalHints = 0;
+     102           0 :   _globalOptions = kOptionMaybeFailureCase;
+     103             : 
+     104           0 :   _options = 0;
+     105             :   _extraReg.reset();
+     106           0 :   _inlineComment = nullptr;
+     107             : 
+     108             :   _nativeGpReg.reset();
+     109           0 :   _nativeGpArray = nullptr;
+     110             : 
+     111           0 :   return kErrorOk;
+     112             : }
+     113             : 
+     114             : // ============================================================================
+     115             : // [asmjit::CodeEmitter - Code-Generation]
+     116             : // ============================================================================
+     117             : 
+     118           0 : Error CodeEmitter::_emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount) {
+     119             :   const Operand_* op = opArray;
+     120           0 :   switch (opCount) {
+     121           0 :     case 0: return _emit(instId, _none, _none, _none, _none);
+     122           0 :     case 1: return _emit(instId, op[0], _none, _none, _none);
+     123           0 :     case 2: return _emit(instId, op[0], op[1], _none, _none);
+     124           0 :     case 3: return _emit(instId, op[0], op[1], op[2], _none);
+     125           0 :     case 4: return _emit(instId, op[0], op[1], op[2], op[3]);
+     126           0 :     case 5: return _emit(instId, op[0], op[1], op[2], op[3], op[4], _none);
+     127           0 :     case 6: return _emit(instId, op[0], op[1], op[2], op[3], op[4], op[5]);
+     128             : 
+     129             :     default:
+     130             :       return DebugUtils::errored(kErrorInvalidArgument);
+     131             :   }
+     132             : }
+     133             : 
+     134             : // ============================================================================
+     135             : // [asmjit::CodeEmitter - Finalize]
+     136             : // ============================================================================
+     137             : 
+     138           0 : Label CodeEmitter::getLabelByName(const char* name, size_t nameLength, uint32_t parentId) noexcept {
+     139           0 :   return Label(_code ? _code->getLabelIdByName(name, nameLength, parentId) : static_cast<uint32_t>(0));
+     140             : }
+     141             : 
+     142             : // ============================================================================
+     143             : // [asmjit::CodeEmitter - Finalize]
+     144             : // ============================================================================
+     145             : 
+     146           0 : Error CodeEmitter::finalize() {
+     147             :   // Finalization does nothing by default, overridden by `CodeBuilder`.
+     148           0 :   return kErrorOk;
+     149             : }
+     150             : 
+     151             : // ============================================================================
+     152             : // [asmjit::CodeEmitter - Error Handling]
+     153             : // ============================================================================
+     154             : 
+     155           0 : Error CodeEmitter::setLastError(Error error, const char* message) {
+     156             :   // This is fatal, CodeEmitter can't set error without being attached to `CodeHolder`.
+     157             :   ASMJIT_ASSERT(_code != nullptr);
+     158             : 
+     159             :   // Special case used to reset the last error.
+     160           0 :   if (error == kErrorOk) {
+     161           0 :     _lastError = kErrorOk;
+     162           0 :     _globalOptions &= ~kOptionMaybeFailureCase;
+     163           0 :     return kErrorOk;
+     164             :   }
+     165             : 
+     166           0 :   if (!message)
+     167           0 :     message = DebugUtils::errorAsString(error);
+     168             : 
+     169             :   // Logging is skipped if the error is handled by `ErrorHandler`.
+     170           0 :   ErrorHandler* handler = _code->_errorHandler;
+     171           0 :   if (handler && handler->handleError(error, message, this))
+     172             :     return error;
+     173             : 
+     174             :   // The handler->handleError() function may throw an exception or longjmp()
+     175             :   // to terminate the execution of `setLastError()`. This is the reason why
+     176             :   // we have delayed changing the `_error` member until now.
+     177           0 :   _lastError = error;
+     178           0 :   _globalOptions |= kOptionMaybeFailureCase;
+     179             : 
+     180           0 :   return error;
+     181             : }
+     182             : 
+     183             : // ============================================================================
+     184             : // [asmjit::CodeEmitter - Helpers]
+     185             : // ============================================================================
+     186             : 
+     187           0 : bool CodeEmitter::isLabelValid(uint32_t id) const noexcept {
+     188           0 :   size_t index = Operand::unpackId(id);
+     189           0 :   return _code && index < _code->_labels.getLength();
+     190             : }
+     191             : 
+     192           0 : Error CodeEmitter::commentf(const char* fmt, ...) {
+     193           0 :   Error err = _lastError;
+     194           0 :   if (err) return err;
+     195             : 
+     196             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     197           0 :   if (_globalOptions & kOptionLoggingEnabled) {
+     198             :     va_list ap;
+     199           0 :     va_start(ap, fmt);
+     200           0 :     err = _code->_logger->logv(fmt, ap);
+     201           0 :     va_end(ap);
+     202             :   }
+     203             : #else
+     204             :   ASMJIT_UNUSED(fmt);
+     205             : #endif
+     206             : 
+     207             :   return err;
+     208             : }
+     209             : 
+     210           0 : Error CodeEmitter::commentv(const char* fmt, va_list ap) {
+     211           0 :   Error err = _lastError;
+     212           0 :   if (err) return err;
+     213             : 
+     214             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     215           0 :   if (_globalOptions & kOptionLoggingEnabled)
+     216           0 :     err = _code->_logger->logv(fmt, ap);
+     217             : #else
+     218             :   ASMJIT_UNUSED(fmt);
+     219             :   ASMJIT_UNUSED(ap);
+     220             : #endif
+     221             : 
+     222             :   return err;
+     223             : }
+     224             : 
+     225             : // ============================================================================
+     226             : // [asmjit::CodeEmitter - Emit]
+     227             : // ============================================================================
+     228             : 
+     229             : #define OP const Operand_&
+     230             : 
+     231        1948 : Error CodeEmitter::emit(uint32_t instId) { return _emit(instId, _none, _none, _none, _none); }
+     232        2240 : Error CodeEmitter::emit(uint32_t instId, OP o0) { return _emit(instId, o0, _none, _none, _none); }
+     233       40542 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1) { return _emit(instId, o0, o1, _none, _none); }
+     234         120 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2) { return _emit(instId, o0, o1, o2, _none); }
+     235           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3) { return _emit(instId, o0, o1, o2, o3); }
+     236           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4) { return _emit(instId, o0, o1, o2, o3, o4, _none); }
+     237           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, OP o5) { return _emit(instId, o0, o1, o2, o3, o4, o5); }
+     238             : 
+     239           0 : Error CodeEmitter::emit(uint32_t instId, int o0) { return _emit(instId, Imm(o0), _none, _none, _none); }
+     240         932 : Error CodeEmitter::emit(uint32_t instId, OP o0, int o1) { return _emit(instId, o0, Imm(o1), _none, _none); }
+     241           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, int o2) { return _emit(instId, o0, o1, Imm(o2), _none); }
+     242           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, int o3) { return _emit(instId, o0, o1, o2, Imm(o3)); }
+     243           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, int o4) { return _emit(instId, o0, o1, o2, o3, Imm(o4), _none); }
+     244           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, int o5) { return _emit(instId, o0, o1, o2, o3, o4, Imm(o5)); }
+     245             : 
+     246           0 : Error CodeEmitter::emit(uint32_t instId, int64_t o0) { return _emit(instId, Imm(o0), _none, _none, _none); }
+     247         932 : Error CodeEmitter::emit(uint32_t instId, OP o0, int64_t o1) { return _emit(instId, o0, Imm(o1), _none, _none); }
+     248           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, int64_t o2) { return _emit(instId, o0, o1, Imm(o2), _none); }
+     249           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, int64_t o3) { return _emit(instId, o0, o1, o2, Imm(o3)); }
+     250             : 
+     251           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, int64_t o4) { return _emit(instId, o0, o1, o2, o3, Imm(o4), _none); }
+     252           0 : Error CodeEmitter::emit(uint32_t instId, OP o0, OP o1, OP o2, OP o3, OP o4, int64_t o5) { return _emit(instId, o0, o1, o2, o3, o4, Imm(o5)); }
+     253             : 
+     254             : #undef OP
+     255             : 
+     256             : } // asmjit namespace
+     257             : } // namespace PLMD
+     258             : 
+     259             : // [Api-End]
+     260             : #include "./asmjit_apiend.h"
+     261             : #pragma GCC diagnostic pop
+     262             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.h.func-sort-c.html b/coverage-libs/asmjit/codeemitter.h.func-sort-c.html new file mode 100644 index 000000000000..6e812a4af85e --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:91181.8 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.h.func.html b/coverage-libs/asmjit/codeemitter.h.func.html new file mode 100644 index 000000000000..5cf1a701d798 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:91181.8 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeemitter.h.gcov.html b/coverage-libs/asmjit/codeemitter.h.gcov.html new file mode 100644 index 000000000000..18d6832948d8 --- /dev/null +++ b/coverage-libs/asmjit/codeemitter.h.gcov.html @@ -0,0 +1,605 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeemitter.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeemitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:91181.8 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_codeemitter_h
+      21             : #define __PLUMED_asmjit_codeemitter_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_CODEEMITTER_H
+      33             : #define _ASMJIT_BASE_CODEEMITTER_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./arch.h"
+      37             : #include "./codeholder.h"
+      38             : #include "./operand.h"
+      39             : 
+      40             : // [Api-Begin]
+      41             : #include "./asmjit_apibegin.h"
+      42             : 
+      43             : namespace PLMD {
+      44             : namespace asmjit {
+      45             : 
+      46             : //! \addtogroup asmjit_base
+      47             : //! \{
+      48             : 
+      49             : // ============================================================================
+      50             : // [Forward Declarations]
+      51             : // ============================================================================
+      52             : 
+      53             : class ConstPool;
+      54             : 
+      55             : // ============================================================================
+      56             : // [asmjit::CodeEmitter]
+      57             : // ============================================================================
+      58             : 
+      59             : //! Provides a base foundation to emit code - specialized by \ref Assembler and
+      60             : //! \ref CodeBuilder.
+      61             : class ASMJIT_VIRTAPI CodeEmitter {
+      62             : public:
+      63             :   //! CodeEmitter type.
+      64             :   ASMJIT_ENUM(Type) {
+      65             :     kTypeNone       = 0,
+      66             :     kTypeAssembler  = 1,
+      67             :     kTypeBuilder    = 2,
+      68             :     kTypeCompiler   = 3,
+      69             :     kTypeCount      = 4
+      70             :   };
+      71             : 
+      72             :   //! CodeEmitter hints - global settings that affect machine-code generation.
+      73             :   ASMJIT_ENUM(Hints) {
+      74             :     //! Emit optimized code-alignment sequences.
+      75             :     //!
+      76             :     //! Default `true`.
+      77             :     //!
+      78             :     //! X86/X64 Specific
+      79             :     //! ----------------
+      80             :     //!
+      81             :     //! Default align sequence used by X86/X64 architecture is one-byte (0x90)
+      82             :     //! opcode that is often shown by disassemblers as nop. However there are
+      83             :     //! more optimized align sequences for 2-11 bytes that may execute faster.
+      84             :     //! If this feature is enabled AsmJit will generate specialized sequences
+      85             :     //! for alignment between 2 to 11 bytes.
+      86             :     kHintOptimizedAlign = 0x00000001U,
+      87             : 
+      88             :     //! Emit jump-prediction hints.
+      89             :     //!
+      90             :     //! Default `false`.
+      91             :     //!
+      92             :     //! X86/X64 Specific
+      93             :     //! ----------------
+      94             :     //!
+      95             :     //! Jump prediction is usually based on the direction of the jump. If the
+      96             :     //! jump is backward it is usually predicted as taken; and if the jump is
+      97             :     //! forward it is usually predicted as not-taken. The reason is that loops
+      98             :     //! generally use backward jumps and conditions usually use forward jumps.
+      99             :     //! However this behavior can be overridden by using instruction prefixes.
+     100             :     //! If this option is enabled these hints will be emitted.
+     101             :     //!
+     102             :     //! This feature is disabled by default, because the only processor that
+     103             :     //! used to take into consideration prediction hints was P4. Newer processors
+     104             :     //! implement heuristics for branch prediction that ignores any static hints.
+     105             :     kHintPredictedJumps = 0x00000002U
+     106             :   };
+     107             : 
+     108             :   //! CodeEmitter options that are merged with instruction options.
+     109             :   ASMJIT_ENUM(Options) {
+     110             :     //! Reserved, used to check for errors in `Assembler::_emit()`. In addition,
+     111             :     //! if an emitter is in error state it will have `kOptionMaybeFailureCase`
+     112             :     //! set
+     113             :     kOptionMaybeFailureCase = 0x00000001U,
+     114             : 
+     115             :     //! Perform a strict validation before the instruction is emitted.
+     116             :     kOptionStrictValidation = 0x00000002U,
+     117             : 
+     118             :     //! Logging is enabled and `CodeHolder::getLogger()` should return a valid
+     119             :     //! \ref Logger pointer.
+     120             :     kOptionLoggingEnabled   = 0x00000004U,
+     121             : 
+     122             :     //! Mask of all internal options that are not used to represent instruction
+     123             :     //! options, but are used to instrument Assembler and CodeBuilder. These
+     124             :     //! options are internal and should not be used outside of AsmJit itself.
+     125             :     //!
+     126             :     //! NOTE: Reserved options should never appear in `CBInst` options.
+     127             :     kOptionReservedMask = 0x00000007U,
+     128             : 
+     129             :     //! Used only by Assembler to mark `_op4` and `_op5` are used.
+     130             :     kOptionOp4Op5Used = 0x00000008U,
+     131             : 
+     132             :     //! Prevents following a jump during compilation (CodeCompiler).
+     133             :     kOptionUnfollow = 0x00000010U,
+     134             : 
+     135             :     //! Overwrite the destination operand (CodeCompiler).
+     136             :     //!
+     137             :     //! Hint that is important for register liveness analysis. It tells the
+     138             :     //! compiler that the destination operand will be overwritten now or by
+     139             :     //! adjacent instructions. CodeCompiler knows when a register is completely
+     140             :     //! overwritten by a single instruction, for example you don't have to
+     141             :     //! mark "movaps" or "pxor x, x", however, if a pair of instructions is
+     142             :     //! used and the first of them doesn't completely overwrite the content
+     143             :     //! of the destination, CodeCompiler fails to mark that register as dead.
+     144             :     //!
+     145             :     //! X86/X64 Specific
+     146             :     //! ----------------
+     147             :     //!
+     148             :     //!   - All instructions that always overwrite at least the size of the
+     149             :     //!     register the virtual-register uses , for example "mov", "movq",
+     150             :     //!     "movaps" don't need the overwrite option to be used - conversion,
+     151             :     //!     shuffle, and other miscellaneous instructions included.
+     152             :     //!
+     153             :     //!   - All instructions that clear the destination register if all operands
+     154             :     //!     are the same, for example "xor x, x", "pcmpeqb x x", etc...
+     155             :     //!
+     156             :     //!   - Consecutive instructions that partially overwrite the variable until
+     157             :     //!     there is no old content require the `overwrite()` to be used. Some
+     158             :     //!     examples (not always the best use cases thought):
+     159             :     //!
+     160             :     //!     - `movlps xmm0, ?` followed by `movhps xmm0, ?` and vice versa
+     161             :     //!     - `movlpd xmm0, ?` followed by `movhpd xmm0, ?` and vice versa
+     162             :     //!     - `mov al, ?` followed by `and ax, 0xFF`
+     163             :     //!     - `mov al, ?` followed by `mov ah, al`
+     164             :     //!     - `pinsrq xmm0, ?, 0` followed by `pinsrq xmm0, ?, 1`
+     165             :     //!
+     166             :     //!   - If allocated variable is used temporarily for scalar operations. For
+     167             :     //!     example if you allocate a full vector like `X86Compiler::newXmm()`
+     168             :     //!     and then use that vector for scalar operations you should use
+     169             :     //!     `overwrite()` directive:
+     170             :     //!
+     171             :     //!     - `sqrtss x, y` - only LO element of `x` is changed, if you don't use
+     172             :     //!       HI elements, use `X86Compiler.overwrite().sqrtss(x, y)`.
+     173             :     kOptionOverwrite = 0x00000020U
+     174             :   };
+     175             : 
+     176             :   // --------------------------------------------------------------------------
+     177             :   // [Construction / Destruction]
+     178             :   // --------------------------------------------------------------------------
+     179             : 
+     180             :   ASMJIT_API CodeEmitter(uint32_t type) noexcept;
+     181             :   ASMJIT_API virtual ~CodeEmitter() noexcept;
+     182             : 
+     183             :   // --------------------------------------------------------------------------
+     184             :   // [Events]
+     185             :   // --------------------------------------------------------------------------
+     186             : 
+     187             :   //! Called after the \ref CodeEmitter was attached to the \ref CodeHolder.
+     188             :   virtual Error onAttach(CodeHolder* code) noexcept = 0;
+     189             :   //! Called after the \ref CodeEmitter was detached from the \ref CodeHolder.
+     190             :   virtual Error onDetach(CodeHolder* code) noexcept = 0;
+     191             : 
+     192             :   // --------------------------------------------------------------------------
+     193             :   // [Code-Generation]
+     194             :   // --------------------------------------------------------------------------
+     195             : 
+     196             :   //! Emit instruction having max 4 operands.
+     197             :   virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) = 0;
+     198             :   //! Emit instruction having max 6 operands.
+     199             :   virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) = 0;
+     200             :   //! Emit instruction having operands stored in array.
+     201             :   virtual Error _emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount);
+     202             : 
+     203             :   //! Create a new label.
+     204             :   virtual Label newLabel() = 0;
+     205             :   //! Create a new named label.
+     206             :   virtual Label newNamedLabel(
+     207             :     const char* name,
+     208             :     size_t nameLength = Globals::kInvalidIndex,
+     209             :     uint32_t type = Label::kTypeGlobal,
+     210             :     uint32_t parentId = 0) = 0;
+     211             : 
+     212             :   //! Get a label by name.
+     213             :   //!
+     214             :   //! Returns invalid Label in case that the name is invalid or label was not found.
+     215             :   //!
+     216             :   //! NOTE: This function doesn't trigger ErrorHandler in case the name is
+     217             :   //! invalid or no such label exist. You must always check the validity of the
+     218             :   //! \ref Label returned.
+     219             :   ASMJIT_API Label getLabelByName(
+     220             :     const char* name,
+     221             :     size_t nameLength = Globals::kInvalidIndex,
+     222             :     uint32_t parentId = 0) noexcept;
+     223             : 
+     224             :   //! Bind the `label` to the current position of the current section.
+     225             :   //!
+     226             :   //! NOTE: Attempt to bind the same label multiple times will return an error.
+     227             :   virtual Error bind(const Label& label) = 0;
+     228             : 
+     229             :   //! Align to the `alignment` specified.
+     230             :   //!
+     231             :   //! The sequence that is used to fill the gap between the aligned location
+     232             :   //! and the current location depends on the align `mode`, see \ref AlignMode.
+     233             :   virtual Error align(uint32_t mode, uint32_t alignment) = 0;
+     234             : 
+     235             :   //! Embed raw data into the code-buffer.
+     236             :   virtual Error embed(const void* data, uint32_t size) = 0;
+     237             : 
+     238             :   //! Embed absolute label address as data (4 or 8 bytes).
+     239             :   virtual Error embedLabel(const Label& label) = 0;
+     240             : 
+     241             :   //! Embed a constant pool into the code-buffer in the following steps:
+     242             :   //!   1. Align by using kAlignData to the minimum `pool` alignment.
+     243             :   //!   2. Bind `label` so it's bound to an aligned location.
+     244             :   //!   3. Emit constant pool data.
+     245             :   virtual Error embedConstPool(const Label& label, const ConstPool& pool) = 0;
+     246             : 
+     247             :   //! Emit a comment string `s` with an optional `len` parameter.
+     248             :   virtual Error comment(const char* s, size_t len = Globals::kInvalidIndex) = 0;
+     249             : 
+     250             :   // --------------------------------------------------------------------------
+     251             :   // [Code-Generation Status]
+     252             :   // --------------------------------------------------------------------------
+     253             : 
+     254             :   //! Get if the CodeEmitter is initialized (i.e. attached to a \ref CodeHolder).
+     255             :   ASMJIT_INLINE bool isInitialized() const noexcept { return _code != nullptr; }
+     256             : 
+     257             :   ASMJIT_API virtual Error finalize();
+     258             : 
+     259             :   // --------------------------------------------------------------------------
+     260             :   // [Code Information]
+     261             :   // --------------------------------------------------------------------------
+     262             : 
+     263             :   //! Get information about the code, see \ref CodeInfo.
+     264             :   ASMJIT_INLINE const CodeInfo& getCodeInfo() const noexcept { return _codeInfo; }
+     265             :   //! Get \ref CodeHolder this CodeEmitter is attached to.
+     266           0 :   ASMJIT_INLINE CodeHolder* getCode() const noexcept { return _code; }
+     267             : 
+     268             :   //! Get information about the architecture, see \ref ArchInfo.
+     269             :   ASMJIT_INLINE const ArchInfo& getArchInfo() const noexcept { return _codeInfo.getArchInfo(); }
+     270             : 
+     271             :   //! Get if the target architecture is 32-bit.
+     272             :   ASMJIT_INLINE bool is32Bit() const noexcept { return getArchInfo().is32Bit(); }
+     273             :   //! Get if the target architecture is 64-bit.
+     274             :   ASMJIT_INLINE bool is64Bit() const noexcept { return getArchInfo().is64Bit(); }
+     275             : 
+     276             :   //! Get the target architecture type.
+     277             :   ASMJIT_INLINE uint32_t getArchType() const noexcept { return getArchInfo().getType(); }
+     278             :   //! Get the target architecture sub-type.
+     279             :   ASMJIT_INLINE uint32_t getArchSubType() const noexcept { return getArchInfo().getSubType(); }
+     280             :   //! Get the target architecture's GP register size (4 or 8 bytes).
+     281             :   ASMJIT_INLINE uint32_t getGpSize() const noexcept { return getArchInfo().getGpSize(); }
+     282             :   //! Get the number of target GP registers.
+     283             :   ASMJIT_INLINE uint32_t getGpCount() const noexcept { return getArchInfo().getGpCount(); }
+     284             : 
+     285             :   // --------------------------------------------------------------------------
+     286             :   // [Code-Emitter Type]
+     287             :   // --------------------------------------------------------------------------
+     288             : 
+     289             :   //! Get the type of this CodeEmitter, see \ref Type.
+     290        7792 :   ASMJIT_INLINE uint32_t getType() const noexcept { return _type; }
+     291             : 
+     292             :   ASMJIT_INLINE bool isAssembler() const noexcept { return _type == kTypeAssembler; }
+     293             :   ASMJIT_INLINE bool isCodeBuilder() const noexcept { return _type == kTypeBuilder; }
+     294             :   ASMJIT_INLINE bool isCodeCompiler() const noexcept { return _type == kTypeCompiler; }
+     295             : 
+     296             :   // --------------------------------------------------------------------------
+     297             :   // [Global Information]
+     298             :   // --------------------------------------------------------------------------
+     299             : 
+     300             :   //! Get global hints.
+     301             :   ASMJIT_INLINE uint32_t getGlobalHints() const noexcept { return _globalHints; }
+     302             : 
+     303             :   //! Get global options.
+     304             :   //!
+     305             :   //! Global options are merged with instruction options before the instruction
+     306             :   //! is encoded. These options have some bits reserved that are used for error
+     307             :   //! checking, logging, and strict validation. Other options are globals that
+     308             :   //! affect each instruction, for example if VEX3 is set globally, it will all
+     309             :   //! instructions, even those that don't have such option set.
+     310       98972 :   ASMJIT_INLINE uint32_t getGlobalOptions() const noexcept { return _globalOptions; }
+     311             : 
+     312             :   // --------------------------------------------------------------------------
+     313             :   // [Error Handling]
+     314             :   // --------------------------------------------------------------------------
+     315             : 
+     316             :   //! Get if the object is in error state.
+     317             :   //!
+     318             :   //! Error state means that it does not consume anything unless the error
+     319             :   //! state is reset by calling `resetLastError()`. Use `getLastError()` to
+     320             :   //! get the last error that put the object into the error state.
+     321             :   ASMJIT_INLINE bool isInErrorState() const noexcept { return _lastError != kErrorOk; }
+     322             : 
+     323             :   //! Get the last error code.
+     324             :   ASMJIT_INLINE Error getLastError() const noexcept { return _lastError; }
+     325             :   //! Set the last error code and propagate it through the error handler.
+     326             :   ASMJIT_API Error setLastError(Error error, const char* message = nullptr);
+     327             :   //! Clear the last error code and return `kErrorOk`.
+     328             :   ASMJIT_INLINE Error resetLastError() noexcept { return setLastError(kErrorOk); }
+     329             : 
+     330             :   // --------------------------------------------------------------------------
+     331             :   // [Accessors That Affect the Next Instruction]
+     332             :   // --------------------------------------------------------------------------
+     333             : 
+     334             :   //! Get options of the next instruction.
+     335       95076 :   ASMJIT_INLINE uint32_t getOptions() const noexcept { return _options; }
+     336             :   //! Set options of the next instruction.
+     337       48362 :   ASMJIT_INLINE void setOptions(uint32_t options) noexcept { _options = options; }
+     338             :   //! Add options of the next instruction.
+     339             :   ASMJIT_INLINE void addOptions(uint32_t options) noexcept { _options |= options; }
+     340             :   //! Reset options of the next instruction.
+     341       95076 :   ASMJIT_INLINE void resetOptions() noexcept { _options = 0; }
+     342             : 
+     343             :   //! Get if the extra register operand is valid.
+     344             :   ASMJIT_INLINE bool hasExtraReg() const noexcept { return _extraReg.isValid(); }
+     345             :   //! Get an extra operand that will be used by the next instruction (architecture specific).
+     346             :   ASMJIT_INLINE const RegOnly& getExtraReg() const noexcept { return _extraReg; }
+     347             :   //! Set an extra operand that will be used by the next instruction (architecture specific).
+     348             :   ASMJIT_INLINE void setExtraReg(const Reg& reg) noexcept { _extraReg.init(reg); }
+     349             :   //! Set an extra operand that will be used by the next instruction (architecture specific).
+     350             :   ASMJIT_INLINE void setExtraReg(const RegOnly& reg) noexcept { _extraReg.init(reg); }
+     351             :   //! Reset an extra operand that will be used by the next instruction (architecture specific).
+     352             :   ASMJIT_INLINE void resetExtraReg() noexcept { _extraReg.reset(); }
+     353             : 
+     354             :   //! Get annotation of the next instruction.
+     355       46714 :   ASMJIT_INLINE const char* getInlineComment() const noexcept { return _inlineComment; }
+     356             :   //! Set annotation of the next instruction.
+     357             :   //!
+     358             :   //! NOTE: This string is set back to null by `_emit()`, but until that it has
+     359             :   //! to remain valid as `CodeEmitter` is not required to make a copy of it (and
+     360             :   //! it would be slow to do that for each instruction).
+     361       65238 :   ASMJIT_INLINE void setInlineComment(const char* s) noexcept { _inlineComment = s; }
+     362             :   //! Reset annotation of the next instruction to null.
+     363       98972 :   ASMJIT_INLINE void resetInlineComment() noexcept { _inlineComment = nullptr; }
+     364             : 
+     365             :   // --------------------------------------------------------------------------
+     366             :   // [Helpers]
+     367             :   // --------------------------------------------------------------------------
+     368             : 
+     369             :   //! Get if the `label` is valid (i.e. registered).
+     370             :   ASMJIT_INLINE bool isLabelValid(const Label& label) const noexcept {
+     371           0 :     return isLabelValid(label.getId());
+     372             :   }
+     373             : 
+     374             :   //! Get if the label `id` is valid (i.e. registered).
+     375             :   ASMJIT_API bool isLabelValid(uint32_t id) const noexcept;
+     376             : 
+     377             :   //! Emit a formatted string `fmt`.
+     378             :   ASMJIT_API Error commentf(const char* fmt, ...);
+     379             :   //! Emit a formatted string `fmt` (va_list version).
+     380             :   ASMJIT_API Error commentv(const char* fmt, va_list ap);
+     381             : 
+     382             :   // --------------------------------------------------------------------------
+     383             :   // [Emit]
+     384             :   // --------------------------------------------------------------------------
+     385             : 
+     386             :   // NOTE: These `emit()` helpers are designed to address a code-bloat generated
+     387             :   // by C++ compilers to call a function having many arguments. Each parameter to
+     388             :   // `_emit()` requires code to pass it, which means that if we default to 4
+     389             :   // operand parameters in `_emit()` and instId the C++ compiler would have to
+     390             :   // generate a virtual function call having 5 parameters, which is quite a lot.
+     391             :   // Since by default asm instructions have 2 to 3 operands it's better to
+     392             :   // introduce helpers that pass those and fill all the remaining with `_none`.
+     393             : 
+     394             :   //! Emit an instruction.
+     395             :   ASMJIT_API Error emit(uint32_t instId);
+     396             :   //! \overload
+     397             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0);
+     398             :   //! \overload
+     399             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1);
+     400             :   //! \overload
+     401             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2);
+     402             :   //! \overload
+     403             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3);
+     404             :   //! \overload
+     405             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4);
+     406             :   //! \overload
+     407             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5);
+     408             : 
+     409             :   //! Emit an instruction that has a 32-bit signed immediate operand.
+     410             :   ASMJIT_API Error emit(uint32_t instId, int o0);
+     411             :   //! \overload
+     412             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, int o1);
+     413             :   //! \overload
+     414             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, int o2);
+     415             :   //! \overload
+     416             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, int o3);
+     417             :   //! \overload
+     418             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, int o4);
+     419             :   //! \overload
+     420             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, int o5);
+     421             : 
+     422             :   //! Emit an instruction that has a 64-bit signed immediate operand.
+     423             :   ASMJIT_API Error emit(uint32_t instId, int64_t o0);
+     424             :   //! \overload
+     425             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, int64_t o1);
+     426             :   //! \overload
+     427             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, int64_t o2);
+     428             :   //! \overload
+     429             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, int64_t o3);
+     430             :   //! \overload
+     431             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, int64_t o4);
+     432             :   //! \overload
+     433             :   ASMJIT_API Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, int64_t o5);
+     434             : 
+     435             :   //! \overload
+     436             :   ASMJIT_INLINE Error emit(uint32_t instId, unsigned int o0) {
+     437             :     return emit(instId, static_cast<int64_t>(o0));
+     438             :   }
+     439             :   //! \overload
+     440             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, unsigned int o1) {
+     441             :     return emit(instId, o0, static_cast<int64_t>(o1));
+     442             :   }
+     443             :   //! \overload
+     444             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, unsigned int o2) {
+     445             :     return emit(instId, o0, o1, static_cast<int64_t>(o2));
+     446             :   }
+     447             :   //! \overload
+     448             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, unsigned int o3) {
+     449             :     return emit(instId, o0, o1, o2, static_cast<int64_t>(o3));
+     450             :   }
+     451             :   //! \overload
+     452             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, unsigned int o4) {
+     453             :     return emit(instId, o0, o1, o2, o3, static_cast<int64_t>(o4));
+     454             :   }
+     455             :   //! \overload
+     456             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, unsigned int o5) {
+     457             :     return emit(instId, o0, o1, o2, o3, o4, static_cast<int64_t>(o5));
+     458             :   }
+     459             : 
+     460             :   //! \overload
+     461             :   ASMJIT_INLINE Error emit(uint32_t instId, uint64_t o0) {
+     462             :     return emit(instId, static_cast<int64_t>(o0));
+     463             :   }
+     464             :   //! \overload
+     465             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, uint64_t o1) {
+     466             :     return emit(instId, o0, static_cast<int64_t>(o1));
+     467             :   }
+     468             :   //! \overload
+     469             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, uint64_t o2) {
+     470             :     return emit(instId, o0, o1, static_cast<int64_t>(o2));
+     471             :   }
+     472             :   //! \overload
+     473             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, uint64_t o3) {
+     474             :     return emit(instId, o0, o1, o2, static_cast<int64_t>(o3));
+     475             :   }
+     476             :   //! \overload
+     477             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, uint64_t o4) {
+     478             :     return emit(instId, o0, o1, o2, o3, static_cast<int64_t>(o4));
+     479             :   }
+     480             :   //! \overload
+     481             :   ASMJIT_INLINE Error emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, uint64_t o5) {
+     482             :     return emit(instId, o0, o1, o2, o3, o4, static_cast<int64_t>(o5));
+     483             :   }
+     484             : 
+     485             :   ASMJIT_INLINE Error emitOpArray(uint32_t instId, const Operand_* opArray, size_t opCount) {
+     486       48362 :     return _emitOpArray(instId, opArray, opCount);
+     487             :   }
+     488             : 
+     489             :   // --------------------------------------------------------------------------
+     490             :   // [Members]
+     491             :   // --------------------------------------------------------------------------
+     492             : 
+     493             :   CodeInfo _codeInfo;                    //!< Basic information about the code (matches CodeHolder::_codeInfo).
+     494             :   CodeHolder* _code;                     //!< CodeHolder the CodeEmitter is attached to.
+     495             :   CodeEmitter* _nextEmitter;             //!< Linked list of `CodeEmitter`s attached to the same \ref CodeHolder.
+     496             : 
+     497             :   uint8_t _type;                         //!< See CodeEmitter::Type.
+     498             :   uint8_t _destroyed;                    //!< Set by ~CodeEmitter() before calling `_code->detach()`.
+     499             :   uint8_t _finalized;                    //!< True if the CodeEmitter is finalized (CodeBuilder & CodeCompiler).
+     500             :   uint8_t _reserved;                     //!< \internal
+     501             :   Error _lastError;                      //!< Last error code.
+     502             : 
+     503             :   uint32_t _privateData;                 //!< Internal private data used freely by any CodeEmitter.
+     504             :   uint32_t _globalHints;                 //!< Global hints, always in sync with CodeHolder.
+     505             :   uint32_t _globalOptions;               //!< Global options, combined with `_options` before used by each instruction.
+     506             : 
+     507             :   uint32_t _options;                     //!< Used to pass instruction options        (affects the next instruction).
+     508             :   RegOnly _extraReg;                     //!< Extra register (op-mask {k} on AVX-512) (affects the next instruction).
+     509             :   const char* _inlineComment;            //!< Inline comment of the next instruction  (affects the next instruction).
+     510             : 
+     511             :   Operand_ _none;                        //!< Used to pass unused operands to `_emit()` instead of passing null.
+     512             :   Reg _nativeGpReg;                      //!< Native GP register with zero id.
+     513             :   const Reg* _nativeGpArray;             //!< Array of native registers indexed from zero.
+     514             : };
+     515             : 
+     516             : //! \}
+     517             : 
+     518             : } // asmjit namespace
+     519             : } // namespace PLMD
+     520             : 
+     521             : // [Api-End]
+     522             : #include "./asmjit_apiend.h"
+     523             : 
+     524             : // [Guard]
+     525             : #endif // _ASMJIT_BASE_CODEEMITTER_H
+     526             : #pragma GCC diagnostic pop
+     527             : #endif // __PLUMED_HAS_ASMJIT
+     528             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.cpp.func-sort-c.html b/coverage-libs/asmjit/codeholder.cpp.func-sort-c.html new file mode 100644 index 000000000000..16ea1621e486 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.cpp.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:12025946.3 %
Date:2024-02-22 21:58:47Functions:122548.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CodeHolder12newLabelLinkEPNS0_10LabelEntryEjml0
_ZN4PLMD6asmjit10CodeHolder13newRelocEntryEPPNS0_10RelocEntryEjj0
_ZN4PLMD6asmjit10CodeHolder13reserveBufferEPNS0_10CodeBufferEm0
_ZN4PLMD6asmjit10CodeHolder15newNamedLabelIdERjPKcmjj0
_ZN4PLMD6asmjit10CodeHolder15setErrorHandlerEPNS0_12ErrorHandlerE0
_ZN4PLMD6asmjit10CodeHolder16getLabelIdByNameEPKcmj0
_ZN4PLMD6asmjit10CodeHolder5resetEb0
_ZN4PLMD6asmjit10CodeHolder9setLoggerEPNS0_6LoggerE0
_ZN4PLMD6asmjit12ErrorHandlerC2Ev0
_ZN4PLMD6asmjit12ErrorHandlerD0Ev0
_ZN4PLMD6asmjit12ErrorHandlerD2Ev0
_ZN4PLMD6asmjit12_GLOBAL__N_1L28CodeHolder_hashNameAndFixLenEPKcRm0
_ZN4PLMD6asmjitL26CodeHolder_setGlobalOptionEPNS0_10CodeHolderEjj0
_ZN4PLMD6asmjit10CodeHolder10growBufferEPNS0_10CodeBufferEm1948
_ZN4PLMD6asmjit10CodeHolder4initERKNS0_8CodeInfoE1948
_ZN4PLMD6asmjit10CodeHolderC2Ev1948
_ZN4PLMD6asmjit10CodeHolderD2Ev1948
_ZN4PLMD6asmjitL24CodeHolder_resetInternalEPNS0_10CodeHolderEb1948
_ZN4PLMD6asmjitL26CodeHolder_reserveInternalEPNS0_10CodeHolderEPNS0_10CodeBufferEm1948
_ZNK4PLMD6asmjit10CodeHolder8relocateEPvm1948
_ZN4PLMD6asmjit10CodeHolder10newLabelIdERj3896
_ZN4PLMD6asmjit10CodeHolder4syncEv3896
_ZN4PLMD6asmjit10CodeHolder6attachEPNS0_11CodeEmitterE3896
_ZN4PLMD6asmjit10CodeHolder6detachEPNS0_11CodeEmitterE3896
_ZNK4PLMD6asmjit10CodeHolder11getCodeSizeEv3896
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.cpp.func.html b/coverage-libs/asmjit/codeholder.cpp.func.html new file mode 100644 index 000000000000..43b6cd051799 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.cpp.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:12025946.3 %
Date:2024-02-22 21:58:47Functions:122548.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10CodeHolder10growBufferEPNS0_10CodeBufferEm1948
_ZN4PLMD6asmjit10CodeHolder10newLabelIdERj3896
_ZN4PLMD6asmjit10CodeHolder12newLabelLinkEPNS0_10LabelEntryEjml0
_ZN4PLMD6asmjit10CodeHolder13newRelocEntryEPPNS0_10RelocEntryEjj0
_ZN4PLMD6asmjit10CodeHolder13reserveBufferEPNS0_10CodeBufferEm0
_ZN4PLMD6asmjit10CodeHolder15newNamedLabelIdERjPKcmjj0
_ZN4PLMD6asmjit10CodeHolder15setErrorHandlerEPNS0_12ErrorHandlerE0
_ZN4PLMD6asmjit10CodeHolder16getLabelIdByNameEPKcmj0
_ZN4PLMD6asmjit10CodeHolder4initERKNS0_8CodeInfoE1948
_ZN4PLMD6asmjit10CodeHolder4syncEv3896
_ZN4PLMD6asmjit10CodeHolder5resetEb0
_ZN4PLMD6asmjit10CodeHolder6attachEPNS0_11CodeEmitterE3896
_ZN4PLMD6asmjit10CodeHolder6detachEPNS0_11CodeEmitterE3896
_ZN4PLMD6asmjit10CodeHolder9setLoggerEPNS0_6LoggerE0
_ZN4PLMD6asmjit10CodeHolderC2Ev1948
_ZN4PLMD6asmjit10CodeHolderD2Ev1948
_ZN4PLMD6asmjit12ErrorHandlerC2Ev0
_ZN4PLMD6asmjit12ErrorHandlerD0Ev0
_ZN4PLMD6asmjit12ErrorHandlerD2Ev0
_ZN4PLMD6asmjit12_GLOBAL__N_1L28CodeHolder_hashNameAndFixLenEPKcRm0
_ZN4PLMD6asmjitL24CodeHolder_resetInternalEPNS0_10CodeHolderEb1948
_ZN4PLMD6asmjitL26CodeHolder_reserveInternalEPNS0_10CodeHolderEPNS0_10CodeBufferEm1948
_ZN4PLMD6asmjitL26CodeHolder_setGlobalOptionEPNS0_10CodeHolderEjj0
_ZNK4PLMD6asmjit10CodeHolder11getCodeSizeEv3896
_ZNK4PLMD6asmjit10CodeHolder8relocateEPvm1948
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.cpp.gcov.html b/coverage-libs/asmjit/codeholder.cpp.gcov.html new file mode 100644 index 000000000000..3efbb917005e --- /dev/null +++ b/coverage-libs/asmjit/codeholder.cpp.gcov.html @@ -0,0 +1,800 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:12025946.3 %
Date:2024-02-22 21:58:47Functions:122548.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./assembler.h"
+      34             : #include "./utils.h"
+      35             : #include "./vmem.h"
+      36             : 
+      37             : // [Api-Begin]
+      38             : #include "./asmjit_apibegin.h"
+      39             : 
+      40             : namespace PLMD {
+      41             : namespace asmjit {
+      42             : 
+      43             : // ============================================================================
+      44             : // [asmjit::ErrorHandler]
+      45             : // ============================================================================
+      46             : 
+      47           0 : ErrorHandler::ErrorHandler() noexcept {}
+      48           0 : ErrorHandler::~ErrorHandler() noexcept {}
+      49             : 
+      50             : // ============================================================================
+      51             : // [asmjit::CodeHolder - Utilities]
+      52             : // ============================================================================
+      53             : 
+      54           0 : static void CodeHolder_setGlobalOption(CodeHolder* self, uint32_t clear, uint32_t add) noexcept {
+      55             :   // Modify global options of `CodeHolder` itself.
+      56           0 :   self->_globalOptions = (self->_globalOptions & ~clear) | add;
+      57             : 
+      58             :   // Modify all global options of all `CodeEmitter`s attached.
+      59           0 :   CodeEmitter* emitter = self->_emitters;
+      60           0 :   while (emitter) {
+      61           0 :     emitter->_globalOptions = (emitter->_globalOptions & ~clear) | add;
+      62           0 :     emitter = emitter->_nextEmitter;
+      63             :   }
+      64           0 : }
+      65             : 
+      66        1948 : static void CodeHolder_resetInternal(CodeHolder* self, bool releaseMemory) noexcept {
+      67             :   // Detach all `CodeEmitter`s.
+      68        1948 :   while (self->_emitters)
+      69           0 :     self->detach(self->_emitters);
+      70             : 
+      71             :   // Reset everything into its construction state.
+      72             :   self->_codeInfo.reset();
+      73        1948 :   self->_globalHints = 0;
+      74        1948 :   self->_globalOptions = 0;
+      75        1948 :   self->_logger = nullptr;
+      76        1948 :   self->_errorHandler = nullptr;
+      77             : 
+      78        1948 :   self->_unresolvedLabelsCount = 0;
+      79        1948 :   self->_trampolinesSize = 0;
+      80             : 
+      81             :   // Reset all sections.
+      82             :   size_t numSections = self->_sections.getLength();
+      83        3896 :   for (size_t i = 0; i < numSections; i++) {
+      84        1948 :     SectionEntry* section = self->_sections[i];
+      85        1948 :     if (section->_buffer.hasData() && !section->_buffer.isExternal())
+      86             :       Internal::releaseMemory(section->_buffer._data);
+      87        1948 :     section->_buffer._data = nullptr;
+      88        1948 :     section->_buffer._capacity = 0;
+      89             :   }
+      90             : 
+      91             :   // Reset zone allocator and all containers using it.
+      92        1948 :   ZoneHeap* heap = &self->_baseHeap;
+      93             : 
+      94        1948 :   self->_namedLabels.reset(heap);
+      95             :   self->_relocations.reset();
+      96             :   self->_labels.reset();
+      97             :   self->_sections.reset();
+      98             : 
+      99        1948 :   heap->reset(&self->_baseZone);
+     100        1948 :   self->_baseZone.reset(releaseMemory);
+     101        1948 : }
+     102             : 
+     103             : // ============================================================================
+     104             : // [asmjit::CodeHolder - Construction / Destruction]
+     105             : // ============================================================================
+     106             : 
+     107        1948 : CodeHolder::CodeHolder() noexcept
+     108             :   : _codeInfo(),
+     109        1948 :     _globalHints(0),
+     110        1948 :     _globalOptions(0),
+     111        1948 :     _emitters(nullptr),
+     112        1948 :     _cgAsm(nullptr),
+     113        1948 :     _logger(nullptr),
+     114        1948 :     _errorHandler(nullptr),
+     115        1948 :     _unresolvedLabelsCount(0),
+     116        1948 :     _trampolinesSize(0),
+     117        1948 :     _baseZone(16384 - Zone::kZoneOverhead),
+     118        1948 :     _dataZone(16384 - Zone::kZoneOverhead),
+     119        1948 :     _baseHeap(&_baseZone),
+     120        1948 :     _namedLabels(&_baseHeap) {}
+     121             : 
+     122        1948 : CodeHolder::~CodeHolder() noexcept {
+     123        1948 :   CodeHolder_resetInternal(this, true);
+     124        1948 : }
+     125             : 
+     126             : // ============================================================================
+     127             : // [asmjit::CodeHolder - Init / Reset]
+     128             : // ============================================================================
+     129             : 
+     130        1948 : Error CodeHolder::init(const CodeInfo& info) noexcept {
+     131             :   // Cannot reinitialize if it's locked or there is one or more CodeEmitter
+     132             :   // attached.
+     133        1948 :   if (isInitialized())
+     134             :     return DebugUtils::errored(kErrorAlreadyInitialized);
+     135             : 
+     136             :   // If we are just initializing there should be no emitters attached).
+     137             :   ASMJIT_ASSERT(_emitters == nullptr);
+     138             : 
+     139             :   // Create the default section and insert it to the `_sections` array.
+     140        1948 :   Error err = _sections.willGrow(&_baseHeap);
+     141        1948 :   if (err == kErrorOk) {
+     142        1948 :     SectionEntry* se = _baseZone.allocZeroedT<SectionEntry>();
+     143        1948 :     if (ASMJIT_LIKELY(se)) {
+     144        1948 :       se->_flags = SectionEntry::kFlagExec | SectionEntry::kFlagConst;
+     145             :       se->_setDefaultName('.', 't', 'e', 'x', 't');
+     146             :       _sections.appendUnsafe(se);
+     147             :     }
+     148             :     else {
+     149             :       err = DebugUtils::errored(kErrorNoHeapMemory);
+     150             :     }
+     151             :   }
+     152             : 
+     153        1948 :   if (ASMJIT_UNLIKELY(err)) {
+     154           0 :     _baseZone.reset(false);
+     155           0 :     return err;
+     156             :   }
+     157             :   else {
+     158             :     _codeInfo = info;
+     159        1948 :     return kErrorOk;
+     160             :   }
+     161             : }
+     162             : 
+     163           0 : void CodeHolder::reset(bool releaseMemory) noexcept {
+     164           0 :   CodeHolder_resetInternal(this, releaseMemory);
+     165           0 : }
+     166             : 
+     167             : // ============================================================================
+     168             : // [asmjit::CodeHolder - Attach / Detach]
+     169             : // ============================================================================
+     170             : 
+     171        3896 : Error CodeHolder::attach(CodeEmitter* emitter) noexcept {
+     172             :   // Catch a possible misuse of the API.
+     173        3896 :   if (!emitter)
+     174             :     return DebugUtils::errored(kErrorInvalidArgument);
+     175             : 
+     176             :   uint32_t type = emitter->getType();
+     177        3896 :   if (type == CodeEmitter::kTypeNone || type >= CodeEmitter::kTypeCount)
+     178             :     return DebugUtils::errored(kErrorInvalidState);
+     179             : 
+     180             :   // This is suspicious, but don't fail if `emitter` matches.
+     181        3896 :   if (emitter->_code != nullptr) {
+     182           0 :     if (emitter->_code == this) return kErrorOk;
+     183             :     return DebugUtils::errored(kErrorInvalidState);
+     184             :   }
+     185             : 
+     186             :   // Special case - attach `Assembler`.
+     187             :   CodeEmitter** pSlot = nullptr;
+     188        3896 :   if (type == CodeEmitter::kTypeAssembler) {
+     189        1948 :     if (_cgAsm)
+     190             :       return DebugUtils::errored(kErrorSlotOccupied);
+     191        1948 :     pSlot = reinterpret_cast<CodeEmitter**>(&_cgAsm);
+     192             :   }
+     193             : 
+     194        3896 :   Error err = emitter->onAttach(this);
+     195        3896 :   if (err != kErrorOk) return err;
+     196             : 
+     197             :   // Add to a single-linked list of `CodeEmitter`s.
+     198        3896 :   emitter->_nextEmitter = _emitters;
+     199        3896 :   _emitters = emitter;
+     200        3896 :   if (pSlot) *pSlot = emitter;
+     201             : 
+     202             :   // Establish the connection.
+     203        3896 :   emitter->_code = this;
+     204        3896 :   return kErrorOk;
+     205             : }
+     206             : 
+     207        3896 : Error CodeHolder::detach(CodeEmitter* emitter) noexcept {
+     208        3896 :   if (!emitter)
+     209             :     return DebugUtils::errored(kErrorInvalidArgument);
+     210             : 
+     211        3896 :   if (emitter->_code != this)
+     212             :     return DebugUtils::errored(kErrorInvalidState);
+     213             : 
+     214             :   uint32_t type = emitter->getType();
+     215             :   Error err = kErrorOk;
+     216             : 
+     217             :   // NOTE: We always detach if we were asked to, if error happens during
+     218             :   // `emitter->onDetach()` we just propagate it, but the CodeEmitter will
+     219             :   // be detached.
+     220        3896 :   if (!emitter->_destroyed) {
+     221           0 :     if (type == CodeEmitter::kTypeAssembler)
+     222           0 :       static_cast<Assembler*>(emitter)->sync();
+     223           0 :     err = emitter->onDetach(this);
+     224             :   }
+     225             : 
+     226             :   // Special case - detach `Assembler`.
+     227        3896 :   if (type == CodeEmitter::kTypeAssembler)
+     228        1948 :     _cgAsm = nullptr;
+     229             : 
+     230             :   // Remove from a single-linked list of `CodeEmitter`s.
+     231        3896 :   CodeEmitter** pPrev = &_emitters;
+     232             :   for (;;) {
+     233             :     ASMJIT_ASSERT(*pPrev != nullptr);
+     234        3896 :     CodeEmitter* cur = *pPrev;
+     235             : 
+     236        3896 :     if (cur == emitter) {
+     237        3896 :       *pPrev = emitter->_nextEmitter;
+     238             :       break;
+     239             :     }
+     240             : 
+     241           0 :     pPrev = &cur->_nextEmitter;
+     242           0 :   }
+     243             : 
+     244        3896 :   emitter->_code = nullptr;
+     245        3896 :   emitter->_nextEmitter = nullptr;
+     246             : 
+     247        3896 :   return err;
+     248             : }
+     249             : 
+     250             : // ============================================================================
+     251             : // [asmjit::CodeHolder - Sync]
+     252             : // ============================================================================
+     253             : 
+     254        3896 : void CodeHolder::sync() noexcept {
+     255        3896 :   if (_cgAsm) _cgAsm->sync();
+     256        3896 : }
+     257             : 
+     258             : // ============================================================================
+     259             : // [asmjit::CodeHolder - Result Information]
+     260             : // ============================================================================
+     261             : 
+     262        3896 : size_t CodeHolder::getCodeSize() const noexcept {
+     263             :   // Reflect all changes first.
+     264        3896 :   const_cast<CodeHolder*>(this)->sync();
+     265             : 
+     266             :   // TODO: Support sections.
+     267        3896 :   return _sections[0]->_buffer._length + getTrampolinesSize();
+     268             : }
+     269             : 
+     270             : // ============================================================================
+     271             : // [asmjit::CodeHolder - Logging & Error Handling]
+     272             : // ============================================================================
+     273             : 
+     274             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     275           0 : void CodeHolder::setLogger(Logger* logger) noexcept {
+     276             :   uint32_t opt = 0;
+     277           0 :   if (logger) opt = CodeEmitter::kOptionLoggingEnabled;
+     278             : 
+     279           0 :   _logger = logger;
+     280           0 :   CodeHolder_setGlobalOption(this, CodeEmitter::kOptionLoggingEnabled, opt);
+     281           0 : }
+     282             : #endif // !ASMJIT_DISABLE_LOGGING
+     283             : 
+     284           0 : Error CodeHolder::setErrorHandler(ErrorHandler* handler) noexcept {
+     285           0 :   _errorHandler = handler;
+     286           0 :   return kErrorOk;
+     287             : }
+     288             : 
+     289             : // ============================================================================
+     290             : // [asmjit::CodeHolder - Sections]
+     291             : // ============================================================================
+     292             : 
+     293        1948 : static Error CodeHolder_reserveInternal(CodeHolder* self, CodeBuffer* cb, size_t n) noexcept {
+     294        1948 :   uint8_t* oldData = cb->_data;
+     295             :   uint8_t* newData;
+     296             : 
+     297        1948 :   if (oldData && !cb->isExternal())
+     298             :     newData = static_cast<uint8_t*>(Internal::reallocMemory(oldData, n));
+     299             :   else
+     300             :     newData = static_cast<uint8_t*>(Internal::allocMemory(n));
+     301             : 
+     302        1948 :   if (ASMJIT_UNLIKELY(!newData))
+     303             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     304             : 
+     305        1948 :   cb->_data = newData;
+     306        1948 :   cb->_capacity = n;
+     307             : 
+     308             :   // Update the `Assembler` pointers if attached. Maybe we should introduce an
+     309             :   // event for this, but since only one Assembler can be attached at a time it
+     310             :   // should not matter how these pointers are updated.
+     311        1948 :   Assembler* a = self->_cgAsm;
+     312        1948 :   if (a && &a->_section->_buffer == cb) {
+     313             :     size_t offset = a->getOffset();
+     314             : 
+     315        1948 :     a->_bufferData = newData;
+     316        1948 :     a->_bufferEnd  = newData + n;
+     317        1948 :     a->_bufferPtr  = newData + offset;
+     318             :   }
+     319             : 
+     320             :   return kErrorOk;
+     321             : }
+     322             : 
+     323        1948 : Error CodeHolder::growBuffer(CodeBuffer* cb, size_t n) noexcept {
+     324             :   // This is most likely called by `Assembler` so `sync()` shouldn't be needed,
+     325             :   // however, if this is called by the user and the currently attached Assembler
+     326             :   // did generate some code we could lose that, so sync now and make sure the
+     327             :   // section length is updated.
+     328        1948 :   if (_cgAsm) _cgAsm->sync();
+     329             : 
+     330             :   // Now the length of the section must be valid.
+     331             :   size_t length = cb->getLength();
+     332        1948 :   if (ASMJIT_UNLIKELY(n > IntTraits<uintptr_t>::maxValue() - length))
+     333             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     334             : 
+     335             :   // We can now check if growing the buffer is really necessary. It's unlikely
+     336             :   // that this function is called while there is still room for `n` bytes.
+     337             :   size_t capacity = cb->getCapacity();
+     338        1948 :   size_t required = cb->getLength() + n;
+     339        1948 :   if (ASMJIT_UNLIKELY(required <= capacity)) return kErrorOk;
+     340             : 
+     341        1948 :   if (cb->isFixedSize())
+     342             :     return DebugUtils::errored(kErrorCodeTooLarge);
+     343             : 
+     344        1948 :   if (capacity < 8096)
+     345             :     capacity = 8096;
+     346             :   else
+     347           0 :     capacity += Globals::kAllocOverhead;
+     348             : 
+     349             :   do {
+     350             :     size_t old = capacity;
+     351        1948 :     if (capacity < Globals::kAllocThreshold)
+     352        1948 :       capacity *= 2;
+     353             :     else
+     354           0 :       capacity += Globals::kAllocThreshold;
+     355             : 
+     356        1948 :     if (capacity < Globals::kAllocThreshold)
+     357        1948 :       capacity *= 2;
+     358             :     else
+     359           0 :       capacity += Globals::kAllocThreshold;
+     360             : 
+     361             :     // Overflow.
+     362        1948 :     if (ASMJIT_UNLIKELY(old > capacity))
+     363             :       return DebugUtils::errored(kErrorNoHeapMemory);
+     364        1948 :   } while (capacity - Globals::kAllocOverhead < required);
+     365             : 
+     366        1948 :   return CodeHolder_reserveInternal(this, cb, capacity - Globals::kAllocOverhead);
+     367             : }
+     368             : 
+     369           0 : Error CodeHolder::reserveBuffer(CodeBuffer* cb, size_t n) noexcept {
+     370             :   size_t capacity = cb->getCapacity();
+     371           0 :   if (n <= capacity) return kErrorOk;
+     372             : 
+     373           0 :   if (cb->isFixedSize())
+     374             :     return DebugUtils::errored(kErrorCodeTooLarge);
+     375             : 
+     376             :   // We must sync, as mentioned in `growBuffer()` as well.
+     377           0 :   if (_cgAsm) _cgAsm->sync();
+     378             : 
+     379           0 :   return CodeHolder_reserveInternal(this, cb, n);
+     380             : }
+     381             : 
+     382             : // ============================================================================
+     383             : // [asmjit::CodeHolder - Labels & Symbols]
+     384             : // ============================================================================
+     385             : 
+     386             : namespace {
+     387             : 
+     388             : //! \internal
+     389             : //!
+     390             : //! Only used to lookup a label from `_namedLabels`.
+     391             : class LabelByName {
+     392             : public:
+     393             :   ASMJIT_INLINE LabelByName(const char* name, size_t nameLength, uint32_t hVal) noexcept
+     394             :     : name(name),
+     395           0 :       nameLength(static_cast<uint32_t>(nameLength)),
+     396             :       hVal(hVal) {}
+     397             : 
+     398             :   ASMJIT_INLINE bool matches(const LabelEntry* entry) const noexcept {
+     399           0 :     return static_cast<uint32_t>(entry->getNameLength()) == nameLength &&
+     400           0 :            ::memcmp(entry->getName(), name, nameLength) == 0;
+     401             :   }
+     402             : 
+     403             :   const char* name;
+     404             :   uint32_t nameLength;
+     405             :   uint32_t hVal;
+     406             : };
+     407             : 
+     408             : // Returns a hash of `name` and fixes `nameLength` if it's `Globals::kInvalidIndex`.
+     409           0 : static uint32_t CodeHolder_hashNameAndFixLen(const char* name, size_t& nameLength) noexcept {
+     410             :   uint32_t hVal = 0;
+     411           0 :   if (nameLength == Globals::kInvalidIndex) {
+     412             :     size_t i = 0;
+     413             :     for (;;) {
+     414           0 :       uint8_t c = static_cast<uint8_t>(name[i]);
+     415           0 :       if (!c) break;
+     416           0 :       hVal = Utils::hashRound(hVal, c);
+     417           0 :       i++;
+     418           0 :     }
+     419           0 :     nameLength = i;
+     420             :   }
+     421             :   else {
+     422           0 :     for (size_t i = 0; i < nameLength; i++) {
+     423           0 :       uint8_t c = static_cast<uint8_t>(name[i]);
+     424           0 :       if (ASMJIT_UNLIKELY(!c)) return DebugUtils::errored(kErrorInvalidLabelName);
+     425           0 :       hVal = Utils::hashRound(hVal, c);
+     426             :     }
+     427             :   }
+     428             :   return hVal;
+     429             : }
+     430             : 
+     431             : } // anonymous namespace
+     432             : 
+     433           0 : LabelLink* CodeHolder::newLabelLink(LabelEntry* le, uint32_t sectionId, size_t offset, intptr_t rel) noexcept {
+     434           0 :   LabelLink* link = _baseHeap.allocT<LabelLink>();
+     435           0 :   if (ASMJIT_UNLIKELY(!link)) return nullptr;
+     436             : 
+     437           0 :   link->prev = le->_links;
+     438           0 :   le->_links = link;
+     439             : 
+     440           0 :   link->sectionId = sectionId;
+     441           0 :   link->relocId = RelocEntry::kInvalidId;
+     442           0 :   link->offset = offset;
+     443           0 :   link->rel = rel;
+     444             : 
+     445           0 :   _unresolvedLabelsCount++;
+     446           0 :   return link;
+     447             : }
+     448             : 
+     449        3896 : Error CodeHolder::newLabelId(uint32_t& idOut) noexcept {
+     450        3896 :   idOut = 0;
+     451             : 
+     452             :   size_t index = _labels.getLength();
+     453        3896 :   if (ASMJIT_LIKELY(index >= Operand::kPackedIdCount))
+     454             :     return DebugUtils::errored(kErrorLabelIndexOverflow);
+     455             : 
+     456        5844 :   ASMJIT_PROPAGATE(_labels.willGrow(&_baseHeap));
+     457        3896 :   LabelEntry* le = _baseHeap.allocZeroedT<LabelEntry>();
+     458             : 
+     459        3896 :   if (ASMJIT_UNLIKELY(!le))
+     460             :     return DebugUtils::errored(kErrorNoHeapMemory);;
+     461             : 
+     462        3896 :   uint32_t id = Operand::packId(static_cast<uint32_t>(index));
+     463             :   le->_setId(id);
+     464        3896 :   le->_parentId = 0;
+     465        3896 :   le->_sectionId = SectionEntry::kInvalidId;
+     466        3896 :   le->_offset = 0;
+     467             : 
+     468             :   _labels.appendUnsafe(le);
+     469        3896 :   idOut = id;
+     470        3896 :   return kErrorOk;
+     471             : }
+     472             : 
+     473           0 : Error CodeHolder::newNamedLabelId(uint32_t& idOut, const char* name, size_t nameLength, uint32_t type, uint32_t parentId) noexcept {
+     474           0 :   idOut = 0;
+     475           0 :   uint32_t hVal = CodeHolder_hashNameAndFixLen(name, nameLength);
+     476             : 
+     477           0 :   if (ASMJIT_UNLIKELY(nameLength == 0))
+     478             :     return DebugUtils::errored(kErrorInvalidLabelName);
+     479             : 
+     480           0 :   if (ASMJIT_UNLIKELY(nameLength > Globals::kMaxLabelLength))
+     481             :     return DebugUtils::errored(kErrorLabelNameTooLong);
+     482             : 
+     483           0 :   switch (type) {
+     484             :     case Label::kTypeLocal:
+     485           0 :       if (ASMJIT_UNLIKELY(Operand::unpackId(parentId) >= _labels.getLength()))
+     486             :         return DebugUtils::errored(kErrorInvalidParentLabel);
+     487             : 
+     488           0 :       hVal ^= parentId;
+     489           0 :       break;
+     490             : 
+     491           0 :     case Label::kTypeGlobal:
+     492           0 :       if (ASMJIT_UNLIKELY(parentId != 0))
+     493             :         return DebugUtils::errored(kErrorNonLocalLabelCantHaveParent);
+     494             : 
+     495             :       break;
+     496             : 
+     497             :     default:
+     498             :       return DebugUtils::errored(kErrorInvalidArgument);
+     499             :   }
+     500             : 
+     501             :   // Don't allow to insert duplicates. Local labels allow duplicates that have
+     502             :   // different id, this is already accomplished by having a different hashes
+     503             :   // between the same label names having different parent labels.
+     504           0 :   LabelEntry* le = _namedLabels.get(LabelByName(name, nameLength, hVal));
+     505           0 :   if (ASMJIT_UNLIKELY(le))
+     506             :     return DebugUtils::errored(kErrorLabelAlreadyDefined);
+     507             : 
+     508             :   Error err = kErrorOk;
+     509             :   size_t index = _labels.getLength();
+     510             : 
+     511           0 :   if (ASMJIT_UNLIKELY(index >= Operand::kPackedIdCount))
+     512             :     return DebugUtils::errored(kErrorLabelIndexOverflow);
+     513             : 
+     514           0 :   ASMJIT_PROPAGATE(_labels.willGrow(&_baseHeap));
+     515           0 :   le = _baseHeap.allocZeroedT<LabelEntry>();
+     516             : 
+     517           0 :   if (ASMJIT_UNLIKELY(!le))
+     518             :     return  DebugUtils::errored(kErrorNoHeapMemory);
+     519             : 
+     520           0 :   uint32_t id = Operand::packId(static_cast<uint32_t>(index));
+     521           0 :   le->_hVal = hVal;
+     522             :   le->_setId(id);
+     523           0 :   le->_type = static_cast<uint8_t>(type);
+     524           0 :   le->_parentId = 0;
+     525           0 :   le->_sectionId = SectionEntry::kInvalidId;
+     526           0 :   le->_offset = 0;
+     527             : 
+     528           0 :   if (le->_name.mustEmbed(nameLength)) {
+     529             :     le->_name.setEmbedded(name, nameLength);
+     530             :   }
+     531             :   else {
+     532           0 :     char* nameExternal = static_cast<char*>(_dataZone.dup(name, nameLength, true));
+     533           0 :     if (ASMJIT_UNLIKELY(!nameExternal))
+     534             :       return DebugUtils::errored(kErrorNoHeapMemory);
+     535           0 :     le->_name.setExternal(nameExternal, nameLength);
+     536             :   }
+     537             : 
+     538             :   _labels.appendUnsafe(le);
+     539             :   _namedLabels.put(le);
+     540             : 
+     541           0 :   idOut = id;
+     542           0 :   return err;
+     543             : }
+     544             : 
+     545           0 : uint32_t CodeHolder::getLabelIdByName(const char* name, size_t nameLength, uint32_t parentId) noexcept {
+     546           0 :   uint32_t hVal = CodeHolder_hashNameAndFixLen(name, nameLength);
+     547           0 :   if (ASMJIT_UNLIKELY(!nameLength)) return 0;
+     548             : 
+     549             :   LabelEntry* le = _namedLabels.get(LabelByName(name, nameLength, hVal));
+     550           0 :   return le ? le->getId() : static_cast<uint32_t>(0);
+     551             : }
+     552             : 
+     553             : // ============================================================================
+     554             : // [asmjit::CodeEmitter - Relocations]
+     555             : // ============================================================================
+     556             : 
+     557             : //! Encode MOD byte.
+     558             : static ASMJIT_INLINE uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm) noexcept {
+     559             :   return (m << 6) | (o << 3) | rm;
+     560             : }
+     561             : 
+     562           0 : Error CodeHolder::newRelocEntry(RelocEntry** dst, uint32_t type, uint32_t size) noexcept {
+     563           0 :   ASMJIT_PROPAGATE(_relocations.willGrow(&_baseHeap));
+     564             : 
+     565             :   size_t index = _relocations.getLength();
+     566           0 :   if (ASMJIT_UNLIKELY(index > size_t(0xFFFFFFFFU)))
+     567             :     return DebugUtils::errored(kErrorRelocIndexOverflow);
+     568             : 
+     569           0 :   RelocEntry* re = _baseHeap.allocZeroedT<RelocEntry>();
+     570           0 :   if (ASMJIT_UNLIKELY(!re))
+     571             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     572             : 
+     573           0 :   re->_id = static_cast<uint32_t>(index);
+     574           0 :   re->_type = static_cast<uint8_t>(type);
+     575           0 :   re->_size = static_cast<uint8_t>(size);
+     576           0 :   re->_sourceSectionId = SectionEntry::kInvalidId;
+     577           0 :   re->_targetSectionId = SectionEntry::kInvalidId;
+     578             :   _relocations.appendUnsafe(re);
+     579             : 
+     580           0 :   *dst = re;
+     581           0 :   return kErrorOk;
+     582             : }
+     583             : 
+     584             : // TODO: Support multiple sections, this only relocates the first.
+     585             : // TODO: This should go to Runtime as it's responsible for relocating the
+     586             : //       code, CodeHolder should just hold it.
+     587        1948 : size_t CodeHolder::relocate(void* _dst, uint64_t baseAddress) const noexcept {
+     588        1948 :   SectionEntry* section = _sections[0];
+     589             :   ASMJIT_ASSERT(section != nullptr);
+     590             : 
+     591             :   uint8_t* dst = static_cast<uint8_t*>(_dst);
+     592        1948 :   if (baseAddress == Globals::kNoBaseAddress)
+     593        1948 :     baseAddress = static_cast<uint64_t>((uintptr_t)dst);
+     594             : 
+     595             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     596             :   Logger* logger = getLogger();
+     597             : #endif // ASMJIT_DISABLE_LOGGING
+     598             : 
+     599             :   size_t minCodeSize = section->getBuffer().getLength(); // Minimum code size.
+     600        1948 :   size_t maxCodeSize = getCodeSize();                    // Includes all possible trampolines.
+     601             : 
+     602             :   // We will copy the exact size of the generated code. Extra code for trampolines
+     603             :   // is generated on-the-fly by the relocator (this code doesn't exist at the moment).
+     604        1948 :   ::memcpy(dst, section->_buffer._data, minCodeSize);
+     605             : 
+     606             :   // Trampoline offset from the beginning of dst/baseAddress.
+     607             :   size_t trampOffset = minCodeSize;
+     608             : 
+     609             :   // Relocate all recorded locations.
+     610             :   size_t numRelocs = _relocations.getLength();
+     611             :   const RelocEntry* const* reArray = _relocations.getData();
+     612             : 
+     613        1948 :   for (size_t i = 0; i < numRelocs; i++) {
+     614           0 :     const RelocEntry* re = reArray[i];
+     615             : 
+     616             :     // Possibly deleted or optimized out relocation entry.
+     617           0 :     if (re->getType() == RelocEntry::kTypeNone)
+     618           0 :       continue;
+     619             : 
+     620             :     uint64_t ptr = re->getData();
+     621             :     size_t codeOffset = static_cast<size_t>(re->getSourceOffset());
+     622             : 
+     623             :     // Make sure that the `RelocEntry` is correct, we don't want to write
+     624             :     // out of bounds in `dst`.
+     625           0 :     if (ASMJIT_UNLIKELY(codeOffset + re->getSize() > maxCodeSize))
+     626             :       return DebugUtils::errored(kErrorInvalidRelocEntry);
+     627             : 
+     628             :     // Whether to use trampoline, can be only used if relocation type is `kRelocTrampoline`.
+     629             :     bool useTrampoline = false;
+     630             : 
+     631           0 :     switch (re->getType()) {
+     632             :       case RelocEntry::kTypeAbsToAbs: {
+     633             :         break;
+     634             :       }
+     635             : 
+     636           0 :       case RelocEntry::kTypeRelToAbs: {
+     637           0 :         ptr += baseAddress;
+     638           0 :         break;
+     639             :       }
+     640             : 
+     641             :       case RelocEntry::kTypeAbsToRel: {
+     642           0 :         ptr -= baseAddress + re->getSourceOffset() + re->getSize();
+     643           0 :         break;
+     644             :       }
+     645             : 
+     646             :       case RelocEntry::kTypeTrampoline: {
+     647           0 :         if (re->getSize() != 4)
+     648             :           return DebugUtils::errored(kErrorInvalidRelocEntry);
+     649             : 
+     650           0 :         ptr -= baseAddress + re->getSourceOffset() + re->getSize();
+     651           0 :         if (!Utils::isInt32(static_cast<int64_t>(ptr))) {
+     652           0 :           ptr = (uint64_t)trampOffset - re->getSourceOffset() - re->getSize();
+     653             :           useTrampoline = true;
+     654             :         }
+     655             :         break;
+     656             :       }
+     657             : 
+     658             :       default:
+     659             :         return DebugUtils::errored(kErrorInvalidRelocEntry);
+     660             :     }
+     661             : 
+     662           0 :     switch (re->getSize()) {
+     663           0 :       case 1:
+     664           0 :         Utils::writeU8(dst + codeOffset, static_cast<uint32_t>(ptr & 0xFFU));
+     665             :         break;
+     666             : 
+     667           0 :       case 4:
+     668           0 :         Utils::writeU32u(dst + codeOffset, static_cast<uint32_t>(ptr & 0xFFFFFFFFU));
+     669             :         break;
+     670             : 
+     671           0 :       case 8:
+     672           0 :         Utils::writeU64u(dst + codeOffset, ptr);
+     673             :         break;
+     674             : 
+     675             :       default:
+     676             :         return DebugUtils::errored(kErrorInvalidRelocEntry);
+     677             :     }
+     678             : 
+     679             :     // Handle the trampoline case.
+     680           0 :     if (useTrampoline) {
+     681             :       // Bytes that replace [REX, OPCODE] bytes.
+     682             :       uint32_t byte0 = 0xFF;
+     683           0 :       uint32_t byte1 = dst[codeOffset - 1];
+     684             : 
+     685           0 :       if (byte1 == 0xE8) {
+     686             :         // Patch CALL/MOD byte to FF/2 (-> 0x15).
+     687             :         byte1 = x86EncodeMod(0, 2, 5);
+     688             :       }
+     689           0 :       else if (byte1 == 0xE9) {
+     690             :         // Patch JMP/MOD byte to FF/4 (-> 0x25).
+     691             :         byte1 = x86EncodeMod(0, 4, 5);
+     692             :       }
+     693             :       else {
+     694             :         return DebugUtils::errored(kErrorInvalidRelocEntry);
+     695             :       }
+     696             : 
+     697             :       // Patch `jmp/call` instruction.
+     698             :       ASMJIT_ASSERT(codeOffset >= 2);
+     699           0 :       dst[codeOffset - 2] = static_cast<uint8_t>(byte0);
+     700           0 :       dst[codeOffset - 1] = static_cast<uint8_t>(byte1);
+     701             : 
+     702             :       // Store absolute address and advance the trampoline pointer.
+     703           0 :       Utils::writeU64u(dst + trampOffset, re->getData());
+     704           0 :       trampOffset += 8;
+     705             : 
+     706             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     707           0 :       if (logger)
+     708           0 :         logger->logf("[reloc] dq 0x%016llX ; Trampoline\n", re->getData());
+     709             : #endif // !ASMJIT_DISABLE_LOGGING
+     710             :     }
+     711             :   }
+     712             : 
+     713             :   // If there are no trampolines this is the same as `minCodeSize`.
+     714             :   return trampOffset;
+     715             : }
+     716             : 
+     717             : } // asmjit namespace
+     718             : } // namespace PLMD
+     719             : 
+     720             : // [Api-End]
+     721             : #include "./asmjit_apiend.h"
+     722             : #pragma GCC diagnostic pop
+     723             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.h.func-sort-c.html b/coverage-libs/asmjit/codeholder.h.func-sort-c.html new file mode 100644 index 000000000000..038bf2772486 --- /dev/null +++ b/coverage-libs/asmjit/codeholder.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:324178.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.h.func.html b/coverage-libs/asmjit/codeholder.h.func.html new file mode 100644 index 000000000000..b961205f174c --- /dev/null +++ b/coverage-libs/asmjit/codeholder.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:324178.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/codeholder.h.gcov.html b/coverage-libs/asmjit/codeholder.h.gcov.html new file mode 100644 index 000000000000..7dd56c65c68f --- /dev/null +++ b/coverage-libs/asmjit/codeholder.h.gcov.html @@ -0,0 +1,854 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/codeholder.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - codeholder.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:324178.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_codeholder_h
+      21             : #define __PLUMED_asmjit_codeholder_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_CODEHOLDER_H
+      33             : #define _ASMJIT_BASE_CODEHOLDER_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./arch.h"
+      37             : #include "./func.h"
+      38             : #include "./logging.h"
+      39             : #include "./operand.h"
+      40             : #include "./simdtypes.h"
+      41             : #include "./utils.h"
+      42             : #include "./zone.h"
+      43             : 
+      44             : // [Api-Begin]
+      45             : #include "./asmjit_apibegin.h"
+      46             : 
+      47             : namespace PLMD {
+      48             : namespace asmjit {
+      49             : 
+      50             : //! \addtogroup asmjit_base
+      51             : //! \{
+      52             : 
+      53             : // ============================================================================
+      54             : // [Forward Declarations]
+      55             : // ============================================================================
+      56             : 
+      57             : class Assembler;
+      58             : class CodeEmitter;
+      59             : class CodeHolder;
+      60             : 
+      61             : // ============================================================================
+      62             : // [asmjit::AlignMode]
+      63             : // ============================================================================
+      64             : 
+      65             : //! Align mode.
+      66             : ASMJIT_ENUM(AlignMode) {
+      67             :   kAlignCode = 0,                        //!< Align executable code.
+      68             :   kAlignData = 1,                        //!< Align non-executable code.
+      69             :   kAlignZero = 2,                        //!< Align by a sequence of zeros.
+      70             :   kAlignCount                            //!< Count of alignment modes.
+      71             : };
+      72             : 
+      73             : // ============================================================================
+      74             : // [asmjit::ErrorHandler]
+      75             : // ============================================================================
+      76             : 
+      77             : //! Error handler can be used to override the default behavior of error handling
+      78             : //! available to all classes that inherit \ref CodeEmitter. See \ref handleError().
+      79             : class ASMJIT_VIRTAPI ErrorHandler {
+      80             : public:
+      81             :   // --------------------------------------------------------------------------
+      82             :   // [Construction / Destruction]
+      83             :   // --------------------------------------------------------------------------
+      84             : 
+      85             :   //! Create a new `ErrorHandler` instance.
+      86             :   ASMJIT_API ErrorHandler() noexcept;
+      87             :   //! Destroy the `ErrorHandler` instance.
+      88             :   ASMJIT_API virtual ~ErrorHandler() noexcept;
+      89             : 
+      90             :   // --------------------------------------------------------------------------
+      91             :   // [Handle Error]
+      92             :   // --------------------------------------------------------------------------
+      93             : 
+      94             :   //! Error handler (abstract).
+      95             :   //!
+      96             :   //! Error handler is called after an error happened and before it's propagated
+      97             :   //! to the caller. There are multiple ways how the error handler can be used:
+      98             :   //!
+      99             :   //! 1. Returning `true` or `false` from `handleError()`. If `true` is returned
+     100             :   //!    it means that the error was reported and AsmJit can continue execution.
+     101             :   //!    The reported error still be propagated to the caller, but won't put the
+     102             :   //!    CodeEmitter into an error state (it won't set last-error). However,
+     103             :   //!    returning `false` means that the error cannot be handled - in such case
+     104             :   //!    it stores the error, which can be then retrieved by using `getLastError()`.
+     105             :   //!    Returning `false` is the default behavior when no error handler is present.
+     106             :   //!    To put the assembler into a non-error state again a `resetLastError()` must
+     107             :   //!    be called.
+     108             :   //!
+     109             :   //! 2. Throwing an exception. AsmJit doesn't use exceptions and is completely
+     110             :   //!    exception-safe, but you can throw exception from your error handler if
+     111             :   //!    this way is the preferred way of handling errors in your project. Throwing
+     112             :   //!    an exception acts virtually as returning `true` as AsmJit won't be able
+     113             :   //!    to store the error because the exception changes execution path.
+     114             :   //!
+     115             :   //! 3. Using plain old C's `setjmp()` and `longjmp()`. Asmjit always puts
+     116             :   //!    `CodeEmitter` to a consistent state before calling the `handleError()`
+     117             :   //!    so `longjmp()` can be used without any issues to cancel the code
+     118             :   //!    generation if an error occurred. There is no difference between
+     119             :   //!    exceptions and longjmp() from AsmJit's perspective.
+     120             :   virtual bool handleError(Error err, const char* message, CodeEmitter* origin) = 0;
+     121             : };
+     122             : 
+     123             : // ============================================================================
+     124             : // [asmjit::CodeInfo]
+     125             : // ============================================================================
+     126             : 
+     127             : //! Basic information about a code (or target). It describes its architecture,
+     128             : //! code generation mode (or optimization level), and base address.
+     129             : class CodeInfo {
+     130             : public:
+     131             :   // --------------------------------------------------------------------------
+     132             :   // [Construction / Destruction]
+     133             :   // --------------------------------------------------------------------------
+     134             : 
+     135             :   ASMJIT_INLINE CodeInfo() noexcept
+     136        7820 :     : _archInfo(),
+     137        7820 :       _stackAlignment(0),
+     138        7820 :       _cdeclCallConv(CallConv::kIdNone),
+     139        7820 :       _stdCallConv(CallConv::kIdNone),
+     140        7820 :       _fastCallConv(CallConv::kIdNone),
+     141        7820 :       _baseAddress(Globals::kNoBaseAddress) {}
+     142             :   ASMJIT_INLINE CodeInfo(const CodeInfo& other) noexcept { init(other); }
+     143             : 
+     144             :   explicit ASMJIT_INLINE CodeInfo(uint32_t archType, uint32_t archMode = 0, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept
+     145             :     : _archInfo(archType, archMode),
+     146             :       _packedMiscInfo(0),
+     147             :       _baseAddress(baseAddress) {}
+     148             : 
+     149             :   // --------------------------------------------------------------------------
+     150             :   // [Init / Reset]
+     151             :   // --------------------------------------------------------------------------
+     152             : 
+     153             :   ASMJIT_INLINE bool isInitialized() const noexcept {
+     154        1948 :     return _archInfo._type != ArchInfo::kTypeNone;
+     155             :   }
+     156             : 
+     157             :   ASMJIT_INLINE void init(const CodeInfo& other) noexcept {
+     158        5844 :     _archInfo = other._archInfo;
+     159        5844 :     _packedMiscInfo = other._packedMiscInfo;
+     160        5844 :     _baseAddress = other._baseAddress;
+     161             :   }
+     162             : 
+     163             :   ASMJIT_INLINE void init(uint32_t archType, uint32_t archMode = 0, uint64_t baseAddress = Globals::kNoBaseAddress) noexcept {
+     164             :     _archInfo.init(archType, archMode);
+     165             :     _packedMiscInfo = 0;
+     166             :     _baseAddress = baseAddress;
+     167             :   }
+     168             : 
+     169             :   ASMJIT_INLINE void reset() noexcept {
+     170             :     _archInfo.reset();
+     171        1948 :     _stackAlignment = 0;
+     172        1948 :     _cdeclCallConv = CallConv::kIdNone;
+     173        1948 :     _stdCallConv = CallConv::kIdNone;
+     174        1948 :     _fastCallConv = CallConv::kIdNone;
+     175        1948 :     _baseAddress = Globals::kNoBaseAddress;
+     176             :   }
+     177             : 
+     178             :   // --------------------------------------------------------------------------
+     179             :   // [Architecture Information]
+     180             :   // --------------------------------------------------------------------------
+     181             : 
+     182             :   //! Get architecture information, see \ref ArchInfo.
+     183             :   ASMJIT_INLINE const ArchInfo& getArchInfo() const noexcept { return _archInfo; }
+     184             : 
+     185             :   //! Get architecture type, see \ref ArchInfo::Type.
+     186             :   ASMJIT_INLINE uint32_t getArchType() const noexcept { return _archInfo.getType(); }
+     187             :   //! Get architecture sub-type, see \ref ArchInfo::SubType.
+     188             :   ASMJIT_INLINE uint32_t getArchSubType() const noexcept { return _archInfo.getSubType(); }
+     189             :   //! Get a size of a GP register of the architecture the code is using.
+     190             :   ASMJIT_INLINE uint32_t getGpSize() const noexcept { return _archInfo.getGpSize(); }
+     191             :   //! Get number of GP registers available of the architecture the code is using.
+     192             :   ASMJIT_INLINE uint32_t getGpCount() const noexcept { return _archInfo.getGpCount(); }
+     193             : 
+     194             :   // --------------------------------------------------------------------------
+     195             :   // [High-Level Information]
+     196             :   // --------------------------------------------------------------------------
+     197             : 
+     198             :   //! Get a natural stack alignment that must be honored (or 0 if not known).
+     199        1948 :   ASMJIT_INLINE uint32_t getStackAlignment() const noexcept { return _stackAlignment; }
+     200             :   //! Set a natural stack alignment that must be honored.
+     201             :   ASMJIT_INLINE void setStackAlignment(uint8_t sa) noexcept { _stackAlignment = static_cast<uint8_t>(sa); }
+     202             : 
+     203             :   ASMJIT_INLINE uint32_t getCdeclCallConv() const noexcept { return _cdeclCallConv; }
+     204             :   ASMJIT_INLINE void setCdeclCallConv(uint32_t cc) noexcept { _cdeclCallConv = static_cast<uint8_t>(cc); }
+     205             : 
+     206             :   ASMJIT_INLINE uint32_t getStdCallConv() const noexcept { return _stdCallConv; }
+     207             :   ASMJIT_INLINE void setStdCallConv(uint32_t cc) noexcept { _stdCallConv = static_cast<uint8_t>(cc); }
+     208             : 
+     209             :   ASMJIT_INLINE uint32_t getFastCallConv() const noexcept { return _fastCallConv; }
+     210             :   ASMJIT_INLINE void setFastCallConv(uint32_t cc) noexcept { _fastCallConv = static_cast<uint8_t>(cc); }
+     211             : 
+     212             :   // --------------------------------------------------------------------------
+     213             :   // [Addressing Information]
+     214             :   // --------------------------------------------------------------------------
+     215             : 
+     216             :   ASMJIT_INLINE bool hasBaseAddress() const noexcept { return _baseAddress != Globals::kNoBaseAddress; }
+     217           0 :   ASMJIT_INLINE uint64_t getBaseAddress() const noexcept { return _baseAddress; }
+     218             :   ASMJIT_INLINE void setBaseAddress(uint64_t p) noexcept { _baseAddress = p; }
+     219             :   ASMJIT_INLINE void resetBaseAddress() noexcept { _baseAddress = Globals::kNoBaseAddress; }
+     220             : 
+     221             :   // --------------------------------------------------------------------------
+     222             :   // [Operator Overload]
+     223             :   // --------------------------------------------------------------------------
+     224             : 
+     225             :   ASMJIT_INLINE CodeInfo& operator=(const CodeInfo& other) noexcept { init(other); return *this; }
+     226             :   ASMJIT_INLINE bool operator==(const CodeInfo& other) const noexcept { return ::memcmp(this, &other, sizeof(*this)) == 0; }
+     227             :   ASMJIT_INLINE bool operator!=(const CodeInfo& other) const noexcept { return ::memcmp(this, &other, sizeof(*this)) != 0; }
+     228             : 
+     229             :   // --------------------------------------------------------------------------
+     230             :   // [Members]
+     231             :   // --------------------------------------------------------------------------
+     232             : 
+     233             :   ArchInfo _archInfo;                    //!< Architecture information.
+     234             : 
+     235             :   union {
+     236             :     struct {
+     237             :       uint8_t _stackAlignment;           //!< Natural stack alignment (ARCH+OS).
+     238             :       uint8_t _cdeclCallConv;            //!< Default CDECL calling convention.
+     239             :       uint8_t _stdCallConv;              //!< Default STDCALL calling convention.
+     240             :       uint8_t _fastCallConv;             //!< Default FASTCALL calling convention.
+     241             :     };
+     242             :     uint32_t _packedMiscInfo;            //!< \internal
+     243             :   };
+     244             : 
+     245             :   uint64_t _baseAddress;                 //!< Base address.
+     246             : };
+     247             : 
+     248             : // ============================================================================
+     249             : // [asmjit::CodeBuffer]
+     250             : // ============================================================================
+     251             : 
+     252             : //! Code or data buffer.
+     253             : struct CodeBuffer {
+     254             :   // --------------------------------------------------------------------------
+     255             :   // [Accessors]
+     256             :   // --------------------------------------------------------------------------
+     257             : 
+     258        1948 :   ASMJIT_INLINE bool hasData() const noexcept { return _data != nullptr; }
+     259             :   ASMJIT_INLINE uint8_t* getData() noexcept { return _data; }
+     260             :   ASMJIT_INLINE const uint8_t* getData() const noexcept { return _data; }
+     261             : 
+     262        5844 :   ASMJIT_INLINE size_t getLength() const noexcept { return _length; }
+     263        1948 :   ASMJIT_INLINE size_t getCapacity() const noexcept { return _capacity; }
+     264             : 
+     265        1948 :   ASMJIT_INLINE bool isExternal() const noexcept { return _isExternal; }
+     266        1948 :   ASMJIT_INLINE bool isFixedSize() const noexcept { return _isFixedSize; }
+     267             : 
+     268             :   // --------------------------------------------------------------------------
+     269             :   // [Members]
+     270             :   // --------------------------------------------------------------------------
+     271             : 
+     272             :   uint8_t* _data;                        //!< The content of the buffer (data).
+     273             :   size_t _length;                        //!< Number of bytes of `data` used.
+     274             :   size_t _capacity;                      //!< Buffer capacity (in bytes).
+     275             :   bool _isExternal;                      //!< True if this is external buffer.
+     276             :   bool _isFixedSize;                     //!< True if this buffer cannot grow.
+     277             : };
+     278             : 
+     279             : // ============================================================================
+     280             : // [asmjit::SectionEntry]
+     281             : // ============================================================================
+     282             : 
+     283             : //! Section entry.
+     284             : class SectionEntry {
+     285             : public:
+     286             :   ASMJIT_ENUM(Id) {
+     287             :     kInvalidId       = 0xFFFFFFFFU       //!< Invalid section id.
+     288             :   };
+     289             : 
+     290             :   //! Section flags.
+     291             :   ASMJIT_ENUM(Flags) {
+     292             :     kFlagExec        = 0x00000001U,      //!< Executable (.text sections).
+     293             :     kFlagConst       = 0x00000002U,      //!< Read-only (.text and .data sections).
+     294             :     kFlagZero        = 0x00000004U,      //!< Zero initialized by the loader (BSS).
+     295             :     kFlagInfo        = 0x00000008U,      //!< Info / comment flag.
+     296             :     kFlagImplicit    = 0x80000000U       //!< Section created implicitly (can be deleted by the Runtime).
+     297             :   };
+     298             : 
+     299             :   // --------------------------------------------------------------------------
+     300             :   // [Accessors]
+     301             :   // --------------------------------------------------------------------------
+     302             : 
+     303        3896 :   ASMJIT_INLINE uint32_t getId() const noexcept { return _id; }
+     304             :   ASMJIT_INLINE const char* getName() const noexcept { return _name; }
+     305             : 
+     306             :   ASMJIT_INLINE void _setDefaultName(
+     307             :       char c0 = 0, char c1 = 0, char c2 = 0, char c3 = 0,
+     308             :       char c4 = 0, char c5 = 0, char c6 = 0, char c7 = 0) noexcept {
+     309        1948 :     _nameAsU32[0] = Utils::pack32_4x8(c0, c1, c2, c3);
+     310        1948 :     _nameAsU32[1] = Utils::pack32_4x8(c4, c5, c6, c7);
+     311             :   }
+     312             : 
+     313             :   ASMJIT_INLINE uint32_t getFlags() const noexcept { return _flags; }
+     314             :   ASMJIT_INLINE bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+     315             :   ASMJIT_INLINE void addFlags(uint32_t flags) noexcept { _flags |= flags; }
+     316             :   ASMJIT_INLINE void clearFlags(uint32_t flags) noexcept { _flags &= ~flags; }
+     317             : 
+     318             :   ASMJIT_INLINE uint32_t getAlignment() const noexcept { return _alignment; }
+     319             :   ASMJIT_INLINE void setAlignment(uint32_t alignment) noexcept { _alignment = alignment; }
+     320             : 
+     321             :   ASMJIT_INLINE size_t getPhysicalSize() const noexcept { return _buffer.getLength(); }
+     322             : 
+     323             :   ASMJIT_INLINE size_t getVirtualSize() const noexcept { return _virtualSize; }
+     324             :   ASMJIT_INLINE void setVirtualSize(uint32_t size) noexcept { _virtualSize = size; }
+     325             : 
+     326             :   ASMJIT_INLINE CodeBuffer& getBuffer() noexcept { return _buffer; }
+     327             :   ASMJIT_INLINE const CodeBuffer& getBuffer() const noexcept { return _buffer; }
+     328             : 
+     329             :   // --------------------------------------------------------------------------
+     330             :   // [Members]
+     331             :   // --------------------------------------------------------------------------
+     332             : 
+     333             :   uint32_t _id;                          //!< Section id.
+     334             :   uint32_t _flags;                       //!< Section flags.
+     335             :   uint32_t _alignment;                   //!< Section alignment requirements (0 if no requirements).
+     336             :   uint32_t _virtualSize;                 //!< Virtual size of the section (zero initialized mostly).
+     337             :   union {
+     338             :     char _name[36];                      //!< Section name (max 35 characters, PE allows max 8).
+     339             :     uint32_t _nameAsU32[36 / 4];         //!< Section name as `uint32_t[]` (only optimization).
+     340             :   };
+     341             :   CodeBuffer _buffer;                    //!< Code or data buffer.
+     342             : };
+     343             : 
+     344             : // ============================================================================
+     345             : // [asmjit::LabelLink]
+     346             : // ============================================================================
+     347             : 
+     348             : //! Data structure used to link labels.
+     349             : struct LabelLink {
+     350             :   LabelLink* prev;                       //!< Previous link (single-linked list).
+     351             :   uint32_t sectionId;                    //!< Section id.
+     352             :   uint32_t relocId;                      //!< Relocation id or RelocEntry::kInvalidId.
+     353             :   size_t offset;                         //!< Label offset relative to the start of the section.
+     354             :   intptr_t rel;                          //!< Inlined rel8/rel32.
+     355             : };
+     356             : 
+     357             : // ============================================================================
+     358             : // [asmjit::LabelEntry]
+     359             : // ============================================================================
+     360             : 
+     361             : //! Label entry.
+     362             : //!
+     363             : //! Contains the following properties:
+     364             : //!   * Label id - This is the only thing that is set to the `Label` operand.
+     365             : //!   * Label name - Optional, used mostly to create executables and libraries.
+     366             : //!   * Label type - Type of the label, default `Label::kTypeAnonymous`.
+     367             : //!   * Label parent id - Derived from many assemblers that allow to define a
+     368             : //!       local label that falls under a global label. This allows to define
+     369             : //!       many labels of the same name that have different parent (global) label.
+     370             : //!   * Offset - offset of the label bound by `Assembler`.
+     371             : //!   * Links - single-linked list that contains locations of code that has
+     372             : //!       to be patched when the label gets bound. Every use of unbound label
+     373             : //!       adds one link to `_links` list.
+     374             : //!   * HVal - Hash value of label's name and optionally parentId.
+     375             : //!   * HashNext - Hash-table implementation detail.
+     376             : class LabelEntry : public ZoneHashNode {
+     377             : public:
+     378             :   // NOTE: Label id is stored in `_customData`, which is provided by ZoneHashNode
+     379             :   // to fill a padding that a C++ compiler targeting 64-bit CPU will add to align
+     380             :   // the structure to 64-bits.
+     381             : 
+     382             :   //! Get label id.
+     383           0 :   ASMJIT_INLINE uint32_t getId() const noexcept { return _customData; }
+     384             :   //! Set label id (internal, used only by \ref CodeHolder).
+     385        3896 :   ASMJIT_INLINE void _setId(uint32_t id) noexcept { _customData = id; }
+     386             : 
+     387             :   //! Get label type, see \ref Label::Type.
+     388             :   ASMJIT_INLINE uint32_t getType() const noexcept { return _type; }
+     389             :   //! Get label flags, returns 0 at the moment.
+     390             :   ASMJIT_INLINE uint32_t getFlags() const noexcept { return _flags; }
+     391             : 
+     392           0 :   ASMJIT_INLINE bool hasParent() const noexcept { return _parentId != 0; }
+     393             :   //! Get label's parent id.
+     394             :   ASMJIT_INLINE uint32_t getParentId() const noexcept { return _parentId; }
+     395             : 
+     396             :   //! Get label's section id where it's bound to (or `SectionEntry::kInvalidId` if it's not bound yet).
+     397             :   ASMJIT_INLINE uint32_t getSectionId() const noexcept { return _sectionId; }
+     398             : 
+     399             :   //! Get if the label has name.
+     400             :   ASMJIT_INLINE bool hasName() const noexcept { return !_name.isEmpty(); }
+     401             : 
+     402             :   //! Get the label's name.
+     403             :   //!
+     404             :   //! NOTE: Local labels will return their local name without their parent
+     405             :   //! part, for example ".L1".
+     406             :   ASMJIT_INLINE const char* getName() const noexcept { return _name.getData(); }
+     407             : 
+     408             :   //! Get length of label's name.
+     409             :   //!
+     410             :   //! NOTE: Label name is always null terminated, so you can use `strlen()` to
+     411             :   //! get it, however, it's also cached in `LabelEntry`, so if you want to know
+     412             :   //! the length the easiest way is to use `LabelEntry::getNameLength()`.
+     413             :   ASMJIT_INLINE size_t getNameLength() const noexcept { return _name.getLength(); }
+     414             : 
+     415             :   //! Get if the label is bound.
+     416        3896 :   ASMJIT_INLINE bool isBound() const noexcept { return _sectionId != SectionEntry::kInvalidId; }
+     417             :   //! Get the label offset (only useful if the label is bound).
+     418           0 :   ASMJIT_INLINE intptr_t getOffset() const noexcept { return _offset; }
+     419             : 
+     420             :   //! Get the hash-value of label's name and its parent label (if any).
+     421             :   //!
+     422             :   //! Label hash is calculated as `HASH(Name) ^ ParentId`. The hash function
+     423             :   //! is implemented in `Utils::hashString()` and `Utils::hashRound()`.
+     424             :   ASMJIT_INLINE uint32_t getHVal() const noexcept { return _hVal; }
+     425             : 
+     426             :   // ------------------------------------------------------------------------
+     427             :   // [Members]
+     428             :   // ------------------------------------------------------------------------
+     429             : 
+     430             :   // Let's round the size of `LabelEntry` to 64 bytes (as ZoneHeap has 32
+     431             :   // bytes granularity anyway). This gives `_name` the remaining space, which
+     432             :   // is roughly 16 bytes on 64-bit and 28 bytes on 32-bit architectures.
+     433             :   enum { kNameBytes = 64 - (sizeof(ZoneHashNode) + 16 + sizeof(intptr_t) + sizeof(LabelLink*)) };
+     434             : 
+     435             :   uint8_t _type;                         //!< Label type, see Label::Type.
+     436             :   uint8_t _flags;                        //!< Must be zero.
+     437             :   uint16_t _reserved16;                  //!< Reserved.
+     438             :   uint32_t _parentId;                    //!< Label parent id or zero.
+     439             :   uint32_t _sectionId;                   //!< Section id or `SectionEntry::kInvalidId`.
+     440             :   uint32_t _reserved32;                  //!< Reserved.
+     441             :   intptr_t _offset;                      //!< Label offset.
+     442             :   LabelLink* _links;                     //!< Label links.
+     443             :   SmallString<kNameBytes> _name;         //!< Label name.
+     444             : };
+     445             : 
+     446             : // ============================================================================
+     447             : // [asmjit::RelocEntry]
+     448             : // ============================================================================
+     449             : 
+     450             : //! Relocation entry.
+     451             : struct RelocEntry {
+     452             :   ASMJIT_ENUM(Id) {
+     453             :     kInvalidId       = 0xFFFFFFFFU       //!< Invalid relocation id.
+     454             :   };
+     455             : 
+     456             :   //! Relocation type.
+     457             :   ASMJIT_ENUM(Type) {
+     458             :     kTypeNone        = 0,                //!< Deleted entry (no relocation).
+     459             :     kTypeAbsToAbs    = 1,                //!< Relocate absolute to absolute.
+     460             :     kTypeRelToAbs    = 2,                //!< Relocate relative to absolute.
+     461             :     kTypeAbsToRel    = 3,                //!< Relocate absolute to relative.
+     462             :     kTypeTrampoline  = 4                 //!< Relocate absolute to relative or use trampoline.
+     463             :   };
+     464             : 
+     465             :   // ------------------------------------------------------------------------
+     466             :   // [Accessors]
+     467             :   // ------------------------------------------------------------------------
+     468             : 
+     469           0 :   ASMJIT_INLINE uint32_t getId() const noexcept { return _id; }
+     470             : 
+     471           0 :   ASMJIT_INLINE uint32_t getType() const noexcept { return _type; }
+     472           0 :   ASMJIT_INLINE uint32_t getSize() const noexcept { return _size; }
+     473             : 
+     474             :   ASMJIT_INLINE uint32_t getSourceSectionId() const noexcept { return _sourceSectionId; }
+     475             :   ASMJIT_INLINE uint32_t getTargetSectionId() const noexcept { return _targetSectionId; }
+     476             : 
+     477           0 :   ASMJIT_INLINE uint64_t getSourceOffset() const noexcept { return _sourceOffset; }
+     478           0 :   ASMJIT_INLINE uint64_t getData() const noexcept { return _data; }
+     479             : 
+     480             :   // ------------------------------------------------------------------------
+     481             :   // [Members]
+     482             :   // ------------------------------------------------------------------------
+     483             : 
+     484             :   uint32_t _id;                          //!< Relocation id.
+     485             :   uint8_t _type;                         //!< Type of the relocation.
+     486             :   uint8_t _size;                         //!< Size of the relocation (1, 2, 4 or 8 bytes).
+     487             :   uint8_t _reserved[2];                  //!< Reserved.
+     488             :   uint32_t _sourceSectionId;             //!< Source section id.
+     489             :   uint32_t _targetSectionId;             //!< Destination section id.
+     490             :   uint64_t _sourceOffset;                //!< Source offset (relative to start of the section).
+     491             :   uint64_t _data;                        //!< Relocation data (target offset, target address, etc).
+     492             : };
+     493             : 
+     494             : // ============================================================================
+     495             : // [asmjit::CodeHolder]
+     496             : // ============================================================================
+     497             : 
+     498             : //! Contains basic information about the target architecture plus its settings,
+     499             : //! and holds code & data (including sections, labels, and relocation information).
+     500             : //! CodeHolder can store both binary and intermediate representation of assembly,
+     501             : //! which can be generated by \ref Assembler and/or \ref CodeBuilder.
+     502             : //!
+     503             : //! NOTE: CodeHolder has ability to attach an \ref ErrorHandler, however, this
+     504             : //! error handler is not triggered by CodeHolder itself, it's only used by the
+     505             : //! attached code generators.
+     506             : class CodeHolder {
+     507             : public:
+     508             :   ASMJIT_NONCOPYABLE(CodeHolder)
+     509             : 
+     510             :   // --------------------------------------------------------------------------
+     511             :   // [Construction / Destruction]
+     512             :   // --------------------------------------------------------------------------
+     513             : 
+     514             :   //! Create an uninitialized CodeHolder (you must init() it before it can be used).
+     515             :   ASMJIT_API CodeHolder() noexcept;
+     516             :   //! Destroy the CodeHolder.
+     517             :   ASMJIT_API ~CodeHolder() noexcept;
+     518             : 
+     519             :   // --------------------------------------------------------------------------
+     520             :   // [Init / Reset]
+     521             :   // --------------------------------------------------------------------------
+     522             : 
+     523             :   ASMJIT_INLINE bool isInitialized() const noexcept { return _codeInfo.isInitialized(); }
+     524             : 
+     525             :   //! Initialize to CodeHolder to hold code described by `codeInfo`.
+     526             :   ASMJIT_API Error init(const CodeInfo& info) noexcept;
+     527             :   //! Detach all code-generators attached and reset the \ref CodeHolder.
+     528             :   ASMJIT_API void reset(bool releaseMemory = false) noexcept;
+     529             : 
+     530             :   // --------------------------------------------------------------------------
+     531             :   // [Attach / Detach]
+     532             :   // --------------------------------------------------------------------------
+     533             : 
+     534             :   //! Attach a \ref CodeEmitter to this \ref CodeHolder.
+     535             :   ASMJIT_API Error attach(CodeEmitter* emitter) noexcept;
+     536             :   //! Detach a \ref CodeEmitter from this \ref CodeHolder.
+     537             :   ASMJIT_API Error detach(CodeEmitter* emitter) noexcept;
+     538             : 
+     539             :   // --------------------------------------------------------------------------
+     540             :   // [Sync]
+     541             :   // --------------------------------------------------------------------------
+     542             : 
+     543             :   //! Synchronize all states of all `CodeEmitter`s associated with the CodeHolder.
+     544             :   //! This is required as some code generators don't sync every time they do
+     545             :   //! something - for example \ref Assembler generally syncs when it needs to
+     546             :   //! reallocate the \ref CodeBuffer, but not each time it encodes instruction
+     547             :   //! or directive.
+     548             :   ASMJIT_API void sync() noexcept;
+     549             : 
+     550             :   // --------------------------------------------------------------------------
+     551             :   // [Code-Information]
+     552             :   // --------------------------------------------------------------------------
+     553             : 
+     554             :   //! Get code/target information, see \ref CodeInfo.
+     555             :   ASMJIT_INLINE const CodeInfo& getCodeInfo() const noexcept { return _codeInfo; }
+     556             :   //! Get architecture information, see \ref ArchInfo.
+     557             :   ASMJIT_INLINE const ArchInfo& getArchInfo() const noexcept { return _codeInfo.getArchInfo(); }
+     558             : 
+     559             :   //! Get the target's architecture type.
+     560             :   ASMJIT_INLINE uint32_t getArchType() const noexcept { return getArchInfo().getType(); }
+     561             :   //! Get the target's architecture sub-type.
+     562             :   ASMJIT_INLINE uint32_t getArchSubType() const noexcept { return getArchInfo().getSubType(); }
+     563             : 
+     564             :   //! Get if a static base-address is set.
+     565             :   ASMJIT_INLINE bool hasBaseAddress() const noexcept { return _codeInfo.hasBaseAddress(); }
+     566             :   //! Get a static base-address (uint64_t).
+     567             :   ASMJIT_INLINE uint64_t getBaseAddress() const noexcept { return _codeInfo.getBaseAddress(); }
+     568             : 
+     569             :   // --------------------------------------------------------------------------
+     570             :   // [Global Information]
+     571             :   // --------------------------------------------------------------------------
+     572             : 
+     573             :   //! Get global hints, internally propagated to all `CodeEmitter`s attached.
+     574        3896 :   ASMJIT_INLINE uint32_t getGlobalHints() const noexcept { return _globalHints; }
+     575             :   //! Get global options, internally propagated to all `CodeEmitter`s attached.
+     576        3896 :   ASMJIT_INLINE uint32_t getGlobalOptions() const noexcept { return _globalOptions; }
+     577             : 
+     578             :   // --------------------------------------------------------------------------
+     579             :   // [Result Information]
+     580             :   // --------------------------------------------------------------------------
+     581             : 
+     582             :   //! Get the size code & data of all sections.
+     583             :   ASMJIT_API size_t getCodeSize() const noexcept;
+     584             : 
+     585             :   //! Get size of all possible trampolines.
+     586             :   //!
+     587             :   //! Trampolines are needed to successfully generate relative jumps to absolute
+     588             :   //! addresses. This value is only non-zero if jmp of call instructions were
+     589             :   //! used with immediate operand (this means jumping or calling an absolute
+     590             :   //! address directly).
+     591        3896 :   ASMJIT_INLINE size_t getTrampolinesSize() const noexcept { return _trampolinesSize; }
+     592             : 
+     593             :   // --------------------------------------------------------------------------
+     594             :   // [Logging & Error Handling]
+     595             :   // --------------------------------------------------------------------------
+     596             : 
+     597             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     598             :   //! Get if a logger attached.
+     599             :   ASMJIT_INLINE bool hasLogger() const noexcept { return _logger != nullptr; }
+     600             :   //! Get the attached logger.
+     601        1948 :   ASMJIT_INLINE Logger* getLogger() const noexcept { return _logger; }
+     602             :   //! Attach a `logger` to CodeHolder and propagate it to all attached `CodeEmitter`s.
+     603             :   ASMJIT_API void setLogger(Logger* logger) noexcept;
+     604             :   //! Reset the logger (does nothing if not attached).
+     605             :   ASMJIT_INLINE void resetLogger() noexcept { setLogger(nullptr); }
+     606             : #endif // !ASMJIT_DISABLE_LOGGING
+     607             : 
+     608             :   //! Get if error-handler is attached.
+     609             :   ASMJIT_INLINE bool hasErrorHandler() const noexcept { return _errorHandler != nullptr; }
+     610             :   //! Get the error-handler.
+     611             :   ASMJIT_INLINE ErrorHandler* getErrorHandler() const noexcept { return _errorHandler; }
+     612             :   //! Set the error handler, will affect all attached `CodeEmitter`s.
+     613             :   ASMJIT_API Error setErrorHandler(ErrorHandler* handler) noexcept;
+     614             :   //! Reset the error handler (does nothing if not attached).
+     615             :   ASMJIT_INLINE void resetErrorHandler() noexcept { setErrorHandler(nullptr); }
+     616             : 
+     617             :   // --------------------------------------------------------------------------
+     618             :   // [Sections]
+     619             :   // --------------------------------------------------------------------------
+     620             : 
+     621             :   //! Get array of `SectionEntry*` records.
+     622             :   ASMJIT_INLINE const ZoneVector<SectionEntry*>& getSections() const noexcept { return _sections; }
+     623             : 
+     624             :   //! Get a section entry of the given index.
+     625             :   ASMJIT_INLINE SectionEntry* getSectionEntry(size_t index) const noexcept { return _sections[index]; }
+     626             : 
+     627             :   ASMJIT_API Error growBuffer(CodeBuffer* cb, size_t n) noexcept;
+     628             :   ASMJIT_API Error reserveBuffer(CodeBuffer* cb, size_t n) noexcept;
+     629             : 
+     630             :   // --------------------------------------------------------------------------
+     631             :   // [Labels & Symbols]
+     632             :   // --------------------------------------------------------------------------
+     633             : 
+     634             :   //! Create a new anonymous label and return its id in `idOut`.
+     635             :   //!
+     636             :   //! Returns `Error`, does not report error to \ref ErrorHandler.
+     637             :   ASMJIT_API Error newLabelId(uint32_t& idOut) noexcept;
+     638             : 
+     639             :   //! Create a new named label label-type `type`.
+     640             :   //!
+     641             :   //! Returns `Error`, does not report error to \ref ErrorHandler.
+     642             :   ASMJIT_API Error newNamedLabelId(uint32_t& idOut, const char* name, size_t nameLength, uint32_t type, uint32_t parentId) noexcept;
+     643             : 
+     644             :   //! Get a label id by name.
+     645             :   ASMJIT_API uint32_t getLabelIdByName(const char* name, size_t nameLength = Globals::kInvalidIndex, uint32_t parentId = 0) noexcept;
+     646             : 
+     647             :   //! Create a new label-link used to store information about yet unbound labels.
+     648             :   //!
+     649             :   //! Returns `null` if the allocation failed.
+     650             :   ASMJIT_API LabelLink* newLabelLink(LabelEntry* le, uint32_t sectionId, size_t offset, intptr_t rel) noexcept;
+     651             : 
+     652             :   //! Get array of `LabelEntry*` records.
+     653             :   ASMJIT_INLINE const ZoneVector<LabelEntry*>& getLabelEntries() const noexcept { return _labels; }
+     654             : 
+     655             :   //! Get number of labels created.
+     656             :   ASMJIT_INLINE size_t getLabelsCount() const noexcept { return _labels.getLength(); }
+     657             : 
+     658             :   //! Get number of label references, which are unresolved at the moment.
+     659             :   ASMJIT_INLINE size_t getUnresolvedLabelsCount() const noexcept { return _unresolvedLabelsCount; }
+     660             : 
+     661             :   //! Get if the `label` is valid (i.e. created by `newLabelId()`).
+     662             :   ASMJIT_INLINE bool isLabelValid(const Label& label) const noexcept {
+     663             :     return isLabelValid(label.getId());
+     664             :   }
+     665             :   //! Get if the label having `id` is valid (i.e. created by `newLabelId()`).
+     666             :   ASMJIT_INLINE bool isLabelValid(uint32_t labelId) const noexcept {
+     667             :     size_t index = Operand::unpackId(labelId);
+     668             :     return index < _labels.getLength();
+     669             :   }
+     670             : 
+     671             :   //! Get if the `label` is already bound.
+     672             :   //!
+     673             :   //! Returns `false` if the `label` is not valid.
+     674             :   ASMJIT_INLINE bool isLabelBound(const Label& label) const noexcept {
+     675             :     return isLabelBound(label.getId());
+     676             :   }
+     677             :   //! \overload
+     678             :   ASMJIT_INLINE bool isLabelBound(uint32_t id) const noexcept {
+     679             :     size_t index = Operand::unpackId(id);
+     680             :     return index < _labels.getLength() && _labels[index]->isBound();
+     681             :   }
+     682             : 
+     683             :   //! Get a `label` offset or -1 if the label is not yet bound.
+     684             :   ASMJIT_INLINE intptr_t getLabelOffset(const Label& label) const noexcept {
+     685             :     return getLabelOffset(label.getId());
+     686             :   }
+     687             :   //! \overload
+     688             :   ASMJIT_INLINE intptr_t getLabelOffset(uint32_t id) const noexcept {
+     689             :     ASMJIT_ASSERT(isLabelValid(id));
+     690             :     return _labels[Operand::unpackId(id)]->getOffset();
+     691             :   }
+     692             : 
+     693             :   //! Get information about the given `label`.
+     694             :   ASMJIT_INLINE LabelEntry* getLabelEntry(const Label& label) const noexcept {
+     695             :     return getLabelEntry(label.getId());
+     696             :   }
+     697             :   //! Get information about a label having the given `id`.
+     698             :   ASMJIT_INLINE LabelEntry* getLabelEntry(uint32_t id) const noexcept {
+     699        3896 :     size_t index = static_cast<size_t>(Operand::unpackId(id));
+     700        3896 :     return index < _labels.getLength() ? _labels[index] : static_cast<LabelEntry*>(nullptr);
+     701             :   }
+     702             : 
+     703             :   // --------------------------------------------------------------------------
+     704             :   // [Relocations]
+     705             :   // --------------------------------------------------------------------------
+     706             : 
+     707             :   //! Create a new relocation entry of type `type` and size `size`.
+     708             :   //!
+     709             :   //! Additional fields can be set after the relocation entry was created.
+     710             :   ASMJIT_API Error newRelocEntry(RelocEntry** dst, uint32_t type, uint32_t size) noexcept;
+     711             : 
+     712             :   //! Get if the code contains relocations.
+     713             :   ASMJIT_INLINE bool hasRelocations() const noexcept { return !_relocations.isEmpty(); }
+     714             :   //! Get array of `RelocEntry*` records.
+     715             :   ASMJIT_INLINE const ZoneVector<RelocEntry*>& getRelocEntries() const noexcept { return _relocations; }
+     716             : 
+     717             :   ASMJIT_INLINE RelocEntry* getRelocEntry(uint32_t id) const noexcept { return _relocations[id]; }
+     718             : 
+     719             :   //! Relocate the code to `baseAddress` and copy it to `dst`.
+     720             :   //!
+     721             :   //! \param dst Contains the location where the relocated code should be
+     722             :   //! copied. The pointer can be address returned by virtual memory allocator
+     723             :   //! or any other address that has sufficient space.
+     724             :   //!
+     725             :   //! \param baseAddress Base address used for relocation. `JitRuntime` always
+     726             :   //! sets the `baseAddress` to be the same as `dst`.
+     727             :   //!
+     728             :   //! \return The number bytes actually used. If the code emitter reserved
+     729             :   //! space for possible trampolines, but didn't use it, the number of bytes
+     730             :   //! used can actually be less than the expected worst case. Virtual memory
+     731             :   //! allocator can shrink the memory it allocated initially.
+     732             :   //!
+     733             :   //! A given buffer will be overwritten, to get the number of bytes required,
+     734             :   //! use `getCodeSize()`.
+     735             :   ASMJIT_API size_t relocate(void* dst, uint64_t baseAddress = Globals::kNoBaseAddress) const noexcept;
+     736             : 
+     737             :   // --------------------------------------------------------------------------
+     738             :   // [Members]
+     739             :   // --------------------------------------------------------------------------
+     740             : 
+     741             :   CodeInfo _codeInfo;                    //!< Basic information about the code (architecture and other info).
+     742             : 
+     743             :   uint32_t _globalHints;                 //!< Global hints, propagated to all `CodeEmitter`s.
+     744             :   uint32_t _globalOptions;               //!< Global options, propagated to all `CodeEmitter`s.
+     745             : 
+     746             :   CodeEmitter* _emitters;                //!< Linked-list of all attached `CodeEmitter`s.
+     747             :   Assembler* _cgAsm;                     //!< Attached \ref Assembler (only one at a time).
+     748             : 
+     749             :   Logger* _logger;                       //!< Attached \ref Logger, used by all consumers.
+     750             :   ErrorHandler* _errorHandler;           //!< Attached \ref ErrorHandler.
+     751             : 
+     752             :   uint32_t _unresolvedLabelsCount;       //!< Count of label references which were not resolved.
+     753             :   uint32_t _trampolinesSize;             //!< Size of all possible trampolines.
+     754             : 
+     755             :   Zone _baseZone;                        //!< Base zone (used to allocate core structures).
+     756             :   Zone _dataZone;                        //!< Data zone (used to allocate extra data like label names).
+     757             :   ZoneHeap _baseHeap;                    //!< Zone allocator, used to manage internal containers.
+     758             : 
+     759             :   ZoneVector<SectionEntry*> _sections;   //!< Section entries.
+     760             :   ZoneVector<LabelEntry*> _labels;       //!< Label entries (each label is stored here).
+     761             :   ZoneVector<RelocEntry*> _relocations;  //!< Relocation entries.
+     762             :   ZoneHash<LabelEntry> _namedLabels;     //!< Label name -> LabelEntry (only named labels).
+     763             : };
+     764             : 
+     765             : //! \}
+     766             : 
+     767             : } // asmjit namespace
+     768             : } // namespace PLMD
+     769             : 
+     770             : // [Api-End]
+     771             : #include "./asmjit_apiend.h"
+     772             : 
+     773             : // [Guard]
+     774             : #endif // _ASMJIT_BASE_CODEHOLDER_H
+     775             : #pragma GCC diagnostic pop
+     776             : #endif // __PLUMED_HAS_ASMJIT
+     777             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/constpool.cpp.func-sort-c.html b/coverage-libs/asmjit/constpool.cpp.func-sort-c.html new file mode 100644 index 000000000000..56144e2133dc --- /dev/null +++ b/coverage-libs/asmjit/constpool.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01100.0 %
Date:2024-02-22 21:58:47Functions:080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9ConstPool3addEPKvmRm0
_ZN4PLMD6asmjit9ConstPool4Tree3getEPKv0
_ZN4PLMD6asmjit9ConstPool4Tree3putEPNS1_4NodeE0
_ZN4PLMD6asmjit9ConstPool5resetEPNS0_4ZoneE0
_ZN4PLMD6asmjit9ConstPoolC2EPNS0_4ZoneE0
_ZN4PLMD6asmjit9ConstPoolD2Ev0
_ZN4PLMD6asmjitL16ConstPool_addGapEPNS0_9ConstPoolEmm0
_ZNK4PLMD6asmjit9ConstPool4fillEPv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/constpool.cpp.func.html b/coverage-libs/asmjit/constpool.cpp.func.html new file mode 100644 index 000000000000..ae9a965504a2 --- /dev/null +++ b/coverage-libs/asmjit/constpool.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01100.0 %
Date:2024-02-22 21:58:47Functions:080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9ConstPool3addEPKvmRm0
_ZN4PLMD6asmjit9ConstPool4Tree3getEPKv0
_ZN4PLMD6asmjit9ConstPool4Tree3putEPNS1_4NodeE0
_ZN4PLMD6asmjit9ConstPool5resetEPNS0_4ZoneE0
_ZN4PLMD6asmjit9ConstPoolC2EPNS0_4ZoneE0
_ZN4PLMD6asmjit9ConstPoolD2Ev0
_ZN4PLMD6asmjitL16ConstPool_addGapEPNS0_9ConstPoolEmm0
_ZNK4PLMD6asmjit9ConstPool4fillEPv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/constpool.cpp.gcov.html b/coverage-libs/asmjit/constpool.cpp.gcov.html new file mode 100644 index 000000000000..428405ca1b4f --- /dev/null +++ b/coverage-libs/asmjit/constpool.cpp.gcov.html @@ -0,0 +1,614 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01100.0 %
Date:2024-02-22 21:58:47Functions:080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./constpool.h"
+      34             : #include "./utils.h"
+      35             : 
+      36             : #include <algorithm>
+      37             : 
+      38             : // [Api-Begin]
+      39             : #include "./asmjit_apibegin.h"
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace asmjit {
+      43             : 
+      44             : // Binary tree code is based on Julienne Walker's "Andersson Binary Trees"
+      45             : // article and implementation. However, only three operations are implemented -
+      46             : // get, insert and traverse.
+      47             : 
+      48             : // ============================================================================
+      49             : // [asmjit::ConstPool::Tree - Ops]
+      50             : // ============================================================================
+      51             : 
+      52             : //! \internal
+      53             : //!
+      54             : //! Remove left horizontal links.
+      55             : static ASMJIT_INLINE ConstPool::Node* ConstPoolTree_skewNode(ConstPool::Node* node) noexcept {
+      56           0 :   ConstPool::Node* link = node->_link[0];
+      57           0 :   uint32_t level = node->_level;
+      58             : 
+      59           0 :   if (level != 0 && link && link->_level == level) {
+      60           0 :     node->_link[0] = link->_link[1];
+      61           0 :     link->_link[1] = node;
+      62             : 
+      63             :     node = link;
+      64             :   }
+      65             : 
+      66             :   return node;
+      67             : }
+      68             : 
+      69             : //! \internal
+      70             : //!
+      71             : //! Remove consecutive horizontal links.
+      72             : static ASMJIT_INLINE ConstPool::Node* ConstPoolTree_splitNode(ConstPool::Node* node) noexcept {
+      73           0 :   ConstPool::Node* link = node->_link[1];
+      74           0 :   uint32_t level = node->_level;
+      75             : 
+      76           0 :   if (level != 0 && link && link->_link[1] && link->_link[1]->_level == level) {
+      77           0 :     node->_link[1] = link->_link[0];
+      78           0 :     link->_link[0] = node;
+      79             : 
+      80             :     node = link;
+      81           0 :     node->_level++;
+      82             :   }
+      83             : 
+      84             :   return node;
+      85             : }
+      86             : 
+      87           0 : ConstPool::Node* ConstPool::Tree::get(const void* data) noexcept {
+      88           0 :   ConstPool::Node* node = _root;
+      89           0 :   size_t dataSize = _dataSize;
+      90             : 
+      91           0 :   while (node) {
+      92           0 :     int c = ::memcmp(node->getData(), data, dataSize);
+      93           0 :     if (c == 0)
+      94             :       return node;
+      95           0 :     node = node->_link[c < 0];
+      96             :   }
+      97             : 
+      98             :   return nullptr;
+      99             : }
+     100             : 
+     101           0 : void ConstPool::Tree::put(ConstPool::Node* newNode) noexcept {
+     102           0 :   size_t dataSize = _dataSize;
+     103           0 :   _length++;
+     104             : 
+     105           0 :   if (!_root) {
+     106           0 :     _root = newNode;
+     107           0 :     return;
+     108             :   }
+     109             : 
+     110             :   ConstPool::Node* node = _root;
+     111             :   ConstPool::Node* stack[kHeightLimit];
+     112             : 
+     113             :   unsigned int top = 0;
+     114             :   unsigned int dir;
+     115             : 
+     116             :   // Find a spot and save the stack.
+     117             :   for (;;) {
+     118           0 :     stack[top++] = node;
+     119           0 :     dir = ::memcmp(node->getData(), newNode->getData(), dataSize) < 0;
+     120             : 
+     121           0 :     ConstPool::Node* link = node->_link[dir];
+     122           0 :     if (!link) break;
+     123             : 
+     124             :     node = link;
+     125             :   }
+     126             : 
+     127             :   // Link and rebalance.
+     128           0 :   node->_link[dir] = newNode;
+     129             : 
+     130           0 :   while (top > 0) {
+     131             :     // Which child?
+     132           0 :     node = stack[--top];
+     133             : 
+     134           0 :     if (top != 0) {
+     135           0 :       dir = stack[top - 1]->_link[1] == node;
+     136             :     }
+     137             : 
+     138             :     node = ConstPoolTree_skewNode(node);
+     139             :     node = ConstPoolTree_splitNode(node);
+     140             : 
+     141             :     // Fix the parent.
+     142           0 :     if (top != 0)
+     143           0 :       stack[top - 1]->_link[dir] = node;
+     144             :     else
+     145           0 :       _root = node;
+     146             :   }
+     147             : }
+     148             : 
+     149             : // ============================================================================
+     150             : // [asmjit::ConstPool - Construction / Destruction]
+     151             : // ============================================================================
+     152             : 
+     153           0 : ConstPool::ConstPool(Zone* zone) noexcept { reset(zone); }
+     154           0 : ConstPool::~ConstPool() noexcept {}
+     155             : 
+     156             : // ============================================================================
+     157             : // [asmjit::ConstPool - Reset]
+     158             : // ============================================================================
+     159             : 
+     160           0 : void ConstPool::reset(Zone* zone) noexcept {
+     161           0 :   _zone = zone;
+     162             : 
+     163             :   size_t dataSize = 1;
+     164           0 :   for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) {
+     165             :     _tree[i].reset();
+     166             :     _tree[i].setDataSize(dataSize);
+     167           0 :     _gaps[i] = nullptr;
+     168           0 :     dataSize <<= 1;
+     169             :   }
+     170             : 
+     171           0 :   _gapPool = nullptr;
+     172           0 :   _size = 0;
+     173           0 :   _alignment = 0;
+     174           0 : }
+     175             : 
+     176             : // ============================================================================
+     177             : // [asmjit::ConstPool - Ops]
+     178             : // ============================================================================
+     179             : 
+     180             : static ASMJIT_INLINE ConstPool::Gap* ConstPool_allocGap(ConstPool* self) noexcept {
+     181           0 :   ConstPool::Gap* gap = self->_gapPool;
+     182           0 :   if (!gap) return self->_zone->allocT<ConstPool::Gap>();
+     183             : 
+     184           0 :   self->_gapPool = gap->_next;
+     185           0 :   return gap;
+     186             : }
+     187             : 
+     188             : static ASMJIT_INLINE void ConstPool_freeGap(ConstPool* self,  ConstPool::Gap* gap) noexcept {
+     189           0 :   gap->_next = self->_gapPool;
+     190           0 :   self->_gapPool = gap;
+     191             : }
+     192             : 
+     193           0 : static void ConstPool_addGap(ConstPool* self, size_t offset, size_t length) noexcept {
+     194             :   ASMJIT_ASSERT(length > 0);
+     195             : 
+     196           0 :   while (length > 0) {
+     197             :     size_t gapIndex;
+     198             :     size_t gapLength;
+     199             : 
+     200             :       gapIndex = ConstPool::kIndex16;
+     201           0 :     if (length >= 16 && Utils::isAligned<size_t>(offset, 16)) {
+     202             :       gapLength = 16;
+     203             :     }
+     204           0 :     else if (length >= 8 && Utils::isAligned<size_t>(offset, 8)) {
+     205             :       gapIndex = ConstPool::kIndex8;
+     206             :       gapLength = 8;
+     207             :     }
+     208           0 :     else if (length >= 4 && Utils::isAligned<size_t>(offset, 4)) {
+     209             :       gapIndex = ConstPool::kIndex4;
+     210             :       gapLength = 4;
+     211             :     }
+     212           0 :     else if (length >= 2 && Utils::isAligned<size_t>(offset, 2)) {
+     213             :       gapIndex = ConstPool::kIndex2;
+     214             :       gapLength = 2;
+     215             :     }
+     216             :     else {
+     217             :       gapIndex = ConstPool::kIndex1;
+     218             :       gapLength = 1;
+     219             :     }
+     220             : 
+     221             :     // We don't have to check for errors here, if this failed nothing really
+     222             :     // happened (just the gap won't be visible) and it will fail again at
+     223             :     // place where checking will cause kErrorNoHeapMemory.
+     224             :     ConstPool::Gap* gap = ConstPool_allocGap(self);
+     225           0 :     if (!gap) return;
+     226             : 
+     227           0 :     gap->_next = self->_gaps[gapIndex];
+     228           0 :     self->_gaps[gapIndex] = gap;
+     229             : 
+     230           0 :     gap->_offset = offset;
+     231           0 :     gap->_length = gapLength;
+     232             : 
+     233           0 :     offset += gapLength;
+     234           0 :     length -= gapLength;
+     235             :   }
+     236             : }
+     237             : 
+     238           0 : Error ConstPool::add(const void* data, size_t size, size_t& dstOffset) noexcept {
+     239             :   size_t treeIndex;
+     240             : 
+     241           0 :   if (size == 32)
+     242             :     treeIndex = kIndex32;
+     243             :   else if (size == 16)
+     244             :     treeIndex = kIndex16;
+     245             :   else if (size == 8)
+     246             :     treeIndex = kIndex8;
+     247             :   else if (size == 4)
+     248             :     treeIndex = kIndex4;
+     249             :   else if (size == 2)
+     250             :     treeIndex = kIndex2;
+     251             :   else if (size == 1)
+     252             :     treeIndex = kIndex1;
+     253             :   else
+     254             :     return DebugUtils::errored(kErrorInvalidArgument);
+     255             : 
+     256           0 :   ConstPool::Node* node = _tree[treeIndex].get(data);
+     257           0 :   if (node) {
+     258           0 :     dstOffset = node->_offset;
+     259           0 :     return kErrorOk;
+     260             :   }
+     261             : 
+     262             :   // Before incrementing the current offset try if there is a gap that can
+     263             :   // be used for the requested data.
+     264             :   size_t offset = ~static_cast<size_t>(0);
+     265             :   size_t gapIndex = treeIndex;
+     266             : 
+     267           0 :   while (gapIndex != kIndexCount - 1) {
+     268           0 :     ConstPool::Gap* gap = _gaps[treeIndex];
+     269             : 
+     270             :     // Check if there is a gap.
+     271           0 :     if (gap) {
+     272           0 :       size_t gapOffset = gap->_offset;
+     273           0 :       size_t gapLength = gap->_length;
+     274             : 
+     275             :       // Destroy the gap for now.
+     276           0 :       _gaps[treeIndex] = gap->_next;
+     277             :       ConstPool_freeGap(this, gap);
+     278             : 
+     279             :       offset = gapOffset;
+     280             :       ASMJIT_ASSERT(Utils::isAligned<size_t>(offset, size));
+     281             : 
+     282           0 :       gapLength -= size;
+     283           0 :       if (gapLength > 0)
+     284           0 :         ConstPool_addGap(this, gapOffset, gapLength);
+     285             :     }
+     286             : 
+     287           0 :     gapIndex++;
+     288             :   }
+     289             : 
+     290           0 :   if (offset == ~static_cast<size_t>(0)) {
+     291             :     // Get how many bytes have to be skipped so the address is aligned accordingly
+     292             :     // to the 'size'.
+     293           0 :     size_t diff = Utils::alignDiff<size_t>(_size, size);
+     294             : 
+     295           0 :     if (diff != 0) {
+     296           0 :       ConstPool_addGap(this, _size, diff);
+     297           0 :       _size += diff;
+     298             :     }
+     299             : 
+     300           0 :     offset = _size;
+     301           0 :     _size += size;
+     302             :   }
+     303             : 
+     304             :   // Add the initial node to the right index.
+     305           0 :   node = ConstPool::Tree::_newNode(_zone, data, size, offset, false);
+     306           0 :   if (!node) return DebugUtils::errored(kErrorNoHeapMemory);
+     307             : 
+     308           0 :   _tree[treeIndex].put(node);
+     309           0 :   _alignment = std::max<size_t>(_alignment, size);
+     310             : 
+     311           0 :   dstOffset = offset;
+     312             : 
+     313             :   // Now create a bunch of shared constants that are based on the data pattern.
+     314             :   // We stop at size 4, it probably doesn't make sense to split constants down
+     315             :   // to 1 byte.
+     316             :   size_t pCount = 1;
+     317           0 :   while (size > 4) {
+     318           0 :     size >>= 1;
+     319           0 :     pCount <<= 1;
+     320             : 
+     321             :     ASMJIT_ASSERT(treeIndex != 0);
+     322           0 :     treeIndex--;
+     323             : 
+     324             :     const uint8_t* pData = static_cast<const uint8_t*>(data);
+     325           0 :     for (size_t i = 0; i < pCount; i++, pData += size) {
+     326           0 :       node = _tree[treeIndex].get(pData);
+     327           0 :       if (node) continue;
+     328             : 
+     329           0 :       node = ConstPool::Tree::_newNode(_zone, pData, size, offset + (i * size), true);
+     330           0 :       _tree[treeIndex].put(node);
+     331             :     }
+     332             :   }
+     333             : 
+     334             :   return kErrorOk;
+     335             : }
+     336             : 
+     337             : // ============================================================================
+     338             : // [asmjit::ConstPool - Reset]
+     339             : // ============================================================================
+     340             : 
+     341             : struct ConstPoolFill {
+     342             :   ASMJIT_INLINE ConstPoolFill(uint8_t* dst, size_t dataSize) noexcept :
+     343             :     _dst(dst),
+     344             :     _dataSize(dataSize) {}
+     345             : 
+     346             :   ASMJIT_INLINE void visit(const ConstPool::Node* node) noexcept {
+     347           0 :     if (!node->_shared)
+     348           0 :       ::memcpy(_dst + node->_offset, node->getData(), _dataSize);
+     349             :   }
+     350             : 
+     351             :   uint8_t* _dst;
+     352             :   size_t _dataSize;
+     353             : };
+     354             : 
+     355           0 : void ConstPool::fill(void* dst) const noexcept {
+     356             :   // Clears possible gaps, asmjit should never emit garbage to the output.
+     357           0 :   ::memset(dst, 0, _size);
+     358             : 
+     359             :   ConstPoolFill filler(static_cast<uint8_t*>(dst), 1);
+     360           0 :   for (size_t i = 0; i < ASMJIT_ARRAY_SIZE(_tree); i++) {
+     361             :     _tree[i].iterate(filler);
+     362           0 :     filler._dataSize <<= 1;
+     363             :   }
+     364           0 : }
+     365             : 
+     366             : // ============================================================================
+     367             : // [asmjit::ConstPool - Test]
+     368             : // ============================================================================
+     369             : 
+     370             : #if defined(ASMJIT_TEST)
+     371             : UNIT(base_constpool) {
+     372             :   Zone zone(32384 - Zone::kZoneOverhead);
+     373             :   ConstPool pool(&zone);
+     374             : 
+     375             :   uint32_t i;
+     376             :   uint32_t kCount = 1000000;
+     377             : 
+     378             :   INFO("Adding %u constants to the pool.", kCount);
+     379             :   {
+     380             :     size_t prevOffset;
+     381             :     size_t curOffset;
+     382             :     uint64_t c = ASMJIT_UINT64_C(0x0101010101010101);
+     383             : 
+     384             :     EXPECT(pool.add(&c, 8, prevOffset) == kErrorOk,
+     385             :       "pool.add() - Returned error");
+     386             :     EXPECT(prevOffset == 0,
+     387             :       "pool.add() - First constant should have zero offset");
+     388             : 
+     389             :     for (i = 1; i < kCount; i++) {
+     390             :       c++;
+     391             :       EXPECT(pool.add(&c, 8, curOffset) == kErrorOk,
+     392             :         "pool.add() - Returned error");
+     393             :       EXPECT(prevOffset + 8 == curOffset,
+     394             :         "pool.add() - Returned incorrect curOffset");
+     395             :       EXPECT(pool.getSize() == (i + 1) * 8,
+     396             :         "pool.getSize() - Reported incorrect size");
+     397             :       prevOffset = curOffset;
+     398             :     }
+     399             : 
+     400             :     EXPECT(pool.getAlignment() == 8,
+     401             :       "pool.getAlignment() - Expected 8-byte alignment");
+     402             :   }
+     403             : 
+     404             :   INFO("Retrieving %u constants from the pool.", kCount);
+     405             :   {
+     406             :     uint64_t c = ASMJIT_UINT64_C(0x0101010101010101);
+     407             : 
+     408             :     for (i = 0; i < kCount; i++) {
+     409             :       size_t offset;
+     410             :       EXPECT(pool.add(&c, 8, offset) == kErrorOk,
+     411             :         "pool.add() - Returned error");
+     412             :       EXPECT(offset == i * 8,
+     413             :         "pool.add() - Should have reused constant");
+     414             :       c++;
+     415             :     }
+     416             :   }
+     417             : 
+     418             :   INFO("Checking if the constants were split into 4-byte patterns");
+     419             :   {
+     420             :     uint32_t c = 0x01010101;
+     421             :     for (i = 0; i < kCount; i++) {
+     422             :       size_t offset;
+     423             :       EXPECT(pool.add(&c, 4, offset) == kErrorOk,
+     424             :         "pool.add() - Returned error");
+     425             :       EXPECT(offset == i * 8,
+     426             :         "pool.add() - Should reuse existing constant");
+     427             :       c++;
+     428             :     }
+     429             :   }
+     430             : 
+     431             :   INFO("Adding 2 byte constant to misalign the current offset");
+     432             :   {
+     433             :     uint16_t c = 0xFFFF;
+     434             :     size_t offset;
+     435             : 
+     436             :     EXPECT(pool.add(&c, 2, offset) == kErrorOk,
+     437             :       "pool.add() - Returned error");
+     438             :     EXPECT(offset == kCount * 8,
+     439             :       "pool.add() - Didn't return expected position");
+     440             :     EXPECT(pool.getAlignment() == 8,
+     441             :       "pool.getAlignment() - Expected 8-byte alignment");
+     442             :   }
+     443             : 
+     444             :   INFO("Adding 8 byte constant to check if pool gets aligned again");
+     445             :   {
+     446             :     uint64_t c = ASMJIT_UINT64_C(0xFFFFFFFFFFFFFFFF);
+     447             :     size_t offset;
+     448             : 
+     449             :     EXPECT(pool.add(&c, 8, offset) == kErrorOk,
+     450             :       "pool.add() - Returned error");
+     451             :     EXPECT(offset == kCount * 8 + 8,
+     452             :       "pool.add() - Didn't return aligned offset");
+     453             :   }
+     454             : 
+     455             :   INFO("Adding 2 byte constant to verify the gap is filled");
+     456             :   {
+     457             :     uint16_t c = 0xFFFE;
+     458             :     size_t offset;
+     459             : 
+     460             :     EXPECT(pool.add(&c, 2, offset) == kErrorOk,
+     461             :       "pool.add() - Returned error");
+     462             :     EXPECT(offset == kCount * 8 + 2,
+     463             :       "pool.add() - Didn't fill the gap");
+     464             :     EXPECT(pool.getAlignment() == 8,
+     465             :       "pool.getAlignment() - Expected 8-byte alignment");
+     466             :   }
+     467             : 
+     468             :   INFO("Checking reset functionality");
+     469             :   {
+     470             :     pool.reset(&zone);
+     471             :     zone.reset();
+     472             : 
+     473             :     EXPECT(pool.getSize() == 0,
+     474             :       "pool.getSize() - Expected pool size to be zero");
+     475             :     EXPECT(pool.getAlignment() == 0,
+     476             :       "pool.getSize() - Expected pool alignment to be zero");
+     477             :   }
+     478             : 
+     479             :   INFO("Checking pool alignment when combined constants are added");
+     480             :   {
+     481             :     uint8_t bytes[32] = { 0 };
+     482             :     size_t offset;
+     483             : 
+     484             :     pool.add(bytes, 1, offset);
+     485             : 
+     486             :     EXPECT(pool.getSize() == 1,
+     487             :       "pool.getSize() - Expected pool size to be 1 byte");
+     488             :     EXPECT(pool.getAlignment() == 1,
+     489             :       "pool.getSize() - Expected pool alignment to be 1 byte");
+     490             :     EXPECT(offset == 0,
+     491             :       "pool.getSize() - Expected offset returned to be zero");
+     492             : 
+     493             :     pool.add(bytes, 2, offset);
+     494             : 
+     495             :     EXPECT(pool.getSize() == 4,
+     496             :       "pool.getSize() - Expected pool size to be 4 bytes");
+     497             :     EXPECT(pool.getAlignment() == 2,
+     498             :       "pool.getSize() - Expected pool alignment to be 2 bytes");
+     499             :     EXPECT(offset == 2,
+     500             :       "pool.getSize() - Expected offset returned to be 2");
+     501             : 
+     502             :     pool.add(bytes, 4, offset);
+     503             : 
+     504             :     EXPECT(pool.getSize() == 8,
+     505             :       "pool.getSize() - Expected pool size to be 8 bytes");
+     506             :     EXPECT(pool.getAlignment() == 4,
+     507             :       "pool.getSize() - Expected pool alignment to be 4 bytes");
+     508             :     EXPECT(offset == 4,
+     509             :       "pool.getSize() - Expected offset returned to be 4");
+     510             : 
+     511             :     pool.add(bytes, 4, offset);
+     512             : 
+     513             :     EXPECT(pool.getSize() == 8,
+     514             :       "pool.getSize() - Expected pool size to be 8 bytes");
+     515             :     EXPECT(pool.getAlignment() == 4,
+     516             :       "pool.getSize() - Expected pool alignment to be 4 bytes");
+     517             :     EXPECT(offset == 4,
+     518             :       "pool.getSize() - Expected offset returned to be 8");
+     519             : 
+     520             :     pool.add(bytes, 32, offset);
+     521             :     EXPECT(pool.getSize() == 64,
+     522             :       "pool.getSize() - Expected pool size to be 64 bytes");
+     523             :     EXPECT(pool.getAlignment() == 32,
+     524             :       "pool.getSize() - Expected pool alignment to be 32 bytes");
+     525             :     EXPECT(offset == 32,
+     526             :       "pool.getSize() - Expected offset returned to be 32");
+     527             :   }
+     528             : }
+     529             : #endif // ASMJIT_TEST
+     530             : 
+     531             : } // asmjit namespace
+     532             : } // namespace PLMD
+     533             : 
+     534             : // [Api-End]
+     535             : #include "./asmjit_apiend.h"
+     536             : #pragma GCC diagnostic pop
+     537             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/constpool.h.func-sort-c.html b/coverage-libs/asmjit/constpool.h.func-sort-c.html new file mode 100644 index 000000000000..a762ac7c9b87 --- /dev/null +++ b/coverage-libs/asmjit/constpool.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0310.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/constpool.h.func.html b/coverage-libs/asmjit/constpool.h.func.html new file mode 100644 index 000000000000..c1e55035e3d4 --- /dev/null +++ b/coverage-libs/asmjit/constpool.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0310.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/constpool.h.gcov.html b/coverage-libs/asmjit/constpool.h.gcov.html new file mode 100644 index 000000000000..664aed5efdc0 --- /dev/null +++ b/coverage-libs/asmjit/constpool.h.gcov.html @@ -0,0 +1,363 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/constpool.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - constpool.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0310.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_constpool_h
+      21             : #define __PLUMED_asmjit_constpool_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_CONSTPOOL_H
+      33             : #define _ASMJIT_BASE_CONSTPOOL_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./zone.h"
+      37             : 
+      38             : // [Api-Begin]
+      39             : #include "./asmjit_apibegin.h"
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace asmjit {
+      43             : 
+      44             : //! \addtogroup asmjit_base
+      45             : //! \{
+      46             : 
+      47             : // ============================================================================
+      48             : // [asmjit::ConstPool]
+      49             : // ============================================================================
+      50             : 
+      51             : //! Constant pool.
+      52             : class ConstPool {
+      53             : public:
+      54             :   ASMJIT_NONCOPYABLE(ConstPool)
+      55             : 
+      56             :   enum {
+      57             :     kIndex1 = 0,
+      58             :     kIndex2 = 1,
+      59             :     kIndex4 = 2,
+      60             :     kIndex8 = 3,
+      61             :     kIndex16 = 4,
+      62             :     kIndex32 = 5,
+      63             :     kIndexCount = 6
+      64             :   };
+      65             : 
+      66             :   // --------------------------------------------------------------------------
+      67             :   // [Gap]
+      68             :   // --------------------------------------------------------------------------
+      69             : 
+      70             :   //! \internal
+      71             :   //!
+      72             :   //! Zone-allocated const-pool gap.
+      73             :   struct Gap {
+      74             :     Gap* _next;                          //!< Pointer to the next gap
+      75             :     size_t _offset;                      //!< Offset of the gap.
+      76             :     size_t _length;                      //!< Remaining bytes of the gap (basically a gap size).
+      77             :   };
+      78             : 
+      79             :   // --------------------------------------------------------------------------
+      80             :   // [Node]
+      81             :   // --------------------------------------------------------------------------
+      82             : 
+      83             :   //! \internal
+      84             :   //!
+      85             :   //! Zone-allocated const-pool node.
+      86             :   struct Node {
+      87             :     ASMJIT_INLINE void* getData() const noexcept {
+      88           0 :       return static_cast<void*>(const_cast<ConstPool::Node*>(this) + 1);
+      89             :     }
+      90             : 
+      91             :     Node* _link[2];                      //!< Left/Right nodes.
+      92             :     uint32_t _level : 31;                //!< Horizontal level for balance.
+      93             :     uint32_t _shared : 1;                //!< If this constant is shared with another.
+      94             :     uint32_t _offset;                    //!< Data offset from the beginning of the pool.
+      95             :   };
+      96             : 
+      97             :   // --------------------------------------------------------------------------
+      98             :   // [Tree]
+      99             :   // --------------------------------------------------------------------------
+     100             : 
+     101             :   //! \internal
+     102             :   //!
+     103             :   //! Zone-allocated const-pool tree.
+     104             :   struct Tree {
+     105             :     enum {
+     106             :       //! Maximum tree height == log2(1 << 64).
+     107             :       kHeightLimit = 64
+     108             :     };
+     109             : 
+     110             :     // --------------------------------------------------------------------------
+     111             :     // [Construction / Destruction]
+     112             :     // --------------------------------------------------------------------------
+     113             : 
+     114             :     ASMJIT_INLINE Tree(size_t dataSize = 0) noexcept
+     115           0 :       : _root(nullptr),
+     116           0 :         _length(0),
+     117           0 :         _dataSize(dataSize) {}
+     118           0 :     ASMJIT_INLINE ~Tree() {}
+     119             : 
+     120             :     // --------------------------------------------------------------------------
+     121             :     // [Reset]
+     122             :     // --------------------------------------------------------------------------
+     123             : 
+     124             :     ASMJIT_INLINE void reset() noexcept {
+     125           0 :       _root = nullptr;
+     126           0 :       _length = 0;
+     127             :     }
+     128             : 
+     129             :     // --------------------------------------------------------------------------
+     130             :     // [Accessors]
+     131             :     // --------------------------------------------------------------------------
+     132             : 
+     133             :     ASMJIT_INLINE bool isEmpty() const noexcept { return _length == 0; }
+     134             :     ASMJIT_INLINE size_t getLength() const noexcept { return _length; }
+     135             : 
+     136             :     ASMJIT_INLINE void setDataSize(size_t dataSize) noexcept {
+     137             :       ASMJIT_ASSERT(isEmpty());
+     138           0 :       _dataSize = dataSize;
+     139             :     }
+     140             : 
+     141             :     // --------------------------------------------------------------------------
+     142             :     // [Ops]
+     143             :     // --------------------------------------------------------------------------
+     144             : 
+     145             :     ASMJIT_API Node* get(const void* data) noexcept;
+     146             :     ASMJIT_API void put(Node* node) noexcept;
+     147             : 
+     148             :     // --------------------------------------------------------------------------
+     149             :     // [Iterate]
+     150             :     // --------------------------------------------------------------------------
+     151             : 
+     152             :     template<typename Visitor>
+     153             :     ASMJIT_INLINE void iterate(Visitor& visitor) const noexcept {
+     154           0 :       Node* node = const_cast<Node*>(_root);
+     155           0 :       if (!node) return;
+     156             : 
+     157             :       Node* stack[kHeightLimit];
+     158             :       size_t top = 0;
+     159             : 
+     160             :       for (;;) {
+     161           0 :         Node* left = node->_link[0];
+     162           0 :         if (left != nullptr) {
+     163             :           ASMJIT_ASSERT(top != kHeightLimit);
+     164           0 :           stack[top++] = node;
+     165             : 
+     166             :           node = left;
+     167           0 :           continue;
+     168             :         }
+     169             : 
+     170           0 : Visit:
+     171             :         visitor.visit(node);
+     172           0 :         node = node->_link[1];
+     173           0 :         if (node != nullptr)
+     174           0 :           continue;
+     175             : 
+     176           0 :         if (top == 0)
+     177             :           return;
+     178             : 
+     179           0 :         node = stack[--top];
+     180           0 :         goto Visit;
+     181             :       }
+     182             :     }
+     183             : 
+     184             :     // --------------------------------------------------------------------------
+     185             :     // [Helpers]
+     186             :     // --------------------------------------------------------------------------
+     187             : 
+     188             :     static ASMJIT_INLINE Node* _newNode(Zone* zone, const void* data, size_t size, size_t offset, bool shared) noexcept {
+     189           0 :       Node* node = zone->allocT<Node>(sizeof(Node) + size);
+     190           0 :       if (ASMJIT_UNLIKELY(!node)) return nullptr;
+     191             : 
+     192           0 :       node->_link[0] = nullptr;
+     193           0 :       node->_link[1] = nullptr;
+     194           0 :       node->_level = 1;
+     195           0 :       node->_shared = shared;
+     196           0 :       node->_offset = static_cast<uint32_t>(offset);
+     197             : 
+     198             :       ::memcpy(node->getData(), data, size);
+     199           0 :       return node;
+     200             :     }
+     201             : 
+     202             :     // --------------------------------------------------------------------------
+     203             :     // [Members]
+     204             :     // --------------------------------------------------------------------------
+     205             : 
+     206             :     Node* _root;                         //!< Root of the tree
+     207             :     size_t _length;                      //!< Length of the tree (count of nodes).
+     208             :     size_t _dataSize;                    //!< Size of the data.
+     209             :   };
+     210             : 
+     211             :   // --------------------------------------------------------------------------
+     212             :   // [Construction / Destruction]
+     213             :   // --------------------------------------------------------------------------
+     214             : 
+     215             :   ASMJIT_API ConstPool(Zone* zone) noexcept;
+     216             :   ASMJIT_API ~ConstPool() noexcept;
+     217             : 
+     218             :   // --------------------------------------------------------------------------
+     219             :   // [Reset]
+     220             :   // --------------------------------------------------------------------------
+     221             : 
+     222             :   ASMJIT_API void reset(Zone* zone) noexcept;
+     223             : 
+     224             :   // --------------------------------------------------------------------------
+     225             :   // [Ops]
+     226             :   // --------------------------------------------------------------------------
+     227             : 
+     228             :   //! Get whether the constant-pool is empty.
+     229             :   ASMJIT_INLINE bool isEmpty() const noexcept { return _size == 0; }
+     230             :   //! Get the size of the constant-pool in bytes.
+     231           0 :   ASMJIT_INLINE size_t getSize() const noexcept { return _size; }
+     232             :   //! Get minimum alignment.
+     233           0 :   ASMJIT_INLINE size_t getAlignment() const noexcept { return _alignment; }
+     234             : 
+     235             :   //! Add a constant to the constant pool.
+     236             :   //!
+     237             :   //! The constant must have known size, which is 1, 2, 4, 8, 16 or 32 bytes.
+     238             :   //! The constant is added to the pool only if it doesn't not exist, otherwise
+     239             :   //! cached value is returned.
+     240             :   //!
+     241             :   //! AsmJit is able to subdivide added constants, so for example if you add
+     242             :   //! 8-byte constant 0x1122334455667788 it will create the following slots:
+     243             :   //!
+     244             :   //!   8-byte: 0x1122334455667788
+     245             :   //!   4-byte: 0x11223344, 0x55667788
+     246             :   //!
+     247             :   //! The reason is that when combining MMX/SSE/AVX code some patterns are used
+     248             :   //! frequently. However, AsmJit is not able to reallocate a constant that has
+     249             :   //! been already added. For example if you try to add 4-byte constant and then
+     250             :   //! 8-byte constant having the same 4-byte pattern as the previous one, two
+     251             :   //! independent slots will be generated by the pool.
+     252             :   ASMJIT_API Error add(const void* data, size_t size, size_t& dstOffset) noexcept;
+     253             : 
+     254             :   // --------------------------------------------------------------------------
+     255             :   // [Fill]
+     256             :   // --------------------------------------------------------------------------
+     257             : 
+     258             :   //! Fill the destination with the constants from the pool.
+     259             :   ASMJIT_API void fill(void* dst) const noexcept;
+     260             : 
+     261             :   // --------------------------------------------------------------------------
+     262             :   // [Members]
+     263             :   // --------------------------------------------------------------------------
+     264             : 
+     265             :   Zone* _zone;                           //!< Zone allocator.
+     266             :   Tree _tree[kIndexCount];               //!< Tree per size.
+     267             :   Gap* _gaps[kIndexCount];               //!< Gaps per size.
+     268             :   Gap* _gapPool;                         //!< Gaps pool
+     269             : 
+     270             :   size_t _size;                          //!< Size of the pool (in bytes).
+     271             :   size_t _alignment;                     //!< Required pool alignment.
+     272             : };
+     273             : 
+     274             : //! \}
+     275             : 
+     276             : } // asmjit namespace
+     277             : } // namespace PLMD
+     278             : 
+     279             : // [Api-End]
+     280             : #include "./asmjit_apiend.h"
+     281             : 
+     282             : // [Guard]
+     283             : #endif // _ASMJIT_BASE_CONSTPOOL_H
+     284             : #pragma GCC diagnostic pop
+     285             : #endif // __PLUMED_HAS_ASMJIT
+     286             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.cpp.func-sort-c.html b/coverage-libs/asmjit/cpuinfo.cpp.func-sort-c.html new file mode 100644 index 000000000000..ca56359c0563 --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/cpuinfo.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - cpuinfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:13714991.9 %
Date:2024-02-22 21:58:47Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7CpuInfo6detectEv70
_ZN4PLMD6asmjitL16x86DetectCpuInfoEPNS0_7CpuInfoE70
_ZN4PLMD6asmjit7CpuInfo7getHostEv1976
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.cpp.func.html b/coverage-libs/asmjit/cpuinfo.cpp.func.html new file mode 100644 index 000000000000..29fef032812a --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/cpuinfo.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - cpuinfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:13714991.9 %
Date:2024-02-22 21:58:47Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7CpuInfo6detectEv70
_ZN4PLMD6asmjit7CpuInfo7getHostEv1976
_ZN4PLMD6asmjitL16x86DetectCpuInfoEPNS0_7CpuInfoE70
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.cpp.gcov.html b/coverage-libs/asmjit/cpuinfo.cpp.gcov.html new file mode 100644 index 000000000000..bd830670479b --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.cpp.gcov.html @@ -0,0 +1,777 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/cpuinfo.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - cpuinfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:13714991.9 %
Date:2024-02-22 21:58:47Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./cpuinfo.h"
+      34             : #include "./utils.h"
+      35             : 
+      36             : #if ASMJIT_OS_POSIX
+      37             : # include <errno.h>
+      38             : # include <sys/utsname.h>
+      39             : # include <unistd.h>
+      40             : #endif // ASMJIT_OS_POSIX
+      41             : 
+      42             : #if ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
+      43             : # if ASMJIT_CC_MSC_GE(14, 0, 0)
+      44             :  # include <intrin.h>         // Required by `__cpuid()` and `_xgetbv()`.
+      45             : # endif // _MSC_VER >= 1400
+      46             : #endif
+      47             : 
+      48             : #if ASMJIT_ARCH_ARM32 || ASMJIT_ARCH_ARM64
+      49             : # if ASMJIT_OS_LINUX
+      50             : #  include <sys/auxv.h>       // Required by `getauxval()`.
+      51             : # endif
+      52             : #endif
+      53             : 
+      54             : // [Api-Begin]
+      55             : #include "./asmjit_apibegin.h"
+      56             : 
+      57             : namespace PLMD {
+      58             : namespace asmjit {
+      59             : 
+      60             : // ============================================================================
+      61             : // [asmjit::CpuInfo - Detect ARM]
+      62             : // ============================================================================
+      63             : 
+      64             : // ARM information has to be retrieved by the OS (this is how ARM was designed).
+      65             : #if ASMJIT_ARCH_ARM32 || ASMJIT_ARCH_ARM64
+      66             : 
+      67             : #if ASMJIT_ARCH_ARM32
+      68             : static ASMJIT_INLINE void armPopulateBaselineA32Features(CpuInfo* cpuInfo) noexcept {
+      69             :   cpuInfo->_archInfo.init(ArchInfo::kTypeA32);
+      70             : }
+      71             : #endif // ASMJIT_ARCH_ARM32
+      72             : 
+      73             : #if ASMJIT_ARCH_ARM64
+      74             : static ASMJIT_INLINE void armPopulateBaselineA64Features(CpuInfo* cpuInfo) noexcept {
+      75             :   cpuInfo->_archInfo.init(ArchInfo::kTypeA64);
+      76             : 
+      77             :   // Thumb (including all variations) is supported on A64 (but not accessible from A64).
+      78             :   cpuInfo->addFeature(CpuInfo::kArmFeatureTHUMB);
+      79             :   cpuInfo->addFeature(CpuInfo::kArmFeatureTHUMB2);
+      80             : 
+      81             :   // A64 is based on ARMv8 and newer.
+      82             :   cpuInfo->addFeature(CpuInfo::kArmFeatureV6);
+      83             :   cpuInfo->addFeature(CpuInfo::kArmFeatureV7);
+      84             :   cpuInfo->addFeature(CpuInfo::kArmFeatureV8);
+      85             : 
+      86             :   // A64 comes with these features by default.
+      87             :   cpuInfo->addFeature(CpuInfo::kArmFeatureVFPv2);
+      88             :   cpuInfo->addFeature(CpuInfo::kArmFeatureVFPv3);
+      89             :   cpuInfo->addFeature(CpuInfo::kArmFeatureVFPv4);
+      90             :   cpuInfo->addFeature(CpuInfo::kArmFeatureEDSP);
+      91             :   cpuInfo->addFeature(CpuInfo::kArmFeatureASIMD);
+      92             :   cpuInfo->addFeature(CpuInfo::kArmFeatureIDIVA);
+      93             :   cpuInfo->addFeature(CpuInfo::kArmFeatureIDIVT);
+      94             : }
+      95             : #endif // ASMJIT_ARCH_ARM64
+      96             : 
+      97             : #if ASMJIT_OS_WINDOWS
+      98             : //! \internal
+      99             : //!
+     100             : //! Detect ARM CPU features on Windows.
+     101             : //!
+     102             : //! The detection is based on `IsProcessorFeaturePresent()` API call.
+     103             : static ASMJIT_INLINE void armDetectCpuInfoOnWindows(CpuInfo* cpuInfo) noexcept {
+     104             : #if ASMJIT_ARCH_ARM32
+     105             :   armPopulateBaselineA32Features(cpuInfo);
+     106             : 
+     107             :   // Windows for ARM requires at least ARMv7 with DSP extensions.
+     108             :   cpuInfo->addFeature(CpuInfo::kArmFeatureV6);
+     109             :   cpuInfo->addFeature(CpuInfo::kArmFeatureV7);
+     110             :   cpuInfo->addFeature(CpuInfo::kArmFeatureEDSP);
+     111             : 
+     112             :   // Windows for ARM requires VFPv3.
+     113             :   cpuInfo->addFeature(CpuInfo::kArmFeatureVFPv2);
+     114             :   cpuInfo->addFeature(CpuInfo::kArmFeatureVFPv3);
+     115             : 
+     116             :   // Windows for ARM requires and uses THUMB2.
+     117             :   cpuInfo->addFeature(CpuInfo::kArmFeatureTHUMB);
+     118             :   cpuInfo->addFeature(CpuInfo::kArmFeatureTHUMB2);
+     119             : #else
+     120             :   armPopulateBaselineA64Features(cpuInfo);
+     121             : #endif
+     122             : 
+     123             :   // Windows for ARM requires ASIMD.
+     124             :   cpuInfo->addFeature(CpuInfo::kArmFeatureASIMD);
+     125             : 
+     126             :   // Detect additional CPU features by calling `IsProcessorFeaturePresent()`.
+     127             :   struct WinPFPMapping {
+     128             :     uint32_t pfpId;
+     129             :     uint32_t featureId;
+     130             :   };
+     131             : 
+     132             :   static const WinPFPMapping mapping[] = {
+     133             :     { PF_ARM_FMAC_INSTRUCTIONS_AVAILABLE , CpuInfo::kArmFeatureVFPv4     },
+     134             :     { PF_ARM_VFP_32_REGISTERS_AVAILABLE  , CpuInfo::kArmFeatureVFP_D32   },
+     135             :     { PF_ARM_DIVIDE_INSTRUCTION_AVAILABLE, CpuInfo::kArmFeatureIDIVT     },
+     136             :     { PF_ARM_64BIT_LOADSTORE_ATOMIC      , CpuInfo::kArmFeatureAtomics64 }
+     137             :   };
+     138             : 
+     139             :   for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(mapping); i++)
+     140             :     if (::IsProcessorFeaturePresent(mapping[i].pfpId))
+     141             :       cpuInfo->addFeature(mapping[i].featureId);
+     142             : }
+     143             : #endif // ASMJIT_OS_WINDOWS
+     144             : 
+     145             : #if ASMJIT_OS_LINUX
+     146             : struct LinuxHWCapMapping {
+     147             :   uint32_t hwcapMask;
+     148             :   uint32_t featureId;
+     149             : };
+     150             : 
+     151             : static void armDetectHWCaps(CpuInfo* cpuInfo, unsigned long type, const LinuxHWCapMapping* mapping, size_t length) noexcept {
+     152             :   unsigned long mask = getauxval(type);
+     153             : 
+     154             :   for (size_t i = 0; i < length; i++)
+     155             :     if ((mask & mapping[i].hwcapMask) == mapping[i].hwcapMask)
+     156             :       cpuInfo->addFeature(mapping[i].featureId);
+     157             : }
+     158             : 
+     159             : //! \internal
+     160             : //!
+     161             : //! Detect ARM CPU features on Linux.
+     162             : //!
+     163             : //! The detection is based on `getauxval()`.
+     164             : ASMJIT_FAVOR_SIZE static void armDetectCpuInfoOnLinux(CpuInfo* cpuInfo) noexcept {
+     165             : #if ASMJIT_ARCH_ARM32
+     166             :   armPopulateBaselineA32Features(cpuInfo);
+     167             : 
+     168             :   // `AT_HWCAP` provides ARMv7 (and less) related flags.
+     169             :   static const LinuxHWCapMapping hwCapMapping[] = {
+     170             :     { /* HWCAP_VFP     */ (1 <<  6), CpuInfo::kArmFeatureVFPv2     },
+     171             :     { /* HWCAP_EDSP    */ (1 <<  7), CpuInfo::kArmFeatureEDSP      },
+     172             :     { /* HWCAP_NEON    */ (1 << 12), CpuInfo::kArmFeatureASIMD     },
+     173             :     { /* HWCAP_VFPv3   */ (1 << 13), CpuInfo::kArmFeatureVFPv3     },
+     174             :     { /* HWCAP_VFPv4   */ (1 << 16), CpuInfo::kArmFeatureVFPv4     },
+     175             :     { /* HWCAP_IDIVA   */ (1 << 17), CpuInfo::kArmFeatureIDIVA     },
+     176             :     { /* HWCAP_IDIVT   */ (1 << 18), CpuInfo::kArmFeatureIDIVT     },
+     177             :     { /* HWCAP_VFPD32  */ (1 << 19), CpuInfo::kArmFeatureVFP_D32   }
+     178             :   };
+     179             :   armDetectHWCaps(cpuInfo, AT_HWCAP, hwCapMapping, ASMJIT_ARRAY_SIZE(hwCapMapping));
+     180             : 
+     181             :   // VFPv3 implies VFPv2.
+     182             :   if (cpuInfo->hasFeature(CpuInfo::kArmFeatureVFPv3)) {
+     183             :     cpuInfo->addFeature(CpuInfo::kArmFeatureVFPv2);
+     184             :   }
+     185             : 
+     186             :   // VFPv2 implies ARMv6.
+     187             :   if (cpuInfo->hasFeature(CpuInfo::kArmFeatureVFPv2)) {
+     188             :     cpuInfo->addFeature(CpuInfo::kArmFeatureV6);
+     189             :   }
+     190             : 
+     191             :   // VFPv3 or ASIMD implies ARMv7.
+     192             :   if (cpuInfo->hasFeature(CpuInfo::kArmFeatureVFPv3) ||
+     193             :       cpuInfo->hasFeature(CpuInfo::kArmFeatureASIMD)) {
+     194             :     cpuInfo->addFeature(CpuInfo::kArmFeatureV7);
+     195             :   }
+     196             : 
+     197             :   // `AT_HWCAP2` provides ARMv8+ related flags.
+     198             :   static const LinuxHWCapMapping hwCap2Mapping[] = {
+     199             :     { /* HWCAP2_AES    */ (1 <<  0), CpuInfo::kArmFeatureAES       },
+     200             :     { /* HWCAP2_PMULL  */ (1 <<  1), CpuInfo::kArmFeaturePMULL     },
+     201             :     { /* HWCAP2_SHA1   */ (1 <<  2), CpuInfo::kArmFeatureSHA1      },
+     202             :     { /* HWCAP2_SHA2   */ (1 <<  3), CpuInfo::kArmFeatureSHA256    },
+     203             :     { /* HWCAP2_CRC32  */ (1 <<  4), CpuInfo::kArmFeatureCRC32     }
+     204             :   };
+     205             :   armDetectHWCaps(cpuInfo, AT_HWCAP2, hwCap2Mapping, ASMJIT_ARRAY_SIZE(hwCap2Mapping));
+     206             : 
+     207             :   if (cpuInfo->hasFeature(CpuInfo::kArmFeatureAES   ) ||
+     208             :       cpuInfo->hasFeature(CpuInfo::kArmFeatureCRC32 ) ||
+     209             :       cpuInfo->hasFeature(CpuInfo::kArmFeaturePMULL ) ||
+     210             :       cpuInfo->hasFeature(CpuInfo::kArmFeatureSHA1  ) ||
+     211             :       cpuInfo->hasFeature(CpuInfo::kArmFeatureSHA256)) {
+     212             :     cpuInfo->addFeature(CpuInfo::kArmFeatureV8);
+     213             :   }
+     214             : #else
+     215             :   armPopulateBaselineA64Features(cpuInfo);
+     216             : 
+     217             :   // `AT_HWCAP` provides ARMv8+ related flags.
+     218             :   static const LinuxHWCapMapping hwCapMapping[] = {
+     219             :     { /* HWCAP_ASIMD   */ (1 <<  1), CpuInfo::kArmFeatureASIMD     },
+     220             :     { /* HWCAP_AES     */ (1 <<  3), CpuInfo::kArmFeatureAES       },
+     221             :     { /* HWCAP_CRC32   */ (1 <<  7), CpuInfo::kArmFeatureCRC32     },
+     222             :     { /* HWCAP_PMULL   */ (1 <<  4), CpuInfo::kArmFeaturePMULL     },
+     223             :     { /* HWCAP_SHA1    */ (1 <<  5), CpuInfo::kArmFeatureSHA1      },
+     224             :     { /* HWCAP_SHA2    */ (1 <<  6), CpuInfo::kArmFeatureSHA256    },
+     225             :     { /* HWCAP_ATOMICS */ (1 <<  8), CpuInfo::kArmFeatureAtomics64 }
+     226             :   };
+     227             :   armDetectHWCaps(cpuInfo, AT_HWCAP, hwCapMapping, ASMJIT_ARRAY_SIZE(hwCapMapping));
+     228             : 
+     229             :   // `AT_HWCAP2` is not used at the moment.
+     230             : #endif
+     231             : }
+     232             : #endif // ASMJIT_OS_LINUX
+     233             : 
+     234             : ASMJIT_FAVOR_SIZE static void armDetectCpuInfo(CpuInfo* cpuInfo) noexcept {
+     235             : #if ASMJIT_OS_WINDOWS
+     236             :   armDetectCpuInfoOnWindows(cpuInfo);
+     237             : #elif ASMJIT_OS_LINUX
+     238             :   armDetectCpuInfoOnLinux(cpuInfo);
+     239             : #else
+     240             : # error "[asmjit] armDetectCpuInfo() - Unsupported OS."
+     241             : #endif
+     242             : }
+     243             : #endif // ASMJIT_ARCH_ARM32 || ASMJIT_ARCH_ARM64
+     244             : 
+     245             : // ============================================================================
+     246             : // [asmjit::CpuInfo - Detect X86]
+     247             : // ============================================================================
+     248             : 
+     249             : #if ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
+     250             : 
+     251             : //! \internal
+     252             : //!
+     253             : //! X86 CPUID result.
+     254             : struct CpuIdResult {
+     255             :   uint32_t eax, ebx, ecx, edx;
+     256             : };
+     257             : 
+     258             : //! \internal
+     259             : //!
+     260             : //! Content of XCR register, result of XGETBV instruction.
+     261             : struct XGetBVResult {
+     262             :   uint32_t eax, edx;
+     263             : };
+     264             : 
+     265             : #if ASMJIT_CC_MSC && !ASMJIT_CC_MSC_GE(15, 0, 30729) && ASMJIT_ARCH_X64
+     266             : //! \internal
+     267             : //!
+     268             : //! HACK: VS2008 or less, 64-bit mode - `__cpuidex` doesn't exist! However,
+     269             : //! 64-bit calling convention specifies the first parameter to be passed by
+     270             : //! ECX, so we may be lucky if compiler doesn't move the register, otherwise
+     271             : //! the result would be wrong.
+     272             : static void ASMJIT_NOINLINE void x86CallCpuIdWorkaround(uint32_t inEcx, uint32_t inEax, CpuIdResult* result) noexcept {
+     273             :   __cpuid(reinterpret_cast<int*>(result), inEax);
+     274             : }
+     275             : #endif
+     276             : 
+     277             : //! \internal
+     278             : //!
+     279             : //! Wrapper to call `cpuid` instruction.
+     280             : static void ASMJIT_INLINE x86CallCpuId(CpuIdResult* result, uint32_t inEax, uint32_t inEcx = 0) noexcept {
+     281             : #if ASMJIT_CC_MSC && ASMJIT_CC_MSC_GE(15, 0, 30729)
+     282             :   __cpuidex(reinterpret_cast<int*>(result), inEax, inEcx);
+     283             : #elif ASMJIT_CC_MSC && ASMJIT_ARCH_X64
+     284             :   x86CallCpuIdWorkaround(inEcx, inEax, result);
+     285             : #elif ASMJIT_CC_MSC && ASMJIT_ARCH_X86
+     286             :   uint32_t paramEax = inEax;
+     287             :   uint32_t paramEcx = inEcx;
+     288             :   uint32_t* out = reinterpret_cast<uint32_t*>(result);
+     289             : 
+     290             :   __asm {
+     291             :     mov     eax, paramEax
+     292             :     mov     ecx, paramEcx
+     293             :     mov     edi, out
+     294             :     cpuid
+     295             :     mov     dword ptr[edi +  0], eax
+     296             :     mov     dword ptr[edi +  4], ebx
+     297             :     mov     dword ptr[edi +  8], ecx
+     298             :     mov     dword ptr[edi + 12], edx
+     299             :   }
+     300             : #elif (ASMJIT_CC_GCC || ASMJIT_CC_CLANG) && ASMJIT_ARCH_X86
+     301             :   __asm__ __volatile__(
+     302             :     "mov %%ebx, %%edi\n"
+     303             :     "cpuid\n"
+     304             :     "xchg %%edi, %%ebx\n"
+     305             :       : "=a"(result->eax),
+     306             :         "=D"(result->ebx),
+     307             :         "=c"(result->ecx),
+     308             :         "=d"(result->edx)
+     309             :       : "a"(inEax),
+     310             :         "c"(inEcx));
+     311             : #elif (ASMJIT_CC_GCC || ASMJIT_CC_CLANG || ASMJIT_CC_INTEL) && ASMJIT_ARCH_X64
+     312         770 :   __asm__ __volatile__(
+     313             :     "mov %%rbx, %%rdi\n"
+     314             :     "cpuid\n"
+     315             :     "xchg %%rdi, %%rbx\n"
+     316             :       : "=a"(result->eax),
+     317             :         "=D"(result->ebx),
+     318             :         "=c"(result->ecx),
+     319             :         "=d"(result->edx)
+     320             :       : "a"(inEax),
+     321             :         "c"(inEcx));
+     322             : #else
+     323             : # error "[asmjit] x86CallCpuid() - Unsupported compiler."
+     324             : #endif
+     325             : }
+     326             : 
+     327             : //! \internal
+     328             : //!
+     329             : //! Wrapper to call `xgetbv` instruction.
+     330             : static ASMJIT_INLINE void x86CallXGetBV(XGetBVResult* result, uint32_t inEcx) noexcept {
+     331             : #if ASMJIT_CC_MSC_GE(16, 0, 40219) // 2010SP1+
+     332             :   uint64_t value = _xgetbv(inEcx);
+     333             :   result->eax = static_cast<uint32_t>(value & 0xFFFFFFFFU);
+     334             :   result->edx = static_cast<uint32_t>(value >> 32);
+     335             : #elif ASMJIT_CC_GCC || ASMJIT_CC_CLANG
+     336             :   uint32_t outEax;
+     337             :   uint32_t outEdx;
+     338             : 
+     339             :   // Replaced, because the world is not perfect:
+     340             :   //   __asm__ __volatile__("xgetbv" : "=a"(outEax), "=d"(outEdx) : "c"(inEcx));
+     341          70 :   __asm__ __volatile__(".byte 0x0F, 0x01, 0xd0" : "=a"(outEax), "=d"(outEdx) : "c"(inEcx));
+     342             : 
+     343             :   result->eax = outEax;
+     344             :   result->edx = outEdx;
+     345             : #else
+     346             :   result->eax = 0;
+     347             :   result->edx = 0;
+     348             : #endif
+     349          70 : }
+     350             : 
+     351             : //! \internal
+     352             : //!
+     353             : //! Map a 12-byte vendor string returned by `cpuid` into a `CpuInfo::Vendor` ID.
+     354             : static ASMJIT_INLINE uint32_t x86GetCpuVendorID(const char* vendorString) noexcept {
+     355             :   struct VendorData {
+     356             :     uint32_t id;
+     357             :     char text[12];
+     358             :   };
+     359             : 
+     360             :   static const VendorData vendorList[] = {
+     361             :     { CpuInfo::kVendorIntel , { 'G', 'e', 'n', 'u', 'i', 'n', 'e', 'I', 'n', 't', 'e', 'l' } },
+     362             :     { CpuInfo::kVendorAMD   , { 'A', 'u', 't', 'h', 'e', 'n', 't', 'i', 'c', 'A', 'M', 'D' } },
+     363             :     { CpuInfo::kVendorVIA   , { 'V', 'I', 'A',  0 , 'V', 'I', 'A',  0 , 'V', 'I', 'A',  0  } },
+     364             :     { CpuInfo::kVendorVIA   , { 'C', 'e', 'n', 't', 'a', 'u', 'r', 'H', 'a', 'u', 'l', 's' } }
+     365             :   };
+     366             : 
+     367          70 :   uint32_t dw0 = reinterpret_cast<const uint32_t*>(vendorString)[0];
+     368          70 :   uint32_t dw1 = reinterpret_cast<const uint32_t*>(vendorString)[1];
+     369          70 :   uint32_t dw2 = reinterpret_cast<const uint32_t*>(vendorString)[2];
+     370             : 
+     371         140 :   for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(vendorList); i++) {
+     372         140 :     if (dw0 == reinterpret_cast<const uint32_t*>(vendorList[i].text)[0] &&
+     373          70 :         dw1 == reinterpret_cast<const uint32_t*>(vendorList[i].text)[1] &&
+     374          70 :         dw2 == reinterpret_cast<const uint32_t*>(vendorList[i].text)[2])
+     375          70 :       return vendorList[i].id;
+     376             :   }
+     377             : 
+     378             :   return CpuInfo::kVendorNone;
+     379             : }
+     380             : 
+     381             : static ASMJIT_INLINE void x86SimplifyBrandString(char* s) noexcept {
+     382             :   // Used to always clear the current character to ensure that the result
+     383             :   // doesn't contain garbage after the new zero terminator.
+     384             :   char* d = s;
+     385             : 
+     386             :   char prev = 0;
+     387          70 :   char curr = s[0];
+     388          70 :   s[0] = '\0';
+     389             : 
+     390             :   for (;;) {
+     391        3360 :     if (curr == 0)
+     392             :       break;
+     393             : 
+     394        3290 :     if (curr == ' ') {
+     395        1400 :       if (prev == '@' || s[1] == ' ' || s[1] == '@')
+     396        1050 :         goto L_Skip;
+     397             :     }
+     398             : 
+     399        2240 :     d[0] = curr;
+     400        2240 :     d++;
+     401             :     prev = curr;
+     402             : 
+     403        3290 : L_Skip:
+     404        3290 :     curr = *++s;
+     405        3290 :     s[0] = '\0';
+     406             :   }
+     407             : 
+     408          70 :   d[0] = '\0';
+     409             : }
+     410             : 
+     411          70 : ASMJIT_FAVOR_SIZE static void x86DetectCpuInfo(CpuInfo* cpuInfo) noexcept {
+     412             :   uint32_t i, maxId;
+     413             : 
+     414             :   CpuIdResult regs;
+     415             :   XGetBVResult xcr0 = { 0, 0 };
+     416             : 
+     417          70 :   cpuInfo->_archInfo.init(ArchInfo::kTypeHost);
+     418             :   cpuInfo->addFeature(CpuInfo::kX86FeatureI486);
+     419             : 
+     420             :   // --------------------------------------------------------------------------
+     421             :   // [CPUID EAX=0x0]
+     422             :   // --------------------------------------------------------------------------
+     423             : 
+     424             :   // Get vendor string/id.
+     425             :   x86CallCpuId(&regs, 0x0);
+     426             : 
+     427          70 :   maxId = regs.eax;
+     428          70 :   ::memcpy(cpuInfo->_vendorString + 0, &regs.ebx, 4);
+     429          70 :   ::memcpy(cpuInfo->_vendorString + 4, &regs.edx, 4);
+     430          70 :   ::memcpy(cpuInfo->_vendorString + 8, &regs.ecx, 4);
+     431          70 :   cpuInfo->_vendorId = x86GetCpuVendorID(cpuInfo->_vendorString);
+     432             : 
+     433             :   // --------------------------------------------------------------------------
+     434             :   // [CPUID EAX=0x1]
+     435             :   // --------------------------------------------------------------------------
+     436             : 
+     437          70 :   if (maxId >= 0x1) {
+     438             :     // Get feature flags in ECX/EDX and family/model in EAX.
+     439             :     x86CallCpuId(&regs, 0x1);
+     440             : 
+     441             :     // Fill family and model fields.
+     442          70 :     cpuInfo->_family   = (regs.eax >> 8) & 0x0F;
+     443          70 :     cpuInfo->_model    = (regs.eax >> 4) & 0x0F;
+     444          70 :     cpuInfo->_stepping = (regs.eax     ) & 0x0F;
+     445             : 
+     446             :     // Use extended family and model fields.
+     447          70 :     if (cpuInfo->_family == 0x0F) {
+     448          70 :       cpuInfo->_family += ((regs.eax >> 20) & 0xFF);
+     449          70 :       cpuInfo->_model  += ((regs.eax >> 16) & 0x0F) << 4;
+     450             :     }
+     451             : 
+     452          70 :     cpuInfo->_x86Data._processorType        = ((regs.eax >> 12) & 0x03);
+     453          70 :     cpuInfo->_x86Data._brandIndex           = ((regs.ebx      ) & 0xFF);
+     454          70 :     cpuInfo->_x86Data._flushCacheLineSize   = ((regs.ebx >>  8) & 0xFF) * 8;
+     455          70 :     cpuInfo->_x86Data._maxLogicalProcessors = ((regs.ebx >> 16) & 0xFF);
+     456             : 
+     457          70 :     if (regs.ecx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE3);
+     458          70 :     if (regs.ecx & 0x00000002U) cpuInfo->addFeature(CpuInfo::kX86FeaturePCLMULQDQ);
+     459          70 :     if (regs.ecx & 0x00000008U) cpuInfo->addFeature(CpuInfo::kX86FeatureMONITOR);
+     460          70 :     if (regs.ecx & 0x00000200U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSSE3);
+     461          70 :     if (regs.ecx & 0x00002000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCMPXCHG16B);
+     462          70 :     if (regs.ecx & 0x00080000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE4_1);
+     463          70 :     if (regs.ecx & 0x00100000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE4_2);
+     464          70 :     if (regs.ecx & 0x00400000U) cpuInfo->addFeature(CpuInfo::kX86FeatureMOVBE);
+     465          70 :     if (regs.ecx & 0x00800000U) cpuInfo->addFeature(CpuInfo::kX86FeaturePOPCNT);
+     466          70 :     if (regs.ecx & 0x02000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAESNI);
+     467          70 :     if (regs.ecx & 0x04000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureXSAVE);
+     468          70 :     if (regs.ecx & 0x08000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureOSXSAVE);
+     469          70 :     if (regs.ecx & 0x40000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureRDRAND);
+     470          70 :     if (regs.edx & 0x00000010U) cpuInfo->addFeature(CpuInfo::kX86FeatureRDTSC);
+     471          70 :     if (regs.edx & 0x00000020U) cpuInfo->addFeature(CpuInfo::kX86FeatureMSR);
+     472          70 :     if (regs.edx & 0x00000100U) cpuInfo->addFeature(CpuInfo::kX86FeatureCMPXCHG8B);
+     473          70 :     if (regs.edx & 0x00008000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCMOV);
+     474          70 :     if (regs.edx & 0x00080000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCLFLUSH);
+     475          70 :     if (regs.edx & 0x00800000U) cpuInfo->addFeature(CpuInfo::kX86FeatureMMX);
+     476          70 :     if (regs.edx & 0x01000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFXSR);
+     477          70 :     if (regs.edx & 0x02000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE)
+     478             :                                         .addFeature(CpuInfo::kX86FeatureMMX2);
+     479          70 :     if (regs.edx & 0x04000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE)
+     480             :                                         .addFeature(CpuInfo::kX86FeatureSSE2);
+     481          70 :     if (regs.edx & 0x10000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureMT);
+     482             : 
+     483             :     // Get the content of XCR0 if supported by CPU and enabled by OS.
+     484          70 :     if ((regs.ecx & 0x0C000000U) == 0x0C000000U) {
+     485             :       x86CallXGetBV(&xcr0, 0);
+     486             :     }
+     487             : 
+     488             :     // Detect AVX+.
+     489          70 :     if (regs.ecx & 0x10000000U) {
+     490             :       // - XCR0[2:1] == 11b
+     491             :       //   XMM & YMM states need to be enabled by OS.
+     492          70 :       if ((xcr0.eax & 0x00000006U) == 0x00000006U) {
+     493             :         cpuInfo->addFeature(CpuInfo::kX86FeatureAVX);
+     494             : 
+     495          70 :         if (regs.ecx & 0x00001000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFMA);
+     496          70 :         if (regs.ecx & 0x20000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureF16C);
+     497             :       }
+     498             :     }
+     499             :   }
+     500             : 
+     501             :   // --------------------------------------------------------------------------
+     502             :   // [CPUID EAX=0x7]
+     503             :   // --------------------------------------------------------------------------
+     504             : 
+     505             :   // Detect new features if the processor supports CPUID-07.
+     506             :   bool maybeMPX = false;
+     507             : 
+     508          70 :   if (maxId >= 0x7) {
+     509             :     x86CallCpuId(&regs, 0x7);
+     510             : 
+     511          70 :     if (regs.ebx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeatureFSGSBASE);
+     512          70 :     if (regs.ebx & 0x00000008U) cpuInfo->addFeature(CpuInfo::kX86FeatureBMI);
+     513          70 :     if (regs.ebx & 0x00000010U) cpuInfo->addFeature(CpuInfo::kX86FeatureHLE);
+     514          70 :     if (regs.ebx & 0x00000080U) cpuInfo->addFeature(CpuInfo::kX86FeatureSMEP);
+     515          70 :     if (regs.ebx & 0x00000100U) cpuInfo->addFeature(CpuInfo::kX86FeatureBMI2);
+     516          70 :     if (regs.ebx & 0x00000200U) cpuInfo->addFeature(CpuInfo::kX86FeatureERMS);
+     517          70 :     if (regs.ebx & 0x00000800U) cpuInfo->addFeature(CpuInfo::kX86FeatureRTM);
+     518          70 :     if (regs.ebx & 0x00004000U) maybeMPX = true;
+     519          70 :     if (regs.ebx & 0x00040000U) cpuInfo->addFeature(CpuInfo::kX86FeatureRDSEED);
+     520          70 :     if (regs.ebx & 0x00080000U) cpuInfo->addFeature(CpuInfo::kX86FeatureADX);
+     521          70 :     if (regs.ebx & 0x00100000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSMAP);
+     522          70 :     if (regs.ebx & 0x00400000U) cpuInfo->addFeature(CpuInfo::kX86FeaturePCOMMIT);
+     523          70 :     if (regs.ebx & 0x00800000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCLFLUSHOPT);
+     524          70 :     if (regs.ebx & 0x01000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureCLWB);
+     525          70 :     if (regs.ebx & 0x20000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureSHA);
+     526          70 :     if (regs.ecx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeaturePREFETCHWT1);
+     527             : 
+     528             :     // TSX is supported if at least one of `HLE` and `RTM` is supported.
+     529          70 :     if (regs.ebx & 0x00000810U) cpuInfo->addFeature(CpuInfo::kX86FeatureTSX);
+     530             : 
+     531             :     // Detect AVX2.
+     532          70 :     if (cpuInfo->hasFeature(CpuInfo::kX86FeatureAVX)) {
+     533          70 :       if (regs.ebx & 0x00000020U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX2);
+     534             :     }
+     535             : 
+     536             :     // Detect AVX-512+.
+     537          70 :     if (regs.ebx & 0x00010000U) {
+     538             :       // - XCR0[2:1] == 11b
+     539             :       //   XMM/YMM states need to be enabled by OS.
+     540             :       // - XCR0[7:5] == 111b
+     541             :       //   Upper 256-bit of ZMM0-XMM15 and ZMM16-ZMM31 need to be enabled by the OS.
+     542           0 :       if ((xcr0.eax & 0x000000E6U) == 0x000000E6U) {
+     543             :         cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_F);
+     544             : 
+     545           0 :         if (regs.ebx & 0x00020000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_DQ);
+     546           0 :         if (regs.ebx & 0x00200000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_IFMA);
+     547           0 :         if (regs.ebx & 0x04000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_PFI);
+     548           0 :         if (regs.ebx & 0x08000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_ERI);
+     549           0 :         if (regs.ebx & 0x10000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_CDI);
+     550           0 :         if (regs.ebx & 0x40000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_BW);
+     551           0 :         if (regs.ebx & 0x80000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_VL);
+     552           0 :         if (regs.ecx & 0x00000002U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_VBMI);
+     553           0 :         if (regs.ecx & 0x00004000U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_VPOPCNTDQ);
+     554           0 :         if (regs.edx & 0x00000004U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_4VNNIW);
+     555           0 :         if (regs.edx & 0x00000008U) cpuInfo->addFeature(CpuInfo::kX86FeatureAVX512_4FMAPS);
+     556             :       }
+     557             :     }
+     558             :   }
+     559             : 
+     560             :   // --------------------------------------------------------------------------
+     561             :   // [CPUID EAX=0xD]
+     562             :   // --------------------------------------------------------------------------
+     563             : 
+     564          70 :   if (maxId >= 0xD) {
+     565             :     x86CallCpuId(&regs, 0xD, 0);
+     566             : 
+     567             :     // Both CPUID result and XCR0 has to be enabled to have support for MPX.
+     568          70 :     if (((regs.eax & xcr0.eax) & 0x00000018U) == 0x00000018U && maybeMPX)
+     569             :       cpuInfo->addFeature(CpuInfo::kX86FeatureMPX);
+     570             : 
+     571             :     x86CallCpuId(&regs, 0xD, 1);
+     572          70 :     if (regs.eax & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeatureXSAVEOPT);
+     573          70 :     if (regs.eax & 0x00000002U) cpuInfo->addFeature(CpuInfo::kX86FeatureXSAVEC);
+     574          70 :     if (regs.eax & 0x00000008U) cpuInfo->addFeature(CpuInfo::kX86FeatureXSAVES);
+     575             :   }
+     576             : 
+     577             :   // --------------------------------------------------------------------------
+     578             :   // [CPUID EAX=0x80000000...maxId]
+     579             :   // --------------------------------------------------------------------------
+     580             : 
+     581             :   // The highest EAX that we understand.
+     582          70 :   uint32_t kHighestProcessedEAX = 0x80000008U;
+     583             : 
+     584             :   // Several CPUID calls are required to get the whole branc string. It's easy
+     585             :   // to copy one DWORD at a time instead of performing a byte copy.
+     586          70 :   uint32_t* brand = reinterpret_cast<uint32_t*>(cpuInfo->_brandString);
+     587             : 
+     588             :   i = maxId = 0x80000000U;
+     589             :   do {
+     590             :     x86CallCpuId(&regs, i);
+     591         420 :     switch (i) {
+     592             :       case 0x80000000U:
+     593          70 :         maxId = std::min<uint32_t>(regs.eax, kHighestProcessedEAX);
+     594          70 :         break;
+     595             : 
+     596          70 :       case 0x80000001U:
+     597          70 :         if (regs.ecx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeatureLAHFSAHF);
+     598          70 :         if (regs.ecx & 0x00000020U) cpuInfo->addFeature(CpuInfo::kX86FeatureLZCNT);
+     599          70 :         if (regs.ecx & 0x00000040U) cpuInfo->addFeature(CpuInfo::kX86FeatureSSE4A);
+     600          70 :         if (regs.ecx & 0x00000080U) cpuInfo->addFeature(CpuInfo::kX86FeatureMSSE);
+     601          70 :         if (regs.ecx & 0x00000100U) cpuInfo->addFeature(CpuInfo::kX86FeaturePREFETCHW);
+     602          70 :         if (regs.ecx & 0x00200000U) cpuInfo->addFeature(CpuInfo::kX86FeatureTBM);
+     603          70 :         if (regs.edx & 0x00100000U) cpuInfo->addFeature(CpuInfo::kX86FeatureNX);
+     604          70 :         if (regs.edx & 0x00200000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFXSROPT);
+     605          70 :         if (regs.edx & 0x00400000U) cpuInfo->addFeature(CpuInfo::kX86FeatureMMX2);
+     606          70 :         if (regs.edx & 0x08000000U) cpuInfo->addFeature(CpuInfo::kX86FeatureRDTSCP);
+     607          70 :         if (regs.edx & 0x40000000U) cpuInfo->addFeature(CpuInfo::kX86Feature3DNOW2)
+     608             :                                             .addFeature(CpuInfo::kX86FeatureMMX2);
+     609          70 :         if (regs.edx & 0x80000000U) cpuInfo->addFeature(CpuInfo::kX86Feature3DNOW);
+     610             : 
+     611          70 :         if (cpuInfo->hasFeature(CpuInfo::kX86FeatureAVX)) {
+     612          70 :           if (regs.ecx & 0x00000800U) cpuInfo->addFeature(CpuInfo::kX86FeatureXOP);
+     613          70 :           if (regs.ecx & 0x00010000U) cpuInfo->addFeature(CpuInfo::kX86FeatureFMA4);
+     614             :         }
+     615             : 
+     616             :         // These seem to be only supported by AMD.
+     617          70 :         if (cpuInfo->getVendorId() == CpuInfo::kVendorAMD) {
+     618          70 :           if (regs.ecx & 0x00000010U) cpuInfo->addFeature(CpuInfo::kX86FeatureALTMOVCR8);
+     619             :         }
+     620             :         break;
+     621             : 
+     622         210 :       case 0x80000002U:
+     623             :       case 0x80000003U:
+     624             :       case 0x80000004U:
+     625         210 :         *brand++ = regs.eax;
+     626         210 :         *brand++ = regs.ebx;
+     627         210 :         *brand++ = regs.ecx;
+     628         210 :         *brand++ = regs.edx;
+     629             : 
+     630             :         // Go directly to the last one.
+     631         210 :         if (i == 0x80000004U) i = 0x80000008U - 1;
+     632             :         break;
+     633             : 
+     634          70 :       case 0x80000008U:
+     635          70 :         if (regs.ebx & 0x00000001U) cpuInfo->addFeature(CpuInfo::kX86FeatureCLZERO);
+     636             :         break;
+     637             :     }
+     638         420 :   } while (++i <= maxId);
+     639             : 
+     640             :   // Simplify CPU brand string by removing unnecessary spaces.
+     641             :   x86SimplifyBrandString(cpuInfo->_brandString);
+     642          70 : }
+     643             : #endif // ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
+     644             : 
+     645             : // ============================================================================
+     646             : // [asmjit::CpuInfo - Detect - HWThreadsCount]
+     647             : // ============================================================================
+     648             : 
+     649             : static ASMJIT_INLINE uint32_t cpuDetectHWThreadsCount() noexcept {
+     650             : #if ASMJIT_OS_WINDOWS
+     651             :   SYSTEM_INFO info;
+     652             :   ::GetSystemInfo(&info);
+     653             :   return info.dwNumberOfProcessors;
+     654             : #elif ASMJIT_OS_POSIX && defined(_SC_NPROCESSORS_ONLN)
+     655          70 :   long res = ::sysconf(_SC_NPROCESSORS_ONLN);
+     656             :   if (res <= 0) return 1;
+     657             :   return static_cast<uint32_t>(res);
+     658             : #else
+     659             :   return 1;
+     660             : #endif
+     661             : }
+     662             : 
+     663             : // ============================================================================
+     664             : // [asmjit::CpuInfo - Detect]
+     665             : // ============================================================================
+     666             : 
+     667          70 : ASMJIT_FAVOR_SIZE void CpuInfo::detect() noexcept {
+     668             :   reset();
+     669             : 
+     670             : #if ASMJIT_ARCH_ARM32 || ASMJIT_ARCH_ARM64
+     671             :   armDetectCpuInfo(this);
+     672             : #endif // ASMJIT_ARCH_ARM32 || ASMJIT_ARCH_ARM64
+     673             : 
+     674             : #if ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
+     675          70 :   x86DetectCpuInfo(this);
+     676             : #endif // ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
+     677             : 
+     678          70 :   _hwThreadsCount = cpuDetectHWThreadsCount();
+     679          70 : }
+     680             : 
+     681             : // ============================================================================
+     682             : // [asmjit::CpuInfo - GetHost]
+     683             : // ============================================================================
+     684             : 
+     685             : struct HostCpuInfo : public CpuInfo {
+     686          70 :   ASMJIT_INLINE HostCpuInfo() noexcept : CpuInfo() { detect(); }
+     687             : };
+     688             : 
+     689        1976 : const CpuInfo& CpuInfo::getHost() noexcept {
+     690        2046 :   static HostCpuInfo host;
+     691        1976 :   return host;
+     692             : }
+     693             : 
+     694             : } // asmjit namespace
+     695             : } // namespace PLMD
+     696             : 
+     697             : // [Api-End]
+     698             : #include "./asmjit_apiend.h"
+     699             : #pragma GCC diagnostic pop
+     700             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.h.func-sort-c.html b/coverage-libs/asmjit/cpuinfo.h.func-sort-c.html new file mode 100644 index 000000000000..eeea8b314290 --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/cpuinfo.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - cpuinfo.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.h.func.html b/coverage-libs/asmjit/cpuinfo.h.func.html new file mode 100644 index 000000000000..249764f52ff6 --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/cpuinfo.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - cpuinfo.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/cpuinfo.h.gcov.html b/coverage-libs/asmjit/cpuinfo.h.gcov.html new file mode 100644 index 000000000000..c82c5d450f34 --- /dev/null +++ b/coverage-libs/asmjit/cpuinfo.h.gcov.html @@ -0,0 +1,479 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/cpuinfo.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - cpuinfo.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_cpuinfo_h
+      21             : #define __PLUMED_asmjit_cpuinfo_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_CPUINFO_H
+      33             : #define _ASMJIT_BASE_CPUINFO_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./arch.h"
+      37             : 
+      38             : // [Api-Begin]
+      39             : #include "./asmjit_apibegin.h"
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace asmjit {
+      43             : 
+      44             : //! \addtogroup asmjit_base
+      45             : //! \{
+      46             : 
+      47             : // ============================================================================
+      48             : // [asmjit::CpuFeatures]
+      49             : // ============================================================================
+      50             : 
+      51             : class CpuFeatures {
+      52             : public:
+      53             :   typedef uintptr_t BitWord;
+      54             : 
+      55             :   enum {
+      56             :     kMaxFeatures = 128,
+      57             :     kBitWordSize = static_cast<int>(sizeof(BitWord)) * 8,
+      58             :     kNumBitWords = kMaxFeatures / kBitWordSize
+      59             :   };
+      60             : 
+      61             :   // --------------------------------------------------------------------------
+      62             :   // [Construction / Destruction]
+      63             :   // --------------------------------------------------------------------------
+      64             : 
+      65          70 :   ASMJIT_INLINE CpuFeatures() noexcept { reset(); }
+      66             :   ASMJIT_INLINE CpuFeatures(const CpuFeatures& other) noexcept = default;
+      67             : 
+      68             :   // --------------------------------------------------------------------------
+      69             :   // [Init / Reset]
+      70             :   // --------------------------------------------------------------------------
+      71             : 
+      72             :   ASMJIT_INLINE void init(const CpuFeatures& other) noexcept { ::memcpy(this, &other, sizeof(*this)); }
+      73           0 :   ASMJIT_INLINE void reset() noexcept { ::memset(this, 0, sizeof(*this)); }
+      74             : 
+      75             :   // --------------------------------------------------------------------------
+      76             :   // [Ops]
+      77             :   // --------------------------------------------------------------------------
+      78             : 
+      79             :   //! Get all features as `BitWord` array.
+      80             :   ASMJIT_INLINE BitWord* getBits() noexcept { return _bits; }
+      81             :   //! Get all features as `BitWord` array (const).
+      82             :   ASMJIT_INLINE const BitWord* getBits() const noexcept { return _bits; }
+      83             : 
+      84             :   //! Get if feature `feature` is present.
+      85             :   ASMJIT_INLINE bool has(uint32_t feature) const noexcept {
+      86             :     ASMJIT_ASSERT(feature < kMaxFeatures);
+      87             : 
+      88             :     uint32_t idx = feature / kBitWordSize;
+      89             :     uint32_t bit = feature % kBitWordSize;
+      90             : 
+      91         140 :     return static_cast<bool>((_bits[idx] >> bit) & 0x1);
+      92             :   }
+      93             : 
+      94             :   //! Get if all features as defined by `other` are  present.
+      95             :   ASMJIT_INLINE bool hasAll(const CpuFeatures& other) const noexcept {
+      96             :     for (uint32_t i = 0; i < kNumBitWords; i++)
+      97             :       if ((_bits[i] & other._bits[i]) != other._bits[i])
+      98             :         return false;
+      99             :     return true;
+     100             :   }
+     101             : 
+     102             :   //! Add a CPU `feature`.
+     103             :   ASMJIT_INLINE CpuFeatures& add(uint32_t feature) noexcept {
+     104             :     ASMJIT_ASSERT(feature < kMaxFeatures);
+     105             : 
+     106           0 :     uint32_t idx = feature / kBitWordSize;
+     107           0 :     uint32_t bit = feature % kBitWordSize;
+     108             : 
+     109         140 :     _bits[idx] |= static_cast<BitWord>(1) << bit;
+     110             :     return *this;
+     111             :   }
+     112             : 
+     113             :   //! Remove a CPU `feature`.
+     114             :   ASMJIT_INLINE CpuFeatures& remove(uint32_t feature) noexcept {
+     115             :     ASMJIT_ASSERT(feature < kMaxFeatures);
+     116             : 
+     117             :     uint32_t idx = feature / kBitWordSize;
+     118             :     uint32_t bit = feature % kBitWordSize;
+     119             : 
+     120           0 :     _bits[idx] &= ~(static_cast<BitWord>(1) << bit);
+     121           0 :     return *this;
+     122             :   }
+     123             : 
+     124             :   // --------------------------------------------------------------------------
+     125             :   // [Members]
+     126             :   // --------------------------------------------------------------------------
+     127             : 
+     128             :   BitWord _bits[kNumBitWords];
+     129             : };
+     130             : 
+     131             : // ============================================================================
+     132             : // [asmjit::CpuInfo]
+     133             : // ============================================================================
+     134             : 
+     135             : //! CPU information.
+     136             : class CpuInfo {
+     137             : public:
+     138             :   //! CPU vendor ID.
+     139             :   ASMJIT_ENUM(Vendor) {
+     140             :     kVendorNone  = 0,                    //!< Generic or unknown.
+     141             :     kVendorIntel = 1,                    //!< Intel vendor.
+     142             :     kVendorAMD   = 2,                    //!< AMD vendor.
+     143             :     kVendorVIA   = 3                     //!< VIA vendor.
+     144             :   };
+     145             : 
+     146             :   //! ARM/ARM64 CPU features.
+     147             :   ASMJIT_ENUM(ArmFeatures) {
+     148             :     kArmFeatureV6 = 1,                   //!< ARMv6 instruction set.
+     149             :     kArmFeatureV7,                       //!< ARMv7 instruction set.
+     150             :     kArmFeatureV8,                       //!< ARMv8 instruction set.
+     151             :     kArmFeatureTHUMB,                    //!< CPU provides THUMB v1 instruction set (THUMB mode).
+     152             :     kArmFeatureTHUMB2,                   //!< CPU provides THUMB v2 instruction set (THUMB mode).
+     153             :     kArmFeatureVFPv2,                    //!< CPU provides VFPv2 instruction set.
+     154             :     kArmFeatureVFPv3,                    //!< CPU provides VFPv3 instruction set.
+     155             :     kArmFeatureVFPv4,                    //!< CPU provides VFPv4 instruction set.
+     156             :     kArmFeatureVFP_D32,                  //!< CPU provides 32 VFP-D (64-bit) registers.
+     157             :     kArmFeatureEDSP,                     //!< CPU provides EDSP extensions.
+     158             :     kArmFeatureASIMD,                    //!< CPU provides 'Advanced SIMD'.
+     159             :     kArmFeatureIDIVA,                    //!< CPU provides hardware SDIV and UDIV (ARM mode).
+     160             :     kArmFeatureIDIVT,                    //!< CPU provides hardware SDIV and UDIV (THUMB mode).
+     161             :     kArmFeatureAES,                      //!< CPU provides AES instructions (ARM64 only).
+     162             :     kArmFeatureCRC32,                    //!< CPU provides CRC32 instructions.
+     163             :     kArmFeaturePMULL,                    //!< CPU provides PMULL instructions (ARM64 only).
+     164             :     kArmFeatureSHA1,                     //!< CPU provides SHA1 instructions.
+     165             :     kArmFeatureSHA256,                   //!< CPU provides SHA256 instructions.
+     166             :     kArmFeatureAtomics64,                //!< CPU provides 64-bit load/store atomics (ARM64 only).
+     167             : 
+     168             :     kArmFeaturesCount                    //!< Count of ARM/ARM64 CPU features.
+     169             :   };
+     170             : 
+     171             :   //! X86/X64 CPU features.
+     172             :   ASMJIT_ENUM(X86Features) {
+     173             :     kX86FeatureI486 = 1,                 //!< CPU is at least I486.
+     174             :     kX86FeatureNX,                       //!< CPU has Not-Execute-Bit.
+     175             :     kX86FeatureMT,                       //!< CPU has multi-threading.
+     176             :     kX86FeatureALTMOVCR8,                //!< CPU supports `LOCK MOV CR8` (AMD CPUs).
+     177             :     kX86FeatureCMOV,                     //!< CPU has CMOV.
+     178             :     kX86FeatureCMPXCHG8B,                //!< CPU has CMPXCHG8B.
+     179             :     kX86FeatureCMPXCHG16B,               //!< CPU has CMPXCHG16B (x64).
+     180             :     kX86FeatureMSR,                      //!< CPU has RDMSR/WRMSR.
+     181             :     kX86FeatureRDTSC,                    //!< CPU has RDTSC.
+     182             :     kX86FeatureRDTSCP,                   //!< CPU has RDTSCP.
+     183             :     kX86FeatureCLFLUSH,                  //!< CPU has CLFUSH.
+     184             :     kX86FeatureCLFLUSHOPT,               //!< CPU has CLFUSHOPT.
+     185             :     kX86FeatureCLWB,                     //!< CPU has CLWB.
+     186             :     kX86FeatureCLZERO,                   //!< CPU has CLZERO.
+     187             :     kX86FeaturePCOMMIT,                  //!< CPU has PCOMMIT.
+     188             :     kX86FeaturePREFETCHW,                //!< CPU has PREFETCHW.
+     189             :     kX86FeaturePREFETCHWT1,              //!< CPU has PREFETCHWT1.
+     190             :     kX86FeatureLAHFSAHF,                 //!< CPU has LAHF/SAHF.
+     191             :     kX86FeatureFXSR,                     //!< CPU has FXSAVE/FXRSTOR.
+     192             :     kX86FeatureFXSROPT,                  //!< CPU has FXSAVE/FXRSTOR (optimized).
+     193             :     kX86FeatureMMX,                      //!< CPU has MMX.
+     194             :     kX86FeatureMMX2,                     //!< CPU has extended MMX.
+     195             :     kX86Feature3DNOW,                    //!< CPU has 3DNOW.
+     196             :     kX86Feature3DNOW2,                   //!< CPU has 3DNOW2 (enhanced).
+     197             :     kX86FeatureGEODE,                    //!< CPU has GEODE extensions (few additions to 3DNOW).
+     198             :     kX86FeatureSSE,                      //!< CPU has SSE.
+     199             :     kX86FeatureSSE2,                     //!< CPU has SSE2.
+     200             :     kX86FeatureSSE3,                     //!< CPU has SSE3.
+     201             :     kX86FeatureSSSE3,                    //!< CPU has SSSE3.
+     202             :     kX86FeatureSSE4A,                    //!< CPU has SSE4.A.
+     203             :     kX86FeatureSSE4_1,                   //!< CPU has SSE4.1.
+     204             :     kX86FeatureSSE4_2,                   //!< CPU has SSE4.2.
+     205             :     kX86FeatureMSSE,                     //!< CPU has Misaligned SSE (MSSE).
+     206             :     kX86FeatureMONITOR,                  //!< CPU has MONITOR and MWAIT.
+     207             :     kX86FeatureMOVBE,                    //!< CPU has MOVBE.
+     208             :     kX86FeaturePOPCNT,                   //!< CPU has POPCNT.
+     209             :     kX86FeatureLZCNT,                    //!< CPU has LZCNT.
+     210             :     kX86FeatureAESNI,                    //!< CPU has AESNI.
+     211             :     kX86FeaturePCLMULQDQ,                //!< CPU has PCLMULQDQ.
+     212             :     kX86FeatureRDRAND,                   //!< CPU has RDRAND.
+     213             :     kX86FeatureRDSEED,                   //!< CPU has RDSEED.
+     214             :     kX86FeatureSMAP,                     //!< CPU has SMAP (supervisor-mode access prevention).
+     215             :     kX86FeatureSMEP,                     //!< CPU has SMEP (supervisor-mode execution prevention).
+     216             :     kX86FeatureSHA,                      //!< CPU has SHA-1 and SHA-256.
+     217             :     kX86FeatureXSAVE,                    //!< CPU has XSAVE support (XSAVE/XRSTOR, XSETBV/XGETBV, and XCR).
+     218             :     kX86FeatureXSAVEC,                   //!< CPU has XSAVEC support (XSAVEC).
+     219             :     kX86FeatureXSAVES,                   //!< CPU has XSAVES support (XSAVES/XRSTORS).
+     220             :     kX86FeatureXSAVEOPT,                 //!< CPU has XSAVEOPT support (XSAVEOPT/XSAVEOPT64).
+     221             :     kX86FeatureOSXSAVE,                  //!< CPU has XSAVE enabled by OS.
+     222             :     kX86FeatureAVX,                      //!< CPU has AVX.
+     223             :     kX86FeatureAVX2,                     //!< CPU has AVX2.
+     224             :     kX86FeatureF16C,                     //!< CPU has F16C.
+     225             :     kX86FeatureFMA,                      //!< CPU has FMA.
+     226             :     kX86FeatureFMA4,                     //!< CPU has FMA4.
+     227             :     kX86FeatureXOP,                      //!< CPU has XOP.
+     228             :     kX86FeatureBMI,                      //!< CPU has BMI (bit manipulation instructions #1).
+     229             :     kX86FeatureBMI2,                     //!< CPU has BMI2 (bit manipulation instructions #2).
+     230             :     kX86FeatureADX,                      //!< CPU has ADX (multi-precision add-carry instruction extensions).
+     231             :     kX86FeatureTBM,                      //!< CPU has TBM (trailing bit manipulation).
+     232             :     kX86FeatureMPX,                      //!< CPU has MPX (memory protection extensions).
+     233             :     kX86FeatureHLE,                      //!< CPU has HLE.
+     234             :     kX86FeatureRTM,                      //!< CPU has RTM.
+     235             :     kX86FeatureTSX,                      //!< CPU has TSX.
+     236             :     kX86FeatureERMS,                     //!< CPU has ERMS (enhanced REP MOVSB/STOSB).
+     237             :     kX86FeatureFSGSBASE,                 //!< CPU has FSGSBASE.
+     238             :     kX86FeatureAVX512_F,                 //!< CPU has AVX512-F (foundation).
+     239             :     kX86FeatureAVX512_CDI,               //!< CPU has AVX512-CDI (conflict detection).
+     240             :     kX86FeatureAVX512_PFI,               //!< CPU has AVX512-PFI (prefetch instructions).
+     241             :     kX86FeatureAVX512_ERI,               //!< CPU has AVX512-ERI (exponential and reciprocal).
+     242             :     kX86FeatureAVX512_DQ,                //!< CPU has AVX512-DQ (DWORD/QWORD).
+     243             :     kX86FeatureAVX512_BW,                //!< CPU has AVX512-BW (BYTE/WORD).
+     244             :     kX86FeatureAVX512_VL,                //!< CPU has AVX512-VL (vector length extensions).
+     245             :     kX86FeatureAVX512_IFMA,              //!< CPU has AVX512-IFMA (integer fused-multiply-add using 52-bit precision).
+     246             :     kX86FeatureAVX512_VBMI,              //!< CPU has AVX512-VBMI (vector byte manipulation).
+     247             :     kX86FeatureAVX512_VPOPCNTDQ,         //!< CPU has AVX512-VPOPCNTDQ (VPOPCNT[D|Q] instructions).
+     248             :     kX86FeatureAVX512_4VNNIW,            //!< CPU has AVX512-VNNIW (vector NN instructions word variable precision).
+     249             :     kX86FeatureAVX512_4FMAPS,            //!< CPU has AVX512-FMAPS (FMA packed single).
+     250             : 
+     251             :     kX86FeaturesCount                    //!< Count of X86/X64 CPU features.
+     252             :   };
+     253             : 
+     254             :   // --------------------------------------------------------------------------
+     255             :   // [ArmInfo]
+     256             :   // --------------------------------------------------------------------------
+     257             : 
+     258             :   struct ArmData {
+     259             :   };
+     260             : 
+     261             :   // --------------------------------------------------------------------------
+     262             :   // [X86Info]
+     263             :   // --------------------------------------------------------------------------
+     264             : 
+     265             :   struct X86Data {
+     266             :     uint32_t _processorType;             //!< Processor type.
+     267             :     uint32_t _brandIndex;                //!< Brand index.
+     268             :     uint32_t _flushCacheLineSize;        //!< Flush cache line size (in bytes).
+     269             :     uint32_t _maxLogicalProcessors;      //!< Maximum number of addressable IDs for logical processors.
+     270             :   };
+     271             : 
+     272             :   // --------------------------------------------------------------------------
+     273             :   // [Construction / Destruction]
+     274             :   // --------------------------------------------------------------------------
+     275             : 
+     276          70 :   ASMJIT_INLINE CpuInfo() noexcept { reset(); }
+     277             :   ASMJIT_INLINE CpuInfo(const CpuInfo& other) noexcept = default;
+     278             : 
+     279             :   // --------------------------------------------------------------------------
+     280             :   // [Init / Reset]
+     281             :   // --------------------------------------------------------------------------
+     282             : 
+     283             :   //! Initialize CpuInfo to the given architecture, see \ArchInfo.
+     284             :   ASMJIT_INLINE void initArch(uint32_t archType, uint32_t archMode = 0) noexcept {
+     285             :     _archInfo.init(archType, archMode);
+     286             :   }
+     287             : 
+     288             :   ASMJIT_INLINE void init(const CpuInfo& other) noexcept { ::memcpy(this, &other, sizeof(*this)); }
+     289             :   ASMJIT_INLINE void reset() noexcept { ::memset(this, 0, sizeof(*this)); }
+     290             : 
+     291             :   // --------------------------------------------------------------------------
+     292             :   // [Detect]
+     293             :   // --------------------------------------------------------------------------
+     294             : 
+     295             :   ASMJIT_API void detect() noexcept;
+     296             : 
+     297             :   // --------------------------------------------------------------------------
+     298             :   // [Accessors]
+     299             :   // --------------------------------------------------------------------------
+     300             : 
+     301             :   //! Get generic architecture information.
+     302             :   ASMJIT_INLINE const ArchInfo& getArchInfo() const noexcept { return _archInfo; }
+     303             :   //! Get CPU architecture type, see \ArchInfo::Type.
+     304             :   ASMJIT_INLINE uint32_t getArchType() const noexcept { return _archInfo.getType(); }
+     305             :   //! Get CPU architecture sub-type, see \ArchInfo::SubType.
+     306             :   ASMJIT_INLINE uint32_t getArchSubType() const noexcept { return _archInfo.getSubType(); }
+     307             : 
+     308             :     //! Get CPU vendor ID.
+     309          70 :   ASMJIT_INLINE uint32_t getVendorId() const noexcept { return _vendorId; }
+     310             :   //! Get CPU family ID.
+     311             :   ASMJIT_INLINE uint32_t getFamily() const noexcept { return _family; }
+     312             :   //! Get CPU model ID.
+     313             :   ASMJIT_INLINE uint32_t getModel() const noexcept { return _model; }
+     314             :   //! Get CPU stepping.
+     315             :   ASMJIT_INLINE uint32_t getStepping() const noexcept { return _stepping; }
+     316             : 
+     317             :   //! Get number of hardware threads available.
+     318             :   ASMJIT_INLINE uint32_t getHwThreadsCount() const noexcept {
+     319             :     return _hwThreadsCount;
+     320             :   }
+     321             : 
+     322             :   //! Get all CPU features.
+     323             :   ASMJIT_INLINE const CpuFeatures& getFeatures() const noexcept { return _features; }
+     324             :   //! Get whether CPU has a `feature`.
+     325             :   ASMJIT_INLINE bool hasFeature(uint32_t feature) const noexcept { return _features.has(feature); }
+     326             :   //! Add a CPU `feature`.
+     327        3430 :   ASMJIT_INLINE CpuInfo& addFeature(uint32_t feature) noexcept { _features.add(feature); return *this; }
+     328             : 
+     329             :   //! Get CPU vendor string.
+     330             :   ASMJIT_INLINE const char* getVendorString() const noexcept { return _vendorString; }
+     331             :   //! Get CPU brand string.
+     332             :   ASMJIT_INLINE const char* getBrandString() const noexcept { return _brandString; }
+     333             : 
+     334             :   // --------------------------------------------------------------------------
+     335             :   // [Accessors - ARM]
+     336             :   // --------------------------------------------------------------------------
+     337             : 
+     338             :   // --------------------------------------------------------------------------
+     339             :   // [Accessors - X86]
+     340             :   // --------------------------------------------------------------------------
+     341             : 
+     342             :   //! Get processor type.
+     343             :   ASMJIT_INLINE uint32_t getX86ProcessorType() const noexcept {
+     344             :     return _x86Data._processorType;
+     345             :   }
+     346             : 
+     347             :   //! Get brand index.
+     348             :   ASMJIT_INLINE uint32_t getX86BrandIndex() const noexcept {
+     349             :     return _x86Data._brandIndex;
+     350             :   }
+     351             : 
+     352             :   //! Get flush cache line size.
+     353             :   ASMJIT_INLINE uint32_t getX86FlushCacheLineSize() const noexcept {
+     354             :     return _x86Data._flushCacheLineSize;
+     355             :   }
+     356             : 
+     357             :   //! Get maximum logical processors count.
+     358             :   ASMJIT_INLINE uint32_t getX86MaxLogicalProcessors() const noexcept {
+     359             :     return _x86Data._maxLogicalProcessors;
+     360             :   }
+     361             : 
+     362             :   // --------------------------------------------------------------------------
+     363             :   // [Statics]
+     364             :   // --------------------------------------------------------------------------
+     365             : 
+     366             :   //! Get the host CPU information.
+     367             :   ASMJIT_API static const CpuInfo& getHost() noexcept;
+     368             : 
+     369             :   // --------------------------------------------------------------------------
+     370             :   // [Members]
+     371             :   // --------------------------------------------------------------------------
+     372             : 
+     373             :   ArchInfo _archInfo;                    //!< CPU architecture information.
+     374             :   uint32_t _vendorId;                    //!< CPU vendor id, see \ref Vendor.
+     375             :   uint32_t _family;                      //!< CPU family ID.
+     376             :   uint32_t _model;                       //!< CPU model ID.
+     377             :   uint32_t _stepping;                    //!< CPU stepping.
+     378             :   uint32_t _hwThreadsCount;              //!< Number of hardware threads.
+     379             :   CpuFeatures _features;                 //!< CPU features.
+     380             :   char _vendorString[16];                //!< CPU vendor string.
+     381             :   char _brandString[64];                 //!< CPU brand string.
+     382             : 
+     383             :   // Architecture specific data.
+     384             :   union {
+     385             :     ArmData _armData;
+     386             :     X86Data _x86Data;
+     387             :   };
+     388             : };
+     389             : 
+     390             : //! \}
+     391             : 
+     392             : } // asmjit namespace
+     393             : } // namespace PLMD
+     394             : 
+     395             : // [Api-End]
+     396             : #include "./asmjit_apiend.h"
+     397             : 
+     398             : // [Guard]
+     399             : #endif // _ASMJIT_BASE_CPUINFO_H
+     400             : #pragma GCC diagnostic pop
+     401             : #endif // __PLUMED_HAS_ASMJIT
+     402             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.cpp.func-sort-c.html b/coverage-libs/asmjit/func.cpp.func-sort-c.html new file mode 100644 index 000000000000..1bd35c4d2378 --- /dev/null +++ b/coverage-libs/asmjit/func.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:243177.4 %
Date:2024-02-22 21:58:47Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9FuncUtils9allocArgsEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZNK4PLMD6asmjit14FuncArgsMapper15updateFrameInfoERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit15FuncFrameLayout4initERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1948
_ZN4PLMD6asmjit9FuncUtils10emitEpilogEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit9FuncUtils10emitPrologEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit10FuncDetail4initERKNS0_13FuncSignatureE3596
_ZN4PLMD6asmjit8CallConv4initEj3596
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.cpp.func.html b/coverage-libs/asmjit/func.cpp.func.html new file mode 100644 index 000000000000..06fda40c4317 --- /dev/null +++ b/coverage-libs/asmjit/func.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:243177.4 %
Date:2024-02-22 21:58:47Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10FuncDetail4initERKNS0_13FuncSignatureE3596
_ZN4PLMD6asmjit15FuncFrameLayout4initERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1948
_ZN4PLMD6asmjit8CallConv4initEj3596
_ZN4PLMD6asmjit9FuncUtils10emitEpilogEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit9FuncUtils10emitPrologEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit9FuncUtils9allocArgsEPNS0_11CodeEmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZNK4PLMD6asmjit14FuncArgsMapper15updateFrameInfoERNS0_13FuncFrameInfoE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.cpp.gcov.html b/coverage-libs/asmjit/func.cpp.gcov.html new file mode 100644 index 000000000000..e827f5e6b6a8 --- /dev/null +++ b/coverage-libs/asmjit/func.cpp.gcov.html @@ -0,0 +1,289 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:243177.4 %
Date:2024-02-22 21:58:47Functions:5771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./arch.h"
+      34             : #include "./func.h"
+      35             : 
+      36             : #if defined(ASMJIT_BUILD_X86)
+      37             : #include "./x86internal_p.h"
+      38             : #include "./x86operand.h"
+      39             : #endif // ASMJIT_BUILD_X86
+      40             : 
+      41             : #if defined(ASMJIT_BUILD_ARM)
+      42             : #include "./arminternal_p.h"
+      43             : #include "./armoperand.h"
+      44             : #endif // ASMJIT_BUILD_ARM
+      45             : 
+      46             : // [Api-Begin]
+      47             : #include "./asmjit_apibegin.h"
+      48             : 
+      49             : namespace PLMD {
+      50             : namespace asmjit {
+      51             : 
+      52             : // ============================================================================
+      53             : // [asmjit::CallConv - Init / Reset]
+      54             : // ============================================================================
+      55             : 
+      56        3596 : ASMJIT_FAVOR_SIZE Error CallConv::init(uint32_t ccId) noexcept {
+      57             :   reset();
+      58             : 
+      59             : #if defined(ASMJIT_BUILD_X86)
+      60        3596 :   if (CallConv::isX86Family(ccId))
+      61        3596 :     return X86Internal::initCallConv(*this, ccId);
+      62             : #endif // ASMJIT_BUILD_X86
+      63             : 
+      64             : #if defined(ASMJIT_BUILD_ARM)
+      65             :   if (CallConv::isArmFamily(ccId))
+      66             :     return ArmInternal::initCallConv(*this, ccId);
+      67             : #endif // ASMJIT_BUILD_ARM
+      68             : 
+      69             :   return DebugUtils::errored(kErrorInvalidArgument);
+      70             : }
+      71             : 
+      72             : // ============================================================================
+      73             : // [asmjit::FuncDetail - Init / Reset]
+      74             : // ============================================================================
+      75             : 
+      76        3596 : ASMJIT_FAVOR_SIZE Error FuncDetail::init(const FuncSignature& sign) {
+      77             :   uint32_t ccId = sign.getCallConv();
+      78        3596 :   CallConv& cc = _callConv;
+      79             : 
+      80             :   uint32_t argCount = sign.getArgCount();
+      81        3596 :   if (ASMJIT_UNLIKELY(argCount > kFuncArgCount))
+      82             :     return DebugUtils::errored(kErrorInvalidArgument);
+      83             : 
+      84        3596 :   ASMJIT_PROPAGATE(cc.init(ccId));
+      85             : 
+      86        3596 :   uint32_t gpSize = (cc.getArchType() == ArchInfo::kTypeX86) ? 4 : 8;
+      87             :   uint32_t deabstractDelta = TypeId::deabstractDeltaOfSize(gpSize);
+      88             : 
+      89             :   const uint8_t* args = sign.getArgs();
+      90        5466 :   for (uint32_t i = 0; i < argCount; i++) {
+      91             :     Value& arg = _args[i];
+      92        1870 :     arg.initTypeId(TypeId::deabstract(args[i], deabstractDelta));
+      93             :   }
+      94        3596 :   _argCount = static_cast<uint8_t>(argCount);
+      95             : 
+      96             :   uint32_t ret = sign.getRet();
+      97        3596 :   if (ret != TypeId::kVoid) {
+      98             :     _rets[0].initTypeId(TypeId::deabstract(ret, deabstractDelta));
+      99        3596 :     _retCount = 1;
+     100             :   }
+     101             : 
+     102             : #if defined(ASMJIT_BUILD_X86)
+     103        3596 :   if (CallConv::isX86Family(ccId))
+     104        3596 :     return X86Internal::initFuncDetail(*this, sign, gpSize);
+     105             : #endif // ASMJIT_BUILD_X86
+     106             : 
+     107             : #if defined(ASMJIT_BUILD_ARM)
+     108             :   if (CallConv::isArmFamily(ccId))
+     109             :     return ArmInternal::initFuncDetail(*this, sign, gpSize);
+     110             : #endif // ASMJIT_BUILD_ARM
+     111             : 
+     112             :   // We should never bubble here as if `cc.init()` succeeded then there has to
+     113             :   // be an implementation for the current architecture. However, stay safe.
+     114             :   return DebugUtils::errored(kErrorInvalidArgument);
+     115             : }
+     116             : 
+     117             : // ============================================================================
+     118             : // [asmjit::FuncFrameLayout - Init / Reset]
+     119             : // ============================================================================
+     120             : 
+     121        1948 : ASMJIT_FAVOR_SIZE Error FuncFrameLayout::init(const FuncDetail& func, const FuncFrameInfo& ffi) noexcept {
+     122             :   uint32_t ccId = func.getCallConv().getId();
+     123             : 
+     124             : #if defined(ASMJIT_BUILD_X86)
+     125        1948 :   if (CallConv::isX86Family(ccId))
+     126        1948 :     return X86Internal::initFrameLayout(*this, func, ffi);
+     127             : #endif // ASMJIT_BUILD_X86
+     128             : 
+     129             : #if defined(ASMJIT_BUILD_ARM)
+     130             :   if (CallConv::isArmFamily(ccId))
+     131             :     return ArmInternal::initFrameLayout(*this, func, ffi);
+     132             : #endif // ASMJIT_BUILD_ARM
+     133             : 
+     134             :   return DebugUtils::errored(kErrorInvalidArgument);
+     135             : }
+     136             : 
+     137             : // ============================================================================
+     138             : // [asmjit::FuncArgsMapper]
+     139             : // ============================================================================
+     140             : 
+     141           0 : ASMJIT_FAVOR_SIZE Error FuncArgsMapper::updateFrameInfo(FuncFrameInfo& ffi) const noexcept {
+     142             :   const FuncDetail* func = getFuncDetail();
+     143           0 :   if (!func) return DebugUtils::errored(kErrorInvalidState);
+     144             : 
+     145             :   uint32_t ccId = func->getCallConv().getId();
+     146             : 
+     147             : #if defined(ASMJIT_BUILD_X86)
+     148           0 :   if (CallConv::isX86Family(ccId))
+     149           0 :     return X86Internal::argsToFrameInfo(*this, ffi);
+     150             : #endif // ASMJIT_BUILD_X86
+     151             : 
+     152             : #if defined(ASMJIT_BUILD_ARM)
+     153             :   if (CallConv::isArmFamily(ccId))
+     154             :     return ArmInternal::argsToFrameInfo(*this, ffi);
+     155             : #endif // ASMJIT_BUILD_X86
+     156             : 
+     157             :   return DebugUtils::errored(kErrorInvalidArch);
+     158             : }
+     159             : 
+     160             : // ============================================================================
+     161             : // [asmjit::FuncUtils]
+     162             : // ============================================================================
+     163             : 
+     164        1948 : ASMJIT_FAVOR_SIZE Error FuncUtils::emitProlog(CodeEmitter* emitter, const FuncFrameLayout& layout) {
+     165             : #if defined(ASMJIT_BUILD_X86)
+     166        1948 :   if (emitter->getArchInfo().isX86Family())
+     167        1948 :     return X86Internal::emitProlog(static_cast<X86Emitter*>(emitter), layout);
+     168             : #endif // ASMJIT_BUILD_X86
+     169             : 
+     170             : #if defined(ASMJIT_BUILD_ARM)
+     171             :   if (emitter->getArchInfo().isArmFamily())
+     172             :     return ArmInternal::emitProlog(static_cast<ArmEmitter*>(emitter), layout);
+     173             : #endif // ASMJIT_BUILD_ARM
+     174             : 
+     175             :   return DebugUtils::errored(kErrorInvalidArch);
+     176             : }
+     177             : 
+     178        1948 : ASMJIT_FAVOR_SIZE Error FuncUtils::emitEpilog(CodeEmitter* emitter, const FuncFrameLayout& layout) {
+     179             : #if defined(ASMJIT_BUILD_X86)
+     180        1948 :   if (emitter->getArchInfo().isX86Family())
+     181        1948 :     return X86Internal::emitEpilog(static_cast<X86Emitter*>(emitter), layout);
+     182             : #endif // ASMJIT_BUILD_X86
+     183             : 
+     184             : #if defined(ASMJIT_BUILD_ARM)
+     185             :   if (emitter->getArchInfo().isArmFamily())
+     186             :     return ArmInternal::emitEpilog(static_cast<ArmEmitter*>(emitter), layout);
+     187             : #endif // ASMJIT_BUILD_ARM
+     188             : 
+     189             :   return DebugUtils::errored(kErrorInvalidArch);
+     190             : }
+     191             : 
+     192           0 : ASMJIT_FAVOR_SIZE Error FuncUtils::allocArgs(CodeEmitter* emitter, const FuncFrameLayout& layout, const FuncArgsMapper& args) {
+     193             : #if defined(ASMJIT_BUILD_X86)
+     194           0 :   if (emitter->getArchInfo().isX86Family())
+     195           0 :     return X86Internal::allocArgs(static_cast<X86Emitter*>(emitter), layout, args);
+     196             : #endif // ASMJIT_BUILD_X86
+     197             : 
+     198             : #if defined(ASMJIT_BUILD_ARM)
+     199             :   if (emitter->getArchInfo().isArmFamily())
+     200             :     return ArmInternal::allocArgs(static_cast<ArmEmitter*>(emitter), layout, args);
+     201             : #endif // ASMJIT_BUILD_ARM
+     202             : 
+     203             :   return DebugUtils::errored(kErrorInvalidArch);
+     204             : }
+     205             : 
+     206             : } // asmjit namespace
+     207             : } // namespace PLMD
+     208             : 
+     209             : // [Api-End]
+     210             : #include "./asmjit_apiend.h"
+     211             : #pragma GCC diagnostic pop
+     212             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.h.func-sort-c.html b/coverage-libs/asmjit/func.h.func-sort-c.html new file mode 100644 index 000000000000..9c710a304d8f --- /dev/null +++ b/coverage-libs/asmjit/func.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:689770.1 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.h.func.html b/coverage-libs/asmjit/func.h.func.html new file mode 100644 index 000000000000..26f25dcf2374 --- /dev/null +++ b/coverage-libs/asmjit/func.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:689770.1 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/func.h.gcov.html b/coverage-libs/asmjit/func.h.gcov.html new file mode 100644 index 000000000000..022816e3d13d --- /dev/null +++ b/coverage-libs/asmjit/func.h.gcov.html @@ -0,0 +1,1404 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/func.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - func.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:689770.1 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_func_h
+      21             : #define __PLUMED_asmjit_func_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_FUNC_H
+      33             : #define _ASMJIT_BASE_FUNC_H
+      34             : 
+      35             : #include "./asmjit_build.h"
+      36             : 
+      37             : // [Dependencies]
+      38             : #include "./arch.h"
+      39             : #include "./operand.h"
+      40             : #include "./utils.h"
+      41             : 
+      42             : // [Api-Begin]
+      43             : #include "./asmjit_apibegin.h"
+      44             : 
+      45             : namespace PLMD {
+      46             : namespace asmjit {
+      47             : 
+      48             : //! \addtogroup asmjit_base
+      49             : //! \{
+      50             : 
+      51             : // ============================================================================
+      52             : // [Forward Declarations]
+      53             : // ============================================================================
+      54             : 
+      55             : class CodeEmitter;
+      56             : 
+      57             : // ============================================================================
+      58             : // [asmjit::CallConv]
+      59             : // ============================================================================
+      60             : 
+      61             : //! Function calling convention.
+      62             : //!
+      63             : //! Function calling convention is a scheme that defines how function parameters
+      64             : //! are passed and how function returns its result. AsmJit defines a variety of
+      65             : //! architecture and OS specific calling conventions and also provides a compile
+      66             : //! time detection to make JIT code-generation easier.
+      67             : struct CallConv {
+      68             :   //! Calling convention id.
+      69             :   ASMJIT_ENUM(Id) {
+      70             :     //! None or invalid (can't be used).
+      71             :     kIdNone = 0,
+      72             : 
+      73             :     // ------------------------------------------------------------------------
+      74             :     // [Universal]
+      75             :     // ------------------------------------------------------------------------
+      76             : 
+      77             :     // TODO: To make this possible we need to know target ARCH and ABI.
+      78             : 
+      79             :     /*
+      80             : 
+      81             :     // Universal calling conventions are applicable to any target and are
+      82             :     // converted to target dependent conventions at runtime. The purpose of
+      83             :     // these conventions is to make using functions less target dependent.
+      84             : 
+      85             :     kIdCDecl = 1,
+      86             :     kIdStdCall = 2,
+      87             :     kIdFastCall = 3,
+      88             : 
+      89             :     //! AsmJit specific calling convention designed for calling functions
+      90             :     //! inside a multimedia code like that don't use many registers internally,
+      91             :     //! but are long enough to be called and not inlined. These functions are
+      92             :     //! usually used to calculate trigonometric functions, logarithms, etc...
+      93             :     kIdFastEval2 = 10,
+      94             :     kIdFastEval3 = 11,
+      95             :     kIdFastEval4 = 12,
+      96             :     */
+      97             : 
+      98             :     // ------------------------------------------------------------------------
+      99             :     // [X86]
+     100             :     // ------------------------------------------------------------------------
+     101             : 
+     102             :     //! X86 `__cdecl` calling convention (used by C runtime and libraries).
+     103             :     kIdX86CDecl = 16,
+     104             :     //! X86 `__stdcall` calling convention (used mostly by WinAPI).
+     105             :     kIdX86StdCall = 17,
+     106             :     //! X86 `__thiscall` calling convention (MSVC/Intel).
+     107             :     kIdX86MsThisCall = 18,
+     108             :     //! X86 `__fastcall` convention (MSVC/Intel).
+     109             :     kIdX86MsFastCall = 19,
+     110             :     //! X86 `__fastcall` convention (GCC and Clang).
+     111             :     kIdX86GccFastCall = 20,
+     112             :     //! X86 `regparm(1)` convention (GCC and Clang).
+     113             :     kIdX86GccRegParm1 = 21,
+     114             :     //! X86 `regparm(2)` convention (GCC and Clang).
+     115             :     kIdX86GccRegParm2 = 22,
+     116             :     //! X86 `regparm(3)` convention (GCC and Clang).
+     117             :     kIdX86GccRegParm3 = 23,
+     118             : 
+     119             :     kIdX86FastEval2 = 29,
+     120             :     kIdX86FastEval3 = 30,
+     121             :     kIdX86FastEval4 = 31,
+     122             : 
+     123             :     //! X64 calling convention defined by WIN64-ABI.
+     124             :     //!
+     125             :     //! Links:
+     126             :     //!   * <http://msdn.microsoft.com/en-us/library/9b372w95.aspx>.
+     127             :     kIdX86Win64 = 32,
+     128             :     //! X64 calling convention used by Unix platforms (SYSV/AMD64-ABI).
+     129             :     kIdX86SysV64 = 33,
+     130             : 
+     131             :     kIdX64FastEval2 = 45,
+     132             :     kIdX64FastEval3 = 46,
+     133             :     kIdX64FastEval4 = 47,
+     134             : 
+     135             :     // ------------------------------------------------------------------------
+     136             :     // [ARM]
+     137             :     // ------------------------------------------------------------------------
+     138             : 
+     139             :     //! Legacy calling convention, floating point arguments are passed via GP registers.
+     140             :     kIdArm32SoftFP = 48,
+     141             :     //! Modern calling convention, uses VFP registers to pass floating point arguments.
+     142             :     kIdArm32HardFP = 49,
+     143             : 
+     144             :     // ------------------------------------------------------------------------
+     145             :     // [Internal]
+     146             :     // ------------------------------------------------------------------------
+     147             : 
+     148             :     _kIdX86Start = 16,   //!< \internal
+     149             :     _kIdX86End = 31,     //!< \internal
+     150             : 
+     151             :     _kIdX64Start = 32,  //!< \internal
+     152             :     _kIdX64End = 47,    //!< \internal
+     153             : 
+     154             :     _kIdArmStart = 48,  //!< \internal
+     155             :     _kIdArmEnd = 49,    //!< \internal
+     156             : 
+     157             :     // ------------------------------------------------------------------------
+     158             :     // [Host]
+     159             :     // ------------------------------------------------------------------------
+     160             : 
+     161             : #if defined(ASMJIT_DOCGEN)
+     162             :     //! Default calling convention based on the current C++ compiler's settings.
+     163             :     //!
+     164             :     //! NOTE: This should be always the same as `kIdHostCDecl`, but some
+     165             :     //! compilers allow to override the default calling convention. Overriding
+     166             :     //! is not detected at the moment.
+     167             :     kIdHost          = DETECTED_AT_COMPILE_TIME,
+     168             : 
+     169             :     //! Default CDECL calling convention based on the current C++ compiler's settings.
+     170             :     kIdHostCDecl     = DETECTED_AT_COMPILE_TIME,
+     171             : 
+     172             :     //! Default STDCALL calling convention based on the current C++ compiler's settings.
+     173             :     //!
+     174             :     //! NOTE: If not defined by the host then it's the same as `kIdHostCDecl`.
+     175             :     kIdHostStdCall   = DETECTED_AT_COMPILE_TIME,
+     176             : 
+     177             :     //! Compatibility for `__fastcall` calling convention.
+     178             :     //!
+     179             :     //! NOTE: If not defined by the host then it's the same as `kIdHostCDecl`.
+     180             :     kIdHostFastCall  = DETECTED_AT_COMPILE_TIME
+     181             : #elif ASMJIT_ARCH_X86
+     182             :     kIdHost          = kIdX86CDecl,
+     183             :     kIdHostCDecl     = kIdX86CDecl,
+     184             :     kIdHostStdCall   = kIdX86StdCall,
+     185             :     kIdHostFastCall  = ASMJIT_CC_MSC   ? kIdX86MsFastCall  :
+     186             :                        ASMJIT_CC_GCC   ? kIdX86GccFastCall :
+     187             :                        ASMJIT_CC_CLANG ? kIdX86GccFastCall : kIdNone,
+     188             :     kIdHostFastEval2 = kIdX86FastEval2,
+     189             :     kIdHostFastEval3 = kIdX86FastEval3,
+     190             :     kIdHostFastEval4 = kIdX86FastEval4
+     191             : #elif ASMJIT_ARCH_X64
+     192             :     kIdHost          = ASMJIT_OS_WINDOWS ? kIdX86Win64 : kIdX86SysV64,
+     193             :     kIdHostCDecl     = kIdHost, // Doesn't exist, redirected to host.
+     194             :     kIdHostStdCall   = kIdHost, // Doesn't exist, redirected to host.
+     195             :     kIdHostFastCall  = kIdHost, // Doesn't exist, redirected to host.
+     196             :     kIdHostFastEval2 = kIdX64FastEval2,
+     197             :     kIdHostFastEval3 = kIdX64FastEval3,
+     198             :     kIdHostFastEval4 = kIdX64FastEval4
+     199             : #elif ASMJIT_ARCH_ARM32
+     200             : # if defined(__SOFTFP__)
+     201             :     kIdHost          = kIdArm32SoftFP,
+     202             : # else
+     203             :     kIdHost          = kIdArm32HardFP,
+     204             : # endif
+     205             :     // These don't exist on ARM.
+     206             :     kIdHostCDecl     = kIdHost, // Doesn't exist, redirected to host.
+     207             :     kIdHostStdCall   = kIdHost, // Doesn't exist, redirected to host.
+     208             :     kIdHostFastCall  = kIdHost  // Doesn't exist, redirected to host.
+     209             : #else
+     210             : # error "[asmjit] Couldn't determine the target's calling convention."
+     211             : #endif
+     212             :   };
+     213             : 
+     214             :   //! Calling convention algorithm.
+     215             :   //!
+     216             :   //! This is AsmJit specific. It basically describes how should AsmJit convert
+     217             :   //! the function arguments defined by `FuncSignature` into register ids or
+     218             :   //! stack offsets. The default algorithm is a standard algorithm that assigns
+     219             :   //! registers first, and then assigns stack. The Win64 algorithm does register
+     220             :   //! shadowing as defined by `WIN64` calling convention - it applies to 64-bit
+     221             :   //! calling conventions only.
+     222             :   ASMJIT_ENUM(Algorithm) {
+     223             :     kAlgorithmDefault    = 0,            //!< Default algorithm (cross-platform).
+     224             :     kAlgorithmWin64      = 1             //!< WIN64 specific algorithm.
+     225             :   };
+     226             : 
+     227             :   //! Calling convention flags.
+     228             :   ASMJIT_ENUM(Flags) {
+     229             :     kFlagCalleePopsStack = 0x01,         //!< Callee is responsible for cleaning up the stack.
+     230             :     kFlagPassFloatsByVec = 0x02,         //!< Pass F32 and F64 arguments by VEC128 register.
+     231             :     kFlagVectorCall      = 0x04,         //!< This is a '__vectorcall' calling convention.
+     232             :     kFlagIndirectVecArgs = 0x08          //!< Pass vector arguments indirectly (as a pointer).
+     233             :   };
+     234             : 
+     235             :   //! Internal limits of AsmJit/CallConv.
+     236             :   ASMJIT_ENUM(Limits) {
+     237             :     kMaxVRegKinds        = Globals::kMaxVRegKinds,
+     238             :     kNumRegArgsPerKind   = 8
+     239             :   };
+     240             : 
+     241             :   //! Passed registers' order.
+     242             :   union RegOrder {
+     243             :     uint8_t id[kNumRegArgsPerKind];      //!< Passed registers, ordered.
+     244             :     uint32_t packed[(kNumRegArgsPerKind + 3) / 4];
+     245             :   };
+     246             : 
+     247             :   // --------------------------------------------------------------------------
+     248             :   // [Utilities]
+     249             :   // --------------------------------------------------------------------------
+     250             : 
+     251        3596 :   static ASMJIT_INLINE bool isX86Family(uint32_t ccId) noexcept { return ccId >= _kIdX86Start && ccId <= _kIdX64End; }
+     252             :   static ASMJIT_INLINE bool isArmFamily(uint32_t ccId) noexcept { return ccId >= _kIdArmStart && ccId <= _kIdArmEnd; }
+     253             : 
+     254             :   // --------------------------------------------------------------------------
+     255             :   // [Init / Reset]
+     256             :   // --------------------------------------------------------------------------
+     257             : 
+     258             :   ASMJIT_API Error init(uint32_t ccId) noexcept;
+     259             : 
+     260             :   ASMJIT_INLINE void reset() noexcept {
+     261             :     ::memset(this, 0, sizeof(*this));
+     262        3596 :     ::memset(_passedOrder, 0xFF, sizeof(_passedOrder));
+     263             :   }
+     264             : 
+     265             :   // --------------------------------------------------------------------------
+     266             :   // [Accessors]
+     267             :   // --------------------------------------------------------------------------
+     268             : 
+     269             :   //! Get calling convention id, see \ref Id.
+     270        1948 :   ASMJIT_INLINE uint32_t getId() const noexcept { return _id; }
+     271             :   //! Set calling convention id, see \ref Id.
+     272        3596 :   ASMJIT_INLINE void setId(uint32_t id) noexcept { _id = static_cast<uint8_t>(id); }
+     273             : 
+     274             :   //! Get architecture type.
+     275        5544 :   ASMJIT_INLINE uint32_t getArchType() const noexcept { return _archType; }
+     276             :   //! Set architecture type.
+     277        3596 :   ASMJIT_INLINE void setArchType(uint32_t archType) noexcept { _archType = static_cast<uint8_t>(archType); }
+     278             : 
+     279             :   //! Get calling convention algorithm, see \ref Algorithm.
+     280        3596 :   ASMJIT_INLINE uint32_t getAlgorithm() const noexcept { return _algorithm; }
+     281             :   //! Set calling convention algorithm, see \ref Algorithm.
+     282           0 :   ASMJIT_INLINE void setAlgorithm(uint32_t algorithm) noexcept { _algorithm = static_cast<uint8_t>(algorithm); }
+     283             : 
+     284             :   //! Get if the calling convention has the given `flag` set.
+     285        5046 :   ASMJIT_INLINE bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+     286             :   //! Get calling convention flags, see \ref Flags.
+     287             :   ASMJIT_INLINE uint32_t getFlags() const noexcept { return _flags; }
+     288             :   //! Add calling convention flags, see \ref Flags.
+     289           0 :   ASMJIT_INLINE void setFlags(uint32_t flag) noexcept { _flags = flag; };
+     290             :   //! Add calling convention flags, see \ref Flags.
+     291             :   ASMJIT_INLINE void addFlags(uint32_t flag) noexcept { _flags |= flag; };
+     292             : 
+     293             :   //! Get a natural stack alignment.
+     294        5844 :   ASMJIT_INLINE uint32_t getNaturalStackAlignment() const noexcept { return _naturalStackAlignment; }
+     295             : 
+     296             :   //! Set a natural stack alignment.
+     297             :   //!
+     298             :   //! This function can be used to override the default stack alignment in case
+     299             :   //! that you know that it's alignment is different. For example it allows to
+     300             :   //! implement custom calling conventions that guarantee higher stack alignment.
+     301             :   ASMJIT_INLINE void setNaturalStackAlignment(uint32_t value) noexcept {
+     302             :     ASMJIT_ASSERT(value < 256);
+     303        3596 :     _naturalStackAlignment = static_cast<uint8_t>(value);
+     304           0 :   }
+     305             : 
+     306             :   //! Get if this calling convention specifies 'SpillZone'.
+     307             :   ASMJIT_INLINE bool hasSpillZone() const noexcept { return _spillZoneSize != 0; }
+     308             :   //! Get size of 'SpillZone'.
+     309        1948 :   ASMJIT_INLINE uint32_t getSpillZoneSize() const noexcept { return _spillZoneSize; }
+     310             :   //! Set size of 'SpillZone'.
+     311           0 :   ASMJIT_INLINE void setSpillZoneSize(uint32_t size) noexcept { _spillZoneSize = static_cast<uint8_t>(size); }
+     312             : 
+     313             :   //! Get if this calling convention specifies 'RedZone'.
+     314             :   ASMJIT_INLINE bool hasRedZone() const noexcept { return _redZoneSize != 0; }
+     315             :   //! Get size of 'RedZone'.
+     316             :   ASMJIT_INLINE uint32_t getRedZoneSize() const noexcept { return _redZoneSize; }
+     317             :   //! Set size of 'RedZone'.
+     318        3596 :   ASMJIT_INLINE void setRedZoneSize(uint32_t size) noexcept { _redZoneSize = static_cast<uint16_t>(size); }
+     319             : 
+     320             :   ASMJIT_INLINE const uint8_t* getPassedOrder(uint32_t kind) const noexcept {
+     321             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     322             :     return _passedOrder[kind].id;
+     323             :   }
+     324             : 
+     325             :   ASMJIT_INLINE uint32_t getPassedRegs(uint32_t kind) const noexcept {
+     326             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     327       11388 :     return _passedRegs[kind];
+     328             :   }
+     329             : 
+     330             :   ASMJIT_INLINE void _setPassedPacked(uint32_t kind, uint32_t p0, uint32_t p1) noexcept {
+     331             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     332             : 
+     333        3596 :     _passedOrder[kind].packed[0] = p0;
+     334        3596 :     _passedOrder[kind].packed[1] = p1;
+     335             :   }
+     336             : 
+     337             :   ASMJIT_INLINE void setPassedToNone(uint32_t kind) noexcept {
+     338             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     339             : 
+     340             :     _setPassedPacked(kind, ASMJIT_PACK32_4x8(0xFF, 0xFF, 0xFF, 0xFF),
+     341             :                            ASMJIT_PACK32_4x8(0xFF, 0xFF, 0xFF, 0xFF));
+     342             :     _passedRegs[kind] = 0;
+     343             :   }
+     344             : 
+     345             :   ASMJIT_INLINE void setPassedOrder(uint32_t kind, uint32_t a0, uint32_t a1 = 0xFF, uint32_t a2 = 0xFF, uint32_t a3 = 0xFF, uint32_t a4 = 0xFF, uint32_t a5 = 0xFF, uint32_t a6 = 0xFF, uint32_t a7 = 0xFF) noexcept {
+     346             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     347             : 
+     348             :     _setPassedPacked(kind, ASMJIT_PACK32_4x8(a0, a1, a2, a3),
+     349             :                            ASMJIT_PACK32_4x8(a4, a5, a6, a7));
+     350             : 
+     351             :     // NOTE: This should always be called with all arguments known at compile
+     352             :     // time, so even if it looks scary it should be translated to a single
+     353             :     // instruction.
+     354           0 :     _passedRegs[kind] = (a0 != 0xFF ? 1U << a0 : 0U) |
+     355             :                         (a1 != 0xFF ? 1U << a1 : 0U) |
+     356             :                         (a2 != 0xFF ? 1U << a2 : 0U) |
+     357             :                         (a3 != 0xFF ? 1U << a3 : 0U) |
+     358             :                         (a4 != 0xFF ? 1U << a4 : 0U) |
+     359             :                         (a5 != 0xFF ? 1U << a5 : 0U) |
+     360             :                         (a6 != 0xFF ? 1U << a6 : 0U) |
+     361             :                         (a7 != 0xFF ? 1U << a7 : 0U) ;
+     362             :   }
+     363             : 
+     364             :   ASMJIT_INLINE uint32_t getPreservedRegs(uint32_t kind) const noexcept {
+     365             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     366        9440 :     return _preservedRegs[kind];
+     367             :   }
+     368             : 
+     369             : 
+     370             :   ASMJIT_INLINE void setPreservedRegs(uint32_t kind, uint32_t regs) noexcept {
+     371             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     372           0 :     _preservedRegs[kind] = regs;
+     373        3596 :   }
+     374             : 
+     375             :   // --------------------------------------------------------------------------
+     376             :   // [Members]
+     377             :   // --------------------------------------------------------------------------
+     378             : 
+     379             :   uint8_t _id;                           //!< Calling convention id, see \ref Id.
+     380             :   uint8_t _archType;                     //!< Architecture type (see \ref ArchInfo::Type).
+     381             :   uint8_t _algorithm;                    //!< Calling convention algorithm.
+     382             :   uint8_t _flags;                        //!< Calling convention flags.
+     383             : 
+     384             :   uint8_t _naturalStackAlignment;        //!< Natural stack alignment as defined by OS/ABI.
+     385             :   uint8_t _spillZoneSize;                //!< Spill zone size (WIN64 == 32 bytes).
+     386             :   uint16_t _redZoneSize;                 //!< Red zone size (AMD64 == 128 bytes).
+     387             : 
+     388             :   RegOrder _passedOrder[kMaxVRegKinds];  //!< Passed registers' order, per kind.
+     389             :   uint32_t _passedRegs[kMaxVRegKinds];   //!< Mask of all passed registers, per kind.
+     390             :   uint32_t _preservedRegs[kMaxVRegKinds];//!< Mask of all preserved registers, per kind.
+     391             : };
+     392             : 
+     393             : // ============================================================================
+     394             : // [asmjit::FuncArgIndex]
+     395             : // ============================================================================
+     396             : 
+     397             : //! Function argument index (lo/hi).
+     398             : ASMJIT_ENUM(FuncArgIndex) {
+     399             :   //! Maximum number of function arguments supported by AsmJit.
+     400             :   kFuncArgCount = 16,
+     401             :   //! Extended maximum number of arguments (used internally).
+     402             :   kFuncArgCountLoHi = kFuncArgCount * 2,
+     403             : 
+     404             :   //! Index to the LO part of function argument (default).
+     405             :   //!
+     406             :   //! This value is typically omitted and added only if there is HI argument
+     407             :   //! accessed.
+     408             :   kFuncArgLo = 0,
+     409             : 
+     410             :   //! Index to the HI part of function argument.
+     411             :   //!
+     412             :   //! HI part of function argument depends on target architecture. On x86 it's
+     413             :   //! typically used to transfer 64-bit integers (they form a pair of 32-bit
+     414             :   //! integers).
+     415             :   kFuncArgHi = kFuncArgCount
+     416             : };
+     417             : 
+     418             : // ============================================================================
+     419             : // [asmjit::FuncSignature]
+     420             : // ============================================================================
+     421             : 
+     422             : //! Function signature.
+     423             : //!
+     424             : //! Contains information about function return type, count of arguments and
+     425             : //! their TypeIds. Function signature is a low level structure which doesn't
+     426             : //! contain platform specific or calling convention specific information.
+     427             : struct FuncSignature {
+     428             :   enum {
+     429             :     //! Doesn't have variable number of arguments (`...`).
+     430             :     kNoVarArgs = 0xFF
+     431             :   };
+     432             : 
+     433             :   // --------------------------------------------------------------------------
+     434             :   // [Init / Reset]
+     435             :   // --------------------------------------------------------------------------
+     436             : 
+     437             :   //! Initialize the function signature.
+     438             :   ASMJIT_INLINE void init(uint32_t ccId, uint32_t ret, const uint8_t* args, uint32_t argCount) noexcept {
+     439             :     ASMJIT_ASSERT(ccId <= 0xFF);
+     440             :     ASMJIT_ASSERT(argCount <= 0xFF);
+     441             : 
+     442        3596 :     _callConv = static_cast<uint8_t>(ccId);
+     443        3596 :     _argCount = static_cast<uint8_t>(argCount);
+     444        3596 :     _vaIndex = kNoVarArgs;
+     445        3596 :     _ret = ret;
+     446        3596 :     _args = args;
+     447             :   }
+     448             : 
+     449             :   ASMJIT_INLINE void reset() noexcept {
+     450             :     memset(this, 0, sizeof(*this));
+     451             :   }
+     452             : 
+     453             :   // --------------------------------------------------------------------------
+     454             :   // [Accessors]
+     455             :   // --------------------------------------------------------------------------
+     456             : 
+     457             :   //! Get the function's calling convention.
+     458        3596 :   ASMJIT_INLINE uint32_t getCallConv() const noexcept { return _callConv; }
+     459             : 
+     460             :   //! Get if the function has variable number of arguments (...).
+     461             :   ASMJIT_INLINE bool hasVarArgs() const noexcept { return _vaIndex != kNoVarArgs; }
+     462             :   //! Get the variable arguments (...) index, `kNoVarArgs` if none.
+     463             :   ASMJIT_INLINE uint32_t getVAIndex() const noexcept { return _vaIndex; }
+     464             : 
+     465             :   //! Get the number of function arguments.
+     466        5244 :   ASMJIT_INLINE uint32_t getArgCount() const noexcept { return _argCount; }
+     467             : 
+     468             :   ASMJIT_INLINE bool hasRet() const noexcept { return _ret != TypeId::kVoid; }
+     469             :   //! Get the return value type.
+     470        3596 :   ASMJIT_INLINE uint32_t getRet() const noexcept { return _ret; }
+     471             : 
+     472             :   //! Get the type of the argument at index `i`.
+     473             :   ASMJIT_INLINE uint32_t getArg(uint32_t i) const noexcept {
+     474             :     ASMJIT_ASSERT(i < _argCount);
+     475             :     return _args[i];
+     476             :   }
+     477             :   //! Get the array of function arguments' types.
+     478        3596 :   ASMJIT_INLINE const uint8_t* getArgs() const noexcept { return _args; }
+     479             : 
+     480             :   // --------------------------------------------------------------------------
+     481             :   // [Members]
+     482             :   // --------------------------------------------------------------------------
+     483             : 
+     484             :   uint8_t _callConv;                     //!< Calling convention id.
+     485             :   uint8_t _argCount;                     //!< Count of arguments.
+     486             :   uint8_t _vaIndex;                      //!< Index to a first vararg or `kNoVarArgs`.
+     487             :   uint8_t _ret;                          //!< TypeId of a return value.
+     488             :   const uint8_t* _args;                  //!< TypeIds of function arguments.
+     489             : };
+     490             : 
+     491             : // ============================================================================
+     492             : // [asmjit::FuncSignatureT]
+     493             : // ============================================================================
+     494             : 
+     495             : //! \internal
+     496             : #define T(TYPE) TypeIdOf<TYPE>::kTypeId
+     497             : namespace { // unnamed namespace to avoid unique global symbols
+     498             : 
+     499             : //! Static function signature (no arguments).
+     500             : template<typename RET>
+     501             : class FuncSignature0 : public FuncSignature {
+     502             : public:
+     503        1948 :   ASMJIT_INLINE FuncSignature0(uint32_t ccId = CallConv::kIdHost) noexcept {
+     504             :     init(ccId, T(RET), nullptr, 0);
+     505             :   }
+     506             : };
+     507             : 
+     508             : //! Static function signature (1 argument).
+     509             : template<typename RET, typename A0>
+     510             : class FuncSignature1 : public FuncSignature {
+     511             : public:
+     512        1426 :   ASMJIT_INLINE FuncSignature1(uint32_t ccId = CallConv::kIdHost) noexcept {
+     513             :     static const uint8_t args[] = { T(A0) };
+     514             :     init(ccId, T(RET), args, ASMJIT_ARRAY_SIZE(args));
+     515             :   }
+     516             : };
+     517             : 
+     518             : //! Static function signature (2 arguments).
+     519             : template<typename RET, typename A0, typename A1>
+     520             : class FuncSignature2 : public FuncSignature {
+     521             : public:
+     522         222 :   ASMJIT_INLINE FuncSignature2(uint32_t ccId = CallConv::kIdHost) noexcept {
+     523             :     static const uint8_t args[] = { T(A0), T(A1) };
+     524             :     init(ccId, T(RET), args, ASMJIT_ARRAY_SIZE(args));
+     525             :   }
+     526             : };
+     527             : 
+     528             : //! Static function signature (3 arguments).
+     529             : template<typename RET, typename A0, typename A1, typename A2>
+     530             : class FuncSignature3 : public FuncSignature {
+     531             : public:
+     532             :   ASMJIT_INLINE FuncSignature3(uint32_t ccId = CallConv::kIdHost) noexcept {
+     533             :     static const uint8_t args[] = { T(A0), T(A1), T(A2) };
+     534             :     init(ccId, T(RET), args, ASMJIT_ARRAY_SIZE(args));
+     535             :   }
+     536             : };
+     537             : 
+     538             : //! Static function signature (4 arguments).
+     539             : template<typename RET, typename A0, typename A1, typename A2, typename A3>
+     540             : class FuncSignature4 : public FuncSignature {
+     541             : public:
+     542             :   ASMJIT_INLINE FuncSignature4(uint32_t ccId = CallConv::kIdHost) noexcept {
+     543             :     static const uint8_t args[] = { T(A0), T(A1), T(A2), T(A3) };
+     544             :     init(ccId, T(RET), args, ASMJIT_ARRAY_SIZE(args));
+     545             :   }
+     546             : };
+     547             : 
+     548             : //! Static function signature (5 arguments).
+     549             : template<typename RET, typename A0, typename A1, typename A2, typename A3, typename A4>
+     550             : class FuncSignature5 : public FuncSignature {
+     551             : public:
+     552             :   ASMJIT_INLINE FuncSignature5(uint32_t ccId = CallConv::kIdHost) noexcept {
+     553             :     static const uint8_t args[] = { T(A0), T(A1), T(A2), T(A3), T(A4) };
+     554             :     init(ccId, T(RET), args, ASMJIT_ARRAY_SIZE(args));
+     555             :   }
+     556             : };
+     557             : 
+     558             : //! Static function signature (6 arguments).
+     559             : template<typename RET, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5>
+     560             : class FuncSignature6 : public FuncSignature {
+     561             : public:
+     562             :   ASMJIT_INLINE FuncSignature6(uint32_t ccId = CallConv::kIdHost) noexcept {
+     563             :     static const uint8_t args[] = { T(A0), T(A1), T(A2), T(A3), T(A4), T(A5) };
+     564             :     init(ccId, T(RET), args, ASMJIT_ARRAY_SIZE(args));
+     565             :   }
+     566             : };
+     567             : 
+     568             : //! Static function signature (7 arguments).
+     569             : template<typename RET, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6>
+     570             : class FuncSignature7 : public FuncSignature {
+     571             : public:
+     572             :   ASMJIT_INLINE FuncSignature7(uint32_t ccId = CallConv::kIdHost) noexcept {
+     573             :     static const uint8_t args[] = { T(A0), T(A1), T(A2), T(A3), T(A4), T(A5), T(A6) };
+     574             :     init(ccId, T(RET), args, ASMJIT_ARRAY_SIZE(args));
+     575             :   }
+     576             : };
+     577             : 
+     578             : //! Static function signature (8 arguments).
+     579             : template<typename RET, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7>
+     580             : class FuncSignature8 : public FuncSignature {
+     581             : public:
+     582             :   ASMJIT_INLINE FuncSignature8(uint32_t ccId = CallConv::kIdHost) noexcept {
+     583             :     static const uint8_t args[] = { T(A0), T(A1), T(A2), T(A3), T(A4), T(A5), T(A6), T(A7) };
+     584             :     init(ccId, T(RET), args, ASMJIT_ARRAY_SIZE(args));
+     585             :   }
+     586             : };
+     587             : 
+     588             : //! Static function signature (9 arguments).
+     589             : template<typename RET, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8>
+     590             : class FuncSignature9 : public FuncSignature {
+     591             : public:
+     592             :   ASMJIT_INLINE FuncSignature9(uint32_t ccId = CallConv::kIdHost) noexcept {
+     593             :     static const uint8_t args[] = { T(A0), T(A1), T(A2), T(A3), T(A4), T(A5), T(A6), T(A7), T(A8) };
+     594             :     init(ccId, T(RET), args, ASMJIT_ARRAY_SIZE(args));
+     595             :   }
+     596             : };
+     597             : 
+     598             : //! Static function signature (10 arguments).
+     599             : template<typename RET, typename A0, typename A1, typename A2, typename A3, typename A4, typename A5, typename A6, typename A7, typename A8, typename A9>
+     600             : class FuncSignature10 : public FuncSignature {
+     601             : public:
+     602             :   ASMJIT_INLINE FuncSignature10(uint32_t ccId = CallConv::kIdHost) noexcept {
+     603             :     static const uint8_t args[] = { T(A0), T(A1), T(A2), T(A3), T(A4), T(A5), T(A6), T(A7), T(A8), T(A9) };
+     604             :     init(ccId, T(RET), args, ASMJIT_ARRAY_SIZE(args));
+     605             :   }
+     606             : };
+     607             : 
+     608             : #if ASMJIT_CC_HAS_VARIADIC_TEMPLATES
+     609             : //! Static function signature (variadic).
+     610             : template<typename RET, typename... ARGS>
+     611             : class FuncSignatureT : public FuncSignature {
+     612             : public:
+     613             :   ASMJIT_INLINE FuncSignatureT(uint32_t ccId = CallConv::kIdHost) noexcept {
+     614             :     static const uint8_t args[] = { (T(ARGS))... };
+     615             :     init(ccId, T(RET), args, ASMJIT_ARRAY_SIZE(args));
+     616             :   }
+     617             : };
+     618             : #endif // ASMJIT_CC_HAS_VARIADIC_TEMPLATES
+     619             : 
+     620             : }
+     621             : #undef T
+     622             : 
+     623             : // ============================================================================
+     624             : // [asmjit::FuncSignatureX]
+     625             : // ============================================================================
+     626             : 
+     627             : //! Dynamic function signature.
+     628             : class FuncSignatureX : public FuncSignature {
+     629             : public:
+     630             :   // --------------------------------------------------------------------------
+     631             :   // [Construction / Destruction]
+     632             :   // --------------------------------------------------------------------------
+     633             : 
+     634             :   ASMJIT_INLINE FuncSignatureX(uint32_t ccId = CallConv::kIdHost) noexcept {
+     635             :     init(ccId, TypeId::kVoid, _builderArgList, 0);
+     636             :   }
+     637             : 
+     638             :   // --------------------------------------------------------------------------
+     639             :   // [Accessors]
+     640             :   // --------------------------------------------------------------------------
+     641             : 
+     642             :   ASMJIT_INLINE void setCallConv(uint32_t ccId) noexcept {
+     643             :     ASMJIT_ASSERT(ccId <= 0xFF);
+     644             :     _callConv = static_cast<uint8_t>(ccId);
+     645             :   }
+     646             : 
+     647             :   //! Set the return type to `retType`.
+     648             :   ASMJIT_INLINE void setRet(uint32_t retType) noexcept { _ret = retType; }
+     649             :   //! Set the return type based on `T`.
+     650             :   template<typename T>
+     651             :   ASMJIT_INLINE void setRetT() noexcept { setRet(TypeIdOf<T>::kTypeId); }
+     652             : 
+     653             :   //! Set the argument at index `i` to the `type`
+     654             :   ASMJIT_INLINE void setArg(uint32_t i, uint32_t type) noexcept {
+     655             :     ASMJIT_ASSERT(i < _argCount);
+     656             :     _builderArgList[i] = type;
+     657             :   }
+     658             :   //! Set the argument at index `i` to the type based on `T`.
+     659             :   template<typename T>
+     660             :   ASMJIT_INLINE void setArgT(uint32_t i) noexcept { setArg(i, TypeIdOf<T>::kTypeId); }
+     661             : 
+     662             :   //! Append an argument of `type` to the function prototype.
+     663             :   ASMJIT_INLINE void addArg(uint32_t type) noexcept {
+     664             :     ASMJIT_ASSERT(_argCount < kFuncArgCount);
+     665             :     _builderArgList[_argCount++] = static_cast<uint8_t>(type);
+     666             :   }
+     667             :   //! Append an argument of type based on `T` to the function prototype.
+     668             :   template<typename T>
+     669             :   ASMJIT_INLINE void addArgT() noexcept { addArg(TypeIdOf<T>::kTypeId); }
+     670             : 
+     671             :   // --------------------------------------------------------------------------
+     672             :   // [Members]
+     673             :   // --------------------------------------------------------------------------
+     674             : 
+     675             :   uint8_t _builderArgList[kFuncArgCount];
+     676             : };
+     677             : 
+     678             : // ============================================================================
+     679             : // [asmjit::FuncDetail]
+     680             : // ============================================================================
+     681             : 
+     682             : //! Function detail - CallConv and expanded FuncSignature.
+     683             : //!
+     684             : //! Function details is architecture and OS dependent representation of function.
+     685             : //! It contains calling convention and expanded function signature so all
+     686             : //! arguments have assigned either register type & id or stack address.
+     687             : class FuncDetail {
+     688             : public:
+     689             :   ASMJIT_ENUM(Limits) {
+     690             :     kMaxVRegKinds = Globals::kMaxVRegKinds
+     691             :   };
+     692             : 
+     693             :   //! Argument or return value as defined by `FuncSignature`, but with register
+     694             :   //! or stack address (and other metadata) assigned.
+     695             :   struct Value {
+     696             :     ASMJIT_ENUM(Parts) {
+     697             :       kTypeIdShift      = 24,
+     698             :       kTypeIdMask       = 0xFF000000U,
+     699             : 
+     700             :       kRegTypeShift     = 8,
+     701             :       kRegTypeMask      = 0x0000FF00U,
+     702             : 
+     703             :       kRegIdShift       = 0,
+     704             :       kRegIdMask        = 0x000000FFU,
+     705             : 
+     706             :       kStackOffsetShift = 0,
+     707             :       kStackOffsetMask  = 0x0000FFFFU,
+     708             : 
+     709             :       kIsByReg          = 0x00010000U,
+     710             :       kIsByStack        = 0x00020000U,
+     711             :       kIsIndirect       = 0x00040000U
+     712             :     };
+     713             : 
+     714             :     //! Get if this value is initialized (i.e. contains a valid data).
+     715             :     ASMJIT_INLINE bool isInitialized() const noexcept { return _value != 0; }
+     716             :     //! Initialize this in/out by a given `typeId`.
+     717        5466 :     ASMJIT_INLINE void initTypeId(uint32_t typeId) noexcept { _value = typeId << kTypeIdShift; }
+     718             :     //! Initialize this in/out by a given `typeId`, `regType`, and `regId`.
+     719             :     ASMJIT_INLINE void initReg(uint32_t typeId, uint32_t regType, uint32_t regId) noexcept {
+     720        1450 :       _value = (typeId << kTypeIdShift) | (regType << kRegTypeShift) | (regId << kRegIdShift) | kIsByReg;
+     721           0 :     }
+     722             :     //! Initialize this in/out by a given `typeId` and `offset`.
+     723             :     ASMJIT_INLINE void initStack(uint32_t typeId, uint32_t stackOffset) noexcept {
+     724             :       _value = (typeId << kTypeIdShift) | (stackOffset << kStackOffsetShift) | kIsByStack;
+     725             :     }
+     726             :     //! Reset the value to its uninitialized and unassigned state.
+     727             :     ASMJIT_INLINE void reset() noexcept { _value = 0; }
+     728             : 
+     729             :     ASMJIT_INLINE void assignToReg(uint32_t regType, uint32_t regId) noexcept {
+     730             :       ASMJIT_ASSERT(!isAssigned());
+     731         420 :       _value |= (regType << kRegTypeShift) | (regId << kRegIdShift) | kIsByReg;
+     732        3596 :     }
+     733             : 
+     734             :     ASMJIT_INLINE void assignToStack(int32_t offset) noexcept {
+     735             :       ASMJIT_ASSERT(!isAssigned());
+     736           0 :       _value |= (offset << kStackOffsetShift) | kIsByStack;
+     737             :     }
+     738             : 
+     739             :     //! Get if this argument is passed by register.
+     740        6394 :     ASMJIT_INLINE bool byReg() const noexcept { return (_value & kIsByReg) != 0; }
+     741             :     //! Get if this argument is passed by stack.
+     742           0 :     ASMJIT_INLINE bool byStack() const noexcept { return (_value & kIsByStack) != 0; }
+     743             :     //! Get if this argument is passed by register.
+     744           0 :     ASMJIT_INLINE bool isAssigned() const noexcept { return (_value & (kIsByReg | kIsByStack)) != 0; }
+     745             :     //! Get if this argument is passed through a pointer (used by WIN64 to pass XMM|YMM|ZMM).
+     746             :     ASMJIT_INLINE bool isIndirect() const noexcept { return (_value & kIsIndirect) != 0; }
+     747             : 
+     748             :     //! Get virtual type of this argument or return value.
+     749        5886 :     ASMJIT_INLINE uint32_t getTypeId() const noexcept { return _value >> kTypeIdShift; }
+     750             :     //! Get a register type of the register used to pass the argument or return the value.
+     751        6694 :     ASMJIT_INLINE uint32_t getRegType() const noexcept { return (_value & kRegTypeMask) >> kRegTypeShift; }
+     752             :     //! Get a physical id of the register used to pass the argument or return the value.
+     753        7114 :     ASMJIT_INLINE uint32_t getRegId() const noexcept { return (_value & kRegIdMask) >> kRegIdShift; }
+     754             :     //! Get a stack offset of this argument (always positive).
+     755           0 :     ASMJIT_INLINE int32_t getStackOffset() const noexcept { return (_value & kStackOffsetMask) >> kStackOffsetShift; }
+     756             : 
+     757             :     uint32_t _value;
+     758             :   };
+     759             : 
+     760             :   // --------------------------------------------------------------------------
+     761             :   // [Construction / Destruction]
+     762             :   // --------------------------------------------------------------------------
+     763             : 
+     764        3596 :   ASMJIT_INLINE FuncDetail() noexcept { reset(); }
+     765             :   ASMJIT_INLINE FuncDetail(const FuncDetail& other) noexcept {
+     766             :     ::memcpy(this, &other, sizeof(*this));
+     767             :   }
+     768             : 
+     769             :   // --------------------------------------------------------------------------
+     770             :   // [Init / Reset]
+     771             :   // --------------------------------------------------------------------------
+     772             : 
+     773             :   //! Initialize this `FuncDetail` to the given signature.
+     774             :   ASMJIT_API Error init(const FuncSignature& sign);
+     775             :   ASMJIT_INLINE void reset() noexcept { ::memset(this, 0, sizeof(*this)); }
+     776             : 
+     777             :   // --------------------------------------------------------------------------
+     778             :   // [Accessors - Calling Convention]
+     779             :   // --------------------------------------------------------------------------
+     780             : 
+     781             :   //! Get the function's calling convention, see `CallConv`.
+     782             :   ASMJIT_INLINE const CallConv& getCallConv() const noexcept { return _callConv; }
+     783             : 
+     784             :   //! Get CallConv flags, see \ref CallConv::Flags.
+     785             :   ASMJIT_INLINE uint32_t getFlags() const noexcept { return _callConv.getFlags(); }
+     786             :   //! Check if a CallConv `flag` is set, see \ref CallConv::Flags.
+     787             :   ASMJIT_INLINE bool hasFlag(uint32_t ccFlag) const noexcept { return _callConv.hasFlag(ccFlag); }
+     788             : 
+     789             :   // --------------------------------------------------------------------------
+     790             :   // [Accessors - Arguments and Return]
+     791             :   // --------------------------------------------------------------------------
+     792             : 
+     793             :   //! Get count of function return values.
+     794        3596 :   ASMJIT_INLINE uint32_t getRetCount() const noexcept { return _retCount; }
+     795             :   //! Get the number of function arguments.
+     796       12658 :   ASMJIT_INLINE uint32_t getArgCount() const noexcept { return _argCount; }
+     797             : 
+     798             :   //! Get whether the function has a return value.
+     799        1948 :   ASMJIT_INLINE bool hasRet() const noexcept { return _retCount != 0; }
+     800             :   //! Get function return value.
+     801             :   ASMJIT_INLINE Value& getRet(size_t index = 0) noexcept {
+     802             :     ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_rets));
+     803             :     return _rets[index];
+     804             :   }
+     805             :   //! Get function return value (const).
+     806             :   ASMJIT_INLINE const Value& getRet(size_t index = 0) const noexcept {
+     807             :     ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_rets));
+     808           0 :     return _rets[index];
+     809             :   }
+     810             : 
+     811             :   //! Get function arguments array.
+     812             :   ASMJIT_INLINE Value* getArgs() noexcept { return _args; }
+     813             :   //! Get function arguments array (const).
+     814             :   ASMJIT_INLINE const Value* getArgs() const noexcept { return _args; }
+     815             : 
+     816             :   ASMJIT_INLINE bool hasArg(size_t index) const noexcept {
+     817             :     ASMJIT_ASSERT(index < kFuncArgCountLoHi);
+     818             :     return _args[index].isInitialized();
+     819             :   }
+     820             : 
+     821             :   //! Get function argument at index `index`.
+     822             :   ASMJIT_INLINE Value& getArg(size_t index) noexcept {
+     823             :     ASMJIT_ASSERT(index < kFuncArgCountLoHi);
+     824             :     return _args[index];
+     825             :   }
+     826             : 
+     827             :   //! Get function argument at index `index`.
+     828             :   ASMJIT_INLINE const Value& getArg(size_t index) const noexcept {
+     829             :     ASMJIT_ASSERT(index < kFuncArgCountLoHi);
+     830           0 :     return _args[index];
+     831             :   }
+     832             : 
+     833             :   ASMJIT_INLINE void resetArg(size_t index) noexcept {
+     834             :     ASMJIT_ASSERT(index < kFuncArgCountLoHi);
+     835             :     _args[index].reset();
+     836             :   }
+     837             : 
+     838             :   //! Get if the function passes one or more argument by stack.
+     839             :   ASMJIT_INLINE bool hasStackArgs() const noexcept { return _argStackSize != 0; }
+     840             :   //! Get stack size needed for function arguments passed on the stack.
+     841           0 :   ASMJIT_INLINE uint32_t getArgStackSize() const noexcept { return _argStackSize; }
+     842             : 
+     843             :   ASMJIT_INLINE uint32_t getNaturalStackAlignment() const noexcept { return _callConv.getNaturalStackAlignment(); }
+     844             :   ASMJIT_INLINE uint32_t getSpillZoneSize() const noexcept { return _callConv.getSpillZoneSize(); }
+     845             :   ASMJIT_INLINE uint32_t getRedZoneSize() const noexcept { return _callConv.getRedZoneSize(); }
+     846             : 
+     847             :   ASMJIT_INLINE uint32_t getPassedRegs(uint32_t kind) const noexcept { return _callConv.getPassedRegs(kind); }
+     848             :   ASMJIT_INLINE uint32_t getPreservedRegs(uint32_t kind) const noexcept { return _callConv.getPreservedRegs(kind); }
+     849             : 
+     850             :   ASMJIT_INLINE uint32_t getUsedRegs(uint32_t kind) const noexcept {
+     851             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     852        5244 :     return _usedRegs[kind];
+     853             :   }
+     854             : 
+     855             :   ASMJIT_INLINE void addUsedRegs(uint32_t kind, uint32_t regs) noexcept {
+     856             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     857        1870 :     _usedRegs[kind] |= regs;
+     858           0 :   }
+     859             : 
+     860             :   // --------------------------------------------------------------------------
+     861             :   // [Members]
+     862             :   // --------------------------------------------------------------------------
+     863             : 
+     864             :   CallConv _callConv;                    //!< Calling convention.
+     865             :   uint8_t _argCount;                     //!< Number of function arguments.
+     866             :   uint8_t _retCount;                     //!< Number of function return values.
+     867             :   uint32_t _usedRegs[kMaxVRegKinds];     //!< Registers that contains arguments (signature dependent).
+     868             :   uint32_t _argStackSize;                //!< Size of arguments passed by stack.
+     869             :   Value _rets[2];                        //!< Function return values.
+     870             :   Value _args[kFuncArgCountLoHi];        //!< Function arguments.
+     871             : };
+     872             : 
+     873             : // ============================================================================
+     874             : // [asmjit::FuncFrameInfo]
+     875             : // ============================================================================
+     876             : 
+     877             : //! Function-frame information.
+     878             : //!
+     879             : //! This structure can be used to create a function frame in a cross-platform
+     880             : //! way. It contains information about the function's stack to be used and
+     881             : //! registers to be saved and restored. Based on this information in can
+     882             : //! calculate the optimal layout of a function as \ref FuncFrameLayout.
+     883             : struct FuncFrameInfo {
+     884             :   ASMJIT_ENUM(Limits) {
+     885             :     kMaxVRegKinds = Globals::kMaxVRegKinds
+     886             :   };
+     887             : 
+     888             :   //! Attributes.
+     889             :   //!
+     890             :   //! Attributes are designed in a way that all are initially false, and user
+     891             :   //! or function-frame finalizer sets them when necessary. Architecture-specific
+     892             :   //! attributes are prefixed with the architecture name.
+     893             :   ASMJIT_ENUM(Attributes) {
+     894             :     kAttrPreserveFP       = 0x00000001U, //!< Preserve frame pointer (EBP|RBP).
+     895             :     kAttrCompactPE        = 0x00000002U, //!< Use smaller, but possibly slower prolog/epilog.
+     896             :     kAttrHasCalls         = 0x00000004U, //!< Function calls other functions (is not leaf).
+     897             : 
+     898             :     kX86AttrAlignedVecSR  = 0x00010000U, //!< Use aligned save/restore of VEC regs.
+     899             :     kX86AttrMmxCleanup    = 0x00020000U, //!< Emit EMMS instruction in epilog (X86).
+     900             :     kX86AttrAvxCleanup    = 0x00040000U, //!< Emit VZEROUPPER instruction in epilog (X86).
+     901             :     kX86AttrAvxEnabled    = 0x00080000U  //!< Use AVX instead of SSE for all operations (X86).
+     902             :   };
+     903             : 
+     904             :   // --------------------------------------------------------------------------
+     905             :   // [Construction / Destruction]
+     906             :   // --------------------------------------------------------------------------
+     907             : 
+     908        1948 :   ASMJIT_INLINE FuncFrameInfo() noexcept { reset(); }
+     909             : 
+     910             :   ASMJIT_INLINE FuncFrameInfo(const FuncFrameInfo& other) noexcept {
+     911             :     ::memcpy(this, &other, sizeof(*this));
+     912             :   }
+     913             : 
+     914             :   // --------------------------------------------------------------------------
+     915             :   // [Init / Reset]
+     916             :   // --------------------------------------------------------------------------
+     917             : 
+     918             :   ASMJIT_INLINE void reset() noexcept {
+     919             :     ::memset(this, 0, sizeof(*this));
+     920        1948 :     _stackArgsRegId = Globals::kInvalidRegId;
+     921             :   }
+     922             : 
+     923             :   // --------------------------------------------------------------------------
+     924             :   // [Accessors]
+     925             :   // --------------------------------------------------------------------------
+     926             : 
+     927             :   //! Get frame-info flags, see \ref Attributes.
+     928             :   ASMJIT_INLINE uint32_t getAttributes() const noexcept { return _attributes; }
+     929             :   //! Check if a frame-info `flag` is set, see \ref Attributes.
+     930             :   ASMJIT_INLINE bool hasAttribute(uint32_t attr) const noexcept { return (_attributes & attr) != 0; }
+     931             :   //! Add `flags` to the frame-info, see \ref Attributes.
+     932             :   ASMJIT_INLINE void addAttributes(uint32_t attrs) noexcept { _attributes |= attrs; }
+     933             :   //! Clear `flags` from the frame-info, see \ref Attributes.
+     934             :   ASMJIT_INLINE void clearAttributes(uint32_t attrs) noexcept { _attributes &= ~attrs; }
+     935             : 
+     936             :   //! Get if the function preserves frame pointer (EBP|ESP on X86).
+     937        5844 :   ASMJIT_INLINE bool hasPreservedFP() const noexcept { return (_attributes & kAttrPreserveFP) != 0; }
+     938             :   //! Enable preserved frame pointer.
+     939             :   ASMJIT_INLINE void enablePreservedFP() noexcept { _attributes |= kAttrPreserveFP; }
+     940             :   //! Disable preserved frame pointer.
+     941             :   ASMJIT_INLINE void disablePreservedFP() noexcept { _attributes &= ~kAttrPreserveFP; }
+     942             : 
+     943             :   //! Get if the function prolog and epilog should be compacted (as small as possible).
+     944             :   ASMJIT_INLINE bool hasCompactPE() const noexcept { return (_attributes & kAttrCompactPE) != 0; }
+     945             :   //! Enable compact prolog/epilog.
+     946             :   ASMJIT_INLINE void enableCompactPE() noexcept { _attributes |= kAttrCompactPE; }
+     947             :   //! Disable compact prolog/epilog.
+     948             :   ASMJIT_INLINE void disableCompactPE() noexcept { _attributes &= ~kAttrCompactPE; }
+     949             : 
+     950             :   //! Get if the function calls other functions.
+     951        1016 :   ASMJIT_INLINE bool hasCalls() const noexcept { return (_attributes & kAttrHasCalls) != 0; }
+     952             :   //! Set `kFlagHasCalls` to true.
+     953        1648 :   ASMJIT_INLINE void enableCalls() noexcept { _attributes |= kAttrHasCalls; }
+     954             :   //! Set `kFlagHasCalls` to false.
+     955             :   ASMJIT_INLINE void disableCalls() noexcept { _attributes &= ~kAttrHasCalls; }
+     956             : 
+     957             :   //! Get if the function contains MMX cleanup - 'emms' instruction in epilog.
+     958        1948 :   ASMJIT_INLINE bool hasMmxCleanup() const noexcept { return (_attributes & kX86AttrMmxCleanup) != 0; }
+     959             :   //! Enable MMX cleanup.
+     960             :   ASMJIT_INLINE void enableMmxCleanup() noexcept { _attributes |= kX86AttrMmxCleanup; }
+     961             :   //! Disable MMX cleanup.
+     962             :   ASMJIT_INLINE void disableMmxCleanup() noexcept { _attributes &= ~kX86AttrMmxCleanup; }
+     963             : 
+     964             :   //! Get if the function contains AVX cleanup - 'vzeroupper' instruction in epilog.
+     965        1948 :   ASMJIT_INLINE bool hasAvxCleanup() const noexcept { return (_attributes & kX86AttrAvxCleanup) != 0; }
+     966             :   //! Enable AVX cleanup.
+     967             :   ASMJIT_INLINE void enableAvxCleanup() noexcept { _attributes |= kX86AttrAvxCleanup; }
+     968             :   //! Disable AVX cleanup.
+     969             :   ASMJIT_INLINE void disableAvxCleanup() noexcept { _attributes &= ~kX86AttrAvxCleanup; }
+     970             : 
+     971             :   //! Get if the function contains AVX cleanup - 'vzeroupper' instruction in epilog.
+     972        1948 :   ASMJIT_INLINE bool isAvxEnabled() const noexcept { return (_attributes & kX86AttrAvxEnabled) != 0; }
+     973             :   //! Enable AVX cleanup.
+     974             :   ASMJIT_INLINE void enableAvx() noexcept { _attributes |= kX86AttrAvxEnabled; }
+     975             :   //! Disable AVX cleanup.
+     976             :   ASMJIT_INLINE void disableAvx() noexcept { _attributes &= ~kX86AttrAvxEnabled; }
+     977             : 
+     978             :   //! Get which registers (by `kind`) are saved/restored in prolog/epilog, respectively.
+     979             :   ASMJIT_INLINE uint32_t getDirtyRegs(uint32_t kind) const noexcept {
+     980             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     981        7792 :     return _dirtyRegs[kind];
+     982             :   }
+     983             : 
+     984             :   //! Set which registers (by `kind`) are saved/restored in prolog/epilog, respectively.
+     985             :   ASMJIT_INLINE void setDirtyRegs(uint32_t kind, uint32_t regs) noexcept {
+     986             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     987        1948 :     _dirtyRegs[kind] = regs;
+     988             :   }
+     989             : 
+     990             :   //! Add registers (by `kind`) to saved/restored registers.
+     991             :   ASMJIT_INLINE void addDirtyRegs(uint32_t kind, uint32_t regs) noexcept {
+     992             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+     993           0 :     _dirtyRegs[kind] |= regs;
+     994           0 :   }
+     995             : 
+     996             :   ASMJIT_INLINE void setAllDirty() noexcept {
+     997             :     _dirtyRegs[0] = 0xFFFFFFFFU;
+     998             :     _dirtyRegs[1] = 0xFFFFFFFFU;
+     999             :     _dirtyRegs[2] = 0xFFFFFFFFU;
+    1000             :     _dirtyRegs[3] = 0xFFFFFFFFU;
+    1001             :   }
+    1002             : 
+    1003             :   ASMJIT_INLINE void setAllDirty(uint32_t kind) noexcept {
+    1004             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+    1005             :     _dirtyRegs[kind] = 0xFFFFFFFFU;
+    1006             :   }
+    1007             : 
+    1008             :   //! Get stack-frame size used by the function.
+    1009             :   ASMJIT_INLINE uint32_t getStackFrameSize() const noexcept { return _stackFrameSize; }
+    1010             :   //! Get call-frame size used by the function.
+    1011             :   ASMJIT_INLINE uint32_t getCallFrameSize() const noexcept { return _callFrameSize; }
+    1012             : 
+    1013             :   //! Get minimum stack-frame alignment required by the function.
+    1014        1948 :   ASMJIT_INLINE uint32_t getStackFrameAlignment() const noexcept { return _stackFrameAlignment; }
+    1015             :   //! Get minimum call-frame alignment required by the function.
+    1016        1948 :   ASMJIT_INLINE uint32_t getCallFrameAlignment() const noexcept { return _callFrameAlignment; }
+    1017             : 
+    1018        1948 :   ASMJIT_INLINE void setStackFrameSize(uint32_t size) noexcept { _stackFrameSize = size; }
+    1019             :   ASMJIT_INLINE void setCallFrameSize(uint32_t size) noexcept { _callFrameSize = size; }
+    1020             : 
+    1021             :   ASMJIT_INLINE void setStackFrameAlignment(uint32_t value) noexcept {
+    1022             :     ASMJIT_ASSERT(value < 256);
+    1023        1948 :     _stackFrameAlignment = static_cast<uint8_t>(value);
+    1024             :   }
+    1025             : 
+    1026             :   ASMJIT_INLINE void setCallFrameAlignment(uint32_t value) noexcept {
+    1027             :     ASMJIT_ASSERT(value < 256);
+    1028             :     _callFrameAlignment = static_cast<uint8_t>(value);
+    1029             :   }
+    1030             : 
+    1031             :   ASMJIT_INLINE void mergeStackFrameSize(uint32_t size) noexcept { _stackFrameSize = std::max<uint32_t>(_stackFrameSize, size); }
+    1032        1648 :   ASMJIT_INLINE void mergeCallFrameSize(uint32_t size) noexcept { _callFrameSize = std::max<uint32_t>(_callFrameSize, size); }
+    1033             : 
+    1034             :   ASMJIT_INLINE void mergeStackFrameAlignment(uint32_t value) noexcept {
+    1035             :     ASMJIT_ASSERT(value < 256);
+    1036             :     _stackFrameAlignment = static_cast<uint8_t>(std::max<uint32_t>(_stackFrameAlignment, value));
+    1037             :   }
+    1038             : 
+    1039             :   ASMJIT_INLINE void mergeCallFrameAlignment(uint32_t value) noexcept {
+    1040             :     ASMJIT_ASSERT(value < 256);
+    1041             :     _callFrameAlignment = static_cast<uint8_t>(std::max<uint32_t>(_callFrameAlignment, value));
+    1042             :   }
+    1043             : 
+    1044             :   ASMJIT_INLINE bool hasStackArgsRegId() const noexcept {
+    1045             :     return _stackArgsRegId != Globals::kInvalidRegId;
+    1046             :   }
+    1047        1948 :   ASMJIT_INLINE uint32_t getStackArgsRegId() const noexcept { return _stackArgsRegId; }
+    1048        1948 :   ASMJIT_INLINE void setStackArgsRegId(uint32_t regId) { _stackArgsRegId = regId; }
+    1049             : 
+    1050             :   // --------------------------------------------------------------------------
+    1051             :   // [Members]
+    1052             :   // --------------------------------------------------------------------------
+    1053             : 
+    1054             :   uint32_t _attributes;                  //!< Function attributes.
+    1055             :   uint32_t _dirtyRegs[kMaxVRegKinds];    //!< Registers used by the function.
+    1056             : 
+    1057             :   uint8_t _stackFrameAlignment;          //!< Minimum alignment of stack-frame.
+    1058             :   uint8_t _callFrameAlignment;           //!< Minimum alignment of call-frame.
+    1059             :   uint8_t _stackArgsRegId;               //!< Register that holds base-address to arguments passed by stack.
+    1060             : 
+    1061             :   uint32_t _stackFrameSize;              //!< Size of a stack-frame used by the function.
+    1062             :   uint32_t _callFrameSize;               //!< Size of a call-frame (not part of _stackFrameSize).
+    1063             : };
+    1064             : 
+    1065             : // ============================================================================
+    1066             : // [asmjit::FuncFrameLayout]
+    1067             : // ============================================================================
+    1068             : 
+    1069             : //! Function-frame layout.
+    1070             : //!
+    1071             : //! Function layout is used directly by prolog and epilog insertion helpers. It
+    1072             : //! contains only information necessary to insert proper prolog and epilog, and
+    1073             : //! should be always calculated from \ref FuncDetail and \ref FuncFrameInfo, where
+    1074             : //! \ref FuncDetail defines function's calling convention and signature, and \ref
+    1075             : //! FuncFrameInfo specifies how much stack is used, and which registers are dirty.
+    1076             : struct FuncFrameLayout {
+    1077             :   ASMJIT_ENUM(Limits) {
+    1078             :     kMaxVRegKinds = Globals::kMaxVRegKinds
+    1079             :   };
+    1080             : 
+    1081             :   // --------------------------------------------------------------------------
+    1082             :   // [Init / Reset]
+    1083             :   // --------------------------------------------------------------------------
+    1084             : 
+    1085             :   ASMJIT_API Error init(const FuncDetail& func, const FuncFrameInfo& ffi) noexcept;
+    1086             :   ASMJIT_INLINE void reset() noexcept { ::memset(this, 0, sizeof(*this)); }
+    1087             : 
+    1088             :   // --------------------------------------------------------------------------
+    1089             :   // [Accessors]
+    1090             :   // --------------------------------------------------------------------------
+    1091             : 
+    1092        7792 :   ASMJIT_INLINE bool hasPreservedFP() const noexcept { return static_cast<bool>(_preservedFP); }
+    1093           0 :   ASMJIT_INLINE bool hasDsaSlotUsed() const noexcept { return static_cast<bool>(_dsaSlotUsed); }
+    1094           0 :   ASMJIT_INLINE bool hasAlignedVecSR() const noexcept { return static_cast<bool>(_alignedVecSR); }
+    1095        5844 :   ASMJIT_INLINE bool hasDynamicAlignment() const noexcept { return static_cast<bool>(_dynamicAlignment); }
+    1096             : 
+    1097        1948 :   ASMJIT_INLINE bool hasMmxCleanup() const noexcept { return static_cast<bool>(_mmxCleanup); }
+    1098        1948 :   ASMJIT_INLINE bool hasAvxCleanup() const noexcept { return static_cast<bool>(_avxCleanup); }
+    1099           0 :   ASMJIT_INLINE bool isAvxEnabled() const noexcept { return static_cast<bool>(_avxEnabled); }
+    1100             : 
+    1101             :   ASMJIT_INLINE uint32_t getSavedRegs(uint32_t kind) const noexcept {
+    1102             :     ASMJIT_ASSERT(kind < kMaxVRegKinds);
+    1103        7792 :     return _savedRegs[kind];
+    1104             :   }
+    1105             : 
+    1106             :   //! Get stack size.
+    1107             :   ASMJIT_INLINE uint32_t getStackSize() const noexcept { return _stackSize; }
+    1108             :   //! Get stack alignment.
+    1109           0 :   ASMJIT_INLINE uint32_t getStackAlignment() const noexcept { return _stackAlignment; }
+    1110             :   //! Get the offset needed to access the function's stack (it skips call-stack).
+    1111             :   ASMJIT_INLINE uint32_t getStackBaseOffset() const noexcept { return _stackBaseOffset; }
+    1112             : 
+    1113             :   //! Get stack size required to save GP registers.
+    1114           0 :   ASMJIT_INLINE uint32_t getGpStackSize() const noexcept { return _gpStackSize; }
+    1115             :   //! Get stack size required to save VEC registers.
+    1116             :   ASMJIT_INLINE uint32_t getVecStackSize() const noexcept { return _vecStackSize; }
+    1117             : 
+    1118             :   ASMJIT_INLINE uint32_t getGpStackOffset() const noexcept { return _gpStackOffset; }
+    1119           0 :   ASMJIT_INLINE uint32_t getVecStackOffset() const noexcept { return _vecStackOffset; }
+    1120             : 
+    1121        1948 :   ASMJIT_INLINE uint32_t getStackArgsRegId() const noexcept { return _stackArgsRegId; }
+    1122           0 :   ASMJIT_INLINE uint32_t getStackArgsOffset() const noexcept { return _stackArgsOffset; }
+    1123             : 
+    1124        3896 :   ASMJIT_INLINE bool hasStackAdjustment() const noexcept { return _stackAdjustment != 0; }
+    1125             :   ASMJIT_INLINE uint32_t getStackAdjustment() const noexcept { return _stackAdjustment; }
+    1126             : 
+    1127        1948 :   ASMJIT_INLINE bool hasCalleeStackCleanup() const noexcept { return _calleeStackCleanup != 0; }
+    1128             :   ASMJIT_INLINE uint32_t getCalleeStackCleanup() const noexcept { return _calleeStackCleanup; }
+    1129             : 
+    1130             :   // --------------------------------------------------------------------------
+    1131             :   // [Members]
+    1132             :   // --------------------------------------------------------------------------
+    1133             : 
+    1134             :   uint8_t _stackAlignment;               //!< Final stack alignment of the functions.
+    1135             :   uint8_t _stackBaseRegId;               //!< GP register that holds address of base stack address.
+    1136             :   uint8_t _stackArgsRegId;               //!< GP register that holds address of the first argument passed by stack.
+    1137             : 
+    1138             :   uint32_t _savedRegs[kMaxVRegKinds];    //!< Registers that will be saved/restored in prolog/epilog.
+    1139             : 
+    1140             :   uint32_t _preservedFP : 1;             //!< Function preserves frame-pointer.
+    1141             :   uint32_t _dsaSlotUsed : 1;             //!< True if `_dsaSlot` contains a valid memory slot/offset.
+    1142             :   uint32_t _alignedVecSR : 1;            //!< Use instructions that perform aligned ops to save/restore XMM regs.
+    1143             :   uint32_t _dynamicAlignment : 1;        //!< Function must dynamically align the stack.
+    1144             : 
+    1145             :   uint32_t _mmxCleanup : 1;              //!< Emit 'emms' in epilog (X86).
+    1146             :   uint32_t _avxCleanup : 1;              //!< Emit 'vzeroupper' in epilog (X86).
+    1147             :   uint32_t _avxEnabled : 1;              //!< Use AVX instead of SSE for SIMD saves/restores (X86).
+    1148             : 
+    1149             :   uint32_t _stackSize;                   //!< Stack size (sum of function's stack and call stack).
+    1150             :   uint32_t _stackBaseOffset;             //!< Stack offset (non-zero if kFlagHasCalls is set).
+    1151             :   uint32_t _stackAdjustment;             //!< Stack adjustment in prolog/epilog.
+    1152             :   uint32_t _stackArgsOffset;             //!< Offset to the first argument passed by stack of _stackArgsRegId.
+    1153             : 
+    1154             :   uint32_t _dsaSlot;                     //!< Memory slot where the prolog inserter stores previous (unaligned) ESP.
+    1155             :   uint16_t _calleeStackCleanup;          //!< How many bytes the callee should add to the stack (X86 STDCALL).
+    1156             :   uint16_t _gpStackSize;                 //!< Stack size required to save GP regs.
+    1157             :   uint16_t _vecStackSize;                //!< Stack size required to save VEC regs.
+    1158             :   uint32_t _gpStackOffset;               //!< Offset where saved GP regs are stored.
+    1159             :   uint32_t _vecStackOffset;              //!< Offset where saved GP regs are stored.
+    1160             : };
+    1161             : 
+    1162             : // ============================================================================
+    1163             : // [asmjit::FuncArgsMapper]
+    1164             : // ============================================================================
+    1165             : 
+    1166             : //! Assign a physical register to each function argument.
+    1167             : //!
+    1168             : //! This is used to specify where each function argument should be shuffled
+    1169             : //! or allocated (in case it's passed by stack).
+    1170             : class FuncArgsMapper {
+    1171             : public:
+    1172             :   struct Value {
+    1173             :     // NOTE: The layout is compatible with FuncDetail::Value except stack.
+    1174             :     ASMJIT_ENUM(Parts) {
+    1175             :       kTypeIdShift      = 24,
+    1176             :       kTypeIdMask       = 0xFF000000U,
+    1177             : 
+    1178             :       kRegTypeShift     = 8,
+    1179             :       kRegTypeMask      = 0x0000FF00U,
+    1180             : 
+    1181             :       kRegIdShift       = 0,
+    1182             :       kRegIdMask        = 0x000000FFU,
+    1183             : 
+    1184             :       kIsAssigned       = 0x00010000U
+    1185             :     };
+    1186             : 
+    1187             :     //! Get if this value is initialized (i.e. contains a valid data).
+    1188           0 :     ASMJIT_INLINE bool isAssigned() const noexcept { return _value != 0; }
+    1189             :     //! Initialize this in/out by a given `typeId`, `regType`, and `regId`.
+    1190             :     ASMJIT_INLINE void assign(uint32_t typeId, uint32_t regType, uint32_t regId) noexcept {
+    1191             :       _value = (typeId << kTypeIdShift) | (regType << kRegTypeShift) | (regId << kRegIdShift) | kIsAssigned;
+    1192             :     }
+    1193             :     //! Reset the value to its unassigned state.
+    1194             :     ASMJIT_INLINE void reset() noexcept { _value = 0; }
+    1195             : 
+    1196             :     //! Get virtual type of this argument or return value.
+    1197           0 :     ASMJIT_INLINE uint32_t getTypeId() const noexcept { return _value >> kTypeIdShift; }
+    1198             :     //! Get a register type of the register used to pass the argument or return the value.
+    1199           0 :     ASMJIT_INLINE uint32_t getRegType() const noexcept { return (_value & kRegTypeMask) >> kRegTypeShift; }
+    1200             :     //! Get a physical id of the register used to pass the argument or return the value.
+    1201           0 :     ASMJIT_INLINE uint32_t getRegId() const noexcept { return (_value & kRegIdMask) >> kRegIdShift; }
+    1202             : 
+    1203             :     uint32_t _value;
+    1204             :   };
+    1205             : 
+    1206             :   // --------------------------------------------------------------------------
+    1207             :   // [Construction / Destruction]
+    1208             :   // --------------------------------------------------------------------------
+    1209             : 
+    1210             :   explicit ASMJIT_INLINE FuncArgsMapper(const FuncDetail* fd) noexcept { reset(fd); }
+    1211             :   ASMJIT_INLINE FuncArgsMapper(const FuncArgsMapper& other) noexcept {
+    1212             :     ::memcpy(this, &other, sizeof(*this));
+    1213             :   }
+    1214             : 
+    1215             :   // --------------------------------------------------------------------------
+    1216             :   // [Reset]
+    1217             :   // --------------------------------------------------------------------------
+    1218             : 
+    1219             :   ASMJIT_INLINE void reset(const FuncDetail* fd = nullptr) noexcept {
+    1220             :     _funcDetail = fd;
+    1221             :     ::memset(_args, 0, sizeof(_args));
+    1222             :   }
+    1223             : 
+    1224             :   // --------------------------------------------------------------------------
+    1225             :   // [Accessors]
+    1226             :   // --------------------------------------------------------------------------
+    1227             : 
+    1228           0 :   ASMJIT_INLINE const FuncDetail* getFuncDetail() const noexcept { return _funcDetail; }
+    1229             :   ASMJIT_INLINE void setFuncDetail(const FuncDetail* fd) noexcept { _funcDetail = fd; }
+    1230             : 
+    1231             :   ASMJIT_INLINE Value& getArg(size_t index) noexcept {
+    1232             :     ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_args));
+    1233             :     return _args[index];
+    1234             :   }
+    1235             :   ASMJIT_INLINE const Value& getArg(size_t index) const noexcept {
+    1236             :     ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_args));
+    1237             :     return _args[index];
+    1238             :   }
+    1239             : 
+    1240             :   ASMJIT_INLINE bool isAssigned(size_t index) const noexcept {
+    1241             :     ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_args));
+    1242             :     return _args[index].isAssigned();
+    1243             :   }
+    1244             : 
+    1245             :   ASMJIT_INLINE void assign(size_t index, const Reg& reg, uint32_t typeId = TypeId::kVoid) noexcept {
+    1246             :     // Not designed for virtual registers.
+    1247             :     ASMJIT_ASSERT(index < ASMJIT_ARRAY_SIZE(_args));
+    1248             :     ASMJIT_ASSERT(reg.isPhysReg());
+    1249             : 
+    1250             :     _args[index].assign(typeId, reg.getType(), reg.getId());
+    1251             :   }
+    1252             : 
+    1253             :   // NOTE: All `assignAll()` methods are shortcuts to assign all arguments at
+    1254             :   // once, however, since registers are passed all at once these initializers
+    1255             :   // don't provide any way to pass TypeId and/or to keep any argument between
+    1256             :   // the arguments passed uninitialized.
+    1257             :   ASMJIT_INLINE void assignAll(const Reg& a0) noexcept {
+    1258             :     assign(0, a0);
+    1259             :   }
+    1260             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1) noexcept {
+    1261             :     assign(0, a0); assign(1, a1);
+    1262             :   }
+    1263             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2) noexcept {
+    1264             :     assign(0, a0); assign(1, a1); assign(2, a2);
+    1265             :   }
+    1266             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2, const Reg& a3) noexcept {
+    1267             :     assign(0, a0); assign(1, a1); assign(2, a2); assign(3, a3);
+    1268             :   }
+    1269             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2, const Reg& a3, const Reg& a4) noexcept {
+    1270             :     assign(0, a0); assign(1, a1); assign(2, a2); assign(3, a3);
+    1271             :     assign(4, a4);
+    1272             :   }
+    1273             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2, const Reg& a3, const Reg& a4, const Reg& a5) noexcept {
+    1274             :     assign(0, a0); assign(1, a1); assign(2, a2); assign(3, a3);
+    1275             :     assign(4, a4); assign(5, a5);
+    1276             :   }
+    1277             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2, const Reg& a3, const Reg& a4, const Reg& a5, const Reg& a6) noexcept {
+    1278             :     assign(0, a0); assign(1, a1); assign(2, a2); assign(3, a3);
+    1279             :     assign(4, a4); assign(5, a5); assign(6, a6);
+    1280             :   }
+    1281             :   ASMJIT_INLINE void assignAll(const Reg& a0, const Reg& a1, const Reg& a2, const Reg& a3, const Reg& a4, const Reg& a5, const Reg& a6, const Reg& a7) noexcept {
+    1282             :     assign(0, a0); assign(1, a1); assign(2, a2); assign(3, a3);
+    1283             :     assign(4, a4); assign(5, a5); assign(6, a6); assign(7, a7);
+    1284             :   }
+    1285             : 
+    1286             :   // --------------------------------------------------------------------------
+    1287             :   // [Utilities]
+    1288             :   // --------------------------------------------------------------------------
+    1289             : 
+    1290             :   //! Update `FuncFrameInfo` accordingly to FuncArgsMapper.
+    1291             :   //!
+    1292             :   //! This method must be called if you use `FuncArgsMapper` and you plan to
+    1293             :   //! use `FuncUtils::allocArgs()` to remap all arguments after the prolog is
+    1294             :   //! inserted.
+    1295             :   ASMJIT_API Error updateFrameInfo(FuncFrameInfo& ffi) const noexcept;
+    1296             : 
+    1297             :   // --------------------------------------------------------------------------
+    1298             :   // [Members]
+    1299             :   // --------------------------------------------------------------------------
+    1300             : 
+    1301             :   const FuncDetail* _funcDetail;         //!< Function detail.
+    1302             :   Value _args[kFuncArgCountLoHi];        //!< Mapping of each function argument.
+    1303             : };
+    1304             : 
+    1305             : // ============================================================================
+    1306             : // [asmjit::FuncUtils]
+    1307             : // ============================================================================
+    1308             : 
+    1309             : struct FuncUtils {
+    1310             :   ASMJIT_API static Error emitProlog(CodeEmitter* emitter, const FuncFrameLayout& layout);
+    1311             :   ASMJIT_API static Error emitEpilog(CodeEmitter* emitter, const FuncFrameLayout& layout);
+    1312             :   ASMJIT_API static Error allocArgs(CodeEmitter* emitter, const FuncFrameLayout& layout, const FuncArgsMapper& args);
+    1313             : };
+    1314             : 
+    1315             : //! \}
+    1316             : 
+    1317             : } // asmjit namespace
+    1318             : } // namespace PLMD
+    1319             : 
+    1320             : // [Api-End]
+    1321             : #include "./asmjit_apiend.h"
+    1322             : 
+    1323             : // [Guard]
+    1324             : #endif // _ASMJIT_BASE_FUNC_H
+    1325             : #pragma GCC diagnostic pop
+    1326             : #endif // __PLUMED_HAS_ASMJIT
+    1327             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.cpp.func-sort-c.html b/coverage-libs/asmjit/globals.cpp.func-sort-c.html new file mode 100644 index 000000000000..0195a151125e --- /dev/null +++ b/coverage-libs/asmjit/globals.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:090.0 %
Date:2024-02-22 21:58:47Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10DebugUtils11debugOutputEPKc0
_ZN4PLMD6asmjit10DebugUtils13errorAsStringEj0
_ZN4PLMD6asmjit10DebugUtils15assertionFailedEPKciS3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.cpp.func.html b/coverage-libs/asmjit/globals.cpp.func.html new file mode 100644 index 000000000000..103c8f6b1580 --- /dev/null +++ b/coverage-libs/asmjit/globals.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:090.0 %
Date:2024-02-22 21:58:47Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10DebugUtils11debugOutputEPKc0
_ZN4PLMD6asmjit10DebugUtils13errorAsStringEj0
_ZN4PLMD6asmjit10DebugUtils15assertionFailedEPKciS3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.cpp.gcov.html b/coverage-libs/asmjit/globals.cpp.gcov.html new file mode 100644 index 000000000000..37fd5674e6d2 --- /dev/null +++ b/coverage-libs/asmjit/globals.cpp.gcov.html @@ -0,0 +1,221 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:090.0 %
Date:2024-02-22 21:58:47Functions:030.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./globals.h"
+      34             : #include "./utils.h"
+      35             : 
+      36             : // [Api-Begin]
+      37             : #include "./asmjit_apibegin.h"
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace asmjit {
+      41             : 
+      42             : // ============================================================================
+      43             : // [asmjit::DebugUtils]
+      44             : // ============================================================================
+      45             : 
+      46             : #if !defined(ASMJIT_DISABLE_TEXT)
+      47             : static const char errorMessages[] =
+      48             :   "Ok\0"
+      49             :   "No heap memory\0"
+      50             :   "No virtual memory\0"
+      51             :   "Invalid argument\0"
+      52             :   "Invalid state\0"
+      53             :   "Invalid architecture\0"
+      54             :   "Not initialized\0"
+      55             :   "Already initialized\0"
+      56             :   "Feature not enabled\0"
+      57             :   "Slot occupied\0"
+      58             :   "No code generated\0"
+      59             :   "Code too large\0"
+      60             :   "Invalid label\0"
+      61             :   "Label index overflow\0"
+      62             :   "Label already bound\0"
+      63             :   "Label already defined\0"
+      64             :   "Label name too long\0"
+      65             :   "Invalid label name\0"
+      66             :   "Invalid parent label\0"
+      67             :   "Non-local label can't have parent\0"
+      68             :   "Relocation index overflow\0"
+      69             :   "Invalid relocation entry\0"
+      70             :   "Invalid instruction\0"
+      71             :   "Invalid register type\0"
+      72             :   "Invalid register kind\0"
+      73             :   "Invalid register's physical id\0"
+      74             :   "Invalid register's virtual id\0"
+      75             :   "Invalid prefix combination\0"
+      76             :   "Invalid lock prefix\0"
+      77             :   "Invalid xacquire prefix\0"
+      78             :   "Invalid xrelease prefix\0"
+      79             :   "Invalid rep prefix\0"
+      80             :   "Invalid rex prefix\0"
+      81             :   "Invalid mask, expected {k}\0"
+      82             :   "Invalid use of {k}\0"
+      83             :   "Invalid use of {k}{z}\0"
+      84             :   "Invalid broadcast {1tox}\0"
+      85             :   "Invalid {er} or {sae} option\0"
+      86             :   "Invalid address\0"
+      87             :   "Invalid address index\0"
+      88             :   "Invalid address scale\0"
+      89             :   "Invalid use of 64-bit address\0"
+      90             :   "Invalid displacement\0"
+      91             :   "Invalid segment\0"
+      92             :   "Invalid immediate value\0"
+      93             :   "Invalid operand size\0"
+      94             :   "Ambiguous operand size\0"
+      95             :   "Operand size mismatch\0"
+      96             :   "Invalid type-info\0"
+      97             :   "Invalid use of a low 8-bit GPB register\0"
+      98             :   "Invalid use of a 64-bit GPQ register in 32-bit mode\0"
+      99             :   "Invalid use of an 80-bit float\0"
+     100             :   "Not consecutive registers\0"
+     101             :   "No more physical registers\0"
+     102             :   "Overlapped registers\0"
+     103             :   "Overlapping register and arguments base-address register\0"
+     104             :   "Unknown error\0";
+     105             : #endif // ASMJIT_DISABLE_TEXT
+     106             : 
+     107           0 : ASMJIT_FAVOR_SIZE const char* DebugUtils::errorAsString(Error err) noexcept {
+     108             : #if !defined(ASMJIT_DISABLE_TEXT)
+     109           0 :   return Utils::findPackedString(errorMessages, std::min<Error>(err, kErrorCount));
+     110             : #else
+     111             :   static const char noMessage[] = "";
+     112             :   return noMessage;
+     113             : #endif
+     114             : }
+     115             : 
+     116           0 : ASMJIT_FAVOR_SIZE void DebugUtils::debugOutput(const char* str) noexcept {
+     117             : #if ASMJIT_OS_WINDOWS
+     118             :   ::OutputDebugStringA(str);
+     119             : #else
+     120           0 :   ::fputs(str, stderr);
+     121             : #endif
+     122           0 : }
+     123             : 
+     124           0 : ASMJIT_FAVOR_SIZE void DebugUtils::assertionFailed(const char* file, int line, const char* msg) noexcept {
+     125             :   char str[1024];
+     126             : 
+     127             :   snprintf(str, 1024,
+     128             :     "[asmjit] Assertion failed at %s (line %d):\n"
+     129             :     "[asmjit] %s\n", file, line, msg);
+     130             : 
+     131             :   // Support buggy `snprintf` implementations.
+     132           0 :   str[1023] = '\0';
+     133             : 
+     134           0 :   debugOutput(str);
+     135           0 :   ::abort();
+     136             : }
+     137             : 
+     138             : } // asmjit namespace
+     139             : } // namespace PLMD
+     140             : 
+     141             : // [Api-End]
+     142             : #include "./asmjit_apiend.h"
+     143             : #pragma GCC diagnostic pop
+     144             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.h.func-sort-c.html b/coverage-libs/asmjit/globals.h.func-sort-c.html new file mode 100644 index 000000000000..03d899890d01 --- /dev/null +++ b/coverage-libs/asmjit/globals.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2366.7 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.h.func.html b/coverage-libs/asmjit/globals.h.func.html new file mode 100644 index 000000000000..9bd47894378c --- /dev/null +++ b/coverage-libs/asmjit/globals.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2366.7 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/globals.h.gcov.html b/coverage-libs/asmjit/globals.h.gcov.html new file mode 100644 index 000000000000..507ab9cd7e26 --- /dev/null +++ b/coverage-libs/asmjit/globals.h.gcov.html @@ -0,0 +1,447 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/globals.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - globals.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2366.7 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_globals_h
+      21             : #define __PLUMED_asmjit_globals_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_GLOBALS_H
+      33             : #define _ASMJIT_BASE_GLOBALS_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./asmjit_build.h"
+      37             : 
+      38             : // [Api-Begin]
+      39             : #include "./asmjit_apibegin.h"
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace asmjit {
+      43             : 
+      44             : //! \addtogroup asmjit_base
+      45             : //! \{
+      46             : 
+      47             : // ============================================================================
+      48             : // [asmjit::Globals]
+      49             : // ============================================================================
+      50             : 
+      51             : enum { kInvalidValue = 0xFFFFFFFFU };
+      52             : 
+      53             : //! AsmJit globals.
+      54             : namespace Globals {
+      55             : 
+      56             : //! Invalid index
+      57             : //!
+      58             : //! Invalid index is the last possible index that is never used in practice. In
+      59             : //! AsmJit it is used exclusively with strings to indicate the the length of the
+      60             : //! string is not known and has to be determined.
+      61             : static const size_t kInvalidIndex = ~static_cast<size_t>(0);
+      62             : 
+      63             : //! Invalid base address.
+      64             : static const uint64_t kNoBaseAddress = ~static_cast<uint64_t>(0);
+      65             : 
+      66             : //! Global definitions.
+      67             : ASMJIT_ENUM(Defs) {
+      68             :   //! Invalid register id.
+      69             :   kInvalidRegId = 0xFF,
+      70             : 
+      71             :   //! Host memory allocator overhead.
+      72             :   kAllocOverhead = static_cast<int>(sizeof(intptr_t) * 4),
+      73             :   //! Aggressive growing strategy threshold.
+      74             :   kAllocThreshold = 8192 * 1024
+      75             : };
+      76             : 
+      77             : ASMJIT_ENUM(Limits) {
+      78             :   //! Count of register kinds that are important to Function API and CodeCompiler.
+      79             :   //! The target architecture can define more register kinds for special registers,
+      80             :   //! but these will never map to virtual registers and will never be used to pass
+      81             :   //! and return function arguments and function return values, respectively.
+      82             :   kMaxVRegKinds = 4,
+      83             : 
+      84             :   //! Maximum number of physical registers of all kinds of all supported
+      85             :   //! architectures. This is only important for \ref CodeCompiler and its
+      86             :   //! \ref RAPass (register allocator pass).
+      87             :   //!
+      88             :   //! NOTE: The distribution of these registers is architecture specific.
+      89             :   kMaxPhysRegs = 64,
+      90             : 
+      91             :   //! Maximum alignment.
+      92             :   kMaxAlignment = 64,
+      93             : 
+      94             :   //! Maximum label or symbol length in bytes (take into consideration that a
+      95             :   //! single UTF-8 character can take more than single byte to encode it).
+      96             :   kMaxLabelLength = 2048
+      97             : };
+      98             : 
+      99             : } // Globals namespace
+     100             : 
+     101             : // ============================================================================
+     102             : // [asmjit::Error]
+     103             : // ============================================================================
+     104             : 
+     105             : //! AsmJit error type (uint32_t).
+     106             : typedef uint32_t Error;
+     107             : 
+     108             : //! AsmJit error codes.
+     109             : ASMJIT_ENUM(ErrorCode) {
+     110             :   //! No error (success).
+     111             :   //!
+     112             :   //! This is default state and state you want.
+     113             :   kErrorOk = 0,
+     114             : 
+     115             :   //! Heap memory allocation failed.
+     116             :   kErrorNoHeapMemory,
+     117             : 
+     118             :   //! Virtual memory allocation failed.
+     119             :   kErrorNoVirtualMemory,
+     120             : 
+     121             :   //! Invalid argument.
+     122             :   kErrorInvalidArgument,
+     123             : 
+     124             :   //! Invalid state.
+     125             :   //!
+     126             :   //! If this error is returned it means that either you are doing something
+     127             :   //! wrong or AsmJit caught itself by doing something wrong. This error should
+     128             :   //! not be underestimated.
+     129             :   kErrorInvalidState,
+     130             : 
+     131             :   //! Invalid or incompatible architecture.
+     132             :   kErrorInvalidArch,
+     133             : 
+     134             :   //! The object is not initialized.
+     135             :   kErrorNotInitialized,
+     136             :   //! The object is already initialized.
+     137             :   kErrorAlreadyInitialized,
+     138             : 
+     139             :   //! Built-in feature was disabled at compile time and it's not available.
+     140             :   kErrorFeatureNotEnabled,
+     141             : 
+     142             :   //! CodeHolder can't have attached more than one \ref Assembler at a time.
+     143             :   kErrorSlotOccupied,
+     144             : 
+     145             :   //! No code generated.
+     146             :   //!
+     147             :   //! Returned by runtime if the \ref CodeHolder contains no code.
+     148             :   kErrorNoCodeGenerated,
+     149             :   //! Code generated is larger than allowed.
+     150             :   kErrorCodeTooLarge,
+     151             : 
+     152             :   //! Attempt to use uninitialized label.
+     153             :   kErrorInvalidLabel,
+     154             :   //! Label index overflow - a single `Assembler` instance can hold more than
+     155             :   //! 2 billion labels (2147483391 to be exact). If there is an attempt to
+     156             :   //! create more labels this error is returned.
+     157             :   kErrorLabelIndexOverflow,
+     158             :   //! Label is already bound.
+     159             :   kErrorLabelAlreadyBound,
+     160             :   //! Label is already defined (named labels).
+     161             :   kErrorLabelAlreadyDefined,
+     162             :   //! Label name is too long.
+     163             :   kErrorLabelNameTooLong,
+     164             :   //! Label must always be local if it's anonymous (without a name).
+     165             :   kErrorInvalidLabelName,
+     166             :   //! Parent id passed to `CodeHolder::newNamedLabelId()` was invalid.
+     167             :   kErrorInvalidParentLabel,
+     168             :   //! Parent id specified for a non-local (global) label.
+     169             :   kErrorNonLocalLabelCantHaveParent,
+     170             : 
+     171             :   //! Relocation index overflow.
+     172             :   kErrorRelocIndexOverflow,
+     173             :   //! Invalid relocation entry.
+     174             :   kErrorInvalidRelocEntry,
+     175             : 
+     176             :   //! Invalid instruction.
+     177             :   kErrorInvalidInstruction,
+     178             :   //! Invalid register type.
+     179             :   kErrorInvalidRegType,
+     180             :   //! Invalid register kind.
+     181             :   kErrorInvalidRegKind,
+     182             :   //! Invalid register's physical id.
+     183             :   kErrorInvalidPhysId,
+     184             :   //! Invalid register's virtual id.
+     185             :   kErrorInvalidVirtId,
+     186             :   //! Invalid prefix combination.
+     187             :   kErrorInvalidPrefixCombination,
+     188             :   //! Invalid LOCK prefix.
+     189             :   kErrorInvalidLockPrefix,
+     190             :   //! Invalid XACQUIRE prefix.
+     191             :   kErrorInvalidXAcquirePrefix,
+     192             :   //! Invalid XACQUIRE prefix.
+     193             :   kErrorInvalidXReleasePrefix,
+     194             :   //! Invalid REP prefix.
+     195             :   kErrorInvalidRepPrefix,
+     196             :   //! Invalid REX prefix.
+     197             :   kErrorInvalidRexPrefix,
+     198             :   //! Invalid mask register (not 'k').
+     199             :   kErrorInvalidKMaskReg,
+     200             :   //! Invalid {k} use (not supported by the instruction).
+     201             :   kErrorInvalidKMaskUse,
+     202             :   //! Invalid {k}{z} use (not supported by the instruction).
+     203             :   kErrorInvalidKZeroUse,
+     204             :   //! Invalid broadcast - Currently only related to invalid use of AVX-512 {1tox}.
+     205             :   kErrorInvalidBroadcast,
+     206             :   //! Invalid 'embedded-rounding' {er} or 'suppress-all-exceptions' {sae} (AVX-512).
+     207             :   kErrorInvalidEROrSAE,
+     208             :   //! Invalid address used (not encodable).
+     209             :   kErrorInvalidAddress,
+     210             :   //! Invalid index register used in memory address (not encodable).
+     211             :   kErrorInvalidAddressIndex,
+     212             :   //! Invalid address scale (not encodable).
+     213             :   kErrorInvalidAddressScale,
+     214             :   //! Invalid use of 64-bit address.
+     215             :   kErrorInvalidAddress64Bit,
+     216             :   //! Invalid displacement (not encodable).
+     217             :   kErrorInvalidDisplacement,
+     218             :   //! Invalid segment (X86).
+     219             :   kErrorInvalidSegment,
+     220             : 
+     221             :   //! Invalid immediate (out of bounds on X86 and invalid pattern on ARM).
+     222             :   kErrorInvalidImmediate,
+     223             : 
+     224             :   //! Invalid operand size.
+     225             :   kErrorInvalidOperandSize,
+     226             :   //! Ambiguous operand size (memory has zero size while it's required to determine the operation type.
+     227             :   kErrorAmbiguousOperandSize,
+     228             :   //! Mismatching operand size (size of multiple operands doesn't match the operation size).
+     229             :   kErrorOperandSizeMismatch,
+     230             : 
+     231             :   //! Invalid TypeId.
+     232             :   kErrorInvalidTypeId,
+     233             :   //! Invalid use of a 8-bit GPB-HIGH register.
+     234             :   kErrorInvalidUseOfGpbHi,
+     235             :   //! Invalid use of a 64-bit GPQ register in 32-bit mode.
+     236             :   kErrorInvalidUseOfGpq,
+     237             :   //! Invalid use of an 80-bit float (TypeId::kF80).
+     238             :   kErrorInvalidUseOfF80,
+     239             :   //! Some registers in the instruction muse be consecutive (some ARM and AVX512 neural-net instructions).
+     240             :   kErrorNotConsecutiveRegs,
+     241             : 
+     242             :   //! AsmJit requires a physical register, but no one is available.
+     243             :   kErrorNoMorePhysRegs,
+     244             :   //! A variable has been assigned more than once to a function argument (CodeCompiler).
+     245             :   kErrorOverlappedRegs,
+     246             :   //! Invalid register to hold stack arguments offset.
+     247             :   kErrorOverlappingStackRegWithRegArg,
+     248             : 
+     249             :   //! Count of AsmJit error codes.
+     250             :   kErrorCount
+     251             : };
+     252             : 
+     253             : // ============================================================================
+     254             : // [asmjit::Internal]
+     255             : // ============================================================================
+     256             : 
+     257             : namespace Internal {
+     258             : 
+     259             : #if defined(ASMJIT_CUSTOM_ALLOC)   && \
+     260             :     defined(ASMJIT_CUSTOM_REALLOC) && \
+     261             :     defined(ASMJIT_CUSTOM_FREE)
+     262             : static ASMJIT_INLINE void* allocMemory(size_t size) noexcept { return ASMJIT_CUSTOM_ALLOC(size); }
+     263             : static ASMJIT_INLINE void* reallocMemory(void* p, size_t size) noexcept { return ASMJIT_CUSTOM_REALLOC(p, size); }
+     264             : static ASMJIT_INLINE void releaseMemory(void* p) noexcept { ASMJIT_CUSTOM_FREE(p); }
+     265             : #elif !defined(ASMJIT_CUSTOM_ALLOC)   && \
+     266             :       !defined(ASMJIT_CUSTOM_REALLOC) && \
+     267             :       !defined(ASMJIT_CUSTOM_FREE)
+     268       11700 : static ASMJIT_INLINE void* allocMemory(size_t size) noexcept { return ::malloc(size); }
+     269           0 : static ASMJIT_INLINE void* reallocMemory(void* p, size_t size) noexcept { return ::realloc(p, size); }
+     270       11700 : static ASMJIT_INLINE void releaseMemory(void* p) noexcept { ::free(p); }
+     271             : #else
+     272             : # error "[asmjit] You must provide either none or all of ASMJIT_CUSTOM_[ALLOC|REALLOC|FREE]"
+     273             : #endif
+     274             : 
+     275             : //! Cast designed to cast between function and void* pointers.
+     276             : template<typename Dst, typename Src>
+     277             : static ASMJIT_INLINE Dst ptr_cast(Src p) noexcept { return (Dst)p; }
+     278             : 
+     279             : } // Internal namespace
+     280             : 
+     281             : template<typename Func>
+     282             : static ASMJIT_INLINE Func ptr_as_func(void* func) noexcept { return Internal::ptr_cast<Func, void*>(func); }
+     283             : 
+     284             : template<typename Func>
+     285             : static ASMJIT_INLINE void* func_as_ptr(Func func) noexcept { return Internal::ptr_cast<void*, Func>(func); }
+     286             : 
+     287             : // ============================================================================
+     288             : // [asmjit::DebugUtils]
+     289             : // ============================================================================
+     290             : 
+     291             : namespace DebugUtils {
+     292             : 
+     293             : //! Returns the error `err` passed.
+     294             : //!
+     295             : //! Provided for debugging purposes. Putting a breakpoint inside `errored` can
+     296             : //! help with tracing the origin of any error reported / returned by AsmJit.
+     297             : static ASMJIT_INLINE Error errored(Error err) noexcept { return err; }
+     298             : 
+     299             : //! Get a printable version of `asmjit::Error` code.
+     300             : ASMJIT_API const char* errorAsString(Error err) noexcept;
+     301             : 
+     302             : //! Called to output debugging message(s).
+     303             : ASMJIT_API void debugOutput(const char* str) noexcept;
+     304             : 
+     305             : //! Called on assertion failure.
+     306             : //!
+     307             : //! \param file Source file name where it happened.
+     308             : //! \param line Line in the source file.
+     309             : //! \param msg Message to display.
+     310             : //!
+     311             : //! If you have problems with assertions put a breakpoint at assertionFailed()
+     312             : //! function (asmjit/base/globals.cpp) and check the call stack to locate the
+     313             : //! failing code.
+     314             : ASMJIT_API void ASMJIT_NORETURN assertionFailed(const char* file, int line, const char* msg) noexcept;
+     315             : 
+     316             : #if defined(ASMJIT_DEBUG)
+     317             : # define ASMJIT_ASSERT(exp)                                          \
+     318             :   do {                                                               \
+     319             :     if (ASMJIT_LIKELY(exp))                                          \
+     320             :       break;                                                         \
+     321             :     ::PLMD::asmjit::DebugUtils::assertionFailed(__FILE__, __LINE__, #exp); \
+     322             :   } while (0)
+     323             : # define ASMJIT_NOT_REACHED()                                        \
+     324             :   do {                                                               \
+     325             :     ::PLMD::asmjit::DebugUtils::assertionFailed(__FILE__, __LINE__,        \
+     326             :       "ASMJIT_NOT_REACHED has been reached");                        \
+     327             :     ASMJIT_ASSUME(0);                                                \
+     328             :   } while (0)
+     329             : #else
+     330             : # define ASMJIT_ASSERT(exp) ASMJIT_NOP
+     331             : # define ASMJIT_NOT_REACHED() ASMJIT_ASSUME(0)
+     332             : #endif // DEBUG
+     333             : 
+     334             : //! \internal
+     335             : //!
+     336             : //! Used by AsmJit to propagate a possible `Error` produced by `...` to the caller.
+     337             : #define ASMJIT_PROPAGATE(...)               \
+     338             :   do {                                      \
+     339             :     ::PLMD::asmjit::Error _err = __VA_ARGS__;     \
+     340             :     if (ASMJIT_UNLIKELY(_err))              \
+     341             :       return _err;                          \
+     342             :   } while (0)
+     343             : 
+     344             : } // DebugUtils namespace
+     345             : 
+     346             : // ============================================================================
+     347             : // [asmjit::Init / NoInit]
+     348             : // ============================================================================
+     349             : 
+     350             : #if !defined(ASMJIT_DOCGEN)
+     351             : struct _Init {};
+     352             : static const _Init Init = {};
+     353             : 
+     354             : struct _NoInit {};
+     355             : static const _NoInit NoInit = {};
+     356             : #endif // !ASMJIT_DOCGEN
+     357             : 
+     358             : //! \}
+     359             : 
+     360             : } // asmjit namespace
+     361             : } // namespace PLMD
+     362             : 
+     363             : // [Api-End]
+     364             : #include "./asmjit_apiend.h"
+     365             : 
+     366             : // [Guard]
+     367             : #endif // _ASMJIT_BASE_GLOBALS_H
+     368             : #pragma GCC diagnostic pop
+     369             : #endif // __PLUMED_HAS_ASMJIT
+     370             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/index-sort-f.html b/coverage-libs/asmjit/index-sort-f.html new file mode 100644 index 000000000000..2f175bff7af6 --- /dev/null +++ b/coverage-libs/asmjit/index-sort-f.html @@ -0,0 +1,604 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjitHitTotalCoverage
Test:plumed test coverage (other modules)Lines:2235712431.4 %
Date:2024-02-22 21:58:47Functions:13935239.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
inst.cpp +
0.0%
+
0.0 %0 / 60.0 %0 / 2
x86inst.cpp +
0.0%
+
0.0 %0 / 240.0 %0 / 2
x86compiler.h +
66.7%66.7%
+
66.7 %4 / 60.0 %0 / 2
globals.cpp +
0.0%
+
0.0 %0 / 90.0 %0 / 3
x86instimpl.cpp +
0.0%
+
0.0 %0 / 1700.0 %0 / 3
x86builder.cpp +
0.0%
+
0.0 %0 / 150.0 %0 / 5
constpool.cpp +
0.0%
+
0.0 %0 / 1100.0 %0 / 8
x86logging.cpp +
0.0%
+
0.0 %0 / 2030.0 %0 / 8
string.cpp +
0.0%
+
0.0 %0 / 1380.0 %0 / 14
logging.cpp +
0.0%
+
0.0 %0 / 1470.0 %0 / 25
codeemitter.cpp +
33.7%33.7%
+
33.7 %32 / 9529.0 %9 / 31
codebuilder.cpp +
23.3%23.3%
+
23.3 %60 / 25730.3 %10 / 33
assembler.cpp +
23.0%23.0%
+
23.0 %40 / 17433.3 %6 / 18
codecompiler.cpp +
37.2%37.2%
+
37.2 %89 / 23941.7 %15 / 36
x86internal.cpp +
28.7%28.7%
+
28.7 %113 / 39442.9 %6 / 14
codeholder.cpp +
46.3%46.3%
+
46.3 %120 / 25948.0 %12 / 25
x86assembler.cpp +
10.7%10.7%
+
10.7 %183 / 170557.1 %4 / 7
vmem.cpp +
30.2%30.2%
+
30.2 %96 / 31857.1 %8 / 14
x86regalloc.cpp +
44.2%44.2%
+
44.2 %466 / 105558.6 %17 / 29
zone.cpp +
45.6%45.6%
+
45.6 %136 / 29859.1 %13 / 22
regalloc.cpp +
47.3%47.3%
+
47.3 %114 / 24169.2 %9 / 13
func.cpp +
77.4%77.4%
+
77.4 %24 / 3171.4 %5 / 7
x86compiler.cpp +
31.8%31.8%
+
31.8 %48 / 15171.4 %5 / 7
runtime.cpp +
73.7%73.7%
+
73.7 %28 / 3875.0 %9 / 12
osutils.cpp +
81.8%81.8%
+
81.8 %18 / 2280.0 %4 / 5
runtime.h +
100.0%
+
100.0 %3 / 3-0 / 0
codeemitter.h +
81.8%81.8%
+
81.8 %9 / 11-0 / 0
x86misc.h +
59.5%59.5%
+
59.5 %22 / 37-0 / 0
arch.h +
75.0%75.0%
+
75.0 %6 / 8-0 / 0
x86regalloc_p.h +
69.4%69.4%
+
69.4 %34 / 49-0 / 0
moved_string.h +
22.2%22.2%
+
22.2 %6 / 27-0 / 0
cpuinfo.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
logging.h +
0.0%
+
0.0 %0 / 5-0 / 0
assembler.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
codeholder.h +
78.0%78.0%
+
78.0 %32 / 41-0 / 0
regalloc_p.h +
66.7%66.7%
+
66.7 %36 / 54-0 / 0
x86emitter.h +
63.0%63.0%
+
63.0 %17 / 27-0 / 0
inst.h +
40.0%40.0%
+
40.0 %2 / 5-0 / 0
osutils.h +
100.0%
+
100.0 %5 / 5-0 / 0
globals.h +
66.7%66.7%
+
66.7 %2 / 3-0 / 0
operand.h +
54.4%54.4%
+
54.4 %49 / 90-0 / 0
x86inst.h +
66.7%66.7%
+
66.7 %10 / 15-0 / 0
constpool.h +
0.0%
+
0.0 %0 / 31-0 / 0
x86operand.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
codebuilder.h +
53.2%53.2%
+
53.2 %50 / 94-0 / 0
utils.h +
48.9%48.9%
+
48.9 %22 / 45-0 / 0
func.h +
70.1%70.1%
+
70.1 %68 / 97-0 / 0
x86assembler.h +
100.0%
+
100.0 %2 / 2-0 / 0
codecompiler.h +
64.1%64.1%
+
64.1 %41 / 64-0 / 0
zone.h +
78.5%78.5%
+
78.5 %73 / 93100.0 %2 / 2
arch.cpp +
62.5%62.5%
+
62.5 %25 / 40100.0 %2 / 2
cpuinfo.cpp +
91.9%91.9%
+
91.9 %137 / 149100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/index-sort-l.html b/coverage-libs/asmjit/index-sort-l.html new file mode 100644 index 000000000000..73f056b39a9a --- /dev/null +++ b/coverage-libs/asmjit/index-sort-l.html @@ -0,0 +1,604 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjitHitTotalCoverage
Test:plumed test coverage (other modules)Lines:2235712431.4 %
Date:2024-02-22 21:58:47Functions:13935239.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
logging.h +
0.0%
+
0.0 %0 / 5-0 / 0
inst.cpp +
0.0%
+
0.0 %0 / 60.0 %0 / 2
globals.cpp +
0.0%
+
0.0 %0 / 90.0 %0 / 3
x86builder.cpp +
0.0%
+
0.0 %0 / 150.0 %0 / 5
x86inst.cpp +
0.0%
+
0.0 %0 / 240.0 %0 / 2
constpool.h +
0.0%
+
0.0 %0 / 31-0 / 0
constpool.cpp +
0.0%
+
0.0 %0 / 1100.0 %0 / 8
string.cpp +
0.0%
+
0.0 %0 / 1380.0 %0 / 14
logging.cpp +
0.0%
+
0.0 %0 / 1470.0 %0 / 25
x86instimpl.cpp +
0.0%
+
0.0 %0 / 1700.0 %0 / 3
x86logging.cpp +
0.0%
+
0.0 %0 / 2030.0 %0 / 8
x86assembler.cpp +
10.7%10.7%
+
10.7 %183 / 170557.1 %4 / 7
moved_string.h +
22.2%22.2%
+
22.2 %6 / 27-0 / 0
assembler.cpp +
23.0%23.0%
+
23.0 %40 / 17433.3 %6 / 18
codebuilder.cpp +
23.3%23.3%
+
23.3 %60 / 25730.3 %10 / 33
x86internal.cpp +
28.7%28.7%
+
28.7 %113 / 39442.9 %6 / 14
vmem.cpp +
30.2%30.2%
+
30.2 %96 / 31857.1 %8 / 14
x86compiler.cpp +
31.8%31.8%
+
31.8 %48 / 15171.4 %5 / 7
codeemitter.cpp +
33.7%33.7%
+
33.7 %32 / 9529.0 %9 / 31
codecompiler.cpp +
37.2%37.2%
+
37.2 %89 / 23941.7 %15 / 36
inst.h +
40.0%40.0%
+
40.0 %2 / 5-0 / 0
x86regalloc.cpp +
44.2%44.2%
+
44.2 %466 / 105558.6 %17 / 29
zone.cpp +
45.6%45.6%
+
45.6 %136 / 29859.1 %13 / 22
codeholder.cpp +
46.3%46.3%
+
46.3 %120 / 25948.0 %12 / 25
regalloc.cpp +
47.3%47.3%
+
47.3 %114 / 24169.2 %9 / 13
utils.h +
48.9%48.9%
+
48.9 %22 / 45-0 / 0
assembler.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
codebuilder.h +
53.2%53.2%
+
53.2 %50 / 94-0 / 0
operand.h +
54.4%54.4%
+
54.4 %49 / 90-0 / 0
cpuinfo.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
x86operand.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
x86misc.h +
59.5%59.5%
+
59.5 %22 / 37-0 / 0
arch.cpp +
62.5%62.5%
+
62.5 %25 / 40100.0 %2 / 2
x86emitter.h +
63.0%63.0%
+
63.0 %17 / 27-0 / 0
codecompiler.h +
64.1%64.1%
+
64.1 %41 / 64-0 / 0
globals.h +
66.7%66.7%
+
66.7 %2 / 3-0 / 0
x86compiler.h +
66.7%66.7%
+
66.7 %4 / 60.0 %0 / 2
x86inst.h +
66.7%66.7%
+
66.7 %10 / 15-0 / 0
regalloc_p.h +
66.7%66.7%
+
66.7 %36 / 54-0 / 0
x86regalloc_p.h +
69.4%69.4%
+
69.4 %34 / 49-0 / 0
func.h +
70.1%70.1%
+
70.1 %68 / 97-0 / 0
runtime.cpp +
73.7%73.7%
+
73.7 %28 / 3875.0 %9 / 12
arch.h +
75.0%75.0%
+
75.0 %6 / 8-0 / 0
func.cpp +
77.4%77.4%
+
77.4 %24 / 3171.4 %5 / 7
codeholder.h +
78.0%78.0%
+
78.0 %32 / 41-0 / 0
zone.h +
78.5%78.5%
+
78.5 %73 / 93100.0 %2 / 2
codeemitter.h +
81.8%81.8%
+
81.8 %9 / 11-0 / 0
osutils.cpp +
81.8%81.8%
+
81.8 %18 / 2280.0 %4 / 5
cpuinfo.cpp +
91.9%91.9%
+
91.9 %137 / 149100.0 %3 / 3
x86assembler.h +
100.0%
+
100.0 %2 / 2-0 / 0
runtime.h +
100.0%
+
100.0 %3 / 3-0 / 0
osutils.h +
100.0%
+
100.0 %5 / 5-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/index.html b/coverage-libs/asmjit/index.html new file mode 100644 index 000000000000..322e241817a6 --- /dev/null +++ b/coverage-libs/asmjit/index.html @@ -0,0 +1,604 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjitHitTotalCoverage
Test:plumed test coverage (other modules)Lines:2235712431.4 %
Date:2024-02-22 21:58:47Functions:13935239.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
arch.cpp +
62.5%62.5%
+
62.5 %25 / 40100.0 %2 / 2
arch.h +
75.0%75.0%
+
75.0 %6 / 8-0 / 0
assembler.cpp +
23.0%23.0%
+
23.0 %40 / 17433.3 %6 / 18
assembler.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
codebuilder.cpp +
23.3%23.3%
+
23.3 %60 / 25730.3 %10 / 33
codebuilder.h +
53.2%53.2%
+
53.2 %50 / 94-0 / 0
codecompiler.cpp +
37.2%37.2%
+
37.2 %89 / 23941.7 %15 / 36
codecompiler.h +
64.1%64.1%
+
64.1 %41 / 64-0 / 0
codeemitter.cpp +
33.7%33.7%
+
33.7 %32 / 9529.0 %9 / 31
codeemitter.h +
81.8%81.8%
+
81.8 %9 / 11-0 / 0
codeholder.cpp +
46.3%46.3%
+
46.3 %120 / 25948.0 %12 / 25
codeholder.h +
78.0%78.0%
+
78.0 %32 / 41-0 / 0
constpool.cpp +
0.0%
+
0.0 %0 / 1100.0 %0 / 8
constpool.h +
0.0%
+
0.0 %0 / 31-0 / 0
cpuinfo.cpp +
91.9%91.9%
+
91.9 %137 / 149100.0 %3 / 3
cpuinfo.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
func.cpp +
77.4%77.4%
+
77.4 %24 / 3171.4 %5 / 7
func.h +
70.1%70.1%
+
70.1 %68 / 97-0 / 0
globals.cpp +
0.0%
+
0.0 %0 / 90.0 %0 / 3
globals.h +
66.7%66.7%
+
66.7 %2 / 3-0 / 0
inst.cpp +
0.0%
+
0.0 %0 / 60.0 %0 / 2
inst.h +
40.0%40.0%
+
40.0 %2 / 5-0 / 0
logging.cpp +
0.0%
+
0.0 %0 / 1470.0 %0 / 25
logging.h +
0.0%
+
0.0 %0 / 5-0 / 0
moved_string.h +
22.2%22.2%
+
22.2 %6 / 27-0 / 0
operand.h +
54.4%54.4%
+
54.4 %49 / 90-0 / 0
osutils.cpp +
81.8%81.8%
+
81.8 %18 / 2280.0 %4 / 5
osutils.h +
100.0%
+
100.0 %5 / 5-0 / 0
regalloc.cpp +
47.3%47.3%
+
47.3 %114 / 24169.2 %9 / 13
regalloc_p.h +
66.7%66.7%
+
66.7 %36 / 54-0 / 0
runtime.cpp +
73.7%73.7%
+
73.7 %28 / 3875.0 %9 / 12
runtime.h +
100.0%
+
100.0 %3 / 3-0 / 0
string.cpp +
0.0%
+
0.0 %0 / 1380.0 %0 / 14
utils.h +
48.9%48.9%
+
48.9 %22 / 45-0 / 0
vmem.cpp +
30.2%30.2%
+
30.2 %96 / 31857.1 %8 / 14
x86assembler.cpp +
10.7%10.7%
+
10.7 %183 / 170557.1 %4 / 7
x86assembler.h +
100.0%
+
100.0 %2 / 2-0 / 0
x86builder.cpp +
0.0%
+
0.0 %0 / 150.0 %0 / 5
x86compiler.cpp +
31.8%31.8%
+
31.8 %48 / 15171.4 %5 / 7
x86compiler.h +
66.7%66.7%
+
66.7 %4 / 60.0 %0 / 2
x86emitter.h +
63.0%63.0%
+
63.0 %17 / 27-0 / 0
x86inst.cpp +
0.0%
+
0.0 %0 / 240.0 %0 / 2
x86inst.h +
66.7%66.7%
+
66.7 %10 / 15-0 / 0
x86instimpl.cpp +
0.0%
+
0.0 %0 / 1700.0 %0 / 3
x86internal.cpp +
28.7%28.7%
+
28.7 %113 / 39442.9 %6 / 14
x86logging.cpp +
0.0%
+
0.0 %0 / 2030.0 %0 / 8
x86misc.h +
59.5%59.5%
+
59.5 %22 / 37-0 / 0
x86operand.h +
54.5%54.5%
+
54.5 %6 / 11-0 / 0
x86regalloc.cpp +
44.2%44.2%
+
44.2 %466 / 105558.6 %17 / 29
x86regalloc_p.h +
69.4%69.4%
+
69.4 %34 / 49-0 / 0
zone.cpp +
45.6%45.6%
+
45.6 %136 / 29859.1 %13 / 22
zone.h +
78.5%78.5%
+
78.5 %73 / 93100.0 %2 / 2
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.cpp.func-sort-c.html b/coverage-libs/asmjit/inst.cpp.func-sort-c.html new file mode 100644 index 000000000000..7b60a3cb71f0 --- /dev/null +++ b/coverage-libs/asmjit/inst.cpp.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:060.0 %
Date:2024-02-22 21:58:47Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit4Inst13checkFeaturesEjRKNS1_6DetailEPKNS0_8Operand_EjRNS0_11CpuFeaturesE0
_ZN4PLMD6asmjit4Inst8validateEjRKNS1_6DetailEPKNS0_8Operand_Ej0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.cpp.func.html b/coverage-libs/asmjit/inst.cpp.func.html new file mode 100644 index 000000000000..2209c2e1fd1f --- /dev/null +++ b/coverage-libs/asmjit/inst.cpp.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:060.0 %
Date:2024-02-22 21:58:47Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit4Inst13checkFeaturesEjRKNS1_6DetailEPKNS0_8Operand_EjRNS0_11CpuFeaturesE0
_ZN4PLMD6asmjit4Inst8validateEjRKNS1_6DetailEPKNS0_8Operand_Ej0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.cpp.gcov.html b/coverage-libs/asmjit/inst.cpp.gcov.html new file mode 100644 index 000000000000..1336c52ad195 --- /dev/null +++ b/coverage-libs/asmjit/inst.cpp.gcov.html @@ -0,0 +1,180 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:060.0 %
Date:2024-02-22 21:58:47Functions:020.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Guard]
+      33             : #include "./asmjit_build.h"
+      34             : #if defined(ASMJIT_BUILD_X86)
+      35             : 
+      36             : // [Dependencies]
+      37             : #include "./arch.h"
+      38             : #include "./inst.h"
+      39             : 
+      40             : #if defined(ASMJIT_BUILD_X86)
+      41             : # include "./x86instimpl_p.h"
+      42             : #endif // ASMJIT_BUILD_X86
+      43             : 
+      44             : #if defined(ASMJIT_BUILD_ARM)
+      45             : # include "./arminstimpl_p.h"
+      46             : #endif // ASMJIT_BUILD_ARM
+      47             : 
+      48             : // [Api-Begin]
+      49             : #include "./asmjit_apibegin.h"
+      50             : 
+      51             : namespace PLMD {
+      52             : namespace asmjit {
+      53             : 
+      54             : // ============================================================================
+      55             : // [asmjit::Inst - Validate]
+      56             : // ============================================================================
+      57             : 
+      58             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+      59           0 : Error Inst::validate(uint32_t archType, const Detail& detail, const Operand_* operands, uint32_t count) noexcept {
+      60             :   #if defined(ASMJIT_BUILD_X86)
+      61           0 :   if (ArchInfo::isX86Family(archType))
+      62           0 :     return X86InstImpl::validate(archType, detail, operands, count);
+      63             :   #endif
+      64             : 
+      65             :   #if defined(ASMJIT_BUILD_ARM)
+      66             :   if (ArchInfo::isArmFamily(archType))
+      67             :     return ArmInstImpl::validate(archType, detail, operands, count);
+      68             :   #endif
+      69             : 
+      70             :   return DebugUtils::errored(kErrorInvalidArch);
+      71             : }
+      72             : #endif
+      73             : 
+      74             : // ============================================================================
+      75             : // [asmjit::Inst - CheckFeatures]
+      76             : // ============================================================================
+      77             : 
+      78             : #if !defined(ASMJIT_DISABLE_EXTENSIONS)
+      79           0 : Error Inst::checkFeatures(uint32_t archType, const Detail& detail, const Operand_* operands, uint32_t count, CpuFeatures& out) noexcept {
+      80             :   #if defined(ASMJIT_BUILD_X86)
+      81           0 :   if (ArchInfo::isX86Family(archType))
+      82           0 :     return X86InstImpl::checkFeatures(archType, detail, operands, count, out);
+      83             :   #endif
+      84             : 
+      85             :   #if defined(ASMJIT_BUILD_ARM)
+      86             :   if (ArchInfo::isArmFamily(archType))
+      87             :     return ArmInstImpl::checkFeatures(archType, detail, operands, count, out);
+      88             :   #endif
+      89             : 
+      90             :   return DebugUtils::errored(kErrorInvalidArch);
+      91             : }
+      92             : #endif // !defined(ASMJIT_DISABLE_EXTENSIONS)
+      93             : 
+      94             : } // asmjit namespace
+      95             : } // namespace PLMD
+      96             : 
+      97             : // [Api-End]
+      98             : #include "./asmjit_apiend.h"
+      99             : 
+     100             : // [Guard]
+     101             : #endif // ASMJIT_BUILD_X86
+     102             : #pragma GCC diagnostic pop
+     103             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.h.func-sort-c.html b/coverage-libs/asmjit/inst.h.func-sort-c.html new file mode 100644 index 000000000000..e195bb34df75 --- /dev/null +++ b/coverage-libs/asmjit/inst.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2540.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.h.func.html b/coverage-libs/asmjit/inst.h.func.html new file mode 100644 index 000000000000..4b002ea63bdc --- /dev/null +++ b/coverage-libs/asmjit/inst.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2540.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/inst.h.gcov.html b/coverage-libs/asmjit/inst.h.gcov.html new file mode 100644 index 000000000000..f73d77e98229 --- /dev/null +++ b/coverage-libs/asmjit/inst.h.gcov.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/inst.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:2540.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_inst_h
+      21             : #define __PLUMED_asmjit_inst_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_INST_H
+      33             : #define _ASMJIT_BASE_INST_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./cpuinfo.h"
+      37             : #include "./operand.h"
+      38             : 
+      39             : // [Api-Begin]
+      40             : #include "./asmjit_apibegin.h"
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace asmjit {
+      44             : 
+      45             : //! \addtogroup asmjit_base
+      46             : //! \{
+      47             : 
+      48             : // ============================================================================
+      49             : // [asmjit::Inst]
+      50             : // ============================================================================
+      51             : 
+      52             : //! Definitions and utilities related to instructions used by all architectures.
+      53             : struct Inst {
+      54             :   ASMJIT_ENUM(Id) {
+      55             :     kIdNone = 0                          //!< Invalid or uninitialized instruction id.
+      56             :   };
+      57             : 
+      58             :   //! Describes an instruction's jump type, if any.
+      59             :   ASMJIT_ENUM(JumpType) {
+      60             :     kJumpTypeNone        = 0,            //!< Instruction doesn't jump (regular instruction).
+      61             :     kJumpTypeDirect      = 1,            //!< Instruction is a unconditional (direct) jump.
+      62             :     kJumpTypeConditional = 2,            //!< Instruction is a conditional jump.
+      63             :     kJumpTypeCall        = 3,            //!< Instruction is a function call.
+      64             :     kJumpTypeReturn      = 4             //!< Instruction is a function return.
+      65             :   };
+      66             : 
+      67             :   // --------------------------------------------------------------------------
+      68             :   // [Detail]
+      69             :   // --------------------------------------------------------------------------
+      70             : 
+      71             :   //! Instruction id, options, and extraReg packed in a single structure. This
+      72             :   //! structure exists to simplify analysis and validation API that requires a
+      73             :   //! lot of information about the instruction to be processed.
+      74             :   class Detail {
+      75             :   public:
+      76             :     ASMJIT_INLINE Detail() noexcept
+      77       48362 :       : instId(0),
+      78             :         options(0),
+      79       48362 :         extraReg() {}
+      80             : 
+      81             :     explicit ASMJIT_INLINE Detail(uint32_t instId, uint32_t options = 0) noexcept
+      82             :       : instId(instId),
+      83             :         options(options),
+      84             :         extraReg() {}
+      85             : 
+      86             :     ASMJIT_INLINE Detail(uint32_t instId, uint32_t options, const RegOnly& reg) noexcept
+      87           0 :       : instId(instId),
+      88           0 :         options(options),
+      89           0 :         extraReg(reg) {}
+      90             : 
+      91             :     ASMJIT_INLINE Detail(uint32_t instId, uint32_t options, const Reg& reg) noexcept
+      92             :       : instId(instId),
+      93             :         options(options) { extraReg.init(reg); }
+      94             : 
+      95             :     // ------------------------------------------------------------------------
+      96             :     // [Accessors]
+      97             :     // ------------------------------------------------------------------------
+      98             : 
+      99             :     ASMJIT_INLINE bool hasExtraReg() const noexcept { return extraReg.isValid(); }
+     100             : 
+     101             :     // ------------------------------------------------------------------------
+     102             :     // [Members]
+     103             :     // ------------------------------------------------------------------------
+     104             : 
+     105             :     uint32_t instId;
+     106             :     uint32_t options;
+     107             :     RegOnly extraReg;
+     108             :   };
+     109             : 
+     110             :   // --------------------------------------------------------------------------
+     111             :   // [API]
+     112             :   // --------------------------------------------------------------------------
+     113             : 
+     114             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+     115             :   //! Validate the given instruction.
+     116             :   ASMJIT_API static Error validate(uint32_t archType, const Detail& detail, const Operand_* operands, uint32_t count) noexcept;
+     117             : #endif // !ASMJIT_DISABLE_VALIDATION
+     118             : 
+     119             : #if !defined(ASMJIT_DISABLE_EXTENSIONS)
+     120             :   //! Check CPU features required to execute the given instruction.
+     121             :   ASMJIT_API static Error checkFeatures(uint32_t archType, const Detail& detail, const Operand_* operands, uint32_t count, CpuFeatures& out) noexcept;
+     122             : #endif // !defined(ASMJIT_DISABLE_EXTENSIONS)
+     123             : };
+     124             : 
+     125             : //! \}
+     126             : 
+     127             : } // asmjit namespace
+     128             : } // namespace PLMD
+     129             : 
+     130             : // [Api-End]
+     131             : #include "./asmjit_apiend.h"
+     132             : 
+     133             : // [Guard]
+     134             : #endif // _ASMJIT_BASE_INST_H
+     135             : #pragma GCC diagnostic pop
+     136             : #endif // __PLUMED_HAS_ASMJIT
+     137             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/logging.cpp.func-sort-c.html b/coverage-libs/asmjit/logging.cpp.func-sort-c.html new file mode 100644 index 000000000000..028f9f565d7a --- /dev/null +++ b/coverage-libs/asmjit/logging.cpp.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01470.0 %
Date:2024-02-22 21:58:47Functions:0250.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10FileLogger4_logEPKcm0
_ZN4PLMD6asmjit10FileLoggerC2EP8_IO_FILE0
_ZN4PLMD6asmjit10FileLoggerD0Ev0
_ZN4PLMD6asmjit10FileLoggerD2Ev0
_ZN4PLMD6asmjit12StringLogger4_logEPKcm0
_ZN4PLMD6asmjit12StringLoggerC2Ev0
_ZN4PLMD6asmjit12StringLoggerD0Ev0
_ZN4PLMD6asmjit12StringLoggerD2Ev0
_ZN4PLMD6asmjit6Logger14setIndentationEPKc0
_ZN4PLMD6asmjit6Logger4logfEPKcz0
_ZN4PLMD6asmjit6Logger4logvEPKcP13__va_list_tag0
_ZN4PLMD6asmjit6Logger9logBinaryEPKvm0
_ZN4PLMD6asmjit6LoggerC2Ev0
_ZN4PLMD6asmjit6LoggerD0Ev0
_ZN4PLMD6asmjit6LoggerD2Ev0
_ZN4PLMD6asmjit7Logging10formatLineERNS0_13StringBuilderEPKhmmmPKc0
_ZN4PLMD6asmjit7Logging10formatNodeERNS0_13StringBuilderEjPKNS0_11CodeBuilderEPKNS0_6CBNodeE0
_ZN4PLMD6asmjit7Logging11formatLabelERNS0_13StringBuilderEjPKNS0_11CodeEmitterEj0
_ZN4PLMD6asmjit7Logging13formatOperandERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_8Operand_E0
_ZN4PLMD6asmjit7Logging14formatRegisterERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjjj0
_ZN4PLMD6asmjit7Logging17formatInstructionERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL12formatTypeIdERNS0_13StringBuilderEj0
_ZN4PLMD6asmjitL14formatFuncArgsERNS0_13StringBuilderEjPKNS0_11CodeEmitterERKNS0_10FuncDetailEPKPNS0_7VirtRegE0
_ZN4PLMD6asmjitL14formatFuncRetsERNS0_13StringBuilderEjPKNS0_11CodeEmitterERKNS0_10FuncDetailEPKPNS0_7VirtRegE0
_ZN4PLMD6asmjitL21formatFuncDetailValueERNS0_13StringBuilderEjPKNS0_11CodeEmitterENS0_10FuncDetail5ValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/logging.cpp.func.html b/coverage-libs/asmjit/logging.cpp.func.html new file mode 100644 index 000000000000..c6c6eaa192fe --- /dev/null +++ b/coverage-libs/asmjit/logging.cpp.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01470.0 %
Date:2024-02-22 21:58:47Functions:0250.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10FileLogger4_logEPKcm0
_ZN4PLMD6asmjit10FileLoggerC2EP8_IO_FILE0
_ZN4PLMD6asmjit10FileLoggerD0Ev0
_ZN4PLMD6asmjit10FileLoggerD2Ev0
_ZN4PLMD6asmjit12StringLogger4_logEPKcm0
_ZN4PLMD6asmjit12StringLoggerC2Ev0
_ZN4PLMD6asmjit12StringLoggerD0Ev0
_ZN4PLMD6asmjit12StringLoggerD2Ev0
_ZN4PLMD6asmjit6Logger14setIndentationEPKc0
_ZN4PLMD6asmjit6Logger4logfEPKcz0
_ZN4PLMD6asmjit6Logger4logvEPKcP13__va_list_tag0
_ZN4PLMD6asmjit6Logger9logBinaryEPKvm0
_ZN4PLMD6asmjit6LoggerC2Ev0
_ZN4PLMD6asmjit6LoggerD0Ev0
_ZN4PLMD6asmjit6LoggerD2Ev0
_ZN4PLMD6asmjit7Logging10formatLineERNS0_13StringBuilderEPKhmmmPKc0
_ZN4PLMD6asmjit7Logging10formatNodeERNS0_13StringBuilderEjPKNS0_11CodeBuilderEPKNS0_6CBNodeE0
_ZN4PLMD6asmjit7Logging11formatLabelERNS0_13StringBuilderEjPKNS0_11CodeEmitterEj0
_ZN4PLMD6asmjit7Logging13formatOperandERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_8Operand_E0
_ZN4PLMD6asmjit7Logging14formatRegisterERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjjj0
_ZN4PLMD6asmjit7Logging17formatInstructionERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL12formatTypeIdERNS0_13StringBuilderEj0
_ZN4PLMD6asmjitL14formatFuncArgsERNS0_13StringBuilderEjPKNS0_11CodeEmitterERKNS0_10FuncDetailEPKPNS0_7VirtRegE0
_ZN4PLMD6asmjitL14formatFuncRetsERNS0_13StringBuilderEjPKNS0_11CodeEmitterERKNS0_10FuncDetailEPKPNS0_7VirtRegE0
_ZN4PLMD6asmjitL21formatFuncDetailValueERNS0_13StringBuilderEjPKNS0_11CodeEmitterENS0_10FuncDetail5ValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/logging.cpp.gcov.html b/coverage-libs/asmjit/logging.cpp.gcov.html new file mode 100644 index 000000000000..c8e2bc1be4bc --- /dev/null +++ b/coverage-libs/asmjit/logging.cpp.gcov.html @@ -0,0 +1,601 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01470.0 %
Date:2024-02-22 21:58:47Functions:0250.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Guard]
+      33             : #include "./asmjit_build.h"
+      34             : #if !defined(ASMJIT_DISABLE_LOGGING)
+      35             : 
+      36             : // [Dependencies]
+      37             : #include "./codeholder.h"
+      38             : #include "./codeemitter.h"
+      39             : #include "./logging.h"
+      40             : #include "./utils.h"
+      41             : 
+      42             : #if !defined(ASMJIT_DISABLE_BUILDER)
+      43             : # include "./codebuilder.h"
+      44             : #endif // !ASMJIT_DISABLE_BUILDER
+      45             : 
+      46             : #if !defined(ASMJIT_DISABLE_COMPILER)
+      47             : # include "./codecompiler.h"
+      48             : #else
+      49             : namespace PLMD {
+      50             : namespace asmjit { class VirtReg; }
+      51             : #endif // !ASMJIT_DISABLE_COMPILER
+      52             : 
+      53             : #if defined(ASMJIT_BUILD_X86)
+      54             : # include "./x86logging_p.h"
+      55             : #endif // ASMJIT_BUILD_X86
+      56             : 
+      57             : #if defined(ASMJIT_BUILD_ARM)
+      58             : # include "./armlogging_p.h"
+      59             : #endif // ASMJIT_BUILD_ARM
+      60             : 
+      61             : // [Api-Begin]
+      62             : #include "./asmjit_apibegin.h"
+      63             : 
+      64             : namespace PLMD {
+      65             : namespace asmjit {
+      66             : 
+      67             : // ============================================================================
+      68             : // [asmjit::Logger - Construction / Destruction]
+      69             : // ============================================================================
+      70             : 
+      71           0 : Logger::Logger() noexcept {
+      72           0 :   _options = 0;
+      73           0 :   ::memset(_indentation, 0, ASMJIT_ARRAY_SIZE(_indentation));
+      74           0 : }
+      75           0 : Logger::~Logger() noexcept {}
+      76             : 
+      77             : // ============================================================================
+      78             : // [asmjit::Logger - Logging]
+      79             : // ============================================================================
+      80             : 
+      81           0 : Error Logger::logf(const char* fmt, ...) noexcept {
+      82             :   Error err;
+      83             : 
+      84             :   va_list ap;
+      85           0 :   va_start(ap, fmt);
+      86           0 :   err = logv(fmt, ap);
+      87           0 :   va_end(ap);
+      88             : 
+      89           0 :   return err;
+      90             : }
+      91             : 
+      92           0 : Error Logger::logv(const char* fmt, va_list ap) noexcept {
+      93             :   char buf[1024];
+      94           0 :   size_t len = vsnprintf(buf, sizeof(buf), fmt, ap);
+      95             : 
+      96             :   if (len >= sizeof(buf))
+      97             :     len = sizeof(buf) - 1;
+      98           0 :   return log(buf, len);
+      99             : }
+     100             : 
+     101           0 : Error Logger::logBinary(const void* data, size_t size) noexcept {
+     102             :   static const char prefix[] = ".data ";
+     103             :   static const char hex[16] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
+     104             : 
+     105             :   const uint8_t* s = static_cast<const uint8_t*>(data);
+     106           0 :   size_t i = size;
+     107             : 
+     108             :   char buffer[128];
+     109             :   ::memcpy(buffer, prefix, ASMJIT_ARRAY_SIZE(prefix) - 1);
+     110             : 
+     111           0 :   while (i) {
+     112           0 :     uint32_t n = static_cast<uint32_t>(std::min<size_t>(i, 16));
+     113             :     char* p = buffer + ASMJIT_ARRAY_SIZE(prefix) - 1;
+     114             : 
+     115           0 :     i -= n;
+     116             :     do {
+     117           0 :       uint32_t c = s[0];
+     118             : 
+     119           0 :       p[0] = hex[c >> 4];
+     120           0 :       p[1] = hex[c & 15];
+     121             : 
+     122           0 :       p += 2;
+     123           0 :       s += 1;
+     124           0 :     } while (--n);
+     125             : 
+     126           0 :     *p++ = '\n';
+     127           0 :     ASMJIT_PROPAGATE(log(buffer, (size_t)(p - buffer)));
+     128             :   }
+     129             : 
+     130             :   return kErrorOk;
+     131             : }
+     132             : 
+     133             : // ============================================================================
+     134             : // [asmjit::Logger - Indentation]
+     135             : // ============================================================================
+     136             : 
+     137           0 : void Logger::setIndentation(const char* indentation) noexcept {
+     138           0 :   ::memset(_indentation, 0, ASMJIT_ARRAY_SIZE(_indentation));
+     139           0 :   if (!indentation)
+     140             :     return;
+     141             : 
+     142             :   size_t length = Utils::strLen(indentation, ASMJIT_ARRAY_SIZE(_indentation) - 1);
+     143             :   ::memcpy(_indentation, indentation, length);
+     144             : }
+     145             : 
+     146             : // ============================================================================
+     147             : // [asmjit::FileLogger - Construction / Destruction]
+     148             : // ============================================================================
+     149             : 
+     150           0 : FileLogger::FileLogger(FILE* stream) noexcept : _stream(nullptr) { setStream(stream); }
+     151           0 : FileLogger::~FileLogger() noexcept {}
+     152             : 
+     153             : // ============================================================================
+     154             : // [asmjit::FileLogger - Logging]
+     155             : // ============================================================================
+     156             : 
+     157           0 : Error FileLogger::_log(const char* buf, size_t len) noexcept {
+     158           0 :   if (!_stream)
+     159             :     return kErrorOk;
+     160             : 
+     161           0 :   if (len == Globals::kInvalidIndex)
+     162           0 :     len = strlen(buf);
+     163             : 
+     164           0 :   fwrite(buf, 1, len, _stream);
+     165           0 :   return kErrorOk;
+     166             : }
+     167             : 
+     168             : // ============================================================================
+     169             : // [asmjit::StringLogger - Construction / Destruction]
+     170             : // ============================================================================
+     171             : 
+     172           0 : StringLogger::StringLogger() noexcept {}
+     173           0 : StringLogger::~StringLogger() noexcept {}
+     174             : 
+     175             : // ============================================================================
+     176             : // [asmjit::StringLogger - Logging]
+     177             : // ============================================================================
+     178             : 
+     179           0 : Error StringLogger::_log(const char* buf, size_t len) noexcept {
+     180           0 :   return _stringBuilder.appendString(buf, len);
+     181             : }
+     182             : 
+     183             : // ============================================================================
+     184             : // [asmjit::Logging]
+     185             : // ============================================================================
+     186             : 
+     187           0 : Error Logging::formatLabel(
+     188             :   StringBuilder& sb,
+     189             :   uint32_t logOptions,
+     190             :   const CodeEmitter* emitter,
+     191             :   uint32_t labelId) noexcept {
+     192             : 
+     193             :   const LabelEntry* le = emitter->getCode()->getLabelEntry(labelId);
+     194           0 :   if (ASMJIT_UNLIKELY(!le))
+     195           0 :     return sb.appendFormat("InvalidLabel[Id=%u]", static_cast<unsigned int>(labelId));
+     196             : 
+     197           0 :   if (le->hasName()) {
+     198           0 :     if (le->hasParent()) {
+     199             :       uint32_t parentId = le->getParentId();
+     200             :       const LabelEntry* pe = emitter->getCode()->getLabelEntry(parentId);
+     201             : 
+     202           0 :       if (ASMJIT_UNLIKELY(!pe))
+     203           0 :         ASMJIT_PROPAGATE(sb.appendFormat("InvalidLabel[Id=%u]", static_cast<unsigned int>(labelId)));
+     204           0 :       else if (ASMJIT_UNLIKELY(!pe->hasName()))
+     205           0 :         ASMJIT_PROPAGATE(sb.appendFormat("L%u", Operand::unpackId(parentId)));
+     206             :       else
+     207           0 :         ASMJIT_PROPAGATE(sb.appendString(pe->getName()));
+     208             : 
+     209           0 :       ASMJIT_PROPAGATE(sb.appendChar('.'));
+     210             :     }
+     211           0 :     return sb.appendString(le->getName());
+     212             :   }
+     213             :   else {
+     214           0 :     return sb.appendFormat("L%u", Operand::unpackId(labelId));
+     215             :   }
+     216             : }
+     217             : 
+     218           0 : Error Logging::formatRegister(
+     219             :   StringBuilder& sb,
+     220             :   uint32_t logOptions,
+     221             :   const CodeEmitter* emitter,
+     222             :   uint32_t archType,
+     223             :   uint32_t regType,
+     224             :   uint32_t regId) noexcept {
+     225             : 
+     226             : #if defined(ASMJIT_BUILD_X86)
+     227           0 :   return X86Logging::formatRegister(sb, logOptions, emitter, archType, regType, regId);
+     228             : #endif // ASMJIT_BUILD_X86
+     229             : 
+     230             : #if defined(ASMJIT_BUILD_ARM)
+     231             :   return ArmLogging::formatRegister(sb, logOptions, emitter, archType, regType, regId);
+     232             : #endif // ASMJIT_BUILD_ARM
+     233             : 
+     234             :   return kErrorInvalidArch;
+     235             : }
+     236             : 
+     237           0 : Error Logging::formatOperand(
+     238             :   StringBuilder& sb,
+     239             :   uint32_t logOptions,
+     240             :   const CodeEmitter* emitter,
+     241             :   uint32_t archType,
+     242             :   const Operand_& op) noexcept {
+     243             : 
+     244             : #if defined(ASMJIT_BUILD_X86)
+     245           0 :   return X86Logging::formatOperand(sb, logOptions, emitter, archType, op);
+     246             : #endif // ASMJIT_BUILD_X86
+     247             : 
+     248             : #if defined(ASMJIT_BUILD_ARM)
+     249             :   return ArmLogging::formatOperand(sb, logOptions, emitter, archType, op);
+     250             : #endif // ASMJIT_BUILD_ARM
+     251             : 
+     252             :   return kErrorInvalidArch;
+     253             : }
+     254             : 
+     255           0 : Error Logging::formatInstruction(
+     256             :   StringBuilder& sb,
+     257             :   uint32_t logOptions,
+     258             :   const CodeEmitter* emitter,
+     259             :   uint32_t archType,
+     260             :   const Inst::Detail& detail, const Operand_* opArray, uint32_t opCount) noexcept {
+     261             : 
+     262             : #if defined(ASMJIT_BUILD_X86)
+     263           0 :   return X86Logging::formatInstruction(sb, logOptions, emitter, archType, detail, opArray, opCount);
+     264             : #endif // ASMJIT_BUILD_X86
+     265             : 
+     266             : #if defined(ASMJIT_BUILD_ARM)
+     267             :   return ArmLogging::formatInstruction(sb, logOptions, emitter, archType, detail, opArray, opCount);
+     268             : #endif // ASMJIT_BUILD_ARM
+     269             : 
+     270             :   return kErrorInvalidArch;
+     271             : }
+     272             : 
+     273             : #if !defined(ASMJIT_DISABLE_BUILDER)
+     274           0 : static Error formatTypeId(StringBuilder& sb, uint32_t typeId) noexcept {
+     275           0 :   if (typeId == TypeId::kVoid)
+     276           0 :     return sb.appendString("void");
+     277             : 
+     278           0 :   if (!TypeId::isValid(typeId))
+     279           0 :     return sb.appendString("unknown");
+     280             : 
+     281             :   const char* typeName = "unknown";
+     282             :   uint32_t typeSize = TypeId::sizeOf(typeId);
+     283             : 
+     284             :   uint32_t elementId = TypeId::elementOf(typeId);
+     285           0 :   switch (elementId) {
+     286           0 :     case TypeId::kIntPtr : typeName = "intptr" ; break;
+     287           0 :     case TypeId::kUIntPtr: typeName = "uintptr"; break;
+     288           0 :     case TypeId::kI8     : typeName = "i8"     ; break;
+     289           0 :     case TypeId::kU8     : typeName = "u8"     ; break;
+     290           0 :     case TypeId::kI16    : typeName = "i16"    ; break;
+     291           0 :     case TypeId::kU16    : typeName = "u16"    ; break;
+     292           0 :     case TypeId::kI32    : typeName = "i32"    ; break;
+     293           0 :     case TypeId::kU32    : typeName = "u32"    ; break;
+     294           0 :     case TypeId::kI64    : typeName = "i64"    ; break;
+     295           0 :     case TypeId::kU64    : typeName = "u64"    ; break;
+     296           0 :     case TypeId::kF32    : typeName = "f32"    ; break;
+     297           0 :     case TypeId::kF64    : typeName = "f64"    ; break;
+     298           0 :     case TypeId::kF80    : typeName = "f80"    ; break;
+     299           0 :     case TypeId::kMask8  : typeName = "mask8"  ; break;
+     300           0 :     case TypeId::kMask16 : typeName = "mask16" ; break;
+     301           0 :     case TypeId::kMask32 : typeName = "mask32" ; break;
+     302           0 :     case TypeId::kMask64 : typeName = "mask64" ; break;
+     303           0 :     case TypeId::kMmx32  : typeName = "mmx32"  ; break;
+     304           0 :     case TypeId::kMmx64  : typeName = "mmx64"  ; break;
+     305             :   }
+     306             : 
+     307             :   uint32_t elementSize = TypeId::sizeOf(elementId);
+     308           0 :   if (typeSize > elementSize) {
+     309           0 :     unsigned int numElements = typeSize / elementSize;
+     310           0 :     return sb.appendFormat("%sx%u", typeName, numElements);
+     311             :   }
+     312             :   else {
+     313           0 :     return sb.appendString(typeName);
+     314             :   }
+     315             : }
+     316             : 
+     317           0 : static Error formatFuncDetailValue(
+     318             :   StringBuilder& sb,
+     319             :   uint32_t logOptions,
+     320             :   const CodeEmitter* emitter,
+     321             :   FuncDetail::Value value) noexcept {
+     322             : 
+     323             :   uint32_t typeId = value.getTypeId();
+     324           0 :   ASMJIT_PROPAGATE(formatTypeId(sb, typeId));
+     325             : 
+     326           0 :   if (value.byReg()) {
+     327           0 :     ASMJIT_PROPAGATE(sb.appendChar(':'));
+     328           0 :     ASMJIT_PROPAGATE(Logging::formatRegister(sb, logOptions, emitter, emitter->getArchType(), value.getRegType(), value.getRegId()));
+     329             :   }
+     330             : 
+     331           0 :   if (value.byStack()) {
+     332           0 :     ASMJIT_PROPAGATE(sb.appendFormat(":[%d]", static_cast<int>(value.getStackOffset())));
+     333             :   }
+     334             : 
+     335             :   return kErrorOk;
+     336             : }
+     337             : 
+     338           0 : static Error formatFuncRets(
+     339             :   StringBuilder& sb,
+     340             :   uint32_t logOptions,
+     341             :   const CodeEmitter* emitter,
+     342             :   const FuncDetail& fd,
+     343             :   VirtReg* const* vRegs) noexcept {
+     344             : 
+     345           0 :   if (!fd.hasRet())
+     346           0 :     return sb.appendString("void");
+     347             : 
+     348           0 :   for (uint32_t i = 0; i < fd.getRetCount(); i++) {
+     349           0 :     if (i) ASMJIT_PROPAGATE(sb.appendString(", "));
+     350           0 :     ASMJIT_PROPAGATE(formatFuncDetailValue(sb, logOptions, emitter, fd.getRet(i)));
+     351             : 
+     352             : #if !defined(ASMJIT_DISABLE_COMPILER)
+     353           0 :     if (vRegs)
+     354           0 :       ASMJIT_PROPAGATE(sb.appendFormat(" {%s}", vRegs[i]->getName()));
+     355             : #endif // !ASMJIT_DISABLE_COMPILER
+     356             :   }
+     357             : 
+     358             :   return kErrorOk;
+     359             : }
+     360             : 
+     361           0 : static Error formatFuncArgs(
+     362             :   StringBuilder& sb,
+     363             :   uint32_t logOptions,
+     364             :   const CodeEmitter* emitter,
+     365             :   const FuncDetail& fd,
+     366             :   VirtReg* const* vRegs) noexcept {
+     367             : 
+     368           0 :   for (uint32_t i = 0; i < fd.getArgCount(); i++) {
+     369           0 :     if (i) ASMJIT_PROPAGATE(sb.appendString(", "));
+     370           0 :     ASMJIT_PROPAGATE(formatFuncDetailValue(sb, logOptions, emitter, fd.getArg(i)));
+     371             : 
+     372             : #if !defined(ASMJIT_DISABLE_COMPILER)
+     373           0 :     if (vRegs)
+     374           0 :       ASMJIT_PROPAGATE(sb.appendFormat(" {%s}", vRegs[i]->getName()));
+     375             : #endif // !ASMJIT_DISABLE_COMPILER
+     376             :   }
+     377             : 
+     378             :   return kErrorOk;
+     379             : }
+     380             : 
+     381           0 : Error Logging::formatNode(
+     382             :   StringBuilder& sb,
+     383             :   uint32_t logOptions,
+     384             :   const CodeBuilder* cb,
+     385             :   const CBNode* node_) noexcept {
+     386             : 
+     387           0 :   if (node_->hasPosition())
+     388           0 :     ASMJIT_PROPAGATE(sb.appendFormat("<%04u> ", node_->getPosition()));
+     389             : 
+     390           0 :   switch (node_->getType()) {
+     391             :     case CBNode::kNodeInst: {
+     392             :       const CBInst* node = node_->as<CBInst>();
+     393           0 :       ASMJIT_PROPAGATE(
+     394             :         Logging::formatInstruction(sb, logOptions, cb,
+     395             :           cb->getArchType(),
+     396             :           node->getInstDetail(), node->getOpArray(), node->getOpCount()));
+     397             :       break;
+     398             :     }
+     399             : 
+     400             :     case CBNode::kNodeLabel: {
+     401             :       const CBLabel* node = node_->as<CBLabel>();
+     402           0 :       ASMJIT_PROPAGATE(sb.appendFormat("L%u:", Operand::unpackId(node->getId())));
+     403             :       break;
+     404             :     }
+     405             : 
+     406             :     case CBNode::kNodeData: {
+     407             :       const CBData* node = node_->as<CBData>();
+     408           0 :       ASMJIT_PROPAGATE(sb.appendFormat(".embed (%u bytes)", node->getSize()));
+     409             :       break;
+     410             :     }
+     411             : 
+     412             :     case CBNode::kNodeAlign: {
+     413             :       const CBAlign* node = node_->as<CBAlign>();
+     414           0 :       ASMJIT_PROPAGATE(
+     415             :         sb.appendFormat(".align %u (%s)",
+     416             :           node->getAlignment(),
+     417             :           node->getMode() == kAlignCode ? "code" : "data"));
+     418             :       break;
+     419             :     }
+     420             : 
+     421             :     case CBNode::kNodeComment: {
+     422             :       const CBComment* node = node_->as<CBComment>();
+     423           0 :       ASMJIT_PROPAGATE(sb.appendFormat("; %s", node->getInlineComment()));
+     424             :       break;
+     425             :     }
+     426             : 
+     427             :     case CBNode::kNodeSentinel: {
+     428           0 :       ASMJIT_PROPAGATE(sb.appendString("[sentinel]"));
+     429             :       break;
+     430             :     }
+     431             : 
+     432             : #if !defined(ASMJIT_DISABLE_COMPILER)
+     433             :     case CBNode::kNodeFunc: {
+     434             :       const CCFunc* node = node_->as<CCFunc>();
+     435           0 :       ASMJIT_PROPAGATE(formatLabel(sb, logOptions, cb, node->getId()));
+     436             : 
+     437           0 :       ASMJIT_PROPAGATE(sb.appendString(": ["));
+     438           0 :       ASMJIT_PROPAGATE(formatFuncRets(sb, logOptions, cb, node->getDetail(), nullptr));
+     439           0 :       ASMJIT_PROPAGATE(sb.appendString("]"));
+     440             : 
+     441           0 :       ASMJIT_PROPAGATE(sb.appendString("("));
+     442           0 :       ASMJIT_PROPAGATE(formatFuncArgs(sb, logOptions, cb, node->getDetail(), node->getArgs()));
+     443           0 :       ASMJIT_PROPAGATE(sb.appendString(")"));
+     444             :       break;
+     445             :     }
+     446             : 
+     447             :     case CBNode::kNodeFuncExit: {
+     448           0 :       ASMJIT_PROPAGATE(sb.appendString("[ret]"));
+     449             :       break;
+     450             :     }
+     451             : 
+     452             :     case CBNode::kNodeFuncCall: {
+     453             :       const CCFuncCall* node = node_->as<CCFuncCall>();
+     454           0 :       ASMJIT_PROPAGATE(
+     455             :         Logging::formatInstruction(sb, logOptions, cb,
+     456             :           cb->getArchType(),
+     457             :           node->getInstDetail(), node->getOpArray(), node->getOpCount()));
+     458             :       break;
+     459             :     }
+     460             : #endif // !ASMJIT_DISABLE_COMPILER
+     461             : 
+     462             :     default: {
+     463           0 :       ASMJIT_PROPAGATE(sb.appendFormat("[unknown (type=%u)]", node_->getType()));
+     464             :       break;
+     465             :     }
+     466             :   }
+     467             : 
+     468             :   return kErrorOk;
+     469             : }
+     470             : #endif // !ASMJIT_DISABLE_BUILDER
+     471             : 
+     472           0 : Error Logging::formatLine(StringBuilder& sb, const uint8_t* binData, size_t binLen, size_t dispLen, size_t imLen, const char* comment) noexcept {
+     473             :   size_t currentLen = sb.getLength();
+     474           0 :   size_t commentLen = comment ? Utils::strLen(comment, kMaxCommentLength) : 0;
+     475             : 
+     476             :   ASMJIT_ASSERT(binLen >= dispLen);
+     477             : 
+     478           0 :   if ((binLen != 0 && binLen != Globals::kInvalidIndex) || commentLen) {
+     479             :     size_t align = kMaxInstLength;
+     480             :     char sep = ';';
+     481             : 
+     482           0 :     for (size_t i = (binLen == Globals::kInvalidIndex); i < 2; i++) {
+     483             :       size_t begin = sb.getLength();
+     484             : 
+     485             :       // Append align.
+     486           0 :       if (currentLen < align)
+     487           0 :         ASMJIT_PROPAGATE(sb.appendChars(' ', align - currentLen));
+     488             : 
+     489             :       // Append separator.
+     490             :       if (sep) {
+     491           0 :         ASMJIT_PROPAGATE(sb.appendChar(sep));
+     492           0 :         ASMJIT_PROPAGATE(sb.appendChar(' '));
+     493             :       }
+     494             : 
+     495             :       // Append binary data or comment.
+     496           0 :       if (i == 0) {
+     497           0 :         ASMJIT_PROPAGATE(sb.appendHex(binData, binLen - dispLen - imLen));
+     498           0 :         ASMJIT_PROPAGATE(sb.appendChars('.', dispLen * 2));
+     499           0 :         ASMJIT_PROPAGATE(sb.appendHex(binData + binLen - imLen, imLen));
+     500           0 :         if (commentLen == 0) break;
+     501             :       }
+     502             :       else {
+     503           0 :         ASMJIT_PROPAGATE(sb.appendString(comment, commentLen));
+     504             :       }
+     505             : 
+     506           0 :       currentLen += sb.getLength() - begin;
+     507           0 :       align += kMaxBinaryLength;
+     508             :       sep = '|';
+     509             :     }
+     510             :   }
+     511             : 
+     512           0 :   return sb.appendChar('\n');
+     513             : }
+     514             : 
+     515             : } // asmjit namespace
+     516             : } // namespace PLMD
+     517             : 
+     518             : // [Api-End]
+     519             : #include "./asmjit_apiend.h"
+     520             : 
+     521             : // [Guard]
+     522             : #endif // !ASMJIT_DISABLE_LOGGING
+     523             : #pragma GCC diagnostic pop
+     524             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/logging.h.func-sort-c.html b/coverage-libs/asmjit/logging.h.func-sort-c.html new file mode 100644 index 000000000000..511fa6d3d478 --- /dev/null +++ b/coverage-libs/asmjit/logging.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:050.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/logging.h.func.html b/coverage-libs/asmjit/logging.h.func.html new file mode 100644 index 000000000000..c9cb6083a5a2 --- /dev/null +++ b/coverage-libs/asmjit/logging.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:050.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/logging.h.gcov.html b/coverage-libs/asmjit/logging.h.gcov.html new file mode 100644 index 000000000000..8aeb3e017a96 --- /dev/null +++ b/coverage-libs/asmjit/logging.h.gcov.html @@ -0,0 +1,394 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/logging.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - logging.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:050.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_logging_h
+      21             : #define __PLUMED_asmjit_logging_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_LOGGING_H
+      33             : #define _ASMJIT_BASE_LOGGING_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./inst.h"
+      37             : #include "./moved_string.h"
+      38             : 
+      39             : // [Api-Begin]
+      40             : #include "./asmjit_apibegin.h"
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace asmjit {
+      44             : 
+      45             : //! \addtogroup asmjit_base
+      46             : //! \{
+      47             : 
+      48             : #if !defined(ASMJIT_DISABLE_LOGGING)
+      49             : 
+      50             : // ============================================================================
+      51             : // [Forward Declarations]
+      52             : // ============================================================================
+      53             : 
+      54             : class CodeEmitter;
+      55             : class Reg;
+      56             : struct Operand_;
+      57             : 
+      58             : #if !defined(ASMJIT_DISABLE_BUILDER)
+      59             : class CodeBuilder;
+      60             : class CBNode;
+      61             : #endif // !ASMJIT_DISABLE_BUILDER
+      62             : 
+      63             : // ============================================================================
+      64             : // [asmjit::Logger]
+      65             : // ============================================================================
+      66             : 
+      67             : //! Abstract logging interface and helpers.
+      68             : //!
+      69             : //! This class can be inherited and reimplemented to fit into your logging
+      70             : //! subsystem. When reimplementing use `Logger::_log()` method to log into
+      71             : //! a custom stream.
+      72             : //!
+      73             : //! There are two \ref Logger implementations offered by AsmJit:
+      74             : //!   - \ref FileLogger - allows to log into a `FILE*` stream.
+      75             : //!   - \ref StringLogger - logs into a \ref StringBuilder.
+      76             : class ASMJIT_VIRTAPI Logger {
+      77             : public:
+      78             :   ASMJIT_NONCOPYABLE(Logger)
+      79             : 
+      80             :   // --------------------------------------------------------------------------
+      81             :   // [Options]
+      82             :   // --------------------------------------------------------------------------
+      83             : 
+      84             :   //! Logger options.
+      85             :   ASMJIT_ENUM(Options) {
+      86             :     kOptionBinaryForm      = 0x00000001, //! Output instructions also in binary form.
+      87             :     kOptionImmExtended     = 0x00000002, //! Output a meaning of some immediates.
+      88             :     kOptionHexImmediate    = 0x00000004, //! Output constants in hexadecimal form.
+      89             :     kOptionHexDisplacement = 0x00000008  //! Output displacements in hexadecimal form.
+      90             :   };
+      91             : 
+      92             :   // --------------------------------------------------------------------------
+      93             :   // [Construction / Destruction]
+      94             :   // --------------------------------------------------------------------------
+      95             : 
+      96             :   //! Create a `Logger` instance.
+      97             :   ASMJIT_API Logger() noexcept;
+      98             :   //! Destroy the `Logger` instance.
+      99             :   ASMJIT_API virtual ~Logger() noexcept;
+     100             : 
+     101             :   // --------------------------------------------------------------------------
+     102             :   // [Logging]
+     103             :   // --------------------------------------------------------------------------
+     104             : 
+     105             :   //! Log `str` - must be reimplemented.
+     106             :   virtual Error _log(const char* str, size_t len) noexcept = 0;
+     107             : 
+     108             :   //! Log a string `str`, which is either null terminated or having `len` length.
+     109           0 :   ASMJIT_INLINE Error log(const char* str, size_t len = Globals::kInvalidIndex) noexcept { return _log(str, len); }
+     110             :   //! Log a content of a `StringBuilder` `str`.
+     111             :   ASMJIT_INLINE Error log(const StringBuilder& str) noexcept { return _log(str.getData(), str.getLength()); }
+     112             : 
+     113             :   //! Format the message by using `sprintf()` and then send to `log()`.
+     114             :   ASMJIT_API Error logf(const char* fmt, ...) noexcept;
+     115             :   //! Format the message by using `vsprintf()` and then send to `log()`.
+     116             :   ASMJIT_API Error logv(const char* fmt, va_list ap) noexcept;
+     117             :   //! Log binary data.
+     118             :   ASMJIT_API Error logBinary(const void* data, size_t size) noexcept;
+     119             : 
+     120             :   // --------------------------------------------------------------------------
+     121             :   // [Options]
+     122             :   // --------------------------------------------------------------------------
+     123             : 
+     124             :   //! Get all logger options as a single integer.
+     125           0 :   ASMJIT_INLINE uint32_t getOptions() const noexcept { return _options; }
+     126             :   //! Get the given logger option.
+     127           0 :   ASMJIT_INLINE bool hasOption(uint32_t option) const noexcept { return (_options & option) != 0; }
+     128             :   ASMJIT_INLINE void addOptions(uint32_t options) noexcept { _options |= options; }
+     129             :   ASMJIT_INLINE void clearOptions(uint32_t options) noexcept { _options &= ~options; }
+     130             : 
+     131             :   // --------------------------------------------------------------------------
+     132             :   // [Indentation]
+     133             :   // --------------------------------------------------------------------------
+     134             : 
+     135             :   //! Get indentation.
+     136           0 :   ASMJIT_INLINE const char* getIndentation() const noexcept { return _indentation; }
+     137             :   //! Set indentation.
+     138             :   ASMJIT_API void setIndentation(const char* indentation) noexcept;
+     139             :   //! Reset indentation.
+     140             :   ASMJIT_INLINE void resetIndentation() noexcept { setIndentation(nullptr); }
+     141             : 
+     142             :   // --------------------------------------------------------------------------
+     143             :   // [Members]
+     144             :   // --------------------------------------------------------------------------
+     145             : 
+     146             :   //! Options, see \ref LoggerOption.
+     147             :   uint32_t _options;
+     148             : 
+     149             :   //! Indentation.
+     150             :   char _indentation[12];
+     151             : };
+     152             : 
+     153             : // ============================================================================
+     154             : // [asmjit::FileLogger]
+     155             : // ============================================================================
+     156             : 
+     157             : //! Logger that can log to a `FILE*` stream.
+     158             : class ASMJIT_VIRTAPI FileLogger : public Logger {
+     159             : public:
+     160             :   ASMJIT_NONCOPYABLE(FileLogger)
+     161             : 
+     162             :   // --------------------------------------------------------------------------
+     163             :   // [Construction / Destruction]
+     164             :   // --------------------------------------------------------------------------
+     165             : 
+     166             :   //! Create a new `FileLogger` that logs to a `FILE` stream.
+     167             :   ASMJIT_API FileLogger(FILE* stream = nullptr) noexcept;
+     168             :   //! Destroy the `FileLogger`.
+     169             :   ASMJIT_API virtual ~FileLogger() noexcept;
+     170             : 
+     171             :   // --------------------------------------------------------------------------
+     172             :   // [Accessors]
+     173             :   // --------------------------------------------------------------------------
+     174             : 
+     175             :   //! Get the logging out put stream or null.
+     176             :   ASMJIT_INLINE FILE* getStream() const noexcept { return _stream; }
+     177             : 
+     178             :   //! Set the logging output stream to `stream` or null.
+     179             :   //!
+     180             :   //! NOTE: If the `stream` is null it will disable logging, but it won't
+     181             :   //! stop calling `log()` unless the logger is detached from the
+     182             :   //! \ref Assembler.
+     183           0 :   ASMJIT_INLINE void setStream(FILE* stream) noexcept { _stream = stream; }
+     184             : 
+     185             :   // --------------------------------------------------------------------------
+     186             :   // [Logging]
+     187             :   // --------------------------------------------------------------------------
+     188             : 
+     189             :   ASMJIT_API Error _log(const char* buf, size_t len = Globals::kInvalidIndex) noexcept override;
+     190             : 
+     191             :   // --------------------------------------------------------------------------
+     192             :   // [Members]
+     193             :   // --------------------------------------------------------------------------
+     194             : 
+     195             :   //! C file stream.
+     196             :   FILE* _stream;
+     197             : };
+     198             : 
+     199             : // ============================================================================
+     200             : // [asmjit::StringLogger]
+     201             : // ============================================================================
+     202             : 
+     203             : //! Logger that stores everything in an internal string buffer.
+     204             : class ASMJIT_VIRTAPI StringLogger : public Logger {
+     205             : public:
+     206             :   ASMJIT_NONCOPYABLE(StringLogger)
+     207             : 
+     208             :   // --------------------------------------------------------------------------
+     209             :   // [Construction / Destruction]
+     210             :   // --------------------------------------------------------------------------
+     211             : 
+     212             :   //! Create new `StringLogger`.
+     213             :   ASMJIT_API StringLogger() noexcept;
+     214             :   //! Destroy the `StringLogger`.
+     215             :   ASMJIT_API virtual ~StringLogger() noexcept;
+     216             : 
+     217             :   // --------------------------------------------------------------------------
+     218             :   // [Accessors]
+     219             :   // --------------------------------------------------------------------------
+     220             : 
+     221             :   //! Get `char*` pointer which represents the resulting string.
+     222             :   //!
+     223             :   //! The pointer is owned by `StringLogger`, it can't be modified or freed.
+     224             :   ASMJIT_INLINE const char* getString() const noexcept { return _stringBuilder.getData(); }
+     225             :   //! Clear the resulting string.
+     226             :   ASMJIT_INLINE void clearString() noexcept { _stringBuilder.clear(); }
+     227             : 
+     228             :   //! Get the length of the string returned by `getString()`.
+     229             :   ASMJIT_INLINE size_t getLength() const noexcept { return _stringBuilder.getLength(); }
+     230             : 
+     231             :   // --------------------------------------------------------------------------
+     232             :   // [Logging]
+     233             :   // --------------------------------------------------------------------------
+     234             : 
+     235             :   ASMJIT_API Error _log(const char* buf, size_t len = Globals::kInvalidIndex) noexcept override;
+     236             : 
+     237             :   // --------------------------------------------------------------------------
+     238             :   // [Members]
+     239             :   // --------------------------------------------------------------------------
+     240             : 
+     241             :   //! Output string.
+     242             :   StringBuilder _stringBuilder;
+     243             : };
+     244             : 
+     245             : // ============================================================================
+     246             : // [asmjit::Logging]
+     247             : // ============================================================================
+     248             : 
+     249             : struct Logging {
+     250             :   ASMJIT_API static Error formatRegister(
+     251             :     StringBuilder& sb,
+     252             :     uint32_t logOptions,
+     253             :     const CodeEmitter* emitter,
+     254             :     uint32_t archType,
+     255             :     uint32_t regType,
+     256             :     uint32_t regId) noexcept;
+     257             : 
+     258             :   ASMJIT_API static Error formatLabel(
+     259             :     StringBuilder& sb,
+     260             :     uint32_t logOptions,
+     261             :     const CodeEmitter* emitter,
+     262             :     uint32_t labelId) noexcept;
+     263             : 
+     264             :   ASMJIT_API static Error formatOperand(
+     265             :     StringBuilder& sb,
+     266             :     uint32_t logOptions,
+     267             :     const CodeEmitter* emitter,
+     268             :     uint32_t archType,
+     269             :     const Operand_& op) noexcept;
+     270             : 
+     271             :   ASMJIT_API static Error formatInstruction(
+     272             :     StringBuilder& sb,
+     273             :     uint32_t logOptions,
+     274             :     const CodeEmitter* emitter,
+     275             :     uint32_t archType,
+     276             :     const Inst::Detail& detail, const Operand_* opArray, uint32_t opCount) noexcept;
+     277             : 
+     278             : #if !defined(ASMJIT_DISABLE_BUILDER)
+     279             :   ASMJIT_API static Error formatNode(
+     280             :     StringBuilder& sb,
+     281             :     uint32_t logOptions,
+     282             :     const CodeBuilder* cb,
+     283             :     const CBNode* node_) noexcept;
+     284             : #endif // !ASMJIT_DISABLE_BUILDER
+     285             : 
+     286             : // Only used by AsmJit internals, not available to users.
+     287             : #if defined(ASMJIT_EXPORTS)
+     288             :   enum {
+     289             :     // Has to be big to be able to hold all metadata compiler can assign to a
+     290             :     // single instruction.
+     291             :     kMaxCommentLength = 512,
+     292             :     kMaxInstLength = 40,
+     293             :     kMaxBinaryLength = 26
+     294             :   };
+     295             : 
+     296             :   static Error formatLine(
+     297             :     StringBuilder& sb,
+     298             :     const uint8_t* binData, size_t binLen, size_t dispLen, size_t imLen, const char* comment) noexcept;
+     299             : #endif // ASMJIT_EXPORTS
+     300             : };
+     301             : #else
+     302             : class Logger;
+     303             : #endif // !ASMJIT_DISABLE_LOGGING
+     304             : 
+     305             : //! \}
+     306             : 
+     307             : } // asmjit namespace
+     308             : } // namespace PLMD
+     309             : 
+     310             : // [Api-End]
+     311             : #include "./asmjit_apiend.h"
+     312             : 
+     313             : // [Guard]
+     314             : #endif // _ASMJIT_BASE_LOGGER_H
+     315             : #pragma GCC diagnostic pop
+     316             : #endif // __PLUMED_HAS_ASMJIT
+     317             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/moved_string.h.func-sort-c.html b/coverage-libs/asmjit/moved_string.h.func-sort-c.html new file mode 100644 index 000000000000..3da9a59dc0ad --- /dev/null +++ b/coverage-libs/asmjit/moved_string.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/moved_string.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - moved_string.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:62722.2 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/moved_string.h.func.html b/coverage-libs/asmjit/moved_string.h.func.html new file mode 100644 index 000000000000..c93030c3a8bb --- /dev/null +++ b/coverage-libs/asmjit/moved_string.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/moved_string.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - moved_string.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:62722.2 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/moved_string.h.gcov.html b/coverage-libs/asmjit/moved_string.h.gcov.html new file mode 100644 index 000000000000..419ec01bc52e --- /dev/null +++ b/coverage-libs/asmjit/moved_string.h.gcov.html @@ -0,0 +1,395 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/moved_string.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - moved_string.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:62722.2 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_moved_string_h
+      21             : #define __PLUMED_asmjit_moved_string_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_STRING_H
+      33             : #define _ASMJIT_BASE_STRING_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./globals.h"
+      37             : 
+      38             : // [Api-Begin]
+      39             : #include "./asmjit_apibegin.h"
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace asmjit {
+      43             : 
+      44             : //! \addtogroup asmjit_base
+      45             : //! \{
+      46             : 
+      47             : // ============================================================================
+      48             : // [asmjit::SmallString]
+      49             : // ============================================================================
+      50             : 
+      51             : //! Small string is a template that helps to create strings that can be either
+      52             : //! statically allocated if they are small, or externally allocated in case
+      53             : //! their length exceed the limit. The `WholeSize` represents the size of the
+      54             : //! whole `SmallString` structure, based on that size the maximum size of the
+      55             : //! internal buffer is determined.
+      56             : template<size_t WholeSize>
+      57             : class SmallString {
+      58             : public:
+      59             :   enum { kMaxEmbeddedLength = WholeSize - 5 };
+      60             : 
+      61             :   ASMJIT_INLINE SmallString() noexcept { reset(); }
+      62             :   ASMJIT_INLINE void reset() noexcept { ::memset(this, 0, sizeof(*this)); }
+      63             : 
+      64           0 :   ASMJIT_INLINE bool isEmpty() const noexcept { return _length == 0; }
+      65             :   ASMJIT_INLINE bool isEmbedded() const noexcept { return _length <= kMaxEmbeddedLength; }
+      66             :   ASMJIT_INLINE bool mustEmbed(size_t len) const noexcept { return len <= kMaxEmbeddedLength; }
+      67             : 
+      68           0 :   ASMJIT_INLINE uint32_t getLength() const noexcept { return _length; }
+      69             :   ASMJIT_INLINE char* getData() const noexcept {
+      70           0 :     return _length <= kMaxEmbeddedLength ? const_cast<char*>(_embedded) : _external[1];
+      71             :   }
+      72             : 
+      73             :   ASMJIT_INLINE void setEmbedded(const char* data, size_t len) noexcept {
+      74             :     ASMJIT_ASSERT(len <= kMaxEmbeddedLength);
+      75             : 
+      76           0 :     _length = static_cast<uint32_t>(len);
+      77           0 :     ::memcpy(_embedded, data, len);
+      78           0 :     _embedded[len] = '\0';
+      79           0 :   }
+      80             : 
+      81             :   ASMJIT_INLINE void setExternal(const char* data, size_t len) noexcept {
+      82             :     ASMJIT_ASSERT(len > kMaxEmbeddedLength);
+      83             :     ASMJIT_ASSERT(len <= ~static_cast<uint32_t>(0));
+      84             : 
+      85           0 :     _length = static_cast<uint32_t>(len);
+      86           0 :     _external[1] = const_cast<char*>(data);
+      87           0 :   }
+      88             : 
+      89             :   union {
+      90             :     struct {
+      91             :       uint32_t _length;
+      92             :       char _embedded[WholeSize - 4];
+      93             :     };
+      94             :     char* _external[2];
+      95             :   };
+      96             : };
+      97             : 
+      98             : // ============================================================================
+      99             : // [asmjit::StringBuilder]
+     100             : // ============================================================================
+     101             : 
+     102             : //! String builder.
+     103             : //!
+     104             : //! String builder was designed to be able to build a string using append like
+     105             : //! operation to append numbers, other strings, or signle characters. It can
+     106             : //! allocate it's own buffer or use a buffer created on the stack.
+     107             : //!
+     108             : //! String builder contains method specific to AsmJit functionality, used for
+     109             : //! logging or HTML output.
+     110             : class StringBuilder {
+     111             : public:
+     112             :   ASMJIT_NONCOPYABLE(StringBuilder)
+     113             : 
+     114             :   //! \internal
+     115             :   //!
+     116             :   //! String operation.
+     117             :   ASMJIT_ENUM(OpType) {
+     118             :     kStringOpSet = 0,                    //!< Replace the current string by a given content.
+     119             :     kStringOpAppend = 1                  //!< Append a given content to the current string.
+     120             :   };
+     121             : 
+     122             :   //! \internal
+     123             :   //!
+     124             :   //! String format flags.
+     125             :   ASMJIT_ENUM(StringFormatFlags) {
+     126             :     kStringFormatShowSign  = 0x00000001,
+     127             :     kStringFormatShowSpace = 0x00000002,
+     128             :     kStringFormatAlternate = 0x00000004,
+     129             :     kStringFormatSigned    = 0x80000000
+     130             :   };
+     131             : 
+     132             :   // --------------------------------------------------------------------------
+     133             :   // [Construction / Destruction]
+     134             :   // --------------------------------------------------------------------------
+     135             : 
+     136             :   ASMJIT_API StringBuilder() noexcept;
+     137             :   ASMJIT_API ~StringBuilder() noexcept;
+     138             : 
+     139        1948 :   ASMJIT_INLINE StringBuilder(const _NoInit&) noexcept {}
+     140             : 
+     141             :   // --------------------------------------------------------------------------
+     142             :   // [Accessors]
+     143             :   // --------------------------------------------------------------------------
+     144             : 
+     145             :   //! Get string builder capacity.
+     146             :   ASMJIT_INLINE size_t getCapacity() const noexcept { return _capacity; }
+     147             :   //! Get length.
+     148           0 :   ASMJIT_INLINE size_t getLength() const noexcept { return _length; }
+     149             : 
+     150             :   //! Get null-terminated string data.
+     151           0 :   ASMJIT_INLINE char* getData() noexcept { return _data; }
+     152             :   //! Get null-terminated string data (const).
+     153             :   ASMJIT_INLINE const char* getData() const noexcept { return _data; }
+     154             : 
+     155             :   // --------------------------------------------------------------------------
+     156             :   // [Prepare / Reserve]
+     157             :   // --------------------------------------------------------------------------
+     158             : 
+     159             :   //! Prepare to set/append.
+     160             :   ASMJIT_API char* prepare(uint32_t op, size_t len) noexcept;
+     161             : 
+     162             :   //! Reserve `to` bytes in string builder.
+     163             :   ASMJIT_API Error reserve(size_t to) noexcept;
+     164             : 
+     165             :   // --------------------------------------------------------------------------
+     166             :   // [Clear]
+     167             :   // --------------------------------------------------------------------------
+     168             : 
+     169             :   //! Clear the content in String builder.
+     170             :   ASMJIT_API void clear() noexcept;
+     171             : 
+     172             :   // --------------------------------------------------------------------------
+     173             :   // [Op]
+     174             :   // --------------------------------------------------------------------------
+     175             : 
+     176             :   ASMJIT_API Error _opString(uint32_t op, const char* str, size_t len = Globals::kInvalidIndex) noexcept;
+     177             :   ASMJIT_API Error _opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept;
+     178             :   ASMJIT_API Error _opChar(uint32_t op, char c) noexcept;
+     179             :   ASMJIT_API Error _opChars(uint32_t op, char c, size_t n) noexcept;
+     180             :   ASMJIT_API Error _opNumber(uint32_t op, uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept;
+     181             :   ASMJIT_API Error _opHex(uint32_t op, const void* data, size_t len) noexcept;
+     182             : 
+     183             :   // --------------------------------------------------------------------------
+     184             :   // [Set]
+     185             :   // --------------------------------------------------------------------------
+     186             : 
+     187             :   //! Replace the current string with `str` having `len` characters (or `kInvalidIndex` if it's null terminated).
+     188             :   ASMJIT_INLINE Error setString(const char* str, size_t len = Globals::kInvalidIndex) noexcept { return _opString(kStringOpSet, str, len); }
+     189             :   //! Replace the current content by a formatted string `fmt`.
+     190             :   ASMJIT_API Error setFormat(const char* fmt, ...) noexcept;
+     191             :   //! Replace the current content by a formatted string `fmt` (va_list version).
+     192             :   ASMJIT_INLINE Error setFormatVA(const char* fmt, va_list ap) noexcept { return _opVFormat(kStringOpSet, fmt, ap); }
+     193             : 
+     194             :   //! Replace the current content by a single `c` character.
+     195             :   ASMJIT_INLINE Error setChar(char c) noexcept { return _opChar(kStringOpSet, c); }
+     196             :   //! Replace the current content by `c` character `n` times.
+     197             :   ASMJIT_INLINE Error setChars(char c, size_t n) noexcept { return _opChars(kStringOpSet, c, n); }
+     198             : 
+     199             :   //! Replace the current content by a formatted integer `i` (signed).
+     200             :   ASMJIT_INLINE Error setInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
+     201             :     return _opNumber(kStringOpSet, i, base, width, flags | kStringFormatSigned);
+     202             :   }
+     203             : 
+     204             :   //! Replace the current content by a formatted integer `i` (unsigned).
+     205             :   ASMJIT_INLINE Error setUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
+     206             :     return _opNumber(kStringOpSet, i, base, width, flags);
+     207             :   }
+     208             : 
+     209             :   //! Replace the current content by the given `data` converted to a HEX string.
+     210             :   ASMJIT_INLINE Error setHex(const void* data, size_t len) noexcept {
+     211             :     return _opHex(kStringOpSet, data, len);
+     212             :   }
+     213             : 
+     214             :   // --------------------------------------------------------------------------
+     215             :   // [Append]
+     216             :   // --------------------------------------------------------------------------
+     217             : 
+     218             :   //! Append string `str` having `len` characters (or `kInvalidIndex` if it's null terminated).
+     219           0 :   ASMJIT_INLINE Error appendString(const char* str, size_t len = Globals::kInvalidIndex) noexcept { return _opString(kStringOpAppend, str, len); }
+     220             :   //! Append a formatted string `fmt`.
+     221             :   ASMJIT_API Error appendFormat(const char* fmt, ...) noexcept;
+     222             :   //! Append a formatted string `fmt` (va_list version).
+     223           0 :   ASMJIT_INLINE Error appendFormatVA(const char* fmt, va_list ap) noexcept { return _opVFormat(kStringOpAppend, fmt, ap); }
+     224             : 
+     225             :   //! Append a single `c` character.
+     226           0 :   ASMJIT_INLINE Error appendChar(char c) noexcept { return _opChar(kStringOpAppend, c); }
+     227             :   //! Append `c` character `n` times.
+     228           0 :   ASMJIT_INLINE Error appendChars(char c, size_t n) noexcept { return _opChars(kStringOpAppend, c, n); }
+     229             : 
+     230             :   //! Append `i`.
+     231             :   ASMJIT_INLINE Error appendInt(int64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
+     232           0 :     return _opNumber(kStringOpAppend, static_cast<uint64_t>(i), base, width, flags | kStringFormatSigned);
+     233             :   }
+     234             : 
+     235             :   //! Append `i`.
+     236             :   ASMJIT_INLINE Error appendUInt(uint64_t i, uint32_t base = 0, size_t width = 0, uint32_t flags = 0) noexcept {
+     237           0 :     return _opNumber(kStringOpAppend, i, base, width, flags);
+     238             :   }
+     239             : 
+     240             :   //! Append the given `data` converted to a HEX string.
+     241             :   ASMJIT_INLINE Error appendHex(const void* data, size_t len) noexcept {
+     242           0 :     return _opHex(kStringOpAppend, data, len);
+     243             :   }
+     244             : 
+     245             :   // --------------------------------------------------------------------------
+     246             :   // [Eq]
+     247             :   // --------------------------------------------------------------------------
+     248             : 
+     249             :   //! Check for equality with other `str` of length `len`.
+     250             :   ASMJIT_API bool eq(const char* str, size_t len = Globals::kInvalidIndex) const noexcept;
+     251             :   //! Check for equality with `other`.
+     252             :   ASMJIT_INLINE bool eq(const StringBuilder& other) const noexcept { return eq(other._data, other._length); }
+     253             : 
+     254             :   // --------------------------------------------------------------------------
+     255             :   // [Operator Overload]
+     256             :   // --------------------------------------------------------------------------
+     257             : 
+     258             :   ASMJIT_INLINE bool operator==(const StringBuilder& other) const noexcept { return  eq(other); }
+     259             :   ASMJIT_INLINE bool operator!=(const StringBuilder& other) const noexcept { return !eq(other); }
+     260             : 
+     261             :   ASMJIT_INLINE bool operator==(const char* str) const noexcept { return  eq(str); }
+     262             :   ASMJIT_INLINE bool operator!=(const char* str) const noexcept { return !eq(str); }
+     263             : 
+     264             :   // --------------------------------------------------------------------------
+     265             :   // [Members]
+     266             :   // --------------------------------------------------------------------------
+     267             : 
+     268             :   char* _data;                           //!< String data.
+     269             :   size_t _length;                        //!< String length.
+     270             :   size_t _capacity;                      //!< String capacity.
+     271             :   size_t _canFree;                       //!< If the string data can be freed.
+     272             : };
+     273             : 
+     274             : // ============================================================================
+     275             : // [asmjit::StringBuilderTmp]
+     276             : // ============================================================================
+     277             : 
+     278             : //! Temporary string builder, has statically allocated `N` bytes.
+     279             : template<size_t N>
+     280           0 : class StringBuilderTmp : public StringBuilder {
+     281             : public:
+     282             :   ASMJIT_NONCOPYABLE(StringBuilderTmp<N>)
+     283             : 
+     284             :   // --------------------------------------------------------------------------
+     285             :   // [Construction / Destruction]
+     286             :   // --------------------------------------------------------------------------
+     287             : 
+     288        1948 :   ASMJIT_INLINE StringBuilderTmp() noexcept : StringBuilder(NoInit) {
+     289        1948 :     _data = _embeddedData;
+     290        1948 :     _data[0] = 0;
+     291             : 
+     292        1948 :     _length = 0;
+     293        1948 :     _capacity = N;
+     294           0 :     _canFree = false;
+     295             :   }
+     296             : 
+     297             :   // --------------------------------------------------------------------------
+     298             :   // [Members]
+     299             :   // --------------------------------------------------------------------------
+     300             : 
+     301             :   //! Embedded data.
+     302             :   char _embeddedData[static_cast<size_t>(
+     303             :     N + 1 + sizeof(intptr_t)) & ~static_cast<size_t>(sizeof(intptr_t) - 1)];
+     304             : };
+     305             : 
+     306             : //! \}
+     307             : 
+     308             : } // asmjit namespace
+     309             : } // namespace PLMD
+     310             : 
+     311             : // [Api-End]
+     312             : #include "./asmjit_apiend.h"
+     313             : 
+     314             : // [Guard]
+     315             : #endif // _ASMJIT_BASE_STRING_H
+     316             : #pragma GCC diagnostic pop
+     317             : #endif // __PLUMED_HAS_ASMJIT
+     318             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/operand.h.func-sort-c.html b/coverage-libs/asmjit/operand.h.func-sort-c.html new file mode 100644 index 000000000000..d2af4ab78230 --- /dev/null +++ b/coverage-libs/asmjit/operand.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/operand.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:499054.4 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/operand.h.func.html b/coverage-libs/asmjit/operand.h.func.html new file mode 100644 index 000000000000..7a4f01409e71 --- /dev/null +++ b/coverage-libs/asmjit/operand.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/operand.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:499054.4 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/operand.h.gcov.html b/coverage-libs/asmjit/operand.h.gcov.html new file mode 100644 index 000000000000..93c2d41fdbf2 --- /dev/null +++ b/coverage-libs/asmjit/operand.h.gcov.html @@ -0,0 +1,1676 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/operand.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:499054.4 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_operand_h
+      21             : #define __PLUMED_asmjit_operand_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_OPERAND_H
+      33             : #define _ASMJIT_BASE_OPERAND_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./utils.h"
+      37             : 
+      38             : // [Api-Begin]
+      39             : #include "./asmjit_apibegin.h"
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace asmjit {
+      43             : 
+      44             : //! \addtogroup asmjit_base
+      45             : //! \{
+      46             : 
+      47             : // ============================================================================
+      48             : // [asmjit::Operand_]
+      49             : // ============================================================================
+      50             : 
+      51             : //! Constructor-less \ref Operand.
+      52             : //!
+      53             : //! Contains no initialization code and can be used safely to define an array
+      54             : //! of operands that won't be initialized. This is a \ref Operand compatible
+      55             : //! data structure designed to be statically initialized or `static const`.
+      56             : struct Operand_ {
+      57             :   // --------------------------------------------------------------------------
+      58             :   // [Operand Type]
+      59             :   // --------------------------------------------------------------------------
+      60             : 
+      61             :   //! Operand types that can be encoded in \ref Operand.
+      62             :   ASMJIT_ENUM(OpType) {
+      63             :     kOpNone  = 0,                        //!< Not an operand or not initialized.
+      64             :     kOpReg   = 1,                        //!< Operand is a register.
+      65             :     kOpMem   = 2,                        //!< Operand is a memory.
+      66             :     kOpImm   = 3,                        //!< Operand is an immediate value.
+      67             :     kOpLabel = 4                         //!< Operand is a label.
+      68             :   };
+      69             : 
+      70             :   // --------------------------------------------------------------------------
+      71             :   // [Operand Signature (Bits)]
+      72             :   // --------------------------------------------------------------------------
+      73             : 
+      74             :   ASMJIT_ENUM(SignatureBits) {
+      75             :     // Operand type (3 least significant bits).
+      76             :     // |........|........|........|.....XXX|
+      77             :     kSignatureOpShift           = 0,
+      78             :     kSignatureOpBits            = 0x07U,
+      79             :     kSignatureOpMask            = kSignatureOpBits << kSignatureOpShift,
+      80             : 
+      81             :     // Operand size (8 most significant bits).
+      82             :     // |XXXXXXXX|........|........|........|
+      83             :     kSignatureSizeShift         = 24,
+      84             :     kSignatureSizeBits          = 0xFFU,
+      85             :     kSignatureSizeMask          = kSignatureSizeBits << kSignatureSizeShift,
+      86             : 
+      87             :     // Register type (5 bits).
+      88             :     // |........|........|........|XXXXX...|
+      89             :     kSignatureRegTypeShift      = 3,
+      90             :     kSignatureRegTypeBits       = 0x1FU,
+      91             :     kSignatureRegTypeMask       = kSignatureRegTypeBits << kSignatureRegTypeShift,
+      92             : 
+      93             :     // Register kind (4 bits).
+      94             :     // |........|........|....XXXX|........|
+      95             :     kSignatureRegKindShift      = 8,
+      96             :     kSignatureRegKindBits       = 0x0FU,
+      97             :     kSignatureRegKindMask       = kSignatureRegKindBits << kSignatureRegKindShift,
+      98             : 
+      99             :     // Memory base type (5 bits).
+     100             :     // |........|........|........|XXXXX...|
+     101             :     kSignatureMemBaseTypeShift  = 3,
+     102             :     kSignatureMemBaseTypeBits   = 0x1FU,
+     103             :     kSignatureMemBaseTypeMask   = kSignatureMemBaseTypeBits << kSignatureMemBaseTypeShift,
+     104             : 
+     105             :     // Memory index type (5 bits).
+     106             :     // |........|........|...XXXXX|........|
+     107             :     kSignatureMemIndexTypeShift = 8,
+     108             :     kSignatureMemIndexTypeBits  = 0x1FU,
+     109             :     kSignatureMemIndexTypeMask  = kSignatureMemIndexTypeBits << kSignatureMemIndexTypeShift,
+     110             : 
+     111             :     // Memory base+index combined (10 bits).
+     112             :     // |........|........|...XXXXX|XXXXX...|
+     113             :     kSignatureMemBaseIndexShift = 3,
+     114             :     kSignatureMemBaseIndexBits  = 0x3FFU,
+     115             :     kSignatureMemBaseIndexMask  = kSignatureMemBaseIndexBits << kSignatureMemBaseIndexShift,
+     116             : 
+     117             :     // Memory should be encoded as absolute immediate (X86|X64).
+     118             :     // |........|........|.XX.....|........|
+     119             :     kSignatureMemAddrTypeShift  = 13,
+     120             :     kSignatureMemAddrTypeBits   = 0x03U,
+     121             :     kSignatureMemAddrTypeMask   = kSignatureMemAddrTypeBits << kSignatureMemAddrTypeShift,
+     122             : 
+     123             :     // This memory operand represents a function argument's stack location (CodeCompiler)
+     124             :     // |........|........|.X......|........|
+     125             :     kSignatureMemArgHomeShift   = 15,
+     126             :     kSignatureMemArgHomeBits    = 0x01U,
+     127             :     kSignatureMemArgHomeFlag    = kSignatureMemArgHomeBits << kSignatureMemArgHomeShift,
+     128             : 
+     129             :     // This memory operand represents a virtual register's home-slot (CodeCompiler).
+     130             :     // |........|........|X.......|........|
+     131             :     kSignatureMemRegHomeShift   = 16,
+     132             :     kSignatureMemRegHomeBits    = 0x01U,
+     133             :     kSignatureMemRegHomeFlag    = kSignatureMemRegHomeBits << kSignatureMemRegHomeShift
+     134             :   };
+     135             : 
+     136             :   // --------------------------------------------------------------------------
+     137             :   // [Operand Id]
+     138             :   // --------------------------------------------------------------------------
+     139             : 
+     140             :   //! Operand id helpers useful for id <-> index translation.
+     141             :   ASMJIT_ENUM(PackedId) {
+     142             :     //! Minimum valid packed-id.
+     143             :     kPackedIdMin    = 0x00000100U,
+     144             :     //! Maximum valid packed-id.
+     145             :     kPackedIdMax    = 0xFFFFFFFFU,
+     146             :     //! Count of valid packed-ids.
+     147             :     kPackedIdCount  = kPackedIdMax - kPackedIdMin + 1
+     148             :   };
+     149             : 
+     150             :   // --------------------------------------------------------------------------
+     151             :   // [Operand Utilities]
+     152             :   // --------------------------------------------------------------------------
+     153             : 
+     154             :   //! Get if the given `id` is a valid packed-id that can be used by Operand.
+     155             :   //! Packed ids are those equal or greater than `kPackedIdMin` and lesser or
+     156             :   //! equal to `kPackedIdMax`. This concept was created to support virtual
+     157             :   //! registers and to make them distinguishable from physical ones. It allows
+     158             :   //! a single uint32_t to contain either physical register id or virtual
+     159             :   //! register id represented as `packed-id`. This concept is used also for
+     160             :   //! labels to make the API consistent.
+     161      124078 :   static ASMJIT_INLINE bool isPackedId(uint32_t id) noexcept { return id - kPackedIdMin < kPackedIdCount; }
+     162             :   //! Convert a real-id into a packed-id that can be stored in Operand.
+     163       27684 :   static ASMJIT_INLINE uint32_t packId(uint32_t id) noexcept { return id + kPackedIdMin; }
+     164             :   //! Convert a packed-id back to real-id.
+     165       13892 :   static ASMJIT_INLINE uint32_t unpackId(uint32_t id) noexcept { return id - kPackedIdMin; }
+     166             : 
+     167             :   // --------------------------------------------------------------------------
+     168             :   // [Operand Data]
+     169             :   // --------------------------------------------------------------------------
+     170             : 
+     171             :   //! Any operand.
+     172             :   struct AnyData {
+     173             :     uint32_t signature;                  //!< Type of the operand (see \ref OpType) and other data.
+     174             :     uint32_t id;                         //!< Operand id or `0`.
+     175             :     uint32_t reserved8_4;                //!< \internal
+     176             :     uint32_t reserved12_4;               //!< \internal
+     177             :   };
+     178             : 
+     179             :   //! Register operand data.
+     180             :   struct RegData {
+     181             :     uint32_t signature;                  //!< Type of the operand (always \ref kOpReg) and other data.
+     182             :     uint32_t id;                         //!< Physical or virtual register id.
+     183             :     uint32_t reserved8_4;                //!< \internal
+     184             :     uint32_t reserved12_4;               //!< \internal
+     185             :   };
+     186             : 
+     187             :   //! Memory operand data.
+     188             :   struct MemData {
+     189             :     uint32_t signature;                  //!< Type of the operand (always \ref kOpMem) and other data.
+     190             :     uint32_t index;                      //!< INDEX register id or `0`.
+     191             : 
+     192             :     // [BASE + OFF32] vs just [OFF64].
+     193             :     union {
+     194             :       uint64_t offset64;                 //!< 64-bit offset, combining low and high 32-bit parts.
+     195             :       struct {
+     196             : #if ASMJIT_ARCH_LE
+     197             :         uint32_t offsetLo32;             //!< 32-bit low offset part.
+     198             :         uint32_t base;                   //!< 32-bit high offset part or BASE.
+     199             : #else
+     200             :         uint32_t base;                   //!< 32-bit high offset part or BASE.
+     201             :         uint32_t offsetLo32;             //!< 32-bit low offset part.
+     202             : #endif
+     203             :       };
+     204             :     };
+     205             :   };
+     206             : 
+     207             :   //! Immediate operand data.
+     208             :   struct ImmData {
+     209             :     uint32_t signature;                  //!< Type of the operand (always \ref kOpImm) and other data.
+     210             :     uint32_t id;                         //!< Immediate id (always `0`).
+     211             :     UInt64 value;                        //!< Immediate value.
+     212             :   };
+     213             : 
+     214             :   //! Label operand data.
+     215             :   struct LabelData {
+     216             :     uint32_t signature;                  //!< Type of the operand (always \ref kOpLabel) and other data.
+     217             :     uint32_t id;                         //!< Label id (`0` if not initialized).
+     218             :     uint32_t reserved8_4;                //!< \internal
+     219             :     uint32_t reserved12_4;               //!< \internal
+     220             :   };
+     221             : 
+     222             :   // --------------------------------------------------------------------------
+     223             :   // [Init & Copy]
+     224             :   // --------------------------------------------------------------------------
+     225             : 
+     226             :   //! \internal
+     227             :   //!
+     228             :   //! Initialize the operand to `other` (used by constructors).
+     229             :   ASMJIT_INLINE void _init(const Operand_& other) noexcept { ::memcpy(this, &other, sizeof(Operand_)); }
+     230             : 
+     231             :   //! \internal
+     232             :   ASMJIT_INLINE void _initReg(uint32_t signature, uint32_t rd) {
+     233             :     _init_packed_d0_d1(signature, rd);
+     234             :     _init_packed_d2_d3(0, 0);
+     235             :   }
+     236             : 
+     237             :   //! \internal
+     238             :   ASMJIT_INLINE void _init_packed_d0_d1(uint32_t d0, uint32_t d1) noexcept { _packed[0].setPacked_2x32(d0, d1); }
+     239             :   //! \internal
+     240             :   ASMJIT_INLINE void _init_packed_d2_d3(uint32_t d2, uint32_t d3) noexcept { _packed[1].setPacked_2x32(d2, d3); }
+     241             : 
+     242             :   //! \internal
+     243             :   //!
+     244             :   //! Initialize the operand from `other` (used by operator overloads).
+     245       87412 :   ASMJIT_INLINE void copyFrom(const Operand_& other) noexcept { ::memcpy(this, &other, sizeof(Operand_)); }
+     246             : 
+     247             :   // --------------------------------------------------------------------------
+     248             :   // [Accessors]
+     249             :   // --------------------------------------------------------------------------
+     250             : 
+     251             :   //! Get if the operand matches the given signature `sign`.
+     252           0 :   ASMJIT_INLINE bool hasSignature(uint32_t signature) const noexcept { return _signature == signature; }
+     253             : 
+     254             :   //! Get if the operand matches a signature of the `other` operand.
+     255             :   ASMJIT_INLINE bool hasSignature(const Operand_& other) const noexcept {
+     256             :     return _signature == other.getSignature();
+     257             :   }
+     258             : 
+     259             :   //! Get a 32-bit operand signature.
+     260             :   //!
+     261             :   //! Signature is first 4 bytes of the operand data. It's used mostly for
+     262             :   //! operand checking as it's much faster to check 4 bytes at once than having
+     263             :   //! to check these bytes individually.
+     264           0 :   ASMJIT_INLINE uint32_t getSignature() const noexcept { return _signature; }
+     265             : 
+     266             :   //! Set the operand signature (see \ref getSignature).
+     267             :   //!
+     268             :   //! Improper use of `setSignature()` can lead to hard-to-debug errors.
+     269         420 :   ASMJIT_INLINE void setSignature(uint32_t signature) noexcept { _signature = signature; }
+     270             : 
+     271       41256 :   ASMJIT_INLINE bool _hasSignatureData(uint32_t bits) const noexcept { return (_signature & bits) != 0; }
+     272             : 
+     273             :   //! \internal
+     274             :   //!
+     275             :   //! Unpacks information from operand's signature.
+     276      297664 :   ASMJIT_INLINE uint32_t _getSignatureData(uint32_t bits, uint32_t shift) const noexcept { return (_signature >> shift) & bits; }
+     277             : 
+     278             :   //! \internal
+     279             :   //!
+     280             :   //! Packs information to operand's signature.
+     281             :   ASMJIT_INLINE void _setSignatureData(uint32_t value, uint32_t bits, uint32_t shift) noexcept {
+     282             :     ASMJIT_ASSERT(value <= bits);
+     283        8428 :     _signature = (_signature & ~(bits << shift)) | (value << shift);
+     284             :   }
+     285             : 
+     286             :   ASMJIT_INLINE void _addSignatureData(uint32_t data) noexcept { _signature |= data; }
+     287             : 
+     288             :   //! Clears specified bits in operand's signature.
+     289             :   ASMJIT_INLINE void _clearSignatureData(uint32_t bits, uint32_t shift) noexcept { _signature &= ~(bits << shift); }
+     290             : 
+     291             :   //! Get type of the operand, see \ref OpType.
+     292             :   ASMJIT_INLINE uint32_t getOp() const noexcept { return _getSignatureData(kSignatureOpBits, kSignatureOpShift); }
+     293             :   //! Get if the operand is none (\ref kOpNone).
+     294             :   ASMJIT_INLINE bool isNone() const noexcept { return getOp() == 0; }
+     295             :   //! Get if the operand is a register (\ref kOpReg).
+     296             :   ASMJIT_INLINE bool isReg() const noexcept { return getOp() == kOpReg; }
+     297             :   //! Get if the operand is a memory location (\ref kOpMem).
+     298             :   ASMJIT_INLINE bool isMem() const noexcept { return getOp() == kOpMem; }
+     299             :   //! Get if the operand is an immediate (\ref kOpImm).
+     300             :   ASMJIT_INLINE bool isImm() const noexcept { return getOp() == kOpImm; }
+     301             :   //! Get if the operand is a label (\ref kOpLabel).
+     302             :   ASMJIT_INLINE bool isLabel() const noexcept { return getOp() == kOpLabel; }
+     303             : 
+     304             :   //! Get if the operand is a physical register.
+     305             :   ASMJIT_INLINE bool isPhysReg() const noexcept { return isReg() && _reg.id < Globals::kInvalidRegId; }
+     306             :   //! Get if the operand is a virtual register.
+     307      146394 :   ASMJIT_INLINE bool isVirtReg() const noexcept { return isReg() && isPackedId(_reg.id); }
+     308             : 
+     309             :   //! Get if the operand specifies a size (i.e. the size is not zero).
+     310             :   ASMJIT_INLINE bool hasSize() const noexcept { return _hasSignatureData(kSignatureSizeMask); }
+     311             :   //! Get if the size of the operand matches `size`.
+     312             :   ASMJIT_INLINE bool hasSize(uint32_t size) const noexcept { return getSize() == size; }
+     313             : 
+     314             :   //! Get size of the operand (in bytes).
+     315             :   //!
+     316             :   //! The value returned depends on the operand type:
+     317             :   //!   * None  - Should always return zero size.
+     318             :   //!   * Reg   - Should always return the size of the register. If the register
+     319             :   //!             size depends on architecture (like \ref X86CReg and \ref X86DReg)
+     320             :   //!             the size returned should be the greatest possible (so it should
+     321             :   //!             return 64-bit size in such case).
+     322             :   //!   * Mem   - Size is optional and will be in most cases zero.
+     323             :   //!   * Imm   - Should always return zero size.
+     324             :   //!   * Label - Should always return zero size.
+     325             :   ASMJIT_INLINE uint32_t getSize() const noexcept { return _getSignatureData(kSignatureSizeBits, kSignatureSizeShift); }
+     326             : 
+     327             :   //! Get the operand id.
+     328             :   //!
+     329             :   //! The value returned should be interpreted accordingly to the operand type:
+     330             :   //!   * None  - Should be `0`.
+     331             :   //!   * Reg   - Physical or virtual register id.
+     332             :   //!   * Mem   - Multiple meanings - BASE address (register or label id), or
+     333             :   //!             high value of a 64-bit absolute address.
+     334             :   //!   * Imm   - Should be `0`.
+     335             :   //!   * Label - Label id if it was created by using `newLabel()` or `0`
+     336             :   //!             if the label is invalid or uninitialized.
+     337       54546 :   ASMJIT_INLINE uint32_t getId() const noexcept { return _any.id; }
+     338             : 
+     339             :   //! Get if the operand is 100% equal to `other`.
+     340             :   ASMJIT_INLINE bool isEqual(const Operand_& other) const noexcept {
+     341             :     return (_packed[0] == other._packed[0]) &
+     342             :            (_packed[1] == other._packed[1]) ;
+     343             :   }
+     344             : 
+     345             :   //! Get if the operand is a register matching `rType`.
+     346             :   ASMJIT_INLINE bool isReg(uint32_t rType) const noexcept {
+     347             :     const uint32_t kMsk = (kSignatureOpBits << kSignatureOpShift) | (kSignatureRegTypeBits << kSignatureRegTypeShift);
+     348             :     const uint32_t kSgn = (kOpReg           << kSignatureOpShift) | (rType                 << kSignatureRegTypeShift);
+     349             :     return (_signature & kMsk) == kSgn;
+     350             :   }
+     351             : 
+     352             :   //! Get whether the operand is register and of `type` and `id`.
+     353             :   ASMJIT_INLINE bool isReg(uint32_t rType, uint32_t rId) const noexcept {
+     354             :     return isReg(rType) && getId() == rId;
+     355             :   }
+     356             : 
+     357             :   //! Get whether the operand is a register or memory.
+     358             :   ASMJIT_INLINE bool isRegOrMem() const noexcept {
+     359             :     ASMJIT_ASSERT(kOpMem - kOpReg == 1);
+     360             :     return Utils::inInterval<uint32_t>(getOp(), kOpReg, kOpMem);
+     361             :   }
+     362             : 
+     363             :   //! Cast this operand to `T` type.
+     364             :   template<typename T>
+     365             :   ASMJIT_INLINE T& as() noexcept { return static_cast<T&>(*this); }
+     366             :   //! Cast this operand to `T` type (const).
+     367             :   template<typename T>
+     368             :   ASMJIT_INLINE const T& as() const noexcept { return static_cast<const T&>(*this); }
+     369             : 
+     370             :   // --------------------------------------------------------------------------
+     371             :   // [Reset]
+     372             :   // --------------------------------------------------------------------------
+     373             : 
+     374             :   //! Reset the `Operand` to none.
+     375             :   //!
+     376             :   //! None operand is defined the following way:
+     377             :   //!   - Its signature is zero (kOpNone, and the rest zero as well).
+     378             :   //!   - Its id is `0`.
+     379             :   //!   - The reserved8_4 field is set to `0`.
+     380             :   //!   - The reserved12_4 field is set to zero.
+     381             :   //!
+     382             :   //! In other words, reset operands have all members set to zero. Reset operand
+     383             :   //! must match the Operand state right after its construction. Alternatively,
+     384             :   //! if you have an array of operands, you can simply use `memset()`.
+     385             :   //!
+     386             :   //! ```
+     387             :   //! using namespace asmjit;
+     388             :   //!
+     389             :   //! Operand a;
+     390             :   //! Operand b;
+     391             :   //! assert(a == b);
+     392             :   //!
+     393             :   //! b = x86::eax;
+     394             :   //! assert(a != b);
+     395             :   //!
+     396             :   //! b.reset();
+     397             :   //! assert(a == b);
+     398             :   //!
+     399             :   //! memset(&b, 0, sizeof(Operand));
+     400             :   //! assert(a == b);
+     401             :   //! ```
+     402             :   ASMJIT_INLINE void reset() noexcept {
+     403             :     _init_packed_d0_d1(kOpNone, 0);
+     404             :     _init_packed_d2_d3(0, 0);
+     405           0 :   }
+     406             : 
+     407             :   // --------------------------------------------------------------------------
+     408             :   // [Operator Overload]
+     409             :   // --------------------------------------------------------------------------
+     410             : 
+     411             :   template<typename T>
+     412             :   ASMJIT_INLINE bool operator==(const T& other) const noexcept { return  isEqual(other); }
+     413             :   template<typename T>
+     414             :   ASMJIT_INLINE bool operator!=(const T& other) const noexcept { return !isEqual(other); }
+     415             : 
+     416             :   // --------------------------------------------------------------------------
+     417             :   // [Members]
+     418             :   // --------------------------------------------------------------------------
+     419             : 
+     420             :   union {
+     421             :     AnyData _any;                        //!< Generic data.
+     422             :     RegData _reg;                        //!< Physical or virtual register data.
+     423             :     MemData _mem;                        //!< Memory address data.
+     424             :     ImmData _imm;                        //!< Immediate value data.
+     425             :     LabelData _label;                    //!< Label data.
+     426             : 
+     427             :     uint32_t _signature;                 //!< Operand signature (first 32-bits).
+     428             :     UInt64 _packed[2];                   //!< Operand packed into two 64-bit integers.
+     429             :   };
+     430             : };
+     431             : 
+     432             : // ============================================================================
+     433             : // [asmjit::Operand]
+     434             : // ============================================================================
+     435             : 
+     436             : //! Operand can contain register, memory location, immediate, or label.
+     437             : class Operand : public Operand_ {
+     438             : public:
+     439             :   // --------------------------------------------------------------------------
+     440             :   // [Construction / Destruction]
+     441             :   // --------------------------------------------------------------------------
+     442             : 
+     443             :   //! Create an uninitialized operand.
+     444       24732 :   ASMJIT_INLINE Operand() noexcept { reset(); }
+     445             :   //! Create a reference to `other` operand.
+     446        4316 :   ASMJIT_INLINE Operand(const Operand& other) noexcept { _init(other); }
+     447             :   //! Create a reference to `other` operand.
+     448        9084 :   explicit ASMJIT_INLINE Operand(const Operand_& other) noexcept { _init(other); }
+     449             :   //! Create a completely uninitialized operand (dangerous).
+     450        1984 :   explicit ASMJIT_INLINE Operand(const _NoInit&) noexcept {}
+     451             : 
+     452             :   // --------------------------------------------------------------------------
+     453             :   // [Clone]
+     454             :   // --------------------------------------------------------------------------
+     455             : 
+     456             :   //! Clone the `Operand`.
+     457             :   ASMJIT_INLINE Operand clone() const noexcept { return Operand(*this); }
+     458             : 
+     459             :   ASMJIT_INLINE Operand& operator=(const Operand_& other) noexcept { copyFrom(other); return *this; }
+     460             : };
+     461             : 
+     462             : // ============================================================================
+     463             : // [asmjit::Label]
+     464             : // ============================================================================
+     465             : 
+     466             : //! Label (jump target or data location).
+     467             : //!
+     468             : //! Label represents a location in code typically used as a jump target, but
+     469             : //! may be also a reference to some data or a static variable. Label has to be
+     470             : //! explicitly created by CodeEmitter.
+     471             : //!
+     472             : //! Example of using labels:
+     473             : //!
+     474             : //! ~~~
+     475             : //! // Create a CodeEmitter (for example X86Assembler).
+     476             : //! X86Assembler a;
+     477             : //!
+     478             : //! // Create Label instance.
+     479             : //! Label L1 = a.newLabel();
+     480             : //!
+     481             : //! // ... your code ...
+     482             : //!
+     483             : //! // Using label.
+     484             : //! a.jump(L1);
+     485             : //!
+     486             : //! // ... your code ...
+     487             : //!
+     488             : //! // Bind label to the current position, see `CodeEmitter::bind()`.
+     489             : //! a.bind(L1);
+     490             : //! ~~~
+     491             : class Label : public Operand {
+     492             : public:
+     493             :   //! Type of the Label.
+     494             :   enum Type {
+     495             :     kTypeAnonymous = 0,                  //!< Anonymous (unnamed) label.
+     496             :     kTypeLocal     = 1,                  //!< Local label (always has parentId).
+     497             :     kTypeGlobal    = 2,                  //!< Global label (never has parentId).
+     498             :     kTypeCount     = 3                   //!< Number of label types.
+     499             :   };
+     500             : 
+     501             :   // TODO: Find a better place, find a better name.
+     502             :   enum {
+     503             :     //! Label tag is used as a sub-type, forming a unique signature across all
+     504             :     //! operand types as 0x1 is never associated with any register (reg-type).
+     505             :     //! This means that a memory operand's BASE register can be constructed
+     506             :     //! from virtually any operand (register vs. label) by just assigning its
+     507             :     //! type (reg type or label-tag) and operand id.
+     508             :     kLabelTag = 0x1
+     509             :   };
+     510             : 
+     511             :   // --------------------------------------------------------------------------
+     512             :   // [Construction / Destruction]
+     513             :   // --------------------------------------------------------------------------
+     514             : 
+     515             :   //! Create new, unassociated label.
+     516             :   ASMJIT_INLINE Label() noexcept : Operand(NoInit) { reset(); }
+     517             :   //! Create a reference to another label.
+     518             :   ASMJIT_INLINE Label(const Label& other) noexcept : Operand(other) {}
+     519             : 
+     520             :   explicit ASMJIT_INLINE Label(uint32_t id) noexcept : Operand(NoInit) {
+     521             :     _init_packed_d0_d1(kOpLabel, id);
+     522             :     _init_packed_d2_d3(0, 0);
+     523             :   }
+     524             : 
+     525             :   explicit ASMJIT_INLINE Label(const _NoInit&) noexcept : Operand(NoInit) {}
+     526             : 
+     527             :   // --------------------------------------------------------------------------
+     528             :   // [Reset]
+     529             :   // --------------------------------------------------------------------------
+     530             : 
+     531             :   // TODO: I think that if operand is reset it shouldn't say it's a Label, it
+     532             :   // should be none like all other operands.
+     533             :   ASMJIT_INLINE void reset() noexcept {
+     534             :     _init_packed_d0_d1(kOpLabel, 0);
+     535             :     _init_packed_d2_d3(0, 0);
+     536             :   }
+     537             : 
+     538             :   // --------------------------------------------------------------------------
+     539             :   // [Label Specific]
+     540             :   // --------------------------------------------------------------------------
+     541             : 
+     542             :   //! Get if the label was created by CodeEmitter and has an assigned id.
+     543             :   ASMJIT_INLINE bool isValid() const noexcept { return _label.id != 0; }
+     544             :   //! Set label id.
+     545             :   ASMJIT_INLINE void setId(uint32_t id) { _label.id = id; }
+     546             : 
+     547             :   // --------------------------------------------------------------------------
+     548             :   // [Operator Overload]
+     549             :   // --------------------------------------------------------------------------
+     550             : 
+     551             :   ASMJIT_INLINE Label& operator=(const Label& other) noexcept { copyFrom(other); return *this; }
+     552             : };
+     553             : 
+     554             : // ============================================================================
+     555             : // [asmjit::Reg]
+     556             : // ============================================================================
+     557             : 
+     558             : #define ASMJIT_DEFINE_REG_TRAITS(TRAITS_T, REG_T, TYPE, KIND, SIZE, COUNT, TYPE_ID) \
+     559             : template<>                                                                    \
+     560             : struct TRAITS_T < TYPE > {                                                    \
+     561             :   typedef REG_T Reg;                                                          \
+     562             :                                                                               \
+     563             :   enum {                                                                      \
+     564             :     kValid     = 1,                                                           \
+     565             :     kCount     = COUNT,                                                       \
+     566             :     kTypeId    = TYPE_ID,                                                     \
+     567             :                                                                               \
+     568             :     kType      = TYPE,                                                        \
+     569             :     kKind      = KIND,                                                        \
+     570             :     kSize      = SIZE,                                                        \
+     571             :     kSignature = (Operand::kOpReg << Operand::kSignatureOpShift     ) |       \
+     572             :                  (kType           << Operand::kSignatureRegTypeShift) |       \
+     573             :                  (kKind           << Operand::kSignatureRegKindShift) |       \
+     574             :                  (kSize           << Operand::kSignatureSizeShift   )         \
+     575             :   };                                                                          \
+     576             : }                                                                             \
+     577             : 
+     578             : #define ASMJIT_DEFINE_ABSTRACT_REG(REG_T, BASE_T)                             \
+     579             : public:                                                                       \
+     580             :   /*! Default constructor doesn't setup anything, it's like `Operand()`. */   \
+     581             :   ASMJIT_INLINE REG_T() ASMJIT_NOEXCEPT                                       \
+     582             :     : BASE_T() {}                                                             \
+     583             :                                                                               \
+     584             :   /*! Copy the `other` REG_T register operand. */                             \
+     585             :   ASMJIT_INLINE REG_T(const REG_T& other) ASMJIT_NOEXCEPT                     \
+     586             :     : BASE_T(other) {}                                                        \
+     587             :                                                                               \
+     588             :   /*! Copy the `other` REG_T register operand having its id set to `rId` */   \
+     589             :   ASMJIT_INLINE REG_T(const Reg& other, uint32_t rId) ASMJIT_NOEXCEPT         \
+     590             :     : BASE_T(other, rId) {}                                                   \
+     591             :                                                                               \
+     592             :   /*! Create a REG_T register operand based on `signature` and `rId`. */      \
+     593             :   ASMJIT_INLINE REG_T(const _Init& init, uint32_t signature, uint32_t rId) ASMJIT_NOEXCEPT \
+     594             :     : BASE_T(init, signature, rId) {}                                         \
+     595             :                                                                               \
+     596             :   /*! Create a completely uninitialized REG_T register operand (garbage). */  \
+     597             :   explicit ASMJIT_INLINE REG_T(const _NoInit&) ASMJIT_NOEXCEPT                \
+     598             :     : BASE_T(NoInit) {}                                                       \
+     599             :                                                                               \
+     600             :   /*! Clone the register operand. */                                          \
+     601             :   ASMJIT_INLINE REG_T clone() const ASMJIT_NOEXCEPT { return REG_T(*this); }  \
+     602             :                                                                               \
+     603             :   /*! Create a new register from register type and id. */                     \
+     604             :   static ASMJIT_INLINE REG_T fromTypeAndId(uint32_t rType, uint32_t rId) ASMJIT_NOEXCEPT { \
+     605             :     return REG_T(Init, signatureOf(rType), rId);                              \
+     606             :   }                                                                           \
+     607             :                                                                               \
+     608             :   /*! Create a new register from signature and id. */                         \
+     609             :   static ASMJIT_INLINE REG_T fromSignature(uint32_t signature, uint32_t rId) ASMJIT_NOEXCEPT { \
+     610             :     return REG_T(Init, signature, rId);                                       \
+     611             :   }                                                                           \
+     612             :                                                                               \
+     613             :   ASMJIT_INLINE REG_T& operator=(const REG_T& other) ASMJIT_NOEXCEPT {        \
+     614             :     copyFrom(other); return *this;                                            \
+     615             :   }
+     616             : 
+     617             : #define ASMJIT_DEFINE_FINAL_REG(REG_T, BASE_T, TRAITS_T)                      \
+     618             :   ASMJIT_DEFINE_ABSTRACT_REG(REG_T, BASE_T)                                   \
+     619             :                                                                               \
+     620             :   /*! Create a REG_T register with `id`. */                                   \
+     621             :   explicit ASMJIT_INLINE REG_T(uint32_t rId) ASMJIT_NOEXCEPT                  \
+     622             :     : BASE_T(Init, kSignature, rId) {}                                        \
+     623             :                                                                               \
+     624             :   enum {                                                                      \
+     625             :     kThisType  = TRAITS_T::kType,                                             \
+     626             :     kThisKind  = TRAITS_T::kKind,                                             \
+     627             :     kThisSize  = TRAITS_T::kSize,                                             \
+     628             :     kSignature = TRAITS_T::kSignature                                         \
+     629             :   };
+     630             : 
+     631             : //! Structure that contains core register information.
+     632             : //!
+     633             : //! This information is compatible with operand's signature (32-bit integer)
+     634             : //! and `RegInfo` just provides easy way to access it.
+     635             : struct RegInfo {
+     636             :   ASMJIT_INLINE uint32_t getSignature() const noexcept {
+     637       78684 :     return _signature;
+     638             :   }
+     639             : 
+     640             :   ASMJIT_INLINE uint32_t getOp() const noexcept {
+     641             :     return (_signature >> Operand::kSignatureOpShift) & Operand::kSignatureOpBits;
+     642             :   }
+     643             : 
+     644             :   ASMJIT_INLINE uint32_t getType() const noexcept {
+     645             :     return (_signature >> Operand::kSignatureRegTypeShift) & Operand::kSignatureRegTypeBits;
+     646             :   }
+     647             : 
+     648             :   ASMJIT_INLINE uint32_t getKind() const noexcept {
+     649      183032 :     return (_signature >> Operand::kSignatureRegKindShift) & Operand::kSignatureRegKindBits;
+     650             :   }
+     651             : 
+     652             :   ASMJIT_INLINE uint32_t getSize() const noexcept {
+     653             :     return (_signature >> Operand::kSignatureSizeShift) & Operand::kSignatureSizeBits;
+     654             :   }
+     655             : 
+     656             :   uint32_t _signature;
+     657             : };
+     658             : 
+     659             : //! Physical/Virtual register operand.
+     660             : class Reg : public Operand {
+     661             : public:
+     662             :   //! Architecture neutral register types.
+     663             :   //!
+     664             :   //! These must be reused by any platform that contains that types. All GP
+     665             :   //! and VEC registers are also allowed by design to be part of a BASE|INDEX
+     666             :   //! of a memory operand.
+     667             :   ASMJIT_ENUM(RegType) {
+     668             :     kRegNone      = 0,                   //!< No register - unused, invalid, multiple meanings.
+     669             :     // (1 is used as a LabelTag)
+     670             :     kRegGp8Lo     = 2,                   //!< 8-bit low general purpose register (X86).
+     671             :     kRegGp8Hi     = 3,                   //!< 8-bit high general purpose register (X86).
+     672             :     kRegGp16      = 4,                   //!< 16-bit general purpose register (X86).
+     673             :     kRegGp32      = 5,                   //!< 32-bit general purpose register (X86|ARM).
+     674             :     kRegGp64      = 6,                   //!< 64-bit general purpose register (X86|ARM).
+     675             :     kRegVec32     = 7,                   //!< 32-bit view of a vector register (ARM).
+     676             :     kRegVec64     = 8,                   //!< 64-bit view of a vector register (ARM).
+     677             :     kRegVec128    = 9,                   //!< 128-bit view of a vector register (X86|ARM).
+     678             :     kRegVec256    = 10,                  //!< 256-bit view of a vector register (X86).
+     679             :     kRegVec512    = 11,                  //!< 512-bit view of a vector register (X86).
+     680             :     kRegVec1024   = 12,                  //!< 1024-bit view of a vector register (future).
+     681             :     kRegVec2048   = 13,                  //!< 2048-bit view of a vector register (future).
+     682             :     kRegIP        = 14,                  //!< Universal id of IP/PC register (if separate).
+     683             :     kRegCustom    = 15,                  //!< Start of platform dependent register types (must be honored).
+     684             :     kRegMax       = 31                   //!< Maximum possible register id of all architectures.
+     685             :   };
+     686             : 
+     687             :   //! Architecture neutral register kinds.
+     688             :   ASMJIT_ENUM(Kind) {
+     689             :     kKindGp       = 0,                   //!< General purpose register (X86|ARM).
+     690             :     kKindVec      = 1,                   //!< Vector register (X86|ARM).
+     691             :     kKindMax      = 15                   //!< Maximum possible register kind of all architectures.
+     692             :   };
+     693             : 
+     694             :   // --------------------------------------------------------------------------
+     695             :   // [Construction / Destruction]
+     696             :   // --------------------------------------------------------------------------
+     697             : 
+     698             :   //! Create a dummy register operand.
+     699             :   ASMJIT_INLINE Reg() noexcept : Operand() {}
+     700             :   //! Create a new register operand which is the same as `other` .
+     701             :   ASMJIT_INLINE Reg(const Reg& other) noexcept : Operand(other) {}
+     702             :   //! Create a new register operand compatible with `other`, but with a different `rId`.
+     703             :   ASMJIT_INLINE Reg(const Reg& other, uint32_t rId) noexcept : Operand(NoInit) {
+     704             :     _init_packed_d0_d1(other._signature, rId);
+     705             :     _packed[1] = other._packed[1];
+     706             :   }
+     707             : 
+     708             :   //! Create a register initialized to `signature` and `rId`.
+     709             :   ASMJIT_INLINE Reg(const _Init&, uint32_t signature, uint32_t rId) noexcept : Operand(NoInit) {
+     710             :     _initReg(signature, rId);
+     711             :   }
+     712             :   explicit ASMJIT_INLINE Reg(const _NoInit&) noexcept : Operand(NoInit) {}
+     713             : 
+     714             :   //! Create a new register based on `signature` and `rId`.
+     715             :   static ASMJIT_INLINE Reg fromSignature(uint32_t signature, uint32_t rId) noexcept { return Reg(Init, signature, rId); }
+     716             : 
+     717             :   // --------------------------------------------------------------------------
+     718             :   // [Reg Specific]
+     719             :   // --------------------------------------------------------------------------
+     720             : 
+     721             :   //! Get if the register is valid (either virtual or physical).
+     722        1948 :   ASMJIT_INLINE bool isValid() const noexcept { return _signature != 0; }
+     723             :   //! Get if this is a physical register.
+     724             :   ASMJIT_INLINE bool isPhysReg() const noexcept { return _reg.id < Globals::kInvalidRegId; }
+     725             :   //! Get if this is a virtual register (used by \ref CodeCompiler).
+     726           0 :   ASMJIT_INLINE bool isVirtReg() const noexcept { return isPackedId(_reg.id); }
+     727             : 
+     728             :   //! Get if this register is the same as `other`.
+     729             :   //!
+     730             :   //! This is just an optimization. Registers by default only use the first
+     731             :   //! 8 bytes of the Operand, so this method takes advantage of this knowledge
+     732             :   //! and only compares these 8 bytes. If both operands were created correctly
+     733             :   //! then `isEqual()` and `isSame()` should give the same answer, however, if
+     734             :   //! some operands contains a garbage or other metadata in the upper 8 bytes
+     735             :   //! then `isSame()` may return `true` in cases where `isEqual()` returns
+     736             :   //! false. However. no such case is known at the moment.
+     737             :   ASMJIT_INLINE bool isSame(const Reg& other) const noexcept { return _packed[0] == other._packed[0]; }
+     738             : 
+     739             :   //! Get if the register type matches `rType` - same as `isReg(rType)`, provided for convenience.
+     740             :   ASMJIT_INLINE bool isType(uint32_t rType) const noexcept { return (_signature & kSignatureRegTypeMask) == (rType << kSignatureRegTypeShift); }
+     741             :   //! Get if the register kind matches `rKind`.
+     742       21892 :   ASMJIT_INLINE bool isKind(uint32_t rKind) const noexcept { return (_signature & kSignatureRegKindMask) == (rKind << kSignatureRegKindShift); }
+     743             : 
+     744             :   //! Get if the register is a general purpose register (any size).
+     745             :   ASMJIT_INLINE bool isGp() const noexcept { return isKind(kKindGp); }
+     746             :   //! Get if the register is a vector register.
+     747             :   ASMJIT_INLINE bool isVec() const noexcept { return isKind(kKindVec); }
+     748             : 
+     749             :   using Operand_::isReg;
+     750             : 
+     751             :   //! Same as `isType()`, provided for convenience.
+     752             :   ASMJIT_INLINE bool isReg(uint32_t rType) const noexcept { return isType(rType); }
+     753             :   //! Get if the register type matches `type` and register id matches `rId`.
+     754             :   ASMJIT_INLINE bool isReg(uint32_t rType, uint32_t rId) const noexcept { return isType(rType) && getId() == rId; }
+     755             : 
+     756             :   //! Get the register type.
+     757             :   ASMJIT_INLINE uint32_t getType() const noexcept { return _getSignatureData(kSignatureRegTypeBits, kSignatureRegTypeShift); }
+     758             :   //! Get the register kind.
+     759             :   ASMJIT_INLINE uint32_t getKind() const noexcept { return _getSignatureData(kSignatureRegKindBits, kSignatureRegKindShift); }
+     760             : 
+     761             :   //! Clone the register operand.
+     762             :   ASMJIT_INLINE Reg clone() const noexcept { return Reg(*this); }
+     763             : 
+     764             :   //! Cast this register to `RegT` by also changing its signature.
+     765             :   //!
+     766             :   //! NOTE: Improper use of `cloneAs()` can lead to hard-to-debug errors.
+     767             :   template<typename RegT>
+     768             :   ASMJIT_INLINE RegT cloneAs() const noexcept { return RegT(Init, RegT::kSignature, getId()); }
+     769             : 
+     770             :   //! Cast this register to `other` by also changing its signature.
+     771             :   //!
+     772             :   //! NOTE: Improper use of `cloneAs()` can lead to hard-to-debug errors.
+     773             :   template<typename RegT>
+     774             :   ASMJIT_INLINE RegT cloneAs(const RegT& other) const noexcept { return RegT(Init, other.getSignature(), getId()); }
+     775             : 
+     776             :   //! Set the register id to `id`.
+     777        2660 :   ASMJIT_INLINE void setId(uint32_t rId) noexcept { _reg.id = rId; }
+     778             : 
+     779             :   //! Set a 32-bit operand signature based on traits of `RegT`.
+     780             :   template<typename RegT>
+     781             :   ASMJIT_INLINE void setSignatureT() noexcept { _signature = RegT::kSignature; }
+     782             : 
+     783             :   //! Set register's `signature` and `rId`.
+     784             :   ASMJIT_INLINE void setSignatureAndId(uint32_t signature, uint32_t rId) noexcept {
+     785             :     _signature = signature;
+     786             :     _reg.id = rId;
+     787             :   }
+     788             : 
+     789             :   // --------------------------------------------------------------------------
+     790             :   // [Reg Statics]
+     791             :   // --------------------------------------------------------------------------
+     792             : 
+     793             :   static ASMJIT_INLINE bool isGp(const Operand_& op) noexcept {
+     794             :     // Check operand type and register kind. Not interested in register type and size.
+     795             :     const uint32_t kSgn = (kOpReg  << kSignatureOpShift     ) |
+     796             :                           (kKindGp << kSignatureRegKindShift) ;
+     797           0 :     return (op.getSignature() & (kSignatureOpMask | kSignatureRegKindMask)) == kSgn;
+     798             :   }
+     799             : 
+     800             :   //! Get if the `op` operand is either a low or high 8-bit GPB register.
+     801             :   static ASMJIT_INLINE bool isVec(const Operand_& op) noexcept {
+     802             :     // Check operand type and register kind. Not interested in register type and size.
+     803             :     const uint32_t kSgn = (kOpReg   << kSignatureOpShift     ) |
+     804             :                           (kKindVec << kSignatureRegKindShift) ;
+     805             :     return (op.getSignature() & (kSignatureOpMask | kSignatureRegKindMask)) == kSgn;
+     806             :   }
+     807             : 
+     808           0 :   static ASMJIT_INLINE bool isGp(const Operand_& op, uint32_t rId) noexcept { return isGp(op) & (op.getId() == rId); }
+     809             :   static ASMJIT_INLINE bool isVec(const Operand_& op, uint32_t rId) noexcept { return isVec(op) & (op.getId() == rId); }
+     810             : };
+     811             : 
+     812             : // ============================================================================
+     813             : // [asmjit::RegOnly]
+     814             : // ============================================================================
+     815             : 
+     816             : //! RegOnly is 8-byte version of `Reg` that only allows to store either `Reg`
+     817             : //! or nothing. This class was designed to decrease the space consumed by each
+     818             : //! extra "operand" in `CodeEmitter` and `CBInst` classes.
+     819             : struct RegOnly {
+     820             :   // --------------------------------------------------------------------------
+     821             :   // [Init / Reset]
+     822             :   // --------------------------------------------------------------------------
+     823             : 
+     824             :   //! Initialize the `RegOnly` instance to hold register `signature` and `id`.
+     825             :   ASMJIT_INLINE void init(uint32_t signature, uint32_t id) noexcept {
+     826      143438 :     _signature = signature;
+     827      143438 :     _id = id;
+     828             :   }
+     829             : 
+     830             :   ASMJIT_INLINE void init(const Reg& reg) noexcept { init(reg.getSignature(), reg.getId()); }
+     831             :   ASMJIT_INLINE void init(const RegOnly& reg) noexcept { init(reg.getSignature(), reg.getId()); }
+     832             : 
+     833             :   //! Reset the `RegOnly` to none.
+     834             :   ASMJIT_INLINE void reset() noexcept { init(0, 0); }
+     835             : 
+     836             :   // --------------------------------------------------------------------------
+     837             :   // [Accessors]
+     838             :   // --------------------------------------------------------------------------
+     839             : 
+     840             :   //! Get if the `ExtraReg` is none (same as calling `Operand_::isNone()`).
+     841           0 :   ASMJIT_INLINE bool isNone() const noexcept { return _signature == 0; }
+     842             :   //! Get if the register is valid (either virtual or physical).
+     843       62316 :   ASMJIT_INLINE bool isValid() const noexcept { return _signature != 0; }
+     844             : 
+     845             :   //! Get if this is a physical register.
+     846             :   ASMJIT_INLINE bool isPhysReg() const noexcept { return _id < Globals::kInvalidRegId; }
+     847             :   //! Get if this is a virtual register (used by \ref CodeCompiler).
+     848             :   ASMJIT_INLINE bool isVirtReg() const noexcept { return Operand::isPackedId(_id); }
+     849             : 
+     850             :   //! Get register signature or 0.
+     851       48362 :   ASMJIT_INLINE uint32_t getSignature() const noexcept { return _signature; }
+     852             :   //! Get register id or 0.
+     853       48362 :   ASMJIT_INLINE uint32_t getId() const noexcept { return _id; }
+     854             : 
+     855             :   //! \internal
+     856             :   //!
+     857             :   //! Unpacks information from operand's signature.
+     858           0 :   ASMJIT_INLINE uint32_t _getSignatureData(uint32_t bits, uint32_t shift) const noexcept { return (_signature >> shift) & bits; }
+     859             : 
+     860             :   //! Get the register type.
+     861             :   ASMJIT_INLINE uint32_t getType() const noexcept { return _getSignatureData(Operand::kSignatureRegTypeBits, Operand::kSignatureRegTypeShift); }
+     862             :   //! Get the register kind.
+     863             :   ASMJIT_INLINE uint32_t getKind() const noexcept { return _getSignatureData(Operand::kSignatureRegKindBits, Operand::kSignatureRegKindShift); }
+     864             : 
+     865             :   // --------------------------------------------------------------------------
+     866             :   // [ToReg]
+     867             :   // --------------------------------------------------------------------------
+     868             : 
+     869             :   //! Convert back to `RegT` operand.
+     870             :   template<typename RegT>
+     871           0 :   ASMJIT_INLINE RegT toReg() const noexcept { return RegT(Init, _signature, _id); }
+     872             : 
+     873             :   // --------------------------------------------------------------------------
+     874             :   // [Members]
+     875             :   // --------------------------------------------------------------------------
+     876             : 
+     877             :   //! Type of the operand, either `kOpNone` or `kOpReg`.
+     878             :   uint32_t _signature;
+     879             :   //! Physical or virtual register id.
+     880             :   uint32_t _id;
+     881             : };
+     882             : 
+     883             : // ============================================================================
+     884             : // [asmjit::Mem]
+     885             : // ============================================================================
+     886             : 
+     887             : //! Base class for all memory operands.
+     888             : //!
+     889             : //! NOTE: It's tricky to pack all possible cases that define a memory operand
+     890             : //! into just 16 bytes. The `Mem` splits data into the following parts:
+     891             : //!
+     892             : //!   BASE - Base register or label - requires 36 bits total. 4 bits are used
+     893             : //!     to encode the type of the BASE operand (label vs. register type) and
+     894             : //!     the remaining 32 bits define the BASE id, which can be a physical or
+     895             : //!     virtual register index. If BASE type is zero, which is never used as
+     896             : //!     a register-type and label doesn't use it as well then BASE field
+     897             : //!     contains a high DWORD of a possible 64-bit absolute address, which is
+     898             : //!     possible on X64.
+     899             : //!
+     900             : //!   INDEX - Index register (or theoretically Label, which doesn't make sense).
+     901             : //!     Encoding is similar to BASE - it also requires 36 bits and splits the
+     902             : //!     encoding to INDEX type (4 bits defining the register type) and id (32-bits).
+     903             : //!
+     904             : //!   OFFSET - A relative offset of the address. Basically if BASE is specified
+     905             : //!     the relative displacement adjusts BASE and an optional INDEX. if BASE is
+     906             : //!     not specified then the OFFSET should be considered as ABSOLUTE address
+     907             : //!     (at least on X86/X64). In that case its low 32 bits are stored in
+     908             : //!     DISPLACEMENT field and the remaining high 32 bits are stored in BASE.
+     909             : //!
+     910             : //!   OTHER FIELDS - There is rest 8 bits that can be used for whatever purpose.
+     911             : //!          The X86Mem operand uses these bits to store segment override
+     912             : //!          prefix and index shift (scale).
+     913             : class Mem : public Operand {
+     914             : public:
+     915             :   enum AddrType {
+     916             :     kAddrTypeDefault = 0,
+     917             :     kAddrTypeAbs     = 1,
+     918             :     kAddrTypeRel     = 2,
+     919             :     kAddrTypeWrt     = 3
+     920             :   };
+     921             : 
+     922             :   // Shortcuts.
+     923             :   enum SignatureMem {
+     924             :     kSignatureMemAbs = kAddrTypeAbs << kSignatureMemAddrTypeShift,
+     925             :     kSignatureMemRel = kAddrTypeRel << kSignatureMemAddrTypeShift,
+     926             :     kSignatureMemWrt = kAddrTypeWrt << kSignatureMemAddrTypeShift
+     927             :   };
+     928             : 
+     929             :   // --------------------------------------------------------------------------
+     930             :   // [Construction / Destruction]
+     931             :   // --------------------------------------------------------------------------
+     932             : 
+     933             :   //! Construct a default `Mem` operand, that points to [0].
+     934             :   ASMJIT_INLINE Mem() noexcept : Operand(NoInit) { reset(); }
+     935             :   ASMJIT_INLINE Mem(const Mem& other) noexcept : Operand(other) {}
+     936             : 
+     937             :   ASMJIT_INLINE Mem(const _Init&,
+     938             :     uint32_t baseType, uint32_t baseId,
+     939             :     uint32_t indexType, uint32_t indexId,
+     940             :     int32_t off, uint32_t size, uint32_t flags) noexcept : Operand(NoInit) {
+     941             : 
+     942        8428 :     uint32_t signature = (baseType  << kSignatureMemBaseTypeShift ) |
+     943             :                          (indexType << kSignatureMemIndexTypeShift) |
+     944           0 :                          (size      << kSignatureSizeShift        ) ;
+     945             : 
+     946        8428 :     _init_packed_d0_d1(kOpMem | signature | flags, indexId);
+     947        8428 :     _mem.base = baseId;
+     948        8428 :     _mem.offsetLo32 = static_cast<uint32_t>(off);
+     949             :   }
+     950             :   explicit ASMJIT_INLINE Mem(const _NoInit&) noexcept : Operand(NoInit) {}
+     951             : 
+     952             :   // --------------------------------------------------------------------------
+     953             :   // [Mem Specific]
+     954             :   // --------------------------------------------------------------------------
+     955             : 
+     956             :   //! Clone `Mem` operand.
+     957             :   ASMJIT_INLINE Mem clone() const noexcept { return Mem(*this); }
+     958             : 
+     959             :   //! Reset the memory operand - after reset the memory points to [0].
+     960             :   ASMJIT_INLINE void reset() noexcept {
+     961             :     _init_packed_d0_d1(kOpMem, 0);
+     962             :     _init_packed_d2_d3(0, 0);
+     963             :   }
+     964             : 
+     965             :   ASMJIT_INLINE bool hasAddrType() const noexcept { return _hasSignatureData(kSignatureMemAddrTypeMask); }
+     966             :   ASMJIT_INLINE uint32_t getAddrType() const noexcept { return _getSignatureData(kSignatureMemAddrTypeBits, kSignatureMemAddrTypeShift); }
+     967             :   ASMJIT_INLINE void setAddrType(uint32_t addrType) noexcept { return _setSignatureData(addrType, kSignatureMemAddrTypeBits, kSignatureMemAddrTypeShift); }
+     968             :   ASMJIT_INLINE void resetAddrType() noexcept { return _clearSignatureData(kSignatureMemAddrTypeBits, kSignatureMemAddrTypeShift); }
+     969             : 
+     970             :   ASMJIT_INLINE bool isAbs() const noexcept { return getAddrType() == kAddrTypeAbs; }
+     971             :   ASMJIT_INLINE bool isRel() const noexcept { return getAddrType() == kAddrTypeRel; }
+     972             :   ASMJIT_INLINE bool isWrt() const noexcept { return getAddrType() == kAddrTypeWrt; }
+     973             : 
+     974             :   ASMJIT_INLINE void setAbs() noexcept { setAddrType(kAddrTypeAbs); }
+     975             :   ASMJIT_INLINE void setRel() noexcept { setAddrType(kAddrTypeRel); }
+     976             :   ASMJIT_INLINE void setWrt() noexcept { setAddrType(kAddrTypeWrt); }
+     977             : 
+     978             :   ASMJIT_INLINE bool isArgHome() const noexcept { return _hasSignatureData(kSignatureMemArgHomeFlag); }
+     979             :   ASMJIT_INLINE bool isRegHome() const noexcept { return _hasSignatureData(kSignatureMemRegHomeFlag); }
+     980             : 
+     981           0 :   ASMJIT_INLINE void setArgHome() noexcept { _signature |= kSignatureMemArgHomeFlag; }
+     982             :   ASMJIT_INLINE void setRegHome() noexcept { _signature |= kSignatureMemRegHomeFlag; }
+     983             : 
+     984           0 :   ASMJIT_INLINE void clearArgHome() noexcept { _signature &= ~kSignatureMemArgHomeFlag; }
+     985        8428 :   ASMJIT_INLINE void clearRegHome() noexcept { _signature &= ~kSignatureMemRegHomeFlag; }
+     986             : 
+     987             :   //! Get if the memory operand has a BASE register or label specified.
+     988           0 :   ASMJIT_INLINE bool hasBase() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0; }
+     989             :   //! Get if the memory operand has an INDEX register specified.
+     990           0 :   ASMJIT_INLINE bool hasIndex() const noexcept { return (_signature & kSignatureMemIndexTypeMask) != 0; }
+     991             :   //! Get whether the memory operand has BASE and INDEX register.
+     992           0 :   ASMJIT_INLINE bool hasBaseOrIndex() const noexcept { return (_signature & kSignatureMemBaseIndexMask) != 0; }
+     993             :   //! Get whether the memory operand has BASE and INDEX register.
+     994             :   ASMJIT_INLINE bool hasBaseAndIndex() const noexcept { return (_signature & kSignatureMemBaseTypeMask) != 0 && (_signature & kSignatureMemIndexTypeMask) != 0; }
+     995             : 
+     996             :   //! Get if the BASE operand is a register (registers start after `kLabelTag`).
+     997       12200 :   ASMJIT_INLINE bool hasBaseReg() const noexcept { return (_signature & kSignatureMemBaseTypeMask) > (Label::kLabelTag << kSignatureMemBaseTypeShift); }
+     998             :   //! Get if the BASE operand is a label.
+     999             :   ASMJIT_INLINE bool hasBaseLabel() const noexcept { return (_signature & kSignatureMemBaseTypeMask) == (Label::kLabelTag << kSignatureMemBaseTypeShift); }
+    1000             :   //! Get if the INDEX operand is a register (registers start after `kLabelTag`).
+    1001       12200 :   ASMJIT_INLINE bool hasIndexReg() const noexcept { return (_signature & kSignatureMemIndexTypeMask) > (Label::kLabelTag << kSignatureMemIndexTypeShift); }
+    1002             : 
+    1003             :   //! Get type of a BASE register (0 if this memory operand doesn't use the BASE register).
+    1004             :   //!
+    1005             :   //! NOTE: If the returned type is one (a value never associated to a register
+    1006             :   //! type) the BASE is not register, but it's a label. One equals to `kLabelTag`.
+    1007             :   //! You should always check `hasBaseLabel()` before using `getBaseId()` result.
+    1008             :   ASMJIT_INLINE uint32_t getBaseType() const noexcept { return _getSignatureData(kSignatureMemBaseTypeBits, kSignatureMemBaseTypeShift); }
+    1009             :   //! Get type of an INDEX register (0 if this memory operand doesn't use the INDEX register).
+    1010             :   ASMJIT_INLINE uint32_t getIndexType() const noexcept { return _getSignatureData(kSignatureMemIndexTypeBits, kSignatureMemIndexTypeShift); }
+    1011             : 
+    1012             :   //! Get both BASE (4:0 bits) and INDEX (9:5 bits) types combined into a single integer.
+    1013             :   //!
+    1014             :   //! This is used internally for BASE+INDEX validation.
+    1015             :   ASMJIT_INLINE uint32_t getBaseIndexType() const noexcept { return _getSignatureData(kSignatureMemBaseIndexBits, kSignatureMemBaseIndexShift); }
+    1016             : 
+    1017             :   //! Get id of the BASE register or label (if the BASE was specified as label).
+    1018       20628 :   ASMJIT_INLINE uint32_t getBaseId() const noexcept { return _mem.base; }
+    1019             :   //! Get id of the INDEX register.
+    1020       14528 :   ASMJIT_INLINE uint32_t getIndexId() const noexcept { return _mem.index; }
+    1021             : 
+    1022             :   ASMJIT_INLINE void _setBase(uint32_t rType, uint32_t rId) noexcept {
+    1023             :     _setSignatureData(rType, kSignatureMemBaseTypeBits, kSignatureMemBaseTypeShift);
+    1024        8428 :     _mem.base = rId;
+    1025             :   }
+    1026             : 
+    1027             :   ASMJIT_INLINE void _setIndex(uint32_t rType, uint32_t rId) noexcept {
+    1028             :     _setSignatureData(rType, kSignatureMemIndexTypeBits, kSignatureMemIndexTypeShift);
+    1029             :     _mem.index = rId;
+    1030             :   }
+    1031             : 
+    1032             :   ASMJIT_INLINE void setBase(const Reg& base) noexcept { return _setBase(base.getType(), base.getId()); }
+    1033             :   ASMJIT_INLINE void setIndex(const Reg& index) noexcept { return _setIndex(index.getType(), index.getId()); }
+    1034             : 
+    1035             :   //! Reset the memory operand's BASE register / label.
+    1036             :   ASMJIT_INLINE void resetBase() noexcept { _setBase(0, 0); }
+    1037             :   //! Reset the memory operand's INDEX register.
+    1038             :   ASMJIT_INLINE void resetIndex() noexcept { _setIndex(0, 0); }
+    1039             : 
+    1040             :   //! Set memory operand size.
+    1041             :   ASMJIT_INLINE void setSize(uint32_t size) noexcept {
+    1042             :     _setSignatureData(size, kSignatureSizeBits, kSignatureSizeShift);
+    1043        8428 :   }
+    1044             : 
+    1045             :   ASMJIT_INLINE bool hasOffset() const noexcept {
+    1046           0 :     int32_t lo = static_cast<int32_t>(_mem.offsetLo32);
+    1047           0 :     int32_t hi = static_cast<int32_t>(_mem.base) & -static_cast<int32_t>(getBaseType() == 0);
+    1048           0 :     return (lo | hi) != 0;
+    1049             :   }
+    1050             : 
+    1051             :   //! Get if the memory operand has 64-bit offset or absolute address.
+    1052             :   //!
+    1053             :   //! If this is true then `hasBase()` must always report false.
+    1054             :   ASMJIT_INLINE bool has64BitOffset() const noexcept { return getBaseType() == 0; }
+    1055             : 
+    1056             :   //! Get a 64-bit offset or absolute address.
+    1057             :   ASMJIT_INLINE int64_t getOffset() const noexcept {
+    1058             :     return has64BitOffset()
+    1059           0 :       ? static_cast<int64_t>(_mem.offset64)
+    1060           0 :       : static_cast<int64_t>(static_cast<int32_t>(_mem.offsetLo32)); // Sign-Extend.
+    1061             :   }
+    1062             : 
+    1063             :   //! Get a lower part of a 64-bit offset or absolute address.
+    1064       14528 :   ASMJIT_INLINE int32_t getOffsetLo32() const noexcept { return static_cast<int32_t>(_mem.offsetLo32); }
+    1065             :   //! Get a higher part of a 64-bit offset or absolute address.
+    1066             :   //!
+    1067             :   //! NOTE: This function is UNSAFE and returns garbage if `has64BitOffset()`
+    1068             :   //! returns false. Never use it blindly without checking it.
+    1069           0 :   ASMJIT_INLINE int32_t getOffsetHi32() const noexcept { return static_cast<int32_t>(_mem.base); }
+    1070             : 
+    1071             :   //! Set a 64-bit offset or an absolute address to `offset`.
+    1072             :   //!
+    1073             :   //! NOTE: This functions attempts to set both high and low parts of a 64-bit
+    1074             :   //! offset, however, if the operand has a BASE register it will store only the
+    1075             :   //! low 32 bits of the offset / address as there is no way to store both BASE
+    1076             :   //! and 64-bit offset, and there is currently no architecture that has such
+    1077             :   //! capability targeted by AsmJit.
+    1078             :   ASMJIT_INLINE void setOffset(int64_t offset) noexcept {
+    1079             :     if (has64BitOffset())
+    1080             :       _mem.offset64 = static_cast<uint64_t>(offset);
+    1081             :     else
+    1082             :       _mem.offsetLo32 = static_cast<int32_t>(offset & 0xFFFFFFFF);
+    1083             :   }
+    1084             :   //! Adjust the offset by a 64-bit `off`.
+    1085             :   ASMJIT_INLINE void addOffset(int64_t off) noexcept {
+    1086           0 :     if (has64BitOffset())
+    1087           0 :       _mem.offset64 += static_cast<uint64_t>(off);
+    1088             :     else
+    1089           0 :       _mem.offsetLo32 += static_cast<uint32_t>(off & 0xFFFFFFFF);
+    1090             :   }
+    1091             :   //! Reset the memory offset to zero.
+    1092             :   ASMJIT_INLINE void resetOffset() noexcept { setOffset(0); }
+    1093             : 
+    1094             :   //! Set a low 32-bit offset to `off`.
+    1095             :   ASMJIT_INLINE void setOffsetLo32(int32_t off) noexcept {
+    1096             :     _mem.offsetLo32 = static_cast<uint32_t>(off);
+    1097             :   }
+    1098             :   //! Adjust the offset by `off`.
+    1099             :   //!
+    1100             :   //! NOTE: This is a fast function that doesn't use the HI 32-bits of a
+    1101             :   //! 64-bit offset. Use it only if you know that there is a BASE register
+    1102             :   //! and the offset is only 32 bits anyway.
+    1103             :   ASMJIT_INLINE void addOffsetLo32(int32_t off) noexcept {
+    1104        8428 :     _mem.offsetLo32 += static_cast<uint32_t>(off);
+    1105           0 :   }
+    1106             :   //! Reset the memory offset to zero.
+    1107             :   ASMJIT_INLINE void resetOffsetLo32() noexcept { setOffsetLo32(0); }
+    1108             : 
+    1109             :   // --------------------------------------------------------------------------
+    1110             :   // [Operator Overload]
+    1111             :   // --------------------------------------------------------------------------
+    1112             : 
+    1113           0 :   ASMJIT_INLINE Mem& operator=(const Mem& other) noexcept { copyFrom(other); return *this; }
+    1114             : };
+    1115             : 
+    1116             : // ============================================================================
+    1117             : // [asmjit::Imm]
+    1118             : // ============================================================================
+    1119             : 
+    1120             : //! Immediate operand.
+    1121             : //!
+    1122             : //! Immediate operand is usually part of instruction itself. It's inlined after
+    1123             : //! or before the instruction opcode. Immediates can be only signed or unsigned
+    1124             : //! integers.
+    1125             : //!
+    1126             : //! To create immediate operand use `imm()` or `imm_u()` non-members or `Imm`
+    1127             : //! constructors.
+    1128             : class Imm : public Operand {
+    1129             : public:
+    1130             :   // --------------------------------------------------------------------------
+    1131             :   // [Construction / Destruction]
+    1132             :   // --------------------------------------------------------------------------
+    1133             : 
+    1134             :   //! Create a new immediate value (initial value is 0).
+    1135             :   Imm() noexcept : Operand(NoInit) {
+    1136             :     _init_packed_d0_d1(kOpImm, 0);
+    1137             :     _imm.value.i64 = 0;
+    1138             :   }
+    1139             : 
+    1140             :   //! Create a new signed immediate value, assigning the value to `val`.
+    1141             :   explicit Imm(int64_t val) noexcept : Operand(NoInit) {
+    1142             :     _init_packed_d0_d1(kOpImm, 0);
+    1143        9462 :     _imm.value.i64 = val;
+    1144             :   }
+    1145             : 
+    1146             :   //! Create a new immediate value from `other`.
+    1147             :   ASMJIT_INLINE Imm(const Imm& other) noexcept : Operand(other) {}
+    1148             : 
+    1149             :   explicit ASMJIT_INLINE Imm(const _NoInit&) noexcept : Operand(NoInit) {}
+    1150             : 
+    1151             :   // --------------------------------------------------------------------------
+    1152             :   // [Immediate Specific]
+    1153             :   // --------------------------------------------------------------------------
+    1154             : 
+    1155             :   //! Clone `Imm` operand.
+    1156             :   ASMJIT_INLINE Imm clone() const noexcept { return Imm(*this); }
+    1157             : 
+    1158             :   //! Get whether the immediate can be casted to 8-bit signed integer.
+    1159             :   ASMJIT_INLINE bool isInt8() const noexcept { return Utils::isInt8(_imm.value.i64); }
+    1160             :   //! Get whether the immediate can be casted to 8-bit unsigned integer.
+    1161             :   ASMJIT_INLINE bool isUInt8() const noexcept { return Utils::isUInt8(_imm.value.i64); }
+    1162             : 
+    1163             :   //! Get whether the immediate can be casted to 16-bit signed integer.
+    1164             :   ASMJIT_INLINE bool isInt16() const noexcept { return Utils::isInt16(_imm.value.i64); }
+    1165             :   //! Get whether the immediate can be casted to 16-bit unsigned integer.
+    1166             :   ASMJIT_INLINE bool isUInt16() const noexcept { return Utils::isUInt16(_imm.value.i64); }
+    1167             : 
+    1168             :   //! Get whether the immediate can be casted to 32-bit signed integer.
+    1169             :   ASMJIT_INLINE bool isInt32() const noexcept { return Utils::isInt32(_imm.value.i64); }
+    1170             :   //! Get whether the immediate can be casted to 32-bit unsigned integer.
+    1171             :   ASMJIT_INLINE bool isUInt32() const noexcept { return Utils::isUInt32(_imm.value.i64); }
+    1172             : 
+    1173             :   //! Get immediate value as 8-bit signed integer.
+    1174             :   ASMJIT_INLINE int8_t getInt8() const noexcept { return static_cast<int8_t>(_imm.value.i32Lo & 0xFF); }
+    1175             :   //! Get immediate value as 8-bit unsigned integer.
+    1176           0 :   ASMJIT_INLINE uint8_t getUInt8() const noexcept { return static_cast<uint8_t>(_imm.value.u32Lo & 0xFFU); }
+    1177             :   //! Get immediate value as 16-bit signed integer.
+    1178             :   ASMJIT_INLINE int16_t getInt16() const noexcept { return static_cast<int16_t>(_imm.value.i32Lo & 0xFFFF);}
+    1179             :   //! Get immediate value as 16-bit unsigned integer.
+    1180           0 :   ASMJIT_INLINE uint16_t getUInt16() const noexcept { return static_cast<uint16_t>(_imm.value.u32Lo & 0xFFFFU);}
+    1181             : 
+    1182             :   //! Get immediate value as 32-bit signed integer.
+    1183             :   ASMJIT_INLINE int32_t getInt32() const noexcept { return _imm.value.i32Lo; }
+    1184             :   //! Get low 32-bit signed integer.
+    1185             :   ASMJIT_INLINE int32_t getInt32Lo() const noexcept { return _imm.value.i32Lo; }
+    1186             :   //! Get high 32-bit signed integer.
+    1187             :   ASMJIT_INLINE int32_t getInt32Hi() const noexcept { return _imm.value.i32Hi; }
+    1188             : 
+    1189             :   //! Get immediate value as 32-bit unsigned integer.
+    1190           0 :   ASMJIT_INLINE uint32_t getUInt32() const noexcept { return _imm.value.u32Lo; }
+    1191             :   //! Get low 32-bit signed integer.
+    1192             :   ASMJIT_INLINE uint32_t getUInt32Lo() const noexcept { return _imm.value.u32Lo; }
+    1193             :   //! Get high 32-bit signed integer.
+    1194             :   ASMJIT_INLINE uint32_t getUInt32Hi() const noexcept { return _imm.value.u32Hi; }
+    1195             : 
+    1196             :   //! Get immediate value as 64-bit signed integer.
+    1197        9672 :   ASMJIT_INLINE int64_t getInt64() const noexcept { return _imm.value.i64; }
+    1198             :   //! Get immediate value as 64-bit unsigned integer.
+    1199           0 :   ASMJIT_INLINE uint64_t getUInt64() const noexcept { return _imm.value.u64; }
+    1200             : 
+    1201             :   //! Get immediate value as `intptr_t`.
+    1202             :   ASMJIT_INLINE intptr_t getIntPtr() const noexcept {
+    1203             :     if (sizeof(intptr_t) == sizeof(int64_t))
+    1204             :       return static_cast<intptr_t>(getInt64());
+    1205             :     else
+    1206             :       return static_cast<intptr_t>(getInt32());
+    1207             :   }
+    1208             : 
+    1209             :   //! Get immediate value as `uintptr_t`.
+    1210             :   ASMJIT_INLINE uintptr_t getUIntPtr() const noexcept {
+    1211             :     if (sizeof(uintptr_t) == sizeof(uint64_t))
+    1212             :       return static_cast<uintptr_t>(getUInt64());
+    1213             :     else
+    1214             :       return static_cast<uintptr_t>(getUInt32());
+    1215             :   }
+    1216             : 
+    1217             :   //! Set immediate value to 8-bit signed integer `val`.
+    1218             :   ASMJIT_INLINE void setInt8(int8_t val) noexcept { _imm.value.i64 = static_cast<int64_t>(val); }
+    1219             :   //! Set immediate value to 8-bit unsigned integer `val`.
+    1220             :   ASMJIT_INLINE void setUInt8(uint8_t val) noexcept { _imm.value.u64 = static_cast<uint64_t>(val); }
+    1221             : 
+    1222             :   //! Set immediate value to 16-bit signed integer `val`.
+    1223             :   ASMJIT_INLINE void setInt16(int16_t val) noexcept { _imm.value.i64 = static_cast<int64_t>(val); }
+    1224             :   //! Set immediate value to 16-bit unsigned integer `val`.
+    1225             :   ASMJIT_INLINE void setUInt16(uint16_t val) noexcept { _imm.value.u64 = static_cast<uint64_t>(val); }
+    1226             : 
+    1227             :   //! Set immediate value to 32-bit signed integer `val`.
+    1228             :   ASMJIT_INLINE void setInt32(int32_t val) noexcept { _imm.value.i64 = static_cast<int64_t>(val); }
+    1229             :   //! Set immediate value to 32-bit unsigned integer `val`.
+    1230           0 :   ASMJIT_INLINE void setUInt32(uint32_t val) noexcept { _imm.value.u64 = static_cast<uint64_t>(val); }
+    1231             : 
+    1232             :   //! Set immediate value to 64-bit signed integer `val`.
+    1233             :   ASMJIT_INLINE void setInt64(int64_t val) noexcept { _imm.value.i64 = val; }
+    1234             :   //! Set immediate value to 64-bit unsigned integer `val`.
+    1235             :   ASMJIT_INLINE void setUInt64(uint64_t val) noexcept { _imm.value.u64 = val; }
+    1236             :   //! Set immediate value to intptr_t `val`.
+    1237             :   ASMJIT_INLINE void setIntPtr(intptr_t val) noexcept { _imm.value.i64 = static_cast<int64_t>(val); }
+    1238             :   //! Set immediate value to uintptr_t `val`.
+    1239             :   ASMJIT_INLINE void setUIntPtr(uintptr_t val) noexcept { _imm.value.u64 = static_cast<uint64_t>(val); }
+    1240             : 
+    1241             :   //! Set immediate value as unsigned type to `val`.
+    1242             :   ASMJIT_INLINE void setPtr(void* p) noexcept { setIntPtr((uint64_t)p); }
+    1243             :   //! Set immediate value to `val`.
+    1244             :   template<typename T>
+    1245             :   ASMJIT_INLINE void setValue(T val) noexcept { setIntPtr((int64_t)val); }
+    1246             : 
+    1247             :   // --------------------------------------------------------------------------
+    1248             :   // [Float]
+    1249             :   // --------------------------------------------------------------------------
+    1250             : 
+    1251             :   ASMJIT_INLINE void setFloat(float f) noexcept {
+    1252             :     _imm.value.f32Lo = f;
+    1253             :     _imm.value.u32Hi = 0;
+    1254             :   }
+    1255             : 
+    1256             :   ASMJIT_INLINE void setDouble(double d) noexcept {
+    1257             :     _imm.value.f64 = d;
+    1258             :   }
+    1259             : 
+    1260             :   // --------------------------------------------------------------------------
+    1261             :   // [Truncate]
+    1262             :   // --------------------------------------------------------------------------
+    1263             : 
+    1264             :   ASMJIT_INLINE void truncateTo8Bits() noexcept {
+    1265             :     if (ASMJIT_ARCH_64BIT) {
+    1266           0 :       _imm.value.u64   &= static_cast<uint64_t>(0x000000FFU);
+    1267             :     }
+    1268             :     else {
+    1269             :       _imm.value.u32Lo &= 0x000000FFU;
+    1270             :       _imm.value.u32Hi  = 0;
+    1271             :     }
+    1272           0 :   }
+    1273             : 
+    1274             :   ASMJIT_INLINE void truncateTo16Bits() noexcept {
+    1275             :     if (ASMJIT_ARCH_64BIT) {
+    1276           0 :       _imm.value.u64   &= static_cast<uint64_t>(0x0000FFFFU);
+    1277             :     }
+    1278             :     else {
+    1279             :       _imm.value.u32Lo &= 0x0000FFFFU;
+    1280             :       _imm.value.u32Hi  = 0;
+    1281             :     }
+    1282           0 :   }
+    1283             : 
+    1284           0 :   ASMJIT_INLINE void truncateTo32Bits() noexcept { _imm.value.u32Hi = 0; }
+    1285             : 
+    1286             :   // --------------------------------------------------------------------------
+    1287             :   // [Operator Overload]
+    1288             :   // --------------------------------------------------------------------------
+    1289             : 
+    1290             :   //! Assign `other` to the immediate operand.
+    1291             :   ASMJIT_INLINE Imm& operator=(const Imm& other) noexcept { copyFrom(other); return *this; }
+    1292             : };
+    1293             : 
+    1294             : //! Create a signed immediate operand.
+    1295             : static ASMJIT_INLINE Imm imm(int64_t val) noexcept { return Imm(val); }
+    1296             : //! Create an unsigned immediate operand.
+    1297             : static ASMJIT_INLINE Imm imm_u(uint64_t val) noexcept { return Imm(static_cast<int64_t>(val)); }
+    1298             : //! Create an immediate operand from `p`.
+    1299             : template<typename T>
+    1300        7478 : static ASMJIT_INLINE Imm imm_ptr(T p) noexcept { return Imm(static_cast<int64_t>((intptr_t)p)); }
+    1301             : 
+    1302             : // ============================================================================
+    1303             : // [asmjit::TypeId]
+    1304             : // ============================================================================
+    1305             : 
+    1306             : //! Type-id.
+    1307             : //!
+    1308             : //! This is an additional information that can be used to describe a physical
+    1309             : //! or virtual register. it's used mostly by CodeCompiler to describe register
+    1310             : //! representation (the kind of data stored in the register and the width used)
+    1311             : //! and it's also used by APIs that allow to describe and work with function
+    1312             : //! signatures.
+    1313             : struct TypeId {
+    1314             :   // --------------------------------------------------------------------------
+    1315             :   // [Id]
+    1316             :   // --------------------------------------------------------------------------
+    1317             : 
+    1318             :   enum Id {
+    1319             :     kVoid         = 0,
+    1320             : 
+    1321             :     _kIntStart    = 32,
+    1322             :     _kIntEnd      = 41,
+    1323             : 
+    1324             :     kIntPtr       = 32,
+    1325             :     kUIntPtr      = 33,
+    1326             : 
+    1327             :     kI8           = 34,
+    1328             :     kU8           = 35,
+    1329             :     kI16          = 36,
+    1330             :     kU16          = 37,
+    1331             :     kI32          = 38,
+    1332             :     kU32          = 39,
+    1333             :     kI64          = 40,
+    1334             :     kU64          = 41,
+    1335             : 
+    1336             :     _kFloatStart  = 42,
+    1337             :     _kFloatEnd    = 44,
+    1338             : 
+    1339             :     kF32          = 42,
+    1340             :     kF64          = 43,
+    1341             :     kF80          = 44,
+    1342             : 
+    1343             :     _kMaskStart   = 45,
+    1344             :     _kMaskEnd     = 48,
+    1345             : 
+    1346             :     kMask8        = 45,
+    1347             :     kMask16       = 46,
+    1348             :     kMask32       = 47,
+    1349             :     kMask64       = 48,
+    1350             : 
+    1351             :     _kMmxStart    = 49,
+    1352             :     _kMmxEnd      = 50,
+    1353             : 
+    1354             :     kMmx32        = 49,
+    1355             :     kMmx64        = 50,
+    1356             : 
+    1357             :     _kVec32Start  = 51,
+    1358             :     _kVec32End    = 60,
+    1359             : 
+    1360             :     kI8x4         = 51,
+    1361             :     kU8x4         = 52,
+    1362             :     kI16x2        = 53,
+    1363             :     kU16x2        = 54,
+    1364             :     kI32x1        = 55,
+    1365             :     kU32x1        = 56,
+    1366             :     kF32x1        = 59,
+    1367             : 
+    1368             :     _kVec64Start  = 61,
+    1369             :     _kVec64End    = 70,
+    1370             : 
+    1371             :     kI8x8         = 61,
+    1372             :     kU8x8         = 62,
+    1373             :     kI16x4        = 63,
+    1374             :     kU16x4        = 64,
+    1375             :     kI32x2        = 65,
+    1376             :     kU32x2        = 66,
+    1377             :     kI64x1        = 67,
+    1378             :     kU64x1        = 68,
+    1379             :     kF32x2        = 69,
+    1380             :     kF64x1        = 70,
+    1381             : 
+    1382             :     _kVec128Start = 71,
+    1383             :     _kVec128End   = 80,
+    1384             : 
+    1385             :     kI8x16        = 71,
+    1386             :     kU8x16        = 72,
+    1387             :     kI16x8        = 73,
+    1388             :     kU16x8        = 74,
+    1389             :     kI32x4        = 75,
+    1390             :     kU32x4        = 76,
+    1391             :     kI64x2        = 77,
+    1392             :     kU64x2        = 78,
+    1393             :     kF32x4        = 79,
+    1394             :     kF64x2        = 80,
+    1395             : 
+    1396             :     _kVec256Start = 81,
+    1397             :     _kVec256End   = 90,
+    1398             : 
+    1399             :     kI8x32        = 81,
+    1400             :     kU8x32        = 82,
+    1401             :     kI16x16       = 83,
+    1402             :     kU16x16       = 84,
+    1403             :     kI32x8        = 85,
+    1404             :     kU32x8        = 86,
+    1405             :     kI64x4        = 87,
+    1406             :     kU64x4        = 88,
+    1407             :     kF32x8        = 89,
+    1408             :     kF64x4        = 90,
+    1409             : 
+    1410             :     _kVec512Start = 91,
+    1411             :     _kVec512End   = 100,
+    1412             : 
+    1413             :     kI8x64        = 91,
+    1414             :     kU8x64        = 92,
+    1415             :     kI16x32       = 93,
+    1416             :     kU16x32       = 94,
+    1417             :     kI32x16       = 95,
+    1418             :     kU32x16       = 96,
+    1419             :     kI64x8        = 97,
+    1420             :     kU64x8        = 98,
+    1421             :     kF32x16       = 99,
+    1422             :     kF64x8        = 100,
+    1423             : 
+    1424             :     kCount        = 101
+    1425             :   };
+    1426             : 
+    1427             :   // --------------------------------------------------------------------------
+    1428             :   // [TypeName - Used by Templates]
+    1429             :   // --------------------------------------------------------------------------
+    1430             : 
+    1431             :   struct Int8    {};                     //!< int8_t as C++ type-name.
+    1432             :   struct UInt8   {};                     //!< uint8_t as C++ type-name.
+    1433             :   struct Int16   {};                     //!< int16_t as C++ type-name.
+    1434             :   struct UInt16  {};                     //!< uint16_t as C++ type-name.
+    1435             :   struct Int32   {};                     //!< int32_t as C++ type-name.
+    1436             :   struct UInt32  {};                     //!< uint32_t as C++ type-name.
+    1437             :   struct Int64   {};                     //!< int64_t as C++ type-name.
+    1438             :   struct UInt64  {};                     //!< uint64_t as C++ type-name.
+    1439             :   struct IntPtr  {};                     //!< intptr_t as C++ type-name.
+    1440             :   struct UIntPtr {};                     //!< uintptr_t as C++ type-name.
+    1441             :   struct Float   {};                     //!< float as C++ type-name.
+    1442             :   struct Double  {};                     //!< double as C++ type-name.
+    1443             :   struct MmxReg  {};                     //!< MMX register as C++ type-name.
+    1444             :   struct Vec128  {};                     //!< SIMD128/XMM register as C++ type-name.
+    1445             :   struct Vec256  {};                     //!< SIMD256/YMM register as C++ type-name.
+    1446             :   struct Vec512  {};                     //!< SIMD512/ZMM register as C++ type-name.
+    1447             : 
+    1448             :   // --------------------------------------------------------------------------
+    1449             :   // [Utilities]
+    1450             :   // --------------------------------------------------------------------------
+    1451             : 
+    1452             :   struct Info {
+    1453             :     uint8_t sizeOf[128];
+    1454             :     uint8_t elementOf[128];
+    1455             :   };
+    1456             : 
+    1457             :   ASMJIT_API static const Info _info;
+    1458             : 
+    1459             :   static ASMJIT_INLINE bool isVoid(uint32_t typeId) noexcept { return typeId == 0; }
+    1460       23788 :   static ASMJIT_INLINE bool isValid(uint32_t typeId) noexcept { return typeId >= _kIntStart && typeId <= _kVec512End; }
+    1461        5466 :   static ASMJIT_INLINE bool isAbstract(uint32_t typeId) noexcept { return typeId >= kIntPtr && typeId <= kUIntPtr; }
+    1462        1870 :   static ASMJIT_INLINE bool isInt(uint32_t typeId) noexcept { return typeId >= _kIntStart && typeId <= _kIntEnd; }
+    1463           0 :   static ASMJIT_INLINE bool isGpb(uint32_t typeId) noexcept { return typeId >= kI8 && typeId <= kU8; }
+    1464           0 :   static ASMJIT_INLINE bool isGpw(uint32_t typeId) noexcept { return typeId >= kI16 && typeId <= kU16; }
+    1465             :   static ASMJIT_INLINE bool isGpd(uint32_t typeId) noexcept { return typeId >= kI32 && typeId <= kU32; }
+    1466             :   static ASMJIT_INLINE bool isGpq(uint32_t typeId) noexcept { return typeId >= kI64 && typeId <= kU64; }
+    1467        1450 :   static ASMJIT_INLINE bool isFloat(uint32_t typeId) noexcept { return typeId >= _kFloatStart && typeId <= _kFloatEnd; }
+    1468           0 :   static ASMJIT_INLINE bool isMask(uint32_t typeId) noexcept { return typeId >= _kMaskStart && typeId <= _kMaskEnd; }
+    1469           0 :   static ASMJIT_INLINE bool isMmx(uint32_t typeId) noexcept { return typeId >= _kMmxStart && typeId <= _kMmxEnd; }
+    1470             : 
+    1471           0 :   static ASMJIT_INLINE bool isVec(uint32_t typeId) noexcept { return typeId >= _kVec32Start && typeId <= _kVec512End; }
+    1472        9084 :   static ASMJIT_INLINE bool isVec32(uint32_t typeId) noexcept { return typeId >= _kVec32Start && typeId <= _kVec32End; }
+    1473        9084 :   static ASMJIT_INLINE bool isVec64(uint32_t typeId) noexcept { return typeId >= _kVec64Start && typeId <= _kVec64End; }
+    1474             :   static ASMJIT_INLINE bool isVec128(uint32_t typeId) noexcept { return typeId >= _kVec128Start && typeId <= _kVec128End; }
+    1475             :   static ASMJIT_INLINE bool isVec256(uint32_t typeId) noexcept { return typeId >= _kVec256Start && typeId <= _kVec256End; }
+    1476             :   static ASMJIT_INLINE bool isVec512(uint32_t typeId) noexcept { return typeId >= _kVec512Start && typeId <= _kVec512End; }
+    1477             : 
+    1478             :   static ASMJIT_INLINE uint32_t sizeOf(uint32_t typeId) noexcept {
+    1479             :     ASMJIT_ASSERT(typeId < ASMJIT_ARRAY_SIZE(_info.sizeOf));
+    1480       47576 :     return _info.sizeOf[typeId];
+    1481             :   }
+    1482             : 
+    1483             :   static ASMJIT_INLINE uint32_t elementOf(uint32_t typeId) noexcept {
+    1484             :     ASMJIT_ASSERT(typeId < ASMJIT_ARRAY_SIZE(_info.elementOf));
+    1485        9084 :     return _info.elementOf[typeId];
+    1486             :   }
+    1487             : 
+    1488             :   //! Get an offset to convert a `kIntPtr` and `kUIntPtr` TypeId into a
+    1489             :   //! type that matches `gpSize` (general-purpose register size). If you
+    1490             :   //! find such TypeId it's then only about adding the offset to it.
+    1491             :   //!
+    1492             :   //! For example:
+    1493             :   //! ~~~
+    1494             :   //! uint32_t gpSize = '4' or '8';
+    1495             :   //! uint32_t deabstractDelta = TypeId::deabstractDeltaOfSize(gpSize);
+    1496             :   //!
+    1497             :   //! uint32_t typeId = 'some type-id';
+    1498             :   //!
+    1499             :   //! // Normalize some typeId into a non-abstract typeId.
+    1500             :   //! if (TypeId::isAbstract(typeId)) typeId += deabstractDelta;
+    1501             :   //!
+    1502             :   //! // The same, but by using TypeId::deabstract() function.
+    1503             :   //! typeId = TypeId::deabstract(typeId, deabstractDelta);
+    1504             :   //! ~~~
+    1505             :   static ASMJIT_INLINE uint32_t deabstractDeltaOfSize(uint32_t gpSize) noexcept {
+    1506             :     return gpSize >= 8 ? kI64 - kIntPtr : kI32 - kIntPtr;
+    1507             :   }
+    1508             : 
+    1509             :   static ASMJIT_INLINE uint32_t deabstract(uint32_t typeId, uint32_t deabstractDelta) noexcept {
+    1510        5466 :     return TypeId::isAbstract(typeId) ? typeId += deabstractDelta : typeId;
+    1511             :   }
+    1512             : };
+    1513             : 
+    1514             : //! TypeIdOf<> template allows to get a TypeId of a C++ type.
+    1515             : template<typename T> struct TypeIdOf {
+    1516             :   // Don't provide anything if not specialized.
+    1517             : };
+    1518             : template<typename T> struct TypeIdOf<T*> {
+    1519             :   enum { kTypeId = TypeId::kUIntPtr };
+    1520             : };
+    1521             : 
+    1522             : template<typename T>
+    1523             : struct TypeIdOfInt {
+    1524             :   enum {
+    1525             :     kSigned = int(~T(0) < T(0)),
+    1526             :     kTypeId = (sizeof(T) == 1) ? (int)(kSigned ? TypeId::kI8  : TypeId::kU8 ) :
+    1527             :               (sizeof(T) == 2) ? (int)(kSigned ? TypeId::kI16 : TypeId::kU16) :
+    1528             :               (sizeof(T) == 4) ? (int)(kSigned ? TypeId::kI32 : TypeId::kU32) :
+    1529             :               (sizeof(T) == 8) ? (int)(kSigned ? TypeId::kI64 : TypeId::kU64) : (int)TypeId::kVoid
+    1530             :   };
+    1531             : };
+    1532             : 
+    1533             : #define ASMJIT_DEFINE_TYPE_ID(T, TYPE_ID) \
+    1534             :   template<> \
+    1535             :   struct TypeIdOf<T> { enum { kTypeId = TYPE_ID}; }
+    1536             : 
+    1537             : ASMJIT_DEFINE_TYPE_ID(signed char       , TypeIdOfInt< signed char        >::kTypeId);
+    1538             : ASMJIT_DEFINE_TYPE_ID(unsigned char     , TypeIdOfInt< unsigned char      >::kTypeId);
+    1539             : ASMJIT_DEFINE_TYPE_ID(short             , TypeIdOfInt< short              >::kTypeId);
+    1540             : ASMJIT_DEFINE_TYPE_ID(unsigned short    , TypeIdOfInt< unsigned short     >::kTypeId);
+    1541             : ASMJIT_DEFINE_TYPE_ID(int               , TypeIdOfInt< int                >::kTypeId);
+    1542             : ASMJIT_DEFINE_TYPE_ID(unsigned int      , TypeIdOfInt< unsigned int       >::kTypeId);
+    1543             : ASMJIT_DEFINE_TYPE_ID(long              , TypeIdOfInt< long               >::kTypeId);
+    1544             : ASMJIT_DEFINE_TYPE_ID(unsigned long     , TypeIdOfInt< unsigned long      >::kTypeId);
+    1545             : #if ASMJIT_CC_MSC && !ASMJIT_CC_MSC_GE(16, 0, 0)
+    1546             : ASMJIT_DEFINE_TYPE_ID(__int64           , TypeIdOfInt< __int64            >::kTypeId);
+    1547             : ASMJIT_DEFINE_TYPE_ID(unsigned __int64  , TypeIdOfInt< unsigned __int64   >::kTypeId);
+    1548             : #else
+    1549             : ASMJIT_DEFINE_TYPE_ID(long long         , TypeIdOfInt< long long          >::kTypeId);
+    1550             : ASMJIT_DEFINE_TYPE_ID(unsigned long long, TypeIdOfInt< unsigned long long >::kTypeId);
+    1551             : #endif
+    1552             : #if ASMJIT_CC_HAS_NATIVE_CHAR
+    1553             : ASMJIT_DEFINE_TYPE_ID(char              , TypeIdOfInt< char               >::kTypeId);
+    1554             : #endif
+    1555             : #if ASMJIT_CC_HAS_NATIVE_CHAR16_T
+    1556             : ASMJIT_DEFINE_TYPE_ID(char16_t          , TypeIdOfInt< char16_t           >::kTypeId);
+    1557             : #endif
+    1558             : #if ASMJIT_CC_HAS_NATIVE_CHAR32_T
+    1559             : ASMJIT_DEFINE_TYPE_ID(char32_t          , TypeIdOfInt< char32_t           >::kTypeId);
+    1560             : #endif
+    1561             : #if ASMJIT_CC_HAS_NATIVE_WCHAR_T
+    1562             : ASMJIT_DEFINE_TYPE_ID(wchar_t           , TypeIdOfInt< wchar_t            >::kTypeId);
+    1563             : #endif
+    1564             : 
+    1565             : ASMJIT_DEFINE_TYPE_ID(void              , TypeId::kVoid);
+    1566             : ASMJIT_DEFINE_TYPE_ID(bool              , TypeId::kI8);
+    1567             : ASMJIT_DEFINE_TYPE_ID(float             , TypeId::kF32);
+    1568             : ASMJIT_DEFINE_TYPE_ID(double            , TypeId::kF64);
+    1569             : 
+    1570             : ASMJIT_DEFINE_TYPE_ID(TypeId::Int8      , TypeId::kI8);
+    1571             : ASMJIT_DEFINE_TYPE_ID(TypeId::UInt8     , TypeId::kU8);
+    1572             : ASMJIT_DEFINE_TYPE_ID(TypeId::Int16     , TypeId::kI16);
+    1573             : ASMJIT_DEFINE_TYPE_ID(TypeId::UInt16    , TypeId::kU16);
+    1574             : ASMJIT_DEFINE_TYPE_ID(TypeId::Int32     , TypeId::kI32);
+    1575             : ASMJIT_DEFINE_TYPE_ID(TypeId::UInt32    , TypeId::kU32);
+    1576             : ASMJIT_DEFINE_TYPE_ID(TypeId::Int64     , TypeId::kI64);
+    1577             : ASMJIT_DEFINE_TYPE_ID(TypeId::UInt64    , TypeId::kU64);
+    1578             : ASMJIT_DEFINE_TYPE_ID(TypeId::IntPtr    , TypeId::kIntPtr);
+    1579             : ASMJIT_DEFINE_TYPE_ID(TypeId::UIntPtr   , TypeId::kUIntPtr);
+    1580             : ASMJIT_DEFINE_TYPE_ID(TypeId::Float     , TypeId::kF32);
+    1581             : ASMJIT_DEFINE_TYPE_ID(TypeId::Double    , TypeId::kF64);
+    1582             : ASMJIT_DEFINE_TYPE_ID(TypeId::MmxReg    , TypeId::kMmx64);
+    1583             : ASMJIT_DEFINE_TYPE_ID(TypeId::Vec128    , TypeId::kI32x4);
+    1584             : ASMJIT_DEFINE_TYPE_ID(TypeId::Vec256    , TypeId::kI32x8);
+    1585             : ASMJIT_DEFINE_TYPE_ID(TypeId::Vec512    , TypeId::kI32x16);
+    1586             : 
+    1587             : //! \}
+    1588             : 
+    1589             : } // asmjit namespace
+    1590             : } // namespace PLMD
+    1591             : 
+    1592             : // [Api-End]
+    1593             : #include "./asmjit_apiend.h"
+    1594             : 
+    1595             : // [Guard]
+    1596             : #endif // _ASMJIT_BASE_OPERAND_H
+    1597             : #pragma GCC diagnostic pop
+    1598             : #endif // __PLUMED_HAS_ASMJIT
+    1599             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.cpp.func-sort-c.html b/coverage-libs/asmjit/osutils.cpp.func-sort-c.html new file mode 100644 index 000000000000..d281f0be750b --- /dev/null +++ b/coverage-libs/asmjit/osutils.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:182281.8 %
Date:2024-02-22 21:58:47Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7OSUtils12getTickCountEv0
_ZN4PLMD6asmjit7OSUtils18allocVirtualMemoryEmPmj1948
_ZN4PLMD6asmjit7OSUtils20releaseVirtualMemoryEPvm1948
_ZN4PLMD6asmjit7OSUtils20getVirtualMemoryInfoEv1976
_ZN4PLMD6asmjitL19OSUtils_GetVMemInfoEv3924
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.cpp.func.html b/coverage-libs/asmjit/osutils.cpp.func.html new file mode 100644 index 000000000000..67d6fe4fbbe8 --- /dev/null +++ b/coverage-libs/asmjit/osutils.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:182281.8 %
Date:2024-02-22 21:58:47Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7OSUtils12getTickCountEv0
_ZN4PLMD6asmjit7OSUtils18allocVirtualMemoryEmPmj1948
_ZN4PLMD6asmjit7OSUtils20getVirtualMemoryInfoEv1976
_ZN4PLMD6asmjit7OSUtils20releaseVirtualMemoryEPvm1948
_ZN4PLMD6asmjitL19OSUtils_GetVMemInfoEv3924
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.cpp.gcov.html b/coverage-libs/asmjit/osutils.cpp.gcov.html new file mode 100644 index 000000000000..f7a3e03c560b --- /dev/null +++ b/coverage-libs/asmjit/osutils.cpp.gcov.html @@ -0,0 +1,331 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:182281.8 %
Date:2024-02-22 21:58:47Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./osutils.h"
+      34             : #include "./utils.h"
+      35             : 
+      36             : #if ASMJIT_OS_POSIX
+      37             : # include <sys/types.h>
+      38             : # include <sys/mman.h>
+      39             : # include <time.h>
+      40             : # include <unistd.h>
+      41             : #endif // ASMJIT_OS_POSIX
+      42             : 
+      43             : #if ASMJIT_OS_MAC
+      44             : # include <mach/mach_time.h>
+      45             : #endif // ASMJIT_OS_MAC
+      46             : 
+      47             : #if ASMJIT_OS_WINDOWS
+      48             : # if defined(_MSC_VER) && _MSC_VER >= 1400
+      49             : #  include <intrin.h>
+      50             : # else
+      51             : #  define _InterlockedCompareExchange InterlockedCompareExchange
+      52             : # endif // _MSC_VER
+      53             : #endif // ASMJIT_OS_WINDOWS
+      54             : 
+      55             : // [Api-Begin]
+      56             : #include "./asmjit_apibegin.h"
+      57             : 
+      58             : namespace PLMD {
+      59             : namespace asmjit {
+      60             : 
+      61             : // ============================================================================
+      62             : // [asmjit::OSUtils - Virtual Memory]
+      63             : // ============================================================================
+      64             : 
+      65             : // Windows specific implementation using `VirtualAllocEx` and `VirtualFree`.
+      66             : #if ASMJIT_OS_WINDOWS
+      67             : static ASMJIT_NOINLINE const VMemInfo& OSUtils_GetVMemInfo() noexcept {
+      68             :   static VMemInfo vmi;
+      69             : 
+      70             :   if (ASMJIT_UNLIKELY(!vmi.hCurrentProcess)) {
+      71             :     SYSTEM_INFO info;
+      72             :     ::GetSystemInfo(&info);
+      73             : 
+      74             :     vmi.pageSize = Utils::alignToPowerOf2<uint32_t>(info.dwPageSize);
+      75             :     vmi.pageGranularity = info.dwAllocationGranularity;
+      76             :     vmi.hCurrentProcess = ::GetCurrentProcess();
+      77             :   }
+      78             : 
+      79             :   return vmi;
+      80             : };
+      81             : 
+      82             : VMemInfo OSUtils::getVirtualMemoryInfo() noexcept { return OSUtils_GetVMemInfo(); }
+      83             : 
+      84             : void* OSUtils::allocVirtualMemory(size_t size, size_t* allocated, uint32_t flags) noexcept {
+      85             :   return allocProcessMemory(static_cast<HANDLE>(0), size, allocated, flags);
+      86             : }
+      87             : 
+      88             : Error OSUtils::releaseVirtualMemory(void* p, size_t size) noexcept {
+      89             :   return releaseProcessMemory(static_cast<HANDLE>(0), p, size);
+      90             : }
+      91             : 
+      92             : void* OSUtils::allocProcessMemory(HANDLE hProcess, size_t size, size_t* allocated, uint32_t flags) noexcept {
+      93             :   if (size == 0)
+      94             :     return nullptr;
+      95             : 
+      96             :   const VMemInfo& vmi = OSUtils_GetVMemInfo();
+      97             :   if (!hProcess) hProcess = vmi.hCurrentProcess;
+      98             : 
+      99             :   // VirtualAllocEx rounds the allocated size to a page size automatically,
+     100             :   // but we need the `alignedSize` so we can store the real allocated size
+     101             :   // into `allocated` output.
+     102             :   size_t alignedSize = Utils::alignTo(size, vmi.pageSize);
+     103             : 
+     104             :   // Windows XP SP2 / Vista+ allow data-execution-prevention (DEP).
+     105             :   DWORD protectFlags = 0;
+     106             : 
+     107             :   if (flags & kVMExecutable)
+     108             :     protectFlags |= (flags & kVMWritable) ? PAGE_EXECUTE_READWRITE : PAGE_EXECUTE_READ;
+     109             :   else
+     110             :     protectFlags |= (flags & kVMWritable) ? PAGE_READWRITE : PAGE_READONLY;
+     111             : 
+     112             :   LPVOID mBase = ::VirtualAllocEx(hProcess, nullptr, alignedSize, MEM_COMMIT | MEM_RESERVE, protectFlags);
+     113             :   if (ASMJIT_UNLIKELY(!mBase)) return nullptr;
+     114             : 
+     115             :   ASMJIT_ASSERT(Utils::isAligned<size_t>(reinterpret_cast<size_t>(mBase), vmi.pageSize));
+     116             :   if (allocated) *allocated = alignedSize;
+     117             :   return mBase;
+     118             : }
+     119             : 
+     120             : Error OSUtils::releaseProcessMemory(HANDLE hProcess, void* p, size_t size) noexcept {
+     121             :   const VMemInfo& vmi = OSUtils_GetVMemInfo();
+     122             :   if (!hProcess) hProcess = vmi.hCurrentProcess;
+     123             : 
+     124             :   if (ASMJIT_UNLIKELY(!::VirtualFreeEx(hProcess, p, 0, MEM_RELEASE)))
+     125             :     return DebugUtils::errored(kErrorInvalidState);
+     126             : 
+     127             :   return kErrorOk;
+     128             : }
+     129             : #endif // ASMJIT_OS_WINDOWS
+     130             : 
+     131             : // Posix specific implementation using `mmap()` and `munmap()`.
+     132             : #if ASMJIT_OS_POSIX
+     133             : 
+     134             : // Mac uses MAP_ANON instead of MAP_ANONYMOUS.
+     135             : #if !defined(MAP_ANONYMOUS)
+     136             : # define MAP_ANONYMOUS MAP_ANON
+     137             : #endif // MAP_ANONYMOUS
+     138             : 
+     139        3924 : static const VMemInfo& OSUtils_GetVMemInfo() noexcept {
+     140             :   static VMemInfo vmi;
+     141        3924 :   if (ASMJIT_UNLIKELY(!vmi.pageSize)) {
+     142          70 :     size_t pageSize = ::getpagesize();
+     143          70 :     vmi.pageSize = pageSize;
+     144         140 :     vmi.pageGranularity = std::max<size_t>(pageSize, 65536);
+     145             :   }
+     146        3924 :   return vmi;
+     147             : };
+     148             : 
+     149        1976 : VMemInfo OSUtils::getVirtualMemoryInfo() noexcept { return OSUtils_GetVMemInfo(); }
+     150             : 
+     151        1948 : void* OSUtils::allocVirtualMemory(size_t size, size_t* allocated, uint32_t flags) noexcept {
+     152        1948 :   const VMemInfo& vmi = OSUtils_GetVMemInfo();
+     153             : 
+     154        1948 :   size_t alignedSize = Utils::alignTo<size_t>(size, vmi.pageSize);
+     155             :   int protection = PROT_READ;
+     156             : 
+     157        1948 :   if (flags & kVMWritable  ) protection |= PROT_WRITE;
+     158        1948 :   if (flags & kVMExecutable) protection |= PROT_EXEC;
+     159             : 
+     160        1948 :   void* mbase = ::mmap(nullptr, alignedSize, protection, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
+     161        1948 :   if (ASMJIT_UNLIKELY(mbase == MAP_FAILED)) return nullptr;
+     162             : 
+     163        1948 :   if (allocated) *allocated = alignedSize;
+     164             :   return mbase;
+     165             : }
+     166             : 
+     167        1948 : Error OSUtils::releaseVirtualMemory(void* p, size_t size) noexcept {
+     168        1948 :   if (ASMJIT_UNLIKELY(::munmap(p, size) != 0))
+     169             :     return DebugUtils::errored(kErrorInvalidState);
+     170             : 
+     171        1948 :   return kErrorOk;
+     172             : }
+     173             : #endif // ASMJIT_OS_POSIX
+     174             : 
+     175             : // ============================================================================
+     176             : // [asmjit::OSUtils - GetTickCount]
+     177             : // ============================================================================
+     178             : 
+     179             : #if ASMJIT_OS_WINDOWS
+     180             : static ASMJIT_INLINE uint32_t OSUtils_calcHiRes(const LARGE_INTEGER& now, double freq) noexcept {
+     181             :   return static_cast<uint32_t>(
+     182             :     (int64_t)(double(now.QuadPart) / freq) & 0xFFFFFFFF);
+     183             : }
+     184             : 
+     185             : uint32_t OSUtils::getTickCount() noexcept {
+     186             :   static volatile uint32_t _hiResTicks;
+     187             :   static volatile double _hiResFreq;
+     188             : 
+     189             :   do {
+     190             :     uint32_t hiResOk = _hiResTicks;
+     191             :     LARGE_INTEGER qpf, now;
+     192             : 
+     193             :     // If for whatever reason this fails, bail to `GetTickCount()`.
+     194             :     if (!::QueryPerformanceCounter(&now)) break;
+     195             : 
+     196             :     // Expected - if we ran through this at least once `hiResTicks` will be
+     197             :     // either 1 or 0xFFFFFFFF. If it's '1' then the Hi-Res counter is available
+     198             :     // and `QueryPerformanceCounter()` can be used.
+     199             :     if (hiResOk == 1) return OSUtils_calcHiRes(now, _hiResFreq);
+     200             : 
+     201             :     // Hi-Res counter is not available, bail to `GetTickCount()`.
+     202             :     if (hiResOk != 0) break;
+     203             : 
+     204             :     // Detect availability of Hi-Res counter, if not available, bail to `GetTickCount()`.
+     205             :     if (!::QueryPerformanceFrequency(&qpf)) {
+     206             :       _InterlockedCompareExchange((LONG*)&_hiResTicks, 0xFFFFFFFF, 0);
+     207             :       break;
+     208             :     }
+     209             : 
+     210             :     double freq = double(qpf.QuadPart) / 1000.0;
+     211             :     _hiResFreq = freq;
+     212             : 
+     213             :     _InterlockedCompareExchange((LONG*)&_hiResTicks, 1, 0);
+     214             :     return OSUtils_calcHiRes(now, freq);
+     215             :   } while (0);
+     216             : 
+     217             :   return ::GetTickCount();
+     218             : }
+     219             : #elif ASMJIT_OS_MAC
+     220             : uint32_t OSUtils::getTickCount() noexcept {
+     221             :   static mach_timebase_info_data_t _machTime;
+     222             : 
+     223             :   // See Apple's QA1398.
+     224             :   if (ASMJIT_UNLIKELY(_machTime.denom == 0) || mach_timebase_info(&_machTime) != KERN_SUCCESS)
+     225             :     return 0;
+     226             : 
+     227             :   // `mach_absolute_time()` returns nanoseconds, we want milliseconds.
+     228             :   uint64_t t = mach_absolute_time() / 1000000;
+     229             : 
+     230             :   t = t * _machTime.numer / _machTime.denom;
+     231             :   return static_cast<uint32_t>(t & 0xFFFFFFFFU);
+     232             : }
+     233             : #elif defined(_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
+     234           0 : uint32_t OSUtils::getTickCount() noexcept {
+     235             :   struct timespec ts;
+     236             : 
+     237           0 :   if (ASMJIT_UNLIKELY(clock_gettime(CLOCK_MONOTONIC, &ts) != 0))
+     238             :     return 0;
+     239             : 
+     240           0 :   uint64_t t = (uint64_t(ts.tv_sec ) * 1000) + (uint64_t(ts.tv_nsec) / 1000000);
+     241           0 :   return static_cast<uint32_t>(t & 0xFFFFFFFFU);
+     242             : }
+     243             : #else
+     244             : #error "[asmjit] OSUtils::getTickCount() is not implemented for your target OS."
+     245             : uint32_t OSUtils::getTickCount() noexcept { return 0; }
+     246             : #endif
+     247             : 
+     248             : } // asmjit namespace
+     249             : } // namespace PLMD
+     250             : 
+     251             : // [Api-End]
+     252             : #include "./asmjit_apiend.h"
+     253             : #pragma GCC diagnostic pop
+     254             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.h.func-sort-c.html b/coverage-libs/asmjit/osutils.h.func-sort-c.html new file mode 100644 index 000000000000..ec6f9eca20e5 --- /dev/null +++ b/coverage-libs/asmjit/osutils.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:55100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.h.func.html b/coverage-libs/asmjit/osutils.h.func.html new file mode 100644 index 000000000000..05af8c49842a --- /dev/null +++ b/coverage-libs/asmjit/osutils.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:55100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/osutils.h.gcov.html b/coverage-libs/asmjit/osutils.h.gcov.html new file mode 100644 index 000000000000..f5d0234ec3ae --- /dev/null +++ b/coverage-libs/asmjit/osutils.h.gcov.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/osutils.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - osutils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:55100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_osutils_h
+      21             : #define __PLUMED_asmjit_osutils_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_OSUTILS_H
+      33             : #define _ASMJIT_BASE_OSUTILS_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./globals.h"
+      37             : 
+      38             : // [Api-Begin]
+      39             : #include "./asmjit_apibegin.h"
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace asmjit {
+      43             : 
+      44             : //! \addtogroup asmjit_base
+      45             : //! \{
+      46             : 
+      47             : // ============================================================================
+      48             : // [asmjit::VMemInfo]
+      49             : // ============================================================================
+      50             : 
+      51             : //! Information about OS virtual memory.
+      52             : struct VMemInfo {
+      53             : #if ASMJIT_OS_WINDOWS
+      54             :   HANDLE hCurrentProcess;                //!< Handle of the current process (Windows).
+      55             : #endif // ASMJIT_OS_WINDOWS
+      56             :   size_t pageSize;                       //!< Virtual memory page size.
+      57             :   size_t pageGranularity;                //!< Virtual memory page granularity.
+      58             : };
+      59             : 
+      60             : // ============================================================================
+      61             : // [asmjit::OSUtils]
+      62             : // ============================================================================
+      63             : 
+      64             : //! OS utilities.
+      65             : //!
+      66             : //! Virtual Memory
+      67             : //! --------------
+      68             : //!
+      69             : //! Provides functions to allocate and release virtual memory that is required
+      70             : //! to execute dynamically generated code. If both processor and host OS support
+      71             : //! data-execution-prevention (DEP) then the only way to run machine code is to
+      72             : //! allocate virtual memory that has `OSUtils::kVMExecutable` flag enabled. All
+      73             : //! functions provides by OSUtils use internally platform specific API.
+      74             : //!
+      75             : //! Benchmarking
+      76             : //! ------------
+      77             : //!
+      78             : //! OSUtils also provide a function `getTickCount()` that can be used for
+      79             : //! benchmarking purposes. It's similar to Windows-only `GetTickCount()`, but
+      80             : //! it's cross-platform and tries to be the most reliable platform specific
+      81             : //! calls to make the result usable.
+      82             : struct OSUtils {
+      83             :   // --------------------------------------------------------------------------
+      84             :   // [Virtual Memory]
+      85             :   // --------------------------------------------------------------------------
+      86             : 
+      87             :   //! Virtual memory flags.
+      88             :   ASMJIT_ENUM(VMFlags) {
+      89             :     kVMWritable   = 0x00000001U,         //!< Virtual memory is writable.
+      90             :     kVMExecutable = 0x00000002U          //!< Virtual memory is executable.
+      91             :   };
+      92             : 
+      93             :   ASMJIT_API static VMemInfo getVirtualMemoryInfo() noexcept;
+      94             : 
+      95             :   //! Allocate virtual memory.
+      96             :   ASMJIT_API static void* allocVirtualMemory(size_t size, size_t* allocated, uint32_t flags) noexcept;
+      97             :   //! Release virtual memory previously allocated by \ref allocVirtualMemory().
+      98             :   ASMJIT_API static Error releaseVirtualMemory(void* p, size_t size) noexcept;
+      99             : 
+     100             : #if ASMJIT_OS_WINDOWS
+     101             :   //! Allocate virtual memory of `hProcess` (Windows).
+     102             :   ASMJIT_API static void* allocProcessMemory(HANDLE hProcess, size_t size, size_t* allocated, uint32_t flags) noexcept;
+     103             : 
+     104             :   //! Release virtual memory of `hProcess` (Windows).
+     105             :   ASMJIT_API static Error releaseProcessMemory(HANDLE hProcess, void* p, size_t size) noexcept;
+     106             : #endif // ASMJIT_OS_WINDOWS
+     107             : 
+     108             :   // --------------------------------------------------------------------------
+     109             :   // [GetTickCount]
+     110             :   // --------------------------------------------------------------------------
+     111             : 
+     112             :   //! Get the current CPU tick count, used for benchmarking (1ms resolution).
+     113             :   ASMJIT_API static uint32_t getTickCount() noexcept;
+     114             : };
+     115             : 
+     116             : // ============================================================================
+     117             : // [asmjit::Lock]
+     118             : // ============================================================================
+     119             : 
+     120             : //! \internal
+     121             : //!
+     122             : //! Lock.
+     123             : struct Lock {
+     124             :   ASMJIT_NONCOPYABLE(Lock)
+     125             : 
+     126             :   // --------------------------------------------------------------------------
+     127             :   // [Windows]
+     128             :   // --------------------------------------------------------------------------
+     129             : 
+     130             : #if ASMJIT_OS_WINDOWS
+     131             :   typedef CRITICAL_SECTION Handle;
+     132             : 
+     133             :   //! Create a new `Lock` instance.
+     134             :   ASMJIT_INLINE Lock() noexcept { InitializeCriticalSection(&_handle); }
+     135             :   //! Destroy the `Lock` instance.
+     136             :   ASMJIT_INLINE ~Lock() noexcept { DeleteCriticalSection(&_handle); }
+     137             : 
+     138             :   //! Lock.
+     139             :   ASMJIT_INLINE void lock() noexcept { EnterCriticalSection(&_handle); }
+     140             :   //! Unlock.
+     141             :   ASMJIT_INLINE void unlock() noexcept { LeaveCriticalSection(&_handle); }
+     142             : #endif // ASMJIT_OS_WINDOWS
+     143             : 
+     144             :   // --------------------------------------------------------------------------
+     145             :   // [Posix]
+     146             :   // --------------------------------------------------------------------------
+     147             : 
+     148             : #if ASMJIT_OS_POSIX
+     149             :   typedef pthread_mutex_t Handle;
+     150             : 
+     151             :   //! Create a new `Lock` instance.
+     152        1976 :   ASMJIT_INLINE Lock() noexcept { pthread_mutex_init(&_handle, nullptr); }
+     153             :   //! Destroy the `Lock` instance.
+     154        1976 :   ASMJIT_INLINE ~Lock() noexcept { pthread_mutex_destroy(&_handle); }
+     155             : 
+     156             :   //! Lock.
+     157        1948 :   ASMJIT_INLINE void lock() noexcept { pthread_mutex_lock(&_handle); }
+     158             :   //! Unlock.
+     159        1948 :   ASMJIT_INLINE void unlock() noexcept { pthread_mutex_unlock(&_handle); }
+     160             : #endif // ASMJIT_OS_POSIX
+     161             : 
+     162             :   // --------------------------------------------------------------------------
+     163             :   // [Members]
+     164             :   // --------------------------------------------------------------------------
+     165             : 
+     166             :   //! Native handle.
+     167             :   Handle _handle;
+     168             : };
+     169             : 
+     170             : // ============================================================================
+     171             : // [asmjit::AutoLock]
+     172             : // ============================================================================
+     173             : 
+     174             : //! \internal
+     175             : //!
+     176             : //! Scoped lock.
+     177             : struct AutoLock {
+     178             :   ASMJIT_NONCOPYABLE(AutoLock)
+     179             : 
+     180             :   // --------------------------------------------------------------------------
+     181             :   // [Construction / Destruction]
+     182             :   // --------------------------------------------------------------------------
+     183             : 
+     184             :   ASMJIT_INLINE AutoLock(Lock& target) noexcept : _target(target) { _target.lock(); }
+     185        1948 :   ASMJIT_INLINE ~AutoLock() noexcept { _target.unlock(); }
+     186             : 
+     187             :   // --------------------------------------------------------------------------
+     188             :   // [Members]
+     189             :   // --------------------------------------------------------------------------
+     190             : 
+     191             :   //! Reference to the `Lock`.
+     192             :   Lock& _target;
+     193             : };
+     194             : 
+     195             : //! \}
+     196             : 
+     197             : } // asmjit namespace
+     198             : } // namespace PLMD
+     199             : 
+     200             : // [Api-End]
+     201             : #include "./asmjit_apiend.h"
+     202             : 
+     203             : // [Guard]
+     204             : #endif // _ASMJIT_BASE_OSUTILS_H
+     205             : #pragma GCC diagnostic pop
+     206             : #endif // __PLUMED_HAS_ASMJIT
+     207             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc.cpp.func-sort-c.html b/coverage-libs/asmjit/regalloc.cpp.func-sort-c.html new file mode 100644 index 000000000000..afbc39d74940 --- /dev/null +++ b/coverage-libs/asmjit/regalloc.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11424147.3 %
Date:2024-02-22 21:58:47Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit6RAPass13_newStackCellEjj0
_ZN4PLMD6asmjit6RAPass19formatInlineCommentERNS0_13StringBuilderEPNS0_6CBNodeE0
_ZN4PLMD6asmjit6RAPassD0Ev0
_ZN4PLMD6asmjit6RAPassD2Ev0
_ZN4PLMD6asmjit6RAPass16livenessAnalysisEv1948
_ZN4PLMD6asmjit6RAPass18resolveCellOffsetsEv1948
_ZN4PLMD6asmjit6RAPass21removeUnreachableCodeEv1948
_ZN4PLMD6asmjit6RAPass7cleanupEv1948
_ZN4PLMD6asmjit6RAPass7compileEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit6RAPass7prepareEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit6RAPass7processEPNS0_4ZoneE1948
_ZN4PLMD6asmjit6RAPassC2Ev1948
_ZN4PLMD6asmjit6RAPass11_newVarCellEPNS0_7VirtRegE4004
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc.cpp.func.html b/coverage-libs/asmjit/regalloc.cpp.func.html new file mode 100644 index 000000000000..67186041f596 --- /dev/null +++ b/coverage-libs/asmjit/regalloc.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11424147.3 %
Date:2024-02-22 21:58:47Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit6RAPass11_newVarCellEPNS0_7VirtRegE4004
_ZN4PLMD6asmjit6RAPass13_newStackCellEjj0
_ZN4PLMD6asmjit6RAPass16livenessAnalysisEv1948
_ZN4PLMD6asmjit6RAPass18resolveCellOffsetsEv1948
_ZN4PLMD6asmjit6RAPass19formatInlineCommentERNS0_13StringBuilderEPNS0_6CBNodeE0
_ZN4PLMD6asmjit6RAPass21removeUnreachableCodeEv1948
_ZN4PLMD6asmjit6RAPass7cleanupEv1948
_ZN4PLMD6asmjit6RAPass7compileEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit6RAPass7prepareEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit6RAPass7processEPNS0_4ZoneE1948
_ZN4PLMD6asmjit6RAPassC2Ev1948
_ZN4PLMD6asmjit6RAPassD0Ev0
_ZN4PLMD6asmjit6RAPassD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc.cpp.gcov.html b/coverage-libs/asmjit/regalloc.cpp.gcov.html new file mode 100644 index 000000000000..f8684fbec268 --- /dev/null +++ b/coverage-libs/asmjit/regalloc.cpp.gcov.html @@ -0,0 +1,697 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11424147.3 %
Date:2024-02-22 21:58:47Functions:91369.2 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Guard]
+      33             : #include "./asmjit_build.h"
+      34             : #if !defined(ASMJIT_DISABLE_COMPILER)
+      35             : 
+      36             : // [Dependencies]
+      37             : #include "./regalloc_p.h"
+      38             : #include "./utils.h"
+      39             : 
+      40             : // [Api-Begin]
+      41             : #include "./asmjit_apibegin.h"
+      42             : 
+      43             : namespace PLMD {
+      44             : namespace asmjit {
+      45             : 
+      46             : // ============================================================================
+      47             : // [asmjit::RAPass - Construction / Destruction]
+      48             : // ============================================================================
+      49             : 
+      50        1948 : RAPass::RAPass() noexcept :
+      51             :   CBPass("RA"),
+      52        1948 :   _varMapToVaListOffset(0) {}
+      53           0 : RAPass::~RAPass() noexcept {}
+      54             : 
+      55             : // ============================================================================
+      56             : // [asmjit::RAPass - Interface]
+      57             : // ============================================================================
+      58             : 
+      59        1948 : Error RAPass::process(Zone* zone) noexcept {
+      60        1948 :   _zone = zone;
+      61        1948 :   _heap.reset(zone);
+      62        1948 :   _emitComments = (cb()->getGlobalOptions() & CodeEmitter::kOptionLoggingEnabled) != 0;
+      63             : 
+      64             :   Error err = kErrorOk;
+      65             :   CBNode* node = cc()->getFirstNode();
+      66        1948 :   if (!node) return err;
+      67             : 
+      68             :   do {
+      69        1948 :     if (node->getType() == CBNode::kNodeFunc) {
+      70             :       CCFunc* func = static_cast<CCFunc*>(node);
+      71             :       node = func->getEnd();
+      72             : 
+      73        1948 :       err = compile(func);
+      74        1948 :       if (err) break;
+      75             :     }
+      76             : 
+      77             :     // Find a function by skipping all nodes that are not `kNodeFunc`.
+      78             :     do {
+      79             :       node = node->getNext();
+      80        1948 :     } while (node && node->getType() != CBNode::kNodeFunc);
+      81        1948 :   } while (node);
+      82             : 
+      83        1948 :   _heap.reset(nullptr);
+      84        1948 :   _zone = nullptr;
+      85        1948 :   return err;
+      86             : }
+      87             : 
+      88        1948 : Error RAPass::compile(CCFunc* func) noexcept {
+      89        1948 :   ASMJIT_PROPAGATE(prepare(func));
+      90             : 
+      91             :   Error err;
+      92             :   do {
+      93        1948 :     err = fetch();
+      94        1948 :     if (err) break;
+      95             : 
+      96        1948 :     err = removeUnreachableCode();
+      97        1948 :     if (err) break;
+      98             : 
+      99        1948 :     err = livenessAnalysis();
+     100        1948 :     if (err) break;
+     101             : 
+     102             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     103        1948 :     if (cc()->getGlobalOptions() & CodeEmitter::kOptionLoggingEnabled) {
+     104           0 :       err = annotate();
+     105           0 :       if (err) break;
+     106             :     }
+     107             : #endif // !ASMJIT_DISABLE_LOGGING
+     108             : 
+     109        1948 :     err = translate();
+     110             :   } while (false);
+     111             : 
+     112        1948 :   cleanup();
+     113             : 
+     114             :   // We alter the compiler cursor, because it doesn't make sense to reference
+     115             :   // it after compilation - some nodes may disappear and it's forbidden to add
+     116             :   // new code after the compilation is done.
+     117             :   cc()->_setCursor(nullptr);
+     118        1948 :   return err;
+     119             : }
+     120             : 
+     121        1948 : Error RAPass::prepare(CCFunc* func) noexcept {
+     122             :   CBNode* end = func->getEnd();
+     123             : 
+     124        1948 :   _func = func;
+     125        1948 :   _stop = end->getNext();
+     126             : 
+     127             :   _unreachableList.reset();
+     128             :   _returningList.reset();
+     129             :   _jccList.reset();
+     130             :   _contextVd.reset();
+     131             : 
+     132        1948 :   _memVarCells = nullptr;
+     133        1948 :   _memStackCells = nullptr;
+     134             : 
+     135        1948 :   _mem1ByteVarsUsed = 0;
+     136        1948 :   _mem2ByteVarsUsed = 0;
+     137        1948 :   _mem4ByteVarsUsed = 0;
+     138        1948 :   _mem8ByteVarsUsed = 0;
+     139        1948 :   _mem16ByteVarsUsed = 0;
+     140        1948 :   _mem32ByteVarsUsed = 0;
+     141        1948 :   _mem64ByteVarsUsed = 0;
+     142        1948 :   _memStackCellsUsed = 0;
+     143             : 
+     144        1948 :   _memMaxAlign = 0;
+     145        1948 :   _memVarTotal = 0;
+     146        1948 :   _memStackTotal = 0;
+     147        1948 :   _memAllTotal = 0;
+     148        1948 :   _annotationLength = 12;
+     149             : 
+     150        1948 :   return kErrorOk;
+     151             : }
+     152             : 
+     153        1948 : void RAPass::cleanup() noexcept {
+     154             :   VirtReg** virtArray = _contextVd.getData();
+     155             :   size_t virtCount = _contextVd.getLength();
+     156             : 
+     157       25736 :   for (size_t i = 0; i < virtCount; i++) {
+     158       23788 :     VirtReg* vreg = virtArray[i];
+     159       23788 :     vreg->_raId = kInvalidValue;
+     160             :     vreg->resetPhysId();
+     161             :   }
+     162             : 
+     163             :   _contextVd.reset();
+     164        1948 : }
+     165             : 
+     166             : // ============================================================================
+     167             : // [asmjit::RAPass - Mem]
+     168             : // ============================================================================
+     169             : 
+     170             : static ASMJIT_INLINE uint32_t RAGetDefaultAlignment(uint32_t size) {
+     171           0 :   if (size > 32)
+     172             :     return 64;
+     173           0 :   else if (size > 16)
+     174             :     return 32;
+     175           0 :   else if (size > 8)
+     176             :     return 16;
+     177           0 :   else if (size > 4)
+     178             :     return 8;
+     179           0 :   else if (size > 2)
+     180             :     return 4;
+     181           0 :   else if (size > 1)
+     182             :     return 2;
+     183             :   else
+     184           0 :     return 1;
+     185             : }
+     186             : 
+     187        4004 : RACell* RAPass::_newVarCell(VirtReg* vreg) {
+     188             :   ASMJIT_ASSERT(vreg->_memCell == nullptr);
+     189             : 
+     190             :   RACell* cell;
+     191        4004 :   uint32_t size = vreg->getSize();
+     192             : 
+     193        4004 :   if (vreg->isStack()) {
+     194           0 :     cell = _newStackCell(size, vreg->getAlignment());
+     195           0 :     if (ASMJIT_UNLIKELY(!cell)) return nullptr;
+     196             :   }
+     197             :   else {
+     198        4004 :     cell = static_cast<RACell*>(_zone->alloc(sizeof(RACell)));
+     199        4004 :     if (!cell) goto _NoMemory;
+     200             : 
+     201        4004 :     cell->next = _memVarCells;
+     202        4004 :     cell->offset = 0;
+     203        4004 :     cell->size = size;
+     204        4004 :     cell->alignment = size;
+     205             : 
+     206        4004 :     _memVarCells = cell;
+     207        4004 :     _memMaxAlign = std::max<uint32_t>(_memMaxAlign, size);
+     208        4004 :     _memVarTotal += size;
+     209             : 
+     210        4004 :     switch (size) {
+     211           0 :       case  1: _mem1ByteVarsUsed++ ; break;
+     212           0 :       case  2: _mem2ByteVarsUsed++ ; break;
+     213           0 :       case  4: _mem4ByteVarsUsed++ ; break;
+     214        4004 :       case  8: _mem8ByteVarsUsed++ ; break;
+     215           0 :       case 16: _mem16ByteVarsUsed++; break;
+     216           0 :       case 32: _mem32ByteVarsUsed++; break;
+     217           0 :       case 64: _mem64ByteVarsUsed++; break;
+     218             : 
+     219           0 :       default:
+     220           0 :         ASMJIT_NOT_REACHED();
+     221             :     }
+     222             :   }
+     223             : 
+     224        4004 :   vreg->_memCell = cell;
+     225        4004 :   return cell;
+     226             : 
+     227             : _NoMemory:
+     228           0 :   cc()->setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     229             :   return nullptr;
+     230             : }
+     231             : 
+     232           0 : RACell* RAPass::_newStackCell(uint32_t size, uint32_t alignment) {
+     233           0 :   RACell* cell = static_cast<RACell*>(_zone->alloc(sizeof(RACell)));
+     234           0 :   if (ASMJIT_UNLIKELY(!cell)) return nullptr;
+     235             : 
+     236           0 :   if (alignment == 0)
+     237           0 :     alignment = RAGetDefaultAlignment(size);
+     238             : 
+     239           0 :   if (alignment > 64)
+     240           0 :     alignment = 64;
+     241             : 
+     242             :   ASMJIT_ASSERT(Utils::isPowerOf2(alignment));
+     243           0 :   size = Utils::alignTo<uint32_t>(size, alignment);
+     244             : 
+     245             :   // Insert it sorted according to the alignment and size.
+     246             :   {
+     247           0 :     RACell** pPrev = &_memStackCells;
+     248           0 :     RACell* cur = *pPrev;
+     249             : 
+     250           0 :     while (cur && ((cur->alignment > alignment) || (cur->alignment == alignment && cur->size > size))) {
+     251           0 :       pPrev = &cur->next;
+     252           0 :       cur = *pPrev;
+     253             :     }
+     254             : 
+     255           0 :     cell->next = cur;
+     256           0 :     cell->offset = 0;
+     257           0 :     cell->size = size;
+     258           0 :     cell->alignment = alignment;
+     259             : 
+     260           0 :     *pPrev = cell;
+     261           0 :     _memStackCellsUsed++;
+     262             : 
+     263           0 :     _memMaxAlign = std::max<uint32_t>(_memMaxAlign, alignment);
+     264           0 :     _memStackTotal += size;
+     265             :   }
+     266             : 
+     267           0 :   return cell;
+     268             : }
+     269             : 
+     270        1948 : Error RAPass::resolveCellOffsets() {
+     271        1948 :   RACell* varCell = _memVarCells;
+     272        1948 :   RACell* stackCell = _memStackCells;
+     273             : 
+     274             :   uint32_t pos64 = 0;
+     275        1948 :   uint32_t pos32 = pos64 + _mem64ByteVarsUsed * 64;
+     276        1948 :   uint32_t pos16 = pos32 + _mem32ByteVarsUsed * 32;
+     277        1948 :   uint32_t pos8  = pos16 + _mem16ByteVarsUsed * 16;
+     278        1948 :   uint32_t pos4  = pos8  + _mem8ByteVarsUsed  * 8 ;
+     279        1948 :   uint32_t pos2  = pos4  + _mem4ByteVarsUsed  * 4 ;
+     280        1948 :   uint32_t pos1  = pos2  + _mem2ByteVarsUsed  * 2 ;
+     281             : 
+     282             :   // Assign home slots.
+     283        5952 :   while (varCell) {
+     284        4004 :     uint32_t size = varCell->size;
+     285             :     uint32_t offset = 0;
+     286             : 
+     287        4004 :     switch (size) {
+     288           0 :       case  1: offset = pos1 ; pos1  += 1 ; break;
+     289           0 :       case  2: offset = pos2 ; pos2  += 2 ; break;
+     290           0 :       case  4: offset = pos4 ; pos4  += 4 ; break;
+     291        4004 :       case  8: offset = pos8 ; pos8  += 8 ; break;
+     292           0 :       case 16: offset = pos16; pos16 += 16; break;
+     293           0 :       case 32: offset = pos32; pos32 += 32; break;
+     294           0 :       case 64: offset = pos64; pos64 += 64; break;
+     295             : 
+     296           0 :       default:
+     297           0 :         ASMJIT_NOT_REACHED();
+     298             :     }
+     299             : 
+     300        4004 :     varCell->offset = static_cast<int32_t>(offset);
+     301        4004 :     varCell = varCell->next;
+     302             :   }
+     303             : 
+     304             :   // Assign stack slots.
+     305        1948 :   uint32_t stackPos = pos1 + _mem1ByteVarsUsed;
+     306        1948 :   while (stackCell) {
+     307           0 :     uint32_t size = stackCell->size;
+     308           0 :     uint32_t alignment = stackCell->alignment;
+     309             :     ASMJIT_ASSERT(alignment != 0 && Utils::isPowerOf2(alignment));
+     310             : 
+     311             :     stackPos = Utils::alignTo(stackPos, alignment);
+     312           0 :     stackCell->offset = stackPos;
+     313           0 :     stackCell = stackCell->next;
+     314             : 
+     315           0 :     stackPos += size;
+     316             :   }
+     317             : 
+     318        1948 :   _memAllTotal = stackPos;
+     319        1948 :   return kErrorOk;
+     320             : }
+     321             : 
+     322             : // ============================================================================
+     323             : // [asmjit::RAPass - RemoveUnreachableCode]
+     324             : // ============================================================================
+     325             : 
+     326        1948 : Error RAPass::removeUnreachableCode() {
+     327             :   ZoneList<CBNode*>::Link* link = _unreachableList.getFirst();
+     328             :   CBNode* stop = getStop();
+     329             : 
+     330        3896 :   while (link) {
+     331             :     CBNode* node = link->getValue();
+     332        1948 :     if (node && node->getPrev() && node != stop) {
+     333             :       // Locate all unreachable nodes.
+     334             :       CBNode* first = node;
+     335             :       do {
+     336        1948 :         if (node->hasPassData()) break;
+     337             :         node = node->getNext();
+     338           0 :       } while (node != stop);
+     339             : 
+     340             :       // Remove unreachable nodes that are neither informative nor directives.
+     341        1948 :       if (node != first) {
+     342             :         CBNode* end = node;
+     343             :         node = first;
+     344             : 
+     345             :         // NOTE: The strategy is as follows:
+     346             :         // 1. The algorithm removes everything until it finds a first label.
+     347             :         // 2. After the first label is found it removes only removable nodes.
+     348             :         bool removeEverything = true;
+     349             :         do {
+     350             :           CBNode* next = node->getNext();
+     351             :           bool remove = node->isRemovable();
+     352             : 
+     353           0 :           if (!remove) {
+     354           0 :             if (node->isLabel())
+     355             :               removeEverything = false;
+     356             :             remove = removeEverything;
+     357             :           }
+     358             : 
+     359           0 :           if (remove)
+     360           0 :             cc()->removeNode(node);
+     361             : 
+     362             :           node = next;
+     363           0 :         } while (node != end);
+     364             :       }
+     365             :     }
+     366             : 
+     367             :     link = link->getNext();
+     368             :   }
+     369             : 
+     370        1948 :   return kErrorOk;
+     371             : }
+     372             : 
+     373             : // ============================================================================
+     374             : // [asmjit::RAPass - Liveness Analysis]
+     375             : // ============================================================================
+     376             : 
+     377             : //! \internal
+     378             : struct LivenessTarget {
+     379             :   LivenessTarget* prev;  //!< Previous target.
+     380             :   CBLabel* node;         //!< Target node.
+     381             :   CBJump* from;          //!< Jumped from.
+     382             : };
+     383             : 
+     384        1948 : Error RAPass::livenessAnalysis() {
+     385             :   uint32_t bLen = static_cast<uint32_t>(
+     386        1948 :     ((_contextVd.getLength() + RABits::kEntityBits - 1) / RABits::kEntityBits));
+     387             : 
+     388             :   // No variables.
+     389        1948 :   if (bLen == 0)
+     390             :     return kErrorOk;
+     391             : 
+     392             :   CCFunc* func = getFunc();
+     393             :   CBJump* from = nullptr;
+     394             : 
+     395             :   LivenessTarget* ltCur = nullptr;
+     396             :   LivenessTarget* ltUnused = nullptr;
+     397             : 
+     398             :   ZoneList<CBNode*>::Link* retPtr = _returningList.getFirst();
+     399             :   ASMJIT_ASSERT(retPtr != nullptr);
+     400             : 
+     401             :   CBNode* node = retPtr->getValue();
+     402             :   RAData* wd;
+     403             : 
+     404        1948 :   size_t varMapToVaListOffset = _varMapToVaListOffset;
+     405             :   RABits* bCur = newBits(bLen);
+     406        1948 :   if (ASMJIT_UNLIKELY(!bCur)) goto NoMem;
+     407             : 
+     408             :   // Allocate bits for code visited first time.
+     409       36702 : Visit:
+     410             :   for (;;) {
+     411             :     wd = node->getPassData<RAData>();
+     412       36702 :     if (wd->liveness) {
+     413           0 :       if (bCur->_addBitsDelSource(wd->liveness, bCur, bLen))
+     414           0 :         goto Patch;
+     415             :       else
+     416           0 :         goto Done;
+     417             :     }
+     418             : 
+     419             :     RABits* bTmp = copyBits(bCur, bLen);
+     420       36702 :     if (!bTmp) goto NoMem;
+     421             : 
+     422             :     wd = node->getPassData<RAData>();
+     423       36702 :     wd->liveness = bTmp;
+     424             : 
+     425       36702 :     uint32_t tiedTotal = wd->tiedTotal;
+     426             :     TiedReg* tiedArray = reinterpret_cast<TiedReg*>(((uint8_t*)wd) + varMapToVaListOffset);
+     427             : 
+     428       98196 :     for (uint32_t i = 0; i < tiedTotal; i++) {
+     429       61494 :       TiedReg* tied = &tiedArray[i];
+     430       61494 :       VirtReg* vreg = tied->vreg;
+     431             : 
+     432       61494 :       uint32_t flags = tied->flags;
+     433       61494 :       uint32_t raId = vreg->_raId;
+     434             : 
+     435       61494 :       if ((flags & TiedReg::kWAll) && !(flags & TiedReg::kRAll)) {
+     436             :         // Write-Only.
+     437             :         bTmp->setBit(raId);
+     438             :         bCur->delBit(raId);
+     439             :       }
+     440             :       else {
+     441             :         // Read-Only or Read/Write.
+     442             :         bTmp->setBit(raId);
+     443             :         bCur->setBit(raId);
+     444             :       }
+     445             :     }
+     446             : 
+     447       36702 :     if (node->getType() == CBNode::kNodeLabel)
+     448           0 :       goto Target;
+     449             : 
+     450       36702 :     if (node == func)
+     451        1948 :       goto Done;
+     452             : 
+     453             :     ASMJIT_ASSERT(node->getPrev());
+     454             :     node = node->getPrev();
+     455       34754 :   }
+     456             : 
+     457             :   // Patch already generated liveness bits.
+     458           0 : Patch:
+     459             :   for (;;) {
+     460             :     ASMJIT_ASSERT(node->hasPassData());
+     461             :     ASMJIT_ASSERT(node->getPassData<RAData>()->liveness != nullptr);
+     462             : 
+     463           0 :     RABits* bNode = node->getPassData<RAData>()->liveness;
+     464           0 :     if (!bNode->_addBitsDelSource(bCur, bLen)) goto Done;
+     465           0 :     if (node->getType() == CBNode::kNodeLabel) goto Target;
+     466             : 
+     467           0 :     if (node == func) goto Done;
+     468             :     node = node->getPrev();
+     469           0 :   }
+     470             : 
+     471           0 : Target:
+     472           0 :   if (static_cast<CBLabel*>(node)->getNumRefs() != 0) {
+     473             :     // Push a new LivenessTarget onto the stack if needed.
+     474           0 :     if (!ltCur || ltCur->node != node) {
+     475             :       // Allocate a new LivenessTarget object (from pool or zone).
+     476             :       LivenessTarget* ltTmp = ltUnused;
+     477             : 
+     478           0 :       if (ltTmp) {
+     479           0 :         ltUnused = ltUnused->prev;
+     480             :       }
+     481             :       else {
+     482           0 :         ltTmp = _zone->allocT<LivenessTarget>(
+     483           0 :           sizeof(LivenessTarget) - sizeof(RABits) + bLen * sizeof(uintptr_t));
+     484           0 :         if (!ltTmp) goto NoMem;
+     485             :       }
+     486             : 
+     487             :       // Initialize and make current - ltTmp->from will be set later on.
+     488           0 :       ltTmp->prev = ltCur;
+     489           0 :       ltTmp->node = static_cast<CBLabel*>(node);
+     490             :       ltCur = ltTmp;
+     491             : 
+     492             :       from = static_cast<CBLabel*>(node)->getFrom();
+     493             :       ASMJIT_ASSERT(from != nullptr);
+     494           0 :     }
+     495             :     else {
+     496           0 :       from = ltCur->from;
+     497           0 :       goto JumpNext;
+     498             :     }
+     499             : 
+     500             :     // Visit/Patch.
+     501             :     do {
+     502           0 :       ltCur->from = from;
+     503           0 :       bCur->copyBits(node->getPassData<RAData>()->liveness, bLen);
+     504             : 
+     505           0 :       if (!from->getPassData<RAData>()->liveness) {
+     506             :         node = from;
+     507           0 :         goto Visit;
+     508             :       }
+     509             : 
+     510             :       // Issue #25: Moved 'JumpNext' here since it's important to patch
+     511             :       // code again if there are more live variables than before.
+     512           0 : JumpNext:
+     513           0 :       if (bCur->delBits(from->getPassData<RAData>()->liveness, bLen)) {
+     514             :         node = from;
+     515           0 :         goto Patch;
+     516             :       }
+     517             : 
+     518             :       from = from->getJumpNext();
+     519           0 :     } while (from);
+     520             : 
+     521             :     // Pop the current LivenessTarget from the stack.
+     522             :     {
+     523             :       LivenessTarget* ltTmp = ltCur;
+     524           0 :       ltCur = ltCur->prev;
+     525           0 :       ltTmp->prev = ltUnused;
+     526             :       ltUnused = ltTmp;
+     527             :     }
+     528             :   }
+     529             : 
+     530           0 :   bCur->copyBits(node->getPassData<RAData>()->liveness, bLen);
+     531             :   node = node->getPrev();
+     532           0 :   if (node->isJmp() || !node->hasPassData()) goto Done;
+     533             : 
+     534             :   wd = node->getPassData<RAData>();
+     535           0 :   if (!wd->liveness) goto Visit;
+     536           0 :   if (bCur->delBits(wd->liveness, bLen)) goto Patch;
+     537             : 
+     538           0 : Done:
+     539        1948 :   if (ltCur) {
+     540           0 :     node = ltCur->node;
+     541           0 :     from = ltCur->from;
+     542             : 
+     543           0 :     goto JumpNext;
+     544             :   }
+     545             : 
+     546             :   retPtr = retPtr->getNext();
+     547        1948 :   if (retPtr) {
+     548             :     node = retPtr->getValue();
+     549           0 :     goto Visit;
+     550             :   }
+     551             : 
+     552             :   return kErrorOk;
+     553             : 
+     554             : NoMem:
+     555             :   return DebugUtils::errored(kErrorNoHeapMemory);
+     556             : }
+     557             : 
+     558             : // ============================================================================
+     559             : // [asmjit::RAPass - Annotate]
+     560             : // ============================================================================
+     561             : 
+     562           0 : Error RAPass::formatInlineComment(StringBuilder& dst, CBNode* node) {
+     563             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     564             :   RAData* wd = node->getPassData<RAData>();
+     565             : 
+     566           0 :   if (node->hasInlineComment())
+     567             :     dst.appendString(node->getInlineComment());
+     568             : 
+     569           0 :   if (wd && wd->liveness) {
+     570           0 :     if (dst.getLength() < _annotationLength)
+     571           0 :       dst.appendChars(' ', _annotationLength - dst.getLength());
+     572             : 
+     573           0 :     uint32_t vdCount = static_cast<uint32_t>(_contextVd.getLength());
+     574           0 :     size_t offset = dst.getLength() + 1;
+     575             : 
+     576             :     dst.appendChar('[');
+     577             :     dst.appendChars(' ', vdCount);
+     578             :     dst.appendChar(']');
+     579           0 :     RABits* liveness = wd->liveness;
+     580             : 
+     581             :     uint32_t i;
+     582           0 :     for (i = 0; i < vdCount; i++) {
+     583           0 :       if (liveness->getBit(i))
+     584           0 :         dst.getData()[offset + i] = '.';
+     585             :     }
+     586             : 
+     587           0 :     uint32_t tiedTotal = wd->tiedTotal;
+     588           0 :     TiedReg* tiedArray = reinterpret_cast<TiedReg*>(((uint8_t*)wd) + _varMapToVaListOffset);
+     589             : 
+     590           0 :     for (i = 0; i < tiedTotal; i++) {
+     591           0 :       TiedReg* tied = &tiedArray[i];
+     592           0 :       VirtReg* vreg = tied->vreg;
+     593           0 :       uint32_t flags = tied->flags;
+     594             : 
+     595             :       char c = 'u';
+     596           0 :       if ( (flags & TiedReg::kRAll) && !(flags & TiedReg::kWAll)) c = 'r';
+     597           0 :       if (!(flags & TiedReg::kRAll) &&  (flags & TiedReg::kWAll)) c = 'w';
+     598           0 :       if ( (flags & TiedReg::kRAll) &&  (flags & TiedReg::kWAll)) c = 'x';
+     599             :       // Uppercase if unused.
+     600           0 :       if ( (flags & TiedReg::kUnuse)) c -= 'a' - 'A';
+     601             : 
+     602             :       ASMJIT_ASSERT(offset + vreg->_raId < dst.getLength());
+     603           0 :       dst._data[offset + vreg->_raId] = c;
+     604             :     }
+     605             :   }
+     606             : #endif // !ASMJIT_DISABLE_LOGGING
+     607             : 
+     608           0 :   return kErrorOk;
+     609             : }
+     610             : 
+     611             : } // asmjit namespace
+     612             : } // namespace PLMD
+     613             : 
+     614             : // [Api-End]
+     615             : #include "./asmjit_apiend.h"
+     616             : 
+     617             : // [Guard]
+     618             : #endif // !ASMJIT_DISABLE_COMPILER
+     619             : #pragma GCC diagnostic pop
+     620             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc_p.h.func-sort-c.html b/coverage-libs/asmjit/regalloc_p.h.func-sort-c.html new file mode 100644 index 000000000000..40fb58f7408d --- /dev/null +++ b/coverage-libs/asmjit/regalloc_p.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc_p.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:365466.7 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc_p.h.func.html b/coverage-libs/asmjit/regalloc_p.h.func.html new file mode 100644 index 000000000000..39892ddc599e --- /dev/null +++ b/coverage-libs/asmjit/regalloc_p.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc_p.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:365466.7 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/regalloc_p.h.gcov.html b/coverage-libs/asmjit/regalloc_p.h.gcov.html new file mode 100644 index 000000000000..00a83ec747ba --- /dev/null +++ b/coverage-libs/asmjit/regalloc_p.h.gcov.html @@ -0,0 +1,674 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/regalloc_p.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:365466.7 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_regalloc_p_h
+      21             : #define __PLUMED_asmjit_regalloc_p_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_REGALLOC_P_H
+      33             : #define _ASMJIT_BASE_REGALLOC_P_H
+      34             : 
+      35             : #include "./asmjit_build.h"
+      36             : #if !defined(ASMJIT_DISABLE_COMPILER)
+      37             : 
+      38             : // [Dependencies]
+      39             : #include "./codecompiler.h"
+      40             : #include "./zone.h"
+      41             : 
+      42             : // [Api-Begin]
+      43             : #include "./asmjit_apibegin.h"
+      44             : 
+      45             : namespace PLMD {
+      46             : namespace asmjit {
+      47             : 
+      48             : //! \addtogroup asmjit_base
+      49             : //! \{
+      50             : 
+      51             : // ============================================================================
+      52             : // [asmjit::TiedReg]
+      53             : // ============================================================================
+      54             : 
+      55             : //! Tied register (CodeCompiler)
+      56             : //!
+      57             : //! Tied register is used to describe one ore more register operands that share
+      58             : //! the same virtual register. Tied register contains all the data that is
+      59             : //! essential for register allocation.
+      60             : struct TiedReg {
+      61             :   //! Flags.
+      62             :   ASMJIT_ENUM(Flags) {
+      63             :     kRReg        = 0x00000001U,          //!< Register read.
+      64             :     kWReg        = 0x00000002U,          //!< Register write.
+      65             :     kXReg        = 0x00000003U,          //!< Register read-write.
+      66             : 
+      67             :     kRMem        = 0x00000004U,          //!< Memory read.
+      68             :     kWMem        = 0x00000008U,          //!< Memory write.
+      69             :     kXMem        = 0x0000000CU,          //!< Memory read-write.
+      70             : 
+      71             :     kRDecide     = 0x00000010U,          //!< RA can decide between reg/mem read.
+      72             :     kWDecide     = 0x00000020U,          //!< RA can decide between reg/mem write.
+      73             :     kXDecide     = 0x00000030U,          //!< RA can decide between reg/mem read-write.
+      74             : 
+      75             :     kRFunc       = 0x00000100U,          //!< Function argument passed in register.
+      76             :     kWFunc       = 0x00000200U,          //!< Function return value passed into register.
+      77             :     kXFunc       = 0x00000300U,          //!< Function argument and return value.
+      78             :     kRCall       = 0x00000400U,          //!< Function call operand.
+      79             : 
+      80             :     kSpill       = 0x00000800U,          //!< Variable should be spilled.
+      81             :     kUnuse       = 0x00001000U,          //!< Variable should be unused at the end of the instruction/node.
+      82             : 
+      83             :     kRAll        = kRReg | kRMem | kRDecide | kRFunc | kRCall, //!< All in-flags.
+      84             :     kWAll        = kWReg | kWMem | kWDecide | kWFunc,          //!< All out-flags.
+      85             : 
+      86             :     kRDone       = 0x00400000U,          //!< Already allocated on the input.
+      87             :     kWDone       = 0x00800000U,          //!< Already allocated on the output.
+      88             : 
+      89             :     kX86GpbLo    = 0x10000000U,
+      90             :     kX86GpbHi    = 0x20000000U,
+      91             :     kX86Fld4     = 0x40000000U,
+      92             :     kX86Fld8     = 0x80000000U
+      93             :   };
+      94             : 
+      95             :   // --------------------------------------------------------------------------
+      96             :   // [Init / Reset]
+      97             :   // --------------------------------------------------------------------------
+      98             : 
+      99             :   ASMJIT_INLINE void init(VirtReg* vreg, uint32_t flags = 0, uint32_t inRegs = 0, uint32_t allocableRegs = 0) noexcept {
+     100       61494 :     this->vreg = vreg;
+     101       61494 :     this->flags = flags;
+     102       61494 :     this->refCount = 0;
+     103       61494 :     this->inPhysId = Globals::kInvalidRegId;
+     104       61494 :     this->outPhysId = Globals::kInvalidRegId;
+     105       61494 :     this->reserved = 0;
+     106       61494 :     this->inRegs = inRegs;
+     107        1648 :     this->allocableRegs = allocableRegs;
+     108             :   }
+     109             : 
+     110             :   // --------------------------------------------------------------------------
+     111             :   // [Accessors]
+     112             :   // --------------------------------------------------------------------------
+     113             : 
+     114             :   //! Get whether the variable has to be allocated in a specific input register.
+     115        4272 :   ASMJIT_INLINE uint32_t hasInPhysId() const { return inPhysId != Globals::kInvalidRegId; }
+     116             :   //! Get whether the variable has to be allocated in a specific output register.
+     117       26412 :   ASMJIT_INLINE uint32_t hasOutPhysId() const { return outPhysId != Globals::kInvalidRegId; }
+     118             : 
+     119             :   //! Set the input register index.
+     120       37706 :   ASMJIT_INLINE void setInPhysId(uint32_t index) { inPhysId = static_cast<uint8_t>(index); }
+     121             :   //! Set the output register index.
+     122       23788 :   ASMJIT_INLINE void setOutPhysId(uint32_t index) { outPhysId = static_cast<uint8_t>(index); }
+     123             : 
+     124             :   // --------------------------------------------------------------------------
+     125             :   // [Operator Overload]
+     126             :   // --------------------------------------------------------------------------
+     127             : 
+     128             :   ASMJIT_INLINE TiedReg& operator=(const TiedReg& other) {
+     129             :     ::memcpy(this, &other, sizeof(TiedReg));
+     130             :     return *this;
+     131             :   }
+     132             : 
+     133             :   // --------------------------------------------------------------------------
+     134             :   // [Members]
+     135             :   // --------------------------------------------------------------------------
+     136             : 
+     137             :   //! Pointer to the associated \ref VirtReg.
+     138             :   VirtReg* vreg;
+     139             :   //! Tied flags.
+     140             :   uint32_t flags;
+     141             : 
+     142             :   union {
+     143             :     struct {
+     144             :       //! How many times the variable is used by the instruction/node.
+     145             :       uint8_t refCount;
+     146             :       //! Input register index or `kInvalidReg` if it's not given.
+     147             :       //!
+     148             :       //! Even if the input register index is not given (i.e. it may by any
+     149             :       //! register), register allocator should assign an index that will be
+     150             :       //! used to persist a variable into this specific index. It's helpful
+     151             :       //! in situations where one variable has to be allocated in multiple
+     152             :       //! registers to determine the register which will be persistent.
+     153             :       uint8_t inPhysId;
+     154             :       //! Output register index or `kInvalidReg` if it's not given.
+     155             :       //!
+     156             :       //! Typically `kInvalidReg` if variable is only used on input.
+     157             :       uint8_t outPhysId;
+     158             :       //! \internal
+     159             :       uint8_t reserved;
+     160             :     };
+     161             : 
+     162             :     //! \internal
+     163             :     //!
+     164             :     //! Packed data #0.
+     165             :     uint32_t packed;
+     166             :   };
+     167             : 
+     168             :   //! Mandatory input registers.
+     169             :   //!
+     170             :   //! Mandatory input registers are required by the instruction even if
+     171             :   //! there are duplicates. This schema allows us to allocate one variable
+     172             :   //! in one or more register when needed. Required mostly by instructions
+     173             :   //! that have implicit register operands (imul, cpuid, ...) and function
+     174             :   //! call.
+     175             :   uint32_t inRegs;
+     176             : 
+     177             :   //! Allocable input registers.
+     178             :   //!
+     179             :   //! Optional input registers is a mask of all allocable registers for a given
+     180             :   //! variable where we have to pick one of them. This mask is usually not used
+     181             :   //! when _inRegs is set. If both masks are used then the register
+     182             :   //! allocator tries first to find an intersection between these and allocates
+     183             :   //! an extra slot if not found.
+     184             :   uint32_t allocableRegs;
+     185             : };
+     186             : 
+     187             : // ============================================================================
+     188             : // [asmjit::RABits]
+     189             : // ============================================================================
+     190             : 
+     191             : //! Fixed size bit-array.
+     192             : //!
+     193             : //! Used by variable liveness analysis.
+     194             : struct RABits {
+     195             :   // --------------------------------------------------------------------------
+     196             :   // [Enums]
+     197             :   // --------------------------------------------------------------------------
+     198             : 
+     199             :   enum {
+     200             :     kEntitySize = static_cast<int>(sizeof(uintptr_t)),
+     201             :     kEntityBits = kEntitySize * 8
+     202             :   };
+     203             : 
+     204             :   // --------------------------------------------------------------------------
+     205             :   // [Accessors]
+     206             :   // --------------------------------------------------------------------------
+     207             : 
+     208             :   ASMJIT_INLINE uintptr_t getBit(uint32_t index) const noexcept {
+     209      178746 :     return (data[index / kEntityBits] >> (index % kEntityBits)) & 1;
+     210             :   }
+     211             : 
+     212             :   ASMJIT_INLINE void setBit(uint32_t index) noexcept {
+     213       61494 :     data[index / kEntityBits] |= static_cast<uintptr_t>(1) << (index % kEntityBits);
+     214       37706 :   }
+     215             : 
+     216             :   ASMJIT_INLINE void delBit(uint32_t index) noexcept {
+     217       23788 :     data[index / kEntityBits] &= ~(static_cast<uintptr_t>(1) << (index % kEntityBits));
+     218       23788 :   }
+     219             : 
+     220             :   // --------------------------------------------------------------------------
+     221             :   // [Interface]
+     222             :   // --------------------------------------------------------------------------
+     223             : 
+     224             :   //! Copy bits from `s0`, returns `true` if at least one bit is set in `s0`.
+     225             :   ASMJIT_INLINE bool copyBits(const RABits* s0, uint32_t len) noexcept {
+     226             :     uintptr_t r = 0;
+     227           0 :     for (uint32_t i = 0; i < len; i++) {
+     228           0 :       uintptr_t t = s0->data[i];
+     229           0 :       data[i] = t;
+     230             :       r |= t;
+     231             :     }
+     232             :     return r != 0;
+     233             :   }
+     234             : 
+     235             :   ASMJIT_INLINE bool addBits(const RABits* s0, uint32_t len) noexcept {
+     236             :     return addBits(this, s0, len);
+     237             :   }
+     238             : 
+     239             :   ASMJIT_INLINE bool addBits(const RABits* s0, const RABits* s1, uint32_t len) noexcept {
+     240             :     uintptr_t r = 0;
+     241             :     for (uint32_t i = 0; i < len; i++) {
+     242             :       uintptr_t t = s0->data[i] | s1->data[i];
+     243             :       data[i] = t;
+     244             :       r |= t;
+     245             :     }
+     246             :     return r != 0;
+     247             :   }
+     248             : 
+     249             :   ASMJIT_INLINE bool andBits(const RABits* s1, uint32_t len) noexcept {
+     250             :     return andBits(this, s1, len);
+     251             :   }
+     252             : 
+     253             :   ASMJIT_INLINE bool andBits(const RABits* s0, const RABits* s1, uint32_t len) noexcept {
+     254             :     uintptr_t r = 0;
+     255             :     for (uint32_t i = 0; i < len; i++) {
+     256             :       uintptr_t t = s0->data[i] & s1->data[i];
+     257             :       data[i] = t;
+     258             :       r |= t;
+     259             :     }
+     260             :     return r != 0;
+     261             :   }
+     262             : 
+     263             :   ASMJIT_INLINE bool delBits(const RABits* s1, uint32_t len) noexcept {
+     264             :     return delBits(this, s1, len);
+     265             :   }
+     266             : 
+     267             :   ASMJIT_INLINE bool delBits(const RABits* s0, const RABits* s1, uint32_t len) noexcept {
+     268             :     uintptr_t r = 0;
+     269           0 :     for (uint32_t i = 0; i < len; i++) {
+     270           0 :       uintptr_t t = s0->data[i] & ~s1->data[i];
+     271           0 :       data[i] = t;
+     272           0 :       r |= t;
+     273             :     }
+     274             :     return r != 0;
+     275             :   }
+     276             : 
+     277             :   ASMJIT_INLINE bool _addBitsDelSource(RABits* s1, uint32_t len) noexcept {
+     278             :     return _addBitsDelSource(this, s1, len);
+     279             :   }
+     280             : 
+     281             :   ASMJIT_INLINE bool _addBitsDelSource(const RABits* s0, RABits* s1, uint32_t len) noexcept {
+     282             :     uintptr_t r = 0;
+     283           0 :     for (uint32_t i = 0; i < len; i++) {
+     284           0 :       uintptr_t a = s0->data[i];
+     285           0 :       uintptr_t b = s1->data[i];
+     286             : 
+     287           0 :       this->data[i] = a | b;
+     288           0 :       b &= ~a;
+     289             : 
+     290           0 :       s1->data[i] = b;
+     291           0 :       r |= b;
+     292             :     }
+     293             :     return r != 0;
+     294             :   }
+     295             : 
+     296             :   // --------------------------------------------------------------------------
+     297             :   // [Members]
+     298             :   // --------------------------------------------------------------------------
+     299             : 
+     300             :   uintptr_t data[1];
+     301             : };
+     302             : 
+     303             : // ============================================================================
+     304             : // [asmjit::RACell]
+     305             : // ============================================================================
+     306             : 
+     307             : //! Register allocator's (RA) memory cell.
+     308             : struct RACell {
+     309             :   RACell* next;                          //!< Next active cell.
+     310             :   int32_t offset;                        //!< Cell offset, relative to base-offset.
+     311             :   uint32_t size;                         //!< Cell size.
+     312             :   uint32_t alignment;                    //!< Cell alignment.
+     313             : };
+     314             : 
+     315             : // ============================================================================
+     316             : // [asmjit::RAData]
+     317             : // ============================================================================
+     318             : 
+     319             : //! Register allocator's (RA) data associated with each \ref CBNode.
+     320             : struct RAData {
+     321             :   ASMJIT_INLINE RAData(uint32_t tiedTotal) noexcept
+     322       40598 :     : liveness(nullptr),
+     323       40598 :       state(nullptr),
+     324       40598 :       tiedTotal(tiedTotal) {}
+     325             : 
+     326             :   RABits* liveness;                      //!< Liveness bits (populated by liveness-analysis).
+     327             :   RAState* state;                        //!< Optional saved \ref RAState.
+     328             :   uint32_t tiedTotal;                    //!< Total count of \ref TiedReg regs.
+     329             : };
+     330             : 
+     331             : // ============================================================================
+     332             : // [asmjit::RAState]
+     333             : // ============================================================================
+     334             : 
+     335             : //! Variables' state.
+     336             : struct RAState {};
+     337             : 
+     338             : // ============================================================================
+     339             : // [asmjit::RAPass]
+     340             : // ============================================================================
+     341             : 
+     342             : //! \internal
+     343             : //!
+     344             : //! Register allocator pipeline used by \ref CodeCompiler.
+     345             : struct RAPass : public CBPass {
+     346             : public:
+     347             :   ASMJIT_NONCOPYABLE(RAPass)
+     348             : 
+     349             :   typedef void (ASMJIT_CDECL* TraceNodeFunc)(RAPass* self, CBNode* node_, const char* prefix);
+     350             : 
+     351             :   // --------------------------------------------------------------------------
+     352             :   // [Construction / Destruction]
+     353             :   // --------------------------------------------------------------------------
+     354             : 
+     355             :   RAPass() noexcept;
+     356             :   virtual ~RAPass() noexcept;
+     357             : 
+     358             :   // --------------------------------------------------------------------------
+     359             :   // [Interface]
+     360             :   // --------------------------------------------------------------------------
+     361             : 
+     362             :   virtual Error process(Zone* zone) noexcept override;
+     363             : 
+     364             :   //! Run the register allocator for a given function `func`.
+     365             :   virtual Error compile(CCFunc* func) noexcept;
+     366             : 
+     367             :   //! Called by `compile()` to prepare the register allocator to process the
+     368             :   //! given function. It should reset and set-up everything (i.e. no states
+     369             :   //! from a previous compilation should prevail).
+     370             :   virtual Error prepare(CCFunc* func) noexcept;
+     371             : 
+     372             :   //! Called after `compile()` to clean everything up, no matter if it
+     373             :   //! succeeded or failed.
+     374             :   virtual void cleanup() noexcept;
+     375             : 
+     376             :   // --------------------------------------------------------------------------
+     377             :   // [Accessors]
+     378             :   // --------------------------------------------------------------------------
+     379             : 
+     380             :   //! Get the associated `CodeCompiler`.
+     381        3896 :   ASMJIT_INLINE CodeCompiler* cc() const noexcept { return static_cast<CodeCompiler*>(_cb); }
+     382             : 
+     383             :   //! Get function.
+     384        3896 :   ASMJIT_INLINE CCFunc* getFunc() const noexcept { return _func; }
+     385             :   //! Get stop node.
+     386        5844 :   ASMJIT_INLINE CBNode* getStop() const noexcept { return _stop; }
+     387             : 
+     388             :   // --------------------------------------------------------------------------
+     389             :   // [State]
+     390             :   // --------------------------------------------------------------------------
+     391             : 
+     392             :   //! Get current state.
+     393             :   ASMJIT_INLINE RAState* getState() const { return _state; }
+     394             : 
+     395             :   //! Load current state from `target` state.
+     396             :   virtual void loadState(RAState* src) = 0;
+     397             : 
+     398             :   //! Save current state, returning new `RAState` instance.
+     399             :   virtual RAState* saveState() = 0;
+     400             : 
+     401             :   //! Change the current state to `target` state.
+     402             :   virtual void switchState(RAState* src) = 0;
+     403             : 
+     404             :   //! Change the current state to the intersection of two states `a` and `b`.
+     405             :   virtual void intersectStates(RAState* a, RAState* b) = 0;
+     406             : 
+     407             :   // --------------------------------------------------------------------------
+     408             :   // [Context]
+     409             :   // --------------------------------------------------------------------------
+     410             : 
+     411             :   ASMJIT_INLINE Error assignRAId(VirtReg* vreg) noexcept {
+     412             :     // Likely as a single virtual register would be mostly used more than once,
+     413             :     // this means that each virtual register will hit one bad case (doesn't
+     414             :     // have id) and then all likely cases.
+     415       61494 :     if (ASMJIT_LIKELY(vreg->_raId != kInvalidValue)) return kErrorOk;
+     416             : 
+     417       23788 :     uint32_t raId = static_cast<uint32_t>(_contextVd.getLength());
+     418       23788 :     ASMJIT_PROPAGATE(_contextVd.append(&_heap, vreg));
+     419             : 
+     420       23788 :     vreg->_raId = raId;
+     421           0 :     return kErrorOk;
+     422             :   }
+     423             : 
+     424             :   // --------------------------------------------------------------------------
+     425             :   // [Mem]
+     426             :   // --------------------------------------------------------------------------
+     427             : 
+     428             :   RACell* _newVarCell(VirtReg* vreg);
+     429             :   RACell* _newStackCell(uint32_t size, uint32_t alignment);
+     430             : 
+     431             :   ASMJIT_INLINE RACell* getVarCell(VirtReg* vreg) {
+     432             :     RACell* cell = vreg->getMemCell();
+     433        8428 :     return cell ? cell : _newVarCell(vreg);
+     434             :   }
+     435             : 
+     436             :   virtual Error resolveCellOffsets();
+     437             : 
+     438             :   // --------------------------------------------------------------------------
+     439             :   // [Bits]
+     440             :   // --------------------------------------------------------------------------
+     441             : 
+     442             :   ASMJIT_INLINE RABits* newBits(uint32_t len) {
+     443             :     return static_cast<RABits*>(
+     444        1948 :       _zone->allocZeroed(static_cast<size_t>(len) * RABits::kEntitySize));
+     445             :   }
+     446             : 
+     447             :   ASMJIT_INLINE RABits* copyBits(const RABits* src, uint32_t len) {
+     448             :     return static_cast<RABits*>(
+     449       36702 :       _zone->dup(src, static_cast<size_t>(len) * RABits::kEntitySize));
+     450             :   }
+     451             : 
+     452             :   // --------------------------------------------------------------------------
+     453             :   // [Fetch]
+     454             :   // --------------------------------------------------------------------------
+     455             : 
+     456             :   //! Fetch.
+     457             :   //!
+     458             :   //! Fetch iterates over all nodes and gathers information about all variables
+     459             :   //! used. The process generates information required by register allocator,
+     460             :   //! variable liveness analysis and translator.
+     461             :   virtual Error fetch() = 0;
+     462             : 
+     463             :   // --------------------------------------------------------------------------
+     464             :   // [Unreachable Code]
+     465             :   // --------------------------------------------------------------------------
+     466             : 
+     467             :   //! Add unreachable-flow data to the unreachable flow list.
+     468             :   ASMJIT_INLINE Error addUnreachableNode(CBNode* node) {
+     469        1948 :     ZoneList<CBNode*>::Link* link = _zone->allocT<ZoneList<CBNode*>::Link>();
+     470        1948 :     if (!link) return DebugUtils::errored(kErrorNoHeapMemory);
+     471             : 
+     472             :     link->setValue(node);
+     473             :     _unreachableList.append(link);
+     474             : 
+     475        1948 :     return kErrorOk;
+     476             :   }
+     477             : 
+     478             :   //! Remove unreachable code.
+     479             :   virtual Error removeUnreachableCode();
+     480             : 
+     481             :   // --------------------------------------------------------------------------
+     482             :   // [Code-Flow]
+     483             :   // --------------------------------------------------------------------------
+     484             : 
+     485             :   //! Add returning node (i.e. node that returns and where liveness analysis
+     486             :   //! should start).
+     487             :   ASMJIT_INLINE Error addReturningNode(CBNode* node) {
+     488        1948 :     ZoneList<CBNode*>::Link* link = _zone->allocT<ZoneList<CBNode*>::Link>();
+     489        1948 :     if (!link) return DebugUtils::errored(kErrorNoHeapMemory);
+     490             : 
+     491             :     link->setValue(node);
+     492             :     _returningList.append(link);
+     493             : 
+     494        1948 :     return kErrorOk;
+     495             :   }
+     496             : 
+     497             :   //! Add jump-flow data to the jcc flow list.
+     498             :   ASMJIT_INLINE Error addJccNode(CBNode* node) {
+     499           0 :     ZoneList<CBNode*>::Link* link = _zone->allocT<ZoneList<CBNode*>::Link>();
+     500           0 :     if (!link) return DebugUtils::errored(kErrorNoHeapMemory);
+     501             : 
+     502             :     link->setValue(node);
+     503             :     _jccList.append(link);
+     504             : 
+     505           0 :     return kErrorOk;
+     506             :   }
+     507             : 
+     508             :   // --------------------------------------------------------------------------
+     509             :   // [Analyze]
+     510             :   // --------------------------------------------------------------------------
+     511             : 
+     512             :   //! Perform variable liveness analysis.
+     513             :   //!
+     514             :   //! Analysis phase iterates over nodes in reverse order and generates a bit
+     515             :   //! array describing variables that are alive at every node in the function.
+     516             :   //! When the analysis start all variables are assumed dead. When a read or
+     517             :   //! read/write operations of a variable is detected the variable becomes
+     518             :   //! alive; when only write operation is detected the variable becomes dead.
+     519             :   //!
+     520             :   //! When a label is found all jumps to that label are followed and analysis
+     521             :   //! repeats until all variables are resolved.
+     522             :   virtual Error livenessAnalysis();
+     523             : 
+     524             :   // --------------------------------------------------------------------------
+     525             :   // [Annotate]
+     526             :   // --------------------------------------------------------------------------
+     527             : 
+     528             :   virtual Error annotate() = 0;
+     529             :   virtual Error formatInlineComment(StringBuilder& dst, CBNode* node);
+     530             : 
+     531             :   // --------------------------------------------------------------------------
+     532             :   // [Translate]
+     533             :   // --------------------------------------------------------------------------
+     534             : 
+     535             :   //! Translate code by allocating registers and handling state changes.
+     536             :   virtual Error translate() = 0;
+     537             : 
+     538             :   // --------------------------------------------------------------------------
+     539             :   // [Members]
+     540             :   // --------------------------------------------------------------------------
+     541             : 
+     542             :   Zone* _zone;                           //!< Zone passed to `process()`.
+     543             :   ZoneHeap _heap;                        //!< ZoneHeap that uses `_zone`.
+     544             : 
+     545             :   CCFunc* _func;                         //!< Function being processed.
+     546             :   CBNode* _stop;                         //!< Stop node.
+     547             : 
+     548             :   //! \internal
+     549             :   //!
+     550             :   //! Offset (how many bytes to add) to `VarMap` to get `TiedReg` array. Used
+     551             :   //! by liveness analysis shared across all backends. This is needed because
+     552             :   //! `VarMap` is a base class for a specialized version that liveness analysis
+     553             :   //! doesn't use, it just needs `TiedReg` array.
+     554             :   uint32_t _varMapToVaListOffset;
+     555             : 
+     556             :   uint8_t _emitComments;                 //!< Whether to emit comments.
+     557             : 
+     558             :   ZoneList<CBNode*> _unreachableList;     //!< Unreachable nodes.
+     559             :   ZoneList<CBNode*> _returningList;       //!< Returning nodes.
+     560             :   ZoneList<CBNode*> _jccList;             //!< Jump nodes.
+     561             : 
+     562             :   ZoneVector<VirtReg*> _contextVd;       //!< All variables used by the current function.
+     563             :   RACell* _memVarCells;                  //!< Memory used to spill variables.
+     564             :   RACell* _memStackCells;                //!< Memory used to allocate memory on the stack.
+     565             : 
+     566             :   uint32_t _mem1ByteVarsUsed;            //!< Count of 1-byte cells.
+     567             :   uint32_t _mem2ByteVarsUsed;            //!< Count of 2-byte cells.
+     568             :   uint32_t _mem4ByteVarsUsed;            //!< Count of 4-byte cells.
+     569             :   uint32_t _mem8ByteVarsUsed;            //!< Count of 8-byte cells.
+     570             :   uint32_t _mem16ByteVarsUsed;           //!< Count of 16-byte cells.
+     571             :   uint32_t _mem32ByteVarsUsed;           //!< Count of 32-byte cells.
+     572             :   uint32_t _mem64ByteVarsUsed;           //!< Count of 64-byte cells.
+     573             :   uint32_t _memStackCellsUsed;           //!< Count of stack memory cells.
+     574             : 
+     575             :   uint32_t _memMaxAlign;                 //!< Maximum memory alignment used by the function.
+     576             :   uint32_t _memVarTotal;                 //!< Count of bytes used by variables.
+     577             :   uint32_t _memStackTotal;               //!< Count of bytes used by stack.
+     578             :   uint32_t _memAllTotal;                 //!< Count of bytes used by variables and stack after alignment.
+     579             : 
+     580             :   uint32_t _annotationLength;            //!< Default length of an annotated instruction.
+     581             :   RAState* _state;                       //!< Current RA state.
+     582             : };
+     583             : 
+     584             : //! \}
+     585             : 
+     586             : } // asmjit namespace
+     587             : } // namespace PLMD
+     588             : 
+     589             : // [Api-End]
+     590             : #include "./asmjit_apiend.h"
+     591             : 
+     592             : // [Guard]
+     593             : #endif // !ASMJIT_DISABLE_COMPILER
+     594             : #endif // _ASMJIT_BASE_REGALLOC_P_H
+     595             : #pragma GCC diagnostic pop
+     596             : #endif // __PLUMED_HAS_ASMJIT
+     597             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.cpp.func-sort-c.html b/coverage-libs/asmjit/runtime.cpp.func-sort-c.html new file mode 100644 index 000000000000..efaf80f292ab --- /dev/null +++ b/coverage-libs/asmjit/runtime.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:283873.7 %
Date:2024-02-22 21:58:47Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10JitRuntime8_releaseEPv0
_ZN4PLMD6asmjit11HostRuntimeD0Ev0
_ZN4PLMD6asmjit7RuntimeD0Ev0
_ZN4PLMD6asmjit10JitRuntime4_addEPPvPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11HostRuntime5flushEPKvm1948
_ZN4PLMD6asmjit10JitRuntimeC2Ev1976
_ZN4PLMD6asmjit10JitRuntimeD0Ev1976
_ZN4PLMD6asmjit10JitRuntimeD2Ev1976
_ZN4PLMD6asmjit11HostRuntimeC2Ev1976
_ZN4PLMD6asmjit11HostRuntimeD2Ev1976
_ZN4PLMD6asmjit7RuntimeC2Ev1976
_ZN4PLMD6asmjit7RuntimeD2Ev1976
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.cpp.func.html b/coverage-libs/asmjit/runtime.cpp.func.html new file mode 100644 index 000000000000..49c275e4cc12 --- /dev/null +++ b/coverage-libs/asmjit/runtime.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:283873.7 %
Date:2024-02-22 21:58:47Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10JitRuntime4_addEPPvPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit10JitRuntime8_releaseEPv0
_ZN4PLMD6asmjit10JitRuntimeC2Ev1976
_ZN4PLMD6asmjit10JitRuntimeD0Ev1976
_ZN4PLMD6asmjit10JitRuntimeD2Ev1976
_ZN4PLMD6asmjit11HostRuntime5flushEPKvm1948
_ZN4PLMD6asmjit11HostRuntimeC2Ev1976
_ZN4PLMD6asmjit11HostRuntimeD0Ev0
_ZN4PLMD6asmjit11HostRuntimeD2Ev1976
_ZN4PLMD6asmjit7RuntimeC2Ev1976
_ZN4PLMD6asmjit7RuntimeD0Ev0
_ZN4PLMD6asmjit7RuntimeD2Ev1976
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.cpp.gcov.html b/coverage-libs/asmjit/runtime.cpp.gcov.html new file mode 100644 index 000000000000..a9f3a908d6de --- /dev/null +++ b/coverage-libs/asmjit/runtime.cpp.gcov.html @@ -0,0 +1,250 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:283873.7 %
Date:2024-02-22 21:58:47Functions:91275.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./assembler.h"
+      34             : #include "./cpuinfo.h"
+      35             : #include "./runtime.h"
+      36             : 
+      37             : // [Api-Begin]
+      38             : #include "./asmjit_apibegin.h"
+      39             : 
+      40             : namespace PLMD {
+      41             : namespace asmjit {
+      42             : 
+      43             : static ASMJIT_INLINE void hostFlushInstructionCache(const void* p, size_t size) noexcept {
+      44             :   // Only useful on non-x86 architectures.
+      45             : #if !ASMJIT_ARCH_X86 && !ASMJIT_ARCH_X64
+      46             : # if ASMJIT_OS_WINDOWS
+      47             :   // Windows has a built-in support in kernel32.dll.
+      48             :   ::FlushInstructionCache(_memMgr.getProcessHandle(), p, size);
+      49             : # endif // ASMJIT_OS_WINDOWS
+      50             : #else
+      51             :   ASMJIT_UNUSED(p);
+      52             :   ASMJIT_UNUSED(size);
+      53             : #endif // !ASMJIT_ARCH_X86 && !ASMJIT_ARCH_X64
+      54             : }
+      55             : 
+      56             : static ASMJIT_INLINE uint32_t hostDetectNaturalStackAlignment() noexcept {
+      57             :   // Alignment is assumed to match the pointer-size by default.
+      58             :   uint32_t alignment = sizeof(intptr_t);
+      59             : 
+      60             :   // X86 & X64
+      61             :   // ---------
+      62             :   //
+      63             :   //   - 32-bit X86 requires stack to be aligned to 4 bytes. Modern Linux, Mac
+      64             :   //     and UNIX guarantees 16-byte stack alignment even on 32-bit. I'm not
+      65             :   //     sure about all other UNIX operating systems, because 16-byte alignment
+      66             :   //!    is addition to an older specification.
+      67             :   //   - 64-bit X86 requires stack to be aligned to at least 16 bytes.
+      68             : #if ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
+      69             :   int kIsModernOS = ASMJIT_OS_LINUX  || // Linux & ANDROID.
+      70             :                     ASMJIT_OS_MAC    || // OSX and iOS.
+      71             :                     ASMJIT_OS_BSD    ;  // BSD variants.
+      72             :   alignment = ASMJIT_ARCH_X64 || kIsModernOS ? 16 : 4;
+      73             : #endif
+      74             : 
+      75             :   // ARM32 & ARM64
+      76             :   // -------------
+      77             :   //
+      78             :   //   - 32-bit ARM requires stack to be aligned to 8 bytes.
+      79             :   //   - 64-bit ARM requires stack to be aligned to 16 bytes.
+      80             : #if ASMJIT_ARCH_ARM32 || ASMJIT_ARCH_ARM64
+      81             :   alignment = ASMJIT_ARCH_ARM32 ? 8 : 16;
+      82             : #endif
+      83             : 
+      84             :   return alignment;
+      85             : }
+      86             : 
+      87             : 
+      88             : // ============================================================================
+      89             : // [asmjit::Runtime - Construction / Destruction]
+      90             : // ============================================================================
+      91             : 
+      92        1976 : Runtime::Runtime() noexcept
+      93             :   : _codeInfo(),
+      94        1976 :     _runtimeType(kRuntimeNone),
+      95        1976 :     _allocType(VMemMgr::kAllocFreeable) {}
+      96        1976 : Runtime::~Runtime() noexcept {}
+      97             : 
+      98             : // ============================================================================
+      99             : // [asmjit::HostRuntime - Construction / Destruction]
+     100             : // ============================================================================
+     101             : 
+     102        1976 : HostRuntime::HostRuntime() noexcept {
+     103        1976 :   _runtimeType = kRuntimeJit;
+     104             : 
+     105             :   // Setup the CodeInfo of this Runtime.
+     106        1976 :   _codeInfo._archInfo       = CpuInfo::getHost().getArchInfo();
+     107        1976 :   _codeInfo._stackAlignment = static_cast<uint8_t>(hostDetectNaturalStackAlignment());
+     108        1976 :   _codeInfo._cdeclCallConv  = CallConv::kIdHostCDecl;
+     109        1976 :   _codeInfo._stdCallConv    = CallConv::kIdHostStdCall;
+     110        1976 :   _codeInfo._fastCallConv   = CallConv::kIdHostFastCall;
+     111        1976 : }
+     112        1976 : HostRuntime::~HostRuntime() noexcept {}
+     113             : 
+     114             : // ============================================================================
+     115             : // [asmjit::HostRuntime - Interface]
+     116             : // ============================================================================
+     117             : 
+     118        1948 : void HostRuntime::flush(const void* p, size_t size) noexcept {
+     119             :   hostFlushInstructionCache(p, size);
+     120        1948 : }
+     121             : 
+     122             : // ============================================================================
+     123             : // [asmjit::JitRuntime - Construction / Destruction]
+     124             : // ============================================================================
+     125             : 
+     126        1976 : JitRuntime::JitRuntime() noexcept {}
+     127        3952 : JitRuntime::~JitRuntime() noexcept {}
+     128             : 
+     129             : // ============================================================================
+     130             : // [asmjit::JitRuntime - Interface]
+     131             : // ============================================================================
+     132             : 
+     133        1948 : Error JitRuntime::_add(void** dst, CodeHolder* code) noexcept {
+     134        1948 :   size_t codeSize = code->getCodeSize();
+     135        1948 :   if (ASMJIT_UNLIKELY(codeSize == 0)) {
+     136           0 :     *dst = nullptr;
+     137           0 :     return DebugUtils::errored(kErrorNoCodeGenerated);
+     138             :   }
+     139             : 
+     140        1948 :   void* p = _memMgr.alloc(codeSize, getAllocType());
+     141        1948 :   if (ASMJIT_UNLIKELY(!p)) {
+     142           0 :     *dst = nullptr;
+     143           0 :     return DebugUtils::errored(kErrorNoVirtualMemory);
+     144             :   }
+     145             : 
+     146             :   // Relocate the code and release the unused memory back to `VMemMgr`.
+     147        1948 :   size_t relocSize = code->relocate(p);
+     148        1948 :   if (ASMJIT_UNLIKELY(relocSize == 0)) {
+     149           0 :     *dst = nullptr;
+     150           0 :     _memMgr.release(p);
+     151           0 :     return DebugUtils::errored(kErrorInvalidState);
+     152             :   }
+     153             : 
+     154        1948 :   if (relocSize < codeSize)
+     155           0 :     _memMgr.shrink(p, relocSize);
+     156             : 
+     157        1948 :   flush(p, relocSize);
+     158        1948 :   *dst = p;
+     159             : 
+     160        1948 :   return kErrorOk;
+     161             : }
+     162             : 
+     163           0 : Error JitRuntime::_release(void* p) noexcept {
+     164           0 :   return _memMgr.release(p);
+     165             : }
+     166             : 
+     167             : } // asmjit namespace
+     168             : } // namespace PLMD
+     169             : 
+     170             : // [Api-End]
+     171             : #include "./asmjit_apiend.h"
+     172             : #pragma GCC diagnostic pop
+     173             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.h.func-sort-c.html b/coverage-libs/asmjit/runtime.h.func-sort-c.html new file mode 100644 index 000000000000..def127fa40d6 --- /dev/null +++ b/coverage-libs/asmjit/runtime.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:33100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.h.func.html b/coverage-libs/asmjit/runtime.h.func.html new file mode 100644 index 000000000000..f24a8d5cdac1 --- /dev/null +++ b/coverage-libs/asmjit/runtime.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:33100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/runtime.h.gcov.html b/coverage-libs/asmjit/runtime.h.gcov.html new file mode 100644 index 000000000000..6733ad71d740 --- /dev/null +++ b/coverage-libs/asmjit/runtime.h.gcov.html @@ -0,0 +1,304 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/runtime.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - runtime.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:33100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_runtime_h
+      21             : #define __PLUMED_asmjit_runtime_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_RUNTIME_H
+      33             : #define _ASMJIT_BASE_RUNTIME_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./codeholder.h"
+      37             : #include "./vmem.h"
+      38             : 
+      39             : // [Api-Begin]
+      40             : #include "./asmjit_apibegin.h"
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace asmjit {
+      44             : 
+      45             : // ============================================================================
+      46             : // [Forward Declarations]
+      47             : // ============================================================================
+      48             : 
+      49             : class CodeHolder;
+      50             : 
+      51             : //! \addtogroup asmjit_base
+      52             : //! \{
+      53             : 
+      54             : // ============================================================================
+      55             : // [asmjit::Runtime]
+      56             : // ============================================================================
+      57             : 
+      58             : //! Base runtime.
+      59             : class ASMJIT_VIRTAPI Runtime {
+      60             : public:
+      61             :   ASMJIT_NONCOPYABLE(Runtime)
+      62             : 
+      63             :   ASMJIT_ENUM(RuntimeType) {
+      64             :     kRuntimeNone = 0,
+      65             :     kRuntimeJit = 1,
+      66             :     kRuntimeRemote = 2
+      67             :   };
+      68             : 
+      69             :   // --------------------------------------------------------------------------
+      70             :   // [Construction / Destruction]
+      71             :   // --------------------------------------------------------------------------
+      72             : 
+      73             :   //! Create a `Runtime` instance.
+      74             :   ASMJIT_API Runtime() noexcept;
+      75             :   //! Destroy the `Runtime` instance.
+      76             :   ASMJIT_API virtual ~Runtime() noexcept;
+      77             : 
+      78             :   // --------------------------------------------------------------------------
+      79             :   // [Accessors]
+      80             :   // --------------------------------------------------------------------------
+      81             : 
+      82             :   //! Get CodeInfo of this runtime.
+      83             :   //!
+      84             :   //! CodeInfo can be used to setup a CodeHolder in case you plan to generate a
+      85             :   //! code compatible and executable by this Runtime.
+      86        1948 :   ASMJIT_INLINE const CodeInfo& getCodeInfo() const noexcept { return _codeInfo; }
+      87             : 
+      88             :   //! Get the Runtime's architecture type, see \ref ArchInfo::Type.
+      89             :   ASMJIT_INLINE uint32_t getArchType() const noexcept { return _codeInfo.getArchType(); }
+      90             :   //! Get the Runtime's architecture sub-type, see \ref ArchInfo::SubType.
+      91             :   ASMJIT_INLINE uint32_t getArchSubType() const noexcept { return _codeInfo.getArchSubType(); }
+      92             : 
+      93             :   //! Get the runtime type, see \ref Type.
+      94             :   ASMJIT_INLINE uint32_t getRuntimeType() const noexcept { return _runtimeType; }
+      95             : 
+      96             :   // --------------------------------------------------------------------------
+      97             :   // [Interface]
+      98             :   // --------------------------------------------------------------------------
+      99             : 
+     100             :   // NOTE: To allow passing function pointers to `add()` and `release()` the
+     101             :   // virtual methods are prefixed with `_` and called from templates.
+     102             : 
+     103             :   template<typename Func>
+     104             :   ASMJIT_INLINE Error add(Func* dst, CodeHolder* code) noexcept {
+     105        1948 :     return _add(Internal::ptr_cast<void**, Func*>(dst), code);
+     106             :   }
+     107             : 
+     108             :   template<typename Func>
+     109             :   ASMJIT_INLINE Error release(Func dst) noexcept {
+     110             :     return _release(Internal::ptr_cast<void*, Func>(dst));
+     111             :   }
+     112             : 
+     113             :   //! Allocate a memory needed for a code stored in the \ref CodeHolder and
+     114             :   //! relocate it to the target location.
+     115             :   //!
+     116             :   //! The beginning of the memory allocated for the function is returned in
+     117             :   //! `dst`. If failed the \ref Error code is returned and `dst` is set to null
+     118             :   //! (this means that you don't have to set it to null before calling `add()`).
+     119             :   virtual Error _add(void** dst, CodeHolder* code) noexcept = 0;
+     120             : 
+     121             :   //! Release `p` allocated by `add()`.
+     122             :   virtual Error _release(void* p) noexcept = 0;
+     123             : 
+     124             :   // --------------------------------------------------------------------------
+     125             :   // [Members]
+     126             :   // --------------------------------------------------------------------------
+     127             : 
+     128             :   CodeInfo _codeInfo;                    //!< Basic information about the Runtime's code.
+     129             :   uint8_t _runtimeType;                  //!< Type of the runtime.
+     130             :   uint8_t _allocType;                    //!< Type of the allocator the Runtime uses.
+     131             :   uint8_t _reserved[6];                  //!< \internal
+     132             : };
+     133             : 
+     134             : // ============================================================================
+     135             : // [asmjit::HostRuntime]
+     136             : // ============================================================================
+     137             : 
+     138             : //! Runtime designed to be used in the same process the code is generated in.
+     139             : class ASMJIT_VIRTAPI HostRuntime : public Runtime {
+     140             : public:
+     141             :   ASMJIT_NONCOPYABLE(HostRuntime)
+     142             : 
+     143             :   // --------------------------------------------------------------------------
+     144             :   // [Construction / Destruction]
+     145             :   // --------------------------------------------------------------------------
+     146             : 
+     147             :   //! Create a `HostRuntime` instance.
+     148             :   ASMJIT_API HostRuntime() noexcept;
+     149             :   //! Destroy the `HostRuntime` instance.
+     150             :   ASMJIT_API virtual ~HostRuntime() noexcept;
+     151             : 
+     152             :   // --------------------------------------------------------------------------
+     153             :   // [Interface]
+     154             :   // --------------------------------------------------------------------------
+     155             : 
+     156             :   //! Flush an instruction cache.
+     157             :   //!
+     158             :   //! This member function is called after the code has been copied to the
+     159             :   //! destination buffer. It is only useful for JIT code generation as it
+     160             :   //! causes a flush of the processor's cache.
+     161             :   //!
+     162             :   //! Flushing is basically a NOP under X86/X64, but is needed by architectures
+     163             :   //! that do not have a transparent instruction cache like ARM.
+     164             :   //!
+     165             :   //! This function can also be overridden to improve compatibility with tools
+     166             :   //! such as Valgrind, however, it's not an official part of AsmJit.
+     167             :   ASMJIT_API virtual void flush(const void* p, size_t size) noexcept;
+     168             : };
+     169             : 
+     170             : // ============================================================================
+     171             : // [asmjit::JitRuntime]
+     172             : // ============================================================================
+     173             : 
+     174             : //! Runtime designed to store and execute code generated at runtime (JIT).
+     175             : class ASMJIT_VIRTAPI JitRuntime : public HostRuntime {
+     176             : public:
+     177             :   ASMJIT_NONCOPYABLE(JitRuntime)
+     178             : 
+     179             :   // --------------------------------------------------------------------------
+     180             :   // [Construction / Destruction]
+     181             :   // --------------------------------------------------------------------------
+     182             : 
+     183             :   //! Create a `JitRuntime` instance.
+     184             :   ASMJIT_API JitRuntime() noexcept;
+     185             :   //! Destroy the `JitRuntime` instance.
+     186             :   ASMJIT_API virtual ~JitRuntime() noexcept;
+     187             : 
+     188             :   // --------------------------------------------------------------------------
+     189             :   // [Accessors]
+     190             :   // --------------------------------------------------------------------------
+     191             : 
+     192             :   //! Get the type of allocation.
+     193        1948 :   ASMJIT_INLINE uint32_t getAllocType() const noexcept { return _allocType; }
+     194             :   //! Set the type of allocation.
+     195             :   ASMJIT_INLINE void setAllocType(uint32_t allocType) noexcept { _allocType = allocType; }
+     196             : 
+     197             :   //! Get the virtual memory manager.
+     198             :   ASMJIT_INLINE VMemMgr* getMemMgr() const noexcept { return const_cast<VMemMgr*>(&_memMgr); }
+     199             : 
+     200             :   // --------------------------------------------------------------------------
+     201             :   // [Interface]
+     202             :   // --------------------------------------------------------------------------
+     203             : 
+     204             :   ASMJIT_API Error _add(void** dst, CodeHolder* code) noexcept override;
+     205             :   ASMJIT_API Error _release(void* p) noexcept override;
+     206             : 
+     207             :   // --------------------------------------------------------------------------
+     208             :   // [Members]
+     209             :   // --------------------------------------------------------------------------
+     210             : 
+     211             :   //! Virtual memory manager.
+     212             :   VMemMgr _memMgr;
+     213             : };
+     214             : 
+     215             : //! \}
+     216             : 
+     217             : } // asmjit namespace
+     218             : } // namespace PLMD
+     219             : 
+     220             : // [Api-End]
+     221             : #include "./asmjit_apiend.h"
+     222             : 
+     223             : // [Guard]
+     224             : #endif // _ASMJIT_BASE_RUNTIME_H
+     225             : #pragma GCC diagnostic pop
+     226             : #endif // __PLUMED_HAS_ASMJIT
+     227             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/string.cpp.func-sort-c.html b/coverage-libs/asmjit/string.cpp.func-sort-c.html new file mode 100644 index 000000000000..8f2df269c346 --- /dev/null +++ b/coverage-libs/asmjit/string.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/string.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - string.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01380.0 %
Date:2024-02-22 21:58:47Functions:0140.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit13StringBuilder10_opVFormatEjPKcP13__va_list_tag0
_ZN4PLMD6asmjit13StringBuilder12appendFormatEPKcz0
_ZN4PLMD6asmjit13StringBuilder5clearEv0
_ZN4PLMD6asmjit13StringBuilder6_opHexEjPKvm0
_ZN4PLMD6asmjit13StringBuilder7_opCharEjc0
_ZN4PLMD6asmjit13StringBuilder7prepareEjm0
_ZN4PLMD6asmjit13StringBuilder7reserveEm0
_ZN4PLMD6asmjit13StringBuilder8_opCharsEjcm0
_ZN4PLMD6asmjit13StringBuilder9_opNumberEjmjmj0
_ZN4PLMD6asmjit13StringBuilder9_opStringEjPKcm0
_ZN4PLMD6asmjit13StringBuilder9setFormatEPKcz0
_ZN4PLMD6asmjit13StringBuilderC2Ev0
_ZN4PLMD6asmjit13StringBuilderD2Ev0
_ZNK4PLMD6asmjit13StringBuilder2eqEPKcm0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/string.cpp.func.html b/coverage-libs/asmjit/string.cpp.func.html new file mode 100644 index 000000000000..84e7a5abb087 --- /dev/null +++ b/coverage-libs/asmjit/string.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/string.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - string.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01380.0 %
Date:2024-02-22 21:58:47Functions:0140.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit13StringBuilder10_opVFormatEjPKcP13__va_list_tag0
_ZN4PLMD6asmjit13StringBuilder12appendFormatEPKcz0
_ZN4PLMD6asmjit13StringBuilder5clearEv0
_ZN4PLMD6asmjit13StringBuilder6_opHexEjPKvm0
_ZN4PLMD6asmjit13StringBuilder7_opCharEjc0
_ZN4PLMD6asmjit13StringBuilder7prepareEjm0
_ZN4PLMD6asmjit13StringBuilder7reserveEm0
_ZN4PLMD6asmjit13StringBuilder8_opCharsEjcm0
_ZN4PLMD6asmjit13StringBuilder9_opNumberEjmjmj0
_ZN4PLMD6asmjit13StringBuilder9_opStringEjPKcm0
_ZN4PLMD6asmjit13StringBuilder9setFormatEPKcz0
_ZN4PLMD6asmjit13StringBuilderC2Ev0
_ZN4PLMD6asmjit13StringBuilderD2Ev0
_ZNK4PLMD6asmjit13StringBuilder2eqEPKcm0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/string.cpp.gcov.html b/coverage-libs/asmjit/string.cpp.gcov.html new file mode 100644 index 000000000000..256992049474 --- /dev/null +++ b/coverage-libs/asmjit/string.cpp.gcov.html @@ -0,0 +1,456 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/string.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - string.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01380.0 %
Date:2024-02-22 21:58:47Functions:0140.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./moved_string.h"
+      34             : #include "./utils.h"
+      35             : 
+      36             : // [Api-Begin]
+      37             : #include "./asmjit_apibegin.h"
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace asmjit {
+      41             : 
+      42             : // ============================================================================
+      43             : // [asmjit::StringBuilder - Construction / Destruction]
+      44             : // ============================================================================
+      45             : 
+      46             : // Should be placed in read-only memory.
+      47             : static const char StringBuilder_empty[4] = { 0 };
+      48             : 
+      49           0 : StringBuilder::StringBuilder() noexcept
+      50           0 :   : _data(const_cast<char*>(StringBuilder_empty)),
+      51           0 :     _length(0),
+      52           0 :     _capacity(0),
+      53           0 :     _canFree(false) {}
+      54             : 
+      55           0 : StringBuilder::~StringBuilder() noexcept {
+      56           0 :   if (_canFree)
+      57           0 :     Internal::releaseMemory(_data);
+      58           0 : }
+      59             : 
+      60             : // ============================================================================
+      61             : // [asmjit::StringBuilder - Prepare / Reserve]
+      62             : // ============================================================================
+      63             : 
+      64           0 : ASMJIT_FAVOR_SIZE char* StringBuilder::prepare(uint32_t op, size_t len) noexcept {
+      65           0 :   if (op == kStringOpSet) {
+      66             :     // We don't care here, but we can't return a null pointer since it indicates
+      67             :     // failure in memory allocation.
+      68           0 :     if (len == 0) {
+      69           0 :       if (_data != StringBuilder_empty)
+      70           0 :         _data[0] = 0;
+      71             : 
+      72           0 :       _length = 0;
+      73           0 :       return _data;
+      74             :     }
+      75             : 
+      76           0 :     if (_capacity < len) {
+      77           0 :       if (len >= IntTraits<size_t>::maxValue() - sizeof(intptr_t) * 2)
+      78             :         return nullptr;
+      79             : 
+      80             :       size_t to = Utils::alignTo<size_t>(len, sizeof(intptr_t));
+      81             :       if (to < 256 - sizeof(intptr_t))
+      82             :         to = 256 - sizeof(intptr_t);
+      83             : 
+      84           0 :       char* newData = static_cast<char*>(Internal::allocMemory(to + sizeof(intptr_t)));
+      85           0 :       if (!newData) {
+      86           0 :         clear();
+      87           0 :         return nullptr;
+      88             :       }
+      89             : 
+      90           0 :       if (_canFree)
+      91           0 :         Internal::releaseMemory(_data);
+      92             : 
+      93           0 :       _data = newData;
+      94           0 :       _capacity = to + sizeof(intptr_t) - 1;
+      95           0 :       _canFree = true;
+      96             :     }
+      97             : 
+      98           0 :     _data[len] = 0;
+      99           0 :     _length = len;
+     100             : 
+     101             :     ASMJIT_ASSERT(_length <= _capacity);
+     102           0 :     return _data;
+     103             :   }
+     104             :   else {
+     105             :     // We don't care here, but we can't return a null pointer since it indicates
+     106             :     // failure of memory allocation.
+     107           0 :     if (len == 0)
+     108           0 :       return _data + _length;
+     109             : 
+     110             :     // Overflow.
+     111           0 :     if (IntTraits<size_t>::maxValue() - sizeof(intptr_t) * 2 - _length < len)
+     112             :       return nullptr;
+     113             : 
+     114           0 :     size_t after = _length + len;
+     115           0 :     if (_capacity < after) {
+     116             :       size_t to = _capacity;
+     117             : 
+     118             :       if (to < 256)
+     119             :         to = 256;
+     120             : 
+     121           0 :       while (to < 1024 * 1024 && to < after)
+     122           0 :         to *= 2;
+     123             : 
+     124           0 :       if (to < after) {
+     125             :         to = after;
+     126           0 :         if (to < (IntTraits<size_t>::maxValue() - 1024 * 32))
+     127             :           to = Utils::alignTo<size_t>(to, 1024 * 32);
+     128             :       }
+     129             : 
+     130             :       to = Utils::alignTo<size_t>(to, sizeof(intptr_t));
+     131           0 :       char* newData = static_cast<char*>(Internal::allocMemory(to + sizeof(intptr_t)));
+     132           0 :       if (!newData) return nullptr;
+     133             : 
+     134           0 :       ::memcpy(newData, _data, _length);
+     135           0 :       if (_canFree)
+     136             :         Internal::releaseMemory(_data);
+     137             : 
+     138           0 :       _data = newData;
+     139           0 :       _capacity = to + sizeof(intptr_t) - 1;
+     140           0 :       _canFree = true;
+     141             :     }
+     142             : 
+     143           0 :     char* ret = _data + _length;
+     144           0 :     _data[after] = 0;
+     145           0 :     _length = after;
+     146             : 
+     147             :     ASMJIT_ASSERT(_length <= _capacity);
+     148           0 :     return ret;
+     149             :   }
+     150             : }
+     151             : 
+     152           0 : ASMJIT_FAVOR_SIZE Error StringBuilder::reserve(size_t to) noexcept {
+     153           0 :   if (_capacity >= to)
+     154             :     return kErrorOk;
+     155             : 
+     156           0 :   if (to >= IntTraits<size_t>::maxValue() - sizeof(intptr_t) * 2)
+     157             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     158             : 
+     159             :   to = Utils::alignTo<size_t>(to, sizeof(intptr_t));
+     160           0 :   char* newData = static_cast<char*>(Internal::allocMemory(to + sizeof(intptr_t)));
+     161             : 
+     162           0 :   if (!newData)
+     163             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     164             : 
+     165           0 :   ::memcpy(newData, _data, _length + 1);
+     166           0 :   if (_canFree)
+     167             :     Internal::releaseMemory(_data);
+     168             : 
+     169           0 :   _data = newData;
+     170           0 :   _capacity = to + sizeof(intptr_t) - 1;
+     171           0 :   _canFree = true;
+     172           0 :   return kErrorOk;
+     173             : }
+     174             : 
+     175             : // ============================================================================
+     176             : // [asmjit::StringBuilder - Clear]
+     177             : // ============================================================================
+     178             : 
+     179           0 : void StringBuilder::clear() noexcept {
+     180           0 :   if (_data != StringBuilder_empty)
+     181           0 :     _data[0] = 0;
+     182           0 :   _length = 0;
+     183           0 : }
+     184             : 
+     185             : // ============================================================================
+     186             : // [asmjit::StringBuilder - Methods]
+     187             : // ============================================================================
+     188             : 
+     189           0 : Error StringBuilder::_opString(uint32_t op, const char* str, size_t len) noexcept {
+     190           0 :   if (len == Globals::kInvalidIndex)
+     191           0 :     len = str ? ::strlen(str) : static_cast<size_t>(0);
+     192             : 
+     193           0 :   char* p = prepare(op, len);
+     194           0 :   if (!p) return DebugUtils::errored(kErrorNoHeapMemory);
+     195             : 
+     196             :   ::memcpy(p, str, len);
+     197           0 :   return kErrorOk;
+     198             : }
+     199             : 
+     200           0 : Error StringBuilder::_opChar(uint32_t op, char c) noexcept {
+     201           0 :   char* p = prepare(op, 1);
+     202           0 :   if (!p) return DebugUtils::errored(kErrorNoHeapMemory);
+     203             : 
+     204           0 :   *p = c;
+     205           0 :   return kErrorOk;
+     206             : }
+     207             : 
+     208           0 : Error StringBuilder::_opChars(uint32_t op, char c, size_t n) noexcept {
+     209           0 :   char* p = prepare(op, n);
+     210           0 :   if (!p) return DebugUtils::errored(kErrorNoHeapMemory);
+     211             : 
+     212           0 :   ::memset(p, c, n);
+     213           0 :   return kErrorOk;
+     214             : }
+     215             : 
+     216             : static const char StringBuilder_numbers[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+     217             : 
+     218           0 : Error StringBuilder::_opNumber(uint32_t op, uint64_t i, uint32_t base, size_t width, uint32_t flags) noexcept {
+     219           0 :   if (base < 2 || base > 36)
+     220             :     base = 10;
+     221             : 
+     222             :   char buf[128];
+     223             :   char* p = buf + ASMJIT_ARRAY_SIZE(buf);
+     224             : 
+     225             :   uint64_t orig = i;
+     226             :   char sign = '\0';
+     227             : 
+     228             :   // --------------------------------------------------------------------------
+     229             :   // [Sign]
+     230             :   // --------------------------------------------------------------------------
+     231             : 
+     232           0 :   if ((flags & kStringFormatSigned) != 0 && static_cast<int64_t>(i) < 0) {
+     233           0 :     i = static_cast<uint64_t>(-static_cast<int64_t>(i));
+     234             :     sign = '-';
+     235             :   }
+     236           0 :   else if ((flags & kStringFormatShowSign) != 0) {
+     237             :     sign = '+';
+     238             :   }
+     239           0 :   else if ((flags & kStringFormatShowSpace) != 0) {
+     240             :     sign = ' ';
+     241             :   }
+     242             : 
+     243             :   // --------------------------------------------------------------------------
+     244             :   // [Number]
+     245             :   // --------------------------------------------------------------------------
+     246             : 
+     247             :   do {
+     248           0 :     uint64_t d = i / base;
+     249           0 :     uint64_t r = i % base;
+     250             : 
+     251           0 :     *--p = StringBuilder_numbers[r];
+     252             :     i = d;
+     253           0 :   } while (i);
+     254             : 
+     255           0 :   size_t numberLength = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p);
+     256             : 
+     257             :   // --------------------------------------------------------------------------
+     258             :   // [Alternate Form]
+     259             :   // --------------------------------------------------------------------------
+     260             : 
+     261           0 :   if ((flags & kStringFormatAlternate) != 0) {
+     262           0 :     if (base == 8) {
+     263           0 :       if (orig != 0)
+     264           0 :         *--p = '0';
+     265             :     }
+     266           0 :     if (base == 16) {
+     267           0 :       *--p = 'x';
+     268           0 :       *--p = '0';
+     269             :     }
+     270             :   }
+     271             : 
+     272             :   // --------------------------------------------------------------------------
+     273             :   // [Width]
+     274             :   // --------------------------------------------------------------------------
+     275             : 
+     276           0 :   if (sign != 0)
+     277           0 :     *--p = sign;
+     278             : 
+     279             :   if (width > 256)
+     280             :     width = 256;
+     281             : 
+     282           0 :   if (width <= numberLength)
+     283             :     width = 0;
+     284             :   else
+     285           0 :     width -= numberLength;
+     286             : 
+     287             :   // --------------------------------------------------------------------------
+     288             :   // Write]
+     289             :   // --------------------------------------------------------------------------
+     290             : 
+     291           0 :   size_t prefixLength = (size_t)(buf + ASMJIT_ARRAY_SIZE(buf) - p) - numberLength;
+     292           0 :   char* data = prepare(op, prefixLength + width + numberLength);
+     293             : 
+     294           0 :   if (!data)
+     295             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     296             : 
+     297             :   ::memcpy(data, p, prefixLength);
+     298           0 :   data += prefixLength;
+     299             : 
+     300             :   ::memset(data, '0', width);
+     301           0 :   data += width;
+     302             : 
+     303           0 :   ::memcpy(data, p + prefixLength, numberLength);
+     304           0 :   return kErrorOk;
+     305             : }
+     306             : 
+     307           0 : Error StringBuilder::_opHex(uint32_t op, const void* data, size_t len) noexcept {
+     308             :   char* dst;
+     309             : 
+     310           0 :   if (len >= IntTraits<size_t>::maxValue() / 2 || !(dst = prepare(op, len * 2)))
+     311             :     return DebugUtils::errored(kErrorNoHeapMemory);;
+     312             : 
+     313             :   const char* src = static_cast<const char*>(data);
+     314           0 :   for (size_t i = 0; i < len; i++, dst += 2, src++) {
+     315           0 :     dst[0] = StringBuilder_numbers[(src[0] >> 4) & 0xF];
+     316           0 :     dst[1] = StringBuilder_numbers[(src[0]     ) & 0xF];
+     317             :   }
+     318             :   return kErrorOk;
+     319             : }
+     320             : 
+     321           0 : Error StringBuilder::_opVFormat(uint32_t op, const char* fmt, va_list ap) noexcept {
+     322             :   char buf[1024];
+     323             : 
+     324             :   vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf), fmt, ap);
+     325           0 :   buf[ASMJIT_ARRAY_SIZE(buf) - 1] = '\0';
+     326             : 
+     327           0 :   return _opString(op, buf);
+     328             : }
+     329             : 
+     330           0 : Error StringBuilder::setFormat(const char* fmt, ...) noexcept {
+     331             :   bool result;
+     332             : 
+     333             :   va_list ap;
+     334           0 :   va_start(ap, fmt);
+     335           0 :   result = _opVFormat(kStringOpSet, fmt, ap);
+     336           0 :   va_end(ap);
+     337             : 
+     338           0 :   return result;
+     339             : }
+     340             : 
+     341           0 : Error StringBuilder::appendFormat(const char* fmt, ...) noexcept {
+     342             :   bool result;
+     343             : 
+     344             :   va_list ap;
+     345           0 :   va_start(ap, fmt);
+     346           0 :   result = _opVFormat(kStringOpAppend, fmt, ap);
+     347           0 :   va_end(ap);
+     348             : 
+     349           0 :   return result;
+     350             : }
+     351             : 
+     352           0 : bool StringBuilder::eq(const char* str, size_t len) const noexcept {
+     353           0 :   const char* aData = _data;
+     354             :   const char* bData = str;
+     355             : 
+     356           0 :   size_t aLength = _length;
+     357             :   size_t bLength = len;
+     358             : 
+     359           0 :   if (bLength == Globals::kInvalidIndex) {
+     360             :     size_t i;
+     361           0 :     for (i = 0; i < aLength; i++)
+     362           0 :       if (aData[i] != bData[i] || bData[i] == 0)
+     363             :         return false;
+     364           0 :     return bData[i] == 0;
+     365             :   }
+     366             :   else {
+     367           0 :     if (aLength != bLength)
+     368             :       return false;
+     369           0 :     return ::memcmp(aData, bData, aLength) == 0;
+     370             :   }
+     371             : }
+     372             : 
+     373             : } // asmjit namespace
+     374             : } // namespace PLMD
+     375             : 
+     376             : // [Api-End]
+     377             : #include "./asmjit_apiend.h"
+     378             : #pragma GCC diagnostic pop
+     379             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/utils.h.func-sort-c.html b/coverage-libs/asmjit/utils.h.func-sort-c.html new file mode 100644 index 000000000000..7d1b5ca82297 --- /dev/null +++ b/coverage-libs/asmjit/utils.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/utils.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - utils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:224548.9 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/utils.h.func.html b/coverage-libs/asmjit/utils.h.func.html new file mode 100644 index 000000000000..3923ec2c742e --- /dev/null +++ b/coverage-libs/asmjit/utils.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/utils.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - utils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:224548.9 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/utils.h.gcov.html b/coverage-libs/asmjit/utils.h.gcov.html new file mode 100644 index 000000000000..48f39b4923f8 --- /dev/null +++ b/coverage-libs/asmjit/utils.h.gcov.html @@ -0,0 +1,1464 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/utils.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - utils.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:224548.9 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_utils_h
+      21             : #define __PLUMED_asmjit_utils_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_UTILS_H
+      33             : #define _ASMJIT_BASE_UTILS_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./globals.h"
+      37             : 
+      38             : #if ASMJIT_CC_MSC_GE(14, 0, 0)
+      39             : # include <intrin.h>
+      40             : #endif // ASMJIT_OS_WINDOWS
+      41             : 
+      42             : // [Api-Begin]
+      43             : #include "./asmjit_apibegin.h"
+      44             : 
+      45             : namespace PLMD {
+      46             : namespace asmjit {
+      47             : 
+      48             : //! \addtogroup asmjit_base
+      49             : //! \{
+      50             : 
+      51             : // ============================================================================
+      52             : // [asmjit::IntTraits]
+      53             : // ============================================================================
+      54             : 
+      55             : //! \internal
+      56             : //! \{
+      57             : template<size_t Size, int IsSigned>
+      58             : struct IntTraitsPrivate {}; // Let it fail if not specialized!
+      59             : 
+      60             : template<> struct IntTraitsPrivate<1, 0> { typedef int     IntType; typedef int8_t  SignedType; typedef uint8_t  UnsignedType; };
+      61             : template<> struct IntTraitsPrivate<1, 1> { typedef int     IntType; typedef int8_t  SignedType; typedef uint8_t  UnsignedType; };
+      62             : 
+      63             : template<> struct IntTraitsPrivate<2, 0> { typedef int     IntType; typedef int16_t SignedType; typedef uint16_t UnsignedType; };
+      64             : template<> struct IntTraitsPrivate<2, 1> { typedef int     IntType; typedef int16_t SignedType; typedef uint16_t UnsignedType; };
+      65             : 
+      66             : template<> struct IntTraitsPrivate<4, 0> { typedef int64_t IntType; typedef int32_t SignedType; typedef uint32_t UnsignedType; };
+      67             : template<> struct IntTraitsPrivate<4, 1> { typedef int     IntType; typedef int32_t SignedType; typedef uint32_t UnsignedType; };
+      68             : 
+      69             : template<> struct IntTraitsPrivate<8, 0> { typedef int64_t IntType; typedef int64_t SignedType; typedef uint64_t UnsignedType; };
+      70             : template<> struct IntTraitsPrivate<8, 1> { typedef int64_t IntType; typedef int64_t SignedType; typedef uint64_t UnsignedType; };
+      71             : 
+      72             : //! \internal
+      73             : template<typename T>
+      74             : struct IntTraits {
+      75             :   enum {
+      76             :     kIsSigned   = static_cast<T>(~static_cast<T>(0)) < static_cast<T>(0),
+      77             :     kIsUnsigned = !kIsSigned,
+      78             :     kIs8Bit     = sizeof(T) == 1,
+      79             :     kIs16Bit    = sizeof(T) == 2,
+      80             :     kIs32Bit    = sizeof(T) == 4,
+      81             :     kIs64Bit    = sizeof(T) == 8,
+      82             :     kIsIntPtr   = sizeof(T) == sizeof(intptr_t)
+      83             :   };
+      84             : 
+      85             :   typedef typename IntTraitsPrivate<sizeof(T), kIsSigned>::IntType IntType;
+      86             :   typedef typename IntTraitsPrivate<sizeof(T), kIsSigned>::SignedType SignedType;
+      87             :   typedef typename IntTraitsPrivate<sizeof(T), kIsSigned>::UnsignedType UnsignedType;
+      88             : 
+      89             :   //! Get a minimum value of `T`.
+      90             :   static ASMJIT_INLINE T minValue() noexcept {
+      91             :     return kIsSigned ? T((~static_cast<UnsignedType>(0) >> 1) + static_cast<UnsignedType>(1)) : T(0);
+      92             :   }
+      93             : 
+      94             :   //! Get a maximum value of `T`.
+      95             :   static ASMJIT_INLINE T maxValue() noexcept {
+      96             :     return kIsSigned ? T(~static_cast<UnsignedType>(0) >> 1) : ~T(0);
+      97             :   }
+      98             : };
+      99             : 
+     100             : //! \}
+     101             : 
+     102             : // ============================================================================
+     103             : // [asmjit::Utils]
+     104             : // ============================================================================
+     105             : 
+     106             : //! AsmJit utilities - integer, string, etc...
+     107             : namespace Utils {
+     108             :   // --------------------------------------------------------------------------
+     109             :   // [Float <-> Int]
+     110             :   // --------------------------------------------------------------------------
+     111             : 
+     112             :   //! \internal
+     113             :   union FloatBits {
+     114             :     int32_t i;
+     115             :     float f;
+     116             :   };
+     117             : 
+     118             :   //! \internal
+     119             :   union DoubleBits {
+     120             :     int64_t i;
+     121             :     double d;
+     122             :   };
+     123             : 
+     124             :   //! Bit-cast `float` to a 32-bit integer.
+     125             :   static ASMJIT_INLINE int32_t floatAsInt(float f) noexcept { FloatBits m; m.f = f; return m.i; }
+     126             :   //! Bit-cast 32-bit integer to `float`.
+     127             :   static ASMJIT_INLINE float intAsFloat(int32_t i) noexcept { FloatBits m; m.i = i; return m.f; }
+     128             : 
+     129             :   //! Bit-cast `double` to a 64-bit integer.
+     130             :   static ASMJIT_INLINE int64_t doubleAsInt(double d) noexcept { DoubleBits m; m.d = d; return m.i; }
+     131             :   //! Bit-cast 64-bit integer to `double`.
+     132             :   static ASMJIT_INLINE double intAsDouble(int64_t i) noexcept { DoubleBits m; m.i = i; return m.d; }
+     133             : 
+     134             :   // --------------------------------------------------------------------------
+     135             :   // [Pack / Unpack]
+     136             :   // --------------------------------------------------------------------------
+     137             : 
+     138             :   //! Pack four 8-bit integer into a 32-bit integer as it is an array of `{b0,b1,b2,b3}`.
+     139             :   static ASMJIT_INLINE uint32_t pack32_4x8(uint32_t b0, uint32_t b1, uint32_t b2, uint32_t b3) noexcept {
+     140       36702 :     return ASMJIT_PACK32_4x8(b0, b1, b2, b3);
+     141             :   }
+     142             : 
+     143             :   //! Pack two 32-bit integer into a 64-bit integer as it is an array of `{u0,u1}`.
+     144             :   static ASMJIT_INLINE uint64_t pack64_2x32(uint32_t u0, uint32_t u1) noexcept {
+     145       47292 :     return ASMJIT_ARCH_LE ? (static_cast<uint64_t>(u1) << 32) + u0
+     146       27684 :                           : (static_cast<uint64_t>(u0) << 32) + u1;
+     147             :   }
+     148             : 
+     149             :   // --------------------------------------------------------------------------
+     150             :   // [Position of byte (in bit-shift)]
+     151             :   // --------------------------------------------------------------------------
+     152             : 
+     153             :   static ASMJIT_INLINE uint32_t byteShiftOfDWordStruct(uint32_t index) noexcept {
+     154             :     if (ASMJIT_ARCH_LE)
+     155      122988 :       return index * 8;
+     156             :     else
+     157             :       return (sizeof(uint32_t) - 1 - index) * 8;
+     158             :   }
+     159             : 
+     160             :   // --------------------------------------------------------------------------
+     161             :   // [Lower/Upper]
+     162             :   // --------------------------------------------------------------------------
+     163             : 
+     164             :   template<typename T>
+     165             :   static ASMJIT_INLINE T toLower(T c) noexcept { return c ^ (static_cast<T>(c >= T('A') && c <= T('Z')) << 5); }
+     166             :   template<typename T>
+     167             :   static ASMJIT_INLINE T toUpper(T c) noexcept { return c ^ (static_cast<T>(c >= T('a') && c <= T('z')) << 5); }
+     168             : 
+     169             :   // --------------------------------------------------------------------------
+     170             :   // [Hash]
+     171             :   // --------------------------------------------------------------------------
+     172             : 
+     173             :   // \internal
+     174           0 :   static ASMJIT_INLINE uint32_t hashRound(uint32_t hash, uint32_t c) noexcept { return hash * 65599 + c; }
+     175             : 
+     176             :   // Get a hash of the given string `str` of `len` length. Length must be valid
+     177             :   // as this function doesn't check for a null terminator and allows it in the
+     178             :   // middle of the string.
+     179             :   static ASMJIT_INLINE uint32_t hashString(const char* str, size_t len) noexcept {
+     180             :     uint32_t hVal = 0;
+     181             :     for (uint32_t i = 0; i < len; i++)
+     182             :       hVal = hashRound(hVal, str[i]);
+     183             :     return hVal;
+     184             :   }
+     185             : 
+     186             :   // --------------------------------------------------------------------------
+     187             :   // [Swap]
+     188             :   // --------------------------------------------------------------------------
+     189             : 
+     190             :   template<typename T>
+     191             :   static ASMJIT_INLINE void swap(T& a, T& b) noexcept {
+     192             :     T tmp = a;
+     193             :     a = b;
+     194             :     b = tmp;
+     195             :   }
+     196             : 
+     197             :   // --------------------------------------------------------------------------
+     198             :   // [InInterval]
+     199             :   // --------------------------------------------------------------------------
+     200             : 
+     201             :   //! Get whether `x` is greater than or equal to `a` and lesses than or equal to `b`.
+     202             :   template<typename T>
+     203             :   static ASMJIT_INLINE bool inInterval(T x, T a, T b) noexcept {
+     204       20198 :     return x >= a && x <= b;
+     205             :   }
+     206             : 
+     207             :   // --------------------------------------------------------------------------
+     208             :   // [AsInt]
+     209             :   // --------------------------------------------------------------------------
+     210             : 
+     211             :   //! Map an integer `x` of type `T` to `int` or `int64_t` depending on the
+     212             :   //! type. Used internally by AsmJit to dispatch arguments that can be of
+     213             :   //! arbitrary integer type into a function argument that is either `int` or
+     214             :   //! `int64_t`.
+     215             :   template<typename T>
+     216             :   static ASMJIT_INLINE typename IntTraits<T>::IntType asInt(T x) noexcept {
+     217         932 :     return static_cast<typename IntTraits<T>::IntType>(x);
+     218             :   }
+     219             : 
+     220             :   // --------------------------------------------------------------------------
+     221             :   // [IsInt / IsUInt]
+     222             :   // --------------------------------------------------------------------------
+     223             : 
+     224             :   //! Get whether the given integer `x` can be casted to a 4-bit signed integer.
+     225             :   template<typename T>
+     226             :   static ASMJIT_INLINE bool isInt4(T x) noexcept {
+     227             :     typedef typename IntTraits<T>::SignedType SignedType;
+     228             :     typedef typename IntTraits<T>::UnsignedType UnsignedType;
+     229             : 
+     230             :     if (IntTraits<T>::kIsSigned)
+     231             :       return inInterval<SignedType>(SignedType(x), -8, 7);
+     232             :     else
+     233             :       return UnsignedType(x) <= UnsignedType(7U);
+     234             :   }
+     235             : 
+     236             :   //! Get whether the given integer `x` can be casted to an 8-bit signed integer.
+     237             :   template<typename T>
+     238             :   static ASMJIT_INLINE bool isInt8(T x) noexcept {
+     239             :     typedef typename IntTraits<T>::SignedType SignedType;
+     240             :     typedef typename IntTraits<T>::UnsignedType UnsignedType;
+     241             : 
+     242             :     if (IntTraits<T>::kIsSigned)
+     243             :       return sizeof(T) <= 1 || inInterval<SignedType>(SignedType(x), -128, 127);
+     244             :     else
+     245             :       return UnsignedType(x) <= UnsignedType(127U);
+     246             :   }
+     247             : 
+     248             :   //! Get whether the given integer `x` can be casted to a 16-bit signed integer.
+     249             :   template<typename T>
+     250             :   static ASMJIT_INLINE bool isInt16(T x) noexcept {
+     251             :     typedef typename IntTraits<T>::SignedType SignedType;
+     252             :     typedef typename IntTraits<T>::UnsignedType UnsignedType;
+     253             : 
+     254             :     if (IntTraits<T>::kIsSigned)
+     255             :       return sizeof(T) <= 2 || inInterval<SignedType>(SignedType(x), -32768, 32767);
+     256             :     else
+     257             :       return sizeof(T) <= 1 || UnsignedType(x) <= UnsignedType(32767U);
+     258             :   }
+     259             : 
+     260             :   //! Get whether the given integer `x` can be casted to a 32-bit signed integer.
+     261             :   template<typename T>
+     262             :   static ASMJIT_INLINE bool isInt32(T x) noexcept {
+     263             :     typedef typename IntTraits<T>::SignedType SignedType;
+     264             :     typedef typename IntTraits<T>::UnsignedType UnsignedType;
+     265             : 
+     266             :     if (IntTraits<T>::kIsSigned)
+     267             :       return sizeof(T) <= 4 || inInterval<SignedType>(SignedType(x), -2147483647 - 1, 2147483647);
+     268             :     else
+     269             :       return sizeof(T) <= 2 || UnsignedType(x) <= UnsignedType(2147483647U);
+     270             :   }
+     271             : 
+     272             :   //! Get whether the given integer `x` can be casted to a 4-bit unsigned integer.
+     273             :   template<typename T>
+     274             :   static ASMJIT_INLINE bool isUInt4(T x) noexcept {
+     275             :     typedef typename IntTraits<T>::UnsignedType UnsignedType;
+     276             : 
+     277             :     if (IntTraits<T>::kIsSigned)
+     278             :       return x >= T(0) && x <= T(15);
+     279             :     else
+     280             :       return UnsignedType(x) <= UnsignedType(15U);
+     281             :   }
+     282             : 
+     283             :   //! Get whether the given integer `x` can be casted to an 8-bit unsigned integer.
+     284             :   template<typename T>
+     285             :   static ASMJIT_INLINE bool isUInt8(T x) noexcept {
+     286             :     typedef typename IntTraits<T>::UnsignedType UnsignedType;
+     287             : 
+     288             :     if (IntTraits<T>::kIsSigned)
+     289             :       return x >= T(0) && (sizeof(T) <= 1 ? true : x <= T(255));
+     290             :     else
+     291             :       return sizeof(T) <= 1 || UnsignedType(x) <= UnsignedType(255U);
+     292             :   }
+     293             : 
+     294             :   //! Get whether the given integer `x` can be casted to a 12-bit unsigned integer (ARM specific).
+     295             :   template<typename T>
+     296             :   static ASMJIT_INLINE bool isUInt12(T x) noexcept {
+     297             :     typedef typename IntTraits<T>::UnsignedType UnsignedType;
+     298             : 
+     299             :     if (IntTraits<T>::kIsSigned)
+     300             :       return x >= T(0) && (sizeof(T) <= 1 ? true : x <= T(4095));
+     301             :     else
+     302             :       return sizeof(T) <= 1 || UnsignedType(x) <= UnsignedType(4095U);
+     303             :   }
+     304             : 
+     305             :   //! Get whether the given integer `x` can be casted to a 16-bit unsigned integer.
+     306             :   template<typename T>
+     307             :   static ASMJIT_INLINE bool isUInt16(T x) noexcept {
+     308             :     typedef typename IntTraits<T>::UnsignedType UnsignedType;
+     309             : 
+     310             :     if (IntTraits<T>::kIsSigned)
+     311             :       return x >= T(0) && (sizeof(T) <= 2 ? true : x <= T(65535));
+     312             :     else
+     313             :       return sizeof(T) <= 2 || UnsignedType(x) <= UnsignedType(65535U);
+     314             :   }
+     315             : 
+     316             :   //! Get whether the given integer `x` can be casted to a 32-bit unsigned integer.
+     317             :   template<typename T>
+     318             :   static ASMJIT_INLINE bool isUInt32(T x) noexcept {
+     319             :     typedef typename IntTraits<T>::UnsignedType UnsignedType;
+     320             : 
+     321             :     if (IntTraits<T>::kIsSigned)
+     322        9972 :       return x >= T(0) && (sizeof(T) <= 4 ? true : x <= T(4294967295U));
+     323             :     else
+     324             :       return sizeof(T) <= 4 || UnsignedType(x) <= UnsignedType(4294967295U);
+     325             :   }
+     326             : 
+     327             :   // --------------------------------------------------------------------------
+     328             :   // [IsPowerOf2]
+     329             :   // --------------------------------------------------------------------------
+     330             : 
+     331             :   //! Get whether the `n` value is a power of two (only one bit is set).
+     332             :   template<typename T>
+     333             :   static ASMJIT_INLINE bool isPowerOf2(T n) noexcept {
+     334       26412 :     return n != 0 && (n & (n - 1)) == 0;
+     335             :   }
+     336             : 
+     337             :   // --------------------------------------------------------------------------
+     338             :   // [Mask]
+     339             :   // --------------------------------------------------------------------------
+     340             : 
+     341             :   //! Generate a bit-mask that has `x` bit set.
+     342             :   static ASMJIT_INLINE uint32_t mask(uint32_t x) noexcept {
+     343             :     ASMJIT_ASSERT(x < 32);
+     344      157552 :     return static_cast<uint32_t>(1) << x;
+     345             :   }
+     346             : 
+     347             :   //! Generate a bit-mask that has `x0` and `x1` bits set.
+     348             :   static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1) noexcept {
+     349             :     return mask(x0) | mask(x1);
+     350             :   }
+     351             : 
+     352             :   //! Generate a bit-mask that has `x0`, `x1` and `x2` bits set.
+     353             :   static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2) noexcept {
+     354             :     return mask(x0, x1) | mask(x2);
+     355             :   }
+     356             : 
+     357             :   //! Generate a bit-mask that has `x0`, `x1`, `x2` and `x3` bits set.
+     358             :   static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3) noexcept {
+     359             :     return mask(x0, x1) | mask(x2, x3);
+     360             :   }
+     361             : 
+     362             :   //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3` and `x4` bits set.
+     363             :   static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4) noexcept {
+     364             :     return mask(x0, x1) | mask(x2, x3) | mask(x4);
+     365             :   }
+     366             : 
+     367             :   //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4` and `x5` bits set.
+     368             :   static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5) noexcept {
+     369             :     return mask(x0, x1) | mask(x2, x3) | mask(x4, x5);
+     370             :   }
+     371             : 
+     372             :   //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5` and `x6` bits set.
+     373             :   static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6) noexcept {
+     374             :     return mask(x0, x1) | mask(x2, x3) | mask(x4, x5) | mask(x6);
+     375             :   }
+     376             : 
+     377             :   //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6` and `x7` bits set.
+     378             :   static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7) noexcept {
+     379             :     return mask(x0, x1) | mask(x2, x3) | mask(x4, x5) | mask(x6, x7);
+     380             :   }
+     381             : 
+     382             :   //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6`, `x7` and `x8` bits set.
+     383             :   static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8) noexcept {
+     384             :     return mask(x0, x1) | mask(x2, x3) | mask(x4, x5) | mask(x6, x7) | mask(x8);
+     385             :   }
+     386             : 
+     387             :   //! Generate a bit-mask that has `x0`, `x1`, `x2`, `x3`, `x4`, `x5`, `x6`, `x7`, `x8` and `x9` bits set.
+     388             :   static ASMJIT_INLINE uint32_t mask(uint32_t x0, uint32_t x1, uint32_t x2, uint32_t x3, uint32_t x4, uint32_t x5, uint32_t x6, uint32_t x7, uint32_t x8, uint32_t x9) noexcept {
+     389             :     return mask(x0, x1) | mask(x2, x3) | mask(x4, x5) | mask(x6, x7) | mask(x8, x9);
+     390             :   }
+     391             : 
+     392             :   // --------------------------------------------------------------------------
+     393             :   // [Bits]
+     394             :   // --------------------------------------------------------------------------
+     395             : 
+     396             :   //! Generate a bit-mask that has `x` least significant bits set.
+     397             :   static ASMJIT_INLINE uint32_t bits(uint32_t x) noexcept {
+     398             :     // Shifting more bits than the type has results in undefined behavior. In
+     399             :     // such case asmjit trashes the result by ORing with `overflow` mask, which
+     400             :     // discards the undefined value returned by the shift.
+     401        5544 :     uint32_t overflow = static_cast<uint32_t>(
+     402        5544 :       -static_cast<int32_t>(x >= sizeof(uint32_t) * 8));
+     403             : 
+     404        5544 :     return ((static_cast<uint32_t>(1) << x) - 1U) | overflow;
+     405             :   }
+     406             : 
+     407             :   // --------------------------------------------------------------------------
+     408             :   // [HasBit]
+     409             :   // --------------------------------------------------------------------------
+     410             : 
+     411             :   //! Get whether `x` has bit `n` set.
+     412             :   template<typename T, typename Index>
+     413             :   static ASMJIT_INLINE bool hasBit(T x, Index n) noexcept {
+     414             :     return (x & (static_cast<T>(1) << n)) != 0;
+     415             :   }
+     416             : 
+     417             :   // --------------------------------------------------------------------------
+     418             :   // [BitCount]
+     419             :   // --------------------------------------------------------------------------
+     420             : 
+     421             :   static ASMJIT_INLINE uint32_t bitCountSlow(uint32_t x) noexcept {
+     422             :     // From: http://graphics.stanford.edu/~seander/bithacks.html
+     423             :     x = x - ((x >> 1) & 0x55555555U);
+     424             :     x = (x & 0x33333333U) + ((x >> 2) & 0x33333333U);
+     425             :     return (((x + (x >> 4)) & 0x0F0F0F0FU) * 0x01010101U) >> 24;
+     426             :   }
+     427             : 
+     428             :   //! Get count of bits in `x`.
+     429             :   static ASMJIT_INLINE uint32_t bitCount(uint32_t x) noexcept {
+     430             : #if ASMJIT_CC_GCC || ASMJIT_CC_CLANG
+     431        1948 :     return __builtin_popcount(x);
+     432             : #else
+     433             :     return bitCountSlow(x);
+     434             : #endif
+     435             :   }
+     436             : 
+     437             :   // --------------------------------------------------------------------------
+     438             :   // [FirstBitOf]
+     439             :   // --------------------------------------------------------------------------
+     440             : 
+     441             :   template<uint64_t In>
+     442             :   struct FirstBitOfTImpl {
+     443             :     enum {
+     444             :       _shift = (In & ASMJIT_UINT64_C(0x0000FFFFFFFFFFFF)) == 0 ? 48 :
+     445             :                (In & ASMJIT_UINT64_C(0x00000000FFFFFFFF)) == 0 ? 32 :
+     446             :                (In & ASMJIT_UINT64_C(0x000000000000FFFF)) == 0 ? 16 : 0,
+     447             : 
+     448             :       kValue = ((In >> _shift) & 0x0001) ? (_shift +  0) :
+     449             :                ((In >> _shift) & 0x0002) ? (_shift +  1) :
+     450             :                ((In >> _shift) & 0x0004) ? (_shift +  2) :
+     451             :                ((In >> _shift) & 0x0008) ? (_shift +  3) :
+     452             :                ((In >> _shift) & 0x0010) ? (_shift +  4) :
+     453             :                ((In >> _shift) & 0x0020) ? (_shift +  5) :
+     454             :                ((In >> _shift) & 0x0040) ? (_shift +  6) :
+     455             :                ((In >> _shift) & 0x0080) ? (_shift +  7) :
+     456             :                ((In >> _shift) & 0x0100) ? (_shift +  8) :
+     457             :                ((In >> _shift) & 0x0200) ? (_shift +  9) :
+     458             :                ((In >> _shift) & 0x0400) ? (_shift + 10) :
+     459             :                ((In >> _shift) & 0x0800) ? (_shift + 11) :
+     460             :                ((In >> _shift) & 0x1000) ? (_shift + 12) :
+     461             :                ((In >> _shift) & 0x2000) ? (_shift + 13) :
+     462             :                ((In >> _shift) & 0x4000) ? (_shift + 14) :
+     463             :                ((In >> _shift) & 0x8000) ? (_shift + 15) : 0
+     464             :     };
+     465             :   };
+     466             : 
+     467             :   template<>
+     468             :   struct FirstBitOfTImpl<0> {};
+     469             : 
+     470             :   template<uint64_t In>
+     471             :   static ASMJIT_INLINE uint32_t firstBitOfT() noexcept { return FirstBitOfTImpl<In>::kValue; }
+     472             : 
+     473             :   // --------------------------------------------------------------------------
+     474             :   // [FindFirstBit]
+     475             :   // --------------------------------------------------------------------------
+     476             : 
+     477             :   //! \internal
+     478             :   static ASMJIT_INLINE uint32_t findFirstBitSlow(uint32_t mask) noexcept {
+     479             :     // This is a reference (slow) implementation of `findFirstBit()`, used when
+     480             :     // we don't have a C++ compiler support. The implementation speed has been
+     481             :     // improved to check for 2 bits per iteration.
+     482             :     uint32_t i = 1;
+     483             : 
+     484             :     while (mask != 0) {
+     485             :       uint32_t two = mask & 0x3;
+     486             :       if (two != 0x0)
+     487             :         return i - (two & 0x1);
+     488             : 
+     489             :       i += 2;
+     490             :       mask >>= 2;
+     491             :     }
+     492             : 
+     493             :     return 0xFFFFFFFFU;
+     494             :   }
+     495             : 
+     496             :   //! Find a first bit in `mask`.
+     497             :   static ASMJIT_INLINE uint32_t findFirstBit(uint32_t mask) noexcept {
+     498             : #if ASMJIT_CC_MSC_GE(14, 0, 0) && (ASMJIT_ARCH_X86 || ASMJIT_ARCH_ARM32 || \
+     499             :                                    ASMJIT_ARCH_X64 || ASMJIT_ARCH_ARM64)
+     500             :     DWORD i;
+     501             :     if (_BitScanForward(&i, mask))
+     502             :       return static_cast<uint32_t>(i);
+     503             :     else
+     504             :       return 0xFFFFFFFFU;
+     505             : #elif ASMJIT_CC_GCC_GE(3, 4, 6) || ASMJIT_CC_CLANG
+     506       29716 :     if (mask)
+     507       29716 :       return __builtin_ctz(mask);
+     508             :     else
+     509             :       return 0xFFFFFFFFU;
+     510             : #else
+     511             :     return findFirstBitSlow(mask);
+     512             : #endif
+     513             :   }
+     514             : 
+     515             :   // --------------------------------------------------------------------------
+     516             :   // [Misc]
+     517             :   // --------------------------------------------------------------------------
+     518             : 
+     519             :   static ASMJIT_INLINE uint32_t keepNOnesFromRight(uint32_t mask, uint32_t nBits) noexcept {
+     520             :     uint32_t m = 0x1;
+     521             : 
+     522             :     do {
+     523             :       nBits -= (mask & m) != 0;
+     524             :       m <<= 1;
+     525             :       if (nBits == 0) {
+     526             :         m -= 1;
+     527             :         mask &= m;
+     528             :         break;
+     529             :       }
+     530             :     } while (m);
+     531             : 
+     532             :     return mask;
+     533             :   }
+     534             : 
+     535             :   static ASMJIT_INLINE uint32_t indexNOnesFromRight(uint8_t* dst, uint32_t mask, uint32_t nBits) noexcept {
+     536             :     uint32_t totalBits = nBits;
+     537             :     uint8_t i = 0;
+     538             :     uint32_t m = 0x1;
+     539             : 
+     540             :     do {
+     541             :       if (mask & m) {
+     542             :         *dst++ = i;
+     543             :         if (--nBits == 0)
+     544             :           break;
+     545             :       }
+     546             : 
+     547             :       m <<= 1;
+     548             :       i++;
+     549             :     } while (m);
+     550             : 
+     551             :     return totalBits - nBits;
+     552             :   }
+     553             : 
+     554             :   // --------------------------------------------------------------------------
+     555             :   // [Alignment]
+     556             :   // --------------------------------------------------------------------------
+     557             : 
+     558             :   template<typename X, typename Y>
+     559             :   static ASMJIT_INLINE bool isAligned(X base, Y alignment) noexcept {
+     560             :     typedef typename IntTraitsPrivate<sizeof(X), 0>::UnsignedType U;
+     561           0 :     return ((U)base % (U)alignment) == 0;
+     562             :   }
+     563             : 
+     564             :   template<typename X, typename Y>
+     565             :   static ASMJIT_INLINE X alignTo(X x, Y alignment) noexcept {
+     566             :     typedef typename IntTraitsPrivate<sizeof(X), 0>::UnsignedType U;
+     567      171916 :     return (X)( ((U)x + (U)(alignment - 1)) & ~(static_cast<U>(alignment) - 1) );
+     568             :   }
+     569             : 
+     570             :   //! Get delta required to align `base` to `alignment`.
+     571             :   template<typename X, typename Y>
+     572             :   static ASMJIT_INLINE X alignDiff(X base, Y alignment) noexcept {
+     573        1092 :     return alignTo(base, alignment) - base;
+     574             :   }
+     575             : 
+     576             :   template<typename T>
+     577             :   static ASMJIT_INLINE T alignToPowerOf2(T base) noexcept {
+     578             :     // Implementation is from "Hacker's Delight" by Henry S. Warren, Jr.
+     579             :     base -= 1;
+     580             : 
+     581             : #if defined(_MSC_VER)
+     582             : # pragma warning(push)
+     583             : # pragma warning(disable: 4293)
+     584             : #endif // _MSC_VER
+     585             : 
+     586             :     base = base | (base >> 1);
+     587             :     base = base | (base >> 2);
+     588             :     base = base | (base >> 4);
+     589             : 
+     590             :     // 8/16/32 constants are multiplied by the condition to prevent a compiler
+     591             :     // complaining about the 'shift count >= type width' (GCC).
+     592             :     if (sizeof(T) >= 2) base = base | (base >> ( 8 * (sizeof(T) >= 2))); // Base >>  8.
+     593             :     if (sizeof(T) >= 4) base = base | (base >> (16 * (sizeof(T) >= 4))); // Base >> 16.
+     594             :     if (sizeof(T) >= 8) base = base | (base >> (32 * (sizeof(T) >= 8))); // Base >> 32.
+     595             : 
+     596             : #if defined(_MSC_VER)
+     597             : # pragma warning(pop)
+     598             : #endif // _MSC_VER
+     599             : 
+     600             :     return base + 1;
+     601             :   }
+     602             : 
+     603             :   // --------------------------------------------------------------------------
+     604             :   // [String]
+     605             :   // --------------------------------------------------------------------------
+     606             : 
+     607             :   static ASMJIT_INLINE size_t strLen(const char* s, size_t maxlen) noexcept {
+     608             :     size_t i;
+     609           0 :     for (i = 0; i < maxlen; i++)
+     610           0 :       if (!s[i])
+     611             :         break;
+     612             :     return i;
+     613             :   }
+     614             : 
+     615             :   static ASMJIT_INLINE const char* findPackedString(const char* p, uint32_t id) noexcept {
+     616             :     uint32_t i = 0;
+     617           0 :     while (i < id) {
+     618           0 :       while (p[0])
+     619           0 :         p++;
+     620           0 :       p++;
+     621           0 :       i++;
+     622             :     }
+     623             :     return p;
+     624             :   }
+     625             : 
+     626             :   //! \internal
+     627             :   //!
+     628             :   //! Compare two instruction names.
+     629             :   //!
+     630             :   //! `a` is a null terminated instruction name from `???InstDB::nameData[]` table.
+     631             :   //! `b` is a non-null terminated instruction name passed to `???Inst::getIdByName()`.
+     632             :   static ASMJIT_INLINE int cmpInstName(const char* a, const char* b, size_t len) noexcept {
+     633           0 :     for (size_t i = 0; i < len; i++) {
+     634           0 :       int c = static_cast<int>(static_cast<uint8_t>(a[i])) -
+     635           0 :               static_cast<int>(static_cast<uint8_t>(b[i])) ;
+     636           0 :       if (c != 0) return c;
+     637             :     }
+     638             : 
+     639           0 :     return static_cast<int>(a[len]);
+     640             :   }
+     641             : 
+     642             :   // --------------------------------------------------------------------------
+     643             :   // [BSwap]
+     644             :   // --------------------------------------------------------------------------
+     645             : 
+     646             :   static ASMJIT_INLINE uint32_t byteswap32(uint32_t x) noexcept {
+     647             : #if ASMJIT_CC_MSC
+     648             :     return static_cast<uint32_t>(_byteswap_ulong(x));
+     649             : #elif ASMJIT_CC_GCC_GE(4, 3, 0) || ASMJIT_CC_CLANG_GE(2, 6, 0)
+     650             :     return __builtin_bswap32(x);
+     651             : #else
+     652             :     uint32_t y = x & 0x00FFFF00U;
+     653             :     x = (x << 24) + (x >> 24);
+     654             :     y = (y <<  8) + (y >>  8);
+     655             :     return x + (y & 0x00FFFF00U);
+     656             : #endif
+     657             :   }
+     658             : 
+     659             :   // --------------------------------------------------------------------------
+     660             :   // [ReadMem]
+     661             :   // --------------------------------------------------------------------------
+     662             : 
+     663             :   static ASMJIT_INLINE uint32_t readU8(const void* p) noexcept {
+     664             :     return static_cast<uint32_t>(static_cast<const uint8_t*>(p)[0]);
+     665             :   }
+     666             : 
+     667             :   static ASMJIT_INLINE int32_t readI8(const void* p) noexcept {
+     668             :     return static_cast<int32_t>(static_cast<const int8_t*>(p)[0]);
+     669             :   }
+     670             : 
+     671             :   template<unsigned int Alignment>
+     672             :   static ASMJIT_INLINE uint32_t readU16xLE(const void* p) noexcept {
+     673             :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     674             :     if (ASMJIT_ARCH_LE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) {
+     675             :       return static_cast<uint32_t>(static_cast<const uint16_t*>(p)[0]);
+     676             :     }
+     677             :     else {
+     678             :       uint32_t x = static_cast<uint32_t>(static_cast<const uint8_t*>(p)[0]);
+     679             :       uint32_t y = static_cast<uint32_t>(static_cast<const uint8_t*>(p)[1]);
+     680             :       return x + (y << 8);
+     681             :     }
+     682             :   }
+     683             : 
+     684             :   template<unsigned int Alignment>
+     685             :   static ASMJIT_INLINE uint32_t readU16xBE(const void* p) noexcept {
+     686             :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     687             :     if (ASMJIT_ARCH_BE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) {
+     688             :       return static_cast<uint32_t>(static_cast<const uint16_t*>(p)[0]);
+     689             :     }
+     690             :     else {
+     691             :       uint32_t x = static_cast<uint32_t>(static_cast<const uint8_t*>(p)[0]);
+     692             :       uint32_t y = static_cast<uint32_t>(static_cast<const uint8_t*>(p)[1]);
+     693             :       return (x << 8) + y;
+     694             :     }
+     695             :   }
+     696             : 
+     697             :   template<unsigned int Alignment>
+     698             :   static ASMJIT_INLINE uint32_t readU16x(const void* p) noexcept {
+     699             :     return ASMJIT_ARCH_LE ? readU16xLE<Alignment>(p) : readU16xBE<Alignment>(p);
+     700             :   }
+     701             : 
+     702             :   template<unsigned int Alignment>
+     703             :   static ASMJIT_INLINE int32_t readI16xLE(const void* p) noexcept {
+     704             :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     705             :     if (ASMJIT_ARCH_LE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) {
+     706             :       return static_cast<int32_t>(static_cast<const int16_t*>(p)[0]);
+     707             :     }
+     708             :     else {
+     709             :       int32_t x = static_cast<int32_t>(static_cast<const uint8_t*>(p)[0]);
+     710             :       int32_t y = static_cast<int32_t>(static_cast<const int8_t*>(p)[1]);
+     711             :       return x + (y << 8);
+     712             :     }
+     713             :   }
+     714             : 
+     715             :   template<unsigned int Alignment>
+     716             :   static ASMJIT_INLINE int32_t readI16xBE(const void* p) noexcept {
+     717             :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     718             :     if (ASMJIT_ARCH_BE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) {
+     719             :       return static_cast<int32_t>(static_cast<const int16_t*>(p)[0]);
+     720             :     }
+     721             :     else {
+     722             :       int32_t x = static_cast<int32_t>(static_cast<const int8_t*>(p)[0]);
+     723             :       int32_t y = static_cast<int32_t>(static_cast<const uint8_t*>(p)[1]);
+     724             :       return (x << 8) + y;
+     725             :     }
+     726             :   }
+     727             : 
+     728             :   template<unsigned int Alignment>
+     729             :   static ASMJIT_INLINE int32_t readI16x(const void* p) noexcept {
+     730             :     return ASMJIT_ARCH_LE ? readI16xLE<Alignment>(p) : readI16xBE<Alignment>(p);
+     731             :   }
+     732             : 
+     733             :   static ASMJIT_INLINE uint32_t readU16aLE(const void* p) noexcept { return readU16xLE<2>(p); }
+     734             :   static ASMJIT_INLINE uint32_t readU16uLE(const void* p) noexcept { return readU16xLE<0>(p); }
+     735             : 
+     736             :   static ASMJIT_INLINE uint32_t readU16aBE(const void* p) noexcept { return readU16xBE<2>(p); }
+     737             :   static ASMJIT_INLINE uint32_t readU16uBE(const void* p) noexcept { return readU16xBE<0>(p); }
+     738             : 
+     739             :   static ASMJIT_INLINE uint32_t readU16a(const void* p) noexcept { return readU16x<2>(p); }
+     740             :   static ASMJIT_INLINE uint32_t readU16u(const void* p) noexcept { return readU16x<0>(p); }
+     741             : 
+     742             :   static ASMJIT_INLINE int32_t readI16aLE(const void* p) noexcept { return readI16xLE<2>(p); }
+     743             :   static ASMJIT_INLINE int32_t readI16uLE(const void* p) noexcept { return readI16xLE<0>(p); }
+     744             : 
+     745             :   static ASMJIT_INLINE int32_t readI16aBE(const void* p) noexcept { return readI16xBE<2>(p); }
+     746             :   static ASMJIT_INLINE int32_t readI16uBE(const void* p) noexcept { return readI16xBE<0>(p); }
+     747             : 
+     748             :   static ASMJIT_INLINE int32_t readI16a(const void* p) noexcept { return readI16x<2>(p); }
+     749             :   static ASMJIT_INLINE int32_t readI16u(const void* p) noexcept { return readI16x<0>(p); }
+     750             : 
+     751             :   template<unsigned int Alignment>
+     752             :   static ASMJIT_INLINE uint32_t readU32xLE(const void* p) noexcept {
+     753             :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     754             :     if (ASMJIT_ARCH_UNALIGNED_32 || Alignment >= 4) {
+     755             :       uint32_t x = static_cast<const uint32_t*>(p)[0];
+     756             :       return ASMJIT_ARCH_LE ? x : byteswap32(x);
+     757             :     }
+     758             :     else {
+     759             :       uint32_t x = readU16xLE<Alignment>(static_cast<const uint8_t*>(p) + 0);
+     760             :       uint32_t y = readU16xLE<Alignment>(static_cast<const uint8_t*>(p) + 2);
+     761             :       return x + (y << 16);
+     762             :     }
+     763             :   }
+     764             : 
+     765             :   template<unsigned int Alignment>
+     766             :   static ASMJIT_INLINE uint32_t readU32xBE(const void* p) noexcept {
+     767             :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     768             :     if (ASMJIT_ARCH_UNALIGNED_32 || Alignment >= 4) {
+     769             :       uint32_t x = static_cast<const uint32_t*>(p)[0];
+     770             :       return ASMJIT_ARCH_BE ? x : byteswap32(x);
+     771             :     }
+     772             :     else {
+     773             :       uint32_t x = readU16xBE<Alignment>(static_cast<const uint8_t*>(p) + 0);
+     774             :       uint32_t y = readU16xBE<Alignment>(static_cast<const uint8_t*>(p) + 2);
+     775             :       return (x << 16) + y;
+     776             :     }
+     777             :   }
+     778             : 
+     779             :   template<unsigned int Alignment>
+     780             :   static ASMJIT_INLINE uint32_t readU32x(const void* p) noexcept {
+     781             :     return ASMJIT_ARCH_LE ? readU32xLE<Alignment>(p) : readU32xBE<Alignment>(p);
+     782             :   }
+     783             : 
+     784             :   template<unsigned int Alignment>
+     785             :   static ASMJIT_INLINE int32_t readI32xLE(const void* p) noexcept {
+     786             :     return static_cast<int32_t>(readU32xLE<Alignment>(p));
+     787             :   }
+     788             : 
+     789             :   template<unsigned int Alignment>
+     790             :   static ASMJIT_INLINE int32_t readI32xBE(const void* p) noexcept {
+     791             :     return static_cast<int32_t>(readU32xBE<Alignment>(p));
+     792             :   }
+     793             : 
+     794             :   template<unsigned int Alignment>
+     795             :   static ASMJIT_INLINE int32_t readI32x(const void* p) noexcept {
+     796             :     return ASMJIT_ARCH_LE ? readI32xLE<Alignment>(p) : readI32xBE<Alignment>(p);
+     797             :   }
+     798             : 
+     799             :   static ASMJIT_INLINE uint32_t readU32a(const void* p) noexcept { return readU32x<4>(p); }
+     800             :   static ASMJIT_INLINE uint32_t readU32u(const void* p) noexcept { return readU32x<0>(p); }
+     801             : 
+     802             :   static ASMJIT_INLINE uint32_t readU32aLE(const void* p) noexcept { return readU32xLE<4>(p); }
+     803             :   static ASMJIT_INLINE uint32_t readU32uLE(const void* p) noexcept { return readU32xLE<0>(p); }
+     804             : 
+     805             :   static ASMJIT_INLINE uint32_t readU32aBE(const void* p) noexcept { return readU32xBE<4>(p); }
+     806             :   static ASMJIT_INLINE uint32_t readU32uBE(const void* p) noexcept { return readU32xBE<0>(p); }
+     807             : 
+     808             :   static ASMJIT_INLINE int32_t readI32a(const void* p) noexcept { return readI32x<4>(p); }
+     809             :   static ASMJIT_INLINE int32_t readI32u(const void* p) noexcept { return readI32x<0>(p); }
+     810             : 
+     811             :   static ASMJIT_INLINE int32_t readI32aLE(const void* p) noexcept { return readI32xLE<4>(p); }
+     812             :   static ASMJIT_INLINE int32_t readI32uLE(const void* p) noexcept { return readI32xLE<0>(p); }
+     813             : 
+     814             :   static ASMJIT_INLINE int32_t readI32aBE(const void* p) noexcept { return readI32xBE<4>(p); }
+     815             :   static ASMJIT_INLINE int32_t readI32uBE(const void* p) noexcept { return readI32xBE<0>(p); }
+     816             : 
+     817             :   template<unsigned int Alignment>
+     818             :   static ASMJIT_INLINE uint64_t readU64xLE(const void* p) noexcept {
+     819             :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     820             :     if (ASMJIT_ARCH_LE && (ASMJIT_ARCH_UNALIGNED_64 || Alignment >= 8)) {
+     821             :       return static_cast<const uint64_t*>(p)[0];
+     822             :     }
+     823             :     else {
+     824             :       uint32_t x = readU32xLE<Alignment / 2U>(static_cast<const uint8_t*>(p) + 0);
+     825             :       uint32_t y = readU32xLE<Alignment / 2U>(static_cast<const uint8_t*>(p) + 4);
+     826             :       return static_cast<uint64_t>(x) + (static_cast<uint64_t>(y) << 32);
+     827             :     }
+     828             :   }
+     829             : 
+     830             :   template<unsigned int Alignment>
+     831             :   static ASMJIT_INLINE uint64_t readU64xBE(const void* p) noexcept {
+     832             :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     833             :     if (ASMJIT_ARCH_BE && (ASMJIT_ARCH_UNALIGNED_64 || Alignment >= 8)) {
+     834             :       return static_cast<const uint64_t*>(p)[0];
+     835             :     }
+     836             :     else {
+     837             :       uint32_t x = readU32xLE<Alignment / 2U>(static_cast<const uint8_t*>(p) + 0);
+     838             :       uint32_t y = readU32xLE<Alignment / 2U>(static_cast<const uint8_t*>(p) + 4);
+     839             :       return (static_cast<uint64_t>(x) << 32) + static_cast<uint64_t>(y);
+     840             :     }
+     841             :   }
+     842             : 
+     843             :   template<unsigned int Alignment>
+     844             :   static ASMJIT_INLINE uint64_t readU64x(const void* p) noexcept {
+     845             :     return ASMJIT_ARCH_LE ? readU64xLE<Alignment>(p) : readU64xBE<Alignment>(p);
+     846             :   }
+     847             : 
+     848             :   template<unsigned int Alignment>
+     849             :   static ASMJIT_INLINE int64_t readI64xLE(const void* p) noexcept {
+     850             :     return static_cast<int64_t>(readU64xLE<Alignment>(p));
+     851             :   }
+     852             : 
+     853             :   template<unsigned int Alignment>
+     854             :   static ASMJIT_INLINE int64_t readI64xBE(const void* p) noexcept {
+     855             :     return static_cast<int64_t>(readU64xBE<Alignment>(p));
+     856             :   }
+     857             : 
+     858             :   template<unsigned int Alignment>
+     859             :   static ASMJIT_INLINE int64_t readI64x(const void* p) noexcept {
+     860             :     return ASMJIT_ARCH_LE ? readI64xLE<Alignment>(p) : readI64xBE<Alignment>(p);
+     861             :   }
+     862             : 
+     863             :   static ASMJIT_INLINE uint64_t readU64a(const void* p) noexcept { return readU64x<8>(p); }
+     864             :   static ASMJIT_INLINE uint64_t readU64u(const void* p) noexcept { return readU64x<0>(p); }
+     865             : 
+     866             :   static ASMJIT_INLINE uint64_t readU64aLE(const void* p) noexcept { return readU64xLE<8>(p); }
+     867             :   static ASMJIT_INLINE uint64_t readU64uLE(const void* p) noexcept { return readU64xLE<0>(p); }
+     868             : 
+     869             :   static ASMJIT_INLINE uint64_t readU64aBE(const void* p) noexcept { return readU64xBE<8>(p); }
+     870             :   static ASMJIT_INLINE uint64_t readU64uBE(const void* p) noexcept { return readU64xBE<0>(p); }
+     871             : 
+     872             :   static ASMJIT_INLINE int64_t readI64a(const void* p) noexcept { return readI64x<8>(p); }
+     873             :   static ASMJIT_INLINE int64_t readI64u(const void* p) noexcept { return readI64x<0>(p); }
+     874             : 
+     875             :   static ASMJIT_INLINE int64_t readI64aLE(const void* p) noexcept { return readI64xLE<8>(p); }
+     876             :   static ASMJIT_INLINE int64_t readI64uLE(const void* p) noexcept { return readI64xLE<0>(p); }
+     877             : 
+     878             :   static ASMJIT_INLINE int64_t readI64aBE(const void* p) noexcept { return readI64xBE<8>(p); }
+     879             :   static ASMJIT_INLINE int64_t readI64uBE(const void* p) noexcept { return readI64xBE<0>(p); }
+     880             : 
+     881             :   // --------------------------------------------------------------------------
+     882             :   // [WriteMem]
+     883             :   // --------------------------------------------------------------------------
+     884             : 
+     885             :   static ASMJIT_INLINE void writeU8(void* p, uint32_t x) noexcept {
+     886           0 :     static_cast<uint8_t*>(p)[0] = static_cast<uint8_t>(x & 0xFFU);
+     887           0 :   }
+     888             : 
+     889             :   static ASMJIT_INLINE void writeI8(void* p, int32_t x) noexcept {
+     890             :     static_cast<uint8_t*>(p)[0] = static_cast<uint8_t>(x & 0xFF);
+     891             :   }
+     892             : 
+     893             :   template<unsigned int Alignment>
+     894             :   static ASMJIT_INLINE void writeU16xLE(void* p, uint32_t x) noexcept {
+     895           0 :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     896             :     if (ASMJIT_ARCH_LE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) {
+     897           0 :       static_cast<uint16_t*>(p)[0] = static_cast<uint16_t>(x & 0xFFFFU);
+     898             :     }
+     899             :     else {
+     900             :       static_cast<uint8_t*>(p)[0] = static_cast<uint8_t>((x     ) & 0xFFU);
+     901             :       static_cast<uint8_t*>(p)[1] = static_cast<uint8_t>((x >> 8) & 0xFFU);
+     902             :     }
+     903             :   }
+     904             : 
+     905             :   template<unsigned int Alignment>
+     906             :   static ASMJIT_INLINE void writeU16xBE(void* p, uint32_t x) noexcept {
+     907             :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     908             :     if (ASMJIT_ARCH_BE && (ASMJIT_ARCH_UNALIGNED_16 || Alignment >= 2)) {
+     909             :       static_cast<uint16_t*>(p)[0] = static_cast<uint16_t>(x & 0xFFFFU);
+     910             :     }
+     911             :     else {
+     912             :       static_cast<uint8_t*>(p)[0] = static_cast<uint8_t>((x >> 8) & 0xFFU);
+     913             :       static_cast<uint8_t*>(p)[1] = static_cast<uint8_t>((x     ) & 0xFFU);
+     914             :     }
+     915             :   }
+     916             : 
+     917             :   template<unsigned int Alignment>
+     918             :   static ASMJIT_INLINE void writeU16x(void* p, uint32_t x) noexcept {
+     919             :     if (ASMJIT_ARCH_LE)
+     920             :       writeU16xLE<Alignment>(p, x);
+     921             :     else
+     922             :       writeU16xBE<Alignment>(p, x);
+     923             :   }
+     924             : 
+     925             :   template<unsigned int Alignment>
+     926             :   static ASMJIT_INLINE void writeI16xLE(void* p, int32_t x) noexcept {
+     927             :     writeU16xLE<Alignment>(p, static_cast<uint32_t>(x));
+     928             :   }
+     929             : 
+     930             :   template<unsigned int Alignment>
+     931             :   static ASMJIT_INLINE void writeI16xBE(void* p, int32_t x) noexcept {
+     932             :     writeU16xBE<Alignment>(p, static_cast<uint32_t>(x));
+     933             :   }
+     934             : 
+     935             :   template<unsigned int Alignment>
+     936             :   static ASMJIT_INLINE void writeI16x(void* p, int32_t x) noexcept {
+     937             :     writeU16x<Alignment>(p, static_cast<uint32_t>(x));
+     938             :   }
+     939             : 
+     940             :   static ASMJIT_INLINE void writeU16aLE(void* p, uint32_t x) noexcept { writeU16xLE<2>(p, x); }
+     941             :   static ASMJIT_INLINE void writeU16uLE(void* p, uint32_t x) noexcept { writeU16xLE<0>(p, x); }
+     942             : 
+     943             :   static ASMJIT_INLINE void writeU16aBE(void* p, uint32_t x) noexcept { writeU16xBE<2>(p, x); }
+     944             :   static ASMJIT_INLINE void writeU16uBE(void* p, uint32_t x) noexcept { writeU16xBE<0>(p, x); }
+     945             : 
+     946             :   static ASMJIT_INLINE void writeU16a(void* p, uint32_t x) noexcept { writeU16x<2>(p, x); }
+     947             :   static ASMJIT_INLINE void writeU16u(void* p, uint32_t x) noexcept { writeU16x<0>(p, x); }
+     948             : 
+     949             :   static ASMJIT_INLINE void writeI16aLE(void* p, int32_t x) noexcept { writeI16xLE<2>(p, x); }
+     950             :   static ASMJIT_INLINE void writeI16uLE(void* p, int32_t x) noexcept { writeI16xLE<0>(p, x); }
+     951             : 
+     952             :   static ASMJIT_INLINE void writeI16aBE(void* p, int32_t x) noexcept { writeI16xBE<2>(p, x); }
+     953             :   static ASMJIT_INLINE void writeI16uBE(void* p, int32_t x) noexcept { writeI16xBE<0>(p, x); }
+     954             : 
+     955             :   static ASMJIT_INLINE void writeI16a(void* p, int32_t x) noexcept { writeI16x<2>(p, x); }
+     956             :   static ASMJIT_INLINE void writeI16u(void* p, int32_t x) noexcept { writeI16x<0>(p, x); }
+     957             : 
+     958             :   template<unsigned int Alignment>
+     959             :   static ASMJIT_INLINE void writeU32xLE(void* p, uint32_t x) noexcept {
+     960        7700 :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     961             :     if (ASMJIT_ARCH_UNALIGNED_32 || Alignment >= 4) {
+     962        7700 :       static_cast<uint32_t*>(p)[0] = ASMJIT_ARCH_LE ? x : byteswap32(x);
+     963             :     }
+     964             :     else {
+     965             :       writeU16xLE<Alignment>(static_cast<uint8_t*>(p) + 0, x >> 16);
+     966             :       writeU16xLE<Alignment>(static_cast<uint8_t*>(p) + 2, x);
+     967             :     }
+     968             :   }
+     969             : 
+     970             :   template<unsigned int Alignment>
+     971             :   static ASMJIT_INLINE void writeU32xBE(void* p, uint32_t x) noexcept {
+     972             :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+     973             :     if (ASMJIT_ARCH_UNALIGNED_32 || Alignment >= 4) {
+     974             :       static_cast<uint32_t*>(p)[0] = ASMJIT_ARCH_BE ? x : byteswap32(x);
+     975             :     }
+     976             :     else {
+     977             :       writeU16xBE<Alignment>(static_cast<uint8_t*>(p) + 0, x);
+     978             :       writeU16xBE<Alignment>(static_cast<uint8_t*>(p) + 2, x >> 16);
+     979             :     }
+     980             :   }
+     981             : 
+     982             :   template<unsigned int Alignment>
+     983             :   static ASMJIT_INLINE void writeU32x(void* p, uint32_t x) noexcept {
+     984             :     if (ASMJIT_ARCH_LE)
+     985             :       writeU32xLE<Alignment>(p, x);
+     986             :     else
+     987             :       writeU32xBE<Alignment>(p, x);
+     988             :   }
+     989             : 
+     990             :   template<unsigned int Alignment>
+     991             :   static ASMJIT_INLINE void writeI32xLE(void* p, int32_t x) noexcept {
+     992             :     writeU32xLE<Alignment>(p, static_cast<uint32_t>(x));
+     993             :   }
+     994             : 
+     995             :   template<unsigned int Alignment>
+     996             :   static ASMJIT_INLINE void writeI32xBE(void* p, int32_t x) noexcept {
+     997             :     writeU32xBE<Alignment>(p, static_cast<uint32_t>(x));
+     998             :   }
+     999             : 
+    1000             :   template<unsigned int Alignment>
+    1001             :   static ASMJIT_INLINE void writeI32x(void* p, int32_t x) noexcept {
+    1002             :     writeU32x<Alignment>(p, static_cast<uint32_t>(x));
+    1003             :   }
+    1004             : 
+    1005             :   static ASMJIT_INLINE void writeU32aLE(void* p, uint32_t x) noexcept { writeU32xLE<4>(p, x); }
+    1006             :   static ASMJIT_INLINE void writeU32uLE(void* p, uint32_t x) noexcept { writeU32xLE<0>(p, x); }
+    1007             : 
+    1008             :   static ASMJIT_INLINE void writeU32aBE(void* p, uint32_t x) noexcept { writeU32xBE<4>(p, x); }
+    1009             :   static ASMJIT_INLINE void writeU32uBE(void* p, uint32_t x) noexcept { writeU32xBE<0>(p, x); }
+    1010             : 
+    1011             :   static ASMJIT_INLINE void writeU32a(void* p, uint32_t x) noexcept { writeU32x<4>(p, x); }
+    1012           0 :   static ASMJIT_INLINE void writeU32u(void* p, uint32_t x) noexcept { writeU32x<0>(p, x); }
+    1013             : 
+    1014             :   static ASMJIT_INLINE void writeI32aLE(void* p, int32_t x) noexcept { writeI32xLE<4>(p, x); }
+    1015             :   static ASMJIT_INLINE void writeI32uLE(void* p, int32_t x) noexcept { writeI32xLE<0>(p, x); }
+    1016             : 
+    1017             :   static ASMJIT_INLINE void writeI32aBE(void* p, int32_t x) noexcept { writeI32xBE<4>(p, x); }
+    1018             :   static ASMJIT_INLINE void writeI32uBE(void* p, int32_t x) noexcept { writeI32xBE<0>(p, x); }
+    1019             : 
+    1020             :   static ASMJIT_INLINE void writeI32a(void* p, int32_t x) noexcept { writeI32x<4>(p, x); }
+    1021           0 :   static ASMJIT_INLINE void writeI32u(void* p, int32_t x) noexcept { writeI32x<0>(p, x); }
+    1022             : 
+    1023             :   template<unsigned int Alignment>
+    1024             :   static ASMJIT_INLINE void writeU64xLE(void* p, uint64_t x) noexcept {
+    1025           0 :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+    1026             :     if (ASMJIT_ARCH_LE && (ASMJIT_ARCH_UNALIGNED_64 || Alignment >= 8)) {
+    1027           0 :       static_cast<uint64_t*>(p)[0] = x;
+    1028             :     }
+    1029             :     else {
+    1030             :       writeU32xLE<Alignment / 2U>(static_cast<uint8_t*>(p) + 0, static_cast<uint32_t>(x >> 32));
+    1031             :       writeU32xLE<Alignment / 2U>(static_cast<uint8_t*>(p) + 4, static_cast<uint32_t>(x & 0xFFFFFFFFU));
+    1032             :     }
+    1033             :   }
+    1034             : 
+    1035             :   template<unsigned int Alignment>
+    1036             :   static ASMJIT_INLINE void writeU64xBE(void* p, uint64_t x) noexcept {
+    1037             :     ASMJIT_ASSUME_ALIGNED(p, Alignment > 1 ? Alignment : 1U);
+    1038             :     if (ASMJIT_ARCH_BE && (ASMJIT_ARCH_UNALIGNED_64 || Alignment >= 8)) {
+    1039             :       static_cast<uint64_t*>(p)[0] = x;
+    1040             :     }
+    1041             :     else {
+    1042             :       writeU32xBE<Alignment / 2U>(static_cast<uint8_t*>(p) + 0, static_cast<uint32_t>(x & 0xFFFFFFFFU));
+    1043             :       writeU32xBE<Alignment / 2U>(static_cast<uint8_t*>(p) + 4, static_cast<uint32_t>(x >> 32));
+    1044             :     }
+    1045             :   }
+    1046             : 
+    1047             :   template<unsigned int Alignment>
+    1048             :   static ASMJIT_INLINE void writeU64x(void* p, uint64_t x) noexcept {
+    1049             :     if (ASMJIT_ARCH_LE)
+    1050             :       writeU64xLE<Alignment>(p, x);
+    1051             :     else
+    1052             :       writeU64xBE<Alignment>(p, x);
+    1053             :   }
+    1054             : 
+    1055             :   template<unsigned int Alignment>
+    1056             :   static ASMJIT_INLINE void writeI64xLE(void* p, int64_t x) noexcept {
+    1057             :     writeU64xLE<Alignment>(p, static_cast<uint64_t>(x));
+    1058             :   }
+    1059             : 
+    1060             :   template<unsigned int Alignment>
+    1061             :   static ASMJIT_INLINE void writeI64xBE(void* p, int64_t x) noexcept {
+    1062             :     writeU64xBE<Alignment>(p, static_cast<uint64_t>(x));
+    1063             :   }
+    1064             : 
+    1065             :   template<unsigned int Alignment>
+    1066             :   static ASMJIT_INLINE void writeI64x(void* p, int64_t x) noexcept {
+    1067             :     writeU64x<Alignment>(p, static_cast<uint64_t>(x));
+    1068             :   }
+    1069             : 
+    1070             :   static ASMJIT_INLINE void writeU64aLE(void* p, uint64_t x) noexcept { writeU64xLE<8>(p, x); }
+    1071             :   static ASMJIT_INLINE void writeU64uLE(void* p, uint64_t x) noexcept { writeU64xLE<0>(p, x); }
+    1072             : 
+    1073             :   static ASMJIT_INLINE void writeU64aBE(void* p, uint64_t x) noexcept { writeU64xBE<8>(p, x); }
+    1074             :   static ASMJIT_INLINE void writeU64uBE(void* p, uint64_t x) noexcept { writeU64xBE<0>(p, x); }
+    1075             : 
+    1076             :   static ASMJIT_INLINE void writeU64a(void* p, uint64_t x) noexcept { writeU64x<8>(p, x); }
+    1077           0 :   static ASMJIT_INLINE void writeU64u(void* p, uint64_t x) noexcept { writeU64x<0>(p, x); }
+    1078             : 
+    1079             :   static ASMJIT_INLINE void writeI64aLE(void* p, int64_t x) noexcept { writeI64xLE<8>(p, x); }
+    1080             :   static ASMJIT_INLINE void writeI64uLE(void* p, int64_t x) noexcept { writeI64xLE<0>(p, x); }
+    1081             : 
+    1082             :   static ASMJIT_INLINE void writeI64aBE(void* p, int64_t x) noexcept { writeI64xBE<8>(p, x); }
+    1083             :   static ASMJIT_INLINE void writeI64uBE(void* p, int64_t x) noexcept { writeI64xBE<0>(p, x); }
+    1084             : 
+    1085             :   static ASMJIT_INLINE void writeI64a(void* p, int64_t x) noexcept { writeI64x<8>(p, x); }
+    1086             :   static ASMJIT_INLINE void writeI64u(void* p, int64_t x) noexcept { writeI64x<0>(p, x); }
+    1087             : } // Utils namespace
+    1088             : 
+    1089             : // ============================================================================
+    1090             : // [asmjit::UInt64]
+    1091             : // ============================================================================
+    1092             : 
+    1093             : union UInt64 {
+    1094             :   // --------------------------------------------------------------------------
+    1095             :   // [Construction / Destruction]
+    1096             :   // --------------------------------------------------------------------------
+    1097             : 
+    1098             :   ASMJIT_INLINE UInt64 fromUInt64(uint64_t val) noexcept {
+    1099             :     UInt64 data;
+    1100             :     data.setUInt64(val);
+    1101             :     return data;
+    1102             :   }
+    1103             : 
+    1104             :   ASMJIT_INLINE UInt64 fromUInt64(const UInt64& val) noexcept {
+    1105             :     UInt64 data;
+    1106             :     data.setUInt64(val);
+    1107             :     return data;
+    1108             :   }
+    1109             : 
+    1110             :   // --------------------------------------------------------------------------
+    1111             :   // [Reset]
+    1112             :   // --------------------------------------------------------------------------
+    1113             : 
+    1114             :   ASMJIT_INLINE void reset() noexcept {
+    1115             :     if (ASMJIT_ARCH_64BIT) {
+    1116       80896 :       u64 = 0;
+    1117             :     }
+    1118             :     else {
+    1119             :       u32[0] = 0;
+    1120             :       u32[1] = 0;
+    1121             :     }
+    1122             :   }
+    1123             : 
+    1124             :   // --------------------------------------------------------------------------
+    1125             :   // [Accessors]
+    1126             :   // --------------------------------------------------------------------------
+    1127             : 
+    1128             :   ASMJIT_INLINE uint64_t getUInt64() const noexcept {
+    1129             :     return u64;
+    1130             :   }
+    1131             : 
+    1132             :   ASMJIT_INLINE UInt64& setUInt64(uint64_t val) noexcept {
+    1133             :     u64 = val;
+    1134             :     return *this;
+    1135             :   }
+    1136             : 
+    1137             :   ASMJIT_INLINE UInt64& setUInt64(const UInt64& val) noexcept {
+    1138             :     if (ASMJIT_ARCH_64BIT) {
+    1139             :       u64 = val.u64;
+    1140             :     }
+    1141             :     else {
+    1142             :       u32[0] = val.u32[0];
+    1143             :       u32[1] = val.u32[1];
+    1144             :     }
+    1145             :     return *this;
+    1146             :   }
+    1147             : 
+    1148             :   ASMJIT_INLINE UInt64& setPacked_2x32(uint32_t u0, uint32_t u1) noexcept {
+    1149             :     if (ASMJIT_ARCH_64BIT) {
+    1150       74716 :       u64 = Utils::pack64_2x32(u0, u1);
+    1151             :     }
+    1152             :     else {
+    1153             :       u32[0] = u0;
+    1154             :       u32[1] = u1;
+    1155             :     }
+    1156             :     return *this;
+    1157             :   }
+    1158             : 
+    1159             :   // --------------------------------------------------------------------------
+    1160             :   // [Add]
+    1161             :   // --------------------------------------------------------------------------
+    1162             : 
+    1163             :   ASMJIT_INLINE UInt64& add(uint64_t val) noexcept {
+    1164             :     u64 += val;
+    1165             :     return *this;
+    1166             :   }
+    1167             : 
+    1168             :   ASMJIT_INLINE UInt64& add(const UInt64& val) noexcept {
+    1169             :     if (ASMJIT_ARCH_64BIT) {
+    1170             :       u64 += val.u64;
+    1171             :     }
+    1172             :     else {
+    1173             :       u32[0] += val.u32[0];
+    1174             :       u32[1] += val.u32[1];
+    1175             :     }
+    1176             :     return *this;
+    1177             :   }
+    1178             : 
+    1179             :   // --------------------------------------------------------------------------
+    1180             :   // [Sub]
+    1181             :   // --------------------------------------------------------------------------
+    1182             : 
+    1183             :   ASMJIT_INLINE UInt64& sub(uint64_t val) noexcept {
+    1184             :     u64 -= val;
+    1185             :     return *this;
+    1186             :   }
+    1187             : 
+    1188             :   ASMJIT_INLINE UInt64& sub(const UInt64& val) noexcept {
+    1189             :     if (ASMJIT_ARCH_64BIT) {
+    1190             :       u64 -= val.u64;
+    1191             :     }
+    1192             :     else {
+    1193             :       u32[0] -= val.u32[0];
+    1194             :       u32[1] -= val.u32[1];
+    1195             :     }
+    1196             :     return *this;
+    1197             :   }
+    1198             : 
+    1199             :   // --------------------------------------------------------------------------
+    1200             :   // [And]
+    1201             :   // --------------------------------------------------------------------------
+    1202             : 
+    1203             :   ASMJIT_INLINE UInt64& and_(uint64_t val) noexcept {
+    1204             :     u64 &= val;
+    1205             :     return *this;
+    1206             :   }
+    1207             : 
+    1208             :   ASMJIT_INLINE UInt64& and_(const UInt64& val) noexcept {
+    1209             :     if (ASMJIT_ARCH_64BIT) {
+    1210             :       u64 &= val.u64;
+    1211             :     }
+    1212             :     else {
+    1213             :       u32[0] &= val.u32[0];
+    1214             :       u32[1] &= val.u32[1];
+    1215             :     }
+    1216             :     return *this;
+    1217             :   }
+    1218             : 
+    1219             :   // --------------------------------------------------------------------------
+    1220             :   // [AndNot]
+    1221             :   // --------------------------------------------------------------------------
+    1222             : 
+    1223             :   ASMJIT_INLINE UInt64& andNot(uint64_t val) noexcept {
+    1224             :     u64 &= ~val;
+    1225             :     return *this;
+    1226             :   }
+    1227             : 
+    1228             :   ASMJIT_INLINE UInt64& andNot(const UInt64& val) noexcept {
+    1229             :     if (ASMJIT_ARCH_64BIT) {
+    1230             :       u64 &= ~val.u64;
+    1231             :     }
+    1232             :     else {
+    1233             :       u32[0] &= ~val.u32[0];
+    1234             :       u32[1] &= ~val.u32[1];
+    1235             :     }
+    1236             :     return *this;
+    1237             :   }
+    1238             : 
+    1239             :   // --------------------------------------------------------------------------
+    1240             :   // [Or]
+    1241             :   // --------------------------------------------------------------------------
+    1242             : 
+    1243             :   ASMJIT_INLINE UInt64& or_(uint64_t val) noexcept {
+    1244             :     u64 |= val;
+    1245             :     return *this;
+    1246             :   }
+    1247             : 
+    1248             :   ASMJIT_INLINE UInt64& or_(const UInt64& val) noexcept {
+    1249             :     if (ASMJIT_ARCH_64BIT) {
+    1250       68160 :       u64 |= val.u64;
+    1251             :     }
+    1252             :     else {
+    1253             :       u32[0] |= val.u32[0];
+    1254             :       u32[1] |= val.u32[1];
+    1255             :     }
+    1256             :     return *this;
+    1257             :   }
+    1258             : 
+    1259             :   // --------------------------------------------------------------------------
+    1260             :   // [Xor]
+    1261             :   // --------------------------------------------------------------------------
+    1262             : 
+    1263             :   ASMJIT_INLINE UInt64& xor_(uint64_t val) noexcept {
+    1264             :     u64 ^= val;
+    1265             :     return *this;
+    1266             :   }
+    1267             : 
+    1268             :   ASMJIT_INLINE UInt64& xor_(const UInt64& val) noexcept {
+    1269             :     if (ASMJIT_ARCH_64BIT) {
+    1270             :       u64 ^= val.u64;
+    1271             :     }
+    1272             :     else {
+    1273             :       u32[0] ^= val.u32[0];
+    1274             :       u32[1] ^= val.u32[1];
+    1275             :     }
+    1276             :     return *this;
+    1277             :   }
+    1278             : 
+    1279             :   // --------------------------------------------------------------------------
+    1280             :   // [Eq]
+    1281             :   // --------------------------------------------------------------------------
+    1282             : 
+    1283             :   ASMJIT_INLINE bool isZero() const noexcept {
+    1284             :     if (ASMJIT_ARCH_64BIT)
+    1285             :       return u64 == 0;
+    1286             :     else
+    1287             :       return (u32[0] | u32[1]) == 0;
+    1288             :   }
+    1289             : 
+    1290             :   ASMJIT_INLINE bool isNonZero() const noexcept {
+    1291             :     if (ASMJIT_ARCH_64BIT)
+    1292             :       return u64 != 0;
+    1293             :     else
+    1294             :       return (u32[0] | u32[1]) != 0;
+    1295             :   }
+    1296             : 
+    1297             :   ASMJIT_INLINE bool eq(uint64_t val) const noexcept {
+    1298             :     return u64 == val;
+    1299             :   }
+    1300             : 
+    1301             :   ASMJIT_INLINE bool eq(const UInt64& val) const noexcept {
+    1302             :     if (ASMJIT_ARCH_64BIT)
+    1303             :       return u64 == val.u64;
+    1304             :     else
+    1305             :       return u32[0] == val.u32[0] && u32[1] == val.u32[1];
+    1306             :   }
+    1307             : 
+    1308             :   // --------------------------------------------------------------------------
+    1309             :   // [Operator Overload]
+    1310             :   // --------------------------------------------------------------------------
+    1311             : 
+    1312             :   ASMJIT_INLINE UInt64& operator+=(uint64_t val) noexcept { return add(val); }
+    1313             :   ASMJIT_INLINE UInt64& operator+=(const UInt64& val) noexcept { return add(val); }
+    1314             : 
+    1315             :   ASMJIT_INLINE UInt64& operator-=(uint64_t val) noexcept { return sub(val); }
+    1316             :   ASMJIT_INLINE UInt64& operator-=(const UInt64& val) noexcept { return sub(val); }
+    1317             : 
+    1318             :   ASMJIT_INLINE UInt64& operator&=(uint64_t val) noexcept { return and_(val); }
+    1319             :   ASMJIT_INLINE UInt64& operator&=(const UInt64& val) noexcept { return and_(val); }
+    1320             : 
+    1321             :   ASMJIT_INLINE UInt64& operator|=(uint64_t val) noexcept { return or_(val); }
+    1322             :   ASMJIT_INLINE UInt64& operator|=(const UInt64& val) noexcept { return or_(val); }
+    1323             : 
+    1324             :   ASMJIT_INLINE UInt64& operator^=(uint64_t val) noexcept { return xor_(val); }
+    1325             :   ASMJIT_INLINE UInt64& operator^=(const UInt64& val) noexcept { return xor_(val); }
+    1326             : 
+    1327             :   ASMJIT_INLINE bool operator==(uint64_t val) const noexcept { return eq(val); }
+    1328             :   ASMJIT_INLINE bool operator==(const UInt64& val) const noexcept { return eq(val); }
+    1329             : 
+    1330             :   ASMJIT_INLINE bool operator!=(uint64_t val) const noexcept { return !eq(val); }
+    1331             :   ASMJIT_INLINE bool operator!=(const UInt64& val) const noexcept { return !eq(val); }
+    1332             : 
+    1333             :   ASMJIT_INLINE bool operator<(uint64_t val) const noexcept { return u64 < val; }
+    1334             :   ASMJIT_INLINE bool operator<(const UInt64& val) const noexcept { return u64 < val.u64; }
+    1335             : 
+    1336             :   ASMJIT_INLINE bool operator<=(uint64_t val) const noexcept { return u64 <= val; }
+    1337             :   ASMJIT_INLINE bool operator<=(const UInt64& val) const noexcept { return u64 <= val.u64; }
+    1338             : 
+    1339             :   ASMJIT_INLINE bool operator>(uint64_t val) const noexcept { return u64 > val; }
+    1340             :   ASMJIT_INLINE bool operator>(const UInt64& val) const noexcept { return u64 > val.u64; }
+    1341             : 
+    1342             :   ASMJIT_INLINE bool operator>=(uint64_t val) const noexcept { return u64 >= val; }
+    1343             :   ASMJIT_INLINE bool operator>=(const UInt64& val) const noexcept { return u64 >= val.u64; }
+    1344             : 
+    1345             :   // --------------------------------------------------------------------------
+    1346             :   // [Members]
+    1347             :   // --------------------------------------------------------------------------
+    1348             : 
+    1349             :   int8_t   i8[8];                        //!< 8-bit signed integer (8x).
+    1350             :   uint8_t  u8[8];                        //!< 8-bit unsigned integer (8x).
+    1351             : 
+    1352             :   int16_t  i16[4];                       //!< 16-bit signed integer (4x).
+    1353             :   uint16_t u16[4];                       //!< 16-bit unsigned integer (4x).
+    1354             : 
+    1355             :   int32_t  i32[2];                       //!< 32-bit signed integer (2x).
+    1356             :   uint32_t u32[2];                       //!< 32-bit unsigned integer (2x).
+    1357             : 
+    1358             :   int64_t  i64;                          //!< 64-bit signed integer.
+    1359             :   uint64_t u64;                          //!< 64-bit unsigned integer.
+    1360             : 
+    1361             :   float    f32[2];                       //!< 32-bit floating point (2x).
+    1362             :   double   f64;                          //!< 64-bit floating point.
+    1363             : 
+    1364             : #if ASMJIT_ARCH_LE
+    1365             :   struct { float    f32Lo, f32Hi; };
+    1366             :   struct { int32_t  i32Lo, i32Hi; };
+    1367             :   struct { uint32_t u32Lo, u32Hi; };
+    1368             : #else
+    1369             :   struct { float    f32Hi, f32Lo; };
+    1370             :   struct { int32_t  i32Hi, i32Lo; };
+    1371             :   struct { uint32_t u32Hi, u32Lo; };
+    1372             : #endif // ASMJIT_ARCH_LE
+    1373             : };
+    1374             : 
+    1375             : //! \}
+    1376             : 
+    1377             : } // asmjit namespace
+    1378             : } // namespace PLMD
+    1379             : 
+    1380             : // [Api-End]
+    1381             : #include "./asmjit_apiend.h"
+    1382             : 
+    1383             : // [Guard]
+    1384             : #endif // _ASMJIT_BASE_UTILS_H
+    1385             : #pragma GCC diagnostic pop
+    1386             : #endif // __PLUMED_HAS_ASMJIT
+    1387             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/vmem.cpp.func-sort-c.html b/coverage-libs/asmjit/vmem.cpp.func-sort-c.html new file mode 100644 index 000000000000..9fb88f2698ff --- /dev/null +++ b/coverage-libs/asmjit/vmem.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/vmem.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - vmem.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:9631830.2 %
Date:2024-02-22 21:58:47Functions:81457.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7VMemMgr5resetEv0
_ZN4PLMD6asmjit7VMemMgr6shrinkEPvm0
_ZN4PLMD6asmjit7VMemMgr7releaseEPv0
_ZN4PLMD6asmjitL17vMemMgrRemoveNodeEPNS0_7VMemMgrEPNS1_7MemNodeE0
_ZN4PLMD6asmjitL20vMemMgrFindNodeByPtrEPNS0_7VMemMgrEPh0
_ZN4PLMD6asmjitL21vMemMgrAllocPermanentEPNS0_7VMemMgrEm0
_ZN4PLMD6asmjit7VMemMgr5allocEmj1948
_ZN4PLMD6asmjitL17vMemMgrCreateNodeEPNS0_7VMemMgrEmm1948
_ZN4PLMD6asmjitL17vMemMgrInsertNodeEPNS0_7VMemMgrEPNS1_7MemNodeE1948
_ZN4PLMD6asmjitL20vMemMgrAllocFreeableEPNS0_7VMemMgrEm1948
_ZN4PLMD6asmjit7VMemMgrC2Ev1976
_ZN4PLMD6asmjit7VMemMgrD2Ev1976
_ZN4PLMD6asmjitL12vMemMgrResetEPNS0_7VMemMgrEb1976
_ZN4PLMD6asmjitL8_SetBitsEPmmm3896
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/vmem.cpp.func.html b/coverage-libs/asmjit/vmem.cpp.func.html new file mode 100644 index 000000000000..13bcff6cf6d4 --- /dev/null +++ b/coverage-libs/asmjit/vmem.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/vmem.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - vmem.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:9631830.2 %
Date:2024-02-22 21:58:47Functions:81457.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7VMemMgr5allocEmj1948
_ZN4PLMD6asmjit7VMemMgr5resetEv0
_ZN4PLMD6asmjit7VMemMgr6shrinkEPvm0
_ZN4PLMD6asmjit7VMemMgr7releaseEPv0
_ZN4PLMD6asmjit7VMemMgrC2Ev1976
_ZN4PLMD6asmjit7VMemMgrD2Ev1976
_ZN4PLMD6asmjitL12vMemMgrResetEPNS0_7VMemMgrEb1976
_ZN4PLMD6asmjitL17vMemMgrCreateNodeEPNS0_7VMemMgrEmm1948
_ZN4PLMD6asmjitL17vMemMgrInsertNodeEPNS0_7VMemMgrEPNS1_7MemNodeE1948
_ZN4PLMD6asmjitL17vMemMgrRemoveNodeEPNS0_7VMemMgrEPNS1_7MemNodeE0
_ZN4PLMD6asmjitL20vMemMgrAllocFreeableEPNS0_7VMemMgrEm1948
_ZN4PLMD6asmjitL20vMemMgrFindNodeByPtrEPNS0_7VMemMgrEPh0
_ZN4PLMD6asmjitL21vMemMgrAllocPermanentEPNS0_7VMemMgrEm0
_ZN4PLMD6asmjitL8_SetBitsEPmmm3896
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/vmem.cpp.gcov.html b/coverage-libs/asmjit/vmem.cpp.gcov.html new file mode 100644 index 000000000000..885971a765d1 --- /dev/null +++ b/coverage-libs/asmjit/vmem.cpp.gcov.html @@ -0,0 +1,1180 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/vmem.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - vmem.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:9631830.2 %
Date:2024-02-22 21:58:47Functions:81457.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./osutils.h"
+      34             : #include "./utils.h"
+      35             : #include "./vmem.h"
+      36             : 
+      37             : // [Api-Begin]
+      38             : #include "./asmjit_apibegin.h"
+      39             : 
+      40             : // This file contains implementation of virtual memory management for AsmJit
+      41             : // library. There are several goals I decided to write implementation myself:
+      42             : //
+      43             : // - Granularity of allocated blocks is different than granularity for a typical
+      44             : //   C malloc. It is at least 64-bytes so CodeEmitter can guarantee the alignment
+      45             : //   up to 64 bytes, which is the size of a cache-line and it's also required by
+      46             : //   AVX-512 aligned loads and stores. Alignment requirements can grow in the future,
+      47             : //   but at the moment 64 bytes is safe (we may jump to 128 bytes if necessary or
+      48             : //   make it configurable).
+      49             : //
+      50             : // - Keep memory manager information outside of the allocated virtual memory
+      51             : //   pages, because these pages allow machine code execution and there should
+      52             : //   be not data required to keep track of these blocks. Another reason is that
+      53             : //   some environments (i.e. iOS) allow to generate and run JIT code, but this
+      54             : //   code has to be set to [Executable, but not Writable].
+      55             : //
+      56             : // - Keep implementation simple and easy to follow.
+      57             : //
+      58             : // Implementation is based on bit arrays and binary trees. Bit arrays contain
+      59             : // information related to allocated and unused blocks of memory. The size of
+      60             : // a block is described by `MemNode::density`. Count of blocks is stored in
+      61             : // `MemNode::blocks`. For example if density is 64 and count of blocks is 20,
+      62             : // memory node contains 64*20 bytes of memory and the smallest possible allocation
+      63             : // (and also alignment) is 64 bytes. So density is also related to memory
+      64             : // alignment. Binary trees (RB) are used to enable fast lookup into all addresses
+      65             : // allocated by memory manager instance. This is used mainly by `VMemPrivate::release()`.
+      66             : //
+      67             : // Bit array looks like this (empty = unused, X = used) - Size of block 64:
+      68             : //
+      69             : //   -------------------------------------------------------------------------
+      70             : //   | |X|X| | | | | |X|X|X|X|X|X| | | | | | | | | | | | |X| | | | |X|X|X| | |
+      71             : //   -------------------------------------------------------------------------
+      72             : //                               (Maximum continuous block)
+      73             : //
+      74             : // These bits show that there are 12 allocated blocks (X) of 64 bytes, so total
+      75             : // size allocated is 768 bytes. Maximum count of continuous memory is 12 * 64.
+      76             : 
+      77             : namespace PLMD {
+      78             : namespace asmjit {
+      79             : 
+      80             : // ============================================================================
+      81             : // [asmjit::VMemMgr - BitOps]
+      82             : // ============================================================================
+      83             : 
+      84             : #define M_DIV(x, y) ((x) / (y))
+      85             : #define M_MOD(x, y) ((x) % (y))
+      86             : 
+      87             : //! \internal
+      88             : enum { kBitsPerEntity = (sizeof(size_t) * 8) };
+      89             : 
+      90             : //! \internal
+      91             : //!
+      92             : //! Set `len` bits in `buf` starting at `index` bit index.
+      93        3896 : static void _SetBits(size_t* buf, size_t index, size_t len) noexcept {
+      94        3896 :   if (len == 0)
+      95             :     return;
+      96             : 
+      97        3152 :   size_t i = index / kBitsPerEntity; // size_t[]
+      98        3152 :   size_t j = index % kBitsPerEntity; // size_t[][] bit index
+      99             : 
+     100             :   // How many bytes process in the first group.
+     101        3152 :   size_t c = kBitsPerEntity - j;
+     102             :   if (c > len)
+     103             :     c = len;
+     104             : 
+     105             :   // Offset.
+     106        3152 :   buf += i;
+     107             : 
+     108        3152 :   *buf++ |= ((~(size_t)0) >> (kBitsPerEntity - c)) << j;
+     109        3152 :   len -= c;
+     110             : 
+     111        3152 :   while (len >= kBitsPerEntity) {
+     112           0 :     *buf++ = ~(size_t)0;
+     113           0 :     len -= kBitsPerEntity;
+     114             :   }
+     115             : 
+     116        3152 :   if (len)
+     117           0 :     *buf |= ((~(size_t)0) >> (kBitsPerEntity - len));
+     118             : }
+     119             : 
+     120             : // ============================================================================
+     121             : // [asmjit::VMemMgr::TypeDefs]
+     122             : // ============================================================================
+     123             : 
+     124             : typedef VMemMgr::RbNode RbNode;
+     125             : typedef VMemMgr::MemNode MemNode;
+     126             : typedef VMemMgr::PermanentNode PermanentNode;
+     127             : 
+     128             : // ============================================================================
+     129             : // [asmjit::VMemMgr::RbNode]
+     130             : // ============================================================================
+     131             : 
+     132             : //! \internal
+     133             : //!
+     134             : //! Base red-black tree node.
+     135             : struct VMemMgr::RbNode {
+     136             :   // Implementation is based on article by Julienne Walker (Public Domain),
+     137             :   // including C code and original comments. Thanks for the excellent article.
+     138             : 
+     139             :   RbNode* node[2];                       //!< Left[0] and right[1] nodes.
+     140             :   uint8_t* mem;                          //!< Virtual memory address.
+     141             :   uint32_t red;                          //!< Node color (red vs. black).
+     142             : };
+     143             : 
+     144             : //! \internal
+     145             : //!
+     146             : //! Get if the node is red (nullptr or node with red flag).
+     147             : static ASMJIT_INLINE bool rbIsRed(RbNode* node) noexcept {
+     148           0 :   return node && node->red;
+     149             : }
+     150             : 
+     151             : //! \internal
+     152             : //!
+     153             : //! Check whether the RB tree is valid.
+     154             : static int rbAssert(RbNode* root) noexcept {
+     155             :   if (!root) return 1;
+     156             : 
+     157             :   RbNode* ln = root->node[0];
+     158             :   RbNode* rn = root->node[1];
+     159             : 
+     160             :   // Red violation.
+     161             :   ASMJIT_ASSERT(!(rbIsRed(root) && (rbIsRed(ln) || rbIsRed(rn))));
+     162             : 
+     163             :   int lh = rbAssert(ln);
+     164             :   int rh = rbAssert(rn);
+     165             : 
+     166             :   // Invalid btree.
+     167             :   ASMJIT_ASSERT(ln == nullptr || ln->mem < root->mem);
+     168             :   ASMJIT_ASSERT(rn == nullptr || rn->mem > root->mem);
+     169             : 
+     170             :   // Black violation.
+     171             :   ASMJIT_ASSERT(!(lh != 0 && rh != 0 && lh != rh));
+     172             : 
+     173             :   // Only count black links.
+     174             :   if (lh != 0 && rh != 0)
+     175             :     return rbIsRed(root) ? lh : lh + 1;
+     176             :   else
+     177             :     return 0;
+     178             : }
+     179             : 
+     180             : //! \internal
+     181             : //!
+     182             : //! Single rotation.
+     183             : static ASMJIT_INLINE RbNode* rbRotateSingle(RbNode* root, int dir) noexcept {
+     184           0 :   RbNode* save = root->node[!dir];
+     185             : 
+     186           0 :   root->node[!dir] = save->node[dir];
+     187           0 :   save->node[dir] = root;
+     188             : 
+     189           0 :   root->red = 1;
+     190           0 :   save->red = 0;
+     191             : 
+     192             :   return save;
+     193             : }
+     194             : 
+     195             : //! \internal
+     196             : //!
+     197             : //! Double rotation.
+     198             : static ASMJIT_INLINE RbNode* rbRotateDouble(RbNode* root, int dir) noexcept {
+     199           0 :   root->node[!dir] = rbRotateSingle(root->node[!dir], !dir);
+     200             :   return rbRotateSingle(root, dir);
+     201             : }
+     202             : 
+     203             : // ============================================================================
+     204             : // [asmjit::VMemMgr::MemNode]
+     205             : // ============================================================================
+     206             : 
+     207             : struct VMemMgr::MemNode : public RbNode {
+     208             :   ASMJIT_INLINE void init(MemNode* other) noexcept {
+     209           0 :     mem = other->mem;
+     210             : 
+     211           0 :     size = other->size;
+     212           0 :     used = other->used;
+     213           0 :     blocks = other->blocks;
+     214           0 :     density = other->density;
+     215           0 :     largestBlock = other->largestBlock;
+     216             : 
+     217           0 :     baUsed = other->baUsed;
+     218           0 :     baCont = other->baCont;
+     219           0 :   }
+     220             : 
+     221             :   // Get available space.
+     222           0 :   ASMJIT_INLINE size_t getAvailable() const noexcept { return size - used; }
+     223             : 
+     224             :   MemNode* prev;         // Prev node in list.
+     225             :   MemNode* next;         // Next node in list.
+     226             : 
+     227             :   size_t size;           // How many bytes contain this node.
+     228             :   size_t used;           // How many bytes are used in this node.
+     229             :   size_t blocks;         // How many blocks are here.
+     230             :   size_t density;        // Minimum count of allocated bytes in this node (also alignment).
+     231             :   size_t largestBlock;   // Contains largest block that can be allocated.
+     232             : 
+     233             :   size_t* baUsed;        // Contains bits about used blocks       (0 = unused, 1 = used).
+     234             :   size_t* baCont;        // Contains bits about continuous blocks (0 = stop  , 1 = continue).
+     235             : };
+     236             : 
+     237             : // ============================================================================
+     238             : // [asmjit::VMemMgr::PermanentNode]
+     239             : // ============================================================================
+     240             : 
+     241             : //! \internal
+     242             : //!
+     243             : //! Permanent node.
+     244             : struct VMemMgr::PermanentNode {
+     245             :   //! Get available space.
+     246           0 :   ASMJIT_INLINE size_t getAvailable() const noexcept { return size - used; }
+     247             : 
+     248             :   PermanentNode* prev;   // Pointer to prev chunk or nullptr.
+     249             :   uint8_t* mem;          // Base pointer (virtual memory address).
+     250             :   size_t size;           // Count of bytes allocated.
+     251             :   size_t used;           // Count of bytes used.
+     252             : };
+     253             : 
+     254             : // ============================================================================
+     255             : // [asmjit::VMemMgr - Private]
+     256             : // ============================================================================
+     257             : 
+     258             : //! \internal
+     259             : //!
+     260             : //! Helper to avoid `#ifdef`s in the code.
+     261             : ASMJIT_INLINE uint8_t* vMemMgrAllocVMem(VMemMgr* self, size_t size, size_t* vSize) noexcept {
+     262             :   uint32_t flags = OSUtils::kVMWritable | OSUtils::kVMExecutable;
+     263             : #if !ASMJIT_OS_WINDOWS
+     264        1948 :   return static_cast<uint8_t*>(OSUtils::allocVirtualMemory(size, vSize, flags));
+     265             : #else
+     266             :   return static_cast<uint8_t*>(OSUtils::allocProcessMemory(self->_hProcess, size, vSize, flags));
+     267             : #endif
+     268             : }
+     269             : 
+     270             : //! \internal
+     271             : //!
+     272             : //! Helper to avoid `#ifdef`s in the code.
+     273             : ASMJIT_INLINE Error vMemMgrReleaseVMem(VMemMgr* self, void* p, size_t vSize) noexcept {
+     274             : #if !ASMJIT_OS_WINDOWS
+     275           0 :   return OSUtils::releaseVirtualMemory(p, vSize);
+     276             : #else
+     277             :   return OSUtils::releaseProcessMemory(self->_hProcess, p, vSize);
+     278             : #endif
+     279             : }
+     280             : 
+     281             : //! \internal
+     282             : //!
+     283             : //! Check whether the Red-Black tree is valid.
+     284             : static bool vMemMgrCheckTree(VMemMgr* self) noexcept {
+     285             :   return rbAssert(self->_root) > 0;
+     286             : }
+     287             : 
+     288             : //! \internal
+     289             : //!
+     290             : //! Alloc virtual memory including a heap memory needed for `MemNode` data.
+     291             : //!
+     292             : //! Returns set-up `MemNode*` or nullptr if allocation failed.
+     293        1948 : static MemNode* vMemMgrCreateNode(VMemMgr* self, size_t size, size_t density) noexcept {
+     294             :   size_t vSize;
+     295             :   uint8_t* vmem = vMemMgrAllocVMem(self, size, &vSize);
+     296        1948 :   if (!vmem) return nullptr;
+     297             : 
+     298        1948 :   size_t blocks = (vSize / density);
+     299        1948 :   size_t bsize = (((blocks + 7) >> 3) + sizeof(size_t) - 1) & ~(size_t)(sizeof(size_t) - 1);
+     300             : 
+     301             :   MemNode* node = static_cast<MemNode*>(Internal::allocMemory(sizeof(MemNode)));
+     302        1948 :   uint8_t* data = static_cast<uint8_t*>(Internal::allocMemory(bsize * 2));
+     303             : 
+     304             :   // Out of memory.
+     305        1948 :   if (!node || !data) {
+     306             :     vMemMgrReleaseVMem(self, vmem, vSize);
+     307           0 :     if (node) Internal::releaseMemory(node);
+     308           0 :     if (data) Internal::releaseMemory(data);
+     309           0 :     return nullptr;
+     310             :   }
+     311             : 
+     312             :   // Initialize RbNode data.
+     313        1948 :   node->node[0] = nullptr;
+     314        1948 :   node->node[1] = nullptr;
+     315        1948 :   node->mem = vmem;
+     316        1948 :   node->red = 1;
+     317             : 
+     318             :   // Initialize MemNode data.
+     319        1948 :   node->prev = nullptr;
+     320        1948 :   node->next = nullptr;
+     321             : 
+     322        1948 :   node->size = vSize;
+     323        1948 :   node->used = 0;
+     324        1948 :   node->blocks = blocks;
+     325        1948 :   node->density = density;
+     326        1948 :   node->largestBlock = vSize;
+     327             : 
+     328             :   ::memset(data, 0, bsize * 2);
+     329        1948 :   node->baUsed = reinterpret_cast<size_t*>(data);
+     330        1948 :   node->baCont = reinterpret_cast<size_t*>(data + bsize);
+     331             : 
+     332        1948 :   return node;
+     333             : }
+     334             : 
+     335        1948 : static void vMemMgrInsertNode(VMemMgr* self, MemNode* node) noexcept {
+     336        1948 :   if (!self->_root) {
+     337             :     // Empty tree case.
+     338        1948 :     self->_root = node;
+     339             :   }
+     340             :   else {
+     341             :     // False tree root.
+     342           0 :     RbNode head = { { nullptr, nullptr }, 0, 0 };
+     343             : 
+     344             :     // Grandparent & parent.
+     345             :     RbNode* g = nullptr;
+     346             :     RbNode* t = &head;
+     347             : 
+     348             :     // Iterator & parent.
+     349             :     RbNode* p = nullptr;
+     350           0 :     RbNode* q = t->node[1] = self->_root;
+     351             : 
+     352             :     int dir = 0;
+     353             :     int last = 0; // Not needed to initialize, but makes some tools happy.
+     354             : 
+     355             :     // Search down the tree.
+     356             :     for (;;) {
+     357           0 :       if (!q) {
+     358             :         // Insert new node at the bottom.
+     359             :         q = node;
+     360           0 :         p->node[dir] = node;
+     361             :       }
+     362           0 :       else if (rbIsRed(q->node[0]) && rbIsRed(q->node[1])) {
+     363             :         // Color flip.
+     364           0 :         q->red = 1;
+     365           0 :         q->node[0]->red = 0;
+     366           0 :         q->node[1]->red = 0;
+     367             :       }
+     368             : 
+     369             :       // Fix red violation.
+     370             :       if (rbIsRed(q) && rbIsRed(p)) {
+     371           0 :         int dir2 = t->node[1] == g;
+     372           0 :         t->node[dir2] = q == p->node[last] ? rbRotateSingle(g, !last) : rbRotateDouble(g, !last);
+     373             :       }
+     374             : 
+     375             :       // Stop if found.
+     376           0 :       if (q == node)
+     377             :         break;
+     378             : 
+     379             :       last = dir;
+     380           0 :       dir = q->mem < node->mem;
+     381             : 
+     382             :       // Update helpers.
+     383           0 :       if (g) t = g;
+     384             : 
+     385             :       g = p;
+     386             :       p = q;
+     387           0 :       q = q->node[dir];
+     388           0 :     }
+     389             : 
+     390             :     // Update root.
+     391           0 :     self->_root = static_cast<MemNode*>(head.node[1]);
+     392             :   }
+     393             : 
+     394             :   // Make root black.
+     395        1948 :   self->_root->red = 0;
+     396             : 
+     397             :   // Link with others.
+     398        1948 :   node->prev = self->_last;
+     399             : 
+     400        1948 :   if (!self->_first) {
+     401        1948 :     self->_first = node;
+     402        1948 :     self->_last = node;
+     403        1948 :     self->_optimal = node;
+     404             :   }
+     405             :   else {
+     406             :     node->prev = self->_last;
+     407           0 :     self->_last->next = node;
+     408           0 :     self->_last = node;
+     409             :   }
+     410        1948 : }
+     411             : 
+     412             : //! \internal
+     413             : //!
+     414             : //! Remove node from Red-Black tree.
+     415             : //!
+     416             : //! Returns node that should be freed, but it doesn't have to be necessarily
+     417             : //! the `node` passed.
+     418           0 : static MemNode* vMemMgrRemoveNode(VMemMgr* self, MemNode* node) noexcept {
+     419             :   // False tree root.
+     420           0 :   RbNode head = { { nullptr, nullptr }, 0, 0 };
+     421             : 
+     422             :   // Helpers.
+     423             :   RbNode* q = &head;
+     424             :   RbNode* p = nullptr;
+     425             :   RbNode* g = nullptr;
+     426             : 
+     427             :   // Found item.
+     428             :   RbNode* f = nullptr;
+     429             :   int dir = 1;
+     430             : 
+     431             :   // Set up.
+     432           0 :   q->node[1] = self->_root;
+     433             : 
+     434             :   // Search and push a red down.
+     435           0 :   while (q->node[dir]) {
+     436             :     int last = dir;
+     437             : 
+     438             :     // Update helpers.
+     439             :     g = p;
+     440             :     p = q;
+     441             :     q = q->node[dir];
+     442           0 :     dir = q->mem < node->mem;
+     443             : 
+     444             :     // Save found node.
+     445           0 :     if (q == node)
+     446             :       f = q;
+     447             : 
+     448             :     // Push the red node down.
+     449           0 :     if (!rbIsRed(q) && !rbIsRed(q->node[dir])) {
+     450           0 :       if (rbIsRed(q->node[!dir])) {
+     451           0 :         p = p->node[last] = rbRotateSingle(q, dir);
+     452             :       }
+     453             :       else if (!rbIsRed(q->node[!dir])) {
+     454           0 :         RbNode* s = p->node[!last];
+     455             : 
+     456           0 :         if (s) {
+     457           0 :           if (!rbIsRed(s->node[!last]) && !rbIsRed(s->node[last])) {
+     458             :             // Color flip.
+     459           0 :             p->red = 0;
+     460           0 :             s->red = 1;
+     461           0 :             q->red = 1;
+     462             :           }
+     463             :           else {
+     464           0 :             int dir2 = g->node[1] == p;
+     465             : 
+     466           0 :             if (rbIsRed(s->node[last]))
+     467           0 :               g->node[dir2] = rbRotateDouble(p, last);
+     468             :             else if (rbIsRed(s->node[!last]))
+     469           0 :               g->node[dir2] = rbRotateSingle(p, last);
+     470             : 
+     471             :             // Ensure correct coloring.
+     472           0 :             q->red = g->node[dir2]->red = 1;
+     473           0 :             g->node[dir2]->node[0]->red = 0;
+     474           0 :             g->node[dir2]->node[1]->red = 0;
+     475             :           }
+     476             :         }
+     477             :       }
+     478             :     }
+     479             :   }
+     480             : 
+     481             :   // Replace and remove.
+     482             :   ASMJIT_ASSERT(f != nullptr);
+     483             :   ASMJIT_ASSERT(f != &head);
+     484             :   ASMJIT_ASSERT(q != &head);
+     485             : 
+     486           0 :   if (f != q) {
+     487             :     ASMJIT_ASSERT(f != &head);
+     488             :     static_cast<MemNode*>(f)->init(static_cast<MemNode*>(q));
+     489             :   }
+     490             : 
+     491           0 :   p->node[p->node[1] == q] = q->node[q->node[0] == nullptr];
+     492             : 
+     493             :   // Update root and make it black.
+     494           0 :   self->_root = static_cast<MemNode*>(head.node[1]);
+     495           0 :   if (self->_root) self->_root->red = 0;
+     496             : 
+     497             :   // Unlink.
+     498           0 :   MemNode* next = static_cast<MemNode*>(q)->next;
+     499           0 :   MemNode* prev = static_cast<MemNode*>(q)->prev;
+     500             : 
+     501           0 :   if (prev)
+     502           0 :     prev->next = next;
+     503             :   else
+     504           0 :     self->_first = next;
+     505             : 
+     506           0 :   if (next)
+     507           0 :     next->prev = prev;
+     508             :   else
+     509           0 :     self->_last  = prev;
+     510             : 
+     511           0 :   if (self->_optimal == q)
+     512           0 :     self->_optimal = prev ? prev : next;
+     513             : 
+     514           0 :   return static_cast<MemNode*>(q);
+     515             : }
+     516             : 
+     517           0 : static MemNode* vMemMgrFindNodeByPtr(VMemMgr* self, uint8_t* mem) noexcept {
+     518           0 :   MemNode* node = self->_root;
+     519           0 :   while (node) {
+     520           0 :     uint8_t* nodeMem = node->mem;
+     521             : 
+     522             :     // Go left.
+     523           0 :     if (mem < nodeMem) {
+     524           0 :       node = static_cast<MemNode*>(node->node[0]);
+     525           0 :       continue;
+     526             :     }
+     527             : 
+     528             :     // Go right.
+     529           0 :     uint8_t* nodeEnd = nodeMem + node->size;
+     530           0 :     if (mem >= nodeEnd) {
+     531           0 :       node = static_cast<MemNode*>(node->node[1]);
+     532           0 :       continue;
+     533             :     }
+     534             : 
+     535             :     // Match.
+     536             :     break;
+     537             :   }
+     538           0 :   return node;
+     539             : }
+     540             : 
+     541           0 : static void* vMemMgrAllocPermanent(VMemMgr* self, size_t vSize) noexcept {
+     542             :   static const size_t permanentAlignment = 32;
+     543             :   static const size_t permanentNodeSize  = 32768;
+     544             : 
+     545             :   vSize = Utils::alignTo<size_t>(vSize, permanentAlignment);
+     546             : 
+     547             :   AutoLock locked(self->_lock);
+     548           0 :   PermanentNode* node = self->_permanent;
+     549             : 
+     550             :   // Try to find space in allocated chunks.
+     551           0 :   while (node && vSize > node->getAvailable())
+     552           0 :     node = node->prev;
+     553             : 
+     554             :   // Or allocate new node.
+     555           0 :   if (!node) {
+     556             :     size_t nodeSize = permanentNodeSize;
+     557             :     if (nodeSize < vSize) nodeSize = vSize;
+     558             : 
+     559             :     node = static_cast<PermanentNode*>(Internal::allocMemory(sizeof(PermanentNode)));
+     560           0 :     if (!node) return nullptr;
+     561             : 
+     562           0 :     node->mem = vMemMgrAllocVMem(self, nodeSize, &node->size);
+     563           0 :     if (!node->mem) {
+     564             :       Internal::releaseMemory(node);
+     565           0 :       return nullptr;
+     566             :     }
+     567             : 
+     568           0 :     node->used = 0;
+     569           0 :     node->prev = self->_permanent;
+     570           0 :     self->_permanent = node;
+     571             :   }
+     572             : 
+     573             :   // Finally, copy function code to our space we reserved for.
+     574           0 :   uint8_t* result = node->mem + node->used;
+     575             : 
+     576             :   // Update Statistics.
+     577           0 :   node->used += vSize;
+     578           0 :   self->_usedBytes += vSize;
+     579             : 
+     580             :   // Code can be null to only reserve space for code.
+     581           0 :   return static_cast<void*>(result);
+     582             : }
+     583             : 
+     584        1948 : static void* vMemMgrAllocFreeable(VMemMgr* self, size_t vSize) noexcept {
+     585             :   // Current index.
+     586             :   size_t i;
+     587             : 
+     588             :   // How many we need to be freed.
+     589             :   size_t need;
+     590             :   size_t minVSize;
+     591             : 
+     592             :   // Align to 32 bytes by default.
+     593             :   vSize = Utils::alignTo<size_t>(vSize, 32);
+     594        1948 :   if (vSize == 0)
+     595             :     return nullptr;
+     596             : 
+     597             :   AutoLock locked(self->_lock);
+     598        1948 :   MemNode* node = self->_optimal;
+     599        1948 :   minVSize = self->_blockSize;
+     600             : 
+     601             :   // Try to find memory block in existing nodes.
+     602        1948 :   while (node) {
+     603             :     // Skip this node?
+     604           0 :     if ((node->getAvailable() < vSize) || (node->largestBlock < vSize && node->largestBlock != 0)) {
+     605           0 :       MemNode* next = node->next;
+     606             : 
+     607           0 :       if (node->getAvailable() < minVSize && node == self->_optimal && next)
+     608           0 :         self->_optimal = next;
+     609             : 
+     610             :       node = next;
+     611           0 :       continue;
+     612           0 :     }
+     613             : 
+     614           0 :     size_t* up = node->baUsed;     // Current ubits address.
+     615             :     size_t ubits;                  // Current ubits[0] value.
+     616             :     size_t bit;                    // Current bit mask.
+     617           0 :     size_t blocks = node->blocks;  // Count of blocks in node.
+     618             :     size_t cont = 0;               // How many bits are currently freed in find loop.
+     619             :     size_t maxCont = 0;            // Largest continuous block (bits count).
+     620             :     size_t j;
+     621             : 
+     622           0 :     need = M_DIV((vSize + node->density - 1), node->density);
+     623             :     i = 0;
+     624             : 
+     625             :     // Try to find node that is large enough.
+     626           0 :     while (i < blocks) {
+     627           0 :       ubits = *up++;
+     628             : 
+     629             :       // Fast skip used blocks.
+     630           0 :       if (ubits == ~(size_t)0) {
+     631             :         if (cont > maxCont)
+     632             :           maxCont = cont;
+     633             :         cont = 0;
+     634             : 
+     635           0 :         i += kBitsPerEntity;
+     636           0 :         continue;
+     637             :       }
+     638             : 
+     639             :       size_t max = kBitsPerEntity;
+     640           0 :       if (i + max > blocks)
+     641           0 :         max = blocks - i;
+     642             : 
+     643           0 :       for (j = 0, bit = 1; j < max; bit <<= 1) {
+     644           0 :         j++;
+     645           0 :         if ((ubits & bit) == 0) {
+     646           0 :           if (++cont == need) {
+     647           0 :             i += j;
+     648           0 :             i -= cont;
+     649           0 :             goto L_Found;
+     650             :           }
+     651             : 
+     652           0 :           continue;
+     653             :         }
+     654             : 
+     655             :         if (cont > maxCont) maxCont = cont;
+     656             :         cont = 0;
+     657             :       }
+     658             : 
+     659             :       i += kBitsPerEntity;
+     660             :     }
+     661             : 
+     662             :     // Because we traversed the entire node, we can set largest node size that
+     663             :     // will be used to cache next traversing.
+     664           0 :     node->largestBlock = maxCont * node->density;
+     665             : 
+     666           0 :     node = node->next;
+     667             :   }
+     668             : 
+     669             :   // If we are here, we failed to find existing memory block and we must
+     670             :   // allocate a new one.
+     671             :   {
+     672        1948 :     size_t blockSize = self->_blockSize;
+     673             :     if (blockSize < vSize) blockSize = vSize;
+     674             : 
+     675        1948 :     node = vMemMgrCreateNode(self, blockSize, self->_blockDensity);
+     676        1948 :     if (!node) return nullptr;
+     677             : 
+     678             :     // Update binary tree.
+     679        1948 :     vMemMgrInsertNode(self, node);
+     680             :     ASMJIT_ASSERT(vMemMgrCheckTree(self));
+     681             : 
+     682             :     // Alloc first node at start.
+     683             :     i = 0;
+     684        1948 :     need = (vSize + node->density - 1) / node->density;
+     685             : 
+     686             :     // Update statistics.
+     687        1948 :     self->_allocatedBytes += node->size;
+     688             :   }
+     689             : 
+     690        1948 : L_Found:
+     691             :   // Update bits.
+     692        1948 :   _SetBits(node->baUsed, i, need);
+     693        1948 :   _SetBits(node->baCont, i, need - 1);
+     694             : 
+     695             :   // Update statistics.
+     696             :   {
+     697        1948 :     size_t u = need * node->density;
+     698        1948 :     node->used += u;
+     699        1948 :     node->largestBlock = 0;
+     700        1948 :     self->_usedBytes += u;
+     701             :   }
+     702             : 
+     703             :   // And return pointer to allocated memory.
+     704        1948 :   uint8_t* result = node->mem + i * node->density;
+     705             :   ASMJIT_ASSERT(result >= node->mem && result <= node->mem + node->size - vSize);
+     706        1948 :   return result;
+     707             : }
+     708             : 
+     709             : //! \internal
+     710             : //!
+     711             : //! Reset the whole `VMemMgr` instance, freeing all heap memory allocated an
+     712             : //! virtual memory allocated unless `keepVirtualMemory` is true (and this is
+     713             : //! only used when writing data to a remote process).
+     714        1976 : static void vMemMgrReset(VMemMgr* self, bool keepVirtualMemory) noexcept {
+     715        1976 :   MemNode* node = self->_first;
+     716             : 
+     717        3924 :   while (node) {
+     718        1948 :     MemNode* next = node->next;
+     719             : 
+     720        1948 :     if (!keepVirtualMemory)
+     721        1948 :       vMemMgrReleaseVMem(self, node->mem, node->size);
+     722             : 
+     723        1948 :     Internal::releaseMemory(node->baUsed);
+     724             :     Internal::releaseMemory(node);
+     725             : 
+     726             :     node = next;
+     727             :   }
+     728             : 
+     729        1976 :   self->_allocatedBytes = 0;
+     730        1976 :   self->_usedBytes = 0;
+     731             : 
+     732        1976 :   self->_root = nullptr;
+     733        1976 :   self->_first = nullptr;
+     734        1976 :   self->_last = nullptr;
+     735        1976 :   self->_optimal = nullptr;
+     736        1976 : }
+     737             : 
+     738             : // ============================================================================
+     739             : // [asmjit::VMemMgr - Construction / Destruction]
+     740             : // ============================================================================
+     741             : 
+     742             : #if !ASMJIT_OS_WINDOWS
+     743        1976 : VMemMgr::VMemMgr() noexcept {
+     744             : #else
+     745             : VMemMgr::VMemMgr(HANDLE hProcess) noexcept {
+     746             : #endif
+     747             : 
+     748        1976 :   VMemInfo vm = OSUtils::getVirtualMemoryInfo();
+     749             : 
+     750             : #if ASMJIT_OS_WINDOWS
+     751             :   _hProcess = hProcess ? hProcess : vm.hCurrentProcess;
+     752             : #endif // ASMJIT_OS_WINDOWS
+     753             : 
+     754        1976 :   _blockSize = vm.pageGranularity;
+     755        1976 :   _blockDensity = 64;
+     756             : 
+     757        1976 :   _allocatedBytes = 0;
+     758        1976 :   _usedBytes = 0;
+     759             : 
+     760        1976 :   _root = nullptr;
+     761        1976 :   _first = nullptr;
+     762        1976 :   _last = nullptr;
+     763        1976 :   _optimal = nullptr;
+     764             : 
+     765        1976 :   _permanent = nullptr;
+     766        1976 :   _keepVirtualMemory = false;
+     767        1976 : }
+     768             : 
+     769        1976 : VMemMgr::~VMemMgr() noexcept {
+     770             :   // Freeable memory cleanup - Also frees the virtual memory if configured to.
+     771        1976 :   vMemMgrReset(this, _keepVirtualMemory);
+     772             : 
+     773             :   // Permanent memory cleanup - Never frees the virtual memory.
+     774        1976 :   PermanentNode* node = _permanent;
+     775        1976 :   while (node) {
+     776           0 :     PermanentNode* prev = node->prev;
+     777             :     Internal::releaseMemory(node);
+     778             :     node = prev;
+     779             :   }
+     780        1976 : }
+     781             : 
+     782             : // ============================================================================
+     783             : // [asmjit::VMemMgr - Reset]
+     784             : // ============================================================================
+     785             : 
+     786           0 : void VMemMgr::reset() noexcept {
+     787           0 :   vMemMgrReset(this, false);
+     788           0 : }
+     789             : 
+     790             : // ============================================================================
+     791             : // [asmjit::VMemMgr - Alloc / Release]
+     792             : // ============================================================================
+     793             : 
+     794        1948 : void* VMemMgr::alloc(size_t size, uint32_t type) noexcept {
+     795        1948 :   if (type == kAllocPermanent)
+     796           0 :     return vMemMgrAllocPermanent(this, size);
+     797             :   else
+     798        1948 :     return vMemMgrAllocFreeable(this, size);
+     799             : }
+     800             : 
+     801           0 : Error VMemMgr::release(void* p) noexcept {
+     802           0 :   if (!p) return kErrorOk;
+     803             : 
+     804             :   AutoLock locked(_lock);
+     805           0 :   MemNode* node = vMemMgrFindNodeByPtr(this, static_cast<uint8_t*>(p));
+     806           0 :   if (!node) return DebugUtils::errored(kErrorInvalidArgument);
+     807             : 
+     808           0 :   size_t offset = (size_t)((uint8_t*)p - (uint8_t*)node->mem);
+     809           0 :   size_t bitpos = M_DIV(offset, node->density);
+     810           0 :   size_t i = (bitpos / kBitsPerEntity);
+     811             : 
+     812           0 :   size_t* up = node->baUsed + i;  // Current ubits address.
+     813           0 :   size_t* cp = node->baCont + i;  // Current cbits address.
+     814           0 :   size_t ubits = *up;             // Current ubits[0] value.
+     815           0 :   size_t cbits = *cp;             // Current cbits[0] value.
+     816           0 :   size_t bit = (size_t)1 << (bitpos % kBitsPerEntity);
+     817             : 
+     818             :   size_t cont = 0;
+     819             :   bool stop;
+     820             : 
+     821             :   for (;;) {
+     822           0 :     stop = (cbits & bit) == 0;
+     823           0 :     ubits &= ~bit;
+     824           0 :     cbits &= ~bit;
+     825             : 
+     826           0 :     bit <<= 1;
+     827           0 :     cont++;
+     828             : 
+     829           0 :     if (stop || bit == 0) {
+     830           0 :       *up = ubits;
+     831           0 :       *cp = cbits;
+     832           0 :       if (stop)
+     833             :         break;
+     834             : 
+     835           0 :       ubits = *++up;
+     836           0 :       cbits = *++cp;
+     837             :       bit = 1;
+     838             :     }
+     839             :   }
+     840             : 
+     841             :   // If the freed block is fully allocated node then it's needed to
+     842             :   // update 'optimal' pointer in memory manager.
+     843           0 :   if (node->used == node->size) {
+     844           0 :     MemNode* cur = _optimal;
+     845             : 
+     846             :     do {
+     847           0 :       cur = cur->prev;
+     848           0 :       if (cur == node) {
+     849           0 :         _optimal = node;
+     850           0 :         break;
+     851             :       }
+     852           0 :     } while (cur);
+     853             :   }
+     854             : 
+     855             :   // Statistics.
+     856           0 :   cont *= node->density;
+     857           0 :   if (node->largestBlock < cont)
+     858           0 :     node->largestBlock = cont;
+     859             : 
+     860           0 :   node->used -= cont;
+     861           0 :   _usedBytes -= cont;
+     862             : 
+     863             :   // If page is empty, we can free it.
+     864           0 :   if (node->used == 0) {
+     865             :     // Free memory associated with node (this memory is not accessed
+     866             :     // anymore so it's safe).
+     867           0 :     vMemMgrReleaseVMem(this, node->mem, node->size);
+     868           0 :     Internal::releaseMemory(node->baUsed);
+     869             : 
+     870           0 :     node->baUsed = nullptr;
+     871           0 :     node->baCont = nullptr;
+     872             : 
+     873             :     // Statistics.
+     874           0 :     _allocatedBytes -= node->size;
+     875             : 
+     876             :     // Remove node. This function can return different node than
+     877             :     // passed into, but data is copied into previous node if needed.
+     878           0 :     Internal::releaseMemory(vMemMgrRemoveNode(this, node));
+     879             :     ASMJIT_ASSERT(vMemMgrCheckTree(this));
+     880             :   }
+     881             : 
+     882             :   return kErrorOk;
+     883             : }
+     884             : 
+     885           0 : Error VMemMgr::shrink(void* p, size_t used) noexcept {
+     886           0 :   if (!p) return kErrorOk;
+     887           0 :   if (used == 0)
+     888           0 :     return release(p);
+     889             : 
+     890             :   AutoLock locked(_lock);
+     891           0 :   MemNode* node = vMemMgrFindNodeByPtr(this, (uint8_t*)p);
+     892           0 :   if (!node) return DebugUtils::errored(kErrorInvalidArgument);
+     893             : 
+     894           0 :   size_t offset = (size_t)((uint8_t*)p - (uint8_t*)node->mem);
+     895           0 :   size_t bitpos = M_DIV(offset, node->density);
+     896           0 :   size_t i = (bitpos / kBitsPerEntity);
+     897             : 
+     898           0 :   size_t* up = node->baUsed + i;  // Current ubits address.
+     899           0 :   size_t* cp = node->baCont + i;  // Current cbits address.
+     900           0 :   size_t ubits = *up;             // Current ubits[0] value.
+     901           0 :   size_t cbits = *cp;             // Current cbits[0] value.
+     902           0 :   size_t bit = (size_t)1 << (bitpos % kBitsPerEntity);
+     903             : 
+     904             :   size_t cont = 0;
+     905           0 :   size_t usedBlocks = (used + node->density - 1) / node->density;
+     906             : 
+     907             :   bool stop;
+     908             : 
+     909             :   // Find the first block we can mark as free.
+     910             :   for (;;) {
+     911           0 :     stop = (cbits & bit) == 0;
+     912           0 :     if (stop)
+     913             :       return kErrorOk;
+     914             : 
+     915           0 :     if (++cont == usedBlocks)
+     916             :       break;
+     917             : 
+     918           0 :     bit <<= 1;
+     919           0 :     if (bit == 0) {
+     920           0 :       ubits = *++up;
+     921           0 :       cbits = *++cp;
+     922             :       bit = 1;
+     923             :     }
+     924             :   }
+     925             : 
+     926             :   // Free the tail blocks.
+     927             :   cont = ~(size_t)0;
+     928           0 :   goto _EnterFreeLoop;
+     929             : 
+     930             :   for (;;) {
+     931           0 :     stop = (cbits & bit) == 0;
+     932           0 :     ubits &= ~bit;
+     933             : 
+     934           0 : _EnterFreeLoop:
+     935           0 :     cbits &= ~bit;
+     936             : 
+     937           0 :     bit <<= 1;
+     938           0 :     cont++;
+     939             : 
+     940           0 :     if (stop || bit == 0) {
+     941           0 :       *up = ubits;
+     942           0 :       *cp = cbits;
+     943           0 :       if (stop)
+     944             :         break;
+     945             : 
+     946           0 :       ubits = *++up;
+     947           0 :       cbits = *++cp;
+     948             :       bit = 1;
+     949             :     }
+     950             :   }
+     951             : 
+     952             :   // Statistics.
+     953           0 :   cont *= node->density;
+     954           0 :   if (node->largestBlock < cont)
+     955           0 :     node->largestBlock = cont;
+     956             : 
+     957           0 :   node->used -= cont;
+     958           0 :   _usedBytes -= cont;
+     959             : 
+     960           0 :   return kErrorOk;
+     961             : }
+     962             : 
+     963             : // ============================================================================
+     964             : // [asmjit::VMem - Test]
+     965             : // ============================================================================
+     966             : 
+     967             : #if defined(ASMJIT_TEST)
+     968             : static void VMemTest_fill(void* a, void* b, int i) noexcept {
+     969             :   int pattern = rand() % 256;
+     970             :   *(int *)a = i;
+     971             :   *(int *)b = i;
+     972             :   ::memset((char*)a + sizeof(int), pattern, i - sizeof(int));
+     973             :   ::memset((char*)b + sizeof(int), pattern, i - sizeof(int));
+     974             : }
+     975             : 
+     976             : static void VMemTest_verify(void* a, void* b) noexcept {
+     977             :   int ai = *(int*)a;
+     978             :   int bi = *(int*)b;
+     979             : 
+     980             :   EXPECT(ai == bi,
+     981             :     "The length of 'a' (%d) and 'b' (%d) should be same", ai, bi);
+     982             : 
+     983             :   EXPECT(::memcmp(a, b, ai) == 0,
+     984             :     "Pattern (%p) doesn't match", a);
+     985             : }
+     986             : 
+     987             : static void VMemTest_stats(VMemMgr& memmgr) noexcept {
+     988             :   INFO("Used     : %u", static_cast<unsigned int>(memmgr.getUsedBytes()));
+     989             :   INFO("Allocated: %u", static_cast<unsigned int>(memmgr.getAllocatedBytes()));
+     990             : }
+     991             : 
+     992             : static void VMemTest_shuffle(void** a, void** b, size_t count) noexcept {
+     993             :   for (size_t i = 0; i < count; ++i) {
+     994             :     size_t si = (size_t)rand() % count;
+     995             : 
+     996             :     void* ta = a[i];
+     997             :     void* tb = b[i];
+     998             : 
+     999             :     a[i] = a[si];
+    1000             :     b[i] = b[si];
+    1001             : 
+    1002             :     a[si] = ta;
+    1003             :     b[si] = tb;
+    1004             :   }
+    1005             : }
+    1006             : 
+    1007             : UNIT(base_vmem) {
+    1008             :   VMemMgr memmgr;
+    1009             : 
+    1010             :   // Should be predictible.
+    1011             :   srand(100);
+    1012             : 
+    1013             :   int i;
+    1014             :   int kCount = 200000;
+    1015             : 
+    1016             :   INFO("Memory alloc/free test - %d allocations", static_cast<int>(kCount));
+    1017             : 
+    1018             :   void** a = (void**)Internal::allocMemory(sizeof(void*) * kCount);
+    1019             :   void** b = (void**)Internal::allocMemory(sizeof(void*) * kCount);
+    1020             : 
+    1021             :   EXPECT(a != nullptr && b != nullptr,
+    1022             :     "Couldn't allocate %u bytes on heap", kCount * 2);
+    1023             : 
+    1024             :   INFO("Allocating virtual memory...");
+    1025             :   for (i = 0; i < kCount; i++) {
+    1026             :     int r = (rand() % 1000) + 4;
+    1027             : 
+    1028             :     a[i] = memmgr.alloc(r);
+    1029             :     EXPECT(a[i] != nullptr,
+    1030             :       "Couldn't allocate %d bytes of virtual memory", r);
+    1031             :     ::memset(a[i], 0, r);
+    1032             :   }
+    1033             :   VMemTest_stats(memmgr);
+    1034             : 
+    1035             :   INFO("Freeing virtual memory...");
+    1036             :   for (i = 0; i < kCount; i++) {
+    1037             :     EXPECT(memmgr.release(a[i]) == kErrorOk,
+    1038             :       "Failed to free %p", b[i]);
+    1039             :   }
+    1040             :   VMemTest_stats(memmgr);
+    1041             : 
+    1042             :   INFO("Verified alloc/free test - %d allocations", static_cast<int>(kCount));
+    1043             :   for (i = 0; i < kCount; i++) {
+    1044             :     int r = (rand() % 1000) + 4;
+    1045             : 
+    1046             :     a[i] = memmgr.alloc(r);
+    1047             :     EXPECT(a[i] != nullptr,
+    1048             :       "Couldn't allocate %d bytes of virtual memory", r);
+    1049             : 
+    1050             :     b[i] = Internal::allocMemory(r);
+    1051             :     EXPECT(b[i] != nullptr,
+    1052             :       "Couldn't allocate %d bytes on heap", r);
+    1053             : 
+    1054             :     VMemTest_fill(a[i], b[i], r);
+    1055             :   }
+    1056             :   VMemTest_stats(memmgr);
+    1057             : 
+    1058             :   INFO("Shuffling...");
+    1059             :   VMemTest_shuffle(a, b, kCount);
+    1060             : 
+    1061             :   INFO("Verify and free...");
+    1062             :   for (i = 0; i < kCount / 2; i++) {
+    1063             :     VMemTest_verify(a[i], b[i]);
+    1064             :     EXPECT(memmgr.release(a[i]) == kErrorOk,
+    1065             :       "Failed to free %p", a[i]);
+    1066             :     Internal::releaseMemory(b[i]);
+    1067             :   }
+    1068             :   VMemTest_stats(memmgr);
+    1069             : 
+    1070             :   INFO("Alloc again");
+    1071             :   for (i = 0; i < kCount / 2; i++) {
+    1072             :     int r = (rand() % 1000) + 4;
+    1073             : 
+    1074             :     a[i] = memmgr.alloc(r);
+    1075             :     EXPECT(a[i] != nullptr,
+    1076             :       "Couldn't allocate %d bytes of virtual memory", r);
+    1077             : 
+    1078             :     b[i] = Internal::allocMemory(r);
+    1079             :     EXPECT(b[i] != nullptr,
+    1080             :       "Couldn't allocate %d bytes on heap");
+    1081             : 
+    1082             :     VMemTest_fill(a[i], b[i], r);
+    1083             :   }
+    1084             :   VMemTest_stats(memmgr);
+    1085             : 
+    1086             :   INFO("Verify and free...");
+    1087             :   for (i = 0; i < kCount; i++) {
+    1088             :     VMemTest_verify(a[i], b[i]);
+    1089             :     EXPECT(memmgr.release(a[i]) == kErrorOk,
+    1090             :       "Failed to free %p", a[i]);
+    1091             :     Internal::releaseMemory(b[i]);
+    1092             :   }
+    1093             :   VMemTest_stats(memmgr);
+    1094             : 
+    1095             :   Internal::releaseMemory(a);
+    1096             :   Internal::releaseMemory(b);
+    1097             : }
+    1098             : #endif // ASMJIT_TEST
+    1099             : 
+    1100             : } // asmjit namespace
+    1101             : } // namespace PLMD
+    1102             : #pragma GCC diagnostic pop
+    1103             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.cpp.func-sort-c.html b/coverage-libs/asmjit/x86assembler.cpp.func-sort-c.html new file mode 100644 index 000000000000..5e3fa08c95ed --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:183170510.7 %
Date:2024-02-22 21:58:47Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12X86Assembler5alignEjj0
_ZN4PLMD6asmjit12X86Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12X86AssemblerD0Ev0
_ZN4PLMD6asmjit12X86Assembler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12X86AssemblerC2EPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12X86AssemblerD2Ev1948
_ZN4PLMD6asmjit12X86Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_48362
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.cpp.func.html b/coverage-libs/asmjit/x86assembler.cpp.func.html new file mode 100644 index 000000000000..0c6201af4bb5 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:183170510.7 %
Date:2024-02-22 21:58:47Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12X86Assembler5_emitEjRKNS0_8Operand_ES4_S4_S4_48362
_ZN4PLMD6asmjit12X86Assembler5alignEjj0
_ZN4PLMD6asmjit12X86Assembler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12X86Assembler8onDetachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit12X86AssemblerC2EPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit12X86AssemblerD0Ev0
_ZN4PLMD6asmjit12X86AssemblerD2Ev1948
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.cpp.gcov.html b/coverage-libs/asmjit/x86assembler.cpp.gcov.html new file mode 100644 index 000000000000..dcdd9e44203d --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.cpp.gcov.html @@ -0,0 +1,4722 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:183170510.7 %
Date:2024-02-22 21:58:47Functions:4757.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Guard]
+      33             : #include "./asmjit_build.h"
+      34             : #if defined(ASMJIT_BUILD_X86)
+      35             : 
+      36             : // [Dependencies]
+      37             : #include "./cpuinfo.h"
+      38             : #include "./logging.h"
+      39             : #include "./misc_p.h"
+      40             : #include "./utils.h"
+      41             : #include "./x86assembler.h"
+      42             : #include "./x86logging_p.h"
+      43             : 
+      44             : // [Api-Begin]
+      45             : #include "./asmjit_apibegin.h"
+      46             : 
+      47             : namespace PLMD {
+      48             : namespace asmjit {
+      49             : 
+      50             : // ============================================================================
+      51             : // [FastUInt8]
+      52             : // ============================================================================
+      53             : 
+      54             : #if ASMJIT_ARCH_X86 || ASMJIT_ARCH_X64
+      55             : typedef unsigned char FastUInt8;
+      56             : #else
+      57             : typedef unsigned int FastUInt8;
+      58             : #endif
+      59             : 
+      60             : // ============================================================================
+      61             : // [Constants]
+      62             : // ============================================================================
+      63             : 
+      64             : //! \internal
+      65             : //!
+      66             : //! X86/X64 bytes used to encode important prefixes.
+      67             : enum X86Byte {
+      68             :   //! 1-byte REX prefix mask.
+      69             :   kX86ByteRex = 0x40,
+      70             : 
+      71             :   //! 1-byte REX.W component.
+      72             :   kX86ByteRexW = 0x08,
+      73             : 
+      74             :   //! 2-byte VEX prefix:
+      75             :   //!   - `[0]` - `0xC5`.
+      76             :   //!   - `[1]` - `RvvvvLpp`.
+      77             :   kX86ByteVex2 = 0xC5,
+      78             : 
+      79             :   //! 3-byte VEX prefix.
+      80             :   //!   - `[0]` - `0xC4`.
+      81             :   //!   - `[1]` - `RXBmmmmm`.
+      82             :   //!   - `[2]` - `WvvvvLpp`.
+      83             :   kX86ByteVex3 = 0xC4,
+      84             : 
+      85             :   //! 3-byte XOP prefix.
+      86             :   //!   - `[0]` - `0x8F`.
+      87             :   //!   - `[1]` - `RXBmmmmm`.
+      88             :   //!   - `[2]` - `WvvvvLpp`.
+      89             :   kX86ByteXop3 = 0x8F,
+      90             : 
+      91             :   //! 4-byte EVEX prefix.
+      92             :   //!   - `[0]` - `0x62`.
+      93             :   //!   - `[1]` - Payload0 or `P[ 7: 0]` - `[R  X  B  R' 0  0  m  m]`.
+      94             :   //!   - `[2]` - Payload1 or `P[15: 8]` - `[W  v  v  v  v  1  p  p]`.
+      95             :   //!   - `[3]` - Payload2 or `P[23:16]` - `[z  L' L  b  V' a  a  a]`.
+      96             :   //!
+      97             :   //! Groups:
+      98             :   //!   - `P[ 1: 0]` - OPCODE: EVEX.mmmmm, only lowest 2 bits [1:0] used.
+      99             :   //!   - `P[ 3: 2]` - ______: Must be 0.
+     100             :   //!   - `P[    4]` - REG-ID: EVEX.R' - 5th bit of 'RRRRR'.
+     101             :   //!   - `P[    5]` - REG-ID: EVEX.B  - 4th bit of 'BBBBB'.
+     102             :   //!   - `P[    6]` - REG-ID: EVEX.X  - 5th bit of 'BBBBB' or 4th bit of 'XXXX' (with SIB).
+     103             :   //!   - `P[    7]` - REG-ID: EVEX.R  - 4th bit of 'RRRRR'.
+     104             :   //!   - `P[ 9: 8]` - OPCODE: EVEX.pp.
+     105             :   //!   - `P[   10]` - ______: Must be 1.
+     106             :   //!   - `P[14:11]` - REG-ID: 4 bits of 'VVVV'.
+     107             :   //!   - `P[   15]` - OPCODE: EVEX.W.
+     108             :   //!   - `P[18:16]` - REG-ID: K register k0...k7 (Merging/Zeroing Vector Ops).
+     109             :   //!   - `P[   19]` - REG-ID: 5th bit of 'VVVVV'.
+     110             :   //!   - `P[   20]` - OPCODE: Broadcast/Rounding Control/SAE bit.
+     111             :   //!   - `P[22.21]` - OPCODE: Vector Length (L' and  L) / Rounding Control.
+     112             :   //!   - `P[   23]` - OPCODE: Zeroing/Merging.
+     113             :   kX86ByteEvex = 0x62
+     114             : };
+     115             : 
+     116             : // AsmJit specific (used to encode VVVVV field in XOP/VEX/EVEX).
+     117             : enum VexVVVVV {
+     118             :   kVexVVVVVShift = 7,
+     119             :   kVexVVVVVMask = 0x1F << kVexVVVVVShift
+     120             : };
+     121             : 
+     122             : //! \internal
+     123             : //!
+     124             : //! Instruction 2-byte/3-byte opcode prefix definition.
+     125             : struct X86OpCodeMM {
+     126             :   uint8_t len;
+     127             :   uint8_t data[3];
+     128             : };
+     129             : 
+     130             : //! \internal
+     131             : //!
+     132             : //! Mandatory prefixes used to encode legacy [66, F3, F2] or [9B] byte.
+     133             : static const uint8_t x86OpCodePP[8] = { 0x00, 0x66, 0xF3, 0xF2, 0x00, 0x00, 0x00, 0x9B };
+     134             : 
+     135             : //! \internal
+     136             : //!
+     137             : //! Instruction 2-byte/3-byte opcode prefix data.
+     138             : static const X86OpCodeMM x86OpCodeMM[] = {
+     139             :   { 0, { 0x00, 0x00, 0 } }, // #00 (0b0000).
+     140             :   { 1, { 0x0F, 0x00, 0 } }, // #01 (0b0001).
+     141             :   { 2, { 0x0F, 0x38, 0 } }, // #02 (0b0010).
+     142             :   { 2, { 0x0F, 0x3A, 0 } }, // #03 (0b0011).
+     143             :   { 2, { 0x0F, 0x01, 0 } }, // #04 (0b0100).
+     144             :   { 0, { 0x00, 0x00, 0 } }, // #05 (0b0101).
+     145             :   { 0, { 0x00, 0x00, 0 } }, // #06 (0b0110).
+     146             :   { 0, { 0x00, 0x00, 0 } }, // #07 (0b0111).
+     147             :   { 0, { 0x00, 0x00, 0 } }, // #08 (0b1000).
+     148             :   { 0, { 0x00, 0x00, 0 } }, // #09 (0b1001).
+     149             :   { 0, { 0x00, 0x00, 0 } }, // #0A (0b1010).
+     150             :   { 0, { 0x00, 0x00, 0 } }, // #0B (0b1011).
+     151             :   { 0, { 0x00, 0x00, 0 } }, // #0C (0b1100).
+     152             :   { 0, { 0x00, 0x00, 0 } }, // #0D (0b1101).
+     153             :   { 0, { 0x00, 0x00, 0 } }, // #0E (0b1110).
+     154             :   { 0, { 0x00, 0x00, 0 } }  // #0F (0b1111).
+     155             : };
+     156             : 
+     157             : static const uint8_t x86SegmentPrefix[8] = { 0x00, 0x26, 0x2E, 0x36, 0x3E, 0x64, 0x65, 0x00 };
+     158             : static const uint8_t x86OpCodePushSeg[8] = { 0x00, 0x06, 0x0E, 0x16, 0x1E, 0xA0, 0xA8, 0x00 };
+     159             : static const uint8_t x86OpCodePopSeg[8]  = { 0x00, 0x07, 0x00, 0x17, 0x1F, 0xA1, 0xA9, 0x00 };
+     160             : 
+     161             : // ============================================================================
+     162             : // [asmjit::X86MemInfo | X86VEXPrefix | X86LLByRegType | X86CDisp8Table]
+     163             : // ============================================================================
+     164             : 
+     165             : //! \internal
+     166             : //!
+     167             : //! Memory operand's info bits.
+     168             : //!
+     169             : //! A lookup table that contains various information based on the BASE and INDEX
+     170             : //! information of a memory operand. This is much better and safer than playing
+     171             : //! with IFs in the code and can check for errors must faster and better.
+     172             : enum X86MemInfo_Enum {
+     173             :   kX86MemInfo_0         = 0x00,
+     174             : 
+     175             :   kX86MemInfo_BaseGp    = 0x01, //!< Has BASE reg, REX.B can be 1, compatible with REX.B byte.
+     176             :   kX86MemInfo_Index     = 0x02, //!< Has INDEX reg, REX.X can be 1, compatible with REX.X byte.
+     177             : 
+     178             :   kX86MemInfo_BaseLabel = 0x10, //!< Base is Label.
+     179             :   kX86MemInfo_BaseRip   = 0x20, //!< Base is RIP.
+     180             : 
+     181             :   kX86MemInfo_67H_X86   = 0x40, //!< Address-size override in 32-bit mode.
+     182             :   kX86MemInfo_67H_X64   = 0x80, //!< Address-size override in 64-bit mode.
+     183             :   kX86MemInfo_67H_Mask  = 0xC0  //!< Contains all address-size override bits.
+     184             : };
+     185             : 
+     186             : template<uint32_t X>
+     187             : struct X86MemInfo_T {
+     188             :   enum {
+     189             :     B = (X     ) & 0x1F,
+     190             :     I = (X >> 5) & 0x1F,
+     191             : 
+     192             :     kBase  = ((B >= X86Reg::kRegGpw  && B <= X86Reg::kRegGpq ) ? kX86MemInfo_BaseGp    :
+     193             :               (B == X86Reg::kRegRip                          ) ? kX86MemInfo_BaseRip   :
+     194             :               (B == Label::kLabelTag                         ) ? kX86MemInfo_BaseLabel : 0),
+     195             : 
+     196             :     kIndex = ((I >= X86Reg::kRegGpw  && I <= X86Reg::kRegGpq ) ? kX86MemInfo_Index     :
+     197             :               (I >= X86Reg::kRegXmm  && I <= X86Reg::kRegZmm ) ? kX86MemInfo_Index     : 0),
+     198             : 
+     199             :     k67H   = ((B == X86Reg::kRegGpw  && I == X86Reg::kRegNone) ? kX86MemInfo_67H_X86   :
+     200             :               (B == X86Reg::kRegGpd  && I == X86Reg::kRegNone) ? kX86MemInfo_67H_X64   :
+     201             :               (B == X86Reg::kRegNone && I == X86Reg::kRegGpw ) ? kX86MemInfo_67H_X86   :
+     202             :               (B == X86Reg::kRegNone && I == X86Reg::kRegGpd ) ? kX86MemInfo_67H_X64   :
+     203             :               (B == X86Reg::kRegGpw  && I == X86Reg::kRegGpw ) ? kX86MemInfo_67H_X86   :
+     204             :               (B == X86Reg::kRegGpd  && I == X86Reg::kRegGpd ) ? kX86MemInfo_67H_X64   :
+     205             :               (B == X86Reg::kRegGpw  && I == X86Reg::kRegXmm ) ? kX86MemInfo_67H_X86   :
+     206             :               (B == X86Reg::kRegGpd  && I == X86Reg::kRegXmm ) ? kX86MemInfo_67H_X64   :
+     207             :               (B == X86Reg::kRegGpw  && I == X86Reg::kRegYmm ) ? kX86MemInfo_67H_X86   :
+     208             :               (B == X86Reg::kRegGpd  && I == X86Reg::kRegYmm ) ? kX86MemInfo_67H_X64   :
+     209             :               (B == X86Reg::kRegGpw  && I == X86Reg::kRegZmm ) ? kX86MemInfo_67H_X86   :
+     210             :               (B == X86Reg::kRegGpd  && I == X86Reg::kRegZmm ) ? kX86MemInfo_67H_X64   :
+     211             :               (B == Label::kLabelTag && I == X86Reg::kRegGpw ) ? kX86MemInfo_67H_X86   :
+     212             :               (B == Label::kLabelTag && I == X86Reg::kRegGpd ) ? kX86MemInfo_67H_X64   : 0),
+     213             : 
+     214             :     kValue = kBase | kIndex | k67H | 0x04 | 0x08
+     215             :   };
+     216             : };
+     217             : 
+     218             : // The result stored in the LUT is a combination of
+     219             : //   - 67H - Address override prefix - depends on BASE+INDEX register types and
+     220             : //           the target architecture.
+     221             : //   - REX - A possible combination of REX.[B|X|R|W] bits in REX prefix where
+     222             : //           REX.B and REX.X are possibly masked out, but REX.R and REX.W are
+     223             : //           kept as is.
+     224             : static const uint8_t x86MemInfo[] = { ASMJIT_TABLE_T_1024(X86MemInfo_T, kValue, 0) };
+     225             : 
+     226             : // VEX3 or XOP xor bits applied to the opcode before emitted. The index to this
+     227             : // table is 'mmmmm' value, which contains all we need. This is only used by a
+     228             : // 3 BYTE VEX and XOP prefixes, 2 BYTE VEX prefix is handled differently. The
+     229             : // idea is to minimize the difference between VEX3 vs XOP when encoding VEX
+     230             : // or XOP instruction. This should minimize the code required to emit such
+     231             : // instructions and should also make it faster as we don't need any branch to
+     232             : // decide between VEX3 vs XOP.
+     233             : //            ____    ___
+     234             : // [_OPCODE_|WvvvvLpp|RXBmmmmm|VEX3_XOP]
+     235             : template<uint32_t X>
+     236             : struct X86VEXPrefix_T {
+     237             :   enum { kValue = ((X & 0x08) ? kX86ByteXop3 : kX86ByteVex3) | (0xF << 19) | (0x7 << 13) };
+     238             : };
+     239             : static const uint32_t x86VEXPrefix[] = { ASMJIT_TABLE_T_16(X86VEXPrefix_T, kValue, 0) };
+     240             : 
+     241             : // Table that contains LL opcode field addressed by a register size / 16. It's
+     242             : // used to propagate L.256 or L.512 when YMM or ZMM registers are used,
+     243             : // respectively.
+     244             : template<uint32_t X>
+     245             : struct X86LLBySizeDiv16_T {
+     246             :   enum {
+     247             :     kValue = (X & (64 >> 4)) ? X86Inst::kOpCode_LL_512 :
+     248             :              (X & (32 >> 4)) ? X86Inst::kOpCode_LL_256 : 0
+     249             :   };
+     250             : };
+     251             : static const uint32_t x86LLBySizeDiv16[] = { ASMJIT_TABLE_T_16(X86LLBySizeDiv16_T, kValue, 0) };
+     252             : 
+     253             : // Table that contains LL opcode field addressed by a register size / 16. It's
+     254             : // used to propagate L.256 or L.512 when YMM or ZMM registers are used,
+     255             : // respectively.
+     256             : template<uint32_t X>
+     257             : struct X86LLByRegType_T {
+     258             :   enum {
+     259             :     kValue = X == X86Reg::kRegZmm ? X86Inst::kOpCode_LL_512 :
+     260             :              X == X86Reg::kRegYmm ? X86Inst::kOpCode_LL_256 : 0
+     261             :   };
+     262             : };
+     263             : static const uint32_t x86LLByRegType[] = { ASMJIT_TABLE_T_16(X86LLByRegType_T, kValue, 0) };
+     264             : 
+     265             : // Table that contains a scale (shift left) based on 'TTWLL' field and
+     266             : // the instruction's tuple-type (TT) field. The scale is then applied to
+     267             : // the BASE-N stored in each opcode to calculate the final compressed
+     268             : // displacement used by all EVEX encoded instructions.
+     269             : template<uint32_t X>
+     270             : struct X86CDisp8SHL_T {
+     271             :   enum {
+     272             :     TT = (((X) >> 3) << X86Inst::kOpCode_CDTT_Shift),
+     273             :     LL = (((X) >> 0) & 0x3),
+     274             :     W  = (((X) >> 2) & 0x1),
+     275             : 
+     276             :     kValue = (TT == X86Inst::kOpCode_CDTT_None ? ((LL==0) ? 0 : (LL==1) ? 0   : 0  ) :
+     277             :               TT == X86Inst::kOpCode_CDTT_ByLL ? ((LL==0) ? 0 : (LL==1) ? 1   : 2  ) :
+     278             :               TT == X86Inst::kOpCode_CDTT_T1W  ? ((LL==0) ? W : (LL==1) ? 1+W : 2+W) :
+     279             :               TT == X86Inst::kOpCode_CDTT_DUP  ? ((LL==0) ? 0 : (LL==1) ? 2   : 3  ) : 0 ) << X86Inst::kOpCode_CDSHL_Shift
+     280             :   };
+     281             : };
+     282             : static const uint32_t x86CDisp8SHL[] = { ASMJIT_TABLE_T_32(X86CDisp8SHL_T, kValue, 0) };
+     283             : 
+     284             : // Table that contains MOD byte of a 16-bit [BASE + disp] address.
+     285             : //   0xFF == Invalid.
+     286             : static const uint8_t x86Mod16BaseTable[8] = {
+     287             :   0xFF, // AX -> N/A.
+     288             :   0xFF, // CX -> N/A.
+     289             :   0xFF, // DX -> N/A.
+     290             :   0x07, // BX -> 111.
+     291             :   0xFF, // SP -> N/A.
+     292             :   0x06, // BP -> 110.
+     293             :   0x04, // SI -> 100.
+     294             :   0x05  // DI -> 101.
+     295             : };
+     296             : 
+     297             : // Table that contains MOD byte of a 16-bit [BASE + INDEX + disp] combination.
+     298             : //   0xFF == Invalid.
+     299             : template<uint32_t X>
+     300             : struct X86Mod16BaseIndexTable_T {
+     301             :   enum {
+     302             :     B = X >> 3,
+     303             :     I = X & 0x7,
+     304             : 
+     305             :     kValue = ((B == X86Gp::kIdBx && I == X86Gp::kIdSi) || (B == X86Gp::kIdSi && I == X86Gp::kIdBx)) ? 0x00 :
+     306             :              ((B == X86Gp::kIdBx && I == X86Gp::kIdDi) || (B == X86Gp::kIdDi && I == X86Gp::kIdBx)) ? 0x01 :
+     307             :              ((B == X86Gp::kIdBp && I == X86Gp::kIdSi) || (B == X86Gp::kIdSi && I == X86Gp::kIdBp)) ? 0x02 :
+     308             :              ((B == X86Gp::kIdBp && I == X86Gp::kIdDi) || (B == X86Gp::kIdDi && I == X86Gp::kIdBp)) ? 0x03 : 0xFF
+     309             :   };
+     310             : };
+     311             : static const uint8_t x86Mod16BaseIndexTable[] = { ASMJIT_TABLE_T_64(X86Mod16BaseIndexTable_T, kValue, 0) };
+     312             : 
+     313             : // ============================================================================
+     314             : // [asmjit::X86Assembler - Helpers]
+     315             : // ============================================================================
+     316             : 
+     317             : static ASMJIT_INLINE bool x86IsJmpOrCall(uint32_t instId) noexcept {
+     318           0 :   return instId == X86Inst::kIdJmp ||
+     319           0 :          instId == X86Inst::kIdCall;
+     320             : }
+     321             : 
+     322             : static ASMJIT_INLINE bool x86IsImplicitMem(const Operand_& op, uint32_t base) noexcept {
+     323           0 :   return op.isMem() && op.as<X86Mem>().getBaseId() == base;
+     324             : }
+     325             : 
+     326             : static ASMJIT_INLINE int64_t x86SignExtend32To64(int64_t imm) noexcept {
+     327           0 :   return static_cast<int64_t>(static_cast<int32_t>(imm & 0xFFFFFFFF));
+     328             : }
+     329             : 
+     330             : //! Get `O` field of `opCode`.
+     331             : static ASMJIT_INLINE uint32_t x86ExtractO(uint32_t opCode) noexcept {
+     332       48362 :   return (opCode >> X86Inst::kOpCode_O_Shift) & 0x07;
+     333             : }
+     334             : 
+     335             : static ASMJIT_INLINE uint32_t x86ExtractREX(uint32_t opCode, uint32_t options) noexcept {
+     336             :   // kOpCode_REX was designed in a way that when shifted there will be no bytes
+     337             :   // set except REX.[B|X|R|W]. The returned value forms a real REX prefix byte.
+     338             :   // This case is tested by `X86Inst.cpp`.
+     339       48362 :   return (opCode | options) >> X86Inst::kOpCode_REX_Shift;
+     340             : }
+     341             : 
+     342             : //! Combine `regId` and `vvvvvId` into a single value (used by AVX and AVX-512).
+     343             : static ASMJIT_INLINE uint32_t x86PackRegAndVvvvv(uint32_t regId, uint32_t vvvvvId) noexcept {
+     344           0 :   return regId + (vvvvvId << kVexVVVVVShift);
+     345             : }
+     346             : 
+     347             : static ASMJIT_INLINE uint32_t x86OpCodeLByVMem(const Operand_& op) noexcept {
+     348           0 :   return x86LLByRegType[op.as<X86Mem>().getIndexType()];
+     349             : }
+     350             : 
+     351             : static ASMJIT_INLINE uint32_t x86OpCodeLBySize(uint32_t size) noexcept {
+     352           0 :   return x86LLBySizeDiv16[size / 16];
+     353             : }
+     354             : 
+     355             : static ASMJIT_INLINE uint32_t x86ExtractLLMM(uint32_t opCode, uint32_t options) noexcept {
+     356           0 :   uint32_t x = opCode & (X86Inst::kOpCode_LL_Mask | X86Inst::kOpCode_MM_Mask);
+     357           0 :   uint32_t y = options & X86Inst::kOptionVex3;
+     358           0 :   return (x | y) >> X86Inst::kOpCode_MM_Shift;
+     359             : }
+     360             : 
+     361             : //! Encode MOD byte.
+     362             : static ASMJIT_INLINE uint32_t x86EncodeMod(uint32_t m, uint32_t o, uint32_t rm) noexcept {
+     363             :   ASMJIT_ASSERT(m <= 3);
+     364             :   ASMJIT_ASSERT(o <= 7);
+     365             :   ASMJIT_ASSERT(rm <= 7);
+     366           0 :   return (m << 6) + (o << 3) + rm;
+     367             : }
+     368             : 
+     369             : //! Encode SIB byte.
+     370             : static ASMJIT_INLINE uint32_t x86EncodeSib(uint32_t s, uint32_t i, uint32_t b) noexcept {
+     371             :   ASMJIT_ASSERT(s <= 3);
+     372             :   ASMJIT_ASSERT(i <= 7);
+     373             :   ASMJIT_ASSERT(b <= 7);
+     374           0 :   return (s << 6) + (i << 3) + b;
+     375             : }
+     376             : 
+     377             : // ============================================================================
+     378             : // [asmjit::X86Assembler - Construction / Destruction]
+     379             : // ============================================================================
+     380             : 
+     381        1948 : X86Assembler::X86Assembler(CodeHolder* code) noexcept : Assembler() {
+     382        1948 :   if (code)
+     383        1948 :     code->attach(this);
+     384        1948 : }
+     385        1948 : X86Assembler::~X86Assembler() noexcept {}
+     386             : 
+     387             : // ============================================================================
+     388             : // [asmjit::X86Assembler - Events]
+     389             : // ============================================================================
+     390             : 
+     391        1948 : Error X86Assembler::onAttach(CodeHolder* code) noexcept {
+     392             :   uint32_t archType = code->getArchType();
+     393        1948 :   if (!ArchInfo::isX86Family(archType))
+     394             :     return DebugUtils::errored(kErrorInvalidArch);
+     395             : 
+     396        1948 :   ASMJIT_PROPAGATE(Base::onAttach(code));
+     397             : 
+     398        1948 :   if (archType == ArchInfo::kTypeX86) {
+     399             :     // 32 bit architecture - X86.
+     400             :     _setAddressOverrideMask(kX86MemInfo_67H_X86);
+     401           0 :     _globalOptions |= X86Inst::_kOptionInvalidRex;
+     402           0 :     _nativeGpArray = x86OpData.gpd;
+     403             :   }
+     404             :   else {
+     405             :     // 64 bit architecture - X64 or X32.
+     406             :     _setAddressOverrideMask(kX86MemInfo_67H_X64);
+     407        1948 :     _nativeGpArray = x86OpData.gpq;
+     408             :   }
+     409             : 
+     410        1948 :   _nativeGpReg = _nativeGpArray[0];
+     411        1948 :   return kErrorOk;
+     412             : }
+     413             : 
+     414           0 : Error X86Assembler::onDetach(CodeHolder* code) noexcept {
+     415           0 :   return Base::onDetach(code);
+     416             : }
+     417             : 
+     418             : // ============================================================================
+     419             : // [asmjit::X86Assembler - Helpers]
+     420             : // ============================================================================
+     421             : 
+     422             : #define EMIT_BYTE(VAL)                               \
+     423             :   do {                                               \
+     424             :     cursor[0] = static_cast<uint8_t>((VAL) & 0xFFU); \
+     425             :     cursor += 1;                                     \
+     426             :   } while (0)
+     427             : 
+     428             : #define EMIT_16(VAL)                                 \
+     429             :   do {                                               \
+     430             :     Utils::writeU16uLE(cursor,                       \
+     431             :       static_cast<uint32_t>((VAL) & 0xFFFFU));       \
+     432             :     cursor += 2;                                     \
+     433             :   } while (0)
+     434             : 
+     435             : #define EMIT_32(VAL)                                 \
+     436             :   do {                                               \
+     437             :     Utils::writeU32uLE(cursor,                       \
+     438             :       static_cast<uint32_t>((VAL) & 0xFFFFFFFFU));   \
+     439             :     cursor += 4;                                     \
+     440             :   } while (0)
+     441             : 
+     442             : #define ADD_66H_P(EXP)                                                   \
+     443             :   do {                                                                   \
+     444             :     opCode |= (static_cast<uint32_t>(EXP) << X86Inst::kOpCode_PP_Shift); \
+     445             :   } while (0)
+     446             : 
+     447             : #define ADD_66H_P_BY_SIZE(SIZE)                                          \
+     448             :   do {                                                                   \
+     449             :     opCode |= (static_cast<uint32_t>((SIZE) & 0x02))                     \
+     450             :            << (X86Inst::kOpCode_PP_Shift - 1);                           \
+     451             :   } while (0)
+     452             : 
+     453             : #define ADD_REX_W(EXP)                                                   \
+     454             :   do {                                                                   \
+     455             :     if (EXP)                                                             \
+     456             :       opCode |= X86Inst::kOpCode_W;                                      \
+     457             :   } while (0)
+     458             : 
+     459             : #define ADD_REX_W_BY_SIZE(SIZE)                                          \
+     460             :   do {                                                                   \
+     461             :     if ((SIZE) == 8)                                                     \
+     462             :       opCode |= X86Inst::kOpCode_W;                                      \
+     463             :   } while (0)
+     464             : 
+     465             : #define ADD_PREFIX_BY_SIZE(SIZE)                                         \
+     466             :   do {                                                                   \
+     467             :     ADD_66H_P_BY_SIZE(SIZE);                                             \
+     468             :     ADD_REX_W_BY_SIZE(SIZE);                                             \
+     469             :   } while (0)
+     470             : 
+     471             : #define ADD_VEX_W(EXP)                                                   \
+     472             :   do {                                                                   \
+     473             :     opCode |= static_cast<uint32_t>(EXP) << X86Inst::kOpCode_W_Shift;    \
+     474             :   } while (0)
+     475             : 
+     476             : #define EMIT_PP(OPCODE)                                                  \
+     477             :   do {                                                                   \
+     478             :     uint32_t ppIndex =                                                   \
+     479             :       ((OPCODE                   ) >> X86Inst::kOpCode_PP_Shift) &       \
+     480             :       (X86Inst::kOpCode_PP_FPUMask >> X86Inst::kOpCode_PP_Shift) ;       \
+     481             :     uint8_t ppCode = x86OpCodePP[ppIndex];                               \
+     482             :                                                                          \
+     483             :     cursor[0] = ppCode;                                                  \
+     484             :     cursor   += ppIndex != 0;                                            \
+     485             :   } while (0)
+     486             : 
+     487             : #define EMIT_MM_OP(OPCODE)                                               \
+     488             :   do {                                                                   \
+     489             :     uint32_t op = OPCODE & (0x00FF | X86Inst::kOpCode_MM_Mask);          \
+     490             :                                                                          \
+     491             :     uint32_t mmIndex = op >> X86Inst::kOpCode_MM_Shift;                  \
+     492             :     const X86OpCodeMM& mmCode = x86OpCodeMM[mmIndex];                    \
+     493             :                                                                          \
+     494             :     if (mmIndex) {                                                       \
+     495             :       cursor[0] = mmCode.data[0];                                        \
+     496             :       cursor[1] = mmCode.data[1];                                        \
+     497             :       cursor   += mmCode.len;                                            \
+     498             :     }                                                                    \
+     499             :                                                                          \
+     500             :     EMIT_BYTE(op);                                                       \
+     501             :   } while (0)
+     502             : 
+     503             : // If the operand is BPL|SPL|SIL|DIL|R8B-15B
+     504             : //   - Force REX prefix
+     505             : // If the operand is AH|BH|CH|DH
+     506             : //   - patch its index from 0..3 to 4..7 as encoded by X86.
+     507             : //   - Disallow REX prefix.
+     508             : #define FIXUP_GPB(REG_OP, REG_ID)                                   \
+     509             :   do {                                                                   \
+     510             :     if (!static_cast<const X86Gp&>(REG_OP).isGpbHi()) {                  \
+     511             :       options |= (REG_ID >= 4) ? X86Inst::kOptionRex : 0;                \
+     512             :     }                                                                    \
+     513             :     else {                                                               \
+     514             :       options |= X86Inst::_kOptionInvalidRex;                            \
+     515             :       REG_ID += 4;                                                       \
+     516             :     }                                                                    \
+     517             :   } while (0)
+     518             : 
+     519             : #define ENC_OPS1(OP0)                     ((Operand::kOp##OP0))
+     520             : #define ENC_OPS2(OP0, OP1)                ((Operand::kOp##OP0) + ((Operand::kOp##OP1) << 3))
+     521             : #define ENC_OPS3(OP0, OP1, OP2)           ((Operand::kOp##OP0) + ((Operand::kOp##OP1) << 3) + ((Operand::kOp##OP2) << 6))
+     522             : #define ENC_OPS4(OP0, OP1, OP2, OP3)      ((Operand::kOp##OP0) + ((Operand::kOp##OP1) << 3) + ((Operand::kOp##OP2) << 6) + ((Operand::kOp##OP3) << 9))
+     523             : 
+     524             : // ============================================================================
+     525             : // [asmjit::X86Assembler - Emit]
+     526             : // ============================================================================
+     527             : 
+     528       48362 : Error X86Assembler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+     529             :   Error err;
+     530             : 
+     531             :   const Operand_* rmRel;         // Memory operand or operand that holds Label|Imm.
+     532             :   uint32_t rmInfo;               // Memory operand's info based on x86MemInfo.
+     533             :   uint32_t rbReg;                // Memory base or modRM register.
+     534             :   uint32_t rxReg;                // Memory index register.
+     535             :   uint32_t opReg;                // ModR/M opcode or register id.
+     536             :   uint32_t opCode;               // Instruction opcode.
+     537             : 
+     538             :   LabelEntry* label;             // Label entry.
+     539       48362 :   RelocEntry* re = nullptr;      // Relocation entry.
+     540             :   int32_t relOffset;             // Relative offset
+     541             :   FastUInt8 relSize = 0;         // Relative size.
+     542             : 
+     543             :   int64_t imVal = 0;             // Immediate value (must be 64-bit).
+     544             :   FastUInt8 imLen = 0;           // Immediate length.
+     545             : 
+     546             :   const uint32_t kSHR_W_PP = X86Inst::kOpCode_PP_Shift - 16;
+     547             :   const uint32_t kSHR_W_EW = X86Inst::kOpCode_EW_Shift - 23;
+     548             : 
+     549       48362 :   uint8_t* cursor = _bufferPtr;
+     550       48362 :   uint32_t options = static_cast<uint32_t>(instId >= X86Inst::_kIdCount)       |
+     551       48362 :                      static_cast<uint32_t>((size_t)(_bufferEnd - cursor) < 16) |
+     552       48362 :                      getGlobalOptions() | getOptions();
+     553             : 
+     554       48362 :   const X86Inst* instData = X86InstDB::instData + instId;
+     555             :   const X86Inst::CommonData* commonData;
+     556             : 
+     557             :   // Handle failure and rare cases first.
+     558             :   const uint32_t kErrorsAndSpecialCases =
+     559             :     CodeEmitter::kOptionMaybeFailureCase | // Error and buffer check.
+     560             :     CodeEmitter::kOptionStrictValidation | // Strict validation.
+     561             :     X86Inst::kOptionRep                  | // REP/REPZ prefix.
+     562             :     X86Inst::kOptionRepnz                | // REPNZ prefix.
+     563             :     X86Inst::kOptionLock                 | // LOCK prefix.
+     564             :     X86Inst::kOptionXAcquire             | // XACQUIRE prefix.
+     565             :     X86Inst::kOptionXRelease             ; // XRELEASE prefix.
+     566             : 
+     567             :   // Signature of the first 3 operands.
+     568       48362 :   uint32_t isign3 = o0.getOp() + (o1.getOp() << 3) + (o2.getOp() << 6);
+     569             : 
+     570       48362 :   if (ASMJIT_UNLIKELY(options & kErrorsAndSpecialCases)) {
+     571             :     // Don't do anything if we are in error state.
+     572        1948 :     if (_lastError) return _lastError;
+     573             : 
+     574        1948 :     if (options & CodeEmitter::kOptionMaybeFailureCase) {
+     575             :       // Unknown instruction.
+     576        1948 :       if (ASMJIT_UNLIKELY(instId >= X86Inst::_kIdCount))
+     577           0 :         goto InvalidArgument;
+     578             : 
+     579             :       // Grow request, happens rarely.
+     580        1948 :       if ((size_t)(_bufferEnd - cursor) < 16) {
+     581        1948 :         err = _code->growBuffer(&_section->_buffer, 16);
+     582        1948 :         if (ASMJIT_UNLIKELY(err)) goto Failed;
+     583             : 
+     584        1948 :         cursor = _bufferPtr;
+     585        1948 :         options &= ~1;
+     586             :       }
+     587             :     }
+     588             : 
+     589             :     // Strict validation.
+     590             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+     591        1948 :     if (options & CodeEmitter::kOptionStrictValidation) {
+     592             :       Operand_ opArray[6];
+     593             : 
+     594             :       opArray[0].copyFrom(o0);
+     595             :       opArray[1].copyFrom(o1);
+     596             :       opArray[2].copyFrom(o2);
+     597             :       opArray[3].copyFrom(o3);
+     598             : 
+     599           0 :       if (options & kOptionOp4Op5Used) {
+     600             :         opArray[4].copyFrom(_op4);
+     601             :         opArray[5].copyFrom(_op5);
+     602             :       }
+     603             :       else {
+     604             :         opArray[4].reset();
+     605             :         opArray[5].reset();
+     606             :       }
+     607             : 
+     608           0 :       err = Inst::validate(getArchType(), Inst::Detail(instId, options, _extraReg), opArray, 6);
+     609           0 :       if (ASMJIT_UNLIKELY(err)) goto Failed;
+     610             :     }
+     611             : #endif // !ASMJIT_DISABLE_VALIDATION
+     612             : 
+     613             :     uint32_t iFlags = instData->getFlags();
+     614             : 
+     615             :     // LOCK, XACQUIRE, and XRELEASE prefixes.
+     616        1948 :     if (options & X86Inst::kOptionLock) {
+     617           0 :       bool xAcqRel = (options & (X86Inst::kOptionXAcquire | X86Inst::kOptionXRelease)) != 0;
+     618             : 
+     619           0 :       if (ASMJIT_UNLIKELY(!(iFlags & (X86Inst::kFlagLock)) && !xAcqRel))
+     620           0 :         goto InvalidLockPrefix;
+     621             : 
+     622           0 :       if (xAcqRel) {
+     623           0 :         if (ASMJIT_UNLIKELY((options & X86Inst::kOptionXAcquire) && !(iFlags & X86Inst::kFlagXAcquire)))
+     624           0 :           goto InvalidXAcquirePrefix;
+     625             : 
+     626           0 :         if (ASMJIT_UNLIKELY((options & X86Inst::kOptionXRelease) && !(iFlags & X86Inst::kFlagXRelease)))
+     627           0 :           goto InvalidXReleasePrefix;
+     628             : 
+     629           0 :         EMIT_BYTE((options & X86Inst::kOptionXAcquire) ? 0xF2 : 0xF3);
+     630             :       }
+     631             : 
+     632           0 :       EMIT_BYTE(0xF0);
+     633             :     }
+     634             : 
+     635             :     // REP and REPNZ prefixes.
+     636        1948 :     if (options & (X86Inst::kOptionRep | X86Inst::kOptionRepnz)) {
+     637           0 :       if (ASMJIT_UNLIKELY(!(iFlags & (X86Inst::kFlagRep | X86Inst::kFlagRepnz))))
+     638           0 :         goto InvalidRepPrefix;
+     639             : 
+     640           0 :       if (_extraReg.isValid() && ASMJIT_UNLIKELY(_extraReg.getKind() != X86Reg::kKindGp || _extraReg.getId() != X86Gp::kIdCx))
+     641           0 :         goto InvalidRepPrefix;
+     642             : 
+     643           0 :       EMIT_BYTE((options & X86Inst::kOptionRepnz) ? 0xF2 : 0xF3);
+     644             :     }
+     645             :   }
+     646             : 
+     647             :   // --------------------------------------------------------------------------
+     648             :   // [Encoding Scope]
+     649             :   // --------------------------------------------------------------------------
+     650             : 
+     651             :   opCode = instData->getMainOpCode();
+     652             :   opReg = x86ExtractO(opCode);
+     653             :   commonData = &instData->getCommonData();
+     654             : 
+     655       48362 :   switch (instData->getEncodingType()) {
+     656           0 :     case X86Inst::kEncodingNone:
+     657           0 :       goto EmitDone;
+     658             : 
+     659             :     // ------------------------------------------------------------------------
+     660             :     // [X86]
+     661             :     // ------------------------------------------------------------------------
+     662             : 
+     663           0 :     case X86Inst::kEncodingX86Op:
+     664           0 :       goto EmitX86Op;
+     665             : 
+     666           0 :     case X86Inst::kEncodingX86Op_O_I8:
+     667           0 :       if (ASMJIT_UNLIKELY(isign3 != ENC_OPS1(Imm)))
+     668           0 :         goto InvalidInstruction;
+     669             : 
+     670           0 :       imVal = o0.as<Imm>().getUInt8();
+     671             :       imLen = 1;
+     672             :       ASMJIT_FALLTHROUGH;
+     673             : 
+     674           0 :     case X86Inst::kEncodingX86Op_O:
+     675             :       rbReg = 0;
+     676           0 :       goto EmitX86R;
+     677             : 
+     678           0 :     case X86Inst::kEncodingX86Op_xAX:
+     679           0 :       if (isign3 == 0)
+     680           0 :         goto EmitX86Op;
+     681             : 
+     682           0 :       if (isign3 == ENC_OPS1(Reg) && o0.getId() == X86Gp::kIdAx)
+     683           0 :         goto EmitX86Op;
+     684             :       break;
+     685             : 
+     686           0 :     case X86Inst::kEncodingX86Op_xDX_xAX:
+     687           0 :       if (isign3 == 0)
+     688           0 :         goto EmitX86Op;
+     689             : 
+     690           0 :       if (isign3 == ENC_OPS2(Reg, Reg) && o0.getId() == X86Gp::kIdDx &&
+     691             :                                           o1.getId() == X86Gp::kIdAx)
+     692           0 :         goto EmitX86Op;
+     693             :       break;
+     694             : 
+     695           0 :     case X86Inst::kEncodingX86Op_ZAX:
+     696           0 :       if (isign3 == 0)
+     697           0 :         goto EmitX86Op;
+     698             : 
+     699             :       rmRel = &o0;
+     700           0 :       if (isign3 == ENC_OPS1(Mem) && x86IsImplicitMem(o0, X86Gp::kIdAx))
+     701           0 :         goto EmitX86OpImplicitMem;
+     702             : 
+     703             :       break;
+     704             : 
+     705           0 :     case X86Inst::kEncodingX86I_xAX:
+     706             :       // Implicit form.
+     707           0 :       if (isign3 == ENC_OPS1(Imm)) {
+     708           0 :         imVal = o0.as<Imm>().getUInt8();
+     709             :         imLen = 1;
+     710           0 :         goto EmitX86Op;
+     711             :       }
+     712             : 
+     713             :       // Explicit form.
+     714           0 :       if (isign3 == ENC_OPS2(Reg, Imm) && o0.getId() == X86Gp::kIdAx) {
+     715           0 :         imVal = o1.as<Imm>().getUInt8();
+     716             :         imLen = 1;
+     717           0 :         goto EmitX86Op;
+     718             :       }
+     719             :       break;
+     720             : 
+     721             :     case X86Inst::kEncodingX86M:
+     722             :       rbReg = o0.getId();
+     723           0 :       ADD_PREFIX_BY_SIZE(o0.getSize());
+     724             : 
+     725           0 :       if (isign3 == ENC_OPS1(Reg))
+     726           0 :         goto EmitX86R;
+     727             : 
+     728             :       rmRel = &o0;
+     729           0 :       if (isign3 == ENC_OPS1(Mem))
+     730           0 :         goto EmitX86M;
+     731             :       break;
+     732             : 
+     733             :     case X86Inst::kEncodingX86M_GPB_MulDiv:
+     734           0 : CaseX86M_GPB_MulDiv:
+     735             :       // Explicit form?
+     736           0 :       if (isign3 > 0x7) {
+     737             :         // [AX] <- [AX] div|mul r8.
+     738           0 :         if (isign3 == ENC_OPS2(Reg, Reg)) {
+     739           0 :           if (ASMJIT_UNLIKELY(!X86Reg::isGpw(o0, X86Gp::kIdAx) || !X86Reg::isGpb(o1)))
+     740           0 :             goto InvalidInstruction;
+     741             : 
+     742             :           rbReg = o1.getId();
+     743           0 :           FIXUP_GPB(o1, rbReg);
+     744           0 :           goto EmitX86R;
+     745             :         }
+     746             : 
+     747             :         // [AX] <- [AX] div|mul m8.
+     748           0 :         if (isign3 == ENC_OPS2(Reg, Mem)) {
+     749           0 :           if (ASMJIT_UNLIKELY(!X86Reg::isGpw(o0, X86Gp::kIdAx)))
+     750           0 :             goto InvalidInstruction;
+     751             : 
+     752             :           rmRel = &o1;
+     753           0 :           goto EmitX86M;
+     754             :         }
+     755             : 
+     756             :         // [?DX:?AX] <- [?DX:?AX] div|mul r16|r32|r64
+     757           0 :         if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
+     758           0 :           if (ASMJIT_UNLIKELY(o0.getSize() != o1.getSize()))
+     759           0 :             goto InvalidInstruction;
+     760             :           rbReg = o2.getId();
+     761             : 
+     762           0 :           opCode++;
+     763           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+     764           0 :           goto EmitX86R;
+     765             :         }
+     766             : 
+     767             :         // [?DX:?AX] <- [?DX:?AX] div|mul m16|m32|m64
+     768           0 :         if (isign3 == ENC_OPS3(Reg, Reg, Mem)) {
+     769           0 :           if (ASMJIT_UNLIKELY(o0.getSize() != o1.getSize()))
+     770           0 :             goto InvalidInstruction;
+     771             :           rmRel = &o2;
+     772             : 
+     773           0 :           opCode++;
+     774           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+     775           0 :           goto EmitX86M;
+     776             :         }
+     777             : 
+     778           0 :         goto InvalidInstruction;
+     779             :       }
+     780             : 
+     781             :       ASMJIT_FALLTHROUGH;
+     782             : 
+     783             :     case X86Inst::kEncodingX86M_GPB:
+     784           0 :       if (isign3 == ENC_OPS1(Reg)) {
+     785             :         rbReg = o0.getId();
+     786           0 :         if (o0.getSize() == 1) {
+     787           0 :           FIXUP_GPB(o0, rbReg);
+     788           0 :           goto EmitX86R;
+     789             :         }
+     790             :         else {
+     791           0 :           opCode++;
+     792           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+     793           0 :           goto EmitX86R;
+     794             :         }
+     795             :       }
+     796             : 
+     797           0 :       if (isign3 == ENC_OPS1(Mem)) {
+     798           0 :         if (ASMJIT_UNLIKELY(o0.getSize() == 0))
+     799           0 :           goto AmbiguousOperandSize;
+     800             :         rmRel = &o0;
+     801             : 
+     802           0 :         opCode += o0.getSize() != 1;
+     803           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+     804           0 :         goto EmitX86M;
+     805             :       }
+     806             :       break;
+     807             : 
+     808           0 :     case X86Inst::kEncodingX86M_Only:
+     809           0 :       if (isign3 == ENC_OPS1(Mem)) {
+     810             :         rmRel = &o0;
+     811           0 :         goto EmitX86M;
+     812             :       }
+     813             :       break;
+     814             : 
+     815             :     case X86Inst::kEncodingX86Rm:
+     816           0 :       ADD_PREFIX_BY_SIZE(o0.getSize());
+     817             :       ASMJIT_FALLTHROUGH;
+     818             : 
+     819             :     case X86Inst::kEncodingX86Rm_NoRexW:
+     820           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+     821             :         opReg = o0.getId();
+     822             :         rbReg = o1.getId();
+     823           0 :         goto EmitX86R;
+     824             :       }
+     825             : 
+     826           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+     827             :         opReg = o0.getId();
+     828             :         rmRel = &o1;
+     829           0 :         goto EmitX86M;
+     830             :       }
+     831             :       break;
+     832             : 
+     833           0 :     case X86Inst::kEncodingX86Rm_Raw66H:
+     834             :       // We normally emit either [66|F2|F3], this instruction requires 66+[F2|F3].
+     835           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+     836             :         opReg = o0.getId();
+     837             :         rbReg = o1.getId();
+     838             : 
+     839           0 :         if (o0.getSize() == 2)
+     840           0 :           EMIT_BYTE(0x66);
+     841             :         else
+     842           0 :           ADD_REX_W_BY_SIZE(o0.getSize());
+     843           0 :         goto EmitX86R;
+     844             :       }
+     845             : 
+     846           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+     847             :         opReg = o0.getId();
+     848             :         rmRel = &o1;
+     849             : 
+     850           0 :         if (o0.getSize() == 2)
+     851           0 :           EMIT_BYTE(0x66);
+     852             :         else
+     853           0 :           ADD_REX_W_BY_SIZE(o0.getSize());
+     854           0 :         goto EmitX86M;
+     855             :       }
+     856             :       break;
+     857             : 
+     858             :     case X86Inst::kEncodingX86Mr:
+     859           0 :       ADD_PREFIX_BY_SIZE(o0.getSize());
+     860             :       ASMJIT_FALLTHROUGH;
+     861             : 
+     862             :     case X86Inst::kEncodingX86Mr_NoSize:
+     863           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+     864             :         rbReg = o0.getId();
+     865             :         opReg = o1.getId();
+     866           0 :         goto EmitX86R;
+     867             :       }
+     868             : 
+     869           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+     870             :         rmRel = &o0;
+     871             :         opReg = o1.getId();
+     872           0 :         goto EmitX86M;
+     873             :       }
+     874             :       break;
+     875             : 
+     876        1864 :     case X86Inst::kEncodingX86Arith:
+     877        1864 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+     878           0 :         if (o0.getSize() != o1.getSize())
+     879           0 :           goto OperandSizeMismatch;
+     880             : 
+     881             :         opReg = o0.getId();
+     882             :         rbReg = o1.getId();
+     883             : 
+     884           0 :         if (o0.getSize() == 1) {
+     885           0 :           opCode += 2;
+     886           0 :           FIXUP_GPB(o0, opReg);
+     887           0 :           FIXUP_GPB(o1, rbReg);
+     888             : 
+     889           0 :           if (!(options & X86Inst::kOptionModMR))
+     890           0 :             goto EmitX86R;
+     891             : 
+     892             :           opCode -= 2;
+     893             :           Utils::swap(opReg, rbReg);
+     894           0 :           goto EmitX86R;
+     895             :         }
+     896             :         else {
+     897           0 :           opCode += 3;
+     898           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+     899             : 
+     900           0 :           if (!(options & X86Inst::kOptionModMR))
+     901           0 :             goto EmitX86R;
+     902             : 
+     903           0 :           opCode -= 2;
+     904             :           Utils::swap(opReg, rbReg);
+     905           0 :           goto EmitX86R;
+     906             :         }
+     907             :       }
+     908             : 
+     909        1864 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+     910             :         opReg = o0.getId();
+     911             :         rmRel = &o1;
+     912             : 
+     913           0 :         if (o0.getSize() == 1) {
+     914           0 :           FIXUP_GPB(o0, opReg);
+     915           0 :           opCode += 2;
+     916           0 :           goto EmitX86M;
+     917             :         }
+     918             :         else {
+     919           0 :           opCode += 3;
+     920           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+     921           0 :           goto EmitX86M;
+     922             :         }
+     923             :       }
+     924             : 
+     925        1864 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+     926             :         opReg = o1.getId();
+     927             :         rmRel = &o0;
+     928             : 
+     929           0 :         if (o1.getSize() == 1) {
+     930           0 :           FIXUP_GPB(o1, opReg);
+     931           0 :           goto EmitX86M;
+     932             :         }
+     933             :         else {
+     934           0 :           opCode++;
+     935           0 :           ADD_PREFIX_BY_SIZE(o1.getSize());
+     936           0 :           goto EmitX86M;
+     937             :         }
+     938             :       }
+     939             : 
+     940             :       // The remaining instructions use 0x80 opcode.
+     941             :       opCode = 0x80;
+     942             : 
+     943        1864 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+     944        1864 :         uint32_t size = o0.getSize();
+     945             : 
+     946             :         rbReg = o0.getId();
+     947             :         imVal = static_cast<const Imm&>(o1).getInt64();
+     948             : 
+     949        1864 :         if (size == 1) {
+     950           0 :           FIXUP_GPB(o0, rbReg);
+     951             :           imLen = 1;
+     952             :         }
+     953             :         else {
+     954        1864 :           if (size == 2) {
+     955             :             ADD_66H_P(1);
+     956             :           }
+     957        1864 :           else if (size == 4) {
+     958             :             // Sign extend so isInt8 returns the right result.
+     959             :             imVal = x86SignExtend32To64(imVal);
+     960             :           }
+     961        1864 :           else if (size == 8) {
+     962             :             // In 64-bit mode it's not possible to use 64-bit immediate.
+     963        1864 :             if (Utils::isUInt32(imVal)) {
+     964             :               // Zero-extend `and` by using a 32-bit GPD destination instead of a 64-bit GPQ.
+     965        1864 :               if (instId == X86Inst::kIdAnd)
+     966           0 :                 size = 4;
+     967        1864 :               else if (!Utils::isInt32(imVal))
+     968           0 :                 goto InvalidImmediate;
+     969             :             }
+     970        1864 :             ADD_REX_W_BY_SIZE(size);
+     971             :           }
+     972             : 
+     973        3728 :           imLen = std::min<uint32_t>(size, 4);
+     974        1864 :           if (Utils::isInt8(imVal) && !(options & X86Inst::kOptionLongForm))
+     975             :             imLen = 1;
+     976             :         }
+     977             : 
+     978             :         // Alternate Form - AL, AX, EAX, RAX.
+     979        1864 :         if (rbReg == 0 && (size == 1 || imLen != 1) && !(options & X86Inst::kOptionLongForm)) {
+     980           0 :           opCode &= X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_W;
+     981           0 :           opCode |= ((opReg << 3) | (0x04 + (size != 1)));
+     982           0 :           imLen = std::min<uint32_t>(size, 4);
+     983           0 :           goto EmitX86Op;
+     984             :         }
+     985             : 
+     986        1864 :         opCode += size != 1 ? (imLen != 1 ? 1 : 3) : 0;
+     987        1864 :         goto EmitX86R;
+     988             :       }
+     989             : 
+     990           0 :       if (isign3 == ENC_OPS2(Mem, Imm)) {
+     991           0 :         uint32_t memSize = o0.getSize();
+     992             : 
+     993           0 :         if (ASMJIT_UNLIKELY(memSize == 0))
+     994           0 :           goto AmbiguousOperandSize;
+     995             : 
+     996             :         imVal = static_cast<const Imm&>(o1).getInt64();
+     997           0 :         imLen = std::min<uint32_t>(memSize, 4);
+     998             : 
+     999             :         // Sign extend so isInt8 returns the right result.
+    1000           0 :         if (memSize == 4)
+    1001             :           imVal = x86SignExtend32To64(imVal);
+    1002             : 
+    1003           0 :         if (Utils::isInt8(imVal) && !(options & X86Inst::kOptionLongForm))
+    1004             :           imLen = 1;
+    1005             : 
+    1006           0 :         opCode += memSize != 1 ? (imLen != 1 ? 1 : 3) : 0;
+    1007           0 :         ADD_PREFIX_BY_SIZE(memSize);
+    1008             : 
+    1009             :         rmRel = &o0;
+    1010           0 :         goto EmitX86M;
+    1011             :       }
+    1012             :       break;
+    1013             : 
+    1014           0 :     case X86Inst::kEncodingX86Bswap:
+    1015           0 :       if (isign3 == ENC_OPS1(Reg)) {
+    1016           0 :         if (ASMJIT_UNLIKELY(o0.getSize() < 4))
+    1017           0 :           goto InvalidInstruction;
+    1018             : 
+    1019             :         opReg = o0.getId();
+    1020           0 :         ADD_REX_W_BY_SIZE(o0.getSize());
+    1021           0 :         goto EmitX86OpReg;
+    1022             :       }
+    1023             :       break;
+    1024             : 
+    1025           0 :     case X86Inst::kEncodingX86Bt:
+    1026           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    1027           0 :         ADD_PREFIX_BY_SIZE(o1.getSize());
+    1028             :         opReg = o1.getId();
+    1029             :         rbReg = o0.getId();
+    1030           0 :         goto EmitX86R;
+    1031             :       }
+    1032             : 
+    1033           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    1034           0 :         ADD_PREFIX_BY_SIZE(o1.getSize());
+    1035             :         opReg = o1.getId();
+    1036             :         rmRel = &o0;
+    1037           0 :         goto EmitX86M;
+    1038             :       }
+    1039             : 
+    1040             :       // The remaining instructions use the secondary opcode/r.
+    1041             :       imVal = static_cast<const Imm&>(o1).getInt64();
+    1042             :       imLen = 1;
+    1043             : 
+    1044             :       opCode = commonData->getAltOpCode();
+    1045             :       opReg = x86ExtractO(opCode);
+    1046           0 :       ADD_PREFIX_BY_SIZE(o0.getSize());
+    1047             : 
+    1048           0 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+    1049             :         rbReg = o0.getId();
+    1050           0 :         goto EmitX86R;
+    1051             :       }
+    1052             : 
+    1053           0 :       if (isign3 == ENC_OPS2(Mem, Imm)) {
+    1054           0 :         if (ASMJIT_UNLIKELY(o0.getSize() == 0))
+    1055           0 :           goto AmbiguousOperandSize;
+    1056             : 
+    1057             :         rmRel = &o0;
+    1058           0 :         goto EmitX86M;
+    1059             :       }
+    1060             :       break;
+    1061             : 
+    1062        1648 :     case X86Inst::kEncodingX86Call:
+    1063        1648 :       if (isign3 == ENC_OPS1(Reg)) {
+    1064             :         rbReg = o0.getId();
+    1065        1648 :         goto EmitX86R;
+    1066             :       }
+    1067             : 
+    1068             :       rmRel = &o0;
+    1069           0 :       if (isign3 == ENC_OPS1(Mem))
+    1070           0 :         goto EmitX86M;
+    1071             : 
+    1072             :       // Call with 32-bit displacement use 0xE8 opcode. Call with 8-bit
+    1073             :       // displacement is not encodable so the alternative opcode field
+    1074             :       // in X86DB must be zero.
+    1075             :       opCode = 0xE8;
+    1076             :       opReg = 0;
+    1077           0 :       goto EmitJmpCall;
+    1078             : 
+    1079           0 :     case X86Inst::kEncodingX86Cmpxchg: {
+    1080             :       // Convert explicit to implicit.
+    1081           0 :       if (isign3 & (0x7 << 6)) {
+    1082           0 :         if (!X86Reg::isGp(o2) || o2.getId() != X86Gp::kIdAx)
+    1083           0 :           goto InvalidInstruction;
+    1084           0 :         isign3 &= 0x3F;
+    1085             :       }
+    1086             : 
+    1087           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    1088           0 :         if (o0.getSize() != o1.getSize())
+    1089           0 :           goto OperandSizeMismatch;
+    1090             : 
+    1091             :         rbReg = o0.getId();
+    1092             :         opReg = o1.getId();
+    1093             : 
+    1094           0 :         if (o0.getSize() == 1) {
+    1095           0 :           FIXUP_GPB(o0, rbReg);
+    1096           0 :           FIXUP_GPB(o1, opReg);
+    1097           0 :           goto EmitX86R;
+    1098             :         }
+    1099             :         else {
+    1100           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+    1101           0 :           opCode++;
+    1102           0 :           goto EmitX86R;
+    1103             :         }
+    1104             :       }
+    1105             : 
+    1106           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    1107             :         opReg = o1.getId();
+    1108             :         rmRel = &o0;
+    1109             : 
+    1110           0 :         if (o1.getSize() == 1) {
+    1111           0 :           FIXUP_GPB(o0, opReg);
+    1112           0 :           goto EmitX86M;
+    1113             :         }
+    1114             :         else {
+    1115           0 :           ADD_PREFIX_BY_SIZE(o1.getSize());
+    1116           0 :           opCode++;
+    1117           0 :           goto EmitX86M;
+    1118             :         }
+    1119             :       }
+    1120             :       break;
+    1121             :     }
+    1122             : 
+    1123             :     case X86Inst::kEncodingX86Crc:
+    1124             :       opReg = o0.getId();
+    1125           0 :       ADD_REX_W_BY_SIZE(o0.getSize());
+    1126             : 
+    1127           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    1128             :         rbReg = o1.getId();
+    1129             : 
+    1130           0 :         if (o1.getSize() == 1) {
+    1131           0 :           FIXUP_GPB(o1, rbReg);
+    1132           0 :           goto EmitX86R;
+    1133             :         }
+    1134             :         else {
+    1135             :           // This seems to be the only exception of encoding 66F2 PP prefix.
+    1136           0 :           if (o1.getSize() == 2) EMIT_BYTE(0x66);
+    1137             : 
+    1138           0 :           opCode++;
+    1139           0 :           goto EmitX86R;
+    1140             :         }
+    1141             :       }
+    1142             : 
+    1143           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    1144             :         rmRel = &o1;
+    1145           0 :         if (o1.getSize() == 0)
+    1146           0 :           goto AmbiguousOperandSize;
+    1147             : 
+    1148             :         // This seems to be the only exception of encoding 66F2 PP prefix.
+    1149           0 :         if (o1.getSize() == 2) EMIT_BYTE(0x66);
+    1150             : 
+    1151           0 :         opCode += o1.getSize() != 1;
+    1152           0 :         goto EmitX86M;
+    1153             :       }
+    1154             :       break;
+    1155             : 
+    1156           0 :     case X86Inst::kEncodingX86Enter:
+    1157           0 :       if (isign3 == ENC_OPS2(Imm, Imm)) {
+    1158             :         uint32_t iw = static_cast<const Imm&>(o0).getUInt16();
+    1159             :         uint32_t ib = static_cast<const Imm&>(o1).getUInt8();
+    1160             : 
+    1161           0 :         imVal = iw | (ib << 16);
+    1162             :         imLen = 3;
+    1163           0 :         goto EmitX86Op;
+    1164             :       }
+    1165             :       break;
+    1166             : 
+    1167           0 :     case X86Inst::kEncodingX86Imul:
+    1168             :       // First process all forms distinct of `kEncodingX86M_OptB_MulDiv`.
+    1169           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    1170             :         opCode = 0x6B;
+    1171           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1172             : 
+    1173             :         imVal = static_cast<const Imm&>(o2).getInt64();
+    1174             :         imLen = 1;
+    1175             : 
+    1176           0 :         if (!Utils::isInt8(imVal) || (options & X86Inst::kOptionLongForm)) {
+    1177           0 :           opCode -= 2;
+    1178           0 :           imLen = o0.getSize() == 2 ? 2 : 4;
+    1179             :         }
+    1180             : 
+    1181             :         opReg = o0.getId();
+    1182             :         rbReg = o1.getId();
+    1183             : 
+    1184           0 :         goto EmitX86R;
+    1185             :       }
+    1186             : 
+    1187           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Imm)) {
+    1188             :         opCode = 0x6B;
+    1189           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1190             : 
+    1191             :         imVal = static_cast<const Imm&>(o2).getInt64();
+    1192             :         imLen = 1;
+    1193             : 
+    1194             :         // Sign extend so isInt8 returns the right result.
+    1195           0 :         if (o0.getSize() == 4)
+    1196             :           imVal = x86SignExtend32To64(imVal);
+    1197             : 
+    1198           0 :         if (!Utils::isInt8(imVal) || (options & X86Inst::kOptionLongForm)) {
+    1199           0 :           opCode -= 2;
+    1200           0 :           imLen = o0.getSize() == 2 ? 2 : 4;
+    1201             :         }
+    1202             : 
+    1203             :         opReg = o0.getId();
+    1204             :         rmRel = &o1;
+    1205             : 
+    1206           0 :         goto EmitX86M;
+    1207             :       }
+    1208             : 
+    1209           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    1210             :         // Must be explicit 'ax, r8' form.
+    1211           0 :         if (o1.getSize() == 1)
+    1212           0 :           goto CaseX86M_GPB_MulDiv;
+    1213             : 
+    1214           0 :         if (o0.getSize() != o1.getSize())
+    1215           0 :           goto OperandSizeMismatch;
+    1216             : 
+    1217             :         opReg = o0.getId();
+    1218             :         rbReg = o1.getId();
+    1219             : 
+    1220             :         opCode = X86Inst::kOpCode_MM_0F | 0xAF;
+    1221           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1222           0 :         goto EmitX86R;
+    1223             :       }
+    1224             : 
+    1225           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    1226             :         // Must be explicit 'ax, m8' form.
+    1227           0 :         if (o1.getSize() == 1)
+    1228           0 :           goto CaseX86M_GPB_MulDiv;
+    1229             : 
+    1230             :         opReg = o0.getId();
+    1231             :         rmRel = &o1;
+    1232             : 
+    1233             :         opCode = X86Inst::kOpCode_MM_0F | 0xAF;
+    1234           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1235           0 :         goto EmitX86M;
+    1236             :       }
+    1237             : 
+    1238             :       // Shorthand to imul 'reg, reg, imm'.
+    1239           0 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+    1240             :         opCode = 0x6B;
+    1241           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1242             : 
+    1243             :         imVal = static_cast<const Imm&>(o1).getInt64();
+    1244             :         imLen = 1;
+    1245             : 
+    1246             :         // Sign extend so isInt8 returns the right result.
+    1247           0 :         if (o0.getSize() == 4)
+    1248             :           imVal = x86SignExtend32To64(imVal);
+    1249             : 
+    1250           0 :         if (!Utils::isInt8(imVal) || (options & X86Inst::kOptionLongForm)) {
+    1251           0 :           opCode -= 2;
+    1252           0 :           imLen = o0.getSize() == 2 ? 2 : 4;
+    1253             :         }
+    1254             : 
+    1255             :         opReg = rbReg = o0.getId();
+    1256           0 :         goto EmitX86R;
+    1257             :       }
+    1258             : 
+    1259             :       // Try implicit form.
+    1260           0 :       goto CaseX86M_GPB_MulDiv;
+    1261             : 
+    1262           0 :     case X86Inst::kEncodingX86In:
+    1263           0 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+    1264           0 :         if (ASMJIT_UNLIKELY(o0.getId() != X86Gp::kIdAx))
+    1265           0 :           goto InvalidInstruction;
+    1266             : 
+    1267           0 :         imVal = o1.as<Imm>().getUInt8();
+    1268             :         imLen = 1;
+    1269             : 
+    1270           0 :         opCode = commonData->getAltOpCode() + (o0.getSize() != 1);
+    1271           0 :         ADD_66H_P_BY_SIZE(o0.getSize());
+    1272           0 :         goto EmitX86Op;
+    1273             :       }
+    1274             : 
+    1275           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    1276           0 :         if (ASMJIT_UNLIKELY(o0.getId() != X86Gp::kIdAx || o1.getId() != X86Gp::kIdDx))
+    1277           0 :           goto InvalidInstruction;
+    1278             : 
+    1279           0 :         opCode += o0.getSize() != 1;
+    1280           0 :         ADD_66H_P_BY_SIZE(o0.getSize());
+    1281           0 :         goto EmitX86Op;
+    1282             :       }
+    1283             :       break;
+    1284             : 
+    1285           0 :     case X86Inst::kEncodingX86Ins:
+    1286           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    1287           0 :         if (ASMJIT_UNLIKELY(!x86IsImplicitMem(o0, X86Gp::kIdDi) || o1.getId() != X86Gp::kIdDx))
+    1288           0 :           goto InvalidInstruction;
+    1289             : 
+    1290             :         uint32_t size = o0.getSize();
+    1291           0 :         if (ASMJIT_UNLIKELY(size == 0))
+    1292           0 :           goto AmbiguousOperandSize;
+    1293             : 
+    1294             :         rmRel = &o0;
+    1295           0 :         opCode += (size != 1);
+    1296             : 
+    1297           0 :         ADD_66H_P_BY_SIZE(size);
+    1298           0 :         goto EmitX86OpImplicitMem;
+    1299             :       }
+    1300             :       break;
+    1301             : 
+    1302           0 :     case X86Inst::kEncodingX86IncDec:
+    1303           0 :       if (isign3 == ENC_OPS1(Reg)) {
+    1304             :         rbReg = o0.getId();
+    1305             : 
+    1306           0 :         if (o0.getSize() == 1) {
+    1307           0 :           FIXUP_GPB(o0, rbReg);
+    1308           0 :           goto EmitX86R;
+    1309             :         }
+    1310             : 
+    1311           0 :         if (is32Bit()) {
+    1312             :           // INC r16|r32 is only encodable in 32-bit mode (collides with REX).
+    1313           0 :           opCode = commonData->getAltOpCode() + (rbReg & 0x07);
+    1314           0 :           ADD_66H_P_BY_SIZE(o0.getSize());
+    1315           0 :           goto EmitX86Op;
+    1316             :         }
+    1317             :         else {
+    1318           0 :           opCode++;
+    1319           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+    1320           0 :           goto EmitX86R;
+    1321             :         }
+    1322             :       }
+    1323             : 
+    1324           0 :       if (isign3 == ENC_OPS1(Mem)) {
+    1325             :         rmRel = &o0;
+    1326           0 :         opCode += o0.getSize() != 1;
+    1327             : 
+    1328           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1329           0 :         goto EmitX86M;
+    1330             :       }
+    1331             :       break;
+    1332             : 
+    1333           0 :     case X86Inst::kEncodingX86Int:
+    1334           0 :       if (isign3 == ENC_OPS1(Imm)) {
+    1335             :         imVal = static_cast<const Imm&>(o0).getInt64();
+    1336             :         imLen = 1;
+    1337           0 :         goto EmitX86Op;
+    1338             :       }
+    1339             :       break;
+    1340             : 
+    1341           0 :     case X86Inst::kEncodingX86Jcc:
+    1342           0 :       if (_globalHints & CodeEmitter::kHintPredictedJumps) {
+    1343           0 :         if (options & X86Inst::kOptionTaken)
+    1344           0 :           EMIT_BYTE(0x3E);
+    1345           0 :         if (options & X86Inst::kOptionNotTaken)
+    1346           0 :           EMIT_BYTE(0x2E);
+    1347             :       }
+    1348             : 
+    1349             :       rmRel = &o0;
+    1350             :       opReg = 0;
+    1351           0 :       goto EmitJmpCall;
+    1352             : 
+    1353           0 :     case X86Inst::kEncodingX86JecxzLoop:
+    1354             :       rmRel = &o0;
+    1355             :       // Explicit jecxz|loop [r|e]cx, dst
+    1356           0 :       if (o0.isReg()) {
+    1357           0 :         if (ASMJIT_UNLIKELY(!X86Reg::isGp(o0, X86Gp::kIdCx)))
+    1358           0 :           goto InvalidInstruction;
+    1359             : 
+    1360           0 :         if ((is32Bit() && o0.getSize() == 2) || (is64Bit() && o0.getSize() == 4))
+    1361           0 :           EMIT_BYTE(0x67);
+    1362             : 
+    1363             :         rmRel = &o1;
+    1364             :       }
+    1365             : 
+    1366             :       opReg = 0;
+    1367           0 :       goto EmitJmpCall;
+    1368             : 
+    1369           0 :     case X86Inst::kEncodingX86Jmp:
+    1370           0 :       if (isign3 == ENC_OPS1(Reg)) {
+    1371             :         rbReg = o0.getId();
+    1372           0 :         goto EmitX86R;
+    1373             :       }
+    1374             : 
+    1375             :       rmRel = &o0;
+    1376           0 :       if (isign3 == ENC_OPS1(Mem))
+    1377           0 :         goto EmitX86M;
+    1378             : 
+    1379             :       // Jump encoded with 32-bit displacement use 0xE9 opcode. Jump encoded
+    1380             :       // with 8-bit displacement's opcode is stored as an alternative opcode.
+    1381             :       opCode = 0xE9;
+    1382             :       opReg = 0;
+    1383           0 :       goto EmitJmpCall;
+    1384             : 
+    1385           0 :     case X86Inst::kEncodingX86JmpRel:
+    1386             :       rmRel = &o0;
+    1387           0 :       goto EmitJmpCall;
+    1388             : 
+    1389           0 :     case X86Inst::kEncodingX86Lea:
+    1390           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    1391           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1392             :         opReg = o0.getId();
+    1393             :         rmRel = &o1;
+    1394           0 :         goto EmitX86M;
+    1395             :       }
+    1396             :       break;
+    1397             : 
+    1398        7688 :     case X86Inst::kEncodingX86Mov:
+    1399             :       // Reg <- Reg
+    1400        7688 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    1401             :         opReg = o0.getId();
+    1402             :         rbReg = o1.getId();
+    1403             : 
+    1404             :         // Asmjit uses segment registers indexed from 1 to 6, leaving zero as
+    1405             :         // "no segment register used". We have to fix this (decrement the index
+    1406             :         // of the register) when emitting MOV instructions which move to/from
+    1407             :         // a segment register. The segment register is always `opReg`, because
+    1408             :         // the MOV instruction uses either RM or MR encoding.
+    1409             : 
+    1410             :         // GP <- ??
+    1411           0 :         if (X86Reg::isGp(o0)) {
+    1412             :           // GP <- GP
+    1413           0 :           if (X86Reg::isGp(o1)) {
+    1414             :             uint32_t size0 = o0.getSize();
+    1415             :             uint32_t size1 = o1.getSize();
+    1416             : 
+    1417           0 :             if (size0 != size1) {
+    1418             :               // We allow 'mov r64, r32' as it's basically zero-extend.
+    1419           0 :               if (size0 == 8 && size1 == 4)
+    1420             :                 size0 = 4; // Zero extend, don't promote to 64-bit.
+    1421             :               else
+    1422           0 :                 goto InvalidInstruction;
+    1423             :             }
+    1424             : 
+    1425           0 :             if (size0 == 1) {
+    1426           0 :               FIXUP_GPB(o0, opReg);
+    1427           0 :               FIXUP_GPB(o1, rbReg);
+    1428             :               opCode = 0x8A;
+    1429             : 
+    1430           0 :               if (!(options & X86Inst::kOptionModMR))
+    1431           0 :                 goto EmitX86R;
+    1432             : 
+    1433             :               opCode -= 2;
+    1434             :               Utils::swap(opReg, rbReg);
+    1435           0 :               goto EmitX86R;
+    1436             :             }
+    1437             :             else {
+    1438             :               opCode = 0x8B;
+    1439           0 :               ADD_PREFIX_BY_SIZE(size0);
+    1440             : 
+    1441           0 :               if (!(options & X86Inst::kOptionModMR))
+    1442           0 :                 goto EmitX86R;
+    1443             : 
+    1444           0 :               opCode -= 2;
+    1445             :               Utils::swap(opReg, rbReg);
+    1446           0 :               goto EmitX86R;
+    1447             :             }
+    1448             :           }
+    1449             : 
+    1450             :           opReg = rbReg;
+    1451             :           rbReg = o0.getId();
+    1452             : 
+    1453             :           // GP <- SEG
+    1454           0 :           if (X86Reg::isSeg(o1)) {
+    1455             :             opCode = 0x8C;
+    1456           0 :             opReg--;
+    1457           0 :             ADD_PREFIX_BY_SIZE(o0.getSize());
+    1458           0 :             goto EmitX86R;
+    1459             :           }
+    1460             : 
+    1461             :           // GP <- CR
+    1462           0 :           if (X86Reg::isCr(o1)) {
+    1463             :             opCode = 0x20 | X86Inst::kOpCode_MM_0F;
+    1464             : 
+    1465             :             // Use `LOCK MOV` in 32-bit mode if CR8+ register is accessed (AMD extension).
+    1466           0 :             if ((opReg & 0x8) && is32Bit()) {
+    1467           0 :               EMIT_BYTE(0xF0);
+    1468           0 :               opReg &= 0x7;
+    1469             :             }
+    1470           0 :             goto EmitX86R;
+    1471             :           }
+    1472             : 
+    1473             :           // GP <- DR
+    1474           0 :           if (X86Reg::isDr(o1)) {
+    1475             :             opCode = 0x21 | X86Inst::kOpCode_MM_0F;
+    1476           0 :             goto EmitX86R;
+    1477             :           }
+    1478             :         }
+    1479             :         else {
+    1480             :           // ?? <- GP
+    1481           0 :           if (!X86Reg::isGp(o1))
+    1482           0 :             goto InvalidInstruction;
+    1483             : 
+    1484             :           // SEG <- GP
+    1485           0 :           if (X86Reg::isSeg(o0)) {
+    1486             :             opCode = 0x8E;
+    1487           0 :             opReg--;
+    1488           0 :             ADD_PREFIX_BY_SIZE(o1.getSize());
+    1489           0 :             goto EmitX86R;
+    1490             :           }
+    1491             : 
+    1492             :           // CR <- GP
+    1493           0 :           if (X86Reg::isCr(o0)) {
+    1494             :             opCode = 0x22 | X86Inst::kOpCode_MM_0F;
+    1495             : 
+    1496             :             // Use `LOCK MOV` in 32-bit mode if CR8+ register is accessed (AMD extension).
+    1497           0 :             if ((opReg & 0x8) && is32Bit()) {
+    1498           0 :               EMIT_BYTE(0xF0);
+    1499           0 :               opReg &= 0x7;
+    1500             :             }
+    1501           0 :             goto EmitX86R;
+    1502             :           }
+    1503             : 
+    1504             :           // DR <- GP
+    1505           0 :           if (X86Reg::isDr(o0)) {
+    1506             :             opCode = 0x23 | X86Inst::kOpCode_MM_0F;
+    1507           0 :             goto EmitX86R;
+    1508             :           }
+    1509             :         }
+    1510             : 
+    1511           0 :         goto InvalidInstruction;
+    1512             :       }
+    1513             : 
+    1514        7688 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    1515             :         opReg = o0.getId();
+    1516             :         rmRel = &o1;
+    1517             : 
+    1518             :         // SEG <- Mem
+    1519           0 :         if (X86Reg::isSeg(o0)) {
+    1520             :           opCode = 0x8E;
+    1521           0 :           opReg--;
+    1522           0 :           ADD_PREFIX_BY_SIZE(o1.getSize());
+    1523           0 :           goto EmitX86M;
+    1524             :         }
+    1525             :         // Reg <- Mem
+    1526             :         else {
+    1527           0 :           if (o0.getSize() == 1) {
+    1528             :             opCode = 0;
+    1529           0 :             FIXUP_GPB(o0, opReg);
+    1530             :           }
+    1531             :           else {
+    1532             :             opCode = 1;
+    1533           0 :             ADD_PREFIX_BY_SIZE(o0.getSize());
+    1534             :           }
+    1535             : 
+    1536             :           // Handle a special form `mov al|ax|eax|rax, [ptr64]` that doesn't use MOD.
+    1537           0 :           if (o0.getId() == X86Gp::kIdAx && !rmRel->as<X86Mem>().hasBaseOrIndex()) {
+    1538             :             imVal = rmRel->as<X86Mem>().getOffset();
+    1539           0 :             if (!is64Bit() || (is64Bit() && ((options & X86Inst::kOptionLongForm) || !Utils::isInt32(imVal)))) {
+    1540           0 :               opCode += 0xA0;
+    1541           0 :               goto EmitX86OpMovAbs;
+    1542             :             }
+    1543             :           }
+    1544             : 
+    1545           0 :           opCode += 0x8A;
+    1546           0 :           goto EmitX86M;
+    1547             :         }
+    1548             :       }
+    1549             : 
+    1550        7688 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    1551             :         opReg = o1.getId();
+    1552             :         rmRel = &o0;
+    1553             : 
+    1554             :         // Mem <- SEG
+    1555           0 :         if (X86Reg::isSeg(o1)) {
+    1556             :           opCode = 0x8C;
+    1557           0 :           opReg--;
+    1558           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+    1559           0 :           goto EmitX86M;
+    1560             :         }
+    1561             :         // Mem <- Reg
+    1562             :         else {
+    1563           0 :           if (o1.getSize() == 1) {
+    1564             :             opCode = 0;
+    1565           0 :             FIXUP_GPB(o1, opReg);
+    1566             :           }
+    1567             :           else {
+    1568             :             opCode = 1;
+    1569           0 :             ADD_PREFIX_BY_SIZE(o1.getSize());
+    1570             :           }
+    1571             : 
+    1572             :           // Handle a special form `mov [ptr64], al|ax|eax|rax` that doesn't use MOD.
+    1573           0 :           if (o1.getId() == X86Gp::kIdAx && !rmRel->as<X86Mem>().hasBaseOrIndex()) {
+    1574             :             imVal = rmRel->as<X86Mem>().getOffset();
+    1575           0 :             if (!is64Bit() || (is64Bit() && ((options & X86Inst::kOptionLongForm) || !Utils::isInt32(imVal)))) {
+    1576           0 :               opCode += 0xA2;
+    1577           0 :               goto EmitX86OpMovAbs;
+    1578             :             }
+    1579             :           }
+    1580             : 
+    1581           0 :           opCode += 0x88;
+    1582           0 :           goto EmitX86M;
+    1583             :         }
+    1584             :       }
+    1585             : 
+    1586        7688 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+    1587             :         opReg = o0.getId();
+    1588        7688 :         imLen = o0.getSize();
+    1589             : 
+    1590        7688 :         if (imLen == 1) {
+    1591           0 :           FIXUP_GPB(o0, opReg);
+    1592             : 
+    1593           0 :           imVal = static_cast<const Imm&>(o1).getUInt8();
+    1594             :           opCode = 0xB0;
+    1595           0 :           goto EmitX86OpReg;
+    1596             :         }
+    1597             :         else {
+    1598             :           // 64-bit immediate in 64-bit mode is allowed.
+    1599             :           imVal = static_cast<const Imm&>(o1).getInt64();
+    1600             : 
+    1601             :           // Optimize the instruction size by using a 32-bit immediate if possible.
+    1602        7688 :           if (imLen == 8 && !(options & X86Inst::kOptionLongForm)) {
+    1603        7688 :             if (Utils::isUInt32(imVal)) {
+    1604             :               // Zero-extend by using a 32-bit GPD destination instead of a 64-bit GPQ.
+    1605             :               imLen = 4;
+    1606             :             }
+    1607        7688 :             else if (Utils::isInt32(imVal)) {
+    1608             :               // Sign-extend, uses 'C7 /0' opcode.
+    1609             :               rbReg = opReg;
+    1610             : 
+    1611             :               opCode = 0xC7 | X86Inst::kOpCode_W;
+    1612             :               opReg = 0;
+    1613             : 
+    1614             :               imLen = 4;
+    1615           0 :               goto EmitX86R;
+    1616             :             }
+    1617             :           }
+    1618             : 
+    1619             :           opCode = 0xB8;
+    1620        7688 :           ADD_PREFIX_BY_SIZE(imLen);
+    1621        7688 :           goto EmitX86OpReg;
+    1622             :         }
+    1623             :       }
+    1624             : 
+    1625           0 :       if (isign3 == ENC_OPS2(Mem, Imm)) {
+    1626           0 :         uint32_t memSize = o0.getSize();
+    1627             : 
+    1628           0 :         if (ASMJIT_UNLIKELY(memSize == 0))
+    1629           0 :           goto AmbiguousOperandSize;
+    1630             : 
+    1631             :         imVal = static_cast<const Imm&>(o1).getInt64();
+    1632           0 :         imLen = std::min<uint32_t>(memSize, 4);
+    1633             : 
+    1634           0 :         opCode = 0xC6 + (memSize != 1);
+    1635             :         opReg = 0;
+    1636           0 :         ADD_PREFIX_BY_SIZE(memSize);
+    1637             : 
+    1638             :         rmRel = &o0;
+    1639           0 :         goto EmitX86M;
+    1640             :       }
+    1641             :       break;
+    1642             : 
+    1643           0 :     case X86Inst::kEncodingX86MovsxMovzx:
+    1644           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    1645             :         opReg = o0.getId();
+    1646             :         rbReg = o1.getId();
+    1647           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1648             : 
+    1649           0 :         if (o1.getSize() == 1) {
+    1650           0 :           FIXUP_GPB(o1, rbReg);
+    1651           0 :           goto EmitX86R;
+    1652             :         }
+    1653             :         else {
+    1654           0 :           opCode++;
+    1655           0 :           goto EmitX86R;
+    1656             :         }
+    1657             :       }
+    1658             : 
+    1659           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    1660           0 :         opCode += o1.getSize() != 1;
+    1661           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1662             : 
+    1663             :         opReg = o0.getId();
+    1664             :         rmRel = &o1;
+    1665           0 :         goto EmitX86M;
+    1666             :       }
+    1667             :       break;
+    1668             : 
+    1669           0 :     case X86Inst::kEncodingX86Out:
+    1670           0 :       if (isign3 == ENC_OPS2(Imm, Reg)) {
+    1671           0 :         if (ASMJIT_UNLIKELY(o1.getId() != X86Gp::kIdAx))
+    1672           0 :           goto InvalidInstruction;
+    1673             : 
+    1674           0 :         imVal = o0.as<Imm>().getUInt8();
+    1675             :         imLen = 1;
+    1676             : 
+    1677           0 :         opCode = commonData->getAltOpCode() + (o1.getSize() != 1);
+    1678           0 :         ADD_66H_P_BY_SIZE(o1.getSize());
+    1679           0 :         goto EmitX86Op;
+    1680             :       }
+    1681             : 
+    1682           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    1683           0 :         if (ASMJIT_UNLIKELY(o0.getId() != X86Gp::kIdDx || o1.getId() != X86Gp::kIdAx))
+    1684           0 :           goto InvalidInstruction;
+    1685             : 
+    1686           0 :         opCode += o1.getSize() != 1;
+    1687           0 :         ADD_66H_P_BY_SIZE(o1.getSize());
+    1688           0 :         goto EmitX86Op;
+    1689             :       }
+    1690             :       break;
+    1691             : 
+    1692           0 :     case X86Inst::kEncodingX86Outs:
+    1693           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    1694           0 :         if (ASMJIT_UNLIKELY(o0.getId() != X86Gp::kIdDx || !x86IsImplicitMem(o1, X86Gp::kIdSi)))
+    1695           0 :           goto InvalidInstruction;
+    1696             : 
+    1697             :         uint32_t size = o1.getSize();
+    1698           0 :         if (ASMJIT_UNLIKELY(size == 0))
+    1699           0 :           goto AmbiguousOperandSize;
+    1700             : 
+    1701             :         rmRel = &o1;
+    1702           0 :         opCode += (size != 1);
+    1703             : 
+    1704           0 :         ADD_66H_P_BY_SIZE(size);
+    1705           0 :         goto EmitX86OpImplicitMem;
+    1706             :       }
+    1707             :       break;
+    1708             : 
+    1709        1120 :     case X86Inst::kEncodingX86Push:
+    1710        1120 :       if (isign3 == ENC_OPS1(Reg)) {
+    1711        1120 :         if (X86Reg::isSeg(o0)) {
+    1712             :           uint32_t segment = o0.getId();
+    1713           0 :           if (ASMJIT_UNLIKELY(segment >= X86Seg::kIdCount))
+    1714           0 :             goto InvalidSegment;
+    1715             : 
+    1716           0 :           if (segment >= X86Seg::kIdFs)
+    1717           0 :             EMIT_BYTE(0x0F);
+    1718             : 
+    1719           0 :           EMIT_BYTE(x86OpCodePushSeg[segment]);
+    1720           0 :           goto EmitDone;
+    1721             :         }
+    1722             :         else {
+    1723        1120 :           goto CaseX86Pop_Gp;
+    1724             :         }
+    1725             :       }
+    1726             : 
+    1727           0 :       if (isign3 == ENC_OPS1(Imm)) {
+    1728             :         imVal = static_cast<const Imm&>(o0).getInt64();
+    1729             :         imLen = 4;
+    1730             : 
+    1731           0 :         if (Utils::isInt8(imVal) && !(options & X86Inst::kOptionLongForm))
+    1732             :           imLen = 1;
+    1733             : 
+    1734             :         opCode = imLen == 1 ? 0x6A : 0x68;
+    1735           0 :         goto EmitX86Op;
+    1736             :       }
+    1737             :       ASMJIT_FALLTHROUGH;
+    1738             : 
+    1739             :     case X86Inst::kEncodingX86Pop:
+    1740        1120 :       if (isign3 == ENC_OPS1(Reg)) {
+    1741        1120 :         if (X86Reg::isSeg(o0)) {
+    1742             :           uint32_t segment = o0.getId();
+    1743           0 :           if (ASMJIT_UNLIKELY(segment == X86Seg::kIdCs || segment >= X86Seg::kIdCount))
+    1744           0 :             goto InvalidSegment;
+    1745             : 
+    1746           0 :           if (segment >= X86Seg::kIdFs)
+    1747           0 :             EMIT_BYTE(0x0F);
+    1748             : 
+    1749           0 :           EMIT_BYTE(x86OpCodePopSeg[segment]);
+    1750           0 :           goto EmitDone;
+    1751             :         }
+    1752             :         else {
+    1753        2240 : CaseX86Pop_Gp:
+    1754             :           // We allow 2 byte, 4 byte, and 8 byte register sizes, although PUSH
+    1755             :           // and POP only allow 2 bytes or native size. On 64-bit we simply
+    1756             :           // PUSH/POP 64-bit register even if 32-bit register was given.
+    1757        2240 :           if (ASMJIT_UNLIKELY(o0.getSize() < 2))
+    1758           0 :             goto InvalidInstruction;
+    1759             : 
+    1760             :           opCode = commonData->getAltOpCode();
+    1761             :           opReg = o0.getId();
+    1762             : 
+    1763        2240 :           ADD_66H_P_BY_SIZE(o0.getSize());
+    1764        2240 :           goto EmitX86OpReg;
+    1765             :         }
+    1766             :       }
+    1767             : 
+    1768           0 :       if (isign3 == ENC_OPS1(Mem)) {
+    1769           0 :         if (ASMJIT_UNLIKELY(o0.getSize() == 0))
+    1770           0 :           goto AmbiguousOperandSize;
+    1771             : 
+    1772           0 :         if (ASMJIT_UNLIKELY(o0.getSize() != 2 && o0.getSize() != getGpSize()))
+    1773           0 :           goto InvalidInstruction;
+    1774             : 
+    1775           0 :         ADD_66H_P_BY_SIZE(o0.getSize());
+    1776             :         rmRel = &o0;
+    1777           0 :         goto EmitX86M;
+    1778             :       }
+    1779             :       break;
+    1780             : 
+    1781        1948 :     case X86Inst::kEncodingX86Ret:
+    1782        1948 :       if (isign3 == 0) {
+    1783             :         // 'ret' without immediate, change C2 to C3.
+    1784        1948 :         opCode++;
+    1785        1948 :         goto EmitX86Op;
+    1786             :       }
+    1787             : 
+    1788           0 :       if (isign3 == ENC_OPS1(Imm)) {
+    1789             :         imVal = static_cast<const Imm&>(o0).getInt64();
+    1790           0 :         if (imVal == 0 && !(options & X86Inst::kOptionLongForm)) {
+    1791             :           // 'ret' without immediate, change C2 to C3.
+    1792           0 :           opCode++;
+    1793           0 :           goto EmitX86Op;
+    1794             :         }
+    1795             :         else {
+    1796             :           imLen = 2;
+    1797           0 :           goto EmitX86Op;
+    1798             :         }
+    1799             :       }
+    1800             :       break;
+    1801             : 
+    1802             :     case X86Inst::kEncodingX86Rot:
+    1803           0 :       if (o0.isReg()) {
+    1804             :         rbReg = o0.getId();
+    1805             : 
+    1806           0 :         if (o0.getSize() == 1) {
+    1807           0 :           FIXUP_GPB(o0, rbReg);
+    1808             :         }
+    1809             :         else {
+    1810           0 :           opCode++;
+    1811           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+    1812             :         }
+    1813             : 
+    1814           0 :         if (isign3 == ENC_OPS2(Reg, Reg)) {
+    1815           0 :           if (ASMJIT_UNLIKELY(o1.getId() != X86Gp::kIdCx))
+    1816           0 :             goto InvalidInstruction;
+    1817             : 
+    1818           0 :           opCode += 2;
+    1819           0 :           goto EmitX86R;
+    1820             :         }
+    1821             : 
+    1822           0 :         if (isign3 == ENC_OPS2(Reg, Imm)) {
+    1823           0 :           imVal = static_cast<const Imm&>(o1).getInt64() & 0xFF;
+    1824             :           imLen = 0;
+    1825             : 
+    1826           0 :           if (imVal == 1 && !(options & X86Inst::kOptionLongForm))
+    1827           0 :             goto EmitX86R;
+    1828             : 
+    1829             :           imLen = 1;
+    1830           0 :           opCode -= 0x10;
+    1831           0 :           goto EmitX86R;
+    1832             :         }
+    1833             :       }
+    1834             :       else {
+    1835           0 :         opCode += o0.getSize() != 1;
+    1836           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1837             : 
+    1838           0 :         if (isign3 == ENC_OPS2(Mem, Reg)) {
+    1839           0 :           if (ASMJIT_UNLIKELY(o1.getId() != X86Gp::kIdCx))
+    1840           0 :             goto InvalidInstruction;
+    1841             : 
+    1842           0 :           opCode += 2;
+    1843             :           rmRel = &o0;
+    1844           0 :           goto EmitX86M;
+    1845             :         }
+    1846             : 
+    1847           0 :         if (isign3 == ENC_OPS2(Mem, Imm)) {
+    1848           0 :           if (ASMJIT_UNLIKELY(o0.getSize() == 0))
+    1849           0 :             goto AmbiguousOperandSize;
+    1850             : 
+    1851           0 :           imVal = static_cast<const Imm&>(o1).getInt64() & 0xFF;
+    1852             :           imLen = 0;
+    1853             :           rmRel = &o0;
+    1854             : 
+    1855           0 :           if (imVal == 1 && !(options & X86Inst::kOptionLongForm))
+    1856           0 :             goto EmitX86M;
+    1857             : 
+    1858             :           imLen = 1;
+    1859           0 :           opCode -= 0x10;
+    1860           0 :           goto EmitX86M;
+    1861             :         }
+    1862             :       }
+    1863             :       break;
+    1864             : 
+    1865           0 :     case X86Inst::kEncodingX86Set:
+    1866           0 :       if (isign3 == ENC_OPS1(Reg)) {
+    1867             :         rbReg = o0.getId();
+    1868           0 :         FIXUP_GPB(o0, rbReg);
+    1869           0 :         goto EmitX86R;
+    1870             :       }
+    1871             : 
+    1872           0 :       if (isign3 == ENC_OPS1(Mem)) {
+    1873             :         rmRel = &o0;
+    1874           0 :         goto EmitX86M;
+    1875             :       }
+    1876             :       break;
+    1877             : 
+    1878           0 :     case X86Inst::kEncodingX86ShldShrd:
+    1879           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    1880           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1881             :         imVal = static_cast<const Imm&>(o2).getInt64();
+    1882             :         imLen = 1;
+    1883             : 
+    1884             :         opReg = o1.getId();
+    1885             :         rbReg = o0.getId();
+    1886           0 :         goto EmitX86R;
+    1887             :       }
+    1888             : 
+    1889           0 :       if (isign3 == ENC_OPS3(Mem, Reg, Imm)) {
+    1890           0 :         ADD_PREFIX_BY_SIZE(o1.getSize());
+    1891             :         imVal = static_cast<const Imm&>(o2).getInt64();
+    1892             :         imLen = 1;
+    1893             : 
+    1894             :         opReg = o1.getId();
+    1895             :         rmRel = &o0;
+    1896           0 :         goto EmitX86M;
+    1897             :       }
+    1898             : 
+    1899             :       // The following instructions use opCode + 1.
+    1900           0 :       opCode++;
+    1901             : 
+    1902           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
+    1903           0 :         if (ASMJIT_UNLIKELY(o2.getId() != X86Gp::kIdCx))
+    1904           0 :           goto InvalidInstruction;
+    1905             : 
+    1906           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    1907             :         opReg = o1.getId();
+    1908             :         rbReg = o0.getId();
+    1909           0 :         goto EmitX86R;
+    1910             :       }
+    1911             : 
+    1912           0 :       if (isign3 == ENC_OPS3(Mem, Reg, Reg)) {
+    1913           0 :         if (ASMJIT_UNLIKELY(o2.getId() != X86Gp::kIdCx))
+    1914           0 :           goto InvalidInstruction;
+    1915             : 
+    1916           0 :         ADD_PREFIX_BY_SIZE(o1.getSize());
+    1917             :         opReg = o1.getId();
+    1918             :         rmRel = &o0;
+    1919           0 :         goto EmitX86M;
+    1920             :       }
+    1921             :       break;
+    1922             : 
+    1923           0 :     case X86Inst::kEncodingX86StrRm:
+    1924           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    1925             :         rmRel = &o1;
+    1926           0 :         if (ASMJIT_UNLIKELY(rmRel->as<X86Mem>().getOffsetLo32() || !X86Reg::isGp(o0.as<X86Reg>(), X86Gp::kIdAx)))
+    1927           0 :           goto InvalidInstruction;
+    1928             : 
+    1929             :         uint32_t size = o0.getSize();
+    1930           0 :         if (o1.hasSize() && ASMJIT_UNLIKELY(o1.getSize() != size))
+    1931           0 :           goto OperandSizeMismatch;
+    1932             : 
+    1933           0 :         ADD_PREFIX_BY_SIZE(size);
+    1934           0 :         opCode += static_cast<uint32_t>(size != 1);
+    1935             : 
+    1936           0 :         goto EmitX86OpImplicitMem;
+    1937             :       }
+    1938             :       break;
+    1939             : 
+    1940           0 :     case X86Inst::kEncodingX86StrMr:
+    1941           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    1942             :         rmRel = &o0;
+    1943           0 :         if (ASMJIT_UNLIKELY(rmRel->as<X86Mem>().getOffsetLo32() || !X86Reg::isGp(o1.as<X86Reg>(), X86Gp::kIdAx)))
+    1944           0 :           goto InvalidInstruction;
+    1945             : 
+    1946             :         uint32_t size = o1.getSize();
+    1947           0 :         if (o0.hasSize() && ASMJIT_UNLIKELY(o0.getSize() != size))
+    1948           0 :           goto OperandSizeMismatch;
+    1949             : 
+    1950           0 :         ADD_PREFIX_BY_SIZE(size);
+    1951           0 :         opCode += static_cast<uint32_t>(size != 1);
+    1952             : 
+    1953           0 :         goto EmitX86OpImplicitMem;
+    1954             :       }
+    1955             :       break;
+    1956             : 
+    1957           0 :     case X86Inst::kEncodingX86StrMm:
+    1958           0 :       if (isign3 == ENC_OPS2(Mem, Mem)) {
+    1959           0 :         if (ASMJIT_UNLIKELY(o0.as<X86Mem>().getBaseIndexType() !=
+    1960             :                             o1.as<X86Mem>().getBaseIndexType()))
+    1961           0 :           goto InvalidInstruction;
+    1962             : 
+    1963             :         rmRel = &o1;
+    1964           0 :         if (ASMJIT_UNLIKELY(o0.as<X86Mem>().hasOffset()))
+    1965           0 :           goto InvalidInstruction;
+    1966             : 
+    1967             :         uint32_t size = o1.getSize();
+    1968           0 :         if (ASMJIT_UNLIKELY(size == 0))
+    1969           0 :           goto AmbiguousOperandSize;
+    1970             : 
+    1971           0 :         if (ASMJIT_UNLIKELY(o0.getSize() != size))
+    1972           0 :           goto OperandSizeMismatch;
+    1973             : 
+    1974           0 :         ADD_PREFIX_BY_SIZE(size);
+    1975           0 :         opCode += static_cast<uint32_t>(size != 1);
+    1976             : 
+    1977           0 :         goto EmitX86OpImplicitMem;
+    1978             :       }
+    1979             :       break;
+    1980             : 
+    1981           0 :     case X86Inst::kEncodingX86Test:
+    1982           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    1983           0 :         if (o0.getSize() != o1.getSize())
+    1984           0 :           goto OperandSizeMismatch;
+    1985             : 
+    1986             :         rbReg = o0.getId();
+    1987             :         opReg = o1.getId();
+    1988             : 
+    1989           0 :         if (o0.getSize() == 1) {
+    1990           0 :           FIXUP_GPB(o0, rbReg);
+    1991           0 :           FIXUP_GPB(o1, opReg);
+    1992           0 :           goto EmitX86R;
+    1993             :         }
+    1994             :         else {
+    1995           0 :           opCode++;
+    1996           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+    1997           0 :           goto EmitX86R;
+    1998             :         }
+    1999             :       }
+    2000             : 
+    2001           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2002             :         opReg = o1.getId();
+    2003             :         rmRel = &o0;
+    2004             : 
+    2005           0 :         if (o1.getSize() == 1) {
+    2006           0 :           FIXUP_GPB(o1, opReg);
+    2007           0 :           goto EmitX86M;
+    2008             :         }
+    2009             :         else {
+    2010           0 :           opCode++;
+    2011           0 :           ADD_PREFIX_BY_SIZE(o1.getSize());
+    2012           0 :           goto EmitX86M;
+    2013             :         }
+    2014             :       }
+    2015             : 
+    2016             :       // The following instructions use the secondary opcode.
+    2017             :       opCode = commonData->getAltOpCode();
+    2018             :       opReg = x86ExtractO(opCode);
+    2019             : 
+    2020           0 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+    2021             :         rbReg = o0.getId();
+    2022             : 
+    2023           0 :         if (o0.getSize() == 1) {
+    2024           0 :           FIXUP_GPB(o0, rbReg);
+    2025             : 
+    2026           0 :           imVal = static_cast<const Imm&>(o1).getUInt8();
+    2027             :           imLen = 1;
+    2028             :         }
+    2029             :         else {
+    2030           0 :           opCode++;
+    2031           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+    2032             : 
+    2033             :           imVal = static_cast<const Imm&>(o1).getInt64();
+    2034           0 :           imLen = std::min<uint32_t>(o0.getSize(), 4);
+    2035             :         }
+    2036             : 
+    2037             :         // Alternate Form - AL, AX, EAX, RAX.
+    2038           0 :         if (o0.getId() == 0 && !(options & X86Inst::kOptionLongForm)) {
+    2039           0 :           opCode &= X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_W;
+    2040           0 :           opCode |= 0xA8 + (o0.getSize() != 1);
+    2041           0 :           goto EmitX86Op;
+    2042             :         }
+    2043             : 
+    2044           0 :         goto EmitX86R;
+    2045             :       }
+    2046             : 
+    2047           0 :       if (isign3 == ENC_OPS2(Mem, Imm)) {
+    2048           0 :         if (ASMJIT_UNLIKELY(o0.getSize() == 0))
+    2049           0 :           goto AmbiguousOperandSize;
+    2050             : 
+    2051             :         imVal = static_cast<const Imm&>(o1).getInt64();
+    2052           0 :         imLen = std::min<uint32_t>(o0.getSize(), 4);
+    2053             : 
+    2054           0 :         opCode += (o0.getSize() != 1);
+    2055           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    2056             : 
+    2057             :         rmRel = &o0;
+    2058           0 :         goto EmitX86M;
+    2059             :       }
+    2060             :       break;
+    2061             : 
+    2062           0 :     case X86Inst::kEncodingX86Xchg:
+    2063           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2064             :         opReg = o0.getId();
+    2065             :         rmRel = &o1;
+    2066             : 
+    2067           0 :         if (o0.getSize() == 1) {
+    2068           0 :           FIXUP_GPB(o0, opReg);
+    2069           0 :           goto EmitX86M;
+    2070             :         }
+    2071             :         else {
+    2072           0 :           opCode++;
+    2073           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+    2074           0 :           goto EmitX86M;
+    2075             :         }
+    2076             :       }
+    2077             :       ASMJIT_FALLTHROUGH;
+    2078             : 
+    2079             :     case X86Inst::kEncodingX86Xadd:
+    2080           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2081             :         rbReg = o0.getId();
+    2082             :         opReg = o1.getId();
+    2083             : 
+    2084           0 :         if (o0.getSize() != o1.getSize())
+    2085           0 :           goto OperandSizeMismatch;
+    2086             : 
+    2087           0 :         if (o0.getSize() == 1) {
+    2088           0 :           FIXUP_GPB(o0, rbReg);
+    2089           0 :           FIXUP_GPB(o1, opReg);
+    2090           0 :           goto EmitX86R;
+    2091             :         }
+    2092             :         else {
+    2093           0 :           opCode++;
+    2094           0 :           ADD_PREFIX_BY_SIZE(o0.getSize());
+    2095             : 
+    2096             :           // Special opcode for 'xchg ?ax, reg'.
+    2097           0 :           if (instId == X86Inst::kIdXchg && (opReg == 0 || rbReg == 0)) {
+    2098           0 :             opCode &= X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_W;
+    2099           0 :             opCode |= 0x90;
+    2100             :             // One of `xchg a, b` or `xchg b, a` is AX/EAX/RAX.
+    2101           0 :             opReg += rbReg;
+    2102           0 :             goto EmitX86OpReg;
+    2103             :           }
+    2104             :           else {
+    2105           0 :             goto EmitX86R;
+    2106             :           }
+    2107             :         }
+    2108             :       }
+    2109             : 
+    2110           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2111           0 :         opCode += o1.getSize() != 1;
+    2112           0 :         ADD_PREFIX_BY_SIZE(o1.getSize());
+    2113             : 
+    2114             :         opReg = o1.getId();
+    2115             :         rmRel = &o0;
+    2116           0 :         goto EmitX86M;
+    2117             :       }
+    2118             :       break;
+    2119             : 
+    2120           0 :     case X86Inst::kEncodingX86Fence:
+    2121             :       rbReg = 0;
+    2122           0 :       goto EmitX86R;
+    2123             : 
+    2124           0 :     case X86Inst::kEncodingX86Bndmov:
+    2125           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2126             :         opReg = o0.getId();
+    2127             :         rbReg = o1.getId();
+    2128             : 
+    2129             :         // ModRM encoding:
+    2130           0 :         if (!(options & X86Inst::kOptionModMR))
+    2131           0 :           goto EmitX86R;
+    2132             : 
+    2133             :         // ModMR encoding:
+    2134             :         opCode = commonData->getAltOpCode();
+    2135             :         std::swap(opReg, rbReg);
+    2136           0 :         goto EmitX86R;
+    2137             :       }
+    2138             : 
+    2139           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2140             :         opReg = o0.getId();
+    2141             :         rmRel = &o1;
+    2142           0 :         goto EmitX86M;
+    2143             :       }
+    2144             : 
+    2145           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2146             :         opCode = commonData->getAltOpCode();
+    2147             : 
+    2148             :         rmRel = &o0;
+    2149             :         opReg = o1.getId();
+    2150           0 :         goto EmitX86M;
+    2151             :       }
+    2152             :       break;
+    2153             : 
+    2154             :     // ------------------------------------------------------------------------
+    2155             :     // [FPU]
+    2156             :     // ------------------------------------------------------------------------
+    2157             : 
+    2158           0 :     case X86Inst::kEncodingFpuOp:
+    2159           0 :       goto EmitFpuOp;
+    2160             : 
+    2161           0 :     case X86Inst::kEncodingFpuArith:
+    2162           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2163             :         opReg = o0.getId();
+    2164             :         rbReg = o1.getId();
+    2165             : 
+    2166             :         // We switch to the alternative opcode if the first operand is zero.
+    2167           0 :         if (opReg == 0) {
+    2168           0 : CaseFpuArith_Reg:
+    2169           0 :           opCode = ((0xD8   << X86Inst::kOpCode_FPU_2B_Shift)       ) +
+    2170           0 :                    ((opCode >> X86Inst::kOpCode_FPU_2B_Shift) & 0xFF) + rbReg;
+    2171           0 :           goto EmitFpuOp;
+    2172             :         }
+    2173           0 :         else if (rbReg == 0) {
+    2174             :           rbReg = opReg;
+    2175           0 :           opCode = ((0xDC   << X86Inst::kOpCode_FPU_2B_Shift)       ) +
+    2176           0 :                    ((opCode                                 ) & 0xFF) + rbReg;
+    2177           0 :           goto EmitFpuOp;
+    2178             :         }
+    2179             :         else {
+    2180           0 :           goto InvalidInstruction;
+    2181             :         }
+    2182             :       }
+    2183             : 
+    2184           0 :       if (isign3 == ENC_OPS1(Mem)) {
+    2185           0 : CaseFpuArith_Mem:
+    2186             :         // 0xD8/0xDC, depends on the size of the memory operand; opReg is valid.
+    2187           0 :         opCode = (o0.getSize() == 4) ? 0xD8 : 0xDC;
+    2188             :         // Clear compressed displacement before going to EmitX86M.
+    2189           0 :         opCode &= ~static_cast<uint32_t>(X86Inst::kOpCode_CDSHL_Mask);
+    2190             : 
+    2191             :         rmRel = &o0;
+    2192           0 :         goto EmitX86M;
+    2193             :       }
+    2194             :       break;
+    2195             : 
+    2196           0 :     case X86Inst::kEncodingFpuCom:
+    2197           0 :       if (isign3 == 0) {
+    2198             :         rbReg = 1;
+    2199           0 :         goto CaseFpuArith_Reg;
+    2200             :       }
+    2201             : 
+    2202           0 :       if (isign3 == ENC_OPS1(Reg)) {
+    2203             :         rbReg = o0.getId();
+    2204           0 :         goto CaseFpuArith_Reg;
+    2205             :       }
+    2206             : 
+    2207           0 :       if (isign3 == ENC_OPS1(Mem)) {
+    2208           0 :         goto CaseFpuArith_Mem;
+    2209             :       }
+    2210             :       break;
+    2211             : 
+    2212           0 :     case X86Inst::kEncodingFpuFldFst:
+    2213           0 :       if (isign3 == ENC_OPS1(Mem)) {
+    2214             :         rmRel = &o0;
+    2215             : 
+    2216           0 :         if (o0.getSize() == 4 && commonData->hasFlag(X86Inst::kFlagFpuM32)) {
+    2217           0 :           goto EmitX86M;
+    2218             :         }
+    2219             : 
+    2220           0 :         if (o0.getSize() == 8 && commonData->hasFlag(X86Inst::kFlagFpuM64)) {
+    2221           0 :           opCode += 4;
+    2222           0 :           goto EmitX86M;
+    2223             :         }
+    2224             : 
+    2225           0 :         if (o0.getSize() == 10 && commonData->hasFlag(X86Inst::kFlagFpuM80)) {
+    2226             :           opCode = commonData->getAltOpCode();
+    2227             :           opReg  = x86ExtractO(opCode);
+    2228           0 :           goto EmitX86M;
+    2229             :         }
+    2230             :       }
+    2231             : 
+    2232           0 :       if (isign3 == ENC_OPS1(Reg)) {
+    2233           0 :         if (instId == X86Inst::kIdFld ) { opCode = (0xD9 << X86Inst::kOpCode_FPU_2B_Shift) + 0xC0 + o0.getId(); goto EmitFpuOp; }
+    2234           0 :         if (instId == X86Inst::kIdFst ) { opCode = (0xDD << X86Inst::kOpCode_FPU_2B_Shift) + 0xD0 + o0.getId(); goto EmitFpuOp; }
+    2235           0 :         if (instId == X86Inst::kIdFstp) { opCode = (0xDD << X86Inst::kOpCode_FPU_2B_Shift) + 0xD8 + o0.getId(); goto EmitFpuOp; }
+    2236             :       }
+    2237             :       break;
+    2238             : 
+    2239           0 :     case X86Inst::kEncodingFpuM:
+    2240           0 :       if (isign3 == ENC_OPS1(Mem)) {
+    2241             :         // Clear compressed displacement before going to EmitX86M.
+    2242           0 :         opCode &= ~static_cast<uint32_t>(X86Inst::kOpCode_CDSHL_Mask);
+    2243             : 
+    2244             :         rmRel = &o0;
+    2245           0 :         if (o0.getSize() == 2 && commonData->hasFlag(X86Inst::kFlagFpuM16)) {
+    2246           0 :           opCode += 4;
+    2247           0 :           goto EmitX86M;
+    2248             :         }
+    2249             : 
+    2250           0 :         if (o0.getSize() == 4 && commonData->hasFlag(X86Inst::kFlagFpuM32)) {
+    2251           0 :           goto EmitX86M;
+    2252             :         }
+    2253             : 
+    2254           0 :         if (o0.getSize() == 8 && commonData->hasFlag(X86Inst::kFlagFpuM64)) {
+    2255           0 :           opCode = commonData->getAltOpCode() & ~static_cast<uint32_t>(X86Inst::kOpCode_CDSHL_Mask);
+    2256             :           opReg  = x86ExtractO(opCode);
+    2257           0 :           goto EmitX86M;
+    2258             :         }
+    2259             :       }
+    2260             :       break;
+    2261             : 
+    2262           0 :     case X86Inst::kEncodingFpuRDef:
+    2263           0 :       if (isign3 == 0) {
+    2264           0 :         opCode += 1;
+    2265           0 :         goto EmitFpuOp;
+    2266             :       }
+    2267             :       ASMJIT_FALLTHROUGH;
+    2268             : 
+    2269             :     case X86Inst::kEncodingFpuR:
+    2270           0 :       if (isign3 == ENC_OPS1(Reg)) {
+    2271           0 :         opCode += o0.getId();
+    2272           0 :         goto EmitFpuOp;
+    2273             :       }
+    2274             :       break;
+    2275             : 
+    2276           0 :     case X86Inst::kEncodingFpuStsw:
+    2277           0 :       if (isign3 == ENC_OPS1(Reg)) {
+    2278           0 :         if (ASMJIT_UNLIKELY(o0.getId() != X86Gp::kIdAx))
+    2279           0 :           goto InvalidInstruction;
+    2280             : 
+    2281             :         opCode = commonData->getAltOpCode();
+    2282           0 :         goto EmitFpuOp;
+    2283             :       }
+    2284             : 
+    2285           0 :       if (isign3 == ENC_OPS1(Mem)) {
+    2286             :         // Clear compressed displacement before going to EmitX86M.
+    2287           0 :         opCode &= ~static_cast<uint32_t>(X86Inst::kOpCode_CDSHL_Mask);
+    2288             : 
+    2289             :         rmRel = &o0;
+    2290           0 :         goto EmitX86M;
+    2291             :       }
+    2292             :       break;
+    2293             : 
+    2294             :     // ------------------------------------------------------------------------
+    2295             :     // [Ext]
+    2296             :     // ------------------------------------------------------------------------
+    2297             : 
+    2298           0 :     case X86Inst::kEncodingExtPextrw:
+    2299           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    2300           0 :         ADD_66H_P(X86Reg::isXmm(o1));
+    2301             : 
+    2302             :         imVal = static_cast<const Imm&>(o2).getInt64();
+    2303             :         imLen = 1;
+    2304             : 
+    2305             :         opReg = o0.getId();
+    2306             :         rbReg = o1.getId();
+    2307           0 :         goto EmitX86R;
+    2308             :       }
+    2309             : 
+    2310           0 :       if (isign3 == ENC_OPS3(Mem, Reg, Imm)) {
+    2311             :         // Secondary opcode of 'pextrw' instruction (SSE4.1).
+    2312             :         opCode = commonData->getAltOpCode();
+    2313           0 :         ADD_66H_P(X86Reg::isXmm(o1));
+    2314             : 
+    2315             :         imVal = static_cast<const Imm&>(o2).getInt64();
+    2316             :         imLen = 1;
+    2317             : 
+    2318             :         opReg = o1.getId();
+    2319             :         rmRel = &o0;
+    2320           0 :         goto EmitX86M;
+    2321             :       }
+    2322             :       break;
+    2323             : 
+    2324           0 :     case X86Inst::kEncodingExtExtract:
+    2325           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    2326           0 :         ADD_66H_P(X86Reg::isXmm(o1));
+    2327             : 
+    2328             :         imVal = static_cast<const Imm&>(o2).getInt64();
+    2329             :         imLen = 1;
+    2330             : 
+    2331             :         opReg = o1.getId();
+    2332             :         rbReg = o0.getId();
+    2333           0 :         goto EmitX86R;
+    2334             :       }
+    2335             : 
+    2336           0 :       if (isign3 == ENC_OPS3(Mem, Reg, Imm)) {
+    2337           0 :         ADD_66H_P(X86Reg::isXmm(o1));
+    2338             : 
+    2339             :         imVal = static_cast<const Imm&>(o2).getInt64();
+    2340             :         imLen = 1;
+    2341             : 
+    2342             :         opReg = o1.getId();
+    2343             :         rmRel = &o0;
+    2344           0 :         goto EmitX86M;
+    2345             :       }
+    2346             :       break;
+    2347             : 
+    2348       23848 :     case X86Inst::kEncodingExtMov:
+    2349             :       // GP|MMX|XMM <- GP|MMX|XMM
+    2350       23848 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2351             :         opReg = o0.getId();
+    2352             :         rbReg = o1.getId();
+    2353             : 
+    2354        9320 :         if (!(options & X86Inst::kOptionModMR) || !commonData->hasAltOpCode())
+    2355        9320 :           goto EmitX86R;
+    2356             : 
+    2357             :         opCode = commonData->getAltOpCode();
+    2358             :         Utils::swap(opReg, rbReg);
+    2359           0 :         goto EmitX86R;
+    2360             :       }
+    2361             : 
+    2362             :       // GP|MMX|XMM <- Mem
+    2363       14528 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2364             :         opReg = o0.getId();
+    2365             :         rmRel = &o1;
+    2366       10258 :         goto EmitX86M;
+    2367             :       }
+    2368             : 
+    2369             :       // The following instruction uses opCode[1].
+    2370             :       opCode = commonData->getAltOpCode();
+    2371             : 
+    2372             :       // Mem <- GP|MMX|XMM
+    2373        4270 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2374             :         opReg = o1.getId();
+    2375             :         rmRel = &o0;
+    2376        4270 :         goto EmitX86M;
+    2377             :       }
+    2378             :       break;
+    2379             : 
+    2380           0 :     case X86Inst::kEncodingExtMovnti:
+    2381           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2382           0 :         ADD_REX_W(X86Reg::isGpq(o1));
+    2383             : 
+    2384             :         opReg = o1.getId();
+    2385             :         rmRel = &o0;
+    2386           0 :         goto EmitX86M;
+    2387             :       }
+    2388             :       break;
+    2389             : 
+    2390           0 :     case X86Inst::kEncodingExtMovbe:
+    2391           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2392           0 :         if (o0.getSize() == 1)
+    2393           0 :           goto InvalidInstruction;
+    2394             : 
+    2395           0 :         ADD_PREFIX_BY_SIZE(o0.getSize());
+    2396             :         opReg = o0.getId();
+    2397             :         rmRel = &o1;
+    2398           0 :         goto EmitX86M;
+    2399             :       }
+    2400             : 
+    2401             :       // The following instruction uses the secondary opcode.
+    2402             :       opCode = commonData->getAltOpCode();
+    2403             : 
+    2404           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2405           0 :         if (o1.getSize() == 1)
+    2406           0 :           goto InvalidInstruction;
+    2407             : 
+    2408           0 :         ADD_PREFIX_BY_SIZE(o1.getSize());
+    2409             :         opReg = o1.getId();
+    2410             :         rmRel = &o0;
+    2411           0 :         goto EmitX86M;
+    2412             :       }
+    2413             :       break;
+    2414             : 
+    2415             :     case X86Inst::kEncodingExtMovd:
+    2416           0 : CaseExtMovd:
+    2417             :       opReg = o0.getId();
+    2418           0 :       ADD_66H_P(X86Reg::isXmm(o0));
+    2419             : 
+    2420             :       // MMX/XMM <- Gp
+    2421           0 :       if (isign3 == ENC_OPS2(Reg, Reg) && X86Reg::isGp(o1)) {
+    2422             :         rbReg = o1.getId();
+    2423           0 :         goto EmitX86R;
+    2424             :       }
+    2425             : 
+    2426             :       // MMX/XMM <- Mem
+    2427           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2428             :         rmRel = &o1;
+    2429           0 :         goto EmitX86M;
+    2430             :       }
+    2431             : 
+    2432             :       // The following instructions use the secondary opcode.
+    2433           0 :       opCode &= X86Inst::kOpCode_W;
+    2434           0 :       opCode |= commonData->getAltOpCode();
+    2435             :       opReg = o1.getId();
+    2436           0 :       ADD_66H_P(X86Reg::isXmm(o1));
+    2437             : 
+    2438             :       // GP <- MMX/XMM
+    2439           0 :       if (isign3 == ENC_OPS2(Reg, Reg) && X86Reg::isGp(o0)) {
+    2440             :         rbReg = o0.getId();
+    2441           0 :         goto EmitX86R;
+    2442             :       }
+    2443             : 
+    2444             :       // Mem <- MMX/XMM
+    2445           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2446             :         rmRel = &o0;
+    2447           0 :         goto EmitX86M;
+    2448             :       }
+    2449             :       break;
+    2450             : 
+    2451           0 :     case X86Inst::kEncodingExtMovq:
+    2452           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2453             :         opReg = o0.getId();
+    2454             :         rbReg = o1.getId();
+    2455             : 
+    2456             :         // MMX <- MMX
+    2457           0 :         if (X86Reg::isMm(o0) && X86Reg::isMm(o1)) {
+    2458             :           opCode = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F | 0x6F;
+    2459             : 
+    2460           0 :           if (!(options & X86Inst::kOptionModMR))
+    2461           0 :             goto EmitX86R;
+    2462             : 
+    2463             :           opCode += 0x10;
+    2464             :           Utils::swap(opReg, rbReg);
+    2465           0 :           goto EmitX86R;
+    2466             :         }
+    2467             : 
+    2468             :         // XMM <- XMM
+    2469           0 :         if (X86Reg::isXmm(o0) && X86Reg::isXmm(o1)) {
+    2470             :           opCode = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F | 0x7E;
+    2471             : 
+    2472           0 :           if (!(options & X86Inst::kOptionModMR))
+    2473           0 :             goto EmitX86R;
+    2474             : 
+    2475             :           opCode = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_0F | 0xD6;
+    2476             :           Utils::swap(opReg, rbReg);
+    2477           0 :           goto EmitX86R;
+    2478             :         }
+    2479             : 
+    2480             :         // MMX <- XMM (MOVDQ2Q)
+    2481           0 :         if (X86Reg::isMm(o0) && X86Reg::isXmm(o1)) {
+    2482             :           opCode = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_0F | 0xD6;
+    2483           0 :           goto EmitX86R;
+    2484             :         }
+    2485             : 
+    2486             :         // XMM <- MMX (MOVQ2DQ)
+    2487           0 :         if (X86Reg::isXmm(o0) && X86Reg::isMm(o1)) {
+    2488             :           opCode = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F | 0xD6;
+    2489           0 :           goto EmitX86R;
+    2490             :         }
+    2491             :       }
+    2492             : 
+    2493           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2494             :         opReg = o0.getId();
+    2495             :         rmRel = &o1;
+    2496             : 
+    2497             :         // MMX <- Mem
+    2498           0 :         if (X86Reg::isMm(o0)) {
+    2499             :           opCode = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F | 0x6F;
+    2500           0 :           goto EmitX86M;
+    2501             :         }
+    2502             : 
+    2503             :         // XMM <- Mem
+    2504           0 :         if (X86Reg::isXmm(o0)) {
+    2505             :           opCode = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F | 0x7E;
+    2506           0 :           goto EmitX86M;
+    2507             :         }
+    2508             :       }
+    2509             : 
+    2510           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2511             :         opReg = o1.getId();
+    2512             :         rmRel = &o0;
+    2513             : 
+    2514             :         // Mem <- MMX
+    2515           0 :         if (X86Reg::isMm(o1)) {
+    2516             :           opCode = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F | 0x7F;
+    2517           0 :           goto EmitX86M;
+    2518             :         }
+    2519             : 
+    2520             :         // Mem <- XMM
+    2521           0 :         if (X86Reg::isXmm(o1)) {
+    2522             :           opCode = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_0F | 0xD6;
+    2523           0 :           goto EmitX86M;
+    2524             :         }
+    2525             :       }
+    2526             : 
+    2527             :       // MOVQ in other case is simply a MOVD instruction promoted to 64-bit.
+    2528           0 :       opCode |= X86Inst::kOpCode_W;
+    2529           0 :       goto CaseExtMovd;
+    2530             : 
+    2531             :     case X86Inst::kEncodingExtRm_XMM0:
+    2532           0 :       if (ASMJIT_UNLIKELY(!o2.isNone() && !X86Reg::isXmm(o2, 0)))
+    2533           0 :         goto InvalidInstruction;
+    2534             : 
+    2535           0 :       isign3 &= 0x3F;
+    2536           0 :       goto CaseExtRm;
+    2537             : 
+    2538             :     case X86Inst::kEncodingExtRm_ZDI:
+    2539           0 :       if (ASMJIT_UNLIKELY(!o2.isNone() && !x86IsImplicitMem(o2, X86Gp::kIdDi)))
+    2540           0 :         goto InvalidInstruction;
+    2541             : 
+    2542           0 :       isign3 &= 0x3F;
+    2543           0 :       goto CaseExtRm;
+    2544             : 
+    2545             :     case X86Inst::kEncodingExtRm_Wx:
+    2546           0 :       ADD_REX_W(X86Reg::isGpq(o0) || o1.getSize() == 8);
+    2547             :       ASMJIT_FALLTHROUGH;
+    2548             : 
+    2549             :     case X86Inst::kEncodingExtRm:
+    2550        9006 : CaseExtRm:
+    2551        9006 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2552             :         opReg = o0.getId();
+    2553             :         rbReg = o1.getId();
+    2554        9006 :         goto EmitX86R;
+    2555             :       }
+    2556             : 
+    2557           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2558             :         opReg = o0.getId();
+    2559             :         rmRel = &o1;
+    2560           0 :         goto EmitX86M;
+    2561             :       }
+    2562             :       break;
+    2563             : 
+    2564           0 :     case X86Inst::kEncodingExtRm_P:
+    2565           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2566           0 :         ADD_66H_P(X86Reg::isXmm(o0) | X86Reg::isXmm(o1));
+    2567             : 
+    2568             :         opReg = o0.getId();
+    2569             :         rbReg = o1.getId();
+    2570           0 :         goto EmitX86R;
+    2571             :       }
+    2572             : 
+    2573           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2574           0 :         ADD_66H_P(X86Reg::isXmm(o0));
+    2575             : 
+    2576             :         opReg = o0.getId();
+    2577             :         rmRel = &o1;
+    2578           0 :         goto EmitX86M;
+    2579             :       }
+    2580             :       break;
+    2581             : 
+    2582           0 :     case X86Inst::kEncodingExtRmRi:
+    2583           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2584             :         opReg = o0.getId();
+    2585             :         rbReg = o1.getId();
+    2586           0 :         goto EmitX86R;
+    2587             :       }
+    2588             : 
+    2589           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2590             :         opReg = o0.getId();
+    2591             :         rmRel = &o1;
+    2592           0 :         goto EmitX86M;
+    2593             :       }
+    2594             : 
+    2595             :       // The following instruction uses the secondary opcode.
+    2596             :       opCode = commonData->getAltOpCode();
+    2597             :       opReg  = x86ExtractO(opCode);
+    2598             : 
+    2599           0 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+    2600             :         imVal = static_cast<const Imm&>(o1).getInt64();
+    2601             :         imLen = 1;
+    2602             : 
+    2603             :         rbReg = o0.getId();
+    2604           0 :         goto EmitX86R;
+    2605             :       }
+    2606             :       break;
+    2607             : 
+    2608           0 :     case X86Inst::kEncodingExtRmRi_P:
+    2609           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2610           0 :         ADD_66H_P(X86Reg::isXmm(o0) | X86Reg::isXmm(o1));
+    2611             : 
+    2612             :         opReg = o0.getId();
+    2613             :         rbReg = o1.getId();
+    2614           0 :         goto EmitX86R;
+    2615             :       }
+    2616             : 
+    2617           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2618           0 :         ADD_66H_P(X86Reg::isXmm(o0));
+    2619             : 
+    2620             :         opReg = o0.getId();
+    2621             :         rmRel = &o1;
+    2622           0 :         goto EmitX86M;
+    2623             :       }
+    2624             : 
+    2625             :       // The following instruction uses the secondary opcode.
+    2626             :       opCode = commonData->getAltOpCode();
+    2627             :       opReg  = x86ExtractO(opCode);
+    2628             : 
+    2629           0 :       if (isign3 == ENC_OPS2(Reg, Imm)) {
+    2630           0 :         ADD_66H_P(X86Reg::isXmm(o0));
+    2631             : 
+    2632             :         imVal = static_cast<const Imm&>(o1).getInt64();
+    2633             :         imLen = 1;
+    2634             : 
+    2635             :         rbReg = o0.getId();
+    2636           0 :         goto EmitX86R;
+    2637             :       }
+    2638             :       break;
+    2639             : 
+    2640             :     case X86Inst::kEncodingExtRmi:
+    2641             :       imVal = static_cast<const Imm&>(o2).getInt64();
+    2642             :       imLen = 1;
+    2643             : 
+    2644         120 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    2645             :         opReg = o0.getId();
+    2646             :         rbReg = o1.getId();
+    2647         120 :         goto EmitX86R;
+    2648             :       }
+    2649             : 
+    2650           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Imm)) {
+    2651             :         opReg = o0.getId();
+    2652             :         rmRel = &o1;
+    2653           0 :         goto EmitX86M;
+    2654             :       }
+    2655             :       break;
+    2656             : 
+    2657             :     case X86Inst::kEncodingExtRmi_P:
+    2658             :       imVal = static_cast<const Imm&>(o2).getInt64();
+    2659             :       imLen = 1;
+    2660             : 
+    2661           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    2662           0 :         ADD_66H_P(X86Reg::isXmm(o0) | X86Reg::isXmm(o1));
+    2663             : 
+    2664             :         opReg = o0.getId();
+    2665             :         rbReg = o1.getId();
+    2666           0 :         goto EmitX86R;
+    2667             :       }
+    2668             : 
+    2669           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Imm)) {
+    2670           0 :         ADD_66H_P(X86Reg::isXmm(o0));
+    2671             : 
+    2672             :         opReg = o0.getId();
+    2673             :         rmRel = &o1;
+    2674           0 :         goto EmitX86M;
+    2675             :       }
+    2676             :       break;
+    2677             : 
+    2678             :     // ------------------------------------------------------------------------
+    2679             :     // [Extrq / Insertq (SSE4A)]
+    2680             :     // ------------------------------------------------------------------------
+    2681             : 
+    2682             :     case X86Inst::kEncodingExtExtrq:
+    2683             :       opReg = o0.getId();
+    2684             :       rbReg = o1.getId();
+    2685             : 
+    2686           0 :       if (isign3 == ENC_OPS2(Reg, Reg))
+    2687           0 :         goto EmitX86R;
+    2688             : 
+    2689             :       // The following instruction uses the secondary opcode.
+    2690             :       opCode = commonData->getAltOpCode();
+    2691             : 
+    2692           0 :       if (isign3 == ENC_OPS3(Reg, Imm, Imm)) {
+    2693           0 :         imVal = (static_cast<const Imm&>(o1).getUInt32()     ) +
+    2694           0 :                 (static_cast<const Imm&>(o2).getUInt32() << 8) ;
+    2695             :         imLen = 2;
+    2696             : 
+    2697             :         rbReg = x86ExtractO(opCode);
+    2698           0 :         goto EmitX86R;
+    2699             :       }
+    2700             :       break;
+    2701             : 
+    2702             :     case X86Inst::kEncodingExtInsertq: {
+    2703           0 :       const uint32_t isign4 = isign3 + (o3.getOp() << 9);
+    2704             :       opReg = o0.getId();
+    2705             :       rbReg = o1.getId();
+    2706             : 
+    2707           0 :       if (isign4 == ENC_OPS2(Reg, Reg))
+    2708           0 :         goto EmitX86R;
+    2709             : 
+    2710             :       // The following instruction uses the secondary opcode.
+    2711             :       opCode = commonData->getAltOpCode();
+    2712             : 
+    2713           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Imm, Imm)) {
+    2714           0 :         imVal = (static_cast<const Imm&>(o2).getUInt32()     ) +
+    2715           0 :                 (static_cast<const Imm&>(o3).getUInt32() << 8) ;
+    2716             :         imLen = 2;
+    2717           0 :         goto EmitX86R;
+    2718             :       }
+    2719             :       break;
+    2720             :     }
+    2721             : 
+    2722             :     // ------------------------------------------------------------------------
+    2723             :     // [3dNow]
+    2724             :     // ------------------------------------------------------------------------
+    2725             : 
+    2726           0 :     case X86Inst::kEncodingExt3dNow:
+    2727             :       // Every 3dNow instruction starts with 0x0F0F and the actual opcode is
+    2728             :       // stored as 8-bit immediate.
+    2729           0 :       imVal = opCode & 0xFF;
+    2730             :       imLen = 1;
+    2731             : 
+    2732             :       opCode = X86Inst::kOpCode_MM_0F | 0x0F;
+    2733             :       opReg = o0.getId();
+    2734             : 
+    2735           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2736             :         rbReg = o1.getId();
+    2737           0 :         goto EmitX86R;
+    2738             :       }
+    2739             : 
+    2740           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2741             :         rmRel = &o1;
+    2742           0 :         goto EmitX86M;
+    2743             :       }
+    2744             :       break;
+    2745             : 
+    2746             :     // ------------------------------------------------------------------------
+    2747             :     // [VEX/EVEX]
+    2748             :     // ------------------------------------------------------------------------
+    2749             : 
+    2750           0 :     case X86Inst::kEncodingVexOp:
+    2751           0 :       goto EmitVexEvexOp;
+    2752             : 
+    2753           0 :     case X86Inst::kEncodingVexKmov:
+    2754           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2755             :         opReg = o0.getId();
+    2756             :         rbReg = o1.getId();
+    2757             : 
+    2758             :         // Form 'k, reg'.
+    2759           0 :         if (X86Reg::isGp(o1)) {
+    2760             :           opCode = commonData->getAltOpCode();
+    2761           0 :           goto EmitVexEvexR;
+    2762             :         }
+    2763             : 
+    2764             :         // Form 'reg, k'.
+    2765           0 :         if (X86Reg::isGp(o0)) {
+    2766           0 :           opCode = commonData->getAltOpCode() + 1;
+    2767           0 :           goto EmitVexEvexR;
+    2768             :         }
+    2769             : 
+    2770             :         // Form 'k, k'.
+    2771           0 :         if (!(options & X86Inst::kOptionModMR))
+    2772           0 :           goto EmitVexEvexR;
+    2773             : 
+    2774           0 :         opCode++;
+    2775             :         Utils::swap(opReg, rbReg);
+    2776           0 :         goto EmitVexEvexR;
+    2777             :       }
+    2778             : 
+    2779           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2780             :         opReg = o0.getId();
+    2781             :         rmRel = &o1;
+    2782             : 
+    2783           0 :         goto EmitVexEvexM;
+    2784             :       }
+    2785             : 
+    2786           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2787             :         opReg = o1.getId();
+    2788             :         rmRel = &o0;
+    2789             : 
+    2790           0 :         opCode++;
+    2791           0 :         goto EmitVexEvexM;
+    2792             :       }
+    2793             :       break;
+    2794             : 
+    2795           0 :     case X86Inst::kEncodingVexM:
+    2796           0 :       if (isign3 == ENC_OPS1(Mem)) {
+    2797             :         rmRel = &o0;
+    2798           0 :         goto EmitVexEvexM;
+    2799             :       }
+    2800             :       break;
+    2801             : 
+    2802           0 :     case X86Inst::kEncodingVexM_VM:
+    2803           0 :       if (isign3 == ENC_OPS1(Mem)) {
+    2804           0 :         opCode |= x86OpCodeLByVMem(o0);
+    2805             :         rmRel = &o0;
+    2806           0 :         goto EmitVexEvexM;
+    2807             :       }
+    2808             :       break;
+    2809             : 
+    2810             :     case X86Inst::kEncodingVexMr_Lx:
+    2811           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    2812             : 
+    2813           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2814             :         opReg = o1.getId();
+    2815             :         rbReg = o0.getId();
+    2816           0 :         goto EmitVexEvexR;
+    2817             :       }
+    2818             : 
+    2819           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2820             :         opReg = o1.getId();
+    2821             :         rmRel = &o0;
+    2822           0 :         goto EmitVexEvexM;
+    2823             :       }
+    2824             :       break;
+    2825             : 
+    2826           0 :     case X86Inst::kEncodingVexMr_VM:
+    2827           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    2828           0 :         opCode |= std::max(x86OpCodeLByVMem(o0), x86OpCodeLBySize(o1.getSize()));
+    2829             : 
+    2830             :         opReg = o1.getId();
+    2831             :         rmRel = &o0;
+    2832           0 :         goto EmitVexEvexM;
+    2833             :       }
+    2834             :       break;
+    2835             : 
+    2836             :     case X86Inst::kEncodingVexMri_Lx:
+    2837           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    2838             :       ASMJIT_FALLTHROUGH;
+    2839             : 
+    2840           0 :     case X86Inst::kEncodingVexMri:
+    2841             :       imVal = static_cast<const Imm&>(o2).getInt64();
+    2842             :       imLen = 1;
+    2843             : 
+    2844           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    2845             :         opReg = o1.getId();
+    2846             :         rbReg = o0.getId();
+    2847           0 :         goto EmitVexEvexR;
+    2848             :       }
+    2849             : 
+    2850           0 :       if (isign3 == ENC_OPS3(Mem, Reg, Imm)) {
+    2851             :         opReg = o1.getId();
+    2852             :         rmRel = &o0;
+    2853           0 :         goto EmitVexEvexM;
+    2854             :       }
+    2855             :       break;
+    2856             : 
+    2857             :     case X86Inst::kEncodingVexRm_ZDI:
+    2858           0 :       if (ASMJIT_UNLIKELY(!o2.isNone() && !x86IsImplicitMem(o2, X86Gp::kIdDi)))
+    2859           0 :         goto InvalidInstruction;
+    2860             : 
+    2861           0 :       isign3 &= 0x3F;
+    2862           0 :       goto CaseVexRm;
+    2863             : 
+    2864             :     case X86Inst::kEncodingVexRm_Wx:
+    2865           0 :       ADD_REX_W(X86Reg::isGpq(o0) | X86Reg::isGpq(o1));
+    2866           0 :       goto CaseVexRm;
+    2867             : 
+    2868             :     case X86Inst::kEncodingVexRm_Lx:
+    2869           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    2870             :       ASMJIT_FALLTHROUGH;
+    2871             : 
+    2872             :     case X86Inst::kEncodingVexRm:
+    2873           0 : CaseVexRm:
+    2874           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    2875             :         opReg = o0.getId();
+    2876             :         rbReg = o1.getId();
+    2877           0 :         goto EmitVexEvexR;
+    2878             :       }
+    2879             : 
+    2880           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2881             :         opReg = o0.getId();
+    2882             :         rmRel = &o1;
+    2883           0 :         goto EmitVexEvexM;
+    2884             :       }
+    2885             :       break;
+    2886             : 
+    2887           0 :     case X86Inst::kEncodingVexRm_VM:
+    2888           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    2889           0 :         opCode |= std::max(x86OpCodeLByVMem(o1), x86OpCodeLBySize(o0.getSize()));
+    2890             :         opReg = o0.getId();
+    2891             :         rmRel = &o1;
+    2892           0 :         goto EmitVexEvexM;
+    2893             :       }
+    2894             :       break;
+    2895             : 
+    2896           0 :     case X86Inst::kEncodingVexRm_T1_4X: {
+    2897           0 :       if (!(options & kOptionOp4Op5Used))
+    2898           0 :         goto InvalidInstruction;
+    2899             : 
+    2900           0 :       if (X86Reg::isZmm(o0  ) && X86Reg::isZmm(o1) &&
+    2901           0 :           X86Reg::isZmm(o2  ) && X86Reg::isZmm(o3) &&
+    2902           0 :           X86Reg::isZmm(_op4) && _op5.isMem()) {
+    2903             : 
+    2904             :         // Registers [o1, o2, o3, _op4] must start aligned and must be consecutive.
+    2905             :         uint32_t i1 = o1.getId();
+    2906             :         uint32_t i2 = o2.getId();
+    2907             :         uint32_t i3 = o3.getId();
+    2908             :         uint32_t i4 = _op4.getId();
+    2909             : 
+    2910           0 :         if (ASMJIT_UNLIKELY((i1 & 0x3) != 0 || i2 != i1 + 1 || i3 != i1 + 2 || i4 != i1 + 3))
+    2911           0 :           goto NotConsecutiveRegs;
+    2912             : 
+    2913             :         opReg = o0.getId();
+    2914           0 :         rmRel = &_op5;
+    2915           0 :         goto EmitVexEvexM;
+    2916             :       }
+    2917             :       break;
+    2918             :     }
+    2919             : 
+    2920             :     case X86Inst::kEncodingVexRmi_Wx:
+    2921           0 :       ADD_REX_W(X86Reg::isGpq(o0) | X86Reg::isGpq(o1));
+    2922           0 :       goto CaseVexRmi;
+    2923             : 
+    2924             :     case X86Inst::kEncodingVexRmi_Lx:
+    2925           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    2926             :       ASMJIT_FALLTHROUGH;
+    2927             : 
+    2928             :     case X86Inst::kEncodingVexRmi:
+    2929           0 : CaseVexRmi:
+    2930             :       imVal = static_cast<const Imm&>(o2).getInt64();
+    2931             :       imLen = 1;
+    2932             : 
+    2933           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    2934             :         opReg = o0.getId();
+    2935             :         rbReg = o1.getId();
+    2936           0 :         goto EmitVexEvexR;
+    2937             :       }
+    2938             : 
+    2939           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Imm)) {
+    2940             :         opReg = o0.getId();
+    2941             :         rmRel = &o1;
+    2942           0 :         goto EmitVexEvexM;
+    2943             :       }
+    2944             :       break;
+    2945             : 
+    2946             :     case X86Inst::kEncodingVexRvm:
+    2947           0 : CaseVexRvm:
+    2948           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
+    2949           0 : CaseVexRvm_R:
+    2950             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    2951             :         rbReg = o2.getId();
+    2952           0 :         goto EmitVexEvexR;
+    2953             :       }
+    2954             : 
+    2955           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Mem)) {
+    2956             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    2957             :         rmRel = &o2;
+    2958           0 :         goto EmitVexEvexM;
+    2959             :       }
+    2960             :       break;
+    2961             : 
+    2962             :     case X86Inst::kEncodingVexRvm_ZDX_Wx:
+    2963           0 :       if (ASMJIT_UNLIKELY(!o3.isNone() && !X86Reg::isGp(o3, X86Gp::kIdDx)))
+    2964           0 :         goto InvalidInstruction;
+    2965             :       ASMJIT_FALLTHROUGH;
+    2966             : 
+    2967             :     case X86Inst::kEncodingVexRvm_Wx:
+    2968           0 :       ADD_REX_W(X86Reg::isGpq(o0) | (o2.getSize() == 8));
+    2969           0 :       goto CaseVexRvm;
+    2970             : 
+    2971             :     case X86Inst::kEncodingVexRvm_Lx:
+    2972           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    2973           0 :       goto CaseVexRvm;
+    2974             : 
+    2975             :     case X86Inst::kEncodingVexRvmr_Lx:
+    2976           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    2977             :       ASMJIT_FALLTHROUGH;
+    2978             : 
+    2979           0 :     case X86Inst::kEncodingVexRvmr: {
+    2980           0 :       const uint32_t isign4 = isign3 + (o3.getOp() << 9);
+    2981           0 :       imVal = o3.getId() << 4;
+    2982             :       imLen = 1;
+    2983             : 
+    2984           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
+    2985             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    2986             :         rbReg = o2.getId();
+    2987           0 :         goto EmitVexEvexR;
+    2988             :       }
+    2989             : 
+    2990           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Mem, Reg)) {
+    2991             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    2992             :         rmRel = &o2;
+    2993           0 :         goto EmitVexEvexM;
+    2994             :       }
+    2995             :       break;
+    2996             :     }
+    2997             : 
+    2998             :     case X86Inst::kEncodingVexRvmi_Lx:
+    2999           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    3000             :       ASMJIT_FALLTHROUGH;
+    3001             : 
+    3002           0 :     case X86Inst::kEncodingVexRvmi: {
+    3003           0 :       const uint32_t isign4 = isign3 + (o3.getOp() << 9);
+    3004             :       imVal = static_cast<const Imm&>(o3).getInt64();
+    3005             :       imLen = 1;
+    3006             : 
+    3007           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
+    3008             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3009             :         rbReg = o2.getId();
+    3010           0 :         goto EmitVexEvexR;
+    3011             :       }
+    3012             : 
+    3013           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Mem, Imm)) {
+    3014             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3015             :         rmRel = &o2;
+    3016           0 :         goto EmitVexEvexM;
+    3017             :       }
+    3018             :       break;
+    3019             :     }
+    3020             : 
+    3021             :     case X86Inst::kEncodingVexRmv_Wx:
+    3022           0 :       ADD_REX_W(X86Reg::isGpq(o0) | X86Reg::isGpq(o2));
+    3023             :       ASMJIT_FALLTHROUGH;
+    3024             : 
+    3025             :     case X86Inst::kEncodingVexRmv:
+    3026           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
+    3027             :         opReg = x86PackRegAndVvvvv(o0.getId(), o2.getId());
+    3028             :         rbReg = o1.getId();
+    3029           0 :         goto EmitVexEvexR;
+    3030             :       }
+    3031             : 
+    3032           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Reg)) {
+    3033             :         opReg = x86PackRegAndVvvvv(o0.getId(), o2.getId());
+    3034             :         rmRel = &o1;
+    3035           0 :         goto EmitVexEvexM;
+    3036             :       }
+    3037             :       break;
+    3038             : 
+    3039           0 :     case X86Inst::kEncodingVexRmvRm_VM:
+    3040           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    3041             :         opCode  = commonData->getAltOpCode();
+    3042           0 :         opCode |= std::max(x86OpCodeLByVMem(o1), x86OpCodeLBySize(o0.getSize()));
+    3043             : 
+    3044             :         opReg = o0.getId();
+    3045             :         rmRel = &o1;
+    3046           0 :         goto EmitVexEvexM;
+    3047             :       }
+    3048             : 
+    3049             :       ASMJIT_FALLTHROUGH;
+    3050             : 
+    3051             :     case X86Inst::kEncodingVexRmv_VM:
+    3052           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Reg)) {
+    3053           0 :         opCode |= std::max(x86OpCodeLByVMem(o1), x86OpCodeLBySize(o0.getSize() | o2.getSize()));
+    3054             : 
+    3055             :         opReg = x86PackRegAndVvvvv(o0.getId(), o2.getId());
+    3056             :         rmRel = &o1;
+    3057           0 :         goto EmitVexEvexM;
+    3058             :       }
+    3059             :       break;
+    3060             : 
+    3061             : 
+    3062             :     case X86Inst::kEncodingVexRmvi: {
+    3063           0 :       const uint32_t isign4 = isign3 + (o3.getOp() << 9);
+    3064             :       imVal = static_cast<const Imm&>(o3).getInt64();
+    3065             :       imLen = 1;
+    3066             : 
+    3067           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Reg, Imm)) {
+    3068             :         opReg = x86PackRegAndVvvvv(o0.getId(), o2.getId());
+    3069             :         rbReg = o1.getId();
+    3070           0 :         goto EmitVexEvexR;
+    3071             :       }
+    3072             : 
+    3073           0 :       if (isign4 == ENC_OPS4(Reg, Mem, Reg, Imm)) {
+    3074             :         opReg = x86PackRegAndVvvvv(o0.getId(), o2.getId());
+    3075             :         rmRel = &o1;
+    3076           0 :         goto EmitVexEvexM;
+    3077             :       }
+    3078             :       break;
+    3079             :     }
+    3080             : 
+    3081           0 :     case X86Inst::kEncodingVexMovdMovq:
+    3082           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    3083           0 :         if (X86Reg::isGp(o0)) {
+    3084             :           opCode = commonData->getAltOpCode();
+    3085           0 :           ADD_REX_W_BY_SIZE(o0.getSize());
+    3086             :           opReg = o1.getId();
+    3087             :           rbReg = o0.getId();
+    3088           0 :           goto EmitVexEvexR;
+    3089             :         }
+    3090             : 
+    3091           0 :         if (X86Reg::isGp(o1)) {
+    3092           0 :           ADD_REX_W_BY_SIZE(o1.getSize());
+    3093             :           opReg = o0.getId();
+    3094             :           rbReg = o1.getId();
+    3095           0 :           goto EmitVexEvexR;
+    3096             :         }
+    3097             : 
+    3098             :         // If this is a 'W' version (movq) then allow also vmovq 'xmm|xmm' form.
+    3099           0 :         if (opCode & X86Inst::kOpCode_EW) {
+    3100           0 :           opCode &= ~(X86Inst::kOpCode_PP_VEXMask | X86Inst::kOpCode_MM_Mask | 0xFF);
+    3101           0 :           opCode |=  (X86Inst::kOpCode_PP_F3      | X86Inst::kOpCode_MM_0F   | 0x7E);
+    3102             : 
+    3103             :           opReg = o0.getId();
+    3104             :           rbReg = o1.getId();
+    3105           0 :           goto EmitVexEvexR;
+    3106             :         }
+    3107             :       }
+    3108             : 
+    3109           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    3110           0 :         if (opCode & X86Inst::kOpCode_EW) {
+    3111           0 :           opCode &= ~(X86Inst::kOpCode_PP_VEXMask | X86Inst::kOpCode_MM_Mask | 0xFF);
+    3112           0 :           opCode |=  (X86Inst::kOpCode_PP_F3      | X86Inst::kOpCode_MM_0F   | 0x7E);
+    3113             :         }
+    3114             : 
+    3115             :         opReg = o0.getId();
+    3116             :         rmRel = &o1;
+    3117           0 :         goto EmitVexEvexM;
+    3118             :       }
+    3119             : 
+    3120             :       // The following instruction uses the secondary opcode.
+    3121             :       opCode = commonData->getAltOpCode();
+    3122             : 
+    3123           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    3124           0 :         if (opCode & X86Inst::kOpCode_EW) {
+    3125           0 :           opCode &= ~(X86Inst::kOpCode_PP_VEXMask | X86Inst::kOpCode_MM_Mask | 0xFF);
+    3126           0 :           opCode |=  (X86Inst::kOpCode_PP_66      | X86Inst::kOpCode_MM_0F   | 0xD6);
+    3127             :         }
+    3128             : 
+    3129             :         opReg = o1.getId();
+    3130             :         rmRel = &o0;
+    3131           0 :         goto EmitVexEvexM;
+    3132             :       }
+    3133             :       break;
+    3134             : 
+    3135             :     case X86Inst::kEncodingVexRmMr_Lx:
+    3136           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    3137             :       ASMJIT_FALLTHROUGH;
+    3138             : 
+    3139           0 :     case X86Inst::kEncodingVexRmMr:
+    3140           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    3141             :         opReg = o0.getId();
+    3142             :         rbReg = o1.getId();
+    3143           0 :         goto EmitVexEvexR;
+    3144             :       }
+    3145             : 
+    3146           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    3147             :         opReg = o0.getId();
+    3148             :         rmRel = &o1;
+    3149           0 :         goto EmitVexEvexM;
+    3150             :       }
+    3151             : 
+    3152             :       // The following instruction uses the secondary opcode.
+    3153           0 :       opCode &= X86Inst::kOpCode_LL_Mask;
+    3154           0 :       opCode |= commonData->getAltOpCode();
+    3155             : 
+    3156           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    3157             :         opReg = o1.getId();
+    3158             :         rmRel = &o0;
+    3159           0 :         goto EmitVexEvexM;
+    3160             :       }
+    3161             :       break;
+    3162             : 
+    3163           0 :     case X86Inst::kEncodingVexRvmRmv:
+    3164           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
+    3165             :         opReg = x86PackRegAndVvvvv(o0.getId(), o2.getId());
+    3166             :         rbReg = o1.getId();
+    3167             : 
+    3168           0 :         if (!(options & X86Inst::kOptionModMR))
+    3169           0 :           goto EmitVexEvexR;
+    3170             : 
+    3171             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3172             :         rbReg = o2.getId();
+    3173             : 
+    3174           0 :         ADD_VEX_W(true);
+    3175           0 :         goto EmitVexEvexR;
+    3176             :       }
+    3177             : 
+    3178           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Reg)) {
+    3179             :         opReg = x86PackRegAndVvvvv(o0.getId(), o2.getId());
+    3180             :         rmRel = &o1;
+    3181           0 :         goto EmitVexEvexM;
+    3182             :       }
+    3183             : 
+    3184           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Mem)) {
+    3185             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3186             :         rmRel = &o2;
+    3187             : 
+    3188           0 :         ADD_VEX_W(true);
+    3189           0 :         goto EmitVexEvexM;
+    3190             :       }
+    3191             :       break;
+    3192             : 
+    3193             :     case X86Inst::kEncodingVexRvmRmi_Lx:
+    3194           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    3195             :       ASMJIT_FALLTHROUGH;
+    3196             : 
+    3197           0 :     case X86Inst::kEncodingVexRvmRmi:
+    3198           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
+    3199             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3200             :         rbReg = o2.getId();
+    3201           0 :         goto EmitVexEvexR;
+    3202             :       }
+    3203             : 
+    3204           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Mem)) {
+    3205             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3206             :         rmRel = &o2;
+    3207           0 :         goto EmitVexEvexM;
+    3208             :       }
+    3209             : 
+    3210             :       // The following instructions use the secondary opcode.
+    3211           0 :       opCode &= X86Inst::kOpCode_LL_Mask;
+    3212           0 :       opCode |= commonData->getAltOpCode();
+    3213             : 
+    3214             :       imVal = static_cast<const Imm&>(o2).getInt64();
+    3215             :       imLen = 1;
+    3216             : 
+    3217           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    3218             :         opReg = o0.getId();
+    3219             :         rbReg = o1.getId();
+    3220           0 :         goto EmitVexEvexR;
+    3221             :       }
+    3222             : 
+    3223           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Imm)) {
+    3224             :         opReg = o0.getId();
+    3225             :         rmRel = &o1;
+    3226           0 :         goto EmitVexEvexM;
+    3227             :       }
+    3228             :       break;
+    3229             : 
+    3230           0 :     case X86Inst::kEncodingVexRvmRmvRmi:
+    3231           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
+    3232             :         opReg = x86PackRegAndVvvvv(o0.getId(), o2.getId());
+    3233             :         rbReg = o1.getId();
+    3234             : 
+    3235           0 :         if (!(options & X86Inst::kOptionModMR))
+    3236           0 :           goto EmitVexEvexR;
+    3237             : 
+    3238             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3239             :         rbReg = o2.getId();
+    3240             : 
+    3241           0 :         ADD_VEX_W(true);
+    3242           0 :         goto EmitVexEvexR;
+    3243             :       }
+    3244             : 
+    3245           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Reg)) {
+    3246             :         opReg = x86PackRegAndVvvvv(o0.getId(), o2.getId());
+    3247             :         rmRel = &o1;
+    3248             : 
+    3249           0 :         goto EmitVexEvexM;
+    3250             :       }
+    3251             : 
+    3252           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Mem)) {
+    3253             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3254             :         rmRel = &o2;
+    3255             : 
+    3256           0 :         ADD_VEX_W(true);
+    3257           0 :         goto EmitVexEvexM;
+    3258             :       }
+    3259             : 
+    3260             :       // The following instructions use the secondary opcode.
+    3261             :       opCode = commonData->getAltOpCode();
+    3262             : 
+    3263             :       imVal = static_cast<const Imm&>(o2).getInt64();
+    3264             :       imLen = 1;
+    3265             : 
+    3266           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    3267             :         opReg = o0.getId();
+    3268             :         rbReg = o1.getId();
+    3269           0 :         goto EmitVexEvexR;
+    3270             :       }
+    3271             : 
+    3272           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Imm)) {
+    3273             :         opReg = o0.getId();
+    3274             :         rmRel = &o1;
+    3275           0 :         goto EmitVexEvexM;
+    3276             :       }
+    3277             :       break;
+    3278             : 
+    3279           0 :     case X86Inst::kEncodingVexRvmMr:
+    3280           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
+    3281             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3282             :         rbReg = o2.getId();
+    3283           0 :         goto EmitVexEvexR;
+    3284             :       }
+    3285             : 
+    3286           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Mem)) {
+    3287             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3288             :         rmRel = &o2;
+    3289           0 :         goto EmitVexEvexM;
+    3290             :       }
+    3291             : 
+    3292             :       // The following instructions use the secondary opcode.
+    3293             :       opCode = commonData->getAltOpCode();
+    3294             : 
+    3295           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    3296             :         opReg = o1.getId();
+    3297             :         rbReg = o0.getId();
+    3298           0 :         goto EmitVexEvexR;
+    3299             :       }
+    3300             : 
+    3301           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    3302             :         opReg = o1.getId();
+    3303             :         rmRel = &o0;
+    3304           0 :         goto EmitVexEvexM;
+    3305             :       }
+    3306             :       break;
+    3307             : 
+    3308             :     case X86Inst::kEncodingVexRvmMvr_Lx:
+    3309           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    3310             :       ASMJIT_FALLTHROUGH;
+    3311             : 
+    3312           0 :     case X86Inst::kEncodingVexRvmMvr:
+    3313           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
+    3314             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3315             :         rbReg = o2.getId();
+    3316           0 :         goto EmitVexEvexR;
+    3317             :       }
+    3318             : 
+    3319           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Mem)) {
+    3320             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3321             :         rmRel = &o2;
+    3322           0 :         goto EmitVexEvexM;
+    3323             :       }
+    3324             : 
+    3325             :       // The following instruction uses the secondary opcode.
+    3326           0 :       opCode &= X86Inst::kOpCode_LL_Mask;
+    3327           0 :       opCode |= commonData->getAltOpCode();
+    3328             : 
+    3329           0 :       if (isign3 == ENC_OPS3(Mem, Reg, Reg)) {
+    3330             :         opReg = x86PackRegAndVvvvv(o2.getId(), o1.getId());
+    3331             :         rmRel = &o0;
+    3332           0 :         goto EmitVexEvexM;
+    3333             :       }
+    3334             :       break;
+    3335             : 
+    3336             :     case X86Inst::kEncodingVexRvmVmi_Lx:
+    3337           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    3338             :       ASMJIT_FALLTHROUGH;
+    3339             : 
+    3340           0 :     case X86Inst::kEncodingVexRvmVmi:
+    3341           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
+    3342             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3343             :         rbReg = o2.getId();
+    3344           0 :         goto EmitVexEvexR;
+    3345             :       }
+    3346             : 
+    3347           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Mem)) {
+    3348             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3349             :         rmRel = &o2;
+    3350           0 :         goto EmitVexEvexM;
+    3351             :       }
+    3352             : 
+    3353             :       // The following instruction uses the secondary opcode.
+    3354           0 :       opCode &= X86Inst::kOpCode_LL_Mask;
+    3355           0 :       opCode |= commonData->getAltOpCode();
+    3356             :       opReg = x86ExtractO(opCode);
+    3357             : 
+    3358             :       imVal = static_cast<const Imm&>(o2).getInt64();
+    3359             :       imLen = 1;
+    3360             : 
+    3361           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    3362             :         opReg = x86PackRegAndVvvvv(opReg, o0.getId());
+    3363             :         rbReg = o1.getId();
+    3364           0 :         goto EmitVexEvexR;
+    3365             :       }
+    3366             : 
+    3367           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Imm)) {
+    3368             :         opReg = x86PackRegAndVvvvv(opReg, o0.getId());
+    3369             :         rmRel = &o1;
+    3370           0 :         goto EmitVexEvexM;
+    3371             :       }
+    3372             :       break;
+    3373             : 
+    3374             :     case X86Inst::kEncodingVexVm_Wx:
+    3375           0 :       ADD_REX_W(X86Reg::isGpq(o0) | X86Reg::isGpq(o1));
+    3376             :       ASMJIT_FALLTHROUGH;
+    3377             : 
+    3378             :     case X86Inst::kEncodingVexVm:
+    3379           0 :       if (isign3 == ENC_OPS2(Reg, Reg)) {
+    3380             :         opReg = x86PackRegAndVvvvv(opReg, o0.getId());
+    3381             :         rbReg = o1.getId();
+    3382           0 :         goto EmitVexEvexR;
+    3383             :       }
+    3384             : 
+    3385           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    3386             :         opReg = x86PackRegAndVvvvv(opReg, o0.getId());
+    3387             :         rmRel = &o1;
+    3388           0 :         goto EmitVexEvexM;
+    3389             :       }
+    3390             :       break;
+    3391             : 
+    3392           0 :     case X86Inst::kEncodingVexEvexVmi_Lx:
+    3393           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Imm))
+    3394           0 :         opCode |= X86Inst::kOpCode_MM_ForceEvex;
+    3395             :       ASMJIT_FALLTHROUGH;
+    3396             : 
+    3397             :     case X86Inst::kEncodingVexVmi_Lx:
+    3398           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    3399             :       ASMJIT_FALLTHROUGH;
+    3400             : 
+    3401           0 :     case X86Inst::kEncodingVexVmi:
+    3402             :       imVal = static_cast<const Imm&>(o2).getInt64();
+    3403             :       imLen = 1;
+    3404             : 
+    3405           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Imm)) {
+    3406             :         opReg = x86PackRegAndVvvvv(opReg, o0.getId());
+    3407             :         rbReg = o1.getId();
+    3408           0 :         goto EmitVexEvexR;
+    3409             :       }
+    3410             : 
+    3411           0 :       if (isign3 == ENC_OPS3(Reg, Mem, Imm)) {
+    3412             :         opReg = x86PackRegAndVvvvv(opReg, o0.getId());
+    3413             :         rmRel = &o1;
+    3414           0 :         goto EmitVexEvexM;
+    3415             :       }
+    3416             :       break;
+    3417             : 
+    3418             :     case X86Inst::kEncodingVexRvrmRvmr_Lx:
+    3419           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    3420             :       ASMJIT_FALLTHROUGH;
+    3421             : 
+    3422           0 :     case X86Inst::kEncodingVexRvrmRvmr: {
+    3423           0 :       const uint32_t isign4 = isign3 + (o3.getOp() << 9);
+    3424             : 
+    3425           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
+    3426           0 :         imVal = o3.getId() << 4;
+    3427             :         imLen = 1;
+    3428             : 
+    3429             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3430             :         rbReg = o2.getId();
+    3431             : 
+    3432           0 :         goto EmitVexEvexR;
+    3433             :       }
+    3434             : 
+    3435           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Reg, Mem)) {
+    3436           0 :         imVal = o2.getId() << 4;
+    3437             :         imLen = 1;
+    3438             : 
+    3439             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3440             :         rmRel = &o3;
+    3441             : 
+    3442           0 :         ADD_VEX_W(true);
+    3443           0 :         goto EmitVexEvexM;
+    3444             :       }
+    3445             : 
+    3446           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Mem, Reg)) {
+    3447           0 :         imVal = o3.getId() << 4;
+    3448             :         imLen = 1;
+    3449             : 
+    3450             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3451             :         rmRel = &o2;
+    3452             : 
+    3453           0 :         goto EmitVexEvexM;
+    3454             :       }
+    3455             :       break;
+    3456             :     }
+    3457             : 
+    3458           0 :     case X86Inst::kEncodingVexRvrmiRvmri_Lx: {
+    3459           0 :       if (!(options & CodeEmitter::kOptionOp4Op5Used) || !_op4.isImm())
+    3460           0 :         goto InvalidInstruction;
+    3461             : 
+    3462           0 :       const uint32_t isign4 = isign3 + (o3.getOp() << 9);
+    3463           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize() | o2.getSize() | o3.getSize());
+    3464             : 
+    3465           0 :       imVal = static_cast<const Imm&>(_op4).getUInt8() & 0x0F;
+    3466             :       imLen = 1;
+    3467             : 
+    3468           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
+    3469           0 :         imVal |= o3.getId() << 4;
+    3470             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3471             :         rbReg = o2.getId();
+    3472             : 
+    3473           0 :         goto EmitVexEvexR;
+    3474             :       }
+    3475             : 
+    3476           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Reg, Mem)) {
+    3477           0 :         imVal |= o2.getId() << 4;
+    3478             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3479             :         rmRel = &o3;
+    3480             : 
+    3481           0 :         ADD_VEX_W(true);
+    3482           0 :         goto EmitVexEvexM;
+    3483             :       }
+    3484             : 
+    3485           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Mem, Reg)) {
+    3486           0 :         imVal |= o3.getId() << 4;
+    3487             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3488             :         rmRel = &o2;
+    3489             : 
+    3490           0 :         goto EmitVexEvexM;
+    3491             :       }
+    3492             :       break;
+    3493             :     }
+    3494             : 
+    3495           0 :     case X86Inst::kEncodingVexMovssMovsd:
+    3496           0 :       if (isign3 == ENC_OPS3(Reg, Reg, Reg)) {
+    3497           0 :         goto CaseVexRvm_R;
+    3498             :       }
+    3499             : 
+    3500           0 :       if (isign3 == ENC_OPS2(Reg, Mem)) {
+    3501             :         opReg = o0.getId();
+    3502             :         rmRel = &o1;
+    3503           0 :         goto EmitVexEvexM;
+    3504             :       }
+    3505             : 
+    3506           0 :       if (isign3 == ENC_OPS2(Mem, Reg)) {
+    3507             :         opCode = commonData->getAltOpCode();
+    3508             :         opReg = o1.getId();
+    3509             :         rmRel = &o0;
+    3510           0 :         goto EmitVexEvexM;
+    3511             :       }
+    3512             :       break;
+    3513             : 
+    3514             :     // ------------------------------------------------------------------------
+    3515             :     // [FMA4]
+    3516             :     // ------------------------------------------------------------------------
+    3517             : 
+    3518             :     case X86Inst::kEncodingFma4_Lx:
+    3519             :       // It's fine to just check the first operand, second is just for sanity.
+    3520           0 :       opCode |= x86OpCodeLBySize(o0.getSize() | o1.getSize());
+    3521             :       ASMJIT_FALLTHROUGH;
+    3522             : 
+    3523           0 :     case X86Inst::kEncodingFma4: {
+    3524           0 :       const uint32_t isign4 = isign3 + (o3.getOp() << 9);
+    3525             : 
+    3526           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Reg, Reg)) {
+    3527           0 :         imVal = o3.getId() << 4;
+    3528             :         imLen = 1;
+    3529             : 
+    3530             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3531             :         rbReg = o2.getId();
+    3532             : 
+    3533           0 :         goto EmitVexEvexR;
+    3534             :       }
+    3535             : 
+    3536           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Reg, Mem)) {
+    3537           0 :         imVal = o2.getId() << 4;
+    3538             :         imLen = 1;
+    3539             : 
+    3540             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3541             :         rmRel = &o3;
+    3542             : 
+    3543           0 :         ADD_VEX_W(true);
+    3544           0 :         goto EmitVexEvexM;
+    3545             :       }
+    3546             : 
+    3547           0 :       if (isign4 == ENC_OPS4(Reg, Reg, Mem, Reg)) {
+    3548           0 :         imVal = o3.getId() << 4;
+    3549             :         imLen = 1;
+    3550             : 
+    3551             :         opReg = x86PackRegAndVvvvv(o0.getId(), o1.getId());
+    3552             :         rmRel = &o2;
+    3553             : 
+    3554           0 :         goto EmitVexEvexM;
+    3555             :       }
+    3556             :       break;
+    3557             :     }
+    3558             :   }
+    3559           0 :   goto InvalidInstruction;
+    3560             : 
+    3561             :   // --------------------------------------------------------------------------
+    3562             :   // [Emit - X86]
+    3563             :   // --------------------------------------------------------------------------
+    3564             : 
+    3565           0 : EmitX86OpMovAbs:
+    3566             :   imLen = getGpSize();
+    3567             : 
+    3568             :   // Segment-override prefix.
+    3569           0 :   if (rmRel->as<X86Mem>().hasSegment())
+    3570           0 :     EMIT_BYTE(x86SegmentPrefix[rmRel->as<X86Mem>().getSegmentId()]);
+    3571             : 
+    3572           0 : EmitX86Op:
+    3573             :   // Emit mandatory instruction prefix.
+    3574        1948 :   EMIT_PP(opCode);
+    3575             : 
+    3576             :   // Emit REX prefix (64-bit only).
+    3577             :   {
+    3578             :     uint32_t rex = x86ExtractREX(opCode, options);
+    3579        1948 :     if (rex) {
+    3580           0 :       if (options & X86Inst::_kOptionInvalidRex)
+    3581           0 :         goto InvalidRexPrefix;
+    3582           0 :       EMIT_BYTE(rex | kX86ByteRex);
+    3583             :     }
+    3584             :   }
+    3585             : 
+    3586             :   // Emit instruction opcodes.
+    3587        1948 :   EMIT_MM_OP(opCode);
+    3588             : 
+    3589        1948 :   if (imLen != 0)
+    3590           0 :     goto EmitImm;
+    3591             :   else
+    3592        1948 :     goto EmitDone;
+    3593             : 
+    3594        9928 : EmitX86OpReg:
+    3595             :   // Emit mandatory instruction prefix.
+    3596        9928 :   EMIT_PP(opCode);
+    3597             : 
+    3598             :   // Emit REX prefix (64-bit only).
+    3599             :   {
+    3600             :     uint32_t rex = x86ExtractREX(opCode, options) |
+    3601        9928 :                    (opReg >> 3); // Rex.B (0x01).
+    3602        9928 :     if (rex) {
+    3603        7688 :       EMIT_BYTE(rex | kX86ByteRex);
+    3604        7688 :       if (options & X86Inst::_kOptionInvalidRex)
+    3605           0 :         goto InvalidRexPrefix;
+    3606        7688 :       opReg &= 0x7;
+    3607             :     }
+    3608             :   }
+    3609             : 
+    3610             :   // Emit instruction opcodes.
+    3611        9928 :   opCode += opReg;
+    3612        9928 :   EMIT_MM_OP(opCode);
+    3613             : 
+    3614        9928 :   if (imLen != 0)
+    3615        7688 :     goto EmitImm;
+    3616             :   else
+    3617        2240 :     goto EmitDone;
+    3618             : 
+    3619           0 : EmitX86OpImplicitMem:
+    3620             :   // NOTE: Don't change the emit order here, it's compatible with KeyStone/LLVM.
+    3621           0 :   rmInfo = x86MemInfo[rmRel->as<X86Mem>().getBaseIndexType()];
+    3622           0 :   if (ASMJIT_UNLIKELY(rmRel->as<X86Mem>().hasOffset() || (rmInfo & kX86MemInfo_Index)))
+    3623           0 :     goto InvalidInstruction;
+    3624             : 
+    3625             :   // Emit mandatory instruction prefix.
+    3626           0 :   EMIT_PP(opCode);
+    3627             : 
+    3628             :   // Emit REX prefix (64-bit only).
+    3629             :   {
+    3630             :     uint32_t rex = x86ExtractREX(opCode, options);
+    3631           0 :     if (rex) {
+    3632           0 :       if (options & X86Inst::_kOptionInvalidRex)
+    3633           0 :         goto InvalidRexPrefix;
+    3634           0 :       EMIT_BYTE(rex | kX86ByteRex);
+    3635             :     }
+    3636             :   }
+    3637             : 
+    3638             :   // Segment-override prefix.
+    3639           0 :   if (rmRel->as<X86Mem>().hasSegment())
+    3640           0 :     EMIT_BYTE(x86SegmentPrefix[rmRel->as<X86Mem>().getSegmentId()]);
+    3641             : 
+    3642             :   // Address-override prefix.
+    3643           0 :   if (rmInfo & _getAddressOverrideMask())
+    3644           0 :     EMIT_BYTE(0x67);
+    3645             : 
+    3646             :   // Emit instruction opcodes.
+    3647           0 :   EMIT_MM_OP(opCode);
+    3648             : 
+    3649             :   if (imLen != 0)
+    3650             :     goto EmitImm;
+    3651             :   else
+    3652           0 :     goto EmitDone;
+    3653             : 
+    3654       21958 : EmitX86R:
+    3655             :   // Mandatory instruction prefix.
+    3656       21958 :   EMIT_PP(opCode);
+    3657             : 
+    3658             :   // Rex prefix (64-bit only).
+    3659             :   {
+    3660       21958 :     uint32_t rex = x86ExtractREX(opCode, options) |
+    3661       21958 :                    ((opReg & 0x08) >> 1) | // REX.R (0x04).
+    3662       21958 :                    ((rbReg       ) >> 3) ; // REX.B (0x01).
+    3663       21958 :     if (rex) {
+    3664        2198 :       if (options & X86Inst::_kOptionInvalidRex)
+    3665           0 :         goto InvalidRexPrefix;
+    3666        2198 :       EMIT_BYTE(rex | kX86ByteRex);
+    3667        2198 :       opReg &= 0x07;
+    3668        2198 :       rbReg &= 0x07;
+    3669             :     }
+    3670             :   }
+    3671             : 
+    3672             :   // Instruction opcodes.
+    3673       21958 :   EMIT_MM_OP(opCode);
+    3674             :   // ModR.
+    3675       21958 :   EMIT_BYTE(x86EncodeMod(3, opReg, rbReg));
+    3676             : 
+    3677       21958 :   if (imLen != 0)
+    3678        1984 :     goto EmitImm;
+    3679             :   else
+    3680       19974 :     goto EmitDone;
+    3681             : 
+    3682       14528 : EmitX86M:
+    3683             :   ASMJIT_ASSERT(rmRel != nullptr);
+    3684             :   ASMJIT_ASSERT(rmRel->getOp() == Operand::kOpMem);
+    3685       14528 :   rmInfo = x86MemInfo[rmRel->as<X86Mem>().getBaseIndexType()];
+    3686             : 
+    3687             :   // GP instructions have never compressed displacement specified.
+    3688             :   ASMJIT_ASSERT((opCode & X86Inst::kOpCode_CDSHL_Mask) == 0);
+    3689             : 
+    3690             :   // Segment-override prefix.
+    3691       14528 :   if (rmRel->as<X86Mem>().hasSegment())
+    3692           0 :     EMIT_BYTE(x86SegmentPrefix[rmRel->as<X86Mem>().getSegmentId()]);
+    3693             : 
+    3694             :   // Address-override prefix.
+    3695       14528 :   if (rmInfo & _getAddressOverrideMask())
+    3696           0 :     EMIT_BYTE(0x67);
+    3697             : 
+    3698             :   // Mandatory instruction prefix.
+    3699       14528 :   EMIT_PP(opCode);
+    3700             : 
+    3701             :   rbReg = rmRel->as<X86Mem>().getBaseId();
+    3702             :   rxReg = rmRel->as<X86Mem>().getIndexId();
+    3703             : 
+    3704             :   // REX prefix (64-bit only).
+    3705             :   {
+    3706             :     uint32_t rex;
+    3707             : 
+    3708       14528 :     rex  = (rbReg >> 3) & 0x01; // REX.B (0x01).
+    3709       14528 :     rex |= (rxReg >> 2) & 0x02; // REX.X (0x02).
+    3710       14528 :     rex |= (opReg >> 1) & 0x04; // REX.R (0x04).
+    3711             : 
+    3712       14528 :     rex &= rmInfo;
+    3713       14528 :     rex |= x86ExtractREX(opCode, options);
+    3714             : 
+    3715       14528 :     if (rex) {
+    3716          82 :       if (options & X86Inst::_kOptionInvalidRex)
+    3717           0 :         goto InvalidRexPrefix;
+    3718          82 :       EMIT_BYTE(rex | kX86ByteRex);
+    3719          82 :       opReg &= 0x07;
+    3720             :     }
+    3721             :   }
+    3722             : 
+    3723             :   // Instruction opcodes.
+    3724       14528 :   EMIT_MM_OP(opCode);
+    3725             :   // ... Fall through ...
+    3726             : 
+    3727             :   // --------------------------------------------------------------------------
+    3728             :   // [Emit - MOD/SIB]
+    3729             :   // --------------------------------------------------------------------------
+    3730             : 
+    3731       14528 : EmitModSib:
+    3732       14528 :   if (!(rmInfo & (kX86MemInfo_Index | kX86MemInfo_67H_X86))) {
+    3733             :     // ==========|> [BASE + DISP8|DISP32].
+    3734       14528 :     if (rmInfo & kX86MemInfo_BaseGp) {
+    3735       14528 :       rbReg &= 0x7;
+    3736             :       relOffset = rmRel->as<X86Mem>().getOffsetLo32();
+    3737             : 
+    3738             :       uint32_t mod = x86EncodeMod(0, opReg, rbReg);
+    3739       14528 :       if (rbReg == X86Gp::kIdSp) {
+    3740             :         // [XSP|R12].
+    3741        8428 :         if (relOffset == 0) {
+    3742        1864 :           EMIT_BYTE(mod);
+    3743        1864 :           EMIT_BYTE(x86EncodeSib(0, 4, 4));
+    3744             :         }
+    3745             :         // [XSP|R12 + DISP8|DISP32].
+    3746             :         else {
+    3747        6564 :           uint32_t cdShift = (opCode & X86Inst::kOpCode_CDSHL_Mask) >> X86Inst::kOpCode_CDSHL_Shift;
+    3748        6564 :           int32_t cdOffset = relOffset >> cdShift;
+    3749             : 
+    3750        6564 :           if (Utils::isInt8(cdOffset) && relOffset == (cdOffset << cdShift)) {
+    3751        6564 :             EMIT_BYTE(mod + 0x40); // <- MOD(1, opReg, rbReg).
+    3752        6564 :             EMIT_BYTE(x86EncodeSib(0, 4, 4));
+    3753        6564 :             EMIT_BYTE(cdOffset & 0xFF);
+    3754             :           }
+    3755             :           else {
+    3756           0 :             EMIT_BYTE(mod + 0x80); // <- MOD(2, opReg, rbReg).
+    3757           0 :             EMIT_BYTE(x86EncodeSib(0, 4, 4));
+    3758           0 :             EMIT_32(relOffset);
+    3759             :           }
+    3760             :         }
+    3761             :       }
+    3762        6100 :       else if (rbReg != X86Gp::kIdBp && relOffset == 0) {
+    3763             :         // [BASE].
+    3764        3882 :         EMIT_BYTE(mod);
+    3765             :       }
+    3766             :       else {
+    3767             :         // [BASE + DISP8|DISP32].
+    3768        2218 :         uint32_t cdShift = (opCode & X86Inst::kOpCode_CDSHL_Mask) >> X86Inst::kOpCode_CDSHL_Shift;
+    3769        2218 :         int32_t cdOffset = relOffset >> cdShift;
+    3770             : 
+    3771        2218 :         if (Utils::isInt8(cdOffset) && relOffset == (cdOffset << cdShift)) {
+    3772        2206 :           EMIT_BYTE(mod + 0x40);
+    3773        2206 :           EMIT_BYTE(cdOffset & 0xFF);
+    3774             :         }
+    3775             :         else {
+    3776          12 :           EMIT_BYTE(mod + 0x80);
+    3777          12 :           EMIT_32(relOffset);
+    3778             :         }
+    3779             :       }
+    3780             :     }
+    3781             :     // ==========|> [ABSOLUTE | DISP32].
+    3782           0 :     else if (!(rmInfo & (kX86MemInfo_BaseLabel | kX86MemInfo_BaseRip))) {
+    3783           0 :       if (is32Bit()) {
+    3784             :         relOffset = rmRel->as<X86Mem>().getOffsetLo32();
+    3785           0 :         EMIT_BYTE(x86EncodeMod(0, opReg, 5));
+    3786           0 :         EMIT_32(relOffset);
+    3787             :       }
+    3788             :       else {
+    3789             :         uint64_t baseAddress = getCodeInfo().getBaseAddress();
+    3790             :         relOffset = rmRel->as<X86Mem>().getOffsetLo32();
+    3791             : 
+    3792             :         // Prefer absolute addressing mode if FS|GS segment override is present.
+    3793           0 :         bool absoluteValid = rmRel->as<X86Mem>().getOffsetHi32() == (relOffset >> 31);
+    3794           0 :         bool preferAbsolute = (rmRel->as<X86Mem>().getSegmentId() >= X86Seg::kIdFs) || rmRel->as<X86Mem>().isAbs();
+    3795             : 
+    3796             :         // If we know the base address and the memory operand points to an
+    3797             :         // absolute address it's possible to calculate REL32 that can be
+    3798             :         // be used as [RIP+REL32] in 64-bit mode.
+    3799           0 :         if (baseAddress != Globals::kNoBaseAddress && !preferAbsolute) {
+    3800             :           const uint32_t kModRel32Size = 5;
+    3801           0 :           uint64_t rip64 = baseAddress +
+    3802           0 :             static_cast<uint64_t>((uintptr_t)(cursor - _bufferData)) + imLen + kModRel32Size;
+    3803             : 
+    3804           0 :           uint64_t rel64 = static_cast<uint64_t>(rmRel->as<X86Mem>().getOffset()) - rip64;
+    3805           0 :           if (Utils::isInt32(static_cast<int64_t>(rel64))) {
+    3806           0 :             EMIT_BYTE(x86EncodeMod(0, opReg, 5));
+    3807           0 :             EMIT_32(static_cast<uint32_t>(rel64 & 0xFFFFFFFFU));
+    3808           0 :             if (imLen != 0)
+    3809           0 :               goto EmitImm;
+    3810             :             else
+    3811           0 :               goto EmitDone;
+    3812             :           }
+    3813             :         }
+    3814             : 
+    3815           0 :         if (ASMJIT_UNLIKELY(!absoluteValid))
+    3816           0 :           goto InvalidAddress64Bit;
+    3817             : 
+    3818           0 :         EMIT_BYTE(x86EncodeMod(0, opReg, 4));
+    3819           0 :         EMIT_BYTE(x86EncodeSib(0, 4, 5));
+    3820           0 :         EMIT_32(relOffset);
+    3821             :       }
+    3822             :     }
+    3823             :     // ==========|> [LABEL|RIP + DISP32]
+    3824             :     else {
+    3825           0 :       EMIT_BYTE(x86EncodeMod(0, opReg, 5));
+    3826             : 
+    3827           0 :       if (is32Bit()) {
+    3828           0 : EmitModSib_LabelRip_X86:
+    3829           0 :         if (ASMJIT_UNLIKELY(_code->_relocations.willGrow(&_code->_baseHeap) != kErrorOk))
+    3830           0 :           goto NoHeapMemory;
+    3831             : 
+    3832             :         relOffset = rmRel->as<X86Mem>().getOffsetLo32();
+    3833           0 :         if (rmInfo & kX86MemInfo_BaseLabel) {
+    3834             :           // [LABEL->ABS].
+    3835           0 :           label = _code->getLabelEntry(rmRel->as<X86Mem>().getBaseId());
+    3836           0 :           if (!label) goto InvalidLabel;
+    3837             : 
+    3838           0 :           err = _code->newRelocEntry(&re, RelocEntry::kTypeRelToAbs, 4);
+    3839           0 :           if (ASMJIT_UNLIKELY(err)) goto Failed;
+    3840             : 
+    3841           0 :           re->_sourceSectionId = _section->getId();
+    3842           0 :           re->_sourceOffset = static_cast<uint64_t>((uintptr_t)(cursor - _bufferData));
+    3843           0 :           re->_data = static_cast<int64_t>(relOffset);
+    3844             : 
+    3845           0 :           if (label->isBound()) {
+    3846             :             // Bound label.
+    3847           0 :             re->_data += static_cast<uint64_t>(label->getOffset());
+    3848           0 :             EMIT_32(0);
+    3849             :           }
+    3850             :           else {
+    3851             :             // Non-bound label.
+    3852           0 :             relOffset = -4 - imLen;
+    3853             :             relSize = 4;
+    3854           0 :             goto EmitRel;
+    3855             :           }
+    3856             :         }
+    3857             :         else {
+    3858             :           // [RIP->ABS].
+    3859           0 :           err = _code->newRelocEntry(&re, RelocEntry::kTypeRelToAbs, 4);
+    3860           0 :           if (ASMJIT_UNLIKELY(err)) goto Failed;
+    3861             : 
+    3862           0 :           re->_sourceSectionId = _section->getId();
+    3863           0 :           re->_sourceOffset = static_cast<uint64_t>((uintptr_t)(cursor - _bufferData));
+    3864           0 :           re->_data = re->_sourceOffset + static_cast<uint64_t>(static_cast<int64_t>(relOffset));
+    3865           0 :           EMIT_32(0);
+    3866             :         }
+    3867             :       }
+    3868             :       else {
+    3869             :         relOffset = rmRel->as<X86Mem>().getOffsetLo32();
+    3870           0 :         if (rmInfo & kX86MemInfo_BaseLabel) {
+    3871             :           // [RIP].
+    3872           0 :           label = _code->getLabelEntry(rmRel->as<X86Mem>().getBaseId());
+    3873           0 :           if (!label) goto InvalidLabel;
+    3874             : 
+    3875           0 :           relOffset -= (4 + imLen);
+    3876           0 :           if (label->isBound()) {
+    3877             :             // Bound label.
+    3878           0 :             relOffset += label->getOffset() - static_cast<int32_t>((intptr_t)(cursor - _bufferData));
+    3879           0 :             EMIT_32(static_cast<int32_t>(relOffset));
+    3880             :           }
+    3881             :           else {
+    3882             :             // Non-bound label.
+    3883             :             relSize = 4;
+    3884           0 :             goto EmitRel;
+    3885             :           }
+    3886             :         }
+    3887             :         else {
+    3888             :           // [RIP].
+    3889           0 :           EMIT_32(static_cast<int32_t>(relOffset));
+    3890             :         }
+    3891             :       }
+    3892             :     }
+    3893             :   }
+    3894           0 :   else if (!(rmInfo & kX86MemInfo_67H_X86)) {
+    3895             :     // ESP|RSP can't be used as INDEX in pure SIB mode, however, VSIB mode
+    3896             :     // allows XMM4|YMM4|ZMM4 (that's why the check is before the label).
+    3897           0 :     if (ASMJIT_UNLIKELY(rxReg == X86Gp::kIdSp))
+    3898           0 :       goto InvalidAddressIndex;
+    3899             : 
+    3900           0 : EmitModVSib:
+    3901           0 :     rxReg &= 0x7;
+    3902             : 
+    3903             :     // ==========|> [BASE + INDEX + DISP8|DISP32].
+    3904           0 :     if (rmInfo & kX86MemInfo_BaseGp) {
+    3905           0 :       rbReg &= 0x7;
+    3906             :       relOffset = rmRel->as<X86Mem>().getOffsetLo32();
+    3907             : 
+    3908             :       uint32_t mod = x86EncodeMod(0, opReg, 4);
+    3909             :       uint32_t sib = x86EncodeSib(rmRel->as<X86Mem>().getShift(), rxReg, rbReg);
+    3910             : 
+    3911           0 :       if (relOffset == 0 && rbReg != X86Gp::kIdBp) {
+    3912             :         // [BASE + INDEX << SHIFT].
+    3913           0 :         EMIT_BYTE(mod);
+    3914           0 :         EMIT_BYTE(sib);
+    3915             :       }
+    3916             :       else {
+    3917           0 :         uint32_t cdShift = (opCode & X86Inst::kOpCode_CDSHL_Mask) >> X86Inst::kOpCode_CDSHL_Shift;
+    3918           0 :         int32_t cdOffset = relOffset >> cdShift;
+    3919             : 
+    3920           0 :         if (Utils::isInt8(cdOffset) && relOffset == (cdOffset << cdShift)) {
+    3921             :           // [BASE + INDEX << SHIFT + DISP8].
+    3922           0 :           EMIT_BYTE(mod + 0x40); // <- MOD(1, opReg, 4).
+    3923           0 :           EMIT_BYTE(sib);
+    3924           0 :           EMIT_BYTE(cdOffset);
+    3925             :         }
+    3926             :         else {
+    3927             :           // [BASE + INDEX << SHIFT + DISP32].
+    3928           0 :           EMIT_BYTE(mod + 0x80); // <- MOD(2, opReg, 4).
+    3929           0 :           EMIT_BYTE(sib);
+    3930           0 :           EMIT_32(relOffset);
+    3931             :         }
+    3932             :       }
+    3933             :     }
+    3934             :     // ==========|> [INDEX + DISP32].
+    3935           0 :     else if (!(rmInfo & (kX86MemInfo_BaseLabel | kX86MemInfo_BaseRip))) {
+    3936             :       // [INDEX << SHIFT + DISP32].
+    3937           0 :       EMIT_BYTE(x86EncodeMod(0, opReg, 4));
+    3938           0 :       EMIT_BYTE(x86EncodeSib(rmRel->as<X86Mem>().getShift(), rxReg, 5));
+    3939             : 
+    3940             :       relOffset = rmRel->as<X86Mem>().getOffsetLo32();
+    3941           0 :       EMIT_32(relOffset);
+    3942             :     }
+    3943             :     // ==========|> [LABEL|RIP + INDEX + DISP32].
+    3944             :     else {
+    3945           0 :       if (is32Bit()) {
+    3946           0 :         EMIT_BYTE(x86EncodeMod(0, opReg, 4));
+    3947           0 :         EMIT_BYTE(x86EncodeSib(rmRel->as<X86Mem>().getShift(), rxReg, 5));
+    3948           0 :         goto EmitModSib_LabelRip_X86;
+    3949             :       }
+    3950             :       else {
+    3951             :         // NOTE: This also handles VSIB+RIP, which is not allowed in 64-bit mode.
+    3952           0 :         goto InvalidAddress;
+    3953             :       }
+    3954             :     }
+    3955             :   }
+    3956             :   else {
+    3957             :     // 16-bit address mode (32-bit mode with 67 override prefix).
+    3958           0 :     relOffset = (static_cast<int32_t>(rmRel->as<X86Mem>().getOffsetLo32()) << 16) >> 16;
+    3959             : 
+    3960             :     // NOTE: 16-bit addresses don't use SIB byte and their encoding differs. We
+    3961             :     // use a table-based approach to calculate the proper MOD byte as it's easier.
+    3962             :     // Also, not all BASE [+ INDEX] combinations are supported in 16-bit mode, so
+    3963             :     // this may fail.
+    3964             :     const uint32_t kBaseGpIdx = (kX86MemInfo_BaseGp | kX86MemInfo_Index);
+    3965             : 
+    3966           0 :     if (rmInfo & kBaseGpIdx) {
+    3967             :       // ==========|> [BASE + INDEX + DISP16].
+    3968             :       uint32_t mod;
+    3969             : 
+    3970           0 :       rbReg &= 0x7;
+    3971           0 :       rxReg &= 0x7;
+    3972             : 
+    3973           0 :       if ((rmInfo & kBaseGpIdx) == kBaseGpIdx) {
+    3974             :         uint32_t shf = rmRel->as<X86Mem>().getShift();
+    3975           0 :         if (ASMJIT_UNLIKELY(shf != 0))
+    3976           0 :           goto InvalidAddress;
+    3977           0 :         mod = x86Mod16BaseIndexTable[(rbReg << 3) + rxReg];
+    3978             :       }
+    3979             :       else {
+    3980           0 :         if (rmInfo & kX86MemInfo_Index)
+    3981             :           rbReg = rxReg;
+    3982           0 :         mod = x86Mod16BaseTable[rbReg];
+    3983             :       }
+    3984             : 
+    3985           0 :       if (ASMJIT_UNLIKELY(mod == 0xFF))
+    3986           0 :         goto InvalidAddress;
+    3987             : 
+    3988           0 :       mod += opReg << 3;
+    3989           0 :       if (relOffset == 0 && mod != 0x06) {
+    3990           0 :         EMIT_BYTE(mod);
+    3991             :       }
+    3992           0 :       else if (Utils::isInt8(relOffset)) {
+    3993           0 :         EMIT_BYTE(mod + 0x40);
+    3994           0 :         EMIT_BYTE(relOffset);
+    3995             :       }
+    3996             :       else {
+    3997           0 :         EMIT_BYTE(mod + 0x80);
+    3998           0 :         EMIT_16(relOffset);
+    3999             :       }
+    4000             :     }
+    4001             :     else {
+    4002             :       // Not supported in 16-bit addresses.
+    4003           0 :       if (rmInfo & (kX86MemInfo_BaseRip | kX86MemInfo_BaseLabel))
+    4004           0 :         goto InvalidAddress;
+    4005             : 
+    4006             :       // ==========|> [DISP16].
+    4007           0 :       EMIT_BYTE(opReg | 0x06);
+    4008           0 :       EMIT_16(relOffset);
+    4009             :     }
+    4010             :   }
+    4011             : 
+    4012       14528 :   if (imLen != 0)
+    4013           0 :     goto EmitImm;
+    4014             :   else
+    4015       14528 :     goto EmitDone;
+    4016             : 
+    4017             :   // --------------------------------------------------------------------------
+    4018             :   // [Emit - FPU]
+    4019             :   // --------------------------------------------------------------------------
+    4020             : 
+    4021           0 : EmitFpuOp:
+    4022             :   // Mandatory instruction prefix.
+    4023           0 :   EMIT_PP(opCode);
+    4024             : 
+    4025             :   // FPU instructions consist of two opcodes.
+    4026           0 :   EMIT_BYTE(opCode >> X86Inst::kOpCode_FPU_2B_Shift);
+    4027           0 :   EMIT_BYTE(opCode);
+    4028           0 :   goto EmitDone;
+    4029             : 
+    4030             :   // --------------------------------------------------------------------------
+    4031             :   // [Emit - VEX / EVEX]
+    4032             :   // --------------------------------------------------------------------------
+    4033             : 
+    4034             : EmitVexEvexOp:
+    4035             :   {
+    4036             :     // These don't use immediate.
+    4037             :     ASMJIT_ASSERT(imLen == 0);
+    4038             : 
+    4039             :     // Only 'vzeroall' and 'vzeroupper' instructions use this encoding, they
+    4040             :     // don't define 'W' to be '1' so we can just check the 'mmmmm' field. Both
+    4041             :     // functions can encode by using VEV2 prefix so VEV3 is basically only used
+    4042             :     // when forced from outside.
+    4043             :     ASMJIT_ASSERT((opCode & X86Inst::kOpCode_W) == 0);
+    4044             : 
+    4045           0 :     uint32_t x = ((opCode & X86Inst::kOpCode_MM_Mask   ) >> (X86Inst::kOpCode_MM_Shift     )) |
+    4046           0 :                  ((opCode & X86Inst::kOpCode_LL_Mask   ) >> (X86Inst::kOpCode_LL_Shift - 10)) |
+    4047           0 :                  ((opCode & X86Inst::kOpCode_PP_VEXMask) >> (X86Inst::kOpCode_PP_Shift -  8)) |
+    4048           0 :                  ((options & X86Inst::kOptionVex3      ) >> (X86Inst::kOpCode_MM_Shift     )) ;
+    4049           0 :     if (x & 0x04U) {
+    4050           0 :       x  = (x & (0x4 ^ 0xFFFF)) << 8;                    // [00000000|00000Lpp|0000m0mm|00000000].
+    4051           0 :       x ^= (kX86ByteVex3) |                              // [........|00000Lpp|0000m0mm|__VEX3__].
+    4052             :            (0x07U  << 13) |                              // [........|00000Lpp|1110m0mm|__VEX3__].
+    4053           0 :            (0x0FU  << 19) |                              // [........|01111Lpp|1110m0mm|__VEX3__].
+    4054           0 :            (opCode << 24) ;                              // [_OPCODE_|01111Lpp|1110m0mm|__VEX3__].
+    4055             : 
+    4056           0 :       EMIT_32(x);
+    4057           0 :       goto EmitDone;
+    4058             :     }
+    4059             :     else {
+    4060           0 :       x = ((x >> 8) ^ x) ^ 0xF9;
+    4061           0 :       EMIT_BYTE(kX86ByteVex2);
+    4062           0 :       EMIT_BYTE(x);
+    4063           0 :       EMIT_BYTE(opCode);
+    4064           0 :       goto EmitDone;
+    4065             :     }
+    4066             :   }
+    4067             : 
+    4068           0 : EmitVexEvexR:
+    4069             :   {
+    4070             :     // VEX instructions use only 0-1 BYTE immediate.
+    4071             :     ASMJIT_ASSERT(imLen <= 1);
+    4072             : 
+    4073             :     // Construct `x` - a complete EVEX|VEX prefix.
+    4074           0 :     uint32_t x = ((opReg << 4) & 0xF980U) |              // [........|........|Vvvvv..R|R.......].
+    4075           0 :                  ((rbReg << 2) & 0x0060U) |              // [........|........|........|.BB.....].
+    4076             :                  (x86ExtractLLMM(opCode, options)) |     // [........|.LL.....|Vvvvv..R|RBBmmmmm].
+    4077           0 :                  (_extraReg.getId() << 16);              // [........|.LL..aaa|Vvvvv..R|RBBmmmmm].
+    4078           0 :     opReg &= 0x7;
+    4079             : 
+    4080             :     // Mark invalid VEX (force EVEX) case:               // [@.......|.LL..aaa|Vvvvv..R|RBBmmmmm].
+    4081           0 :     x |= (~commonData->getFlags() & X86Inst::kFlagVex) << (31 - Utils::firstBitOfT<X86Inst::kFlagVex>());
+    4082             : 
+    4083             :     // Handle AVX512 options by a single branch.
+    4084             :     const uint32_t kAvx512Options = X86Inst::kOptionZMask   |
+    4085             :                                     X86Inst::kOption1ToX    |
+    4086             :                                     X86Inst::kOptionSAE     |
+    4087             :                                     X86Inst::kOptionER      ;
+    4088           0 :     if (options & kAvx512Options) {
+    4089             :       // Memory broadcast without a memory operand is invalid.
+    4090           0 :       if (ASMJIT_UNLIKELY(options & X86Inst::kOption1ToX))
+    4091           0 :         goto InvalidBroadcast;
+    4092             : 
+    4093             :       // TODO: {sae} and {er}
+    4094           0 :       x |= options & X86Inst::kOptionZMask;              // [@.......|zLL..aaa|Vvvvv..R|RBBmmmmm].
+    4095             :     }
+    4096             : 
+    4097             :     // Check if EVEX is required by checking bits in `x` :  [@.......|xx...xxx|x......x|.x.x....].
+    4098           0 :     if (x & 0x80C78150U) {
+    4099           0 :       uint32_t y = ((x << 4) & 0x00080000U) |            // [@.......|....V...|........|........].
+    4100           0 :                    ((x >> 4) & 0x00000010U) ;            // [@.......|....V...|........|...R....].
+    4101           0 :       x  = (x & 0x00FF78E3U) | y;                        // [........|zLL.Vaaa|0vvvv000|RBBR00mm].
+    4102           0 :       x  = (x << 8) |                                    // [zLL.Vaaa|0vvvv000|RBBR00mm|00000000].
+    4103           0 :            ((opCode >> kSHR_W_PP) & 0x00830000U) |       // [zLL.Vaaa|Wvvvv0pp|RBBR00mm|00000000].
+    4104           0 :            ((opCode >> kSHR_W_EW) & 0x00800000U) ;       // [zLL.Vaaa|Wvvvv0pp|RBBR00mm|00000000] (added EVEX.W).
+    4105             :                                                          //      _     ____    ____
+    4106           0 :       x ^= 0x087CF000U | kX86ByteEvex;                   // [zLL.Vaaa|Wvvvv1pp|RBBR00mm|01100010].
+    4107             : 
+    4108             :       EMIT_32(x);
+    4109           0 :       EMIT_BYTE(opCode);
+    4110             : 
+    4111           0 :       rbReg &= 0x7;
+    4112           0 :       EMIT_BYTE(x86EncodeMod(3, opReg, rbReg));
+    4113             : 
+    4114           0 :       if (imLen == 0) goto EmitDone;
+    4115           0 :       EMIT_BYTE(imVal & 0xFF);
+    4116           0 :       goto EmitDone;
+    4117             :     }
+    4118             : 
+    4119             :     // Not EVEX, prepare `x` for VEX2 or VEX3:          x = [........|00L00000|0vvvv000|R0B0mmmm].
+    4120           0 :     x |= ((opCode >> (kSHR_W_PP + 8)) & 0x8300U) |       // [00000000|00L00000|Wvvvv0pp|R0B0mmmm].
+    4121           0 :          ((x      >> 11             ) & 0x0400U) ;       // [00000000|00L00000|WvvvvLpp|R0B0mmmm].
+    4122             : 
+    4123             :     // Check if VEX3 is required / forced:                  [........|........|x.......|..x..x..].
+    4124           0 :     if (x & 0x0008024U) {
+    4125           0 :       uint32_t xorMsk = x86VEXPrefix[x & 0xF] | (opCode << 24);
+    4126             : 
+    4127             :       // Clear 'FORCE-VEX3' bit and all high bits.
+    4128           0 :       x  = (x & (0x4 ^ 0xFFFF)) << 8;                    // [00000000|WvvvvLpp|R0B0m0mm|00000000].
+    4129             :                                                          //            ____    _ _
+    4130           0 :       x ^= xorMsk;                                       // [_OPCODE_|WvvvvLpp|R1Bmmmmm|VEX3|XOP].
+    4131             :       EMIT_32(x);
+    4132             : 
+    4133           0 :       rbReg &= 0x7;
+    4134           0 :       EMIT_BYTE(x86EncodeMod(3, opReg, rbReg));
+    4135             : 
+    4136           0 :       if (imLen == 0) goto EmitDone;
+    4137           0 :       EMIT_BYTE(imVal & 0xFF);
+    4138           0 :       goto EmitDone;
+    4139             :     }
+    4140             :     else {
+    4141             :       // 'mmmmm' must be '00001'.
+    4142             :       ASMJIT_ASSERT((x & 0x1F) == 0x01);
+    4143             : 
+    4144           0 :       x = ((x >> 8) ^ x) ^ 0xF9;
+    4145           0 :       EMIT_BYTE(kX86ByteVex2);
+    4146           0 :       EMIT_BYTE(x);
+    4147           0 :       EMIT_BYTE(opCode);
+    4148             : 
+    4149           0 :       rbReg &= 0x7;
+    4150           0 :       EMIT_BYTE(x86EncodeMod(3, opReg, rbReg));
+    4151             : 
+    4152           0 :       if (imLen == 0) goto EmitDone;
+    4153           0 :       EMIT_BYTE(imVal & 0xFF);
+    4154           0 :       goto EmitDone;
+    4155             :     }
+    4156             :   }
+    4157             : 
+    4158           0 : EmitVexEvexM:
+    4159             :   ASMJIT_ASSERT(rmRel != nullptr);
+    4160             :   ASMJIT_ASSERT(rmRel->getOp() == Operand::kOpMem);
+    4161           0 :   rmInfo = x86MemInfo[rmRel->as<X86Mem>().getBaseIndexType()];
+    4162             : 
+    4163             :   // Segment-override prefix.
+    4164           0 :   if (rmRel->as<X86Mem>().hasSegment())
+    4165           0 :     EMIT_BYTE(x86SegmentPrefix[rmRel->as<X86Mem>().getSegmentId()]);
+    4166             : 
+    4167             :   // Address-override prefix.
+    4168           0 :   if (rmInfo & _getAddressOverrideMask())
+    4169           0 :     EMIT_BYTE(0x67);
+    4170             : 
+    4171           0 :   rbReg = rmRel->as<X86Mem>().hasBaseReg()  ? rmRel->as<X86Mem>().getBaseId()  : uint32_t(0);
+    4172           0 :   rxReg = rmRel->as<X86Mem>().hasIndexReg() ? rmRel->as<X86Mem>().getIndexId() : uint32_t(0);
+    4173             : 
+    4174             :   {
+    4175             :     // VEX instructions use only 0-1 BYTE immediate.
+    4176             :     ASMJIT_ASSERT(imLen <= 1);
+    4177             : 
+    4178             :     // Construct `x` - a complete EVEX|VEX prefix.
+    4179           0 :     uint32_t x = ((opReg << 4 ) & 0x0000F980U) |         // [........|........|Vvvvv..R|R.......].
+    4180           0 :                  ((rxReg << 3 ) & 0x00000040U) |         // [........|........|........|.X......].
+    4181           0 :                  ((rxReg << 15) & 0x00080000U) |         // [........|....X...|........|........].
+    4182           0 :                  ((rbReg << 2 ) & 0x00000020U) |         // [........|........|........|..B.....].
+    4183             :                  (x86ExtractLLMM(opCode, options)) |     // [........|.LL.X...|Vvvvv..R|RXBmmmmm].
+    4184           0 :                  (_extraReg.getId() << 16)         ;     // [........|.LL.Xaaa|Vvvvv..R|RXBmmmmm].
+    4185           0 :     opReg &= 0x07U;
+    4186             : 
+    4187             :     // Mark invalid VEX (force EVEX) case:               // [@.......|.LL.Xaaa|Vvvvv..R|RXBmmmmm].
+    4188           0 :     x |= (~commonData->getFlags() & X86Inst::kFlagVex) << (31 - Utils::firstBitOfT<X86Inst::kFlagVex>());
+    4189             : 
+    4190             :     // Handle AVX512 options by a single branch.
+    4191             :     const uint32_t kAvx512Options = X86Inst::kOption1ToX    |
+    4192             :                                     X86Inst::kOptionZMask   |
+    4193             :                                     X86Inst::kOptionSAE     |
+    4194             :                                     X86Inst::kOptionER      ;
+    4195           0 :     if (options & kAvx512Options) {
+    4196             :       // {er} and {sae} are both invalid if memory operand is used.
+    4197           0 :       if (ASMJIT_UNLIKELY(options & (X86Inst::kOptionSAE | X86Inst::kOptionER)))
+    4198           0 :         goto InvalidEROrSAE;
+    4199             : 
+    4200           0 :       x |= options & (X86Inst::kOption1ToX |             // [@.......|.LLbXaaa|Vvvvv..R|RXBmmmmm].
+    4201             :                       X86Inst::kOptionZMask);            // [@.......|zLLbXaaa|Vvvvv..R|RXBmmmmm].
+    4202             :     }
+    4203             : 
+    4204             :     // Check if EVEX is required by checking bits in `x` :  [@.......|xx.xxxxx|x......x|...x....].
+    4205           0 :     if (x & 0x80DF8110U) {
+    4206           0 :       uint32_t y = ((x << 4) & 0x00080000U) |            // [@.......|....V...|........|........].
+    4207           0 :                    ((x >> 4) & 0x00000010U) ;            // [@.......|....V...|........|...R....].
+    4208           0 :       x  = (x & 0x00FF78E3U) | y;                        // [........|zLLbVaaa|0vvvv000|RXBR00mm].
+    4209           0 :       x  = (x << 8) |                                    // [zLLbVaaa|0vvvv000|RBBR00mm|00000000].
+    4210           0 :            ((opCode >> kSHR_W_PP) & 0x00830000U) |       // [zLLbVaaa|Wvvvv0pp|RBBR00mm|00000000].
+    4211           0 :            ((opCode >> kSHR_W_EW) & 0x00800000U) ;       // [zLLbVaaa|Wvvvv0pp|RBBR00mm|00000000] (added EVEX.W).
+    4212             :                                                          //      _     ____    ____
+    4213           0 :       x ^= 0x087CF000U | kX86ByteEvex;                   // [zLLbVaaa|Wvvvv1pp|RBBR00mm|01100010].
+    4214             : 
+    4215             :       EMIT_32(x);
+    4216           0 :       EMIT_BYTE(opCode);
+    4217             : 
+    4218           0 :       if (opCode & 0x10000000U) {
+    4219             :         // Broadcast, change the compressed displacement scale to either x4 (SHL 2) or x8 (SHL 3)
+    4220             :         // depending on instruction's W. If 'W' is 1 'SHL' must be 3, otherwise it must be 2.
+    4221           0 :         opCode &=~static_cast<uint32_t>(X86Inst::kOpCode_CDSHL_Mask);
+    4222           0 :         opCode |= ((x & 0x00800000U) ? 3 : 2) << X86Inst::kOpCode_CDSHL_Shift;
+    4223             :       }
+    4224             :       else {
+    4225             :         // Add the compressed displacement 'SHF' to the opcode based on 'TTWLL'.
+    4226           0 :         uint32_t TTWLL = ((opCode >> (X86Inst::kOpCode_CDTT_Shift - 3)) & 0x18) +
+    4227           0 :                          ((opCode >> (X86Inst::kOpCode_W_Shift    - 2)) & 0x04) +
+    4228           0 :                          ((x >> 29) & 0x3);
+    4229           0 :         opCode += x86CDisp8SHL[TTWLL];
+    4230             :       }
+    4231             :     }
+    4232             :     else {
+    4233             :       // Not EVEX, prepare `x` for VEX2 or VEX3:        x = [........|00L00000|0vvvv000|RXB0mmmm].
+    4234           0 :       x |= ((opCode >> (kSHR_W_PP + 8)) & 0x8300U) |     // [00000000|00L00000|Wvvvv0pp|RXB0mmmm].
+    4235           0 :            ((x      >> 11             ) & 0x0400U) ;     // [00000000|00L00000|WvvvvLpp|RXB0mmmm].
+    4236             : 
+    4237             :       // Clear a possible CDisp specified by EVEX.
+    4238           0 :       opCode &= ~X86Inst::kOpCode_CDSHL_Mask;
+    4239             : 
+    4240             :       // Check if VEX3 is required / forced:                [........|........|x.......|.xx..x..].
+    4241           0 :       if (x & 0x0008064U) {
+    4242           0 :         uint32_t xorMsk = x86VEXPrefix[x & 0xF] | (opCode << 24);
+    4243             : 
+    4244             :         // Clear 'FORCE-VEX3' bit and all high bits.
+    4245           0 :         x  = (x & (0x4 ^ 0xFFFF)) << 8;                  // [00000000|WvvvvLpp|RXB0m0mm|00000000].
+    4246             :                                                          //            ____    ___
+    4247           0 :         x ^= xorMsk;                                     // [_OPCODE_|WvvvvLpp|RXBmmmmm|VEX3_XOP].
+    4248           0 :         EMIT_32(x);
+    4249             :       }
+    4250             :       else {
+    4251             :         // 'mmmmm' must be '00001'.
+    4252             :         ASMJIT_ASSERT((x & 0x1F) == 0x01);
+    4253             : 
+    4254           0 :         x = ((x >> 8) ^ x) ^ 0xF9;
+    4255           0 :         EMIT_BYTE(kX86ByteVex2);
+    4256           0 :         EMIT_BYTE(x);
+    4257           0 :         EMIT_BYTE(opCode);
+    4258             :       }
+    4259             :     }
+    4260             :   }
+    4261             : 
+    4262             :   // MOD|SIB address.
+    4263           0 :   if (!commonData->hasFlag(X86Inst::kFlagVsib))
+    4264           0 :     goto EmitModSib;
+    4265             : 
+    4266             :   // MOD|VSIB address without INDEX is invalid.
+    4267           0 :   if (rmInfo & kX86MemInfo_Index)
+    4268           0 :     goto EmitModVSib;
+    4269           0 :   goto InvalidInstruction;
+    4270             : 
+    4271             :   // --------------------------------------------------------------------------
+    4272             :   // [Emit - Jmp/Jcc/Call]
+    4273             :   // --------------------------------------------------------------------------
+    4274             : 
+    4275             :   // TODO: Should be adjusted after the support for multiple sections feature is added.
+    4276           0 : EmitJmpCall:
+    4277             :   {
+    4278             :     // Emit REX prefix if asked for (64-bit only).
+    4279             :     uint32_t rex = x86ExtractREX(opCode, options);
+    4280           0 :     if (rex) {
+    4281           0 :       if (options & X86Inst::_kOptionInvalidRex)
+    4282           0 :         goto InvalidRexPrefix;
+    4283           0 :       EMIT_BYTE(rex | kX86ByteRex);
+    4284             :     }
+    4285             : 
+    4286           0 :     uint64_t ip = static_cast<uint64_t>((intptr_t)(cursor - _bufferData));
+    4287             :     uint32_t rel32 = 0;
+    4288             :     uint32_t opCode8 = commonData->getAltOpCode();
+    4289             : 
+    4290             :     uint32_t inst8Size  = 1 + 1; //          OPCODE + REL8 .
+    4291             :     uint32_t inst32Size = 1 + 4; // [PREFIX] OPCODE + REL32.
+    4292             : 
+    4293             :     // Jcc instructions with 32-bit displacement use 0x0F prefix,
+    4294             :     // other instructions don't. No other prefixes are used by X86.
+    4295             :     ASMJIT_ASSERT((opCode8 & X86Inst::kOpCode_MM_Mask) == 0);
+    4296             :     ASMJIT_ASSERT((opCode  & X86Inst::kOpCode_MM_Mask) == 0 ||
+    4297             :                   (opCode  & X86Inst::kOpCode_MM_Mask) == X86Inst::kOpCode_MM_0F);
+    4298             : 
+    4299             :     // Only one of these should be used at the same time.
+    4300           0 :     inst32Size += static_cast<uint32_t>(opReg != 0);
+    4301           0 :     inst32Size += static_cast<uint32_t>((opCode & X86Inst::kOpCode_MM_Mask) == X86Inst::kOpCode_MM_0F);
+    4302             : 
+    4303           0 :     if (rmRel->isLabel()) {
+    4304           0 :       label = _code->getLabelEntry(rmRel->as<Label>());
+    4305           0 :       if (!label) goto InvalidLabel;
+    4306             : 
+    4307           0 :       if (label->isBound()) {
+    4308             :         // Bound label.
+    4309           0 :         rel32 = static_cast<uint32_t>((static_cast<uint64_t>(label->getOffset()) - ip - inst32Size) & 0xFFFFFFFFU);
+    4310           0 :         goto EmitJmpCallRel;
+    4311             :       }
+    4312             :       else {
+    4313             :         // Non-bound label.
+    4314           0 :         if (opCode8 && (!opCode || (options & X86Inst::kOptionShortForm))) {
+    4315           0 :           EMIT_BYTE(opCode8);
+    4316             :           relOffset = -1;
+    4317             :           relSize = 1;
+    4318           0 :           goto EmitRel;
+    4319             :         }
+    4320             :         else {
+    4321             :           // Refuse also 'short' prefix, if specified.
+    4322           0 :           if (ASMJIT_UNLIKELY(!opCode || (options & X86Inst::kOptionShortForm) != 0))
+    4323           0 :             goto InvalidDisplacement;
+    4324             : 
+    4325             :           // Emit [PREFIX] OPCODE [/X] <DISP32>.
+    4326           0 :           if (opCode & X86Inst::kOpCode_MM_Mask)
+    4327           0 :             EMIT_BYTE(0x0F);
+    4328             : 
+    4329           0 :           EMIT_BYTE(opCode);
+    4330           0 :           if (opReg)
+    4331           0 :             EMIT_BYTE(x86EncodeMod(3, opReg, 0));
+    4332             : 
+    4333             :           relOffset = -4;
+    4334             :           relSize = 4;
+    4335           0 :           goto EmitRel;
+    4336             :         }
+    4337             :       }
+    4338             :     }
+    4339             : 
+    4340           0 :     if (rmRel->isImm()) {
+    4341             :       uint64_t baseAddress = getCodeInfo().getBaseAddress();
+    4342             :       uint64_t jumpAddress = rmRel->as<Imm>().getUInt64();
+    4343             : 
+    4344             :       // If the base-address is known calculate a relative displacement and
+    4345             :       // check if it fits in 32 bits (which is always true in 32-bit mode).
+    4346             :       // Emit relative displacement as it was a bound label if all checks ok.
+    4347           0 :       if (baseAddress != Globals::kNoBaseAddress) {
+    4348           0 :         uint64_t rel64 = jumpAddress - (ip + baseAddress) - inst32Size;
+    4349           0 :         if (getArchType() == ArchInfo::kTypeX86 || Utils::isInt32(static_cast<int64_t>(rel64))) {
+    4350           0 :           rel32 = static_cast<uint32_t>(rel64 & 0xFFFFFFFFU);
+    4351           0 :           goto EmitJmpCallRel;
+    4352             :         }
+    4353             :         else {
+    4354             :           // Relative displacement exceeds 32-bits - relocator can only
+    4355             :           // insert trampoline for jmp/call, but not for jcc/jecxz.
+    4356           0 :           if (ASMJIT_UNLIKELY(!x86IsJmpOrCall(instId)))
+    4357           0 :             goto InvalidDisplacement;
+    4358             :         }
+    4359             :       }
+    4360             : 
+    4361           0 :       if (ASMJIT_UNLIKELY(_code->_relocations.willGrow(&_code->_baseHeap) != kErrorOk))
+    4362           0 :         goto NoHeapMemory;
+    4363             : 
+    4364           0 :       err = _code->newRelocEntry(&re, RelocEntry::kTypeAbsToRel, 0);
+    4365           0 :       if (ASMJIT_UNLIKELY(err)) goto Failed;
+    4366             : 
+    4367           0 :       re->_sourceSectionId = _section->getId();
+    4368           0 :       re->_data = static_cast<int64_t>(jumpAddress);
+    4369             : 
+    4370           0 :       if (ASMJIT_LIKELY(opCode)) {
+    4371             :         // 64-bit: Emit REX prefix so the instruction can be patched later.
+    4372             :         // REX prefix does nothing if not patched, but allows to patch the
+    4373             :         // instruction to use MOD/M and to point to a memory where the final
+    4374             :         // 64-bit address is stored.
+    4375           0 :         re->_size = 4;
+    4376           0 :         re->_sourceOffset = ip + inst32Size - 4;
+    4377             : 
+    4378           0 :         if (getArchType() != ArchInfo::kTypeX86 && x86IsJmpOrCall(instId)) {
+    4379           0 :           if (!rex) {
+    4380           0 :             re->_sourceOffset++;
+    4381           0 :             EMIT_BYTE(kX86ByteRex);
+    4382             :           }
+    4383             : 
+    4384           0 :           re->_type = RelocEntry::kTypeTrampoline;
+    4385           0 :           _code->_trampolinesSize += 8;
+    4386             :         }
+    4387             : 
+    4388             :         // Emit [PREFIX] OPCODE [/X] DISP32.
+    4389           0 :         if (opCode & X86Inst::kOpCode_MM_Mask)
+    4390           0 :           EMIT_BYTE(0x0F);
+    4391             : 
+    4392           0 :         EMIT_BYTE(opCode);
+    4393           0 :         if (opReg)
+    4394           0 :           EMIT_BYTE(x86EncodeMod(3, opReg, 0));
+    4395             : 
+    4396           0 :         EMIT_32(0);
+    4397             :       }
+    4398             :       else {
+    4399           0 :         re->_size = 1;
+    4400           0 :         re->_sourceOffset = ip + inst8Size - 1;
+    4401             : 
+    4402             :         // Emit OPCODE + DISP8.
+    4403           0 :         EMIT_BYTE(opCode8);
+    4404           0 :         EMIT_BYTE(0);
+    4405             :       }
+    4406           0 :       goto EmitDone;
+    4407             :     }
+    4408             : 
+    4409             :     // Not Label|Imm -> Invalid.
+    4410           0 :     goto InvalidInstruction;
+    4411             : 
+    4412             :     // Emit jmp/call with relative displacement known at assembly-time. Decide
+    4413             :     // between 8-bit and 32-bit displacement encoding. Some instructions only
+    4414             :     // allow either 8-bit or 32-bit encoding, others allow both encodings.
+    4415           0 : EmitJmpCallRel:
+    4416           0 :     if (Utils::isInt8(static_cast<int32_t>(rel32 + inst32Size - inst8Size)) && opCode8 && !(options & X86Inst::kOptionLongForm)) {
+    4417           0 :       options |= X86Inst::kOptionShortForm;
+    4418           0 :       EMIT_BYTE(opCode8);
+    4419           0 :       EMIT_BYTE(rel32 + inst32Size - inst8Size);
+    4420           0 :       goto EmitDone;
+    4421             :     }
+    4422             :     else {
+    4423           0 :       if (ASMJIT_UNLIKELY(!opCode || (options & X86Inst::kOptionShortForm) != 0))
+    4424           0 :         goto InvalidDisplacement;
+    4425             : 
+    4426           0 :       options &= ~X86Inst::kOptionShortForm;
+    4427           0 :       if (opCode & X86Inst::kOpCode_MM_Mask)
+    4428           0 :         EMIT_BYTE(0x0F);
+    4429             : 
+    4430           0 :       EMIT_BYTE(opCode);
+    4431           0 :       if (opReg)
+    4432           0 :         EMIT_BYTE(x86EncodeMod(3, opReg, 0));
+    4433             : 
+    4434           0 :       EMIT_32(rel32);
+    4435           0 :       goto EmitDone;
+    4436             :     }
+    4437             :   }
+    4438             : 
+    4439             :   // --------------------------------------------------------------------------
+    4440             :   // [Emit - Relative]
+    4441             :   // --------------------------------------------------------------------------
+    4442             : 
+    4443           0 : EmitRel:
+    4444             :   {
+    4445             :     ASMJIT_ASSERT(!label->isBound());
+    4446             :     ASMJIT_ASSERT(relSize == 1 || relSize == 4);
+    4447             : 
+    4448             :     // Chain with label.
+    4449           0 :     size_t offset = (size_t)(cursor - _bufferData);
+    4450           0 :     LabelLink* link = _code->newLabelLink(label, _section->getId(), offset, relOffset);
+    4451             : 
+    4452           0 :     if (ASMJIT_UNLIKELY(!link))
+    4453           0 :       goto NoHeapMemory;
+    4454             : 
+    4455           0 :     if (re)
+    4456           0 :       link->relocId = re->getId();
+    4457             : 
+    4458             :     // Emit label size as dummy data.
+    4459           0 :     if (relSize == 1)
+    4460           0 :       EMIT_BYTE(0x01);
+    4461             :     else // if (relSize == 4)
+    4462           0 :       EMIT_32(0x04040404);
+    4463             :   }
+    4464             : 
+    4465           0 :   if (imLen == 0)
+    4466           0 :     goto EmitDone;
+    4467             : 
+    4468             :   // --------------------------------------------------------------------------
+    4469             :   // [Emit - Immediate]
+    4470             :   // --------------------------------------------------------------------------
+    4471             : 
+    4472           0 : EmitImm:
+    4473             :   {
+    4474             : #if ASMJIT_ARCH_64BIT
+    4475        9672 :     uint32_t i = imLen;
+    4476        9672 :     uint64_t imm = static_cast<uint64_t>(imVal);
+    4477             : #else
+    4478             :     uint32_t i = imLen;
+    4479             :     uint32_t imm = static_cast<uint32_t>(imVal & 0xFFFFFFFFU);
+    4480             : #endif
+    4481             : 
+    4482             :     // Many instructions just use a single byte immediate, so make it fast.
+    4483        9672 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4484        7688 :     imm >>= 8;
+    4485        7688 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4486        7688 :     imm >>= 8;
+    4487        7688 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4488        7688 :     imm >>= 8;
+    4489        7688 :     EMIT_BYTE(imm & 0xFFU); if (--i == 0) goto EmitDone;
+    4490             : 
+    4491             :     // Can be 1-4 or 8 bytes, this handles the remaining high DWORD of an 8-byte immediate.
+    4492             :     ASMJIT_ASSERT(i == 4);
+    4493             : 
+    4494             : #if ASMJIT_ARCH_64BIT
+    4495        7688 :     imm >>= 8;
+    4496        7688 :     EMIT_32(static_cast<uint32_t>(imm));
+    4497             : #else
+    4498             :     EMIT_32(static_cast<uint32_t>((static_cast<uint64_t>(imVal) >> 32) & 0xFFFFFFFFU));
+    4499             : #endif
+    4500             :   }
+    4501             : 
+    4502             :   // --------------------------------------------------------------------------
+    4503             :   // [Done]
+    4504             :   // --------------------------------------------------------------------------
+    4505             : 
+    4506       48362 : EmitDone:
+    4507             : #if !defined(ASMJIT_DISABLE_LOGGING)
+    4508             :   // Logging is a performance hit anyway, so make it the unlikely case.
+    4509       48362 :   if (ASMJIT_UNLIKELY(options & CodeEmitter::kOptionLoggingEnabled))
+    4510           0 :     _emitLog(instId, options, o0, o1, o2, o3, relSize, imLen, cursor);
+    4511             : #endif // !ASMJIT_DISABLE_LOGGING
+    4512             : 
+    4513             :   resetOptions();
+    4514             :   resetExtraReg();
+    4515             :   resetInlineComment();
+    4516             : 
+    4517       48362 :   _bufferPtr = cursor;
+    4518       48362 :   return kErrorOk;
+    4519             : 
+    4520             :   // --------------------------------------------------------------------------
+    4521             :   // [Error Cases]
+    4522             :   // --------------------------------------------------------------------------
+    4523             : 
+    4524             : #define ERROR_HANDLER(ERROR)                \
+    4525             : ERROR:                                      \
+    4526             :   err = DebugUtils::errored(kError##ERROR); \
+    4527             :   goto Failed;
+    4528             : 
+    4529           0 : ERROR_HANDLER(NoHeapMemory)
+    4530           0 : ERROR_HANDLER(InvalidArgument)
+    4531           0 : ERROR_HANDLER(InvalidLabel)
+    4532           0 : ERROR_HANDLER(InvalidInstruction)
+    4533           0 : ERROR_HANDLER(InvalidLockPrefix)
+    4534           0 : ERROR_HANDLER(InvalidXAcquirePrefix)
+    4535           0 : ERROR_HANDLER(InvalidXReleasePrefix)
+    4536           0 : ERROR_HANDLER(InvalidRepPrefix)
+    4537           0 : ERROR_HANDLER(InvalidRexPrefix)
+    4538           0 : ERROR_HANDLER(InvalidBroadcast)
+    4539           0 : ERROR_HANDLER(InvalidEROrSAE)
+    4540           0 : ERROR_HANDLER(InvalidAddress)
+    4541           0 : ERROR_HANDLER(InvalidAddressIndex)
+    4542           0 : ERROR_HANDLER(InvalidAddress64Bit)
+    4543           0 : ERROR_HANDLER(InvalidDisplacement)
+    4544           0 : ERROR_HANDLER(InvalidSegment)
+    4545           0 : ERROR_HANDLER(InvalidImmediate)
+    4546           0 : ERROR_HANDLER(OperandSizeMismatch)
+    4547           0 : ERROR_HANDLER(AmbiguousOperandSize)
+    4548           0 : ERROR_HANDLER(NotConsecutiveRegs)
+    4549             : 
+    4550           0 : Failed:
+    4551           0 :   return _emitFailed(err, instId, options, o0, o1, o2, o3);
+    4552             : }
+    4553             : 
+    4554             : // ============================================================================
+    4555             : // [asmjit::X86Assembler - Align]
+    4556             : // ============================================================================
+    4557             : 
+    4558           0 : Error X86Assembler::align(uint32_t mode, uint32_t alignment) {
+    4559             : #if !defined(ASMJIT_DISABLE_LOGGING)
+    4560           0 :   if (_globalOptions & kOptionLoggingEnabled)
+    4561           0 :     _code->_logger->logf("%s.align %u\n", _code->_logger->getIndentation(), alignment);
+    4562             : #endif // !ASMJIT_DISABLE_LOGGING
+    4563             : 
+    4564           0 :   if (mode >= kAlignCount)
+    4565           0 :     return setLastError(DebugUtils::errored(kErrorInvalidArgument));
+    4566             : 
+    4567           0 :   if (alignment <= 1)
+    4568             :     return kErrorOk;
+    4569             : 
+    4570           0 :   if (!Utils::isPowerOf2(alignment) || alignment > Globals::kMaxAlignment)
+    4571           0 :     return setLastError(DebugUtils::errored(kErrorInvalidArgument));
+    4572             : 
+    4573           0 :   uint32_t i = static_cast<uint32_t>(Utils::alignDiff<size_t>(getOffset(), alignment));
+    4574           0 :   if (i == 0)
+    4575             :     return kErrorOk;
+    4576             : 
+    4577           0 :   if (getRemainingSpace() < i) {
+    4578           0 :     Error err = _code->growBuffer(&_section->_buffer, i);
+    4579           0 :     if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+    4580             :   }
+    4581             : 
+    4582           0 :   uint8_t* cursor = _bufferPtr;
+    4583             :   uint8_t pattern = 0x00;
+    4584             : 
+    4585           0 :   switch (mode) {
+    4586           0 :     case kAlignCode: {
+    4587           0 :       if (_globalHints & kHintOptimizedAlign) {
+    4588             :         // Intel 64 and IA-32 Architectures Software Developer's Manual - Volume 2B (NOP).
+    4589             :         enum { kMaxNopSize = 9 };
+    4590             : 
+    4591             :         static const uint8_t nopData[kMaxNopSize][kMaxNopSize] = {
+    4592             :           { 0x90 },
+    4593             :           { 0x66, 0x90 },
+    4594             :           { 0x0F, 0x1F, 0x00 },
+    4595             :           { 0x0F, 0x1F, 0x40, 0x00 },
+    4596             :           { 0x0F, 0x1F, 0x44, 0x00, 0x00 },
+    4597             :           { 0x66, 0x0F, 0x1F, 0x44, 0x00, 0x00 },
+    4598             :           { 0x0F, 0x1F, 0x80, 0x00, 0x00, 0x00, 0x00 },
+    4599             :           { 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 },
+    4600             :           { 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 }
+    4601             :         };
+    4602             : 
+    4603             :         do {
+    4604           0 :           uint32_t n = std::min<uint32_t>(i, kMaxNopSize);
+    4605           0 :           const uint8_t* src = nopData[n - 1];
+    4606             : 
+    4607           0 :           i -= n;
+    4608             :           do {
+    4609           0 :             EMIT_BYTE(*src++);
+    4610           0 :           } while (--n);
+    4611           0 :         } while (i);
+    4612             :       }
+    4613             : 
+    4614             :       pattern = 0x90;
+    4615             :       break;
+    4616             :     }
+    4617             : 
+    4618           0 :     case kAlignData:
+    4619             :       pattern = 0xCC;
+    4620           0 :       break;
+    4621             : 
+    4622             :     case kAlignZero:
+    4623             :       // Pattern already set to zero.
+    4624             :       break;
+    4625             :   }
+    4626             : 
+    4627           0 :   while (i) {
+    4628           0 :     EMIT_BYTE(pattern);
+    4629           0 :     i--;
+    4630             :   }
+    4631             : 
+    4632           0 :   _bufferPtr = cursor;
+    4633           0 :   return kErrorOk;
+    4634             : }
+    4635             : 
+    4636             : } // asmjit namespace
+    4637             : } // namespace PLMD
+    4638             : 
+    4639             : // [Api-End]
+    4640             : #include "./asmjit_apiend.h"
+    4641             : 
+    4642             : // [Guard]
+    4643             : #endif // ASMJIT_BUILD_X86
+    4644             : #pragma GCC diagnostic pop
+    4645             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.h.func-sort-c.html b/coverage-libs/asmjit/x86assembler.h.func-sort-c.html new file mode 100644 index 000000000000..2b786e628e5f --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.h.func.html b/coverage-libs/asmjit/x86assembler.h.func.html new file mode 100644 index 000000000000..e844e2f8888a --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86assembler.h.gcov.html b/coverage-libs/asmjit/x86assembler.h.gcov.html new file mode 100644 index 000000000000..d4ad82d6b098 --- /dev/null +++ b/coverage-libs/asmjit/x86assembler.h.gcov.html @@ -0,0 +1,202 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86assembler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86assembler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_x86assembler_h
+      21             : #define __PLUMED_asmjit_x86assembler_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_X86_X86ASSEMBLER_H
+      33             : #define _ASMJIT_X86_X86ASSEMBLER_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./assembler.h"
+      37             : #include "./utils.h"
+      38             : #include "./x86emitter.h"
+      39             : #include "./x86operand.h"
+      40             : 
+      41             : // [Api-Begin]
+      42             : #include "./asmjit_apibegin.h"
+      43             : 
+      44             : namespace PLMD {
+      45             : namespace asmjit {
+      46             : 
+      47             : //! \addtogroup asmjit_x86
+      48             : //! \{
+      49             : 
+      50             : // ============================================================================
+      51             : // [asmjit::X86Assembler]
+      52             : // ============================================================================
+      53             : 
+      54             : //! X86/X64 assembler.
+      55             : //!
+      56             : //! X86/X64 assembler emits machine-code into buffers managed by \ref CodeHolder.
+      57             : class ASMJIT_VIRTAPI X86Assembler
+      58             :   : public Assembler,
+      59             :     public X86EmitterImplicitT<X86Assembler> {
+      60             : 
+      61             : public:
+      62             :   typedef Assembler Base;
+      63             : 
+      64             :   // --------------------------------------------------------------------------
+      65             :   // [Construction / Destruction]
+      66             :   // --------------------------------------------------------------------------
+      67             : 
+      68             :   ASMJIT_API X86Assembler(CodeHolder* code = nullptr) noexcept;
+      69             :   ASMJIT_API virtual ~X86Assembler() noexcept;
+      70             : 
+      71             :   // --------------------------------------------------------------------------
+      72             :   // [Compatibility]
+      73             :   // --------------------------------------------------------------------------
+      74             : 
+      75             :   //! Explicit cast to `X86Emitter`.
+      76             :   ASMJIT_INLINE X86Emitter* asEmitter() noexcept { return reinterpret_cast<X86Emitter*>(this); }
+      77             :   //! Explicit cast to `X86Emitter` (const).
+      78             :   ASMJIT_INLINE const X86Emitter* asEmitter() const noexcept { return reinterpret_cast<const X86Emitter*>(this); }
+      79             : 
+      80             :   //! Implicit cast to `X86Emitter`.
+      81             :   ASMJIT_INLINE operator X86Emitter&() noexcept { return *asEmitter(); }
+      82             :   //! Implicit cast to `X86Emitter` (const).
+      83             :   ASMJIT_INLINE operator const X86Emitter&() const noexcept { return *asEmitter(); }
+      84             : 
+      85             :   // --------------------------------------------------------------------------
+      86             :   // [Accessors]
+      87             :   // --------------------------------------------------------------------------
+      88             : 
+      89             :   // NOTE: X86Assembler uses _privateData to store 'address-override' bit that
+      90             :   // is used to decide whether to emit address-override (67H) prefix based on
+      91             :   // the memory BASE+INDEX registers. It's either `kX86MemInfo_67H_X86` or
+      92             :   // `kX86MemInfo_67H_X64`.
+      93       14528 :   ASMJIT_INLINE uint32_t _getAddressOverrideMask() const noexcept { return _privateData; }
+      94        1948 :   ASMJIT_INLINE void _setAddressOverrideMask(uint32_t m) noexcept { _privateData = m; }
+      95             : 
+      96             :   // --------------------------------------------------------------------------
+      97             :   // [Events]
+      98             :   // --------------------------------------------------------------------------
+      99             : 
+     100             :   ASMJIT_API Error onAttach(CodeHolder* code) noexcept override;
+     101             :   ASMJIT_API Error onDetach(CodeHolder* code) noexcept override;
+     102             : 
+     103             :   // --------------------------------------------------------------------------
+     104             :   // [Code-Generation]
+     105             :   // --------------------------------------------------------------------------
+     106             : 
+     107             :   using CodeEmitter::_emit;
+     108             : 
+     109             :   ASMJIT_API Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) override;
+     110             :   ASMJIT_API Error align(uint32_t mode, uint32_t alignment) override;
+     111             : };
+     112             : 
+     113             : //! \}
+     114             : 
+     115             : } // asmjit namespace
+     116             : } // namespace PLMD
+     117             : 
+     118             : // [Api-End]
+     119             : #include "./asmjit_apiend.h"
+     120             : 
+     121             : // [Guard]
+     122             : #endif // _ASMJIT_X86_X86ASSEMBLER_H
+     123             : #pragma GCC diagnostic pop
+     124             : #endif // __PLUMED_HAS_ASMJIT
+     125             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86builder.cpp.func-sort-c.html b/coverage-libs/asmjit/x86builder.cpp.func-sort-c.html new file mode 100644 index 000000000000..18a460d5ff76 --- /dev/null +++ b/coverage-libs/asmjit/x86builder.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86builder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86builder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0150.0 %
Date:2024-02-22 21:58:47Functions:050.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10X86Builder5_emitEjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit10X86Builder8onAttachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit10X86BuilderC2EPNS0_10CodeHolderE0
_ZN4PLMD6asmjit10X86BuilderD0Ev0
_ZN4PLMD6asmjit10X86BuilderD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86builder.cpp.func.html b/coverage-libs/asmjit/x86builder.cpp.func.html new file mode 100644 index 000000000000..4b6ee3c2adde --- /dev/null +++ b/coverage-libs/asmjit/x86builder.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86builder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86builder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0150.0 %
Date:2024-02-22 21:58:47Functions:050.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10X86Builder5_emitEjRKNS0_8Operand_ES4_S4_S4_0
_ZN4PLMD6asmjit10X86Builder8onAttachEPNS0_10CodeHolderE0
_ZN4PLMD6asmjit10X86BuilderC2EPNS0_10CodeHolderE0
_ZN4PLMD6asmjit10X86BuilderD0Ev0
_ZN4PLMD6asmjit10X86BuilderD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86builder.cpp.gcov.html b/coverage-libs/asmjit/x86builder.cpp.gcov.html new file mode 100644 index 000000000000..a6cfea30bc4d --- /dev/null +++ b/coverage-libs/asmjit/x86builder.cpp.gcov.html @@ -0,0 +1,169 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86builder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86builder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0150.0 %
Date:2024-02-22 21:58:47Functions:050.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Guard]
+      33             : #include "./asmjit_build.h"
+      34             : #if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_DISABLE_COMPILER)
+      35             : 
+      36             : // [Dependencies]
+      37             : #include "./x86builder.h"
+      38             : 
+      39             : // [Api-Begin]
+      40             : #include "./asmjit_apibegin.h"
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace asmjit {
+      44             : 
+      45             : // ============================================================================
+      46             : // [asmjit::X86Builder - Construction / Destruction]
+      47             : // ============================================================================
+      48             : 
+      49           0 : X86Builder::X86Builder(CodeHolder* code) noexcept : CodeBuilder() {
+      50           0 :   if (code)
+      51           0 :     code->attach(this);
+      52           0 : }
+      53           0 : X86Builder::~X86Builder() noexcept {}
+      54             : 
+      55             : // ============================================================================
+      56             : // [asmjit::X86Builder - Events]
+      57             : // ============================================================================
+      58             : 
+      59           0 : Error X86Builder::onAttach(CodeHolder* code) noexcept {
+      60             :   uint32_t archType = code->getArchType();
+      61           0 :   if (!ArchInfo::isX86Family(archType))
+      62             :     return DebugUtils::errored(kErrorInvalidArch);
+      63             : 
+      64           0 :   ASMJIT_PROPAGATE(Base::onAttach(code));
+      65             : 
+      66           0 :   if (archType == ArchInfo::kTypeX86)
+      67           0 :     _nativeGpArray = x86OpData.gpd;
+      68             :   else
+      69           0 :     _nativeGpArray = x86OpData.gpq;
+      70           0 :   _nativeGpReg = _nativeGpArray[0];
+      71           0 :   return kErrorOk;
+      72             : }
+      73             : 
+      74             : // ============================================================================
+      75             : // [asmjit::X86Builder - Inst]
+      76             : // ============================================================================
+      77             : 
+      78           0 : Error X86Builder::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+      79             :   // TODO:
+      80           0 :   return kErrorOk;
+      81             : }
+      82             : 
+      83             : } // asmjit namespace
+      84             : } // namespace PLMD
+      85             : 
+      86             : // [Api-End]
+      87             : #include "./asmjit_apiend.h"
+      88             : 
+      89             : // [Guard]
+      90             : #endif // ASMJIT_BUILD_X86 && !ASMJIT_DISABLE_COMPILER
+      91             : #pragma GCC diagnostic pop
+      92             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.cpp.func-sort-c.html b/coverage-libs/asmjit/x86compiler.cpp.func-sort-c.html new file mode 100644 index 000000000000..477bfed87bd4 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4815131.8 %
Date:2024-02-22 21:58:47Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11X86CompilerD0Ev0
_ZN4PLMD6asmjit11X86Compiler8finalizeEv1948
_ZN4PLMD6asmjit11X86Compiler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11X86CompilerC2EPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11X86CompilerD2Ev1948
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_46714
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.cpp.func.html b/coverage-libs/asmjit/x86compiler.cpp.func.html new file mode 100644 index 000000000000..1792bf4fcc9a --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4815131.8 %
Date:2024-02-22 21:58:47Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_46714
_ZN4PLMD6asmjit11X86Compiler5_emitEjRKNS0_8Operand_ES4_S4_S4_S4_S4_0
_ZN4PLMD6asmjit11X86Compiler8finalizeEv1948
_ZN4PLMD6asmjit11X86Compiler8onAttachEPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11X86CompilerC2EPNS0_10CodeHolderE1948
_ZN4PLMD6asmjit11X86CompilerD0Ev0
_ZN4PLMD6asmjit11X86CompilerD2Ev1948
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.cpp.gcov.html b/coverage-libs/asmjit/x86compiler.cpp.gcov.html new file mode 100644 index 000000000000..ca484b3f4e8e --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.cpp.gcov.html @@ -0,0 +1,479 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4815131.8 %
Date:2024-02-22 21:58:47Functions:5771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Guard]
+      33             : #include "./asmjit_build.h"
+      34             : #if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_DISABLE_COMPILER)
+      35             : 
+      36             : // [Dependencies]
+      37             : #include "./utils.h"
+      38             : #include "./x86compiler.h"
+      39             : #include "./x86regalloc_p.h"
+      40             : 
+      41             : // [Api-Begin]
+      42             : #include "./asmjit_apibegin.h"
+      43             : 
+      44             : namespace PLMD {
+      45             : namespace asmjit {
+      46             : 
+      47             : // ============================================================================
+      48             : // [asmjit::X86Compiler - Construction / Destruction]
+      49             : // ============================================================================
+      50             : 
+      51        1948 : X86Compiler::X86Compiler(CodeHolder* code) noexcept : CodeCompiler() {
+      52        1948 :   if (code)
+      53        1948 :     code->attach(this);
+      54        1948 : }
+      55        1948 : X86Compiler::~X86Compiler() noexcept {}
+      56             : 
+      57             : // ============================================================================
+      58             : // [asmjit::X86Compiler - Events]
+      59             : // ============================================================================
+      60             : 
+      61        1948 : Error X86Compiler::onAttach(CodeHolder* code) noexcept {
+      62             :   uint32_t archType = code->getArchType();
+      63        1948 :   if (!ArchInfo::isX86Family(archType))
+      64             :     return DebugUtils::errored(kErrorInvalidArch);
+      65             : 
+      66        3896 :   ASMJIT_PROPAGATE(_cbPasses.willGrow(&_cbHeap, 1));
+      67        1948 :   ASMJIT_PROPAGATE(Base::onAttach(code));
+      68             : 
+      69        1948 :   if (archType == ArchInfo::kTypeX86)
+      70           0 :     _nativeGpArray = x86OpData.gpd;
+      71             :   else
+      72        1948 :     _nativeGpArray = x86OpData.gpq;
+      73        1948 :   _nativeGpReg = _nativeGpArray[0];
+      74             : 
+      75        3896 :   return addPassT<X86RAPass>();
+      76             : }
+      77             : 
+      78             : // ============================================================================
+      79             : // [asmjit::X86Compiler - Finalize]
+      80             : // ============================================================================
+      81             : 
+      82        1948 : Error X86Compiler::finalize() {
+      83        1948 :   if (_lastError) return _lastError;
+      84             : 
+      85             :   // Flush the global constant pool.
+      86        1948 :   if (_globalConstPool) {
+      87           0 :     addNode(_globalConstPool);
+      88           0 :     _globalConstPool = nullptr;
+      89             :   }
+      90             : 
+      91             :   Error err = kErrorOk;
+      92             :   ZoneVector<CBPass*>& passes = _cbPasses;
+      93             : 
+      94        3896 :   for (size_t i = 0, len = passes.getLength(); i < len; i++) {
+      95        1948 :     CBPass* pass = passes[i];
+      96        1948 :     err = pass->process(&_cbPassZone);
+      97        1948 :     _cbPassZone.reset();
+      98        1948 :     if (err) break;
+      99             :   }
+     100             : 
+     101        1948 :   _cbPassZone.reset();
+     102        1948 :   if (ASMJIT_UNLIKELY(err)) return setLastError(err);
+     103             : 
+     104             :   // TODO: There must be possibility to attach more assemblers, this is not so nice.
+     105        1948 :   if (_code->_cgAsm) {
+     106           0 :     return serialize(_code->_cgAsm);
+     107             :   }
+     108             :   else {
+     109        1948 :     X86Assembler a(_code);
+     110        1948 :     return serialize(&a);
+     111        1948 :   }
+     112             : }
+     113             : 
+     114             : // ============================================================================
+     115             : // [asmjit::X86Compiler - Inst]
+     116             : // ============================================================================
+     117             : 
+     118             : static ASMJIT_INLINE bool isJumpInst(uint32_t instId) noexcept {
+     119       46714 :   return (instId >= X86Inst::kIdJa   && instId <= X86Inst::kIdJz    ) ||
+     120       46714 :          (instId >= X86Inst::kIdLoop && instId <= X86Inst::kIdLoopne) ;
+     121             : }
+     122             : 
+     123       46714 : Error X86Compiler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) {
+     124       46714 :   uint32_t options = getOptions() | getGlobalOptions();
+     125             :   const char* inlineComment = getInlineComment();
+     126             : 
+     127       46714 :   uint32_t opCount = static_cast<uint32_t>(!o0.isNone()) +
+     128       46714 :                      static_cast<uint32_t>(!o1.isNone()) +
+     129       46714 :                      static_cast<uint32_t>(!o2.isNone()) +
+     130       46714 :                      static_cast<uint32_t>(!o3.isNone()) ;
+     131             : 
+     132             :   // Handle failure and rare cases first.
+     133             :   const uint32_t kErrorsAndSpecialCases = kOptionMaybeFailureCase | // CodeEmitter is in error state.
+     134             :                                           kOptionStrictValidation ; // Strict validation.
+     135             : 
+     136       46714 :   if (ASMJIT_UNLIKELY(options & kErrorsAndSpecialCases)) {
+     137             :     // Don't do anything if we are in error state.
+     138           0 :     if (_lastError) return _lastError;
+     139             : 
+     140             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+     141             :     // Strict validation.
+     142           0 :     if (options & kOptionStrictValidation) {
+     143             :       Operand opArray[] = {
+     144             :         Operand(o0),
+     145             :         Operand(o1),
+     146             :         Operand(o2),
+     147             :         Operand(o3)
+     148             :       };
+     149             : 
+     150             :       Inst::Detail instDetail(instId, options, _extraReg);
+     151           0 :       Error err = Inst::validate(getArchType(), instDetail, opArray, opCount);
+     152             : 
+     153           0 :       if (err) {
+     154             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     155             :         StringBuilderTmp<256> sb;
+     156           0 :         sb.appendString(DebugUtils::errorAsString(err));
+     157             :         sb.appendString(": ");
+     158           0 :         Logging::formatInstruction(sb, 0, this, getArchType(), instDetail, opArray, opCount);
+     159           0 :         return setLastError(err, sb.getData());
+     160             : #else
+     161             :         return setLastError(err);
+     162             : #endif
+     163             :       }
+     164             : 
+     165             :       // Clear it as it must be enabled explicitly on assembler side.
+     166           0 :       options &= ~kOptionStrictValidation;
+     167             :     }
+     168             : #endif // ASMJIT_DISABLE_VALIDATION
+     169             :   }
+     170             : 
+     171             :   resetOptions();
+     172             :   resetInlineComment();
+     173             : 
+     174             :   // decide between `CBInst` and `CBJump`.
+     175       46714 :   if (isJumpInst(instId)) {
+     176           0 :     CBJump* node = _cbHeap.allocT<CBJump>(sizeof(CBJump) + opCount * sizeof(Operand));
+     177           0 :     Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CBJump));
+     178             : 
+     179           0 :     if (ASMJIT_UNLIKELY(!node))
+     180           0 :       return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     181             : 
+     182           0 :     if (opCount > 0) opArray[0].copyFrom(o0);
+     183           0 :     if (opCount > 1) opArray[1].copyFrom(o1);
+     184           0 :     if (opCount > 2) opArray[2].copyFrom(o2);
+     185           0 :     if (opCount > 3) opArray[3].copyFrom(o3);
+     186             : 
+     187             :     new(node) CBJump(this, instId, options, opArray, opCount);
+     188           0 :     node->_instDetail.extraReg = _extraReg;
+     189             :     _extraReg.reset();
+     190             : 
+     191           0 :     CBLabel* jTarget = nullptr;
+     192           0 :     if (!(options & kOptionUnfollow)) {
+     193           0 :       if (opArray[0].isLabel()) {
+     194           0 :         Error err = getCBLabel(&jTarget, static_cast<Label&>(opArray[0]));
+     195           0 :         if (err) return setLastError(err);
+     196             :       }
+     197             :       else {
+     198           0 :         options |= kOptionUnfollow;
+     199             :       }
+     200             :     }
+     201             :     node->setOptions(options);
+     202             : 
+     203           0 :     node->orFlags(instId == X86Inst::kIdJmp ? CBNode::kFlagIsJmp | CBNode::kFlagIsTaken : CBNode::kFlagIsJcc);
+     204           0 :     node->_target = jTarget;
+     205           0 :     node->_jumpNext = nullptr;
+     206             : 
+     207           0 :     if (jTarget) {
+     208           0 :       node->_jumpNext = static_cast<CBJump*>(jTarget->_from);
+     209           0 :       jTarget->_from = node;
+     210             :       jTarget->addNumRefs();
+     211             :     }
+     212             : 
+     213             :     // The 'jmp' is always taken, conditional jump can contain hint, we detect it.
+     214           0 :     if (instId == X86Inst::kIdJmp)
+     215             :       node->orFlags(CBNode::kFlagIsTaken);
+     216           0 :     else if (options & X86Inst::kOptionTaken)
+     217             :       node->orFlags(CBNode::kFlagIsTaken);
+     218             : 
+     219           0 :     if (inlineComment) {
+     220           0 :       inlineComment = static_cast<char*>(_cbDataZone.dup(inlineComment, ::strlen(inlineComment), true));
+     221             :       node->setInlineComment(inlineComment);
+     222             :     }
+     223             : 
+     224           0 :     addNode(node);
+     225           0 :     return kErrorOk;
+     226             :   }
+     227             :   else {
+     228       46714 :     CBInst* node = _cbHeap.allocT<CBInst>(sizeof(CBInst) + opCount * sizeof(Operand));
+     229       46714 :     Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CBInst));
+     230             : 
+     231       46714 :     if (ASMJIT_UNLIKELY(!node))
+     232           0 :       return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     233             : 
+     234       46714 :     if (opCount > 0) opArray[0].copyFrom(o0);
+     235       46714 :     if (opCount > 1) opArray[1].copyFrom(o1);
+     236       46714 :     if (opCount > 2) opArray[2].copyFrom(o2);
+     237       46714 :     if (opCount > 3) opArray[3].copyFrom(o3);
+     238             : 
+     239             :     node = new(node) CBInst(this, instId, options, opArray, opCount);
+     240       46714 :     node->_instDetail.extraReg = _extraReg;
+     241             :     _extraReg.reset();
+     242             : 
+     243       46714 :     if (inlineComment) {
+     244           0 :       inlineComment = static_cast<char*>(_cbDataZone.dup(inlineComment, ::strlen(inlineComment), true));
+     245             :       node->setInlineComment(inlineComment);
+     246             :     }
+     247             : 
+     248       46714 :     addNode(node);
+     249       46714 :     return kErrorOk;
+     250             :   }
+     251             : }
+     252             : 
+     253           0 : Error X86Compiler::_emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) {
+     254           0 :   uint32_t options = getOptions() | getGlobalOptions();
+     255             :   const char* inlineComment = getInlineComment();
+     256             : 
+     257           0 :   uint32_t opCount = static_cast<uint32_t>(!o0.isNone()) +
+     258           0 :                      static_cast<uint32_t>(!o1.isNone()) +
+     259           0 :                      static_cast<uint32_t>(!o2.isNone()) +
+     260           0 :                      static_cast<uint32_t>(!o3.isNone()) ;
+     261             : 
+     262             :   // Count 5th and 6th operands.
+     263           0 :   if (!o4.isNone()) opCount = 5;
+     264           0 :   if (!o5.isNone()) opCount = 6;
+     265             : 
+     266             :   // Handle failure and rare cases first.
+     267             :   const uint32_t kErrorsAndSpecialCases = kOptionMaybeFailureCase | // CodeEmitter in error state.
+     268             :                                           kOptionStrictValidation ; // Strict validation.
+     269             : 
+     270           0 :   if (ASMJIT_UNLIKELY(options & kErrorsAndSpecialCases)) {
+     271             :     // Don't do anything if we are in error state.
+     272           0 :     if (_lastError) return _lastError;
+     273             : 
+     274             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+     275             :     // Strict validation.
+     276           0 :     if (options & kOptionStrictValidation) {
+     277             :       Operand opArray[] = {
+     278             :         Operand(o0),
+     279             :         Operand(o1),
+     280             :         Operand(o2),
+     281             :         Operand(o3),
+     282             :         Operand(o4),
+     283             :         Operand(o5)
+     284             :       };
+     285             : 
+     286             :       Inst::Detail instDetail(instId, options, _extraReg);
+     287           0 :       Error err = Inst::validate(getArchType(), instDetail, opArray, opCount);
+     288             : 
+     289           0 :       if (err) {
+     290             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     291             :         StringBuilderTmp<256> sb;
+     292           0 :         sb.appendString(DebugUtils::errorAsString(err));
+     293             :         sb.appendString(": ");
+     294           0 :         Logging::formatInstruction(sb, 0, this, getArchType(), instDetail, opArray, opCount);
+     295           0 :         return setLastError(err, sb.getData());
+     296             : #else
+     297             :         return setLastError(err);
+     298             : #endif
+     299             :       }
+     300             : 
+     301             :       // Clear it as it must be enabled explicitly on assembler side.
+     302           0 :       options &= ~kOptionStrictValidation;
+     303             :     }
+     304             : #endif // ASMJIT_DISABLE_VALIDATION
+     305             :   }
+     306             : 
+     307             :   resetOptions();
+     308             :   resetInlineComment();
+     309             : 
+     310             :   // decide between `CBInst` and `CBJump`.
+     311           0 :   if (isJumpInst(instId)) {
+     312           0 :     CBJump* node = _cbHeap.allocT<CBJump>(sizeof(CBJump) + opCount * sizeof(Operand));
+     313           0 :     Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CBJump));
+     314             : 
+     315           0 :     if (ASMJIT_UNLIKELY(!node))
+     316           0 :       return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     317             : 
+     318           0 :     if (opCount > 0) opArray[0].copyFrom(o0);
+     319           0 :     if (opCount > 1) opArray[1].copyFrom(o1);
+     320           0 :     if (opCount > 2) opArray[2].copyFrom(o2);
+     321           0 :     if (opCount > 3) opArray[3].copyFrom(o3);
+     322           0 :     if (opCount > 4) opArray[4].copyFrom(o4);
+     323           0 :     if (opCount > 5) opArray[5].copyFrom(o5);
+     324             : 
+     325             :     new(node) CBJump(this, instId, options, opArray, opCount);
+     326           0 :     node->_instDetail.extraReg = _extraReg;
+     327             :     _extraReg.reset();
+     328             : 
+     329           0 :     CBLabel* jTarget = nullptr;
+     330           0 :     if (!(options & kOptionUnfollow)) {
+     331           0 :       if (opArray[0].isLabel()) {
+     332           0 :         Error err = getCBLabel(&jTarget, static_cast<Label&>(opArray[0]));
+     333           0 :         if (err) return setLastError(err);
+     334             :       }
+     335             :       else {
+     336           0 :         options |= kOptionUnfollow;
+     337             :       }
+     338             :     }
+     339             :     node->setOptions(options);
+     340             : 
+     341           0 :     node->orFlags(instId == X86Inst::kIdJmp ? CBNode::kFlagIsJmp | CBNode::kFlagIsTaken : CBNode::kFlagIsJcc);
+     342           0 :     node->_target = jTarget;
+     343           0 :     node->_jumpNext = nullptr;
+     344             : 
+     345           0 :     if (jTarget) {
+     346           0 :       node->_jumpNext = static_cast<CBJump*>(jTarget->_from);
+     347           0 :       jTarget->_from = node;
+     348             :       jTarget->addNumRefs();
+     349             :     }
+     350             : 
+     351             :     // The 'jmp' is always taken, conditional jump can contain hint, we detect it.
+     352           0 :     if (instId == X86Inst::kIdJmp)
+     353             :       node->orFlags(CBNode::kFlagIsTaken);
+     354           0 :     else if (options & X86Inst::kOptionTaken)
+     355             :       node->orFlags(CBNode::kFlagIsTaken);
+     356             : 
+     357           0 :     if (inlineComment) {
+     358           0 :       inlineComment = static_cast<char*>(_cbDataZone.dup(inlineComment, ::strlen(inlineComment), true));
+     359             :       node->setInlineComment(inlineComment);
+     360             :     }
+     361             : 
+     362           0 :     addNode(node);
+     363           0 :     return kErrorOk;
+     364             :   }
+     365             :   else {
+     366           0 :     CBInst* node = _cbHeap.allocT<CBInst>(sizeof(CBInst) + opCount * sizeof(Operand));
+     367           0 :     Operand* opArray = reinterpret_cast<Operand*>(reinterpret_cast<uint8_t*>(node) + sizeof(CBInst));
+     368             : 
+     369           0 :     if (ASMJIT_UNLIKELY(!node))
+     370           0 :       return setLastError(DebugUtils::errored(kErrorNoHeapMemory));
+     371             : 
+     372           0 :     if (opCount > 0) opArray[0].copyFrom(o0);
+     373           0 :     if (opCount > 1) opArray[1].copyFrom(o1);
+     374           0 :     if (opCount > 2) opArray[2].copyFrom(o2);
+     375           0 :     if (opCount > 3) opArray[3].copyFrom(o3);
+     376           0 :     if (opCount > 4) opArray[4].copyFrom(o4);
+     377           0 :     if (opCount > 5) opArray[5].copyFrom(o5);
+     378             : 
+     379             :     node = new(node) CBInst(this, instId, options, opArray, opCount);
+     380           0 :     node->_instDetail.extraReg = _extraReg;
+     381             :     _extraReg.reset();
+     382             : 
+     383           0 :     if (inlineComment) {
+     384           0 :       inlineComment = static_cast<char*>(_cbDataZone.dup(inlineComment, ::strlen(inlineComment), true));
+     385             :       node->setInlineComment(inlineComment);
+     386             :     }
+     387             : 
+     388           0 :     addNode(node);
+     389           0 :     return kErrorOk;
+     390             :   }
+     391             : }
+     392             : 
+     393             : } // asmjit namespace
+     394             : } // namespace PLMD
+     395             : 
+     396             : // [Api-End]
+     397             : #include "./asmjit_apiend.h"
+     398             : 
+     399             : // [Guard]
+     400             : #endif // ASMJIT_BUILD_X86 && !ASMJIT_DISABLE_COMPILER
+     401             : #pragma GCC diagnostic pop
+     402             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.h.func-sort-c.html b/coverage-libs/asmjit/x86compiler.h.func-sort-c.html new file mode 100644 index 000000000000..fa628c8e63d7 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4666.7 %
Date:2024-02-22 21:58:47Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler6newGpzEPKcz0
_ZN4PLMD6asmjit11X86Compiler6newRegEjPKcz0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.h.func.html b/coverage-libs/asmjit/x86compiler.h.func.html new file mode 100644 index 000000000000..38ba3fb11879 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4666.7 %
Date:2024-02-22 21:58:47Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Compiler6newGpzEPKcz0
_ZN4PLMD6asmjit11X86Compiler6newRegEjPKcz0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86compiler.h.gcov.html b/coverage-libs/asmjit/x86compiler.h.gcov.html new file mode 100644 index 000000000000..d8013eb0d979 --- /dev/null +++ b/coverage-libs/asmjit/x86compiler.h.gcov.html @@ -0,0 +1,399 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86compiler.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86compiler.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4666.7 %
Date:2024-02-22 21:58:47Functions:020.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_x86compiler_h
+      21             : #define __PLUMED_asmjit_x86compiler_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_X86_X86COMPILER_H
+      33             : #define _ASMJIT_X86_X86COMPILER_H
+      34             : 
+      35             : #include "./asmjit_build.h"
+      36             : #if !defined(ASMJIT_DISABLE_COMPILER)
+      37             : 
+      38             : // [Dependencies]
+      39             : #include "./codecompiler.h"
+      40             : #include "./simdtypes.h"
+      41             : #include "./x86emitter.h"
+      42             : #include "./x86misc.h"
+      43             : 
+      44             : // [Api-Begin]
+      45             : #include "./asmjit_apibegin.h"
+      46             : 
+      47             : namespace PLMD {
+      48             : namespace asmjit {
+      49             : 
+      50             : //! \addtogroup asmjit_x86
+      51             : //! \{
+      52             : 
+      53             : // ============================================================================
+      54             : // [asmjit::X86Compiler]
+      55             : // ============================================================================
+      56             : 
+      57             : //! Architecture-dependent \ref CodeCompiler targeting X86 and X64.
+      58             : class ASMJIT_VIRTAPI X86Compiler
+      59             :   : public CodeCompiler,
+      60             :     public X86EmitterExplicitT<X86Compiler> {
+      61             : 
+      62             : public:
+      63             :   ASMJIT_NONCOPYABLE(X86Compiler)
+      64             :   typedef CodeCompiler Base;
+      65             : 
+      66             :   // --------------------------------------------------------------------------
+      67             :   // [Construction / Destruction]
+      68             :   // --------------------------------------------------------------------------
+      69             : 
+      70             :   //! Create a `X86Compiler` instance.
+      71             :   ASMJIT_API X86Compiler(CodeHolder* code = nullptr) noexcept;
+      72             :   //! Destroy the `X86Compiler` instance.
+      73             :   ASMJIT_API ~X86Compiler() noexcept;
+      74             : 
+      75             :   // --------------------------------------------------------------------------
+      76             :   // [Compatibility]
+      77             :   // --------------------------------------------------------------------------
+      78             : 
+      79             :   //! Explicit cast to `X86Emitter`.
+      80             :   ASMJIT_INLINE X86Emitter* asEmitter() noexcept { return reinterpret_cast<X86Emitter*>(this); }
+      81             :   //! Explicit cast to `X86Emitter` (const).
+      82             :   ASMJIT_INLINE const X86Emitter* asEmitter() const noexcept { return reinterpret_cast<const X86Emitter*>(this); }
+      83             : 
+      84             :   //! Implicit cast to `X86Emitter`.
+      85             :   ASMJIT_INLINE operator X86Emitter&() noexcept { return *asEmitter(); }
+      86             :   //! Implicit cast to `X86Emitter` (const).
+      87             :   ASMJIT_INLINE operator const X86Emitter&() const noexcept { return *asEmitter(); }
+      88             : 
+      89             :   // --------------------------------------------------------------------------
+      90             :   // [Events]
+      91             :   // --------------------------------------------------------------------------
+      92             : 
+      93             :   ASMJIT_API virtual Error onAttach(CodeHolder* code) noexcept override;
+      94             : 
+      95             :   // --------------------------------------------------------------------------
+      96             :   // [Code-Generation]
+      97             :   // --------------------------------------------------------------------------
+      98             : 
+      99             :   ASMJIT_API virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3) override;
+     100             :   ASMJIT_API virtual Error _emit(uint32_t instId, const Operand_& o0, const Operand_& o1, const Operand_& o2, const Operand_& o3, const Operand_& o4, const Operand_& o5) override;
+     101             : 
+     102             :   // -------------------------------------------------------------------------
+     103             :   // [Finalize]
+     104             :   // -------------------------------------------------------------------------
+     105             : 
+     106             :   ASMJIT_API virtual Error finalize() override;
+     107             : 
+     108             :   // --------------------------------------------------------------------------
+     109             :   // [VirtReg]
+     110             :   // --------------------------------------------------------------------------
+     111             : 
+     112             : #if !defined(ASMJIT_DISABLE_LOGGING)
+     113             : #define ASMJIT_NEW_REG(OUT, PARAM, NAME_FMT)            \
+     114             :   va_list ap;                                           \
+     115             :   va_start(ap, NAME_FMT);                               \
+     116             :   _newReg(OUT, PARAM, NAME_FMT, ap);                    \
+     117             :   va_end(ap)
+     118             : #else
+     119             : #define ASMJIT_NEW_REG(OUT, PARAM, NAME_FMT)            \
+     120             :   ASMJIT_UNUSED(NAME_FMT);                              \
+     121             :   _newReg(OUT, PARAM, nullptr)
+     122             : #endif
+     123             : 
+     124             : #define ASMJIT_NEW_REG_USER(FUNC, REG)                  \
+     125             :   ASMJIT_INLINE REG FUNC(uint32_t typeId) {             \
+     126             :     REG reg(NoInit);                                    \
+     127             :     _newReg(reg, typeId, nullptr);                      \
+     128             :     return reg;                                         \
+     129             :   }                                                     \
+     130             :                                                         \
+     131             :   REG FUNC(uint32_t typeId, const char* nameFmt, ...) { \
+     132             :     REG reg(NoInit);                                    \
+     133             :     ASMJIT_NEW_REG(reg, typeId, nameFmt);               \
+     134             :     return reg;                                         \
+     135             :   }
+     136             : 
+     137             : #define ASMJIT_NEW_REG_AUTO(FUNC, REG, TYPE_ID)         \
+     138             :   ASMJIT_INLINE REG FUNC() {                            \
+     139             :     REG reg(NoInit);                                    \
+     140             :     _newReg(reg, TYPE_ID, nullptr);                     \
+     141             :     return reg;                                         \
+     142             :   }                                                     \
+     143             :                                                         \
+     144             :   REG FUNC(const char* nameFmt, ...) {                  \
+     145             :     REG reg(NoInit);                                    \
+     146             :     ASMJIT_NEW_REG(reg, TYPE_ID, nameFmt);              \
+     147             :     return reg;                                         \
+     148             :   }
+     149             : 
+     150             :   template<typename RegT>
+     151             :   ASMJIT_INLINE RegT newSimilarReg(const RegT& ref) {
+     152             :     RegT reg(NoInit);
+     153             :     _newReg(reg, ref, nullptr);
+     154             :     return reg;
+     155             :   }
+     156             : 
+     157             :   template<typename RegT>
+     158             :   RegT newSimilarReg(const RegT& ref, const char* nameFmt, ...) {
+     159             :     RegT reg(NoInit);
+     160             :     ASMJIT_NEW_REG(reg, ref, nameFmt);
+     161             :     return reg;
+     162             :   }
+     163             : 
+     164           0 :   ASMJIT_NEW_REG_USER(newReg    , X86Reg )
+     165             :   ASMJIT_NEW_REG_USER(newGpReg  , X86Gp  )
+     166             :   ASMJIT_NEW_REG_USER(newMmReg  , X86Mm  )
+     167             :   ASMJIT_NEW_REG_USER(newKReg   , X86KReg)
+     168             :   ASMJIT_NEW_REG_USER(newXmmReg , X86Xmm )
+     169             :   ASMJIT_NEW_REG_USER(newYmmReg , X86Ymm )
+     170             :   ASMJIT_NEW_REG_USER(newZmmReg , X86Zmm )
+     171             : 
+     172             :   ASMJIT_NEW_REG_AUTO(newI8     , X86Gp  , TypeId::kI8     )
+     173             :   ASMJIT_NEW_REG_AUTO(newU8     , X86Gp  , TypeId::kU8     )
+     174             :   ASMJIT_NEW_REG_AUTO(newI16    , X86Gp  , TypeId::kI16    )
+     175             :   ASMJIT_NEW_REG_AUTO(newU16    , X86Gp  , TypeId::kU16    )
+     176             :   ASMJIT_NEW_REG_AUTO(newI32    , X86Gp  , TypeId::kI32    )
+     177             :   ASMJIT_NEW_REG_AUTO(newU32    , X86Gp  , TypeId::kU32    )
+     178             :   ASMJIT_NEW_REG_AUTO(newI64    , X86Gp  , TypeId::kI64    )
+     179             :   ASMJIT_NEW_REG_AUTO(newU64    , X86Gp  , TypeId::kU64    )
+     180             :   ASMJIT_NEW_REG_AUTO(newInt8   , X86Gp  , TypeId::kI8     )
+     181             :   ASMJIT_NEW_REG_AUTO(newUInt8  , X86Gp  , TypeId::kU8     )
+     182             :   ASMJIT_NEW_REG_AUTO(newInt16  , X86Gp  , TypeId::kI16    )
+     183             :   ASMJIT_NEW_REG_AUTO(newUInt16 , X86Gp  , TypeId::kU16    )
+     184             :   ASMJIT_NEW_REG_AUTO(newInt32  , X86Gp  , TypeId::kI32    )
+     185             :   ASMJIT_NEW_REG_AUTO(newUInt32 , X86Gp  , TypeId::kU32    )
+     186             :   ASMJIT_NEW_REG_AUTO(newInt64  , X86Gp  , TypeId::kI64    )
+     187             :   ASMJIT_NEW_REG_AUTO(newUInt64 , X86Gp  , TypeId::kU64    )
+     188        7268 :   ASMJIT_NEW_REG_AUTO(newIntPtr , X86Gp  , TypeId::kIntPtr )
+     189             :   ASMJIT_NEW_REG_AUTO(newUIntPtr, X86Gp  , TypeId::kUIntPtr)
+     190             : 
+     191             :   ASMJIT_NEW_REG_AUTO(newGpb    , X86Gp  , TypeId::kU8     )
+     192             :   ASMJIT_NEW_REG_AUTO(newGpw    , X86Gp  , TypeId::kU16    )
+     193             :   ASMJIT_NEW_REG_AUTO(newGpd    , X86Gp  , TypeId::kU32    )
+     194             :   ASMJIT_NEW_REG_AUTO(newGpq    , X86Gp  , TypeId::kU64    )
+     195           0 :   ASMJIT_NEW_REG_AUTO(newGpz    , X86Gp  , TypeId::kUIntPtr)
+     196             :   ASMJIT_NEW_REG_AUTO(newKb     , X86KReg, TypeId::kMask8  )
+     197             :   ASMJIT_NEW_REG_AUTO(newKw     , X86KReg, TypeId::kMask16 )
+     198             :   ASMJIT_NEW_REG_AUTO(newKd     , X86KReg, TypeId::kMask32 )
+     199             :   ASMJIT_NEW_REG_AUTO(newKq     , X86KReg, TypeId::kMask64 )
+     200             :   ASMJIT_NEW_REG_AUTO(newMm     , X86Mm  , TypeId::kMmx64  )
+     201             :   ASMJIT_NEW_REG_AUTO(newXmm    , X86Xmm , TypeId::kI32x4  )
+     202             :   ASMJIT_NEW_REG_AUTO(newXmmSs  , X86Xmm , TypeId::kF32x1  )
+     203       16520 :   ASMJIT_NEW_REG_AUTO(newXmmSd  , X86Xmm , TypeId::kF64x1  )
+     204             :   ASMJIT_NEW_REG_AUTO(newXmmPs  , X86Xmm , TypeId::kF32x4  )
+     205             :   ASMJIT_NEW_REG_AUTO(newXmmPd  , X86Xmm , TypeId::kF64x2  )
+     206             :   ASMJIT_NEW_REG_AUTO(newYmm    , X86Ymm , TypeId::kI32x8  )
+     207             :   ASMJIT_NEW_REG_AUTO(newYmmPs  , X86Ymm , TypeId::kF32x8  )
+     208             :   ASMJIT_NEW_REG_AUTO(newYmmPd  , X86Ymm , TypeId::kF64x4  )
+     209             :   ASMJIT_NEW_REG_AUTO(newZmm    , X86Zmm , TypeId::kI32x16 )
+     210             :   ASMJIT_NEW_REG_AUTO(newZmmPs  , X86Zmm , TypeId::kF32x16 )
+     211             :   ASMJIT_NEW_REG_AUTO(newZmmPd  , X86Zmm , TypeId::kF64x8  )
+     212             : 
+     213             : #undef ASMJIT_NEW_REG_AUTO
+     214             : #undef ASMJIT_NEW_REG_USER
+     215             : #undef ASMJIT_NEW_REG
+     216             : 
+     217             :   // --------------------------------------------------------------------------
+     218             :   // [Stack]
+     219             :   // --------------------------------------------------------------------------
+     220             : 
+     221             :   //! Create a new memory chunk allocated on the current function's stack.
+     222             :   ASMJIT_INLINE X86Mem newStack(uint32_t size, uint32_t alignment, const char* name = nullptr) {
+     223             :     X86Mem m(NoInit);
+     224             :     _newStack(m, size, alignment, name);
+     225             :     return m;
+     226             :   }
+     227             : 
+     228             :   // --------------------------------------------------------------------------
+     229             :   // [Const]
+     230             :   // --------------------------------------------------------------------------
+     231             : 
+     232             :   //! Put data to a constant-pool and get a memory reference to it.
+     233             :   ASMJIT_INLINE X86Mem newConst(uint32_t scope, const void* data, size_t size) {
+     234             :     X86Mem m(NoInit);
+     235             :     _newConst(m, scope, data, size);
+     236             :     return m;
+     237             :   }
+     238             : 
+     239             :   //! Put a BYTE `val` to a constant-pool.
+     240             :   ASMJIT_INLINE X86Mem newByteConst(uint32_t scope, uint8_t val) noexcept { return newConst(scope, &val, 1); }
+     241             :   //! Put a WORD `val` to a constant-pool.
+     242             :   ASMJIT_INLINE X86Mem newWordConst(uint32_t scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
+     243             :   //! Put a DWORD `val` to a constant-pool.
+     244             :   ASMJIT_INLINE X86Mem newDWordConst(uint32_t scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
+     245             :   //! Put a QWORD `val` to a constant-pool.
+     246             :   ASMJIT_INLINE X86Mem newQWordConst(uint32_t scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
+     247             : 
+     248             :   //! Put a WORD `val` to a constant-pool.
+     249             :   ASMJIT_INLINE X86Mem newInt16Const(uint32_t scope, int16_t val) noexcept { return newConst(scope, &val, 2); }
+     250             :   //! Put a WORD `val` to a constant-pool.
+     251             :   ASMJIT_INLINE X86Mem newUInt16Const(uint32_t scope, uint16_t val) noexcept { return newConst(scope, &val, 2); }
+     252             :   //! Put a DWORD `val` to a constant-pool.
+     253             :   ASMJIT_INLINE X86Mem newInt32Const(uint32_t scope, int32_t val) noexcept { return newConst(scope, &val, 4); }
+     254             :   //! Put a DWORD `val` to a constant-pool.
+     255             :   ASMJIT_INLINE X86Mem newUInt32Const(uint32_t scope, uint32_t val) noexcept { return newConst(scope, &val, 4); }
+     256             :   //! Put a QWORD `val` to a constant-pool.
+     257             :   ASMJIT_INLINE X86Mem newInt64Const(uint32_t scope, int64_t val) noexcept { return newConst(scope, &val, 8); }
+     258             :   //! Put a QWORD `val` to a constant-pool.
+     259             :   ASMJIT_INLINE X86Mem newUInt64Const(uint32_t scope, uint64_t val) noexcept { return newConst(scope, &val, 8); }
+     260             : 
+     261             :   //! Put a SP-FP `val` to a constant-pool.
+     262             :   ASMJIT_INLINE X86Mem newFloatConst(uint32_t scope, float val) noexcept { return newConst(scope, &val, 4); }
+     263             :   //! Put a DP-FP `val` to a constant-pool.
+     264             :   ASMJIT_INLINE X86Mem newDoubleConst(uint32_t scope, double val) noexcept { return newConst(scope, &val, 8); }
+     265             : 
+     266             :   //! Put a MMX `val` to a constant-pool.
+     267             :   ASMJIT_INLINE X86Mem newMmConst(uint32_t scope, const Data64& val) noexcept { return newConst(scope, &val, 8); }
+     268             :   //! Put a XMM `val` to a constant-pool.
+     269             :   ASMJIT_INLINE X86Mem newXmmConst(uint32_t scope, const Data128& val) noexcept { return newConst(scope, &val, 16); }
+     270             :   //! Put a YMM `val` to a constant-pool.
+     271             :   ASMJIT_INLINE X86Mem newYmmConst(uint32_t scope, const Data256& val) noexcept { return newConst(scope, &val, 32); }
+     272             : 
+     273             :   // -------------------------------------------------------------------------
+     274             :   // [Instruction Options]
+     275             :   // -------------------------------------------------------------------------
+     276             : 
+     277             :   //! Force the compiler to not follow the conditional or unconditional jump.
+     278             :   ASMJIT_INLINE X86Compiler& unfollow() noexcept { _options |= kOptionUnfollow; return *this; }
+     279             :   //! Tell the compiler that the destination variable will be overwritten.
+     280             :   ASMJIT_INLINE X86Compiler& overwrite() noexcept { _options |= kOptionOverwrite; return *this; }
+     281             : 
+     282             :   // --------------------------------------------------------------------------
+     283             :   // [Emit]
+     284             :   // --------------------------------------------------------------------------
+     285             : 
+     286             :   //! Call a function.
+     287        1648 :   ASMJIT_INLINE CCFuncCall* call(const X86Gp& dst, const FuncSignature& sign) { return addCall(X86Inst::kIdCall, dst, sign); }
+     288             :   //! \overload
+     289             :   ASMJIT_INLINE CCFuncCall* call(const X86Mem& dst, const FuncSignature& sign) { return addCall(X86Inst::kIdCall, dst, sign); }
+     290             :   //! \overload
+     291             :   ASMJIT_INLINE CCFuncCall* call(const Label& label, const FuncSignature& sign) { return addCall(X86Inst::kIdCall, label, sign); }
+     292             :   //! \overload
+     293             :   ASMJIT_INLINE CCFuncCall* call(const Imm& dst, const FuncSignature& sign) { return addCall(X86Inst::kIdCall, dst, sign); }
+     294             :   //! \overload
+     295             :   ASMJIT_INLINE CCFuncCall* call(uint64_t dst, const FuncSignature& sign) { return addCall(X86Inst::kIdCall, Imm(dst), sign); }
+     296             : 
+     297             :   //! Return.
+     298             :   ASMJIT_INLINE CCFuncRet* ret() { return addRet(Operand(), Operand()); }
+     299             :   //! \overload
+     300             :   ASMJIT_INLINE CCFuncRet* ret(const X86Gp& o0) { return addRet(o0, Operand()); }
+     301             :   //! \overload
+     302             :   ASMJIT_INLINE CCFuncRet* ret(const X86Gp& o0, const X86Gp& o1) { return addRet(o0, o1); }
+     303             :   //! \overload
+     304        1948 :   ASMJIT_INLINE CCFuncRet* ret(const X86Xmm& o0) { return addRet(o0, Operand()); }
+     305             :   //! \overload
+     306             :   ASMJIT_INLINE CCFuncRet* ret(const X86Xmm& o0, const X86Xmm& o1) { return addRet(o0, o1); }
+     307             : };
+     308             : 
+     309             : //! \}
+     310             : 
+     311             : } // asmjit namespace
+     312             : } // namespace PLMD
+     313             : 
+     314             : // [Api-End]
+     315             : #include "./asmjit_apiend.h"
+     316             : 
+     317             : // [Guard]
+     318             : #endif // !ASMJIT_DISABLE_COMPILER
+     319             : #endif // _ASMJIT_X86_X86COMPILER_H
+     320             : #pragma GCC diagnostic pop
+     321             : #endif // __PLUMED_HAS_ASMJIT
+     322             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86emitter.h.func-sort-c.html b/coverage-libs/asmjit/x86emitter.h.func-sort-c.html new file mode 100644 index 000000000000..c14d8965724b --- /dev/null +++ b/coverage-libs/asmjit/x86emitter.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86emitter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86emitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:172763.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86emitter.h.func.html b/coverage-libs/asmjit/x86emitter.h.func.html new file mode 100644 index 000000000000..893b8d9a87d4 --- /dev/null +++ b/coverage-libs/asmjit/x86emitter.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86emitter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86emitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:172763.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86emitter.h.gcov.html b/coverage-libs/asmjit/x86emitter.h.gcov.html new file mode 100644 index 000000000000..bff5d97bb4cb --- /dev/null +++ b/coverage-libs/asmjit/x86emitter.h.gcov.html @@ -0,0 +1,5226 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86emitter.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86emitter.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:172763.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_x86emitter_h
+      21             : #define __PLUMED_asmjit_x86emitter_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_X86_X86EMITTER_H
+      33             : #define _ASMJIT_X86_X86EMITTER_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./codeemitter.h"
+      37             : #include "./x86inst.h"
+      38             : #include "./x86operand.h"
+      39             : 
+      40             : // [Api-Begin]
+      41             : #include "./asmjit_apibegin.h"
+      42             : 
+      43             : namespace PLMD {
+      44             : namespace asmjit {
+      45             : 
+      46             : //! \addtogroup asmjit_x86
+      47             : //! \{
+      48             : 
+      49             : // ============================================================================
+      50             : // [asmjit::X86EmitterExplicitT]
+      51             : // ============================================================================
+      52             : 
+      53             : #define ASMJIT_EMIT static_cast<This*>(this)->emit
+      54             : 
+      55             : #define ASMJIT_INST_0x(NAME, ID) \
+      56             :   ASMJIT_INLINE Error NAME() { return ASMJIT_EMIT(X86Inst::kId##ID); }
+      57             : 
+      58             : #define ASMJIT_INST_1x(NAME, ID, T0) \
+      59             :   ASMJIT_INLINE Error NAME(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID, o0); }
+      60             : 
+      61             : #define ASMJIT_INST_1i(NAME, ID, T0) \
+      62             :   ASMJIT_INLINE Error NAME(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID, o0); } \
+      63             :   ASMJIT_INLINE Error NAME(int o0) { return ASMJIT_EMIT(X86Inst::kId##ID, Utils::asInt(o0)); } \
+      64             :   ASMJIT_INLINE Error NAME(unsigned int o0) { return ASMJIT_EMIT(X86Inst::kId##ID, Utils::asInt(o0)); } \
+      65             :   ASMJIT_INLINE Error NAME(int64_t o0) { return ASMJIT_EMIT(X86Inst::kId##ID, Utils::asInt(o0)); } \
+      66             :   ASMJIT_INLINE Error NAME(uint64_t o0) { return ASMJIT_EMIT(X86Inst::kId##ID, Utils::asInt(o0)); }
+      67             : 
+      68             : #define ASMJIT_INST_1c(NAME, ID, CONV, T0) \
+      69             :   ASMJIT_INLINE Error NAME(uint32_t cc, const T0& o0) { return ASMJIT_EMIT(CONV(cc), o0); } \
+      70             :   ASMJIT_INLINE Error NAME##a(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##a, o0); } \
+      71             :   ASMJIT_INLINE Error NAME##ae(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##ae, o0); } \
+      72             :   ASMJIT_INLINE Error NAME##b(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##b, o0); } \
+      73             :   ASMJIT_INLINE Error NAME##be(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##be, o0); } \
+      74             :   ASMJIT_INLINE Error NAME##c(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##c, o0); } \
+      75             :   ASMJIT_INLINE Error NAME##e(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##e, o0); } \
+      76             :   ASMJIT_INLINE Error NAME##g(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##g, o0); } \
+      77             :   ASMJIT_INLINE Error NAME##ge(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##ge, o0); } \
+      78             :   ASMJIT_INLINE Error NAME##l(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##l, o0); } \
+      79             :   ASMJIT_INLINE Error NAME##le(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##le, o0); } \
+      80             :   ASMJIT_INLINE Error NAME##na(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##na, o0); } \
+      81             :   ASMJIT_INLINE Error NAME##nae(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nae, o0); } \
+      82             :   ASMJIT_INLINE Error NAME##nb(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nb, o0); } \
+      83             :   ASMJIT_INLINE Error NAME##nbe(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nbe, o0); } \
+      84             :   ASMJIT_INLINE Error NAME##nc(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nc, o0); } \
+      85             :   ASMJIT_INLINE Error NAME##ne(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##ne, o0); } \
+      86             :   ASMJIT_INLINE Error NAME##ng(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##ng, o0); } \
+      87             :   ASMJIT_INLINE Error NAME##nge(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nge, o0); } \
+      88             :   ASMJIT_INLINE Error NAME##nl(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nl, o0); } \
+      89             :   ASMJIT_INLINE Error NAME##nle(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nle, o0); } \
+      90             :   ASMJIT_INLINE Error NAME##no(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##no, o0); } \
+      91             :   ASMJIT_INLINE Error NAME##np(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##np, o0); } \
+      92             :   ASMJIT_INLINE Error NAME##ns(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##ns, o0); } \
+      93             :   ASMJIT_INLINE Error NAME##nz(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##nz, o0); } \
+      94             :   ASMJIT_INLINE Error NAME##o(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##o, o0); } \
+      95             :   ASMJIT_INLINE Error NAME##p(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##p, o0); } \
+      96             :   ASMJIT_INLINE Error NAME##pe(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##pe, o0); } \
+      97             :   ASMJIT_INLINE Error NAME##po(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##po, o0); } \
+      98             :   ASMJIT_INLINE Error NAME##s(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##s, o0); } \
+      99             :   ASMJIT_INLINE Error NAME##z(const T0& o0) { return ASMJIT_EMIT(X86Inst::kId##ID##z, o0); }
+     100             : 
+     101             : #define ASMJIT_INST_2x(NAME, ID, T0, T1) \
+     102             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1) { \
+     103             :     return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1); \
+     104             :   }
+     105             : 
+     106             : #define ASMJIT_INST_2i(NAME, ID, T0, T1) \
+     107             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1); } \
+     108             :   ASMJIT_INLINE Error NAME(const T0& o0, int o1) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, Utils::asInt(o1)); } \
+     109             :   ASMJIT_INLINE Error NAME(const T0& o0, unsigned int o1) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, Utils::asInt(o1)); } \
+     110             :   ASMJIT_INLINE Error NAME(const T0& o0, int64_t o1) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, Utils::asInt(o1)); } \
+     111             :   ASMJIT_INLINE Error NAME(const T0& o0, uint64_t o1) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, Utils::asInt(o1)); }
+     112             : 
+     113             : #define ASMJIT_INST_2c(NAME, ID, CONV, T0, T1) \
+     114             :   ASMJIT_INLINE Error NAME(uint32_t cc, const T0& o0, const T1& o1) { return ASMJIT_EMIT(CONV(cc), o0, o1); } \
+     115             :   ASMJIT_INLINE Error NAME##a(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##a, o0, o1); } \
+     116             :   ASMJIT_INLINE Error NAME##ae(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##ae, o0, o1); } \
+     117             :   ASMJIT_INLINE Error NAME##b(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##b, o0, o1); } \
+     118             :   ASMJIT_INLINE Error NAME##be(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##be, o0, o1); } \
+     119             :   ASMJIT_INLINE Error NAME##c(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##c, o0, o1); } \
+     120             :   ASMJIT_INLINE Error NAME##e(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##e, o0, o1); } \
+     121             :   ASMJIT_INLINE Error NAME##g(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##g, o0, o1); } \
+     122             :   ASMJIT_INLINE Error NAME##ge(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##ge, o0, o1); } \
+     123             :   ASMJIT_INLINE Error NAME##l(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##l, o0, o1); } \
+     124             :   ASMJIT_INLINE Error NAME##le(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##le, o0, o1); } \
+     125             :   ASMJIT_INLINE Error NAME##na(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##na, o0, o1); } \
+     126             :   ASMJIT_INLINE Error NAME##nae(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nae, o0, o1); } \
+     127             :   ASMJIT_INLINE Error NAME##nb(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nb, o0, o1); } \
+     128             :   ASMJIT_INLINE Error NAME##nbe(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nbe, o0, o1); } \
+     129             :   ASMJIT_INLINE Error NAME##nc(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nc, o0, o1); } \
+     130             :   ASMJIT_INLINE Error NAME##ne(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##ne, o0, o1); } \
+     131             :   ASMJIT_INLINE Error NAME##ng(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##ng, o0, o1); } \
+     132             :   ASMJIT_INLINE Error NAME##nge(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nge, o0, o1); } \
+     133             :   ASMJIT_INLINE Error NAME##nl(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nl, o0, o1); } \
+     134             :   ASMJIT_INLINE Error NAME##nle(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nle, o0, o1); } \
+     135             :   ASMJIT_INLINE Error NAME##no(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##no, o0, o1); } \
+     136             :   ASMJIT_INLINE Error NAME##np(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##np, o0, o1); } \
+     137             :   ASMJIT_INLINE Error NAME##ns(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##ns, o0, o1); } \
+     138             :   ASMJIT_INLINE Error NAME##nz(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##nz, o0, o1); } \
+     139             :   ASMJIT_INLINE Error NAME##o(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##o, o0, o1); } \
+     140             :   ASMJIT_INLINE Error NAME##p(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##p, o0, o1); } \
+     141             :   ASMJIT_INLINE Error NAME##pe(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##pe, o0, o1); } \
+     142             :   ASMJIT_INLINE Error NAME##po(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##po, o0, o1); } \
+     143             :   ASMJIT_INLINE Error NAME##s(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##s, o0, o1); } \
+     144             :   ASMJIT_INLINE Error NAME##z(const T0& o0, const T1& o1) { return ASMJIT_EMIT(X86Inst::kId##ID##z, o0, o1); }
+     145             : 
+     146             : #define ASMJIT_INST_3x(NAME, ID, T0, T1, T2) \
+     147             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2); }
+     148             : 
+     149             : #define ASMJIT_INST_3i(NAME, ID, T0, T1, T2) \
+     150             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2); } \
+     151             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, int o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, Utils::asInt(o2)); } \
+     152             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, unsigned int o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, Utils::asInt(o2)); } \
+     153             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, int64_t o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, Utils::asInt(o2)); } \
+     154             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, uint64_t o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, Utils::asInt(o2)); }
+     155             : 
+     156             : #define ASMJIT_INST_3ii(NAME, ID, T0, T1, T2) \
+     157             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2); } \
+     158             :   ASMJIT_INLINE Error NAME(const T0& o0, int o1, int o2) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, Imm(o1), Utils::asInt(o2)); }
+     159             : 
+     160             : #define ASMJIT_INST_4x(NAME, ID, T0, T1, T2, T3) \
+     161             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3); }
+     162             : 
+     163             : #define ASMJIT_INST_4i(NAME, ID, T0, T1, T2, T3) \
+     164             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3); } \
+     165             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, int o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, Utils::asInt(o3)); } \
+     166             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, unsigned int o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, Utils::asInt(o3)); } \
+     167             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, int64_t o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, Utils::asInt(o3)); } \
+     168             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, uint64_t o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, Utils::asInt(o3)); }
+     169             : 
+     170             : #define ASMJIT_INST_4ii(NAME, ID, T0, T1, T2, T3) \
+     171             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3); } \
+     172             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, int o2, int o3) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, Imm(o2), Utils::asInt(o3)); }
+     173             : 
+     174             : #define ASMJIT_INST_5x(NAME, ID, T0, T1, T2, T3, T4) \
+     175             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, const T4& o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, o4); }
+     176             : 
+     177             : #define ASMJIT_INST_5i(NAME, ID, T0, T1, T2, T3, T4) \
+     178             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, const T4& o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, o4); } \
+     179             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, int o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, Utils::asInt(o4)); } \
+     180             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, unsigned int o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, Utils::asInt(o4)); } \
+     181             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, int64_t o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, Utils::asInt(o4)); } \
+     182             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, uint64_t o4) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, Utils::asInt(o4)); }
+     183             : 
+     184             : #define ASMJIT_INST_6x(NAME, ID, T0, T1, T2, T3, T4, T5) \
+     185             :   ASMJIT_INLINE Error NAME(const T0& o0, const T1& o1, const T2& o2, const T3& o3, const T4& o4, const T5& o5) { return ASMJIT_EMIT(X86Inst::kId##ID, o0, o1, o2, o3, o4, o5); }
+     186             : 
+     187             : template<typename This>
+     188             : struct X86EmitterExplicitT {
+     189             :   // These typedefs are used to describe implicit operands passed explicitly.
+     190             :   typedef X86Gp AL;
+     191             :   typedef X86Gp AH;
+     192             :   typedef X86Gp CL;
+     193             :   typedef X86Gp AX;
+     194             :   typedef X86Gp DX;
+     195             : 
+     196             :   typedef X86Gp EAX;
+     197             :   typedef X86Gp EBX;
+     198             :   typedef X86Gp ECX;
+     199             :   typedef X86Gp EDX;
+     200             : 
+     201             :   typedef X86Gp RAX;
+     202             :   typedef X86Gp RBX;
+     203             :   typedef X86Gp RCX;
+     204             :   typedef X86Gp RDX;
+     205             : 
+     206             :   typedef X86Gp ZAX;
+     207             :   typedef X86Gp ZBX;
+     208             :   typedef X86Gp ZCX;
+     209             :   typedef X86Gp ZDX;
+     210             : 
+     211             :   typedef X86Mem DS_ZAX; // ds:[zax]
+     212             :   typedef X86Mem DS_ZDI; // ds:[zdi]
+     213             :   typedef X86Mem ES_ZDI; // es:[zdi]
+     214             :   typedef X86Mem DS_ZSI; // ds:[zsi]
+     215             : 
+     216             :   typedef X86Xmm XMM0;
+     217             : 
+     218             :   // --------------------------------------------------------------------------
+     219             :   // [Accessors]
+     220             :   // --------------------------------------------------------------------------
+     221             : 
+     222             :   //! Get GPD or GPQ register at index `id` depending on the current architecture.
+     223             :   ASMJIT_INLINE X86Gp gpz(uint32_t id) const noexcept {
+     224             :     return X86Gp(Init, static_cast<const This*>(this)->_nativeGpReg.getSignature(), id);
+     225             :   }
+     226             : 
+     227             :   ASMJIT_INLINE const X86Gp& gpzRef(uint32_t id) const noexcept {
+     228             :     ASMJIT_ASSERT(id < 16);
+     229        5844 :     return static_cast<const X86Gp&>(static_cast<const This*>(this)->_nativeGpArray[id]);
+     230             :   }
+     231             : 
+     232             :   ASMJIT_INLINE const X86Gp& zax() const noexcept { return gpzRef(X86Gp::kIdAx); }
+     233             :   ASMJIT_INLINE const X86Gp& zcx() const noexcept { return gpzRef(X86Gp::kIdCx); }
+     234             :   ASMJIT_INLINE const X86Gp& zdx() const noexcept { return gpzRef(X86Gp::kIdDx); }
+     235             :   ASMJIT_INLINE const X86Gp& zbx() const noexcept { return gpzRef(X86Gp::kIdBx); }
+     236             :   ASMJIT_INLINE const X86Gp& zsp() const noexcept { return gpzRef(X86Gp::kIdSp); }
+     237             :   ASMJIT_INLINE const X86Gp& zbp() const noexcept { return gpzRef(X86Gp::kIdBp); }
+     238             :   ASMJIT_INLINE const X86Gp& zsi() const noexcept { return gpzRef(X86Gp::kIdSi); }
+     239             :   ASMJIT_INLINE const X86Gp& zdi() const noexcept { return gpzRef(X86Gp::kIdDi); }
+     240             : 
+     241             :   //! Create a target dependent pointer of which base register's id is `baseId`.
+     242             :   ASMJIT_INLINE X86Mem ptr_base(uint32_t baseId, int32_t off = 0, uint32_t size = 0) const noexcept {
+     243             :     uint32_t baseType = static_cast<const This*>(this)->_nativeGpReg.getType();
+     244             :     uint32_t flags = 0;
+     245             :     return X86Mem(Init, baseType, baseId, 0, 0, off, size, flags);
+     246             :   }
+     247             : 
+     248             :   ASMJIT_INLINE X86Mem ptr_zax(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdAx, off, size); }
+     249             :   ASMJIT_INLINE X86Mem ptr_zcx(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdCx, off, size); }
+     250             :   ASMJIT_INLINE X86Mem ptr_zdx(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdDx, off, size); }
+     251             :   ASMJIT_INLINE X86Mem ptr_zbx(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdBx, off, size); }
+     252             :   ASMJIT_INLINE X86Mem ptr_zsp(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdSp, off, size); }
+     253             :   ASMJIT_INLINE X86Mem ptr_zbp(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdBp, off, size); }
+     254             :   ASMJIT_INLINE X86Mem ptr_zsi(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdSi, off, size); }
+     255             :   ASMJIT_INLINE X86Mem ptr_zdi(int32_t off = 0, uint32_t size = 0) const noexcept { return ptr_base(X86Gp::kIdDi, off, size); }
+     256             : 
+     257             :   //! Create an `intptr_t` memory operand depending on the current architecture.
+     258             :   ASMJIT_INLINE X86Mem intptr_ptr(const X86Gp& base, int32_t offset = 0) const noexcept {
+     259             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     260             :     return X86Mem(base, offset, nativeGpSize);
+     261             :   }
+     262             :   //! \overload
+     263             :   ASMJIT_INLINE X86Mem intptr_ptr(const X86Gp& base, const X86Gp& index, uint32_t shift = 0, int32_t offset = 0) const noexcept {
+     264             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     265             :     return X86Mem(base, index, shift, offset, nativeGpSize);
+     266             :   }
+     267             :   //! \overload
+     268             :   ASMJIT_INLINE X86Mem intptr_ptr(const X86Gp& base, const X86Vec& index, uint32_t shift = 0, int32_t offset = 0) const noexcept {
+     269             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     270             :     return X86Mem(base, index, shift, offset, nativeGpSize);
+     271             :   }
+     272             :   //! \overload
+     273             :   ASMJIT_INLINE X86Mem intptr_ptr(const Label& base, int32_t offset = 0) const noexcept {
+     274             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     275             :     return X86Mem(base, offset, nativeGpSize);
+     276             :   }
+     277             :   //! \overload
+     278             :   ASMJIT_INLINE X86Mem intptr_ptr(const Label& base, const X86Gp& index, uint32_t shift, int32_t offset = 0) const noexcept {
+     279             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     280             :     return X86Mem(base, index, shift, offset, nativeGpSize);
+     281             :   }
+     282             :   //! \overload
+     283             :   ASMJIT_INLINE X86Mem intptr_ptr(const Label& base, const X86Vec& index, uint32_t shift, int32_t offset = 0) const noexcept {
+     284             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     285             :     return X86Mem(base, index, shift, offset, nativeGpSize);
+     286             :   }
+     287             :   //! \overload
+     288             :   ASMJIT_INLINE X86Mem intptr_ptr(const X86Rip& rip, int32_t offset = 0) const noexcept {
+     289             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     290             :     return X86Mem(rip, offset, nativeGpSize);
+     291             :   }
+     292             :   //! \overload
+     293             :   ASMJIT_INLINE X86Mem intptr_ptr(uint64_t base) const noexcept {
+     294             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     295             :     return X86Mem(base, nativeGpSize);
+     296             :   }
+     297             :   //! \overload
+     298             :   ASMJIT_INLINE X86Mem intptr_ptr(uint64_t base, const X86Gp& index, uint32_t shift = 0) const noexcept {
+     299             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     300             :     return X86Mem(base, index, shift, nativeGpSize);
+     301             :   }
+     302             :   //! \overload
+     303             :   ASMJIT_INLINE X86Mem intptr_ptr_abs(uint64_t base) const noexcept {
+     304             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     305             :     return X86Mem(base, nativeGpSize, Mem::kSignatureMemAbs);
+     306             :   }
+     307             :   //! \overload
+     308             :   ASMJIT_INLINE X86Mem intptr_ptr_abs(uint64_t base, const X86Gp& index, uint32_t shift = 0) const noexcept {
+     309             :     uint32_t nativeGpSize = static_cast<const This*>(this)->getGpSize();
+     310             :     return X86Mem(base, index, shift, nativeGpSize, Mem::kSignatureMemAbs);
+     311             :   }
+     312             : 
+     313             :   // --------------------------------------------------------------------------
+     314             :   // [Embed]
+     315             :   // --------------------------------------------------------------------------
+     316             : 
+     317             :   //! Add 8-bit integer data to the instruction stream.
+     318             :   ASMJIT_INLINE Error db(uint8_t x) { return static_cast<This*>(this)->embed(&x, 1); }
+     319             :   //! Add 16-bit integer data to the instruction stream.
+     320             :   ASMJIT_INLINE Error dw(uint16_t x) { return static_cast<This*>(this)->embed(&x, 2); }
+     321             :   //! Add 32-bit integer data to the instruction stream.
+     322             :   ASMJIT_INLINE Error dd(uint32_t x) { return static_cast<This*>(this)->embed(&x, 4); }
+     323             :   //! Add 64-bit integer data to the instruction stream.
+     324             :   ASMJIT_INLINE Error dq(uint64_t x) { return static_cast<This*>(this)->embed(&x, 8); }
+     325             : 
+     326             :   //! Add 8-bit integer data to the instruction stream.
+     327             :   ASMJIT_INLINE Error dint8(int8_t x) { return static_cast<This*>(this)->embed(&x, sizeof(int8_t)); }
+     328             :   //! Add 8-bit integer data to the instruction stream.
+     329             :   ASMJIT_INLINE Error duint8(uint8_t x) { return static_cast<This*>(this)->embed(&x, sizeof(uint8_t)); }
+     330             : 
+     331             :   //! Add 16-bit integer data to the instruction stream.
+     332             :   ASMJIT_INLINE Error dint16(int16_t x) { return static_cast<This*>(this)->embed(&x, sizeof(int16_t)); }
+     333             :   //! Add 16-bit integer data to the instruction stream.
+     334             :   ASMJIT_INLINE Error duint16(uint16_t x) { return static_cast<This*>(this)->embed(&x, sizeof(uint16_t)); }
+     335             : 
+     336             :   //! Add 32-bit integer data to the instruction stream.
+     337             :   ASMJIT_INLINE Error dint32(int32_t x) { return static_cast<This*>(this)->embed(&x, sizeof(int32_t)); }
+     338             :   //! Add 32-bit integer data to the instruction stream.
+     339             :   ASMJIT_INLINE Error duint32(uint32_t x) { return static_cast<This*>(this)->embed(&x, sizeof(uint32_t)); }
+     340             : 
+     341             :   //! Add 64-bit integer data to the instruction stream.
+     342             :   ASMJIT_INLINE Error dint64(int64_t x) { return static_cast<This*>(this)->embed(&x, sizeof(int64_t)); }
+     343             :   //! Add 64-bit integer data to the instruction stream.
+     344             :   ASMJIT_INLINE Error duint64(uint64_t x) { return static_cast<This*>(this)->embed(&x, sizeof(uint64_t)); }
+     345             : 
+     346             :   //! Add float data to the instruction stream.
+     347             :   ASMJIT_INLINE Error dfloat(float x) { return static_cast<This*>(this)->embed(&x, sizeof(float)); }
+     348             :   //! Add double data to the instruction stream.
+     349             :   ASMJIT_INLINE Error ddouble(double x) { return static_cast<This*>(this)->embed(&x, sizeof(double)); }
+     350             : 
+     351             :   //! Add MMX data to the instruction stream.
+     352             :   ASMJIT_INLINE Error dmm(const Data64& x) { return static_cast<This*>(this)->embed(&x, sizeof(Data64)); }
+     353             :   //! Add XMM data to the instruction stream.
+     354             :   ASMJIT_INLINE Error dxmm(const Data128& x) { return static_cast<This*>(this)->embed(&x, sizeof(Data128)); }
+     355             :   //! Add YMM data to the instruction stream.
+     356             :   ASMJIT_INLINE Error dymm(const Data256& x) { return static_cast<This*>(this)->embed(&x, sizeof(Data256)); }
+     357             : 
+     358             :   //! Add data in a given structure instance to the instruction stream.
+     359             :   template<typename T>
+     360             :   ASMJIT_INLINE Error dstruct(const T& x) { return static_cast<This*>(this)->embed(&x, static_cast<uint32_t>(sizeof(T))); }
+     361             : 
+     362             :   // --------------------------------------------------------------------------
+     363             :   // [Options]
+     364             :   // --------------------------------------------------------------------------
+     365             : 
+     366             : protected:
+     367             :   ASMJIT_INLINE This& _addOptions(uint32_t options) noexcept {
+     368             :     static_cast<This*>(this)->addOptions(options);
+     369             :     return *static_cast<This*>(this);
+     370             :   }
+     371             : 
+     372             : public:
+     373             :   //! Force short form of jmp/jcc instruction.
+     374             :   ASMJIT_INLINE This& short_() noexcept { return _addOptions(X86Inst::kOptionShortForm); }
+     375             :   //! Force long form of jmp/jcc instruction.
+     376             :   ASMJIT_INLINE This& long_() noexcept { return _addOptions(X86Inst::kOptionLongForm); }
+     377             : 
+     378             :   //! Condition is likely to be taken (has only benefit on P4).
+     379             :   ASMJIT_INLINE This& taken() noexcept { return _addOptions(X86Inst::kOptionTaken); }
+     380             :   //! Condition is unlikely to be taken (has only benefit on P4).
+     381             :   ASMJIT_INLINE This& notTaken() noexcept { return _addOptions(X86Inst::kOptionNotTaken); }
+     382             : 
+     383             :   //! Use LOCK prefix.
+     384             :   ASMJIT_INLINE This& lock() noexcept { return _addOptions(X86Inst::kOptionLock); }
+     385             :   //! Use XACQUIRE prefix.
+     386             :   ASMJIT_INLINE This& xacquire() noexcept { return _addOptions(X86Inst::kOptionXAcquire); }
+     387             :   //! Use XRELEASE prefix.
+     388             :   ASMJIT_INLINE This& xrelease() noexcept { return _addOptions(X86Inst::kOptionXRelease); }
+     389             : 
+     390             :   //! Use REP/REPZ prefix.
+     391             :   ASMJIT_INLINE This& rep(const X86Gp& zcx) noexcept {
+     392             :     static_cast<This*>(this)->_extraReg.init(zcx);
+     393             :     return _addOptions(X86Inst::kOptionRep);
+     394             :   }
+     395             :   //! Use REPNZ prefix.
+     396             :   ASMJIT_INLINE This& repnz(const X86Gp& zcx) noexcept {
+     397             :     static_cast<This*>(this)->_extraReg.init(zcx);
+     398             :     return _addOptions(X86Inst::kOptionRepnz);
+     399             :   }
+     400             : 
+     401             :   //! Use REP/REPZ prefix.
+     402             :   ASMJIT_INLINE This& repe(const X86Gp& zcx) noexcept { return rep(zcx); }
+     403             :   //! Use REP/REPZ prefix.
+     404             :   ASMJIT_INLINE This& repz(const X86Gp& zcx) noexcept { return rep(zcx); }
+     405             :   //! Use REPNZ prefix.
+     406             :   ASMJIT_INLINE This& repne(const X86Gp& zcx) noexcept { return repnz(zcx); }
+     407             : 
+     408             :   //! Prefer MOD_MR encoding over MOD_RM (the default) when encoding instruction
+     409             :   //! that allows both. This option is only applicable to legacy instructions
+     410             :   //! where both operands are registers.
+     411             :   ASMJIT_INLINE This& mod_mr() noexcept { return _addOptions(X86Inst::kOptionModMR); }
+     412             : 
+     413             :   //! Force REX prefix to be emitted even when it's not needed (X64).
+     414             :   //!
+     415             :   //! NOTE: Don't use when using high 8-bit registers as REX prefix makes them
+     416             :   //! inaccessible and \ref X86Assembler refuses to encode such instructions.
+     417             :   ASMJIT_INLINE This& rex() noexcept { return _addOptions(X86Inst::kOptionRex);}
+     418             : 
+     419             :   //! Force REX.B prefix (X64) [It exists for special purposes only].
+     420             :   ASMJIT_INLINE This& rex_b() noexcept { return _addOptions(X86Inst::kOptionOpCodeB); }
+     421             :   //! Force REX.X prefix (X64) [It exists for special purposes only].
+     422             :   ASMJIT_INLINE This& rex_x() noexcept { return _addOptions(X86Inst::kOptionOpCodeX); }
+     423             :   //! Force REX.R prefix (X64) [It exists for special purposes only].
+     424             :   ASMJIT_INLINE This& rex_r() noexcept { return _addOptions(X86Inst::kOptionOpCodeR); }
+     425             :   //! Force REX.W prefix (X64) [It exists for special purposes only].
+     426             :   ASMJIT_INLINE This& rex_w() noexcept { return _addOptions(X86Inst::kOptionOpCodeW); }
+     427             : 
+     428             :   //! Force 3-byte VEX prefix (AVX+).
+     429             :   ASMJIT_INLINE This& vex3() noexcept { return _addOptions(X86Inst::kOptionVex3); }
+     430             :   //! Force 4-byte EVEX prefix (AVX512+).
+     431             :   ASMJIT_INLINE This& evex() noexcept { return _addOptions(X86Inst::kOptionEvex); }
+     432             : 
+     433             :   //! Use masking {k} (AVX512+).
+     434             :   ASMJIT_INLINE This& k(const X86KReg& kreg) noexcept {
+     435             :     static_cast<This*>(this)->_extraReg.init(kreg);
+     436             :     return *static_cast<This*>(this);
+     437             :   }
+     438             : 
+     439             :   //! Use zeroing instead of merging (AVX512+).
+     440             :   ASMJIT_INLINE This& z() noexcept { return _addOptions(X86Inst::kOptionZMask); }
+     441             :   //! Broadcast one element to all other elements (AVX512+).
+     442             :   ASMJIT_INLINE This& _1tox() noexcept { return _addOptions(X86Inst::kOption1ToX); }
+     443             : 
+     444             :   //! Suppress all exceptions (AVX512+).
+     445             :   ASMJIT_INLINE This& sae() noexcept { return _addOptions(X86Inst::kOptionSAE); }
+     446             :   //! Static rounding mode {rn} (round-to-nearest even) and {sae} (AVX512+).
+     447             :   ASMJIT_INLINE This& rn_sae() noexcept { return _addOptions(X86Inst::kOptionER | X86Inst::kOptionRN_SAE); }
+     448             :   //! Static rounding mode {rd} (round-down, toward -inf) and {sae} (AVX512+).
+     449             :   ASMJIT_INLINE This& rd_sae() noexcept { return _addOptions(X86Inst::kOptionER | X86Inst::kOptionRD_SAE); }
+     450             :   //! Static rounding mode {ru} (round-up, toward +inf) and {sae} (AVX512+).
+     451             :   ASMJIT_INLINE This& ru_sae() noexcept { return _addOptions(X86Inst::kOptionER | X86Inst::kOptionRU_SAE); }
+     452             :   //! Static rounding mode {rz} (round-toward-zero, truncate) and {sae} (AVX512+).
+     453             :   ASMJIT_INLINE This& rz_sae() noexcept { return _addOptions(X86Inst::kOptionER | X86Inst::kOptionRZ_SAE); }
+     454             : 
+     455             :   // --------------------------------------------------------------------------
+     456             :   // [General Purpose and Non-SIMD Instructions]
+     457             :   // --------------------------------------------------------------------------
+     458             : 
+     459             :   ASMJIT_INST_2x(adc, Adc, X86Gp, X86Gp)                                      // ANY
+     460             :   ASMJIT_INST_2x(adc, Adc, X86Gp, X86Mem)                                     // ANY
+     461             :   ASMJIT_INST_2i(adc, Adc, X86Gp, Imm)                                        // ANY
+     462             :   ASMJIT_INST_2x(adc, Adc, X86Mem, X86Gp)                                     // ANY
+     463             :   ASMJIT_INST_2i(adc, Adc, X86Mem, Imm)                                       // ANY
+     464             :   ASMJIT_INST_2x(adcx, Adcx, X86Gp, X86Gp)                                    // ADX
+     465             :   ASMJIT_INST_2x(adcx, Adcx, X86Gp, X86Mem)                                   // ADX
+     466             :   ASMJIT_INST_2x(add, Add, X86Gp, X86Gp)                                      // ANY
+     467             :   ASMJIT_INST_2x(add, Add, X86Gp, X86Mem)                                     // ANY
+     468         932 :   ASMJIT_INST_2i(add, Add, X86Gp, Imm)                                        // ANY
+     469             :   ASMJIT_INST_2x(add, Add, X86Mem, X86Gp)                                     // ANY
+     470             :   ASMJIT_INST_2i(add, Add, X86Mem, Imm)                                       // ANY
+     471             :   ASMJIT_INST_2x(adox, Adox, X86Gp, X86Gp)                                    // ADX
+     472             :   ASMJIT_INST_2x(adox, Adox, X86Gp, X86Mem)                                   // ADX
+     473             :   ASMJIT_INST_2x(and_, And, X86Gp, X86Gp)                                     // ANY
+     474             :   ASMJIT_INST_2x(and_, And, X86Gp, X86Mem)                                    // ANY
+     475           0 :   ASMJIT_INST_2i(and_, And, X86Gp, Imm)                                       // ANY
+     476             :   ASMJIT_INST_2x(and_, And, X86Mem, X86Gp)                                    // ANY
+     477             :   ASMJIT_INST_2i(and_, And, X86Mem, Imm)                                      // ANY
+     478             :   ASMJIT_INST_3x(andn, Andn, X86Gp, X86Gp, X86Gp)                             // BMI
+     479             :   ASMJIT_INST_3x(andn, Andn, X86Gp, X86Gp, X86Mem)                            // BMI
+     480             :   ASMJIT_INST_2x(arpl, Arpl, X86Gp, X86Gp)                                    // X86
+     481             :   ASMJIT_INST_2x(arpl, Arpl, X86Mem, X86Gp)                                   // X86
+     482             :   ASMJIT_INST_3x(bextr, Bextr, X86Gp, X86Gp, X86Gp)                           // BMI
+     483             :   ASMJIT_INST_3x(bextr, Bextr, X86Gp, X86Mem, X86Gp)                          // BMI
+     484             :   ASMJIT_INST_2x(blcfill, Blcfill, X86Gp, X86Gp)                              // TBM
+     485             :   ASMJIT_INST_2x(blcfill, Blcfill, X86Gp, X86Mem)                             // TBM
+     486             :   ASMJIT_INST_2x(blci, Blci, X86Gp, X86Gp)                                    // TBM
+     487             :   ASMJIT_INST_2x(blci, Blci, X86Gp, X86Mem)                                   // TBM
+     488             :   ASMJIT_INST_2x(blcic, Blcic, X86Gp, X86Gp)                                  // TBM
+     489             :   ASMJIT_INST_2x(blcic, Blcic, X86Gp, X86Mem)                                 // TBM
+     490             :   ASMJIT_INST_2x(blcmsk, Blcmsk, X86Gp, X86Gp)                                // TBM
+     491             :   ASMJIT_INST_2x(blcmsk, Blcmsk, X86Gp, X86Mem)                               // TBM
+     492             :   ASMJIT_INST_2x(blcs, Blcs, X86Gp, X86Gp)                                    // TBM
+     493             :   ASMJIT_INST_2x(blcs, Blcs, X86Gp, X86Mem)                                   // TBM
+     494             :   ASMJIT_INST_2x(blsfill, Blsfill, X86Gp, X86Gp)                              // TBM
+     495             :   ASMJIT_INST_2x(blsfill, Blsfill, X86Gp, X86Mem)                             // TBM
+     496             :   ASMJIT_INST_2x(blsi, Blsi, X86Gp, X86Gp)                                    // BMI
+     497             :   ASMJIT_INST_2x(blsi, Blsi, X86Gp, X86Mem)                                   // BMI
+     498             :   ASMJIT_INST_2x(blsic, Blsic, X86Gp, X86Gp)                                  // TBM
+     499             :   ASMJIT_INST_2x(blsic, Blsic, X86Gp, X86Mem)                                 // TBM
+     500             :   ASMJIT_INST_2x(blsmsk, Blsmsk, X86Gp, X86Gp)                                // BMI
+     501             :   ASMJIT_INST_2x(blsmsk, Blsmsk, X86Gp, X86Mem)                               // BMI
+     502             :   ASMJIT_INST_2x(blsr, Blsr, X86Gp, X86Gp)                                    // BMI
+     503             :   ASMJIT_INST_2x(blsr, Blsr, X86Gp, X86Mem)                                   // BMI
+     504             :   ASMJIT_INST_2x(bndcl, Bndcl, X86Bnd, X86Gp)                                 // MPX
+     505             :   ASMJIT_INST_2x(bndcl, Bndcl, X86Bnd, X86Mem)                                // MPX
+     506             :   ASMJIT_INST_2x(bndcn, Bndcn, X86Bnd, X86Gp)                                 // MPX
+     507             :   ASMJIT_INST_2x(bndcn, Bndcn, X86Bnd, X86Mem)                                // MPX
+     508             :   ASMJIT_INST_2x(bndcu, Bndcu, X86Bnd, X86Gp)                                 // MPX
+     509             :   ASMJIT_INST_2x(bndcu, Bndcu, X86Bnd, X86Mem)                                // MPX
+     510             :   ASMJIT_INST_2x(bndldx, Bndldx, X86Bnd, X86Mem)                              // MPX
+     511             :   ASMJIT_INST_2x(bndmk, Bndmk, X86Bnd, X86Mem)                                // MPX
+     512             :   ASMJIT_INST_2x(bndmov, Bndmov, X86Bnd, X86Bnd)                              // MPX
+     513             :   ASMJIT_INST_2x(bndmov, Bndmov, X86Bnd, X86Mem)                              // MPX
+     514             :   ASMJIT_INST_2x(bndmov, Bndmov, X86Mem, X86Bnd)                              // MPX
+     515             :   ASMJIT_INST_2x(bndstx, Bndstx, X86Mem, X86Bnd)                              // MPX
+     516             :   ASMJIT_INST_2x(bound, Bound, X86Gp, X86Mem)                                 // X86
+     517             :   ASMJIT_INST_2x(bsf, Bsf, X86Gp, X86Gp)                                      // ANY
+     518             :   ASMJIT_INST_2x(bsf, Bsf, X86Gp, X86Mem)                                     // ANY
+     519             :   ASMJIT_INST_2x(bsr, Bsr, X86Gp, X86Gp)                                      // ANY
+     520             :   ASMJIT_INST_2x(bsr, Bsr, X86Gp, X86Mem)                                     // ANY
+     521             :   ASMJIT_INST_1x(bswap, Bswap, X86Gp)                                         // ANY
+     522             :   ASMJIT_INST_2x(bt, Bt, X86Gp, X86Gp)                                        // ANY
+     523             :   ASMJIT_INST_2i(bt, Bt, X86Gp, Imm)                                          // ANY
+     524             :   ASMJIT_INST_2x(bt, Bt, X86Mem, X86Gp)                                       // ANY
+     525             :   ASMJIT_INST_2i(bt, Bt, X86Mem, Imm)                                         // ANY
+     526             :   ASMJIT_INST_2x(btc, Btc, X86Gp, X86Gp)                                      // ANY
+     527             :   ASMJIT_INST_2i(btc, Btc, X86Gp, Imm)                                        // ANY
+     528             :   ASMJIT_INST_2x(btc, Btc, X86Mem, X86Gp)                                     // ANY
+     529             :   ASMJIT_INST_2i(btc, Btc, X86Mem, Imm)                                       // ANY
+     530             :   ASMJIT_INST_2x(btr, Btr, X86Gp, X86Gp)                                      // ANY
+     531             :   ASMJIT_INST_2i(btr, Btr, X86Gp, Imm)                                        // ANY
+     532             :   ASMJIT_INST_2x(btr, Btr, X86Mem, X86Gp)                                     // ANY
+     533             :   ASMJIT_INST_2i(btr, Btr, X86Mem, Imm)                                       // ANY
+     534             :   ASMJIT_INST_2x(bts, Bts, X86Gp, X86Gp)                                      // ANY
+     535             :   ASMJIT_INST_2i(bts, Bts, X86Gp, Imm)                                        // ANY
+     536             :   ASMJIT_INST_2x(bts, Bts, X86Mem, X86Gp)                                     // ANY
+     537             :   ASMJIT_INST_2i(bts, Bts, X86Mem, Imm)                                       // ANY
+     538             :   ASMJIT_INST_3x(bzhi, Bzhi, X86Gp, X86Gp, X86Gp)                             // BMI2
+     539             :   ASMJIT_INST_3x(bzhi, Bzhi, X86Gp, X86Mem, X86Gp)                            // BMI2
+     540             :   ASMJIT_INST_1x(cbw, Cbw, AX)                                                // ANY       [EXPLICIT] AX      <- Sign Extend AL
+     541             :   ASMJIT_INST_2x(cdq, Cdq, EDX, EAX)                                          // ANY       [EXPLICIT] EDX:EAX <- Sign Extend EAX
+     542             :   ASMJIT_INST_1x(cdqe, Cdqe, EAX)                                             // X64       [EXPLICIT] RAX     <- Sign Extend EAX
+     543             :   ASMJIT_INST_2x(cqo, Cqo, RDX, RAX)                                          // X64       [EXPLICIT] RDX:RAX <- Sign Extend RAX
+     544             :   ASMJIT_INST_2x(cwd, Cwd, DX, AX)                                            // ANY       [EXPLICIT] DX:AX   <- Sign Extend AX
+     545             :   ASMJIT_INST_1x(cwde, Cwde, EAX)                                             // ANY       [EXPLICIT] EAX     <- Sign Extend AX
+     546             :   ASMJIT_INST_1x(call, Call, X86Gp)                                           // ANY
+     547             :   ASMJIT_INST_1x(call, Call, X86Mem)                                          // ANY
+     548             :   ASMJIT_INST_1x(call, Call, Label)                                           // ANY
+     549             :   ASMJIT_INST_1i(call, Call, Imm)                                             // ANY
+     550             :   ASMJIT_INST_0x(clac, Clac)                                                  // SMAP
+     551             :   ASMJIT_INST_0x(clc, Clc)                                                    // ANY
+     552             :   ASMJIT_INST_0x(cld, Cld)                                                    // ANY
+     553             :   ASMJIT_INST_1x(clflush, Clflush, X86Mem)                                    // CLFLUSH
+     554             :   ASMJIT_INST_1x(clflushopt, Clflushopt, X86Mem)                              // CLFLUSH_OPT
+     555             :   ASMJIT_INST_0x(cli, Cli)                                                    // ANY
+     556             :   ASMJIT_INST_0x(clts, Clts)                                                  // ANY
+     557             :   ASMJIT_INST_1x(clwb, Clwb, X86Mem)                                          // CLWB
+     558             :   ASMJIT_INST_1x(clzero, Clzero, DS_ZAX)                                      // CLZERO    [EXPLICIT]
+     559             :   ASMJIT_INST_0x(cmc, Cmc)                                                    // ANY
+     560             :   ASMJIT_INST_2c(cmov, Cmov, X86Inst::condToCmovcc, X86Gp, X86Gp)             // CMOV
+     561             :   ASMJIT_INST_2c(cmov, Cmov, X86Inst::condToCmovcc, X86Gp, X86Mem)            // CMOV
+     562             :   ASMJIT_INST_2x(cmp, Cmp, X86Gp, X86Gp)                                      // ANY
+     563             :   ASMJIT_INST_2x(cmp, Cmp, X86Gp, X86Mem)                                     // ANY
+     564             :   ASMJIT_INST_2i(cmp, Cmp, X86Gp, Imm)                                        // ANY
+     565             :   ASMJIT_INST_2x(cmp, Cmp, X86Mem, X86Gp)                                     // ANY
+     566             :   ASMJIT_INST_2i(cmp, Cmp, X86Mem, Imm)                                       // ANY
+     567             :   ASMJIT_INST_2x(cmps, Cmps, DS_ZSI, ES_ZDI)                                  // ANY       [EXPLICIT]
+     568             :   ASMJIT_INST_3x(cmpxchg, Cmpxchg, X86Gp, X86Gp, ZAX)                         // I486      [EXPLICIT]
+     569             :   ASMJIT_INST_3x(cmpxchg, Cmpxchg, X86Mem, X86Gp, ZAX)                        // I486      [EXPLICIT]
+     570             :   ASMJIT_INST_5x(cmpxchg16b, Cmpxchg16b, X86Mem, RDX, RAX, RCX, RBX);         // CMPXCHG16B[EXPLICIT] m == EDX:EAX ? m <- ECX:EBX
+     571             :   ASMJIT_INST_5x(cmpxchg8b, Cmpxchg8b, X86Mem, EDX, EAX, ECX, EBX);           // CMPXCHG8B [EXPLICIT] m == RDX:RAX ? m <- RCX:RBX
+     572             :   ASMJIT_INST_4x(cpuid, Cpuid, EAX, EBX, ECX, EDX)                            // I486      [EXPLICIT] EAX:EBX:ECX:EDX  <- CPUID[EAX:ECX]
+     573             :   ASMJIT_INST_2x(crc32, Crc32, X86Gp, X86Gp)                                  // SSE4_2
+     574             :   ASMJIT_INST_2x(crc32, Crc32, X86Gp, X86Mem)                                 // SSE4_2
+     575             :   ASMJIT_INST_1x(daa, Daa, X86Gp)                                             // X86       [EXPLICIT]
+     576             :   ASMJIT_INST_1x(das, Das, X86Gp)                                             // X86       [EXPLICIT]
+     577             :   ASMJIT_INST_1x(dec, Dec, X86Gp)                                             // ANY
+     578             :   ASMJIT_INST_1x(dec, Dec, X86Mem)                                            // ANY
+     579             :   ASMJIT_INST_2x(div, Div, X86Gp, X86Gp)                                      // ANY       [EXPLICIT]  AH[Rem]: AL[Quot] <- AX / r8
+     580             :   ASMJIT_INST_2x(div, Div, X86Gp, X86Mem)                                     // ANY       [EXPLICIT]  AH[Rem]: AL[Quot] <- AX / m8
+     581             :   ASMJIT_INST_3x(div, Div, X86Gp, X86Gp, X86Gp)                               // ANY       [EXPLICIT] xDX[Rem]:xAX[Quot] <- xDX:xAX / r16|r32|r64
+     582             :   ASMJIT_INST_3x(div, Div, X86Gp, X86Gp, X86Mem)                              // ANY       [EXPLICIT] xDX[Rem]:xAX[Quot] <- xDX:xAX / m16|m32|m64
+     583           0 :   ASMJIT_INST_0x(emms, Emms)                                                  // MMX
+     584             :   ASMJIT_INST_2x(enter, Enter, Imm, Imm)                                      // ANY
+     585             :   ASMJIT_INST_1x(fxrstor, Fxrstor, X86Mem)                                    // FXSR
+     586             :   ASMJIT_INST_1x(fxrstor64, Fxrstor64, X86Mem)                                // FXSR
+     587             :   ASMJIT_INST_1x(fxsave, Fxsave, X86Mem)                                      // FXSR
+     588             :   ASMJIT_INST_1x(fxsave64, Fxsave64, X86Mem)                                  // FXSR
+     589             :   ASMJIT_INST_0x(hlt, Hlt)                                                    // ANY
+     590             :   ASMJIT_INST_2x(idiv, Idiv, X86Gp, X86Gp)                                    // ANY       [EXPLICIT]  AH[Rem]: AL[Quot] <- AX / r8
+     591             :   ASMJIT_INST_2x(idiv, Idiv, X86Gp, X86Mem)                                   // ANY       [EXPLICIT]  AH[Rem]: AL[Quot] <- AX / m8
+     592             :   ASMJIT_INST_3x(idiv, Idiv, X86Gp, X86Gp, X86Gp)                             // ANY       [EXPLICIT] xDX[Rem]:xAX[Quot] <- xDX:xAX / r16|r32|r64
+     593             :   ASMJIT_INST_3x(idiv, Idiv, X86Gp, X86Gp, X86Mem)                            // ANY       [EXPLICIT] xDX[Rem]:xAX[Quot] <- xDX:xAX / m16|m32|m64
+     594             :   ASMJIT_INST_2x(imul, Imul, X86Gp, X86Gp)                                    // ANY       [EXPLICIT] AX <- AL * r8 | ra <- ra * rb
+     595             :   ASMJIT_INST_2x(imul, Imul, X86Gp, X86Mem)                                   // ANY       [EXPLICIT] AX <- AL * m8 | ra <- ra * m16|m32|m64
+     596             :   ASMJIT_INST_2i(imul, Imul, X86Gp, Imm)                                      // ANY
+     597             :   ASMJIT_INST_3i(imul, Imul, X86Gp, X86Gp, Imm)                               // ANY
+     598             :   ASMJIT_INST_3i(imul, Imul, X86Gp, X86Mem, Imm)                              // ANY
+     599             :   ASMJIT_INST_3x(imul, Imul, X86Gp, X86Gp, X86Gp)                             // ANY       [EXPLICIT] xDX:xAX <- xAX * r16|r32|r64
+     600             :   ASMJIT_INST_3x(imul, Imul, X86Gp, X86Gp, X86Mem)                            // ANY       [EXPLICIT] xDX:xAX <- xAX * m16|m32|m64
+     601             :   ASMJIT_INST_2i(in, In, ZAX, Imm)                                            // ANY
+     602             :   ASMJIT_INST_2x(in, In, ZAX, DX)                                             // ANY
+     603             :   ASMJIT_INST_1x(inc, Inc, X86Gp)                                             // ANY
+     604             :   ASMJIT_INST_1x(inc, Inc, X86Mem)                                            // ANY
+     605             :   ASMJIT_INST_2x(ins, Ins, ES_ZDI, DX)                                        // ANY
+     606             :   ASMJIT_INST_1i(int_, Int, Imm)                                              // ANY
+     607             :   ASMJIT_INST_0x(int3, Int3)                                                  // ANY
+     608             :   ASMJIT_INST_0x(into, Into)                                                  // ANY
+     609             :   ASMJIT_INST_0x(invd, Invd)                                                  // ANY
+     610             :   ASMJIT_INST_1x(invlpg, Invlpg, X86Mem)                                      // ANY
+     611             :   ASMJIT_INST_2x(invpcid, Invpcid, X86Gp, X86Mem)                             // ANY
+     612             :   ASMJIT_INST_1c(j, J, X86Inst::condToJcc, Label)                             // ANY
+     613             :   ASMJIT_INST_1c(j, J, X86Inst::condToJcc, Imm)                               // ANY
+     614             :   ASMJIT_INST_1c(j, J, X86Inst::condToJcc, uint64_t)                          // ANY
+     615             :   ASMJIT_INST_2x(jecxz, Jecxz, X86Gp, Label)                                  // ANY       [EXPLICIT] Short jump if CX/ECX/RCX is zero.
+     616             :   ASMJIT_INST_2x(jecxz, Jecxz, X86Gp, Imm)                                    // ANY       [EXPLICIT] Short jump if CX/ECX/RCX is zero.
+     617             :   ASMJIT_INST_2x(jecxz, Jecxz, X86Gp, uint64_t)                               // ANY       [EXPLICIT] Short jump if CX/ECX/RCX is zero.
+     618             :   ASMJIT_INST_1x(jmp, Jmp, X86Gp)                                             // ANY
+     619             :   ASMJIT_INST_1x(jmp, Jmp, X86Mem)                                            // ANY
+     620           0 :   ASMJIT_INST_1x(jmp, Jmp, Label)                                             // ANY
+     621             :   ASMJIT_INST_1x(jmp, Jmp, Imm)                                               // ANY
+     622             :   ASMJIT_INST_1x(jmp, Jmp, uint64_t)                                          // ANY
+     623             :   ASMJIT_INST_1x(lahf, Lahf, AH)                                              // LAHFSAHF  [EXPLICIT] AH <- EFL
+     624             :   ASMJIT_INST_2x(lar, Lar, X86Gp, X86Gp)                                      // ANY
+     625             :   ASMJIT_INST_2x(lar, Lar, X86Gp, X86Mem)                                     // ANY
+     626             :   ASMJIT_INST_1x(ldmxcsr, Ldmxcsr, X86Mem)                                    // SSE
+     627             :   ASMJIT_INST_2x(lds, Lds, X86Gp, X86Mem)                                     // X86
+     628           0 :   ASMJIT_INST_2x(lea, Lea, X86Gp, X86Mem)                                     // ANY
+     629             :   ASMJIT_INST_0x(leave, Leave)                                                // ANY
+     630             :   ASMJIT_INST_2x(les, Les, X86Gp, X86Mem)                                     // X86
+     631             :   ASMJIT_INST_0x(lfence, Lfence)                                              // SSE2
+     632             :   ASMJIT_INST_2x(lfs, Lfs, X86Gp, X86Mem)                                     // ANY
+     633             :   ASMJIT_INST_1x(lgdt, Lgdt, X86Mem)                                          // ANY
+     634             :   ASMJIT_INST_2x(lgs, Lgs, X86Gp, X86Mem)                                     // ANY
+     635             :   ASMJIT_INST_1x(lidt, Lidt, X86Mem)                                          // ANY
+     636             :   ASMJIT_INST_1x(lldt, Lldt, X86Gp)                                           // ANY
+     637             :   ASMJIT_INST_1x(lldt, Lldt, X86Mem)                                          // ANY
+     638             :   ASMJIT_INST_1x(lmsw, Lmsw, X86Gp)                                           // ANY
+     639             :   ASMJIT_INST_1x(lmsw, Lmsw, X86Mem)                                          // ANY
+     640             :   ASMJIT_INST_2x(lods, Lods, ZAX, DS_ZSI)                                     // ANY       [EXPLICIT]
+     641             :   ASMJIT_INST_2x(loop, Loop, ZCX, Label)                                      // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0.
+     642             :   ASMJIT_INST_2x(loop, Loop, ZCX, Imm)                                        // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0.
+     643             :   ASMJIT_INST_2x(loop, Loop, ZCX, uint64_t)                                   // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0.
+     644             :   ASMJIT_INST_2x(loope, Loope, ZCX, Label)                                    // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+     645             :   ASMJIT_INST_2x(loope, Loope, ZCX, Imm)                                      // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+     646             :   ASMJIT_INST_2x(loope, Loope, ZCX, uint64_t)                                 // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+     647             :   ASMJIT_INST_2x(loopne, Loopne, ZCX, Label)                                  // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+     648             :   ASMJIT_INST_2x(loopne, Loopne, ZCX, Imm)                                    // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+     649             :   ASMJIT_INST_2x(loopne, Loopne, ZCX, uint64_t)                               // ANY       [EXPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+     650             :   ASMJIT_INST_2x(lsl, Lsl, X86Gp, X86Gp)                                      // ANY
+     651             :   ASMJIT_INST_2x(lsl, Lsl, X86Gp, X86Mem)                                     // ANY
+     652             :   ASMJIT_INST_2x(lss, Lss, X86Gp, X86Mem)                                     // ANY
+     653             :   ASMJIT_INST_1x(ltr, Ltr, X86Gp)                                             // ANY
+     654             :   ASMJIT_INST_1x(ltr, Ltr, X86Mem)                                            // ANY
+     655             :   ASMJIT_INST_2x(lzcnt, Lzcnt, X86Gp, X86Gp)                                  // LZCNT
+     656             :   ASMJIT_INST_2x(lzcnt, Lzcnt, X86Gp, X86Mem)                                 // LZCNT
+     657             :   ASMJIT_INST_0x(mfence, Mfence)                                              // SSE2
+     658           0 :   ASMJIT_INST_2x(mov, Mov, X86Gp, X86Gp)                                      // ANY
+     659           0 :   ASMJIT_INST_2x(mov, Mov, X86Gp, X86Mem)                                     // ANY
+     660        7268 :   ASMJIT_INST_2i(mov, Mov, X86Gp, Imm)                                        // ANY
+     661           0 :   ASMJIT_INST_2x(mov, Mov, X86Mem, X86Gp)                                     // ANY
+     662             :   ASMJIT_INST_2i(mov, Mov, X86Mem, Imm)                                       // ANY
+     663             :   ASMJIT_INST_2x(mov, Mov, X86Gp, X86CReg)                                    // ANY
+     664             :   ASMJIT_INST_2x(mov, Mov, X86CReg, X86Gp)                                    // ANY
+     665             :   ASMJIT_INST_2x(mov, Mov, X86Gp, X86DReg)                                    // ANY
+     666             :   ASMJIT_INST_2x(mov, Mov, X86DReg, X86Gp)                                    // ANY
+     667             :   ASMJIT_INST_2x(mov, Mov, X86Gp, X86Seg)                                     // ANY
+     668             :   ASMJIT_INST_2x(mov, Mov, X86Mem, X86Seg)                                    // ANY
+     669             :   ASMJIT_INST_2x(mov, Mov, X86Seg, X86Gp)                                     // ANY
+     670             :   ASMJIT_INST_2x(mov, Mov, X86Seg, X86Mem)                                    // ANY
+     671             :   ASMJIT_INST_2x(movbe, Movbe, X86Gp, X86Mem)                                 // MOVBE
+     672             :   ASMJIT_INST_2x(movbe, Movbe, X86Mem, X86Gp)                                 // MOVBE
+     673             :   ASMJIT_INST_2x(movnti, Movnti, X86Mem, X86Gp)                               // SSE2
+     674             :   ASMJIT_INST_2x(movs, Movs, ES_ZDI, DS_ZSI)                                  // ANY       [EXPLICIT]
+     675             :   ASMJIT_INST_2x(movsx, Movsx, X86Gp, X86Gp)                                  // ANY
+     676             :   ASMJIT_INST_2x(movsx, Movsx, X86Gp, X86Mem)                                 // ANY
+     677             :   ASMJIT_INST_2x(movsxd, Movsxd, X86Gp, X86Gp)                                // X64
+     678             :   ASMJIT_INST_2x(movsxd, Movsxd, X86Gp, X86Mem)                               // X64
+     679             :   ASMJIT_INST_2x(movzx, Movzx, X86Gp, X86Gp)                                  // ANY
+     680             :   ASMJIT_INST_2x(movzx, Movzx, X86Gp, X86Mem)                                 // ANY
+     681             :   ASMJIT_INST_2x(mul, Mul, AX, X86Gp)                                         // ANY       [EXPLICIT] AX      <-  AL * r8
+     682             :   ASMJIT_INST_2x(mul, Mul, AX, X86Mem)                                        // ANY       [EXPLICIT] AX      <-  AL * m8
+     683             :   ASMJIT_INST_3x(mul, Mul, ZDX, ZAX, X86Gp)                                   // ANY       [EXPLICIT] xDX:xAX <- xAX * r16|r32|r64
+     684             :   ASMJIT_INST_3x(mul, Mul, ZDX, ZAX, X86Mem)                                  // ANY       [EXPLICIT] xDX:xAX <- xAX * m16|m32|m64
+     685             :   ASMJIT_INST_4x(mulx, Mulx, X86Gp, X86Gp, X86Gp, ZDX)                        // BMI2      [EXPLICIT]
+     686             :   ASMJIT_INST_4x(mulx, Mulx, X86Gp, X86Gp, X86Mem, ZDX)                       // BMI2      [EXPLICIT]
+     687             :   ASMJIT_INST_1x(neg, Neg, X86Gp)                                             // ANY
+     688             :   ASMJIT_INST_1x(neg, Neg, X86Mem)                                            // ANY
+     689             :   ASMJIT_INST_0x(nop, Nop)                                                    // ANY
+     690             :   ASMJIT_INST_1x(not_, Not, X86Gp)                                            // ANY
+     691             :   ASMJIT_INST_1x(not_, Not, X86Mem)                                           // ANY
+     692             :   ASMJIT_INST_2x(or_, Or, X86Gp, X86Gp)                                       // ANY
+     693             :   ASMJIT_INST_2x(or_, Or, X86Gp, X86Mem)                                      // ANY
+     694             :   ASMJIT_INST_2i(or_, Or, X86Gp, Imm)                                         // ANY
+     695             :   ASMJIT_INST_2x(or_, Or, X86Mem, X86Gp)                                      // ANY
+     696             :   ASMJIT_INST_2i(or_, Or, X86Mem, Imm)                                        // ANY
+     697             :   ASMJIT_INST_2x(out, Out, Imm, ZAX)                                          // ANY
+     698             :   ASMJIT_INST_2i(out, Out, DX, ZAX)                                           // ANY
+     699             :   ASMJIT_INST_2i(outs, Outs, DX, DS_ZSI)                                      // ANY
+     700             :   ASMJIT_INST_0x(pause, Pause)                                                // SSE2
+     701             :   ASMJIT_INST_3x(pdep, Pdep, X86Gp, X86Gp, X86Gp)                             // BMI2
+     702             :   ASMJIT_INST_3x(pdep, Pdep, X86Gp, X86Gp, X86Mem)                            // BMI2
+     703             :   ASMJIT_INST_3x(pext, Pext, X86Gp, X86Gp, X86Gp)                             // BMI2
+     704             :   ASMJIT_INST_3x(pext, Pext, X86Gp, X86Gp, X86Mem)                            // BMI2
+     705             :   ASMJIT_INST_0x(pcommit, Pcommit)                                            // PCOMMIT
+     706        1120 :   ASMJIT_INST_1x(pop, Pop, X86Gp)                                             // ANY
+     707             :   ASMJIT_INST_1x(pop, Pop, X86Mem)                                            // ANY
+     708             :   ASMJIT_INST_1x(pop, Pop, X86Seg);                                           // ANY
+     709             :   ASMJIT_INST_0x(popa, Popa)                                                  // X86
+     710             :   ASMJIT_INST_0x(popad, Popad)                                                // X86
+     711             :   ASMJIT_INST_2x(popcnt, Popcnt, X86Gp, X86Gp)                                // POPCNT
+     712             :   ASMJIT_INST_2x(popcnt, Popcnt, X86Gp, X86Mem)                               // POPCNT
+     713             :   ASMJIT_INST_0x(popf, Popf)                                                  // ANY
+     714             :   ASMJIT_INST_0x(popfd, Popfd)                                                // X86
+     715             :   ASMJIT_INST_0x(popfq, Popfq)                                                // X64
+     716             :   ASMJIT_INST_1x(prefetch, Prefetch, X86Mem)                                  // 3DNOW
+     717             :   ASMJIT_INST_1x(prefetchnta, Prefetchnta, X86Mem)                            // SSE
+     718             :   ASMJIT_INST_1x(prefetcht0, Prefetcht0, X86Mem)                              // SSE
+     719             :   ASMJIT_INST_1x(prefetcht1, Prefetcht1, X86Mem)                              // SSE
+     720             :   ASMJIT_INST_1x(prefetcht2, Prefetcht2, X86Mem)                              // SSE
+     721             :   ASMJIT_INST_1x(prefetchw, Prefetchw, X86Mem)                                // PREFETCHW
+     722             :   ASMJIT_INST_1x(prefetchwt1, Prefetchwt1, X86Mem)                            // PREFETCHW1
+     723        1120 :   ASMJIT_INST_1x(push, Push, X86Gp)                                           // ANY
+     724             :   ASMJIT_INST_1x(push, Push, X86Mem)                                          // ANY
+     725             :   ASMJIT_INST_1x(push, Push, X86Seg)                                          // ANY
+     726             :   ASMJIT_INST_1i(push, Push, Imm)                                             // ANY
+     727             :   ASMJIT_INST_0x(pusha, Pusha)                                                // X86
+     728             :   ASMJIT_INST_0x(pushad, Pushad)                                              // X86
+     729             :   ASMJIT_INST_0x(pushf, Pushf)                                                // ANY
+     730             :   ASMJIT_INST_0x(pushfd, Pushfd)                                              // X86
+     731             :   ASMJIT_INST_0x(pushfq, Pushfq)                                              // X64
+     732             :   ASMJIT_INST_2x(rcl, Rcl, X86Gp, CL)                                         // ANY
+     733             :   ASMJIT_INST_2x(rcl, Rcl, X86Mem, CL)                                        // ANY
+     734             :   ASMJIT_INST_2i(rcl, Rcl, X86Gp, Imm)                                        // ANY
+     735             :   ASMJIT_INST_2i(rcl, Rcl, X86Mem, Imm)                                       // ANY
+     736             :   ASMJIT_INST_2x(rcr, Rcr, X86Gp, CL)                                         // ANY
+     737             :   ASMJIT_INST_2x(rcr, Rcr, X86Mem, CL)                                        // ANY
+     738             :   ASMJIT_INST_2i(rcr, Rcr, X86Gp, Imm)                                        // ANY
+     739             :   ASMJIT_INST_2i(rcr, Rcr, X86Mem, Imm)                                       // ANY
+     740             :   ASMJIT_INST_1x(rdfsbase, Rdfsbase, X86Gp)                                   // FSGSBASE
+     741             :   ASMJIT_INST_1x(rdgsbase, Rdgsbase, X86Gp)                                   // FSGSBASE
+     742             :   ASMJIT_INST_1x(rdrand, Rdrand, X86Gp)                                       // RDRAND
+     743             :   ASMJIT_INST_1x(rdseed, Rdseed, X86Gp)                                       // RDSEED
+     744             :   ASMJIT_INST_3x(rdmsr, Rdmsr, EDX, EAX, ECX)                                 // MSR       [EXPLICIT] RDX:EAX     <- MSR[ECX]
+     745             :   ASMJIT_INST_3x(rdpmc, Rdpmc, EDX, EAX, ECX)                                 // ANY       [EXPLICIT] RDX:EAX     <- PMC[ECX]
+     746             :   ASMJIT_INST_2x(rdtsc, Rdtsc, EDX, EAX)                                      // RDTSC     [EXPLICIT] EDX:EAX     <- Counter
+     747             :   ASMJIT_INST_3x(rdtscp, Rdtscp, EDX, EAX, ECX)                               // RDTSCP    [EXPLICIT] EDX:EAX:EXC <- Counter
+     748             :   ASMJIT_INST_2x(rol, Rol, X86Gp, CL)                                         // ANY
+     749             :   ASMJIT_INST_2x(rol, Rol, X86Mem, CL)                                        // ANY
+     750             :   ASMJIT_INST_2i(rol, Rol, X86Gp, Imm)                                        // ANY
+     751             :   ASMJIT_INST_2i(rol, Rol, X86Mem, Imm)                                       // ANY
+     752             :   ASMJIT_INST_2x(ror, Ror, X86Gp, CL)                                         // ANY
+     753             :   ASMJIT_INST_2x(ror, Ror, X86Mem, CL)                                        // ANY
+     754             :   ASMJIT_INST_2i(ror, Ror, X86Gp, Imm)                                        // ANY
+     755             :   ASMJIT_INST_2i(ror, Ror, X86Mem, Imm)                                       // ANY
+     756             :   ASMJIT_INST_3i(rorx, Rorx, X86Gp, X86Gp, Imm)                               // BMI2
+     757             :   ASMJIT_INST_3i(rorx, Rorx, X86Gp, X86Mem, Imm)                              // BMI2
+     758             :   ASMJIT_INST_0x(rsm, Rsm)                                                    // X86
+     759             :   ASMJIT_INST_2x(sbb, Sbb, X86Gp, X86Gp)                                      // ANY
+     760             :   ASMJIT_INST_2x(sbb, Sbb, X86Gp, X86Mem)                                     // ANY
+     761             :   ASMJIT_INST_2i(sbb, Sbb, X86Gp, Imm)                                        // ANY
+     762             :   ASMJIT_INST_2x(sbb, Sbb, X86Mem, X86Gp)                                     // ANY
+     763             :   ASMJIT_INST_2i(sbb, Sbb, X86Mem, Imm)                                       // ANY
+     764             :   ASMJIT_INST_1x(sahf, Sahf, AH)                                              // LAHFSAHF  [EXPLICIT] EFL <- AH
+     765             :   ASMJIT_INST_2x(sal, Sal, X86Gp, CL)                                         // ANY
+     766             :   ASMJIT_INST_2x(sal, Sal, X86Mem, CL)                                        // ANY
+     767             :   ASMJIT_INST_2i(sal, Sal, X86Gp, Imm)                                        // ANY
+     768             :   ASMJIT_INST_2i(sal, Sal, X86Mem, Imm)                                       // ANY
+     769             :   ASMJIT_INST_2x(sar, Sar, X86Gp, CL)                                         // ANY
+     770             :   ASMJIT_INST_2x(sar, Sar, X86Mem, CL)                                        // ANY
+     771             :   ASMJIT_INST_2i(sar, Sar, X86Gp, Imm)                                        // ANY
+     772             :   ASMJIT_INST_2i(sar, Sar, X86Mem, Imm)                                       // ANY
+     773             :   ASMJIT_INST_3x(sarx, Sarx, X86Gp, X86Gp, X86Gp)                             // BMI2
+     774             :   ASMJIT_INST_3x(sarx, Sarx, X86Gp, X86Mem, X86Gp)                            // BMI2
+     775             :   ASMJIT_INST_2x(scas, Scas, ZAX, ES_ZDI)                                     // ANY       [EXPLICIT]
+     776             :   ASMJIT_INST_1c(set, Set, X86Inst::condToSetcc, X86Gp)                       // ANY
+     777             :   ASMJIT_INST_1c(set, Set, X86Inst::condToSetcc, X86Mem)                      // ANY
+     778             :   ASMJIT_INST_0x(sfence, Sfence)                                              // SSE
+     779             :   ASMJIT_INST_1x(sgdt, Sgdt, X86Mem)                                          // ANY
+     780             :   ASMJIT_INST_2x(shl, Shl, X86Gp, CL)                                         // ANY
+     781             :   ASMJIT_INST_2x(shl, Shl, X86Mem, CL)                                        // ANY
+     782             :   ASMJIT_INST_2i(shl, Shl, X86Gp, Imm)                                        // ANY
+     783             :   ASMJIT_INST_2i(shl, Shl, X86Mem, Imm)                                       // ANY
+     784             :   ASMJIT_INST_3x(shlx, Shlx, X86Gp, X86Gp, X86Gp)                             // BMI2
+     785             :   ASMJIT_INST_3x(shlx, Shlx, X86Gp, X86Mem, X86Gp)                            // BMI2
+     786             :   ASMJIT_INST_2x(shr, Shr, X86Gp, CL)                                         // ANY
+     787             :   ASMJIT_INST_2x(shr, Shr, X86Mem, CL)                                        // ANY
+     788             :   ASMJIT_INST_2i(shr, Shr, X86Gp, Imm)                                        // ANY
+     789             :   ASMJIT_INST_2i(shr, Shr, X86Mem, Imm)                                       // ANY
+     790             :   ASMJIT_INST_3x(shrx, Shrx, X86Gp, X86Gp, X86Gp)                             // BMI2
+     791             :   ASMJIT_INST_3x(shrx, Shrx, X86Gp, X86Mem, X86Gp)                            // BMI2
+     792             :   ASMJIT_INST_3x(shld, Shld, X86Gp, X86Gp, CL)                                // ANY
+     793             :   ASMJIT_INST_3x(shld, Shld, X86Mem, X86Gp, CL)                               // ANY
+     794             :   ASMJIT_INST_3i(shld, Shld, X86Gp, X86Gp, Imm)                               // ANY
+     795             :   ASMJIT_INST_3i(shld, Shld, X86Mem, X86Gp, Imm)                              // ANY
+     796             :   ASMJIT_INST_3x(shrd, Shrd, X86Gp, X86Gp, CL)                                // ANY
+     797             :   ASMJIT_INST_3x(shrd, Shrd, X86Mem, X86Gp, CL)                               // ANY
+     798             :   ASMJIT_INST_3i(shrd, Shrd, X86Gp, X86Gp, Imm)                               // ANY
+     799             :   ASMJIT_INST_3i(shrd, Shrd, X86Mem, X86Gp, Imm)                              // ANY
+     800             :   ASMJIT_INST_1x(sidt, Sidt, X86Mem)                                          // ANY
+     801             :   ASMJIT_INST_1x(sldt, Sldt, X86Gp)                                           // ANY
+     802             :   ASMJIT_INST_1x(sldt, Sldt, X86Mem)                                          // ANY
+     803             :   ASMJIT_INST_1x(smsw, Smsw, X86Gp)                                           // ANY
+     804             :   ASMJIT_INST_1x(smsw, Smsw, X86Mem)                                          // ANY
+     805             :   ASMJIT_INST_0x(stac, Stac)                                                  // SMAP
+     806             :   ASMJIT_INST_0x(stc, Stc)                                                    // ANY
+     807             :   ASMJIT_INST_0x(std, Std)                                                    // ANY
+     808             :   ASMJIT_INST_0x(sti, Sti)                                                    // ANY
+     809             :   ASMJIT_INST_1x(stmxcsr, Stmxcsr, X86Mem)                                    // SSE
+     810             :   ASMJIT_INST_2x(stos, Stos, ES_ZDI, ZAX)                                     // ANY       [EXPLICIT]
+     811             :   ASMJIT_INST_1x(str, Str, X86Gp)                                             // ANY
+     812             :   ASMJIT_INST_1x(str, Str, X86Mem)                                            // ANY
+     813             :   ASMJIT_INST_2x(sub, Sub, X86Gp, X86Gp)                                      // ANY
+     814             :   ASMJIT_INST_2x(sub, Sub, X86Gp, X86Mem)                                     // ANY
+     815         932 :   ASMJIT_INST_2i(sub, Sub, X86Gp, Imm)                                        // ANY
+     816             :   ASMJIT_INST_2x(sub, Sub, X86Mem, X86Gp)                                     // ANY
+     817             :   ASMJIT_INST_2i(sub, Sub, X86Mem, Imm)                                       // ANY
+     818             :   ASMJIT_INST_0x(swapgs, Swapgs)                                              // X64
+     819             :   ASMJIT_INST_2x(t1mskc, T1mskc, X86Gp, X86Gp)                                // TBM
+     820             :   ASMJIT_INST_2x(t1mskc, T1mskc, X86Gp, X86Mem)                               // TBM
+     821             :   ASMJIT_INST_2x(test, Test, X86Gp, X86Gp)                                    // ANY
+     822             :   ASMJIT_INST_2i(test, Test, X86Gp, Imm)                                      // ANY
+     823             :   ASMJIT_INST_2x(test, Test, X86Mem, X86Gp)                                   // ANY
+     824             :   ASMJIT_INST_2i(test, Test, X86Mem, Imm)                                     // ANY
+     825             :   ASMJIT_INST_2x(tzcnt, Tzcnt, X86Gp, X86Gp)                                  // BMI
+     826             :   ASMJIT_INST_2x(tzcnt, Tzcnt, X86Gp, X86Mem)                                 // BMI
+     827             :   ASMJIT_INST_2x(tzmsk, Tzmsk, X86Gp, X86Gp)                                  // TBM
+     828             :   ASMJIT_INST_2x(tzmsk, Tzmsk, X86Gp, X86Mem)                                 // TBM
+     829             :   ASMJIT_INST_0x(ud2, Ud2)                                                    // ANY
+     830             :   ASMJIT_INST_1x(verr, Verr, X86Gp)                                           // ANY
+     831             :   ASMJIT_INST_1x(verr, Verr, X86Mem)                                          // ANY
+     832             :   ASMJIT_INST_1x(verw, Verw, X86Gp)                                           // ANY
+     833             :   ASMJIT_INST_1x(verw, Verw, X86Mem)                                          // ANY
+     834             :   ASMJIT_INST_1x(wrfsbase, Wrfsbase, X86Gp)                                   // FSGSBASE
+     835             :   ASMJIT_INST_1x(wrgsbase, Wrgsbase, X86Gp)                                   // FSGSBASE
+     836             :   ASMJIT_INST_3x(wrmsr, Wrmsr, EDX, EAX, ECX)                                 // MSR       [EXPLICIT] RDX:EAX     -> MSR[ECX]
+     837             :   ASMJIT_INST_0x(xabort, Xabort)                                              // RTM
+     838             :   ASMJIT_INST_2x(xadd, Xadd, X86Gp, X86Gp)                                    // ANY
+     839             :   ASMJIT_INST_2x(xadd, Xadd, X86Mem, X86Gp)                                   // ANY
+     840             :   ASMJIT_INST_1x(xbegin, Xbegin, Label)                                       // RTM
+     841             :   ASMJIT_INST_1x(xbegin, Xbegin, Imm)                                         // RTM
+     842             :   ASMJIT_INST_1x(xbegin, Xbegin, uint64_t)                                    // RTM
+     843             :   ASMJIT_INST_2x(xchg, Xchg, X86Gp, X86Gp)                                    // ANY
+     844             :   ASMJIT_INST_2x(xchg, Xchg, X86Mem, X86Gp)                                   // ANY
+     845             :   ASMJIT_INST_2x(xchg, Xchg, X86Gp, X86Mem)                                   // ANY
+     846             :   ASMJIT_INST_0x(xend, Xend)                                                  // RTM
+     847             :   ASMJIT_INST_3x(xgetbv, Xgetbv, EDX, EAX, ECX)                               // XSAVE     [EXPLICIT] EDX:EAX <- XCR[ECX]
+     848             :   ASMJIT_INST_2x(xor_, Xor, X86Gp, X86Gp)                                     // ANY
+     849             :   ASMJIT_INST_2x(xor_, Xor, X86Gp, X86Mem)                                    // ANY
+     850             :   ASMJIT_INST_2i(xor_, Xor, X86Gp, Imm)                                       // ANY
+     851             :   ASMJIT_INST_2x(xor_, Xor, X86Mem, X86Gp)                                    // ANY
+     852             :   ASMJIT_INST_2i(xor_, Xor, X86Mem, Imm)                                      // ANY
+     853             :   ASMJIT_INST_3x(xsetbv, Xsetbv, EDX, EAX, ECX)                               // XSAVE     [EXPLICIT] XCR[ECX] <- EDX:EAX
+     854             :   ASMJIT_INST_0x(xtest, Xtest)                                                // TSX
+     855             : 
+     856             :   // --------------------------------------------------------------------------
+     857             :   // [FPU Instructions]
+     858             :   // --------------------------------------------------------------------------
+     859             : 
+     860             :   ASMJIT_INST_0x(f2xm1, F2xm1)                                                // FPU
+     861             :   ASMJIT_INST_0x(fabs, Fabs)                                                  // FPU
+     862             :   ASMJIT_INST_2x(fadd, Fadd, X86Fp, X86Fp)                                    // FPU
+     863             :   ASMJIT_INST_1x(fadd, Fadd, X86Mem)                                          // FPU
+     864             :   ASMJIT_INST_1x(faddp, Faddp, X86Fp)                                         // FPU
+     865             :   ASMJIT_INST_0x(faddp, Faddp)                                                // FPU
+     866             :   ASMJIT_INST_1x(fbld, Fbld, X86Mem)                                          // FPU
+     867             :   ASMJIT_INST_1x(fbstp, Fbstp, X86Mem)                                        // FPU
+     868             :   ASMJIT_INST_0x(fchs, Fchs)                                                  // FPU
+     869             :   ASMJIT_INST_0x(fclex, Fclex)                                                // FPU
+     870             :   ASMJIT_INST_1x(fcmovb, Fcmovb, X86Fp)                                       // FPU
+     871             :   ASMJIT_INST_1x(fcmovbe, Fcmovbe, X86Fp)                                     // FPU
+     872             :   ASMJIT_INST_1x(fcmove, Fcmove, X86Fp)                                       // FPU
+     873             :   ASMJIT_INST_1x(fcmovnb, Fcmovnb, X86Fp)                                     // FPU
+     874             :   ASMJIT_INST_1x(fcmovnbe, Fcmovnbe, X86Fp)                                   // FPU
+     875             :   ASMJIT_INST_1x(fcmovne, Fcmovne, X86Fp)                                     // FPU
+     876             :   ASMJIT_INST_1x(fcmovnu, Fcmovnu, X86Fp)                                     // FPU
+     877             :   ASMJIT_INST_1x(fcmovu, Fcmovu, X86Fp)                                       // FPU
+     878             :   ASMJIT_INST_1x(fcom, Fcom, X86Fp)                                           // FPU
+     879             :   ASMJIT_INST_0x(fcom, Fcom)                                                  // FPU
+     880             :   ASMJIT_INST_1x(fcom, Fcom, X86Mem)                                          // FPU
+     881             :   ASMJIT_INST_1x(fcomp, Fcomp, X86Fp)                                         // FPU
+     882             :   ASMJIT_INST_0x(fcomp, Fcomp)                                                // FPU
+     883             :   ASMJIT_INST_1x(fcomp, Fcomp, X86Mem)                                        // FPU
+     884             :   ASMJIT_INST_0x(fcompp, Fcompp)                                              // FPU
+     885             :   ASMJIT_INST_1x(fcomi, Fcomi, X86Fp)                                         // FPU
+     886             :   ASMJIT_INST_1x(fcomip, Fcomip, X86Fp)                                       // FPU
+     887             :   ASMJIT_INST_0x(fcos, Fcos)                                                  // FPU
+     888             :   ASMJIT_INST_0x(fdecstp, Fdecstp)                                            // FPU
+     889             :   ASMJIT_INST_2x(fdiv, Fdiv, X86Fp, X86Fp)                                    // FPU
+     890             :   ASMJIT_INST_1x(fdiv, Fdiv, X86Mem)                                          // FPU
+     891             :   ASMJIT_INST_1x(fdivp, Fdivp, X86Fp)                                         // FPU
+     892             :   ASMJIT_INST_0x(fdivp, Fdivp)                                                // FPU
+     893             :   ASMJIT_INST_2x(fdivr, Fdivr, X86Fp, X86Fp)                                  // FPU
+     894             :   ASMJIT_INST_1x(fdivr, Fdivr, X86Mem)                                        // FPU
+     895             :   ASMJIT_INST_1x(fdivrp, Fdivrp, X86Fp)                                       // FPU
+     896             :   ASMJIT_INST_0x(fdivrp, Fdivrp)                                              // FPU
+     897             :   ASMJIT_INST_1x(ffree, Ffree, X86Fp)                                         // FPU
+     898             :   ASMJIT_INST_1x(fiadd, Fiadd, X86Mem)                                        // FPU
+     899             :   ASMJIT_INST_1x(ficom, Ficom, X86Mem)                                        // FPU
+     900             :   ASMJIT_INST_1x(ficomp, Ficomp, X86Mem)                                      // FPU
+     901             :   ASMJIT_INST_1x(fidiv, Fidiv, X86Mem)                                        // FPU
+     902             :   ASMJIT_INST_1x(fidivr, Fidivr, X86Mem)                                      // FPU
+     903             :   ASMJIT_INST_1x(fild, Fild, X86Mem)                                          // FPU
+     904             :   ASMJIT_INST_1x(fimul, Fimul, X86Mem)                                        // FPU
+     905             :   ASMJIT_INST_0x(fincstp, Fincstp)                                            // FPU
+     906             :   ASMJIT_INST_0x(finit, Finit)                                                // FPU
+     907             :   ASMJIT_INST_1x(fisub, Fisub, X86Mem)                                        // FPU
+     908             :   ASMJIT_INST_1x(fisubr, Fisubr, X86Mem)                                      // FPU
+     909             :   ASMJIT_INST_0x(fninit, Fninit)                                              // FPU
+     910             :   ASMJIT_INST_1x(fist, Fist, X86Mem)                                          // FPU
+     911             :   ASMJIT_INST_1x(fistp, Fistp, X86Mem)                                        // FPU
+     912             :   ASMJIT_INST_1x(fisttp, Fisttp, X86Mem)                                      // FPU+SSE3
+     913           0 :   ASMJIT_INST_1x(fld, Fld, X86Mem)                                            // FPU
+     914             :   ASMJIT_INST_1x(fld, Fld, X86Fp)                                             // FPU
+     915             :   ASMJIT_INST_0x(fld1, Fld1)                                                  // FPU
+     916             :   ASMJIT_INST_0x(fldl2t, Fldl2t)                                              // FPU
+     917             :   ASMJIT_INST_0x(fldl2e, Fldl2e)                                              // FPU
+     918             :   ASMJIT_INST_0x(fldpi, Fldpi)                                                // FPU
+     919             :   ASMJIT_INST_0x(fldlg2, Fldlg2)                                              // FPU
+     920             :   ASMJIT_INST_0x(fldln2, Fldln2)                                              // FPU
+     921             :   ASMJIT_INST_0x(fldz, Fldz)                                                  // FPU
+     922             :   ASMJIT_INST_1x(fldcw, Fldcw, X86Mem)                                        // FPU
+     923             :   ASMJIT_INST_1x(fldenv, Fldenv, X86Mem)                                      // FPU
+     924             :   ASMJIT_INST_2x(fmul, Fmul, X86Fp, X86Fp)                                    // FPU
+     925             :   ASMJIT_INST_1x(fmul, Fmul, X86Mem)                                          // FPU
+     926             :   ASMJIT_INST_1x(fmulp, Fmulp, X86Fp)                                         // FPU
+     927             :   ASMJIT_INST_0x(fmulp, Fmulp)                                                // FPU
+     928             :   ASMJIT_INST_0x(fnclex, Fnclex)                                              // FPU
+     929             :   ASMJIT_INST_0x(fnop, Fnop)                                                  // FPU
+     930             :   ASMJIT_INST_1x(fnsave, Fnsave, X86Mem)                                      // FPU
+     931             :   ASMJIT_INST_1x(fnstenv, Fnstenv, X86Mem)                                    // FPU
+     932             :   ASMJIT_INST_1x(fnstcw, Fnstcw, X86Mem)                                      // FPU
+     933             :   ASMJIT_INST_0x(fpatan, Fpatan)                                              // FPU
+     934             :   ASMJIT_INST_0x(fprem, Fprem)                                                // FPU
+     935             :   ASMJIT_INST_0x(fprem1, Fprem1)                                              // FPU
+     936             :   ASMJIT_INST_0x(fptan, Fptan)                                                // FPU
+     937             :   ASMJIT_INST_0x(frndint, Frndint)                                            // FPU
+     938             :   ASMJIT_INST_1x(frstor, Frstor, X86Mem)                                      // FPU
+     939             :   ASMJIT_INST_1x(fsave, Fsave, X86Mem)                                        // FPU
+     940             :   ASMJIT_INST_0x(fscale, Fscale)                                              // FPU
+     941             :   ASMJIT_INST_0x(fsin, Fsin)                                                  // FPU
+     942             :   ASMJIT_INST_0x(fsincos, Fsincos)                                            // FPU
+     943             :   ASMJIT_INST_0x(fsqrt, Fsqrt)                                                // FPU
+     944             :   ASMJIT_INST_1x(fst, Fst, X86Mem)                                            // FPU
+     945             :   ASMJIT_INST_1x(fst, Fst, X86Fp)                                             // FPU
+     946           0 :   ASMJIT_INST_1x(fstp, Fstp, X86Mem)                                          // FPU
+     947             :   ASMJIT_INST_1x(fstp, Fstp, X86Fp)                                           // FPU
+     948             :   ASMJIT_INST_1x(fstcw, Fstcw, X86Mem)                                        // FPU
+     949             :   ASMJIT_INST_1x(fstenv, Fstenv, X86Mem)                                      // FPU
+     950             :   ASMJIT_INST_2x(fsub, Fsub, X86Fp, X86Fp)                                    // FPU
+     951             :   ASMJIT_INST_1x(fsub, Fsub, X86Mem)                                          // FPU
+     952             :   ASMJIT_INST_1x(fsubp, Fsubp, X86Fp)                                         // FPU
+     953             :   ASMJIT_INST_0x(fsubp, Fsubp)                                                // FPU
+     954             :   ASMJIT_INST_2x(fsubr, Fsubr, X86Fp, X86Fp)                                  // FPU
+     955             :   ASMJIT_INST_1x(fsubr, Fsubr, X86Mem)                                        // FPU
+     956             :   ASMJIT_INST_1x(fsubrp, Fsubrp, X86Fp)                                       // FPU
+     957             :   ASMJIT_INST_0x(fsubrp, Fsubrp)                                              // FPU
+     958             :   ASMJIT_INST_0x(ftst, Ftst)                                                  // FPU
+     959             :   ASMJIT_INST_1x(fucom, Fucom, X86Fp)                                         // FPU
+     960             :   ASMJIT_INST_0x(fucom, Fucom)                                                // FPU
+     961             :   ASMJIT_INST_1x(fucomi, Fucomi, X86Fp)                                       // FPU
+     962             :   ASMJIT_INST_1x(fucomip, Fucomip, X86Fp)                                     // FPU
+     963             :   ASMJIT_INST_1x(fucomp, Fucomp, X86Fp)                                       // FPU
+     964             :   ASMJIT_INST_0x(fucomp, Fucomp)                                              // FPU
+     965             :   ASMJIT_INST_0x(fucompp, Fucompp)                                            // FPU
+     966             :   ASMJIT_INST_0x(fwait, Fwait)                                                // FPU
+     967             :   ASMJIT_INST_0x(fxam, Fxam)                                                  // FPU
+     968             :   ASMJIT_INST_1x(fxch, Fxch, X86Fp)                                           // FPU
+     969             :   ASMJIT_INST_0x(fxtract, Fxtract)                                            // FPU
+     970             :   ASMJIT_INST_0x(fyl2x, Fyl2x)                                                // FPU
+     971             :   ASMJIT_INST_0x(fyl2xp1, Fyl2xp1)                                            // FPU
+     972             :   ASMJIT_INST_1x(fstsw, Fstsw, X86Gp)                                         // FPU
+     973             :   ASMJIT_INST_1x(fstsw, Fstsw, X86Mem)                                        // FPU
+     974             :   ASMJIT_INST_1x(fnstsw, Fnstsw, X86Gp)                                       // FPU
+     975             :   ASMJIT_INST_1x(fnstsw, Fnstsw, X86Mem)                                      // FPU
+     976             : 
+     977             :   // --------------------------------------------------------------------------
+     978             :   // [MMX & SSE Instructions]
+     979             :   // --------------------------------------------------------------------------
+     980             : 
+     981             :   ASMJIT_INST_2x(addpd, Addpd, X86Xmm, X86Xmm)                                // SSE2
+     982             :   ASMJIT_INST_2x(addpd, Addpd, X86Xmm, X86Mem)                                // SSE2
+     983             :   ASMJIT_INST_2x(addps, Addps, X86Xmm, X86Xmm)                                // SSE
+     984             :   ASMJIT_INST_2x(addps, Addps, X86Xmm, X86Mem)                                // SSE
+     985        1986 :   ASMJIT_INST_2x(addsd, Addsd, X86Xmm, X86Xmm)                                // SSE2
+     986             :   ASMJIT_INST_2x(addsd, Addsd, X86Xmm, X86Mem)                                // SSE2
+     987             :   ASMJIT_INST_2x(addss, Addss, X86Xmm, X86Xmm)                                // SSE
+     988             :   ASMJIT_INST_2x(addss, Addss, X86Xmm, X86Mem)                                // SSE
+     989             :   ASMJIT_INST_2x(addsubpd, Addsubpd, X86Xmm, X86Xmm)                          // SSE3
+     990             :   ASMJIT_INST_2x(addsubpd, Addsubpd, X86Xmm, X86Mem)                          // SSE3
+     991             :   ASMJIT_INST_2x(addsubps, Addsubps, X86Xmm, X86Xmm)                          // SSE3
+     992             :   ASMJIT_INST_2x(addsubps, Addsubps, X86Xmm, X86Mem)                          // SSE3
+     993             :   ASMJIT_INST_2x(andnpd, Andnpd, X86Xmm, X86Xmm)                              // SSE2
+     994             :   ASMJIT_INST_2x(andnpd, Andnpd, X86Xmm, X86Mem)                              // SSE2
+     995             :   ASMJIT_INST_2x(andnps, Andnps, X86Xmm, X86Xmm)                              // SSE
+     996             :   ASMJIT_INST_2x(andnps, Andnps, X86Xmm, X86Mem)                              // SSE
+     997             :   ASMJIT_INST_2x(andpd, Andpd, X86Xmm, X86Xmm)                                // SSE2
+     998             :   ASMJIT_INST_2x(andpd, Andpd, X86Xmm, X86Mem)                                // SSE2
+     999         120 :   ASMJIT_INST_2x(andps, Andps, X86Xmm, X86Xmm)                                // SSE
+    1000             :   ASMJIT_INST_2x(andps, Andps, X86Xmm, X86Mem)                                // SSE
+    1001             :   ASMJIT_INST_3i(blendpd, Blendpd, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1002             :   ASMJIT_INST_3i(blendpd, Blendpd, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1003             :   ASMJIT_INST_3i(blendps, Blendps, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1004             :   ASMJIT_INST_3i(blendps, Blendps, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1005             :   ASMJIT_INST_3x(blendvpd, Blendvpd, X86Xmm, X86Xmm, XMM0)                    // SSE4_1 [EXPLICIT]
+    1006             :   ASMJIT_INST_3x(blendvpd, Blendvpd, X86Xmm, X86Mem, XMM0)                    // SSE4_1 [EXPLICIT]
+    1007             :   ASMJIT_INST_3x(blendvps, Blendvps, X86Xmm, X86Xmm, XMM0)                    // SSE4_1 [EXPLICIT]
+    1008             :   ASMJIT_INST_3x(blendvps, Blendvps, X86Xmm, X86Mem, XMM0)                    // SSE4_1 [EXPLICIT]
+    1009             :   ASMJIT_INST_3i(cmppd, Cmppd, X86Xmm, X86Xmm, Imm)                           // SSE2
+    1010             :   ASMJIT_INST_3i(cmppd, Cmppd, X86Xmm, X86Mem, Imm)                           // SSE2
+    1011             :   ASMJIT_INST_3i(cmpps, Cmpps, X86Xmm, X86Xmm, Imm)                           // SSE
+    1012             :   ASMJIT_INST_3i(cmpps, Cmpps, X86Xmm, X86Mem, Imm)                           // SSE
+    1013         120 :   ASMJIT_INST_3i(cmpsd, Cmpsd, X86Xmm, X86Xmm, Imm)                           // SSE2
+    1014             :   ASMJIT_INST_3i(cmpsd, Cmpsd, X86Xmm, X86Mem, Imm)                           // SSE2
+    1015             :   ASMJIT_INST_3i(cmpss, Cmpss, X86Xmm, X86Xmm, Imm)                           // SSE
+    1016             :   ASMJIT_INST_3i(cmpss, Cmpss, X86Xmm, X86Mem, Imm)                           // SSE
+    1017             :   ASMJIT_INST_2x(comisd, Comisd, X86Xmm, X86Xmm)                              // SSE2
+    1018             :   ASMJIT_INST_2x(comisd, Comisd, X86Xmm, X86Mem)                              // SSE2
+    1019             :   ASMJIT_INST_2x(comiss, Comiss, X86Xmm, X86Xmm)                              // SSE
+    1020             :   ASMJIT_INST_2x(comiss, Comiss, X86Xmm, X86Mem)                              // SSE
+    1021             :   ASMJIT_INST_2x(cvtdq2pd, Cvtdq2pd, X86Xmm, X86Xmm)                          // SSE2
+    1022             :   ASMJIT_INST_2x(cvtdq2pd, Cvtdq2pd, X86Xmm, X86Mem)                          // SSE2
+    1023             :   ASMJIT_INST_2x(cvtdq2ps, Cvtdq2ps, X86Xmm, X86Xmm)                          // SSE2
+    1024             :   ASMJIT_INST_2x(cvtdq2ps, Cvtdq2ps, X86Xmm, X86Mem)                          // SSE2
+    1025             :   ASMJIT_INST_2x(cvtpd2dq, Cvtpd2dq, X86Xmm, X86Xmm)                          // SSE2
+    1026             :   ASMJIT_INST_2x(cvtpd2dq, Cvtpd2dq, X86Xmm, X86Mem)                          // SSE2
+    1027             :   ASMJIT_INST_2x(cvtpd2pi, Cvtpd2pi, X86Mm, X86Xmm)                           // SSE2
+    1028             :   ASMJIT_INST_2x(cvtpd2pi, Cvtpd2pi, X86Mm, X86Mem)                           // SSE2
+    1029             :   ASMJIT_INST_2x(cvtpd2ps, Cvtpd2ps, X86Xmm, X86Xmm)                          // SSE2
+    1030             :   ASMJIT_INST_2x(cvtpd2ps, Cvtpd2ps, X86Xmm, X86Mem)                          // SSE2
+    1031             :   ASMJIT_INST_2x(cvtpi2pd, Cvtpi2pd, X86Xmm, X86Mm)                           // SSE2
+    1032             :   ASMJIT_INST_2x(cvtpi2pd, Cvtpi2pd, X86Xmm, X86Mem)                          // SSE2
+    1033             :   ASMJIT_INST_2x(cvtpi2ps, Cvtpi2ps, X86Xmm, X86Mm)                           // SSE
+    1034             :   ASMJIT_INST_2x(cvtpi2ps, Cvtpi2ps, X86Xmm, X86Mem)                          // SSE
+    1035             :   ASMJIT_INST_2x(cvtps2dq, Cvtps2dq, X86Xmm, X86Xmm)                          // SSE2
+    1036             :   ASMJIT_INST_2x(cvtps2dq, Cvtps2dq, X86Xmm, X86Mem)                          // SSE2
+    1037             :   ASMJIT_INST_2x(cvtps2pd, Cvtps2pd, X86Xmm, X86Xmm)                          // SSE2
+    1038             :   ASMJIT_INST_2x(cvtps2pd, Cvtps2pd, X86Xmm, X86Mem)                          // SSE2
+    1039             :   ASMJIT_INST_2x(cvtps2pi, Cvtps2pi, X86Mm, X86Xmm)                           // SSE
+    1040             :   ASMJIT_INST_2x(cvtps2pi, Cvtps2pi, X86Mm, X86Mem)                           // SSE
+    1041             :   ASMJIT_INST_2x(cvtsd2si, Cvtsd2si, X86Gp, X86Xmm)                           // SSE2
+    1042             :   ASMJIT_INST_2x(cvtsd2si, Cvtsd2si, X86Gp, X86Mem)                           // SSE2
+    1043             :   ASMJIT_INST_2x(cvtsd2ss, Cvtsd2ss, X86Xmm, X86Xmm)                          // SSE2
+    1044             :   ASMJIT_INST_2x(cvtsd2ss, Cvtsd2ss, X86Xmm, X86Mem)                          // SSE2
+    1045             :   ASMJIT_INST_2x(cvtsi2sd, Cvtsi2sd, X86Xmm, X86Gp)                           // SSE2
+    1046             :   ASMJIT_INST_2x(cvtsi2sd, Cvtsi2sd, X86Xmm, X86Mem)                          // SSE2
+    1047             :   ASMJIT_INST_2x(cvtsi2ss, Cvtsi2ss, X86Xmm, X86Gp)                           // SSE
+    1048             :   ASMJIT_INST_2x(cvtsi2ss, Cvtsi2ss, X86Xmm, X86Mem)                          // SSE
+    1049             :   ASMJIT_INST_2x(cvtss2sd, Cvtss2sd, X86Xmm, X86Xmm)                          // SSE2
+    1050             :   ASMJIT_INST_2x(cvtss2sd, Cvtss2sd, X86Xmm, X86Mem)                          // SSE2
+    1051             :   ASMJIT_INST_2x(cvtss2si, Cvtss2si, X86Gp, X86Xmm)                           // SSE
+    1052             :   ASMJIT_INST_2x(cvtss2si, Cvtss2si, X86Gp, X86Mem)                           // SSE
+    1053             :   ASMJIT_INST_2x(cvttpd2pi, Cvttpd2pi, X86Mm, X86Xmm)                         // SSE2
+    1054             :   ASMJIT_INST_2x(cvttpd2pi, Cvttpd2pi, X86Mm, X86Mem)                         // SSE2
+    1055             :   ASMJIT_INST_2x(cvttpd2dq, Cvttpd2dq, X86Xmm, X86Xmm)                        // SSE2
+    1056             :   ASMJIT_INST_2x(cvttpd2dq, Cvttpd2dq, X86Xmm, X86Mem)                        // SSE2
+    1057             :   ASMJIT_INST_2x(cvttps2dq, Cvttps2dq, X86Xmm, X86Xmm)                        // SSE2
+    1058             :   ASMJIT_INST_2x(cvttps2dq, Cvttps2dq, X86Xmm, X86Mem)                        // SSE2
+    1059             :   ASMJIT_INST_2x(cvttps2pi, Cvttps2pi, X86Mm, X86Xmm)                         // SSE
+    1060             :   ASMJIT_INST_2x(cvttps2pi, Cvttps2pi, X86Mm, X86Mem)                         // SSE
+    1061             :   ASMJIT_INST_2x(cvttsd2si, Cvttsd2si, X86Gp, X86Xmm)                         // SSE2
+    1062             :   ASMJIT_INST_2x(cvttsd2si, Cvttsd2si, X86Gp, X86Mem)                         // SSE2
+    1063             :   ASMJIT_INST_2x(cvttss2si, Cvttss2si, X86Gp, X86Xmm)                         // SSE
+    1064             :   ASMJIT_INST_2x(cvttss2si, Cvttss2si, X86Gp, X86Mem)                         // SSE
+    1065             :   ASMJIT_INST_2x(divpd, Divpd, X86Xmm, X86Xmm)                                // SSE2
+    1066             :   ASMJIT_INST_2x(divpd, Divpd, X86Xmm, X86Mem)                                // SSE2
+    1067             :   ASMJIT_INST_2x(divps, Divps, X86Xmm, X86Xmm)                                // SSE
+    1068             :   ASMJIT_INST_2x(divps, Divps, X86Xmm, X86Mem)                                // SSE
+    1069         270 :   ASMJIT_INST_2x(divsd, Divsd, X86Xmm, X86Xmm)                                // SSE2
+    1070             :   ASMJIT_INST_2x(divsd, Divsd, X86Xmm, X86Mem)                                // SSE2
+    1071             :   ASMJIT_INST_2x(divss, Divss, X86Xmm, X86Xmm)                                // SSE
+    1072             :   ASMJIT_INST_2x(divss, Divss, X86Xmm, X86Mem)                                // SSE
+    1073             :   ASMJIT_INST_3i(dppd, Dppd, X86Xmm, X86Xmm, Imm)                             // SSE4_1
+    1074             :   ASMJIT_INST_3i(dppd, Dppd, X86Xmm, X86Mem, Imm)                             // SSE4_1
+    1075             :   ASMJIT_INST_3i(dpps, Dpps, X86Xmm, X86Xmm, Imm)                             // SSE4_1
+    1076             :   ASMJIT_INST_3i(dpps, Dpps, X86Xmm, X86Mem, Imm)                             // SSE4_1
+    1077             :   ASMJIT_INST_3i(extractps, Extractps, X86Gp, X86Xmm, Imm)                    // SSE4_1
+    1078             :   ASMJIT_INST_3i(extractps, Extractps, X86Mem, X86Xmm, Imm)                   // SSE4_1
+    1079             :   ASMJIT_INST_2x(extrq, Extrq, X86Xmm, X86Xmm)                                // SSE4A
+    1080             :   ASMJIT_INST_3ii(extrq, Extrq, X86Xmm, Imm, Imm)                             // SSE4A
+    1081             :   ASMJIT_INST_2x(haddpd, Haddpd, X86Xmm, X86Xmm)                              // SSE3
+    1082             :   ASMJIT_INST_2x(haddpd, Haddpd, X86Xmm, X86Mem)                              // SSE3
+    1083             :   ASMJIT_INST_2x(haddps, Haddps, X86Xmm, X86Xmm)                              // SSE3
+    1084             :   ASMJIT_INST_2x(haddps, Haddps, X86Xmm, X86Mem)                              // SSE3
+    1085             :   ASMJIT_INST_2x(hsubpd, Hsubpd, X86Xmm, X86Xmm)                              // SSE3
+    1086             :   ASMJIT_INST_2x(hsubpd, Hsubpd, X86Xmm, X86Mem)                              // SSE3
+    1087             :   ASMJIT_INST_2x(hsubps, Hsubps, X86Xmm, X86Xmm)                              // SSE3
+    1088             :   ASMJIT_INST_2x(hsubps, Hsubps, X86Xmm, X86Mem)                              // SSE3
+    1089             :   ASMJIT_INST_3i(insertps, Insertps, X86Xmm, X86Xmm, Imm)                     // SSE4_1
+    1090             :   ASMJIT_INST_3i(insertps, Insertps, X86Xmm, X86Mem, Imm)                     // SSE4_1
+    1091             :   ASMJIT_INST_2x(insertq, Insertq, X86Xmm, X86Xmm)                            // SSE4A
+    1092             :   ASMJIT_INST_4ii(insertq, Insertq, X86Xmm, X86Xmm, Imm, Imm)                 // SSE4A
+    1093             :   ASMJIT_INST_2x(lddqu, Lddqu, X86Xmm, X86Mem)                                // SSE3
+    1094             :   ASMJIT_INST_3x(maskmovq, Maskmovq, X86Mm, X86Mm, DS_ZDI)                    // SSE  [EXPLICIT]
+    1095             :   ASMJIT_INST_3x(maskmovdqu, Maskmovdqu, X86Xmm, X86Xmm, DS_ZDI)              // SSE2 [EXPLICIT]
+    1096             :   ASMJIT_INST_2x(maxpd, Maxpd, X86Xmm, X86Xmm)                                // SSE2
+    1097             :   ASMJIT_INST_2x(maxpd, Maxpd, X86Xmm, X86Mem)                                // SSE2
+    1098             :   ASMJIT_INST_2x(maxps, Maxps, X86Xmm, X86Xmm)                                // SSE
+    1099             :   ASMJIT_INST_2x(maxps, Maxps, X86Xmm, X86Mem)                                // SSE
+    1100             :   ASMJIT_INST_2x(maxsd, Maxsd, X86Xmm, X86Xmm)                                // SSE2
+    1101             :   ASMJIT_INST_2x(maxsd, Maxsd, X86Xmm, X86Mem)                                // SSE2
+    1102             :   ASMJIT_INST_2x(maxss, Maxss, X86Xmm, X86Xmm)                                // SSE
+    1103             :   ASMJIT_INST_2x(maxss, Maxss, X86Xmm, X86Mem)                                // SSE
+    1104             :   ASMJIT_INST_2x(minpd, Minpd, X86Xmm, X86Xmm)                                // SSE2
+    1105             :   ASMJIT_INST_2x(minpd, Minpd, X86Xmm, X86Mem)                                // SSE2
+    1106             :   ASMJIT_INST_2x(minps, Minps, X86Xmm, X86Xmm)                                // SSE
+    1107             :   ASMJIT_INST_2x(minps, Minps, X86Xmm, X86Mem)                                // SSE
+    1108             :   ASMJIT_INST_2x(minsd, Minsd, X86Xmm, X86Xmm)                                // SSE2
+    1109             :   ASMJIT_INST_2x(minsd, Minsd, X86Xmm, X86Mem)                                // SSE2
+    1110             :   ASMJIT_INST_2x(minss, Minss, X86Xmm, X86Xmm)                                // SSE
+    1111             :   ASMJIT_INST_2x(minss, Minss, X86Xmm, X86Mem)                                // SSE
+    1112             :   ASMJIT_INST_2x(movapd, Movapd, X86Xmm, X86Xmm)                              // SSE2
+    1113             :   ASMJIT_INST_2x(movapd, Movapd, X86Xmm, X86Mem)                              // SSE2
+    1114             :   ASMJIT_INST_2x(movapd, Movapd, X86Mem, X86Xmm)                              // SSE2
+    1115             :   ASMJIT_INST_2x(movaps, Movaps, X86Xmm, X86Xmm)                              // SSE
+    1116             :   ASMJIT_INST_2x(movaps, Movaps, X86Xmm, X86Mem)                              // SSE
+    1117             :   ASMJIT_INST_2x(movaps, Movaps, X86Mem, X86Xmm)                              // SSE
+    1118             :   ASMJIT_INST_2x(movd, Movd, X86Mem, X86Mm)                                   // MMX
+    1119             :   ASMJIT_INST_2x(movd, Movd, X86Mem, X86Xmm)                                  // SSE
+    1120             :   ASMJIT_INST_2x(movd, Movd, X86Gp, X86Mm)                                    // MMX
+    1121             :   ASMJIT_INST_2x(movd, Movd, X86Gp, X86Xmm)                                   // SSE
+    1122             :   ASMJIT_INST_2x(movd, Movd, X86Mm, X86Mem)                                   // MMX
+    1123             :   ASMJIT_INST_2x(movd, Movd, X86Xmm, X86Mem)                                  // SSE
+    1124             :   ASMJIT_INST_2x(movd, Movd, X86Mm, X86Gp)                                    // MMX
+    1125             :   ASMJIT_INST_2x(movd, Movd, X86Xmm, X86Gp)                                   // SSE
+    1126             :   ASMJIT_INST_2x(movddup, Movddup, X86Xmm, X86Xmm)                            // SSE3
+    1127             :   ASMJIT_INST_2x(movddup, Movddup, X86Xmm, X86Mem)                            // SSE3
+    1128             :   ASMJIT_INST_2x(movdq2q, Movdq2q, X86Mm, X86Xmm)                             // SSE2
+    1129             :   ASMJIT_INST_2x(movdqa, Movdqa, X86Xmm, X86Xmm)                              // SSE2
+    1130             :   ASMJIT_INST_2x(movdqa, Movdqa, X86Xmm, X86Mem)                              // SSE2
+    1131             :   ASMJIT_INST_2x(movdqa, Movdqa, X86Mem, X86Xmm)                              // SSE2
+    1132             :   ASMJIT_INST_2x(movdqu, Movdqu, X86Xmm, X86Xmm)                              // SSE2
+    1133             :   ASMJIT_INST_2x(movdqu, Movdqu, X86Xmm, X86Mem)                              // SSE2
+    1134             :   ASMJIT_INST_2x(movdqu, Movdqu, X86Mem, X86Xmm)                              // SSE2
+    1135             :   ASMJIT_INST_2x(movhlps, Movhlps, X86Xmm, X86Xmm)                            // SSE
+    1136             :   ASMJIT_INST_2x(movhpd, Movhpd, X86Xmm, X86Mem)                              // SSE2
+    1137             :   ASMJIT_INST_2x(movhpd, Movhpd, X86Mem, X86Xmm)                              // SSE2
+    1138             :   ASMJIT_INST_2x(movhps, Movhps, X86Xmm, X86Mem)                              // SSE
+    1139             :   ASMJIT_INST_2x(movhps, Movhps, X86Mem, X86Xmm)                              // SSE
+    1140             :   ASMJIT_INST_2x(movlhps, Movlhps, X86Xmm, X86Xmm)                            // SSE
+    1141             :   ASMJIT_INST_2x(movlpd, Movlpd, X86Xmm, X86Mem)                              // SSE2
+    1142             :   ASMJIT_INST_2x(movlpd, Movlpd, X86Mem, X86Xmm)                              // SSE2
+    1143             :   ASMJIT_INST_2x(movlps, Movlps, X86Xmm, X86Mem)                              // SSE
+    1144             :   ASMJIT_INST_2x(movlps, Movlps, X86Mem, X86Xmm)                              // SSE
+    1145             :   ASMJIT_INST_2x(movmskps, Movmskps, X86Gp, X86Xmm)                           // SSE2
+    1146             :   ASMJIT_INST_2x(movmskpd, Movmskpd, X86Gp, X86Xmm)                           // SSE2
+    1147             :   ASMJIT_INST_2x(movntdq, Movntdq, X86Mem, X86Xmm)                            // SSE2
+    1148             :   ASMJIT_INST_2x(movntdqa, Movntdqa, X86Xmm, X86Mem)                          // SSE4_1
+    1149             :   ASMJIT_INST_2x(movntpd, Movntpd, X86Mem, X86Xmm)                            // SSE2
+    1150             :   ASMJIT_INST_2x(movntps, Movntps, X86Mem, X86Xmm)                            // SSE
+    1151             :   ASMJIT_INST_2x(movntsd, Movntsd, X86Mem, X86Xmm)                            // SSE4A
+    1152             :   ASMJIT_INST_2x(movntss, Movntss, X86Mem, X86Xmm)                            // SSE4A
+    1153             :   ASMJIT_INST_2x(movntq, Movntq, X86Mem, X86Mm)                               // SSE
+    1154             :   ASMJIT_INST_2x(movq, Movq, X86Mm, X86Mm)                                    // MMX
+    1155             :   ASMJIT_INST_2x(movq, Movq, X86Xmm, X86Xmm)                                  // SSE
+    1156             :   ASMJIT_INST_2x(movq, Movq, X86Mem, X86Mm)                                   // MMX
+    1157             :   ASMJIT_INST_2x(movq, Movq, X86Mem, X86Xmm)                                  // SSE
+    1158             :   ASMJIT_INST_2x(movq, Movq, X86Mm, X86Mem)                                   // MMX
+    1159             :   ASMJIT_INST_2x(movq, Movq, X86Xmm, X86Mem)                                  // SSE
+    1160             :   ASMJIT_INST_2x(movq, Movq, X86Gp, X86Mm)                                    // MMX
+    1161             :   ASMJIT_INST_2x(movq, Movq, X86Gp, X86Xmm)                                   // SSE+X64.
+    1162             :   ASMJIT_INST_2x(movq, Movq, X86Mm, X86Gp)                                    // MMX
+    1163             :   ASMJIT_INST_2x(movq, Movq, X86Xmm, X86Gp)                                   // SSE+X64.
+    1164             :   ASMJIT_INST_2x(movq2dq, Movq2dq, X86Xmm, X86Mm)                             // SSE2
+    1165        8664 :   ASMJIT_INST_2x(movsd, Movsd, X86Xmm, X86Xmm)                                // SSE2
+    1166        5834 :   ASMJIT_INST_2x(movsd, Movsd, X86Xmm, X86Mem)                                // SSE2
+    1167         266 :   ASMJIT_INST_2x(movsd, Movsd, X86Mem, X86Xmm)                                // SSE2
+    1168             :   ASMJIT_INST_2x(movshdup, Movshdup, X86Xmm, X86Xmm)                          // SSE3
+    1169             :   ASMJIT_INST_2x(movshdup, Movshdup, X86Xmm, X86Mem)                          // SSE3
+    1170             :   ASMJIT_INST_2x(movsldup, Movsldup, X86Xmm, X86Xmm)                          // SSE3
+    1171             :   ASMJIT_INST_2x(movsldup, Movsldup, X86Xmm, X86Mem)                          // SSE3
+    1172             :   ASMJIT_INST_2x(movss, Movss, X86Xmm, X86Xmm)                                // SSE
+    1173             :   ASMJIT_INST_2x(movss, Movss, X86Xmm, X86Mem)                                // SSE
+    1174             :   ASMJIT_INST_2x(movss, Movss, X86Mem, X86Xmm)                                // SSE
+    1175             :   ASMJIT_INST_2x(movupd, Movupd, X86Xmm, X86Xmm)                              // SSE2
+    1176             :   ASMJIT_INST_2x(movupd, Movupd, X86Xmm, X86Mem)                              // SSE2
+    1177             :   ASMJIT_INST_2x(movupd, Movupd, X86Mem, X86Xmm)                              // SSE2
+    1178             :   ASMJIT_INST_2x(movups, Movups, X86Xmm, X86Xmm)                              // SSE
+    1179             :   ASMJIT_INST_2x(movups, Movups, X86Xmm, X86Mem)                              // SSE
+    1180             :   ASMJIT_INST_2x(movups, Movups, X86Mem, X86Xmm)                              // SSE
+    1181             :   ASMJIT_INST_3i(mpsadbw, Mpsadbw, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1182             :   ASMJIT_INST_3i(mpsadbw, Mpsadbw, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1183             :   ASMJIT_INST_2x(mulpd, Mulpd, X86Xmm, X86Xmm)                                // SSE2
+    1184             :   ASMJIT_INST_2x(mulpd, Mulpd, X86Xmm, X86Mem)                                // SSE2
+    1185             :   ASMJIT_INST_2x(mulps, Mulps, X86Xmm, X86Xmm)                                // SSE
+    1186             :   ASMJIT_INST_2x(mulps, Mulps, X86Xmm, X86Mem)                                // SSE
+    1187        5200 :   ASMJIT_INST_2x(mulsd, Mulsd, X86Xmm, X86Xmm)                                // SSE2
+    1188             :   ASMJIT_INST_2x(mulsd, Mulsd, X86Xmm, X86Mem)                                // SSE2
+    1189             :   ASMJIT_INST_2x(mulss, Mulss, X86Xmm, X86Xmm)                                // SSE
+    1190             :   ASMJIT_INST_2x(mulss, Mulss, X86Xmm, X86Mem)                                // SSE
+    1191             :   ASMJIT_INST_2x(orpd, Orpd, X86Xmm, X86Xmm)                                  // SSE2
+    1192             :   ASMJIT_INST_2x(orpd, Orpd, X86Xmm, X86Mem)                                  // SSE2
+    1193             :   ASMJIT_INST_2x(orps, Orps, X86Xmm, X86Xmm)                                  // SSE
+    1194             :   ASMJIT_INST_2x(orps, Orps, X86Xmm, X86Mem)                                  // SSE
+    1195             :   ASMJIT_INST_2x(packssdw, Packssdw, X86Mm, X86Mm)                            // MMX
+    1196             :   ASMJIT_INST_2x(packssdw, Packssdw, X86Mm, X86Mem)                           // MMX
+    1197             :   ASMJIT_INST_2x(packssdw, Packssdw, X86Xmm, X86Xmm)                          // SSE2
+    1198             :   ASMJIT_INST_2x(packssdw, Packssdw, X86Xmm, X86Mem)                          // SSE2
+    1199             :   ASMJIT_INST_2x(packsswb, Packsswb, X86Mm, X86Mm)                            // MMX
+    1200             :   ASMJIT_INST_2x(packsswb, Packsswb, X86Mm, X86Mem)                           // MMX
+    1201             :   ASMJIT_INST_2x(packsswb, Packsswb, X86Xmm, X86Xmm)                          // SSE2
+    1202             :   ASMJIT_INST_2x(packsswb, Packsswb, X86Xmm, X86Mem)                          // SSE2
+    1203             :   ASMJIT_INST_2x(packusdw, Packusdw, X86Xmm, X86Xmm)                          // SSE4_1
+    1204             :   ASMJIT_INST_2x(packusdw, Packusdw, X86Xmm, X86Mem)                          // SSE4_1
+    1205             :   ASMJIT_INST_2x(packuswb, Packuswb, X86Mm, X86Mm)                            // MMX
+    1206             :   ASMJIT_INST_2x(packuswb, Packuswb, X86Mm, X86Mem)                           // MMX
+    1207             :   ASMJIT_INST_2x(packuswb, Packuswb, X86Xmm, X86Xmm)                          // SSE2
+    1208             :   ASMJIT_INST_2x(packuswb, Packuswb, X86Xmm, X86Mem)                          // SSE2
+    1209             :   ASMJIT_INST_2x(pabsb, Pabsb, X86Mm, X86Mm)                                  // SSSE3
+    1210             :   ASMJIT_INST_2x(pabsb, Pabsb, X86Mm, X86Mem)                                 // SSSE3
+    1211             :   ASMJIT_INST_2x(pabsb, Pabsb, X86Xmm, X86Xmm)                                // SSSE3
+    1212             :   ASMJIT_INST_2x(pabsb, Pabsb, X86Xmm, X86Mem)                                // SSSE3
+    1213             :   ASMJIT_INST_2x(pabsd, Pabsd, X86Mm, X86Mm)                                  // SSSE3
+    1214             :   ASMJIT_INST_2x(pabsd, Pabsd, X86Mm, X86Mem)                                 // SSSE3
+    1215             :   ASMJIT_INST_2x(pabsd, Pabsd, X86Xmm, X86Xmm)                                // SSSE3
+    1216             :   ASMJIT_INST_2x(pabsd, Pabsd, X86Xmm, X86Mem)                                // SSSE3
+    1217             :   ASMJIT_INST_2x(pabsw, Pabsw, X86Mm, X86Mm)                                  // SSSE3
+    1218             :   ASMJIT_INST_2x(pabsw, Pabsw, X86Mm, X86Mem)                                 // SSSE3
+    1219             :   ASMJIT_INST_2x(pabsw, Pabsw, X86Xmm, X86Xmm)                                // SSSE3
+    1220             :   ASMJIT_INST_2x(pabsw, Pabsw, X86Xmm, X86Mem)                                // SSSE3
+    1221             :   ASMJIT_INST_2x(paddb, Paddb, X86Mm, X86Mm)                                  // MMX
+    1222             :   ASMJIT_INST_2x(paddb, Paddb, X86Mm, X86Mem)                                 // MMX
+    1223             :   ASMJIT_INST_2x(paddb, Paddb, X86Xmm, X86Xmm)                                // SSE2
+    1224             :   ASMJIT_INST_2x(paddb, Paddb, X86Xmm, X86Mem)                                // SSE2
+    1225             :   ASMJIT_INST_2x(paddd, Paddd, X86Mm, X86Mm)                                  // MMX
+    1226             :   ASMJIT_INST_2x(paddd, Paddd, X86Mm, X86Mem)                                 // MMX
+    1227             :   ASMJIT_INST_2x(paddd, Paddd, X86Xmm, X86Xmm)                                // SSE2
+    1228             :   ASMJIT_INST_2x(paddd, Paddd, X86Xmm, X86Mem)                                // SSE2
+    1229             :   ASMJIT_INST_2x(paddq, Paddq, X86Mm, X86Mm)                                  // SSE2
+    1230             :   ASMJIT_INST_2x(paddq, Paddq, X86Mm, X86Mem)                                 // SSE2
+    1231             :   ASMJIT_INST_2x(paddq, Paddq, X86Xmm, X86Xmm)                                // SSE2
+    1232             :   ASMJIT_INST_2x(paddq, Paddq, X86Xmm, X86Mem)                                // SSE2
+    1233             :   ASMJIT_INST_2x(paddsb, Paddsb, X86Mm, X86Mm)                                // MMX
+    1234             :   ASMJIT_INST_2x(paddsb, Paddsb, X86Mm, X86Mem)                               // MMX
+    1235             :   ASMJIT_INST_2x(paddsb, Paddsb, X86Xmm, X86Xmm)                              // SSE2
+    1236             :   ASMJIT_INST_2x(paddsb, Paddsb, X86Xmm, X86Mem)                              // SSE2
+    1237             :   ASMJIT_INST_2x(paddsw, Paddsw, X86Mm, X86Mm)                                // MMX
+    1238             :   ASMJIT_INST_2x(paddsw, Paddsw, X86Mm, X86Mem)                               // MMX
+    1239             :   ASMJIT_INST_2x(paddsw, Paddsw, X86Xmm, X86Xmm)                              // SSE2
+    1240             :   ASMJIT_INST_2x(paddsw, Paddsw, X86Xmm, X86Mem)                              // SSE2
+    1241             :   ASMJIT_INST_2x(paddusb, Paddusb, X86Mm, X86Mm)                              // MMX
+    1242             :   ASMJIT_INST_2x(paddusb, Paddusb, X86Mm, X86Mem)                             // MMX
+    1243             :   ASMJIT_INST_2x(paddusb, Paddusb, X86Xmm, X86Xmm)                            // SSE2
+    1244             :   ASMJIT_INST_2x(paddusb, Paddusb, X86Xmm, X86Mem)                            // SSE2
+    1245             :   ASMJIT_INST_2x(paddusw, Paddusw, X86Mm, X86Mm)                              // MMX
+    1246             :   ASMJIT_INST_2x(paddusw, Paddusw, X86Mm, X86Mem)                             // MMX
+    1247             :   ASMJIT_INST_2x(paddusw, Paddusw, X86Xmm, X86Xmm)                            // SSE2
+    1248             :   ASMJIT_INST_2x(paddusw, Paddusw, X86Xmm, X86Mem)                            // SSE2
+    1249             :   ASMJIT_INST_2x(paddw, Paddw, X86Mm, X86Mm)                                  // MMX
+    1250             :   ASMJIT_INST_2x(paddw, Paddw, X86Mm, X86Mem)                                 // MMX
+    1251             :   ASMJIT_INST_2x(paddw, Paddw, X86Xmm, X86Xmm)                                // SSE2
+    1252             :   ASMJIT_INST_2x(paddw, Paddw, X86Xmm, X86Mem)                                // SSE2
+    1253             :   ASMJIT_INST_3i(palignr, Palignr, X86Mm, X86Mm, Imm)                         // SSSE3
+    1254             :   ASMJIT_INST_3i(palignr, Palignr, X86Mm, X86Mem, Imm)                        // SSSE3
+    1255             :   ASMJIT_INST_3i(palignr, Palignr, X86Xmm, X86Xmm, Imm)                       // SSSE3
+    1256             :   ASMJIT_INST_3i(palignr, Palignr, X86Xmm, X86Mem, Imm)                       // SSSE3
+    1257             :   ASMJIT_INST_2x(pand, Pand, X86Mm, X86Mm)                                    // MMX
+    1258             :   ASMJIT_INST_2x(pand, Pand, X86Mm, X86Mem)                                   // MMX
+    1259             :   ASMJIT_INST_2x(pand, Pand, X86Xmm, X86Xmm)                                  // SSE2
+    1260             :   ASMJIT_INST_2x(pand, Pand, X86Xmm, X86Mem)                                  // SSE2
+    1261             :   ASMJIT_INST_2x(pandn, Pandn, X86Mm, X86Mm)                                  // MMX
+    1262             :   ASMJIT_INST_2x(pandn, Pandn, X86Mm, X86Mem)                                 // MMX
+    1263             :   ASMJIT_INST_2x(pandn, Pandn, X86Xmm, X86Xmm)                                // SSE2
+    1264             :   ASMJIT_INST_2x(pandn, Pandn, X86Xmm, X86Mem)                                // SSE2
+    1265             :   ASMJIT_INST_2x(pavgb, Pavgb, X86Mm, X86Mm)                                  // SSE
+    1266             :   ASMJIT_INST_2x(pavgb, Pavgb, X86Mm, X86Mem)                                 // SSE
+    1267             :   ASMJIT_INST_2x(pavgb, Pavgb, X86Xmm, X86Xmm)                                // SSE2
+    1268             :   ASMJIT_INST_2x(pavgb, Pavgb, X86Xmm, X86Mem)                                // SSE2
+    1269             :   ASMJIT_INST_2x(pavgw, Pavgw, X86Mm, X86Mm)                                  // SSE
+    1270             :   ASMJIT_INST_2x(pavgw, Pavgw, X86Mm, X86Mem)                                 // SSE
+    1271             :   ASMJIT_INST_2x(pavgw, Pavgw, X86Xmm, X86Xmm)                                // SSE2
+    1272             :   ASMJIT_INST_2x(pavgw, Pavgw, X86Xmm, X86Mem)                                // SSE2
+    1273             :   ASMJIT_INST_3x(pblendvb, Pblendvb, X86Xmm, X86Xmm, XMM0)                    // SSE4_1 [EXPLICIT]
+    1274             :   ASMJIT_INST_3x(pblendvb, Pblendvb, X86Xmm, X86Mem, XMM0)                    // SSE4_1 [EXPLICIT]
+    1275             :   ASMJIT_INST_3i(pblendw, Pblendw, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1276             :   ASMJIT_INST_3i(pblendw, Pblendw, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1277             :   ASMJIT_INST_3i(pclmulqdq, Pclmulqdq, X86Xmm, X86Xmm, Imm)                   // PCLMULQDQ.
+    1278             :   ASMJIT_INST_3i(pclmulqdq, Pclmulqdq, X86Xmm, X86Mem, Imm)                   // PCLMULQDQ.
+    1279             :   ASMJIT_INST_6x(pcmpestri, Pcmpestri, X86Xmm, X86Xmm, Imm, ECX, EAX, EDX)    // SSE4_2 [EXPLICIT]
+    1280             :   ASMJIT_INST_6x(pcmpestri, Pcmpestri, X86Xmm, X86Mem, Imm, ECX, EAX, EDX)    // SSE4_2 [EXPLICIT]
+    1281             :   ASMJIT_INST_6x(pcmpestrm, Pcmpestrm, X86Xmm, X86Xmm, Imm, XMM0, EAX, EDX)   // SSE4_2 [EXPLICIT]
+    1282             :   ASMJIT_INST_6x(pcmpestrm, Pcmpestrm, X86Xmm, X86Mem, Imm, XMM0, EAX, EDX)   // SSE4_2 [EXPLICIT]
+    1283             :   ASMJIT_INST_2x(pcmpeqb, Pcmpeqb, X86Mm, X86Mm)                              // MMX
+    1284             :   ASMJIT_INST_2x(pcmpeqb, Pcmpeqb, X86Mm, X86Mem)                             // MMX
+    1285             :   ASMJIT_INST_2x(pcmpeqb, Pcmpeqb, X86Xmm, X86Xmm)                            // SSE2
+    1286             :   ASMJIT_INST_2x(pcmpeqb, Pcmpeqb, X86Xmm, X86Mem)                            // SSE2
+    1287             :   ASMJIT_INST_2x(pcmpeqd, Pcmpeqd, X86Mm, X86Mm)                              // MMX
+    1288             :   ASMJIT_INST_2x(pcmpeqd, Pcmpeqd, X86Mm, X86Mem)                             // MMX
+    1289             :   ASMJIT_INST_2x(pcmpeqd, Pcmpeqd, X86Xmm, X86Xmm)                            // SSE2
+    1290             :   ASMJIT_INST_2x(pcmpeqd, Pcmpeqd, X86Xmm, X86Mem)                            // SSE2
+    1291             :   ASMJIT_INST_2x(pcmpeqq, Pcmpeqq, X86Xmm, X86Xmm)                            // SSE4_1
+    1292             :   ASMJIT_INST_2x(pcmpeqq, Pcmpeqq, X86Xmm, X86Mem)                            // SSE4_1
+    1293             :   ASMJIT_INST_2x(pcmpeqw, Pcmpeqw, X86Mm, X86Mm)                              // MMX
+    1294             :   ASMJIT_INST_2x(pcmpeqw, Pcmpeqw, X86Mm, X86Mem)                             // MMX
+    1295             :   ASMJIT_INST_2x(pcmpeqw, Pcmpeqw, X86Xmm, X86Xmm)                            // SSE2
+    1296             :   ASMJIT_INST_2x(pcmpeqw, Pcmpeqw, X86Xmm, X86Mem)                            // SSE2
+    1297             :   ASMJIT_INST_2x(pcmpgtb, Pcmpgtb, X86Mm, X86Mm)                              // MMX
+    1298             :   ASMJIT_INST_2x(pcmpgtb, Pcmpgtb, X86Mm, X86Mem)                             // MMX
+    1299             :   ASMJIT_INST_2x(pcmpgtb, Pcmpgtb, X86Xmm, X86Xmm)                            // SSE2
+    1300             :   ASMJIT_INST_2x(pcmpgtb, Pcmpgtb, X86Xmm, X86Mem)                            // SSE2
+    1301             :   ASMJIT_INST_2x(pcmpgtd, Pcmpgtd, X86Mm, X86Mm)                              // MMX
+    1302             :   ASMJIT_INST_2x(pcmpgtd, Pcmpgtd, X86Mm, X86Mem)                             // MMX
+    1303             :   ASMJIT_INST_2x(pcmpgtd, Pcmpgtd, X86Xmm, X86Xmm)                            // SSE2
+    1304             :   ASMJIT_INST_2x(pcmpgtd, Pcmpgtd, X86Xmm, X86Mem)                            // SSE2
+    1305             :   ASMJIT_INST_2x(pcmpgtq, Pcmpgtq, X86Xmm, X86Xmm)                            // SSE4_2.
+    1306             :   ASMJIT_INST_2x(pcmpgtq, Pcmpgtq, X86Xmm, X86Mem)                            // SSE4_2.
+    1307             :   ASMJIT_INST_2x(pcmpgtw, Pcmpgtw, X86Mm, X86Mm)                              // MMX
+    1308             :   ASMJIT_INST_2x(pcmpgtw, Pcmpgtw, X86Mm, X86Mem)                             // MMX
+    1309             :   ASMJIT_INST_2x(pcmpgtw, Pcmpgtw, X86Xmm, X86Xmm)                            // SSE2
+    1310             :   ASMJIT_INST_2x(pcmpgtw, Pcmpgtw, X86Xmm, X86Mem)                            // SSE2
+    1311             :   ASMJIT_INST_4x(pcmpistri, Pcmpistri, X86Xmm, X86Xmm, Imm, ECX)              // SSE4_2 [EXPLICIT]
+    1312             :   ASMJIT_INST_4x(pcmpistri, Pcmpistri, X86Xmm, X86Mem, Imm, ECX)              // SSE4_2 [EXPLICIT]
+    1313             :   ASMJIT_INST_4x(pcmpistrm, Pcmpistrm, X86Xmm, X86Xmm, Imm, XMM0)             // SSE4_2 [EXPLICIT]
+    1314             :   ASMJIT_INST_4x(pcmpistrm, Pcmpistrm, X86Xmm, X86Mem, Imm, XMM0)             // SSE4_2 [EXPLICIT]
+    1315             :   ASMJIT_INST_3i(pextrb, Pextrb, X86Gp, X86Xmm, Imm)                          // SSE4_1
+    1316             :   ASMJIT_INST_3i(pextrb, Pextrb, X86Mem, X86Xmm, Imm)                         // SSE4_1
+    1317             :   ASMJIT_INST_3i(pextrd, Pextrd, X86Gp, X86Xmm, Imm)                          // SSE4_1
+    1318             :   ASMJIT_INST_3i(pextrd, Pextrd, X86Mem, X86Xmm, Imm)                         // SSE4_1
+    1319             :   ASMJIT_INST_3i(pextrq, Pextrq, X86Gp, X86Xmm, Imm)                          // SSE4_1
+    1320             :   ASMJIT_INST_3i(pextrq, Pextrq, X86Mem, X86Xmm, Imm)                         // SSE4_1
+    1321             :   ASMJIT_INST_3i(pextrw, Pextrw, X86Gp, X86Mm, Imm)                           // SSE
+    1322             :   ASMJIT_INST_3i(pextrw, Pextrw, X86Gp, X86Xmm, Imm)                          // SSE2
+    1323             :   ASMJIT_INST_3i(pextrw, Pextrw, X86Mem, X86Xmm, Imm)                         // SSE4_1
+    1324             :   ASMJIT_INST_2x(phaddd, Phaddd, X86Mm, X86Mm)                                // SSSE3
+    1325             :   ASMJIT_INST_2x(phaddd, Phaddd, X86Mm, X86Mem)                               // SSSE3
+    1326             :   ASMJIT_INST_2x(phaddd, Phaddd, X86Xmm, X86Xmm)                              // SSSE3
+    1327             :   ASMJIT_INST_2x(phaddd, Phaddd, X86Xmm, X86Mem)                              // SSSE3
+    1328             :   ASMJIT_INST_2x(phaddsw, Phaddsw, X86Mm, X86Mm)                              // SSSE3
+    1329             :   ASMJIT_INST_2x(phaddsw, Phaddsw, X86Mm, X86Mem)                             // SSSE3
+    1330             :   ASMJIT_INST_2x(phaddsw, Phaddsw, X86Xmm, X86Xmm)                            // SSSE3
+    1331             :   ASMJIT_INST_2x(phaddsw, Phaddsw, X86Xmm, X86Mem)                            // SSSE3
+    1332             :   ASMJIT_INST_2x(phaddw, Phaddw, X86Mm, X86Mm)                                // SSSE3
+    1333             :   ASMJIT_INST_2x(phaddw, Phaddw, X86Mm, X86Mem)                               // SSSE3
+    1334             :   ASMJIT_INST_2x(phaddw, Phaddw, X86Xmm, X86Xmm)                              // SSSE3
+    1335             :   ASMJIT_INST_2x(phaddw, Phaddw, X86Xmm, X86Mem)                              // SSSE3
+    1336             :   ASMJIT_INST_2x(phminposuw, Phminposuw, X86Xmm, X86Xmm)                      // SSE4_1
+    1337             :   ASMJIT_INST_2x(phminposuw, Phminposuw, X86Xmm, X86Mem)                      // SSE4_1
+    1338             :   ASMJIT_INST_2x(phsubd, Phsubd, X86Mm, X86Mm)                                // SSSE3
+    1339             :   ASMJIT_INST_2x(phsubd, Phsubd, X86Mm, X86Mem)                               // SSSE3
+    1340             :   ASMJIT_INST_2x(phsubd, Phsubd, X86Xmm, X86Xmm)                              // SSSE3
+    1341             :   ASMJIT_INST_2x(phsubd, Phsubd, X86Xmm, X86Mem)                              // SSSE3
+    1342             :   ASMJIT_INST_2x(phsubsw, Phsubsw, X86Mm, X86Mm)                              // SSSE3
+    1343             :   ASMJIT_INST_2x(phsubsw, Phsubsw, X86Mm, X86Mem)                             // SSSE3
+    1344             :   ASMJIT_INST_2x(phsubsw, Phsubsw, X86Xmm, X86Xmm)                            // SSSE3
+    1345             :   ASMJIT_INST_2x(phsubsw, Phsubsw, X86Xmm, X86Mem)                            // SSSE3
+    1346             :   ASMJIT_INST_2x(phsubw, Phsubw, X86Mm, X86Mm)                                // SSSE3
+    1347             :   ASMJIT_INST_2x(phsubw, Phsubw, X86Mm, X86Mem)                               // SSSE3
+    1348             :   ASMJIT_INST_2x(phsubw, Phsubw, X86Xmm, X86Xmm)                              // SSSE3
+    1349             :   ASMJIT_INST_2x(phsubw, Phsubw, X86Xmm, X86Mem)                              // SSSE3
+    1350             :   ASMJIT_INST_3i(pinsrb, Pinsrb, X86Xmm, X86Gp, Imm)                          // SSE4_1
+    1351             :   ASMJIT_INST_3i(pinsrb, Pinsrb, X86Xmm, X86Mem, Imm)                         // SSE4_1
+    1352             :   ASMJIT_INST_3i(pinsrd, Pinsrd, X86Xmm, X86Gp, Imm)                          // SSE4_1
+    1353             :   ASMJIT_INST_3i(pinsrd, Pinsrd, X86Xmm, X86Mem, Imm)                         // SSE4_1
+    1354             :   ASMJIT_INST_3i(pinsrq, Pinsrq, X86Xmm, X86Gp, Imm)                          // SSE4_1
+    1355             :   ASMJIT_INST_3i(pinsrq, Pinsrq, X86Xmm, X86Mem, Imm)                         // SSE4_1
+    1356             :   ASMJIT_INST_3i(pinsrw, Pinsrw, X86Mm, X86Gp, Imm)                           // SSE
+    1357             :   ASMJIT_INST_3i(pinsrw, Pinsrw, X86Mm, X86Mem, Imm)                          // SSE
+    1358             :   ASMJIT_INST_3i(pinsrw, Pinsrw, X86Xmm, X86Gp, Imm)                          // SSE2
+    1359             :   ASMJIT_INST_3i(pinsrw, Pinsrw, X86Xmm, X86Mem, Imm)                         // SSE2
+    1360             :   ASMJIT_INST_2x(pmaddubsw, Pmaddubsw, X86Mm, X86Mm)                          // SSSE3
+    1361             :   ASMJIT_INST_2x(pmaddubsw, Pmaddubsw, X86Mm, X86Mem)                         // SSSE3
+    1362             :   ASMJIT_INST_2x(pmaddubsw, Pmaddubsw, X86Xmm, X86Xmm)                        // SSSE3
+    1363             :   ASMJIT_INST_2x(pmaddubsw, Pmaddubsw, X86Xmm, X86Mem)                        // SSSE3
+    1364             :   ASMJIT_INST_2x(pmaddwd, Pmaddwd, X86Mm, X86Mm)                              // MMX
+    1365             :   ASMJIT_INST_2x(pmaddwd, Pmaddwd, X86Mm, X86Mem)                             // MMX
+    1366             :   ASMJIT_INST_2x(pmaddwd, Pmaddwd, X86Xmm, X86Xmm)                            // SSE2
+    1367             :   ASMJIT_INST_2x(pmaddwd, Pmaddwd, X86Xmm, X86Mem)                            // SSE2
+    1368             :   ASMJIT_INST_2x(pmaxsb, Pmaxsb, X86Xmm, X86Xmm)                              // SSE4_1
+    1369             :   ASMJIT_INST_2x(pmaxsb, Pmaxsb, X86Xmm, X86Mem)                              // SSE4_1
+    1370             :   ASMJIT_INST_2x(pmaxsd, Pmaxsd, X86Xmm, X86Xmm)                              // SSE4_1
+    1371             :   ASMJIT_INST_2x(pmaxsd, Pmaxsd, X86Xmm, X86Mem)                              // SSE4_1
+    1372             :   ASMJIT_INST_2x(pmaxsw, Pmaxsw, X86Mm, X86Mm)                                // SSE
+    1373             :   ASMJIT_INST_2x(pmaxsw, Pmaxsw, X86Mm, X86Mem)                               // SSE
+    1374             :   ASMJIT_INST_2x(pmaxsw, Pmaxsw, X86Xmm, X86Xmm)                              // SSE2
+    1375             :   ASMJIT_INST_2x(pmaxsw, Pmaxsw, X86Xmm, X86Mem)                              // SSE2
+    1376             :   ASMJIT_INST_2x(pmaxub, Pmaxub, X86Mm, X86Mm)                                // SSE
+    1377             :   ASMJIT_INST_2x(pmaxub, Pmaxub, X86Mm, X86Mem)                               // SSE
+    1378             :   ASMJIT_INST_2x(pmaxub, Pmaxub, X86Xmm, X86Xmm)                              // SSE2
+    1379             :   ASMJIT_INST_2x(pmaxub, Pmaxub, X86Xmm, X86Mem)                              // SSE2
+    1380             :   ASMJIT_INST_2x(pmaxud, Pmaxud, X86Xmm, X86Xmm)                              // SSE4_1
+    1381             :   ASMJIT_INST_2x(pmaxud, Pmaxud, X86Xmm, X86Mem)                              // SSE4_1
+    1382             :   ASMJIT_INST_2x(pmaxuw, Pmaxuw, X86Xmm, X86Xmm)                              // SSE4_1
+    1383             :   ASMJIT_INST_2x(pmaxuw, Pmaxuw, X86Xmm, X86Mem)                              // SSE4_1
+    1384             :   ASMJIT_INST_2x(pminsb, Pminsb, X86Xmm, X86Xmm)                              // SSE4_1
+    1385             :   ASMJIT_INST_2x(pminsb, Pminsb, X86Xmm, X86Mem)                              // SSE4_1
+    1386             :   ASMJIT_INST_2x(pminsd, Pminsd, X86Xmm, X86Xmm)                              // SSE4_1
+    1387             :   ASMJIT_INST_2x(pminsd, Pminsd, X86Xmm, X86Mem)                              // SSE4_1
+    1388             :   ASMJIT_INST_2x(pminsw, Pminsw, X86Mm, X86Mm)                                // SSE
+    1389             :   ASMJIT_INST_2x(pminsw, Pminsw, X86Mm, X86Mem)                               // SSE
+    1390             :   ASMJIT_INST_2x(pminsw, Pminsw, X86Xmm, X86Xmm)                              // SSE2
+    1391             :   ASMJIT_INST_2x(pminsw, Pminsw, X86Xmm, X86Mem)                              // SSE2
+    1392             :   ASMJIT_INST_2x(pminub, Pminub, X86Mm, X86Mm)                                // SSE
+    1393             :   ASMJIT_INST_2x(pminub, Pminub, X86Mm, X86Mem)                               // SSE
+    1394             :   ASMJIT_INST_2x(pminub, Pminub, X86Xmm, X86Xmm)                              // SSE2
+    1395             :   ASMJIT_INST_2x(pminub, Pminub, X86Xmm, X86Mem)                              // SSE2
+    1396             :   ASMJIT_INST_2x(pminud, Pminud, X86Xmm, X86Xmm)                              // SSE4_1
+    1397             :   ASMJIT_INST_2x(pminud, Pminud, X86Xmm, X86Mem)                              // SSE4_1
+    1398             :   ASMJIT_INST_2x(pminuw, Pminuw, X86Xmm, X86Xmm)                              // SSE4_1
+    1399             :   ASMJIT_INST_2x(pminuw, Pminuw, X86Xmm, X86Mem)                              // SSE4_1
+    1400             :   ASMJIT_INST_2x(pmovmskb, Pmovmskb, X86Gp, X86Mm)                            // SSE
+    1401             :   ASMJIT_INST_2x(pmovmskb, Pmovmskb, X86Gp, X86Xmm)                           // SSE2
+    1402             :   ASMJIT_INST_2x(pmovsxbd, Pmovsxbd, X86Xmm, X86Xmm)                          // SSE4_1
+    1403             :   ASMJIT_INST_2x(pmovsxbd, Pmovsxbd, X86Xmm, X86Mem)                          // SSE4_1
+    1404             :   ASMJIT_INST_2x(pmovsxbq, Pmovsxbq, X86Xmm, X86Xmm)                          // SSE4_1
+    1405             :   ASMJIT_INST_2x(pmovsxbq, Pmovsxbq, X86Xmm, X86Mem)                          // SSE4_1
+    1406             :   ASMJIT_INST_2x(pmovsxbw, Pmovsxbw, X86Xmm, X86Xmm)                          // SSE4_1
+    1407             :   ASMJIT_INST_2x(pmovsxbw, Pmovsxbw, X86Xmm, X86Mem)                          // SSE4_1
+    1408             :   ASMJIT_INST_2x(pmovsxdq, Pmovsxdq, X86Xmm, X86Xmm)                          // SSE4_1
+    1409             :   ASMJIT_INST_2x(pmovsxdq, Pmovsxdq, X86Xmm, X86Mem)                          // SSE4_1
+    1410             :   ASMJIT_INST_2x(pmovsxwd, Pmovsxwd, X86Xmm, X86Xmm)                          // SSE4_1
+    1411             :   ASMJIT_INST_2x(pmovsxwd, Pmovsxwd, X86Xmm, X86Mem)                          // SSE4_1
+    1412             :   ASMJIT_INST_2x(pmovsxwq, Pmovsxwq, X86Xmm, X86Xmm)                          // SSE4_1
+    1413             :   ASMJIT_INST_2x(pmovsxwq, Pmovsxwq, X86Xmm, X86Mem)                          // SSE4_1
+    1414             :   ASMJIT_INST_2x(pmovzxbd, Pmovzxbd, X86Xmm, X86Xmm)                          // SSE4_1
+    1415             :   ASMJIT_INST_2x(pmovzxbd, Pmovzxbd, X86Xmm, X86Mem)                          // SSE4_1
+    1416             :   ASMJIT_INST_2x(pmovzxbq, Pmovzxbq, X86Xmm, X86Xmm)                          // SSE4_1
+    1417             :   ASMJIT_INST_2x(pmovzxbq, Pmovzxbq, X86Xmm, X86Mem)                          // SSE4_1
+    1418             :   ASMJIT_INST_2x(pmovzxbw, Pmovzxbw, X86Xmm, X86Xmm)                          // SSE4_1
+    1419             :   ASMJIT_INST_2x(pmovzxbw, Pmovzxbw, X86Xmm, X86Mem)                          // SSE4_1
+    1420             :   ASMJIT_INST_2x(pmovzxdq, Pmovzxdq, X86Xmm, X86Xmm)                          // SSE4_1
+    1421             :   ASMJIT_INST_2x(pmovzxdq, Pmovzxdq, X86Xmm, X86Mem)                          // SSE4_1
+    1422             :   ASMJIT_INST_2x(pmovzxwd, Pmovzxwd, X86Xmm, X86Xmm)                          // SSE4_1
+    1423             :   ASMJIT_INST_2x(pmovzxwd, Pmovzxwd, X86Xmm, X86Mem)                          // SSE4_1
+    1424             :   ASMJIT_INST_2x(pmovzxwq, Pmovzxwq, X86Xmm, X86Xmm)                          // SSE4_1
+    1425             :   ASMJIT_INST_2x(pmovzxwq, Pmovzxwq, X86Xmm, X86Mem)                          // SSE4_1
+    1426             :   ASMJIT_INST_2x(pmuldq, Pmuldq, X86Xmm, X86Xmm)                              // SSE4_1
+    1427             :   ASMJIT_INST_2x(pmuldq, Pmuldq, X86Xmm, X86Mem)                              // SSE4_1
+    1428             :   ASMJIT_INST_2x(pmulhrsw, Pmulhrsw, X86Mm, X86Mm)                            // SSSE3
+    1429             :   ASMJIT_INST_2x(pmulhrsw, Pmulhrsw, X86Mm, X86Mem)                           // SSSE3
+    1430             :   ASMJIT_INST_2x(pmulhrsw, Pmulhrsw, X86Xmm, X86Xmm)                          // SSSE3
+    1431             :   ASMJIT_INST_2x(pmulhrsw, Pmulhrsw, X86Xmm, X86Mem)                          // SSSE3
+    1432             :   ASMJIT_INST_2x(pmulhw, Pmulhw, X86Mm, X86Mm)                                // MMX
+    1433             :   ASMJIT_INST_2x(pmulhw, Pmulhw, X86Mm, X86Mem)                               // MMX
+    1434             :   ASMJIT_INST_2x(pmulhw, Pmulhw, X86Xmm, X86Xmm)                              // SSE2
+    1435             :   ASMJIT_INST_2x(pmulhw, Pmulhw, X86Xmm, X86Mem)                              // SSE2
+    1436             :   ASMJIT_INST_2x(pmulhuw, Pmulhuw, X86Mm, X86Mm)                              // SSE
+    1437             :   ASMJIT_INST_2x(pmulhuw, Pmulhuw, X86Mm, X86Mem)                             // SSE
+    1438             :   ASMJIT_INST_2x(pmulhuw, Pmulhuw, X86Xmm, X86Xmm)                            // SSE2
+    1439             :   ASMJIT_INST_2x(pmulhuw, Pmulhuw, X86Xmm, X86Mem)                            // SSE2
+    1440             :   ASMJIT_INST_2x(pmulld, Pmulld, X86Xmm, X86Xmm)                              // SSE4_1
+    1441             :   ASMJIT_INST_2x(pmulld, Pmulld, X86Xmm, X86Mem)                              // SSE4_1
+    1442             :   ASMJIT_INST_2x(pmullw, Pmullw, X86Mm, X86Mm)                                // MMX
+    1443             :   ASMJIT_INST_2x(pmullw, Pmullw, X86Mm, X86Mem)                               // MMX
+    1444             :   ASMJIT_INST_2x(pmullw, Pmullw, X86Xmm, X86Xmm)                              // SSE2
+    1445             :   ASMJIT_INST_2x(pmullw, Pmullw, X86Xmm, X86Mem)                              // SSE2
+    1446             :   ASMJIT_INST_2x(pmuludq, Pmuludq, X86Mm, X86Mm)                              // SSE2
+    1447             :   ASMJIT_INST_2x(pmuludq, Pmuludq, X86Mm, X86Mem)                             // SSE2
+    1448             :   ASMJIT_INST_2x(pmuludq, Pmuludq, X86Xmm, X86Xmm)                            // SSE2
+    1449             :   ASMJIT_INST_2x(pmuludq, Pmuludq, X86Xmm, X86Mem)                            // SSE2
+    1450             :   ASMJIT_INST_2x(por, Por, X86Mm, X86Mm)                                      // MMX
+    1451             :   ASMJIT_INST_2x(por, Por, X86Mm, X86Mem)                                     // MMX
+    1452             :   ASMJIT_INST_2x(por, Por, X86Xmm, X86Xmm)                                    // SSE2
+    1453             :   ASMJIT_INST_2x(por, Por, X86Xmm, X86Mem)                                    // SSE2
+    1454             :   ASMJIT_INST_2x(psadbw, Psadbw, X86Mm, X86Mm)                                // SSE
+    1455             :   ASMJIT_INST_2x(psadbw, Psadbw, X86Mm, X86Mem)                               // SSE
+    1456             :   ASMJIT_INST_2x(psadbw, Psadbw, X86Xmm, X86Xmm)                              // SSE
+    1457             :   ASMJIT_INST_2x(psadbw, Psadbw, X86Xmm, X86Mem)                              // SSE
+    1458             :   ASMJIT_INST_2x(pslld, Pslld, X86Mm, X86Mm)                                  // MMX
+    1459             :   ASMJIT_INST_2x(pslld, Pslld, X86Mm, X86Mem)                                 // MMX
+    1460             :   ASMJIT_INST_2i(pslld, Pslld, X86Mm, Imm)                                    // MMX
+    1461             :   ASMJIT_INST_2x(pslld, Pslld, X86Xmm, X86Xmm)                                // SSE2
+    1462             :   ASMJIT_INST_2x(pslld, Pslld, X86Xmm, X86Mem)                                // SSE2
+    1463             :   ASMJIT_INST_2i(pslld, Pslld, X86Xmm, Imm)                                   // SSE2
+    1464             :   ASMJIT_INST_2i(pslldq, Pslldq, X86Xmm, Imm)                                 // SSE2
+    1465             :   ASMJIT_INST_2x(psllq, Psllq, X86Mm, X86Mm)                                  // MMX
+    1466             :   ASMJIT_INST_2x(psllq, Psllq, X86Mm, X86Mem)                                 // MMX
+    1467             :   ASMJIT_INST_2i(psllq, Psllq, X86Mm, Imm)                                    // MMX
+    1468             :   ASMJIT_INST_2x(psllq, Psllq, X86Xmm, X86Xmm)                                // SSE2
+    1469             :   ASMJIT_INST_2x(psllq, Psllq, X86Xmm, X86Mem)                                // SSE2
+    1470             :   ASMJIT_INST_2i(psllq, Psllq, X86Xmm, Imm)                                   // SSE2
+    1471             :   ASMJIT_INST_2x(psllw, Psllw, X86Mm, X86Mm)                                  // MMX
+    1472             :   ASMJIT_INST_2x(psllw, Psllw, X86Mm, X86Mem)                                 // MMX
+    1473             :   ASMJIT_INST_2i(psllw, Psllw, X86Mm, Imm)                                    // MMX
+    1474             :   ASMJIT_INST_2x(psllw, Psllw, X86Xmm, X86Xmm)                                // SSE2
+    1475             :   ASMJIT_INST_2x(psllw, Psllw, X86Xmm, X86Mem)                                // SSE2
+    1476             :   ASMJIT_INST_2i(psllw, Psllw, X86Xmm, Imm)                                   // SSE2
+    1477             :   ASMJIT_INST_2x(psrad, Psrad, X86Mm, X86Mm)                                  // MMX
+    1478             :   ASMJIT_INST_2x(psrad, Psrad, X86Mm, X86Mem)                                 // MMX
+    1479             :   ASMJIT_INST_2i(psrad, Psrad, X86Mm, Imm)                                    // MMX
+    1480             :   ASMJIT_INST_2x(psrad, Psrad, X86Xmm, X86Xmm)                                // SSE2
+    1481             :   ASMJIT_INST_2x(psrad, Psrad, X86Xmm, X86Mem)                                // SSE2
+    1482             :   ASMJIT_INST_2i(psrad, Psrad, X86Xmm, Imm)                                   // SSE2
+    1483             :   ASMJIT_INST_2x(psraw, Psraw, X86Mm, X86Mm)                                  // MMX
+    1484             :   ASMJIT_INST_2x(psraw, Psraw, X86Mm, X86Mem)                                 // MMX
+    1485             :   ASMJIT_INST_2i(psraw, Psraw, X86Mm, Imm)                                    // MMX
+    1486             :   ASMJIT_INST_2x(psraw, Psraw, X86Xmm, X86Xmm)                                // SSE2
+    1487             :   ASMJIT_INST_2x(psraw, Psraw, X86Xmm, X86Mem)                                // SSE2
+    1488             :   ASMJIT_INST_2i(psraw, Psraw, X86Xmm, Imm)                                   // SSE2
+    1489             :   ASMJIT_INST_2x(pshufb, Pshufb, X86Mm, X86Mm)                                // SSSE3
+    1490             :   ASMJIT_INST_2x(pshufb, Pshufb, X86Mm, X86Mem)                               // SSSE3
+    1491             :   ASMJIT_INST_2x(pshufb, Pshufb, X86Xmm, X86Xmm)                              // SSSE3
+    1492             :   ASMJIT_INST_2x(pshufb, Pshufb, X86Xmm, X86Mem)                              // SSSE3
+    1493             :   ASMJIT_INST_3i(pshufd, Pshufd, X86Xmm, X86Xmm, Imm)                         // SSE2
+    1494             :   ASMJIT_INST_3i(pshufd, Pshufd, X86Xmm, X86Mem, Imm)                         // SSE2
+    1495             :   ASMJIT_INST_3i(pshufhw, Pshufhw, X86Xmm, X86Xmm, Imm)                       // SSE2
+    1496             :   ASMJIT_INST_3i(pshufhw, Pshufhw, X86Xmm, X86Mem, Imm)                       // SSE2
+    1497             :   ASMJIT_INST_3i(pshuflw, Pshuflw, X86Xmm, X86Xmm, Imm)                       // SSE2
+    1498             :   ASMJIT_INST_3i(pshuflw, Pshuflw, X86Xmm, X86Mem, Imm)                       // SSE2
+    1499             :   ASMJIT_INST_3i(pshufw, Pshufw, X86Mm, X86Mm, Imm)                           // SSE
+    1500             :   ASMJIT_INST_3i(pshufw, Pshufw, X86Mm, X86Mem, Imm)                          // SSE
+    1501             :   ASMJIT_INST_2x(psignb, Psignb, X86Mm, X86Mm)                                // SSSE3
+    1502             :   ASMJIT_INST_2x(psignb, Psignb, X86Mm, X86Mem)                               // SSSE3
+    1503             :   ASMJIT_INST_2x(psignb, Psignb, X86Xmm, X86Xmm)                              // SSSE3
+    1504             :   ASMJIT_INST_2x(psignb, Psignb, X86Xmm, X86Mem)                              // SSSE3
+    1505             :   ASMJIT_INST_2x(psignd, Psignd, X86Mm, X86Mm)                                // SSSE3
+    1506             :   ASMJIT_INST_2x(psignd, Psignd, X86Mm, X86Mem)                               // SSSE3
+    1507             :   ASMJIT_INST_2x(psignd, Psignd, X86Xmm, X86Xmm)                              // SSSE3
+    1508             :   ASMJIT_INST_2x(psignd, Psignd, X86Xmm, X86Mem)                              // SSSE3
+    1509             :   ASMJIT_INST_2x(psignw, Psignw, X86Mm, X86Mm)                                // SSSE3
+    1510             :   ASMJIT_INST_2x(psignw, Psignw, X86Mm, X86Mem)                               // SSSE3
+    1511             :   ASMJIT_INST_2x(psignw, Psignw, X86Xmm, X86Xmm)                              // SSSE3
+    1512             :   ASMJIT_INST_2x(psignw, Psignw, X86Xmm, X86Mem)                              // SSSE3
+    1513             :   ASMJIT_INST_2x(psrld, Psrld, X86Mm, X86Mm)                                  // MMX
+    1514             :   ASMJIT_INST_2x(psrld, Psrld, X86Mm, X86Mem)                                 // MMX
+    1515             :   ASMJIT_INST_2i(psrld, Psrld, X86Mm, Imm)                                    // MMX
+    1516             :   ASMJIT_INST_2x(psrld, Psrld, X86Xmm, X86Xmm)                                // SSE2
+    1517             :   ASMJIT_INST_2x(psrld, Psrld, X86Xmm, X86Mem)                                // SSE2
+    1518             :   ASMJIT_INST_2i(psrld, Psrld, X86Xmm, Imm)                                   // SSE2
+    1519             :   ASMJIT_INST_2i(psrldq, Psrldq, X86Xmm, Imm)                                 // SSE2
+    1520             :   ASMJIT_INST_2x(psrlq, Psrlq, X86Mm, X86Mm)                                  // MMX
+    1521             :   ASMJIT_INST_2x(psrlq, Psrlq, X86Mm, X86Mem)                                 // MMX
+    1522             :   ASMJIT_INST_2i(psrlq, Psrlq, X86Mm, Imm)                                    // MMX
+    1523             :   ASMJIT_INST_2x(psrlq, Psrlq, X86Xmm, X86Xmm)                                // SSE2
+    1524             :   ASMJIT_INST_2x(psrlq, Psrlq, X86Xmm, X86Mem)                                // SSE2
+    1525             :   ASMJIT_INST_2i(psrlq, Psrlq, X86Xmm, Imm)                                   // SSE2
+    1526             :   ASMJIT_INST_2x(psrlw, Psrlw, X86Mm, X86Mm)                                  // MMX
+    1527             :   ASMJIT_INST_2x(psrlw, Psrlw, X86Mm, X86Mem)                                 // MMX
+    1528             :   ASMJIT_INST_2i(psrlw, Psrlw, X86Mm, Imm)                                    // MMX
+    1529             :   ASMJIT_INST_2x(psrlw, Psrlw, X86Xmm, X86Xmm)                                // SSE2
+    1530             :   ASMJIT_INST_2x(psrlw, Psrlw, X86Xmm, X86Mem)                                // SSE2
+    1531             :   ASMJIT_INST_2i(psrlw, Psrlw, X86Xmm, Imm)                                   // SSE2
+    1532             :   ASMJIT_INST_2x(psubb, Psubb, X86Mm, X86Mm)                                  // MMX
+    1533             :   ASMJIT_INST_2x(psubb, Psubb, X86Mm, X86Mem)                                 // MMX
+    1534             :   ASMJIT_INST_2x(psubb, Psubb, X86Xmm, X86Xmm)                                // SSE2
+    1535             :   ASMJIT_INST_2x(psubb, Psubb, X86Xmm, X86Mem)                                // SSE2
+    1536             :   ASMJIT_INST_2x(psubd, Psubd, X86Mm, X86Mm)                                  // MMX
+    1537             :   ASMJIT_INST_2x(psubd, Psubd, X86Mm, X86Mem)                                 // MMX
+    1538             :   ASMJIT_INST_2x(psubd, Psubd, X86Xmm, X86Xmm)                                // SSE2
+    1539             :   ASMJIT_INST_2x(psubd, Psubd, X86Xmm, X86Mem)                                // SSE2
+    1540             :   ASMJIT_INST_2x(psubq, Psubq, X86Mm, X86Mm)                                  // SSE2
+    1541             :   ASMJIT_INST_2x(psubq, Psubq, X86Mm, X86Mem)                                 // SSE2
+    1542             :   ASMJIT_INST_2x(psubq, Psubq, X86Xmm, X86Xmm)                                // SSE2
+    1543             :   ASMJIT_INST_2x(psubq, Psubq, X86Xmm, X86Mem)                                // SSE2
+    1544             :   ASMJIT_INST_2x(psubsb, Psubsb, X86Mm, X86Mm)                                // MMX
+    1545             :   ASMJIT_INST_2x(psubsb, Psubsb, X86Mm, X86Mem)                               // MMX
+    1546             :   ASMJIT_INST_2x(psubsb, Psubsb, X86Xmm, X86Xmm)                              // SSE2
+    1547             :   ASMJIT_INST_2x(psubsb, Psubsb, X86Xmm, X86Mem)                              // SSE2
+    1548             :   ASMJIT_INST_2x(psubsw, Psubsw, X86Mm, X86Mm)                                // MMX
+    1549             :   ASMJIT_INST_2x(psubsw, Psubsw, X86Mm, X86Mem)                               // MMX
+    1550             :   ASMJIT_INST_2x(psubsw, Psubsw, X86Xmm, X86Xmm)                              // SSE2
+    1551             :   ASMJIT_INST_2x(psubsw, Psubsw, X86Xmm, X86Mem)                              // SSE2
+    1552             :   ASMJIT_INST_2x(psubusb, Psubusb, X86Mm, X86Mm)                              // MMX
+    1553             :   ASMJIT_INST_2x(psubusb, Psubusb, X86Mm, X86Mem)                             // MMX
+    1554             :   ASMJIT_INST_2x(psubusb, Psubusb, X86Xmm, X86Xmm)                            // SSE2
+    1555             :   ASMJIT_INST_2x(psubusb, Psubusb, X86Xmm, X86Mem)                            // SSE2
+    1556             :   ASMJIT_INST_2x(psubusw, Psubusw, X86Mm, X86Mm)                              // MMX
+    1557             :   ASMJIT_INST_2x(psubusw, Psubusw, X86Mm, X86Mem)                             // MMX
+    1558             :   ASMJIT_INST_2x(psubusw, Psubusw, X86Xmm, X86Xmm)                            // SSE2
+    1559             :   ASMJIT_INST_2x(psubusw, Psubusw, X86Xmm, X86Mem)                            // SSE2
+    1560             :   ASMJIT_INST_2x(psubw, Psubw, X86Mm, X86Mm)                                  // MMX
+    1561             :   ASMJIT_INST_2x(psubw, Psubw, X86Mm, X86Mem)                                 // MMX
+    1562             :   ASMJIT_INST_2x(psubw, Psubw, X86Xmm, X86Xmm)                                // SSE2
+    1563             :   ASMJIT_INST_2x(psubw, Psubw, X86Xmm, X86Mem)                                // SSE2
+    1564             :   ASMJIT_INST_2x(ptest, Ptest, X86Xmm, X86Xmm)                                // SSE4_1
+    1565             :   ASMJIT_INST_2x(ptest, Ptest, X86Xmm, X86Mem)                                // SSE4_1
+    1566             :   ASMJIT_INST_2x(punpckhbw, Punpckhbw, X86Mm, X86Mm)                          // MMX
+    1567             :   ASMJIT_INST_2x(punpckhbw, Punpckhbw, X86Mm, X86Mem)                         // MMX
+    1568             :   ASMJIT_INST_2x(punpckhbw, Punpckhbw, X86Xmm, X86Xmm)                        // SSE2
+    1569             :   ASMJIT_INST_2x(punpckhbw, Punpckhbw, X86Xmm, X86Mem)                        // SSE2
+    1570             :   ASMJIT_INST_2x(punpckhdq, Punpckhdq, X86Mm, X86Mm)                          // MMX
+    1571             :   ASMJIT_INST_2x(punpckhdq, Punpckhdq, X86Mm, X86Mem)                         // MMX
+    1572             :   ASMJIT_INST_2x(punpckhdq, Punpckhdq, X86Xmm, X86Xmm)                        // SSE2
+    1573             :   ASMJIT_INST_2x(punpckhdq, Punpckhdq, X86Xmm, X86Mem)                        // SSE2
+    1574             :   ASMJIT_INST_2x(punpckhqdq, Punpckhqdq, X86Xmm, X86Xmm)                      // SSE2
+    1575             :   ASMJIT_INST_2x(punpckhqdq, Punpckhqdq, X86Xmm, X86Mem)                      // SSE2
+    1576             :   ASMJIT_INST_2x(punpckhwd, Punpckhwd, X86Mm, X86Mm)                          // MMX
+    1577             :   ASMJIT_INST_2x(punpckhwd, Punpckhwd, X86Mm, X86Mem)                         // MMX
+    1578             :   ASMJIT_INST_2x(punpckhwd, Punpckhwd, X86Xmm, X86Xmm)                        // SSE2
+    1579             :   ASMJIT_INST_2x(punpckhwd, Punpckhwd, X86Xmm, X86Mem)                        // SSE2
+    1580             :   ASMJIT_INST_2x(punpcklbw, Punpcklbw, X86Mm, X86Mm)                          // MMX
+    1581             :   ASMJIT_INST_2x(punpcklbw, Punpcklbw, X86Mm, X86Mem)                         // MMX
+    1582             :   ASMJIT_INST_2x(punpcklbw, Punpcklbw, X86Xmm, X86Xmm)                        // SSE2
+    1583             :   ASMJIT_INST_2x(punpcklbw, Punpcklbw, X86Xmm, X86Mem)                        // SSE2
+    1584             :   ASMJIT_INST_2x(punpckldq, Punpckldq, X86Mm, X86Mm)                          // MMX
+    1585             :   ASMJIT_INST_2x(punpckldq, Punpckldq, X86Mm, X86Mem)                         // MMX
+    1586             :   ASMJIT_INST_2x(punpckldq, Punpckldq, X86Xmm, X86Xmm)                        // SSE2
+    1587             :   ASMJIT_INST_2x(punpckldq, Punpckldq, X86Xmm, X86Mem)                        // SSE2
+    1588             :   ASMJIT_INST_2x(punpcklqdq, Punpcklqdq, X86Xmm, X86Xmm)                      // SSE2
+    1589             :   ASMJIT_INST_2x(punpcklqdq, Punpcklqdq, X86Xmm, X86Mem)                      // SSE2
+    1590             :   ASMJIT_INST_2x(punpcklwd, Punpcklwd, X86Mm, X86Mm)                          // MMX
+    1591             :   ASMJIT_INST_2x(punpcklwd, Punpcklwd, X86Mm, X86Mem)                         // MMX
+    1592             :   ASMJIT_INST_2x(punpcklwd, Punpcklwd, X86Xmm, X86Xmm)                        // SSE2
+    1593             :   ASMJIT_INST_2x(punpcklwd, Punpcklwd, X86Xmm, X86Mem)                        // SSE2
+    1594             :   ASMJIT_INST_2x(pxor, Pxor, X86Mm, X86Mm)                                    // MMX
+    1595             :   ASMJIT_INST_2x(pxor, Pxor, X86Mm, X86Mem)                                   // MMX
+    1596             :   ASMJIT_INST_2x(pxor, Pxor, X86Xmm, X86Xmm)                                  // SSE2
+    1597             :   ASMJIT_INST_2x(pxor, Pxor, X86Xmm, X86Mem)                                  // SSE2
+    1598             :   ASMJIT_INST_2x(rcpps, Rcpps, X86Xmm, X86Xmm)                                // SSE
+    1599             :   ASMJIT_INST_2x(rcpps, Rcpps, X86Xmm, X86Mem)                                // SSE
+    1600             :   ASMJIT_INST_2x(rcpss, Rcpss, X86Xmm, X86Xmm)                                // SSE
+    1601             :   ASMJIT_INST_2x(rcpss, Rcpss, X86Xmm, X86Mem)                                // SSE
+    1602             :   ASMJIT_INST_3i(roundpd, Roundpd, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1603             :   ASMJIT_INST_3i(roundpd, Roundpd, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1604             :   ASMJIT_INST_3i(roundps, Roundps, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1605             :   ASMJIT_INST_3i(roundps, Roundps, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1606             :   ASMJIT_INST_3i(roundsd, Roundsd, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1607             :   ASMJIT_INST_3i(roundsd, Roundsd, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1608             :   ASMJIT_INST_3i(roundss, Roundss, X86Xmm, X86Xmm, Imm)                       // SSE4_1
+    1609             :   ASMJIT_INST_3i(roundss, Roundss, X86Xmm, X86Mem, Imm)                       // SSE4_1
+    1610             :   ASMJIT_INST_2x(rsqrtps, Rsqrtps, X86Xmm, X86Xmm)                            // SSE
+    1611             :   ASMJIT_INST_2x(rsqrtps, Rsqrtps, X86Xmm, X86Mem)                            // SSE
+    1612             :   ASMJIT_INST_2x(rsqrtss, Rsqrtss, X86Xmm, X86Xmm)                            // SSE
+    1613             :   ASMJIT_INST_2x(rsqrtss, Rsqrtss, X86Xmm, X86Mem)                            // SSE
+    1614             :   ASMJIT_INST_3i(shufpd, Shufpd, X86Xmm, X86Xmm, Imm)                         // SSE2
+    1615             :   ASMJIT_INST_3i(shufpd, Shufpd, X86Xmm, X86Mem, Imm)                         // SSE2
+    1616             :   ASMJIT_INST_3i(shufps, Shufps, X86Xmm, X86Xmm, Imm)                         // SSE
+    1617             :   ASMJIT_INST_3i(shufps, Shufps, X86Xmm, X86Mem, Imm)                         // SSE
+    1618             :   ASMJIT_INST_2x(sqrtpd, Sqrtpd, X86Xmm, X86Xmm)                              // SSE2
+    1619             :   ASMJIT_INST_2x(sqrtpd, Sqrtpd, X86Xmm, X86Mem)                              // SSE2
+    1620             :   ASMJIT_INST_2x(sqrtps, Sqrtps, X86Xmm, X86Xmm)                              // SSE
+    1621             :   ASMJIT_INST_2x(sqrtps, Sqrtps, X86Xmm, X86Mem)                              // SSE
+    1622         126 :   ASMJIT_INST_2x(sqrtsd, Sqrtsd, X86Xmm, X86Xmm)                              // SSE2
+    1623             :   ASMJIT_INST_2x(sqrtsd, Sqrtsd, X86Xmm, X86Mem)                              // SSE2
+    1624             :   ASMJIT_INST_2x(sqrtss, Sqrtss, X86Xmm, X86Xmm)                              // SSE
+    1625             :   ASMJIT_INST_2x(sqrtss, Sqrtss, X86Xmm, X86Mem)                              // SSE
+    1626             :   ASMJIT_INST_2x(subpd, Subpd, X86Xmm, X86Xmm)                                // SSE2
+    1627             :   ASMJIT_INST_2x(subpd, Subpd, X86Xmm, X86Mem)                                // SSE2
+    1628             :   ASMJIT_INST_2x(subps, Subps, X86Xmm, X86Xmm)                                // SSE
+    1629             :   ASMJIT_INST_2x(subps, Subps, X86Xmm, X86Mem)                                // SSE
+    1630         990 :   ASMJIT_INST_2x(subsd, Subsd, X86Xmm, X86Xmm)                                // SSE2
+    1631             :   ASMJIT_INST_2x(subsd, Subsd, X86Xmm, X86Mem)                                // SSE2
+    1632             :   ASMJIT_INST_2x(subss, Subss, X86Xmm, X86Xmm)                                // SSE
+    1633             :   ASMJIT_INST_2x(subss, Subss, X86Xmm, X86Mem)                                // SSE
+    1634             :   ASMJIT_INST_2x(ucomisd, Ucomisd, X86Xmm, X86Xmm)                            // SSE2
+    1635             :   ASMJIT_INST_2x(ucomisd, Ucomisd, X86Xmm, X86Mem)                            // SSE2
+    1636             :   ASMJIT_INST_2x(ucomiss, Ucomiss, X86Xmm, X86Xmm)                            // SSE
+    1637             :   ASMJIT_INST_2x(ucomiss, Ucomiss, X86Xmm, X86Mem)                            // SSE
+    1638             :   ASMJIT_INST_2x(unpckhpd, Unpckhpd, X86Xmm, X86Xmm)                          // SSE2
+    1639             :   ASMJIT_INST_2x(unpckhpd, Unpckhpd, X86Xmm, X86Mem)                          // SSE2
+    1640             :   ASMJIT_INST_2x(unpckhps, Unpckhps, X86Xmm, X86Xmm)                          // SSE
+    1641             :   ASMJIT_INST_2x(unpckhps, Unpckhps, X86Xmm, X86Mem)                          // SSE
+    1642             :   ASMJIT_INST_2x(unpcklpd, Unpcklpd, X86Xmm, X86Xmm)                          // SSE2
+    1643             :   ASMJIT_INST_2x(unpcklpd, Unpcklpd, X86Xmm, X86Mem)                          // SSE2
+    1644             :   ASMJIT_INST_2x(unpcklps, Unpcklps, X86Xmm, X86Xmm)                          // SSE
+    1645             :   ASMJIT_INST_2x(unpcklps, Unpcklps, X86Xmm, X86Mem)                          // SSE
+    1646             :   ASMJIT_INST_2x(xorpd, Xorpd, X86Xmm, X86Xmm)                                // SSE2
+    1647             :   ASMJIT_INST_2x(xorpd, Xorpd, X86Xmm, X86Mem)                                // SSE2
+    1648         248 :   ASMJIT_INST_2x(xorps, Xorps, X86Xmm, X86Xmm)                                // SSE
+    1649             :   ASMJIT_INST_2x(xorps, Xorps, X86Xmm, X86Mem)                                // SSE
+    1650             : 
+    1651             :   // -------------------------------------------------------------------------
+    1652             :   // [3DNOW & GEODE]
+    1653             :   // -------------------------------------------------------------------------
+    1654             : 
+    1655             :   ASMJIT_INST_2x(pavgusb, Pavgusb, X86Mm, X86Mm)                              // 3DNOW
+    1656             :   ASMJIT_INST_2x(pavgusb, Pavgusb, X86Mm, X86Mem)                             // 3DNOW
+    1657             :   ASMJIT_INST_2x(pf2id, Pf2id, X86Mm, X86Mm)                                  // 3DNOW
+    1658             :   ASMJIT_INST_2x(pf2id, Pf2id, X86Mm, X86Mem)                                 // 3DNOW
+    1659             :   ASMJIT_INST_2x(pf2iw, Pf2iw, X86Mm, X86Mm)                                  // 3DNOW
+    1660             :   ASMJIT_INST_2x(pf2iw, Pf2iw, X86Mm, X86Mem)                                 // 3DNOW
+    1661             :   ASMJIT_INST_2x(pfacc, Pfacc, X86Mm, X86Mm)                                  // 3DNOW
+    1662             :   ASMJIT_INST_2x(pfacc, Pfacc, X86Mm, X86Mem)                                 // 3DNOW
+    1663             :   ASMJIT_INST_2x(pfadd, Pfadd, X86Mm, X86Mm)                                  // 3DNOW
+    1664             :   ASMJIT_INST_2x(pfadd, Pfadd, X86Mm, X86Mem)                                 // 3DNOW
+    1665             :   ASMJIT_INST_2x(pfcmpeq, Pfcmpeq, X86Mm, X86Mm)                              // 3DNOW
+    1666             :   ASMJIT_INST_2x(pfcmpeq, Pfcmpeq, X86Mm, X86Mem)                             // 3DNOW
+    1667             :   ASMJIT_INST_2x(pfcmpge, Pfcmpge, X86Mm, X86Mm)                              // 3DNOW
+    1668             :   ASMJIT_INST_2x(pfcmpge, Pfcmpge, X86Mm, X86Mem)                             // 3DNOW
+    1669             :   ASMJIT_INST_2x(pfcmpgt, Pfcmpgt, X86Mm, X86Mm)                              // 3DNOW
+    1670             :   ASMJIT_INST_2x(pfcmpgt, Pfcmpgt, X86Mm, X86Mem)                             // 3DNOW
+    1671             :   ASMJIT_INST_2x(pfmax, Pfmax, X86Mm, X86Mm)                                  // 3DNOW
+    1672             :   ASMJIT_INST_2x(pfmax, Pfmax, X86Mm, X86Mem)                                 // 3DNOW
+    1673             :   ASMJIT_INST_2x(pfmin, Pfmin, X86Mm, X86Mm)                                  // 3DNOW
+    1674             :   ASMJIT_INST_2x(pfmin, Pfmin, X86Mm, X86Mem)                                 // 3DNOW
+    1675             :   ASMJIT_INST_2x(pfmul, Pfmul, X86Mm, X86Mm)                                  // 3DNOW
+    1676             :   ASMJIT_INST_2x(pfmul, Pfmul, X86Mm, X86Mem)                                 // 3DNOW
+    1677             :   ASMJIT_INST_2x(pfnacc, Pfnacc, X86Mm, X86Mm)                                // 3DNOW
+    1678             :   ASMJIT_INST_2x(pfnacc, Pfnacc, X86Mm, X86Mem)                               // 3DNOW
+    1679             :   ASMJIT_INST_2x(pfpnacc, Pfpnacc, X86Mm, X86Mm)                              // 3DNOW
+    1680             :   ASMJIT_INST_2x(pfpnacc, Pfpnacc, X86Mm, X86Mem)                             // 3DNOW
+    1681             :   ASMJIT_INST_2x(pfrcp, Pfrcp, X86Mm, X86Mm)                                  // 3DNOW
+    1682             :   ASMJIT_INST_2x(pfrcp, Pfrcp, X86Mm, X86Mem)                                 // 3DNOW
+    1683             :   ASMJIT_INST_2x(pfrcpit1, Pfrcpit1, X86Mm, X86Mm)                            // 3DNOW
+    1684             :   ASMJIT_INST_2x(pfrcpit1, Pfrcpit1, X86Mm, X86Mem)                           // 3DNOW
+    1685             :   ASMJIT_INST_2x(pfrcpit2, Pfrcpit2, X86Mm, X86Mm)                            // 3DNOW
+    1686             :   ASMJIT_INST_2x(pfrcpit2, Pfrcpit2, X86Mm, X86Mem)                           // 3DNOW
+    1687             :   ASMJIT_INST_2x(pfrcpv, Pfrcpv, X86Mm, X86Mm)                                // GEODE
+    1688             :   ASMJIT_INST_2x(pfrcpv, Pfrcpv, X86Mm, X86Mem)                               // GEODE
+    1689             :   ASMJIT_INST_2x(pfrsqit1, Pfrsqit1, X86Mm, X86Mm)                            // 3DNOW
+    1690             :   ASMJIT_INST_2x(pfrsqit1, Pfrsqit1, X86Mm, X86Mem)                           // 3DNOW
+    1691             :   ASMJIT_INST_2x(pfrsqrt, Pfrsqrt, X86Mm, X86Mm)                              // 3DNOW
+    1692             :   ASMJIT_INST_2x(pfrsqrt, Pfrsqrt, X86Mm, X86Mem)                             // 3DNOW
+    1693             :   ASMJIT_INST_2x(pfrsqrtv, Pfrsqrtv, X86Mm, X86Mm)                            // GEODE
+    1694             :   ASMJIT_INST_2x(pfrsqrtv, Pfrsqrtv, X86Mm, X86Mem)                           // GEODE
+    1695             :   ASMJIT_INST_2x(pfsub, Pfsub, X86Mm, X86Mm)                                  // 3DNOW
+    1696             :   ASMJIT_INST_2x(pfsub, Pfsub, X86Mm, X86Mem)                                 // 3DNOW
+    1697             :   ASMJIT_INST_2x(pfsubr, Pfsubr, X86Mm, X86Mm)                                // 3DNOW
+    1698             :   ASMJIT_INST_2x(pfsubr, Pfsubr, X86Mm, X86Mem)                               // 3DNOW
+    1699             :   ASMJIT_INST_2x(pi2fd, Pi2fd, X86Mm, X86Mm)                                  // 3DNOW
+    1700             :   ASMJIT_INST_2x(pi2fd, Pi2fd, X86Mm, X86Mem)                                 // 3DNOW
+    1701             :   ASMJIT_INST_2x(pi2fw, Pi2fw, X86Mm, X86Mm)                                  // 3DNOW
+    1702             :   ASMJIT_INST_2x(pi2fw, Pi2fw, X86Mm, X86Mem)                                 // 3DNOW
+    1703             :   ASMJIT_INST_2x(pmulhrw, Pmulhrw, X86Mm, X86Mm)                              // 3DNOW
+    1704             :   ASMJIT_INST_2x(pmulhrw, Pmulhrw, X86Mm, X86Mem)                             // 3DNOW
+    1705             :   ASMJIT_INST_2x(pswapd, Pswapd, X86Mm, X86Mm)                                // 3DNOW
+    1706             :   ASMJIT_INST_2x(pswapd, Pswapd, X86Mm, X86Mem)                               // 3DNOW
+    1707             :   ASMJIT_INST_0x(femms, Femms)                                                // 3DNOW
+    1708             : 
+    1709             :   // --------------------------------------------------------------------------
+    1710             :   // [AESNI]
+    1711             :   // --------------------------------------------------------------------------
+    1712             : 
+    1713             :   ASMJIT_INST_2x(aesdec, Aesdec, X86Xmm, X86Xmm)                              // AESNI
+    1714             :   ASMJIT_INST_2x(aesdec, Aesdec, X86Xmm, X86Mem)                              // AESNI
+    1715             :   ASMJIT_INST_2x(aesdeclast, Aesdeclast, X86Xmm, X86Xmm)                      // AESNI
+    1716             :   ASMJIT_INST_2x(aesdeclast, Aesdeclast, X86Xmm, X86Mem)                      // AESNI
+    1717             :   ASMJIT_INST_2x(aesenc, Aesenc, X86Xmm, X86Xmm)                              // AESNI
+    1718             :   ASMJIT_INST_2x(aesenc, Aesenc, X86Xmm, X86Mem)                              // AESNI
+    1719             :   ASMJIT_INST_2x(aesenclast, Aesenclast, X86Xmm, X86Xmm)                      // AESNI
+    1720             :   ASMJIT_INST_2x(aesenclast, Aesenclast, X86Xmm, X86Mem)                      // AESNI
+    1721             :   ASMJIT_INST_2x(aesimc, Aesimc, X86Xmm, X86Xmm)                              // AESNI
+    1722             :   ASMJIT_INST_2x(aesimc, Aesimc, X86Xmm, X86Mem)                              // AESNI
+    1723             :   ASMJIT_INST_3i(aeskeygenassist, Aeskeygenassist, X86Xmm, X86Xmm, Imm)       // AESNI
+    1724             :   ASMJIT_INST_3i(aeskeygenassist, Aeskeygenassist, X86Xmm, X86Mem, Imm)       // AESNI
+    1725             : 
+    1726             :   // --------------------------------------------------------------------------
+    1727             :   // [SHA]
+    1728             :   // --------------------------------------------------------------------------
+    1729             : 
+    1730             :   ASMJIT_INST_2x(sha1msg1, Sha1msg1, X86Xmm, X86Xmm)                          // SHA
+    1731             :   ASMJIT_INST_2x(sha1msg1, Sha1msg1, X86Xmm, X86Mem)                          // SHA
+    1732             :   ASMJIT_INST_2x(sha1msg2, Sha1msg2, X86Xmm, X86Xmm)                          // SHA
+    1733             :   ASMJIT_INST_2x(sha1msg2, Sha1msg2, X86Xmm, X86Mem)                          // SHA
+    1734             :   ASMJIT_INST_2x(sha1nexte, Sha1nexte, X86Xmm, X86Xmm)                        // SHA
+    1735             :   ASMJIT_INST_2x(sha1nexte, Sha1nexte, X86Xmm, X86Mem)                        // SHA
+    1736             :   ASMJIT_INST_3i(sha1rnds4, Sha1rnds4, X86Xmm, X86Xmm, Imm)                   // SHA
+    1737             :   ASMJIT_INST_3i(sha1rnds4, Sha1rnds4, X86Xmm, X86Mem, Imm)                   // SHA
+    1738             :   ASMJIT_INST_2x(sha256msg1, Sha256msg1, X86Xmm, X86Xmm)                      // SHA
+    1739             :   ASMJIT_INST_2x(sha256msg1, Sha256msg1, X86Xmm, X86Mem)                      // SHA
+    1740             :   ASMJIT_INST_2x(sha256msg2, Sha256msg2, X86Xmm, X86Xmm)                      // SHA
+    1741             :   ASMJIT_INST_2x(sha256msg2, Sha256msg2, X86Xmm, X86Mem)                      // SHA
+    1742             :   ASMJIT_INST_3x(sha256rnds2, Sha256rnds2, X86Xmm, X86Xmm, XMM0)              // SHA [EXPLICIT]
+    1743             :   ASMJIT_INST_3x(sha256rnds2, Sha256rnds2, X86Xmm, X86Mem, XMM0)              // SHA [EXPLICIT]
+    1744             : 
+    1745             :   // --------------------------------------------------------------------------
+    1746             :   // [AVX...AVX512]
+    1747             :   // --------------------------------------------------------------------------
+    1748             : 
+    1749             :   ASMJIT_INST_3x(kaddb, Kaddb, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1750             :   ASMJIT_INST_3x(kaddd, Kaddd, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1751             :   ASMJIT_INST_3x(kaddq, Kaddq, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1752             :   ASMJIT_INST_3x(kaddw, Kaddw, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1753             :   ASMJIT_INST_3x(kandb, Kandb, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1754             :   ASMJIT_INST_3x(kandd, Kandd, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1755             :   ASMJIT_INST_3x(kandnb, Kandnb, X86KReg, X86KReg, X86KReg)                   // AVX512_DQ
+    1756             :   ASMJIT_INST_3x(kandnd, Kandnd, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1757             :   ASMJIT_INST_3x(kandnq, Kandnq, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1758             :   ASMJIT_INST_3x(kandnw, Kandnw, X86KReg, X86KReg, X86KReg)                   // AVX512_F
+    1759             :   ASMJIT_INST_3x(kandq, Kandq, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1760             :   ASMJIT_INST_3x(kandw, Kandw, X86KReg, X86KReg, X86KReg)                     // AVX512_F
+    1761             :   ASMJIT_INST_2x(kmovb, Kmovb, X86KReg, X86KReg)                              // AVX512_DQ
+    1762             :   ASMJIT_INST_2x(kmovb, Kmovb, X86KReg, X86Mem)                               // AVX512_DQ
+    1763             :   ASMJIT_INST_2x(kmovb, Kmovb, X86KReg, X86Gp)                                // AVX512_DQ
+    1764             :   ASMJIT_INST_2x(kmovb, Kmovb, X86Mem, X86KReg)                               // AVX512_DQ
+    1765             :   ASMJIT_INST_2x(kmovb, Kmovb, X86Gp, X86KReg)                                // AVX512_DQ
+    1766             :   ASMJIT_INST_2x(kmovd, Kmovd, X86KReg, X86KReg)                              // AVX512_BW
+    1767             :   ASMJIT_INST_2x(kmovd, Kmovd, X86KReg, X86Mem)                               // AVX512_BW
+    1768             :   ASMJIT_INST_2x(kmovd, Kmovd, X86KReg, X86Gp)                                // AVX512_BW
+    1769             :   ASMJIT_INST_2x(kmovd, Kmovd, X86Mem, X86KReg)                               // AVX512_BW
+    1770             :   ASMJIT_INST_2x(kmovd, Kmovd, X86Gp, X86KReg)                                // AVX512_BW
+    1771             :   ASMJIT_INST_2x(kmovq, Kmovq, X86KReg, X86KReg)                              // AVX512_BW
+    1772             :   ASMJIT_INST_2x(kmovq, Kmovq, X86KReg, X86Mem)                               // AVX512_BW
+    1773             :   ASMJIT_INST_2x(kmovq, Kmovq, X86KReg, X86Gp)                                // AVX512_BW
+    1774             :   ASMJIT_INST_2x(kmovq, Kmovq, X86Mem, X86KReg)                               // AVX512_BW
+    1775             :   ASMJIT_INST_2x(kmovq, Kmovq, X86Gp, X86KReg)                                // AVX512_BW
+    1776             :   ASMJIT_INST_2x(kmovw, Kmovw, X86KReg, X86KReg)                              // AVX512_F
+    1777             :   ASMJIT_INST_2x(kmovw, Kmovw, X86KReg, X86Mem)                               // AVX512_F
+    1778             :   ASMJIT_INST_2x(kmovw, Kmovw, X86KReg, X86Gp)                                // AVX512_F
+    1779             :   ASMJIT_INST_2x(kmovw, Kmovw, X86Mem, X86KReg)                               // AVX512_F
+    1780             :   ASMJIT_INST_2x(kmovw, Kmovw, X86Gp, X86KReg)                                // AVX512_F
+    1781             :   ASMJIT_INST_2x(knotb, Knotb, X86KReg, X86KReg)                              // AVX512_DQ
+    1782             :   ASMJIT_INST_2x(knotd, Knotd, X86KReg, X86KReg)                              // AVX512_BW
+    1783             :   ASMJIT_INST_2x(knotq, Knotq, X86KReg, X86KReg)                              // AVX512_BW
+    1784             :   ASMJIT_INST_2x(knotw, Knotw, X86KReg, X86KReg)                              // AVX512_F
+    1785             :   ASMJIT_INST_3x(korb, Korb, X86KReg, X86KReg, X86KReg)                       // AVX512_DQ
+    1786             :   ASMJIT_INST_3x(kord, Kord, X86KReg, X86KReg, X86KReg)                       // AVX512_BW
+    1787             :   ASMJIT_INST_3x(korq, Korq, X86KReg, X86KReg, X86KReg)                       // AVX512_BW
+    1788             :   ASMJIT_INST_2x(kortestb, Kortestb, X86KReg, X86KReg)                        // AVX512_DQ
+    1789             :   ASMJIT_INST_2x(kortestd, Kortestd, X86KReg, X86KReg)                        // AVX512_BW
+    1790             :   ASMJIT_INST_2x(kortestq, Kortestq, X86KReg, X86KReg)                        // AVX512_BW
+    1791             :   ASMJIT_INST_2x(kortestw, Kortestw, X86KReg, X86KReg)                        // AVX512_F
+    1792             :   ASMJIT_INST_3x(korw, Korw, X86KReg, X86KReg, X86KReg)                       // AVX512_F
+    1793             :   ASMJIT_INST_3i(kshiftlb, Kshiftlb, X86KReg, X86KReg, Imm)                   // AVX512_DQ
+    1794             :   ASMJIT_INST_3i(kshiftld, Kshiftld, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1795             :   ASMJIT_INST_3i(kshiftlq, Kshiftlq, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1796             :   ASMJIT_INST_3i(kshiftlw, Kshiftlw, X86KReg, X86KReg, Imm)                   // AVX512_F
+    1797             :   ASMJIT_INST_3i(kshiftrb, Kshiftrb, X86KReg, X86KReg, Imm)                   // AVX512_DQ
+    1798             :   ASMJIT_INST_3i(kshiftrd, Kshiftrd, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1799             :   ASMJIT_INST_3i(kshiftrq, Kshiftrq, X86KReg, X86KReg, Imm)                   // AVX512_BW
+    1800             :   ASMJIT_INST_3i(kshiftrw, Kshiftrw, X86KReg, X86KReg, Imm)                   // AVX512_F
+    1801             :   ASMJIT_INST_2x(ktestb, Ktestb, X86KReg, X86KReg)                            // AVX512_DQ
+    1802             :   ASMJIT_INST_2x(ktestd, Ktestd, X86KReg, X86KReg)                            // AVX512_BW
+    1803             :   ASMJIT_INST_2x(ktestq, Ktestq, X86KReg, X86KReg)                            // AVX512_BW
+    1804             :   ASMJIT_INST_2x(ktestw, Ktestw, X86KReg, X86KReg)                            // AVX512_DQ
+    1805             :   ASMJIT_INST_3x(kunpckbw, Kunpckbw, X86KReg, X86KReg, X86KReg)               // AVX512_F
+    1806             :   ASMJIT_INST_3x(kunpckdq, Kunpckdq, X86KReg, X86KReg, X86KReg)               // AVX512_BW
+    1807             :   ASMJIT_INST_3x(kunpckwd, Kunpckwd, X86KReg, X86KReg, X86KReg)               // AVX512_BW
+    1808             :   ASMJIT_INST_3x(kxnorb, Kxnorb, X86KReg, X86KReg, X86KReg)                   // AVX512_DQ
+    1809             :   ASMJIT_INST_3x(kxnord, Kxnord, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1810             :   ASMJIT_INST_3x(kxnorq, Kxnorq, X86KReg, X86KReg, X86KReg)                   // AVX512_BW
+    1811             :   ASMJIT_INST_3x(kxnorw, Kxnorw, X86KReg, X86KReg, X86KReg)                   // AVX512_F
+    1812             :   ASMJIT_INST_3x(kxorb, Kxorb, X86KReg, X86KReg, X86KReg)                     // AVX512_DQ
+    1813             :   ASMJIT_INST_3x(kxord, Kxord, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1814             :   ASMJIT_INST_3x(kxorq, Kxorq, X86KReg, X86KReg, X86KReg)                     // AVX512_BW
+    1815             :   ASMJIT_INST_3x(kxorw, Kxorw, X86KReg, X86KReg, X86KReg)                     // AVX512_F
+    1816             :   ASMJIT_INST_6x(v4fmaddps, V4fmaddps, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem)   // AVX512_4FMAPS{kz}
+    1817             :   ASMJIT_INST_6x(v4fnmaddps, V4fnmaddps, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem) // AVX512_4FMAPS{kz}
+    1818             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    1819             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    1820             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    1821             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    1822             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    1823             :   ASMJIT_INST_3x(vaddpd, Vaddpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    1824             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    1825             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    1826             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    1827             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    1828             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    1829             :   ASMJIT_INST_3x(vaddps, Vaddps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    1830             :   ASMJIT_INST_3x(vaddsd, Vaddsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    1831             :   ASMJIT_INST_3x(vaddsd, Vaddsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    1832             :   ASMJIT_INST_3x(vaddss, Vaddss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    1833             :   ASMJIT_INST_3x(vaddss, Vaddss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    1834             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Xmm, X86Xmm, X86Xmm)                // AVX
+    1835             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Xmm, X86Xmm, X86Mem)                // AVX
+    1836             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Ymm, X86Ymm, X86Ymm)                // AVX
+    1837             :   ASMJIT_INST_3x(vaddsubpd, Vaddsubpd, X86Ymm, X86Ymm, X86Mem)                // AVX
+    1838             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Xmm, X86Xmm, X86Xmm)                // AVX
+    1839             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Xmm, X86Xmm, X86Mem)                // AVX
+    1840             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Ymm, X86Ymm, X86Ymm)                // AVX
+    1841             :   ASMJIT_INST_3x(vaddsubps, Vaddsubps, X86Ymm, X86Ymm, X86Mem)                // AVX
+    1842             :   ASMJIT_INST_3x(vaesdec, Vaesdec, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    1843             :   ASMJIT_INST_3x(vaesdec, Vaesdec, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    1844             :   ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, X86Xmm, X86Xmm, X86Xmm)            // AVX
+    1845             :   ASMJIT_INST_3x(vaesdeclast, Vaesdeclast, X86Xmm, X86Xmm, X86Mem)            // AVX
+    1846             :   ASMJIT_INST_3x(vaesenc, Vaesenc, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    1847             :   ASMJIT_INST_3x(vaesenc, Vaesenc, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    1848             :   ASMJIT_INST_3x(vaesenclast, Vaesenclast, X86Xmm, X86Xmm, X86Xmm)            // AVX
+    1849             :   ASMJIT_INST_3x(vaesenclast, Vaesenclast, X86Xmm, X86Xmm, X86Mem)            // AVX
+    1850             :   ASMJIT_INST_2x(vaesimc, Vaesimc, X86Xmm, X86Xmm)                            // AVX
+    1851             :   ASMJIT_INST_2x(vaesimc, Vaesimc, X86Xmm, X86Mem)                            // AVX
+    1852             :   ASMJIT_INST_3i(vaeskeygenassist, Vaeskeygenassist, X86Xmm, X86Xmm, Imm)     // AVX
+    1853             :   ASMJIT_INST_3i(vaeskeygenassist, Vaeskeygenassist, X86Xmm, X86Mem, Imm)     // AVX
+    1854             :   ASMJIT_INST_4i(valignd, Valignd, X86Xmm, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b32}-VL
+    1855             :   ASMJIT_INST_4i(valignd, Valignd, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    1856             :   ASMJIT_INST_4i(valignd, Valignd, X86Ymm, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b32}-VL
+    1857             :   ASMJIT_INST_4i(valignd, Valignd, X86Ymm, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    1858             :   ASMJIT_INST_4i(valignd, Valignd, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b32}
+    1859             :   ASMJIT_INST_4i(valignd, Valignd, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b32}
+    1860             :   ASMJIT_INST_4i(valignq, Valignq, X86Xmm, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b64}-VL
+    1861             :   ASMJIT_INST_4i(valignq, Valignq, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    1862             :   ASMJIT_INST_4i(valignq, Valignq, X86Ymm, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b64}-VL
+    1863             :   ASMJIT_INST_4i(valignq, Valignq, X86Ymm, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    1864             :   ASMJIT_INST_4i(valignq, Valignq, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b64}
+    1865             :   ASMJIT_INST_4i(valignq, Valignq, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b64}
+    1866             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1867             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1868             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Ymm, X86Ymm, X86Ymm)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1869             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Ymm, X86Ymm, X86Mem)                    // AVX  AVX512_DQ{kz|b64}-VL
+    1870             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|b64}
+    1871             :   ASMJIT_INST_3x(vandnpd, Vandnpd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|b64}
+    1872             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1873             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1874             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Ymm, X86Ymm, X86Ymm)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1875             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Ymm, X86Ymm, X86Mem)                    // AVX  AVX512_DQ{kz|b32}-VL
+    1876             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|b32}
+    1877             :   ASMJIT_INST_3x(vandnps, Vandnps, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|b32}
+    1878             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1879             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1880             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1881             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    1882             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b64}
+    1883             :   ASMJIT_INST_3x(vandpd, Vandpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b64}
+    1884             :   ASMJIT_INST_3x(vandps, Vandps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1885             :   ASMJIT_INST_3x(vandps, Vandps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1886             :   ASMJIT_INST_3x(vandps, Vandps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1887             :   ASMJIT_INST_3x(vandps, Vandps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    1888             :   ASMJIT_INST_3x(vandps, Vandps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b32}
+    1889             :   ASMJIT_INST_3x(vandps, Vandps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b32}
+    1890             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    1891             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1892             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    1893             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1894             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    1895             :   ASMJIT_INST_3x(vblendmb, Vblendmb, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    1896             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b32}-VL
+    1897             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    1898             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b32}-VL
+    1899             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    1900             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b32}
+    1901             :   ASMJIT_INST_3x(vblendmd, Vblendmd, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b32}
+    1902             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    1903             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    1904             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    1905             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    1906             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    1907             :   ASMJIT_INST_3x(vblendmpd, Vblendmpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    1908             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    1909             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    1910             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    1911             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    1912             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    1913             :   ASMJIT_INST_3x(vblendmps, Vblendmps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    1914             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b64}-VL
+    1915             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    1916             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b64}-VL
+    1917             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    1918             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    1919             :   ASMJIT_INST_3x(vblendmq, Vblendmq, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    1920             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    1921             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1922             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    1923             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    1924             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    1925             :   ASMJIT_INST_3x(vblendmw, Vblendmw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    1926             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    1927             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    1928             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX
+    1929             :   ASMJIT_INST_4i(vblendpd, Vblendpd, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX
+    1930             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    1931             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    1932             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX
+    1933             :   ASMJIT_INST_4i(vblendps, Vblendps, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX
+    1934             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // AVX
+    1935             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // AVX
+    1936             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // AVX
+    1937             :   ASMJIT_INST_4x(vblendvpd, Vblendvpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // AVX
+    1938             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // AVX
+    1939             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // AVX
+    1940             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // AVX
+    1941             :   ASMJIT_INST_4x(vblendvps, Vblendvps, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // AVX
+    1942             :   ASMJIT_INST_2x(vbroadcastf128, Vbroadcastf128, X86Ymm, X86Mem)              // AVX
+    1943             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Ymm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1944             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1945             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1946             :   ASMJIT_INST_2x(vbroadcastf32x2, Vbroadcastf32x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1947             :   ASMJIT_INST_2x(vbroadcastf32x4, Vbroadcastf32x4, X86Ymm, X86Mem)            //      AVX512_F{kz}
+    1948             :   ASMJIT_INST_2x(vbroadcastf32x4, Vbroadcastf32x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1949             :   ASMJIT_INST_2x(vbroadcastf32x8, Vbroadcastf32x8, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1950             :   ASMJIT_INST_2x(vbroadcastf64x2, Vbroadcastf64x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1951             :   ASMJIT_INST_2x(vbroadcastf64x2, Vbroadcastf64x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1952             :   ASMJIT_INST_2x(vbroadcastf64x4, Vbroadcastf64x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1953             :   ASMJIT_INST_2x(vbroadcasti128, Vbroadcasti128, X86Ymm, X86Mem)              // AVX2
+    1954             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Xmm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1955             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Xmm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1956             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Ymm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1957             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1958             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1959             :   ASMJIT_INST_2x(vbroadcasti32x2, Vbroadcasti32x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1960             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Ymm, X86Xmm)            //      AVX512_F{kz}-VL
+    1961             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Ymm, X86Mem)            //      AVX512_F{kz}-VL
+    1962             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Zmm, X86Xmm)            //      AVX512_F{kz}
+    1963             :   ASMJIT_INST_2x(vbroadcasti32x4, Vbroadcasti32x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1964             :   ASMJIT_INST_2x(vbroadcasti32x8, Vbroadcasti32x8, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1965             :   ASMJIT_INST_2x(vbroadcasti32x8, Vbroadcasti32x8, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1966             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Ymm, X86Xmm)            //      AVX512_DQ{kz}-VL
+    1967             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Ymm, X86Mem)            //      AVX512_DQ{kz}-VL
+    1968             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Zmm, X86Xmm)            //      AVX512_DQ{kz}
+    1969             :   ASMJIT_INST_2x(vbroadcasti64x2, Vbroadcasti64x2, X86Zmm, X86Mem)            //      AVX512_DQ{kz}
+    1970             :   ASMJIT_INST_2x(vbroadcasti64x4, Vbroadcasti64x4, X86Zmm, X86Xmm)            //      AVX512_F{kz}
+    1971             :   ASMJIT_INST_2x(vbroadcasti64x4, Vbroadcasti64x4, X86Zmm, X86Mem)            //      AVX512_F{kz}
+    1972             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Ymm, X86Mem)                  // AVX  AVX512_F{kz}-VL
+    1973             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    1974             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Zmm, X86Xmm)                  //      AVX512_F{kz}
+    1975             :   ASMJIT_INST_2x(vbroadcastsd, Vbroadcastsd, X86Zmm, X86Mem)                  //      AVX512_F{kz}
+    1976             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Xmm, X86Mem)                  // AVX  AVX512_F{kz}-VL
+    1977             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Xmm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    1978             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Ymm, X86Mem)                  // AVX  AVX512_F{kz}
+    1979             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}
+    1980             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Zmm, X86Xmm)                  //      AVX512_F{kz}-VL
+    1981             :   ASMJIT_INST_2x(vbroadcastss, Vbroadcastss, X86Zmm, X86Mem)                  //      AVX512_F{kz}-VL
+    1982             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    1983             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    1984             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Ymm, X86Ymm, X86Ymm, Imm)                 // AVX
+    1985             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86Ymm, X86Ymm, X86Mem, Imm)                 // AVX
+    1986             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|b64}-VL
+    1987             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|b64}-VL
+    1988             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{kz|b64}-VL
+    1989             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{kz|b64}-VL
+    1990             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{kz|sae|b64}
+    1991             :   ASMJIT_INST_4i(vcmppd, Vcmppd, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{kz|sae|b64}
+    1992             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    1993             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    1994             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Ymm, X86Ymm, X86Ymm, Imm)                 // AVX
+    1995             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86Ymm, X86Ymm, X86Mem, Imm)                 // AVX
+    1996             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|b32}-VL
+    1997             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|b32}-VL
+    1998             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{kz|b32}-VL
+    1999             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{kz|b32}-VL
+    2000             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{kz|sae|b32}
+    2001             :   ASMJIT_INST_4i(vcmpps, Vcmpps, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{kz|sae|b32}
+    2002             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    2003             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    2004             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|sae}
+    2005             :   ASMJIT_INST_4i(vcmpsd, Vcmpsd, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|sae}
+    2006             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86Xmm, X86Xmm, X86Xmm, Imm)                 // AVX
+    2007             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86Xmm, X86Xmm, X86Mem, Imm)                 // AVX
+    2008             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{kz|sae}
+    2009             :   ASMJIT_INST_4i(vcmpss, Vcmpss, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{kz|sae}
+    2010             :   ASMJIT_INST_2x(vcomisd, Vcomisd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{sae}
+    2011             :   ASMJIT_INST_2x(vcomisd, Vcomisd, X86Xmm, X86Mem)                            // AVX  AVX512_F{sae}
+    2012             :   ASMJIT_INST_2x(vcomiss, Vcomiss, X86Xmm, X86Xmm)                            // AVX  AVX512_F{sae}
+    2013             :   ASMJIT_INST_2x(vcomiss, Vcomiss, X86Xmm, X86Mem)                            // AVX  AVX512_F{sae}
+    2014             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    2015             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    2016             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    2017             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    2018             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    2019             :   ASMJIT_INST_2x(vcompresspd, Vcompresspd, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    2020             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    2021             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    2022             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    2023             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    2024             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    2025             :   ASMJIT_INST_2x(vcompressps, Vcompressps, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    2026             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2027             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2028             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Ymm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2029             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2030             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Zmm, X86Ymm)                        //      AVX512_F{kz|b32}
+    2031             :   ASMJIT_INST_2x(vcvtdq2pd, Vcvtdq2pd, X86Zmm, X86Mem)                        //      AVX512_F{kz|b32}
+    2032             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2033             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2034             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz|b32}-VL
+    2035             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2036             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Zmm, X86Zmm)                        //      AVX512_F{kz|er|b32}
+    2037             :   ASMJIT_INST_2x(vcvtdq2ps, Vcvtdq2ps, X86Zmm, X86Mem)                        //      AVX512_F{kz|er|b32}
+    2038             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b64}-VL
+    2039             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b64}-VL
+    2040             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Xmm, X86Ymm)                        // AVX  AVX512_F{kz|b64}-VL
+    2041             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Ymm, X86Zmm)                        //      AVX512_F{kz|er|b64}
+    2042             :   ASMJIT_INST_2x(vcvtpd2dq, Vcvtpd2dq, X86Ymm, X86Mem)                        //      AVX512_F{kz|er|b64}
+    2043             :   ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, X86Xmm, X86Xmm)                        // AVX
+    2044             :   ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, X86Xmm, X86Mem)                        // AVX
+    2045             :   ASMJIT_INST_2x(vcvtpd2ps, Vcvtpd2ps, X86Xmm, X86Ymm)                        // AVX
+    2046             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b64}-VL
+    2047             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2048             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Ymm, X86Ymm)                        //      AVX512_DQ{kz|b64}-VL
+    2049             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2050             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Zmm, X86Zmm)                        //      AVX512_DQ{kz|er|b64}
+    2051             :   ASMJIT_INST_2x(vcvtpd2qq, Vcvtpd2qq, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|er|b64}
+    2052             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    2053             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    2054             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Xmm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    2055             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Ymm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    2056             :   ASMJIT_INST_2x(vcvtpd2udq, Vcvtpd2udq, X86Ymm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    2057             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b64}-VL
+    2058             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2059             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Ymm, X86Ymm)                      //      AVX512_DQ{kz|b64}-VL
+    2060             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2061             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|er|b64}
+    2062             :   ASMJIT_INST_2x(vcvtpd2uqq, Vcvtpd2uqq, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|er|b64}
+    2063             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Xmm, X86Xmm)                        // F16C AVX512_F{kz}-VL
+    2064             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Xmm, X86Mem)                        // F16C AVX512_F{kz}-VL
+    2065             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Ymm, X86Xmm)                        // F16C AVX512_F{kz}-VL
+    2066             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Ymm, X86Mem)                        // F16C AVX512_F{kz}-VL
+    2067             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Zmm, X86Ymm)                        //      AVX512_F{kz|sae}
+    2068             :   ASMJIT_INST_2x(vcvtph2ps, Vcvtph2ps, X86Zmm, X86Mem)                        //      AVX512_F{kz|sae}
+    2069             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2070             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2071             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz|b32}-VL
+    2072             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2073             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Zmm, X86Zmm)                        //      AVX512_F{kz|er|b32}
+    2074             :   ASMJIT_INST_2x(vcvtps2dq, Vcvtps2dq, X86Zmm, X86Mem)                        //      AVX512_F{kz|er|b32}
+    2075             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2076             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2077             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Ymm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2078             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2079             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Zmm, X86Ymm)                        //      AVX512_F{kz|er|b32}
+    2080             :   ASMJIT_INST_2x(vcvtps2pd, Vcvtps2pd, X86Zmm, X86Mem)                        //      AVX512_F{kz|er|b32}
+    2081             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Xmm, X86Xmm, Imm)                   // F16C AVX512_F{kz}-VL
+    2082             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Mem, X86Xmm, Imm)                   // F16C AVX512_F{kz}-VL
+    2083             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Xmm, X86Ymm, Imm)                   // F16C AVX512_F{kz}-VL
+    2084             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Mem, X86Ymm, Imm)                   // F16C AVX512_F{kz}-VL
+    2085             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Ymm, X86Zmm, Imm)                   //      AVX512_F{kz|sae}
+    2086             :   ASMJIT_INST_3i(vcvtps2ph, Vcvtps2ph, X86Mem, X86Zmm, Imm)                   //      AVX512_F{kz|sae}
+    2087             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b32}-VL
+    2088             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b32}-VL
+    2089             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Ymm, X86Xmm)                        //      AVX512_DQ{kz|b32}-VL
+    2090             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|b32}-VL
+    2091             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Zmm, X86Ymm)                        //      AVX512_DQ{kz|er|b32}
+    2092             :   ASMJIT_INST_2x(vcvtps2qq, Vcvtps2qq, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|er|b32}
+    2093             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2094             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2095             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    2096             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2097             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2098             :   ASMJIT_INST_2x(vcvtps2udq, Vcvtps2udq, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2099             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2100             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2101             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Ymm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2102             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2103             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Zmm, X86Ymm)                      //      AVX512_DQ{kz|er|b32}
+    2104             :   ASMJIT_INST_2x(vcvtps2uqq, Vcvtps2uqq, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|er|b32}
+    2105             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b64}-VL
+    2106             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2107             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Ymm, X86Ymm)                        //      AVX512_DQ{kz|b64}-VL
+    2108             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2109             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Zmm, X86Zmm)                        //      AVX512_DQ{kz|er|b64}
+    2110             :   ASMJIT_INST_2x(vcvtqq2pd, Vcvtqq2pd, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|er|b64}
+    2111             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Xmm, X86Xmm)                        //      AVX512_DQ{kz|b64}-VL
+    2112             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Xmm, X86Mem)                        //      AVX512_DQ{kz|b64}-VL
+    2113             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Xmm, X86Ymm)                        //      AVX512_DQ{kz|b64}-VL
+    2114             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Ymm, X86Zmm)                        //      AVX512_DQ{kz|er|b64}
+    2115             :   ASMJIT_INST_2x(vcvtqq2ps, Vcvtqq2ps, X86Ymm, X86Mem)                        //      AVX512_DQ{kz|er|b64}
+    2116             :   ASMJIT_INST_2x(vcvtsd2si, Vcvtsd2si, X86Gp, X86Xmm)                         // AVX  AVX512_F{er}
+    2117             :   ASMJIT_INST_2x(vcvtsd2si, Vcvtsd2si, X86Gp, X86Mem)                         // AVX  AVX512_F{er}
+    2118             :   ASMJIT_INST_3x(vcvtsd2ss, Vcvtsd2ss, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|er}
+    2119             :   ASMJIT_INST_3x(vcvtsd2ss, Vcvtsd2ss, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|er}
+    2120             :   ASMJIT_INST_2x(vcvtsd2usi, Vcvtsd2usi, X86Gp, X86Xmm)                       //      AVX512_F{er}
+    2121             :   ASMJIT_INST_2x(vcvtsd2usi, Vcvtsd2usi, X86Gp, X86Mem)                       //      AVX512_F{er}
+    2122             :   ASMJIT_INST_3x(vcvtsi2sd, Vcvtsi2sd, X86Xmm, X86Xmm, X86Gp)                 // AVX  AVX512_F{er}
+    2123             :   ASMJIT_INST_3x(vcvtsi2sd, Vcvtsi2sd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{er}
+    2124             :   ASMJIT_INST_3x(vcvtsi2ss, Vcvtsi2ss, X86Xmm, X86Xmm, X86Gp)                 // AVX  AVX512_F{er}
+    2125             :   ASMJIT_INST_3x(vcvtsi2ss, Vcvtsi2ss, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{er}
+    2126             :   ASMJIT_INST_3x(vcvtss2sd, Vcvtss2sd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|sae}
+    2127             :   ASMJIT_INST_3x(vcvtss2sd, Vcvtss2sd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|sae}
+    2128             :   ASMJIT_INST_2x(vcvtss2si, Vcvtss2si, X86Gp, X86Xmm)                         // AVX  AVX512_F{er}
+    2129             :   ASMJIT_INST_2x(vcvtss2si, Vcvtss2si, X86Gp, X86Mem)                         // AVX  AVX512_F{er}
+    2130             :   ASMJIT_INST_2x(vcvtss2usi, Vcvtss2usi, X86Gp, X86Xmm)                       //      AVX512_F{er}
+    2131             :   ASMJIT_INST_2x(vcvtss2usi, Vcvtss2usi, X86Gp, X86Mem)                       //      AVX512_F{er}
+    2132             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2133             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2134             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Xmm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2135             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Ymm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2136             :   ASMJIT_INST_2x(vcvttpd2dq, Vcvttpd2dq, X86Ymm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2137             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    2138             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    2139             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    2140             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    2141             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2142             :   ASMJIT_INST_2x(vcvttpd2qq, Vcvttpd2qq, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2143             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    2144             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    2145             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Xmm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    2146             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Ymm, X86Zmm)                    //      AVX512_F{kz|sae|b64}
+    2147             :   ASMJIT_INST_2x(vcvttpd2udq, Vcvttpd2udq, X86Ymm, X86Mem)                    //      AVX512_F{kz|sae|b64}
+    2148             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Xmm, X86Xmm)                    //      AVX512_DQ{kz|b64}-VL
+    2149             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Xmm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    2150             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Ymm, X86Ymm)                    //      AVX512_DQ{kz|b64}-VL
+    2151             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Ymm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    2152             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|sae|b64}
+    2153             :   ASMJIT_INST_2x(vcvttpd2uqq, Vcvttpd2uqq, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|sae|b64}
+    2154             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2155             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2156             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2157             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2158             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b32}
+    2159             :   ASMJIT_INST_2x(vcvttps2dq, Vcvttps2dq, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b32}
+    2160             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2161             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2162             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Ymm, X86Xmm)                      //      AVX512_DQ{kz|b32}-VL
+    2163             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b32}-VL
+    2164             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Zmm, X86Ymm)                      //      AVX512_DQ{kz|sae|b32}
+    2165             :   ASMJIT_INST_2x(vcvttps2qq, Vcvttps2qq, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|sae|b32}
+    2166             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    2167             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    2168             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    2169             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    2170             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Zmm, X86Zmm)                    //      AVX512_F{kz|sae|b32}
+    2171             :   ASMJIT_INST_2x(vcvttps2udq, Vcvttps2udq, X86Zmm, X86Mem)                    //      AVX512_F{kz|sae|b32}
+    2172             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Xmm, X86Xmm)                    //      AVX512_DQ{kz|b32}-VL
+    2173             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Xmm, X86Mem)                    //      AVX512_DQ{kz|b32}-VL
+    2174             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Ymm, X86Xmm)                    //      AVX512_DQ{kz|b32}-VL
+    2175             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Ymm, X86Mem)                    //      AVX512_DQ{kz|b32}-VL
+    2176             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Zmm, X86Ymm)                    //      AVX512_DQ{kz|sae|b32}
+    2177             :   ASMJIT_INST_2x(vcvttps2uqq, Vcvttps2uqq, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|sae|b32}
+    2178             :   ASMJIT_INST_2x(vcvttsd2si, Vcvttsd2si, X86Gp, X86Xmm)                       // AVX  AVX512_F{sae}
+    2179             :   ASMJIT_INST_2x(vcvttsd2si, Vcvttsd2si, X86Gp, X86Mem)                       // AVX  AVX512_F{sae}
+    2180             :   ASMJIT_INST_2x(vcvttsd2usi, Vcvttsd2usi, X86Gp, X86Xmm)                     //      AVX512_F{sae}
+    2181             :   ASMJIT_INST_2x(vcvttsd2usi, Vcvttsd2usi, X86Gp, X86Mem)                     //      AVX512_F{sae}
+    2182             :   ASMJIT_INST_2x(vcvttss2si, Vcvttss2si, X86Gp, X86Xmm)                       // AVX  AVX512_F{sae}
+    2183             :   ASMJIT_INST_2x(vcvttss2si, Vcvttss2si, X86Gp, X86Mem)                       // AVX  AVX512_F{sae}
+    2184             :   ASMJIT_INST_2x(vcvttss2usi, Vcvttss2usi, X86Gp, X86Xmm)                     //      AVX512_F{sae}
+    2185             :   ASMJIT_INST_2x(vcvttss2usi, Vcvttss2usi, X86Gp, X86Mem)                     //      AVX512_F{sae}
+    2186             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2187             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2188             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Ymm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2189             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2190             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Zmm, X86Ymm)                      //      AVX512_F{kz|b32}
+    2191             :   ASMJIT_INST_2x(vcvtudq2pd, Vcvtudq2pd, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    2192             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    2193             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2194             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    2195             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    2196             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2197             :   ASMJIT_INST_2x(vcvtudq2ps, Vcvtudq2ps, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2198             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b64}-VL
+    2199             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2200             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Ymm, X86Ymm)                      //      AVX512_DQ{kz|b64}-VL
+    2201             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2202             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|er|b64}
+    2203             :   ASMJIT_INST_2x(vcvtuqq2pd, Vcvtuqq2pd, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|er|b64}
+    2204             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Xmm, X86Xmm)                      //      AVX512_DQ{kz|b64}-VL
+    2205             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Xmm, X86Mem)                      //      AVX512_DQ{kz|b64}-VL
+    2206             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Xmm, X86Ymm)                      //      AVX512_DQ{kz|b64}-VL
+    2207             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Ymm, X86Zmm)                      //      AVX512_DQ{kz|er|b64}
+    2208             :   ASMJIT_INST_2x(vcvtuqq2ps, Vcvtuqq2ps, X86Ymm, X86Mem)                      //      AVX512_DQ{kz|er|b64}
+    2209             :   ASMJIT_INST_3x(vcvtusi2sd, Vcvtusi2sd, X86Xmm, X86Xmm, X86Gp)               //      AVX512_F{er}
+    2210             :   ASMJIT_INST_3x(vcvtusi2sd, Vcvtusi2sd, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{er}
+    2211             :   ASMJIT_INST_3x(vcvtusi2ss, Vcvtusi2ss, X86Xmm, X86Xmm, X86Gp)               //      AVX512_F{er}
+    2212             :   ASMJIT_INST_3x(vcvtusi2ss, Vcvtusi2ss, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{er}
+    2213             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Xmm, X86Xmm, X86Xmm, Imm)           //      AVX512_BW{kz}-VL
+    2214             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Xmm, X86Xmm, X86Mem, Imm)           //      AVX512_BW{kz}-VL
+    2215             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Ymm, X86Ymm, X86Ymm, Imm)           //      AVX512_BW{kz}-VL
+    2216             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Ymm, X86Ymm, X86Mem, Imm)           //      AVX512_BW{kz}-VL
+    2217             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Zmm, X86Zmm, X86Zmm, Imm)           //      AVX512_BW{kz}
+    2218             :   ASMJIT_INST_4i(vdbpsadbw, Vdbpsadbw, X86Zmm, X86Zmm, X86Mem, Imm)           //      AVX512_BW{kz}
+    2219             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2220             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2221             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2222             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2223             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    2224             :   ASMJIT_INST_3x(vdivpd, Vdivpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    2225             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2226             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2227             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2228             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2229             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2230             :   ASMJIT_INST_3x(vdivps, Vdivps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2231             :   ASMJIT_INST_3x(vdivsd, Vdivsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2232             :   ASMJIT_INST_3x(vdivsd, Vdivsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2233             :   ASMJIT_INST_3x(vdivss, Vdivss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2234             :   ASMJIT_INST_3x(vdivss, Vdivss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2235             :   ASMJIT_INST_4i(vdppd, Vdppd, X86Xmm, X86Xmm, X86Xmm, Imm)                   // AVX
+    2236             :   ASMJIT_INST_4i(vdppd, Vdppd, X86Xmm, X86Xmm, X86Mem, Imm)                   // AVX
+    2237             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Xmm, X86Xmm, X86Xmm, Imm)                   // AVX
+    2238             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Xmm, X86Xmm, X86Mem, Imm)                   // AVX
+    2239             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Ymm, X86Ymm, X86Ymm, Imm)                   // AVX
+    2240             :   ASMJIT_INST_4i(vdpps, Vdpps, X86Ymm, X86Ymm, X86Mem, Imm)                   // AVX
+    2241             :   ASMJIT_INST_2x(vexp2pd, Vexp2pd, X86Zmm, X86Zmm)                            //      AVX512_ER{kz|sae|b64}
+    2242             :   ASMJIT_INST_2x(vexp2pd, Vexp2pd, X86Zmm, X86Mem)                            //      AVX512_ER{kz|sae|b64}
+    2243             :   ASMJIT_INST_2x(vexp2ps, Vexp2ps, X86Zmm, X86Zmm)                            //      AVX512_ER{kz|sae|b32}
+    2244             :   ASMJIT_INST_2x(vexp2ps, Vexp2ps, X86Zmm, X86Mem)                            //      AVX512_ER{kz|sae|b32}
+    2245             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2246             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2247             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2248             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2249             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2250             :   ASMJIT_INST_2x(vexpandpd, Vexpandpd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2251             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2252             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2253             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2254             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2255             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2256             :   ASMJIT_INST_2x(vexpandps, Vexpandps, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2257             :   ASMJIT_INST_3i(vextractf128, Vextractf128, X86Xmm, X86Ymm, Imm)             // AVX
+    2258             :   ASMJIT_INST_3i(vextractf128, Vextractf128, X86Mem, X86Ymm, Imm)             // AVX
+    2259             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Xmm, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2260             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Mem, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2261             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Xmm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2262             :   ASMJIT_INST_3i(vextractf32x4, Vextractf32x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2263             :   ASMJIT_INST_3i(vextractf32x8, Vextractf32x8, X86Ymm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2264             :   ASMJIT_INST_3i(vextractf32x8, Vextractf32x8, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2265             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Xmm, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2266             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Mem, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2267             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Xmm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2268             :   ASMJIT_INST_3i(vextractf64x2, Vextractf64x2, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2269             :   ASMJIT_INST_3i(vextractf64x4, Vextractf64x4, X86Ymm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2270             :   ASMJIT_INST_3i(vextractf64x4, Vextractf64x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2271             :   ASMJIT_INST_3i(vextracti128, Vextracti128, X86Xmm, X86Ymm, Imm)             // AVX2
+    2272             :   ASMJIT_INST_3i(vextracti128, Vextracti128, X86Mem, X86Ymm, Imm)             // AVX2
+    2273             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Xmm, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2274             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Mem, X86Ymm, Imm)           //      AVX512_F{kz}-VL
+    2275             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Xmm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2276             :   ASMJIT_INST_3i(vextracti32x4, Vextracti32x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2277             :   ASMJIT_INST_3i(vextracti32x8, Vextracti32x8, X86Ymm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2278             :   ASMJIT_INST_3i(vextracti32x8, Vextracti32x8, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2279             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Xmm, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2280             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Mem, X86Ymm, Imm)           //      AVX512_DQ{kz}-VL
+    2281             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Xmm, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2282             :   ASMJIT_INST_3i(vextracti64x2, Vextracti64x2, X86Mem, X86Zmm, Imm)           //      AVX512_DQ{kz}
+    2283             :   ASMJIT_INST_3i(vextracti64x4, Vextracti64x4, X86Ymm, X86Zmm, Imm)           //      AVX512_F{kz}
+    2284             :   ASMJIT_INST_3i(vextracti64x4, Vextracti64x4, X86Mem, X86Zmm, Imm)           //      AVX512_F{kz}
+    2285             :   ASMJIT_INST_3i(vextractps, Vextractps, X86Gp, X86Xmm, Imm)                  // AVX  AVX512_F
+    2286             :   ASMJIT_INST_3i(vextractps, Vextractps, X86Mem, X86Xmm, Imm)                 // AVX  AVX512_F
+    2287             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|b64}-VL
+    2288             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|b64}-VL
+    2289             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Ymm, X86Ymm, X86Ymm, Imm)       //      AVX512_F{kz|b64}-VL
+    2290             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Ymm, X86Ymm, X86Mem, Imm)       //      AVX512_F{kz|b64}-VL
+    2291             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Zmm, X86Zmm, X86Zmm, Imm)       //      AVX512_F{kz|sae|b64}
+    2292             :   ASMJIT_INST_4i(vfixupimmpd, Vfixupimmpd, X86Zmm, X86Zmm, X86Mem, Imm)       //      AVX512_F{kz|sae|b64}
+    2293             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|b32}-VL
+    2294             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|b32}-VL
+    2295             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Ymm, X86Ymm, X86Ymm, Imm)       //      AVX512_F{kz|b32}-VL
+    2296             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Ymm, X86Ymm, X86Mem, Imm)       //      AVX512_F{kz|b32}-VL
+    2297             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Zmm, X86Zmm, X86Zmm, Imm)       //      AVX512_F{kz|sae|b32}
+    2298             :   ASMJIT_INST_4i(vfixupimmps, Vfixupimmps, X86Zmm, X86Zmm, X86Mem, Imm)       //      AVX512_F{kz|sae|b32}
+    2299             :   ASMJIT_INST_4i(vfixupimmsd, Vfixupimmsd, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    2300             :   ASMJIT_INST_4i(vfixupimmsd, Vfixupimmsd, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    2301             :   ASMJIT_INST_4i(vfixupimmss, Vfixupimmss, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    2302             :   ASMJIT_INST_4i(vfixupimmss, Vfixupimmss, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    2303             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2304             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2305             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2306             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2307             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2308             :   ASMJIT_INST_3x(vfmadd132pd, Vfmadd132pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2309             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2310             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2311             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2312             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2313             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2314             :   ASMJIT_INST_3x(vfmadd132ps, Vfmadd132ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2315             :   ASMJIT_INST_3x(vfmadd132sd, Vfmadd132sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2316             :   ASMJIT_INST_3x(vfmadd132sd, Vfmadd132sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2317             :   ASMJIT_INST_3x(vfmadd132ss, Vfmadd132ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2318             :   ASMJIT_INST_3x(vfmadd132ss, Vfmadd132ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2319             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2320             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2321             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2322             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2323             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2324             :   ASMJIT_INST_3x(vfmadd213pd, Vfmadd213pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2325             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2326             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2327             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2328             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2329             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2330             :   ASMJIT_INST_3x(vfmadd213ps, Vfmadd213ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2331             :   ASMJIT_INST_3x(vfmadd213sd, Vfmadd213sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2332             :   ASMJIT_INST_3x(vfmadd213sd, Vfmadd213sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2333             :   ASMJIT_INST_3x(vfmadd213ss, Vfmadd213ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2334             :   ASMJIT_INST_3x(vfmadd213ss, Vfmadd213ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2335             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2336             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2337             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2338             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2339             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2340             :   ASMJIT_INST_3x(vfmadd231pd, Vfmadd231pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2341             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2342             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2343             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2344             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2345             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2346             :   ASMJIT_INST_3x(vfmadd231ps, Vfmadd231ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2347             :   ASMJIT_INST_3x(vfmadd231sd, Vfmadd231sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2348             :   ASMJIT_INST_3x(vfmadd231sd, Vfmadd231sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2349             :   ASMJIT_INST_3x(vfmadd231ss, Vfmadd231ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2350             :   ASMJIT_INST_3x(vfmadd231ss, Vfmadd231ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2351             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2352             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2353             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2354             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2355             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2356             :   ASMJIT_INST_3x(vfmaddsub132pd, Vfmaddsub132pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2357             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2358             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2359             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2360             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2361             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2362             :   ASMJIT_INST_3x(vfmaddsub132ps, Vfmaddsub132ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2363             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2364             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2365             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2366             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2367             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2368             :   ASMJIT_INST_3x(vfmaddsub213pd, Vfmaddsub213pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2369             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2370             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2371             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2372             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2373             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2374             :   ASMJIT_INST_3x(vfmaddsub213ps, Vfmaddsub213ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2375             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2376             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2377             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2378             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2379             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2380             :   ASMJIT_INST_3x(vfmaddsub231pd, Vfmaddsub231pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2381             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2382             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2383             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2384             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2385             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2386             :   ASMJIT_INST_3x(vfmaddsub231ps, Vfmaddsub231ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2387             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2388             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2389             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2390             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2391             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2392             :   ASMJIT_INST_3x(vfmsub132pd, Vfmsub132pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2393             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2394             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2395             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2396             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2397             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2398             :   ASMJIT_INST_3x(vfmsub132ps, Vfmsub132ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2399             :   ASMJIT_INST_3x(vfmsub132sd, Vfmsub132sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2400             :   ASMJIT_INST_3x(vfmsub132sd, Vfmsub132sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2401             :   ASMJIT_INST_3x(vfmsub132ss, Vfmsub132ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2402             :   ASMJIT_INST_3x(vfmsub132ss, Vfmsub132ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2403             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2404             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2405             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2406             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2407             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2408             :   ASMJIT_INST_3x(vfmsub213pd, Vfmsub213pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2409             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2410             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2411             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2412             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2413             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2414             :   ASMJIT_INST_3x(vfmsub213ps, Vfmsub213ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2415             :   ASMJIT_INST_3x(vfmsub213sd, Vfmsub213sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2416             :   ASMJIT_INST_3x(vfmsub213sd, Vfmsub213sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2417             :   ASMJIT_INST_3x(vfmsub213ss, Vfmsub213ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2418             :   ASMJIT_INST_3x(vfmsub213ss, Vfmsub213ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2419             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b64}-VL
+    2420             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2421             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b64}-VL
+    2422             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b64}-VL
+    2423             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b64}
+    2424             :   ASMJIT_INST_3x(vfmsub231pd, Vfmsub231pd, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b64}
+    2425             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|b32}-VL
+    2426             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2427             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Ymm, X86Ymm, X86Ymm)            // FMA  AVX512_F{kz|b32}-VL
+    2428             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Ymm, X86Ymm, X86Mem)            // FMA  AVX512_F{kz|b32}-VL
+    2429             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Zmm, X86Zmm, X86Zmm)            // FMA  AVX512_F{kz|er|b32}
+    2430             :   ASMJIT_INST_3x(vfmsub231ps, Vfmsub231ps, X86Zmm, X86Zmm, X86Mem)            // FMA  AVX512_F{kz|er|b32}
+    2431             :   ASMJIT_INST_3x(vfmsub231sd, Vfmsub231sd, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2432             :   ASMJIT_INST_3x(vfmsub231sd, Vfmsub231sd, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2433             :   ASMJIT_INST_3x(vfmsub231ss, Vfmsub231ss, X86Xmm, X86Xmm, X86Xmm)            // FMA  AVX512_F{kz|er}
+    2434             :   ASMJIT_INST_3x(vfmsub231ss, Vfmsub231ss, X86Xmm, X86Xmm, X86Mem)            // FMA  AVX512_F{kz|er}
+    2435             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2436             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2437             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2438             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2439             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2440             :   ASMJIT_INST_3x(vfmsubadd132pd, Vfmsubadd132pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2441             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2442             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2443             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2444             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2445             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2446             :   ASMJIT_INST_3x(vfmsubadd132ps, Vfmsubadd132ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2447             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2448             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2449             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2450             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2451             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2452             :   ASMJIT_INST_3x(vfmsubadd213pd, Vfmsubadd213pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2453             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2454             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2455             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2456             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2457             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2458             :   ASMJIT_INST_3x(vfmsubadd213ps, Vfmsubadd213ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2459             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b64}-VL
+    2460             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2461             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b64}-VL
+    2462             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b64}-VL
+    2463             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b64}
+    2464             :   ASMJIT_INST_3x(vfmsubadd231pd, Vfmsubadd231pd, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b64}
+    2465             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Xmm, X86Xmm, X86Xmm)      // FMA  AVX512_F{kz|b32}-VL
+    2466             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Xmm, X86Xmm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2467             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Ymm, X86Ymm, X86Ymm)      // FMA  AVX512_F{kz|b32}-VL
+    2468             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Ymm, X86Ymm, X86Mem)      // FMA  AVX512_F{kz|b32}-VL
+    2469             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Zmm, X86Zmm, X86Zmm)      // FMA  AVX512_F{kz|er|b32}
+    2470             :   ASMJIT_INST_3x(vfmsubadd231ps, Vfmsubadd231ps, X86Zmm, X86Zmm, X86Mem)      // FMA  AVX512_F{kz|er|b32}
+    2471             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2472             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2473             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2474             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2475             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2476             :   ASMJIT_INST_3x(vfnmadd132pd, Vfnmadd132pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2477             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2478             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2479             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2480             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2481             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2482             :   ASMJIT_INST_3x(vfnmadd132ps, Vfnmadd132ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2483             :   ASMJIT_INST_3x(vfnmadd132sd, Vfnmadd132sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2484             :   ASMJIT_INST_3x(vfnmadd132sd, Vfnmadd132sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2485             :   ASMJIT_INST_3x(vfnmadd132ss, Vfnmadd132ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2486             :   ASMJIT_INST_3x(vfnmadd132ss, Vfnmadd132ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2487             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2488             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2489             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2490             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2491             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2492             :   ASMJIT_INST_3x(vfnmadd213pd, Vfnmadd213pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2493             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2494             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2495             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2496             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2497             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2498             :   ASMJIT_INST_3x(vfnmadd213ps, Vfnmadd213ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2499             :   ASMJIT_INST_3x(vfnmadd213sd, Vfnmadd213sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2500             :   ASMJIT_INST_3x(vfnmadd213sd, Vfnmadd213sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2501             :   ASMJIT_INST_3x(vfnmadd213ss, Vfnmadd213ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2502             :   ASMJIT_INST_3x(vfnmadd213ss, Vfnmadd213ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2503             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2504             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2505             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2506             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2507             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2508             :   ASMJIT_INST_3x(vfnmadd231pd, Vfnmadd231pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2509             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2510             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2511             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2512             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2513             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2514             :   ASMJIT_INST_3x(vfnmadd231ps, Vfnmadd231ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2515             :   ASMJIT_INST_3x(vfnmadd231sd, Vfnmadd231sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2516             :   ASMJIT_INST_3x(vfnmadd231sd, Vfnmadd231sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2517             :   ASMJIT_INST_3x(vfnmadd231ss, Vfnmadd231ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2518             :   ASMJIT_INST_3x(vfnmadd231ss, Vfnmadd231ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2519             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2520             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2521             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2522             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2523             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2524             :   ASMJIT_INST_3x(vfnmsub132pd, Vfnmsub132pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2525             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2526             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2527             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2528             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2529             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2530             :   ASMJIT_INST_3x(vfnmsub132ps, Vfnmsub132ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2531             :   ASMJIT_INST_3x(vfnmsub132sd, Vfnmsub132sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2532             :   ASMJIT_INST_3x(vfnmsub132sd, Vfnmsub132sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2533             :   ASMJIT_INST_3x(vfnmsub132ss, Vfnmsub132ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2534             :   ASMJIT_INST_3x(vfnmsub132ss, Vfnmsub132ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2535             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2536             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2537             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2538             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2539             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2540             :   ASMJIT_INST_3x(vfnmsub213pd, Vfnmsub213pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2541             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2542             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2543             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2544             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2545             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2546             :   ASMJIT_INST_3x(vfnmsub213ps, Vfnmsub213ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2547             :   ASMJIT_INST_3x(vfnmsub213sd, Vfnmsub213sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2548             :   ASMJIT_INST_3x(vfnmsub213sd, Vfnmsub213sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2549             :   ASMJIT_INST_3x(vfnmsub213ss, Vfnmsub213ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2550             :   ASMJIT_INST_3x(vfnmsub213ss, Vfnmsub213ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2551             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b64}-VL
+    2552             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2553             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b64}-VL
+    2554             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b64}-VL
+    2555             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b64}
+    2556             :   ASMJIT_INST_3x(vfnmsub231pd, Vfnmsub231pd, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b64}
+    2557             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|b32}-VL
+    2558             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2559             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Ymm, X86Ymm, X86Ymm)          // FMA  AVX512_F{kz|b32}-VL
+    2560             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Ymm, X86Ymm, X86Mem)          // FMA  AVX512_F{kz|b32}-VL
+    2561             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Zmm, X86Zmm, X86Zmm)          // FMA  AVX512_F{kz|er|b32}
+    2562             :   ASMJIT_INST_3x(vfnmsub231ps, Vfnmsub231ps, X86Zmm, X86Zmm, X86Mem)          // FMA  AVX512_F{kz|er|b32}
+    2563             :   ASMJIT_INST_3x(vfnmsub231sd, Vfnmsub231sd, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2564             :   ASMJIT_INST_3x(vfnmsub231sd, Vfnmsub231sd, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2565             :   ASMJIT_INST_3x(vfnmsub231ss, Vfnmsub231ss, X86Xmm, X86Xmm, X86Xmm)          // FMA  AVX512_F{kz|er}
+    2566             :   ASMJIT_INST_3x(vfnmsub231ss, Vfnmsub231ss, X86Xmm, X86Xmm, X86Mem)          // FMA  AVX512_F{kz|er}
+    2567             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k|b64}-VL
+    2568             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k|b64} AVX512_DQ{k|b64}-VL
+    2569             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Ymm, Imm)                //      AVX512_DQ{k|b64}-VL
+    2570             :   ASMJIT_INST_3i(vfpclasspd, Vfpclasspd, X86KReg, X86Zmm, Imm)                //      AVX512_DQ{k|b64}
+    2571             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k|b32}-VL
+    2572             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k|b32} AVX512_DQ{k|b32}-VL
+    2573             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Ymm, Imm)                //      AVX512_DQ{k|b32}-VL
+    2574             :   ASMJIT_INST_3i(vfpclassps, Vfpclassps, X86KReg, X86Zmm, Imm)                //      AVX512_DQ{k|b32}
+    2575             :   ASMJIT_INST_3i(vfpclasssd, Vfpclasssd, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k}
+    2576             :   ASMJIT_INST_3i(vfpclasssd, Vfpclasssd, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k}
+    2577             :   ASMJIT_INST_3i(vfpclassss, Vfpclassss, X86KReg, X86Xmm, Imm)                //      AVX512_DQ{k}
+    2578             :   ASMJIT_INST_3i(vfpclassss, Vfpclassss, X86KReg, X86Mem, Imm)                //      AVX512_DQ{k}
+    2579             :   ASMJIT_INST_3x(vgatherdpd, Vgatherdpd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2580             :   ASMJIT_INST_3x(vgatherdpd, Vgatherdpd, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    2581             :   ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2582             :   ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2583             :   ASMJIT_INST_2x(vgatherdpd, Vgatherdpd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2584             :   ASMJIT_INST_3x(vgatherdps, Vgatherdps, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2585             :   ASMJIT_INST_3x(vgatherdps, Vgatherdps, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    2586             :   ASMJIT_INST_2x(vgatherdps, Vgatherdps, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2587             :   ASMJIT_INST_2x(vgatherdps, Vgatherdps, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2588             :   ASMJIT_INST_2x(vgatherdps, Vgatherdps, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2589             :   ASMJIT_INST_1x(vgatherpf0dpd, Vgatherpf0dpd, X86Mem)                        //      AVX512_PF{k}
+    2590             :   ASMJIT_INST_1x(vgatherpf0dps, Vgatherpf0dps, X86Mem)                        //      AVX512_PF{k}
+    2591             :   ASMJIT_INST_1x(vgatherpf0qpd, Vgatherpf0qpd, X86Mem)                        //      AVX512_PF{k}
+    2592             :   ASMJIT_INST_1x(vgatherpf0qps, Vgatherpf0qps, X86Mem)                        //      AVX512_PF{k}
+    2593             :   ASMJIT_INST_1x(vgatherpf1dpd, Vgatherpf1dpd, X86Mem)                        //      AVX512_PF{k}
+    2594             :   ASMJIT_INST_1x(vgatherpf1dps, Vgatherpf1dps, X86Mem)                        //      AVX512_PF{k}
+    2595             :   ASMJIT_INST_1x(vgatherpf1qpd, Vgatherpf1qpd, X86Mem)                        //      AVX512_PF{k}
+    2596             :   ASMJIT_INST_1x(vgatherpf1qps, Vgatherpf1qps, X86Mem)                        //      AVX512_PF{k}
+    2597             :   ASMJIT_INST_3x(vgatherqpd, Vgatherqpd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2598             :   ASMJIT_INST_3x(vgatherqpd, Vgatherqpd, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    2599             :   ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2600             :   ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2601             :   ASMJIT_INST_2x(vgatherqpd, Vgatherqpd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2602             :   ASMJIT_INST_3x(vgatherqps, Vgatherqps, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    2603             :   ASMJIT_INST_2x(vgatherqps, Vgatherqps, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    2604             :   ASMJIT_INST_2x(vgatherqps, Vgatherqps, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    2605             :   ASMJIT_INST_2x(vgatherqps, Vgatherqps, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    2606             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b64}-VL
+    2607             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Xmm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    2608             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b64}-VL
+    2609             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Ymm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    2610             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Zmm, X86Zmm)                        //      AVX512_F{kz|sae|b64}
+    2611             :   ASMJIT_INST_2x(vgetexppd, Vgetexppd, X86Zmm, X86Mem)                        //      AVX512_F{kz|sae|b64}
+    2612             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b32}-VL
+    2613             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Xmm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    2614             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b32}-VL
+    2615             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Ymm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    2616             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Zmm, X86Zmm)                        //      AVX512_F{kz|sae|b32}
+    2617             :   ASMJIT_INST_2x(vgetexpps, Vgetexpps, X86Zmm, X86Mem)                        //      AVX512_F{kz|sae|b32}
+    2618             :   ASMJIT_INST_2x(vgetexpsd, Vgetexpsd, X86Xmm, X86Xmm)                        //      AVX512_F{kz|sae}
+    2619             :   ASMJIT_INST_2x(vgetexpsd, Vgetexpsd, X86Xmm, X86Mem)                        //      AVX512_F{kz|sae}
+    2620             :   ASMJIT_INST_2x(vgetexpss, Vgetexpss, X86Xmm, X86Xmm)                        //      AVX512_F{kz|sae}
+    2621             :   ASMJIT_INST_2x(vgetexpss, Vgetexpss, X86Xmm, X86Mem)                        //      AVX512_F{kz|sae}
+    2622             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|b64}-VL
+    2623             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|b64}-VL
+    2624             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Ymm, X86Ymm, Imm)                 //      AVX512_F{kz|b64}-VL
+    2625             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Ymm, X86Mem, Imm)                 //      AVX512_F{kz|b64}-VL
+    2626             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Zmm, X86Zmm, Imm)                 //      AVX512_F{kz|sae|b64}
+    2627             :   ASMJIT_INST_3i(vgetmantpd, Vgetmantpd, X86Zmm, X86Mem, Imm)                 //      AVX512_F{kz|sae|b64}
+    2628             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|b32}-VL
+    2629             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|b32}-VL
+    2630             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Ymm, X86Ymm, Imm)                 //      AVX512_F{kz|b32}-VL
+    2631             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Ymm, X86Mem, Imm)                 //      AVX512_F{kz|b32}-VL
+    2632             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Zmm, X86Zmm, Imm)                 //      AVX512_F{kz|sae|b32}
+    2633             :   ASMJIT_INST_3i(vgetmantps, Vgetmantps, X86Zmm, X86Mem, Imm)                 //      AVX512_F{kz|sae|b32}
+    2634             :   ASMJIT_INST_3i(vgetmantsd, Vgetmantsd, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|sae}
+    2635             :   ASMJIT_INST_3i(vgetmantsd, Vgetmantsd, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|sae}
+    2636             :   ASMJIT_INST_3i(vgetmantss, Vgetmantss, X86Xmm, X86Xmm, Imm)                 //      AVX512_F{kz|sae}
+    2637             :   ASMJIT_INST_3i(vgetmantss, Vgetmantss, X86Xmm, X86Mem, Imm)                 //      AVX512_F{kz|sae}
+    2638             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2639             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2640             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2641             :   ASMJIT_INST_3x(vhaddpd, Vhaddpd, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2642             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2643             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2644             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2645             :   ASMJIT_INST_3x(vhaddps, Vhaddps, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2646             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2647             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2648             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2649             :   ASMJIT_INST_3x(vhsubpd, Vhsubpd, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2650             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    2651             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    2652             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Ymm, X86Ymm, X86Ymm)                    // AVX
+    2653             :   ASMJIT_INST_3x(vhsubps, Vhsubps, X86Ymm, X86Ymm, X86Mem)                    // AVX
+    2654             :   ASMJIT_INST_4i(vinsertf128, Vinsertf128, X86Ymm, X86Ymm, X86Xmm, Imm)       // AVX
+    2655             :   ASMJIT_INST_4i(vinsertf128, Vinsertf128, X86Ymm, X86Ymm, X86Mem, Imm)       // AVX
+    2656             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_F{kz}-VL
+    2657             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_F{kz}-VL
+    2658             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_F{kz}
+    2659             :   ASMJIT_INST_4i(vinsertf32x4, Vinsertf32x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2660             :   ASMJIT_INST_4i(vinsertf32x8, Vinsertf32x8, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_DQ{kz}
+    2661             :   ASMJIT_INST_4i(vinsertf32x8, Vinsertf32x8, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2662             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_DQ{kz}-VL
+    2663             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_DQ{kz}-VL
+    2664             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_DQ{kz}
+    2665             :   ASMJIT_INST_4i(vinsertf64x2, Vinsertf64x2, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2666             :   ASMJIT_INST_4i(vinsertf64x4, Vinsertf64x4, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_F{kz}
+    2667             :   ASMJIT_INST_4i(vinsertf64x4, Vinsertf64x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2668             :   ASMJIT_INST_4i(vinserti128, Vinserti128, X86Ymm, X86Ymm, X86Xmm, Imm)       // AVX2
+    2669             :   ASMJIT_INST_4i(vinserti128, Vinserti128, X86Ymm, X86Ymm, X86Mem, Imm)       // AVX2
+    2670             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_F{kz}-VL
+    2671             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_F{kz}-VL
+    2672             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_F{kz}
+    2673             :   ASMJIT_INST_4i(vinserti32x4, Vinserti32x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2674             :   ASMJIT_INST_4i(vinserti32x8, Vinserti32x8, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_DQ{kz}
+    2675             :   ASMJIT_INST_4i(vinserti32x8, Vinserti32x8, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2676             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Ymm, X86Ymm, X86Xmm, Imm)     //      AVX512_DQ{kz}-VL
+    2677             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Ymm, X86Ymm, X86Mem, Imm)     //      AVX512_DQ{kz}-VL
+    2678             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Zmm, X86Zmm, X86Xmm, Imm)     //      AVX512_DQ{kz}
+    2679             :   ASMJIT_INST_4i(vinserti64x2, Vinserti64x2, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_DQ{kz}
+    2680             :   ASMJIT_INST_4i(vinserti64x4, Vinserti64x4, X86Zmm, X86Zmm, X86Ymm, Imm)     //      AVX512_F{kz}
+    2681             :   ASMJIT_INST_4i(vinserti64x4, Vinserti64x4, X86Zmm, X86Zmm, X86Mem, Imm)     //      AVX512_F{kz}
+    2682             :   ASMJIT_INST_4i(vinsertps, Vinsertps, X86Xmm, X86Xmm, X86Xmm, Imm)           // AVX  AVX512_F
+    2683             :   ASMJIT_INST_4i(vinsertps, Vinsertps, X86Xmm, X86Xmm, X86Mem, Imm)           // AVX  AVX512_F
+    2684             :   ASMJIT_INST_2x(vlddqu, Vlddqu, X86Xmm, X86Mem)                              // AVX
+    2685             :   ASMJIT_INST_2x(vlddqu, Vlddqu, X86Ymm, X86Mem)                              // AVX
+    2686             :   ASMJIT_INST_1x(vldmxcsr, Vldmxcsr, X86Mem)                                  // AVX
+    2687             :   ASMJIT_INST_3x(vmaskmovdqu, Vmaskmovdqu, X86Xmm, X86Xmm, DS_ZDI)            // AVX  [EXPLICIT]
+    2688             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Mem, X86Xmm, X86Xmm)              // AVX
+    2689             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Mem, X86Ymm, X86Ymm)              // AVX
+    2690             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Xmm, X86Xmm, X86Mem)              // AVX
+    2691             :   ASMJIT_INST_3x(vmaskmovpd, Vmaskmovpd, X86Ymm, X86Ymm, X86Mem)              // AVX
+    2692             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Mem, X86Xmm, X86Xmm)              // AVX
+    2693             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Mem, X86Ymm, X86Ymm)              // AVX
+    2694             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Xmm, X86Xmm, X86Mem)              // AVX
+    2695             :   ASMJIT_INST_3x(vmaskmovps, Vmaskmovps, X86Ymm, X86Ymm, X86Mem)              // AVX
+    2696             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2697             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2698             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2699             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2700             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2701             :   ASMJIT_INST_3x(vmaxpd, Vmaxpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2702             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2703             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2704             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2705             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2706             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b32}
+    2707             :   ASMJIT_INST_3x(vmaxps, Vmaxps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b32}
+    2708             :   ASMJIT_INST_3x(vmaxsd, Vmaxsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2709             :   ASMJIT_INST_3x(vmaxsd, Vmaxsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2710             :   ASMJIT_INST_3x(vmaxss, Vmaxss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2711             :   ASMJIT_INST_3x(vmaxss, Vmaxss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2712             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2713             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2714             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b64}-VL
+    2715             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2716             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b64}
+    2717             :   ASMJIT_INST_3x(vminpd, Vminpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b64}
+    2718             :   ASMJIT_INST_3x(vminps, Vminps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2719             :   ASMJIT_INST_3x(vminps, Vminps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2720             :   ASMJIT_INST_3x(vminps, Vminps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_F{kz|b32}-VL
+    2721             :   ASMJIT_INST_3x(vminps, Vminps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2722             :   ASMJIT_INST_3x(vminps, Vminps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|sae|b32}
+    2723             :   ASMJIT_INST_3x(vminps, Vminps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|sae|b32}
+    2724             :   ASMJIT_INST_3x(vminsd, Vminsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2725             :   ASMJIT_INST_3x(vminsd, Vminsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2726             :   ASMJIT_INST_3x(vminss, Vminss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|sae}-VL
+    2727             :   ASMJIT_INST_3x(vminss, Vminss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|sae}-VL
+    2728             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2729             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2730             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2731             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2732             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2733             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2734             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2735             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2736             :   ASMJIT_INST_2x(vmovapd, Vmovapd, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2737             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2738             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2739             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2740             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2741             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2742             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2743             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2744             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2745             :   ASMJIT_INST_2x(vmovaps, Vmovaps, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2746             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Gp, X86Xmm)                                 // AVX  AVX512_F
+    2747             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Mem, X86Xmm)                                // AVX  AVX512_F
+    2748             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Xmm, X86Gp)                                 // AVX  AVX512_F
+    2749             :   ASMJIT_INST_2x(vmovd, Vmovd, X86Xmm, X86Mem)                                // AVX  AVX512_F
+    2750             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Xmm, X86Xmm)                          // AVX  AVX512_F{kz}-VL
+    2751             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Xmm, X86Mem)                          // AVX  AVX512_F{kz}-VL
+    2752             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Ymm, X86Ymm)                          // AVX  AVX512_F{kz}-VL
+    2753             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Ymm, X86Mem)                          // AVX  AVX512_F{kz}-VL
+    2754             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Zmm, X86Zmm)                          //      AVX512_F{kz}
+    2755             :   ASMJIT_INST_2x(vmovddup, Vmovddup, X86Zmm, X86Mem)                          //      AVX512_F{kz}
+    2756             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Xmm, X86Xmm)                            // AVX
+    2757             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Xmm, X86Mem)                            // AVX
+    2758             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Mem, X86Xmm)                            // AVX
+    2759             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Ymm, X86Ymm)                            // AVX
+    2760             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Ymm, X86Mem)                            // AVX
+    2761             :   ASMJIT_INST_2x(vmovdqa, Vmovdqa, X86Mem, X86Ymm)                            // AVX
+    2762             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2763             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2764             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2765             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2766             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2767             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2768             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2769             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2770             :   ASMJIT_INST_2x(vmovdqa32, Vmovdqa32, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2771             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2772             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2773             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2774             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2775             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2776             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2777             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2778             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2779             :   ASMJIT_INST_2x(vmovdqa64, Vmovdqa64, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2780             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Xmm, X86Xmm)                            // AVX
+    2781             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Xmm, X86Mem)                            // AVX
+    2782             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Mem, X86Xmm)                            // AVX
+    2783             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Ymm, X86Ymm)                            // AVX
+    2784             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Ymm, X86Mem)                            // AVX
+    2785             :   ASMJIT_INST_2x(vmovdqu, Vmovdqu, X86Mem, X86Ymm)                            // AVX
+    2786             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Xmm, X86Xmm)                        //      AVX512_BW{kz}-VL
+    2787             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Xmm, X86Mem)                        //      AVX512_BW{kz}-VL
+    2788             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Mem, X86Xmm)                        //      AVX512_BW{kz}-VL
+    2789             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Ymm, X86Ymm)                        //      AVX512_BW{kz}-VL
+    2790             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Ymm, X86Mem)                        //      AVX512_BW{kz}-VL
+    2791             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Mem, X86Ymm)                        //      AVX512_BW{kz}-VL
+    2792             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Zmm, X86Zmm)                        //      AVX512_BW{kz}
+    2793             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Zmm, X86Mem)                        //      AVX512_BW{kz}
+    2794             :   ASMJIT_INST_2x(vmovdqu16, Vmovdqu16, X86Mem, X86Zmm)                        //      AVX512_BW{kz}
+    2795             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2796             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2797             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2798             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2799             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2800             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2801             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2802             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2803             :   ASMJIT_INST_2x(vmovdqu32, Vmovdqu32, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2804             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    2805             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    2806             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    2807             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    2808             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    2809             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    2810             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2811             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2812             :   ASMJIT_INST_2x(vmovdqu64, Vmovdqu64, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    2813             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Xmm, X86Xmm)                          //      AVX512_BW{kz}-VL
+    2814             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Xmm, X86Mem)                          //      AVX512_BW{kz}-VL
+    2815             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Mem, X86Xmm)                          //      AVX512_BW{kz}-VL
+    2816             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Ymm, X86Ymm)                          //      AVX512_BW{kz}-VL
+    2817             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Ymm, X86Mem)                          //      AVX512_BW{kz}-VL
+    2818             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Mem, X86Ymm)                          //      AVX512_BW{kz}-VL
+    2819             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Zmm, X86Zmm)                          //      AVX512_BW{kz}
+    2820             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Zmm, X86Mem)                          //      AVX512_BW{kz}
+    2821             :   ASMJIT_INST_2x(vmovdqu8, Vmovdqu8, X86Mem, X86Zmm)                          //      AVX512_BW{kz}
+    2822             :   ASMJIT_INST_3x(vmovhlps, Vmovhlps, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_F
+    2823             :   ASMJIT_INST_2x(vmovhpd, Vmovhpd, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2824             :   ASMJIT_INST_3x(vmovhpd, Vmovhpd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2825             :   ASMJIT_INST_2x(vmovhps, Vmovhps, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2826             :   ASMJIT_INST_3x(vmovhps, Vmovhps, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2827             :   ASMJIT_INST_3x(vmovlhps, Vmovlhps, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_F
+    2828             :   ASMJIT_INST_2x(vmovlpd, Vmovlpd, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2829             :   ASMJIT_INST_3x(vmovlpd, Vmovlpd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2830             :   ASMJIT_INST_2x(vmovlps, Vmovlps, X86Mem, X86Xmm)                            // AVX  AVX512_F
+    2831             :   ASMJIT_INST_3x(vmovlps, Vmovlps, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F
+    2832             :   ASMJIT_INST_2x(vmovmskpd, Vmovmskpd, X86Gp, X86Xmm)                         // AVX
+    2833             :   ASMJIT_INST_2x(vmovmskpd, Vmovmskpd, X86Gp, X86Ymm)                         // AVX
+    2834             :   ASMJIT_INST_2x(vmovmskps, Vmovmskps, X86Gp, X86Xmm)                         // AVX
+    2835             :   ASMJIT_INST_2x(vmovmskps, Vmovmskps, X86Gp, X86Ymm)                         // AVX
+    2836             :   ASMJIT_INST_2x(vmovntdq, Vmovntdq, X86Mem, X86Xmm)                          // AVX  AVX512_F-VL
+    2837             :   ASMJIT_INST_2x(vmovntdq, Vmovntdq, X86Mem, X86Ymm)                          // AVX  AVX512_F-VL
+    2838             :   ASMJIT_INST_2x(vmovntdq, Vmovntdq, X86Mem, X86Zmm)                          //      AVX512_F
+    2839             :   ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, X86Xmm, X86Mem)                        // AVX  AVX512_F-VL
+    2840             :   ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, X86Ymm, X86Mem)                        // AVX2 AVX512_F-VL
+    2841             :   ASMJIT_INST_2x(vmovntdqa, Vmovntdqa, X86Zmm, X86Mem)                        //      AVX512_F
+    2842             :   ASMJIT_INST_2x(vmovntpd, Vmovntpd, X86Mem, X86Xmm)                          // AVX  AVX512_F-VL
+    2843             :   ASMJIT_INST_2x(vmovntpd, Vmovntpd, X86Mem, X86Ymm)                          // AVX  AVX512_F-VL
+    2844             :   ASMJIT_INST_2x(vmovntpd, Vmovntpd, X86Mem, X86Zmm)                          //      AVX512_F
+    2845             :   ASMJIT_INST_2x(vmovntps, Vmovntps, X86Mem, X86Xmm)                          // AVX  AVX512_F-VL
+    2846             :   ASMJIT_INST_2x(vmovntps, Vmovntps, X86Mem, X86Ymm)                          // AVX  AVX512_F-VL
+    2847             :   ASMJIT_INST_2x(vmovntps, Vmovntps, X86Mem, X86Zmm)                          //      AVX512_F
+    2848             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Gp, X86Xmm)                                 // AVX  AVX512_F
+    2849             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Mem, X86Xmm)                                // AVX  AVX512_F
+    2850             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Xmm, X86Mem)                                // AVX  AVX512_F
+    2851             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Xmm, X86Gp)                                 // AVX  AVX512_F
+    2852             :   ASMJIT_INST_2x(vmovq, Vmovq, X86Xmm, X86Xmm)                                // AVX  AVX512_F
+    2853             :   ASMJIT_INST_2x(vmovsd, Vmovsd, X86Mem, X86Xmm)                              // AVX  AVX512_F
+    2854             :   ASMJIT_INST_2x(vmovsd, Vmovsd, X86Xmm, X86Mem)                              // AVX  AVX512_F{kz}
+    2855             :   ASMJIT_INST_3x(vmovsd, Vmovsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}
+    2856             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    2857             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2858             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz}-VL
+    2859             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2860             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2861             :   ASMJIT_INST_2x(vmovshdup, Vmovshdup, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2862             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    2863             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2864             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz}-VL
+    2865             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    2866             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    2867             :   ASMJIT_INST_2x(vmovsldup, Vmovsldup, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    2868             :   ASMJIT_INST_2x(vmovss, Vmovss, X86Mem, X86Xmm)                              // AVX  AVX512_F
+    2869             :   ASMJIT_INST_2x(vmovss, Vmovss, X86Xmm, X86Mem)                              // AVX  AVX512_F{kz}
+    2870             :   ASMJIT_INST_3x(vmovss, Vmovss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}
+    2871             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2872             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2873             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2874             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2875             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2876             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2877             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2878             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2879             :   ASMJIT_INST_2x(vmovupd, Vmovupd, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2880             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2881             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2882             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Mem, X86Xmm)                            // AVX  AVX512_F{kz}-VL
+    2883             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2884             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz}-VL
+    2885             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Mem, X86Ymm)                            // AVX  AVX512_F{kz}-VL
+    2886             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Zmm, X86Zmm)                            //      AVX512_F{kz}
+    2887             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Zmm, X86Mem)                            //      AVX512_F{kz}
+    2888             :   ASMJIT_INST_2x(vmovups, Vmovups, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    2889             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    2890             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    2891             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2
+    2892             :   ASMJIT_INST_4i(vmpsadbw, Vmpsadbw, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2
+    2893             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2894             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2895             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    2896             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    2897             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    2898             :   ASMJIT_INST_3x(vmulpd, Vmulpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    2899             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2900             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2901             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    2902             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    2903             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    2904             :   ASMJIT_INST_3x(vmulps, Vmulps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    2905             :   ASMJIT_INST_3x(vmulsd, Vmulsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2906             :   ASMJIT_INST_3x(vmulsd, Vmulsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2907             :   ASMJIT_INST_3x(vmulss, Vmulss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    2908             :   ASMJIT_INST_3x(vmulss, Vmulss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    2909             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Xmm, X86Xmm, X86Xmm)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2910             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Xmm, X86Xmm, X86Mem)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2911             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Ymm, X86Ymm, X86Ymm)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2912             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Ymm, X86Ymm, X86Mem)                        // AVX  AVX512_DQ{kz|b64}-VL
+    2913             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_DQ{kz|b64}
+    2914             :   ASMJIT_INST_3x(vorpd, Vorpd, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_DQ{kz|b64}
+    2915             :   ASMJIT_INST_3x(vorps, Vorps, X86Xmm, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz|b32}-VL
+    2916             :   ASMJIT_INST_3x(vorps, Vorps, X86Xmm, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2917             :   ASMJIT_INST_3x(vorps, Vorps, X86Ymm, X86Ymm, X86Ymm)                        // AVX  AVX512_F{kz|b32}-VL
+    2918             :   ASMJIT_INST_3x(vorps, Vorps, X86Ymm, X86Ymm, X86Mem)                        // AVX  AVX512_F{kz|b32}-VL
+    2919             :   ASMJIT_INST_3x(vorps, Vorps, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_F{kz|b32}
+    2920             :   ASMJIT_INST_3x(vorps, Vorps, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_F{kz|b32}
+    2921             :   ASMJIT_INST_6x(vp4dpwssd, Vp4dpwssd, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem)   // AVX512_4FMAPS{kz}
+    2922             :   ASMJIT_INST_6x(vp4dpwssds, Vp4dpwssds, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Zmm, X86Mem) // AVX512_4FMAPS{kz}
+    2923             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Xmm, X86Xmm)                              // AVX  AVX512_BW{kz}-VL
+    2924             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Xmm, X86Mem)                              // AVX  AVX512_BW{kz}-VL
+    2925             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Ymm, X86Ymm)                              // AVX2 AVX512_BW{kz}-VL
+    2926             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Ymm, X86Mem)                              // AVX2 AVX512_BW{kz}-VL
+    2927             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Zmm, X86Zmm)                              //      AVX512_BW{kz}
+    2928             :   ASMJIT_INST_2x(vpabsb, Vpabsb, X86Zmm, X86Mem)                              //      AVX512_BW{kz}
+    2929             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Xmm, X86Xmm)                              // AVX  AVX512_F{kz}-VL
+    2930             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Xmm, X86Mem)                              // AVX  AVX512_F{kz}-VL
+    2931             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Ymm, X86Ymm)                              // AVX2 AVX512_F{kz}-VL
+    2932             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Ymm, X86Mem)                              // AVX2 AVX512_F{kz}-VL
+    2933             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Zmm, X86Zmm)                              //      AVX512_F{kz}
+    2934             :   ASMJIT_INST_2x(vpabsd, Vpabsd, X86Zmm, X86Mem)                              //      AVX512_F{kz}
+    2935             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Xmm, X86Xmm)                              //      AVX512_F{kz}-VL
+    2936             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Xmm, X86Mem)                              //      AVX512_F{kz}-VL
+    2937             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Ymm, X86Ymm)                              //      AVX512_F{kz}-VL
+    2938             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Ymm, X86Mem)                              //      AVX512_F{kz}-VL
+    2939             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Zmm, X86Zmm)                              //      AVX512_F{kz}
+    2940             :   ASMJIT_INST_2x(vpabsq, Vpabsq, X86Zmm, X86Mem)                              //      AVX512_F{kz}
+    2941             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Xmm, X86Xmm)                              // AVX  AVX512_BW{kz}-VL
+    2942             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Xmm, X86Mem)                              // AVX  AVX512_BW{kz}-VL
+    2943             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Ymm, X86Ymm)                              // AVX2 AVX512_BW{kz}-VL
+    2944             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Ymm, X86Mem)                              // AVX2 AVX512_BW{kz}-VL
+    2945             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Zmm, X86Zmm)                              //      AVX512_BW{kz}
+    2946             :   ASMJIT_INST_2x(vpabsw, Vpabsw, X86Zmm, X86Mem)                              //      AVX512_BW{kz}
+    2947             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz|b32}-VL
+    2948             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz|b32}-VL
+    2949             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz|b32}-VL
+    2950             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz|b32}-VL
+    2951             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz|b32}
+    2952             :   ASMJIT_INST_3x(vpackssdw, Vpackssdw, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz|b32}
+    2953             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz}-VL
+    2954             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz}-VL
+    2955             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz}-VL
+    2956             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz}-VL
+    2957             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz}
+    2958             :   ASMJIT_INST_3x(vpacksswb, Vpacksswb, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz}
+    2959             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz|b32}-VL
+    2960             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz|b32}-VL
+    2961             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz|b32}-VL
+    2962             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz|b32}-VL
+    2963             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz|b32}
+    2964             :   ASMJIT_INST_3x(vpackusdw, Vpackusdw, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz|b32}
+    2965             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz}-VL
+    2966             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz}-VL
+    2967             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz}-VL
+    2968             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz}-VL
+    2969             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz}
+    2970             :   ASMJIT_INST_3x(vpackuswb, Vpackuswb, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz}
+    2971             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    2972             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    2973             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    2974             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    2975             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    2976             :   ASMJIT_INST_3x(vpaddb, Vpaddb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    2977             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    2978             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    2979             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    2980             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    2981             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    2982             :   ASMJIT_INST_3x(vpaddd, Vpaddd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    2983             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    2984             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    2985             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    2986             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    2987             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    2988             :   ASMJIT_INST_3x(vpaddq, Vpaddq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    2989             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    2990             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    2991             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    2992             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    2993             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    2994             :   ASMJIT_INST_3x(vpaddsb, Vpaddsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    2995             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    2996             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    2997             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    2998             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    2999             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3000             :   ASMJIT_INST_3x(vpaddsw, Vpaddsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3001             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3002             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3003             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3004             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3005             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3006             :   ASMJIT_INST_3x(vpaddusb, Vpaddusb, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3007             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3008             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3009             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3010             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3011             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3012             :   ASMJIT_INST_3x(vpaddusw, Vpaddusw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3013             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    3014             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    3015             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    3016             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    3017             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3018             :   ASMJIT_INST_3x(vpaddw, Vpaddw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3019             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX  AVX512_BW{kz}-VL
+    3020             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX  AVX512_BW{kz}-VL
+    3021             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2 AVX512_BW{kz}-VL
+    3022             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2 AVX512_BW{kz}-VL
+    3023             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Zmm, X86Zmm, X86Zmm, Imm)             //      AVX512_BW{kz}
+    3024             :   ASMJIT_INST_4i(vpalignr, Vpalignr, X86Zmm, X86Zmm, X86Mem, Imm)             //      AVX512_BW{kz}
+    3025             :   ASMJIT_INST_3x(vpand, Vpand, X86Xmm, X86Xmm, X86Xmm)                        // AVX
+    3026             :   ASMJIT_INST_3x(vpand, Vpand, X86Xmm, X86Xmm, X86Mem)                        // AVX
+    3027             :   ASMJIT_INST_3x(vpand, Vpand, X86Ymm, X86Ymm, X86Ymm)                        // AVX2
+    3028             :   ASMJIT_INST_3x(vpand, Vpand, X86Ymm, X86Ymm, X86Mem)                        // AVX2
+    3029             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    3030             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    3031             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    3032             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    3033             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    3034             :   ASMJIT_INST_3x(vpandd, Vpandd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    3035             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Xmm, X86Xmm, X86Xmm)                      // AVX
+    3036             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Xmm, X86Xmm, X86Mem)                      // AVX
+    3037             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Ymm, X86Ymm, X86Ymm)                      // AVX2
+    3038             :   ASMJIT_INST_3x(vpandn, Vpandn, X86Ymm, X86Ymm, X86Mem)                      // AVX2
+    3039             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    3040             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3041             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    3042             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3043             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3044             :   ASMJIT_INST_3x(vpandnd, Vpandnd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3045             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3046             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3047             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3048             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3049             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3050             :   ASMJIT_INST_3x(vpandnq, Vpandnq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3051             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    3052             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3053             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    3054             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3055             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    3056             :   ASMJIT_INST_3x(vpandq, Vpandq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    3057             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    3058             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    3059             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_BW{kz}-VL
+    3060             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    3061             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3062             :   ASMJIT_INST_3x(vpavgb, Vpavgb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3063             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Xmm, X86Xmm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    3064             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Xmm, X86Xmm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    3065             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    3066             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    3067             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3068             :   ASMJIT_INST_3x(vpavgw, Vpavgw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3069             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX2
+    3070             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX2
+    3071             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2
+    3072             :   ASMJIT_INST_4i(vpblendd, Vpblendd, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2
+    3073             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // AVX
+    3074             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // AVX
+    3075             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // AVX2
+    3076             :   ASMJIT_INST_4x(vpblendvb, Vpblendvb, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // AVX2
+    3077             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    3078             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    3079             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Ymm, X86Ymm, X86Ymm, Imm)             // AVX2
+    3080             :   ASMJIT_INST_4i(vpblendw, Vpblendw, X86Ymm, X86Ymm, X86Mem, Imm)             // AVX2
+    3081             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Xmm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3082             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Xmm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3083             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Ymm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3084             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3085             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Xmm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3086             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Ymm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3087             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Zmm, X86Gp)                   //      AVX512_BW{kz}
+    3088             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Zmm, X86Xmm)                  //      AVX512_BW{kz}
+    3089             :   ASMJIT_INST_2x(vpbroadcastb, Vpbroadcastb, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3090             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Xmm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3091             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Xmm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3092             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3093             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Ymm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3094             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Xmm, X86Gp)                   //      AVX512_F{kz}-VL
+    3095             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Ymm, X86Gp)                   //      AVX512_F{kz}-VL
+    3096             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Zmm, X86Gp)                   //      AVX512_F{kz}
+    3097             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Zmm, X86Xmm)                  //      AVX512_F{kz}
+    3098             :   ASMJIT_INST_2x(vpbroadcastd, Vpbroadcastd, X86Zmm, X86Mem)                  //      AVX512_F{kz}
+    3099             :   ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, X86Xmm, X86KReg)           //      AVX512_CD-VL
+    3100             :   ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, X86Ymm, X86KReg)           //      AVX512_CD-VL
+    3101             :   ASMJIT_INST_2x(vpbroadcastmb2d, Vpbroadcastmb2d, X86Zmm, X86KReg)           //      AVX512_CD
+    3102             :   ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, X86Xmm, X86KReg)           //      AVX512_CD-VL
+    3103             :   ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, X86Ymm, X86KReg)           //      AVX512_CD-VL
+    3104             :   ASMJIT_INST_2x(vpbroadcastmb2q, Vpbroadcastmb2q, X86Zmm, X86KReg)           //      AVX512_CD
+    3105             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Xmm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3106             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Xmm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3107             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Ymm, X86Xmm)                  // AVX2 AVX512_F{kz}-VL
+    3108             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Ymm, X86Mem)                  // AVX2 AVX512_F{kz}-VL
+    3109             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Xmm, X86Gp)                   //      AVX512_F{kz}-VL
+    3110             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Ymm, X86Gp)                   //      AVX512_F{kz}-VL
+    3111             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Zmm, X86Gp)                   //      AVX512_F{kz}
+    3112             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Zmm, X86Xmm)                  //      AVX512_F{kz}
+    3113             :   ASMJIT_INST_2x(vpbroadcastq, Vpbroadcastq, X86Zmm, X86Mem)                  //      AVX512_F{kz}
+    3114             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Xmm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3115             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Xmm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3116             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Ymm, X86Xmm)                  // AVX2 AVX512_BW{kz}-VL
+    3117             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3118             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Xmm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3119             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Ymm, X86Gp)                   //      AVX512_BW{kz}-VL
+    3120             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Zmm, X86Gp)                   //      AVX512_BW{kz}
+    3121             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Zmm, X86Xmm)                  //      AVX512_BW{kz}
+    3122             :   ASMJIT_INST_2x(vpbroadcastw, Vpbroadcastw, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3123             :   ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, X86Xmm, X86Xmm, X86Xmm, Imm)         // AVX
+    3124             :   ASMJIT_INST_4i(vpclmulqdq, Vpclmulqdq, X86Xmm, X86Xmm, X86Mem, Imm)         // AVX
+    3125             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_BW{k}-VL
+    3126             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_BW{k}-VL
+    3127             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_BW{k}-VL
+    3128             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_BW{k}-VL
+    3129             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_BW{k}
+    3130             :   ASMJIT_INST_4i(vpcmpb, Vpcmpb, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_BW{k}
+    3131             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{k|b32}-VL
+    3132             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{k|b32}-VL
+    3133             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{k|b32}-VL
+    3134             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{k|b32}-VL
+    3135             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{k|b32}
+    3136             :   ASMJIT_INST_4i(vpcmpd, Vpcmpd, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{k|b32}
+    3137             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3138             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3139             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3140             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3141             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3142             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3143             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3144             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3145             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3146             :   ASMJIT_INST_3x(vpcmpeqb, Vpcmpeqb, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3147             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3148             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3149             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3150             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3151             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b32}-VL
+    3152             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3153             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b32}-VL
+    3154             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3155             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b32}
+    3156             :   ASMJIT_INST_3x(vpcmpeqd, Vpcmpeqd, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b32}
+    3157             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3158             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3159             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3160             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3161             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b64}-VL
+    3162             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3163             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b64}-VL
+    3164             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3165             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b64}
+    3166             :   ASMJIT_INST_3x(vpcmpeqq, Vpcmpeqq, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b64}
+    3167             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3168             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3169             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3170             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3171             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3172             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3173             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3174             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3175             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3176             :   ASMJIT_INST_3x(vpcmpeqw, Vpcmpeqw, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3177             :   ASMJIT_INST_6x(vpcmpestri, Vpcmpestri, X86Xmm, X86Xmm, Imm, ECX, EAX, EDX)  // AVX  [EXPLICIT]
+    3178             :   ASMJIT_INST_6x(vpcmpestri, Vpcmpestri, X86Xmm, X86Mem, Imm, ECX, EAX, EDX)  // AVX  [EXPLICIT]
+    3179             :   ASMJIT_INST_6x(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Xmm, Imm, XMM0, EAX, EDX) // AVX  [EXPLICIT]
+    3180             :   ASMJIT_INST_6x(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Mem, Imm, XMM0, EAX, EDX) // AVX  [EXPLICIT]
+    3181             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3182             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3183             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3184             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3185             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3186             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3187             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3188             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3189             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3190             :   ASMJIT_INST_3x(vpcmpgtb, Vpcmpgtb, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3191             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3192             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3193             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3194             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3195             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b32}-VL
+    3196             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3197             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b32}-VL
+    3198             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    3199             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b32}
+    3200             :   ASMJIT_INST_3x(vpcmpgtd, Vpcmpgtd, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b32}
+    3201             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3202             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3203             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3204             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3205             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b64}-VL
+    3206             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3207             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b64}-VL
+    3208             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    3209             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b64}
+    3210             :   ASMJIT_INST_3x(vpcmpgtq, Vpcmpgtq, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b64}
+    3211             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3212             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3213             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3214             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3215             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    3216             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    3217             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    3218             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    3219             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    3220             :   ASMJIT_INST_3x(vpcmpgtw, Vpcmpgtw, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    3221             :   ASMJIT_INST_4x(vpcmpistri, Vpcmpistri, X86Xmm, X86Xmm, Imm, ECX)            // AVX  [EXPLICIT]
+    3222             :   ASMJIT_INST_4x(vpcmpistri, Vpcmpistri, X86Xmm, X86Mem, Imm, ECX)            // AVX  [EXPLICIT]
+    3223             :   ASMJIT_INST_4x(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Xmm, Imm, XMM0)           // AVX  [EXPLICIT]
+    3224             :   ASMJIT_INST_4x(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Mem, Imm, XMM0)           // AVX  [EXPLICIT]
+    3225             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_F{k|b64}-VL
+    3226             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_F{k|b64}-VL
+    3227             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_F{k|b64}-VL
+    3228             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_F{k|b64}-VL
+    3229             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_F{k|b64}
+    3230             :   ASMJIT_INST_4i(vpcmpq, Vpcmpq, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_F{k|b64}
+    3231             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_BW{k}-VL
+    3232             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_BW{k}-VL
+    3233             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_BW{k}-VL
+    3234             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_BW{k}-VL
+    3235             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_BW{k}
+    3236             :   ASMJIT_INST_4i(vpcmpub, Vpcmpub, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_BW{k}
+    3237             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_F{k|b32}-VL
+    3238             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_F{k|b32}-VL
+    3239             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_F{k|b32}-VL
+    3240             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_F{k|b32}-VL
+    3241             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_F{k|b32}
+    3242             :   ASMJIT_INST_4i(vpcmpud, Vpcmpud, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_F{k|b32}
+    3243             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_F{k|b64}-VL
+    3244             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_F{k|b64}-VL
+    3245             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_F{k|b64}-VL
+    3246             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_F{k|b64}-VL
+    3247             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_F{k|b64}
+    3248             :   ASMJIT_INST_4i(vpcmpuq, Vpcmpuq, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_F{k|b64}
+    3249             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Xmm, X86Xmm, Imm)              //      AVX512_BW{k|b64}-VL
+    3250             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Xmm, X86Mem, Imm)              //      AVX512_BW{k|b64}-VL
+    3251             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Ymm, X86Ymm, Imm)              //      AVX512_BW{k|b64}-VL
+    3252             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Ymm, X86Mem, Imm)              //      AVX512_BW{k|b64}-VL
+    3253             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Zmm, X86Zmm, Imm)              //      AVX512_BW{k|b64}
+    3254             :   ASMJIT_INST_4i(vpcmpuw, Vpcmpuw, X86KReg, X86Zmm, X86Mem, Imm)              //      AVX512_BW{k|b64}
+    3255             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Xmm, X86Xmm, Imm)                //      AVX512_BW{k|b64}-VL
+    3256             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Xmm, X86Mem, Imm)                //      AVX512_BW{k|b64}-VL
+    3257             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Ymm, X86Ymm, Imm)                //      AVX512_BW{k|b64}-VL
+    3258             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Ymm, X86Mem, Imm)                //      AVX512_BW{k|b64}-VL
+    3259             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Zmm, X86Zmm, Imm)                //      AVX512_BW{k|b64}
+    3260             :   ASMJIT_INST_4i(vpcmpw, Vpcmpw, X86KReg, X86Zmm, X86Mem, Imm)                //      AVX512_BW{k|b64}
+    3261             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    3262             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    3263             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    3264             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    3265             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    3266             :   ASMJIT_INST_2x(vpcompressd, Vpcompressd, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    3267             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Xmm, X86Xmm)                    //      AVX512_F{kz}-VL
+    3268             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Mem, X86Xmm)                    //      AVX512_F{kz}-VL
+    3269             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Ymm, X86Ymm)                    //      AVX512_F{kz}-VL
+    3270             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Mem, X86Ymm)                    //      AVX512_F{kz}-VL
+    3271             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Zmm, X86Zmm)                    //      AVX512_F{kz}
+    3272             :   ASMJIT_INST_2x(vpcompressq, Vpcompressq, X86Mem, X86Zmm)                    //      AVX512_F{kz}
+    3273             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Xmm, X86Xmm)                    //      AVX512_CD{kz|b32}-VL
+    3274             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Xmm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3275             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Ymm, X86Ymm)                    //      AVX512_CD{kz|b32}-VL
+    3276             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Ymm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3277             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Zmm, X86Zmm)                    //      AVX512_CD{kz|b32}
+    3278             :   ASMJIT_INST_2x(vpconflictd, Vpconflictd, X86Zmm, X86Mem)                    //      AVX512_CD{kz|b32}
+    3279             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Xmm, X86Xmm)                    //      AVX512_CD{kz|b32}-VL
+    3280             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Xmm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3281             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Ymm, X86Ymm)                    //      AVX512_CD{kz|b32}-VL
+    3282             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Ymm, X86Mem)                    //      AVX512_CD{kz|b32}-VL
+    3283             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Zmm, X86Zmm)                    //      AVX512_CD{kz|b32}
+    3284             :   ASMJIT_INST_2x(vpconflictq, Vpconflictq, X86Zmm, X86Mem)                    //      AVX512_CD{kz|b32}
+    3285             :   ASMJIT_INST_4i(vperm2f128, Vperm2f128, X86Ymm, X86Ymm, X86Ymm, Imm)         // AVX
+    3286             :   ASMJIT_INST_4i(vperm2f128, Vperm2f128, X86Ymm, X86Ymm, X86Mem, Imm)         // AVX
+    3287             :   ASMJIT_INST_4i(vperm2i128, Vperm2i128, X86Ymm, X86Ymm, X86Ymm, Imm)         // AVX2
+    3288             :   ASMJIT_INST_4i(vperm2i128, Vperm2i128, X86Ymm, X86Ymm, X86Mem, Imm)         // AVX2
+    3289             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_VBMI{kz}-VL
+    3290             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_VBMI{kz}-VL
+    3291             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_VBMI{kz}-VL
+    3292             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_VBMI{kz}-VL
+    3293             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_VBMI{kz}
+    3294             :   ASMJIT_INST_3x(vpermb, Vpermb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_VBMI{kz}
+    3295             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    3296             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    3297             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}-VL
+    3298             :   ASMJIT_INST_3x(vpermd, Vpermd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    3299             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_VBMI{kz}-VL
+    3300             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3301             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_VBMI{kz}-VL
+    3302             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3303             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_VBMI{kz}
+    3304             :   ASMJIT_INST_3x(vpermi2b, Vpermi2b, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_VBMI{kz}
+    3305             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b32}-VL
+    3306             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3307             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b32}-VL
+    3308             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3309             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b32}
+    3310             :   ASMJIT_INST_3x(vpermi2d, Vpermi2d, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b32}
+    3311             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    3312             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3313             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    3314             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3315             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3316             :   ASMJIT_INST_3x(vpermi2pd, Vpermi2pd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3317             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    3318             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3319             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    3320             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3321             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    3322             :   ASMJIT_INST_3x(vpermi2ps, Vpermi2ps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    3323             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b64}-VL
+    3324             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3325             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b64}-VL
+    3326             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3327             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    3328             :   ASMJIT_INST_3x(vpermi2q, Vpermi2q, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    3329             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    3330             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3331             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    3332             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3333             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3334             :   ASMJIT_INST_3x(vpermi2w, Vpermi2w, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3335             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    3336             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3337             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Xmm, X86Xmm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3338             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Xmm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3339             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    3340             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3341             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Ymm, X86Ymm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3342             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Ymm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3343             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3344             :   ASMJIT_INST_3x(vpermilpd, Vpermilpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3345             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Zmm, X86Zmm, Imm)                   //      AVX512_F{kz|b64}
+    3346             :   ASMJIT_INST_3i(vpermilpd, Vpermilpd, X86Zmm, X86Mem, Imm)                   //      AVX512_F{kz|b64}
+    3347             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    3348             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3349             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Xmm, X86Xmm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3350             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Xmm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3351             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    3352             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    3353             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Ymm, X86Ymm, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3354             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Ymm, X86Mem, Imm)                   // AVX  AVX512_F{kz|b64}-VL
+    3355             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3356             :   ASMJIT_INST_3x(vpermilps, Vpermilps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3357             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Zmm, X86Zmm, Imm)                   //      AVX512_F{kz|b64}
+    3358             :   ASMJIT_INST_3i(vpermilps, Vpermilps, X86Zmm, X86Mem, Imm)                   //      AVX512_F{kz|b64}
+    3359             :   ASMJIT_INST_3i(vpermpd, Vpermpd, X86Ymm, X86Ymm, Imm)                       // AVX2
+    3360             :   ASMJIT_INST_3i(vpermpd, Vpermpd, X86Ymm, X86Mem, Imm)                       // AVX2
+    3361             :   ASMJIT_INST_3x(vpermps, Vpermps, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3362             :   ASMJIT_INST_3x(vpermps, Vpermps, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3363             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    3364             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Ymm, X86Mem, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    3365             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    3366             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3367             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}-VL
+    3368             :   ASMJIT_INST_3x(vpermq, Vpermq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    3369             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3370             :   ASMJIT_INST_3i(vpermq, Vpermq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3371             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_VBMI{kz}-VL
+    3372             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3373             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_VBMI{kz}-VL
+    3374             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_VBMI{kz}-VL
+    3375             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_VBMI{kz}
+    3376             :   ASMJIT_INST_3x(vpermt2b, Vpermt2b, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_VBMI{kz}
+    3377             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b32}-VL
+    3378             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3379             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b32}-VL
+    3380             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b32}-VL
+    3381             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b32}
+    3382             :   ASMJIT_INST_3x(vpermt2d, Vpermt2d, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b32}
+    3383             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    3384             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3385             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    3386             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    3387             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    3388             :   ASMJIT_INST_3x(vpermt2pd, Vpermt2pd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    3389             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    3390             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3391             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    3392             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    3393             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    3394             :   ASMJIT_INST_3x(vpermt2ps, Vpermt2ps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    3395             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz|b64}-VL
+    3396             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3397             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_F{kz|b64}-VL
+    3398             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_F{kz|b64}-VL
+    3399             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    3400             :   ASMJIT_INST_3x(vpermt2q, Vpermt2q, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    3401             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_BW{kz}-VL
+    3402             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3403             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Ymm, X86Ymm, X86Ymm)                  //      AVX512_BW{kz}-VL
+    3404             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Ymm, X86Ymm, X86Mem)                  //      AVX512_BW{kz}-VL
+    3405             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3406             :   ASMJIT_INST_3x(vpermt2w, Vpermt2w, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3407             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_BW{kz}-VL
+    3408             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_BW{kz}-VL
+    3409             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_BW{kz}-VL
+    3410             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_BW{kz}-VL
+    3411             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    3412             :   ASMJIT_INST_3x(vpermw, Vpermw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    3413             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3414             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    3415             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3416             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    3417             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    3418             :   ASMJIT_INST_2x(vpexpandd, Vpexpandd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3419             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3420             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Xmm, X86Mem)                        //      AVX512_F{kz}-VL
+    3421             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Ymm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3422             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Ymm, X86Mem)                        //      AVX512_F{kz}-VL
+    3423             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Zmm, X86Zmm)                        //      AVX512_F{kz}
+    3424             :   ASMJIT_INST_2x(vpexpandq, Vpexpandq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3425             :   ASMJIT_INST_3i(vpextrb, Vpextrb, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_BW
+    3426             :   ASMJIT_INST_3i(vpextrb, Vpextrb, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_BW
+    3427             :   ASMJIT_INST_3i(vpextrd, Vpextrd, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_DQ
+    3428             :   ASMJIT_INST_3i(vpextrd, Vpextrd, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_DQ
+    3429             :   ASMJIT_INST_3i(vpextrq, Vpextrq, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_DQ
+    3430             :   ASMJIT_INST_3i(vpextrq, Vpextrq, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_DQ
+    3431             :   ASMJIT_INST_3i(vpextrw, Vpextrw, X86Gp, X86Xmm, Imm)                        // AVX  AVX512_BW
+    3432             :   ASMJIT_INST_3i(vpextrw, Vpextrw, X86Mem, X86Xmm, Imm)                       // AVX  AVX512_BW
+    3433             :   ASMJIT_INST_3x(vpgatherdd, Vpgatherdd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3434             :   ASMJIT_INST_3x(vpgatherdd, Vpgatherdd, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    3435             :   ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3436             :   ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3437             :   ASMJIT_INST_2x(vpgatherdd, Vpgatherdd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3438             :   ASMJIT_INST_3x(vpgatherdq, Vpgatherdq, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3439             :   ASMJIT_INST_3x(vpgatherdq, Vpgatherdq, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    3440             :   ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3441             :   ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3442             :   ASMJIT_INST_2x(vpgatherdq, Vpgatherdq, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3443             :   ASMJIT_INST_3x(vpgatherqd, Vpgatherqd, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3444             :   ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3445             :   ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3446             :   ASMJIT_INST_2x(vpgatherqd, Vpgatherqd, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3447             :   ASMJIT_INST_3x(vpgatherqq, Vpgatherqq, X86Xmm, X86Mem, X86Xmm)              // AVX2
+    3448             :   ASMJIT_INST_3x(vpgatherqq, Vpgatherqq, X86Ymm, X86Mem, X86Ymm)              // AVX2
+    3449             :   ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, X86Xmm, X86Mem)                      //      AVX512_F{k}-VL
+    3450             :   ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, X86Ymm, X86Mem)                      //      AVX512_F{k}-VL
+    3451             :   ASMJIT_INST_2x(vpgatherqq, Vpgatherqq, X86Zmm, X86Mem)                      //      AVX512_F{k}
+    3452             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3453             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3454             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3455             :   ASMJIT_INST_3x(vphaddd, Vphaddd, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3456             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3457             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3458             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3459             :   ASMJIT_INST_3x(vphaddsw, Vphaddsw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3460             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3461             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3462             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3463             :   ASMJIT_INST_3x(vphaddw, Vphaddw, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3464             :   ASMJIT_INST_2x(vphminposuw, Vphminposuw, X86Xmm, X86Xmm)                    // AVX
+    3465             :   ASMJIT_INST_2x(vphminposuw, Vphminposuw, X86Xmm, X86Mem)                    // AVX
+    3466             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3467             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3468             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3469             :   ASMJIT_INST_3x(vphsubd, Vphsubd, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3470             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    3471             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    3472             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2
+    3473             :   ASMJIT_INST_3x(vphsubsw, Vphsubsw, X86Ymm, X86Ymm, X86Mem)                  // AVX2
+    3474             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    3475             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    3476             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    3477             :   ASMJIT_INST_3x(vphsubw, Vphsubw, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    3478             :   ASMJIT_INST_3i(vpinsrb, Vpinsrb, X86Xmm, X86Gp, Imm)                        // AVX
+    3479             :   ASMJIT_INST_3i(vpinsrb, Vpinsrb, X86Xmm, X86Mem, Imm)                       // AVX
+    3480             :   ASMJIT_INST_4i(vpinsrb, Vpinsrb, X86Xmm, X86Xmm, X86Gp, Imm)                //      AVX512_BW{kz}
+    3481             :   ASMJIT_INST_4i(vpinsrb, Vpinsrb, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_BW{kz}
+    3482             :   ASMJIT_INST_3i(vpinsrd, Vpinsrd, X86Xmm, X86Gp, Imm)                        // AVX
+    3483             :   ASMJIT_INST_3i(vpinsrd, Vpinsrd, X86Xmm, X86Mem, Imm)                       // AVX
+    3484             :   ASMJIT_INST_4i(vpinsrd, Vpinsrd, X86Xmm, X86Xmm, X86Gp, Imm)                //      AVX512_DQ{kz}
+    3485             :   ASMJIT_INST_4i(vpinsrd, Vpinsrd, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_DQ{kz}
+    3486             :   ASMJIT_INST_3i(vpinsrq, Vpinsrq, X86Xmm, X86Gp, Imm)                        // AVX
+    3487             :   ASMJIT_INST_3i(vpinsrq, Vpinsrq, X86Xmm, X86Mem, Imm)                       // AVX
+    3488             :   ASMJIT_INST_4i(vpinsrq, Vpinsrq, X86Xmm, X86Xmm, X86Gp, Imm)                //      AVX512_DQ{kz}
+    3489             :   ASMJIT_INST_4i(vpinsrq, Vpinsrq, X86Xmm, X86Xmm, X86Mem, Imm)               //      AVX512_DQ{kz}
+    3490             :   ASMJIT_INST_4i(vpinsrw, Vpinsrw, X86Xmm, X86Xmm, X86Gp, Imm)                // AVX  AVX512_BW{kz}
+    3491             :   ASMJIT_INST_4i(vpinsrw, Vpinsrw, X86Xmm, X86Xmm, X86Mem, Imm)               // AVX  AVX512_BW{kz}
+    3492             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Xmm, X86Xmm)                          //      AVX512_CD{kz|b32}-VL
+    3493             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Xmm, X86Mem)                          //      AVX512_CD{kz|b32}-VL
+    3494             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Ymm, X86Ymm)                          //      AVX512_CD{kz|b32}-VL
+    3495             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Ymm, X86Mem)                          //      AVX512_CD{kz|b32}-VL
+    3496             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Zmm, X86Zmm)                          //      AVX512_CD{kz|b32}
+    3497             :   ASMJIT_INST_2x(vplzcntd, Vplzcntd, X86Zmm, X86Mem)                          //      AVX512_CD{kz|b32}
+    3498             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Xmm, X86Xmm)                          //      AVX512_CD{kz|b64}-VL
+    3499             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Xmm, X86Mem)                          //      AVX512_CD{kz|b64}-VL
+    3500             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Ymm, X86Ymm)                          //      AVX512_CD{kz|b64}-VL
+    3501             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Ymm, X86Mem)                          //      AVX512_CD{kz|b64}-VL
+    3502             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Zmm, X86Zmm)                          //      AVX512_CD{kz|b64}
+    3503             :   ASMJIT_INST_2x(vplzcntq, Vplzcntq, X86Zmm, X86Mem)                          //      AVX512_CD{kz|b64}
+    3504             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Xmm, X86Xmm, X86Xmm)            //      AVX512_IFMA{kz|b64}-VL
+    3505             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Xmm, X86Xmm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3506             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Ymm, X86Ymm, X86Ymm)            //      AVX512_IFMA{kz|b64}-VL
+    3507             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Ymm, X86Ymm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3508             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_IFMA{kz|b64}
+    3509             :   ASMJIT_INST_3x(vpmadd52huq, Vpmadd52huq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_IFMA{kz|b64}
+    3510             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Xmm, X86Xmm, X86Xmm)            //      AVX512_IFMA{kz|b64}-VL
+    3511             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Xmm, X86Xmm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3512             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Ymm, X86Ymm, X86Ymm)            //      AVX512_IFMA{kz|b64}-VL
+    3513             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Ymm, X86Ymm, X86Mem)            //      AVX512_IFMA{kz|b64}-VL
+    3514             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_IFMA{kz|b64}
+    3515             :   ASMJIT_INST_3x(vpmadd52luq, Vpmadd52luq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_IFMA{kz|b64}
+    3516             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    3517             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    3518             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    3519             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    3520             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    3521             :   ASMJIT_INST_3x(vpmaddubsw, Vpmaddubsw, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    3522             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3523             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3524             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3525             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3526             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3527             :   ASMJIT_INST_3x(vpmaddwd, Vpmaddwd, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3528             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Mem, X86Xmm, X86Xmm)              // AVX2
+    3529             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Mem, X86Ymm, X86Ymm)              // AVX2
+    3530             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Xmm, X86Xmm, X86Mem)              // AVX2
+    3531             :   ASMJIT_INST_3x(vpmaskmovd, Vpmaskmovd, X86Ymm, X86Ymm, X86Mem)              // AVX2
+    3532             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Mem, X86Xmm, X86Xmm)              // AVX2
+    3533             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Mem, X86Ymm, X86Ymm)              // AVX2
+    3534             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Xmm, X86Xmm, X86Mem)              // AVX2
+    3535             :   ASMJIT_INST_3x(vpmaskmovq, Vpmaskmovq, X86Ymm, X86Ymm, X86Mem)              // AVX2
+    3536             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3537             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3538             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3539             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3540             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3541             :   ASMJIT_INST_3x(vpmaxsb, Vpmaxsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3542             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3543             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3544             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3545             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3546             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3547             :   ASMJIT_INST_3x(vpmaxsd, Vpmaxsd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3548             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3549             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3550             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3551             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3552             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3553             :   ASMJIT_INST_3x(vpmaxsq, Vpmaxsq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3554             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3555             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3556             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3557             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3558             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3559             :   ASMJIT_INST_3x(vpmaxsw, Vpmaxsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3560             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3561             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3562             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3563             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3564             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3565             :   ASMJIT_INST_3x(vpmaxub, Vpmaxub, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3566             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3567             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3568             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3569             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3570             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3571             :   ASMJIT_INST_3x(vpmaxud, Vpmaxud, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3572             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3573             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3574             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3575             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3576             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3577             :   ASMJIT_INST_3x(vpmaxuq, Vpmaxuq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3578             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3579             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3580             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3581             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3582             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3583             :   ASMJIT_INST_3x(vpmaxuw, Vpmaxuw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3584             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3585             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3586             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3587             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3588             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3589             :   ASMJIT_INST_3x(vpminsb, Vpminsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3590             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3591             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3592             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3593             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3594             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3595             :   ASMJIT_INST_3x(vpminsd, Vpminsd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3596             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3597             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3598             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3599             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3600             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3601             :   ASMJIT_INST_3x(vpminsq, Vpminsq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3602             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3603             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3604             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3605             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3606             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3607             :   ASMJIT_INST_3x(vpminsw, Vpminsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3608             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3609             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3610             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3611             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3612             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3613             :   ASMJIT_INST_3x(vpminub, Vpminub, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3614             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3615             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3616             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3617             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3618             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3619             :   ASMJIT_INST_3x(vpminud, Vpminud, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3620             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3621             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3622             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3623             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3624             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3625             :   ASMJIT_INST_3x(vpminuq, Vpminuq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3626             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3627             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3628             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3629             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3630             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3631             :   ASMJIT_INST_3x(vpminuw, Vpminuw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3632             :   ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, X86KReg, X86Xmm)                         //      AVX512_BW-VL
+    3633             :   ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, X86KReg, X86Ymm)                         //      AVX512_BW-VL
+    3634             :   ASMJIT_INST_2x(vpmovb2m, Vpmovb2m, X86KReg, X86Zmm)                         //      AVX512_BW
+    3635             :   ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, X86KReg, X86Xmm)                         //      AVX512_DQ-VL
+    3636             :   ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, X86KReg, X86Ymm)                         //      AVX512_DQ-VL
+    3637             :   ASMJIT_INST_2x(vpmovd2m, Vpmovd2m, X86KReg, X86Zmm)                         //      AVX512_DQ
+    3638             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3639             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3640             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3641             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3642             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Xmm, X86Zmm)                            //      AVX512_F{kz}
+    3643             :   ASMJIT_INST_2x(vpmovdb, Vpmovdb, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3644             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3645             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3646             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3647             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3648             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Ymm, X86Zmm)                            //      AVX512_F{kz}
+    3649             :   ASMJIT_INST_2x(vpmovdw, Vpmovdw, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3650             :   ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, X86Xmm, X86KReg)                         //      AVX512_BW-VL
+    3651             :   ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, X86Ymm, X86KReg)                         //      AVX512_BW-VL
+    3652             :   ASMJIT_INST_2x(vpmovm2b, Vpmovm2b, X86Zmm, X86KReg)                         //      AVX512_BW
+    3653             :   ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, X86Xmm, X86KReg)                         //      AVX512_DQ-VL
+    3654             :   ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, X86Ymm, X86KReg)                         //      AVX512_DQ-VL
+    3655             :   ASMJIT_INST_2x(vpmovm2d, Vpmovm2d, X86Zmm, X86KReg)                         //      AVX512_DQ
+    3656             :   ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, X86Xmm, X86KReg)                         //      AVX512_DQ-VL
+    3657             :   ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, X86Ymm, X86KReg)                         //      AVX512_DQ-VL
+    3658             :   ASMJIT_INST_2x(vpmovm2q, Vpmovm2q, X86Zmm, X86KReg)                         //      AVX512_DQ
+    3659             :   ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, X86Xmm, X86KReg)                         //      AVX512_BW-VL
+    3660             :   ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, X86Ymm, X86KReg)                         //      AVX512_BW-VL
+    3661             :   ASMJIT_INST_2x(vpmovm2w, Vpmovm2w, X86Zmm, X86KReg)                         //      AVX512_BW
+    3662             :   ASMJIT_INST_2x(vpmovmskb, Vpmovmskb, X86Gp, X86Xmm)                         // AVX
+    3663             :   ASMJIT_INST_2x(vpmovmskb, Vpmovmskb, X86Gp, X86Ymm)                         // AVX2
+    3664             :   ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, X86KReg, X86Xmm)                         //      AVX512_DQ-VL
+    3665             :   ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, X86KReg, X86Ymm)                         //      AVX512_DQ-VL
+    3666             :   ASMJIT_INST_2x(vpmovq2m, Vpmovq2m, X86KReg, X86Zmm)                         //      AVX512_DQ
+    3667             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3668             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3669             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3670             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3671             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Xmm, X86Zmm)                            //      AVX512_F{kz}
+    3672             :   ASMJIT_INST_2x(vpmovqb, Vpmovqb, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3673             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3674             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3675             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3676             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3677             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Ymm, X86Zmm)                            //      AVX512_F{kz}
+    3678             :   ASMJIT_INST_2x(vpmovqd, Vpmovqd, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3679             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Xmm, X86Xmm)                            //      AVX512_F{kz}-VL
+    3680             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Mem, X86Xmm)                            //      AVX512_F{kz}-VL
+    3681             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Xmm, X86Ymm)                            //      AVX512_F{kz}-VL
+    3682             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Mem, X86Ymm)                            //      AVX512_F{kz}-VL
+    3683             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Xmm, X86Zmm)                            //      AVX512_F{kz}
+    3684             :   ASMJIT_INST_2x(vpmovqw, Vpmovqw, X86Mem, X86Zmm)                            //      AVX512_F{kz}
+    3685             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3686             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3687             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3688             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3689             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Xmm, X86Zmm)                          //      AVX512_F{kz}
+    3690             :   ASMJIT_INST_2x(vpmovsdb, Vpmovsdb, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3691             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3692             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3693             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3694             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3695             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Ymm, X86Zmm)                          //      AVX512_F{kz}
+    3696             :   ASMJIT_INST_2x(vpmovsdw, Vpmovsdw, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3697             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3698             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3699             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3700             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3701             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Xmm, X86Zmm)                          //      AVX512_F{kz}
+    3702             :   ASMJIT_INST_2x(vpmovsqb, Vpmovsqb, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3703             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3704             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3705             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3706             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3707             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Ymm, X86Zmm)                          //      AVX512_F{kz}
+    3708             :   ASMJIT_INST_2x(vpmovsqd, Vpmovsqd, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3709             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Xmm, X86Xmm)                          //      AVX512_F{kz}-VL
+    3710             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Mem, X86Xmm)                          //      AVX512_F{kz}-VL
+    3711             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Xmm, X86Ymm)                          //      AVX512_F{kz}-VL
+    3712             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Mem, X86Ymm)                          //      AVX512_F{kz}-VL
+    3713             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Xmm, X86Zmm)                          //      AVX512_F{kz}
+    3714             :   ASMJIT_INST_2x(vpmovsqw, Vpmovsqw, X86Mem, X86Zmm)                          //      AVX512_F{kz}
+    3715             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Xmm, X86Xmm)                          //      AVX512_BW{kz}-VL
+    3716             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Mem, X86Xmm)                          //      AVX512_BW{kz}-VL
+    3717             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Xmm, X86Ymm)                          //      AVX512_BW{kz}-VL
+    3718             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Mem, X86Ymm)                          //      AVX512_BW{kz}-VL
+    3719             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Ymm, X86Zmm)                          //      AVX512_BW{kz}
+    3720             :   ASMJIT_INST_2x(vpmovswb, Vpmovswb, X86Mem, X86Zmm)                          //      AVX512_BW{kz}
+    3721             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3722             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3723             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3724             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3725             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3726             :   ASMJIT_INST_2x(vpmovsxbd, Vpmovsxbd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3727             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3728             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3729             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3730             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3731             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3732             :   ASMJIT_INST_2x(vpmovsxbq, Vpmovsxbq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3733             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Xmm, X86Xmm)                        // AVX  AVX512_BW{kz}-VL
+    3734             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Xmm, X86Mem)                        // AVX  AVX512_BW{kz}-VL
+    3735             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Ymm, X86Xmm)                        // AVX2 AVX512_BW{kz}-VL
+    3736             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Ymm, X86Mem)                        // AVX2 AVX512_BW{kz}-VL
+    3737             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Zmm, X86Ymm)                        //      AVX512_BW{kz}
+    3738             :   ASMJIT_INST_2x(vpmovsxbw, Vpmovsxbw, X86Zmm, X86Mem)                        //      AVX512_BW{kz}
+    3739             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3740             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3741             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3742             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3743             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3744             :   ASMJIT_INST_2x(vpmovsxdq, Vpmovsxdq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3745             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3746             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3747             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3748             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3749             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Zmm, X86Ymm)                        //      AVX512_F{kz}
+    3750             :   ASMJIT_INST_2x(vpmovsxwd, Vpmovsxwd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3751             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3752             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3753             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3754             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3755             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3756             :   ASMJIT_INST_2x(vpmovsxwq, Vpmovsxwq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3757             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3758             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3759             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3760             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3761             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Xmm, X86Zmm)                        //      AVX512_F{kz}
+    3762             :   ASMJIT_INST_2x(vpmovusdb, Vpmovusdb, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3763             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3764             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3765             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3766             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3767             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Ymm, X86Zmm)                        //      AVX512_F{kz}
+    3768             :   ASMJIT_INST_2x(vpmovusdw, Vpmovusdw, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3769             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3770             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3771             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3772             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3773             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Xmm, X86Zmm)                        //      AVX512_F{kz}
+    3774             :   ASMJIT_INST_2x(vpmovusqb, Vpmovusqb, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3775             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3776             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3777             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3778             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3779             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Ymm, X86Zmm)                        //      AVX512_F{kz}
+    3780             :   ASMJIT_INST_2x(vpmovusqd, Vpmovusqd, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3781             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Xmm, X86Xmm)                        //      AVX512_F{kz}-VL
+    3782             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Mem, X86Xmm)                        //      AVX512_F{kz}-VL
+    3783             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Xmm, X86Ymm)                        //      AVX512_F{kz}-VL
+    3784             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Mem, X86Ymm)                        //      AVX512_F{kz}-VL
+    3785             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Xmm, X86Zmm)                        //      AVX512_F{kz}
+    3786             :   ASMJIT_INST_2x(vpmovusqw, Vpmovusqw, X86Mem, X86Zmm)                        //      AVX512_F{kz}
+    3787             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Xmm, X86Xmm)                        //      AVX512_BW{kz}-VL
+    3788             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Mem, X86Xmm)                        //      AVX512_BW{kz}-VL
+    3789             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Xmm, X86Ymm)                        //      AVX512_BW{kz}-VL
+    3790             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Mem, X86Ymm)                        //      AVX512_BW{kz}-VL
+    3791             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Ymm, X86Zmm)                        //      AVX512_BW{kz}
+    3792             :   ASMJIT_INST_2x(vpmovuswb, Vpmovuswb, X86Mem, X86Zmm)                        //      AVX512_BW{kz}
+    3793             :   ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, X86KReg, X86Xmm)                         //      AVX512_BW-VL
+    3794             :   ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, X86KReg, X86Ymm)                         //      AVX512_BW-VL
+    3795             :   ASMJIT_INST_2x(vpmovw2m, Vpmovw2m, X86KReg, X86Zmm)                         //      AVX512_BW
+    3796             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Xmm, X86Xmm)                            //      AVX512_BW{kz}-VL
+    3797             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Mem, X86Xmm)                            //      AVX512_BW{kz}-VL
+    3798             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Xmm, X86Ymm)                            //      AVX512_BW{kz}-VL
+    3799             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Mem, X86Ymm)                            //      AVX512_BW{kz}-VL
+    3800             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Ymm, X86Zmm)                            //      AVX512_BW{kz}
+    3801             :   ASMJIT_INST_2x(vpmovwb, Vpmovwb, X86Mem, X86Zmm)                            //      AVX512_BW{kz}
+    3802             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3803             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3804             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3805             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3806             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3807             :   ASMJIT_INST_2x(vpmovzxbd, Vpmovzxbd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3808             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3809             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3810             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3811             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3812             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3813             :   ASMJIT_INST_2x(vpmovzxbq, Vpmovzxbq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3814             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Xmm, X86Xmm)                        // AVX  AVX512_BW{kz}-VL
+    3815             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Xmm, X86Mem)                        // AVX  AVX512_BW{kz}-VL
+    3816             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Ymm, X86Xmm)                        // AVX2 AVX512_BW{kz}-VL
+    3817             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Ymm, X86Mem)                        // AVX2 AVX512_BW{kz}-VL
+    3818             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Zmm, X86Ymm)                        //      AVX512_BW{kz}
+    3819             :   ASMJIT_INST_2x(vpmovzxbw, Vpmovzxbw, X86Zmm, X86Mem)                        //      AVX512_BW{kz}
+    3820             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3821             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3822             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3823             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3824             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3825             :   ASMJIT_INST_2x(vpmovzxdq, Vpmovzxdq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3826             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3827             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3828             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3829             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3830             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Zmm, X86Ymm)                        //      AVX512_F{kz}
+    3831             :   ASMJIT_INST_2x(vpmovzxwd, Vpmovzxwd, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3832             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Xmm, X86Xmm)                        // AVX  AVX512_F{kz}-VL
+    3833             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Xmm, X86Mem)                        // AVX  AVX512_F{kz}-VL
+    3834             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Ymm, X86Xmm)                        // AVX2 AVX512_F{kz}-VL
+    3835             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Ymm, X86Mem)                        // AVX2 AVX512_F{kz}-VL
+    3836             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Zmm, X86Xmm)                        //      AVX512_F{kz}
+    3837             :   ASMJIT_INST_2x(vpmovzxwq, Vpmovzxwq, X86Zmm, X86Mem)                        //      AVX512_F{kz}
+    3838             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b64}-VL
+    3839             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b64}-VL
+    3840             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b64}-VL
+    3841             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    3842             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3843             :   ASMJIT_INST_3x(vpmuldq, Vpmuldq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3844             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_BW{kz}-VL
+    3845             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_BW{kz}-VL
+    3846             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Ymm, X86Ymm, X86Ymm)                // AVX2 AVX512_BW{kz}-VL
+    3847             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Ymm, X86Ymm, X86Mem)                // AVX2 AVX512_BW{kz}-VL
+    3848             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_BW{kz}
+    3849             :   ASMJIT_INST_3x(vpmulhrsw, Vpmulhrsw, X86Zmm, X86Zmm, X86Mem)                //      AVX512_BW{kz}
+    3850             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    3851             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    3852             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    3853             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    3854             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    3855             :   ASMJIT_INST_3x(vpmulhuw, Vpmulhuw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    3856             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3857             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3858             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3859             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3860             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3861             :   ASMJIT_INST_3x(vpmulhw, Vpmulhw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3862             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|b32}-VL
+    3863             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|b32}-VL
+    3864             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    3865             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    3866             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3867             :   ASMJIT_INST_3x(vpmulld, Vpmulld, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3868             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_DQ{kz|b64}-VL
+    3869             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    3870             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_DQ{kz|b64}-VL
+    3871             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_DQ{kz|b64}-VL
+    3872             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_DQ{kz|b64}
+    3873             :   ASMJIT_INST_3x(vpmullq, Vpmullq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_DQ{kz|b64}
+    3874             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3875             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3876             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3877             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3878             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3879             :   ASMJIT_INST_3x(vpmullw, Vpmullw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3880             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Xmm, X86Xmm, X86Xmm)      //      AVX512_VBMI{kz|b64}-VL
+    3881             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Xmm, X86Xmm, X86Mem)      //      AVX512_VBMI{kz|b64}-VL
+    3882             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Ymm, X86Ymm, X86Ymm)      //      AVX512_VBMI{kz|b64}-VL
+    3883             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Ymm, X86Ymm, X86Mem)      //      AVX512_VBMI{kz|b64}-VL
+    3884             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Zmm, X86Zmm, X86Zmm)      //      AVX512_VBMI{kz|b64}
+    3885             :   ASMJIT_INST_3x(vpmultishiftqb, Vpmultishiftqb, X86Zmm, X86Zmm, X86Mem)      //      AVX512_VBMI{kz|b64}
+    3886             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_F{kz|b64}-VL
+    3887             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_F{kz|b64}-VL
+    3888             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_F{kz|b64}-VL
+    3889             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_F{kz|b64}-VL
+    3890             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_F{kz|b64}
+    3891             :   ASMJIT_INST_3x(vpmuludq, Vpmuludq, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_F{kz|b64}
+    3892             :   ASMJIT_INST_2x(vpopcntd, Vpopcntd, X86Zmm, X86Zmm)                          //      AVX512_VPOPCNTDQ{kz|b32}
+    3893             :   ASMJIT_INST_2x(vpopcntd, Vpopcntd, X86Zmm, X86Mem)                          //      AVX512_VPOPCNTDQ{kz|b32}
+    3894             :   ASMJIT_INST_2x(vpopcntq, Vpopcntq, X86Zmm, X86Zmm)                          //      AVX512_VPOPCNTDQ{kz|b64}
+    3895             :   ASMJIT_INST_2x(vpopcntq, Vpopcntq, X86Zmm, X86Mem)                          //      AVX512_VPOPCNTDQ{kz|b64}
+    3896             :   ASMJIT_INST_3x(vpor, Vpor, X86Xmm, X86Xmm, X86Xmm)                          // AVX
+    3897             :   ASMJIT_INST_3x(vpor, Vpor, X86Xmm, X86Xmm, X86Mem)                          // AVX
+    3898             :   ASMJIT_INST_3x(vpor, Vpor, X86Ymm, X86Ymm, X86Ymm)                          // AVX2
+    3899             :   ASMJIT_INST_3x(vpor, Vpor, X86Ymm, X86Ymm, X86Mem)                          // AVX2
+    3900             :   ASMJIT_INST_3x(vpord, Vpord, X86Xmm, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b32}-VL
+    3901             :   ASMJIT_INST_3x(vpord, Vpord, X86Xmm, X86Xmm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    3902             :   ASMJIT_INST_3x(vpord, Vpord, X86Ymm, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b32}-VL
+    3903             :   ASMJIT_INST_3x(vpord, Vpord, X86Ymm, X86Ymm, X86Mem)                        //      AVX512_F{kz|b32}-VL
+    3904             :   ASMJIT_INST_3x(vpord, Vpord, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_F{kz|b32}
+    3905             :   ASMJIT_INST_3x(vpord, Vpord, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_F{kz|b32}
+    3906             :   ASMJIT_INST_3x(vporq, Vporq, X86Xmm, X86Xmm, X86Xmm)                        //      AVX512_F{kz|b64}-VL
+    3907             :   ASMJIT_INST_3x(vporq, Vporq, X86Xmm, X86Xmm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    3908             :   ASMJIT_INST_3x(vporq, Vporq, X86Ymm, X86Ymm, X86Ymm)                        //      AVX512_F{kz|b64}-VL
+    3909             :   ASMJIT_INST_3x(vporq, Vporq, X86Ymm, X86Ymm, X86Mem)                        //      AVX512_F{kz|b64}-VL
+    3910             :   ASMJIT_INST_3x(vporq, Vporq, X86Zmm, X86Zmm, X86Zmm)                        //      AVX512_F{kz|b64}
+    3911             :   ASMJIT_INST_3x(vporq, Vporq, X86Zmm, X86Zmm, X86Mem)                        //      AVX512_F{kz|b64}
+    3912             :   ASMJIT_INST_3i(vprold, Vprold, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3913             :   ASMJIT_INST_3i(vprold, Vprold, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3914             :   ASMJIT_INST_3i(vprold, Vprold, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3915             :   ASMJIT_INST_3i(vprold, Vprold, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3916             :   ASMJIT_INST_3i(vprold, Vprold, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    3917             :   ASMJIT_INST_3i(vprold, Vprold, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    3918             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3919             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3920             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3921             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3922             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    3923             :   ASMJIT_INST_3i(vprolq, Vprolq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    3924             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    3925             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3926             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    3927             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3928             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3929             :   ASMJIT_INST_3x(vprolvd, Vprolvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3930             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3931             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3932             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3933             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3934             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3935             :   ASMJIT_INST_3x(vprolvq, Vprolvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3936             :   ASMJIT_INST_3i(vprord, Vprord, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3937             :   ASMJIT_INST_3i(vprord, Vprord, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3938             :   ASMJIT_INST_3i(vprord, Vprord, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b32}-VL
+    3939             :   ASMJIT_INST_3i(vprord, Vprord, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    3940             :   ASMJIT_INST_3i(vprord, Vprord, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    3941             :   ASMJIT_INST_3i(vprord, Vprord, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    3942             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3943             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3944             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b64}-VL
+    3945             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    3946             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    3947             :   ASMJIT_INST_3i(vprorq, Vprorq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    3948             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b32}-VL
+    3949             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3950             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b32}-VL
+    3951             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b32}-VL
+    3952             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    3953             :   ASMJIT_INST_3x(vprorvd, Vprorvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    3954             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    3955             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3956             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    3957             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    3958             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    3959             :   ASMJIT_INST_3x(vprorvq, Vprorvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    3960             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW-VL
+    3961             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW-VL
+    3962             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW-VL
+    3963             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW-VL
+    3964             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW
+    3965             :   ASMJIT_INST_3x(vpsadbw, Vpsadbw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW
+    3966             :   ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3967             :   ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    3968             :   ASMJIT_INST_2x(vpscatterdd, Vpscatterdd, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    3969             :   ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3970             :   ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    3971             :   ASMJIT_INST_2x(vpscatterdq, Vpscatterdq, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    3972             :   ASMJIT_INST_2x(vpscatterqd, Vpscatterqd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3973             :   ASMJIT_INST_2x(vpscatterqd, Vpscatterqd, X86Mem, X86Ymm)                    //      AVX512_F{k}
+    3974             :   ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    3975             :   ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    3976             :   ASMJIT_INST_2x(vpscatterqq, Vpscatterqq, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    3977             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    3978             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    3979             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    3980             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    3981             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    3982             :   ASMJIT_INST_3x(vpshufb, Vpshufb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    3983             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Xmm, X86Xmm, Imm)                       // AVX  AVX512_F{kz|b32}-VL
+    3984             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Xmm, X86Mem, Imm)                       // AVX  AVX512_F{kz|b32}-VL
+    3985             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Ymm, X86Ymm, Imm)                       // AVX2 AVX512_F{kz|b32}-VL
+    3986             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Ymm, X86Mem, Imm)                       // AVX2 AVX512_F{kz|b32}-VL
+    3987             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Zmm, X86Zmm, Imm)                       //      AVX512_F{kz|b32}
+    3988             :   ASMJIT_INST_3i(vpshufd, Vpshufd, X86Zmm, X86Mem, Imm)                       //      AVX512_F{kz|b32}
+    3989             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Xmm, X86Xmm, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3990             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Xmm, X86Mem, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3991             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Ymm, X86Ymm, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3992             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Ymm, X86Mem, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3993             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Zmm, X86Zmm, Imm)                     //      AVX512_BW{kz}
+    3994             :   ASMJIT_INST_3i(vpshufhw, Vpshufhw, X86Zmm, X86Mem, Imm)                     //      AVX512_BW{kz}
+    3995             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Xmm, X86Xmm, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3996             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Xmm, X86Mem, Imm)                     // AVX  AVX512_BW{kz}-VL
+    3997             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Ymm, X86Ymm, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3998             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Ymm, X86Mem, Imm)                     // AVX2 AVX512_BW{kz}-VL
+    3999             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Zmm, X86Zmm, Imm)                     //      AVX512_BW{kz}
+    4000             :   ASMJIT_INST_3i(vpshuflw, Vpshuflw, X86Zmm, X86Mem, Imm)                     //      AVX512_BW{kz}
+    4001             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    4002             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    4003             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    4004             :   ASMJIT_INST_3x(vpsignb, Vpsignb, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    4005             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    4006             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    4007             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    4008             :   ASMJIT_INST_3x(vpsignd, Vpsignd, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    4009             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Xmm, X86Xmm, X86Xmm)                    // AVX
+    4010             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Xmm, X86Xmm, X86Mem)                    // AVX
+    4011             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2
+    4012             :   ASMJIT_INST_3x(vpsignw, Vpsignw, X86Ymm, X86Ymm, X86Mem)                    // AVX2
+    4013             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b32}-VL
+    4014             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4015             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4016             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b32}-VL
+    4017             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4018             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4019             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4020             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4021             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4022             :   ASMJIT_INST_3x(vpslld, Vpslld, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4023             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    4024             :   ASMJIT_INST_3i(vpslld, Vpslld, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    4025             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Xmm, X86Xmm, Imm)                       // AVX  AVX512_BW-VL
+    4026             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Ymm, X86Ymm, Imm)                       // AVX2 AVX512_BW-VL
+    4027             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Xmm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4028             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Ymm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4029             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Zmm, X86Zmm, Imm)                       //      AVX512_BW
+    4030             :   ASMJIT_INST_3i(vpslldq, Vpslldq, X86Zmm, X86Mem, Imm)                       //      AVX512_BW
+    4031             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b64}-VL
+    4032             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4033             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4034             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    4035             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4036             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4037             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4038             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4039             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4040             :   ASMJIT_INST_3x(vpsllq, Vpsllq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4041             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    4042             :   ASMJIT_INST_3i(vpsllq, Vpsllq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    4043             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4044             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4045             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4046             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4047             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    4048             :   ASMJIT_INST_3x(vpsllvd, Vpsllvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    4049             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4050             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4051             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4052             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4053             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    4054             :   ASMJIT_INST_3x(vpsllvq, Vpsllvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    4055             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_BW{kz}-VL
+    4056             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4057             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_BW{kz}-VL
+    4058             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4059             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4060             :   ASMJIT_INST_3x(vpsllvw, Vpsllvw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4061             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_BW{kz}-VL
+    4062             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4063             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4064             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_BW{kz}-VL
+    4065             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    4066             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4067             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Xmm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4068             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Ymm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4069             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_BW{kz}
+    4070             :   ASMJIT_INST_3x(vpsllw, Vpsllw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4071             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Zmm, X86Zmm, Imm)                         //      AVX512_BW{kz}
+    4072             :   ASMJIT_INST_3i(vpsllw, Vpsllw, X86Zmm, X86Mem, Imm)                         //      AVX512_BW{kz}
+    4073             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b32}-VL
+    4074             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4075             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4076             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b32}-VL
+    4077             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4078             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4079             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4080             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4081             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4082             :   ASMJIT_INST_3x(vpsrad, Vpsrad, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4083             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    4084             :   ASMJIT_INST_3i(vpsrad, Vpsrad, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    4085             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz}-VL
+    4086             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz}-VL
+    4087             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Xmm, X86Xmm, Imm)                         //      AVX512_F{kz|b64}-VL
+    4088             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4089             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Ymm, X86Ymm, X86Xmm)                      //      AVX512_F{kz}-VL
+    4090             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz}-VL
+    4091             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Ymm, X86Ymm, Imm)                         //      AVX512_F{kz|b64}-VL
+    4092             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4093             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4094             :   ASMJIT_INST_3x(vpsraq, Vpsraq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4095             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    4096             :   ASMJIT_INST_3i(vpsraq, Vpsraq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    4097             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4098             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4099             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4100             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4101             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    4102             :   ASMJIT_INST_3x(vpsravd, Vpsravd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    4103             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_F{kz|b64}-VL
+    4104             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    4105             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_F{kz|b64}-VL
+    4106             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_F{kz|b64}-VL
+    4107             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    4108             :   ASMJIT_INST_3x(vpsravq, Vpsravq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    4109             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_BW{kz}-VL
+    4110             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4111             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_BW{kz}-VL
+    4112             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4113             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4114             :   ASMJIT_INST_3x(vpsravw, Vpsravw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4115             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_BW{kz}-VL
+    4116             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4117             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4118             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_BW{kz}-VL
+    4119             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    4120             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4121             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Xmm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4122             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Ymm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4123             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_BW{kz}
+    4124             :   ASMJIT_INST_3x(vpsraw, Vpsraw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4125             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Zmm, X86Zmm, Imm)                         //      AVX512_BW{kz}
+    4126             :   ASMJIT_INST_3i(vpsraw, Vpsraw, X86Zmm, X86Mem, Imm)                         //      AVX512_BW{kz}
+    4127             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b32}-VL
+    4128             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4129             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4130             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b32}-VL
+    4131             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4132             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4133             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4134             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b32}-VL
+    4135             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4136             :   ASMJIT_INST_3x(vpsrld, Vpsrld, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4137             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b32}
+    4138             :   ASMJIT_INST_3i(vpsrld, Vpsrld, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b32}
+    4139             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Xmm, X86Xmm, Imm)                       // AVX  AVX512_BW-VL
+    4140             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Ymm, X86Ymm, Imm)                       // AVX2 AVX512_BW-VL
+    4141             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Xmm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4142             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Ymm, X86Mem, Imm)                       //      AVX512_BW-VL
+    4143             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Zmm, X86Zmm, Imm)                       //      AVX512_BW
+    4144             :   ASMJIT_INST_3i(vpsrldq, Vpsrldq, X86Zmm, X86Mem, Imm)                       //      AVX512_BW
+    4145             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_F{kz|b64}-VL
+    4146             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz}-VL
+    4147             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz}-VL
+    4148             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_F{kz|b64}-VL
+    4149             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_F{kz}-VL
+    4150             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz}-VL
+    4151             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Xmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4152             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Ymm, X86Mem, Imm)                         //      AVX512_F{kz|b64}-VL
+    4153             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_F{kz}
+    4154             :   ASMJIT_INST_3x(vpsrlq, Vpsrlq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz}
+    4155             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Zmm, X86Zmm, Imm)                         //      AVX512_F{kz|b64}
+    4156             :   ASMJIT_INST_3i(vpsrlq, Vpsrlq, X86Zmm, X86Mem, Imm)                         //      AVX512_F{kz|b64}
+    4157             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4158             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4159             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b32}-VL
+    4160             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b32}-VL
+    4161             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b32}
+    4162             :   ASMJIT_INST_3x(vpsrlvd, Vpsrlvd, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b32}
+    4163             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Xmm, X86Xmm, X86Xmm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4164             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Xmm, X86Xmm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4165             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_F{kz|b64}-VL
+    4166             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_F{kz|b64}-VL
+    4167             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_F{kz|b64}
+    4168             :   ASMJIT_INST_3x(vpsrlvq, Vpsrlvq, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_F{kz|b64}
+    4169             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Xmm, X86Xmm, X86Xmm)                    //      AVX512_BW{kz}-VL
+    4170             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Xmm, X86Xmm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4171             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Ymm, X86Ymm, X86Ymm)                    //      AVX512_BW{kz}-VL
+    4172             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Ymm, X86Ymm, X86Mem)                    //      AVX512_BW{kz}-VL
+    4173             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4174             :   ASMJIT_INST_3x(vpsrlvw, Vpsrlvw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4175             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Xmm, X86Xmm, Imm)                         // AVX  AVX512_BW{kz}-VL
+    4176             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4177             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4178             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Ymm, X86Ymm, Imm)                         // AVX2 AVX512_BW{kz}-VL
+    4179             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Ymm, X86Ymm, X86Xmm)                      // AVX2 AVX512_BW{kz}-VL
+    4180             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4181             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Xmm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4182             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Ymm, X86Mem, Imm)                         //      AVX512_BW{kz}-VL
+    4183             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Zmm, X86Zmm, X86Xmm)                      //      AVX512_BW{kz}
+    4184             :   ASMJIT_INST_3x(vpsrlw, Vpsrlw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4185             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Zmm, X86Zmm, Imm)                         //      AVX512_BW{kz}
+    4186             :   ASMJIT_INST_3i(vpsrlw, Vpsrlw, X86Zmm, X86Mem, Imm)                         //      AVX512_BW{kz}
+    4187             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4188             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4189             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    4190             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4191             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    4192             :   ASMJIT_INST_3x(vpsubb, Vpsubb, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4193             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    4194             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    4195             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    4196             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    4197             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    4198             :   ASMJIT_INST_3x(vpsubd, Vpsubd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    4199             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    4200             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    4201             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    4202             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    4203             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    4204             :   ASMJIT_INST_3x(vpsubq, Vpsubq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    4205             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    4206             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    4207             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    4208             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    4209             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4210             :   ASMJIT_INST_3x(vpsubsb, Vpsubsb, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4211             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_BW{kz}-VL
+    4212             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_BW{kz}-VL
+    4213             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Ymm, X86Ymm, X86Ymm)                    // AVX2 AVX512_BW{kz}-VL
+    4214             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Ymm, X86Ymm, X86Mem)                    // AVX2 AVX512_BW{kz}-VL
+    4215             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Zmm, X86Zmm, X86Zmm)                    //      AVX512_BW{kz}
+    4216             :   ASMJIT_INST_3x(vpsubsw, Vpsubsw, X86Zmm, X86Zmm, X86Mem)                    //      AVX512_BW{kz}
+    4217             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    4218             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    4219             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    4220             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    4221             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    4222             :   ASMJIT_INST_3x(vpsubusb, Vpsubusb, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    4223             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Xmm, X86Xmm, X86Xmm)                  // AVX  AVX512_BW{kz}-VL
+    4224             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Xmm, X86Xmm, X86Mem)                  // AVX  AVX512_BW{kz}-VL
+    4225             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Ymm, X86Ymm, X86Ymm)                  // AVX2 AVX512_BW{kz}-VL
+    4226             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Ymm, X86Ymm, X86Mem)                  // AVX2 AVX512_BW{kz}-VL
+    4227             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Zmm, X86Zmm, X86Zmm)                  //      AVX512_BW{kz}
+    4228             :   ASMJIT_INST_3x(vpsubusw, Vpsubusw, X86Zmm, X86Zmm, X86Mem)                  //      AVX512_BW{kz}
+    4229             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_BW{kz}-VL
+    4230             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_BW{kz}-VL
+    4231             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_BW{kz}-VL
+    4232             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_BW{kz}-VL
+    4233             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_BW{kz}
+    4234             :   ASMJIT_INST_3x(vpsubw, Vpsubw, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_BW{kz}
+    4235             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Xmm, X86Xmm, X86Xmm, Imm)         //      AVX512_F{kz|b32}-VL
+    4236             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Xmm, X86Xmm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4237             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b32}-VL
+    4238             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4239             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b32}
+    4240             :   ASMJIT_INST_4i(vpternlogd, Vpternlogd, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b32}
+    4241             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Xmm, X86Xmm, X86Xmm, Imm)         //      AVX512_F{kz|b64}-VL
+    4242             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Xmm, X86Xmm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4243             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b64}-VL
+    4244             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4245             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b64}
+    4246             :   ASMJIT_INST_4i(vpternlogq, Vpternlogq, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b64}
+    4247             :   ASMJIT_INST_2x(vptest, Vptest, X86Xmm, X86Xmm)                              // AVX
+    4248             :   ASMJIT_INST_2x(vptest, Vptest, X86Xmm, X86Mem)                              // AVX
+    4249             :   ASMJIT_INST_2x(vptest, Vptest, X86Ymm, X86Ymm)                              // AVX
+    4250             :   ASMJIT_INST_2x(vptest, Vptest, X86Ymm, X86Mem)                              // AVX
+    4251             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    4252             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    4253             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    4254             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    4255             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    4256             :   ASMJIT_INST_3x(vptestmb, Vptestmb, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    4257             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b32}-VL
+    4258             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    4259             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b32}-VL
+    4260             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b32}-VL
+    4261             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b32}
+    4262             :   ASMJIT_INST_3x(vptestmd, Vptestmd, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b32}
+    4263             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_F{k|b64}-VL
+    4264             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Xmm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    4265             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_F{k|b64}-VL
+    4266             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Ymm, X86Mem)                 //      AVX512_F{k|b64}-VL
+    4267             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_F{k|b64}
+    4268             :   ASMJIT_INST_3x(vptestmq, Vptestmq, X86KReg, X86Zmm, X86Mem)                 //      AVX512_F{k|b64}
+    4269             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Xmm, X86Xmm)                 //      AVX512_BW{k}-VL
+    4270             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Xmm, X86Mem)                 //      AVX512_BW{k}-VL
+    4271             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Ymm, X86Ymm)                 //      AVX512_BW{k}-VL
+    4272             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Ymm, X86Mem)                 //      AVX512_BW{k}-VL
+    4273             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Zmm, X86Zmm)                 //      AVX512_BW{k}
+    4274             :   ASMJIT_INST_3x(vptestmw, Vptestmw, X86KReg, X86Zmm, X86Mem)                 //      AVX512_BW{k}
+    4275             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Xmm, X86Xmm)               //      AVX512_BW{k}-VL
+    4276             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Xmm, X86Mem)               //      AVX512_BW{k}-VL
+    4277             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Ymm, X86Ymm)               //      AVX512_BW{k}-VL
+    4278             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Ymm, X86Mem)               //      AVX512_BW{k}-VL
+    4279             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Zmm, X86Zmm)               //      AVX512_BW{k}
+    4280             :   ASMJIT_INST_3x(vptestnmb, Vptestnmb, X86KReg, X86Zmm, X86Mem)               //      AVX512_BW{k}
+    4281             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Xmm, X86Xmm)               //      AVX512_F{k|b32}-VL
+    4282             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Xmm, X86Mem)               //      AVX512_F{k|b32}-VL
+    4283             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Ymm, X86Ymm)               //      AVX512_F{k|b32}-VL
+    4284             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Ymm, X86Mem)               //      AVX512_F{k|b32}-VL
+    4285             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Zmm, X86Zmm)               //      AVX512_F{k|b32}
+    4286             :   ASMJIT_INST_3x(vptestnmd, Vptestnmd, X86KReg, X86Zmm, X86Mem)               //      AVX512_F{k|b32}
+    4287             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Xmm, X86Xmm)               //      AVX512_F{k|b64}-VL
+    4288             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Xmm, X86Mem)               //      AVX512_F{k|b64}-VL
+    4289             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Ymm, X86Ymm)               //      AVX512_F{k|b64}-VL
+    4290             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Ymm, X86Mem)               //      AVX512_F{k|b64}-VL
+    4291             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Zmm, X86Zmm)               //      AVX512_F{k|b64}
+    4292             :   ASMJIT_INST_3x(vptestnmq, Vptestnmq, X86KReg, X86Zmm, X86Mem)               //      AVX512_F{k|b64}
+    4293             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Xmm, X86Xmm)               //      AVX512_BW{k}-VL
+    4294             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Xmm, X86Mem)               //      AVX512_BW{k}-VL
+    4295             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Ymm, X86Ymm)               //      AVX512_BW{k}-VL
+    4296             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Ymm, X86Mem)               //      AVX512_BW{k}-VL
+    4297             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Zmm, X86Zmm)               //      AVX512_BW{k}
+    4298             :   ASMJIT_INST_3x(vptestnmw, Vptestnmw, X86KReg, X86Zmm, X86Mem)               //      AVX512_BW{k}
+    4299             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4300             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4301             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4302             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4303             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4304             :   ASMJIT_INST_3x(vpunpckhbw, Vpunpckhbw, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4305             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_F{kz|b32}-VL
+    4306             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_F{kz|b32}-VL
+    4307             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_F{kz|b32}-VL
+    4308             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_F{kz|b32}-VL
+    4309             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_F{kz|b32}
+    4310             :   ASMJIT_INST_3x(vpunpckhdq, Vpunpckhdq, X86Zmm, X86Zmm, X86Mem)              //      AVX512_F{kz|b32}
+    4311             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Xmm, X86Xmm, X86Xmm)            // AVX  AVX512_F{kz|b64}-VL
+    4312             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Xmm, X86Xmm, X86Mem)            // AVX  AVX512_F{kz|b64}-VL
+    4313             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Ymm, X86Ymm, X86Ymm)            // AVX2 AVX512_F{kz|b64}-VL
+    4314             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Ymm, X86Ymm, X86Mem)            // AVX2 AVX512_F{kz|b64}-VL
+    4315             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_F{kz|b64}
+    4316             :   ASMJIT_INST_3x(vpunpckhqdq, Vpunpckhqdq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_F{kz|b64}
+    4317             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4318             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4319             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4320             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4321             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4322             :   ASMJIT_INST_3x(vpunpckhwd, Vpunpckhwd, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4323             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4324             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4325             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4326             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4327             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4328             :   ASMJIT_INST_3x(vpunpcklbw, Vpunpcklbw, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4329             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_F{kz|b32}-VL
+    4330             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_F{kz|b32}-VL
+    4331             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_F{kz|b32}-VL
+    4332             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_F{kz|b32}-VL
+    4333             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_F{kz|b32}
+    4334             :   ASMJIT_INST_3x(vpunpckldq, Vpunpckldq, X86Zmm, X86Zmm, X86Mem)              //      AVX512_F{kz|b32}
+    4335             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Xmm, X86Xmm, X86Xmm)            // AVX  AVX512_F{kz|b64}-VL
+    4336             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Xmm, X86Xmm, X86Mem)            // AVX  AVX512_F{kz|b64}-VL
+    4337             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Ymm, X86Ymm, X86Ymm)            // AVX2 AVX512_F{kz|b64}-VL
+    4338             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Ymm, X86Ymm, X86Mem)            // AVX2 AVX512_F{kz|b64}-VL
+    4339             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Zmm, X86Zmm, X86Zmm)            //      AVX512_F{kz|b64}
+    4340             :   ASMJIT_INST_3x(vpunpcklqdq, Vpunpcklqdq, X86Zmm, X86Zmm, X86Mem)            //      AVX512_F{kz|b64}
+    4341             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Xmm, X86Xmm, X86Xmm)              // AVX  AVX512_BW{kz}-VL
+    4342             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Xmm, X86Xmm, X86Mem)              // AVX  AVX512_BW{kz}-VL
+    4343             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Ymm, X86Ymm, X86Ymm)              // AVX2 AVX512_BW{kz}-VL
+    4344             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Ymm, X86Ymm, X86Mem)              // AVX2 AVX512_BW{kz}-VL
+    4345             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Zmm, X86Zmm, X86Zmm)              //      AVX512_BW{kz}
+    4346             :   ASMJIT_INST_3x(vpunpcklwd, Vpunpcklwd, X86Zmm, X86Zmm, X86Mem)              //      AVX512_BW{kz}
+    4347             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Xmm, X86Xmm, X86Xmm)                        // AVX
+    4348             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Xmm, X86Xmm, X86Mem)                        // AVX
+    4349             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Ymm, X86Ymm, X86Ymm)                        // AVX2
+    4350             :   ASMJIT_INST_3x(vpxor, Vpxor, X86Ymm, X86Ymm, X86Mem)                        // AVX2
+    4351             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    4352             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4353             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    4354             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4355             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    4356             :   ASMJIT_INST_3x(vpxord, Vpxord, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    4357             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Xmm, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    4358             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Xmm, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4359             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Ymm, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    4360             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Ymm, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4361             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    4362             :   ASMJIT_INST_3x(vpxorq, Vpxorq, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    4363             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4364             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4365             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Ymm, X86Ymm, X86Ymm, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4366             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Ymm, X86Ymm, X86Mem, Imm)             //      AVX512_DQ{kz|b64}-VL
+    4367             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Zmm, X86Zmm, X86Zmm, Imm)             //      AVX512_DQ{kz|sae|b64}
+    4368             :   ASMJIT_INST_4i(vrangepd, Vrangepd, X86Zmm, X86Zmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae|b64}
+    4369             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4370             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4371             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Ymm, X86Ymm, X86Ymm, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4372             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Ymm, X86Ymm, X86Mem, Imm)             //      AVX512_DQ{kz|b32}-VL
+    4373             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Zmm, X86Zmm, X86Zmm, Imm)             //      AVX512_DQ{kz|sae|b32}
+    4374             :   ASMJIT_INST_4i(vrangeps, Vrangeps, X86Zmm, X86Zmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae|b32}
+    4375             :   ASMJIT_INST_4i(vrangesd, Vrangesd, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|sae}
+    4376             :   ASMJIT_INST_4i(vrangesd, Vrangesd, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae}
+    4377             :   ASMJIT_INST_4i(vrangess, Vrangess, X86Xmm, X86Xmm, X86Xmm, Imm)             //      AVX512_DQ{kz|sae}
+    4378             :   ASMJIT_INST_4i(vrangess, Vrangess, X86Xmm, X86Xmm, X86Mem, Imm)             //      AVX512_DQ{kz|sae}
+    4379             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Xmm, X86Xmm)                          //      AVX512_F{kz|b64}-VL
+    4380             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Xmm, X86Mem)                          //      AVX512_F{kz|b64}-VL
+    4381             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Ymm, X86Ymm)                          //      AVX512_F{kz|b64}-VL
+    4382             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Ymm, X86Mem)                          //      AVX512_F{kz|b64}-VL
+    4383             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Zmm, X86Zmm)                          //      AVX512_F{kz|b64}
+    4384             :   ASMJIT_INST_2x(vrcp14pd, Vrcp14pd, X86Zmm, X86Mem)                          //      AVX512_F{kz|b64}
+    4385             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Xmm, X86Xmm)                          //      AVX512_F{kz|b32}-VL
+    4386             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Xmm, X86Mem)                          //      AVX512_F{kz|b32}-VL
+    4387             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Ymm, X86Ymm)                          //      AVX512_F{kz|b32}-VL
+    4388             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Ymm, X86Mem)                          //      AVX512_F{kz|b32}-VL
+    4389             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Zmm, X86Zmm)                          //      AVX512_F{kz|b32}
+    4390             :   ASMJIT_INST_2x(vrcp14ps, Vrcp14ps, X86Zmm, X86Mem)                          //      AVX512_F{kz|b32}
+    4391             :   ASMJIT_INST_3x(vrcp14sd, Vrcp14sd, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz}
+    4392             :   ASMJIT_INST_3x(vrcp14sd, Vrcp14sd, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz}
+    4393             :   ASMJIT_INST_3x(vrcp14ss, Vrcp14ss, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_F{kz}
+    4394             :   ASMJIT_INST_3x(vrcp14ss, Vrcp14ss, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_F{kz}
+    4395             :   ASMJIT_INST_2x(vrcp28pd, Vrcp28pd, X86Zmm, X86Zmm)                          //      AVX512_ER{kz|sae|b64}
+    4396             :   ASMJIT_INST_2x(vrcp28pd, Vrcp28pd, X86Zmm, X86Mem)                          //      AVX512_ER{kz|sae|b64}
+    4397             :   ASMJIT_INST_2x(vrcp28ps, Vrcp28ps, X86Zmm, X86Zmm)                          //      AVX512_ER{kz|sae|b32}
+    4398             :   ASMJIT_INST_2x(vrcp28ps, Vrcp28ps, X86Zmm, X86Mem)                          //      AVX512_ER{kz|sae|b32}
+    4399             :   ASMJIT_INST_3x(vrcp28sd, Vrcp28sd, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_ER{kz|sae}
+    4400             :   ASMJIT_INST_3x(vrcp28sd, Vrcp28sd, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_ER{kz|sae}
+    4401             :   ASMJIT_INST_3x(vrcp28ss, Vrcp28ss, X86Xmm, X86Xmm, X86Xmm)                  //      AVX512_ER{kz|sae}
+    4402             :   ASMJIT_INST_3x(vrcp28ss, Vrcp28ss, X86Xmm, X86Xmm, X86Mem)                  //      AVX512_ER{kz|sae}
+    4403             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Xmm, X86Xmm)                              // AVX
+    4404             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Xmm, X86Mem)                              // AVX
+    4405             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Ymm, X86Ymm)                              // AVX
+    4406             :   ASMJIT_INST_2x(vrcpps, Vrcpps, X86Ymm, X86Mem)                              // AVX
+    4407             :   ASMJIT_INST_3x(vrcpss, Vrcpss, X86Xmm, X86Xmm, X86Xmm)                      // AVX
+    4408             :   ASMJIT_INST_3x(vrcpss, Vrcpss, X86Xmm, X86Xmm, X86Mem)                      // AVX
+    4409             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Xmm, X86Xmm, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4410             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Xmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4411             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Ymm, X86Ymm, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4412             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Ymm, X86Mem, Imm)                   //      AVX512_DQ{kz|b64}-VL
+    4413             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Zmm, X86Zmm, Imm)                   //      AVX512_DQ{kz|b64}
+    4414             :   ASMJIT_INST_3i(vreducepd, Vreducepd, X86Zmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b64}
+    4415             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Xmm, X86Xmm, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4416             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Xmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4417             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Ymm, X86Ymm, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4418             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Ymm, X86Mem, Imm)                   //      AVX512_DQ{kz|b32}-VL
+    4419             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Zmm, X86Zmm, Imm)                   //      AVX512_DQ{kz|b32}
+    4420             :   ASMJIT_INST_3i(vreduceps, Vreduceps, X86Zmm, X86Mem, Imm)                   //      AVX512_DQ{kz|b32}
+    4421             :   ASMJIT_INST_4i(vreducesd, Vreducesd, X86Xmm, X86Xmm, X86Xmm, Imm)           //      AVX512_DQ{kz}
+    4422             :   ASMJIT_INST_4i(vreducesd, Vreducesd, X86Xmm, X86Xmm, X86Mem, Imm)           //      AVX512_DQ{kz}
+    4423             :   ASMJIT_INST_4i(vreducess, Vreducess, X86Xmm, X86Xmm, X86Xmm, Imm)           //      AVX512_DQ{kz}
+    4424             :   ASMJIT_INST_4i(vreducess, Vreducess, X86Xmm, X86Xmm, X86Mem, Imm)           //      AVX512_DQ{kz}
+    4425             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b64}-VL
+    4426             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    4427             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b64}-VL
+    4428             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b64}-VL
+    4429             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|sae|b64}
+    4430             :   ASMJIT_INST_3i(vrndscalepd, Vrndscalepd, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|sae|b64}
+    4431             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Xmm, X86Xmm, Imm)               //      AVX512_F{kz|b32}-VL
+    4432             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Xmm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    4433             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Ymm, X86Ymm, Imm)               //      AVX512_F{kz|b32}-VL
+    4434             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Ymm, X86Mem, Imm)               //      AVX512_F{kz|b32}-VL
+    4435             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|sae|b32}
+    4436             :   ASMJIT_INST_3i(vrndscaleps, Vrndscaleps, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|sae|b32}
+    4437             :   ASMJIT_INST_4i(vrndscalesd, Vrndscalesd, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    4438             :   ASMJIT_INST_4i(vrndscalesd, Vrndscalesd, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    4439             :   ASMJIT_INST_4i(vrndscaless, Vrndscaless, X86Xmm, X86Xmm, X86Xmm, Imm)       //      AVX512_F{kz|sae}
+    4440             :   ASMJIT_INST_4i(vrndscaless, Vrndscaless, X86Xmm, X86Xmm, X86Mem, Imm)       //      AVX512_F{kz|sae}
+    4441             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Xmm, X86Xmm, Imm)                     // AVX
+    4442             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Xmm, X86Mem, Imm)                     // AVX
+    4443             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Ymm, X86Ymm, Imm)                     // AVX
+    4444             :   ASMJIT_INST_3i(vroundpd, Vroundpd, X86Ymm, X86Mem, Imm)                     // AVX
+    4445             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Xmm, X86Xmm, Imm)                     // AVX
+    4446             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Xmm, X86Mem, Imm)                     // AVX
+    4447             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Ymm, X86Ymm, Imm)                     // AVX
+    4448             :   ASMJIT_INST_3i(vroundps, Vroundps, X86Ymm, X86Mem, Imm)                     // AVX
+    4449             :   ASMJIT_INST_4i(vroundsd, Vroundsd, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    4450             :   ASMJIT_INST_4i(vroundsd, Vroundsd, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    4451             :   ASMJIT_INST_4i(vroundss, Vroundss, X86Xmm, X86Xmm, X86Xmm, Imm)             // AVX
+    4452             :   ASMJIT_INST_4i(vroundss, Vroundss, X86Xmm, X86Xmm, X86Mem, Imm)             // AVX
+    4453             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b64}-VL
+    4454             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Xmm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4455             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b64}-VL
+    4456             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Ymm, X86Mem)                      //      AVX512_F{kz|b64}-VL
+    4457             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b64}
+    4458             :   ASMJIT_INST_2x(vrsqrt14pd, Vrsqrt14pd, X86Zmm, X86Mem)                      //      AVX512_F{kz|b64}
+    4459             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Xmm, X86Xmm)                      //      AVX512_F{kz|b32}-VL
+    4460             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Xmm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4461             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Ymm, X86Ymm)                      //      AVX512_F{kz|b32}-VL
+    4462             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Ymm, X86Mem)                      //      AVX512_F{kz|b32}-VL
+    4463             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Zmm, X86Zmm)                      //      AVX512_F{kz|b32}
+    4464             :   ASMJIT_INST_2x(vrsqrt14ps, Vrsqrt14ps, X86Zmm, X86Mem)                      //      AVX512_F{kz|b32}
+    4465             :   ASMJIT_INST_3x(vrsqrt14sd, Vrsqrt14sd, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_F{kz}
+    4466             :   ASMJIT_INST_3x(vrsqrt14sd, Vrsqrt14sd, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{kz}
+    4467             :   ASMJIT_INST_3x(vrsqrt14ss, Vrsqrt14ss, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_F{kz}
+    4468             :   ASMJIT_INST_3x(vrsqrt14ss, Vrsqrt14ss, X86Xmm, X86Xmm, X86Mem)              //      AVX512_F{kz}
+    4469             :   ASMJIT_INST_2x(vrsqrt28pd, Vrsqrt28pd, X86Zmm, X86Zmm)                      //      AVX512_ER{kz|sae|b64}
+    4470             :   ASMJIT_INST_2x(vrsqrt28pd, Vrsqrt28pd, X86Zmm, X86Mem)                      //      AVX512_ER{kz|sae|b64}
+    4471             :   ASMJIT_INST_2x(vrsqrt28ps, Vrsqrt28ps, X86Zmm, X86Zmm)                      //      AVX512_ER{kz|sae|b32}
+    4472             :   ASMJIT_INST_2x(vrsqrt28ps, Vrsqrt28ps, X86Zmm, X86Mem)                      //      AVX512_ER{kz|sae|b32}
+    4473             :   ASMJIT_INST_3x(vrsqrt28sd, Vrsqrt28sd, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_ER{kz|sae}
+    4474             :   ASMJIT_INST_3x(vrsqrt28sd, Vrsqrt28sd, X86Xmm, X86Xmm, X86Mem)              //      AVX512_ER{kz|sae}
+    4475             :   ASMJIT_INST_3x(vrsqrt28ss, Vrsqrt28ss, X86Xmm, X86Xmm, X86Xmm)              //      AVX512_ER{kz|sae}
+    4476             :   ASMJIT_INST_3x(vrsqrt28ss, Vrsqrt28ss, X86Xmm, X86Xmm, X86Mem)              //      AVX512_ER{kz|sae}
+    4477             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Xmm, X86Xmm)                          // AVX
+    4478             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Xmm, X86Mem)                          // AVX
+    4479             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Ymm, X86Ymm)                          // AVX
+    4480             :   ASMJIT_INST_2x(vrsqrtps, Vrsqrtps, X86Ymm, X86Mem)                          // AVX
+    4481             :   ASMJIT_INST_3x(vrsqrtss, Vrsqrtss, X86Xmm, X86Xmm, X86Xmm)                  // AVX
+    4482             :   ASMJIT_INST_3x(vrsqrtss, Vrsqrtss, X86Xmm, X86Xmm, X86Mem)                  // AVX
+    4483             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b64}-VL
+    4484             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    4485             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b64}-VL
+    4486             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b64}-VL
+    4487             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|er|b64}
+    4488             :   ASMJIT_INST_3x(vscalefpd, Vscalefpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|er|b64}
+    4489             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|b32}-VL
+    4490             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    4491             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Ymm, X86Ymm, X86Ymm)                //      AVX512_F{kz|b32}-VL
+    4492             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Ymm, X86Ymm, X86Mem)                //      AVX512_F{kz|b32}-VL
+    4493             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|er|b32}
+    4494             :   ASMJIT_INST_3x(vscalefps, Vscalefps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|er|b32}
+    4495             :   ASMJIT_INST_3x(vscalefsd, Vscalefsd, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|er}
+    4496             :   ASMJIT_INST_3x(vscalefsd, Vscalefsd, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|er}
+    4497             :   ASMJIT_INST_3x(vscalefss, Vscalefss, X86Xmm, X86Xmm, X86Xmm)                //      AVX512_F{kz|er}
+    4498             :   ASMJIT_INST_3x(vscalefss, Vscalefss, X86Xmm, X86Xmm, X86Mem)                //      AVX512_F{kz|er}
+    4499             :   ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4500             :   ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    4501             :   ASMJIT_INST_2x(vscatterdpd, Vscatterdpd, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    4502             :   ASMJIT_INST_2x(vscatterdps, Vscatterdps, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4503             :   ASMJIT_INST_2x(vscatterdps, Vscatterdps, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    4504             :   ASMJIT_INST_2x(vscatterdps, Vscatterdps, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    4505             :   ASMJIT_INST_1x(vscatterpf0dpd, Vscatterpf0dpd, X86Mem)                      //      AVX512_PF{k}
+    4506             :   ASMJIT_INST_1x(vscatterpf0dps, Vscatterpf0dps, X86Mem)                      //      AVX512_PF{k}
+    4507             :   ASMJIT_INST_1x(vscatterpf0qpd, Vscatterpf0qpd, X86Mem)                      //      AVX512_PF{k}
+    4508             :   ASMJIT_INST_1x(vscatterpf0qps, Vscatterpf0qps, X86Mem)                      //      AVX512_PF{k}
+    4509             :   ASMJIT_INST_1x(vscatterpf1dpd, Vscatterpf1dpd, X86Mem)                      //      AVX512_PF{k}
+    4510             :   ASMJIT_INST_1x(vscatterpf1dps, Vscatterpf1dps, X86Mem)                      //      AVX512_PF{k}
+    4511             :   ASMJIT_INST_1x(vscatterpf1qpd, Vscatterpf1qpd, X86Mem)                      //      AVX512_PF{k}
+    4512             :   ASMJIT_INST_1x(vscatterpf1qps, Vscatterpf1qps, X86Mem)                      //      AVX512_PF{k}
+    4513             :   ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4514             :   ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, X86Mem, X86Ymm)                    //      AVX512_F{k}-VL
+    4515             :   ASMJIT_INST_2x(vscatterqpd, Vscatterqpd, X86Mem, X86Zmm)                    //      AVX512_F{k}
+    4516             :   ASMJIT_INST_2x(vscatterqps, Vscatterqps, X86Mem, X86Xmm)                    //      AVX512_F{k}-VL
+    4517             :   ASMJIT_INST_2x(vscatterqps, Vscatterqps, X86Mem, X86Ymm)                    //      AVX512_F{k}
+    4518             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b32}-VL
+    4519             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4520             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b32}
+    4521             :   ASMJIT_INST_4i(vshuff32x4, Vshuff32x4, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b32}
+    4522             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b64}-VL
+    4523             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4524             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b64}
+    4525             :   ASMJIT_INST_4i(vshuff64x2, Vshuff64x2, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b64}
+    4526             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b32}-VL
+    4527             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b32}-VL
+    4528             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b32}
+    4529             :   ASMJIT_INST_4i(vshufi32x4, Vshufi32x4, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b32}
+    4530             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Ymm, X86Ymm, X86Ymm, Imm)         //      AVX512_F{kz|b64}-VL
+    4531             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Ymm, X86Ymm, X86Mem, Imm)         //      AVX512_F{kz|b64}-VL
+    4532             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Zmm, X86Zmm, X86Zmm, Imm)         //      AVX512_F{kz|b64}
+    4533             :   ASMJIT_INST_4i(vshufi64x2, Vshufi64x2, X86Zmm, X86Zmm, X86Mem, Imm)         //      AVX512_F{kz|b64}
+    4534             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Xmm, X86Xmm, X86Xmm, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4535             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Xmm, X86Xmm, X86Mem, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4536             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Ymm, X86Ymm, X86Ymm, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4537             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Ymm, X86Ymm, X86Mem, Imm)               // AVX  AVX512_F{kz|b32}-VL
+    4538             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b32}
+    4539             :   ASMJIT_INST_4i(vshufpd, Vshufpd, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b32}
+    4540             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Xmm, X86Xmm, X86Xmm, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4541             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Xmm, X86Xmm, X86Mem, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4542             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Ymm, X86Ymm, X86Ymm, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4543             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Ymm, X86Ymm, X86Mem, Imm)               // AVX  AVX512_F{kz|b64}-VL
+    4544             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Zmm, X86Zmm, X86Zmm, Imm)               //      AVX512_F{kz|b64}
+    4545             :   ASMJIT_INST_4i(vshufps, Vshufps, X86Zmm, X86Zmm, X86Mem, Imm)               //      AVX512_F{kz|b64}
+    4546             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz|b64}-VL
+    4547             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz|b64}-VL
+    4548             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz|b64}-VL
+    4549             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz|b64}-VL
+    4550             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Zmm, X86Zmm)                            //      AVX512_F{kz|er|b64}
+    4551             :   ASMJIT_INST_2x(vsqrtpd, Vsqrtpd, X86Zmm, X86Mem)                            //      AVX512_F{kz|er|b64}
+    4552             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Xmm, X86Xmm)                            // AVX  AVX512_F{kz|b32}-VL
+    4553             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Xmm, X86Mem)                            // AVX  AVX512_F{kz|b32}-VL
+    4554             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Ymm, X86Ymm)                            // AVX  AVX512_F{kz|b32}-VL
+    4555             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Ymm, X86Mem)                            // AVX  AVX512_F{kz|b32}-VL
+    4556             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Zmm, X86Zmm)                            //      AVX512_F{kz|er|b32}
+    4557             :   ASMJIT_INST_2x(vsqrtps, Vsqrtps, X86Zmm, X86Mem)                            //      AVX512_F{kz|er|b32}
+    4558             :   ASMJIT_INST_3x(vsqrtsd, Vsqrtsd, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|er}
+    4559             :   ASMJIT_INST_3x(vsqrtsd, Vsqrtsd, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|er}
+    4560             :   ASMJIT_INST_3x(vsqrtss, Vsqrtss, X86Xmm, X86Xmm, X86Xmm)                    // AVX  AVX512_F{kz|er}
+    4561             :   ASMJIT_INST_3x(vsqrtss, Vsqrtss, X86Xmm, X86Xmm, X86Mem)                    // AVX  AVX512_F{kz|er}
+    4562             :   ASMJIT_INST_1x(vstmxcsr, Vstmxcsr, X86Mem)                                  // AVX
+    4563             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b64}-VL
+    4564             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b64}-VL
+    4565             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b64}-VL
+    4566             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b64}-VL
+    4567             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b64}
+    4568             :   ASMJIT_INST_3x(vsubpd, Vsubpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b64}
+    4569             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|b32}-VL
+    4570             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|b32}-VL
+    4571             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Ymm, X86Ymm, X86Ymm)                      // AVX2 AVX512_F{kz|b32}-VL
+    4572             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Ymm, X86Ymm, X86Mem)                      // AVX2 AVX512_F{kz|b32}-VL
+    4573             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_F{kz|er|b32}
+    4574             :   ASMJIT_INST_3x(vsubps, Vsubps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_F{kz|er|b32}
+    4575             :   ASMJIT_INST_3x(vsubsd, Vsubsd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    4576             :   ASMJIT_INST_3x(vsubsd, Vsubsd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    4577             :   ASMJIT_INST_3x(vsubss, Vsubss, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_F{kz|er}
+    4578             :   ASMJIT_INST_3x(vsubss, Vsubss, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_F{kz|er}
+    4579             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Xmm, X86Xmm)                            // AVX
+    4580             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Xmm, X86Mem)                            // AVX
+    4581             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Ymm, X86Ymm)                            // AVX
+    4582             :   ASMJIT_INST_2x(vtestpd, Vtestpd, X86Ymm, X86Mem)                            // AVX
+    4583             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Xmm, X86Xmm)                            // AVX
+    4584             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Xmm, X86Mem)                            // AVX
+    4585             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Ymm, X86Ymm)                            // AVX
+    4586             :   ASMJIT_INST_2x(vtestps, Vtestps, X86Ymm, X86Mem)                            // AVX
+    4587             :   ASMJIT_INST_2x(vucomisd, Vucomisd, X86Xmm, X86Xmm)                          // AVX  AVX512_F{sae}
+    4588             :   ASMJIT_INST_2x(vucomisd, Vucomisd, X86Xmm, X86Mem)                          // AVX  AVX512_F{sae}
+    4589             :   ASMJIT_INST_2x(vucomiss, Vucomiss, X86Xmm, X86Xmm)                          // AVX  AVX512_F{sae}
+    4590             :   ASMJIT_INST_2x(vucomiss, Vucomiss, X86Xmm, X86Mem)                          // AVX  AVX512_F{sae}
+    4591             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    4592             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4593             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    4594             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4595             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    4596             :   ASMJIT_INST_3x(vunpckhpd, Vunpckhpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    4597             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b32}-VL
+    4598             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4599             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b32}-VL
+    4600             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4601             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    4602             :   ASMJIT_INST_3x(vunpckhps, Vunpckhps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    4603             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b64}-VL
+    4604             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4605             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b64}-VL
+    4606             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b64}-VL
+    4607             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b64}
+    4608             :   ASMJIT_INST_3x(vunpcklpd, Vunpcklpd, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b64}
+    4609             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Xmm, X86Xmm, X86Xmm)                // AVX  AVX512_F{kz|b32}-VL
+    4610             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Xmm, X86Xmm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4611             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Ymm, X86Ymm, X86Ymm)                // AVX  AVX512_F{kz|b32}-VL
+    4612             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Ymm, X86Ymm, X86Mem)                // AVX  AVX512_F{kz|b32}-VL
+    4613             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Zmm, X86Zmm, X86Zmm)                //      AVX512_F{kz|b32}
+    4614             :   ASMJIT_INST_3x(vunpcklps, Vunpcklps, X86Zmm, X86Zmm, X86Mem)                //      AVX512_F{kz|b32}
+    4615             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4616             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4617             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4618             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b64}-VL
+    4619             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b64}
+    4620             :   ASMJIT_INST_3x(vxorpd, Vxorpd, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b64}
+    4621             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Xmm, X86Xmm, X86Xmm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4622             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Xmm, X86Xmm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4623             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Ymm, X86Ymm, X86Ymm)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4624             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Ymm, X86Ymm, X86Mem)                      // AVX  AVX512_DQ{kz|b32}-VL
+    4625             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Zmm, X86Zmm, X86Zmm)                      //      AVX512_DQ{kz|b32}
+    4626             :   ASMJIT_INST_3x(vxorps, Vxorps, X86Zmm, X86Zmm, X86Mem)                      //      AVX512_DQ{kz|b32}
+    4627             :   ASMJIT_INST_0x(vzeroall, Vzeroall)                                          // AVX
+    4628           0 :   ASMJIT_INST_0x(vzeroupper, Vzeroupper)                                      // AVX
+    4629             : 
+    4630             :   // --------------------------------------------------------------------------
+    4631             :   // [FMA4]
+    4632             :   // --------------------------------------------------------------------------
+    4633             : 
+    4634             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4635             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4636             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4637             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4638             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4639             :   ASMJIT_INST_4x(vfmaddpd, Vfmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4640             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4641             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4642             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4643             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4644             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4645             :   ASMJIT_INST_4x(vfmaddps, Vfmaddps, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4646             :   ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4647             :   ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4648             :   ASMJIT_INST_4x(vfmaddsd, Vfmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4649             :   ASMJIT_INST_4x(vfmaddss, Vfmaddss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4650             :   ASMJIT_INST_4x(vfmaddss, Vfmaddss, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4651             :   ASMJIT_INST_4x(vfmaddss, Vfmaddss, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4652             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4653             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4654             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4655             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4656             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4657             :   ASMJIT_INST_4x(vfmaddsubpd, Vfmaddsubpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4658             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4659             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4660             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4661             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4662             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4663             :   ASMJIT_INST_4x(vfmaddsubps, Vfmaddsubps, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4664             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4665             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4666             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4667             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4668             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4669             :   ASMJIT_INST_4x(vfmsubaddpd, Vfmsubaddpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4670             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)    // FMA4
+    4671             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Xmm, X86Xmm, X86Mem, X86Xmm)    // FMA4
+    4672             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Xmm, X86Xmm, X86Xmm, X86Mem)    // FMA4
+    4673             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)    // FMA4
+    4674             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Ymm, X86Ymm, X86Mem, X86Ymm)    // FMA4
+    4675             :   ASMJIT_INST_4x(vfmsubaddps, Vfmsubaddps, X86Ymm, X86Ymm, X86Ymm, X86Mem)    // FMA4
+    4676             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4677             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4678             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4679             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4680             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4681             :   ASMJIT_INST_4x(vfmsubpd, Vfmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4682             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4683             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4684             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4685             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)          // FMA4
+    4686             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Ymm, X86Ymm, X86Mem, X86Ymm)          // FMA4
+    4687             :   ASMJIT_INST_4x(vfmsubps, Vfmsubps, X86Ymm, X86Ymm, X86Ymm, X86Mem)          // FMA4
+    4688             :   ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4689             :   ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4690             :   ASMJIT_INST_4x(vfmsubsd, Vfmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4691             :   ASMJIT_INST_4x(vfmsubss, Vfmsubss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // FMA4
+    4692             :   ASMJIT_INST_4x(vfmsubss, Vfmsubss, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // FMA4
+    4693             :   ASMJIT_INST_4x(vfmsubss, Vfmsubss, X86Xmm, X86Xmm, X86Xmm, X86Mem)          // FMA4
+    4694             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4695             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4696             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4697             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4698             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4699             :   ASMJIT_INST_4x(vfnmaddpd, Vfnmaddpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4700             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4701             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4702             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4703             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4704             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4705             :   ASMJIT_INST_4x(vfnmaddps, Vfnmaddps, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4706             :   ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4707             :   ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4708             :   ASMJIT_INST_4x(vfnmaddsd, Vfnmaddsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4709             :   ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4710             :   ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4711             :   ASMJIT_INST_4x(vfnmaddss, Vfnmaddss, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4712             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4713             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4714             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4715             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4716             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4717             :   ASMJIT_INST_4x(vfnmsubpd, Vfnmsubpd, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4718             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4719             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4720             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4721             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Ymm, X86Ymm, X86Ymm, X86Ymm)        // FMA4
+    4722             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Ymm, X86Ymm, X86Mem, X86Ymm)        // FMA4
+    4723             :   ASMJIT_INST_4x(vfnmsubps, Vfnmsubps, X86Ymm, X86Ymm, X86Ymm, X86Mem)        // FMA4
+    4724             :   ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4725             :   ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4726             :   ASMJIT_INST_4x(vfnmsubsd, Vfnmsubsd, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4727             :   ASMJIT_INST_4x(vfnmsubss, Vfnmsubss, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // FMA4
+    4728             :   ASMJIT_INST_4x(vfnmsubss, Vfnmsubss, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // FMA4
+    4729             :   ASMJIT_INST_4x(vfnmsubss, Vfnmsubss, X86Xmm, X86Xmm, X86Xmm, X86Mem)        // FMA4
+    4730             : 
+    4731             :   // --------------------------------------------------------------------------
+    4732             :   // [XOP]
+    4733             :   // --------------------------------------------------------------------------
+    4734             : 
+    4735             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Xmm, X86Xmm)                            // XOP
+    4736             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Xmm, X86Mem)                            // XOP
+    4737             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Ymm, X86Ymm)                            // XOP
+    4738             :   ASMJIT_INST_2x(vfrczpd, Vfrczpd, X86Ymm, X86Mem)                            // XOP
+    4739             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Xmm, X86Xmm)                            // XOP
+    4740             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Xmm, X86Mem)                            // XOP
+    4741             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Ymm, X86Ymm)                            // XOP
+    4742             :   ASMJIT_INST_2x(vfrczps, Vfrczps, X86Ymm, X86Mem)                            // XOP
+    4743             :   ASMJIT_INST_2x(vfrczsd, Vfrczsd, X86Xmm, X86Xmm)                            // XOP
+    4744             :   ASMJIT_INST_2x(vfrczsd, Vfrczsd, X86Xmm, X86Mem)                            // XOP
+    4745             :   ASMJIT_INST_2x(vfrczss, Vfrczss, X86Xmm, X86Xmm)                            // XOP
+    4746             :   ASMJIT_INST_2x(vfrczss, Vfrczss, X86Xmm, X86Mem)                            // XOP
+    4747             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Xmm, X86Xmm, X86Xmm, X86Xmm)              // XOP
+    4748             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Xmm, X86Xmm, X86Mem, X86Xmm)              // XOP
+    4749             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Xmm, X86Xmm, X86Xmm, X86Mem)              // XOP
+    4750             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Ymm, X86Ymm, X86Ymm, X86Ymm)              // XOP
+    4751             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Ymm, X86Ymm, X86Mem, X86Ymm)              // XOP
+    4752             :   ASMJIT_INST_4x(vpcmov, Vpcmov, X86Ymm, X86Ymm, X86Ymm, X86Mem)              // XOP
+    4753             :   ASMJIT_INST_4i(vpcomb, Vpcomb, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4754             :   ASMJIT_INST_4i(vpcomb, Vpcomb, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4755             :   ASMJIT_INST_4i(vpcomd, Vpcomd, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4756             :   ASMJIT_INST_4i(vpcomd, Vpcomd, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4757             :   ASMJIT_INST_4i(vpcomq, Vpcomq, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4758             :   ASMJIT_INST_4i(vpcomq, Vpcomq, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4759             :   ASMJIT_INST_4i(vpcomw, Vpcomw, X86Xmm, X86Xmm, X86Xmm, Imm)                 // XOP
+    4760             :   ASMJIT_INST_4i(vpcomw, Vpcomw, X86Xmm, X86Xmm, X86Mem, Imm)                 // XOP
+    4761             :   ASMJIT_INST_4i(vpcomub, Vpcomub, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4762             :   ASMJIT_INST_4i(vpcomub, Vpcomub, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4763             :   ASMJIT_INST_4i(vpcomud, Vpcomud, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4764             :   ASMJIT_INST_4i(vpcomud, Vpcomud, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4765             :   ASMJIT_INST_4i(vpcomuq, Vpcomuq, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4766             :   ASMJIT_INST_4i(vpcomuq, Vpcomuq, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4767             :   ASMJIT_INST_4i(vpcomuw, Vpcomuw, X86Xmm, X86Xmm, X86Xmm, Imm)               // XOP
+    4768             :   ASMJIT_INST_4i(vpcomuw, Vpcomuw, X86Xmm, X86Xmm, X86Mem, Imm)               // XOP
+    4769             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Xmm, X86Xmm, X86Xmm, X86Xmm, Imm) // XOP
+    4770             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Xmm, X86Xmm, X86Mem, X86Xmm, Imm) // XOP
+    4771             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Xmm, X86Xmm, X86Xmm, X86Mem, Imm) // XOP
+    4772             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Ymm, X86Ymm, X86Ymm, X86Ymm, Imm) // XOP
+    4773             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Ymm, X86Ymm, X86Mem, X86Ymm, Imm) // XOP
+    4774             :   ASMJIT_INST_5i(vpermil2pd, Vpermil2pd, X86Ymm, X86Ymm, X86Ymm, X86Mem, Imm) // XOP
+    4775             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Xmm, X86Xmm, X86Xmm, X86Xmm, Imm) // XOP
+    4776             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Xmm, X86Xmm, X86Mem, X86Xmm, Imm) // XOP
+    4777             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Xmm, X86Xmm, X86Xmm, X86Mem, Imm) // XOP
+    4778             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Ymm, X86Ymm, X86Ymm, X86Ymm, Imm) // XOP
+    4779             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Ymm, X86Ymm, X86Mem, X86Ymm, Imm) // XOP
+    4780             :   ASMJIT_INST_5i(vpermil2ps, Vpermil2ps, X86Ymm, X86Ymm, X86Ymm, X86Mem, Imm) // XOP
+    4781             :   ASMJIT_INST_2x(vphaddbd, Vphaddbd, X86Xmm, X86Xmm)                          // XOP
+    4782             :   ASMJIT_INST_2x(vphaddbd, Vphaddbd, X86Xmm, X86Mem)                          // XOP
+    4783             :   ASMJIT_INST_2x(vphaddbq, Vphaddbq, X86Xmm, X86Xmm)                          // XOP
+    4784             :   ASMJIT_INST_2x(vphaddbq, Vphaddbq, X86Xmm, X86Mem)                          // XOP
+    4785             :   ASMJIT_INST_2x(vphaddbw, Vphaddbw, X86Xmm, X86Xmm)                          // XOP
+    4786             :   ASMJIT_INST_2x(vphaddbw, Vphaddbw, X86Xmm, X86Mem)                          // XOP
+    4787             :   ASMJIT_INST_2x(vphadddq, Vphadddq, X86Xmm, X86Xmm)                          // XOP
+    4788             :   ASMJIT_INST_2x(vphadddq, Vphadddq, X86Xmm, X86Mem)                          // XOP
+    4789             :   ASMJIT_INST_2x(vphaddwd, Vphaddwd, X86Xmm, X86Xmm)                          // XOP
+    4790             :   ASMJIT_INST_2x(vphaddwd, Vphaddwd, X86Xmm, X86Mem)                          // XOP
+    4791             :   ASMJIT_INST_2x(vphaddwq, Vphaddwq, X86Xmm, X86Xmm)                          // XOP
+    4792             :   ASMJIT_INST_2x(vphaddwq, Vphaddwq, X86Xmm, X86Mem)                          // XOP
+    4793             :   ASMJIT_INST_2x(vphaddubd, Vphaddubd, X86Xmm, X86Xmm)                        // XOP
+    4794             :   ASMJIT_INST_2x(vphaddubd, Vphaddubd, X86Xmm, X86Mem)                        // XOP
+    4795             :   ASMJIT_INST_2x(vphaddubq, Vphaddubq, X86Xmm, X86Xmm)                        // XOP
+    4796             :   ASMJIT_INST_2x(vphaddubq, Vphaddubq, X86Xmm, X86Mem)                        // XOP
+    4797             :   ASMJIT_INST_2x(vphaddubw, Vphaddubw, X86Xmm, X86Xmm)                        // XOP
+    4798             :   ASMJIT_INST_2x(vphaddubw, Vphaddubw, X86Xmm, X86Mem)                        // XOP
+    4799             :   ASMJIT_INST_2x(vphaddudq, Vphaddudq, X86Xmm, X86Xmm)                        // XOP
+    4800             :   ASMJIT_INST_2x(vphaddudq, Vphaddudq, X86Xmm, X86Mem)                        // XOP
+    4801             :   ASMJIT_INST_2x(vphadduwd, Vphadduwd, X86Xmm, X86Xmm)                        // XOP
+    4802             :   ASMJIT_INST_2x(vphadduwd, Vphadduwd, X86Xmm, X86Mem)                        // XOP
+    4803             :   ASMJIT_INST_2x(vphadduwq, Vphadduwq, X86Xmm, X86Xmm)                        // XOP
+    4804             :   ASMJIT_INST_2x(vphadduwq, Vphadduwq, X86Xmm, X86Mem)                        // XOP
+    4805             :   ASMJIT_INST_2x(vphsubbw, Vphsubbw, X86Xmm, X86Xmm)                          // XOP
+    4806             :   ASMJIT_INST_2x(vphsubbw, Vphsubbw, X86Xmm, X86Mem)                          // XOP
+    4807             :   ASMJIT_INST_2x(vphsubdq, Vphsubdq, X86Xmm, X86Xmm)                          // XOP
+    4808             :   ASMJIT_INST_2x(vphsubdq, Vphsubdq, X86Xmm, X86Mem)                          // XOP
+    4809             :   ASMJIT_INST_2x(vphsubwd, Vphsubwd, X86Xmm, X86Xmm)                          // XOP
+    4810             :   ASMJIT_INST_2x(vphsubwd, Vphsubwd, X86Xmm, X86Mem)                          // XOP
+    4811             :   ASMJIT_INST_4x(vpmacsdd, Vpmacsdd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // XOP
+    4812             :   ASMJIT_INST_4x(vpmacsdd, Vpmacsdd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // XOP
+    4813             :   ASMJIT_INST_4x(vpmacsdqh, Vpmacsdqh, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4814             :   ASMJIT_INST_4x(vpmacsdqh, Vpmacsdqh, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4815             :   ASMJIT_INST_4x(vpmacsdql, Vpmacsdql, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4816             :   ASMJIT_INST_4x(vpmacsdql, Vpmacsdql, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4817             :   ASMJIT_INST_4x(vpmacswd, Vpmacswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // XOP
+    4818             :   ASMJIT_INST_4x(vpmacswd, Vpmacswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // XOP
+    4819             :   ASMJIT_INST_4x(vpmacsww, Vpmacsww, X86Xmm, X86Xmm, X86Xmm, X86Xmm)          // XOP
+    4820             :   ASMJIT_INST_4x(vpmacsww, Vpmacsww, X86Xmm, X86Xmm, X86Mem, X86Xmm)          // XOP
+    4821             :   ASMJIT_INST_4x(vpmacssdd, Vpmacssdd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4822             :   ASMJIT_INST_4x(vpmacssdd, Vpmacssdd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4823             :   ASMJIT_INST_4x(vpmacssdqh, Vpmacssdqh, X86Xmm, X86Xmm, X86Xmm, X86Xmm)      // XOP
+    4824             :   ASMJIT_INST_4x(vpmacssdqh, Vpmacssdqh, X86Xmm, X86Xmm, X86Mem, X86Xmm)      // XOP
+    4825             :   ASMJIT_INST_4x(vpmacssdql, Vpmacssdql, X86Xmm, X86Xmm, X86Xmm, X86Xmm)      // XOP
+    4826             :   ASMJIT_INST_4x(vpmacssdql, Vpmacssdql, X86Xmm, X86Xmm, X86Mem, X86Xmm)      // XOP
+    4827             :   ASMJIT_INST_4x(vpmacsswd, Vpmacsswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4828             :   ASMJIT_INST_4x(vpmacsswd, Vpmacsswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4829             :   ASMJIT_INST_4x(vpmacssww, Vpmacssww, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4830             :   ASMJIT_INST_4x(vpmacssww, Vpmacssww, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4831             :   ASMJIT_INST_4x(vpmadcsswd, Vpmadcsswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)      // XOP
+    4832             :   ASMJIT_INST_4x(vpmadcsswd, Vpmadcsswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)      // XOP
+    4833             :   ASMJIT_INST_4x(vpmadcswd, Vpmadcswd, X86Xmm, X86Xmm, X86Xmm, X86Xmm)        // XOP
+    4834             :   ASMJIT_INST_4x(vpmadcswd, Vpmadcswd, X86Xmm, X86Xmm, X86Mem, X86Xmm)        // XOP
+    4835             :   ASMJIT_INST_4x(vpperm, Vpperm, X86Xmm, X86Xmm, X86Xmm, X86Xmm)              // XOP
+    4836             :   ASMJIT_INST_4x(vpperm, Vpperm, X86Xmm, X86Xmm, X86Mem, X86Xmm)              // XOP
+    4837             :   ASMJIT_INST_4x(vpperm, Vpperm, X86Xmm, X86Xmm, X86Xmm, X86Mem)              // XOP
+    4838             :   ASMJIT_INST_3x(vprotb, Vprotb, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4839             :   ASMJIT_INST_3x(vprotb, Vprotb, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4840             :   ASMJIT_INST_3x(vprotb, Vprotb, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4841             :   ASMJIT_INST_3i(vprotb, Vprotb, X86Xmm, X86Xmm, Imm)                         // XOP
+    4842             :   ASMJIT_INST_3i(vprotb, Vprotb, X86Xmm, X86Mem, Imm)                         // XOP
+    4843             :   ASMJIT_INST_3x(vprotd, Vprotd, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4844             :   ASMJIT_INST_3x(vprotd, Vprotd, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4845             :   ASMJIT_INST_3x(vprotd, Vprotd, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4846             :   ASMJIT_INST_3i(vprotd, Vprotd, X86Xmm, X86Xmm, Imm)                         // XOP
+    4847             :   ASMJIT_INST_3i(vprotd, Vprotd, X86Xmm, X86Mem, Imm)                         // XOP
+    4848             :   ASMJIT_INST_3x(vprotq, Vprotq, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4849             :   ASMJIT_INST_3x(vprotq, Vprotq, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4850             :   ASMJIT_INST_3x(vprotq, Vprotq, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4851             :   ASMJIT_INST_3i(vprotq, Vprotq, X86Xmm, X86Xmm, Imm)                         // XOP
+    4852             :   ASMJIT_INST_3i(vprotq, Vprotq, X86Xmm, X86Mem, Imm)                         // XOP
+    4853             :   ASMJIT_INST_3x(vprotw, Vprotw, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4854             :   ASMJIT_INST_3x(vprotw, Vprotw, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4855             :   ASMJIT_INST_3x(vprotw, Vprotw, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4856             :   ASMJIT_INST_3i(vprotw, Vprotw, X86Xmm, X86Xmm, Imm)                         // XOP
+    4857             :   ASMJIT_INST_3i(vprotw, Vprotw, X86Xmm, X86Mem, Imm)                         // XOP
+    4858             :   ASMJIT_INST_3x(vpshab, Vpshab, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4859             :   ASMJIT_INST_3x(vpshab, Vpshab, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4860             :   ASMJIT_INST_3x(vpshab, Vpshab, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4861             :   ASMJIT_INST_3x(vpshad, Vpshad, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4862             :   ASMJIT_INST_3x(vpshad, Vpshad, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4863             :   ASMJIT_INST_3x(vpshad, Vpshad, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4864             :   ASMJIT_INST_3x(vpshaq, Vpshaq, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4865             :   ASMJIT_INST_3x(vpshaq, Vpshaq, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4866             :   ASMJIT_INST_3x(vpshaq, Vpshaq, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4867             :   ASMJIT_INST_3x(vpshaw, Vpshaw, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4868             :   ASMJIT_INST_3x(vpshaw, Vpshaw, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4869             :   ASMJIT_INST_3x(vpshaw, Vpshaw, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4870             :   ASMJIT_INST_3x(vpshlb, Vpshlb, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4871             :   ASMJIT_INST_3x(vpshlb, Vpshlb, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4872             :   ASMJIT_INST_3x(vpshlb, Vpshlb, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4873             :   ASMJIT_INST_3x(vpshld, Vpshld, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4874             :   ASMJIT_INST_3x(vpshld, Vpshld, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4875             :   ASMJIT_INST_3x(vpshld, Vpshld, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4876             :   ASMJIT_INST_3x(vpshlq, Vpshlq, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4877             :   ASMJIT_INST_3x(vpshlq, Vpshlq, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4878             :   ASMJIT_INST_3x(vpshlq, Vpshlq, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4879             :   ASMJIT_INST_3x(vpshlw, Vpshlw, X86Xmm, X86Xmm, X86Xmm)                      // XOP
+    4880             :   ASMJIT_INST_3x(vpshlw, Vpshlw, X86Xmm, X86Mem, X86Xmm)                      // XOP
+    4881             :   ASMJIT_INST_3x(vpshlw, Vpshlw, X86Xmm, X86Xmm, X86Mem)                      // XOP
+    4882             : };
+    4883             : 
+    4884             : // ============================================================================
+    4885             : // [asmjit::X86EmitterImplicitT]
+    4886             : // ============================================================================
+    4887             : 
+    4888             : template<typename This>
+    4889             : struct X86EmitterImplicitT : public X86EmitterExplicitT<This> {
+    4890             :   // --------------------------------------------------------------------------
+    4891             :   // [Options]
+    4892             :   // --------------------------------------------------------------------------
+    4893             : 
+    4894             :   //! Use REP/REPZ prefix.
+    4895             :   ASMJIT_INLINE This& rep() noexcept { return X86EmitterExplicitT<This>::_addOptions(X86Inst::kOptionRep); }
+    4896             :   //! Use REPNZ prefix.
+    4897             :   ASMJIT_INLINE This& repnz() noexcept { return X86EmitterExplicitT<This>::_addOptions(X86Inst::kOptionRepnz); }
+    4898             : 
+    4899             :   //! Use REP/REPZ prefix.
+    4900             :   ASMJIT_INLINE This& repe() noexcept { return rep(); }
+    4901             :   //! Use REP/REPZ prefix.
+    4902             :   ASMJIT_INLINE This& repz() noexcept { return rep(); }
+    4903             :   //! Use REPNZ prefix.
+    4904             :   ASMJIT_INLINE This& repne() noexcept { return repnz(); }
+    4905             : 
+    4906             :   // --------------------------------------------------------------------------
+    4907             :   // [General Purpose and Non-SIMD Instructions]
+    4908             :   // --------------------------------------------------------------------------
+    4909             : 
+    4910             :   // TODO: xrstor and xsave don't have explicit variants yet.
+    4911             : 
+    4912             :   using X86EmitterExplicitT<This>::cbw;
+    4913             :   using X86EmitterExplicitT<This>::cdq;
+    4914             :   using X86EmitterExplicitT<This>::cdqe;
+    4915             :   using X86EmitterExplicitT<This>::clzero;
+    4916             :   using X86EmitterExplicitT<This>::cqo;
+    4917             :   using X86EmitterExplicitT<This>::cwd;
+    4918             :   using X86EmitterExplicitT<This>::cwde;
+    4919             :   using X86EmitterExplicitT<This>::cmpsd;
+    4920             :   using X86EmitterExplicitT<This>::cmpxchg;
+    4921             :   using X86EmitterExplicitT<This>::cmpxchg8b;
+    4922             :   using X86EmitterExplicitT<This>::cmpxchg16b;
+    4923             :   using X86EmitterExplicitT<This>::cpuid;
+    4924             :   using X86EmitterExplicitT<This>::div;
+    4925             :   using X86EmitterExplicitT<This>::idiv;
+    4926             :   using X86EmitterExplicitT<This>::imul;
+    4927             :   using X86EmitterExplicitT<This>::jecxz;
+    4928             :   using X86EmitterExplicitT<This>::lahf;
+    4929             :   using X86EmitterExplicitT<This>::mulx;
+    4930             :   using X86EmitterExplicitT<This>::movsd;
+    4931             :   using X86EmitterExplicitT<This>::mul;
+    4932             :   using X86EmitterExplicitT<This>::rdmsr;
+    4933             :   using X86EmitterExplicitT<This>::rdpmc;
+    4934             :   using X86EmitterExplicitT<This>::rdtsc;
+    4935             :   using X86EmitterExplicitT<This>::rdtscp;
+    4936             :   using X86EmitterExplicitT<This>::sahf;
+    4937             :   using X86EmitterExplicitT<This>::wrmsr;
+    4938             :   using X86EmitterExplicitT<This>::xgetbv;
+    4939             :   using X86EmitterExplicitT<This>::xsetbv;
+    4940             : 
+    4941             :   ASMJIT_INST_0x(cbw, Cbw)                                                    // ANY       [IMPLICIT] AX      <- Sign Extend AL
+    4942             :   ASMJIT_INST_0x(cdq, Cdq)                                                    // ANY       [IMPLICIT] EDX:EAX <- Sign Extend EAX
+    4943             :   ASMJIT_INST_0x(cdqe, Cdqe)                                                  // X64       [IMPLICIT] RAX     <- Sign Extend EAX
+    4944             :   ASMJIT_INST_0x(clzero, Clzero)                                              // CLZERO    [IMPLICIT]
+    4945             :   ASMJIT_INST_2x(cmpxchg, Cmpxchg, X86Gp, X86Gp)                              // I486      [IMPLICIT]
+    4946             :   ASMJIT_INST_2x(cmpxchg, Cmpxchg, X86Mem, X86Gp)                             // I486      [IMPLICIT]
+    4947             :   ASMJIT_INST_1x(cmpxchg16b, Cmpxchg16b, X86Mem)                              // CMPXCHG8B [IMPLICIT] m == RDX:RAX ? m <- RCX:RBX
+    4948             :   ASMJIT_INST_1x(cmpxchg8b, Cmpxchg8b, X86Mem)                                // CMPXCHG16B[IMPLICIT] m == EDX:EAX ? m <- ECX:EBX
+    4949             :   ASMJIT_INST_0x(cpuid, Cpuid)                                                // I486      [IMPLICIT] EAX:EBX:ECX:EDX  <- CPUID[EAX:ECX]
+    4950             :   ASMJIT_INST_0x(cqo, Cqo)                                                    // X64       [IMPLICIT] RDX:RAX <- Sign Extend RAX
+    4951             :   ASMJIT_INST_0x(cwd, Cwd)                                                    // ANY       [IMPLICIT] DX:AX   <- Sign Extend AX
+    4952             :   ASMJIT_INST_0x(cwde, Cwde)                                                  // ANY       [IMPLICIT] EAX     <- Sign Extend AX
+    4953             :   ASMJIT_INST_0x(daa, Daa)
+    4954             :   ASMJIT_INST_0x(das, Das)
+    4955             :   ASMJIT_INST_1x(div, Div, X86Gp)                                             // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / r8} {xDX[Rem]:xAX[Quot] <- DX:AX / r16|r32|r64}
+    4956             :   ASMJIT_INST_1x(div, Div, X86Mem)                                            // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / m8} {xDX[Rem]:xAX[Quot] <- DX:AX / m16|m32|m64}
+    4957             :   ASMJIT_INST_1x(idiv, Idiv, X86Gp)                                           // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / r8} {xDX[Rem]:xAX[Quot] <- DX:AX / r16|r32|r64}
+    4958             :   ASMJIT_INST_1x(idiv, Idiv, X86Mem)                                          // ANY       [IMPLICIT] {AH[Rem]: AL[Quot] <- AX / m8} {xDX[Rem]:xAX[Quot] <- DX:AX / m16|m32|m64}
+    4959             :   ASMJIT_INST_1x(imul, Imul, X86Gp)                                           // ANY       [IMPLICIT] {AX <- AL * r8} {xAX:xDX <- xAX * r16|r32|r64}
+    4960             :   ASMJIT_INST_1x(imul, Imul, X86Mem)                                          // ANY       [IMPLICIT] {AX <- AL * m8} {xAX:xDX <- xAX * m16|m32|m64}
+    4961             :   ASMJIT_INST_0x(iret, Iret)                                                  // ANY       [IMPLICIT]
+    4962             :   ASMJIT_INST_0x(iretd, Iretd)                                                // ANY       [IMPLICIT]
+    4963             :   ASMJIT_INST_0x(iretq, Iretq)                                                // X64       [IMPLICIT]
+    4964             :   ASMJIT_INST_0x(iretw, Iretw)                                                // ANY       [IMPLICIT]
+    4965             :   ASMJIT_INST_1x(jecxz, Jecxz, Label)                                         // ANY       [IMPLICIT] Short jump if CX/ECX/RCX is zero.
+    4966             :   ASMJIT_INST_1x(jecxz, Jecxz, Imm)                                           // ANY       [IMPLICIT] Short jump if CX/ECX/RCX is zero.
+    4967             :   ASMJIT_INST_1x(jecxz, Jecxz, uint64_t)                                      // ANY       [IMPLICIT] Short jump if CX/ECX/RCX is zero.
+    4968             :   ASMJIT_INST_0x(lahf, Lahf)                                                  // LAHFSAHF  [IMPLICIT] AH <- EFL
+    4969             :   ASMJIT_INST_1x(loop, Loop, Label)                                           // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0.
+    4970             :   ASMJIT_INST_1x(loop, Loop, Imm)                                             // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0.
+    4971             :   ASMJIT_INST_1x(loop, Loop, uint64_t)                                        // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0.
+    4972             :   ASMJIT_INST_1x(loope, Loope, Label)                                         // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+    4973             :   ASMJIT_INST_1x(loope, Loope, Imm)                                           // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+    4974             :   ASMJIT_INST_1x(loope, Loope, uint64_t)                                      // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 1.
+    4975             :   ASMJIT_INST_1x(loopne, Loopne, Label)                                       // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+    4976             :   ASMJIT_INST_1x(loopne, Loopne, Imm)                                         // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+    4977             :   ASMJIT_INST_1x(loopne, Loopne, uint64_t)                                    // ANY       [IMPLICIT] Decrement xCX; short jump if xCX != 0 && ZF == 0.
+    4978             :   ASMJIT_INST_1x(mul, Mul, X86Gp)                                             // ANY       [IMPLICIT] {AX <- AL * r8} {xDX:xAX <- xAX * r16|r32|r64}
+    4979             :   ASMJIT_INST_1x(mul, Mul, X86Mem)                                            // ANY       [IMPLICIT] {AX <- AL * m8} {xDX:xAX <- xAX * m16|m32|m64}
+    4980             :   ASMJIT_INST_3x(mulx, Mulx, X86Gp, X86Gp, X86Gp)                             // BMI2      [IMPLICIT]
+    4981             :   ASMJIT_INST_3x(mulx, Mulx, X86Gp, X86Gp, X86Mem)                            // BMI2      [IMPLICIT]
+    4982             :   ASMJIT_INST_0x(rdmsr, Rdmsr)                                                // ANY       [IMPLICIT]
+    4983             :   ASMJIT_INST_0x(rdpmc, Rdpmc)                                                // ANY       [IMPLICIT]
+    4984             :   ASMJIT_INST_0x(rdtsc, Rdtsc)                                                // RDTSC     [IMPLICIT] EDX:EAX <- CNT
+    4985             :   ASMJIT_INST_0x(rdtscp, Rdtscp)                                              // RDTSCP    [IMPLICIT] EDX:EAX:EXC <- CNT
+    4986             :   ASMJIT_INST_0x(ret, Ret)
+    4987             :   ASMJIT_INST_1i(ret, Ret, Imm)
+    4988             :   ASMJIT_INST_0x(sahf, Sahf)                                                  // LAHFSAHF  [IMPLICIT] EFL <- AH
+    4989             :   ASMJIT_INST_0x(syscall, Syscall)                                            // X64       [IMPLICIT]
+    4990             :   ASMJIT_INST_0x(sysenter, Sysenter)                                          // X64       [IMPLICIT]
+    4991             :   ASMJIT_INST_0x(sysexit, Sysexit)                                            // X64       [IMPLICIT]
+    4992             :   ASMJIT_INST_0x(sysexit64, Sysexit64)                                        // X64       [IMPLICIT]
+    4993             :   ASMJIT_INST_0x(sysret, Sysret)                                              // X64       [IMPLICIT]
+    4994             :   ASMJIT_INST_0x(sysret64, Sysret64)                                          // X64       [IMPLICIT]
+    4995             :   ASMJIT_INST_0x(wrmsr, Wrmsr)                                                // ANY       [IMPLICIT]
+    4996             :   ASMJIT_INST_0x(xgetbv, Xgetbv)                                              // XSAVE     [IMPLICIT] EDX:EAX <- XCR[ECX]
+    4997             :   ASMJIT_INST_0x(xlatb, Xlatb)                                                // ANY       [IMPLICIT]
+    4998             :   ASMJIT_INST_1x(xrstor, Xrstor, X86Mem)                                      // XSAVE     [IMPLICIT]
+    4999             :   ASMJIT_INST_1x(xrstor64, Xrstor64, X86Mem)                                  // XSAVE+X64 [IMPLICIT]
+    5000             :   ASMJIT_INST_1x(xrstors, Xrstors, X86Mem)                                    // XSAVE     [IMPLICIT]
+    5001             :   ASMJIT_INST_1x(xrstors64, Xrstors64, X86Mem)                                // XSAVE+X64 [IMPLICIT]
+    5002             :   ASMJIT_INST_1x(xsave, Xsave, X86Mem)                                        // XSAVE     [IMPLICIT]
+    5003             :   ASMJIT_INST_1x(xsave64, Xsave64, X86Mem)                                    // XSAVE+X64 [IMPLICIT]
+    5004             :   ASMJIT_INST_1x(xsavec, Xsavec, X86Mem)                                      // XSAVE     [IMPLICIT]
+    5005             :   ASMJIT_INST_1x(xsavec64, Xsavec64, X86Mem)                                  // XSAVE+X64 [IMPLICIT]
+    5006             :   ASMJIT_INST_1x(xsaveopt, Xsaveopt, X86Mem)                                  // XSAVE     [IMPLICIT]
+    5007             :   ASMJIT_INST_1x(xsaveopt64, Xsaveopt64, X86Mem)                              // XSAVE+X64 [IMPLICIT]
+    5008             :   ASMJIT_INST_1x(xsaves, Xsaves, X86Mem)                                      // XSAVE     [IMPLICIT]
+    5009             :   ASMJIT_INST_1x(xsaves64, Xsaves64, X86Mem)                                  // XSAVE+X64 [IMPLICIT]
+    5010             :   ASMJIT_INST_0x(xsetbv, Xsetbv)                                              // XSAVE     [IMPLICIT] XCR[ECX] <- EDX:EAX
+    5011             : 
+    5012             :   // String instructions aliases.
+    5013             :   ASMJIT_INLINE Error cmpsb() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 1), X86EmitterExplicitT<This>::ptr_zdi(0, 1)); }
+    5014             :   ASMJIT_INLINE Error cmpsd() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 4), X86EmitterExplicitT<This>::ptr_zdi(0, 4)); }
+    5015             :   ASMJIT_INLINE Error cmpsq() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 8), X86EmitterExplicitT<This>::ptr_zdi(0, 8)); }
+    5016             :   ASMJIT_INLINE Error cmpsw() { return ASMJIT_EMIT(X86Inst::kIdCmps, X86EmitterExplicitT<This>::ptr_zsi(0, 2), X86EmitterExplicitT<This>::ptr_zdi(0, 2)); }
+    5017             : 
+    5018             :   ASMJIT_INLINE Error lodsb() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::al , X86EmitterExplicitT<This>::ptr_zdi(0, 1)); }
+    5019             :   ASMJIT_INLINE Error lodsd() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::eax, X86EmitterExplicitT<This>::ptr_zdi(0, 4)); }
+    5020             :   ASMJIT_INLINE Error lodsq() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::rax, X86EmitterExplicitT<This>::ptr_zdi(0, 8)); }
+    5021             :   ASMJIT_INLINE Error lodsw() { return ASMJIT_EMIT(X86Inst::kIdLods, x86::ax , X86EmitterExplicitT<This>::ptr_zdi(0, 2)); }
+    5022             : 
+    5023             :   ASMJIT_INLINE Error movsb() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 1), X86EmitterExplicitT<This>::ptr_zsi(0, 1)); }
+    5024             :   ASMJIT_INLINE Error movsd() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 4), X86EmitterExplicitT<This>::ptr_zsi(0, 4)); }
+    5025             :   ASMJIT_INLINE Error movsq() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 8), X86EmitterExplicitT<This>::ptr_zsi(0, 8)); }
+    5026             :   ASMJIT_INLINE Error movsw() { return ASMJIT_EMIT(X86Inst::kIdMovs, X86EmitterExplicitT<This>::ptr_zdi(0, 2), X86EmitterExplicitT<This>::ptr_zsi(0, 2)); }
+    5027             : 
+    5028             :   ASMJIT_INLINE Error scasb() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::al , X86EmitterExplicitT<This>::ptr_zdi(0, 1)); }
+    5029             :   ASMJIT_INLINE Error scasd() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::eax, X86EmitterExplicitT<This>::ptr_zdi(0, 4)); }
+    5030             :   ASMJIT_INLINE Error scasq() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::rax, X86EmitterExplicitT<This>::ptr_zdi(0, 8)); }
+    5031             :   ASMJIT_INLINE Error scasw() { return ASMJIT_EMIT(X86Inst::kIdScas, x86::ax , X86EmitterExplicitT<This>::ptr_zdi(0, 2)); }
+    5032             : 
+    5033             :   ASMJIT_INLINE Error stosb() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 1), x86::al ); }
+    5034             :   ASMJIT_INLINE Error stosd() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 4), x86::eax); }
+    5035             :   ASMJIT_INLINE Error stosq() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 8), x86::rax); }
+    5036             :   ASMJIT_INLINE Error stosw() { return ASMJIT_EMIT(X86Inst::kIdStos, X86EmitterExplicitT<This>::ptr_zdi(0, 2), x86::ax ); }
+    5037             : 
+    5038             :   // --------------------------------------------------------------------------
+    5039             :   // [MONITOR|MWAIT]
+    5040             :   // --------------------------------------------------------------------------
+    5041             : 
+    5042             :   ASMJIT_INST_0x(monitor, Monitor)
+    5043             :   ASMJIT_INST_0x(mwait, Mwait)
+    5044             : 
+    5045             :   // --------------------------------------------------------------------------
+    5046             :   // [MMX & SSE Instructions]
+    5047             :   // --------------------------------------------------------------------------
+    5048             : 
+    5049             :   using X86EmitterExplicitT<This>::blendvpd;
+    5050             :   using X86EmitterExplicitT<This>::blendvps;
+    5051             :   using X86EmitterExplicitT<This>::maskmovq;
+    5052             :   using X86EmitterExplicitT<This>::maskmovdqu;
+    5053             :   using X86EmitterExplicitT<This>::pblendvb;
+    5054             :   using X86EmitterExplicitT<This>::pcmpestri;
+    5055             :   using X86EmitterExplicitT<This>::pcmpestrm;
+    5056             :   using X86EmitterExplicitT<This>::pcmpistri;
+    5057             :   using X86EmitterExplicitT<This>::pcmpistrm;
+    5058             : 
+    5059             :   ASMJIT_INST_2x(blendvpd, Blendvpd, X86Xmm, X86Xmm)                          // SSE4_1 [IMPLICIT]
+    5060             :   ASMJIT_INST_2x(blendvpd, Blendvpd, X86Xmm, X86Mem)                          // SSE4_1 [IMPLICIT]
+    5061             :   ASMJIT_INST_2x(blendvps, Blendvps, X86Xmm, X86Xmm)                          // SSE4_1 [IMPLICIT]
+    5062             :   ASMJIT_INST_2x(blendvps, Blendvps, X86Xmm, X86Mem)                          // SSE4_1 [IMPLICIT]
+    5063             :   ASMJIT_INST_2x(pblendvb, Pblendvb, X86Xmm, X86Xmm)                          // SSE4_1 [IMPLICIT]
+    5064             :   ASMJIT_INST_2x(pblendvb, Pblendvb, X86Xmm, X86Mem)                          // SSE4_1 [IMPLICIT]
+    5065             :   ASMJIT_INST_2x(maskmovq, Maskmovq, X86Mm, X86Mm)                            // SSE    [IMPLICIT]
+    5066             :   ASMJIT_INST_2x(maskmovdqu, Maskmovdqu, X86Xmm, X86Xmm)                      // SSE2   [IMPLICIT]
+    5067             :   ASMJIT_INST_3i(pcmpestri, Pcmpestri, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5068             :   ASMJIT_INST_3i(pcmpestri, Pcmpestri, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5069             :   ASMJIT_INST_3i(pcmpestrm, Pcmpestrm, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5070             :   ASMJIT_INST_3i(pcmpestrm, Pcmpestrm, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5071             :   ASMJIT_INST_3i(pcmpistri, Pcmpistri, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5072             :   ASMJIT_INST_3i(pcmpistri, Pcmpistri, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5073             :   ASMJIT_INST_3i(pcmpistrm, Pcmpistrm, X86Xmm, X86Xmm, Imm)                   // SSE4_1 [IMPLICIT]
+    5074             :   ASMJIT_INST_3i(pcmpistrm, Pcmpistrm, X86Xmm, X86Mem, Imm)                   // SSE4_1 [IMPLICIT]
+    5075             : 
+    5076             :   // --------------------------------------------------------------------------
+    5077             :   // [SHA]
+    5078             :   // --------------------------------------------------------------------------
+    5079             : 
+    5080             :   using X86EmitterExplicitT<This>::sha256rnds2;
+    5081             : 
+    5082             :   ASMJIT_INST_2x(sha256rnds2, Sha256rnds2, X86Xmm, X86Xmm)                    // SHA [IMPLICIT]
+    5083             :   ASMJIT_INST_2x(sha256rnds2, Sha256rnds2, X86Xmm, X86Mem)                    // SHA [IMPLICIT]
+    5084             : 
+    5085             :   // --------------------------------------------------------------------------
+    5086             :   // [AVX...AVX512]
+    5087             :   // --------------------------------------------------------------------------
+    5088             : 
+    5089             :   using X86EmitterExplicitT<This>::vmaskmovdqu;
+    5090             :   using X86EmitterExplicitT<This>::vpcmpestri;
+    5091             :   using X86EmitterExplicitT<This>::vpcmpestrm;
+    5092             :   using X86EmitterExplicitT<This>::vpcmpistri;
+    5093             :   using X86EmitterExplicitT<This>::vpcmpistrm;
+    5094             : 
+    5095             :   ASMJIT_INST_2x(vmaskmovdqu, Vmaskmovdqu, X86Xmm, X86Xmm)                    // AVX  [IMPLICIT]
+    5096             :   ASMJIT_INST_3i(vpcmpestri, Vpcmpestri, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5097             :   ASMJIT_INST_3i(vpcmpestri, Vpcmpestri, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5098             :   ASMJIT_INST_3i(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5099             :   ASMJIT_INST_3i(vpcmpestrm, Vpcmpestrm, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5100             :   ASMJIT_INST_3i(vpcmpistri, Vpcmpistri, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5101             :   ASMJIT_INST_3i(vpcmpistri, Vpcmpistri, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5102             :   ASMJIT_INST_3i(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Xmm, Imm)                 // AVX  [IMPLICIT]
+    5103             :   ASMJIT_INST_3i(vpcmpistrm, Vpcmpistrm, X86Xmm, X86Mem, Imm)                 // AVX  [IMPLICIT]
+    5104             : };
+    5105             : 
+    5106             : #undef ASMJIT_INST_0x
+    5107             : #undef ASMJIT_INST_1x
+    5108             : #undef ASMJIT_INST_1i
+    5109             : #undef ASMJIT_INST_1c
+    5110             : #undef ASMJIT_INST_2x
+    5111             : #undef ASMJIT_INST_2i
+    5112             : #undef ASMJIT_INST_2c
+    5113             : #undef ASMJIT_INST_3x
+    5114             : #undef ASMJIT_INST_3i
+    5115             : #undef ASMJIT_INST_3ii
+    5116             : #undef ASMJIT_INST_4x
+    5117             : #undef ASMJIT_INST_4i
+    5118             : #undef ASMJIT_INST_4ii
+    5119             : #undef ASMJIT_INST_5x
+    5120             : #undef ASMJIT_INST_5i
+    5121             : #undef ASMJIT_INST_6x
+    5122             : #undef ASMJIT_EMIT
+    5123             : 
+    5124             : // ============================================================================
+    5125             : // [asmjit::X86Emitter]
+    5126             : // ============================================================================
+    5127             : 
+    5128             : //! X86/X64 emitter.
+    5129             : //!
+    5130             : //! NOTE: This class cannot be created, you can only cast to it and use it as
+    5131             : //! emitter that emits to either X86Assembler, X86Builder, or X86Compiler (use
+    5132             : //! with caution with X86Compiler as it expects virtual registers to be used).
+    5133             : class X86Emitter : public CodeEmitter, public X86EmitterImplicitT<X86Emitter> {
+    5134             :   ASMJIT_NONCONSTRUCTIBLE(X86Emitter)
+    5135             : };
+    5136             : 
+    5137             : //! \}
+    5138             : 
+    5139             : } // asmjit namespace
+    5140             : } // namespace PLMD
+    5141             : 
+    5142             : // [Api-End]
+    5143             : #include "./asmjit_apiend.h"
+    5144             : 
+    5145             : // [Guard]
+    5146             : #endif // _ASMJIT_X86_X86EMITTER_H
+    5147             : #pragma GCC diagnostic pop
+    5148             : #endif // __PLUMED_HAS_ASMJIT
+    5149             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.cpp.func-sort-c.html b/coverage-libs/asmjit/x86inst.cpp.func-sort-c.html new file mode 100644 index 000000000000..0682b9698fc7 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.cpp.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0240.0 %
Date:2024-02-22 21:58:47Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7X86Inst11getIdByNameEPKcm0
_ZN4PLMD6asmjit7X86Inst11getNameByIdEj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.cpp.func.html b/coverage-libs/asmjit/x86inst.cpp.func.html new file mode 100644 index 000000000000..202f30f0eb49 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.cpp.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0240.0 %
Date:2024-02-22 21:58:47Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit7X86Inst11getIdByNameEPKcm0
_ZN4PLMD6asmjit7X86Inst11getNameByIdEj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.cpp.gcov.html b/coverage-libs/asmjit/x86inst.cpp.gcov.html new file mode 100644 index 000000000000..d876c5726fec --- /dev/null +++ b/coverage-libs/asmjit/x86inst.cpp.gcov.html @@ -0,0 +1,3830 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0240.0 %
Date:2024-02-22 21:58:47Functions:020.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // ----------------------------------------------------------------------------
+      30             : // IMPORTANT: AsmJit now uses an external instruction database to populate
+      31             : // static tables within this file. Perform the following steps to regenerate
+      32             : // all tables enclosed by ${...}:
+      33             : //
+      34             : //   1. Install node.js environment <https://nodejs.org>
+      35             : //   2. Go to asmjit/tools directory
+      36             : //   3. Install either asmdb package by executing `npm install asmdb` or get
+      37             : //      the latest asmdb from <https://github.com/asmjit/asmdb> and copy/link
+      38             : //      the `asmdb` directory to `asmjit/tools/asmdb`.
+      39             : //   4. Execute `node generate-x86.js`
+      40             : //
+      41             : // Instruction encoding and opcodes were added to the `x86inst.cpp` database
+      42             : // manually in the past and they are not updated by the script as they seem
+      43             : // consistent. However, everything else is updated including instruction
+      44             : // operands and tables required to validate them, instruction read/write
+      45             : // information (including registers and flags), and all indexes to all tables.
+      46             : // ----------------------------------------------------------------------------
+      47             : 
+      48             : // [Export]
+      49             : #define ASMJIT_EXPORTS
+      50             : 
+      51             : // [Guard]
+      52             : #include "./asmjit_build.h"
+      53             : #if defined(ASMJIT_BUILD_X86)
+      54             : 
+      55             : // [Dependencies]
+      56             : #include "./cpuinfo.h"
+      57             : #include "./utils.h"
+      58             : #include "./x86inst.h"
+      59             : #include "./x86operand.h"
+      60             : 
+      61             : // [Api-Begin]
+      62             : #include "./asmjit_apibegin.h"
+      63             : 
+      64             : namespace PLMD {
+      65             : namespace asmjit {
+      66             : 
+      67             : // ============================================================================
+      68             : // [Enums (Internal)]
+      69             : // ============================================================================
+      70             : 
+      71             : //! \internal
+      72             : enum ODATA_ {
+      73             :   // PREFIX.
+      74             :   ODATA_000000  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_00,
+      75             :   ODATA_000F00  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F,
+      76             :   ODATA_000F01  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F01,
+      77             :   ODATA_000F38  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F38,
+      78             :   ODATA_000F3A  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F3A,
+      79             :   ODATA_660000  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_00,
+      80             :   ODATA_660F00  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_0F,
+      81             :   ODATA_660F38  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_0F38,
+      82             :   ODATA_660F3A  = X86Inst::kOpCode_PP_66 | X86Inst::kOpCode_MM_0F3A,
+      83             :   ODATA_F20000  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_00,
+      84             :   ODATA_F20F00  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_0F,
+      85             :   ODATA_F20F38  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_0F38,
+      86             :   ODATA_F20F3A  = X86Inst::kOpCode_PP_F2 | X86Inst::kOpCode_MM_0F3A,
+      87             :   ODATA_F30000  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_00,
+      88             :   ODATA_F30F00  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F,
+      89             :   ODATA_F30F38  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F38,
+      90             :   ODATA_F30F3A  = X86Inst::kOpCode_PP_F3 | X86Inst::kOpCode_MM_0F3A,
+      91             :   ODATA_000F0F  = X86Inst::kOpCode_PP_00 | X86Inst::kOpCode_MM_0F, // 3DNOW, special case.
+      92             : 
+      93             :   ODATA_FPU_00  = X86Inst::kOpCode_PP_00,
+      94             :   ODATA_FPU_9B  = X86Inst::kOpCode_PP_9B,
+      95             : 
+      96             :   ODATA_XOP_M8  = X86Inst::kOpCode_MM_XOP08,
+      97             :   ODATA_XOP_M9  = X86Inst::kOpCode_MM_XOP09,
+      98             : 
+      99             :   ODATA_O__     = 0,
+     100             :   ODATA_O_0     = 0 << X86Inst::kOpCode_O_Shift,
+     101             :   ODATA_O_1     = 1 << X86Inst::kOpCode_O_Shift,
+     102             :   ODATA_O_2     = 2 << X86Inst::kOpCode_O_Shift,
+     103             :   ODATA_O_3     = 3 << X86Inst::kOpCode_O_Shift,
+     104             :   ODATA_O_4     = 4 << X86Inst::kOpCode_O_Shift,
+     105             :   ODATA_O_5     = 5 << X86Inst::kOpCode_O_Shift,
+     106             :   ODATA_O_6     = 6 << X86Inst::kOpCode_O_Shift,
+     107             :   ODATA_O_7     = 7 << X86Inst::kOpCode_O_Shift,
+     108             : 
+     109             :   // REX/VEX.
+     110             :   ODATA_LL__    = 0,                                  // L is unspecified.
+     111             :   ODATA_LL_x    = 0,                                  // L is based on operand(s).
+     112             :   ODATA_LL_I    = 0,                                  // L is ignored (LIG).
+     113             :   ODATA_LL_0    = 0,                                  // L has to be zero (L.128).
+     114             :   ODATA_LL_1    = X86Inst::kOpCode_LL_256,            // L has to be one (L.256).
+     115             :   ODATA_LL_2    = X86Inst::kOpCode_LL_512,            // L has to be two (L.512).
+     116             : 
+     117             :   ODATA_W__     = 0,                                  // W is unspecified.
+     118             :   ODATA_W_x     = 0,                                  // W is based on operand(s).
+     119             :   ODATA_W_I     = 0,                                  // W is ignored (WIG).
+     120             :   ODATA_W_0     = 0,                                  // W has to be zero (W0).
+     121             :   ODATA_W_1     = X86Inst::kOpCode_W,                 // W has to be one (W1).
+     122             : 
+     123             :   // EVEX.
+     124             :   ODATA_EvexW__ = 0,                                  // Not EVEX instruction.
+     125             :   ODATA_EvexW_x = 0,                                  // EVEX.W is based on operand(s).
+     126             :   ODATA_EvexW_I = 0,                                  // EVEX.W is ignored     (EVEX.WIG).
+     127             :   ODATA_EvexW_0 = 0,                                  // EVEX.W has to be zero (EVEX.W0).
+     128             :   ODATA_EvexW_1 = X86Inst::kOpCode_EW,                // EVEX.W has to be one  (EVEX.W1).
+     129             : 
+     130             :   ODATA_N__      = 0,                                 // Base element size not used.
+     131             :   ODATA_N_0      = 0 << X86Inst::kOpCode_CDSHL_Shift, // N << 0 (BYTE).
+     132             :   ODATA_N_1      = 1 << X86Inst::kOpCode_CDSHL_Shift, // N << 1 (WORD).
+     133             :   ODATA_N_2      = 2 << X86Inst::kOpCode_CDSHL_Shift, // N << 2 (DWORD).
+     134             :   ODATA_N_3      = 3 << X86Inst::kOpCode_CDSHL_Shift, // N << 3 (QWORD).
+     135             :   ODATA_N_4      = 4 << X86Inst::kOpCode_CDSHL_Shift, // N << 4 (OWORD).
+     136             :   ODATA_N_5      = 5 << X86Inst::kOpCode_CDSHL_Shift, // N << 5 (YWORD).
+     137             : 
+     138             :   ODATA_TT__     = 0,
+     139             :   ODATA_TT_FV    = X86Inst::kOpCode_CDTT_FV,
+     140             :   ODATA_TT_HV    = X86Inst::kOpCode_CDTT_HV,
+     141             :   ODATA_TT_FVM   = X86Inst::kOpCode_CDTT_FVM,
+     142             :   ODATA_TT_T1S   = X86Inst::kOpCode_CDTT_T1S,
+     143             :   ODATA_TT_T1F   = X86Inst::kOpCode_CDTT_T1F,
+     144             :   ODATA_TT_T1W   = X86Inst::kOpCode_CDTT_T1W,
+     145             :   ODATA_TT_T2    = X86Inst::kOpCode_CDTT_T2,
+     146             :   ODATA_TT_T4    = X86Inst::kOpCode_CDTT_T4,
+     147             :   ODATA_TT_T8    = X86Inst::kOpCode_CDTT_T8,
+     148             :   ODATA_TT_HVM   = X86Inst::kOpCode_CDTT_HVM,
+     149             :   ODATA_TT_OVM   = X86Inst::kOpCode_CDTT_OVM,
+     150             :   ODATA_TT_QVM   = X86Inst::kOpCode_CDTT_QVM,
+     151             :   ODATA_TT_128   = X86Inst::kOpCode_CDTT_128,
+     152             :   ODATA_TT_DUP   = X86Inst::kOpCode_CDTT_DUP,
+     153             :   ODATA_TT_T4X   = X86Inst::kOpCode_CDTT_T1_4X
+     154             : };
+     155             : 
+     156             : // ============================================================================
+     157             : // [asmjit::X86Inst]
+     158             : // ============================================================================
+     159             : 
+     160             : // Instruction opcode definitions:
+     161             : //   - `O` encodes X86|MMX|SSE instructions.
+     162             : //   - `V` encodes VEX|XOP|EVEX instructions.
+     163             : #define O_ENCODE(VEX, PREFIX, OPCODE, O, L, W, EvexW, N, TT) \
+     164             :   ((PREFIX) | (OPCODE) | (O) | (L) | (W) | (EvexW) | (N) | (TT) | \
+     165             :    (VEX && ((PREFIX) & X86Inst::kOpCode_MM_Mask) != X86Inst::kOpCode_MM_0F ? int(X86Inst::kOpCode_MM_ForceVex3) : 0))
+     166             : 
+     167             : #define O(PREFIX, OPCODE, O, LL, W, EvexW, N, TT) (O_ENCODE(0, ODATA_##PREFIX, 0x##OPCODE, ODATA_O_##O, ODATA_LL_##LL, ODATA_W_##W, ODATA_EvexW_##EvexW, ODATA_N_##N, ODATA_TT_##TT))
+     168             : #define V(PREFIX, OPCODE, O, LL, W, EvexW, N, TT) (O_ENCODE(1, ODATA_##PREFIX, 0x##OPCODE, ODATA_O_##O, ODATA_LL_##LL, ODATA_W_##W, ODATA_EvexW_##EvexW, ODATA_N_##N, ODATA_TT_##TT))
+     169             : 
+     170             : #define O_FPU(PREFIX, OPCODE, O) (ODATA_FPU_##PREFIX | (0x##OPCODE & 0xFFU) | ((0x##OPCODE >> 8) << X86Inst::kOpCode_FPU_2B_Shift) | ODATA_O_##O)
+     171             : 
+     172             : // Don't store `_nameDataIndex` if instruction names are disabled. Since some
+     173             : // APIs can use `_nameDataIndex` it's much safer if it's zero if it's not used.
+     174             : #if defined(ASMJIT_DISABLE_TEXT)
+     175             : # define NAME_DATA_INDEX(X) 0
+     176             : #else
+     177             : # define NAME_DATA_INDEX(X) X
+     178             : #endif
+     179             : 
+     180             : // Defines an X86/X64 instruction.
+     181             : #define INST(id, encoding, opcode0, opcode1, writeIndex, writeSize, nameDataIndex, commonDataIndex, operationDataIndex, seeToAvxDataIndex) { \
+     182             :   uint32_t(X86Inst::kEncoding##encoding),   \
+     183             :   uint32_t(NAME_DATA_INDEX(nameDataIndex)), \
+     184             :   uint32_t(commonDataIndex),                \
+     185             :   uint32_t(operationDataIndex),             \
+     186             :   uint32_t(seeToAvxDataIndex),              \
+     187             :   0,                                        \
+     188             :   opcode0                                   \
+     189             : }
+     190             : const X86Inst X86InstDB::instData[] = {
+     191             :   // <-----------------+--------------------+------------------+--------+------------------+--------+-------+-----+----+----+---+
+     192             :   //                   |                    |    Main OpCode   |#0 EVEX |Alternative OpCode|#1 EVEX | Write |     |    |    |Sse|
+     193             :   //    Instruction    |   Inst. Encoding   |                  +--------+                  +--------+---+---+NameX|ComX|OpnX|<->|
+     194             :   //                   |                    |#0:PP-MMM OP/O L|W|W|N|TT. |#1:PP-MMM OP/O L|W|W|N|TT. |Idx|Cnt|     |    |    |Avx|
+     195             :   // <-----------------+--------------------+------------------+--------+------------------+--------+---+---+-----+----+----+---+
+     196             :   // ${instData:Begin}
+     197             :   INST(None            , None               , 0                         , 0                         , 0 , 0 , 0   , 0  , 0  , 0 ),
+     198             :   INST(Aaa             , X86Op_xAX          , O(000000,37,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1   , 1  , 1  , 0 ),
+     199             :   INST(Aad             , X86I_xAX           , O(000000,D5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5   , 2  , 1  , 0 ),
+     200             :   INST(Aam             , X86I_xAX           , O(000000,D4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9   , 2  , 1  , 0 ),
+     201             :   INST(Aas             , X86Op_xAX          , O(000000,3F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 13  , 1  , 1  , 0 ),
+     202             :   INST(Adc             , X86Arith           , O(000000,10,2,_,x,_,_,_  ), 0                         , 0 , 0 , 17  , 3  , 2  , 0 ),
+     203             :   INST(Adcx            , X86Rm              , O(660F38,F6,_,_,x,_,_,_  ), 0                         , 0 , 0 , 21  , 4  , 3  , 0 ),
+     204             :   INST(Add             , X86Arith           , O(000000,00,0,_,x,_,_,_  ), 0                         , 0 , 0 , 732 , 3  , 1  , 0 ),
+     205             :   INST(Addpd           , ExtRm              , O(660F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4619, 5  , 4  , 1 ),
+     206             :   INST(Addps           , ExtRm              , O(000F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4631, 5  , 5  , 1 ),
+     207             :   INST(Addsd           , ExtRm              , O(F20F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4853, 6  , 4  , 1 ),
+     208             :   INST(Addss           , ExtRm              , O(F30F00,58,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4863, 7  , 5  , 1 ),
+     209             :   INST(Addsubpd        , ExtRm              , O(660F00,D0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4358, 5  , 6  , 1 ),
+     210             :   INST(Addsubps        , ExtRm              , O(F20F00,D0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4370, 5  , 6  , 1 ),
+     211             :   INST(Adox            , X86Rm              , O(F30F38,F6,_,_,x,_,_,_  ), 0                         , 0 , 0 , 26  , 4  , 7  , 0 ),
+     212             :   INST(Aesdec          , ExtRm              , O(660F38,DE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2854, 5  , 8  , 2 ),
+     213             :   INST(Aesdeclast      , ExtRm              , O(660F38,DF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2862, 5  , 8  , 2 ),
+     214             :   INST(Aesenc          , ExtRm              , O(660F38,DC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2874, 5  , 8  , 2 ),
+     215             :   INST(Aesenclast      , ExtRm              , O(660F38,DD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2882, 5  , 8  , 2 ),
+     216             :   INST(Aesimc          , ExtRm              , O(660F38,DB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2894, 8  , 8  , 3 ),
+     217             :   INST(Aeskeygenassist , ExtRmi             , O(660F3A,DF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2902, 9  , 8  , 3 ),
+     218             :   INST(And             , X86Arith           , O(000000,20,4,_,x,_,_,_  ), 0                         , 0 , 0 , 2317, 10 , 1  , 0 ),
+     219             :   INST(Andn            , VexRvm_Wx          , V(000F38,F2,_,0,x,_,_,_  ), 0                         , 0 , 0 , 6150, 11 , 9  , 0 ),
+     220             :   INST(Andnpd          , ExtRm              , O(660F00,55,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2935, 5  , 4  , 2 ),
+     221             :   INST(Andnps          , ExtRm              , O(000F00,55,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2943, 5  , 5  , 2 ),
+     222             :   INST(Andpd           , ExtRm              , O(660F00,54,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3872, 12 , 4  , 2 ),
+     223             :   INST(Andps           , ExtRm              , O(000F00,54,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3882, 12 , 5  , 2 ),
+     224             :   INST(Arpl            , X86Mr_NoSize       , O(000000,63,_,_,_,_,_,_  ), 0                         , 0 , 0 , 31  , 13 , 10 , 0 ),
+     225             :   INST(Bextr           , VexRmv_Wx          , V(000F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 36  , 14 , 9  , 0 ),
+     226             :   INST(Blcfill         , VexVm_Wx           , V(XOP_M9,01,1,0,x,_,_,_  ), 0                         , 0 , 0 , 42  , 15 , 11 , 0 ),
+     227             :   INST(Blci            , VexVm_Wx           , V(XOP_M9,02,6,0,x,_,_,_  ), 0                         , 0 , 0 , 50  , 15 , 11 , 0 ),
+     228             :   INST(Blcic           , VexVm_Wx           , V(XOP_M9,01,5,0,x,_,_,_  ), 0                         , 0 , 0 , 55  , 15 , 11 , 0 ),
+     229             :   INST(Blcmsk          , VexVm_Wx           , V(XOP_M9,02,1,0,x,_,_,_  ), 0                         , 0 , 0 , 61  , 15 , 11 , 0 ),
+     230             :   INST(Blcs            , VexVm_Wx           , V(XOP_M9,01,3,0,x,_,_,_  ), 0                         , 0 , 0 , 68  , 15 , 11 , 0 ),
+     231             :   INST(Blendpd         , ExtRmi             , O(660F3A,0D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3021, 16 , 12 , 4 ),
+     232             :   INST(Blendps         , ExtRmi             , O(660F3A,0C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3030, 16 , 12 , 4 ),
+     233             :   INST(Blendvpd        , ExtRm_XMM0         , O(660F38,15,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3039, 17 , 12 , 5 ),
+     234             :   INST(Blendvps        , ExtRm_XMM0         , O(660F38,14,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3049, 17 , 12 , 5 ),
+     235             :   INST(Blsfill         , VexVm_Wx           , V(XOP_M9,01,2,0,x,_,_,_  ), 0                         , 0 , 0 , 73  , 15 , 11 , 0 ),
+     236             :   INST(Blsi            , VexVm_Wx           , V(000F38,F3,3,0,x,_,_,_  ), 0                         , 0 , 0 , 81  , 15 , 9  , 0 ),
+     237             :   INST(Blsic           , VexVm_Wx           , V(XOP_M9,01,6,0,x,_,_,_  ), 0                         , 0 , 0 , 86  , 15 , 11 , 0 ),
+     238             :   INST(Blsmsk          , VexVm_Wx           , V(000F38,F3,2,0,x,_,_,_  ), 0                         , 0 , 0 , 92  , 15 , 9  , 0 ),
+     239             :   INST(Blsr            , VexVm_Wx           , V(000F38,F3,1,0,x,_,_,_  ), 0                         , 0 , 0 , 99  , 15 , 9  , 0 ),
+     240             :   INST(Bndcl           , X86Rm              , O(F30F00,1A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 104 , 18 , 13 , 0 ),
+     241             :   INST(Bndcn           , X86Rm              , O(F20F00,1B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 110 , 18 , 13 , 0 ),
+     242             :   INST(Bndcu           , X86Rm              , O(F20F00,1A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 116 , 18 , 13 , 0 ),
+     243             :   INST(Bndldx          , X86Rm              , O(000F00,1A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 122 , 19 , 13 , 0 ),
+     244             :   INST(Bndmk           , X86Rm              , O(F30F00,1B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 129 , 20 , 13 , 0 ),
+     245             :   INST(Bndmov          , X86Bndmov          , O(660F00,1A,_,_,_,_,_,_  ), O(660F00,1B,_,_,_,_,_,_  ), 0 , 0 , 135 , 21 , 13 , 0 ),
+     246             :   INST(Bndstx          , X86Mr              , O(000F00,1B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 142 , 22 , 13 , 0 ),
+     247             :   INST(Bound           , X86Rm              , O(000000,62,_,_,_,_,_,_  ), 0                         , 0 , 0 , 149 , 23 , 0  , 0 ),
+     248             :   INST(Bsf             , X86Rm              , O(000F00,BC,_,_,x,_,_,_  ), 0                         , 0 , 0 , 155 , 24 , 1  , 0 ),
+     249             :   INST(Bsr             , X86Rm              , O(000F00,BD,_,_,x,_,_,_  ), 0                         , 0 , 0 , 159 , 24 , 1  , 0 ),
+     250             :   INST(Bswap           , X86Bswap           , O(000F00,C8,_,_,x,_,_,_  ), 0                         , 0 , 0 , 163 , 25 , 0  , 0 ),
+     251             :   INST(Bt              , X86Bt              , O(000F00,A3,_,_,x,_,_,_  ), O(000F00,BA,4,_,x,_,_,_  ), 0 , 0 , 169 , 26 , 14 , 0 ),
+     252             :   INST(Btc             , X86Bt              , O(000F00,BB,_,_,x,_,_,_  ), O(000F00,BA,7,_,x,_,_,_  ), 0 , 0 , 172 , 27 , 14 , 0 ),
+     253             :   INST(Btr             , X86Bt              , O(000F00,B3,_,_,x,_,_,_  ), O(000F00,BA,6,_,x,_,_,_  ), 0 , 0 , 176 , 28 , 14 , 0 ),
+     254             :   INST(Bts             , X86Bt              , O(000F00,AB,_,_,x,_,_,_  ), O(000F00,BA,5,_,x,_,_,_  ), 0 , 0 , 180 , 29 , 14 , 0 ),
+     255             :   INST(Bzhi            , VexRmv_Wx          , V(000F38,F5,_,0,x,_,_,_  ), 0                         , 0 , 0 , 184 , 14 , 15 , 0 ),
+     256             :   INST(Call            , X86Call            , O(000000,FF,2,_,_,_,_,_  ), 0                         , 0 , 0 , 2713, 30 , 16 , 0 ),
+     257             :   INST(Cbw             , X86Op_xAX          , O(660000,98,_,_,_,_,_,_  ), 0                         , 0 , 0 , 189 , 31 , 0  , 0 ),
+     258             :   INST(Cdq             , X86Op_xDX_xAX      , O(000000,99,_,_,_,_,_,_  ), 0                         , 0 , 0 , 193 , 32 , 0  , 0 ),
+     259             :   INST(Cdqe            , X86Op_xAX          , O(000000,98,_,_,1,_,_,_  ), 0                         , 0 , 0 , 197 , 33 , 0  , 0 ),
+     260             :   INST(Clac            , X86Op              , O(000F01,CA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 202 , 34 , 17 , 0 ),
+     261             :   INST(Clc             , X86Op              , O(000000,F8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 207 , 34 , 18 , 0 ),
+     262             :   INST(Cld             , X86Op              , O(000000,FC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 211 , 34 , 19 , 0 ),
+     263             :   INST(Clflush         , X86M_Only          , O(000F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 215 , 35 , 20 , 0 ),
+     264             :   INST(Clflushopt      , X86M_Only          , O(660F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 223 , 35 , 21 , 0 ),
+     265             :   INST(Cli             , X86Op              , O(000000,FA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 234 , 34 , 22 , 0 ),
+     266             :   INST(Clts            , X86Op              , O(000F00,06,_,_,_,_,_,_  ), 0                         , 0 , 0 , 238 , 34 , 23 , 0 ),
+     267             :   INST(Clwb            , X86M_Only          , O(660F00,AE,6,_,_,_,_,_  ), 0                         , 0 , 0 , 243 , 35 , 24 , 0 ),
+     268             :   INST(Clzero          , X86Op_ZAX          , O(000F01,FC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 248 , 36 , 25 , 0 ),
+     269             :   INST(Cmc             , X86Op              , O(000000,F5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 255 , 34 , 26 , 0 ),
+     270             :   INST(Cmova           , X86Rm              , O(000F00,47,_,_,x,_,_,_  ), 0                         , 0 , 0 , 259 , 24 , 27 , 0 ),
+     271             :   INST(Cmovae          , X86Rm              , O(000F00,43,_,_,x,_,_,_  ), 0                         , 0 , 0 , 265 , 24 , 28 , 0 ),
+     272             :   INST(Cmovb           , X86Rm              , O(000F00,42,_,_,x,_,_,_  ), 0                         , 0 , 0 , 589 , 24 , 28 , 0 ),
+     273             :   INST(Cmovbe          , X86Rm              , O(000F00,46,_,_,x,_,_,_  ), 0                         , 0 , 0 , 596 , 24 , 27 , 0 ),
+     274             :   INST(Cmovc           , X86Rm              , O(000F00,42,_,_,x,_,_,_  ), 0                         , 0 , 0 , 272 , 24 , 28 , 0 ),
+     275             :   INST(Cmove           , X86Rm              , O(000F00,44,_,_,x,_,_,_  ), 0                         , 0 , 0 , 604 , 24 , 29 , 0 ),
+     276             :   INST(Cmovg           , X86Rm              , O(000F00,4F,_,_,x,_,_,_  ), 0                         , 0 , 0 , 278 , 24 , 30 , 0 ),
+     277             :   INST(Cmovge          , X86Rm              , O(000F00,4D,_,_,x,_,_,_  ), 0                         , 0 , 0 , 284 , 24 , 31 , 0 ),
+     278             :   INST(Cmovl           , X86Rm              , O(000F00,4C,_,_,x,_,_,_  ), 0                         , 0 , 0 , 291 , 24 , 31 , 0 ),
+     279             :   INST(Cmovle          , X86Rm              , O(000F00,4E,_,_,x,_,_,_  ), 0                         , 0 , 0 , 297 , 24 , 30 , 0 ),
+     280             :   INST(Cmovna          , X86Rm              , O(000F00,46,_,_,x,_,_,_  ), 0                         , 0 , 0 , 304 , 24 , 27 , 0 ),
+     281             :   INST(Cmovnae         , X86Rm              , O(000F00,42,_,_,x,_,_,_  ), 0                         , 0 , 0 , 311 , 24 , 28 , 0 ),
+     282             :   INST(Cmovnb          , X86Rm              , O(000F00,43,_,_,x,_,_,_  ), 0                         , 0 , 0 , 611 , 24 , 28 , 0 ),
+     283             :   INST(Cmovnbe         , X86Rm              , O(000F00,47,_,_,x,_,_,_  ), 0                         , 0 , 0 , 619 , 24 , 27 , 0 ),
+     284             :   INST(Cmovnc          , X86Rm              , O(000F00,43,_,_,x,_,_,_  ), 0                         , 0 , 0 , 319 , 24 , 28 , 0 ),
+     285             :   INST(Cmovne          , X86Rm              , O(000F00,45,_,_,x,_,_,_  ), 0                         , 0 , 0 , 628 , 24 , 29 , 0 ),
+     286             :   INST(Cmovng          , X86Rm              , O(000F00,4E,_,_,x,_,_,_  ), 0                         , 0 , 0 , 326 , 24 , 30 , 0 ),
+     287             :   INST(Cmovnge         , X86Rm              , O(000F00,4C,_,_,x,_,_,_  ), 0                         , 0 , 0 , 333 , 24 , 31 , 0 ),
+     288             :   INST(Cmovnl          , X86Rm              , O(000F00,4D,_,_,x,_,_,_  ), 0                         , 0 , 0 , 341 , 24 , 31 , 0 ),
+     289             :   INST(Cmovnle         , X86Rm              , O(000F00,4F,_,_,x,_,_,_  ), 0                         , 0 , 0 , 348 , 24 , 30 , 0 ),
+     290             :   INST(Cmovno          , X86Rm              , O(000F00,41,_,_,x,_,_,_  ), 0                         , 0 , 0 , 356 , 24 , 32 , 0 ),
+     291             :   INST(Cmovnp          , X86Rm              , O(000F00,4B,_,_,x,_,_,_  ), 0                         , 0 , 0 , 363 , 24 , 33 , 0 ),
+     292             :   INST(Cmovns          , X86Rm              , O(000F00,49,_,_,x,_,_,_  ), 0                         , 0 , 0 , 370 , 24 , 34 , 0 ),
+     293             :   INST(Cmovnz          , X86Rm              , O(000F00,45,_,_,x,_,_,_  ), 0                         , 0 , 0 , 377 , 24 , 29 , 0 ),
+     294             :   INST(Cmovo           , X86Rm              , O(000F00,40,_,_,x,_,_,_  ), 0                         , 0 , 0 , 384 , 24 , 32 , 0 ),
+     295             :   INST(Cmovp           , X86Rm              , O(000F00,4A,_,_,x,_,_,_  ), 0                         , 0 , 0 , 390 , 24 , 33 , 0 ),
+     296             :   INST(Cmovpe          , X86Rm              , O(000F00,4A,_,_,x,_,_,_  ), 0                         , 0 , 0 , 396 , 24 , 33 , 0 ),
+     297             :   INST(Cmovpo          , X86Rm              , O(000F00,4B,_,_,x,_,_,_  ), 0                         , 0 , 0 , 403 , 24 , 33 , 0 ),
+     298             :   INST(Cmovs           , X86Rm              , O(000F00,48,_,_,x,_,_,_  ), 0                         , 0 , 0 , 410 , 24 , 34 , 0 ),
+     299             :   INST(Cmovz           , X86Rm              , O(000F00,44,_,_,x,_,_,_  ), 0                         , 0 , 0 , 416 , 24 , 29 , 0 ),
+     300             :   INST(Cmp             , X86Arith           , O(000000,38,7,_,x,_,_,_  ), 0                         , 0 , 0 , 422 , 37 , 1  , 0 ),
+     301             :   INST(Cmppd           , ExtRmi             , O(660F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3275, 16 , 4  , 6 ),
+     302             :   INST(Cmpps           , ExtRmi             , O(000F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3282, 16 , 5  , 6 ),
+     303             :   INST(Cmps            , X86StrMm           , O(000000,A6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 426 , 38 , 35 , 0 ),
+     304             :   INST(Cmpsd           , ExtRmi             , O(F20F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3289, 39 , 4  , 7 ),
+     305             :   INST(Cmpss           , ExtRmi             , O(F30F00,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3296, 40 , 5  , 7 ),
+     306             :   INST(Cmpxchg         , X86Cmpxchg         , O(000F00,B0,_,_,x,_,_,_  ), 0                         , 0 , 0 , 431 , 41 , 36 , 0 ),
+     307             :   INST(Cmpxchg16b      , X86M_Only          , O(000F00,C7,1,_,1,_,_,_  ), 0                         , 0 , 0 , 439 , 42 , 37 , 0 ),
+     308             :   INST(Cmpxchg8b       , X86M_Only          , O(000F00,C7,1,_,_,_,_,_  ), 0                         , 0 , 0 , 450 , 43 , 38 , 0 ),
+     309             :   INST(Comisd          , ExtRm              , O(660F00,2F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9371, 44 , 39 , 8 ),
+     310             :   INST(Comiss          , ExtRm              , O(000F00,2F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9380, 45 , 40 , 8 ),
+     311             :   INST(Cpuid           , X86Op              , O(000F00,A2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 460 , 46 , 41 , 0 ),
+     312             :   INST(Cqo             , X86Op_xDX_xAX      , O(000000,99,_,_,1,_,_,_  ), 0                         , 0 , 0 , 466 , 47 , 0  , 0 ),
+     313             :   INST(Crc32           , X86Crc             , O(F20F38,F0,_,_,x,_,_,_  ), 0                         , 0 , 0 , 470 , 48 , 42 , 0 ),
+     314             :   INST(Cvtdq2pd        , ExtRm              , O(F30F00,E6,_,_,_,_,_,_  ), 0                         , 0 , 16, 3343, 49 , 4  , 9 ),
+     315             :   INST(Cvtdq2ps        , ExtRm              , O(000F00,5B,_,_,_,_,_,_  ), 0                         , 0 , 16, 3353, 50 , 4  , 9 ),
+     316             :   INST(Cvtpd2dq        , ExtRm              , O(F20F00,E6,_,_,_,_,_,_  ), 0                         , 0 , 16, 3363, 50 , 4  , 9 ),
+     317             :   INST(Cvtpd2pi        , ExtRm              , O(660F00,2D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 476 , 51 , 4  , 0 ),
+     318             :   INST(Cvtpd2ps        , ExtRm              , O(660F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 16, 3373, 50 , 4  , 10),
+     319             :   INST(Cvtpi2pd        , ExtRm              , O(660F00,2A,_,_,_,_,_,_  ), 0                         , 0 , 16, 485 , 52 , 4  , 0 ),
+     320             :   INST(Cvtpi2ps        , ExtRm              , O(000F00,2A,_,_,_,_,_,_  ), 0                         , 0 , 8 , 494 , 53 , 5  , 0 ),
+     321             :   INST(Cvtps2dq        , ExtRm              , O(660F00,5B,_,_,_,_,_,_  ), 0                         , 0 , 16, 3425, 50 , 4  , 8 ),
+     322             :   INST(Cvtps2pd        , ExtRm              , O(000F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 16, 3435, 49 , 4  , 8 ),
+     323             :   INST(Cvtps2pi        , ExtRm              , O(000F00,2D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 503 , 54 , 5  , 0 ),
+     324             :   INST(Cvtsd2si        , ExtRm_Wx           , O(F20F00,2D,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3507, 55 , 4  , 11),
+     325             :   INST(Cvtsd2ss        , ExtRm              , O(F20F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 4 , 3517, 56 , 4  , 12),
+     326             :   INST(Cvtsi2sd        , ExtRm_Wx           , O(F20F00,2A,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3538, 57 , 4  , 13),
+     327             :   INST(Cvtsi2ss        , ExtRm_Wx           , O(F30F00,2A,_,_,x,_,_,_  ), 0                         , 0 , 4 , 3548, 58 , 5  , 13),
+     328             :   INST(Cvtss2sd        , ExtRm              , O(F30F00,5A,_,_,_,_,_,_  ), 0                         , 0 , 8 , 3558, 59 , 4  , 13),
+     329             :   INST(Cvtss2si        , ExtRm_Wx           , O(F30F00,2D,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3568, 60 , 5  , 14),
+     330             :   INST(Cvttpd2dq       , ExtRm              , O(660F00,E6,_,_,_,_,_,_  ), 0                         , 0 , 16, 3589, 50 , 4  , 15),
+     331             :   INST(Cvttpd2pi       , ExtRm              , O(660F00,2C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 512 , 51 , 4  , 0 ),
+     332             :   INST(Cvttps2dq       , ExtRm              , O(F30F00,5B,_,_,_,_,_,_  ), 0                         , 0 , 16, 3635, 50 , 4  , 16),
+     333             :   INST(Cvttps2pi       , ExtRm              , O(000F00,2C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 522 , 54 , 5  , 0 ),
+     334             :   INST(Cvttsd2si       , ExtRm_Wx           , O(F20F00,2C,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3681, 55 , 4  , 17),
+     335             :   INST(Cvttss2si       , ExtRm_Wx           , O(F30F00,2C,_,_,x,_,_,_  ), 0                         , 0 , 8 , 3704, 60 , 5  , 18),
+     336             :   INST(Cwd             , X86Op_xDX_xAX      , O(660000,99,_,_,_,_,_,_  ), 0                         , 0 , 0 , 532 , 61 , 0  , 0 ),
+     337             :   INST(Cwde            , X86Op_xAX          , O(000000,98,_,_,_,_,_,_  ), 0                         , 0 , 0 , 536 , 62 , 0  , 0 ),
+     338             :   INST(Daa             , X86Op              , O(000000,27,_,_,_,_,_,_  ), 0                         , 0 , 0 , 541 , 1  , 1  , 0 ),
+     339             :   INST(Das             , X86Op              , O(000000,2F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 545 , 1  , 1  , 0 ),
+     340             :   INST(Dec             , X86IncDec          , O(000000,FE,1,_,x,_,_,_  ), O(000000,48,_,_,x,_,_,_  ), 0 , 0 , 2857, 63 , 43 , 0 ),
+     341             :   INST(Div             , X86M_GPB_MulDiv    , O(000000,F6,6,_,x,_,_,_  ), 0                         , 0 , 0 , 751 , 64 , 1  , 0 ),
+     342             :   INST(Divpd           , ExtRm              , O(660F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3803, 5  , 4  , 19),
+     343             :   INST(Divps           , ExtRm              , O(000F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3810, 5  , 5  , 19),
+     344             :   INST(Divsd           , ExtRm              , O(F20F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3817, 6  , 4  , 19),
+     345             :   INST(Divss           , ExtRm              , O(F30F00,5E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3824, 7  , 5  , 19),
+     346             :   INST(Dppd            , ExtRmi             , O(660F3A,41,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3831, 16 , 12 , 19),
+     347             :   INST(Dpps            , ExtRmi             , O(660F3A,40,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3837, 16 , 12 , 19),
+     348             :   INST(Emms            , X86Op              , O(000F00,77,_,_,_,_,_,_  ), 0                         , 0 , 0 , 719 , 65 , 44 , 0 ),
+     349             :   INST(Enter           , X86Enter           , O(000000,C8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2721, 66 , 45 , 0 ),
+     350             :   INST(Extractps       , ExtExtract         , O(660F3A,17,_,_,_,_,_,_  ), 0                         , 0 , 8 , 4027, 67 , 12 , 20),
+     351             :   INST(Extrq           , ExtExtrq           , O(660F00,79,_,_,_,_,_,_  ), O(660F00,78,0,_,_,_,_,_  ), 0 , 0 , 6864, 68 , 46 , 0 ),
+     352             :   INST(F2xm1           , FpuOp              , O_FPU(00,D9F0,_)          , 0                         , 0 , 0 , 549 , 34 , 47 , 0 ),
+     353             :   INST(Fabs            , FpuOp              , O_FPU(00,D9E1,_)          , 0                         , 0 , 0 , 555 , 34 , 47 , 0 ),
+     354             :   INST(Fadd            , FpuArith           , O_FPU(00,C0C0,0)          , 0                         , 0 , 0 , 1957, 69 , 47 , 0 ),
+     355             :   INST(Faddp           , FpuRDef            , O_FPU(00,DEC0,_)          , 0                         , 0 , 0 , 560 , 70 , 47 , 0 ),
+     356             :   INST(Fbld            , X86M_Only          , O_FPU(00,00DF,4)          , 0                         , 0 , 0 , 566 , 71 , 47 , 0 ),
+     357             :   INST(Fbstp           , X86M_Only          , O_FPU(00,00DF,6)          , 0                         , 0 , 0 , 571 , 72 , 47 , 0 ),
+     358             :   INST(Fchs            , FpuOp              , O_FPU(00,D9E0,_)          , 0                         , 0 , 0 , 577 , 34 , 47 , 0 ),
+     359             :   INST(Fclex           , FpuOp              , O_FPU(9B,DBE2,_)          , 0                         , 0 , 0 , 582 , 34 , 47 , 0 ),
+     360             :   INST(Fcmovb          , FpuR               , O_FPU(00,DAC0,_)          , 0                         , 0 , 0 , 588 , 73 , 48 , 0 ),
+     361             :   INST(Fcmovbe         , FpuR               , O_FPU(00,DAD0,_)          , 0                         , 0 , 0 , 595 , 73 , 48 , 0 ),
+     362             :   INST(Fcmove          , FpuR               , O_FPU(00,DAC8,_)          , 0                         , 0 , 0 , 603 , 73 , 48 , 0 ),
+     363             :   INST(Fcmovnb         , FpuR               , O_FPU(00,DBC0,_)          , 0                         , 0 , 0 , 610 , 73 , 48 , 0 ),
+     364             :   INST(Fcmovnbe        , FpuR               , O_FPU(00,DBD0,_)          , 0                         , 0 , 0 , 618 , 73 , 48 , 0 ),
+     365             :   INST(Fcmovne         , FpuR               , O_FPU(00,DBC8,_)          , 0                         , 0 , 0 , 627 , 73 , 48 , 0 ),
+     366             :   INST(Fcmovnu         , FpuR               , O_FPU(00,DBD8,_)          , 0                         , 0 , 0 , 635 , 73 , 48 , 0 ),
+     367             :   INST(Fcmovu          , FpuR               , O_FPU(00,DAD8,_)          , 0                         , 0 , 0 , 643 , 73 , 48 , 0 ),
+     368             :   INST(Fcom            , FpuCom             , O_FPU(00,D0D0,2)          , 0                         , 0 , 0 , 650 , 74 , 47 , 0 ),
+     369             :   INST(Fcomi           , FpuR               , O_FPU(00,DBF0,_)          , 0                         , 0 , 0 , 655 , 75 , 49 , 0 ),
+     370             :   INST(Fcomip          , FpuR               , O_FPU(00,DFF0,_)          , 0                         , 0 , 0 , 661 , 75 , 49 , 0 ),
+     371             :   INST(Fcomp           , FpuCom             , O_FPU(00,D8D8,3)          , 0                         , 0 , 0 , 668 , 74 , 47 , 0 ),
+     372             :   INST(Fcompp          , FpuOp              , O_FPU(00,DED9,_)          , 0                         , 0 , 0 , 674 , 34 , 47 , 0 ),
+     373             :   INST(Fcos            , FpuOp              , O_FPU(00,D9FF,_)          , 0                         , 0 , 0 , 681 , 34 , 47 , 0 ),
+     374             :   INST(Fdecstp         , FpuOp              , O_FPU(00,D9F6,_)          , 0                         , 0 , 0 , 686 , 34 , 47 , 0 ),
+     375             :   INST(Fdiv            , FpuArith           , O_FPU(00,F0F8,6)          , 0                         , 0 , 0 , 694 , 69 , 47 , 0 ),
+     376             :   INST(Fdivp           , FpuRDef            , O_FPU(00,DEF8,_)          , 0                         , 0 , 0 , 699 , 70 , 47 , 0 ),
+     377             :   INST(Fdivr           , FpuArith           , O_FPU(00,F8F0,7)          , 0                         , 0 , 0 , 705 , 69 , 47 , 0 ),
+     378             :   INST(Fdivrp          , FpuRDef            , O_FPU(00,DEF0,_)          , 0                         , 0 , 0 , 711 , 70 , 47 , 0 ),
+     379             :   INST(Femms           , X86Op              , O(000F00,0E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 718 , 34 , 50 , 0 ),
+     380             :   INST(Ffree           , FpuR               , O_FPU(00,DDC0,_)          , 0                         , 0 , 0 , 724 , 73 , 47 , 0 ),
+     381             :   INST(Fiadd           , FpuM               , O_FPU(00,00DA,0)          , 0                         , 0 , 0 , 730 , 76 , 47 , 0 ),
+     382             :   INST(Ficom           , FpuM               , O_FPU(00,00DA,2)          , 0                         , 0 , 0 , 736 , 76 , 47 , 0 ),
+     383             :   INST(Ficomp          , FpuM               , O_FPU(00,00DA,3)          , 0                         , 0 , 0 , 742 , 76 , 47 , 0 ),
+     384             :   INST(Fidiv           , FpuM               , O_FPU(00,00DA,6)          , 0                         , 0 , 0 , 749 , 76 , 47 , 0 ),
+     385             :   INST(Fidivr          , FpuM               , O_FPU(00,00DA,7)          , 0                         , 0 , 0 , 755 , 76 , 47 , 0 ),
+     386             :   INST(Fild            , FpuM               , O_FPU(00,00DB,0)          , O_FPU(00,00DF,5)          , 0 , 0 , 762 , 77 , 47 , 0 ),
+     387             :   INST(Fimul           , FpuM               , O_FPU(00,00DA,1)          , 0                         , 0 , 0 , 767 , 76 , 47 , 0 ),
+     388             :   INST(Fincstp         , FpuOp              , O_FPU(00,D9F7,_)          , 0                         , 0 , 0 , 773 , 34 , 47 , 0 ),
+     389             :   INST(Finit           , FpuOp              , O_FPU(9B,DBE3,_)          , 0                         , 0 , 0 , 781 , 34 , 47 , 0 ),
+     390             :   INST(Fist            , FpuM               , O_FPU(00,00DB,2)          , 0                         , 0 , 0 , 787 , 78 , 47 , 0 ),
+     391             :   INST(Fistp           , FpuM               , O_FPU(00,00DB,3)          , O_FPU(00,00DF,7)          , 0 , 0 , 792 , 79 , 47 , 0 ),
+     392             :   INST(Fisttp          , FpuM               , O_FPU(00,00DB,1)          , O_FPU(00,00DD,1)          , 0 , 0 , 798 , 80 , 51 , 0 ),
+     393             :   INST(Fisub           , FpuM               , O_FPU(00,00DA,4)          , 0                         , 0 , 0 , 805 , 76 , 47 , 0 ),
+     394             :   INST(Fisubr          , FpuM               , O_FPU(00,00DA,5)          , 0                         , 0 , 0 , 811 , 76 , 47 , 0 ),
+     395             :   INST(Fld             , FpuFldFst          , O_FPU(00,00D9,0)          , O_FPU(00,00DB,5)          , 0 , 0 , 818 , 81 , 47 , 0 ),
+     396             :   INST(Fld1            , FpuOp              , O_FPU(00,D9E8,_)          , 0                         , 0 , 0 , 822 , 34 , 47 , 0 ),
+     397             :   INST(Fldcw           , X86M_Only          , O_FPU(00,00D9,5)          , 0                         , 0 , 0 , 827 , 82 , 47 , 0 ),
+     398             :   INST(Fldenv          , X86M_Only          , O_FPU(00,00D9,4)          , 0                         , 0 , 0 , 833 , 35 , 47 , 0 ),
+     399             :   INST(Fldl2e          , FpuOp              , O_FPU(00,D9EA,_)          , 0                         , 0 , 0 , 840 , 34 , 47 , 0 ),
+     400             :   INST(Fldl2t          , FpuOp              , O_FPU(00,D9E9,_)          , 0                         , 0 , 0 , 847 , 34 , 47 , 0 ),
+     401             :   INST(Fldlg2          , FpuOp              , O_FPU(00,D9EC,_)          , 0                         , 0 , 0 , 854 , 34 , 47 , 0 ),
+     402             :   INST(Fldln2          , FpuOp              , O_FPU(00,D9ED,_)          , 0                         , 0 , 0 , 861 , 34 , 47 , 0 ),
+     403             :   INST(Fldpi           , FpuOp              , O_FPU(00,D9EB,_)          , 0                         , 0 , 0 , 868 , 34 , 47 , 0 ),
+     404             :   INST(Fldz            , FpuOp              , O_FPU(00,D9EE,_)          , 0                         , 0 , 0 , 874 , 34 , 47 , 0 ),
+     405             :   INST(Fmul            , FpuArith           , O_FPU(00,C8C8,1)          , 0                         , 0 , 0 , 1999, 83 , 47 , 0 ),
+     406             :   INST(Fmulp           , FpuRDef            , O_FPU(00,DEC8,_)          , 0                         , 0 , 0 , 879 , 70 , 47 , 0 ),
+     407             :   INST(Fnclex          , FpuOp              , O_FPU(00,DBE2,_)          , 0                         , 0 , 0 , 885 , 34 , 47 , 0 ),
+     408             :   INST(Fninit          , FpuOp              , O_FPU(00,DBE3,_)          , 0                         , 0 , 0 , 892 , 34 , 47 , 0 ),
+     409             :   INST(Fnop            , FpuOp              , O_FPU(00,D9D0,_)          , 0                         , 0 , 0 , 899 , 34 , 47 , 0 ),
+     410             :   INST(Fnsave          , X86M_Only          , O_FPU(00,00DD,6)          , 0                         , 0 , 0 , 904 , 84 , 47 , 0 ),
+     411             :   INST(Fnstcw          , X86M_Only          , O_FPU(00,00D9,7)          , 0                         , 0 , 0 , 911 , 85 , 47 , 0 ),
+     412             :   INST(Fnstenv         , X86M_Only          , O_FPU(00,00D9,6)          , 0                         , 0 , 0 , 918 , 84 , 47 , 0 ),
+     413             :   INST(Fnstsw          , FpuStsw            , O_FPU(00,00DD,7)          , O_FPU(00,DFE0,_)          , 0 , 0 , 926 , 86 , 47 , 0 ),
+     414             :   INST(Fpatan          , FpuOp              , O_FPU(00,D9F3,_)          , 0                         , 0 , 0 , 933 , 34 , 47 , 0 ),
+     415             :   INST(Fprem           , FpuOp              , O_FPU(00,D9F8,_)          , 0                         , 0 , 0 , 940 , 34 , 47 , 0 ),
+     416             :   INST(Fprem1          , FpuOp              , O_FPU(00,D9F5,_)          , 0                         , 0 , 0 , 946 , 34 , 47 , 0 ),
+     417             :   INST(Fptan           , FpuOp              , O_FPU(00,D9F2,_)          , 0                         , 0 , 0 , 953 , 34 , 47 , 0 ),
+     418             :   INST(Frndint         , FpuOp              , O_FPU(00,D9FC,_)          , 0                         , 0 , 0 , 959 , 34 , 47 , 0 ),
+     419             :   INST(Frstor          , X86M_Only          , O_FPU(00,00DD,4)          , 0                         , 0 , 0 , 967 , 35 , 47 , 0 ),
+     420             :   INST(Fsave           , X86M_Only          , O_FPU(9B,00DD,6)          , 0                         , 0 , 0 , 974 , 84 , 47 , 0 ),
+     421             :   INST(Fscale          , FpuOp              , O_FPU(00,D9FD,_)          , 0                         , 0 , 0 , 980 , 34 , 47 , 0 ),
+     422             :   INST(Fsin            , FpuOp              , O_FPU(00,D9FE,_)          , 0                         , 0 , 0 , 987 , 34 , 47 , 0 ),
+     423             :   INST(Fsincos         , FpuOp              , O_FPU(00,D9FB,_)          , 0                         , 0 , 0 , 992 , 34 , 47 , 0 ),
+     424             :   INST(Fsqrt           , FpuOp              , O_FPU(00,D9FA,_)          , 0                         , 0 , 0 , 1000, 34 , 47 , 0 ),
+     425             :   INST(Fst             , FpuFldFst          , O_FPU(00,00D9,2)          , 0                         , 0 , 0 , 1006, 87 , 47 , 0 ),
+     426             :   INST(Fstcw           , X86M_Only          , O_FPU(9B,00D9,7)          , 0                         , 0 , 0 , 1010, 85 , 47 , 0 ),
+     427             :   INST(Fstenv          , X86M_Only          , O_FPU(9B,00D9,6)          , 0                         , 0 , 0 , 1016, 84 , 47 , 0 ),
+     428             :   INST(Fstp            , FpuFldFst          , O_FPU(00,00D9,3)          , O(000000,DB,7,_,_,_,_,_  ), 0 , 0 , 1023, 88 , 47 , 0 ),
+     429             :   INST(Fstsw           , FpuStsw            , O_FPU(9B,00DD,7)          , O_FPU(9B,DFE0,_)          , 0 , 0 , 1028, 89 , 47 , 0 ),
+     430             :   INST(Fsub            , FpuArith           , O_FPU(00,E0E8,4)          , 0                         , 0 , 0 , 2077, 69 , 47 , 0 ),
+     431             :   INST(Fsubp           , FpuRDef            , O_FPU(00,DEE8,_)          , 0                         , 0 , 0 , 1034, 70 , 47 , 0 ),
+     432             :   INST(Fsubr           , FpuArith           , O_FPU(00,E8E0,5)          , 0                         , 0 , 0 , 2083, 69 , 47 , 0 ),
+     433             :   INST(Fsubrp          , FpuRDef            , O_FPU(00,DEE0,_)          , 0                         , 0 , 0 , 1040, 70 , 47 , 0 ),
+     434             :   INST(Ftst            , FpuOp              , O_FPU(00,D9E4,_)          , 0                         , 0 , 0 , 1047, 34 , 47 , 0 ),
+     435             :   INST(Fucom           , FpuRDef            , O_FPU(00,DDE0,_)          , 0                         , 0 , 0 , 1052, 90 , 47 , 0 ),
+     436             :   INST(Fucomi          , FpuR               , O_FPU(00,DBE8,_)          , 0                         , 0 , 0 , 1058, 75 , 49 , 0 ),
+     437             :   INST(Fucomip         , FpuR               , O_FPU(00,DFE8,_)          , 0                         , 0 , 0 , 1065, 75 , 49 , 0 ),
+     438             :   INST(Fucomp          , FpuRDef            , O_FPU(00,DDE8,_)          , 0                         , 0 , 0 , 1073, 90 , 47 , 0 ),
+     439             :   INST(Fucompp         , FpuOp              , O_FPU(00,DAE9,_)          , 0                         , 0 , 0 , 1080, 34 , 47 , 0 ),
+     440             :   INST(Fwait           , X86Op              , O_FPU(00,00DB,_)          , 0                         , 0 , 0 , 1088, 34 , 47 , 0 ),
+     441             :   INST(Fxam            , FpuOp              , O_FPU(00,D9E5,_)          , 0                         , 0 , 0 , 1094, 34 , 47 , 0 ),
+     442             :   INST(Fxch            , FpuR               , O_FPU(00,D9C8,_)          , 0                         , 0 , 0 , 1099, 70 , 47 , 0 ),
+     443             :   INST(Fxrstor         , X86M_Only          , O(000F00,AE,1,_,_,_,_,_  ), 0                         , 0 , 0 , 1104, 35 , 52 , 0 ),
+     444             :   INST(Fxrstor64       , X86M_Only          , O(000F00,AE,1,_,1,_,_,_  ), 0                         , 0 , 0 , 1112, 91 , 52 , 0 ),
+     445             :   INST(Fxsave          , X86M_Only          , O(000F00,AE,0,_,_,_,_,_  ), 0                         , 0 , 0 , 1122, 84 , 53 , 0 ),
+     446             :   INST(Fxsave64        , X86M_Only          , O(000F00,AE,0,_,1,_,_,_  ), 0                         , 0 , 0 , 1129, 92 , 53 , 0 ),
+     447             :   INST(Fxtract         , FpuOp              , O_FPU(00,D9F4,_)          , 0                         , 0 , 0 , 1138, 34 , 47 , 0 ),
+     448             :   INST(Fyl2x           , FpuOp              , O_FPU(00,D9F1,_)          , 0                         , 0 , 0 , 1146, 34 , 47 , 0 ),
+     449             :   INST(Fyl2xp1         , FpuOp              , O_FPU(00,D9F9,_)          , 0                         , 0 , 0 , 1152, 34 , 47 , 0 ),
+     450             :   INST(Haddpd          , ExtRm              , O(660F00,7C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5382, 5  , 6  , 21),
+     451             :   INST(Haddps          , ExtRm              , O(F20F00,7C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5390, 5  , 6  , 21),
+     452             :   INST(Hlt             , X86Op              , O(000000,F4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1160, 34 , 23 , 0 ),
+     453             :   INST(Hsubpd          , ExtRm              , O(660F00,7D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5398, 5  , 6  , 22),
+     454             :   INST(Hsubps          , ExtRm              , O(F20F00,7D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5406, 5  , 6  , 22),
+     455             :   INST(Idiv            , X86M_GPB_MulDiv    , O(000000,F6,7,_,x,_,_,_  ), 0                         , 0 , 0 , 750 , 64 , 1  , 0 ),
+     456             :   INST(Imul            , X86Imul            , O(000000,F6,5,_,x,_,_,_  ), 0                         , 0 , 0 , 768 , 93 , 1  , 0 ),
+     457             :   INST(In              , X86In              , O(000000,EC,_,_,_,_,_,_  ), O(000000,E4,_,_,_,_,_,_  ), 0 , 0 , 9508, 94 , 45 , 0 ),
+     458             :   INST(Inc             , X86IncDec          , O(000000,FE,0,_,x,_,_,_  ), O(000000,40,_,_,x,_,_,_  ), 0 , 0 , 1164, 95 , 43 , 0 ),
+     459             :   INST(Ins             , X86Ins             , O(000000,6C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1168, 96 , 45 , 0 ),
+     460             :   INST(Insertps        , ExtRmi             , O(660F3A,21,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5542, 40 , 12 , 23),
+     461             :   INST(Insertq         , ExtInsertq         , O(F20F00,79,_,_,_,_,_,_  ), O(F20F00,78,_,_,_,_,_,_  ), 0 , 0 , 1172, 97 , 46 , 0 ),
+     462             :   INST(Int             , X86Int             , O(000000,CD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 963 , 98 , 45 , 0 ),
+     463             :   INST(Int3            , X86Op              , O(000000,CC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1180, 34 , 45 , 0 ),
+     464             :   INST(Into            , X86Op              , O(000000,CE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1185, 99 , 54 , 0 ),
+     465             :   INST(Invd            , X86Op              , O(000F00,08,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9463, 34 , 55 , 0 ),
+     466             :   INST(Invlpg          , X86M_Only          , O(000F00,01,7,_,_,_,_,_  ), 0                         , 0 , 0 , 1190, 35 , 55 , 0 ),
+     467             :   INST(Invpcid         , X86Rm_NoRexW       , O(660F38,82,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1197, 100, 55 , 0 ),
+     468             :   INST(Iret            , X86Op              , O(000000,CF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1205, 34 , 16 , 0 ),
+     469             :   INST(Iretd           , X86Op              , O(000000,CF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1210, 34 , 16 , 0 ),
+     470             :   INST(Iretq           , X86Op              , O(000000,CF,_,_,1,_,_,_  ), 0                         , 0 , 0 , 1216, 101, 16 , 0 ),
+     471             :   INST(Iretw           , X86Op              , O(660000,CF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1222, 34 , 16 , 0 ),
+     472             :   INST(Ja              , X86Jcc             , O(000F00,87,_,_,_,_,_,_  ), O(000000,77,_,_,_,_,_,_  ), 0 , 0 , 1228, 102, 56 , 0 ),
+     473             :   INST(Jae             , X86Jcc             , O(000F00,83,_,_,_,_,_,_  ), O(000000,73,_,_,_,_,_,_  ), 0 , 0 , 1231, 103, 57 , 0 ),
+     474             :   INST(Jb              , X86Jcc             , O(000F00,82,_,_,_,_,_,_  ), O(000000,72,_,_,_,_,_,_  ), 0 , 0 , 1235, 104, 57 , 0 ),
+     475             :   INST(Jbe             , X86Jcc             , O(000F00,86,_,_,_,_,_,_  ), O(000000,76,_,_,_,_,_,_  ), 0 , 0 , 1238, 105, 56 , 0 ),
+     476             :   INST(Jc              , X86Jcc             , O(000F00,82,_,_,_,_,_,_  ), O(000000,72,_,_,_,_,_,_  ), 0 , 0 , 1242, 106, 57 , 0 ),
+     477             :   INST(Je              , X86Jcc             , O(000F00,84,_,_,_,_,_,_  ), O(000000,74,_,_,_,_,_,_  ), 0 , 0 , 1245, 107, 58 , 0 ),
+     478             :   INST(Jecxz           , X86JecxzLoop       , 0                         , O(000000,E3,_,_,_,_,_,_  ), 0 , 0 , 1248, 108, 45 , 0 ),
+     479             :   INST(Jg              , X86Jcc             , O(000F00,8F,_,_,_,_,_,_  ), O(000000,7F,_,_,_,_,_,_  ), 0 , 0 , 1254, 109, 59 , 0 ),
+     480             :   INST(Jge             , X86Jcc             , O(000F00,8D,_,_,_,_,_,_  ), O(000000,7D,_,_,_,_,_,_  ), 0 , 0 , 1257, 110, 60 , 0 ),
+     481             :   INST(Jl              , X86Jcc             , O(000F00,8C,_,_,_,_,_,_  ), O(000000,7C,_,_,_,_,_,_  ), 0 , 0 , 1261, 111, 60 , 0 ),
+     482             :   INST(Jle             , X86Jcc             , O(000F00,8E,_,_,_,_,_,_  ), O(000000,7E,_,_,_,_,_,_  ), 0 , 0 , 1264, 112, 59 , 0 ),
+     483             :   INST(Jmp             , X86Jmp             , O(000000,FF,4,_,_,_,_,_  ), O(000000,EB,_,_,_,_,_,_  ), 0 , 0 , 1268, 113, 45 , 0 ),
+     484             :   INST(Jna             , X86Jcc             , O(000F00,86,_,_,_,_,_,_  ), O(000000,76,_,_,_,_,_,_  ), 0 , 0 , 1272, 105, 56 , 0 ),
+     485             :   INST(Jnae            , X86Jcc             , O(000F00,82,_,_,_,_,_,_  ), O(000000,72,_,_,_,_,_,_  ), 0 , 0 , 1276, 104, 57 , 0 ),
+     486             :   INST(Jnb             , X86Jcc             , O(000F00,83,_,_,_,_,_,_  ), O(000000,73,_,_,_,_,_,_  ), 0 , 0 , 1281, 103, 57 , 0 ),
+     487             :   INST(Jnbe            , X86Jcc             , O(000F00,87,_,_,_,_,_,_  ), O(000000,77,_,_,_,_,_,_  ), 0 , 0 , 1285, 102, 56 , 0 ),
+     488             :   INST(Jnc             , X86Jcc             , O(000F00,83,_,_,_,_,_,_  ), O(000000,73,_,_,_,_,_,_  ), 0 , 0 , 1290, 114, 57 , 0 ),
+     489             :   INST(Jne             , X86Jcc             , O(000F00,85,_,_,_,_,_,_  ), O(000000,75,_,_,_,_,_,_  ), 0 , 0 , 1294, 115, 58 , 0 ),
+     490             :   INST(Jng             , X86Jcc             , O(000F00,8E,_,_,_,_,_,_  ), O(000000,7E,_,_,_,_,_,_  ), 0 , 0 , 1298, 112, 59 , 0 ),
+     491             :   INST(Jnge            , X86Jcc             , O(000F00,8C,_,_,_,_,_,_  ), O(000000,7C,_,_,_,_,_,_  ), 0 , 0 , 1302, 111, 60 , 0 ),
+     492             :   INST(Jnl             , X86Jcc             , O(000F00,8D,_,_,_,_,_,_  ), O(000000,7D,_,_,_,_,_,_  ), 0 , 0 , 1307, 110, 60 , 0 ),
+     493             :   INST(Jnle            , X86Jcc             , O(000F00,8F,_,_,_,_,_,_  ), O(000000,7F,_,_,_,_,_,_  ), 0 , 0 , 1311, 109, 59 , 0 ),
+     494             :   INST(Jno             , X86Jcc             , O(000F00,81,_,_,_,_,_,_  ), O(000000,71,_,_,_,_,_,_  ), 0 , 0 , 1316, 116, 54 , 0 ),
+     495             :   INST(Jnp             , X86Jcc             , O(000F00,8B,_,_,_,_,_,_  ), O(000000,7B,_,_,_,_,_,_  ), 0 , 0 , 1320, 117, 61 , 0 ),
+     496             :   INST(Jns             , X86Jcc             , O(000F00,89,_,_,_,_,_,_  ), O(000000,79,_,_,_,_,_,_  ), 0 , 0 , 1324, 118, 62 , 0 ),
+     497             :   INST(Jnz             , X86Jcc             , O(000F00,85,_,_,_,_,_,_  ), O(000000,75,_,_,_,_,_,_  ), 0 , 0 , 1328, 115, 58 , 0 ),
+     498             :   INST(Jo              , X86Jcc             , O(000F00,80,_,_,_,_,_,_  ), O(000000,70,_,_,_,_,_,_  ), 0 , 0 , 1332, 119, 54 , 0 ),
+     499             :   INST(Jp              , X86Jcc             , O(000F00,8A,_,_,_,_,_,_  ), O(000000,7A,_,_,_,_,_,_  ), 0 , 0 , 1335, 120, 61 , 0 ),
+     500             :   INST(Jpe             , X86Jcc             , O(000F00,8A,_,_,_,_,_,_  ), O(000000,7A,_,_,_,_,_,_  ), 0 , 0 , 1338, 120, 61 , 0 ),
+     501             :   INST(Jpo             , X86Jcc             , O(000F00,8B,_,_,_,_,_,_  ), O(000000,7B,_,_,_,_,_,_  ), 0 , 0 , 1342, 117, 61 , 0 ),
+     502             :   INST(Js              , X86Jcc             , O(000F00,88,_,_,_,_,_,_  ), O(000000,78,_,_,_,_,_,_  ), 0 , 0 , 1346, 121, 62 , 0 ),
+     503             :   INST(Jz              , X86Jcc             , O(000F00,84,_,_,_,_,_,_  ), O(000000,74,_,_,_,_,_,_  ), 0 , 0 , 1349, 107, 58 , 0 ),
+     504             :   INST(Kaddb           , VexRvm             , V(660F00,4A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1352, 122, 63 , 0 ),
+     505             :   INST(Kaddd           , VexRvm             , V(660F00,4A,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1358, 122, 64 , 0 ),
+     506             :   INST(Kaddq           , VexRvm             , V(000F00,4A,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1364, 122, 64 , 0 ),
+     507             :   INST(Kaddw           , VexRvm             , V(000F00,4A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1370, 122, 63 , 0 ),
+     508             :   INST(Kandb           , VexRvm             , V(660F00,41,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1376, 122, 63 , 0 ),
+     509             :   INST(Kandd           , VexRvm             , V(660F00,41,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1382, 122, 64 , 0 ),
+     510             :   INST(Kandnb          , VexRvm             , V(660F00,42,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1388, 122, 63 , 0 ),
+     511             :   INST(Kandnd          , VexRvm             , V(660F00,42,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1395, 122, 64 , 0 ),
+     512             :   INST(Kandnq          , VexRvm             , V(000F00,42,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1402, 122, 64 , 0 ),
+     513             :   INST(Kandnw          , VexRvm             , V(000F00,42,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1409, 122, 65 , 0 ),
+     514             :   INST(Kandq           , VexRvm             , V(000F00,41,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1416, 122, 64 , 0 ),
+     515             :   INST(Kandw           , VexRvm             , V(000F00,41,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1422, 122, 65 , 0 ),
+     516             :   INST(Kmovb           , VexKmov            , V(660F00,90,_,0,0,_,_,_  ), V(660F00,92,_,0,0,_,_,_  ), 0 , 0 , 1428, 123, 63 , 0 ),
+     517             :   INST(Kmovd           , VexKmov            , V(660F00,90,_,0,1,_,_,_  ), V(F20F00,92,_,0,0,_,_,_  ), 0 , 0 , 7344, 124, 64 , 0 ),
+     518             :   INST(Kmovq           , VexKmov            , V(000F00,90,_,0,1,_,_,_  ), V(F20F00,92,_,0,1,_,_,_  ), 0 , 0 , 7355, 125, 64 , 0 ),
+     519             :   INST(Kmovw           , VexKmov            , V(000F00,90,_,0,0,_,_,_  ), V(000F00,92,_,0,0,_,_,_  ), 0 , 0 , 1434, 126, 65 , 0 ),
+     520             :   INST(Knotb           , VexRm              , V(660F00,44,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1440, 127, 63 , 0 ),
+     521             :   INST(Knotd           , VexRm              , V(660F00,44,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1446, 127, 64 , 0 ),
+     522             :   INST(Knotq           , VexRm              , V(000F00,44,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1452, 127, 64 , 0 ),
+     523             :   INST(Knotw           , VexRm              , V(000F00,44,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1458, 127, 65 , 0 ),
+     524             :   INST(Korb            , VexRvm             , V(660F00,45,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1464, 122, 63 , 0 ),
+     525             :   INST(Kord            , VexRvm             , V(660F00,45,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1469, 122, 64 , 0 ),
+     526             :   INST(Korq            , VexRvm             , V(000F00,45,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1474, 122, 64 , 0 ),
+     527             :   INST(Kortestb        , VexRm              , V(660F00,98,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1479, 128, 66 , 0 ),
+     528             :   INST(Kortestd        , VexRm              , V(660F00,98,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1488, 128, 67 , 0 ),
+     529             :   INST(Kortestq        , VexRm              , V(000F00,98,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1497, 128, 67 , 0 ),
+     530             :   INST(Kortestw        , VexRm              , V(000F00,98,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1506, 128, 68 , 0 ),
+     531             :   INST(Korw            , VexRvm             , V(000F00,45,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1515, 122, 65 , 0 ),
+     532             :   INST(Kshiftlb        , VexRmi             , V(660F3A,32,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1520, 129, 63 , 0 ),
+     533             :   INST(Kshiftld        , VexRmi             , V(660F3A,33,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1529, 129, 64 , 0 ),
+     534             :   INST(Kshiftlq        , VexRmi             , V(660F3A,33,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1538, 129, 64 , 0 ),
+     535             :   INST(Kshiftlw        , VexRmi             , V(660F3A,32,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1547, 129, 65 , 0 ),
+     536             :   INST(Kshiftrb        , VexRmi             , V(660F3A,30,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1556, 129, 63 , 0 ),
+     537             :   INST(Kshiftrd        , VexRmi             , V(660F3A,31,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1565, 129, 64 , 0 ),
+     538             :   INST(Kshiftrq        , VexRmi             , V(660F3A,31,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1574, 129, 64 , 0 ),
+     539             :   INST(Kshiftrw        , VexRmi             , V(660F3A,30,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1583, 129, 65 , 0 ),
+     540             :   INST(Ktestb          , VexRm              , V(660F00,99,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1592, 128, 66 , 0 ),
+     541             :   INST(Ktestd          , VexRm              , V(660F00,99,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1599, 128, 67 , 0 ),
+     542             :   INST(Ktestq          , VexRm              , V(000F00,99,_,0,1,_,_,_  ), 0                         , 0 , 0 , 1606, 128, 67 , 0 ),
+     543             :   INST(Ktestw          , VexRm              , V(000F00,99,_,0,0,_,_,_  ), 0                         , 0 , 0 , 1613, 128, 66 , 0 ),
+     544             :   INST(Kunpckbw        , VexRvm             , V(660F00,4B,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1620, 122, 65 , 0 ),
+     545             :   INST(Kunpckdq        , VexRvm             , V(000F00,4B,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1629, 122, 64 , 0 ),
+     546             :   INST(Kunpckwd        , VexRvm             , V(000F00,4B,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1638, 122, 64 , 0 ),
+     547             :   INST(Kxnorb          , VexRvm             , V(660F00,46,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1647, 122, 63 , 0 ),
+     548             :   INST(Kxnord          , VexRvm             , V(660F00,46,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1654, 122, 64 , 0 ),
+     549             :   INST(Kxnorq          , VexRvm             , V(000F00,46,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1661, 122, 64 , 0 ),
+     550             :   INST(Kxnorw          , VexRvm             , V(000F00,46,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1668, 122, 65 , 0 ),
+     551             :   INST(Kxorb           , VexRvm             , V(660F00,47,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1675, 122, 63 , 0 ),
+     552             :   INST(Kxord           , VexRvm             , V(660F00,47,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1681, 122, 64 , 0 ),
+     553             :   INST(Kxorq           , VexRvm             , V(000F00,47,_,1,1,_,_,_  ), 0                         , 0 , 0 , 1687, 122, 64 , 0 ),
+     554             :   INST(Kxorw           , VexRvm             , V(000F00,47,_,1,0,_,_,_  ), 0                         , 0 , 0 , 1693, 122, 65 , 0 ),
+     555             :   INST(Lahf            , X86Op              , O(000000,9F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1699, 130, 69 , 0 ),
+     556             :   INST(Lar             , X86Rm              , O(000F00,02,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1704, 131, 70 , 0 ),
+     557             :   INST(Lddqu           , ExtRm              , O(F20F00,F0,_,_,_,_,_,_  ), 0                         , 0 , 16, 5552, 132, 6  , 24),
+     558             :   INST(Ldmxcsr         , X86M_Only          , O(000F00,AE,2,_,_,_,_,_  ), 0                         , 0 , 0 , 5559, 133, 5  , 0 ),
+     559             :   INST(Lds             , X86Rm              , O(000000,C5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1708, 134, 45 , 0 ),
+     560             :   INST(Lea             , X86Lea             , O(000000,8D,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1712, 135, 0  , 0 ),
+     561             :   INST(Leave           , X86Op              , O(000000,C9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1716, 34 , 45 , 0 ),
+     562             :   INST(Les             , X86Rm              , O(000000,C4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1722, 134, 45 , 0 ),
+     563             :   INST(Lfence          , X86Fence           , O(000F00,AE,5,_,_,_,_,_  ), 0                         , 0 , 0 , 1726, 34 , 71 , 0 ),
+     564             :   INST(Lfs             , X86Rm              , O(000F00,B4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1733, 136, 45 , 0 ),
+     565             :   INST(Lgdt            , X86M_Only          , O(000F00,01,2,_,_,_,_,_  ), 0                         , 0 , 0 , 1737, 35 , 23 , 0 ),
+     566             :   INST(Lgs             , X86Rm              , O(000F00,B5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1742, 136, 45 , 0 ),
+     567             :   INST(Lidt            , X86M_Only          , O(000F00,01,3,_,_,_,_,_  ), 0                         , 0 , 0 , 1746, 35 , 23 , 0 ),
+     568             :   INST(Lldt            , X86M               , O(000F00,00,2,_,_,_,_,_  ), 0                         , 0 , 0 , 1751, 137, 23 , 0 ),
+     569             :   INST(Lmsw            , X86M               , O(000F00,01,6,_,_,_,_,_  ), 0                         , 0 , 0 , 1756, 137, 23 , 0 ),
+     570             :   INST(Lods            , X86StrRm           , O(000000,AC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1761, 138, 72 , 0 ),
+     571             :   INST(Loop            , X86JecxzLoop       , 0                         , O(000000,E2,_,_,_,_,_,_  ), 0 , 0 , 1766, 139, 45 , 0 ),
+     572             :   INST(Loope           , X86JecxzLoop       , 0                         , O(000000,E1,_,_,_,_,_,_  ), 0 , 0 , 1771, 140, 58 , 0 ),
+     573             :   INST(Loopne          , X86JecxzLoop       , 0                         , O(000000,E0,_,_,_,_,_,_  ), 0 , 0 , 1777, 141, 58 , 0 ),
+     574             :   INST(Lsl             , X86Rm              , O(000F00,03,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1784, 142, 70 , 0 ),
+     575             :   INST(Lss             , X86Rm              , O(000F00,B2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5959, 136, 45 , 0 ),
+     576             :   INST(Ltr             , X86M               , O(000F00,00,3,_,_,_,_,_  ), 0                         , 0 , 0 , 1788, 137, 23 , 0 ),
+     577             :   INST(Lzcnt           , X86Rm_Raw66H       , O(F30F00,BD,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1792, 143, 73 , 0 ),
+     578             :   INST(Maskmovdqu      , ExtRm_ZDI          , O(660F00,57,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5568, 144, 4  , 25),
+     579             :   INST(Maskmovq        , ExtRm_ZDI          , O(000F00,F7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7352, 145, 74 , 0 ),
+     580             :   INST(Maxpd           , ExtRm              , O(660F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5602, 5  , 4  , 26),
+     581             :   INST(Maxps           , ExtRm              , O(000F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5609, 5  , 5  , 26),
+     582             :   INST(Maxsd           , ExtRm              , O(F20F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7371, 6  , 4  , 26),
+     583             :   INST(Maxss           , ExtRm              , O(F30F00,5F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5623, 7  , 5  , 26),
+     584             :   INST(Mfence          , X86Fence           , O(000F00,AE,6,_,_,_,_,_  ), 0                         , 0 , 0 , 1798, 34 , 71 , 0 ),
+     585             :   INST(Minpd           , ExtRm              , O(660F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5630, 5  , 4  , 27),
+     586             :   INST(Minps           , ExtRm              , O(000F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5637, 5  , 5  , 27),
+     587             :   INST(Minsd           , ExtRm              , O(F20F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7435, 6  , 4  , 27),
+     588             :   INST(Minss           , ExtRm              , O(F30F00,5D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5651, 7  , 5  , 27),
+     589             :   INST(Monitor         , X86Op              , O(000F01,C8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1805, 146, 75 , 0 ),
+     590             :   INST(Mov             , X86Mov             , 0                         , 0                         , 0 , 0 , 138 , 147, 76 , 0 ),
+     591             :   INST(Movapd          , ExtMov             , O(660F00,28,_,_,_,_,_,_  ), O(660F00,29,_,_,_,_,_,_  ), 0 , 16, 5658, 148, 4  , 28),
+     592             :   INST(Movaps          , ExtMov             , O(000F00,28,_,_,_,_,_,_  ), O(000F00,29,_,_,_,_,_,_  ), 0 , 16, 5666, 149, 5  , 28),
+     593             :   INST(Movbe           , ExtMovbe           , O(000F38,F0,_,_,x,_,_,_  ), O(000F38,F1,_,_,x,_,_,_  ), 0 , 0 , 597 , 150, 77 , 0 ),
+     594             :   INST(Movd            , ExtMovd            , O(000F00,6E,_,_,_,_,_,_  ), O(000F00,7E,_,_,_,_,_,_  ), 0 , 16, 7345, 151, 78 , 29),
+     595             :   INST(Movddup         , ExtMov             , O(F20F00,12,_,_,_,_,_,_  ), 0                         , 0 , 16, 5680, 49 , 6  , 29),
+     596             :   INST(Movdq2q         , ExtMov             , O(F20F00,D6,_,_,_,_,_,_  ), 0                         , 0 , 8 , 1813, 152, 4  , 0 ),
+     597             :   INST(Movdqa          , ExtMov             , O(660F00,6F,_,_,_,_,_,_  ), O(660F00,7F,_,_,_,_,_,_  ), 0 , 16, 5689, 153, 4  , 30),
+     598             :   INST(Movdqu          , ExtMov             , O(F30F00,6F,_,_,_,_,_,_  ), O(F30F00,7F,_,_,_,_,_,_  ), 0 , 16, 5572, 154, 4  , 28),
+     599             :   INST(Movhlps         , ExtMov             , O(000F00,12,_,_,_,_,_,_  ), 0                         , 0 , 8 , 5764, 155, 5  , 31),
+     600             :   INST(Movhpd          , ExtMov             , O(660F00,16,_,_,_,_,_,_  ), O(660F00,17,_,_,_,_,_,_  ), 8 , 8 , 5773, 156, 4  , 32),
+     601             :   INST(Movhps          , ExtMov             , O(000F00,16,_,_,_,_,_,_  ), O(000F00,17,_,_,_,_,_,_  ), 8 , 8 , 5781, 157, 5  , 32),
+     602             :   INST(Movlhps         , ExtMov             , O(000F00,16,_,_,_,_,_,_  ), 0                         , 8 , 8 , 5789, 158, 5  , 31),
+     603             :   INST(Movlpd          , ExtMov             , O(660F00,12,_,_,_,_,_,_  ), O(660F00,13,_,_,_,_,_,_  ), 0 , 8 , 5798, 159, 4  , 32),
+     604             :   INST(Movlps          , ExtMov             , O(000F00,12,_,_,_,_,_,_  ), O(000F00,13,_,_,_,_,_,_  ), 0 , 8 , 5806, 160, 5  , 32),
+     605             :   INST(Movmskpd        , ExtMov             , O(660F00,50,_,_,_,_,_,_  ), 0                         , 0 , 8 , 5814, 161, 4  , 33),
+     606             :   INST(Movmskps        , ExtMov             , O(000F00,50,_,_,_,_,_,_  ), 0                         , 0 , 8 , 5824, 161, 5  , 33),
+     607             :   INST(Movntdq         , ExtMov             , 0                         , O(660F00,E7,_,_,_,_,_,_  ), 0 , 16, 5834, 162, 4  , 33),
+     608             :   INST(Movntdqa        , ExtMov             , O(660F38,2A,_,_,_,_,_,_  ), 0                         , 0 , 16, 5843, 132, 12 , 33),
+     609             :   INST(Movnti          , ExtMovnti          , O(000F00,C3,_,_,x,_,_,_  ), 0                         , 0 , 8 , 1821, 163, 4  , 0 ),
+     610             :   INST(Movntpd         , ExtMov             , 0                         , O(660F00,2B,_,_,_,_,_,_  ), 0 , 16, 5853, 164, 4  , 34),
+     611             :   INST(Movntps         , ExtMov             , 0                         , O(000F00,2B,_,_,_,_,_,_  ), 0 , 16, 5862, 165, 5  , 34),
+     612             :   INST(Movntq          , ExtMov             , 0                         , O(000F00,E7,_,_,_,_,_,_  ), 0 , 8 , 1828, 166, 74 , 0 ),
+     613             :   INST(Movntsd         , ExtMov             , 0                         , O(F20F00,2B,_,_,_,_,_,_  ), 0 , 8 , 1835, 167, 46 , 0 ),
+     614             :   INST(Movntss         , ExtMov             , 0                         , O(F30F00,2B,_,_,_,_,_,_  ), 0 , 4 , 1843, 168, 46 , 0 ),
+     615             :   INST(Movq            , ExtMovq            , O(000F00,6E,_,_,x,_,_,_  ), O(000F00,7E,_,_,x,_,_,_  ), 0 , 16, 7356, 169, 78 , 28),
+     616             :   INST(Movq2dq         , ExtRm              , O(F30F00,D6,_,_,_,_,_,_  ), 0                         , 0 , 16, 1851, 170, 4  , 0 ),
+     617             :   INST(Movs            , X86StrMm           , O(000000,A4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 411 , 171, 72 , 0 ),
+     618             :   INST(Movsd           , ExtMov             , O(F20F00,10,_,_,_,_,_,_  ), O(F20F00,11,_,_,_,_,_,_  ), 0 , 8 , 5877, 172, 79 , 35),
+     619             :   INST(Movshdup        , ExtRm              , O(F30F00,16,_,_,_,_,_,_  ), 0                         , 0 , 16, 5884, 50 , 6  , 30),
+     620             :   INST(Movsldup        , ExtRm              , O(F30F00,12,_,_,_,_,_,_  ), 0                         , 0 , 16, 5894, 50 , 6  , 30),
+     621             :   INST(Movss           , ExtMov             , O(F30F00,10,_,_,_,_,_,_  ), O(F30F00,11,_,_,_,_,_,_  ), 0 , 4 , 5904, 173, 80 , 35),
+     622             :   INST(Movsx           , X86MovsxMovzx      , O(000F00,BE,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1859, 174, 0  , 0 ),
+     623             :   INST(Movsxd          , X86Rm              , O(000000,63,_,_,1,_,_,_  ), 0                         , 0 , 0 , 1865, 175, 0  , 0 ),
+     624             :   INST(Movupd          , ExtMov             , O(660F00,10,_,_,_,_,_,_  ), O(660F00,11,_,_,_,_,_,_  ), 0 , 16, 5911, 176, 4  , 36),
+     625             :   INST(Movups          , ExtMov             , O(000F00,10,_,_,_,_,_,_  ), O(000F00,11,_,_,_,_,_,_  ), 0 , 16, 5919, 177, 5  , 36),
+     626             :   INST(Movzx           , X86MovsxMovzx      , O(000F00,B6,_,_,x,_,_,_  ), 0                         , 0 , 0 , 1872, 174, 0  , 0 ),
+     627             :   INST(Mpsadbw         , ExtRmi             , O(660F3A,42,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5927, 16 , 12 , 37),
+     628             :   INST(Mul             , X86M_GPB_MulDiv    , O(000000,F6,4,_,x,_,_,_  ), 0                         , 0 , 0 , 769 , 178, 1  , 0 ),
+     629             :   INST(Mulpd           , ExtRm              , O(660F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5936, 5  , 4  , 38),
+     630             :   INST(Mulps           , ExtRm              , O(000F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5943, 5  , 5  , 38),
+     631             :   INST(Mulsd           , ExtRm              , O(F20F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5950, 6  , 4  , 38),
+     632             :   INST(Mulss           , ExtRm              , O(F30F00,59,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5957, 7  , 5  , 38),
+     633             :   INST(Mulx            , VexRvm_ZDX_Wx      , V(F20F38,F6,_,0,x,_,_,_  ), 0                         , 0 , 0 , 1878, 179, 81 , 0 ),
+     634             :   INST(Mwait           , X86Op              , O(000F01,C9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1883, 180, 75 , 0 ),
+     635             :   INST(Neg             , X86M_GPB           , O(000000,F6,3,_,x,_,_,_  ), 0                         , 0 , 0 , 1889, 181, 1  , 0 ),
+     636             :   INST(Nop             , X86Op              , O(000000,90,_,_,_,_,_,_  ), 0                         , 0 , 0 , 900 , 182, 0  , 0 ),
+     637             :   INST(Not             , X86M_GPB           , O(000000,F6,2,_,x,_,_,_  ), 0                         , 0 , 0 , 1893, 181, 0  , 0 ),
+     638             :   INST(Or              , X86Arith           , O(000000,08,1,_,x,_,_,_  ), 0                         , 0 , 0 , 1109, 183, 1  , 0 ),
+     639             :   INST(Orpd            , ExtRm              , O(660F00,56,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9429, 12 , 4  , 39),
+     640             :   INST(Orps            , ExtRm              , O(000F00,56,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9436, 12 , 5  , 39),
+     641             :   INST(Out             , X86Out             , O(000000,EE,_,_,_,_,_,_  ), O(000000,E6,_,_,_,_,_,_  ), 0 , 0 , 1897, 184, 45 , 0 ),
+     642             :   INST(Outs            , X86Outs            , O(000000,6E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1901, 185, 45 , 0 ),
+     643             :   INST(Pabsb           , ExtRm_P            , O(000F38,1C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5997, 186, 82 , 40),
+     644             :   INST(Pabsd           , ExtRm_P            , O(000F38,1E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6004, 186, 82 , 40),
+     645             :   INST(Pabsw           , ExtRm_P            , O(000F38,1D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6018, 186, 82 , 41),
+     646             :   INST(Packssdw        , ExtRm_P            , O(000F00,6B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6025, 187, 78 , 42),
+     647             :   INST(Packsswb        , ExtRm_P            , O(000F00,63,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6035, 187, 78 , 42),
+     648             :   INST(Packusdw        , ExtRm              , O(660F38,2B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6045, 5  , 12 , 42),
+     649             :   INST(Packuswb        , ExtRm_P            , O(000F00,67,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6055, 187, 78 , 42),
+     650             :   INST(Paddb           , ExtRm_P            , O(000F00,FC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6065, 187, 78 , 42),
+     651             :   INST(Paddd           , ExtRm_P            , O(000F00,FE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6072, 187, 78 , 42),
+     652             :   INST(Paddq           , ExtRm_P            , O(000F00,D4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6079, 187, 4  , 42),
+     653             :   INST(Paddsb          , ExtRm_P            , O(000F00,EC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6086, 187, 78 , 42),
+     654             :   INST(Paddsw          , ExtRm_P            , O(000F00,ED,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6094, 187, 78 , 42),
+     655             :   INST(Paddusb         , ExtRm_P            , O(000F00,DC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6102, 187, 78 , 42),
+     656             :   INST(Paddusw         , ExtRm_P            , O(000F00,DD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6111, 187, 78 , 42),
+     657             :   INST(Paddw           , ExtRm_P            , O(000F00,FD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6120, 187, 78 , 42),
+     658             :   INST(Palignr         , ExtRmi_P           , O(000F3A,0F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6127, 188, 6  , 42),
+     659             :   INST(Pand            , ExtRm_P            , O(000F00,DB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6136, 189, 78 , 42),
+     660             :   INST(Pandn           , ExtRm_P            , O(000F00,DF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6149, 190, 78 , 43),
+     661             :   INST(Pause           , X86Op              , O(F30000,90,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1906, 34 , 45 , 0 ),
+     662             :   INST(Pavgb           , ExtRm_P            , O(000F00,E0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6179, 187, 83 , 44),
+     663             :   INST(Pavgusb         , Ext3dNow           , O(000F0F,BF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1912, 191, 84 , 0 ),
+     664             :   INST(Pavgw           , ExtRm_P            , O(000F00,E3,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6186, 187, 83 , 45),
+     665             :   INST(Pblendvb        , ExtRm_XMM0         , O(660F38,10,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6202, 17 , 12 , 46),
+     666             :   INST(Pblendw         , ExtRmi             , O(660F3A,0E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6212, 16 , 12 , 44),
+     667             :   INST(Pclmulqdq       , ExtRmi             , O(660F3A,44,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6305, 16 , 85 , 47),
+     668             :   INST(Pcmpeqb         , ExtRm_P            , O(000F00,74,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6337, 190, 78 , 48),
+     669             :   INST(Pcmpeqd         , ExtRm_P            , O(000F00,76,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6346, 190, 78 , 48),
+     670             :   INST(Pcmpeqq         , ExtRm              , O(660F38,29,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6355, 192, 12 , 48),
+     671             :   INST(Pcmpeqw         , ExtRm_P            , O(000F00,75,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6364, 190, 78 , 48),
+     672             :   INST(Pcmpestri       , ExtRmi             , O(660F3A,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6373, 193, 86 , 49),
+     673             :   INST(Pcmpestrm       , ExtRmi             , O(660F3A,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6384, 194, 86 , 49),
+     674             :   INST(Pcmpgtb         , ExtRm_P            , O(000F00,64,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6395, 190, 78 , 48),
+     675             :   INST(Pcmpgtd         , ExtRm_P            , O(000F00,66,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6404, 190, 78 , 48),
+     676             :   INST(Pcmpgtq         , ExtRm              , O(660F38,37,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6413, 192, 42 , 48),
+     677             :   INST(Pcmpgtw         , ExtRm_P            , O(000F00,65,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6422, 190, 78 , 48),
+     678             :   INST(Pcmpistri       , ExtRmi             , O(660F3A,63,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6431, 195, 86 , 49),
+     679             :   INST(Pcmpistrm       , ExtRmi             , O(660F3A,62,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6442, 196, 86 , 49),
+     680             :   INST(Pcommit         , X86Op_O            , O(660F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 1920, 34 , 87 , 0 ),
+     681             :   INST(Pdep            , VexRvm_Wx          , V(F20F38,F5,_,0,x,_,_,_  ), 0                         , 0 , 0 , 1928, 11 , 81 , 0 ),
+     682             :   INST(Pext            , VexRvm_Wx          , V(F30F38,F5,_,0,x,_,_,_  ), 0                         , 0 , 0 , 1933, 11 , 81 , 0 ),
+     683             :   INST(Pextrb          , ExtExtract         , O(000F3A,14,_,_,_,_,_,_  ), 0                         , 0 , 8 , 6847, 197, 12 , 50),
+     684             :   INST(Pextrd          , ExtExtract         , O(000F3A,16,_,_,_,_,_,_  ), 0                         , 0 , 8 , 6855, 67 , 12 , 50),
+     685             :   INST(Pextrq          , ExtExtract         , O(000F3A,16,_,_,1,_,_,_  ), 0                         , 0 , 8 , 6863, 198, 12 , 50),
+     686             :   INST(Pextrw          , ExtPextrw          , O(000F00,C5,_,_,_,_,_,_  ), O(000F3A,15,_,_,_,_,_,_  ), 0 , 8 , 6871, 199, 88 , 50),
+     687             :   INST(Pf2id           , Ext3dNow           , O(000F0F,1D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 1938, 200, 84 , 0 ),
+     688             :   INST(Pf2iw           , Ext3dNow           , O(000F0F,1C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 1944, 200, 89 , 0 ),
+     689             :   INST(Pfacc           , Ext3dNow           , O(000F0F,AE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1950, 191, 84 , 0 ),
+     690             :   INST(Pfadd           , Ext3dNow           , O(000F0F,9E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1956, 191, 84 , 0 ),
+     691             :   INST(Pfcmpeq         , Ext3dNow           , O(000F0F,B0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1962, 191, 84 , 0 ),
+     692             :   INST(Pfcmpge         , Ext3dNow           , O(000F0F,90,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1970, 191, 84 , 0 ),
+     693             :   INST(Pfcmpgt         , Ext3dNow           , O(000F0F,A0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1978, 191, 84 , 0 ),
+     694             :   INST(Pfmax           , Ext3dNow           , O(000F0F,A4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1986, 191, 84 , 0 ),
+     695             :   INST(Pfmin           , Ext3dNow           , O(000F0F,94,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1992, 191, 84 , 0 ),
+     696             :   INST(Pfmul           , Ext3dNow           , O(000F0F,B4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 1998, 191, 84 , 0 ),
+     697             :   INST(Pfnacc          , Ext3dNow           , O(000F0F,8A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2004, 191, 89 , 0 ),
+     698             :   INST(Pfpnacc         , Ext3dNow           , O(000F0F,8E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2011, 191, 89 , 0 ),
+     699             :   INST(Pfrcp           , Ext3dNow           , O(000F0F,96,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2019, 200, 84 , 0 ),
+     700             :   INST(Pfrcpit1        , Ext3dNow           , O(000F0F,A6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2025, 191, 84 , 0 ),
+     701             :   INST(Pfrcpit2        , Ext3dNow           , O(000F0F,B6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2034, 191, 84 , 0 ),
+     702             :   INST(Pfrcpv          , Ext3dNow           , O(000F0F,86,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2043, 191, 90 , 0 ),
+     703             :   INST(Pfrsqit1        , Ext3dNow           , O(000F0F,A7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2050, 201, 84 , 0 ),
+     704             :   INST(Pfrsqrt         , Ext3dNow           , O(000F0F,97,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2059, 201, 84 , 0 ),
+     705             :   INST(Pfrsqrtv        , Ext3dNow           , O(000F0F,87,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2067, 191, 90 , 0 ),
+     706             :   INST(Pfsub           , Ext3dNow           , O(000F0F,9A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2076, 191, 84 , 0 ),
+     707             :   INST(Pfsubr          , Ext3dNow           , O(000F0F,AA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2082, 191, 84 , 0 ),
+     708             :   INST(Phaddd          , ExtRm_P            , O(000F38,02,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6950, 187, 82 , 51),
+     709             :   INST(Phaddsw         , ExtRm_P            , O(000F38,03,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6967, 187, 82 , 52),
+     710             :   INST(Phaddw          , ExtRm_P            , O(000F38,01,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7036, 187, 82 , 53),
+     711             :   INST(Phminposuw      , ExtRm              , O(660F38,41,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7062, 5  , 12 , 54),
+     712             :   INST(Phsubd          , ExtRm_P            , O(000F38,06,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7083, 187, 82 , 55),
+     713             :   INST(Phsubsw         , ExtRm_P            , O(000F38,07,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7100, 187, 82 , 56),
+     714             :   INST(Phsubw          , ExtRm_P            , O(000F38,05,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7109, 187, 82 , 56),
+     715             :   INST(Pi2fd           , Ext3dNow           , O(000F0F,0D,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2089, 200, 84 , 0 ),
+     716             :   INST(Pi2fw           , Ext3dNow           , O(000F0F,0C,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2095, 200, 89 , 0 ),
+     717             :   INST(Pinsrb          , ExtRmi             , O(660F3A,20,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7126, 202, 12 , 57),
+     718             :   INST(Pinsrd          , ExtRmi             , O(660F3A,22,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7134, 203, 12 , 57),
+     719             :   INST(Pinsrq          , ExtRmi             , O(660F3A,22,_,_,1,_,_,_  ), 0                         , 0 , 0 , 7142, 204, 12 , 57),
+     720             :   INST(Pinsrw          , ExtRmi_P           , O(000F00,C4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7150, 205, 83 , 55),
+     721             :   INST(Pmaddubsw       , ExtRm_P            , O(000F38,04,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7320, 187, 82 , 58),
+     722             :   INST(Pmaddwd         , ExtRm_P            , O(000F00,F5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7331, 187, 78 , 58),
+     723             :   INST(Pmaxsb          , ExtRm              , O(660F38,3C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7362, 12 , 12 , 59),
+     724             :   INST(Pmaxsd          , ExtRm              , O(660F38,3D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7370, 12 , 12 , 59),
+     725             :   INST(Pmaxsw          , ExtRm_P            , O(000F00,EE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7386, 189, 83 , 60),
+     726             :   INST(Pmaxub          , ExtRm_P            , O(000F00,DE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7394, 189, 83 , 60),
+     727             :   INST(Pmaxud          , ExtRm              , O(660F38,3F,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7402, 12 , 12 , 60),
+     728             :   INST(Pmaxuw          , ExtRm              , O(660F38,3E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7418, 12 , 12 , 61),
+     729             :   INST(Pminsb          , ExtRm              , O(660F38,38,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7426, 12 , 12 , 61),
+     730             :   INST(Pminsd          , ExtRm              , O(660F38,39,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7434, 12 , 12 , 61),
+     731             :   INST(Pminsw          , ExtRm_P            , O(000F00,EA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7450, 189, 83 , 62),
+     732             :   INST(Pminub          , ExtRm_P            , O(000F00,DA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7458, 189, 83 , 62),
+     733             :   INST(Pminud          , ExtRm              , O(660F38,3B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7466, 12 , 12 , 62),
+     734             :   INST(Pminuw          , ExtRm              , O(660F38,3A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7482, 12 , 12 , 63),
+     735             :   INST(Pmovmskb        , ExtRm_P            , O(000F00,D7,_,_,_,_,_,_  ), 0                         , 0 , 8 , 7560, 206, 83 , 64),
+     736             :   INST(Pmovsxbd        , ExtRm              , O(660F38,21,_,_,_,_,_,_  ), 0                         , 0 , 16, 7657, 207, 12 , 14),
+     737             :   INST(Pmovsxbq        , ExtRm              , O(660F38,22,_,_,_,_,_,_  ), 0                         , 0 , 16, 7667, 208, 12 , 14),
+     738             :   INST(Pmovsxbw        , ExtRm              , O(660F38,20,_,_,_,_,_,_  ), 0                         , 0 , 16, 7677, 49 , 12 , 14),
+     739             :   INST(Pmovsxdq        , ExtRm              , O(660F38,25,_,_,_,_,_,_  ), 0                         , 0 , 16, 7687, 49 , 12 , 14),
+     740             :   INST(Pmovsxwd        , ExtRm              , O(660F38,23,_,_,_,_,_,_  ), 0                         , 0 , 16, 7697, 49 , 12 , 14),
+     741             :   INST(Pmovsxwq        , ExtRm              , O(660F38,24,_,_,_,_,_,_  ), 0                         , 0 , 16, 7707, 207, 12 , 14),
+     742             :   INST(Pmovzxbd        , ExtRm              , O(660F38,31,_,_,_,_,_,_  ), 0                         , 0 , 16, 7794, 207, 12 , 65),
+     743             :   INST(Pmovzxbq        , ExtRm              , O(660F38,32,_,_,_,_,_,_  ), 0                         , 0 , 16, 7804, 208, 12 , 65),
+     744             :   INST(Pmovzxbw        , ExtRm              , O(660F38,30,_,_,_,_,_,_  ), 0                         , 0 , 16, 7814, 49 , 12 , 65),
+     745             :   INST(Pmovzxdq        , ExtRm              , O(660F38,35,_,_,_,_,_,_  ), 0                         , 0 , 16, 7824, 49 , 12 , 65),
+     746             :   INST(Pmovzxwd        , ExtRm              , O(660F38,33,_,_,_,_,_,_  ), 0                         , 0 , 16, 7834, 49 , 12 , 65),
+     747             :   INST(Pmovzxwq        , ExtRm              , O(660F38,34,_,_,_,_,_,_  ), 0                         , 0 , 16, 7844, 207, 12 , 65),
+     748             :   INST(Pmuldq          , ExtRm              , O(660F38,28,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7854, 5  , 12 , 19),
+     749             :   INST(Pmulhrsw        , ExtRm_P            , O(000F38,0B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7862, 187, 82 , 19),
+     750             :   INST(Pmulhrw         , Ext3dNow           , O(000F0F,B7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2101, 191, 84 , 0 ),
+     751             :   INST(Pmulhuw         , ExtRm_P            , O(000F00,E4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7872, 187, 83 , 66),
+     752             :   INST(Pmulhw          , ExtRm_P            , O(000F00,E5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7881, 187, 78 , 66),
+     753             :   INST(Pmulld          , ExtRm              , O(660F38,40,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7889, 5  , 12 , 66),
+     754             :   INST(Pmullw          , ExtRm_P            , O(000F00,D5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7905, 187, 78 , 19),
+     755             :   INST(Pmuludq         , ExtRm_P            , O(000F00,F4,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7928, 187, 4  , 67),
+     756             :   INST(Pop             , X86Pop             , O(000000,8F,0,_,_,_,_,_  ), O(000000,58,_,_,_,_,_,_  ), 0 , 0 , 2109, 209, 45 , 0 ),
+     757             :   INST(Popa            , X86Op              , O(660000,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2113, 99 , 45 , 0 ),
+     758             :   INST(Popad           , X86Op              , O(000000,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2118, 99 , 45 , 0 ),
+     759             :   INST(Popcnt          , X86Rm_Raw66H       , O(F30F00,B8,_,_,x,_,_,_  ), 0                         , 0 , 0 , 2124, 143, 91 , 0 ),
+     760             :   INST(Popf            , X86Op              , O(660000,9D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2131, 34 , 16 , 0 ),
+     761             :   INST(Popfd           , X86Op              , O(000000,9D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2136, 99 , 16 , 0 ),
+     762             :   INST(Popfq           , X86Op              , O(000000,9D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2142, 101, 16 , 0 ),
+     763             :   INST(Por             , ExtRm_P            , O(000F00,EB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 7955, 189, 78 , 68),
+     764             :   INST(Prefetch        , X86M_Only          , O(000F00,0D,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2148, 35 , 92 , 0 ),
+     765             :   INST(Prefetchnta     , X86M_Only          , O(000F00,18,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2157, 35 , 93 , 0 ),
+     766             :   INST(Prefetcht0      , X86M_Only          , O(000F00,18,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2169, 35 , 93 , 0 ),
+     767             :   INST(Prefetcht1      , X86M_Only          , O(000F00,18,2,_,_,_,_,_  ), 0                         , 0 , 0 , 2180, 35 , 93 , 0 ),
+     768             :   INST(Prefetcht2      , X86M_Only          , O(000F00,18,3,_,_,_,_,_  ), 0                         , 0 , 0 , 2191, 35 , 93 , 0 ),
+     769             :   INST(Prefetchw       , X86M_Only          , O(000F00,0D,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2202, 35 , 94 , 0 ),
+     770             :   INST(Prefetchwt1     , X86M_Only          , O(000F00,0D,2,_,_,_,_,_  ), 0                         , 0 , 0 , 2212, 35 , 95 , 0 ),
+     771             :   INST(Psadbw          , ExtRm_P            , O(000F00,F6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 3795, 187, 83 , 69),
+     772             :   INST(Pshufb          , ExtRm_P            , O(000F38,00,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8179, 187, 82 , 70),
+     773             :   INST(Pshufd          , ExtRmi             , O(660F00,70,_,_,_,_,_,_  ), 0                         , 0 , 16, 8187, 210, 4  , 71),
+     774             :   INST(Pshufhw         , ExtRmi             , O(F30F00,70,_,_,_,_,_,_  ), 0                         , 0 , 16, 8195, 210, 4  , 71),
+     775             :   INST(Pshuflw         , ExtRmi             , O(F20F00,70,_,_,_,_,_,_  ), 0                         , 0 , 16, 8204, 210, 4  , 71),
+     776             :   INST(Pshufw          , ExtRmi_P           , O(000F00,70,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2224, 211, 74 , 0 ),
+     777             :   INST(Psignb          , ExtRm_P            , O(000F38,08,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8213, 187, 82 , 72),
+     778             :   INST(Psignd          , ExtRm_P            , O(000F38,0A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8221, 187, 82 , 72),
+     779             :   INST(Psignw          , ExtRm_P            , O(000F38,09,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8229, 187, 82 , 72),
+     780             :   INST(Pslld           , ExtRmRi_P          , O(000F00,F2,_,_,_,_,_,_  ), O(000F00,72,6,_,_,_,_,_  ), 0 , 0 , 8237, 212, 78 , 72),
+     781             :   INST(Pslldq          , ExtRmRi            , 0                         , O(660F00,73,7,_,_,_,_,_  ), 0 , 0 , 8244, 213, 4  , 72),
+     782             :   INST(Psllq           , ExtRmRi_P          , O(000F00,F3,_,_,_,_,_,_  ), O(000F00,73,6,_,_,_,_,_  ), 0 , 0 , 8252, 214, 78 , 72),
+     783             :   INST(Psllw           , ExtRmRi_P          , O(000F00,F1,_,_,_,_,_,_  ), O(000F00,71,6,_,_,_,_,_  ), 0 , 0 , 8283, 215, 78 , 73),
+     784             :   INST(Psrad           , ExtRmRi_P          , O(000F00,E2,_,_,_,_,_,_  ), O(000F00,72,4,_,_,_,_,_  ), 0 , 0 , 8290, 216, 78 , 73),
+     785             :   INST(Psraw           , ExtRmRi_P          , O(000F00,E1,_,_,_,_,_,_  ), O(000F00,71,4,_,_,_,_,_  ), 0 , 0 , 8328, 217, 78 , 74),
+     786             :   INST(Psrld           , ExtRmRi_P          , O(000F00,D2,_,_,_,_,_,_  ), O(000F00,72,2,_,_,_,_,_  ), 0 , 0 , 8335, 218, 78 , 74),
+     787             :   INST(Psrldq          , ExtRmRi            , 0                         , O(660F00,73,3,_,_,_,_,_  ), 0 , 0 , 8342, 219, 4  , 74),
+     788             :   INST(Psrlq           , ExtRmRi_P          , O(000F00,D3,_,_,_,_,_,_  ), O(000F00,73,2,_,_,_,_,_  ), 0 , 0 , 8350, 220, 78 , 74),
+     789             :   INST(Psrlw           , ExtRmRi_P          , O(000F00,D1,_,_,_,_,_,_  ), O(000F00,71,2,_,_,_,_,_  ), 0 , 0 , 8381, 221, 78 , 75),
+     790             :   INST(Psubb           , ExtRm_P            , O(000F00,F8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8388, 190, 78 , 75),
+     791             :   INST(Psubd           , ExtRm_P            , O(000F00,FA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8395, 190, 78 , 75),
+     792             :   INST(Psubq           , ExtRm_P            , O(000F00,FB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8402, 190, 4  , 75),
+     793             :   INST(Psubsb          , ExtRm_P            , O(000F00,E8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8409, 190, 78 , 75),
+     794             :   INST(Psubsw          , ExtRm_P            , O(000F00,E9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8417, 190, 78 , 75),
+     795             :   INST(Psubusb         , ExtRm_P            , O(000F00,D8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8425, 190, 78 , 75),
+     796             :   INST(Psubusw         , ExtRm_P            , O(000F00,D9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8434, 190, 78 , 75),
+     797             :   INST(Psubw           , ExtRm_P            , O(000F00,F9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8443, 190, 78 , 75),
+     798             :   INST(Pswapd          , Ext3dNow           , O(000F0F,BB,_,_,_,_,_,_  ), 0                         , 0 , 8 , 2231, 200, 89 , 0 ),
+     799             :   INST(Ptest           , ExtRm              , O(660F38,17,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8472, 222, 96 , 76),
+     800             :   INST(Punpckhbw       , ExtRm_P            , O(000F00,68,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8555, 187, 78 , 77),
+     801             :   INST(Punpckhdq       , ExtRm_P            , O(000F00,6A,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8566, 187, 78 , 77),
+     802             :   INST(Punpckhqdq      , ExtRm              , O(660F00,6D,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8577, 5  , 4  , 77),
+     803             :   INST(Punpckhwd       , ExtRm_P            , O(000F00,69,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8589, 187, 78 , 77),
+     804             :   INST(Punpcklbw       , ExtRm_P            , O(000F00,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8600, 187, 78 , 77),
+     805             :   INST(Punpckldq       , ExtRm_P            , O(000F00,62,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8611, 187, 78 , 77),
+     806             :   INST(Punpcklqdq      , ExtRm              , O(660F00,6C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8622, 5  , 4  , 77),
+     807             :   INST(Punpcklwd       , ExtRm_P            , O(000F00,61,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8634, 187, 78 , 77),
+     808             :   INST(Push            , X86Push            , O(000000,FF,6,_,_,_,_,_  ), O(000000,50,_,_,_,_,_,_  ), 0 , 0 , 2238, 223, 45 , 0 ),
+     809             :   INST(Pusha           , X86Op              , O(660000,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2243, 99 , 45 , 0 ),
+     810             :   INST(Pushad          , X86Op              , O(000000,60,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2249, 99 , 45 , 0 ),
+     811             :   INST(Pushf           , X86Op              , O(660000,9C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2256, 34 , 45 , 0 ),
+     812             :   INST(Pushfd          , X86Op              , O(000000,9C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2262, 99 , 45 , 0 ),
+     813             :   INST(Pushfq          , X86Op              , O(000000,9C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2269, 101, 45 , 0 ),
+     814             :   INST(Pxor            , ExtRm_P            , O(000F00,EF,_,_,_,_,_,_  ), 0                         , 0 , 0 , 8645, 190, 78 , 78),
+     815             :   INST(Rcl             , X86Rot             , O(000000,D0,2,_,x,_,_,_  ), 0                         , 0 , 0 , 2276, 224, 97 , 0 ),
+     816             :   INST(Rcpps           , ExtRm              , O(000F00,53,_,_,_,_,_,_  ), 0                         , 0 , 16, 8773, 50 , 5  , 79),
+     817             :   INST(Rcpss           , ExtRm              , O(F30F00,53,_,_,_,_,_,_  ), 0                         , 0 , 4 , 8780, 225, 5  , 80),
+     818             :   INST(Rcr             , X86Rot             , O(000000,D0,3,_,x,_,_,_  ), 0                         , 0 , 0 , 2280, 224, 97 , 0 ),
+     819             :   INST(Rdfsbase        , X86M               , O(F30F00,AE,0,_,x,_,_,_  ), 0                         , 0 , 8 , 2284, 226, 98 , 0 ),
+     820             :   INST(Rdgsbase        , X86M               , O(F30F00,AE,1,_,x,_,_,_  ), 0                         , 0 , 8 , 2293, 226, 98 , 0 ),
+     821             :   INST(Rdmsr           , X86Op              , O(000F00,32,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2302, 227, 99 , 0 ),
+     822             :   INST(Rdpmc           , X86Op              , O(000F00,33,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2308, 227, 23 , 0 ),
+     823             :   INST(Rdrand          , X86M               , O(000F00,C7,6,_,x,_,_,_  ), 0                         , 0 , 8 , 2314, 228, 100, 0 ),
+     824             :   INST(Rdseed          , X86M               , O(000F00,C7,7,_,x,_,_,_  ), 0                         , 0 , 8 , 2321, 228, 101, 0 ),
+     825             :   INST(Rdtsc           , X86Op              , O(000F00,31,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2328, 229, 102, 0 ),
+     826             :   INST(Rdtscp          , X86Op              , O(000F01,F9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2334, 230, 103, 0 ),
+     827             :   INST(Ret             , X86Ret             , O(000000,C2,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2748, 231, 45 , 0 ),
+     828             :   INST(Rol             , X86Rot             , O(000000,D0,0,_,x,_,_,_  ), 0                         , 0 , 0 , 2341, 224, 97 , 0 ),
+     829             :   INST(Ror             , X86Rot             , O(000000,D0,1,_,x,_,_,_  ), 0                         , 0 , 0 , 2345, 224, 97 , 0 ),
+     830             :   INST(Rorx            , VexRmi_Wx          , V(F20F3A,F0,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2349, 232, 81 , 0 ),
+     831             :   INST(Roundpd         , ExtRmi             , O(660F3A,09,_,_,_,_,_,_  ), 0                         , 0 , 16, 8875, 210, 12 , 81),
+     832             :   INST(Roundps         , ExtRmi             , O(660F3A,08,_,_,_,_,_,_  ), 0                         , 0 , 16, 8884, 210, 12 , 81),
+     833             :   INST(Roundsd         , ExtRmi             , O(660F3A,0B,_,_,_,_,_,_  ), 0                         , 0 , 8 , 8893, 233, 12 , 82),
+     834             :   INST(Roundss         , ExtRmi             , O(660F3A,0A,_,_,_,_,_,_  ), 0                         , 0 , 4 , 8902, 234, 12 , 82),
+     835             :   INST(Rsm             , X86Op              , O(000F00,AA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2354, 99 , 16 , 0 ),
+     836             :   INST(Rsqrtps         , ExtRm              , O(000F00,52,_,_,_,_,_,_  ), 0                         , 0 , 16, 8999, 50 , 5  , 3 ),
+     837             :   INST(Rsqrtss         , ExtRm              , O(F30F00,52,_,_,_,_,_,_  ), 0                         , 0 , 4 , 9008, 225, 5  , 2 ),
+     838             :   INST(Sahf            , X86Op              , O(000000,9E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2358, 235, 104, 0 ),
+     839             :   INST(Sal             , X86Rot             , O(000000,D0,4,_,x,_,_,_  ), 0                         , 0 , 0 , 2363, 224, 1  , 0 ),
+     840             :   INST(Sar             , X86Rot             , O(000000,D0,7,_,x,_,_,_  ), 0                         , 0 , 0 , 2367, 224, 1  , 0 ),
+     841             :   INST(Sarx            , VexRmv_Wx          , V(F30F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2371, 14 , 81 , 0 ),
+     842             :   INST(Sbb             , X86Arith           , O(000000,18,3,_,x,_,_,_  ), 0                         , 0 , 0 , 2376, 3  , 2  , 0 ),
+     843             :   INST(Scas            , X86StrRm           , O(000000,AE,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2380, 236, 35 , 0 ),
+     844             :   INST(Seta            , X86Set             , O(000F00,97,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2385, 237, 105, 0 ),
+     845             :   INST(Setae           , X86Set             , O(000F00,93,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2390, 237, 106, 0 ),
+     846             :   INST(Setb            , X86Set             , O(000F00,92,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2396, 237, 106, 0 ),
+     847             :   INST(Setbe           , X86Set             , O(000F00,96,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2401, 237, 105, 0 ),
+     848             :   INST(Setc            , X86Set             , O(000F00,92,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2407, 237, 106, 0 ),
+     849             :   INST(Sete            , X86Set             , O(000F00,94,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2412, 237, 107, 0 ),
+     850             :   INST(Setg            , X86Set             , O(000F00,9F,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2417, 237, 108, 0 ),
+     851             :   INST(Setge           , X86Set             , O(000F00,9D,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2422, 237, 109, 0 ),
+     852             :   INST(Setl            , X86Set             , O(000F00,9C,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2428, 237, 109, 0 ),
+     853             :   INST(Setle           , X86Set             , O(000F00,9E,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2433, 237, 108, 0 ),
+     854             :   INST(Setna           , X86Set             , O(000F00,96,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2439, 237, 105, 0 ),
+     855             :   INST(Setnae          , X86Set             , O(000F00,92,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2445, 237, 106, 0 ),
+     856             :   INST(Setnb           , X86Set             , O(000F00,93,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2452, 237, 106, 0 ),
+     857             :   INST(Setnbe          , X86Set             , O(000F00,97,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2458, 237, 105, 0 ),
+     858             :   INST(Setnc           , X86Set             , O(000F00,93,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2465, 237, 106, 0 ),
+     859             :   INST(Setne           , X86Set             , O(000F00,95,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2471, 237, 107, 0 ),
+     860             :   INST(Setng           , X86Set             , O(000F00,9E,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2477, 237, 108, 0 ),
+     861             :   INST(Setnge          , X86Set             , O(000F00,9C,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2483, 237, 109, 0 ),
+     862             :   INST(Setnl           , X86Set             , O(000F00,9D,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2490, 237, 109, 0 ),
+     863             :   INST(Setnle          , X86Set             , O(000F00,9F,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2496, 237, 108, 0 ),
+     864             :   INST(Setno           , X86Set             , O(000F00,91,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2503, 237, 110, 0 ),
+     865             :   INST(Setnp           , X86Set             , O(000F00,9B,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2509, 237, 111, 0 ),
+     866             :   INST(Setns           , X86Set             , O(000F00,99,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2515, 237, 112, 0 ),
+     867             :   INST(Setnz           , X86Set             , O(000F00,95,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2521, 237, 107, 0 ),
+     868             :   INST(Seto            , X86Set             , O(000F00,90,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2527, 237, 110, 0 ),
+     869             :   INST(Setp            , X86Set             , O(000F00,9A,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2532, 237, 111, 0 ),
+     870             :   INST(Setpe           , X86Set             , O(000F00,9A,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2537, 237, 111, 0 ),
+     871             :   INST(Setpo           , X86Set             , O(000F00,9B,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2543, 237, 111, 0 ),
+     872             :   INST(Sets            , X86Set             , O(000F00,98,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2549, 237, 112, 0 ),
+     873             :   INST(Setz            , X86Set             , O(000F00,94,_,_,_,_,_,_  ), 0                         , 0 , 1 , 2554, 237, 107, 0 ),
+     874             :   INST(Sfence          , X86Fence           , O(000F00,AE,7,_,_,_,_,_  ), 0                         , 0 , 0 , 2559, 34 , 113, 0 ),
+     875             :   INST(Sgdt            , X86M_Only          , O(000F00,01,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2566, 84 , 45 , 0 ),
+     876             :   INST(Sha1msg1        , ExtRm              , O(000F38,C9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2571, 5  , 114, 0 ),
+     877             :   INST(Sha1msg2        , ExtRm              , O(000F38,CA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2580, 5  , 114, 0 ),
+     878             :   INST(Sha1nexte       , ExtRm              , O(000F38,C8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2589, 5  , 114, 0 ),
+     879             :   INST(Sha1rnds4       , ExtRmi             , O(000F3A,CC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2599, 16 , 114, 0 ),
+     880             :   INST(Sha256msg1      , ExtRm              , O(000F38,CC,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2609, 5  , 114, 0 ),
+     881             :   INST(Sha256msg2      , ExtRm              , O(000F38,CD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2620, 5  , 114, 0 ),
+     882             :   INST(Sha256rnds2     , ExtRm_XMM0         , O(000F38,CB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2631, 17 , 114, 0 ),
+     883             :   INST(Shl             , X86Rot             , O(000000,D0,4,_,x,_,_,_  ), 0                         , 0 , 0 , 2643, 224, 1  , 0 ),
+     884             :   INST(Shld            , X86ShldShrd        , O(000F00,A4,_,_,x,_,_,_  ), 0                         , 0 , 0 , 8159, 238, 1  , 0 ),
+     885             :   INST(Shlx            , VexRmv_Wx          , V(660F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2647, 14 , 81 , 0 ),
+     886             :   INST(Shr             , X86Rot             , O(000000,D0,5,_,x,_,_,_  ), 0                         , 0 , 0 , 2652, 224, 1  , 0 ),
+     887             :   INST(Shrd            , X86ShldShrd        , O(000F00,AC,_,_,x,_,_,_  ), 0                         , 0 , 0 , 2656, 238, 1  , 0 ),
+     888             :   INST(Shrx            , VexRmv_Wx          , V(F20F38,F7,_,0,x,_,_,_  ), 0                         , 0 , 0 , 2661, 14 , 81 , 0 ),
+     889             :   INST(Shufpd          , ExtRmi             , O(660F00,C6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9269, 16 , 4  , 83),
+     890             :   INST(Shufps          , ExtRmi             , O(000F00,C6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9277, 16 , 5  , 83),
+     891             :   INST(Sidt            , X86M_Only          , O(000F00,01,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2666, 84 , 45 , 0 ),
+     892             :   INST(Sldt            , X86M               , O(000F00,00,0,_,_,_,_,_  ), 0                         , 0 , 0 , 2671, 239, 45 , 0 ),
+     893             :   INST(Smsw            , X86M               , O(000F00,01,4,_,_,_,_,_  ), 0                         , 0 , 0 , 2676, 239, 45 , 0 ),
+     894             :   INST(Sqrtpd          , ExtRm              , O(660F00,51,_,_,_,_,_,_  ), 0                         , 0 , 16, 9285, 50 , 4  , 84),
+     895             :   INST(Sqrtps          , ExtRm              , O(000F00,51,_,_,_,_,_,_  ), 0                         , 0 , 16, 9000, 50 , 5  , 84),
+     896             :   INST(Sqrtsd          , ExtRm              , O(F20F00,51,_,_,_,_,_,_  ), 0                         , 0 , 8 , 9301, 240, 4  , 85),
+     897             :   INST(Sqrtss          , ExtRm              , O(F30F00,51,_,_,_,_,_,_  ), 0                         , 0 , 4 , 9009, 225, 5  , 85),
+     898             :   INST(Stac            , X86Op              , O(000F01,CB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2681, 34 , 17 , 0 ),
+     899             :   INST(Stc             , X86Op              , O(000000,F9,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2686, 34 , 18 , 0 ),
+     900             :   INST(Std             , X86Op              , O(000000,FD,_,_,_,_,_,_  ), 0                         , 0 , 0 , 6242, 34 , 19 , 0 ),
+     901             :   INST(Sti             , X86Op              , O(000000,FB,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2690, 34 , 22 , 0 ),
+     902             :   INST(Stmxcsr         , X86M_Only          , O(000F00,AE,3,_,_,_,_,_  ), 0                         , 0 , 0 , 9317, 241, 5  , 0 ),
+     903             :   INST(Stos            , X86StrMr           , O(000000,AA,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2694, 242, 72 , 0 ),
+     904             :   INST(Str             , X86M               , O(000F00,00,1,_,_,_,_,_  ), 0                         , 0 , 0 , 2699, 239, 45 , 0 ),
+     905             :   INST(Sub             , X86Arith           , O(000000,28,5,_,x,_,_,_  ), 0                         , 0 , 0 , 807 , 243, 1  , 0 ),
+     906             :   INST(Subpd           , ExtRm              , O(660F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4361, 5  , 4  , 86),
+     907             :   INST(Subps           , ExtRm              , O(000F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 4373, 5  , 5  , 86),
+     908             :   INST(Subsd           , ExtRm              , O(F20F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5049, 6  , 4  , 86),
+     909             :   INST(Subss           , ExtRm              , O(F30F00,5C,_,_,_,_,_,_  ), 0                         , 0 , 0 , 5059, 7  , 5  , 86),
+     910             :   INST(Swapgs          , X86Op              , O(000F01,F8,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2703, 101, 23 , 0 ),
+     911             :   INST(Syscall         , X86Op              , O(000F00,05,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2710, 101, 45 , 0 ),
+     912             :   INST(Sysenter        , X86Op              , O(000F00,34,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2718, 34 , 45 , 0 ),
+     913             :   INST(Sysexit         , X86Op              , O(000F00,35,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2727, 34 , 23 , 0 ),
+     914             :   INST(Sysexit64       , X86Op              , O(000F00,35,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2735, 34 , 23 , 0 ),
+     915             :   INST(Sysret          , X86Op              , O(000F00,07,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2745, 101, 23 , 0 ),
+     916             :   INST(Sysret64        , X86Op              , O(000F00,07,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2752, 101, 23 , 0 ),
+     917             :   INST(T1mskc          , VexVm_Wx           , V(XOP_M9,01,7,0,x,_,_,_  ), 0                         , 0 , 0 , 2761, 15 , 11 , 0 ),
+     918             :   INST(Test            , X86Test            , O(000000,84,_,_,x,_,_,_  ), O(000000,F6,_,_,x,_,_,_  ), 0 , 0 , 8473, 244, 1  , 0 ),
+     919             :   INST(Tzcnt           , X86Rm_Raw66H       , O(F30F00,BC,_,_,x,_,_,_  ), 0                         , 0 , 0 , 2768, 143, 9  , 0 ),
+     920             :   INST(Tzmsk           , VexVm_Wx           , V(XOP_M9,01,4,0,x,_,_,_  ), 0                         , 0 , 0 , 2774, 15 , 11 , 0 ),
+     921             :   INST(Ucomisd         , ExtRm              , O(660F00,2E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9370, 44 , 39 , 15),
+     922             :   INST(Ucomiss         , ExtRm              , O(000F00,2E,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9379, 45 , 40 , 15),
+     923             :   INST(Ud2             , X86Op              , O(000F00,0B,_,_,_,_,_,_  ), 0                         , 0 , 0 , 2780, 34 , 0  , 0 ),
+     924             :   INST(Unpckhpd        , ExtRm              , O(660F00,15,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9388, 5  , 4  , 13),
+     925             :   INST(Unpckhps        , ExtRm              , O(000F00,15,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9398, 5  , 5  , 13),
+     926             :   INST(Unpcklpd        , ExtRm              , O(660F00,14,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9408, 5  , 4  , 13),
+     927             :   INST(Unpcklps        , ExtRm              , O(000F00,14,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9418, 5  , 5  , 13),
+     928             :   INST(V4fmaddps       , VexRm_T1_4X        , V(F20F38,9A,_,2,_,0,2,T4X), 0                         , 0 , 0 , 2784, 245, 115, 0 ),
+     929             :   INST(V4fnmaddps      , VexRm_T1_4X        , V(F20F38,AA,_,2,_,0,2,T4X), 0                         , 0 , 0 , 2794, 245, 115, 0 ),
+     930             :   INST(Vaddpd          , VexRvm_Lx          , V(660F00,58,_,x,I,1,4,FV ), 0                         , 0 , 0 , 2805, 246, 116, 1 ),
+     931             :   INST(Vaddps          , VexRvm_Lx          , V(000F00,58,_,x,I,0,4,FV ), 0                         , 0 , 0 , 2812, 247, 116, 1 ),
+     932             :   INST(Vaddsd          , VexRvm             , V(F20F00,58,_,I,I,1,3,T1S), 0                         , 0 , 0 , 2819, 248, 117, 1 ),
+     933             :   INST(Vaddss          , VexRvm             , V(F30F00,58,_,I,I,0,2,T1S), 0                         , 0 , 0 , 2826, 249, 117, 1 ),
+     934             :   INST(Vaddsubpd       , VexRvm_Lx          , V(660F00,D0,_,x,I,_,_,_  ), 0                         , 0 , 0 , 2833, 250, 118, 1 ),
+     935             :   INST(Vaddsubps       , VexRvm_Lx          , V(F20F00,D0,_,x,I,_,_,_  ), 0                         , 0 , 0 , 2843, 250, 118, 1 ),
+     936             :   INST(Vaesdec         , VexRvm             , V(660F38,DE,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2853, 251, 119, 2 ),
+     937             :   INST(Vaesdeclast     , VexRvm             , V(660F38,DF,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2861, 251, 119, 2 ),
+     938             :   INST(Vaesenc         , VexRvm             , V(660F38,DC,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2873, 251, 119, 2 ),
+     939             :   INST(Vaesenclast     , VexRvm             , V(660F38,DD,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2881, 251, 119, 2 ),
+     940             :   INST(Vaesimc         , VexRm              , V(660F38,DB,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2893, 252, 119, 3 ),
+     941             :   INST(Vaeskeygenassist, VexRmi             , V(660F3A,DF,_,0,I,_,_,_  ), 0                         , 0 , 0 , 2901, 253, 119, 3 ),
+     942             :   INST(Valignd         , VexRvmi_Lx         , V(660F3A,03,_,x,_,0,4,FV ), 0                         , 0 , 0 , 2918, 254, 120, 0 ),
+     943             :   INST(Valignq         , VexRvmi_Lx         , V(660F3A,03,_,x,_,1,4,FV ), 0                         , 0 , 0 , 2926, 255, 120, 0 ),
+     944             :   INST(Vandnpd         , VexRvm_Lx          , V(660F00,55,_,x,I,1,4,FV ), 0                         , 0 , 0 , 2934, 256, 121, 2 ),
+     945             :   INST(Vandnps         , VexRvm_Lx          , V(000F00,55,_,x,I,0,4,FV ), 0                         , 0 , 0 , 2942, 257, 121, 2 ),
+     946             :   INST(Vandpd          , VexRvm_Lx          , V(660F00,54,_,x,I,1,4,FV ), 0                         , 0 , 0 , 2950, 258, 121, 2 ),
+     947             :   INST(Vandps          , VexRvm_Lx          , V(000F00,54,_,x,I,0,4,FV ), 0                         , 0 , 0 , 2957, 259, 121, 2 ),
+     948             :   INST(Vblendmb        , VexRvm_Lx          , V(660F38,66,_,x,_,0,4,FVM), 0                         , 0 , 0 , 2964, 260, 122, 0 ),
+     949             :   INST(Vblendmd        , VexRvm_Lx          , V(660F38,64,_,x,_,0,4,FV ), 0                         , 0 , 0 , 2973, 261, 120, 0 ),
+     950             :   INST(Vblendmpd       , VexRvm_Lx          , V(660F38,65,_,x,_,1,4,FV ), 0                         , 0 , 0 , 2982, 262, 120, 0 ),
+     951             :   INST(Vblendmps       , VexRvm_Lx          , V(660F38,65,_,x,_,0,4,FV ), 0                         , 0 , 0 , 2992, 261, 120, 0 ),
+     952             :   INST(Vblendmq        , VexRvm_Lx          , V(660F38,64,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3002, 262, 120, 0 ),
+     953             :   INST(Vblendmw        , VexRvm_Lx          , V(660F38,66,_,x,_,1,4,FVM), 0                         , 0 , 0 , 3011, 260, 122, 0 ),
+     954             :   INST(Vblendpd        , VexRvmi_Lx         , V(660F3A,0D,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3020, 263, 118, 4 ),
+     955             :   INST(Vblendps        , VexRvmi_Lx         , V(660F3A,0C,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3029, 263, 118, 4 ),
+     956             :   INST(Vblendvpd       , VexRvmr_Lx         , V(660F3A,4B,_,x,0,_,_,_  ), 0                         , 0 , 0 , 3038, 264, 118, 5 ),
+     957             :   INST(Vblendvps       , VexRvmr_Lx         , V(660F3A,4A,_,x,0,_,_,_  ), 0                         , 0 , 0 , 3048, 264, 118, 5 ),
+     958             :   INST(Vbroadcastf128  , VexRm              , V(660F38,1A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3058, 265, 118, 0 ),
+     959             :   INST(Vbroadcastf32x2 , VexRm_Lx           , V(660F38,19,_,x,_,0,3,T2 ), 0                         , 0 , 0 , 3073, 266, 123, 0 ),
+     960             :   INST(Vbroadcastf32x4 , VexRm_Lx           , V(660F38,1A,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3089, 267, 65 , 0 ),
+     961             :   INST(Vbroadcastf32x8 , VexRm              , V(660F38,1B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3105, 268, 63 , 0 ),
+     962             :   INST(Vbroadcastf64x2 , VexRm_Lx           , V(660F38,1A,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3121, 267, 123, 0 ),
+     963             :   INST(Vbroadcastf64x4 , VexRm              , V(660F38,1B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 3137, 268, 65 , 0 ),
+     964             :   INST(Vbroadcasti128  , VexRm              , V(660F38,5A,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3153, 265, 124, 0 ),
+     965             :   INST(Vbroadcasti32x2 , VexRm_Lx           , V(660F38,59,_,x,_,0,3,T2 ), 0                         , 0 , 0 , 3168, 269, 123, 0 ),
+     966             :   INST(Vbroadcasti32x4 , VexRm_Lx           , V(660F38,5A,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3184, 266, 120, 0 ),
+     967             :   INST(Vbroadcasti32x8 , VexRm              , V(660F38,5B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3200, 270, 63 , 0 ),
+     968             :   INST(Vbroadcasti64x2 , VexRm_Lx           , V(660F38,5A,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3216, 266, 123, 0 ),
+     969             :   INST(Vbroadcasti64x4 , VexRm              , V(660F38,5B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 3232, 270, 65 , 0 ),
+     970             :   INST(Vbroadcastsd    , VexRm_Lx           , V(660F38,19,_,x,0,1,3,T1S), 0                         , 0 , 0 , 3248, 271, 125, 0 ),
+     971             :   INST(Vbroadcastss    , VexRm_Lx           , V(660F38,18,_,x,0,0,2,T1S), 0                         , 0 , 0 , 3261, 272, 125, 0 ),
+     972             :   INST(Vcmppd          , VexRvmi_Lx         , V(660F00,C2,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3274, 273, 116, 6 ),
+     973             :   INST(Vcmpps          , VexRvmi_Lx         , V(000F00,C2,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3281, 274, 116, 6 ),
+     974             :   INST(Vcmpsd          , VexRvmi            , V(F20F00,C2,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3288, 275, 117, 7 ),
+     975             :   INST(Vcmpss          , VexRvmi            , V(F30F00,C2,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3295, 276, 117, 7 ),
+     976             :   INST(Vcomisd         , VexRm              , V(660F00,2F,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3302, 277, 126, 8 ),
+     977             :   INST(Vcomiss         , VexRm              , V(000F00,2F,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3310, 278, 126, 8 ),
+     978             :   INST(Vcompresspd     , VexMr_Lx           , V(660F38,8A,_,x,_,1,3,T1S), 0                         , 0 , 0 , 3318, 279, 120, 0 ),
+     979             :   INST(Vcompressps     , VexMr_Lx           , V(660F38,8A,_,x,_,0,2,T1S), 0                         , 0 , 0 , 3330, 279, 120, 0 ),
+     980             :   INST(Vcvtdq2pd       , VexRm_Lx           , V(F30F00,E6,_,x,I,0,3,HV ), 0                         , 0 , 0 , 3342, 280, 116, 9 ),
+     981             :   INST(Vcvtdq2ps       , VexRm_Lx           , V(000F00,5B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3352, 281, 116, 9 ),
+     982             :   INST(Vcvtpd2dq       , VexRm_Lx           , V(F20F00,E6,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3362, 282, 116, 9 ),
+     983             :   INST(Vcvtpd2ps       , VexRm_Lx           , V(660F00,5A,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3372, 283, 116, 10),
+     984             :   INST(Vcvtpd2qq       , VexRm_Lx           , V(660F00,7B,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3382, 284, 123, 0 ),
+     985             :   INST(Vcvtpd2udq      , VexRm_Lx           , V(000F00,79,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3392, 285, 120, 0 ),
+     986             :   INST(Vcvtpd2uqq      , VexRm_Lx           , V(660F00,79,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3403, 284, 123, 0 ),
+     987             :   INST(Vcvtph2ps       , VexRm_Lx           , V(660F38,13,_,x,0,0,3,HVM), 0                         , 0 , 0 , 3414, 286, 127, 0 ),
+     988             :   INST(Vcvtps2dq       , VexRm_Lx           , V(660F00,5B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3424, 281, 116, 8 ),
+     989             :   INST(Vcvtps2pd       , VexRm_Lx           , V(000F00,5A,_,x,I,0,4,HV ), 0                         , 0 , 0 , 3434, 287, 116, 8 ),
+     990             :   INST(Vcvtps2ph       , VexMri_Lx          , V(660F3A,1D,_,x,0,0,3,HVM), 0                         , 0 , 0 , 3444, 288, 127, 0 ),
+     991             :   INST(Vcvtps2qq       , VexRm_Lx           , V(660F00,7B,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3454, 289, 123, 0 ),
+     992             :   INST(Vcvtps2udq      , VexRm_Lx           , V(000F00,79,_,x,_,0,4,FV ), 0                         , 0 , 0 , 3464, 290, 120, 0 ),
+     993             :   INST(Vcvtps2uqq      , VexRm_Lx           , V(660F00,79,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3475, 289, 123, 0 ),
+     994             :   INST(Vcvtqq2pd       , VexRm_Lx           , V(F30F00,E6,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3486, 284, 123, 0 ),
+     995             :   INST(Vcvtqq2ps       , VexRm_Lx           , V(000F00,5B,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3496, 285, 123, 0 ),
+     996             :   INST(Vcvtsd2si       , VexRm_Wx           , V(F20F00,2D,_,I,x,x,3,T1F), 0                         , 0 , 0 , 3506, 291, 117, 11),
+     997             :   INST(Vcvtsd2ss       , VexRvm             , V(F20F00,5A,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3516, 248, 117, 12),
+     998             :   INST(Vcvtsd2usi      , VexRm_Wx           , V(F20F00,79,_,I,_,x,3,T1F), 0                         , 0 , 0 , 3526, 292, 65 , 0 ),
+     999             :   INST(Vcvtsi2sd       , VexRvm_Wx          , V(F20F00,2A,_,I,x,x,2,T1W), 0                         , 0 , 0 , 3537, 293, 117, 13),
+    1000             :   INST(Vcvtsi2ss       , VexRvm_Wx          , V(F30F00,2A,_,I,x,x,2,T1W), 0                         , 0 , 0 , 3547, 293, 117, 13),
+    1001             :   INST(Vcvtss2sd       , VexRvm             , V(F30F00,5A,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3557, 294, 117, 13),
+    1002             :   INST(Vcvtss2si       , VexRm_Wx           , V(F30F00,2D,_,I,x,x,2,T1F), 0                         , 0 , 0 , 3567, 295, 117, 14),
+    1003             :   INST(Vcvtss2usi      , VexRm_Wx           , V(F30F00,79,_,I,_,x,2,T1F), 0                         , 0 , 0 , 3577, 296, 65 , 0 ),
+    1004             :   INST(Vcvttpd2dq      , VexRm_Lx           , V(660F00,E6,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3588, 297, 116, 15),
+    1005             :   INST(Vcvttpd2qq      , VexRm_Lx           , V(660F00,7A,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3599, 298, 120, 0 ),
+    1006             :   INST(Vcvttpd2udq     , VexRm_Lx           , V(000F00,78,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3610, 299, 120, 0 ),
+    1007             :   INST(Vcvttpd2uqq     , VexRm_Lx           , V(660F00,78,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3622, 298, 123, 0 ),
+    1008             :   INST(Vcvttps2dq      , VexRm_Lx           , V(F30F00,5B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3634, 300, 116, 16),
+    1009             :   INST(Vcvttps2qq      , VexRm_Lx           , V(660F00,7A,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3645, 301, 123, 0 ),
+    1010             :   INST(Vcvttps2udq     , VexRm_Lx           , V(000F00,78,_,x,_,0,4,FV ), 0                         , 0 , 0 , 3656, 302, 120, 0 ),
+    1011             :   INST(Vcvttps2uqq     , VexRm_Lx           , V(660F00,78,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3668, 301, 123, 0 ),
+    1012             :   INST(Vcvttsd2si      , VexRm_Wx           , V(F20F00,2C,_,I,x,x,3,T1F), 0                         , 0 , 0 , 3680, 303, 117, 17),
+    1013             :   INST(Vcvttsd2usi     , VexRm_Wx           , V(F20F00,78,_,I,_,x,3,T1F), 0                         , 0 , 0 , 3691, 304, 65 , 0 ),
+    1014             :   INST(Vcvttss2si      , VexRm_Wx           , V(F30F00,2C,_,I,x,x,2,T1F), 0                         , 0 , 0 , 3703, 305, 117, 18),
+    1015             :   INST(Vcvttss2usi     , VexRm_Wx           , V(F30F00,78,_,I,_,x,2,T1F), 0                         , 0 , 0 , 3714, 306, 65 , 0 ),
+    1016             :   INST(Vcvtudq2pd      , VexRm_Lx           , V(F30F00,7A,_,x,_,0,3,HV ), 0                         , 0 , 0 , 3726, 307, 120, 0 ),
+    1017             :   INST(Vcvtudq2ps      , VexRm_Lx           , V(F20F00,7A,_,x,_,0,4,FV ), 0                         , 0 , 0 , 3737, 290, 120, 0 ),
+    1018             :   INST(Vcvtuqq2pd      , VexRm_Lx           , V(F30F00,7A,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3748, 284, 123, 0 ),
+    1019             :   INST(Vcvtuqq2ps      , VexRm_Lx           , V(F20F00,7A,_,x,_,1,4,FV ), 0                         , 0 , 0 , 3759, 285, 123, 0 ),
+    1020             :   INST(Vcvtusi2sd      , VexRvm_Wx          , V(F20F00,7B,_,I,_,x,2,T1W), 0                         , 0 , 0 , 3770, 308, 65 , 0 ),
+    1021             :   INST(Vcvtusi2ss      , VexRvm_Wx          , V(F30F00,7B,_,I,_,x,2,T1W), 0                         , 0 , 0 , 3781, 308, 65 , 0 ),
+    1022             :   INST(Vdbpsadbw       , VexRvmi_Lx         , V(660F3A,42,_,x,_,0,4,FVM), 0                         , 0 , 0 , 3792, 309, 122, 0 ),
+    1023             :   INST(Vdivpd          , VexRvm_Lx          , V(660F00,5E,_,x,I,1,4,FV ), 0                         , 0 , 0 , 3802, 246, 116, 19),
+    1024             :   INST(Vdivps          , VexRvm_Lx          , V(000F00,5E,_,x,I,0,4,FV ), 0                         , 0 , 0 , 3809, 247, 116, 19),
+    1025             :   INST(Vdivsd          , VexRvm             , V(F20F00,5E,_,I,I,1,3,T1S), 0                         , 0 , 0 , 3816, 248, 117, 19),
+    1026             :   INST(Vdivss          , VexRvm             , V(F30F00,5E,_,I,I,0,2,T1S), 0                         , 0 , 0 , 3823, 249, 117, 19),
+    1027             :   INST(Vdppd           , VexRvmi_Lx         , V(660F3A,41,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3830, 310, 118, 19),
+    1028             :   INST(Vdpps           , VexRvmi_Lx         , V(660F3A,40,_,x,I,_,_,_  ), 0                         , 0 , 0 , 3836, 263, 118, 19),
+    1029             :   INST(Verr            , X86M               , O(000F00,00,4,_,_,_,_,_  ), 0                         , 0 , 0 , 3842, 137, 70 , 0 ),
+    1030             :   INST(Verw            , X86M               , O(000F00,00,5,_,_,_,_,_  ), 0                         , 0 , 0 , 3847, 137, 70 , 0 ),
+    1031             :   INST(Vexp2pd         , VexRm              , V(660F38,C8,_,2,_,1,4,FV ), 0                         , 0 , 0 , 3852, 311, 128, 0 ),
+    1032             :   INST(Vexp2ps         , VexRm              , V(660F38,C8,_,2,_,0,4,FV ), 0                         , 0 , 0 , 3860, 312, 128, 0 ),
+    1033             :   INST(Vexpandpd       , VexRm_Lx           , V(660F38,88,_,x,_,1,3,T1S), 0                         , 0 , 0 , 3868, 313, 120, 0 ),
+    1034             :   INST(Vexpandps       , VexRm_Lx           , V(660F38,88,_,x,_,0,2,T1S), 0                         , 0 , 0 , 3878, 313, 120, 0 ),
+    1035             :   INST(Vextractf128    , VexMri             , V(660F3A,19,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3888, 314, 118, 0 ),
+    1036             :   INST(Vextractf32x4   , VexMri_Lx          , V(660F3A,19,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3901, 315, 120, 0 ),
+    1037             :   INST(Vextractf32x8   , VexMri             , V(660F3A,1B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3915, 316, 63 , 0 ),
+    1038             :   INST(Vextractf64x2   , VexMri_Lx          , V(660F3A,19,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3929, 315, 123, 0 ),
+    1039             :   INST(Vextractf64x4   , VexMri             , V(660F3A,1B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 3943, 316, 65 , 0 ),
+    1040             :   INST(Vextracti128    , VexMri             , V(660F3A,39,_,1,0,_,_,_  ), 0                         , 0 , 0 , 3957, 314, 124, 0 ),
+    1041             :   INST(Vextracti32x4   , VexMri_Lx          , V(660F3A,39,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 3970, 315, 120, 0 ),
+    1042             :   INST(Vextracti32x8   , VexMri             , V(660F3A,3B,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 3984, 316, 63 , 0 ),
+    1043             :   INST(Vextracti64x2   , VexMri_Lx          , V(660F3A,39,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 3998, 315, 123, 0 ),
+    1044             :   INST(Vextracti64x4   , VexMri             , V(660F3A,3B,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 4012, 316, 65 , 0 ),
+    1045             :   INST(Vextractps      , VexMri             , V(660F3A,17,_,0,I,I,2,T1S), 0                         , 0 , 0 , 4026, 317, 117, 20),
+    1046             :   INST(Vfixupimmpd     , VexRvmi_Lx         , V(660F3A,54,_,x,_,1,4,FV ), 0                         , 0 , 0 , 4037, 318, 120, 0 ),
+    1047             :   INST(Vfixupimmps     , VexRvmi_Lx         , V(660F3A,54,_,x,_,0,4,FV ), 0                         , 0 , 0 , 4049, 319, 120, 0 ),
+    1048             :   INST(Vfixupimmsd     , VexRvmi            , V(660F3A,55,_,I,_,1,3,T1S), 0                         , 0 , 0 , 4061, 320, 65 , 0 ),
+    1049             :   INST(Vfixupimmss     , VexRvmi            , V(660F3A,55,_,I,_,0,2,T1S), 0                         , 0 , 0 , 4073, 321, 65 , 0 ),
+    1050             :   INST(Vfmadd132pd     , VexRvm_Lx          , V(660F38,98,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4085, 322, 129, 0 ),
+    1051             :   INST(Vfmadd132ps     , VexRvm_Lx          , V(660F38,98,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4097, 323, 129, 0 ),
+    1052             :   INST(Vfmadd132sd     , VexRvm             , V(660F38,99,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4109, 324, 130, 0 ),
+    1053             :   INST(Vfmadd132ss     , VexRvm             , V(660F38,99,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4121, 325, 130, 0 ),
+    1054             :   INST(Vfmadd213pd     , VexRvm_Lx          , V(660F38,A8,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4133, 322, 129, 0 ),
+    1055             :   INST(Vfmadd213ps     , VexRvm_Lx          , V(660F38,A8,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4145, 323, 129, 0 ),
+    1056             :   INST(Vfmadd213sd     , VexRvm             , V(660F38,A9,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4157, 324, 130, 0 ),
+    1057             :   INST(Vfmadd213ss     , VexRvm             , V(660F38,A9,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4169, 325, 130, 0 ),
+    1058             :   INST(Vfmadd231pd     , VexRvm_Lx          , V(660F38,B8,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4181, 322, 129, 0 ),
+    1059             :   INST(Vfmadd231ps     , VexRvm_Lx          , V(660F38,B8,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4193, 323, 129, 0 ),
+    1060             :   INST(Vfmadd231sd     , VexRvm             , V(660F38,B9,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4205, 324, 130, 0 ),
+    1061             :   INST(Vfmadd231ss     , VexRvm             , V(660F38,B9,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4217, 325, 130, 0 ),
+    1062             :   INST(Vfmaddpd        , Fma4_Lx            , V(660F3A,69,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4229, 326, 131, 0 ),
+    1063             :   INST(Vfmaddps        , Fma4_Lx            , V(660F3A,68,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4238, 326, 131, 0 ),
+    1064             :   INST(Vfmaddsd        , Fma4               , V(660F3A,6B,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4247, 327, 131, 0 ),
+    1065             :   INST(Vfmaddss        , Fma4               , V(660F3A,6A,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4256, 328, 131, 0 ),
+    1066             :   INST(Vfmaddsub132pd  , VexRvm_Lx          , V(660F38,96,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4265, 322, 129, 0 ),
+    1067             :   INST(Vfmaddsub132ps  , VexRvm_Lx          , V(660F38,96,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4280, 323, 129, 0 ),
+    1068             :   INST(Vfmaddsub213pd  , VexRvm_Lx          , V(660F38,A6,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4295, 322, 129, 0 ),
+    1069             :   INST(Vfmaddsub213ps  , VexRvm_Lx          , V(660F38,A6,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4310, 323, 129, 0 ),
+    1070             :   INST(Vfmaddsub231pd  , VexRvm_Lx          , V(660F38,B6,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4325, 322, 129, 0 ),
+    1071             :   INST(Vfmaddsub231ps  , VexRvm_Lx          , V(660F38,B6,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4340, 323, 129, 0 ),
+    1072             :   INST(Vfmaddsubpd     , Fma4_Lx            , V(660F3A,5D,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4355, 326, 131, 0 ),
+    1073             :   INST(Vfmaddsubps     , Fma4_Lx            , V(660F3A,5C,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4367, 326, 131, 0 ),
+    1074             :   INST(Vfmsub132pd     , VexRvm_Lx          , V(660F38,9A,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4379, 322, 129, 0 ),
+    1075             :   INST(Vfmsub132ps     , VexRvm_Lx          , V(660F38,9A,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4391, 323, 129, 0 ),
+    1076             :   INST(Vfmsub132sd     , VexRvm             , V(660F38,9B,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4403, 324, 130, 0 ),
+    1077             :   INST(Vfmsub132ss     , VexRvm             , V(660F38,9B,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4415, 325, 130, 0 ),
+    1078             :   INST(Vfmsub213pd     , VexRvm_Lx          , V(660F38,AA,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4427, 322, 129, 0 ),
+    1079             :   INST(Vfmsub213ps     , VexRvm_Lx          , V(660F38,AA,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4439, 323, 129, 0 ),
+    1080             :   INST(Vfmsub213sd     , VexRvm             , V(660F38,AB,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4451, 324, 130, 0 ),
+    1081             :   INST(Vfmsub213ss     , VexRvm             , V(660F38,AB,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4463, 325, 130, 0 ),
+    1082             :   INST(Vfmsub231pd     , VexRvm_Lx          , V(660F38,BA,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4475, 322, 129, 0 ),
+    1083             :   INST(Vfmsub231ps     , VexRvm_Lx          , V(660F38,BA,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4487, 323, 129, 0 ),
+    1084             :   INST(Vfmsub231sd     , VexRvm             , V(660F38,BB,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4499, 324, 130, 0 ),
+    1085             :   INST(Vfmsub231ss     , VexRvm             , V(660F38,BB,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4511, 325, 130, 0 ),
+    1086             :   INST(Vfmsubadd132pd  , VexRvm_Lx          , V(660F38,97,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4523, 322, 129, 0 ),
+    1087             :   INST(Vfmsubadd132ps  , VexRvm_Lx          , V(660F38,97,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4538, 323, 129, 0 ),
+    1088             :   INST(Vfmsubadd213pd  , VexRvm_Lx          , V(660F38,A7,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4553, 322, 129, 0 ),
+    1089             :   INST(Vfmsubadd213ps  , VexRvm_Lx          , V(660F38,A7,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4568, 323, 129, 0 ),
+    1090             :   INST(Vfmsubadd231pd  , VexRvm_Lx          , V(660F38,B7,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4583, 322, 129, 0 ),
+    1091             :   INST(Vfmsubadd231ps  , VexRvm_Lx          , V(660F38,B7,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4598, 323, 129, 0 ),
+    1092             :   INST(Vfmsubaddpd     , Fma4_Lx            , V(660F3A,5F,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4613, 326, 131, 0 ),
+    1093             :   INST(Vfmsubaddps     , Fma4_Lx            , V(660F3A,5E,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4625, 326, 131, 0 ),
+    1094             :   INST(Vfmsubpd        , Fma4_Lx            , V(660F3A,6D,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4637, 326, 131, 0 ),
+    1095             :   INST(Vfmsubps        , Fma4_Lx            , V(660F3A,6C,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4646, 326, 131, 0 ),
+    1096             :   INST(Vfmsubsd        , Fma4               , V(660F3A,6F,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4655, 327, 131, 0 ),
+    1097             :   INST(Vfmsubss        , Fma4               , V(660F3A,6E,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4664, 328, 131, 0 ),
+    1098             :   INST(Vfnmadd132pd    , VexRvm_Lx          , V(660F38,9C,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4673, 322, 129, 0 ),
+    1099             :   INST(Vfnmadd132ps    , VexRvm_Lx          , V(660F38,9C,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4686, 323, 129, 0 ),
+    1100             :   INST(Vfnmadd132sd    , VexRvm             , V(660F38,9D,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4699, 324, 130, 0 ),
+    1101             :   INST(Vfnmadd132ss    , VexRvm             , V(660F38,9D,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4712, 325, 130, 0 ),
+    1102             :   INST(Vfnmadd213pd    , VexRvm_Lx          , V(660F38,AC,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4725, 322, 129, 0 ),
+    1103             :   INST(Vfnmadd213ps    , VexRvm_Lx          , V(660F38,AC,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4738, 323, 129, 0 ),
+    1104             :   INST(Vfnmadd213sd    , VexRvm             , V(660F38,AD,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4751, 324, 130, 0 ),
+    1105             :   INST(Vfnmadd213ss    , VexRvm             , V(660F38,AD,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4764, 325, 130, 0 ),
+    1106             :   INST(Vfnmadd231pd    , VexRvm_Lx          , V(660F38,BC,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4777, 322, 129, 0 ),
+    1107             :   INST(Vfnmadd231ps    , VexRvm_Lx          , V(660F38,BC,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4790, 323, 129, 0 ),
+    1108             :   INST(Vfnmadd231sd    , VexRvm             , V(660F38,BC,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4803, 324, 130, 0 ),
+    1109             :   INST(Vfnmadd231ss    , VexRvm             , V(660F38,BC,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4816, 325, 130, 0 ),
+    1110             :   INST(Vfnmaddpd       , Fma4_Lx            , V(660F3A,79,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4829, 326, 131, 0 ),
+    1111             :   INST(Vfnmaddps       , Fma4_Lx            , V(660F3A,78,_,x,x,_,_,_  ), 0                         , 0 , 0 , 4839, 326, 131, 0 ),
+    1112             :   INST(Vfnmaddsd       , Fma4               , V(660F3A,7B,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4849, 327, 131, 0 ),
+    1113             :   INST(Vfnmaddss       , Fma4               , V(660F3A,7A,_,0,x,_,_,_  ), 0                         , 0 , 0 , 4859, 328, 131, 0 ),
+    1114             :   INST(Vfnmsub132pd    , VexRvm_Lx          , V(660F38,9E,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4869, 322, 129, 0 ),
+    1115             :   INST(Vfnmsub132ps    , VexRvm_Lx          , V(660F38,9E,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4882, 323, 129, 0 ),
+    1116             :   INST(Vfnmsub132sd    , VexRvm             , V(660F38,9F,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4895, 324, 130, 0 ),
+    1117             :   INST(Vfnmsub132ss    , VexRvm             , V(660F38,9F,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4908, 325, 130, 0 ),
+    1118             :   INST(Vfnmsub213pd    , VexRvm_Lx          , V(660F38,AE,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4921, 322, 129, 0 ),
+    1119             :   INST(Vfnmsub213ps    , VexRvm_Lx          , V(660F38,AE,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4934, 323, 129, 0 ),
+    1120             :   INST(Vfnmsub213sd    , VexRvm             , V(660F38,AF,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4947, 324, 130, 0 ),
+    1121             :   INST(Vfnmsub213ss    , VexRvm             , V(660F38,AF,_,I,0,0,2,T1S), 0                         , 0 , 0 , 4960, 325, 130, 0 ),
+    1122             :   INST(Vfnmsub231pd    , VexRvm_Lx          , V(660F38,BE,_,x,1,1,4,FV ), 0                         , 0 , 0 , 4973, 322, 129, 0 ),
+    1123             :   INST(Vfnmsub231ps    , VexRvm_Lx          , V(660F38,BE,_,x,0,0,4,FV ), 0                         , 0 , 0 , 4986, 323, 129, 0 ),
+    1124             :   INST(Vfnmsub231sd    , VexRvm             , V(660F38,BF,_,I,1,1,3,T1S), 0                         , 0 , 0 , 4999, 324, 130, 0 ),
+    1125             :   INST(Vfnmsub231ss    , VexRvm             , V(660F38,BF,_,I,0,0,2,T1S), 0                         , 0 , 0 , 5012, 325, 130, 0 ),
+    1126             :   INST(Vfnmsubpd       , Fma4_Lx            , V(660F3A,7D,_,x,x,_,_,_  ), 0                         , 0 , 0 , 5025, 326, 131, 0 ),
+    1127             :   INST(Vfnmsubps       , Fma4_Lx            , V(660F3A,7C,_,x,x,_,_,_  ), 0                         , 0 , 0 , 5035, 326, 131, 0 ),
+    1128             :   INST(Vfnmsubsd       , Fma4               , V(660F3A,7F,_,0,x,_,_,_  ), 0                         , 0 , 0 , 5045, 327, 131, 0 ),
+    1129             :   INST(Vfnmsubss       , Fma4               , V(660F3A,7E,_,0,x,_,_,_  ), 0                         , 0 , 0 , 5055, 328, 131, 0 ),
+    1130             :   INST(Vfpclasspd      , VexRmi_Lx          , V(660F3A,66,_,x,_,1,4,FV ), 0                         , 0 , 0 , 5065, 329, 123, 0 ),
+    1131             :   INST(Vfpclassps      , VexRmi_Lx          , V(660F3A,66,_,x,_,0,4,FV ), 0                         , 0 , 0 , 5076, 330, 123, 0 ),
+    1132             :   INST(Vfpclasssd      , VexRmi_Lx          , V(660F3A,67,_,I,_,1,3,T1S), 0                         , 0 , 0 , 5087, 331, 63 , 0 ),
+    1133             :   INST(Vfpclassss      , VexRmi_Lx          , V(660F3A,67,_,I,_,0,2,T1S), 0                         , 0 , 0 , 5098, 332, 63 , 0 ),
+    1134             :   INST(Vfrczpd         , VexRm_Lx           , V(XOP_M9,81,_,x,0,_,_,_  ), 0                         , 0 , 0 , 5109, 333, 132, 0 ),
+    1135             :   INST(Vfrczps         , VexRm_Lx           , V(XOP_M9,80,_,x,0,_,_,_  ), 0                         , 0 , 0 , 5117, 333, 132, 0 ),
+    1136             :   INST(Vfrczsd         , VexRm              , V(XOP_M9,83,_,0,0,_,_,_  ), 0                         , 0 , 0 , 5125, 334, 132, 0 ),
+    1137             :   INST(Vfrczss         , VexRm              , V(XOP_M9,82,_,0,0,_,_,_  ), 0                         , 0 , 0 , 5133, 335, 132, 0 ),
+    1138             :   INST(Vgatherdpd      , VexRmvRm_VM        , V(660F38,92,_,x,1,_,_,_  ), V(660F38,92,_,x,_,1,3,T1S), 0 , 0 , 5141, 336, 133, 0 ),
+    1139             :   INST(Vgatherdps      , VexRmvRm_VM        , V(660F38,92,_,x,0,_,_,_  ), V(660F38,92,_,x,_,0,2,T1S), 0 , 0 , 5152, 337, 133, 0 ),
+    1140             :   INST(Vgatherpf0dpd   , VexM_VM            , V(660F38,C6,1,2,_,1,3,T1S), 0                         , 0 , 0 , 5163, 338, 134, 0 ),
+    1141             :   INST(Vgatherpf0dps   , VexM_VM            , V(660F38,C6,1,2,_,0,2,T1S), 0                         , 0 , 0 , 5177, 339, 134, 0 ),
+    1142             :   INST(Vgatherpf0qpd   , VexM_VM            , V(660F38,C7,1,2,_,1,3,T1S), 0                         , 0 , 0 , 5191, 340, 134, 0 ),
+    1143             :   INST(Vgatherpf0qps   , VexM_VM            , V(660F38,C7,1,2,_,0,2,T1S), 0                         , 0 , 0 , 5205, 340, 134, 0 ),
+    1144             :   INST(Vgatherpf1dpd   , VexM_VM            , V(660F38,C6,2,2,_,1,3,T1S), 0                         , 0 , 0 , 5219, 338, 134, 0 ),
+    1145             :   INST(Vgatherpf1dps   , VexM_VM            , V(660F38,C6,2,2,_,0,2,T1S), 0                         , 0 , 0 , 5233, 339, 134, 0 ),
+    1146             :   INST(Vgatherpf1qpd   , VexM_VM            , V(660F38,C7,2,2,_,1,3,T1S), 0                         , 0 , 0 , 5247, 340, 134, 0 ),
+    1147             :   INST(Vgatherpf1qps   , VexM_VM            , V(660F38,C7,2,2,_,0,2,T1S), 0                         , 0 , 0 , 5261, 340, 134, 0 ),
+    1148             :   INST(Vgatherqpd      , VexRmvRm_VM        , V(660F38,93,_,x,1,_,_,_  ), V(660F38,93,_,x,_,1,3,T1S), 0 , 0 , 5275, 341, 133, 0 ),
+    1149             :   INST(Vgatherqps      , VexRmvRm_VM        , V(660F38,93,_,x,0,_,_,_  ), V(660F38,93,_,x,_,0,2,T1S), 0 , 0 , 5286, 342, 133, 0 ),
+    1150             :   INST(Vgetexppd       , VexRm_Lx           , V(660F38,42,_,x,_,1,4,FV ), 0                         , 0 , 0 , 5297, 298, 120, 0 ),
+    1151             :   INST(Vgetexpps       , VexRm_Lx           , V(660F38,42,_,x,_,0,4,FV ), 0                         , 0 , 0 , 5307, 302, 120, 0 ),
+    1152             :   INST(Vgetexpsd       , VexRm              , V(660F38,43,_,I,_,1,3,T1S), 0                         , 0 , 0 , 5317, 343, 65 , 0 ),
+    1153             :   INST(Vgetexpss       , VexRm              , V(660F38,43,_,I,_,0,2,T1S), 0                         , 0 , 0 , 5327, 344, 65 , 0 ),
+    1154             :   INST(Vgetmantpd      , VexRmi_Lx          , V(660F3A,26,_,x,_,1,4,FV ), 0                         , 0 , 0 , 5337, 345, 120, 0 ),
+    1155             :   INST(Vgetmantps      , VexRmi_Lx          , V(660F3A,26,_,x,_,0,4,FV ), 0                         , 0 , 0 , 5348, 346, 120, 0 ),
+    1156             :   INST(Vgetmantsd      , VexRmi             , V(660F3A,27,_,I,_,1,3,T1S), 0                         , 0 , 0 , 5359, 347, 65 , 0 ),
+    1157             :   INST(Vgetmantss      , VexRmi             , V(660F3A,27,_,I,_,0,2,T1S), 0                         , 0 , 0 , 5370, 348, 65 , 0 ),
+    1158             :   INST(Vhaddpd         , VexRvm_Lx          , V(660F00,7C,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5381, 250, 118, 21),
+    1159             :   INST(Vhaddps         , VexRvm_Lx          , V(F20F00,7C,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5389, 250, 118, 21),
+    1160             :   INST(Vhsubpd         , VexRvm_Lx          , V(660F00,7D,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5397, 250, 118, 22),
+    1161             :   INST(Vhsubps         , VexRvm_Lx          , V(F20F00,7D,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5405, 250, 118, 22),
+    1162             :   INST(Vinsertf128     , VexRvmi            , V(660F3A,18,_,1,0,_,_,_  ), 0                         , 0 , 0 , 5413, 349, 118, 0 ),
+    1163             :   INST(Vinsertf32x4    , VexRvmi_Lx         , V(660F3A,18,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 5425, 350, 120, 0 ),
+    1164             :   INST(Vinsertf32x8    , VexRvmi            , V(660F3A,1A,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 5438, 351, 63 , 0 ),
+    1165             :   INST(Vinsertf64x2    , VexRvmi_Lx         , V(660F3A,18,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 5451, 350, 123, 0 ),
+    1166             :   INST(Vinsertf64x4    , VexRvmi            , V(660F3A,1A,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 5464, 351, 65 , 0 ),
+    1167             :   INST(Vinserti128     , VexRvmi            , V(660F3A,38,_,1,0,_,_,_  ), 0                         , 0 , 0 , 5477, 349, 124, 0 ),
+    1168             :   INST(Vinserti32x4    , VexRvmi_Lx         , V(660F3A,38,_,x,_,0,4,T4 ), 0                         , 0 , 0 , 5489, 350, 120, 0 ),
+    1169             :   INST(Vinserti32x8    , VexRvmi            , V(660F3A,3A,_,2,_,0,5,T8 ), 0                         , 0 , 0 , 5502, 351, 63 , 0 ),
+    1170             :   INST(Vinserti64x2    , VexRvmi_Lx         , V(660F3A,38,_,x,_,1,4,T2 ), 0                         , 0 , 0 , 5515, 350, 123, 0 ),
+    1171             :   INST(Vinserti64x4    , VexRvmi            , V(660F3A,3A,_,2,_,1,5,T4 ), 0                         , 0 , 0 , 5528, 351, 65 , 0 ),
+    1172             :   INST(Vinsertps       , VexRvmi            , V(660F3A,21,_,0,I,0,2,T1S), 0                         , 0 , 0 , 5541, 352, 117, 23),
+    1173             :   INST(Vlddqu          , VexRm_Lx           , V(F20F00,F0,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5551, 353, 118, 24),
+    1174             :   INST(Vldmxcsr        , VexM               , V(000F00,AE,2,0,I,_,_,_  ), 0                         , 0 , 0 , 5558, 354, 118, 0 ),
+    1175             :   INST(Vmaskmovdqu     , VexRm_ZDI          , V(660F00,F7,_,0,I,_,_,_  ), 0                         , 0 , 0 , 5567, 355, 118, 25),
+    1176             :   INST(Vmaskmovpd      , VexRvmMvr_Lx       , V(660F38,2D,_,x,0,_,_,_  ), V(660F38,2F,_,x,0,_,_,_  ), 0 , 0 , 5579, 356, 118, 0 ),
+    1177             :   INST(Vmaskmovps      , VexRvmMvr_Lx       , V(660F38,2C,_,x,0,_,_,_  ), V(660F38,2E,_,x,0,_,_,_  ), 0 , 0 , 5590, 357, 118, 0 ),
+    1178             :   INST(Vmaxpd          , VexRvm_Lx          , V(660F00,5F,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5601, 358, 116, 26),
+    1179             :   INST(Vmaxps          , VexRvm_Lx          , V(000F00,5F,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5608, 359, 116, 26),
+    1180             :   INST(Vmaxsd          , VexRvm             , V(F20F00,5F,_,I,I,1,3,T1S), 0                         , 0 , 0 , 5615, 360, 116, 26),
+    1181             :   INST(Vmaxss          , VexRvm             , V(F30F00,5F,_,I,I,0,2,T1S), 0                         , 0 , 0 , 5622, 294, 116, 26),
+    1182             :   INST(Vminpd          , VexRvm_Lx          , V(660F00,5D,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5629, 358, 116, 27),
+    1183             :   INST(Vminps          , VexRvm_Lx          , V(000F00,5D,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5636, 359, 116, 27),
+    1184             :   INST(Vminsd          , VexRvm             , V(F20F00,5D,_,I,I,1,3,T1S), 0                         , 0 , 0 , 5643, 360, 116, 27),
+    1185             :   INST(Vminss          , VexRvm             , V(F30F00,5D,_,I,I,0,2,T1S), 0                         , 0 , 0 , 5650, 294, 116, 27),
+    1186             :   INST(Vmovapd         , VexRmMr_Lx         , V(660F00,28,_,x,I,1,4,FVM), V(660F00,29,_,x,I,1,4,FVM), 0 , 0 , 5657, 361, 116, 28),
+    1187             :   INST(Vmovaps         , VexRmMr_Lx         , V(000F00,28,_,x,I,0,4,FVM), V(000F00,29,_,x,I,0,4,FVM), 0 , 0 , 5665, 362, 116, 28),
+    1188             :   INST(Vmovd           , VexMovdMovq        , V(660F00,6E,_,0,0,0,2,T1S), V(660F00,7E,_,0,0,0,2,T1S), 0 , 0 , 5673, 363, 117, 29),
+    1189             :   INST(Vmovddup        , VexRm_Lx           , V(F20F00,12,_,x,I,1,3,DUP), 0                         , 0 , 0 , 5679, 364, 116, 29),
+    1190             :   INST(Vmovdqa         , VexRmMr_Lx         , V(660F00,6F,_,x,I,_,_,_  ), V(660F00,7F,_,x,I,_,_,_  ), 0 , 0 , 5688, 365, 118, 30),
+    1191             :   INST(Vmovdqa32       , VexRmMr_Lx         , V(660F00,6F,_,x,_,0,4,FVM), V(660F00,7F,_,x,_,0,4,FVM), 0 , 0 , 5696, 366, 120, 0 ),
+    1192             :   INST(Vmovdqa64       , VexRmMr_Lx         , V(660F00,6F,_,x,_,1,4,FVM), V(660F00,7F,_,x,_,1,4,FVM), 0 , 0 , 5706, 367, 120, 0 ),
+    1193             :   INST(Vmovdqu         , VexRmMr_Lx         , V(F30F00,6F,_,x,I,_,_,_  ), V(F30F00,7F,_,x,I,_,_,_  ), 0 , 0 , 5716, 368, 118, 28),
+    1194             :   INST(Vmovdqu16       , VexRmMr_Lx         , V(F20F00,6F,_,x,_,1,4,FVM), V(F20F00,7F,_,x,_,1,4,FVM), 0 , 0 , 5724, 369, 122, 0 ),
+    1195             :   INST(Vmovdqu32       , VexRmMr_Lx         , V(F30F00,6F,_,x,_,0,4,FVM), V(F30F00,7F,_,x,_,0,4,FVM), 0 , 0 , 5734, 370, 120, 0 ),
+    1196             :   INST(Vmovdqu64       , VexRmMr_Lx         , V(F30F00,6F,_,x,_,1,4,FVM), V(F30F00,7F,_,x,_,1,4,FVM), 0 , 0 , 5744, 371, 120, 0 ),
+    1197             :   INST(Vmovdqu8        , VexRmMr_Lx         , V(F20F00,6F,_,x,_,0,4,FVM), V(F20F00,7F,_,x,_,0,4,FVM), 0 , 0 , 5754, 372, 122, 0 ),
+    1198             :   INST(Vmovhlps        , VexRvm             , V(000F00,12,_,0,I,0,_,_  ), 0                         , 0 , 0 , 5763, 373, 117, 31),
+    1199             :   INST(Vmovhpd         , VexRvmMr           , V(660F00,16,_,0,I,1,3,T1S), V(660F00,17,_,0,I,1,3,T1S), 0 , 0 , 5772, 374, 117, 32),
+    1200             :   INST(Vmovhps         , VexRvmMr           , V(000F00,16,_,0,I,0,3,T2 ), V(000F00,17,_,0,I,0,3,T2 ), 0 , 0 , 5780, 375, 117, 32),
+    1201             :   INST(Vmovlhps        , VexRvm             , V(000F00,16,_,0,I,0,_,_  ), 0                         , 0 , 0 , 5788, 373, 117, 31),
+    1202             :   INST(Vmovlpd         , VexRvmMr           , V(660F00,12,_,0,I,1,3,T1S), V(660F00,13,_,0,I,1,3,T1S), 0 , 0 , 5797, 376, 117, 32),
+    1203             :   INST(Vmovlps         , VexRvmMr           , V(000F00,12,_,0,I,0,3,T2 ), V(000F00,13,_,0,I,0,3,T2 ), 0 , 0 , 5805, 377, 117, 32),
+    1204             :   INST(Vmovmskpd       , VexRm_Lx           , V(660F00,50,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5813, 378, 118, 33),
+    1205             :   INST(Vmovmskps       , VexRm_Lx           , V(000F00,50,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5823, 378, 118, 33),
+    1206             :   INST(Vmovntdq        , VexMr_Lx           , V(660F00,E7,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5833, 379, 116, 33),
+    1207             :   INST(Vmovntdqa       , VexRm_Lx           , V(660F38,2A,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5842, 380, 125, 33),
+    1208             :   INST(Vmovntpd        , VexMr_Lx           , V(660F00,2B,_,x,I,1,4,FVM), 0                         , 0 , 0 , 5852, 379, 116, 34),
+    1209             :   INST(Vmovntps        , VexMr_Lx           , V(000F00,2B,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5861, 379, 116, 34),
+    1210             :   INST(Vmovq           , VexMovdMovq        , V(660F00,6E,_,0,I,1,3,T1S), V(660F00,7E,_,0,I,1,3,T1S), 0 , 0 , 5870, 381, 117, 28),
+    1211             :   INST(Vmovsd          , VexMovssMovsd      , V(F20F00,10,_,I,I,1,3,T1S), V(F20F00,11,_,I,I,1,3,T1S), 0 , 0 , 5876, 382, 117, 35),
+    1212             :   INST(Vmovshdup       , VexRm_Lx           , V(F30F00,16,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5883, 383, 116, 30),
+    1213             :   INST(Vmovsldup       , VexRm_Lx           , V(F30F00,12,_,x,I,0,4,FVM), 0                         , 0 , 0 , 5893, 383, 116, 30),
+    1214             :   INST(Vmovss          , VexMovssMovsd      , V(F30F00,10,_,I,I,0,2,T1S), V(F30F00,11,_,I,I,0,2,T1S), 0 , 0 , 5903, 384, 117, 35),
+    1215             :   INST(Vmovupd         , VexRmMr_Lx         , V(660F00,10,_,x,I,1,4,FVM), V(660F00,11,_,x,I,1,4,FVM), 0 , 0 , 5910, 385, 116, 36),
+    1216             :   INST(Vmovups         , VexRmMr_Lx         , V(000F00,10,_,x,I,0,4,FVM), V(000F00,11,_,x,I,0,4,FVM), 0 , 0 , 5918, 386, 116, 36),
+    1217             :   INST(Vmpsadbw        , VexRvmi_Lx         , V(660F3A,42,_,x,I,_,_,_  ), 0                         , 0 , 0 , 5926, 263, 135, 37),
+    1218             :   INST(Vmulpd          , VexRvm_Lx          , V(660F00,59,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5935, 246, 116, 38),
+    1219             :   INST(Vmulps          , VexRvm_Lx          , V(000F00,59,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5942, 247, 116, 38),
+    1220             :   INST(Vmulsd          , VexRvm_Lx          , V(F20F00,59,_,I,I,1,3,T1S), 0                         , 0 , 0 , 5949, 248, 117, 38),
+    1221             :   INST(Vmulss          , VexRvm_Lx          , V(F30F00,59,_,I,I,0,2,T1S), 0                         , 0 , 0 , 5956, 249, 117, 38),
+    1222             :   INST(Vorpd           , VexRvm_Lx          , V(660F00,56,_,x,I,1,4,FV ), 0                         , 0 , 0 , 5963, 258, 121, 39),
+    1223             :   INST(Vorps           , VexRvm_Lx          , V(000F00,56,_,x,I,0,4,FV ), 0                         , 0 , 0 , 5969, 259, 116, 39),
+    1224             :   INST(Vp4dpwssd       , VexRm_T1_4X        , V(F20F38,52,_,2,_,0,2,T4X), 0                         , 0 , 0 , 5975, 387, 136, 0 ),
+    1225             :   INST(Vp4dpwssds      , VexRm_T1_4X        , V(F20F38,53,_,2,_,0,2,T4X), 0                         , 0 , 0 , 5985, 387, 136, 0 ),
+    1226             :   INST(Vpabsb          , VexRm_Lx           , V(660F38,1C,_,x,I,_,4,FVM), 0                         , 0 , 0 , 5996, 383, 137, 40),
+    1227             :   INST(Vpabsd          , VexRm_Lx           , V(660F38,1E,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6003, 383, 125, 40),
+    1228             :   INST(Vpabsq          , VexRm_Lx           , V(660F38,1F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6010, 313, 120, 0 ),
+    1229             :   INST(Vpabsw          , VexRm_Lx           , V(660F38,1D,_,x,I,_,4,FVM), 0                         , 0 , 0 , 6017, 383, 137, 41),
+    1230             :   INST(Vpackssdw       , VexRvm_Lx          , V(660F00,6B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6024, 257, 137, 42),
+    1231             :   INST(Vpacksswb       , VexRvm_Lx          , V(660F00,63,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6034, 388, 137, 42),
+    1232             :   INST(Vpackusdw       , VexRvm_Lx          , V(660F38,2B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6044, 257, 137, 42),
+    1233             :   INST(Vpackuswb       , VexRvm_Lx          , V(660F00,67,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6054, 388, 137, 42),
+    1234             :   INST(Vpaddb          , VexRvm_Lx          , V(660F00,FC,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6064, 388, 137, 42),
+    1235             :   INST(Vpaddd          , VexRvm_Lx          , V(660F00,FE,_,x,I,0,4,FV ), 0                         , 0 , 0 , 6071, 257, 125, 42),
+    1236             :   INST(Vpaddq          , VexRvm_Lx          , V(660F00,D4,_,x,I,1,4,FV ), 0                         , 0 , 0 , 6078, 256, 125, 42),
+    1237             :   INST(Vpaddsb         , VexRvm_Lx          , V(660F00,EC,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6085, 388, 137, 42),
+    1238             :   INST(Vpaddsw         , VexRvm_Lx          , V(660F00,ED,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6093, 388, 137, 42),
+    1239             :   INST(Vpaddusb        , VexRvm_Lx          , V(660F00,DC,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6101, 388, 137, 42),
+    1240             :   INST(Vpaddusw        , VexRvm_Lx          , V(660F00,DD,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6110, 388, 137, 42),
+    1241             :   INST(Vpaddw          , VexRvm_Lx          , V(660F00,FD,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6119, 388, 137, 42),
+    1242             :   INST(Vpalignr        , VexRvmi_Lx         , V(660F3A,0F,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6126, 389, 137, 42),
+    1243             :   INST(Vpand           , VexRvm_Lx          , V(660F00,DB,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6135, 390, 135, 42),
+    1244             :   INST(Vpandd          , VexRvm_Lx          , V(660F00,DB,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6141, 391, 120, 0 ),
+    1245             :   INST(Vpandn          , VexRvm_Lx          , V(660F00,DF,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6148, 392, 135, 43),
+    1246             :   INST(Vpandnd         , VexRvm_Lx          , V(660F00,DF,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6155, 393, 120, 0 ),
+    1247             :   INST(Vpandnq         , VexRvm_Lx          , V(660F00,DF,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6163, 394, 120, 0 ),
+    1248             :   INST(Vpandq          , VexRvm_Lx          , V(660F00,DB,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6171, 395, 120, 0 ),
+    1249             :   INST(Vpavgb          , VexRvm_Lx          , V(660F00,E0,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6178, 388, 137, 44),
+    1250             :   INST(Vpavgw          , VexRvm_Lx          , V(660F00,E3,_,x,I,I,4,FVM), 0                         , 0 , 0 , 6185, 388, 137, 45),
+    1251             :   INST(Vpblendd        , VexRvmi_Lx         , V(660F3A,02,_,x,0,_,_,_  ), 0                         , 0 , 0 , 6192, 263, 124, 0 ),
+    1252             :   INST(Vpblendvb       , VexRvmr            , V(660F3A,4C,_,x,0,_,_,_  ), 0                         , 0 , 0 , 6201, 264, 135, 46),
+    1253             :   INST(Vpblendw        , VexRvmi_Lx         , V(660F3A,0E,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6211, 263, 135, 44),
+    1254             :   INST(Vpbroadcastb    , VexRm_Lx           , V(660F38,78,_,x,0,0,0,T1S), 0                         , 0 , 0 , 6220, 396, 138, 0 ),
+    1255             :   INST(Vpbroadcastd    , VexRm_Lx           , V(660F38,58,_,x,0,0,2,T1S), 0                         , 0 , 0 , 6233, 397, 133, 0 ),
+    1256             :   INST(Vpbroadcastmb2d , VexRm_Lx           , V(F30F38,3A,_,x,_,0,_,_  ), 0                         , 0 , 0 , 6246, 398, 139, 0 ),
+    1257             :   INST(Vpbroadcastmb2q , VexRm_Lx           , V(F30F38,2A,_,x,_,1,_,_  ), 0                         , 0 , 0 , 6262, 398, 139, 0 ),
+    1258             :   INST(Vpbroadcastq    , VexRm_Lx           , V(660F38,59,_,x,0,1,3,T1S), 0                         , 0 , 0 , 6278, 399, 133, 0 ),
+    1259             :   INST(Vpbroadcastw    , VexRm_Lx           , V(660F38,79,_,x,0,0,1,T1S), 0                         , 0 , 0 , 6291, 400, 138, 0 ),
+    1260             :   INST(Vpclmulqdq      , VexRvmi            , V(660F3A,44,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6304, 310, 140, 47),
+    1261             :   INST(Vpcmov          , VexRvrmRvmr_Lx     , V(XOP_M8,A2,_,x,x,_,_,_  ), 0                         , 0 , 0 , 6315, 326, 132, 0 ),
+    1262             :   INST(Vpcmpb          , VexRvmi_Lx         , V(660F3A,3F,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6322, 401, 122, 0 ),
+    1263             :   INST(Vpcmpd          , VexRvmi_Lx         , V(660F3A,1F,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6329, 402, 120, 0 ),
+    1264             :   INST(Vpcmpeqb        , VexRvm_Lx          , V(660F00,74,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6336, 403, 137, 48),
+    1265             :   INST(Vpcmpeqd        , VexRvm_Lx          , V(660F00,76,_,x,I,0,4,FVM), 0                         , 0 , 0 , 6345, 404, 125, 48),
+    1266             :   INST(Vpcmpeqq        , VexRvm_Lx          , V(660F38,29,_,x,I,1,4,FVM), 0                         , 0 , 0 , 6354, 405, 125, 48),
+    1267             :   INST(Vpcmpeqw        , VexRvm_Lx          , V(660F00,75,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6363, 403, 137, 48),
+    1268             :   INST(Vpcmpestri      , VexRmi             , V(660F3A,61,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6372, 406, 141, 49),
+    1269             :   INST(Vpcmpestrm      , VexRmi             , V(660F3A,60,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6383, 407, 141, 49),
+    1270             :   INST(Vpcmpgtb        , VexRvm_Lx          , V(660F00,64,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6394, 403, 137, 48),
+    1271             :   INST(Vpcmpgtd        , VexRvm_Lx          , V(660F00,66,_,x,I,0,4,FVM), 0                         , 0 , 0 , 6403, 404, 125, 48),
+    1272             :   INST(Vpcmpgtq        , VexRvm_Lx          , V(660F38,37,_,x,I,1,4,FVM), 0                         , 0 , 0 , 6412, 405, 125, 48),
+    1273             :   INST(Vpcmpgtw        , VexRvm_Lx          , V(660F00,65,_,x,I,I,4,FV ), 0                         , 0 , 0 , 6421, 403, 137, 48),
+    1274             :   INST(Vpcmpistri      , VexRmi             , V(660F3A,63,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6430, 408, 141, 49),
+    1275             :   INST(Vpcmpistrm      , VexRmi             , V(660F3A,62,_,0,I,_,_,_  ), 0                         , 0 , 0 , 6441, 409, 141, 49),
+    1276             :   INST(Vpcmpq          , VexRvmi_Lx         , V(660F3A,1F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6452, 410, 120, 0 ),
+    1277             :   INST(Vpcmpub         , VexRvmi_Lx         , V(660F3A,3E,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6459, 401, 122, 0 ),
+    1278             :   INST(Vpcmpud         , VexRvmi_Lx         , V(660F3A,1E,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6467, 402, 120, 0 ),
+    1279             :   INST(Vpcmpuq         , VexRvmi_Lx         , V(660F3A,1E,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6475, 410, 120, 0 ),
+    1280             :   INST(Vpcmpuw         , VexRvmi_Lx         , V(660F3A,3E,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6483, 410, 122, 0 ),
+    1281             :   INST(Vpcmpw          , VexRvmi_Lx         , V(660F3A,3F,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6491, 410, 122, 0 ),
+    1282             :   INST(Vpcomb          , VexRvmi            , V(XOP_M8,CC,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6498, 310, 132, 0 ),
+    1283             :   INST(Vpcomd          , VexRvmi            , V(XOP_M8,CE,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6505, 310, 132, 0 ),
+    1284             :   INST(Vpcompressd     , VexMr_Lx           , V(660F38,8B,_,x,_,0,2,T1S), 0                         , 0 , 0 , 6512, 279, 120, 0 ),
+    1285             :   INST(Vpcompressq     , VexMr_Lx           , V(660F38,8B,_,x,_,1,3,T1S), 0                         , 0 , 0 , 6524, 279, 120, 0 ),
+    1286             :   INST(Vpcomq          , VexRvmi            , V(XOP_M8,CF,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6536, 310, 132, 0 ),
+    1287             :   INST(Vpcomub         , VexRvmi            , V(XOP_M8,EC,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6543, 310, 132, 0 ),
+    1288             :   INST(Vpcomud         , VexRvmi            , V(XOP_M8,EE,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6551, 310, 132, 0 ),
+    1289             :   INST(Vpcomuq         , VexRvmi            , V(XOP_M8,EF,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6559, 310, 132, 0 ),
+    1290             :   INST(Vpcomuw         , VexRvmi            , V(XOP_M8,ED,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6567, 310, 132, 0 ),
+    1291             :   INST(Vpcomw          , VexRvmi            , V(XOP_M8,CD,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6575, 310, 132, 0 ),
+    1292             :   INST(Vpconflictd     , VexRm_Lx           , V(660F38,C4,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6582, 411, 139, 0 ),
+    1293             :   INST(Vpconflictq     , VexRm_Lx           , V(660F38,C4,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6594, 411, 139, 0 ),
+    1294             :   INST(Vperm2f128      , VexRvmi            , V(660F3A,06,_,1,0,_,_,_  ), 0                         , 0 , 0 , 6606, 412, 118, 0 ),
+    1295             :   INST(Vperm2i128      , VexRvmi            , V(660F3A,46,_,1,0,_,_,_  ), 0                         , 0 , 0 , 6617, 412, 124, 0 ),
+    1296             :   INST(Vpermb          , VexRvm_Lx          , V(660F38,8D,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6628, 260, 142, 0 ),
+    1297             :   INST(Vpermd          , VexRvm_Lx          , V(660F38,36,_,x,0,0,4,FV ), 0                         , 0 , 0 , 6635, 413, 133, 0 ),
+    1298             :   INST(Vpermi2b        , VexRvm_Lx          , V(660F38,75,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6642, 260, 142, 0 ),
+    1299             :   INST(Vpermi2d        , VexRvm_Lx          , V(660F38,76,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6651, 414, 120, 0 ),
+    1300             :   INST(Vpermi2pd       , VexRvm_Lx          , V(660F38,77,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6660, 262, 120, 0 ),
+    1301             :   INST(Vpermi2ps       , VexRvm_Lx          , V(660F38,77,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6670, 261, 120, 0 ),
+    1302             :   INST(Vpermi2q        , VexRvm_Lx          , V(660F38,76,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6680, 415, 120, 0 ),
+    1303             :   INST(Vpermi2w        , VexRvm_Lx          , V(660F38,75,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6689, 416, 122, 0 ),
+    1304             :   INST(Vpermil2pd      , VexRvrmiRvmri_Lx   , V(660F3A,49,_,x,x,_,_,_  ), 0                         , 0 , 0 , 6698, 417, 132, 0 ),
+    1305             :   INST(Vpermil2ps      , VexRvrmiRvmri_Lx   , V(660F3A,48,_,x,x,_,_,_  ), 0                         , 0 , 0 , 6709, 417, 132, 0 ),
+    1306             :   INST(Vpermilpd       , VexRvmRmi_Lx       , V(660F38,0D,_,x,0,1,4,FV ), V(660F3A,05,_,x,0,1,4,FV ), 0 , 0 , 6720, 418, 116, 0 ),
+    1307             :   INST(Vpermilps       , VexRvmRmi_Lx       , V(660F38,0C,_,x,0,0,4,FV ), V(660F3A,04,_,x,0,0,4,FV ), 0 , 0 , 6730, 419, 116, 0 ),
+    1308             :   INST(Vpermpd         , VexRmi             , V(660F3A,01,_,1,1,_,_,_  ), 0                         , 0 , 0 , 6740, 420, 124, 0 ),
+    1309             :   INST(Vpermps         , VexRvm             , V(660F38,16,_,1,0,_,_,_  ), 0                         , 0 , 0 , 6748, 421, 124, 0 ),
+    1310             :   INST(Vpermq          , VexRvmRmi_Lx       , V(660F38,36,_,x,_,1,4,FV ), V(660F3A,00,_,x,1,1,4,FV ), 0 , 0 , 6756, 422, 133, 0 ),
+    1311             :   INST(Vpermt2b        , VexRvm_Lx          , V(660F38,7D,_,x,_,0,4,FVM), 0                         , 0 , 0 , 6763, 260, 142, 0 ),
+    1312             :   INST(Vpermt2d        , VexRvm_Lx          , V(660F38,7E,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6772, 414, 120, 0 ),
+    1313             :   INST(Vpermt2pd       , VexRvm_Lx          , V(660F38,7F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6781, 415, 120, 0 ),
+    1314             :   INST(Vpermt2ps       , VexRvm_Lx          , V(660F38,7F,_,x,_,0,4,FV ), 0                         , 0 , 0 , 6791, 414, 120, 0 ),
+    1315             :   INST(Vpermt2q        , VexRvm_Lx          , V(660F38,7E,_,x,_,1,4,FV ), 0                         , 0 , 0 , 6801, 415, 120, 0 ),
+    1316             :   INST(Vpermt2w        , VexRvm_Lx          , V(660F38,7D,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6810, 416, 122, 0 ),
+    1317             :   INST(Vpermw          , VexRvm_Lx          , V(660F38,8D,_,x,_,1,4,FVM), 0                         , 0 , 0 , 6819, 260, 122, 0 ),
+    1318             :   INST(Vpexpandd       , VexRm_Lx           , V(660F38,89,_,x,_,0,2,T1S), 0                         , 0 , 0 , 6826, 313, 120, 0 ),
+    1319             :   INST(Vpexpandq       , VexRm_Lx           , V(660F38,89,_,x,_,1,3,T1S), 0                         , 0 , 0 , 6836, 313, 120, 0 ),
+    1320             :   INST(Vpextrb         , VexMri             , V(660F3A,14,_,0,0,I,0,T1S), 0                         , 0 , 0 , 6846, 423, 143, 50),
+    1321             :   INST(Vpextrd         , VexMri             , V(660F3A,16,_,0,0,0,2,T1S), 0                         , 0 , 0 , 6854, 317, 144, 50),
+    1322             :   INST(Vpextrq         , VexMri             , V(660F3A,16,_,0,1,1,3,T1S), 0                         , 0 , 0 , 6862, 424, 144, 50),
+    1323             :   INST(Vpextrw         , VexMri             , V(660F3A,15,_,0,0,I,1,T1S), 0                         , 0 , 0 , 6870, 425, 143, 50),
+    1324             :   INST(Vpgatherdd      , VexRmvRm_VM        , V(660F38,90,_,x,0,_,_,_  ), V(660F38,90,_,x,_,0,2,T1S), 0 , 0 , 6878, 426, 133, 0 ),
+    1325             :   INST(Vpgatherdq      , VexRmvRm_VM        , V(660F38,90,_,x,1,_,_,_  ), V(660F38,90,_,x,_,1,3,T1S), 0 , 0 , 6889, 427, 133, 0 ),
+    1326             :   INST(Vpgatherqd      , VexRmvRm_VM        , V(660F38,91,_,x,0,_,_,_  ), V(660F38,91,_,x,_,0,2,T1S), 0 , 0 , 6900, 428, 133, 0 ),
+    1327             :   INST(Vpgatherqq      , VexRmvRm_VM        , V(660F38,91,_,x,1,_,_,_  ), V(660F38,91,_,x,_,1,3,T1S), 0 , 0 , 6911, 429, 133, 0 ),
+    1328             :   INST(Vphaddbd        , VexRm              , V(XOP_M9,C2,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6922, 252, 132, 0 ),
+    1329             :   INST(Vphaddbq        , VexRm              , V(XOP_M9,C3,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6931, 252, 132, 0 ),
+    1330             :   INST(Vphaddbw        , VexRm              , V(XOP_M9,C1,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6940, 252, 132, 0 ),
+    1331             :   INST(Vphaddd         , VexRvm_Lx          , V(660F38,02,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6949, 250, 135, 51),
+    1332             :   INST(Vphadddq        , VexRm              , V(XOP_M9,CB,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6957, 252, 132, 0 ),
+    1333             :   INST(Vphaddsw        , VexRvm_Lx          , V(660F38,03,_,x,I,_,_,_  ), 0                         , 0 , 0 , 6966, 250, 135, 52),
+    1334             :   INST(Vphaddubd       , VexRm              , V(XOP_M9,D2,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6975, 252, 132, 0 ),
+    1335             :   INST(Vphaddubq       , VexRm              , V(XOP_M9,D3,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6985, 252, 132, 0 ),
+    1336             :   INST(Vphaddubw       , VexRm              , V(XOP_M9,D1,_,0,0,_,_,_  ), 0                         , 0 , 0 , 6995, 252, 132, 0 ),
+    1337             :   INST(Vphaddudq       , VexRm              , V(XOP_M9,DB,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7005, 252, 132, 0 ),
+    1338             :   INST(Vphadduwd       , VexRm              , V(XOP_M9,D6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7015, 252, 132, 0 ),
+    1339             :   INST(Vphadduwq       , VexRm              , V(XOP_M9,D7,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7025, 252, 132, 0 ),
+    1340             :   INST(Vphaddw         , VexRvm_Lx          , V(660F38,01,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7035, 250, 135, 53),
+    1341             :   INST(Vphaddwd        , VexRm              , V(XOP_M9,C6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7043, 252, 132, 0 ),
+    1342             :   INST(Vphaddwq        , VexRm              , V(XOP_M9,C7,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7052, 252, 132, 0 ),
+    1343             :   INST(Vphminposuw     , VexRm              , V(660F38,41,_,0,I,_,_,_  ), 0                         , 0 , 0 , 7061, 252, 118, 54),
+    1344             :   INST(Vphsubbw        , VexRm              , V(XOP_M9,E1,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7073, 252, 132, 0 ),
+    1345             :   INST(Vphsubd         , VexRvm_Lx          , V(660F38,06,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7082, 250, 135, 55),
+    1346             :   INST(Vphsubdq        , VexRm              , V(XOP_M9,E3,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7090, 252, 132, 0 ),
+    1347             :   INST(Vphsubsw        , VexRvm_Lx          , V(660F38,07,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7099, 250, 135, 56),
+    1348             :   INST(Vphsubw         , VexRvm_Lx          , V(660F38,05,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7108, 250, 135, 56),
+    1349             :   INST(Vphsubwd        , VexRm              , V(XOP_M9,E2,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7116, 252, 132, 0 ),
+    1350             :   INST(Vpinsrb         , VexRvmi            , V(660F3A,20,_,0,0,I,0,T1S), 0                         , 0 , 0 , 7125, 430, 143, 57),
+    1351             :   INST(Vpinsrd         , VexRvmi            , V(660F3A,22,_,0,0,0,2,T1S), 0                         , 0 , 0 , 7133, 431, 144, 57),
+    1352             :   INST(Vpinsrq         , VexRvmi            , V(660F3A,22,_,0,1,1,3,T1S), 0                         , 0 , 0 , 7141, 432, 144, 57),
+    1353             :   INST(Vpinsrw         , VexRvmi            , V(660F00,C4,_,0,0,I,1,T1S), 0                         , 0 , 0 , 7149, 433, 143, 55),
+    1354             :   INST(Vplzcntd        , VexRm_Lx           , V(660F38,44,_,x,_,0,4,FV ), 0                         , 0 , 0 , 7157, 411, 139, 0 ),
+    1355             :   INST(Vplzcntq        , VexRm_Lx           , V(660F38,44,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7166, 434, 139, 0 ),
+    1356             :   INST(Vpmacsdd        , VexRvmr            , V(XOP_M8,9E,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7175, 435, 132, 0 ),
+    1357             :   INST(Vpmacsdqh       , VexRvmr            , V(XOP_M8,9F,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7184, 435, 132, 0 ),
+    1358             :   INST(Vpmacsdql       , VexRvmr            , V(XOP_M8,97,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7194, 435, 132, 0 ),
+    1359             :   INST(Vpmacssdd       , VexRvmr            , V(XOP_M8,8E,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7204, 435, 132, 0 ),
+    1360             :   INST(Vpmacssdqh      , VexRvmr            , V(XOP_M8,8F,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7214, 435, 132, 0 ),
+    1361             :   INST(Vpmacssdql      , VexRvmr            , V(XOP_M8,87,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7225, 435, 132, 0 ),
+    1362             :   INST(Vpmacsswd       , VexRvmr            , V(XOP_M8,86,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7236, 435, 132, 0 ),
+    1363             :   INST(Vpmacssww       , VexRvmr            , V(XOP_M8,85,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7246, 435, 132, 0 ),
+    1364             :   INST(Vpmacswd        , VexRvmr            , V(XOP_M8,96,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7256, 435, 132, 0 ),
+    1365             :   INST(Vpmacsww        , VexRvmr            , V(XOP_M8,95,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7265, 435, 132, 0 ),
+    1366             :   INST(Vpmadcsswd      , VexRvmr            , V(XOP_M8,A6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7274, 435, 132, 0 ),
+    1367             :   INST(Vpmadcswd       , VexRvmr            , V(XOP_M8,B6,_,0,0,_,_,_  ), 0                         , 0 , 0 , 7285, 435, 132, 0 ),
+    1368             :   INST(Vpmadd52huq     , VexRvm_Lx          , V(660F38,B5,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7295, 262, 145, 0 ),
+    1369             :   INST(Vpmadd52luq     , VexRvm_Lx          , V(660F38,B4,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7307, 262, 145, 0 ),
+    1370             :   INST(Vpmaddubsw      , VexRvm_Lx          , V(660F38,04,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7319, 388, 137, 58),
+    1371             :   INST(Vpmaddwd        , VexRvm_Lx          , V(660F00,F5,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7330, 388, 137, 58),
+    1372             :   INST(Vpmaskmovd      , VexRvmMvr_Lx       , V(660F38,8C,_,x,0,_,_,_  ), V(660F38,8E,_,x,0,_,_,_  ), 0 , 0 , 7339, 436, 124, 0 ),
+    1373             :   INST(Vpmaskmovq      , VexRvmMvr_Lx       , V(660F38,8C,_,x,1,_,_,_  ), V(660F38,8E,_,x,1,_,_,_  ), 0 , 0 , 7350, 437, 124, 0 ),
+    1374             :   INST(Vpmaxsb         , VexRvm_Lx          , V(660F38,3C,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7361, 438, 137, 59),
+    1375             :   INST(Vpmaxsd         , VexRvm_Lx          , V(660F38,3D,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7369, 259, 125, 59),
+    1376             :   INST(Vpmaxsq         , VexRvm_Lx          , V(660F38,3D,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7377, 262, 120, 0 ),
+    1377             :   INST(Vpmaxsw         , VexRvm_Lx          , V(660F00,EE,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7385, 438, 137, 60),
+    1378             :   INST(Vpmaxub         , VexRvm_Lx          , V(660F00,DE,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7393, 438, 137, 60),
+    1379             :   INST(Vpmaxud         , VexRvm_Lx          , V(660F38,3F,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7401, 259, 125, 60),
+    1380             :   INST(Vpmaxuq         , VexRvm_Lx          , V(660F38,3F,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7409, 262, 120, 0 ),
+    1381             :   INST(Vpmaxuw         , VexRvm_Lx          , V(660F38,3E,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7417, 438, 137, 61),
+    1382             :   INST(Vpminsb         , VexRvm_Lx          , V(660F38,38,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7425, 438, 137, 61),
+    1383             :   INST(Vpminsd         , VexRvm_Lx          , V(660F38,39,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7433, 259, 125, 61),
+    1384             :   INST(Vpminsq         , VexRvm_Lx          , V(660F38,39,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7441, 262, 120, 0 ),
+    1385             :   INST(Vpminsw         , VexRvm_Lx          , V(660F00,EA,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7449, 438, 137, 62),
+    1386             :   INST(Vpminub         , VexRvm_Lx          , V(660F00,DA,_,x,I,_,4,FVM), 0                         , 0 , 0 , 7457, 438, 137, 62),
+    1387             :   INST(Vpminud         , VexRvm_Lx          , V(660F38,3B,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7465, 259, 125, 62),
+    1388             :   INST(Vpminuq         , VexRvm_Lx          , V(660F38,3B,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7473, 262, 120, 0 ),
+    1389             :   INST(Vpminuw         , VexRvm_Lx          , V(660F38,3A,_,x,I,_,4,FVM), 0                         , 0 , 0 , 7481, 438, 137, 63),
+    1390             :   INST(Vpmovb2m        , VexRm_Lx           , V(F30F38,29,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7489, 439, 122, 0 ),
+    1391             :   INST(Vpmovd2m        , VexRm_Lx           , V(F30F38,39,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7498, 439, 123, 0 ),
+    1392             :   INST(Vpmovdb         , VexMr_Lx           , V(F30F38,31,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7507, 440, 120, 0 ),
+    1393             :   INST(Vpmovdw         , VexMr_Lx           , V(F30F38,33,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7515, 441, 120, 0 ),
+    1394             :   INST(Vpmovm2b        , VexRm_Lx           , V(F30F38,28,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7523, 398, 122, 0 ),
+    1395             :   INST(Vpmovm2d        , VexRm_Lx           , V(F30F38,38,_,x,_,0,_,_  ), 0                         , 0 , 0 , 7532, 398, 123, 0 ),
+    1396             :   INST(Vpmovm2q        , VexRm_Lx           , V(F30F38,38,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7541, 398, 123, 0 ),
+    1397             :   INST(Vpmovm2w        , VexRm_Lx           , V(F30F38,28,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7550, 398, 122, 0 ),
+    1398             :   INST(Vpmovmskb       , VexRm_Lx           , V(660F00,D7,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7559, 378, 135, 64),
+    1399             :   INST(Vpmovq2m        , VexRm_Lx           , V(F30F38,39,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7569, 439, 123, 0 ),
+    1400             :   INST(Vpmovqb         , VexMr_Lx           , V(F30F38,32,_,x,_,0,1,OVM), 0                         , 0 , 0 , 7578, 442, 120, 0 ),
+    1401             :   INST(Vpmovqd         , VexMr_Lx           , V(F30F38,35,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7586, 441, 120, 0 ),
+    1402             :   INST(Vpmovqw         , VexMr_Lx           , V(F30F38,34,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7594, 440, 120, 0 ),
+    1403             :   INST(Vpmovsdb        , VexMr_Lx           , V(F30F38,21,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7602, 440, 120, 0 ),
+    1404             :   INST(Vpmovsdw        , VexMr_Lx           , V(F30F38,23,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7611, 441, 120, 0 ),
+    1405             :   INST(Vpmovsqb        , VexMr_Lx           , V(F30F38,22,_,x,_,0,1,OVM), 0                         , 0 , 0 , 7620, 442, 120, 0 ),
+    1406             :   INST(Vpmovsqd        , VexMr_Lx           , V(F30F38,25,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7629, 441, 120, 0 ),
+    1407             :   INST(Vpmovsqw        , VexMr_Lx           , V(F30F38,24,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7638, 440, 120, 0 ),
+    1408             :   INST(Vpmovswb        , VexMr_Lx           , V(F30F38,20,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7647, 441, 122, 0 ),
+    1409             :   INST(Vpmovsxbd       , VexRm_Lx           , V(660F38,21,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7656, 443, 125, 14),
+    1410             :   INST(Vpmovsxbq       , VexRm_Lx           , V(660F38,22,_,x,I,I,1,OVM), 0                         , 0 , 0 , 7666, 444, 125, 14),
+    1411             :   INST(Vpmovsxbw       , VexRm_Lx           , V(660F38,20,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7676, 445, 137, 14),
+    1412             :   INST(Vpmovsxdq       , VexRm_Lx           , V(660F38,25,_,x,I,0,3,HVM), 0                         , 0 , 0 , 7686, 446, 125, 14),
+    1413             :   INST(Vpmovsxwd       , VexRm_Lx           , V(660F38,23,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7696, 445, 125, 14),
+    1414             :   INST(Vpmovsxwq       , VexRm_Lx           , V(660F38,24,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7706, 443, 125, 14),
+    1415             :   INST(Vpmovusdb       , VexMr_Lx           , V(F30F38,11,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7716, 440, 120, 0 ),
+    1416             :   INST(Vpmovusdw       , VexMr_Lx           , V(F30F38,13,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7726, 441, 120, 0 ),
+    1417             :   INST(Vpmovusqb       , VexMr_Lx           , V(F30F38,12,_,x,_,0,1,OVM), 0                         , 0 , 0 , 7736, 442, 120, 0 ),
+    1418             :   INST(Vpmovusqd       , VexMr_Lx           , V(F30F38,15,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7746, 441, 120, 0 ),
+    1419             :   INST(Vpmovusqw       , VexMr_Lx           , V(F30F38,14,_,x,_,0,2,QVM), 0                         , 0 , 0 , 7756, 440, 120, 0 ),
+    1420             :   INST(Vpmovuswb       , VexMr_Lx           , V(F30F38,10,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7766, 441, 122, 0 ),
+    1421             :   INST(Vpmovw2m        , VexRm_Lx           , V(F30F38,29,_,x,_,1,_,_  ), 0                         , 0 , 0 , 7776, 439, 122, 0 ),
+    1422             :   INST(Vpmovwb         , VexMr_Lx           , V(F30F38,30,_,x,_,0,3,HVM), 0                         , 0 , 0 , 7785, 441, 122, 0 ),
+    1423             :   INST(Vpmovzxbd       , VexRm_Lx           , V(660F38,31,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7793, 443, 125, 65),
+    1424             :   INST(Vpmovzxbq       , VexRm_Lx           , V(660F38,32,_,x,I,I,1,OVM), 0                         , 0 , 0 , 7803, 444, 125, 65),
+    1425             :   INST(Vpmovzxbw       , VexRm_Lx           , V(660F38,30,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7813, 445, 137, 65),
+    1426             :   INST(Vpmovzxdq       , VexRm_Lx           , V(660F38,35,_,x,I,0,3,HVM), 0                         , 0 , 0 , 7823, 446, 125, 65),
+    1427             :   INST(Vpmovzxwd       , VexRm_Lx           , V(660F38,33,_,x,I,I,3,HVM), 0                         , 0 , 0 , 7833, 445, 125, 65),
+    1428             :   INST(Vpmovzxwq       , VexRm_Lx           , V(660F38,34,_,x,I,I,2,QVM), 0                         , 0 , 0 , 7843, 443, 125, 65),
+    1429             :   INST(Vpmuldq         , VexRvm_Lx          , V(660F38,28,_,x,I,1,4,FV ), 0                         , 0 , 0 , 7853, 256, 125, 19),
+    1430             :   INST(Vpmulhrsw       , VexRvm_Lx          , V(660F38,0B,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7861, 388, 137, 19),
+    1431             :   INST(Vpmulhuw        , VexRvm_Lx          , V(660F00,E4,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7871, 388, 137, 66),
+    1432             :   INST(Vpmulhw         , VexRvm_Lx          , V(660F00,E5,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7880, 388, 137, 66),
+    1433             :   INST(Vpmulld         , VexRvm_Lx          , V(660F38,40,_,x,I,0,4,FV ), 0                         , 0 , 0 , 7888, 257, 125, 66),
+    1434             :   INST(Vpmullq         , VexRvm_Lx          , V(660F38,40,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7896, 262, 123, 0 ),
+    1435             :   INST(Vpmullw         , VexRvm_Lx          , V(660F00,D5,_,x,I,I,4,FVM), 0                         , 0 , 0 , 7904, 388, 137, 19),
+    1436             :   INST(Vpmultishiftqb  , VexRvm_Lx          , V(660F38,83,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7912, 262, 142, 0 ),
+    1437             :   INST(Vpmuludq        , VexRvm_Lx          , V(660F00,F4,_,x,I,1,4,FV ), 0                         , 0 , 0 , 7927, 256, 125, 67),
+    1438             :   INST(Vpopcntd        , VexRm              , V(660F38,55,_,2,_,0,4,FVM), 0                         , 0 , 0 , 7936, 447, 146, 0 ),
+    1439             :   INST(Vpopcntq        , VexRm              , V(660F38,55,_,2,_,1,4,FVM), 0                         , 0 , 0 , 7945, 448, 146, 0 ),
+    1440             :   INST(Vpor            , VexRvm_Lx          , V(660F00,EB,_,x,I,_,_,_  ), 0                         , 0 , 0 , 7954, 390, 135, 68),
+    1441             :   INST(Vpord           , VexRvm_Lx          , V(660F00,EB,_,x,_,0,4,FV ), 0                         , 0 , 0 , 7959, 391, 120, 0 ),
+    1442             :   INST(Vporq           , VexRvm_Lx          , V(660F00,EB,_,x,_,1,4,FV ), 0                         , 0 , 0 , 7965, 395, 120, 0 ),
+    1443             :   INST(Vpperm          , VexRvrmRvmr        , V(XOP_M8,A3,_,0,x,_,_,_  ), 0                         , 0 , 0 , 7971, 449, 132, 0 ),
+    1444             :   INST(Vprold          , VexVmi_Lx          , V(660F00,72,1,x,_,0,4,FV ), 0                         , 0 , 0 , 7978, 450, 120, 0 ),
+    1445             :   INST(Vprolq          , VexVmi_Lx          , V(660F00,72,1,x,_,1,4,FV ), 0                         , 0 , 0 , 7985, 451, 120, 0 ),
+    1446             :   INST(Vprolvd         , VexRvm_Lx          , V(660F38,15,_,x,_,0,4,FV ), 0                         , 0 , 0 , 7992, 261, 120, 0 ),
+    1447             :   INST(Vprolvq         , VexRvm_Lx          , V(660F38,15,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8000, 262, 120, 0 ),
+    1448             :   INST(Vprord          , VexVmi_Lx          , V(660F00,72,0,x,_,0,4,FV ), 0                         , 0 , 0 , 8008, 450, 120, 0 ),
+    1449             :   INST(Vprorq          , VexVmi_Lx          , V(660F00,72,0,x,_,1,4,FV ), 0                         , 0 , 0 , 8015, 451, 120, 0 ),
+    1450             :   INST(Vprorvd         , VexRvm_Lx          , V(660F38,14,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8022, 261, 120, 0 ),
+    1451             :   INST(Vprorvq         , VexRvm_Lx          , V(660F38,14,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8030, 262, 120, 0 ),
+    1452             :   INST(Vprotb          , VexRvmRmvRmi       , V(XOP_M9,90,_,0,x,_,_,_  ), V(XOP_M8,C0,_,0,x,_,_,_  ), 0 , 0 , 8038, 452, 132, 0 ),
+    1453             :   INST(Vprotd          , VexRvmRmvRmi       , V(XOP_M9,92,_,0,x,_,_,_  ), V(XOP_M8,C2,_,0,x,_,_,_  ), 0 , 0 , 8045, 453, 132, 0 ),
+    1454             :   INST(Vprotq          , VexRvmRmvRmi       , V(XOP_M9,93,_,0,x,_,_,_  ), V(XOP_M8,C3,_,0,x,_,_,_  ), 0 , 0 , 8052, 454, 132, 0 ),
+    1455             :   INST(Vprotw          , VexRvmRmvRmi       , V(XOP_M9,91,_,0,x,_,_,_  ), V(XOP_M8,C1,_,0,x,_,_,_  ), 0 , 0 , 8059, 455, 132, 0 ),
+    1456             :   INST(Vpsadbw         , VexRvm_Lx          , V(660F00,F6,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8066, 456, 137, 69),
+    1457             :   INST(Vpscatterdd     , VexMr_VM           , V(660F38,A0,_,x,_,0,2,T1S), 0                         , 0 , 0 , 8074, 457, 120, 0 ),
+    1458             :   INST(Vpscatterdq     , VexMr_VM           , V(660F38,A0,_,x,_,1,3,T1S), 0                         , 0 , 0 , 8086, 457, 120, 0 ),
+    1459             :   INST(Vpscatterqd     , VexMr_VM           , V(660F38,A1,_,x,_,0,2,T1S), 0                         , 0 , 0 , 8098, 458, 120, 0 ),
+    1460             :   INST(Vpscatterqq     , VexMr_VM           , V(660F38,A1,_,x,_,1,3,T1S), 0                         , 0 , 0 , 8110, 459, 120, 0 ),
+    1461             :   INST(Vpshab          , VexRvmRmv          , V(XOP_M9,98,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8122, 460, 132, 0 ),
+    1462             :   INST(Vpshad          , VexRvmRmv          , V(XOP_M9,9A,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8129, 460, 132, 0 ),
+    1463             :   INST(Vpshaq          , VexRvmRmv          , V(XOP_M9,9B,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8136, 460, 132, 0 ),
+    1464             :   INST(Vpshaw          , VexRvmRmv          , V(XOP_M9,99,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8143, 460, 132, 0 ),
+    1465             :   INST(Vpshlb          , VexRvmRmv          , V(XOP_M9,94,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8150, 460, 132, 0 ),
+    1466             :   INST(Vpshld          , VexRvmRmv          , V(XOP_M9,96,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8157, 460, 132, 0 ),
+    1467             :   INST(Vpshlq          , VexRvmRmv          , V(XOP_M9,97,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8164, 460, 132, 0 ),
+    1468             :   INST(Vpshlw          , VexRvmRmv          , V(XOP_M9,95,_,0,x,_,_,_  ), 0                         , 0 , 0 , 8171, 460, 132, 0 ),
+    1469             :   INST(Vpshufb         , VexRvm_Lx          , V(660F38,00,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8178, 388, 137, 70),
+    1470             :   INST(Vpshufd         , VexRmi_Lx          , V(660F00,70,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8186, 461, 125, 71),
+    1471             :   INST(Vpshufhw        , VexRmi_Lx          , V(F30F00,70,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8194, 462, 137, 71),
+    1472             :   INST(Vpshuflw        , VexRmi_Lx          , V(F20F00,70,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8203, 462, 137, 71),
+    1473             :   INST(Vpsignb         , VexRvm_Lx          , V(660F38,08,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8212, 250, 135, 72),
+    1474             :   INST(Vpsignd         , VexRvm_Lx          , V(660F38,0A,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8220, 250, 135, 72),
+    1475             :   INST(Vpsignw         , VexRvm_Lx          , V(660F38,09,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8228, 250, 135, 72),
+    1476             :   INST(Vpslld          , VexRvmVmi_Lx       , V(660F00,F2,_,x,I,0,4,128), V(660F00,72,6,x,I,0,4,FV ), 0 , 0 , 8236, 463, 125, 72),
+    1477             :   INST(Vpslldq         , VexEvexVmi_Lx      , V(660F00,73,7,x,I,I,4,FVM), 0                         , 0 , 0 , 8243, 464, 137, 72),
+    1478             :   INST(Vpsllq          , VexRvmVmi_Lx       , V(660F00,F3,_,x,I,1,4,128), V(660F00,73,6,x,I,1,4,FV ), 0 , 0 , 8251, 465, 125, 72),
+    1479             :   INST(Vpsllvd         , VexRvm_Lx          , V(660F38,47,_,x,0,0,4,FV ), 0                         , 0 , 0 , 8258, 257, 133, 0 ),
+    1480             :   INST(Vpsllvq         , VexRvm_Lx          , V(660F38,47,_,x,1,1,4,FV ), 0                         , 0 , 0 , 8266, 256, 133, 0 ),
+    1481             :   INST(Vpsllvw         , VexRvm_Lx          , V(660F38,12,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8274, 260, 122, 0 ),
+    1482             :   INST(Vpsllw          , VexRvmVmi_Lx       , V(660F00,F1,_,x,I,I,4,FVM), V(660F00,71,6,x,I,I,4,FVM), 0 , 0 , 8282, 466, 137, 73),
+    1483             :   INST(Vpsrad          , VexRvmVmi_Lx       , V(660F00,E2,_,x,I,0,4,128), V(660F00,72,4,x,I,0,4,FV ), 0 , 0 , 8289, 467, 125, 73),
+    1484             :   INST(Vpsraq          , VexRvmVmi_Lx       , V(660F00,E2,_,x,_,1,4,128), V(660F00,72,4,x,_,1,4,FV ), 0 , 0 , 8296, 468, 120, 0 ),
+    1485             :   INST(Vpsravd         , VexRvm_Lx          , V(660F38,46,_,x,0,0,4,FV ), 0                         , 0 , 0 , 8303, 257, 133, 0 ),
+    1486             :   INST(Vpsravq         , VexRvm_Lx          , V(660F38,46,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8311, 262, 120, 0 ),
+    1487             :   INST(Vpsravw         , VexRvm_Lx          , V(660F38,11,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8319, 260, 122, 0 ),
+    1488             :   INST(Vpsraw          , VexRvmVmi_Lx       , V(660F00,E1,_,x,I,I,4,128), V(660F00,71,4,x,I,I,4,FVM), 0 , 0 , 8327, 469, 137, 74),
+    1489             :   INST(Vpsrld          , VexRvmVmi_Lx       , V(660F00,D2,_,x,I,0,4,128), V(660F00,72,2,x,I,0,4,FV ), 0 , 0 , 8334, 470, 125, 74),
+    1490             :   INST(Vpsrldq         , VexEvexVmi_Lx      , V(660F00,73,3,x,I,I,4,FVM), 0                         , 0 , 0 , 8341, 464, 137, 74),
+    1491             :   INST(Vpsrlq          , VexRvmVmi_Lx       , V(660F00,D3,_,x,I,1,4,128), V(660F00,73,2,x,I,1,4,FV ), 0 , 0 , 8349, 471, 125, 74),
+    1492             :   INST(Vpsrlvd         , VexRvm_Lx          , V(660F38,45,_,x,0,0,4,FV ), 0                         , 0 , 0 , 8356, 257, 133, 0 ),
+    1493             :   INST(Vpsrlvq         , VexRvm_Lx          , V(660F38,45,_,x,1,1,4,FV ), 0                         , 0 , 0 , 8364, 256, 133, 0 ),
+    1494             :   INST(Vpsrlvw         , VexRvm_Lx          , V(660F38,10,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8372, 260, 122, 0 ),
+    1495             :   INST(Vpsrlw          , VexRvmVmi_Lx       , V(660F00,D1,_,x,I,I,4,128), V(660F00,71,2,x,I,I,4,FVM), 0 , 0 , 8380, 472, 137, 75),
+    1496             :   INST(Vpsubb          , VexRvm_Lx          , V(660F00,F8,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8387, 473, 137, 75),
+    1497             :   INST(Vpsubd          , VexRvm_Lx          , V(660F00,FA,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8394, 474, 125, 75),
+    1498             :   INST(Vpsubq          , VexRvm_Lx          , V(660F00,FB,_,x,I,1,4,FV ), 0                         , 0 , 0 , 8401, 475, 125, 75),
+    1499             :   INST(Vpsubsb         , VexRvm_Lx          , V(660F00,E8,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8408, 473, 137, 75),
+    1500             :   INST(Vpsubsw         , VexRvm_Lx          , V(660F00,E9,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8416, 473, 137, 75),
+    1501             :   INST(Vpsubusb        , VexRvm_Lx          , V(660F00,D8,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8424, 473, 137, 75),
+    1502             :   INST(Vpsubusw        , VexRvm_Lx          , V(660F00,D9,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8433, 473, 137, 75),
+    1503             :   INST(Vpsubw          , VexRvm_Lx          , V(660F00,F9,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8442, 473, 137, 75),
+    1504             :   INST(Vpternlogd      , VexRvmi_Lx         , V(660F3A,25,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8449, 476, 120, 0 ),
+    1505             :   INST(Vpternlogq      , VexRvmi_Lx         , V(660F3A,25,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8460, 477, 120, 0 ),
+    1506             :   INST(Vptest          , VexRm_Lx           , V(660F38,17,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8471, 478, 141, 76),
+    1507             :   INST(Vptestmb        , VexRvm_Lx          , V(660F38,26,_,x,_,0,4,FVM), 0                         , 0 , 0 , 8478, 479, 122, 0 ),
+    1508             :   INST(Vptestmd        , VexRvm_Lx          , V(660F38,27,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8487, 480, 120, 0 ),
+    1509             :   INST(Vptestmq        , VexRvm_Lx          , V(660F38,27,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8496, 481, 120, 0 ),
+    1510             :   INST(Vptestmw        , VexRvm_Lx          , V(660F38,26,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8505, 479, 122, 0 ),
+    1511             :   INST(Vptestnmb       , VexRvm_Lx          , V(F30F38,26,_,x,_,0,4,FVM), 0                         , 0 , 0 , 8514, 479, 122, 0 ),
+    1512             :   INST(Vptestnmd       , VexRvm_Lx          , V(F30F38,27,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8524, 480, 120, 0 ),
+    1513             :   INST(Vptestnmq       , VexRvm_Lx          , V(F30F38,27,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8534, 481, 120, 0 ),
+    1514             :   INST(Vptestnmw       , VexRvm_Lx          , V(F30F38,26,_,x,_,1,4,FVM), 0                         , 0 , 0 , 8544, 479, 122, 0 ),
+    1515             :   INST(Vpunpckhbw      , VexRvm_Lx          , V(660F00,68,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8554, 388, 137, 77),
+    1516             :   INST(Vpunpckhdq      , VexRvm_Lx          , V(660F00,6A,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8565, 257, 125, 77),
+    1517             :   INST(Vpunpckhqdq     , VexRvm_Lx          , V(660F00,6D,_,x,I,1,4,FV ), 0                         , 0 , 0 , 8576, 256, 125, 77),
+    1518             :   INST(Vpunpckhwd      , VexRvm_Lx          , V(660F00,69,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8588, 388, 137, 77),
+    1519             :   INST(Vpunpcklbw      , VexRvm_Lx          , V(660F00,60,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8599, 388, 137, 77),
+    1520             :   INST(Vpunpckldq      , VexRvm_Lx          , V(660F00,62,_,x,I,0,4,FV ), 0                         , 0 , 0 , 8610, 257, 125, 77),
+    1521             :   INST(Vpunpcklqdq     , VexRvm_Lx          , V(660F00,6C,_,x,I,1,4,FV ), 0                         , 0 , 0 , 8621, 256, 125, 77),
+    1522             :   INST(Vpunpcklwd      , VexRvm_Lx          , V(660F00,61,_,x,I,I,4,FVM), 0                         , 0 , 0 , 8633, 388, 137, 77),
+    1523             :   INST(Vpxor           , VexRvm_Lx          , V(660F00,EF,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8644, 392, 135, 78),
+    1524             :   INST(Vpxord          , VexRvm_Lx          , V(660F00,EF,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8650, 393, 120, 0 ),
+    1525             :   INST(Vpxorq          , VexRvm_Lx          , V(660F00,EF,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8657, 394, 120, 0 ),
+    1526             :   INST(Vrangepd        , VexRvmi_Lx         , V(660F3A,50,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8664, 482, 123, 0 ),
+    1527             :   INST(Vrangeps        , VexRvmi_Lx         , V(660F3A,50,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8673, 483, 123, 0 ),
+    1528             :   INST(Vrangesd        , VexRvmi            , V(660F3A,51,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8682, 484, 63 , 0 ),
+    1529             :   INST(Vrangess        , VexRvmi            , V(660F3A,51,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8691, 485, 63 , 0 ),
+    1530             :   INST(Vrcp14pd        , VexRm_Lx           , V(660F38,4C,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8700, 434, 120, 0 ),
+    1531             :   INST(Vrcp14ps        , VexRm_Lx           , V(660F38,4C,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8709, 411, 120, 0 ),
+    1532             :   INST(Vrcp14sd        , VexRvm             , V(660F38,4D,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8718, 486, 65 , 0 ),
+    1533             :   INST(Vrcp14ss        , VexRvm             , V(660F38,4D,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8727, 487, 65 , 0 ),
+    1534             :   INST(Vrcp28pd        , VexRm              , V(660F38,CA,_,2,_,1,4,FV ), 0                         , 0 , 0 , 8736, 311, 128, 0 ),
+    1535             :   INST(Vrcp28ps        , VexRm              , V(660F38,CA,_,2,_,0,4,FV ), 0                         , 0 , 0 , 8745, 312, 128, 0 ),
+    1536             :   INST(Vrcp28sd        , VexRvm             , V(660F38,CB,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8754, 488, 128, 0 ),
+    1537             :   INST(Vrcp28ss        , VexRvm             , V(660F38,CB,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8763, 489, 128, 0 ),
+    1538             :   INST(Vrcpps          , VexRm_Lx           , V(000F00,53,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8772, 333, 118, 79),
+    1539             :   INST(Vrcpss          , VexRvm             , V(F30F00,53,_,I,I,_,_,_  ), 0                         , 0 , 0 , 8779, 490, 118, 80),
+    1540             :   INST(Vreducepd       , VexRmi_Lx          , V(660F3A,56,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8786, 451, 123, 0 ),
+    1541             :   INST(Vreduceps       , VexRmi_Lx          , V(660F3A,56,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8796, 450, 123, 0 ),
+    1542             :   INST(Vreducesd       , VexRvmi            , V(660F3A,57,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8806, 491, 63 , 0 ),
+    1543             :   INST(Vreducess       , VexRvmi            , V(660F3A,57,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8816, 492, 63 , 0 ),
+    1544             :   INST(Vrndscalepd     , VexRmi_Lx          , V(660F3A,09,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8826, 345, 120, 0 ),
+    1545             :   INST(Vrndscaleps     , VexRmi_Lx          , V(660F3A,08,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8838, 346, 120, 0 ),
+    1546             :   INST(Vrndscalesd     , VexRvmi            , V(660F3A,0B,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8850, 484, 65 , 0 ),
+    1547             :   INST(Vrndscaless     , VexRvmi            , V(660F3A,0A,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8862, 485, 65 , 0 ),
+    1548             :   INST(Vroundpd        , VexRmi_Lx          , V(660F3A,09,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8874, 493, 118, 81),
+    1549             :   INST(Vroundps        , VexRmi_Lx          , V(660F3A,08,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8883, 493, 118, 81),
+    1550             :   INST(Vroundsd        , VexRvmi            , V(660F3A,0B,_,I,I,_,_,_  ), 0                         , 0 , 0 , 8892, 494, 118, 82),
+    1551             :   INST(Vroundss        , VexRvmi            , V(660F3A,0A,_,I,I,_,_,_  ), 0                         , 0 , 0 , 8901, 495, 118, 82),
+    1552             :   INST(Vrsqrt14pd      , VexRm_Lx           , V(660F38,4E,_,x,_,1,4,FV ), 0                         , 0 , 0 , 8910, 434, 120, 0 ),
+    1553             :   INST(Vrsqrt14ps      , VexRm_Lx           , V(660F38,4E,_,x,_,0,4,FV ), 0                         , 0 , 0 , 8921, 411, 120, 0 ),
+    1554             :   INST(Vrsqrt14sd      , VexRvm             , V(660F38,4F,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8932, 486, 65 , 0 ),
+    1555             :   INST(Vrsqrt14ss      , VexRvm             , V(660F38,4F,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8943, 487, 65 , 0 ),
+    1556             :   INST(Vrsqrt28pd      , VexRm              , V(660F38,CC,_,2,_,1,4,FV ), 0                         , 0 , 0 , 8954, 311, 128, 0 ),
+    1557             :   INST(Vrsqrt28ps      , VexRm              , V(660F38,CC,_,2,_,0,4,FV ), 0                         , 0 , 0 , 8965, 312, 128, 0 ),
+    1558             :   INST(Vrsqrt28sd      , VexRvm             , V(660F38,CD,_,I,_,1,3,T1S), 0                         , 0 , 0 , 8976, 488, 128, 0 ),
+    1559             :   INST(Vrsqrt28ss      , VexRvm             , V(660F38,CD,_,I,_,0,2,T1S), 0                         , 0 , 0 , 8987, 489, 128, 0 ),
+    1560             :   INST(Vrsqrtps        , VexRm_Lx           , V(000F00,52,_,x,I,_,_,_  ), 0                         , 0 , 0 , 8998, 333, 118, 3 ),
+    1561             :   INST(Vrsqrtss        , VexRvm             , V(F30F00,52,_,I,I,_,_,_  ), 0                         , 0 , 0 , 9007, 490, 118, 2 ),
+    1562             :   INST(Vscalefpd       , VexRvm_Lx          , V(660F38,2C,_,x,_,1,4,FV ), 0                         , 0 , 0 , 9016, 496, 120, 0 ),
+    1563             :   INST(Vscalefps       , VexRvm_Lx          , V(660F38,2C,_,x,_,0,4,FV ), 0                         , 0 , 0 , 9026, 497, 120, 0 ),
+    1564             :   INST(Vscalefsd       , VexRvm             , V(660F38,2D,_,I,_,1,3,T1S), 0                         , 0 , 0 , 9036, 498, 65 , 0 ),
+    1565             :   INST(Vscalefss       , VexRvm             , V(660F38,2D,_,I,_,0,2,T1S), 0                         , 0 , 0 , 9046, 499, 65 , 0 ),
+    1566             :   INST(Vscatterdpd     , VexMr_Lx           , V(660F38,A2,_,x,_,1,3,T1S), 0                         , 0 , 0 , 9056, 500, 120, 0 ),
+    1567             :   INST(Vscatterdps     , VexMr_Lx           , V(660F38,A2,_,x,_,0,2,T1S), 0                         , 0 , 0 , 9068, 457, 120, 0 ),
+    1568             :   INST(Vscatterpf0dpd  , VexM_VM            , V(660F38,C6,5,2,_,1,3,T1S), 0                         , 0 , 0 , 9080, 338, 134, 0 ),
+    1569             :   INST(Vscatterpf0dps  , VexM_VM            , V(660F38,C6,5,2,_,0,2,T1S), 0                         , 0 , 0 , 9095, 339, 134, 0 ),
+    1570             :   INST(Vscatterpf0qpd  , VexM_VM            , V(660F38,C7,5,2,_,1,3,T1S), 0                         , 0 , 0 , 9110, 340, 134, 0 ),
+    1571             :   INST(Vscatterpf0qps  , VexM_VM            , V(660F38,C7,5,2,_,0,2,T1S), 0                         , 0 , 0 , 9125, 340, 134, 0 ),
+    1572             :   INST(Vscatterpf1dpd  , VexM_VM            , V(660F38,C6,6,2,_,1,3,T1S), 0                         , 0 , 0 , 9140, 338, 134, 0 ),
+    1573             :   INST(Vscatterpf1dps  , VexM_VM            , V(660F38,C6,6,2,_,0,2,T1S), 0                         , 0 , 0 , 9155, 339, 134, 0 ),
+    1574             :   INST(Vscatterpf1qpd  , VexM_VM            , V(660F38,C7,6,2,_,1,3,T1S), 0                         , 0 , 0 , 9170, 340, 134, 0 ),
+    1575             :   INST(Vscatterpf1qps  , VexM_VM            , V(660F38,C7,6,2,_,0,2,T1S), 0                         , 0 , 0 , 9185, 340, 134, 0 ),
+    1576             :   INST(Vscatterqpd     , VexMr_Lx           , V(660F38,A3,_,x,_,1,3,T1S), 0                         , 0 , 0 , 9200, 459, 120, 0 ),
+    1577             :   INST(Vscatterqps     , VexMr_Lx           , V(660F38,A3,_,x,_,0,2,T1S), 0                         , 0 , 0 , 9212, 458, 120, 0 ),
+    1578             :   INST(Vshuff32x4      , VexRvmi_Lx         , V(660F3A,23,_,x,_,0,4,FV ), 0                         , 0 , 0 , 9224, 501, 120, 0 ),
+    1579             :   INST(Vshuff64x2      , VexRvmi_Lx         , V(660F3A,23,_,x,_,1,4,FV ), 0                         , 0 , 0 , 9235, 502, 120, 0 ),
+    1580             :   INST(Vshufi32x4      , VexRvmi_Lx         , V(660F3A,43,_,x,_,0,4,FV ), 0                         , 0 , 0 , 9246, 501, 120, 0 ),
+    1581             :   INST(Vshufi64x2      , VexRvmi_Lx         , V(660F3A,43,_,x,_,1,4,FV ), 0                         , 0 , 0 , 9257, 502, 120, 0 ),
+    1582             :   INST(Vshufpd         , VexRvmi_Lx         , V(660F00,C6,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9268, 503, 116, 83),
+    1583             :   INST(Vshufps         , VexRvmi_Lx         , V(000F00,C6,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9276, 504, 116, 83),
+    1584             :   INST(Vsqrtpd         , VexRm_Lx           , V(660F00,51,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9284, 505, 116, 84),
+    1585             :   INST(Vsqrtps         , VexRm_Lx           , V(000F00,51,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9292, 281, 116, 84),
+    1586             :   INST(Vsqrtsd         , VexRvm             , V(F20F00,51,_,I,I,1,3,T1S), 0                         , 0 , 0 , 9300, 248, 117, 85),
+    1587             :   INST(Vsqrtss         , VexRvm             , V(F30F00,51,_,I,I,0,2,T1S), 0                         , 0 , 0 , 9308, 249, 117, 85),
+    1588             :   INST(Vstmxcsr        , VexM               , V(000F00,AE,3,0,I,_,_,_  ), 0                         , 0 , 0 , 9316, 506, 118, 0 ),
+    1589             :   INST(Vsubpd          , VexRvm_Lx          , V(660F00,5C,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9325, 246, 116, 86),
+    1590             :   INST(Vsubps          , VexRvm_Lx          , V(000F00,5C,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9332, 247, 116, 86),
+    1591             :   INST(Vsubsd          , VexRvm             , V(F20F00,5C,_,I,I,1,3,T1S), 0                         , 0 , 0 , 9339, 248, 117, 86),
+    1592             :   INST(Vsubss          , VexRvm             , V(F30F00,5C,_,I,I,0,2,T1S), 0                         , 0 , 0 , 9346, 249, 117, 86),
+    1593             :   INST(Vtestpd         , VexRm_Lx           , V(660F38,0F,_,x,0,_,_,_  ), 0                         , 0 , 0 , 9353, 478, 141, 0 ),
+    1594             :   INST(Vtestps         , VexRm_Lx           , V(660F38,0E,_,x,0,_,_,_  ), 0                         , 0 , 0 , 9361, 478, 141, 0 ),
+    1595             :   INST(Vucomisd        , VexRm              , V(660F00,2E,_,I,I,1,3,T1S), 0                         , 0 , 0 , 9369, 277, 126, 15),
+    1596             :   INST(Vucomiss        , VexRm              , V(000F00,2E,_,I,I,0,2,T1S), 0                         , 0 , 0 , 9378, 278, 126, 15),
+    1597             :   INST(Vunpckhpd       , VexRvm_Lx          , V(660F00,15,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9387, 256, 116, 13),
+    1598             :   INST(Vunpckhps       , VexRvm_Lx          , V(000F00,15,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9397, 257, 116, 13),
+    1599             :   INST(Vunpcklpd       , VexRvm_Lx          , V(660F00,14,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9407, 256, 116, 13),
+    1600             :   INST(Vunpcklps       , VexRvm_Lx          , V(000F00,14,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9417, 257, 116, 13),
+    1601             :   INST(Vxorpd          , VexRvm_Lx          , V(660F00,57,_,x,I,1,4,FV ), 0                         , 0 , 0 , 9427, 475, 121, 87),
+    1602             :   INST(Vxorps          , VexRvm_Lx          , V(000F00,57,_,x,I,0,4,FV ), 0                         , 0 , 0 , 9434, 474, 121, 87),
+    1603             :   INST(Vzeroall        , VexOp              , V(000F00,77,_,1,I,_,_,_  ), 0                         , 0 , 0 , 9441, 507, 118, 0 ),
+    1604             :   INST(Vzeroupper      , VexOp              , V(000F00,77,_,0,I,_,_,_  ), 0                         , 0 , 0 , 9450, 507, 118, 0 ),
+    1605             :   INST(Wbinvd          , X86Op              , O(000F00,09,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9461, 34 , 23 , 0 ),
+    1606             :   INST(Wrfsbase        , X86M               , O(F30F00,AE,2,_,x,_,_,_  ), 0                         , 0 , 0 , 9468, 508, 98 , 0 ),
+    1607             :   INST(Wrgsbase        , X86M               , O(F30F00,AE,3,_,x,_,_,_  ), 0                         , 0 , 0 , 9477, 508, 98 , 0 ),
+    1608             :   INST(Wrmsr           , X86Op              , O(000F00,30,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9486, 509, 147, 0 ),
+    1609             :   INST(Xabort          , X86Op_O_I8         , O(000000,C6,7,_,_,_,_,_  ), 0                         , 0 , 0 , 9492, 98 , 148, 0 ),
+    1610             :   INST(Xadd            , X86Xadd            , O(000F00,C0,_,_,x,_,_,_  ), 0                         , 0 , 0 , 9499, 510, 36 , 0 ),
+    1611             :   INST(Xbegin          , X86JmpRel          , O(000000,C7,7,_,_,_,_,_  ), 0                         , 0 , 0 , 9504, 511, 148, 0 ),
+    1612             :   INST(Xchg            , X86Xchg            , O(000000,86,_,_,x,_,_,_  ), 0                         , 0 , 0 , 434 , 512, 0  , 0 ),
+    1613             :   INST(Xend            , X86Op              , O(000F01,D5,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9511, 34 , 148, 0 ),
+    1614             :   INST(Xgetbv          , X86Op              , O(000F01,D0,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9516, 227, 149, 0 ),
+    1615             :   INST(Xlatb           , X86Op              , O(000000,D7,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9523, 34 , 45 , 0 ),
+    1616             :   INST(Xor             , X86Arith           , O(000000,30,6,_,x,_,_,_  ), 0                         , 0 , 0 , 8646, 243, 1  , 0 ),
+    1617             :   INST(Xorpd           , ExtRm              , O(660F00,57,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9428, 192, 4  , 87),
+    1618             :   INST(Xorps           , ExtRm              , O(000F00,57,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9435, 192, 5  , 87),
+    1619             :   INST(Xrstor          , X86M_Only          , O(000F00,AE,5,_,_,_,_,_  ), 0                         , 0 , 0 , 1105, 513, 149, 0 ),
+    1620             :   INST(Xrstor64        , X86M_Only          , O(000F00,AE,5,_,1,_,_,_  ), 0                         , 0 , 0 , 1113, 514, 149, 0 ),
+    1621             :   INST(Xrstors         , X86M_Only          , O(000F00,C7,3,_,_,_,_,_  ), 0                         , 0 , 0 , 9529, 513, 150, 0 ),
+    1622             :   INST(Xrstors64       , X86M_Only          , O(000F00,C7,3,_,1,_,_,_  ), 0                         , 0 , 0 , 9537, 514, 150, 0 ),
+    1623             :   INST(Xsave           , X86M_Only          , O(000F00,AE,4,_,_,_,_,_  ), 0                         , 0 , 0 , 1123, 515, 149, 0 ),
+    1624             :   INST(Xsave64         , X86M_Only          , O(000F00,AE,4,_,1,_,_,_  ), 0                         , 0 , 0 , 1130, 516, 149, 0 ),
+    1625             :   INST(Xsavec          , X86M_Only          , O(000F00,C7,4,_,_,_,_,_  ), 0                         , 0 , 0 , 9547, 515, 151, 0 ),
+    1626             :   INST(Xsavec64        , X86M_Only          , O(000F00,C7,4,_,1,_,_,_  ), 0                         , 0 , 0 , 9554, 516, 151, 0 ),
+    1627             :   INST(Xsaveopt        , X86M_Only          , O(000F00,AE,6,_,_,_,_,_  ), 0                         , 0 , 0 , 9563, 515, 152, 0 ),
+    1628             :   INST(Xsaveopt64      , X86M_Only          , O(000F00,AE,6,_,1,_,_,_  ), 0                         , 0 , 0 , 9572, 516, 152, 0 ),
+    1629             :   INST(Xsaves          , X86M_Only          , O(000F00,C7,5,_,_,_,_,_  ), 0                         , 0 , 0 , 9583, 515, 150, 0 ),
+    1630             :   INST(Xsaves64        , X86M_Only          , O(000F00,C7,5,_,1,_,_,_  ), 0                         , 0 , 0 , 9590, 516, 150, 0 ),
+    1631             :   INST(Xsetbv          , X86Op              , O(000F01,D1,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9599, 509, 153, 0 ),
+    1632             :   INST(Xtest           , X86Op              , O(000F01,D6,_,_,_,_,_,_  ), 0                         , 0 , 0 , 9606, 34 , 154, 0 )
+    1633             :   // ${instData:End}
+    1634             : };
+    1635             : #undef NAME_DATA_INDEX
+    1636             : #undef INST
+    1637             : 
+    1638             : // ${altOpCodeData:Begin}
+    1639             : // ------------------- Automatically generated, do not edit -------------------
+    1640             : const uint32_t X86InstDB::altOpCodeData[] = {
+    1641             :   0                         , // #0
+    1642             :   O(660F00,1B,_,_,_,_,_,_  ), // #1
+    1643             :   O(000F00,BA,4,_,x,_,_,_  ), // #2
+    1644             :   O(000F00,BA,7,_,x,_,_,_  ), // #3
+    1645             :   O(000F00,BA,6,_,x,_,_,_  ), // #4
+    1646             :   O(000F00,BA,5,_,x,_,_,_  ), // #5
+    1647             :   O(000000,48,_,_,x,_,_,_  ), // #6
+    1648             :   O(660F00,78,0,_,_,_,_,_  ), // #7
+    1649             :   O_FPU(00,00DF,5)          , // #8
+    1650             :   O_FPU(00,00DF,7)          , // #9
+    1651             :   O_FPU(00,00DD,1)          , // #10
+    1652             :   O_FPU(00,00DB,5)          , // #11
+    1653             :   O_FPU(00,DFE0,_)          , // #12
+    1654             :   O(000000,DB,7,_,_,_,_,_  ), // #13
+    1655             :   O_FPU(9B,DFE0,_)          , // #14
+    1656             :   O(000000,E4,_,_,_,_,_,_  ), // #15
+    1657             :   O(000000,40,_,_,x,_,_,_  ), // #16
+    1658             :   O(F20F00,78,_,_,_,_,_,_  ), // #17
+    1659             :   O(000000,77,_,_,_,_,_,_  ), // #18
+    1660             :   O(000000,73,_,_,_,_,_,_  ), // #19
+    1661             :   O(000000,72,_,_,_,_,_,_  ), // #20
+    1662             :   O(000000,76,_,_,_,_,_,_  ), // #21
+    1663             :   O(000000,74,_,_,_,_,_,_  ), // #22
+    1664             :   O(000000,E3,_,_,_,_,_,_  ), // #23
+    1665             :   O(000000,7F,_,_,_,_,_,_  ), // #24
+    1666             :   O(000000,7D,_,_,_,_,_,_  ), // #25
+    1667             :   O(000000,7C,_,_,_,_,_,_  ), // #26
+    1668             :   O(000000,7E,_,_,_,_,_,_  ), // #27
+    1669             :   O(000000,EB,_,_,_,_,_,_  ), // #28
+    1670             :   O(000000,75,_,_,_,_,_,_  ), // #29
+    1671             :   O(000000,71,_,_,_,_,_,_  ), // #30
+    1672             :   O(000000,7B,_,_,_,_,_,_  ), // #31
+    1673             :   O(000000,79,_,_,_,_,_,_  ), // #32
+    1674             :   O(000000,70,_,_,_,_,_,_  ), // #33
+    1675             :   O(000000,7A,_,_,_,_,_,_  ), // #34
+    1676             :   O(000000,78,_,_,_,_,_,_  ), // #35
+    1677             :   V(660F00,92,_,0,0,_,_,_  ), // #36
+    1678             :   V(F20F00,92,_,0,0,_,_,_  ), // #37
+    1679             :   V(F20F00,92,_,0,1,_,_,_  ), // #38
+    1680             :   V(000F00,92,_,0,0,_,_,_  ), // #39
+    1681             :   O(000000,E2,_,_,_,_,_,_  ), // #40
+    1682             :   O(000000,E1,_,_,_,_,_,_  ), // #41
+    1683             :   O(000000,E0,_,_,_,_,_,_  ), // #42
+    1684             :   O(660F00,29,_,_,_,_,_,_  ), // #43
+    1685             :   O(000F00,29,_,_,_,_,_,_  ), // #44
+    1686             :   O(000F38,F1,_,_,x,_,_,_  ), // #45
+    1687             :   O(000F00,7E,_,_,_,_,_,_  ), // #46
+    1688             :   O(660F00,7F,_,_,_,_,_,_  ), // #47
+    1689             :   O(F30F00,7F,_,_,_,_,_,_  ), // #48
+    1690             :   O(660F00,17,_,_,_,_,_,_  ), // #49
+    1691             :   O(000F00,17,_,_,_,_,_,_  ), // #50
+    1692             :   O(660F00,13,_,_,_,_,_,_  ), // #51
+    1693             :   O(000F00,13,_,_,_,_,_,_  ), // #52
+    1694             :   O(660F00,E7,_,_,_,_,_,_  ), // #53
+    1695             :   O(660F00,2B,_,_,_,_,_,_  ), // #54
+    1696             :   O(000F00,2B,_,_,_,_,_,_  ), // #55
+    1697             :   O(000F00,E7,_,_,_,_,_,_  ), // #56
+    1698             :   O(F20F00,2B,_,_,_,_,_,_  ), // #57
+    1699             :   O(F30F00,2B,_,_,_,_,_,_  ), // #58
+    1700             :   O(000F00,7E,_,_,x,_,_,_  ), // #59
+    1701             :   O(F20F00,11,_,_,_,_,_,_  ), // #60
+    1702             :   O(F30F00,11,_,_,_,_,_,_  ), // #61
+    1703             :   O(660F00,11,_,_,_,_,_,_  ), // #62
+    1704             :   O(000F00,11,_,_,_,_,_,_  ), // #63
+    1705             :   O(000000,E6,_,_,_,_,_,_  ), // #64
+    1706             :   O(000F3A,15,_,_,_,_,_,_  ), // #65
+    1707             :   O(000000,58,_,_,_,_,_,_  ), // #66
+    1708             :   O(000F00,72,6,_,_,_,_,_  ), // #67
+    1709             :   O(660F00,73,7,_,_,_,_,_  ), // #68
+    1710             :   O(000F00,73,6,_,_,_,_,_  ), // #69
+    1711             :   O(000F00,71,6,_,_,_,_,_  ), // #70
+    1712             :   O(000F00,72,4,_,_,_,_,_  ), // #71
+    1713             :   O(000F00,71,4,_,_,_,_,_  ), // #72
+    1714             :   O(000F00,72,2,_,_,_,_,_  ), // #73
+    1715             :   O(660F00,73,3,_,_,_,_,_  ), // #74
+    1716             :   O(000F00,73,2,_,_,_,_,_  ), // #75
+    1717             :   O(000F00,71,2,_,_,_,_,_  ), // #76
+    1718             :   O(000000,50,_,_,_,_,_,_  ), // #77
+    1719             :   O(000000,F6,_,_,x,_,_,_  ), // #78
+    1720             :   V(660F38,92,_,x,_,1,3,T1S), // #79
+    1721             :   V(660F38,92,_,x,_,0,2,T1S), // #80
+    1722             :   V(660F38,93,_,x,_,1,3,T1S), // #81
+    1723             :   V(660F38,93,_,x,_,0,2,T1S), // #82
+    1724             :   V(660F38,2F,_,x,0,_,_,_  ), // #83
+    1725             :   V(660F38,2E,_,x,0,_,_,_  ), // #84
+    1726             :   V(660F00,29,_,x,I,1,4,FVM), // #85
+    1727             :   V(000F00,29,_,x,I,0,4,FVM), // #86
+    1728             :   V(660F00,7E,_,0,0,0,2,T1S), // #87
+    1729             :   V(660F00,7F,_,x,I,_,_,_  ), // #88
+    1730             :   V(660F00,7F,_,x,_,0,4,FVM), // #89
+    1731             :   V(660F00,7F,_,x,_,1,4,FVM), // #90
+    1732             :   V(F30F00,7F,_,x,I,_,_,_  ), // #91
+    1733             :   V(F20F00,7F,_,x,_,1,4,FVM), // #92
+    1734             :   V(F30F00,7F,_,x,_,0,4,FVM), // #93
+    1735             :   V(F30F00,7F,_,x,_,1,4,FVM), // #94
+    1736             :   V(F20F00,7F,_,x,_,0,4,FVM), // #95
+    1737             :   V(660F00,17,_,0,I,1,3,T1S), // #96
+    1738             :   V(000F00,17,_,0,I,0,3,T2 ), // #97
+    1739             :   V(660F00,13,_,0,I,1,3,T1S), // #98
+    1740             :   V(000F00,13,_,0,I,0,3,T2 ), // #99
+    1741             :   V(660F00,7E,_,0,I,1,3,T1S), // #100
+    1742             :   V(F20F00,11,_,I,I,1,3,T1S), // #101
+    1743             :   V(F30F00,11,_,I,I,0,2,T1S), // #102
+    1744             :   V(660F00,11,_,x,I,1,4,FVM), // #103
+    1745             :   V(000F00,11,_,x,I,0,4,FVM), // #104
+    1746             :   V(660F3A,05,_,x,0,1,4,FV ), // #105
+    1747             :   V(660F3A,04,_,x,0,0,4,FV ), // #106
+    1748             :   V(660F3A,00,_,x,1,1,4,FV ), // #107
+    1749             :   V(660F38,90,_,x,_,0,2,T1S), // #108
+    1750             :   V(660F38,90,_,x,_,1,3,T1S), // #109
+    1751             :   V(660F38,91,_,x,_,0,2,T1S), // #110
+    1752             :   V(660F38,91,_,x,_,1,3,T1S), // #111
+    1753             :   V(660F38,8E,_,x,0,_,_,_  ), // #112
+    1754             :   V(660F38,8E,_,x,1,_,_,_  ), // #113
+    1755             :   V(XOP_M8,C0,_,0,x,_,_,_  ), // #114
+    1756             :   V(XOP_M8,C2,_,0,x,_,_,_  ), // #115
+    1757             :   V(XOP_M8,C3,_,0,x,_,_,_  ), // #116
+    1758             :   V(XOP_M8,C1,_,0,x,_,_,_  ), // #117
+    1759             :   V(660F00,72,6,x,I,0,4,FV ), // #118
+    1760             :   V(660F00,73,6,x,I,1,4,FV ), // #119
+    1761             :   V(660F00,71,6,x,I,I,4,FVM), // #120
+    1762             :   V(660F00,72,4,x,I,0,4,FV ), // #121
+    1763             :   V(660F00,72,4,x,_,1,4,FV ), // #122
+    1764             :   V(660F00,71,4,x,I,I,4,FVM), // #123
+    1765             :   V(660F00,72,2,x,I,0,4,FV ), // #124
+    1766             :   V(660F00,73,2,x,I,1,4,FV ), // #125
+    1767             :   V(660F00,71,2,x,I,I,4,FVM)  // #126
+    1768             : };
+    1769             : // ----------------------------------------------------------------------------
+    1770             : // ${altOpCodeData:End}
+    1771             : 
+    1772             : #undef O_FPU
+    1773             : #undef O
+    1774             : #undef V
+    1775             : 
+    1776             : // ${commonData:Begin}
+    1777             : // ------------------- Automatically generated, do not edit -------------------
+    1778             : #define F(VAL) X86Inst::kFlag##VAL
+    1779             : #define JUMP_TYPE(VAL) Inst::kJumpType##VAL
+    1780             : #define SINGLE_REG(VAL) X86Inst::kSingleReg##VAL
+    1781             : const X86Inst::CommonData X86InstDB::commonData[] = {
+    1782             :   { F(UseR)                                               , 0  , 0  , 0  , 0  , 0 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #0
+    1783             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 383, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #1
+    1784             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 384, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #2
+    1785             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 15 , 12, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #3
+    1786             :   { F(UseX)                                               , 0  , 0  , 0  , 25 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #4
+    1787             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 336, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #5
+    1788             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 385, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #6
+    1789             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 386, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #7
+    1790             :   { F(UseW)|F(Vec)                                        , 0  , 0  , 0  , 87 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #8
+    1791             :   { F(UseW)|F(Vec)                                        , 0  , 0  , 0  , 94 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #9
+    1792             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 39 , 11, JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #10
+    1793             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 273, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #11
+    1794             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 336, 1 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #12
+    1795             :   { F(UseX)                                               , 0  , 0  , 0  , 387, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #13
+    1796             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 275, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #14
+    1797             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 184, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #15
+    1798             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 338, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #16
+    1799             :   { F(UseX)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 388, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #17
+    1800             :   { F(UseR)                                               , 0  , 0  , 0  , 277, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #18
+    1801             :   { F(UseW)|F(Mib)                                        , 0  , 0  , 0  , 389, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #19
+    1802             :   { F(UseW)                                               , 0  , 0  , 0  , 390, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #20
+    1803             :   { F(UseW)                                               , 0  , 0  , 1  , 279, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #21
+    1804             :   { F(UseW)|F(Mib)                                        , 0  , 0  , 0  , 391, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #22
+    1805             :   { F(UseR)                                               , 0  , 0  , 0  , 281, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #23
+    1806             :   { F(UseX)                                               , 0  , 0  , 0  , 24 , 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #24
+    1807             :   { F(UseX)                                               , 0  , 0  , 0  , 392, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #25
+    1808             :   { F(UseR)                                               , 0  , 0  , 2  , 126, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #26
+    1809             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 3  , 130, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #27
+    1810             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 4  , 130, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #28
+    1811             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 5  , 130, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #29
+    1812             :   { F(UseR)                                               , 0  , 0  , 0  , 283, 2 , JUMP_TYPE(Call)       , SINGLE_REG(None), 0 }, // #30
+    1813             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 393, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #31
+    1814             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 394, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #32
+    1815             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 395, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #33
+    1816             :   { F(UseR)                                               , 0  , 0  , 0  , 291, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #34
+    1817             :   { F(UseR)                                               , 0  , 0  , 0  , 396, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #35
+    1818             :   { F(UseR)|F(FixedRM)                                    , 0  , 0  , 0  , 397, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #36
+    1819             :   { F(UseR)                                               , 0  , 0  , 0  , 27 , 12, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #37
+    1820             :   { F(UseX)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 398, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #38
+    1821             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 399, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #39
+    1822             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 400, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #40
+    1823             :   { F(UseX)|F(FixedReg)|F(Lock)|F(XAcquire)|F(XRelease)   , 0  , 0  , 0  , 134, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #41
+    1824             :   { F(UseX)|F(FixedReg)|F(Lock)|F(XAcquire)|F(XRelease)   , 0  , 0  , 0  , 401, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #42
+    1825             :   { F(UseX)|F(FixedReg)|F(Lock)|F(XAcquire)|F(XRelease)   , 0  , 0  , 0  , 402, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #43
+    1826             :   { F(UseR)|F(Vec)                                        , 0  , 0  , 0  , 403, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #44
+    1827             :   { F(UseR)|F(Vec)                                        , 0  , 0  , 0  , 404, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #45
+    1828             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 405, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #46
+    1829             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 406, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #47
+    1830             :   { F(UseX)                                               , 0  , 0  , 0  , 285, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #48
+    1831             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #49
+    1832             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 87 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #50
+    1833             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 407, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #51
+    1834             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 0  , 408, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #52
+    1835             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 408, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #53
+    1836             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 409, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #54
+    1837             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #55
+    1838             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #56
+    1839             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 411, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #57
+    1840             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 411, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #58
+    1841             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #59
+    1842             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #60
+    1843             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 413, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #61
+    1844             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 414, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #62
+    1845             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 6  , 287, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #63
+    1846             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 138, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #64
+    1847             :   { F(UseR)|F(Mmx)                                        , 0  , 0  , 0  , 291, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #65
+    1848             :   { F(UseR)                                               , 0  , 0  , 0  , 415, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #66
+    1849             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 416, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #67
+    1850             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 7  , 289, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #68
+    1851             :   { F(UseA)|F(FixedReg)|F(FpuM32)|F(FpuM64)               , 0  , 0  , 0  , 174, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #69
+    1852             :   { F(UseX)                                               , 0  , 0  , 0  , 291, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #70
+    1853             :   { F(UseR)|F(FpuM80)                                     , 0  , 0  , 0  , 417, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #71
+    1854             :   { F(UseW)|F(FpuM80)                                     , 0  , 0  , 0  , 418, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #72
+    1855             :   { F(UseX)                                               , 0  , 0  , 0  , 292, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #73
+    1856             :   { F(UseR)|F(FpuM32)|F(FpuM64)                           , 0  , 0  , 0  , 293, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #74
+    1857             :   { F(UseR)                                               , 0  , 0  , 0  , 296, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #75
+    1858             :   { F(UseR)|F(FpuM16)|F(FpuM32)                           , 0  , 0  , 0  , 419, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #76
+    1859             :   { F(UseR)|F(FpuM16)|F(FpuM32)|F(FpuM64)                 , 0  , 0  , 8  , 420, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #77
+    1860             :   { F(UseW)|F(FpuM16)|F(FpuM32)                           , 0  , 0  , 0  , 421, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #78
+    1861             :   { F(UseW)|F(FpuM16)|F(FpuM32)|F(FpuM64)                 , 0  , 0  , 9  , 422, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #79
+    1862             :   { F(UseW)|F(FpuM16)|F(FpuM32)|F(FpuM64)                 , 0  , 0  , 10 , 422, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #80
+    1863             :   { F(UseR)|F(FpuM32)|F(FpuM64)|F(FpuM80)                 , 0  , 0  , 11 , 423, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #81
+    1864             :   { F(UseR)|F(FpuM16)                                     , 0  , 0  , 0  , 424, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #82
+    1865             :   { F(UseX)|F(FixedReg)|F(FpuM32)|F(FpuM64)               , 0  , 0  , 0  , 177, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #83
+    1866             :   { F(UseW)                                               , 0  , 0  , 0  , 425, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #84
+    1867             :   { F(UseW)|F(FpuM16)                                     , 0  , 0  , 0  , 426, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #85
+    1868             :   { F(UseW)|F(FixedReg)|F(FpuM16)                         , 0  , 0  , 12 , 427, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #86
+    1869             :   { F(UseW)|F(FpuM32)|F(FpuM64)                           , 0  , 0  , 0  , 428, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #87
+    1870             :   { F(UseW)|F(FpuM32)|F(FpuM64)|F(FpuM80)                 , 0  , 0  , 13 , 429, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #88
+    1871             :   { F(UseW)|F(FixedReg)|F(FpuM16)                         , 0  , 0  , 14 , 427, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #89
+    1872             :   { F(UseR)                                               , 0  , 0  , 0  , 295, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #90
+    1873             :   { F(UseR)                                               , 0  , 0  , 0  , 430, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #91
+    1874             :   { F(UseW)                                               , 0  , 0  , 0  , 431, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #92
+    1875             :   { F(UseA)|F(FixedReg)                                   , 0  , 0  , 0  , 50 , 10, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #93
+    1876             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 15 , 432, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #94
+    1877             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 16 , 287, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #95
+    1878             :   { F(UseW)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 433, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #96
+    1879             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 17 , 297, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #97
+    1880             :   { F(UseR)                                               , 0  , 0  , 0  , 434, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #98
+    1881             :   { F(UseR)                                               , 0  , 0  , 0  , 435, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #99
+    1882             :   { F(UseR)                                               , 0  , 0  , 0  , 299, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #100
+    1883             :   { F(UseR)                                               , 0  , 0  , 0  , 436, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #101
+    1884             :   { F(UseR)                                               , 0  , 0  , 18 , 437, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #102
+    1885             :   { F(UseR)                                               , 0  , 0  , 19 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #103
+    1886             :   { F(UseR)                                               , 0  , 0  , 20 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #104
+    1887             :   { F(UseR)                                               , 0  , 0  , 21 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #105
+    1888             :   { F(UseR)                                               , 0  , 0  , 20 , 438, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #106
+    1889             :   { F(UseR)                                               , 0  , 0  , 22 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #107
+    1890             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 23 , 301, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #108
+    1891             :   { F(UseR)                                               , 0  , 0  , 24 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #109
+    1892             :   { F(UseR)                                               , 0  , 0  , 25 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #110
+    1893             :   { F(UseR)                                               , 0  , 0  , 26 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #111
+    1894             :   { F(UseR)                                               , 0  , 0  , 27 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #112
+    1895             :   { F(UseR)                                               , 0  , 0  , 28 , 303, 2 , JUMP_TYPE(Direct)     , SINGLE_REG(None), 0 }, // #113
+    1896             :   { F(UseR)                                               , 0  , 0  , 19 , 438, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #114
+    1897             :   { F(UseR)                                               , 0  , 0  , 29 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #115
+    1898             :   { F(UseR)                                               , 0  , 0  , 30 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #116
+    1899             :   { F(UseR)                                               , 0  , 0  , 31 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #117
+    1900             :   { F(UseR)                                               , 0  , 0  , 32 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #118
+    1901             :   { F(UseR)                                               , 0  , 0  , 33 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #119
+    1902             :   { F(UseR)                                               , 0  , 0  , 34 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #120
+    1903             :   { F(UseR)                                               , 0  , 0  , 35 , 437, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #121
+    1904             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 439, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #122
+    1905             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 36 , 305, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #123
+    1906             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 37 , 307, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #124
+    1907             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 38 , 309, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #125
+    1908             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 39 , 311, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #126
+    1909             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 440, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #127
+    1910             :   { F(UseR)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 441, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #128
+    1911             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 442, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #129
+    1912             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 443, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #130
+    1913             :   { F(UseW)                                               , 0  , 0  , 0  , 313, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #131
+    1914             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 228, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #132
+    1915             :   { F(UseR)                                               , 0  , 0  , 0  , 444, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #133
+    1916             :   { F(UseX)                                               , 0  , 0  , 0  , 315, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #134
+    1917             :   { F(UseW)                                               , 0  , 0  , 0  , 445, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #135
+    1918             :   { F(UseX)                                               , 0  , 0  , 0  , 180, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #136
+    1919             :   { F(UseR)                                               , 0  , 0  , 0  , 446, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #137
+    1920             :   { F(UseW)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 447, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #138
+    1921             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 40 , 317, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #139
+    1922             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 41 , 317, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #140
+    1923             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 42 , 317, 2 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #141
+    1924             :   { F(UseW)                                               , 0  , 0  , 0  , 319, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #142
+    1925             :   { F(UseW)                                               , 0  , 0  , 0  , 183, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #143
+    1926             :   { F(UseX)|F(FixedRM)|F(Vec)                             , 0  , 0  , 0  , 448, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #144
+    1927             :   { F(UseX)|F(FixedRM)|F(Mmx)                             , 0  , 0  , 0  , 449, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #145
+    1928             :   { F(UseR)|F(FixedRM)                                    , 0  , 0  , 0  , 450, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #146
+    1929             :   { F(UseW)|F(XRelease)                                   , 0  , 0  , 0  , 0  , 15, JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #147
+    1930             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 43 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #148
+    1931             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 44 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #149
+    1932             :   { F(UseW)                                               , 0  , 0  , 45 , 75 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #150
+    1933             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 46 , 321, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #151
+    1934             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 451, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #152
+    1935             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 47 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #153
+    1936             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 48 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #154
+    1937             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 452, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #155
+    1938             :   { F(UseW)|F(Vec)                                        , 8  , 8  , 49 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #156
+    1939             :   { F(UseW)|F(Vec)                                        , 8  , 8  , 50 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #157
+    1940             :   { F(UseW)|F(Vec)                                        , 8  , 8  , 0  , 452, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #158
+    1941             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 51 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #159
+    1942             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 52 , 234, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #160
+    1943             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 453, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #161
+    1944             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 53 , 225, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #162
+    1945             :   { F(UseW)                                               , 0  , 8  , 0  , 79 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #163
+    1946             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 54 , 225, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #164
+    1947             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 55 , 225, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #165
+    1948             :   { F(UseW)|F(Mmx)                                        , 0  , 8  , 56 , 454, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #166
+    1949             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 57 , 234, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #167
+    1950             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 58 , 237, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #168
+    1951             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 59 , 81 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #169
+    1952             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 16 , 0  , 455, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #170
+    1953             :   { F(UseX)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 456, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #171
+    1954             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 60 , 323, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #172
+    1955             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 61 , 325, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #173
+    1956             :   { F(UseW)                                               , 0  , 0  , 0  , 327, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #174
+    1957             :   { F(UseW)                                               , 0  , 0  , 0  , 457, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #175
+    1958             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 62 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #176
+    1959             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 63 , 87 , 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #177
+    1960             :   { F(UseA)|F(FixedReg)                                   , 0  , 0  , 0  , 50 , 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #178
+    1961             :   { F(UseW)|F(FixedReg)|F(Vex)                            , 0  , 0  , 0  , 329, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #179
+    1962             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 458, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #180
+    1963             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 288, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #181
+    1964             :   { F(UseR)                                               , 0  , 0  , 0  , 331, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #182
+    1965             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 15 , 12, JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #183
+    1966             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 64 , 459, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #184
+    1967             :   { F(UseR)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 460, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #185
+    1968             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 333, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #186
+    1969             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 335, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #187
+    1970             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 337, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #188
+    1971             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 335, 2 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #189
+    1972             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 335, 2 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #190
+    1973             :   { F(UseX)|F(Mmx)                                        , 0  , 0  , 0  , 335, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #191
+    1974             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 336, 1 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #192
+    1975             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 461, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #193
+    1976             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 462, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #194
+    1977             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 463, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #195
+    1978             :   { F(UseR)|F(FixedReg)|F(Vec)                            , 0  , 0  , 0  , 464, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #196
+    1979             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 465, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #197
+    1980             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 466, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #198
+    1981             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 65 , 339, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #199
+    1982             :   { F(UseW)|F(Mmx)                                        , 0  , 8  , 0  , 333, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #200
+    1983             :   { F(UseW)|F(Mmx)                                        , 0  , 0  , 0  , 333, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #201
+    1984             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 467, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #202
+    1985             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 468, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #203
+    1986             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 0  , 469, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #204
+    1987             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 0  , 470, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #205
+    1988             :   { F(UseW)|F(Mmx)|F(Vec)                                 , 0  , 8  , 0  , 471, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #206
+    1989             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #207
+    1990             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 258, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #208
+    1991             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 66 , 142, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #209
+    1992             :   { F(UseW)|F(Vec)                                        , 0  , 16 , 0  , 94 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #210
+    1993             :   { F(UseW)|F(Mmx)                                        , 0  , 8  , 0  , 472, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #211
+    1994             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 67 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #212
+    1995             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 68 , 473, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #213
+    1996             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 69 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #214
+    1997             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 70 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #215
+    1998             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 71 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #216
+    1999             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 72 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #217
+    2000             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 73 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #218
+    2001             :   { F(UseX)|F(Vec)                                        , 0  , 0  , 74 , 473, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #219
+    2002             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 75 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #220
+    2003             :   { F(UseX)|F(Mmx)|F(Vec)                                 , 0  , 0  , 76 , 341, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #221
+    2004             :   { F(UseR)|F(Vec)                                        , 0  , 0  , 0  , 379, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #222
+    2005             :   { F(UseA)|F(FixedReg)                                   , 0  , 0  , 77 , 146, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #223
+    2006             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 474, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #224
+    2007             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #225
+    2008             :   { F(UseW)                                               , 0  , 8  , 0  , 475, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #226
+    2009             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 476, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #227
+    2010             :   { F(UseW)                                               , 0  , 8  , 0  , 477, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #228
+    2011             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 478, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #229
+    2012             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 479, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #230
+    2013             :   { F(UseR)                                               , 0  , 0  , 0  , 343, 2 , JUMP_TYPE(Return)     , SINGLE_REG(None), 0 }, // #231
+    2014             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 345, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #232
+    2015             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 480, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #233
+    2016             :   { F(UseW)|F(Vec)                                        , 0  , 4  , 0  , 481, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #234
+    2017             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 482, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #235
+    2018             :   { F(UseR)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 483, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #236
+    2019             :   { F(UseW)                                               , 0  , 1  , 0  , 484, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #237
+    2020             :   { F(UseX)|F(FixedReg)                                   , 0  , 0  , 0  , 186, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #238
+    2021             :   { F(UseW)                                               , 0  , 0  , 0  , 485, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #239
+    2022             :   { F(UseW)|F(Vec)                                        , 0  , 8  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #240
+    2023             :   { F(UseW)                                               , 0  , 0  , 0  , 486, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #241
+    2024             :   { F(UseX)|F(FixedRM)|F(Rep)|F(Repnz)                    , 0  , 0  , 0  , 487, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #242
+    2025             :   { F(UseX)|F(Lock)|F(XAcquire)|F(XRelease)               , 0  , 0  , 0  , 15 , 12, JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #243
+    2026             :   { F(UseR)                                               , 0  , 0  , 78 , 68 , 7 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #244
+    2027             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ)       , 0  , 0  , 0  , 488, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #245
+    2028             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #246
+    2029             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #247
+    2030             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #248
+    2031             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #249
+    2032             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 189, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #250
+    2033             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 93 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #251
+    2034             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 87 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #252
+    2035             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 94 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #253
+    2036             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #254
+    2037             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #255
+    2038             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #256
+    2039             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #257
+    2040             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #258
+    2041             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #259
+    2042             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #260
+    2043             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #261
+    2044             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #262
+    2045             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 192, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #263
+    2046             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 347, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #264
+    2047             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 491, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #265
+    2048             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 492, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #266
+    2049             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 493, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #267
+    2050             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 494, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #268
+    2051             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 495, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #269
+    2052             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 260, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #270
+    2053             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 492, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #271
+    2054             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 363, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #272
+    2055             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64)     , 0  , 0  , 0  , 195, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #273
+    2056             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32)     , 0  , 0  , 0  , 195, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #274
+    2057             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 496, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #275
+    2058             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 497, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #276
+    2059             :   { F(UseR)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 403, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #277
+    2060             :   { F(UseR)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 404, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #278
+    2061             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 198, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #279
+    2062             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #280
+    2063             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #281
+    2064             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #282
+    2065             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 207, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #283
+    2066             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64)         , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #284
+    2067             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64)         , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #285
+    2068             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #286
+    2069             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #287
+    2070             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 210, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #288
+    2071             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32)         , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #289
+    2072             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32)         , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #290
+    2073             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE)         , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #291
+    2074             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512ER_SAE)                , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #292
+    2075             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE)         , 0  , 0  , 0  , 498, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #293
+    2076             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #294
+    2077             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512ER_SAE)         , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #295
+    2078             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512ER_SAE)                , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #296
+    2079             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64)     , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #297
+    2080             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #298
+    2081             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 349, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #299
+    2082             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32)     , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #300
+    2083             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #301
+    2084             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #302
+    2085             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #303
+    2086             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512SAE)                   , 0  , 0  , 0  , 410, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #304
+    2087             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512SAE)            , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #305
+    2088             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512SAE)                   , 0  , 0  , 0  , 412, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #306
+    2089             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #307
+    2090             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512ER_SAE)                , 0  , 0  , 0  , 498, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #308
+    2091             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #309
+    2092             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 192, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #310
+    2093             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #311
+    2094             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #312
+    2095             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #313
+    2096             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 211, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #314
+    2097             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 499, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #315
+    2098             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 212, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #316
+    2099             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 416, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #317
+    2100             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #318
+    2101             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #319
+    2102             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 500, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #320
+    2103             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 501, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #321
+    2104             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #322
+    2105             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B32)  , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #323
+    2106             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 502, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #324
+    2107             :   { F(UseX)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE)      , 0  , 0  , 0  , 503, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #325
+    2108             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 150, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #326
+    2109             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 351, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #327
+    2110             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 353, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #328
+    2111             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B64)                 , 0  , 0  , 0  , 504, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #329
+    2112             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B32)                 , 0  , 0  , 0  , 504, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #330
+    2113             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 505, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #331
+    2114             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 506, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #332
+    2115             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 204, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #333
+    2116             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #334
+    2117             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #335
+    2118             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 79 , 111, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #336
+    2119             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 80 , 116, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #337
+    2120             :   { F(UseR)|F(Vsib)|F(Evex)|F(Avx512K)                    , 0  , 0  , 0  , 507, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #338
+    2121             :   { F(UseR)|F(Vsib)|F(Evex)|F(Avx512K)                    , 0  , 0  , 0  , 508, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #339
+    2122             :   { F(UseR)|F(Vsib)|F(Evex)|F(Avx512K)                    , 0  , 0  , 0  , 509, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #340
+    2123             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 81 , 121, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #341
+    2124             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 82 , 154, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #342
+    2125             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 85 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #343
+    2126             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 255, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #344
+    2127             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #345
+    2128             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #346
+    2129             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 480, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #347
+    2130             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 481, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #348
+    2131             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 355, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #349
+    2132             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 355, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #350
+    2133             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 510, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #351
+    2134             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #352
+    2135             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 228, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #353
+    2136             :   { F(UseR)|F(Vex)                                        , 0  , 0  , 0  , 444, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #354
+    2137             :   { F(UseR)|F(FixedRM)|F(Vec)|F(Vex)                      , 0  , 0  , 0  , 512, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #355
+    2138             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 83 , 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #356
+    2139             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 84 , 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #357
+    2140             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B64)     , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #358
+    2141             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE_B32)     , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #359
+    2142             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_SAE)         , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #360
+    2143             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 85 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #361
+    2144             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 86 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #362
+    2145             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 87 , 357, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #363
+    2146             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 222, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #364
+    2147             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 88 , 87 , 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #365
+    2148             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 89 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #366
+    2149             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 90 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #367
+    2150             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 91 , 87 , 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #368
+    2151             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 92 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #369
+    2152             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 93 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #370
+    2153             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 94 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #371
+    2154             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 95 , 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #372
+    2155             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 236, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #373
+    2156             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 96 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #374
+    2157             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 97 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #375
+    2158             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 98 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #376
+    2159             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 99 , 359, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #377
+    2160             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 513, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #378
+    2161             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 225, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #379
+    2162             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 228, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #380
+    2163             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 100, 231, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #381
+    2164             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 101, 234, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #382
+    2165             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #383
+    2166             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 102, 237, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #384
+    2167             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 103, 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #385
+    2168             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 104, 87 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #386
+    2169             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512T4X)|F(Avx512KZ)       , 0  , 0  , 0  , 514, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #387
+    2170             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #388
+    2171             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #389
+    2172             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 189, 2 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #390
+    2173             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #391
+    2174             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 189, 2 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #392
+    2175             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #393
+    2176             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #394
+    2177             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #395
+    2178             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 361, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #396
+    2179             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 363, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #397
+    2180             :   { F(UseW)|F(Vec)|F(Evex)                                , 0  , 0  , 0  , 515, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #398
+    2181             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 516, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #399
+    2182             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 365, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #400
+    2183             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 240, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #401
+    2184             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B32)                 , 0  , 0  , 0  , 240, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #402
+    2185             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512K)              , 0  , 0  , 0  , 243, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #403
+    2186             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512K_B32)          , 0  , 0  , 0  , 243, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #404
+    2187             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512K_B64)          , 0  , 0  , 0  , 243, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #405
+    2188             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 461, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #406
+    2189             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 462, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #407
+    2190             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 463, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #408
+    2191             :   { F(UseR)|F(FixedReg)|F(Vec)|F(Vex)                     , 0  , 0  , 0  , 464, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #409
+    2192             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B64)                 , 0  , 0  , 0  , 240, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #410
+    2193             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #411
+    2194             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 193, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #412
+    2195             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 167, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #413
+    2196             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #414
+    2197             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #415
+    2198             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 216, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #416
+    2199             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 162, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #417
+    2200             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 105, 93 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #418
+    2201             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 106, 93 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #419
+    2202             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 96 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #420
+    2203             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 95 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #421
+    2204             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 107, 166, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #422
+    2205             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 465, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #423
+    2206             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 466, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #424
+    2207             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 340, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #425
+    2208             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 108, 116, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #426
+    2209             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 109, 111, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #427
+    2210             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 110, 154, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #428
+    2211             :   { F(UseX)|F(Vec)|F(Vsib)|F(Vex)|F(Evex)|F(Avx512K)      , 0  , 0  , 111, 121, 5 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #429
+    2212             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 367, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #430
+    2213             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 369, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #431
+    2214             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 371, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #432
+    2215             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 517, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #433
+    2216             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #434
+    2217             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 151, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #435
+    2218             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 112, 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #436
+    2219             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 113, 158, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #437
+    2220             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #438
+    2221             :   { F(UseW)|F(Vec)|F(Evex)                                , 0  , 0  , 0  , 518, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #439
+    2222             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 246, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #440
+    2223             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 249, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #441
+    2224             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 252, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #442
+    2225             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 255, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #443
+    2226             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 258, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #444
+    2227             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 201, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #445
+    2228             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 261, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #446
+    2229             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #447
+    2230             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 91 , 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #448
+    2231             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 150, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #449
+    2232             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #450
+    2233             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #451
+    2234             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 114, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #452
+    2235             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 115, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #453
+    2236             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 116, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #454
+    2237             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 117, 373, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #455
+    2238             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #456
+    2239             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 264, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #457
+    2240             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 375, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #458
+    2241             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 267, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #459
+    2242             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 377, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #460
+    2243             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #461
+    2244             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #462
+    2245             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 118, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #463
+    2246             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)                         , 0  , 0  , 0  , 219, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #464
+    2247             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 119, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #465
+    2248             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 120, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #466
+    2249             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 121, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #467
+    2250             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 122, 105, 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #468
+    2251             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 123, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #469
+    2252             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 124, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #470
+    2253             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 125, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #471
+    2254             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 126, 99 , 6 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #472
+    2255             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ)             , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #473
+    2256             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #474
+    2257             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(WO)  , 0 }, // #475
+    2258             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #476
+    2259             :   { F(UseX)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 213, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #477
+    2260             :   { F(UseR)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 379, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #478
+    2261             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K)                     , 0  , 0  , 0  , 270, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #479
+    2262             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B32)                 , 0  , 0  , 0  , 270, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #480
+    2263             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512K_B64)                 , 0  , 0  , 0  , 270, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #481
+    2264             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B64)            , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #482
+    2265             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE_B32)            , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #483
+    2266             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 519, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #484
+    2267             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #485
+    2268             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #486
+    2269             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #487
+    2270             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #488
+    2271             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_SAE)                , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #489
+    2272             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #490
+    2273             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 519, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #491
+    2274             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ)                    , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #492
+    2275             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 101, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #493
+    2276             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 519, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #494
+    2277             :   { F(UseW)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 511, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #495
+    2278             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B64)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #496
+    2279             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE_B32)         , 0  , 0  , 0  , 189, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #497
+    2280             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE)             , 0  , 0  , 0  , 489, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #498
+    2281             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_ER_SAE)             , 0  , 0  , 0  , 490, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #499
+    2282             :   { F(UseW)|F(Vec)|F(Vsib)|F(Evex)|F(Avx512K)             , 0  , 0  , 0  , 381, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #500
+    2283             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B32)                , 0  , 0  , 0  , 193, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #501
+    2284             :   { F(UseW)|F(Vec)|F(Evex)|F(Avx512KZ_B64)                , 0  , 0  , 0  , 193, 2 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #502
+    2285             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B32)         , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #503
+    2286             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_B64)         , 0  , 0  , 0  , 192, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #504
+    2287             :   { F(UseW)|F(Vec)|F(Vex)|F(Evex)|F(Avx512KZ_ER_SAE_B64)  , 0  , 0  , 0  , 204, 3 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #505
+    2288             :   { F(UseW)|F(Vex)                                        , 0  , 0  , 0  , 486, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #506
+    2289             :   { F(UseR)|F(Vec)|F(Vex)                                 , 0  , 0  , 0  , 291, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #507
+    2290             :   { F(UseR)                                               , 0  , 0  , 0  , 520, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #508
+    2291             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 521, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #509
+    2292             :   { F(UseX)|F(UseXX)|F(Lock)|F(XAcquire)|F(XRelease)      , 0  , 0  , 0  , 170, 4 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #510
+    2293             :   { F(UseR)                                               , 0  , 0  , 0  , 522, 1 , JUMP_TYPE(Conditional), SINGLE_REG(None), 0 }, // #511
+    2294             :   { F(UseX)|F(UseXX)|F(Lock)|F(XAcquire)                  , 0  , 0  , 0  , 60 , 8 , JUMP_TYPE(None)       , SINGLE_REG(RO)  , 0 }, // #512
+    2295             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 523, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #513
+    2296             :   { F(UseR)|F(FixedReg)                                   , 0  , 0  , 0  , 524, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #514
+    2297             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 525, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }, // #515
+    2298             :   { F(UseW)|F(FixedReg)                                   , 0  , 0  , 0  , 526, 1 , JUMP_TYPE(None)       , SINGLE_REG(None), 0 }  // #516
+    2299             : };
+    2300             : #undef SINGLE_REG
+    2301             : #undef JUMP_TYPE
+    2302             : #undef F
+    2303             : // ----------------------------------------------------------------------------
+    2304             : // ${commonData:End}
+    2305             : 
+    2306             : // ${operationData:Begin}
+    2307             : // ------------------- Automatically generated, do not edit -------------------
+    2308             : #define OP_FLAG(F) X86Inst::kOperation##F
+    2309             : #define FEATURE(F) CpuInfo::kX86Feature##F
+    2310             : #define SPECIAL(F) x86::kSpecialReg_##F
+    2311             : const X86Inst::OperationData X86InstDB::operationData[] = {
+    2312             :   { 0, { 0 }, 0, 0 }, // #0
+    2313             :   { 0, { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #1
+    2314             :   { 0, { 0 }, SPECIAL(FLAGS_CF), SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #2
+    2315             :   { 0, { FEATURE(ADX) }, SPECIAL(FLAGS_CF), SPECIAL(FLAGS_CF) }, // #3
+    2316             :   { 0, { FEATURE(SSE2) }, 0, 0 }, // #4
+    2317             :   { 0, { FEATURE(SSE) }, 0, 0 }, // #5
+    2318             :   { 0, { FEATURE(SSE3) }, 0, 0 }, // #6
+    2319             :   { 0, { FEATURE(ADX) }, SPECIAL(FLAGS_OF), SPECIAL(FLAGS_OF) }, // #7
+    2320             :   { 0, { FEATURE(AESNI) }, 0, 0 }, // #8
+    2321             :   { 0, { FEATURE(BMI) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #9
+    2322             :   { 0, { 0 }, 0, SPECIAL(FLAGS_ZF) }, // #10
+    2323             :   { 0, { FEATURE(TBM) }, 0, 0 }, // #11
+    2324             :   { 0, { FEATURE(SSE4_1) }, 0, 0 }, // #12
+    2325             :   { 0, { FEATURE(MPX) }, 0, 0 }, // #13
+    2326             :   { 0, { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) }, // #14
+    2327             :   { 0, { FEATURE(BMI2) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #15
+    2328             :   { OP_FLAG(Volatile), { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #16
+    2329             :   { OP_FLAG(Volatile), { FEATURE(SMAP) }, 0, SPECIAL(FLAGS_AC) }, // #17
+    2330             :   { 0, { 0 }, 0, SPECIAL(FLAGS_CF) }, // #18
+    2331             :   { 0, { 0 }, 0, SPECIAL(FLAGS_DF) }, // #19
+    2332             :   { OP_FLAG(Volatile), { FEATURE(CLFLUSH) }, 0, 0 }, // #20
+    2333             :   { OP_FLAG(Volatile), { FEATURE(CLFLUSHOPT) }, 0, 0 }, // #21
+    2334             :   { OP_FLAG(Volatile), { 0 }, 0, SPECIAL(FLAGS_IF) }, // #22
+    2335             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { 0 }, 0, 0 }, // #23
+    2336             :   { OP_FLAG(Volatile), { FEATURE(CLWB) }, 0, 0 }, // #24
+    2337             :   { OP_FLAG(Volatile), { FEATURE(CLZERO) }, 0, 0 }, // #25
+    2338             :   { 0, { 0 }, SPECIAL(FLAGS_CF), SPECIAL(FLAGS_CF) }, // #26
+    2339             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_ZF), 0 }, // #27
+    2340             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_CF), 0 }, // #28
+    2341             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_ZF), 0 }, // #29
+    2342             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #30
+    2343             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF), 0 }, // #31
+    2344             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_OF), 0 }, // #32
+    2345             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_PF), 0 }, // #33
+    2346             :   { 0, { FEATURE(CMOV) }, SPECIAL(FLAGS_SF), 0 }, // #34
+    2347             :   { 0, { 0 }, SPECIAL(FLAGS_DF), SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #35
+    2348             :   { 0, { FEATURE(I486) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #36
+    2349             :   { OP_FLAG(Volatile), { FEATURE(CMPXCHG16B) }, 0, SPECIAL(FLAGS_ZF) }, // #37
+    2350             :   { OP_FLAG(Volatile), { FEATURE(CMPXCHG8B) }, 0, SPECIAL(FLAGS_ZF) }, // #38
+    2351             :   { 0, { FEATURE(SSE2) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #39
+    2352             :   { 0, { FEATURE(SSE) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #40
+    2353             :   { OP_FLAG(Volatile), { FEATURE(I486) }, 0, 0 }, // #41
+    2354             :   { 0, { FEATURE(SSE4_2) }, 0, 0 }, // #42
+    2355             :   { 0, { 0 }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #43
+    2356             :   { OP_FLAG(Volatile), { FEATURE(MMX) }, 0, 0 }, // #44
+    2357             :   { OP_FLAG(Volatile), { 0 }, 0, 0 }, // #45
+    2358             :   { 0, { FEATURE(SSE4A) }, 0, 0 }, // #46
+    2359             :   { 0, { 0 }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #47
+    2360             :   { 0, { FEATURE(CMOV) }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #48
+    2361             :   { 0, { 0 }, 0, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_ZF) | SPECIAL(X87SW_C1) }, // #49
+    2362             :   { OP_FLAG(Volatile), { FEATURE(3DNOW) }, 0, 0 }, // #50
+    2363             :   { 0, { FEATURE(SSE3) }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #51
+    2364             :   { OP_FLAG(Volatile), { FEATURE(FXSR) }, 0, SPECIAL(X87SW_C0) | SPECIAL(X87SW_C1) | SPECIAL(X87SW_C2) | SPECIAL(X87SW_C3) }, // #52
+    2365             :   { OP_FLAG(Volatile), { FEATURE(FXSR) }, 0, 0 }, // #53
+    2366             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_OF), 0 }, // #54
+    2367             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(I486) }, 0, 0 }, // #55
+    2368             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_ZF), 0 }, // #56
+    2369             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_CF), 0 }, // #57
+    2370             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_ZF), 0 }, // #58
+    2371             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #59
+    2372             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF), 0 }, // #60
+    2373             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_PF), 0 }, // #61
+    2374             :   { OP_FLAG(Volatile), { 0 }, SPECIAL(FLAGS_SF), 0 }, // #62
+    2375             :   { 0, { FEATURE(AVX512_DQ) }, 0, 0 }, // #63
+    2376             :   { 0, { FEATURE(AVX512_BW) }, 0, 0 }, // #64
+    2377             :   { 0, { FEATURE(AVX512_F) }, 0, 0 }, // #65
+    2378             :   { 0, { FEATURE(AVX512_DQ) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #66
+    2379             :   { 0, { FEATURE(AVX512_BW) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #67
+    2380             :   { 0, { FEATURE(AVX512_F) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #68
+    2381             :   { OP_FLAG(Volatile), { FEATURE(LAHFSAHF) }, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #69
+    2382             :   { OP_FLAG(Volatile), { 0 }, 0, SPECIAL(FLAGS_ZF) }, // #70
+    2383             :   { OP_FLAG(Barrier) | OP_FLAG(Volatile), { FEATURE(SSE2) }, 0, 0 }, // #71
+    2384             :   { 0, { 0 }, SPECIAL(FLAGS_DF), 0 }, // #72
+    2385             :   { 0, { FEATURE(LZCNT) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #73
+    2386             :   { 0, { FEATURE(MMX2) }, 0, 0 }, // #74
+    2387             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(MONITOR) }, 0, 0 }, // #75
+    2388             :   { OP_FLAG(MovCrDr), { 0 }, 0, 0 }, // #76
+    2389             :   { 0, { FEATURE(MOVBE) }, 0, 0 }, // #77
+    2390             :   { 0, { FEATURE(MMX), FEATURE(SSE2) }, 0, 0 }, // #78
+    2391             :   { OP_FLAG(MovSsSd), { FEATURE(SSE2) }, 0, 0 }, // #79
+    2392             :   { OP_FLAG(MovSsSd), { FEATURE(SSE) }, 0, 0 }, // #80
+    2393             :   { 0, { FEATURE(BMI2) }, 0, 0 }, // #81
+    2394             :   { 0, { FEATURE(SSSE3) }, 0, 0 }, // #82
+    2395             :   { 0, { FEATURE(MMX2), FEATURE(SSE2) }, 0, 0 }, // #83
+    2396             :   { 0, { FEATURE(3DNOW) }, 0, 0 }, // #84
+    2397             :   { 0, { FEATURE(PCLMULQDQ) }, 0, 0 }, // #85
+    2398             :   { 0, { FEATURE(SSE4_2) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #86
+    2399             :   { OP_FLAG(Volatile), { FEATURE(PCOMMIT) }, 0, 0 }, // #87
+    2400             :   { 0, { FEATURE(MMX2), FEATURE(SSE2), FEATURE(SSE4_1) }, 0, 0 }, // #88
+    2401             :   { 0, { FEATURE(3DNOW2) }, 0, 0 }, // #89
+    2402             :   { 0, { FEATURE(GEODE) }, 0, 0 }, // #90
+    2403             :   { 0, { FEATURE(POPCNT) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #91
+    2404             :   { OP_FLAG(Prefetch), { FEATURE(3DNOW) }, 0, 0 }, // #92
+    2405             :   { OP_FLAG(Prefetch), { FEATURE(MMX2) }, 0, 0 }, // #93
+    2406             :   { OP_FLAG(Prefetch), { FEATURE(PREFETCHW) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #94
+    2407             :   { OP_FLAG(Prefetch), { FEATURE(PREFETCHWT1) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #95
+    2408             :   { 0, { FEATURE(SSE4_1) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #96
+    2409             :   { 0, { 0 }, 0, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) }, // #97
+    2410             :   { OP_FLAG(Volatile), { FEATURE(FSGSBASE) }, 0, 0 }, // #98
+    2411             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(MSR) }, SPECIAL(MSR), 0 }, // #99
+    2412             :   { OP_FLAG(Volatile), { FEATURE(RDRAND) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #100
+    2413             :   { OP_FLAG(Volatile), { FEATURE(RDSEED) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #101
+    2414             :   { OP_FLAG(Volatile), { FEATURE(RDTSC) }, 0, 0 }, // #102
+    2415             :   { OP_FLAG(Volatile), { FEATURE(RDTSCP) }, 0, 0 }, // #103
+    2416             :   { OP_FLAG(Volatile), { FEATURE(LAHFSAHF) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #104
+    2417             :   { 0, { 0 }, SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_ZF), 0 }, // #105
+    2418             :   { 0, { 0 }, SPECIAL(FLAGS_CF), 0 }, // #106
+    2419             :   { 0, { 0 }, SPECIAL(FLAGS_ZF), 0 }, // #107
+    2420             :   { 0, { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF), 0 }, // #108
+    2421             :   { 0, { 0 }, SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_SF), 0 }, // #109
+    2422             :   { 0, { 0 }, SPECIAL(FLAGS_OF), 0 }, // #110
+    2423             :   { 0, { 0 }, SPECIAL(FLAGS_PF), 0 }, // #111
+    2424             :   { 0, { 0 }, SPECIAL(FLAGS_SF), 0 }, // #112
+    2425             :   { OP_FLAG(Barrier) | OP_FLAG(Volatile), { FEATURE(MMX2) }, 0, 0 }, // #113
+    2426             :   { 0, { FEATURE(SHA) }, 0, 0 }, // #114
+    2427             :   { 0, { FEATURE(AVX512_4FMAPS) }, 0, 0 }, // #115
+    2428             :   { 0, { FEATURE(AVX), FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #116
+    2429             :   { 0, { FEATURE(AVX), FEATURE(AVX512_F) }, 0, 0 }, // #117
+    2430             :   { 0, { FEATURE(AVX) }, 0, 0 }, // #118
+    2431             :   { 0, { FEATURE(AESNI), FEATURE(AVX) }, 0, 0 }, // #119
+    2432             :   { 0, { FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #120
+    2433             :   { 0, { FEATURE(AVX), FEATURE(AVX512_DQ), FEATURE(AVX512_VL) }, 0, 0 }, // #121
+    2434             :   { 0, { FEATURE(AVX512_BW), FEATURE(AVX512_VL) }, 0, 0 }, // #122
+    2435             :   { 0, { FEATURE(AVX512_DQ), FEATURE(AVX512_VL) }, 0, 0 }, // #123
+    2436             :   { 0, { FEATURE(AVX2) }, 0, 0 }, // #124
+    2437             :   { 0, { FEATURE(AVX), FEATURE(AVX2), FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #125
+    2438             :   { 0, { FEATURE(AVX), FEATURE(AVX512_F) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #126
+    2439             :   { 0, { FEATURE(AVX512_F), FEATURE(AVX512_VL), FEATURE(F16C) }, 0, 0 }, // #127
+    2440             :   { 0, { FEATURE(AVX512_ERI) }, 0, 0 }, // #128
+    2441             :   { 0, { FEATURE(AVX512_F), FEATURE(AVX512_VL), FEATURE(FMA) }, 0, 0 }, // #129
+    2442             :   { 0, { FEATURE(AVX512_F), FEATURE(FMA) }, 0, 0 }, // #130
+    2443             :   { 0, { FEATURE(FMA4) }, 0, 0 }, // #131
+    2444             :   { 0, { FEATURE(XOP) }, 0, 0 }, // #132
+    2445             :   { 0, { FEATURE(AVX2), FEATURE(AVX512_F), FEATURE(AVX512_VL) }, 0, 0 }, // #133
+    2446             :   { 0, { FEATURE(AVX512_PFI) }, 0, 0 }, // #134
+    2447             :   { 0, { FEATURE(AVX), FEATURE(AVX2) }, 0, 0 }, // #135
+    2448             :   { 0, { FEATURE(AVX512_4VNNIW) }, 0, 0 }, // #136
+    2449             :   { 0, { FEATURE(AVX), FEATURE(AVX2), FEATURE(AVX512_BW), FEATURE(AVX512_VL) }, 0, 0 }, // #137
+    2450             :   { 0, { FEATURE(AVX2), FEATURE(AVX512_BW), FEATURE(AVX512_VL) }, 0, 0 }, // #138
+    2451             :   { 0, { FEATURE(AVX512_CDI), FEATURE(AVX512_VL) }, 0, 0 }, // #139
+    2452             :   { 0, { FEATURE(AVX), FEATURE(PCLMULQDQ) }, 0, 0 }, // #140
+    2453             :   { 0, { FEATURE(AVX) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }, // #141
+    2454             :   { 0, { FEATURE(AVX512_VBMI), FEATURE(AVX512_VL) }, 0, 0 }, // #142
+    2455             :   { 0, { FEATURE(AVX), FEATURE(AVX512_BW) }, 0, 0 }, // #143
+    2456             :   { 0, { FEATURE(AVX), FEATURE(AVX512_DQ) }, 0, 0 }, // #144
+    2457             :   { 0, { FEATURE(AVX512_IFMA), FEATURE(AVX512_VL) }, 0, 0 }, // #145
+    2458             :   { 0, { FEATURE(AVX512_VPOPCNTDQ) }, 0, 0 }, // #146
+    2459             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(MSR) }, 0, SPECIAL(MSR) }, // #147
+    2460             :   { OP_FLAG(Volatile), { FEATURE(RTM) }, 0, 0 }, // #148
+    2461             :   { OP_FLAG(Volatile), { FEATURE(XSAVE) }, SPECIAL(XCR), 0 }, // #149
+    2462             :   { OP_FLAG(Volatile), { FEATURE(XSAVES) }, SPECIAL(XCR), 0 }, // #150
+    2463             :   { OP_FLAG(Volatile), { FEATURE(XSAVEC) }, SPECIAL(XCR), 0 }, // #151
+    2464             :   { OP_FLAG(Volatile), { FEATURE(XSAVEOPT) }, SPECIAL(XCR), 0 }, // #152
+    2465             :   { OP_FLAG(Volatile) | OP_FLAG(Privileged), { FEATURE(XSAVE) }, 0, SPECIAL(XCR) }, // #153
+    2466             :   { OP_FLAG(Volatile), { FEATURE(TSX) }, 0, SPECIAL(FLAGS_AF) | SPECIAL(FLAGS_CF) | SPECIAL(FLAGS_OF) | SPECIAL(FLAGS_PF) | SPECIAL(FLAGS_SF) | SPECIAL(FLAGS_ZF) }  // #154
+    2467             : };
+    2468             : #undef SPECIAL
+    2469             : #undef FEATURE
+    2470             : #undef OP_FLAG
+    2471             : // ----------------------------------------------------------------------------
+    2472             : // ${operationData:End}
+    2473             : 
+    2474             : // ${sseToAvxData:Begin}
+    2475             : // ------------------- Automatically generated, do not edit -------------------
+    2476             : const X86Inst::SseToAvxData X86InstDB::sseToAvxData[] = {
+    2477             :   { X86Inst::kSseToAvxNone     , 0    }, // #0
+    2478             :   { X86Inst::kSseToAvxExtend   , 725  }, // #1
+    2479             :   { X86Inst::kSseToAvxExtend   , 724  }, // #2
+    2480             :   { X86Inst::kSseToAvxMove     , 724  }, // #3
+    2481             :   { X86Inst::kSseToAvxExtend   , 723  }, // #4
+    2482             :   { X86Inst::kSseToAvxBlend    , 723  }, // #5
+    2483             :   { X86Inst::kSseToAvxExtend   , 671  }, // #6
+    2484             :   { X86Inst::kSseToAvxExtend   , 670  }, // #7
+    2485             :   { X86Inst::kSseToAvxMove     , 667  }, // #8
+    2486             :   { X86Inst::kSseToAvxMove     , 666  }, // #9
+    2487             :   { X86Inst::kSseToAvxMove     , 665  }, // #10
+    2488             :   { X86Inst::kSseToAvxMove     , 672  }, // #11
+    2489             :   { X86Inst::kSseToAvxExtend   , 672  }, // #12
+    2490             :   { X86Inst::kSseToAvxExtend   , 673  }, // #13
+    2491             :   { X86Inst::kSseToAvxMove     , 673  }, // #14
+    2492             :   { X86Inst::kSseToAvxMove     , 674  }, // #15
+    2493             :   { X86Inst::kSseToAvxMove     , 676  }, // #16
+    2494             :   { X86Inst::kSseToAvxMove     , 678  }, // #17
+    2495             :   { X86Inst::kSseToAvxMove     , 679  }, // #18
+    2496             :   { X86Inst::kSseToAvxExtend   , 681  }, // #19
+    2497             :   { X86Inst::kSseToAvxMove     , 695  }, // #20
+    2498             :   { X86Inst::kSseToAvxExtend   , 708  }, // #21
+    2499             :   { X86Inst::kSseToAvxExtend   , 707  }, // #22
+    2500             :   { X86Inst::kSseToAvxExtend   , 712  }, // #23
+    2501             :   { X86Inst::kSseToAvxMove     , 616  }, // #24
+    2502             :   { X86Inst::kSseToAvxMove     , 597  }, // #25
+    2503             :   { X86Inst::kSseToAvxExtend   , 598  }, // #26
+    2504             :   { X86Inst::kSseToAvxExtend   , 597  }, // #27
+    2505             :   { X86Inst::kSseToAvxMove     , 595  }, // #28
+    2506             :   { X86Inst::kSseToAvxMove     , 594  }, // #29
+    2507             :   { X86Inst::kSseToAvxMove     , 593  }, // #30
+    2508             :   { X86Inst::kSseToAvxExtend   , 599  }, // #31
+    2509             :   { X86Inst::kSseToAvxMoveIfMem, 599  }, // #32
+    2510             :   { X86Inst::kSseToAvxMove     , 599  }, // #33
+    2511             :   { X86Inst::kSseToAvxMove     , 598  }, // #34
+    2512             :   { X86Inst::kSseToAvxMoveIfMem, 593  }, // #35
+    2513             :   { X86Inst::kSseToAvxMove     , 591  }, // #36
+    2514             :   { X86Inst::kSseToAvxExtend   , 590  }, // #37
+    2515             :   { X86Inst::kSseToAvxExtend   , 589  }, // #38
+    2516             :   { X86Inst::kSseToAvxExtend   , 583  }, // #39
+    2517             :   { X86Inst::kSseToAvxMove     , 583  }, // #40
+    2518             :   { X86Inst::kSseToAvxMove     , 584  }, // #41
+    2519             :   { X86Inst::kSseToAvxExtend   , 584  }, // #42
+    2520             :   { X86Inst::kSseToAvxExtend   , 585  }, // #43
+    2521             :   { X86Inst::kSseToAvxExtend   , 587  }, // #44
+    2522             :   { X86Inst::kSseToAvxExtend   , 586  }, // #45
+    2523             :   { X86Inst::kSseToAvxBlend    , 587  }, // #46
+    2524             :   { X86Inst::kSseToAvxExtend   , 593  }, // #47
+    2525             :   { X86Inst::kSseToAvxExtend   , 596  }, // #48
+    2526             :   { X86Inst::kSseToAvxMove     , 596  }, // #49
+    2527             :   { X86Inst::kSseToAvxMove     , 637  }, // #50
+    2528             :   { X86Inst::kSseToAvxExtend   , 623  }, // #51
+    2529             :   { X86Inst::kSseToAvxExtend   , 624  }, // #52
+    2530             :   { X86Inst::kSseToAvxExtend   , 630  }, // #53
+    2531             :   { X86Inst::kSseToAvxMove     , 632  }, // #54
+    2532             :   { X86Inst::kSseToAvxExtend   , 633  }, // #55
+    2533             :   { X86Inst::kSseToAvxExtend   , 634  }, // #56
+    2534             :   { X86Inst::kSseToAvxMove     , 633  }, // #57
+    2535             :   { X86Inst::kSseToAvxExtend   , 649  }, // #58
+    2536             :   { X86Inst::kSseToAvxExtend   , 651  }, // #59
+    2537             :   { X86Inst::kSseToAvxExtend   , 652  }, // #60
+    2538             :   { X86Inst::kSseToAvxExtend   , 653  }, // #61
+    2539             :   { X86Inst::kSseToAvxExtend   , 654  }, // #62
+    2540             :   { X86Inst::kSseToAvxExtend   , 655  }, // #63
+    2541             :   { X86Inst::kSseToAvxMove     , 663  }, // #64
+    2542             :   { X86Inst::kSseToAvxMove     , 681  }, // #65
+    2543             :   { X86Inst::kSseToAvxExtend   , 680  }, // #66
+    2544             :   { X86Inst::kSseToAvxExtend   , 682  }, // #67
+    2545             :   { X86Inst::kSseToAvxExtend   , 677  }, // #68
+    2546             :   { X86Inst::kSseToAvxExtend   , 685  }, // #69
+    2547             :   { X86Inst::kSseToAvxExtend   , 697  }, // #70
+    2548             :   { X86Inst::kSseToAvxMove     , 697  }, // #71
+    2549             :   { X86Inst::kSseToAvxExtend   , 696  }, // #72
+    2550             :   { X86Inst::kSseToAvxExtend   , 699  }, // #73
+    2551             :   { X86Inst::kSseToAvxExtend   , 703  }, // #74
+    2552             :   { X86Inst::kSseToAvxExtend   , 706  }, // #75
+    2553             :   { X86Inst::kSseToAvxMove     , 707  }, // #76
+    2554             :   { X86Inst::kSseToAvxExtend   , 715  }, // #77
+    2555             :   { X86Inst::kSseToAvxExtend   , 709  }, // #78
+    2556             :   { X86Inst::kSseToAvxMove     , 722  }, // #79
+    2557             :   { X86Inst::kSseToAvxExtend   , 722  }, // #80
+    2558             :   { X86Inst::kSseToAvxMove     , 717  }, // #81
+    2559             :   { X86Inst::kSseToAvxExtend   , 717  }, // #82
+    2560             :   { X86Inst::kSseToAvxExtend   , 693  }, // #83
+    2561             :   { X86Inst::kSseToAvxMove     , 690  }, // #84
+    2562             :   { X86Inst::kSseToAvxExtend   , 690  }, // #85
+    2563             :   { X86Inst::kSseToAvxExtend   , 683  }, // #86
+    2564             :   { X86Inst::kSseToAvxExtend   , -16  }  // #87
+    2565             : };
+    2566             : // ----------------------------------------------------------------------------
+    2567             : // ${sseToAvxData:End}
+    2568             : 
+    2569             : // ============================================================================
+    2570             : // [asmjit::X86Inst - Id <-> Name]
+    2571             : // ============================================================================
+    2572             : 
+    2573             : #if !defined(ASMJIT_DISABLE_TEXT)
+    2574             : // ${nameData:Begin}
+    2575             : // ------------------- Automatically generated, do not edit -------------------
+    2576             : const char X86InstDB::nameData[] =
+    2577             :   "\0" "aaa\0" "aad\0" "aam\0" "aas\0" "adc\0" "adcx\0" "adox\0" "arpl\0"
+    2578             :   "bextr\0" "blcfill\0" "blci\0" "blcic\0" "blcmsk\0" "blcs\0" "blsfill\0"
+    2579             :   "blsi\0" "blsic\0" "blsmsk\0" "blsr\0" "bndcl\0" "bndcn\0" "bndcu\0"
+    2580             :   "bndldx\0" "bndmk\0" "bndmov\0" "bndstx\0" "bound\0" "bsf\0" "bsr\0"
+    2581             :   "bswap\0" "bt\0" "btc\0" "btr\0" "bts\0" "bzhi\0" "cbw\0" "cdq\0" "cdqe\0"
+    2582             :   "clac\0" "clc\0" "cld\0" "clflush\0" "clflushopt\0" "cli\0" "clts\0" "clwb\0"
+    2583             :   "clzero\0" "cmc\0" "cmova\0" "cmovae\0" "cmovc\0" "cmovg\0" "cmovge\0"
+    2584             :   "cmovl\0" "cmovle\0" "cmovna\0" "cmovnae\0" "cmovnc\0" "cmovng\0" "cmovnge\0"
+    2585             :   "cmovnl\0" "cmovnle\0" "cmovno\0" "cmovnp\0" "cmovns\0" "cmovnz\0" "cmovo\0"
+    2586             :   "cmovp\0" "cmovpe\0" "cmovpo\0" "cmovs\0" "cmovz\0" "cmp\0" "cmps\0"
+    2587             :   "cmpxchg\0" "cmpxchg16b\0" "cmpxchg8b\0" "cpuid\0" "cqo\0" "crc32\0"
+    2588             :   "cvtpd2pi\0" "cvtpi2pd\0" "cvtpi2ps\0" "cvtps2pi\0" "cvttpd2pi\0"
+    2589             :   "cvttps2pi\0" "cwd\0" "cwde\0" "daa\0" "das\0" "f2xm1\0" "fabs\0" "faddp\0"
+    2590             :   "fbld\0" "fbstp\0" "fchs\0" "fclex\0" "fcmovb\0" "fcmovbe\0" "fcmove\0"
+    2591             :   "fcmovnb\0" "fcmovnbe\0" "fcmovne\0" "fcmovnu\0" "fcmovu\0" "fcom\0"
+    2592             :   "fcomi\0" "fcomip\0" "fcomp\0" "fcompp\0" "fcos\0" "fdecstp\0" "fdiv\0"
+    2593             :   "fdivp\0" "fdivr\0" "fdivrp\0" "femms\0" "ffree\0" "fiadd\0" "ficom\0"
+    2594             :   "ficomp\0" "fidiv\0" "fidivr\0" "fild\0" "fimul\0" "fincstp\0" "finit\0"
+    2595             :   "fist\0" "fistp\0" "fisttp\0" "fisub\0" "fisubr\0" "fld\0" "fld1\0" "fldcw\0"
+    2596             :   "fldenv\0" "fldl2e\0" "fldl2t\0" "fldlg2\0" "fldln2\0" "fldpi\0" "fldz\0"
+    2597             :   "fmulp\0" "fnclex\0" "fninit\0" "fnop\0" "fnsave\0" "fnstcw\0" "fnstenv\0"
+    2598             :   "fnstsw\0" "fpatan\0" "fprem\0" "fprem1\0" "fptan\0" "frndint\0" "frstor\0"
+    2599             :   "fsave\0" "fscale\0" "fsin\0" "fsincos\0" "fsqrt\0" "fst\0" "fstcw\0"
+    2600             :   "fstenv\0" "fstp\0" "fstsw\0" "fsubp\0" "fsubrp\0" "ftst\0" "fucom\0"
+    2601             :   "fucomi\0" "fucomip\0" "fucomp\0" "fucompp\0" "fwait\0" "fxam\0" "fxch\0"
+    2602             :   "fxrstor\0" "fxrstor64\0" "fxsave\0" "fxsave64\0" "fxtract\0" "fyl2x\0"
+    2603             :   "fyl2xp1\0" "hlt\0" "inc\0" "ins\0" "insertq\0" "int3\0" "into\0" "invlpg\0"
+    2604             :   "invpcid\0" "iret\0" "iretd\0" "iretq\0" "iretw\0" "ja\0" "jae\0" "jb\0"
+    2605             :   "jbe\0" "jc\0" "je\0" "jecxz\0" "jg\0" "jge\0" "jl\0" "jle\0" "jmp\0" "jna\0"
+    2606             :   "jnae\0" "jnb\0" "jnbe\0" "jnc\0" "jne\0" "jng\0" "jnge\0" "jnl\0" "jnle\0"
+    2607             :   "jno\0" "jnp\0" "jns\0" "jnz\0" "jo\0" "jp\0" "jpe\0" "jpo\0" "js\0" "jz\0"
+    2608             :   "kaddb\0" "kaddd\0" "kaddq\0" "kaddw\0" "kandb\0" "kandd\0" "kandnb\0"
+    2609             :   "kandnd\0" "kandnq\0" "kandnw\0" "kandq\0" "kandw\0" "kmovb\0" "kmovw\0"
+    2610             :   "knotb\0" "knotd\0" "knotq\0" "knotw\0" "korb\0" "kord\0" "korq\0"
+    2611             :   "kortestb\0" "kortestd\0" "kortestq\0" "kortestw\0" "korw\0" "kshiftlb\0"
+    2612             :   "kshiftld\0" "kshiftlq\0" "kshiftlw\0" "kshiftrb\0" "kshiftrd\0" "kshiftrq\0"
+    2613             :   "kshiftrw\0" "ktestb\0" "ktestd\0" "ktestq\0" "ktestw\0" "kunpckbw\0"
+    2614             :   "kunpckdq\0" "kunpckwd\0" "kxnorb\0" "kxnord\0" "kxnorq\0" "kxnorw\0"
+    2615             :   "kxorb\0" "kxord\0" "kxorq\0" "kxorw\0" "lahf\0" "lar\0" "lds\0" "lea\0"
+    2616             :   "leave\0" "les\0" "lfence\0" "lfs\0" "lgdt\0" "lgs\0" "lidt\0" "lldt\0"
+    2617             :   "lmsw\0" "lods\0" "loop\0" "loope\0" "loopne\0" "lsl\0" "ltr\0" "lzcnt\0"
+    2618             :   "mfence\0" "monitor\0" "movdq2q\0" "movnti\0" "movntq\0" "movntsd\0"
+    2619             :   "movntss\0" "movq2dq\0" "movsx\0" "movsxd\0" "movzx\0" "mulx\0" "mwait\0"
+    2620             :   "neg\0" "not\0" "out\0" "outs\0" "pause\0" "pavgusb\0" "pcommit\0" "pdep\0"
+    2621             :   "pext\0" "pf2id\0" "pf2iw\0" "pfacc\0" "pfadd\0" "pfcmpeq\0" "pfcmpge\0"
+    2622             :   "pfcmpgt\0" "pfmax\0" "pfmin\0" "pfmul\0" "pfnacc\0" "pfpnacc\0" "pfrcp\0"
+    2623             :   "pfrcpit1\0" "pfrcpit2\0" "pfrcpv\0" "pfrsqit1\0" "pfrsqrt\0" "pfrsqrtv\0"
+    2624             :   "pfsub\0" "pfsubr\0" "pi2fd\0" "pi2fw\0" "pmulhrw\0" "pop\0" "popa\0"
+    2625             :   "popad\0" "popcnt\0" "popf\0" "popfd\0" "popfq\0" "prefetch\0"
+    2626             :   "prefetchnta\0" "prefetcht0\0" "prefetcht1\0" "prefetcht2\0" "prefetchw\0"
+    2627             :   "prefetchwt1\0" "pshufw\0" "pswapd\0" "push\0" "pusha\0" "pushad\0" "pushf\0"
+    2628             :   "pushfd\0" "pushfq\0" "rcl\0" "rcr\0" "rdfsbase\0" "rdgsbase\0" "rdmsr\0"
+    2629             :   "rdpmc\0" "rdrand\0" "rdseed\0" "rdtsc\0" "rdtscp\0" "rol\0" "ror\0" "rorx\0"
+    2630             :   "rsm\0" "sahf\0" "sal\0" "sar\0" "sarx\0" "sbb\0" "scas\0" "seta\0" "setae\0"
+    2631             :   "setb\0" "setbe\0" "setc\0" "sete\0" "setg\0" "setge\0" "setl\0" "setle\0"
+    2632             :   "setna\0" "setnae\0" "setnb\0" "setnbe\0" "setnc\0" "setne\0" "setng\0"
+    2633             :   "setnge\0" "setnl\0" "setnle\0" "setno\0" "setnp\0" "setns\0" "setnz\0"
+    2634             :   "seto\0" "setp\0" "setpe\0" "setpo\0" "sets\0" "setz\0" "sfence\0" "sgdt\0"
+    2635             :   "sha1msg1\0" "sha1msg2\0" "sha1nexte\0" "sha1rnds4\0" "sha256msg1\0"
+    2636             :   "sha256msg2\0" "sha256rnds2\0" "shl\0" "shlx\0" "shr\0" "shrd\0" "shrx\0"
+    2637             :   "sidt\0" "sldt\0" "smsw\0" "stac\0" "stc\0" "sti\0" "stos\0" "str\0"
+    2638             :   "swapgs\0" "syscall\0" "sysenter\0" "sysexit\0" "sysexit64\0" "sysret\0"
+    2639             :   "sysret64\0" "t1mskc\0" "tzcnt\0" "tzmsk\0" "ud2\0" "v4fmaddps\0"
+    2640             :   "v4fnmaddps\0" "vaddpd\0" "vaddps\0" "vaddsd\0" "vaddss\0" "vaddsubpd\0"
+    2641             :   "vaddsubps\0" "vaesdec\0" "vaesdeclast\0" "vaesenc\0" "vaesenclast\0"
+    2642             :   "vaesimc\0" "vaeskeygenassist\0" "valignd\0" "valignq\0" "vandnpd\0"
+    2643             :   "vandnps\0" "vandpd\0" "vandps\0" "vblendmb\0" "vblendmd\0" "vblendmpd\0"
+    2644             :   "vblendmps\0" "vblendmq\0" "vblendmw\0" "vblendpd\0" "vblendps\0"
+    2645             :   "vblendvpd\0" "vblendvps\0" "vbroadcastf128\0" "vbroadcastf32x2\0"
+    2646             :   "vbroadcastf32x4\0" "vbroadcastf32x8\0" "vbroadcastf64x2\0"
+    2647             :   "vbroadcastf64x4\0" "vbroadcasti128\0" "vbroadcasti32x2\0"
+    2648             :   "vbroadcasti32x4\0" "vbroadcasti32x8\0" "vbroadcasti64x2\0"
+    2649             :   "vbroadcasti64x4\0" "vbroadcastsd\0" "vbroadcastss\0" "vcmppd\0" "vcmpps\0"
+    2650             :   "vcmpsd\0" "vcmpss\0" "vcomisd\0" "vcomiss\0" "vcompresspd\0" "vcompressps\0"
+    2651             :   "vcvtdq2pd\0" "vcvtdq2ps\0" "vcvtpd2dq\0" "vcvtpd2ps\0" "vcvtpd2qq\0"
+    2652             :   "vcvtpd2udq\0" "vcvtpd2uqq\0" "vcvtph2ps\0" "vcvtps2dq\0" "vcvtps2pd\0"
+    2653             :   "vcvtps2ph\0" "vcvtps2qq\0" "vcvtps2udq\0" "vcvtps2uqq\0" "vcvtqq2pd\0"
+    2654             :   "vcvtqq2ps\0" "vcvtsd2si\0" "vcvtsd2ss\0" "vcvtsd2usi\0" "vcvtsi2sd\0"
+    2655             :   "vcvtsi2ss\0" "vcvtss2sd\0" "vcvtss2si\0" "vcvtss2usi\0" "vcvttpd2dq\0"
+    2656             :   "vcvttpd2qq\0" "vcvttpd2udq\0" "vcvttpd2uqq\0" "vcvttps2dq\0" "vcvttps2qq\0"
+    2657             :   "vcvttps2udq\0" "vcvttps2uqq\0" "vcvttsd2si\0" "vcvttsd2usi\0" "vcvttss2si\0"
+    2658             :   "vcvttss2usi\0" "vcvtudq2pd\0" "vcvtudq2ps\0" "vcvtuqq2pd\0" "vcvtuqq2ps\0"
+    2659             :   "vcvtusi2sd\0" "vcvtusi2ss\0" "vdbpsadbw\0" "vdivpd\0" "vdivps\0" "vdivsd\0"
+    2660             :   "vdivss\0" "vdppd\0" "vdpps\0" "verr\0" "verw\0" "vexp2pd\0" "vexp2ps\0"
+    2661             :   "vexpandpd\0" "vexpandps\0" "vextractf128\0" "vextractf32x4\0"
+    2662             :   "vextractf32x8\0" "vextractf64x2\0" "vextractf64x4\0" "vextracti128\0"
+    2663             :   "vextracti32x4\0" "vextracti32x8\0" "vextracti64x2\0" "vextracti64x4\0"
+    2664             :   "vextractps\0" "vfixupimmpd\0" "vfixupimmps\0" "vfixupimmsd\0"
+    2665             :   "vfixupimmss\0" "vfmadd132pd\0" "vfmadd132ps\0" "vfmadd132sd\0"
+    2666             :   "vfmadd132ss\0" "vfmadd213pd\0" "vfmadd213ps\0" "vfmadd213sd\0"
+    2667             :   "vfmadd213ss\0" "vfmadd231pd\0" "vfmadd231ps\0" "vfmadd231sd\0"
+    2668             :   "vfmadd231ss\0" "vfmaddpd\0" "vfmaddps\0" "vfmaddsd\0" "vfmaddss\0"
+    2669             :   "vfmaddsub132pd\0" "vfmaddsub132ps\0" "vfmaddsub213pd\0" "vfmaddsub213ps\0"
+    2670             :   "vfmaddsub231pd\0" "vfmaddsub231ps\0" "vfmaddsubpd\0" "vfmaddsubps\0"
+    2671             :   "vfmsub132pd\0" "vfmsub132ps\0" "vfmsub132sd\0" "vfmsub132ss\0"
+    2672             :   "vfmsub213pd\0" "vfmsub213ps\0" "vfmsub213sd\0" "vfmsub213ss\0"
+    2673             :   "vfmsub231pd\0" "vfmsub231ps\0" "vfmsub231sd\0" "vfmsub231ss\0"
+    2674             :   "vfmsubadd132pd\0" "vfmsubadd132ps\0" "vfmsubadd213pd\0" "vfmsubadd213ps\0"
+    2675             :   "vfmsubadd231pd\0" "vfmsubadd231ps\0" "vfmsubaddpd\0" "vfmsubaddps\0"
+    2676             :   "vfmsubpd\0" "vfmsubps\0" "vfmsubsd\0" "vfmsubss\0" "vfnmadd132pd\0"
+    2677             :   "vfnmadd132ps\0" "vfnmadd132sd\0" "vfnmadd132ss\0" "vfnmadd213pd\0"
+    2678             :   "vfnmadd213ps\0" "vfnmadd213sd\0" "vfnmadd213ss\0" "vfnmadd231pd\0"
+    2679             :   "vfnmadd231ps\0" "vfnmadd231sd\0" "vfnmadd231ss\0" "vfnmaddpd\0"
+    2680             :   "vfnmaddps\0" "vfnmaddsd\0" "vfnmaddss\0" "vfnmsub132pd\0" "vfnmsub132ps\0"
+    2681             :   "vfnmsub132sd\0" "vfnmsub132ss\0" "vfnmsub213pd\0" "vfnmsub213ps\0"
+    2682             :   "vfnmsub213sd\0" "vfnmsub213ss\0" "vfnmsub231pd\0" "vfnmsub231ps\0"
+    2683             :   "vfnmsub231sd\0" "vfnmsub231ss\0" "vfnmsubpd\0" "vfnmsubps\0" "vfnmsubsd\0"
+    2684             :   "vfnmsubss\0" "vfpclasspd\0" "vfpclassps\0" "vfpclasssd\0" "vfpclassss\0"
+    2685             :   "vfrczpd\0" "vfrczps\0" "vfrczsd\0" "vfrczss\0" "vgatherdpd\0" "vgatherdps\0"
+    2686             :   "vgatherpf0dpd\0" "vgatherpf0dps\0" "vgatherpf0qpd\0" "vgatherpf0qps\0"
+    2687             :   "vgatherpf1dpd\0" "vgatherpf1dps\0" "vgatherpf1qpd\0" "vgatherpf1qps\0"
+    2688             :   "vgatherqpd\0" "vgatherqps\0" "vgetexppd\0" "vgetexpps\0" "vgetexpsd\0"
+    2689             :   "vgetexpss\0" "vgetmantpd\0" "vgetmantps\0" "vgetmantsd\0" "vgetmantss\0"
+    2690             :   "vhaddpd\0" "vhaddps\0" "vhsubpd\0" "vhsubps\0" "vinsertf128\0"
+    2691             :   "vinsertf32x4\0" "vinsertf32x8\0" "vinsertf64x2\0" "vinsertf64x4\0"
+    2692             :   "vinserti128\0" "vinserti32x4\0" "vinserti32x8\0" "vinserti64x2\0"
+    2693             :   "vinserti64x4\0" "vinsertps\0" "vlddqu\0" "vldmxcsr\0" "vmaskmovdqu\0"
+    2694             :   "vmaskmovpd\0" "vmaskmovps\0" "vmaxpd\0" "vmaxps\0" "vmaxsd\0" "vmaxss\0"
+    2695             :   "vminpd\0" "vminps\0" "vminsd\0" "vminss\0" "vmovapd\0" "vmovaps\0" "vmovd\0"
+    2696             :   "vmovddup\0" "vmovdqa\0" "vmovdqa32\0" "vmovdqa64\0" "vmovdqu\0"
+    2697             :   "vmovdqu16\0" "vmovdqu32\0" "vmovdqu64\0" "vmovdqu8\0" "vmovhlps\0"
+    2698             :   "vmovhpd\0" "vmovhps\0" "vmovlhps\0" "vmovlpd\0" "vmovlps\0" "vmovmskpd\0"
+    2699             :   "vmovmskps\0" "vmovntdq\0" "vmovntdqa\0" "vmovntpd\0" "vmovntps\0" "vmovq\0"
+    2700             :   "vmovsd\0" "vmovshdup\0" "vmovsldup\0" "vmovss\0" "vmovupd\0" "vmovups\0"
+    2701             :   "vmpsadbw\0" "vmulpd\0" "vmulps\0" "vmulsd\0" "vmulss\0" "vorpd\0" "vorps\0"
+    2702             :   "vp4dpwssd\0" "vp4dpwssds\0" "vpabsb\0" "vpabsd\0" "vpabsq\0" "vpabsw\0"
+    2703             :   "vpackssdw\0" "vpacksswb\0" "vpackusdw\0" "vpackuswb\0" "vpaddb\0" "vpaddd\0"
+    2704             :   "vpaddq\0" "vpaddsb\0" "vpaddsw\0" "vpaddusb\0" "vpaddusw\0" "vpaddw\0"
+    2705             :   "vpalignr\0" "vpand\0" "vpandd\0" "vpandn\0" "vpandnd\0" "vpandnq\0"
+    2706             :   "vpandq\0" "vpavgb\0" "vpavgw\0" "vpblendd\0" "vpblendvb\0" "vpblendw\0"
+    2707             :   "vpbroadcastb\0" "vpbroadcastd\0" "vpbroadcastmb2d\0" "vpbroadcastmb2q\0"
+    2708             :   "vpbroadcastq\0" "vpbroadcastw\0" "vpclmulqdq\0" "vpcmov\0" "vpcmpb\0"
+    2709             :   "vpcmpd\0" "vpcmpeqb\0" "vpcmpeqd\0" "vpcmpeqq\0" "vpcmpeqw\0" "vpcmpestri\0"
+    2710             :   "vpcmpestrm\0" "vpcmpgtb\0" "vpcmpgtd\0" "vpcmpgtq\0" "vpcmpgtw\0"
+    2711             :   "vpcmpistri\0" "vpcmpistrm\0" "vpcmpq\0" "vpcmpub\0" "vpcmpud\0" "vpcmpuq\0"
+    2712             :   "vpcmpuw\0" "vpcmpw\0" "vpcomb\0" "vpcomd\0" "vpcompressd\0" "vpcompressq\0"
+    2713             :   "vpcomq\0" "vpcomub\0" "vpcomud\0" "vpcomuq\0" "vpcomuw\0" "vpcomw\0"
+    2714             :   "vpconflictd\0" "vpconflictq\0" "vperm2f128\0" "vperm2i128\0" "vpermb\0"
+    2715             :   "vpermd\0" "vpermi2b\0" "vpermi2d\0" "vpermi2pd\0" "vpermi2ps\0" "vpermi2q\0"
+    2716             :   "vpermi2w\0" "vpermil2pd\0" "vpermil2ps\0" "vpermilpd\0" "vpermilps\0"
+    2717             :   "vpermpd\0" "vpermps\0" "vpermq\0" "vpermt2b\0" "vpermt2d\0" "vpermt2pd\0"
+    2718             :   "vpermt2ps\0" "vpermt2q\0" "vpermt2w\0" "vpermw\0" "vpexpandd\0"
+    2719             :   "vpexpandq\0" "vpextrb\0" "vpextrd\0" "vpextrq\0" "vpextrw\0" "vpgatherdd\0"
+    2720             :   "vpgatherdq\0" "vpgatherqd\0" "vpgatherqq\0" "vphaddbd\0" "vphaddbq\0"
+    2721             :   "vphaddbw\0" "vphaddd\0" "vphadddq\0" "vphaddsw\0" "vphaddubd\0"
+    2722             :   "vphaddubq\0" "vphaddubw\0" "vphaddudq\0" "vphadduwd\0" "vphadduwq\0"
+    2723             :   "vphaddw\0" "vphaddwd\0" "vphaddwq\0" "vphminposuw\0" "vphsubbw\0"
+    2724             :   "vphsubd\0" "vphsubdq\0" "vphsubsw\0" "vphsubw\0" "vphsubwd\0" "vpinsrb\0"
+    2725             :   "vpinsrd\0" "vpinsrq\0" "vpinsrw\0" "vplzcntd\0" "vplzcntq\0" "vpmacsdd\0"
+    2726             :   "vpmacsdqh\0" "vpmacsdql\0" "vpmacssdd\0" "vpmacssdqh\0" "vpmacssdql\0"
+    2727             :   "vpmacsswd\0" "vpmacssww\0" "vpmacswd\0" "vpmacsww\0" "vpmadcsswd\0"
+    2728             :   "vpmadcswd\0" "vpmadd52huq\0" "vpmadd52luq\0" "vpmaddubsw\0" "vpmaddwd\0"
+    2729             :   "vpmaskmovd\0" "vpmaskmovq\0" "vpmaxsb\0" "vpmaxsd\0" "vpmaxsq\0" "vpmaxsw\0"
+    2730             :   "vpmaxub\0" "vpmaxud\0" "vpmaxuq\0" "vpmaxuw\0" "vpminsb\0" "vpminsd\0"
+    2731             :   "vpminsq\0" "vpminsw\0" "vpminub\0" "vpminud\0" "vpminuq\0" "vpminuw\0"
+    2732             :   "vpmovb2m\0" "vpmovd2m\0" "vpmovdb\0" "vpmovdw\0" "vpmovm2b\0" "vpmovm2d\0"
+    2733             :   "vpmovm2q\0" "vpmovm2w\0" "vpmovmskb\0" "vpmovq2m\0" "vpmovqb\0" "vpmovqd\0"
+    2734             :   "vpmovqw\0" "vpmovsdb\0" "vpmovsdw\0" "vpmovsqb\0" "vpmovsqd\0" "vpmovsqw\0"
+    2735             :   "vpmovswb\0" "vpmovsxbd\0" "vpmovsxbq\0" "vpmovsxbw\0" "vpmovsxdq\0"
+    2736             :   "vpmovsxwd\0" "vpmovsxwq\0" "vpmovusdb\0" "vpmovusdw\0" "vpmovusqb\0"
+    2737             :   "vpmovusqd\0" "vpmovusqw\0" "vpmovuswb\0" "vpmovw2m\0" "vpmovwb\0"
+    2738             :   "vpmovzxbd\0" "vpmovzxbq\0" "vpmovzxbw\0" "vpmovzxdq\0" "vpmovzxwd\0"
+    2739             :   "vpmovzxwq\0" "vpmuldq\0" "vpmulhrsw\0" "vpmulhuw\0" "vpmulhw\0" "vpmulld\0"
+    2740             :   "vpmullq\0" "vpmullw\0" "vpmultishiftqb\0" "vpmuludq\0" "vpopcntd\0"
+    2741             :   "vpopcntq\0" "vpor\0" "vpord\0" "vporq\0" "vpperm\0" "vprold\0" "vprolq\0"
+    2742             :   "vprolvd\0" "vprolvq\0" "vprord\0" "vprorq\0" "vprorvd\0" "vprorvq\0"
+    2743             :   "vprotb\0" "vprotd\0" "vprotq\0" "vprotw\0" "vpsadbw\0" "vpscatterdd\0"
+    2744             :   "vpscatterdq\0" "vpscatterqd\0" "vpscatterqq\0" "vpshab\0" "vpshad\0"
+    2745             :   "vpshaq\0" "vpshaw\0" "vpshlb\0" "vpshld\0" "vpshlq\0" "vpshlw\0" "vpshufb\0"
+    2746             :   "vpshufd\0" "vpshufhw\0" "vpshuflw\0" "vpsignb\0" "vpsignd\0" "vpsignw\0"
+    2747             :   "vpslld\0" "vpslldq\0" "vpsllq\0" "vpsllvd\0" "vpsllvq\0" "vpsllvw\0"
+    2748             :   "vpsllw\0" "vpsrad\0" "vpsraq\0" "vpsravd\0" "vpsravq\0" "vpsravw\0"
+    2749             :   "vpsraw\0" "vpsrld\0" "vpsrldq\0" "vpsrlq\0" "vpsrlvd\0" "vpsrlvq\0"
+    2750             :   "vpsrlvw\0" "vpsrlw\0" "vpsubb\0" "vpsubd\0" "vpsubq\0" "vpsubsb\0"
+    2751             :   "vpsubsw\0" "vpsubusb\0" "vpsubusw\0" "vpsubw\0" "vpternlogd\0"
+    2752             :   "vpternlogq\0" "vptest\0" "vptestmb\0" "vptestmd\0" "vptestmq\0" "vptestmw\0"
+    2753             :   "vptestnmb\0" "vptestnmd\0" "vptestnmq\0" "vptestnmw\0" "vpunpckhbw\0"
+    2754             :   "vpunpckhdq\0" "vpunpckhqdq\0" "vpunpckhwd\0" "vpunpcklbw\0" "vpunpckldq\0"
+    2755             :   "vpunpcklqdq\0" "vpunpcklwd\0" "vpxor\0" "vpxord\0" "vpxorq\0" "vrangepd\0"
+    2756             :   "vrangeps\0" "vrangesd\0" "vrangess\0" "vrcp14pd\0" "vrcp14ps\0" "vrcp14sd\0"
+    2757             :   "vrcp14ss\0" "vrcp28pd\0" "vrcp28ps\0" "vrcp28sd\0" "vrcp28ss\0" "vrcpps\0"
+    2758             :   "vrcpss\0" "vreducepd\0" "vreduceps\0" "vreducesd\0" "vreducess\0"
+    2759             :   "vrndscalepd\0" "vrndscaleps\0" "vrndscalesd\0" "vrndscaless\0" "vroundpd\0"
+    2760             :   "vroundps\0" "vroundsd\0" "vroundss\0" "vrsqrt14pd\0" "vrsqrt14ps\0"
+    2761             :   "vrsqrt14sd\0" "vrsqrt14ss\0" "vrsqrt28pd\0" "vrsqrt28ps\0" "vrsqrt28sd\0"
+    2762             :   "vrsqrt28ss\0" "vrsqrtps\0" "vrsqrtss\0" "vscalefpd\0" "vscalefps\0"
+    2763             :   "vscalefsd\0" "vscalefss\0" "vscatterdpd\0" "vscatterdps\0"
+    2764             :   "vscatterpf0dpd\0" "vscatterpf0dps\0" "vscatterpf0qpd\0" "vscatterpf0qps\0"
+    2765             :   "vscatterpf1dpd\0" "vscatterpf1dps\0" "vscatterpf1qpd\0" "vscatterpf1qps\0"
+    2766             :   "vscatterqpd\0" "vscatterqps\0" "vshuff32x4\0" "vshuff64x2\0" "vshufi32x4\0"
+    2767             :   "vshufi64x2\0" "vshufpd\0" "vshufps\0" "vsqrtpd\0" "vsqrtps\0" "vsqrtsd\0"
+    2768             :   "vsqrtss\0" "vstmxcsr\0" "vsubpd\0" "vsubps\0" "vsubsd\0" "vsubss\0"
+    2769             :   "vtestpd\0" "vtestps\0" "vucomisd\0" "vucomiss\0" "vunpckhpd\0" "vunpckhps\0"
+    2770             :   "vunpcklpd\0" "vunpcklps\0" "vxorpd\0" "vxorps\0" "vzeroall\0" "vzeroupper\0"
+    2771             :   "wbinvd\0" "wrfsbase\0" "wrgsbase\0" "wrmsr\0" "xabort\0" "xadd\0" "xbegin\0"
+    2772             :   "xend\0" "xgetbv\0" "xlatb\0" "xrstors\0" "xrstors64\0" "xsavec\0"
+    2773             :   "xsavec64\0" "xsaveopt\0" "xsaveopt64\0" "xsaves\0" "xsaves64\0" "xsetbv\0"
+    2774             :   "xtest";
+    2775             : 
+    2776             : enum {
+    2777             :   kX86InstMaxLength = 16
+    2778             : };
+    2779             : 
+    2780             : struct InstNameAZ {
+    2781             :   uint16_t start;
+    2782             :   uint16_t end;
+    2783             : };
+    2784             : 
+    2785             : static const InstNameAZ X86InstNameAZ[26] = {
+    2786             :   { X86Inst::kIdAaa       , X86Inst::kIdArpl       + 1 },
+    2787             :   { X86Inst::kIdBextr     , X86Inst::kIdBzhi       + 1 },
+    2788             :   { X86Inst::kIdCall      , X86Inst::kIdCwde       + 1 },
+    2789             :   { X86Inst::kIdDaa       , X86Inst::kIdDpps       + 1 },
+    2790             :   { X86Inst::kIdEmms      , X86Inst::kIdExtrq      + 1 },
+    2791             :   { X86Inst::kIdF2xm1     , X86Inst::kIdFyl2xp1    + 1 },
+    2792             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 },
+    2793             :   { X86Inst::kIdHaddpd    , X86Inst::kIdHsubps     + 1 },
+    2794             :   { X86Inst::kIdIdiv      , X86Inst::kIdIretw      + 1 },
+    2795             :   { X86Inst::kIdJa        , X86Inst::kIdJz         + 1 },
+    2796             :   { X86Inst::kIdKaddb     , X86Inst::kIdKxorw      + 1 },
+    2797             :   { X86Inst::kIdLahf      , X86Inst::kIdLzcnt      + 1 },
+    2798             :   { X86Inst::kIdMaskmovdqu, X86Inst::kIdMwait      + 1 },
+    2799             :   { X86Inst::kIdNeg       , X86Inst::kIdNot        + 1 },
+    2800             :   { X86Inst::kIdOr        , X86Inst::kIdOuts       + 1 },
+    2801             :   { X86Inst::kIdPabsb     , X86Inst::kIdPxor       + 1 },
+    2802             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 },
+    2803             :   { X86Inst::kIdRcl       , X86Inst::kIdRsqrtss    + 1 },
+    2804             :   { X86Inst::kIdSahf      , X86Inst::kIdSysret64   + 1 },
+    2805             :   { X86Inst::kIdT1mskc    , X86Inst::kIdTzmsk      + 1 },
+    2806             :   { X86Inst::kIdUcomisd   , X86Inst::kIdUnpcklps   + 1 },
+    2807             :   { X86Inst::kIdV4fmaddps , X86Inst::kIdVzeroupper + 1 },
+    2808             :   { X86Inst::kIdWbinvd    , X86Inst::kIdWrmsr      + 1 },
+    2809             :   { X86Inst::kIdXabort    , X86Inst::kIdXtest      + 1 },
+    2810             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 },
+    2811             :   { X86Inst::kIdNone      , X86Inst::kIdNone       + 1 }
+    2812             : };
+    2813             : // ----------------------------------------------------------------------------
+    2814             : // ${nameData:End}
+    2815             : 
+    2816           0 : uint32_t X86Inst::getIdByName(const char* name, size_t len) noexcept {
+    2817           0 :   if (ASMJIT_UNLIKELY(!name))
+    2818             :     return Inst::kIdNone;
+    2819             : 
+    2820           0 :   if (len == Globals::kInvalidIndex)
+    2821           0 :     len = ::strlen(name);
+    2822             : 
+    2823           0 :   if (ASMJIT_UNLIKELY(len == 0 || len > kX86InstMaxLength))
+    2824             :     return Inst::kIdNone;
+    2825             : 
+    2826           0 :   uint32_t prefix = static_cast<uint32_t>(name[0]) - 'a';
+    2827           0 :   if (ASMJIT_UNLIKELY(prefix > 'z' - 'a'))
+    2828             :     return Inst::kIdNone;
+    2829             : 
+    2830           0 :   uint32_t index = X86InstNameAZ[prefix].start;
+    2831           0 :   if (ASMJIT_UNLIKELY(!index))
+    2832             :     return Inst::kIdNone;
+    2833             : 
+    2834             :   const char* nameData = X86InstDB::nameData;
+    2835             :   const X86Inst* instData = X86InstDB::instData;
+    2836             : 
+    2837           0 :   const X86Inst* base = instData + index;
+    2838           0 :   const X86Inst* end  = instData + X86InstNameAZ[prefix].end;
+    2839             : 
+    2840           0 :   for (size_t lim = (size_t)(end - base); lim != 0; lim >>= 1) {
+    2841           0 :     const X86Inst* cur = base + (lim >> 1);
+    2842           0 :     int result = Utils::cmpInstName(nameData + cur[0].getNameDataIndex(), name, len);
+    2843             : 
+    2844           0 :     if (result < 0) {
+    2845           0 :       base = cur + 1;
+    2846           0 :       lim--;
+    2847           0 :       continue;
+    2848             :     }
+    2849             : 
+    2850           0 :     if (result > 0)
+    2851           0 :       continue;
+    2852             : 
+    2853           0 :     return static_cast<uint32_t>((size_t)(cur - instData));
+    2854             :   }
+    2855             : 
+    2856             :   return Inst::kIdNone;
+    2857             : }
+    2858             : 
+    2859           0 : const char* X86Inst::getNameById(uint32_t id) noexcept {
+    2860           0 :   if (ASMJIT_UNLIKELY(id >= X86Inst::_kIdCount))
+    2861             :     return nullptr;
+    2862           0 :   return X86Inst::getInst(id).getName();
+    2863             : }
+    2864             : #else
+    2865             : const char X86InstDB::nameData[] = "";
+    2866             : #endif // !ASMJIT_DISABLE_TEXT
+    2867             : 
+    2868             : // ============================================================================
+    2869             : // [asmjit::X86Inst - Validation]
+    2870             : // ============================================================================
+    2871             : 
+    2872             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+    2873             : // ${signatureData:Begin}
+    2874             : // ------------------- Automatically generated, do not edit -------------------
+    2875             : #define FLAG(flag) X86Inst::kOp##flag
+    2876             : #define MEM(mem) X86Inst::kMemOp##mem
+    2877             : #define OSIGNATURE(flags, memFlags, extFlags, regId) \
+    2878             :   { uint32_t(flags), uint16_t(memFlags), uint8_t(extFlags), uint8_t(regId) }
+    2879             : const X86Inst::OSignature X86InstDB::oSignatureData[] = {
+    2880             :   OSIGNATURE(0, 0, 0, 0xFF),
+    2881             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    2882             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi), 0, 0, 0x00),
+    2883             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2884             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Seg), 0, 0, 0x00),
+    2885             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Seg) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2886             :   OSIGNATURE(FLAG(R) | FLAG(Gpd), 0, 0, 0x00),
+    2887             :   OSIGNATURE(FLAG(W) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2888             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Seg) | FLAG(I32), 0, 0, 0x00),
+    2889             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi), 0, 0, 0x00),
+    2890             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem) | FLAG(I8) | FLAG(U8), MEM(Any) | MEM(M8), 0, 0x00),
+    2891             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Seg), 0, 0, 0x00),
+    2892             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2893             :   OSIGNATURE(FLAG(W) | FLAG(Gpd), 0, 0, 0x00),
+    2894             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Seg) | FLAG(Mem) | FLAG(I32) | FLAG(U32), MEM(Any) | MEM(M32), 0, 0x00),
+    2895             :   OSIGNATURE(FLAG(W) | FLAG(Gpq) | FLAG(Seg), 0, 0, 0x00),
+    2896             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2897             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Mem), MEM(M16), 0, 0x00),
+    2898             :   OSIGNATURE(FLAG(R) | FLAG(I16) | FLAG(U16), 0, 0, 0x00),
+    2899             :   OSIGNATURE(FLAG(W) | FLAG(Gpq), 0, 0, 0x00),
+    2900             :   OSIGNATURE(FLAG(R) | FLAG(Cr) | FLAG(Dr) | FLAG(I64) | FLAG(U64), 0, 0, 0x00),
+    2901             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(M8), 0, 0x00),
+    2902             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(U8), 0, 0, 0x00),
+    2903             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Mem), MEM(M32), 0, 0x00),
+    2904             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(U32), 0, 0, 0x00),
+    2905             :   OSIGNATURE(FLAG(R) | FLAG(Cr) | FLAG(Dr), 0, 0, 0x00),
+    2906             :   OSIGNATURE(FLAG(W) | FLAG(Cr) | FLAG(Dr), 0, 0, 0x00),
+    2907             :   OSIGNATURE(FLAG(R) | FLAG(Gpq), 0, 0, 0x00),
+    2908             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(M8), 0, 0x00),
+    2909             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Mem), MEM(M16), 0, 0x00),
+    2910             :   OSIGNATURE(FLAG(X) | FLAG(Gpd) | FLAG(Mem), MEM(M32), 0, 0x00),
+    2911             :   OSIGNATURE(FLAG(X) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2912             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(I32), 0, 0, 0x00),
+    2913             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    2914             :   OSIGNATURE(FLAG(R) | FLAG(I8), 0, 0, 0x00),
+    2915             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    2916             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2917             :   OSIGNATURE(FLAG(R) | FLAG(Gpw), 0, 0, 0x00),
+    2918             :   OSIGNATURE(FLAG(X) | FLAG(Gpd) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2919             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi), 0, 0, 0x00),
+    2920             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    2921             :   OSIGNATURE(FLAG(X) | FLAG(Gpw), 0, 0, 0x00),
+    2922             :   OSIGNATURE(FLAG(X) | FLAG(Gpd), 0, 0, 0x00),
+    2923             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2924             :   OSIGNATURE(FLAG(X) | FLAG(Gpq), 0, 0, 0x00),
+    2925             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Mem), MEM(M8), 0, 0x00),
+    2926             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Mem), MEM(M16), 0, 0x00),
+    2927             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Mem), MEM(M32), 0, 0x00),
+    2928             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    2929             :   OSIGNATURE(FLAG(X) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M8) | MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    2930             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x01),
+    2931             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x04),
+    2932             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x04),
+    2933             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x01),
+    2934             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x04),
+    2935             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x01),
+    2936             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Mem) | FLAG(I8) | FLAG(I16), MEM(Any) | MEM(M16), 0, 0x00),
+    2937             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Mem) | FLAG(I8) | FLAG(I32), MEM(Any) | MEM(M32), 0, 0x00),
+    2938             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem) | FLAG(I8) | FLAG(I32), MEM(Any) | MEM(M64), 0, 0x00),
+    2939             :   OSIGNATURE(FLAG(W) | FLAG(Gpw), 0, 0, 0x00),
+    2940             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(I16) | FLAG(U16), 0, 0, 0x00),
+    2941             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(I32) | FLAG(U32), 0, 0, 0x00),
+    2942             :   OSIGNATURE(FLAG(R) | FLAG(I8) | FLAG(I32), 0, 0, 0x00),
+    2943             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2944             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2945             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2946             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    2947             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    2948             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2949             :   OSIGNATURE(FLAG(W) | FLAG(Mm), 0, 0, 0x00),
+    2950             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mm) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2951             :   OSIGNATURE(FLAG(W) | FLAG(Gpq) | FLAG(Mm) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2952             :   OSIGNATURE(FLAG(R) | FLAG(Mm), 0, 0, 0x00),
+    2953             :   OSIGNATURE(FLAG(R) | FLAG(Xmm), 0, 0, 0x00),
+    2954             :   OSIGNATURE(FLAG(W) | FLAG(Xmm), 0, 0, 0x00),
+    2955             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2956             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    2957             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2958             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2959             :   OSIGNATURE(FLAG(W) | FLAG(Ymm), 0, 0, 0x00),
+    2960             :   OSIGNATURE(FLAG(R) | FLAG(Ymm) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2961             :   OSIGNATURE(FLAG(W) | FLAG(Ymm) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2962             :   OSIGNATURE(FLAG(R) | FLAG(Ymm), 0, 0, 0x00),
+    2963             :   OSIGNATURE(FLAG(W) | FLAG(Zmm), 0, 0, 0x00),
+    2964             :   OSIGNATURE(FLAG(R) | FLAG(Zmm) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    2965             :   OSIGNATURE(FLAG(W) | FLAG(Zmm) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    2966             :   OSIGNATURE(FLAG(R) | FLAG(Zmm), 0, 0, 0x00),
+    2967             :   OSIGNATURE(FLAG(R) | FLAG(U8), 0, 0, 0x00),
+    2968             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem) | FLAG(U8), MEM(Any) | MEM(M128), 0, 0x00),
+    2969             :   OSIGNATURE(FLAG(X) | FLAG(Xmm), 0, 0, 0x00),
+    2970             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm32x), 0, 0x00),
+    2971             :   OSIGNATURE(FLAG(X) | FLAG(Ymm), 0, 0, 0x00),
+    2972             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm32y), 0, 0x00),
+    2973             :   OSIGNATURE(FLAG(X) | FLAG(Zmm), 0, 0, 0x00),
+    2974             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm32z), 0, 0x00),
+    2975             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64x), 0, 0x00),
+    2976             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64y), 0, 0x00),
+    2977             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64z), 0, 0x00),
+    2978             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(U8), 0, 0, 0x00),
+    2979             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    2980             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    2981             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(GpbLo), 0, 0, 0x01),
+    2982             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x01),
+    2983             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x01),
+    2984             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x01),
+    2985             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpw), 0, 0, 0x04),
+    2986             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x04),
+    2987             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x04),
+    2988             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16) | MEM(M64), 0, 0x00),
+    2989             :   OSIGNATURE(FLAG(W) | FLAG(Seg), 0, 0, 0x1A),
+    2990             :   OSIGNATURE(FLAG(W) | FLAG(Seg), 0, 0, 0x60),
+    2991             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpq) | FLAG(Mem) | FLAG(I8) | FLAG(I16) | FLAG(I32), MEM(Any) | MEM(M16) | MEM(M64), 0, 0x00),
+    2992             :   OSIGNATURE(FLAG(R) | FLAG(Seg), 0, 0, 0x1E),
+    2993             :   OSIGNATURE(FLAG(R) | FLAG(Seg), 0, 0, 0x60),
+    2994             :   OSIGNATURE(FLAG(R) | FLAG(Vm), MEM(Vm64x) | MEM(Vm64y), 0, 0x00),
+    2995             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2996             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2997             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    2998             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    2999             :   OSIGNATURE(FLAG(R) | FLAG(U4), 0, 0, 0x00),
+    3000             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3001             :   OSIGNATURE(FLAG(X) | FLAG(Fp), 0, 0, 0x01),
+    3002             :   OSIGNATURE(FLAG(R) | FLAG(Fp), 0, 0, 0x00),
+    3003             :   OSIGNATURE(FLAG(X) | FLAG(Fp), 0, 0, 0x00),
+    3004             :   OSIGNATURE(FLAG(R) | FLAG(Fp), 0, 0, 0x01),
+    3005             :   OSIGNATURE(FLAG(X) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3006             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M48), 0, 0x00),
+    3007             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M80), 0, 0x00),
+    3008             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(U8), 0, 0, 0x02),
+    3009             :   OSIGNATURE(FLAG(W) | FLAG(K) | FLAG(Xmm), 0, 0, 0x00),
+    3010             :   OSIGNATURE(FLAG(W) | FLAG(K) | FLAG(Ymm), 0, 0, 0x00),
+    3011             :   OSIGNATURE(FLAG(W) | FLAG(K), 0, 0, 0x00),
+    3012             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Mem), MEM(M64) | MEM(M128) | MEM(M256), 0, 0x00),
+    3013             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(M128), 0, 0x00),
+    3014             :   OSIGNATURE(FLAG(R) | FLAG(Ymm) | FLAG(Mem), MEM(M256), 0, 0x00),
+    3015             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    3016             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M512), 0, 0x00),
+    3017             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3018             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3019             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3020             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3021             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3022             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M256), 0, 0x00),
+    3023             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm32x), 0, 0x00),
+    3024             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm32y), 0, 0x00),
+    3025             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm32z), 0, 0x00),
+    3026             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64x), 0, 0x00),
+    3027             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64y), 0, 0x00),
+    3028             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64z), 0, 0x00),
+    3029             :   OSIGNATURE(FLAG(R) | FLAG(Bnd), 0, 0, 0x00),
+    3030             :   OSIGNATURE(FLAG(W) | FLAG(Bnd), 0, 0, 0x00),
+    3031             :   OSIGNATURE(FLAG(R) | FLAG(Bnd) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3032             :   OSIGNATURE(FLAG(W) | FLAG(Bnd) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3033             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem) | FLAG(I32) | FLAG(I64) | FLAG(Rel32), MEM(Any) | MEM(M64), 0, 0x00),
+    3034             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(M8) | MEM(M16) | MEM(M32), 0, 0x00),
+    3035             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpq) | FLAG(Mem), MEM(M8) | MEM(M64), 0, 0x00),
+    3036             :   OSIGNATURE(FLAG(X) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x00),
+    3037             :   OSIGNATURE(FLAG(R) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3038             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x02),
+    3039             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(I64) | FLAG(Rel8), 0, 0, 0x00),
+    3040             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x02),
+    3041             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(Mem) | FLAG(I32) | FLAG(I64) | FLAG(Rel8) | FLAG(Rel32), MEM(Any) | MEM(M64), 0, 0x00),
+    3042             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3043             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3044             :   OSIGNATURE(FLAG(R) | FLAG(K), 0, 0, 0x00),
+    3045             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3046             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3047             :   OSIGNATURE(FLAG(R) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3048             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(K) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3049             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3050             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3051             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x02),
+    3052             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x02),
+    3053             :   OSIGNATURE(FLAG(W) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3054             :   OSIGNATURE(FLAG(W) | FLAG(Mm) | FLAG(Xmm), 0, 0, 0x00),
+    3055             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M32), 0, 0x00),
+    3056             :   OSIGNATURE(FLAG(R) | FLAG(Mm) | FLAG(Xmm), 0, 0, 0x00),
+    3057             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3058             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x04),
+    3059             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x04),
+    3060             :   OSIGNATURE(FLAG(R) | FLAG(Mm) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3061             :   OSIGNATURE(FLAG(X) | FLAG(Mm), 0, 0, 0x00),
+    3062             :   OSIGNATURE(FLAG(R) | FLAG(Mm) | FLAG(Mem) | FLAG(U8), MEM(Any) | MEM(M64), 0, 0x00),
+    3063             :   OSIGNATURE(FLAG(R) | FLAG(U16), 0, 0, 0x00),
+    3064             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Mem), MEM(M128) | MEM(M256), 0, 0x00),
+    3065             :   OSIGNATURE(FLAG(W) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3066             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3067             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3068             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(GpbHi) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M8), 0, 0x00),
+    3069             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(U8), 0, 0, 0x00),
+    3070             :   OSIGNATURE(FLAG(W) | FLAG(Vm), MEM(Vm64x) | MEM(Vm64y), 0, 0x00),
+    3071             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm), 0, 0, 0x00),
+    3072             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Xmm), 0, 0, 0x01),
+    3073             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Mib), 0, 0x00),
+    3074             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3075             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Mib), 0, 0x00),
+    3076             :   OSIGNATURE(FLAG(X) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x00),
+    3077             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x01),
+    3078             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x40),
+    3079             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Es), 0, 0x80),
+    3080             :   OSIGNATURE(FLAG(X) | FLAG(Mem), MEM(Any) | MEM(M128), 0, 0x00),
+    3081             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x02),
+    3082             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpq), 0, 0, 0x08),
+    3083             :   OSIGNATURE(FLAG(X) | FLAG(Mem), MEM(Any) | MEM(M64), 0, 0x00),
+    3084             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x02),
+    3085             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x08),
+    3086             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x08),
+    3087             :   OSIGNATURE(FLAG(X) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x02),
+    3088             :   OSIGNATURE(FLAG(R) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M32) | MEM(M64), 0, 0x00),
+    3089             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any) | MEM(M80), 0, 0x00),
+    3090             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    3091             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    3092             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(M16) | MEM(M32), 0, 0x00),
+    3093             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(M16) | MEM(M32) | MEM(M64), 0, 0x00),
+    3094             :   OSIGNATURE(FLAG(R) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64) | MEM(M80), 0, 0x00),
+    3095             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(Any), 0, 0x00),
+    3096             :   OSIGNATURE(FLAG(W) | FLAG(Gpw) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x01),
+    3097             :   OSIGNATURE(FLAG(W) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64), 0, 0x00),
+    3098             :   OSIGNATURE(FLAG(W) | FLAG(Fp) | FLAG(Mem), MEM(M32) | MEM(M64) | MEM(M80), 0, 0x00),
+    3099             :   OSIGNATURE(FLAG(W) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x01),
+    3100             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(U8), 0, 0, 0x04),
+    3101             :   OSIGNATURE(FLAG(W) | FLAG(Mem), MEM(BaseOnly) | MEM(Es), 0, 0x80),
+    3102             :   OSIGNATURE(FLAG(R) | FLAG(Gpw), 0, 0, 0x04),
+    3103             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(I64) | FLAG(Rel8) | FLAG(Rel32), 0, 0, 0x00),
+    3104             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(GpbHi), 0, 0, 0x01),
+    3105             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(Any) | MEM(M8) | MEM(M16) | MEM(M32) | MEM(M48) | MEM(M64) | MEM(M80) | MEM(M128) | MEM(M256) | MEM(M512) | MEM(M1024), 0, 0x00),
+    3106             :   OSIGNATURE(FLAG(R) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq) | FLAG(Mem), MEM(Any) | MEM(M16), 0, 0x00),
+    3107             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x01),
+    3108             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x80),
+    3109             :   OSIGNATURE(FLAG(R) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd), 0, 0, 0x01),
+    3110             :   OSIGNATURE(FLAG(R) | FLAG(Mem), MEM(BaseOnly) | MEM(Ds), 0, 0x40),
+    3111             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x02),
+    3112             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Xmm), 0, 0, 0x01),
+    3113             :   OSIGNATURE(FLAG(X) | FLAG(Mm) | FLAG(Xmm), 0, 0, 0x00),
+    3114             :   OSIGNATURE(FLAG(W) | FLAG(Implicit) | FLAG(Gpd), 0, 0, 0x01),
+    3115             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(GpbHi), 0, 0, 0x01),
+    3116             :   OSIGNATURE(FLAG(R) | FLAG(Implicit) | FLAG(GpbLo) | FLAG(Gpw) | FLAG(Gpd) | FLAG(Gpq), 0, 0, 0x01),
+    3117             :   OSIGNATURE(FLAG(W) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3118             :   OSIGNATURE(FLAG(R) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3119             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Zmm) | FLAG(Mem), MEM(M128) | MEM(M256) | MEM(M512), 0, 0x00),
+    3120             :   OSIGNATURE(FLAG(R) | FLAG(Xmm) | FLAG(Ymm) | FLAG(Zmm), 0, 0, 0x00),
+    3121             :   OSIGNATURE(FLAG(R) | FLAG(I32) | FLAG(I64) | FLAG(Rel32), 0, 0, 0x00)
+    3122             : };
+    3123             : #undef OSIGNATURE
+    3124             : #undef MEM
+    3125             : #undef FLAG
+    3126             : 
+    3127             : #define ISIGNATURE(count, x86, x64, implicit, o0, o1, o2, o3, o4, o5) \
+    3128             :   { count, (x86 ? uint8_t(X86Inst::kArchMaskX86) : uint8_t(0)) |      \
+    3129             :            (x64 ? uint8_t(X86Inst::kArchMaskX64) : uint8_t(0)) ,      \
+    3130             :     implicit,                                                         \
+    3131             :     0,                                                                \
+    3132             :     { o0, o1, o2, o3, o4, o5 }                                        \
+    3133             :   }
+    3134             : const X86Inst::ISignature X86InstDB::iSignatureData[] = {
+    3135             :   ISIGNATURE(2, 1, 1, 0, 1  , 2  , 0  , 0  , 0  , 0  ), // #0   {W:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3136             :   ISIGNATURE(2, 1, 1, 0, 3  , 4  , 0  , 0  , 0  , 0  ), //      {W:r16|m16|mem, R:r16|sreg}
+    3137             :   ISIGNATURE(2, 1, 1, 0, 5  , 6  , 0  , 0  , 0  , 0  ), //      {W:r32|m32|mem|sreg, R:r32}
+    3138             :   ISIGNATURE(2, 0, 1, 0, 7  , 8  , 0  , 0  , 0  , 0  ), //      {W:r64|m64|mem, R:r64|sreg|i32}
+    3139             :   ISIGNATURE(2, 1, 1, 0, 9  , 10 , 0  , 0  , 0  , 0  ), //      {W:r8lo|r8hi, R:r8lo|r8hi|m8|mem|i8|u8}
+    3140             :   ISIGNATURE(2, 1, 1, 0, 11 , 12 , 0  , 0  , 0  , 0  ), //      {W:r16|sreg, R:r16|m16|mem}
+    3141             :   ISIGNATURE(2, 1, 1, 0, 13 , 14 , 0  , 0  , 0  , 0  ), //      {W:r32, R:r32|m32|mem|sreg|i32|u32}
+    3142             :   ISIGNATURE(2, 0, 1, 0, 15 , 16 , 0  , 0  , 0  , 0  ), //      {W:r64|sreg, R:r64|m64|mem}
+    3143             :   ISIGNATURE(2, 1, 1, 0, 17 , 18 , 0  , 0  , 0  , 0  ), //      {W:r16|m16, R:i16|u16}
+    3144             :   ISIGNATURE(2, 0, 1, 0, 19 , 20 , 0  , 0  , 0  , 0  ), //      {W:r64, R:i64|u64|creg|dreg}
+    3145             :   ISIGNATURE(2, 1, 1, 0, 21 , 22 , 0  , 0  , 0  , 0  ), //      {W:r8lo|r8hi|m8, R:i8|u8}
+    3146             :   ISIGNATURE(2, 1, 1, 0, 23 , 24 , 0  , 0  , 0  , 0  ), //      {W:r32|m32, R:i32|u32}
+    3147             :   ISIGNATURE(2, 1, 0, 0, 13 , 25 , 0  , 0  , 0  , 0  ), //      {W:r32, R:creg|dreg}
+    3148             :   ISIGNATURE(2, 1, 0, 0, 26 , 6  , 0  , 0  , 0  , 0  ), //      {W:creg|dreg, R:r32}
+    3149             :   ISIGNATURE(2, 0, 1, 0, 26 , 27 , 0  , 0  , 0  , 0  ), //      {W:creg|dreg, R:r64}
+    3150             :   ISIGNATURE(2, 1, 1, 0, 28 , 22 , 0  , 0  , 0  , 0  ), // #15  {X:r8lo|r8hi|m8, R:i8|u8}
+    3151             :   ISIGNATURE(2, 1, 1, 0, 29 , 18 , 0  , 0  , 0  , 0  ), //      {X:r16|m16, R:i16|u16}
+    3152             :   ISIGNATURE(2, 1, 1, 0, 30 , 24 , 0  , 0  , 0  , 0  ), //      {X:r32|m32, R:i32|u32}
+    3153             :   ISIGNATURE(2, 0, 1, 0, 31 , 32 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, R:i32|r64}
+    3154             :   ISIGNATURE(2, 1, 1, 0, 33 , 34 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|r32|m32|r64|m64|mem, R:i8}
+    3155             :   ISIGNATURE(2, 1, 1, 0, 35 , 2  , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3156             :   ISIGNATURE(2, 1, 1, 0, 36 , 37 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|mem, R:r16}
+    3157             :   ISIGNATURE(2, 1, 1, 0, 38 , 6  , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32}
+    3158             :   ISIGNATURE(2, 1, 1, 0, 39 , 40 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi, R:r8lo|r8hi|m8|mem}
+    3159             :   ISIGNATURE(2, 1, 1, 0, 41 , 12 , 0  , 0  , 0  , 0  ), // #24  {X:r16, R:r16|m16|mem}
+    3160             :   ISIGNATURE(2, 1, 1, 0, 42 , 43 , 0  , 0  , 0  , 0  ), // #25  {X:r32, R:r32|m32|mem}
+    3161             :   ISIGNATURE(2, 0, 1, 0, 44 , 16 , 0  , 0  , 0  , 0  ), //      {X:r64, R:r64|m64|mem}
+    3162             :   ISIGNATURE(2, 1, 1, 0, 45 , 22 , 0  , 0  , 0  , 0  ), // #27  {R:r8lo|r8hi|m8, R:i8|u8}
+    3163             :   ISIGNATURE(2, 1, 1, 0, 46 , 18 , 0  , 0  , 0  , 0  ), //      {R:r16|m16, R:i16|u16}
+    3164             :   ISIGNATURE(2, 1, 1, 0, 47 , 24 , 0  , 0  , 0  , 0  ), //      {R:r32|m32, R:i32|u32}
+    3165             :   ISIGNATURE(2, 0, 1, 0, 16 , 32 , 0  , 0  , 0  , 0  ), //      {R:r64|m64|mem, R:i32|r64}
+    3166             :   ISIGNATURE(2, 1, 1, 0, 48 , 34 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|r32|m32|r64|m64|mem, R:i8}
+    3167             :   ISIGNATURE(2, 1, 1, 0, 40 , 2  , 0  , 0  , 0  , 0  ), //      {R:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3168             :   ISIGNATURE(2, 1, 1, 0, 12 , 37 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|mem, R:r16}
+    3169             :   ISIGNATURE(2, 1, 1, 0, 43 , 6  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem, R:r32}
+    3170             :   ISIGNATURE(2, 1, 1, 0, 2  , 40 , 0  , 0  , 0  , 0  ), //      {R:r8lo|r8hi, R:r8lo|r8hi|m8|mem}
+    3171             :   ISIGNATURE(2, 1, 1, 0, 37 , 12 , 0  , 0  , 0  , 0  ), //      {R:r16, R:r16|m16|mem}
+    3172             :   ISIGNATURE(2, 1, 1, 0, 6  , 43 , 0  , 0  , 0  , 0  ), //      {R:r32, R:r32|m32|mem}
+    3173             :   ISIGNATURE(2, 0, 1, 0, 27 , 16 , 0  , 0  , 0  , 0  ), //      {R:r64, R:r64|m64|mem}
+    3174             :   ISIGNATURE(2, 1, 1, 0, 49 , 22 , 0  , 0  , 0  , 0  ), // #39  {X:r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem, R:i8|u8}
+    3175             :   ISIGNATURE(2, 1, 1, 0, 29 , 18 , 0  , 0  , 0  , 0  ), //      {X:r16|m16, R:i16|u16}
+    3176             :   ISIGNATURE(2, 1, 1, 0, 30 , 24 , 0  , 0  , 0  , 0  ), //      {X:r32|m32, R:i32|u32}
+    3177             :   ISIGNATURE(2, 0, 1, 0, 31 , 32 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, R:i32|r64}
+    3178             :   ISIGNATURE(2, 1, 1, 0, 35 , 2  , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3179             :   ISIGNATURE(2, 1, 1, 0, 36 , 37 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|mem, R:r16}
+    3180             :   ISIGNATURE(2, 1, 1, 0, 38 , 6  , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32}
+    3181             :   ISIGNATURE(2, 1, 1, 0, 39 , 40 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi, R:r8lo|r8hi|m8|mem}
+    3182             :   ISIGNATURE(2, 1, 1, 0, 41 , 12 , 0  , 0  , 0  , 0  ), //      {X:r16, R:r16|m16|mem}
+    3183             :   ISIGNATURE(2, 1, 1, 0, 42 , 43 , 0  , 0  , 0  , 0  ), //      {X:r32, R:r32|m32|mem}
+    3184             :   ISIGNATURE(2, 0, 1, 0, 44 , 16 , 0  , 0  , 0  , 0  ), //      {X:r64, R:r64|m64|mem}
+    3185             :   ISIGNATURE(2, 1, 1, 1, 50 , 40 , 0  , 0  , 0  , 0  ), // #50  {X:<ax>, R:r8lo|r8hi|m8|mem}
+    3186             :   ISIGNATURE(3, 1, 1, 2, 51 , 50 , 12 , 0  , 0  , 0  ), //      {W:<dx>, X:<ax>, R:r16|m16|mem}
+    3187             :   ISIGNATURE(3, 1, 1, 2, 52 , 53 , 43 , 0  , 0  , 0  ), //      {W:<edx>, X:<eax>, R:r32|m32|mem}
+    3188             :   ISIGNATURE(3, 0, 1, 2, 54 , 55 , 16 , 0  , 0  , 0  ), //      {W:<rdx>, X:<rax>, R:r64|m64|mem}
+    3189             :   ISIGNATURE(2, 1, 1, 0, 41 , 56 , 0  , 0  , 0  , 0  ), //      {X:r16, R:r16|m16|mem|i8|i16}
+    3190             :   ISIGNATURE(2, 1, 1, 0, 42 , 57 , 0  , 0  , 0  , 0  ), //      {X:r32, R:r32|m32|mem|i8|i32}
+    3191             :   ISIGNATURE(2, 0, 1, 0, 44 , 58 , 0  , 0  , 0  , 0  ), //      {X:r64, R:r64|m64|mem|i8|i32}
+    3192             :   ISIGNATURE(3, 1, 1, 0, 59 , 12 , 60 , 0  , 0  , 0  ), //      {W:r16, R:r16|m16|mem, R:i8|i16|u16}
+    3193             :   ISIGNATURE(3, 1, 1, 0, 13 , 43 , 61 , 0  , 0  , 0  ), //      {W:r32, R:r32|m32|mem, R:i8|i32|u32}
+    3194             :   ISIGNATURE(3, 0, 1, 0, 19 , 16 , 62 , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem, R:i8|i32}
+    3195             :   ISIGNATURE(2, 1, 1, 0, 36 , 41 , 0  , 0  , 0  , 0  ), // #60  {X:r16|m16|mem, X:r16}
+    3196             :   ISIGNATURE(2, 1, 1, 0, 38 , 42 , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, X:r32}
+    3197             :   ISIGNATURE(2, 0, 1, 0, 31 , 44 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, X:r64}
+    3198             :   ISIGNATURE(2, 1, 1, 0, 41 , 36 , 0  , 0  , 0  , 0  ), //      {X:r16, X:r16|m16|mem}
+    3199             :   ISIGNATURE(2, 1, 1, 0, 42 , 38 , 0  , 0  , 0  , 0  ), //      {X:r32, X:r32|m32|mem}
+    3200             :   ISIGNATURE(2, 0, 1, 0, 44 , 31 , 0  , 0  , 0  , 0  ), //      {X:r64, X:r64|m64|mem}
+    3201             :   ISIGNATURE(2, 1, 1, 0, 35 , 39 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi|m8|mem, X:r8lo|r8hi}
+    3202             :   ISIGNATURE(2, 1, 1, 0, 39 , 35 , 0  , 0  , 0  , 0  ), //      {X:r8lo|r8hi, X:r8lo|r8hi|m8|mem}
+    3203             :   ISIGNATURE(2, 1, 1, 0, 45 , 22 , 0  , 0  , 0  , 0  ), // #68  {R:r8lo|r8hi|m8, R:i8|u8}
+    3204             :   ISIGNATURE(2, 1, 1, 0, 46 , 18 , 0  , 0  , 0  , 0  ), //      {R:r16|m16, R:i16|u16}
+    3205             :   ISIGNATURE(2, 1, 1, 0, 47 , 24 , 0  , 0  , 0  , 0  ), //      {R:r32|m32, R:i32|u32}
+    3206             :   ISIGNATURE(2, 0, 1, 0, 16 , 32 , 0  , 0  , 0  , 0  ), //      {R:r64|m64|mem, R:i32|r64}
+    3207             :   ISIGNATURE(2, 1, 1, 0, 40 , 2  , 0  , 0  , 0  , 0  ), //      {R:r8lo|r8hi|m8|mem, R:r8lo|r8hi}
+    3208             :   ISIGNATURE(2, 1, 1, 0, 12 , 37 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|mem, R:r16}
+    3209             :   ISIGNATURE(2, 1, 1, 0, 43 , 6  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem, R:r32}
+    3210             :   ISIGNATURE(2, 1, 1, 0, 59 , 63 , 0  , 0  , 0  , 0  ), // #75  {W:r16, R:m16|mem}
+    3211             :   ISIGNATURE(2, 1, 1, 0, 13 , 64 , 0  , 0  , 0  , 0  ), //      {W:r32, R:m32|mem}
+    3212             :   ISIGNATURE(2, 0, 1, 0, 19 , 65 , 0  , 0  , 0  , 0  ), //      {W:r64, R:m64|mem}
+    3213             :   ISIGNATURE(2, 1, 1, 0, 66 , 37 , 0  , 0  , 0  , 0  ), //      {W:m16|mem, R:r16}
+    3214             :   ISIGNATURE(2, 1, 1, 0, 67 , 6  , 0  , 0  , 0  , 0  ), // #79  {W:m32|mem, R:r32}
+    3215             :   ISIGNATURE(2, 0, 1, 0, 68 , 27 , 0  , 0  , 0  , 0  ), //      {W:m64|mem, R:r64}
+    3216             :   ISIGNATURE(2, 1, 1, 0, 69 , 70 , 0  , 0  , 0  , 0  ), // #81  {W:mm, R:mm|m64|mem|r64|xmm}
+    3217             :   ISIGNATURE(2, 1, 1, 0, 71 , 72 , 0  , 0  , 0  , 0  ), //      {W:mm|m64|mem|r64|xmm, R:mm}
+    3218             :   ISIGNATURE(2, 0, 1, 0, 7  , 73 , 0  , 0  , 0  , 0  ), //      {W:r64|m64|mem, R:xmm}
+    3219             :   ISIGNATURE(2, 0, 1, 0, 74 , 16 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:r64|m64|mem}
+    3220             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #85  {W:xmm, R:xmm|m64|mem}
+    3221             :   ISIGNATURE(2, 1, 1, 0, 76 , 73 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:xmm}
+    3222             :   ISIGNATURE(2, 1, 1, 0, 74 , 77 , 0  , 0  , 0  , 0  ), // #87  {W:xmm, R:xmm|m128|mem}
+    3223             :   ISIGNATURE(2, 1, 1, 0, 78 , 73 , 0  , 0  , 0  , 0  ), //      {W:xmm|m128|mem, R:xmm}
+    3224             :   ISIGNATURE(2, 1, 1, 0, 79 , 80 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem}
+    3225             :   ISIGNATURE(2, 1, 1, 0, 81 , 82 , 0  , 0  , 0  , 0  ), //      {W:ymm|m256|mem, R:ymm}
+    3226             :   ISIGNATURE(2, 1, 1, 0, 83 , 84 , 0  , 0  , 0  , 0  ), // #91  {W:zmm, R:zmm|m512|mem}
+    3227             :   ISIGNATURE(2, 1, 1, 0, 85 , 86 , 0  , 0  , 0  , 0  ), //      {W:zmm|m512|mem, R:zmm}
+    3228             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #93  {W:xmm, R:xmm, R:xmm|m128|mem}
+    3229             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), // #94  {W:xmm, R:xmm|m128|mem, R:u8}
+    3230             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 80 , 0  , 0  , 0  ), // #95  {W:ymm, R:ymm, R:ymm|m256|mem}
+    3231             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), // #96  {W:ymm, R:ymm|m256|mem, R:u8}
+    3232             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 84 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem}
+    3233             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3234             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 88 , 0  , 0  , 0  ), // #99  {W:xmm, R:xmm, R:u8|xmm|m128|mem}
+    3235             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 88 , 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:u8|xmm|m128|mem}
+    3236             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), // #101 {W:xmm, R:xmm|m128|mem, R:u8}
+    3237             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem, R:u8}
+    3238             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 77 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:xmm|m128|mem}
+    3239             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3240             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #105 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3241             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem, R:u8}
+    3242             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 77 , 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:xmm|m128|mem}
+    3243             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem, R:u8}
+    3244             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 77 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:xmm|m128|mem}
+    3245             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3246             :   ISIGNATURE(3, 1, 1, 0, 89 , 90 , 89 , 0  , 0  , 0  ), // #111 {X:xmm, R:vm32x, X:xmm}
+    3247             :   ISIGNATURE(3, 1, 1, 0, 91 , 90 , 91 , 0  , 0  , 0  ), //      {X:ymm, R:vm32x, X:ymm}
+    3248             :   ISIGNATURE(2, 1, 1, 0, 89 , 90 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm32x}
+    3249             :   ISIGNATURE(2, 1, 1, 0, 91 , 92 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm32y}
+    3250             :   ISIGNATURE(2, 1, 1, 0, 93 , 94 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm32z}
+    3251             :   ISIGNATURE(3, 1, 1, 0, 89 , 90 , 89 , 0  , 0  , 0  ), // #116 {X:xmm, R:vm32x, X:xmm}
+    3252             :   ISIGNATURE(3, 1, 1, 0, 91 , 92 , 91 , 0  , 0  , 0  ), //      {X:ymm, R:vm32y, X:ymm}
+    3253             :   ISIGNATURE(2, 1, 1, 0, 89 , 90 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm32x}
+    3254             :   ISIGNATURE(2, 1, 1, 0, 91 , 92 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm32y}
+    3255             :   ISIGNATURE(2, 1, 1, 0, 93 , 94 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm32z}
+    3256             :   ISIGNATURE(3, 1, 1, 0, 89 , 95 , 89 , 0  , 0  , 0  ), // #121 {X:xmm, R:vm64x, X:xmm}
+    3257             :   ISIGNATURE(3, 1, 1, 0, 91 , 96 , 91 , 0  , 0  , 0  ), //      {X:ymm, R:vm64y, X:ymm}
+    3258             :   ISIGNATURE(2, 1, 1, 0, 89 , 95 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm64x}
+    3259             :   ISIGNATURE(2, 1, 1, 0, 91 , 96 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm64y}
+    3260             :   ISIGNATURE(2, 1, 1, 0, 93 , 97 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm64z}
+    3261             :   ISIGNATURE(2, 1, 1, 0, 12 , 37 , 0  , 0  , 0  , 0  ), // #126 {R:r16|m16|mem, R:r16}
+    3262             :   ISIGNATURE(2, 1, 1, 0, 43 , 6  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem, R:r32}
+    3263             :   ISIGNATURE(2, 0, 1, 0, 16 , 98 , 0  , 0  , 0  , 0  ), //      {R:r64|m64|mem, R:r64|u8}
+    3264             :   ISIGNATURE(2, 1, 1, 0, 99 , 87 , 0  , 0  , 0  , 0  ), //      {R:r16|m16|r32|m32, R:u8}
+    3265             :   ISIGNATURE(2, 1, 1, 0, 36 , 37 , 0  , 0  , 0  , 0  ), // #130 {X:r16|m16|mem, R:r16}
+    3266             :   ISIGNATURE(2, 1, 1, 0, 38 , 6  , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32}
+    3267             :   ISIGNATURE(2, 0, 1, 0, 31 , 98 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, R:r64|u8}
+    3268             :   ISIGNATURE(2, 1, 1, 0, 100, 87 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|r32|m32, R:u8}
+    3269             :   ISIGNATURE(3, 1, 1, 1, 35 , 2  , 101, 0  , 0  , 0  ), // #134 {X:r8lo|r8hi|m8|mem, R:r8lo|r8hi, R:<al>}
+    3270             :   ISIGNATURE(3, 1, 1, 1, 36 , 37 , 102, 0  , 0  , 0  ), //      {X:r16|m16|mem, R:r16, R:<ax>}
+    3271             :   ISIGNATURE(3, 1, 1, 1, 38 , 6  , 103, 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32, R:<eax>}
+    3272             :   ISIGNATURE(3, 0, 1, 1, 31 , 27 , 104, 0  , 0  , 0  ), //      {X:r64|m64|mem, R:r64, R:<rax>}
+    3273             :   ISIGNATURE(2, 1, 1, 1, 50 , 40 , 0  , 0  , 0  , 0  ), // #138 {X:<ax>, R:r8lo|r8hi|m8|mem}
+    3274             :   ISIGNATURE(3, 1, 1, 2, 105, 50 , 12 , 0  , 0  , 0  ), //      {X:<dx>, X:<ax>, R:r16|m16|mem}
+    3275             :   ISIGNATURE(3, 1, 1, 2, 106, 53 , 43 , 0  , 0  , 0  ), //      {X:<edx>, X:<eax>, R:r32|m32|mem}
+    3276             :   ISIGNATURE(3, 0, 1, 2, 107, 55 , 16 , 0  , 0  , 0  ), //      {X:<rdx>, X:<rax>, R:r64|m64|mem}
+    3277             :   ISIGNATURE(1, 1, 1, 0, 108, 0  , 0  , 0  , 0  , 0  ), // #142 {W:r16|m16|r64|m64|mem}
+    3278             :   ISIGNATURE(1, 1, 0, 0, 23 , 0  , 0  , 0  , 0  , 0  ), //      {W:r32|m32}
+    3279             :   ISIGNATURE(1, 1, 0, 0, 109, 0  , 0  , 0  , 0  , 0  ), //      {W:ds|es|ss}
+    3280             :   ISIGNATURE(1, 1, 1, 0, 110, 0  , 0  , 0  , 0  , 0  ), //      {W:fs|gs}
+    3281             :   ISIGNATURE(1, 1, 1, 0, 111, 0  , 0  , 0  , 0  , 0  ), // #146 {R:r16|m16|r64|m64|mem|i8|i16|i32}
+    3282             :   ISIGNATURE(1, 1, 0, 0, 47 , 0  , 0  , 0  , 0  , 0  ), //      {R:r32|m32}
+    3283             :   ISIGNATURE(1, 1, 0, 0, 112, 0  , 0  , 0  , 0  , 0  ), //      {R:cs|ss|ds|es}
+    3284             :   ISIGNATURE(1, 1, 1, 0, 113, 0  , 0  , 0  , 0  , 0  ), //      {R:fs|gs}
+    3285             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 73 , 77 , 0  , 0  ), // #150 {W:xmm, R:xmm, R:xmm, R:xmm|m128|mem}
+    3286             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 77 , 73 , 0  , 0  ), // #151 {W:xmm, R:xmm, R:xmm|m128|mem, R:xmm}
+    3287             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 82 , 80 , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm, R:ymm|m256|mem}
+    3288             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 80 , 82 , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem, R:ymm}
+    3289             :   ISIGNATURE(3, 1, 1, 0, 89 , 114, 89 , 0  , 0  , 0  ), // #154 {X:xmm, R:vm64x|vm64y, X:xmm}
+    3290             :   ISIGNATURE(2, 1, 1, 0, 89 , 95 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:vm64x}
+    3291             :   ISIGNATURE(2, 1, 1, 0, 91 , 96 , 0  , 0  , 0  , 0  ), //      {X:ymm, R:vm64y}
+    3292             :   ISIGNATURE(2, 1, 1, 0, 93 , 97 , 0  , 0  , 0  , 0  ), //      {X:zmm, R:vm64z}
+    3293             :   ISIGNATURE(3, 1, 1, 0, 115, 73 , 73 , 0  , 0  , 0  ), // #158 {W:m128|mem, R:xmm, R:xmm}
+    3294             :   ISIGNATURE(3, 1, 1, 0, 116, 82 , 82 , 0  , 0  , 0  ), //      {W:m256|mem, R:ymm, R:ymm}
+    3295             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 117, 0  , 0  , 0  ), //      {W:xmm, R:xmm, R:m128|mem}
+    3296             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 118, 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:m256|mem}
+    3297             :   ISIGNATURE(5, 1, 1, 0, 74 , 73 , 77 , 73 , 119, 0  ), // #162 {W:xmm, R:xmm, R:xmm|m128|mem, R:xmm, R:u4}
+    3298             :   ISIGNATURE(5, 1, 1, 0, 74 , 73 , 73 , 77 , 119, 0  ), //      {W:xmm, R:xmm, R:xmm, R:xmm|m128|mem, R:u4}
+    3299             :   ISIGNATURE(5, 1, 1, 0, 79 , 82 , 80 , 82 , 119, 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem, R:ymm, R:u4}
+    3300             :   ISIGNATURE(5, 1, 1, 0, 79 , 82 , 82 , 80 , 119, 0  ), //      {W:ymm, R:ymm, R:ymm, R:ymm|m256|mem, R:u4}
+    3301             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), // #166 {W:ymm, R:ymm|m256|mem, R:u8}
+    3302             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 80 , 0  , 0  , 0  ), // #167 {W:ymm, R:ymm, R:ymm|m256|mem}
+    3303             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 84 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem}
+    3304             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3305             :   ISIGNATURE(2, 1, 1, 0, 35 , 39 , 0  , 0  , 0  , 0  ), // #170 {X:r8lo|r8hi|m8|mem, X:r8lo|r8hi}
+    3306             :   ISIGNATURE(2, 1, 1, 0, 36 , 41 , 0  , 0  , 0  , 0  ), //      {X:r16|m16|mem, X:r16}
+    3307             :   ISIGNATURE(2, 1, 1, 0, 38 , 42 , 0  , 0  , 0  , 0  ), //      {X:r32|m32|mem, X:r32}
+    3308             :   ISIGNATURE(2, 0, 1, 0, 31 , 44 , 0  , 0  , 0  , 0  ), //      {X:r64|m64|mem, X:r64}
+    3309             :   ISIGNATURE(1, 1, 1, 0, 120, 0  , 0  , 0  , 0  , 0  ), // #174 {R:m32|m64}
+    3310             :   ISIGNATURE(2, 1, 1, 0, 121, 122, 0  , 0  , 0  , 0  ), //      {X:fp0, R:fp}
+    3311             :   ISIGNATURE(2, 1, 1, 0, 123, 124, 0  , 0  , 0  , 0  ), //      {X:fp, R:fp0}
+    3312             :   ISIGNATURE(1, 1, 1, 0, 125, 0  , 0  , 0  , 0  , 0  ), // #177 {X:m32|m64}
+    3313             :   ISIGNATURE(2, 1, 1, 0, 121, 122, 0  , 0  , 0  , 0  ), //      {X:fp0, R:fp}
+    3314             :   ISIGNATURE(2, 1, 1, 0, 123, 124, 0  , 0  , 0  , 0  ), //      {X:fp, R:fp0}
+    3315             :   ISIGNATURE(2, 1, 1, 0, 41 , 64 , 0  , 0  , 0  , 0  ), // #180 {X:r16, R:m32|mem}
+    3316             :   ISIGNATURE(2, 1, 1, 0, 42 , 126, 0  , 0  , 0  , 0  ), //      {X:r32, R:m48|mem}
+    3317             :   ISIGNATURE(2, 0, 1, 0, 44 , 127, 0  , 0  , 0  , 0  ), //      {X:r64, R:m80|mem}
+    3318             :   ISIGNATURE(2, 1, 1, 0, 59 , 12 , 0  , 0  , 0  , 0  ), // #183 {W:r16, R:r16|m16|mem}
+    3319             :   ISIGNATURE(2, 1, 1, 0, 13 , 43 , 0  , 0  , 0  , 0  ), // #184 {W:r32, R:r32|m32|mem}
+    3320             :   ISIGNATURE(2, 0, 1, 0, 19 , 16 , 0  , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem}
+    3321             :   ISIGNATURE(3, 1, 1, 0, 36 , 37 , 128, 0  , 0  , 0  ), // #186 {X:r16|m16|mem, R:r16, R:u8|cl}
+    3322             :   ISIGNATURE(3, 1, 1, 0, 38 , 6  , 128, 0  , 0  , 0  ), //      {X:r32|m32|mem, R:r32, R:u8|cl}
+    3323             :   ISIGNATURE(3, 0, 1, 0, 31 , 27 , 128, 0  , 0  , 0  ), //      {X:r64|m64|mem, R:r64, R:u8|cl}
+    3324             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #189 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3325             :   ISIGNATURE(3, 1, 1, 0, 79 , 82 , 80 , 0  , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem}
+    3326             :   ISIGNATURE(3, 1, 1, 0, 83 , 86 , 84 , 0  , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem}
+    3327             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 77 , 87 , 0  , 0  ), // #192 {W:xmm, R:xmm, R:xmm|m128|mem, R:u8}
+    3328             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 80 , 87 , 0  , 0  ), // #193 {W:ymm, R:ymm, R:ymm|m256|mem, R:u8}
+    3329             :   ISIGNATURE(4, 1, 1, 0, 83 , 86 , 84 , 87 , 0  , 0  ), //      {W:zmm, R:zmm, R:zmm|m512|mem, R:u8}
+    3330             :   ISIGNATURE(4, 1, 1, 0, 129, 73 , 77 , 87 , 0  , 0  ), // #195 {W:xmm|k, R:xmm, R:xmm|m128|mem, R:u8}
+    3331             :   ISIGNATURE(4, 1, 1, 0, 130, 82 , 80 , 87 , 0  , 0  ), //      {W:ymm|k, R:ymm, R:ymm|m256|mem, R:u8}
+    3332             :   ISIGNATURE(4, 1, 1, 0, 131, 86 , 84 , 87 , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem, R:u8}
+    3333             :   ISIGNATURE(2, 1, 1, 0, 78 , 73 , 0  , 0  , 0  , 0  ), // #198 {W:xmm|m128|mem, R:xmm}
+    3334             :   ISIGNATURE(2, 1, 1, 0, 81 , 82 , 0  , 0  , 0  , 0  ), //      {W:ymm|m256|mem, R:ymm}
+    3335             :   ISIGNATURE(2, 1, 1, 0, 85 , 86 , 0  , 0  , 0  , 0  ), //      {W:zmm|m512|mem, R:zmm}
+    3336             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #201 {W:xmm, R:xmm|m64|mem}
+    3337             :   ISIGNATURE(2, 1, 1, 0, 79 , 77 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m128|mem}
+    3338             :   ISIGNATURE(2, 1, 1, 0, 83 , 80 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:ymm|m256|mem}
+    3339             :   ISIGNATURE(2, 1, 1, 0, 74 , 77 , 0  , 0  , 0  , 0  ), // #204 {W:xmm, R:xmm|m128|mem}
+    3340             :   ISIGNATURE(2, 1, 1, 0, 79 , 80 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem}
+    3341             :   ISIGNATURE(2, 1, 1, 0, 83 , 84 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem}
+    3342             :   ISIGNATURE(2, 1, 1, 0, 74 , 132, 0  , 0  , 0  , 0  ), // #207 {W:xmm, R:xmm|m128|ymm|m256|m64}
+    3343             :   ISIGNATURE(2, 1, 1, 0, 79 , 133, 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m128}
+    3344             :   ISIGNATURE(2, 1, 1, 0, 83 , 134, 0  , 0  , 0  , 0  ), //      {W:zmm, R:ymm|m256}
+    3345             :   ISIGNATURE(3, 1, 1, 0, 76 , 73 , 87 , 0  , 0  , 0  ), // #210 {W:xmm|m64|mem, R:xmm, R:u8}
+    3346             :   ISIGNATURE(3, 1, 1, 0, 78 , 82 , 87 , 0  , 0  , 0  ), // #211 {W:xmm|m128|mem, R:ymm, R:u8}
+    3347             :   ISIGNATURE(3, 1, 1, 0, 81 , 86 , 87 , 0  , 0  , 0  ), // #212 {W:ymm|m256|mem, R:zmm, R:u8}
+    3348             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 77 , 87 , 0  , 0  ), // #213 {X:xmm, R:xmm, R:xmm|m128|mem, R:u8}
+    3349             :   ISIGNATURE(4, 1, 1, 0, 91 , 82 , 80 , 87 , 0  , 0  ), //      {X:ymm, R:ymm, R:ymm|m256|mem, R:u8}
+    3350             :   ISIGNATURE(4, 1, 1, 0, 93 , 86 , 84 , 87 , 0  , 0  ), //      {X:zmm, R:zmm, R:zmm|m512|mem, R:u8}
+    3351             :   ISIGNATURE(3, 1, 1, 0, 89 , 73 , 77 , 0  , 0  , 0  ), // #216 {X:xmm, R:xmm, R:xmm|m128|mem}
+    3352             :   ISIGNATURE(3, 1, 1, 0, 91 , 82 , 80 , 0  , 0  , 0  ), //      {X:ymm, R:ymm, R:ymm|m256|mem}
+    3353             :   ISIGNATURE(3, 1, 1, 0, 93 , 86 , 84 , 0  , 0  , 0  ), //      {X:zmm, R:zmm, R:zmm|m512|mem}
+    3354             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 87 , 0  , 0  , 0  ), // #219 {W:xmm, R:xmm|m128|mem, R:u8}
+    3355             :   ISIGNATURE(3, 1, 1, 0, 79 , 80 , 87 , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem, R:u8}
+    3356             :   ISIGNATURE(3, 1, 1, 0, 83 , 84 , 87 , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem, R:u8}
+    3357             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #222 {W:xmm, R:xmm|m64|mem}
+    3358             :   ISIGNATURE(2, 1, 1, 0, 79 , 80 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:ymm|m256|mem}
+    3359             :   ISIGNATURE(2, 1, 1, 0, 83 , 84 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:zmm|m512|mem}
+    3360             :   ISIGNATURE(2, 1, 1, 0, 115, 73 , 0  , 0  , 0  , 0  ), // #225 {W:m128|mem, R:xmm}
+    3361             :   ISIGNATURE(2, 1, 1, 0, 116, 82 , 0  , 0  , 0  , 0  ), //      {W:m256|mem, R:ymm}
+    3362             :   ISIGNATURE(2, 1, 1, 0, 135, 86 , 0  , 0  , 0  , 0  ), //      {W:m512|mem, R:zmm}
+    3363             :   ISIGNATURE(2, 1, 1, 0, 74 , 117, 0  , 0  , 0  , 0  ), // #228 {W:xmm, R:m128|mem}
+    3364             :   ISIGNATURE(2, 1, 1, 0, 79 , 118, 0  , 0  , 0  , 0  ), //      {W:ymm, R:m256|mem}
+    3365             :   ISIGNATURE(2, 1, 1, 0, 83 , 136, 0  , 0  , 0  , 0  ), //      {W:zmm, R:m512|mem}
+    3366             :   ISIGNATURE(2, 0, 1, 0, 7  , 73 , 0  , 0  , 0  , 0  ), // #231 {W:r64|m64|mem, R:xmm}
+    3367             :   ISIGNATURE(2, 1, 1, 0, 74 , 137, 0  , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m64|mem|r64}
+    3368             :   ISIGNATURE(2, 1, 1, 0, 76 , 73 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:xmm}
+    3369             :   ISIGNATURE(2, 1, 1, 0, 68 , 73 , 0  , 0  , 0  , 0  ), // #234 {W:m64|mem, R:xmm}
+    3370             :   ISIGNATURE(2, 1, 1, 0, 74 , 65 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:m64|mem}
+    3371             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 73 , 0  , 0  , 0  ), // #236 {W:xmm, R:xmm, R:xmm}
+    3372             :   ISIGNATURE(2, 1, 1, 0, 67 , 73 , 0  , 0  , 0  , 0  ), // #237 {W:m32|mem, R:xmm}
+    3373             :   ISIGNATURE(2, 1, 1, 0, 74 , 64 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:m32|mem}
+    3374             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 73 , 0  , 0  , 0  ), //      {W:xmm, R:xmm, R:xmm}
+    3375             :   ISIGNATURE(4, 1, 1, 0, 131, 73 , 77 , 87 , 0  , 0  ), // #240 {W:k, R:xmm, R:xmm|m128|mem, R:u8}
+    3376             :   ISIGNATURE(4, 1, 1, 0, 131, 82 , 80 , 87 , 0  , 0  ), //      {W:k, R:ymm, R:ymm|m256|mem, R:u8}
+    3377             :   ISIGNATURE(4, 1, 1, 0, 131, 86 , 84 , 87 , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem, R:u8}
+    3378             :   ISIGNATURE(3, 1, 1, 0, 129, 73 , 77 , 0  , 0  , 0  ), // #243 {W:xmm|k, R:xmm, R:xmm|m128|mem}
+    3379             :   ISIGNATURE(3, 1, 1, 0, 130, 82 , 80 , 0  , 0  , 0  ), //      {W:ymm|k, R:ymm, R:ymm|m256|mem}
+    3380             :   ISIGNATURE(3, 1, 1, 0, 131, 86 , 84 , 0  , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem}
+    3381             :   ISIGNATURE(2, 1, 1, 0, 138, 73 , 0  , 0  , 0  , 0  ), // #246 {W:xmm|m32|mem, R:xmm}
+    3382             :   ISIGNATURE(2, 1, 1, 0, 76 , 82 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:ymm}
+    3383             :   ISIGNATURE(2, 1, 1, 0, 78 , 86 , 0  , 0  , 0  , 0  ), //      {W:xmm|m128|mem, R:zmm}
+    3384             :   ISIGNATURE(2, 1, 1, 0, 76 , 73 , 0  , 0  , 0  , 0  ), // #249 {W:xmm|m64|mem, R:xmm}
+    3385             :   ISIGNATURE(2, 1, 1, 0, 78 , 82 , 0  , 0  , 0  , 0  ), //      {W:xmm|m128|mem, R:ymm}
+    3386             :   ISIGNATURE(2, 1, 1, 0, 81 , 86 , 0  , 0  , 0  , 0  ), //      {W:ymm|m256|mem, R:zmm}
+    3387             :   ISIGNATURE(2, 1, 1, 0, 139, 73 , 0  , 0  , 0  , 0  ), // #252 {W:xmm|m16|mem, R:xmm}
+    3388             :   ISIGNATURE(2, 1, 1, 0, 138, 82 , 0  , 0  , 0  , 0  ), //      {W:xmm|m32|mem, R:ymm}
+    3389             :   ISIGNATURE(2, 1, 1, 0, 76 , 86 , 0  , 0  , 0  , 0  ), //      {W:xmm|m64|mem, R:zmm}
+    3390             :   ISIGNATURE(2, 1, 1, 0, 74 , 140, 0  , 0  , 0  , 0  ), // #255 {W:xmm, R:xmm|m32|mem}
+    3391             :   ISIGNATURE(2, 1, 1, 0, 79 , 75 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m64|mem}
+    3392             :   ISIGNATURE(2, 1, 1, 0, 83 , 77 , 0  , 0  , 0  , 0  ), //      {W:zmm, R:xmm|m128|mem}
+    3393             :   ISIGNATURE(2, 1, 1, 0, 74 , 141, 0  , 0  , 0  , 0  ), // #258 {W:xmm, R:xmm|m16|mem}
+    3394             :   ISIGNATURE(2, 1, 1, 0, 79 , 140, 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m32|mem}
+    3395             :   ISIGNATURE(2, 1, 1, 0, 83 , 75 , 0  , 0  , 0  , 0  ), // #260 {W:zmm, R:xmm|m64|mem}
+    3396             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #261 {W:xmm, R:xmm|m64|mem}
+    3397             :   ISIGNATURE(2, 1, 1, 0, 79 , 77 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:xmm|m128|mem}
+    3398             :   ISIGNATURE(2, 1, 1, 0, 83 , 142, 0  , 0  , 0  , 0  ), //      {W:zmm, R:xmm|m256|mem}
+    3399             :   ISIGNATURE(2, 1, 1, 0, 143, 73 , 0  , 0  , 0  , 0  ), // #264 {W:vm32x, R:xmm}
+    3400             :   ISIGNATURE(2, 1, 1, 0, 144, 82 , 0  , 0  , 0  , 0  ), //      {W:vm32y, R:ymm}
+    3401             :   ISIGNATURE(2, 1, 1, 0, 145, 86 , 0  , 0  , 0  , 0  ), //      {W:vm32z, R:zmm}
+    3402             :   ISIGNATURE(2, 1, 1, 0, 146, 73 , 0  , 0  , 0  , 0  ), // #267 {W:vm64x, R:xmm}
+    3403             :   ISIGNATURE(2, 1, 1, 0, 147, 82 , 0  , 0  , 0  , 0  ), //      {W:vm64y, R:ymm}
+    3404             :   ISIGNATURE(2, 1, 1, 0, 148, 86 , 0  , 0  , 0  , 0  ), //      {W:vm64z, R:zmm}
+    3405             :   ISIGNATURE(3, 1, 1, 0, 131, 73 , 77 , 0  , 0  , 0  ), // #270 {W:k, R:xmm, R:xmm|m128|mem}
+    3406             :   ISIGNATURE(3, 1, 1, 0, 131, 82 , 80 , 0  , 0  , 0  ), //      {W:k, R:ymm, R:ymm|m256|mem}
+    3407             :   ISIGNATURE(3, 1, 1, 0, 131, 86 , 84 , 0  , 0  , 0  ), //      {W:k, R:zmm, R:zmm|m512|mem}
+    3408             :   ISIGNATURE(3, 1, 1, 0, 13 , 6  , 43 , 0  , 0  , 0  ), // #273 {W:r32, R:r32, R:r32|m32|mem}
+    3409             :   ISIGNATURE(3, 0, 1, 0, 19 , 27 , 16 , 0  , 0  , 0  ), //      {W:r64, R:r64, R:r64|m64|mem}
+    3410             :   ISIGNATURE(3, 1, 1, 0, 13 , 43 , 6  , 0  , 0  , 0  ), // #275 {W:r32, R:r32|m32|mem, R:r32}
+    3411             :   ISIGNATURE(3, 0, 1, 0, 19 , 16 , 27 , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem, R:r64}
+    3412             :   ISIGNATURE(2, 1, 0, 0, 149, 43 , 0  , 0  , 0  , 0  ), // #277 {R:bnd, R:r32|m32|mem}
+    3413             :   ISIGNATURE(2, 0, 1, 0, 149, 16 , 0  , 0  , 0  , 0  ), //      {R:bnd, R:r64|m64|mem}
+    3414             :   ISIGNATURE(2, 1, 1, 0, 150, 151, 0  , 0  , 0  , 0  ), // #279 {W:bnd, R:bnd|mem}
+    3415             :   ISIGNATURE(2, 1, 1, 0, 152, 149, 0  , 0  , 0  , 0  ), //      {W:bnd|mem, R:bnd}
+    3416             :   ISIGNATURE(2, 1, 0, 0, 37 , 64 , 0  , 0  , 0  , 0  ), // #281 {R:r16, R:m32|mem}
+    3417             :   ISIGNATURE(2, 1, 0, 0, 6  , 65 , 0  , 0  , 0  , 0  ), //      {R:r32, R:m64|mem}
+    3418             :   ISIGNATURE(1, 1, 1, 0, 153, 0  , 0  , 0  , 0  , 0  ), // #283 {R:rel32|r64|m64|mem}
+    3419             :   ISIGNATURE(1, 1, 0, 0, 43 , 0  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem}
+    3420             :   ISIGNATURE(2, 1, 1, 0, 42 , 154, 0  , 0  , 0  , 0  ), // #285 {X:r32, R:r8lo|r8hi|m8|r16|m16|r32|m32}
+    3421             :   ISIGNATURE(2, 0, 1, 0, 44 , 155, 0  , 0  , 0  , 0  ), //      {X:r64, R:r8lo|r8hi|m8|r64|m64}
+    3422             :   ISIGNATURE(1, 1, 0, 0, 156, 0  , 0  , 0  , 0  , 0  ), // #287 {X:r16|r32}
+    3423             :   ISIGNATURE(1, 1, 1, 0, 49 , 0  , 0  , 0  , 0  , 0  ), // #288 {X:r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem}
+    3424             :   ISIGNATURE(3, 1, 1, 0, 89 , 87 , 87 , 0  , 0  , 0  ), // #289 {X:xmm, R:u8, R:u8}
+    3425             :   ISIGNATURE(2, 1, 1, 0, 89 , 73 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:xmm}
+    3426             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #291 {}
+    3427             :   ISIGNATURE(1, 1, 1, 0, 123, 0  , 0  , 0  , 0  , 0  ), // #292 {X:fp}
+    3428             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #293 {}
+    3429             :   ISIGNATURE(1, 1, 1, 0, 157, 0  , 0  , 0  , 0  , 0  ), //      {R:m32|m64|fp}
+    3430             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #295 {}
+    3431             :   ISIGNATURE(1, 1, 1, 0, 122, 0  , 0  , 0  , 0  , 0  ), // #296 {R:fp}
+    3432             :   ISIGNATURE(2, 1, 1, 0, 89 , 73 , 0  , 0  , 0  , 0  ), // #297 {X:xmm, R:xmm}
+    3433             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 87 , 87 , 0  , 0  ), //      {X:xmm, R:xmm, R:u8, R:u8}
+    3434             :   ISIGNATURE(2, 1, 0, 0, 6  , 117, 0  , 0  , 0  , 0  ), // #299 {R:r32, R:m128|mem}
+    3435             :   ISIGNATURE(2, 0, 1, 0, 27 , 117, 0  , 0  , 0  , 0  ), //      {R:r64, R:m128|mem}
+    3436             :   ISIGNATURE(2, 1, 0, 1, 158, 159, 0  , 0  , 0  , 0  ), // #301 {R:<cx|ecx>, R:rel8}
+    3437             :   ISIGNATURE(2, 0, 1, 1, 160, 159, 0  , 0  , 0  , 0  ), //      {R:<ecx|rcx>, R:rel8}
+    3438             :   ISIGNATURE(1, 1, 1, 0, 161, 0  , 0  , 0  , 0  , 0  ), // #303 {R:rel8|rel32|r64|m64|mem}
+    3439             :   ISIGNATURE(1, 1, 0, 0, 43 , 0  , 0  , 0  , 0  , 0  ), //      {R:r32|m32|mem}
+    3440             :   ISIGNATURE(2, 1, 1, 0, 131, 162, 0  , 0  , 0  , 0  ), // #305 {W:k, R:k|m8|mem|r32|r64|r8lo|r8hi|r16}
+    3441             :   ISIGNATURE(2, 1, 1, 0, 163, 164, 0  , 0  , 0  , 0  ), //      {W:m8|mem|r32|r64|r8lo|r8hi|r16, R:k}
+    3442             :   ISIGNATURE(2, 1, 1, 0, 131, 165, 0  , 0  , 0  , 0  ), // #307 {W:k, R:k|m32|mem|r32|r64}
+    3443             :   ISIGNATURE(2, 1, 1, 0, 166, 164, 0  , 0  , 0  , 0  ), //      {W:m32|mem|r32|r64, R:k}
+    3444             :   ISIGNATURE(2, 1, 1, 0, 131, 167, 0  , 0  , 0  , 0  ), // #309 {W:k, R:k|m64|mem|r64}
+    3445             :   ISIGNATURE(2, 1, 1, 0, 7  , 164, 0  , 0  , 0  , 0  ), //      {W:m64|mem|r64, R:k}
+    3446             :   ISIGNATURE(2, 1, 1, 0, 131, 168, 0  , 0  , 0  , 0  ), // #311 {W:k, R:k|m16|mem|r32|r64|r16}
+    3447             :   ISIGNATURE(2, 1, 1, 0, 169, 164, 0  , 0  , 0  , 0  ), //      {W:m16|mem|r32|r64|r16, R:k}
+    3448             :   ISIGNATURE(2, 1, 1, 0, 59 , 12 , 0  , 0  , 0  , 0  ), // #313 {W:r16, R:r16|m16|mem}
+    3449             :   ISIGNATURE(2, 1, 1, 0, 13 , 170, 0  , 0  , 0  , 0  ), //      {W:r32, R:r32|m16|mem|r16}
+    3450             :   ISIGNATURE(2, 1, 0, 0, 41 , 64 , 0  , 0  , 0  , 0  ), // #315 {X:r16, R:m32|mem}
+    3451             :   ISIGNATURE(2, 1, 0, 0, 42 , 126, 0  , 0  , 0  , 0  ), //      {X:r32, R:m48|mem}
+    3452             :   ISIGNATURE(2, 1, 0, 1, 171, 159, 0  , 0  , 0  , 0  ), // #317 {X:<cx|ecx>, R:rel8}
+    3453             :   ISIGNATURE(2, 0, 1, 1, 172, 159, 0  , 0  , 0  , 0  ), //      {X:<ecx|rcx>, R:rel8}
+    3454             :   ISIGNATURE(2, 1, 1, 0, 59 , 12 , 0  , 0  , 0  , 0  ), // #319 {W:r16, R:r16|m16|mem}
+    3455             :   ISIGNATURE(2, 1, 1, 0, 173, 170, 0  , 0  , 0  , 0  ), //      {W:r32|r64, R:r32|m16|mem|r16}
+    3456             :   ISIGNATURE(2, 1, 1, 0, 174, 175, 0  , 0  , 0  , 0  ), // #321 {W:mm|xmm, R:r32|m32|mem|r64}
+    3457             :   ISIGNATURE(2, 1, 1, 0, 166, 176, 0  , 0  , 0  , 0  ), //      {W:r32|m32|mem|r64, R:mm|xmm}
+    3458             :   ISIGNATURE(2, 1, 1, 0, 74 , 75 , 0  , 0  , 0  , 0  ), // #323 {W:xmm, R:xmm|m64|mem}
+    3459             :   ISIGNATURE(2, 1, 1, 0, 68 , 73 , 0  , 0  , 0  , 0  ), //      {W:m64|mem, R:xmm}
+    3460             :   ISIGNATURE(2, 1, 1, 0, 74 , 140, 0  , 0  , 0  , 0  ), // #325 {W:xmm, R:xmm|m32|mem}
+    3461             :   ISIGNATURE(2, 1, 1, 0, 67 , 73 , 0  , 0  , 0  , 0  ), //      {W:m32|mem, R:xmm}
+    3462             :   ISIGNATURE(2, 1, 1, 0, 177, 45 , 0  , 0  , 0  , 0  ), // #327 {W:r16|r32|r64, R:r8lo|r8hi|m8}
+    3463             :   ISIGNATURE(2, 1, 1, 0, 173, 46 , 0  , 0  , 0  , 0  ), //      {W:r32|r64, R:r16|m16}
+    3464             :   ISIGNATURE(4, 1, 1, 1, 13 , 13 , 43 , 178, 0  , 0  ), // #329 {W:r32, W:r32, R:r32|m32|mem, R:<edx>}
+    3465             :   ISIGNATURE(4, 0, 1, 1, 19 , 19 , 16 , 179, 0  , 0  ), //      {W:r64, W:r64, R:r64|m64|mem, R:<rdx>}
+    3466             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #331 {}
+    3467             :   ISIGNATURE(1, 1, 1, 0, 99 , 0  , 0  , 0  , 0  , 0  ), //      {R:r16|m16|r32|m32}
+    3468             :   ISIGNATURE(2, 1, 1, 0, 69 , 180, 0  , 0  , 0  , 0  ), // #333 {W:mm, R:mm|m64|mem}
+    3469             :   ISIGNATURE(2, 1, 1, 0, 74 , 77 , 0  , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem}
+    3470             :   ISIGNATURE(2, 1, 1, 0, 181, 180, 0  , 0  , 0  , 0  ), // #335 {X:mm, R:mm|m64|mem}
+    3471             :   ISIGNATURE(2, 1, 1, 0, 89 , 77 , 0  , 0  , 0  , 0  ), // #336 {X:xmm, R:xmm|m128|mem}
+    3472             :   ISIGNATURE(3, 1, 1, 0, 181, 180, 87 , 0  , 0  , 0  ), // #337 {X:mm, R:mm|m64|mem, R:u8}
+    3473             :   ISIGNATURE(3, 1, 1, 0, 89 , 77 , 87 , 0  , 0  , 0  ), // #338 {X:xmm, R:xmm|m128|mem, R:u8}
+    3474             :   ISIGNATURE(3, 1, 1, 0, 173, 72 , 87 , 0  , 0  , 0  ), // #339 {W:r32|r64, R:mm, R:u8}
+    3475             :   ISIGNATURE(3, 1, 1, 0, 169, 73 , 87 , 0  , 0  , 0  ), // #340 {W:r32|r64|m16|mem|r16, R:xmm, R:u8}
+    3476             :   ISIGNATURE(2, 1, 1, 0, 181, 182, 0  , 0  , 0  , 0  ), // #341 {X:mm, R:u8|mm|m64|mem}
+    3477             :   ISIGNATURE(2, 1, 1, 0, 89 , 88 , 0  , 0  , 0  , 0  ), //      {X:xmm, R:u8|xmm|m128|mem}
+    3478             :   ISIGNATURE(0, 1, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #343 {}
+    3479             :   ISIGNATURE(1, 1, 1, 0, 183, 0  , 0  , 0  , 0  , 0  ), //      {R:u16}
+    3480             :   ISIGNATURE(3, 1, 1, 0, 13 , 43 , 87 , 0  , 0  , 0  ), // #345 {W:r32, R:r32|m32|mem, R:u8}
+    3481             :   ISIGNATURE(3, 0, 1, 0, 19 , 16 , 87 , 0  , 0  , 0  ), //      {W:r64, R:r64|m64|mem, R:u8}
+    3482             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 77 , 73 , 0  , 0  ), // #347 {W:xmm, R:xmm, R:xmm|m128|mem, R:xmm}
+    3483             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 80 , 82 , 0  , 0  ), //      {W:ymm, R:ymm, R:ymm|m256|mem, R:ymm}
+    3484             :   ISIGNATURE(2, 1, 1, 0, 74 , 184, 0  , 0  , 0  , 0  ), // #349 {W:xmm, R:xmm|m128|ymm|m256}
+    3485             :   ISIGNATURE(2, 1, 1, 0, 79 , 84 , 0  , 0  , 0  , 0  ), //      {W:ymm, R:zmm|m512|mem}
+    3486             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 73 , 75 , 0  , 0  ), // #351 {W:xmm, R:xmm, R:xmm, R:xmm|m64|mem}
+    3487             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 75 , 73 , 0  , 0  ), //      {W:xmm, R:xmm, R:xmm|m64|mem, R:xmm}
+    3488             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 73 , 140, 0  , 0  ), // #353 {W:xmm, R:xmm, R:xmm, R:xmm|m32|mem}
+    3489             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 140, 73 , 0  , 0  ), //      {W:xmm, R:xmm, R:xmm|m32|mem, R:xmm}
+    3490             :   ISIGNATURE(4, 1, 1, 0, 79 , 82 , 77 , 87 , 0  , 0  ), // #355 {W:ymm, R:ymm, R:xmm|m128|mem, R:u8}
+    3491             :   ISIGNATURE(4, 1, 1, 0, 83 , 86 , 77 , 87 , 0  , 0  ), //      {W:zmm, R:zmm, R:xmm|m128|mem, R:u8}
+    3492             :   ISIGNATURE(2, 1, 1, 0, 166, 73 , 0  , 0  , 0  , 0  ), // #357 {W:r32|m32|mem|r64, R:xmm}
+    3493             :   ISIGNATURE(2, 1, 1, 0, 74 , 175, 0  , 0  , 0  , 0  ), //      {W:xmm, R:r32|m32|mem|r64}
+    3494             :   ISIGNATURE(2, 1, 1, 0, 68 , 73 , 0  , 0  , 0  , 0  ), // #359 {W:m64|mem, R:xmm}
+    3495             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 65 , 0  , 0  , 0  ), //      {W:xmm, R:xmm, R:m64|mem}
+    3496             :   ISIGNATURE(2, 1, 1, 0, 185, 186, 0  , 0  , 0  , 0  ), // #361 {W:xmm|ymm|zmm, R:xmm|m8|mem}
+    3497             :   ISIGNATURE(2, 1, 1, 0, 185, 187, 0  , 0  , 0  , 0  ), //      {W:xmm|ymm|zmm, R:r32|r64}
+    3498             :   ISIGNATURE(2, 1, 1, 0, 185, 140, 0  , 0  , 0  , 0  ), // #363 {W:xmm|ymm|zmm, R:xmm|m32|mem}
+    3499             :   ISIGNATURE(2, 1, 1, 0, 185, 187, 0  , 0  , 0  , 0  ), //      {W:xmm|ymm|zmm, R:r32|r64}
+    3500             :   ISIGNATURE(2, 1, 1, 0, 185, 141, 0  , 0  , 0  , 0  ), // #365 {W:xmm|ymm|zmm, R:xmm|m16|mem}
+    3501             :   ISIGNATURE(2, 1, 1, 0, 185, 187, 0  , 0  , 0  , 0  ), //      {W:xmm|ymm|zmm, R:r32|r64}
+    3502             :   ISIGNATURE(3, 1, 1, 0, 74 , 188, 87 , 0  , 0  , 0  ), // #367 {W:xmm, R:r32|m8|mem|r8lo|r8hi|r16|r64, R:u8}
+    3503             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 188, 87 , 0  , 0  ), //      {W:xmm, R:xmm, R:r32|m8|mem|r8lo|r8hi|r16|r64, R:u8}
+    3504             :   ISIGNATURE(3, 1, 1, 0, 74 , 175, 87 , 0  , 0  , 0  ), // #369 {W:xmm, R:r32|m32|mem|r64, R:u8}
+    3505             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 175, 87 , 0  , 0  ), //      {W:xmm, R:xmm, R:r32|m32|mem|r64, R:u8}
+    3506             :   ISIGNATURE(3, 0, 1, 0, 74 , 16 , 87 , 0  , 0  , 0  ), // #371 {W:xmm, R:r64|m64|mem, R:u8}
+    3507             :   ISIGNATURE(4, 0, 1, 0, 74 , 73 , 16 , 87 , 0  , 0  ), //      {W:xmm, R:xmm, R:r64|m64|mem, R:u8}
+    3508             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #373 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3509             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 189, 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem, R:u8|xmm}
+    3510             :   ISIGNATURE(2, 1, 1, 0, 190, 73 , 0  , 0  , 0  , 0  ), // #375 {W:vm64x|vm64y, R:xmm}
+    3511             :   ISIGNATURE(2, 1, 1, 0, 148, 82 , 0  , 0  , 0  , 0  ), //      {W:vm64z, R:ymm}
+    3512             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 77 , 0  , 0  , 0  ), // #377 {W:xmm, R:xmm, R:xmm|m128|mem}
+    3513             :   ISIGNATURE(3, 1, 1, 0, 74 , 77 , 73 , 0  , 0  , 0  ), //      {W:xmm, R:xmm|m128|mem, R:xmm}
+    3514             :   ISIGNATURE(2, 1, 1, 0, 73 , 77 , 0  , 0  , 0  , 0  ), // #379 {R:xmm, R:xmm|m128|mem}
+    3515             :   ISIGNATURE(2, 1, 1, 0, 82 , 80 , 0  , 0  , 0  , 0  ), //      {R:ymm, R:ymm|m256|mem}
+    3516             :   ISIGNATURE(2, 1, 1, 0, 143, 191, 0  , 0  , 0  , 0  ), // #381 {W:vm32x, R:xmm|ymm}
+    3517             :   ISIGNATURE(2, 1, 1, 0, 144, 86 , 0  , 0  , 0  , 0  ), //      {W:vm32y, R:zmm}
+    3518             :   ISIGNATURE(1, 1, 0, 1, 50 , 0  , 0  , 0  , 0  , 0  ), // #383 {X:<ax>}
+    3519             :   ISIGNATURE(2, 1, 0, 1, 50 , 87 , 0  , 0  , 0  , 0  ), // #384 {X:<ax>, R:u8}
+    3520             :   ISIGNATURE(2, 1, 1, 0, 89 , 75 , 0  , 0  , 0  , 0  ), // #385 {X:xmm, R:xmm|m64|mem}
+    3521             :   ISIGNATURE(2, 1, 1, 0, 89 , 140, 0  , 0  , 0  , 0  ), // #386 {X:xmm, R:xmm|m32|mem}
+    3522             :   ISIGNATURE(2, 1, 0, 0, 36 , 37 , 0  , 0  , 0  , 0  ), // #387 {X:r16|m16|mem, R:r16}
+    3523             :   ISIGNATURE(3, 1, 1, 1, 89 , 77 , 192, 0  , 0  , 0  ), // #388 {X:xmm, R:xmm|m128|mem, R:<xmm0>}
+    3524             :   ISIGNATURE(2, 1, 1, 0, 150, 193, 0  , 0  , 0  , 0  ), // #389 {W:bnd, R:mib}
+    3525             :   ISIGNATURE(2, 1, 1, 0, 150, 194, 0  , 0  , 0  , 0  ), // #390 {W:bnd, R:mem}
+    3526             :   ISIGNATURE(2, 1, 1, 0, 195, 149, 0  , 0  , 0  , 0  ), // #391 {W:mib, R:bnd}
+    3527             :   ISIGNATURE(1, 1, 1, 0, 196, 0  , 0  , 0  , 0  , 0  ), // #392 {X:r32|r64}
+    3528             :   ISIGNATURE(1, 1, 1, 1, 50 , 0  , 0  , 0  , 0  , 0  ), // #393 {X:<ax>}
+    3529             :   ISIGNATURE(2, 1, 1, 2, 52 , 103, 0  , 0  , 0  , 0  ), // #394 {W:<edx>, R:<eax>}
+    3530             :   ISIGNATURE(1, 0, 1, 1, 55 , 0  , 0  , 0  , 0  , 0  ), // #395 {X:<rax>}
+    3531             :   ISIGNATURE(1, 1, 1, 0, 194, 0  , 0  , 0  , 0  , 0  ), // #396 {R:mem}
+    3532             :   ISIGNATURE(1, 1, 1, 1, 197, 0  , 0  , 0  , 0  , 0  ), // #397 {R:<ds:[zax]>}
+    3533             :   ISIGNATURE(2, 1, 1, 2, 198, 199, 0  , 0  , 0  , 0  ), // #398 {X:<ds:[zsi]>, X:<es:[zdi]>}
+    3534             :   ISIGNATURE(3, 1, 1, 0, 89 , 75 , 87 , 0  , 0  , 0  ), // #399 {X:xmm, R:xmm|m64|mem, R:u8}
+    3535             :   ISIGNATURE(3, 1, 1, 0, 89 , 140, 87 , 0  , 0  , 0  ), // #400 {X:xmm, R:xmm|m32|mem, R:u8}
+    3536             :   ISIGNATURE(5, 0, 1, 4, 200, 107, 55 , 201, 202, 0  ), // #401 {X:m128|mem, X:<rdx>, X:<rax>, R:<rcx>, R:<rbx>}
+    3537             :   ISIGNATURE(5, 1, 1, 4, 203, 106, 53 , 204, 205, 0  ), // #402 {X:m64|mem, X:<edx>, X:<eax>, R:<ecx>, R:<ebx>}
+    3538             :   ISIGNATURE(2, 1, 1, 0, 73 , 75 , 0  , 0  , 0  , 0  ), // #403 {R:xmm, R:xmm|m64|mem}
+    3539             :   ISIGNATURE(2, 1, 1, 0, 73 , 140, 0  , 0  , 0  , 0  ), // #404 {R:xmm, R:xmm|m32|mem}
+    3540             :   ISIGNATURE(4, 1, 1, 4, 53 , 206, 207, 52 , 0  , 0  ), // #405 {X:<eax>, W:<ebx>, X:<ecx>, W:<edx>}
+    3541             :   ISIGNATURE(2, 0, 1, 2, 54 , 104, 0  , 0  , 0  , 0  ), // #406 {W:<rdx>, R:<rax>}
+    3542             :   ISIGNATURE(2, 1, 1, 0, 69 , 77 , 0  , 0  , 0  , 0  ), // #407 {W:mm, R:xmm|m128|mem}
+    3543             :   ISIGNATURE(2, 1, 1, 0, 74 , 180, 0  , 0  , 0  , 0  ), // #408 {W:xmm, R:mm|m64|mem}
+    3544             :   ISIGNATURE(2, 1, 1, 0, 69 , 75 , 0  , 0  , 0  , 0  ), // #409 {W:mm, R:xmm|m64|mem}
+    3545             :   ISIGNATURE(2, 1, 1, 0, 173, 75 , 0  , 0  , 0  , 0  ), // #410 {W:r32|r64, R:xmm|m64|mem}
+    3546             :   ISIGNATURE(2, 1, 1, 0, 74 , 208, 0  , 0  , 0  , 0  ), // #411 {W:xmm, R:r32|m32|mem|r64|m64}
+    3547             :   ISIGNATURE(2, 1, 1, 0, 173, 140, 0  , 0  , 0  , 0  ), // #412 {W:r32|r64, R:xmm|m32|mem}
+    3548             :   ISIGNATURE(2, 1, 1, 2, 51 , 102, 0  , 0  , 0  , 0  ), // #413 {W:<dx>, R:<ax>}
+    3549             :   ISIGNATURE(1, 1, 1, 1, 53 , 0  , 0  , 0  , 0  , 0  ), // #414 {X:<eax>}
+    3550             :   ISIGNATURE(2, 1, 1, 0, 183, 87 , 0  , 0  , 0  , 0  ), // #415 {R:u16, R:u8}
+    3551             :   ISIGNATURE(3, 1, 1, 0, 166, 73 , 87 , 0  , 0  , 0  ), // #416 {W:r32|m32|mem|r64, R:xmm, R:u8}
+    3552             :   ISIGNATURE(1, 1, 1, 0, 127, 0  , 0  , 0  , 0  , 0  ), // #417 {R:m80|mem}
+    3553             :   ISIGNATURE(1, 1, 1, 0, 209, 0  , 0  , 0  , 0  , 0  ), // #418 {W:m80|mem}
+    3554             :   ISIGNATURE(1, 1, 1, 0, 210, 0  , 0  , 0  , 0  , 0  ), // #419 {R:m16|m32}
+    3555             :   ISIGNATURE(1, 1, 1, 0, 211, 0  , 0  , 0  , 0  , 0  ), // #420 {R:m16|m32|m64}
+    3556             :   ISIGNATURE(1, 1, 1, 0, 212, 0  , 0  , 0  , 0  , 0  ), // #421 {W:m16|m32}
+    3557             :   ISIGNATURE(1, 1, 1, 0, 213, 0  , 0  , 0  , 0  , 0  ), // #422 {W:m16|m32|m64}
+    3558             :   ISIGNATURE(1, 1, 1, 0, 214, 0  , 0  , 0  , 0  , 0  ), // #423 {R:m32|m64|m80|fp}
+    3559             :   ISIGNATURE(1, 1, 1, 0, 63 , 0  , 0  , 0  , 0  , 0  ), // #424 {R:m16|mem}
+    3560             :   ISIGNATURE(1, 1, 1, 0, 215, 0  , 0  , 0  , 0  , 0  ), // #425 {W:mem}
+    3561             :   ISIGNATURE(1, 1, 1, 0, 66 , 0  , 0  , 0  , 0  , 0  ), // #426 {W:m16|mem}
+    3562             :   ISIGNATURE(1, 1, 1, 0, 216, 0  , 0  , 0  , 0  , 0  ), // #427 {W:ax|m16|mem}
+    3563             :   ISIGNATURE(1, 1, 1, 0, 217, 0  , 0  , 0  , 0  , 0  ), // #428 {W:m32|m64|fp}
+    3564             :   ISIGNATURE(1, 1, 1, 0, 218, 0  , 0  , 0  , 0  , 0  ), // #429 {W:m32|m64|m80|fp}
+    3565             :   ISIGNATURE(1, 0, 1, 0, 194, 0  , 0  , 0  , 0  , 0  ), // #430 {R:mem}
+    3566             :   ISIGNATURE(1, 0, 1, 0, 215, 0  , 0  , 0  , 0  , 0  ), // #431 {W:mem}
+    3567             :   ISIGNATURE(2, 1, 1, 0, 219, 220, 0  , 0  , 0  , 0  ), // #432 {W:al|ax|eax, R:u8|dx}
+    3568             :   ISIGNATURE(2, 1, 1, 0, 221, 222, 0  , 0  , 0  , 0  ), // #433 {W:es:[zdi], R:dx}
+    3569             :   ISIGNATURE(1, 1, 1, 0, 87 , 0  , 0  , 0  , 0  , 0  ), // #434 {R:u8}
+    3570             :   ISIGNATURE(0, 1, 0, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #435 {}
+    3571             :   ISIGNATURE(0, 0, 1, 0, 0  , 0  , 0  , 0  , 0  , 0  ), // #436 {}
+    3572             :   ISIGNATURE(1, 1, 1, 0, 223, 0  , 0  , 0  , 0  , 0  ), // #437 {R:rel8|rel32}
+    3573             :   ISIGNATURE(1, 1, 1, 0, 159, 0  , 0  , 0  , 0  , 0  ), // #438 {R:rel8}
+    3574             :   ISIGNATURE(3, 1, 1, 0, 131, 164, 164, 0  , 0  , 0  ), // #439 {W:k, R:k, R:k}
+    3575             :   ISIGNATURE(2, 1, 1, 0, 131, 164, 0  , 0  , 0  , 0  ), // #440 {W:k, R:k}
+    3576             :   ISIGNATURE(2, 1, 1, 0, 164, 164, 0  , 0  , 0  , 0  ), // #441 {R:k, R:k}
+    3577             :   ISIGNATURE(3, 1, 1, 0, 131, 164, 87 , 0  , 0  , 0  ), // #442 {W:k, R:k, R:u8}
+    3578             :   ISIGNATURE(1, 1, 1, 1, 224, 0  , 0  , 0  , 0  , 0  ), // #443 {W:<ah>}
+    3579             :   ISIGNATURE(1, 1, 1, 0, 64 , 0  , 0  , 0  , 0  , 0  ), // #444 {R:m32|mem}
+    3580             :   ISIGNATURE(2, 1, 1, 0, 177, 225, 0  , 0  , 0  , 0  ), // #445 {W:r16|r32|r64, R:mem|m8|m16|m32|m48|m64|m80|m128|m256|m512|m1024}
+    3581             :   ISIGNATURE(1, 1, 1, 0, 226, 0  , 0  , 0  , 0  , 0  ), // #446 {R:r16|m16|mem|r32|r64}
+    3582             :   ISIGNATURE(2, 1, 1, 2, 227, 198, 0  , 0  , 0  , 0  ), // #447 {W:<al|ax|eax|rax>, X:<ds:[zsi]>}
+    3583             :   ISIGNATURE(3, 1, 1, 1, 89 , 73 , 228, 0  , 0  , 0  ), // #448 {X:xmm, R:xmm, R:<ds:[zdi]>}
+    3584             :   ISIGNATURE(3, 1, 1, 1, 181, 72 , 228, 0  , 0  , 0  ), // #449 {X:mm, R:mm, R:<ds:[zdi]>}
+    3585             :   ISIGNATURE(3, 1, 1, 3, 197, 204, 178, 0  , 0  , 0  ), // #450 {R:<ds:[zax]>, R:<ecx>, R:<edx>}
+    3586             :   ISIGNATURE(2, 1, 1, 0, 69 , 73 , 0  , 0  , 0  , 0  ), // #451 {W:mm, R:xmm}
+    3587             :   ISIGNATURE(2, 1, 1, 0, 74 , 73 , 0  , 0  , 0  , 0  ), // #452 {W:xmm, R:xmm}
+    3588             :   ISIGNATURE(2, 1, 1, 0, 173, 73 , 0  , 0  , 0  , 0  ), // #453 {W:r32|r64, R:xmm}
+    3589             :   ISIGNATURE(2, 1, 1, 0, 68 , 72 , 0  , 0  , 0  , 0  ), // #454 {W:m64|mem, R:mm}
+    3590             :   ISIGNATURE(2, 1, 1, 0, 74 , 72 , 0  , 0  , 0  , 0  ), // #455 {W:xmm, R:mm}
+    3591             :   ISIGNATURE(2, 1, 1, 2, 199, 198, 0  , 0  , 0  , 0  ), // #456 {X:<es:[zdi]>, X:<ds:[zsi]>}
+    3592             :   ISIGNATURE(2, 0, 1, 0, 19 , 43 , 0  , 0  , 0  , 0  ), // #457 {W:r64, R:r32|m32|mem}
+    3593             :   ISIGNATURE(2, 1, 1, 2, 103, 204, 0  , 0  , 0  , 0  ), // #458 {R:<eax>, R:<ecx>}
+    3594             :   ISIGNATURE(2, 1, 1, 0, 220, 229, 0  , 0  , 0  , 0  ), // #459 {R:u8|dx, R:al|ax|eax}
+    3595             :   ISIGNATURE(2, 1, 1, 0, 222, 230, 0  , 0  , 0  , 0  ), // #460 {R:dx, R:ds:[zsi]}
+    3596             :   ISIGNATURE(6, 1, 1, 3, 73 , 77 , 87 , 231, 103, 178), // #461 {R:xmm, R:xmm|m128|mem, R:u8, W:<ecx>, R:<eax>, R:<edx>}
+    3597             :   ISIGNATURE(6, 1, 1, 3, 73 , 77 , 87 , 232, 103, 178), // #462 {R:xmm, R:xmm|m128|mem, R:u8, W:<xmm0>, R:<eax>, R:<edx>}
+    3598             :   ISIGNATURE(4, 1, 1, 1, 73 , 77 , 87 , 231, 0  , 0  ), // #463 {R:xmm, R:xmm|m128|mem, R:u8, W:<ecx>}
+    3599             :   ISIGNATURE(4, 1, 1, 1, 73 , 77 , 87 , 232, 0  , 0  ), // #464 {R:xmm, R:xmm|m128|mem, R:u8, W:<xmm0>}
+    3600             :   ISIGNATURE(3, 1, 1, 0, 163, 73 , 87 , 0  , 0  , 0  ), // #465 {W:r32|m8|mem|r8lo|r8hi|r16|r64, R:xmm, R:u8}
+    3601             :   ISIGNATURE(3, 0, 1, 0, 7  , 73 , 87 , 0  , 0  , 0  ), // #466 {W:r64|m64|mem, R:xmm, R:u8}
+    3602             :   ISIGNATURE(3, 1, 1, 0, 89 , 188, 87 , 0  , 0  , 0  ), // #467 {X:xmm, R:r32|m8|mem|r8lo|r8hi|r16|r64, R:u8}
+    3603             :   ISIGNATURE(3, 1, 1, 0, 89 , 175, 87 , 0  , 0  , 0  ), // #468 {X:xmm, R:r32|m32|mem|r64, R:u8}
+    3604             :   ISIGNATURE(3, 0, 1, 0, 89 , 16 , 87 , 0  , 0  , 0  ), // #469 {X:xmm, R:r64|m64|mem, R:u8}
+    3605             :   ISIGNATURE(3, 1, 1, 0, 233, 226, 87 , 0  , 0  , 0  ), // #470 {X:mm|xmm, R:r32|m16|mem|r16|r64, R:u8}
+    3606             :   ISIGNATURE(2, 1, 1, 0, 173, 176, 0  , 0  , 0  , 0  ), // #471 {W:r32|r64, R:mm|xmm}
+    3607             :   ISIGNATURE(3, 1, 1, 0, 69 , 180, 87 , 0  , 0  , 0  ), // #472 {W:mm, R:mm|m64|mem, R:u8}
+    3608             :   ISIGNATURE(2, 1, 1, 0, 89 , 87 , 0  , 0  , 0  , 0  ), // #473 {X:xmm, R:u8}
+    3609             :   ISIGNATURE(2, 1, 1, 0, 49 , 128, 0  , 0  , 0  , 0  ), // #474 {X:r8lo|r8hi|m8|r16|m16|r32|m32|r64|m64|mem, R:cl|u8}
+    3610             :   ISIGNATURE(1, 0, 1, 0, 173, 0  , 0  , 0  , 0  , 0  ), // #475 {W:r32|r64}
+    3611             :   ISIGNATURE(3, 1, 1, 3, 52 , 234, 204, 0  , 0  , 0  ), // #476 {W:<edx>, W:<eax>, R:<ecx>}
+    3612             :   ISIGNATURE(1, 1, 1, 0, 177, 0  , 0  , 0  , 0  , 0  ), // #477 {W:r16|r32|r64}
+    3613             :   ISIGNATURE(2, 1, 1, 2, 52 , 234, 0  , 0  , 0  , 0  ), // #478 {W:<edx>, W:<eax>}
+    3614             :   ISIGNATURE(3, 1, 1, 3, 52 , 234, 231, 0  , 0  , 0  ), // #479 {W:<edx>, W:<eax>, W:<ecx>}
+    3615             :   ISIGNATURE(3, 1, 1, 0, 74 , 75 , 87 , 0  , 0  , 0  ), // #480 {W:xmm, R:xmm|m64|mem, R:u8}
+    3616             :   ISIGNATURE(3, 1, 1, 0, 74 , 140, 87 , 0  , 0  , 0  ), // #481 {W:xmm, R:xmm|m32|mem, R:u8}
+    3617             :   ISIGNATURE(1, 1, 1, 1, 235, 0  , 0  , 0  , 0  , 0  ), // #482 {R:<ah>}
+    3618             :   ISIGNATURE(2, 1, 1, 2, 236, 199, 0  , 0  , 0  , 0  ), // #483 {R:<al|ax|eax|rax>, X:<es:[zdi]>}
+    3619             :   ISIGNATURE(1, 1, 1, 0, 1  , 0  , 0  , 0  , 0  , 0  ), // #484 {W:r8lo|r8hi|m8|mem}
+    3620             :   ISIGNATURE(1, 1, 1, 0, 169, 0  , 0  , 0  , 0  , 0  ), // #485 {W:r16|m16|mem|r32|r64}
+    3621             :   ISIGNATURE(1, 1, 1, 0, 67 , 0  , 0  , 0  , 0  , 0  ), // #486 {W:m32|mem}
+    3622             :   ISIGNATURE(2, 1, 1, 2, 199, 236, 0  , 0  , 0  , 0  ), // #487 {X:<es:[zdi]>, R:<al|ax|eax|rax>}
+    3623             :   ISIGNATURE(6, 1, 1, 0, 93 , 86 , 86 , 86 , 86 , 117), // #488 {X:zmm, R:zmm, R:zmm, R:zmm, R:zmm, R:m128|mem}
+    3624             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 75 , 0  , 0  , 0  ), // #489 {W:xmm, R:xmm, R:xmm|m64|mem}
+    3625             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 140, 0  , 0  , 0  ), // #490 {W:xmm, R:xmm, R:xmm|m32|mem}
+    3626             :   ISIGNATURE(2, 1, 1, 0, 79 , 117, 0  , 0  , 0  , 0  ), // #491 {W:ymm, R:m128|mem}
+    3627             :   ISIGNATURE(2, 1, 1, 0, 237, 75 , 0  , 0  , 0  , 0  ), // #492 {W:ymm|zmm, R:xmm|m64|mem}
+    3628             :   ISIGNATURE(2, 1, 1, 0, 237, 117, 0  , 0  , 0  , 0  ), // #493 {W:ymm|zmm, R:m128|mem}
+    3629             :   ISIGNATURE(2, 1, 1, 0, 83 , 118, 0  , 0  , 0  , 0  ), // #494 {W:zmm, R:m256|mem}
+    3630             :   ISIGNATURE(2, 1, 1, 0, 185, 75 , 0  , 0  , 0  , 0  ), // #495 {W:xmm|ymm|zmm, R:xmm|m64|mem}
+    3631             :   ISIGNATURE(4, 1, 1, 0, 129, 73 , 75 , 87 , 0  , 0  ), // #496 {W:xmm|k, R:xmm, R:xmm|m64|mem, R:u8}
+    3632             :   ISIGNATURE(4, 1, 1, 0, 129, 73 , 140, 87 , 0  , 0  ), // #497 {W:xmm|k, R:xmm, R:xmm|m32|mem, R:u8}
+    3633             :   ISIGNATURE(3, 1, 1, 0, 74 , 73 , 208, 0  , 0  , 0  ), // #498 {W:xmm, R:xmm, R:r32|m32|mem|r64|m64}
+    3634             :   ISIGNATURE(3, 1, 1, 0, 78 , 238, 87 , 0  , 0  , 0  ), // #499 {W:xmm|m128|mem, R:ymm|zmm, R:u8}
+    3635             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 75 , 87 , 0  , 0  ), // #500 {X:xmm, R:xmm, R:xmm|m64|mem, R:u8}
+    3636             :   ISIGNATURE(4, 1, 1, 0, 89 , 73 , 140, 87 , 0  , 0  ), // #501 {X:xmm, R:xmm, R:xmm|m32|mem, R:u8}
+    3637             :   ISIGNATURE(3, 1, 1, 0, 89 , 73 , 75 , 0  , 0  , 0  ), // #502 {X:xmm, R:xmm, R:xmm|m64|mem}
+    3638             :   ISIGNATURE(3, 1, 1, 0, 89 , 73 , 140, 0  , 0  , 0  ), // #503 {X:xmm, R:xmm, R:xmm|m32|mem}
+    3639             :   ISIGNATURE(3, 1, 1, 0, 131, 239, 87 , 0  , 0  , 0  ), // #504 {W:k, R:xmm|m128|ymm|m256|zmm|m512, R:u8}
+    3640             :   ISIGNATURE(3, 1, 1, 0, 131, 75 , 87 , 0  , 0  , 0  ), // #505 {W:k, R:xmm|m64|mem, R:u8}
+    3641             :   ISIGNATURE(3, 1, 1, 0, 131, 140, 87 , 0  , 0  , 0  ), // #506 {W:k, R:xmm|m32|mem, R:u8}
+    3642             :   ISIGNATURE(1, 1, 1, 0, 92 , 0  , 0  , 0  , 0  , 0  ), // #507 {R:vm32y}
+    3643             :   ISIGNATURE(1, 1, 1, 0, 94 , 0  , 0  , 0  , 0  , 0  ), // #508 {R:vm32z}
+    3644             :   ISIGNATURE(1, 1, 1, 0, 97 , 0  , 0  , 0  , 0  , 0  ), // #509 {R:vm64z}
+    3645             :   ISIGNATURE(4, 1, 1, 0, 83 , 86 , 80 , 87 , 0  , 0  ), // #510 {W:zmm, R:zmm, R:ymm|m256|mem, R:u8}
+    3646             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 140, 87 , 0  , 0  ), // #511 {W:xmm, R:xmm, R:xmm|m32|mem, R:u8}
+    3647             :   ISIGNATURE(3, 1, 1, 1, 73 , 73 , 228, 0  , 0  , 0  ), // #512 {R:xmm, R:xmm, R:<ds:[zdi]>}
+    3648             :   ISIGNATURE(2, 1, 1, 0, 173, 191, 0  , 0  , 0  , 0  ), // #513 {W:r32|r64, R:xmm|ymm}
+    3649             :   ISIGNATURE(6, 1, 1, 0, 83 , 86 , 86 , 86 , 86 , 117), // #514 {W:zmm, R:zmm, R:zmm, R:zmm, R:zmm, R:m128|mem}
+    3650             :   ISIGNATURE(2, 1, 1, 0, 185, 164, 0  , 0  , 0  , 0  ), // #515 {W:xmm|ymm|zmm, R:k}
+    3651             :   ISIGNATURE(2, 1, 1, 0, 185, 137, 0  , 0  , 0  , 0  ), // #516 {W:xmm|ymm|zmm, R:xmm|m64|mem|r64}
+    3652             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 226, 87 , 0  , 0  ), // #517 {W:xmm, R:xmm, R:r32|m16|mem|r16|r64, R:u8}
+    3653             :   ISIGNATURE(2, 1, 1, 0, 131, 240, 0  , 0  , 0  , 0  ), // #518 {W:k, R:xmm|ymm|zmm}
+    3654             :   ISIGNATURE(4, 1, 1, 0, 74 , 73 , 75 , 87 , 0  , 0  ), // #519 {W:xmm, R:xmm, R:xmm|m64|mem, R:u8}
+    3655             :   ISIGNATURE(1, 0, 1, 0, 187, 0  , 0  , 0  , 0  , 0  ), // #520 {R:r32|r64}
+    3656             :   ISIGNATURE(3, 1, 1, 3, 178, 103, 204, 0  , 0  , 0  ), // #521 {R:<edx>, R:<eax>, R:<ecx>}
+    3657             :   ISIGNATURE(1, 1, 1, 0, 241, 0  , 0  , 0  , 0  , 0  ), // #522 {R:rel16|rel32}
+    3658             :   ISIGNATURE(3, 1, 1, 2, 194, 178, 103, 0  , 0  , 0  ), // #523 {R:mem, R:<edx>, R:<eax>}
+    3659             :   ISIGNATURE(3, 0, 1, 2, 194, 178, 103, 0  , 0  , 0  ), // #524 {R:mem, R:<edx>, R:<eax>}
+    3660             :   ISIGNATURE(3, 1, 1, 2, 215, 178, 103, 0  , 0  , 0  ), // #525 {W:mem, R:<edx>, R:<eax>}
+    3661             :   ISIGNATURE(3, 0, 1, 2, 215, 178, 103, 0  , 0  , 0  )  // #526 {W:mem, R:<edx>, R:<eax>}
+    3662             : };
+    3663             : #undef ISIGNATURE
+    3664             : // ----------------------------------------------------------------------------
+    3665             : // ${signatureData:End}
+    3666             : #endif // !ASMJIT_DISABLE_VALIDATION
+    3667             : 
+    3668             : // ============================================================================
+    3669             : // [asmjit::X86Inst - MiscData]
+    3670             : // ============================================================================
+    3671             : 
+    3672             : #define CC_TO_INST(inst) {               \
+    3673             :   inst##o, inst##no, inst##b , inst##ae, \
+    3674             :   inst##e, inst##ne, inst##be, inst##a , \
+    3675             :   inst##s, inst##ns, inst##pe, inst##po, \
+    3676             :   inst##l, inst##ge, inst##le, inst##g   \
+    3677             : }
+    3678             : 
+    3679             : const X86Inst::MiscData X86InstDB::miscData = {
+    3680             :   CC_TO_INST(X86Inst::kIdJ),
+    3681             :   CC_TO_INST(X86Inst::kIdSet),
+    3682             :   CC_TO_INST(X86Inst::kIdCmov),
+    3683             : 
+    3684             :   // ReversedCond[]:
+    3685             :   {
+    3686             :     x86::kCondO, x86::kCondNO, x86::kCondA , x86::kCondBE, // O|NO|B |AE
+    3687             :     x86::kCondE, x86::kCondNE, x86::kCondAE, x86::kCondB , // E|NE|BE|A
+    3688             :     x86::kCondS, x86::kCondNS, x86::kCondPE, x86::kCondPO, // S|NS|PE|PO
+    3689             :     x86::kCondG, x86::kCondLE, x86::kCondGE, x86::kCondL   // L|GE|LE|G
+    3690             :   }
+    3691             : };
+    3692             : 
+    3693             : #undef CC_TO_INST
+    3694             : 
+    3695             : // ============================================================================
+    3696             : // [asmjit::X86Inst - Test]
+    3697             : // ============================================================================
+    3698             : 
+    3699             : #if defined(ASMJIT_TEST)
+    3700             : UNIT(x86_inst_bits) {
+    3701             :   INFO("Checking validity of X86Inst enums");
+    3702             : 
+    3703             :   // Cross-validate prefixes.
+    3704             :   EXPECT(X86Inst::kOptionRex  == 0x80000000U, "REX prefix must be at 0x80000000");
+    3705             :   EXPECT(X86Inst::kOptionVex3 == 0x00000400U, "VEX3 prefix must be at 0x00000400");
+    3706             :   EXPECT(X86Inst::kOptionEvex == 0x00001000U, "EVEX prefix must be at 0x00001000");
+    3707             : 
+    3708             :   // These could be combined together to form a valid REX prefix, they must match.
+    3709             :   EXPECT(int(X86Inst::kOptionOpCodeB) == int(X86Inst::kOpCode_B));
+    3710             :   EXPECT(int(X86Inst::kOptionOpCodeX) == int(X86Inst::kOpCode_X));
+    3711             :   EXPECT(int(X86Inst::kOptionOpCodeR) == int(X86Inst::kOpCode_R));
+    3712             :   EXPECT(int(X86Inst::kOptionOpCodeW) == int(X86Inst::kOpCode_W));
+    3713             : 
+    3714             :   uint32_t rex_rb = (X86Inst::kOpCode_R >> X86Inst::kOpCode_REX_Shift) |
+    3715             :                     (X86Inst::kOpCode_B >> X86Inst::kOpCode_REX_Shift) | 0x40;
+    3716             :   uint32_t rex_rw = (X86Inst::kOpCode_R >> X86Inst::kOpCode_REX_Shift) |
+    3717             :                     (X86Inst::kOpCode_W >> X86Inst::kOpCode_REX_Shift) | 0x40;
+    3718             :   EXPECT(rex_rb == 0x45, "kOpCode_R|B must form a valid REX prefix 0x45 if combined with 0x40");
+    3719             :   EXPECT(rex_rw == 0x4C, "kOpCode_R|W must form a valid REX prefix 0x4C if combined with 0x40");
+    3720             : }
+    3721             : #endif // ASMJIT_TEST
+    3722             : 
+    3723             : #if defined(ASMJIT_TEST) && !defined(ASMJIT_DISABLE_TEXT)
+    3724             : UNIT(x86_inst_names) {
+    3725             :   // All known instructions should be matched.
+    3726             :   INFO("Matching all X86/X64 instructions");
+    3727             :   for (uint32_t a = 0; a < X86Inst::_kIdCount; a++) {
+    3728             :     uint32_t b = X86Inst::getIdByName(X86Inst::getInst(a).getName());
+    3729             :     EXPECT(a == b,
+    3730             :       "Should match existing instruction \"%s\" {id:%u} != \"%s\" {id:%u}",
+    3731             :         X86Inst::getInst(a).getName(), a,
+    3732             :         X86Inst::getInst(b).getName(), b);
+    3733             :   }
+    3734             : 
+    3735             :   // Everything else should return `Inst::kIdNone`.
+    3736             :   INFO("Trying to look-up instructions that don't exist");
+    3737             :   EXPECT(X86Inst::getIdByName(nullptr)  == Inst::kIdNone, "Should return Inst::kIdNone for null input");
+    3738             :   EXPECT(X86Inst::getIdByName("")       == Inst::kIdNone, "Should return Inst::kIdNone for empty string");
+    3739             :   EXPECT(X86Inst::getIdByName("_")      == Inst::kIdNone, "Should return Inst::kIdNone for unknown instruction");
+    3740             :   EXPECT(X86Inst::getIdByName("123xyz") == Inst::kIdNone, "Should return Inst::kIdNone for unknown instruction");
+    3741             : }
+    3742             : #endif // ASMJIT_TEST && !ASMJIT_DISABLE_TEXT
+    3743             : 
+    3744             : } // asmjit namespace
+    3745             : } // namespace PLMD
+    3746             : 
+    3747             : // [Api-End]
+    3748             : #include "./asmjit_apiend.h"
+    3749             : 
+    3750             : // [Guard]
+    3751             : #endif // ASMJIT_BUILD_X86
+    3752             : #pragma GCC diagnostic pop
+    3753             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.h.func-sort-c.html b/coverage-libs/asmjit/x86inst.h.func-sort-c.html new file mode 100644 index 000000000000..4b66b1bc6411 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:101566.7 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.h.func.html b/coverage-libs/asmjit/x86inst.h.func.html new file mode 100644 index 000000000000..3f40065f858a --- /dev/null +++ b/coverage-libs/asmjit/x86inst.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:101566.7 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86inst.h.gcov.html b/coverage-libs/asmjit/x86inst.h.gcov.html new file mode 100644 index 000000000000..f7bd9b6846d3 --- /dev/null +++ b/coverage-libs/asmjit/x86inst.h.gcov.html @@ -0,0 +1,2624 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86inst.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86inst.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:101566.7 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_x86inst_h
+      21             : #define __PLUMED_asmjit_x86inst_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_X86_X86INST_H
+      33             : #define _ASMJIT_X86_X86INST_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./assembler.h" // TODO: Is that necessary?
+      37             : #include "./inst.h"
+      38             : #include "./operand.h"
+      39             : #include "./utils.h"
+      40             : #include "./x86globals.h"
+      41             : 
+      42             : // [Api-Begin]
+      43             : #include "./asmjit_apibegin.h"
+      44             : 
+      45             : namespace PLMD {
+      46             : namespace asmjit {
+      47             : 
+      48             : //! \addtogroup asmjit_x86
+      49             : //! \{
+      50             : 
+      51             : // ============================================================================
+      52             : // [asmjit::X86Inst]
+      53             : // ============================================================================
+      54             : 
+      55             : //! X86/X64 instruction data.
+      56             : struct X86Inst {
+      57             :   //! Instruction id (AsmJit specific).
+      58             :   //!
+      59             :   //! Each instruction has a unique ID that is used as an index to AsmJit's
+      60             :   //! instruction table. Instructions are sorted alphabetically.
+      61             :   ASMJIT_ENUM(Id) {
+      62             :     // ${idData:Begin}
+      63             :     kIdNone = 0,
+      64             :     kIdAaa,                              // [X86]
+      65             :     kIdAad,                              // [X86]
+      66             :     kIdAam,                              // [X86]
+      67             :     kIdAas,                              // [X86]
+      68             :     kIdAdc,                              // [ANY]
+      69             :     kIdAdcx,                             // [ANY] {ADX}
+      70             :     kIdAdd,                              // [ANY]
+      71             :     kIdAddpd,                            // [ANY] {SSE2}
+      72             :     kIdAddps,                            // [ANY] {SSE}
+      73             :     kIdAddsd,                            // [ANY] {SSE2}
+      74             :     kIdAddss,                            // [ANY] {SSE}
+      75             :     kIdAddsubpd,                         // [ANY] {SSE3}
+      76             :     kIdAddsubps,                         // [ANY] {SSE3}
+      77             :     kIdAdox,                             // [ANY] {ADX}
+      78             :     kIdAesdec,                           // [ANY] {AESNI}
+      79             :     kIdAesdeclast,                       // [ANY] {AESNI}
+      80             :     kIdAesenc,                           // [ANY] {AESNI}
+      81             :     kIdAesenclast,                       // [ANY] {AESNI}
+      82             :     kIdAesimc,                           // [ANY] {AESNI}
+      83             :     kIdAeskeygenassist,                  // [ANY] {AESNI}
+      84             :     kIdAnd,                              // [ANY]
+      85             :     kIdAndn,                             // [ANY] {BMI}
+      86             :     kIdAndnpd,                           // [ANY] {SSE2}
+      87             :     kIdAndnps,                           // [ANY] {SSE}
+      88             :     kIdAndpd,                            // [ANY] {SSE2}
+      89             :     kIdAndps,                            // [ANY] {SSE}
+      90             :     kIdArpl,                             // [X86]
+      91             :     kIdBextr,                            // [ANY] {BMI}
+      92             :     kIdBlcfill,                          // [ANY] {TBM}
+      93             :     kIdBlci,                             // [ANY] {TBM}
+      94             :     kIdBlcic,                            // [ANY] {TBM}
+      95             :     kIdBlcmsk,                           // [ANY] {TBM}
+      96             :     kIdBlcs,                             // [ANY] {TBM}
+      97             :     kIdBlendpd,                          // [ANY] {SSE4_1}
+      98             :     kIdBlendps,                          // [ANY] {SSE4_1}
+      99             :     kIdBlendvpd,                         // [ANY] {SSE4_1}
+     100             :     kIdBlendvps,                         // [ANY] {SSE4_1}
+     101             :     kIdBlsfill,                          // [ANY] {TBM}
+     102             :     kIdBlsi,                             // [ANY] {BMI}
+     103             :     kIdBlsic,                            // [ANY] {TBM}
+     104             :     kIdBlsmsk,                           // [ANY] {BMI}
+     105             :     kIdBlsr,                             // [ANY] {BMI}
+     106             :     kIdBndcl,                            // [ANY] {MPX}
+     107             :     kIdBndcn,                            // [ANY] {MPX}
+     108             :     kIdBndcu,                            // [ANY] {MPX}
+     109             :     kIdBndldx,                           // [ANY] {MPX}
+     110             :     kIdBndmk,                            // [ANY] {MPX}
+     111             :     kIdBndmov,                           // [ANY] {MPX}
+     112             :     kIdBndstx,                           // [ANY] {MPX}
+     113             :     kIdBound,                            // [X86]
+     114             :     kIdBsf,                              // [ANY]
+     115             :     kIdBsr,                              // [ANY]
+     116             :     kIdBswap,                            // [ANY]
+     117             :     kIdBt,                               // [ANY]
+     118             :     kIdBtc,                              // [ANY]
+     119             :     kIdBtr,                              // [ANY]
+     120             :     kIdBts,                              // [ANY]
+     121             :     kIdBzhi,                             // [ANY] {BMI2}
+     122             :     kIdCall,                             // [ANY]
+     123             :     kIdCbw,                              // [ANY]
+     124             :     kIdCdq,                              // [ANY]
+     125             :     kIdCdqe,                             // [X64]
+     126             :     kIdClac,                             // [ANY] {SMAP}
+     127             :     kIdClc,                              // [ANY]
+     128             :     kIdCld,                              // [ANY]
+     129             :     kIdClflush,                          // [ANY] {CLFLUSH}
+     130             :     kIdClflushopt,                       // [ANY] {CLFLUSHOPT}
+     131             :     kIdCli,                              // [ANY]
+     132             :     kIdClts,                             // [ANY]
+     133             :     kIdClwb,                             // [ANY] {CLWB}
+     134             :     kIdClzero,                           // [ANY] {CLZERO}
+     135             :     kIdCmc,                              // [ANY]
+     136             :     kIdCmova,                            // [ANY] {CMOV}
+     137             :     kIdCmovae,                           // [ANY] {CMOV}
+     138             :     kIdCmovb,                            // [ANY] {CMOV}
+     139             :     kIdCmovbe,                           // [ANY] {CMOV}
+     140             :     kIdCmovc,                            // [ANY] {CMOV}
+     141             :     kIdCmove,                            // [ANY] {CMOV}
+     142             :     kIdCmovg,                            // [ANY] {CMOV}
+     143             :     kIdCmovge,                           // [ANY] {CMOV}
+     144             :     kIdCmovl,                            // [ANY] {CMOV}
+     145             :     kIdCmovle,                           // [ANY] {CMOV}
+     146             :     kIdCmovna,                           // [ANY] {CMOV}
+     147             :     kIdCmovnae,                          // [ANY] {CMOV}
+     148             :     kIdCmovnb,                           // [ANY] {CMOV}
+     149             :     kIdCmovnbe,                          // [ANY] {CMOV}
+     150             :     kIdCmovnc,                           // [ANY] {CMOV}
+     151             :     kIdCmovne,                           // [ANY] {CMOV}
+     152             :     kIdCmovng,                           // [ANY] {CMOV}
+     153             :     kIdCmovnge,                          // [ANY] {CMOV}
+     154             :     kIdCmovnl,                           // [ANY] {CMOV}
+     155             :     kIdCmovnle,                          // [ANY] {CMOV}
+     156             :     kIdCmovno,                           // [ANY] {CMOV}
+     157             :     kIdCmovnp,                           // [ANY] {CMOV}
+     158             :     kIdCmovns,                           // [ANY] {CMOV}
+     159             :     kIdCmovnz,                           // [ANY] {CMOV}
+     160             :     kIdCmovo,                            // [ANY] {CMOV}
+     161             :     kIdCmovp,                            // [ANY] {CMOV}
+     162             :     kIdCmovpe,                           // [ANY] {CMOV}
+     163             :     kIdCmovpo,                           // [ANY] {CMOV}
+     164             :     kIdCmovs,                            // [ANY] {CMOV}
+     165             :     kIdCmovz,                            // [ANY] {CMOV}
+     166             :     kIdCmp,                              // [ANY]
+     167             :     kIdCmppd,                            // [ANY] {SSE2}
+     168             :     kIdCmpps,                            // [ANY] {SSE}
+     169             :     kIdCmps,                             // [ANY]
+     170             :     kIdCmpsd,                            // [ANY] {SSE2}
+     171             :     kIdCmpss,                            // [ANY] {SSE}
+     172             :     kIdCmpxchg,                          // [ANY] {I486}
+     173             :     kIdCmpxchg16b,                       // [X64] {CMPXCHG16B}
+     174             :     kIdCmpxchg8b,                        // [ANY] {CMPXCHG8B}
+     175             :     kIdComisd,                           // [ANY] {SSE2}
+     176             :     kIdComiss,                           // [ANY] {SSE}
+     177             :     kIdCpuid,                            // [ANY] {I486}
+     178             :     kIdCqo,                              // [X64]
+     179             :     kIdCrc32,                            // [ANY] {SSE4_2}
+     180             :     kIdCvtdq2pd,                         // [ANY] {SSE2}
+     181             :     kIdCvtdq2ps,                         // [ANY] {SSE2}
+     182             :     kIdCvtpd2dq,                         // [ANY] {SSE2}
+     183             :     kIdCvtpd2pi,                         // [ANY] {SSE2}
+     184             :     kIdCvtpd2ps,                         // [ANY] {SSE2}
+     185             :     kIdCvtpi2pd,                         // [ANY] {SSE2}
+     186             :     kIdCvtpi2ps,                         // [ANY] {SSE}
+     187             :     kIdCvtps2dq,                         // [ANY] {SSE2}
+     188             :     kIdCvtps2pd,                         // [ANY] {SSE2}
+     189             :     kIdCvtps2pi,                         // [ANY] {SSE}
+     190             :     kIdCvtsd2si,                         // [ANY] {SSE2}
+     191             :     kIdCvtsd2ss,                         // [ANY] {SSE2}
+     192             :     kIdCvtsi2sd,                         // [ANY] {SSE2}
+     193             :     kIdCvtsi2ss,                         // [ANY] {SSE}
+     194             :     kIdCvtss2sd,                         // [ANY] {SSE2}
+     195             :     kIdCvtss2si,                         // [ANY] {SSE}
+     196             :     kIdCvttpd2dq,                        // [ANY] {SSE2}
+     197             :     kIdCvttpd2pi,                        // [ANY] {SSE2}
+     198             :     kIdCvttps2dq,                        // [ANY] {SSE2}
+     199             :     kIdCvttps2pi,                        // [ANY] {SSE}
+     200             :     kIdCvttsd2si,                        // [ANY] {SSE2}
+     201             :     kIdCvttss2si,                        // [ANY] {SSE}
+     202             :     kIdCwd,                              // [ANY]
+     203             :     kIdCwde,                             // [ANY]
+     204             :     kIdDaa,                              // [X86]
+     205             :     kIdDas,                              // [X86]
+     206             :     kIdDec,                              // [ANY]
+     207             :     kIdDiv,                              // [ANY]
+     208             :     kIdDivpd,                            // [ANY] {SSE2}
+     209             :     kIdDivps,                            // [ANY] {SSE}
+     210             :     kIdDivsd,                            // [ANY] {SSE2}
+     211             :     kIdDivss,                            // [ANY] {SSE}
+     212             :     kIdDppd,                             // [ANY] {SSE4_1}
+     213             :     kIdDpps,                             // [ANY] {SSE4_1}
+     214             :     kIdEmms,                             // [ANY] {MMX}
+     215             :     kIdEnter,                            // [ANY]
+     216             :     kIdExtractps,                        // [ANY] {SSE4_1}
+     217             :     kIdExtrq,                            // [ANY] {SSE4A}
+     218             :     kIdF2xm1,                            // [ANY]
+     219             :     kIdFabs,                             // [ANY]
+     220             :     kIdFadd,                             // [ANY]
+     221             :     kIdFaddp,                            // [ANY]
+     222             :     kIdFbld,                             // [ANY]
+     223             :     kIdFbstp,                            // [ANY]
+     224             :     kIdFchs,                             // [ANY]
+     225             :     kIdFclex,                            // [ANY]
+     226             :     kIdFcmovb,                           // [ANY] {CMOV}
+     227             :     kIdFcmovbe,                          // [ANY] {CMOV}
+     228             :     kIdFcmove,                           // [ANY] {CMOV}
+     229             :     kIdFcmovnb,                          // [ANY] {CMOV}
+     230             :     kIdFcmovnbe,                         // [ANY] {CMOV}
+     231             :     kIdFcmovne,                          // [ANY] {CMOV}
+     232             :     kIdFcmovnu,                          // [ANY] {CMOV}
+     233             :     kIdFcmovu,                           // [ANY] {CMOV}
+     234             :     kIdFcom,                             // [ANY]
+     235             :     kIdFcomi,                            // [ANY]
+     236             :     kIdFcomip,                           // [ANY]
+     237             :     kIdFcomp,                            // [ANY]
+     238             :     kIdFcompp,                           // [ANY]
+     239             :     kIdFcos,                             // [ANY]
+     240             :     kIdFdecstp,                          // [ANY]
+     241             :     kIdFdiv,                             // [ANY]
+     242             :     kIdFdivp,                            // [ANY]
+     243             :     kIdFdivr,                            // [ANY]
+     244             :     kIdFdivrp,                           // [ANY]
+     245             :     kIdFemms,                            // [ANY] {3DNOW}
+     246             :     kIdFfree,                            // [ANY]
+     247             :     kIdFiadd,                            // [ANY]
+     248             :     kIdFicom,                            // [ANY]
+     249             :     kIdFicomp,                           // [ANY]
+     250             :     kIdFidiv,                            // [ANY]
+     251             :     kIdFidivr,                           // [ANY]
+     252             :     kIdFild,                             // [ANY]
+     253             :     kIdFimul,                            // [ANY]
+     254             :     kIdFincstp,                          // [ANY]
+     255             :     kIdFinit,                            // [ANY]
+     256             :     kIdFist,                             // [ANY]
+     257             :     kIdFistp,                            // [ANY]
+     258             :     kIdFisttp,                           // [ANY] {SSE3}
+     259             :     kIdFisub,                            // [ANY]
+     260             :     kIdFisubr,                           // [ANY]
+     261             :     kIdFld,                              // [ANY]
+     262             :     kIdFld1,                             // [ANY]
+     263             :     kIdFldcw,                            // [ANY]
+     264             :     kIdFldenv,                           // [ANY]
+     265             :     kIdFldl2e,                           // [ANY]
+     266             :     kIdFldl2t,                           // [ANY]
+     267             :     kIdFldlg2,                           // [ANY]
+     268             :     kIdFldln2,                           // [ANY]
+     269             :     kIdFldpi,                            // [ANY]
+     270             :     kIdFldz,                             // [ANY]
+     271             :     kIdFmul,                             // [ANY]
+     272             :     kIdFmulp,                            // [ANY]
+     273             :     kIdFnclex,                           // [ANY]
+     274             :     kIdFninit,                           // [ANY]
+     275             :     kIdFnop,                             // [ANY]
+     276             :     kIdFnsave,                           // [ANY]
+     277             :     kIdFnstcw,                           // [ANY]
+     278             :     kIdFnstenv,                          // [ANY]
+     279             :     kIdFnstsw,                           // [ANY]
+     280             :     kIdFpatan,                           // [ANY]
+     281             :     kIdFprem,                            // [ANY]
+     282             :     kIdFprem1,                           // [ANY]
+     283             :     kIdFptan,                            // [ANY]
+     284             :     kIdFrndint,                          // [ANY]
+     285             :     kIdFrstor,                           // [ANY]
+     286             :     kIdFsave,                            // [ANY]
+     287             :     kIdFscale,                           // [ANY]
+     288             :     kIdFsin,                             // [ANY]
+     289             :     kIdFsincos,                          // [ANY]
+     290             :     kIdFsqrt,                            // [ANY]
+     291             :     kIdFst,                              // [ANY]
+     292             :     kIdFstcw,                            // [ANY]
+     293             :     kIdFstenv,                           // [ANY]
+     294             :     kIdFstp,                             // [ANY]
+     295             :     kIdFstsw,                            // [ANY]
+     296             :     kIdFsub,                             // [ANY]
+     297             :     kIdFsubp,                            // [ANY]
+     298             :     kIdFsubr,                            // [ANY]
+     299             :     kIdFsubrp,                           // [ANY]
+     300             :     kIdFtst,                             // [ANY]
+     301             :     kIdFucom,                            // [ANY]
+     302             :     kIdFucomi,                           // [ANY]
+     303             :     kIdFucomip,                          // [ANY]
+     304             :     kIdFucomp,                           // [ANY]
+     305             :     kIdFucompp,                          // [ANY]
+     306             :     kIdFwait,                            // [ANY]
+     307             :     kIdFxam,                             // [ANY]
+     308             :     kIdFxch,                             // [ANY]
+     309             :     kIdFxrstor,                          // [ANY] {FXSR}
+     310             :     kIdFxrstor64,                        // [X64] {FXSR}
+     311             :     kIdFxsave,                           // [ANY] {FXSR}
+     312             :     kIdFxsave64,                         // [X64] {FXSR}
+     313             :     kIdFxtract,                          // [ANY]
+     314             :     kIdFyl2x,                            // [ANY]
+     315             :     kIdFyl2xp1,                          // [ANY]
+     316             :     kIdHaddpd,                           // [ANY] {SSE3}
+     317             :     kIdHaddps,                           // [ANY] {SSE3}
+     318             :     kIdHlt,                              // [ANY]
+     319             :     kIdHsubpd,                           // [ANY] {SSE3}
+     320             :     kIdHsubps,                           // [ANY] {SSE3}
+     321             :     kIdIdiv,                             // [ANY]
+     322             :     kIdImul,                             // [ANY]
+     323             :     kIdIn,                               // [ANY]
+     324             :     kIdInc,                              // [ANY]
+     325             :     kIdIns,                              // [ANY]
+     326             :     kIdInsertps,                         // [ANY] {SSE4_1}
+     327             :     kIdInsertq,                          // [ANY] {SSE4A}
+     328             :     kIdInt,                              // [ANY]
+     329             :     kIdInt3,                             // [ANY]
+     330             :     kIdInto,                             // [X86]
+     331             :     kIdInvd,                             // [ANY] {I486}
+     332             :     kIdInvlpg,                           // [ANY] {I486}
+     333             :     kIdInvpcid,                          // [ANY] {I486}
+     334             :     kIdIret,                             // [ANY]
+     335             :     kIdIretd,                            // [ANY]
+     336             :     kIdIretq,                            // [X64]
+     337             :     kIdIretw,                            // [ANY]
+     338             :     kIdJa,                               // [ANY]
+     339             :     kIdJae,                              // [ANY]
+     340             :     kIdJb,                               // [ANY]
+     341             :     kIdJbe,                              // [ANY]
+     342             :     kIdJc,                               // [ANY]
+     343             :     kIdJe,                               // [ANY]
+     344             :     kIdJecxz,                            // [ANY]
+     345             :     kIdJg,                               // [ANY]
+     346             :     kIdJge,                              // [ANY]
+     347             :     kIdJl,                               // [ANY]
+     348             :     kIdJle,                              // [ANY]
+     349             :     kIdJmp,                              // [ANY]
+     350             :     kIdJna,                              // [ANY]
+     351             :     kIdJnae,                             // [ANY]
+     352             :     kIdJnb,                              // [ANY]
+     353             :     kIdJnbe,                             // [ANY]
+     354             :     kIdJnc,                              // [ANY]
+     355             :     kIdJne,                              // [ANY]
+     356             :     kIdJng,                              // [ANY]
+     357             :     kIdJnge,                             // [ANY]
+     358             :     kIdJnl,                              // [ANY]
+     359             :     kIdJnle,                             // [ANY]
+     360             :     kIdJno,                              // [ANY]
+     361             :     kIdJnp,                              // [ANY]
+     362             :     kIdJns,                              // [ANY]
+     363             :     kIdJnz,                              // [ANY]
+     364             :     kIdJo,                               // [ANY]
+     365             :     kIdJp,                               // [ANY]
+     366             :     kIdJpe,                              // [ANY]
+     367             :     kIdJpo,                              // [ANY]
+     368             :     kIdJs,                               // [ANY]
+     369             :     kIdJz,                               // [ANY]
+     370             :     kIdKaddb,                            // [ANY] {AVX512_DQ}
+     371             :     kIdKaddd,                            // [ANY] {AVX512_BW}
+     372             :     kIdKaddq,                            // [ANY] {AVX512_BW}
+     373             :     kIdKaddw,                            // [ANY] {AVX512_DQ}
+     374             :     kIdKandb,                            // [ANY] {AVX512_DQ}
+     375             :     kIdKandd,                            // [ANY] {AVX512_BW}
+     376             :     kIdKandnb,                           // [ANY] {AVX512_DQ}
+     377             :     kIdKandnd,                           // [ANY] {AVX512_BW}
+     378             :     kIdKandnq,                           // [ANY] {AVX512_BW}
+     379             :     kIdKandnw,                           // [ANY] {AVX512_F}
+     380             :     kIdKandq,                            // [ANY] {AVX512_BW}
+     381             :     kIdKandw,                            // [ANY] {AVX512_F}
+     382             :     kIdKmovb,                            // [ANY] {AVX512_DQ}
+     383             :     kIdKmovd,                            // [ANY] {AVX512_BW}
+     384             :     kIdKmovq,                            // [ANY] {AVX512_BW}
+     385             :     kIdKmovw,                            // [ANY] {AVX512_F}
+     386             :     kIdKnotb,                            // [ANY] {AVX512_DQ}
+     387             :     kIdKnotd,                            // [ANY] {AVX512_BW}
+     388             :     kIdKnotq,                            // [ANY] {AVX512_BW}
+     389             :     kIdKnotw,                            // [ANY] {AVX512_F}
+     390             :     kIdKorb,                             // [ANY] {AVX512_DQ}
+     391             :     kIdKord,                             // [ANY] {AVX512_BW}
+     392             :     kIdKorq,                             // [ANY] {AVX512_BW}
+     393             :     kIdKortestb,                         // [ANY] {AVX512_DQ}
+     394             :     kIdKortestd,                         // [ANY] {AVX512_BW}
+     395             :     kIdKortestq,                         // [ANY] {AVX512_BW}
+     396             :     kIdKortestw,                         // [ANY] {AVX512_F}
+     397             :     kIdKorw,                             // [ANY] {AVX512_F}
+     398             :     kIdKshiftlb,                         // [ANY] {AVX512_DQ}
+     399             :     kIdKshiftld,                         // [ANY] {AVX512_BW}
+     400             :     kIdKshiftlq,                         // [ANY] {AVX512_BW}
+     401             :     kIdKshiftlw,                         // [ANY] {AVX512_F}
+     402             :     kIdKshiftrb,                         // [ANY] {AVX512_DQ}
+     403             :     kIdKshiftrd,                         // [ANY] {AVX512_BW}
+     404             :     kIdKshiftrq,                         // [ANY] {AVX512_BW}
+     405             :     kIdKshiftrw,                         // [ANY] {AVX512_F}
+     406             :     kIdKtestb,                           // [ANY] {AVX512_DQ}
+     407             :     kIdKtestd,                           // [ANY] {AVX512_BW}
+     408             :     kIdKtestq,                           // [ANY] {AVX512_BW}
+     409             :     kIdKtestw,                           // [ANY] {AVX512_DQ}
+     410             :     kIdKunpckbw,                         // [ANY] {AVX512_F}
+     411             :     kIdKunpckdq,                         // [ANY] {AVX512_BW}
+     412             :     kIdKunpckwd,                         // [ANY] {AVX512_BW}
+     413             :     kIdKxnorb,                           // [ANY] {AVX512_DQ}
+     414             :     kIdKxnord,                           // [ANY] {AVX512_BW}
+     415             :     kIdKxnorq,                           // [ANY] {AVX512_BW}
+     416             :     kIdKxnorw,                           // [ANY] {AVX512_F}
+     417             :     kIdKxorb,                            // [ANY] {AVX512_DQ}
+     418             :     kIdKxord,                            // [ANY] {AVX512_BW}
+     419             :     kIdKxorq,                            // [ANY] {AVX512_BW}
+     420             :     kIdKxorw,                            // [ANY] {AVX512_F}
+     421             :     kIdLahf,                             // [ANY] {LAHFSAHF}
+     422             :     kIdLar,                              // [ANY]
+     423             :     kIdLddqu,                            // [ANY] {SSE3}
+     424             :     kIdLdmxcsr,                          // [ANY] {SSE}
+     425             :     kIdLds,                              // [X86]
+     426             :     kIdLea,                              // [ANY]
+     427             :     kIdLeave,                            // [ANY]
+     428             :     kIdLes,                              // [X86]
+     429             :     kIdLfence,                           // [ANY] {SSE2}
+     430             :     kIdLfs,                              // [ANY]
+     431             :     kIdLgdt,                             // [ANY]
+     432             :     kIdLgs,                              // [ANY]
+     433             :     kIdLidt,                             // [ANY]
+     434             :     kIdLldt,                             // [ANY]
+     435             :     kIdLmsw,                             // [ANY]
+     436             :     kIdLods,                             // [ANY]
+     437             :     kIdLoop,                             // [ANY]
+     438             :     kIdLoope,                            // [ANY]
+     439             :     kIdLoopne,                           // [ANY]
+     440             :     kIdLsl,                              // [ANY]
+     441             :     kIdLss,                              // [ANY]
+     442             :     kIdLtr,                              // [ANY]
+     443             :     kIdLzcnt,                            // [ANY] {LZCNT}
+     444             :     kIdMaskmovdqu,                       // [ANY] {SSE2}
+     445             :     kIdMaskmovq,                         // [ANY] {MMX2}
+     446             :     kIdMaxpd,                            // [ANY] {SSE2}
+     447             :     kIdMaxps,                            // [ANY] {SSE}
+     448             :     kIdMaxsd,                            // [ANY] {SSE2}
+     449             :     kIdMaxss,                            // [ANY] {SSE}
+     450             :     kIdMfence,                           // [ANY] {SSE2}
+     451             :     kIdMinpd,                            // [ANY] {SSE2}
+     452             :     kIdMinps,                            // [ANY] {SSE}
+     453             :     kIdMinsd,                            // [ANY] {SSE2}
+     454             :     kIdMinss,                            // [ANY] {SSE}
+     455             :     kIdMonitor,                          // [ANY] {MONITOR}
+     456             :     kIdMov,                              // [ANY]
+     457             :     kIdMovapd,                           // [ANY] {SSE2}
+     458             :     kIdMovaps,                           // [ANY] {SSE}
+     459             :     kIdMovbe,                            // [ANY] {MOVBE}
+     460             :     kIdMovd,                             // [ANY] {MMX|SSE2}
+     461             :     kIdMovddup,                          // [ANY] {SSE3}
+     462             :     kIdMovdq2q,                          // [ANY] {SSE2}
+     463             :     kIdMovdqa,                           // [ANY] {SSE2}
+     464             :     kIdMovdqu,                           // [ANY] {SSE2}
+     465             :     kIdMovhlps,                          // [ANY] {SSE}
+     466             :     kIdMovhpd,                           // [ANY] {SSE2}
+     467             :     kIdMovhps,                           // [ANY] {SSE}
+     468             :     kIdMovlhps,                          // [ANY] {SSE}
+     469             :     kIdMovlpd,                           // [ANY] {SSE2}
+     470             :     kIdMovlps,                           // [ANY] {SSE}
+     471             :     kIdMovmskpd,                         // [ANY] {SSE2}
+     472             :     kIdMovmskps,                         // [ANY] {SSE}
+     473             :     kIdMovntdq,                          // [ANY] {SSE2}
+     474             :     kIdMovntdqa,                         // [ANY] {SSE4_1}
+     475             :     kIdMovnti,                           // [ANY] {SSE2}
+     476             :     kIdMovntpd,                          // [ANY] {SSE2}
+     477             :     kIdMovntps,                          // [ANY] {SSE}
+     478             :     kIdMovntq,                           // [ANY] {MMX2}
+     479             :     kIdMovntsd,                          // [ANY] {SSE4A}
+     480             :     kIdMovntss,                          // [ANY] {SSE4A}
+     481             :     kIdMovq,                             // [ANY] {MMX|SSE2}
+     482             :     kIdMovq2dq,                          // [ANY] {SSE2}
+     483             :     kIdMovs,                             // [ANY]
+     484             :     kIdMovsd,                            // [ANY] {SSE2}
+     485             :     kIdMovshdup,                         // [ANY] {SSE3}
+     486             :     kIdMovsldup,                         // [ANY] {SSE3}
+     487             :     kIdMovss,                            // [ANY] {SSE}
+     488             :     kIdMovsx,                            // [ANY]
+     489             :     kIdMovsxd,                           // [X64]
+     490             :     kIdMovupd,                           // [ANY] {SSE2}
+     491             :     kIdMovups,                           // [ANY] {SSE}
+     492             :     kIdMovzx,                            // [ANY]
+     493             :     kIdMpsadbw,                          // [ANY] {SSE4_1}
+     494             :     kIdMul,                              // [ANY]
+     495             :     kIdMulpd,                            // [ANY] {SSE2}
+     496             :     kIdMulps,                            // [ANY] {SSE}
+     497             :     kIdMulsd,                            // [ANY] {SSE2}
+     498             :     kIdMulss,                            // [ANY] {SSE}
+     499             :     kIdMulx,                             // [ANY] {BMI2}
+     500             :     kIdMwait,                            // [ANY] {MONITOR}
+     501             :     kIdNeg,                              // [ANY]
+     502             :     kIdNop,                              // [ANY]
+     503             :     kIdNot,                              // [ANY]
+     504             :     kIdOr,                               // [ANY]
+     505             :     kIdOrpd,                             // [ANY] {SSE2}
+     506             :     kIdOrps,                             // [ANY] {SSE}
+     507             :     kIdOut,                              // [ANY]
+     508             :     kIdOuts,                             // [ANY]
+     509             :     kIdPabsb,                            // [ANY] {SSSE3}
+     510             :     kIdPabsd,                            // [ANY] {SSSE3}
+     511             :     kIdPabsw,                            // [ANY] {SSSE3}
+     512             :     kIdPackssdw,                         // [ANY] {MMX|SSE2}
+     513             :     kIdPacksswb,                         // [ANY] {MMX|SSE2}
+     514             :     kIdPackusdw,                         // [ANY] {SSE4_1}
+     515             :     kIdPackuswb,                         // [ANY] {MMX|SSE2}
+     516             :     kIdPaddb,                            // [ANY] {MMX|SSE2}
+     517             :     kIdPaddd,                            // [ANY] {MMX|SSE2}
+     518             :     kIdPaddq,                            // [ANY] {SSE2}
+     519             :     kIdPaddsb,                           // [ANY] {MMX|SSE2}
+     520             :     kIdPaddsw,                           // [ANY] {MMX|SSE2}
+     521             :     kIdPaddusb,                          // [ANY] {MMX|SSE2}
+     522             :     kIdPaddusw,                          // [ANY] {MMX|SSE2}
+     523             :     kIdPaddw,                            // [ANY] {MMX|SSE2}
+     524             :     kIdPalignr,                          // [ANY] {SSE3}
+     525             :     kIdPand,                             // [ANY] {MMX|SSE2}
+     526             :     kIdPandn,                            // [ANY] {MMX|SSE2}
+     527             :     kIdPause,                            // [ANY]
+     528             :     kIdPavgb,                            // [ANY] {MMX2|SSE2}
+     529             :     kIdPavgusb,                          // [ANY] {3DNOW}
+     530             :     kIdPavgw,                            // [ANY] {MMX2|SSE2}
+     531             :     kIdPblendvb,                         // [ANY] {SSE4_1}
+     532             :     kIdPblendw,                          // [ANY] {SSE4_1}
+     533             :     kIdPclmulqdq,                        // [ANY] {PCLMULQDQ}
+     534             :     kIdPcmpeqb,                          // [ANY] {MMX|SSE2}
+     535             :     kIdPcmpeqd,                          // [ANY] {MMX|SSE2}
+     536             :     kIdPcmpeqq,                          // [ANY] {SSE4_1}
+     537             :     kIdPcmpeqw,                          // [ANY] {MMX|SSE2}
+     538             :     kIdPcmpestri,                        // [ANY] {SSE4_2}
+     539             :     kIdPcmpestrm,                        // [ANY] {SSE4_2}
+     540             :     kIdPcmpgtb,                          // [ANY] {MMX|SSE2}
+     541             :     kIdPcmpgtd,                          // [ANY] {MMX|SSE2}
+     542             :     kIdPcmpgtq,                          // [ANY] {SSE4_2}
+     543             :     kIdPcmpgtw,                          // [ANY] {MMX|SSE2}
+     544             :     kIdPcmpistri,                        // [ANY] {SSE4_2}
+     545             :     kIdPcmpistrm,                        // [ANY] {SSE4_2}
+     546             :     kIdPcommit,                          // [ANY] {PCOMMIT}
+     547             :     kIdPdep,                             // [ANY] {BMI2}
+     548             :     kIdPext,                             // [ANY] {BMI2}
+     549             :     kIdPextrb,                           // [ANY] {SSE4_1}
+     550             :     kIdPextrd,                           // [ANY] {SSE4_1}
+     551             :     kIdPextrq,                           // [X64] {SSE4_1}
+     552             :     kIdPextrw,                           // [ANY] {MMX2|SSE2|SSE4_1}
+     553             :     kIdPf2id,                            // [ANY] {3DNOW}
+     554             :     kIdPf2iw,                            // [ANY] {3DNOW2}
+     555             :     kIdPfacc,                            // [ANY] {3DNOW}
+     556             :     kIdPfadd,                            // [ANY] {3DNOW}
+     557             :     kIdPfcmpeq,                          // [ANY] {3DNOW}
+     558             :     kIdPfcmpge,                          // [ANY] {3DNOW}
+     559             :     kIdPfcmpgt,                          // [ANY] {3DNOW}
+     560             :     kIdPfmax,                            // [ANY] {3DNOW}
+     561             :     kIdPfmin,                            // [ANY] {3DNOW}
+     562             :     kIdPfmul,                            // [ANY] {3DNOW}
+     563             :     kIdPfnacc,                           // [ANY] {3DNOW2}
+     564             :     kIdPfpnacc,                          // [ANY] {3DNOW2}
+     565             :     kIdPfrcp,                            // [ANY] {3DNOW}
+     566             :     kIdPfrcpit1,                         // [ANY] {3DNOW}
+     567             :     kIdPfrcpit2,                         // [ANY] {3DNOW}
+     568             :     kIdPfrcpv,                           // [ANY] {GEODE}
+     569             :     kIdPfrsqit1,                         // [ANY] {3DNOW}
+     570             :     kIdPfrsqrt,                          // [ANY] {3DNOW}
+     571             :     kIdPfrsqrtv,                         // [ANY] {GEODE}
+     572             :     kIdPfsub,                            // [ANY] {3DNOW}
+     573             :     kIdPfsubr,                           // [ANY] {3DNOW}
+     574             :     kIdPhaddd,                           // [ANY] {SSSE3}
+     575             :     kIdPhaddsw,                          // [ANY] {SSSE3}
+     576             :     kIdPhaddw,                           // [ANY] {SSSE3}
+     577             :     kIdPhminposuw,                       // [ANY] {SSE4_1}
+     578             :     kIdPhsubd,                           // [ANY] {SSSE3}
+     579             :     kIdPhsubsw,                          // [ANY] {SSSE3}
+     580             :     kIdPhsubw,                           // [ANY] {SSSE3}
+     581             :     kIdPi2fd,                            // [ANY] {3DNOW}
+     582             :     kIdPi2fw,                            // [ANY] {3DNOW2}
+     583             :     kIdPinsrb,                           // [ANY] {SSE4_1}
+     584             :     kIdPinsrd,                           // [ANY] {SSE4_1}
+     585             :     kIdPinsrq,                           // [X64] {SSE4_1}
+     586             :     kIdPinsrw,                           // [ANY] {MMX2|SSE2}
+     587             :     kIdPmaddubsw,                        // [ANY] {SSSE3}
+     588             :     kIdPmaddwd,                          // [ANY] {MMX|SSE2}
+     589             :     kIdPmaxsb,                           // [ANY] {SSE4_1}
+     590             :     kIdPmaxsd,                           // [ANY] {SSE4_1}
+     591             :     kIdPmaxsw,                           // [ANY] {MMX2|SSE2}
+     592             :     kIdPmaxub,                           // [ANY] {MMX2|SSE2}
+     593             :     kIdPmaxud,                           // [ANY] {SSE4_1}
+     594             :     kIdPmaxuw,                           // [ANY] {SSE4_1}
+     595             :     kIdPminsb,                           // [ANY] {SSE4_1}
+     596             :     kIdPminsd,                           // [ANY] {SSE4_1}
+     597             :     kIdPminsw,                           // [ANY] {MMX2|SSE2}
+     598             :     kIdPminub,                           // [ANY] {MMX2|SSE2}
+     599             :     kIdPminud,                           // [ANY] {SSE4_1}
+     600             :     kIdPminuw,                           // [ANY] {SSE4_1}
+     601             :     kIdPmovmskb,                         // [ANY] {MMX2|SSE2}
+     602             :     kIdPmovsxbd,                         // [ANY] {SSE4_1}
+     603             :     kIdPmovsxbq,                         // [ANY] {SSE4_1}
+     604             :     kIdPmovsxbw,                         // [ANY] {SSE4_1}
+     605             :     kIdPmovsxdq,                         // [ANY] {SSE4_1}
+     606             :     kIdPmovsxwd,                         // [ANY] {SSE4_1}
+     607             :     kIdPmovsxwq,                         // [ANY] {SSE4_1}
+     608             :     kIdPmovzxbd,                         // [ANY] {SSE4_1}
+     609             :     kIdPmovzxbq,                         // [ANY] {SSE4_1}
+     610             :     kIdPmovzxbw,                         // [ANY] {SSE4_1}
+     611             :     kIdPmovzxdq,                         // [ANY] {SSE4_1}
+     612             :     kIdPmovzxwd,                         // [ANY] {SSE4_1}
+     613             :     kIdPmovzxwq,                         // [ANY] {SSE4_1}
+     614             :     kIdPmuldq,                           // [ANY] {SSE4_1}
+     615             :     kIdPmulhrsw,                         // [ANY] {SSSE3}
+     616             :     kIdPmulhrw,                          // [ANY] {3DNOW}
+     617             :     kIdPmulhuw,                          // [ANY] {MMX2|SSE2}
+     618             :     kIdPmulhw,                           // [ANY] {MMX|SSE2}
+     619             :     kIdPmulld,                           // [ANY] {SSE4_1}
+     620             :     kIdPmullw,                           // [ANY] {MMX|SSE2}
+     621             :     kIdPmuludq,                          // [ANY] {SSE2}
+     622             :     kIdPop,                              // [ANY]
+     623             :     kIdPopa,                             // [X86]
+     624             :     kIdPopad,                            // [X86]
+     625             :     kIdPopcnt,                           // [ANY] {POPCNT}
+     626             :     kIdPopf,                             // [ANY]
+     627             :     kIdPopfd,                            // [X86]
+     628             :     kIdPopfq,                            // [X64]
+     629             :     kIdPor,                              // [ANY] {MMX|SSE2}
+     630             :     kIdPrefetch,                         // [ANY] {3DNOW}
+     631             :     kIdPrefetchnta,                      // [ANY] {MMX2}
+     632             :     kIdPrefetcht0,                       // [ANY] {MMX2}
+     633             :     kIdPrefetcht1,                       // [ANY] {MMX2}
+     634             :     kIdPrefetcht2,                       // [ANY] {MMX2}
+     635             :     kIdPrefetchw,                        // [ANY] {PREFETCHW}
+     636             :     kIdPrefetchwt1,                      // [ANY] {PREFETCHWT1}
+     637             :     kIdPsadbw,                           // [ANY] {MMX2|SSE2}
+     638             :     kIdPshufb,                           // [ANY] {SSSE3}
+     639             :     kIdPshufd,                           // [ANY] {SSE2}
+     640             :     kIdPshufhw,                          // [ANY] {SSE2}
+     641             :     kIdPshuflw,                          // [ANY] {SSE2}
+     642             :     kIdPshufw,                           // [ANY] {MMX2}
+     643             :     kIdPsignb,                           // [ANY] {SSSE3}
+     644             :     kIdPsignd,                           // [ANY] {SSSE3}
+     645             :     kIdPsignw,                           // [ANY] {SSSE3}
+     646             :     kIdPslld,                            // [ANY] {MMX|SSE2}
+     647             :     kIdPslldq,                           // [ANY] {SSE2}
+     648             :     kIdPsllq,                            // [ANY] {MMX|SSE2}
+     649             :     kIdPsllw,                            // [ANY] {MMX|SSE2}
+     650             :     kIdPsrad,                            // [ANY] {MMX|SSE2}
+     651             :     kIdPsraw,                            // [ANY] {MMX|SSE2}
+     652             :     kIdPsrld,                            // [ANY] {MMX|SSE2}
+     653             :     kIdPsrldq,                           // [ANY] {SSE2}
+     654             :     kIdPsrlq,                            // [ANY] {MMX|SSE2}
+     655             :     kIdPsrlw,                            // [ANY] {MMX|SSE2}
+     656             :     kIdPsubb,                            // [ANY] {MMX|SSE2}
+     657             :     kIdPsubd,                            // [ANY] {MMX|SSE2}
+     658             :     kIdPsubq,                            // [ANY] {SSE2}
+     659             :     kIdPsubsb,                           // [ANY] {MMX|SSE2}
+     660             :     kIdPsubsw,                           // [ANY] {MMX|SSE2}
+     661             :     kIdPsubusb,                          // [ANY] {MMX|SSE2}
+     662             :     kIdPsubusw,                          // [ANY] {MMX|SSE2}
+     663             :     kIdPsubw,                            // [ANY] {MMX|SSE2}
+     664             :     kIdPswapd,                           // [ANY] {3DNOW2}
+     665             :     kIdPtest,                            // [ANY] {SSE4_1}
+     666             :     kIdPunpckhbw,                        // [ANY] {MMX|SSE2}
+     667             :     kIdPunpckhdq,                        // [ANY] {MMX|SSE2}
+     668             :     kIdPunpckhqdq,                       // [ANY] {SSE2}
+     669             :     kIdPunpckhwd,                        // [ANY] {MMX|SSE2}
+     670             :     kIdPunpcklbw,                        // [ANY] {MMX|SSE2}
+     671             :     kIdPunpckldq,                        // [ANY] {MMX|SSE2}
+     672             :     kIdPunpcklqdq,                       // [ANY] {SSE2}
+     673             :     kIdPunpcklwd,                        // [ANY] {MMX|SSE2}
+     674             :     kIdPush,                             // [ANY]
+     675             :     kIdPusha,                            // [X86]
+     676             :     kIdPushad,                           // [X86]
+     677             :     kIdPushf,                            // [ANY]
+     678             :     kIdPushfd,                           // [X86]
+     679             :     kIdPushfq,                           // [X64]
+     680             :     kIdPxor,                             // [ANY] {MMX|SSE2}
+     681             :     kIdRcl,                              // [ANY]
+     682             :     kIdRcpps,                            // [ANY] {SSE}
+     683             :     kIdRcpss,                            // [ANY] {SSE}
+     684             :     kIdRcr,                              // [ANY]
+     685             :     kIdRdfsbase,                         // [X64] {FSGSBASE}
+     686             :     kIdRdgsbase,                         // [X64] {FSGSBASE}
+     687             :     kIdRdmsr,                            // [ANY] {MSR}
+     688             :     kIdRdpmc,                            // [ANY]
+     689             :     kIdRdrand,                           // [ANY] {RDRAND}
+     690             :     kIdRdseed,                           // [ANY] {RDSEED}
+     691             :     kIdRdtsc,                            // [ANY] {RDTSC}
+     692             :     kIdRdtscp,                           // [ANY] {RDTSCP}
+     693             :     kIdRet,                              // [ANY]
+     694             :     kIdRol,                              // [ANY]
+     695             :     kIdRor,                              // [ANY]
+     696             :     kIdRorx,                             // [ANY] {BMI2}
+     697             :     kIdRoundpd,                          // [ANY] {SSE4_1}
+     698             :     kIdRoundps,                          // [ANY] {SSE4_1}
+     699             :     kIdRoundsd,                          // [ANY] {SSE4_1}
+     700             :     kIdRoundss,                          // [ANY] {SSE4_1}
+     701             :     kIdRsm,                              // [X86]
+     702             :     kIdRsqrtps,                          // [ANY] {SSE}
+     703             :     kIdRsqrtss,                          // [ANY] {SSE}
+     704             :     kIdSahf,                             // [ANY] {LAHFSAHF}
+     705             :     kIdSal,                              // [ANY]
+     706             :     kIdSar,                              // [ANY]
+     707             :     kIdSarx,                             // [ANY] {BMI2}
+     708             :     kIdSbb,                              // [ANY]
+     709             :     kIdScas,                             // [ANY]
+     710             :     kIdSeta,                             // [ANY]
+     711             :     kIdSetae,                            // [ANY]
+     712             :     kIdSetb,                             // [ANY]
+     713             :     kIdSetbe,                            // [ANY]
+     714             :     kIdSetc,                             // [ANY]
+     715             :     kIdSete,                             // [ANY]
+     716             :     kIdSetg,                             // [ANY]
+     717             :     kIdSetge,                            // [ANY]
+     718             :     kIdSetl,                             // [ANY]
+     719             :     kIdSetle,                            // [ANY]
+     720             :     kIdSetna,                            // [ANY]
+     721             :     kIdSetnae,                           // [ANY]
+     722             :     kIdSetnb,                            // [ANY]
+     723             :     kIdSetnbe,                           // [ANY]
+     724             :     kIdSetnc,                            // [ANY]
+     725             :     kIdSetne,                            // [ANY]
+     726             :     kIdSetng,                            // [ANY]
+     727             :     kIdSetnge,                           // [ANY]
+     728             :     kIdSetnl,                            // [ANY]
+     729             :     kIdSetnle,                           // [ANY]
+     730             :     kIdSetno,                            // [ANY]
+     731             :     kIdSetnp,                            // [ANY]
+     732             :     kIdSetns,                            // [ANY]
+     733             :     kIdSetnz,                            // [ANY]
+     734             :     kIdSeto,                             // [ANY]
+     735             :     kIdSetp,                             // [ANY]
+     736             :     kIdSetpe,                            // [ANY]
+     737             :     kIdSetpo,                            // [ANY]
+     738             :     kIdSets,                             // [ANY]
+     739             :     kIdSetz,                             // [ANY]
+     740             :     kIdSfence,                           // [ANY] {MMX2}
+     741             :     kIdSgdt,                             // [ANY]
+     742             :     kIdSha1msg1,                         // [ANY] {SHA}
+     743             :     kIdSha1msg2,                         // [ANY] {SHA}
+     744             :     kIdSha1nexte,                        // [ANY] {SHA}
+     745             :     kIdSha1rnds4,                        // [ANY] {SHA}
+     746             :     kIdSha256msg1,                       // [ANY] {SHA}
+     747             :     kIdSha256msg2,                       // [ANY] {SHA}
+     748             :     kIdSha256rnds2,                      // [ANY] {SHA}
+     749             :     kIdShl,                              // [ANY]
+     750             :     kIdShld,                             // [ANY]
+     751             :     kIdShlx,                             // [ANY] {BMI2}
+     752             :     kIdShr,                              // [ANY]
+     753             :     kIdShrd,                             // [ANY]
+     754             :     kIdShrx,                             // [ANY] {BMI2}
+     755             :     kIdShufpd,                           // [ANY] {SSE2}
+     756             :     kIdShufps,                           // [ANY] {SSE}
+     757             :     kIdSidt,                             // [ANY]
+     758             :     kIdSldt,                             // [ANY]
+     759             :     kIdSmsw,                             // [ANY]
+     760             :     kIdSqrtpd,                           // [ANY] {SSE2}
+     761             :     kIdSqrtps,                           // [ANY] {SSE}
+     762             :     kIdSqrtsd,                           // [ANY] {SSE2}
+     763             :     kIdSqrtss,                           // [ANY] {SSE}
+     764             :     kIdStac,                             // [ANY] {SMAP}
+     765             :     kIdStc,                              // [ANY]
+     766             :     kIdStd,                              // [ANY]
+     767             :     kIdSti,                              // [ANY]
+     768             :     kIdStmxcsr,                          // [ANY] {SSE}
+     769             :     kIdStos,                             // [ANY]
+     770             :     kIdStr,                              // [ANY]
+     771             :     kIdSub,                              // [ANY]
+     772             :     kIdSubpd,                            // [ANY] {SSE2}
+     773             :     kIdSubps,                            // [ANY] {SSE}
+     774             :     kIdSubsd,                            // [ANY] {SSE2}
+     775             :     kIdSubss,                            // [ANY] {SSE}
+     776             :     kIdSwapgs,                           // [X64]
+     777             :     kIdSyscall,                          // [X64]
+     778             :     kIdSysenter,                         // [ANY]
+     779             :     kIdSysexit,                          // [ANY]
+     780             :     kIdSysexit64,                        // [ANY]
+     781             :     kIdSysret,                           // [X64]
+     782             :     kIdSysret64,                         // [X64]
+     783             :     kIdT1mskc,                           // [ANY] {TBM}
+     784             :     kIdTest,                             // [ANY]
+     785             :     kIdTzcnt,                            // [ANY] {BMI}
+     786             :     kIdTzmsk,                            // [ANY] {TBM}
+     787             :     kIdUcomisd,                          // [ANY] {SSE2}
+     788             :     kIdUcomiss,                          // [ANY] {SSE}
+     789             :     kIdUd2,                              // [ANY]
+     790             :     kIdUnpckhpd,                         // [ANY] {SSE2}
+     791             :     kIdUnpckhps,                         // [ANY] {SSE}
+     792             :     kIdUnpcklpd,                         // [ANY] {SSE2}
+     793             :     kIdUnpcklps,                         // [ANY] {SSE}
+     794             :     kIdV4fmaddps,                        // [ANY] {AVX512_4FMAPS}
+     795             :     kIdV4fnmaddps,                       // [ANY] {AVX512_4FMAPS}
+     796             :     kIdVaddpd,                           // [ANY] {AVX|AVX512_F+VL}
+     797             :     kIdVaddps,                           // [ANY] {AVX|AVX512_F+VL}
+     798             :     kIdVaddsd,                           // [ANY] {AVX|AVX512_F}
+     799             :     kIdVaddss,                           // [ANY] {AVX|AVX512_F}
+     800             :     kIdVaddsubpd,                        // [ANY] {AVX}
+     801             :     kIdVaddsubps,                        // [ANY] {AVX}
+     802             :     kIdVaesdec,                          // [ANY] {AESNI|AVX}
+     803             :     kIdVaesdeclast,                      // [ANY] {AESNI|AVX}
+     804             :     kIdVaesenc,                          // [ANY] {AESNI|AVX}
+     805             :     kIdVaesenclast,                      // [ANY] {AESNI|AVX}
+     806             :     kIdVaesimc,                          // [ANY] {AESNI|AVX}
+     807             :     kIdVaeskeygenassist,                 // [ANY] {AESNI|AVX}
+     808             :     kIdValignd,                          // [ANY] {AVX512_F+VL}
+     809             :     kIdValignq,                          // [ANY] {AVX512_F+VL}
+     810             :     kIdVandnpd,                          // [ANY] {AVX|AVX512_DQ+VL}
+     811             :     kIdVandnps,                          // [ANY] {AVX|AVX512_DQ+VL}
+     812             :     kIdVandpd,                           // [ANY] {AVX|AVX512_DQ+VL}
+     813             :     kIdVandps,                           // [ANY] {AVX|AVX512_DQ+VL}
+     814             :     kIdVblendmb,                         // [ANY] {AVX512_BW+VL}
+     815             :     kIdVblendmd,                         // [ANY] {AVX512_F+VL}
+     816             :     kIdVblendmpd,                        // [ANY] {AVX512_F+VL}
+     817             :     kIdVblendmps,                        // [ANY] {AVX512_F+VL}
+     818             :     kIdVblendmq,                         // [ANY] {AVX512_F+VL}
+     819             :     kIdVblendmw,                         // [ANY] {AVX512_BW+VL}
+     820             :     kIdVblendpd,                         // [ANY] {AVX}
+     821             :     kIdVblendps,                         // [ANY] {AVX}
+     822             :     kIdVblendvpd,                        // [ANY] {AVX}
+     823             :     kIdVblendvps,                        // [ANY] {AVX}
+     824             :     kIdVbroadcastf128,                   // [ANY] {AVX}
+     825             :     kIdVbroadcastf32x2,                  // [ANY] {AVX512_DQ+VL}
+     826             :     kIdVbroadcastf32x4,                  // [ANY] {AVX512_F}
+     827             :     kIdVbroadcastf32x8,                  // [ANY] {AVX512_DQ}
+     828             :     kIdVbroadcastf64x2,                  // [ANY] {AVX512_DQ+VL}
+     829             :     kIdVbroadcastf64x4,                  // [ANY] {AVX512_F}
+     830             :     kIdVbroadcasti128,                   // [ANY] {AVX2}
+     831             :     kIdVbroadcasti32x2,                  // [ANY] {AVX512_DQ+VL}
+     832             :     kIdVbroadcasti32x4,                  // [ANY] {AVX512_F+VL}
+     833             :     kIdVbroadcasti32x8,                  // [ANY] {AVX512_DQ}
+     834             :     kIdVbroadcasti64x2,                  // [ANY] {AVX512_DQ+VL}
+     835             :     kIdVbroadcasti64x4,                  // [ANY] {AVX512_F}
+     836             :     kIdVbroadcastsd,                     // [ANY] {AVX|AVX2|AVX512_F+VL}
+     837             :     kIdVbroadcastss,                     // [ANY] {AVX|AVX2|AVX512_F+VL}
+     838             :     kIdVcmppd,                           // [ANY] {AVX|AVX512_F+VL}
+     839             :     kIdVcmpps,                           // [ANY] {AVX|AVX512_F+VL}
+     840             :     kIdVcmpsd,                           // [ANY] {AVX|AVX512_F}
+     841             :     kIdVcmpss,                           // [ANY] {AVX|AVX512_F}
+     842             :     kIdVcomisd,                          // [ANY] {AVX|AVX512_F}
+     843             :     kIdVcomiss,                          // [ANY] {AVX|AVX512_F}
+     844             :     kIdVcompresspd,                      // [ANY] {AVX512_F+VL}
+     845             :     kIdVcompressps,                      // [ANY] {AVX512_F+VL}
+     846             :     kIdVcvtdq2pd,                        // [ANY] {AVX|AVX512_F+VL}
+     847             :     kIdVcvtdq2ps,                        // [ANY] {AVX|AVX512_F+VL}
+     848             :     kIdVcvtpd2dq,                        // [ANY] {AVX|AVX512_F+VL}
+     849             :     kIdVcvtpd2ps,                        // [ANY] {AVX|AVX512_F+VL}
+     850             :     kIdVcvtpd2qq,                        // [ANY] {AVX512_DQ+VL}
+     851             :     kIdVcvtpd2udq,                       // [ANY] {AVX512_F+VL}
+     852             :     kIdVcvtpd2uqq,                       // [ANY] {AVX512_DQ+VL}
+     853             :     kIdVcvtph2ps,                        // [ANY] {AVX512_F|F16C+VL}
+     854             :     kIdVcvtps2dq,                        // [ANY] {AVX|AVX512_F+VL}
+     855             :     kIdVcvtps2pd,                        // [ANY] {AVX|AVX512_F+VL}
+     856             :     kIdVcvtps2ph,                        // [ANY] {AVX512_F|F16C+VL}
+     857             :     kIdVcvtps2qq,                        // [ANY] {AVX512_DQ+VL}
+     858             :     kIdVcvtps2udq,                       // [ANY] {AVX512_F+VL}
+     859             :     kIdVcvtps2uqq,                       // [ANY] {AVX512_DQ+VL}
+     860             :     kIdVcvtqq2pd,                        // [ANY] {AVX512_DQ+VL}
+     861             :     kIdVcvtqq2ps,                        // [ANY] {AVX512_DQ+VL}
+     862             :     kIdVcvtsd2si,                        // [ANY] {AVX|AVX512_F}
+     863             :     kIdVcvtsd2ss,                        // [ANY] {AVX|AVX512_F}
+     864             :     kIdVcvtsd2usi,                       // [ANY] {AVX512_F}
+     865             :     kIdVcvtsi2sd,                        // [ANY] {AVX|AVX512_F}
+     866             :     kIdVcvtsi2ss,                        // [ANY] {AVX|AVX512_F}
+     867             :     kIdVcvtss2sd,                        // [ANY] {AVX|AVX512_F}
+     868             :     kIdVcvtss2si,                        // [ANY] {AVX|AVX512_F}
+     869             :     kIdVcvtss2usi,                       // [ANY] {AVX512_F}
+     870             :     kIdVcvttpd2dq,                       // [ANY] {AVX|AVX512_F+VL}
+     871             :     kIdVcvttpd2qq,                       // [ANY] {AVX512_F+VL}
+     872             :     kIdVcvttpd2udq,                      // [ANY] {AVX512_F+VL}
+     873             :     kIdVcvttpd2uqq,                      // [ANY] {AVX512_DQ+VL}
+     874             :     kIdVcvttps2dq,                       // [ANY] {AVX|AVX512_F+VL}
+     875             :     kIdVcvttps2qq,                       // [ANY] {AVX512_DQ+VL}
+     876             :     kIdVcvttps2udq,                      // [ANY] {AVX512_F+VL}
+     877             :     kIdVcvttps2uqq,                      // [ANY] {AVX512_DQ+VL}
+     878             :     kIdVcvttsd2si,                       // [ANY] {AVX|AVX512_F}
+     879             :     kIdVcvttsd2usi,                      // [ANY] {AVX512_F}
+     880             :     kIdVcvttss2si,                       // [ANY] {AVX|AVX512_F}
+     881             :     kIdVcvttss2usi,                      // [ANY] {AVX512_F}
+     882             :     kIdVcvtudq2pd,                       // [ANY] {AVX512_F+VL}
+     883             :     kIdVcvtudq2ps,                       // [ANY] {AVX512_F+VL}
+     884             :     kIdVcvtuqq2pd,                       // [ANY] {AVX512_DQ+VL}
+     885             :     kIdVcvtuqq2ps,                       // [ANY] {AVX512_DQ+VL}
+     886             :     kIdVcvtusi2sd,                       // [ANY] {AVX512_F}
+     887             :     kIdVcvtusi2ss,                       // [ANY] {AVX512_F}
+     888             :     kIdVdbpsadbw,                        // [ANY] {AVX512_BW+VL}
+     889             :     kIdVdivpd,                           // [ANY] {AVX|AVX512_F+VL}
+     890             :     kIdVdivps,                           // [ANY] {AVX|AVX512_F+VL}
+     891             :     kIdVdivsd,                           // [ANY] {AVX|AVX512_F}
+     892             :     kIdVdivss,                           // [ANY] {AVX|AVX512_F}
+     893             :     kIdVdppd,                            // [ANY] {AVX}
+     894             :     kIdVdpps,                            // [ANY] {AVX}
+     895             :     kIdVerr,                             // [ANY]
+     896             :     kIdVerw,                             // [ANY]
+     897             :     kIdVexp2pd,                          // [ANY] {AVX512_ERI}
+     898             :     kIdVexp2ps,                          // [ANY] {AVX512_ERI}
+     899             :     kIdVexpandpd,                        // [ANY] {AVX512_F+VL}
+     900             :     kIdVexpandps,                        // [ANY] {AVX512_F+VL}
+     901             :     kIdVextractf128,                     // [ANY] {AVX}
+     902             :     kIdVextractf32x4,                    // [ANY] {AVX512_F+VL}
+     903             :     kIdVextractf32x8,                    // [ANY] {AVX512_DQ}
+     904             :     kIdVextractf64x2,                    // [ANY] {AVX512_DQ+VL}
+     905             :     kIdVextractf64x4,                    // [ANY] {AVX512_F}
+     906             :     kIdVextracti128,                     // [ANY] {AVX2}
+     907             :     kIdVextracti32x4,                    // [ANY] {AVX512_F+VL}
+     908             :     kIdVextracti32x8,                    // [ANY] {AVX512_DQ}
+     909             :     kIdVextracti64x2,                    // [ANY] {AVX512_DQ+VL}
+     910             :     kIdVextracti64x4,                    // [ANY] {AVX512_F}
+     911             :     kIdVextractps,                       // [ANY] {AVX|AVX512_F}
+     912             :     kIdVfixupimmpd,                      // [ANY] {AVX512_F+VL}
+     913             :     kIdVfixupimmps,                      // [ANY] {AVX512_F+VL}
+     914             :     kIdVfixupimmsd,                      // [ANY] {AVX512_F}
+     915             :     kIdVfixupimmss,                      // [ANY] {AVX512_F}
+     916             :     kIdVfmadd132pd,                      // [ANY] {AVX512_F|FMA+VL}
+     917             :     kIdVfmadd132ps,                      // [ANY] {AVX512_F|FMA+VL}
+     918             :     kIdVfmadd132sd,                      // [ANY] {AVX512_F|FMA}
+     919             :     kIdVfmadd132ss,                      // [ANY] {AVX512_F|FMA}
+     920             :     kIdVfmadd213pd,                      // [ANY] {AVX512_F|FMA+VL}
+     921             :     kIdVfmadd213ps,                      // [ANY] {AVX512_F|FMA+VL}
+     922             :     kIdVfmadd213sd,                      // [ANY] {AVX512_F|FMA}
+     923             :     kIdVfmadd213ss,                      // [ANY] {AVX512_F|FMA}
+     924             :     kIdVfmadd231pd,                      // [ANY] {AVX512_F|FMA+VL}
+     925             :     kIdVfmadd231ps,                      // [ANY] {AVX512_F|FMA+VL}
+     926             :     kIdVfmadd231sd,                      // [ANY] {AVX512_F|FMA}
+     927             :     kIdVfmadd231ss,                      // [ANY] {AVX512_F|FMA}
+     928             :     kIdVfmaddpd,                         // [ANY] {FMA4}
+     929             :     kIdVfmaddps,                         // [ANY] {FMA4}
+     930             :     kIdVfmaddsd,                         // [ANY] {FMA4}
+     931             :     kIdVfmaddss,                         // [ANY] {FMA4}
+     932             :     kIdVfmaddsub132pd,                   // [ANY] {AVX512_F|FMA+VL}
+     933             :     kIdVfmaddsub132ps,                   // [ANY] {AVX512_F|FMA+VL}
+     934             :     kIdVfmaddsub213pd,                   // [ANY] {AVX512_F|FMA+VL}
+     935             :     kIdVfmaddsub213ps,                   // [ANY] {AVX512_F|FMA+VL}
+     936             :     kIdVfmaddsub231pd,                   // [ANY] {AVX512_F|FMA+VL}
+     937             :     kIdVfmaddsub231ps,                   // [ANY] {AVX512_F|FMA+VL}
+     938             :     kIdVfmaddsubpd,                      // [ANY] {FMA4}
+     939             :     kIdVfmaddsubps,                      // [ANY] {FMA4}
+     940             :     kIdVfmsub132pd,                      // [ANY] {AVX512_F|FMA+VL}
+     941             :     kIdVfmsub132ps,                      // [ANY] {AVX512_F|FMA+VL}
+     942             :     kIdVfmsub132sd,                      // [ANY] {AVX512_F|FMA}
+     943             :     kIdVfmsub132ss,                      // [ANY] {AVX512_F|FMA}
+     944             :     kIdVfmsub213pd,                      // [ANY] {AVX512_F|FMA+VL}
+     945             :     kIdVfmsub213ps,                      // [ANY] {AVX512_F|FMA+VL}
+     946             :     kIdVfmsub213sd,                      // [ANY] {AVX512_F|FMA}
+     947             :     kIdVfmsub213ss,                      // [ANY] {AVX512_F|FMA}
+     948             :     kIdVfmsub231pd,                      // [ANY] {AVX512_F|FMA+VL}
+     949             :     kIdVfmsub231ps,                      // [ANY] {AVX512_F|FMA+VL}
+     950             :     kIdVfmsub231sd,                      // [ANY] {AVX512_F|FMA}
+     951             :     kIdVfmsub231ss,                      // [ANY] {AVX512_F|FMA}
+     952             :     kIdVfmsubadd132pd,                   // [ANY] {AVX512_F|FMA+VL}
+     953             :     kIdVfmsubadd132ps,                   // [ANY] {AVX512_F|FMA+VL}
+     954             :     kIdVfmsubadd213pd,                   // [ANY] {AVX512_F|FMA+VL}
+     955             :     kIdVfmsubadd213ps,                   // [ANY] {AVX512_F|FMA+VL}
+     956             :     kIdVfmsubadd231pd,                   // [ANY] {AVX512_F|FMA+VL}
+     957             :     kIdVfmsubadd231ps,                   // [ANY] {AVX512_F|FMA+VL}
+     958             :     kIdVfmsubaddpd,                      // [ANY] {FMA4}
+     959             :     kIdVfmsubaddps,                      // [ANY] {FMA4}
+     960             :     kIdVfmsubpd,                         // [ANY] {FMA4}
+     961             :     kIdVfmsubps,                         // [ANY] {FMA4}
+     962             :     kIdVfmsubsd,                         // [ANY] {FMA4}
+     963             :     kIdVfmsubss,                         // [ANY] {FMA4}
+     964             :     kIdVfnmadd132pd,                     // [ANY] {AVX512_F|FMA+VL}
+     965             :     kIdVfnmadd132ps,                     // [ANY] {AVX512_F|FMA+VL}
+     966             :     kIdVfnmadd132sd,                     // [ANY] {AVX512_F|FMA}
+     967             :     kIdVfnmadd132ss,                     // [ANY] {AVX512_F|FMA}
+     968             :     kIdVfnmadd213pd,                     // [ANY] {AVX512_F|FMA+VL}
+     969             :     kIdVfnmadd213ps,                     // [ANY] {AVX512_F|FMA+VL}
+     970             :     kIdVfnmadd213sd,                     // [ANY] {AVX512_F|FMA}
+     971             :     kIdVfnmadd213ss,                     // [ANY] {AVX512_F|FMA}
+     972             :     kIdVfnmadd231pd,                     // [ANY] {AVX512_F|FMA+VL}
+     973             :     kIdVfnmadd231ps,                     // [ANY] {AVX512_F|FMA+VL}
+     974             :     kIdVfnmadd231sd,                     // [ANY] {AVX512_F|FMA}
+     975             :     kIdVfnmadd231ss,                     // [ANY] {AVX512_F|FMA}
+     976             :     kIdVfnmaddpd,                        // [ANY] {FMA4}
+     977             :     kIdVfnmaddps,                        // [ANY] {FMA4}
+     978             :     kIdVfnmaddsd,                        // [ANY] {FMA4}
+     979             :     kIdVfnmaddss,                        // [ANY] {FMA4}
+     980             :     kIdVfnmsub132pd,                     // [ANY] {AVX512_F|FMA+VL}
+     981             :     kIdVfnmsub132ps,                     // [ANY] {AVX512_F|FMA+VL}
+     982             :     kIdVfnmsub132sd,                     // [ANY] {AVX512_F|FMA}
+     983             :     kIdVfnmsub132ss,                     // [ANY] {AVX512_F|FMA}
+     984             :     kIdVfnmsub213pd,                     // [ANY] {AVX512_F|FMA+VL}
+     985             :     kIdVfnmsub213ps,                     // [ANY] {AVX512_F|FMA+VL}
+     986             :     kIdVfnmsub213sd,                     // [ANY] {AVX512_F|FMA}
+     987             :     kIdVfnmsub213ss,                     // [ANY] {AVX512_F|FMA}
+     988             :     kIdVfnmsub231pd,                     // [ANY] {AVX512_F|FMA+VL}
+     989             :     kIdVfnmsub231ps,                     // [ANY] {AVX512_F|FMA+VL}
+     990             :     kIdVfnmsub231sd,                     // [ANY] {AVX512_F|FMA}
+     991             :     kIdVfnmsub231ss,                     // [ANY] {AVX512_F|FMA}
+     992             :     kIdVfnmsubpd,                        // [ANY] {FMA4}
+     993             :     kIdVfnmsubps,                        // [ANY] {FMA4}
+     994             :     kIdVfnmsubsd,                        // [ANY] {FMA4}
+     995             :     kIdVfnmsubss,                        // [ANY] {FMA4}
+     996             :     kIdVfpclasspd,                       // [ANY] {AVX512_DQ+VL}
+     997             :     kIdVfpclassps,                       // [ANY] {AVX512_DQ+VL}
+     998             :     kIdVfpclasssd,                       // [ANY] {AVX512_DQ}
+     999             :     kIdVfpclassss,                       // [ANY] {AVX512_DQ}
+    1000             :     kIdVfrczpd,                          // [ANY] {XOP}
+    1001             :     kIdVfrczps,                          // [ANY] {XOP}
+    1002             :     kIdVfrczsd,                          // [ANY] {XOP}
+    1003             :     kIdVfrczss,                          // [ANY] {XOP}
+    1004             :     kIdVgatherdpd,                       // [ANY] {AVX2|AVX512_F+VL}
+    1005             :     kIdVgatherdps,                       // [ANY] {AVX2|AVX512_F+VL}
+    1006             :     kIdVgatherpf0dpd,                    // [ANY] {AVX512_PFI}
+    1007             :     kIdVgatherpf0dps,                    // [ANY] {AVX512_PFI}
+    1008             :     kIdVgatherpf0qpd,                    // [ANY] {AVX512_PFI}
+    1009             :     kIdVgatherpf0qps,                    // [ANY] {AVX512_PFI}
+    1010             :     kIdVgatherpf1dpd,                    // [ANY] {AVX512_PFI}
+    1011             :     kIdVgatherpf1dps,                    // [ANY] {AVX512_PFI}
+    1012             :     kIdVgatherpf1qpd,                    // [ANY] {AVX512_PFI}
+    1013             :     kIdVgatherpf1qps,                    // [ANY] {AVX512_PFI}
+    1014             :     kIdVgatherqpd,                       // [ANY] {AVX2|AVX512_F+VL}
+    1015             :     kIdVgatherqps,                       // [ANY] {AVX2|AVX512_F+VL}
+    1016             :     kIdVgetexppd,                        // [ANY] {AVX512_F+VL}
+    1017             :     kIdVgetexpps,                        // [ANY] {AVX512_F+VL}
+    1018             :     kIdVgetexpsd,                        // [ANY] {AVX512_F}
+    1019             :     kIdVgetexpss,                        // [ANY] {AVX512_F}
+    1020             :     kIdVgetmantpd,                       // [ANY] {AVX512_F+VL}
+    1021             :     kIdVgetmantps,                       // [ANY] {AVX512_F+VL}
+    1022             :     kIdVgetmantsd,                       // [ANY] {AVX512_F}
+    1023             :     kIdVgetmantss,                       // [ANY] {AVX512_F}
+    1024             :     kIdVhaddpd,                          // [ANY] {AVX}
+    1025             :     kIdVhaddps,                          // [ANY] {AVX}
+    1026             :     kIdVhsubpd,                          // [ANY] {AVX}
+    1027             :     kIdVhsubps,                          // [ANY] {AVX}
+    1028             :     kIdVinsertf128,                      // [ANY] {AVX}
+    1029             :     kIdVinsertf32x4,                     // [ANY] {AVX512_F+VL}
+    1030             :     kIdVinsertf32x8,                     // [ANY] {AVX512_DQ}
+    1031             :     kIdVinsertf64x2,                     // [ANY] {AVX512_DQ+VL}
+    1032             :     kIdVinsertf64x4,                     // [ANY] {AVX512_F}
+    1033             :     kIdVinserti128,                      // [ANY] {AVX2}
+    1034             :     kIdVinserti32x4,                     // [ANY] {AVX512_F+VL}
+    1035             :     kIdVinserti32x8,                     // [ANY] {AVX512_DQ}
+    1036             :     kIdVinserti64x2,                     // [ANY] {AVX512_DQ+VL}
+    1037             :     kIdVinserti64x4,                     // [ANY] {AVX512_F}
+    1038             :     kIdVinsertps,                        // [ANY] {AVX|AVX512_F}
+    1039             :     kIdVlddqu,                           // [ANY] {AVX}
+    1040             :     kIdVldmxcsr,                         // [ANY] {AVX}
+    1041             :     kIdVmaskmovdqu,                      // [ANY] {AVX}
+    1042             :     kIdVmaskmovpd,                       // [ANY] {AVX}
+    1043             :     kIdVmaskmovps,                       // [ANY] {AVX}
+    1044             :     kIdVmaxpd,                           // [ANY] {AVX|AVX512_F+VL}
+    1045             :     kIdVmaxps,                           // [ANY] {AVX|AVX512_F+VL}
+    1046             :     kIdVmaxsd,                           // [ANY] {AVX|AVX512_F+VL}
+    1047             :     kIdVmaxss,                           // [ANY] {AVX|AVX512_F+VL}
+    1048             :     kIdVminpd,                           // [ANY] {AVX|AVX512_F+VL}
+    1049             :     kIdVminps,                           // [ANY] {AVX|AVX512_F+VL}
+    1050             :     kIdVminsd,                           // [ANY] {AVX|AVX512_F+VL}
+    1051             :     kIdVminss,                           // [ANY] {AVX|AVX512_F+VL}
+    1052             :     kIdVmovapd,                          // [ANY] {AVX|AVX512_F+VL}
+    1053             :     kIdVmovaps,                          // [ANY] {AVX|AVX512_F+VL}
+    1054             :     kIdVmovd,                            // [ANY] {AVX|AVX512_F}
+    1055             :     kIdVmovddup,                         // [ANY] {AVX|AVX512_F+VL}
+    1056             :     kIdVmovdqa,                          // [ANY] {AVX}
+    1057             :     kIdVmovdqa32,                        // [ANY] {AVX512_F+VL}
+    1058             :     kIdVmovdqa64,                        // [ANY] {AVX512_F+VL}
+    1059             :     kIdVmovdqu,                          // [ANY] {AVX}
+    1060             :     kIdVmovdqu16,                        // [ANY] {AVX512_BW+VL}
+    1061             :     kIdVmovdqu32,                        // [ANY] {AVX512_F+VL}
+    1062             :     kIdVmovdqu64,                        // [ANY] {AVX512_F+VL}
+    1063             :     kIdVmovdqu8,                         // [ANY] {AVX512_BW+VL}
+    1064             :     kIdVmovhlps,                         // [ANY] {AVX|AVX512_F}
+    1065             :     kIdVmovhpd,                          // [ANY] {AVX|AVX512_F}
+    1066             :     kIdVmovhps,                          // [ANY] {AVX|AVX512_F}
+    1067             :     kIdVmovlhps,                         // [ANY] {AVX|AVX512_F}
+    1068             :     kIdVmovlpd,                          // [ANY] {AVX|AVX512_F}
+    1069             :     kIdVmovlps,                          // [ANY] {AVX|AVX512_F}
+    1070             :     kIdVmovmskpd,                        // [ANY] {AVX}
+    1071             :     kIdVmovmskps,                        // [ANY] {AVX}
+    1072             :     kIdVmovntdq,                         // [ANY] {AVX|AVX512_F+VL}
+    1073             :     kIdVmovntdqa,                        // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1074             :     kIdVmovntpd,                         // [ANY] {AVX|AVX512_F+VL}
+    1075             :     kIdVmovntps,                         // [ANY] {AVX|AVX512_F+VL}
+    1076             :     kIdVmovq,                            // [ANY] {AVX|AVX512_F}
+    1077             :     kIdVmovsd,                           // [ANY] {AVX|AVX512_F}
+    1078             :     kIdVmovshdup,                        // [ANY] {AVX|AVX512_F+VL}
+    1079             :     kIdVmovsldup,                        // [ANY] {AVX|AVX512_F+VL}
+    1080             :     kIdVmovss,                           // [ANY] {AVX|AVX512_F}
+    1081             :     kIdVmovupd,                          // [ANY] {AVX|AVX512_F+VL}
+    1082             :     kIdVmovups,                          // [ANY] {AVX|AVX512_F+VL}
+    1083             :     kIdVmpsadbw,                         // [ANY] {AVX|AVX2}
+    1084             :     kIdVmulpd,                           // [ANY] {AVX|AVX512_F+VL}
+    1085             :     kIdVmulps,                           // [ANY] {AVX|AVX512_F+VL}
+    1086             :     kIdVmulsd,                           // [ANY] {AVX|AVX512_F}
+    1087             :     kIdVmulss,                           // [ANY] {AVX|AVX512_F}
+    1088             :     kIdVorpd,                            // [ANY] {AVX|AVX512_DQ+VL}
+    1089             :     kIdVorps,                            // [ANY] {AVX|AVX512_F+VL}
+    1090             :     kIdVp4dpwssd,                        // [ANY] {AVX512_4VNNIW}
+    1091             :     kIdVp4dpwssds,                       // [ANY] {AVX512_4VNNIW}
+    1092             :     kIdVpabsb,                           // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1093             :     kIdVpabsd,                           // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1094             :     kIdVpabsq,                           // [ANY] {AVX512_F+VL}
+    1095             :     kIdVpabsw,                           // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1096             :     kIdVpackssdw,                        // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1097             :     kIdVpacksswb,                        // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1098             :     kIdVpackusdw,                        // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1099             :     kIdVpackuswb,                        // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1100             :     kIdVpaddb,                           // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1101             :     kIdVpaddd,                           // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1102             :     kIdVpaddq,                           // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1103             :     kIdVpaddsb,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1104             :     kIdVpaddsw,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1105             :     kIdVpaddusb,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1106             :     kIdVpaddusw,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1107             :     kIdVpaddw,                           // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1108             :     kIdVpalignr,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1109             :     kIdVpand,                            // [ANY] {AVX|AVX2}
+    1110             :     kIdVpandd,                           // [ANY] {AVX512_F+VL}
+    1111             :     kIdVpandn,                           // [ANY] {AVX|AVX2}
+    1112             :     kIdVpandnd,                          // [ANY] {AVX512_F+VL}
+    1113             :     kIdVpandnq,                          // [ANY] {AVX512_F+VL}
+    1114             :     kIdVpandq,                           // [ANY] {AVX512_F+VL}
+    1115             :     kIdVpavgb,                           // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1116             :     kIdVpavgw,                           // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1117             :     kIdVpblendd,                         // [ANY] {AVX2}
+    1118             :     kIdVpblendvb,                        // [ANY] {AVX|AVX2}
+    1119             :     kIdVpblendw,                         // [ANY] {AVX|AVX2}
+    1120             :     kIdVpbroadcastb,                     // [ANY] {AVX2|AVX512_BW+VL}
+    1121             :     kIdVpbroadcastd,                     // [ANY] {AVX2|AVX512_F+VL}
+    1122             :     kIdVpbroadcastmb2d,                  // [ANY] {AVX512_CDI+VL}
+    1123             :     kIdVpbroadcastmb2q,                  // [ANY] {AVX512_CDI+VL}
+    1124             :     kIdVpbroadcastq,                     // [ANY] {AVX2|AVX512_F+VL}
+    1125             :     kIdVpbroadcastw,                     // [ANY] {AVX2|AVX512_BW+VL}
+    1126             :     kIdVpclmulqdq,                       // [ANY] {AVX|PCLMULQDQ}
+    1127             :     kIdVpcmov,                           // [ANY] {XOP}
+    1128             :     kIdVpcmpb,                           // [ANY] {AVX512_BW+VL}
+    1129             :     kIdVpcmpd,                           // [ANY] {AVX512_F+VL}
+    1130             :     kIdVpcmpeqb,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1131             :     kIdVpcmpeqd,                         // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1132             :     kIdVpcmpeqq,                         // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1133             :     kIdVpcmpeqw,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1134             :     kIdVpcmpestri,                       // [ANY] {AVX}
+    1135             :     kIdVpcmpestrm,                       // [ANY] {AVX}
+    1136             :     kIdVpcmpgtb,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1137             :     kIdVpcmpgtd,                         // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1138             :     kIdVpcmpgtq,                         // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1139             :     kIdVpcmpgtw,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1140             :     kIdVpcmpistri,                       // [ANY] {AVX}
+    1141             :     kIdVpcmpistrm,                       // [ANY] {AVX}
+    1142             :     kIdVpcmpq,                           // [ANY] {AVX512_F+VL}
+    1143             :     kIdVpcmpub,                          // [ANY] {AVX512_BW+VL}
+    1144             :     kIdVpcmpud,                          // [ANY] {AVX512_F+VL}
+    1145             :     kIdVpcmpuq,                          // [ANY] {AVX512_F+VL}
+    1146             :     kIdVpcmpuw,                          // [ANY] {AVX512_BW+VL}
+    1147             :     kIdVpcmpw,                           // [ANY] {AVX512_BW+VL}
+    1148             :     kIdVpcomb,                           // [ANY] {XOP}
+    1149             :     kIdVpcomd,                           // [ANY] {XOP}
+    1150             :     kIdVpcompressd,                      // [ANY] {AVX512_F+VL}
+    1151             :     kIdVpcompressq,                      // [ANY] {AVX512_F+VL}
+    1152             :     kIdVpcomq,                           // [ANY] {XOP}
+    1153             :     kIdVpcomub,                          // [ANY] {XOP}
+    1154             :     kIdVpcomud,                          // [ANY] {XOP}
+    1155             :     kIdVpcomuq,                          // [ANY] {XOP}
+    1156             :     kIdVpcomuw,                          // [ANY] {XOP}
+    1157             :     kIdVpcomw,                           // [ANY] {XOP}
+    1158             :     kIdVpconflictd,                      // [ANY] {AVX512_CDI+VL}
+    1159             :     kIdVpconflictq,                      // [ANY] {AVX512_CDI+VL}
+    1160             :     kIdVperm2f128,                       // [ANY] {AVX}
+    1161             :     kIdVperm2i128,                       // [ANY] {AVX2}
+    1162             :     kIdVpermb,                           // [ANY] {AVX512_VBMI+VL}
+    1163             :     kIdVpermd,                           // [ANY] {AVX2|AVX512_F+VL}
+    1164             :     kIdVpermi2b,                         // [ANY] {AVX512_VBMI+VL}
+    1165             :     kIdVpermi2d,                         // [ANY] {AVX512_F+VL}
+    1166             :     kIdVpermi2pd,                        // [ANY] {AVX512_F+VL}
+    1167             :     kIdVpermi2ps,                        // [ANY] {AVX512_F+VL}
+    1168             :     kIdVpermi2q,                         // [ANY] {AVX512_F+VL}
+    1169             :     kIdVpermi2w,                         // [ANY] {AVX512_BW+VL}
+    1170             :     kIdVpermil2pd,                       // [ANY] {XOP}
+    1171             :     kIdVpermil2ps,                       // [ANY] {XOP}
+    1172             :     kIdVpermilpd,                        // [ANY] {AVX|AVX512_F+VL}
+    1173             :     kIdVpermilps,                        // [ANY] {AVX|AVX512_F+VL}
+    1174             :     kIdVpermpd,                          // [ANY] {AVX2}
+    1175             :     kIdVpermps,                          // [ANY] {AVX2}
+    1176             :     kIdVpermq,                           // [ANY] {AVX2|AVX512_F+VL}
+    1177             :     kIdVpermt2b,                         // [ANY] {AVX512_VBMI+VL}
+    1178             :     kIdVpermt2d,                         // [ANY] {AVX512_F+VL}
+    1179             :     kIdVpermt2pd,                        // [ANY] {AVX512_F+VL}
+    1180             :     kIdVpermt2ps,                        // [ANY] {AVX512_F+VL}
+    1181             :     kIdVpermt2q,                         // [ANY] {AVX512_F+VL}
+    1182             :     kIdVpermt2w,                         // [ANY] {AVX512_BW+VL}
+    1183             :     kIdVpermw,                           // [ANY] {AVX512_BW+VL}
+    1184             :     kIdVpexpandd,                        // [ANY] {AVX512_F+VL}
+    1185             :     kIdVpexpandq,                        // [ANY] {AVX512_F+VL}
+    1186             :     kIdVpextrb,                          // [ANY] {AVX|AVX512_BW}
+    1187             :     kIdVpextrd,                          // [ANY] {AVX|AVX512_DQ}
+    1188             :     kIdVpextrq,                          // [X64] {AVX|AVX512_DQ}
+    1189             :     kIdVpextrw,                          // [ANY] {AVX|AVX512_BW}
+    1190             :     kIdVpgatherdd,                       // [ANY] {AVX2|AVX512_F+VL}
+    1191             :     kIdVpgatherdq,                       // [ANY] {AVX2|AVX512_F+VL}
+    1192             :     kIdVpgatherqd,                       // [ANY] {AVX2|AVX512_F+VL}
+    1193             :     kIdVpgatherqq,                       // [ANY] {AVX2|AVX512_F+VL}
+    1194             :     kIdVphaddbd,                         // [ANY] {XOP}
+    1195             :     kIdVphaddbq,                         // [ANY] {XOP}
+    1196             :     kIdVphaddbw,                         // [ANY] {XOP}
+    1197             :     kIdVphaddd,                          // [ANY] {AVX|AVX2}
+    1198             :     kIdVphadddq,                         // [ANY] {XOP}
+    1199             :     kIdVphaddsw,                         // [ANY] {AVX|AVX2}
+    1200             :     kIdVphaddubd,                        // [ANY] {XOP}
+    1201             :     kIdVphaddubq,                        // [ANY] {XOP}
+    1202             :     kIdVphaddubw,                        // [ANY] {XOP}
+    1203             :     kIdVphaddudq,                        // [ANY] {XOP}
+    1204             :     kIdVphadduwd,                        // [ANY] {XOP}
+    1205             :     kIdVphadduwq,                        // [ANY] {XOP}
+    1206             :     kIdVphaddw,                          // [ANY] {AVX|AVX2}
+    1207             :     kIdVphaddwd,                         // [ANY] {XOP}
+    1208             :     kIdVphaddwq,                         // [ANY] {XOP}
+    1209             :     kIdVphminposuw,                      // [ANY] {AVX}
+    1210             :     kIdVphsubbw,                         // [ANY] {XOP}
+    1211             :     kIdVphsubd,                          // [ANY] {AVX|AVX2}
+    1212             :     kIdVphsubdq,                         // [ANY] {XOP}
+    1213             :     kIdVphsubsw,                         // [ANY] {AVX|AVX2}
+    1214             :     kIdVphsubw,                          // [ANY] {AVX|AVX2}
+    1215             :     kIdVphsubwd,                         // [ANY] {XOP}
+    1216             :     kIdVpinsrb,                          // [ANY] {AVX|AVX512_BW}
+    1217             :     kIdVpinsrd,                          // [ANY] {AVX|AVX512_DQ}
+    1218             :     kIdVpinsrq,                          // [X64] {AVX|AVX512_DQ}
+    1219             :     kIdVpinsrw,                          // [ANY] {AVX|AVX512_BW}
+    1220             :     kIdVplzcntd,                         // [ANY] {AVX512_CDI+VL}
+    1221             :     kIdVplzcntq,                         // [ANY] {AVX512_CDI+VL}
+    1222             :     kIdVpmacsdd,                         // [ANY] {XOP}
+    1223             :     kIdVpmacsdqh,                        // [ANY] {XOP}
+    1224             :     kIdVpmacsdql,                        // [ANY] {XOP}
+    1225             :     kIdVpmacssdd,                        // [ANY] {XOP}
+    1226             :     kIdVpmacssdqh,                       // [ANY] {XOP}
+    1227             :     kIdVpmacssdql,                       // [ANY] {XOP}
+    1228             :     kIdVpmacsswd,                        // [ANY] {XOP}
+    1229             :     kIdVpmacssww,                        // [ANY] {XOP}
+    1230             :     kIdVpmacswd,                         // [ANY] {XOP}
+    1231             :     kIdVpmacsww,                         // [ANY] {XOP}
+    1232             :     kIdVpmadcsswd,                       // [ANY] {XOP}
+    1233             :     kIdVpmadcswd,                        // [ANY] {XOP}
+    1234             :     kIdVpmadd52huq,                      // [ANY] {AVX512_IFMA+VL}
+    1235             :     kIdVpmadd52luq,                      // [ANY] {AVX512_IFMA+VL}
+    1236             :     kIdVpmaddubsw,                       // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1237             :     kIdVpmaddwd,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1238             :     kIdVpmaskmovd,                       // [ANY] {AVX2}
+    1239             :     kIdVpmaskmovq,                       // [ANY] {AVX2}
+    1240             :     kIdVpmaxsb,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1241             :     kIdVpmaxsd,                          // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1242             :     kIdVpmaxsq,                          // [ANY] {AVX512_F+VL}
+    1243             :     kIdVpmaxsw,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1244             :     kIdVpmaxub,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1245             :     kIdVpmaxud,                          // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1246             :     kIdVpmaxuq,                          // [ANY] {AVX512_F+VL}
+    1247             :     kIdVpmaxuw,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1248             :     kIdVpminsb,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1249             :     kIdVpminsd,                          // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1250             :     kIdVpminsq,                          // [ANY] {AVX512_F+VL}
+    1251             :     kIdVpminsw,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1252             :     kIdVpminub,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1253             :     kIdVpminud,                          // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1254             :     kIdVpminuq,                          // [ANY] {AVX512_F+VL}
+    1255             :     kIdVpminuw,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1256             :     kIdVpmovb2m,                         // [ANY] {AVX512_BW+VL}
+    1257             :     kIdVpmovd2m,                         // [ANY] {AVX512_DQ+VL}
+    1258             :     kIdVpmovdb,                          // [ANY] {AVX512_F+VL}
+    1259             :     kIdVpmovdw,                          // [ANY] {AVX512_F+VL}
+    1260             :     kIdVpmovm2b,                         // [ANY] {AVX512_BW+VL}
+    1261             :     kIdVpmovm2d,                         // [ANY] {AVX512_DQ+VL}
+    1262             :     kIdVpmovm2q,                         // [ANY] {AVX512_DQ+VL}
+    1263             :     kIdVpmovm2w,                         // [ANY] {AVX512_BW+VL}
+    1264             :     kIdVpmovmskb,                        // [ANY] {AVX|AVX2}
+    1265             :     kIdVpmovq2m,                         // [ANY] {AVX512_DQ+VL}
+    1266             :     kIdVpmovqb,                          // [ANY] {AVX512_F+VL}
+    1267             :     kIdVpmovqd,                          // [ANY] {AVX512_F+VL}
+    1268             :     kIdVpmovqw,                          // [ANY] {AVX512_F+VL}
+    1269             :     kIdVpmovsdb,                         // [ANY] {AVX512_F+VL}
+    1270             :     kIdVpmovsdw,                         // [ANY] {AVX512_F+VL}
+    1271             :     kIdVpmovsqb,                         // [ANY] {AVX512_F+VL}
+    1272             :     kIdVpmovsqd,                         // [ANY] {AVX512_F+VL}
+    1273             :     kIdVpmovsqw,                         // [ANY] {AVX512_F+VL}
+    1274             :     kIdVpmovswb,                         // [ANY] {AVX512_BW+VL}
+    1275             :     kIdVpmovsxbd,                        // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1276             :     kIdVpmovsxbq,                        // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1277             :     kIdVpmovsxbw,                        // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1278             :     kIdVpmovsxdq,                        // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1279             :     kIdVpmovsxwd,                        // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1280             :     kIdVpmovsxwq,                        // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1281             :     kIdVpmovusdb,                        // [ANY] {AVX512_F+VL}
+    1282             :     kIdVpmovusdw,                        // [ANY] {AVX512_F+VL}
+    1283             :     kIdVpmovusqb,                        // [ANY] {AVX512_F+VL}
+    1284             :     kIdVpmovusqd,                        // [ANY] {AVX512_F+VL}
+    1285             :     kIdVpmovusqw,                        // [ANY] {AVX512_F+VL}
+    1286             :     kIdVpmovuswb,                        // [ANY] {AVX512_BW+VL}
+    1287             :     kIdVpmovw2m,                         // [ANY] {AVX512_BW+VL}
+    1288             :     kIdVpmovwb,                          // [ANY] {AVX512_BW+VL}
+    1289             :     kIdVpmovzxbd,                        // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1290             :     kIdVpmovzxbq,                        // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1291             :     kIdVpmovzxbw,                        // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1292             :     kIdVpmovzxdq,                        // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1293             :     kIdVpmovzxwd,                        // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1294             :     kIdVpmovzxwq,                        // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1295             :     kIdVpmuldq,                          // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1296             :     kIdVpmulhrsw,                        // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1297             :     kIdVpmulhuw,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1298             :     kIdVpmulhw,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1299             :     kIdVpmulld,                          // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1300             :     kIdVpmullq,                          // [ANY] {AVX512_DQ+VL}
+    1301             :     kIdVpmullw,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1302             :     kIdVpmultishiftqb,                   // [ANY] {AVX512_VBMI+VL}
+    1303             :     kIdVpmuludq,                         // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1304             :     kIdVpopcntd,                         // [ANY] {AVX512_VPOPCNTDQ}
+    1305             :     kIdVpopcntq,                         // [ANY] {AVX512_VPOPCNTDQ}
+    1306             :     kIdVpor,                             // [ANY] {AVX|AVX2}
+    1307             :     kIdVpord,                            // [ANY] {AVX512_F+VL}
+    1308             :     kIdVporq,                            // [ANY] {AVX512_F+VL}
+    1309             :     kIdVpperm,                           // [ANY] {XOP}
+    1310             :     kIdVprold,                           // [ANY] {AVX512_F+VL}
+    1311             :     kIdVprolq,                           // [ANY] {AVX512_F+VL}
+    1312             :     kIdVprolvd,                          // [ANY] {AVX512_F+VL}
+    1313             :     kIdVprolvq,                          // [ANY] {AVX512_F+VL}
+    1314             :     kIdVprord,                           // [ANY] {AVX512_F+VL}
+    1315             :     kIdVprorq,                           // [ANY] {AVX512_F+VL}
+    1316             :     kIdVprorvd,                          // [ANY] {AVX512_F+VL}
+    1317             :     kIdVprorvq,                          // [ANY] {AVX512_F+VL}
+    1318             :     kIdVprotb,                           // [ANY] {XOP}
+    1319             :     kIdVprotd,                           // [ANY] {XOP}
+    1320             :     kIdVprotq,                           // [ANY] {XOP}
+    1321             :     kIdVprotw,                           // [ANY] {XOP}
+    1322             :     kIdVpsadbw,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1323             :     kIdVpscatterdd,                      // [ANY] {AVX512_F+VL}
+    1324             :     kIdVpscatterdq,                      // [ANY] {AVX512_F+VL}
+    1325             :     kIdVpscatterqd,                      // [ANY] {AVX512_F+VL}
+    1326             :     kIdVpscatterqq,                      // [ANY] {AVX512_F+VL}
+    1327             :     kIdVpshab,                           // [ANY] {XOP}
+    1328             :     kIdVpshad,                           // [ANY] {XOP}
+    1329             :     kIdVpshaq,                           // [ANY] {XOP}
+    1330             :     kIdVpshaw,                           // [ANY] {XOP}
+    1331             :     kIdVpshlb,                           // [ANY] {XOP}
+    1332             :     kIdVpshld,                           // [ANY] {XOP}
+    1333             :     kIdVpshlq,                           // [ANY] {XOP}
+    1334             :     kIdVpshlw,                           // [ANY] {XOP}
+    1335             :     kIdVpshufb,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1336             :     kIdVpshufd,                          // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1337             :     kIdVpshufhw,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1338             :     kIdVpshuflw,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1339             :     kIdVpsignb,                          // [ANY] {AVX|AVX2}
+    1340             :     kIdVpsignd,                          // [ANY] {AVX|AVX2}
+    1341             :     kIdVpsignw,                          // [ANY] {AVX|AVX2}
+    1342             :     kIdVpslld,                           // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1343             :     kIdVpslldq,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1344             :     kIdVpsllq,                           // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1345             :     kIdVpsllvd,                          // [ANY] {AVX2|AVX512_F+VL}
+    1346             :     kIdVpsllvq,                          // [ANY] {AVX2|AVX512_F+VL}
+    1347             :     kIdVpsllvw,                          // [ANY] {AVX512_BW+VL}
+    1348             :     kIdVpsllw,                           // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1349             :     kIdVpsrad,                           // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1350             :     kIdVpsraq,                           // [ANY] {AVX512_F+VL}
+    1351             :     kIdVpsravd,                          // [ANY] {AVX2|AVX512_F+VL}
+    1352             :     kIdVpsravq,                          // [ANY] {AVX512_F+VL}
+    1353             :     kIdVpsravw,                          // [ANY] {AVX512_BW+VL}
+    1354             :     kIdVpsraw,                           // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1355             :     kIdVpsrld,                           // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1356             :     kIdVpsrldq,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1357             :     kIdVpsrlq,                           // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1358             :     kIdVpsrlvd,                          // [ANY] {AVX2|AVX512_F+VL}
+    1359             :     kIdVpsrlvq,                          // [ANY] {AVX2|AVX512_F+VL}
+    1360             :     kIdVpsrlvw,                          // [ANY] {AVX512_BW+VL}
+    1361             :     kIdVpsrlw,                           // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1362             :     kIdVpsubb,                           // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1363             :     kIdVpsubd,                           // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1364             :     kIdVpsubq,                           // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1365             :     kIdVpsubsb,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1366             :     kIdVpsubsw,                          // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1367             :     kIdVpsubusb,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1368             :     kIdVpsubusw,                         // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1369             :     kIdVpsubw,                           // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1370             :     kIdVpternlogd,                       // [ANY] {AVX512_F+VL}
+    1371             :     kIdVpternlogq,                       // [ANY] {AVX512_F+VL}
+    1372             :     kIdVptest,                           // [ANY] {AVX}
+    1373             :     kIdVptestmb,                         // [ANY] {AVX512_BW+VL}
+    1374             :     kIdVptestmd,                         // [ANY] {AVX512_F+VL}
+    1375             :     kIdVptestmq,                         // [ANY] {AVX512_F+VL}
+    1376             :     kIdVptestmw,                         // [ANY] {AVX512_BW+VL}
+    1377             :     kIdVptestnmb,                        // [ANY] {AVX512_BW+VL}
+    1378             :     kIdVptestnmd,                        // [ANY] {AVX512_F+VL}
+    1379             :     kIdVptestnmq,                        // [ANY] {AVX512_F+VL}
+    1380             :     kIdVptestnmw,                        // [ANY] {AVX512_BW+VL}
+    1381             :     kIdVpunpckhbw,                       // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1382             :     kIdVpunpckhdq,                       // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1383             :     kIdVpunpckhqdq,                      // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1384             :     kIdVpunpckhwd,                       // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1385             :     kIdVpunpcklbw,                       // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1386             :     kIdVpunpckldq,                       // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1387             :     kIdVpunpcklqdq,                      // [ANY] {AVX|AVX2|AVX512_F+VL}
+    1388             :     kIdVpunpcklwd,                       // [ANY] {AVX|AVX2|AVX512_BW+VL}
+    1389             :     kIdVpxor,                            // [ANY] {AVX|AVX2}
+    1390             :     kIdVpxord,                           // [ANY] {AVX512_F+VL}
+    1391             :     kIdVpxorq,                           // [ANY] {AVX512_F+VL}
+    1392             :     kIdVrangepd,                         // [ANY] {AVX512_DQ+VL}
+    1393             :     kIdVrangeps,                         // [ANY] {AVX512_DQ+VL}
+    1394             :     kIdVrangesd,                         // [ANY] {AVX512_DQ}
+    1395             :     kIdVrangess,                         // [ANY] {AVX512_DQ}
+    1396             :     kIdVrcp14pd,                         // [ANY] {AVX512_F+VL}
+    1397             :     kIdVrcp14ps,                         // [ANY] {AVX512_F+VL}
+    1398             :     kIdVrcp14sd,                         // [ANY] {AVX512_F}
+    1399             :     kIdVrcp14ss,                         // [ANY] {AVX512_F}
+    1400             :     kIdVrcp28pd,                         // [ANY] {AVX512_ERI}
+    1401             :     kIdVrcp28ps,                         // [ANY] {AVX512_ERI}
+    1402             :     kIdVrcp28sd,                         // [ANY] {AVX512_ERI}
+    1403             :     kIdVrcp28ss,                         // [ANY] {AVX512_ERI}
+    1404             :     kIdVrcpps,                           // [ANY] {AVX}
+    1405             :     kIdVrcpss,                           // [ANY] {AVX}
+    1406             :     kIdVreducepd,                        // [ANY] {AVX512_DQ+VL}
+    1407             :     kIdVreduceps,                        // [ANY] {AVX512_DQ+VL}
+    1408             :     kIdVreducesd,                        // [ANY] {AVX512_DQ}
+    1409             :     kIdVreducess,                        // [ANY] {AVX512_DQ}
+    1410             :     kIdVrndscalepd,                      // [ANY] {AVX512_F+VL}
+    1411             :     kIdVrndscaleps,                      // [ANY] {AVX512_F+VL}
+    1412             :     kIdVrndscalesd,                      // [ANY] {AVX512_F}
+    1413             :     kIdVrndscaless,                      // [ANY] {AVX512_F}
+    1414             :     kIdVroundpd,                         // [ANY] {AVX}
+    1415             :     kIdVroundps,                         // [ANY] {AVX}
+    1416             :     kIdVroundsd,                         // [ANY] {AVX}
+    1417             :     kIdVroundss,                         // [ANY] {AVX}
+    1418             :     kIdVrsqrt14pd,                       // [ANY] {AVX512_F+VL}
+    1419             :     kIdVrsqrt14ps,                       // [ANY] {AVX512_F+VL}
+    1420             :     kIdVrsqrt14sd,                       // [ANY] {AVX512_F}
+    1421             :     kIdVrsqrt14ss,                       // [ANY] {AVX512_F}
+    1422             :     kIdVrsqrt28pd,                       // [ANY] {AVX512_ERI}
+    1423             :     kIdVrsqrt28ps,                       // [ANY] {AVX512_ERI}
+    1424             :     kIdVrsqrt28sd,                       // [ANY] {AVX512_ERI}
+    1425             :     kIdVrsqrt28ss,                       // [ANY] {AVX512_ERI}
+    1426             :     kIdVrsqrtps,                         // [ANY] {AVX}
+    1427             :     kIdVrsqrtss,                         // [ANY] {AVX}
+    1428             :     kIdVscalefpd,                        // [ANY] {AVX512_F+VL}
+    1429             :     kIdVscalefps,                        // [ANY] {AVX512_F+VL}
+    1430             :     kIdVscalefsd,                        // [ANY] {AVX512_F}
+    1431             :     kIdVscalefss,                        // [ANY] {AVX512_F}
+    1432             :     kIdVscatterdpd,                      // [ANY] {AVX512_F+VL}
+    1433             :     kIdVscatterdps,                      // [ANY] {AVX512_F+VL}
+    1434             :     kIdVscatterpf0dpd,                   // [ANY] {AVX512_PFI}
+    1435             :     kIdVscatterpf0dps,                   // [ANY] {AVX512_PFI}
+    1436             :     kIdVscatterpf0qpd,                   // [ANY] {AVX512_PFI}
+    1437             :     kIdVscatterpf0qps,                   // [ANY] {AVX512_PFI}
+    1438             :     kIdVscatterpf1dpd,                   // [ANY] {AVX512_PFI}
+    1439             :     kIdVscatterpf1dps,                   // [ANY] {AVX512_PFI}
+    1440             :     kIdVscatterpf1qpd,                   // [ANY] {AVX512_PFI}
+    1441             :     kIdVscatterpf1qps,                   // [ANY] {AVX512_PFI}
+    1442             :     kIdVscatterqpd,                      // [ANY] {AVX512_F+VL}
+    1443             :     kIdVscatterqps,                      // [ANY] {AVX512_F+VL}
+    1444             :     kIdVshuff32x4,                       // [ANY] {AVX512_F+VL}
+    1445             :     kIdVshuff64x2,                       // [ANY] {AVX512_F+VL}
+    1446             :     kIdVshufi32x4,                       // [ANY] {AVX512_F+VL}
+    1447             :     kIdVshufi64x2,                       // [ANY] {AVX512_F+VL}
+    1448             :     kIdVshufpd,                          // [ANY] {AVX|AVX512_F+VL}
+    1449             :     kIdVshufps,                          // [ANY] {AVX|AVX512_F+VL}
+    1450             :     kIdVsqrtpd,                          // [ANY] {AVX|AVX512_F+VL}
+    1451             :     kIdVsqrtps,                          // [ANY] {AVX|AVX512_F+VL}
+    1452             :     kIdVsqrtsd,                          // [ANY] {AVX|AVX512_F}
+    1453             :     kIdVsqrtss,                          // [ANY] {AVX|AVX512_F}
+    1454             :     kIdVstmxcsr,                         // [ANY] {AVX}
+    1455             :     kIdVsubpd,                           // [ANY] {AVX|AVX512_F+VL}
+    1456             :     kIdVsubps,                           // [ANY] {AVX|AVX512_F+VL}
+    1457             :     kIdVsubsd,                           // [ANY] {AVX|AVX512_F}
+    1458             :     kIdVsubss,                           // [ANY] {AVX|AVX512_F}
+    1459             :     kIdVtestpd,                          // [ANY] {AVX}
+    1460             :     kIdVtestps,                          // [ANY] {AVX}
+    1461             :     kIdVucomisd,                         // [ANY] {AVX|AVX512_F}
+    1462             :     kIdVucomiss,                         // [ANY] {AVX|AVX512_F}
+    1463             :     kIdVunpckhpd,                        // [ANY] {AVX|AVX512_F+VL}
+    1464             :     kIdVunpckhps,                        // [ANY] {AVX|AVX512_F+VL}
+    1465             :     kIdVunpcklpd,                        // [ANY] {AVX|AVX512_F+VL}
+    1466             :     kIdVunpcklps,                        // [ANY] {AVX|AVX512_F+VL}
+    1467             :     kIdVxorpd,                           // [ANY] {AVX|AVX512_DQ+VL}
+    1468             :     kIdVxorps,                           // [ANY] {AVX|AVX512_DQ+VL}
+    1469             :     kIdVzeroall,                         // [ANY] {AVX}
+    1470             :     kIdVzeroupper,                       // [ANY] {AVX}
+    1471             :     kIdWbinvd,                           // [ANY]
+    1472             :     kIdWrfsbase,                         // [X64] {FSGSBASE}
+    1473             :     kIdWrgsbase,                         // [X64] {FSGSBASE}
+    1474             :     kIdWrmsr,                            // [ANY] {MSR}
+    1475             :     kIdXabort,                           // [ANY] {RTM}
+    1476             :     kIdXadd,                             // [ANY] {I486}
+    1477             :     kIdXbegin,                           // [ANY] {RTM}
+    1478             :     kIdXchg,                             // [ANY]
+    1479             :     kIdXend,                             // [ANY] {RTM}
+    1480             :     kIdXgetbv,                           // [ANY] {XSAVE}
+    1481             :     kIdXlatb,                            // [ANY]
+    1482             :     kIdXor,                              // [ANY]
+    1483             :     kIdXorpd,                            // [ANY] {SSE2}
+    1484             :     kIdXorps,                            // [ANY] {SSE}
+    1485             :     kIdXrstor,                           // [ANY] {XSAVE}
+    1486             :     kIdXrstor64,                         // [X64] {XSAVE}
+    1487             :     kIdXrstors,                          // [ANY] {XSAVES}
+    1488             :     kIdXrstors64,                        // [X64] {XSAVES}
+    1489             :     kIdXsave,                            // [ANY] {XSAVE}
+    1490             :     kIdXsave64,                          // [X64] {XSAVE}
+    1491             :     kIdXsavec,                           // [ANY] {XSAVEC}
+    1492             :     kIdXsavec64,                         // [X64] {XSAVEC}
+    1493             :     kIdXsaveopt,                         // [ANY] {XSAVEOPT}
+    1494             :     kIdXsaveopt64,                       // [X64] {XSAVEOPT}
+    1495             :     kIdXsaves,                           // [ANY] {XSAVES}
+    1496             :     kIdXsaves64,                         // [X64] {XSAVES}
+    1497             :     kIdXsetbv,                           // [ANY] {XSAVE}
+    1498             :     kIdXtest,                            // [ANY] {TSX}
+    1499             :     _kIdCount
+    1500             :     // ${idData:End}
+    1501             :   };
+    1502             : 
+    1503             :   //! Instruction encodings, used by \ref X86Assembler (AsmJit specific).
+    1504             :   ASMJIT_ENUM(EncodingType) {
+    1505             :     kEncodingNone = 0,                   //!< Never used.
+    1506             :     kEncodingX86Op,                      //!< X86 [OP].
+    1507             :     kEncodingX86Op_O,                    //!< X86 [OP] (opcode and /0-7).
+    1508             :     kEncodingX86Op_O_I8,                 //!< X86 [OP] (opcode and /0-7 + 8-bit immediate).
+    1509             :     kEncodingX86Op_xAX,                  //!< X86 [OP] (implicit or explicit '?AX' form).
+    1510             :     kEncodingX86Op_xDX_xAX,              //!< X86 [OP] (implicit or explicit '?DX, ?AX' form).
+    1511             :     kEncodingX86Op_ZAX,                  //!< X86 [OP] (implicit or explicit '[EAX|RDX]' form).
+    1512             :     kEncodingX86I_xAX,                   //!< X86 [I] (implicit or explicit '?AX' form).
+    1513             :     kEncodingX86M,                       //!< X86 [M] (handles 2|4|8-bytes size).
+    1514             :     kEncodingX86M_GPB,                   //!< X86 [M] (handles single-byte size).
+    1515             :     kEncodingX86M_GPB_MulDiv,            //!< X86 [M] (like GPB, handles implicit|explicit MUL|DIV|IDIV).
+    1516             :     kEncodingX86M_Only,                  //!< X86 [M] (restricted to memory operand of any size).
+    1517             :     kEncodingX86Rm,                      //!< X86 [RM] (doesn't handle single-byte size).
+    1518             :     kEncodingX86Rm_Raw66H,               //!< X86 [RM] (used by LZCNT, POPCNT, and TZCNT).
+    1519             :     kEncodingX86Rm_NoRexW,               //!< X86 [RM] (doesn't add REX.W prefix if 64-bit reg is used).
+    1520             :     kEncodingX86Mr,                      //!< X86 [MR] (doesn't handle single-byte size).
+    1521             :     kEncodingX86Mr_NoSize,               //!< X86 [MR] (doesn't handle any size).
+    1522             :     kEncodingX86Arith,                   //!< X86 adc, add, and, cmp, or, sbb, sub, xor.
+    1523             :     kEncodingX86Bswap,                   //!< X86 bswap.
+    1524             :     kEncodingX86Bt,                      //!< X86 bt, btc, btr, bts.
+    1525             :     kEncodingX86Call,                    //!< X86 call.
+    1526             :     kEncodingX86Cmpxchg,                 //!< X86 [MR] cmpxchg.
+    1527             :     kEncodingX86Crc,                     //!< X86 crc32.
+    1528             :     kEncodingX86Enter,                   //!< X86 enter.
+    1529             :     kEncodingX86Imul,                    //!< X86 imul.
+    1530             :     kEncodingX86In,                      //!< X86 in.
+    1531             :     kEncodingX86Ins,                     //!< X86 ins[b|q|d].
+    1532             :     kEncodingX86IncDec,                  //!< X86 inc, dec.
+    1533             :     kEncodingX86Int,                     //!< X86 int (interrupt).
+    1534             :     kEncodingX86Jcc,                     //!< X86 jcc.
+    1535             :     kEncodingX86JecxzLoop,               //!< X86 jcxz, jecxz, jrcxz, loop, loope, loopne.
+    1536             :     kEncodingX86Jmp,                     //!< X86 jmp.
+    1537             :     kEncodingX86JmpRel,                  //!< X86 xbegin.
+    1538             :     kEncodingX86Lea,                     //!< X86 lea.
+    1539             :     kEncodingX86Mov,                     //!< X86 mov (all possible cases).
+    1540             :     kEncodingX86MovsxMovzx,              //!< X86 movsx, movzx.
+    1541             :     kEncodingX86Out,                     //!< X86 out.
+    1542             :     kEncodingX86Outs,                    //!< X86 out[b|q|d].
+    1543             :     kEncodingX86Push,                    //!< X86 push.
+    1544             :     kEncodingX86Pop,                     //!< X86 pop.
+    1545             :     kEncodingX86Ret,                     //!< X86 ret.
+    1546             :     kEncodingX86Rot,                     //!< X86 rcl, rcr, rol, ror, sal, sar, shl, shr.
+    1547             :     kEncodingX86Set,                     //!< X86 setcc.
+    1548             :     kEncodingX86ShldShrd,                //!< X86 shld, shrd.
+    1549             :     kEncodingX86StrRm,                   //!< X86 lods.
+    1550             :     kEncodingX86StrMr,                   //!< X86 scas, stos.
+    1551             :     kEncodingX86StrMm,                   //!< X86 cmps, movs.
+    1552             :     kEncodingX86Test,                    //!< X86 test.
+    1553             :     kEncodingX86Xadd,                    //!< X86 xadd.
+    1554             :     kEncodingX86Xchg,                    //!< X86 xchg.
+    1555             :     kEncodingX86Fence,                   //!< X86 lfence, mfence, sfence.
+    1556             :     kEncodingX86Bndmov,                  //!< X86 [RM|MR] (used by BNDMOV).
+    1557             :     kEncodingFpuOp,                      //!< FPU [OP].
+    1558             :     kEncodingFpuArith,                   //!< FPU fadd, fdiv, fdivr, fmul, fsub, fsubr.
+    1559             :     kEncodingFpuCom,                     //!< FPU fcom, fcomp.
+    1560             :     kEncodingFpuFldFst,                  //!< FPU fld, fst, fstp.
+    1561             :     kEncodingFpuM,                       //!< FPU fiadd, ficom, ficomp, fidiv, fidivr, fild, fimul, fist, fistp, fisttp, fisub, fisubr.
+    1562             :     kEncodingFpuR,                       //!< FPU fcmov, fcomi, fcomip, ffree, fucom, fucomi, fucomip, fucomp, fxch.
+    1563             :     kEncodingFpuRDef,                    //!< FPU faddp, fdivp, fdivrp, fmulp, fsubp, fsubrp.
+    1564             :     kEncodingFpuStsw,                    //!< FPU fnstsw, Fstsw.
+    1565             :     kEncodingExtRm,                      //!< EXT [RM].
+    1566             :     kEncodingExtRm_XMM0,                 //!< EXT [RM<XMM0>].
+    1567             :     kEncodingExtRm_ZDI,                  //!< EXT [RM<ZDI>].
+    1568             :     kEncodingExtRm_P,                    //!< EXT [RM] (propagates 66H if the instruction uses XMM register).
+    1569             :     kEncodingExtRm_Wx,                   //!< EXT [RM] (propagates REX.W if GPQ is used).
+    1570             :     kEncodingExtRmRi,                    //!< EXT [RM|RI].
+    1571             :     kEncodingExtRmRi_P,                  //!< EXT [RM|RI] (propagates 66H if the instruction uses XMM register).
+    1572             :     kEncodingExtRmi,                     //!< EXT [RMI].
+    1573             :     kEncodingExtRmi_P,                   //!< EXT [RMI] (propagates 66H if the instruction uses XMM register).
+    1574             :     kEncodingExtPextrw,                  //!< EXT pextrw.
+    1575             :     kEncodingExtExtract,                 //!< EXT pextrb, pextrd, pextrq, extractps.
+    1576             :     kEncodingExtMov,                     //!< EXT mov?? - #1:[MM|XMM, MM|XMM|Mem] #2:[MM|XMM|Mem, MM|XMM].
+    1577             :     kEncodingExtMovnti,                  //!< EXT movnti.
+    1578             :     kEncodingExtMovbe,                   //!< EXT movbe.
+    1579             :     kEncodingExtMovd,                    //!< EXT movd.
+    1580             :     kEncodingExtMovq,                    //!< EXT movq.
+    1581             :     kEncodingExtExtrq,                   //!< EXT extrq (SSE4A).
+    1582             :     kEncodingExtInsertq,                 //!< EXT insrq (SSE4A).
+    1583             :     kEncodingExt3dNow,                   //!< EXT [RMI] (3DNOW specific).
+    1584             :     kEncodingVexOp,                      //!< VEX [OP].
+    1585             :     kEncodingVexKmov,                    //!< VEX [RM|MR] (used by kmov[b|w|d|q]).
+    1586             :     kEncodingVexM,                       //!< VEX|EVEX [M].
+    1587             :     kEncodingVexM_VM,                    //!< VEX|EVEX [M] (propagates VEX|EVEX.L, VSIB support).
+    1588             :     kEncodingVexMr_Lx,                   //!< VEX|EVEX [MR] (propagates VEX|EVEX.L if YMM used).
+    1589             :     kEncodingVexMr_VM,                   //!< VEX|EVEX [MR] (propagates VEX|EVEX.L, VSIB support).
+    1590             :     kEncodingVexMri,                     //!< VEX|EVEX [MRI].
+    1591             :     kEncodingVexMri_Lx,                  //!< VEX|EVEX [MRI] (propagates VEX|EVEX.L if YMM used).
+    1592             :     kEncodingVexRm,                      //!< VEX|EVEX [RM].
+    1593             :     kEncodingVexRm_ZDI,                  //!< VEX|EVEX [RM<ZDI>].
+    1594             :     kEncodingVexRm_Wx,                   //!< VEX|EVEX [RM] (propagates VEX|EVEX.W if GPQ used).
+    1595             :     kEncodingVexRm_Lx,                   //!< VEX|EVEX [RM] (propagates VEX|EVEX.L if YMM used).
+    1596             :     kEncodingVexRm_VM,                   //!< VEX|EVEX [RM] (propagates VEX|EVEX.L, VSIB support).
+    1597             :     kEncodingVexRm_T1_4X,                //!<     EVEX [RM] (used by NN instructions that use RM-T1_4X encoding).
+    1598             :     kEncodingVexRmi,                     //!< VEX|EVEX [RMI].
+    1599             :     kEncodingVexRmi_Wx,                  //!< VEX|EVEX [RMI] (propagates VEX|EVEX.W if GPQ used).
+    1600             :     kEncodingVexRmi_Lx,                  //!< VEX|EVEX [RMI] (propagates VEX|EVEX.L if YMM used).
+    1601             :     kEncodingVexRvm,                     //!< VEX|EVEX [RVM].
+    1602             :     kEncodingVexRvm_Wx,                  //!< VEX|EVEX [RVM] (propagates VEX|EVEX.W if GPQ used).
+    1603             :     kEncodingVexRvm_ZDX_Wx,              //!< VEX|EVEX [RVM<ZDX>] (propagates VEX|EVEX.W if GPQ used).
+    1604             :     kEncodingVexRvm_Lx,                  //!< VEX|EVEX [RVM] (propagates VEX|EVEX.L if YMM used).
+    1605             :     kEncodingVexRvmr,                    //!< VEX|EVEX [RVMR].
+    1606             :     kEncodingVexRvmr_Lx,                 //!< VEX|EVEX [RVMR] (propagates VEX|EVEX.L if YMM used).
+    1607             :     kEncodingVexRvmi,                    //!< VEX|EVEX [RVMI].
+    1608             :     kEncodingVexRvmi_Lx,                 //!< VEX|EVEX [RVMI] (propagates VEX|EVEX.L if YMM used).
+    1609             :     kEncodingVexRmv,                     //!< VEX|EVEX [RMV].
+    1610             :     kEncodingVexRmv_Wx,                  //!< VEX|EVEX [RMV] (propagates VEX|EVEX.W if GPQ used).
+    1611             :     kEncodingVexRmv_VM,                  //!< VEX|EVEX [RMV] (propagates VEX|EVEX.L, VSIB support).
+    1612             :     kEncodingVexRmvRm_VM,                //!< VEX|EVEX [RMV|RM] (propagates VEX|EVEX.L, VSIB support).
+    1613             :     kEncodingVexRmvi,                    //!< VEX|EVEX [RMVI].
+    1614             :     kEncodingVexRmMr,                    //!< VEX|EVEX [RM|MR].
+    1615             :     kEncodingVexRmMr_Lx,                 //!< VEX|EVEX [RM|MR] (propagates VEX|EVEX.L if YMM used).
+    1616             :     kEncodingVexRvmRmv,                  //!< VEX|EVEX [RVM|RMV].
+    1617             :     kEncodingVexRvmRmi,                  //!< VEX|EVEX [RVM|RMI].
+    1618             :     kEncodingVexRvmRmi_Lx,               //!< VEX|EVEX [RVM|RMI] (propagates VEX|EVEX.L if YMM used).
+    1619             :     kEncodingVexRvmRmvRmi,               //!< VEX|EVEX [RVM|RMV|RMI].
+    1620             :     kEncodingVexRvmMr,                   //!< VEX|EVEX [RVM|MR].
+    1621             :     kEncodingVexRvmMvr,                  //!< VEX|EVEX [RVM|MVR].
+    1622             :     kEncodingVexRvmMvr_Lx,               //!< VEX|EVEX [RVM|MVR] (propagates VEX|EVEX.L if YMM used).
+    1623             :     kEncodingVexRvmVmi,                  //!< VEX|EVEX [RVM|VMI].
+    1624             :     kEncodingVexRvmVmi_Lx,               //!< VEX|EVEX [RVM|VMI] (propagates VEX|EVEX.L if YMM used).
+    1625             :     kEncodingVexVm,                      //!< VEX|EVEX [VM].
+    1626             :     kEncodingVexVm_Wx,                   //!< VEX|EVEX [VM] (propagates VEX|EVEX.W if GPQ used).
+    1627             :     kEncodingVexVmi,                     //!< VEX|EVEX [VMI].
+    1628             :     kEncodingVexVmi_Lx,                  //!< VEX|EVEX [VMI] (propagates VEX|EVEX.L if YMM used).
+    1629             :     kEncodingVexEvexVmi_Lx,              //!< VEX|EVEX [VMI] (special, used by vpsrldq and vpslldq)
+    1630             :     kEncodingVexRvrmRvmr,                //!< VEX|EVEX [RVRM|RVMR].
+    1631             :     kEncodingVexRvrmRvmr_Lx,             //!< VEX|EVEX [RVRM|RVMR] (propagates VEX|EVEX.L if YMM used).
+    1632             :     kEncodingVexRvrmiRvmri_Lx,           //!< VEX|EVEX [RVRMI|RVMRI] (propagates VEX|EVEX.L if YMM used).
+    1633             :     kEncodingVexMovdMovq,                //!< VEX|EVEX vmovd, vmovq.
+    1634             :     kEncodingVexMovssMovsd,              //!< VEX|EVEX vmovss, vmovsd.
+    1635             :     kEncodingFma4,                       //!< FMA4 [R, R, R/M, R/M].
+    1636             :     kEncodingFma4_Lx,                    //!< FMA4 [R, R, R/M, R/M] (propagates AVX.L if YMM used).
+    1637             :     _kEncodingCount                      //!< Count of instruction encodings.
+    1638             :   };
+    1639             : 
+    1640             :   //! Describes a meaning of all bits of AsmJit's 32-bit opcode (AsmJit specific).
+    1641             :   //!
+    1642             :   //! This schema is AsmJit specific and has been designed to allow encoding of
+    1643             :   //! all X86 instructions available. X86, MMX, and SSE+ instructions always use
+    1644             :   //! `MM` and `PP` fields, which are encoded to corresponding prefixes needed
+    1645             :   //! by X86 or SIMD instructions. AVX+ instructions embed `MMMMM` and `PP` fields
+    1646             :   //! in a VEX prefix, and AVX-512 instructions embed `MM` and `PP` in EVEX prefix.
+    1647             :   //!
+    1648             :   //! The instruction opcode definition uses 1 or 2 bytes as an opcode value. 1
+    1649             :   //! byte is needed by most of the instructions, 2 bytes are only used by legacy
+    1650             :   //! X87-FPU instructions. This means that a second byte is free to by used by
+    1651             :   //! instructions encoded by using VEX and/or EVEX prefix.
+    1652             :   //!
+    1653             :   //! The fields description:
+    1654             :   //!
+    1655             :   //! - `MM` field is used to encode prefixes needed by the instruction or as
+    1656             :   //!   a part of VEX/EVEX prefix. Described as `mm` and `mmmmm` in instruction
+    1657             :   //!   manuals.
+    1658             :   //!
+    1659             :   //!   NOTE: Since `MM` field is defined as `mmmmm` (5 bits), but only 2 least
+    1660             :   //!   significant bits are used by VEX and EVEX prefixes, and additional 4th
+    1661             :   //!   bit is used by XOP prefix, AsmJit uses the 3rd and 5th bit for it's own
+    1662             :   //!   purposes. These bits will probably never be used in future encodings as
+    1663             :   //!   AVX512 uses only `000mm` from `mmmmm`.
+    1664             :   //!
+    1665             :   //! - `PP` field is used to encode prefixes needed by the instruction or as a
+    1666             :   //!   part of VEX/EVEX prefix. Described as `pp` in instruction manuals.
+    1667             :   //!
+    1668             :   //! - `LL` field is used exclusively by AVX+ and AVX512+ instruction sets. It
+    1669             :   //!   describes vector size, which is `L.128` for XMM register, `L.256` for
+    1670             :   //!   for YMM register, and `L.512` for ZMM register. The `LL` field is omitted
+    1671             :   //!   in case that instruction supports multiple vector lengths, however, if the
+    1672             :   //!   instruction requires specific `L` value it must be specified as a part of
+    1673             :   //!   the opcode.
+    1674             :   //!
+    1675             :   //!   NOTE: `LL` having value `11` is not defined yet.
+    1676             :   //!
+    1677             :   //! - `W` field is the most complicated. It was added by 64-bit architecture
+    1678             :   //!   to promote default operation width (instructions that perform 32-bit
+    1679             :   //!   operation by default require to override the width to 64-bit explicitly).
+    1680             :   //!   There is nothing wrong on this, however, some instructions introduced
+    1681             :   //!   implicit `W` override, for example a `cdqe` instruction is basically a
+    1682             :   //!   `cwde` instruction with overridden `W` (set to 1). There are some others
+    1683             :   //!   in the base X86 instruction set. More recent instruction sets started
+    1684             :   //!   using `W` field more often:
+    1685             :   //!
+    1686             :   //!   - AVX instructions started using `W` field as an extended opcode for FMA,
+    1687             :   //!     GATHER, PERM, and other instructions. It also uses `W` field to override
+    1688             :   //!     the default operation width in instructions like `vmovq`.
+    1689             :   //!
+    1690             :   //!   - AVX-512 instructions started using `W` field as an extended opcode for
+    1691             :   //!     all new instructions. This wouldn't have been an issue if the `W` field
+    1692             :   //!     of AVX-512 have matched AVX, but this is not always the case.
+    1693             :   //!
+    1694             :   //! - `O` field is an extended opcode field (3 bits) embedded in ModR/M BYTE.
+    1695             :   //!
+    1696             :   //! - `CDSHL` and `CDTT` fields describe 'compressed-displacement'. `CDSHL` is
+    1697             :   //!   defined for each instruction that is AVX-512 encodable (EVEX) and contains
+    1698             :   //!   a base N shift (base shift to perform the calculation). The `CDTT` field
+    1699             :   //!   is derived from instruction specification and describes additional shift
+    1700             :   //!   to calculate the final `CDSHL` that will be used in SIB byte.
+    1701             :   //!
+    1702             :   //! NOTE: Don't reorder any fields here, the shifts and masks were defined
+    1703             :   //! carefully to make encoding of X86|X64 instructions fast, especially to
+    1704             :   //! construct REX, VEX, and EVEX prefixes in the most efficient way. Changing
+    1705             :   //! values defined by these enums many cause AsmJit to emit invalid binary
+    1706             :   //! representations of instructions passed to `X86Assembler::_emit`.
+    1707             :   ASMJIT_ENUM(OpCodeBits) {
+    1708             :     // MM & VEX & EVEX & XOP
+    1709             :     // ---------------------
+    1710             :     //
+    1711             :     // Two meanings:
+    1712             :     //  * `MMMMM` field in AVX/XOP/AVX-512 instruction.
+    1713             :     //  * Part of the opcode in legacy encoding (bytes emitted before the main
+    1714             :     //    opcode byte).
+    1715             :     //
+    1716             :     // AVX reserves 5 bits for `MMMMM` field, however AVX instructions only use
+    1717             :     // 2 bits and XOP 3 bits. AVX-512 shrinks `MMMMM` field into `MM` so it's
+    1718             :     // safe to assume that bits [4:2] of `MM` field won't be used in future
+    1719             :     // extensions, which will most probably use EVEX encoding. AsmJit divides
+    1720             :     // MM field into this layout:
+    1721             :     //
+    1722             :     // [1:0] - Used to describe 0F, 0F38 and 0F3A legacy prefix bytes and
+    1723             :     //         2 bits of MM field.
+    1724             :     // [2]   - Used to force 3-BYTE VEX prefix, but then cleared to zero before
+    1725             :     //         the prefix is emitted. This bit is not used by any instruction
+    1726             :     //         so it can be used for any purpose by AsmJit. Also, this bit is
+    1727             :     //         used as an extension to `MM` field describing 0F|0F38|0F3A to also
+    1728             :     //         describe 0F01 as used by some legacy instructions (instructions
+    1729             :     //         not using VEX/EVEX prefix).
+    1730             :     // [3]   - Required by XOP instructions, so we use this bit also to indicate
+    1731             :     //         that this is a XOP opcode.
+    1732             :     kOpCode_MM_Shift      = 8,
+    1733             :     kOpCode_MM_Mask       = 0x1FU << kOpCode_MM_Shift,
+    1734             :     kOpCode_MM_00         = 0x00U << kOpCode_MM_Shift,
+    1735             :     kOpCode_MM_0F         = 0x01U << kOpCode_MM_Shift,
+    1736             :     kOpCode_MM_0F38       = 0x02U << kOpCode_MM_Shift,
+    1737             :     kOpCode_MM_0F3A       = 0x03U << kOpCode_MM_Shift, // Described also as XOP.M3 in AMD manuals.
+    1738             :     kOpCode_MM_0F01       = 0x04U << kOpCode_MM_Shift, // AsmJit way to describe 0F01 (never VEX/EVEX).
+    1739             : 
+    1740             :     // `XOP` field is only used to force XOP prefix instead of VEX3 prefix. We
+    1741             :     // know that only XOP encoding uses bit 0b1000 of MM field and that no VEX
+    1742             :     // and EVEX instruction uses such bit, so we can use this bit to force XOP
+    1743             :     // prefix to be emitted instead of VEX3 prefix. See `x86VEXPrefix` defined
+    1744             :     // in `x86assembler.cpp`.
+    1745             :     kOpCode_MM_XOP08      = 0x08U << kOpCode_MM_Shift, // XOP.M8.
+    1746             :     kOpCode_MM_XOP09      = 0x09U << kOpCode_MM_Shift, // XOP.M9.
+    1747             : 
+    1748             :     kOpCode_MM_IsXOP_Shift= kOpCode_MM_Shift + 3,
+    1749             :     kOpCode_MM_IsXOP      = kOpCode_MM_XOP08,
+    1750             : 
+    1751             :     // NOTE: Force VEX3 allows to force to emit VEX3 instead of VEX2 in some
+    1752             :     // cases (similar to forcing REX prefix). Force EVEX will force emitting
+    1753             :     // EVEX prefix instead of VEX2|VEX3. EVEX-only instructions will have
+    1754             :     // ForceEvex always set, however. instructions that can be encoded by
+    1755             :     // either VEX or EVEX prefix shall not have ForceEvex set.
+    1756             : 
+    1757             :     kOpCode_MM_ForceVex3  = 0x04U << kOpCode_MM_Shift, // Force 3-BYTE VEX prefix.
+    1758             :     kOpCode_MM_ForceEvex  = 0x10U << kOpCode_MM_Shift, // Force 4-BYTE EVEX prefix.
+    1759             : 
+    1760             :     // FPU_2B - Second-Byte of OpCode used by FPU
+    1761             :     // ------------------------------------------
+    1762             :     //
+    1763             :     // Second byte opcode. This BYTE is ONLY used by FPU instructions and
+    1764             :     // collides with 3 bits from `MM` and 5 bits from 'CDSHL' and 'CDTT'.
+    1765             :     // It's fine as FPU and AVX512 flags are never used at the same time.
+    1766             :     kOpCode_FPU_2B_Shift  = 10,
+    1767             :     kOpCode_FPU_2B_Mask   = 0xFF << kOpCode_FPU_2B_Shift,
+    1768             : 
+    1769             :     // CDSHL & CDTT
+    1770             :     // ------------
+    1771             :     //
+    1772             :     // Compressed displacement bits.
+    1773             :     //
+    1774             :     // Each opcode defines the base size (N) shift:
+    1775             :     //   [0]: BYTE  (1 byte).
+    1776             :     //   [1]: WORD  (2 bytes).
+    1777             :     //   [2]: DWORD (4 bytes - float/int32).
+    1778             :     //   [3]: QWORD (8 bytes - double/int64).
+    1779             :     //   [4]: OWORD (16 bytes - used by FV|FVM|M128).
+    1780             :     //
+    1781             :     // Which is then scaled by the instruction's TT (TupleType) into possible:
+    1782             :     //   [5]: YWORD (32 bytes)
+    1783             :     //   [6]: ZWORD (64 bytes)
+    1784             :     //
+    1785             :     // These bits are then adjusted before calling EmitModSib or EmitModVSib.
+    1786             :     kOpCode_CDSHL_Shift   = 13,
+    1787             :     kOpCode_CDSHL_Mask    = 0x7 << kOpCode_CDSHL_Shift,
+    1788             : 
+    1789             :     // Compressed displacement tuple-type (specific to AsmJit).
+    1790             :     //
+    1791             :     // Since we store the base offset independently of CDTT we can simplify the
+    1792             :     // number of 'TUPLE_TYPE' kinds significantly and just handle special cases.
+    1793             :     kOpCode_CDTT_Shift    = 16,
+    1794             :     kOpCode_CDTT_Mask     = 0x3 << kOpCode_CDTT_Shift,
+    1795             :     kOpCode_CDTT_None     = 0x0 << kOpCode_CDTT_Shift, // Does nothing.
+    1796             :     kOpCode_CDTT_ByLL     = 0x1 << kOpCode_CDTT_Shift, // Scales by LL (1x 2x 4x).
+    1797             :     kOpCode_CDTT_T1W      = 0x2 << kOpCode_CDTT_Shift, // Used to add 'W' to the shift.
+    1798             :     kOpCode_CDTT_DUP      = 0x3 << kOpCode_CDTT_Shift, // Special 'VMOVDDUP' case.
+    1799             : 
+    1800             :     // Aliases that match names used in instruction manuals.
+    1801             :     kOpCode_CDTT_FV       = kOpCode_CDTT_ByLL,
+    1802             :     kOpCode_CDTT_HV       = kOpCode_CDTT_ByLL,
+    1803             :     kOpCode_CDTT_FVM      = kOpCode_CDTT_ByLL,
+    1804             :     kOpCode_CDTT_T1S      = kOpCode_CDTT_None,
+    1805             :     kOpCode_CDTT_T1F      = kOpCode_CDTT_None,
+    1806             :     kOpCode_CDTT_T1_4X    = kOpCode_CDTT_None,
+    1807             :     kOpCode_CDTT_T2       = kOpCode_CDTT_None,
+    1808             :     kOpCode_CDTT_T4       = kOpCode_CDTT_None,
+    1809             :     kOpCode_CDTT_T8       = kOpCode_CDTT_None,
+    1810             :     kOpCode_CDTT_HVM      = kOpCode_CDTT_ByLL,
+    1811             :     kOpCode_CDTT_QVM      = kOpCode_CDTT_ByLL,
+    1812             :     kOpCode_CDTT_OVM      = kOpCode_CDTT_ByLL,
+    1813             :     kOpCode_CDTT_128      = kOpCode_CDTT_None,
+    1814             : 
+    1815             :     // `O` Field in MorR/M
+    1816             :     // -------------------
+    1817             : 
+    1818             :     kOpCode_O_Shift       = 18,
+    1819             :     kOpCode_O_Mask        = 0x07U << kOpCode_O_Shift,
+    1820             : 
+    1821             :     // `PP` and `L` Fields
+    1822             :     // -------------------
+    1823             :     //
+    1824             :     // These fields are stored deliberately right after each other as it makes
+    1825             :     // it easier to construct VEX prefix from the opcode value stored in the
+    1826             :     // instruction database.
+    1827             :     //
+    1828             :     // Two meanings:
+    1829             :     //   * "PP" field in AVX/XOP/AVX-512 instruction.
+    1830             :     //   * Mandatory Prefix in legacy encoding.
+    1831             :     //
+    1832             :     // AVX reserves 2 bits for `PP` field, but AsmJit extends the storage by 1
+    1833             :     // more bit that is used to emit 9B prefix for some X87-FPU instructions.
+    1834             : 
+    1835             :     kOpCode_PP_Shift      = 21,
+    1836             :     kOpCode_PP_VEXMask    = 0x03U << kOpCode_PP_Shift, // PP field mask used by VEX/EVEX.
+    1837             :     kOpCode_PP_FPUMask    = 0x07U << kOpCode_PP_Shift, // Mask used by EMIT_PP, also includes 0x9B.
+    1838             :     kOpCode_PP_00         = 0x00U << kOpCode_PP_Shift,
+    1839             :     kOpCode_PP_66         = 0x01U << kOpCode_PP_Shift,
+    1840             :     kOpCode_PP_F3         = 0x02U << kOpCode_PP_Shift,
+    1841             :     kOpCode_PP_F2         = 0x03U << kOpCode_PP_Shift,
+    1842             : 
+    1843             :     // AsmJit specific to emit FPU's 9B byte.
+    1844             :     kOpCode_PP_9B         = 0x07U << kOpCode_PP_Shift,
+    1845             : 
+    1846             :     // EVEX.W Field
+    1847             :     // ------------
+    1848             :     //
+    1849             :     // `W` field used by EVEX instruction encoding.
+    1850             : 
+    1851             :     kOpCode_EW_Shift      = 24,
+    1852             :     kOpCode_EW            = 0x01U << kOpCode_EW_Shift,
+    1853             : 
+    1854             :     // REX B|X|R|W Bits
+    1855             :     // ----------------
+    1856             :     //
+    1857             :     // NOTE: REX.[B|X|R] are never stored within the opcode itself, they are
+    1858             :     // reserved by AsmJit are are added dynamically to the opcode to represent
+    1859             :     // [REX|VEX|EVEX].[B|X|R] bits. REX.W can be stored in DB as it's sometimes
+    1860             :     // part of the opcode itself.
+    1861             : 
+    1862             :     // These must be binary compatible with instruction options.
+    1863             :     kOpCode_REX_Shift     = 25,
+    1864             :     kOpCode_REX_Mask      = 0x0FU << kOpCode_REX_Shift,
+    1865             :     kOpCode_B             = 0x01U << kOpCode_REX_Shift, // Never stored in DB.
+    1866             :     kOpCode_X             = 0x02U << kOpCode_REX_Shift, // Never stored in DB.
+    1867             :     kOpCode_R             = 0x04U << kOpCode_REX_Shift, // Never stored in DB.
+    1868             :     kOpCode_W             = 0x08U << kOpCode_REX_Shift,
+    1869             :     kOpCode_W_Shift       = kOpCode_REX_Shift + 3,
+    1870             : 
+    1871             :     // `L` field in AVX/XOP/AVX-512
+    1872             :     // ----------------------------
+    1873             :     //
+    1874             :     // VEX/XOP prefix can only use the first bit `L.128` or `L.256`. EVEX prefix
+    1875             :     // prefix makes it possible to use also `L.512`.
+    1876             :     //
+    1877             :     // If the instruction set manual describes an instruction by `LIG` it means
+    1878             :     // that the `L` field is ignored and AsmJit defaults to `0` in such case.
+    1879             :     kOpCode_LL_Shift      = 29,
+    1880             :     kOpCode_LL_Mask       = 0x03U << kOpCode_LL_Shift,
+    1881             :     kOpCode_LL_128        = 0x00U << kOpCode_LL_Shift,
+    1882             :     kOpCode_LL_256        = 0x01U << kOpCode_LL_Shift,
+    1883             :     kOpCode_LL_512        = 0x02U << kOpCode_LL_Shift
+    1884             :   };
+    1885             : 
+    1886             :   //! Instruction flags.
+    1887             :   //!
+    1888             :   //! Details about instruction encoding, operation, features, and some limitations.
+    1889             :   ASMJIT_ENUM(Flags) {
+    1890             :     kFlagNone             = 0x00000000U, //!< No flags.
+    1891             : 
+    1892             :     // Operand's Use
+    1893             :     // -------------
+    1894             :     //
+    1895             :     // These flags describe the use of 1st and/or 1st+2nd operands. This allows
+    1896             :     // to fast calculate which operands are read, written, or read and written.
+    1897             :     //
+    1898             :     // In some cases this information is not reliable, because AsmJit uses data
+    1899             :     // generated by a script that merges usually more than one instruction into
+    1900             :     // one AsmJit instruction as some X86 instructions uses more encodings to
+    1901             :     // describe the same operation. In such case `kFlagUseComplex` is set and
+    1902             :     // AsmJit will use different approach to calculate operand's use flags.
+    1903             : 
+    1904             :     kFlagUseA             = 0x00000001U, //!< Use flags are 'A'mbiguous as USE information couldn't be flattened.
+    1905             :     kFlagUseR             = 0x00000002U, //!< 1st operand is R (read), read-only if `kFlagOpW` isn't set.
+    1906             :     kFlagUseW             = 0x00000004U, //!< 1st operand is W (written), write-only if `kFlagOpR` isn't set.
+    1907             :     kFlagUseX             = 0x00000006U, //!< 1st operand is X (read-write).
+    1908             :     kFlagUseXX            = 0x00000008U, //!< 1st and 2nd operands are XX (read & written) (XCHG, XADD).
+    1909             : 
+    1910             :     kFlagFixedReg         = 0x00000010U, //!< Some operand uses fixed register.
+    1911             :     kFlagFixedMem         = 0x00000020U, //!< Some operand uses fixed register to access memory (EAX|RAX, EDI|RDI, ESI|RSI).
+    1912             :     kFlagFixedRM          = 0x00000030U, //!< Combination of `kFlagUseFixedReg` and `kFlagUseFixedMem`.
+    1913             : 
+    1914             :     // Instruction Family
+    1915             :     // ------------------
+    1916             :     //
+    1917             :     // Instruction family information.
+    1918             : 
+    1919             :     kFlagFpu              = 0x00000100U, //!< Instruction that accesses FPU registers.
+    1920             :     kFlagMmx              = 0x00000200U, //!< Instruction that accesses MMX registers (including 3DNOW and GEODE) and EMMS.
+    1921             :     kFlagVec              = 0x00000400U, //!< Instruction that accesses XMM registers (SSE, AVX, AVX512).
+    1922             : 
+    1923             :     // Prefixes and Encoding Flags
+    1924             :     // ---------------------------
+    1925             :     //
+    1926             :     // These describe optional X86 prefixes that can be used to change the instruction's operation.
+    1927             : 
+    1928             :     kFlagRep              = 0x00001000U, //!< Instruction can be prefixed by using the REP/REPZ/REPE prefix.
+    1929             :     kFlagRepnz            = 0x00002000U, //!< Instruction can be prefixed by using the REPNZ/REPNE prefix.
+    1930             :     kFlagLock             = 0x00004000U, //!< Instruction can be prefixed by using the LOCK prefix.
+    1931             :     kFlagXAcquire         = 0x00008000U, //!< Instruction can be prefixed by using the XACQUIRE prefix.
+    1932             :     kFlagXRelease         = 0x00010000U, //!< Instruction can be prefixed by using the XRELEASE prefix.
+    1933             :     kFlagMib              = 0x00020000U, //!< Instruction uses MIB (BNDLDX|BNDSTX) to encode two registers.
+    1934             :     kFlagVsib             = 0x00040000U, //!< Instruction uses VSIB instead of legacy SIB.
+    1935             :     kFlagVex              = 0x00080000U, //!< Instruction can be encoded by VEX|XOP (AVX|AVX2|BMI|XOP|...).
+    1936             :     kFlagEvex             = 0x00100000U, //!< Instruction can be encoded by EVEX (AVX512).
+    1937             : 
+    1938             :     // FPU Flags
+    1939             :     // ---------
+    1940             :     //
+    1941             :     // Used to tell the encoder which memory operand sizes are encodable.
+    1942             : 
+    1943             :     kFlagFpuM16           = 0x00200000U, //!< FPU instruction can address `word_ptr` (shared with M10).
+    1944             :     kFlagFpuM32           = 0x00400000U, //!< FPU instruction can address `dword_ptr`.
+    1945             :     kFlagFpuM64           = 0x00800000U, //!< FPU instruction can address `qword_ptr`.
+    1946             :     kFlagFpuM80           = 0x00200000U, //!< FPU instruction can address `tword_ptr` (shared with M2).
+    1947             : 
+    1948             :     // AVX and AVX515 Flags
+    1949             :     // --------------------
+    1950             :     //
+    1951             :     // If both `kFlagPrefixVex` and `kFlagPrefixEvex` flags are specified it
+    1952             :     // means that the instructions can be encoded by either VEX or EVEX prefix.
+    1953             :     // In that case AsmJit checks global options and also instruction options
+    1954             :     // to decide whether to emit VEX or EVEX prefix.
+    1955             : 
+    1956             :     kFlagAvx512_          = 0x00000000U, //!< Internally used in tables, has no meaning.
+    1957             :     kFlagAvx512K          = 0x01000000U, //!< Supports masking {k0..k7}.
+    1958             :     kFlagAvx512Z          = 0x02000000U, //!< Supports zeroing {z}, must be used together with `kAvx512k`.
+    1959             :     kFlagAvx512ER         = 0x04000000U, //!< Supports 'embedded-rounding' {er} with implicit {sae},
+    1960             :     kFlagAvx512SAE        = 0x08000000U, //!< Supports 'suppress-all-exceptions' {sae}.
+    1961             :     kFlagAvx512B32        = 0x10000000U, //!< Supports 32-bit broadcast 'b32'.
+    1962             :     kFlagAvx512B64        = 0x20000000U, //!< Supports 64-bit broadcast 'b64'.
+    1963             :     kFlagAvx512T4X        = 0x80000000U, //!< Operates on a vector of consecutive registers (AVX512_4FMAPS and AVX512_4VNNIW).
+    1964             : 
+    1965             :     // Combinations used by instruction tables to make AVX512 definitions more compact.
+    1966             :     kFlagAvx512KZ            = kFlagAvx512K         | kFlagAvx512Z,
+    1967             :     kFlagAvx512ER_SAE        = kFlagAvx512ER        | kFlagAvx512SAE,
+    1968             :     kFlagAvx512KZ_SAE        = kFlagAvx512KZ        | kFlagAvx512SAE,
+    1969             :     kFlagAvx512KZ_SAE_B32    = kFlagAvx512KZ_SAE    | kFlagAvx512B32,
+    1970             :     kFlagAvx512KZ_SAE_B64    = kFlagAvx512KZ_SAE    | kFlagAvx512B64,
+    1971             : 
+    1972             :     kFlagAvx512KZ_ER_SAE     = kFlagAvx512KZ        | kFlagAvx512ER_SAE,
+    1973             :     kFlagAvx512KZ_ER_SAE_B32 = kFlagAvx512KZ_ER_SAE | kFlagAvx512B32,
+    1974             :     kFlagAvx512KZ_ER_SAE_B64 = kFlagAvx512KZ_ER_SAE | kFlagAvx512B64,
+    1975             : 
+    1976             :     kFlagAvx512K_B32         = kFlagAvx512K         | kFlagAvx512B32,
+    1977             :     kFlagAvx512K_B64         = kFlagAvx512K         | kFlagAvx512B64,
+    1978             :     kFlagAvx512KZ_B32        = kFlagAvx512KZ        | kFlagAvx512B32,
+    1979             :     kFlagAvx512KZ_B64        = kFlagAvx512KZ        | kFlagAvx512B64
+    1980             :   };
+    1981             : 
+    1982             :   //! Used to describe what the instruction does and some of its quirks.
+    1983             :   enum OperationFlags {
+    1984             :     kOperationMovCrDr      = 0x00000001U, //!< `MOV REG <-> CREG|DREG` - OS|SF|ZF|AF|PF|CF flags are undefined.
+    1985             :     kOperationMovSsSd      = 0x00000002U, //!< `MOVSS|MOVSD XMM, [MEM]` - Sestination operand is completely overwritten.
+    1986             : 
+    1987             :     kOperationPrefetch     = 0x10000000U, //!< Instruction does hardware prefetch.
+    1988             :     kOperationBarrier      = 0x20000000U, //!< Instruction acts as a barrier / fence.
+    1989             :     kOperationVolatile     = 0x40000000U, //!< Hint for instruction schedulers to never reorder this instruction (side effects, memory barrier, etc).
+    1990             :     kOperationPrivileged   = 0x80000000U  //!< This is a privileged operation that cannot run in user mode (system instruction).
+    1991             :   };
+    1992             : 
+    1993             :   //! SSE to AVX conversion mode.
+    1994             :   enum SseToAvxMode {
+    1995             :     kSseToAvxNone         = 0,           //!< No conversion possible.
+    1996             :     kSseToAvxMove         = 1,           //!< No change (no operands changed).
+    1997             :     kSseToAvxMoveIfMem    = 2,           //!< No change if the second operand is mem, extend otherwise.
+    1998             :     kSseToAvxExtend       = 3,           //!< The first SSE operand becomes first and second AVX operand.
+    1999             :     kSseToAvxBlend        = 4            //!< Special case for 'vblendvpd', 'vblendvps', and 'vpblendvb'.
+    2000             :   };
+    2001             : 
+    2002             :   //! Instruction options (AsmJit specific).
+    2003             :   ASMJIT_ENUM(Options) {
+    2004             :     // NOTE: Don't collide with reserved bits used by CodeEmitter (0x0000003F).
+    2005             :     kOptionOp4Op5Used     = CodeEmitter::kOptionOp4Op5Used,
+    2006             : 
+    2007             :     kOptionShortForm      = 0x00000040U, //!< Emit short-form of the instruction.
+    2008             :     kOptionLongForm       = 0x00000080U, //!< Emit long-form of the instruction.
+    2009             : 
+    2010             :     kOptionTaken          = 0x00000100U, //!< Conditional jump is likely to be taken.
+    2011             :     kOptionNotTaken       = 0x00000200U, //!< Conditional jump is unlikely to be taken.
+    2012             : 
+    2013             :     kOptionVex3           = 0x00000400U, //!< Use 3-byte VEX prefix if possible (AVX) (must be 0x00000400).
+    2014             :     kOptionModMR          = 0x00000800U, //!< Use ModMR instead of ModRM when it's available.
+    2015             :     kOptionEvex           = 0x00001000U, //!< Use 4-byte EVEX prefix if possible (AVX-512) (must be 0x00001000).
+    2016             : 
+    2017             :     kOptionLock           = 0x00002000U, //!< LOCK prefix (lock-enabled instructions only).
+    2018             :     kOptionRep            = 0x00004000U, //!< REP/REPZ prefix (string instructions only).
+    2019             :     kOptionRepnz          = 0x00008000U, //!< REPNZ prefix (string instructions only).
+    2020             : 
+    2021             :     kOptionXAcquire       = 0x00010000U, //!< XACQUIRE prefix (only allowed instructions).
+    2022             :     kOptionXRelease       = 0x00020000U, //!< XRELEASE prefix (only allowed instructions).
+    2023             : 
+    2024             :     kOptionER             = 0x00040000U, //!< AVX-512: 'embedded-rounding' {er} and {sae}.
+    2025             :     kOptionSAE            = 0x00080000U, //!< AVX-512: 'suppress-all-exceptions' {sae}.
+    2026             :     kOption1ToX           = 0x00100000U, //!< AVX-512: broadcast the first element to all {1tox}.
+    2027             :     kOptionRN_SAE         = 0x00000000U, //!< AVX-512: round-to-nearest (even)      {rn-sae} (bits 00).
+    2028             :     kOptionRD_SAE         = 0x00200000U, //!< AVX-512: round-down (toward -inf)     {rd-sae} (bits 01).
+    2029             :     kOptionRU_SAE         = 0x00400000U, //!< AVX-512: round-up (toward +inf)       {ru-sae} (bits 10).
+    2030             :     kOptionRZ_SAE         = 0x00600000U, //!< AVX-512: round-toward-zero (truncate) {rz-sae} (bits 11).
+    2031             :     kOptionZMask          = 0x00800000U, //!< AVX-512: Use zeroing {k}{z} instead of merging {k}.
+    2032             :     _kOptionAvx512Mask    = 0x00FC0000U, //!< AVX-512: Mask of all possible AVX-512 options except EVEX prefix flag.
+    2033             : 
+    2034             :     _kOptionInvalidRex    = 0x01000000U, //!< REX prefix can't be emitted (internal).
+    2035             :     kOptionOpCodeB        = 0x02000000U, //!< REX.B and/or VEX.B field (X64).
+    2036             :     kOptionOpCodeX        = 0x04000000U, //!< REX.X and/or VEX.X field (X64).
+    2037             :     kOptionOpCodeR        = 0x08000000U, //!< REX.R and/or VEX.R field (X64).
+    2038             :     kOptionOpCodeW        = 0x10000000U, //!< REX.W and/or VEX.W field (X64).
+    2039             :     kOptionRex            = 0x80000000U  //!< Use REX prefix (X64) (must be 0x80000000).
+    2040             :   };
+    2041             : 
+    2042             :   //! Supported architectures.
+    2043             :   ASMJIT_ENUM(ArchMask) {
+    2044             :     kArchMaskX86          = 0x01,        //!< X86 mode supported.
+    2045             :     kArchMaskX64          = 0x02         //!< X64 mode supported.
+    2046             :   };
+    2047             : 
+    2048             :   ASMJIT_ENUM(SingleRegCase) {
+    2049             :     kSingleRegNone        = 0,           //!< No special handling.
+    2050             :     kSingleRegRO          = 1,           //!< Operands become read-only  - `REG & REG` and similar.
+    2051             :     kSingleRegWO          = 2            //!< Operands become write-only - `REG ^ REG` and similar.
+    2052             :   };
+    2053             : 
+    2054             :   //! Instruction's operand flags.
+    2055             :   ASMJIT_ENUM(OpFlags) {
+    2056             :     kOpNone               = 0x00000000U, //!< No operand.
+    2057             : 
+    2058             :     kOpGpbLo              = 0x00000001U, //!< Operand can be a low 8-bit GPB register.
+    2059             :     kOpGpbHi              = 0x00000002U, //!< Operand can be a high 8-bit GPB register.
+    2060             :     kOpGpw                = 0x00000004U, //!< Operand can be a 16-bit GPW register.
+    2061             :     kOpGpd                = 0x00000008U, //!< Operand can be a 32-bit GPD register.
+    2062             :     kOpGpq                = 0x00000010U, //!< Operand can be a 64-bit GPQ register.
+    2063             :     kOpFp                 = 0x00000020U, //!< Operand can be an FPU register.
+    2064             :     kOpMm                 = 0x00000040U, //!< Operand can be a 64-bit MM register.
+    2065             :     kOpK                  = 0x00000080U, //!< Operand can be a 64-bit K register.
+    2066             :     kOpCr                 = 0x00000100U, //!< Operand can be a control register.
+    2067             :     kOpDr                 = 0x00000200U, //!< Operand can be a debug register.
+    2068             :     kOpBnd                = 0x00000400U, //!< Operand can be a BND register.
+    2069             :     kOpSeg                = 0x00000800U, //!< Operand can be a segment register.
+    2070             :     kOpXmm                = 0x00001000U, //!< Operand can be a 128-bit XMM register.
+    2071             :     kOpYmm                = 0x00002000U, //!< Operand can be a 256-bit YMM register.
+    2072             :     kOpZmm                = 0x00004000U, //!< Operand can be a 512-bit ZMM register.
+    2073             : 
+    2074             :     kOpAllRegs            = 0x00007FFFU, //!< Combination of all possible registers.
+    2075             : 
+    2076             :     kOpMem                = 0x00010000U, //!< Operand can be a scalar memory pointer.
+    2077             :     kOpVm                 = 0x00020000U, //!< Operand can be a vector memory pointer.
+    2078             : 
+    2079             :     kOpU4                 = 0x00040000U, //!< Operand can be unsigned 4-bit  immediate.
+    2080             :     kOpI8                 = 0x00080000U, //!< Operand can be signed   8-bit  immediate.
+    2081             :     kOpU8                 = 0x00100000U, //!< Operand can be unsigned 8-bit  immediate.
+    2082             :     kOpI16                = 0x00200000U, //!< Operand can be signed   16-bit immediate.
+    2083             :     kOpU16                = 0x00400000U, //!< Operand can be unsigned 16-bit immediate.
+    2084             :     kOpI32                = 0x00800000U, //!< Operand can be signed   32-bit immediate.
+    2085             :     kOpU32                = 0x01000000U, //!< Operand can be unsigned 32-bit immediate.
+    2086             :     kOpI64                = 0x02000000U, //!< Operand can be signed   64-bit immediate.
+    2087             :     kOpU64                = 0x04000000U, //!< Operand can be unsigned 64-bit immediate.
+    2088             :     kOpAllImm             = 0x07FC0000U, //!< Operand can be any immediate.
+    2089             : 
+    2090             :     kOpRel8               = 0x08000000U, //!< Operand can be relative 8-bit  displacement.
+    2091             :     kOpRel32              = 0x10000000U, //!< Operand can be relative 32-bit displacement.
+    2092             : 
+    2093             :     kOpR                  = 0x20000000U, //!< Operand is read.
+    2094             :     kOpW                  = 0x40000000U, //!< Operand is written.
+    2095             :     kOpX                  = 0x60000000U, //!< Operand is read & written.
+    2096             :     kOpImplicit           = 0x80000000U  //!< Operand is implicit.
+    2097             :   };
+    2098             : 
+    2099             :   //! Instruction's memory operand flags.
+    2100             :   ASMJIT_ENUM(MemOpFlags) {
+    2101             :     // NOTE: Instruction uses either scalar or vector memory operands, they
+    2102             :     // never collide, this is the reason "M" and "Vm" can share bits here.
+    2103             : 
+    2104             :     kMemOpM8              = 0x0001U,     //!< Operand can be an 8-bit memory pointer.
+    2105             :     kMemOpM16             = 0x0002U,     //!< Operand can be a 16-bit memory pointer.
+    2106             :     kMemOpM32             = 0x0004U,     //!< Operand can be a 32-bit memory pointer.
+    2107             :     kMemOpM48             = 0x0008U,     //!< Operand can be a 32-bit memory pointer.
+    2108             :     kMemOpM64             = 0x0010U,     //!< Operand can be a 64-bit memory pointer.
+    2109             :     kMemOpM80             = 0x0020U,     //!< Operand can be an 80-bit memory pointer.
+    2110             :     kMemOpM128            = 0x0040U,     //!< Operand can be a 128-bit memory pointer.
+    2111             :     kMemOpM256            = 0x0080U,     //!< Operand can be a 256-bit memory pointer.
+    2112             :     kMemOpM512            = 0x0100U,     //!< Operand can be a 512-bit memory pointer.
+    2113             :     kMemOpM1024           = 0x0200U,     //!< Operand can be a 1024-bit memory pointer.
+    2114             : 
+    2115             :     kMemOpVm32x           = 0x0001U,     //!< Operand can be a vm32x (vector) pointer.
+    2116             :     kMemOpVm32y           = 0x0002U,     //!< Operand can be a vm32y (vector) pointer.
+    2117             :     kMemOpVm32z           = 0x0004U,     //!< Operand can be a vm32z (vector) pointer.
+    2118             :     kMemOpVm64x           = 0x0010U,     //!< Operand can be a vm64x (vector) pointer.
+    2119             :     kMemOpVm64y           = 0x0020U,     //!< Operand can be a vm64y (vector) pointer.
+    2120             :     kMemOpVm64z           = 0x0040U,     //!< Operand can be a vm64z (vector) pointer.
+    2121             : 
+    2122             :     kMemOpBaseOnly        = 0x0800U,     //!< Only memory base is allowed (no index, no offset).
+    2123             :     kMemOpDs              = 0x1000U,     //!< Implicit memory operand's DS segment.
+    2124             :     kMemOpEs              = 0x2000U,     //!< Implicit memory operand's ES segment.
+    2125             : 
+    2126             :     kMemOpMib             = 0x4000U,     //!< Operand must be MIB (base+index) pointer.
+    2127             :     kMemOpAny             = 0x8000U      //!< Operand can be any scalar memory pointer.
+    2128             :   };
+    2129             : 
+    2130             :   //! Instruction signature.
+    2131             :   //!
+    2132             :   //! Contains a sequence of operands' combinations and other metadata that defines
+    2133             :   //! a single instruction. This data is used by instruction validator.
+    2134             :   struct ISignature {
+    2135             :     uint8_t opCount  : 3;                //!< Count of operands in `opIndex` (0..6).
+    2136             :     uint8_t archMask : 2;                //!< Architecture mask of this record.
+    2137             :     uint8_t implicit : 3;                //!< Number of implicit operands.
+    2138             :     uint8_t reserved;                    //!< Reserved for future use.
+    2139             :     uint8_t operands[6];                 //!< Indexes to `OSignature` table.
+    2140             :   };
+    2141             : 
+    2142             :   //! Operand signature, used by \ref ISignature.
+    2143             :   //!
+    2144             :   //! Contains all possible operand combinations, memory size information,
+    2145             :   //! and register index (or \ref Globals::kInvalidRegId if not mandatory).
+    2146             :   struct OSignature {
+    2147             :     uint32_t flags;                      //!< Operand flags.
+    2148             :     uint16_t memFlags;                   //!< Memory flags.
+    2149             :     uint8_t extFlags;                    //!< Extra flags.
+    2150             :     uint8_t regMask;                     //!< Mask of possible register IDs.
+    2151             :   };
+    2152             : 
+    2153             :   //! Common data - aggregated data that is shared across many instructions.
+    2154             :   struct CommonData {
+    2155             :     //! Get all instruction flags, see \ref X86Inst::Flags.
+    2156       30892 :     ASMJIT_INLINE uint32_t getFlags() const noexcept { return _flags; }
+    2157             :     //! Get if the instruction has a `flag`, see \ref X86Inst::Flags.
+    2158       73104 :     ASMJIT_INLINE bool hasFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+    2159             : 
+    2160             :     //! Get if 1st operand is read-only.
+    2161             :     ASMJIT_INLINE bool isUseR() const noexcept { return (getFlags() & kFlagUseX) == kFlagUseR; }
+    2162             :     //! Get if 1st operand is write-only.
+    2163       30892 :     ASMJIT_INLINE bool isUseW() const noexcept { return (getFlags() & kFlagUseX) == kFlagUseW; }
+    2164             :     //! Get if 1st operand is read-write.
+    2165             :     ASMJIT_INLINE bool isUseX() const noexcept { return (getFlags() & kFlagUseX) == kFlagUseX; }
+    2166             :     //! Get if 1st and 2nd operands are read-write.
+    2167             :     ASMJIT_INLINE bool isUseXX() const noexcept { return hasFlag(kFlagUseXX); }
+    2168             : 
+    2169             :     ASMJIT_INLINE bool hasFixedReg() const noexcept { return hasFlag(kFlagFixedReg); }
+    2170             :     ASMJIT_INLINE bool hasFixedMem() const noexcept { return hasFlag(kFlagFixedMem); }
+    2171             :     ASMJIT_INLINE bool hasFixedRM() const noexcept { return hasFlag(kFlagFixedRM); }
+    2172             : 
+    2173             :     //! Get if the instruction is FPU instruction.
+    2174             :     ASMJIT_INLINE bool isFpu() const noexcept { return hasFlag(kFlagFpu); }
+    2175             :     //! Get if the instruction is MMX|3DNOW instruction that accesses MMX registers (includes EMMS).
+    2176             :     ASMJIT_INLINE bool isMmx() const noexcept { return hasFlag(kFlagMmx); }
+    2177             : 
+    2178             :     //! Get if the instruction is SSE|AVX|AVX512 instruction that accesses XMM|YMM|ZMM registers (includes VZEROALL|VZEROUPPER).
+    2179             :     ASMJIT_INLINE bool isVec() const noexcept { return hasFlag(kFlagVec); }
+    2180             :     //! Get if the instruction is SSE+ (SSE4.2, AES, SHA included) instruction that accesses XMM registers.
+    2181             :     ASMJIT_INLINE bool isSse() const noexcept { return (getFlags() & (kFlagVec | kFlagVex | kFlagEvex)) == kFlagVec; }
+    2182             :     //! Get if the instruction is AVX+ (FMA included) instruction that accesses XMM|YMM|ZMM registers.
+    2183             :     ASMJIT_INLINE bool isAvx() const noexcept { return isVec() && isVexOrEvex(); }
+    2184             : 
+    2185             :     //! Get if the instruction can be prefixed by LOCK prefix.
+    2186             :     ASMJIT_INLINE bool isLockEnabled() const noexcept { return hasFlag(kFlagLock); }
+    2187             :     //! Get if the instruction can be prefixed by REP prefix.
+    2188             :     ASMJIT_INLINE bool isRepEnabled() const noexcept { return hasFlag(kFlagRep); }
+    2189             :     //! Get if the instruction can be prefixed by REPZ prefix.
+    2190             :     ASMJIT_INLINE bool isRepzEnabled() const noexcept { return hasFlag(kFlagRep); }
+    2191             :     //! Get if the instruction can be prefixed by REPNZ prefix.
+    2192             :     ASMJIT_INLINE bool isRepnzEnabled() const noexcept { return hasFlag(kFlagRepnz); }
+    2193             : 
+    2194             :     //! Get if the instruction uses MIB.
+    2195             :     ASMJIT_INLINE bool isMibOp() const noexcept { return hasFlag(kFlagMib); }
+    2196             :     //! Get if the instruction uses VSIB.
+    2197             :     ASMJIT_INLINE bool isVsibOp() const noexcept { return hasFlag(kFlagVsib); }
+    2198             :     //! Get if the instruction uses VEX (can be set together with EVEX if both are encodable).
+    2199             :     ASMJIT_INLINE bool isVex() const noexcept { return hasFlag(kFlagVex); }
+    2200             :     //! Get if the instruction uses EVEX (can be set together with VEX if both are encodable).
+    2201             :     ASMJIT_INLINE bool isEvex() const noexcept { return hasFlag(kFlagEvex); }
+    2202             :     //! Get if the instruction uses VEX and/or EVEX.
+    2203             :     ASMJIT_INLINE bool isVexOrEvex() const noexcept { return hasFlag(kFlagVex | kFlagEvex); }
+    2204             : 
+    2205             :     //! Get if the instruction supports AVX512 masking {k}.
+    2206             :     ASMJIT_INLINE bool hasAvx512K() const noexcept { return hasFlag(kFlagAvx512K); }
+    2207             :     //! Get if the instruction supports AVX512 zeroing {k}{z}.
+    2208             :     ASMJIT_INLINE bool hasAvx512Z() const noexcept { return hasFlag(kFlagAvx512Z); }
+    2209             :     //! Get if the instruction supports AVX512 embedded-rounding {er}.
+    2210             :     ASMJIT_INLINE bool hasAvx512ER() const noexcept { return hasFlag(kFlagAvx512ER); }
+    2211             :     //! Get if the instruction supports AVX512 suppress-all-exceptions {sae}.
+    2212             :     ASMJIT_INLINE bool hasAvx512SAE() const noexcept { return hasFlag(kFlagAvx512SAE); }
+    2213             :     //! Get if the instruction supports AVX512 broadcast (either 32-bit or 64-bit).
+    2214             :     ASMJIT_INLINE bool hasAvx512B() const noexcept { return hasFlag(kFlagAvx512B32 | kFlagAvx512B64); }
+    2215             :     //! Get if the instruction supports AVX512 broadcast (32-bit).
+    2216             :     ASMJIT_INLINE bool hasAvx512B32() const noexcept { return hasFlag(kFlagAvx512B32); }
+    2217             :     //! Get if the instruction supports AVX512 broadcast (64-bit).
+    2218             :     ASMJIT_INLINE bool hasAvx512B64() const noexcept { return hasFlag(kFlagAvx512B64); }
+    2219             : 
+    2220             :     //! Get if the instruction may or will jump (returns true also for calls and returns).
+    2221             :     ASMJIT_INLINE bool doesJump() const noexcept { return _jumpType != Inst::kJumpTypeNone; }
+    2222             : 
+    2223             :     //! Get the destination index of WRITE operation.
+    2224             :     ASMJIT_INLINE uint32_t getWriteIndex() const noexcept { return _writeIndex; }
+    2225             :     //! Get the number of bytes that will be written by a WRITE operation.
+    2226             :     //!
+    2227             :     //! This information is required by a liveness analysis to mark virtual
+    2228             :     //! registers dead even if the instruction doesn't completely overwrite
+    2229             :     //! the whole register. If the analysis keeps which bytes are completely
+    2230             :     //! overwritten by the instruction it can find the where a register becomes
+    2231             :     //! dead by simply checking if the instruction overwrites all remaining
+    2232             :     //! bytes.
+    2233       21892 :     ASMJIT_INLINE uint32_t getWriteSize() const noexcept { return _writeSize; }
+    2234             : 
+    2235             :     //! Get if the instruction has alternative opcode.
+    2236           0 :     ASMJIT_INLINE bool hasAltOpCode() const noexcept { return _altOpCodeIndex != 0; }
+    2237             :     //! Get alternative opcode, see \ref OpCodeBits.
+    2238             :     ASMJIT_INLINE uint32_t getAltOpCode() const noexcept;
+    2239             : 
+    2240             :     ASMJIT_INLINE uint32_t getISignatureIndex() const noexcept { return _iSignatureIndex; }
+    2241             :     ASMJIT_INLINE uint32_t getISignatureCount() const noexcept { return _iSignatureCount; }
+    2242             : 
+    2243             :     ASMJIT_INLINE const ISignature* getISignatureData() const noexcept;
+    2244             :     ASMJIT_INLINE const ISignature* getISignatureEnd() const noexcept;
+    2245             : 
+    2246             :     ASMJIT_INLINE uint32_t getJumpType() const noexcept { return _jumpType; }
+    2247             :     ASMJIT_INLINE uint32_t getSingleRegCase() const noexcept { return _singleRegCase; }
+    2248             : 
+    2249             :     uint32_t _flags;                     //!< Instruction flags.
+    2250             :     uint32_t _writeIndex         : 8;    //!< First DST byte of a WRITE operation (default 0).
+    2251             :     uint32_t _writeSize          :24;    //!< Number of bytes to be written in DST.
+    2252             : 
+    2253             :     uint32_t _altOpCodeIndex     : 8;    //!< Index to table with alternative opcodes.
+    2254             :     uint32_t _iSignatureIndex    :10;    //!< First `ISignature` entry in the database.
+    2255             :     uint32_t _iSignatureCount    : 4;    //!< Number of relevant `ISignature` entries.
+    2256             :     uint32_t _jumpType           : 3;    //!< Jump type, see `Inst::JumpType`.
+    2257             :     uint32_t _singleRegCase      : 2;    //!< Specifies what happens if all source operands share the same register.
+    2258             :     uint32_t _reserved           : 5;    //!< \internal
+    2259             :   };
+    2260             : 
+    2261             :   //! Detailed data about instruction's operation, requirements, and side-effects.
+    2262             :   struct OperationData {
+    2263             :     ASMJIT_INLINE uint32_t getOperationFlags() const noexcept { return _flags; }
+    2264        5834 :     ASMJIT_INLINE bool hasOperationFlag(uint32_t flag) const noexcept { return (_flags & flag) != 0; }
+    2265             : 
+    2266             :     ASMJIT_INLINE bool isMovCrDr() const noexcept { return hasOperationFlag(kOperationMovCrDr); }
+    2267             :     ASMJIT_INLINE bool isMovSsSd() const noexcept { return hasOperationFlag(kOperationMovSsSd); }
+    2268             : 
+    2269             :     ASMJIT_INLINE bool isPrefetch() const noexcept { return hasOperationFlag(kOperationPrefetch); }
+    2270             :     ASMJIT_INLINE bool isBarrier() const noexcept { return hasOperationFlag(kOperationBarrier); }
+    2271             :     ASMJIT_INLINE bool isVolatile() const noexcept { return hasOperationFlag(kOperationVolatile); }
+    2272             :     ASMJIT_INLINE bool isPrivileged() const noexcept { return hasOperationFlag(kOperationPrivileged); }
+    2273             : 
+    2274             :     ASMJIT_INLINE bool hasFeature(uint32_t feature) const noexcept {
+    2275             :       for (uint32_t i = 0; i < ASMJIT_ARRAY_SIZE(_features); i++)
+    2276             :         if (feature == _features[i])
+    2277             :           return true;
+    2278             :       return false;
+    2279             :     }
+    2280             : 
+    2281             :     ASMJIT_INLINE uint32_t getSpecialRegsR() const noexcept { return _specialRegsR; }
+    2282             :     ASMJIT_INLINE uint32_t getSpecialRegsW() const noexcept { return _specialRegsW; }
+    2283             : 
+    2284           0 :     ASMJIT_INLINE const uint8_t* getFeaturesData() const noexcept { return _features; }
+    2285           0 :     ASMJIT_INLINE const uint8_t* getFeaturesEnd() const noexcept { return _features + ASMJIT_ARRAY_SIZE(_features); }
+    2286             : 
+    2287             :     uint32_t _flags;                     //!< Operation flags.
+    2288             :     uint8_t _features[4];                //!< Features vector (max 4 features).
+    2289             :     uint32_t _specialRegsR;              //!< Special registers read.
+    2290             :     uint32_t _specialRegsW;              //!< Special registers written.
+    2291             :   };
+    2292             : 
+    2293             :   //! Contains data that can be used to convert SSE to AVX (or back).
+    2294             :   struct SseToAvxData {
+    2295             :     ASMJIT_INLINE uint32_t getMode() const noexcept { return _mode; }
+    2296             :     ASMJIT_INLINE int32_t getDelta() const noexcept { return _delta; }
+    2297             : 
+    2298             :     uint16_t _mode :  3;                 //!< SSE to AVX conversion mode, see \ref AvxConvMode.
+    2299             :     int16_t _delta : 13;                 //!< Delta to get a corresponding AVX instruction.
+    2300             :   };
+    2301             : 
+    2302             :   //! Data that is not related to a specific X86 instruction (not referenced by
+    2303             :   //! any tables).
+    2304             :   struct MiscData {
+    2305             :     uint32_t condToJcc[x86::kCondCount];
+    2306             :     uint32_t condToSetcc[x86::kCondCount];
+    2307             :     uint32_t condToCmovcc[x86::kCondCount];
+    2308             :     uint32_t reversedCond[x86::kCondCount];
+    2309             :   };
+    2310             : 
+    2311             :   // --------------------------------------------------------------------------
+    2312             :   // [Accessors]
+    2313             :   // --------------------------------------------------------------------------
+    2314             : 
+    2315             :   //! Get instruction name (null terminated).
+    2316             :   //!
+    2317             :   //! NOTE: If AsmJit was compiled with `ASMJIT_DISABLE_TEXT` then this will
+    2318             :   //! return an empty string (null terminated string of zero length).
+    2319             :   ASMJIT_INLINE const char* getName() const noexcept;
+    2320             :   //! Get index to `X86InstDB::nameData` of this instruction.
+    2321             :   //!
+    2322             :   //! NOTE: If AsmJit was compiled with `ASMJIT_DISABLE_TEXT` then this will
+    2323             :   //! always return zero.
+    2324           0 :   ASMJIT_INLINE uint32_t getNameDataIndex() const noexcept { return _nameDataIndex; }
+    2325             : 
+    2326             :   //! Get \ref CommonData of the instruction.
+    2327             :   ASMJIT_INLINE const CommonData& getCommonData() const noexcept;
+    2328             :   //! Get index to `X86InstDB::commonData` of this instruction.
+    2329             :   ASMJIT_INLINE uint32_t getCommonDataIndex() const noexcept { return _commonDataIndex; }
+    2330             : 
+    2331             :   //! Get \ref OperationData of the instruction.
+    2332             :   ASMJIT_INLINE const OperationData& getOperationData() const noexcept;
+    2333             :   //! Get index to `X86InstDB::operationData` of this instruction.
+    2334             :   ASMJIT_INLINE uint32_t getOperationDataIndex() const noexcept { return _operationDataIndex; }
+    2335             : 
+    2336             :   //! Get data that can be used to convert SSE instruction to AVX (or back).
+    2337             :   ASMJIT_INLINE const SseToAvxData& getSseToAvxData() const noexcept;
+    2338             :   //! Get index to `X86InstDB::sseToAvxData` of this instruction.
+    2339             :   ASMJIT_INLINE uint32_t getSseToAvxDataIndex() const noexcept { return _sseToAvxDataIndex; }
+    2340             : 
+    2341             :   //! Get instruction encoding, see \ref EncodingType.
+    2342       48362 :   ASMJIT_INLINE uint32_t getEncodingType() const noexcept { return _encodingType; }
+    2343             : 
+    2344             :   //! Get if the instruction has main opcode (rare, but it's possible it doesn't have).
+    2345             :   ASMJIT_INLINE bool hasMainOpCode() const noexcept { return _mainOpCode != 0; }
+    2346             :   //! Get main opcode, see \ref OpCodeBits.
+    2347       48362 :   ASMJIT_INLINE uint32_t getMainOpCode() const noexcept { return _mainOpCode; }
+    2348             : 
+    2349             :   //! Get if the instruction has alternative opcode.
+    2350             :   ASMJIT_INLINE bool hasAltOpCode() const noexcept { return getCommonData().hasAltOpCode(); }
+    2351             :   //! Get alternative opcode, see \ref OpCodeBits.
+    2352             :   ASMJIT_INLINE uint32_t getAltOpCode() const noexcept { return getCommonData().getAltOpCode(); }
+    2353             : 
+    2354             :   //! Get if the instruction has flag `flag`, see \ref Flags.
+    2355             :   ASMJIT_INLINE bool hasFlag(uint32_t flag) const noexcept { return getCommonData().hasFlag(flag); }
+    2356             :   //! Get instruction flags, see \ref Flags.
+    2357             :   ASMJIT_INLINE uint32_t getFlags() const noexcept { return getCommonData().getFlags(); }
+    2358             : 
+    2359             :   //! Get if the instruction is FPU instruction.
+    2360             :   ASMJIT_INLINE bool isFpu() const noexcept { return getCommonData().isFpu(); }
+    2361             :   //! Get if the instruction is MMX instruction that accesses MMX registersm, including EMMS.
+    2362             :   ASMJIT_INLINE bool isMmx() const noexcept { return getCommonData().isMmx(); }
+    2363             : 
+    2364             :   //! Get if the instruction is SSE|AVX|AVX512 instruction that accesses XMM|YMM|ZMM registers.
+    2365             :   ASMJIT_INLINE bool isVec() const noexcept { return getCommonData().isVec(); }
+    2366             :   //! Get if the instruction is SSE+ (SSE4.2, AES, SHA included) instruction that accesses XMM registers.
+    2367             :   ASMJIT_INLINE bool isSse() const noexcept { return getCommonData().isSse(); }
+    2368             :   //! Get if the instruction is AVX+ (FMA included) instruction that accesses XMM|YMM|ZMM registers.
+    2369             :   ASMJIT_INLINE bool isAvx() const noexcept { return getCommonData().isAvx(); }
+    2370             : 
+    2371             :   //! Get if the instruction can be prefixed by LOCK prefix.
+    2372             :   ASMJIT_INLINE bool isLockEnabled() const noexcept { return getCommonData().isLockEnabled(); }
+    2373             :   //! Get if the instruction can be prefixed by REP prefix.
+    2374             :   ASMJIT_INLINE bool isRepEnabled() const noexcept { return getCommonData().isRepEnabled(); }
+    2375             :   //! Get if the instruction can be prefixed by REPZ prefix.
+    2376             :   ASMJIT_INLINE bool isRepzEnabled() const noexcept { return getCommonData().isRepzEnabled(); }
+    2377             :   //! Get if the instruction can be prefixed by REPNZ prefix.
+    2378             :   ASMJIT_INLINE bool isRepnzEnabled() const noexcept { return getCommonData().isRepnzEnabled(); }
+    2379             : 
+    2380             :   //! Get if the instruction uses MIB.
+    2381             :   ASMJIT_INLINE bool isMibOp() const noexcept { return getCommonData().isMibOp(); }
+    2382             :   //! Get if the instruction uses VSIB.
+    2383             :   ASMJIT_INLINE bool isVsibOp() const noexcept { return getCommonData().isVsibOp(); }
+    2384             :   //! Get if the instruction uses VEX (can be set together with EVEX if both are encodable).
+    2385             :   ASMJIT_INLINE bool isVex() const noexcept { return getCommonData().isVex(); }
+    2386             :   //! Get if the instruction uses EVEX (can be set together with VEX if both are encodable).
+    2387             :   ASMJIT_INLINE bool isEvex() const noexcept { return getCommonData().isEvex(); }
+    2388             : 
+    2389             :   //! Get if the instruction supports AVX512 masking {k}.
+    2390             :   ASMJIT_INLINE bool hasAvx512K() const noexcept { return getCommonData().hasAvx512K(); }
+    2391             :   //! Get if the instruction supports AVX512 zeroing {k}{z}.
+    2392             :   ASMJIT_INLINE bool hasAvx512Z() const noexcept { return getCommonData().hasAvx512Z(); }
+    2393             :   //! Get if the instruction supports AVX512 embedded-rounding {er}.
+    2394             :   ASMJIT_INLINE bool hasAvx512ER() const noexcept { return getCommonData().hasAvx512ER(); }
+    2395             :   //! Get if the instruction supports AVX512 suppress-all-exceptions {sae}.
+    2396             :   ASMJIT_INLINE bool hasAvx512SAE() const noexcept { return getCommonData().hasAvx512SAE(); }
+    2397             :   //! Get if the instruction supports AVX512 broadcast (either 32-bit or 64-bit).
+    2398             :   ASMJIT_INLINE bool hasAvx512B() const noexcept { return getCommonData().hasAvx512B(); }
+    2399             :   //! Get if the instruction supports AVX512 broadcast (32-bit).
+    2400             :   ASMJIT_INLINE bool hasAvx512B32() const noexcept { return getCommonData().hasAvx512B32(); }
+    2401             :   //! Get if the instruction supports AVX512 broadcast (64-bit).
+    2402             :   ASMJIT_INLINE bool hasAvx512B64() const noexcept { return getCommonData().hasAvx512B64(); }
+    2403             : 
+    2404             :   ASMJIT_INLINE uint32_t getISignatureIndex() const noexcept { return getCommonData().getISignatureIndex(); }
+    2405             :   ASMJIT_INLINE uint32_t getISignatureCount() const noexcept { return getCommonData().getISignatureCount(); }
+    2406             : 
+    2407             :   ASMJIT_INLINE const ISignature* getISignatureData() const noexcept { return getCommonData().getISignatureData(); }
+    2408             :   ASMJIT_INLINE const ISignature* getISignatureEnd() const noexcept { return getCommonData().getISignatureEnd(); }
+    2409             : 
+    2410             :   // --------------------------------------------------------------------------
+    2411             :   // [Get]
+    2412             :   // --------------------------------------------------------------------------
+    2413             : 
+    2414             :   //! Get if the `instId` is defined (counts also Inst::kIdNone, which must be zero).
+    2415             :   static ASMJIT_INLINE bool isDefinedId(uint32_t instId) noexcept { return instId < _kIdCount; }
+    2416             : 
+    2417             :   //! Get instruction information based on the instruction `instId`.
+    2418             :   //!
+    2419             :   //! NOTE: `instId` has to be a valid instruction ID, it can't be greater than
+    2420             :   //! or equal to `X86Inst::_kIdCount`. It asserts in debug mode.
+    2421             :   static ASMJIT_INLINE const X86Inst& getInst(uint32_t instId) noexcept;
+    2422             : 
+    2423             :   // --------------------------------------------------------------------------
+    2424             :   // [Utilities]
+    2425             :   // --------------------------------------------------------------------------
+    2426             : 
+    2427             :   static ASMJIT_INLINE const MiscData& getMiscData() noexcept;
+    2428             : 
+    2429             :   //! Get the equivalent of a negated condition code.
+    2430             :   static ASMJIT_INLINE uint32_t negateCond(uint32_t cond) noexcept {
+    2431             :     ASMJIT_ASSERT(cond < x86::kCondCount);
+    2432             :     return cond ^ 1;
+    2433             :   }
+    2434             : 
+    2435             :   //! Convert a condition code into a condition code that reverses the
+    2436             :   //! corresponding operands of a comparison.
+    2437             :   static ASMJIT_INLINE uint32_t reverseCond(uint32_t cond) noexcept {
+    2438             :     ASMJIT_ASSERT(cond < x86::kCondCount);
+    2439             :     return getMiscData().reversedCond[cond];
+    2440             :   }
+    2441             : 
+    2442             :   //! Translate a condition code `cc` to a "cmovcc" instruction id.
+    2443             :   static ASMJIT_INLINE uint32_t condToCmovcc(uint32_t cond) noexcept {
+    2444             :     ASMJIT_ASSERT(cond < x86::kCondCount);
+    2445             :     return getMiscData().condToCmovcc[cond];
+    2446             :   }
+    2447             : 
+    2448             :   //! Translate a condition code `cc` to a "jcc" instruction id.
+    2449             :   static ASMJIT_INLINE uint32_t condToJcc(uint32_t cond) noexcept {
+    2450             :     ASMJIT_ASSERT(cond < x86::kCondCount);
+    2451             :     return getMiscData().condToJcc[cond];
+    2452             :   }
+    2453             : 
+    2454             :   //! Translate a condition code `cc` to a "setcc" instruction id.
+    2455             :   static ASMJIT_INLINE uint32_t condToSetcc(uint32_t cond) noexcept {
+    2456             :     ASMJIT_ASSERT(cond < x86::kCondCount);
+    2457             :     return getMiscData().condToSetcc[cond];
+    2458             :   }
+    2459             : 
+    2460             :   //! Get a 'kmov?' instruction by register `size`.
+    2461             :   static ASMJIT_INLINE uint32_t kmovIdFromSize(uint32_t size) noexcept {
+    2462             :     return size == 1 ? X86Inst::kIdKmovb :
+    2463             :            size == 2 ? X86Inst::kIdKmovw :
+    2464             :            size == 4 ? X86Inst::kIdKmovd : X86Inst::kIdKmovq;
+    2465             :   }
+    2466             : 
+    2467             :   // --------------------------------------------------------------------------
+    2468             :   // [Id <-> Name]
+    2469             :   // --------------------------------------------------------------------------
+    2470             : 
+    2471             : #if !defined(ASMJIT_DISABLE_TEXT)
+    2472             :   //! Get an instruction ID from a given instruction `name`.
+    2473             :   //!
+    2474             :   //! NOTE: Instruction name MUST BE in lowercase, otherwise there will be no
+    2475             :   //! match. If there is an exact match the instruction id is returned, otherwise
+    2476             :   //! `kInvalidInstId` (zero) is returned instead. The given `name` doesn't have
+    2477             :   //! to be null-terminated if `len` is provided.
+    2478             :   ASMJIT_API static uint32_t getIdByName(const char* name, size_t len = Globals::kInvalidIndex) noexcept;
+    2479             : 
+    2480             :   //! Get an instruction name from a given instruction id `instId`.
+    2481             :   ASMJIT_API static const char* getNameById(uint32_t instId) noexcept;
+    2482             : #endif // !ASMJIT_DISABLE_TEXT
+    2483             : 
+    2484             :   // --------------------------------------------------------------------------
+    2485             :   // [Members]
+    2486             :   // --------------------------------------------------------------------------
+    2487             : 
+    2488             :   uint32_t _encodingType       : 8;      //!< Encoding type.
+    2489             :   uint32_t _nameDataIndex      : 14;     //!< Index to `X86InstDB::nameData` table.
+    2490             :   uint32_t _commonDataIndex    : 10;     //!< Index to `X86InstDB::commonData` table.
+    2491             :   uint32_t _operationDataIndex : 8;      //!< Index to `X86InstDB::operationData` table.
+    2492             :   uint32_t _sseToAvxDataIndex  : 7;      //!< Index to `X86InstDB::sseToAvxData` table.
+    2493             :   uint32_t _reserved           : 17;     //!< \internal
+    2494             :   uint32_t _mainOpCode;                  //!< Instruction's primary opcode.
+    2495             : };
+    2496             : 
+    2497             : //! X86 instruction data under a single namespace.
+    2498             : struct X86InstDB {
+    2499             :   ASMJIT_API static const X86Inst instData[];
+    2500             :   ASMJIT_API static const uint32_t altOpCodeData[];
+    2501             : 
+    2502             :   ASMJIT_API static const X86Inst::CommonData commonData[];
+    2503             :   ASMJIT_API static const X86Inst::OperationData operationData[];
+    2504             :   ASMJIT_API static const X86Inst::SseToAvxData sseToAvxData[];
+    2505             : 
+    2506             :   ASMJIT_API static const char nameData[];
+    2507             :   ASMJIT_API static const X86Inst::MiscData miscData;
+    2508             : 
+    2509             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+    2510             :   ASMJIT_API static const X86Inst::ISignature iSignatureData[];
+    2511             :   ASMJIT_API static const X86Inst::OSignature oSignatureData[];
+    2512             : #endif // ASMJIT_DISABLE_VALIDATION
+    2513             : };
+    2514             : 
+    2515             : ASMJIT_INLINE const X86Inst& X86Inst::getInst(uint32_t instId) noexcept {
+    2516             :   ASMJIT_ASSERT(instId < X86Inst::_kIdCount);
+    2517             :   return X86InstDB::instData[instId];
+    2518             : }
+    2519             : 
+    2520           0 : ASMJIT_INLINE const char* X86Inst::getName() const noexcept { return &X86InstDB::nameData[_nameDataIndex]; }
+    2521       81468 : ASMJIT_INLINE const X86Inst::CommonData& X86Inst::getCommonData() const noexcept { return X86InstDB::commonData[_commonDataIndex]; }
+    2522        5834 : ASMJIT_INLINE const X86Inst::OperationData& X86Inst::getOperationData() const noexcept { return X86InstDB::operationData[_operationDataIndex]; }
+    2523             : ASMJIT_INLINE const X86Inst::SseToAvxData& X86Inst::getSseToAvxData() const noexcept { return X86InstDB::sseToAvxData[_sseToAvxDataIndex]; }
+    2524        6510 : ASMJIT_INLINE uint32_t X86Inst::CommonData::getAltOpCode() const noexcept { return X86InstDB::altOpCodeData[_altOpCodeIndex]; }
+    2525             : ASMJIT_INLINE const X86Inst::MiscData& X86Inst::getMiscData() noexcept { return X86InstDB::miscData; }
+    2526             : 
+    2527             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+    2528             : ASMJIT_INLINE const X86Inst::ISignature* X86Inst::CommonData::getISignatureData() const noexcept { return X86InstDB::iSignatureData + _iSignatureIndex; }
+    2529             : ASMJIT_INLINE const X86Inst::ISignature* X86Inst::CommonData::getISignatureEnd() const noexcept { return X86InstDB::iSignatureData + _iSignatureIndex + _iSignatureCount; }
+    2530             : #else
+    2531             : ASMJIT_INLINE const X86Inst::ISignature* X86Inst::CommonData::getISignatureData() const noexcept { return static_cast<const X86Inst::ISignature*>(nullptr); }
+    2532             : ASMJIT_INLINE const X86Inst::ISignature* X86Inst::CommonData::getISignatureEnd() const noexcept { return static_cast<const X86Inst::ISignature*>(nullptr); }
+    2533             : #endif // ASMJIT_DISABLE_VALIDATION
+    2534             : 
+    2535             : //! \}
+    2536             : 
+    2537             : } // asmjit namespace
+    2538             : } // namespace PLMD
+    2539             : 
+    2540             : // [Api-End]
+    2541             : #include "./asmjit_apiend.h"
+    2542             : 
+    2543             : // [Guard]
+    2544             : #endif // _ASMJIT_X86_X86INST_H
+    2545             : #pragma GCC diagnostic pop
+    2546             : #endif // __PLUMED_HAS_ASMJIT
+    2547             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86instimpl.cpp.func-sort-c.html b/coverage-libs/asmjit/x86instimpl.cpp.func-sort-c.html new file mode 100644 index 000000000000..8d984e9e93f8 --- /dev/null +++ b/coverage-libs/asmjit/x86instimpl.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86instimpl.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86instimpl.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01700.0 %
Date:2024-02-22 21:58:47Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86InstImpl13checkFeaturesEjRKNS0_4Inst6DetailEPKNS0_8Operand_EjRNS0_11CpuFeaturesE0
_ZN4PLMD6asmjit11X86InstImpl8validateEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL18x86GetRegTypesMaskEPKNS0_8Operand_Ej0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86instimpl.cpp.func.html b/coverage-libs/asmjit/x86instimpl.cpp.func.html new file mode 100644 index 000000000000..67f0260f4c2b --- /dev/null +++ b/coverage-libs/asmjit/x86instimpl.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86instimpl.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86instimpl.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01700.0 %
Date:2024-02-22 21:58:47Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86InstImpl13checkFeaturesEjRKNS0_4Inst6DetailEPKNS0_8Operand_EjRNS0_11CpuFeaturesE0
_ZN4PLMD6asmjit11X86InstImpl8validateEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL18x86GetRegTypesMaskEPKNS0_8Operand_Ej0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86instimpl.cpp.gcov.html b/coverage-libs/asmjit/x86instimpl.cpp.gcov.html new file mode 100644 index 000000000000..b0e1a0298d4e --- /dev/null +++ b/coverage-libs/asmjit/x86instimpl.cpp.gcov.html @@ -0,0 +1,834 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86instimpl.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86instimpl.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:01700.0 %
Date:2024-02-22 21:58:47Functions:030.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./misc_p.h"
+      34             : #include "./utils.h"
+      35             : #include "./x86instimpl_p.h"
+      36             : #include "./x86operand.h"
+      37             : 
+      38             : // [Api-Begin]
+      39             : #include "./asmjit_apibegin.h"
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace asmjit {
+      43             : 
+      44             : // ============================================================================
+      45             : // [asmjit::X86InstImpl - Validate]
+      46             : // ============================================================================
+      47             : 
+      48             : #if !defined(ASMJIT_DISABLE_VALIDATION)
+      49             : template<uint32_t RegType>
+      50             : struct X86OpTypeFromRegTypeT {
+      51             :   enum {
+      52             :     kValue = (RegType == X86Reg::kRegGpbLo) ? X86Inst::kOpGpbLo :
+      53             :              (RegType == X86Reg::kRegGpbHi) ? X86Inst::kOpGpbHi :
+      54             :              (RegType == X86Reg::kRegGpw  ) ? X86Inst::kOpGpw   :
+      55             :              (RegType == X86Reg::kRegGpd  ) ? X86Inst::kOpGpd   :
+      56             :              (RegType == X86Reg::kRegGpq  ) ? X86Inst::kOpGpq   :
+      57             :              (RegType == X86Reg::kRegXmm  ) ? X86Inst::kOpXmm   :
+      58             :              (RegType == X86Reg::kRegYmm  ) ? X86Inst::kOpYmm   :
+      59             :              (RegType == X86Reg::kRegZmm  ) ? X86Inst::kOpZmm   :
+      60             :              (RegType == X86Reg::kRegRip  ) ? X86Inst::kOpNone  :
+      61             :              (RegType == X86Reg::kRegSeg  ) ? X86Inst::kOpSeg   :
+      62             :              (RegType == X86Reg::kRegFp   ) ? X86Inst::kOpFp    :
+      63             :              (RegType == X86Reg::kRegMm   ) ? X86Inst::kOpMm    :
+      64             :              (RegType == X86Reg::kRegK    ) ? X86Inst::kOpK     :
+      65             :              (RegType == X86Reg::kRegBnd  ) ? X86Inst::kOpBnd   :
+      66             :              (RegType == X86Reg::kRegCr   ) ? X86Inst::kOpCr    :
+      67             :              (RegType == X86Reg::kRegDr   ) ? X86Inst::kOpDr    : X86Inst::kOpNone
+      68             :   };
+      69             : };
+      70             : 
+      71             : template<uint32_t RegType>
+      72             : struct X86RegMaskFromRegTypeT {
+      73             :   enum {
+      74             :     kMask = (RegType == X86Reg::kRegGpbLo) ? 0x0000000FU :
+      75             :             (RegType == X86Reg::kRegGpbHi) ? 0x0000000FU :
+      76             :             (RegType == X86Reg::kRegGpw  ) ? 0x000000FFU :
+      77             :             (RegType == X86Reg::kRegGpd  ) ? 0x000000FFU :
+      78             :             (RegType == X86Reg::kRegGpq  ) ? 0x000000FFU :
+      79             :             (RegType == X86Reg::kRegXmm  ) ? 0x000000FFU :
+      80             :             (RegType == X86Reg::kRegYmm  ) ? 0x000000FFU :
+      81             :             (RegType == X86Reg::kRegZmm  ) ? 0x000000FFU :
+      82             :             (RegType == X86Reg::kRegRip  ) ? 0x00000001U :
+      83             :             (RegType == X86Reg::kRegSeg  ) ? 0x0000007EU : // [ES|CS|SS|DS|FS|GS]
+      84             :             (RegType == X86Reg::kRegFp   ) ? 0x000000FFU :
+      85             :             (RegType == X86Reg::kRegMm   ) ? 0x000000FFU :
+      86             :             (RegType == X86Reg::kRegK    ) ? 0x000000FFU :
+      87             :             (RegType == X86Reg::kRegBnd  ) ? 0x0000000FU :
+      88             :             (RegType == X86Reg::kRegCr   ) ? 0x0000FFFFU :
+      89             :             (RegType == X86Reg::kRegDr   ) ? 0x000000FFU : X86Inst::kOpNone
+      90             :   };
+      91             : };
+      92             : 
+      93             : template<uint32_t RegType>
+      94             : struct X64RegMaskFromRegTypeT {
+      95             :   enum {
+      96             :     kMask = (RegType == X86Reg::kRegGpbLo) ? 0x0000FFFFU :
+      97             :             (RegType == X86Reg::kRegGpbHi) ? 0x0000000FU :
+      98             :             (RegType == X86Reg::kRegGpw  ) ? 0x0000FFFFU :
+      99             :             (RegType == X86Reg::kRegGpd  ) ? 0x0000FFFFU :
+     100             :             (RegType == X86Reg::kRegGpq  ) ? 0x0000FFFFU :
+     101             :             (RegType == X86Reg::kRegXmm  ) ? 0xFFFFFFFFU :
+     102             :             (RegType == X86Reg::kRegYmm  ) ? 0xFFFFFFFFU :
+     103             :             (RegType == X86Reg::kRegZmm  ) ? 0xFFFFFFFFU :
+     104             :             (RegType == X86Reg::kRegRip  ) ? 0x00000001U :
+     105             :             (RegType == X86Reg::kRegSeg  ) ? 0x0000007EU : // [ES|CS|SS|DS|FS|GS]
+     106             :             (RegType == X86Reg::kRegFp   ) ? 0x000000FFU :
+     107             :             (RegType == X86Reg::kRegMm   ) ? 0x000000FFU :
+     108             :             (RegType == X86Reg::kRegK    ) ? 0x000000FFU :
+     109             :             (RegType == X86Reg::kRegBnd  ) ? 0x0000000FU :
+     110             :             (RegType == X86Reg::kRegCr   ) ? 0x0000FFFFU :
+     111             :             (RegType == X86Reg::kRegDr   ) ? 0x0000FFFFU : X86Inst::kOpNone
+     112             :   };
+     113             : };
+     114             : 
+     115             : struct X86ValidationData {
+     116             :   //! Allowed registers by reg-type (X86::kReg...).
+     117             :   uint32_t allowedRegMask[X86Reg::kRegMax + 1];
+     118             :   uint32_t allowedMemBaseRegs;
+     119             :   uint32_t allowedMemIndexRegs;
+     120             : };
+     121             : 
+     122             : static const uint32_t _x86OpFlagFromRegType[X86Reg::kRegMax + 1] = {
+     123             :   ASMJIT_TABLE_T_32(X86OpTypeFromRegTypeT, kValue, 0)
+     124             : };
+     125             : 
+     126             : static const X86ValidationData _x86ValidationData = {
+     127             :   { ASMJIT_TABLE_T_32(X86RegMaskFromRegTypeT, kMask, 0) },
+     128             :   (1U << X86Reg::kRegGpw) | (1U << X86Reg::kRegGpd) | (1U << X86Reg::kRegRip) | (1U << Label::kLabelTag),
+     129             :   (1U << X86Reg::kRegGpw) | (1U << X86Reg::kRegGpd) | (1U << X86Reg::kRegXmm) | (1U << X86Reg::kRegYmm) | (1U << X86Reg::kRegZmm)
+     130             : };
+     131             : 
+     132             : static const X86ValidationData _x64ValidationData = {
+     133             :   { ASMJIT_TABLE_T_32(X64RegMaskFromRegTypeT, kMask, 0) },
+     134             :   (1U << X86Reg::kRegGpd) | (1U << X86Reg::kRegGpq) | (1U << X86Reg::kRegRip) | (1U << Label::kLabelTag),
+     135             :   (1U << X86Reg::kRegGpd) | (1U << X86Reg::kRegGpq) | (1U << X86Reg::kRegXmm) | (1U << X86Reg::kRegYmm) | (1U << X86Reg::kRegZmm)
+     136             : };
+     137             : 
+     138             : static ASMJIT_INLINE bool x86CheckOSig(const X86Inst::OSignature& op, const X86Inst::OSignature& ref, bool& immOutOfRange) noexcept {
+     139             :   // Fail if operand types are incompatible.
+     140           0 :   uint32_t opFlags = op.flags;
+     141           0 :   if ((opFlags & ref.flags) == 0) {
+     142             :     // Mark temporarily `immOutOfRange` so we can return a more descriptive error.
+     143           0 :     if ((opFlags & X86Inst::kOpAllImm) && (ref.flags & X86Inst::kOpAllImm)) {
+     144             :       immOutOfRange = true;
+     145           0 :       return true;
+     146             :     }
+     147             : 
+     148             :     return false;
+     149             :   }
+     150             : 
+     151             :   // Fail if memory specific flags and sizes are incompatibles.
+     152           0 :   uint32_t opMemFlags = op.memFlags;
+     153           0 :   if (opMemFlags != 0) {
+     154           0 :     uint32_t refMemFlags = ref.memFlags;
+     155           0 :     if ((refMemFlags & opMemFlags) == 0)
+     156             :       return false;
+     157             : 
+     158           0 :     if ((refMemFlags & X86Inst::kMemOpBaseOnly) && !(opMemFlags & X86Inst::kMemOpBaseOnly))
+     159             :       return false;
+     160             :   }
+     161             : 
+     162             :   // Specific register index.
+     163           0 :   if (opFlags & X86Inst::kOpAllRegs) {
+     164           0 :     uint32_t refRegMask = ref.regMask;
+     165           0 :     if (refRegMask && !(op.regMask & refRegMask))
+     166           0 :       return false;
+     167             :   }
+     168             : 
+     169             :   return true;
+     170             : }
+     171             : 
+     172           0 : ASMJIT_FAVOR_SIZE Error X86InstImpl::validate(uint32_t archType, const Inst::Detail& detail, const Operand_* operands, uint32_t count) noexcept {
+     173             :   uint32_t i;
+     174             :   uint32_t archMask;
+     175             :   const X86ValidationData* vd;
+     176             : 
+     177           0 :   if (!ArchInfo::isX86Family(archType))
+     178             :     return DebugUtils::errored(kErrorInvalidArch);
+     179             : 
+     180           0 :   if (archType == ArchInfo::kTypeX86) {
+     181             :     vd = &_x86ValidationData;
+     182             :     archMask = X86Inst::kArchMaskX86;
+     183             :   }
+     184             :   else {
+     185             :     vd = &_x64ValidationData;
+     186             :     archMask = X86Inst::kArchMaskX64;
+     187             :   }
+     188             : 
+     189             :   // Get the instruction data.
+     190           0 :   uint32_t instId = detail.instId;
+     191           0 :   uint32_t options = detail.options;
+     192             : 
+     193           0 :   if (ASMJIT_UNLIKELY(instId >= X86Inst::_kIdCount))
+     194             :     return DebugUtils::errored(kErrorInvalidArgument);
+     195             : 
+     196             :   const X86Inst* iData = &X86InstDB::instData[instId];
+     197             :   uint32_t iFlags = iData->getFlags();
+     198             : 
+     199             :   // Validate LOCK, XACQUIRE, and XRELEASE prefixes.
+     200             :   const uint32_t kLockXAcqRel = X86Inst::kOptionXAcquire | X86Inst::kOptionXRelease;
+     201           0 :   if (options & (X86Inst::kOptionLock | kLockXAcqRel)) {
+     202           0 :     if (options & X86Inst::kOptionLock) {
+     203           0 :       if (ASMJIT_UNLIKELY(!(iFlags & X86Inst::kFlagLock) && !(options & kLockXAcqRel)))
+     204             :         return DebugUtils::errored(kErrorInvalidLockPrefix);
+     205             : 
+     206           0 :       if (ASMJIT_UNLIKELY(count < 1 || !operands[0].isMem()))
+     207             :         return DebugUtils::errored(kErrorInvalidLockPrefix);
+     208             :     }
+     209             : 
+     210           0 :     if (options & kLockXAcqRel) {
+     211           0 :       if (ASMJIT_UNLIKELY(!(options & X86Inst::kOptionLock) || (options & kLockXAcqRel) == kLockXAcqRel))
+     212             :         return DebugUtils::errored(kErrorInvalidPrefixCombination);
+     213             : 
+     214           0 :       if (ASMJIT_UNLIKELY((options & X86Inst::kOptionXAcquire) && !(iFlags & X86Inst::kFlagXAcquire)))
+     215             :         return DebugUtils::errored(kErrorInvalidXAcquirePrefix);
+     216             : 
+     217           0 :       if (ASMJIT_UNLIKELY((options & X86Inst::kOptionXRelease) && !(iFlags & X86Inst::kFlagXRelease)))
+     218             :         return DebugUtils::errored(kErrorInvalidXReleasePrefix);
+     219             :     }
+     220             :   }
+     221             : 
+     222             :   // Validate REP and REPNZ prefixes.
+     223             :   const uint32_t kRepRepRepnz = X86Inst::kOptionRep | X86Inst::kOptionRepnz;
+     224           0 :   if (options & kRepRepRepnz) {
+     225           0 :     if (ASMJIT_UNLIKELY((options & kRepRepRepnz) == kRepRepRepnz))
+     226             :       return DebugUtils::errored(kErrorInvalidPrefixCombination);
+     227             : 
+     228           0 :     if (ASMJIT_UNLIKELY((options & X86Inst::kOptionRep) && !(iFlags & X86Inst::kFlagRep)))
+     229             :       return DebugUtils::errored(kErrorInvalidRepPrefix);
+     230             : 
+     231           0 :     if (ASMJIT_UNLIKELY((options & X86Inst::kOptionRepnz) && !(iFlags & X86Inst::kFlagRepnz)))
+     232             :       return DebugUtils::errored(kErrorInvalidRepPrefix);
+     233             : 
+     234             :     // TODO: Validate extraReg {cx|ecx|rcx}.
+     235             :   }
+     236             : 
+     237             :   // Translate the given operands to `X86Inst::OSignature`.
+     238             :   X86Inst::OSignature oSigTranslated[6];
+     239             :   uint32_t combinedOpFlags = 0;
+     240             :   uint32_t combinedRegMask = 0;
+     241             : 
+     242             :   const X86Mem* memOp = nullptr;
+     243             : 
+     244           0 :   for (i = 0; i < count; i++) {
+     245           0 :     const Operand_& op = operands[i];
+     246           0 :     if (op.getOp() == Operand::kOpNone) break;
+     247             : 
+     248             :     uint32_t opFlags = 0;
+     249             :     uint32_t memFlags = 0;
+     250             :     uint32_t regMask = 0;
+     251             : 
+     252           0 :     switch (op.getOp()) {
+     253             :       case Operand::kOpReg: {
+     254             :         uint32_t regType = op.as<Reg>().getType();
+     255           0 :         if (ASMJIT_UNLIKELY(regType >= X86Reg::kRegCount))
+     256             :           return DebugUtils::errored(kErrorInvalidRegType);
+     257             : 
+     258           0 :         opFlags = _x86OpFlagFromRegType[regType];
+     259           0 :         if (ASMJIT_UNLIKELY(opFlags == 0))
+     260             :           return DebugUtils::errored(kErrorInvalidRegType);
+     261             : 
+     262             :         // If `regId` is equal or greater than Operand::kPackedIdMin it means
+     263             :         // that the register is virtual and its index will be assigned later
+     264             :         // by the register allocator. We must pass unless asked to disallow
+     265             :         // virtual registers.
+     266             :         // TODO: We need an option to refuse virtual regs here.
+     267             :         uint32_t regId = op.getId();
+     268           0 :         if (regId < Operand::kPackedIdMin) {
+     269           0 :           if (ASMJIT_UNLIKELY(regId >= 32))
+     270             :             return DebugUtils::errored(kErrorInvalidPhysId);
+     271             : 
+     272             :           regMask = Utils::mask(regId);
+     273           0 :           if (ASMJIT_UNLIKELY((vd->allowedRegMask[regType] & regMask) == 0))
+     274             :             return DebugUtils::errored(kErrorInvalidPhysId);
+     275             : 
+     276           0 :           combinedRegMask |= regMask;
+     277             :         }
+     278             :         else {
+     279             :           regMask = 0xFFFFFFFFU;
+     280             :         }
+     281             :         break;
+     282             :       }
+     283             : 
+     284             :       // TODO: Validate base and index and combine with `combinedRegMask`.
+     285             :       case Operand::kOpMem: {
+     286             :         const X86Mem& m = op.as<X86Mem>();
+     287             : 
+     288             :         uint32_t baseType = m.getBaseType();
+     289             :         uint32_t indexType = m.getIndexType();
+     290             : 
+     291             :         memOp = &m;
+     292             : 
+     293           0 :         if (m.getSegmentId() > 6)
+     294             :           return DebugUtils::errored(kErrorInvalidSegment);
+     295             : 
+     296           0 :         if (baseType) {
+     297             :           uint32_t baseId = m.getBaseId();
+     298             : 
+     299           0 :           if (m.isRegHome()) {
+     300             :             // Home address of virtual register. In such case we don't want to
+     301             :             // validate the type of the base register as it will always be patched
+     302             :             // to ESP|RSP.
+     303             :           }
+     304             :           else {
+     305           0 :             if (ASMJIT_UNLIKELY((vd->allowedMemBaseRegs & (1U << baseType)) == 0))
+     306             :               return DebugUtils::errored(kErrorInvalidAddress);
+     307             :           }
+     308             : 
+     309             :           // Create information that will be validated only if this is an implicit
+     310             :           // memory operand. Basically only usable for string instructions and other
+     311             :           // instructions where memory operand is implicit and has 'seg:[reg]' form.
+     312           0 :           if (baseId < Operand::kPackedIdMin) {
+     313             :             // Physical base id.
+     314             :             regMask = Utils::mask(baseId);
+     315           0 :             combinedRegMask |= regMask;
+     316             :           }
+     317             :           else {
+     318             :             // Virtual base id - will the whole mask for implicit mem validation.
+     319             :             // The register is not assigned yet, so we cannot predict the phys id.
+     320             :             regMask = 0xFFFFFFFFU;
+     321             :           }
+     322             : 
+     323           0 :           if (!indexType && !m.getOffsetLo32())
+     324             :             memFlags |= X86Inst::kMemOpBaseOnly;
+     325             :         }
+     326             :         else {
+     327             :           // Base is an address, make sure that the address doesn't overflow 32-bit
+     328             :           // integer (either int32_t or uint32_t) in 32-bit targets.
+     329             :           int64_t offset = m.getOffset();
+     330           0 :           if (archMask == X86Inst::kArchMaskX86 && !Utils::isInt32(offset) && !Utils::isUInt32(offset))
+     331             :             return DebugUtils::errored(kErrorInvalidAddress);
+     332             :         }
+     333             : 
+     334           0 :         if (indexType) {
+     335           0 :           if (ASMJIT_UNLIKELY((vd->allowedMemIndexRegs & (1U << indexType)) == 0))
+     336             :             return DebugUtils::errored(kErrorInvalidAddress);
+     337             : 
+     338           0 :           if (indexType == X86Reg::kRegXmm) {
+     339             :             opFlags |= X86Inst::kOpVm;
+     340           0 :             memFlags |= X86Inst::kMemOpVm32x | X86Inst::kMemOpVm64x;
+     341             :           }
+     342           0 :           else if (indexType == X86Reg::kRegYmm) {
+     343             :             opFlags |= X86Inst::kOpVm;
+     344           0 :             memFlags |= X86Inst::kMemOpVm32y | X86Inst::kMemOpVm64y;
+     345             :           }
+     346           0 :           else if (indexType == X86Reg::kRegZmm) {
+     347             :             opFlags |= X86Inst::kOpVm;
+     348           0 :             memFlags |= X86Inst::kMemOpVm32z | X86Inst::kMemOpVm64z;
+     349             :           }
+     350             :           else {
+     351             :             opFlags |= X86Inst::kOpMem;
+     352           0 :             if (baseType)
+     353           0 :               memFlags |= X86Inst::kMemOpMib;
+     354             :           }
+     355             : 
+     356             :           // [RIP + {XMM|YMM|ZMM}] is not allowed.
+     357           0 :           if (baseType == X86Reg::kRegRip && (opFlags & X86Inst::kOpVm))
+     358             :             return DebugUtils::errored(kErrorInvalidAddress);
+     359             : 
+     360             :           uint32_t indexId = m.getIndexId();
+     361           0 :           if (indexId < Operand::kPackedIdMin)
+     362           0 :             combinedRegMask |= Utils::mask(indexId);
+     363             : 
+     364             :           // Only used for implicit memory operands having 'seg:[reg]' form, so clear it.
+     365             :           regMask = 0;
+     366             :         }
+     367             :         else {
+     368             :           opFlags |= X86Inst::kOpMem;
+     369             :         }
+     370             : 
+     371             :         switch (m.getSize()) {
+     372           0 :           case  0: memFlags |= X86Inst::kMemOpAny ; break;
+     373           0 :           case  1: memFlags |= X86Inst::kMemOpM8  ; break;
+     374           0 :           case  2: memFlags |= X86Inst::kMemOpM16 ; break;
+     375           0 :           case  4: memFlags |= X86Inst::kMemOpM32 ; break;
+     376           0 :           case  6: memFlags |= X86Inst::kMemOpM48 ; break;
+     377           0 :           case  8: memFlags |= X86Inst::kMemOpM64 ; break;
+     378           0 :           case 10: memFlags |= X86Inst::kMemOpM80 ; break;
+     379           0 :           case 16: memFlags |= X86Inst::kMemOpM128; break;
+     380           0 :           case 32: memFlags |= X86Inst::kMemOpM256; break;
+     381           0 :           case 64: memFlags |= X86Inst::kMemOpM512; break;
+     382             :           default:
+     383             :             return DebugUtils::errored(kErrorInvalidOperandSize);
+     384             :         }
+     385             : 
+     386             :         break;
+     387             :       }
+     388             : 
+     389             :       case Operand::kOpImm: {
+     390             :         uint64_t immValue = op.as<Imm>().getUInt64();
+     391             :         uint32_t immFlags = 0;
+     392             : 
+     393           0 :         if (static_cast<int64_t>(immValue) >= 0) {
+     394             :           const uint32_t k32AndMore = X86Inst::kOpI32 | X86Inst::kOpU32 |
+     395             :                                       X86Inst::kOpI64 | X86Inst::kOpU64 ;
+     396             : 
+     397           0 :           if (immValue <= 0xFU)
+     398             :             immFlags = X86Inst::kOpU4 | X86Inst::kOpI8 | X86Inst::kOpU8 | X86Inst::kOpI16 | X86Inst::kOpU16 | k32AndMore;
+     399           0 :           else if (immValue <= 0x7FU)
+     400             :             immFlags = X86Inst::kOpI8 | X86Inst::kOpU8 | X86Inst::kOpI16 | X86Inst::kOpU16 | k32AndMore;
+     401           0 :           else if (immValue <= 0xFFU)
+     402             :             immFlags = X86Inst::kOpU8 | X86Inst::kOpI16 | X86Inst::kOpU16 | k32AndMore;
+     403           0 :           else if (immValue <= 0x7FFFU)
+     404             :             immFlags = X86Inst::kOpI16 | X86Inst::kOpU16 | k32AndMore;
+     405           0 :           else if (immValue <= 0xFFFFU)
+     406             :             immFlags = X86Inst::kOpU16 | k32AndMore;
+     407           0 :           else if (immValue <= 0x7FFFFFFFU)
+     408             :             immFlags = k32AndMore;
+     409           0 :           else if (immValue <= 0xFFFFFFFFU)
+     410             :             immFlags = X86Inst::kOpU32 | X86Inst::kOpI64 | X86Inst::kOpU64;
+     411             :           else if (immValue <= ASMJIT_UINT64_C(0x7FFFFFFFFFFFFFFF))
+     412             :             immFlags = X86Inst::kOpI64 | X86Inst::kOpU64;
+     413             :           else
+     414             :             immFlags = X86Inst::kOpU64;
+     415             :         }
+     416             :         else {
+     417             :           // 2s complement negation, as our number is unsigned...
+     418           0 :           immValue = (~immValue + 1);
+     419             : 
+     420           0 :           if (immValue <= 0x80U)
+     421             :             immFlags = X86Inst::kOpI8 | X86Inst::kOpI16 | X86Inst::kOpI32 | X86Inst::kOpI64;
+     422           0 :           else if (immValue <= 0x8000U)
+     423             :             immFlags = X86Inst::kOpI16 | X86Inst::kOpI32 | X86Inst::kOpI64;
+     424           0 :           else if (immValue <= 0x80000000U)
+     425             :             immFlags = X86Inst::kOpI32 | X86Inst::kOpI64;
+     426             :           else
+     427             :             immFlags = X86Inst::kOpI64;
+     428             :         }
+     429             :         opFlags |= immFlags;
+     430             :         break;
+     431             :       }
+     432             : 
+     433             :       case Operand::kOpLabel: {
+     434             :         opFlags |= X86Inst::kOpRel8 | X86Inst::kOpRel32;
+     435             :         break;
+     436             :       }
+     437             : 
+     438             :       default:
+     439             :         return DebugUtils::errored(kErrorInvalidState);
+     440             :     }
+     441             : 
+     442             :     X86Inst::OSignature& tod = oSigTranslated[i];
+     443           0 :     tod.flags = opFlags;
+     444           0 :     tod.memFlags = static_cast<uint16_t>(memFlags);
+     445           0 :     tod.regMask = static_cast<uint8_t>(regMask & 0xFFU);
+     446           0 :     combinedOpFlags |= opFlags;
+     447             :   }
+     448             : 
+     449             :   // Decrease the number of operands of those that are none. This is important
+     450             :   // as Assembler and CodeCompiler may just pass more operands where some of
+     451             :   // them are none (it means that no operand is given at that index). However,
+     452             :   // validate that there are no gaps (like [reg, none, reg] or [none, reg]).
+     453           0 :   if (i < count) {
+     454           0 :     while (--count > i)
+     455           0 :       if (ASMJIT_UNLIKELY(!operands[count].isNone()))
+     456             :         return DebugUtils::errored(kErrorInvalidState);
+     457             :   }
+     458             : 
+     459             :   // Validate X86 and X64 specific cases.
+     460           0 :   if (archMask == X86Inst::kArchMaskX86) {
+     461             :     // Illegal use of 64-bit register in 32-bit mode.
+     462           0 :     if (ASMJIT_UNLIKELY((combinedOpFlags & X86Inst::kOpGpq) != 0))
+     463             :       return DebugUtils::errored(kErrorInvalidUseOfGpq);
+     464             :   }
+     465             :   else {
+     466             :     // Illegal use of a high 8-bit register with REX prefix.
+     467           0 :     if (ASMJIT_UNLIKELY((combinedOpFlags & X86Inst::kOpGpbHi) != 0 && (combinedRegMask & 0xFFFFFF00U) != 0))
+     468             :       return DebugUtils::errored(kErrorInvalidUseOfGpbHi);
+     469             :   }
+     470             : 
+     471             :   // Validate instruction operands.
+     472             :   const X86Inst::CommonData* commonData = &iData->getCommonData();
+     473           0 :   const X86Inst::ISignature* iSig = X86InstDB::iSignatureData + commonData->_iSignatureIndex;
+     474           0 :   const X86Inst::ISignature* iEnd = iSig                      + commonData->_iSignatureCount;
+     475             : 
+     476           0 :   if (iSig != iEnd) {
+     477             :     const X86Inst::OSignature* oSigData = X86InstDB::oSignatureData;
+     478             : 
+     479             :     // If set it means that we matched a signature where only immediate value
+     480             :     // was out of bounds. We can return a more descriptive error if we know this.
+     481             :     bool globalImmOutOfRange = false;
+     482             : 
+     483             :     do {
+     484             :       // Check if the architecture is compatible.
+     485           0 :       if ((iSig->archMask & archMask) == 0) continue;
+     486             : 
+     487             :       // Compare the operands table with reference operands.
+     488             :       uint32_t j = 0;
+     489           0 :       uint32_t iSigCount = iSig->opCount;
+     490             :       bool localImmOutOfRange = false;
+     491             : 
+     492           0 :       if (iSigCount == count) {
+     493           0 :         for (j = 0; j < count; j++)
+     494           0 :           if (!x86CheckOSig(oSigTranslated[j], oSigData[iSig->operands[j]], localImmOutOfRange))
+     495             :             break;
+     496             :       }
+     497           0 :       else if (iSigCount - iSig->implicit == count) {
+     498             :         uint32_t r = 0;
+     499           0 :         for (j = 0; j < count && r < iSigCount; j++, r++) {
+     500           0 :           const X86Inst::OSignature* oChk = oSigTranslated + j;
+     501             :           const X86Inst::OSignature* oRef;
+     502           0 : Next:
+     503           0 :           oRef = oSigData + iSig->operands[r];
+     504             :           // Skip implicit.
+     505           0 :           if ((oRef->flags & X86Inst::kOpImplicit) != 0) {
+     506           0 :             if (++r >= iSigCount)
+     507             :               break;
+     508             :             else
+     509           0 :               goto Next;
+     510             :           }
+     511             : 
+     512           0 :           if (!x86CheckOSig(*oChk, *oRef, localImmOutOfRange))
+     513             :             break;
+     514             :         }
+     515             :       }
+     516             : 
+     517           0 :       if (j == count) {
+     518           0 :         if (!localImmOutOfRange) {
+     519             :           // Match, must clear possible `globalImmOutOfRange`.
+     520             :           globalImmOutOfRange = false;
+     521             :           break;
+     522             :         }
+     523             :         globalImmOutOfRange = localImmOutOfRange;
+     524             :       }
+     525           0 :     } while (++iSig != iEnd);
+     526             : 
+     527           0 :     if (iSig == iEnd) {
+     528           0 :       if (globalImmOutOfRange)
+     529             :         return DebugUtils::errored(kErrorInvalidImmediate);
+     530             :       else
+     531           0 :         return DebugUtils::errored(kErrorInvalidInstruction);
+     532             :     }
+     533             :   }
+     534             : 
+     535             :   // Validate AVX-512 options:
+     536             :   const RegOnly& extraReg = detail.extraReg;
+     537             :   const uint32_t kAvx512Options = X86Inst::kOptionZMask   |
+     538             :                                   X86Inst::kOption1ToX    |
+     539             :                                   X86Inst::kOptionER      |
+     540             :                                   X86Inst::kOptionSAE     ;
+     541             : 
+     542           0 :   if (!extraReg.isNone() || (options & kAvx512Options)) {
+     543           0 :     if (commonData->hasFlag(X86Inst::kFlagEvex)) {
+     544             :       // Validate AVX-512 {k} and {k}{z}.
+     545           0 :       if (!extraReg.isNone()) {
+     546             :         // Mask can only be specified by a 'k' register.
+     547           0 :         if (ASMJIT_UNLIKELY(extraReg.getType() != X86Reg::kRegK))
+     548             :           return DebugUtils::errored(kErrorInvalidKMaskReg);
+     549             : 
+     550           0 :         if (ASMJIT_UNLIKELY(!commonData->hasAvx512K()))
+     551             :           return DebugUtils::errored(kErrorInvalidKMaskUse);
+     552             :       }
+     553             : 
+     554           0 :       if ((options & X86Inst::kOptionZMask)) {
+     555           0 :         if (ASMJIT_UNLIKELY((options & X86Inst::kOptionZMask) != 0 && !commonData->hasAvx512Z()))
+     556             :           return DebugUtils::errored(kErrorInvalidKZeroUse);
+     557             :       }
+     558             : 
+     559             :       // Validate AVX-512 broadcast {1tox}.
+     560           0 :       if (options & X86Inst::kOption1ToX) {
+     561           0 :         if (ASMJIT_UNLIKELY(!memOp))
+     562             :           return DebugUtils::errored(kErrorInvalidBroadcast);
+     563             : 
+     564             :         uint32_t size = memOp->getSize();
+     565           0 :         if (size != 0) {
+     566             :           // The the size is specified it has to match the broadcast size.
+     567           0 :           if (ASMJIT_UNLIKELY(commonData->hasAvx512B32() && size != 4))
+     568             :             return DebugUtils::errored(kErrorInvalidBroadcast);
+     569             : 
+     570           0 :           if (ASMJIT_UNLIKELY(commonData->hasAvx512B64() && size != 8))
+     571             :             return DebugUtils::errored(kErrorInvalidBroadcast);
+     572             :         }
+     573             :       }
+     574             : 
+     575             :       // Validate AVX-512 {sae} and {er}.
+     576           0 :       if (options & (X86Inst::kOptionSAE | X86Inst::kOptionER)) {
+     577             :         // Rounding control is impossible if the instruction is not reg-to-reg.
+     578           0 :         if (ASMJIT_UNLIKELY(memOp))
+     579             :           return DebugUtils::errored(kErrorInvalidEROrSAE);
+     580             : 
+     581             :         // Check if {sae} or {er} is supported by the instruction.
+     582           0 :         if (options & X86Inst::kOptionER) {
+     583             :           // NOTE: if both {sae} and {er} are set, we don't care, as {sae} is implied.
+     584           0 :           if (ASMJIT_UNLIKELY(!commonData->hasAvx512ER()))
+     585             :             return DebugUtils::errored(kErrorInvalidEROrSAE);
+     586             : 
+     587             :           // {er} is defined for scalar ops or vector ops using zmm (LL = 10). We
+     588             :           // don't need any more bits in the instruction database to be able to
+     589             :           // validate this, as each AVX512 instruction that has broadcast is vector
+     590             :           // instruction (in this case we require zmm registers), otherwise it's a
+     591             :           // scalar instruction, which is valid.
+     592           0 :           if (commonData->hasAvx512B()) {
+     593             :             // Supports broadcast, thus we require LL to be '10', which means there
+     594             :             // have to be zmm registers used. We don't calculate LL here, but we know
+     595             :             // that it would be '10' if there is at least one ZMM register used.
+     596             : 
+     597             :             // There is no 'ER' enabled instruction with less than two operands.
+     598             :             ASMJIT_ASSERT(count >= 2);
+     599           0 :             if (ASMJIT_UNLIKELY(!X86Reg::isZmm(operands[0]) && !X86Reg::isZmm(operands[1])))
+     600             :               return DebugUtils::errored(kErrorInvalidEROrSAE);
+     601             :           }
+     602             :         }
+     603             :         else {
+     604             :           // {sae} doesn't have the same limitations as {er}, this is enough.
+     605           0 :           if (ASMJIT_UNLIKELY(!commonData->hasAvx512SAE()))
+     606             :             return DebugUtils::errored(kErrorInvalidEROrSAE);
+     607             :         }
+     608             :       }
+     609             :     }
+     610             :     else {
+     611             :       // Not AVX512 instruction - maybe OpExtra is xCX register used by REP/REPNZ prefix. Otherwise the instruction is invalid.
+     612           0 :       if ((options & kAvx512Options) || (options & (X86Inst::kOptionRep | X86Inst::kOptionRepnz)) == 0)
+     613             :         return DebugUtils::errored(kErrorInvalidInstruction);
+     614             :     }
+     615             :   }
+     616             : 
+     617             :   return kErrorOk;
+     618             : }
+     619             : #endif
+     620             : 
+     621             : // ============================================================================
+     622             : // [asmjit::X86InstImpl - CheckFeatures]
+     623             : // ============================================================================
+     624             : 
+     625             : #if !defined(ASMJIT_DISABLE_EXTENSIONS)
+     626           0 : ASMJIT_FAVOR_SIZE static uint32_t x86GetRegTypesMask(const Operand_* operands, uint32_t count) noexcept {
+     627             :   uint32_t mask = 0;
+     628           0 :   for (uint32_t i = 0; i < count; i++) {
+     629           0 :     const Operand_& op = operands[i];
+     630           0 :     if (op.isReg()) {
+     631             :       const Reg& reg = op.as<Reg>();
+     632           0 :       mask |= Utils::mask(reg.getType());
+     633             :     }
+     634           0 :     else if (op.isMem()) {
+     635             :       const Mem& mem = op.as<Mem>();
+     636           0 :       if (mem.hasBaseReg()) mask |= Utils::mask(mem.getBaseType());
+     637           0 :       if (mem.hasIndexReg()) mask |= Utils::mask(mem.getIndexType());
+     638             :     }
+     639             :   }
+     640           0 :   return mask;
+     641             : }
+     642             : 
+     643           0 : ASMJIT_FAVOR_SIZE Error X86InstImpl::checkFeatures(uint32_t archType, const Inst::Detail& detail, const Operand_* operands, uint32_t count, CpuFeatures& out) noexcept {
+     644           0 :   if (!ArchInfo::isX86Family(archType))
+     645             :     return DebugUtils::errored(kErrorInvalidArch);
+     646             : 
+     647             :   // Get the instruction data.
+     648           0 :   uint32_t instId = detail.instId;
+     649           0 :   if (ASMJIT_UNLIKELY(instId >= X86Inst::_kIdCount))
+     650             :     return DebugUtils::errored(kErrorInvalidArgument);
+     651             : 
+     652             :   const X86Inst* iData = &X86InstDB::instData[instId];
+     653             :   const X86Inst::OperationData& od = iData->getOperationData();
+     654             : 
+     655             :   const uint8_t* fData = od.getFeaturesData();
+     656             :   const uint8_t* fEnd = od.getFeaturesEnd();
+     657             : 
+     658             :   // Copy all features to `out`.
+     659             :   out.reset();
+     660             :   do {
+     661           0 :     uint32_t feature = fData[0];
+     662           0 :     if (!feature)
+     663             :       break;
+     664             :     out.add(feature);
+     665           0 :   } while (++fData != fEnd);
+     666             : 
+     667             :   // Since AsmJit merges all instructions that share the same name we have to
+     668             :   // deal with some special cases and also with MMX/SSE and AVX/AVX2 overlaps.
+     669             : 
+     670             :   // Only proceed if there were some CPU flags set.
+     671           0 :   if (fData != od.getFeaturesData()) {
+     672           0 :     uint32_t mask = x86GetRegTypesMask(operands, count);
+     673             : 
+     674             :     // Check for MMX vs SSE overlap.
+     675           0 :     if (out.has(CpuInfo::kX86FeatureMMX) || out.has(CpuInfo::kX86FeatureMMX2)) {
+     676             :       // Only instructions defined by SSE and SSE2 overlap. Instructions introduced
+     677             :       // by newer instruction sets like SSE3+ don't state MMX as they require SSE3+.
+     678           0 :       if (out.has(CpuInfo::kX86FeatureSSE) || out.has(CpuInfo::kX86FeatureSSE2)) {
+     679           0 :         if (!(mask & Utils::mask(X86Reg::kRegXmm))) {
+     680             :           // The instruction doesn't use XMM register(s), thus it's MMX/MMX2 only.
+     681             :           out.remove(CpuInfo::kX86FeatureSSE);
+     682             :           out.remove(CpuInfo::kX86FeatureSSE2);
+     683             :         }
+     684             :         else {
+     685             :           out.remove(CpuInfo::kX86FeatureMMX);
+     686             :           out.remove(CpuInfo::kX86FeatureMMX2);
+     687             :         }
+     688             : 
+     689             :         // Special case: PEXTRW instruction is MMX/SSE2 instruction. However, this
+     690             :         // instruction couldn't access memory (only register to register extract) so
+     691             :         // when SSE4.1 introduced the whole family of PEXTR/PINSR instructions they
+     692             :         // also introduced PEXTRW with a new opcode 0x15 that can extract directly to
+     693             :         // memory. This instruction is, of course, not compatible with MMX/SSE2 one.
+     694           0 :         if (instId == X86Inst::kIdPextrw && count > 0 && !operands[0].isMem()) {
+     695             :           out.remove(CpuInfo::kX86FeatureSSE4_1);
+     696             :         }
+     697             :       }
+     698             :     }
+     699             : 
+     700             :     // Check for AVX vs AVX2 overlap.
+     701           0 :     if (out.has(CpuInfo::kX86FeatureAVX) && out.has(CpuInfo::kX86FeatureAVX2)) {
+     702             :       bool isAVX2 = true;
+     703             :       // Special case: VBROADCASTSS and VBROADCASTSD were introduced in AVX, but
+     704             :       // only version that uses memory as a source operand. AVX2 then added support
+     705             :       // for register source operand.
+     706           0 :       if (instId == X86Inst::kIdVbroadcastss || instId == X86Inst::kIdVbroadcastsd) {
+     707           0 :         if (count > 1 && operands[0].isMem())
+     708             :           isAVX2 = false;
+     709             :       }
+     710             :       else {
+     711             :         // AVX instruction set doesn't support integer operations on YMM registers
+     712             :         // as these were later introcuced by AVX2. In our case we have to check if
+     713             :         // YMM register(s) are in use and if that is the case this is an AVX2 instruction.
+     714           0 :         if (!(mask & Utils::mask(X86Reg::kRegYmm, X86Reg::kRegZmm)))
+     715             :           isAVX2 = false;
+     716             :       }
+     717             : 
+     718             :       if (isAVX2)
+     719             :         out.remove(CpuInfo::kX86FeatureAVX);
+     720             :       else
+     721             :         out.remove(CpuInfo::kX86FeatureAVX2);
+     722             :     }
+     723             : 
+     724             :     // Check for AVX|AVX2|FMA|F16C vs AVX512 overlap.
+     725           0 :     if (out.has(CpuInfo::kX86FeatureAVX) || out.has(CpuInfo::kX86FeatureAVX2) || out.has(CpuInfo::kX86FeatureFMA) || out.has(CpuInfo::kX86FeatureF16C)) {
+     726             :       // Only AVX512-F|BW|DQ allow to encode AVX/AVX2 instructions
+     727           0 :       if (out.has(CpuInfo::kX86FeatureAVX512_F) || out.has(CpuInfo::kX86FeatureAVX512_BW) || out.has(CpuInfo::kX86FeatureAVX512_DQ)) {
+     728           0 :         uint32_t options = detail.options;
+     729             :         uint32_t kAvx512Options = X86Inst::kOptionEvex | X86Inst::_kOptionAvx512Mask;
+     730             : 
+     731           0 :         if (!(mask & Utils::mask(X86Reg::kRegZmm, X86Reg::kRegK)) && !(options & (kAvx512Options)) && detail.extraReg.getType() != X86Reg::kRegK) {
+     732             :           out.remove(CpuInfo::kX86FeatureAVX512_F)
+     733             :              .remove(CpuInfo::kX86FeatureAVX512_BW)
+     734             :              .remove(CpuInfo::kX86FeatureAVX512_DQ)
+     735             :              .remove(CpuInfo::kX86FeatureAVX512_VL);
+     736             :         }
+     737             :       }
+     738             :     }
+     739             : 
+     740             :     // Remove or keep AVX512_VL feature.
+     741           0 :     if (out.has(CpuInfo::kX86FeatureAVX512_VL)) {
+     742           0 :       if (!(mask & Utils::mask(X86Reg::kRegZmm)))
+     743             :         out.remove(CpuInfo::kX86FeatureAVX512_VL);
+     744             :     }
+     745             :   }
+     746             : 
+     747             :   return kErrorOk;
+     748             : }
+     749             : #endif
+     750             : 
+     751             : } // asmjit namespace
+     752             : } // namespace PLMD
+     753             : 
+     754             : // [Api-End]
+     755             : #include "./asmjit_apiend.h"
+     756             : #pragma GCC diagnostic pop
+     757             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86internal.cpp.func-sort-c.html b/coverage-libs/asmjit/x86internal.cpp.func-sort-c.html new file mode 100644 index 000000000000..63c64e71c684 --- /dev/null +++ b/coverage-libs/asmjit/x86internal.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86internal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86internal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11339428.7 %
Date:2024-02-22 21:58:47Functions:61442.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Internal11emitArgMoveEPNS0_10X86EmitterERKNS0_6X86RegEjRKNS0_8Operand_EjbPKc0
_ZN4PLMD6asmjit11X86Internal15argsToFrameInfoERKNS0_14FuncArgsMapperERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit11X86Internal9allocArgsEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZN4PLMD6asmjit18X86FuncArgsContext12initWorkDataERKNS0_14FuncArgsMapperEPKjb0
_ZN4PLMD6asmjit18X86FuncArgsContext16markDstRegsDirtyERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markRegsForSwapsERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markStackArgsRegERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContextC2Ev0
_ZN4PLMD6asmjit11X86Internal10emitEpilogEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit11X86Internal10emitPrologEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit11X86Internal15initFrameLayoutERNS0_15FuncFrameLayoutERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1948
_ZN4PLMD6asmjit11X86Internal12initCallConvERNS0_8CallConvEj3596
_ZN4PLMD6asmjit11X86Internal14initFuncDetailERNS0_10FuncDetailERKNS0_13FuncSignatureEj3596
_ZN4PLMD6asmjit11X86Internal11emitRegMoveEPNS0_10X86EmitterERKNS0_8Operand_ES6_jbPKc9084
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86internal.cpp.func.html b/coverage-libs/asmjit/x86internal.cpp.func.html new file mode 100644 index 000000000000..1deb9a730e0f --- /dev/null +++ b/coverage-libs/asmjit/x86internal.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86internal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86internal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11339428.7 %
Date:2024-02-22 21:58:47Functions:61442.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86Internal10emitEpilogEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit11X86Internal10emitPrologEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjit11X86Internal11emitArgMoveEPNS0_10X86EmitterERKNS0_6X86RegEjRKNS0_8Operand_EjbPKc0
_ZN4PLMD6asmjit11X86Internal11emitRegMoveEPNS0_10X86EmitterERKNS0_8Operand_ES6_jbPKc9084
_ZN4PLMD6asmjit11X86Internal12initCallConvERNS0_8CallConvEj3596
_ZN4PLMD6asmjit11X86Internal14initFuncDetailERNS0_10FuncDetailERKNS0_13FuncSignatureEj3596
_ZN4PLMD6asmjit11X86Internal15argsToFrameInfoERKNS0_14FuncArgsMapperERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit11X86Internal15initFrameLayoutERNS0_15FuncFrameLayoutERKNS0_10FuncDetailERKNS0_13FuncFrameInfoE1948
_ZN4PLMD6asmjit11X86Internal9allocArgsEPNS0_10X86EmitterERKNS0_15FuncFrameLayoutERKNS0_14FuncArgsMapperE0
_ZN4PLMD6asmjit18X86FuncArgsContext12initWorkDataERKNS0_14FuncArgsMapperEPKjb0
_ZN4PLMD6asmjit18X86FuncArgsContext16markDstRegsDirtyERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markRegsForSwapsERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContext16markStackArgsRegERNS0_13FuncFrameInfoE0
_ZN4PLMD6asmjit18X86FuncArgsContextC2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86internal.cpp.gcov.html b/coverage-libs/asmjit/x86internal.cpp.gcov.html new file mode 100644 index 000000000000..e851b8bccf2a --- /dev/null +++ b/coverage-libs/asmjit/x86internal.cpp.gcov.html @@ -0,0 +1,1459 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86internal.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86internal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11339428.7 %
Date:2024-02-22 21:58:47Functions:61442.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Guard]
+      33             : #include "./asmjit_build.h"
+      34             : #if defined(ASMJIT_BUILD_X86)
+      35             : 
+      36             : // [Dependencies]
+      37             : #include "./x86internal_p.h"
+      38             : 
+      39             : // [Api-Begin]
+      40             : #include "./asmjit_apibegin.h"
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace asmjit {
+      44             : 
+      45             : // ============================================================================
+      46             : // [asmjit::X86Internal - Helpers]
+      47             : // ============================================================================
+      48             : 
+      49             : static ASMJIT_INLINE uint32_t x86GetXmmMovInst(const FuncFrameLayout& layout) {
+      50             :   bool avx = layout.isAvxEnabled();
+      51             :   bool aligned = layout.hasAlignedVecSR();
+      52             : 
+      53           0 :   return aligned ? (avx ? X86Inst::kIdVmovaps : X86Inst::kIdMovaps)
+      54             :                  : (avx ? X86Inst::kIdVmovups : X86Inst::kIdMovups);
+      55             : }
+      56             : 
+      57             : static ASMJIT_INLINE uint32_t x86VecTypeIdToRegType(uint32_t typeId) noexcept {
+      58        1450 :   return typeId <= TypeId::_kVec128End ? X86Reg::kRegXmm :
+      59             :          typeId <= TypeId::_kVec256End ? X86Reg::kRegYmm :
+      60             :                                          X86Reg::kRegZmm ;
+      61             : }
+      62             : 
+      63             : // ============================================================================
+      64             : // [asmjit::X86FuncArgsContext]
+      65             : // ============================================================================
+      66             : 
+      67             : // Used by both, `Utils::argsToFrameInfo()` and `Utils::allocArgs()`.
+      68             : class X86FuncArgsContext {
+      69             : public:
+      70             :   typedef FuncDetail::Value SrcArg;
+      71             :   typedef FuncArgsMapper::Value DstArg;
+      72             : 
+      73             :   enum { kMaxVRegKinds = Globals::kMaxVRegKinds };
+      74             : 
+      75             :   struct WorkData {
+      76             :     uint32_t archRegs;                   //!< Architecture provided and allocable regs.
+      77             :     uint32_t workRegs;                   //!< Registers that can be used by shuffler.
+      78             :     uint32_t usedRegs;                   //!< Only registers used to pass arguments.
+      79             :     uint32_t srcRegs;                    //!< Source registers that need shuffling.
+      80             :     uint32_t dstRegs;                    //!< Destination registers that need shuffling.
+      81             :     uint8_t numOps;                      //!< Number of operations to finish.
+      82             :     uint8_t numSwaps;                    //!< Number of register swaps.
+      83             :     uint8_t numStackArgs;                //!< Number of stack loads.
+      84             :     uint8_t reserved[9];                 //!< Reserved (only used as padding).
+      85             :     uint8_t argIndex[32];                //!< Only valid if a corresponding bit in `userRegs` is true.
+      86             :   };
+      87             : 
+      88             :   X86FuncArgsContext() noexcept;
+      89             :   Error initWorkData(const FuncArgsMapper& args, const uint32_t* dirtyRegs, bool preservedFP) noexcept;
+      90             : 
+      91             :   Error markRegsForSwaps(FuncFrameInfo& ffi) noexcept;
+      92             :   Error markDstRegsDirty(FuncFrameInfo& ffi) noexcept;
+      93             :   Error markStackArgsReg(FuncFrameInfo& ffi) noexcept;
+      94             : 
+      95             :   // --------------------------------------------------------------------------
+      96             :   // [Members]
+      97             :   // --------------------------------------------------------------------------
+      98             : 
+      99             :   WorkData _workData[kMaxVRegKinds];
+     100             :   bool _hasStackArgs;
+     101             :   bool _hasRegSwaps;
+     102             : };
+     103             : 
+     104           0 : X86FuncArgsContext::X86FuncArgsContext() noexcept {
+     105           0 :   ::memset(_workData, 0, sizeof(_workData));
+     106           0 :   _hasStackArgs = false;
+     107           0 :   _hasRegSwaps = false;
+     108           0 : }
+     109             : 
+     110           0 : ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::initWorkData(const FuncArgsMapper& args, const uint32_t* dirtyRegs, bool preservedFP) noexcept {
+     111             :   // This code has to be updated if this changes.
+     112             :   ASMJIT_ASSERT(kMaxVRegKinds == 4);
+     113             : 
+     114             :   uint32_t i;
+     115             :   const FuncDetail& func = *args.getFuncDetail();
+     116             : 
+     117             :   uint32_t archType = func.getCallConv().getArchType();
+     118           0 :   uint32_t count = (archType == ArchInfo::kTypeX86) ? 8 : 16;
+     119             : 
+     120             :   // Initialize WorkData::archRegs.
+     121           0 :   _workData[X86Reg::kKindGp ].archRegs = Utils::bits(count) & ~Utils::mask(X86Gp::kIdSp);
+     122           0 :   _workData[X86Reg::kKindMm ].archRegs = Utils::bits(8);
+     123           0 :   _workData[X86Reg::kKindK  ].archRegs = Utils::bits(8);
+     124           0 :   _workData[X86Reg::kKindVec].archRegs = Utils::bits(count);
+     125             : 
+     126           0 :   if (preservedFP)
+     127           0 :     _workData[X86Reg::kKindGp].archRegs &= ~Utils::mask(X86Gp::kIdBp);
+     128             : 
+     129             :   // Initialize WorkData::workRegs.
+     130           0 :   for (i = 0; i < kMaxVRegKinds; i++)
+     131           0 :     _workData[i].workRegs = _workData[i].archRegs & (dirtyRegs[i] | ~func.getCallConv().getPreservedRegs(i));
+     132             : 
+     133             :   // Build WorkData.
+     134           0 :   for (i = 0; i < kFuncArgCountLoHi; i++) {
+     135           0 :     const DstArg& dstArg = args.getArg(i);
+     136           0 :     if (!dstArg.isAssigned()) continue;
+     137             : 
+     138             :     const SrcArg& srcArg = func.getArg(i);
+     139           0 :     if (ASMJIT_UNLIKELY(!srcArg.isAssigned()))
+     140             :       return DebugUtils::errored(kErrorInvalidState);
+     141             : 
+     142             :     uint32_t dstRegType = dstArg.getRegType();
+     143           0 :     if (ASMJIT_UNLIKELY(dstRegType >= X86Reg::kRegCount))
+     144             :       return DebugUtils::errored(kErrorInvalidRegType);
+     145             : 
+     146             :     uint32_t dstRegKind = X86Reg::kindOf(dstRegType);
+     147           0 :     if (ASMJIT_UNLIKELY(dstRegKind >= kMaxVRegKinds))
+     148             :       return DebugUtils::errored(kErrorInvalidState);
+     149             : 
+     150             :     WorkData& dstData = _workData[dstRegKind];
+     151             :     uint32_t dstRegId = dstArg.getRegId();
+     152           0 :     if (ASMJIT_UNLIKELY(dstRegId >= 32 || !(dstData.archRegs & Utils::mask(dstRegId))))
+     153             :       return DebugUtils::errored(kErrorInvalidPhysId);
+     154             : 
+     155             :     uint32_t dstRegMask = Utils::mask(dstRegId);
+     156           0 :     if (ASMJIT_UNLIKELY(dstData.usedRegs & dstRegMask))
+     157             :       return DebugUtils::errored(kErrorOverlappedRegs);
+     158             : 
+     159           0 :     dstData.usedRegs |= dstRegMask;
+     160           0 :     dstData.argIndex[dstRegId] = static_cast<uint8_t>(i);
+     161             : 
+     162           0 :     if (srcArg.byReg()) {
+     163             :       uint32_t srcRegKind = X86Reg::kindOf(srcArg.getRegType());
+     164             :       uint32_t srcRegId = srcArg.getRegId();
+     165             :       uint32_t srcRegMask = Utils::mask(srcRegId);
+     166             : 
+     167           0 :       if (dstRegKind == srcRegKind) {
+     168             :         // The best case, register is allocated where it is expected to be.
+     169           0 :         if (dstRegId == srcRegId) continue;
+     170             : 
+     171             :         // Detect a register swap.
+     172           0 :         if (dstData.usedRegs & srcRegMask) {
+     173           0 :           const SrcArg& ref = func.getArg(dstData.argIndex[srcRegId]);
+     174           0 :           if (ref.byReg() && X86Reg::kindOf(ref.getRegType()) == dstRegKind && ref.getRegId() == dstRegId) {
+     175           0 :             dstData.numSwaps++;
+     176           0 :             _hasRegSwaps = true;
+     177             :           }
+     178             :         }
+     179           0 :         dstData.srcRegs |= srcRegMask;
+     180             :       }
+     181             :       else {
+     182           0 :         if (ASMJIT_UNLIKELY(srcRegKind >= kMaxVRegKinds))
+     183             :           return DebugUtils::errored(kErrorInvalidState);
+     184             : 
+     185             :         WorkData& srcData = _workData[srcRegKind];
+     186           0 :         srcData.srcRegs |= srcRegMask;
+     187             :       }
+     188             :     }
+     189             :     else {
+     190           0 :       dstData.numStackArgs++;
+     191           0 :       _hasStackArgs = true;
+     192             :     }
+     193             : 
+     194           0 :     dstData.numOps++;
+     195           0 :     dstData.dstRegs |= dstRegMask;
+     196             :   }
+     197             : 
+     198             :   return kErrorOk;
+     199             : }
+     200             : 
+     201           0 : ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::markDstRegsDirty(FuncFrameInfo& ffi) noexcept {
+     202           0 :   for (uint32_t i = 0; i < kMaxVRegKinds; i++) {
+     203             :     WorkData& wd = _workData[i];
+     204           0 :     uint32_t regs = wd.usedRegs | wd.dstRegs;
+     205             : 
+     206           0 :     wd.workRegs |= regs;
+     207             :     ffi.addDirtyRegs(i, regs);
+     208             :   }
+     209             : 
+     210           0 :   return kErrorOk;
+     211             : }
+     212             : 
+     213           0 : ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::markRegsForSwaps(FuncFrameInfo& ffi) noexcept {
+     214           0 :   if (!_hasRegSwaps)
+     215             :     return kErrorOk;
+     216             : 
+     217             :   // If some registers require swapping then select one dirty register that
+     218             :   // can be used as a temporary. We can do it also without it (by using xors),
+     219             :   // but using temporary is always safer and also faster approach.
+     220           0 :   for (uint32_t i = 0; i < kMaxVRegKinds; i++) {
+     221             :     // Skip all register kinds where swapping is natively supported (GP regs).
+     222           0 :     if (i == X86Reg::kKindGp) continue;
+     223             : 
+     224             :     // Skip all register kinds that don't require swapping.
+     225             :     WorkData& wd = _workData[i];
+     226           0 :     if (!wd.numSwaps) continue;
+     227             : 
+     228             :     // Initially, pick some clobbered or dirty register.
+     229           0 :     uint32_t workRegs = wd.workRegs;
+     230           0 :     uint32_t regs = workRegs & ~(wd.usedRegs | wd.dstRegs);
+     231             : 
+     232             :     // If that didn't work out pick some register which is not in 'used'.
+     233           0 :     if (!regs) regs = workRegs & ~wd.usedRegs;
+     234             : 
+     235             :     // If that didn't work out pick any other register that is allocable.
+     236             :     // This last resort case will, however, result in marking one more
+     237             :     // register dirty.
+     238           0 :     if (!regs) regs = wd.archRegs & ~workRegs;
+     239             : 
+     240             :     // If that didn't work out we will have to use xors instead of moves.
+     241           0 :     if (!regs) continue;
+     242             : 
+     243             :     uint32_t regMask = Utils::mask(Utils::findFirstBit(regs));
+     244           0 :     wd.workRegs |= regMask;
+     245             :     ffi.addDirtyRegs(i, regMask);
+     246             :   }
+     247             : 
+     248             :   return kErrorOk;
+     249             : }
+     250             : 
+     251           0 : ASMJIT_FAVOR_SIZE Error X86FuncArgsContext::markStackArgsReg(FuncFrameInfo& ffi) noexcept {
+     252           0 :   if (!_hasStackArgs)
+     253             :     return kErrorOk;
+     254             : 
+     255             :   // Decide which register to use to hold the stack base address.
+     256           0 :   if (!ffi.hasPreservedFP()) {
+     257             :     WorkData& wd = _workData[X86Reg::kKindGp];
+     258             :     uint32_t saRegId = ffi.getStackArgsRegId();
+     259           0 :     uint32_t usedRegs = wd.usedRegs;
+     260             : 
+     261           0 :     if (saRegId != Globals::kInvalidRegId) {
+     262             :       // Check if the user chosen SA register doesn't overlap with others.
+     263             :       // However, it's fine if it overlaps with some 'dstMove' register.
+     264           0 :       if (usedRegs & Utils::mask(saRegId))
+     265             :         return DebugUtils::errored(kErrorOverlappingStackRegWithRegArg);
+     266             :     }
+     267             :     else {
+     268             :       // Initially, pick some clobbered or dirty register that is neither
+     269             :       // in 'used' and neither in 'dstMove'. That's the safest bet as the
+     270             :       // register won't collide with anything right now.
+     271           0 :       uint32_t regs = wd.workRegs & ~(usedRegs | wd.dstRegs);
+     272             : 
+     273             :       // If that didn't work out pick some register which is not in 'used'.
+     274           0 :       if (!regs) regs = wd.workRegs & ~usedRegs;
+     275             : 
+     276             :       // If that didn't work out then we have to make one more register dirty.
+     277           0 :       if (!regs) regs = wd.archRegs & ~wd.workRegs;
+     278             : 
+     279             :       // If that didn't work out we can't continue.
+     280           0 :       if (ASMJIT_UNLIKELY(!regs))
+     281             :         return DebugUtils::errored(kErrorNoMorePhysRegs);
+     282             : 
+     283             :       saRegId = Utils::findFirstBit(regs);
+     284             :       ffi.setStackArgsRegId(saRegId);
+     285             :     }
+     286             :   }
+     287             :   else {
+     288             :     ffi.setStackArgsRegId(X86Gp::kIdBp);
+     289             :   }
+     290             : 
+     291             :   return kErrorOk;
+     292             : }
+     293             : 
+     294             : // ============================================================================
+     295             : // [asmjit::X86Internal - CallConv]
+     296             : // ============================================================================
+     297             : 
+     298        3596 : ASMJIT_FAVOR_SIZE Error X86Internal::initCallConv(CallConv& cc, uint32_t ccId) noexcept {
+     299             :   const uint32_t kKindGp  = X86Reg::kKindGp;
+     300             :   const uint32_t kKindVec = X86Reg::kKindVec;
+     301             :   const uint32_t kKindMm  = X86Reg::kKindMm;
+     302             :   const uint32_t kKindK   = X86Reg::kKindK;
+     303             : 
+     304             :   const uint32_t kZax = X86Gp::kIdAx;
+     305             :   const uint32_t kZbx = X86Gp::kIdBx;
+     306             :   const uint32_t kZcx = X86Gp::kIdCx;
+     307             :   const uint32_t kZdx = X86Gp::kIdDx;
+     308             :   const uint32_t kZsp = X86Gp::kIdSp;
+     309             :   const uint32_t kZbp = X86Gp::kIdBp;
+     310             :   const uint32_t kZsi = X86Gp::kIdSi;
+     311             :   const uint32_t kZdi = X86Gp::kIdDi;
+     312             : 
+     313        3596 :   switch (ccId) {
+     314             :     case CallConv::kIdX86StdCall:
+     315             :       cc.setFlags(CallConv::kFlagCalleePopsStack);
+     316           0 :       goto X86CallConv;
+     317             : 
+     318             :     case CallConv::kIdX86MsThisCall:
+     319             :       cc.setFlags(CallConv::kFlagCalleePopsStack);
+     320             :       cc.setPassedOrder(kKindGp, kZcx);
+     321           0 :       goto X86CallConv;
+     322             : 
+     323             :     case CallConv::kIdX86MsFastCall:
+     324             :     case CallConv::kIdX86GccFastCall:
+     325             :       cc.setFlags(CallConv::kFlagCalleePopsStack);
+     326             :       cc.setPassedOrder(kKindGp, kZcx, kZdx);
+     327           0 :       goto X86CallConv;
+     328             : 
+     329             :     case CallConv::kIdX86GccRegParm1:
+     330             :       cc.setPassedOrder(kKindGp, kZax);
+     331           0 :       goto X86CallConv;
+     332             : 
+     333             :     case CallConv::kIdX86GccRegParm2:
+     334             :       cc.setPassedOrder(kKindGp, kZax, kZdx);
+     335           0 :       goto X86CallConv;
+     336             : 
+     337             :     case CallConv::kIdX86GccRegParm3:
+     338             :       cc.setPassedOrder(kKindGp, kZax, kZdx, kZcx);
+     339           0 :       goto X86CallConv;
+     340             : 
+     341             :     case CallConv::kIdX86CDecl:
+     342           0 : X86CallConv:
+     343             :       cc.setNaturalStackAlignment(4);
+     344             :       cc.setArchType(ArchInfo::kTypeX86);
+     345             :       cc.setPreservedRegs(kKindGp, Utils::mask(kZbx, kZsp, kZbp, kZsi, kZdi));
+     346             :       break;
+     347             : 
+     348             :     case CallConv::kIdX86Win64:
+     349             :       cc.setArchType(ArchInfo::kTypeX64);
+     350             :       cc.setAlgorithm(CallConv::kAlgorithmWin64);
+     351             :       cc.setFlags(CallConv::kFlagPassFloatsByVec | CallConv::kFlagIndirectVecArgs);
+     352             :       cc.setNaturalStackAlignment(16);
+     353             :       cc.setSpillZoneSize(32);
+     354             :       cc.setPassedOrder(kKindGp, kZcx, kZdx, 8, 9);
+     355             :       cc.setPassedOrder(kKindVec, 0, 1, 2, 3);
+     356             :       cc.setPreservedRegs(kKindGp, Utils::mask(kZbx, kZsp, kZbp, kZsi, kZdi, 12, 13, 14, 15));
+     357             :       cc.setPreservedRegs(kKindVec, Utils::mask(6, 7, 8, 9, 10, 11, 12, 13, 14, 15));
+     358             :       break;
+     359             : 
+     360             :     case CallConv::kIdX86SysV64:
+     361             :       cc.setArchType(ArchInfo::kTypeX64);
+     362             :       cc.setFlags(CallConv::kFlagPassFloatsByVec);
+     363             :       cc.setNaturalStackAlignment(16);
+     364             :       cc.setRedZoneSize(128);
+     365             :       cc.setPassedOrder(kKindGp, kZdi, kZsi, kZdx, kZcx, 8, 9);
+     366             :       cc.setPassedOrder(kKindVec, 0, 1, 2, 3, 4, 5, 6, 7);
+     367             :       cc.setPreservedRegs(kKindGp, Utils::mask(kZbx, kZsp, kZbp, 12, 13, 14, 15));
+     368             :       break;
+     369             : 
+     370           0 :     case CallConv::kIdX86FastEval2:
+     371             :     case CallConv::kIdX86FastEval3:
+     372             :     case CallConv::kIdX86FastEval4: {
+     373           0 :       uint32_t n = ccId - CallConv::kIdX86FastEval2;
+     374             : 
+     375             :       cc.setArchType(ArchInfo::kTypeX86);
+     376             :       cc.setFlags(CallConv::kFlagPassFloatsByVec);
+     377             :       cc.setNaturalStackAlignment(16);
+     378             :       cc.setPassedOrder(kKindGp, kZax, kZdx, kZcx, kZsi, kZdi);
+     379             :       cc.setPassedOrder(kKindMm, 0, 1, 2, 3, 4, 5, 6, 7);
+     380             :       cc.setPassedOrder(kKindVec, 0, 1, 2, 3, 4, 5, 6, 7);
+     381             : 
+     382             :       cc.setPreservedRegs(kKindGp , Utils::bits(8));
+     383           0 :       cc.setPreservedRegs(kKindVec, Utils::bits(8) & ~Utils::bits(n));
+     384             :       cc.setPreservedRegs(kKindMm , Utils::bits(8));
+     385             :       cc.setPreservedRegs(kKindK  , Utils::bits(8));
+     386             :       break;
+     387             :     }
+     388             : 
+     389           0 :     case CallConv::kIdX64FastEval2:
+     390             :     case CallConv::kIdX64FastEval3:
+     391             :     case CallConv::kIdX64FastEval4: {
+     392           0 :       uint32_t n = ccId - CallConv::kIdX64FastEval2;
+     393             : 
+     394             :       cc.setArchType(ArchInfo::kTypeX64);
+     395             :       cc.setFlags(CallConv::kFlagPassFloatsByVec);
+     396             :       cc.setNaturalStackAlignment(16);
+     397             :       cc.setPassedOrder(kKindGp, kZax, kZdx, kZcx, kZsi, kZdi);
+     398             :       cc.setPassedOrder(kKindMm, 0, 1, 2, 3, 4, 5, 6, 7);
+     399             :       cc.setPassedOrder(kKindVec, 0, 1, 2, 3, 4, 5, 6, 7);
+     400             : 
+     401             :       cc.setPreservedRegs(kKindGp , Utils::bits(16));
+     402           0 :       cc.setPreservedRegs(kKindVec,~Utils::bits(n));
+     403             :       cc.setPreservedRegs(kKindMm , Utils::bits(8));
+     404             :       cc.setPreservedRegs(kKindK  , Utils::bits(8));
+     405             :       break;
+     406             :     }
+     407             : 
+     408             :     default:
+     409             :       return DebugUtils::errored(kErrorInvalidArgument);
+     410             :   }
+     411             : 
+     412             :   cc.setId(ccId);
+     413        3596 :   return kErrorOk;
+     414             : }
+     415             : 
+     416             : // ============================================================================
+     417             : // [asmjit::X86Internal - FuncDetail]
+     418             : // ============================================================================
+     419             : 
+     420        3596 : ASMJIT_FAVOR_SIZE Error X86Internal::initFuncDetail(FuncDetail& func, const FuncSignature& sign, uint32_t gpSize) noexcept {
+     421             :   const CallConv& cc = func.getCallConv();
+     422             :   uint32_t archType = cc.getArchType();
+     423             : 
+     424             :   uint32_t i;
+     425             :   uint32_t argCount = func.getArgCount();
+     426             : 
+     427        3596 :   if (func.getRetCount() != 0) {
+     428             :     uint32_t typeId = func._rets[0].getTypeId();
+     429        3596 :     switch (typeId) {
+     430           0 :       case TypeId::kI64:
+     431             :       case TypeId::kU64: {
+     432           0 :         if (archType == ArchInfo::kTypeX86) {
+     433             :           // Convert a 64-bit return to two 32-bit returns.
+     434           0 :           func._retCount = 2;
+     435           0 :           typeId -= 2;
+     436             : 
+     437             :           // 64-bit value is returned in EDX:EAX on X86.
+     438             :           func._rets[0].initReg(typeId, X86Gp::kRegGpd, X86Gp::kIdAx);
+     439             :           func._rets[1].initReg(typeId, X86Gp::kRegGpd, X86Gp::kIdDx);
+     440             :           break;
+     441             :         }
+     442             :         else {
+     443             :           func._rets[0].initReg(typeId, X86Gp::kRegGpq, X86Gp::kIdAx);
+     444             :         }
+     445             :         break;
+     446             :       }
+     447             : 
+     448           0 :       case TypeId::kI8:
+     449             :       case TypeId::kU8:
+     450             :       case TypeId::kI16:
+     451             :       case TypeId::kU16:
+     452             :       case TypeId::kI32:
+     453             :       case TypeId::kU32: {
+     454             :         func._rets[0].assignToReg(X86Gp::kRegGpd, X86Gp::kIdAx);
+     455             :         break;
+     456             :       }
+     457             : 
+     458        3596 :       case TypeId::kF32:
+     459             :       case TypeId::kF64: {
+     460        3596 :         uint32_t regType = (archType == ArchInfo::kTypeX86) ? X86Reg::kRegFp : X86Reg::kRegXmm;
+     461             :         func._rets[0].assignToReg(regType, 0);
+     462             :         break;
+     463             :       }
+     464             : 
+     465           0 :       case TypeId::kF80: {
+     466             :         // 80-bit floats are always returned by FP0.
+     467             :         func._rets[0].assignToReg(X86Reg::kRegFp, 0);
+     468             :         break;
+     469             :       }
+     470             : 
+     471           0 :       case TypeId::kMmx32:
+     472             :       case TypeId::kMmx64: {
+     473             :         // On X64 MM register(s) are returned through XMM or GPQ (Win64).
+     474             :         uint32_t regType = X86Reg::kRegMm;
+     475           0 :         if (archType != ArchInfo::kTypeX86)
+     476           0 :           regType = cc.getAlgorithm() == CallConv::kAlgorithmDefault ? X86Reg::kRegXmm : X86Reg::kRegGpq;
+     477             : 
+     478             :         func._rets[0].assignToReg(regType, 0);
+     479             :         break;
+     480             :       }
+     481             : 
+     482           0 :       default: {
+     483             :         func._rets[0].assignToReg(x86VecTypeIdToRegType(typeId), 0);
+     484             :         break;
+     485             :       }
+     486             :     }
+     487             :   }
+     488             : 
+     489        3596 :   uint32_t stackBase = gpSize;
+     490        3596 :   uint32_t stackOffset = stackBase + cc._spillZoneSize;
+     491             : 
+     492        3596 :   if (cc.getAlgorithm() == CallConv::kAlgorithmDefault) {
+     493             :     uint32_t gpzPos = 0;
+     494             :     uint32_t vecPos = 0;
+     495             : 
+     496        5466 :     for (i = 0; i < argCount; i++) {
+     497             :       FuncDetail::Value& arg = func._args[i];
+     498             :       uint32_t typeId = arg.getTypeId();
+     499             : 
+     500        1870 :       if (TypeId::isInt(typeId)) {
+     501         420 :         uint32_t regId = gpzPos < CallConv::kNumRegArgsPerKind ? cc._passedOrder[X86Reg::kKindGp].id[gpzPos] : Globals::kInvalidRegId;
+     502         420 :         if (regId != Globals::kInvalidRegId) {
+     503             :           uint32_t regType = (typeId <= TypeId::kU32)
+     504         420 :             ? X86Reg::kRegGpd
+     505             :             : X86Reg::kRegGpq;
+     506             :           arg.assignToReg(regType, regId);
+     507             :           func.addUsedRegs(X86Reg::kKindGp, Utils::mask(regId));
+     508         420 :           gpzPos++;
+     509             :         }
+     510             :         else {
+     511           0 :           uint32_t size = std::max<uint32_t>(TypeId::sizeOf(typeId), gpSize);
+     512             :           arg.assignToStack(stackOffset);
+     513           0 :           stackOffset += size;
+     514             :         }
+     515         420 :         continue;
+     516         420 :       }
+     517             : 
+     518        1450 :       if (TypeId::isFloat(typeId) || TypeId::isVec(typeId)) {
+     519        1450 :         uint32_t regId = vecPos < CallConv::kNumRegArgsPerKind ? cc._passedOrder[X86Reg::kKindVec].id[vecPos] : Globals::kInvalidRegId;
+     520             : 
+     521             :         // If this is a float, but `floatByVec` is false, we have to pass by stack.
+     522        1450 :         if (TypeId::isFloat(typeId) && !cc.hasFlag(CallConv::kFlagPassFloatsByVec))
+     523             :           regId = Globals::kInvalidRegId;
+     524             : 
+     525        1450 :         if (regId != Globals::kInvalidRegId) {
+     526             :           arg.initReg(typeId, x86VecTypeIdToRegType(typeId), regId);
+     527             :           func.addUsedRegs(X86Reg::kKindVec, Utils::mask(regId));
+     528        1450 :           vecPos++;
+     529             :         }
+     530             :         else {
+     531             :           int32_t size = TypeId::sizeOf(typeId);
+     532             :           arg.assignToStack(stackOffset);
+     533           0 :           stackOffset += size;
+     534             :         }
+     535        1450 :         continue;
+     536        1450 :       }
+     537             :     }
+     538             :   }
+     539             : 
+     540        3596 :   if (cc.getAlgorithm() == CallConv::kAlgorithmWin64) {
+     541           0 :     for (i = 0; i < argCount; i++) {
+     542             :       FuncDetail::Value& arg = func._args[i];
+     543             : 
+     544             :       uint32_t typeId = arg.getTypeId();
+     545             :       uint32_t size = TypeId::sizeOf(typeId);
+     546             : 
+     547           0 :       if (TypeId::isInt(typeId) || TypeId::isMmx(typeId)) {
+     548           0 :         uint32_t regId = i < CallConv::kNumRegArgsPerKind ? cc._passedOrder[X86Reg::kKindGp].id[i] : Globals::kInvalidRegId;
+     549           0 :         if (regId != Globals::kInvalidRegId) {
+     550           0 :           uint32_t regType = (size <= 4 && !TypeId::isMmx(typeId))
+     551           0 :             ? X86Reg::kRegGpd
+     552             :             : X86Reg::kRegGpq;
+     553             : 
+     554             :           arg.assignToReg(regType, regId);
+     555             :           func.addUsedRegs(X86Reg::kKindGp, Utils::mask(regId));
+     556             :         }
+     557             :         else {
+     558             :           arg.assignToStack(stackOffset);
+     559           0 :           stackOffset += gpSize;
+     560             :         }
+     561           0 :         continue;
+     562           0 :       }
+     563             : 
+     564           0 :       if (TypeId::isFloat(typeId) || TypeId::isVec(typeId)) {
+     565           0 :         uint32_t regId = i < CallConv::kNumRegArgsPerKind ? cc._passedOrder[X86Reg::kKindVec].id[i] : Globals::kInvalidRegId;
+     566           0 :         if (regId != Globals::kInvalidRegId && (TypeId::isFloat(typeId) || cc.hasFlag(CallConv::kFlagVectorCall))) {
+     567             :           uint32_t regType = x86VecTypeIdToRegType(typeId);
+     568             :           uint32_t regId = cc._passedOrder[X86Reg::kKindVec].id[i];
+     569             : 
+     570             :           arg.assignToReg(regType, regId);
+     571             :           func.addUsedRegs(X86Reg::kKindVec, Utils::mask(regId));
+     572             :         }
+     573             :         else {
+     574             :           arg.assignToStack(stackOffset);
+     575           0 :           stackOffset += 8; // Always 8 bytes (float/double).
+     576             :         }
+     577           0 :         continue;
+     578           0 :       }
+     579             :     }
+     580             :   }
+     581             : 
+     582        3596 :   func._argStackSize = stackOffset - stackBase;
+     583        3596 :   return kErrorOk;
+     584             : }
+     585             : 
+     586             : // ============================================================================
+     587             : // [asmjit::X86Internal - FrameLayout]
+     588             : // ============================================================================
+     589             : 
+     590        1948 : ASMJIT_FAVOR_SIZE Error X86Internal::initFrameLayout(FuncFrameLayout& layout, const FuncDetail& func, const FuncFrameInfo& ffi) noexcept {
+     591             :   layout.reset();
+     592             : 
+     593             :   uint32_t kind;
+     594        1948 :   uint32_t gpSize = (func.getCallConv().getArchType() == ArchInfo::kTypeX86) ? 4 : 8;
+     595             : 
+     596             :   // Calculate a bit-mask of all registers that must be saved & restored.
+     597        9740 :   for (kind = 0; kind < Globals::kMaxVRegKinds; kind++)
+     598        7792 :     layout._savedRegs[kind] = (ffi.getDirtyRegs(kind) & ~func.getPassedRegs(kind)) & func.getPreservedRegs(kind);
+     599             : 
+     600             :   // Include EBP|RBP if the function preserves the frame-pointer.
+     601        1948 :   if (ffi.hasPreservedFP()) {
+     602           0 :     layout._preservedFP = true;
+     603           0 :     layout._savedRegs[X86Reg::kKindGp] |= Utils::mask(X86Gp::kIdBp);
+     604             :   }
+     605             : 
+     606             :   // Exclude ESP/RSP - this register is never included in saved-regs.
+     607        1948 :   layout._savedRegs[X86Reg::kKindGp] &= ~Utils::mask(X86Gp::kIdSp);
+     608             : 
+     609             :   // Calculate the final stack alignment.
+     610             :   uint32_t stackAlignment =
+     611             :     std::max<uint32_t>(
+     612             :       std::max<uint32_t>(
+     613        1948 :         ffi.getStackFrameAlignment(),
+     614        1948 :         ffi.getCallFrameAlignment()),
+     615        1948 :       func.getCallConv().getNaturalStackAlignment());
+     616        1948 :   layout._stackAlignment = static_cast<uint8_t>(stackAlignment);
+     617             : 
+     618             :   // Calculate if dynamic stack alignment is required. If true the function has
+     619             :   // to align stack dynamically to match `_stackAlignment` and would require to
+     620             :   // access its stack-based arguments through `_stackArgsRegId`.
+     621        1948 :   bool dsa = stackAlignment > func.getCallConv().getNaturalStackAlignment() && stackAlignment >= 16;
+     622           0 :   layout._dynamicAlignment = dsa;
+     623             : 
+     624             :   // This flag describes if the prolog inserter must store the previous ESP|RSP
+     625             :   // to stack so the epilog inserter can load the stack from it before returning.
+     626           0 :   bool dsaSlotUsed = dsa && !ffi.hasPreservedFP();
+     627        1948 :   layout._dsaSlotUsed = dsaSlotUsed;
+     628             : 
+     629             :   // These two are identical if the function doesn't align its stack dynamically.
+     630             :   uint32_t stackArgsRegId = ffi.getStackArgsRegId();
+     631        1948 :   if (stackArgsRegId == Globals::kInvalidRegId)
+     632             :     stackArgsRegId = X86Gp::kIdSp;
+     633             : 
+     634             :   // Fix stack arguments base-register from ESP|RSP to EBP|RBP in case it was
+     635             :   // not picked before and the function performs dynamic stack alignment.
+     636        1948 :   if (dsa && stackArgsRegId == X86Gp::kIdSp)
+     637             :     stackArgsRegId = X86Gp::kIdBp;
+     638             : 
+     639        1948 :   if (stackArgsRegId != X86Gp::kIdSp)
+     640           0 :     layout._savedRegs[X86Reg::kKindGp] |= Utils::mask(stackArgsRegId) & func.getPreservedRegs(X86Gp::kKindGp);
+     641             : 
+     642        1948 :   layout._stackBaseRegId = X86Gp::kIdSp;
+     643        1948 :   layout._stackArgsRegId = static_cast<uint8_t>(stackArgsRegId);
+     644             : 
+     645             :   // Setup stack size used to save preserved registers.
+     646        1948 :   layout._gpStackSize  = Utils::bitCount(layout.getSavedRegs(X86Reg::kKindGp )) * gpSize;
+     647        1948 :   layout._vecStackSize = Utils::bitCount(layout.getSavedRegs(X86Reg::kKindVec)) * 16 +
+     648             :                          Utils::bitCount(layout.getSavedRegs(X86Reg::kKindMm )) *  8 ;
+     649             : 
+     650             :   uint32_t v = 0;                        // The beginning of the stack frame, aligned to CallFrame alignment.
+     651        1948 :   v += ffi._callFrameSize;               // Count '_callFrameSize'  <- This is used to call functions.
+     652             :   v  = Utils::alignTo(v, stackAlignment);// Align to function's SA
+     653             : 
+     654        1948 :   layout._stackBaseOffset = v;           // Store '_stackBaseOffset'<- Function's own stack starts here..
+     655        1948 :   v += ffi._stackFrameSize;              // Count '_stackFrameSize' <- Function's own stack ends here.
+     656             : 
+     657             :   // If the function is aligned, calculate the alignment necessary to store
+     658             :   // vector registers, and set `FuncFrameInfo::kX86FlagAlignedVecSR` to inform
+     659             :   // PrologEpilog inserter that it can use instructions to perform aligned
+     660             :   // stores/loads to save/restore VEC registers.
+     661        1948 :   if (stackAlignment >= 16 && layout._vecStackSize) {
+     662             :     v = Utils::alignTo(v, 16);           // Align '_vecStackOffset'.
+     663           0 :     layout._alignedVecSR = true;
+     664             :   }
+     665             : 
+     666        1948 :   layout._vecStackOffset = v;            // Store '_vecStackOffset' <- Functions VEC Save|Restore starts here.
+     667        1948 :   v += layout._vecStackSize;             // Count '_vecStackSize'   <- Functions VEC Save|Restore ends here.
+     668             : 
+     669        1948 :   if (dsaSlotUsed) {
+     670           0 :     layout._dsaSlot = v;                 // Store '_dsaSlot'        <- Old stack pointer is stored here.
+     671           0 :     v += gpSize;
+     672             :   }
+     673             : 
+     674             :   // The return address should be stored after GP save/restore regs. It has
+     675             :   // the same size as `gpSize` (basically the native register/pointer size).
+     676             :   // We don't adjust it now as `v` now contains the exact size that the
+     677             :   // function requires to adjust (call frame + stack frame, vec stack size).
+     678             :   // The stack (if we consider this size) is misaligned now, as it's always
+     679             :   // aligned before the function call - when `call()` is executed it pushes
+     680             :   // the current EIP|RIP onto the stack, and misaligns it by 12 or 8 bytes
+     681             :   // (depending on the architecture). So count number of bytes needed to align
+     682             :   // it up to the function's CallFrame (the beginning).
+     683        1948 :   if (v || ffi.hasCalls())
+     684        1092 :     v += Utils::alignDiff(v + layout._gpStackSize + gpSize, stackAlignment);
+     685             : 
+     686        1948 :   layout._stackAdjustment = v;           // Store '_stackAdjustment'<- SA used by 'add zsp, SA' and 'sub zsp, SA'.
+     687        1948 :   layout._gpStackOffset = v;             // Store '_gpStackOffset'  <- Functions GP Save|Restore starts here.
+     688        1948 :   v += layout._gpStackSize;              // Count '_gpStackSize'    <- Functions GP Save|Restore ends here.
+     689             : 
+     690        1948 :   v += gpSize;                           // Count 'ReturnAddress'.
+     691        1948 :   v += func.getSpillZoneSize();          // Count 'SpillZoneSize'.
+     692             : 
+     693             :   // Calculate where function arguments start, relative to the stackArgsRegId.
+     694             :   // If the register that will be used to access arguments passed by stack is
+     695             :   // ESP|RSP then it's exactly where we are now, otherwise we must calculate
+     696             :   // how many 'push regs' we did and adjust it based on that.
+     697             :   uint32_t stackArgsOffset = v;
+     698        1948 :   if (stackArgsRegId != X86Gp::kIdSp) {
+     699           0 :     if (ffi.hasPreservedFP())
+     700             :       stackArgsOffset = gpSize;
+     701             :     else
+     702             :       stackArgsOffset = layout._gpStackSize;
+     703             :   }
+     704        1948 :   layout._stackArgsOffset = stackArgsOffset;
+     705             : 
+     706             :   // If the function does dynamic stack adjustment then the stack-adjustment
+     707             :   // must be aligned.
+     708        1948 :   if (dsa)
+     709           0 :     layout._stackAdjustment = Utils::alignTo(layout._stackAdjustment, stackAlignment);
+     710             : 
+     711             :   // Initialize variables based on CallConv flags.
+     712        1948 :   if (func.hasFlag(CallConv::kFlagCalleePopsStack))
+     713           0 :     layout._calleeStackCleanup = static_cast<uint16_t>(func.getArgStackSize());
+     714             : 
+     715             :   // Initialize variables based on FFI flags.
+     716        1948 :   layout._mmxCleanup = ffi.hasMmxCleanup();
+     717        1948 :   layout._avxEnabled = ffi.isAvxEnabled();
+     718        1948 :   layout._avxCleanup = ffi.hasAvxCleanup();
+     719             : 
+     720        1948 :   return kErrorOk;
+     721             : }
+     722             : 
+     723             : // ============================================================================
+     724             : // [asmjit::X86Internal - ArgsToFrameInfo]
+     725             : // ============================================================================
+     726             : 
+     727           0 : ASMJIT_FAVOR_SIZE Error X86Internal::argsToFrameInfo(const FuncArgsMapper& args, FuncFrameInfo& ffi) noexcept {
+     728           0 :   X86FuncArgsContext ctx;
+     729           0 :   ASMJIT_PROPAGATE(ctx.initWorkData(args, ffi._dirtyRegs, ffi.hasPreservedFP()));
+     730             : 
+     731           0 :   ASMJIT_PROPAGATE(ctx.markDstRegsDirty(ffi));
+     732           0 :   ASMJIT_PROPAGATE(ctx.markRegsForSwaps(ffi));
+     733           0 :   ASMJIT_PROPAGATE(ctx.markStackArgsReg(ffi));
+     734             :   return kErrorOk;
+     735             : }
+     736             : 
+     737             : // ============================================================================
+     738             : // [asmjit::X86Internal - Emit Helpers]
+     739             : // ============================================================================
+     740             : 
+     741        9084 : ASMJIT_FAVOR_SIZE Error X86Internal::emitRegMove(X86Emitter* emitter,
+     742             :   const Operand_& dst_,
+     743             :   const Operand_& src_, uint32_t typeId, bool avxEnabled, const char* comment) {
+     744             : 
+     745             :   // Invalid or abstract TypeIds are not allowed.
+     746             :   ASMJIT_ASSERT(TypeId::isValid(typeId) && !TypeId::isAbstract(typeId));
+     747             : 
+     748             :   Operand dst(dst_);
+     749             :   Operand src(src_);
+     750             : 
+     751             :   uint32_t instId = Inst::kIdNone;
+     752             :   uint32_t memFlags = 0;
+     753             : 
+     754             :   enum MemFlags {
+     755             :     kDstMem = 0x1,
+     756             :     kSrcMem = 0x2
+     757             :   };
+     758             : 
+     759             :   // Detect memory operands and patch them to have the same size as the register.
+     760             :   // CodeCompiler always sets memory size of allocs and spills, so it shouldn't
+     761             :   // be really necessary, however, after this function was separated from Compiler
+     762             :   // it's better to make sure that the size is always specified, as we can use
+     763             :   // 'movzx' and 'movsx' that rely on it.
+     764        9084 :   if (dst.isMem()) { memFlags |= kDstMem; dst.as<X86Mem>().setSize(src.getSize()); }
+     765        9084 :   if (src.isMem()) { memFlags |= kSrcMem; src.as<X86Mem>().setSize(dst.getSize()); }
+     766             : 
+     767        9084 :   switch (typeId) {
+     768           0 :     case TypeId::kI8:
+     769             :     case TypeId::kU8:
+     770             :     case TypeId::kI16:
+     771             :     case TypeId::kU16:
+     772             :       // Special case - 'movzx' load.
+     773           0 :       if (memFlags & kSrcMem) {
+     774             :         instId = X86Inst::kIdMovzx;
+     775             :         dst.setSignature(X86RegTraits<X86Reg::kRegGpd>::kSignature);
+     776             :       }
+     777           0 :       else if (!memFlags) {
+     778             :         // Change both destination and source registers to GPD (safer, no dependencies).
+     779             :         dst.setSignature(X86RegTraits<X86Reg::kRegGpd>::kSignature);
+     780             :         src.setSignature(X86RegTraits<X86Reg::kRegGpd>::kSignature);
+     781             :       }
+     782             :       ASMJIT_FALLTHROUGH;
+     783             : 
+     784             :     case TypeId::kI32:
+     785             :     case TypeId::kU32:
+     786             :     case TypeId::kI64:
+     787             :     case TypeId::kU64:
+     788             :       instId = X86Inst::kIdMov;
+     789             :       break;
+     790             : 
+     791           0 :     case TypeId::kMmx32:
+     792             :       instId = X86Inst::kIdMovd;
+     793           0 :       if (memFlags) break;
+     794             :       ASMJIT_FALLTHROUGH;
+     795           0 :     case TypeId::kMmx64 : instId = X86Inst::kIdMovq ; break;
+     796             :     case TypeId::kMask8 : instId = X86Inst::kIdKmovb; break;
+     797           0 :     case TypeId::kMask16: instId = X86Inst::kIdKmovw; break;
+     798           0 :     case TypeId::kMask32: instId = X86Inst::kIdKmovd; break;
+     799           0 :     case TypeId::kMask64: instId = X86Inst::kIdKmovq; break;
+     800             : 
+     801             :     default: {
+     802             :       uint32_t elementTypeId = TypeId::elementOf(typeId);
+     803        9084 :       if (TypeId::isVec32(typeId) && memFlags) {
+     804           0 :         if (elementTypeId == TypeId::kF32)
+     805           0 :           instId = avxEnabled ? X86Inst::kIdVmovss : X86Inst::kIdMovss;
+     806             :         else
+     807           0 :           instId = avxEnabled ? X86Inst::kIdVmovd : X86Inst::kIdMovd;
+     808             :         break;
+     809             :       }
+     810             : 
+     811        9084 :       if (TypeId::isVec64(typeId) && memFlags) {
+     812        8428 :         if (elementTypeId == TypeId::kF64)
+     813        8428 :           instId = avxEnabled ? X86Inst::kIdVmovsd : X86Inst::kIdMovsd;
+     814             :         else
+     815           0 :           instId = avxEnabled ? X86Inst::kIdVmovq : X86Inst::kIdMovq;
+     816             :         break;
+     817             :       }
+     818             : 
+     819         656 :       if (elementTypeId == TypeId::kF32)
+     820           0 :         instId = avxEnabled ? X86Inst::kIdVmovaps : X86Inst::kIdMovaps;
+     821         656 :       else if (elementTypeId == TypeId::kF64)
+     822         656 :         instId = avxEnabled ? X86Inst::kIdVmovapd : X86Inst::kIdMovapd;
+     823           0 :       else if (typeId <= TypeId::_kVec256End)
+     824           0 :         instId = avxEnabled ? X86Inst::kIdVmovdqa : X86Inst::kIdMovdqa;
+     825           0 :       else if (elementTypeId <= TypeId::kU32)
+     826             :         instId = X86Inst::kIdVmovdqa32;
+     827             :       else
+     828             :         instId = X86Inst::kIdVmovdqa64;
+     829             :       break;
+     830             :     }
+     831             :   }
+     832             : 
+     833             :   if (!instId)
+     834             :     return DebugUtils::errored(kErrorInvalidState);
+     835             : 
+     836             :   emitter->setInlineComment(comment);
+     837        9084 :   return emitter->emit(instId, dst, src);
+     838             : }
+     839             : 
+     840           0 : ASMJIT_FAVOR_SIZE Error X86Internal::emitArgMove(X86Emitter* emitter,
+     841             :   const X86Reg& dst_, uint32_t dstTypeId,
+     842             :   const Operand_& src_, uint32_t srcTypeId, bool avxEnabled, const char* comment) {
+     843             : 
+     844             :   // Deduce optional `dstTypeId`, which may be `TypeId::kVoid` in some cases.
+     845           0 :   if (!dstTypeId) dstTypeId = x86OpData.archRegs.regTypeToTypeId[dst_.getType()];
+     846             : 
+     847             :   // Invalid or abstract TypeIds are not allowed.
+     848             :   ASMJIT_ASSERT(TypeId::isValid(dstTypeId) && !TypeId::isAbstract(dstTypeId));
+     849             :   ASMJIT_ASSERT(TypeId::isValid(srcTypeId) && !TypeId::isAbstract(srcTypeId));
+     850             : 
+     851             :   X86Reg dst(dst_);
+     852             :   Operand src(src_);
+     853             : 
+     854           0 :   uint32_t dstSize = TypeId::sizeOf(dstTypeId);
+     855           0 :   uint32_t srcSize = TypeId::sizeOf(srcTypeId);
+     856             : 
+     857             :   int32_t instId = Inst::kIdNone;
+     858             : 
+     859             :   // Not a real loop, just 'break' is nicer than 'goto'.
+     860             :   for (;;) {
+     861           0 :     if (TypeId::isInt(dstTypeId)) {
+     862           0 :       if (TypeId::isInt(srcTypeId)) {
+     863             :         instId = X86Inst::kIdMovsx;
+     864           0 :         uint32_t typeOp = (dstTypeId << 8) | srcTypeId;
+     865             : 
+     866             :         // Sign extend by using 'movsx'.
+     867           0 :         if (typeOp == ((TypeId::kI16 << 8) | TypeId::kI8 ) ||
+     868           0 :             typeOp == ((TypeId::kI32 << 8) | TypeId::kI8 ) ||
+     869           0 :             typeOp == ((TypeId::kI32 << 8) | TypeId::kI16) ||
+     870           0 :             typeOp == ((TypeId::kI64 << 8) | TypeId::kI8 ) ||
+     871             :             typeOp == ((TypeId::kI64 << 8) | TypeId::kI16)) break;
+     872             : 
+     873             :         // Sign extend by using 'movsxd'.
+     874             :         instId = X86Inst::kIdMovsxd;
+     875             :         if (typeOp == ((TypeId::kI64 << 8) | TypeId::kI32)) break;
+     876             :       }
+     877             : 
+     878           0 :       if (TypeId::isInt(srcTypeId) || src_.isMem()) {
+     879             :         // Zero extend by using 'movzx' or 'mov'.
+     880           0 :         if (dstSize <= 4 && srcSize < 4) {
+     881             :           instId = X86Inst::kIdMovzx;
+     882             :           dst.setSignature(X86Reg::signatureOfT<X86Reg::kRegGpd>());
+     883             :         }
+     884             :         else {
+     885             :           // We should have caught all possibilities where `srcSize` is less
+     886             :           // than 4, so we don't have to worry about 'movzx' anymore. Minimum
+     887             :           // size is enough to determine if we want 32-bit or 64-bit move.
+     888             :           instId = X86Inst::kIdMov;
+     889           0 :           srcSize = std::min(srcSize, dstSize);
+     890             : 
+     891           0 :           dst.setSignature(srcSize == 4 ? X86Reg::signatureOfT<X86Reg::kRegGpd>()
+     892             :                                         : X86Reg::signatureOfT<X86Reg::kRegGpq>());
+     893           0 :           if (src.isReg()) src.setSignature(dst.getSignature());
+     894             :         }
+     895             :         break;
+     896             :       }
+     897             : 
+     898             :       // NOTE: The previous branch caught all memory sources, from here it's
+     899             :       // always register to register conversion, so catch the remaining cases.
+     900           0 :       srcSize = std::min(srcSize, dstSize);
+     901             : 
+     902           0 :       if (TypeId::isMmx(srcTypeId)) {
+     903             :         // 64-bit move.
+     904             :         instId = X86Inst::kIdMovq;
+     905           0 :         if (srcSize == 8) break;
+     906             : 
+     907             :         // 32-bit move.
+     908             :         instId = X86Inst::kIdMovd;
+     909             :         dst.setSignature(X86Reg::signatureOfT<X86Reg::kRegGpd>());
+     910             :         break;
+     911             :       }
+     912             : 
+     913           0 :       if (TypeId::isMask(srcTypeId)) {
+     914           0 :         instId = X86Inst::kmovIdFromSize(srcSize);
+     915           0 :         dst.setSignature(srcSize <= 4 ? X86Reg::signatureOfT<X86Reg::kRegGpd>()
+     916             :                                       : X86Reg::signatureOfT<X86Reg::kRegGpq>());
+     917             :         break;
+     918             :       }
+     919             : 
+     920           0 :       if (TypeId::isVec(srcTypeId)) {
+     921             :         // 64-bit move.
+     922           0 :         instId = avxEnabled ? X86Inst::kIdVmovq : X86Inst::kIdMovq;
+     923           0 :         if (srcSize == 8) break;
+     924             : 
+     925             :         // 32-bit move.
+     926           0 :         instId = avxEnabled ? X86Inst::kIdVmovd : X86Inst::kIdMovd;
+     927             :         dst.setSignature(X86Reg::signatureOfT<X86Reg::kRegGpd>());
+     928             :         break;
+     929             :       }
+     930             :     }
+     931             : 
+     932           0 :     if (TypeId::isMmx(dstTypeId)) {
+     933             :       instId = X86Inst::kIdMovq;
+     934           0 :       srcSize = std::min(srcSize, dstSize);
+     935             : 
+     936           0 :       if (TypeId::isInt(srcTypeId) || src.isMem()) {
+     937             :         // 64-bit move.
+     938           0 :         if (srcSize == 8) break;
+     939             : 
+     940             :         // 32-bit move.
+     941             :         instId = X86Inst::kIdMovd;
+     942           0 :         if (src.isReg()) src.setSignature(X86Reg::signatureOfT<X86Reg::kRegGpd>());
+     943             :         break;
+     944             :       }
+     945             : 
+     946           0 :       if (TypeId::isMmx(srcTypeId)) break;
+     947             : 
+     948             :       // NOTE: This will hurt if `avxEnabled`.
+     949             :       instId = X86Inst::kIdMovdq2q;
+     950           0 :       if (TypeId::isVec(srcTypeId)) break;
+     951             :     }
+     952             : 
+     953           0 :     if (TypeId::isMask(dstTypeId)) {
+     954           0 :       srcSize = std::min(srcSize, dstSize);
+     955             : 
+     956           0 :       if (TypeId::isInt(srcTypeId) || TypeId::isMask(srcTypeId) || src.isMem()) {
+     957           0 :         instId = X86Inst::kmovIdFromSize(srcSize);
+     958           0 :         if (X86Reg::isGp(src) && srcSize <= 4) src.setSignature(X86Reg::signatureOfT<X86Reg::kRegGpd>());
+     959             :         break;
+     960             :       }
+     961             :     }
+     962             : 
+     963           0 :     if (TypeId::isVec(dstTypeId)) {
+     964             :       // By default set destination to XMM, will be set to YMM|ZMM if needed.
+     965             :       dst.setSignature(X86Reg::signatureOfT<X86Reg::kRegXmm>());
+     966             : 
+     967             :       // NOTE: This will hurt if `avxEnabled`.
+     968           0 :       if (X86Reg::isMm(src)) {
+     969             :         // 64-bit move.
+     970             :         instId = X86Inst::kIdMovq2dq;
+     971             :         break;
+     972             :       }
+     973             : 
+     974             :       // Argument conversion.
+     975             :       uint32_t dstElement = TypeId::elementOf(dstTypeId);
+     976             :       uint32_t srcElement = TypeId::elementOf(srcTypeId);
+     977             : 
+     978           0 :       if (dstElement == TypeId::kF32 && srcElement == TypeId::kF64) {
+     979           0 :         srcSize = std::min(dstSize * 2, srcSize);
+     980           0 :         dstSize = srcSize / 2;
+     981             : 
+     982           0 :         if (srcSize <= 8)
+     983           0 :           instId = avxEnabled ? X86Inst::kIdVcvtss2sd : X86Inst::kIdCvtss2sd;
+     984             :         else
+     985           0 :           instId = avxEnabled ? X86Inst::kIdVcvtps2pd : X86Inst::kIdCvtps2pd;
+     986             : 
+     987           0 :         if (dstSize == 32)
+     988             :           dst.setSignature(X86Reg::signatureOfT<X86Reg::kRegYmm>());
+     989           0 :         if (src.isReg())
+     990             :           src.setSignature(X86Reg::signatureOfVecBySize(srcSize));
+     991             :         break;
+     992             :       }
+     993             : 
+     994           0 :       if (dstElement == TypeId::kF64 && srcElement == TypeId::kF32) {
+     995           0 :         srcSize = std::min(dstSize, srcSize * 2) / 2;
+     996           0 :         dstSize = srcSize * 2;
+     997             : 
+     998           0 :         if (srcSize <= 4)
+     999           0 :           instId = avxEnabled ? X86Inst::kIdVcvtsd2ss : X86Inst::kIdCvtsd2ss;
+    1000             :         else
+    1001           0 :           instId = avxEnabled ? X86Inst::kIdVcvtpd2ps : X86Inst::kIdCvtpd2ps;
+    1002             : 
+    1003             :         dst.setSignature(X86Reg::signatureOfVecBySize(dstSize));
+    1004           0 :         if (src.isReg() && srcSize >= 32)
+    1005             :           src.setSignature(X86Reg::signatureOfT<X86Reg::kRegYmm>());
+    1006             :         break;
+    1007             :       }
+    1008             : 
+    1009           0 :       srcSize = std::min(srcSize, dstSize);
+    1010           0 :       if (X86Reg::isGp(src) || src.isMem()) {
+    1011             :         // 32-bit move.
+    1012           0 :         if (srcSize <= 4) {
+    1013           0 :           instId = avxEnabled ? X86Inst::kIdVmovd : X86Inst::kIdMovd;
+    1014           0 :           if (src.isReg()) src.setSignature(X86Reg::signatureOfT<X86Reg::kRegGpd>());
+    1015             :           break;
+    1016             :         }
+    1017             : 
+    1018             :         // 64-bit move.
+    1019           0 :         if (srcSize == 8) {
+    1020           0 :           instId = avxEnabled ? X86Inst::kIdVmovq : X86Inst::kIdMovq;
+    1021             :           break;
+    1022             :         }
+    1023             :       }
+    1024             : 
+    1025           0 :       if (X86Reg::isVec(src) || src.isMem()) {
+    1026           0 :         instId = avxEnabled ? X86Inst::kIdVmovaps : X86Inst::kIdMovaps;
+    1027             :         uint32_t sign = X86Reg::signatureOfVecBySize(srcSize);
+    1028             : 
+    1029             :         dst.setSignature(sign);
+    1030           0 :         if (src.isReg()) src.setSignature(sign);
+    1031             :         break;
+    1032             :       }
+    1033             :     }
+    1034             : 
+    1035             :     return DebugUtils::errored(kErrorInvalidState);
+    1036             :   }
+    1037             : 
+    1038           0 :   if (src.isMem())
+    1039           0 :     src.as<X86Mem>().setSize(srcSize);
+    1040             : 
+    1041             :   emitter->setInlineComment(comment);
+    1042           0 :   return emitter->emit(instId, dst, src);
+    1043             : }
+    1044             : 
+    1045             : // ============================================================================
+    1046             : // [asmjit::X86Internal - Emit Prolog & Epilog]
+    1047             : // ============================================================================
+    1048             : 
+    1049        1948 : ASMJIT_FAVOR_SIZE Error X86Internal::emitProlog(X86Emitter* emitter, const FuncFrameLayout& layout) {
+    1050             :   uint32_t gpSaved = layout.getSavedRegs(X86Reg::kKindGp);
+    1051             : 
+    1052             :   X86Gp zsp = emitter->zsp();   // ESP|RSP register.
+    1053             :   X86Gp zbp = emitter->zbp();   // EBP|RBP register.
+    1054             :   X86Gp gpReg = emitter->zsp(); // General purpose register (temporary).
+    1055             :   X86Gp saReg = emitter->zsp(); // Stack-arguments base register.
+    1056             : 
+    1057             :   // Emit: 'push zbp'
+    1058             :   //       'mov  zbp, zsp'.
+    1059        1948 :   if (layout.hasPreservedFP()) {
+    1060           0 :     gpSaved &= ~Utils::mask(X86Gp::kIdBp);
+    1061           0 :     ASMJIT_PROPAGATE(emitter->push(zbp));
+    1062           0 :     ASMJIT_PROPAGATE(emitter->mov(zbp, zsp));
+    1063             :   }
+    1064             : 
+    1065             :   // Emit: 'push gp' sequence.
+    1066        1948 :   if (gpSaved) {
+    1067        5468 :     for (uint32_t i = gpSaved, regId = 0; i; i >>= 1, regId++) {
+    1068        4392 :       if (!(i & 0x1)) continue;
+    1069             :       gpReg.setId(regId);
+    1070        1120 :       ASMJIT_PROPAGATE(emitter->push(gpReg));
+    1071             :     }
+    1072             :   }
+    1073             : 
+    1074             :   // Emit: 'mov saReg, zsp'.
+    1075             :   uint32_t stackArgsRegId = layout.getStackArgsRegId();
+    1076        1948 :   if (stackArgsRegId != Globals::kInvalidRegId && stackArgsRegId != X86Gp::kIdSp) {
+    1077             :     saReg.setId(stackArgsRegId);
+    1078           0 :     if (!(layout.hasPreservedFP() && stackArgsRegId == X86Gp::kIdBp))
+    1079           0 :       ASMJIT_PROPAGATE(emitter->mov(saReg, zsp));
+    1080             :   }
+    1081             : 
+    1082             :   // Emit: 'and zsp, StackAlignment'.
+    1083        1948 :   if (layout.hasDynamicAlignment())
+    1084           0 :     ASMJIT_PROPAGATE(emitter->and_(zsp, -static_cast<int32_t>(layout.getStackAlignment())));
+    1085             : 
+    1086             :   // Emit: 'sub zsp, StackAdjustment'.
+    1087        1948 :   if (layout.hasStackAdjustment())
+    1088         932 :     ASMJIT_PROPAGATE(emitter->sub(zsp, layout.getStackAdjustment()));
+    1089             : 
+    1090             :   // Emit: 'mov [zsp + dsaSlot], saReg'.
+    1091        1948 :   if (layout.hasDynamicAlignment() && layout.hasDsaSlotUsed()) {
+    1092           0 :     X86Mem saMem = x86::ptr(zsp, layout._dsaSlot);
+    1093           0 :     ASMJIT_PROPAGATE(emitter->mov(saMem, saReg));
+    1094             :   }
+    1095             : 
+    1096             :   // Emit 'movaps|movups [zsp + X], xmm0..15'.
+    1097             :   uint32_t xmmSaved = layout.getSavedRegs(X86Reg::kKindVec);
+    1098        1948 :   if (xmmSaved) {
+    1099             :     X86Mem vecBase = x86::ptr(zsp, layout.getVecStackOffset());
+    1100             :     X86Reg vecReg = x86::xmm(0);
+    1101             : 
+    1102             :     uint32_t vecInst = x86GetXmmMovInst(layout);
+    1103             :     uint32_t vecSize = 16;
+    1104             : 
+    1105           0 :     for (uint32_t i = xmmSaved, regId = 0; i; i >>= 1, regId++) {
+    1106           0 :       if (!(i & 0x1)) continue;
+    1107             :       vecReg.setId(regId);
+    1108           0 :       ASMJIT_PROPAGATE(emitter->emit(vecInst, vecBase, vecReg));
+    1109             :       vecBase.addOffsetLo32(static_cast<int32_t>(vecSize));
+    1110             :     }
+    1111             :   }
+    1112             : 
+    1113             :   return kErrorOk;
+    1114             : }
+    1115             : 
+    1116        1948 : ASMJIT_FAVOR_SIZE Error X86Internal::emitEpilog(X86Emitter* emitter, const FuncFrameLayout& layout) {
+    1117             :   uint32_t i;
+    1118             :   uint32_t regId;
+    1119             : 
+    1120             :   uint32_t gpSize = emitter->getGpSize();
+    1121             :   uint32_t gpSaved = layout.getSavedRegs(X86Reg::kKindGp);
+    1122             : 
+    1123             :   X86Gp zsp = emitter->zsp();   // ESP|RSP register.
+    1124             :   X86Gp zbp = emitter->zbp();   // EBP|RBP register.
+    1125             :   X86Gp gpReg = emitter->zsp(); // General purpose register (temporary).
+    1126             : 
+    1127             :   // Don't emit 'pop zbp' in the pop sequence, this case is handled separately.
+    1128        1948 :   if (layout.hasPreservedFP()) gpSaved &= ~Utils::mask(X86Gp::kIdBp);
+    1129             : 
+    1130             :   // Emit 'movaps|movups xmm0..15, [zsp + X]'.
+    1131             :   uint32_t xmmSaved = layout.getSavedRegs(X86Reg::kKindVec);
+    1132        1948 :   if (xmmSaved) {
+    1133             :     X86Mem vecBase = x86::ptr(zsp, layout.getVecStackOffset());
+    1134             :     X86Reg vecReg = x86::xmm(0);
+    1135             : 
+    1136             :     uint32_t vecInst = x86GetXmmMovInst(layout);
+    1137             :     uint32_t vecSize = 16;
+    1138             : 
+    1139           0 :     for (i = xmmSaved, regId = 0; i; i >>= 1, regId++) {
+    1140           0 :       if (!(i & 0x1)) continue;
+    1141             :       vecReg.setId(regId);
+    1142           0 :       ASMJIT_PROPAGATE(emitter->emit(vecInst, vecReg, vecBase));
+    1143             :       vecBase.addOffsetLo32(static_cast<int32_t>(vecSize));
+    1144             :     }
+    1145             :   }
+    1146             : 
+    1147             :   // Emit 'emms' and 'vzeroupper'.
+    1148        1948 :   if (layout.hasMmxCleanup()) ASMJIT_PROPAGATE(emitter->emms());
+    1149        1948 :   if (layout.hasAvxCleanup()) ASMJIT_PROPAGATE(emitter->vzeroupper());
+    1150             : 
+    1151        1948 :   if (layout.hasPreservedFP()) {
+    1152             :     // Emit 'mov zsp, zbp' or 'lea zsp, [zbp - x]'
+    1153           0 :     int32_t count = static_cast<int32_t>(layout.getGpStackSize() - gpSize);
+    1154           0 :     if (!count)
+    1155           0 :       ASMJIT_PROPAGATE(emitter->mov(zsp, zbp));
+    1156             :     else
+    1157           0 :       ASMJIT_PROPAGATE(emitter->lea(zsp, x86::ptr(zbp, -count)));
+    1158             :   }
+    1159             :   else {
+    1160        1948 :     if (layout.hasDynamicAlignment() && layout.hasDsaSlotUsed()) {
+    1161             :       // Emit 'mov zsp, [zsp + DsaSlot]'.
+    1162           0 :       X86Mem saMem = x86::ptr(zsp, layout._dsaSlot);
+    1163           0 :       ASMJIT_PROPAGATE(emitter->mov(zsp, saMem));
+    1164             :     }
+    1165        1948 :     else if (layout.hasStackAdjustment()) {
+    1166             :       // Emit 'add zsp, StackAdjustment'.
+    1167         932 :       ASMJIT_PROPAGATE(emitter->add(zsp, static_cast<int32_t>(layout.getStackAdjustment())));
+    1168             :     }
+    1169             :   }
+    1170             : 
+    1171             :   // Emit 'pop gp' sequence.
+    1172        1948 :   if (gpSaved) {
+    1173             :     i = gpSaved;
+    1174             :     regId = 16;
+    1175             : 
+    1176             :     do {
+    1177       17216 :       regId--;
+    1178       17216 :       if (i & 0x8000) {
+    1179             :         gpReg.setId(regId);
+    1180        1120 :         ASMJIT_PROPAGATE(emitter->pop(gpReg));
+    1181             :       }
+    1182       17216 :       i <<= 1;
+    1183       17216 :     } while (regId != 0);
+    1184             :   }
+    1185             : 
+    1186             :   // Emit 'pop zbp'.
+    1187        1948 :   if (layout.hasPreservedFP()) ASMJIT_PROPAGATE(emitter->pop(zbp));
+    1188             : 
+    1189             :   // Emit 'ret' or 'ret x'.
+    1190        1948 :   if (layout.hasCalleeStackCleanup())
+    1191           0 :     ASMJIT_PROPAGATE(emitter->emit(X86Inst::kIdRet, static_cast<int>(layout.getCalleeStackCleanup())));
+    1192             :   else
+    1193        1948 :     ASMJIT_PROPAGATE(emitter->emit(X86Inst::kIdRet));
+    1194             : 
+    1195             :   return kErrorOk;
+    1196             : }
+    1197             : 
+    1198             : // ============================================================================
+    1199             : // [asmjit::X86Internal - AllocArgs]
+    1200             : // ============================================================================
+    1201             : 
+    1202           0 : ASMJIT_FAVOR_SIZE Error X86Internal::allocArgs(X86Emitter* emitter, const FuncFrameLayout& layout, const FuncArgsMapper& args) {
+    1203             :   typedef X86FuncArgsContext::SrcArg SrcArg;
+    1204             :   typedef X86FuncArgsContext::DstArg DstArg;
+    1205             :   typedef X86FuncArgsContext::WorkData WorkData;
+    1206             :   enum { kMaxVRegKinds = Globals::kMaxVRegKinds };
+    1207             : 
+    1208             :   uint32_t i;
+    1209             :   const FuncDetail& func = *args.getFuncDetail();
+    1210             : 
+    1211           0 :   X86FuncArgsContext ctx;
+    1212           0 :   ASMJIT_PROPAGATE(ctx.initWorkData(args, layout._savedRegs, layout.hasPreservedFP()));
+    1213             : 
+    1214             :   // We must honor AVX if it's enabled.
+    1215             :   bool avxEnabled = layout.isAvxEnabled();
+    1216             : 
+    1217             :   // Free registers that can be used as temporaries and during shuffling.
+    1218             :   // We initialize them to match all workRegs (registers that can be used
+    1219             :   // by the function) except source regs, which are used to pass arguments.
+    1220             :   // Free registers are changed during shuffling - when an argument is moved
+    1221             :   // to the final register then the register itself is removed from freeRegs
+    1222             :   // (it can't be altered anymore during shuffling).
+    1223             :   uint32_t freeRegs[kMaxVRegKinds];
+    1224           0 :   for (i = 0; i < kMaxVRegKinds; i++)
+    1225           0 :     freeRegs[i] = ctx._workData[i].workRegs & ~ctx._workData[i].srcRegs;
+    1226             : 
+    1227             :   // This is an iterative process that runs until there is a work to do. When
+    1228             :   // one register is moved it can create space for another move. Such moves can
+    1229             :   // depend on each other so the algorithm may run multiple times before all
+    1230             :   // arguments are in place. This part does only register-to-register work,
+    1231             :   // arguments moved from stack-to-register area handled later.
+    1232             :   for (;;) {
+    1233             :     bool hasWork = false; // Do we have a work to do?
+    1234             :     bool didWork = false; // If we did something...
+    1235             : 
+    1236             :     uint32_t dstRegKind = kMaxVRegKinds;
+    1237             :     do {
+    1238           0 :       WorkData& wd = ctx._workData[--dstRegKind];
+    1239           0 :       if (wd.numOps > wd.numStackArgs) {
+    1240             :         hasWork = true;
+    1241             : 
+    1242             :         // Iterate over all destination regs and check if we can do something.
+    1243             :         // We always go from destination to source, never the opposite.
+    1244           0 :         uint32_t regsToDo = wd.dstRegs;
+    1245             :         do {
+    1246             :           // If there is a work to do there has to be at least one dstReg.
+    1247             :           ASMJIT_ASSERT(regsToDo != 0);
+    1248             :           uint32_t dstRegId = Utils::findFirstBit(regsToDo);
+    1249             :           uint32_t dstRegMask = Utils::mask(dstRegId);
+    1250             : 
+    1251           0 :           uint32_t argIndex = wd.argIndex[dstRegId];
+    1252           0 :           const DstArg& dstArg = args.getArg(argIndex);
+    1253             :           const SrcArg& srcArg = func.getArg(argIndex);
+    1254             : 
+    1255           0 :           if (srcArg.byReg()) {
+    1256           0 :             uint32_t srcRegType = srcArg.getRegType();
+    1257             :             uint32_t srcRegKind = X86Reg::kindOf(srcRegType);
+    1258             : 
+    1259           0 :             if (freeRegs[dstRegKind] & dstRegMask) {
+    1260             :               X86Reg dstReg(X86Reg::fromTypeAndId(dstArg.getRegType(), dstRegId));
+    1261             :               X86Reg srcReg(X86Reg::fromTypeAndId(srcRegType, srcArg.getRegId()));
+    1262             : 
+    1263           0 :               ASMJIT_PROPAGATE(
+    1264             :                 emitArgMove(emitter,
+    1265             :                   dstReg, dstArg.getTypeId(),
+    1266             :                   srcReg, srcArg.getTypeId(), avxEnabled));
+    1267           0 :               freeRegs[dstRegKind] ^= dstRegMask;                     // Make the DST reg occupied.
+    1268           0 :               freeRegs[srcRegKind] |= Utils::mask(srcArg.getRegId()); // Make the SRC reg free.
+    1269             : 
+    1270             :               ASMJIT_ASSERT(wd.numOps >= 1);
+    1271           0 :               wd.numOps--;
+    1272             :               didWork = true;
+    1273             :             }
+    1274             :             else {
+    1275             :               // Check if this is a swap operation.
+    1276           0 :               if (dstRegKind == srcRegKind) {
+    1277             :                 uint32_t srcRegId = srcArg.getRegId();
+    1278             : 
+    1279           0 :                 uint32_t otherIndex = wd.argIndex[srcRegId];
+    1280           0 :                 const DstArg& otherArg = args.getArg(otherIndex);
+    1281             : 
+    1282           0 :                 if (otherArg.getRegId() == srcRegId && X86Reg::kindOf(otherArg.getRegType()) == dstRegKind) {
+    1283             :                   // If this is GP reg it can be handled by 'xchg'.
+    1284           0 :                   if (dstRegKind == X86Reg::kKindGp) {
+    1285           0 :                     uint32_t highestType = std::max(dstArg.getRegType(), srcRegType);
+    1286             : 
+    1287           0 :                     X86Reg dstReg = x86::gpd(dstRegId);
+    1288           0 :                     X86Reg srcReg = x86::gpd(srcRegId);
+    1289             : 
+    1290           0 :                     if (highestType == X86Reg::kRegGpq) {
+    1291             :                       dstReg.setSignature(X86RegTraits<X86Reg::kRegGpq>::kSignature);
+    1292             :                       srcReg.setSignature(X86RegTraits<X86Reg::kRegGpq>::kSignature);
+    1293             :                     }
+    1294           0 :                     ASMJIT_PROPAGATE(emitter->emit(X86Inst::kIdXchg, dstReg, srcReg));
+    1295           0 :                     regsToDo &= ~Utils::mask(srcRegId);
+    1296           0 :                     freeRegs[dstRegKind] &= ~(Utils::mask(srcRegId) | dstRegMask);
+    1297             : 
+    1298             :                     ASMJIT_ASSERT(wd.numOps >= 2);
+    1299             :                     ASMJIT_ASSERT(wd.numSwaps >= 1);
+    1300           0 :                     wd.numOps-=2;
+    1301           0 :                     wd.numSwaps--;
+    1302             :                     didWork = true;
+    1303             :                   }
+    1304             :                 }
+    1305             :               }
+    1306             :             }
+    1307             :           }
+    1308             : 
+    1309             :           // Clear the reg in `regsToDo` and continue if there are more.
+    1310           0 :           regsToDo ^= dstRegMask;
+    1311           0 :         } while (regsToDo);
+    1312             :       }
+    1313           0 :     } while (dstRegKind);
+    1314             : 
+    1315           0 :     if (!hasWork)
+    1316             :       break;
+    1317             : 
+    1318           0 :     if (!didWork)
+    1319             :       return DebugUtils::errored(kErrorInvalidState);
+    1320             :   }
+    1321             : 
+    1322             :   // Load arguments passed by stack into registers. This is pretty simple and
+    1323             :   // it never requires multiple iterations like the previous phase.
+    1324           0 :   if (ctx._hasStackArgs) {
+    1325             :     // Base address of all arguments passed by stack.
+    1326             :     X86Mem saBase = x86::ptr(emitter->gpz(layout.getStackArgsRegId()), layout.getStackArgsOffset());
+    1327             : 
+    1328             :     uint32_t dstRegKind = kMaxVRegKinds;
+    1329             :     do {
+    1330           0 :       WorkData& wd = ctx._workData[--dstRegKind];
+    1331           0 :       if (wd.numStackArgs) {
+    1332             :         // Iterate over all destination regs and check if we can do something.
+    1333             :         // We always go from destination to source, never the opposite.
+    1334           0 :         uint32_t regsToDo = wd.dstRegs;
+    1335             :         do {
+    1336             :           // If there is a work to do there has to be at least one dstReg.
+    1337             :           ASMJIT_ASSERT(regsToDo != 0);
+    1338             :           ASMJIT_ASSERT(wd.numOps > 0);
+    1339             : 
+    1340             :           uint32_t dstRegId = Utils::findFirstBit(regsToDo);
+    1341             :           uint32_t dstRegMask = Utils::mask(dstRegId);
+    1342             : 
+    1343           0 :           uint32_t argIndex = wd.argIndex[dstRegId];
+    1344           0 :           const DstArg& dstArg = args.getArg(argIndex);
+    1345             :           const SrcArg& srcArg = func.getArg(argIndex);
+    1346             : 
+    1347             :           // Only arguments passed by stack should remain, also the destination
+    1348             :           // registers must be free now (otherwise the first part of the algorithm
+    1349             :           // failed). Ideally this should be assert, but it's much safer to enforce
+    1350             :           // this in release as well.
+    1351           0 :           if (!srcArg.byStack() || !(freeRegs[dstRegKind] & dstRegMask))
+    1352           0 :             return DebugUtils::errored(kErrorInvalidState);
+    1353             : 
+    1354             :           X86Reg dstReg = X86Reg::fromTypeAndId(dstArg.getRegType(), dstRegId);
+    1355             :           X86Mem srcMem = saBase.adjusted(srcArg.getStackOffset());
+    1356             : 
+    1357           0 :           ASMJIT_PROPAGATE(
+    1358             :             emitArgMove(emitter,
+    1359             :               dstReg, dstArg.getTypeId(),
+    1360             :               srcMem, srcArg.getTypeId(), avxEnabled));
+    1361             : 
+    1362           0 :           freeRegs[dstRegKind] ^= dstRegMask;
+    1363           0 :           regsToDo ^= dstRegMask;
+    1364           0 :           wd.numOps--;
+    1365           0 :         } while (regsToDo);
+    1366             :       }
+    1367           0 :     } while (dstRegKind);
+    1368             :   }
+    1369             : 
+    1370             :   return kErrorOk;
+    1371             : }
+    1372             : 
+    1373             : } // asmjit namespace
+    1374             : } // namespace PLMD
+    1375             : 
+    1376             : // [Api-End]
+    1377             : #include "./asmjit_apiend.h"
+    1378             : 
+    1379             : // [Guard]
+    1380             : #endif // ASMJIT_BUILD_X86
+    1381             : #pragma GCC diagnostic pop
+    1382             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86logging.cpp.func-sort-c.html b/coverage-libs/asmjit/x86logging.cpp.func-sort-c.html new file mode 100644 index 000000000000..fb6cdf844e65 --- /dev/null +++ b/coverage-libs/asmjit/x86logging.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86logging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:02030.0 %
Date:2024-02-22 21:58:47Functions:080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10X86Logging13formatOperandERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_8Operand_E0
_ZN4PLMD6asmjit10X86Logging14formatRegisterERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjjj0
_ZN4PLMD6asmjit10X86Logging17formatInstructionERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL23x86GetAddressSizeStringEj0
_ZN4PLMD6asmjitL24X86Logging_formatImmBitsERNS0_13StringBuilderEjPKNS0_7ImmBitsEj0
_ZN4PLMD6asmjitL24X86Logging_formatImmShufERNS0_13StringBuilderEjjj0
_ZN4PLMD6asmjitL24X86Logging_formatImmTextERNS0_13StringBuilderEjjjPKcj0
_ZN4PLMD6asmjitL28X86Logging_formatImmExtendedERNS0_13StringBuilderEjjjRKNS0_3ImmE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86logging.cpp.func.html b/coverage-libs/asmjit/x86logging.cpp.func.html new file mode 100644 index 000000000000..7fe3773b41f8 --- /dev/null +++ b/coverage-libs/asmjit/x86logging.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86logging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:02030.0 %
Date:2024-02-22 21:58:47Functions:080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10X86Logging13formatOperandERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_8Operand_E0
_ZN4PLMD6asmjit10X86Logging14formatRegisterERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjjj0
_ZN4PLMD6asmjit10X86Logging17formatInstructionERNS0_13StringBuilderEjPKNS0_11CodeEmitterEjRKNS0_4Inst6DetailEPKNS0_8Operand_Ej0
_ZN4PLMD6asmjitL23x86GetAddressSizeStringEj0
_ZN4PLMD6asmjitL24X86Logging_formatImmBitsERNS0_13StringBuilderEjPKNS0_7ImmBitsEj0
_ZN4PLMD6asmjitL24X86Logging_formatImmShufERNS0_13StringBuilderEjjj0
_ZN4PLMD6asmjitL24X86Logging_formatImmTextERNS0_13StringBuilderEjjjPKcj0
_ZN4PLMD6asmjitL28X86Logging_formatImmExtendedERNS0_13StringBuilderEjjjRKNS0_3ImmE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86logging.cpp.gcov.html b/coverage-libs/asmjit/x86logging.cpp.gcov.html new file mode 100644 index 000000000000..59695eaed18f --- /dev/null +++ b/coverage-libs/asmjit/x86logging.cpp.gcov.html @@ -0,0 +1,787 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86logging.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86logging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:02030.0 %
Date:2024-02-22 21:58:47Functions:080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Guard]
+      33             : #include "./asmjit_build.h"
+      34             : #if !defined(ASMJIT_DISABLE_LOGGING)
+      35             : 
+      36             : // [Dependencies]
+      37             : #include "./misc_p.h"
+      38             : #include "./x86inst.h"
+      39             : #include "./x86logging_p.h"
+      40             : #include "./x86operand.h"
+      41             : 
+      42             : #if !defined(ASMJIT_DISABLE_COMPILER)
+      43             : #include "./codecompiler.h"
+      44             : #endif // !ASMJIT_DISABLE_COMPILER
+      45             : 
+      46             : // [Api-Begin]
+      47             : #include "./asmjit_apibegin.h"
+      48             : 
+      49             : namespace PLMD {
+      50             : namespace asmjit {
+      51             : 
+      52             : // ============================================================================
+      53             : // [asmjit::X86Logging - Constants]
+      54             : // ============================================================================
+      55             : 
+      56             : struct X86RegFormatInfo {
+      57             :   uint8_t count;
+      58             :   uint8_t formatIndex;
+      59             :   uint8_t specialIndex;
+      60             :   uint8_t specialCount;
+      61             : };
+      62             : 
+      63             : static const char x86RegFormatStrings[] =
+      64             :   "r%ub"  "\0" // #0
+      65             :   "r%uh"  "\0" // #5
+      66             :   "r%uw"  "\0" // #10
+      67             :   "r%ud"  "\0" // #15
+      68             :   "r%u"   "\0" // #20
+      69             :   "xmm%u" "\0" // #24
+      70             :   "ymm%u" "\0" // #30
+      71             :   "zmm%u" "\0" // #36
+      72             :   "rip%u" "\0" // #42
+      73             :   "seg%u" "\0" // #48
+      74             :   "fp%u"  "\0" // #54
+      75             :   "mm%u"  "\0" // #59
+      76             :   "k%u"   "\0" // #64
+      77             :   "bnd%u" "\0" // #68
+      78             :   "cr%u"  "\0" // #74
+      79             :   "dr%u"  "\0" // #79
+      80             : 
+      81             :   "rip\0"      // #84
+      82             :   "\0\0\0\0"   // #88
+      83             :   "\0\0\0\0"   // #92
+      84             : 
+      85             :   "al\0\0" "cl\0\0" "dl\0\0" "bl\0\0" "spl\0"  "bpl\0"  "sil\0"  "dil\0"  // #96
+      86             :   "ah\0\0" "ch\0\0" "dh\0\0" "bh\0\0" "n/a\0"  "n/a\0"  "n/a\0"  "n/a\0"  // #128
+      87             :   "eax\0"  "ecx\0"  "edx\0"  "ebx\0"  "esp\0"  "ebp\0"  "esi\0"  "edi\0"  // #160
+      88             :   "rax\0"  "rcx\0"  "rdx\0"  "rbx\0"  "rsp\0"  "rbp\0"  "rsi\0"  "rdi\0"  // #192
+      89             :   "n/a\0"  "es\0\0" "cs\0\0" "ss\0\0" "ds\0\0" "fs\0\0" "gs\0\0" "n/a\0"; // #224
+      90             : 
+      91             : template<uint32_t X>
+      92             : struct X86RegFormatInfo_T {
+      93             :   enum {
+      94             :     kFormatIndex  = X == X86Reg::kRegGpbLo ? 0   :
+      95             :                     X == X86Reg::kRegGpbHi ? 5   :
+      96             :                     X == X86Reg::kRegGpw   ? 10  :
+      97             :                     X == X86Reg::kRegGpd   ? 15  :
+      98             :                     X == X86Reg::kRegGpq   ? 20  :
+      99             :                     X == X86Reg::kRegXmm   ? 24  :
+     100             :                     X == X86Reg::kRegYmm   ? 30  :
+     101             :                     X == X86Reg::kRegZmm   ? 36  :
+     102             :                     X == X86Reg::kRegRip   ? 42  :
+     103             :                     X == X86Reg::kRegSeg   ? 48  :
+     104             :                     X == X86Reg::kRegFp    ? 54  :
+     105             :                     X == X86Reg::kRegMm    ? 59  :
+     106             :                     X == X86Reg::kRegK     ? 64  :
+     107             :                     X == X86Reg::kRegBnd   ? 68  :
+     108             :                     X == X86Reg::kRegCr    ? 74  :
+     109             :                     X == X86Reg::kRegDr    ? 79  : 0,
+     110             : 
+     111             :     kSpecialIndex = X == X86Reg::kRegGpbLo ? 96  :
+     112             :                     X == X86Reg::kRegGpbHi ? 128 :
+     113             :                     X == X86Reg::kRegGpw   ? 161 :
+     114             :                     X == X86Reg::kRegGpd   ? 160 :
+     115             :                     X == X86Reg::kRegGpq   ? 192 :
+     116             :                     X == X86Reg::kRegRip   ? 84  :
+     117             :                     X == X86Reg::kRegSeg   ? 224 : 0,
+     118             : 
+     119             :     kSpecialCount = X == X86Reg::kRegGpbLo ? 8   :
+     120             :                     X == X86Reg::kRegGpbHi ? 4   :
+     121             :                     X == X86Reg::kRegGpw   ? 8   :
+     122             :                     X == X86Reg::kRegGpd   ? 8   :
+     123             :                     X == X86Reg::kRegGpq   ? 8   :
+     124             :                     X == X86Reg::kRegRip   ? 1   :
+     125             :                     X == X86Reg::kRegSeg   ? 7   : 0
+     126             :   };
+     127             : };
+     128             : 
+     129             : #define ASMJIT_X86_REG_FORMAT(TYPE) {      \
+     130             :   X86RegTraits<TYPE>::kCount,              \
+     131             :   X86RegFormatInfo_T<TYPE>::kFormatIndex,  \
+     132             :   X86RegFormatInfo_T<TYPE>::kSpecialIndex, \
+     133             :   X86RegFormatInfo_T<TYPE>::kSpecialCount  \
+     134             : }
+     135             : 
+     136             : static const X86RegFormatInfo x86RegFormatInfo[] = {
+     137             :   ASMJIT_TABLE_16(ASMJIT_X86_REG_FORMAT, 0 ),
+     138             :   ASMJIT_TABLE_16(ASMJIT_X86_REG_FORMAT, 16)
+     139             : };
+     140             : 
+     141           0 : static const char* x86GetAddressSizeString(uint32_t size) noexcept {
+     142           0 :   switch (size) {
+     143             :     case 1 : return "byte ";
+     144           0 :     case 2 : return "word ";
+     145           0 :     case 4 : return "dword ";
+     146           0 :     case 6 : return "fword ";
+     147           0 :     case 8 : return "qword ";
+     148           0 :     case 10: return "tword ";
+     149           0 :     case 16: return "oword ";
+     150           0 :     case 32: return "yword ";
+     151           0 :     case 64: return "zword ";
+     152           0 :     default: return "";
+     153             :   }
+     154             : }
+     155             : 
+     156             : // ============================================================================
+     157             : // [asmjit::X86Logging - Format Operand]
+     158             : // ============================================================================
+     159             : 
+     160           0 : ASMJIT_FAVOR_SIZE Error X86Logging::formatOperand(
+     161             :   StringBuilder& sb,
+     162             :   uint32_t logOptions,
+     163             :   const CodeEmitter* emitter,
+     164             :   uint32_t archType,
+     165             :   const Operand_& op) noexcept {
+     166             : 
+     167           0 :   if (op.isReg())
+     168           0 :     return formatRegister(sb, logOptions, emitter, archType, op.as<Reg>().getType(), op.as<Reg>().getId());
+     169             : 
+     170           0 :   if (op.isMem()) {
+     171             :     const X86Mem& m = op.as<X86Mem>();
+     172           0 :     ASMJIT_PROPAGATE(sb.appendString(x86GetAddressSizeString(m.getSize())));
+     173             : 
+     174             :     // Segment override prefix.
+     175             :     uint32_t seg = m.getSegmentId();
+     176           0 :     if (seg != X86Seg::kIdNone && seg < X86Seg::kIdCount)
+     177           0 :       ASMJIT_PROPAGATE(sb.appendFormat("%s:", x86RegFormatStrings + 224 + seg * 4));
+     178             : 
+     179           0 :     ASMJIT_PROPAGATE(sb.appendChar('['));
+     180           0 :     if (m.isAbs())
+     181           0 :       ASMJIT_PROPAGATE(sb.appendString("abs "));
+     182             : 
+     183           0 :     if (m.hasBase()) {
+     184           0 :       if (m.hasBaseLabel()) {
+     185           0 :         ASMJIT_PROPAGATE(Logging::formatLabel(sb, logOptions, emitter, m.getBaseId()));
+     186             :       }
+     187             :       else {
+     188           0 :         if (m.isArgHome()) ASMJIT_PROPAGATE(sb.appendString("$"));
+     189           0 :         if (m.isRegHome()) ASMJIT_PROPAGATE(sb.appendString("&"));
+     190           0 :         ASMJIT_PROPAGATE(formatRegister(sb, logOptions, emitter, archType, m.getBaseType(), m.getBaseId()));
+     191             :       }
+     192             :     }
+     193             : 
+     194           0 :     if (m.hasIndex()) {
+     195           0 :       ASMJIT_PROPAGATE(sb.appendChar('+'));
+     196           0 :       ASMJIT_PROPAGATE(formatRegister(sb, logOptions, emitter, archType, m.getIndexType(), m.getIndexId()));
+     197           0 :       if (m.hasShift())
+     198           0 :         ASMJIT_PROPAGATE(sb.appendFormat("*%u", 1 << m.getShift()));
+     199             :     }
+     200             : 
+     201           0 :     uint64_t off = static_cast<uint64_t>(m.getOffset());
+     202           0 :     if (off) {
+     203             :       uint32_t base = 10;
+     204             :       char prefix = '+';
+     205             : 
+     206           0 :       if (static_cast<int64_t>(off) < 0) {
+     207           0 :         off = ~off + 1;
+     208             :         prefix = '-';
+     209             :       }
+     210             : 
+     211           0 :       ASMJIT_PROPAGATE(sb.appendChar(prefix));
+     212           0 :       if ((logOptions & Logger::kOptionHexDisplacement) != 0 && off > 9) {
+     213           0 :         ASMJIT_PROPAGATE(sb.appendString("0x", 2));
+     214             :         base = 16;
+     215             :       }
+     216           0 :       ASMJIT_PROPAGATE(sb.appendUInt(off, base));
+     217             :     }
+     218             : 
+     219           0 :     return sb.appendChar(']');
+     220             :   }
+     221             : 
+     222           0 :   if (op.isImm()) {
+     223             :     const Imm& i = op.as<Imm>();
+     224             :     int64_t val = i.getInt64();
+     225             : 
+     226           0 :     if ((logOptions & Logger::kOptionHexImmediate) != 0 && static_cast<uint64_t>(val) > 9)
+     227           0 :       return sb.appendUInt(static_cast<uint64_t>(val), 16);
+     228             :     else
+     229           0 :       return sb.appendInt(val, 10);
+     230             :   }
+     231             : 
+     232           0 :   if (op.isLabel()) {
+     233           0 :     return Logging::formatLabel(sb, logOptions, emitter, op.getId());
+     234             :   }
+     235             : 
+     236           0 :   return sb.appendString("<None>");
+     237             : }
+     238             : 
+     239             : // ============================================================================
+     240             : // [asmjit::X86Logging - Format Immediate (Extension)]
+     241             : // ============================================================================
+     242             : 
+     243             : struct ImmBits {
+     244             :   enum Mode {
+     245             :     kModeLookup = 0x0,
+     246             :     kModeFormat = 0x1
+     247             :   };
+     248             : 
+     249             :   uint8_t mask;
+     250             :   uint8_t shift;
+     251             :   uint8_t mode;
+     252             :   char text[45];
+     253             : };
+     254             : 
+     255           0 : ASMJIT_FAVOR_SIZE static Error X86Logging_formatImmShuf(StringBuilder& sb, uint32_t u8, uint32_t bits, uint32_t count) noexcept {
+     256           0 :   ASMJIT_PROPAGATE(sb.appendChar('<'));
+     257           0 :   uint32_t mask = (1 << bits) - 1;
+     258             : 
+     259           0 :   for (uint32_t i = 0; i < count; i++, u8 >>= bits) {
+     260           0 :     uint32_t value = u8 & mask;
+     261           0 :     if (i != 0)
+     262           0 :       ASMJIT_PROPAGATE(sb.appendChar('|'));
+     263           0 :     ASMJIT_PROPAGATE(sb.appendUInt(value));
+     264             :   }
+     265             : 
+     266           0 :   return sb.appendChar('>');
+     267             : }
+     268             : 
+     269           0 : ASMJIT_FAVOR_SIZE static Error X86Logging_formatImmBits(StringBuilder& sb, uint32_t u8, const ImmBits* bits, uint32_t count) noexcept {
+     270             :   uint32_t n = 0;
+     271             :   char buf[64];
+     272             : 
+     273           0 :   for (uint32_t i = 0; i < count; i++) {
+     274           0 :     const ImmBits& spec = bits[i];
+     275             : 
+     276           0 :     uint32_t value = (u8 & static_cast<uint32_t>(spec.mask)) >> spec.shift;
+     277             :     const char* str = nullptr;
+     278             : 
+     279           0 :     switch (spec.mode) {
+     280           0 :       case ImmBits::kModeLookup:
+     281           0 :         str = Utils::findPackedString(spec.text, value);
+     282             :         break;
+     283             : 
+     284           0 :       case ImmBits::kModeFormat:
+     285           0 :         snprintf(buf, sizeof(buf), spec.text, static_cast<unsigned int>(value));
+     286             :         str = buf;
+     287           0 :         break;
+     288             : 
+     289             :       default:
+     290             :         return DebugUtils::errored(kErrorInvalidState);
+     291             :     }
+     292             : 
+     293           0 :     if (!str[0])
+     294           0 :       continue;
+     295             : 
+     296           0 :     ASMJIT_PROPAGATE(sb.appendChar(++n == 1 ? '<' : '|'));
+     297           0 :     ASMJIT_PROPAGATE(sb.appendString(str));
+     298             :   }
+     299             : 
+     300           0 :   return n ? sb.appendChar('>') : static_cast<Error>(kErrorOk);
+     301             : }
+     302             : 
+     303           0 : ASMJIT_FAVOR_SIZE static Error X86Logging_formatImmText(StringBuilder& sb, uint32_t u8, uint32_t bits, uint32_t advance, const char* text, uint32_t count = 1) noexcept {
+     304           0 :   ASMJIT_PROPAGATE(sb.appendChar('<'));
+     305             : 
+     306           0 :   uint32_t mask = (1 << bits) - 1;
+     307             :   uint32_t pos = 0;
+     308             : 
+     309           0 :   for (uint32_t i = 0; i < count; i++, u8 >>= bits, pos += advance) {
+     310           0 :     uint32_t value = (u8 & mask) + pos;
+     311           0 :     if (i != 0)
+     312           0 :       ASMJIT_PROPAGATE(sb.appendChar('|'));
+     313           0 :     ASMJIT_PROPAGATE(sb.appendString(Utils::findPackedString(text, value)));
+     314             :   }
+     315             : 
+     316           0 :   return sb.appendChar('>');
+     317             : }
+     318             : 
+     319           0 : ASMJIT_FAVOR_SIZE static Error X86Logging_formatImmExtended(
+     320             :   StringBuilder& sb,
+     321             :   uint32_t logOptions,
+     322             :   uint32_t instId,
+     323             :   uint32_t vecSize,
+     324             :   const Imm& imm) noexcept {
+     325             : 
+     326             :   static const char vcmpx[] =
+     327             :     "eq_oq\0" "lt_os\0"  "le_os\0"  "unord_q\0"  "neq_uq\0" "nlt_us\0" "nle_us\0" "ord_q\0"
+     328             :     "eq_uq\0" "nge_us\0" "ngt_us\0" "false_oq\0" "neq_oq\0" "ge_os\0"  "gt_os\0"  "true_uq\0"
+     329             :     "eq_os\0" "lt_oq\0"  "le_oq\0"  "unord_s\0"  "neq_us\0" "nlt_uq\0" "nle_uq\0" "ord_s\0"
+     330             :     "eq_us\0" "nge_uq\0" "ngt_uq\0" "false_os\0" "neq_os\0" "ge_oq\0"  "gt_oq\0"  "true_us\0";
+     331             : 
+     332             :   // Try to find 7 differences...
+     333             :   static const char vpcmpx[] = "eq\0" "lt\0" "le\0" "false\0" "neq\0" "ge\0"  "gt\0"    "true\0";
+     334             :   static const char vpcomx[] = "lt\0" "le\0" "gt\0" "ge\0"    "eq\0"  "neq\0" "false\0" "true\0";
+     335             : 
+     336             :   static const char vshufpd[] = "a0\0a1\0b0\0b1\0a2\0a3\0b2\0b3\0a4\0a5\0b4\0b5\0a6\0a7\0b6\0b7\0";
+     337             :   static const char vshufps[] = "a0\0a1\0a2\0a3\0a0\0a1\0a2\0a3\0b0\0b1\0b2\0b3\0b0\0b1\0b2\0b3\0";
+     338             : 
+     339             :   static const ImmBits vfpclassxx[] = {
+     340             :     { 0x07, 0, ImmBits::kModeLookup, "qnan\0" "+0\0" "-0\0" "+inf\0" "-inf\0" "denormal\0" "-finite\0" "snan\0" }
+     341             :   };
+     342             : 
+     343             :   static const ImmBits vgetmantxx[] = {
+     344             :     { 0x03, 0, ImmBits::kModeLookup, "[1, 2)\0" "[1/2, 2)\0" "1/2, 1)\0" "[3/4, 3/2)\0" },
+     345             :     { 0x04, 2, ImmBits::kModeLookup, "\0" "no-sign\0" },
+     346             :     { 0x08, 3, ImmBits::kModeLookup, "\0" "qnan-if-sign\0" }
+     347             :   };
+     348             : 
+     349             :   static const ImmBits vmpsadbw[] = {
+     350             :     { 0x04, 2, ImmBits::kModeLookup, "blk1[0]\0" "blk1[1]\0" },
+     351             :     { 0x03, 0, ImmBits::kModeLookup, "blk2[0]\0" "blk2[1]\0" "blk2[2]\0" "blk2[3]\0" },
+     352             :     { 0x40, 6, ImmBits::kModeLookup, "blk1[4]\0" "blk1[5]\0" },
+     353             :     { 0x30, 4, ImmBits::kModeLookup, "blk2[4]\0" "blk2[5]\0" "blk2[6]\0" "blk2[7]\0" }
+     354             :   };
+     355             : 
+     356             :   static const ImmBits vpclmulqdq[] = {
+     357             :     { 0x01, 0, ImmBits::kModeLookup, "lq\0" "hq\0" },
+     358             :     { 0x10, 4, ImmBits::kModeLookup, "lq\0" "hq\0" }
+     359             :   };
+     360             : 
+     361             :   static const ImmBits vperm2x128[] = {
+     362             :     { 0x0B, 0, ImmBits::kModeLookup, "a0\0" "a1\0" "b0\0" "b1\0" "\0" "\0" "\0" "\0" "0\0" "0\0" "0\0" "0\0" },
+     363             :     { 0xB0, 4, ImmBits::kModeLookup, "a0\0" "a1\0" "b0\0" "b1\0" "\0" "\0" "\0" "\0" "0\0" "0\0" "0\0" "0\0" }
+     364             :   };
+     365             : 
+     366             :   static const ImmBits vrangexx[] = {
+     367             :     { 0x03, 0, ImmBits::kModeLookup, "min\0" "max\0" "min-abs\0" "max-abs\0" },
+     368             :     { 0x0C, 2, ImmBits::kModeLookup, "sign=src1\0" "sign=src2\0" "sign=0\0" "sign=1\0" }
+     369             :   };
+     370             : 
+     371             :   static const ImmBits vreducexx_vrndscalexx[] = {
+     372             :     { 0x07, 0, ImmBits::kModeLookup, "\0" "\0" "\0" "\0" "round\0" "floor\0" "ceil\0" "truncate\0" },
+     373             :     { 0x08, 3, ImmBits::kModeLookup, "\0" "suppress\0" },
+     374             :     { 0xF0, 4, ImmBits::kModeFormat, "len=%d" }
+     375             :   };
+     376             : 
+     377             :   static const ImmBits vroundxx[] = {
+     378             :     { 0x07, 0, ImmBits::kModeLookup, "round\0" "floor\0" "ceil\0" "truncate\0" "\0" "\0" "\0" "\0" },
+     379             :     { 0x08, 3, ImmBits::kModeLookup, "\0" "inexact\0" }
+     380             :   };
+     381             : 
+     382             :   uint32_t u8 = imm.getUInt8();
+     383           0 :   switch (instId) {
+     384           0 :     case X86Inst::kIdVblendpd:
+     385             :     case X86Inst::kIdBlendpd:
+     386           0 :       return X86Logging_formatImmShuf(sb, u8, 1, vecSize / 8);
+     387             : 
+     388           0 :     case X86Inst::kIdVblendps:
+     389             :     case X86Inst::kIdBlendps:
+     390           0 :       return X86Logging_formatImmShuf(sb, u8, 1, vecSize / 4);
+     391             : 
+     392           0 :     case X86Inst::kIdVcmppd:
+     393             :     case X86Inst::kIdVcmpps:
+     394             :     case X86Inst::kIdVcmpsd:
+     395             :     case X86Inst::kIdVcmpss:
+     396           0 :       return X86Logging_formatImmText(sb, u8, 5, 0, vcmpx);
+     397             : 
+     398           0 :     case X86Inst::kIdCmppd:
+     399             :     case X86Inst::kIdCmpps:
+     400             :     case X86Inst::kIdCmpsd:
+     401             :     case X86Inst::kIdCmpss:
+     402           0 :       return X86Logging_formatImmText(sb, u8, 3, 0, vcmpx);
+     403             : 
+     404           0 :     case X86Inst::kIdVdbpsadbw:
+     405           0 :       return X86Logging_formatImmShuf(sb, u8, 2, 4);
+     406             : 
+     407           0 :     case X86Inst::kIdVdppd:
+     408             :     case X86Inst::kIdVdpps:
+     409             :     case X86Inst::kIdDppd:
+     410             :     case X86Inst::kIdDpps:
+     411           0 :       return X86Logging_formatImmShuf(sb, u8, 1, 8);
+     412             : 
+     413           0 :     case X86Inst::kIdVmpsadbw:
+     414             :     case X86Inst::kIdMpsadbw:
+     415           0 :       return X86Logging_formatImmBits(sb, u8, vmpsadbw, std::min<uint32_t>(vecSize / 8, 4));
+     416             : 
+     417           0 :     case X86Inst::kIdVpblendw:
+     418             :     case X86Inst::kIdPblendw:
+     419           0 :       return X86Logging_formatImmShuf(sb, u8, 1, 8);
+     420             : 
+     421           0 :     case X86Inst::kIdVpblendd:
+     422           0 :       return X86Logging_formatImmShuf(sb, u8, 1, std::min<uint32_t>(vecSize / 4, 8));
+     423             : 
+     424           0 :     case X86Inst::kIdVpclmulqdq:
+     425             :     case X86Inst::kIdPclmulqdq:
+     426           0 :       return X86Logging_formatImmBits(sb, u8, vpclmulqdq, ASMJIT_ARRAY_SIZE(vpclmulqdq));
+     427             : 
+     428           0 :     case X86Inst::kIdVroundpd:
+     429             :     case X86Inst::kIdVroundps:
+     430             :     case X86Inst::kIdVroundsd:
+     431             :     case X86Inst::kIdVroundss:
+     432             :     case X86Inst::kIdRoundpd:
+     433             :     case X86Inst::kIdRoundps:
+     434             :     case X86Inst::kIdRoundsd:
+     435             :     case X86Inst::kIdRoundss:
+     436           0 :       return X86Logging_formatImmBits(sb, u8, vroundxx, ASMJIT_ARRAY_SIZE(vroundxx));
+     437             : 
+     438           0 :     case X86Inst::kIdVshufpd:
+     439             :     case X86Inst::kIdShufpd:
+     440           0 :       return X86Logging_formatImmText(sb, u8, 1, 2, vshufpd, std::min<uint32_t>(vecSize / 8, 8));
+     441             : 
+     442           0 :     case X86Inst::kIdVshufps:
+     443             :     case X86Inst::kIdShufps:
+     444           0 :       return X86Logging_formatImmText(sb, u8, 2, 4, vshufps, 4);
+     445             : 
+     446           0 :     case X86Inst::kIdVcvtps2ph:
+     447           0 :       return X86Logging_formatImmBits(sb, u8, vroundxx, 1);
+     448             : 
+     449           0 :     case X86Inst::kIdVperm2f128:
+     450             :     case X86Inst::kIdVperm2i128:
+     451           0 :       return X86Logging_formatImmBits(sb, u8, vperm2x128, ASMJIT_ARRAY_SIZE(vperm2x128));
+     452             : 
+     453           0 :     case X86Inst::kIdVpermilpd:
+     454           0 :       return X86Logging_formatImmShuf(sb, u8, 1, vecSize / 8);
+     455             : 
+     456           0 :     case X86Inst::kIdVpermilps:
+     457           0 :       return X86Logging_formatImmShuf(sb, u8, 2, 4);
+     458             : 
+     459           0 :     case X86Inst::kIdVpshufd:
+     460             :     case X86Inst::kIdPshufd:
+     461           0 :       return X86Logging_formatImmShuf(sb, u8, 2, 4);
+     462             : 
+     463           0 :     case X86Inst::kIdVpshufhw:
+     464             :     case X86Inst::kIdVpshuflw:
+     465             :     case X86Inst::kIdPshufhw:
+     466             :     case X86Inst::kIdPshuflw:
+     467             :     case X86Inst::kIdPshufw:
+     468           0 :       return X86Logging_formatImmShuf(sb, u8, 2, 4);
+     469             : 
+     470             :     // TODO: Maybe?
+     471             :     case X86Inst::kIdVfixupimmpd:
+     472             :     case X86Inst::kIdVfixupimmps:
+     473             :     case X86Inst::kIdVfixupimmsd:
+     474             :     case X86Inst::kIdVfixupimmss:
+     475             :       return kErrorOk;
+     476             : 
+     477           0 :     case X86Inst::kIdVfpclasspd:
+     478             :     case X86Inst::kIdVfpclassps:
+     479             :     case X86Inst::kIdVfpclasssd:
+     480             :     case X86Inst::kIdVfpclassss:
+     481           0 :       return X86Logging_formatImmBits(sb, u8, vfpclassxx, ASMJIT_ARRAY_SIZE(vfpclassxx));
+     482             : 
+     483           0 :     case X86Inst::kIdVgetmantpd:
+     484             :     case X86Inst::kIdVgetmantps:
+     485             :     case X86Inst::kIdVgetmantsd:
+     486             :     case X86Inst::kIdVgetmantss:
+     487           0 :       return X86Logging_formatImmBits(sb, u8, vgetmantxx, ASMJIT_ARRAY_SIZE(vgetmantxx));
+     488             : 
+     489           0 :     case X86Inst::kIdVpcmpb:
+     490             :     case X86Inst::kIdVpcmpd:
+     491             :     case X86Inst::kIdVpcmpq:
+     492             :     case X86Inst::kIdVpcmpw:
+     493             :     case X86Inst::kIdVpcmpub:
+     494             :     case X86Inst::kIdVpcmpud:
+     495             :     case X86Inst::kIdVpcmpuq:
+     496             :     case X86Inst::kIdVpcmpuw:
+     497           0 :       return X86Logging_formatImmText(sb, u8, 2, 4, vpcmpx, 4);
+     498             : 
+     499           0 :     case X86Inst::kIdVpcomb:
+     500             :     case X86Inst::kIdVpcomd:
+     501             :     case X86Inst::kIdVpcomq:
+     502             :     case X86Inst::kIdVpcomw:
+     503             :     case X86Inst::kIdVpcomub:
+     504             :     case X86Inst::kIdVpcomud:
+     505             :     case X86Inst::kIdVpcomuq:
+     506             :     case X86Inst::kIdVpcomuw:
+     507           0 :       return X86Logging_formatImmText(sb, u8, 2, 4, vpcomx, 4);
+     508             : 
+     509           0 :     case X86Inst::kIdVpermq:
+     510             :     case X86Inst::kIdVpermpd:
+     511           0 :       return X86Logging_formatImmShuf(sb, u8, 2, 4);
+     512             : 
+     513           0 :     case X86Inst::kIdVpternlogd:
+     514             :     case X86Inst::kIdVpternlogq:
+     515           0 :       return X86Logging_formatImmShuf(sb, u8, 1, 8);
+     516             : 
+     517           0 :     case X86Inst::kIdVrangepd:
+     518             :     case X86Inst::kIdVrangeps:
+     519             :     case X86Inst::kIdVrangesd:
+     520             :     case X86Inst::kIdVrangess:
+     521           0 :       return X86Logging_formatImmBits(sb, u8, vrangexx, ASMJIT_ARRAY_SIZE(vrangexx));
+     522             : 
+     523           0 :     case X86Inst::kIdVreducepd:
+     524             :     case X86Inst::kIdVreduceps:
+     525             :     case X86Inst::kIdVreducesd:
+     526             :     case X86Inst::kIdVreducess:
+     527             :     case X86Inst::kIdVrndscalepd:
+     528             :     case X86Inst::kIdVrndscaleps:
+     529             :     case X86Inst::kIdVrndscalesd:
+     530             :     case X86Inst::kIdVrndscaless:
+     531           0 :       return X86Logging_formatImmBits(sb, u8, vreducexx_vrndscalexx, ASMJIT_ARRAY_SIZE(vreducexx_vrndscalexx));
+     532             : 
+     533           0 :     case X86Inst::kIdVshuff32x4:
+     534             :     case X86Inst::kIdVshuff64x2:
+     535             :     case X86Inst::kIdVshufi32x4:
+     536             :     case X86Inst::kIdVshufi64x2: {
+     537           0 :       uint32_t count = std::max<uint32_t>(vecSize / 16, 2);
+     538           0 :       uint32_t bits = count <= 2 ? 1 : 2;
+     539           0 :       return X86Logging_formatImmShuf(sb, u8, bits, count);
+     540             :     }
+     541             : 
+     542             :     default:
+     543             :       return kErrorOk;
+     544             :   }
+     545             : }
+     546             : 
+     547             : // ============================================================================
+     548             : // [asmjit::X86Logging - Format Register]
+     549             : // ============================================================================
+     550             : 
+     551           0 : ASMJIT_FAVOR_SIZE Error X86Logging::formatRegister(
+     552             :   StringBuilder& sb,
+     553             :   uint32_t logOptions,
+     554             :   const CodeEmitter* emitter,
+     555             :   uint32_t archType,
+     556             :   uint32_t rType,
+     557             :   uint32_t rId) noexcept {
+     558             : 
+     559             :   ASMJIT_UNUSED(logOptions);
+     560             :   ASMJIT_UNUSED(archType);
+     561             : 
+     562           0 :   if (Operand::isPackedId(rId)) {
+     563             : #if !defined(ASMJIT_DISABLE_COMPILER)
+     564           0 :     if (emitter && emitter->getType() == CodeEmitter::kTypeCompiler) {
+     565             :       const CodeCompiler* cc = static_cast<const CodeCompiler*>(emitter);
+     566             : 
+     567           0 :       if (cc->isVirtRegValid(rId)) {
+     568             :         VirtReg* vReg = cc->getVirtRegById(rId);
+     569             :         ASMJIT_ASSERT(vReg != nullptr);
+     570             : 
+     571             :         const char* name = vReg->getName();
+     572           0 :         if (name && name[0] != '\0')
+     573           0 :           return sb.appendString(name);
+     574             :         else
+     575           0 :           return sb.appendFormat("v%u", static_cast<unsigned int>(Operand::unpackId(rId)));
+     576             :       }
+     577             :     }
+     578             : #endif // !ASMJIT_DISABLE_COMPILER
+     579             : 
+     580           0 :     return sb.appendFormat("VirtReg<Type=%u Id=%u>", rType, rId);
+     581             :   }
+     582             :   else {
+     583           0 :     if (rType < ASMJIT_ARRAY_SIZE(x86RegFormatInfo)) {
+     584             :       const X86RegFormatInfo& rfi = x86RegFormatInfo[rType];
+     585             : 
+     586           0 :       if (rId < rfi.specialCount)
+     587           0 :         return sb.appendString(x86RegFormatStrings + rfi.specialIndex + rId * 4);
+     588             : 
+     589           0 :       if (rId < rfi.count)
+     590           0 :         return sb.appendFormat(x86RegFormatStrings + rfi.formatIndex, static_cast<unsigned int>(rId));
+     591             :     }
+     592             : 
+     593           0 :     return sb.appendFormat("PhysReg<Type=%u Id=%u>", rType, rId);
+     594             :   }
+     595             : }
+     596             : 
+     597             : // ============================================================================
+     598             : // [asmjit::X86Logging - Format Instruction]
+     599             : // ============================================================================
+     600             : 
+     601           0 : ASMJIT_FAVOR_SIZE Error X86Logging::formatInstruction(
+     602             :   StringBuilder& sb,
+     603             :   uint32_t logOptions,
+     604             :   const CodeEmitter* emitter,
+     605             :   uint32_t archType,
+     606             :   const Inst::Detail& detail, const Operand_* opArray, uint32_t opCount) noexcept {
+     607             : 
+     608           0 :   uint32_t instId = detail.instId;
+     609           0 :   uint32_t options = detail.options;
+     610             : 
+     611             :   // Format instruction options and instruction mnemonic.
+     612           0 :   if (instId < X86Inst::_kIdCount) {
+     613             :     const X86Inst& instInfo = X86Inst::getInst(instId);
+     614             : 
+     615             :     // SHORT|LONG options.
+     616           0 :     if (options & X86Inst::kOptionShortForm) ASMJIT_PROPAGATE(sb.appendString("short "));
+     617           0 :     if (options & X86Inst::kOptionLongForm) ASMJIT_PROPAGATE(sb.appendString("long "));
+     618             : 
+     619             :     // LOCK|XACQUIRE|XRELEASE options.
+     620           0 :     if (options & X86Inst::kOptionXAcquire) ASMJIT_PROPAGATE(sb.appendString("xacquire "));
+     621           0 :     if (options & X86Inst::kOptionXRelease) ASMJIT_PROPAGATE(sb.appendString("xrelease "));
+     622           0 :     if (options & X86Inst::kOptionLock) ASMJIT_PROPAGATE(sb.appendString("lock "));
+     623             : 
+     624             :     // REP|REPNZ options.
+     625           0 :     if (options & (X86Inst::kOptionRep | X86Inst::kOptionRepnz)) {
+     626           0 :       sb.appendString((options & X86Inst::kOptionRep) ? "rep " : "repnz ");
+     627           0 :       if (detail.hasExtraReg()) {
+     628           0 :         ASMJIT_PROPAGATE(sb.appendChar('{'));
+     629           0 :         ASMJIT_PROPAGATE(formatOperand(sb, logOptions, emitter, archType, detail.extraReg.toReg<Reg>()));
+     630           0 :         ASMJIT_PROPAGATE(sb.appendString("} "));
+     631             :       }
+     632             :     }
+     633             : 
+     634             :     // REX options.
+     635           0 :     if (options & X86Inst::kOptionRex) {
+     636             :       const uint32_t kRXBWMask = X86Inst::kOptionOpCodeR |
+     637             :                                  X86Inst::kOptionOpCodeX |
+     638             :                                  X86Inst::kOptionOpCodeB |
+     639             :                                  X86Inst::kOptionOpCodeW ;
+     640           0 :       if (options & kRXBWMask) {
+     641             :         sb.appendString("rex.");
+     642           0 :         if (options & X86Inst::kOptionOpCodeR) sb.appendChar('r');
+     643           0 :         if (options & X86Inst::kOptionOpCodeX) sb.appendChar('x');
+     644           0 :         if (options & X86Inst::kOptionOpCodeB) sb.appendChar('b');
+     645           0 :         if (options & X86Inst::kOptionOpCodeW) sb.appendChar('w');
+     646             :         sb.appendChar(' ');
+     647             :       }
+     648             :       else {
+     649           0 :         ASMJIT_PROPAGATE(sb.appendString("rex "));
+     650             :       }
+     651             :     }
+     652             : 
+     653             :     // VEX|EVEX options.
+     654           0 :     if (options & X86Inst::kOptionVex3) ASMJIT_PROPAGATE(sb.appendString("vex3 "));
+     655           0 :     if (options & X86Inst::kOptionEvex) ASMJIT_PROPAGATE(sb.appendString("evex "));
+     656             : 
+     657           0 :     ASMJIT_PROPAGATE(sb.appendString(instInfo.getName()));
+     658             :   }
+     659             :   else {
+     660           0 :     ASMJIT_PROPAGATE(sb.appendFormat("<unknown id=#%u>", static_cast<unsigned int>(instId)));
+     661             :   }
+     662             : 
+     663           0 :   for (uint32_t i = 0; i < opCount; i++) {
+     664           0 :     const Operand_& op = opArray[i];
+     665           0 :     if (op.isNone()) break;
+     666             : 
+     667           0 :     ASMJIT_PROPAGATE(sb.appendString(i == 0 ? " " : ", "));
+     668           0 :     ASMJIT_PROPAGATE(formatOperand(sb, logOptions, emitter, archType, op));
+     669             : 
+     670           0 :     if (op.isImm() && (logOptions & Logger::kOptionImmExtended)) {
+     671           0 :       uint32_t vecSize = 16;
+     672           0 :       for (uint32_t j = 0; j < opCount; j++)
+     673           0 :         if (opArray[j].isReg())
+     674           0 :           vecSize = std::max<uint32_t>(vecSize, opArray[j].getSize());
+     675           0 :       ASMJIT_PROPAGATE(X86Logging_formatImmExtended(sb, logOptions, instId, vecSize, op.as<Imm>()));
+     676             :     }
+     677             : 
+     678             :     // Support AVX-512 {k}{z}.
+     679           0 :     if (i == 0) {
+     680           0 :       if (detail.extraReg.getKind() == X86Reg::kKindK) {
+     681           0 :         ASMJIT_PROPAGATE(sb.appendString(" {"));
+     682           0 :         ASMJIT_PROPAGATE(formatOperand(sb, logOptions, emitter, archType, detail.extraReg.toReg<Reg>()));
+     683           0 :         ASMJIT_PROPAGATE(sb.appendChar('}'));
+     684             : 
+     685           0 :         if (options & X86Inst::kOptionZMask)
+     686           0 :           ASMJIT_PROPAGATE(sb.appendString("{z}"));
+     687             :       }
+     688           0 :       else if (options & X86Inst::kOptionZMask) {
+     689           0 :         ASMJIT_PROPAGATE(sb.appendString(" {z}"));
+     690             :       }
+     691             :     }
+     692             : 
+     693             :     // Support AVX-512 {1tox}.
+     694           0 :     if (op.isMem() && (options & X86Inst::kOption1ToX))
+     695           0 :       ASMJIT_PROPAGATE(sb.appendString(" {1tox}"));
+     696             :   }
+     697             : 
+     698             :   return kErrorOk;
+     699             : }
+     700             : 
+     701             : } // asmjit namespace
+     702             : } // namespace PLMD
+     703             : 
+     704             : // [Api-End]
+     705             : #include "./asmjit_apiend.h"
+     706             : 
+     707             : // [Guard]
+     708             : #endif // !ASMJIT_DISABLE_LOGGING
+     709             : #pragma GCC diagnostic pop
+     710             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86misc.h.func-sort-c.html b/coverage-libs/asmjit/x86misc.h.func-sort-c.html new file mode 100644 index 000000000000..792322af4ebd --- /dev/null +++ b/coverage-libs/asmjit/x86misc.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86misc.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86misc.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:223759.5 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86misc.h.func.html b/coverage-libs/asmjit/x86misc.h.func.html new file mode 100644 index 000000000000..a72ee2fc7df7 --- /dev/null +++ b/coverage-libs/asmjit/x86misc.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86misc.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86misc.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:223759.5 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86misc.h.gcov.html b/coverage-libs/asmjit/x86misc.h.gcov.html new file mode 100644 index 000000000000..ca8632c9517d --- /dev/null +++ b/coverage-libs/asmjit/x86misc.h.gcov.html @@ -0,0 +1,494 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86misc.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86misc.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:223759.5 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_x86misc_h
+      21             : #define __PLUMED_asmjit_x86misc_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_X86_X86MISC_H
+      33             : #define _ASMJIT_X86_X86MISC_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./x86operand.h"
+      37             : 
+      38             : // [Api-Begin]
+      39             : #include "./asmjit_apibegin.h"
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace asmjit {
+      43             : 
+      44             : //! \addtogroup asmjit_x86
+      45             : //! \{
+      46             : 
+      47             : // ============================================================================
+      48             : // [asmjit::X86RegCount]
+      49             : // ============================================================================
+      50             : 
+      51             : //! \internal
+      52             : //!
+      53             : //! X86/X64 registers count.
+      54             : //!
+      55             : //! Since the number of registers changed across CPU generations `X86RegCount`
+      56             : //! class is used by `X86Assembler` and `X86Compiler` to provide a way to get
+      57             : //! number of available registers dynamically. 32-bit mode offers always only
+      58             : //! 8 registers of all classes, however, 64-bit mode offers 16 GP registers and
+      59             : //! 16 XMM/YMM/ZMM registers. AVX512 instruction set doubles the number of SIMD
+      60             : //! registers (XMM/YMM/ZMM) to 32, this mode has to be explicitly enabled to
+      61             : //! take effect as it changes some assumptions.
+      62             : //!
+      63             : //! `X86RegCount` is also used extensively by X86Compiler's register allocator
+      64             : //! and data structures. FP registers were omitted as they are never mapped to
+      65             : //! variables, thus, not needed to be managed.
+      66             : //!
+      67             : //! NOTE: At the moment `X86RegCount` can fit into 32-bits, having 8-bits for
+      68             : //! each register kind except FP. This can change in the future after a new
+      69             : //! instruction set, which adds more registers, is introduced.
+      70             : struct X86RegCount {
+      71             :   // --------------------------------------------------------------------------
+      72             :   // [Zero]
+      73             :   // --------------------------------------------------------------------------
+      74             : 
+      75             :   //! Reset all counters to zero.
+      76      114002 :   ASMJIT_INLINE void reset() noexcept { _packed = 0; }
+      77             : 
+      78             :   // --------------------------------------------------------------------------
+      79             :   // [Get]
+      80             :   // --------------------------------------------------------------------------
+      81             : 
+      82             :   //! Get register count by a register `kind`.
+      83             :   ASMJIT_INLINE uint32_t get(uint32_t kind) const noexcept {
+      84             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+      85             : 
+      86             :     uint32_t shift = Utils::byteShiftOfDWordStruct(kind);
+      87      574028 :     return (_packed >> shift) & static_cast<uint32_t>(0xFF);
+      88             :   }
+      89             : 
+      90             :   //! Get Gp count.
+      91             :   ASMJIT_INLINE uint32_t getGp() const noexcept { return get(X86Reg::kKindGp); }
+      92             :   //! Get Mm count.
+      93             :   ASMJIT_INLINE uint32_t getMm() const noexcept { return get(X86Reg::kKindMm); }
+      94             :   //! Get K count.
+      95             :   ASMJIT_INLINE uint32_t getK() const noexcept { return get(X86Reg::kKindK); }
+      96             :   //! Get XMM/YMM/ZMM count.
+      97             :   ASMJIT_INLINE uint32_t getVec() const noexcept { return get(X86Reg::kKindVec); }
+      98             : 
+      99             :   // --------------------------------------------------------------------------
+     100             :   // [Set]
+     101             :   // --------------------------------------------------------------------------
+     102             : 
+     103             :   //! Set register count by a register `kind`.
+     104             :   ASMJIT_INLINE void set(uint32_t kind, uint32_t n) noexcept {
+     105             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     106             :     ASMJIT_ASSERT(n <= 0xFF);
+     107             : 
+     108             :     uint32_t shift = Utils::byteShiftOfDWordStruct(kind);
+     109           0 :     _packed = (_packed & ~static_cast<uint32_t>(0xFF << shift)) + (n << shift);
+     110           0 :   }
+     111             : 
+     112             :   //! Set Gp count.
+     113             :   ASMJIT_INLINE void setGp(uint32_t n) noexcept { set(X86Reg::kKindGp, n); }
+     114             :   //! Set Mm count.
+     115             :   ASMJIT_INLINE void setMm(uint32_t n) noexcept { set(X86Reg::kKindMm, n); }
+     116             :   //! Set K count.
+     117             :   ASMJIT_INLINE void setK(uint32_t n) noexcept { set(X86Reg::kKindK, n); }
+     118             :   //! Set XMM/YMM/ZMM count.
+     119             :   ASMJIT_INLINE void setVec(uint32_t n) noexcept { set(X86Reg::kKindVec, n); }
+     120             : 
+     121             :   // --------------------------------------------------------------------------
+     122             :   // [Add]
+     123             :   // --------------------------------------------------------------------------
+     124             : 
+     125             :   //! Add register count by a register `kind`.
+     126             :   ASMJIT_INLINE void add(uint32_t kind, uint32_t n = 1) noexcept {
+     127             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     128             :     ASMJIT_ASSERT(0xFF - static_cast<uint32_t>(_regs[kind]) >= n);
+     129             : 
+     130             :     uint32_t shift = Utils::byteShiftOfDWordStruct(kind);
+     131      122988 :     _packed += n << shift;
+     132       61494 :   }
+     133             : 
+     134             :   //! Add GP count.
+     135             :   ASMJIT_INLINE void addGp(uint32_t n) noexcept { add(X86Reg::kKindGp, n); }
+     136             :   //! Add MMX count.
+     137             :   ASMJIT_INLINE void addMm(uint32_t n) noexcept { add(X86Reg::kKindMm, n); }
+     138             :   //! Add K count.
+     139             :   ASMJIT_INLINE void addK(uint32_t n) noexcept { add(X86Reg::kKindK, n); }
+     140             :   //! Add XMM/YMM/ZMM count.
+     141             :   ASMJIT_INLINE void addVec(uint32_t n) noexcept { add(X86Reg::kKindVec, n); }
+     142             : 
+     143             :   // --------------------------------------------------------------------------
+     144             :   // [Misc]
+     145             :   // --------------------------------------------------------------------------
+     146             : 
+     147             :   //! Build register indexes based on the given `count` of registers.
+     148             :   ASMJIT_INLINE void indexFromRegCount(const X86RegCount& count) noexcept {
+     149       36702 :     uint32_t x = static_cast<uint32_t>(count._regs[0]);
+     150       36702 :     uint32_t y = static_cast<uint32_t>(count._regs[1]) + x;
+     151       36702 :     uint32_t z = static_cast<uint32_t>(count._regs[2]) + y;
+     152             : 
+     153             :     ASMJIT_ASSERT(y <= 0xFF);
+     154             :     ASMJIT_ASSERT(z <= 0xFF);
+     155             :     _packed = Utils::pack32_4x8(0, x, y, z);
+     156             :   }
+     157             : 
+     158             :   // --------------------------------------------------------------------------
+     159             :   // [Members]
+     160             :   // --------------------------------------------------------------------------
+     161             : 
+     162             :   union {
+     163             :     struct {
+     164             :       //! Count of GP registers.
+     165             :       uint8_t _gp;
+     166             :       //! Count of XMM|YMM|ZMM registers.
+     167             :       uint8_t _vec;
+     168             :       //! Count of MMX registers.
+     169             :       uint8_t _mm;
+     170             :       //! Count of K registers.
+     171             :       uint8_t _k;
+     172             :     };
+     173             : 
+     174             :     uint8_t _regs[4];
+     175             :     uint32_t _packed;
+     176             :   };
+     177             : };
+     178             : 
+     179             : // ============================================================================
+     180             : // [asmjit::X86RegMask]
+     181             : // ============================================================================
+     182             : 
+     183             : //! \internal
+     184             : //!
+     185             : //! X86/X64 registers mask.
+     186             : struct X86RegMask {
+     187             :   // --------------------------------------------------------------------------
+     188             :   // [Reset]
+     189             :   // --------------------------------------------------------------------------
+     190             : 
+     191             :   //! Reset all register masks to zero.
+     192             :   ASMJIT_INLINE void reset() noexcept {
+     193             :     _packed.reset();
+     194             :   }
+     195             : 
+     196             :   // --------------------------------------------------------------------------
+     197             :   // [IsEmpty / Has]
+     198             :   // --------------------------------------------------------------------------
+     199             : 
+     200             :   //! Get whether all register masks are zero (empty).
+     201             :   ASMJIT_INLINE bool isEmpty() const noexcept {
+     202             :     return _packed.isZero();
+     203             :   }
+     204             : 
+     205             :   ASMJIT_INLINE bool has(uint32_t kind, uint32_t mask = 0xFFFFFFFFU) const noexcept {
+     206             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     207             : 
+     208           0 :     switch (kind) {
+     209           0 :       case X86Reg::kKindGp : return (static_cast<uint32_t>(_gp ) & mask) != 0;
+     210           0 :       case X86Reg::kKindVec: return (static_cast<uint32_t>(_vec) & mask) != 0;
+     211           0 :       case X86Reg::kKindMm : return (static_cast<uint32_t>(_mm ) & mask) != 0;
+     212           0 :       case X86Reg::kKindK  : return (static_cast<uint32_t>(_k  ) & mask) != 0;
+     213             :     }
+     214             : 
+     215             :     return false;
+     216             :   }
+     217             : 
+     218             :   ASMJIT_INLINE bool hasGp(uint32_t mask = 0xFFFFFFFFU) const noexcept { return has(X86Reg::kKindGp, mask); }
+     219             :   ASMJIT_INLINE bool hasVec(uint32_t mask = 0xFFFFFFFFU) const noexcept { return has(X86Reg::kKindVec, mask); }
+     220             :   ASMJIT_INLINE bool hasMm(uint32_t mask = 0xFFFFFFFFU) const noexcept { return has(X86Reg::kKindMm, mask); }
+     221             :   ASMJIT_INLINE bool hasK(uint32_t mask = 0xFFFFFFFFU) const noexcept { return has(X86Reg::kKindK, mask); }
+     222             : 
+     223             :   // --------------------------------------------------------------------------
+     224             :   // [Get]
+     225             :   // --------------------------------------------------------------------------
+     226             : 
+     227             :   ASMJIT_INLINE uint32_t get(uint32_t kind) const noexcept {
+     228             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     229             : 
+     230       54800 :     switch (kind) {
+     231       95866 :       case X86Reg::kKindGp : return _gp;
+     232      215126 :       case X86Reg::kKindVec: return _vec;
+     233       41346 :       case X86Reg::kKindMm : return _mm;
+     234           0 :       case X86Reg::kKindK  : return _k;
+     235             :     }
+     236             : 
+     237             :     return 0;
+     238             :   }
+     239             : 
+     240             :   ASMJIT_INLINE uint32_t getGp() const noexcept { return get(X86Reg::kKindGp); }
+     241             :   ASMJIT_INLINE uint32_t getVec() const noexcept { return get(X86Reg::kKindVec); }
+     242             :   ASMJIT_INLINE uint32_t getMm() const noexcept { return get(X86Reg::kKindMm); }
+     243             :   ASMJIT_INLINE uint32_t getK() const noexcept { return get(X86Reg::kKindK); }
+     244             : 
+     245             :   // --------------------------------------------------------------------------
+     246             :   // [Zero]
+     247             :   // --------------------------------------------------------------------------
+     248             : 
+     249             :   ASMJIT_INLINE void zero(uint32_t kind) noexcept {
+     250             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     251             : 
+     252             :     switch (kind) {
+     253             :       case X86Reg::kKindGp : _gp  = 0; break;
+     254             :       case X86Reg::kKindVec: _vec = 0; break;
+     255             :       case X86Reg::kKindMm : _mm  = 0; break;
+     256             :       case X86Reg::kKindK  : _k   = 0; break;
+     257             :     }
+     258             :   }
+     259             : 
+     260             :   ASMJIT_INLINE void zeroGp() noexcept { zero(X86Reg::kKindGp); }
+     261             :   ASMJIT_INLINE void zeroVec() noexcept { zero(X86Reg::kKindVec); }
+     262             :   ASMJIT_INLINE void zeroMm() noexcept { zero(X86Reg::kKindMm); }
+     263             :   ASMJIT_INLINE void zeroK() noexcept { zero(X86Reg::kKindK); }
+     264             : 
+     265             :   // --------------------------------------------------------------------------
+     266             :   // [Set]
+     267             :   // --------------------------------------------------------------------------
+     268             : 
+     269             :   ASMJIT_INLINE void set(const X86RegMask& other) noexcept {
+     270             :     _packed = other._packed;
+     271             :   }
+     272             : 
+     273             :   ASMJIT_INLINE void set(uint32_t kind, uint32_t mask) noexcept {
+     274             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     275             : 
+     276             :     switch (kind) {
+     277       16664 :       case X86Reg::kKindGp : _gp  = static_cast<uint16_t>(mask); break;
+     278        3296 :       case X86Reg::kKindMm : _mm  = static_cast<uint8_t >(mask); break;
+     279        1648 :       case X86Reg::kKindK  : _k   = static_cast<uint8_t >(mask); break;
+     280       30782 :       case X86Reg::kKindVec: _vec = static_cast<uint32_t>(mask); break;
+     281             :     }
+     282             :   }
+     283             : 
+     284             :   ASMJIT_INLINE void setGp(uint32_t mask) noexcept { return set(X86Reg::kKindGp, mask); }
+     285             :   ASMJIT_INLINE void setVec(uint32_t mask) noexcept { return set(X86Reg::kKindVec, mask); }
+     286             :   ASMJIT_INLINE void setMm(uint32_t mask) noexcept { return set(X86Reg::kKindMm, mask); }
+     287             :   ASMJIT_INLINE void setK(uint32_t mask) noexcept { return set(X86Reg::kKindK, mask); }
+     288             : 
+     289             :   // --------------------------------------------------------------------------
+     290             :   // [And]
+     291             :   // --------------------------------------------------------------------------
+     292             : 
+     293             :   ASMJIT_INLINE void and_(const X86RegMask& other) noexcept {
+     294             :     _packed.and_(other._packed);
+     295             :   }
+     296             : 
+     297             :   ASMJIT_INLINE void and_(uint32_t kind, uint32_t mask) noexcept {
+     298             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     299             : 
+     300             :     switch (kind) {
+     301             :       case X86Reg::kKindGp : _gp  &= static_cast<uint16_t>(mask); break;
+     302             :       case X86Reg::kKindMm : _mm  &= static_cast<uint8_t >(mask); break;
+     303             :       case X86Reg::kKindK  : _k   &= static_cast<uint8_t >(mask); break;
+     304             :       case X86Reg::kKindVec: _vec &= static_cast<uint32_t>(mask); break;
+     305             :     }
+     306             :   }
+     307             : 
+     308             :   ASMJIT_INLINE void andGp(uint32_t mask) noexcept { and_(X86Reg::kKindGp, mask); }
+     309             :   ASMJIT_INLINE void andVec(uint32_t mask) noexcept { and_(X86Reg::kKindVec, mask); }
+     310             :   ASMJIT_INLINE void andMm(uint32_t mask) noexcept { and_(X86Reg::kKindMm, mask); }
+     311             :   ASMJIT_INLINE void andK(uint32_t mask) noexcept { and_(X86Reg::kKindK, mask); }
+     312             : 
+     313             :   // --------------------------------------------------------------------------
+     314             :   // [AndNot]
+     315             :   // --------------------------------------------------------------------------
+     316             : 
+     317             :   ASMJIT_INLINE void andNot(const X86RegMask& other) noexcept {
+     318             :     _packed.andNot(other._packed);
+     319             :   }
+     320             : 
+     321             :   ASMJIT_INLINE void andNot(uint32_t kind, uint32_t mask) noexcept {
+     322             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     323             : 
+     324             :     switch (kind) {
+     325        7268 :       case X86Reg::kKindGp : _gp  &= ~static_cast<uint16_t>(mask); break;
+     326           0 :       case X86Reg::kKindMm : _mm  &= ~static_cast<uint8_t >(mask); break;
+     327             :       case X86Reg::kKindK  : _k   &= ~static_cast<uint8_t >(mask); break;
+     328       22464 :       case X86Reg::kKindVec: _vec &= ~static_cast<uint32_t>(mask); break;
+     329             :     }
+     330             :   }
+     331             : 
+     332             :   ASMJIT_INLINE void andNotGp(uint32_t mask) noexcept { andNot(X86Reg::kKindGp, mask); }
+     333             :   ASMJIT_INLINE void andNotVec(uint32_t mask) noexcept { andNot(X86Reg::kKindVec, mask); }
+     334             :   ASMJIT_INLINE void andNotMm(uint32_t mask) noexcept { andNot(X86Reg::kKindMm, mask); }
+     335             :   ASMJIT_INLINE void andNotK(uint32_t mask) noexcept { andNot(X86Reg::kKindK, mask); }
+     336             : 
+     337             :   // --------------------------------------------------------------------------
+     338             :   // [Or]
+     339             :   // --------------------------------------------------------------------------
+     340             : 
+     341             :   ASMJIT_INLINE void or_(const X86RegMask& other) noexcept {
+     342             :     _packed.or_(other._packed);
+     343       33106 :   }
+     344             : 
+     345             :   ASMJIT_INLINE void or_(uint32_t kind, uint32_t mask) noexcept {
+     346             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     347        1948 :     switch (kind) {
+     348       14536 :       case X86Reg::kKindGp : _gp  |= static_cast<uint16_t>(mask); break;
+     349           0 :       case X86Reg::kKindMm : _mm  |= static_cast<uint8_t >(mask); break;
+     350           0 :       case X86Reg::kKindK  : _k   |= static_cast<uint8_t >(mask); break;
+     351       42900 :       case X86Reg::kKindVec: _vec |= static_cast<uint32_t>(mask); break;
+     352             :     }
+     353             :   }
+     354             : 
+     355             :   ASMJIT_INLINE void orGp(uint32_t mask) noexcept { return or_(X86Reg::kKindGp, mask); }
+     356             :   ASMJIT_INLINE void orVec(uint32_t mask) noexcept { return or_(X86Reg::kKindVec, mask); }
+     357             :   ASMJIT_INLINE void orMm(uint32_t mask) noexcept { return or_(X86Reg::kKindMm, mask); }
+     358             :   ASMJIT_INLINE void orK(uint32_t mask) noexcept { return or_(X86Reg::kKindK, mask); }
+     359             : 
+     360             :   // --------------------------------------------------------------------------
+     361             :   // [Xor]
+     362             :   // --------------------------------------------------------------------------
+     363             : 
+     364             :   ASMJIT_INLINE void xor_(const X86RegMask& other) noexcept {
+     365             :     _packed.xor_(other._packed);
+     366             :   }
+     367             : 
+     368             :   ASMJIT_INLINE void xor_(uint32_t kind, uint32_t mask) noexcept {
+     369             :     ASMJIT_ASSERT(kind < Globals::kMaxVRegKinds);
+     370             : 
+     371           0 :     switch (kind) {
+     372           0 :       case X86Reg::kKindGp : _gp  ^= static_cast<uint16_t>(mask); break;
+     373           0 :       case X86Reg::kKindMm : _mm  ^= static_cast<uint8_t >(mask); break;
+     374           0 :       case X86Reg::kKindK  : _k   ^= static_cast<uint8_t >(mask); break;
+     375        5080 :       case X86Reg::kKindVec: _vec ^= static_cast<uint32_t>(mask); break;
+     376             :     }
+     377             :   }
+     378             : 
+     379             :   ASMJIT_INLINE void xorGp(uint32_t mask) noexcept { xor_(X86Reg::kKindGp, mask); }
+     380             :   ASMJIT_INLINE void xorVec(uint32_t mask) noexcept { xor_(X86Reg::kKindVec, mask); }
+     381             :   ASMJIT_INLINE void xorMm(uint32_t mask) noexcept { xor_(X86Reg::kKindMm, mask); }
+     382             :   ASMJIT_INLINE void xorK(uint32_t mask) noexcept { xor_(X86Reg::kKindK, mask); }
+     383             : 
+     384             :   // --------------------------------------------------------------------------
+     385             :   // [Members]
+     386             :   // --------------------------------------------------------------------------
+     387             : 
+     388             :   union {
+     389             :     struct {
+     390             :       //! GP registers mask (16 bits).
+     391             :       uint16_t _gp;
+     392             :       //! MMX registers mask (8 bits).
+     393             :       uint8_t _mm;
+     394             :       //! K registers mask (8 bits).
+     395             :       uint8_t _k;
+     396             :       //! XMM|YMM|ZMM registers mask (32 bits).
+     397             :       uint32_t _vec;
+     398             :     };
+     399             : 
+     400             :     //! Packed masks.
+     401             :     UInt64 _packed;
+     402             :   };
+     403             : };
+     404             : 
+     405             : //! \}
+     406             : 
+     407             : } // asmjit namespace
+     408             : } // namespace PLMD
+     409             : 
+     410             : // [Api-End]
+     411             : #include "./asmjit_apiend.h"
+     412             : 
+     413             : // [Guard]
+     414             : #endif // _ASMJIT_X86_X86MISC_H
+     415             : #pragma GCC diagnostic pop
+     416             : #endif // __PLUMED_HAS_ASMJIT
+     417             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86operand.h.func-sort-c.html b/coverage-libs/asmjit/x86operand.h.func-sort-c.html new file mode 100644 index 000000000000..688b1fbb9c96 --- /dev/null +++ b/coverage-libs/asmjit/x86operand.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86operand.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86operand.h.func.html b/coverage-libs/asmjit/x86operand.h.func.html new file mode 100644 index 000000000000..c785d2cc4489 --- /dev/null +++ b/coverage-libs/asmjit/x86operand.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86operand.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86operand.h.gcov.html b/coverage-libs/asmjit/x86operand.h.gcov.html new file mode 100644 index 000000000000..8907d77239c5 --- /dev/null +++ b/coverage-libs/asmjit/x86operand.h.gcov.html @@ -0,0 +1,1210 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86operand.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86operand.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:61154.5 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_x86operand_h
+      21             : #define __PLUMED_asmjit_x86operand_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_X86_X86OPERAND_H
+      33             : #define _ASMJIT_X86_X86OPERAND_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./arch.h"
+      37             : #include "./operand.h"
+      38             : #include "./utils.h"
+      39             : #include "./x86globals.h"
+      40             : 
+      41             : // [Api-Begin]
+      42             : #include "./asmjit_apibegin.h"
+      43             : 
+      44             : namespace PLMD {
+      45             : namespace asmjit {
+      46             : 
+      47             : // ============================================================================
+      48             : // [Forward Declarations]
+      49             : // ============================================================================
+      50             : 
+      51             : class X86Mem;
+      52             : class X86Reg;
+      53             : class X86Vec;
+      54             : 
+      55             : class X86Gp;
+      56             : class X86Gpb;
+      57             : class X86GpbLo;
+      58             : class X86GpbHi;
+      59             : class X86Gpw;
+      60             : class X86Gpd;
+      61             : class X86Gpq;
+      62             : class X86Fp;
+      63             : class X86Mm;
+      64             : class X86KReg;
+      65             : class X86Xmm;
+      66             : class X86Ymm;
+      67             : class X86Zmm;
+      68             : class X86Bnd;
+      69             : class X86Seg;
+      70             : class X86Rip;
+      71             : class X86CReg;
+      72             : class X86DReg;
+      73             : 
+      74             : //! \addtogroup asmjit_x86
+      75             : //! \{
+      76             : 
+      77             : // ============================================================================
+      78             : // [asmjit::X86Mem]
+      79             : // ============================================================================
+      80             : 
+      81             : //! Memory operand (X86).
+      82             : class X86Mem : public Mem {
+      83             : public:
+      84             :   //! Additional bits of operand's signature used by `X86Mem`.
+      85             :   ASMJIT_ENUM(AdditionalBits) {
+      86             :     kSignatureMemShiftShift   = 19,
+      87             :     kSignatureMemShiftBits    = 0x03U,
+      88             :     kSignatureMemShiftMask    = kSignatureMemShiftBits << kSignatureMemShiftShift,
+      89             : 
+      90             :     kSignatureMemSegmentShift = 21,
+      91             :     kSignatureMemSegmentBits  = 0x07U,
+      92             :     kSignatureMemSegmentMask  = kSignatureMemSegmentBits << kSignatureMemSegmentShift
+      93             :   };
+      94             : 
+      95             :   // --------------------------------------------------------------------------
+      96             :   // [Construction / Destruction]
+      97             :   // --------------------------------------------------------------------------
+      98             : 
+      99             :   //! Construct a default `X86Mem` operand, that points to [0].
+     100             :   ASMJIT_INLINE X86Mem() noexcept : Mem(NoInit) { reset(); }
+     101             :   ASMJIT_INLINE X86Mem(const X86Mem& other) noexcept : Mem(other) {}
+     102             : 
+     103             :   ASMJIT_INLINE X86Mem(const Label& base, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept : Mem(NoInit) {
+     104             :     uint32_t signature = (Label::kLabelTag << kSignatureMemBaseTypeShift ) |
+     105             :                          (size             << kSignatureSizeShift        ) ;
+     106             : 
+     107             :     _init_packed_d0_d1(kOpMem | signature | flags, 0);
+     108             :     _mem.base = base.getId();
+     109             :     _mem.offsetLo32 = static_cast<uint32_t>(off);
+     110             :   }
+     111             : 
+     112             :   ASMJIT_INLINE X86Mem(const Label& base, const Reg& index, uint32_t shift, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept : Mem(NoInit) {
+     113             :     ASMJIT_ASSERT(shift <= kSignatureMemShiftMask);
+     114             :     uint32_t signature = (Label::kLabelTag << kSignatureMemBaseTypeShift ) |
+     115             :                          (index.getType()  << kSignatureMemIndexTypeShift) |
+     116             :                          (shift            << kSignatureMemShiftShift    ) |
+     117             :                          (size             << kSignatureSizeShift        ) ;
+     118             : 
+     119             :     _init_packed_d0_d1(kOpMem | signature | flags, index.getId());
+     120             :     _mem.base = base.getId();
+     121             :     _mem.offsetLo32 = static_cast<uint32_t>(off);
+     122             :   }
+     123             : 
+     124             :   ASMJIT_INLINE X86Mem(const Reg& base, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept : Mem(NoInit) {
+     125        6100 :     uint32_t signature = (base.getType()   << kSignatureMemBaseTypeShift ) |
+     126             :                          (size             << kSignatureSizeShift        ) ;
+     127             : 
+     128        6100 :     _init_packed_d0_d1(kOpMem | signature | flags, 0);
+     129        6100 :     _mem.base = base.getId();
+     130        6100 :     _mem.offsetLo32 = static_cast<uint32_t>(off);
+     131             :   }
+     132             : 
+     133             :   ASMJIT_INLINE X86Mem(const Reg& base, const Reg& index, uint32_t shift, int32_t off, uint32_t size = 0, uint32_t flags = 0) noexcept : Mem(NoInit) {
+     134             :     ASMJIT_ASSERT(shift <= kSignatureMemShiftMask);
+     135             :     uint32_t signature = (base.getType()   << kSignatureMemBaseTypeShift ) |
+     136             :                          (index.getType()  << kSignatureMemIndexTypeShift) |
+     137             :                          (shift            << kSignatureMemShiftShift    ) |
+     138             :                          (size             << kSignatureSizeShift        ) ;
+     139             : 
+     140             :     _init_packed_d0_d1(kOpMem | signature | flags, index.getId());
+     141             :     _mem.base = base.getId();
+     142             :     _mem.offsetLo32 = static_cast<uint32_t>(off);
+     143             :   }
+     144             : 
+     145             :   ASMJIT_INLINE X86Mem(uint64_t base, uint32_t size = 0, uint32_t flags = 0) noexcept : Mem(NoInit) {
+     146             :     _init_packed_d0_d1(kOpMem | flags | (size << kSignatureSizeShift), 0);
+     147             :     _mem.offset64 = base;
+     148             :   }
+     149             : 
+     150             :   ASMJIT_INLINE X86Mem(uint64_t base, const Reg& index, uint32_t shift = 0, uint32_t size = 0, uint32_t flags = 0) noexcept : Mem(NoInit) {
+     151             :     ASMJIT_ASSERT(shift <= kSignatureMemShiftMask);
+     152             :     uint32_t signature = (index.getType()  << kSignatureMemIndexTypeShift) |
+     153             :                          (shift            << kSignatureMemShiftShift    ) |
+     154             :                          (size             << kSignatureSizeShift        ) ;
+     155             : 
+     156             :     _init_packed_d0_d1(kOpMem | signature | flags, index.getId());
+     157             :     _mem.offset64 = base;
+     158             :   }
+     159             : 
+     160             :   ASMJIT_INLINE X86Mem(const _Init& init,
+     161             :     uint32_t baseType, uint32_t baseId,
+     162             :     uint32_t indexType, uint32_t indexId,
+     163             :     int32_t off, uint32_t size, uint32_t flags) noexcept : Mem(init, baseType, baseId, indexType, indexId, off, size, flags) {}
+     164             : 
+     165             :   explicit ASMJIT_INLINE X86Mem(const _NoInit&) noexcept : Mem(NoInit) {}
+     166             : 
+     167             :   // --------------------------------------------------------------------------
+     168             :   // [X86Mem]
+     169             :   // --------------------------------------------------------------------------
+     170             : 
+     171             :   //! Clone the memory operand.
+     172             :   ASMJIT_INLINE X86Mem clone() const noexcept { return X86Mem(*this); }
+     173             : 
+     174             :   using Mem::setIndex;
+     175             : 
+     176             :   ASMJIT_INLINE void setIndex(const Reg& index, uint32_t shift) noexcept {
+     177             :     setIndex(index);
+     178             :     setShift(shift);
+     179             :   }
+     180             : 
+     181             :   //! Get if the memory operand has shift (aka scale) constant.
+     182             :   ASMJIT_INLINE bool hasShift() const noexcept { return _hasSignatureData(kSignatureMemShiftMask); }
+     183             :   //! Get the memory operand's shift (aka scale) constant.
+     184             :   ASMJIT_INLINE uint32_t getShift() const noexcept { return _getSignatureData(kSignatureMemShiftBits, kSignatureMemShiftShift); }
+     185             :   //! Set the memory operand's shift (aka scale) constant.
+     186             :   ASMJIT_INLINE void setShift(uint32_t shift) noexcept { _setSignatureData(shift, kSignatureMemShiftBits, kSignatureMemShiftShift); }
+     187             :   //! Reset the memory operand's shift (aka scale) constant to zero.
+     188             :   ASMJIT_INLINE void resetShift() noexcept { _signature &= ~kSignatureMemShiftMask; }
+     189             : 
+     190             :   //! Get if the memory operand has a segment override.
+     191             :   ASMJIT_INLINE bool hasSegment() const noexcept { return _hasSignatureData(kSignatureMemSegmentMask); }
+     192             :   //! Get associated segment override as `X86Seg` operand.
+     193             :   ASMJIT_INLINE X86Seg getSegment() const noexcept;
+     194             :   //! Set the segment override to `seg`.
+     195             :   ASMJIT_INLINE void setSegment(const X86Seg& seg) noexcept;
+     196             : 
+     197             :   //! Get segment override as id, see \ref X86Seg::Id.
+     198             :   ASMJIT_INLINE uint32_t getSegmentId() const noexcept { return _getSignatureData(kSignatureMemSegmentBits, kSignatureMemSegmentShift); }
+     199             :   //! Set the segment override to `id`.
+     200             :   ASMJIT_INLINE void setSegmentId(uint32_t sId) noexcept { _setSignatureData(sId, kSignatureMemSegmentBits, kSignatureMemSegmentShift); }
+     201             :   //! Reset the segment override.
+     202             :   ASMJIT_INLINE void resetSegment() noexcept { _signature &= ~kSignatureMemSegmentMask; }
+     203             : 
+     204             :   //! Get new memory operand adjusted by `off`.
+     205             :   ASMJIT_INLINE X86Mem adjusted(int64_t off) const noexcept {
+     206             :     X86Mem result(*this);
+     207             :     result.addOffset(off);
+     208             :     return result;
+     209             :   }
+     210             : 
+     211             :   // --------------------------------------------------------------------------
+     212             :   // [Operator Overload]
+     213             :   // --------------------------------------------------------------------------
+     214             : 
+     215             :   ASMJIT_INLINE X86Mem& operator=(const X86Mem& other) noexcept { copyFrom(other); return *this; }
+     216             : };
+     217             : 
+     218             : // ============================================================================
+     219             : // [asmjit::X86Reg]
+     220             : // ============================================================================
+     221             : 
+     222             : //! Register traits (X86/X64).
+     223             : //!
+     224             : //! Register traits contains information about a particular register type. It's
+     225             : //! used by asmjit to setup register information on-the-fly and to populate
+     226             : //! tables that contain register information (this way it's possible to change
+     227             : //! register types and kinds without having to reorder these tables).
+     228             : template<uint32_t RegType>
+     229             : struct X86RegTraits {
+     230             :   enum {
+     231             :     kValid     = 0,                      //!< RegType is not valid by default.
+     232             :     kCount     = 0,                      //!< Count of registers (0 if none).
+     233             :     kTypeId    = TypeId::kVoid,          //!< Everything is void by default.
+     234             : 
+     235             :     kType      = 0,                      //!< Zero type by default.
+     236             :     kKind      = 0,                      //!< Zero kind by default.
+     237             :     kSize      = 0,                      //!< No size by default.
+     238             :     kSignature = 0                       //!< No signature by default.
+     239             :   };
+     240             : };
+     241             : 
+     242             : //! Register (X86/X64).
+     243             : class X86Reg : public Reg {
+     244             : public:
+     245             :   //! Register type.
+     246             :   //!
+     247             :   //! Don't change these constants; they are essential to some built-in tables.
+     248             :   ASMJIT_ENUM(RegType) {
+     249             :     kRegNone      = Reg::kRegNone,       //!< No register type or invalid register.
+     250             : 
+     251             :     kRegGpbLo     = Reg::kRegGp8Lo,      //!< Low GPB register (AL, BL, CL, DL, ...).
+     252             :     kRegGpbHi     = Reg::kRegGp8Hi,      //!< High GPB register (AH, BH, CH, DH only).
+     253             :     kRegGpw       = Reg::kRegGp16,       //!< GPW register.
+     254             :     kRegGpd       = Reg::kRegGp32,       //!< GPD register.
+     255             :     kRegGpq       = Reg::kRegGp64,       //!< GPQ register (X64).
+     256             :     kRegXmm       = Reg::kRegVec128,     //!< XMM register (SSE+).
+     257             :     kRegYmm       = Reg::kRegVec256,     //!< YMM register (AVX+).
+     258             :     kRegZmm       = Reg::kRegVec512,     //!< ZMM register (AVX512+).
+     259             :     kRegRip       = Reg::kRegIP,         //!< Instruction pointer (EIP, RIP).
+     260             :     kRegSeg       = Reg::kRegCustom,     //!< Segment register (None, ES, CS, SS, DS, FS, GS).
+     261             :     kRegFp        = Reg::kRegCustom + 1, //!< FPU (x87) register.
+     262             :     kRegMm        = Reg::kRegCustom + 2, //!< MMX register.
+     263             :     kRegK         = Reg::kRegCustom + 3, //!< K register (AVX512+).
+     264             :     kRegBnd       = Reg::kRegCustom + 4, //!< Bound register (BND).
+     265             :     kRegCr        = Reg::kRegCustom + 5, //!< Control register (CR).
+     266             :     kRegDr        = Reg::kRegCustom + 6, //!< Debug register (DR).
+     267             :     kRegCount                            //!< Count of register types.
+     268             :   };
+     269             : 
+     270             :   //! Register kind.
+     271             :   ASMJIT_ENUM(Kind) {
+     272             :     kKindGp       = Reg::kKindGp,        //!< GP register kind or none (universal).
+     273             :     kKindVec      = Reg::kKindVec,       //!< XMM|YMM|ZMM register kind (universal).
+     274             :     kKindMm       = 2,                   //!< MMX register kind (legacy).
+     275             :     kKindK        = 3,                   //!< K register kind.
+     276             : 
+     277             :     // These are not managed by CodeCompiler nor used by Func-API:
+     278             :     kKindFp       = 4,                   //!< FPU (x87) register kind.
+     279             :     kKindCr       = 5,                   //!< Control register kind.
+     280             :     kKindDr       = 6,                   //!< Debug register kind.
+     281             :     kKindBnd      = 7,                   //!< Bound register kind.
+     282             :     kKindSeg      = 8,                   //!< Segment register kind.
+     283             :     kKindRip      = 9,                   //!< Instrucion pointer (IP).
+     284             :     kKindCount                           //!< Count of all register kinds.
+     285             :   };
+     286             : 
+     287             :   ASMJIT_DEFINE_ABSTRACT_REG(X86Reg, Reg)
+     288             : 
+     289             :   //! Get if the register is a GPB register (8-bit).
+     290             :   ASMJIT_INLINE bool isGpb() const noexcept { return getSize() == 1; }
+     291             :   //! Get if the register is RIP.
+     292             :   ASMJIT_INLINE bool isRip() const noexcept { return hasSignature(signatureOf(kRegRip)); }
+     293             :   //! Get if the register is a segment register.
+     294             :   ASMJIT_INLINE bool isSeg() const noexcept { return hasSignature(signatureOf(kRegSeg)); }
+     295             :   //! Get if the register is a low GPB register (8-bit).
+     296             :   ASMJIT_INLINE bool isGpbLo() const noexcept { return hasSignature(signatureOf(kRegGpbLo)); }
+     297             :   //! Get if the register is a high GPB register (8-bit).
+     298             :   ASMJIT_INLINE bool isGpbHi() const noexcept { return hasSignature(signatureOf(kRegGpbHi)); }
+     299             :   //! Get if the register is a GPW register (16-bit).
+     300             :   ASMJIT_INLINE bool isGpw() const noexcept { return hasSignature(signatureOf(kRegGpw)); }
+     301             :   //! Get if the register is a GPD register (32-bit).
+     302             :   ASMJIT_INLINE bool isGpd() const noexcept { return hasSignature(signatureOf(kRegGpd)); }
+     303             :   //! Get if the register is a GPQ register (64-bit).
+     304             :   ASMJIT_INLINE bool isGpq() const noexcept { return hasSignature(signatureOf(kRegGpq)); }
+     305             :   //! Get if the register is an FPU register (80-bit).
+     306             :   ASMJIT_INLINE bool isFp() const noexcept { return hasSignature(signatureOf(kRegFp)); }
+     307             :   //! Get if the register is an MMX register (64-bit).
+     308             :   ASMJIT_INLINE bool isMm() const noexcept { return hasSignature(signatureOf(kRegMm)); }
+     309             :   //! Get if the register is a K register (64-bit).
+     310             :   ASMJIT_INLINE bool isK() const noexcept { return hasSignature(signatureOf(kRegK)); }
+     311             :   //! Get if the register is an XMM register (128-bit).
+     312             :   ASMJIT_INLINE bool isXmm() const noexcept { return hasSignature(signatureOf(kRegXmm)); }
+     313             :   //! Get if the register is a YMM register (256-bit).
+     314             :   ASMJIT_INLINE bool isYmm() const noexcept { return hasSignature(signatureOf(kRegYmm)); }
+     315             :   //! Get if the register is a ZMM register (512-bit).
+     316             :   ASMJIT_INLINE bool isZmm() const noexcept { return hasSignature(signatureOf(kRegZmm)); }
+     317             :   //! Get if the register is a bound register.
+     318             :   ASMJIT_INLINE bool isBnd() const noexcept { return hasSignature(signatureOf(kRegBnd)); }
+     319             :   //! Get if the register is a control register.
+     320             :   ASMJIT_INLINE bool isCr() const noexcept { return hasSignature(signatureOf(kRegCr)); }
+     321             :   //! Get if the register is a debug register.
+     322             :   ASMJIT_INLINE bool isDr() const noexcept { return hasSignature(signatureOf(kRegDr)); }
+     323             : 
+     324             :   template<uint32_t Type>
+     325             :   ASMJIT_INLINE void setX86RegT(uint32_t rId) noexcept {
+     326             :     setSignature(X86RegTraits<Type>::kSignature);
+     327             :     setId(rId);
+     328             :   }
+     329             : 
+     330             :   ASMJIT_INLINE void setTypeAndId(uint32_t rType, uint32_t rId) noexcept {
+     331             :     ASMJIT_ASSERT(rType < kRegCount);
+     332             :     setSignature(signatureOf(rType));
+     333             :     setId(rId);
+     334             :   }
+     335             : 
+     336             :   static ASMJIT_INLINE uint32_t kindOf(uint32_t rType) noexcept;
+     337             :   template<uint32_t Type>
+     338             :   static ASMJIT_INLINE uint32_t kindOfT() noexcept { return X86RegTraits<Type>::kKind; }
+     339             : 
+     340             :   static ASMJIT_INLINE uint32_t signatureOf(uint32_t rType) noexcept;
+     341             :   template<uint32_t Type>
+     342             :   static ASMJIT_INLINE uint32_t signatureOfT() noexcept { return X86RegTraits<Type>::kSignature; }
+     343             : 
+     344             :   static ASMJIT_INLINE uint32_t signatureOfVecByType(uint32_t typeId) noexcept {
+     345             :     return typeId <= TypeId::_kVec128End ? signatureOfT<kRegXmm>() :
+     346             :            typeId <= TypeId::_kVec256End ? signatureOfT<kRegYmm>() : signatureOfT<kRegZmm>() ;
+     347             :   }
+     348             : 
+     349             :   static ASMJIT_INLINE uint32_t signatureOfVecBySize(uint32_t size) noexcept {
+     350           0 :     return size <= 16 ? signatureOfT<kRegXmm>() :
+     351           0 :            size <= 32 ? signatureOfT<kRegYmm>() : signatureOfT<kRegZmm>() ;
+     352             :   }
+     353             : 
+     354             :   //! Get if the `op` operand is either a low or high 8-bit GPB register.
+     355             :   static ASMJIT_INLINE bool isGpb(const Operand_& op) noexcept {
+     356             :     // Check operand type, register kind, and size. Not interested in register type.
+     357             :     const uint32_t kSgn = (Operand::kOpReg << kSignatureOpShift  ) |
+     358             :                           (1               << kSignatureSizeShift) ;
+     359           0 :     return (op.getSignature() & (kSignatureOpMask | kSignatureSizeMask)) == kSgn;
+     360             :   }
+     361             : 
+     362             :   static ASMJIT_INLINE bool isRip(const Operand_& op) noexcept { return op.as<X86Reg>().isRip(); }
+     363             :   static ASMJIT_INLINE bool isSeg(const Operand_& op) noexcept { return op.as<X86Reg>().isSeg(); }
+     364             :   static ASMJIT_INLINE bool isGpbLo(const Operand_& op) noexcept { return op.as<X86Reg>().isGpbLo(); }
+     365             :   static ASMJIT_INLINE bool isGpbHi(const Operand_& op) noexcept { return op.as<X86Reg>().isGpbHi(); }
+     366             :   static ASMJIT_INLINE bool isGpw(const Operand_& op) noexcept { return op.as<X86Reg>().isGpw(); }
+     367             :   static ASMJIT_INLINE bool isGpd(const Operand_& op) noexcept { return op.as<X86Reg>().isGpd(); }
+     368             :   static ASMJIT_INLINE bool isGpq(const Operand_& op) noexcept { return op.as<X86Reg>().isGpq(); }
+     369             :   static ASMJIT_INLINE bool isFp(const Operand_& op) noexcept { return op.as<X86Reg>().isFp(); }
+     370             :   static ASMJIT_INLINE bool isMm(const Operand_& op) noexcept { return op.as<X86Reg>().isMm(); }
+     371             :   static ASMJIT_INLINE bool isK(const Operand_& op) noexcept { return op.as<X86Reg>().isK(); }
+     372             :   static ASMJIT_INLINE bool isXmm(const Operand_& op) noexcept { return op.as<X86Reg>().isXmm(); }
+     373             :   static ASMJIT_INLINE bool isYmm(const Operand_& op) noexcept { return op.as<X86Reg>().isYmm(); }
+     374             :   static ASMJIT_INLINE bool isZmm(const Operand_& op) noexcept { return op.as<X86Reg>().isZmm(); }
+     375             :   static ASMJIT_INLINE bool isBnd(const Operand_& op) noexcept { return op.as<X86Reg>().isBnd(); }
+     376             :   static ASMJIT_INLINE bool isCr(const Operand_& op) noexcept { return op.as<X86Reg>().isCr(); }
+     377             :   static ASMJIT_INLINE bool isDr(const Operand_& op) noexcept { return op.as<X86Reg>().isDr(); }
+     378             : 
+     379             :   static ASMJIT_INLINE bool isGpb(const Operand_& op, uint32_t rId) noexcept { return isGpb(op) & (op.getId() == rId); }
+     380             : 
+     381             :   static ASMJIT_INLINE bool isRip(const Operand_& op, uint32_t rId) noexcept { return isRip(op) & (op.getId() == rId); }
+     382             :   static ASMJIT_INLINE bool isSeg(const Operand_& op, uint32_t rId) noexcept { return isSeg(op) & (op.getId() == rId); }
+     383             :   static ASMJIT_INLINE bool isGpbLo(const Operand_& op, uint32_t rId) noexcept { return isGpbLo(op) & (op.getId() == rId); }
+     384             :   static ASMJIT_INLINE bool isGpbHi(const Operand_& op, uint32_t rId) noexcept { return isGpbHi(op) & (op.getId() == rId); }
+     385           0 :   static ASMJIT_INLINE bool isGpw(const Operand_& op, uint32_t rId) noexcept { return isGpw(op) & (op.getId() == rId); }
+     386             :   static ASMJIT_INLINE bool isGpd(const Operand_& op, uint32_t rId) noexcept { return isGpd(op) & (op.getId() == rId); }
+     387             :   static ASMJIT_INLINE bool isGpq(const Operand_& op, uint32_t rId) noexcept { return isGpq(op) & (op.getId() == rId); }
+     388             :   static ASMJIT_INLINE bool isFp(const Operand_& op, uint32_t rId) noexcept { return isFp(op) & (op.getId() == rId); }
+     389             :   static ASMJIT_INLINE bool isMm(const Operand_& op, uint32_t rId) noexcept { return isMm(op) & (op.getId() == rId); }
+     390             :   static ASMJIT_INLINE bool isK(const Operand_& op, uint32_t rId) noexcept { return isK(op) & (op.getId() == rId); }
+     391           0 :   static ASMJIT_INLINE bool isXmm(const Operand_& op, uint32_t rId) noexcept { return isXmm(op) & (op.getId() == rId); }
+     392             :   static ASMJIT_INLINE bool isYmm(const Operand_& op, uint32_t rId) noexcept { return isYmm(op) & (op.getId() == rId); }
+     393             :   static ASMJIT_INLINE bool isZmm(const Operand_& op, uint32_t rId) noexcept { return isZmm(op) & (op.getId() == rId); }
+     394             :   static ASMJIT_INLINE bool isBnd(const Operand_& op, uint32_t rId) noexcept { return isBnd(op) & (op.getId() == rId); }
+     395             :   static ASMJIT_INLINE bool isCr(const Operand_& op, uint32_t rId) noexcept { return isCr(op) & (op.getId() == rId); }
+     396             :   static ASMJIT_INLINE bool isDr(const Operand_& op, uint32_t rId) noexcept { return isDr(op) & (op.getId() == rId); }
+     397             : 
+     398             :   // --------------------------------------------------------------------------
+     399             :   // [Memory Cast]
+     400             :   // --------------------------------------------------------------------------
+     401             : 
+     402             :   // DEPRECATED in next-wip.
+     403             :   ASMJIT_INLINE X86Mem m(int32_t disp = 0) const noexcept {
+     404             :     return X86Mem(*this, disp, getSize(), Mem::kSignatureMemRegHomeFlag);
+     405             :   }
+     406             : 
+     407             :   //! \overload
+     408             :   ASMJIT_INLINE X86Mem m(const X86Reg& index, uint32_t shift = 0, int32_t disp = 0) const noexcept {
+     409             :     return X86Mem(*this, index, shift, disp, getSize(), Mem::kSignatureMemRegHomeFlag);
+     410             :   }
+     411             : 
+     412             :   //! Cast this variable to 8-bit memory operand.
+     413             :   ASMJIT_INLINE X86Mem m8(int32_t disp = 0) const noexcept {
+     414             :     return X86Mem(*this, disp, 1, Mem::kSignatureMemRegHomeFlag);
+     415             :   }
+     416             : 
+     417             :   //! \overload
+     418             :   ASMJIT_INLINE X86Mem m8(const X86Reg& index, uint32_t shift = 0, int32_t disp = 0) const noexcept {
+     419             :     return X86Mem(*this, index, shift, disp, 1, Mem::kSignatureMemRegHomeFlag);
+     420             :   }
+     421             : 
+     422             :   //! Cast this variable to 16-bit memory operand.
+     423             :   ASMJIT_INLINE X86Mem m16(int32_t disp = 0) const noexcept {
+     424             :     return X86Mem(*this, disp, 2, Mem::kSignatureMemRegHomeFlag);
+     425             :   }
+     426             : 
+     427             :   //! \overload
+     428             :   ASMJIT_INLINE X86Mem m16(const X86Reg& index, uint32_t shift = 0, int32_t disp = 0) const noexcept {
+     429             :     return X86Mem(*this, index, shift, disp, 2, Mem::kSignatureMemRegHomeFlag);
+     430             :   }
+     431             : 
+     432             :   //! Cast this variable to 32-bit memory operand.
+     433             :   ASMJIT_INLINE X86Mem m32(int32_t disp = 0) const noexcept {
+     434             :     return X86Mem(*this, disp, 4, Mem::kSignatureMemRegHomeFlag);
+     435             :   }
+     436             : 
+     437             :   //! \overload
+     438             :   ASMJIT_INLINE X86Mem m32(const X86Reg& index, uint32_t shift = 0, int32_t disp = 0) const noexcept {
+     439             :     return X86Mem(*this, index, shift, disp, 4, Mem::kSignatureMemRegHomeFlag);
+     440             :   }
+     441             : 
+     442             :   //! Cast this variable to 64-bit memory operand.
+     443             :   ASMJIT_INLINE X86Mem m64(int32_t disp = 0) const noexcept {
+     444             :     return X86Mem(*this, disp, 8, Mem::kSignatureMemRegHomeFlag);
+     445             :   }
+     446             : 
+     447             :   //! \overload
+     448             :   ASMJIT_INLINE X86Mem m64(const X86Reg& index, uint32_t shift = 0, int32_t disp = 0) const noexcept {
+     449             :     return X86Mem(*this, index, shift, disp, 8, Mem::kSignatureMemRegHomeFlag);
+     450             :   }
+     451             : 
+     452             :   //! Cast this variable to 80-bit memory operand (long double).
+     453             :   ASMJIT_INLINE X86Mem m80(int32_t disp = 0) const noexcept {
+     454             :     return X86Mem(*this, disp, 10, Mem::kSignatureMemRegHomeFlag);
+     455             :   }
+     456             : 
+     457             :   //! \overload
+     458             :   ASMJIT_INLINE X86Mem m80(const X86Reg& index, uint32_t shift = 0, int32_t disp = 0) const noexcept {
+     459             :     return X86Mem(*this, index, shift, disp, 10, Mem::kSignatureMemRegHomeFlag);
+     460             :   }
+     461             : 
+     462             :   //! Cast this variable to 128-bit memory operand.
+     463             :   ASMJIT_INLINE X86Mem m128(int32_t disp = 0) const noexcept {
+     464             :     return X86Mem(*this, disp, 16, Mem::kSignatureMemRegHomeFlag);
+     465             :   }
+     466             : 
+     467             :   //! \overload
+     468             :   ASMJIT_INLINE X86Mem m128(const X86Reg& index, uint32_t shift = 0, int32_t disp = 0) const noexcept {
+     469             :     return X86Mem(*this, index, shift, disp, 16, Mem::kSignatureMemRegHomeFlag);
+     470             :   }
+     471             : 
+     472             :   //! Cast this variable to 256-bit memory operand.
+     473             :   ASMJIT_INLINE X86Mem m256(int32_t disp = 0) const noexcept {
+     474             :     return X86Mem(*this, disp, 32, Mem::kSignatureMemRegHomeFlag);
+     475             :   }
+     476             : 
+     477             :   //! \overload
+     478             :   ASMJIT_INLINE X86Mem m256(const X86Reg& index, uint32_t shift = 0, int32_t disp = 0) const noexcept {
+     479             :     return X86Mem(*this, index, shift, disp, 32, Mem::kSignatureMemRegHomeFlag);
+     480             :   }
+     481             : 
+     482             :   //! Cast this variable to 256-bit memory operand.
+     483             :   ASMJIT_INLINE X86Mem m512(int32_t disp = 0) const noexcept {
+     484             :     return X86Mem(*this, disp, 64, Mem::kSignatureMemRegHomeFlag);
+     485             :   }
+     486             : 
+     487             :   //! \overload
+     488             :   ASMJIT_INLINE X86Mem m512(const X86Reg& index, uint32_t shift = 0, int32_t disp = 0) const noexcept {
+     489             :     return X86Mem(*this, index, shift, disp, 64, Mem::kSignatureMemRegHomeFlag);
+     490             :   };
+     491             : };
+     492             : 
+     493             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Gp  , X86Reg::kRegGpbLo, X86Reg::kKindGp , 1 , 16, TypeId::kI8    );
+     494             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Gp  , X86Reg::kRegGpbHi, X86Reg::kKindGp , 1 , 4 , TypeId::kI8    );
+     495             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Gp  , X86Reg::kRegGpw  , X86Reg::kKindGp , 2 , 16, TypeId::kI16   );
+     496             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Gp  , X86Reg::kRegGpd  , X86Reg::kKindGp , 4 , 16, TypeId::kI32   );
+     497             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Gp  , X86Reg::kRegGpq  , X86Reg::kKindGp , 8 , 16, TypeId::kI64   );
+     498             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Xmm , X86Reg::kRegXmm  , X86Reg::kKindVec, 16, 32, TypeId::kI32x4 );
+     499             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Ymm , X86Reg::kRegYmm  , X86Reg::kKindVec, 32, 32, TypeId::kI32x8 );
+     500             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Zmm , X86Reg::kRegZmm  , X86Reg::kKindVec, 64, 32, TypeId::kI32x16);
+     501             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Rip , X86Reg::kRegRip  , X86Reg::kKindRip, 0 , 1 , TypeId::kVoid  );
+     502             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Seg , X86Reg::kRegSeg  , X86Reg::kKindSeg, 2 , 7 , TypeId::kVoid  );
+     503             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Fp  , X86Reg::kRegFp   , X86Reg::kKindFp , 10, 8 , TypeId::kF80   );
+     504             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Mm  , X86Reg::kRegMm   , X86Reg::kKindMm , 8 , 8 , TypeId::kMmx64 );
+     505             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86KReg, X86Reg::kRegK    , X86Reg::kKindK  , 0 , 8 , TypeId::kVoid  );
+     506             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86Bnd , X86Reg::kRegBnd  , X86Reg::kKindBnd, 16, 4 , TypeId::kVoid  );
+     507             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86CReg, X86Reg::kRegCr   , X86Reg::kKindCr , 0 , 16, TypeId::kVoid  );
+     508             : ASMJIT_DEFINE_REG_TRAITS(X86RegTraits, X86DReg, X86Reg::kRegDr   , X86Reg::kKindDr , 0 , 16, TypeId::kVoid  );
+     509             : 
+     510             : //! General purpose register (X86/X64).
+     511             : class X86Gp : public X86Reg {
+     512             : public:
+     513        1948 :   ASMJIT_DEFINE_ABSTRACT_REG(X86Gp, X86Reg)
+     514             : 
+     515             :   //! X86/X64 physical id.
+     516             :   //!
+     517             :   //! NOTE: Register indexes have been reduced to only support general purpose
+     518             :   //! registers. There is no need to have enumerations with number suffix that
+     519             :   //! expands to the exactly same value as the suffix value itself.
+     520             :   ASMJIT_ENUM(Id) {
+     521             :     kIdAx  = 0,  //!< Physical id of AL|AH|AX|EAX|RAX registers.
+     522             :     kIdCx  = 1,  //!< Physical id of CL|CH|CX|ECX|RCX registers.
+     523             :     kIdDx  = 2,  //!< Physical id of DL|DH|DX|EDX|RDX registers.
+     524             :     kIdBx  = 3,  //!< Physical id of BL|BH|BX|EBX|RBX registers.
+     525             :     kIdSp  = 4,  //!< Physical id of SPL|SP|ESP|RSP registers.
+     526             :     kIdBp  = 5,  //!< Physical id of BPL|BP|EBP|RBP registers.
+     527             :     kIdSi  = 6,  //!< Physical id of SIL|SI|ESI|RSI registers.
+     528             :     kIdDi  = 7,  //!< Physical id of DIL|DI|EDI|RDI registers.
+     529             :     kIdR8  = 8,  //!< Physical id of R8B|R8W|R8D|R8 registers (64-bit only).
+     530             :     kIdR9  = 9,  //!< Physical id of R9B|R9W|R9D|R9 registers (64-bit only).
+     531             :     kIdR10 = 10, //!< Physical id of R10B|R10W|R10D|R10 registers (64-bit only).
+     532             :     kIdR11 = 11, //!< Physical id of R11B|R11W|R11D|R11 registers (64-bit only).
+     533             :     kIdR12 = 12, //!< Physical id of R12B|R12W|R12D|R12 registers (64-bit only).
+     534             :     kIdR13 = 13, //!< Physical id of R13B|R13W|R13D|R13 registers (64-bit only).
+     535             :     kIdR14 = 14, //!< Physical id of R14B|R14W|R14D|R14 registers (64-bit only).
+     536             :     kIdR15 = 15  //!< Physical id of R15B|R15W|R15D|R15 registers (64-bit only).
+     537             :   };
+     538             : 
+     539             :   //! Cast this register to 8-bit (LO) part.
+     540             :   ASMJIT_INLINE X86GpbLo r8() const noexcept;
+     541             :   //! Cast this register to 8-bit (LO) part.
+     542             :   ASMJIT_INLINE X86GpbLo r8Lo() const noexcept;
+     543             :   //! Cast this register to 8-bit (HI) part.
+     544             :   ASMJIT_INLINE X86GpbHi r8Hi() const noexcept;
+     545             :   //! Cast this register to 16-bit.
+     546             :   ASMJIT_INLINE X86Gpw r16() const noexcept;
+     547             :   //! Cast this register to 32-bit.
+     548             :   ASMJIT_INLINE X86Gpd r32() const noexcept;
+     549             :   //! Cast this register to 64-bit.
+     550             :   ASMJIT_INLINE X86Gpq r64() const noexcept;
+     551             : };
+     552             : 
+     553             : //! XMM|YMM|ZMM register (X86/X64).
+     554             : class X86Vec : public X86Reg {
+     555             :   ASMJIT_DEFINE_ABSTRACT_REG(X86Vec, X86Reg)
+     556             : 
+     557             :   //! Cast this register to XMM (clone).
+     558             :   ASMJIT_INLINE X86Xmm xmm() const noexcept;
+     559             :   //! Cast this register to YMM.
+     560             :   ASMJIT_INLINE X86Ymm ymm() const noexcept;
+     561             :   //! Cast this register to ZMM.
+     562             :   ASMJIT_INLINE X86Zmm zmm() const noexcept;
+     563             : };
+     564             : 
+     565             : //! Segment register (X86/X64).
+     566             : class X86Seg : public X86Reg {
+     567             :   ASMJIT_DEFINE_FINAL_REG(X86Seg, X86Reg, X86RegTraits<kRegSeg>)
+     568             : 
+     569             :   //! X86/X64 segment id.
+     570             :   ASMJIT_ENUM(Id) {
+     571             :     kIdNone = 0, //!< No segment (default).
+     572             :     kIdEs   = 1, //!< ES segment.
+     573             :     kIdCs   = 2, //!< CS segment.
+     574             :     kIdSs   = 3, //!< SS segment.
+     575             :     kIdDs   = 4, //!< DS segment.
+     576             :     kIdFs   = 5, //!< FS segment.
+     577             :     kIdGs   = 6, //!< GS segment.
+     578             : 
+     579             :     //! Count of X86 segment registers supported by AsmJit.
+     580             :     //!
+     581             :     //! NOTE: X86 architecture has 6 segment registers - ES, CS, SS, DS, FS, GS.
+     582             :     //! X64 architecture lowers them down to just FS and GS. AsmJit supports 7
+     583             :     //! segment registers - all addressable in both X86 and X64 modes and one
+     584             :     //! extra called `X86Seg::kIdNone`, which is AsmJit specific and means that
+     585             :     //! there is no segment register specified.
+     586             :     kIdCount = 7
+     587             :   };
+     588             : };
+     589             : 
+     590             : //! GPB (low or high) register (X86/X64).
+     591             : class X86Gpb : public X86Gp { ASMJIT_DEFINE_ABSTRACT_REG(X86Gpb, X86Gp) };
+     592             : //! GPB low register (X86/X64).
+     593             : class X86GpbLo : public X86Gpb { ASMJIT_DEFINE_FINAL_REG(X86GpbLo, X86Gpb, X86RegTraits<kRegGpbLo>) };
+     594             : //! GPB high register (X86/X64).
+     595             : class X86GpbHi : public X86Gpb { ASMJIT_DEFINE_FINAL_REG(X86GpbHi, X86Gpb, X86RegTraits<kRegGpbHi>) };
+     596             : //! GPW register (X86/X64).
+     597             : class X86Gpw : public X86Gp { ASMJIT_DEFINE_FINAL_REG(X86Gpw, X86Gp, X86RegTraits<kRegGpw>) };
+     598             : //! GPD register (X86/X64).
+     599             : class X86Gpd : public X86Gp { ASMJIT_DEFINE_FINAL_REG(X86Gpd, X86Gp, X86RegTraits<kRegGpd>) };
+     600             : //! GPQ register (X64).
+     601             : class X86Gpq : public X86Gp { ASMJIT_DEFINE_FINAL_REG(X86Gpq, X86Gp, X86RegTraits<kRegGpq>) };
+     602             : 
+     603             : //! RIP register (X86/X64).
+     604             : class X86Rip : public X86Reg { ASMJIT_DEFINE_FINAL_REG(X86Rip, X86Reg, X86RegTraits<kRegRip>) };
+     605             : //! 80-bit FPU register (X86/X64).
+     606             : class X86Fp : public X86Reg { ASMJIT_DEFINE_FINAL_REG(X86Fp, X86Reg, X86RegTraits<kRegFp>) };
+     607             : //! 64-bit MMX register (MMX+).
+     608             : class X86Mm : public X86Reg { ASMJIT_DEFINE_FINAL_REG(X86Mm, X86Reg, X86RegTraits<kRegMm>) };
+     609             : //! 64-bit K register (AVX512+).
+     610             : class X86KReg : public X86Reg { ASMJIT_DEFINE_FINAL_REG(X86KReg, X86Reg, X86RegTraits<kRegK>) };
+     611             : //! 128-bit XMM register (SSE+).
+     612       16520 : class X86Xmm : public X86Vec { ASMJIT_DEFINE_FINAL_REG(X86Xmm, X86Vec, X86RegTraits<kRegXmm>) };
+     613             : //! 256-bit YMM register (AVX+).
+     614             : class X86Ymm : public X86Vec { ASMJIT_DEFINE_FINAL_REG(X86Ymm, X86Vec, X86RegTraits<kRegYmm>) };
+     615             : //! 512-bit ZMM register (AVX512+).
+     616             : class X86Zmm : public X86Vec { ASMJIT_DEFINE_FINAL_REG(X86Zmm, X86Vec, X86RegTraits<kRegZmm>) };
+     617             : //! 128-bit BND register (BND+).
+     618             : class X86Bnd : public X86Reg { ASMJIT_DEFINE_FINAL_REG(X86Bnd, X86Reg, X86RegTraits<kRegBnd>) };
+     619             : //! 32-bit or 64-bit control register (X86/X64).
+     620             : class X86CReg : public X86Reg { ASMJIT_DEFINE_FINAL_REG(X86CReg, X86Reg, X86RegTraits<kRegCr>) };
+     621             : //! 32-bit or 64-bit debug register (X86/X64).
+     622             : class X86DReg : public X86Reg { ASMJIT_DEFINE_FINAL_REG(X86DReg, X86Reg, X86RegTraits<kRegDr>) };
+     623             : 
+     624             : ASMJIT_INLINE X86GpbLo X86Gp::r8() const noexcept { return X86GpbLo(getId()); }
+     625             : ASMJIT_INLINE X86GpbLo X86Gp::r8Lo() const noexcept { return X86GpbLo(getId()); }
+     626             : ASMJIT_INLINE X86GpbHi X86Gp::r8Hi() const noexcept { return X86GpbHi(getId()); }
+     627             : ASMJIT_INLINE X86Gpw X86Gp::r16() const noexcept { return X86Gpw(getId()); }
+     628             : ASMJIT_INLINE X86Gpd X86Gp::r32() const noexcept { return X86Gpd(getId()); }
+     629             : ASMJIT_INLINE X86Gpq X86Gp::r64() const noexcept { return X86Gpq(getId()); }
+     630             : ASMJIT_INLINE X86Xmm X86Vec::xmm() const noexcept { return X86Xmm(*this, getId()); }
+     631             : ASMJIT_INLINE X86Ymm X86Vec::ymm() const noexcept { return X86Ymm(*this, getId()); }
+     632             : ASMJIT_INLINE X86Zmm X86Vec::zmm() const noexcept { return X86Zmm(*this, getId()); }
+     633             : 
+     634             : ASMJIT_INLINE X86Seg X86Mem::getSegment() const noexcept { return X86Seg(getSegmentId()); }
+     635             : ASMJIT_INLINE void X86Mem::setSegment(const X86Seg& seg) noexcept { setSegmentId(seg.getId()); }
+     636             : 
+     637             : 
+     638             : ASMJIT_DEFINE_TYPE_ID(X86Gpb, TypeId::kI8);
+     639             : ASMJIT_DEFINE_TYPE_ID(X86Gpw, TypeId::kI16);
+     640             : ASMJIT_DEFINE_TYPE_ID(X86Gpd, TypeId::kI32);
+     641             : ASMJIT_DEFINE_TYPE_ID(X86Gpq, TypeId::kI64);
+     642             : ASMJIT_DEFINE_TYPE_ID(X86Mm , TypeId::kMmx64);
+     643             : ASMJIT_DEFINE_TYPE_ID(X86Xmm, TypeId::kI32x4);
+     644             : ASMJIT_DEFINE_TYPE_ID(X86Ymm, TypeId::kI32x8);
+     645             : ASMJIT_DEFINE_TYPE_ID(X86Zmm, TypeId::kI32x16);
+     646             : 
+     647             : // ============================================================================
+     648             : // [asmjit::X86OpData]
+     649             : // ============================================================================
+     650             : 
+     651             : struct X86OpData {
+     652             :   // --------------------------------------------------------------------------
+     653             :   // [Signatures]
+     654             :   // --------------------------------------------------------------------------
+     655             : 
+     656             :   //! Information about all architecture registers.
+     657             :   ArchRegs archRegs;
+     658             : 
+     659             :   // --------------------------------------------------------------------------
+     660             :   // [Operands]
+     661             :   // --------------------------------------------------------------------------
+     662             : 
+     663             :   // Prevent calling constructors of these registers when exporting.
+     664             : #if defined(ASMJIT_EXPORTS_X86_OPERAND)
+     665             : # define ASMJIT_X86_REG_DATA(REG) Operand_
+     666             : #else
+     667             : # define ASMJIT_X86_REG_DATA(REG) REG
+     668             : #endif
+     669             :   ASMJIT_X86_REG_DATA(X86Rip ) rip[1];
+     670             :   ASMJIT_X86_REG_DATA(X86Seg ) seg[7];
+     671             :   ASMJIT_X86_REG_DATA(X86Gp  ) gpbLo[16];
+     672             :   ASMJIT_X86_REG_DATA(X86Gp  ) gpbHi[4];
+     673             :   ASMJIT_X86_REG_DATA(X86Gp  ) gpw[16];
+     674             :   ASMJIT_X86_REG_DATA(X86Gp  ) gpd[16];
+     675             :   ASMJIT_X86_REG_DATA(X86Gp  ) gpq[16];
+     676             :   ASMJIT_X86_REG_DATA(X86Fp  ) fp[8];
+     677             :   ASMJIT_X86_REG_DATA(X86Mm  ) mm[8];
+     678             :   ASMJIT_X86_REG_DATA(X86KReg) k[8];
+     679             :   ASMJIT_X86_REG_DATA(X86Xmm ) xmm[32];
+     680             :   ASMJIT_X86_REG_DATA(X86Ymm ) ymm[32];
+     681             :   ASMJIT_X86_REG_DATA(X86Zmm ) zmm[32];
+     682             :   ASMJIT_X86_REG_DATA(X86Bnd ) bnd[4];
+     683             :   ASMJIT_X86_REG_DATA(X86CReg) cr[16];
+     684             :   ASMJIT_X86_REG_DATA(X86DReg) dr[16];
+     685             : #undef ASMJIT_X86_REG_DATA
+     686             : };
+     687             : ASMJIT_VARAPI const X86OpData x86OpData;
+     688             : 
+     689             : // ... X86Reg methods that require `x86OpData`.
+     690             : ASMJIT_INLINE uint32_t X86Reg::signatureOf(uint32_t rType) noexcept {
+     691             :   ASMJIT_ASSERT(rType <= Reg::kRegMax);
+     692             :   return x86OpData.archRegs.regInfo[rType].getSignature();
+     693             : }
+     694             : 
+     695             : ASMJIT_INLINE uint32_t X86Reg::kindOf(uint32_t rType) noexcept {
+     696             :   ASMJIT_ASSERT(rType <= Reg::kRegMax);
+     697             :   return x86OpData.archRegs.regInfo[rType].getKind();
+     698             : }
+     699             : 
+     700             : // ============================================================================
+     701             : // [asmjit::x86]
+     702             : // ============================================================================
+     703             : 
+     704             : namespace x86 {
+     705             : 
+     706             : // ============================================================================
+     707             : // [asmjit::x86 - Reg]
+     708             : // ============================================================================
+     709             : 
+     710             : #if !defined(ASMJIT_EXPORTS_X86_OPERAND)
+     711             : namespace {
+     712             : #define ASMJIT_X86_PHYS_REG(TYPE, NAME, PROPERTY) \
+     713             :   static const TYPE& NAME = x86OpData.PROPERTY
+     714             : 
+     715             : ASMJIT_X86_PHYS_REG(X86Rip , rip  , rip[0]);    //!< RIP register.
+     716             : ASMJIT_X86_PHYS_REG(X86Seg , es   , seg[1]);    //!< CS segment register.
+     717             : ASMJIT_X86_PHYS_REG(X86Seg , cs   , seg[2]);    //!< SS segment register.
+     718             : ASMJIT_X86_PHYS_REG(X86Seg , ss   , seg[3]);    //!< DS segment register.
+     719             : ASMJIT_X86_PHYS_REG(X86Seg , ds   , seg[4]);    //!< ES segment register.
+     720             : ASMJIT_X86_PHYS_REG(X86Seg , fs   , seg[5]);    //!< FS segment register.
+     721             : ASMJIT_X86_PHYS_REG(X86Seg , gs   , seg[6]);    //!< GS segment register.
+     722             : 
+     723             : ASMJIT_X86_PHYS_REG(X86Gp  , al   , gpbLo[0]);  //!< 8-bit low GPB register.
+     724             : ASMJIT_X86_PHYS_REG(X86Gp  , cl   , gpbLo[1]);  //!< 8-bit low GPB register.
+     725             : ASMJIT_X86_PHYS_REG(X86Gp  , dl   , gpbLo[2]);  //!< 8-bit low GPB register.
+     726             : ASMJIT_X86_PHYS_REG(X86Gp  , bl   , gpbLo[3]);  //!< 8-bit low GPB register.
+     727             : ASMJIT_X86_PHYS_REG(X86Gp  , spl  , gpbLo[4]);  //!< 8-bit low GPB register (X64).
+     728             : ASMJIT_X86_PHYS_REG(X86Gp  , bpl  , gpbLo[5]);  //!< 8-bit low GPB register (X64).
+     729             : ASMJIT_X86_PHYS_REG(X86Gp  , sil  , gpbLo[6]);  //!< 8-bit low GPB register (X64).
+     730             : ASMJIT_X86_PHYS_REG(X86Gp  , dil  , gpbLo[7]);  //!< 8-bit low GPB register (X64).
+     731             : ASMJIT_X86_PHYS_REG(X86Gp  , r8b  , gpbLo[8]);  //!< 8-bit low GPB register (X64).
+     732             : ASMJIT_X86_PHYS_REG(X86Gp  , r9b  , gpbLo[9]);  //!< 8-bit low GPB register (X64).
+     733             : ASMJIT_X86_PHYS_REG(X86Gp  , r10b , gpbLo[10]); //!< 8-bit low GPB register (X64).
+     734             : ASMJIT_X86_PHYS_REG(X86Gp  , r11b , gpbLo[11]); //!< 8-bit low GPB register (X64).
+     735             : ASMJIT_X86_PHYS_REG(X86Gp  , r12b , gpbLo[12]); //!< 8-bit low GPB register (X64).
+     736             : ASMJIT_X86_PHYS_REG(X86Gp  , r13b , gpbLo[13]); //!< 8-bit low GPB register (X64).
+     737             : ASMJIT_X86_PHYS_REG(X86Gp  , r14b , gpbLo[14]); //!< 8-bit low GPB register (X64).
+     738             : ASMJIT_X86_PHYS_REG(X86Gp  , r15b , gpbLo[15]); //!< 8-bit low GPB register (X64).
+     739             : 
+     740             : ASMJIT_X86_PHYS_REG(X86Gp  , ah   , gpbHi[0]);  //!< 8-bit high GPB register.
+     741             : ASMJIT_X86_PHYS_REG(X86Gp  , ch   , gpbHi[1]);  //!< 8-bit high GPB register.
+     742             : ASMJIT_X86_PHYS_REG(X86Gp  , dh   , gpbHi[2]);  //!< 8-bit high GPB register.
+     743             : ASMJIT_X86_PHYS_REG(X86Gp  , bh   , gpbHi[3]);  //!< 8-bit high GPB register.
+     744             : 
+     745             : ASMJIT_X86_PHYS_REG(X86Gp  , ax   , gpw[0]);    //!< 16-bit GPW register.
+     746             : ASMJIT_X86_PHYS_REG(X86Gp  , cx   , gpw[1]);    //!< 16-bit GPW register.
+     747             : ASMJIT_X86_PHYS_REG(X86Gp  , dx   , gpw[2]);    //!< 16-bit GPW register.
+     748             : ASMJIT_X86_PHYS_REG(X86Gp  , bx   , gpw[3]);    //!< 16-bit GPW register.
+     749             : ASMJIT_X86_PHYS_REG(X86Gp  , sp   , gpw[4]);    //!< 16-bit GPW register.
+     750             : ASMJIT_X86_PHYS_REG(X86Gp  , bp   , gpw[5]);    //!< 16-bit GPW register.
+     751             : ASMJIT_X86_PHYS_REG(X86Gp  , si   , gpw[6]);    //!< 16-bit GPW register.
+     752             : ASMJIT_X86_PHYS_REG(X86Gp  , di   , gpw[7]);    //!< 16-bit GPW register.
+     753             : ASMJIT_X86_PHYS_REG(X86Gp  , r8w  , gpw[8]);    //!< 16-bit GPW register (X64).
+     754             : ASMJIT_X86_PHYS_REG(X86Gp  , r9w  , gpw[9]);    //!< 16-bit GPW register (X64).
+     755             : ASMJIT_X86_PHYS_REG(X86Gp  , r10w , gpw[10]);   //!< 16-bit GPW register (X64).
+     756             : ASMJIT_X86_PHYS_REG(X86Gp  , r11w , gpw[11]);   //!< 16-bit GPW register (X64).
+     757             : ASMJIT_X86_PHYS_REG(X86Gp  , r12w , gpw[12]);   //!< 16-bit GPW register (X64).
+     758             : ASMJIT_X86_PHYS_REG(X86Gp  , r13w , gpw[13]);   //!< 16-bit GPW register (X64).
+     759             : ASMJIT_X86_PHYS_REG(X86Gp  , r14w , gpw[14]);   //!< 16-bit GPW register (X64).
+     760             : ASMJIT_X86_PHYS_REG(X86Gp  , r15w , gpw[15]);   //!< 16-bit GPW register (X64).
+     761             : 
+     762             : ASMJIT_X86_PHYS_REG(X86Gp  , eax  , gpd[0]);    //!< 32-bit GPD register.
+     763             : ASMJIT_X86_PHYS_REG(X86Gp  , ecx  , gpd[1]);    //!< 32-bit GPD register.
+     764             : ASMJIT_X86_PHYS_REG(X86Gp  , edx  , gpd[2]);    //!< 32-bit GPD register.
+     765             : ASMJIT_X86_PHYS_REG(X86Gp  , ebx  , gpd[3]);    //!< 32-bit GPD register.
+     766             : ASMJIT_X86_PHYS_REG(X86Gp  , esp  , gpd[4]);    //!< 32-bit GPD register.
+     767             : ASMJIT_X86_PHYS_REG(X86Gp  , ebp  , gpd[5]);    //!< 32-bit GPD register.
+     768             : ASMJIT_X86_PHYS_REG(X86Gp  , esi  , gpd[6]);    //!< 32-bit GPD register.
+     769             : ASMJIT_X86_PHYS_REG(X86Gp  , edi  , gpd[7]);    //!< 32-bit GPD register.
+     770             : ASMJIT_X86_PHYS_REG(X86Gp  , r8d  , gpd[8]);    //!< 32-bit GPD register (X64).
+     771             : ASMJIT_X86_PHYS_REG(X86Gp  , r9d  , gpd[9]);    //!< 32-bit GPD register (X64).
+     772             : ASMJIT_X86_PHYS_REG(X86Gp  , r10d , gpd[10]);   //!< 32-bit GPD register (X64).
+     773             : ASMJIT_X86_PHYS_REG(X86Gp  , r11d , gpd[11]);   //!< 32-bit GPD register (X64).
+     774             : ASMJIT_X86_PHYS_REG(X86Gp  , r12d , gpd[12]);   //!< 32-bit GPD register (X64).
+     775             : ASMJIT_X86_PHYS_REG(X86Gp  , r13d , gpd[13]);   //!< 32-bit GPD register (X64).
+     776             : ASMJIT_X86_PHYS_REG(X86Gp  , r14d , gpd[14]);   //!< 32-bit GPD register (X64).
+     777             : ASMJIT_X86_PHYS_REG(X86Gp  , r15d , gpd[15]);   //!< 32-bit GPD register (X64).
+     778             : 
+     779             : ASMJIT_X86_PHYS_REG(X86Gp  , rax  , gpq[0]);    //!< 64-bit GPQ register (X64).
+     780             : ASMJIT_X86_PHYS_REG(X86Gp  , rcx  , gpq[1]);    //!< 64-bit GPQ register (X64).
+     781             : ASMJIT_X86_PHYS_REG(X86Gp  , rdx  , gpq[2]);    //!< 64-bit GPQ register (X64).
+     782             : ASMJIT_X86_PHYS_REG(X86Gp  , rbx  , gpq[3]);    //!< 64-bit GPQ register (X64).
+     783             : ASMJIT_X86_PHYS_REG(X86Gp  , rsp  , gpq[4]);    //!< 64-bit GPQ register (X64).
+     784             : ASMJIT_X86_PHYS_REG(X86Gp  , rbp  , gpq[5]);    //!< 64-bit GPQ register (X64).
+     785             : ASMJIT_X86_PHYS_REG(X86Gp  , rsi  , gpq[6]);    //!< 64-bit GPQ register (X64).
+     786             : ASMJIT_X86_PHYS_REG(X86Gp  , rdi  , gpq[7]);    //!< 64-bit GPQ register (X64).
+     787             : ASMJIT_X86_PHYS_REG(X86Gp  , r8   , gpq[8]);    //!< 64-bit GPQ register (X64).
+     788             : ASMJIT_X86_PHYS_REG(X86Gp  , r9   , gpq[9]);    //!< 64-bit GPQ register (X64).
+     789             : ASMJIT_X86_PHYS_REG(X86Gp  , r10  , gpq[10]);   //!< 64-bit GPQ register (X64).
+     790             : ASMJIT_X86_PHYS_REG(X86Gp  , r11  , gpq[11]);   //!< 64-bit GPQ register (X64).
+     791             : ASMJIT_X86_PHYS_REG(X86Gp  , r12  , gpq[12]);   //!< 64-bit GPQ register (X64).
+     792             : ASMJIT_X86_PHYS_REG(X86Gp  , r13  , gpq[13]);   //!< 64-bit GPQ register (X64).
+     793             : ASMJIT_X86_PHYS_REG(X86Gp  , r14  , gpq[14]);   //!< 64-bit GPQ register (X64).
+     794             : ASMJIT_X86_PHYS_REG(X86Gp  , r15  , gpq[15]);   //!< 64-bit GPQ register (X64).
+     795             : 
+     796             : ASMJIT_X86_PHYS_REG(X86Fp  , fp0  , fp[0]);     //!< 80-bit FPU register.
+     797             : ASMJIT_X86_PHYS_REG(X86Fp  , fp1  , fp[1]);     //!< 80-bit FPU register.
+     798             : ASMJIT_X86_PHYS_REG(X86Fp  , fp2  , fp[2]);     //!< 80-bit FPU register.
+     799             : ASMJIT_X86_PHYS_REG(X86Fp  , fp3  , fp[3]);     //!< 80-bit FPU register.
+     800             : ASMJIT_X86_PHYS_REG(X86Fp  , fp4  , fp[4]);     //!< 80-bit FPU register.
+     801             : ASMJIT_X86_PHYS_REG(X86Fp  , fp5  , fp[5]);     //!< 80-bit FPU register.
+     802             : ASMJIT_X86_PHYS_REG(X86Fp  , fp6  , fp[6]);     //!< 80-bit FPU register.
+     803             : ASMJIT_X86_PHYS_REG(X86Fp  , fp7  , fp[7]);     //!< 80-bit FPU register.
+     804             : 
+     805             : ASMJIT_X86_PHYS_REG(X86Mm  , mm0  , mm[0]);     //!< 64-bit MMX register.
+     806             : ASMJIT_X86_PHYS_REG(X86Mm  , mm1  , mm[1]);     //!< 64-bit MMX register.
+     807             : ASMJIT_X86_PHYS_REG(X86Mm  , mm2  , mm[2]);     //!< 64-bit MMX register.
+     808             : ASMJIT_X86_PHYS_REG(X86Mm  , mm3  , mm[3]);     //!< 64-bit MMX register.
+     809             : ASMJIT_X86_PHYS_REG(X86Mm  , mm4  , mm[4]);     //!< 64-bit MMX register.
+     810             : ASMJIT_X86_PHYS_REG(X86Mm  , mm5  , mm[5]);     //!< 64-bit MMX register.
+     811             : ASMJIT_X86_PHYS_REG(X86Mm  , mm6  , mm[6]);     //!< 64-bit MMX register.
+     812             : ASMJIT_X86_PHYS_REG(X86Mm  , mm7  , mm[7]);     //!< 64-bit MMX register.
+     813             : 
+     814             : ASMJIT_X86_PHYS_REG(X86KReg, k0   , k[0]);      //!< 64-bit K register.
+     815             : ASMJIT_X86_PHYS_REG(X86KReg, k1   , k[1]);      //!< 64-bit K register.
+     816             : ASMJIT_X86_PHYS_REG(X86KReg, k2   , k[2]);      //!< 64-bit K register.
+     817             : ASMJIT_X86_PHYS_REG(X86KReg, k3   , k[3]);      //!< 64-bit K register.
+     818             : ASMJIT_X86_PHYS_REG(X86KReg, k4   , k[4]);      //!< 64-bit K register.
+     819             : ASMJIT_X86_PHYS_REG(X86KReg, k5   , k[5]);      //!< 64-bit K register.
+     820             : ASMJIT_X86_PHYS_REG(X86KReg, k6   , k[6]);      //!< 64-bit K register.
+     821             : ASMJIT_X86_PHYS_REG(X86KReg, k7   , k[7]);      //!< 64-bit K register.
+     822             : 
+     823             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm0 , xmm[0]);    //!< 128-bit XMM register.
+     824             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm1 , xmm[1]);    //!< 128-bit XMM register.
+     825             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm2 , xmm[2]);    //!< 128-bit XMM register.
+     826             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm3 , xmm[3]);    //!< 128-bit XMM register.
+     827             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm4 , xmm[4]);    //!< 128-bit XMM register.
+     828             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm5 , xmm[5]);    //!< 128-bit XMM register.
+     829             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm6 , xmm[6]);    //!< 128-bit XMM register.
+     830             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm7 , xmm[7]);    //!< 128-bit XMM register.
+     831             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm8 , xmm[8]);    //!< 128-bit XMM register (X64).
+     832             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm9 , xmm[9]);    //!< 128-bit XMM register (X64).
+     833             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm10, xmm[10]);   //!< 128-bit XMM register (X64).
+     834             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm11, xmm[11]);   //!< 128-bit XMM register (X64).
+     835             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm12, xmm[12]);   //!< 128-bit XMM register (X64).
+     836             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm13, xmm[13]);   //!< 128-bit XMM register (X64).
+     837             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm14, xmm[14]);   //!< 128-bit XMM register (X64).
+     838             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm15, xmm[15]);   //!< 128-bit XMM register (X64).
+     839             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm16, xmm[16]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     840             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm17, xmm[17]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     841             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm18, xmm[18]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     842             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm19, xmm[19]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     843             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm20, xmm[20]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     844             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm21, xmm[21]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     845             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm22, xmm[22]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     846             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm23, xmm[23]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     847             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm24, xmm[24]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     848             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm25, xmm[25]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     849             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm26, xmm[26]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     850             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm27, xmm[27]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     851             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm28, xmm[28]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     852             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm29, xmm[29]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     853             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm30, xmm[30]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     854             : ASMJIT_X86_PHYS_REG(X86Xmm , xmm31, xmm[31]);   //!< 128-bit XMM register (X64 & AVX512_VL+).
+     855             : 
+     856             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm0 , ymm[0]);    //!< 256-bit YMM register.
+     857             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm1 , ymm[1]);    //!< 256-bit YMM register.
+     858             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm2 , ymm[2]);    //!< 256-bit YMM register.
+     859             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm3 , ymm[3]);    //!< 256-bit YMM register.
+     860             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm4 , ymm[4]);    //!< 256-bit YMM register.
+     861             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm5 , ymm[5]);    //!< 256-bit YMM register.
+     862             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm6 , ymm[6]);    //!< 256-bit YMM register.
+     863             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm7 , ymm[7]);    //!< 256-bit YMM register.
+     864             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm8 , ymm[8]);    //!< 256-bit YMM register (X64).
+     865             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm9 , ymm[9]);    //!< 256-bit YMM register (X64).
+     866             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm10, ymm[10]);   //!< 256-bit YMM register (X64).
+     867             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm11, ymm[11]);   //!< 256-bit YMM register (X64).
+     868             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm12, ymm[12]);   //!< 256-bit YMM register (X64).
+     869             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm13, ymm[13]);   //!< 256-bit YMM register (X64).
+     870             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm14, ymm[14]);   //!< 256-bit YMM register (X64).
+     871             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm15, ymm[15]);   //!< 256-bit YMM register (X64).
+     872             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm16, ymm[16]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     873             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm17, ymm[17]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     874             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm18, ymm[18]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     875             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm19, ymm[19]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     876             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm20, ymm[20]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     877             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm21, ymm[21]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     878             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm22, ymm[22]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     879             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm23, ymm[23]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     880             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm24, ymm[24]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     881             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm25, ymm[25]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     882             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm26, ymm[26]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     883             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm27, ymm[27]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     884             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm28, ymm[28]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     885             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm29, ymm[29]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     886             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm30, ymm[30]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     887             : ASMJIT_X86_PHYS_REG(X86Ymm , ymm31, ymm[31]);   //!< 256-bit YMM register (X64 & AVX512_VL+).
+     888             : 
+     889             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm0 , zmm[0]);    //!< 512-bit ZMM register.
+     890             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm1 , zmm[1]);    //!< 512-bit ZMM register.
+     891             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm2 , zmm[2]);    //!< 512-bit ZMM register.
+     892             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm3 , zmm[3]);    //!< 512-bit ZMM register.
+     893             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm4 , zmm[4]);    //!< 512-bit ZMM register.
+     894             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm5 , zmm[5]);    //!< 512-bit ZMM register.
+     895             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm6 , zmm[6]);    //!< 512-bit ZMM register.
+     896             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm7 , zmm[7]);    //!< 512-bit ZMM register.
+     897             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm8 , zmm[8]);    //!< 512-bit ZMM register (X64).
+     898             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm9 , zmm[9]);    //!< 512-bit ZMM register (X64).
+     899             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm10, zmm[10]);   //!< 512-bit ZMM register (X64).
+     900             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm11, zmm[11]);   //!< 512-bit ZMM register (X64).
+     901             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm12, zmm[12]);   //!< 512-bit ZMM register (X64).
+     902             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm13, zmm[13]);   //!< 512-bit ZMM register (X64).
+     903             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm14, zmm[14]);   //!< 512-bit ZMM register (X64).
+     904             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm15, zmm[15]);   //!< 512-bit ZMM register (X64).
+     905             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm16, zmm[16]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     906             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm17, zmm[17]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     907             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm18, zmm[18]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     908             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm19, zmm[19]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     909             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm20, zmm[20]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     910             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm21, zmm[21]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     911             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm22, zmm[22]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     912             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm23, zmm[23]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     913             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm24, zmm[24]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     914             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm25, zmm[25]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     915             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm26, zmm[26]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     916             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm27, zmm[27]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     917             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm28, zmm[28]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     918             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm29, zmm[29]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     919             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm30, zmm[30]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     920             : ASMJIT_X86_PHYS_REG(X86Zmm , zmm31, zmm[31]);   //!< 512-bit ZMM register (X64 & AVX512_F+).
+     921             : 
+     922             : ASMJIT_X86_PHYS_REG(X86Bnd , bnd0 , bnd[0]);    //!< 128-bit bound register.
+     923             : ASMJIT_X86_PHYS_REG(X86Bnd , bnd1 , bnd[1]);    //!< 128-bit bound register.
+     924             : ASMJIT_X86_PHYS_REG(X86Bnd , bnd2 , bnd[2]);    //!< 128-bit bound register.
+     925             : ASMJIT_X86_PHYS_REG(X86Bnd , bnd3 , bnd[3]);    //!< 128-bit bound register.
+     926             : 
+     927             : ASMJIT_X86_PHYS_REG(X86CReg, cr0  , cr[0]);     //!< 32-bit or 64-bit control register.
+     928             : ASMJIT_X86_PHYS_REG(X86CReg, cr1  , cr[1]);     //!< 32-bit or 64-bit control register.
+     929             : ASMJIT_X86_PHYS_REG(X86CReg, cr2  , cr[2]);     //!< 32-bit or 64-bit control register.
+     930             : ASMJIT_X86_PHYS_REG(X86CReg, cr3  , cr[3]);     //!< 32-bit or 64-bit control register.
+     931             : ASMJIT_X86_PHYS_REG(X86CReg, cr4  , cr[4]);     //!< 32-bit or 64-bit control register.
+     932             : ASMJIT_X86_PHYS_REG(X86CReg, cr5  , cr[5]);     //!< 32-bit or 64-bit control register.
+     933             : ASMJIT_X86_PHYS_REG(X86CReg, cr6  , cr[6]);     //!< 32-bit or 64-bit control register.
+     934             : ASMJIT_X86_PHYS_REG(X86CReg, cr7  , cr[7]);     //!< 32-bit or 64-bit control register.
+     935             : ASMJIT_X86_PHYS_REG(X86CReg, cr8  , cr[8]);     //!< 32-bit or 64-bit control register.
+     936             : ASMJIT_X86_PHYS_REG(X86CReg, cr9  , cr[9]);     //!< 32-bit or 64-bit control register.
+     937             : ASMJIT_X86_PHYS_REG(X86CReg, cr10 , cr[10]);    //!< 32-bit or 64-bit control register.
+     938             : ASMJIT_X86_PHYS_REG(X86CReg, cr11 , cr[11]);    //!< 32-bit or 64-bit control register.
+     939             : ASMJIT_X86_PHYS_REG(X86CReg, cr12 , cr[12]);    //!< 32-bit or 64-bit control register.
+     940             : ASMJIT_X86_PHYS_REG(X86CReg, cr13 , cr[13]);    //!< 32-bit or 64-bit control register.
+     941             : ASMJIT_X86_PHYS_REG(X86CReg, cr14 , cr[14]);    //!< 32-bit or 64-bit control register.
+     942             : ASMJIT_X86_PHYS_REG(X86CReg, cr15 , cr[15]);    //!< 32-bit or 64-bit control register.
+     943             : 
+     944             : ASMJIT_X86_PHYS_REG(X86DReg, dr0  , dr[0]);     //!< 32-bit or 64-bit debug register.
+     945             : ASMJIT_X86_PHYS_REG(X86DReg, dr1  , dr[1]);     //!< 32-bit or 64-bit debug register.
+     946             : ASMJIT_X86_PHYS_REG(X86DReg, dr2  , dr[2]);     //!< 32-bit or 64-bit debug register.
+     947             : ASMJIT_X86_PHYS_REG(X86DReg, dr3  , dr[3]);     //!< 32-bit or 64-bit debug register.
+     948             : ASMJIT_X86_PHYS_REG(X86DReg, dr4  , dr[4]);     //!< 32-bit or 64-bit debug register.
+     949             : ASMJIT_X86_PHYS_REG(X86DReg, dr5  , dr[5]);     //!< 32-bit or 64-bit debug register.
+     950             : ASMJIT_X86_PHYS_REG(X86DReg, dr6  , dr[6]);     //!< 32-bit or 64-bit debug register.
+     951             : ASMJIT_X86_PHYS_REG(X86DReg, dr7  , dr[7]);     //!< 32-bit or 64-bit debug register.
+     952             : ASMJIT_X86_PHYS_REG(X86DReg, dr8  , dr[8]);     //!< 32-bit or 64-bit debug register.
+     953             : ASMJIT_X86_PHYS_REG(X86DReg, dr9  , dr[9]);     //!< 32-bit or 64-bit debug register.
+     954             : ASMJIT_X86_PHYS_REG(X86DReg, dr10 , dr[10]);    //!< 32-bit or 64-bit debug register.
+     955             : ASMJIT_X86_PHYS_REG(X86DReg, dr11 , dr[11]);    //!< 32-bit or 64-bit debug register.
+     956             : ASMJIT_X86_PHYS_REG(X86DReg, dr12 , dr[12]);    //!< 32-bit or 64-bit debug register.
+     957             : ASMJIT_X86_PHYS_REG(X86DReg, dr13 , dr[13]);    //!< 32-bit or 64-bit debug register.
+     958             : ASMJIT_X86_PHYS_REG(X86DReg, dr14 , dr[14]);    //!< 32-bit or 64-bit debug register.
+     959             : ASMJIT_X86_PHYS_REG(X86DReg, dr15 , dr[15]);    //!< 32-bit or 64-bit debug register.
+     960             : 
+     961             : #undef ASMJIT_X86_PHYS_REG
+     962             : } // anonymous namespace
+     963             : #endif // !ASMJIT_EXPORTS_X86_OPERAND
+     964             : 
+     965             : //! Create an 8-bit low GPB register operand.
+     966             : static ASMJIT_INLINE X86GpbLo gpb(uint32_t rId) noexcept { return X86GpbLo(rId); }
+     967             : //! Create an 8-bit low GPB register operand.
+     968             : static ASMJIT_INLINE X86GpbLo gpb_lo(uint32_t rId) noexcept { return X86GpbLo(rId); }
+     969             : //! Create an 8-bit high GPB register operand.
+     970             : static ASMJIT_INLINE X86GpbHi gpb_hi(uint32_t rId) noexcept { return X86GpbHi(rId); }
+     971             : //! Create a 16-bit GPW register operand.
+     972             : static ASMJIT_INLINE X86Gpw gpw(uint32_t rId) noexcept { return X86Gpw(rId); }
+     973             : //! Create a 32-bit GPD register operand.
+     974             : static ASMJIT_INLINE X86Gpd gpd(uint32_t rId) noexcept { return X86Gpd(rId); }
+     975             : //! Create a 64-bit GPQ register operand (X64).
+     976             : static ASMJIT_INLINE X86Gpq gpq(uint32_t rId) noexcept { return X86Gpq(rId); }
+     977             : //! Create an 80-bit Fp register operand.
+     978             : static ASMJIT_INLINE X86Fp fp(uint32_t rId) noexcept { return X86Fp(rId); }
+     979             : //! Create a 64-bit Mm register operand.
+     980             : static ASMJIT_INLINE X86Mm mm(uint32_t rId) noexcept { return X86Mm(rId); }
+     981             : //! Create a 64-bit K register operand.
+     982             : static ASMJIT_INLINE X86KReg k(uint32_t rId) noexcept { return X86KReg(rId); }
+     983             : //! Create a 128-bit XMM register operand.
+     984             : static ASMJIT_INLINE X86Xmm xmm(uint32_t rId) noexcept { return X86Xmm(rId); }
+     985             : //! Create a 256-bit YMM register operand.
+     986             : static ASMJIT_INLINE X86Ymm ymm(uint32_t rId) noexcept { return X86Ymm(rId); }
+     987             : //! Create a 512-bit ZMM register operand.
+     988             : static ASMJIT_INLINE X86Zmm zmm(uint32_t rId) noexcept { return X86Zmm(rId); }
+     989             : //! Create a 128-bit bound register operand.
+     990             : static ASMJIT_INLINE X86Bnd bnd(uint32_t rId) noexcept { return X86Bnd(rId); }
+     991             : //! Create a 32-bit or 64-bit control register operand.
+     992             : static ASMJIT_INLINE X86CReg cr(uint32_t rId) noexcept { return X86CReg(rId); }
+     993             : //! Create a 32-bit or 64-bit debug register operand.
+     994             : static ASMJIT_INLINE X86DReg dr(uint32_t rId) noexcept { return X86DReg(rId); }
+     995             : 
+     996             : // ============================================================================
+     997             : // [asmjit::x86 - Ptr (Reg)]
+     998             : // ============================================================================
+     999             : 
+    1000             : //! Create a `[base.reg + offset]` memory operand.
+    1001             : static ASMJIT_INLINE X86Mem ptr(const X86Gp& base, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1002             :   return X86Mem(base, offset, size);
+    1003             : }
+    1004             : //! Create a `[base.reg + (index << shift) + offset]` memory operand (scalar index).
+    1005             : static ASMJIT_INLINE X86Mem ptr(const X86Gp& base, const X86Gp& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1006             :   return X86Mem(base, index, shift, offset, size);
+    1007             : }
+    1008             : //! Create a `[base.reg + (index << shift) + offset]` memory operand (vector index).
+    1009             : static ASMJIT_INLINE X86Mem ptr(const X86Gp& base, const X86Vec& index, uint32_t shift = 0, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1010             :   return X86Mem(base, index, shift, offset, size);
+    1011             : }
+    1012             : 
+    1013             : //! Create a `[base + offset]` memory operand.
+    1014             : static ASMJIT_INLINE X86Mem ptr(const Label& base, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1015             :   return X86Mem(base, offset, size);
+    1016             : }
+    1017             : //! Create a `[base + (index << shift) + offset]` memory operand.
+    1018             : static ASMJIT_INLINE X86Mem ptr(const Label& base, const X86Gp& index, uint32_t shift, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1019             :   return X86Mem(base, index, shift, offset, size);
+    1020             : }
+    1021             : //! Create a `[base + (index << shift) + offset]` memory operand.
+    1022             : static ASMJIT_INLINE X86Mem ptr(const Label& base, const X86Vec& index, uint32_t shift, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1023             :   return X86Mem(base, index, shift, offset, size);
+    1024             : }
+    1025             : 
+    1026             : //! Create `[rip + offset]` memory operand.
+    1027             : static ASMJIT_INLINE X86Mem ptr(const X86Rip& rip_, int32_t offset = 0, uint32_t size = 0) noexcept {
+    1028             :   return X86Mem(rip_, offset, size);
+    1029             : }
+    1030             : 
+    1031             : //! Create an `[base]` absolute memory operand.
+    1032             : static ASMJIT_INLINE X86Mem ptr(uint64_t base, uint32_t size = 0) noexcept {
+    1033             :   return X86Mem(base, size);
+    1034             : }
+    1035             : //! Create an `[abs + (index.reg << shift)]` absolute memory operand.
+    1036             : static ASMJIT_INLINE X86Mem ptr(uint64_t base, const X86Reg& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+    1037             :   return X86Mem(base, index, shift, size);
+    1038             : }
+    1039             : //! Create an `[abs + (index.reg << shift)]` absolute memory operand.
+    1040             : static ASMJIT_INLINE X86Mem ptr(uint64_t base, const X86Vec& index, uint32_t shift = 0, uint32_t size = 0) noexcept {
+    1041             :   return X86Mem(base, index, shift, size);
+    1042             : }
+    1043             : 
+    1044             : //! \internal
+    1045             : #define ASMJIT_X86_PTR_FN(FUNC, SIZE)                                                 \
+    1046             :   /*! Create a `[base + offset]` memory operand. */                                   \
+    1047             :   static ASMJIT_INLINE X86Mem FUNC(const X86Gp& base, int32_t offset = 0) noexcept {  \
+    1048             :     return X86Mem(base, offset, SIZE);                                                \
+    1049             :   }                                                                                   \
+    1050             :   /*! Create a `[base + (index << shift) + offset]` memory operand. */                \
+    1051             :   static ASMJIT_INLINE X86Mem FUNC(const X86Gp& base, const X86Gp& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
+    1052             :     return X86Mem(base, index, shift, offset, SIZE);                                  \
+    1053             :   }                                                                                   \
+    1054             :   /*! Create a `[base + (vec_index << shift) + offset]` memory operand. */            \
+    1055             :   static ASMJIT_INLINE X86Mem FUNC(const X86Gp& base, const X86Vec& index, uint32_t shift = 0, int32_t offset = 0) noexcept { \
+    1056             :     return X86Mem(base, index, shift, offset, SIZE);                                  \
+    1057             :   }                                                                                   \
+    1058             :   /*! Create a `[base + offset]` memory operand. */                                   \
+    1059             :   static ASMJIT_INLINE X86Mem FUNC(const Label& base, int32_t offset = 0) noexcept {  \
+    1060             :     return X86Mem(base, offset, SIZE);                                                \
+    1061             :   }                                                                                   \
+    1062             :   /*! Create a `[base + (index << shift) + offset]` memory operand. */                \
+    1063             :   static ASMJIT_INLINE X86Mem FUNC(const Label& base, const X86Gp& index, uint32_t shift, int32_t offset = 0) noexcept { \
+    1064             :     return X86Mem(base, index, shift, offset, SIZE);                                  \
+    1065             :   }                                                                                   \
+    1066             :   /*! Create a `[rip + offset]` memory operand. */                                    \
+    1067             :   static ASMJIT_INLINE X86Mem FUNC(const X86Rip& rip_, int32_t offset = 0) noexcept { \
+    1068             :     return X86Mem(rip_, offset, SIZE);                                                \
+    1069             :   }                                                                                   \
+    1070             :   /*! Create a `[base + offset]` memory operand. */                                   \
+    1071             :   static ASMJIT_INLINE X86Mem FUNC(uint64_t base) noexcept {                          \
+    1072             :     return X86Mem(base, SIZE);                                                        \
+    1073             :   }                                                                                   \
+    1074             :   /*! Create a `[base + (index << shift) + offset]` memory operand. */                \
+    1075             :   static ASMJIT_INLINE X86Mem FUNC(uint64_t base, const X86Gp& index, uint32_t shift = 0) noexcept { \
+    1076             :     return X86Mem(base, index, shift, SIZE);                                          \
+    1077             :   }                                                                                   \
+    1078             :   /*! Create a `[base + (vec_index << shift) + offset]` memory operand. */            \
+    1079             :   static ASMJIT_INLINE X86Mem FUNC(uint64_t base, const X86Vec& index, uint32_t shift = 0) noexcept { \
+    1080             :     return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbs);                   \
+    1081             :   }                                                                                   \
+    1082             :   /*! Create a `[base + offset]` memory operand. */                                   \
+    1083             :   static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base) noexcept {                    \
+    1084             :     return X86Mem(base, SIZE);                                                        \
+    1085             :   }                                                                                   \
+    1086             :   /*! Create a `[base + (index << shift) + offset]` memory operand. */                \
+    1087             :   static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base, const X86Gp& index, uint32_t shift = 0) noexcept { \
+    1088             :     return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbs);                   \
+    1089             :   }                                                                                   \
+    1090             :   /*! Create a `[base + (vec_index << shift) + offset]` memory operand. */            \
+    1091             :   static ASMJIT_INLINE X86Mem FUNC##_abs(uint64_t base, const X86Vec& index, uint32_t shift = 0) noexcept { \
+    1092             :     return X86Mem(base, index, shift, SIZE, Mem::kSignatureMemAbs);                   \
+    1093             :   }
+    1094             : 
+    1095             : // Define memory operand constructors that use platform independent naming.
+    1096             : ASMJIT_X86_PTR_FN(ptr_8, 1)
+    1097             : ASMJIT_X86_PTR_FN(ptr_16, 2)
+    1098             : ASMJIT_X86_PTR_FN(ptr_32, 4)
+    1099             : ASMJIT_X86_PTR_FN(ptr_48, 6)
+    1100             : ASMJIT_X86_PTR_FN(ptr_64, 8)
+    1101             : ASMJIT_X86_PTR_FN(ptr_80, 10)
+    1102             : ASMJIT_X86_PTR_FN(ptr_128, 16)
+    1103             : ASMJIT_X86_PTR_FN(ptr_256, 32)
+    1104             : ASMJIT_X86_PTR_FN(ptr_512, 64)
+    1105             : 
+    1106             : // Define memory operand constructors that use X86/X64 specific naming.
+    1107             : ASMJIT_X86_PTR_FN(byte_ptr, 1)
+    1108             : ASMJIT_X86_PTR_FN(word_ptr, 2)
+    1109             : ASMJIT_X86_PTR_FN(dword_ptr, 4)
+    1110             : ASMJIT_X86_PTR_FN(qword_ptr, 8)
+    1111             : ASMJIT_X86_PTR_FN(tword_ptr, 10)
+    1112             : ASMJIT_X86_PTR_FN(oword_ptr, 16)
+    1113             : ASMJIT_X86_PTR_FN(dqword_ptr, 16)
+    1114             : ASMJIT_X86_PTR_FN(yword_ptr, 32)
+    1115             : ASMJIT_X86_PTR_FN(zword_ptr, 64)
+    1116             : 
+    1117             : #undef ASMJIT_X86_PTR_FN
+    1118             : 
+    1119             : } // x86 namespace
+    1120             : 
+    1121             : //! \}
+    1122             : 
+    1123             : } // asmjit namespace
+    1124             : } // namespace PLMD
+    1125             : 
+    1126             : // [Api-End]
+    1127             : #include "./asmjit_apiend.h"
+    1128             : 
+    1129             : // [Guard]
+    1130             : #endif // _ASMJIT_X86_X86OPERAND_H
+    1131             : #pragma GCC diagnostic pop
+    1132             : #endif // __PLUMED_HAS_ASMJIT
+    1133             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc.cpp.func-sort-c.html b/coverage-libs/asmjit/x86regalloc.cpp.func-sort-c.html new file mode 100644 index 000000000000..6f9c9d716ea1 --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc.cpp.func-sort-c.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:466105544.2 %
Date:2024-02-22 21:58:47Functions:172958.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit9X86RAPass10emitSwapGpEPNS0_7VirtRegES3_jjPKc0
_ZN4PLMD6asmjit9X86RAPass11_checkStateEv0
_ZN4PLMD6asmjit9X86RAPass11switchStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass14emitImmToStackEjPKNS0_6X86MemEPKNS0_3ImmE0
_ZN4PLMD6asmjit9X86RAPass14emitRegToStackEjPKNS0_6X86MemEjj0
_ZN4PLMD6asmjit9X86RAPass15intersectStatesEPNS0_7RAStateES3_0
_ZN4PLMD6asmjit9X86RAPass8annotateEv0
_ZN4PLMD6asmjit9X86RAPass9loadStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass9saveStateEv0
_ZN4PLMD6asmjit9X86RAPassD0Ev0
_ZN4PLMD6asmjit9X86RAPassD2Ev0
_ZN4PLMD6asmjitL23X86RAPass_translateJumpEPNS0_9X86RAPassEPNS0_6CBJumpEPNS0_7CBLabelE0
_ZN4PLMD6asmjitL30X86RAPass_prepareSingleVarInstEjPNS0_7TiedRegE248
_ZN4PLMD6asmjit9X86RAPass12emitImmToRegEjjPKNS0_3ImmE420
_ZN4PLMD6asmjit9X86RAPass8emitMoveEPNS0_7VirtRegEjjPKc656
_ZN4PLMD6asmjit12X86CallAlloc3runEPNS0_10CCFuncCallE1648
_ZN4PLMD6asmjit9X86RAPass5fetchEv1948
_ZN4PLMD6asmjit9X86RAPass7prepareEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit9X86RAPass7processEPNS0_4ZoneE1948
_ZN4PLMD6asmjit9X86RAPass9translateEv1948
_ZN4PLMD6asmjit9X86RAPassC2Ev1948
_ZN4PLMD6asmjitL22X86RAPass_patchFuncMemEPNS0_9X86RAPassEPNS0_6CCFuncEPNS0_6CBNodeERNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjitL22X86RAPass_translateRetEPNS0_9X86RAPassEPNS0_9CCFuncRetEPNS0_7CBLabelE1948
_ZN4PLMD6asmjitL26X86RAPass_prepareFuncFrameEPNS0_9X86RAPassEPNS0_6CCFuncE1948
_ZN4PLMD6asmjitL30X86RAPass_assignStackArgsRegIdEPNS0_9X86RAPassEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit9X86RAPass8emitSaveEPNS0_7VirtRegEjPKc4004
_ZN4PLMD6asmjit9X86RAPass8emitLoadEPNS0_7VirtRegEjPKc4424
_ZN4PLMD6asmjitL27X86RAPass_translateOperandsEPNS0_9X86RAPassEPNS0_8Operand_Ej32806
_ZN4PLMD6asmjit11X86VarAlloc3runEPNS0_6CBNodeE35054
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc.cpp.func.html b/coverage-libs/asmjit/x86regalloc.cpp.func.html new file mode 100644 index 000000000000..daf333a1ee5d --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc.cpp.func.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:466105544.2 %
Date:2024-02-22 21:58:47Functions:172958.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit11X86VarAlloc3runEPNS0_6CBNodeE35054
_ZN4PLMD6asmjit12X86CallAlloc3runEPNS0_10CCFuncCallE1648
_ZN4PLMD6asmjit9X86RAPass10emitSwapGpEPNS0_7VirtRegES3_jjPKc0
_ZN4PLMD6asmjit9X86RAPass11_checkStateEv0
_ZN4PLMD6asmjit9X86RAPass11switchStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass12emitImmToRegEjjPKNS0_3ImmE420
_ZN4PLMD6asmjit9X86RAPass14emitImmToStackEjPKNS0_6X86MemEPKNS0_3ImmE0
_ZN4PLMD6asmjit9X86RAPass14emitRegToStackEjPKNS0_6X86MemEjj0
_ZN4PLMD6asmjit9X86RAPass15intersectStatesEPNS0_7RAStateES3_0
_ZN4PLMD6asmjit9X86RAPass5fetchEv1948
_ZN4PLMD6asmjit9X86RAPass7prepareEPNS0_6CCFuncE1948
_ZN4PLMD6asmjit9X86RAPass7processEPNS0_4ZoneE1948
_ZN4PLMD6asmjit9X86RAPass8annotateEv0
_ZN4PLMD6asmjit9X86RAPass8emitLoadEPNS0_7VirtRegEjPKc4424
_ZN4PLMD6asmjit9X86RAPass8emitMoveEPNS0_7VirtRegEjjPKc656
_ZN4PLMD6asmjit9X86RAPass8emitSaveEPNS0_7VirtRegEjPKc4004
_ZN4PLMD6asmjit9X86RAPass9loadStateEPNS0_7RAStateE0
_ZN4PLMD6asmjit9X86RAPass9saveStateEv0
_ZN4PLMD6asmjit9X86RAPass9translateEv1948
_ZN4PLMD6asmjit9X86RAPassC2Ev1948
_ZN4PLMD6asmjit9X86RAPassD0Ev0
_ZN4PLMD6asmjit9X86RAPassD2Ev0
_ZN4PLMD6asmjitL22X86RAPass_patchFuncMemEPNS0_9X86RAPassEPNS0_6CCFuncEPNS0_6CBNodeERNS0_15FuncFrameLayoutE1948
_ZN4PLMD6asmjitL22X86RAPass_translateRetEPNS0_9X86RAPassEPNS0_9CCFuncRetEPNS0_7CBLabelE1948
_ZN4PLMD6asmjitL23X86RAPass_translateJumpEPNS0_9X86RAPassEPNS0_6CBJumpEPNS0_7CBLabelE0
_ZN4PLMD6asmjitL26X86RAPass_prepareFuncFrameEPNS0_9X86RAPassEPNS0_6CCFuncE1948
_ZN4PLMD6asmjitL27X86RAPass_translateOperandsEPNS0_9X86RAPassEPNS0_8Operand_Ej32806
_ZN4PLMD6asmjitL30X86RAPass_assignStackArgsRegIdEPNS0_9X86RAPassEPNS0_6CCFuncE1948
_ZN4PLMD6asmjitL30X86RAPass_prepareSingleVarInstEjPNS0_7TiedRegE248
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc.cpp.gcov.html b/coverage-libs/asmjit/x86regalloc.cpp.gcov.html new file mode 100644 index 000000000000..49b07a7514a6 --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc.cpp.gcov.html @@ -0,0 +1,4165 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:466105544.2 %
Date:2024-02-22 21:58:47Functions:172958.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Guard]
+      33             : #include "./asmjit_build.h"
+      34             : #if defined(ASMJIT_BUILD_X86) && !defined(ASMJIT_DISABLE_COMPILER)
+      35             : 
+      36             : // [Dependencies]
+      37             : #include "./cpuinfo.h"
+      38             : #include "./utils.h"
+      39             : #include "./x86assembler.h"
+      40             : #include "./x86compiler.h"
+      41             : #include "./x86internal_p.h"
+      42             : #include "./x86regalloc_p.h"
+      43             : 
+      44             : // [Api-Begin]
+      45             : #include "./asmjit_apibegin.h"
+      46             : 
+      47             : namespace PLMD {
+      48             : namespace asmjit {
+      49             : 
+      50             : // ============================================================================
+      51             : // [Forward Declarations]
+      52             : // ============================================================================
+      53             : 
+      54             : enum { kCompilerDefaultLookAhead = 64 };
+      55             : 
+      56             : static Error X86RAPass_translateOperands(X86RAPass* self, Operand_* opArray, uint32_t opCount);
+      57             : 
+      58             : // ============================================================================
+      59             : // [asmjit::X86RAPass - SpecialInst]
+      60             : // ============================================================================
+      61             : 
+      62             : struct X86SpecialInst {
+      63             :   uint8_t inReg;
+      64             :   uint8_t outReg;
+      65             :   uint16_t flags;
+      66             : };
+      67             : 
+      68             : static ASMJIT_INLINE const X86SpecialInst* X86SpecialInst_get(uint32_t instId, const Operand* opArray, uint32_t opCount) noexcept {
+      69             :   enum { kAny = Globals::kInvalidRegId };
+      70             : 
+      71             : #define R(ri) { uint8_t(ri)  , uint8_t(kAny), uint16_t(TiedReg::kRReg) }
+      72             : #define W(ri) { uint8_t(kAny), uint8_t(ri)  , uint16_t(TiedReg::kWReg) }
+      73             : #define X(ri) { uint8_t(ri)  , uint8_t(ri)  , uint16_t(TiedReg::kXReg) }
+      74             : #define NONE() { uint8_t(kAny), uint8_t(kAny), 0 }
+      75             :   static const X86SpecialInst instCpuid[]        = { X(X86Gp::kIdAx), W(X86Gp::kIdBx), X(X86Gp::kIdCx), W(X86Gp::kIdDx) };
+      76             :   static const X86SpecialInst instCbwCdqeCwde[]  = { X(X86Gp::kIdAx) };
+      77             :   static const X86SpecialInst instCdqCwdCqo[]    = { W(X86Gp::kIdDx), R(X86Gp::kIdAx) };
+      78             :   static const X86SpecialInst instCmpxchg[]      = { X(kAny), R(kAny), X(X86Gp::kIdAx) };
+      79             :   static const X86SpecialInst instCmpxchg8b16b[] = { NONE(), X(X86Gp::kIdDx), X(X86Gp::kIdAx), R(X86Gp::kIdCx), R(X86Gp::kIdBx) };
+      80             :   static const X86SpecialInst instDaaDas[]       = { X(X86Gp::kIdAx) };
+      81             :   static const X86SpecialInst instDiv2[]         = { X(X86Gp::kIdAx), R(kAny) };
+      82             :   static const X86SpecialInst instDiv3[]         = { X(X86Gp::kIdDx), X(X86Gp::kIdAx), R(kAny) };
+      83             :   static const X86SpecialInst instJecxz[]        = { R(X86Gp::kIdCx) };
+      84             :   static const X86SpecialInst instMul2[]         = { X(X86Gp::kIdAx), R(kAny) };
+      85             :   static const X86SpecialInst instMul3[]         = { W(X86Gp::kIdDx), X(X86Gp::kIdAx), R(kAny) };
+      86             :   static const X86SpecialInst instMulx[]         = { W(kAny), W(kAny), R(kAny), R(X86Gp::kIdDx) };
+      87             :   static const X86SpecialInst instLahf[]         = { W(X86Gp::kIdAx) };
+      88             :   static const X86SpecialInst instSahf[]         = { R(X86Gp::kIdAx) };
+      89             :   static const X86SpecialInst instMaskmovq[]     = { R(kAny), R(kAny), R(X86Gp::kIdDi) };
+      90             :   static const X86SpecialInst instRdtscRdtscp[]  = { W(X86Gp::kIdDx), W(X86Gp::kIdAx), W(X86Gp::kIdCx) };
+      91             :   static const X86SpecialInst instRot[]          = { X(kAny), R(X86Gp::kIdCx) };
+      92             :   static const X86SpecialInst instShldShrd[]     = { X(kAny), R(kAny), R(X86Gp::kIdCx) };
+      93             :   static const X86SpecialInst instThirdXMM0[]    = { W(kAny), R(kAny), R(0) };
+      94             :   static const X86SpecialInst instPcmpestri[]    = { R(kAny), R(kAny), NONE(), W(X86Gp::kIdCx) };
+      95             :   static const X86SpecialInst instPcmpestrm[]    = { R(kAny), R(kAny), NONE(), W(0) };
+      96             :   static const X86SpecialInst instPcmpistri[]    = { R(kAny), R(kAny), NONE(), W(X86Gp::kIdCx), R(X86Gp::kIdAx), R(X86Gp::kIdDx) };
+      97             :   static const X86SpecialInst instPcmpistrm[]    = { R(kAny), R(kAny), NONE(), W(0)           , R(X86Gp::kIdAx), R(X86Gp::kIdDx) };
+      98             :   static const X86SpecialInst instXsaveXrstor[]  = { W(kAny), R(X86Gp::kIdDx), R(X86Gp::kIdAx) };
+      99             :   static const X86SpecialInst instReadMR[]       = { W(X86Gp::kIdDx), W(X86Gp::kIdAx), R(X86Gp::kIdCx) };
+     100             :   static const X86SpecialInst instWriteMR[]      = { R(X86Gp::kIdDx), R(X86Gp::kIdAx), R(X86Gp::kIdCx) };
+     101             : 
+     102             :   static const X86SpecialInst instCmps[]         = { X(X86Gp::kIdSi), X(X86Gp::kIdDi) };
+     103             :   static const X86SpecialInst instLods[]         = { W(X86Gp::kIdAx), X(X86Gp::kIdSi) };
+     104             :   static const X86SpecialInst instMovs[]         = { X(X86Gp::kIdDi), X(X86Gp::kIdSi) };
+     105             :   static const X86SpecialInst instScas[]         = { X(X86Gp::kIdDi), R(X86Gp::kIdAx) };
+     106             :   static const X86SpecialInst instStos[]         = { X(X86Gp::kIdDi), R(X86Gp::kIdAx) };
+     107             : #undef NONE
+     108             : #undef X
+     109             : #undef W
+     110             : #undef R
+     111             : 
+     112           0 :   switch (instId) {
+     113             :     case X86Inst::kIdCpuid      : return instCpuid;
+     114           0 :     case X86Inst::kIdCbw        :
+     115             :     case X86Inst::kIdCdqe       :
+     116           0 :     case X86Inst::kIdCwde       : return instCbwCdqeCwde;
+     117           0 :     case X86Inst::kIdCdq        :
+     118             :     case X86Inst::kIdCwd        :
+     119           0 :     case X86Inst::kIdCqo        : return instCdqCwdCqo;
+     120           0 :     case X86Inst::kIdCmps       : return instCmps;
+     121           0 :     case X86Inst::kIdCmpxchg    : return instCmpxchg;
+     122           0 :     case X86Inst::kIdCmpxchg8b  :
+     123           0 :     case X86Inst::kIdCmpxchg16b : return instCmpxchg8b16b;
+     124           0 :     case X86Inst::kIdDaa        :
+     125           0 :     case X86Inst::kIdDas        : return instDaaDas;
+     126           0 :     case X86Inst::kIdDiv        : return (opCount == 2) ? instDiv2 : instDiv3;
+     127           0 :     case X86Inst::kIdIdiv       : return (opCount == 2) ? instDiv2 : instDiv3;
+     128           0 :     case X86Inst::kIdImul       : if (opCount == 2) return nullptr;
+     129           0 :                                   if (opCount == 3 && !(opArray[0].isReg() && opArray[1].isReg() && opArray[2].isRegOrMem())) return nullptr;
+     130             :                                   ASMJIT_FALLTHROUGH;
+     131           0 :     case X86Inst::kIdMul        : return (opCount == 2) ? instMul2 : instMul3;
+     132           0 :     case X86Inst::kIdMulx       : return instMulx;
+     133           0 :     case X86Inst::kIdJecxz      : return instJecxz;
+     134           0 :     case X86Inst::kIdLods       : return instLods;
+     135           0 :     case X86Inst::kIdMovs       : return instMovs;
+     136           0 :     case X86Inst::kIdLahf       : return instLahf;
+     137           0 :     case X86Inst::kIdSahf       : return instSahf;
+     138           0 :     case X86Inst::kIdMaskmovq   :
+     139             :     case X86Inst::kIdMaskmovdqu :
+     140           0 :     case X86Inst::kIdVmaskmovdqu: return instMaskmovq;
+     141             :     case X86Inst::kIdEnter      : return nullptr; // Not supported.
+     142             :     case X86Inst::kIdLeave      : return nullptr; // Not supported.
+     143             :     case X86Inst::kIdRet        : return nullptr; // Not supported.
+     144             :     case X86Inst::kIdMonitor    : return nullptr; // TODO: [COMPILER] Monitor/MWait.
+     145             :     case X86Inst::kIdMwait      : return nullptr; // TODO: [COMPILER] Monitor/MWait.
+     146             :     case X86Inst::kIdPop        : return nullptr; // TODO: [COMPILER] Pop/Push.
+     147             :     case X86Inst::kIdPush       : return nullptr; // TODO: [COMPILER] Pop/Push.
+     148             :     case X86Inst::kIdPopa       : return nullptr; // Not supported.
+     149             :     case X86Inst::kIdPopf       : return nullptr; // Not supported.
+     150             :     case X86Inst::kIdPusha      : return nullptr; // Not supported.
+     151             :     case X86Inst::kIdPushf      : return nullptr; // Not supported.
+     152           0 :     case X86Inst::kIdRcl        :
+     153             :     case X86Inst::kIdRcr        :
+     154             :     case X86Inst::kIdRol        :
+     155             :     case X86Inst::kIdRor        :
+     156             :     case X86Inst::kIdSal        :
+     157             :     case X86Inst::kIdSar        :
+     158             :     case X86Inst::kIdShl        : // Rot instruction is special only if the last operand is a variable.
+     159           0 :     case X86Inst::kIdShr        : if (!opArray[1].isReg()) return nullptr;
+     160             :                                   return instRot;
+     161           0 :     case X86Inst::kIdShld       : // Shld/Shrd instruction is special only if the last operand is a variable.
+     162           0 :     case X86Inst::kIdShrd       : if (!opArray[2].isReg()) return nullptr;
+     163             :                                   return instShldShrd;
+     164           0 :     case X86Inst::kIdRdtsc      :
+     165           0 :     case X86Inst::kIdRdtscp     : return instRdtscRdtscp;
+     166           0 :     case X86Inst::kIdScas       : return instScas;
+     167           0 :     case X86Inst::kIdStos       : return instStos;
+     168           0 :     case X86Inst::kIdBlendvpd   :
+     169             :     case X86Inst::kIdBlendvps   :
+     170             :     case X86Inst::kIdPblendvb   :
+     171           0 :     case X86Inst::kIdSha256rnds2: return instThirdXMM0;
+     172           0 :     case X86Inst::kIdPcmpestri  :
+     173           0 :     case X86Inst::kIdVpcmpestri : return instPcmpestri;
+     174           0 :     case X86Inst::kIdPcmpistri  :
+     175           0 :     case X86Inst::kIdVpcmpistri : return instPcmpistri;
+     176           0 :     case X86Inst::kIdPcmpestrm  :
+     177           0 :     case X86Inst::kIdVpcmpestrm : return instPcmpestrm;
+     178           0 :     case X86Inst::kIdPcmpistrm  :
+     179           0 :     case X86Inst::kIdVpcmpistrm : return instPcmpistrm;
+     180           0 :     case X86Inst::kIdXrstor     :
+     181             :     case X86Inst::kIdXrstor64   :
+     182             :     case X86Inst::kIdXsave      :
+     183             :     case X86Inst::kIdXsave64    :
+     184             :     case X86Inst::kIdXsaveopt   :
+     185           0 :     case X86Inst::kIdXsaveopt64 : return instXsaveXrstor;
+     186           0 :     case X86Inst::kIdRdmsr      :
+     187             :     case X86Inst::kIdRdpmc      :
+     188           0 :     case X86Inst::kIdXgetbv     : return instReadMR;
+     189           0 :     case X86Inst::kIdWrmsr      :
+     190           0 :     case X86Inst::kIdXsetbv     : return instWriteMR;
+     191             :     default                     : return nullptr;
+     192             :   }
+     193             : }
+     194             : 
+     195             : // ============================================================================
+     196             : // [asmjit::X86RAPass - Construction / Destruction]
+     197             : // ============================================================================
+     198             : 
+     199        1948 : X86RAPass::X86RAPass() noexcept : RAPass() {
+     200        1948 :   _state = &_x86State;
+     201        1948 :   _varMapToVaListOffset = ASMJIT_OFFSET_OF(X86RAData, tiedArray);
+     202        1948 : }
+     203           0 : X86RAPass::~X86RAPass() noexcept {}
+     204             : 
+     205             : // ============================================================================
+     206             : // [asmjit::X86RAPass - Interface]
+     207             : // ============================================================================
+     208             : 
+     209        1948 : Error X86RAPass::process(Zone* zone) noexcept {
+     210        1948 :   return Base::process(zone);
+     211             : }
+     212             : 
+     213        1948 : Error X86RAPass::prepare(CCFunc* func) noexcept {
+     214        1948 :   ASMJIT_PROPAGATE(Base::prepare(func));
+     215             : 
+     216             :   uint32_t archType = cc()->getArchType();
+     217        1948 :   _regCount._gp  = archType == ArchInfo::kTypeX86 ? 8 : 16;
+     218        1948 :   _regCount._mm  = 8;
+     219        1948 :   _regCount._k   = 8;
+     220        1948 :   _regCount._vec = archType == ArchInfo::kTypeX86 ? 8 : 16;
+     221             :   _zsp = cc()->zsp();
+     222             :   _zbp = cc()->zbp();
+     223             : 
+     224        1948 :   _gaRegs[X86Reg::kKindGp ] = Utils::bits(_regCount.getGp()) & ~Utils::mask(X86Gp::kIdSp);
+     225        1948 :   _gaRegs[X86Reg::kKindMm ] = Utils::bits(_regCount.getMm());
+     226        1948 :   _gaRegs[X86Reg::kKindK  ] = Utils::bits(_regCount.getK());
+     227        1948 :   _gaRegs[X86Reg::kKindVec] = Utils::bits(_regCount.getVec());
+     228             : 
+     229        1948 :   _x86State.reset(0);
+     230             :   _clobberedRegs.reset();
+     231             : 
+     232        1948 :   _avxEnabled = false;
+     233             : 
+     234        1948 :   _varBaseRegId = Globals::kInvalidRegId; // Used by patcher.
+     235        1948 :   _varBaseOffset = 0;                     // Used by patcher.
+     236             : 
+     237        1948 :   return kErrorOk;
+     238             : }
+     239             : 
+     240             : // ============================================================================
+     241             : // [asmjit::X86RAPass - Emit]
+     242             : // ============================================================================
+     243             : 
+     244         656 : Error X86RAPass::emitMove(VirtReg* vReg, uint32_t dstId, uint32_t srcId, const char* reason) {
+     245             :   const char* comment = nullptr;
+     246         656 :   if (_emitComments) {
+     247           0 :     _stringBuilder.setFormat("[%s] %s", reason, vReg->getName());
+     248             :     comment = _stringBuilder.getData();
+     249             :   }
+     250             : 
+     251             :   X86Reg dst(X86Reg::fromSignature(vReg->getSignature(), dstId));
+     252             :   X86Reg src(X86Reg::fromSignature(vReg->getSignature(), srcId));
+     253         656 :   return X86Internal::emitRegMove(reinterpret_cast<X86Emitter*>(cc()), dst, src, vReg->getTypeId(), _avxEnabled, comment);
+     254             : }
+     255             : 
+     256        4424 : Error X86RAPass::emitLoad(VirtReg* vReg, uint32_t id, const char* reason) {
+     257             :   const char* comment = nullptr;
+     258        4424 :   if (_emitComments) {
+     259           0 :     _stringBuilder.setFormat("[%s] %s", reason, vReg->getName());
+     260             :     comment = _stringBuilder.getData();
+     261             :   }
+     262             : 
+     263             :   X86Reg dst(X86Reg::fromSignature(vReg->getSignature(), id));
+     264             :   X86Mem src(getVarMem(vReg));
+     265        4424 :   return X86Internal::emitRegMove(reinterpret_cast<X86Emitter*>(cc()), dst, src, vReg->getTypeId(), _avxEnabled, comment);
+     266             : }
+     267             : 
+     268        4004 : Error X86RAPass::emitSave(VirtReg* vReg, uint32_t id, const char* reason) {
+     269             :   const char* comment = nullptr;
+     270        4004 :   if (_emitComments) {
+     271           0 :     _stringBuilder.setFormat("[%s] %s", reason, vReg->getName());
+     272             :     comment = _stringBuilder.getData();
+     273             :   }
+     274             : 
+     275             :   X86Mem dst(getVarMem(vReg));
+     276             :   X86Reg src(X86Reg::fromSignature(vReg->getSignature(), id));
+     277        4004 :   return X86Internal::emitRegMove(reinterpret_cast<X86Emitter*>(cc()), dst, src, vReg->getTypeId(), _avxEnabled, comment);
+     278             : }
+     279             : 
+     280           0 : Error X86RAPass::emitSwapGp(VirtReg* dstReg, VirtReg* srcReg, uint32_t dstPhysId, uint32_t srcPhysId, const char* reason) noexcept {
+     281             :   ASMJIT_ASSERT(dstPhysId != Globals::kInvalidRegId);
+     282             :   ASMJIT_ASSERT(srcPhysId != Globals::kInvalidRegId);
+     283             : 
+     284           0 :   uint32_t is64 = std::max(dstReg->getTypeId(), srcReg->getTypeId()) >= TypeId::kI64;
+     285           0 :   uint32_t sign = is64 ? uint32_t(X86RegTraits<X86Reg::kRegGpq>::kSignature)
+     286             :                        : uint32_t(X86RegTraits<X86Reg::kRegGpd>::kSignature);
+     287             : 
+     288             :   X86Reg a = X86Reg::fromSignature(sign, dstPhysId);
+     289             :   X86Reg b = X86Reg::fromSignature(sign, srcPhysId);
+     290             : 
+     291           0 :   ASMJIT_PROPAGATE(cc()->emit(X86Inst::kIdXchg, a, b));
+     292           0 :   if (_emitComments)
+     293           0 :     cc()->getCursor()->setInlineComment(cc()->_cbDataZone.sformat("[%s] %s, %s", reason, dstReg->getName(), srcReg->getName()));
+     294             :   return kErrorOk;
+     295             : }
+     296             : 
+     297         420 : Error X86RAPass::emitImmToReg(uint32_t dstTypeId, uint32_t dstPhysId, const Imm* src) noexcept {
+     298             :   ASMJIT_ASSERT(dstPhysId != Globals::kInvalidRegId);
+     299             : 
+     300             :   X86Reg r0;
+     301             :   Imm imm(*src);
+     302             : 
+     303         420 :   switch (dstTypeId) {
+     304             :     case TypeId::kI8:
+     305             :     case TypeId::kU8:
+     306             :       imm.truncateTo8Bits();
+     307             :       ASMJIT_FALLTHROUGH;
+     308             : 
+     309           0 :     case TypeId::kI16:
+     310             :     case TypeId::kU16:
+     311             :       imm.truncateTo16Bits();
+     312             :       ASMJIT_FALLTHROUGH;
+     313             : 
+     314             :     case TypeId::kI32:
+     315             :     case TypeId::kU32:
+     316           0 : Mov32Truncate:
+     317             :       imm.truncateTo32Bits();
+     318             :       r0.setX86RegT<X86Reg::kRegGpd>(dstPhysId);
+     319           0 :       cc()->emit(X86Inst::kIdMov, r0, imm);
+     320           0 :       break;
+     321             : 
+     322             :     case TypeId::kI64:
+     323             :     case TypeId::kU64:
+     324             :       // Move to GPD register will also clear the high DWORD of GPQ
+     325             :       // register in 64-bit mode.
+     326         420 :       if (imm.isUInt32())
+     327           0 :         goto Mov32Truncate;
+     328             : 
+     329             :       r0.setX86RegT<X86Reg::kRegGpq>(dstPhysId);
+     330         420 :       cc()->emit(X86Inst::kIdMov, r0, imm);
+     331         420 :       break;
+     332             : 
+     333             :     case TypeId::kF32:
+     334             :     case TypeId::kF64:
+     335             :       // Compiler doesn't manage FPU stack.
+     336             :       ASMJIT_NOT_REACHED();
+     337             :       break;
+     338             : 
+     339             :     case TypeId::kMmx32:
+     340             :     case TypeId::kMmx64:
+     341             :       // TODO: [COMPILER] EmitMoveImmToReg.
+     342             :       break;
+     343             : 
+     344             :     default:
+     345             :       // TODO: [COMPILER] EmitMoveImmToReg.
+     346             :       break;
+     347             :   }
+     348             : 
+     349         420 :   return kErrorOk;
+     350             : }
+     351             : 
+     352           0 : Error X86RAPass::emitImmToStack(uint32_t dstTypeId, const X86Mem* dst, const Imm* src) noexcept {
+     353             :   X86Mem mem(*dst);
+     354             :   Imm imm(*src);
+     355             : 
+     356             :   // One stack entry has the same size as the native register size. That means
+     357             :   // that if we want to move a 32-bit integer on the stack in 64-bit mode, we
+     358             :   // need to extend it to a 64-bit integer first. In 32-bit mode, pushing a
+     359             :   // 64-bit on stack is done in two steps by pushing low and high parts
+     360             :   // separately.
+     361             :   uint32_t gpSize = cc()->getGpSize();
+     362             : 
+     363           0 :   switch (dstTypeId) {
+     364             :     case TypeId::kI8:
+     365             :     case TypeId::kU8:
+     366             :       imm.truncateTo8Bits();
+     367             :       ASMJIT_FALLTHROUGH;
+     368             : 
+     369           0 :     case TypeId::kI16:
+     370             :     case TypeId::kU16:
+     371             :       imm.truncateTo16Bits();
+     372             :       ASMJIT_FALLTHROUGH;
+     373             : 
+     374           0 :     case TypeId::kI32:
+     375             :     case TypeId::kU32:
+     376             :     case TypeId::kF32:
+     377             :       mem.setSize(4);
+     378             :       imm.truncateTo32Bits();
+     379           0 :       cc()->emit(X86Inst::kIdMov, mem, imm);
+     380           0 :       break;
+     381             : 
+     382           0 :     case TypeId::kI64:
+     383             :     case TypeId::kU64:
+     384             :     case TypeId::kF64:
+     385             :     case TypeId::kMmx32:
+     386             :     case TypeId::kMmx64:
+     387           0 :       if (gpSize == 4) {
+     388             :         uint32_t hi = imm.getUInt32Hi();
+     389             : 
+     390             :         // Lo-Part.
+     391             :         mem.setSize(4);
+     392             :         imm.truncateTo32Bits();
+     393             : 
+     394           0 :         cc()->emit(X86Inst::kIdMov, mem, imm);
+     395             :         mem.addOffsetLo32(gpSize);
+     396             : 
+     397             :         // Hi-Part.
+     398             :         imm.setUInt32(hi);
+     399           0 :         cc()->emit(X86Inst::kIdMov, mem, imm);
+     400             :       }
+     401             :       else {
+     402             :         mem.setSize(8);
+     403           0 :         cc()->emit(X86Inst::kIdMov, mem, imm);
+     404             :       }
+     405             :       break;
+     406             : 
+     407             :     default:
+     408             :       return DebugUtils::errored(kErrorInvalidState);
+     409             :   }
+     410             : 
+     411             :   return kErrorOk;
+     412             : }
+     413             : 
+     414           0 : Error X86RAPass::emitRegToStack(uint32_t dstTypeId, const X86Mem* dst, uint32_t srcTypeId, uint32_t srcPhysId) noexcept {
+     415             :   ASMJIT_ASSERT(srcPhysId != Globals::kInvalidRegId);
+     416             : 
+     417             :   X86Mem m0(*dst);
+     418             :   X86Reg r0, r1;
+     419             : 
+     420             :   uint32_t gpSize = cc()->getGpSize();
+     421             :   uint32_t instId = 0;
+     422             : 
+     423           0 :   switch (dstTypeId) {
+     424             :     case TypeId::kI64:
+     425             :     case TypeId::kU64:
+     426             :       // Extend BYTE->QWORD (GP).
+     427           0 :       if (TypeId::isGpb(srcTypeId)) {
+     428             :         r1.setX86RegT<X86Reg::kRegGpbLo>(srcPhysId);
+     429             : 
+     430           0 :         instId = (dstTypeId == TypeId::kI64 && srcTypeId == TypeId::kI8) ? X86Inst::kIdMovsx : X86Inst::kIdMovzx;
+     431           0 :         goto _ExtendMovGpXQ;
+     432             :       }
+     433             : 
+     434             :       // Extend WORD->QWORD (GP).
+     435             :       if (TypeId::isGpw(srcTypeId)) {
+     436             :         r1.setX86RegT<X86Reg::kRegGpw>(srcPhysId);
+     437             : 
+     438           0 :         instId = (dstTypeId == TypeId::kI64 && srcTypeId == TypeId::kI16) ? X86Inst::kIdMovsx : X86Inst::kIdMovzx;
+     439           0 :         goto _ExtendMovGpXQ;
+     440             :       }
+     441             : 
+     442             :       // Extend DWORD->QWORD (GP).
+     443             :       if (TypeId::isGpd(srcTypeId)) {
+     444             :         r1.setX86RegT<X86Reg::kRegGpd>(srcPhysId);
+     445             : 
+     446             :         instId = X86Inst::kIdMovsxd;
+     447           0 :         if (dstTypeId == TypeId::kI64 && srcTypeId == TypeId::kI32)
+     448           0 :           goto _ExtendMovGpXQ;
+     449             :         else
+     450           0 :           goto _ZeroExtendGpDQ;
+     451             :       }
+     452             : 
+     453             :       // Move QWORD (GP).
+     454           0 :       if (TypeId::isGpq(srcTypeId)) goto MovGpQ;
+     455           0 :       if (TypeId::isMmx(srcTypeId)) goto MovMmQ;
+     456           0 :       if (TypeId::isVec(srcTypeId)) goto MovXmmQ;
+     457             :       break;
+     458             : 
+     459             :     case TypeId::kI32:
+     460             :     case TypeId::kU32:
+     461             :     case TypeId::kI16:
+     462             :     case TypeId::kU16:
+     463             :       // DWORD <- WORD (Zero|Sign Extend).
+     464           0 :       if (TypeId::isGpw(srcTypeId)) {
+     465           0 :         bool isDstSigned = dstTypeId == TypeId::kI16 || dstTypeId == TypeId::kI32;
+     466           0 :         bool isSrcSigned = srcTypeId == TypeId::kI8  || srcTypeId == TypeId::kI16;
+     467             : 
+     468             :         r1.setX86RegT<X86Reg::kRegGpw>(srcPhysId);
+     469           0 :         instId = isDstSigned && isSrcSigned ? X86Inst::kIdMovsx : X86Inst::kIdMovzx;
+     470           0 :         goto _ExtendMovGpD;
+     471             :       }
+     472             : 
+     473             :       // DWORD <- BYTE (Zero|Sign Extend).
+     474           0 :       if (TypeId::isGpb(srcTypeId)) {
+     475           0 :         bool isDstSigned = dstTypeId == TypeId::kI16 || dstTypeId == TypeId::kI32;
+     476           0 :         bool isSrcSigned = srcTypeId == TypeId::kI8  || srcTypeId == TypeId::kI16;
+     477             : 
+     478             :         r1.setX86RegT<X86Reg::kRegGpbLo>(srcPhysId);
+     479           0 :         instId = isDstSigned && isSrcSigned ? X86Inst::kIdMovsx : X86Inst::kIdMovzx;
+     480           0 :         goto _ExtendMovGpD;
+     481             :       }
+     482             :       ASMJIT_FALLTHROUGH;
+     483             : 
+     484             :     case TypeId::kI8:
+     485             :     case TypeId::kU8:
+     486           0 :       if (TypeId::isInt(srcTypeId)) goto MovGpD;
+     487           0 :       if (TypeId::isMmx(srcTypeId)) goto MovMmD;
+     488           0 :       if (TypeId::isVec(srcTypeId)) goto MovXmmD;
+     489             :       break;
+     490             : 
+     491             :     case TypeId::kMmx32:
+     492             :     case TypeId::kMmx64:
+     493             :       // Extend BYTE->QWORD (GP).
+     494           0 :       if (TypeId::isGpb(srcTypeId)) {
+     495             :         r1.setX86RegT<X86Reg::kRegGpbLo>(srcPhysId);
+     496             : 
+     497             :         instId = X86Inst::kIdMovzx;
+     498           0 :         goto _ExtendMovGpXQ;
+     499             :       }
+     500             : 
+     501             :       // Extend WORD->QWORD (GP).
+     502             :       if (TypeId::isGpw(srcTypeId)) {
+     503             :         r1.setX86RegT<X86Reg::kRegGpw>(srcPhysId);
+     504             : 
+     505             :         instId = X86Inst::kIdMovzx;
+     506           0 :         goto _ExtendMovGpXQ;
+     507             :       }
+     508             : 
+     509           0 :       if (TypeId::isGpd(srcTypeId)) goto _ExtendMovGpDQ;
+     510           0 :       if (TypeId::isGpq(srcTypeId)) goto MovGpQ;
+     511           0 :       if (TypeId::isMmx(srcTypeId)) goto MovMmQ;
+     512           0 :       if (TypeId::isVec(srcTypeId)) goto MovXmmQ;
+     513             :       break;
+     514             : 
+     515             :     case TypeId::kF32:
+     516             :     case TypeId::kF32x1:
+     517           0 :       if (TypeId::isVec(srcTypeId)) goto MovXmmD;
+     518             :       break;
+     519             : 
+     520             :     case TypeId::kF64:
+     521             :     case TypeId::kF64x1:
+     522           0 :       if (TypeId::isVec(srcTypeId)) goto MovXmmQ;
+     523             :       break;
+     524             : 
+     525             :     default:
+     526             :       // TODO: Vector types by stack.
+     527             :       break;
+     528             :   }
+     529             :   return DebugUtils::errored(kErrorInvalidState);
+     530             : 
+     531             :   // Extend+Move Gp.
+     532           0 : _ExtendMovGpD:
+     533             :   m0.setSize(4);
+     534             :   r0.setX86RegT<X86Reg::kRegGpd>(srcPhysId);
+     535             : 
+     536           0 :   cc()->emit(instId, r0, r1);
+     537           0 :   cc()->emit(X86Inst::kIdMov, m0, r0);
+     538           0 :   return kErrorOk;
+     539             : 
+     540           0 : _ExtendMovGpXQ:
+     541           0 :   if (gpSize == 8) {
+     542             :     m0.setSize(8);
+     543             :     r0.setX86RegT<X86Reg::kRegGpq>(srcPhysId);
+     544             : 
+     545           0 :     cc()->emit(instId, r0, r1);
+     546           0 :     cc()->emit(X86Inst::kIdMov, m0, r0);
+     547             :   }
+     548             :   else {
+     549             :     m0.setSize(4);
+     550             :     r0.setX86RegT<X86Reg::kRegGpd>(srcPhysId);
+     551             : 
+     552           0 :     cc()->emit(instId, r0, r1);
+     553             : 
+     554           0 : _ExtendMovGpDQ:
+     555           0 :     cc()->emit(X86Inst::kIdMov, m0, r0);
+     556             :     m0.addOffsetLo32(4);
+     557           0 :     cc()->emit(X86Inst::kIdAnd, m0, 0);
+     558             :   }
+     559             :   return kErrorOk;
+     560             : 
+     561             : _ZeroExtendGpDQ:
+     562             :   m0.setSize(4);
+     563             :   r0.setX86RegT<X86Reg::kRegGpd>(srcPhysId);
+     564           0 :   goto _ExtendMovGpDQ;
+     565             : 
+     566             :   // Move Gp.
+     567             : MovGpD:
+     568             :   m0.setSize(4);
+     569             :   r0.setX86RegT<X86Reg::kRegGpd>(srcPhysId);
+     570           0 :   return cc()->emit(X86Inst::kIdMov, m0, r0);
+     571             : 
+     572           0 : MovGpQ:
+     573             :   m0.setSize(8);
+     574             :   r0.setX86RegT<X86Reg::kRegGpq>(srcPhysId);
+     575           0 :   return cc()->emit(X86Inst::kIdMov, m0, r0);
+     576             : 
+     577             :   // Move Mm.
+     578             : MovMmD:
+     579             :   m0.setSize(4);
+     580             :   r0.setX86RegT<X86Reg::kRegMm>(srcPhysId);
+     581           0 :   return cc()->emit(X86Inst::kIdMovd, m0, r0);
+     582             : 
+     583           0 : MovMmQ:
+     584             :   m0.setSize(8);
+     585             :   r0.setX86RegT<X86Reg::kRegMm>(srcPhysId);
+     586           0 :   return cc()->emit(X86Inst::kIdMovq, m0, r0);
+     587             : 
+     588             :   // Move XMM.
+     589           0 : MovXmmD:
+     590             :   m0.setSize(4);
+     591             :   r0.setX86RegT<X86Reg::kRegXmm>(srcPhysId);
+     592           0 :   return cc()->emit(X86Inst::kIdMovss, m0, r0);
+     593             : 
+     594           0 : MovXmmQ:
+     595             :   m0.setSize(8);
+     596             :   r0.setX86RegT<X86Reg::kRegXmm>(srcPhysId);
+     597           0 :   return cc()->emit(X86Inst::kIdMovlps, m0, r0);
+     598             : }
+     599             : 
+     600             : // ============================================================================
+     601             : // [asmjit::X86RAPass - Register Management]
+     602             : // ============================================================================
+     603             : 
+     604             : #if defined(ASMJIT_DEBUG)
+     605             : template<int C>
+     606             : static ASMJIT_INLINE void X86RAPass_checkStateVars(X86RAPass* self) {
+     607             :   X86RAState* state = self->getState();
+     608             :   VirtReg** sVars = state->getListByKind(C);
+     609             : 
+     610             :   uint32_t physId;
+     611             :   uint32_t regMask;
+     612             :   uint32_t regCount = self->_regCount.get(C);
+     613             : 
+     614             :   uint32_t occupied = state->_occupied.get(C);
+     615             :   uint32_t modified = state->_modified.get(C);
+     616             : 
+     617             :   for (physId = 0, regMask = 1; physId < regCount; physId++, regMask <<= 1) {
+     618             :     VirtReg* vreg = sVars[physId];
+     619             : 
+     620             :     if (!vreg) {
+     621             :       ASMJIT_ASSERT((occupied & regMask) == 0);
+     622             :       ASMJIT_ASSERT((modified & regMask) == 0);
+     623             :     }
+     624             :     else {
+     625             :       ASMJIT_ASSERT((occupied & regMask) != 0);
+     626             :       ASMJIT_ASSERT((modified & regMask) == (static_cast<uint32_t>(vreg->isModified()) << physId));
+     627             : 
+     628             :       ASMJIT_ASSERT(vreg->getKind() == C);
+     629             :       ASMJIT_ASSERT(vreg->getState() == VirtReg::kStateReg);
+     630             :       ASMJIT_ASSERT(vreg->getPhysId() == physId);
+     631             :     }
+     632             :   }
+     633             : }
+     634             : 
+     635             : void X86RAPass::_checkState() {
+     636             :   X86RAPass_checkStateVars<X86Reg::kKindGp >(this);
+     637             :   X86RAPass_checkStateVars<X86Reg::kKindMm >(this);
+     638             :   X86RAPass_checkStateVars<X86Reg::kKindVec>(this);
+     639             : }
+     640             : #else
+     641           0 : void X86RAPass::_checkState() {}
+     642             : #endif // ASMJIT_DEBUG
+     643             : 
+     644             : // ============================================================================
+     645             : // [asmjit::X86RAPass - State - Load]
+     646             : // ============================================================================
+     647             : 
+     648             : template<int C>
+     649             : static ASMJIT_INLINE void X86RAPass_loadStateVars(X86RAPass* self, X86RAState* src) {
+     650             :   X86RAState* cur = self->getState();
+     651             : 
+     652             :   VirtReg** cVars = cur->getListByKind(C);
+     653             :   VirtReg** sVars = src->getListByKind(C);
+     654             : 
+     655             :   uint32_t physId;
+     656             :   uint32_t modified = src->_modified.get(C);
+     657             :   uint32_t regCount = self->_regCount.get(C);
+     658             : 
+     659           0 :   for (physId = 0; physId < regCount; physId++, modified >>= 1) {
+     660           0 :     VirtReg* vreg = sVars[physId];
+     661           0 :     cVars[physId] = vreg;
+     662           0 :     if (!vreg) continue;
+     663             : 
+     664             :     vreg->setState(VirtReg::kStateReg);
+     665             :     vreg->setPhysId(physId);
+     666           0 :     vreg->setModified(modified & 0x1);
+     667             :   }
+     668             : }
+     669             : 
+     670           0 : void X86RAPass::loadState(RAState* src_) {
+     671             :   X86RAState* cur = getState();
+     672             :   X86RAState* src = static_cast<X86RAState*>(src_);
+     673             : 
+     674             :   VirtReg** vregs = _contextVd.getData();
+     675           0 :   uint32_t count = static_cast<uint32_t>(_contextVd.getLength());
+     676             : 
+     677             :   // Load allocated variables.
+     678             :   X86RAPass_loadStateVars<X86Reg::kKindGp >(this, src);
+     679             :   X86RAPass_loadStateVars<X86Reg::kKindMm >(this, src);
+     680             :   X86RAPass_loadStateVars<X86Reg::kKindVec>(this, src);
+     681             : 
+     682             :   // Load masks.
+     683           0 :   cur->_occupied = src->_occupied;
+     684           0 :   cur->_modified = src->_modified;
+     685             : 
+     686             :   // Load states of other variables and clear their 'Modified' flags.
+     687           0 :   for (uint32_t i = 0; i < count; i++) {
+     688             :     uint32_t vState = src->_cells[i].getState();
+     689             : 
+     690           0 :     if (vState == VirtReg::kStateReg)
+     691           0 :       continue;
+     692             : 
+     693           0 :     vregs[i]->setState(vState);
+     694           0 :     vregs[i]->setPhysId(Globals::kInvalidRegId);
+     695           0 :     vregs[i]->setModified(false);
+     696             :   }
+     697             : 
+     698             :   ASMJIT_X86_CHECK_STATE
+     699           0 : }
+     700             : 
+     701             : // ============================================================================
+     702             : // [asmjit::X86RAPass - State - Save]
+     703             : // ============================================================================
+     704             : 
+     705           0 : RAState* X86RAPass::saveState() {
+     706             :   VirtReg** vregs = _contextVd.getData();
+     707           0 :   uint32_t count = static_cast<uint32_t>(_contextVd.getLength());
+     708             : 
+     709             :   size_t size = Utils::alignTo<size_t>(
+     710             :     sizeof(X86RAState) + count * sizeof(X86StateCell), sizeof(void*));
+     711             : 
+     712             :   X86RAState* cur = getState();
+     713           0 :   X86RAState* dst = _zone->allocT<X86RAState>(size);
+     714           0 :   if (!dst) return nullptr;
+     715             : 
+     716             :   // Store links.
+     717           0 :   ::memcpy(dst->_list, cur->_list, X86RAState::kAllCount * sizeof(VirtReg*));
+     718             : 
+     719             :   // Store masks.
+     720           0 :   dst->_occupied = cur->_occupied;
+     721           0 :   dst->_modified = cur->_modified;
+     722             : 
+     723             :   // Store cells.
+     724           0 :   for (uint32_t i = 0; i < count; i++) {
+     725           0 :     VirtReg* vreg = static_cast<VirtReg*>(vregs[i]);
+     726             :     X86StateCell& cell = dst->_cells[i];
+     727             : 
+     728             :     cell.reset();
+     729             :     cell.setState(vreg->getState());
+     730             :   }
+     731             : 
+     732             :   return dst;
+     733             : }
+     734             : 
+     735             : // ============================================================================
+     736             : // [asmjit::X86RAPass - State - Switch]
+     737             : // ============================================================================
+     738             : 
+     739             : template<int C>
+     740             : static ASMJIT_INLINE void X86RAPass_switchStateVars(X86RAPass* self, X86RAState* src) {
+     741             :   X86RAState* dst = self->getState();
+     742             : 
+     743             :   VirtReg** dVars = dst->getListByKind(C);
+     744             :   VirtReg** sVars = src->getListByKind(C);
+     745             : 
+     746           0 :   X86StateCell* cells = src->_cells;
+     747             :   uint32_t regCount = self->_regCount.get(C);
+     748             :   bool didWork;
+     749             : 
+     750           0 :   do {
+     751             :     didWork = false;
+     752             : 
+     753           0 :     for (uint32_t physId = 0, regMask = 0x1; physId < regCount; physId++, regMask <<= 1) {
+     754           0 :       VirtReg* dVReg = dVars[physId];
+     755           0 :       VirtReg* sVd = sVars[physId];
+     756           0 :       if (dVReg == sVd) continue;
+     757             : 
+     758           0 :       if (dVReg) {
+     759           0 :         const X86StateCell& cell = cells[dVReg->_raId];
+     760             : 
+     761           0 :         if (cell.getState() != VirtReg::kStateReg) {
+     762           0 :           if (cell.getState() == VirtReg::kStateMem)
+     763             :             self->spill<C>(dVReg);
+     764             :           else
+     765             :             self->unuse<C>(dVReg);
+     766             : 
+     767             :           dVReg = nullptr;
+     768             :           didWork = true;
+     769           0 :           if (!sVd) continue;
+     770             :         }
+     771             :       }
+     772             : 
+     773           0 :       if (!dVReg && sVd) {
+     774           0 : _MoveOrLoad:
+     775           0 :         if (sVd->getPhysId() != Globals::kInvalidRegId)
+     776             :           self->move<C>(sVd, physId);
+     777             :         else
+     778             :           self->load<C>(sVd, physId);
+     779             : 
+     780             :         didWork = true;
+     781           0 :         continue;
+     782             :       }
+     783             : 
+     784           0 :       if (dVReg) {
+     785           0 :         const X86StateCell& cell = cells[dVReg->_raId];
+     786           0 :         if (!sVd) {
+     787           0 :           if (cell.getState() == VirtReg::kStateReg)
+     788           0 :             continue;
+     789             : 
+     790           0 :           if (cell.getState() == VirtReg::kStateMem)
+     791             :             self->spill<C>(dVReg);
+     792             :           else
+     793             :             self->unuse<C>(dVReg);
+     794             : 
+     795             :           didWork = true;
+     796           0 :           continue;
+     797             :         }
+     798             :         else {
+     799           0 :           if (cell.getState() == VirtReg::kStateReg) {
+     800           0 :             if (dVReg->getPhysId() != Globals::kInvalidRegId && sVd->getPhysId() != Globals::kInvalidRegId) {
+     801             :               if (C == X86Reg::kKindGp) {
+     802             :                 self->swapGp(dVReg, sVd);
+     803             :               }
+     804             :               else {
+     805             :                 self->spill<C>(dVReg);
+     806             :                 self->move<C>(sVd, physId);
+     807             :               }
+     808             : 
+     809             :               didWork = true;
+     810           0 :               continue;
+     811             :             }
+     812             :             else {
+     813             :               didWork = true;
+     814           0 :               continue;
+     815             :             }
+     816             :           }
+     817             : 
+     818           0 :           if (cell.getState() == VirtReg::kStateMem)
+     819             :             self->spill<C>(dVReg);
+     820             :           else
+     821             :             self->unuse<C>(dVReg);
+     822           0 :           goto _MoveOrLoad;
+     823             :         }
+     824             :       }
+     825             :     }
+     826             :   } while (didWork);
+     827             : 
+     828             :   uint32_t dModified = dst->_modified.get(C);
+     829             :   uint32_t sModified = src->_modified.get(C);
+     830             : 
+     831           0 :   if (dModified != sModified) {
+     832           0 :     for (uint32_t physId = 0, regMask = 0x1; physId < regCount; physId++, regMask <<= 1) {
+     833           0 :       VirtReg* vreg = dVars[physId];
+     834           0 :       if (!vreg) continue;
+     835             : 
+     836           0 :       if ((dModified & regMask) && !(sModified & regMask)) {
+     837             :         self->save<C>(vreg);
+     838           0 :         continue;
+     839             :       }
+     840             : 
+     841           0 :       if (!(dModified & regMask) && (sModified & regMask)) {
+     842             :         self->modify<C>(vreg);
+     843           0 :         continue;
+     844             :       }
+     845             :     }
+     846             :   }
+     847             : }
+     848             : 
+     849           0 : void X86RAPass::switchState(RAState* src_) {
+     850             :   ASMJIT_ASSERT(src_ != nullptr);
+     851             : 
+     852             :   X86RAState* cur = getState();
+     853             :   X86RAState* src = static_cast<X86RAState*>(src_);
+     854             : 
+     855             :   // Ignore if both states are equal.
+     856           0 :   if (cur == src)
+     857             :     return;
+     858             : 
+     859             :   // Switch variables.
+     860             :   X86RAPass_switchStateVars<X86Reg::kKindGp >(this, src);
+     861             :   X86RAPass_switchStateVars<X86Reg::kKindMm >(this, src);
+     862             :   X86RAPass_switchStateVars<X86Reg::kKindVec>(this, src);
+     863             : 
+     864             :   // Calculate changed state.
+     865             :   VirtReg** vregs = _contextVd.getData();
+     866           0 :   uint32_t count = static_cast<uint32_t>(_contextVd.getLength());
+     867             : 
+     868             :   X86StateCell* cells = src->_cells;
+     869           0 :   for (uint32_t i = 0; i < count; i++) {
+     870           0 :     VirtReg* vreg = static_cast<VirtReg*>(vregs[i]);
+     871           0 :     const X86StateCell& cell = cells[i];
+     872             :     uint32_t vState = cell.getState();
+     873             : 
+     874           0 :     if (vState != VirtReg::kStateReg) {
+     875             :       vreg->setState(vState);
+     876             :       vreg->setModified(false);
+     877             :     }
+     878             :   }
+     879             : 
+     880             :   ASMJIT_X86_CHECK_STATE
+     881             : }
+     882             : 
+     883             : // ============================================================================
+     884             : // [asmjit::X86RAPass - State - Intersect]
+     885             : // ============================================================================
+     886             : 
+     887             : // The algorithm is actually not so smart, but tries to find an intersection od
+     888             : // `a` and `b` and tries to move/alloc a variable into that location if it's
+     889             : // possible. It also finds out which variables will be spilled/unused  by `a`
+     890             : // and `b` and performs that action here. It may improve the switch state code
+     891             : // in certain cases, but doesn't necessarily do the best job possible.
+     892             : template<int C>
+     893             : static ASMJIT_INLINE void X86RAPass_intersectStateVars(X86RAPass* self, X86RAState* a, X86RAState* b) {
+     894             :   X86RAState* dst = self->getState();
+     895             : 
+     896             :   VirtReg** dVars = dst->getListByKind(C);
+     897             :   VirtReg** aVars = a->getListByKind(C);
+     898             : 
+     899           0 :   X86StateCell* aCells = a->_cells;
+     900           0 :   X86StateCell* bCells = b->_cells;
+     901             : 
+     902             :   uint32_t regCount = self->_regCount.get(C);
+     903             :   bool didWork;
+     904             : 
+     905             :   // Similar to `switchStateVars()`, we iterate over and over until there is
+     906             :   // no work to be done.
+     907           0 :   do {
+     908             :     didWork = false;
+     909             : 
+     910           0 :     for (uint32_t physId = 0, regMask = 0x1; physId < regCount; physId++, regMask <<= 1) {
+     911           0 :       VirtReg* dVReg = dVars[physId]; // Destination reg.
+     912           0 :       VirtReg* aVReg = aVars[physId]; // State-a reg.
+     913             : 
+     914           0 :       if (dVReg == aVReg) continue;
+     915             : 
+     916           0 :       if (dVReg) {
+     917           0 :         const X86StateCell& aCell = aCells[dVReg->_raId];
+     918           0 :         const X86StateCell& bCell = bCells[dVReg->_raId];
+     919             : 
+     920           0 :         if (aCell.getState() != VirtReg::kStateReg && bCell.getState() != VirtReg::kStateReg) {
+     921           0 :           if (aCell.getState() == VirtReg::kStateMem || bCell.getState() == VirtReg::kStateMem)
+     922             :             self->spill<C>(dVReg);
+     923             :           else
+     924             :             self->unuse<C>(dVReg);
+     925             : 
+     926             :           dVReg = nullptr;
+     927             :           didWork = true;
+     928           0 :           if (!aVReg) continue;
+     929             :         }
+     930             :       }
+     931             : 
+     932           0 :       if (!dVReg && aVReg) {
+     933           0 :         if (aVReg->getPhysId() != Globals::kInvalidRegId)
+     934             :           self->move<C>(aVReg, physId);
+     935             :         else
+     936             :           self->load<C>(aVReg, physId);
+     937             : 
+     938             :         didWork = true;
+     939           0 :         continue;
+     940             :       }
+     941             : 
+     942           0 :       if (dVReg) {
+     943           0 :         const X86StateCell& aCell = aCells[dVReg->_raId];
+     944           0 :         const X86StateCell& bCell = bCells[dVReg->_raId];
+     945             : 
+     946           0 :         if (!aVReg) {
+     947           0 :           if (aCell.getState() == VirtReg::kStateReg || bCell.getState() == VirtReg::kStateReg)
+     948           0 :             continue;
+     949             : 
+     950           0 :           if (aCell.getState() == VirtReg::kStateMem || bCell.getState() == VirtReg::kStateMem)
+     951             :             self->spill<C>(dVReg);
+     952             :           else
+     953             :             self->unuse<C>(dVReg);
+     954             : 
+     955             :           didWork = true;
+     956           0 :           continue;
+     957             :         }
+     958             :         else if (C == X86Reg::kKindGp) {
+     959           0 :           if (aCell.getState() == VirtReg::kStateReg) {
+     960           0 :             if (dVReg->getPhysId() != Globals::kInvalidRegId && aVReg->getPhysId() != Globals::kInvalidRegId) {
+     961             :               self->swapGp(dVReg, aVReg);
+     962             : 
+     963             :               didWork = true;
+     964           0 :               continue;
+     965             :             }
+     966             :           }
+     967             :         }
+     968             :       }
+     969             :     }
+     970             :   } while (didWork);
+     971             : 
+     972             :   uint32_t dModified = dst->_modified.get(C);
+     973             :   uint32_t aModified = a->_modified.get(C);
+     974             : 
+     975           0 :   if (dModified != aModified) {
+     976           0 :     for (uint32_t physId = 0, regMask = 0x1; physId < regCount; physId++, regMask <<= 1) {
+     977           0 :       VirtReg* vreg = dVars[physId];
+     978           0 :       if (!vreg) continue;
+     979             : 
+     980           0 :       const X86StateCell& aCell = aCells[vreg->_raId];
+     981           0 :       if ((dModified & regMask) && !(aModified & regMask) && aCell.getState() == VirtReg::kStateReg)
+     982             :         self->save<C>(vreg);
+     983             :     }
+     984             :   }
+     985             : }
+     986             : 
+     987           0 : void X86RAPass::intersectStates(RAState* a_, RAState* b_) {
+     988             :   X86RAState* a = static_cast<X86RAState*>(a_);
+     989             :   X86RAState* b = static_cast<X86RAState*>(b_);
+     990             : 
+     991             :   ASMJIT_ASSERT(a != nullptr);
+     992             :   ASMJIT_ASSERT(b != nullptr);
+     993             : 
+     994             :   X86RAPass_intersectStateVars<X86Reg::kKindGp >(this, a, b);
+     995             :   X86RAPass_intersectStateVars<X86Reg::kKindMm >(this, a, b);
+     996             :   X86RAPass_intersectStateVars<X86Reg::kKindVec>(this, a, b);
+     997             : 
+     998             :   ASMJIT_X86_CHECK_STATE
+     999           0 : }
+    1000             : 
+    1001             : // ============================================================================
+    1002             : // [asmjit::X86RAPass - GetJccFlow / GetOppositeJccFlow]
+    1003             : // ============================================================================
+    1004             : 
+    1005             : //! \internal
+    1006             : static ASMJIT_INLINE CBNode* X86RAPass_getJccFlow(CBJump* jNode) {
+    1007           0 :   if (jNode->isTaken())
+    1008           0 :     return jNode->getTarget();
+    1009             :   else
+    1010           0 :     return jNode->getNext();
+    1011             : }
+    1012             : 
+    1013             : //! \internal
+    1014             : static ASMJIT_INLINE CBNode* X86RAPass_getOppositeJccFlow(CBJump* jNode) {
+    1015           0 :   if (jNode->isTaken())
+    1016           0 :     return jNode->getNext();
+    1017             :   else
+    1018           0 :     return jNode->getTarget();
+    1019             : }
+    1020             : 
+    1021             : // ============================================================================
+    1022             : // [asmjit::X86RAPass - SingleVarInst]
+    1023             : // ============================================================================
+    1024             : 
+    1025             : //! \internal
+    1026         248 : static void X86RAPass_prepareSingleVarInst(uint32_t instId, TiedReg* tr) {
+    1027         248 :   switch (instId) {
+    1028             :     // - andn     reg, reg ; Set all bits in reg to 0.
+    1029             :     // - xor/pxor reg, reg ; Set all bits in reg to 0.
+    1030             :     // - sub/psub reg, reg ; Set all bits in reg to 0.
+    1031             :     // - pcmpgt   reg, reg ; Set all bits in reg to 0.
+    1032             :     // - pcmpeq   reg, reg ; Set all bits in reg to 1.
+    1033         248 :     case X86Inst::kIdPandn     :
+    1034             :     case X86Inst::kIdXor       : case X86Inst::kIdXorpd     : case X86Inst::kIdXorps     : case X86Inst::kIdPxor      :
+    1035             :     case X86Inst::kIdSub:
+    1036             :     case X86Inst::kIdPsubb     : case X86Inst::kIdPsubw     : case X86Inst::kIdPsubd     : case X86Inst::kIdPsubq     :
+    1037             :     case X86Inst::kIdPsubsb    : case X86Inst::kIdPsubsw    : case X86Inst::kIdPsubusb   : case X86Inst::kIdPsubusw   :
+    1038             :     case X86Inst::kIdPcmpeqb   : case X86Inst::kIdPcmpeqw   : case X86Inst::kIdPcmpeqd   : case X86Inst::kIdPcmpeqq   :
+    1039             :     case X86Inst::kIdPcmpgtb   : case X86Inst::kIdPcmpgtw   : case X86Inst::kIdPcmpgtd   : case X86Inst::kIdPcmpgtq   :
+    1040         248 :       tr->flags &= ~TiedReg::kRReg;
+    1041         248 :       break;
+    1042             : 
+    1043             :     // - and      reg, reg ; Nop.
+    1044             :     // - or       reg, reg ; Nop.
+    1045             :     // - xchg     reg, reg ; Nop.
+    1046           0 :     case X86Inst::kIdAnd       : case X86Inst::kIdAndpd     : case X86Inst::kIdAndps     : case X86Inst::kIdPand      :
+    1047             :     case X86Inst::kIdOr        : case X86Inst::kIdOrpd      : case X86Inst::kIdOrps      : case X86Inst::kIdPor       :
+    1048             :     case X86Inst::kIdXchg      :
+    1049           0 :       tr->flags &= ~TiedReg::kWReg;
+    1050           0 :       break;
+    1051             :   }
+    1052         248 : }
+    1053             : 
+    1054             : // ============================================================================
+    1055             : // [asmjit::X86RAPass - Helpers]
+    1056             : // ============================================================================
+    1057             : 
+    1058        1948 : static void X86RAPass_assignStackArgsRegId(X86RAPass* self, CCFunc* func) {
+    1059             :   const FuncDetail& fd = func->getDetail();
+    1060             :   FuncFrameInfo& ffi = func->getFrameInfo();
+    1061             : 
+    1062             :   // Select some register which will contain the base address of function
+    1063             :   // arguments and return address. The algorithm tries to select registers
+    1064             :   // which are saved or not preserved by default, if not successful it picks
+    1065             :   // any other register and adds it to `_savedRegs`.
+    1066             :   uint32_t stackArgsRegId;
+    1067        1948 :   if (ffi.hasPreservedFP()) {
+    1068             :     stackArgsRegId = X86Gp::kIdBp;
+    1069             :   }
+    1070             :   else {
+    1071             :     // Passed registers as defined by the calling convention.
+    1072             :     uint32_t passed = fd.getPassedRegs(X86Reg::kKindGp);
+    1073             : 
+    1074             :     // Registers actually used to pass function arguments (related to this
+    1075             :     // function signature) with ESP|RSP included as this register can't be
+    1076             :     // used in general to hold anything bug stack pointer.
+    1077        1948 :     uint32_t used = fd.getUsedRegs(X86Reg::kKindGp) | Utils::mask(X86Gp::kIdSp);
+    1078             : 
+    1079             :     // First try register that is defined to pass a function argument by the
+    1080             :     // calling convention, but is not used by this function. This will most
+    1081             :     // likely fail in 32-bit mode, but there is a high chance that it will
+    1082             :     // pass in 64-bit mode if the function doesn't use so many arguments.
+    1083        1948 :     uint32_t regs = passed & ~used;
+    1084             : 
+    1085             :     // Pick any other register if that didn't work out.
+    1086        1948 :     if (!regs) regs = ~passed & ~used;
+    1087             : 
+    1088             :     stackArgsRegId = Utils::findFirstBit(regs);
+    1089             :     ASMJIT_ASSERT(stackArgsRegId < self->cc()->getGpCount());
+    1090             :   }
+    1091             : 
+    1092             :   ffi.setStackArgsRegId(stackArgsRegId);
+    1093        1948 : }
+    1094             : 
+    1095             : // ============================================================================
+    1096             : // [asmjit::X86RAPass - SArg Insertion]
+    1097             : // ============================================================================
+    1098             : 
+    1099             : struct SArgData {
+    1100             :   VirtReg* sVd;
+    1101             :   VirtReg* cVd;
+    1102             :   CCPushArg* sArg;
+    1103             :   uint32_t aType;
+    1104             : };
+    1105             : 
+    1106             : static ASMJIT_INLINE bool X86RAPass_mustConvertSArg(X86RAPass* self, uint32_t dstTypeId, uint32_t srcTypeId) noexcept{
+    1107           0 :   uint32_t dstFloatSize = dstTypeId == TypeId::kF32   ? 4 :
+    1108             :                           dstTypeId == TypeId::kF64   ? 8 : 0;
+    1109             : 
+    1110           0 :   uint32_t srcFloatSize = srcTypeId == TypeId::kF32   ? 4 :
+    1111             :                           srcTypeId == TypeId::kF32x1 ? 4 :
+    1112             :                           srcTypeId == TypeId::kF64   ? 8 :
+    1113             :                           srcTypeId == TypeId::kF64x1 ? 8 : 0;
+    1114             : 
+    1115           0 :   if (dstFloatSize && srcFloatSize)
+    1116             :     return dstFloatSize != srcFloatSize;
+    1117             :   else
+    1118             :     return false;
+    1119             : }
+    1120             : 
+    1121             : static ASMJIT_INLINE uint32_t X86RAPass_typeOfConvertedSArg(X86RAPass* self, uint32_t dstTypeId, uint32_t srcTypeId) noexcept {
+    1122             :   ASMJIT_ASSERT(X86RAPass_mustConvertSArg(self, dstTypeId, srcTypeId));
+    1123           0 :   return dstTypeId == TypeId::kF32 ? TypeId::kF32x1 : TypeId::kF64x1;
+    1124             : }
+    1125             : 
+    1126             : static ASMJIT_INLINE Error X86RAPass_insertPushArg(
+    1127             :   X86RAPass* self, CCFuncCall* call,
+    1128             :   VirtReg* sReg, const uint32_t* gaRegs,
+    1129             :   const FuncDetail::Value& arg, uint32_t argIndex,
+    1130             :   SArgData* sArgList, uint32_t& sArgCount) {
+    1131             : 
+    1132             :   X86Compiler* cc = self->cc();
+    1133             :   uint32_t i;
+    1134             :   uint32_t dstTypeId = arg.getTypeId();
+    1135             :   uint32_t srcTypeId = sReg->getTypeId();
+    1136             : 
+    1137             :   // First locate or create sArgBase.
+    1138           0 :   for (i = 0; i < sArgCount; i++)
+    1139           0 :     if (sArgList[i].sVd == sReg && !sArgList[i].cVd)
+    1140             :       break;
+    1141             : 
+    1142           0 :   SArgData* sArgData = &sArgList[i];
+    1143           0 :   if (i == sArgCount) {
+    1144           0 :     sArgData->sVd = sReg;
+    1145           0 :     sArgData->cVd = nullptr;
+    1146           0 :     sArgData->sArg = nullptr;
+    1147           0 :     sArgData->aType = 0xFF;
+    1148           0 :     sArgCount++;
+    1149             :   }
+    1150             : 
+    1151             :   uint32_t srcRegKind = sReg->getKind();
+    1152             : 
+    1153             :   // Only handles float<->double conversion.
+    1154           0 :   if (X86RAPass_mustConvertSArg(self, dstTypeId, srcTypeId)) {
+    1155             :     uint32_t cvtTypeId = X86RAPass_typeOfConvertedSArg(self, dstTypeId, srcTypeId);
+    1156             :     uint32_t cvtRegKind = X86Reg::kKindVec;
+    1157             : 
+    1158           0 :     while (++i < sArgCount) {
+    1159           0 :       sArgData = &sArgList[i];
+    1160           0 :       if (sArgData->sVd != sReg)
+    1161             :         break;
+    1162             : 
+    1163           0 :       if (sArgData->cVd->getTypeId() != cvtTypeId || sArgData->aType != dstTypeId)
+    1164           0 :         continue;
+    1165             : 
+    1166           0 :       sArgData->sArg->_args |= Utils::mask(argIndex);
+    1167             :       return kErrorOk;
+    1168             :     }
+    1169             : 
+    1170           0 :     VirtReg* cReg = cc->newVirtReg(dstTypeId, x86OpData.archRegs.regInfo[X86Reg::kRegXmm].getSignature(), nullptr);
+    1171           0 :     if (!cReg) return DebugUtils::errored(kErrorNoHeapMemory);
+    1172             : 
+    1173             :     CCPushArg* sArg = cc->newNodeT<CCPushArg>(call, sReg, cReg);
+    1174           0 :     if (!sArg) return DebugUtils::errored(kErrorNoHeapMemory);
+    1175             : 
+    1176             :     X86RAData* raData = self->newRAData(2);
+    1177           0 :     if (!raData) return DebugUtils::errored(kErrorNoHeapMemory);
+    1178             : 
+    1179           0 :     ASMJIT_PROPAGATE(self->assignRAId(cReg));
+    1180           0 :     ASMJIT_PROPAGATE(self->assignRAId(sReg));
+    1181             : 
+    1182           0 :     raData->tiedTotal = 2;
+    1183             :     raData->tiedCount.reset();
+    1184             :     raData->tiedCount.add(srcRegKind);
+    1185             :     raData->tiedCount.add(cvtRegKind);
+    1186             : 
+    1187             :     raData->tiedIndex.reset();
+    1188             :     raData->inRegs.reset();
+    1189             :     raData->outRegs.reset();
+    1190             :     raData->clobberedRegs.reset();
+    1191             : 
+    1192           0 :     if (srcRegKind <= cvtRegKind) {
+    1193           0 :       raData->tiedArray[0].init(sReg, TiedReg::kRReg, 0, gaRegs[srcRegKind]);
+    1194           0 :       raData->tiedArray[1].init(cReg, TiedReg::kWReg, 0, gaRegs[cvtRegKind]);
+    1195           0 :       raData->tiedIndex.set(cvtRegKind, srcRegKind != cvtRegKind);
+    1196             :     }
+    1197             :     else {
+    1198           0 :       raData->tiedArray[0].init(cReg, TiedReg::kWReg, 0, gaRegs[cvtRegKind]);
+    1199           0 :       raData->tiedArray[1].init(sReg, TiedReg::kRReg, 0, gaRegs[srcRegKind]);
+    1200             :       raData->tiedIndex.set(srcRegKind, 1);
+    1201             :     }
+    1202             : 
+    1203             :     sArg->setPassData(raData);
+    1204           0 :     sArg->_args |= Utils::mask(argIndex);
+    1205             : 
+    1206           0 :     cc->addBefore(sArg, call);
+    1207           0 :     ::memmove(sArgData + 1, sArgData, (sArgCount - i) * sizeof(SArgData));
+    1208             : 
+    1209           0 :     sArgData->sVd = sReg;
+    1210           0 :     sArgData->cVd = cReg;
+    1211           0 :     sArgData->sArg = sArg;
+    1212           0 :     sArgData->aType = dstTypeId;
+    1213             : 
+    1214           0 :     sArgCount++;
+    1215             :     return kErrorOk;
+    1216             :   }
+    1217             :   else {
+    1218           0 :     CCPushArg* sArg = sArgData->sArg;
+    1219           0 :     ASMJIT_PROPAGATE(self->assignRAId(sReg));
+    1220             : 
+    1221           0 :     if (!sArg) {
+    1222             :       sArg = cc->newNodeT<CCPushArg>(call, sReg, (VirtReg*)nullptr);
+    1223           0 :       if (!sArg) return DebugUtils::errored(kErrorNoHeapMemory);
+    1224             : 
+    1225             :       X86RAData* raData = self->newRAData(1);
+    1226           0 :       if (!raData) return DebugUtils::errored(kErrorNoHeapMemory);
+    1227             : 
+    1228             :       raData->tiedTotal = 1;
+    1229             :       raData->tiedIndex.reset();
+    1230             :       raData->tiedCount.reset();
+    1231             :       raData->tiedCount.add(srcRegKind);
+    1232             :       raData->inRegs.reset();
+    1233             :       raData->outRegs.reset();
+    1234             :       raData->clobberedRegs.reset();
+    1235           0 :       raData->tiedArray[0].init(sReg, TiedReg::kRReg, 0, gaRegs[srcRegKind]);
+    1236             : 
+    1237             :       sArg->setPassData(raData);
+    1238           0 :       sArgData->sArg = sArg;
+    1239             : 
+    1240           0 :       cc->addBefore(sArg, call);
+    1241             :     }
+    1242             : 
+    1243           0 :     sArg->_args |= Utils::mask(argIndex);
+    1244             :     return kErrorOk;
+    1245             :   }
+    1246             : }
+    1247             : 
+    1248             : // ============================================================================
+    1249             : // [asmjit::X86RAPass - Fetch]
+    1250             : // ============================================================================
+    1251             : 
+    1252             : //! \internal
+    1253             : //!
+    1254             : //! Prepare the given function `func`.
+    1255             : //!
+    1256             : //! For each node:
+    1257             : //! - Create and assign groupId and position.
+    1258             : //! - Collect all variables and merge them to vaList.
+    1259        1948 : Error X86RAPass::fetch() {
+    1260             :   uint32_t archType = cc()->getArchType();
+    1261             :   CCFunc* func = getFunc();
+    1262             : 
+    1263             :   CBNode* node_ = func;
+    1264             :   CBNode* next = nullptr;
+    1265             :   CBNode* stop = getStop();
+    1266             : 
+    1267      157788 :   TiedReg agTmp[80];
+    1268             :   SArgData sArgList[80];
+    1269             : 
+    1270             :   uint32_t position = 0;
+    1271             :   ZoneList<CBNode*>::Link* jLink = nullptr;
+    1272             : 
+    1273             :   // Global allocable registers.
+    1274        1948 :   uint32_t* gaRegs = _gaRegs;
+    1275             : 
+    1276        1948 :   if (func->getFrameInfo().hasPreservedFP())
+    1277           0 :     gaRegs[X86Reg::kKindGp] &= ~Utils::mask(X86Gp::kIdBp);
+    1278             : 
+    1279             :   // Allowed index registers (GP/XMM/YMM).
+    1280        1948 :   const uint32_t indexMask = Utils::bits(_regCount.getGp()) & ~(Utils::mask(4));
+    1281             : 
+    1282             :   // --------------------------------------------------------------------------
+    1283             :   // [VI Macros]
+    1284             :   // --------------------------------------------------------------------------
+    1285             : 
+    1286             : #define RA_POPULATE(NODE) \
+    1287             :   do { \
+    1288             :     X86RAData* raData = newRAData(0); \
+    1289             :     if (!raData) goto NoMem; \
+    1290             :     NODE->setPassData(raData); \
+    1291             :   } while (0)
+    1292             : 
+    1293             : #define RA_DECLARE() \
+    1294             :   do { \
+    1295             :     X86RegCount tiedCount; \
+    1296             :     X86RegCount tiedIndex; \
+    1297             :     uint32_t tiedTotal = 0; \
+    1298             :     \
+    1299             :     X86RegMask inRegs; \
+    1300             :     X86RegMask outRegs; \
+    1301             :     X86RegMask clobberedRegs; \
+    1302             :     \
+    1303             :     tiedCount.reset(); \
+    1304             :     inRegs.reset(); \
+    1305             :     outRegs.reset(); \
+    1306             :     clobberedRegs.reset()
+    1307             : 
+    1308             : #define RA_FINALIZE(NODE) \
+    1309             :     { \
+    1310             :       X86RAData* raData = newRAData(tiedTotal); \
+    1311             :       if (!raData) goto NoMem; \
+    1312             :       \
+    1313             :       tiedIndex.indexFromRegCount(tiedCount); \
+    1314             :       raData->tiedCount = tiedCount; \
+    1315             :       raData->tiedIndex = tiedIndex; \
+    1316             :       \
+    1317             :       raData->inRegs = inRegs; \
+    1318             :       raData->outRegs = outRegs; \
+    1319             :       raData->clobberedRegs = clobberedRegs; \
+    1320             :       \
+    1321             :       TiedReg* tied = agTmp; \
+    1322             :       while (tiedTotal) { \
+    1323             :         VirtReg* vreg = tied->vreg; \
+    1324             :         \
+    1325             :         uint32_t _kind  = vreg->getKind(); \
+    1326             :         uint32_t _index = tiedIndex.get(_kind); \
+    1327             :         \
+    1328             :         tiedIndex.add(_kind); \
+    1329             :         if (tied->inRegs) \
+    1330             :           tied->allocableRegs = tied->inRegs; \
+    1331             :         else if (tied->outPhysId != Globals::kInvalidRegId) \
+    1332             :           tied->allocableRegs = Utils::mask(tied->outPhysId); \
+    1333             :         else \
+    1334             :           tied->allocableRegs &= ~inRegs.get(_kind); \
+    1335             :         \
+    1336             :         vreg->_tied = nullptr; \
+    1337             :         raData->setTiedAt(_index, *tied); \
+    1338             :         \
+    1339             :         tied++; \
+    1340             :         tiedTotal--; \
+    1341             :       } \
+    1342             :       NODE->setPassData(raData); \
+    1343             :      } \
+    1344             :   } while (0)
+    1345             : 
+    1346             : #define RA_INSERT(REG, TIED, FLAGS, NEW_ALLOCABLE) \
+    1347             :   do { \
+    1348             :     ASMJIT_ASSERT(REG->_tied == nullptr); \
+    1349             :     TIED = &agTmp[tiedTotal++]; \
+    1350             :     TIED->init(REG, FLAGS, 0, NEW_ALLOCABLE); \
+    1351             :     TIED->refCount++; \
+    1352             :     REG->_tied = TIED; \
+    1353             :     \
+    1354             :     if (assignRAId(REG) != kErrorOk) goto NoMem; \
+    1355             :     tiedCount.add(REG->getKind()); \
+    1356             :   } while (0)
+    1357             : 
+    1358             : #define RA_MERGE(REG, TIED, FLAGS, NEW_ALLOCABLE) \
+    1359             :   do { \
+    1360             :     TIED = REG->_tied; \
+    1361             :     \
+    1362             :     if (!TIED) { \
+    1363             :       TIED = &agTmp[tiedTotal++]; \
+    1364             :       TIED->init(REG, 0, 0, NEW_ALLOCABLE); \
+    1365             :       REG->_tied = TIED; \
+    1366             :       \
+    1367             :       if (assignRAId(REG) != kErrorOk) goto NoMem; \
+    1368             :       tiedCount.add(REG->getKind()); \
+    1369             :     } \
+    1370             :     \
+    1371             :     TIED->flags |= FLAGS; \
+    1372             :     TIED->refCount++; \
+    1373             :   } while (0)
+    1374             : 
+    1375             :   // --------------------------------------------------------------------------
+    1376             :   // [Loop]
+    1377             :   // --------------------------------------------------------------------------
+    1378             : 
+    1379             :   do {
+    1380       34754 : _Do:
+    1381       36702 :     while (node_->hasPassData()) {
+    1382           0 : _NextGroup:
+    1383        1948 :       if (!jLink)
+    1384             :         jLink = _jccList.getFirst();
+    1385             :       else
+    1386             :         jLink = jLink->getNext();
+    1387             : 
+    1388        1948 :       if (!jLink) goto _Done;
+    1389             :       node_ = X86RAPass_getOppositeJccFlow(static_cast<CBJump*>(jLink->getValue()));
+    1390             :     }
+    1391             : 
+    1392       36702 :     position++;
+    1393             : 
+    1394             :     next = node_->getNext();
+    1395             :     node_->setPosition(position);
+    1396             : 
+    1397       36702 :     switch (node_->getType()) {
+    1398             :       // ----------------------------------------------------------------------
+    1399             :       // [Align/Embed]
+    1400             :       // ----------------------------------------------------------------------
+    1401             : 
+    1402             :       case CBNode::kNodeAlign:
+    1403             :       case CBNode::kNodeData:
+    1404             :       default:
+    1405           0 :         RA_POPULATE(node_);
+    1406             :         break;
+    1407             : 
+    1408             :       // ----------------------------------------------------------------------
+    1409             :       // [Hint]
+    1410             :       // ----------------------------------------------------------------------
+    1411             : 
+    1412           0 :       case CBNode::kNodeHint: {
+    1413             :         CCHint* node = static_cast<CCHint*>(node_);
+    1414             :         RA_DECLARE();
+    1415             : 
+    1416           0 :         if (node->getHint() == CCHint::kHintAlloc) {
+    1417             :           uint32_t remain[Globals::kMaxVRegKinds];
+    1418             :           CCHint* cur = node;
+    1419             : 
+    1420           0 :           remain[X86Reg::kKindGp ] = _regCount.getGp() - 1 - func->getFrameInfo().hasPreservedFP();
+    1421           0 :           remain[X86Reg::kKindMm ] = _regCount.getMm();
+    1422           0 :           remain[X86Reg::kKindK  ] = _regCount.getK();
+    1423           0 :           remain[X86Reg::kKindVec] = _regCount.getVec();
+    1424             : 
+    1425             :           // Merge as many alloc-hints as possible.
+    1426             :           for (;;) {
+    1427             :             VirtReg* vreg = static_cast<VirtReg*>(cur->getVReg());
+    1428           0 :             TiedReg* tied = vreg->_tied;
+    1429             : 
+    1430             :             uint32_t kind = vreg->getKind();
+    1431             :             uint32_t physId = cur->getValue();
+    1432             :             uint32_t regMask = 0;
+    1433             : 
+    1434             :             // We handle both kInvalidReg and kInvalidValue.
+    1435           0 :             if (physId < Globals::kInvalidRegId)
+    1436             :               regMask = Utils::mask(physId);
+    1437             : 
+    1438           0 :             if (!tied) {
+    1439           0 :               if (inRegs.has(kind, regMask) || remain[kind] == 0)
+    1440             :                 break;
+    1441           0 :               RA_INSERT(vreg, tied, TiedReg::kRReg, gaRegs[kind]);
+    1442             : 
+    1443           0 :               if (regMask != 0) {
+    1444             :                 inRegs.xor_(kind, regMask);
+    1445           0 :                 tied->inRegs = regMask;
+    1446             :                 tied->setInPhysId(physId);
+    1447             :               }
+    1448           0 :               remain[kind]--;
+    1449             :             }
+    1450           0 :             else if (regMask != 0) {
+    1451           0 :               if (inRegs.has(kind, regMask) && tied->inRegs != regMask)
+    1452             :                 break;
+    1453             : 
+    1454           0 :               inRegs.xor_(kind, tied->inRegs | regMask);
+    1455           0 :               tied->inRegs = regMask;
+    1456             :               tied->setInPhysId(physId);
+    1457             :             }
+    1458             : 
+    1459           0 :             if (cur != node)
+    1460           0 :               cc()->removeNode(cur);
+    1461             : 
+    1462             :             cur = static_cast<CCHint*>(node->getNext());
+    1463           0 :             if (!cur || cur->getType() != CBNode::kNodeHint || cur->getHint() != CCHint::kHintAlloc)
+    1464             :               break;
+    1465             :           }
+    1466             : 
+    1467             :           next = node->getNext();
+    1468             :         }
+    1469             :         else  {
+    1470             :           VirtReg* vreg = static_cast<VirtReg*>(node->getVReg());
+    1471             :           TiedReg* tied;
+    1472             : 
+    1473             :           uint32_t flags = 0;
+    1474             :           switch (node->getHint()) {
+    1475           0 :             case CCHint::kHintSpill       : flags = TiedReg::kRMem | TiedReg::kSpill; break;
+    1476           0 :             case CCHint::kHintSave        : flags = TiedReg::kRMem                  ; break;
+    1477           0 :             case CCHint::kHintSaveAndUnuse: flags = TiedReg::kRMem | TiedReg::kUnuse; break;
+    1478           0 :             case CCHint::kHintUnuse       : flags = TiedReg::kUnuse                 ; break;
+    1479             :           }
+    1480           0 :           RA_INSERT(vreg, tied, flags, 0);
+    1481             :         }
+    1482             : 
+    1483           0 :         RA_FINALIZE(node_);
+    1484           0 :         break;
+    1485             :       }
+    1486             : 
+    1487             :       // ----------------------------------------------------------------------
+    1488             :       // [Label]
+    1489             :       // ----------------------------------------------------------------------
+    1490             : 
+    1491             :       case CBNode::kNodeLabel: {
+    1492           0 :         RA_POPULATE(node_);
+    1493           0 :         if (node_ == func->getExitNode()) {
+    1494           0 :           ASMJIT_PROPAGATE(addReturningNode(node_));
+    1495           0 :           goto _NextGroup;
+    1496             :         }
+    1497             :         break;
+    1498             :       }
+    1499             : 
+    1500             :       // ----------------------------------------------------------------------
+    1501             :       // [Inst]
+    1502             :       // ----------------------------------------------------------------------
+    1503             : 
+    1504       31158 :       case CBNode::kNodeInst: {
+    1505             :         CBInst* node = static_cast<CBInst*>(node_);
+    1506             : 
+    1507             :         uint32_t instId = node->getInstId();
+    1508             :         uint32_t flags = node->getFlags();
+    1509             :         uint32_t options = node->getOptions();
+    1510             :         uint32_t gpAllowedMask = 0xFFFFFFFF;
+    1511             : 
+    1512             :         Operand* opArray = node->getOpArray();
+    1513             :         uint32_t opCount = node->getOpCount();
+    1514             : 
+    1515             :         RA_DECLARE();
+    1516       31158 :         if (opCount) {
+    1517             :           const X86Inst& inst = X86Inst::getInst(instId);
+    1518             :           const X86Inst::CommonData& commonData = inst.getCommonData();
+    1519             :           const X86SpecialInst* special = nullptr;
+    1520             : 
+    1521             :           // Collect instruction flags and merge all 'TiedReg's.
+    1522       31158 :           if (commonData.isFpu())
+    1523             :             flags |= CBNode::kFlagIsFp;
+    1524             : 
+    1525       31158 :           if (commonData.hasFixedRM() && (special = X86SpecialInst_get(instId, opArray, opCount)) != nullptr)
+    1526           0 :             flags |= CBNode::kFlagIsSpecial;
+    1527             : 
+    1528       93594 :           for (uint32_t i = 0; i < opCount; i++) {
+    1529       62436 :             Operand* op = &opArray[i];
+    1530             :             VirtReg* vreg;
+    1531             :             TiedReg* tied;
+    1532             : 
+    1533             :             if (op->isVirtReg()) {
+    1534             :               vreg = cc()->getVirtRegById(op->getId());
+    1535       48948 :               if (vreg->isFixed()) continue;
+    1536             : 
+    1537      119788 :               RA_MERGE(vreg, tied, 0, gaRegs[vreg->getKind()] & gpAllowedMask);
+    1538       48948 :               if (static_cast<X86Reg*>(op)->isGpb()) {
+    1539           0 :                 tied->flags |= static_cast<X86Gp*>(op)->isGpbLo() ? TiedReg::kX86GpbLo : TiedReg::kX86GpbHi;
+    1540           0 :                 if (archType == ArchInfo::kTypeX86) {
+    1541             :                   // If a byte register is accessed in 32-bit mode we have to limit
+    1542             :                   // all allocable registers for that variable to eax/ebx/ecx/edx.
+    1543             :                   // Other variables are not affected.
+    1544           0 :                   tied->allocableRegs &= 0x0F;
+    1545             :                 }
+    1546             :                 else {
+    1547             :                   // It's fine if lo-byte register is accessed in 64-bit mode;
+    1548             :                   // however, hi-byte has to be checked and if it's used all
+    1549             :                   // registers (GP/XMM) could be only allocated in the lower eight
+    1550             :                   // half. To do that, we patch 'allocableRegs' of all variables
+    1551             :                   // we collected until now and change the allocable restriction
+    1552             :                   // for variables that come after.
+    1553           0 :                   if (static_cast<X86Gp*>(op)->isGpbHi()) {
+    1554           0 :                     tied->allocableRegs &= 0x0F;
+    1555           0 :                     if (gpAllowedMask != 0xFF) {
+    1556           0 :                       for (uint32_t j = 0; j < i; j++)
+    1557           0 :                         agTmp[j].allocableRegs &= (agTmp[j].flags & TiedReg::kX86GpbHi) ? 0x0F : 0xFF;
+    1558             :                       gpAllowedMask = 0xFF;
+    1559             :                     }
+    1560             :                   }
+    1561             :                 }
+    1562             :               }
+    1563             : 
+    1564       48948 :               if (special) {
+    1565           0 :                 uint32_t inReg = special[i].inReg;
+    1566           0 :                 uint32_t outReg = special[i].outReg;
+    1567             :                 uint32_t c;
+    1568             : 
+    1569           0 :                 if (static_cast<const X86Reg*>(op)->isGp())
+    1570             :                   c = X86Reg::kKindGp;
+    1571             :                 else
+    1572             :                   c = X86Reg::kKindVec;
+    1573             : 
+    1574           0 :                 if (inReg != Globals::kInvalidRegId) {
+    1575             :                   uint32_t mask = Utils::mask(inReg);
+    1576             :                   inRegs.or_(c, mask);
+    1577           0 :                   tied->inRegs |= mask;
+    1578             :                 }
+    1579             : 
+    1580           0 :                 if (outReg != Globals::kInvalidRegId) {
+    1581             :                   uint32_t mask = Utils::mask(outReg);
+    1582             :                   outRegs.or_(c, mask);
+    1583             :                   tied->setOutPhysId(outReg);
+    1584             :                 }
+    1585             : 
+    1586           0 :                 tied->flags |= special[i].flags;
+    1587             :               }
+    1588             :               else {
+    1589             :                 uint32_t inFlags = TiedReg::kRReg;
+    1590             :                 uint32_t outFlags = TiedReg::kWReg;
+    1591             :                 uint32_t combinedFlags;
+    1592             : 
+    1593       48948 :                 if (i == 0) {
+    1594             :                   // Read/Write is usually the combination of the first operand.
+    1595             :                   combinedFlags = inFlags | outFlags;
+    1596             : 
+    1597       30892 :                   if (node->getOptions() & CodeEmitter::kOptionOverwrite) {
+    1598             :                     // Manually forcing write-only.
+    1599             :                     combinedFlags = outFlags;
+    1600             :                   }
+    1601       30892 :                   else if (commonData.isUseW()) {
+    1602             :                     // Write-only instruction.
+    1603             :                     uint32_t movSize = commonData.getWriteSize();
+    1604             :                     uint32_t regSize = vreg->getSize();
+    1605             : 
+    1606             :                     // Exception - If the source operand is a memory location
+    1607             :                     // promote move size into 16 bytes.
+    1608       21892 :                     if (opArray[1].isMem() && inst.getOperationData().isMovSsSd())
+    1609             :                       movSize = 16;
+    1610             : 
+    1611       21892 :                     if (static_cast<const X86Reg*>(op)->isGp()) {
+    1612             :                       uint32_t opSize = static_cast<const X86Reg*>(op)->getSize();
+    1613             : 
+    1614             :                       // Move size is zero in case that it should be determined
+    1615             :                       // from the destination register.
+    1616        7268 :                       if (movSize == 0)
+    1617             :                         movSize = opSize;
+    1618             : 
+    1619             :                       // Handle the case that a 32-bit operation in 64-bit mode
+    1620             :                       // always clears the rest of the destination register and
+    1621             :                       // the case that move size is actually greater than or
+    1622             :                       // equal to the size of the variable.
+    1623        7268 :                       if (movSize >= 4 || movSize >= regSize)
+    1624             :                         combinedFlags = outFlags;
+    1625             :                     }
+    1626       14624 :                     else if (movSize == 0 || movSize >= regSize) {
+    1627             :                       // If move size is greater than or equal to the size of
+    1628             :                       // the variable there is nothing to do, because the move
+    1629             :                       // will overwrite the variable in all cases.
+    1630             :                       combinedFlags = outFlags;
+    1631             :                     }
+    1632             :                   }
+    1633        9000 :                   else if (commonData.isUseR()) {
+    1634             :                     // Comparison/Test instructions don't modify any operand.
+    1635             :                     combinedFlags = inFlags;
+    1636             :                   }
+    1637        9000 :                   else if (instId == X86Inst::kIdImul && opCount == 3) {
+    1638             :                     // Imul.
+    1639             :                     combinedFlags = outFlags;
+    1640             :                   }
+    1641             :                 }
+    1642             :                 else {
+    1643             :                   // Read-Only is usually the combination of the second/third/fourth operands.
+    1644             :                   combinedFlags = inFlags;
+    1645             : 
+    1646             :                   // Idiv is a special instruction, never handled here.
+    1647             :                   ASMJIT_ASSERT(instId != X86Inst::kIdIdiv);
+    1648             : 
+    1649             :                   // Xchg/Xadd/Imul.
+    1650       18056 :                   if (commonData.isUseXX() || (instId == X86Inst::kIdImul && opCount == 3 && i == 1))
+    1651             :                     combinedFlags = inFlags | outFlags;
+    1652             :                 }
+    1653       48948 :                 tied->flags |= combinedFlags;
+    1654             :               }
+    1655             :             }
+    1656       13488 :             else if (op->isMem()) {
+    1657             :               X86Mem* m = static_cast<X86Mem*>(op);
+    1658             :               node->setMemOpIndex(i);
+    1659             : 
+    1660        6100 :               uint32_t specBase = special ? uint32_t(special[i].inReg) : uint32_t(Globals::kInvalidRegId);
+    1661             : 
+    1662        6100 :               if (m->hasBaseReg()) {
+    1663             :                 uint32_t id = m->getBaseId();
+    1664        6100 :                 if (cc()->isVirtRegValid(id)) {
+    1665             :                   vreg = cc()->getVirtRegById(id);
+    1666        6100 :                   if (!vreg->isStack() && !vreg->isFixed()) {
+    1667       12200 :                     RA_MERGE(vreg, tied, 0, gaRegs[vreg->getKind()] & gpAllowedMask);
+    1668        6100 :                     if (m->isRegHome()) {
+    1669             :                       uint32_t inFlags = TiedReg::kRMem;
+    1670             :                       uint32_t outFlags = TiedReg::kWMem;
+    1671             :                       uint32_t combinedFlags;
+    1672             : 
+    1673           0 :                       if (i == 0) {
+    1674             :                         // Default for the first operand.
+    1675             :                         combinedFlags = inFlags | outFlags;
+    1676             : 
+    1677           0 :                         if (commonData.isUseW()) {
+    1678             :                           // Move to memory - setting the right flags is important
+    1679             :                           // as if it's just move to the register. It's just a bit
+    1680             :                           // simpler as there are no special cases.
+    1681           0 :                           uint32_t movSize = std::max<uint32_t>(commonData.getWriteSize(), m->getSize());
+    1682             :                           uint32_t regSize = vreg->getSize();
+    1683             : 
+    1684           0 :                           if (movSize >= regSize)
+    1685             :                             combinedFlags = outFlags;
+    1686             :                         }
+    1687           0 :                         else if (commonData.isUseR()) {
+    1688             :                           // Comparison/Test instructions don't modify any operand.
+    1689             :                           combinedFlags = inFlags;
+    1690             :                         }
+    1691             :                       }
+    1692             :                       else {
+    1693             :                         // Default for the second operand.
+    1694             :                         combinedFlags = inFlags;
+    1695             : 
+    1696             :                         // Handle Xchg instruction (modifies both operands).
+    1697           0 :                         if (commonData.isUseXX())
+    1698             :                           combinedFlags = inFlags | outFlags;
+    1699             :                       }
+    1700             : 
+    1701           0 :                       tied->flags |= combinedFlags;
+    1702             :                     }
+    1703             :                     else {
+    1704        6100 :                       if (specBase != Globals::kInvalidRegId) {
+    1705             :                         uint32_t mask = Utils::mask(specBase);
+    1706             :                         inRegs.or_(vreg->getKind(), mask);
+    1707             :                         outRegs.or_(vreg->getKind(), mask);
+    1708           0 :                         tied->inRegs |= mask;
+    1709             :                         tied->setOutPhysId(specBase);
+    1710           0 :                         tied->flags |= special[i].flags;
+    1711             :                       }
+    1712             :                       else {
+    1713        6100 :                         tied->flags |= TiedReg::kRReg;
+    1714             :                       }
+    1715             :                     }
+    1716             :                   }
+    1717             :                 }
+    1718             :               }
+    1719             : 
+    1720        6100 :               if (m->hasIndexReg()) {
+    1721             :                 uint32_t id = m->getIndexId();
+    1722           0 :                 if (cc()->isVirtRegValid(id)) {
+    1723             :                   // Restrict allocation to all registers except ESP|RSP.
+    1724             :                   vreg = cc()->getVirtRegById(m->getIndexId());
+    1725           0 :                   if (!vreg->isFixed()) {
+    1726             :                     // TODO: AVX vector operands support.
+    1727           0 :                     RA_MERGE(vreg, tied, 0, gaRegs[X86Reg::kKindGp] & gpAllowedMask);
+    1728           0 :                     tied->allocableRegs &= indexMask;
+    1729           0 :                     tied->flags |= TiedReg::kRReg;
+    1730             :                   }
+    1731             :                 }
+    1732             :               }
+    1733             :             }
+    1734             :           }
+    1735             : 
+    1736             :           node->setFlags(flags);
+    1737       31158 :           if (tiedTotal) {
+    1738             :             // Handle instructions which result in zeros/ones or nop if used with the
+    1739             :             // same destination and source operand.
+    1740       31406 :             if (tiedTotal == 1 && opCount >= 2 && opArray[0].isVirtReg() && opArray[1].isVirtReg() && !node->hasMemOp())
+    1741         248 :               X86RAPass_prepareSingleVarInst(instId, &agTmp[0]);
+    1742             :           }
+    1743             : 
+    1744             :           // Turn on AVX if the instruction operates on XMM|YMM|ZMM registers and uses VEX|EVEX prefix.
+    1745       31158 :           if (tiedCount.getVec() && commonData.hasFlag(X86Inst::kFlagVex | X86Inst::kFlagEvex))
+    1746           0 :             _avxEnabled = true;
+    1747             :         }
+    1748             : 
+    1749             :         const RegOnly& extraReg = node->getExtraReg();
+    1750       31158 :         if (extraReg.isValid()) {
+    1751             :           uint32_t id = extraReg.getId();
+    1752           0 :           if (cc()->isVirtRegValid(id)) {
+    1753             :             VirtReg* vreg = cc()->getVirtRegById(id);
+    1754             :             TiedReg* tied;
+    1755           0 :             RA_MERGE(vreg, tied, 0, gaRegs[vreg->getKind()] & gpAllowedMask);
+    1756             : 
+    1757           0 :             if (options & (X86Inst::kOptionRep | X86Inst::kOptionRepnz)) {
+    1758           0 :               tied->allocableRegs = Utils::mask(X86Gp::kIdCx);
+    1759           0 :               tied->flags |= TiedReg::kXReg;
+    1760             :             }
+    1761             :             else {
+    1762           0 :               tied->flags |= TiedReg::kRReg;
+    1763             :             }
+    1764             :           }
+    1765             :         }
+    1766             : 
+    1767       85958 :         RA_FINALIZE(node_);
+    1768             : 
+    1769             :         // Handle conditional/unconditional jump.
+    1770       31158 :         if (node->isJmpOrJcc()) {
+    1771             :           CBJump* jNode = static_cast<CBJump*>(node);
+    1772             :           CBLabel* jTarget = jNode->getTarget();
+    1773             : 
+    1774             :           // If this jump is unconditional we put next node to unreachable node
+    1775             :           // list so we can eliminate possible dead code. We have to do this in
+    1776             :           // all cases since we are unable to translate without fetch() step.
+    1777             :           //
+    1778             :           // We also advance our node pointer to the target node to simulate
+    1779             :           // natural flow of the function.
+    1780           0 :           if (jNode->isJmp()) {
+    1781           0 :             if (next && !next->hasPassData())
+    1782           0 :               ASMJIT_PROPAGATE(addUnreachableNode(next));
+    1783             : 
+    1784             :             // Jump not followed.
+    1785           0 :             if (!jTarget) {
+    1786           0 :               ASMJIT_PROPAGATE(addReturningNode(jNode));
+    1787           0 :               goto _NextGroup;
+    1788             :             }
+    1789             : 
+    1790             :             node_ = jTarget;
+    1791           0 :             goto _Do;
+    1792             :           }
+    1793             :           else {
+    1794             :             // Jump not followed.
+    1795           0 :             if (!jTarget) break;
+    1796             : 
+    1797           0 :             if (jTarget->hasPassData()) {
+    1798             :               uint32_t jTargetPosition = jTarget->getPosition();
+    1799             : 
+    1800             :               // Update CBNode::kFlagIsTaken to true if this is a conditional
+    1801             :               // backward jump. This behavior can be overridden by using
+    1802             :               // `X86Inst::kOptionTaken` when the instruction is created.
+    1803           0 :               if (!jNode->isTaken() && opCount == 1 && jTargetPosition <= position) {
+    1804           0 :                 jNode->_flags |= CBNode::kFlagIsTaken;
+    1805             :               }
+    1806             :             }
+    1807           0 :             else if (next->hasPassData()) {
+    1808             :               node_ = jTarget;
+    1809           0 :               goto _Do;
+    1810             :             }
+    1811             :             else {
+    1812           0 :               ASMJIT_PROPAGATE(addJccNode(jNode));
+    1813             :               node_ = X86RAPass_getJccFlow(jNode);
+    1814           0 :               goto _Do;
+    1815             :             }
+    1816             :           }
+    1817             :         }
+    1818             :         break;
+    1819             :       }
+    1820             : 
+    1821             :       // ----------------------------------------------------------------------
+    1822             :       // [Func-Entry]
+    1823             :       // ----------------------------------------------------------------------
+    1824             : 
+    1825        1948 :       case CBNode::kNodeFunc: {
+    1826             :         ASMJIT_ASSERT(node_ == func);
+    1827        1948 :         X86RAPass_assignStackArgsRegId(this, func);
+    1828             : 
+    1829             :         FuncDetail& fd = func->getDetail();
+    1830             :         TiedReg* tied;
+    1831             : 
+    1832             :         RA_DECLARE();
+    1833        1948 :         cc()->setCursor(node_);
+    1834             : 
+    1835             :         X86Gp saReg;
+    1836             :         uint32_t argCount = fd.getArgCount();
+    1837             : 
+    1838        1948 :         for (uint32_t i = 0; i < argCount; i++) {
+    1839           0 :           const FuncDetail::Value& arg = fd.getArg(i);
+    1840             : 
+    1841             :           VirtReg* vReg = func->getArg(i);
+    1842           0 :           if (!vReg) continue;
+    1843             : 
+    1844             :           // Overlapped function arguments.
+    1845           0 :           if (vReg->_tied)
+    1846           0 :             return DebugUtils::errored(kErrorOverlappedRegs);
+    1847             : 
+    1848             :           uint32_t aKind = X86Reg::kindOf(arg.getRegType());
+    1849             :           uint32_t vKind = vReg->getKind();
+    1850             : 
+    1851           0 :           if (arg.byReg()) {
+    1852           0 :             if (aKind == vKind) {
+    1853           0 :               RA_INSERT(vReg, tied, TiedReg::kWReg, 0);
+    1854             :               tied->setOutPhysId(arg.getRegId());
+    1855             :             }
+    1856             :             else {
+    1857           0 :               X86Reg rTmp = cc()->newReg(arg.getTypeId(), "arg%u", i);
+    1858             :               VirtReg* vTmp = cc()->getVirtReg(rTmp);
+    1859             : 
+    1860           0 :               RA_INSERT(vTmp, tied, TiedReg::kWReg, 0);
+    1861             :               tied->setOutPhysId(arg.getRegId());
+    1862             : 
+    1863             :               X86Reg dstReg(X86Reg::fromSignature(vReg->getSignature(), vReg->getId()));
+    1864             :               X86Reg srcReg(X86Reg::fromSignature(vTmp->getSignature(), vTmp->getId()));
+    1865             : 
+    1866             :               // Emit conversion after the prolog.
+    1867           0 :               return X86Internal::emitArgMove(reinterpret_cast<X86Emitter*>(cc()),
+    1868             :                 dstReg, vReg->getTypeId(),
+    1869           0 :                 srcReg, vTmp->getTypeId(), _avxEnabled);
+    1870             :             }
+    1871             :           }
+    1872             :           else {
+    1873             :             // Instead of complicating the prolog allocation we create a virtual
+    1874             :             // register that holds the base address to all arguments passed by
+    1875             :             // stack and then insert nodes that copy these arguments to registers.
+    1876           0 :             if (!saReg.isValid()) {
+    1877           0 :               saReg = cc()->newGpz("__args");
+    1878           0 :               if (!saReg.isValid()) goto NoMem;
+    1879             : 
+    1880             :               VirtReg* saBase = cc()->getVirtReg(saReg);
+    1881           0 :               RA_INSERT(saBase, tied, TiedReg::kWReg, 0);
+    1882             : 
+    1883           0 :               if (func->getFrameInfo().hasPreservedFP())
+    1884           0 :                 saBase->_isFixed = true;
+    1885             :               tied->setOutPhysId(func->getFrameInfo().getStackArgsRegId());
+    1886             :             }
+    1887             : 
+    1888             :             // Argument passed by stack is handled after the prolog.
+    1889             :             X86Gp aReg = X86Gp::fromSignature(vReg->getSignature(), vReg->getId());
+    1890             :             X86Mem aMem = x86::ptr(saReg, arg.getStackOffset());
+    1891             :             aMem.setArgHome();
+    1892             : 
+    1893           0 :             ASMJIT_PROPAGATE(
+    1894             :               X86Internal::emitArgMove(reinterpret_cast<X86Emitter*>(cc()),
+    1895             :                 aReg, vReg->getTypeId(), aMem, arg.getTypeId(), _avxEnabled));
+    1896             :           }
+    1897             :         }
+    1898             : 
+    1899             :         // If saReg is not needed, clear it also from FuncFrameInfo.
+    1900        1948 :         if (!saReg.isValid())
+    1901             :           func->getFrameInfo().setStackArgsRegId(Globals::kInvalidRegId);
+    1902             : 
+    1903        1948 :         RA_FINALIZE(node_);
+    1904             :         next = node_->getNext();
+    1905        1948 :         break;
+    1906             :       }
+    1907             : 
+    1908             :       // ----------------------------------------------------------------------
+    1909             :       // [End]
+    1910             :       // ----------------------------------------------------------------------
+    1911             : 
+    1912             :       case CBNode::kNodeSentinel: {
+    1913           0 :         RA_POPULATE(node_);
+    1914           0 :         ASMJIT_PROPAGATE(addReturningNode(node_));
+    1915           0 :         goto _NextGroup;
+    1916             :       }
+    1917             : 
+    1918             :       // ----------------------------------------------------------------------
+    1919             :       // [Func-Exit]
+    1920             :       // ----------------------------------------------------------------------
+    1921             : 
+    1922        1948 :       case CBNode::kNodeFuncExit: {
+    1923             :         CCFuncRet* node = static_cast<CCFuncRet*>(node_);
+    1924        1948 :         ASMJIT_PROPAGATE(addReturningNode(node));
+    1925             : 
+    1926             :         FuncDetail& fd = func->getDetail();
+    1927             :         RA_DECLARE();
+    1928             : 
+    1929        1948 :         if (fd.hasRet()) {
+    1930             :           const FuncDetail::Value& ret = fd.getRet(0);
+    1931             :           uint32_t retKind = X86Reg::kindOf(ret.getRegType());
+    1932             : 
+    1933        5844 :           for (uint32_t i = 0; i < 2; i++) {
+    1934             :             Operand_* op = &node->_ret[i];
+    1935             :             if (op->isVirtReg()) {
+    1936             :               VirtReg* vreg = cc()->getVirtRegById(op->getId());
+    1937             :               TiedReg* tied;
+    1938        3896 :               RA_MERGE(vreg, tied, 0, 0);
+    1939             : 
+    1940        1948 :               if (retKind == vreg->getKind()) {
+    1941        1948 :                 tied->flags |= TiedReg::kRReg;
+    1942        1948 :                 tied->inRegs = Utils::mask(ret.getRegId());
+    1943             :                 inRegs.or_(retKind, tied->inRegs);
+    1944             :               }
+    1945           0 :               else if (retKind == X86Reg::kKindFp) {
+    1946           0 :                 uint32_t fldFlag = ret.getTypeId() == TypeId::kF32 ? TiedReg::kX86Fld4 : TiedReg::kX86Fld8;
+    1947           0 :                 tied->flags |= TiedReg::kRMem | fldFlag;
+    1948             :               }
+    1949             :               else {
+    1950             :                 // TODO: Fix possible other return type conversions.
+    1951           0 :                 ASMJIT_NOT_REACHED();
+    1952             :               }
+    1953             :             }
+    1954             :           }
+    1955             :         }
+    1956        3896 :         RA_FINALIZE(node_);
+    1957             : 
+    1958        1948 :         if (!next->hasPassData())
+    1959        1948 :           ASMJIT_PROPAGATE(addUnreachableNode(next));
+    1960        1948 :         goto _NextGroup;
+    1961             :       }
+    1962             : 
+    1963             :       // ----------------------------------------------------------------------
+    1964             :       // [Func-Call]
+    1965             :       // ----------------------------------------------------------------------
+    1966             : 
+    1967        1648 :       case CBNode::kNodeFuncCall: {
+    1968             :         CCFuncCall* node = static_cast<CCFuncCall*>(node_);
+    1969             :         FuncDetail& fd = node->getDetail();
+    1970             : 
+    1971        1648 :         Operand_* target = node->_opArray;
+    1972        1648 :         Operand_* args = node->_args;
+    1973        1648 :         Operand_* rets = node->_ret;
+    1974             : 
+    1975             :         func->getFrameInfo().enableCalls();
+    1976        1648 :         func->getFrameInfo().mergeCallFrameSize(fd.getArgStackSize());
+    1977             :         // TODO: Each function frame should also define its stack arguments' alignment.
+    1978             :         // func->getFrameInfo().mergeCallFrameAlignment();
+    1979             : 
+    1980             :         uint32_t i;
+    1981             :         uint32_t argCount = fd.getArgCount();
+    1982             :         uint32_t sArgCount = 0;
+    1983        1648 :         uint32_t gpAllocableMask = gaRegs[X86Reg::kKindGp] & ~node->getDetail().getUsedRegs(X86Reg::kKindGp);
+    1984             : 
+    1985             :         VirtReg* vreg;
+    1986             :         TiedReg* tied;
+    1987             : 
+    1988             :         RA_DECLARE();
+    1989             : 
+    1990             :         // Function-call operand.
+    1991             :         if (target->isVirtReg()) {
+    1992             :           vreg = cc()->getVirtRegById(target->getId());
+    1993        1648 :           RA_MERGE(vreg, tied, 0, 0);
+    1994             : 
+    1995        1648 :           tied->flags |= TiedReg::kRReg | TiedReg::kRCall;
+    1996        1648 :           if (tied->inRegs == 0)
+    1997        1648 :             tied->allocableRegs |= gpAllocableMask;
+    1998             :         }
+    1999           0 :         else if (target->isMem()) {
+    2000             :           X86Mem* m = static_cast<X86Mem*>(target);
+    2001             : 
+    2002           0 :           if (m->hasBaseReg() &&  Operand::isPackedId(m->getBaseId())) {
+    2003             :             vreg = cc()->getVirtRegById(m->getBaseId());
+    2004           0 :             if (!vreg->isStack()) {
+    2005           0 :               RA_MERGE(vreg, tied, 0, 0);
+    2006           0 :               if (m->isRegHome()) {
+    2007           0 :                 tied->flags |= TiedReg::kRMem | TiedReg::kRCall;
+    2008             :               }
+    2009             :               else {
+    2010           0 :                 tied->flags |= TiedReg::kRReg | TiedReg::kRCall;
+    2011           0 :                 if (tied->inRegs == 0)
+    2012           0 :                   tied->allocableRegs |= gpAllocableMask;
+    2013             :               }
+    2014             :             }
+    2015             :           }
+    2016             : 
+    2017           0 :           if (m->hasIndexReg() && Operand::isPackedId(m->getIndexId())) {
+    2018             :             // Restrict allocation to all registers except ESP/RSP.
+    2019             :             vreg = cc()->getVirtRegById(m->getIndexId());
+    2020           0 :             RA_MERGE(vreg, tied, 0, 0);
+    2021             : 
+    2022           0 :             tied->flags |= TiedReg::kRReg | TiedReg::kRCall;
+    2023           0 :             if ((tied->inRegs & ~indexMask) == 0)
+    2024           0 :               tied->allocableRegs &= gpAllocableMask & indexMask;
+    2025             :           }
+    2026             :         }
+    2027             : 
+    2028             :         // Function-call arguments.
+    2029        3518 :         for (i = 0; i < argCount; i++) {
+    2030        1870 :           Operand_* op = &args[i];
+    2031         420 :           if (!op->isVirtReg()) continue;
+    2032             : 
+    2033             :           vreg = cc()->getVirtRegById(op->getId());
+    2034             :           const FuncDetail::Value& arg = fd.getArg(i);
+    2035             : 
+    2036        1450 :           if (arg.byReg()) {
+    2037        2900 :             RA_MERGE(vreg, tied, 0, 0);
+    2038             : 
+    2039             :             uint32_t argClass = X86Reg::kindOf(arg.getRegType());
+    2040             : 
+    2041        1450 :             if (vreg->getKind() == argClass) {
+    2042        1450 :               tied->inRegs |= Utils::mask(arg.getRegId());
+    2043        1450 :               tied->flags |= TiedReg::kRReg | TiedReg::kRFunc;
+    2044             :             }
+    2045             :             else {
+    2046             :               // TODO: Function-call argument conversion.
+    2047             :             }
+    2048             :           }
+    2049             :           // If this is a stack-based argument we insert CCPushArg instead of
+    2050             :           // using TiedReg. It improves the code, because the argument can be
+    2051             :           // moved onto stack as soon as it is ready and the register used by
+    2052             :           // the variable can be reused for something else. It is also much
+    2053             :           // easier to handle argument conversions, because there will be at
+    2054             :           // most only one node per conversion.
+    2055             :           else {
+    2056           0 :             if (X86RAPass_insertPushArg(this, node, vreg, gaRegs, arg, i, sArgList, sArgCount) != kErrorOk)
+    2057           0 :               goto NoMem;
+    2058             :           }
+    2059             :         }
+    2060             : 
+    2061             :         // Function-call returns.
+    2062        4944 :         for (i = 0; i < 2; i++) {
+    2063        3296 :           Operand_* op = &rets[i];
+    2064        1648 :           if (!op->isVirtReg()) continue;
+    2065             : 
+    2066             :           const FuncDetail::Value& ret = fd.getRet(i);
+    2067        1648 :           if (ret.byReg()) {
+    2068             :             uint32_t retKind = X86Reg::kindOf(ret.getRegType());
+    2069             : 
+    2070             :             vreg = cc()->getVirtRegById(op->getId());
+    2071        4944 :             RA_MERGE(vreg, tied, 0, 0);
+    2072             : 
+    2073        1648 :             if (vreg->getKind() == retKind) {
+    2074             :               tied->setOutPhysId(ret.getRegId());
+    2075        1648 :               tied->flags |= TiedReg::kWReg | TiedReg::kWFunc;
+    2076             :             }
+    2077             :             else {
+    2078             :               // TODO: Function-call return value conversion.
+    2079             :             }
+    2080             :           }
+    2081             :         }
+    2082             : 
+    2083             :         // Init clobbered.
+    2084        1648 :         clobberedRegs.set(X86Reg::kKindGp , Utils::bits(_regCount.getGp())  & (fd.getPassedRegs(X86Reg::kKindGp ) | ~fd.getPreservedRegs(X86Reg::kKindGp )));
+    2085        1648 :         clobberedRegs.set(X86Reg::kKindMm , Utils::bits(_regCount.getMm())  & (fd.getPassedRegs(X86Reg::kKindMm ) | ~fd.getPreservedRegs(X86Reg::kKindMm )));
+    2086        1648 :         clobberedRegs.set(X86Reg::kKindK  , Utils::bits(_regCount.getK())   & (fd.getPassedRegs(X86Reg::kKindK  ) | ~fd.getPreservedRegs(X86Reg::kKindK  )));
+    2087        1648 :         clobberedRegs.set(X86Reg::kKindVec, Utils::bits(_regCount.getVec()) & (fd.getPassedRegs(X86Reg::kKindVec) | ~fd.getPreservedRegs(X86Reg::kKindVec)));
+    2088             : 
+    2089        6394 :         RA_FINALIZE(node_);
+    2090             :         break;
+    2091             :       }
+    2092             :     }
+    2093             : 
+    2094             :     node_ = next;
+    2095       34754 :   } while (node_ != stop);
+    2096             : 
+    2097        1948 : _Done:
+    2098             :   // Mark exit label and end node as fetched, otherwise they can be removed by
+    2099             :   // `removeUnreachableCode()`, which could lead to a crash in some later step.
+    2100             :   node_ = func->getEnd();
+    2101        1948 :   if (!node_->hasPassData()) {
+    2102             :     CBLabel* fExit = func->getExitNode();
+    2103        1948 :     RA_POPULATE(fExit);
+    2104        1948 :     fExit->setPosition(++position);
+    2105             : 
+    2106        1948 :     RA_POPULATE(node_);
+    2107        1948 :     node_->setPosition(++position);
+    2108             :   }
+    2109             :   return kErrorOk;
+    2110             : 
+    2111             :   // --------------------------------------------------------------------------
+    2112             :   // [Failure]
+    2113             :   // --------------------------------------------------------------------------
+    2114             : 
+    2115             : NoMem:
+    2116             :   return DebugUtils::errored(kErrorNoHeapMemory);
+    2117             : }
+    2118             : 
+    2119             : // ============================================================================
+    2120             : // [asmjit::X86RAPass - Annotate]
+    2121             : // ============================================================================
+    2122             : 
+    2123           0 : Error X86RAPass::annotate() {
+    2124             : #if !defined(ASMJIT_DISABLE_LOGGING)
+    2125             :   CCFunc* func = getFunc();
+    2126             : 
+    2127             :   CBNode* node_ = func;
+    2128             :   CBNode* end = func->getEnd();
+    2129             : 
+    2130           0 :   Zone& dataZone = cc()->_cbDataZone;
+    2131             :   StringBuilderTmp<256> sb;
+    2132             : 
+    2133           0 :   uint32_t maxLen = 0;
+    2134           0 :   while (node_ && node_ != end) {
+    2135           0 :     if (!node_->hasInlineComment()) {
+    2136           0 :       if (node_->getType() == CBNode::kNodeInst) {
+    2137             :         CBInst* node = static_cast<CBInst*>(node_);
+    2138           0 :         Logging::formatInstruction(
+    2139             :           sb,
+    2140             :           0,
+    2141             :           cc(),
+    2142             :           cc()->getArchType(),
+    2143             :           node->getInstDetail(), node->getOpArray(), node->getOpCount());
+    2144             : 
+    2145             :         node_->setInlineComment(
+    2146           0 :           static_cast<char*>(dataZone.dup(sb.getData(), sb.getLength(), true)));
+    2147           0 :         maxLen = std::max<uint32_t>(maxLen, static_cast<uint32_t>(sb.getLength()));
+    2148             : 
+    2149           0 :         sb.clear();
+    2150             :       }
+    2151             :     }
+    2152             : 
+    2153             :     node_ = node_->getNext();
+    2154             :   }
+    2155           0 :   _annotationLength = maxLen + 1;
+    2156             : #endif // !ASMJIT_DISABLE_LOGGING
+    2157             : 
+    2158           0 :   return kErrorOk;
+    2159             : }
+    2160             : 
+    2161             : // ============================================================================
+    2162             : // [asmjit::X86BaseAlloc]
+    2163             : // ============================================================================
+    2164             : 
+    2165             : struct X86BaseAlloc {
+    2166             :   // --------------------------------------------------------------------------
+    2167             :   // [Construction / Destruction]
+    2168             :   // --------------------------------------------------------------------------
+    2169             : 
+    2170        1948 :   ASMJIT_INLINE X86BaseAlloc(X86RAPass* context) {
+    2171        1948 :     _context = context;
+    2172        1948 :     _cc = context->cc();
+    2173             :   }
+    2174             :   ASMJIT_INLINE ~X86BaseAlloc() {}
+    2175             : 
+    2176             :   // --------------------------------------------------------------------------
+    2177             :   // [Accessors]
+    2178             :   // --------------------------------------------------------------------------
+    2179             : 
+    2180             :   //! Get the context.
+    2181             :   ASMJIT_INLINE X86RAPass* getContext() const { return _context; }
+    2182             :   //! Get the current state (always the same instance as X86RAPass::_x86State).
+    2183       10432 :   ASMJIT_INLINE X86RAState* getState() const { return _context->getState(); }
+    2184             : 
+    2185             :   //! Get the node.
+    2186             :   ASMJIT_INLINE CBNode* getNode() const { return _node; }
+    2187             : 
+    2188             :   //! Get TiedReg list (all).
+    2189             :   ASMJIT_INLINE TiedReg* getTiedArray() const { return _tiedArray[0]; }
+    2190             :   //! Get TiedReg list (per class).
+    2191      333940 :   ASMJIT_INLINE TiedReg* getTiedArrayByKind(uint32_t kind) const { return _tiedArray[kind]; }
+    2192             : 
+    2193             :   //! Get TiedReg count (all).
+    2194             :   ASMJIT_INLINE uint32_t getTiedCount() const { return _tiedTotal; }
+    2195             :   //! Get TiedReg count (per class).
+    2196             :   ASMJIT_INLINE uint32_t getTiedCountByKind(uint32_t kind) const { return _tiedCount.get(kind); }
+    2197             : 
+    2198             :   //! Get if all variables of the given register `kind` are done.
+    2199             :   ASMJIT_INLINE bool isTiedDone(uint32_t kind) const { return _tiedDone.get(kind) == _tiedCount.get(kind); }
+    2200             : 
+    2201             :   //! Get how many variables have been allocated.
+    2202             :   ASMJIT_INLINE uint32_t getTiedDone(uint32_t kind) const { return _tiedDone.get(kind); }
+    2203             :   //! Add to the count of variables allocated.
+    2204       26078 :   ASMJIT_INLINE void addTiedDone(uint32_t kind, uint32_t n = 1) { _tiedDone.add(kind, n); }
+    2205             : 
+    2206             :   //! Get number of allocable registers per class.
+    2207             :   ASMJIT_INLINE uint32_t getGaRegs(uint32_t kind) const {
+    2208             :     return _context->_gaRegs[kind];
+    2209             :   }
+    2210             : 
+    2211             :   // --------------------------------------------------------------------------
+    2212             :   // [Init / Cleanup]
+    2213             :   // --------------------------------------------------------------------------
+    2214             : 
+    2215             : protected:
+    2216             :   // Just to prevent calling these methods by X86RAPass::translate().
+    2217             :   ASMJIT_INLINE void init(CBNode* node, X86RAData* map);
+    2218             :   ASMJIT_INLINE void cleanup();
+    2219             : 
+    2220             :   // --------------------------------------------------------------------------
+    2221             :   // [Unuse]
+    2222             :   // --------------------------------------------------------------------------
+    2223             : 
+    2224             :   template<int C>
+    2225             :   ASMJIT_INLINE void unuseBefore();
+    2226             : 
+    2227             :   template<int C>
+    2228             :   ASMJIT_INLINE void unuseAfter();
+    2229             : 
+    2230             :   // --------------------------------------------------------------------------
+    2231             :   // [Members]
+    2232             :   // --------------------------------------------------------------------------
+    2233             : 
+    2234             :   //! RA context.
+    2235             :   X86RAPass* _context;
+    2236             :   //! Compiler.
+    2237             :   X86Compiler* _cc;
+    2238             : 
+    2239             :   //! Node.
+    2240             :   CBNode* _node;
+    2241             : 
+    2242             :   //! Register allocator (RA) data.
+    2243             :   X86RAData* _raData;
+    2244             :   //! TiedReg list (per register kind).
+    2245             :   TiedReg* _tiedArray[Globals::kMaxVRegKinds];
+    2246             : 
+    2247             :   //! Count of all TiedReg's.
+    2248             :   uint32_t _tiedTotal;
+    2249             : 
+    2250             :   //! TiedReg's total counter.
+    2251             :   X86RegCount _tiedCount;
+    2252             :   //! TiedReg's done counter.
+    2253             :   X86RegCount _tiedDone;
+    2254             : };
+    2255             : 
+    2256             : // ============================================================================
+    2257             : // [asmjit::X86BaseAlloc - Init / Cleanup]
+    2258             : // ============================================================================
+    2259             : 
+    2260             : ASMJIT_INLINE void X86BaseAlloc::init(CBNode* node, X86RAData* raData) {
+    2261       36702 :   _node = node;
+    2262       36702 :   _raData = raData;
+    2263             : 
+    2264             :   // We have to set the correct cursor in case any instruction is emitted
+    2265             :   // during the allocation phase; it has to be emitted before the current
+    2266             :   // instruction.
+    2267       36702 :   _cc->_setCursor(node->getPrev());
+    2268             : 
+    2269             :   // Setup the lists of variables.
+    2270             :   {
+    2271             :     TiedReg* tied = raData->getTiedArray();
+    2272       36702 :     _tiedArray[X86Reg::kKindGp ] = tied;
+    2273       36702 :     _tiedArray[X86Reg::kKindMm ] = tied + raData->getTiedStart(X86Reg::kKindMm );
+    2274       36702 :     _tiedArray[X86Reg::kKindK  ] = tied + raData->getTiedStart(X86Reg::kKindK  );
+    2275       36702 :     _tiedArray[X86Reg::kKindVec] = tied + raData->getTiedStart(X86Reg::kKindVec);
+    2276             :   }
+    2277             : 
+    2278             :   // Setup counters.
+    2279       36702 :   _tiedTotal = raData->tiedTotal;
+    2280       36702 :   _tiedCount = raData->tiedCount;
+    2281             :   _tiedDone.reset();
+    2282             : 
+    2283             :   // Connect VREG->TIED.
+    2284       98196 :   for (uint32_t i = 0; i < _tiedTotal; i++) {
+    2285       61494 :     TiedReg* tied = &_tiedArray[0][i];
+    2286       61494 :     VirtReg* vreg = tied->vreg;
+    2287       61494 :     vreg->_tied = tied;
+    2288             :   }
+    2289             : }
+    2290             : 
+    2291             : ASMJIT_INLINE void X86BaseAlloc::cleanup() {
+    2292             :   // Disconnect VREG->TIED.
+    2293       96248 :   for (uint32_t i = 0; i < _tiedTotal; i++) {
+    2294       61494 :     TiedReg* tied = &_tiedArray[0][i];
+    2295       61494 :     VirtReg* vreg = tied->vreg;
+    2296       61494 :     vreg->_tied = nullptr;
+    2297             :   }
+    2298             : }
+    2299             : 
+    2300             : // ============================================================================
+    2301             : // [asmjit::X86BaseAlloc - Unuse]
+    2302             : // ============================================================================
+    2303             : 
+    2304             : template<int C>
+    2305             : ASMJIT_INLINE void X86BaseAlloc::unuseBefore() {
+    2306             :   TiedReg* tiedArray = getTiedArrayByKind(C);
+    2307             :   uint32_t tiedCount = getTiedCountByKind(C);
+    2308             : 
+    2309             :   const uint32_t checkFlags = TiedReg::kXReg  |
+    2310             :                               TiedReg::kRMem  |
+    2311             :                               TiedReg::kRFunc |
+    2312             :                               TiedReg::kRCall ;
+    2313             : 
+    2314       89854 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2315       56748 :     TiedReg* tied = &tiedArray[i];
+    2316       56748 :     if ((tied->flags & checkFlags) == TiedReg::kWReg)
+    2317       22140 :       _context->unuse<C>(tied->vreg);
+    2318             :   }
+    2319             : }
+    2320             : 
+    2321             : template<int C>
+    2322             : ASMJIT_INLINE void X86BaseAlloc::unuseAfter() {
+    2323             :   TiedReg* tiedArray = getTiedArrayByKind(C);
+    2324             :   uint32_t tiedCount = getTiedCountByKind(C);
+    2325             : 
+    2326       96248 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2327       61494 :     TiedReg* tied = &tiedArray[i];
+    2328       61494 :     if (tied->flags & TiedReg::kUnuse)
+    2329       21840 :       _context->unuse<C>(tied->vreg);
+    2330             :   }
+    2331             : }
+    2332             : 
+    2333             : // ============================================================================
+    2334             : // [asmjit::X86VarAlloc]
+    2335             : // ============================================================================
+    2336             : 
+    2337             : //! \internal
+    2338             : //!
+    2339             : //! Register allocator context (asm instructions).
+    2340             : struct X86VarAlloc : public X86BaseAlloc {
+    2341             :   // --------------------------------------------------------------------------
+    2342             :   // [Construction / Destruction]
+    2343             :   // --------------------------------------------------------------------------
+    2344             : 
+    2345        1948 :   ASMJIT_INLINE X86VarAlloc(X86RAPass* context) : X86BaseAlloc(context) {}
+    2346        1948 :   ASMJIT_INLINE ~X86VarAlloc() {}
+    2347             : 
+    2348             :   // --------------------------------------------------------------------------
+    2349             :   // [Run]
+    2350             :   // --------------------------------------------------------------------------
+    2351             : 
+    2352             :   Error run(CBNode* node);
+    2353             : 
+    2354             :   // --------------------------------------------------------------------------
+    2355             :   // [Init / Cleanup]
+    2356             :   // --------------------------------------------------------------------------
+    2357             : 
+    2358             : protected:
+    2359             :   // Just to prevent calling these methods by X86RAPass::translate().
+    2360             :   ASMJIT_INLINE void init(CBNode* node, X86RAData* map);
+    2361             :   ASMJIT_INLINE void cleanup();
+    2362             : 
+    2363             :   // --------------------------------------------------------------------------
+    2364             :   // [Plan / Spill / Alloc]
+    2365             :   // --------------------------------------------------------------------------
+    2366             : 
+    2367             :   template<int C>
+    2368             :   ASMJIT_INLINE void plan();
+    2369             : 
+    2370             :   template<int C>
+    2371             :   ASMJIT_INLINE void spill();
+    2372             : 
+    2373             :   template<int C>
+    2374             :   ASMJIT_INLINE void alloc();
+    2375             : 
+    2376             :   // --------------------------------------------------------------------------
+    2377             :   // [GuessAlloc / GuessSpill]
+    2378             :   // --------------------------------------------------------------------------
+    2379             : 
+    2380             :   //! Guess which register is the best candidate for `vreg` from `allocableRegs`.
+    2381             :   //!
+    2382             :   //! The guess is based on looking ahead and inspecting register allocator
+    2383             :   //! instructions. The main reason is to prevent allocation to a register
+    2384             :   //! which is needed by next instruction(s). The guess look tries to go as far
+    2385             :   //! as possible, after the remaining registers are zero, the mask of previous
+    2386             :   //! registers (called 'safeRegs') is returned.
+    2387             :   template<int C>
+    2388             :   ASMJIT_INLINE uint32_t guessAlloc(VirtReg* vreg, uint32_t allocableRegs);
+    2389             : 
+    2390             :   //! Guess whether to move the given `vreg` instead of spill.
+    2391             :   template<int C>
+    2392             :   ASMJIT_INLINE uint32_t guessSpill(VirtReg* vreg, uint32_t allocableRegs);
+    2393             : 
+    2394             :   // --------------------------------------------------------------------------
+    2395             :   // [Modified]
+    2396             :   // --------------------------------------------------------------------------
+    2397             : 
+    2398             :   template<int C>
+    2399             :   ASMJIT_INLINE void modified();
+    2400             : 
+    2401             :   // --------------------------------------------------------------------------
+    2402             :   // [Members]
+    2403             :   // --------------------------------------------------------------------------
+    2404             : 
+    2405             :   //! Will alloc to these registers.
+    2406             :   X86RegMask _willAlloc;
+    2407             :   //! Will spill these registers.
+    2408             :   X86RegMask _willSpill;
+    2409             : };
+    2410             : 
+    2411             : // ============================================================================
+    2412             : // [asmjit::X86VarAlloc - Run]
+    2413             : // ============================================================================
+    2414             : 
+    2415       35054 : Error X86VarAlloc::run(CBNode* node_) {
+    2416             :   // Initialize.
+    2417             :   X86RAData* raData = node_->getPassData<X86RAData>();
+    2418             :   // Initialize the allocator; connect Vd->Va.
+    2419             :   init(node_, raData);
+    2420             : 
+    2421       35054 :   if (raData->tiedTotal != 0) {
+    2422             :     // Unuse overwritten variables.
+    2423             :     unuseBefore<X86Reg::kKindGp>();
+    2424             :     unuseBefore<X86Reg::kKindMm>();
+    2425             :     unuseBefore<X86Reg::kKindVec>();
+    2426             : 
+    2427             :     // Plan the allocation. Planner assigns input/output registers for each
+    2428             :     // variable and decides whether to allocate it in register or stack.
+    2429             :     plan<X86Reg::kKindGp>();
+    2430             :     plan<X86Reg::kKindMm>();
+    2431             :     plan<X86Reg::kKindVec>();
+    2432             : 
+    2433             :     // Spill all variables marked by plan().
+    2434             :     spill<X86Reg::kKindGp>();
+    2435             :     spill<X86Reg::kKindMm>();
+    2436             :     spill<X86Reg::kKindVec>();
+    2437             : 
+    2438             :     // Alloc all variables marked by plan().
+    2439             :     alloc<X86Reg::kKindGp>();
+    2440             :     alloc<X86Reg::kKindMm>();
+    2441             :     alloc<X86Reg::kKindVec>();
+    2442             : 
+    2443             :     // Translate node operands.
+    2444       33106 :     if (node_->getType() == CBNode::kNodeInst) {
+    2445             :       CBInst* node = static_cast<CBInst*>(node_);
+    2446       31158 :       if (node->hasExtraReg()) {
+    2447             :         Reg reg = node->getExtraReg().toReg<Reg>();
+    2448           0 :         ASMJIT_PROPAGATE(X86RAPass_translateOperands(_context, &reg, 1));
+    2449             :         node->setExtraReg(reg);
+    2450             :       }
+    2451       31158 :       ASMJIT_PROPAGATE(X86RAPass_translateOperands(_context, node->getOpArray(), node->getOpCount()));
+    2452             :     }
+    2453        1948 :     else if (node_->getType() == CBNode::kNodePushArg) {
+    2454             :       CCPushArg* node = static_cast<CCPushArg*>(node_);
+    2455             : 
+    2456             :       CCFuncCall* call = static_cast<CCFuncCall*>(node->getCall());
+    2457             :       FuncDetail& fd = call->getDetail();
+    2458             : 
+    2459             :       uint32_t argIndex = 0;
+    2460           0 :       uint32_t argMask = node->_args;
+    2461             : 
+    2462             :       VirtReg* cvtReg = node->getCvtReg();
+    2463             :       VirtReg* srcReg = node->getSrcReg();
+    2464             : 
+    2465             :       // Convert first.
+    2466             :       ASMJIT_ASSERT(srcReg->getPhysId() != Globals::kInvalidRegId);
+    2467             : 
+    2468           0 :       if (cvtReg) {
+    2469             :         ASMJIT_ASSERT(cvtReg->getPhysId() != Globals::kInvalidRegId);
+    2470             : 
+    2471             :         X86Reg dstOp(X86Reg::fromSignature(cvtReg->getSignature(), cvtReg->getId()));
+    2472             :         X86Reg srcOp(X86Reg::fromSignature(srcReg->getSignature(), srcReg->getId()));
+    2473             : 
+    2474             :         // Emit conversion after the prolog.
+    2475           0 :         X86Internal::emitArgMove(reinterpret_cast<X86Emitter*>(_context->cc()),
+    2476             :           dstOp, cvtReg->getTypeId(),
+    2477           0 :           srcOp, srcReg->getTypeId(), _context->_avxEnabled);
+    2478             :         srcReg = cvtReg;
+    2479             :       }
+    2480             : 
+    2481           0 :       while (argMask != 0) {
+    2482           0 :         if (argMask & 0x1) {
+    2483           0 :           FuncDetail::Value& arg = fd.getArg(argIndex);
+    2484             :           ASMJIT_ASSERT(arg.byStack());
+    2485             : 
+    2486           0 :           X86Mem dst = x86::ptr(_context->_zsp, -static_cast<int>(_context->getGpSize()) + arg.getStackOffset());
+    2487           0 :           _context->emitRegToStack(arg.getTypeId(), &dst, srcReg->getTypeId(), srcReg->getPhysId());
+    2488             :         }
+    2489             : 
+    2490           0 :         argIndex++;
+    2491           0 :         argMask >>= 1;
+    2492             :       }
+    2493             :     }
+    2494             : 
+    2495             :     // Mark variables as modified.
+    2496             :     modified<X86Reg::kKindGp>();
+    2497             :     modified<X86Reg::kKindMm>();
+    2498             :     modified<X86Reg::kKindVec>();
+    2499             : 
+    2500             :     // Cleanup; disconnect Vd->Va.
+    2501             :     cleanup();
+    2502             : 
+    2503             :     // Update clobbered mask.
+    2504       33106 :     _context->_clobberedRegs.or_(_willAlloc);
+    2505             :   }
+    2506             : 
+    2507             :   // Update clobbered mask.
+    2508       35054 :   _context->_clobberedRegs.or_(raData->clobberedRegs);
+    2509             : 
+    2510             :   // Unuse.
+    2511       35054 :   if (raData->tiedTotal != 0) {
+    2512             :     unuseAfter<X86Reg::kKindGp>();
+    2513             :     unuseAfter<X86Reg::kKindMm>();
+    2514             :     unuseAfter<X86Reg::kKindVec>();
+    2515             :   }
+    2516             : 
+    2517             :   return kErrorOk;
+    2518             : }
+    2519             : 
+    2520             : // ============================================================================
+    2521             : // [asmjit::X86VarAlloc - Init / Cleanup]
+    2522             : // ============================================================================
+    2523             : 
+    2524             : ASMJIT_INLINE void X86VarAlloc::init(CBNode* node, X86RAData* raData) {
+    2525             :   X86BaseAlloc::init(node, raData);
+    2526             : 
+    2527             :   // These will block planner from assigning them during planning. Planner will
+    2528             :   // add more registers when assigning registers to variables that don't need
+    2529             :   // any specific register.
+    2530       35054 :   _willAlloc = raData->inRegs;
+    2531             :   _willAlloc.or_(raData->outRegs);
+    2532             :   _willSpill.reset();
+    2533             : }
+    2534             : 
+    2535             : ASMJIT_INLINE void X86VarAlloc::cleanup() {
+    2536             :   X86BaseAlloc::cleanup();
+    2537             : }
+    2538             : 
+    2539             : // ============================================================================
+    2540             : // [asmjit::X86VarAlloc - Plan / Spill / Alloc]
+    2541             : // ============================================================================
+    2542             : 
+    2543             : template<int C>
+    2544             : ASMJIT_INLINE void X86VarAlloc::plan() {
+    2545       46474 :   if (isTiedDone(C)) return;
+    2546             : 
+    2547             :   uint32_t i;
+    2548             :   uint32_t willAlloc = _willAlloc.get(C);
+    2549             :   uint32_t willFree = 0;
+    2550             : 
+    2551             :   TiedReg* tiedArray = getTiedArrayByKind(C);
+    2552             :   uint32_t tiedCount = getTiedCountByKind(C);
+    2553             :   X86RAState* state = getState();
+    2554             : 
+    2555             :   // Calculate 'willAlloc' and 'willFree' masks based on mandatory masks.
+    2556       95954 :   for (i = 0; i < tiedCount; i++) {
+    2557       56748 :     TiedReg* tied = &tiedArray[i];
+    2558       56748 :     VirtReg* vreg = tied->vreg;
+    2559             : 
+    2560       56748 :     uint32_t vaFlags = tied->flags;
+    2561             :     uint32_t physId = vreg->getPhysId();
+    2562       56748 :     uint32_t regMask = (physId != Globals::kInvalidRegId) ? Utils::mask(physId) : 0;
+    2563             : 
+    2564       56748 :     if ((vaFlags & TiedReg::kXReg) != 0) {
+    2565             :       // Planning register allocation. First check whether the variable is
+    2566             :       // already allocated in register and if it can stay allocated there.
+    2567             :       //
+    2568             :       // The following conditions may happen:
+    2569             :       //
+    2570             :       // a) Allocated register is one of the mandatoryRegs.
+    2571             :       // b) Allocated register is one of the allocableRegs.
+    2572       56748 :       uint32_t mandatoryRegs = tied->inRegs;
+    2573       56748 :       uint32_t allocableRegs = tied->allocableRegs;
+    2574             : 
+    2575       56748 :       if (regMask != 0) {
+    2576             :         // Special path for planning output-only registers.
+    2577       30670 :         if ((vaFlags & TiedReg::kXReg) == TiedReg::kWReg) {
+    2578           0 :           uint32_t outPhysId = tied->outPhysId;
+    2579           0 :           mandatoryRegs = (outPhysId != Globals::kInvalidRegId) ? Utils::mask(outPhysId) : 0;
+    2580             : 
+    2581           0 :           if ((mandatoryRegs | allocableRegs) & regMask) {
+    2582             :             tied->setOutPhysId(physId);
+    2583           0 :             tied->flags |= TiedReg::kWDone;
+    2584             : 
+    2585           0 :             if (mandatoryRegs & regMask) {
+    2586             :               // Case 'a' - 'willAlloc' contains initially all inRegs from all TiedReg's.
+    2587             :               ASMJIT_ASSERT((willAlloc & regMask) != 0);
+    2588             :             }
+    2589             :             else {
+    2590             :               // Case 'b'.
+    2591             :               tied->setOutPhysId(physId);
+    2592           0 :               willAlloc |= regMask;
+    2593             :             }
+    2594             : 
+    2595             :             addTiedDone(C);
+    2596           0 :             continue;
+    2597             :           }
+    2598             :         }
+    2599             :         else {
+    2600       30670 :           if ((mandatoryRegs | allocableRegs) & regMask) {
+    2601             :             tied->setInPhysId(physId);
+    2602       30336 :             tied->flags |= TiedReg::kRDone;
+    2603             : 
+    2604       30336 :             if (mandatoryRegs & regMask) {
+    2605             :               // Case 'a' - 'willAlloc' contains initially all inRegs from all TiedReg's.
+    2606             :               ASMJIT_ASSERT((willAlloc & regMask) != 0);
+    2607             :             }
+    2608             :             else {
+    2609             :               // Case 'b'.
+    2610       28722 :               tied->inRegs |= regMask;
+    2611       28722 :               willAlloc |= regMask;
+    2612             :             }
+    2613             : 
+    2614             :             addTiedDone(C);
+    2615       30336 :             continue;
+    2616             :           }
+    2617             :         }
+    2618             :       }
+    2619             : 
+    2620             :       // Variable is not allocated or allocated in register that doesn't
+    2621             :       // match inRegs or allocableRegs. The next step is to pick the best
+    2622             :       // register for this variable. If `inRegs` contains any register the
+    2623             :       // decision is simple - we have to follow, in other case will use
+    2624             :       // the advantage of `guessAlloc()` to find a register (or registers)
+    2625             :       // by looking ahead. But the best way to find a good register is not
+    2626             :       // here since now we have no information about the registers that
+    2627             :       // will be freed. So instead of finding register here, we just mark
+    2628             :       // the current register (if variable is allocated) as `willFree` so
+    2629             :       // the planner can use this information in the second step to plan the
+    2630             :       // allocation as a whole.
+    2631       26412 :       willFree |= regMask;
+    2632       26412 :       continue;
+    2633       26412 :     }
+    2634             :     else {
+    2635           0 :       if (regMask != 0) {
+    2636           0 :         willFree |= regMask;
+    2637           0 :         continue;
+    2638             :       }
+    2639             :       else {
+    2640           0 :         tied->flags |= TiedReg::kRDone;
+    2641             :         addTiedDone(C);
+    2642           0 :         continue;
+    2643             :       }
+    2644             :     }
+    2645             :   }
+    2646             : 
+    2647             :   // Occupied registers without 'willFree' registers; contains basically
+    2648             :   // all the registers we can use to allocate variables without inRegs
+    2649             :   // specified.
+    2650       39206 :   uint32_t occupied = state->_occupied.get(C) & ~willFree;
+    2651             :   uint32_t willSpill = 0;
+    2652             : 
+    2653             :   // Find the best registers for variables that are not allocated yet.
+    2654       95954 :   for (i = 0; i < tiedCount; i++) {
+    2655       56748 :     TiedReg* tied = &tiedArray[i];
+    2656       56748 :     VirtReg* vreg = tied->vreg;
+    2657       56748 :     uint32_t vaFlags = tied->flags;
+    2658             : 
+    2659       56748 :     if ((vaFlags & TiedReg::kXReg) != 0) {
+    2660       56748 :       if ((vaFlags & TiedReg::kXReg) == TiedReg::kWReg) {
+    2661       22140 :         if (vaFlags & TiedReg::kWDone)
+    2662           0 :           continue;
+    2663             : 
+    2664             :         // Skip all registers that have assigned outPhysId. Spill if occupied.
+    2665       22140 :         if (tied->hasOutPhysId()) {
+    2666           0 :           uint32_t outRegs = Utils::mask(tied->outPhysId);
+    2667           0 :           willSpill |= occupied & outRegs;
+    2668           0 :           continue;
+    2669           0 :         }
+    2670             :       }
+    2671             :       else {
+    2672       34608 :         if (vaFlags & TiedReg::kRDone)
+    2673       30336 :           continue;
+    2674             : 
+    2675             :         // We skip all registers that have assigned inPhysId, indicates that
+    2676             :         // the register to allocate in is known.
+    2677        4272 :         if (tied->hasInPhysId()) {
+    2678           0 :           uint32_t inRegs = tied->inRegs;
+    2679           0 :           willSpill |= occupied & inRegs;
+    2680           0 :           continue;
+    2681           0 :         }
+    2682             :       }
+    2683             : 
+    2684       26412 :       uint32_t m = tied->inRegs;
+    2685       26412 :       if (tied->hasOutPhysId())
+    2686           0 :         m |= Utils::mask(tied->outPhysId);
+    2687             : 
+    2688       26412 :       m = tied->allocableRegs & ~(willAlloc ^ m);
+    2689             :       m = guessAlloc<C>(vreg, m);
+    2690             :       ASMJIT_ASSERT(m != 0);
+    2691             : 
+    2692       26412 :       uint32_t candidateRegs = m & ~occupied;
+    2693             :       uint32_t homeMask = vreg->getHomeMask();
+    2694             : 
+    2695             :       uint32_t physId;
+    2696             :       uint32_t regMask;
+    2697             : 
+    2698       26412 :       if (candidateRegs == 0) {
+    2699         138 :         candidateRegs = m & occupied & ~state->_modified.get(C);
+    2700         138 :         if (candidateRegs == 0)
+    2701             :           candidateRegs = m;
+    2702             :       }
+    2703       26412 :       if (candidateRegs & homeMask) candidateRegs &= homeMask;
+    2704             : 
+    2705             :       physId = Utils::findFirstBit(candidateRegs);
+    2706             :       regMask = Utils::mask(physId);
+    2707             : 
+    2708       26412 :       if ((vaFlags & TiedReg::kXReg) == TiedReg::kWReg) {
+    2709             :         tied->setOutPhysId(physId);
+    2710             :       }
+    2711             :       else {
+    2712             :         tied->setInPhysId(physId);
+    2713        4272 :         tied->inRegs = regMask;
+    2714             :       }
+    2715             : 
+    2716       26412 :       willAlloc |= regMask;
+    2717       26412 :       willSpill |= regMask & occupied;
+    2718             :       willFree  &=~regMask;
+    2719       26412 :       occupied  |= regMask;
+    2720             : 
+    2721       26412 :       continue;
+    2722       26412 :     }
+    2723           0 :     else if ((vaFlags & TiedReg::kXMem) != 0) {
+    2724             :       uint32_t physId = vreg->getPhysId();
+    2725           0 :       if (physId != Globals::kInvalidRegId && (vaFlags & TiedReg::kXMem) != TiedReg::kWMem) {
+    2726           0 :         willSpill |= Utils::mask(physId);
+    2727             :       }
+    2728             :     }
+    2729             :   }
+    2730             : 
+    2731             :   // Set calculated masks back to the allocator; needed by spill() and alloc().
+    2732             :   _willSpill.set(C, willSpill);
+    2733             :   _willAlloc.set(C, willAlloc);
+    2734             : }
+    2735             : 
+    2736             : template<int C>
+    2737             : ASMJIT_INLINE void X86VarAlloc::spill() {
+    2738             :   uint32_t m = _willSpill.get(C);
+    2739             :   uint32_t i = static_cast<uint32_t>(0) - 1;
+    2740       33106 :   if (m == 0) return;
+    2741             : 
+    2742             :   X86RAState* state = getState();
+    2743             :   VirtReg** vregs = state->getListByKind(C);
+    2744             : 
+    2745             :   // Available registers for decision if move has any benefit over spill.
+    2746             :   uint32_t availableRegs = getGaRegs(C) & ~(state->_occupied.get(C) | m | _willAlloc.get(C));
+    2747             : 
+    2748             :   do {
+    2749             :     // We always advance one more to destroy the bit that we have found.
+    2750         138 :     uint32_t bitIndex = Utils::findFirstBit(m) + 1;
+    2751             : 
+    2752         138 :     i += bitIndex;
+    2753         138 :     m >>= bitIndex;
+    2754             : 
+    2755         138 :     VirtReg* vreg = vregs[i];
+    2756             :     ASMJIT_ASSERT(vreg);
+    2757             : 
+    2758             :     TiedReg* tied = vreg->_tied;
+    2759             :     ASMJIT_ASSERT(!tied || (tied->flags & TiedReg::kXReg) == 0);
+    2760             : 
+    2761             :     if (vreg->isModified() && availableRegs) {
+    2762             :       // Don't check for alternatives if the variable has to be spilled.
+    2763             :       if (!tied || (tied->flags & TiedReg::kSpill) == 0) {
+    2764             :         uint32_t altRegs = guessSpill<C>(vreg, availableRegs);
+    2765             : 
+    2766             :         if (altRegs != 0) {
+    2767             :           uint32_t physId = Utils::findFirstBit(altRegs);
+    2768             :           uint32_t regMask = Utils::mask(physId);
+    2769             : 
+    2770             :           _context->move<C>(vreg, physId);
+    2771             :           availableRegs ^= regMask;
+    2772             :           continue;
+    2773             :         }
+    2774             :       }
+    2775             :     }
+    2776             : 
+    2777         138 :     _context->spill<C>(vreg);
+    2778         138 :   } while (m != 0);
+    2779             : }
+    2780             : 
+    2781             : template<int C>
+    2782             : ASMJIT_INLINE void X86VarAlloc::alloc() {
+    2783       40374 :   if (isTiedDone(C)) return;
+    2784             : 
+    2785             :   uint32_t i;
+    2786             :   bool didWork;
+    2787             : 
+    2788             :   TiedReg* tiedArray = getTiedArrayByKind(C);
+    2789             :   uint32_t tiedCount = getTiedCountByKind(C);
+    2790             : 
+    2791             :   // Alloc `in` regs.
+    2792       29562 :   do {
+    2793             :     didWork = false;
+    2794       74600 :     for (i = 0; i < tiedCount; i++) {
+    2795       45038 :       TiedReg* aTied = &tiedArray[i];
+    2796       45038 :       VirtReg* aVReg = aTied->vreg;
+    2797             : 
+    2798       45038 :       if ((aTied->flags & (TiedReg::kRReg | TiedReg::kRDone)) != TiedReg::kRReg)
+    2799       40766 :         continue;
+    2800             : 
+    2801             :       uint32_t aPhysId = aVReg->getPhysId();
+    2802        4272 :       uint32_t bPhysId = aTied->inPhysId;
+    2803             : 
+    2804             :       // Shouldn't be the same.
+    2805             :       ASMJIT_ASSERT(aPhysId != bPhysId);
+    2806             : 
+    2807        4272 :       VirtReg* bVReg = getState()->getListByKind(C)[bPhysId];
+    2808        4272 :       if (bVReg) {
+    2809             :         // Gp registers only - Swap two registers if we can solve two
+    2810             :         // allocation tasks by a single 'xchg' instruction, swapping
+    2811             :         // two registers required by the instruction/node or one register
+    2812             :         // required with another non-required.
+    2813           0 :         if (C == X86Reg::kKindGp && aPhysId != Globals::kInvalidRegId) {
+    2814           0 :           TiedReg* bTied = bVReg->_tied;
+    2815             :           _context->swapGp(aVReg, bVReg);
+    2816             : 
+    2817           0 :           aTied->flags |= TiedReg::kRDone;
+    2818             :           addTiedDone(C);
+    2819             : 
+    2820             :           // Double-hit, two registers allocated by a single xchg.
+    2821           0 :           if (bTied && bTied->inPhysId == aPhysId) {
+    2822           0 :             bTied->flags |= TiedReg::kRDone;
+    2823             :             addTiedDone(C);
+    2824             :           }
+    2825             : 
+    2826             :           didWork = true;
+    2827           0 :           continue;
+    2828           0 :         }
+    2829             :       }
+    2830        4272 :       else if (aPhysId != Globals::kInvalidRegId) {
+    2831             :         _context->move<C>(aVReg, bPhysId);
+    2832             : 
+    2833         334 :         aTied->flags |= TiedReg::kRDone;
+    2834             :         addTiedDone(C);
+    2835             : 
+    2836             :         didWork = true;
+    2837         334 :         continue;
+    2838             :       }
+    2839             :       else {
+    2840             :         _context->alloc<C>(aVReg, bPhysId);
+    2841             : 
+    2842        3938 :         aTied->flags |= TiedReg::kRDone;
+    2843             :         addTiedDone(C);
+    2844             : 
+    2845             :         didWork = true;
+    2846        3938 :         continue;
+    2847             :       }
+    2848             :     }
+    2849             :   } while (didWork);
+    2850             : 
+    2851             :   // Alloc 'out' regs.
+    2852       62152 :   for (i = 0; i < tiedCount; i++) {
+    2853       36862 :     TiedReg* tied = &tiedArray[i];
+    2854       36862 :     VirtReg* vreg = tied->vreg;
+    2855             : 
+    2856       36862 :     if ((tied->flags & (TiedReg::kXReg | TiedReg::kWDone)) != TiedReg::kWReg)
+    2857       14722 :       continue;
+    2858             : 
+    2859       22140 :     uint32_t physId = tied->outPhysId;
+    2860             :     ASMJIT_ASSERT(physId != Globals::kInvalidRegId);
+    2861             : 
+    2862       22140 :     if (vreg->getPhysId() != physId) {
+    2863             :       ASMJIT_ASSERT(getState()->getListByKind(C)[physId] == nullptr);
+    2864       22140 :       _context->attach<C>(vreg, physId, false);
+    2865             :     }
+    2866             : 
+    2867       22140 :     tied->flags |= TiedReg::kWDone;
+    2868             :     addTiedDone(C);
+    2869             :   }
+    2870             : }
+    2871             : 
+    2872             : // ============================================================================
+    2873             : // [asmjit::X86VarAlloc - GuessAlloc / GuessSpill]
+    2874             : // ============================================================================
+    2875             : 
+    2876             : template<int C>
+    2877             : ASMJIT_INLINE uint32_t X86VarAlloc::guessAlloc(VirtReg* vreg, uint32_t allocableRegs) {
+    2878             :   ASMJIT_ASSERT(allocableRegs != 0);
+    2879             : 
+    2880             :   // Stop now if there is only one bit (register) set in `allocableRegs` mask.
+    2881             :   if (Utils::isPowerOf2(allocableRegs)) return allocableRegs;
+    2882             : 
+    2883       26078 :   uint32_t raId = vreg->_raId;
+    2884             :   uint32_t safeRegs = allocableRegs;
+    2885             : 
+    2886             :   uint32_t i;
+    2887             :   uint32_t maxLookAhead = kCompilerDefaultLookAhead;
+    2888             : 
+    2889             :   // Look ahead and calculate mask of special registers on both - input/output.
+    2890       26078 :   CBNode* node = _node;
+    2891      119272 :   for (i = 0; i < maxLookAhead; i++) {
+    2892             :     X86RAData* raData = node->getPassData<X86RAData>();
+    2893      119200 :     RABits* liveness = raData ? raData->liveness : static_cast<RABits*>(nullptr);
+    2894             : 
+    2895             :     // If the variable becomes dead it doesn't make sense to continue.
+    2896      119200 :     if (liveness && !liveness->getBit(raId)) break;
+    2897             : 
+    2898             :     // Stop on `CBSentinel` and `CCFuncRet`.
+    2899       99342 :     if (node->hasFlag(CBNode::kFlagIsRet)) break;
+    2900             : 
+    2901             :     // Stop on conditional jump, we don't follow them.
+    2902       99342 :     if (node->hasFlag(CBNode::kFlagIsJcc)) break;
+    2903             : 
+    2904             :     // Advance on non-conditional jump.
+    2905       99342 :     if (node->hasFlag(CBNode::kFlagIsJmp)) {
+    2906             :       node = static_cast<CBJump*>(node)->getTarget();
+    2907             :       // Stop on jump that is not followed.
+    2908           0 :       if (!node) break;
+    2909             :     }
+    2910             : 
+    2911             :     node = node->getNext();
+    2912             :     ASMJIT_ASSERT(node != nullptr);
+    2913             : 
+    2914             :     raData = node->getPassData<X86RAData>();
+    2915       99342 :     if (raData) {
+    2916             :       TiedReg* tied = raData->findTiedByKind(C, vreg);
+    2917             :       uint32_t mask;
+    2918             : 
+    2919       99342 :       if (tied) {
+    2920             :         // If the variable is overwritten it doesn't make sense to continue.
+    2921       29928 :         if ((tied->flags & TiedReg::kRAll) == 0)
+    2922             :           break;
+    2923             : 
+    2924       29928 :         mask = tied->allocableRegs;
+    2925       29928 :         if (mask != 0) {
+    2926       29928 :           allocableRegs &= mask;
+    2927       29928 :           if (allocableRegs == 0) break;
+    2928             :           safeRegs = allocableRegs;
+    2929             :         }
+    2930             : 
+    2931       29272 :         mask = tied->inRegs;
+    2932       29272 :         if (mask != 0) {
+    2933        2088 :           allocableRegs &= mask;
+    2934        2088 :           if (allocableRegs == 0) break;
+    2935             :           safeRegs = allocableRegs;
+    2936        2088 :           break;
+    2937             :         }
+    2938             : 
+    2939       27184 :         allocableRegs &= ~(raData->outRegs.get(C) | raData->clobberedRegs.get(C));
+    2940       27184 :         if (allocableRegs == 0) break;
+    2941             :       }
+    2942             :       else {
+    2943       69414 :         allocableRegs &= ~(raData->inRegs.get(C) | raData->outRegs.get(C) | raData->clobberedRegs.get(C));
+    2944       69414 :         if (allocableRegs == 0) break;
+    2945             :       }
+    2946             : 
+    2947             :       safeRegs = allocableRegs;
+    2948             :     }
+    2949             :   }
+    2950             : 
+    2951             :   return safeRegs;
+    2952             : }
+    2953             : 
+    2954             : template<int C>
+    2955             : ASMJIT_INLINE uint32_t X86VarAlloc::guessSpill(VirtReg* vreg, uint32_t allocableRegs) {
+    2956             :   ASMJIT_ASSERT(allocableRegs != 0);
+    2957             : 
+    2958             :   return 0;
+    2959             : }
+    2960             : 
+    2961             : // ============================================================================
+    2962             : // [asmjit::X86VarAlloc - Modified]
+    2963             : // ============================================================================
+    2964             : 
+    2965             : template<int C>
+    2966             : ASMJIT_INLINE void X86VarAlloc::modified() {
+    2967             :   TiedReg* tiedArray = getTiedArrayByKind(C);
+    2968             :   uint32_t tiedCount = getTiedCountByKind(C);
+    2969             : 
+    2970       89854 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    2971       56748 :     TiedReg* tied = &tiedArray[i];
+    2972             : 
+    2973       56748 :     if (tied->flags & TiedReg::kWReg) {
+    2974       30892 :       VirtReg* vreg = tied->vreg;
+    2975             : 
+    2976             :       uint32_t physId = vreg->getPhysId();
+    2977             :       uint32_t regMask = Utils::mask(physId);
+    2978             : 
+    2979             :       vreg->setModified(true);
+    2980       30892 :       _context->_x86State._modified.or_(C, regMask);
+    2981             :     }
+    2982             :   }
+    2983             : }
+    2984             : 
+    2985             : // ============================================================================
+    2986             : // [asmjit::X86CallAlloc]
+    2987             : // ============================================================================
+    2988             : 
+    2989             : //! \internal
+    2990             : //!
+    2991             : //! Register allocator context (function call).
+    2992             : struct X86CallAlloc : public X86BaseAlloc {
+    2993             :   // --------------------------------------------------------------------------
+    2994             :   // [Construction / Destruction]
+    2995             :   // --------------------------------------------------------------------------
+    2996             : 
+    2997        1948 :   ASMJIT_INLINE X86CallAlloc(X86RAPass* context) : X86BaseAlloc(context) {}
+    2998        1948 :   ASMJIT_INLINE ~X86CallAlloc() {}
+    2999             : 
+    3000             :   // --------------------------------------------------------------------------
+    3001             :   // [Accessors]
+    3002             :   // --------------------------------------------------------------------------
+    3003             : 
+    3004             :   //! Get the node.
+    3005        1648 :   ASMJIT_INLINE CCFuncCall* getNode() const { return static_cast<CCFuncCall*>(_node); }
+    3006             : 
+    3007             :   // --------------------------------------------------------------------------
+    3008             :   // [Run]
+    3009             :   // --------------------------------------------------------------------------
+    3010             : 
+    3011             :   Error run(CCFuncCall* node);
+    3012             : 
+    3013             :   // --------------------------------------------------------------------------
+    3014             :   // [Init / Cleanup]
+    3015             :   // --------------------------------------------------------------------------
+    3016             : 
+    3017             : protected:
+    3018             :   // Just to prevent calling these methods from X86RAPass::translate().
+    3019             :   ASMJIT_INLINE void init(CCFuncCall* node, X86RAData* raData);
+    3020             :   ASMJIT_INLINE void cleanup();
+    3021             : 
+    3022             :   // --------------------------------------------------------------------------
+    3023             :   // [Plan / Alloc / Spill / Move]
+    3024             :   // --------------------------------------------------------------------------
+    3025             : 
+    3026             :   template<int C>
+    3027             :   ASMJIT_INLINE void plan();
+    3028             : 
+    3029             :   template<int C>
+    3030             :   ASMJIT_INLINE void spill();
+    3031             : 
+    3032             :   template<int C>
+    3033             :   ASMJIT_INLINE void alloc();
+    3034             : 
+    3035             :   // --------------------------------------------------------------------------
+    3036             :   // [AllocImmsOnStack]
+    3037             :   // --------------------------------------------------------------------------
+    3038             : 
+    3039             :   ASMJIT_INLINE void allocImmsOnStack();
+    3040             : 
+    3041             :   // --------------------------------------------------------------------------
+    3042             :   // [Duplicate]
+    3043             :   // --------------------------------------------------------------------------
+    3044             : 
+    3045             :   template<int C>
+    3046             :   ASMJIT_INLINE void duplicate();
+    3047             : 
+    3048             :   // --------------------------------------------------------------------------
+    3049             :   // [GuessAlloc / GuessSpill]
+    3050             :   // --------------------------------------------------------------------------
+    3051             : 
+    3052             :   template<int C>
+    3053             :   ASMJIT_INLINE uint32_t guessAlloc(VirtReg* vreg, uint32_t allocableRegs);
+    3054             : 
+    3055             :   template<int C>
+    3056             :   ASMJIT_INLINE uint32_t guessSpill(VirtReg* vreg, uint32_t allocableRegs);
+    3057             : 
+    3058             :   // --------------------------------------------------------------------------
+    3059             :   // [Save]
+    3060             :   // --------------------------------------------------------------------------
+    3061             : 
+    3062             :   template<int C>
+    3063             :   ASMJIT_INLINE void save();
+    3064             : 
+    3065             :   // --------------------------------------------------------------------------
+    3066             :   // [Clobber]
+    3067             :   // --------------------------------------------------------------------------
+    3068             : 
+    3069             :   template<int C>
+    3070             :   ASMJIT_INLINE void clobber();
+    3071             : 
+    3072             :   // --------------------------------------------------------------------------
+    3073             :   // [Ret]
+    3074             :   // --------------------------------------------------------------------------
+    3075             : 
+    3076             :   ASMJIT_INLINE void ret();
+    3077             : 
+    3078             :   // --------------------------------------------------------------------------
+    3079             :   // [Members]
+    3080             :   // --------------------------------------------------------------------------
+    3081             : 
+    3082             :   //! Will alloc to these registers.
+    3083             :   X86RegMask _willAlloc;
+    3084             :   //! Will spill these registers.
+    3085             :   X86RegMask _willSpill;
+    3086             : };
+    3087             : 
+    3088             : // ============================================================================
+    3089             : // [asmjit::X86CallAlloc - Run]
+    3090             : // ============================================================================
+    3091             : 
+    3092        1648 : Error X86CallAlloc::run(CCFuncCall* node) {
+    3093             :   // Initialize the allocator; prepare basics and connect Vd->Va.
+    3094             :   X86RAData* raData = node->getPassData<X86RAData>();
+    3095             :   init(node, raData);
+    3096             : 
+    3097             :   // Plan register allocation. Planner is only able to assign one register per
+    3098             :   // variable. If any variable is used multiple times it will be handled later.
+    3099             :   plan<X86Reg::kKindGp >();
+    3100             :   plan<X86Reg::kKindMm >();
+    3101             :   plan<X86Reg::kKindVec>();
+    3102             : 
+    3103             :   // Spill.
+    3104             :   spill<X86Reg::kKindGp >();
+    3105             :   spill<X86Reg::kKindMm >();
+    3106             :   spill<X86Reg::kKindVec>();
+    3107             : 
+    3108             :   // Alloc.
+    3109             :   alloc<X86Reg::kKindGp >();
+    3110             :   alloc<X86Reg::kKindMm >();
+    3111             :   alloc<X86Reg::kKindVec>();
+    3112             : 
+    3113             :   // Unuse clobbered registers that are not used to pass function arguments and
+    3114             :   // save variables used to pass function arguments that will be reused later on.
+    3115             :   save<X86Reg::kKindGp >();
+    3116             :   save<X86Reg::kKindMm >();
+    3117             :   save<X86Reg::kKindVec>();
+    3118             : 
+    3119             :   // Allocate immediates in registers and on the stack.
+    3120             :   allocImmsOnStack();
+    3121             : 
+    3122             :   // Duplicate.
+    3123             :   duplicate<X86Reg::kKindGp >();
+    3124             :   duplicate<X86Reg::kKindMm >();
+    3125             :   duplicate<X86Reg::kKindVec>();
+    3126             : 
+    3127             :   // Translate call operand.
+    3128        1648 :   ASMJIT_PROPAGATE(X86RAPass_translateOperands(_context, node->getOpArray(), node->getOpCount()));
+    3129             : 
+    3130             :   // To emit instructions after call.
+    3131        1648 :   _cc->_setCursor(node);
+    3132             : 
+    3133             :   // If the callee pops stack it has to be manually adjusted back.
+    3134             :   FuncDetail& fd = node->getDetail();
+    3135        1648 :   if (fd.hasFlag(CallConv::kFlagCalleePopsStack) && fd.getArgStackSize() != 0)
+    3136           0 :     _cc->emit(X86Inst::kIdSub, _context->_zsp, static_cast<int>(fd.getArgStackSize()));
+    3137             : 
+    3138             :   // Clobber.
+    3139             :   clobber<X86Reg::kKindGp >();
+    3140             :   clobber<X86Reg::kKindMm >();
+    3141             :   clobber<X86Reg::kKindVec>();
+    3142             : 
+    3143             :   // Return.
+    3144             :   ret();
+    3145             : 
+    3146             :   // Unuse.
+    3147             :   unuseAfter<X86Reg::kKindGp >();
+    3148             :   unuseAfter<X86Reg::kKindMm >();
+    3149             :   unuseAfter<X86Reg::kKindVec>();
+    3150             : 
+    3151             :   // Cleanup; disconnect Vd->Va.
+    3152             :   cleanup();
+    3153             : 
+    3154             :   return kErrorOk;
+    3155             : }
+    3156             : 
+    3157             : // ============================================================================
+    3158             : // [asmjit::X86CallAlloc - Init / Cleanup]
+    3159             : // ============================================================================
+    3160             : 
+    3161             : ASMJIT_INLINE void X86CallAlloc::init(CCFuncCall* node, X86RAData* raData) {
+    3162             :   X86BaseAlloc::init(node, raData);
+    3163             : 
+    3164             :   // Create mask of all registers that will be used to pass function arguments.
+    3165             :   _willAlloc.reset();
+    3166             :   _willAlloc.set(X86Reg::kKindGp , node->getDetail().getUsedRegs(X86Reg::kKindGp ));
+    3167             :   _willAlloc.set(X86Reg::kKindMm , node->getDetail().getUsedRegs(X86Reg::kKindMm ));
+    3168             :   _willAlloc.set(X86Reg::kKindK  , node->getDetail().getUsedRegs(X86Reg::kKindK  ));
+    3169             :   _willAlloc.set(X86Reg::kKindVec, node->getDetail().getUsedRegs(X86Reg::kKindVec));
+    3170             :   _willSpill.reset();
+    3171             : }
+    3172             : 
+    3173             : ASMJIT_INLINE void X86CallAlloc::cleanup() {
+    3174             :   X86BaseAlloc::cleanup();
+    3175             : }
+    3176             : 
+    3177             : // ============================================================================
+    3178             : // [asmjit::X86CallAlloc - Plan / Spill / Alloc]
+    3179             : // ============================================================================
+    3180             : 
+    3181             : template<int C>
+    3182             : ASMJIT_INLINE void X86CallAlloc::plan() {
+    3183             :   uint32_t i;
+    3184        4944 :   uint32_t clobbered = _raData->clobberedRegs.get(C);
+    3185             : 
+    3186             :   uint32_t willAlloc = _willAlloc.get(C);
+    3187        4944 :   uint32_t willFree = clobbered & ~willAlloc;
+    3188             : 
+    3189             :   TiedReg* tiedArray = getTiedArrayByKind(C);
+    3190             :   uint32_t tiedCount = getTiedCountByKind(C);
+    3191             : 
+    3192             :   X86RAState* state = getState();
+    3193             : 
+    3194             :   // Calculate 'willAlloc' and 'willFree' masks based on mandatory masks.
+    3195        9690 :   for (i = 0; i < tiedCount; i++) {
+    3196        4746 :     TiedReg* tied = &tiedArray[i];
+    3197        4746 :     VirtReg* vreg = tied->vreg;
+    3198             : 
+    3199        4746 :     uint32_t vaFlags = tied->flags;
+    3200             :     uint32_t physId = vreg->getPhysId();
+    3201        4746 :     uint32_t regMask = (physId != Globals::kInvalidRegId) ? Utils::mask(physId) : 0;
+    3202             : 
+    3203        4746 :     if ((vaFlags & TiedReg::kRReg) != 0) {
+    3204             :       // Planning register allocation. First check whether the variable is
+    3205             :       // already allocated in register and if it can stay there. Function
+    3206             :       // arguments are passed either in a specific register or in stack so
+    3207             :       // we care mostly of mandatory registers.
+    3208        3098 :       uint32_t inRegs = tied->inRegs;
+    3209             : 
+    3210        3098 :       if (inRegs == 0) {
+    3211        1648 :         inRegs = tied->allocableRegs;
+    3212             :       }
+    3213             : 
+    3214             :       // Optimize situation where the variable has to be allocated in a
+    3215             :       // mandatory register, but it's already allocated in register that
+    3216             :       // is not clobbered (i.e. it will survive function call).
+    3217        3098 :       if ((regMask & inRegs) != 0 || ((regMask & ~clobbered) != 0 && (vaFlags & TiedReg::kUnuse) == 0)) {
+    3218             :         tied->setInPhysId(physId);
+    3219        2290 :         tied->flags |= TiedReg::kRDone;
+    3220             :         addTiedDone(C);
+    3221             :       }
+    3222             :       else {
+    3223         808 :         willFree |= regMask;
+    3224             :       }
+    3225             :     }
+    3226             :     else {
+    3227             :       // Memory access - if variable is allocated it has to be freed.
+    3228        1648 :       if (regMask != 0) {
+    3229           0 :         willFree |= regMask;
+    3230             :       }
+    3231             :       else {
+    3232        1648 :         tied->flags |= TiedReg::kRDone;
+    3233             :         addTiedDone(C);
+    3234             :       }
+    3235             :     }
+    3236             :   }
+    3237             : 
+    3238             :   // Occupied registers without 'willFree' registers; contains basically
+    3239             :   // all the registers we can use to allocate variables without inRegs
+    3240             :   // speficied.
+    3241        4944 :   uint32_t occupied = state->_occupied.get(C) & ~willFree;
+    3242             :   uint32_t willSpill = 0;
+    3243             : 
+    3244             :   // Find the best registers for variables that are not allocated yet. Only
+    3245             :   // useful for Gp registers used as call operand.
+    3246        9690 :   for (i = 0; i < tiedCount; i++) {
+    3247        4746 :     TiedReg* tied = &tiedArray[i];
+    3248        1648 :     VirtReg* vreg = tied->vreg;
+    3249             : 
+    3250        4746 :     uint32_t vaFlags = tied->flags;
+    3251        4746 :     if ((vaFlags & TiedReg::kRDone) != 0 || (vaFlags & TiedReg::kRReg) == 0)
+    3252        3938 :       continue;
+    3253             : 
+    3254             :     // All registers except Gp used by call itself must have inPhysId.
+    3255         808 :     uint32_t m = tied->inRegs;
+    3256           0 :     if (C != X86Reg::kKindGp || m) {
+    3257             :       ASMJIT_ASSERT(m != 0);
+    3258             :       tied->setInPhysId(Utils::findFirstBit(m));
+    3259         808 :       willSpill |= occupied & m;
+    3260         808 :       continue;
+    3261             :     }
+    3262             : 
+    3263           0 :     m = tied->allocableRegs & ~(willAlloc ^ m);
+    3264             :     m = guessAlloc<C>(vreg, m);
+    3265             :     ASMJIT_ASSERT(m != 0);
+    3266             : 
+    3267           0 :     uint32_t candidateRegs = m & ~occupied;
+    3268           0 :     if (candidateRegs == 0) {
+    3269           0 :       candidateRegs = m & occupied & ~state->_modified.get(C);
+    3270           0 :       if (candidateRegs == 0)
+    3271             :         candidateRegs = m;
+    3272             :     }
+    3273             : 
+    3274           0 :     if (!(vaFlags & (TiedReg::kWReg | TiedReg::kUnuse)) && (candidateRegs & ~clobbered))
+    3275             :       candidateRegs &= ~clobbered;
+    3276             : 
+    3277             :     uint32_t physId = Utils::findFirstBit(candidateRegs);
+    3278             :     uint32_t regMask = Utils::mask(physId);
+    3279             : 
+    3280             :     tied->setInPhysId(physId);
+    3281           0 :     tied->inRegs = regMask;
+    3282             : 
+    3283           0 :     willAlloc |= regMask;
+    3284           0 :     willSpill |= regMask & occupied;
+    3285             :     willFree &= ~regMask;
+    3286             : 
+    3287           0 :     occupied |= regMask;
+    3288           0 :     continue;
+    3289             :   }
+    3290             : 
+    3291             :   // Set calculated masks back to the allocator; needed by spill() and alloc().
+    3292             :   _willSpill.set(C, willSpill);
+    3293             :   _willAlloc.set(C, willAlloc);
+    3294             : }
+    3295             : 
+    3296             : template<int C>
+    3297             : ASMJIT_INLINE void X86CallAlloc::spill() {
+    3298             :   uint32_t m = _willSpill.get(C);
+    3299             :   uint32_t i = static_cast<uint32_t>(0) - 1;
+    3300             : 
+    3301        1648 :   if (m == 0)
+    3302             :     return;
+    3303             : 
+    3304             :   X86RAState* state = getState();
+    3305             :   VirtReg** sVars = state->getListByKind(C);
+    3306             : 
+    3307             :   // Available registers for decision if move has any benefit over spill.
+    3308             :   uint32_t availableRegs = getGaRegs(C) & ~(state->_occupied.get(C) | m | _willAlloc.get(C));
+    3309             : 
+    3310             :   do {
+    3311             :     // We always advance one more to destroy the bit that we have found.
+    3312         410 :     uint32_t bitIndex = Utils::findFirstBit(m) + 1;
+    3313             : 
+    3314         410 :     i += bitIndex;
+    3315         410 :     m >>= bitIndex;
+    3316             : 
+    3317         410 :     VirtReg* vreg = sVars[i];
+    3318             :     ASMJIT_ASSERT(vreg && !vreg->_tied);
+    3319             : 
+    3320             :     if (vreg->isModified() && availableRegs) {
+    3321             :       uint32_t available = guessSpill<C>(vreg, availableRegs);
+    3322             :       if (available != 0) {
+    3323             :         uint32_t physId = Utils::findFirstBit(available);
+    3324             :         uint32_t regMask = Utils::mask(physId);
+    3325             : 
+    3326             :         _context->move<C>(vreg, physId);
+    3327             :         availableRegs ^= regMask;
+    3328             :         continue;
+    3329             :       }
+    3330             :     }
+    3331             : 
+    3332         410 :     _context->spill<C>(vreg);
+    3333         410 :   } while (m != 0);
+    3334             : }
+    3335             : 
+    3336             : template<int C>
+    3337             : ASMJIT_INLINE void X86CallAlloc::alloc() {
+    3338        1648 :   if (isTiedDone(C)) return;
+    3339             : 
+    3340             :   TiedReg* tiedArray = getTiedArrayByKind(C);
+    3341             :   uint32_t tiedCount = getTiedCountByKind(C);
+    3342             : 
+    3343             :   uint32_t i;
+    3344             :   bool didWork;
+    3345             : 
+    3346        1616 :   do {
+    3347             :     didWork = false;
+    3348        4872 :     for (i = 0; i < tiedCount; i++) {
+    3349        3256 :       TiedReg* aTied = &tiedArray[i];
+    3350        3256 :       VirtReg* aVReg = aTied->vreg;
+    3351        3256 :       if ((aTied->flags & (TiedReg::kRReg | TiedReg::kRDone)) != TiedReg::kRReg) continue;
+    3352             : 
+    3353             :       uint32_t sPhysId = aVReg->getPhysId();
+    3354         808 :       uint32_t bPhysId = aTied->inPhysId;
+    3355             : 
+    3356             :       // Shouldn't be the same.
+    3357             :       ASMJIT_ASSERT(sPhysId != bPhysId);
+    3358             : 
+    3359         808 :       VirtReg* bVReg = getState()->getListByKind(C)[bPhysId];
+    3360         808 :       if (bVReg) {
+    3361           0 :         TiedReg* bTied = bVReg->_tied;
+    3362             : 
+    3363             :         // GP registers only - Swap two registers if we can solve two
+    3364             :         // allocation tasks by a single 'xchg' instruction, swapping
+    3365             :         // two registers required by the instruction/node or one register
+    3366             :         // required with another non-required.
+    3367             :         if (C == X86Reg::kKindGp) {
+    3368             :           _context->swapGp(aVReg, bVReg);
+    3369             : 
+    3370           0 :           aTied->flags |= TiedReg::kRDone;
+    3371             :           addTiedDone(C);
+    3372             : 
+    3373             :           // Double-hit, two registers allocated by a single swap.
+    3374           0 :           if (bTied && bTied->inPhysId == sPhysId) {
+    3375           0 :             bTied->flags |= TiedReg::kRDone;
+    3376             :             addTiedDone(C);
+    3377             :           }
+    3378             : 
+    3379             :           didWork = true;
+    3380           0 :           continue;
+    3381             :         }
+    3382           0 :       }
+    3383         808 :       else if (sPhysId != Globals::kInvalidRegId) {
+    3384             :         _context->move<C>(aVReg, bPhysId);
+    3385         322 :         _context->_clobberedRegs.or_(C, Utils::mask(bPhysId));
+    3386             : 
+    3387         322 :         aTied->flags |= TiedReg::kRDone;
+    3388             :         addTiedDone(C);
+    3389             : 
+    3390             :         didWork = true;
+    3391         322 :         continue;
+    3392             :       }
+    3393             :       else {
+    3394             :         _context->alloc<C>(aVReg, bPhysId);
+    3395         486 :         _context->_clobberedRegs.or_(C, Utils::mask(bPhysId));
+    3396             : 
+    3397         486 :         aTied->flags |= TiedReg::kRDone;
+    3398             :         addTiedDone(C);
+    3399             : 
+    3400             :         didWork = true;
+    3401         486 :         continue;
+    3402             :       }
+    3403             :     }
+    3404             :   } while (didWork);
+    3405             : }
+    3406             : 
+    3407             : // ============================================================================
+    3408             : // [asmjit::X86CallAlloc - AllocImmsOnStack]
+    3409             : // ============================================================================
+    3410             : 
+    3411             : ASMJIT_INLINE void X86CallAlloc::allocImmsOnStack() {
+    3412             :   CCFuncCall* node = getNode();
+    3413             :   FuncDetail& fd = node->getDetail();
+    3414             : 
+    3415             :   uint32_t argCount = fd.getArgCount();
+    3416        1648 :   Operand_* args = node->_args;
+    3417             : 
+    3418        3518 :   for (uint32_t i = 0; i < argCount; i++) {
+    3419        1870 :     Operand_& op = args[i];
+    3420        1870 :     if (!op.isImm()) continue;
+    3421             : 
+    3422             :     const Imm& imm = static_cast<const Imm&>(op);
+    3423             :     const FuncDetail::Value& arg = fd.getArg(i);
+    3424             :     uint32_t varType = arg.getTypeId();
+    3425             : 
+    3426         420 :     if (arg.byReg()) {
+    3427         420 :       _context->emitImmToReg(varType, arg.getRegId(), &imm);
+    3428             :     }
+    3429             :     else {
+    3430           0 :       X86Mem dst = x86::ptr(_context->_zsp, -static_cast<int>(_context->getGpSize()) + arg.getStackOffset());
+    3431           0 :       _context->emitImmToStack(varType, &dst, &imm);
+    3432             :     }
+    3433             :   }
+    3434             : }
+    3435             : 
+    3436             : // ============================================================================
+    3437             : // [asmjit::X86CallAlloc - Duplicate]
+    3438             : // ============================================================================
+    3439             : 
+    3440             : template<int C>
+    3441             : ASMJIT_INLINE void X86CallAlloc::duplicate() {
+    3442             :   TiedReg* tiedArray = getTiedArrayByKind(C);
+    3443             :   uint32_t tiedCount = getTiedCountByKind(C);
+    3444             : 
+    3445        6394 :   for (uint32_t i = 0; i < tiedCount; i++) {
+    3446        4746 :     TiedReg* tied = &tiedArray[i];
+    3447        4746 :     if ((tied->flags & TiedReg::kRReg) == 0) continue;
+    3448             : 
+    3449        3098 :     uint32_t inRegs = tied->inRegs;
+    3450        3098 :     if (!inRegs) continue;
+    3451             : 
+    3452        1450 :     VirtReg* vreg = tied->vreg;
+    3453             :     uint32_t physId = vreg->getPhysId();
+    3454             : 
+    3455             :     ASMJIT_ASSERT(physId != Globals::kInvalidRegId);
+    3456             : 
+    3457        1450 :     inRegs &= ~Utils::mask(physId);
+    3458        1450 :     if (!inRegs) continue;
+    3459             : 
+    3460           0 :     for (uint32_t dupIndex = 0; inRegs != 0; dupIndex++, inRegs >>= 1) {
+    3461           0 :       if (inRegs & 0x1) {
+    3462           0 :         _context->emitMove(vreg, dupIndex, physId, "Duplicate");
+    3463           0 :         _context->_clobberedRegs.or_(C, Utils::mask(dupIndex));
+    3464             :       }
+    3465             :     }
+    3466             :   }
+    3467             : }
+    3468             : 
+    3469             : // ============================================================================
+    3470             : // [asmjit::X86CallAlloc - GuessAlloc / GuessSpill]
+    3471             : // ============================================================================
+    3472             : 
+    3473             : template<int C>
+    3474             : ASMJIT_INLINE uint32_t X86CallAlloc::guessAlloc(VirtReg* vreg, uint32_t allocableRegs) {
+    3475             :   ASMJIT_ASSERT(allocableRegs != 0);
+    3476             : 
+    3477             :   // Stop now if there is only one bit (register) set in 'allocableRegs' mask.
+    3478             :   if (Utils::isPowerOf2(allocableRegs))
+    3479             :     return allocableRegs;
+    3480             : 
+    3481             :   uint32_t i;
+    3482             :   uint32_t safeRegs = allocableRegs;
+    3483             :   uint32_t maxLookAhead = kCompilerDefaultLookAhead;
+    3484             : 
+    3485             :   // Look ahead and calculate mask of special registers on both - input/output.
+    3486           0 :   CBNode* node = _node;
+    3487           0 :   for (i = 0; i < maxLookAhead; i++) {
+    3488             :     // Stop on `CCFuncRet` and `CBSentinel`.
+    3489           0 :     if (node->hasFlag(CBNode::kFlagIsRet))
+    3490             :       break;
+    3491             : 
+    3492             :     // Stop on conditional jump, we don't follow them.
+    3493           0 :     if (node->hasFlag(CBNode::kFlagIsJcc))
+    3494             :       break;
+    3495             : 
+    3496             :     // Advance on non-conditional jump.
+    3497           0 :     if (node->hasFlag(CBNode::kFlagIsJmp)) {
+    3498             :       node = static_cast<CBJump*>(node)->getTarget();
+    3499             :       // Stop on jump that is not followed.
+    3500           0 :       if (!node) break;
+    3501             :     }
+    3502             : 
+    3503             :     node = node->getNext();
+    3504             :     ASMJIT_ASSERT(node != nullptr);
+    3505             : 
+    3506             :     X86RAData* raData = node->getPassData<X86RAData>();
+    3507           0 :     if (raData) {
+    3508             :       TiedReg* tied = raData->findTiedByKind(C, vreg);
+    3509           0 :       if (tied) {
+    3510           0 :         uint32_t inRegs = tied->inRegs;
+    3511           0 :         if (inRegs != 0) {
+    3512             :           safeRegs = allocableRegs;
+    3513           0 :           allocableRegs &= inRegs;
+    3514             : 
+    3515           0 :           if (allocableRegs == 0)
+    3516           0 :             goto _UseSafeRegs;
+    3517             :           else
+    3518             :             return allocableRegs;
+    3519             :         }
+    3520             :       }
+    3521             : 
+    3522             :       safeRegs = allocableRegs;
+    3523           0 :       allocableRegs &= ~(raData->inRegs.get(C) | raData->outRegs.get(C) | raData->clobberedRegs.get(C));
+    3524             : 
+    3525           0 :       if (allocableRegs == 0)
+    3526             :         break;
+    3527             :     }
+    3528             :   }
+    3529             : 
+    3530           0 : _UseSafeRegs:
+    3531             :   return safeRegs;
+    3532             : }
+    3533             : 
+    3534             : template<int C>
+    3535             : ASMJIT_INLINE uint32_t X86CallAlloc::guessSpill(VirtReg* vreg, uint32_t allocableRegs) {
+    3536             :   ASMJIT_ASSERT(allocableRegs != 0);
+    3537             :   return 0;
+    3538             : }
+    3539             : 
+    3540             : // ============================================================================
+    3541             : // [asmjit::X86CallAlloc - Save]
+    3542             : // ============================================================================
+    3543             : 
+    3544             : template<int C>
+    3545             : ASMJIT_INLINE void X86CallAlloc::save() {
+    3546             :   X86RAState* state = getState();
+    3547             :   VirtReg** sVars = state->getListByKind(C);
+    3548             : 
+    3549             :   uint32_t i;
+    3550        4944 :   uint32_t affected = _raData->clobberedRegs.get(C) & state->_occupied.get(C) & state->_modified.get(C);
+    3551             : 
+    3552        6460 :   for (i = 0; affected != 0; i++, affected >>= 1) {
+    3553        4812 :     if (affected & 0x1) {
+    3554        3940 :       VirtReg* vreg = sVars[i];
+    3555             :       ASMJIT_ASSERT(vreg != nullptr);
+    3556             :       ASMJIT_ASSERT(vreg->isModified());
+    3557             : 
+    3558        3940 :       TiedReg* tied = vreg->_tied;
+    3559        3940 :       if (!tied || (tied->flags & (TiedReg::kWReg | TiedReg::kUnuse)) == 0)
+    3560        3468 :         _context->save<C>(vreg);
+    3561             :     }
+    3562             :   }
+    3563             : }
+    3564             : 
+    3565             : // ============================================================================
+    3566             : // [asmjit::X86CallAlloc - Clobber]
+    3567             : // ============================================================================
+    3568             : 
+    3569             : template<int C>
+    3570             : ASMJIT_INLINE void X86CallAlloc::clobber() {
+    3571             :   X86RAState* state = getState();
+    3572             :   VirtReg** sVars = state->getListByKind(C);
+    3573             : 
+    3574             :   uint32_t i;
+    3575        4944 :   uint32_t affected = _raData->clobberedRegs.get(C) & state->_occupied.get(C);
+    3576             : 
+    3577        6886 :   for (i = 0; affected != 0; i++, affected >>= 1) {
+    3578        5238 :     if (affected & 0x1) {
+    3579        4834 :       VirtReg* vreg = sVars[i];
+    3580             :       ASMJIT_ASSERT(vreg != nullptr);
+    3581             : 
+    3582        4834 :       TiedReg* tied = vreg->_tied;
+    3583             :       uint32_t vdState = VirtReg::kStateNone;
+    3584             : 
+    3585        4834 :       if (!vreg->isModified() || (tied && (tied->flags & (TiedReg::kWAll | TiedReg::kUnuse)) != 0))
+    3586             :         vdState = VirtReg::kStateMem;
+    3587        4834 :       _context->unuse<C>(vreg, vdState);
+    3588             :     }
+    3589             :   }
+    3590             : }
+    3591             : 
+    3592             : // ============================================================================
+    3593             : // [asmjit::X86CallAlloc - Ret]
+    3594             : // ============================================================================
+    3595             : 
+    3596             : ASMJIT_INLINE void X86CallAlloc::ret() {
+    3597             :   CCFuncCall* node = getNode();
+    3598             :   FuncDetail& fd = node->getDetail();
+    3599        1648 :   Operand_* rets = node->_ret;
+    3600             : 
+    3601        4944 :   for (uint32_t i = 0; i < 2; i++) {
+    3602        3296 :     const FuncDetail::Value& ret = fd.getRet(i);
+    3603        3296 :     Operand_* op = &rets[i];
+    3604             : 
+    3605        3296 :     if (!ret.byReg() || !op->isVirtReg())
+    3606        1648 :       continue;
+    3607             : 
+    3608        1648 :     VirtReg* vreg = _cc->getVirtRegById(op->getId());
+    3609             :     uint32_t regId = ret.getRegId();
+    3610             : 
+    3611        1648 :     switch (vreg->getKind()) {
+    3612           0 :       case X86Reg::kKindGp:
+    3613           0 :         _context->unuse<X86Reg::kKindGp>(vreg);
+    3614           0 :         _context->attach<X86Reg::kKindGp>(vreg, regId, true);
+    3615             :         break;
+    3616             : 
+    3617           0 :       case X86Reg::kKindMm:
+    3618           0 :         _context->unuse<X86Reg::kKindMm>(vreg);
+    3619           0 :         _context->attach<X86Reg::kKindMm>(vreg, regId, true);
+    3620             :         break;
+    3621             : 
+    3622             :       case X86Reg::kKindVec:
+    3623        1648 :         if (X86Reg::kindOf(ret.getRegType()) == X86Reg::kKindVec) {
+    3624        1648 :           _context->unuse<X86Reg::kKindVec>(vreg);
+    3625        1648 :           _context->attach<X86Reg::kKindVec>(vreg, regId, true);
+    3626             :         }
+    3627             :         else {
+    3628             :           uint32_t elementId = TypeId::elementOf(vreg->getTypeId());
+    3629           0 :           uint32_t size = (elementId == TypeId::kF32) ? 4 : 8;
+    3630             : 
+    3631           0 :           X86Mem m = _context->getVarMem(vreg);
+    3632             :           m.setSize(size);
+    3633             : 
+    3634           0 :           _context->unuse<X86Reg::kKindVec>(vreg, VirtReg::kStateMem);
+    3635           0 :           _cc->fstp(m);
+    3636             :         }
+    3637             :         break;
+    3638             :     }
+    3639             :   }
+    3640             : }
+    3641             : 
+    3642             : // ============================================================================
+    3643             : // [asmjit::X86RAPass - TranslateOperands]
+    3644             : // ============================================================================
+    3645             : 
+    3646             : //! \internal
+    3647       32806 : static Error X86RAPass_translateOperands(X86RAPass* self, Operand_* opArray, uint32_t opCount) {
+    3648             :   X86Compiler* cc = self->cc();
+    3649             : 
+    3650             :   // Translate variables into registers.
+    3651       96890 :   for (uint32_t i = 0; i < opCount; i++) {
+    3652       64084 :     Operand_* op = &opArray[i];
+    3653             :     if (op->isVirtReg()) {
+    3654             :       VirtReg* vreg = cc->getVirtRegById(op->getId());
+    3655             :       ASMJIT_ASSERT(vreg != nullptr);
+    3656             :       ASMJIT_ASSERT(vreg->getPhysId() != Globals::kInvalidRegId);
+    3657       50596 :       op->_reg.id = vreg->getPhysId();
+    3658             :     }
+    3659       13488 :     else if (op->isMem()) {
+    3660             :       X86Mem* m = static_cast<X86Mem*>(op);
+    3661             : 
+    3662        6100 :       if (m->hasBaseReg() && cc->isVirtRegValid(m->getBaseId())) {
+    3663             :         VirtReg* vreg = cc->getVirtRegById(m->getBaseId());
+    3664             : 
+    3665        6100 :         if (m->isRegHome()) {
+    3666           0 :           self->getVarCell(vreg);
+    3667             :         }
+    3668             :         else {
+    3669             :           ASMJIT_ASSERT(vreg->getPhysId() != Globals::kInvalidRegId);
+    3670        6100 :           op->_mem.base = vreg->getPhysId();
+    3671             :         }
+    3672             :       }
+    3673             : 
+    3674        6100 :       if (m->hasIndexReg() && cc->isVirtRegValid(m->getIndexId())) {
+    3675             :         VirtReg* vreg = cc->getVirtRegById(m->getIndexId());
+    3676           0 :         op->_mem.index = vreg->getPhysId();
+    3677             :       }
+    3678             :     }
+    3679             :   }
+    3680             : 
+    3681       32806 :   return kErrorOk;
+    3682             : }
+    3683             : 
+    3684             : // ============================================================================
+    3685             : // [asmjit::X86RAPass - TranslatePrologEpilog]
+    3686             : // ============================================================================
+    3687             : 
+    3688             : //! \internal
+    3689        1948 : static Error X86RAPass_prepareFuncFrame(X86RAPass* self, CCFunc* func) {
+    3690             :   FuncFrameInfo& ffi = func->getFrameInfo();
+    3691             : 
+    3692             :   X86RegMask& clobberedRegs = self->_clobberedRegs;
+    3693             : 
+    3694             :   // Initialize dirty registers.
+    3695             :   ffi.setDirtyRegs(X86Reg::kKindGp , clobberedRegs.get(X86Reg::kKindGp ));
+    3696             :   ffi.setDirtyRegs(X86Reg::kKindMm , clobberedRegs.get(X86Reg::kKindMm ));
+    3697             :   ffi.setDirtyRegs(X86Reg::kKindK  , clobberedRegs.get(X86Reg::kKindK  ));
+    3698             :   ffi.setDirtyRegs(X86Reg::kKindVec, clobberedRegs.get(X86Reg::kKindVec));
+    3699             : 
+    3700             :   // Initialize stack size & alignment.
+    3701        1948 :   ffi.setStackFrameSize(self->_memAllTotal);
+    3702        1948 :   ffi.setStackFrameAlignment(self->_memMaxAlign);
+    3703             : 
+    3704        1948 :   return kErrorOk;
+    3705             : }
+    3706             : 
+    3707             : //! \internal
+    3708        1948 : static Error X86RAPass_patchFuncMem(X86RAPass* self, CCFunc* func, CBNode* stop, FuncFrameLayout& layout) {
+    3709             :   X86Compiler* cc = self->cc();
+    3710             :   CBNode* node = func;
+    3711             : 
+    3712             :   do {
+    3713       50102 :     if (node->getType() == CBNode::kNodeInst) {
+    3714             :       CBInst* iNode = static_cast<CBInst*>(node);
+    3715             : 
+    3716       40662 :       if (iNode->hasMemOp()) {
+    3717             :         X86Mem* m = iNode->getMemOp<X86Mem>();
+    3718             : 
+    3719       14528 :         if (m->isArgHome()) {
+    3720             :           m->addOffsetLo32(layout.getStackArgsOffset());
+    3721             :           m->clearArgHome();
+    3722             :         }
+    3723             : 
+    3724       14528 :         if (m->isRegHome() && Operand::isPackedId(m->getBaseId())) {
+    3725             :           VirtReg* vreg = cc->getVirtRegById(m->getBaseId());
+    3726             :           ASMJIT_ASSERT(vreg != nullptr);
+    3727             : 
+    3728             :           RACell* cell = vreg->getMemCell();
+    3729             :           ASMJIT_ASSERT(cell != nullptr);
+    3730             : 
+    3731        8428 :           m->_setBase(cc->_nativeGpReg.getType(), self->_varBaseRegId);
+    3732        8428 :           m->addOffsetLo32(self->_varBaseOffset + cell->offset);
+    3733             :           m->clearRegHome();
+    3734             :         }
+    3735             :       }
+    3736             :     }
+    3737             : 
+    3738             :     node = node->getNext();
+    3739       50102 :   } while (node != stop);
+    3740             : 
+    3741        1948 :   return kErrorOk;
+    3742             : }
+    3743             : 
+    3744             : // ============================================================================
+    3745             : // [asmjit::X86RAPass - Translate - Jump]
+    3746             : // ============================================================================
+    3747             : 
+    3748             : //! \internal
+    3749           0 : static void X86RAPass_translateJump(X86RAPass* self, CBJump* jNode, CBLabel* jTarget) {
+    3750             :   X86Compiler* cc = self->cc();
+    3751             : 
+    3752             :   CBNode* injectRef = self->getFunc()->getEnd()->getPrev();
+    3753           0 :   CBNode* prevCursor = cc->setCursor(injectRef);
+    3754             : 
+    3755           0 :   self->switchState(jTarget->getPassData<RAData>()->state);
+    3756             : 
+    3757             :   // Any code necessary to `switchState()` will be added at the end of the function.
+    3758           0 :   if (cc->getCursor() != injectRef) {
+    3759             :     // TODO: Can fail.
+    3760           0 :     CBLabel* injectLabel = cc->newLabelNode();
+    3761             : 
+    3762             :     // Add the jump to the target.
+    3763           0 :     cc->jmp(jTarget->getLabel());
+    3764             : 
+    3765             :     // Inject the label.
+    3766             :     cc->_setCursor(injectRef);
+    3767           0 :     cc->addNode(injectLabel);
+    3768             : 
+    3769             :     // Finally, patch `jNode` target.
+    3770             :     ASMJIT_ASSERT(jNode->getOpCount() > 0);
+    3771           0 :     jNode->_opArray[jNode->getOpCount() - 1] = injectLabel->getLabel();
+    3772           0 :     jNode->_target = injectLabel;
+    3773             :     // If we injected any code it may not satisfy short form anymore.
+    3774             :     jNode->delOptions(X86Inst::kOptionShortForm);
+    3775             :   }
+    3776             : 
+    3777             :   cc->_setCursor(prevCursor);
+    3778           0 :   self->loadState(jNode->getPassData<RAData>()->state);
+    3779           0 : }
+    3780             : 
+    3781             : // ============================================================================
+    3782             : // [asmjit::X86RAPass - Translate - Ret]
+    3783             : // ============================================================================
+    3784             : 
+    3785        1948 : static Error X86RAPass_translateRet(X86RAPass* self, CCFuncRet* rNode, CBLabel* exitTarget) {
+    3786             :   X86Compiler* cc = self->cc();
+    3787             :   CBNode* node = rNode->getNext();
+    3788             : 
+    3789             :   // 32-bit mode requires to push floating point return value(s), handle it
+    3790             :   // here as it's a special case.
+    3791             :   X86RAData* raData = rNode->getPassData<X86RAData>();
+    3792        1948 :   if (raData) {
+    3793        1948 :     TiedReg* tiedArray = raData->tiedArray;
+    3794        1948 :     uint32_t tiedTotal = raData->tiedTotal;
+    3795             : 
+    3796        3896 :     for (uint32_t i = 0; i < tiedTotal; i++) {
+    3797        1948 :       TiedReg* tied = &tiedArray[i];
+    3798        1948 :       if (tied->flags & (TiedReg::kX86Fld4 | TiedReg::kX86Fld8)) {
+    3799           0 :         VirtReg* vreg = tied->vreg;
+    3800             :         X86Mem m(self->getVarMem(vreg));
+    3801             : 
+    3802             :         uint32_t elementId = TypeId::elementOf(vreg->getTypeId());
+    3803           0 :         m.setSize(elementId == TypeId::kF32 ? 4 :
+    3804             :                   elementId == TypeId::kF64 ? 8 :
+    3805           0 :                   (tied->flags & TiedReg::kX86Fld4) ? 4 : 8);
+    3806             : 
+    3807             :         cc->fld(m);
+    3808             :       }
+    3809             :     }
+    3810             :   }
+    3811             : 
+    3812             :   // Decide whether to `jmp` or not in case we are next to the return label.
+    3813        1948 :   while (node) {
+    3814        1948 :     switch (node->getType()) {
+    3815             :       // If we have found an exit label we just return, there is no need to
+    3816             :       // emit jump to that.
+    3817        1948 :       case CBNode::kNodeLabel:
+    3818        1948 :         if (static_cast<CBLabel*>(node) == exitTarget)
+    3819             :           return kErrorOk;
+    3820           0 :         goto _EmitRet;
+    3821             : 
+    3822           0 :       case CBNode::kNodeData:
+    3823             :       case CBNode::kNodeInst:
+    3824             :       case CBNode::kNodeFuncCall:
+    3825             :       case CBNode::kNodeFuncExit:
+    3826           0 :         goto _EmitRet;
+    3827             : 
+    3828             :       // Continue iterating.
+    3829             :       case CBNode::kNodeComment:
+    3830             :       case CBNode::kNodeAlign:
+    3831             :       case CBNode::kNodeHint:
+    3832             :         break;
+    3833             : 
+    3834             :       // Invalid node to be here.
+    3835             :       case CBNode::kNodeFunc:
+    3836             :         return DebugUtils::errored(kErrorInvalidState);
+    3837             : 
+    3838             :       // We can't go forward from here.
+    3839           0 :       case CBNode::kNodeSentinel:
+    3840           0 :         return kErrorOk;
+    3841             :     }
+    3842             : 
+    3843             :     node = node->getNext();
+    3844             :   }
+    3845             : 
+    3846           0 : _EmitRet:
+    3847             :   {
+    3848             :     cc->_setCursor(rNode);
+    3849           0 :     cc->jmp(exitTarget->getLabel());
+    3850             :   }
+    3851           0 :   return kErrorOk;
+    3852             : }
+    3853             : 
+    3854             : // ============================================================================
+    3855             : // [asmjit::X86RAPass - Translate - Func]
+    3856             : // ============================================================================
+    3857             : 
+    3858        1948 : Error X86RAPass::translate() {
+    3859             :   X86Compiler* cc = this->cc();
+    3860             :   CCFunc* func = getFunc();
+    3861             : 
+    3862             :   // Register allocator contexts.
+    3863             :   X86VarAlloc vAlloc(this);
+    3864             :   X86CallAlloc cAlloc(this);
+    3865             : 
+    3866             :   // Flow.
+    3867             :   CBNode* node_ = func;
+    3868             :   CBNode* next = nullptr;
+    3869             :   CBNode* stop = getStop();
+    3870             : 
+    3871             :   ZoneList<CBNode*>::Link* jLink = _jccList.getFirst();
+    3872             : 
+    3873             :   for (;;) {
+    3874       36702 :     while (node_->isTranslated()) {
+    3875             :       // Switch state if we went to a node that is already translated.
+    3876           0 :       if (node_->getType() == CBNode::kNodeLabel) {
+    3877             :         CBLabel* node = static_cast<CBLabel*>(node_);
+    3878             :         cc->_setCursor(node->getPrev());
+    3879           0 :         switchState(node->getPassData<RAData>()->state);
+    3880             :       }
+    3881             : 
+    3882           0 : _NextGroup:
+    3883        1948 :       if (!jLink) {
+    3884        1948 :         goto _Done;
+    3885             :       }
+    3886             :       else {
+    3887             :         node_ = jLink->getValue();
+    3888             :         jLink = jLink->getNext();
+    3889             : 
+    3890             :         CBNode* jFlow = X86RAPass_getOppositeJccFlow(static_cast<CBJump*>(node_));
+    3891           0 :         loadState(node_->getPassData<RAData>()->state);
+    3892             : 
+    3893           0 :         if (jFlow->hasPassData() && jFlow->getPassData<RAData>()->state) {
+    3894           0 :           X86RAPass_translateJump(this, static_cast<CBJump*>(node_), static_cast<CBLabel*>(jFlow));
+    3895             : 
+    3896             :           node_ = jFlow;
+    3897           0 :           if (node_->isTranslated())
+    3898           0 :             goto _NextGroup;
+    3899             :         }
+    3900             :         else {
+    3901             :           node_ = jFlow;
+    3902             :         }
+    3903             : 
+    3904             :         break;
+    3905             :       }
+    3906             :     }
+    3907             : 
+    3908             :     next = node_->getNext();
+    3909       36702 :     node_->_flags |= CBNode::kFlagIsTranslated;
+    3910             : 
+    3911       36702 :     if (node_->hasPassData()) {
+    3912       36702 :       switch (node_->getType()) {
+    3913             :         // --------------------------------------------------------------------
+    3914             :         // [Align / Embed]
+    3915             :         // --------------------------------------------------------------------
+    3916             : 
+    3917             :         case CBNode::kNodeAlign:
+    3918             :         case CBNode::kNodeData:
+    3919             :           break;
+    3920             : 
+    3921             :         // --------------------------------------------------------------------
+    3922             :         // [Label]
+    3923             :         // --------------------------------------------------------------------
+    3924             : 
+    3925           0 :         case CBNode::kNodeLabel: {
+    3926             :           CBLabel* node = static_cast<CBLabel*>(node_);
+    3927             :           ASMJIT_ASSERT(node->getPassData<RAData>()->state == nullptr);
+    3928           0 :           node->getPassData<RAData>()->state = saveState();
+    3929             : 
+    3930           0 :           if (node == func->getExitNode())
+    3931           0 :             goto _NextGroup;
+    3932             :           break;
+    3933             :         }
+    3934             : 
+    3935             :         // --------------------------------------------------------------------
+    3936             :         // [Inst/Call/SArg/Ret]
+    3937             :         // --------------------------------------------------------------------
+    3938             : 
+    3939             :         case CBNode::kNodeInst:
+    3940             :         case CBNode::kNodeFunc:
+    3941             :         case CBNode::kNodeFuncCall:
+    3942             :         case CBNode::kNodePushArg:
+    3943             :           // Update TiedReg's unuse flags based on liveness of the next node.
+    3944       34754 :           if (!node_->isJcc()) {
+    3945             :             X86RAData* raData = node_->getPassData<X86RAData>();
+    3946             :             RABits* liveness;
+    3947             : 
+    3948       34754 :             if (raData && next && next->hasPassData() && (liveness = next->getPassData<RAData>()->liveness)) {
+    3949       34754 :               TiedReg* tiedArray = raData->tiedArray;
+    3950       34754 :               uint32_t tiedTotal = raData->tiedTotal;
+    3951             : 
+    3952       94300 :               for (uint32_t i = 0; i < tiedTotal; i++) {
+    3953       59546 :                 TiedReg* tied = &tiedArray[i];
+    3954       59546 :                 VirtReg* vreg = tied->vreg;
+    3955             : 
+    3956       59546 :                 if (!liveness->getBit(vreg->_raId) && !vreg->isFixed())
+    3957       21840 :                   tied->flags |= TiedReg::kUnuse;
+    3958             :               }
+    3959             :             }
+    3960             :           }
+    3961             : 
+    3962       34754 :           if (node_->getType() == CBNode::kNodeFuncCall) {
+    3963        1648 :             ASMJIT_PROPAGATE(cAlloc.run(static_cast<CCFuncCall*>(node_)));
+    3964             :             break;
+    3965             :           }
+    3966             :           ASMJIT_FALLTHROUGH;
+    3967             : 
+    3968             :         case CBNode::kNodeHint:
+    3969             :         case CBNode::kNodeFuncExit: {
+    3970       35054 :           ASMJIT_PROPAGATE(vAlloc.run(node_));
+    3971             : 
+    3972             :           // Handle conditional/unconditional jump.
+    3973       35054 :           if (node_->isJmpOrJcc()) {
+    3974             :             CBJump* node = static_cast<CBJump*>(node_);
+    3975             :             CBLabel* jTarget = node->getTarget();
+    3976             : 
+    3977             :             // Target not followed.
+    3978           0 :             if (!jTarget) {
+    3979           0 :               if (node->isJmp())
+    3980           0 :                 goto _NextGroup;
+    3981             :               else
+    3982             :                 break;
+    3983             :             }
+    3984             : 
+    3985           0 :             if (node->isJmp()) {
+    3986           0 :               if (jTarget->hasPassData() && jTarget->getPassData<RAData>()->state) {
+    3987             :                 cc->_setCursor(node->getPrev());
+    3988           0 :                 switchState(jTarget->getPassData<RAData>()->state);
+    3989             : 
+    3990           0 :                 goto _NextGroup;
+    3991             :               }
+    3992             :               else {
+    3993             :                 next = jTarget;
+    3994             :               }
+    3995             :             }
+    3996             :             else {
+    3997             :               CBNode* jNext = node->getNext();
+    3998             : 
+    3999           0 :               if (jTarget->isTranslated()) {
+    4000           0 :                 if (jNext->isTranslated()) {
+    4001             :                   ASMJIT_ASSERT(jNext->getType() == CBNode::kNodeLabel);
+    4002             :                   cc->_setCursor(node->getPrev());
+    4003           0 :                   intersectStates(
+    4004             :                     jTarget->getPassData<RAData>()->state,
+    4005             :                     jNext->getPassData<RAData>()->state);
+    4006             :                 }
+    4007             : 
+    4008           0 :                 RAState* savedState = saveState();
+    4009           0 :                 node->getPassData<RAData>()->state = savedState;
+    4010             : 
+    4011           0 :                 X86RAPass_translateJump(this, node, jTarget);
+    4012             :                 next = jNext;
+    4013             :               }
+    4014           0 :               else if (jNext->isTranslated()) {
+    4015             :                 ASMJIT_ASSERT(jNext->getType() == CBNode::kNodeLabel);
+    4016             : 
+    4017           0 :                 RAState* savedState = saveState();
+    4018           0 :                 node->getPassData<RAData>()->state = savedState;
+    4019             : 
+    4020             :                 cc->_setCursor(node);
+    4021           0 :                 switchState(jNext->getPassData<RAData>()->state);
+    4022             :                 next = jTarget;
+    4023             :               }
+    4024             :               else {
+    4025           0 :                 node->getPassData<RAData>()->state = saveState();
+    4026             :                 next = X86RAPass_getJccFlow(node);
+    4027             :               }
+    4028             :             }
+    4029             :           }
+    4030       35054 :           else if (node_->isRet()) {
+    4031        1948 :             ASMJIT_PROPAGATE(
+    4032             :               X86RAPass_translateRet(this, static_cast<CCFuncRet*>(node_), func->getExitNode()));
+    4033        1948 :             goto _NextGroup;
+    4034             :           }
+    4035             :           break;
+    4036             :         }
+    4037             : 
+    4038             :         // --------------------------------------------------------------------
+    4039             :         // [End]
+    4040             :         // --------------------------------------------------------------------
+    4041             : 
+    4042           0 :         case CBNode::kNodeSentinel: {
+    4043           0 :           goto _NextGroup;
+    4044             :         }
+    4045             : 
+    4046             :         default:
+    4047             :           break;
+    4048             :       }
+    4049             :     }
+    4050             : 
+    4051       34754 :     if (next == stop)
+    4052           0 :       goto _NextGroup;
+    4053             :     node_ = next;
+    4054             :   }
+    4055             : 
+    4056             : _Done:
+    4057             :   {
+    4058        1948 :     ASMJIT_PROPAGATE(resolveCellOffsets());
+    4059        1948 :     ASMJIT_PROPAGATE(X86RAPass_prepareFuncFrame(this, func));
+    4060             : 
+    4061             :     FuncFrameLayout layout;
+    4062        1948 :     ASMJIT_PROPAGATE(layout.init(func->getDetail(), func->getFrameInfo()));
+    4063             : 
+    4064        1948 :     _varBaseRegId = layout._stackBaseRegId;
+    4065        1948 :     _varBaseOffset = layout._stackBaseOffset;
+    4066             : 
+    4067        1948 :     ASMJIT_PROPAGATE(X86RAPass_patchFuncMem(this, func, stop, layout));
+    4068             : 
+    4069             :     cc->_setCursor(func);
+    4070        1948 :     ASMJIT_PROPAGATE(FuncUtils::emitProlog(this->cc(), layout));
+    4071             : 
+    4072             :     cc->_setCursor(func->getExitNode());
+    4073        1948 :     ASMJIT_PROPAGATE(FuncUtils::emitEpilog(this->cc(), layout));
+    4074             :   }
+    4075             : 
+    4076        1948 :   return kErrorOk;
+    4077             : }
+    4078             : 
+    4079             : } // asmjit namespace
+    4080             : } // namespace PLMD
+    4081             : 
+    4082             : // [Api-End]
+    4083             : #include "./asmjit_apiend.h"
+    4084             : 
+    4085             : // [Guard]
+    4086             : #endif // ASMJIT_BUILD_X86 && !ASMJIT_DISABLE_COMPILER
+    4087             : #pragma GCC diagnostic pop
+    4088             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc_p.h.func-sort-c.html b/coverage-libs/asmjit/x86regalloc_p.h.func-sort-c.html new file mode 100644 index 000000000000..009cbc59211a --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc_p.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc_p.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:344969.4 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc_p.h.func.html b/coverage-libs/asmjit/x86regalloc_p.h.func.html new file mode 100644 index 000000000000..e43e078279fa --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc_p.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc_p.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:344969.4 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/x86regalloc_p.h.gcov.html b/coverage-libs/asmjit/x86regalloc_p.h.gcov.html new file mode 100644 index 000000000000..d00ee385a6b8 --- /dev/null +++ b/coverage-libs/asmjit/x86regalloc_p.h.gcov.html @@ -0,0 +1,811 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/x86regalloc_p.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - x86regalloc_p.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:344969.4 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_x86regalloc_p_h
+      21             : #define __PLUMED_asmjit_x86regalloc_p_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_X86_X86REGALLOC_P_H
+      33             : #define _ASMJIT_X86_X86REGALLOC_P_H
+      34             : 
+      35             : #include "./asmjit_build.h"
+      36             : #if !defined(ASMJIT_DISABLE_COMPILER)
+      37             : 
+      38             : // [Dependencies]
+      39             : #include "./codecompiler.h"
+      40             : #include "./regalloc_p.h"
+      41             : #include "./utils.h"
+      42             : #include "./x86assembler.h"
+      43             : #include "./x86compiler.h"
+      44             : #include "./x86misc.h"
+      45             : 
+      46             : // [Api-Begin]
+      47             : #include "./asmjit_apibegin.h"
+      48             : 
+      49             : namespace PLMD {
+      50             : namespace asmjit {
+      51             : 
+      52             : //! \addtogroup asmjit_x86
+      53             : //! \{
+      54             : 
+      55             : // ============================================================================
+      56             : // [asmjit::X86RAData]
+      57             : // ============================================================================
+      58             : 
+      59             : struct X86RAData : public RAData {
+      60       81196 :   ASMJIT_INLINE X86RAData(uint32_t tiedTotal) noexcept : RAData(tiedTotal) {
+      61             :     inRegs.reset();
+      62             :     outRegs.reset();
+      63             :     clobberedRegs.reset();
+      64             :     tiedIndex.reset();
+      65             :     tiedCount.reset();
+      66             :   }
+      67             : 
+      68             :   // --------------------------------------------------------------------------
+      69             :   // [Accessors]
+      70             :   // --------------------------------------------------------------------------
+      71             : 
+      72             :   //! Get TiedReg array.
+      73             :   ASMJIT_INLINE TiedReg* getTiedArray() const noexcept {
+      74       36702 :     return const_cast<TiedReg*>(tiedArray);
+      75             :   }
+      76             : 
+      77             :   //! Get TiedReg array for a given register `kind`.
+      78             :   ASMJIT_INLINE TiedReg* getTiedArrayByKind(uint32_t kind) const noexcept {
+      79       99342 :     return const_cast<TiedReg*>(tiedArray) + tiedIndex.get(kind);
+      80             :   }
+      81             : 
+      82             :   //! Get TiedReg index for a given register `kind`.
+      83             :   ASMJIT_INLINE uint32_t getTiedStart(uint32_t kind) const noexcept {
+      84             :     return tiedIndex.get(kind);
+      85             :   }
+      86             : 
+      87             :   //! Get TiedReg count for a given register `kind`.
+      88             :   ASMJIT_INLINE uint32_t getTiedCountByKind(uint32_t kind) const noexcept {
+      89             :     return tiedCount.get(kind);
+      90             :   }
+      91             : 
+      92             :   //! Get TiedReg at the specified `index`.
+      93             :   ASMJIT_INLINE TiedReg* getTiedAt(uint32_t index) const noexcept {
+      94             :     ASMJIT_ASSERT(index < tiedTotal);
+      95             :     return getTiedArray() + index;
+      96             :   }
+      97             : 
+      98             :   //! Get TiedReg at the specified index for a given register `kind`.
+      99             :   ASMJIT_INLINE TiedReg* getTiedAtByKind(uint32_t kind, uint32_t index) const noexcept {
+     100             :     ASMJIT_ASSERT(index < tiedCount._regs[kind]);
+     101             :     return getTiedArrayByKind(kind) + index;
+     102             :   }
+     103             : 
+     104             :   ASMJIT_INLINE void setTiedAt(uint32_t index, TiedReg& tied) noexcept {
+     105             :     ASMJIT_ASSERT(index < tiedTotal);
+     106       61494 :     tiedArray[index] = tied;
+     107             :   }
+     108             : 
+     109             :   // --------------------------------------------------------------------------
+     110             :   // [Utils]
+     111             :   // --------------------------------------------------------------------------
+     112             : 
+     113             :   //! Find TiedReg.
+     114             :   ASMJIT_INLINE TiedReg* findTied(VirtReg* vreg) const noexcept {
+     115             :     TiedReg* tiedArray = getTiedArray();
+     116             :     uint32_t tiedCount = tiedTotal;
+     117             : 
+     118             :     for (uint32_t i = 0; i < tiedCount; i++)
+     119             :       if (tiedArray[i].vreg == vreg)
+     120             :         return &tiedArray[i];
+     121             : 
+     122             :     return nullptr;
+     123             :   }
+     124             : 
+     125             :   //! Find TiedReg (by class).
+     126             :   ASMJIT_INLINE TiedReg* findTiedByKind(uint32_t kind, VirtReg* vreg) const noexcept {
+     127             :     TiedReg* tiedArray = getTiedArrayByKind(kind);
+     128             :     uint32_t tiedCount = getTiedCountByKind(kind);
+     129             : 
+     130      209940 :     for (uint32_t i = 0; i < tiedCount; i++)
+     131      140526 :       if (tiedArray[i].vreg == vreg)
+     132             :         return &tiedArray[i];
+     133             : 
+     134             :     return nullptr;
+     135             :   }
+     136             : 
+     137             :   // --------------------------------------------------------------------------
+     138             :   // [Members]
+     139             :   // --------------------------------------------------------------------------
+     140             : 
+     141             :   //! Special registers on input.
+     142             :   //!
+     143             :   //! Special register(s) restricted to one or more physical register. If there
+     144             :   //! is more than one special register it means that we have to duplicate the
+     145             :   //! variable content to all of them (it means that the same variable was used
+     146             :   //! by two or more operands). We forget about duplicates after the register
+     147             :   //! allocation finishes and marks all duplicates as non-assigned.
+     148             :   X86RegMask inRegs;
+     149             : 
+     150             :   //! Special registers on output.
+     151             :   //!
+     152             :   //! Special register(s) used on output. Each variable can have only one
+     153             :   //! special register on the output, 'X86RAData' contains all registers from
+     154             :   //! all 'TiedReg's.
+     155             :   X86RegMask outRegs;
+     156             : 
+     157             :   //! Clobbered registers (by a function call).
+     158             :   X86RegMask clobberedRegs;
+     159             : 
+     160             :   //! Start indexes of `TiedReg`s per register kind.
+     161             :   X86RegCount tiedIndex;
+     162             :   //! Count of variables per register kind.
+     163             :   X86RegCount tiedCount;
+     164             : 
+     165             :   //! Linked registers.
+     166             :   TiedReg tiedArray[1];
+     167             : };
+     168             : 
+     169             : // ============================================================================
+     170             : // [asmjit::X86StateCell]
+     171             : // ============================================================================
+     172             : 
+     173             : //! X86/X64 state-cell.
+     174             : union X86StateCell {
+     175             :   // --------------------------------------------------------------------------
+     176             :   // [Accessors]
+     177             :   // --------------------------------------------------------------------------
+     178             : 
+     179           0 :   ASMJIT_INLINE uint32_t getState() const noexcept { return _state; }
+     180           0 :   ASMJIT_INLINE void setState(uint32_t state) noexcept { _state = static_cast<uint8_t>(state); }
+     181             : 
+     182             :   // --------------------------------------------------------------------------
+     183             :   // [Reset]
+     184             :   // --------------------------------------------------------------------------
+     185             : 
+     186           0 :   ASMJIT_INLINE void reset() noexcept { _packed = 0; }
+     187             : 
+     188             :   // --------------------------------------------------------------------------
+     189             :   // [Members]
+     190             :   // --------------------------------------------------------------------------
+     191             : 
+     192             :   uint8_t _packed;
+     193             : 
+     194             :   struct {
+     195             :     uint8_t _state : 2;
+     196             :     uint8_t _unused : 6;
+     197             :   };
+     198             : };
+     199             : 
+     200             : // ============================================================================
+     201             : // [asmjit::X86RAState]
+     202             : // ============================================================================
+     203             : 
+     204             : //! X86/X64 state.
+     205             : struct X86RAState : RAState {
+     206             :   enum {
+     207             :     //! Base index of GP registers.
+     208             :     kGpIndex = 0,
+     209             :     //! Count of GP registers.
+     210             :     kGpCount = 16,
+     211             : 
+     212             :     //! Base index of MMX registers.
+     213             :     kMmIndex = kGpIndex + kGpCount,
+     214             :     //! Count of Mm registers.
+     215             :     kMmCount = 8,
+     216             : 
+     217             :     //! Base index of XMM registers.
+     218             :     kXmmIndex = kMmIndex + kMmCount,
+     219             :     //! Count of XMM registers.
+     220             :     kXmmCount = 16,
+     221             : 
+     222             :     //! Count of all registers in `X86RAState`.
+     223             :     kAllCount = kXmmIndex + kXmmCount
+     224             :   };
+     225             : 
+     226             :   // --------------------------------------------------------------------------
+     227             :   // [Accessors]
+     228             :   // --------------------------------------------------------------------------
+     229             : 
+     230             :   ASMJIT_INLINE VirtReg** getList() {
+     231             :     return _list;
+     232             :   }
+     233             : 
+     234             :   ASMJIT_INLINE VirtReg** getListByKind(uint32_t kind) {
+     235             :     switch (kind) {
+     236        3296 :       case X86Reg::kKindGp : return _listGp;
+     237        3296 :       case X86Reg::kKindMm : return _listMm;
+     238        8920 :       case X86Reg::kKindVec: return _listXmm;
+     239             : 
+     240             :       default:
+     241             :         return nullptr;
+     242             :     }
+     243             :   }
+     244             : 
+     245             :   // --------------------------------------------------------------------------
+     246             :   // [Clear]
+     247             :   // --------------------------------------------------------------------------
+     248             : 
+     249             :   ASMJIT_INLINE void reset(size_t numCells) {
+     250             :     ::memset(this, 0, kAllCount * sizeof(VirtReg*) +
+     251             :                       2         * sizeof(X86RegMask) +
+     252             :                       numCells  * sizeof(X86StateCell));
+     253             :   }
+     254             : 
+     255             :   // --------------------------------------------------------------------------
+     256             :   // [Members]
+     257             :   // --------------------------------------------------------------------------
+     258             : 
+     259             :   union {
+     260             :     //! List of all allocated variables in one array.
+     261             :     VirtReg* _list[kAllCount];
+     262             : 
+     263             :     struct {
+     264             :       //! Allocated GP registers.
+     265             :       VirtReg* _listGp[kGpCount];
+     266             :       //! Allocated MMX registers.
+     267             :       VirtReg* _listMm[kMmCount];
+     268             :       //! Allocated XMM registers.
+     269             :       VirtReg* _listXmm[kXmmCount];
+     270             :     };
+     271             :   };
+     272             : 
+     273             :   //! Occupied registers (mask).
+     274             :   X86RegMask _occupied;
+     275             :   //! Modified registers (mask).
+     276             :   X86RegMask _modified;
+     277             : 
+     278             :   //! Variables data, the length is stored in `X86RAPass`.
+     279             :   X86StateCell _cells[1];
+     280             : };
+     281             : 
+     282             : // ============================================================================
+     283             : // [asmjit::X86RAPass]
+     284             : // ============================================================================
+     285             : 
+     286             : #if defined(ASMJIT_DEBUG)
+     287             : # define ASMJIT_X86_CHECK_STATE _checkState();
+     288             : #else
+     289             : # define ASMJIT_X86_CHECK_STATE
+     290             : #endif // ASMJIT_DEBUG
+     291             : 
+     292             : //! \internal
+     293             : //!
+     294             : //! X86 register allocator pipeline.
+     295             : //!
+     296             : //! Takes care of generating function prologs and epilogs, and also performs
+     297             : //! register allocation.
+     298             : class X86RAPass : public RAPass {
+     299             : public:
+     300             :   ASMJIT_NONCOPYABLE(X86RAPass)
+     301             :   typedef RAPass Base;
+     302             : 
+     303             :   enum RegOp {
+     304             :     kRegOpMove,
+     305             :     kRegOpLoad,
+     306             :     kRegOpSave
+     307             :   };
+     308             : 
+     309             :   // --------------------------------------------------------------------------
+     310             :   // [Construction / Destruction]
+     311             :   // --------------------------------------------------------------------------
+     312             : 
+     313             :   X86RAPass() noexcept;
+     314             :   virtual ~X86RAPass() noexcept;
+     315             : 
+     316             :   // --------------------------------------------------------------------------
+     317             :   // [Interface]
+     318             :   // --------------------------------------------------------------------------
+     319             : 
+     320             :   virtual Error process(Zone* zone) noexcept override;
+     321             :   virtual Error prepare(CCFunc* func) noexcept override;
+     322             : 
+     323             :   // --------------------------------------------------------------------------
+     324             :   // [ArchInfo]
+     325             :   // --------------------------------------------------------------------------
+     326             : 
+     327             :   ASMJIT_INLINE uint32_t getGpSize() const noexcept { return _zsp.getSize(); }
+     328             : 
+     329             :   // --------------------------------------------------------------------------
+     330             :   // [Accessors]
+     331             :   // --------------------------------------------------------------------------
+     332             : 
+     333             :   //! Get compiler as `X86Compiler`.
+     334      119636 :   ASMJIT_INLINE X86Compiler* cc() const noexcept { return static_cast<X86Compiler*>(_cb); }
+     335             :   //! Get clobbered registers (global).
+     336             :   ASMJIT_INLINE uint32_t getClobberedRegs(uint32_t kind) noexcept { return _clobberedRegs.get(kind); }
+     337             : 
+     338             :   // --------------------------------------------------------------------------
+     339             :   // [Helpers]
+     340             :   // --------------------------------------------------------------------------
+     341             : 
+     342             :   ASMJIT_INLINE X86RAData* newRAData(uint32_t tiedTotal) noexcept {
+     343       40598 :     return new(_zone->alloc(sizeof(X86RAData) + tiedTotal * sizeof(TiedReg))) X86RAData(tiedTotal);
+     344             :   }
+     345             : 
+     346             :   // --------------------------------------------------------------------------
+     347             :   // [Emit]
+     348             :   // --------------------------------------------------------------------------
+     349             : 
+     350             :   // Tiny wrappers that call `X86Internal::emit...()`.
+     351             :   Error emitMove(VirtReg* vreg, uint32_t dstId, uint32_t srcId, const char* reason);
+     352             :   Error emitLoad(VirtReg* vreg, uint32_t id, const char* reason);
+     353             :   Error emitSave(VirtReg* vreg, uint32_t id, const char* reason);
+     354             :   Error emitSwapGp(VirtReg* aVReg, VirtReg* bVReg, uint32_t aId, uint32_t bId, const char* reason) noexcept;
+     355             : 
+     356             :   Error emitImmToReg(uint32_t dstTypeId, uint32_t dstPhysId, const Imm* src) noexcept;
+     357             :   Error emitImmToStack(uint32_t dstTypeId, const X86Mem* dst, const Imm* src) noexcept;
+     358             :   Error emitRegToStack(uint32_t dstTypeId, const X86Mem* dst, uint32_t srcTypeId, uint32_t srcPhysId) noexcept;
+     359             : 
+     360             :   // --------------------------------------------------------------------------
+     361             :   // [Register Management]
+     362             :   // --------------------------------------------------------------------------
+     363             : 
+     364             :   void _checkState();
+     365             : 
+     366             :   // --------------------------------------------------------------------------
+     367             :   // [Attach / Detach]
+     368             :   // --------------------------------------------------------------------------
+     369             : 
+     370             :   //! Attach.
+     371             :   //!
+     372             :   //! Attach a register to the 'VirtReg', changing 'VirtReg' members to show
+     373             :   //! that the variable is currently alive and linking variable with the
+     374             :   //! current 'X86RAState'.
+     375             :   template<int C>
+     376             :   ASMJIT_INLINE void attach(VirtReg* vreg, uint32_t physId, bool modified) {
+     377             :     ASMJIT_ASSERT(vreg->getKind() == C);
+     378             :     ASMJIT_ASSERT(physId != Globals::kInvalidRegId);
+     379             : 
+     380             :     // Prevent Esp allocation if C==Gp.
+     381             :     ASMJIT_ASSERT(C != X86Reg::kKindGp || physId != X86Gp::kIdSp);
+     382             : 
+     383             :     uint32_t regMask = Utils::mask(physId);
+     384             : 
+     385             :     vreg->setState(VirtReg::kStateReg);
+     386             :     vreg->setModified(modified);
+     387             :     vreg->setPhysId(physId);
+     388             :     vreg->addHomeId(physId);
+     389             : 
+     390       23788 :     _x86State.getListByKind(C)[physId] = vreg;
+     391             :     _x86State._occupied.or_(C, regMask);
+     392             :     _x86State._modified.or_(C, static_cast<uint32_t>(modified) << physId);
+     393             : 
+     394             :     ASMJIT_X86_CHECK_STATE
+     395       23788 :   }
+     396             : 
+     397             :   //! Detach.
+     398             :   //!
+     399             :   //! The opposite of 'Attach'. Detach resets the members in 'VirtReg'
+     400             :   //! (physId, state and changed flags) and unlinks the variable with the
+     401             :   //! current 'X86RAState'.
+     402             :   template<int C>
+     403             :   ASMJIT_INLINE void detach(VirtReg* vreg, uint32_t physId, uint32_t vState) {
+     404             :     ASMJIT_ASSERT(vreg->getKind() == C);
+     405             :     ASMJIT_ASSERT(vreg->getPhysId() == physId);
+     406             :     ASMJIT_ASSERT(vState != VirtReg::kStateReg);
+     407             : 
+     408             :     uint32_t regMask = Utils::mask(physId);
+     409             : 
+     410             :     vreg->setState(vState);
+     411             :     vreg->resetPhysId();
+     412             :     vreg->setModified(false);
+     413             : 
+     414       26264 :     _x86State.getListByKind(C)[physId] = nullptr;
+     415             :     _x86State._occupied.andNot(C, regMask);
+     416             :     _x86State._modified.andNot(C, regMask);
+     417             : 
+     418             :     ASMJIT_X86_CHECK_STATE
+     419       26264 :   }
+     420             : 
+     421             :   // --------------------------------------------------------------------------
+     422             :   // [Rebase]
+     423             :   // --------------------------------------------------------------------------
+     424             : 
+     425             :   //! Rebase.
+     426             :   //!
+     427             :   //! Change the register of the 'VirtReg' changing also the current 'X86RAState'.
+     428             :   //! Rebase is nearly identical to 'Detach' and 'Attach' sequence, but doesn't
+     429             :   //! change the `VirtReg`s modified flag.
+     430             :   template<int C>
+     431             :   ASMJIT_INLINE void rebase(VirtReg* vreg, uint32_t newPhysId, uint32_t oldPhysId) {
+     432             :     ASMJIT_ASSERT(vreg->getKind() == C);
+     433             : 
+     434             :     uint32_t newRegMask = Utils::mask(newPhysId);
+     435             :     uint32_t oldRegMask = Utils::mask(oldPhysId);
+     436         656 :     uint32_t bothRegMask = newRegMask ^ oldRegMask;
+     437             : 
+     438             :     vreg->setPhysId(newPhysId);
+     439             : 
+     440         656 :     _x86State.getListByKind(C)[oldPhysId] = nullptr;
+     441         656 :     _x86State.getListByKind(C)[newPhysId] = vreg;
+     442             : 
+     443             :     _x86State._occupied.xor_(C, bothRegMask);
+     444         656 :     _x86State._modified.xor_(C, bothRegMask & -static_cast<int32_t>(vreg->isModified()));
+     445             : 
+     446             :     ASMJIT_X86_CHECK_STATE
+     447         656 :   }
+     448             : 
+     449             :   // --------------------------------------------------------------------------
+     450             :   // [Load / Save]
+     451             :   // --------------------------------------------------------------------------
+     452             : 
+     453             :   //! Load.
+     454             :   //!
+     455             :   //! Load variable from its memory slot to a register, emitting 'Load'
+     456             :   //! instruction and changing the variable state to allocated.
+     457             :   template<int C>
+     458             :   ASMJIT_INLINE void load(VirtReg* vreg, uint32_t physId) {
+     459             :     // Can be only called if variable is not allocated.
+     460             :     ASMJIT_ASSERT(vreg->getKind() == C);
+     461             :     ASMJIT_ASSERT(vreg->getState() != VirtReg::kStateReg);
+     462             :     ASMJIT_ASSERT(vreg->getPhysId() == Globals::kInvalidRegId);
+     463             : 
+     464           0 :     emitLoad(vreg, physId, "Load");
+     465             :     attach<C>(vreg, physId, false);
+     466             : 
+     467             :     ASMJIT_X86_CHECK_STATE
+     468           0 :   }
+     469             : 
+     470             :   //! Save.
+     471             :   //!
+     472             :   //! Save the variable into its home location, but keep it as allocated.
+     473             :   template<int C>
+     474             :   ASMJIT_INLINE void save(VirtReg* vreg) {
+     475             :     ASMJIT_ASSERT(vreg->getKind() == C);
+     476             :     ASMJIT_ASSERT(vreg->getState() == VirtReg::kStateReg);
+     477             :     ASMJIT_ASSERT(vreg->getPhysId() != Globals::kInvalidRegId);
+     478             : 
+     479             :     uint32_t physId = vreg->getPhysId();
+     480             :     uint32_t regMask = Utils::mask(physId);
+     481             : 
+     482        3468 :     emitSave(vreg, physId, "Save");
+     483             :     vreg->setModified(false);
+     484             :     _x86State._modified.andNot(C, regMask);
+     485             : 
+     486             :     ASMJIT_X86_CHECK_STATE
+     487        3468 :   }
+     488             : 
+     489             :   // --------------------------------------------------------------------------
+     490             :   // [Move / Swap]
+     491             :   // --------------------------------------------------------------------------
+     492             : 
+     493             :   //! Move a register.
+     494             :   //!
+     495             :   //! Move register from one index to another, emitting 'Move' if needed. This
+     496             :   //! function does nothing if register is already at the given index.
+     497             :   template<int C>
+     498             :   ASMJIT_INLINE void move(VirtReg* vreg, uint32_t newPhysId) {
+     499             :     ASMJIT_ASSERT(vreg->getKind() == C);
+     500             :     ASMJIT_ASSERT(vreg->getState() == VirtReg::kStateReg);
+     501             :     ASMJIT_ASSERT(vreg->getPhysId() != Globals::kInvalidRegId);
+     502             : 
+     503             :     uint32_t oldPhysId = vreg->getPhysId();
+     504         656 :     if (newPhysId != oldPhysId) {
+     505         656 :       emitMove(vreg, newPhysId, oldPhysId, "Move");
+     506             :       rebase<C>(vreg, newPhysId, oldPhysId);
+     507             :     }
+     508             : 
+     509             :     ASMJIT_X86_CHECK_STATE
+     510             :   }
+     511             : 
+     512             :   //! Swap two registers
+     513             :   //!
+     514             :   //! It's only possible to swap Gp registers.
+     515             :   ASMJIT_INLINE void swapGp(VirtReg* aVReg, VirtReg* bVReg) {
+     516             :     ASMJIT_ASSERT(aVReg != bVReg);
+     517             : 
+     518             :     ASMJIT_ASSERT(aVReg->getKind() == X86Reg::kKindGp);
+     519             :     ASMJIT_ASSERT(aVReg->getState() == VirtReg::kStateReg);
+     520             :     ASMJIT_ASSERT(aVReg->getPhysId() != Globals::kInvalidRegId);
+     521             : 
+     522             :     ASMJIT_ASSERT(bVReg->getKind() == X86Reg::kKindGp);
+     523             :     ASMJIT_ASSERT(bVReg->getState() == VirtReg::kStateReg);
+     524             :     ASMJIT_ASSERT(bVReg->getPhysId() != Globals::kInvalidRegId);
+     525             : 
+     526             :     uint32_t aIndex = aVReg->getPhysId();
+     527             :     uint32_t bIndex = bVReg->getPhysId();
+     528             : 
+     529           0 :     emitSwapGp(aVReg, bVReg, aIndex, bIndex, "Swap");
+     530             : 
+     531             :     aVReg->setPhysId(bIndex);
+     532             :     bVReg->setPhysId(aIndex);
+     533             : 
+     534           0 :     _x86State.getListByKind(X86Reg::kKindGp)[aIndex] = bVReg;
+     535           0 :     _x86State.getListByKind(X86Reg::kKindGp)[bIndex] = aVReg;
+     536             : 
+     537           0 :     uint32_t m = aVReg->isModified() ^ bVReg->isModified();
+     538           0 :     _x86State._modified.xor_(X86Reg::kKindGp, (m << aIndex) | (m << bIndex));
+     539             : 
+     540             :     ASMJIT_X86_CHECK_STATE
+     541             :   }
+     542             : 
+     543             :   // --------------------------------------------------------------------------
+     544             :   // [Alloc / Spill]
+     545             :   // --------------------------------------------------------------------------
+     546             : 
+     547             :   //! Alloc.
+     548             :   template<int C>
+     549             :   ASMJIT_INLINE void alloc(VirtReg* vreg, uint32_t physId) {
+     550             :     ASMJIT_ASSERT(vreg->getKind() == C);
+     551             :     ASMJIT_ASSERT(physId != Globals::kInvalidRegId);
+     552             : 
+     553             :     uint32_t oldPhysId = vreg->getPhysId();
+     554             :     uint32_t oldState = vreg->getState();
+     555             :     uint32_t regMask = Utils::mask(physId);
+     556             : 
+     557             :     ASMJIT_ASSERT(_x86State.getListByKind(C)[physId] == nullptr || physId == oldPhysId);
+     558             : 
+     559        4424 :     if (oldState != VirtReg::kStateReg) {
+     560        4424 :       if (oldState == VirtReg::kStateMem)
+     561        4424 :         emitLoad(vreg, physId, "Alloc");
+     562             :       vreg->setModified(false);
+     563             :     }
+     564           0 :     else if (oldPhysId != physId) {
+     565           0 :       emitMove(vreg, physId, oldPhysId, "Alloc");
+     566             : 
+     567           0 :       _x86State.getListByKind(C)[oldPhysId] = nullptr;
+     568           0 :       regMask ^= Utils::mask(oldPhysId);
+     569             :     }
+     570             :     else {
+     571             :       ASMJIT_X86_CHECK_STATE
+     572             :       return;
+     573             :     }
+     574             : 
+     575             :     vreg->setState(VirtReg::kStateReg);
+     576             :     vreg->setPhysId(physId);
+     577             :     vreg->addHomeId(physId);
+     578             : 
+     579        4424 :     _x86State.getListByKind(C)[physId] = vreg;
+     580             :     _x86State._occupied.xor_(C, regMask);
+     581        4424 :     _x86State._modified.xor_(C, regMask & -static_cast<int32_t>(vreg->isModified()));
+     582             : 
+     583             :     ASMJIT_X86_CHECK_STATE
+     584             :   }
+     585             : 
+     586             :   //! Spill.
+     587             :   //!
+     588             :   //! Spill variable/register, saves the content to the memory-home if modified.
+     589             :   template<int C>
+     590             :   ASMJIT_INLINE void spill(VirtReg* vreg) {
+     591             :     ASMJIT_ASSERT(vreg->getKind() == C);
+     592             : 
+     593         548 :     if (vreg->getState() != VirtReg::kStateReg) {
+     594             :       ASMJIT_X86_CHECK_STATE
+     595             :       return;
+     596             :     }
+     597             : 
+     598             :     uint32_t physId = vreg->getPhysId();
+     599             :     ASMJIT_ASSERT(physId != Globals::kInvalidRegId);
+     600             :     ASMJIT_ASSERT(_x86State.getListByKind(C)[physId] == vreg);
+     601             : 
+     602         548 :     if (vreg->isModified())
+     603         536 :       emitSave(vreg, physId, "Spill");
+     604             :     detach<C>(vreg, physId, VirtReg::kStateMem);
+     605             : 
+     606             :     ASMJIT_X86_CHECK_STATE
+     607             :   }
+     608             : 
+     609             :   // --------------------------------------------------------------------------
+     610             :   // [Modify]
+     611             :   // --------------------------------------------------------------------------
+     612             : 
+     613             :   template<int C>
+     614             :   ASMJIT_INLINE void modify(VirtReg* vreg) {
+     615             :     ASMJIT_ASSERT(vreg->getKind() == C);
+     616             : 
+     617             :     uint32_t physId = vreg->getPhysId();
+     618             :     uint32_t regMask = Utils::mask(physId);
+     619             : 
+     620             :     vreg->setModified(true);
+     621             :     _x86State._modified.or_(C, regMask);
+     622             : 
+     623             :     ASMJIT_X86_CHECK_STATE
+     624             :   }
+     625             : 
+     626             :   // --------------------------------------------------------------------------
+     627             :   // [Unuse]
+     628             :   // --------------------------------------------------------------------------
+     629             : 
+     630             :   //! Unuse.
+     631             :   //!
+     632             :   //! Unuse variable, it will be detached it if it's allocated then its state
+     633             :   //! will be changed to VirtReg::kStateNone.
+     634             :   template<int C>
+     635             :   ASMJIT_INLINE void unuse(VirtReg* vreg, uint32_t vState = VirtReg::kStateNone) {
+     636             :     ASMJIT_ASSERT(vreg->getKind() == C);
+     637             :     ASMJIT_ASSERT(vState != VirtReg::kStateReg);
+     638             : 
+     639             :     uint32_t physId = vreg->getPhysId();
+     640       50462 :     if (physId != Globals::kInvalidRegId)
+     641             :       detach<C>(vreg, physId, vState);
+     642             :     else
+     643             :       vreg->setState(vState);
+     644             : 
+     645             :     ASMJIT_X86_CHECK_STATE
+     646             :   }
+     647             : 
+     648             :   // --------------------------------------------------------------------------
+     649             :   // [State]
+     650             :   // --------------------------------------------------------------------------
+     651             : 
+     652             :   //! Get state as `X86RAState`.
+     653           0 :   ASMJIT_INLINE X86RAState* getState() const { return const_cast<X86RAState*>(&_x86State); }
+     654             : 
+     655             :   virtual void loadState(RAState* src) override;
+     656             :   virtual RAState* saveState() override;
+     657             : 
+     658             :   virtual void switchState(RAState* src) override;
+     659             :   virtual void intersectStates(RAState* a, RAState* b) override;
+     660             : 
+     661             :   // --------------------------------------------------------------------------
+     662             :   // [Memory]
+     663             :   // --------------------------------------------------------------------------
+     664             : 
+     665             :   ASMJIT_INLINE X86Mem getVarMem(VirtReg* vreg) {
+     666        8428 :     (void)getVarCell(vreg);
+     667             :     return X86Mem(Init,
+     668             :       cc()->_nativeGpReg.getType(), vreg->getId(),
+     669             :       Reg::kRegNone, kInvalidValue,
+     670             :       0, 0, Mem::kSignatureMemRegHomeFlag);
+     671             :   }
+     672             : 
+     673             :   // --------------------------------------------------------------------------
+     674             :   // [Fetch]
+     675             :   // --------------------------------------------------------------------------
+     676             : 
+     677             :   virtual Error fetch() override;
+     678             : 
+     679             :   // --------------------------------------------------------------------------
+     680             :   // [Annotate]
+     681             :   // --------------------------------------------------------------------------
+     682             : 
+     683             :   virtual Error annotate() override;
+     684             : 
+     685             :   // --------------------------------------------------------------------------
+     686             :   // [Translate]
+     687             :   // --------------------------------------------------------------------------
+     688             : 
+     689             :   virtual Error translate() override;
+     690             : 
+     691             :   // --------------------------------------------------------------------------
+     692             :   // [Members]
+     693             :   // --------------------------------------------------------------------------
+     694             : 
+     695             :   //! Count of X86/X64 registers.
+     696             :   X86RegCount _regCount;
+     697             :   //! X86/X64 stack-pointer (esp or rsp).
+     698             :   X86Gp _zsp;
+     699             :   //! X86/X64 frame-pointer (ebp or rbp).
+     700             :   X86Gp _zbp;
+     701             : 
+     702             :   //! X86/X64 specific compiler state, linked to `_state`.
+     703             :   X86RAState _x86State;
+     704             :   //! Clobbered registers (for the whole function).
+     705             :   X86RegMask _clobberedRegs;
+     706             : 
+     707             :   //! Global allocable registers mask.
+     708             :   uint32_t _gaRegs[Globals::kMaxVRegKinds];
+     709             : 
+     710             :   bool _avxEnabled;
+     711             : 
+     712             :   //! Function variables base pointer (register).
+     713             :   uint8_t _varBaseRegId;
+     714             :   //! Function variables base offset.
+     715             :   int32_t _varBaseOffset;
+     716             : 
+     717             :   //! Temporary string builder used for logging.
+     718             :   StringBuilderTmp<256> _stringBuilder;
+     719             : };
+     720             : 
+     721             : //! \}
+     722             : 
+     723             : } // asmjit namespace
+     724             : } // namespace PLMD
+     725             : 
+     726             : // [Api-End]
+     727             : #include "./asmjit_apiend.h"
+     728             : 
+     729             : // [Guard]
+     730             : #endif // !ASMJIT_DISABLE_COMPILER
+     731             : #endif // _ASMJIT_X86_X86REGALLOC_P_H
+     732             : #pragma GCC diagnostic pop
+     733             : #endif // __PLUMED_HAS_ASMJIT
+     734             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.cpp.func-sort-c.html b/coverage-libs/asmjit/zone.cpp.func-sort-c.html new file mode 100644 index 000000000000..80aa4d53fff1 --- /dev/null +++ b/coverage-libs/asmjit/zone.cpp.func-sort-c.html @@ -0,0 +1,161 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:13629845.6 %
Date:2024-02-22 21:58:47Functions:132259.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12ZoneHashBase4_delEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase4_putEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase7_rehashEj0
_ZN4PLMD6asmjit13ZoneBitVector4fillEmmb0
_ZN4PLMD6asmjit13ZoneBitVector7_appendEPNS0_8ZoneHeapEb0
_ZN4PLMD6asmjit13ZoneBitVector7_resizeEPNS0_8ZoneHeapEmmb0
_ZN4PLMD6asmjit4Zone7sformatEPKcz0
_ZN4PLMD6asmjit8ZoneHeap15_releaseDynamicEPvm0
_ZN4PLMD6asmjitL24ZoneHash_getClosestPrimeEj0
_ZN4PLMD6asmjit12ZoneHashBase5resetEPNS0_8ZoneHeapE3896
_ZN4PLMD6asmjit14ZoneVectorBase7_resizeEPNS0_8ZoneHeapEmm3896
_ZN4PLMD6asmjit8ZoneHeap12_allocZeroedEmRm3896
_ZN4PLMD6asmjit4Zone6_allocEm7796
_ZN4PLMD6asmjit8ZoneHeap5resetEPNS0_4ZoneE9740
_ZN4PLMD6asmjit4ZoneC2Ejj11688
_ZN4PLMD6asmjit4ZoneD2Ev11688
_ZN4PLMD6asmjit4Zone5resetEb17532
_ZN4PLMD6asmjit14ZoneVectorBase5_growEPNS0_8ZoneHeapEmm18288
_ZN4PLMD6asmjit14ZoneVectorBase8_reserveEPNS0_8ZoneHeapEmm18288
_ZN4PLMD6asmjit4Zone11allocZeroedEm27684
_ZN4PLMD6asmjit4Zone3dupEPKvmb36702
_ZN4PLMD6asmjit8ZoneHeap6_allocEmRm79986
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.cpp.func.html b/coverage-libs/asmjit/zone.cpp.func.html new file mode 100644 index 000000000000..529b03b1e676 --- /dev/null +++ b/coverage-libs/asmjit/zone.cpp.func.html @@ -0,0 +1,161 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:13629845.6 %
Date:2024-02-22 21:58:47Functions:132259.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit12ZoneHashBase4_delEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase4_putEPNS0_12ZoneHashNodeE0
_ZN4PLMD6asmjit12ZoneHashBase5resetEPNS0_8ZoneHeapE3896
_ZN4PLMD6asmjit12ZoneHashBase7_rehashEj0
_ZN4PLMD6asmjit13ZoneBitVector4fillEmmb0
_ZN4PLMD6asmjit13ZoneBitVector7_appendEPNS0_8ZoneHeapEb0
_ZN4PLMD6asmjit13ZoneBitVector7_resizeEPNS0_8ZoneHeapEmmb0
_ZN4PLMD6asmjit14ZoneVectorBase5_growEPNS0_8ZoneHeapEmm18288
_ZN4PLMD6asmjit14ZoneVectorBase7_resizeEPNS0_8ZoneHeapEmm3896
_ZN4PLMD6asmjit14ZoneVectorBase8_reserveEPNS0_8ZoneHeapEmm18288
_ZN4PLMD6asmjit4Zone11allocZeroedEm27684
_ZN4PLMD6asmjit4Zone3dupEPKvmb36702
_ZN4PLMD6asmjit4Zone5resetEb17532
_ZN4PLMD6asmjit4Zone6_allocEm7796
_ZN4PLMD6asmjit4Zone7sformatEPKcz0
_ZN4PLMD6asmjit4ZoneC2Ejj11688
_ZN4PLMD6asmjit4ZoneD2Ev11688
_ZN4PLMD6asmjit8ZoneHeap12_allocZeroedEmRm3896
_ZN4PLMD6asmjit8ZoneHeap15_releaseDynamicEPvm0
_ZN4PLMD6asmjit8ZoneHeap5resetEPNS0_4ZoneE9740
_ZN4PLMD6asmjit8ZoneHeap6_allocEmRm79986
_ZN4PLMD6asmjitL24ZoneHash_getClosestPrimeEj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.cpp.gcov.html b/coverage-libs/asmjit/zone.cpp.gcov.html new file mode 100644 index 000000000000..f0757e713062 --- /dev/null +++ b/coverage-libs/asmjit/zone.cpp.gcov.html @@ -0,0 +1,936 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:13629845.6 %
Date:2024-02-22 21:58:47Functions:132259.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifdef __PLUMED_HAS_ASMJIT
+      21             : #pragma GCC diagnostic push
+      22             : #pragma GCC diagnostic ignored "-Wpedantic"
+      23             : // [AsmJit]
+      24             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      25             : //
+      26             : // [License]
+      27             : // Zlib - See LICENSE.md file in the package.
+      28             : 
+      29             : // [Export]
+      30             : #define ASMJIT_EXPORTS
+      31             : 
+      32             : // [Dependencies]
+      33             : #include "./utils.h"
+      34             : #include "./zone.h"
+      35             : 
+      36             : // [Api-Begin]
+      37             : #include "./asmjit_apibegin.h"
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace asmjit {
+      41             : 
+      42             : //! Zero size block used by `Zone` that doesn't have any memory allocated.
+      43             : static const Zone::Block Zone_zeroBlock = { nullptr, nullptr, 0, { 0 } };
+      44             : 
+      45             : static ASMJIT_INLINE uint32_t Zone_getAlignmentOffsetFromAlignment(uint32_t x) noexcept {
+      46       11688 :   switch (x) {
+      47             :     default: return 0;
+      48             :     case 0 : return 0;
+      49             :     case 1 : return 0;
+      50           0 :     case 2 : return 1;
+      51           0 :     case 4 : return 2;
+      52           0 :     case 8 : return 3;
+      53           0 :     case 16: return 4;
+      54           0 :     case 32: return 5;
+      55           0 :     case 64: return 6;
+      56             :   }
+      57             : }
+      58             : 
+      59             : // ============================================================================
+      60             : // [asmjit::Zone - Construction / Destruction]
+      61             : // ============================================================================
+      62             : 
+      63       11688 : Zone::Zone(uint32_t blockSize, uint32_t blockAlignment) noexcept
+      64       11688 :   : _ptr(nullptr),
+      65       11688 :     _end(nullptr),
+      66       11688 :     _block(const_cast<Zone::Block*>(&Zone_zeroBlock)),
+      67       11688 :     _blockSize(blockSize),
+      68       11688 :     _blockAlignmentShift(Zone_getAlignmentOffsetFromAlignment(blockAlignment)) {}
+      69             : 
+      70       11688 : Zone::~Zone() noexcept {
+      71       11688 :   reset(true);
+      72       11688 : }
+      73             : 
+      74             : // ============================================================================
+      75             : // [asmjit::Zone - Reset]
+      76             : // ============================================================================
+      77             : 
+      78       17532 : void Zone::reset(bool releaseMemory) noexcept {
+      79       17532 :   Block* cur = _block;
+      80             : 
+      81             :   // Can't be altered.
+      82       17532 :   if (cur == &Zone_zeroBlock)
+      83             :     return;
+      84             : 
+      85       11688 :   if (releaseMemory) {
+      86             :     // Since cur can be in the middle of the double-linked list, we have to
+      87             :     // traverse to both directions `prev` and `next` separately.
+      88        7792 :     Block* next = cur->next;
+      89             :     do {
+      90        7796 :       Block* prev = cur->prev;
+      91             :       Internal::releaseMemory(cur);
+      92             :       cur = prev;
+      93        7796 :     } while (cur);
+      94             : 
+      95             :     cur = next;
+      96        7792 :     while (cur) {
+      97           0 :       next = cur->next;
+      98             :       Internal::releaseMemory(cur);
+      99             :       cur = next;
+     100             :     }
+     101             : 
+     102        7792 :     _ptr = nullptr;
+     103        7792 :     _end = nullptr;
+     104        7792 :     _block = const_cast<Zone::Block*>(&Zone_zeroBlock);
+     105             :   }
+     106             :   else {
+     107        3896 :     while (cur->prev)
+     108             :       cur = cur->prev;
+     109             : 
+     110        3896 :     _ptr = cur->data;
+     111        3896 :     _end = _ptr + cur->size;
+     112        3896 :     _block = cur;
+     113             :   }
+     114             : }
+     115             : 
+     116             : // ============================================================================
+     117             : // [asmjit::Zone - Alloc]
+     118             : // ============================================================================
+     119             : 
+     120        7796 : void* Zone::_alloc(size_t size) noexcept {
+     121        7796 :   Block* curBlock = _block;
+     122             :   uint8_t* p;
+     123             : 
+     124        7796 :   size_t blockSize = std::max<size_t>(_blockSize, size);
+     125        7796 :   size_t blockAlignment = getBlockAlignment();
+     126             : 
+     127             :   // The `_alloc()` method can only be called if there is not enough space
+     128             :   // in the current block, see `alloc()` implementation for more details.
+     129             :   ASMJIT_ASSERT(curBlock == &Zone_zeroBlock || getRemainingSize() < size);
+     130             : 
+     131             :   // If the `Zone` has been cleared the current block doesn't have to be the
+     132             :   // last one. Check if there is a block that can be used instead of allocating
+     133             :   // a new one. If there is a `next` block it's completely unused, we don't have
+     134             :   // to check for remaining bytes.
+     135        7796 :   Block* next = curBlock->next;
+     136        7796 :   if (next && next->size >= size) {
+     137           0 :     p = Utils::alignTo(next->data, blockAlignment);
+     138             : 
+     139           0 :     _block = next;
+     140           0 :     _ptr = p + size;
+     141           0 :     _end = next->data + next->size;
+     142             : 
+     143           0 :     return static_cast<void*>(p);
+     144             :   }
+     145             : 
+     146             :   // Prevent arithmetic overflow.
+     147        7796 :   if (ASMJIT_UNLIKELY(blockSize > (~static_cast<size_t>(0) - sizeof(Block) - blockAlignment)))
+     148             :     return nullptr;
+     149             : 
+     150        7796 :   blockSize += blockAlignment;
+     151        7796 :   Block* newBlock = static_cast<Block*>(Internal::allocMemory(sizeof(Block) + blockSize));
+     152             : 
+     153        7796 :   if (ASMJIT_UNLIKELY(!newBlock))
+     154             :     return nullptr;
+     155             : 
+     156             :   // Align the pointer to `blockAlignment` and adjust the size of this block
+     157             :   // accordingly. It's the same as using `blockAlignment - Utils::alignDiff()`,
+     158             :   // just written differently.
+     159        7796 :   p = Utils::alignTo(newBlock->data, blockAlignment);
+     160        7796 :   newBlock->prev = nullptr;
+     161        7796 :   newBlock->next = nullptr;
+     162        7796 :   newBlock->size = blockSize;
+     163             : 
+     164        7796 :   if (curBlock != &Zone_zeroBlock) {
+     165           4 :     newBlock->prev = curBlock;
+     166           4 :     curBlock->next = newBlock;
+     167             : 
+     168             :     // Does only happen if there is a next block, but the requested memory
+     169             :     // can't fit into it. In this case a new buffer is allocated and inserted
+     170             :     // between the current block and the next one.
+     171           4 :     if (next) {
+     172           0 :       newBlock->next = next;
+     173           0 :       next->prev = newBlock;
+     174             :     }
+     175             :   }
+     176             : 
+     177        7796 :   _block = newBlock;
+     178        7796 :   _ptr = p + size;
+     179        7796 :   _end = newBlock->data + blockSize;
+     180             : 
+     181        7796 :   return static_cast<void*>(p);
+     182             : }
+     183             : 
+     184       27684 : void* Zone::allocZeroed(size_t size) noexcept {
+     185             :   void* p = alloc(size);
+     186       27684 :   if (ASMJIT_UNLIKELY(!p)) return p;
+     187       27684 :   return ::memset(p, 0, size);
+     188             : }
+     189             : 
+     190       36702 : void* Zone::dup(const void* data, size_t size, bool nullTerminate) noexcept {
+     191       36702 :   if (ASMJIT_UNLIKELY(!data || !size)) return nullptr;
+     192             : 
+     193             :   ASMJIT_ASSERT(size != IntTraits<size_t>::maxValue());
+     194       36702 :   uint8_t* m = allocT<uint8_t>(size + nullTerminate);
+     195       36702 :   if (ASMJIT_UNLIKELY(!m)) return nullptr;
+     196             : 
+     197             :   ::memcpy(m, data, size);
+     198       36702 :   if (nullTerminate) m[size] = '\0';
+     199             : 
+     200             :   return static_cast<void*>(m);
+     201             : }
+     202             : 
+     203           0 : char* Zone::sformat(const char* fmt, ...) noexcept {
+     204           0 :   if (ASMJIT_UNLIKELY(!fmt)) return nullptr;
+     205             : 
+     206             :   char buf[512];
+     207             :   size_t len;
+     208             : 
+     209             :   va_list ap;
+     210           0 :   va_start(ap, fmt);
+     211             : 
+     212           0 :   len = vsnprintf(buf, ASMJIT_ARRAY_SIZE(buf) - 1, fmt, ap);
+     213           0 :   buf[len++] = 0;
+     214             : 
+     215           0 :   va_end(ap);
+     216           0 :   return static_cast<char*>(dup(buf, len));
+     217             : }
+     218             : 
+     219             : // ============================================================================
+     220             : // [asmjit::ZoneHeap - Helpers]
+     221             : // ============================================================================
+     222             : 
+     223             : static bool ZoneHeap_hasDynamicBlock(ZoneHeap* self, ZoneHeap::DynamicBlock* block) noexcept {
+     224             :   ZoneHeap::DynamicBlock* cur = self->_dynamicBlocks;
+     225             :   while (cur) {
+     226             :     if (cur == block)
+     227             :       return true;
+     228             :     cur = cur->next;
+     229             :   }
+     230             :   return false;
+     231             : }
+     232             : 
+     233             : // ============================================================================
+     234             : // [asmjit::ZoneHeap - Init / Reset]
+     235             : // ============================================================================
+     236             : 
+     237        9740 : void ZoneHeap::reset(Zone* zone) noexcept {
+     238             :   // Free dynamic blocks.
+     239        9740 :   DynamicBlock* block = _dynamicBlocks;
+     240        9748 :   while (block) {
+     241           8 :     DynamicBlock* next = block->next;
+     242             :     Internal::releaseMemory(block);
+     243             :     block = next;
+     244             :   }
+     245             : 
+     246             :   // Zero the entire class and initialize to the given `zone`.
+     247             :   ::memset(this, 0, sizeof(*this));
+     248        9740 :   _zone = zone;
+     249        9740 : }
+     250             : 
+     251             : // ============================================================================
+     252             : // [asmjit::ZoneHeap - Alloc / Release]
+     253             : // ============================================================================
+     254             : 
+     255       79986 : void* ZoneHeap::_alloc(size_t size, size_t& allocatedSize) noexcept {
+     256             :   ASMJIT_ASSERT(isInitialized());
+     257             : 
+     258             :   // We use our memory pool only if the requested block is of a reasonable size.
+     259             :   uint32_t slot;
+     260             :   if (_getSlotIndex(size, slot, allocatedSize)) {
+     261             :     // Slot reuse.
+     262       79978 :     uint8_t* p = reinterpret_cast<uint8_t*>(_slots[slot]);
+     263       79978 :     size = allocatedSize;
+     264             : 
+     265       79978 :     if (p) {
+     266        1688 :       _slots[slot] = reinterpret_cast<Slot*>(p)->next;
+     267             :       //printf("ALLOCATED %p of size %d (SLOT %d)\n", p, int(size), slot);
+     268        1688 :       return p;
+     269             :     }
+     270             : 
+     271             :     // So use Zone to allocate a new chunk for us. But before we use it, we
+     272             :     // check if there is enough room for the new chunk in zone, and if not,
+     273             :     // we redistribute the remaining memory in Zone's current block into slots.
+     274       78290 :     Zone* zone = _zone;
+     275             :     p = Utils::alignTo(zone->getCursor(), kBlockAlignment);
+     276       78290 :     size_t remain = (p <= zone->getEnd()) ? (size_t)(zone->getEnd() - p) : size_t(0);
+     277             : 
+     278       78290 :     if (ASMJIT_LIKELY(remain >= size)) {
+     279       74394 :       zone->setCursor(p + size);
+     280             :       //printf("ALLOCATED %p of size %d (SLOT %d)\n", p, int(size), slot);
+     281       74394 :       return p;
+     282             :     }
+     283             :     else {
+     284             :       // Distribute the remaining memory to suitable slots.
+     285        3896 :       if (remain >= kLoGranularity) {
+     286             :         do {
+     287           0 :           size_t distSize = std::min<size_t>(remain, kLoMaxSize);
+     288           0 :           uint32_t distSlot = static_cast<uint32_t>((distSize - kLoGranularity) / kLoGranularity);
+     289             :           ASMJIT_ASSERT(distSlot < kLoCount);
+     290             : 
+     291           0 :           reinterpret_cast<Slot*>(p)->next = _slots[distSlot];
+     292           0 :           _slots[distSlot] = reinterpret_cast<Slot*>(p);
+     293             : 
+     294           0 :           p += distSize;
+     295           0 :           remain -= distSize;
+     296           0 :         } while (remain >= kLoGranularity);
+     297             :         zone->setCursor(p);
+     298             :       }
+     299             : 
+     300        3896 :       p = static_cast<uint8_t*>(zone->_alloc(size));
+     301        3896 :       if (ASMJIT_UNLIKELY(!p)) {
+     302           0 :         allocatedSize = 0;
+     303           0 :         return nullptr;
+     304             :       }
+     305             : 
+     306             :       //printf("ALLOCATED %p of size %d (SLOT %d)\n", p, int(size), slot);
+     307             :       return p;
+     308             :     }
+     309             :   }
+     310             :   else {
+     311             :     // Allocate a dynamic block.
+     312             :     size_t overhead = sizeof(DynamicBlock) + sizeof(DynamicBlock*) + kBlockAlignment;
+     313             : 
+     314             :     // Handle a possible overflow.
+     315           8 :     if (ASMJIT_UNLIKELY(overhead >= ~static_cast<size_t>(0) - size))
+     316             :       return nullptr;
+     317             : 
+     318           8 :     void* p = Internal::allocMemory(size + overhead);
+     319           8 :     if (ASMJIT_UNLIKELY(!p)) {
+     320           0 :       allocatedSize = 0;
+     321           0 :       return nullptr;
+     322             :     }
+     323             : 
+     324             :     // Link as first in `_dynamicBlocks` double-linked list.
+     325             :     DynamicBlock* block = static_cast<DynamicBlock*>(p);
+     326           8 :     DynamicBlock* next = _dynamicBlocks;
+     327             : 
+     328           8 :     if (next)
+     329           0 :       next->prev = block;
+     330             : 
+     331           8 :     block->prev = nullptr;
+     332           8 :     block->next = next;
+     333           8 :     _dynamicBlocks = block;
+     334             : 
+     335             :     // Align the pointer to the guaranteed alignment and store `DynamicBlock`
+     336             :     // at the end of the memory block, so `_releaseDynamic()` can find it.
+     337           8 :     p = Utils::alignTo(static_cast<uint8_t*>(p) + sizeof(DynamicBlock) + sizeof(DynamicBlock*), kBlockAlignment);
+     338           8 :     reinterpret_cast<DynamicBlock**>(p)[-1] = block;
+     339             : 
+     340           8 :     allocatedSize = size;
+     341             :     //printf("ALLOCATED DYNAMIC %p of size %d\n", p, int(size));
+     342           8 :     return p;
+     343             :   }
+     344             : }
+     345             : 
+     346        3896 : void* ZoneHeap::_allocZeroed(size_t size, size_t& allocatedSize) noexcept {
+     347             :   ASMJIT_ASSERT(isInitialized());
+     348             : 
+     349        3896 :   void* p = _alloc(size, allocatedSize);
+     350        3896 :   if (ASMJIT_UNLIKELY(!p)) return p;
+     351        3896 :   return ::memset(p, 0, allocatedSize);
+     352             : }
+     353             : 
+     354           0 : void ZoneHeap::_releaseDynamic(void* p, size_t size) noexcept {
+     355             :   ASMJIT_ASSERT(isInitialized());
+     356             :   //printf("RELEASING DYNAMIC %p of size %d\n", p, int(size));
+     357             : 
+     358             :   // Pointer to `DynamicBlock` is stored at [-1].
+     359           0 :   DynamicBlock* block = reinterpret_cast<DynamicBlock**>(p)[-1];
+     360             :   ASMJIT_ASSERT(ZoneHeap_hasDynamicBlock(this, block));
+     361             : 
+     362             :   // Unlink and free.
+     363           0 :   DynamicBlock* prev = block->prev;
+     364           0 :   DynamicBlock* next = block->next;
+     365             : 
+     366           0 :   if (prev)
+     367           0 :     prev->next = next;
+     368             :   else
+     369           0 :     _dynamicBlocks = next;
+     370             : 
+     371           0 :   if (next)
+     372           0 :     next->prev = prev;
+     373             : 
+     374             :   Internal::releaseMemory(block);
+     375           0 : }
+     376             : 
+     377             : // ============================================================================
+     378             : // [asmjit::ZoneVectorBase - Helpers]
+     379             : // ============================================================================
+     380             : 
+     381       18288 : Error ZoneVectorBase::_grow(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     382       18288 :   size_t threshold = Globals::kAllocThreshold / sizeOfT;
+     383       18288 :   size_t capacity = _capacity;
+     384       18288 :   size_t after = _length;
+     385             : 
+     386       18288 :   if (ASMJIT_UNLIKELY(IntTraits<size_t>::maxValue() - n < after))
+     387             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     388             : 
+     389       18288 :   after += n;
+     390       18288 :   if (capacity >= after)
+     391             :     return kErrorOk;
+     392             : 
+     393             :   // ZoneVector is used as an array to hold short-lived data structures used
+     394             :   // during code generation. The growing strategy is simple - use small capacity
+     395             :   // at the beginning (very good for ZoneHeap) and then grow quicker to prevent
+     396             :   // successive reallocations.
+     397       18288 :   if (capacity < 4)
+     398             :     capacity = 4;
+     399        6600 :   else if (capacity < 8)
+     400             :     capacity = 8;
+     401        3500 :   else if (capacity < 16)
+     402             :     capacity = 16;
+     403        1232 :   else if (capacity < 64)
+     404             :     capacity = 64;
+     405             :   else if (capacity < 256)
+     406             :     capacity = 256;
+     407             : 
+     408       18288 :   while (capacity < after) {
+     409           0 :     if (capacity < threshold)
+     410           0 :       capacity *= 2;
+     411             :     else
+     412           0 :       capacity += threshold;
+     413             :   }
+     414             : 
+     415       18288 :   return _reserve(heap, sizeOfT, capacity);
+     416             : }
+     417             : 
+     418       18288 : Error ZoneVectorBase::_reserve(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     419       18288 :   size_t oldCapacity = _capacity;
+     420       18288 :   if (oldCapacity >= n) return kErrorOk;
+     421             : 
+     422       18288 :   size_t nBytes = n * sizeOfT;
+     423       18288 :   if (ASMJIT_UNLIKELY(nBytes < n))
+     424             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     425             : 
+     426             :   size_t allocatedBytes;
+     427             :   uint8_t* newData = static_cast<uint8_t*>(heap->alloc(nBytes, allocatedBytes));
+     428             : 
+     429       18288 :   if (ASMJIT_UNLIKELY(!newData))
+     430             :     return DebugUtils::errored(kErrorNoHeapMemory);
+     431             : 
+     432       18288 :   void* oldData = _data;
+     433       18288 :   if (_length)
+     434        6600 :     ::memcpy(newData, oldData, _length * sizeOfT);
+     435             : 
+     436       18288 :   if (oldData)
+     437        6600 :     heap->release(oldData, oldCapacity * sizeOfT);
+     438             : 
+     439       18288 :   _capacity = allocatedBytes / sizeOfT;
+     440             :   ASMJIT_ASSERT(_capacity >= n);
+     441             : 
+     442       18288 :   _data = newData;
+     443       18288 :   return kErrorOk;
+     444             : }
+     445             : 
+     446        3896 : Error ZoneVectorBase::_resize(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept {
+     447        3896 :   size_t length = _length;
+     448        3896 :   if (_capacity < n) {
+     449        1948 :     ASMJIT_PROPAGATE(_grow(heap, sizeOfT, n - length));
+     450             :     ASMJIT_ASSERT(_capacity >= n);
+     451             :   }
+     452             : 
+     453        3896 :   if (length < n)
+     454        3896 :     ::memset(static_cast<uint8_t*>(_data) + length * sizeOfT, 0, (n - length) * sizeOfT);
+     455             : 
+     456        3896 :   _length = n;
+     457        3896 :   return kErrorOk;
+     458             : }
+     459             : 
+     460             : // ============================================================================
+     461             : // [asmjit::ZoneBitVector - Ops]
+     462             : // ============================================================================
+     463             : 
+     464           0 : Error ZoneBitVector::_resize(ZoneHeap* heap, size_t newLength, size_t idealCapacity, bool newBitsValue) noexcept {
+     465             :   ASMJIT_ASSERT(idealCapacity >= newLength);
+     466             : 
+     467           0 :   if (newLength <= _length) {
+     468             :     // The size after the resize is lesser than or equal to the current length.
+     469           0 :     size_t idx = newLength / kBitsPerWord;
+     470           0 :     size_t bit = newLength % kBitsPerWord;
+     471             : 
+     472             :     // Just set all bits outside of the new length in the last word to zero.
+     473             :     // There is a case that there are not bits to set if `bit` is zero. This
+     474             :     // happens when `newLength` is a multiply of `kBitsPerWord` like 64, 128,
+     475             :     // and so on. In that case don't change anything as that would mean settings
+     476             :     // bits outside of the `_length`.
+     477           0 :     if (bit)
+     478           0 :       _data[idx] &= (static_cast<uintptr_t>(1) << bit) - 1U;
+     479             : 
+     480           0 :     _length = newLength;
+     481           0 :     return kErrorOk;
+     482             :   }
+     483             : 
+     484             :   size_t oldLength = _length;
+     485           0 :   BitWord* data = _data;
+     486             : 
+     487           0 :   if (newLength > _capacity) {
+     488             :     // Realloc needed... Calculate the minimum capacity (in bytes) requied.
+     489             :     size_t minimumCapacityInBits = Utils::alignTo<size_t>(idealCapacity, kBitsPerWord);
+     490             :     size_t allocatedCapacity;
+     491             : 
+     492           0 :     if (ASMJIT_UNLIKELY(minimumCapacityInBits < newLength))
+     493           0 :       return DebugUtils::errored(kErrorNoHeapMemory);
+     494             : 
+     495             :     // Normalize to bytes.
+     496           0 :     size_t minimumCapacity = minimumCapacityInBits / 8;
+     497             :     BitWord* newData = static_cast<BitWord*>(heap->alloc(minimumCapacity, allocatedCapacity));
+     498             : 
+     499           0 :     if (ASMJIT_UNLIKELY(!newData))
+     500             :       return DebugUtils::errored(kErrorNoHeapMemory);
+     501             : 
+     502             :     // `allocatedCapacity` now contains number in bytes, we need bits.
+     503           0 :     size_t allocatedCapacityInBits = allocatedCapacity * 8;
+     504             : 
+     505             :     // Arithmetic overflow should normally not happen. If it happens we just
+     506             :     // change the `allocatedCapacityInBits` to the `minimumCapacityInBits` as
+     507             :     // this value is still safe to be used to call `_heap->release(...)`.
+     508           0 :     if (ASMJIT_UNLIKELY(allocatedCapacityInBits < allocatedCapacity))
+     509             :       allocatedCapacityInBits = minimumCapacityInBits;
+     510             : 
+     511           0 :     if (oldLength)
+     512             :       ::memcpy(newData, data, _wordsPerBits(oldLength));
+     513             : 
+     514           0 :     if (data)
+     515           0 :       heap->release(data, _capacity / 8);
+     516             :     data = newData;
+     517             : 
+     518           0 :     _data = data;
+     519           0 :     _capacity = allocatedCapacityInBits;
+     520             :   }
+     521             : 
+     522             :   // Start (of the old length) and end (of the new length) bits
+     523           0 :   size_t idx = oldLength / kBitsPerWord;
+     524           0 :   size_t startBit = oldLength % kBitsPerWord;
+     525           0 :   size_t endBit = newLength % kBitsPerWord;
+     526             : 
+     527             :   // Set new bits to either 0 or 1. The `pattern` is used to set multiple
+     528             :   // bits per bit-word and contains either all zeros or all ones.
+     529             :   BitWord pattern = _patternFromBit(newBitsValue);
+     530             : 
+     531             :   // First initialize the last bit-word of the old length.
+     532           0 :   if (startBit) {
+     533             :     size_t nBits = 0;
+     534             : 
+     535           0 :     if (idx == (newLength / kBitsPerWord)) {
+     536             :       // The number of bit-words is the same after the resize. In that case
+     537             :       // we need to set only bits necessary in the current last bit-word.
+     538             :       ASMJIT_ASSERT(startBit < endBit);
+     539           0 :       nBits = endBit - startBit;
+     540             :     }
+     541             :     else {
+     542             :       // There is be more bit-words after the resize. In that case we don't
+     543             :       // have to be extra careful about the last bit-word of the old length.
+     544           0 :       nBits = kBitsPerWord - startBit;
+     545             :     }
+     546             : 
+     547           0 :     data[idx++] |= pattern << nBits;
+     548             :   }
+     549             : 
+     550             :   // Initialize all bit-words after the last bit-word of the old length.
+     551             :   size_t endIdx = _wordsPerBits(newLength);
+     552           0 :   endIdx -= static_cast<size_t>(endIdx * kBitsPerWord == newLength);
+     553             : 
+     554           0 :   while (idx <= endIdx)
+     555           0 :     data[idx++] = pattern;
+     556             : 
+     557             :   // Clear unused bits of the last bit-word.
+     558           0 :   if (endBit)
+     559           0 :     data[endIdx] &= (static_cast<BitWord>(1) << endBit) - 1;
+     560             : 
+     561           0 :   _length = newLength;
+     562           0 :   return kErrorOk;
+     563             : }
+     564             : 
+     565           0 : Error ZoneBitVector::_append(ZoneHeap* heap, bool value) noexcept {
+     566             :   size_t kThreshold = Globals::kAllocThreshold * 8;
+     567           0 :   size_t newLength = _length + 1;
+     568           0 :   size_t idealCapacity = _capacity;
+     569             : 
+     570           0 :   if (idealCapacity < 128)
+     571             :     idealCapacity = 128;
+     572           0 :   else if (idealCapacity <= kThreshold)
+     573           0 :     idealCapacity *= 2;
+     574             :   else
+     575           0 :     idealCapacity += kThreshold;
+     576             : 
+     577           0 :   if (ASMJIT_UNLIKELY(idealCapacity < _capacity)) {
+     578             :     // It's technically impossible that `_length + 1` overflows.
+     579             :     idealCapacity = newLength;
+     580             :     ASMJIT_ASSERT(idealCapacity > _capacity);
+     581             :   }
+     582             : 
+     583           0 :   return _resize(heap, newLength, idealCapacity, value);
+     584             : }
+     585             : 
+     586           0 : Error ZoneBitVector::fill(size_t from, size_t to, bool value) noexcept {
+     587           0 :   if (ASMJIT_UNLIKELY(from >= to)) {
+     588           0 :     if (from > to)
+     589             :       return DebugUtils::errored(kErrorInvalidArgument);
+     590             :     else
+     591           0 :       return kErrorOk;
+     592             :   }
+     593             : 
+     594             :   ASMJIT_ASSERT(from <= _length);
+     595             :   ASMJIT_ASSERT(to <= _length);
+     596             : 
+     597             :   // This is very similar to `ZoneBitVector::_fill()`, however, since we
+     598             :   // actually set bits that are already part of the container we need to
+     599             :   // special case filiing to zeros and ones.
+     600           0 :   size_t idx = from / kBitsPerWord;
+     601           0 :   size_t startBit = from % kBitsPerWord;
+     602             : 
+     603           0 :   size_t endIdx = to / kBitsPerWord;
+     604           0 :   size_t endBit = to % kBitsPerWord;
+     605             : 
+     606           0 :   BitWord* data = _data;
+     607             :   ASMJIT_ASSERT(data != nullptr);
+     608             : 
+     609             :   // Special case for non-zero `startBit`.
+     610           0 :   if (startBit) {
+     611           0 :     if (idx == endIdx) {
+     612             :       ASMJIT_ASSERT(startBit < endBit);
+     613             : 
+     614           0 :       size_t nBits = endBit - startBit;
+     615           0 :       BitWord mask = ((static_cast<BitWord>(1) << nBits) - 1) << startBit;
+     616             : 
+     617           0 :       if (value)
+     618           0 :         data[idx] |= mask;
+     619             :       else
+     620           0 :         data[idx] &= ~mask;
+     621           0 :       return kErrorOk;
+     622             :     }
+     623             :     else {
+     624           0 :       BitWord mask = (static_cast<BitWord>(0) - 1) << startBit;
+     625             : 
+     626           0 :       if (value)
+     627           0 :         data[idx++] |= mask;
+     628             :       else
+     629           0 :         data[idx++] &= ~mask;
+     630             :     }
+     631             :   }
+     632             : 
+     633             :   // Fill all bits in case there is a gap between the current `idx` and `endIdx`.
+     634           0 :   if (idx < endIdx) {
+     635             :     BitWord pattern = _patternFromBit(value);
+     636             :     do {
+     637           0 :       data[idx++] = pattern;
+     638           0 :     } while (idx < endIdx);
+     639             :   }
+     640             : 
+     641             :   // Special case for non-zero `endBit`.
+     642           0 :   if (endBit) {
+     643           0 :     BitWord mask = ((static_cast<BitWord>(1) << endBit) - 1);
+     644           0 :     if (value)
+     645           0 :       data[endIdx] |= mask;
+     646             :     else
+     647           0 :       data[endIdx] &= ~mask;
+     648             :   }
+     649             : 
+     650             :   return kErrorOk;
+     651             : }
+     652             : 
+     653             : // ============================================================================
+     654             : // [asmjit::ZoneHashBase - Utilities]
+     655             : // ============================================================================
+     656             : 
+     657           0 : static uint32_t ZoneHash_getClosestPrime(uint32_t x) noexcept {
+     658             :   static const uint32_t primeTable[] = {
+     659             :     23, 53, 193, 389, 769, 1543, 3079, 6151, 12289, 24593
+     660             :   };
+     661             : 
+     662             :   size_t i = 0;
+     663             :   uint32_t p;
+     664             : 
+     665             :   do {
+     666           0 :     if ((p = primeTable[i]) > x)
+     667             :       break;
+     668           0 :   } while (++i < ASMJIT_ARRAY_SIZE(primeTable));
+     669             : 
+     670           0 :   return p;
+     671             : }
+     672             : 
+     673             : // ============================================================================
+     674             : // [asmjit::ZoneHashBase - Reset]
+     675             : // ============================================================================
+     676             : 
+     677        3896 : void ZoneHashBase::reset(ZoneHeap* heap) noexcept {
+     678        3896 :   ZoneHashNode** oldData = _data;
+     679        3896 :   if (oldData != _embedded)
+     680           0 :     _heap->release(oldData, _bucketsCount * sizeof(ZoneHashNode*));
+     681             : 
+     682        3896 :   _heap = heap;
+     683        3896 :   _size = 0;
+     684        3896 :   _bucketsCount = 1;
+     685        3896 :   _bucketsGrow = 1;
+     686        3896 :   _data = _embedded;
+     687        3896 :   _embedded[0] = nullptr;
+     688        3896 : }
+     689             : 
+     690             : // ============================================================================
+     691             : // [asmjit::ZoneHashBase - Rehash]
+     692             : // ============================================================================
+     693             : 
+     694           0 : void ZoneHashBase::_rehash(uint32_t newCount) noexcept {
+     695             :   ASMJIT_ASSERT(isInitialized());
+     696             : 
+     697           0 :   ZoneHashNode** oldData = _data;
+     698             :   ZoneHashNode** newData = reinterpret_cast<ZoneHashNode**>(
+     699           0 :     _heap->allocZeroed(static_cast<size_t>(newCount) * sizeof(ZoneHashNode*)));
+     700             : 
+     701             :   // We can still store nodes into the table, but it will degrade.
+     702           0 :   if (ASMJIT_UNLIKELY(newData == nullptr))
+     703             :     return;
+     704             : 
+     705             :   uint32_t i;
+     706           0 :   uint32_t oldCount = _bucketsCount;
+     707             : 
+     708           0 :   for (i = 0; i < oldCount; i++) {
+     709           0 :     ZoneHashNode* node = oldData[i];
+     710           0 :     while (node) {
+     711           0 :       ZoneHashNode* next = node->_hashNext;
+     712           0 :       uint32_t hMod = node->_hVal % newCount;
+     713             : 
+     714           0 :       node->_hashNext = newData[hMod];
+     715           0 :       newData[hMod] = node;
+     716             : 
+     717             :       node = next;
+     718             :     }
+     719             :   }
+     720             : 
+     721             :   // 90% is the maximum occupancy, can't overflow since the maximum capacity
+     722             :   // is limited to the last prime number stored in the prime table.
+     723           0 :   if (oldData != _embedded)
+     724           0 :     _heap->release(oldData, _bucketsCount * sizeof(ZoneHashNode*));
+     725             : 
+     726           0 :   _bucketsCount = newCount;
+     727           0 :   _bucketsGrow = newCount * 9 / 10;
+     728             : 
+     729           0 :   _data = newData;
+     730             : }
+     731             : 
+     732             : // ============================================================================
+     733             : // [asmjit::ZoneHashBase - Ops]
+     734             : // ============================================================================
+     735             : 
+     736           0 : ZoneHashNode* ZoneHashBase::_put(ZoneHashNode* node) noexcept {
+     737           0 :   uint32_t hMod = node->_hVal % _bucketsCount;
+     738           0 :   ZoneHashNode* next = _data[hMod];
+     739             : 
+     740           0 :   node->_hashNext = next;
+     741           0 :   _data[hMod] = node;
+     742             : 
+     743           0 :   if (++_size >= _bucketsGrow && next) {
+     744           0 :     uint32_t newCapacity = ZoneHash_getClosestPrime(_bucketsCount);
+     745           0 :     if (newCapacity != _bucketsCount)
+     746           0 :       _rehash(newCapacity);
+     747             :   }
+     748             : 
+     749           0 :   return node;
+     750             : }
+     751             : 
+     752           0 : ZoneHashNode* ZoneHashBase::_del(ZoneHashNode* node) noexcept {
+     753           0 :   uint32_t hMod = node->_hVal % _bucketsCount;
+     754             : 
+     755           0 :   ZoneHashNode** pPrev = &_data[hMod];
+     756           0 :   ZoneHashNode* p = *pPrev;
+     757             : 
+     758           0 :   while (p) {
+     759           0 :     if (p == node) {
+     760           0 :       *pPrev = p->_hashNext;
+     761           0 :       return node;
+     762             :     }
+     763             : 
+     764           0 :     pPrev = &p->_hashNext;
+     765           0 :     p = *pPrev;
+     766             :   }
+     767             : 
+     768             :   return nullptr;
+     769             : }
+     770             : 
+     771             : // ============================================================================
+     772             : // [asmjit::Zone - Test]
+     773             : // ============================================================================
+     774             : 
+     775             : #if defined(ASMJIT_TEST)
+     776             : UNIT(base_zonevector) {
+     777             :   Zone zone(8096 - Zone::kZoneOverhead);
+     778             :   ZoneHeap heap(&zone);
+     779             : 
+     780             :   int i;
+     781             :   int kMax = 100000;
+     782             : 
+     783             :   ZoneVector<int> vec;
+     784             : 
+     785             :   INFO("ZoneVector<int> basic tests");
+     786             :   EXPECT(vec.append(&heap, 0) == kErrorOk);
+     787             :   EXPECT(vec.isEmpty() == false);
+     788             :   EXPECT(vec.getLength() == 1);
+     789             :   EXPECT(vec.getCapacity() >= 1);
+     790             :   EXPECT(vec.indexOf(0) == 0);
+     791             :   EXPECT(vec.indexOf(-11) == Globals::kInvalidIndex);
+     792             : 
+     793             :   vec.clear();
+     794             :   EXPECT(vec.isEmpty());
+     795             :   EXPECT(vec.getLength() == 0);
+     796             :   EXPECT(vec.indexOf(0) == Globals::kInvalidIndex);
+     797             : 
+     798             :   for (i = 0; i < kMax; i++) {
+     799             :     EXPECT(vec.append(&heap, i) == kErrorOk);
+     800             :   }
+     801             :   EXPECT(vec.isEmpty() == false);
+     802             :   EXPECT(vec.getLength() == static_cast<size_t>(kMax));
+     803             :   EXPECT(vec.indexOf(kMax - 1) == static_cast<size_t>(kMax - 1));
+     804             : }
+     805             : 
+     806             : UNIT(base_ZoneBitVector) {
+     807             :   Zone zone(8096 - Zone::kZoneOverhead);
+     808             :   ZoneHeap heap(&zone);
+     809             : 
+     810             :   size_t i, count;
+     811             :   size_t kMaxCount = 100;
+     812             : 
+     813             :   ZoneBitVector vec;
+     814             :   EXPECT(vec.isEmpty());
+     815             :   EXPECT(vec.getLength() == 0);
+     816             : 
+     817             :   INFO("ZoneBitVector::resize()");
+     818             :   for (count = 1; count < kMaxCount; count++) {
+     819             :     vec.clear();
+     820             :     EXPECT(vec.resize(&heap, count, false) == kErrorOk);
+     821             :     EXPECT(vec.getLength() == count);
+     822             : 
+     823             :     for (i = 0; i < count; i++)
+     824             :       EXPECT(vec.getAt(i) == false);
+     825             : 
+     826             :     vec.clear();
+     827             :     EXPECT(vec.resize(&heap, count, true) == kErrorOk);
+     828             :     EXPECT(vec.getLength() == count);
+     829             : 
+     830             :     for (i = 0; i < count; i++)
+     831             :       EXPECT(vec.getAt(i) == true);
+     832             :   }
+     833             : 
+     834             :   INFO("ZoneBitVector::fill()");
+     835             :   for (count = 1; count < kMaxCount; count += 2) {
+     836             :     vec.clear();
+     837             :     EXPECT(vec.resize(&heap, count) == kErrorOk);
+     838             :     EXPECT(vec.getLength() == count);
+     839             : 
+     840             :     for (i = 0; i < (count + 1) / 2; i++) {
+     841             :       bool value = static_cast<bool>(i & 1);
+     842             :       EXPECT(vec.fill(i, count - i, value) == kErrorOk);
+     843             :     }
+     844             : 
+     845             :     for (i = 0; i < count; i++) {
+     846             :       EXPECT(vec.getAt(i) == static_cast<bool>(i & 1));
+     847             :     }
+     848             :   }
+     849             : }
+     850             : 
+     851             : #endif // ASMJIT_TEST
+     852             : 
+     853             : } // asmjit namespace
+     854             : } // namespace PLMD
+     855             : 
+     856             : // [Api-End]
+     857             : #include "./asmjit_apiend.h"
+     858             : #pragma GCC diagnostic pop
+     859             : #endif // __PLUMED_HAS_ASMJIT
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.h.func-sort-c.html b/coverage-libs/asmjit/zone.h.func-sort-c.html new file mode 100644 index 000000000000..ef30957c94c8 --- /dev/null +++ b/coverage-libs/asmjit/zone.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:739378.5 %
Date:2024-02-22 21:58:47Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10ZoneVectorIPNS0_6CBPassEE6appendEPNS0_8ZoneHeapERKS3_1948
_ZN4PLMD6asmjit10ZoneVectorIPNS0_7VirtRegEE6appendEPNS0_8ZoneHeapERKS3_23788
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.h.func.html b/coverage-libs/asmjit/zone.h.func.html new file mode 100644 index 000000000000..cb2511ecb199 --- /dev/null +++ b/coverage-libs/asmjit/zone.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:739378.5 %
Date:2024-02-22 21:58:47Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6asmjit10ZoneVectorIPNS0_6CBPassEE6appendEPNS0_8ZoneHeapERKS3_1948
_ZN4PLMD6asmjit10ZoneVectorIPNS0_7VirtRegEE6appendEPNS0_8ZoneHeapERKS3_23788
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/asmjit/zone.h.gcov.html b/coverage-libs/asmjit/zone.h.gcov.html new file mode 100644 index 000000000000..0eff0d22eb52 --- /dev/null +++ b/coverage-libs/asmjit/zone.h.gcov.html @@ -0,0 +1,1234 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - asmjit/zone.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - asmjit - zone.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:739378.5 %
Date:2024-02-22 21:58:47Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2008-2017, Petr Kobalicek
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : #ifndef __PLUMED_asmjit_zone_h
+      21             : #define __PLUMED_asmjit_zone_h
+      22             : #ifdef __PLUMED_HAS_ASMJIT
+      23             : #pragma GCC diagnostic push
+      24             : #pragma GCC diagnostic ignored "-Wpedantic"
+      25             : // [AsmJit]
+      26             : // Complete x86/x64 JIT and Remote Assembler for C++.
+      27             : //
+      28             : // [License]
+      29             : // Zlib - See LICENSE.md file in the package.
+      30             : 
+      31             : // [Guard]
+      32             : #ifndef _ASMJIT_BASE_ZONE_H
+      33             : #define _ASMJIT_BASE_ZONE_H
+      34             : 
+      35             : // [Dependencies]
+      36             : #include "./utils.h"
+      37             : 
+      38             : // [Api-Begin]
+      39             : #include "./asmjit_apibegin.h"
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace asmjit {
+      43             : 
+      44             : //! \addtogroup asmjit_base
+      45             : //! \{
+      46             : 
+      47             : // ============================================================================
+      48             : // [asmjit::Zone]
+      49             : // ============================================================================
+      50             : 
+      51             : //! Memory zone.
+      52             : //!
+      53             : //! Zone is an incremental memory allocator that allocates memory by simply
+      54             : //! incrementing a pointer. It allocates blocks of memory by using standard
+      55             : //! C `malloc`, but divides these blocks into smaller segments requested by
+      56             : //! calling `Zone::alloc()` and friends.
+      57             : //!
+      58             : //! Zone has no function to release the allocated memory. It has to be released
+      59             : //! all at once by calling `reset()`. If you need a more friendly allocator that
+      60             : //! also supports `release()`, consider using \ref Zone with \ref ZoneHeap.
+      61             : class Zone {
+      62             : public:
+      63             :   //! \internal
+      64             :   //!
+      65             :   //! A single block of memory.
+      66             :   struct Block {
+      67             :     Block* prev;                         //!< Link to the previous block.
+      68             :     Block* next;                         //!< Link to the next block.
+      69             :     size_t size;                         //!< Size of the block.
+      70             :     uint8_t data[sizeof(void*)];         //!< Data.
+      71             :   };
+      72             : 
+      73             :   enum {
+      74             :     //! Zone allocator overhead.
+      75             :     kZoneOverhead = Globals::kAllocOverhead + static_cast<int>(sizeof(Block))
+      76             :   };
+      77             : 
+      78             :   // --------------------------------------------------------------------------
+      79             :   // [Construction / Destruction]
+      80             :   // --------------------------------------------------------------------------
+      81             : 
+      82             :   //! Create a new instance of `Zone` allocator.
+      83             :   //!
+      84             :   //! The `blockSize` parameter describes the default size of the block. If the
+      85             :   //! `size` parameter passed to `alloc()` is greater than the default size
+      86             :   //! `Zone` will allocate and use a larger block, but it will not change the
+      87             :   //! default `blockSize`.
+      88             :   //!
+      89             :   //! It's not required, but it's good practice to set `blockSize` to a
+      90             :   //! reasonable value that depends on the usage of `Zone`. Greater block sizes
+      91             :   //! are generally safer and perform better than unreasonably low values.
+      92             :   ASMJIT_API Zone(uint32_t blockSize, uint32_t blockAlignment = 0) noexcept;
+      93             : 
+      94             :   //! Destroy the `Zone` instance.
+      95             :   //!
+      96             :   //! This will destroy the `Zone` instance and release all blocks of memory
+      97             :   //! allocated by it. It performs implicit `reset(true)`.
+      98             :   ASMJIT_API ~Zone() noexcept;
+      99             : 
+     100             :   // --------------------------------------------------------------------------
+     101             :   // [Reset]
+     102             :   // --------------------------------------------------------------------------
+     103             : 
+     104             :   //! Reset the `Zone` invalidating all blocks allocated.
+     105             :   //!
+     106             :   //! If `releaseMemory` is true all buffers will be released to the system.
+     107             :   ASMJIT_API void reset(bool releaseMemory = false) noexcept;
+     108             : 
+     109             :   // --------------------------------------------------------------------------
+     110             :   // [Accessors]
+     111             :   // --------------------------------------------------------------------------
+     112             : 
+     113             :   //! Get the default block size.
+     114             :   ASMJIT_INLINE uint32_t getBlockSize() const noexcept { return _blockSize; }
+     115             :   //! Get the default block alignment.
+     116        7796 :   ASMJIT_INLINE uint32_t getBlockAlignment() const noexcept { return (uint32_t)1 << _blockAlignmentShift; }
+     117             :   //! Get remaining size of the current block.
+     118             :   ASMJIT_INLINE size_t getRemainingSize() const noexcept { return (size_t)(_end - _ptr); }
+     119             : 
+     120             :   //! Get the current zone cursor (dangerous).
+     121             :   //!
+     122             :   //! This is a function that can be used to get exclusive access to the current
+     123             :   //! block's memory buffer.
+     124       78290 :   ASMJIT_INLINE uint8_t* getCursor() noexcept { return _ptr; }
+     125             :   //! Get the end of the current zone block, only useful if you use `getCursor()`.
+     126       78290 :   ASMJIT_INLINE uint8_t* getEnd() noexcept { return _end; }
+     127             : 
+     128             :   //! Set the current zone cursor to `p` (must match the current block).
+     129             :   //!
+     130             :   //! This is a counterpart of `getZoneCursor()`.
+     131             :   ASMJIT_INLINE void setCursor(uint8_t* p) noexcept {
+     132             :     ASMJIT_ASSERT(p >= _ptr && p <= _end);
+     133       74394 :     _ptr = p;
+     134           0 :   }
+     135             : 
+     136             :   // --------------------------------------------------------------------------
+     137             :   // [Alloc]
+     138             :   // --------------------------------------------------------------------------
+     139             : 
+     140             :   //! Allocate `size` bytes of memory.
+     141             :   //!
+     142             :   //! Pointer returned is valid until the `Zone` instance is destroyed or reset
+     143             :   //! by calling `reset()`. If you plan to make an instance of C++ from the
+     144             :   //! given pointer use placement `new` and `delete` operators:
+     145             :   //!
+     146             :   //! ~~~
+     147             :   //! using namespace asmjit;
+     148             :   //!
+     149             :   //! class Object { ... };
+     150             :   //!
+     151             :   //! // Create Zone with default block size of approximately 65536 bytes.
+     152             :   //! Zone zone(65536 - Zone::kZoneOverhead);
+     153             :   //!
+     154             :   //! // Create your objects using zone object allocating, for example:
+     155             :   //! Object* obj = static_cast<Object*>( zone.alloc(sizeof(Object)) );
+     156             :   //
+     157             :   //! if (!obj) {
+     158             :   //!   // Handle out of memory error.
+     159             :   //! }
+     160             :   //!
+     161             :   //! // Placement `new` and `delete` operators can be used to instantiate it.
+     162             :   //! new(obj) Object();
+     163             :   //!
+     164             :   //! // ... lifetime of your objects ...
+     165             :   //!
+     166             :   //! // To destroy the instance (if required).
+     167             :   //! obj->~Object();
+     168             :   //!
+     169             :   //! // Reset or destroy `Zone`.
+     170             :   //! zone.reset();
+     171             :   //! ~~~
+     172             :   ASMJIT_INLINE void* alloc(size_t size) noexcept {
+     173      114832 :     uint8_t* ptr = _ptr;
+     174      114832 :     size_t remainingBytes = (size_t)(_end - ptr);
+     175             : 
+     176      114832 :     if (ASMJIT_UNLIKELY(remainingBytes < size))
+     177        3900 :       return _alloc(size);
+     178             : 
+     179      110932 :     _ptr += size;
+     180             :     ASMJIT_ASSERT(_ptr <= _end);
+     181             : 
+     182      110932 :     return static_cast<void*>(ptr);
+     183             :   }
+     184             : 
+     185             :   //! Allocate `size` bytes without any checks.
+     186             :   //!
+     187             :   //! Can only be called if `getRemainingSize()` returns size at least equal
+     188             :   //! to `size`.
+     189             :   ASMJIT_INLINE void* allocNoCheck(size_t size) noexcept {
+     190             :     ASMJIT_ASSERT((size_t)(_end - _ptr) >= size);
+     191             : 
+     192             :     uint8_t* ptr = _ptr;
+     193             :     _ptr += size;
+     194             :     return static_cast<void*>(ptr);
+     195             :   }
+     196             : 
+     197             :   //! Allocate `size` bytes of zeroed memory.
+     198             :   //!
+     199             :   //! See \ref alloc() for more details.
+     200             :   ASMJIT_API void* allocZeroed(size_t size) noexcept;
+     201             : 
+     202             :   //! Like `alloc()`, but the return pointer is casted to `T*`.
+     203             :   template<typename T>
+     204             :   ASMJIT_INLINE T* allocT(size_t size = sizeof(T)) noexcept {
+     205             :     return static_cast<T*>(alloc(size));
+     206             :   }
+     207             : 
+     208             :   //! Like `allocNoCheck()`, but the return pointer is casted to `T*`.
+     209             :   template<typename T>
+     210             :   ASMJIT_INLINE T* allocNoCheckT(size_t size = sizeof(T)) noexcept {
+     211             :     return static_cast<T*>(allocNoCheck(size));
+     212             :   }
+     213             : 
+     214             :   //! Like `allocZeroed()`, but the return pointer is casted to `T*`.
+     215             :   template<typename T>
+     216             :   ASMJIT_INLINE T* allocZeroedT(size_t size = sizeof(T)) noexcept {
+     217       25736 :     return static_cast<T*>(allocZeroed(size));
+     218             :   }
+     219             : 
+     220             :   //! Like `new(std::nothrow) T(...)`, but allocated by `Zone`.
+     221             :   template<typename T>
+     222             :   ASMJIT_INLINE T* newT() noexcept {
+     223             :     void* p = alloc(sizeof(T));
+     224             :     if (ASMJIT_UNLIKELY(!p))
+     225             :       return nullptr;
+     226             :     return new(p) T();
+     227             :   }
+     228             :   //! Like `new(std::nothrow) T(...)`, but allocated by `Zone`.
+     229             :   template<typename T, typename P1>
+     230             :   ASMJIT_INLINE T* newT(P1 p1) noexcept {
+     231             :     void* p = alloc(sizeof(T));
+     232             :     if (ASMJIT_UNLIKELY(!p))
+     233             :       return nullptr;
+     234             :     return new(p) T(p1);
+     235             :   }
+     236             : 
+     237             :   //! \internal
+     238             :   ASMJIT_API void* _alloc(size_t size) noexcept;
+     239             : 
+     240             :   //! Helper to duplicate data.
+     241             :   ASMJIT_API void* dup(const void* data, size_t size, bool nullTerminate = false) noexcept;
+     242             : 
+     243             :   //! Helper to duplicate formatted string, maximum length is 256 bytes.
+     244             :   ASMJIT_API char* sformat(const char* str, ...) noexcept;
+     245             : 
+     246             :   // --------------------------------------------------------------------------
+     247             :   // [Members]
+     248             :   // --------------------------------------------------------------------------
+     249             : 
+     250             :   uint8_t* _ptr;                         //!< Pointer in the current block's buffer.
+     251             :   uint8_t* _end;                         //!< End of the current block's buffer.
+     252             :   Block* _block;                         //!< Current block.
+     253             : 
+     254             : #if ASMJIT_ARCH_64BIT
+     255             :   uint32_t _blockSize;                   //!< Default size of a newly allocated block.
+     256             :   uint32_t _blockAlignmentShift;         //!< Minimum alignment of each block.
+     257             : #else
+     258             :   uint32_t _blockSize : 29;              //!< Default size of a newly allocated block.
+     259             :   uint32_t _blockAlignmentShift : 3;     //!< Minimum alignment of each block.
+     260             : #endif
+     261             : };
+     262             : 
+     263             : // ============================================================================
+     264             : // [asmjit::ZoneHeap]
+     265             : // ============================================================================
+     266             : 
+     267             : //! Zone-based memory allocator that uses an existing \ref Zone and provides
+     268             : //! a `release()` functionality on top of it. It uses \ref Zone only for chunks
+     269             : //! that can be pooled, and uses libc `malloc()` for chunks that are large.
+     270             : //!
+     271             : //! The advantage of ZoneHeap is that it can allocate small chunks of memory
+     272             : //! really fast, and these chunks, when released, will be reused by consecutive
+     273             : //! calls to `alloc()`. Also, since ZoneHeap uses \ref Zone, you can turn any
+     274             : //! \ref Zone into a \ref ZoneHeap, and use it in your \ref Pass when necessary.
+     275             : //!
+     276             : //! ZoneHeap is used by AsmJit containers to make containers having only
+     277             : //! few elements fast (and lightweight) and to allow them to grow and use
+     278             : //! dynamic blocks when require more storage.
+     279             : class ZoneHeap {
+     280             :   ASMJIT_NONCOPYABLE(ZoneHeap)
+     281             : 
+     282             :   enum {
+     283             :     // In short, we pool chunks of these sizes:
+     284             :     //   [32, 64, 96, 128, 192, 256, 320, 384, 448, 512]
+     285             : 
+     286             :     //! How many bytes per a low granularity pool (has to be at least 16).
+     287             :     kLoGranularity = 32,
+     288             :     //! Number of slots of a low granularity pool.
+     289             :     kLoCount = 4,
+     290             :     //! Maximum size of a block that can be allocated in a low granularity pool.
+     291             :     kLoMaxSize = kLoGranularity * kLoCount,
+     292             : 
+     293             :     //! How many bytes per a high granularity pool.
+     294             :     kHiGranularity = 64,
+     295             :     //! Number of slots of a high granularity pool.
+     296             :     kHiCount = 6,
+     297             :     //! Maximum size of a block that can be allocated in a high granularity pool.
+     298             :     kHiMaxSize = kLoMaxSize + kHiGranularity * kHiCount,
+     299             : 
+     300             :     //! Alignment of every pointer returned by `alloc()`.
+     301             :     kBlockAlignment = kLoGranularity
+     302             :   };
+     303             : 
+     304             :   //! Single-linked list used to store unused chunks.
+     305             :   struct Slot {
+     306             :     //! Link to a next slot in a single-linked list.
+     307             :     Slot* next;
+     308             :   };
+     309             : 
+     310             :   //! A block of memory that has been allocated dynamically and is not part of
+     311             :   //! block-list used by the allocator. This is used to keep track of all these
+     312             :   //! blocks so they can be freed by `reset()` if not freed explicitly.
+     313             :   struct DynamicBlock {
+     314             :     DynamicBlock* prev;
+     315             :     DynamicBlock* next;
+     316             :   };
+     317             : 
+     318             :   // --------------------------------------------------------------------------
+     319             :   // [Construction / Destruction]
+     320             :   // --------------------------------------------------------------------------
+     321             : 
+     322             :   //! Create a new `ZoneHeap`.
+     323             :   //!
+     324             :   //! NOTE: To use it, you must first `init()` it.
+     325        1948 :   ASMJIT_INLINE ZoneHeap() noexcept {
+     326             :     ::memset(this, 0, sizeof(*this));
+     327             :   }
+     328             :   //! Create a new `ZoneHeap` initialized to use `zone`.
+     329        3896 :   explicit ASMJIT_INLINE ZoneHeap(Zone* zone) noexcept {
+     330             :     ::memset(this, 0, sizeof(*this));
+     331        3896 :     _zone = zone;
+     332             :   }
+     333             :   //! Destroy the `ZoneHeap`.
+     334        3896 :   ASMJIT_INLINE ~ZoneHeap() noexcept { reset(); }
+     335             : 
+     336             :   // --------------------------------------------------------------------------
+     337             :   // [Init / Reset]
+     338             :   // --------------------------------------------------------------------------
+     339             : 
+     340             :   //! Get if the `ZoneHeap` is initialized (i.e. has `Zone`).
+     341             :   ASMJIT_INLINE bool isInitialized() const noexcept { return _zone != nullptr; }
+     342             : 
+     343             :   //! Convenience method to initialize the `ZoneHeap` with `zone`.
+     344             :   //!
+     345             :   //! It's the same as calling `reset(zone)`.
+     346             :   ASMJIT_INLINE void init(Zone* zone) noexcept { reset(zone); }
+     347             : 
+     348             :   //! Reset this `ZoneHeap` and also forget about the current `Zone` which
+     349             :   //! is attached (if any). Reset optionally attaches a new `zone` passed, or
+     350             :   //! keeps the `ZoneHeap` in an uninitialized state, if `zone` is null.
+     351             :   ASMJIT_API void reset(Zone* zone = nullptr) noexcept;
+     352             : 
+     353             :   // --------------------------------------------------------------------------
+     354             :   // [Accessors]
+     355             :   // --------------------------------------------------------------------------
+     356             : 
+     357             :   //! Get the `Zone` the `ZoneHeap` is using, or null if it's not initialized.
+     358             :   ASMJIT_INLINE Zone* getZone() const noexcept { return _zone; }
+     359             : 
+     360             :   // --------------------------------------------------------------------------
+     361             :   // [Utilities]
+     362             :   // --------------------------------------------------------------------------
+     363             : 
+     364             :   //! \internal
+     365             :   //!
+     366             :   //! Get the slot index to be used for `size`. Returns `true` if a valid slot
+     367             :   //! has been written to `slot` and `allocatedSize` has been filled with slot
+     368             :   //! exact size (`allocatedSize` can be equal or slightly greater than `size`).
+     369             :   static ASMJIT_INLINE bool _getSlotIndex(size_t size, uint32_t& slot) noexcept {
+     370             :     ASMJIT_ASSERT(size > 0);
+     371        6600 :     if (size > kHiMaxSize)
+     372             :       return false;
+     373             : 
+     374        6600 :     if (size <= kLoMaxSize)
+     375        6592 :       slot = static_cast<uint32_t>((size - 1) / kLoGranularity);
+     376             :     else
+     377           8 :       slot = static_cast<uint32_t>((size - kLoMaxSize - 1) / kHiGranularity) + kLoCount;
+     378             : 
+     379             :     return true;
+     380             :   }
+     381             : 
+     382             :   //! \overload
+     383             :   static ASMJIT_INLINE bool _getSlotIndex(size_t size, uint32_t& slot, size_t& allocatedSize) noexcept {
+     384             :     ASMJIT_ASSERT(size > 0);
+     385       79986 :     if (size > kHiMaxSize)
+     386             :       return false;
+     387             : 
+     388       79978 :     if (size <= kLoMaxSize) {
+     389       75158 :       slot = static_cast<uint32_t>((size - 1) / kLoGranularity);
+     390       75158 :       allocatedSize = Utils::alignTo(size, kLoGranularity);
+     391             :     }
+     392             :     else {
+     393        4820 :       slot = static_cast<uint32_t>((size - kLoMaxSize - 1) / kHiGranularity) + kLoCount;
+     394        4820 :       allocatedSize = Utils::alignTo(size, kHiGranularity);
+     395             :     }
+     396             : 
+     397             :     return true;
+     398             :   }
+     399             : 
+     400             :   // --------------------------------------------------------------------------
+     401             :   // [Alloc / Release]
+     402             :   // --------------------------------------------------------------------------
+     403             : 
+     404             :   ASMJIT_API void* _alloc(size_t size, size_t& allocatedSize) noexcept;
+     405             :   ASMJIT_API void* _allocZeroed(size_t size, size_t& allocatedSize) noexcept;
+     406             :   ASMJIT_API void _releaseDynamic(void* p, size_t size) noexcept;
+     407             : 
+     408             :   //! Allocate `size` bytes of memory, ideally from an available pool.
+     409             :   //!
+     410             :   //! NOTE: `size` can't be zero, it will assert in debug mode in such case.
+     411             :   ASMJIT_INLINE void* alloc(size_t size) noexcept {
+     412             :     ASMJIT_ASSERT(isInitialized());
+     413             :     size_t allocatedSize;
+     414       57802 :     return _alloc(size, allocatedSize);
+     415             :   }
+     416             : 
+     417             :   //! Like `alloc(size)`, but provides a second argument `allocatedSize` that
+     418             :   //! provides a way to know how big the block returned actually is. This is
+     419             :   //! useful for containers to prevent growing too early.
+     420             :   ASMJIT_INLINE void* alloc(size_t size, size_t& allocatedSize) noexcept {
+     421             :     ASMJIT_ASSERT(isInitialized());
+     422       18288 :     return _alloc(size, allocatedSize);
+     423             :   }
+     424             : 
+     425             :   //! Like `alloc()`, but the return pointer is casted to `T*`.
+     426             :   template<typename T>
+     427             :   ASMJIT_INLINE T* allocT(size_t size = sizeof(T)) noexcept {
+     428             :     return static_cast<T*>(alloc(size));
+     429             :   }
+     430             : 
+     431             :   //! Like `alloc(size)`, but returns zeroed memory.
+     432             :   ASMJIT_INLINE void* allocZeroed(size_t size) noexcept {
+     433             :     ASMJIT_ASSERT(isInitialized());
+     434             : 
+     435             :     size_t allocatedSize;
+     436        3896 :     return _allocZeroed(size, allocatedSize);
+     437             :   }
+     438             : 
+     439             :   //! Like `alloc(size, allocatedSize)`, but returns zeroed memory.
+     440             :   ASMJIT_INLINE void* allocZeroed(size_t size, size_t& allocatedSize) noexcept {
+     441             :     ASMJIT_ASSERT(isInitialized());
+     442             : 
+     443             :     return _allocZeroed(size, allocatedSize);
+     444             :   }
+     445             : 
+     446             :   //! Like `allocZeroed()`, but the return pointer is casted to `T*`.
+     447             :   template<typename T>
+     448             :   ASMJIT_INLINE T* allocZeroedT(size_t size = sizeof(T)) noexcept {
+     449             :     return static_cast<T*>(allocZeroed(size));
+     450             :   }
+     451             : 
+     452             :   //! Release the memory previously allocated by `alloc()`. The `size` argument
+     453             :   //! has to be the same as used to call `alloc()` or `allocatedSize` returned
+     454             :   //! by `alloc()`.
+     455             :   ASMJIT_INLINE void release(void* p, size_t size) noexcept {
+     456             :     ASMJIT_ASSERT(isInitialized());
+     457             : 
+     458             :     ASMJIT_ASSERT(p != nullptr);
+     459             :     ASMJIT_ASSERT(size != 0);
+     460             : 
+     461             :     uint32_t slot;
+     462             :     if (_getSlotIndex(size, slot)) {
+     463             :       //printf("RELEASING %p of size %d (SLOT %u)\n", p, int(size), slot);
+     464        6600 :       static_cast<Slot*>(p)->next = static_cast<Slot*>(_slots[slot]);
+     465        6600 :       _slots[slot] = static_cast<Slot*>(p);
+     466             :     }
+     467             :     else {
+     468           0 :       _releaseDynamic(p, size);
+     469             :     }
+     470             :   }
+     471             : 
+     472             :   // --------------------------------------------------------------------------
+     473             :   // [Members]
+     474             :   // --------------------------------------------------------------------------
+     475             : 
+     476             :   Zone* _zone;                           //!< Zone used to allocate memory that fits into slots.
+     477             :   Slot* _slots[kLoCount + kHiCount];     //!< Indexed slots containing released memory.
+     478             :   DynamicBlock* _dynamicBlocks;          //!< Dynamic blocks for larger allocations (no slots).
+     479             : };
+     480             : 
+     481             : // ============================================================================
+     482             : // [asmjit::ZoneList<T>]
+     483             : // ============================================================================
+     484             : 
+     485             : //! \internal
+     486             : template <typename T>
+     487             : class ZoneList {
+     488             : public:
+     489             :   ASMJIT_NONCOPYABLE(ZoneList<T>)
+     490             : 
+     491             :   // --------------------------------------------------------------------------
+     492             :   // [Link]
+     493             :   // --------------------------------------------------------------------------
+     494             : 
+     495             :   //! ZoneList node.
+     496             :   struct Link {
+     497             :     //! Get next node.
+     498        3896 :     ASMJIT_INLINE Link* getNext() const noexcept { return _next; }
+     499             :     //! Get value.
+     500        1948 :     ASMJIT_INLINE T getValue() const noexcept { return _value; }
+     501             :     //! Set value to `value`.
+     502        3896 :     ASMJIT_INLINE void setValue(const T& value) noexcept { _value = value; }
+     503             : 
+     504             :     Link* _next;
+     505             :     T _value;
+     506             :   };
+     507             : 
+     508             :   // --------------------------------------------------------------------------
+     509             :   // [Appender]
+     510             :   // --------------------------------------------------------------------------
+     511             : 
+     512             :   //! Specialized appender that takes advantage of ZoneList structure. You must
+     513             :   //! initialize it and then call done().
+     514             :   struct Appender {
+     515             :     ASMJIT_INLINE Appender(ZoneList<T>& list) noexcept { init(list); }
+     516             : 
+     517             :     ASMJIT_INLINE void init(ZoneList<T>& list) noexcept {
+     518             :       pPrev = &list._first;
+     519             :     }
+     520             : 
+     521             :     ASMJIT_INLINE void done(ZoneList<T>& list) noexcept {
+     522             :       list._last = *pPrev;
+     523             :       *pPrev = nullptr;
+     524             :     }
+     525             : 
+     526             :     ASMJIT_INLINE void append(Link* node) noexcept {
+     527             :       *pPrev = node;
+     528             :       pPrev = &node->_next;
+     529             :     }
+     530             : 
+     531             :     Link** pPrev;
+     532             :   };
+     533             : 
+     534             :   // --------------------------------------------------------------------------
+     535             :   // [Construction / Destruction]
+     536             :   // --------------------------------------------------------------------------
+     537             : 
+     538        1948 :   ASMJIT_INLINE ZoneList() noexcept : _first(nullptr), _last(nullptr) {}
+     539           0 :   ASMJIT_INLINE ~ZoneList() noexcept {}
+     540             : 
+     541             :   // --------------------------------------------------------------------------
+     542             :   // [Data]
+     543             :   // --------------------------------------------------------------------------
+     544             : 
+     545             :   ASMJIT_INLINE bool isEmpty() const noexcept { return _first != nullptr; }
+     546        7792 :   ASMJIT_INLINE Link* getFirst() const noexcept { return _first; }
+     547             :   ASMJIT_INLINE Link* getLast() const noexcept { return _last; }
+     548             : 
+     549             :   // --------------------------------------------------------------------------
+     550             :   // [Ops]
+     551             :   // --------------------------------------------------------------------------
+     552             : 
+     553             :   ASMJIT_INLINE void reset() noexcept {
+     554        1948 :     _first = nullptr;
+     555        1948 :     _last = nullptr;
+     556             :   }
+     557             : 
+     558             :   ASMJIT_INLINE void prepend(Link* link) noexcept {
+     559             :     link->_next = _first;
+     560             :     if (!_first) _last = link;
+     561             :     _first = link;
+     562             :   }
+     563             : 
+     564             :   ASMJIT_INLINE void append(Link* link) noexcept {
+     565        3896 :     link->_next = nullptr;
+     566        3896 :     if (!_first)
+     567        3896 :       _first = link;
+     568             :     else
+     569           0 :       _last->_next = link;
+     570        3896 :     _last = link;
+     571             :   }
+     572             : 
+     573             :   // --------------------------------------------------------------------------
+     574             :   // [Members]
+     575             :   // --------------------------------------------------------------------------
+     576             : 
+     577             :   Link* _first;
+     578             :   Link* _last;
+     579             : };
+     580             : 
+     581             : // ============================================================================
+     582             : // [asmjit::ZoneVectorBase]
+     583             : // ============================================================================
+     584             : 
+     585             : //! \internal
+     586             : class ZoneVectorBase {
+     587             : public:
+     588             :   ASMJIT_NONCOPYABLE(ZoneVectorBase)
+     589             : 
+     590             : protected:
+     591             :   // --------------------------------------------------------------------------
+     592             :   // [Construction / Destruction]
+     593             :   // --------------------------------------------------------------------------
+     594             : 
+     595             :   //! Create a new instance of `ZoneVectorBase`.
+     596             :   explicit ASMJIT_INLINE ZoneVectorBase() noexcept
+     597        7792 :     : _data(nullptr),
+     598        7792 :       _length(0),
+     599        7792 :       _capacity(0) {}
+     600             : 
+     601             :   // --------------------------------------------------------------------------
+     602             :   // [Accessors]
+     603             :   // --------------------------------------------------------------------------
+     604             : 
+     605             : public:
+     606             :   //! Get if the vector is empty.
+     607             :   ASMJIT_INLINE bool isEmpty() const noexcept { return _length == 0; }
+     608             :   //! Get vector length.
+     609       73412 :   ASMJIT_INLINE size_t getLength() const noexcept { return _length; }
+     610             :   //! Get vector capacity.
+     611             :   ASMJIT_INLINE size_t getCapacity() const noexcept { return _capacity; }
+     612             : 
+     613             :   // --------------------------------------------------------------------------
+     614             :   // [Ops]
+     615             :   // --------------------------------------------------------------------------
+     616             : 
+     617             :   //! Makes the vector empty (won't change the capacity or data pointer).
+     618             :   ASMJIT_INLINE void clear() noexcept { _length = 0; }
+     619             :   //! Reset the vector data and set its `length` to zero.
+     620             :   ASMJIT_INLINE void reset() noexcept {
+     621        5844 :     _data = nullptr;
+     622        5844 :     _length = 0;
+     623        5844 :     _capacity = 0;
+     624             :   }
+     625             : 
+     626             :   //! Truncate the vector to at most `n` items.
+     627             :   ASMJIT_INLINE void truncate(size_t n) noexcept {
+     628             :     _length = std::min(_length, n);
+     629             :   }
+     630             : 
+     631             :   // --------------------------------------------------------------------------
+     632             :   // [Memory Management]
+     633             :   // --------------------------------------------------------------------------
+     634             : 
+     635             : protected:
+     636             :   ASMJIT_INLINE void _release(ZoneHeap* heap, size_t sizeOfT) noexcept {
+     637             :     if (_data != nullptr) {
+     638             :       heap->release(_data, _capacity * sizeOfT);
+     639             :       reset();
+     640             :     }
+     641             :   }
+     642             : 
+     643             :   ASMJIT_API Error _grow(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept;
+     644             :   ASMJIT_API Error _resize(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept;
+     645             :   ASMJIT_API Error _reserve(ZoneHeap* heap, size_t sizeOfT, size_t n) noexcept;
+     646             : 
+     647             :   // --------------------------------------------------------------------------
+     648             :   // [Members]
+     649             :   // --------------------------------------------------------------------------
+     650             : 
+     651             : public:
+     652             :   void* _data;                           //!< Vector data.
+     653             :   size_t _length;                        //!< Length of the vector.
+     654             :   size_t _capacity;                      //!< Capacity of the vector.
+     655             : };
+     656             : 
+     657             : // ============================================================================
+     658             : // [asmjit::ZoneVector<T>]
+     659             : // ============================================================================
+     660             : 
+     661             : //! Template used to store and manage array of Zone allocated data.
+     662             : //!
+     663             : //! This template has these advantages over other std::vector<>:
+     664             : //! - Always non-copyable (designed to be non-copyable, we want it).
+     665             : //! - No copy-on-write (some implementations of STL can use it).
+     666             : //! - Optimized for working only with POD types.
+     667             : //! - Uses ZoneHeap, thus small vectors are basically for free.
+     668             : template <typename T>
+     669             : class ZoneVector : public ZoneVectorBase {
+     670             : public:
+     671             :   ASMJIT_NONCOPYABLE(ZoneVector<T>)
+     672             : 
+     673             :   // --------------------------------------------------------------------------
+     674             :   // [Construction / Destruction]
+     675             :   // --------------------------------------------------------------------------
+     676             : 
+     677             :   //! Create a new instance of `ZoneVector<T>`.
+     678             :   explicit ASMJIT_INLINE ZoneVector() noexcept : ZoneVectorBase() {}
+     679             : 
+     680             :   // --------------------------------------------------------------------------
+     681             :   // [Accessors]
+     682             :   // --------------------------------------------------------------------------
+     683             : 
+     684             :   //! Get data.
+     685       11688 :   ASMJIT_INLINE T* getData() noexcept { return static_cast<T*>(_data); }
+     686             :   //! \overload
+     687      136306 :   ASMJIT_INLINE const T* getData() const noexcept { return static_cast<const T*>(_data); }
+     688             : 
+     689             :   // --------------------------------------------------------------------------
+     690             :   // [Ops]
+     691             :   // --------------------------------------------------------------------------
+     692             : 
+     693             :   //! Prepend `item` to the vector.
+     694             :   Error prepend(ZoneHeap* heap, const T& item) noexcept {
+     695             :     if (ASMJIT_UNLIKELY(_length == _capacity))
+     696             :       ASMJIT_PROPAGATE(grow(heap, 1));
+     697             : 
+     698             :     ::memmove(static_cast<T*>(_data) + 1, _data, _length * sizeof(T));
+     699             :     ::memcpy(_data, &item, sizeof(T));
+     700             : 
+     701             :     _length++;
+     702             :     return kErrorOk;
+     703             :   }
+     704             : 
+     705             :   //! Insert an `item` at the specified `index`.
+     706             :   Error insert(ZoneHeap* heap, size_t index, const T& item) noexcept {
+     707             :     ASMJIT_ASSERT(index <= _length);
+     708             : 
+     709             :     if (ASMJIT_UNLIKELY(_length == _capacity))
+     710             :       ASMJIT_PROPAGATE(grow(heap, 1));
+     711             : 
+     712             :     T* dst = static_cast<T*>(_data) + index;
+     713             :     ::memmove(dst + 1, dst, _length - index);
+     714             :     ::memcpy(dst, &item, sizeof(T));
+     715             : 
+     716             :     _length++;
+     717             :     return kErrorOk;
+     718             :   }
+     719             : 
+     720             :   //! Append `item` to the vector.
+     721       25736 :   Error append(ZoneHeap* heap, const T& item) noexcept {
+     722       25736 :     if (ASMJIT_UNLIKELY(_length == _capacity))
+     723        5248 :       ASMJIT_PROPAGATE(grow(heap, 1));
+     724             : 
+     725       25736 :     ::memcpy(static_cast<T*>(_data) + _length, &item, sizeof(T));
+     726             : 
+     727       25736 :     _length++;
+     728       25736 :     return kErrorOk;
+     729             :   }
+     730             : 
+     731             :   Error concat(ZoneHeap* heap, const ZoneVector<T>& other) noexcept {
+     732             :     size_t count = other._length;
+     733             :     if (_capacity - _length < count)
+     734             :       ASMJIT_PROPAGATE(grow(heap, count));
+     735             : 
+     736             :     ::memcpy(static_cast<T*>(_data) + _length, other._data, count * sizeof(T));
+     737             : 
+     738             :     _length += count;
+     739             :     return kErrorOk;
+     740             :   }
+     741             : 
+     742             :   //! Prepend `item` to the vector (unsafe case).
+     743             :   //!
+     744             :   //! Can only be used together with `willGrow()`. If `willGrow(N)` returns
+     745             :   //! `kErrorOk` then N elements can be added to the vector without checking
+     746             :   //! if there is a place for them. Used mostly internally.
+     747             :   ASMJIT_INLINE void prependUnsafe(const T& item) noexcept {
+     748             :     ASMJIT_ASSERT(_length < _capacity);
+     749             :     T* data = static_cast<T*>(_data);
+     750             : 
+     751             :     if (_length)
+     752             :       ::memmove(data + 1, data, _length * sizeof(T));
+     753             : 
+     754             :     ::memcpy(data, &item, sizeof(T));
+     755             :     _length++;
+     756             :   }
+     757             : 
+     758             :   //! Append `item` to the vector (unsafe case).
+     759             :   //!
+     760             :   //! Can only be used together with `willGrow()`. If `willGrow(N)` returns
+     761             :   //! `kErrorOk` then N elements can be added to the vector without checking
+     762             :   //! if there is a place for them. Used mostly internally.
+     763             :   ASMJIT_INLINE void appendUnsafe(const T& item) noexcept {
+     764             :     ASMJIT_ASSERT(_length < _capacity);
+     765             : 
+     766       29632 :     ::memcpy(static_cast<T*>(_data) + _length, &item, sizeof(T));
+     767       27684 :     _length++;
+     768        1948 :   }
+     769             : 
+     770             :   //! Concatenate all items of `other` at the end of the vector.
+     771             :   ASMJIT_INLINE void concatUnsafe(const ZoneVector<T>& other) noexcept {
+     772             :     size_t count = other._length;
+     773             :     ASMJIT_ASSERT(_capacity - _length >= count);
+     774             : 
+     775             :     ::memcpy(static_cast<T*>(_data) + _length, other._data, count * sizeof(T));
+     776             :     _length += count;
+     777             :   }
+     778             : 
+     779             :   //! Get index of `val` or `kInvalidIndex` if not found.
+     780             :   ASMJIT_INLINE size_t indexOf(const T& val) const noexcept {
+     781           0 :     const T* data = static_cast<const T*>(_data);
+     782           0 :     size_t length = _length;
+     783             : 
+     784           0 :     for (size_t i = 0; i < length; i++)
+     785           0 :       if (data[i] == val)
+     786             :         return i;
+     787             : 
+     788             :     return Globals::kInvalidIndex;
+     789             :   }
+     790             : 
+     791             :   //! Get whether the vector contains `val`.
+     792             :   ASMJIT_INLINE bool contains(const T& val) const noexcept {
+     793             :     return indexOf(val) != Globals::kInvalidIndex;
+     794             :   }
+     795             : 
+     796             :   //! Remove item at index `i`.
+     797             :   ASMJIT_INLINE void removeAt(size_t i) noexcept {
+     798             :     ASMJIT_ASSERT(i < _length);
+     799             : 
+     800           0 :     T* data = static_cast<T*>(_data) + i;
+     801           0 :     _length--;
+     802           0 :     ::memmove(data, data + 1, _length - i);
+     803           0 :   }
+     804             : 
+     805             :   //! Swap this pod-vector with `other`.
+     806             :   ASMJIT_INLINE void swap(ZoneVector<T>& other) noexcept {
+     807             :     Utils::swap(_length, other._length);
+     808             :     Utils::swap(_capacity, other._capacity);
+     809             :     Utils::swap(_data, other._data);
+     810             :   }
+     811             : 
+     812             :   //! Get item at index `i` (const).
+     813             :   ASMJIT_INLINE const T& getAt(size_t i) const noexcept {
+     814             :     ASMJIT_ASSERT(i < _length);
+     815             :     return getData()[i];
+     816             :   }
+     817             : 
+     818             :   //! Get item at index `i`.
+     819             :   ASMJIT_INLINE T& operator[](size_t i) noexcept {
+     820             :     ASMJIT_ASSERT(i < _length);
+     821        7792 :     return getData()[i];
+     822             :   }
+     823             : 
+     824             :   //! Get item at index `i`.
+     825             :   ASMJIT_INLINE const T& operator[](size_t i) const noexcept {
+     826             :     ASMJIT_ASSERT(i < _length);
+     827      132410 :     return getData()[i];
+     828             :   }
+     829             : 
+     830             :   // --------------------------------------------------------------------------
+     831             :   // [Memory Management]
+     832             :   // --------------------------------------------------------------------------
+     833             : 
+     834             :   //! Release the memory held by `ZoneVector<T>` back to the `heap`.
+     835             :   ASMJIT_INLINE void release(ZoneHeap* heap) noexcept { _release(heap, sizeof(T)); }
+     836             : 
+     837             :   //! Called to grow the buffer to fit at least `n` elements more.
+     838       16340 :   ASMJIT_INLINE Error grow(ZoneHeap* heap, size_t n) noexcept { return ZoneVectorBase::_grow(heap, sizeof(T), n); }
+     839             : 
+     840             :   //! Resize the vector to hold `n` elements.
+     841             :   //!
+     842             :   //! If `n` is greater than the current length then the additional elements'
+     843             :   //! content will be initialized to zero. If `n` is less than the current
+     844             :   //! length then the vector will be truncated to exactly `n` elements.
+     845        3896 :   ASMJIT_INLINE Error resize(ZoneHeap* heap, size_t n) noexcept { return ZoneVectorBase::_resize(heap, sizeof(T), n); }
+     846             : 
+     847             :   //! Realloc internal array to fit at least `n` items.
+     848             :   ASMJIT_INLINE Error reserve(ZoneHeap* heap, size_t n) noexcept { return ZoneVectorBase::_reserve(heap, sizeof(T), n); }
+     849             : 
+     850             :   ASMJIT_INLINE Error willGrow(ZoneHeap* heap, size_t n = 1) noexcept {
+     851       31580 :     return _capacity - _length < n ? grow(heap, n) : static_cast<Error>(kErrorOk);
+     852             :   }
+     853             : };
+     854             : 
+     855             : // ============================================================================
+     856             : // [asmjit::ZoneBitVector]
+     857             : // ============================================================================
+     858             : 
+     859             : class ZoneBitVector {
+     860             : public:
+     861             :   ASMJIT_NONCOPYABLE(ZoneBitVector)
+     862             : 
+     863             :   //! Storage used to store a pack of bits (should by compatible with a machine word).
+     864             :   typedef uintptr_t BitWord;
+     865             :   enum { kBitsPerWord = static_cast<int>(sizeof(BitWord)) * 8 };
+     866             : 
+     867             :   static ASMJIT_INLINE size_t _wordsPerBits(size_t nBits) noexcept {
+     868           0 :     return ((nBits + kBitsPerWord) / kBitsPerWord) - 1;
+     869             :   }
+     870             : 
+     871             :   // Return all bits zero if 0 and all bits set if 1.
+     872             :   static ASMJIT_INLINE BitWord _patternFromBit(bool bit) noexcept {
+     873           0 :     BitWord bitAsWord = static_cast<BitWord>(bit);
+     874             :     ASMJIT_ASSERT(bitAsWord == 0 || bitAsWord == 1);
+     875           0 :     return static_cast<BitWord>(0) - bitAsWord;
+     876             :   }
+     877             : 
+     878             :   // --------------------------------------------------------------------------
+     879             :   // [Construction / Destruction]
+     880             :   // --------------------------------------------------------------------------
+     881             : 
+     882             :   explicit ASMJIT_INLINE ZoneBitVector() noexcept :
+     883             :     _data(nullptr),
+     884             :     _length(0),
+     885             :     _capacity(0) {}
+     886             : 
+     887             :   // --------------------------------------------------------------------------
+     888             :   // [Accessors]
+     889             :   // --------------------------------------------------------------------------
+     890             : 
+     891             :   //! Get if the bit-vector is empty (has no bits).
+     892             :   ASMJIT_INLINE bool isEmpty() const noexcept { return _length == 0; }
+     893             :   //! Get a length of this bit-vector (in bits).
+     894             :   ASMJIT_INLINE size_t getLength() const noexcept { return _length; }
+     895             :   //! Get a capacity of this bit-vector (in bits).
+     896             :   ASMJIT_INLINE size_t getCapacity() const noexcept { return _capacity; }
+     897             : 
+     898             :   //! Get data.
+     899             :   ASMJIT_INLINE BitWord* getData() noexcept { return _data; }
+     900             :   //! \overload
+     901             :   ASMJIT_INLINE const BitWord* getData() const noexcept { return _data; }
+     902             : 
+     903             :   // --------------------------------------------------------------------------
+     904             :   // [Ops]
+     905             :   // --------------------------------------------------------------------------
+     906             : 
+     907             :   ASMJIT_INLINE void clear() noexcept {
+     908             :     _length = 0;
+     909             :   }
+     910             : 
+     911             :   ASMJIT_INLINE void reset() noexcept {
+     912             :     _data = nullptr;
+     913             :     _length = 0;
+     914             :     _capacity = 0;
+     915             :   }
+     916             : 
+     917             :   ASMJIT_INLINE void truncate(size_t newLength) noexcept {
+     918             :     _length = std::min(_length, newLength);
+     919             :     _clearUnusedBits();
+     920             :   }
+     921             : 
+     922             :   ASMJIT_INLINE bool getAt(size_t index) const noexcept {
+     923             :     ASMJIT_ASSERT(index < _length);
+     924             : 
+     925             :     size_t idx = index / kBitsPerWord;
+     926             :     size_t bit = index % kBitsPerWord;
+     927             :     return static_cast<bool>((_data[idx] >> bit) & 1);
+     928             :   }
+     929             : 
+     930             :   ASMJIT_INLINE void setAt(size_t index, bool value) noexcept {
+     931             :     ASMJIT_ASSERT(index < _length);
+     932             : 
+     933             :     size_t idx = index / kBitsPerWord;
+     934             :     size_t bit = index % kBitsPerWord;
+     935             :     if (value)
+     936             :       _data[idx] |= static_cast<BitWord>(1) << bit;
+     937             :     else
+     938             :       _data[idx] &= ~(static_cast<BitWord>(1) << bit);
+     939             :   }
+     940             : 
+     941             :   ASMJIT_INLINE void toggleAt(size_t index) noexcept {
+     942             :     ASMJIT_ASSERT(index < _length);
+     943             : 
+     944             :     size_t idx = index / kBitsPerWord;
+     945             :     size_t bit = index % kBitsPerWord;
+     946             :     _data[idx] ^= static_cast<BitWord>(1) << bit;
+     947             :   }
+     948             : 
+     949             :   ASMJIT_INLINE Error append(ZoneHeap* heap, bool value) noexcept {
+     950             :     size_t index = _length;
+     951             :     if (ASMJIT_UNLIKELY(index >= _capacity))
+     952             :       return _append(heap, value);
+     953             : 
+     954             :     size_t idx = index / kBitsPerWord;
+     955             :     size_t bit = index % kBitsPerWord;
+     956             : 
+     957             :     if (bit == 0)
+     958             :       _data[idx] = static_cast<BitWord>(value) << bit;
+     959             :     else
+     960             :       _data[idx] |= static_cast<BitWord>(value) << bit;
+     961             : 
+     962             :     _length++;
+     963             :     return kErrorOk;
+     964             :   }
+     965             : 
+     966             :   ASMJIT_API Error fill(size_t fromIndex, size_t toIndex, bool value) noexcept;
+     967             : 
+     968             :   ASMJIT_INLINE void and_(const ZoneBitVector& other) noexcept {
+     969             :     BitWord* dst = _data;
+     970             :     const BitWord* src = other._data;
+     971             : 
+     972             :     size_t numWords = (std::min(_length, other._length) + kBitsPerWord - 1) / kBitsPerWord;
+     973             :     for (size_t i = 0; i < numWords; i++)
+     974             :       dst[i] = dst[i] & src[i];
+     975             :     _clearUnusedBits();
+     976             :   }
+     977             : 
+     978             :   ASMJIT_INLINE void andNot(const ZoneBitVector& other) noexcept {
+     979             :     BitWord* dst = _data;
+     980             :     const BitWord* src = other._data;
+     981             : 
+     982             :     size_t numWords = (std::min(_length, other._length) + kBitsPerWord - 1) / kBitsPerWord;
+     983             :     for (size_t i = 0; i < numWords; i++)
+     984             :       dst[i] = dst[i] & ~src[i];
+     985             :     _clearUnusedBits();
+     986             :   }
+     987             : 
+     988             :   ASMJIT_INLINE void or_(const ZoneBitVector& other) noexcept {
+     989             :     BitWord* dst = _data;
+     990             :     const BitWord* src = other._data;
+     991             : 
+     992             :     size_t numWords = (std::min(_length, other._length) + kBitsPerWord - 1) / kBitsPerWord;
+     993             :     for (size_t i = 0; i < numWords; i++)
+     994             :       dst[i] = dst[i] | src[i];
+     995             :     _clearUnusedBits();
+     996             :   }
+     997             : 
+     998             :   ASMJIT_INLINE void _clearUnusedBits() noexcept {
+     999             :     size_t idx = _length / kBitsPerWord;
+    1000             :     size_t bit = _length % kBitsPerWord;
+    1001             : 
+    1002             :     if (!bit) return;
+    1003             :     _data[idx] &= (static_cast<BitWord>(1) << bit) - 1U;
+    1004             :   }
+    1005             : 
+    1006             :   // --------------------------------------------------------------------------
+    1007             :   // [Memory Management]
+    1008             :   // --------------------------------------------------------------------------
+    1009             : 
+    1010             :   ASMJIT_INLINE void release(ZoneHeap* heap) noexcept {
+    1011             :     if (_data != nullptr) {
+    1012             :       heap->release(_data, _capacity / 8);
+    1013             :       reset();
+    1014             :     }
+    1015             :   }
+    1016             : 
+    1017             :   ASMJIT_INLINE Error resize(ZoneHeap* heap, size_t newLength, bool newBitsValue = false) noexcept {
+    1018             :     return _resize(heap, newLength, newLength, newBitsValue);
+    1019             :   }
+    1020             : 
+    1021             :   ASMJIT_API Error _resize(ZoneHeap* heap, size_t newLength, size_t idealCapacity, bool newBitsValue) noexcept;
+    1022             :   ASMJIT_API Error _append(ZoneHeap* heap, bool value) noexcept;
+    1023             : 
+    1024             :   // --------------------------------------------------------------------------
+    1025             :   // [Members]
+    1026             :   // --------------------------------------------------------------------------
+    1027             : 
+    1028             :   BitWord* _data;                        //!< Bits.
+    1029             :   size_t _length;                        //!< Length of the bit-vector (in bits).
+    1030             :   size_t _capacity;                      //!< Capacity of the bit-vector (in bits).
+    1031             : };
+    1032             : 
+    1033             : // ============================================================================
+    1034             : // [asmjit::ZoneHashNode]
+    1035             : // ============================================================================
+    1036             : 
+    1037             : //! Node used by \ref ZoneHash<> template.
+    1038             : //!
+    1039             : //! You must provide function `bool eq(const Key& key)` in order to make
+    1040             : //! `ZoneHash::get()` working.
+    1041             : class ZoneHashNode {
+    1042             : public:
+    1043             :   ASMJIT_INLINE ZoneHashNode(uint32_t hVal = 0) noexcept
+    1044             :     : _hashNext(nullptr),
+    1045             :       _hVal(hVal) {}
+    1046             : 
+    1047             :   //! Next node in the chain, null if it terminates the chain.
+    1048             :   ZoneHashNode* _hashNext;
+    1049             :   //! Key hash.
+    1050             :   uint32_t _hVal;
+    1051             :   //! Should be used by Node that inherits ZoneHashNode, it aligns ZoneHashNode.
+    1052             :   uint32_t _customData;
+    1053             : };
+    1054             : 
+    1055             : // ============================================================================
+    1056             : // [asmjit::ZoneHashBase]
+    1057             : // ============================================================================
+    1058             : 
+    1059             : class ZoneHashBase {
+    1060             : public:
+    1061             :   ASMJIT_NONCOPYABLE(ZoneHashBase)
+    1062             : 
+    1063             :   // --------------------------------------------------------------------------
+    1064             :   // [Construction / Destruction]
+    1065             :   // --------------------------------------------------------------------------
+    1066             : 
+    1067        1948 :   ASMJIT_INLINE ZoneHashBase(ZoneHeap* heap) noexcept {
+    1068        1948 :     _heap = heap;
+    1069        1948 :     _size = 0;
+    1070        1948 :     _bucketsCount = 1;
+    1071        1948 :     _bucketsGrow = 1;
+    1072        1948 :     _data = _embedded;
+    1073        1948 :     _embedded[0] = nullptr;
+    1074             :   }
+    1075        1948 :   ASMJIT_INLINE ~ZoneHashBase() noexcept { reset(nullptr); }
+    1076             : 
+    1077             :   // --------------------------------------------------------------------------
+    1078             :   // [Reset]
+    1079             :   // --------------------------------------------------------------------------
+    1080             : 
+    1081             :   ASMJIT_INLINE bool isInitialized() const noexcept { return _heap != nullptr; }
+    1082             :   ASMJIT_API void reset(ZoneHeap* heap) noexcept;
+    1083             : 
+    1084             :   // --------------------------------------------------------------------------
+    1085             :   // [Accessors]
+    1086             :   // --------------------------------------------------------------------------
+    1087             : 
+    1088             :   //! Get a `ZoneHeap` attached to this container.
+    1089             :   ASMJIT_INLINE ZoneHeap* getHeap() const noexcept { return _heap; }
+    1090             : 
+    1091             :   ASMJIT_INLINE size_t getSize() const noexcept { return _size; }
+    1092             : 
+    1093             :   // --------------------------------------------------------------------------
+    1094             :   // [Ops]
+    1095             :   // --------------------------------------------------------------------------
+    1096             : 
+    1097             :   ASMJIT_API void _rehash(uint32_t newCount) noexcept;
+    1098             :   ASMJIT_API ZoneHashNode* _put(ZoneHashNode* node) noexcept;
+    1099             :   ASMJIT_API ZoneHashNode* _del(ZoneHashNode* node) noexcept;
+    1100             : 
+    1101             :   // --------------------------------------------------------------------------
+    1102             :   // [Members]
+    1103             :   // --------------------------------------------------------------------------
+    1104             : 
+    1105             :   ZoneHeap* _heap;                       //!< ZoneHeap used to allocate data.
+    1106             :   size_t _size;                          //!< Count of records inserted into the hash table.
+    1107             :   uint32_t _bucketsCount;                //!< Count of hash buckets.
+    1108             :   uint32_t _bucketsGrow;                 //!< When buckets array should grow.
+    1109             : 
+    1110             :   ZoneHashNode** _data;                  //!< Buckets data.
+    1111             :   ZoneHashNode* _embedded[1];            //!< Embedded data, used by empty hash tables.
+    1112             : };
+    1113             : 
+    1114             : // ============================================================================
+    1115             : // [asmjit::ZoneHash<Key, Node>]
+    1116             : // ============================================================================
+    1117             : 
+    1118             : //! Low-level hash table specialized for storing string keys and POD values.
+    1119             : //!
+    1120             : //! This hash table allows duplicates to be inserted (the API is so low
+    1121             : //! level that it's up to you if you allow it or not, as you should first
+    1122             : //! `get()` the node and then modify it or insert a new node by using `put()`,
+    1123             : //! depending on the intention).
+    1124             : template<typename Node>
+    1125             : class ZoneHash : public ZoneHashBase {
+    1126             : public:
+    1127             :   explicit ASMJIT_INLINE ZoneHash(ZoneHeap* heap = nullptr) noexcept
+    1128             :     : ZoneHashBase(heap) {}
+    1129        1948 :   ASMJIT_INLINE ~ZoneHash() noexcept {}
+    1130             : 
+    1131             :   template<typename Key>
+    1132             :   ASMJIT_INLINE Node* get(const Key& key) const noexcept {
+    1133           0 :     uint32_t hMod = key.hVal % _bucketsCount;
+    1134           0 :     Node* node = static_cast<Node*>(_data[hMod]);
+    1135             : 
+    1136           0 :     while (node && !key.matches(node))
+    1137           0 :       node = static_cast<Node*>(node->_hashNext);
+    1138             :     return node;
+    1139             :   }
+    1140             : 
+    1141           0 :   ASMJIT_INLINE Node* put(Node* node) noexcept { return static_cast<Node*>(_put(node)); }
+    1142             :   ASMJIT_INLINE Node* del(Node* node) noexcept { return static_cast<Node*>(_del(node)); }
+    1143             : };
+    1144             : 
+    1145             : //! \}
+    1146             : 
+    1147             : } // asmjit namespace
+    1148             : } // namespace PLMD
+    1149             : 
+    1150             : // [Api-End]
+    1151             : #include "./asmjit_apiend.h"
+    1152             : 
+    1153             : // [Guard]
+    1154             : #endif // _ASMJIT_BASE_ZONE_H
+    1155             : #pragma GCC diagnostic pop
+    1156             : #endif // __PLUMED_HAS_ASMJIT
+    1157             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/blas.cpp.func-sort-c.html b/coverage-libs/blas/blas.cpp.func-sort-c.html new file mode 100644 index 000000000000..4b74c1c4a3c8 --- /dev/null +++ b/coverage-libs/blas/blas.cpp.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas/blas.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blas - blas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:405160525.2 %
Date:2024-02-22 21:58:47Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4blas5sger_EPiS1_PfS2_S1_S2_S1_S2_S1_0
_ZN4PLMD4blas5srot_EPiPfS1_S2_S1_S2_S2_0
_ZN4PLMD4blas6dasum_EPiPdS1_0
_ZN4PLMD4blas6dtrsm_EPKcS2_S2_S2_PiS3_PdS4_S3_S4_S3_0
_ZN4PLMD4blas6sasum_EPiPfS1_0
_ZN4PLMD4blas6saxpy_EPiPfS2_S1_S2_S1_0
_ZN4PLMD4blas6scopy_EPiPfS1_S2_S1_0
_ZN4PLMD4blas6sgemm_EPKcS2_PiS3_S3_PfS4_S3_S4_S3_S4_S4_S3_0
_ZN4PLMD4blas6sgemv_EPKcPiS3_PfS4_S3_S4_S3_S4_S4_S3_0
_ZN4PLMD4blas6snrm2_EPiPfS1_0
_ZN4PLMD4blas6sscal_EPiPfS2_S1_0
_ZN4PLMD4blas6sswap_EPiPfS1_S2_S1_0
_ZN4PLMD4blas6ssymv_EPKcPiPfS4_S3_S4_S3_S4_S4_S3_0
_ZN4PLMD4blas6ssyr2_EPKcPiPfS4_S3_S4_S3_S4_S3_0
_ZN4PLMD4blas6strmm_EPKcS2_S2_S2_PiS3_PfS4_S3_S4_S3_0
_ZN4PLMD4blas6strmv_EPKcS2_S2_PiPfS3_S4_S3_0
_ZN4PLMD4blas6strsm_EPKcS2_S2_S2_PiS3_PfS4_S3_S4_S3_0
_ZN4PLMD4blas7isamax_EPiPfS1_0
_ZN4PLMD4blas7ssyr2k_EPKcS2_PiS3_PfS4_S3_S4_S3_S4_S4_S3_0
_ZN4PLMD4blas5sdot_EPiPfS1_S2_S1_1
_ZN4PLMD4blas7dsyr2k_EPKcS2_PiS3_PdS4_S3_S4_S3_S4_S4_S3_19
_ZN4PLMD4blas7idamax_EPiPdS1_114
_ZN4PLMD4blas5drot_EPiPdS1_S2_S1_S2_S2_360
_ZN4PLMD4blas6dtrmm_EPKcS2_S2_S2_PiS3_PdS4_S3_S4_S3_441
_ZN4PLMD4blas6dgemm_EPKcS2_PiS3_S3_PdS4_S3_S4_S3_S4_S4_S3_520
_ZN4PLMD4blas6dtrmv_EPKcS2_S2_PiPdS3_S4_S3_3624
_ZN4PLMD4blas6dswap_EPiPdS1_S2_S1_5884
_ZN4PLMD4blas6dsyr2_EPKcPiPdS4_S3_S4_S3_S4_S3_1113894
_ZN4PLMD4blas6daxpy_EPiPdS2_S1_S2_S1_1114407
_ZN4PLMD4blas6dsymv_EPKcPiPdS4_S3_S4_S3_S4_S4_S3_1114407
_ZN4PLMD4blas5ddot_EPiPdS1_S2_S1_1114408
_ZN4PLMD4blas5dger_EPiS1_PdS2_S1_S2_S1_S2_S1_1119684
_ZN4PLMD4blas6dnrm2_EPiPdS1_1125770
_ZN4PLMD4blas6dgemv_EPKcPiS3_PdS4_S3_S4_S3_S4_S4_S3_1131534
_ZN4PLMD4blas6dscal_EPiPdS2_S1_1728053
_ZN4PLMD4blas6dcopy_EPiPdS1_S2_S1_4000743
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/blas.cpp.func.html b/coverage-libs/blas/blas.cpp.func.html new file mode 100644 index 000000000000..c0c16bf349da --- /dev/null +++ b/coverage-libs/blas/blas.cpp.func.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas/blas.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blas - blas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:405160525.2 %
Date:2024-02-22 21:58:47Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4blas5ddot_EPiPdS1_S2_S1_1114408
_ZN4PLMD4blas5dger_EPiS1_PdS2_S1_S2_S1_S2_S1_1119684
_ZN4PLMD4blas5drot_EPiPdS1_S2_S1_S2_S2_360
_ZN4PLMD4blas5sdot_EPiPfS1_S2_S1_1
_ZN4PLMD4blas5sger_EPiS1_PfS2_S1_S2_S1_S2_S1_0
_ZN4PLMD4blas5srot_EPiPfS1_S2_S1_S2_S2_0
_ZN4PLMD4blas6dasum_EPiPdS1_0
_ZN4PLMD4blas6daxpy_EPiPdS2_S1_S2_S1_1114407
_ZN4PLMD4blas6dcopy_EPiPdS1_S2_S1_4000743
_ZN4PLMD4blas6dgemm_EPKcS2_PiS3_S3_PdS4_S3_S4_S3_S4_S4_S3_520
_ZN4PLMD4blas6dgemv_EPKcPiS3_PdS4_S3_S4_S3_S4_S4_S3_1131534
_ZN4PLMD4blas6dnrm2_EPiPdS1_1125770
_ZN4PLMD4blas6dscal_EPiPdS2_S1_1728053
_ZN4PLMD4blas6dswap_EPiPdS1_S2_S1_5884
_ZN4PLMD4blas6dsymv_EPKcPiPdS4_S3_S4_S3_S4_S4_S3_1114407
_ZN4PLMD4blas6dsyr2_EPKcPiPdS4_S3_S4_S3_S4_S3_1113894
_ZN4PLMD4blas6dtrmm_EPKcS2_S2_S2_PiS3_PdS4_S3_S4_S3_441
_ZN4PLMD4blas6dtrmv_EPKcS2_S2_PiPdS3_S4_S3_3624
_ZN4PLMD4blas6dtrsm_EPKcS2_S2_S2_PiS3_PdS4_S3_S4_S3_0
_ZN4PLMD4blas6sasum_EPiPfS1_0
_ZN4PLMD4blas6saxpy_EPiPfS2_S1_S2_S1_0
_ZN4PLMD4blas6scopy_EPiPfS1_S2_S1_0
_ZN4PLMD4blas6sgemm_EPKcS2_PiS3_S3_PfS4_S3_S4_S3_S4_S4_S3_0
_ZN4PLMD4blas6sgemv_EPKcPiS3_PfS4_S3_S4_S3_S4_S4_S3_0
_ZN4PLMD4blas6snrm2_EPiPfS1_0
_ZN4PLMD4blas6sscal_EPiPfS2_S1_0
_ZN4PLMD4blas6sswap_EPiPfS1_S2_S1_0
_ZN4PLMD4blas6ssymv_EPKcPiPfS4_S3_S4_S3_S4_S4_S3_0
_ZN4PLMD4blas6ssyr2_EPKcPiPfS4_S3_S4_S3_S4_S3_0
_ZN4PLMD4blas6strmm_EPKcS2_S2_S2_PiS3_PfS4_S3_S4_S3_0
_ZN4PLMD4blas6strmv_EPKcS2_S2_PiPfS3_S4_S3_0
_ZN4PLMD4blas6strsm_EPKcS2_S2_S2_PiS3_PfS4_S3_S4_S3_0
_ZN4PLMD4blas7dsyr2k_EPKcS2_PiS3_PdS4_S3_S4_S3_S4_S4_S3_19
_ZN4PLMD4blas7idamax_EPiPdS1_114
_ZN4PLMD4blas7isamax_EPiPfS1_0
_ZN4PLMD4blas7ssyr2k_EPKcS2_PiS3_PfS4_S3_S4_S3_S4_S4_S3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/blas.cpp.gcov.html b/coverage-libs/blas/blas.cpp.gcov.html new file mode 100644 index 000000000000..09b4a18cb3ec --- /dev/null +++ b/coverage-libs/blas/blas.cpp.gcov.html @@ -0,0 +1,3767 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas/blas.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blas - blas.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:405160525.2 %
Date:2024-02-22 21:58:47Functions:173647.2 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : These files are semi-automatic translations by f2c from the original netlib BLAS library.
+       3             : The source has been modified to (mostly) use modern C formatting, and to get rid of
+       4             : compiler warnings. Any errors in doing this should be blamed on the GROMACS developers, and
+       5             : not the reference BLAS implementation.
+       6             : 
+       7             : The reference BLAS implementation is available from http://www.netlib.org/blas 
+       8             : 
+       9             : BLAS does not come with a formal named "license", but a general statement that 
+      10             : 
+      11             : "The reference BLAS is a freely-available software package. It is available from netlib
+      12             : via anonymous ftp and the World Wide Web. Thus, it can be included in commercial software
+      13             : packages (and has been). We only ask that proper credit be given to the authors."
+      14             : 
+      15             : While the rest of GROMACS is LGPL, we think it's only fair to give you the same rights to
+      16             : our modified BLAS files as the original netlib versions, so do what you want with them.
+      17             : However, be warned that we have only tested that they to the right thing in the cases used
+      18             : in GROMACS (primarily full & sparse matrix diagonalization), so in most cases it is a much
+      19             : better idea to use the full reference implementation.
+      20             : 
+      21             : Erik Lindahl, 2008-10-07.
+      22             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      23             : #if ! defined (__PLUMED_HAS_EXTERNAL_BLAS)
+      24             : #include <cmath>
+      25             : #include "blas.h"
+      26             : 
+      27             : namespace PLMD{
+      28             : namespace blas{
+      29             : double
+      30           0 : PLUMED_BLAS_F77_FUNC(dasum,DASUM)(int *n__, 
+      31             :                       double *dx, 
+      32             :                       int *incx__)
+      33             : {
+      34             :     int i__1, i__2;
+      35             :     
+      36             :     int i__, m, mp1;
+      37             :     double dtemp;
+      38             :     int nincx;
+      39             :     
+      40           0 :     int n = *n__;
+      41           0 :     int incx = *incx__;
+      42             :     
+      43           0 :     --dx;
+      44             :     
+      45             :     dtemp = 0.;
+      46           0 :     if (n <= 0 || incx <= 0) {
+      47             :         return 0.0;
+      48             :     }
+      49           0 :     if (incx != 1) {
+      50           0 :         nincx = n * incx;
+      51             :         i__1 = nincx;
+      52             :         i__2 = incx;
+      53           0 :         for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+      54           0 :             dtemp += std::abs(dx[i__]);
+      55             :         }
+      56             :         return dtemp;
+      57             :     }
+      58             :     
+      59           0 :     m = n % 6;
+      60           0 :     if (m != 0) {
+      61             :         i__2 = m;
+      62           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+      63           0 :             dtemp += std::abs(dx[i__]);
+      64             :         }
+      65           0 :         if (n < 6) {
+      66             :             return dtemp;
+      67             :         }
+      68             :     }
+      69           0 :     mp1 = m + 1;
+      70             :     i__2 = n;
+      71           0 :     for (i__ = mp1; i__ <= i__2; i__ += 6) {
+      72           0 :         dtemp = dtemp + std::abs(dx[i__]) + std::abs(dx[i__ + 1]) + 
+      73           0 :         std::abs(dx[i__ + 2]) + std::abs(dx[i__+ 3]) + std::abs(dx[i__ + 4]) +
+      74           0 :         std::abs(dx[i__ + 5]);
+      75             :     }
+      76             :     return dtemp;
+      77             : }
+      78             : 
+      79             : 
+      80             : }
+      81             : }
+      82             : #include "blas.h"
+      83             : 
+      84             : 
+      85             : namespace PLMD{
+      86             : namespace blas{
+      87             : void
+      88     1114407 : PLUMED_BLAS_F77_FUNC(daxpy,DAXPY)(int   *   n_arg,
+      89             :                       double *   da_arg,
+      90             :                       double *   dx,
+      91             :                       int *      incx_arg,
+      92             :                       double *   dy,
+      93             :                       int *      incy_arg)
+      94             : {
+      95             :   int i,ix,iy;
+      96     1114407 :   int n=*n_arg;
+      97     1114407 :   double da=*da_arg;
+      98     1114407 :   int incx = *incx_arg;
+      99     1114407 :   int incy = *incy_arg;
+     100             : 
+     101     1114407 :   if (n<=0)
+     102             :     return;
+     103             : 
+     104     1114407 :   if(incx!=1 || incy!=1) {
+     105             :     ix = 0;
+     106             :     iy = 0;
+     107           0 :     if(incx<0)
+     108           0 :       ix = (1-n)*incx;
+     109           0 :     if(incy<0)
+     110           0 :       iy = (1-n)*incy;
+     111             :     
+     112           0 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) 
+     113           0 :       dy[iy] += da*dx[ix];
+     114             : 
+     115             :     return;
+     116             : 
+     117             :   } else {
+     118             : 
+     119             :     /* unroll */
+     120             :     
+     121     1162444 :     for(i=0;i<(n-4);i+=4) {
+     122       48037 :       dy[i]   += da*dx[i];
+     123       48037 :       dy[i+1] += da*dx[i+1];
+     124       48037 :       dy[i+2] += da*dx[i+2];
+     125       48037 :       dy[i+3] += da*dx[i+3];
+     126             :     }
+     127             :     /* continue with current value of i */
+     128     3900113 :     for(;i<n;i++)
+     129     2785706 :       dy[i]   += da*dx[i];
+     130             :   }
+     131             : }
+     132             : }
+     133             : }
+     134             : #include "blas.h"
+     135             : 
+     136             : namespace PLMD{
+     137             : namespace blas{
+     138             : void
+     139     4000743 : PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(int *n__,
+     140             :                       double *dx,
+     141             :                       int *incx__,
+     142             :                       double *dy,
+     143             :                       int *incy__)
+     144             : {
+     145             :     int i,ix,iy;
+     146             : 
+     147     4000743 :     int n= *n__;
+     148     4000743 :     int incx = *incx__;
+     149     4000743 :     int incy = *incy__;
+     150             :     
+     151             : 
+     152     4000743 :     if(incx!=1 || incy!=1) {
+     153             :         ix = 0;
+     154             :         iy = 0;
+     155        6132 :         if(incx<0)
+     156           0 :             ix = (1-n)*(incx);
+     157        6132 :         if(incy<0)
+     158           0 :             iy = (1-n)*(incy);
+     159             :         
+     160     1183902 :         for(i=0;i<n;i++,ix+=incx,iy+=incy) 
+     161     1177770 :             dy[iy] = dx[ix];
+     162             :         
+     163             :         return;
+     164             :         
+     165             :     } else {
+     166             :         
+     167             :         /* unroll */
+     168             :         
+     169     4101524 :         for(i=0;i<(n-8);i+=8) {
+     170      106913 :             dy[i]   = dx[i];
+     171      106913 :             dy[i+1] = dx[i+1];
+     172      106913 :             dy[i+2] = dx[i+2];
+     173      106913 :             dy[i+3] = dx[i+3];
+     174      106913 :             dy[i+4] = dx[i+4];
+     175      106913 :             dy[i+5] = dx[i+5];
+     176      106913 :             dy[i+6] = dx[i+6];
+     177      106913 :             dy[i+7] = dx[i+7];
+     178             :         }
+     179             :         /* continue with current value of i */
+     180    16426561 :         for(;i<n;i++)
+     181    12431950 :             dy[i] = dx[i];
+     182             :     }
+     183             : }
+     184             : }
+     185             : }
+     186             : #include "blas.h"
+     187             : 
+     188             : namespace PLMD{
+     189             : namespace blas{
+     190             : double
+     191     1114408 : PLUMED_BLAS_F77_FUNC(ddot,DDOT)(int *n_arg,
+     192             :                     double *dx,
+     193             :                     int *incx_arg,
+     194             :                     double *dy,
+     195             :                     int *incy_arg)
+     196             : {
+     197             :     int i,ix,iy,m;
+     198     1114408 :     int n=*n_arg;
+     199     1114408 :     int incx = *incx_arg;
+     200     1114408 :     int incy = *incy_arg;
+     201             :     double t1;
+     202             :     
+     203     1114408 :     if(n<=0)
+     204             :         return 0.0;
+     205             :     
+     206             :     t1 = 0.0;
+     207             :     
+     208     1114408 :     if(incx!=1 || incy!=1) {
+     209             :         ix = 0;
+     210             :         iy = 0;
+     211           0 :         if(incx<0)
+     212           0 :             ix = (1-n)*incx;
+     213           0 :         if(incy<0)
+     214           0 :             iy = (1-n)*incy;
+     215             :         
+     216           0 :         for(i=0;i<n;i++,ix+=incx,iy+=incy) 
+     217           0 :             t1 += dx[ix] * dy[iy];
+     218             :         
+     219             :         return t1;
+     220             :         
+     221             :     } else {
+     222             :         
+     223     1114408 :         m = n%5;
+     224             :         
+     225     3899267 :         for(i=0;i<m;i++)
+     226     2784859 :             t1 += dx[i] * dy[i];
+     227             :         
+     228             :         /* unroll */
+     229     1153008 :         for(i=m;i<n;i+=5) 
+     230       38600 :             t1  =  t1 + dx[i] * dy[i]   
+     231       38600 :                 +    dx[i+1] * dy[i+1] 
+     232       38600 :                 +    dx[i+2] * dy[i+2] 
+     233       38600 :                 +    dx[i+3] * dy[i+3]   
+     234       38600 :                 +    dx[i+4] * dy[i+4];   
+     235             :         
+     236             :         return t1;
+     237             :     }
+     238             : }
+     239             : 
+     240             :  
+     241             : }
+     242             : }
+     243             : #include <cctype>
+     244             : #include <cmath>
+     245             : 
+     246             : #include "real.h"
+     247             : 
+     248             : #include "blas.h"
+     249             : 
+     250             : namespace PLMD{
+     251             : namespace blas{
+     252             : void
+     253         520 : PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)(const char *transa,
+     254             :                       const char *transb,
+     255             :                       int *m__,
+     256             :                       int *n__,
+     257             :                       int *k__,
+     258             :                       double *alpha__,
+     259             :                       double *a,
+     260             :                       int *lda__,
+     261             :                       double *b,
+     262             :                       int *ldb__,
+     263             :                       double *beta__,
+     264             :                       double *c,
+     265             :                       int *ldc__)
+     266             : {
+     267         520 :   const char tra=std::toupper(*transa);
+     268         520 :   const char trb=std::toupper(*transb);
+     269             :   double temp;
+     270             :   int i,j,l;
+     271             : 
+     272         520 :   int m = *m__;
+     273         520 :   int n = *n__;
+     274         520 :   int k = *k__;
+     275         520 :   int lda = *lda__;
+     276         520 :   int ldb = *ldb__;
+     277         520 :   int ldc = *ldc__;
+     278             :   
+     279         520 :   double alpha = *alpha__;
+     280         520 :   double beta  = *beta__;
+     281             :   
+     282         520 :   if(m==0 || n==0 || (( std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN || k==0) && std::abs(beta-1.0)<PLUMED_GMX_DOUBLE_EPS))
+     283             :     return;
+     284             : 
+     285         471 :   if(std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN) {
+     286           0 :     if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN) {
+     287           0 :       for(j=0;j<n;j++)
+     288           0 :         for(i=0;i<m;i++)
+     289           0 :           c[j*(ldc)+i] = 0.0;
+     290             :     } else {
+     291             :       /* nonzero beta */
+     292           0 :       for(j=0;j<n;j++)
+     293           0 :         for(i=0;i<m;i++)
+     294           0 :           c[j*(ldc)+i] *= beta;
+     295             :     }
+     296           0 :     return;
+     297             :   }
+     298             : 
+     299         471 :   if(trb=='N') {
+     300         354 :     if(tra=='N') {
+     301             :       
+     302       17396 :       for(j=0;j<n;j++) {
+     303       17120 :         if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN) {
+     304      934292 :           for(i=0;i<m;i++)
+     305      924369 :             c[j*(ldc)+i] = 0.0;
+     306        7197 :         } else if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+     307           0 :           for(i=0;i<m;i++)
+     308           0 :             c[j*(ldc)+i] *= beta;
+     309             :         } 
+     310      898860 :         for(l=0;l<k;l++) {
+     311      881740 :           if( std::abs(b[ j*(ldb) + l ])>PLUMED_GMX_DOUBLE_MIN) {
+     312      879210 :             temp = alpha * b[ j*(ldb) + l ];
+     313   223022936 :             for(i=0;i<m;i++)
+     314   222143726 :               c[j*(ldc)+i] += temp * a[l*(lda)+i]; 
+     315             :           }
+     316             :         }
+     317             :       }
+     318             :     } else {
+     319             :       /* transpose A, but not B */
+     320        2290 :       for(j=0;j<n;j++) {
+     321      599172 :         for(i=0;i<m;i++) {
+     322             :           temp = 0.0;
+     323   126807456 :           for(l=0;l<k;l++) 
+     324   126210496 :             temp += a[i*(lda)+l] * b[j*(ldb)+l];
+     325      596960 :           if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN)
+     326           0 :             c[j*(ldc)+i] = alpha * temp;
+     327             :           else
+     328      596960 :             c[j*(ldc)+i] = alpha * temp + beta * c[j*(ldc)+i];
+     329             :         }
+     330             :       }
+     331             :     }
+     332             :   } else {
+     333             :     /* transpose B */
+     334         117 :     if(tra=='N') {
+     335             : 
+     336             :       /* transpose B, but not A */
+     337             : 
+     338       24143 :       for(j=0;j<n;j++) {
+     339       24026 :         if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN) {
+     340           0 :           for(i=0;i<m;i++)
+     341           0 :             c[j*(ldc)+i] = 0.0;
+     342       24026 :         } else if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+     343           0 :           for(i=0;i<m;i++)
+     344           0 :             c[j*(ldc)+i] *= beta;
+     345             :         } 
+     346      851290 :         for(l=0;l<k;l++) {
+     347      827264 :           if( std::abs(b[ l*(ldb) + j ])>PLUMED_GMX_DOUBLE_MIN) {
+     348      714770 :             temp = alpha * b[ l*(ldb) + j ];
+     349   208051270 :             for(i=0;i<m;i++)
+     350   207336500 :               c[j*(ldc)+i] += temp * a[l*(lda)+i]; 
+     351             :           }
+     352             :         }
+     353             :       }
+     354             :  
+     355             :     } else {
+     356             :       /* Transpose both A and B */
+     357           0 :        for(j=0;j<n;j++) {
+     358           0 :         for(i=0;i<m;i++) {
+     359             :           temp = 0.0;
+     360           0 :           for(l=0;l<k;l++) 
+     361           0 :             temp += a[i*(lda)+l] * b[l*(ldb)+j];
+     362           0 :           if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN)
+     363           0 :             c[j*(ldc)+i] = alpha * temp;
+     364             :           else
+     365           0 :             c[j*(ldc)+i] = alpha * temp + beta * c[j*(ldc)+i];
+     366             :         }
+     367             :        }
+     368             :     }
+     369             :   }
+     370             : }
+     371             : }
+     372             : }
+     373             : #include <cctype>
+     374             : #include <cmath>
+     375             : 
+     376             : #include "real.h"
+     377             : 
+     378             : #include "blas.h"
+     379             : 
+     380             : namespace PLMD{
+     381             : namespace blas{
+     382             : void
+     383     1131534 : PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)(const char *trans, 
+     384             :        int *m__,
+     385             :        int *n__,
+     386             :        double *alpha__,
+     387             :        double *a,
+     388             :        int *lda__,
+     389             :        double *x,
+     390             :        int *incx__,
+     391             :        double *beta__,
+     392             :        double *y,
+     393             :        int *incy__)
+     394             : {
+     395     1131534 :   const char ch=std::toupper(*trans);
+     396             :   int lenx,leny,kx,ky;
+     397             :   int i,j,jx,jy,ix,iy;
+     398             :   double temp;
+     399             : 
+     400     1131534 :   int m = *m__;
+     401     1131534 :   int n = *n__;
+     402     1131534 :   double alpha = *alpha__;
+     403     1131534 :   double beta = *beta__;
+     404     1131534 :   int incx = *incx__;
+     405     1131534 :   int incy = *incy__;
+     406     1131534 :   int lda = *lda__;
+     407             :   
+     408     1131534 :   if(n<=0 || m<=0 || (std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN && std::abs(beta-1.0)<PLUMED_GMX_DOUBLE_EPS))
+     409             :     return;
+     410             : 
+     411     1131342 :   if(ch=='N') {
+     412             :     lenx = n;
+     413             :     leny = m;
+     414             :   } else {
+     415             :     lenx = m;
+     416             :     leny = n;
+     417             :   }
+     418             :   
+     419     1131342 :    if(incx>0)
+     420             :     kx = 1;
+     421             :   else
+     422           0 :     kx = 1 - (lenx -1)*(incx);
+     423             : 
+     424     1131342 :   if(incy>0)
+     425             :     ky = 1;
+     426             :   else
+     427           0 :     ky = 1 - (leny -1)*(incy);
+     428             :  
+     429     1131342 :   if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+     430     1126309 :     if(incy==1) {
+     431     1126309 :       if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN)
+     432     2736407 :         for(i=0;i<leny;i++)
+     433     1610098 :           y[i] = 0.0;
+     434             :       else
+     435           0 :         for(i=0;i<leny;i++)
+     436           0 :           y[i] *= beta;
+     437             :     } else {
+     438             :       /* non-unit incr. */
+     439             :       iy = ky;
+     440           0 :       if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN) 
+     441           0 :         for(i=0;i<leny;i++,iy+=incy)
+     442           0 :           y[iy] = 0.0;
+     443             :       else
+     444           0 :         for(i=0;i<leny;i++,iy+=incy)
+     445           0 :           y[iy] *= beta;
+     446             :     }
+     447             :   }
+     448             :   
+     449     1131342 :   if(std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN)
+     450             :     return;
+     451             :   
+     452     1131342 :   if(ch=='N') {
+     453             :     jx = kx;
+     454        9325 :     if(incy==1) {
+     455      474392 :       for(j=1;j<=n;j++,jx+=incx) 
+     456      465451 :         if(std::abs(x[jx-1])>PLUMED_GMX_DOUBLE_MIN) {
+     457      465451 :           temp = alpha * x[jx-1];
+     458    63040550 :           for(i=1;i<=m;i++)
+     459    62575099 :             y[i-1] += temp * a[(j-1)*(lda)+(i-1)];
+     460             :         }
+     461             :     } else {
+     462             :       /* non-unit y incr. */
+     463        6720 :       for(j=1;j<=n;j++,jx+=incx) 
+     464        6336 :         if(std::abs(x[jx-1])>PLUMED_GMX_DOUBLE_MIN) {
+     465        6336 :           temp = alpha * x[jx-1];
+     466             :           iy = ky;
+     467     1921920 :           for(i=1;i<=m;i++,iy+=incy)
+     468     1915584 :             y[iy-1] += temp * a[(j-1)*(lda)+(i-1)];
+     469             :         }
+     470             :     }
+     471             :   } else {
+     472             :     /* transpose */
+     473             :     jy = ky;
+     474     1122017 :     if(incx==1) {
+     475     2638111 :       for(j=1;j<=n;j++,jy+=incy) {
+     476             :         temp = 0.0;
+     477    60769782 :         for(i=1;i<=m;i++)
+     478    59252932 :           temp += a[(j-1)*(lda)+(i-1)] * x[i-1];
+     479     1516850 :         y[jy-1] += alpha * temp;
+     480             :       }
+     481             :     } else {
+     482             :       /* non-unit y incr. */
+     483      121296 :       for(j=1;j<=n;j++,jy+=incy) {
+     484             :         temp = 0.0;
+     485             :         ix = kx;
+     486     3833628 :         for(i=1;i<=m;i++,ix+=incx)
+     487     3713088 :           temp += a[(j-1)*(lda)+(i-1)] * x[ix-1];
+     488      120540 :         y[jy-1] += alpha * temp;
+     489             :       }
+     490             :     }
+     491             :   }
+     492             : } 
+     493             :    
+     494             : }
+     495             : }
+     496             : #include <cmath>
+     497             : 
+     498             : #include "real.h"
+     499             : 
+     500             : #include "blas.h"
+     501             : 
+     502             : namespace PLMD{
+     503             : namespace blas{
+     504             : void
+     505     1119684 : PLUMED_BLAS_F77_FUNC(dger,DGER)(int *m__,
+     506             :                     int *n__,
+     507             :                     double *alpha__,
+     508             :                     double *x,
+     509             :                     int *incx__,
+     510             :                     double *y,
+     511             :                     int *incy__,
+     512             :                     double *a,
+     513             :                     int *lda__)
+     514             : {
+     515             :     int ix,kx,jy;
+     516             :     int i,j;
+     517             :     double temp;
+     518             :     
+     519             :     
+     520     1119684 :     int m = *m__;
+     521     1119684 :     int n = *n__;
+     522     1119684 :     int incx = *incx__;
+     523     1119684 :     int incy = *incy__;
+     524     1119684 :     int lda = *lda__;
+     525     1119684 :     double alpha = *alpha__;
+     526             :     
+     527     1119684 :     if(m<=0 || n<=0 || std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN)
+     528             :         return;
+     529             :     
+     530     1119684 :     if(incy>0)
+     531             :         jy = 0;
+     532             :     else
+     533           0 :         jy = incy * (1 - n);
+     534             :     
+     535     1119684 :     if(incx==1) {
+     536     2387895 :         for(j=0;j<n;j++,jy+=incy)
+     537     1268211 :             if(std::abs(y[jy])>PLUMED_GMX_DOUBLE_MIN) {
+     538     1268203 :                 temp = alpha * y[jy];
+     539     6935836 :                 for(i=0;i<m;i++)
+     540     5667633 :                     a[j*(lda)+i] += temp*x[i];
+     541             :             }
+     542             :     } else {
+     543             :         /* non-unit incx */
+     544           0 :         if(incx>0) 
+     545             :             kx = 0;
+     546             :         else
+     547           0 :             kx = incx * (1 - m);
+     548             :         
+     549           0 :         for(j=0;j<n;j++,jy+=incy) {
+     550           0 :             if(std::abs(y[jy])>PLUMED_GMX_DOUBLE_MIN) {
+     551           0 :                 temp = alpha * y[jy];
+     552             :                 ix = kx;
+     553           0 :                 for(i=0;i<m;i++,ix+=incx)
+     554           0 :                     a[j*(lda)+i] += temp*x[ix];
+     555             :             }
+     556             :         }
+     557             :     }
+     558             :         return;
+     559             : }
+     560             : }
+     561             : }
+     562             : #include <cmath>
+     563             : 
+     564             : #include "real.h"
+     565             : #include "blas.h"
+     566             : 
+     567             : namespace PLMD{
+     568             : namespace blas{
+     569             : double
+     570     1125770 : PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(int  *     n__,
+     571             :                       double *    x,
+     572             :                       int    *    incx__)
+     573             : {
+     574             :     int ix,max_ix;
+     575             :     double ssq,scale,absxi,t;
+     576             :     
+     577     1125770 :     int n = *n__;
+     578     1125770 :     int incx = *incx__;
+     579             :     
+     580     1125770 :     if(n<1 || incx<1)
+     581             :         return 0;
+     582     1125770 :     else if (n==1) {
+     583      556838 :         t = x[0];
+     584      556838 :         if(t>=0)
+     585             :             return t;
+     586             :         else 
+     587      417149 :             return -t;
+     588             :     }
+     589             :     
+     590             :     scale = 0.0;
+     591             :     ssq   = 1.0;
+     592             :     
+     593      568932 :     max_ix = 1+(n-1)*(incx);
+     594     3017075 :     for(ix=1;ix<=max_ix;ix+=incx) {
+     595     2448143 :         t = x[ix-1];
+     596     2448143 :         if(std::abs(t)>PLUMED_GMX_DOUBLE_MIN) {
+     597     2447161 :             absxi = (t>=0) ? t : (-t);
+     598     2447161 :             if(scale<absxi) {
+     599      823385 :                 t = scale/absxi;
+     600      823385 :                 t = t*t;
+     601      823385 :                 ssq = ssq*t + 1.0;
+     602             :                 scale = absxi;
+     603             :             } else {
+     604     1623776 :                 t = absxi/scale;
+     605     1623776 :                 ssq += t*t;
+     606             :             }
+     607             :         }
+     608             :     }
+     609      568932 :     return scale*std::sqrt(ssq);
+     610             :     
+     611             : }
+     612             : 
+     613             : 
+     614             :  
+     615             : }
+     616             : }
+     617             : #include "blas.h"
+     618             : 
+     619             : namespace PLMD{
+     620             : namespace blas{
+     621             : void
+     622         360 : PLUMED_BLAS_F77_FUNC(drot,DROT)(int *n__,
+     623             :       double *dx,
+     624             :       int *incx__,
+     625             :       double *dy,
+     626             :       int *incy__,
+     627             :       double *c__,
+     628             :       double *s__)
+     629             : {
+     630             :   int i,ix,iy;
+     631             :   double dtemp;
+     632             : 
+     633         360 :   int n = *n__;
+     634         360 :   int incx = *incx__;
+     635         360 :   int incy = *incy__;
+     636         360 :   double c = *c__;
+     637         360 :   double s = *s__;
+     638             :   
+     639         360 :   if(incx!=1 || incy!=1) {
+     640             :     ix = 0;
+     641             :     iy = 0;
+     642         180 :     if(incx<0)
+     643           0 :       ix = (1-n)*(incx);
+     644         180 :     if(incy<0)
+     645           0 :       iy = (1-n)*(incy);
+     646             :     
+     647        3136 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) {
+     648        2956 :       dtemp  = (c) * dx[ix] + (s) * dy[iy];
+     649        2956 :       dy[iy] = (c) * dy[iy] - (s) * dx[ix];
+     650        2956 :       dx[ix] = dtemp;
+     651             :     }
+     652             : 
+     653             :     return;
+     654             : 
+     655             :   } else {
+     656             : 
+     657             :     /* unit increments */   
+     658        3075 :     for(i=0;i<n;i++) {
+     659        2895 :       dtemp = (c) * dx[i] + (s) * dy[i];
+     660        2895 :       dy[i] = (c) * dy[i] - (s) * dx[i];
+     661        2895 :       dx[i] = dtemp;      
+     662             :     }
+     663             : 
+     664             :   }
+     665             : }
+     666             : }
+     667             : }
+     668             : #include "blas.h"
+     669             : 
+     670             : namespace PLMD{
+     671             : namespace blas{
+     672             : void 
+     673     1728053 : PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(int  *    n__,
+     674             :                       double *   fact__,
+     675             :                       double *   dx,
+     676             :                       int    *   incx__)
+     677             : {
+     678             :     int nincx,i;
+     679             : 
+     680     1728053 :     int n = *n__;
+     681     1728053 :     double fact = *fact__;
+     682     1728053 :     int incx = *incx__;
+     683             :     
+     684     1728053 :     if(n<=0 || incx<=0)
+     685             :         return;
+     686             :     
+     687     1727996 :     if(incx==1) {
+     688             :         /* Unrool factor 5 */
+     689     1912115 :         for(i=0;i<(n-5);i+=5) {
+     690      187002 :             dx[i]   *= fact;
+     691      187002 :             dx[i+1] *= fact;
+     692      187002 :             dx[i+2] *= fact;
+     693      187002 :             dx[i+3] *= fact;
+     694      187002 :             dx[i+4] *= fact;
+     695             :         }    
+     696             :         /* continue with current value of i */
+     697     5781769 :         for(;i<n;i++)
+     698     4056656 :             dx[i]   *= fact;
+     699             :         
+     700             :         return;
+     701             :     } else {
+     702             :         /* inc != 1 */
+     703        2883 :         nincx = n * (incx);
+     704      159270 :         for (i=0;i<nincx;i+=incx)
+     705      156387 :             dx[i] *= fact;
+     706             :         
+     707             :         return;
+     708             :     } 
+     709             :     
+     710             : }
+     711             : }
+     712             : }
+     713             : #include "blas.h"
+     714             : 
+     715             : namespace PLMD{
+     716             : namespace blas{
+     717             : void
+     718        5884 : PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(int *n__,
+     719             :                       double *dx,
+     720             :                       int *incx__,
+     721             :                       double *dy,
+     722             :                       int *incy__)
+     723             : {
+     724             :   int i,ix,iy;
+     725             :   double d1,d2,d3;
+     726             : 
+     727        5884 :   int n = *n__;
+     728        5884 :   int incx = *incx__;
+     729        5884 :   int incy = *incy__;
+     730             :   
+     731        5884 :   if(n<=0)
+     732             :     return;
+     733             : 
+     734        5884 :   if(incx==1 && incy==1) {
+     735       85127 :     for(i=0;i<(n-3);i+=3) {
+     736       81866 :       d1      = dx[i];
+     737       81866 :       d2      = dx[i+1];
+     738       81866 :       d3      = dx[i+2];
+     739       81866 :       dx[i]   = dy[i];
+     740       81866 :       dx[i+1] = dy[i+1];
+     741       81866 :       dx[i+2] = dy[i+2];
+     742       81866 :       dy[i]   = d1;
+     743       81866 :       dy[i+1] = d2;
+     744       81866 :       dy[i+2] = d3;
+     745             :     }
+     746             :     /* continue with last i value */
+     747        9150 :     for(;i<n;i++) {
+     748        5889 :       d1      = dx[i];
+     749        5889 :       dx[i]   = dy[i];
+     750        5889 :       dy[i]   = d1;
+     751             :     }
+     752             : 
+     753             :   } else {
+     754             :     ix = 0;
+     755             :     iy = 0;
+     756        2623 :     if(incx<0)
+     757           0 :       ix = incx * (1 - n);
+     758        2623 :     if(incy<0)
+     759           0 :       iy = incy * (1 - n);
+     760             : 
+     761      195103 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) {
+     762      192480 :       d1     = dx[ix];
+     763      192480 :       dx[ix] = dy[iy];
+     764      192480 :       dy[iy] = d1;
+     765             :     }
+     766             :   }
+     767             :   return;
+     768             : }
+     769             :  
+     770             : }
+     771             : }
+     772             : #include <cctype>
+     773             : #include <cmath>
+     774             : 
+     775             : #include "real.h"
+     776             : #include "blas.h"
+     777             : 
+     778             : namespace PLMD{
+     779             : namespace blas{
+     780             : void
+     781     1114407 : PLUMED_BLAS_F77_FUNC(dsymv,DSYMV)(const char *uplo,
+     782             :        int *n__,
+     783             :        double *alpha__,
+     784             :        double *a,
+     785             :        int *lda__,
+     786             :        double *x,
+     787             :        int *incx__,
+     788             :        double *beta__,
+     789             :        double *y,
+     790             :        int *incy__)
+     791             : {
+     792     1114407 :     const char ch=std::toupper(*uplo);
+     793             :     int kx,ky,i,j,ix,iy,jx,jy;
+     794             :     double temp1,temp2;
+     795             :     
+     796     1114407 :     int n = *n__;
+     797     1114407 :     int lda = *lda__;
+     798     1114407 :     int incx = *incx__;
+     799     1114407 :     int incy = *incy__;
+     800     1114407 :     double alpha = *alpha__;
+     801     1114407 :     double beta  = *beta__;
+     802             :     
+     803     1114407 :     if(n<=0 || incx==0 || incy==0)
+     804             :         return;
+     805             :     
+     806     1114407 :     if(incx>0)
+     807             :         kx = 1;
+     808             :     else
+     809           0 :         kx = 1 - (n -1)*(incx);
+     810             :     
+     811     1114407 :     if(incy>0)
+     812             :         ky = 1;
+     813             :     else
+     814           0 :         ky = 1 - (n -1)*(incy);
+     815             :     
+     816     1114407 :     if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+     817     1114407 :         if(incy==1) {
+     818     1114407 :             if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN) 
+     819     4092261 :                 for(i=1;i<=n;i++)
+     820     2977854 :                     y[i-1] = 0.0;
+     821             :             else
+     822           0 :                 for(i=1;i<=n;i++)
+     823           0 :                     y[i-1] *= beta;
+     824             :         } else {
+     825             :             /* non-unit incr. */
+     826             :             iy = ky;
+     827           0 :             if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN) 
+     828           0 :                 for(i=1;i<=n;i++) {
+     829           0 :                     y[iy-1] = 0.0;
+     830           0 :                     iy += incy;
+     831             :                 }
+     832             :                     else
+     833           0 :                         for(i=1;i<=n;i++) {
+     834           0 :                             y[iy-1] *= beta;
+     835           0 :                             iy += incy;
+     836             :                         }
+     837             :         }
+     838             :     }
+     839             :         
+     840     1114407 :         if(std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN) 
+     841             :             return;
+     842             :         
+     843     1114407 :         if(ch=='U') {
+     844     1114407 :             if(incx==1 && incy==1) {
+     845     4092261 :                 for(j=1;j<=n;j++) {
+     846     2977854 :                     temp1 = alpha * x[j-1];
+     847             :                     temp2 = 0.0;
+     848    29707001 :                     for(i=1;i<j;i++) {
+     849    26729147 :                         y[i-1] += temp1*a[(j-1)*(lda)+(i-1)];
+     850    26729147 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[i-1];
+     851             :                     }
+     852     2977854 :                     y[j-1] += temp1*a[(j-1)*(lda)+(j-1)] + alpha *temp2;
+     853             :                 }
+     854             :             } else {
+     855             :                 /* non-unit incr. */
+     856             :                 jx = kx;
+     857             :                 jy = ky;
+     858           0 :                 for(j=1;j<=n;j++) {
+     859           0 :                     temp1 = alpha * x[jx-1];
+     860             :                     temp2 = 0.0;
+     861             :                     ix = kx;
+     862             :                     iy = ky;
+     863           0 :                     for(i=1;i<j;i++) {
+     864           0 :                         y[iy-1] += temp1 * a[(j-1)*(lda)+(i-1)];
+     865           0 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[ix-1];
+     866           0 :                         ix += incx;
+     867           0 :                         iy += incy;
+     868             :                     }
+     869           0 :                     y[jy-1] += temp1*a[(j-1)*(lda)+(j-1)] + alpha*temp2;
+     870           0 :                     jx += incx;
+     871           0 :                     jy += incy;
+     872             :                 }
+     873             :             }
+     874             :         } else {
+     875             :             /* lower */
+     876           0 :             if(incx==1 && incy==1) {
+     877           0 :                 for(j=1;j<=n;j++) {
+     878           0 :                     temp1 = alpha * x[j-1];
+     879             :                     temp2 = 0.0;
+     880           0 :                     y[j-1] += temp1 * a[(j-1)*(lda)+(j-1)];
+     881           0 :                     for(i=j+1;i<=n;i++) {
+     882           0 :                         y[i-1] += temp1*a[(j-1)*(lda)+(i-1)];
+     883           0 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[i-1];
+     884             :                     }
+     885           0 :                     y[j-1] += alpha *temp2;
+     886             :                 }
+     887             :             } else {
+     888             :                 /* non-unit incr. */
+     889             :                 jx = kx;
+     890             :                 jy = ky;
+     891           0 :                 for(j=1;j<=n;j++) {
+     892           0 :                     temp1 = alpha * x[jx-1];
+     893             :                     temp2 = 0.0;
+     894           0 :                     y[jy-1] += temp1 * a[(j-1)*(lda)+(j-1)];
+     895             :                     ix = jx;
+     896             :                     iy = jy;
+     897           0 :                     for(i=j+1;i<=n;i++) {
+     898           0 :                         ix += incx;
+     899           0 :                         iy += incy;
+     900           0 :                         y[iy-1] += temp1 * a[(j-1)*(lda)+(i-1)];
+     901           0 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[ix-1];
+     902             :                     }
+     903           0 :                     y[jy-1] += alpha*temp2;
+     904           0 :                     jx += incx;
+     905           0 :                     jy += incy;
+     906             :                 }
+     907             :             }
+     908             :         }
+     909             :         return;
+     910             : }    
+     911             : }
+     912             : }
+     913             : #include <cctype>
+     914             : #include <cmath>
+     915             : 
+     916             : #include "real.h"
+     917             : 
+     918             : #include "blas.h"
+     919             : 
+     920             : namespace PLMD{
+     921             : namespace blas{
+     922             : void
+     923     1113894 : PLUMED_BLAS_F77_FUNC(dsyr2,DSYR2)(const char *    uplo,
+     924             :                       int *     n__,
+     925             :                       double *  alpha__,
+     926             :                       double *  x,
+     927             :                       int *     incx__,
+     928             :                       double *  y,
+     929             :                       int *     incy__,
+     930             :                       double *  a,
+     931             :                       int *     lda__)
+     932             : {
+     933             :     int kx,ky,ix,iy,jx,jy,j,i;
+     934             :     double temp1,temp2;
+     935     1113894 :     const char ch=std::toupper(*uplo);
+     936             :     
+     937     1113894 :     int n = *n__;
+     938     1113894 :     int lda = *lda__;
+     939     1113894 :     int incx = *incx__;
+     940     1113894 :     int incy = *incy__;
+     941     1113894 :     float alpha = *alpha__;
+     942             :     
+     943             :     
+     944     1113894 :     if(n<=0 || std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN || incx==0 || incy==0 ||
+     945     1113894 :        (ch != 'U' && ch != 'L'))
+     946             :         return;
+     947             :     
+     948             :     jx = jy = kx = ky = 0;
+     949             :     
+     950             :     /* init start points for non-unit increments */
+     951     1113894 :     if(incx!=1 || incy!=1) {
+     952           0 :         if(incx>0)
+     953             :             kx = 1;
+     954             :         else
+     955           0 :             kx = 1 - (n - 1)*(incx);
+     956           0 :         if(incy>0)
+     957             :             ky = 1;
+     958             :         else
+     959           0 :             ky = 1 - (n - 1)*(incy);
+     960             :         
+     961             :         jx = kx;
+     962             :         jy = ky;
+     963             :     }
+     964             :     
+     965     1113894 :     if(ch == 'U') {
+     966             :         /* Data in upper part of A */
+     967     1113894 :         if(incx==1 && incy==1) {
+     968             :             /* Unit increments for both x and y */
+     969     3949809 :             for(j=1;j<=n;j++) {
+     970     2835915 :                 if( std::abs(x[j-1])>PLUMED_GMX_DOUBLE_MIN  || std::abs(y[j-1])>PLUMED_GMX_DOUBLE_MIN ) {
+     971     2835915 :                     temp1 = alpha * y[j-1];
+     972     2835915 :                     temp2 = alpha * x[j-1];
+     973     9661622 :                     for(i=1;i<=j;i++)
+     974     6825707 :                         a[(j-1)*(lda)+(i-1)] += x[i-1]*temp1 + y[i-1]*temp2;
+     975             :                 }
+     976             :             }
+     977             :         } else {
+     978             :             
+     979             :             /* non-unit increments */
+     980           0 :             for(j=1;j<=n;j++) {
+     981             :                 
+     982           0 :                 if( std::abs(x[jx-1])>PLUMED_GMX_DOUBLE_MIN || std::abs(y[jy-1])>PLUMED_GMX_DOUBLE_MIN ) {
+     983           0 :                     temp1 = alpha * y[jy-1];
+     984           0 :                     temp2 = alpha * x[jx-1];
+     985             :                     ix = kx;
+     986             :                     iy = ky;
+     987           0 :                     for(i=1;i<=j;i++) {
+     988           0 :                         a[(j-1)*(lda)+(i-1)] += x[ix-1]*temp1 + y[iy-1]*temp2;
+     989           0 :                         ix += incx;
+     990           0 :                         iy += incy;
+     991             :                     }
+     992             :                 }
+     993           0 :                 jx += incx;
+     994           0 :                 jy += incy;
+     995             :             }
+     996             :         }
+     997             :     } else {
+     998             :         /* Data in lower part of A */
+     999           0 :         if(incx==1 && incy==1) {
+    1000             :             /* Unit increments for both x and y */
+    1001           0 :             for(j=1;j<=n;j++) {
+    1002           0 :                 if( std::abs(x[j-1])>PLUMED_GMX_DOUBLE_MIN  || std::abs(y[j-1])>PLUMED_GMX_DOUBLE_MIN ) {
+    1003           0 :                     temp1 = alpha * y[j-1];
+    1004           0 :                     temp2 = alpha * x[j-1];
+    1005           0 :                     for(i=j;i<=n;i++)
+    1006           0 :                         a[(j-1)*(lda)+(i-1)] += x[i-1]*temp1 + y[i-1]*temp2;
+    1007             :                 }
+    1008             :             }
+    1009             :         } else {
+    1010             :             
+    1011             :             /* non-unit increments */
+    1012           0 :             for(j=1;j<=n;j++) {
+    1013             :                 
+    1014           0 :                 if( std::abs(x[jx-1])>PLUMED_GMX_DOUBLE_MIN || std::abs(y[jy-1])>PLUMED_GMX_DOUBLE_MIN ) {
+    1015           0 :                     temp1 = alpha * y[jy-1];
+    1016           0 :                     temp2 = alpha * x[jx-1];
+    1017             :                     ix = jx;
+    1018             :                     iy = jy;
+    1019           0 :                     for(i=j;i<=n;i++) {
+    1020           0 :                         a[(j-1)*(lda)+(i-1)] += x[ix-1]*temp1 + y[iy-1]*temp2;
+    1021           0 :                         ix += incx;
+    1022           0 :                         iy += incy;
+    1023             :                     }
+    1024             :                 }
+    1025           0 :                 jx += incx;
+    1026           0 :                 jy += incy;
+    1027             :             }
+    1028             :         }
+    1029             :     }
+    1030             :     
+    1031             :     return;
+    1032             : }
+    1033             : }
+    1034             : }
+    1035             : #include <cctype>
+    1036             : #include <cmath>
+    1037             : 
+    1038             : #include "real.h"
+    1039             : #include "blas.h"
+    1040             : 
+    1041             : namespace PLMD{
+    1042             : namespace blas{
+    1043             : void
+    1044          19 : PLUMED_BLAS_F77_FUNC(dsyr2k,DSYR2K)(const char *uplo, 
+    1045             :         const char *trans,
+    1046             :         int *n__,
+    1047             :         int *k__,
+    1048             :         double *alpha__,
+    1049             :         double *a,
+    1050             :         int *lda__,
+    1051             :         double *b,
+    1052             :         int *ldb__,
+    1053             :         double *beta__,
+    1054             :         double *c,
+    1055             :         int *ldc__)
+    1056             : {
+    1057             :   char ch1,ch2;
+    1058             :   int i,j,l;
+    1059             :   double temp1,temp2;
+    1060             : 
+    1061             :   
+    1062          19 :   int n = *n__;
+    1063          19 :   int k = *k__;
+    1064          19 :   int lda = *lda__;
+    1065          19 :   int ldb = *ldb__;
+    1066          19 :   int ldc = *ldc__;
+    1067             :   
+    1068          19 :   double alpha = *alpha__;
+    1069          19 :   double beta  = *beta__;
+    1070             :   
+    1071          19 :   ch1 = std::toupper(*uplo);
+    1072          19 :   ch2 = std::toupper(*trans);
+    1073             : 
+    1074          19 :   if(n==0 || ( ( std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN || k==0 ) && std::abs(beta-1.0)<PLUMED_GMX_DOUBLE_EPS))
+    1075             :     return;
+    1076             : 
+    1077          19 :   if(std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN ) {
+    1078           0 :     if(ch1=='U') {
+    1079           0 :       if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN) 
+    1080           0 :         for(j=1;j<=n;j++) 
+    1081           0 :           for(i=1;i<=j;i++)
+    1082           0 :             c[(j-1)*(ldc)+(i-1)] = 0.0;
+    1083             :       else
+    1084           0 :         for(j=1;j<=n;j++) 
+    1085           0 :           for(i=1;i<=j;i++)
+    1086           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    1087             :     } else {
+    1088             :       /* lower */
+    1089           0 :       if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN) 
+    1090           0 :         for(j=1;j<=n;j++) 
+    1091           0 :           for(i=j;i<=n;i++)
+    1092           0 :             c[(j-1)*(ldc)+(i-1)] = 0.0;
+    1093             :       else
+    1094           0 :         for(j=1;j<=n;j++) 
+    1095           0 :           for(i=j;i<=n;i++)
+    1096           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    1097             :     }
+    1098           0 :     return;
+    1099             :   }
+    1100             : 
+    1101          19 :   if(ch2=='N') {
+    1102          19 :     if(ch1=='U') {
+    1103        5029 :       for(j=1;j<=n;j++) {
+    1104        5010 :         if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN)
+    1105           0 :           for(i=1;i<=j;i++)
+    1106           0 :              c[(j-1)*(ldc)+(i-1)] = 0.0;
+    1107        5010 :         else if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS)
+    1108           0 :           for(i=1;i<=j;i++)
+    1109           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    1110      140280 :         for(l=1;l<=k;l++) {
+    1111      135270 :           if( std::abs(a[(l-1)*(lda)+(j-1)])>PLUMED_GMX_DOUBLE_MIN ||
+    1112           0 :               std::abs(b[(l-1)*(ldb)+(j-1)])>PLUMED_GMX_DOUBLE_MIN) {
+    1113      135270 :             temp1 = alpha * b[(l-1)*(ldb)+(j-1)];
+    1114      135270 :             temp2 = alpha * a[(l-1)*(lda)+(j-1)];
+    1115    21195810 :             for(i=1;i<=j;i++)
+    1116    21060540 :               c[(j-1)*(ldc)+(i-1)] += 
+    1117    21060540 :                 a[(l-1)*(lda)+(i-1)] * temp1 + 
+    1118    21060540 :                 b[(l-1)*(ldb)+(i-1)] * temp2;
+    1119             :           }
+    1120             :         }
+    1121             :       }
+    1122             :     } else {
+    1123             :       /* lower */
+    1124           0 :       for(j=1;j<=n;j++) {
+    1125           0 :         if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN)
+    1126           0 :           for(i=j;i<=n;i++)
+    1127           0 :             c[(j-1)*(ldc)+(i-1)] = 0.0;
+    1128           0 :         else if(std::abs(beta-1.0)>PLUMED_GMX_DOUBLE_EPS)
+    1129           0 :           for(i=j;i<=n;i++)
+    1130           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    1131           0 :         for(l=1;l<=k;l++) {
+    1132           0 :           if( std::abs(a[(l-1)*(lda)+(j-1)])>PLUMED_GMX_DOUBLE_MIN ||
+    1133           0 :               std::abs(b[(l-1)*(ldb)+(j-1)])>PLUMED_GMX_DOUBLE_MIN) {
+    1134           0 :             temp1 = alpha * b[(l-1)*(ldb)+(j-1)];
+    1135           0 :             temp2 = alpha * a[(l-1)*(lda)+(j-1)];
+    1136           0 :             for(i=j;i<=n;i++)
+    1137           0 :               c[(j-1)*(ldc)+(i-1)] += 
+    1138           0 :                 a[(l-1)*(lda)+(i-1)] * temp1 + 
+    1139           0 :                 b[(l-1)*(ldb)+(i-1)] * temp2;
+    1140             :           }
+    1141             :         }
+    1142             :       }
+    1143             :     }
+    1144             :   } else {
+    1145             :     /* transpose */
+    1146           0 :     if(ch1=='U') {
+    1147           0 :       for(j=1;j<=n;j++) 
+    1148           0 :         for(i=1;i<=j;i++) {
+    1149             :           temp1 = 0.0;
+    1150             :           temp2 = 0.0;
+    1151           0 :           for (l=1;l<=k;l++) {
+    1152           0 :              temp1 += a[(i-1)*(lda)+(l-1)] * b[(j-1)*(ldb)+(l-1)];
+    1153           0 :              temp2 += b[(i-1)*(ldb)+(l-1)] * a[(j-1)*(lda)+(l-1)];
+    1154             :           }
+    1155           0 :           if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN)
+    1156           0 :             c[(j-1)*(ldc)+(i-1)] = alpha * (temp1 + temp2);
+    1157             :           else
+    1158           0 :             c[(j-1)*(ldc)+(i-1)] = beta * c[(j-1)*(ldc)+(i-1)] +
+    1159           0 :               alpha * (temp1 + temp2);
+    1160             :         }
+    1161             :     } else {
+    1162             :       /* lower */
+    1163           0 :       for(j=1;j<=n;j++) 
+    1164           0 :         for(i=j;i<=n;i++) {
+    1165             :           temp1 = 0.0;
+    1166             :           temp2 = 0.0;
+    1167           0 :           for (l=1;l<=k;l++) {
+    1168           0 :              temp1 += a[(i-1)*(lda)+(l-1)] * b[(j-1)*(ldb)+(l-1)];
+    1169           0 :              temp2 += b[(i-1)*(ldb)+(l-1)] * a[(j-1)*(lda)+(l-1)];
+    1170             :           }
+    1171           0 :           if(std::abs(beta)<PLUMED_GMX_DOUBLE_MIN)
+    1172           0 :             c[(j-1)*(ldc)+(i-1)] = alpha * (temp1 + temp2);
+    1173             :           else
+    1174           0 :             c[(j-1)*(ldc)+(i-1)] = beta * c[(j-1)*(ldc)+(i-1)] +
+    1175           0 :               alpha * (temp1 + temp2);
+    1176             :         }
+    1177             :     }
+    1178             :   }
+    1179             :   return;
+    1180             : }
+    1181             : }
+    1182             : }
+    1183             : #include <cmath>
+    1184             : 
+    1185             : #include "real.h"
+    1186             : 
+    1187             : #include "blas.h"
+    1188             : 
+    1189             : namespace PLMD{
+    1190             : namespace blas{
+    1191             : void 
+    1192         441 : PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)(const char *side, 
+    1193             :        const char *uplo, 
+    1194             :        const char *transa, 
+    1195             :        const char *diag, 
+    1196             :        int *m__, 
+    1197             :        int *n__, 
+    1198             :        double *alpha__, 
+    1199             :        double *a, 
+    1200             :        int *lda__, 
+    1201             :        double *b, 
+    1202             :        int *ldb__)
+    1203             : {
+    1204             :     int a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3;
+    1205             : 
+    1206         441 :     int m = *m__;
+    1207         441 :     int n = *n__;
+    1208         441 :     int lda = *lda__;
+    1209         441 :     int ldb = *ldb__;
+    1210         441 :     double alpha = *alpha__;
+    1211             :     
+    1212             :     /* Local variables */
+    1213             :     int i__, j, k;
+    1214             :     double temp;
+    1215             :     int lside;
+    1216             :     int upper;
+    1217             :     int nounit;
+    1218             :     a_dim1 = lda;
+    1219         441 :     a_offset = 1 + a_dim1;
+    1220         441 :     a -= a_offset;
+    1221             :     b_dim1 = ldb;
+    1222         441 :     b_offset = 1 + b_dim1;
+    1223         441 :     b -= b_offset;
+    1224             : 
+    1225             :     /* Function Body */
+    1226         441 :     lside = (*side=='L' || *side=='l');
+    1227             : 
+    1228         441 :     nounit = (*diag=='N' || *diag=='n');
+    1229         441 :     upper = (*uplo=='U' || *uplo=='u');
+    1230             : 
+    1231         441 :     if (n == 0) {
+    1232             :         return;
+    1233             :     }
+    1234         441 :     if (std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN) {
+    1235             :         i__1 = n;
+    1236           0 :         for (j = 1; j <= i__1; ++j) {
+    1237             :             i__2 = m;
+    1238           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    1239           0 :                 b[i__ + j * b_dim1] = 0.;
+    1240             :             }
+    1241             :         }
+    1242             :         return;
+    1243             :     }
+    1244         441 :     if (lside) {
+    1245           0 :         if (*transa=='N' || *transa=='n') {
+    1246           0 :             if (upper) {
+    1247             :                 i__1 = n;
+    1248           0 :                 for (j = 1; j <= i__1; ++j) {
+    1249             :                     i__2 = m;
+    1250           0 :                     for (k = 1; k <= i__2; ++k) {
+    1251           0 :                         if (std::abs(b[k + j * b_dim1])>PLUMED_GMX_DOUBLE_MIN) {
+    1252           0 :                             temp = alpha * b[k + j * b_dim1];
+    1253             :                             i__3 = k - 1;
+    1254           0 :                             for (i__ = 1; i__ <= i__3; ++i__) {
+    1255           0 :                                 b[i__ + j * b_dim1] += temp * a[i__ + k * a_dim1];
+    1256             :                             }
+    1257           0 :                             if (nounit) {
+    1258           0 :                                 temp *= a[k + k * a_dim1];
+    1259             :                             }
+    1260           0 :                             b[k + j * b_dim1] = temp;
+    1261             :                         }
+    1262             :                     }
+    1263             :                 }
+    1264             :             } else {
+    1265             :                 i__1 = n;
+    1266           0 :                 for (j = 1; j <= i__1; ++j) {
+    1267           0 :                     for (k = m; k >= 1; --k) {
+    1268           0 :                         if (std::abs(b[k + j * b_dim1])>PLUMED_GMX_DOUBLE_MIN) {
+    1269           0 :                             temp = alpha * b[k + j * b_dim1];
+    1270           0 :                             b[k + j * b_dim1] = temp;
+    1271           0 :                             if (nounit) {
+    1272           0 :                                 b[k + j * b_dim1] *= a[k + k * a_dim1];
+    1273             :                             }
+    1274             :                             i__2 = m;
+    1275           0 :                             for (i__ = k + 1; i__ <= i__2; ++i__) {
+    1276           0 :                                 b[i__ + j * b_dim1] += temp * a[i__ + k * 
+    1277           0 :                                         a_dim1];
+    1278             :                             }
+    1279             :                         }
+    1280             :                     }
+    1281             :                 }
+    1282             :             }
+    1283             :         } else {
+    1284             : 
+    1285           0 :             if (upper) {
+    1286             :                 i__1 = n;
+    1287           0 :                 for (j = 1; j <= i__1; ++j) {
+    1288           0 :                     for (i__ = m; i__ >= 1; --i__) {
+    1289           0 :                         temp = b[i__ + j * b_dim1];
+    1290           0 :                         if (nounit) {
+    1291           0 :                             temp *= a[i__ + i__ * a_dim1];
+    1292             :                         }
+    1293             :                         i__2 = i__ - 1;
+    1294           0 :                         for (k = 1; k <= i__2; ++k) {
+    1295           0 :                             temp += a[k + i__ * a_dim1] * b[k + j * b_dim1];
+    1296             :                         }
+    1297           0 :                         b[i__ + j * b_dim1] = alpha * temp;
+    1298             :                     }
+    1299             :                 }
+    1300             :             } else {
+    1301             :                 i__1 = n;
+    1302           0 :                 for (j = 1; j <= i__1; ++j) {
+    1303             :                     i__2 = m;
+    1304           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    1305           0 :                         temp = b[i__ + j * b_dim1];
+    1306           0 :                         if (nounit) {
+    1307           0 :                             temp *= a[i__ + i__ * a_dim1];
+    1308             :                         }
+    1309             :                         i__3 = m;
+    1310           0 :                         for (k = i__ + 1; k <= i__3; ++k) {
+    1311           0 :                             temp += a[k + i__ * a_dim1] * b[k + j * b_dim1];
+    1312             :                         }
+    1313           0 :                         b[i__ + j * b_dim1] = alpha * temp;
+    1314             :                     }
+    1315             :                 }
+    1316             :             }
+    1317             :         }
+    1318             :     } else {
+    1319         441 :         if (*transa=='N' || *transa=='n') {
+    1320             : 
+    1321         147 :             if (upper) {
+    1322        2634 :                 for (j = n; j >= 1; --j) {
+    1323             :                     temp = alpha;
+    1324        2535 :                     if (nounit) {
+    1325           0 :                         temp *= a[j + j * a_dim1];
+    1326             :                     }
+    1327             :                     i__1 = m;
+    1328      658291 :                     for (i__ = 1; i__ <= i__1; ++i__) {
+    1329      655756 :                         b[i__ + j * b_dim1] = temp * b[i__ + j * b_dim1];
+    1330             :                     }
+    1331             :                     i__1 = j - 1;
+    1332       40262 :                     for (k = 1; k <= i__1; ++k) {
+    1333       37727 :                         if (std::abs(a[k + j * a_dim1])>PLUMED_GMX_DOUBLE_MIN) {
+    1334       37727 :                             temp = alpha * a[k + j * a_dim1];
+    1335             :                             i__2 = m;
+    1336     9987691 :                             for (i__ = 1; i__ <= i__2; ++i__) {
+    1337     9949964 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    1338     9949964 :                                         b_dim1];
+    1339             :                             }
+    1340             :                         }
+    1341             :                     }
+    1342             :                 }
+    1343             :             } else {
+    1344             :                 i__1 = n;
+    1345        1124 :                 for (j = 1; j <= i__1; ++j) {
+    1346             :                     temp = alpha;
+    1347        1076 :                     if (nounit) {
+    1348           0 :                         temp *= a[j + j * a_dim1];
+    1349             :                     }
+    1350             :                     i__2 = m;
+    1351      271892 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    1352      270816 :                         b[i__ + j * b_dim1] = temp * b[i__ + j * b_dim1];
+    1353             :                     }
+    1354             :                     i__2 = n;
+    1355       16778 :                     for (k = j + 1; k <= i__2; ++k) {
+    1356       15702 :                         if (std::abs(a[k + j * a_dim1])>PLUMED_GMX_DOUBLE_MIN) {
+    1357       15486 :                             temp = alpha * a[k + j * a_dim1];
+    1358             :                             i__3 = m;
+    1359     4113622 :                             for (i__ = 1; i__ <= i__3; ++i__) {
+    1360     4098136 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    1361     4098136 :                                         b_dim1];
+    1362             :                             }
+    1363             :                         }
+    1364             :                     }
+    1365             :                 }
+    1366             :             }
+    1367             :         } else {
+    1368             : 
+    1369         294 :             if (upper) {
+    1370             :                 i__1 = n;
+    1371        4729 :                 for (k = 1; k <= i__1; ++k) {
+    1372             :                     i__2 = k - 1;
+    1373       71622 :                     for (j = 1; j <= i__2; ++j) {
+    1374       67080 :                         if (std::abs(a[j + k * a_dim1])>PLUMED_GMX_DOUBLE_MIN) {
+    1375       66959 :                             temp = alpha * a[j + k * a_dim1];
+    1376             :                             i__3 = m;
+    1377    18130215 :                             for (i__ = 1; i__ <= i__3; ++i__) {
+    1378    18063256 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    1379    18063256 :                                         b_dim1];
+    1380             :                             }
+    1381             :                         }
+    1382             :                     }
+    1383             :                     temp = alpha;
+    1384        4542 :                     if (nounit) {
+    1385        2007 :                         temp *= a[k + k * a_dim1];
+    1386             :                     }
+    1387        4542 :                     if (std::abs(temp-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+    1388             :                         i__2 = m;
+    1389      538339 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+    1390      536332 :                             b[i__ + k * b_dim1] = temp * b[i__ + k * b_dim1];
+    1391             :                         }
+    1392             :                     }
+    1393             :                 }
+    1394             :             } else {
+    1395        2787 :                 for (k = n; k >= 1; --k) {
+    1396             :                     i__1 = n;
+    1397       42458 :                     for (j = k + 1; j <= i__1; ++j) {
+    1398       39778 :                         if (std::abs(a[j + k * a_dim1])>PLUMED_GMX_DOUBLE_MIN) {
+    1399       39190 :                             temp = alpha * a[j + k * a_dim1];
+    1400             :                             i__2 = m;
+    1401    10008102 :                             for (i__ = 1; i__ <= i__2; ++i__) {
+    1402     9968912 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    1403     9968912 :                                         b_dim1];
+    1404             :                             }
+    1405             :                         }
+    1406             :                     }
+    1407             :                     temp = alpha;
+    1408        2680 :                     if (nounit) {
+    1409        1604 :                         temp *= a[k + k * a_dim1];
+    1410             :                     }
+    1411        2680 :                     if (std::abs(temp-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+    1412             :                         i__1 = m;
+    1413      391844 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+    1414      390240 :                             b[i__ + k * b_dim1] = temp * b[i__ + k * b_dim1];
+    1415             :                         }
+    1416             :                     }
+    1417             :                 }
+    1418             :             }
+    1419             :         }
+    1420             :     }
+    1421             : 
+    1422             :     return;
+    1423             : 
+    1424             : }
+    1425             : 
+    1426             : 
+    1427             : }
+    1428             : }
+    1429             : #include <cmath>
+    1430             : 
+    1431             : #include "real.h"
+    1432             : #include "blas.h"
+    1433             : 
+    1434             : namespace PLMD{
+    1435             : namespace blas{
+    1436             : void 
+    1437        3624 : PLUMED_BLAS_F77_FUNC(dtrmv,DTRMV)(const char *uplo, 
+    1438             :        const char *trans,
+    1439             :        const char *diag, 
+    1440             :        int *n__, 
+    1441             :        double *a, 
+    1442             :        int *lda__, 
+    1443             :        double *x, 
+    1444             :        int *incx__)
+    1445             : {
+    1446             :     int a_dim1, a_offset, i__1, i__2;
+    1447             : 
+    1448             :     int i__, j, ix, jx, kx;
+    1449             :     double temp;
+    1450             :     int nounit;
+    1451             :     
+    1452        3624 :     int n = *n__;
+    1453        3624 :     int lda = *lda__;
+    1454        3624 :     int incx = *incx__;
+    1455             :     
+    1456             :     a_dim1 = lda;
+    1457        3624 :     a_offset = 1 + a_dim1;
+    1458        3624 :     a -= a_offset;
+    1459        3624 :     --x;
+    1460             : 
+    1461        3624 :     if (n == 0) {
+    1462             :         return;
+    1463             :     }
+    1464             : 
+    1465        3483 :     nounit = (*diag=='n' || *diag=='N');
+    1466             : 
+    1467        3483 :     if (incx <= 0) {
+    1468           0 :         kx = 1 - (n - 1) * incx;
+    1469             :     } else {
+    1470             :         kx = 1;
+    1471             :     }
+    1472             : 
+    1473        3483 :     if (*trans=='N' || *trans=='n') {
+    1474             : 
+    1475        3483 :         if (*uplo=='U' || *uplo=='u') {
+    1476        1950 :             if (incx == 1) {
+    1477             :                 i__1 = n;
+    1478       31239 :                 for (j = 1; j <= i__1; ++j) {
+    1479       29289 :                     if (std::abs(x[j])>PLUMED_GMX_DOUBLE_MIN) {
+    1480             :                         temp = x[j];
+    1481             :                         i__2 = j - 1;
+    1482      318678 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+    1483      289605 :                             x[i__] += temp * a[i__ + j * a_dim1];
+    1484             :                         }
+    1485       29073 :                         if (nounit) {
+    1486       29073 :                             x[j] *= a[j + j * a_dim1];
+    1487             :                         }
+    1488             :                     }
+    1489             :                 }
+    1490             :             } else {
+    1491             :                 jx = kx;
+    1492             :                 i__1 = n;
+    1493           0 :                 for (j = 1; j <= i__1; ++j) {
+    1494           0 :                     if (std::abs(x[jx])>PLUMED_GMX_DOUBLE_MIN) {
+    1495             :                         temp = x[jx];
+    1496             :                         ix = kx;
+    1497             :                         i__2 = j - 1;
+    1498           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+    1499           0 :                             x[ix] += temp * a[i__ + j * a_dim1];
+    1500           0 :                             ix += incx;
+    1501             :                         }
+    1502           0 :                         if (nounit) {
+    1503           0 :                             x[jx] *= a[j + j * a_dim1];
+    1504             :                         }
+    1505             :                     }
+    1506           0 :                     jx += incx;
+    1507             :                 }
+    1508             :             }
+    1509             :         } else {
+    1510        1533 :             if (incx == 1) {
+    1511       25237 :                 for (j = n; j >= 1; --j) {
+    1512       23704 :                     if (std::abs(x[j])>PLUMED_GMX_DOUBLE_MIN) {
+    1513             :                         temp = x[j];
+    1514             :                         i__1 = j + 1;
+    1515      255880 :                         for (i__ = n; i__ >= i__1; --i__) {
+    1516      232176 :                             x[i__] += temp * a[i__ + j * a_dim1];
+    1517             :                         }
+    1518       23704 :                         if (nounit) {
+    1519       23704 :                             x[j] *= a[j + j * a_dim1];
+    1520             :                         }
+    1521             :                     }
+    1522             :                 }
+    1523             :             } else {
+    1524           0 :                 kx += (n - 1) * incx;
+    1525             :                 jx = kx;
+    1526           0 :                 for (j = n; j >= 1; --j) {
+    1527           0 :                     if (std::abs(x[jx])>PLUMED_GMX_DOUBLE_MIN) {
+    1528             :                         temp = x[jx];
+    1529             :                         ix = kx;
+    1530             :                         i__1 = j + 1;
+    1531           0 :                         for (i__ = n; i__ >= i__1; --i__) {
+    1532           0 :                             x[ix] += temp * a[i__ + j * a_dim1];
+    1533           0 :                             ix -= incx;
+    1534             :                         }
+    1535           0 :                         if (nounit) {
+    1536           0 :                             x[jx] *= a[j + j * a_dim1];
+    1537             :                         }
+    1538             :                     }
+    1539           0 :                     jx -= incx;
+    1540             :                 }
+    1541             :             }
+    1542             :         }
+    1543             :     } else {
+    1544             : 
+    1545           0 :         if (*uplo=='U' || *uplo=='u') {
+    1546           0 :             if (incx == 1) {
+    1547           0 :                 for (j = n; j >= 1; --j) {
+    1548           0 :                     temp = x[j];
+    1549           0 :                     if (nounit) {
+    1550           0 :                         temp *= a[j + j * a_dim1];
+    1551             :                     }
+    1552           0 :                     for (i__ = j - 1; i__ >= 1; --i__) {
+    1553           0 :                         temp += a[i__ + j * a_dim1] * x[i__];
+    1554             :                     }
+    1555           0 :                     x[j] = temp;
+    1556             :                 }
+    1557             :             } else {
+    1558           0 :                 jx = kx + (n - 1) * incx;
+    1559           0 :                 for (j = n; j >= 1; --j) {
+    1560           0 :                     temp = x[jx];
+    1561             :                     ix = jx;
+    1562           0 :                     if (nounit) {
+    1563           0 :                         temp *= a[j + j * a_dim1];
+    1564             :                     }
+    1565           0 :                     for (i__ = j - 1; i__ >= 1; --i__) {
+    1566           0 :                         ix -= incx;
+    1567           0 :                         temp += a[i__ + j * a_dim1] * x[ix];
+    1568             :                     }
+    1569           0 :                     x[jx] = temp;
+    1570           0 :                     jx -= incx;
+    1571             :                 }
+    1572             :             }
+    1573             :         } else {
+    1574           0 :             if (incx == 1) {
+    1575             :                 i__1 = n;
+    1576           0 :                 for (j = 1; j <= i__1; ++j) {
+    1577           0 :                     temp = x[j];
+    1578           0 :                     if (nounit) {
+    1579           0 :                         temp *= a[j + j * a_dim1];
+    1580             :                     }
+    1581             :                     i__2 = n;
+    1582           0 :                     for (i__ = j + 1; i__ <= i__2; ++i__) {
+    1583           0 :                         temp += a[i__ + j * a_dim1] * x[i__];
+    1584             :                     }
+    1585           0 :                     x[j] = temp;
+    1586             :                 }
+    1587             :             } else {
+    1588             :                 jx = kx;
+    1589             :                 i__1 = n;
+    1590           0 :                 for (j = 1; j <= i__1; ++j) {
+    1591           0 :                     temp = x[jx];
+    1592             :                     ix = jx;
+    1593           0 :                     if (nounit) {
+    1594           0 :                         temp *= a[j + j * a_dim1];
+    1595             :                     }
+    1596             :                     i__2 = n;
+    1597           0 :                     for (i__ = j + 1; i__ <= i__2; ++i__) {
+    1598           0 :                         ix += incx;
+    1599           0 :                         temp += a[i__ + j * a_dim1] * x[ix];
+    1600             :                     }
+    1601           0 :                     x[jx] = temp;
+    1602           0 :                     jx += incx;
+    1603             :                 }
+    1604             :             }
+    1605             :         }
+    1606             :     }
+    1607             : 
+    1608             :     return;
+    1609             : 
+    1610             : }
+    1611             : 
+    1612             : 
+    1613             : }
+    1614             : }
+    1615             : #include <cctype>
+    1616             : #include <cmath>
+    1617             : 
+    1618             : #include "real.h"
+    1619             : #include "blas.h"
+    1620             : 
+    1621             : namespace PLMD{
+    1622             : namespace blas{
+    1623             : void
+    1624           0 : PLUMED_BLAS_F77_FUNC(dtrsm,DTRSM)(const char * side,
+    1625             :        const char * uplo,
+    1626             :        const char * transa,
+    1627             :        const char * diag,
+    1628             :        int *  m__,
+    1629             :        int *  n__,
+    1630             :        double *alpha__,
+    1631             :        double *a,
+    1632             :        int *  lda__,
+    1633             :        double *b,
+    1634             :        int *  ldb__)
+    1635             : {
+    1636           0 :   const char xside  = std::toupper(*side);
+    1637           0 :   const char xuplo  = std::toupper(*uplo);
+    1638           0 :   const char xtrans = std::toupper(*transa);
+    1639           0 :   const char xdiag  = std::toupper(*diag);
+    1640             :   int i,j,k;
+    1641             :   double temp;
+    1642             : 
+    1643             :   
+    1644           0 :   int m = *m__;
+    1645           0 :   int n = *n__;
+    1646           0 :   int lda = *lda__;
+    1647           0 :   int ldb = *ldb__;
+    1648           0 :   double alpha = *alpha__;
+    1649             : 
+    1650           0 :   if(n<=0)
+    1651             :     return;
+    1652             :   
+    1653           0 :   if(std::abs(alpha)<PLUMED_GMX_DOUBLE_MIN) { 
+    1654           0 :     for(j=0;j<n;j++)
+    1655           0 :       for(i=0;i<m;i++)
+    1656           0 :         b[j*(ldb)+i] = 0.0;
+    1657             :     return;
+    1658             :   }
+    1659             : 
+    1660           0 :   if(xside=='L') {
+    1661             :     /* left side */
+    1662           0 :     if(xtrans=='N') {
+    1663             :       /* No transpose */
+    1664           0 :       if(xuplo=='U') {
+    1665             :         /* upper */
+    1666           0 :         for(j=0;j<n;j++) {
+    1667           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+    1668           0 :             for(i=0;i<m;i++)
+    1669           0 :               b[j*(ldb)+i] *= alpha;
+    1670             :           }
+    1671           0 :           for(k=m-1;k>=0;k--) {
+    1672           0 :             if(std::abs(b[j*(ldb)+k])>PLUMED_GMX_DOUBLE_MIN) {
+    1673           0 :               if(xdiag=='N')
+    1674           0 :                 b[j*(ldb)+k] /= a[k*(lda)+k];
+    1675           0 :               for(i=0;i<k;i++)
+    1676           0 :                 b[j*(ldb)+i] -= b[j*(ldb)+k]*a[k*(lda)+i];
+    1677             :             }
+    1678             :           }
+    1679             :         }
+    1680             :       } else {
+    1681             :         /* lower */
+    1682           0 :         for(j=0;j<n;j++) {
+    1683           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_DOUBLE_EPS)
+    1684           0 :             for(i=0;i<m;i++)
+    1685           0 :               b[j*(ldb)+i] *= alpha;
+    1686           0 :           for(k=0;k<m;k++) {
+    1687           0 :             if(std::abs(b[j*(ldb)+k])>PLUMED_GMX_DOUBLE_MIN) {
+    1688           0 :               if(xdiag=='N')
+    1689           0 :                 b[j*(ldb)+k] /= a[k*(lda)+k];
+    1690           0 :               for(i=k+1;i<m;i++)
+    1691           0 :                 b[j*(ldb)+i] -= b[j*(ldb)+k]*a[k*(lda)+i];
+    1692             :             }
+    1693             :           }
+    1694             :         }
+    1695             :       }
+    1696             :     } else {
+    1697             :       /* Transpose */
+    1698           0 :       if(xuplo=='U') {
+    1699             :         /* upper */
+    1700           0 :         for(j=0;j<n;j++) {
+    1701           0 :           for(i=0;i<m;i++) {
+    1702           0 :             temp = alpha * b[j*(ldb)+i];
+    1703           0 :             for(k=0;k<i;k++)
+    1704           0 :               temp -= a[i*(lda)+k] * b[j*(ldb)+k];
+    1705           0 :             if(xdiag=='N')
+    1706           0 :                 temp /= a[i*(lda)+i];
+    1707           0 :             b[j*(ldb)+i] = temp;
+    1708             :           }
+    1709             :         }
+    1710             :       } else {
+    1711             :         /* lower */
+    1712           0 :         for(j=0;j<n;j++) {
+    1713           0 :           for(i=m-1;i>=0;i--) {
+    1714           0 :             temp = alpha * b[j*(ldb)+i];
+    1715           0 :             for(k=i+1;k<m;k++)
+    1716           0 :               temp -= a[i*(lda)+k] * b[j*(ldb)+k];
+    1717           0 :             if(xdiag=='N')
+    1718           0 :                 temp /= a[i*(lda)+i];
+    1719           0 :             b[j*(ldb)+i] = temp;
+    1720             :           }
+    1721             :         }
+    1722             :       }
+    1723             :     }
+    1724             :   } else {
+    1725             :     /* right side */
+    1726           0 :     if(xtrans=='N') {
+    1727             :       /* No transpose */
+    1728           0 :       if(xuplo=='U') {
+    1729             :         /* upper */
+    1730           0 :         for(j=0;j<n;j++) {
+    1731           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_DOUBLE_EPS)
+    1732           0 :             for(i=0;i<m;i++)
+    1733           0 :               b[j*(ldb)+i] *= alpha;
+    1734           0 :           for(k=0;k<j;k++) {
+    1735           0 :             if(std::abs(a[j*(lda)+k])>PLUMED_GMX_DOUBLE_MIN) {
+    1736           0 :               for(i=0;i<m;i++)
+    1737           0 :                 b[j*(ldb)+i] -= a[j*(lda)+k]*b[k*(ldb)+i];
+    1738             :             }
+    1739             :           }
+    1740           0 :           if(xdiag=='N') {
+    1741           0 :             temp = 1.0/a[j*(lda)+j];
+    1742           0 :             for(i=0;i<m;i++)
+    1743           0 :               b[j*(ldb)+i] *= temp;
+    1744             :           }
+    1745             :         }
+    1746             :       } else {
+    1747             :         /* lower */
+    1748           0 :         for(j=n-1;j>=0;j--) {
+    1749           0 :           if(std::abs(alpha)>PLUMED_GMX_DOUBLE_MIN)
+    1750           0 :             for(i=0;i<m;i++)
+    1751           0 :               b[j*(ldb)+i] *= alpha;
+    1752           0 :           for(k=j+1;k<n;k++) {
+    1753           0 :             if(std::abs(a[j*(lda)+k])>PLUMED_GMX_DOUBLE_MIN) {
+    1754           0 :               for(i=0;i<m;i++)
+    1755           0 :                 b[j*(ldb)+i] -= a[j*(lda)+k]*b[k*(ldb)+i];
+    1756             :             }
+    1757             :           }
+    1758           0 :           if(xdiag=='N') {
+    1759           0 :             temp = 1.0/a[j*(lda)+j];
+    1760           0 :             for(i=0;i<m;i++)
+    1761           0 :               b[j*(ldb)+i] *= temp;
+    1762             :           }
+    1763             :         }
+    1764             :       }
+    1765             :     } else {
+    1766             :       /* Transpose */
+    1767           0 :       if(xuplo=='U') {
+    1768             :         /* upper */
+    1769           0 :         for(k=n-1;k>=0;k--) {
+    1770           0 :           if(xdiag=='N') {
+    1771           0 :             temp = 1.0/a[k*(lda)+k];
+    1772           0 :             for(i=0;i<m;i++)
+    1773           0 :               b[k*(ldb)+i] *= temp;
+    1774             :           }
+    1775           0 :           for(j=0;j<k;j++) {
+    1776           0 :             if(std::abs(a[k*(lda)+j])>PLUMED_GMX_DOUBLE_MIN) {
+    1777             :               temp = a[k*(lda)+j];
+    1778           0 :               for(i=0;i<m;i++)
+    1779           0 :                 b[j*(ldb)+i] -= temp * b[k*(ldb)+i];
+    1780             :             }
+    1781             :           }
+    1782           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_DOUBLE_EPS)
+    1783           0 :             for(i=0;i<m;i++)
+    1784           0 :               b[k*(ldb)+i] *= alpha;
+    1785             :         }
+    1786             :       } else {
+    1787             :         /* lower */
+    1788           0 :         for(k=0;k<n;k++) {
+    1789           0 :           if(xdiag=='N') {
+    1790           0 :             temp = 1.0/a[k*(lda)+k];
+    1791           0 :             for(i=0;i<m;i++)
+    1792           0 :               b[k*(ldb)+i] *= temp;
+    1793             :           }
+    1794           0 :           for(j=k+1;j<n;j++) {
+    1795           0 :             if(std::abs(a[k*(lda)+j])>PLUMED_GMX_DOUBLE_MIN) {
+    1796             :               temp = a[k*(lda)+j];
+    1797           0 :               for(i=0;i<m;i++)
+    1798           0 :                 b[j*(ldb)+i] -= temp * b[k*(ldb)+i];
+    1799             :             }
+    1800             :           }
+    1801           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_DOUBLE_EPS)
+    1802           0 :             for(i=0;i<m;i++)
+    1803           0 :               b[k*(ldb)+i] *= alpha;
+    1804             :         }
+    1805             :       }      
+    1806             :     }
+    1807             :   }    
+    1808             : }
+    1809             : }
+    1810             : }
+    1811             : #include <cmath>
+    1812             : #include "blas.h"
+    1813             : 
+    1814             : namespace PLMD{
+    1815             : namespace blas{
+    1816             : int
+    1817         114 : PLUMED_BLAS_F77_FUNC(idamax,IDAMAX)(int *n__,
+    1818             :                         double *dx,
+    1819             :                         int *incx__)
+    1820             : {
+    1821             :   int i,ix,idxmax;
+    1822             :   double dmax,tmp;
+    1823             : 
+    1824         114 :   int n    = *n__;
+    1825         114 :   int incx = *incx__;
+    1826             :   
+    1827         114 :   if(n<1 || incx<=0)
+    1828             :     return -1;
+    1829             : 
+    1830         114 :   if(n==1)
+    1831             :     return 1;
+    1832             : 
+    1833          57 :   dmax = std::abs(dx[0]);
+    1834             :   idxmax = 1;
+    1835             : 
+    1836          57 :   if(incx==1) {
+    1837         114 :     for(i=1;i<n;i++) {
+    1838          57 :       tmp = std::abs(dx[i]);
+    1839          57 :       if(tmp>dmax) {
+    1840             :         dmax = tmp;
+    1841           0 :         idxmax = i+1;
+    1842             :       }
+    1843             :     }
+    1844             :   } else {
+    1845             :     /* Non-unit increments */
+    1846             :     ix = incx; /* this is really 0 + an increment */
+    1847           0 :     for(i=1;i<n;i++,ix+=incx) {
+    1848           0 :       tmp = std::abs(dx[ix]);
+    1849           0 :       if(tmp>dmax) {
+    1850             :         dmax = tmp;
+    1851           0 :         idxmax = ix+1;
+    1852             :       }
+    1853             :     }    
+    1854             :   }
+    1855             :   return idxmax;
+    1856             : }
+    1857             : }
+    1858             : }
+    1859             : #include <cmath>
+    1860             : #include "blas.h"
+    1861             : 
+    1862             : namespace PLMD{
+    1863             : namespace blas{
+    1864             : int
+    1865           0 : PLUMED_BLAS_F77_FUNC(isamax,ISAMAX)(int *n__,
+    1866             :        float *dx,
+    1867             :        int *incx__)
+    1868             : {
+    1869             :   int i,ix,idxmax;
+    1870             :   float dmax,tmp;
+    1871             : 
+    1872           0 :   int n    = *n__;
+    1873           0 :   int incx = *incx__;
+    1874             :   
+    1875           0 :   if(n<1 || incx<=0)
+    1876             :     return -1;
+    1877             : 
+    1878           0 :   if(n==1)
+    1879             :     return 1;
+    1880             : 
+    1881           0 :   dmax = std::abs(dx[0]);
+    1882             :   idxmax = 1;
+    1883             : 
+    1884           0 :   if(incx==1) {
+    1885           0 :     for(i=1;i<n;i++) {
+    1886           0 :       tmp = std::abs(dx[i]);
+    1887           0 :       if(tmp>dmax) {
+    1888             :         dmax = tmp;
+    1889           0 :         idxmax = i+1;
+    1890             :       }
+    1891             :     }
+    1892             :   } else {
+    1893             :     /* Non-unit increments */
+    1894             :     ix = incx; /* this is really 0 + an increment */
+    1895           0 :     for(i=1;i<n;i++,ix+=incx) {
+    1896           0 :       tmp = std::abs(dx[ix]);
+    1897           0 :       if(tmp>dmax) {
+    1898             :         dmax = tmp;
+    1899           0 :         idxmax = ix+1;
+    1900             :       }
+    1901             :     }    
+    1902             :   }
+    1903             :   return idxmax;
+    1904             : }
+    1905             : }
+    1906             : }
+    1907             : #include <cmath>
+    1908             : #include "blas.h"
+    1909             : 
+    1910             : namespace PLMD{
+    1911             : namespace blas{
+    1912             : float
+    1913           0 : PLUMED_BLAS_F77_FUNC(sasum,SASUM)(int *n__, 
+    1914             :        float *dx, 
+    1915             :        int *incx__)
+    1916             : {
+    1917             :     int i__1, i__2;
+    1918             :     
+    1919             :     int i__, m, mp1;
+    1920             :     float dtemp;
+    1921             :     int nincx;
+    1922             :     
+    1923           0 :     int n = *n__;
+    1924           0 :     int incx = *incx__;
+    1925             :     
+    1926             :     
+    1927           0 :     --dx;
+    1928             :     
+    1929             :     dtemp = 0.;
+    1930           0 :     if (n <= 0 || incx <= 0) {
+    1931             :         return 0.0;
+    1932             :     }
+    1933           0 :     if (incx != 1) {
+    1934           0 :         nincx = n * incx;
+    1935             :         i__1 = nincx;
+    1936             :         i__2 = incx;
+    1937           0 :         for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+    1938           0 :             dtemp += std::abs(dx[i__]);
+    1939             :         }
+    1940             :         return dtemp;
+    1941             :     }
+    1942             :     
+    1943           0 :     m = n % 6;
+    1944           0 :     if (m != 0) {
+    1945             :         i__2 = m;
+    1946           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    1947           0 :             dtemp += std::abs(dx[i__]);
+    1948             :         }
+    1949           0 :         if (n < 6) {
+    1950             :             return dtemp;
+    1951             :         }
+    1952             :     }
+    1953           0 :     mp1 = m + 1;
+    1954             :     i__2 = n;
+    1955           0 :     for (i__ = mp1; i__ <= i__2; i__ += 6) {
+    1956           0 :         dtemp = dtemp + std::abs(dx[i__]) + std::abs(dx[i__ + 1]) + 
+    1957           0 :         std::abs(dx[i__ + 2]) + std::abs(dx[i__+ 3]) + std::abs(dx[i__ + 4]) +
+    1958           0 :         std::abs(dx[i__ + 5]);
+    1959             :     }
+    1960             :     return dtemp;
+    1961             : }
+    1962             : 
+    1963             : 
+    1964             : }
+    1965             : }
+    1966             : #include "blas.h"
+    1967             : 
+    1968             : 
+    1969             : namespace PLMD{
+    1970             : namespace blas{
+    1971             : void
+    1972           0 : PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(int   *   n_arg,
+    1973             :                       float *   da_arg,
+    1974             :                       float *   dx,
+    1975             :                       int *      incx_arg,
+    1976             :                       float *   dy,
+    1977             :                       int *      incy_arg)
+    1978             : {
+    1979             :   int i,ix,iy;
+    1980           0 :   int n=*n_arg;
+    1981           0 :   float da=*da_arg;
+    1982           0 :   int incx = *incx_arg;
+    1983           0 :   int incy = *incy_arg;
+    1984             : 
+    1985           0 :   if (n<=0)
+    1986             :     return;
+    1987             : 
+    1988           0 :   if(incx!=1 || incy!=1) {
+    1989             :     ix = 0;
+    1990             :     iy = 0;
+    1991           0 :     if(incx<0)
+    1992           0 :       ix = (1-n)*incx;
+    1993           0 :     if(incy<0)
+    1994           0 :       iy = (1-n)*incy;
+    1995             :     
+    1996           0 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) 
+    1997           0 :       dy[iy] += da*dx[ix];
+    1998             : 
+    1999             :     return;
+    2000             : 
+    2001             :   } else {
+    2002             : 
+    2003             :     /* unroll */
+    2004             :     
+    2005           0 :     for(i=0;i<(n-4);i+=4) {
+    2006           0 :       dy[i]   += da*dx[i];
+    2007           0 :       dy[i+1] += da*dx[i+1];
+    2008           0 :       dy[i+2] += da*dx[i+2];
+    2009           0 :       dy[i+3] += da*dx[i+3];
+    2010             :     }
+    2011             :     /* continue with current value of i */
+    2012           0 :     for(;i<n;i++)
+    2013           0 :       dy[i]   += da*dx[i];
+    2014             :   }
+    2015             : }
+    2016             : }
+    2017             : }
+    2018             : #include "blas.h"
+    2019             : 
+    2020             : namespace PLMD{
+    2021             : namespace blas{
+    2022             : void
+    2023           0 : PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(int *n__,
+    2024             :                       float *dx,
+    2025             :                       int *incx__,
+    2026             :                       float *dy,
+    2027             :                       int *incy__)
+    2028             : {
+    2029             :     int i,ix,iy;
+    2030             : 
+    2031           0 :     int n= *n__;
+    2032           0 :     int incx = *incx__;
+    2033           0 :     int incy = *incy__;
+    2034             :     
+    2035           0 :     if(incx!=1 || incy!=1) 
+    2036             :     {
+    2037             :         ix = 0;
+    2038             :         iy = 0;
+    2039           0 :         if(incx<0)
+    2040           0 :             ix = (1-n)*(incx);
+    2041           0 :         if(incy<0)
+    2042           0 :             iy = (1-n)*(incy);
+    2043             :         
+    2044           0 :         for(i=0;i<n;i++,ix+=incx,iy+=incy) 
+    2045           0 :             dy[iy] = dx[ix];
+    2046             :         
+    2047             :         return;
+    2048             :         
+    2049             :     } else {
+    2050             :         
+    2051             :         /* unroll */
+    2052             :         
+    2053           0 :         for(i=0;i<(n-8);i+=8) {
+    2054           0 :             dy[i]   = dx[i];
+    2055           0 :             dy[i+1] = dx[i+1];
+    2056           0 :             dy[i+2] = dx[i+2];
+    2057           0 :             dy[i+3] = dx[i+3];
+    2058           0 :             dy[i+4] = dx[i+4];
+    2059           0 :             dy[i+5] = dx[i+5];
+    2060           0 :             dy[i+6] = dx[i+6];
+    2061           0 :             dy[i+7] = dx[i+7];
+    2062             :         }
+    2063             :         /* continue with current value of i */
+    2064           0 :         for(;i<n;i++)
+    2065           0 :             dy[i] = dx[i];
+    2066             :     }
+    2067             : }
+    2068             : }
+    2069             : }
+    2070             : #include "blas.h"
+    2071             : 
+    2072             : 
+    2073             : namespace PLMD{
+    2074             : namespace blas{
+    2075             : float
+    2076           1 : PLUMED_BLAS_F77_FUNC(sdot,SDOT)(int *n_arg,
+    2077             :                     float *dx,
+    2078             :                     int *incx_arg,
+    2079             :                     float *dy,
+    2080             :                     int *incy_arg)
+    2081             : {
+    2082             :     int i,ix,iy,m;
+    2083           1 :     int n=*n_arg;
+    2084           1 :     int incx = *incx_arg;
+    2085           1 :     int incy = *incy_arg;
+    2086             :     float t1;
+    2087             :     
+    2088           1 :     if(n<=0)
+    2089             :         return 0.0;
+    2090             :     
+    2091             :     t1 = 0.0;
+    2092             :     
+    2093           1 :     if(incx!=1 || incy!=1) {
+    2094             :         ix = 0;
+    2095             :         iy = 0;
+    2096           0 :         if(incx<0)
+    2097           0 :             ix = (1-n)*incx;
+    2098           0 :         if(incy<0)
+    2099           0 :             iy = (1-n)*incy;
+    2100             :         
+    2101           0 :         for(i=0;i<n;i++,ix+=incx,iy+=incy) 
+    2102           0 :             t1 += dx[ix] * dy[iy];
+    2103             :         
+    2104             :         return t1;
+    2105             :         
+    2106             :     } else {
+    2107             :         
+    2108           1 :         m = n%5;
+    2109             :         
+    2110           1 :         for(i=0;i<m;i++)
+    2111           0 :             t1 += dx[i] * dy[i];
+    2112             :         
+    2113             :         /* unroll */
+    2114           2 :         for(i=m;i<n;i+=5) 
+    2115           1 :             t1  =  t1 + dx[i] * dy[i]   
+    2116           1 :                 +    dx[i+1] * dy[i+1] 
+    2117           1 :                 +    dx[i+2] * dy[i+2] 
+    2118           1 :                 +    dx[i+3] * dy[i+3]   
+    2119           1 :                 +    dx[i+4] * dy[i+4];   
+    2120             :         
+    2121             :         return t1;
+    2122             :     }
+    2123             : }
+    2124             : 
+    2125             : 
+    2126             : }
+    2127             : }
+    2128             : #include <cctype>
+    2129             : #include <cmath>
+    2130             : 
+    2131             : #include "real.h"
+    2132             : #include "blas.h"
+    2133             : 
+    2134             : namespace PLMD{
+    2135             : namespace blas{
+    2136             : void
+    2137           0 : PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)(const char *transa,
+    2138             :        const char *transb,
+    2139             :        int *m__,
+    2140             :        int *n__,
+    2141             :        int *k__,
+    2142             :        float *alpha__,
+    2143             :        float *a,
+    2144             :        int *lda__,
+    2145             :        float *b,
+    2146             :        int *ldb__,
+    2147             :        float *beta__,
+    2148             :        float *c,
+    2149             :        int *ldc__)
+    2150             : {
+    2151           0 :   const char tra=std::toupper(*transa);
+    2152           0 :   const char trb=std::toupper(*transb);
+    2153             :   float temp;
+    2154             :   int i,j,l;
+    2155             : 
+    2156           0 :   int m   = *m__;
+    2157           0 :   int n   = *n__;
+    2158           0 :   int k   = *k__;
+    2159           0 :   int lda = *lda__;
+    2160           0 :   int ldb = *ldb__;
+    2161           0 :   int ldc = *ldc__;
+    2162             :   
+    2163           0 :   float alpha = *alpha__;
+    2164           0 :   float beta  = *beta__;
+    2165             :   
+    2166           0 :   if(m==0 || n==0 || (( std::abs(alpha)<PLUMED_GMX_FLOAT_MIN || k==0) && std::abs(beta-1.0)<PLUMED_GMX_FLOAT_EPS))
+    2167             :     return;
+    2168             : 
+    2169           0 :   if(std::abs(alpha)<PLUMED_GMX_FLOAT_MIN) {
+    2170           0 :     if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) {
+    2171           0 :       for(j=0;j<n;j++)
+    2172           0 :         for(i=0;i<m;i++)
+    2173           0 :           c[j*(ldc)+i] = 0.0;
+    2174             :     } else {
+    2175             :       /* nonzero beta */
+    2176           0 :       for(j=0;j<n;j++)
+    2177           0 :         for(i=0;i<m;i++)
+    2178           0 :           c[j*(ldc)+i] *= beta;
+    2179             :     }
+    2180           0 :     return;
+    2181             :   }
+    2182             : 
+    2183           0 :   if(trb=='N') {
+    2184           0 :     if(tra=='N') {
+    2185             :       
+    2186           0 :       for(j=0;j<n;j++) {
+    2187           0 :         if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) {
+    2188           0 :           for(i=0;i<m;i++)
+    2189           0 :             c[j*(ldc)+i] = 0.0;
+    2190           0 :         } else if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    2191           0 :           for(i=0;i<m;i++)
+    2192           0 :             c[j*(ldc)+i] *= beta;
+    2193             :         } 
+    2194           0 :         for(l=0;l<k;l++) {
+    2195           0 :           if( std::abs(b[ j*(ldb) + l ])>PLUMED_GMX_FLOAT_MIN) {
+    2196           0 :             temp = alpha * b[ j*(ldb) + l ];
+    2197           0 :             for(i=0;i<m;i++)
+    2198           0 :               c[j*(ldc)+i] += temp * a[l*(lda)+i]; 
+    2199             :           }
+    2200             :         }
+    2201             :       }
+    2202             :     } else {
+    2203             :       /* transpose A, but not B */
+    2204           0 :       for(j=0;j<n;j++) {
+    2205           0 :         for(i=0;i<m;i++) {
+    2206             :           temp = 0.0;
+    2207           0 :           for(l=0;l<k;l++) 
+    2208           0 :             temp += a[i*(lda)+l] * b[j*(ldb)+l];
+    2209           0 :           if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    2210           0 :             c[j*(ldc)+i] = alpha * temp;
+    2211             :           else
+    2212           0 :             c[j*(ldc)+i] = alpha * temp + beta * c[j*(ldc)+i];
+    2213             :         }
+    2214             :       }
+    2215             :     }
+    2216             :   } else {
+    2217             :     /* transpose B */
+    2218           0 :     if(tra=='N') {
+    2219             : 
+    2220             :       /* transpose B, but not A */
+    2221             : 
+    2222           0 :       for(j=0;j<n;j++) {
+    2223           0 :         if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) {
+    2224           0 :           for(i=0;i<m;i++)
+    2225           0 :             c[j*(ldc)+i] = 0.0;
+    2226           0 :         } else if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    2227           0 :           for(i=0;i<m;i++)
+    2228           0 :             c[j*(ldc)+i] *= beta;
+    2229             :         } 
+    2230           0 :         for(l=0;l<k;l++) {
+    2231           0 :           if( std::abs(b[ l*(ldb) + j ])>PLUMED_GMX_FLOAT_MIN) {
+    2232           0 :             temp = alpha * b[ l*(ldb) + j ];
+    2233           0 :             for(i=0;i<m;i++)
+    2234           0 :               c[j*(ldc)+i] += temp * a[l*(lda)+i]; 
+    2235             :           }
+    2236             :         }
+    2237             :       }
+    2238             :  
+    2239             :     } else {
+    2240             :       /* Transpose both A and B */
+    2241           0 :        for(j=0;j<n;j++) {
+    2242           0 :         for(i=0;i<m;i++) {
+    2243             :           temp = 0.0;
+    2244           0 :           for(l=0;l<k;l++) 
+    2245           0 :             temp += a[i*(lda)+l] * b[l*(ldb)+j];
+    2246           0 :           if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    2247           0 :             c[j*(ldc)+i] = alpha * temp;
+    2248             :           else
+    2249           0 :             c[j*(ldc)+i] = alpha * temp + beta * c[j*(ldc)+i];
+    2250             :         }
+    2251             :        }
+    2252             :     }
+    2253             :   }
+    2254             : }
+    2255             : }
+    2256             : }
+    2257             : #include <cctype>
+    2258             : #include <cmath>
+    2259             : 
+    2260             : #include "real.h"
+    2261             : #include "blas.h"
+    2262             : 
+    2263             : namespace PLMD{
+    2264             : namespace blas{
+    2265             : void
+    2266           0 : PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)(const char *trans, 
+    2267             :                       int *m__,
+    2268             :                       int *n__,
+    2269             :                       float *alpha__,
+    2270             :                       float *a,
+    2271             :                       int *lda__,
+    2272             :                       float *x,
+    2273             :                       int *incx__,
+    2274             :                       float *beta__,
+    2275             :                       float *y,
+    2276             :                       int *incy__)
+    2277             : {
+    2278           0 :   const char ch=std::toupper(*trans);
+    2279             :   int lenx,leny,kx,ky;
+    2280             :   int i,j,jx,jy,ix,iy;
+    2281             :   float temp;
+    2282             : 
+    2283           0 :   int m = *m__;
+    2284           0 :   int n = *n__;
+    2285           0 :   float alpha = *alpha__;
+    2286           0 :   float beta = *beta__;
+    2287           0 :   int incx = *incx__;
+    2288           0 :   int incy = *incy__;
+    2289           0 :   int lda = *lda__;
+    2290             :   
+    2291           0 :   if(n<=0 || m<=0 || (std::abs(alpha)<PLUMED_GMX_FLOAT_MIN && std::abs(beta-1.0)<PLUMED_GMX_FLOAT_EPS))
+    2292             :     return;
+    2293             : 
+    2294           0 :   if(ch=='N') {
+    2295             :     lenx = n;
+    2296             :     leny = m;
+    2297             :   } else {
+    2298             :     lenx = m;
+    2299             :     leny = n;
+    2300             :   }
+    2301             :   
+    2302           0 :    if(incx>0)
+    2303             :     kx = 1;
+    2304             :   else
+    2305           0 :     kx = 1 - (lenx -1)*(incx);
+    2306             : 
+    2307           0 :   if(incy>0)
+    2308             :     ky = 1;
+    2309             :   else
+    2310           0 :     ky = 1 - (leny -1)*(incy);
+    2311             :  
+    2312           0 :   if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    2313           0 :     if(incy==1) {
+    2314           0 :       if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    2315           0 :         for(i=0;i<leny;i++)
+    2316           0 :           y[i] = 0.0;
+    2317             :       else
+    2318           0 :         for(i=0;i<leny;i++)
+    2319           0 :           y[i] *= beta;
+    2320             :     } else {
+    2321             :       /* non-unit incr. */
+    2322             :       iy = ky;
+    2323           0 :       if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) 
+    2324           0 :         for(i=0;i<leny;i++,iy+=incy)
+    2325           0 :           y[iy] = 0.0;
+    2326             :       else
+    2327           0 :         for(i=0;i<leny;i++,iy+=incy)
+    2328           0 :           y[iy] *= beta;
+    2329             :     }
+    2330             :   }
+    2331             :   
+    2332           0 :   if(std::abs(alpha)<PLUMED_GMX_FLOAT_MIN)
+    2333             :     return;
+    2334             :   
+    2335           0 :   if(ch=='N') {
+    2336             :     jx = kx;
+    2337           0 :     if(incy==1) {
+    2338           0 :       for(j=1;j<=n;j++,jx+=incx) 
+    2339           0 :         if( std::abs(x[jx-1])>PLUMED_GMX_FLOAT_MIN) {
+    2340           0 :           temp = alpha * x[jx-1];
+    2341           0 :           for(i=1;i<=m;i++)
+    2342           0 :             y[i-1] += temp * a[(j-1)*(lda)+(i-1)];
+    2343             :         }
+    2344             :     } else {
+    2345             :       /* non-unit y incr. */
+    2346           0 :       for(j=1;j<=n;j++,jx+=incx) 
+    2347           0 :         if( std::abs(x[jx-1])>PLUMED_GMX_FLOAT_MIN) {
+    2348           0 :           temp = alpha * x[jx-1];
+    2349             :           iy = ky;
+    2350           0 :           for(i=1;i<=m;i++,iy+=incy)
+    2351           0 :             y[iy-1] += temp * a[(j-1)*(lda)+(i-1)];
+    2352             :         }
+    2353             :     }
+    2354             :   } else {
+    2355             :     /* transpose */
+    2356             :     jy = ky;
+    2357           0 :     if(incx==1) {
+    2358           0 :       for(j=1;j<=n;j++,jy+=incy) {
+    2359             :         temp = 0.0;
+    2360           0 :         for(i=1;i<=m;i++)
+    2361           0 :           temp += a[(j-1)*(lda)+(i-1)] * x[i-1];
+    2362           0 :         y[jy-1] += alpha * temp;
+    2363             :       }
+    2364             :     } else {
+    2365             :       /* non-unit y incr. */
+    2366           0 :       for(j=1;j<=n;j++,jy+=incy) {
+    2367             :         temp = 0.0;
+    2368             :         ix = kx;
+    2369           0 :         for(i=1;i<=m;i++,ix+=incx)
+    2370           0 :           temp += a[(j-1)*(lda)+(i-1)] * x[ix-1];
+    2371           0 :         y[jy-1] += alpha * temp;
+    2372             :       }
+    2373             :     }
+    2374             :   }
+    2375             : } 
+    2376             :    
+    2377             : }
+    2378             : }
+    2379             : #include <cmath>
+    2380             : 
+    2381             : #include "real.h"
+    2382             : #include "blas.h"
+    2383             : 
+    2384             : namespace PLMD{
+    2385             : namespace blas{
+    2386             : void
+    2387           0 : PLUMED_BLAS_F77_FUNC(sger,SGER)(int *m__,
+    2388             :                     int *n__,
+    2389             :                     float *alpha__,
+    2390             :                     float *x,
+    2391             :                     int *incx__,
+    2392             :                     float *y,
+    2393             :                     int *incy__,
+    2394             :                     float *a,
+    2395             :                     int *lda__)
+    2396             : {
+    2397             :     int ix,kx,jy;
+    2398             :     int i,j;
+    2399             :     float temp;
+    2400             :     
+    2401           0 :     int m = *m__;
+    2402           0 :     int n = *n__;
+    2403           0 :     int incx = *incx__;
+    2404           0 :     int incy = *incy__;
+    2405           0 :     int lda = *lda__;
+    2406           0 :     float alpha = *alpha__;
+    2407             :     
+    2408           0 :     if(m<=0 || n<=0 || std::abs(alpha)<PLUMED_GMX_FLOAT_MIN)
+    2409             :         return;
+    2410             :     
+    2411           0 :     if(incy>0)
+    2412             :         jy = 0;
+    2413             :     else
+    2414           0 :         jy = incy * (1 - n);
+    2415             :     
+    2416           0 :     if(incx==1) {
+    2417           0 :         for(j=0;j<n;j++,jy+=incy)
+    2418           0 :             if(std::abs(y[jy])>PLUMED_GMX_FLOAT_MIN) {
+    2419           0 :                 temp = alpha * y[jy];
+    2420           0 :                 for(i=0;i<m;i++)
+    2421           0 :                     a[j*(lda)+i] += temp*x[i];
+    2422             :             }
+    2423             :     } else {
+    2424             :         /* non-unit incx */
+    2425           0 :         if(incx>0) 
+    2426             :             kx = 0;
+    2427             :         else
+    2428           0 :             kx = incx * (1 - m);
+    2429             :         
+    2430           0 :         for(j=0;j<n;j++,jy+=incy) {
+    2431           0 :             if(std::abs(y[jy])>PLUMED_GMX_FLOAT_MIN) {
+    2432           0 :                 temp = alpha * y[jy];
+    2433             :                 ix = kx;
+    2434           0 :                 for(i=0;i<m;i++,ix+=incx)
+    2435           0 :                     a[j*(lda)+i] += temp*x[ix];
+    2436             :             }
+    2437             :         }
+    2438             :     }
+    2439             :         return;
+    2440             : }
+    2441             : }
+    2442             : }
+    2443             : #include <cmath>
+    2444             : 
+    2445             : 
+    2446             : #include "real.h"
+    2447             : #include "blas.h"
+    2448             : 
+    2449             : namespace PLMD{
+    2450             : namespace blas{
+    2451             : float
+    2452           0 : PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(int  *     n__,
+    2453             :                       float *    x,
+    2454             :                       int    *    incx__)
+    2455             : {
+    2456             :     int ix,max_ix;
+    2457             :     float ssq,scale,absxi,t;
+    2458             :     
+    2459           0 :     int n = *n__;
+    2460           0 :     int incx = *incx__;
+    2461             :     
+    2462           0 :     if(n<1 || incx<1)
+    2463             :         return 0;
+    2464           0 :     else if (n==1) {
+    2465           0 :         t = x[0];
+    2466           0 :         if(t>=0)
+    2467             :             return t;
+    2468             :         else 
+    2469           0 :             return -t;
+    2470             :     }
+    2471             :     
+    2472             :     scale = 0.0;
+    2473             :     ssq   = 1.0;
+    2474             :     
+    2475           0 :     max_ix = 1+(n-1)*(incx);
+    2476           0 :     for(ix=1;ix<=max_ix;ix+=incx) {
+    2477           0 :         t = x[ix-1];
+    2478           0 :         if(std::abs(t)>PLUMED_GMX_FLOAT_MIN) {
+    2479           0 :             absxi = (t>=0) ? t : (-t);
+    2480           0 :             if(scale<absxi) {
+    2481           0 :                 t = scale/absxi;
+    2482           0 :                 t = t*t;
+    2483           0 :                 ssq = ssq*t + 1.0;
+    2484             :                 scale = absxi;
+    2485             :             } else {
+    2486           0 :                 t = absxi/scale;
+    2487           0 :                 ssq += t*t;
+    2488             :             }
+    2489             :         }
+    2490             :     }
+    2491           0 :     return scale*std::sqrt(ssq);
+    2492             :     
+    2493             : }
+    2494             : 
+    2495             : 
+    2496             :  
+    2497             : }
+    2498             : }
+    2499             : #include "blas.h"
+    2500             : 
+    2501             : namespace PLMD{
+    2502             : namespace blas{
+    2503             : void
+    2504           0 : PLUMED_BLAS_F77_FUNC(srot,SROT)(int *n__,
+    2505             :                     float *dx,
+    2506             :                     int *incx__,
+    2507             :                     float *dy,
+    2508             :                     int *incy__,
+    2509             :                     float *c__,
+    2510             :                     float *s__)
+    2511             : {
+    2512             :   int i,ix,iy;
+    2513             :   float dtemp;
+    2514             : 
+    2515           0 :   int n = *n__;
+    2516           0 :   int incx = *incx__;
+    2517           0 :   int incy = *incy__;
+    2518           0 :   float c = *c__;
+    2519           0 :   float s = *s__;
+    2520             :   
+    2521           0 :   if(incx!=1 || incy!=1) {
+    2522             :     ix = 0;
+    2523             :     iy = 0;
+    2524           0 :     if(incx<0)
+    2525           0 :       ix = (1-n)*(incx);
+    2526           0 :     if(incy<0)
+    2527           0 :       iy = (1-n)*(incy);
+    2528             :     
+    2529           0 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) {
+    2530           0 :       dtemp  = (c) * dx[ix] + (s) * dy[iy];
+    2531           0 :       dy[iy] = (c) * dy[iy] - (s) * dx[ix];
+    2532           0 :       dx[ix] = dtemp;
+    2533             :     }
+    2534             : 
+    2535             :     return;
+    2536             : 
+    2537             :   } else {
+    2538             : 
+    2539             :     /* unit increments */   
+    2540           0 :     for(i=0;i<n;i++) {
+    2541           0 :       dtemp = (c) * dx[i] + (s) * dy[i];
+    2542           0 :       dy[i] = (c) * dy[i] - (s) * dx[i];
+    2543           0 :       dx[i] = dtemp;      
+    2544             :     }
+    2545             : 
+    2546             :   }
+    2547             : }
+    2548             : }
+    2549             : }
+    2550             : #include "blas.h"
+    2551             : 
+    2552             : namespace PLMD{
+    2553             : namespace blas{
+    2554             : void 
+    2555           0 : PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(int  *n__,
+    2556             :                       float *fact__,
+    2557             :                       float *dx,
+    2558             :                       int   *incx__)
+    2559             : {
+    2560             :     int nincx,i;
+    2561             : 
+    2562           0 :     int n = *n__;
+    2563           0 :     float fact = *fact__;
+    2564           0 :     int incx = *incx__;
+    2565             :     
+    2566           0 :     if(n<=0 || incx<=0)
+    2567             :         return;
+    2568             :     
+    2569           0 :     if(incx==1) {
+    2570             :         /* Unrool factor 5 */
+    2571           0 :         for(i=0;i<(n-5);i+=5) {
+    2572           0 :             dx[i]   *= fact;
+    2573           0 :             dx[i+1] *= fact;
+    2574           0 :             dx[i+2] *= fact;
+    2575           0 :             dx[i+3] *= fact;
+    2576           0 :             dx[i+4] *= fact;
+    2577             :         }    
+    2578             :         /* continue with current value of i */
+    2579           0 :         for(;i<n;i++)
+    2580           0 :             dx[i]   *= fact;
+    2581             :         
+    2582             :         return;
+    2583             :     } else {
+    2584             :         /* inc != 1 */
+    2585           0 :         nincx = n * (incx);
+    2586           0 :         for (i=0;i<nincx;i+=incx)
+    2587           0 :             dx[i] *= fact;
+    2588             :         
+    2589             :         return;
+    2590             :     } 
+    2591             :     
+    2592             : }
+    2593             : }
+    2594             : }
+    2595             : #include "blas.h"
+    2596             : 
+    2597             : namespace PLMD{
+    2598             : namespace blas{
+    2599             : void
+    2600           0 : PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(int *n__,
+    2601             :                       float *dx,
+    2602             :                       int *incx__,
+    2603             :                       float *dy,
+    2604             :                       int *incy__)
+    2605             : {
+    2606             :   int i,ix,iy;
+    2607             :   float d1,d2,d3;
+    2608             : 
+    2609           0 :   int n = *n__;
+    2610           0 :   int incx = *incx__;
+    2611           0 :   int incy = *incy__;
+    2612             :   
+    2613           0 :   if(n<=0)
+    2614             :     return;
+    2615             : 
+    2616           0 :   if(incx==1 && incy==1) {
+    2617           0 :     for(i=0;i<(n-3);i+=3) {
+    2618           0 :       d1      = dx[i];
+    2619           0 :       d2      = dx[i+1];
+    2620           0 :       d3      = dx[i+2];
+    2621           0 :       dx[i]   = dy[i];
+    2622           0 :       dx[i+1] = dy[i+1];
+    2623           0 :       dx[i+2] = dy[i+2];
+    2624           0 :       dy[i]   = d1;
+    2625           0 :       dy[i+1] = d2;
+    2626           0 :       dy[i+2] = d3;
+    2627             :     }
+    2628             :     /* continue with last i value */
+    2629           0 :     for(;i<n;i++) {
+    2630           0 :       d1      = dx[i];
+    2631           0 :       dx[i]   = dy[i];
+    2632           0 :       dy[i]   = d1;
+    2633             :     }
+    2634             : 
+    2635             :   } else {
+    2636             :     ix = 0;
+    2637             :     iy = 0;
+    2638           0 :     if(incx<0)
+    2639           0 :       ix = incx * (1 - n);
+    2640           0 :     if(incy<0)
+    2641           0 :       iy = incy * (1 - n);
+    2642             : 
+    2643           0 :     for(i=0;i<n;i++,ix+=incx,iy+=incy) {
+    2644           0 :       d1     = dx[ix];
+    2645           0 :       dx[ix] = dy[iy];
+    2646           0 :       dy[iy] = d1;
+    2647             :     }
+    2648             :   }
+    2649             :   return;
+    2650             : }
+    2651             :  
+    2652             : }
+    2653             : }
+    2654             : #include <cctype>
+    2655             : #include <cmath>
+    2656             : 
+    2657             : #include "real.h"
+    2658             : #include "blas.h"
+    2659             : 
+    2660             : namespace PLMD{
+    2661             : namespace blas{
+    2662             : void
+    2663           0 : PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)(const char *uplo,
+    2664             :                       int *n__,
+    2665             :                       float *alpha__,
+    2666             :                       float *a,
+    2667             :                       int *lda__,
+    2668             :                       float *x,
+    2669             :                       int *incx__,
+    2670             :                       float *beta__,
+    2671             :                       float *y,
+    2672             :                       int *incy__)
+    2673             : {
+    2674           0 :     const char ch=std::toupper(*uplo);
+    2675             :     int kx,ky,i,j,ix,iy,jx,jy;
+    2676             :     float temp1,temp2;
+    2677             :     
+    2678           0 :     int n = *n__;
+    2679           0 :     int lda = *lda__;
+    2680           0 :     int incx = *incx__;
+    2681           0 :     int incy = *incy__;
+    2682           0 :     float alpha = *alpha__;
+    2683           0 :     float beta  = *beta__;
+    2684             :     
+    2685           0 :     if(n<=0 || incx==0 || incy==0)
+    2686             :         return;
+    2687             :     
+    2688           0 :     if(incx>0)
+    2689             :         kx = 1;
+    2690             :     else
+    2691           0 :         kx = 1 - (n -1)*(incx);
+    2692             :     
+    2693           0 :     if(incy>0)
+    2694             :         ky = 1;
+    2695             :     else
+    2696           0 :         ky = 1 - (n -1)*(incy);
+    2697             :     
+    2698           0 :     if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    2699           0 :         if(incy==1) {
+    2700           0 :             if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) 
+    2701           0 :                 for(i=1;i<=n;i++)
+    2702           0 :                     y[i-1] = 0.0;
+    2703             :             else
+    2704           0 :                 for(i=1;i<=n;i++)
+    2705           0 :                     y[i-1] *= beta;
+    2706             :         } else {
+    2707             :             /* non-unit incr. */
+    2708             :             iy = ky;
+    2709           0 :             if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) 
+    2710           0 :                 for(i=1;i<=n;i++) {
+    2711           0 :                     y[iy-1] = 0.0;
+    2712           0 :                     iy += incy;
+    2713             :                 }
+    2714             :                     else
+    2715           0 :                         for(i=1;i<=n;i++) {
+    2716           0 :                             y[iy-1] *= beta;
+    2717           0 :                             iy += incy;
+    2718             :                         }
+    2719             :         }
+    2720             :     }
+    2721             :         
+    2722           0 :         if(std::abs(alpha)<PLUMED_GMX_FLOAT_MIN) 
+    2723             :             return;
+    2724             :         
+    2725           0 :         if(ch=='U') {
+    2726           0 :             if(incx==1 && incy==1) {
+    2727           0 :                 for(j=1;j<=n;j++) {
+    2728           0 :                     temp1 = alpha * x[j-1];
+    2729             :                     temp2 = 0.0;
+    2730           0 :                     for(i=1;i<j;i++) {
+    2731           0 :                         y[i-1] += temp1*a[(j-1)*(lda)+(i-1)];
+    2732           0 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[i-1];
+    2733             :                     }
+    2734           0 :                     y[j-1] += temp1*a[(j-1)*(lda)+(j-1)] + alpha *temp2;
+    2735             :                 }
+    2736             :             } else {
+    2737             :                 /* non-unit incr. */
+    2738             :                 jx = kx;
+    2739             :                 jy = ky;
+    2740           0 :                 for(j=1;j<=n;j++) {
+    2741           0 :                     temp1 = alpha * x[jx-1];
+    2742             :                     temp2 = 0.0;
+    2743             :                     ix = kx;
+    2744             :                     iy = ky;
+    2745           0 :                     for(i=1;i<j;i++) {
+    2746           0 :                         y[iy-1] += temp1 * a[(j-1)*(lda)+(i-1)];
+    2747           0 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[ix-1];
+    2748           0 :                         ix += incx;
+    2749           0 :                         iy += incy;
+    2750             :                     }
+    2751           0 :                     y[jy-1] += temp1*a[(j-1)*(lda)+(j-1)] + alpha*temp2;
+    2752           0 :                     jx += incx;
+    2753           0 :                     jy += incy;
+    2754             :                 }
+    2755             :             }
+    2756             :         } else {
+    2757             :             /* lower */
+    2758           0 :             if(incx==1 && incy==1) {
+    2759           0 :                 for(j=1;j<=n;j++) {
+    2760           0 :                     temp1 = alpha * x[j-1];
+    2761             :                     temp2 = 0.0;
+    2762           0 :                     y[j-1] += temp1 * a[(j-1)*(lda)+(j-1)];
+    2763           0 :                     for(i=j+1;i<=n;i++) {
+    2764           0 :                         y[i-1] += temp1*a[(j-1)*(lda)+(i-1)];
+    2765           0 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[i-1];
+    2766             :                     }
+    2767           0 :                     y[j-1] += alpha *temp2;
+    2768             :                 }
+    2769             :             } else {
+    2770             :                 /* non-unit incr. */
+    2771             :                 jx = kx;
+    2772             :                 jy = ky;
+    2773           0 :                 for(j=1;j<=n;j++) {
+    2774           0 :                     temp1 = alpha * x[jx-1];
+    2775             :                     temp2 = 0.0;
+    2776           0 :                     y[jy-1] += temp1 * a[(j-1)*(lda)+(j-1)];
+    2777             :                     ix = jx;
+    2778             :                     iy = jy;
+    2779           0 :                     for(i=j+1;i<=n;i++) {
+    2780           0 :                         ix += incx;
+    2781           0 :                         iy += incy;
+    2782           0 :                         y[iy-1] += temp1 * a[(j-1)*(lda)+(i-1)];
+    2783           0 :                         temp2 += a[(j-1)*(lda)+(i-1)] * x[ix-1];
+    2784             :                     }
+    2785           0 :                     y[jy-1] += alpha*temp2;
+    2786           0 :                     jx += incx;
+    2787           0 :                     jy += incy;
+    2788             :                 }
+    2789             :             }
+    2790             :         }
+    2791             :         return;
+    2792             : }    
+    2793             : }
+    2794             : }
+    2795             : #include <cctype>
+    2796             : #include <cmath>
+    2797             : 
+    2798             : #include "real.h"
+    2799             : #include "blas.h"
+    2800             : 
+    2801             : namespace PLMD{
+    2802             : namespace blas{
+    2803             : void
+    2804           0 : PLUMED_BLAS_F77_FUNC(ssyr2,SSYR2)(const char *    uplo,
+    2805             :                       int *     n__,
+    2806             :                       float *  alpha__,
+    2807             :                       float *  x,
+    2808             :                       int *     incx__,
+    2809             :                       float *  y,
+    2810             :                       int *     incy__,
+    2811             :                       float *  a,
+    2812             :                       int *     lda__)
+    2813             : {
+    2814             :     int kx,ky,ix,iy,jx,jy,j,i;
+    2815             :     float temp1,temp2;
+    2816           0 :     const char ch=std::toupper(*uplo);
+    2817             :     
+    2818           0 :     int n = *n__;
+    2819           0 :     int lda = *lda__;
+    2820           0 :     int incx = *incx__;
+    2821           0 :     int incy = *incy__;
+    2822           0 :     float alpha = *alpha__;
+    2823             :     
+    2824           0 :     if(n<=0 || std::abs(alpha)<PLUMED_GMX_FLOAT_MIN || incx==0 || incy==0 ||
+    2825           0 :        (ch != 'U' && ch != 'L'))
+    2826             :         return;
+    2827             :     
+    2828             :     jx = jy = kx = ky = 0;
+    2829             :     
+    2830             :     /* init start points for non-unit increments */
+    2831           0 :     if(incx!=1 || incy!=1) {
+    2832           0 :         if(incx>0)
+    2833             :             kx = 1;
+    2834             :         else
+    2835           0 :             kx = 1 - (n - 1)*(incx);
+    2836           0 :         if(incy>0)
+    2837             :             ky = 1;
+    2838             :         else
+    2839           0 :             ky = 1 - (n - 1)*(incy);
+    2840             :         
+    2841             :         jx = kx;
+    2842             :         jy = ky;
+    2843             :     }
+    2844             :     
+    2845           0 :     if(ch == 'U') {
+    2846             :         /* Data in upper part of A */
+    2847           0 :         if(incx==1 && incy==1) {
+    2848             :             /* Unit increments for both x and y */
+    2849           0 :             for(j=1;j<=n;j++) {
+    2850           0 :                 if( std::abs(x[j-1])>PLUMED_GMX_FLOAT_MIN  || std::abs(y[j-1])>PLUMED_GMX_FLOAT_MIN ) {
+    2851           0 :                     temp1 = alpha * y[j-1];
+    2852           0 :                     temp2 = alpha * x[j-1];
+    2853           0 :                     for(i=1;i<=j;i++)
+    2854           0 :                         a[(j-1)*(lda)+(i-1)] += x[i-1]*temp1 + y[i-1]*temp2;
+    2855             :                 }
+    2856             :             }
+    2857             :         } else {
+    2858             :             
+    2859             :             /* non-unit increments */
+    2860           0 :             for(j=1;j<=n;j++) {
+    2861             :                 
+    2862           0 :                 if( std::abs(x[jx-1])>PLUMED_GMX_FLOAT_MIN || std::abs(y[jy-1])>PLUMED_GMX_FLOAT_MIN ) {
+    2863           0 :                     temp1 = alpha * y[jy-1];
+    2864           0 :                     temp2 = alpha * x[jx-1];
+    2865             :                     ix = kx;
+    2866             :                     iy = ky;
+    2867           0 :                     for(i=1;i<=j;i++) {
+    2868           0 :                         a[(j-1)*(lda)+(i-1)] += x[ix-1]*temp1 + y[iy-1]*temp2;
+    2869           0 :                         ix += incx;
+    2870           0 :                         iy += incy;
+    2871             :                     }
+    2872             :                 }
+    2873           0 :                 jx += incx;
+    2874           0 :                 jy += incy;
+    2875             :             }
+    2876             :         }
+    2877             :     } else {
+    2878             :         /* Data in lower part of A */
+    2879           0 :         if(incx==1 && incy==1) {
+    2880             :             /* Unit increments for both x and y */
+    2881           0 :             for(j=1;j<=n;j++) {
+    2882           0 :                 if( std::abs(x[j-1])>PLUMED_GMX_FLOAT_MIN  || std::abs(y[j-1])>PLUMED_GMX_FLOAT_MIN ) {
+    2883           0 :                     temp1 = alpha * y[j-1];
+    2884           0 :                     temp2 = alpha * x[j-1];
+    2885           0 :                     for(i=j;i<=n;i++)
+    2886           0 :                         a[(j-1)*(lda)+(i-1)] += x[i-1]*temp1 + y[i-1]*temp2;
+    2887             :                 }
+    2888             :             }
+    2889             :         } else {
+    2890             :             
+    2891             :             /* non-unit increments */
+    2892           0 :             for(j=1;j<=n;j++) {
+    2893             :                 
+    2894           0 :                 if( std::abs(x[jx-1])>PLUMED_GMX_FLOAT_MIN || std::abs(y[jy-1])>PLUMED_GMX_FLOAT_MIN ) {
+    2895           0 :                     temp1 = alpha * y[jy-1];
+    2896           0 :                     temp2 = alpha * x[jx-1];
+    2897             :                     ix = jx;
+    2898             :                     iy = jy;
+    2899           0 :                     for(i=j;i<=n;i++) {
+    2900           0 :                         a[(j-1)*(lda)+(i-1)] += x[ix-1]*temp1 + y[iy-1]*temp2;
+    2901           0 :                         ix += incx;
+    2902           0 :                         iy += incy;
+    2903             :                     }
+    2904             :                 }
+    2905           0 :                 jx += incx;
+    2906           0 :                 jy += incy;
+    2907             :             }
+    2908             :         }
+    2909             :     }
+    2910             :     
+    2911             :     return;
+    2912             : }
+    2913             : }
+    2914             : }
+    2915             : #include <cctype>
+    2916             : #include <cmath>
+    2917             : 
+    2918             : #include "real.h"
+    2919             : #include "blas.h"
+    2920             : 
+    2921             : namespace PLMD{
+    2922             : namespace blas{
+    2923             : void
+    2924           0 : PLUMED_BLAS_F77_FUNC(ssyr2k,SSYR2K)(const char *uplo, 
+    2925             :                         const char *trans,
+    2926             :                         int *n__,
+    2927             :                         int *k__,
+    2928             :                         float *alpha__,
+    2929             :                         float *a,
+    2930             :                         int *lda__,
+    2931             :                         float *b,
+    2932             :                         int *ldb__,
+    2933             :                         float *beta__,
+    2934             :                         float *c,
+    2935             :                         int *ldc__)
+    2936             : {
+    2937             :   char ch1,ch2;
+    2938             :   int i,j,l;
+    2939             :   float temp1,temp2;
+    2940             : 
+    2941           0 :   int n = *n__;
+    2942           0 :   int k = *k__;
+    2943           0 :   int lda = *lda__;
+    2944           0 :   int ldb = *ldb__;
+    2945           0 :   int ldc = *ldc__;
+    2946             :   
+    2947           0 :   float alpha = *alpha__;
+    2948           0 :   float beta  = *beta__;
+    2949             :   
+    2950           0 :   ch1 = std::toupper(*uplo);
+    2951           0 :   ch2 = std::toupper(*trans);
+    2952             : 
+    2953           0 :   if(n==0 || ( ( std::abs(alpha)<PLUMED_GMX_FLOAT_MIN || k==0 ) && std::abs(beta-1.0)<PLUMED_GMX_FLOAT_EPS))
+    2954             :     return;
+    2955             : 
+    2956           0 :   if(std::abs(alpha)<PLUMED_GMX_FLOAT_MIN) {
+    2957           0 :     if(ch1=='U') {
+    2958           0 :       if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) 
+    2959           0 :         for(j=1;j<=n;j++) 
+    2960           0 :           for(i=1;i<=j;i++)
+    2961           0 :             c[(j-1)*(ldc)+(i-1)] = 0.0;
+    2962             :       else
+    2963           0 :         for(j=1;j<=n;j++) 
+    2964           0 :           for(i=1;i<=j;i++)
+    2965           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    2966             :     } else {
+    2967             :       /* lower */
+    2968           0 :       if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN) 
+    2969           0 :         for(j=1;j<=n;j++) 
+    2970           0 :           for(i=j;i<=n;i++)
+    2971           0 :             c[(j-1)*(ldc)+(i-1)] = 0.0;
+    2972             :       else
+    2973           0 :         for(j=1;j<=n;j++) 
+    2974           0 :           for(i=j;i<=n;i++)
+    2975           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    2976             :     }
+    2977           0 :     return;
+    2978             :   }
+    2979             : 
+    2980           0 :   if(ch2=='N') {
+    2981           0 :     if(ch1=='U') {
+    2982           0 :       for(j=1;j<=n;j++) {
+    2983           0 :         if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    2984           0 :           for(i=1;i<=j;i++)
+    2985           0 :              c[(j-1)*(ldc)+(i-1)] = 0.0;
+    2986           0 :         else if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS)
+    2987           0 :           for(i=1;i<=j;i++)
+    2988           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    2989           0 :         for(l=1;l<=k;l++) {
+    2990           0 :           if( std::abs(a[(l-1)*(lda)+(j-1)])>PLUMED_GMX_FLOAT_MIN ||
+    2991           0 :               std::abs(b[(l-1)*(ldb)+(j-1)])>PLUMED_GMX_FLOAT_MIN) {
+    2992           0 :             temp1 = alpha * b[(l-1)*(ldb)+(j-1)];
+    2993           0 :             temp2 = alpha * a[(l-1)*(lda)+(j-1)];
+    2994           0 :             for(i=1;i<=j;i++)
+    2995           0 :               c[(j-1)*(ldc)+(i-1)] += 
+    2996           0 :                 a[(l-1)*(lda)+(i-1)] * temp1 + 
+    2997           0 :                 b[(l-1)*(ldb)+(i-1)] * temp2;
+    2998             :           }
+    2999             :         }
+    3000             :       }
+    3001             :     } else {
+    3002             :       /* lower */
+    3003           0 :       for(j=1;j<=n;j++) {
+    3004           0 :         if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    3005           0 :           for(i=j;i<=n;i++)
+    3006           0 :             c[(j-1)*(ldc)+(i-1)] = 0.0;
+    3007           0 :         else if(std::abs(beta-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3008           0 :           for(i=j;i<=n;i++)
+    3009           0 :             c[(j-1)*(ldc)+(i-1)] *= beta;
+    3010           0 :         for(l=1;l<=k;l++) {
+    3011           0 :           if( std::abs(a[(l-1)*(lda)+(j-1)])>PLUMED_GMX_FLOAT_MIN ||
+    3012           0 :               std::abs(b[(l-1)*(ldb)+(j-1)])>PLUMED_GMX_FLOAT_MIN) {
+    3013           0 :             temp1 = alpha * b[(l-1)*(ldb)+(j-1)];
+    3014           0 :             temp2 = alpha * a[(l-1)*(lda)+(j-1)];
+    3015           0 :             for(i=j;i<=n;i++)
+    3016           0 :               c[(j-1)*(ldc)+(i-1)] += 
+    3017           0 :                 a[(l-1)*(lda)+(i-1)] * temp1 + 
+    3018           0 :                 b[(l-1)*(ldb)+(i-1)] * temp2;
+    3019             :           }
+    3020             :         }
+    3021             :       }
+    3022             :     }
+    3023             :   } else {
+    3024             :     /* transpose */
+    3025           0 :     if(ch1=='U') {
+    3026           0 :       for(j=1;j<=n;j++) 
+    3027           0 :         for(i=1;i<=j;i++) {
+    3028             :           temp1 = 0.0;
+    3029             :           temp2 = 0.0;
+    3030           0 :           for (l=1;l<=k;l++) {
+    3031           0 :              temp1 += a[(i-1)*(lda)+(l-1)] * b[(j-1)*(ldb)+(l-1)];
+    3032           0 :              temp2 += b[(i-1)*(ldb)+(l-1)] * a[(j-1)*(lda)+(l-1)];
+    3033             :           }
+    3034           0 :           if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    3035           0 :             c[(j-1)*(ldc)+(i-1)] = alpha * (temp1 + temp2);
+    3036             :           else
+    3037           0 :             c[(j-1)*(ldc)+(i-1)] = beta * c[(j-1)*(ldc)+(i-1)] +
+    3038           0 :               alpha * (temp1 + temp2);
+    3039             :         }
+    3040             :     } else {
+    3041             :       /* lower */
+    3042           0 :       for(j=1;j<=n;j++) 
+    3043           0 :         for(i=j;i<=n;i++) {
+    3044             :           temp1 = 0.0;
+    3045             :           temp2 = 0.0;
+    3046           0 :           for (l=1;l<=k;l++) {
+    3047           0 :              temp1 += a[(i-1)*(lda)+(l-1)] * b[(j-1)*(ldb)+(l-1)];
+    3048           0 :              temp2 += b[(i-1)*(ldb)+(l-1)] * a[(j-1)*(lda)+(l-1)];
+    3049             :           }
+    3050           0 :           if(std::abs(beta)<PLUMED_GMX_FLOAT_MIN)
+    3051           0 :             c[(j-1)*(ldc)+(i-1)] = alpha * (temp1 + temp2);
+    3052             :           else
+    3053           0 :             c[(j-1)*(ldc)+(i-1)] = beta * c[(j-1)*(ldc)+(i-1)] +
+    3054           0 :               alpha * (temp1 + temp2);
+    3055             :         }
+    3056             :     }
+    3057             :   }
+    3058             :   return;
+    3059             : }
+    3060             : }
+    3061             : }
+    3062             : #include <cmath>
+    3063             : 
+    3064             : #include "real.h"
+    3065             : #include "blas.h"
+    3066             : 
+    3067             : namespace PLMD{
+    3068             : namespace blas{
+    3069             : void 
+    3070           0 : PLUMED_BLAS_F77_FUNC(strmm,STRMM)(const char *side, 
+    3071             :                       const char *uplo, 
+    3072             :                       const char *transa, 
+    3073             :                       const char *diag, 
+    3074             :                       int *m__, 
+    3075             :                       int *n__, 
+    3076             :                       float *alpha__, 
+    3077             :                       float *a, 
+    3078             :                       int *lda__, 
+    3079             :                       float *b, 
+    3080             :                       int *ldb__)
+    3081             : {
+    3082             :     int a_dim1, a_offset, b_dim1, b_offset, i__1, i__2, i__3;
+    3083             :     
+    3084           0 :     int m = *m__;
+    3085           0 :     int n = *n__;
+    3086           0 :     int lda = *lda__;
+    3087           0 :     int ldb = *ldb__;
+    3088           0 :     float alpha = *alpha__;
+    3089             :     
+    3090             :     /* Local variables */
+    3091             :     int i__, j, k;
+    3092             :     float temp;
+    3093             :     int lside;
+    3094             :     int upper;
+    3095             :     int nounit;
+    3096             :     a_dim1 = lda;
+    3097           0 :     a_offset = 1 + a_dim1;
+    3098           0 :     a -= a_offset;
+    3099             :     b_dim1 = ldb;
+    3100           0 :     b_offset = 1 + b_dim1;
+    3101           0 :     b -= b_offset;
+    3102             : 
+    3103             :     /* Function Body */
+    3104           0 :     lside = (*side=='L' || *side=='l');
+    3105             : 
+    3106           0 :     nounit = (*diag=='N' || *diag=='n');
+    3107           0 :     upper = (*uplo=='U' || *uplo=='u');
+    3108             : 
+    3109           0 :     if (n == 0) {
+    3110             :         return;
+    3111             :     }
+    3112           0 :     if (std::abs(alpha)<PLUMED_GMX_FLOAT_MIN) {
+    3113             :         i__1 = n;
+    3114           0 :         for (j = 1; j <= i__1; ++j) {
+    3115             :             i__2 = m;
+    3116           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    3117           0 :                 b[i__ + j * b_dim1] = 0.;
+    3118             :             }
+    3119             :         }
+    3120             :         return;
+    3121             :     }
+    3122           0 :     if (lside) {
+    3123           0 :         if (*transa=='N' || *transa=='n') {
+    3124           0 :             if (upper) {
+    3125             :                 i__1 = n;
+    3126           0 :                 for (j = 1; j <= i__1; ++j) {
+    3127             :                     i__2 = m;
+    3128           0 :                     for (k = 1; k <= i__2; ++k) {
+    3129           0 :                         if ( std::abs(b[k + j * b_dim1])>PLUMED_GMX_FLOAT_MIN) {
+    3130           0 :                             temp = alpha * b[k + j * b_dim1];
+    3131             :                             i__3 = k - 1;
+    3132           0 :                             for (i__ = 1; i__ <= i__3; ++i__) {
+    3133           0 :                                 b[i__ + j * b_dim1] += temp * a[i__ + k * 
+    3134           0 :                                         a_dim1];
+    3135             :                             }
+    3136           0 :                             if (nounit) {
+    3137           0 :                                 temp *= a[k + k * a_dim1];
+    3138             :                             }
+    3139           0 :                             b[k + j * b_dim1] = temp;
+    3140             :                         }
+    3141             :                     }
+    3142             :                 }
+    3143             :             } else {
+    3144             :                 i__1 = n;
+    3145           0 :                 for (j = 1; j <= i__1; ++j) {
+    3146           0 :                     for (k = m; k >= 1; --k) {
+    3147           0 :                         if (std::abs(b[k + j * b_dim1])>PLUMED_GMX_FLOAT_MIN) {
+    3148           0 :                             temp = alpha * b[k + j * b_dim1];
+    3149           0 :                             b[k + j * b_dim1] = temp;
+    3150           0 :                             if (nounit) {
+    3151           0 :                                 b[k + j * b_dim1] *= a[k + k * a_dim1];
+    3152             :                             }
+    3153             :                             i__2 = m;
+    3154           0 :                             for (i__ = k + 1; i__ <= i__2; ++i__) {
+    3155           0 :                                 b[i__ + j * b_dim1] += temp * a[i__ + k * 
+    3156           0 :                                         a_dim1];
+    3157             :                             }
+    3158             :                         }
+    3159             :                     }
+    3160             :                 }
+    3161             :             }
+    3162             :         } else {
+    3163             : 
+    3164           0 :             if (upper) {
+    3165             :                 i__1 = n;
+    3166           0 :                 for (j = 1; j <= i__1; ++j) {
+    3167           0 :                     for (i__ = m; i__ >= 1; --i__) {
+    3168           0 :                         temp = b[i__ + j * b_dim1];
+    3169           0 :                         if (nounit) {
+    3170           0 :                             temp *= a[i__ + i__ * a_dim1];
+    3171             :                         }
+    3172             :                         i__2 = i__ - 1;
+    3173           0 :                         for (k = 1; k <= i__2; ++k) {
+    3174           0 :                             temp += a[k + i__ * a_dim1] * b[k + j * b_dim1];
+    3175             :                         }
+    3176           0 :                         b[i__ + j * b_dim1] = alpha * temp;
+    3177             :                     }
+    3178             :                 }
+    3179             :             } else {
+    3180             :                 i__1 = n;
+    3181           0 :                 for (j = 1; j <= i__1; ++j) {
+    3182             :                     i__2 = m;
+    3183           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    3184           0 :                         temp = b[i__ + j * b_dim1];
+    3185           0 :                         if (nounit) {
+    3186           0 :                             temp *= a[i__ + i__ * a_dim1];
+    3187             :                         }
+    3188             :                         i__3 = m;
+    3189           0 :                         for (k = i__ + 1; k <= i__3; ++k) {
+    3190           0 :                             temp += a[k + i__ * a_dim1] * b[k + j * b_dim1];
+    3191             :                         }
+    3192           0 :                         b[i__ + j * b_dim1] = alpha * temp;
+    3193             :                     }
+    3194             :                 }
+    3195             :             }
+    3196             :         }
+    3197             :     } else {
+    3198           0 :         if (*transa=='N' || *transa=='n') {
+    3199             : 
+    3200           0 :             if (upper) {
+    3201           0 :                 for (j = n; j >= 1; --j) {
+    3202             :                     temp = alpha;
+    3203           0 :                     if (nounit) {
+    3204           0 :                         temp *= a[j + j * a_dim1];
+    3205             :                     }
+    3206             :                     i__1 = m;
+    3207           0 :                     for (i__ = 1; i__ <= i__1; ++i__) {
+    3208           0 :                         b[i__ + j * b_dim1] = temp * b[i__ + j * b_dim1];
+    3209             :                     }
+    3210             :                     i__1 = j - 1;
+    3211           0 :                     for (k = 1; k <= i__1; ++k) {
+    3212           0 :                         if ( std::abs(a[k + j * a_dim1])>PLUMED_GMX_FLOAT_MIN) {
+    3213           0 :                             temp = alpha * a[k + j * a_dim1];
+    3214             :                             i__2 = m;
+    3215           0 :                             for (i__ = 1; i__ <= i__2; ++i__) {
+    3216           0 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    3217           0 :                                         b_dim1];
+    3218             :                             }
+    3219             :                         }
+    3220             :                     }
+    3221             :                 }
+    3222             :             } else {
+    3223             :                 i__1 = n;
+    3224           0 :                 for (j = 1; j <= i__1; ++j) {
+    3225             :                     temp = alpha;
+    3226           0 :                     if (nounit) {
+    3227           0 :                         temp *= a[j + j * a_dim1];
+    3228             :                     }
+    3229             :                     i__2 = m;
+    3230           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    3231           0 :                         b[i__ + j * b_dim1] = temp * b[i__ + j * b_dim1];
+    3232             :                     }
+    3233             :                     i__2 = n;
+    3234           0 :                     for (k = j + 1; k <= i__2; ++k) {
+    3235           0 :                         if ( std::abs(a[k + j * a_dim1])>PLUMED_GMX_FLOAT_MIN) {
+    3236           0 :                             temp = alpha * a[k + j * a_dim1];
+    3237             :                             i__3 = m;
+    3238           0 :                             for (i__ = 1; i__ <= i__3; ++i__) {
+    3239           0 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    3240           0 :                                         b_dim1];
+    3241             :                             }
+    3242             :                         }
+    3243             :                     }
+    3244             :                 }
+    3245             :             }
+    3246             :         } else {
+    3247             : 
+    3248           0 :             if (upper) {
+    3249             :                 i__1 = n;
+    3250           0 :                 for (k = 1; k <= i__1; ++k) {
+    3251             :                     i__2 = k - 1;
+    3252           0 :                     for (j = 1; j <= i__2; ++j) {
+    3253           0 :                         if ( std::abs(a[j + k * a_dim1])>PLUMED_GMX_FLOAT_MIN ) {
+    3254           0 :                             temp = alpha * a[j + k * a_dim1];
+    3255             :                             i__3 = m;
+    3256           0 :                             for (i__ = 1; i__ <= i__3; ++i__) {
+    3257           0 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    3258           0 :                                         b_dim1];
+    3259             :                             }
+    3260             :                         }
+    3261             :                     }
+    3262             :                     temp = alpha;
+    3263           0 :                     if (nounit) {
+    3264           0 :                         temp *= a[k + k * a_dim1];
+    3265             :                     }
+    3266           0 :                     if ( std::abs(temp-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    3267             :                         i__2 = m;
+    3268           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+    3269           0 :                             b[i__ + k * b_dim1] = temp * b[i__ + k * b_dim1];
+    3270             :                         }
+    3271             :                     }
+    3272             :                 }
+    3273             :             } else {
+    3274           0 :                 for (k = n; k >= 1; --k) {
+    3275             :                     i__1 = n;
+    3276           0 :                     for (j = k + 1; j <= i__1; ++j) {
+    3277           0 :                         if ( std::abs(a[j + k * a_dim1])>PLUMED_GMX_FLOAT_MIN) {
+    3278           0 :                             temp = alpha * a[j + k * a_dim1];
+    3279             :                             i__2 = m;
+    3280           0 :                             for (i__ = 1; i__ <= i__2; ++i__) {
+    3281           0 :                                 b[i__ + j * b_dim1] += temp * b[i__ + k * 
+    3282           0 :                                         b_dim1];
+    3283             :                             }
+    3284             :                         }
+    3285             :                     }
+    3286             :                     temp = alpha;
+    3287           0 :                     if (nounit) {
+    3288           0 :                         temp *= a[k + k * a_dim1];
+    3289             :                     }
+    3290           0 :                     if ( std::abs(temp-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    3291             :                         i__1 = m;
+    3292           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+    3293           0 :                             b[i__ + k * b_dim1] = temp * b[i__ + k * b_dim1];
+    3294             :                         }
+    3295             :                     }
+    3296             :                 }
+    3297             :             }
+    3298             :         }
+    3299             :     }
+    3300             : 
+    3301             :     return;
+    3302             : 
+    3303             : }
+    3304             : 
+    3305             : 
+    3306             : }
+    3307             : }
+    3308             : #include <cmath>
+    3309             : 
+    3310             : #include "real.h"
+    3311             : #include "blas.h"
+    3312             : 
+    3313             : namespace PLMD{
+    3314             : namespace blas{
+    3315             : void 
+    3316           0 : PLUMED_BLAS_F77_FUNC(strmv,STRMV)(const char *uplo, 
+    3317             :                       const char *trans,
+    3318             :                       const char *diag, 
+    3319             :                       int *n__, 
+    3320             :                       float *a, 
+    3321             :                       int *lda__, 
+    3322             :                       float *x, 
+    3323             :                       int *incx__)
+    3324             : {
+    3325             :     int a_dim1, a_offset, i__1, i__2;
+    3326             : 
+    3327             :     int i__, j, ix, jx, kx;
+    3328             :     float temp;
+    3329             :     int nounit;
+    3330             :     
+    3331           0 :     int n = *n__;
+    3332           0 :     int lda = *lda__;
+    3333           0 :     int incx = *incx__;
+    3334             :     
+    3335             :     a_dim1 = lda;
+    3336           0 :     a_offset = 1 + a_dim1;
+    3337           0 :     a -= a_offset;
+    3338           0 :     --x;
+    3339             : 
+    3340           0 :     if (n == 0) {
+    3341             :         return;
+    3342             :     }
+    3343             : 
+    3344           0 :     nounit = (*diag=='n' || *diag=='N');
+    3345             : 
+    3346           0 :     if (incx <= 0) {
+    3347           0 :         kx = 1 - (n - 1) * incx;
+    3348             :     } else {
+    3349             :         kx = 1;
+    3350             :     }
+    3351             : 
+    3352           0 :     if (*trans=='N' || *trans=='n') {
+    3353             : 
+    3354           0 :         if (*uplo=='U' || *uplo=='u') {
+    3355           0 :             if (incx == 1) {
+    3356             :                 i__1 = n;
+    3357           0 :                 for (j = 1; j <= i__1; ++j) {
+    3358           0 :                     if (std::abs(x[j])>PLUMED_GMX_FLOAT_MIN) {
+    3359             :                         temp = x[j];
+    3360             :                         i__2 = j - 1;
+    3361           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+    3362           0 :                             x[i__] += temp * a[i__ + j * a_dim1];
+    3363             :                         }
+    3364           0 :                         if (nounit) {
+    3365           0 :                             x[j] *= a[j + j * a_dim1];
+    3366             :                         }
+    3367             :                     }
+    3368             :                 }
+    3369             :             } else {
+    3370             :                 jx = kx;
+    3371             :                 i__1 = n;
+    3372           0 :                 for (j = 1; j <= i__1; ++j) {
+    3373           0 :                     if (std::abs(x[jx])>PLUMED_GMX_FLOAT_MIN) {
+    3374             :                         temp = x[jx];
+    3375             :                         ix = kx;
+    3376             :                         i__2 = j - 1;
+    3377           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+    3378           0 :                             x[ix] += temp * a[i__ + j * a_dim1];
+    3379           0 :                             ix += incx;
+    3380             :                         }
+    3381           0 :                         if (nounit) {
+    3382           0 :                             x[jx] *= a[j + j * a_dim1];
+    3383             :                         }
+    3384             :                     }
+    3385           0 :                     jx += incx;
+    3386             :                 }
+    3387             :             }
+    3388             :         } else {
+    3389           0 :             if (incx == 1) {
+    3390           0 :                 for (j = n; j >= 1; --j) {
+    3391           0 :                     if (std::abs(x[j])>PLUMED_GMX_FLOAT_MIN) {
+    3392             :                         temp = x[j];
+    3393             :                         i__1 = j + 1;
+    3394           0 :                         for (i__ = n; i__ >= i__1; --i__) {
+    3395           0 :                             x[i__] += temp * a[i__ + j * a_dim1];
+    3396             :                         }
+    3397           0 :                         if (nounit) {
+    3398           0 :                             x[j] *= a[j + j * a_dim1];
+    3399             :                         }
+    3400             :                     }
+    3401             :                 }
+    3402             :             } else {
+    3403           0 :                 kx += (n - 1) * incx;
+    3404             :                 jx = kx;
+    3405           0 :                 for (j = n; j >= 1; --j) {
+    3406           0 :                     if (std::abs(x[jx])>PLUMED_GMX_FLOAT_MIN) {
+    3407             :                         temp = x[jx];
+    3408             :                         ix = kx;
+    3409             :                         i__1 = j + 1;
+    3410           0 :                         for (i__ = n; i__ >= i__1; --i__) {
+    3411           0 :                             x[ix] += temp * a[i__ + j * a_dim1];
+    3412           0 :                             ix -= incx;
+    3413             :                         }
+    3414           0 :                         if (nounit) {
+    3415           0 :                             x[jx] *= a[j + j * a_dim1];
+    3416             :                         }
+    3417             :                     }
+    3418           0 :                     jx -= incx;
+    3419             :                 }
+    3420             :             }
+    3421             :         }
+    3422             :     } else {
+    3423             : 
+    3424           0 :         if (*uplo=='U' || *uplo=='u') {
+    3425           0 :             if (incx == 1) {
+    3426           0 :                 for (j = n; j >= 1; --j) {
+    3427           0 :                     temp = x[j];
+    3428           0 :                     if (nounit) {
+    3429           0 :                         temp *= a[j + j * a_dim1];
+    3430             :                     }
+    3431           0 :                     for (i__ = j - 1; i__ >= 1; --i__) {
+    3432           0 :                         temp += a[i__ + j * a_dim1] * x[i__];
+    3433             :                     }
+    3434           0 :                     x[j] = temp;
+    3435             :                 }
+    3436             :             } else {
+    3437           0 :                 jx = kx + (n - 1) * incx;
+    3438           0 :                 for (j = n; j >= 1; --j) {
+    3439           0 :                     temp = x[jx];
+    3440             :                     ix = jx;
+    3441           0 :                     if (nounit) {
+    3442           0 :                         temp *= a[j + j * a_dim1];
+    3443             :                     }
+    3444           0 :                     for (i__ = j - 1; i__ >= 1; --i__) {
+    3445           0 :                         ix -= incx;
+    3446           0 :                         temp += a[i__ + j * a_dim1] * x[ix];
+    3447             :                     }
+    3448           0 :                     x[jx] = temp;
+    3449           0 :                     jx -= incx;
+    3450             :                 }
+    3451             :             }
+    3452             :         } else {
+    3453           0 :             if (incx == 1) {
+    3454             :                 i__1 = n;
+    3455           0 :                 for (j = 1; j <= i__1; ++j) {
+    3456           0 :                     temp = x[j];
+    3457           0 :                     if (nounit) {
+    3458           0 :                         temp *= a[j + j * a_dim1];
+    3459             :                     }
+    3460             :                     i__2 = n;
+    3461           0 :                     for (i__ = j + 1; i__ <= i__2; ++i__) {
+    3462           0 :                         temp += a[i__ + j * a_dim1] * x[i__];
+    3463             :                     }
+    3464           0 :                     x[j] = temp;
+    3465             :                 }
+    3466             :             } else {
+    3467             :                 jx = kx;
+    3468             :                 i__1 = n;
+    3469           0 :                 for (j = 1; j <= i__1; ++j) {
+    3470           0 :                     temp = x[jx];
+    3471             :                     ix = jx;
+    3472           0 :                     if (nounit) {
+    3473           0 :                         temp *= a[j + j * a_dim1];
+    3474             :                     }
+    3475             :                     i__2 = n;
+    3476           0 :                     for (i__ = j + 1; i__ <= i__2; ++i__) {
+    3477           0 :                         ix += incx;
+    3478           0 :                         temp += a[i__ + j * a_dim1] * x[ix];
+    3479             :                     }
+    3480           0 :                     x[jx] = temp;
+    3481           0 :                     jx += incx;
+    3482             :                 }
+    3483             :             }
+    3484             :         }
+    3485             :     }
+    3486             : 
+    3487             :     return;
+    3488             : 
+    3489             : }
+    3490             : 
+    3491             : 
+    3492             : }
+    3493             : }
+    3494             : #include <cctype>
+    3495             : #include <cmath>
+    3496             : 
+    3497             : #include "real.h"
+    3498             : #include "blas.h"
+    3499             : 
+    3500             : namespace PLMD{
+    3501             : namespace blas{
+    3502             : void
+    3503           0 : PLUMED_BLAS_F77_FUNC(strsm,STRSM)(const char * side,
+    3504             :                       const char * uplo,
+    3505             :                       const char * transa,
+    3506             :                       const char * diag,
+    3507             :                       int *  m__,
+    3508             :                       int *  n__,
+    3509             :                       float *alpha__,
+    3510             :                       float *a,
+    3511             :                       int *  lda__,
+    3512             :                       float *b,
+    3513             :                       int *  ldb__)
+    3514             : {
+    3515           0 :   const char xside  = std::toupper(*side);
+    3516           0 :   const char xuplo  = std::toupper(*uplo);
+    3517           0 :   const char xtrans = std::toupper(*transa);
+    3518           0 :   const char xdiag  = std::toupper(*diag);
+    3519             :   int i,j,k;
+    3520             :   float temp;
+    3521             : 
+    3522           0 :   int m = *m__;
+    3523           0 :   int n = *n__;
+    3524           0 :   int lda = *lda__;
+    3525           0 :   int ldb = *ldb__;
+    3526           0 :   float alpha = *alpha__;
+    3527             :   
+    3528           0 :   if(n<=0)
+    3529             :     return;
+    3530             : 
+    3531             :   
+    3532           0 :   if(std::abs(alpha)<PLUMED_GMX_FLOAT_MIN) { 
+    3533           0 :     for(j=0;j<n;j++)
+    3534           0 :       for(i=0;i<m;i++)
+    3535           0 :         b[j*(ldb)+i] = 0.0;
+    3536             :     return;
+    3537             :   }
+    3538             : 
+    3539           0 :   if(xside=='L') {
+    3540             :     /* left side */
+    3541           0 :     if(xtrans=='N') {
+    3542             :       /* No transpose */
+    3543           0 :       if(xuplo=='U') {
+    3544             :         /* upper */
+    3545           0 :         for(j=0;j<n;j++) {
+    3546           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS) {
+    3547           0 :             for(i=0;i<m;i++)
+    3548           0 :               b[j*(ldb)+i] *= alpha;
+    3549             :           }
+    3550           0 :           for(k=m-1;k>=0;k--) {
+    3551           0 :             if( std::abs(b[j*(ldb)+k])>PLUMED_GMX_FLOAT_MIN) {
+    3552           0 :               if(xdiag=='N')
+    3553           0 :                 b[j*(ldb)+k] /= a[k*(lda)+k];
+    3554           0 :               for(i=0;i<k;i++)
+    3555           0 :                 b[j*(ldb)+i] -= b[j*(ldb)+k]*a[k*(lda)+i];
+    3556             :             }
+    3557             :           }
+    3558             :         }
+    3559             :       } else {
+    3560             :         /* lower */
+    3561           0 :         for(j=0;j<n;j++) {
+    3562           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3563           0 :             for(i=0;i<m;i++)
+    3564           0 :               b[j*(ldb)+i] *= alpha;
+    3565           0 :           for(k=0;k<m;k++) {
+    3566           0 :             if( std::abs(b[j*(ldb)+k])>PLUMED_GMX_FLOAT_MIN) {
+    3567           0 :               if(xdiag=='N')
+    3568           0 :                 b[j*(ldb)+k] /= a[k*(lda)+k];
+    3569           0 :               for(i=k+1;i<m;i++)
+    3570           0 :                 b[j*(ldb)+i] -= b[j*(ldb)+k]*a[k*(lda)+i];
+    3571             :             }
+    3572             :           }
+    3573             :         }
+    3574             :       }
+    3575             :     } else {
+    3576             :       /* Transpose */
+    3577           0 :       if(xuplo=='U') {
+    3578             :         /* upper */
+    3579           0 :         for(j=0;j<n;j++) {
+    3580           0 :           for(i=0;i<m;i++) {
+    3581           0 :             temp = alpha * b[j*(ldb)+i];
+    3582           0 :             for(k=0;k<i;k++)
+    3583           0 :               temp -= a[i*(lda)+k] * b[j*(ldb)+k];
+    3584           0 :             if(xdiag=='N')
+    3585           0 :                 temp /= a[i*(lda)+i];
+    3586           0 :             b[j*(ldb)+i] = temp;
+    3587             :           }
+    3588             :         }
+    3589             :       } else {
+    3590             :         /* lower */
+    3591           0 :         for(j=0;j<n;j++) {
+    3592           0 :           for(i=m-1;i>=0;i--) {
+    3593           0 :             temp = alpha * b[j*(ldb)+i];
+    3594           0 :             for(k=i+1;k<m;k++)
+    3595           0 :               temp -= a[i*(lda)+k] * b[j*(ldb)+k];
+    3596           0 :             if(xdiag=='N')
+    3597           0 :                 temp /= a[i*(lda)+i];
+    3598           0 :             b[j*(ldb)+i] = temp;
+    3599             :           }
+    3600             :         }
+    3601             :       }
+    3602             :     }
+    3603             :   } else {
+    3604             :     /* right side */
+    3605           0 :     if(xtrans=='N') {
+    3606             :       /* No transpose */
+    3607           0 :       if(xuplo=='U') {
+    3608             :         /* upper */
+    3609           0 :         for(j=0;j<n;j++) {
+    3610           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3611           0 :             for(i=0;i<m;i++)
+    3612           0 :               b[j*(ldb)+i] *= alpha;
+    3613           0 :           for(k=0;k<j;k++) {
+    3614           0 :             if( std::abs(a[j*(lda)+k])>PLUMED_GMX_FLOAT_MIN) {
+    3615           0 :               for(i=0;i<m;i++)
+    3616           0 :                 b[j*(ldb)+i] -= a[j*(lda)+k]*b[k*(ldb)+i];
+    3617             :             }
+    3618             :           }
+    3619           0 :           if(xdiag=='N') {
+    3620           0 :             temp = 1.0/a[j*(lda)+j];
+    3621           0 :             for(i=0;i<m;i++)
+    3622           0 :               b[j*(ldb)+i] *= temp;
+    3623             :           }
+    3624             :         }
+    3625             :       } else {
+    3626             :         /* lower */
+    3627           0 :         for(j=n-1;j>=0;j--) {
+    3628           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3629           0 :             for(i=0;i<m;i++)
+    3630           0 :               b[j*(ldb)+i] *= alpha;
+    3631           0 :           for(k=j+1;k<n;k++) {
+    3632           0 :             if( std::abs(a[j*(lda)+k])>PLUMED_GMX_FLOAT_MIN ) {
+    3633           0 :               for(i=0;i<m;i++)
+    3634           0 :                 b[j*(ldb)+i] -= a[j*(lda)+k]*b[k*(ldb)+i];
+    3635             :             }
+    3636             :           }
+    3637           0 :           if(xdiag=='N') {
+    3638           0 :             temp = 1.0/a[j*(lda)+j];
+    3639           0 :             for(i=0;i<m;i++)
+    3640           0 :               b[j*(ldb)+i] *= temp;
+    3641             :           }
+    3642             :         }
+    3643             :       }
+    3644             :     } else {
+    3645             :       /* Transpose */
+    3646           0 :       if(xuplo=='U') {
+    3647             :         /* upper */
+    3648           0 :         for(k=n-1;k>=0;k--) {
+    3649           0 :           if(xdiag=='N') {
+    3650           0 :             temp = 1.0/a[k*(lda)+k];
+    3651           0 :             for(i=0;i<m;i++)
+    3652           0 :               b[k*(ldb)+i] *= temp;
+    3653             :           }
+    3654           0 :           for(j=0;j<k;j++) {
+    3655           0 :             if( std::abs(a[k*(lda)+j])>PLUMED_GMX_FLOAT_MIN) {
+    3656             :               temp = a[k*(lda)+j];
+    3657           0 :               for(i=0;i<m;i++)
+    3658           0 :                 b[j*(ldb)+i] -= temp * b[k*(ldb)+i];
+    3659             :             }
+    3660             :           }
+    3661           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3662           0 :             for(i=0;i<m;i++)
+    3663           0 :               b[k*(ldb)+i] *= alpha;
+    3664             :         }
+    3665             :       } else {
+    3666             :         /* lower */
+    3667           0 :         for(k=0;k<n;k++) {
+    3668           0 :           if(xdiag=='N') {
+    3669           0 :             temp = 1.0/a[k*(lda)+k];
+    3670           0 :             for(i=0;i<m;i++)
+    3671           0 :               b[k*(ldb)+i] *= temp;
+    3672             :           }
+    3673           0 :           for(j=k+1;j<n;j++) {
+    3674           0 :             if( std::abs(a[k*(lda)+j])>PLUMED_GMX_FLOAT_MIN) {
+    3675             :               temp = a[k*(lda)+j];
+    3676           0 :               for(i=0;i<m;i++)
+    3677           0 :                 b[j*(ldb)+i] -= temp * b[k*(ldb)+i];
+    3678             :             }
+    3679             :           }
+    3680           0 :           if(std::abs(alpha-1.0)>PLUMED_GMX_FLOAT_EPS)
+    3681           0 :             for(i=0;i<m;i++)
+    3682           0 :               b[k*(ldb)+i] *= alpha;
+    3683             :         }
+    3684             :       }      
+    3685             :     }
+    3686             :   }    
+    3687             : }
+    3688             : }
+    3689             : }
+    3690             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/index-sort-f.html b/coverage-libs/blas/index-sort-f.html new file mode 100644 index 000000000000..12dd010ed1a5 --- /dev/null +++ b/coverage-libs/blas/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blasHitTotalCoverage
Test:plumed test coverage (other modules)Lines:405160525.2 %
Date:2024-02-22 21:58:47Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
blas.cpp +
25.2%25.2%
+
25.2 %405 / 160547.2 %17 / 36
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/index-sort-l.html b/coverage-libs/blas/index-sort-l.html new file mode 100644 index 000000000000..59f383744130 --- /dev/null +++ b/coverage-libs/blas/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blasHitTotalCoverage
Test:plumed test coverage (other modules)Lines:405160525.2 %
Date:2024-02-22 21:58:47Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
blas.cpp +
25.2%25.2%
+
25.2 %405 / 160547.2 %17 / 36
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/blas/index.html b/coverage-libs/blas/index.html new file mode 100644 index 000000000000..b28b6e2787d2 --- /dev/null +++ b/coverage-libs/blas/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - blas + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - blasHitTotalCoverage
Test:plumed test coverage (other modules)Lines:405160525.2 %
Date:2024-02-22 21:58:47Functions:173647.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
blas.cpp +
25.2%25.2%
+
25.2 %405 / 160547.2 %17 / 36
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/emerald.png b/coverage-libs/emerald.png new file mode 100644 index 0000000000000000000000000000000000000000..38ad4f4068b935643d2486f323005fb294a9bd7e GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^Jb!lvI6;R0X`wF(yt=9xVZRt1vCRixIA4P dLn>}1Cji+@42)0J?}79&c)I$ztaD0e0sy@GAL0N2 literal 0 HcmV?d00001 diff --git a/coverage-libs/gcov.css b/coverage-libs/gcov.css new file mode 100644 index 000000000000..0fcdff13cea9 --- /dev/null +++ b/coverage-libs/gcov.css @@ -0,0 +1,519 @@ +/* All views: initial background and text color */ +body +{ + color: #000000; + background-color: #ffffff; +} + +/* All views: standard link format*/ +a:link +{ + color: #284fa8; + text-decoration: underline; +} + +/* All views: standard link - visited format */ +a:visited +{ + color: #00cb40; + text-decoration: underline; +} + +/* All views: standard link - activated format */ +a:active +{ + color: #ff0040; + text-decoration: underline; +} + +/* All views: main title format */ +td.title +{ + text-align: center; + padding-bottom: 10px; + font-family: sans-serif; + font-size: 20pt; + font-style: italic; + font-weight: bold; +} + +/* All views: header item format */ +td.headerItem +{ + text-align: right; + padding-right: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: top; + white-space: nowrap; +} + +/* All views: header item value format */ +td.headerValue +{ + text-align: left; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; +} + +/* All views: header item coverage table heading */ +td.headerCovTableHead +{ + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; +} + +/* All views: header item coverage table entry */ +td.headerCovTableEntry +{ + text-align: right; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #dae7fe; +} + +/* All views: header item coverage table entry for high coverage rate */ +td.headerCovTableEntryHi +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #a7fc9d; +} + +/* All views: header item coverage table entry for medium coverage rate */ +td.headerCovTableEntryMed +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ffea20; +} + +/* All views: header item coverage table entry for ow coverage rate */ +td.headerCovTableEntryLo +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ff0000; +} + +/* All views: header legend value for legend entry */ +td.headerValueLeg +{ + text-align: left; + color: #000000; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; + padding-top: 4px; +} + +/* All views: color of horizontal ruler */ +td.ruler +{ + background-color: #6688d4; +} + +/* All views: version string format */ +td.versionInfo +{ + text-align: center; + padding-top: 2px; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all)/Test case descriptions: + table headline format */ +td.tableHead +{ + text-align: center; + color: #ffffff; + background-color: #6688d4; + font-family: sans-serif; + font-size: 120%; + font-weight: bold; + white-space: nowrap; + padding-left: 4px; + padding-right: 4px; +} + +span.tableHeadSort +{ + padding-right: 4px; +} + +/* Directory view/File view (all): filename entry format */ +td.coverFile +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; +} + +/* Directory view/File view (all): bar-graph outline color */ +td.coverBarOutline +{ + background-color: #000000; +} + +/* Directory view/File view (all): percentage entry for files with + high coverage rate */ +td.coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + high coverage rate */ +td.coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + medium coverage rate */ +td.coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + medium coverage rate */ +td.coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + low coverage rate */ +td.coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + low coverage rate */ +td.coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + white-space: nowrap; + font-family: sans-serif; +} + +/* File view (all): "show/hide details" link format */ +a.detail:link +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - visited format */ +a.detail:visited +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - activated format */ +a.detail:active +{ + color: #ffffff; + font-size:80%; +} + +/* File view (detail): test name entry */ +td.testName +{ + text-align: right; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test percentage entry */ +td.testPer +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test lines count entry */ +td.testNum +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* Test case descriptions: test name format*/ +dt +{ + font-family: sans-serif; + font-weight: bold; +} + +/* Test case descriptions: description table body */ +td.testDescription +{ + padding-top: 10px; + padding-left: 30px; + padding-bottom: 10px; + padding-right: 30px; + background-color: #dae7fe; +} + +/* Source code view: function entry */ +td.coverFn +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: source code format */ +pre.source +{ + font-family: monospace; + white-space: pre; + margin-top: 2px; +} + +/* Source code view: line number format */ +span.lineNum +{ + background-color: #efe383; +} + +/* Source code view: format for lines which were executed */ +td.lineCov, +span.lineCov +{ + background-color: #cad7fe; +} + +/* Source code view: format for Cov legend */ +span.coverLegendCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #cad7fe; +} + +/* Source code view: format for lines which were not executed */ +td.lineNoCov, +span.lineNoCov +{ + background-color: #ff6230; +} + +/* Source code view: format for NoCov legend */ +span.coverLegendNoCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #ff6230; +} + +/* Source code view (function table): standard link - visited format */ +td.lineNoCov > a:visited, +td.lineCov > a:visited +{ + color: #000000; + text-decoration: underline; +} + +/* Source code view: format for lines which were executed only in a + previous version */ +span.lineDiffCov +{ + background-color: #b5f7af; +} + +/* Source code view: format for branches which were executed + * and taken */ +span.branchCov +{ + background-color: #cad7fe; +} + +/* Source code view: format for branches which were executed + * but not taken */ +span.branchNoCov +{ + background-color: #ff6230; +} + +/* Source code view: format for branches which were not executed */ +span.branchNoExec +{ + background-color: #ff6230; +} + +/* Source code view: format for the source code heading line */ +pre.sourceHeading +{ + white-space: pre; + font-family: monospace; + font-weight: bold; + margin: 0px; +} + +/* All views: header legend value for low rate */ +td.headerValueLegL +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 4px; + padding-right: 2px; + background-color: #ff0000; + font-size: 80%; +} + +/* All views: header legend value for med rate */ +td.headerValueLegM +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 2px; + background-color: #ffea20; + font-size: 80%; +} + +/* All views: header legend value for hi rate */ +td.headerValueLegH +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 4px; + background-color: #a7fc9d; + font-size: 80%; +} + +/* All views except source code view: legend format for low coverage */ +span.coverLegendCovLo +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ff0000; +} + +/* All views except source code view: legend format for med coverage */ +span.coverLegendCovMed +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ffea20; +} + +/* All views except source code view: legend format for hi coverage */ +span.coverLegendCovHi +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #a7fc9d; +} diff --git a/coverage-libs/glass.png b/coverage-libs/glass.png new file mode 100644 index 0000000000000000000000000000000000000000..e1abc00680a3093c49fdb775ae6bdb6764c95af2 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)gaEa{HEjtmSN`?>!lvI6;R0X`wF z|Ns97GD8ntt^-nxB|(0{3=Yq3q=7g|-tI089jvk*Kn`btM`SSr1Gf+eGhVt|_XjA* zUgGKN%6^Gmn4d%Ph(nkFP>9RZ#WAE}PI3Z}&BVayv3^M*kj3EX>gTe~DWM4f=_Dpv literal 0 HcmV?d00001 diff --git a/coverage-libs/index-sort-f.html b/coverage-libs/index-sort-f.html new file mode 100644 index 000000000000..261dc943a9a2 --- /dev/null +++ b/coverage-libs/index-sort-f.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage (other modules) + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverage (other modules)Lines:94952901432.7 %
Date:2024-02-22 21:58:47Functions:715121458.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
lapack +
25.2%25.2%
+
25.2 %3838 / 1522635.9 %65 / 181
asmjit +
31.4%31.4%
+
31.4 %2235 / 712439.5 %139 / 352
molfile +
40.9%40.9%
+
40.9 %861 / 210445.2 %56 / 124
xdrfile +
48.3%48.3%
+
48.3 %563 / 116646.2 %43 / 93
blas +
25.2%25.2%
+
25.2 %405 / 160547.2 %17 / 36
lepton +
89.0%89.0%
+
89.0 %1593 / 178992.3 %395 / 428
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/index-sort-l.html b/coverage-libs/index-sort-l.html new file mode 100644 index 000000000000..38f4e6c18991 --- /dev/null +++ b/coverage-libs/index-sort-l.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage (other modules) + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverage (other modules)Lines:94952901432.7 %
Date:2024-02-22 21:58:47Functions:715121458.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
blas +
25.2%25.2%
+
25.2 %405 / 160547.2 %17 / 36
lapack +
25.2%25.2%
+
25.2 %3838 / 1522635.9 %65 / 181
asmjit +
31.4%31.4%
+
31.4 %2235 / 712439.5 %139 / 352
molfile +
40.9%40.9%
+
40.9 %861 / 210445.2 %56 / 124
xdrfile +
48.3%48.3%
+
48.3 %563 / 116646.2 %43 / 93
lepton +
89.0%89.0%
+
89.0 %1593 / 178992.3 %395 / 428
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/index.html b/coverage-libs/index.html new file mode 100644 index 000000000000..9480fc889bc6 --- /dev/null +++ b/coverage-libs/index.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage (other modules) + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverage (other modules)Lines:94952901432.7 %
Date:2024-02-22 21:58:47Functions:715121458.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
asmjit +
31.4%31.4%
+
31.4 %2235 / 712439.5 %139 / 352
blas +
25.2%25.2%
+
25.2 %405 / 160547.2 %17 / 36
lapack +
25.2%25.2%
+
25.2 %3838 / 1522635.9 %65 / 181
lepton +
89.0%89.0%
+
89.0 %1593 / 178992.3 %395 / 428
molfile +
40.9%40.9%
+
40.9 %861 / 210445.2 %56 / 124
xdrfile +
48.3%48.3%
+
48.3 %563 / 116646.2 %43 / 93
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/index-sort-f.html b/coverage-libs/lapack/index-sort-f.html new file mode 100644 index 000000000000..52ecade13460 --- /dev/null +++ b/coverage-libs/lapack/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapackHitTotalCoverage
Test:plumed test coverage (other modules)Lines:38381522625.2 %
Date:2024-02-22 21:58:47Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
lapack.cpp +
25.2%25.2%
+
25.2 %3838 / 1522635.9 %65 / 181
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/index-sort-l.html b/coverage-libs/lapack/index-sort-l.html new file mode 100644 index 000000000000..9180d1f2644d --- /dev/null +++ b/coverage-libs/lapack/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapackHitTotalCoverage
Test:plumed test coverage (other modules)Lines:38381522625.2 %
Date:2024-02-22 21:58:47Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
lapack.cpp +
25.2%25.2%
+
25.2 %3838 / 1522635.9 %65 / 181
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/index.html b/coverage-libs/lapack/index.html new file mode 100644 index 000000000000..5a88526e0a9f --- /dev/null +++ b/coverage-libs/lapack/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapackHitTotalCoverage
Test:plumed test coverage (other modules)Lines:38381522625.2 %
Date:2024-02-22 21:58:47Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
lapack.cpp +
25.2%25.2%
+
25.2 %3838 / 1522635.9 %65 / 181
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/lapack.cpp.func-sort-c.html b/coverage-libs/lapack/lapack.cpp.func-sort-c.html new file mode 100644 index 000000000000..f9055884d279 --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.func-sort-c.html @@ -0,0 +1,797 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack/lapack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapack - lapack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:38381522625.2 %
Date:2024-02-22 21:58:47Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lapack6dlae2_EPdS1_S1_S1_S1_0
_ZN4PLMD6lapack6slae2_EPfS1_S1_S1_S1_0
_ZN4PLMD6lapack6slarf_EPKcPiS3_PfS3_S4_S4_S3_S4_0
_ZN4PLMD6lapack6slas2_EPfS1_S1_S1_S1_0
_ZN4PLMD6lapack6slasr_EPKcS2_S2_PiS3_PfS4_S4_S3_0
_ZN4PLMD6lapack7dgelq2_EPiS1_PdS1_S2_S2_S1_0
_ZN4PLMD6lapack7dgelqf_EPiS1_PdS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dgetrs_EPKcPiS3_PdS3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7dlaebz_EPiS1_S1_S1_S1_S1_PdS2_S2_S2_S2_S2_S1_S2_S2_S1_S1_S2_S1_S1_0
_ZN4PLMD6lapack7dlaev2_EPdS1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7dlagtf_EPiPdS2_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dlagts_EPiS1_PdS2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7dlarnv_EPiS1_S1_Pd0
_ZN4PLMD6lapack7dlaruv_EPiS1_Pd0
_ZN4PLMD6lapack7dlasd5_EPiPdS2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7dlasd6_EPiS1_S1_S1_PdS2_S2_S2_S2_S1_S1_S1_S1_S1_S2_S1_S2_S2_S2_S2_S1_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dlasd7_EPiS1_S1_S1_S1_PdS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S1_S1_S1_S1_S1_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7dlasd8_EPiS1_PdS2_S2_S2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7dlasda_EPiS1_S1_S1_PdS2_S2_S1_S2_S1_S2_S2_S2_S2_S1_S1_S1_S1_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dlasq1_EPiPdS2_S2_S1_0
_ZN4PLMD6lapack7dlasq6_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7dlassq_EPiPdS1_S2_S2_0
_ZN4PLMD6lapack7dlaswp_EPiPdS1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7dorgbr_EPKcPiS3_S3_PdS3_S4_S4_S3_S3_0
_ZN4PLMD6lapack7dorgl2_EPiS1_S1_PdS1_S2_S2_S1_0
_ZN4PLMD6lapack7dorglq_EPiS1_S1_PdS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dstebz_EPKcS2_PiPdS4_S3_S3_S4_S4_S4_S3_S3_S4_S3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7dstein_EPiPdS2_S1_S2_S1_S1_S2_S1_S2_S1_S1_S1_0
_ZN4PLMD6lapack7dsteqr_EPKcPiPdS4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7dsterf_EPiPdS2_S1_0
_ZN4PLMD6lapack7dstevr_EPKcS2_PiPdS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7sbdsdc_EPKcS2_PiPfS4_S4_S3_S4_S3_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sbdsqr_EPKcPiS3_S3_S3_PfS4_S4_S3_S4_S3_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sgebd2_EPiS1_PfS1_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7sgebrd_EPiS1_PfS1_S2_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sgelq2_EPiS1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sgelqf_EPiS1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sgeqr2_EPiS1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sgeqrf_EPiS1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sgesdd_EPKcPiS3_PfS3_S4_S4_S3_S4_S3_S4_S3_S3_S3_0
_ZN4PLMD6lapack7sgetf2_EPiS1_PfS1_S1_S1_0
_ZN4PLMD6lapack7sgetrf_EPiS1_PfS1_S1_S1_0
_ZN4PLMD6lapack7sgetri_EPiPfS1_S1_S2_S1_S1_0
_ZN4PLMD6lapack7sgetrs_EPKcPiS3_PfS3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7slabrd_EPiS1_S1_PfS1_S2_S2_S2_S2_S2_S1_S2_S1_0
_ZN4PLMD6lapack7slacpy_EPKcPiS3_PfS3_S4_S3_0
_ZN4PLMD6lapack7slaebz_EPiS1_S1_S1_S1_S1_PfS2_S2_S2_S2_S2_S1_S2_S2_S1_S1_S2_S1_S1_0
_ZN4PLMD6lapack7slaed6_EPiS1_PfS2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slaev2_EPfS1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slagtf_EPiPfS2_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7slagts_EPiS1_PfS2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7slamrg_EPiS1_PfS1_S1_S1_0
_ZN4PLMD6lapack7slange_EPKcPiS3_PfS3_S4_0
_ZN4PLMD6lapack7slanst_EPKcPiPfS4_0
_ZN4PLMD6lapack7slansy_EPKcS2_PiPfS3_S4_0
_ZN4PLMD6lapack7slarfb_EPKcS2_S2_S2_PiS3_S3_PfS3_S4_S3_S4_S3_S4_S3_0
_ZN4PLMD6lapack7slarfg_EPiPfS2_S1_S2_0
_ZN4PLMD6lapack7slarft_EPKcS2_PiS3_PfS3_S4_S4_S3_0
_ZN4PLMD6lapack7slarnv_EPiS1_S1_Pf0
_ZN4PLMD6lapack7slartg_EPfS1_S1_S1_S1_0
_ZN4PLMD6lapack7slaruv_EPiS1_Pf0
_ZN4PLMD6lapack7slascl_EPKcPiS3_PfS4_S3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7slasd0_EPiS1_PfS2_S2_S1_S2_S1_S1_S1_S2_S1_0
_ZN4PLMD6lapack7slasd1_EPiS1_S1_PfS2_S2_S2_S1_S2_S1_S1_S1_S2_S1_0
_ZN4PLMD6lapack7slasd2_EPiS1_S1_S1_PfS2_S2_S2_S2_S1_S2_S1_S2_S2_S1_S2_S1_S1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slasd3_EPiS1_S1_S1_PfS2_S1_S2_S2_S1_S2_S1_S2_S1_S2_S1_S1_S1_S2_S1_0
_ZN4PLMD6lapack7slasd4_EPiS1_PfS2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slasd5_EPiPfS2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7slasd6_EPiS1_S1_S1_PfS2_S2_S2_S2_S1_S1_S1_S1_S1_S2_S1_S2_S2_S2_S2_S1_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7slasd7_EPiS1_S1_S1_S1_PfS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S1_S1_S1_S1_S1_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7slasd8_EPiS1_PfS2_S2_S2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7slasda_EPiS1_S1_S1_PfS2_S2_S1_S2_S1_S2_S2_S2_S2_S1_S1_S1_S1_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7slasdq_EPKcPiS3_S3_S3_S3_PfS4_S4_S3_S4_S3_S4_S3_S4_S3_0
_ZN4PLMD6lapack7slasdt_EPiS1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slaset_EPKcPiS3_PfS4_S4_S3_0
_ZN4PLMD6lapack7slasq1_EPiPfS2_S2_S1_0
_ZN4PLMD6lapack7slasq2_EPiPfS1_0
_ZN4PLMD6lapack7slasq3_EPiS1_PfS1_S2_S2_S2_S2_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slasq4_EPiS1_PfS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slasq5_EPiS1_PfS1_S2_S2_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slasq6_EPiS1_PfS1_S2_S2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7slasrt_EPKcPiPfS3_0
_ZN4PLMD6lapack7slassq_EPiPfS1_S2_S2_0
_ZN4PLMD6lapack7slasv2_EPfS1_S1_S1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slaswp_EPiPfS1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slatrd_EPKcPiS3_PfS3_S4_S4_S4_S3_0
_ZN4PLMD6lapack7sorg2r_EPiS1_S1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sorgbr_EPKcPiS3_S3_PfS3_S4_S4_S3_S3_0
_ZN4PLMD6lapack7sorgl2_EPiS1_S1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sorglq_EPiS1_S1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sorgqr_EPiS1_S1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sorm2l_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sorm2r_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sormbr_EPKcS2_S2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sorml2_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sormlq_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sormql_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sormqr_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sormtr_EPKcS2_S2_PiS3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sstebz_EPKcS2_PiPfS4_S3_S3_S4_S4_S4_S3_S3_S4_S3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sstegr_EPKcS2_PiPfS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7sstein_EPiPfS2_S1_S2_S1_S1_S2_S1_S2_S1_S1_S1_0
_ZN4PLMD6lapack7ssteqr_EPKcPiPfS4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7ssterf_EPiPfS2_S1_0
_ZN4PLMD6lapack7sstevr_EPKcS2_PiPfS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7ssyevr_EPKcS2_S2_PiPfS3_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7ssytd2_EPKcPiPfS3_S4_S4_S4_S3_0
_ZN4PLMD6lapack7ssytrd_EPKcPiPfS3_S4_S4_S4_S4_S3_S3_0
_ZN4PLMD6lapack7strti2_EPKcS2_PiPfS3_S3_0
_ZN4PLMD6lapack7strtri_EPKcS2_PiPfS3_S3_0
_ZN4PLMD6lapack8slar1vx_EPiS1_S1_PfS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S2_0
_ZN4PLMD6lapack8slarrbx_EPiPfS2_S2_S2_S1_S1_S2_S2_S1_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack8slarrex_EPKcPiPfS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_0
_ZN4PLMD6lapack8slarrfx_EPiPfS2_S2_S2_S1_S1_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack8slarrvx_EPiPfS2_S1_S1_S2_S1_S1_S2_S2_S2_S1_S1_S2_S1_S1_0
_ZN4PLMD6lapack8slasrt2_EPKcPiPfS3_S3_0
_ZN4PLMD6lapack7dgeqr2_EPiS1_PdS1_S2_S2_S1_1
_ZN4PLMD6lapack7dgeqrf_EPiS1_PdS1_S2_S2_S1_S1_1
_ZN4PLMD6lapack7dorg2r_EPiS1_S1_PdS1_S2_S2_S1_1
_ZN4PLMD6lapack7dorgqr_EPiS1_S1_PdS1_S2_S2_S1_S1_1
_ZN4PLMD6lapack7slapy2_EPfS1_1
_ZN4PLMD6lapack8dlasrt2_EPKcPiPdS3_S3_10
_ZN4PLMD6lapack8ilasrt2_EPKcPiS3_S3_S3_10
_ZN4PLMD6lapack7dlabrd_EPiS1_S1_PdS1_S2_S2_S2_S2_S2_S1_S2_S1_12
_ZN4PLMD6lapack7dlatrd_EPKcPiS3_PdS3_S4_S4_S4_S3_19
_ZN4PLMD6lapack7dlasd0_EPiS1_PdS2_S2_S1_S2_S1_S1_S1_S2_S1_29
_ZN4PLMD6lapack7dlasdt_EPiS1_S1_S1_S1_S1_S1_29
_ZN4PLMD6lapack7dlacpy_EPKcPiS3_PdS3_S4_S3_54
_ZN4PLMD6lapack7dgetf2_EPiS1_PdS1_S1_S1_57
_ZN4PLMD6lapack7dgetrf_EPiS1_PdS1_S1_S1_57
_ZN4PLMD6lapack7dtrti2_EPKcS2_PiPdS3_S3_57
_ZN4PLMD6lapack7dtrtri_EPKcS2_PiPdS3_S3_57
_ZN4PLMD6lapack7dlasd1_EPiS1_S1_PdS2_S2_S2_S1_S2_S1_S1_S1_S2_S1_59
_ZN4PLMD6lapack7dlasd2_EPiS1_S1_S1_PdS2_S2_S2_S2_S1_S2_S1_S2_S2_S1_S2_S1_S1_S1_S1_S1_S1_S1_59
_ZN4PLMD6lapack7dlasd3_EPiS1_S1_S1_PdS2_S1_S2_S2_S1_S2_S1_S2_S1_S2_S1_S1_S1_S2_S1_59
_ZN4PLMD6lapack8dlarrfx_EPiPdS2_S2_S2_S1_S1_S2_S2_S2_S2_S2_S1_70
_ZN4PLMD6lapack7dorm2r_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_79
_ZN4PLMD6lapack7dorml2_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_83
_ZN4PLMD6lapack7dbdsdc_EPKcS2_PiPdS4_S4_S3_S4_S3_S4_S3_S4_S3_S3_96
_ZN4PLMD6lapack7dgebd2_EPiS1_PdS1_S2_S2_S2_S2_S2_S1_96
_ZN4PLMD6lapack7dgebrd_EPiS1_PdS1_S2_S2_S2_S2_S2_S1_S1_96
_ZN4PLMD6lapack7dlange_EPKcPiS3_PdS3_S4_96
_ZN4PLMD6lapack7dormlq_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_96
_ZN4PLMD6lapack7dormqr_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_96
_ZN4PLMD6lapack7dgetri_EPiPdS1_S1_S2_S1_S1_114
_ZN4PLMD6lapack7dlamrg_EPiS1_PdS1_S1_S1_118
_ZN4PLMD6lapack7dlarfb_EPKcS2_S2_S2_PiS3_S3_PdS3_S4_S3_S4_S3_S4_S3_147
_ZN4PLMD6lapack7dlarft_EPKcS2_PiS3_PdS3_S4_S4_S3_147
_ZN4PLMD6lapack7dbdsqr_EPKcPiS3_S3_S3_PdS4_S4_S3_S4_S3_S4_S3_S4_S3_155
_ZN4PLMD6lapack7dlasdq_EPKcPiS3_S3_S3_S3_PdS4_S4_S3_S4_S3_S4_S3_S4_S3_155
_ZN4PLMD6lapack7dlasv2_EPdS1_S1_S1_S1_S1_S1_S1_S1_180
_ZN4PLMD6lapack7dgesdd_EPKcPiS3_PdS3_S4_S4_S3_S4_S3_S4_S3_S3_S3_192
_ZN4PLMD6lapack7dormbr_EPKcS2_S2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_192
_ZN4PLMD6lapack7dlascl_EPKcPiS3_PdS4_S3_S3_S4_S3_S3_264
_ZN4PLMD6lapack7dlaed6_EPiS1_PdS2_S2_S2_S2_S1_1387
_ZN4PLMD6lapack7dlasd4_EPiS1_PdS2_S2_S2_S2_S2_S1_3251
_ZN4PLMD6lapack6dlas2_EPdS1_S1_S1_S1_4552
_ZN4PLMD6lapack6dlasr_EPKcS2_S2_PiS3_PdS4_S4_S3_9382
_ZN4PLMD6lapack7dlartg_EPdS1_S1_S1_S1_90519
_ZN4PLMD6lapack7dlasrt_EPKcPiPdS3_557314
_ZN4PLMD6lapack7dorm2l_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_569949
_ZN4PLMD6lapack7dormql_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_569961
_ZN4PLMD6lapack7dormtr_EPKcS2_S2_PiS3_PdS3_S4_S4_S3_S4_S3_S3_569961
_ZN4PLMD6lapack8dlarrvx_EPiPdS2_S1_S1_S2_S1_S1_S2_S2_S2_S1_S1_S2_S1_S1_569961
_ZN4PLMD6lapack7dlansy_EPKcS2_PiPdS3_S4_570005
_ZN4PLMD6lapack7dlasq2_EPiPdS1_570005
_ZN4PLMD6lapack7dstegr_EPKcS2_PiPdS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_570005
_ZN4PLMD6lapack7dsytd2_EPKcPiPdS3_S4_S4_S4_S3_570005
_ZN4PLMD6lapack7dsytrd_EPKcPiPdS3_S4_S4_S4_S4_S3_S3_570005
_ZN4PLMD6lapack8dlarrex_EPKcPiPdS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_570005
_ZN4PLMD6lapack7dlanst_EPKcPiPdS4_570034
_ZN4PLMD6lapack8dlarrbx_EPiPdS2_S2_S2_S1_S1_S2_S2_S1_S2_S2_S2_S2_S1_S1_570075
_ZN4PLMD6lapack7dlaset_EPKcPiS3_PdS4_S4_S3_570473
_ZN4PLMD6lapack7dsyevr_EPKcS2_S2_PiPdS3_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_584792
_ZN4PLMD6lapack8dlar1vx_EPiS1_S1_PdS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S2_608131
_ZN4PLMD6lapack7dlapy2_EPdS1_1119235
_ZN4PLMD6lapack7dlarfg_EPiPdS2_S1_S2_1689406
_ZN4PLMD6lapack6dlarf_EPKcPiS3_PdS3_S4_S4_S3_S4_1689932
_ZN4PLMD6lapack7dlasq4_EPiS1_PdS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_12568745
_ZN4PLMD6lapack7dlasq5_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_S2_S1_12568749
_ZN4PLMD6lapack7dlasq3_EPiS1_PdS1_S2_S2_S2_S2_S1_S1_S1_S1_13125530
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/lapack.cpp.func.html b/coverage-libs/lapack/lapack.cpp.func.html new file mode 100644 index 000000000000..604a888331f5 --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.func.html @@ -0,0 +1,797 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack/lapack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapack - lapack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:38381522625.2 %
Date:2024-02-22 21:58:47Functions:6518135.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lapack6dlae2_EPdS1_S1_S1_S1_0
_ZN4PLMD6lapack6dlarf_EPKcPiS3_PdS3_S4_S4_S3_S4_1689932
_ZN4PLMD6lapack6dlas2_EPdS1_S1_S1_S1_4552
_ZN4PLMD6lapack6dlasr_EPKcS2_S2_PiS3_PdS4_S4_S3_9382
_ZN4PLMD6lapack6slae2_EPfS1_S1_S1_S1_0
_ZN4PLMD6lapack6slarf_EPKcPiS3_PfS3_S4_S4_S3_S4_0
_ZN4PLMD6lapack6slas2_EPfS1_S1_S1_S1_0
_ZN4PLMD6lapack6slasr_EPKcS2_S2_PiS3_PfS4_S4_S3_0
_ZN4PLMD6lapack7dbdsdc_EPKcS2_PiPdS4_S4_S3_S4_S3_S4_S3_S4_S3_S3_96
_ZN4PLMD6lapack7dbdsqr_EPKcPiS3_S3_S3_PdS4_S4_S3_S4_S3_S4_S3_S4_S3_155
_ZN4PLMD6lapack7dgebd2_EPiS1_PdS1_S2_S2_S2_S2_S2_S1_96
_ZN4PLMD6lapack7dgebrd_EPiS1_PdS1_S2_S2_S2_S2_S2_S1_S1_96
_ZN4PLMD6lapack7dgelq2_EPiS1_PdS1_S2_S2_S1_0
_ZN4PLMD6lapack7dgelqf_EPiS1_PdS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dgeqr2_EPiS1_PdS1_S2_S2_S1_1
_ZN4PLMD6lapack7dgeqrf_EPiS1_PdS1_S2_S2_S1_S1_1
_ZN4PLMD6lapack7dgesdd_EPKcPiS3_PdS3_S4_S4_S3_S4_S3_S4_S3_S3_S3_192
_ZN4PLMD6lapack7dgetf2_EPiS1_PdS1_S1_S1_57
_ZN4PLMD6lapack7dgetrf_EPiS1_PdS1_S1_S1_57
_ZN4PLMD6lapack7dgetri_EPiPdS1_S1_S2_S1_S1_114
_ZN4PLMD6lapack7dgetrs_EPKcPiS3_PdS3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7dlabrd_EPiS1_S1_PdS1_S2_S2_S2_S2_S2_S1_S2_S1_12
_ZN4PLMD6lapack7dlacpy_EPKcPiS3_PdS3_S4_S3_54
_ZN4PLMD6lapack7dlaebz_EPiS1_S1_S1_S1_S1_PdS2_S2_S2_S2_S2_S1_S2_S2_S1_S1_S2_S1_S1_0
_ZN4PLMD6lapack7dlaed6_EPiS1_PdS2_S2_S2_S2_S1_1387
_ZN4PLMD6lapack7dlaev2_EPdS1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7dlagtf_EPiPdS2_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dlagts_EPiS1_PdS2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7dlamrg_EPiS1_PdS1_S1_S1_118
_ZN4PLMD6lapack7dlange_EPKcPiS3_PdS3_S4_96
_ZN4PLMD6lapack7dlanst_EPKcPiPdS4_570034
_ZN4PLMD6lapack7dlansy_EPKcS2_PiPdS3_S4_570005
_ZN4PLMD6lapack7dlapy2_EPdS1_1119235
_ZN4PLMD6lapack7dlarfb_EPKcS2_S2_S2_PiS3_S3_PdS3_S4_S3_S4_S3_S4_S3_147
_ZN4PLMD6lapack7dlarfg_EPiPdS2_S1_S2_1689406
_ZN4PLMD6lapack7dlarft_EPKcS2_PiS3_PdS3_S4_S4_S3_147
_ZN4PLMD6lapack7dlarnv_EPiS1_S1_Pd0
_ZN4PLMD6lapack7dlartg_EPdS1_S1_S1_S1_90519
_ZN4PLMD6lapack7dlaruv_EPiS1_Pd0
_ZN4PLMD6lapack7dlascl_EPKcPiS3_PdS4_S3_S3_S4_S3_S3_264
_ZN4PLMD6lapack7dlasd0_EPiS1_PdS2_S2_S1_S2_S1_S1_S1_S2_S1_29
_ZN4PLMD6lapack7dlasd1_EPiS1_S1_PdS2_S2_S2_S1_S2_S1_S1_S1_S2_S1_59
_ZN4PLMD6lapack7dlasd2_EPiS1_S1_S1_PdS2_S2_S2_S2_S1_S2_S1_S2_S2_S1_S2_S1_S1_S1_S1_S1_S1_S1_59
_ZN4PLMD6lapack7dlasd3_EPiS1_S1_S1_PdS2_S1_S2_S2_S1_S2_S1_S2_S1_S2_S1_S1_S1_S2_S1_59
_ZN4PLMD6lapack7dlasd4_EPiS1_PdS2_S2_S2_S2_S2_S1_3251
_ZN4PLMD6lapack7dlasd5_EPiPdS2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7dlasd6_EPiS1_S1_S1_PdS2_S2_S2_S2_S1_S1_S1_S1_S1_S2_S1_S2_S2_S2_S2_S1_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dlasd7_EPiS1_S1_S1_S1_PdS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S1_S1_S1_S1_S1_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7dlasd8_EPiS1_PdS2_S2_S2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7dlasda_EPiS1_S1_S1_PdS2_S2_S1_S2_S1_S2_S2_S2_S2_S1_S1_S1_S1_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dlasdq_EPKcPiS3_S3_S3_S3_PdS4_S4_S3_S4_S3_S4_S3_S4_S3_155
_ZN4PLMD6lapack7dlasdt_EPiS1_S1_S1_S1_S1_S1_29
_ZN4PLMD6lapack7dlaset_EPKcPiS3_PdS4_S4_S3_570473
_ZN4PLMD6lapack7dlasq1_EPiPdS2_S2_S1_0
_ZN4PLMD6lapack7dlasq2_EPiPdS1_570005
_ZN4PLMD6lapack7dlasq3_EPiS1_PdS1_S2_S2_S2_S2_S1_S1_S1_S1_13125530
_ZN4PLMD6lapack7dlasq4_EPiS1_PdS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_12568745
_ZN4PLMD6lapack7dlasq5_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_S2_S1_12568749
_ZN4PLMD6lapack7dlasq6_EPiS1_PdS1_S2_S2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7dlasrt_EPKcPiPdS3_557314
_ZN4PLMD6lapack7dlassq_EPiPdS1_S2_S2_0
_ZN4PLMD6lapack7dlasv2_EPdS1_S1_S1_S1_S1_S1_S1_S1_180
_ZN4PLMD6lapack7dlaswp_EPiPdS1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7dlatrd_EPKcPiS3_PdS3_S4_S4_S4_S3_19
_ZN4PLMD6lapack7dorg2r_EPiS1_S1_PdS1_S2_S2_S1_1
_ZN4PLMD6lapack7dorgbr_EPKcPiS3_S3_PdS3_S4_S4_S3_S3_0
_ZN4PLMD6lapack7dorgl2_EPiS1_S1_PdS1_S2_S2_S1_0
_ZN4PLMD6lapack7dorglq_EPiS1_S1_PdS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7dorgqr_EPiS1_S1_PdS1_S2_S2_S1_S1_1
_ZN4PLMD6lapack7dorm2l_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_569949
_ZN4PLMD6lapack7dorm2r_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_79
_ZN4PLMD6lapack7dormbr_EPKcS2_S2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_192
_ZN4PLMD6lapack7dorml2_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_83
_ZN4PLMD6lapack7dormlq_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_96
_ZN4PLMD6lapack7dormql_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_569961
_ZN4PLMD6lapack7dormqr_EPKcS2_PiS3_S3_PdS3_S4_S4_S3_S4_S3_S3_96
_ZN4PLMD6lapack7dormtr_EPKcS2_S2_PiS3_PdS3_S4_S4_S3_S4_S3_S3_569961
_ZN4PLMD6lapack7dstebz_EPKcS2_PiPdS4_S3_S3_S4_S4_S4_S3_S3_S4_S3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7dstegr_EPKcS2_PiPdS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_570005
_ZN4PLMD6lapack7dstein_EPiPdS2_S1_S2_S1_S1_S2_S1_S2_S1_S1_S1_0
_ZN4PLMD6lapack7dsteqr_EPKcPiPdS4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7dsterf_EPiPdS2_S1_0
_ZN4PLMD6lapack7dstevr_EPKcS2_PiPdS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7dsyevr_EPKcS2_S2_PiPdS3_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_584792
_ZN4PLMD6lapack7dsytd2_EPKcPiPdS3_S4_S4_S4_S3_570005
_ZN4PLMD6lapack7dsytrd_EPKcPiPdS3_S4_S4_S4_S4_S3_S3_570005
_ZN4PLMD6lapack7dtrti2_EPKcS2_PiPdS3_S3_57
_ZN4PLMD6lapack7dtrtri_EPKcS2_PiPdS3_S3_57
_ZN4PLMD6lapack7sbdsdc_EPKcS2_PiPfS4_S4_S3_S4_S3_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sbdsqr_EPKcPiS3_S3_S3_PfS4_S4_S3_S4_S3_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sgebd2_EPiS1_PfS1_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7sgebrd_EPiS1_PfS1_S2_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sgelq2_EPiS1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sgelqf_EPiS1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sgeqr2_EPiS1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sgeqrf_EPiS1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sgesdd_EPKcPiS3_PfS3_S4_S4_S3_S4_S3_S4_S3_S3_S3_0
_ZN4PLMD6lapack7sgetf2_EPiS1_PfS1_S1_S1_0
_ZN4PLMD6lapack7sgetrf_EPiS1_PfS1_S1_S1_0
_ZN4PLMD6lapack7sgetri_EPiPfS1_S1_S2_S1_S1_0
_ZN4PLMD6lapack7sgetrs_EPKcPiS3_PfS3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7slabrd_EPiS1_S1_PfS1_S2_S2_S2_S2_S2_S1_S2_S1_0
_ZN4PLMD6lapack7slacpy_EPKcPiS3_PfS3_S4_S3_0
_ZN4PLMD6lapack7slaebz_EPiS1_S1_S1_S1_S1_PfS2_S2_S2_S2_S2_S1_S2_S2_S1_S1_S2_S1_S1_0
_ZN4PLMD6lapack7slaed6_EPiS1_PfS2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slaev2_EPfS1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slagtf_EPiPfS2_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7slagts_EPiS1_PfS2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7slamrg_EPiS1_PfS1_S1_S1_0
_ZN4PLMD6lapack7slange_EPKcPiS3_PfS3_S4_0
_ZN4PLMD6lapack7slanst_EPKcPiPfS4_0
_ZN4PLMD6lapack7slansy_EPKcS2_PiPfS3_S4_0
_ZN4PLMD6lapack7slapy2_EPfS1_1
_ZN4PLMD6lapack7slarfb_EPKcS2_S2_S2_PiS3_S3_PfS3_S4_S3_S4_S3_S4_S3_0
_ZN4PLMD6lapack7slarfg_EPiPfS2_S1_S2_0
_ZN4PLMD6lapack7slarft_EPKcS2_PiS3_PfS3_S4_S4_S3_0
_ZN4PLMD6lapack7slarnv_EPiS1_S1_Pf0
_ZN4PLMD6lapack7slartg_EPfS1_S1_S1_S1_0
_ZN4PLMD6lapack7slaruv_EPiS1_Pf0
_ZN4PLMD6lapack7slascl_EPKcPiS3_PfS4_S3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7slasd0_EPiS1_PfS2_S2_S1_S2_S1_S1_S1_S2_S1_0
_ZN4PLMD6lapack7slasd1_EPiS1_S1_PfS2_S2_S2_S1_S2_S1_S1_S1_S2_S1_0
_ZN4PLMD6lapack7slasd2_EPiS1_S1_S1_PfS2_S2_S2_S2_S1_S2_S1_S2_S2_S1_S2_S1_S1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slasd3_EPiS1_S1_S1_PfS2_S1_S2_S2_S1_S2_S1_S2_S1_S2_S1_S1_S1_S2_S1_0
_ZN4PLMD6lapack7slasd4_EPiS1_PfS2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slasd5_EPiPfS2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7slasd6_EPiS1_S1_S1_PfS2_S2_S2_S2_S1_S1_S1_S1_S1_S2_S1_S2_S2_S2_S2_S1_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7slasd7_EPiS1_S1_S1_S1_PfS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S1_S1_S1_S1_S1_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7slasd8_EPiS1_PfS2_S2_S2_S2_S2_S1_S2_S2_S1_0
_ZN4PLMD6lapack7slasda_EPiS1_S1_S1_PfS2_S2_S1_S2_S1_S2_S2_S2_S2_S1_S1_S1_S1_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack7slasdq_EPKcPiS3_S3_S3_S3_PfS4_S4_S3_S4_S3_S4_S3_S4_S3_0
_ZN4PLMD6lapack7slasdt_EPiS1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slaset_EPKcPiS3_PfS4_S4_S3_0
_ZN4PLMD6lapack7slasq1_EPiPfS2_S2_S1_0
_ZN4PLMD6lapack7slasq2_EPiPfS1_0
_ZN4PLMD6lapack7slasq3_EPiS1_PfS1_S2_S2_S2_S2_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slasq4_EPiS1_PfS1_S1_S2_S2_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slasq5_EPiS1_PfS1_S2_S2_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack7slasq6_EPiS1_PfS1_S2_S2_S2_S2_S2_S2_0
_ZN4PLMD6lapack7slasrt_EPKcPiPfS3_0
_ZN4PLMD6lapack7slassq_EPiPfS1_S2_S2_0
_ZN4PLMD6lapack7slasv2_EPfS1_S1_S1_S1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slaswp_EPiPfS1_S1_S1_S1_S1_0
_ZN4PLMD6lapack7slatrd_EPKcPiS3_PfS3_S4_S4_S4_S3_0
_ZN4PLMD6lapack7sorg2r_EPiS1_S1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sorgbr_EPKcPiS3_S3_PfS3_S4_S4_S3_S3_0
_ZN4PLMD6lapack7sorgl2_EPiS1_S1_PfS1_S2_S2_S1_0
_ZN4PLMD6lapack7sorglq_EPiS1_S1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sorgqr_EPiS1_S1_PfS1_S2_S2_S1_S1_0
_ZN4PLMD6lapack7sorm2l_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sorm2r_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sormbr_EPKcS2_S2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sorml2_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7sormlq_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sormql_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sormqr_EPKcS2_PiS3_S3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sormtr_EPKcS2_S2_PiS3_PfS3_S4_S4_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sstebz_EPKcS2_PiPfS4_S3_S3_S4_S4_S4_S3_S3_S4_S3_S3_S4_S3_S3_0
_ZN4PLMD6lapack7sstegr_EPKcS2_PiPfS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7sstein_EPiPfS2_S1_S2_S1_S1_S2_S1_S2_S1_S1_S1_0
_ZN4PLMD6lapack7ssteqr_EPKcPiPfS4_S4_S3_S4_S3_0
_ZN4PLMD6lapack7ssterf_EPiPfS2_S1_0
_ZN4PLMD6lapack7sstevr_EPKcS2_PiPfS4_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7ssyevr_EPKcS2_S2_PiPfS3_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_0
_ZN4PLMD6lapack7ssytd2_EPKcPiPfS3_S4_S4_S4_S3_0
_ZN4PLMD6lapack7ssytrd_EPKcPiPfS3_S4_S4_S4_S4_S3_S3_0
_ZN4PLMD6lapack7strti2_EPKcS2_PiPfS3_S3_0
_ZN4PLMD6lapack7strtri_EPKcS2_PiPfS3_S3_0
_ZN4PLMD6lapack8dlar1vx_EPiS1_S1_PdS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S2_608131
_ZN4PLMD6lapack8dlarrbx_EPiPdS2_S2_S2_S1_S1_S2_S2_S1_S2_S2_S2_S2_S1_S1_570075
_ZN4PLMD6lapack8dlarrex_EPKcPiPdS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_570005
_ZN4PLMD6lapack8dlarrfx_EPiPdS2_S2_S2_S1_S1_S2_S2_S2_S2_S2_S1_70
_ZN4PLMD6lapack8dlarrvx_EPiPdS2_S1_S1_S2_S1_S1_S2_S2_S2_S1_S1_S2_S1_S1_569961
_ZN4PLMD6lapack8dlasrt2_EPKcPiPdS3_S3_10
_ZN4PLMD6lapack8ilasrt2_EPKcPiS3_S3_S3_10
_ZN4PLMD6lapack8slar1vx_EPiS1_S1_PfS2_S2_S2_S2_S2_S2_S2_S2_S2_S1_S1_S2_0
_ZN4PLMD6lapack8slarrbx_EPiPfS2_S2_S2_S1_S1_S2_S2_S1_S2_S2_S2_S2_S1_S1_0
_ZN4PLMD6lapack8slarrex_EPKcPiPfS4_S3_S3_S4_S4_S4_S3_S3_S3_S4_S3_S3_S4_S4_S3_S3_0
_ZN4PLMD6lapack8slarrfx_EPiPfS2_S2_S2_S1_S1_S2_S2_S2_S2_S2_S1_0
_ZN4PLMD6lapack8slarrvx_EPiPfS2_S1_S1_S2_S1_S1_S2_S2_S2_S1_S1_S2_S1_S1_0
_ZN4PLMD6lapack8slasrt2_EPKcPiPfS3_S3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lapack/lapack.cpp.gcov.html b/coverage-libs/lapack/lapack.cpp.gcov.html new file mode 100644 index 000000000000..ac95aed7a10c --- /dev/null +++ b/coverage-libs/lapack/lapack.cpp.gcov.html @@ -0,0 +1,31100 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lapack/lapack.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lapack - lapack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:38381522625.2 %
Date:2024-02-22 21:58:47Functions:6518135.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : These files are semi-automatic translations by f2c from the original netlib LAPACK library.
+       3             : The source has been modified to (mostly) use modern C formatting, and to get rid of
+       4             : compiler warnings. Any errors in doing this should be blamed on the GROMACS developers, and
+       5             : not the reference LAPACK implementation.
+       6             : 
+       7             : The reference LAPACK implementation is available from http://www.netlib.org/lapack 
+       8             : 
+       9             : LAPACK does not come with a formal named "license", but a general statement saying:
+      10             : 
+      11             : "The reference LAPACK is a freely-available software package. It is available from netlib
+      12             : via anonymous ftp and the World Wide Web. Thus, it can be included in commercial software
+      13             : packages (and has been). We only ask that proper credit be given to the authors."
+      14             : 
+      15             : While the rest of GROMACS is LGPL, we think it's only fair to give you the same rights to
+      16             : our modified LAPACK files as the original netlib versions, so do what you want with them.
+      17             : 
+      18             : However, be warned that we have only tested that they to the right thing in the cases used
+      19             : in GROMACS (primarily full & sparse matrix diagonalization), so in most cases it is a much
+      20             : better idea to use the full reference implementation.
+      21             : 
+      22             : Erik Lindahl, 2008-10-07.
+      23             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      24             : #if ! defined(__PLUMED_HAS_EXTERNAL_LAPACK)
+      25             : #include <cctype>
+      26             : #include <cmath>
+      27             : #include "blas/blas.h"
+      28             : #include "lapack.h"
+      29             : #include "lapack_limits.h"
+      30             : 
+      31             : #include "real.h"
+      32             : 
+      33             : #include "blas/blas.h"
+      34             : namespace PLMD{
+      35             : namespace lapack{
+      36             : using namespace blas;
+      37             : void
+      38          96 : PLUMED_BLAS_F77_FUNC(dbdsdc,DBDSDC)(const char *uplo, 
+      39             :         const char *compq, 
+      40             :         int *n,
+      41             :         double *d__, 
+      42             :         double *e, 
+      43             :         double *u, 
+      44             :         int *ldu,
+      45             :         double *vt, 
+      46             :         int *ldvt,
+      47             :         double *q,
+      48             :         int *iq,
+      49             :         double *work, 
+      50             :         int *iwork, 
+      51             :         int *info)
+      52             : {
+      53             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+      54             :     int i__, j, k;
+      55             :     double p, r__;
+      56             :     int z__, ic, ii, kk;
+      57             :     double cs;
+      58             :     int is, iu;
+      59             :     double sn;
+      60             :     int nm1;
+      61             :     double eps;
+      62             :     int ivt, difl, difr, ierr, perm, mlvl, sqre;
+      63             :     int poles, iuplo, nsize, start;
+      64             :     int givcol;
+      65             :     int icompq;
+      66             :     double orgnrm;
+      67             :     int givnum, givptr, qstart, smlsiz, wstart, smlszp;
+      68          96 :     double zero = 0.0;
+      69          96 :     double one = 1.0;
+      70          96 :     int c_0 = 0;
+      71          96 :     int c_1 = 1;
+      72             : 
+      73          96 :     --d__;
+      74          96 :     --e;
+      75          96 :     u_dim1 = *ldu;
+      76          96 :     u_offset = 1 + u_dim1;
+      77          96 :     u -= u_offset;
+      78          96 :     vt_dim1 = *ldvt;
+      79          96 :     vt_offset = 1 + vt_dim1;
+      80          96 :     vt -= vt_offset;
+      81          96 :     --q;
+      82          96 :     --iq;
+      83          96 :     --work;
+      84             :     --iwork;
+      85             : 
+      86             :     k = iu = z__ = ic = is = ivt = difl = difr = perm = 0;
+      87             :     poles = givnum = givptr = givcol = 0;
+      88             :     
+      89          96 :     smlsiz = DBDSDC_SMALLSIZE;
+      90          96 :     *info = 0;
+      91             : 
+      92          96 :     iuplo = (*uplo=='U' || *uplo=='u') ? 1 : 2;
+      93             : 
+      94          96 :     switch(*compq) {
+      95           0 :     case 'n':
+      96             :     case 'N':
+      97           0 :       icompq = 0;
+      98           0 :       break;
+      99           0 :     case 'p':
+     100             :     case 'P':
+     101           0 :       icompq = 1;
+     102           0 :       break;
+     103          96 :     case 'i':
+     104             :     case 'I':
+     105          96 :       icompq = 2;
+     106          96 :       break;
+     107             :     default:
+     108             :       return;
+     109             :     }
+     110             : 
+     111          96 :     if (*n <= 0) 
+     112             :         return;
+     113             :     
+     114          96 :     if (*n == 1) {
+     115           0 :         if (icompq == 1) {
+     116           0 :           q[1] = (d__[1]>0) ? 1.0 : -1.0;
+     117           0 :           q[smlsiz * *n + 1] = 1.;
+     118           0 :         } else if (icompq == 2) {
+     119           0 :           u[u_dim1 + 1] = (d__[1]>0) ? 1.0 : -1.0;
+     120           0 :           vt[vt_dim1 + 1] = 1.;
+     121             :         }
+     122           0 :         d__[1] = std::abs(d__[1]);
+     123           0 :         return;
+     124             :     }
+     125          96 :     nm1 = *n - 1;
+     126             :     wstart = 1;
+     127             :     qstart = 3;
+     128          96 :     if (icompq == 1) {
+     129           0 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &d__[1], &c_1, &q[1], &c_1);
+     130           0 :         i__1 = *n - 1;
+     131           0 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &e[1], &c_1, &q[*n + 1], &c_1);
+     132             :     }
+     133          96 :     if (iuplo == 2) {
+     134             :         qstart = 5;
+     135           0 :         wstart = (*n << 1) - 1;
+     136           0 :         i__1 = *n - 1;
+     137           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+     138           0 :             PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+     139           0 :             d__[i__] = r__;
+     140           0 :             e[i__] = sn * d__[i__ + 1];
+     141           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+     142           0 :             if (icompq == 1) {
+     143           0 :                 q[i__ + (*n << 1)] = cs;
+     144           0 :                 q[i__ + *n * 3] = sn;
+     145           0 :             } else if (icompq == 2) {
+     146           0 :                 work[i__] = cs;
+     147           0 :                 work[nm1 + i__] = -sn;
+     148             :             }
+     149             :         }
+     150             :     }
+     151          96 :     if (icompq == 0) {
+     152           0 :       PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U",&c_0,n,&c_0,&c_0,&c_0,&d__[1],&e[1],&vt[vt_offset],ldvt,
+     153           0 :               &u[u_offset], ldu, &u[u_offset], ldu, &work[wstart], info);
+     154           0 :         goto L40;
+     155             :     }
+     156          96 :     if (*n <= smlsiz) {
+     157          67 :         if (icompq == 2) {
+     158          67 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", n, n, &zero, &one, &u[u_offset], ldu);
+     159          67 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", n, n, &zero, &one, &vt[vt_offset], ldvt);
+     160          67 :             PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U",&c_0,n,n,n,&c_0,&d__[1],&e[1],&vt[vt_offset],ldvt,
+     161          67 :                     &u[u_offset],ldu,&u[u_offset],ldu,&work[wstart],info);
+     162           0 :         } else if (icompq == 1) {
+     163             :             iu = 1;
+     164           0 :             ivt = iu + *n;
+     165           0 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", n, n, &zero, &one, &q[iu + (qstart - 1) * *n], n);
+     166           0 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", n, n, &zero, &one, &q[ivt + (qstart - 1) * *n], n);
+     167           0 :             PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U", &c_0, n, n, n, &c_0, &d__[1], &e[1], 
+     168           0 :                     &q[ivt + (qstart - 1) * *n], n, &q[iu + (qstart - 1) * *n], 
+     169           0 :                     n, &q[iu + (qstart - 1) * *n], n, &work[wstart], info);
+     170             :         }
+     171          67 :         goto L40;
+     172             :     }
+     173             : 
+     174          29 :     if (icompq == 2) {
+     175          29 :         PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", n, n, &zero, &one, &u[u_offset], ldu);
+     176          29 :         PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", n, n, &zero, &one, &vt[vt_offset], ldvt);
+     177             :     }
+     178             : 
+     179          29 :     orgnrm = PLUMED_BLAS_F77_FUNC(dlanst,DLANST)("M", n, &d__[1], &e[1]);
+     180          29 :     if ( std::abs(orgnrm)<PLUMED_GMX_DOUBLE_MIN) {
+     181             :         return;
+     182             :     }
+     183          29 :     PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c_0, &c_0, &orgnrm, &one, n, &c_1, &d__[1], n, &ierr);
+     184          29 :     PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c_0, &c_0, &orgnrm, &one, &nm1, &c_1, &e[1], &nm1, &ierr);
+     185             : 
+     186             :     eps = PLUMED_GMX_DOUBLE_EPS;
+     187             : 
+     188          29 :     mlvl = (int) (std::log((double) (*n) / (double) (smlsiz + 1)) / 
+     189             :                   std::log(2.)) + 1;
+     190             :     smlszp = smlsiz + 1;
+     191             : 
+     192          29 :     if (icompq == 1) {
+     193             :         iu = 1;
+     194             :         ivt = smlsiz + 1;
+     195           0 :         difl = ivt + smlszp;
+     196           0 :         difr = difl + mlvl;
+     197           0 :         z__ = difr + (mlvl << 1);
+     198           0 :         ic = z__ + mlvl;
+     199           0 :         is = ic + 1;
+     200           0 :         poles = is + 1;
+     201           0 :         givnum = poles + (mlvl << 1);
+     202             : 
+     203             :         k = 1;
+     204             :         givptr = 2;
+     205             :         perm = 3;
+     206           0 :         givcol = perm + mlvl;
+     207             :     }
+     208             : 
+     209          29 :     i__1 = *n;
+     210        1453 :     for (i__ = 1; i__ <= i__1; ++i__) {
+     211        1424 :         if (std::abs(d__[i__]) < eps) 
+     212          40 :             d__[i__] = (d__[i__]>0) ? eps : -eps;
+     213             :     }
+     214             : 
+     215             :     start = 1;
+     216          29 :     sqre = 0;
+     217             : 
+     218          29 :     i__1 = nm1;
+     219        1424 :     for (i__ = 1; i__ <= i__1; ++i__) {
+     220        1395 :         if (std::abs(e[i__]) < eps || i__ == nm1) {
+     221          29 :             if (i__ < nm1) {
+     222           0 :                 nsize = i__ - start + 1;
+     223          29 :             } else if (std::abs(e[i__]) >= eps) {
+     224          24 :                 nsize = *n - start + 1;
+     225             :             } else {
+     226           5 :                 nsize = i__ - start + 1;
+     227           5 :                 if (icompq == 2) {
+     228           5 :                     u[*n + *n * u_dim1] = (d__[*n]>0) ? 1.0 : -1.0; 
+     229           5 :                     vt[*n + *n * vt_dim1] = 1.;
+     230           0 :                 } else if (icompq == 1) {
+     231           0 :                     q[*n + (qstart - 1) * *n] = (d__[*n]>0) ? 1.0 : -1.0; 
+     232           0 :                     q[*n + (smlsiz + qstart - 1) * *n] = 1.;
+     233             :                 }
+     234           5 :                 d__[*n] = std::abs(d__[*n]);
+     235             :             }
+     236          29 :             if (icompq == 2) {
+     237          29 :                 PLUMED_BLAS_F77_FUNC(dlasd0,DLASD0)(&nsize, &sqre, &d__[start], &e[start], 
+     238          29 :                         &u[start + start * u_dim1], ldu, 
+     239          29 :                         &vt[start + start * vt_dim1], 
+     240          29 :                         ldvt, &smlsiz, &iwork[1], &work[wstart], info);
+     241             :             } else {
+     242           0 :                 PLUMED_BLAS_F77_FUNC(dlasda,DLASDA)(&icompq, &smlsiz, &nsize, &sqre, &d__[start], 
+     243           0 :                         &e[start], &q[start + (iu + qstart - 2) * *n], n, 
+     244           0 :                         &q[start + (ivt + qstart - 2) * *n], &iq[start + k * *n],
+     245           0 :                         &q[start + (difl + qstart - 2) * *n], 
+     246           0 :                         &q[start + (difr + qstart - 2) * *n], 
+     247           0 :                         &q[start + (z__ + qstart - 2) * *n], 
+     248           0 :                         &q[start + (poles + qstart - 2) * *n], 
+     249           0 :                         &iq[start + givptr * *n], &iq[start + givcol * *n], n, 
+     250           0 :                         &iq[start + perm * *n], 
+     251           0 :                         &q[start + (givnum + qstart - 2) * *n], 
+     252           0 :                         &q[start + (ic + qstart - 2) * *n], 
+     253           0 :                         &q[start + (is + qstart - 2) * *n], &work[wstart], 
+     254             :                         &iwork[1], info);
+     255           0 :                 if (*info != 0) {
+     256             :                     return;
+     257             :                 }
+     258             :             }
+     259          29 :             start = i__ + 1;
+     260             :         }
+     261             :     }
+     262          29 :     PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c_0, &c_0, &one, &orgnrm, n, &c_1, &d__[1], n, &ierr);
+     263          96 : L40:
+     264          96 :     i__1 = *n;
+     265        2544 :     for (ii = 2; ii <= i__1; ++ii) {
+     266        2448 :         i__ = ii - 1;
+     267             :         kk = i__;
+     268        2448 :         p = d__[i__];
+     269        2448 :         i__2 = *n;
+     270      152041 :         for (j = ii; j <= i__2; ++j) {
+     271      149593 :             if (d__[j] > p) {
+     272             :                 kk = j;
+     273             :                 p = d__[j];
+     274             :             }
+     275             :         }
+     276        2448 :         if (kk != i__) {
+     277        1263 :             d__[kk] = d__[i__];
+     278        1263 :             d__[i__] = p;
+     279        1263 :             if (icompq == 1) {
+     280           0 :                 iq[i__] = kk;
+     281        1263 :             } else if (icompq == 2) {
+     282        1263 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(n, &u[i__ * u_dim1 + 1],&c_1,&u[kk*u_dim1+1],&c_1);
+     283        1263 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(n, &vt[i__ + vt_dim1], ldvt, &vt[kk + vt_dim1], ldvt);
+     284             :             }
+     285        1185 :         } else if (icompq == 1) {
+     286           0 :             iq[i__] = i__;
+     287             :         }
+     288             :     }
+     289          96 :     if (icompq == 1) {
+     290           0 :         if (iuplo == 1) {
+     291           0 :             iq[*n] = 1;
+     292             :         } else {
+     293           0 :             iq[*n] = 0;
+     294             :         }
+     295             :     }
+     296          96 :     if (iuplo == 2 && icompq == 2) {
+     297           0 :         PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "B", n, n, &work[1], &work[*n], &u[u_offset], ldu);
+     298             :     }
+     299             : 
+     300             :     return;
+     301             : }
+     302             : }
+     303             : }
+     304             : #include <cctype>
+     305             : #include <cmath>
+     306             : 
+     307             : #include "blas/blas.h"
+     308             : #include "lapack.h"
+     309             : 
+     310             : #include "real.h"
+     311             : 
+     312             : #include "blas/blas.h"
+     313             : namespace PLMD{
+     314             : namespace lapack{
+     315             : using namespace blas;
+     316             : void 
+     317         155 : PLUMED_BLAS_F77_FUNC(dbdsqr,DBDSQR)(const char *uplo,
+     318             :                         int *n,
+     319             :                         int *ncvt,
+     320             :                         int *nru, 
+     321             :                         int *ncc, 
+     322             :                         double *d__,
+     323             :                         double *e,
+     324             :                         double *vt, 
+     325             :                         int *ldvt,
+     326             :                         double *u, 
+     327             :                         int *ldu,
+     328             :                         double *c__, 
+     329             :                         int *ldc,
+     330             :                         double *work,
+     331             :                         int *info)
+     332             : {
+     333         155 :     const char xuplo = std::toupper(*uplo);
+     334             :     int c_dim1, c_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, 
+     335             :             i__2;
+     336             :     double r__1, r__2, r__3, r__4;
+     337             :     double c_b15 = -.125;
+     338             : 
+     339         155 :     int c__1 = 1;
+     340             :     double c_b49 = 1.f;
+     341         155 :     double c_b72 = -1.f;
+     342             : 
+     343             :     double f, g, h__;
+     344             :     int i__, j, m;
+     345             :     double r__, cs;
+     346             :     int ll;
+     347             :     double sn, mu;
+     348             :     int nm1, nm12, nm13, lll;
+     349             :     double eps, sll, tol, abse;
+     350             :     int idir;
+     351             :     double abss;
+     352             :     int oldm;
+     353             :     double cosl;
+     354             :     int isub, iter;
+     355             :     double unfl, sinl, cosr, smin, smax, sinr;
+     356             :     double oldcs;
+     357             :     int oldll;
+     358         155 :     double shift, sigmn, oldsn = 0.;
+     359             :     int maxit;
+     360             :     double sminl;
+     361             :     double sigmx;
+     362             :     int lower;
+     363             :     double sminoa;
+     364             :     double thresh;
+     365             :     int rotate;
+     366             :     double tolmul;
+     367             :     int itmp1,itmp2;
+     368             :     
+     369         155 :     --d__;
+     370         155 :     --e;
+     371         155 :     vt_dim1 = *ldvt;
+     372         155 :     vt_offset = 1 + vt_dim1;
+     373         155 :     vt -= vt_offset;
+     374         155 :     u_dim1 = *ldu;
+     375         155 :     u_offset = 1 + u_dim1;
+     376         155 :     u -= u_offset;
+     377         155 :     c_dim1 = *ldc;
+     378         155 :     c_offset = 1 + c_dim1;
+     379         155 :     c__ -= c_offset;
+     380         155 :     --work;
+     381             : 
+     382         155 :     *info = 0;
+     383             :     
+     384         155 :     itmp1 = (*n > 1) ? *n : 1;
+     385         155 :     itmp2 = (*nru > 1) ? *nru : 1;
+     386             :     
+     387             :     lower = (xuplo == 'L');
+     388         155 :     if ( (xuplo!='U') && !lower) {
+     389           0 :         *info = -1;
+     390         155 :     } else if (*n < 0) {
+     391           0 :         *info = -2;
+     392         155 :     } else if (*ncvt < 0) {
+     393           0 :         *info = -3;
+     394         155 :     } else if (*nru < 0) {
+     395           0 :         *info = -4;
+     396         155 :     } else if (*ncc < 0) {
+     397           0 :         *info = -5;
+     398         155 :     } else if ( ((*ncvt == 0) && (*ldvt < 1)) || ((*ncvt > 0) && (*ldvt < itmp1)) ) {
+     399           0 :         *info = -9;
+     400         155 :     } else if (*ldu < itmp2) {
+     401           0 :         *info = -11;
+     402         155 :     } else if ( ((*ncc == 0) && (*ldc < 1)) || ((*ncc > 0) && (*ldc < itmp1))) {
+     403           0 :         *info = -13;
+     404             :     }
+     405         155 :     if (*info != 0) {
+     406             :         return;
+     407             :     }
+     408         155 :     if (*n == 0) {
+     409             :         return;
+     410             :     }
+     411         155 :     if (*n == 1) {
+     412           0 :         goto L160;
+     413             :     }
+     414             : 
+     415         155 :     rotate = *ncvt > 0 || *nru > 0 || *ncc > 0;
+     416             : 
+     417             :     if (! rotate) {
+     418           0 :         PLUMED_BLAS_F77_FUNC(dlasq1,DLASQ1)(n, &d__[1], &e[1], &work[1], info);
+     419           0 :         return;
+     420             :     }
+     421             : 
+     422         155 :     nm1 = *n - 1;
+     423         155 :     nm12 = nm1 + nm1;
+     424         155 :     nm13 = nm12 + nm1;
+     425             :     idir = 0;
+     426             : 
+     427             :     eps = PLUMED_GMX_DOUBLE_EPS;
+     428             :     unfl = PLUMED_GMX_DOUBLE_MIN/PLUMED_GMX_DOUBLE_EPS;
+     429             : 
+     430         155 :     if (lower) {
+     431           0 :         i__1 = *n - 1;
+     432           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+     433           0 :             PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+     434           0 :             d__[i__] = r__;
+     435           0 :             e[i__] = sn * d__[i__ + 1];
+     436           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+     437           0 :             work[i__] = cs;
+     438           0 :             work[nm1 + i__] = sn;
+     439             :         }
+     440             : 
+     441           0 :         if (*nru > 0) {
+     442           0 :             PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "F", nru, n, &work[1], &work[*n], &u[u_offset], 
+     443             :                     ldu);
+     444             :         }
+     445           0 :         if (*ncc > 0) {
+     446           0 :             PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "F", n, ncc, &work[1], &work[*n], &c__[c_offset],
+     447             :                      ldc);
+     448             :         }
+     449             :     }
+     450             : 
+     451             :     r__3 = 100.f, r__4 = std::pow(PLUMED_GMX_DOUBLE_EPS,c_b15);
+     452         155 :     r__1 = 10.f, r__2 = (r__3<r__4) ? r__3 : r__4;
+     453             :     tolmul = (r__1>r__2) ? r__1 : r__2;
+     454             :     tol = tolmul * eps;
+     455             :     smax = 0.f;
+     456         155 :     i__1 = *n;
+     457        2635 :     for (i__ = 1; i__ <= i__1; ++i__) {
+     458        2480 :         r__2 = smax, r__3 = (r__1 = d__[i__], std::abs(r__1));
+     459        2480 :         smax = (r__2>r__3) ? r__2 : r__3;
+     460             :     }
+     461         155 :     i__1 = *n - 1;
+     462        2480 :     for (i__ = 1; i__ <= i__1; ++i__) {
+     463        2325 :         r__2 = smax, r__3 = (r__1 = e[i__], std::abs(r__1));
+     464        2325 :         smax = (r__2>r__3) ? r__2 : r__3;
+     465             :     }
+     466             :     sminl = 0.f;
+     467             :     if (tol >= 0.f) {
+     468         155 :         sminoa = std::abs(d__[1]);
+     469         155 :         if (sminoa == 0.f) {
+     470           0 :             goto L50;
+     471             :         }
+     472             :         mu = sminoa;
+     473         155 :         i__1 = *n;
+     474        2480 :         for (i__ = 2; i__ <= i__1; ++i__) {
+     475        2325 :             mu = (r__2 = d__[i__], std::abs(r__2)) * (mu / (mu + (r__1 = e[i__ - 
+     476        2325 :                     1], std::abs(r__1))));
+     477        2325 :             sminoa = (sminoa<mu) ? sminoa : mu;
+     478        2325 :             if (sminoa == 0.f) {
+     479           0 :                 goto L50;
+     480             :             }
+     481             :         }
+     482         155 : L50:
+     483         155 :         sminoa /=  std::sqrt((double) (*n));
+     484         155 :         r__1 = tol * sminoa, r__2 = *n * 6 * *n * unfl;
+     485         155 :         thresh = (r__1>r__2) ? r__1 : r__2;
+     486             :     } else {
+     487             :         r__1 = std::abs(tol) * smax, r__2 = *n * 6 * *n * unfl;
+     488             :         thresh = (r__1>r__2) ? r__1 : r__2;
+     489             :     }
+     490             :     maxit = *n * 6 * *n;
+     491             :     iter = 0;
+     492             :     oldll = -1;
+     493             :     oldm = -1;
+     494             :     m = *n;
+     495             : 
+     496        8153 : L60:
+     497             : 
+     498        8308 :     if (m <= 1) {
+     499         155 :         goto L160;
+     500             :     }
+     501        8153 :     if (iter > maxit) {
+     502           0 :         goto L200;
+     503             :     }
+     504             : 
+     505             :     if (tol < 0.f && (r__1 = d__[m], std::abs(r__1)) <= thresh) {
+     506             :         d__[m] = 0.f;
+     507             :     }
+     508        8153 :     smax = (r__1 = d__[m], std::abs(r__1));
+     509             :     smin = smax;
+     510        8153 :     i__1 = m - 1;
+     511       64129 :     for (lll = 1; lll <= i__1; ++lll) {
+     512       58204 :         ll = m - lll;
+     513       58204 :         abss = (r__1 = d__[ll], std::abs(r__1));
+     514       58204 :         abse = (r__1 = e[ll], std::abs(r__1));
+     515             :         if (tol < 0.f && abss <= thresh) {
+     516             :             d__[ll] = 0.f;
+     517             :         }
+     518       58204 :         if (abse <= thresh) {
+     519        2228 :             goto L80;
+     520             :         }
+     521       55976 :         smin = (smin<abss) ? smin : abss;
+     522       55976 :         r__1 = (smax>abss) ? smax : abss;
+     523       55976 :         smax = (r__1>abse) ? r__1 : abse;
+     524             :     }
+     525             :     ll = 0;
+     526        5925 :     goto L90;
+     527             : L80:
+     528        2228 :     e[ll] = 0.f;
+     529        2228 :     if (ll == m - 1) {
+     530             :         --m;
+     531        2119 :         goto L60;
+     532             :     }
+     533         109 : L90:
+     534        6034 :     ++ll;
+     535        6034 :     if (ll == m - 1) {
+     536         180 :         PLUMED_BLAS_F77_FUNC(dlasv2,DLASV2)(&d__[m - 1], &e[m - 1], &d__[m], &sigmn, &sigmx, &sinr, &cosr,
+     537             :                  &sinl, &cosl);
+     538         180 :         d__[m - 1] = sigmx;
+     539         180 :         e[m - 1] = 0.f;
+     540         180 :         d__[m] = sigmn;
+     541         180 :         if (*ncvt > 0) {
+     542         180 :             PLUMED_BLAS_F77_FUNC(drot,DROT)(ncvt, &vt[m - 1 + vt_dim1], ldvt, &vt[m + vt_dim1], ldvt, &
+     543             :                     cosr, &sinr);
+     544             :         }
+     545         180 :         if (*nru > 0) {
+     546         180 :             PLUMED_BLAS_F77_FUNC(drot,DROT)(nru, &u[(m - 1) * u_dim1 + 1], &c__1, &u[m * u_dim1 + 1], &
+     547             :                     c__1, &cosl, &sinl);
+     548             :         }
+     549         180 :         if (*ncc > 0) {
+     550           0 :             PLUMED_BLAS_F77_FUNC(drot,DROT)(ncc, &c__[m - 1 + c_dim1], ldc, &c__[m + c_dim1], ldc, &
+     551             :                     cosl, &sinl);
+     552             :         }
+     553         180 :         m += -2;
+     554         180 :         goto L60;
+     555             :     }
+     556        5854 :     if (ll > oldm || m < oldll) {
+     557         182 :         if ((r__1 = d__[ll], std::abs(r__1)) >= (r__2 = d__[m], std::abs(r__2))) {
+     558             :             idir = 1;
+     559             :         } else {
+     560             :             idir = 2;
+     561             :         }
+     562             :     }
+     563        5672 :     if (idir == 1) {
+     564             : 
+     565        5821 :         if( (std::abs(e[m-1]) <= std::abs(tol) * std::abs(d__[m])) ||
+     566             :             (tol<0.0 && std::abs(e[m-1])<=thresh)) {
+     567        1172 :             e[m - 1] = 0.f;
+     568        1172 :             goto L60;
+     569             :         }
+     570             :         if (tol >= 0.f) {
+     571        4649 :             mu = (r__1 = d__[ll], std::abs(r__1));
+     572             :             sminl = mu;
+     573             :             i__1 = m - 1;
+     574       49166 :             for (lll = ll; lll <= i__1; ++lll) {
+     575       44567 :                 if ((r__1 = e[lll], std::abs(r__1)) <= tol * mu) {
+     576          50 :                     e[lll] = 0.f;
+     577          50 :                     goto L60;
+     578             :                 }
+     579       44517 :                 mu = (r__2 = d__[lll + 1], std::abs(r__2)) * (mu / (mu + (r__1 = 
+     580             :                         e[lll], std::abs(r__1))));
+     581       44517 :                 sminl = (sminl<mu) ? sminl : mu;
+     582             :             }
+     583             :         }
+     584             :     } else {
+     585          33 :         if( (std::abs(e[ll]) <= std::abs(tol)*std::abs(d__[ll])) ||
+     586             :             (tol<0.0 && std::abs(e[ll])<=thresh)) {
+     587           0 :             e[ll] = 0.f;
+     588           0 :             goto L60;
+     589             :         }
+     590             :         if (tol >= 0.f) {
+     591          33 :             mu = (r__1 = d__[m], std::abs(r__1));
+     592             :             sminl = mu;
+     593          33 :             i__1 = ll;
+     594         305 :             for (lll = m - 1; lll >= i__1; --lll) {
+     595         272 :                 if ((r__1 = e[lll], std::abs(r__1)) <= tol * mu) {
+     596           0 :                     e[lll] = 0.f;
+     597           0 :                     goto L60;
+     598             :                 }
+     599         272 :                 mu = (r__2 = d__[lll], std::abs(r__2)) * (mu / (mu + (r__1 = e[
+     600             :                         lll], std::abs(r__1))));
+     601         272 :                 sminl = (sminl<mu) ? sminl : mu;
+     602             :             }
+     603             :         }
+     604             :     }
+     605             :     oldll = ll;
+     606             :     oldm = m;
+     607             : 
+     608        4632 :     r__1 = eps, r__2 = tol * .01f;
+     609        4632 :     if (tol >= 0.f && *n * tol * (sminl / smax) <= ((r__1>r__2) ? r__1 : r__2)) {
+     610          80 :         shift = 0.f;
+     611             :     } else {
+     612        4552 :         if (idir == 1) {
+     613        4519 :             sll = (r__1 = d__[ll], std::abs(r__1));
+     614        4519 :             PLUMED_BLAS_F77_FUNC(dlas2,DLAS2)(&d__[m - 1], &e[m - 1], &d__[m], &shift, &r__);
+     615             :         } else {
+     616          33 :             sll = (r__1 = d__[m], std::abs(r__1));
+     617          33 :             PLUMED_BLAS_F77_FUNC(dlas2,DLAS2)(&d__[ll], &e[ll], &d__[ll + 1], &shift, &r__);
+     618             :         }
+     619        4552 :         if (sll > 0.f) {
+     620        4552 :             r__1 = shift / sll;
+     621        4552 :             if (r__1 * r__1 < eps) {
+     622           0 :                 shift = 0.f;
+     623             :             }
+     624             :         }
+     625             :     }
+     626        4632 :     iter = iter + m - ll;
+     627        4632 :     if (shift == 0.f) {
+     628          80 :         if (idir == 1) {
+     629          80 :             cs = 1.f;
+     630          80 :             oldcs = 1.f;
+     631          80 :             i__1 = m - 1;
+     632        1346 :             for (i__ = ll; i__ <= i__1; ++i__) {
+     633        1266 :                 r__1 = d__[i__] * cs;
+     634        1266 :                 PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&r__1, &e[i__], &cs, &sn, &r__);
+     635        1266 :                 if (i__ > ll) {
+     636        1186 :                     e[i__ - 1] = oldsn * r__;
+     637             :                 }
+     638        1266 :                 r__1 = oldcs * r__;
+     639        1266 :                 r__2 = d__[i__ + 1] * sn;
+     640        1266 :                 PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
+     641        1266 :                 work[i__ - ll + 1] = cs;
+     642        1266 :                 work[i__ - ll + 1 + nm1] = sn;
+     643        1266 :                 work[i__ - ll + 1 + nm12] = oldcs;
+     644        1266 :                 work[i__ - ll + 1 + nm13] = oldsn;
+     645             :             }
+     646          80 :             h__ = d__[m] * cs;
+     647          80 :             d__[m] = h__ * oldcs;
+     648          80 :             e[m - 1] = h__ * oldsn;
+     649          80 :             if (*ncvt > 0) {
+     650          80 :                 i__1 = m - ll + 1;
+     651          80 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt[
+     652          80 :                         ll + vt_dim1], ldvt);
+     653             :             }
+     654          80 :             if (*nru > 0) {
+     655          80 :                 i__1 = m - ll + 1;
+     656          80 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13 
+     657          80 :                         + 1], &u[ll * u_dim1 + 1], ldu);
+     658             :             }
+     659          80 :             if (*ncc > 0) {
+     660           0 :                 i__1 = m - ll + 1;
+     661           0 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13 
+     662           0 :                         + 1], &c__[ll + c_dim1], ldc);
+     663             :             }
+     664          80 :             if ((r__1 = e[m - 1], std::abs(r__1)) <= thresh) {
+     665          75 :                 e[m - 1] = 0.f;
+     666             :             }
+     667             :         } else {
+     668           0 :             cs = 1.f;
+     669           0 :             oldcs = 1.f;
+     670           0 :             i__1 = ll + 1;
+     671           0 :             for (i__ = m; i__ >= i__1; --i__) {
+     672           0 :                 r__1 = d__[i__] * cs;
+     673           0 :                 PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&r__1, &e[i__ - 1], &cs, &sn, &r__);
+     674           0 :                 if (i__ < m) {
+     675           0 :                     e[i__] = oldsn * r__;
+     676             :                 }
+     677           0 :                 r__1 = oldcs * r__;
+     678           0 :                 r__2 = d__[i__ - 1] * sn;
+     679           0 :                 PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
+     680           0 :                 work[i__ - ll] = cs;
+     681           0 :                 work[i__ - ll + nm1] = -sn;
+     682           0 :                 work[i__ - ll + nm12] = oldcs;
+     683           0 :                 work[i__ - ll + nm13] = -oldsn;
+     684             :             }
+     685           0 :             h__ = d__[ll] * cs;
+     686           0 :             d__[ll] = h__ * oldcs;
+     687           0 :             e[ll] = h__ * oldsn;
+     688           0 :             if (*ncvt > 0) {
+     689           0 :                 i__1 = m - ll + 1;
+     690           0 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[
+     691           0 :                         nm13 + 1], &vt[ll + vt_dim1], ldvt);
+     692             :             }
+     693           0 :             if (*nru > 0) {
+     694           0 :                 i__1 = m - ll + 1;
+     695           0 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u[ll *
+     696           0 :                          u_dim1 + 1], ldu);
+     697             :             }
+     698           0 :             if (*ncc > 0) {
+     699           0 :                 i__1 = m - ll + 1;
+     700           0 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c__[
+     701           0 :                         ll + c_dim1], ldc);
+     702             :             }
+     703           0 :             if ((r__1 = e[ll], std::abs(r__1)) <= thresh) {
+     704           0 :                 e[ll] = 0.f;
+     705             :             }
+     706             :         }
+     707             :     } else {
+     708             : 
+     709        4552 :         if (idir == 1) {
+     710        4519 :             f = ((r__1 = d__[ll], std::abs(r__1)) - shift) * ( ((d__[ll] > 0) ? c_b49 : -c_b49) + shift / d__[ll]);
+     711        4519 :             g = e[ll];
+     712        4519 :             i__1 = m - 1;
+     713       47367 :             for (i__ = ll; i__ <= i__1; ++i__) {
+     714       42848 :                 PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&f, &g, &cosr, &sinr, &r__);
+     715       42848 :                 if (i__ > ll) {
+     716       38329 :                     e[i__ - 1] = r__;
+     717             :                 }
+     718       42848 :                 f = cosr * d__[i__] + sinr * e[i__];
+     719       42848 :                 e[i__] = cosr * e[i__] - sinr * d__[i__];
+     720       42848 :                 g = sinr * d__[i__ + 1];
+     721       42848 :                 d__[i__ + 1] = cosr * d__[i__ + 1];
+     722       42848 :                 PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&f, &g, &cosl, &sinl, &r__);
+     723       42848 :                 d__[i__] = r__;
+     724       42848 :                 f = cosl * e[i__] + sinl * d__[i__ + 1];
+     725       42848 :                 d__[i__ + 1] = cosl * d__[i__ + 1] - sinl * e[i__];
+     726       42848 :                 if (i__ < m - 1) {
+     727       38329 :                     g = sinl * e[i__ + 1];
+     728       38329 :                     e[i__ + 1] = cosl * e[i__ + 1];
+     729             :                 }
+     730       42848 :                 work[i__ - ll + 1] = cosr;
+     731       42848 :                 work[i__ - ll + 1 + nm1] = sinr;
+     732       42848 :                 work[i__ - ll + 1 + nm12] = cosl;
+     733       42848 :                 work[i__ - ll + 1 + nm13] = sinl;
+     734             :             }
+     735        4519 :             e[m - 1] = f;
+     736             : 
+     737        4519 :             if (*ncvt > 0) {
+     738        4519 :                 i__1 = m - ll + 1;
+     739        4519 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt[
+     740        4519 :                         ll + vt_dim1], ldvt);
+     741             :             }
+     742        4519 :             if (*nru > 0) {
+     743        4519 :                 i__1 = m - ll + 1;
+     744        4519 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13 
+     745        4519 :                         + 1], &u[ll * u_dim1 + 1], ldu);
+     746             :             }
+     747        4519 :             if (*ncc > 0) {
+     748           0 :                 i__1 = m - ll + 1;
+     749           0 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13 
+     750           0 :                         + 1], &c__[ll + c_dim1], ldc);
+     751             :             }
+     752        4519 :             if ((r__1 = e[m - 1], std::abs(r__1)) <= thresh) {
+     753         834 :                 e[m - 1] = 0.f;
+     754             :             }
+     755             :         } else {
+     756             : 
+     757          33 :             f = ((r__1 = d__[m], std::abs(r__1)) - shift) * ( ((d__[m] > 0) ? c_b49 : -c_b49) + shift / d__[m]);
+     758          33 :             g = e[m - 1];
+     759          33 :             i__1 = ll + 1;
+     760         305 :             for (i__ = m; i__ >= i__1; --i__) {
+     761         272 :                 PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&f, &g, &cosr, &sinr, &r__);
+     762         272 :                 if (i__ < m) {
+     763         239 :                     e[i__] = r__;
+     764             :                 }
+     765         272 :                 f = cosr * d__[i__] + sinr * e[i__ - 1];
+     766         272 :                 e[i__ - 1] = cosr * e[i__ - 1] - sinr * d__[i__];
+     767         272 :                 g = sinr * d__[i__ - 1];
+     768         272 :                 d__[i__ - 1] = cosr * d__[i__ - 1];
+     769         272 :                 PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&f, &g, &cosl, &sinl, &r__);
+     770         272 :                 d__[i__] = r__;
+     771         272 :                 f = cosl * e[i__ - 1] + sinl * d__[i__ - 1];
+     772         272 :                 d__[i__ - 1] = cosl * d__[i__ - 1] - sinl * e[i__ - 1];
+     773         272 :                 if (i__ > ll + 1) {
+     774         239 :                     g = sinl * e[i__ - 2];
+     775         239 :                     e[i__ - 2] = cosl * e[i__ - 2];
+     776             :                 }
+     777         272 :                 work[i__ - ll] = cosr;
+     778         272 :                 work[i__ - ll + nm1] = -sinr;
+     779         272 :                 work[i__ - ll + nm12] = cosl;
+     780         272 :                 work[i__ - ll + nm13] = -sinl;
+     781             :             }
+     782          33 :             e[ll] = f;
+     783             : 
+     784          33 :             if ((r__1 = e[ll], std::abs(r__1)) <= thresh) {
+     785          12 :                 e[ll] = 0.f;
+     786             :             }
+     787          33 :             if (*ncvt > 0) {
+     788          33 :                 i__1 = m - ll + 1;
+     789          33 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[
+     790          33 :                         nm13 + 1], &vt[ll + vt_dim1], ldvt);
+     791             :             }
+     792          33 :             if (*nru > 0) {
+     793          33 :                 i__1 = m - ll + 1;
+     794          33 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u[ll *
+     795          33 :                          u_dim1 + 1], ldu);
+     796             :             }
+     797          33 :             if (*ncc > 0) {
+     798           0 :                 i__1 = m - ll + 1;
+     799           0 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c__[
+     800           0 :                         ll + c_dim1], ldc);
+     801             :             }
+     802             :         }
+     803             :     }
+     804             : 
+     805        4632 :     goto L60;
+     806             : 
+     807         155 : L160:
+     808         155 :     i__1 = *n;
+     809        2635 :     for (i__ = 1; i__ <= i__1; ++i__) {
+     810        2480 :         if (d__[i__] < 0.f) {
+     811         531 :             d__[i__] = -d__[i__];
+     812             : 
+     813         531 :             if (*ncvt > 0) {
+     814         531 :                 PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(ncvt, &c_b72, &vt[i__ + vt_dim1], ldvt);
+     815             :             }
+     816             :         }
+     817             :     }
+     818             : 
+     819         155 :     i__1 = *n - 1;
+     820        2480 :     for (i__ = 1; i__ <= i__1; ++i__) {
+     821             : 
+     822             :         isub = 1;
+     823        2325 :         smin = d__[1];
+     824        2325 :         i__2 = *n + 1 - i__;
+     825       22122 :         for (j = 2; j <= i__2; ++j) {
+     826       19797 :             if (d__[j] <= smin) {
+     827             :                 isub = j;
+     828             :                 smin = d__[j];
+     829             :             }
+     830             :         }
+     831        2325 :         if (isub != *n + 1 - i__) {
+     832         179 :             d__[isub] = d__[*n + 1 - i__];
+     833         179 :             d__[*n + 1 - i__] = smin;
+     834         179 :             if (*ncvt > 0) {
+     835         179 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(ncvt, &vt[isub + vt_dim1], ldvt, &vt[*n + 1 - i__ + 
+     836         179 :                         vt_dim1], ldvt);
+     837             :             }
+     838         179 :             if (*nru > 0) {
+     839         179 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(nru, &u[isub * u_dim1 + 1], &c__1, &u[(*n + 1 - i__) * 
+     840         179 :                         u_dim1 + 1], &c__1);
+     841             :             }
+     842         179 :             if (*ncc > 0) {
+     843           0 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(ncc, &c__[isub + c_dim1], ldc, &c__[*n + 1 - i__ + 
+     844           0 :                         c_dim1], ldc);
+     845             :             }
+     846             :         }
+     847             :     }
+     848         155 :     goto L220;
+     849             : 
+     850             : L200:
+     851           0 :     *info = 0;
+     852           0 :     i__1 = *n - 1;
+     853           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+     854           0 :         if (e[i__] != 0.f) {
+     855           0 :             ++(*info);
+     856             :         }
+     857             :     }
+     858           0 : L220:
+     859             :     return;
+     860             : 
+     861             : }
+     862             : 
+     863             : 
+     864             : }
+     865             : }
+     866             : #include "lapack.h"
+     867             : 
+     868             : #include "blas/blas.h"
+     869             : namespace PLMD{
+     870             : namespace lapack{
+     871             : using namespace blas;
+     872             : void
+     873          96 : PLUMED_BLAS_F77_FUNC(dgebd2,DGEBD2)(int *m,
+     874             :         int *n,
+     875             :         double *a,
+     876             :         int *lda,
+     877             :         double *d,
+     878             :         double *e,
+     879             :         double *tauq,
+     880             :         double *taup,
+     881             :         double *work,
+     882             :         int *info)
+     883             : {
+     884             :   int i,i1,i2,i3;
+     885             :     
+     886          96 :     *info = 0;
+     887             : 
+     888          96 :   if(*m>=*n) {
+     889             :     /* reduce to upper bidiag. form */
+     890        2256 :     for(i=0;i<*n;i++) {
+     891        2160 :       i1 = *m - i;
+     892        2160 :       i2 = ( (i+1) < (*m-1)) ? (i+1) : (*m-1);
+     893        2160 :       i3 = 1;
+     894        2160 :       PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i*(*lda)+i2]),&i3,&(tauq[i]));
+     895        2160 :       d[i] = a[i*(*lda)+i];
+     896        2160 :       a[i*(*lda)+i] = 1.0;
+     897        2160 :       i2 = *n - i - 1;
+     898        2160 :       PLUMED_BLAS_F77_FUNC(dlarf,DLARF)("L",&i1,&i2,&(a[i*(*lda)+i]),&i3,&(tauq[i]),&(a[(i+1)*(*lda)+i]),lda,work);
+     899        2160 :       a[i*(*lda)+i] = d[i];
+     900             : 
+     901        2160 :       if(i<(*n-1)) {
+     902             : 
+     903        2064 :         i1 = *n - i -1;
+     904        2064 :         i2 = ( (i+2) < (*n-1)) ? (i+2) : (*n-1); 
+     905        2064 :         PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i1,&(a[(i+1)*(*lda)+i]),&(a[i2*(*lda)+i]),lda,&(taup[i]));
+     906             : 
+     907        2064 :         e[i] = a[(i+1)*(*lda)+i];
+     908        2064 :         a[(i+1)*(*lda)+i] = 1.0;
+     909             : 
+     910        2064 :         i1 = *m - i - 1;
+     911        2064 :         i2 = *n - i - 1;
+     912        2064 :         PLUMED_BLAS_F77_FUNC(dlarf,DLARF)("R",&i1,&i2,&(a[(i+1)*(*lda)+i]),lda,&(taup[i]),&(a[(i+1)*(*lda)+i+1]),lda,work);
+     913        2064 :         a[(i+1)*(*lda)+i] = e[i];
+     914             :       } else
+     915          96 :         taup[i] = 0.0;
+     916             :     }
+     917             :   } else {
+     918             :     /* reduce to lower bidiag. form */
+     919           0 :     for(i=0;i<*m;i++) {
+     920           0 :       i1 = *n - i;
+     921           0 :       i2 = ( (i+1) < (*n-1)) ? (i+1) : (*n-1);
+     922           0 :       PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i2*(*lda)+i]),lda,&(taup[i]));
+     923           0 :       d[i] = a[i*(*lda)+i];
+     924           0 :       a[i*(*lda)+i] = 1.0;
+     925             : 
+     926           0 :       i2 = *m - i - 1;
+     927           0 :       i3 = ( (i+1) < (*m-1)) ? (i+1) : (*m-1);
+     928           0 :       PLUMED_BLAS_F77_FUNC(dlarf,DLARF)("R",&i2,&i1,&(a[i*(*lda)+i]),lda,&(taup[i]),&(a[(i)*(*lda)+i3]),lda,work);
+     929           0 :       a[i*(*lda)+i] = d[i];
+     930             : 
+     931           0 :       if(i<(*m-1)) {
+     932             : 
+     933           0 :         i1 = *m - i - 1;
+     934           0 :         i2 = ( (i+2) < (*m-1)) ? (i+2) : (*m-1);
+     935           0 :         i3 = 1;
+     936           0 :         PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i1,&(a[(i)*(*lda)+i+1]),&(a[i*(*lda)+i2]),&i3,&(tauq[i]));
+     937             : 
+     938           0 :         e[i] = a[(i)*(*lda)+i+1];
+     939           0 :         a[(i)*(*lda)+i+1] = 1.0;
+     940             : 
+     941           0 :         i1 = *m - i - 1;
+     942           0 :         i2 = *n - i - 1;
+     943           0 :         i3 = 1;
+     944           0 :         PLUMED_BLAS_F77_FUNC(dlarf,DLARF)("L",&i1,&i2,&(a[(i)*(*lda)+i+1]),&i3,&(tauq[i]),&(a[(i+1)*(*lda)+i+1]),lda,work);
+     945           0 :         a[(i)*(*lda)+i+1] = e[i];
+     946             :       } else
+     947           0 :         tauq[i] = 0.0;
+     948             :     }
+     949             :   }
+     950          96 :   return;
+     951             : }
+     952             : }
+     953             : }
+     954             : #include "lapack.h"
+     955             : #include "blas/blas.h"
+     956             : #include "lapack_limits.h"
+     957             : 
+     958             : 
+     959             : #include "blas/blas.h"
+     960             : namespace PLMD{
+     961             : namespace lapack{
+     962             : using namespace blas;
+     963             : void
+     964          96 : PLUMED_BLAS_F77_FUNC(dgebrd,DGEBRD)(int *m, 
+     965             :         int *n, 
+     966             :         double *a, 
+     967             :         int *lda, 
+     968             :         double *d__, 
+     969             :         double *e,
+     970             :         double *tauq, 
+     971             :         double *taup,
+     972             :         double *work, 
+     973             :         int *lwork,
+     974             :         int *info)
+     975             : {
+     976             :     /* System generated locals */
+     977             :     int a_dim1, a_offset, i_1, i_2, i_3, i_4;
+     978             : 
+     979             :     /* Local variables */
+     980             :     int i_, j, nx,nb;
+     981             :     double ws;
+     982             :     int nbmin, iinfo, minmn;
+     983             :     int ldwrkx, ldwrky;
+     984          96 :     double one = 1.0;
+     985          96 :     double minusone = -1.0;
+     986             : 
+     987          96 :     a_dim1 = *lda;
+     988          96 :     a_offset = 1 + a_dim1;
+     989          96 :     a -= a_offset;
+     990          96 :     --d__;
+     991          96 :     --e;
+     992          96 :     --tauq;
+     993          96 :     --taup;
+     994          96 :     --work;
+     995             : 
+     996          96 :     nb = DGEBRD_BLOCKSIZE;
+     997          96 :     *info = 0;
+     998          96 :     if (*lwork==-1) {
+     999           0 :       work[1] = (double) ( (*m + *n) * nb);
+    1000           0 :       return;
+    1001             :     }
+    1002          96 :     minmn = (*m < *n) ? *m : *n;
+    1003          96 :     if (minmn == 0) {
+    1004           0 :       work[1] = 1.;
+    1005           0 :       return;
+    1006             :     }
+    1007             : 
+    1008          96 :     ws = (*m > *n) ? *m : *n;
+    1009          96 :     ldwrkx = *m;
+    1010          96 :     ldwrky = *n;
+    1011             : 
+    1012          96 :     if (nb > 1 && nb < minmn) {
+    1013             :         nx = DGEBRD_CROSSOVER;
+    1014          17 :         if (nx < minmn) {
+    1015           1 :             ws = (double) ((*m + *n) * nb);
+    1016           1 :             if ((double) (*lwork) < ws) {
+    1017             :               nbmin = DGEBRD_MINBLOCKSIZE;
+    1018           0 :                 if (*lwork >= (*m + *n) * nbmin) {
+    1019           0 :                     nb = *lwork / (*m + *n);
+    1020             :                 } else {
+    1021           0 :                     nb = 1;
+    1022             :                     nx = minmn;
+    1023             :                 }
+    1024             :             }
+    1025             :         }
+    1026             :     } else {
+    1027             :         nx = minmn;
+    1028             :     }
+    1029             : 
+    1030          96 :     i_1 = minmn - nx;
+    1031          96 :     i_2 = nb;
+    1032         108 :     for (i_ = 1; i_2 < 0 ? i_ >= i_1 : i_ <= i_1; i_ += i_2) {
+    1033             : 
+    1034          12 :         i_3 = *m - i_ + 1;
+    1035          12 :         i_4 = *n - i_ + 1;
+    1036          12 :         PLUMED_BLAS_F77_FUNC(dlabrd,DLABRD)(&i_3, &i_4, &nb, &a[i_ + i_ * a_dim1], lda, &d__[i_], 
+    1037          12 :                 &e[i_], &tauq[i_], &taup[i_], &work[1], &ldwrkx, 
+    1038          12 :                 &work[ldwrkx * nb + 1], &ldwrky);
+    1039             : 
+    1040          12 :         i_3 = *m - i_ - nb + 1;
+    1041          12 :         i_4 = *n - i_ - nb + 1;
+    1042          12 :         PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "T", &i_3, &i_4, &nb, &minusone, 
+    1043          12 :                &a[i_ + nb + i_ * a_dim1], lda, &work[ldwrkx * nb + nb + 1],
+    1044          12 :                &ldwrky, &one, &a[i_ + nb + (i_ + nb) * a_dim1], lda);
+    1045          12 :         i_3 = *m - i_ - nb + 1;
+    1046          12 :         i_4 = *n - i_ - nb + 1;
+    1047          12 :         PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", &i_3, &i_4, &nb, &minusone, &work[nb + 1], &ldwrkx,
+    1048          12 :                &a[i_ + (i_ + nb) * a_dim1], lda, &one, 
+    1049          12 :                &a[i_ + nb + (i_ + nb) * a_dim1], lda);
+    1050             : 
+    1051          12 :         if (*m >= *n) {
+    1052          12 :             i_3 = i_ + nb - 1;
+    1053         396 :             for (j = i_; j <= i_3; ++j) {
+    1054         384 :                 a[j + j * a_dim1] = d__[j];
+    1055         384 :                 a[j + (j + 1) * a_dim1] = e[j];
+    1056             :             }
+    1057             :         } else {
+    1058           0 :             i_3 = i_ + nb - 1;
+    1059           0 :             for (j = i_; j <= i_3; ++j) {
+    1060           0 :                 a[j + j * a_dim1] = d__[j];
+    1061           0 :                 a[j + 1 + j * a_dim1] = e[j];
+    1062             :             }
+    1063             :         }
+    1064             :     }
+    1065             : 
+    1066          96 :     i_2 = *m - i_ + 1;
+    1067          96 :     i_1 = *n - i_ + 1;
+    1068          96 :     PLUMED_BLAS_F77_FUNC(dgebd2,DGEBD2)(&i_2, &i_1, &a[i_ + i_ * a_dim1], lda, &d__[i_], &e[i_], &
+    1069          96 :             tauq[i_], &taup[i_], &work[1], &iinfo);
+    1070          96 :     work[1] = ws;
+    1071          96 :     return;
+    1072             : 
+    1073             : }
+    1074             : }
+    1075             : }
+    1076             : #include "lapack.h"
+    1077             : 
+    1078             : #include "blas/blas.h"
+    1079             : namespace PLMD{
+    1080             : namespace lapack{
+    1081             : using namespace blas;
+    1082             : void 
+    1083           0 : PLUMED_BLAS_F77_FUNC(dgelq2,DGELQ2)(int *m, 
+    1084             :                         int *n, 
+    1085             :                         double *a,
+    1086             :                         int *lda, 
+    1087             :                         double *tau, 
+    1088             :                         double *work, 
+    1089             :                         int *info)
+    1090             : {
+    1091             :     /* System generated locals */
+    1092             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+    1093             : 
+    1094             :     /* Local variables */
+    1095             :     int i__, k;
+    1096             :     double aii;
+    1097             : 
+    1098           0 :     a_dim1 = *lda;
+    1099           0 :     a_offset = 1 + a_dim1;
+    1100           0 :     a -= a_offset;
+    1101           0 :     --tau;
+    1102             :     --work;
+    1103             : 
+    1104           0 :     *info = 0;
+    1105             :     
+    1106           0 :     i__4 = (*m > 1) ? *m : 1;
+    1107             :     
+    1108           0 :     if (*m < 0) {
+    1109           0 :         *info = -1;
+    1110           0 :     } else if (*n < 0) {
+    1111           0 :         *info = -2;
+    1112           0 :     } else if (*lda < i__4) {
+    1113           0 :         *info = -4;
+    1114             :     }
+    1115           0 :     if (*info != 0) {
+    1116             :         return;
+    1117             :     }
+    1118             : 
+    1119             :     
+    1120           0 :     k = (*m < *n ) ? *m : *n;
+    1121             :     i__1 = k;
+    1122           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    1123           0 :         i__2 = *n - i__ + 1;
+    1124           0 :         i__3 = i__ + 1;
+    1125             :     i__4 = (i__3 < *n) ? i__3 : *n;
+    1126           0 :         PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i__2, &a[i__ + i__ * a_dim1], &a[i__ + i__4 * a_dim1],
+    1127           0 :                             lda, &tau[i__]);
+    1128           0 :         if (i__ < *m) {
+    1129           0 :             aii = a[i__ + i__ * a_dim1];
+    1130           0 :             a[i__ + i__ * a_dim1] = 1.f;
+    1131           0 :             i__2 = *m - i__;
+    1132           0 :             i__3 = *n - i__ + 1;
+    1133           0 :             PLUMED_BLAS_F77_FUNC(dlarf,DLARF)("R", &i__2, &i__3, &a[i__ + i__ * a_dim1], lda, 
+    1134           0 :                               &tau[i__], &a[i__ + 1 + i__ * a_dim1], lda, &work[1]);
+    1135           0 :             a[i__ + i__ * a_dim1] = aii;
+    1136             :         }
+    1137             :     }
+    1138             :     return;
+    1139             : }
+    1140             : 
+    1141             : 
+    1142             : }
+    1143             : }
+    1144             : #include <cmath>
+    1145             : #include "lapack.h"
+    1146             : #include "lapack_limits.h"
+    1147             : 
+    1148             : 
+    1149             : 
+    1150             : #include "blas/blas.h"
+    1151             : namespace PLMD{
+    1152             : namespace lapack{
+    1153             : using namespace blas;
+    1154             : void
+    1155           0 : PLUMED_BLAS_F77_FUNC(dgelqf,DGELQF)(int *m,
+    1156             :         int *n, 
+    1157             :         double *a, 
+    1158             :         int *lda, 
+    1159             :         double *tau,
+    1160             :         double *work, 
+    1161             :         int *lwork, 
+    1162             :         int *info)
+    1163             : {
+    1164             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+    1165             : 
+    1166             :     int i__, k, ib, nb, nx, iws, nbmin, iinfo;
+    1167             :     int ldwork, lwkopt;
+    1168             : 
+    1169           0 :     a_dim1 = *lda;
+    1170           0 :     a_offset = 1 + a_dim1;
+    1171           0 :     a -= a_offset;
+    1172           0 :     --tau;
+    1173             :     --work;
+    1174             : 
+    1175           0 :     *info = 0;
+    1176             :     nb = DGELQF_BLOCKSIZE;
+    1177           0 :     lwkopt = *m * nb;
+    1178           0 :     work[1] = (double) lwkopt;
+    1179             : 
+    1180           0 :     if (*lwork==-1) {
+    1181             :         return;
+    1182             :     }
+    1183             : 
+    1184           0 :     k =(*m < *n) ? *m : *n;
+    1185           0 :     if (k == 0) {
+    1186           0 :         work[1] = 1.;
+    1187           0 :         return;
+    1188             :     }
+    1189             : 
+    1190             :     nbmin = 2;
+    1191             :     nx = 0;
+    1192             :     iws = *m;
+    1193           0 :     if (nb > 1 && nb < k) {
+    1194             :         nx = DGELQF_CROSSOVER;
+    1195           0 :         if (nx < k) {
+    1196           0 :             ldwork = *m;
+    1197           0 :             iws = ldwork * nb;
+    1198           0 :             if (*lwork < iws) {
+    1199             : 
+    1200           0 :                 nb = *lwork / ldwork;
+    1201             :                 nbmin = DGELQF_MINBLOCKSIZE;
+    1202             :             }
+    1203             :         }
+    1204             :     }
+    1205             : 
+    1206           0 :     if (nb >= nbmin && nb < k && nx < k) {
+    1207             : 
+    1208           0 :         i__1 = k - nx;
+    1209           0 :         i__2 = nb;
+    1210           0 :         for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+    1211           0 :             i__3 = k - i__ + 1;
+    1212           0 :             ib = (i__3 < nb) ? i__3 : nb;
+    1213             : 
+    1214           0 :             i__3 = *n - i__ + 1;
+    1215           0 :             PLUMED_BLAS_F77_FUNC(dgelq2,DGELQ2)(&ib, &i__3, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[
+    1216             :                     1], &iinfo);
+    1217           0 :             if (i__ + ib <= *m) {
+    1218             : 
+    1219           0 :                 i__3 = *n - i__ + 1;
+    1220           0 :                 PLUMED_BLAS_F77_FUNC(dlarft,DLARFT)("Forward", "Rowwise", &i__3, &ib, &a[i__ + i__ * 
+    1221             :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+    1222             : 
+    1223           0 :                 i__3 = *m - i__ - ib + 1;
+    1224           0 :                 i__4 = *n - i__ + 1;
+    1225           0 :                 PLUMED_BLAS_F77_FUNC(dlarfb,DLARFB)("Right", "No transpose", "Forward", "Rowwise", &i__3, 
+    1226             :                         &i__4, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+    1227           0 :                         ldwork, &a[i__ + ib + i__ * a_dim1], lda, &work[ib + 
+    1228           0 :                         1], &ldwork);
+    1229             :             }
+    1230             :         }
+    1231             :     } else {
+    1232             :         i__ = 1;
+    1233             :     }
+    1234             : 
+    1235           0 :     if (i__ <= k) {
+    1236           0 :         i__2 = *m - i__ + 1;
+    1237           0 :         i__1 = *n - i__ + 1;
+    1238           0 :         PLUMED_BLAS_F77_FUNC(dgelq2,DGELQ2)(&i__2, &i__1, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[1]
+    1239             :                 , &iinfo);
+    1240             :     }
+    1241             : 
+    1242           0 :     work[1] = (double) iws;
+    1243           0 :     return;
+    1244             : 
+    1245             : }
+    1246             : }
+    1247             : }
+    1248             : #include "lapack.h"
+    1249             : 
+    1250             : 
+    1251             : #include "blas/blas.h"
+    1252             : namespace PLMD{
+    1253             : namespace lapack{
+    1254             : using namespace blas;
+    1255             : void
+    1256           1 : PLUMED_BLAS_F77_FUNC(dgeqr2,DGEQR2)(int *m,
+    1257             :         int *n,
+    1258             :         double *a,
+    1259             :         int *lda,
+    1260             :         double *tau,
+    1261             :         double *work,
+    1262             :         int *info)
+    1263             : {
+    1264           1 :   int k = (*m < *n) ? *m : *n;
+    1265             :   int i,i1,i2,i3;
+    1266             :   double aii;
+    1267             : 
+    1268           1 :   *info = 0;
+    1269             :   
+    1270           3 :   for(i=0;i<k;i++) {
+    1271           2 :     i1 = *m - i;
+    1272           2 :     i2 = ( (i+1) < (*m-1) ) ? (i+1) : (*m-1);
+    1273           2 :     i3 = 1;
+    1274           2 :     PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i*(*lda)+i2]),&i3,&(tau[i]));
+    1275           2 :     if(i<(*n-1)) {
+    1276           1 :       aii = a[i*(*lda)+i];
+    1277           1 :       a[i*(*lda)+i] = 1.0;
+    1278           1 :       i2 = *n - i - 1;
+    1279           1 :       PLUMED_BLAS_F77_FUNC(dlarf,DLARF)("L",&i1,&i2,&(a[i*(*lda)+i]),&i3,&(tau[i]),
+    1280           1 :              &(a[(i+1)*(*lda)+i]),lda,work);
+    1281           1 :       a[i*(*lda)+i] = aii;
+    1282             :     }
+    1283             :   }
+    1284           1 :   return;
+    1285             : }
+    1286             : }
+    1287             : }
+    1288             : #include "lapack.h"
+    1289             : #include "lapack_limits.h"
+    1290             : 
+    1291             : #include "blas/blas.h"
+    1292             : namespace PLMD{
+    1293             : namespace lapack{
+    1294             : using namespace blas;
+    1295             : void 
+    1296           1 : PLUMED_BLAS_F77_FUNC(dgeqrf,DGEQRF)(int *m, 
+    1297             :         int *n, 
+    1298             :         double *a, 
+    1299             :         int *lda, 
+    1300             :         double *tau,
+    1301             :         double *work, 
+    1302             :         int *lwork, 
+    1303             :         int *info)
+    1304             : {
+    1305             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+    1306             : 
+    1307             :     int i__, k, ib, nb, nx, iws, nbmin, iinfo;
+    1308             :     int ldwork, lwkopt;
+    1309             : 
+    1310           1 :     a_dim1 = *lda;
+    1311           1 :     a_offset = 1 + a_dim1;
+    1312           1 :     a -= a_offset;
+    1313           1 :     --tau;
+    1314             :     --work;
+    1315             : 
+    1316           1 :     *info = 0;
+    1317             :     nb = DGEQRF_BLOCKSIZE;
+    1318           1 :     lwkopt = *n * nb;
+    1319           1 :     work[1] = (double) lwkopt;
+    1320           1 :         if (*lwork==-1)
+    1321             :         return;
+    1322             :     
+    1323             : 
+    1324           1 :     k = (*m < *n) ? *m : *n;
+    1325           1 :     if (k == 0) {
+    1326           0 :         work[1] = 1.;
+    1327           0 :         return;
+    1328             :     }
+    1329             : 
+    1330             :     nbmin = 2;
+    1331             :     nx = 0;
+    1332             :     iws = *n;
+    1333           1 :     if (nb > 1 && nb < k) {
+    1334             :         
+    1335             :       nx = DGEQRF_CROSSOVER;
+    1336           0 :         if (nx < k) {
+    1337             : 
+    1338           0 :             ldwork = *n;
+    1339           0 :             iws = ldwork * nb;
+    1340           0 :             if (*lwork < iws) {
+    1341             : 
+    1342           0 :                 nb = *lwork / ldwork;
+    1343             :                 nbmin = DGEQRF_MINBLOCKSIZE;
+    1344             :             }
+    1345             :         }
+    1346             :     }
+    1347             : 
+    1348           1 :     if (nb >= nbmin && nb < k && nx < k) {
+    1349           0 :         i__1 = k - nx;
+    1350           0 :         i__2 = nb;
+    1351           0 :         for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+    1352             : 
+    1353           0 :             i__3 = k - i__ + 1;
+    1354           0 :             ib = (i__3 < nb) ? i__3 : nb;
+    1355             : 
+    1356           0 :             i__3 = *m - i__ + 1;
+    1357           0 :             PLUMED_BLAS_F77_FUNC(dgeqr2,DGEQR2)(&i__3, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[
+    1358             :                     1], &iinfo);
+    1359           0 :             if (i__ + ib <= *n) {
+    1360             : 
+    1361           0 :                 i__3 = *m - i__ + 1;
+    1362           0 :                 PLUMED_BLAS_F77_FUNC(dlarft,DLARFT)("Forward", "Columnwise", &i__3, &ib, &a[i__ + i__ * 
+    1363             :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+    1364             : 
+    1365           0 :                 i__3 = *m - i__ + 1;
+    1366           0 :                 i__4 = *n - i__ - ib + 1;
+    1367           0 :                 PLUMED_BLAS_F77_FUNC(dlarfb,DLARFB)("Left", "Transpose", "Forward", "Columnwise", &i__3, &
+    1368             :                         i__4, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+    1369           0 :                         ldwork, &a[i__ + (i__ + ib) * a_dim1], lda, &work[ib 
+    1370           0 :                         + 1], &ldwork);
+    1371             :             }
+    1372             :         }
+    1373             :     } else {
+    1374             :         i__ = 1;
+    1375             :     }
+    1376             : 
+    1377           1 :     if (i__ <= k) {
+    1378           1 :         i__2 = *m - i__ + 1;
+    1379           1 :         i__1 = *n - i__ + 1;
+    1380           1 :         PLUMED_BLAS_F77_FUNC(dgeqr2,DGEQR2)(&i__2, &i__1, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[1]
+    1381             :                 , &iinfo);
+    1382             :     }
+    1383             : 
+    1384           1 :     work[1] = (double) iws;
+    1385           1 :     return;
+    1386             : 
+    1387             : } 
+    1388             : 
+    1389             : }
+    1390             : }
+    1391             : #include <cmath>
+    1392             : #include "real.h"
+    1393             : 
+    1394             : #include "blas/blas.h"
+    1395             : #include "lapack.h"
+    1396             : #include "lapack_limits.h"
+    1397             : 
+    1398             : 
+    1399             : #include "blas/blas.h"
+    1400             : namespace PLMD{
+    1401             : namespace lapack{
+    1402             : using namespace blas;
+    1403             : void 
+    1404         192 : PLUMED_BLAS_F77_FUNC(dgesdd,DGESDD)(const char *jobz, 
+    1405             :         int *m, 
+    1406             :         int *n, 
+    1407             :         double *a, 
+    1408             :         int *lda, 
+    1409             :         double *s,
+    1410             :         double *u, 
+    1411             :         int *ldu, 
+    1412             :         double *vt, 
+    1413             :         int *ldvt, 
+    1414             :         double *work,
+    1415             :         int *lwork, 
+    1416             :         int *iwork, 
+    1417             :         int *info)
+    1418             : {
+    1419             :     int a_dim1, a_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+    1420             : 
+    1421             :     int ie, iu;
+    1422             :     double dum[1], eps;
+    1423             :     int ivt, iscl;
+    1424             :     double anrm;
+    1425             :     int idum[1], ierr, itau;
+    1426             :     int minmn, wrkbl, itaup, itauq, mnthr;
+    1427             :     int nwork;
+    1428             :     int wntqn;
+    1429             :     int bdspac;
+    1430             :     double bignum;
+    1431             :     int ldwrku, maxwrk, ldwkvt;
+    1432             :     double smlnum,minval, safemin;
+    1433             :     int lquery;
+    1434         192 :     int c__0 = 0;
+    1435         192 :     int c__1 = 1;
+    1436         192 :     double zero = 0.0;
+    1437         192 :     double one = 1.0;
+    1438             : 
+    1439             : 
+    1440         192 :     a_dim1 = *lda;
+    1441         192 :     a_offset = 1 + a_dim1;
+    1442         192 :     a -= a_offset;
+    1443             :     --s;
+    1444         192 :     u_dim1 = *ldu;
+    1445         192 :     u_offset = 1 + u_dim1;
+    1446         192 :     u -= u_offset;
+    1447         192 :     vt_dim1 = *ldvt;
+    1448         192 :     vt_offset = 1 + vt_dim1;
+    1449         192 :     vt -= vt_offset;
+    1450         192 :     --work;
+    1451             :     --iwork;
+    1452             : 
+    1453         192 :     *info = 0;
+    1454         192 :     minmn = (*m < *n) ? *m : *n;
+    1455         192 :     mnthr = (int) (minmn * 11. / 6.);
+    1456         192 :     wntqn = (*jobz=='o' || *jobz=='O');
+    1457             : 
+    1458             :     maxwrk = 1;
+    1459         192 :     lquery = *lwork == -1;
+    1460             : 
+    1461         192 :     if (*info == 0 && *m > 0 && *n > 0) {
+    1462         192 :         if (*m >= *n) {
+    1463             : 
+    1464         192 :             if (wntqn) {
+    1465           0 :                 bdspac = *n * 7;
+    1466             :             } else {
+    1467         192 :                 bdspac = *n * 3 * *n + (*n << 2);
+    1468             :             }
+    1469         192 :             if (*m >= mnthr) {
+    1470           2 :                 if (wntqn) {
+    1471             : 
+    1472           0 :                     wrkbl = *n * 67;
+    1473           0 :                     i__1 = wrkbl, i__2 = bdspac + *n;
+    1474             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+    1475             :                 } else {
+    1476             : 
+    1477           2 :                     wrkbl = *n * 67;
+    1478           2 :                     i__1 = wrkbl, i__2 = *n + (*m << 5);
+    1479             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+    1480           2 :                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
+    1481             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+    1482           2 :                     maxwrk = wrkbl + *n * *n;
+    1483             :                 }
+    1484             :             } else {
+    1485             : 
+    1486         190 :                 wrkbl = *n * 3 + (*m + *n*32);
+    1487         190 :                 if (wntqn) {
+    1488           0 :                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
+    1489             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+    1490             :                 } else {
+    1491         190 :                     i__1 = maxwrk, i__2 = bdspac + *n * 3;
+    1492             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+    1493             :                 }
+    1494             :             }
+    1495             :         } else {
+    1496             : 
+    1497           0 :             if (wntqn) {
+    1498           0 :                 bdspac = *m * 7;
+    1499             :             } else {
+    1500           0 :                 bdspac = *m * 3 * *m + (*m*4);
+    1501             :             }
+    1502           0 :             if (*n >= mnthr) {
+    1503           0 :                 if (wntqn) {
+    1504             : 
+    1505           0 :                     wrkbl = *m * 67;
+    1506           0 :                     i__1 = wrkbl, i__2 = bdspac + *m;
+    1507             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+    1508             :                 } else {
+    1509             : 
+    1510           0 :                     wrkbl = *m * 67;
+    1511           0 :                     i__1 = wrkbl, i__2 = *m + (*n*32);
+    1512             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+    1513             : 
+    1514           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+    1515             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+    1516           0 :                     maxwrk = wrkbl + *m * *m;
+    1517             :                 }
+    1518             :             } else {
+    1519           0 :                 wrkbl = *m * 3 + (*m + *n*32);
+    1520           0 :                 if (wntqn) {
+    1521           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+    1522             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+    1523             :                 } else {
+    1524           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+    1525             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+    1526             :                 }
+    1527             :             }
+    1528             :         }
+    1529         192 :         work[1] = (double) maxwrk;
+    1530             :     }
+    1531             : 
+    1532             :     
+    1533         192 :     if( lquery != 0)
+    1534             :     {
+    1535             :         return;
+    1536             :     }
+    1537             :     
+    1538             : 
+    1539          96 :     if (*m == 0 || *n == 0) {
+    1540           0 :         if (*lwork >= 1) {
+    1541           0 :             work[1] = 1.;
+    1542             :         }
+    1543           0 :         return;
+    1544             :     }
+    1545             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    1546             :     minval = PLUMED_GMX_DOUBLE_MIN;
+    1547             :     safemin = minval / eps;
+    1548          96 :     smlnum =  std::sqrt(safemin) / eps;
+    1549             : 
+    1550             : 
+    1551          96 :     bignum = 1. / smlnum;
+    1552             : 
+    1553             : 
+    1554          96 :     anrm = PLUMED_BLAS_F77_FUNC(dlange,DLANGE)("M", m, n, &a[a_offset], lda, dum);
+    1555             :     iscl = 0;
+    1556          96 :     if (anrm > 0. && anrm < smlnum) {
+    1557             :         iscl = 1;
+    1558           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G",&c__0,&c__0,&anrm,&smlnum,m,n,&a[a_offset],lda,&ierr);
+    1559          96 :     } else if (anrm > bignum) {
+    1560             :         iscl = 1;
+    1561           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G",&c__0,&c__0,&anrm,&bignum,m,n,&a[a_offset],lda,&ierr);
+    1562             :     }
+    1563             : 
+    1564          96 :     if (*m >= *n) {
+    1565          96 :         if (*m >= mnthr) {
+    1566             : 
+    1567           1 :             if (wntqn) {
+    1568             : 
+    1569             :                 itau = 1;
+    1570           0 :                 nwork = itau + *n;
+    1571             : 
+    1572           0 :                 i__1 = *lwork - nwork + 1;
+    1573           0 :                 PLUMED_BLAS_F77_FUNC(dgeqrf,DGEQRF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+    1574             :                         i__1, &ierr);
+    1575             : 
+    1576           0 :                 i__1 = *n - 1;
+    1577           0 :                 i__2 = *n - 1;
+    1578           0 :                 PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("L", &i__1, &i__2, &zero, &zero, &a[a_dim1 + 2], 
+    1579             :                         lda);
+    1580             :                 ie = 1;
+    1581           0 :                 itauq = ie + *n;
+    1582           0 :                 itaup = itauq + *n;
+    1583           0 :                 nwork = itaup + *n;
+    1584             : 
+    1585           0 :                 i__1 = *lwork - nwork + 1;
+    1586           0 :                 PLUMED_BLAS_F77_FUNC(dgebrd,DGEBRD)(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
+    1587           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+    1588           0 :                 nwork = ie + *n;
+    1589             : 
+    1590           0 :                 PLUMED_BLAS_F77_FUNC(dbdsdc,DBDSDC)("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+    1591           0 :                          dum, idum, &work[nwork], &iwork[1], info);
+    1592             : 
+    1593             :             } else {
+    1594             :                 iu = 1;
+    1595             : 
+    1596           1 :                 ldwrku = *n;
+    1597           1 :                 itau = iu + ldwrku * *n;
+    1598           1 :                 nwork = itau + *n;
+    1599             : 
+    1600           1 :                 i__1 = *lwork - nwork + 1;
+    1601           1 :                 PLUMED_BLAS_F77_FUNC(dgeqrf,DGEQRF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+    1602             :                         i__1, &ierr);
+    1603           1 :                 PLUMED_BLAS_F77_FUNC(dlacpy,DLACPY)("L", m, n, &a[a_offset], lda, &u[u_offset], ldu);
+    1604             : 
+    1605           1 :                 i__1 = *lwork - nwork + 1;
+    1606           1 :                 PLUMED_BLAS_F77_FUNC(dorgqr,DORGQR)(m, m, n, &u[u_offset], ldu, &work[itau], &work[nwork],
+    1607             :                          &i__1, &ierr);
+    1608             : 
+    1609           1 :                 i__1 = *n - 1;
+    1610           1 :                 i__2 = *n - 1;
+    1611           1 :                 PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("L", &i__1, &i__2, &zero, &zero, &a[a_dim1 + 2], 
+    1612             :                         lda);
+    1613             :                 ie = itau;
+    1614           1 :                 itauq = ie + *n;
+    1615           1 :                 itaup = itauq + *n;
+    1616           1 :                 nwork = itaup + *n;
+    1617             : 
+    1618           1 :                 i__1 = *lwork - nwork + 1;
+    1619           1 :                 PLUMED_BLAS_F77_FUNC(dgebrd,DGEBRD)(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
+    1620           1 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+    1621             : 
+    1622           1 :                 PLUMED_BLAS_F77_FUNC(dbdsdc,DBDSDC)("U", "I", n, &s[1], &work[ie], &work[iu], n, &vt[
+    1623             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+    1624             :                         info);
+    1625             : 
+    1626           1 :                 i__1 = *lwork - nwork + 1;
+    1627           1 :                 PLUMED_BLAS_F77_FUNC(dormbr,DORMBR)("Q", "L", "N", n, n, n, &a[a_offset], lda, &work[
+    1628             :                         itauq], &work[iu], &ldwrku, &work[nwork], &i__1, &
+    1629             :                         ierr);
+    1630           1 :                 i__1 = *lwork - nwork + 1;
+    1631           1 :                 PLUMED_BLAS_F77_FUNC(dormbr,DORMBR)("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
+    1632             :                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
+    1633             :                         ierr);
+    1634             : 
+    1635           1 :                 PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", m, n, n, &one, &u[u_offset], ldu, &work[iu]
+    1636             :                         , &ldwrku, &zero, &a[a_offset], lda);
+    1637             : 
+    1638           1 :                 PLUMED_BLAS_F77_FUNC(dlacpy,DLACPY)("F", m, n, &a[a_offset], lda, &u[u_offset], ldu);
+    1639             : 
+    1640             :             }
+    1641             : 
+    1642             :         } else {
+    1643             :             ie = 1;
+    1644          95 :             itauq = ie + *n;
+    1645          95 :             itaup = itauq + *n;
+    1646          95 :             nwork = itaup + *n;
+    1647             : 
+    1648          95 :             i__1 = *lwork - nwork + 1;
+    1649          95 :             PLUMED_BLAS_F77_FUNC(dgebrd,DGEBRD)(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
+    1650          95 :                     work[itaup], &work[nwork], &i__1, &ierr);
+    1651          95 :             if (wntqn) {
+    1652             : 
+    1653           0 :                 PLUMED_BLAS_F77_FUNC(dbdsdc,DBDSDC)("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+    1654             :                          dum, idum, &work[nwork], &iwork[1], info);
+    1655             :             } else {
+    1656             : 
+    1657          95 :                 PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("F", m, m, &zero, &zero, &u[u_offset], ldu);
+    1658          95 :                 PLUMED_BLAS_F77_FUNC(dbdsdc,DBDSDC)("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
+    1659             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+    1660             :                         info);
+    1661             : 
+    1662          95 :                 i__1 = *m - *n;
+    1663          95 :                 i__2 = *m - *n;
+    1664          95 :                 PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("F", &i__1, &i__2, &zero, &one, &u[*n + 1 + (*n + 
+    1665          95 :                         1) * u_dim1], ldu);
+    1666             : 
+    1667          95 :                 i__1 = *lwork - nwork + 1;
+    1668          95 :                 PLUMED_BLAS_F77_FUNC(dormbr,DORMBR)("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
+    1669             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+    1670          95 :                 i__1 = *lwork - nwork + 1;
+    1671          95 :                 PLUMED_BLAS_F77_FUNC(dormbr,DORMBR)("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
+    1672             :                         itaup], &vt[vt_offset],ldvt,&work[nwork],&i__1,&ierr);
+    1673             :             }
+    1674             : 
+    1675             :         }
+    1676             : 
+    1677             :     } else {
+    1678             : 
+    1679           0 :         if (*n >= mnthr) {
+    1680             : 
+    1681           0 :             if (wntqn) {
+    1682             : 
+    1683             :                 itau = 1;
+    1684           0 :                 nwork = itau + *m;
+    1685             : 
+    1686           0 :                 i__1 = *lwork - nwork + 1;
+    1687           0 :                 PLUMED_BLAS_F77_FUNC(dgelqf,DGELQF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+    1688             :                         i__1, &ierr);
+    1689             : 
+    1690           0 :                 i__1 = *m - 1;
+    1691           0 :                 i__2 = *m - 1;
+    1692           0 :                 PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("U", &i__1, &i__2, &zero, &zero, &a[(a_dim1*2) + 
+    1693           0 :                         1], lda);
+    1694             :                 ie = 1;
+    1695           0 :                 itauq = ie + *m;
+    1696           0 :                 itaup = itauq + *m;
+    1697           0 :                 nwork = itaup + *m;
+    1698             : 
+    1699           0 :                 i__1 = *lwork - nwork + 1;
+    1700           0 :                 PLUMED_BLAS_F77_FUNC(dgebrd,DGEBRD)(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
+    1701           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+    1702           0 :                 nwork = ie + *m;
+    1703             : 
+    1704           0 :                 PLUMED_BLAS_F77_FUNC(dbdsdc,DBDSDC)("U", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+    1705           0 :                          dum, idum, &work[nwork], &iwork[1], info);
+    1706             : 
+    1707             :             } else {
+    1708             : 
+    1709             :                 ivt = 1;
+    1710             : 
+    1711           0 :                 ldwkvt = *m;
+    1712           0 :                 itau = ivt + ldwkvt * *m;
+    1713           0 :                 nwork = itau + *m;
+    1714             : 
+    1715           0 :                 i__1 = *lwork - nwork + 1;
+    1716           0 :                 PLUMED_BLAS_F77_FUNC(dgelqf,DGELQF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+    1717             :                         i__1, &ierr);
+    1718           0 :                 PLUMED_BLAS_F77_FUNC(dlacpy,DLACPY)("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
+    1719             : 
+    1720           0 :                 i__1 = *lwork - nwork + 1;
+    1721           0 :                 PLUMED_BLAS_F77_FUNC(dorglq,DORGLQ)(n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[
+    1722             :                         nwork], &i__1, &ierr);
+    1723             : 
+    1724           0 :                 i__1 = *m - 1;
+    1725           0 :                 i__2 = *m - 1;
+    1726           0 :                 PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("U", &i__1, &i__2, &zero, &zero, &a[(a_dim1*2) + 
+    1727           0 :                         1], lda);
+    1728             :                 ie = itau;
+    1729           0 :                 itauq = ie + *m;
+    1730           0 :                 itaup = itauq + *m;
+    1731           0 :                 nwork = itaup + *m;
+    1732             : 
+    1733           0 :                 i__1 = *lwork - nwork + 1;
+    1734           0 :                 PLUMED_BLAS_F77_FUNC(dgebrd,DGEBRD)(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
+    1735           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+    1736             : 
+    1737           0 :                 PLUMED_BLAS_F77_FUNC(dbdsdc,DBDSDC)("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
+    1738             :                         work[ivt], &ldwkvt, dum, idum, &work[nwork], &iwork[1]
+    1739             :                         , info);
+    1740             : 
+    1741           0 :                 i__1 = *lwork - nwork + 1;
+    1742           0 :                 PLUMED_BLAS_F77_FUNC(dormbr,DORMBR)("Q", "L", "N", m, m, m, &a[a_offset], lda, &work[
+    1743             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+    1744           0 :                 i__1 = *lwork - nwork + 1;
+    1745           0 :                 PLUMED_BLAS_F77_FUNC(dormbr,DORMBR)("P", "R", "T", m, m, m, &a[a_offset], lda, &work[
+    1746             :                         itaup], &work[ivt], &ldwkvt, &work[nwork], &i__1, &
+    1747             :                         ierr);
+    1748             : 
+    1749           0 :                 PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", m, n, m, &one, &work[ivt], &ldwkvt, &vt[
+    1750             :                         vt_offset], ldvt, &zero, &a[a_offset], lda);
+    1751             : 
+    1752           0 :                 PLUMED_BLAS_F77_FUNC(dlacpy,DLACPY)("F", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
+    1753             : 
+    1754             :             }
+    1755             : 
+    1756             :         } else {
+    1757             : 
+    1758             :             ie = 1;
+    1759           0 :             itauq = ie + *m;
+    1760           0 :             itaup = itauq + *m;
+    1761           0 :             nwork = itaup + *m;
+    1762             : 
+    1763           0 :             i__1 = *lwork - nwork + 1;
+    1764           0 :             PLUMED_BLAS_F77_FUNC(dgebrd,DGEBRD)(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
+    1765           0 :                     work[itaup], &work[nwork], &i__1, &ierr);
+    1766           0 :             if (wntqn) {
+    1767             : 
+    1768           0 :                 PLUMED_BLAS_F77_FUNC(dbdsdc,DBDSDC)("L", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+    1769             :                          dum, idum, &work[nwork], &iwork[1], info);
+    1770             :             } else {
+    1771           0 :                 PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("F", n, n, &zero, &zero, &vt[vt_offset], ldvt);
+    1772           0 :                 PLUMED_BLAS_F77_FUNC(dbdsdc,DBDSDC)("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
+    1773             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+    1774             :                         info);
+    1775             : 
+    1776           0 :                 i__1 = *n - *m;
+    1777           0 :                 i__2 = *n - *m;
+    1778           0 :                 PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("F", &i__1, &i__2, &zero, &one, &vt[*m + 1 + (*m + 
+    1779           0 :                         1) * vt_dim1], ldvt);
+    1780             : 
+    1781           0 :                 i__1 = *lwork - nwork + 1;
+    1782           0 :                 PLUMED_BLAS_F77_FUNC(dormbr,DORMBR)("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
+    1783             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+    1784           0 :                 i__1 = *lwork - nwork + 1;
+    1785           0 :                 PLUMED_BLAS_F77_FUNC(dormbr,DORMBR)("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
+    1786             :                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
+    1787             :                         ierr);
+    1788             :             }
+    1789             : 
+    1790             :         }
+    1791             : 
+    1792             :     }
+    1793             : 
+    1794          96 :     if (iscl == 1) {
+    1795           0 :         if (anrm > bignum) {
+    1796           0 :             PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &bignum, &anrm, &minmn, &c__1, &s[1], &
+    1797             :                     minmn, &ierr);
+    1798             :         }
+    1799           0 :         if (anrm < smlnum) {
+    1800           0 :             PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &smlnum, &anrm, &minmn, &c__1, &s[1], &
+    1801             :                     minmn, &ierr);
+    1802             :         }
+    1803             :     }
+    1804             : 
+    1805          96 :     work[1] = (double) maxwrk;
+    1806             : 
+    1807          96 :     return;
+    1808             : 
+    1809             : }
+    1810             : 
+    1811             : 
+    1812             : }
+    1813             : }
+    1814             : #include <cmath>
+    1815             : #include "real.h"
+    1816             : 
+    1817             : #include "blas/blas.h"
+    1818             : #include "lapack.h"
+    1819             : 
+    1820             : 
+    1821             : #include "blas/blas.h"
+    1822             : namespace PLMD{
+    1823             : namespace lapack{
+    1824             : using namespace blas;
+    1825             : void
+    1826          57 : PLUMED_BLAS_F77_FUNC(dgetf2,DGETF2)(int *m,
+    1827             :         int *n,
+    1828             :         double *a,
+    1829             :         int *lda,
+    1830             :         int *ipiv,
+    1831             :         int *info)
+    1832             : {
+    1833             :   int j,jp,k,t1,t2,t3;
+    1834             :   double minusone;
+    1835             :   double tmp;
+    1836             : 
+    1837          57 :   minusone = -1.0;
+    1838             : 
+    1839          57 :   if(*m<=0 || *n<=0)
+    1840             :     return;
+    1841             : 
+    1842             :   k = (*m < *n) ? *m : *n;
+    1843         171 :   for(j=1;j<=k;j++) {
+    1844         114 :     t1 = *m-j+1;
+    1845         114 :     t2 = 1;
+    1846         114 :     jp = j - 1 + PLUMED_BLAS_F77_FUNC(idamax,IDAMAX)(&t1,&(a[(j-1)*(*lda)+(j-1)]),&t2);
+    1847         114 :     ipiv[j-1] = jp;
+    1848         114 :     if( std::abs(a[(j-1)*(*lda)+(jp-1)])>PLUMED_GMX_DOUBLE_MIN ) {
+    1849         114 :       if(jp != j)
+    1850           0 :         PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(n,&(a[ j-1 ]),lda,&(a[ jp-1 ]),lda);
+    1851             :       
+    1852         114 :       if(j<*m) {
+    1853          57 :         t1 = *m-j;
+    1854          57 :         t2 = 1;
+    1855          57 :         tmp = 1.0/a[(j-1)*(*lda)+(j-1)];
+    1856          57 :         PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&t1,&tmp,&(a[(j-1)*(*lda)+(j)]),&t2);
+    1857             :       }
+    1858             :     } else {
+    1859           0 :       *info = j;
+    1860             :     }
+    1861             : 
+    1862         114 :     if(j<k) {
+    1863          57 :       t1 = *m-j;
+    1864          57 :       t2 = *n-j;
+    1865          57 :       t3 = 1;
+    1866          57 :       PLUMED_BLAS_F77_FUNC(dger,DGER)(&t1,&t2,&minusone,&(a[(j-1)*(*lda)+(j)]),&t3,
+    1867          57 :             &(a[(j)*(*lda)+(j-1)]),lda, &(a[(j)*(*lda)+(j)]),lda);
+    1868             :     }
+    1869             :   }
+    1870             :   return;
+    1871             : }
+    1872             : }
+    1873             : }
+    1874             : #include "blas/blas.h"
+    1875             : #include "lapack.h"
+    1876             : #include "lapack_limits.h"
+    1877             : 
+    1878             : #include "blas/blas.h"
+    1879             : namespace PLMD{
+    1880             : namespace lapack{
+    1881             : using namespace blas;
+    1882             : void
+    1883          57 : PLUMED_BLAS_F77_FUNC(dgetrf,DGETRF)(int *m,
+    1884             :         int *n,
+    1885             :         double *a,
+    1886             :         int *lda,
+    1887             :         int *ipiv,
+    1888             :         int *info)
+    1889             : {
+    1890             :   int mindim,jb;
+    1891             :   int i,j,k,l;
+    1892             :   int iinfo;
+    1893          57 :   double minusone = -1.0;
+    1894          57 :   double one = 1.0;
+    1895             : 
+    1896          57 :   if(*m<=0 || *n<=0)
+    1897           0 :     return;
+    1898             : 
+    1899          57 :   *info = 0;
+    1900             : 
+    1901          57 :   mindim = (*m < *n) ? *m : *n;
+    1902             : 
+    1903          57 :   if(DGETRF_BLOCKSIZE>=mindim) {
+    1904             : 
+    1905             :     /* unblocked code */
+    1906          57 :     PLUMED_BLAS_F77_FUNC(dgetf2,DGETF2)(m,n,a,lda,ipiv,info);
+    1907             : 
+    1908             :   } else {
+    1909             : 
+    1910             :     /* blocked case */
+    1911             : 
+    1912           0 :     for(j=1;j<=mindim;j+=DGETRF_BLOCKSIZE) {
+    1913           0 :       jb = ( DGETRF_BLOCKSIZE < (mindim-j+1)) ? DGETRF_BLOCKSIZE : (mindim-j+1);
+    1914             :       /* factor diag. and subdiag blocks and test for singularity */
+    1915           0 :       k = *m-j+1;
+    1916           0 :       PLUMED_BLAS_F77_FUNC(dgetf2,DGETF2)(&k,&jb,&(a[(j-1)*(*lda)+(j-1)]),lda,&(ipiv[j-1]),&iinfo);
+    1917             :       
+    1918           0 :       if(*info==0 && iinfo>0)
+    1919           0 :         *info = iinfo + j - 1;
+    1920             : 
+    1921             :       /* adjust pivot indices */
+    1922           0 :       k = (*m < (j+jb-1)) ? *m : (j+jb-1);
+    1923           0 :       for(i=j;i<=k;i++)
+    1924           0 :         ipiv[i-1] += j - 1;
+    1925             : 
+    1926             :       /* Apply to columns 1 throughj j-1 */
+    1927           0 :       k = j - 1;
+    1928           0 :       i = j + jb - 1;
+    1929           0 :       l = 1;
+    1930           0 :       PLUMED_BLAS_F77_FUNC(dlaswp,DLASWP)(&k,a,lda,&j,&i,ipiv,&l);
+    1931           0 :       if((j+jb)<=*n) {
+    1932             :         /* Apply to cols. j+jb through n */
+    1933           0 :         k = *n-j-jb+1;
+    1934           0 :         i = j+jb-1;
+    1935           0 :         l = 1;
+    1936           0 :         PLUMED_BLAS_F77_FUNC(dlaswp,DLASWP)(&k,&(a[(j+jb-1)*(*lda)+0]),lda,&j,&i,ipiv,&l);
+    1937             :         /* Compute block row of U */
+    1938           0 :         k = *n-j-jb+1;
+    1939           0 :         PLUMED_BLAS_F77_FUNC(dtrsm,DTRSM)("Left","Lower","No transpose","Unit",&jb,&k,&one,
+    1940           0 :                &(a[(j-1)*(*lda)+(j-1)]),lda,&(a[(j+jb-1)*(*lda)+(j-1)]),lda);
+    1941             : 
+    1942           0 :         if((j+jb)<=*m) {
+    1943             :           /* Update trailing submatrix */
+    1944           0 :           k = *m-j-jb+1;
+    1945           0 :           i = *n-j-jb+1;
+    1946           0 :           PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose","No transpose",&k,&i,&jb,&minusone,
+    1947           0 :                  &(a[(j-1)*(*lda)+(j+jb-1)]),lda,
+    1948           0 :                  &(a[(j+jb-1)*(*lda)+(j-1)]),lda,&one,
+    1949           0 :                  &(a[(j+jb-1)*(*lda)+(j+jb-1)]),lda);
+    1950             :         }
+    1951             : 
+    1952             :       }
+    1953             :     }
+    1954             :   }
+    1955             : }
+    1956             : }
+    1957             : }
+    1958             : #include "blas/blas.h"
+    1959             : #include "lapack.h"
+    1960             : #include "lapack_limits.h"
+    1961             : 
+    1962             : #include "blas/blas.h"
+    1963             : namespace PLMD{
+    1964             : namespace lapack{
+    1965             : using namespace blas;
+    1966             : void
+    1967         114 : PLUMED_BLAS_F77_FUNC(dgetri,DGETRI)(int *n, 
+    1968             :         double *a, 
+    1969             :         int *lda, 
+    1970             :         int *ipiv, 
+    1971             :         double *work, 
+    1972             :         int *lwork, 
+    1973             :         int *info)
+    1974             : {
+    1975             :     int a_dim1, a_offset, i__1, i__2, i__3;
+    1976             : 
+    1977             :     int i__, j, jb, nb, jj, jp, nn, iws;
+    1978             :     int nbmin;
+    1979             :     int ldwork;
+    1980             :     int lwkopt;
+    1981         114 :     int c__1 = 1;
+    1982         114 :     double c_b20 = -1.;
+    1983         114 :     double c_b22 = 1.;
+    1984             : 
+    1985         114 :     a_dim1 = *lda;
+    1986         114 :     a_offset = 1 + a_dim1;
+    1987         114 :     a -= a_offset;
+    1988             :     --ipiv;
+    1989         114 :     --work;
+    1990             : 
+    1991         114 :     *info = 0;
+    1992             :     nb = DGETRI_BLOCKSIZE;
+    1993         114 :     lwkopt = *n * nb;
+    1994         114 :     work[1] = (double) lwkopt;
+    1995             : 
+    1996         114 :     if (*n < 0) {
+    1997           0 :         *info = -1;
+    1998         114 :     } else if (*lda < (*n)) {
+    1999           0 :         *info = -3;
+    2000         114 :     } else if (*lwork < (*n) && *lwork!=-1) {
+    2001           0 :         *info = -6;
+    2002             :     }
+    2003         114 :     if (*info != 0) {
+    2004             :         i__1 = -(*info);
+    2005             :         return;
+    2006         114 :     } else if (*lwork == -1) {
+    2007             :         return;
+    2008             :     }
+    2009             : 
+    2010          57 :     if (*n == 0) {
+    2011             :         return;
+    2012             :     }
+    2013             : 
+    2014          57 :     PLUMED_BLAS_F77_FUNC(dtrtri,DTRTRI)("Upper", "Non-unit", n, &a[a_offset], lda, info);
+    2015          57 :     if (*info > 0) {
+    2016             :         return;
+    2017             :     }
+    2018             : 
+    2019             :     nbmin = 2;
+    2020          57 :     ldwork = *n;
+    2021          57 :     if (nb > 1 && nb < *n) {
+    2022           0 :         i__1 = ldwork * nb;
+    2023           0 :         iws = (i__1>1) ? i__1 : 1;
+    2024           0 :         if (*lwork < iws) {
+    2025           0 :             nb = *lwork / ldwork;
+    2026             :             nbmin = DGETRI_MINBLOCKSIZE;
+    2027             :         }
+    2028             :     } else {
+    2029             :         iws = *n;
+    2030             :     }
+    2031             : 
+    2032          57 :     if (nb < nbmin || nb >= *n) {
+    2033             : 
+    2034         171 :         for (j = *n; j >= 1; --j) {
+    2035             : 
+    2036         114 :             i__1 = *n;
+    2037         171 :             for (i__ = j + 1; i__ <= i__1; ++i__) {
+    2038          57 :                 work[i__] = a[i__ + j * a_dim1];
+    2039          57 :                 a[i__ + j * a_dim1] = 0.;
+    2040             :             }
+    2041             : 
+    2042         114 :             if (j < *n) {
+    2043          57 :                 i__1 = *n - j;
+    2044          57 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", n, &i__1, &c_b20, &a[(j + 1) * a_dim1 
+    2045          57 :                         + 1], lda, &work[j + 1], &c__1, &c_b22, &a[j * a_dim1 
+    2046          57 :                         + 1], &c__1);
+    2047             :             }
+    2048             :         }
+    2049             :     } else {
+    2050             : 
+    2051           0 :         nn = (*n - 1) / nb * nb + 1;
+    2052           0 :         i__1 = -nb;
+    2053           0 :         for (j = nn; i__1 < 0 ? j >= 1 : j <= 1; j += i__1) {
+    2054           0 :             i__2 = nb, i__3 = *n - j + 1;
+    2055           0 :             jb = (i__2<i__3) ? i__2 : i__3;
+    2056             : 
+    2057           0 :             i__2 = j + jb - 1;
+    2058           0 :             for (jj = j; jj <= i__2; ++jj) {
+    2059           0 :                 i__3 = *n;
+    2060           0 :                 for (i__ = jj + 1; i__ <= i__3; ++i__) {
+    2061           0 :                     work[i__ + (jj - j) * ldwork] = a[i__ + jj * a_dim1];
+    2062           0 :                     a[i__ + jj * a_dim1] = 0.;
+    2063             :                 }
+    2064             :             }
+    2065             : 
+    2066           0 :             if (j + jb <= *n) {
+    2067           0 :                 i__2 = *n - j - jb + 1;
+    2068           0 :                 PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose", "No transpose", n, &jb, &i__2, &c_b20, 
+    2069           0 :                         &a[(j + jb) * a_dim1 + 1], lda, &work[j + jb], &
+    2070           0 :                         ldwork, &c_b22, &a[j * a_dim1 + 1], lda);
+    2071             :             }
+    2072           0 :             PLUMED_BLAS_F77_FUNC(dtrsm,DTRSM)("Right", "Lower", "No transpose", "Unit", n, &jb, &c_b22, &
+    2073           0 :                     work[j], &ldwork, &a[j * a_dim1 + 1], lda);
+    2074             :         }
+    2075             :     }
+    2076             : 
+    2077         114 :     for (j = *n - 1; j >= 1; --j) {
+    2078          57 :         jp = ipiv[j];
+    2079          57 :         if (jp != j) {
+    2080           0 :             PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(n, &a[j * a_dim1 + 1], &c__1, &a[jp * a_dim1 + 1], &c__1);
+    2081             :         }
+    2082             :     }
+    2083             : 
+    2084          57 :     work[1] = (double) iws;
+    2085          57 :     return;
+    2086             : 
+    2087             : }
+    2088             : 
+    2089             : 
+    2090             : }
+    2091             : }
+    2092             : #include "blas/blas.h"
+    2093             : #include "lapack.h"
+    2094             : 
+    2095             : #include "blas/blas.h"
+    2096             : namespace PLMD{
+    2097             : namespace lapack{
+    2098             : using namespace blas;
+    2099             : void
+    2100           0 : PLUMED_BLAS_F77_FUNC(dgetrs,DGETRS)(const char *trans, 
+    2101             :         int *n, 
+    2102             :         int *nrhs, 
+    2103             :         double *a, 
+    2104             :         int *lda, 
+    2105             :         int *ipiv,
+    2106             :         double *b, 
+    2107             :         int *ldb, 
+    2108             :         int *info)
+    2109             : {
+    2110             :     int a_dim1, a_offset, b_dim1, b_offset;
+    2111             :     int notran;
+    2112           0 :     int c__1 = 1;
+    2113           0 :     int c_n1 = -1;
+    2114           0 :     double one = 1.0;
+    2115             : 
+    2116             :     a_dim1 = *lda;
+    2117             :     a_offset = 1 + a_dim1;
+    2118             :     a -= a_offset;
+    2119             :     --ipiv;
+    2120             :     b_dim1 = *ldb;
+    2121             :     b_offset = 1 + b_dim1;
+    2122             :     b -= b_offset;
+    2123             : 
+    2124           0 :     *info = 0;
+    2125           0 :     notran = (*trans=='N' || *trans=='n');
+    2126             : 
+    2127           0 :     if (*n <= 0 || *nrhs <= 0) 
+    2128             :         return;
+    2129             : 
+    2130           0 :     if (notran) {
+    2131           0 :         PLUMED_BLAS_F77_FUNC(dlaswp,DLASWP)(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c__1);
+    2132           0 :         PLUMED_BLAS_F77_FUNC(dtrsm,DTRSM)("Left", "Lower", "No transpose", "Unit", n, nrhs, &one, 
+    2133             :                &a[a_offset], lda, &b[b_offset], ldb);
+    2134             : 
+    2135           0 :         PLUMED_BLAS_F77_FUNC(dtrsm,DTRSM)("Left", "Upper", "No transpose", "Non-unit", n, nrhs, &one, 
+    2136             :                &a[a_offset], lda, &b[b_offset], ldb);
+    2137             :     } else {
+    2138           0 :         PLUMED_BLAS_F77_FUNC(dtrsm,DTRSM)("Left", "Upper", "Transpose", "Non-unit", n, nrhs, &one, 
+    2139             :                &a[a_offset], lda, &b[b_offset], ldb);
+    2140           0 :         PLUMED_BLAS_F77_FUNC(dtrsm,DTRSM)("Left", "Lower", "Transpose", "Unit", n, nrhs, &one, 
+    2141             :                &a[a_offset], lda, &b[b_offset], ldb);
+    2142             : 
+    2143           0 :         PLUMED_BLAS_F77_FUNC(dlaswp,DLASWP)(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c_n1);
+    2144             :     }
+    2145             : 
+    2146             :     return;
+    2147             : 
+    2148             : } 
+    2149             : }
+    2150             : }
+    2151             : #include <cmath>
+    2152             : #include "blas/blas.h"
+    2153             : #include "lapack.h"
+    2154             : 
+    2155             : 
+    2156             : #include "blas/blas.h"
+    2157             : namespace PLMD{
+    2158             : namespace lapack{
+    2159             : using namespace blas;
+    2160             : void 
+    2161          12 : PLUMED_BLAS_F77_FUNC(dlabrd,DLABRD)(int *m, 
+    2162             :         int *n, 
+    2163             :         int *nb,
+    2164             :         double *a, 
+    2165             :         int *lda, 
+    2166             :         double *d__,
+    2167             :         double *e,
+    2168             :         double *tauq, 
+    2169             :         double *taup,
+    2170             :         double *x,
+    2171             :         int *ldx,
+    2172             :         double *y,
+    2173             :         int *ldy)
+    2174             : {
+    2175             :     int a_dim1, a_offset, x_dim1, x_offset, y_dim1, y_offset;
+    2176             :     int i__1, i__2, i__3;
+    2177          12 :     double one = 1.0;
+    2178          12 :     double minusone = -1.0;
+    2179          12 :     double zero = 0.0;
+    2180          12 :     int c__1 = 1;
+    2181             :     int i__;
+    2182             : 
+    2183          12 :     a_dim1 = *lda;
+    2184          12 :     a_offset = 1 + a_dim1;
+    2185          12 :     a -= a_offset;
+    2186          12 :     --d__;
+    2187          12 :     --e;
+    2188          12 :     --tauq;
+    2189          12 :     --taup;
+    2190          12 :     x_dim1 = *ldx;
+    2191          12 :     x_offset = 1 + x_dim1;
+    2192          12 :     x -= x_offset;
+    2193          12 :     y_dim1 = *ldy;
+    2194          12 :     y_offset = 1 + y_dim1;
+    2195          12 :     y -= y_offset;
+    2196             : 
+    2197          12 :     if (*m <= 0 || *n <= 0) {
+    2198             :         return;
+    2199             :     }
+    2200             : 
+    2201          12 :     if (*m >= *n) {
+    2202             : 
+    2203          12 :         i__1 = *nb;
+    2204         396 :         for (i__ = 1; i__ <= i__1; ++i__) {
+    2205             : 
+    2206         384 :             i__2 = *m - i__ + 1;
+    2207         384 :             i__3 = i__ - 1;
+    2208         384 :             PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + a_dim1], lda,
+    2209         384 :                      &y[i__ + y_dim1], ldy, &one, &a[i__ + i__ * a_dim1], &c__1);
+    2210         384 :             i__2 = *m - i__ + 1;
+    2211         384 :             i__3 = i__ - 1;
+    2212         384 :             PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + x_dim1], ldx,
+    2213         384 :                    &a[i__*a_dim1+1],&c__1,&one,&a[i__+i__*a_dim1],&c__1);
+    2214             : 
+    2215         384 :             i__2 = *m - i__ + 1;
+    2216         384 :             i__3 = i__ + 1;
+    2217         384 :             if(*m<i__3)
+    2218           0 :               i__3 = *m;
+    2219         384 :             PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i__2, &a[i__ + i__ * a_dim1], &a[i__3 + i__ * a_dim1], 
+    2220         384 :                     &c__1, &tauq[i__]);
+    2221         384 :             d__[i__] = a[i__ + i__ * a_dim1];
+    2222         384 :             if (i__ < *n) {
+    2223         384 :                 a[i__ + i__ * a_dim1] = 1.;
+    2224             : 
+    2225         384 :                 i__2 = *m - i__ + 1;
+    2226         384 :                 i__3 = *n - i__;
+    2227         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + (i__ + 1) * 
+    2228         384 :                         a_dim1], lda, &a[i__ + i__ * a_dim1], &c__1, &zero, &
+    2229         384 :                         y[i__ + 1 + i__ * y_dim1], &c__1);
+    2230         384 :                 i__2 = *m - i__ + 1;
+    2231         384 :                 i__3 = i__ - 1;
+    2232         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + a_dim1], 
+    2233         384 :                         lda, &a[i__ + i__ * a_dim1], &c__1, &zero, &y[i__ * 
+    2234         384 :                         y_dim1 + 1], &c__1);
+    2235         384 :                 i__2 = *n - i__;
+    2236         384 :                 i__3 = i__ - 1;
+    2237         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + 1 + 
+    2238         384 :                         y_dim1], ldy, &y[i__ * y_dim1 + 1], &c__1, &one, &y[
+    2239         384 :                         i__ + 1 + i__ * y_dim1], &c__1);
+    2240         384 :                 i__2 = *m - i__ + 1;
+    2241         384 :                 i__3 = i__ - 1;
+    2242         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__3, &one, &x[i__ + x_dim1], 
+    2243         384 :                         ldx, &a[i__ + i__ * a_dim1], &c__1, &zero, &y[i__ * 
+    2244         384 :                         y_dim1 + 1], &c__1);
+    2245         384 :                 i__2 = i__ - 1;
+    2246         384 :                 i__3 = *n - i__;
+    2247         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__3, &minusone, &a[(i__ + 1) * 
+    2248         384 :                         a_dim1 + 1], lda, &y[i__ * y_dim1 + 1], &c__1, &one, 
+    2249         384 :                         &y[i__ + 1 + i__ * y_dim1], &c__1);
+    2250         384 :                 i__2 = *n - i__;
+    2251         384 :                 PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__2, &tauq[i__], &y[i__ + 1 + i__ * y_dim1], &c__1);
+    2252             : 
+    2253         384 :                 i__2 = *n - i__;
+    2254         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__, &minusone, &y[i__ + 1 + 
+    2255         384 :                         y_dim1], ldy, &a[i__ + a_dim1], lda, &one, &a[i__ + (
+    2256         384 :                         i__ + 1) * a_dim1], lda);
+    2257         384 :                 i__2 = i__ - 1;
+    2258         384 :                 i__3 = *n - i__;
+    2259         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__3, &minusone, &a[(i__ + 1) * 
+    2260         384 :                         a_dim1 + 1], lda, &x[i__ + x_dim1], ldx, &one, &a[
+    2261         384 :                         i__ + (i__ + 1) * a_dim1], lda);
+    2262             : 
+    2263         384 :                 i__2 = *n - i__;
+    2264         384 :                 i__3 = i__ + 2;
+    2265         384 :                 if(*n<i__3)
+    2266           0 :                   i__3 = *n;
+    2267         384 :                 PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i__2, &a[i__ + (i__ + 1) * a_dim1], 
+    2268         384 :                         &a[i__ + i__3 * a_dim1], lda, &taup[i__]);
+    2269         384 :                 e[i__] = a[i__ + (i__ + 1) * a_dim1];
+    2270         384 :                 a[i__ + (i__ + 1) * a_dim1] = 1.;
+    2271             : 
+    2272         384 :                 i__2 = *m - i__;
+    2273         384 :                 i__3 = *n - i__;
+    2274         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &one, &a[i__ + 1 + (i__ 
+    2275         384 :                         + 1) * a_dim1], lda, &a[i__ + (i__ + 1) * a_dim1], 
+    2276         384 :                         lda, &zero, &x[i__ + 1 + i__ * x_dim1], &c__1);
+    2277         384 :                 i__2 = *n - i__;
+    2278         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__, &one, &y[i__ + 1 + y_dim1], 
+    2279         384 :                         ldy, &a[i__ + (i__ + 1) * a_dim1], lda, &zero, &x[
+    2280         384 :                         i__ * x_dim1 + 1], &c__1);
+    2281         384 :                 i__2 = *m - i__;
+    2282         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__, &minusone, &a[i__ + 1 + 
+    2283         384 :                         a_dim1], lda, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+    2284         384 :                         i__ + 1 + i__ * x_dim1], &c__1);
+    2285         384 :                 i__2 = i__ - 1;
+    2286         384 :                 i__3 = *n - i__;
+    2287         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &one, &a[(i__ + 1) * 
+    2288         384 :                         a_dim1 + 1], lda, &a[i__ + (i__ + 1) * a_dim1], lda, &
+    2289         384 :                         zero, &x[i__ * x_dim1 + 1], &c__1);
+    2290         384 :                 i__2 = *m - i__;
+    2291         384 :                 i__3 = i__ - 1;
+    2292         384 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + 1 + 
+    2293         384 :                         x_dim1], ldx, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+    2294         384 :                         i__ + 1 + i__ * x_dim1], &c__1);
+    2295         384 :                 i__2 = *m - i__;
+    2296         384 :                 PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__2, &taup[i__], &x[i__ + 1 + i__ * x_dim1], &c__1);
+    2297             :             }
+    2298             :         }
+    2299             :     } else {
+    2300             : 
+    2301           0 :         i__1 = *nb;
+    2302           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+    2303             : 
+    2304           0 :             i__2 = *n - i__ + 1;
+    2305           0 :             i__3 = i__ - 1;
+    2306           0 :             PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + y_dim1], ldy,
+    2307           0 :                      &a[i__ + a_dim1], lda, &one, &a[i__ + i__ * a_dim1],lda);
+    2308           0 :             i__2 = i__ - 1;
+    2309           0 :             i__3 = *n - i__ + 1;
+    2310           0 :             PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__3, &minusone, &a[i__ * a_dim1 + 1], 
+    2311           0 :                     lda, &x[i__ + x_dim1], ldx, &one,&a[i__+i__*a_dim1],lda);
+    2312             : 
+    2313           0 :             i__2 = *n - i__ + 1;
+    2314           0 :             i__3 = i__ + 1;
+    2315           0 :             if(*n<i__3)
+    2316           0 :               i__3 = *n;
+    2317           0 :             PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i__2, &a[i__ + i__ * a_dim1], 
+    2318           0 :                     &a[i__ + i__3 * a_dim1], lda, &taup[i__]);
+    2319           0 :             d__[i__] = a[i__ + i__ * a_dim1];
+    2320           0 :             if (i__ < *m) {
+    2321           0 :                 a[i__ + i__ * a_dim1] = 1.;
+    2322             : 
+    2323           0 :                 i__2 = *m - i__;
+    2324           0 :                 i__3 = *n - i__ + 1;
+    2325           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose",&i__2,&i__3,&one,&a[i__+1+i__*a_dim1], 
+    2326             :                        lda, &a[i__ + i__ * a_dim1], lda, &zero, 
+    2327           0 :                        &x[i__ + 1 + i__ * x_dim1], &c__1);
+    2328           0 :                 i__2 = *n - i__ + 1;
+    2329           0 :                 i__3 = i__ - 1;
+    2330           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__3, &one, &y[i__ + y_dim1], 
+    2331           0 :                         ldy, &a[i__ + i__ * a_dim1], lda, &zero, &x[i__ * 
+    2332           0 :                         x_dim1 + 1], &c__1);
+    2333           0 :                 i__2 = *m - i__;
+    2334           0 :                 i__3 = i__ - 1;
+    2335           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + 1 + 
+    2336           0 :                         a_dim1], lda, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+    2337           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+    2338           0 :                 i__2 = i__ - 1;
+    2339           0 :                 i__3 = *n - i__ + 1;
+    2340           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &one, &a[i__ * a_dim1 + 
+    2341           0 :                         1], lda, &a[i__ + i__ * a_dim1], lda, &zero, &x[i__ *
+    2342           0 :                          x_dim1 + 1], &c__1);
+    2343           0 :                 i__2 = *m - i__;
+    2344           0 :                 i__3 = i__ - 1;
+    2345           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + 1 + 
+    2346           0 :                         x_dim1], ldx, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+    2347           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+    2348           0 :                 i__2 = *m - i__;
+    2349           0 :                 PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__2, &taup[i__], &x[i__ + 1 + i__ * x_dim1], &c__1);
+    2350             : 
+    2351           0 :                 i__2 = *m - i__;
+    2352           0 :                 i__3 = i__ - 1;
+    2353           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + 1 + 
+    2354           0 :                         a_dim1], lda, &y[i__ + y_dim1], ldy, &one, &a[i__ + 
+    2355           0 :                         1 + i__ * a_dim1], &c__1);
+    2356           0 :                 i__2 = *m - i__;
+    2357           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__, &minusone, &x[i__ + 1 + 
+    2358           0 :                         x_dim1], ldx, &a[i__ * a_dim1 + 1], &c__1, &one, &a[
+    2359           0 :                         i__ + 1 + i__ * a_dim1], &c__1);
+    2360             : 
+    2361           0 :                 i__2 = *m - i__;
+    2362           0 :                 i__3 = i__ + 2;
+    2363           0 :                 if(*m<i__3)
+    2364           0 :                   i__3 = *m;
+    2365           0 :                 PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i__2, &a[i__ + 1 + i__ * a_dim1], 
+    2366           0 :                         &a[i__3 + i__ * a_dim1], &c__1, &tauq[i__]);
+    2367           0 :                 e[i__] = a[i__ + 1 + i__ * a_dim1];
+    2368           0 :                 a[i__ + 1 + i__ * a_dim1] = 1.;
+    2369             : 
+    2370           0 :                 i__2 = *m - i__;
+    2371           0 :                 i__3 = *n - i__;
+    2372           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + 1 + (i__ + 
+    2373           0 :                         1) * a_dim1], lda, &a[i__ + 1 + i__ * a_dim1], &c__1, 
+    2374           0 :                         &zero, &y[i__ + 1 + i__ * y_dim1], &c__1);
+    2375           0 :                 i__2 = *m - i__;
+    2376           0 :                 i__3 = i__ - 1;
+    2377           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + 1 + a_dim1],
+    2378           0 :                          lda, &a[i__ + 1 + i__ * a_dim1], &c__1, &zero, &y[
+    2379           0 :                         i__ * y_dim1 + 1], &c__1);
+    2380           0 :                 i__2 = *n - i__;
+    2381           0 :                 i__3 = i__ - 1;
+    2382           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + 1 + 
+    2383           0 :                         y_dim1], ldy, &y[i__ * y_dim1 + 1], &c__1, &one, &y[
+    2384           0 :                         i__ + 1 + i__ * y_dim1], &c__1);
+    2385           0 :                 i__2 = *m - i__;
+    2386           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__, &one, &x[i__ + 1 + x_dim1], 
+    2387           0 :                         ldx, &a[i__ + 1 + i__ * a_dim1], &c__1, &zero, &y[
+    2388           0 :                         i__ * y_dim1 + 1], &c__1);
+    2389           0 :                 i__2 = *n - i__;
+    2390           0 :                 PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__, &i__2, &minusone, &a[(i__ + 1) * a_dim1 
+    2391           0 :                         + 1], lda, &y[i__ * y_dim1 + 1], &c__1, &one, &y[i__ 
+    2392           0 :                         + 1 + i__ * y_dim1], &c__1);
+    2393           0 :                 i__2 = *n - i__;
+    2394           0 :                 PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__2, &tauq[i__], &y[i__ + 1 + i__ * y_dim1], &c__1);
+    2395             :             }
+    2396             :         }
+    2397             :     }
+    2398             :     return;
+    2399             : } 
+    2400             : 
+    2401             : }
+    2402             : }
+    2403             : #include <cctype>
+    2404             : #include "lapack.h"
+    2405             : 
+    2406             : /* LAPACK */
+    2407             : #include "blas/blas.h"
+    2408             : namespace PLMD{
+    2409             : namespace lapack{
+    2410             : using namespace blas;
+    2411             : void
+    2412          54 : PLUMED_BLAS_F77_FUNC(dlacpy,DLACPY)(const char *uplo,
+    2413             :         int *m,
+    2414             :         int *n,
+    2415             :         double *a,
+    2416             :         int *lda,
+    2417             :         double *b,
+    2418             :         int *ldb)
+    2419             : {
+    2420             :   int i,j,minjm;
+    2421          54 :   const char ch=std::toupper(*uplo);
+    2422             : 
+    2423          54 :   if(ch=='U') {
+    2424           0 :     for(j=0;j<*n;j++) {
+    2425           0 :       minjm = (j < (*m-1)) ? j : (*m-1);
+    2426           0 :       for(i=0;i<=minjm;i++)
+    2427           0 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+    2428             :     }
+    2429          54 :   } else if(ch=='L') {
+    2430           3 :     for(j=0;j<*n;j++) {
+    2431           7 :       for(i=j;i<*m;i++)
+    2432           5 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+    2433             :     }
+    2434             :   } else {
+    2435        2222 :     for(j=0;j<*n;j++) {
+    2436       99977 :       for(i=0;i<*m;i++)
+    2437       97808 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+    2438             :     }    
+    2439             :   }
+    2440          54 : }
+    2441             : }
+    2442             : }
+    2443             : #include <cmath>
+    2444             : #include "lapack.h"
+    2445             : 
+    2446             : 
+    2447             : #include "blas/blas.h"
+    2448             : namespace PLMD{
+    2449             : namespace lapack{
+    2450             : using namespace blas;
+    2451             : void
+    2452           0 : PLUMED_BLAS_F77_FUNC(dlae2,DLAE2)(double *a, 
+    2453             :        double *b,
+    2454             :        double *c__, 
+    2455             :        double *rt1, 
+    2456             :        double *rt2)
+    2457             : {
+    2458             :     double d__1;
+    2459             :     double ab, df, tb, sm, rt, adf, acmn, acmx;
+    2460             : 
+    2461             : 
+    2462           0 :     sm = *a + *c__;
+    2463           0 :     df = *a - *c__;
+    2464             :     adf = std::abs(df);
+    2465           0 :     tb = *b + *b;
+    2466             :     ab = std::abs(tb);
+    2467           0 :     if (std::abs(*a) > std::abs(*c__)) {
+    2468             :         acmx = *a;
+    2469             :         acmn = *c__;
+    2470             :     } else {
+    2471             :         acmx = *c__;
+    2472             :         acmn = *a;
+    2473             :     }
+    2474           0 :     if (adf > ab) {
+    2475           0 :         d__1 = ab / adf;
+    2476           0 :         rt = adf *  std::sqrt(d__1 * d__1 + 1.);
+    2477           0 :     } else if (adf < ab) {
+    2478           0 :         d__1 = adf / ab;
+    2479           0 :         rt = ab *  std::sqrt(d__1 * d__1 + 1.);
+    2480             :     } else {
+    2481             : 
+    2482           0 :         rt = ab *  std::sqrt(2.);
+    2483             :     }
+    2484           0 :     if (sm < 0.) {
+    2485           0 :         *rt1 = (sm - rt) * .5;
+    2486           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+    2487           0 :     } else if (sm > 0.) {
+    2488           0 :         *rt1 = (sm + rt) * .5;
+    2489           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+    2490             :     } else {
+    2491           0 :         *rt1 = rt * .5;
+    2492           0 :         *rt2 = rt * -.5;
+    2493             :     }
+    2494           0 :     return;
+    2495             : 
+    2496             : }
+    2497             : 
+    2498             : 
+    2499             : }
+    2500             : }
+    2501             : #include <cmath>
+    2502             : #include "lapack.h"
+    2503             : 
+    2504             : #include "blas/blas.h"
+    2505             : namespace PLMD{
+    2506             : namespace lapack{
+    2507             : using namespace blas;
+    2508             : void
+    2509           0 : PLUMED_BLAS_F77_FUNC(dlaebz,DLAEBZ)(int *ijob,
+    2510             :         int *nitmax,
+    2511             :         int *n, 
+    2512             :         int *mmax,
+    2513             :         int *minp,
+    2514             :         int *nbmin,
+    2515             :         double *abstol, 
+    2516             :         double *reltol, 
+    2517             :         double *pivmin, 
+    2518             :         double *d__,
+    2519             :         double *e,
+    2520             :         double *e2, 
+    2521             :         int *nval,
+    2522             :         double *ab, 
+    2523             :         double *c__, 
+    2524             :         int *mout, 
+    2525             :         int *nab,
+    2526             :         double *work,
+    2527             :         int *iwork, 
+    2528             :         int *info)
+    2529             : {
+    2530             :     int nab_dim1, nab_offset, ab_dim1, ab_offset, i__1, i__2, i__3, i__4, 
+    2531             :             i__5, i__6;
+    2532             :     double d__1, d__2, d__3, d__4;
+    2533             : 
+    2534             :     int j, kf, ji, kl, jp, jit;
+    2535             :     double tmp1, tmp2;
+    2536             :     int itmp1, itmp2, kfnew, klnew;
+    2537             : 
+    2538           0 :     nab_dim1 = *mmax;
+    2539           0 :     nab_offset = 1 + nab_dim1;
+    2540           0 :     nab -= nab_offset;
+    2541             :     ab_dim1 = *mmax;
+    2542             :     ab_offset = 1 + ab_dim1;
+    2543           0 :     ab -= ab_offset;
+    2544           0 :     --d__;
+    2545             :     --e;
+    2546           0 :     --e2;
+    2547           0 :     --nval;
+    2548           0 :     --c__;
+    2549           0 :     --work;
+    2550           0 :     --iwork;
+    2551             : 
+    2552           0 :     *info = 0;
+    2553           0 :     if (*ijob < 1 || *ijob > 3) {
+    2554           0 :         *info = -1;
+    2555           0 :         return;
+    2556             :     }
+    2557             : 
+    2558           0 :     if (*ijob == 1) {
+    2559             : 
+    2560           0 :         *mout = 0;
+    2561             : 
+    2562           0 :         i__1 = *minp;
+    2563           0 :         for (ji = 1; ji <= i__1; ++ji) {
+    2564           0 :             for (jp = 1; jp <= 2; ++jp) {
+    2565           0 :                 tmp1 = d__[1] - ab[ji + jp * ab_dim1];
+    2566           0 :                 if (std::abs(tmp1) < *pivmin) {
+    2567           0 :                     tmp1 = -(*pivmin);
+    2568             :                 }
+    2569           0 :                 nab[ji + jp * nab_dim1] = 0;
+    2570           0 :                 if (tmp1 <= 0.) {
+    2571           0 :                     nab[ji + jp * nab_dim1] = 1;
+    2572             :                 }
+    2573             : 
+    2574           0 :                 i__2 = *n;
+    2575           0 :                 for (j = 2; j <= i__2; ++j) {
+    2576           0 :                     tmp1 = d__[j] - e2[j - 1] / tmp1 - ab[ji + jp * ab_dim1];
+    2577           0 :                     if (std::abs(tmp1) < *pivmin) {
+    2578           0 :                         tmp1 = -(*pivmin);
+    2579             :                     }
+    2580           0 :                     if (tmp1 <= 0.) {
+    2581           0 :                         ++nab[ji + jp * nab_dim1];
+    2582             :                     }
+    2583             :                 }
+    2584             :             }
+    2585           0 :             *mout = *mout + nab[ji + (nab_dim1 << 1)] - nab[ji + nab_dim1];
+    2586             :         }
+    2587             :         return;
+    2588             :     }
+    2589             : 
+    2590             :     kf = 1;
+    2591           0 :     kl = *minp;
+    2592             : 
+    2593           0 :     if (*ijob == 2) {
+    2594             :         i__1 = *minp;
+    2595           0 :         for (ji = 1; ji <= i__1; ++ji) {
+    2596           0 :             c__[ji] = (ab[ji + ab_dim1] + ab[ji + (ab_dim1 << 1)]) * .5;
+    2597             :         }
+    2598             :     }
+    2599             : 
+    2600           0 :     i__1 = *nitmax;
+    2601           0 :     for (jit = 1; jit <= i__1; ++jit) {
+    2602             : 
+    2603           0 :         if (kl - kf + 1 >= *nbmin && *nbmin > 0) {
+    2604             : 
+    2605             :             i__2 = kl;
+    2606           0 :             for (ji = kf; ji <= i__2; ++ji) {
+    2607             : 
+    2608           0 :                 work[ji] = d__[1] - c__[ji];
+    2609           0 :                 iwork[ji] = 0;
+    2610           0 :                 if (work[ji] <= *pivmin) {
+    2611           0 :                     iwork[ji] = 1;
+    2612           0 :                     d__1 = work[ji], d__2 = -(*pivmin);
+    2613           0 :                     work[ji] = (d__1<d__2) ? d__1 : d__2;
+    2614             :                 }
+    2615             : 
+    2616           0 :                 i__3 = *n;
+    2617           0 :                 for (j = 2; j <= i__3; ++j) {
+    2618           0 :                     work[ji] = d__[j] - e2[j - 1] / work[ji] - c__[ji];
+    2619           0 :                     if (work[ji] <= *pivmin) {
+    2620           0 :                         ++iwork[ji];
+    2621           0 :                         d__1 = work[ji], d__2 = -(*pivmin);
+    2622           0 :                         work[ji] = (d__1<d__2) ? d__1 : d__2;
+    2623             :                     }
+    2624             :                 }
+    2625             :             }
+    2626             : 
+    2627           0 :             if (*ijob <= 2) {
+    2628             : 
+    2629             :                 klnew = kl;
+    2630             :                 i__2 = kl;
+    2631           0 :                 for (ji = kf; ji <= i__2; ++ji) {
+    2632             : 
+    2633           0 :                   i__5 = nab[ji + nab_dim1];
+    2634           0 :                   i__6 = iwork[ji];
+    2635           0 :                   i__3 = nab[ji + (nab_dim1 << 1)];
+    2636             :                   i__4 = (i__5>i__6) ? i__5 : i__6;
+    2637           0 :                     iwork[ji] = (i__3<i__4) ? i__3 : i__4;
+    2638             : 
+    2639           0 :                     if (iwork[ji] == nab[ji + (nab_dim1 << 1)]) {
+    2640             : 
+    2641           0 :                         ab[ji + (ab_dim1 << 1)] = c__[ji];
+    2642             : 
+    2643           0 :                     } else if (iwork[ji] == nab[ji + nab_dim1]) {
+    2644             : 
+    2645           0 :                         ab[ji + ab_dim1] = c__[ji];
+    2646             :                     } else {
+    2647           0 :                         ++klnew;
+    2648           0 :                         if (klnew <= *mmax) {
+    2649             : 
+    2650           0 :                             ab[klnew + (ab_dim1 << 1)] = ab[ji + (ab_dim1 << 
+    2651           0 :                                     1)];
+    2652           0 :                             nab[klnew + (nab_dim1 << 1)] = nab[ji + (nab_dim1 
+    2653           0 :                                     << 1)];
+    2654           0 :                             ab[klnew + ab_dim1] = c__[ji];
+    2655           0 :                             nab[klnew + nab_dim1] = iwork[ji];
+    2656           0 :                             ab[ji + (ab_dim1 << 1)] = c__[ji];
+    2657           0 :                             nab[ji + (nab_dim1 << 1)] = iwork[ji];
+    2658             :                         } else {
+    2659           0 :                             *info = *mmax + 1;
+    2660             :                         }
+    2661             :                     }
+    2662             :                 }
+    2663           0 :                 if (*info != 0) {
+    2664             :                     return;
+    2665             :                 }
+    2666             :                 kl = klnew;
+    2667             :             } else {
+    2668             : 
+    2669             :                 i__2 = kl;
+    2670           0 :                 for (ji = kf; ji <= i__2; ++ji) {
+    2671           0 :                     if (iwork[ji] <= nval[ji]) {
+    2672           0 :                         ab[ji + ab_dim1] = c__[ji];
+    2673           0 :                         nab[ji + nab_dim1] = iwork[ji];
+    2674             :                     }
+    2675           0 :                     if (iwork[ji] >= nval[ji]) {
+    2676           0 :                         ab[ji + (ab_dim1 << 1)] = c__[ji];
+    2677           0 :                         nab[ji + (nab_dim1 << 1)] = iwork[ji];
+    2678             :                     }
+    2679             :                 }
+    2680             :             }
+    2681             : 
+    2682             :         } else {
+    2683             : 
+    2684             :             klnew = kl;
+    2685             :             i__2 = kl;
+    2686           0 :             for (ji = kf; ji <= i__2; ++ji) {
+    2687             : 
+    2688           0 :                 tmp1 = c__[ji];
+    2689           0 :                 tmp2 = d__[1] - tmp1;
+    2690             :                 itmp1 = 0;
+    2691           0 :                 if (tmp2 <= *pivmin) {
+    2692             :                     itmp1 = 1;
+    2693           0 :                     d__1 = tmp2, d__2 = -(*pivmin);
+    2694           0 :                     tmp2 = (d__1<d__2) ? d__1 : d__2;
+    2695             :                 }
+    2696             : 
+    2697           0 :                 i__3 = *n;
+    2698           0 :                 for (j = 2; j <= i__3; ++j) {
+    2699           0 :                     tmp2 = d__[j] - e2[j - 1] / tmp2 - tmp1;
+    2700           0 :                     if (tmp2 <= *pivmin) {
+    2701           0 :                         ++itmp1;
+    2702           0 :                         d__1 = tmp2, d__2 = -(*pivmin);
+    2703           0 :                         tmp2 = (d__1<d__2) ? d__1 : d__2;
+    2704             :                     }
+    2705             :                 }
+    2706             : 
+    2707           0 :                 if (*ijob <= 2) {
+    2708             : 
+    2709           0 :                     i__5 = nab[ji + nab_dim1];
+    2710           0 :                     i__3 = nab[ji + (nab_dim1 << 1)];
+    2711             :                     i__4 = (i__5>itmp1) ? i__5 : itmp1;
+    2712             :                     itmp1 = (i__3<i__4) ? i__3 : i__4;
+    2713             : 
+    2714           0 :                     if (itmp1 == nab[ji + (nab_dim1 << 1)]) {
+    2715             : 
+    2716           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+    2717             : 
+    2718           0 :                     } else if (itmp1 == nab[ji + nab_dim1]) {
+    2719             : 
+    2720           0 :                         ab[ji + ab_dim1] = tmp1;
+    2721           0 :                     } else if (klnew < *mmax) {
+    2722             : 
+    2723           0 :                         ++klnew;
+    2724           0 :                         ab[klnew + (ab_dim1 << 1)] = ab[ji + (ab_dim1 << 1)];
+    2725           0 :                         nab[klnew + (nab_dim1 << 1)] = nab[ji + (nab_dim1 << 
+    2726           0 :                                 1)];
+    2727           0 :                         ab[klnew + ab_dim1] = tmp1;
+    2728           0 :                         nab[klnew + nab_dim1] = itmp1;
+    2729           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+    2730           0 :                         nab[ji + (nab_dim1 << 1)] = itmp1;
+    2731             :                     } else {
+    2732           0 :                         *info = *mmax + 1;
+    2733           0 :                         return;
+    2734             :                     }
+    2735             :                 } else {
+    2736             : 
+    2737           0 :                     if (itmp1 <= nval[ji]) {
+    2738           0 :                         ab[ji + ab_dim1] = tmp1;
+    2739           0 :                         nab[ji + nab_dim1] = itmp1;
+    2740             :                     }
+    2741           0 :                     if (itmp1 >= nval[ji]) {
+    2742           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+    2743           0 :                         nab[ji + (nab_dim1 << 1)] = itmp1;
+    2744             :                     }
+    2745             :                 }
+    2746             :             }
+    2747             :             kl = klnew;
+    2748             : 
+    2749             :         }
+    2750             : 
+    2751             :         kfnew = kf;
+    2752             :         i__2 = kl;
+    2753           0 :         for (ji = kf; ji <= i__2; ++ji) {
+    2754           0 :             tmp1 = std::abs(ab[ji + (ab_dim1 << 1)] - ab[ji + ab_dim1]);
+    2755             :             d__3 = std::abs(ab[ji + (ab_dim1 << 1)]);
+    2756             :             d__4 = std::abs(ab[ji + ab_dim1]);
+    2757           0 :             tmp2 = (d__3>d__4) ? d__3 : d__4;
+    2758           0 :             d__1 = (*abstol>*pivmin) ? *abstol : *pivmin;
+    2759           0 :             d__2 = *reltol * tmp2;
+    2760           0 :             if (tmp1 < ((d__1>d__2) ? d__1 : d__2) || nab[ji + nab_dim1] >= nab[ji + (
+    2761           0 :                     nab_dim1 << 1)]) {
+    2762             : 
+    2763           0 :                 if (ji > kfnew) {
+    2764             :                     tmp1 = ab[ji + ab_dim1];
+    2765             :                     tmp2 = ab[ji + (ab_dim1 << 1)];
+    2766           0 :                     itmp1 = nab[ji + nab_dim1];
+    2767           0 :                     itmp2 = nab[ji + (nab_dim1 << 1)];
+    2768           0 :                     ab[ji + ab_dim1] = ab[kfnew + ab_dim1];
+    2769           0 :                     ab[ji + (ab_dim1 << 1)] = ab[kfnew + (ab_dim1 << 1)];
+    2770           0 :                     nab[ji + nab_dim1] = nab[kfnew + nab_dim1];
+    2771           0 :                     nab[ji + (nab_dim1 << 1)] = nab[kfnew + (nab_dim1 << 1)];
+    2772           0 :                     ab[kfnew + ab_dim1] = tmp1;
+    2773           0 :                     ab[kfnew + (ab_dim1 << 1)] = tmp2;
+    2774           0 :                     nab[kfnew + nab_dim1] = itmp1;
+    2775           0 :                     nab[kfnew + (nab_dim1 << 1)] = itmp2;
+    2776           0 :                     if (*ijob == 3) {
+    2777           0 :                         itmp1 = nval[ji];
+    2778           0 :                         nval[ji] = nval[kfnew];
+    2779           0 :                         nval[kfnew] = itmp1;
+    2780             :                     }
+    2781             :                 }
+    2782           0 :                 ++kfnew;
+    2783             :             }
+    2784             :         }
+    2785             :         kf = kfnew;
+    2786             : 
+    2787             :         i__2 = kl;
+    2788           0 :         for (ji = kf; ji <= i__2; ++ji) {
+    2789           0 :             c__[ji] = (ab[ji + ab_dim1] + ab[ji + (ab_dim1 << 1)]) * .5;
+    2790             :         }
+    2791             : 
+    2792           0 :         if (kf > kl) {
+    2793             :             break;
+    2794             :         }
+    2795             :     }
+    2796             : 
+    2797           0 :     i__1 = kl + 1 - kf;
+    2798           0 :     if(i__1>0)
+    2799           0 :       *info = i__1;
+    2800             : 
+    2801           0 :     *mout = kl;
+    2802             : 
+    2803           0 :     return;
+    2804             : 
+    2805             : }
+    2806             : 
+    2807             : 
+    2808             : }
+    2809             : }
+    2810             : #include <cmath>
+    2811             : 
+    2812             : #include "lapack.h"
+    2813             : 
+    2814             : #include "real.h"
+    2815             : 
+    2816             : #include "blas/blas.h"
+    2817             : namespace PLMD{
+    2818             : namespace lapack{
+    2819             : using namespace blas;
+    2820             : void
+    2821        1387 : PLUMED_BLAS_F77_FUNC(dlaed6,DLAED6)(int *kniter, 
+    2822             :                         int *orgati, 
+    2823             :                         double *rho, 
+    2824             :                         double *d__,
+    2825             :                         double *z__, 
+    2826             :                         double *finit, 
+    2827             :                         double *tau, 
+    2828             :                         int *info)
+    2829             : {
+    2830             :     int i__1;
+    2831             :     double r__1, r__2, r__3, r__4;
+    2832             : 
+    2833             :     double a, b, c__, f;
+    2834             :     int i__;
+    2835             :     double fc, df, ddf, eta, eps, base;
+    2836             :     int iter;
+    2837             :     double temp, temp1, temp2, temp3, temp4;
+    2838             :     int scale;
+    2839             :     int niter;
+    2840             :     double small1, small2, sminv1, sminv2, dscale[3], sclfac;
+    2841             :     double zscale[3], erretm;
+    2842             :     double safemin;
+    2843             :     double sclinv = 0;
+    2844             :     
+    2845        1387 :     --z__;
+    2846        1387 :     --d__;
+    2847             : 
+    2848        1387 :     *info = 0;
+    2849             : 
+    2850             :     niter = 1;
+    2851        1387 :     *tau = 0.f;
+    2852        1387 :     if (*kniter == 2) {
+    2853         342 :         if (*orgati) {
+    2854         173 :             temp = (d__[3] - d__[2]) / 2.f;
+    2855         173 :             c__ = *rho + z__[1] / (d__[1] - d__[2] - temp);
+    2856         173 :             a = c__ * (d__[2] + d__[3]) + z__[2] + z__[3];
+    2857         173 :             b = c__ * d__[2] * d__[3] + z__[2] * d__[3] + z__[3] * d__[2];
+    2858             :         } else {
+    2859         169 :             temp = (d__[1] - d__[2]) / 2.f;
+    2860         169 :             c__ = *rho + z__[3] / (d__[3] - d__[2] - temp);
+    2861         169 :             a = c__ * (d__[1] + d__[2]) + z__[1] + z__[2];
+    2862         169 :             b = c__ * d__[1] * d__[2] + z__[1] * d__[2] + z__[2] * d__[1];
+    2863             :         }
+    2864         342 :         r__1 = std::abs(a), r__2 = std::abs(b), r__1 = ((r__1>r__2)? r__1:r__2), r__2 = std::abs(c__);
+    2865         342 :         temp = (r__1>r__2) ? r__1 : r__2;
+    2866         342 :         a /= temp;
+    2867         342 :         b /= temp;
+    2868         342 :         c__ /= temp;
+    2869         342 :         if (c__ == 0.f) {
+    2870           0 :             *tau = b / a;
+    2871         342 :         } else if (a <= 0.f) {
+    2872         113 :             *tau = (a -  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1)))) / (
+    2873         113 :                     c__ * 2.f);
+    2874             :         } else {
+    2875         229 :             *tau = b * 2.f / (a +  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1))));
+    2876             :         }
+    2877             : 
+    2878         342 :         temp = *rho + z__[1] / (d__[1] - *tau) + z__[2] / (d__[2] - *tau) + 
+    2879         342 :                 z__[3] / (d__[3] - *tau);
+    2880         342 :         if (std::abs(*finit) <= std::abs(temp)) {
+    2881           0 :             *tau = 0.f;
+    2882             :         }
+    2883             :     }
+    2884             : 
+    2885             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    2886             :     base = 2;
+    2887             :     safemin = PLUMED_GMX_DOUBLE_MIN*(1.0+PLUMED_GMX_DOUBLE_EPS);
+    2888             :     i__1 = static_cast<int>(std::log(safemin) / std::log(base) / 3.f);
+    2889             :     small1 = std::pow(base, static_cast<double>(i__1));
+    2890             :     sminv1 = 1.f / small1;
+    2891             :     small2 = small1 * small1;
+    2892             :     sminv2 = sminv1 * sminv1;
+    2893             : 
+    2894        1387 :     if (*orgati) {
+    2895         706 :         r__3 = (r__1 = d__[2] - *tau, std::abs(r__1)), r__4 = (r__2 = d__[3] - *
+    2896             :                 tau, std::abs(r__2));
+    2897         706 :         temp = (r__3<r__4) ? r__3 : r__4;
+    2898             :     } else {
+    2899         681 :         r__3 = (r__1 = d__[1] - *tau, std::abs(r__1)), r__4 = (r__2 = d__[2] - *
+    2900             :                 tau, std::abs(r__2));
+    2901         681 :         temp = (r__3<r__4) ? r__3 : r__4;
+    2902             :     }
+    2903             :     scale = 0;
+    2904        1387 :     if (temp <= small1) {
+    2905             :         scale = 1;
+    2906           0 :         if (temp <= small2) {
+    2907             : 
+    2908             :             sclfac = sminv2;
+    2909             :             sclinv = small2;
+    2910             :         } else {
+    2911             : 
+    2912             :             sclfac = sminv1;
+    2913             :             sclinv = small1;
+    2914             : 
+    2915             :         }
+    2916             : 
+    2917           0 :         for (i__ = 1; i__ <= 3; ++i__) {
+    2918           0 :             dscale[i__ - 1] = d__[i__] * sclfac;
+    2919           0 :             zscale[i__ - 1] = z__[i__] * sclfac;
+    2920             :         }
+    2921           0 :         *tau *= sclfac;
+    2922             :     } else {
+    2923             : 
+    2924        5548 :         for (i__ = 1; i__ <= 3; ++i__) {
+    2925        4161 :             dscale[i__ - 1] = d__[i__];
+    2926        4161 :             zscale[i__ - 1] = z__[i__];
+    2927             :         }
+    2928             :     }
+    2929             :     fc = 0.f;
+    2930             :     df = 0.f;
+    2931             :     ddf = 0.f;
+    2932        5548 :     for (i__ = 1; i__ <= 3; ++i__) {
+    2933        4161 :         temp = 1.f / (dscale[i__ - 1] - *tau);
+    2934        4161 :         temp1 = zscale[i__ - 1] * temp;
+    2935        4161 :         temp2 = temp1 * temp;
+    2936        4161 :         temp3 = temp2 * temp;
+    2937        4161 :         fc += temp1 / dscale[i__ - 1];
+    2938        4161 :         df += temp2;
+    2939        4161 :         ddf += temp3;
+    2940             :     }
+    2941        1387 :     f = *finit + *tau * fc;
+    2942             : 
+    2943        1387 :     if (std::abs(f) <= 0.f) {
+    2944           0 :         goto L60;
+    2945             :     }
+    2946             :     iter = niter + 1;
+    2947        2782 :     for (niter = iter; niter <= 20; ++niter) {
+    2948        2782 :         if (*orgati) {
+    2949        1436 :             temp1 = dscale[1] - *tau;
+    2950        1436 :             temp2 = dscale[2] - *tau;
+    2951             :         } else {
+    2952        1346 :             temp1 = dscale[0] - *tau;
+    2953        1346 :             temp2 = dscale[1] - *tau;
+    2954             :         }
+    2955        2782 :         a = (temp1 + temp2) * f - temp1 * temp2 * df;
+    2956        2782 :         b = temp1 * temp2 * f;
+    2957        2782 :         c__ = f - (temp1 + temp2) * df + temp1 * temp2 * ddf;
+    2958        2782 :         r__1 = std::abs(a), r__2 = std::abs(b), r__1 = ((r__1>r__2)? r__1:r__2), r__2 = std::abs(c__);
+    2959        2782 :         temp = (r__1>r__2) ? r__1 : r__2;
+    2960        2782 :         a /= temp;
+    2961        2782 :         b /= temp;
+    2962        2782 :         c__ /= temp;
+    2963        2782 :         if (c__ == 0.f) {
+    2964           0 :             eta = b / a;
+    2965        2782 :         } else if (a <= 0.f) {
+    2966          46 :             eta = (a -  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1)))) / ( c__ * 2.f);
+    2967             :         } else {
+    2968        2736 :             eta = b * 2.f / (a +  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs( r__1))));
+    2969             :         }
+    2970        2782 :         if (f * eta >= 0.f) {
+    2971           0 :             eta = -f / df;
+    2972             :         }
+    2973        2782 :         temp = eta + *tau;
+    2974        2782 :         if (*orgati) {
+    2975        1436 :             if (eta > 0.f && temp >= dscale[2]) {
+    2976           0 :                 eta = (dscale[2] - *tau) / 2.f;
+    2977             :             }
+    2978             : 
+    2979        1436 :             if (eta < 0.f && temp <= dscale[1]) {
+    2980           0 :                 eta = (dscale[1] - *tau) / 2.f;
+    2981             :             }
+    2982             :         } else {
+    2983        1346 :             if (eta > 0.f && temp >= dscale[1]) {
+    2984           0 :                 eta = (dscale[1] - *tau) / 2.f;
+    2985             :             }
+    2986        1346 :             if (eta < 0.f && temp <= dscale[0]) {
+    2987           0 :                 eta = (dscale[0] - *tau) / 2.f;
+    2988             :             }
+    2989             :         }
+    2990        2782 :         *tau += eta;
+    2991             :         fc = 0.f;
+    2992             :         erretm = 0.f;
+    2993             :         df = 0.f;
+    2994             :         ddf = 0.f;
+    2995       11128 :         for (i__ = 1; i__ <= 3; ++i__) {
+    2996        8346 :             temp = 1.f / (dscale[i__ - 1] - *tau);
+    2997        8346 :             temp1 = zscale[i__ - 1] * temp;
+    2998        8346 :             temp2 = temp1 * temp;
+    2999        8346 :             temp3 = temp2 * temp;
+    3000        8346 :             temp4 = temp1 / dscale[i__ - 1];
+    3001        8346 :             fc += temp4;
+    3002        8346 :             erretm += std::abs(temp4);
+    3003        8346 :             df += temp2;
+    3004        8346 :             ddf += temp3;
+    3005             :         }
+    3006        2782 :         f = *finit + *tau * fc;
+    3007        2782 :         erretm = (std::abs(*finit) + std::abs(*tau) * erretm) * 8.f + std::abs(*tau) * df;
+    3008        2782 :         if (std::abs(f) <= eps * erretm) {
+    3009        1387 :             goto L60;
+    3010             :         }
+    3011             :     }
+    3012           0 :     *info = 1;
+    3013        1387 : L60:
+    3014        1387 :     if (scale) {
+    3015           0 :         *tau *= sclinv;
+    3016             :     }
+    3017        1387 :     return;
+    3018             : } 
+    3019             : 
+    3020             : 
+    3021             : }
+    3022             : }
+    3023             : #include <cmath>
+    3024             : #include "real.h"
+    3025             : 
+    3026             : #include "lapack.h"
+    3027             : 
+    3028             : 
+    3029             : #include "blas/blas.h"
+    3030             : namespace PLMD{
+    3031             : namespace lapack{
+    3032             : using namespace blas;
+    3033             : void
+    3034           0 : PLUMED_BLAS_F77_FUNC(dlaev2,DLAEV2)(double *   a, 
+    3035             :         double *   b, 
+    3036             :         double *   c__, 
+    3037             :         double *   rt1, 
+    3038             :         double *   rt2, 
+    3039             :         double *   cs1, 
+    3040             :         double *   sn1)
+    3041             : {
+    3042             :     double d__1;
+    3043             : 
+    3044             :     double ab, df, cs, ct, tb, sm, tn, rt, adf, acs;
+    3045             :     int sgn1, sgn2;
+    3046             :     double acmn, acmx;
+    3047             : 
+    3048           0 :     sm = *a + *c__;
+    3049           0 :     df = *a - *c__;
+    3050             :     adf = std::abs(df);
+    3051           0 :     tb = *b + *b;
+    3052             :     ab = std::abs(tb);
+    3053           0 :     if (std::abs(*a) > std::abs(*c__)) {
+    3054             :         acmx = *a;
+    3055             :         acmn = *c__;
+    3056             :     } else {
+    3057             :         acmx = *c__;
+    3058             :         acmn = *a;
+    3059             :     }
+    3060           0 :     if (adf > ab) {
+    3061           0 :         d__1 = ab / adf;
+    3062           0 :         rt = adf *  std::sqrt(d__1 * d__1 + 1.);
+    3063           0 :     } else if (adf < ab) {
+    3064           0 :         d__1 = adf / ab;
+    3065           0 :         rt = ab *  std::sqrt(d__1 * d__1 + 1.);
+    3066             :     } else {
+    3067             : 
+    3068           0 :         rt = ab *  std::sqrt(2.);
+    3069             :     }
+    3070           0 :     if (sm < 0.) {
+    3071           0 :         *rt1 = (sm - rt) * .5;
+    3072             :         sgn1 = -1;
+    3073             : 
+    3074           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+    3075           0 :     } else if (sm > 0.) {
+    3076           0 :         *rt1 = (sm + rt) * .5;
+    3077             :         sgn1 = 1;
+    3078           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+    3079             :     } else {
+    3080           0 :         *rt1 = rt * .5;
+    3081           0 :         *rt2 = rt * -.5;
+    3082             :         sgn1 = 1;
+    3083             :     }
+    3084           0 :     if (df >= 0.) {
+    3085           0 :         cs = df + rt;
+    3086             :         sgn2 = 1;
+    3087             :     } else {
+    3088           0 :         cs = df - rt;
+    3089             :         sgn2 = -1;
+    3090             :     }
+    3091             :     acs = std::abs(cs);
+    3092           0 :     if (acs > ab) {
+    3093           0 :         ct = -tb / cs;
+    3094           0 :         *sn1 = 1. /  std::sqrt(ct * ct + 1.);
+    3095           0 :         *cs1 = ct * *sn1;
+    3096             :     } else {
+    3097           0 :         if (std::abs(ab)<PLUMED_GMX_DOUBLE_MIN) {
+    3098           0 :             *cs1 = 1.;
+    3099           0 :             *sn1 = 0.;
+    3100             :         } else {
+    3101           0 :             tn = -cs / tb;
+    3102           0 :             *cs1 = 1. /  std::sqrt(tn * tn + 1.);
+    3103           0 :             *sn1 = tn * *cs1;
+    3104             :         }
+    3105             :     }
+    3106           0 :     if (sgn1 == sgn2) {
+    3107           0 :         tn = *cs1;
+    3108           0 :         *cs1 = -(*sn1);
+    3109           0 :         *sn1 = tn;
+    3110             :     }
+    3111           0 :     return;
+    3112             : 
+    3113             : }
+    3114             : 
+    3115             : 
+    3116             : }
+    3117             : }
+    3118             : #include <cmath>
+    3119             : #include "real.h"
+    3120             : 
+    3121             : #include "lapack.h"
+    3122             : #include "lapack_limits.h"
+    3123             : 
+    3124             : 
+    3125             : 
+    3126             : #include "blas/blas.h"
+    3127             : namespace PLMD{
+    3128             : namespace lapack{
+    3129             : using namespace blas;
+    3130             : void
+    3131           0 : PLUMED_BLAS_F77_FUNC(dlagtf,DLAGTF)(int *n, 
+    3132             :         double *a, 
+    3133             :         double *lambda, 
+    3134             :         double *b, 
+    3135             :         double *c__, 
+    3136             :         double *tol, 
+    3137             :         double *d__, 
+    3138             :         int *in, 
+    3139             :         int *info)
+    3140             : {
+    3141             :     int i__1;
+    3142             : 
+    3143             :     int k;
+    3144             :     double tl, eps, piv1, piv2, temp, mult, scale1, scale2;
+    3145             : 
+    3146           0 :     --in;
+    3147           0 :     --d__;
+    3148           0 :     --c__;
+    3149           0 :     --b;
+    3150           0 :     --a;
+    3151             : 
+    3152           0 :     *info = 0;
+    3153           0 :     if (*n < 0) {
+    3154           0 :         *info = -1;
+    3155           0 :         return;
+    3156             :     }
+    3157             : 
+    3158           0 :     if (*n == 0) 
+    3159             :         return;
+    3160             :     
+    3161           0 :     a[1] -= *lambda;
+    3162           0 :     in[*n] = 0;
+    3163           0 :     if (*n == 1) {
+    3164           0 :         if (std::abs(a[1])<PLUMED_GMX_DOUBLE_MIN) {
+    3165           0 :             in[1] = 1;
+    3166             :         }
+    3167           0 :         return;
+    3168             :     }
+    3169             : 
+    3170             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    3171             : 
+    3172           0 :     tl = (*tol>eps) ? *tol : eps;
+    3173           0 :     scale1 = std::abs(a[1]) + std::abs(b[1]);
+    3174             :     i__1 = *n - 1;
+    3175           0 :     for (k = 1; k <= i__1; ++k) {
+    3176           0 :         a[k + 1] -= *lambda;
+    3177           0 :         scale2 = std::abs(c__[k]) + std::abs(a[k + 1]);
+    3178           0 :         if (k < *n - 1) {
+    3179           0 :             scale2 += std::abs(b[k + 1]);
+    3180             :         }
+    3181           0 :         if (std::abs(a[k])<PLUMED_GMX_DOUBLE_MIN) {
+    3182             :             piv1 = 0.;
+    3183             :         } else {
+    3184           0 :             piv1 = std::abs(a[k]) / scale1;
+    3185             :         }
+    3186           0 :         if (std::abs(c__[k])<PLUMED_GMX_DOUBLE_MIN) {
+    3187           0 :             in[k] = 0;
+    3188             :             piv2 = 0.;
+    3189             :             scale1 = scale2;
+    3190           0 :             if (k < *n - 1) {
+    3191           0 :                 d__[k] = 0.;
+    3192             :             }
+    3193             :         } else {
+    3194           0 :             piv2 = std::abs(c__[k]) / scale2;
+    3195           0 :             if (piv2 <= piv1) {
+    3196           0 :                 in[k] = 0;
+    3197             :                 scale1 = scale2;
+    3198           0 :                 c__[k] /= a[k];
+    3199           0 :                 a[k + 1] -= c__[k] * b[k];
+    3200           0 :                 if (k < *n - 1) {
+    3201           0 :                     d__[k] = 0.;
+    3202             :                 }
+    3203             :             } else {
+    3204           0 :                 in[k] = 1;
+    3205           0 :                 mult = a[k] / c__[k];
+    3206           0 :                 a[k] = c__[k];
+    3207           0 :                 temp = a[k + 1];
+    3208           0 :                 a[k + 1] = b[k] - mult * temp;
+    3209           0 :                 if (k < *n - 1) {
+    3210           0 :                     d__[k] = b[k + 1];
+    3211           0 :                     b[k + 1] = -mult * d__[k];
+    3212             :                 }
+    3213           0 :                 b[k] = temp;
+    3214           0 :                 c__[k] = mult;
+    3215             :             }
+    3216             :         }
+    3217           0 :         if (((piv1>piv2) ? piv1 : piv2) <= tl && in[*n] == 0) {
+    3218           0 :             in[*n] = k;
+    3219             :         }
+    3220             :     }
+    3221           0 :     if (std::abs(a[*n]) <= scale1 * tl && in[*n] == 0) {
+    3222           0 :         in[*n] = *n;
+    3223             :     }
+    3224             : 
+    3225             :     return;
+    3226             : 
+    3227             : }
+    3228             : 
+    3229             : 
+    3230             : }
+    3231             : }
+    3232             : #include <stdlib.h>
+    3233             : #include <cmath>
+    3234             : #include "real.h"
+    3235             : 
+    3236             : #include "lapack.h"
+    3237             : #include "lapack_limits.h"
+    3238             : 
+    3239             : 
+    3240             : #include "blas/blas.h"
+    3241             : namespace PLMD{
+    3242             : namespace lapack{
+    3243             : using namespace blas;
+    3244             : void
+    3245           0 : PLUMED_BLAS_F77_FUNC(dlagts,DLAGTS)(int *job, 
+    3246             :         int *n, 
+    3247             :         double *a, 
+    3248             :         double *b, 
+    3249             :         double *c__, 
+    3250             :         double *d__, 
+    3251             :         int *in, 
+    3252             :         double *y, 
+    3253             :         double *tol, 
+    3254             :         int *info)
+    3255             : {
+    3256             :     int i__1;
+    3257             :     double d__1, d__2, d__4, d__5;
+    3258             : 
+    3259             :     int k;
+    3260             :     double ak, eps, temp, pert, absak, sfmin;
+    3261             :     double bignum,minval;
+    3262           0 :     --y;
+    3263           0 :     --in;
+    3264           0 :     --d__;
+    3265           0 :     --c__;
+    3266           0 :     --b;
+    3267           0 :     --a;
+    3268             : 
+    3269           0 :     *info = 0;
+    3270           0 :     if (abs(*job) > 2 || *job == 0) {
+    3271           0 :         *info = -1;
+    3272           0 :     } else if (*n < 0) {
+    3273           0 :         *info = -2;
+    3274             :     }
+    3275           0 :     if (*info != 0) {
+    3276             :         return;
+    3277             :     }
+    3278             : 
+    3279           0 :     if (*n == 0) {
+    3280             :         return;
+    3281             :     }
+    3282             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    3283             :     minval = PLUMED_GMX_DOUBLE_MIN;
+    3284             :     sfmin = minval / eps;
+    3285             : 
+    3286             :     bignum = 1. / sfmin;
+    3287             : 
+    3288           0 :     if (*job < 0) {
+    3289           0 :         if (*tol <= 0.) {
+    3290           0 :             *tol = std::abs(a[1]);
+    3291           0 :             if (*n > 1) {
+    3292             :                 d__1 = *tol;
+    3293           0 :                 d__2 = std::abs(a[2]);
+    3294           0 :                 d__1 = (d__1>d__2) ? d__1 : d__2;
+    3295           0 :                 d__2 = std::abs(b[1]);
+    3296           0 :                 *tol = (d__1>d__2) ? d__1 : d__2;
+    3297             :             }
+    3298           0 :             i__1 = *n;
+    3299           0 :             for (k = 3; k <= i__1; ++k) {
+    3300           0 :               d__4 = *tol;
+    3301           0 :               d__5 = std::abs(a[k]);
+    3302           0 :               d__4 = (d__4>d__5) ? d__4 : d__5;
+    3303           0 :               d__5 = std::abs(b[k - 1]);
+    3304           0 :               d__4 = (d__4>d__5) ? d__4 : d__5;
+    3305           0 :               d__5 = std::abs(d__[k - 2]);
+    3306           0 :               *tol = (d__4>d__5) ? d__4 : d__5;
+    3307             :             }
+    3308           0 :             *tol *= eps;
+    3309           0 :             if (std::abs(*tol)<PLUMED_GMX_DOUBLE_MIN) {
+    3310           0 :                 *tol = eps;
+    3311             :             }
+    3312             :         }
+    3313             :     }
+    3314             : 
+    3315           0 :     if (1 == abs(*job)) {
+    3316           0 :         i__1 = *n;
+    3317           0 :         for (k = 2; k <= i__1; ++k) {
+    3318           0 :             if (in[k - 1] == 0) {
+    3319           0 :                 y[k] -= c__[k - 1] * y[k - 1];
+    3320             :             } else {
+    3321           0 :                 temp = y[k - 1];
+    3322           0 :                 y[k - 1] = y[k];
+    3323           0 :                 y[k] = temp - c__[k - 1] * y[k];
+    3324             :             }
+    3325             :         }
+    3326           0 :         if (*job == 1) {
+    3327           0 :             for (k = *n; k >= 1; --k) {
+    3328           0 :                 if (k <= *n - 2) {
+    3329           0 :                     temp = y[k] - b[k] * y[k + 1] - d__[k] * y[k + 2];
+    3330           0 :                 } else if (k == *n - 1) {
+    3331           0 :                     temp = y[k] - b[k] * y[k + 1];
+    3332             :                 } else {
+    3333           0 :                     temp = y[k];
+    3334             :                 }
+    3335           0 :                 ak = a[k];
+    3336             :                 absak = std::abs(ak);
+    3337           0 :                 if (absak < 1.) {
+    3338           0 :                     if (absak < sfmin) {
+    3339           0 :                         if (std::abs(absak)<PLUMED_GMX_DOUBLE_MIN || std::abs(temp) * sfmin > absak) {
+    3340           0 :                             *info = k;
+    3341           0 :                             return;
+    3342             :                         } else {
+    3343           0 :                             temp *= bignum;
+    3344           0 :                             ak *= bignum;
+    3345             :                         }
+    3346           0 :                     } else if (std::abs(temp) > absak * bignum) {
+    3347           0 :                         *info = k;
+    3348           0 :                         return;
+    3349             :                     }
+    3350             :                 }
+    3351           0 :                 y[k] = temp / ak;
+    3352             :             }
+    3353             :         } else {
+    3354           0 :             for (k = *n; k >= 1; --k) {
+    3355           0 :                 if (k + 2 <= *n) {
+    3356           0 :                     temp = y[k] - b[k] * y[k + 1] - d__[k] * y[k + 2];
+    3357           0 :                 } else if (k + 1 == *n) {
+    3358           0 :                     temp = y[k] - b[k] * y[k + 1];
+    3359             :                 } else {
+    3360           0 :                     temp = y[k];
+    3361             :                 }
+    3362           0 :                 ak = a[k];
+    3363             : 
+    3364           0 :                 pert = *tol;
+    3365           0 :                 if(ak<0)
+    3366           0 :                   pert *= -1.0;
+    3367           0 : L40:
+    3368             :                 absak = std::abs(ak);
+    3369           0 :                 if (absak < 1.) {
+    3370           0 :                     if (absak < sfmin) {
+    3371           0 :                         if (std::abs(absak)<PLUMED_GMX_DOUBLE_MIN || std::abs(temp) * sfmin > absak) {
+    3372           0 :                             ak += pert;
+    3373           0 :                             pert *= 2;
+    3374           0 :                             goto L40;
+    3375             :                         } else {
+    3376           0 :                             temp *= bignum;
+    3377           0 :                             ak *= bignum;
+    3378             :                         }
+    3379           0 :                     } else if (std::abs(temp) > absak * bignum) {
+    3380           0 :                         ak += pert;
+    3381           0 :                         pert *= 2;
+    3382           0 :                         goto L40;
+    3383             :                     }
+    3384             :                 }
+    3385           0 :                 y[k] = temp / ak;
+    3386             :             }
+    3387             :         }
+    3388             :     } else {
+    3389             : 
+    3390           0 :         if (*job == 2) {
+    3391           0 :             i__1 = *n;
+    3392           0 :             for (k = 1; k <= i__1; ++k) {
+    3393           0 :                 if (k >= 3) {
+    3394           0 :                     temp = y[k] - b[k - 1] * y[k - 1] - d__[k - 2] * y[k - 2];
+    3395           0 :                 } else if (k == 2) {
+    3396           0 :                     temp = y[k] - b[k - 1] * y[k - 1];
+    3397             :                 } else {
+    3398           0 :                     temp = y[k];
+    3399             :                 }
+    3400           0 :                 ak = a[k];
+    3401             :                 absak = std::abs(ak);
+    3402           0 :                 if (absak < 1.) {
+    3403           0 :                     if (absak < sfmin) {
+    3404           0 :                         if (std::abs(absak)<PLUMED_GMX_DOUBLE_MIN || std::abs(temp) * sfmin > absak) {
+    3405           0 :                             *info = k;
+    3406           0 :                             return;
+    3407             :                         } else {
+    3408           0 :                             temp *= bignum;
+    3409           0 :                             ak *= bignum;
+    3410             :                         }
+    3411           0 :                     } else if (std::abs(temp) > absak * bignum) {
+    3412           0 :                         *info = k;
+    3413           0 :                         return;
+    3414             :                     }
+    3415             :                 }
+    3416           0 :                 y[k] = temp / ak;
+    3417             :             }
+    3418             :         } else {
+    3419           0 :             i__1 = *n;
+    3420           0 :             for (k = 1; k <= i__1; ++k) {
+    3421           0 :                 if (k >= 3) {
+    3422           0 :                     temp = y[k] - b[k - 1] * y[k - 1] - d__[k - 2] * y[k - 2];
+    3423           0 :                 } else if (k == 2) {
+    3424           0 :                     temp = y[k] - b[k - 1] * y[k - 1];
+    3425             :                 } else {
+    3426           0 :                     temp = y[k];
+    3427             :                 }
+    3428           0 :                 ak = a[k];
+    3429             : 
+    3430           0 :                 pert = *tol;
+    3431           0 :                 if(ak<0)
+    3432           0 :                   pert *= -1.0;
+    3433             : 
+    3434           0 : L70:
+    3435             :                 absak = std::abs(ak);
+    3436           0 :                 if (absak < 1.) {
+    3437           0 :                     if (absak < sfmin) {
+    3438           0 :                         if (std::abs(absak)<PLUMED_GMX_DOUBLE_MIN || std::abs(temp) * sfmin > absak) {
+    3439           0 :                             ak += pert;
+    3440           0 :                             pert *= 2;
+    3441           0 :                             goto L70;
+    3442             :                         } else {
+    3443           0 :                             temp *= bignum;
+    3444           0 :                             ak *= bignum;
+    3445             :                         }
+    3446           0 :                     } else if (std::abs(temp) > absak * bignum) {
+    3447           0 :                         ak += pert;
+    3448           0 :                         pert *= 2;
+    3449           0 :                         goto L70;
+    3450             :                     }
+    3451             :                 }
+    3452           0 :                 y[k] = temp / ak;
+    3453             :             }
+    3454             :         }
+    3455             : 
+    3456           0 :         for (k = *n; k >= 2; --k) {
+    3457           0 :             if (in[k - 1] == 0) {
+    3458           0 :                 y[k - 1] -= c__[k - 1] * y[k];
+    3459             :             } else {
+    3460           0 :                 temp = y[k - 1];
+    3461           0 :                 y[k - 1] = y[k];
+    3462           0 :                 y[k] = temp - c__[k - 1] * y[k];
+    3463             :             }
+    3464             :         }
+    3465             :     }
+    3466             : 
+    3467             :     return;
+    3468             : }
+    3469             : 
+    3470             : 
+    3471             : }
+    3472             : }
+    3473             : #include "lapack.h"
+    3474             : 
+    3475             : 
+    3476             : /* LAPACK */
+    3477             : 
+    3478             : 
+    3479             : #include "blas/blas.h"
+    3480             : namespace PLMD{
+    3481             : namespace lapack{
+    3482             : using namespace blas;
+    3483             : void
+    3484         118 : PLUMED_BLAS_F77_FUNC(dlamrg,DLAMRG)(int *n1,
+    3485             :                         int *n2,
+    3486             :                         double *a,
+    3487             :                         int *dtrd1,
+    3488             :                         int *dtrd2,
+    3489             :                         int *index)
+    3490             : {
+    3491         118 :   int n1sv = *n1;
+    3492         118 :   int n2sv = *n2;
+    3493             :   int i,ind1,ind2;
+    3494             : 
+    3495         118 :   if(*dtrd1>0)
+    3496             :     ind1 = 0;
+    3497             :   else
+    3498           0 :     ind1 = *n1-1;
+    3499             : 
+    3500         118 :   if(*dtrd2>0)
+    3501             :     ind2 = *n1;
+    3502             :   else
+    3503          59 :     ind2 = *n1+*n2-1;
+    3504             : 
+    3505             :   i = 0;
+    3506             :   
+    3507        4270 :   while(n1sv>0 && n2sv>0) {
+    3508        4152 :     if(a[ind1]<=a[ind2]) {
+    3509        2476 :       index[i] = ind1 + 1;
+    3510        2476 :       i++;
+    3511        2476 :       ind1 += *dtrd1;
+    3512        2476 :       n1sv--;
+    3513             :     } else {
+    3514        1676 :       index[i] = ind2 + 1;
+    3515        1676 :       i++;
+    3516        1676 :       ind2 += *dtrd2;
+    3517        1676 :       n2sv--;
+    3518             :     }
+    3519             :   }
+    3520             : 
+    3521         118 :   if(n1sv==0) {
+    3522         126 :     for(n1sv=1;n1sv<=n2sv;n1sv++) {
+    3523         120 :       index[i] = ind2 + 1;
+    3524         120 :       i++;
+    3525         120 :       ind2 += *dtrd2;
+    3526             :     } 
+    3527             :   } else {
+    3528        2567 :     for(n2sv=1;n2sv<=n1sv;n2sv++) {
+    3529        2455 :       index[i] = ind1 + 1;
+    3530        2455 :       i++;
+    3531        2455 :       ind1 += *dtrd1;
+    3532             :     } 
+    3533             :   }
+    3534         118 :   return;
+    3535             : }
+    3536             : }
+    3537             : }
+    3538             : #include <cctype>
+    3539             : #include <cmath>
+    3540             : #include "lapack.h"
+    3541             : 
+    3542             : 
+    3543             : #include "blas/blas.h"
+    3544             : namespace PLMD{
+    3545             : namespace lapack{
+    3546             : using namespace blas;
+    3547             : double
+    3548          96 : PLUMED_BLAS_F77_FUNC(dlange,DLANGE)(const char *norm,
+    3549             :         int *m,
+    3550             :         int *n,
+    3551             :         double *a,
+    3552             :         int *lda,
+    3553             :         double *work)
+    3554             : {
+    3555          96 :   const char ch=std::toupper(*norm);
+    3556             :   double dtemp,sum,max,val,scale;
+    3557             :   int i,j;
+    3558             : 
+    3559          96 :   switch(ch) {
+    3560             :   case 'M':
+    3561             :     max = 0.0;
+    3562        2640 :     for(j=0;j<*n;j++)
+    3563      304276 :       for(i=0;i<*m;i++) {
+    3564      301732 :         dtemp = std::abs(a[j*(*lda)+i]);
+    3565      301732 :         if(dtemp>max)
+    3566             :           max = dtemp;
+    3567             :       }
+    3568             :     val = max;
+    3569             :     break;
+    3570             : 
+    3571             :   case 'O':
+    3572             :   case '1':
+    3573             :     max = 0.0;
+    3574           0 :     for(j=0;j<*n;j++) {
+    3575           0 :       sum = 0.0;
+    3576           0 :       for(i=0;i<*m;i++) 
+    3577           0 :         sum += std::abs(a[j*(*lda)+i]);
+    3578           0 :       if(sum>max)
+    3579             :         max = sum;
+    3580             :     }
+    3581             :     val = max;
+    3582             :     break;
+    3583             : 
+    3584           0 :   case 'I':
+    3585           0 :     for(i=0;i<*m;i++)
+    3586           0 :       work[i] = 0.0;
+    3587           0 :     for(j=0;j<*n;j++)
+    3588           0 :       for(i=0;i<*m;i++)
+    3589           0 :         work[i] += std::abs(a[j*(*lda)+i]);
+    3590             :     max = 0;
+    3591           0 :     for(i=0;i<*m;i++)
+    3592           0 :       if(work[i]>max)
+    3593             :         max=work[i];
+    3594             :     val = max;
+    3595             :     break;
+    3596             : 
+    3597           0 :   case 'F':
+    3598             :   case 'E':
+    3599           0 :     scale = 0.0;
+    3600           0 :     sum   = 1.0;
+    3601           0 :     i = 1;
+    3602           0 :     for(j=0;j<*n;j++) 
+    3603           0 :       PLUMED_BLAS_F77_FUNC(dlassq,DLASSQ)(m,&(a[j*(*lda)+0]),&i,&scale,&sum);
+    3604           0 :     val = scale* std::sqrt(sum);
+    3605           0 :     break;
+    3606             : 
+    3607             :   default:
+    3608             :     val = 0.0;
+    3609             :     break;
+    3610             :   }
+    3611          96 :   return val;
+    3612             : }
+    3613             : }
+    3614             : }
+    3615             : #include <cctype>
+    3616             : #include <cmath>
+    3617             : #include "lapack.h"
+    3618             : 
+    3619             : 
+    3620             : #include "blas/blas.h"
+    3621             : namespace PLMD{
+    3622             : namespace lapack{
+    3623             : using namespace blas;
+    3624             : double
+    3625      570034 : PLUMED_BLAS_F77_FUNC(dlanst,DLANST)(const char *norm,
+    3626             :         int *n,
+    3627             :         double *d,
+    3628             :         double *e)
+    3629             : {
+    3630      570034 :   const char ch=std::toupper(*norm);
+    3631             :   double dtemp,max,val,scale,sum;
+    3632             :   int i,j;
+    3633             : 
+    3634             : 
+    3635      570034 :   if(*n<=0)
+    3636             :     return 0.0;
+    3637             :   
+    3638      570034 :   switch(ch) {
+    3639      570034 :   case 'M':
+    3640      570034 :     max = std::abs(d[*n-1]);
+    3641     2255841 :       for(i=0;i<(*n-1);i++) {
+    3642     1685807 :         dtemp = std::abs(d[i]);
+    3643     1685807 :         if(dtemp>max)
+    3644             :           max = dtemp;
+    3645     1685807 :         dtemp = std::abs(e[i]);
+    3646     1685807 :         if(dtemp>max)
+    3647             :           max = dtemp;
+    3648             :       }
+    3649             :     val = max;
+    3650             :     break;
+    3651             :     
+    3652           0 :   case 'O':
+    3653             :   case '1':
+    3654             :   case 'I':
+    3655             : 
+    3656           0 :     if(*n==1)
+    3657           0 :       val = std::abs(d[0]);
+    3658             :     else {
+    3659           0 :       max = std::abs(d[0]) + std::abs(e[0]);
+    3660           0 :       dtemp = std::abs(e[*n-2]) + std::abs(d[*n-1]);
+    3661           0 :       if(dtemp>max)
+    3662             :         max = dtemp;
+    3663           0 :       for(i=1;i<(*n-1);i++) {
+    3664           0 :         dtemp = std::abs(d[i]) + std::abs(e[i]) + std::abs(e[i-1]);
+    3665           0 :         if(dtemp>max)
+    3666             :           max = dtemp;
+    3667             :       }
+    3668             :       val = max;
+    3669             :     }
+    3670             :     break;
+    3671             : 
+    3672           0 :   case 'F':
+    3673             :   case 'E':
+    3674           0 :     scale = 0.0;
+    3675           0 :     sum   = 1.0;
+    3676           0 :     i = *n-1;
+    3677           0 :     j = 1;
+    3678           0 :     if(*n>1) {
+    3679           0 :       PLUMED_BLAS_F77_FUNC(dlassq,DLASSQ)(&i,e,&j,&scale,&sum);
+    3680           0 :       sum *= 2;
+    3681             :     }
+    3682           0 :     PLUMED_BLAS_F77_FUNC(dlassq,DLASSQ)(n,d,&j,&scale,&sum);
+    3683           0 :     val = scale *  std::sqrt(sum);
+    3684           0 :     break;
+    3685             :     
+    3686             :   default:
+    3687             :     val = 0.0;
+    3688             :     break;
+    3689             :   }
+    3690             :   return val;
+    3691             : }
+    3692             : }
+    3693             : }
+    3694             : #include <cmath>
+    3695             : 
+    3696             : 
+    3697             : #include "lapack.h"
+    3698             : 
+    3699             : #include "blas/blas.h"
+    3700             : namespace PLMD{
+    3701             : namespace lapack{
+    3702             : using namespace blas;
+    3703             : double 
+    3704      570005 : PLUMED_BLAS_F77_FUNC(dlansy,DLANSY)(const char *norm, const char *uplo, int *n, double *a, int 
+    3705             :         *lda, double *work)
+    3706             : {
+    3707             :     /* System generated locals */
+    3708             :     int a_dim1, a_offset, i__1, i__2;
+    3709             :     double ret_val, d__1, d__2, d__3;
+    3710      570005 :     int c__1 = 1;
+    3711             : 
+    3712             :     /* Local variables */
+    3713             :     int i__, j;
+    3714             :     double sum, absa, scale;
+    3715             :     double value =0.0;
+    3716             : 
+    3717      570005 :     a_dim1 = *lda;
+    3718      570005 :     a_offset = 1 + a_dim1;
+    3719      570005 :     a -= a_offset;
+    3720      570005 :     --work;
+    3721             : 
+    3722      570005 :     if (*n == 0) {
+    3723             :         value = 0.;
+    3724      570005 :     } else if (*norm=='M' || *norm=='m') {
+    3725             : 
+    3726             :         value = 0.;
+    3727      570005 :         if (*uplo=='U' || *uplo=='u') {
+    3728      570005 :             i__1 = *n;
+    3729     2824422 :             for (j = 1; j <= i__1; ++j) {
+    3730             :                 i__2 = j;
+    3731     8056693 :                 for (i__ = 1; i__ <= i__2; ++i__) {
+    3732             :                   d__2 = value;
+    3733     5802276 :                   d__3 = std::abs(a[i__ + j * a_dim1]);
+    3734     5802276 :                   value = (d__2>d__3) ? d__2 : d__3;
+    3735             :                 }
+    3736             :             }
+    3737             :         } else {
+    3738           0 :             i__1 = *n;
+    3739           0 :             for (j = 1; j <= i__1; ++j) {
+    3740             :                 i__2 = *n;
+    3741           0 :                 for (i__ = j; i__ <= i__2; ++i__) {
+    3742             :                   d__2 = value;
+    3743           0 :                   d__3 = std::abs(a[i__ + j * a_dim1]);
+    3744           0 :                     value =  (d__2>d__3) ? d__2 : d__3;
+    3745             :                 }
+    3746             :             }
+    3747             :         }
+    3748           0 :     } else if (*norm=='I' || *norm=='i' || *norm=='O' || *norm=='o' || *norm=='1') {
+    3749             : 
+    3750             :         value = 0.;
+    3751           0 :         if (*uplo=='U' || *uplo=='u') {
+    3752           0 :             i__1 = *n;
+    3753           0 :             for (j = 1; j <= i__1; ++j) {
+    3754           0 :                 sum = 0.;
+    3755           0 :                 i__2 = j - 1;
+    3756           0 :                 for (i__ = 1; i__ <= i__2; ++i__) {
+    3757           0 :                     absa = std::abs(a[i__ + j * a_dim1]);
+    3758           0 :                     sum += absa;
+    3759           0 :                     work[i__] += absa;
+    3760             :                 }
+    3761           0 :                 work[j] = sum + std::abs(a[j + j * a_dim1]);
+    3762             :             }
+    3763           0 :             i__1 = *n;
+    3764           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    3765           0 :                 d__1 = value, d__2 = work[i__];
+    3766           0 :                 value =  (d__1>d__2) ? d__1 : d__2;
+    3767             :             }
+    3768             :         } else {
+    3769             :             i__1 = *n;
+    3770           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    3771           0 :                 work[i__] = 0.;
+    3772             :             }
+    3773           0 :             i__1 = *n;
+    3774           0 :             for (j = 1; j <= i__1; ++j) {
+    3775           0 :                 sum = work[j] + std::abs(a[j + j * a_dim1]);
+    3776           0 :                 i__2 = *n;
+    3777           0 :                 for (i__ = j + 1; i__ <= i__2; ++i__) {
+    3778           0 :                     absa = std::abs(a[i__ + j * a_dim1]);
+    3779           0 :                     sum += absa;
+    3780           0 :                     work[i__] += absa;
+    3781             :                 }
+    3782           0 :                 if(sum>value)
+    3783             :                   value = sum;
+    3784             :             }
+    3785             :         }
+    3786             :     } else if (*norm=='F' || *norm=='f' || *norm=='E' || *norm=='e') {
+    3787             : 
+    3788           0 :         scale = 0.;
+    3789           0 :         sum = 1.;
+    3790           0 :         if (*uplo=='U' || *uplo=='u') {
+    3791           0 :             i__1 = *n;
+    3792           0 :             for (j = 2; j <= i__1; ++j) {
+    3793           0 :                 i__2 = j - 1;
+    3794           0 :                 PLUMED_BLAS_F77_FUNC(dlassq,DLASSQ)(&i__2, &a[j * a_dim1 + 1], &c__1, &scale, &sum);
+    3795             :             }
+    3796             :         } else {
+    3797           0 :             i__1 = *n - 1;
+    3798           0 :             for (j = 1; j <= i__1; ++j) {
+    3799           0 :                 i__2 = *n - j;
+    3800           0 :                 PLUMED_BLAS_F77_FUNC(dlassq,DLASSQ)(&i__2, &a[j + 1 + j * a_dim1], &c__1, &scale, &sum);
+    3801             :             }
+    3802             :         }
+    3803           0 :         sum *= 2;
+    3804           0 :         i__1 = *lda + 1;
+    3805           0 :         PLUMED_BLAS_F77_FUNC(dlassq,DLASSQ)(n, &a[a_offset], &i__1, &scale, &sum);
+    3806           0 :         value = scale *  std::sqrt(sum);
+    3807             :     }
+    3808             : 
+    3809             :     ret_val = value;
+    3810      570005 :     return ret_val;
+    3811             : }
+    3812             : 
+    3813             : 
+    3814             : }
+    3815             : }
+    3816             : #include <cmath>
+    3817             : #include "lapack.h"
+    3818             : 
+    3819             : #include "real.h"
+    3820             : 
+    3821             : #include "blas/blas.h"
+    3822             : namespace PLMD{
+    3823             : namespace lapack{
+    3824             : using namespace blas;
+    3825             : double
+    3826     1119235 : PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(double * x, double * y)
+    3827             : {
+    3828             :   double xabs,yabs;
+    3829             :   double w,z;
+    3830             : 
+    3831     1119235 :   xabs = std::abs(*x);
+    3832     1119235 :   yabs = std::abs(*y);
+    3833             :   
+    3834     1119235 :   if(xabs>yabs) {
+    3835             :     w = xabs;
+    3836             :     z = yabs;
+    3837             :   } else {
+    3838             :     w = yabs;
+    3839             :     z = xabs;
+    3840             :   }
+    3841             : 
+    3842     1119235 :   if( std::abs(z)<PLUMED_GMX_DOUBLE_MIN) 
+    3843             :     return w;
+    3844             :   else {
+    3845     1119235 :     z = z/w;
+    3846     1119235 :     return w* std::sqrt(1.0+z*z);
+    3847             :   }
+    3848             : }
+    3849             :   
+    3850             : }
+    3851             : }
+    3852             : #include <cmath>
+    3853             : 
+    3854             : #include "real.h"
+    3855             : 
+    3856             : #include "lapack.h"
+    3857             : #include "lapack_limits.h"
+    3858             : #include "blas/blas.h"
+    3859             : namespace PLMD{
+    3860             : namespace lapack{
+    3861             : using namespace blas;
+    3862             : 
+    3863      608131 : void PLUMED_BLAS_F77_FUNC(dlar1vx,DLAR1VX)(int *n, 
+    3864             :               int *b1, 
+    3865             :               int *bn,
+    3866             :               double *sigma, 
+    3867             :               double *d__, 
+    3868             :               double *l, 
+    3869             :               double *ld, 
+    3870             :               double *lld, 
+    3871             :               double *eval, 
+    3872             :               double *gersch, 
+    3873             :               double *z__, 
+    3874             :               double *ztz, 
+    3875             :               double *mingma, 
+    3876             :               int *r__, 
+    3877             :               int *isuppz, 
+    3878             :               double *work)
+    3879             : {
+    3880             :     int i__1;
+    3881             : 
+    3882             :     int i__, j;
+    3883             :     double s;
+    3884             :     int r1, r2;
+    3885             :     int to;
+    3886             :     double eps, tmp;
+    3887             :     int indp, inds, from;
+    3888             :     double dplus;
+    3889             :     int sawnan;
+    3890             :     int indumn;
+    3891             :     double dminus;
+    3892             : 
+    3893      608131 :     --work;
+    3894             :     --isuppz;
+    3895      608131 :     --z__;
+    3896      608131 :     --gersch;
+    3897      608131 :     --lld;
+    3898      608131 :     --ld;
+    3899      608131 :     --l;
+    3900      608131 :     --d__;
+    3901             : 
+    3902             :     /* Function Body */
+    3903             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    3904      608131 :     if (*r__ == 0) {
+    3905             : 
+    3906      606860 :         r1 = *b1;
+    3907      606860 :         r2 = *bn;
+    3908             :         i__1 = *bn;
+    3909     1399099 :         for (i__ = *b1; i__ <= i__1; ++i__) {
+    3910     1399099 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+    3911             :                 r1 = i__;
+    3912      606860 :                 goto L20;
+    3913             :             }
+    3914             :         }
+    3915           0 :         goto L40;
+    3916             : L20:
+    3917             :         i__1 = *b1;
+    3918     1557127 :         for (i__ = *bn; i__ >= i__1; --i__) {
+    3919     1557127 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+    3920             :                 r2 = i__;
+    3921      606860 :                 goto L40;
+    3922             :             }
+    3923             :         }
+    3924             :     } else {
+    3925             :         r1 = *r__;
+    3926             :         r2 = *r__;
+    3927             :     }
+    3928             : 
+    3929      608131 : L40:
+    3930      608131 :     indumn = *n;
+    3931      608131 :     inds = (*n << 1) + 1;
+    3932      608131 :     indp = *n * 3 + 1;
+    3933             :     sawnan = 0;
+    3934             : 
+    3935      608131 :     if (*b1 == 1) {
+    3936      608131 :         work[inds] = 0.;
+    3937             :     } else {
+    3938           0 :         work[inds] = lld[*b1 - 1];
+    3939             :     }
+    3940      608131 :     s = work[inds] - *sigma;
+    3941             :     i__1 = r2 - 1;
+    3942     1842499 :     for (i__ = *b1; i__ <= i__1; ++i__) {
+    3943     1234368 :         dplus = d__[i__] + s;
+    3944     1234368 :         work[i__] = ld[i__] / dplus;
+    3945     1234368 :         work[inds + i__] = s * work[i__] * l[i__];
+    3946     1234368 :         s = work[inds + i__] - *sigma;
+    3947             :     }
+    3948             : 
+    3949      608131 :     if (std::isnan(s)) {
+    3950             : 
+    3951             :         sawnan = 1;
+    3952           0 :         j = *b1 + 1;
+    3953           0 : L60:
+    3954           0 :     if (!std::isnan(work[inds + j])) {
+    3955           0 :             ++j;
+    3956           0 :             goto L60;
+    3957             :         }
+    3958           0 :         work[inds + j] = lld[j];
+    3959           0 :         s = work[inds + j] - *sigma;
+    3960             :         i__1 = r2 - 1;
+    3961           0 :         for (i__ = j + 1; i__ <= i__1; ++i__) {
+    3962           0 :             dplus = d__[i__] + s;
+    3963           0 :             work[i__] = ld[i__] / dplus;
+    3964           0 :             if (std::abs(work[i__])<PLUMED_GMX_DOUBLE_MIN) {
+    3965           0 :                 work[inds + i__] = lld[i__];
+    3966             :             } else {
+    3967           0 :                 work[inds + i__] = s * work[i__] * l[i__];
+    3968             :             }
+    3969           0 :             s = work[inds + i__] - *sigma;
+    3970             :         }
+    3971             :     }
+    3972             : 
+    3973      608131 :     work[indp + *bn - 1] = d__[*bn] - *sigma;
+    3974             :     i__1 = r1;
+    3975     2110756 :     for (i__ = *bn - 1; i__ >= i__1; --i__) {
+    3976     1502625 :         dminus = lld[i__] + work[indp + i__];
+    3977     1502625 :         tmp = d__[i__] / dminus;
+    3978     1502625 :         work[indumn + i__] = l[i__] * tmp;
+    3979     1502625 :         work[indp + i__ - 1] = work[indp + i__] * tmp - *sigma;
+    3980             :     }
+    3981      608131 :     tmp = work[indp + r1 - 1];
+    3982      608131 :     if (std::isnan(tmp)) {
+    3983             : 
+    3984             :         sawnan = 1;
+    3985           0 :         j = *bn - 3;
+    3986           0 : L90:
+    3987           0 :     if (!std::isnan(work[indp + j])) {
+    3988           0 :             --j;
+    3989           0 :             goto L90;
+    3990             :         }
+    3991           0 :         work[indp + j] = d__[j + 1] - *sigma;
+    3992             :         i__1 = r1;
+    3993           0 :         for (i__ = j; i__ >= i__1; --i__) {
+    3994           0 :             dminus = lld[i__] + work[indp + i__];
+    3995           0 :             tmp = d__[i__] / dminus;
+    3996           0 :             work[indumn + i__] = l[i__] * tmp;
+    3997           0 :             if (std::abs(tmp)<PLUMED_GMX_DOUBLE_MIN) {
+    3998           0 :                 work[indp + i__ - 1] = d__[i__] - *sigma;
+    3999             :             } else {
+    4000           0 :                 work[indp + i__ - 1] = work[indp + i__] * tmp - *sigma;
+    4001             :             }
+    4002             :         }
+    4003             :     }
+    4004             : 
+    4005      608131 :     *mingma = work[inds + r1 - 1] + work[indp + r1 - 1];
+    4006      608131 :     if (std::abs(*mingma)<PLUMED_GMX_DOUBLE_MIN) {
+    4007       45757 :         *mingma = eps * work[inds + r1 - 1];
+    4008             :     }
+    4009      608131 :     *r__ = r1;
+    4010             :     i__1 = r2 - 1;
+    4011      956196 :     for (i__ = r1; i__ <= i__1; ++i__) {
+    4012      348065 :         tmp = work[inds + i__] + work[indp + i__];
+    4013      348065 :         if (std::abs(tmp)<PLUMED_GMX_DOUBLE_MIN) {
+    4014       23354 :             tmp = eps * work[inds + i__];
+    4015             :         }
+    4016      348065 :         if (std::abs(tmp) < std::abs(*mingma)) {
+    4017       50704 :             *mingma = tmp;
+    4018       50704 :             *r__ = i__ + 1;
+    4019             :         }
+    4020             :     }
+    4021             : 
+    4022      608131 :     isuppz[1] = *b1;
+    4023      608131 :     isuppz[2] = *bn;
+    4024      608131 :     z__[*r__] = 1.;
+    4025      608131 :     *ztz = 1.;
+    4026      608131 :     if (! sawnan) {
+    4027      608131 :         from = *r__ - 1;
+    4028      608131 :         i__1 = *r__ - 32;
+    4029      608131 :         to = (i__1>(*b1)) ? i__1 : (*b1);
+    4030             : L120:
+    4031     1148725 :         if (from >= *b1) {
+    4032             :             i__1 = to;
+    4033     1355277 :             for (i__ = from; i__ >= i__1; --i__) {
+    4034      813471 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+    4035      813471 :                 *ztz += z__[i__] * z__[i__];
+    4036             :             }
+    4037      541806 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to + 1]) <= eps) {
+    4038        1212 :                 isuppz[1] = to + 2;
+    4039             :             } else {
+    4040      540594 :                 from = to - 1;
+    4041      540594 :                 i__1 = to - 32;
+    4042      540594 :                 to = (i__1>*b1) ? i__1 : *b1;
+    4043      540594 :                 goto L120;
+    4044             :             }
+    4045             :         }
+    4046      608131 :         from = *r__ + 1;
+    4047      608131 :         i__1 = *r__ + 32;
+    4048      608131 :         to = (i__1<*bn) ? i__1 : *bn;
+    4049             : L140:
+    4050     1192340 :         if (from <= *bn) {
+    4051             :             i__1 = to;
+    4052     2016511 :             for (i__ = from; i__ <= i__1; ++i__) {
+    4053     1432296 :                 z__[i__] = -(work[indumn + i__ - 1] * z__[i__ - 1]);
+    4054     1432296 :                 *ztz += z__[i__] * z__[i__];
+    4055             :             }
+    4056      584215 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to - 1]) <= eps) {
+    4057           6 :                 isuppz[2] = to - 2;
+    4058             :             } else {
+    4059      584209 :                 from = to + 1;
+    4060      584209 :                 i__1 = to + 32;
+    4061      584209 :                 to = (i__1<*bn) ? i__1 : *bn;
+    4062      584209 :                 goto L140;
+    4063             :             }
+    4064             :         }
+    4065             :     } else {
+    4066           0 :         i__1 = *b1;
+    4067           0 :         for (i__ = *r__ - 1; i__ >= i__1; --i__) {
+    4068           0 :             if (std::abs(z__[i__ + 1])<PLUMED_GMX_DOUBLE_MIN) {
+    4069           0 :                 z__[i__] = -(ld[i__ + 1] / ld[i__]) * z__[i__ + 2];
+    4070             :             } else {
+    4071           0 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+    4072             :             }
+    4073           0 :             if (std::abs(z__[i__]) <= eps && std::abs(z__[i__ + 1]) <= eps) {
+    4074           0 :                 isuppz[1] = i__ + 2;
+    4075           0 :                 goto L170;
+    4076             :             }
+    4077           0 :             *ztz += z__[i__] * z__[i__];
+    4078             :         }
+    4079           0 : L170:
+    4080           0 :         i__1 = *bn - 1;
+    4081           0 :         for (i__ = *r__; i__ <= i__1; ++i__) {
+    4082           0 :             if (std::abs(z__[i__])<PLUMED_GMX_DOUBLE_MIN) {
+    4083           0 :                 z__[i__ + 1] = -(ld[i__ - 1] / ld[i__]) * z__[i__ - 1];
+    4084             :             } else {
+    4085           0 :                 z__[i__ + 1] = -(work[indumn + i__] * z__[i__]);
+    4086             :             }
+    4087           0 :             if (std::abs(z__[i__]) <= eps && std::abs(z__[i__ + 1]) <= eps) {
+    4088           0 :                 isuppz[2] = i__ - 1;
+    4089           0 :                 break;
+    4090             :             }
+    4091           0 :             *ztz += z__[i__ + 1] * z__[i__ + 1];
+    4092             :         }
+    4093             :     }
+    4094             : 
+    4095      608131 :     return;
+    4096             : 
+    4097             : }
+    4098             : 
+    4099             : 
+    4100             : }
+    4101             : }
+    4102             : #include <cctype>
+    4103             : #include <cmath>
+    4104             : 
+    4105             : #include "blas/blas.h"
+    4106             : #include "lapack.h"
+    4107             : 
+    4108             : #include "real.h"
+    4109             : 
+    4110             : #include "blas/blas.h"
+    4111             : namespace PLMD{
+    4112             : namespace lapack{
+    4113             : using namespace blas;
+    4114             : void
+    4115     1689932 : PLUMED_BLAS_F77_FUNC(dlarf,DLARF)(const char *side,
+    4116             :        int *m,
+    4117             :        int *n,
+    4118             :        double *v,
+    4119             :        int *incv,
+    4120             :        double *tau,
+    4121             :        double *c,
+    4122             :        int *ldc,
+    4123             :        double *work)
+    4124             : {
+    4125     1689932 :   const char ch=std::toupper(*side);
+    4126     1689932 :   double one = 1.0;
+    4127     1689932 :   double zero = 0.0;
+    4128     1689932 :   double minustau = -(*tau);
+    4129     1689932 :   int i1 = 1;
+    4130             : 
+    4131             : 
+    4132     1689932 :   if(ch=='L') {
+    4133     1686351 :     if(std::abs(*tau)>PLUMED_GMX_DOUBLE_MIN) {
+    4134     1116225 :       PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("T",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+    4135     1116225 :       PLUMED_BLAS_F77_FUNC(dger,DGER)(m,n,&minustau,v,incv,work,&i1,c,ldc);
+    4136             :     }
+    4137             :   } else {
+    4138        3581 :     if(std::abs(*tau)>PLUMED_GMX_DOUBLE_MIN) {
+    4139        3402 :       PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("N",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+    4140        3402 :       PLUMED_BLAS_F77_FUNC(dger,DGER)(m,n,&minustau,work,&i1,v,incv,c,ldc);
+    4141             :     }
+    4142             :   }
+    4143     1689932 :   return;
+    4144             : }
+    4145             : }
+    4146             : }
+    4147             : #include "blas/blas.h"
+    4148             : #include "lapack.h"
+    4149             : 
+    4150             : 
+    4151             : #include "blas/blas.h"
+    4152             : namespace PLMD{
+    4153             : namespace lapack{
+    4154             : using namespace blas;
+    4155             : void 
+    4156         147 : PLUMED_BLAS_F77_FUNC(dlarfb,DLARFB)(const char *side, 
+    4157             :         const char *trans, 
+    4158             :         const char *direct, 
+    4159             :         const char *storev, 
+    4160             :         int *m, 
+    4161             :         int *n, 
+    4162             :         int *k, 
+    4163             :         double *v, 
+    4164             :         int *ldv, 
+    4165             :         double *t, 
+    4166             :         int *ldt, 
+    4167             :         double *c__,
+    4168             :         int *ldc, 
+    4169             :         double *work, 
+    4170             :         int *ldwork)
+    4171             : {
+    4172             :     int c_dim1, c_offset, t_dim1, t_offset, v_dim1, v_offset, work_dim1, 
+    4173             :             work_offset, i__1, i__2;
+    4174             : 
+    4175             :     int i__, j;
+    4176             :     char transt[1];
+    4177         147 :     int c__1 = 1;
+    4178         147 :     double one = 1.0;
+    4179         147 :     double minusone = -1.0;
+    4180             : 
+    4181         147 :     v_dim1 = *ldv;
+    4182         147 :     v_offset = 1 + v_dim1;
+    4183         147 :     v -= v_offset;
+    4184             :     t_dim1 = *ldt;
+    4185             :     t_offset = 1 + t_dim1;
+    4186             :     t -= t_offset;
+    4187         147 :     c_dim1 = *ldc;
+    4188         147 :     c_offset = 1 + c_dim1;
+    4189         147 :     c__ -= c_offset;
+    4190         147 :     work_dim1 = *ldwork;
+    4191         147 :     work_offset = 1 + work_dim1;
+    4192         147 :     work -= work_offset;
+    4193             : 
+    4194         147 :     if (*m <= 0 || *n <= 0) {
+    4195             :         return;
+    4196             :     }
+    4197         147 :     if (*trans=='N' || *trans=='n') {
+    4198         107 :       *(unsigned char *)transt = 'T';
+    4199             :     } else {
+    4200          40 :         *(unsigned char *)transt = 'N';
+    4201             :     }
+    4202             :     
+    4203         147 :     if (*storev=='C' || *storev=='c') {
+    4204             : 
+    4205         107 :         if (*direct=='F' || *direct=='f') {
+    4206          48 :           if (*side=='l' || *side=='L') {
+    4207             : 
+    4208          48 :                 i__1 = *k;
+    4209        1124 :                 for (j = 1; j <= i__1; ++j) {
+    4210        1076 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &c__[j + c_dim1], ldc, &work[j * work_dim1 + 1],
+    4211             :                              &c__1);
+    4212             :                 }
+    4213             : 
+    4214          48 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", "No transpose", "Unit", n, k, &one,
+    4215             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+    4216          48 :                 if (*m > *k) {
+    4217             : 
+    4218          31 :                     i__1 = *m - *k;
+    4219          31 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("Transpose", "No transpose", n, k, &i__1, &one, &
+    4220          31 :                             c__[*k + 1 + c_dim1], ldc, &v[*k + 1 + v_dim1], 
+    4221             :                             ldv, &one, &work[work_offset], ldwork);
+    4222             :                 }
+    4223             : 
+    4224          48 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", transt, "Non-unit", n, k, &one, &t[
+    4225             :                         t_offset], ldt, &work[work_offset], ldwork);
+    4226             : 
+    4227          48 :                 if (*m > *k) {
+    4228          31 :                     i__1 = *m - *k;
+    4229          31 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose", "Transpose", &i__1, n, k, &minusone, &
+    4230          31 :                             v[*k + 1 + v_dim1], ldv, &work[work_offset], 
+    4231          31 :                             ldwork, &one, &c__[*k + 1 + c_dim1], ldc);
+    4232             :                 }
+    4233             : 
+    4234          48 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", "Transpose", "Unit", n, k, &one, &
+    4235             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+    4236             : 
+    4237          48 :                 i__1 = *k;
+    4238        1124 :                 for (j = 1; j <= i__1; ++j) {
+    4239        1076 :                     i__2 = *n;
+    4240      271892 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    4241      270816 :                         c__[j + i__ * c_dim1] -= work[i__ + j * work_dim1];
+    4242             :                     }
+    4243             :                 }
+    4244             : 
+    4245           0 :             } else if (*side=='r' || *side=='R') {
+    4246             : 
+    4247           0 :                 i__1 = *k;
+    4248           0 :                 for (j = 1; j <= i__1; ++j) {
+    4249           0 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(m, &c__[j * c_dim1 + 1], &c__1, &work[j * 
+    4250           0 :                             work_dim1 + 1], &c__1);
+    4251             :                 }
+    4252             : 
+    4253           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", "No transpose", "Unit", m, k, &one,
+    4254             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+    4255           0 :                 if (*n > *k) {
+    4256             : 
+    4257           0 :                     i__1 = *n - *k;
+    4258           0 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose", "No transpose", m, k, &i__1, &
+    4259           0 :                             one, &c__[(*k + 1) * c_dim1 + 1], ldc, &v[*k + 
+    4260           0 :                             1 + v_dim1], ldv, &one, &work[work_offset], 
+    4261             :                             ldwork);
+    4262             :                 }
+    4263             : 
+    4264           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", trans, "Non-unit", m, k, &one, &t[
+    4265             :                         t_offset], ldt, &work[work_offset], ldwork);
+    4266             : 
+    4267           0 :                 if (*n > *k) {
+    4268           0 :                     i__1 = *n - *k;
+    4269           0 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose", "Transpose", m, &i__1, k, &minusone, &
+    4270           0 :                             work[work_offset], ldwork, &v[*k + 1 + v_dim1], 
+    4271           0 :                             ldv, &one, &c__[(*k + 1) * c_dim1 + 1], ldc);
+    4272             :                 }
+    4273             : 
+    4274           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", "Transpose", "Unit", m, k, &one, &
+    4275             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+    4276             : 
+    4277           0 :                 i__1 = *k;
+    4278           0 :                 for (j = 1; j <= i__1; ++j) {
+    4279           0 :                     i__2 = *m;
+    4280           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    4281           0 :                         c__[i__ + j * c_dim1] -= work[i__ + j * work_dim1];
+    4282             :                     }
+    4283             :                 }
+    4284             :             }
+    4285             : 
+    4286             :         } else {
+    4287             : 
+    4288          59 :           if (*side=='l' || *side=='L') {
+    4289          59 :                 i__1 = *k;
+    4290        1663 :                 for (j = 1; j <= i__1; ++j) {
+    4291        1604 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &c__[*m - *k + j + c_dim1], ldc, &work[j * 
+    4292        1604 :                             work_dim1 + 1], &c__1);
+    4293             :                 }
+    4294             : 
+    4295          59 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", "No transpose", "Unit", n, k, &one,
+    4296          59 :                          &v[*m - *k + 1 + v_dim1], ldv, &work[work_offset], 
+    4297             :                         ldwork);
+    4298          59 :                 if (*m > *k) {
+    4299          47 :                     i__1 = *m - *k;
+    4300          47 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("Transpose", "No transpose", n, k, &i__1, &one, &
+    4301             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+    4302             :                             work[work_offset], ldwork);
+    4303             :                 }
+    4304             : 
+    4305          59 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", transt, "Non-unit", n, k, &one, &t[
+    4306             :                         t_offset], ldt, &work[work_offset], ldwork);
+    4307             : 
+    4308          59 :                 if (*m > *k) {
+    4309             : 
+    4310          47 :                     i__1 = *m - *k;
+    4311          47 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose", "Transpose", &i__1, n, k, &minusone, &
+    4312             :                             v[v_offset], ldv, &work[work_offset], ldwork, &
+    4313             :                             one, &c__[c_offset], ldc)
+    4314             :                             ;
+    4315             :                 }
+    4316             : 
+    4317          59 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", "Transpose", "Unit", n, k, &one, &
+    4318          59 :                         v[*m - *k + 1 + v_dim1], ldv, &work[work_offset], 
+    4319             :                         ldwork);
+    4320             : 
+    4321          59 :                 i__1 = *k;
+    4322        1663 :                 for (j = 1; j <= i__1; ++j) {
+    4323        1604 :                     i__2 = *n;
+    4324      391844 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    4325      390240 :                         c__[*m - *k + j + i__ * c_dim1] -= work[i__ + j * 
+    4326      390240 :                                 work_dim1];
+    4327             :                     }
+    4328             :                 }
+    4329             : 
+    4330           0 :             } else if (*side=='r' || *side=='R') {
+    4331           0 :                 i__1 = *k;
+    4332           0 :                 for (j = 1; j <= i__1; ++j) {
+    4333           0 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(m, &c__[(*n - *k + j) * c_dim1 + 1], &c__1, &work[
+    4334           0 :                             j * work_dim1 + 1], &c__1);
+    4335             :                 }
+    4336             : 
+    4337           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", "No transpose", "Unit", m, k, &one,
+    4338           0 :                          &v[*n - *k + 1 + v_dim1], ldv, &work[work_offset], 
+    4339             :                         ldwork);
+    4340           0 :                 if (*n > *k) {
+    4341           0 :                     i__1 = *n - *k;
+    4342           0 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose", "No transpose", m, k, &i__1, &
+    4343             :                             one, &c__[c_offset], ldc, &v[v_offset], ldv, &
+    4344             :                             one, &work[work_offset], ldwork);
+    4345             :                 }
+    4346           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", trans, "Non-unit", m, k, &one, &t[
+    4347             :                         t_offset], ldt, &work[work_offset], ldwork);
+    4348           0 :                 if (*n > *k) {
+    4349           0 :                     i__1 = *n - *k;
+    4350           0 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose", "Transpose", m, &i__1, k, &minusone, &
+    4351             :                             work[work_offset], ldwork, &v[v_offset], ldv, &
+    4352             :                             one, &c__[c_offset], ldc)
+    4353             :                             ;
+    4354             :                 }
+    4355           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", "Transpose", "Unit", m, k, &one, &
+    4356           0 :                         v[*n - *k + 1 + v_dim1], ldv, &work[work_offset], 
+    4357             :                         ldwork);
+    4358           0 :                 i__1 = *k;
+    4359           0 :                 for (j = 1; j <= i__1; ++j) {
+    4360           0 :                     i__2 = *m;
+    4361           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    4362           0 :                         c__[i__ + (*n - *k + j) * c_dim1] -= work[i__ + j * 
+    4363           0 :                                 work_dim1];
+    4364             :                     }
+    4365             :                 }
+    4366             :             }
+    4367             :         }
+    4368             : 
+    4369          40 :     } else  if (*storev=='r' || *storev=='R') {
+    4370          40 :       if (*direct=='F' || *direct=='f') {
+    4371          40 :           if (*side=='l' || *side=='L') {
+    4372           0 :                 i__1 = *k;
+    4373           0 :                 for (j = 1; j <= i__1; ++j) {
+    4374           0 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &c__[j + c_dim1], ldc, &work[j * work_dim1 + 1],
+    4375             :                              &c__1);
+    4376             :                 }
+    4377           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", "Transpose", "Unit", n, k, &one, &
+    4378             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+    4379           0 :                 if (*m > *k) {
+    4380           0 :                     i__1 = *m - *k;
+    4381           0 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("Transpose", "Transpose", n, k, &i__1, &one, &
+    4382           0 :                             c__[*k + 1 + c_dim1], ldc, &v[(*k + 1) * v_dim1 + 
+    4383           0 :                             1], ldv, &one, &work[work_offset], ldwork);
+    4384             :                 }
+    4385             : 
+    4386           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", transt, "Non-unit", n, k, &one, &t[
+    4387             :                         t_offset], ldt, &work[work_offset], ldwork);
+    4388           0 :                 if (*m > *k) {
+    4389             : 
+    4390           0 :                     i__1 = *m - *k;
+    4391           0 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("Transpose", "Transpose", &i__1, n, k, &minusone, &v[(
+    4392           0 :                             *k + 1) * v_dim1 + 1], ldv, &work[work_offset], 
+    4393           0 :                             ldwork, &one, &c__[*k + 1 + c_dim1], ldc);
+    4394             :                 }
+    4395             : 
+    4396           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", "No transpose", "Unit", n, k, &one,
+    4397             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+    4398             : 
+    4399           0 :                 i__1 = *k;
+    4400           0 :                 for (j = 1; j <= i__1; ++j) {
+    4401           0 :                     i__2 = *n;
+    4402           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    4403           0 :                         c__[j + i__ * c_dim1] -= work[i__ + j * work_dim1];
+    4404             :                     }
+    4405             :                 }
+    4406             : 
+    4407          40 :             } else if (*side=='r' || *side=='R') {
+    4408             : 
+    4409          40 :                 i__1 = *k;
+    4410         971 :                 for (j = 1; j <= i__1; ++j) {
+    4411         931 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(m, &c__[j * c_dim1 + 1], &c__1, &work[j * 
+    4412         931 :                             work_dim1 + 1], &c__1);
+    4413             :                 }
+    4414             : 
+    4415          40 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", "Transpose", "Unit", m, k, &one, &
+    4416             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+    4417          40 :                 if (*n > *k) {
+    4418             : 
+    4419          27 :                     i__1 = *n - *k;
+    4420          27 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose", "Transpose", m, k, &i__1, &one, &
+    4421          27 :                             c__[(*k + 1) * c_dim1 + 1], ldc, &v[(*k + 1) * 
+    4422          27 :                             v_dim1 + 1], ldv, &one, &work[work_offset], 
+    4423             :                             ldwork);
+    4424             :                 }
+    4425             : 
+    4426          40 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", trans, "Non-unit", m, k, &one, &t[
+    4427             :                         t_offset], ldt, &work[work_offset], ldwork);
+    4428             : 
+    4429          40 :                 if (*n > *k) {
+    4430             : 
+    4431          27 :                     i__1 = *n - *k;
+    4432          27 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose", "No transpose", m, &i__1, k, &
+    4433          27 :                             minusone, &work[work_offset], ldwork, &v[(*k + 1) * 
+    4434          27 :                             v_dim1 + 1], ldv, &one, &c__[(*k + 1) * c_dim1 
+    4435          27 :                             + 1], ldc);
+    4436             :                 }
+    4437          40 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Upper", "No transpose", "Unit", m, k, &one,
+    4438             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+    4439          40 :                 i__1 = *k;
+    4440         971 :                 for (j = 1; j <= i__1; ++j) {
+    4441         931 :                     i__2 = *m;
+    4442      266447 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    4443      265516 :                         c__[i__ + j * c_dim1] -= work[i__ + j * work_dim1];
+    4444             :                     }
+    4445             :                 }
+    4446             : 
+    4447             :             }
+    4448             : 
+    4449             :         } else {
+    4450             : 
+    4451           0 :             if (*side=='l' || *side=='L') {
+    4452             : 
+    4453           0 :                 i__1 = *k;
+    4454           0 :                 for (j = 1; j <= i__1; ++j) {
+    4455           0 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &c__[*m - *k + j + c_dim1], ldc, &work[j * 
+    4456           0 :                             work_dim1 + 1], &c__1);
+    4457             :                 }
+    4458             : 
+    4459           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", "Transpose", "Unit", n, k, &one, &
+    4460           0 :                         v[(*m - *k + 1) * v_dim1 + 1], ldv, &work[work_offset]
+    4461             :                         , ldwork);
+    4462           0 :                 if (*m > *k) {
+    4463             : 
+    4464           0 :                     i__1 = *m - *k;
+    4465           0 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("Transpose", "Transpose", n, k, &i__1, &one, &
+    4466             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+    4467             :                             work[work_offset], ldwork);
+    4468             :                 }
+    4469             : 
+    4470           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", transt, "Non-unit", n, k, &one, &t[
+    4471             :                         t_offset], ldt, &work[work_offset], ldwork);
+    4472             : 
+    4473           0 :                 if (*m > *k) {
+    4474             : 
+    4475           0 :                     i__1 = *m - *k;
+    4476           0 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("Transpose", "Transpose", &i__1, n, k, &minusone, &v[
+    4477             :                             v_offset], ldv, &work[work_offset], ldwork, &
+    4478             :                             one, &c__[c_offset], ldc);
+    4479             :                 }
+    4480             : 
+    4481           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", "No transpose", "Unit", n, k, &one,
+    4482           0 :                          &v[(*m - *k + 1) * v_dim1 + 1], ldv, &work[
+    4483             :                         work_offset], ldwork);
+    4484             : 
+    4485           0 :                 i__1 = *k;
+    4486           0 :                 for (j = 1; j <= i__1; ++j) {
+    4487           0 :                     i__2 = *n;
+    4488           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    4489           0 :                         c__[*m - *k + j + i__ * c_dim1] -= work[i__ + j * 
+    4490           0 :                                 work_dim1];
+    4491             :                     }
+    4492             :                 }
+    4493             : 
+    4494           0 :             } else if (*side=='r' || *side=='R') {
+    4495             : 
+    4496           0 :                 i__1 = *k;
+    4497           0 :                 for (j = 1; j <= i__1; ++j) {
+    4498           0 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(m, &c__[(*n - *k + j) * c_dim1 + 1], &c__1, &work[
+    4499           0 :                             j * work_dim1 + 1], &c__1);
+    4500             :                 }
+    4501             : 
+    4502           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", "Transpose", "Unit", m, k, &one, &
+    4503           0 :                         v[(*n - *k + 1) * v_dim1 + 1], ldv, &work[work_offset]
+    4504             :                         , ldwork);
+    4505           0 :                 if (*n > *k) {
+    4506             : 
+    4507           0 :                     i__1 = *n - *k;
+    4508           0 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose", "Transpose", m, k, &i__1, &one, &
+    4509             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+    4510             :                             work[work_offset], ldwork);
+    4511             :                 }
+    4512             : 
+    4513           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", trans, "Non-unit", m, k, &one, &t[
+    4514             :                         t_offset], ldt, &work[work_offset], ldwork);
+    4515             : 
+    4516           0 :                 if (*n > *k) {
+    4517             : 
+    4518           0 :                     i__1 = *n - *k;
+    4519           0 :                     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("No transpose", "No transpose", m, &i__1, k, &
+    4520             :                             minusone, &work[work_offset], ldwork, &v[v_offset], 
+    4521             :                             ldv, &one, &c__[c_offset], ldc);
+    4522             :                 }
+    4523             : 
+    4524           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Right", "Lower", "No transpose", "Unit", m, k, &one,
+    4525           0 :                          &v[(*n - *k + 1) * v_dim1 + 1], ldv, &work[
+    4526             :                         work_offset], ldwork);
+    4527             : 
+    4528           0 :                 i__1 = *k;
+    4529           0 :                 for (j = 1; j <= i__1; ++j) {
+    4530           0 :                     i__2 = *m;
+    4531           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+    4532           0 :                         c__[i__ + (*n - *k + j) * c_dim1] -= work[i__ + j * 
+    4533           0 :                                 work_dim1];
+    4534             :                     }
+    4535             :                 }
+    4536             : 
+    4537             :             }
+    4538             : 
+    4539             :         }
+    4540             :     }
+    4541             : 
+    4542             :     return;
+    4543             : 
+    4544             : 
+    4545             : }
+    4546             : 
+    4547             : }
+    4548             : }
+    4549             : #include <cmath>
+    4550             : #include "real.h"
+    4551             : 
+    4552             : #include "blas/blas.h"
+    4553             : #include "lapack.h"
+    4554             : #include "lapack_limits.h"
+    4555             : 
+    4556             : 
+    4557             : #include "blas/blas.h"
+    4558             : namespace PLMD{
+    4559             : namespace lapack{
+    4560             : using namespace blas;
+    4561             : void
+    4562     1689406 : PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(int   *n,
+    4563             :                         double *alpha,
+    4564             :                         double *x,
+    4565             :                         int    *incx,
+    4566             :                         double *tau)
+    4567             : {
+    4568             :   double xnorm,t;
+    4569             :   int    ti1,knt,j;
+    4570             :   double minval,safmin,rsafmn,beta;
+    4571             : 
+    4572     1689406 :   if(*n<=1) {
+    4573      570197 :     *tau = 0;
+    4574      570197 :     return;
+    4575             :   }
+    4576             : 
+    4577     1119209 :   ti1 = *n-1;
+    4578             : 
+    4579     1119209 :   xnorm = PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(&ti1,x,incx);
+    4580             : 
+    4581     1119209 :   if(std::abs(xnorm)<PLUMED_GMX_DOUBLE_MIN) {
+    4582           1 :     *tau = 0.0;
+    4583             :   } else {
+    4584             : 
+    4585     1119208 :     t = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(alpha,&xnorm);
+    4586             : 
+    4587     1119208 :     if(*alpha<0)
+    4588             :       beta = t;
+    4589             :     else
+    4590      453491 :       beta = -t;
+    4591             : 
+    4592             :     minval = PLUMED_GMX_DOUBLE_MIN;
+    4593             :     
+    4594             :     safmin = minval*(1.0+PLUMED_GMX_DOUBLE_EPS) / PLUMED_GMX_DOUBLE_EPS;
+    4595             : 
+    4596             :         
+    4597     1119208 :     if(std::abs(beta)<safmin) {
+    4598             : 
+    4599             :       knt = 0;
+    4600           0 :       rsafmn = 1.0 / safmin;
+    4601             :       
+    4602           0 :       while(std::abs(beta)<safmin) {
+    4603           0 :         knt++;
+    4604           0 :         ti1 = *n-1;
+    4605           0 :         PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&ti1,&rsafmn,x,incx);
+    4606           0 :         beta *= rsafmn;
+    4607           0 :         *alpha *= rsafmn;
+    4608             :       }
+    4609             :       
+    4610             :       /* safmin <= beta <= 1 now */
+    4611           0 :       ti1 = *n-1;
+    4612           0 :       xnorm = PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(&ti1,x,incx);
+    4613           0 :       t = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(alpha,&xnorm);
+    4614             :       
+    4615           0 :       if(*alpha<0)
+    4616             :         beta = t;
+    4617             :       else
+    4618           0 :         beta = -t;
+    4619             :       
+    4620           0 :       *tau = (beta-*alpha)/beta;
+    4621             : 
+    4622           0 :       ti1= *n-1;
+    4623           0 :       t = 1.0/(*alpha-beta);
+    4624           0 :       PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&ti1,&t,x,incx);
+    4625             :    
+    4626           0 :       *alpha = beta;
+    4627           0 :       for(j=0;j<knt;j++)
+    4628           0 :         *alpha *= safmin;
+    4629             :     } else {
+    4630     1119208 :       *tau = (beta-*alpha)/beta;
+    4631     1119208 :       ti1= *n-1;
+    4632     1119208 :       t = 1.0/(*alpha-beta);
+    4633     1119208 :       PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&ti1,&t,x,incx);
+    4634     1119208 :       *alpha = beta;
+    4635             :     }
+    4636             :   }
+    4637             :    
+    4638             :   return;
+    4639             : }
+    4640             : }
+    4641             : }
+    4642             : #include <cmath>
+    4643             : #include "real.h"
+    4644             : 
+    4645             : #include "blas/blas.h"
+    4646             : #include "lapack.h"
+    4647             : 
+    4648             : #include "blas/blas.h"
+    4649             : namespace PLMD{
+    4650             : namespace lapack{
+    4651             : using namespace blas;
+    4652             : void 
+    4653         147 : PLUMED_BLAS_F77_FUNC(dlarft,DLARFT)(const char *direct, 
+    4654             :         const char *storev, 
+    4655             :         int *n, 
+    4656             :         int *k, 
+    4657             :         double *v, 
+    4658             :         int *ldv, 
+    4659             :         double *tau, 
+    4660             :         double *t, 
+    4661             :         int *ldt)
+    4662             : {
+    4663             :     /* System generated locals */
+    4664             :     int t_dim1, t_offset, v_dim1, v_offset, i__1, i__2, i__3;
+    4665             :     double d__1;
+    4666             : 
+    4667             :     /* Local variables */
+    4668             :     int i__, j;
+    4669             :     double vii;
+    4670         147 :     int c__1 = 1;
+    4671         147 :     double zero = 0.0;
+    4672             : 
+    4673         147 :     v_dim1 = *ldv;
+    4674         147 :     v_offset = 1 + v_dim1;
+    4675         147 :     v -= v_offset;
+    4676         147 :     --tau;
+    4677         147 :     t_dim1 = *ldt;
+    4678         147 :     t_offset = 1 + t_dim1;
+    4679         147 :     t -= t_offset;
+    4680             : 
+    4681         147 :     if (*n == 0) {
+    4682             :         return;
+    4683             :     }
+    4684             : 
+    4685         147 :     if (*direct=='F' || *direct=='f') {
+    4686          88 :         i__1 = *k;
+    4687        2095 :         for (i__ = 1; i__ <= i__1; ++i__) {
+    4688        2007 :             if (std::abs(tau[i__])<PLUMED_GMX_DOUBLE_MIN) {
+    4689             : 
+    4690          30 :                 i__2 = i__;
+    4691         181 :                 for (j = 1; j <= i__2; ++j) {
+    4692         151 :                     t[j + i__ * t_dim1] = 0.;
+    4693             :                 }
+    4694             :             } else {
+    4695             : 
+    4696        1977 :                 vii = v[i__ + i__ * v_dim1];
+    4697        1977 :                 v[i__ + i__ * v_dim1] = 1.;
+    4698        1977 :                 if (*storev=='C' || *storev=='c') {
+    4699             : 
+    4700        1059 :                     i__2 = *n - i__ + 1;
+    4701        1059 :                     i__3 = i__ - 1;
+    4702        1059 :                     d__1 = -tau[i__];
+    4703        1059 :                     PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__2, &i__3, &d__1, &v[i__ + v_dim1],
+    4704             :                              ldv, &v[i__ + i__ * v_dim1], &c__1, &zero, &t[
+    4705        1059 :                             i__ * t_dim1 + 1], &c__1);
+    4706             :                 } else {
+    4707             : 
+    4708         918 :                     i__2 = i__ - 1;
+    4709         918 :                     i__3 = *n - i__ + 1;
+    4710         918 :                     d__1 = -tau[i__];
+    4711         918 :                     PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__2, &i__3, &d__1, &v[i__ * 
+    4712         918 :                             v_dim1 + 1], ldv, &v[i__ + i__ * v_dim1], ldv, &
+    4713         918 :                             zero, &t[i__ * t_dim1 + 1], &c__1);
+    4714             :                 }
+    4715        1977 :                 v[i__ + i__ * v_dim1] = vii;
+    4716             : 
+    4717             : 
+    4718        1977 :                 i__2 = i__ - 1;
+    4719        1977 :                 PLUMED_BLAS_F77_FUNC(dtrmv,DTRMV)("Upper", "No transpose", "Non-unit", &i__2, &t[
+    4720        1977 :                         t_offset], ldt, &t[i__ * t_dim1 + 1], &c__1);
+    4721        1977 :                 t[i__ + i__ * t_dim1] = tau[i__];
+    4722             :             }
+    4723             :         }
+    4724             :     } else {
+    4725        1663 :         for (i__ = *k; i__ >= 1; --i__) {
+    4726        1604 :             if (std::abs(tau[i__])<PLUMED_GMX_DOUBLE_MIN) {
+    4727             : 
+    4728          12 :                 i__1 = *k;
+    4729         396 :                 for (j = i__; j <= i__1; ++j) {
+    4730         384 :                     t[j + i__ * t_dim1] = 0.;
+    4731             :                 }
+    4732             :             } else {
+    4733             : 
+    4734        1592 :                 if (i__ < *k) {
+    4735        1533 :                     if (*storev=='C' || *storev=='c') {
+    4736        1533 :                         vii = v[*n - *k + i__ + i__ * v_dim1];
+    4737        1533 :                         v[*n - *k + i__ + i__ * v_dim1] = 1.;
+    4738             : 
+    4739        1533 :                         i__1 = *n - *k + i__;
+    4740        1533 :                         i__2 = *k - i__;
+    4741        1533 :                         d__1 = -tau[i__];
+    4742        1533 :                         PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("Transpose", &i__1, &i__2, &d__1, &v[(i__ + 1) 
+    4743        1533 :                                 * v_dim1 + 1], ldv, &v[i__ * v_dim1 + 1], &
+    4744        1533 :                                 c__1, &zero, &t[i__ + 1 + i__ * t_dim1], &
+    4745             :                                 c__1);
+    4746        1533 :                         v[*n - *k + i__ + i__ * v_dim1] = vii;
+    4747             :                     } else {
+    4748           0 :                         vii = v[i__ + (*n - *k + i__) * v_dim1];
+    4749           0 :                         v[i__ + (*n - *k + i__) * v_dim1] = 1.;
+    4750             : 
+    4751           0 :                         i__1 = *k - i__;
+    4752           0 :                         i__2 = *n - *k + i__;
+    4753           0 :                         d__1 = -tau[i__];
+    4754           0 :                         PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("No transpose", &i__1, &i__2, &d__1, &v[i__ + 
+    4755           0 :                                 1 + v_dim1], ldv, &v[i__ + v_dim1], ldv, &
+    4756           0 :                                 zero, &t[i__ + 1 + i__ * t_dim1], &c__1);
+    4757           0 :                         v[i__ + (*n - *k + i__) * v_dim1] = vii;
+    4758             :                     }
+    4759             : 
+    4760        1533 :                     i__1 = *k - i__;
+    4761        1533 :                     PLUMED_BLAS_F77_FUNC(dtrmv,DTRMV)("Lower", "No transpose", "Non-unit", &i__1, &t[i__ 
+    4762        1533 :                             + 1 + (i__ + 1) * t_dim1], ldt, &t[i__ + 1 + i__ *
+    4763        1533 :                              t_dim1], &c__1)
+    4764             :                             ;
+    4765             :                 }
+    4766        1592 :                 t[i__ + i__ * t_dim1] = tau[i__];
+    4767             :             }
+    4768             :         }
+    4769             :     }
+    4770             :     return;
+    4771             : 
+    4772             : 
+    4773             : }
+    4774             : }
+    4775             : }
+    4776             : #include <cmath>
+    4777             : #include "lapack.h"
+    4778             : 
+    4779             : #include "blas/blas.h"
+    4780             : namespace PLMD{
+    4781             : namespace lapack{
+    4782             : using namespace blas;
+    4783             : void
+    4784           0 : PLUMED_BLAS_F77_FUNC(dlarnv,DLARNV)(int *idist, 
+    4785             :         int *iseed, 
+    4786             :         int *n, 
+    4787             :         double *x)
+    4788             : {
+    4789             :     int i__1, i__2, i__3;
+    4790             : 
+    4791             :     int i__;
+    4792             :     double u[128];
+    4793             :     int il, iv, il2;
+    4794             : 
+    4795           0 :     --x;
+    4796             :     --iseed;
+    4797             : 
+    4798           0 :     i__1 = *n;
+    4799           0 :     for (iv = 1; iv <= i__1; iv += 64) {
+    4800           0 :         i__2 = 64, i__3 = *n - iv + 1;
+    4801             :         il = (i__2<i__3) ? i__2 : i__3;
+    4802           0 :         if (*idist == 3) {
+    4803           0 :             il2 = il << 1;
+    4804             :         } else {
+    4805           0 :             il2 = il;
+    4806             :         }
+    4807             : 
+    4808           0 :         PLUMED_BLAS_F77_FUNC(dlaruv,DLARUV)(&iseed[1], &il2, u);
+    4809             : 
+    4810           0 :         if (*idist == 1) {
+    4811             : 
+    4812             :             i__2 = il;
+    4813           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    4814           0 :                 x[iv + i__ - 1] = u[i__ - 1];
+    4815             :             }
+    4816           0 :         } else if (*idist == 2) {
+    4817             : 
+    4818             :             i__2 = il;
+    4819           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    4820           0 :                 x[iv + i__ - 1] = u[i__ - 1] * 2. - 1.;
+    4821             :             }
+    4822           0 :         } else if (*idist == 3) {
+    4823             : 
+    4824             :             i__2 = il;
+    4825           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    4826           0 :                 x[iv + i__ - 1] =  std::sqrt(std::log(u[(i__ << 1) - 2]) * -2.) * 
+    4827           0 :                   std::cos(u[(i__ << 1) - 1] * (double)6.2831853071795864769252867663);
+    4828             :             }
+    4829             :         }
+    4830             :     }
+    4831           0 :     return;
+    4832             : 
+    4833             : }
+    4834             : }
+    4835             : }
+    4836             : #include <cmath>
+    4837             : 
+    4838             : #include "real.h"
+    4839             : 
+    4840             : #include "lapack.h"
+    4841             : #include "lapack_limits.h"
+    4842             : 
+    4843             : #include "blas/blas.h"
+    4844             : namespace PLMD{
+    4845             : namespace lapack{
+    4846             : using namespace blas;
+    4847             : void
+    4848      570075 : PLUMED_BLAS_F77_FUNC(dlarrbx,DLARRBX)(int *n, 
+    4849             :          double *d__, 
+    4850             :          double *l, 
+    4851             :          double *ld, 
+    4852             :          double *lld, 
+    4853             :          int *ifirst, 
+    4854             :          int *ilast, 
+    4855             :          double *rtol1, 
+    4856             :          double *rtol2, 
+    4857             :          int *offset, 
+    4858             :          double *w, 
+    4859             :          double *wgap, 
+    4860             :          double *werr, 
+    4861             :          double *work,
+    4862             :          int *iwork, 
+    4863             :          int *info)
+    4864             : {
+    4865             :     int i__1, i__2, i__3;
+    4866             :     double d__1, d__2;
+    4867             : 
+    4868             :     int i__, j, k, p;
+    4869             :     double s;
+    4870             :     int i1, i2, ii, kk;
+    4871             :     double fac, gap, mid;
+    4872             :     int cnt;
+    4873             :     double tmp, left;
+    4874             :     int nint, prev, next, nleft;
+    4875             :     double right, width, dplus;
+    4876             :     int nright, olnint;
+    4877             :     k = 0;
+    4878             :     right = 0.0;
+    4879             : 
+    4880      570075 :     --iwork;
+    4881      570075 :     --work;
+    4882      570075 :     --werr;
+    4883      570075 :     --wgap;
+    4884      570075 :     --w;
+    4885      570075 :     --lld;
+    4886             :     --ld;
+    4887             :     --l;
+    4888      570075 :     --d__;
+    4889             : 
+    4890      570075 :     *info = 0;
+    4891      570075 :     i__1 = *n << 1;
+    4892     5134135 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    4893     4564060 :         iwork[i__] = 0;
+    4894             :     }
+    4895      570075 :     i1 = *ifirst;
+    4896             :     i2 = *ifirst;
+    4897             :     prev = 0;
+    4898      570075 :     i__1 = *ilast;
+    4899     1141016 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+    4900      570941 :         k = i__ << 1;
+    4901      570941 :         iwork[k - 1] = 1;
+    4902             :         i2 = i__;
+    4903             :     }
+    4904             : 
+    4905             :     i__ = i1;
+    4906             :     nint = 0;
+    4907     1141016 : L30:
+    4908     1141016 :     if (i__ <= i2) {
+    4909      570941 :         ii = i__ - *offset;
+    4910      570941 :         if (iwork[(i__ << 1) - 1] == 1) {
+    4911             :             fac = 1.;
+    4912      570941 :             left = w[ii] - werr[ii];
+    4913             : 
+    4914             : 
+    4915      571031 : L40:
+    4916      571031 :             if (i__ > i1 && left <= right) {
+    4917             :                 left = right;
+    4918           0 :                 cnt = i__ - 1;
+    4919             :             } else {
+    4920      571031 :                 s = -left;
+    4921             :                 cnt = 0;
+    4922      571031 :                 i__1 = *n - 1;
+    4923     2677322 :                 for (j = 1; j <= i__1; ++j) {
+    4924     2106291 :                     dplus = d__[j] + s;
+    4925     2106291 :                     s = s * lld[j] / dplus - left;
+    4926     2106291 :                     if (dplus < 0.) {
+    4927      209478 :                         ++cnt;
+    4928             :                     }
+    4929             :                 }
+    4930      571031 :                 dplus = d__[*n] + s;
+    4931      571031 :                 if (dplus < 0.) {
+    4932          90 :                     ++cnt;
+    4933             :                 }
+    4934      571031 :         if (std::isnan(s)) {
+    4935             : 
+    4936             :                     cnt = 0;
+    4937             :                     s = -left;
+    4938             :                     i__1 = *n - 1;
+    4939           0 :                     for (j = 1; j <= i__1; ++j) {
+    4940           0 :                         dplus = d__[j] + s;
+    4941           0 :                         if (dplus < 0.) {
+    4942           0 :                             ++cnt;
+    4943             :                         }
+    4944           0 :                         tmp = lld[j] / dplus;
+    4945           0 :                         if (std::abs(tmp)<PLUMED_GMX_DOUBLE_MIN) {
+    4946           0 :                             s = lld[j] - left;
+    4947             :                         } else {
+    4948           0 :                             s = s * tmp - left;
+    4949             :                         }
+    4950             :                     }
+    4951           0 :                     dplus = d__[*n] + s;
+    4952           0 :                     if (dplus < 0.) {
+    4953           0 :                         ++cnt;
+    4954             :                     }
+    4955             :                 }
+    4956      571031 :                 if (cnt > i__ - 1) {
+    4957          90 :                     left -= werr[ii] * fac;
+    4958          90 :                     fac *= 2.;
+    4959          90 :                     goto L40;
+    4960             :                 }
+    4961             :             }
+    4962      570941 :             nleft = cnt + 1;
+    4963             :             i1 = (i1<nleft) ? i1 : nleft;
+    4964             :             fac = 1.;
+    4965      570941 :             right = w[ii] + werr[ii];
+    4966      570957 : L60:
+    4967      570957 :             s = -right;
+    4968             :             cnt = 0;
+    4969      570957 :             i__1 = *n - 1;
+    4970     2654322 :             for (j = 1; j <= i__1; ++j) {
+    4971     2083365 :                 dplus = d__[j] + s;
+    4972     2083365 :                 s = s * lld[j] / dplus - right;
+    4973     2083365 :                 if (dplus < 0.) {
+    4974     1882760 :                     ++cnt;
+    4975             :                 }
+    4976             :             }
+    4977      570957 :             dplus = d__[*n] + s;
+    4978      570957 :             if (dplus < 0.) {
+    4979      570937 :                 ++cnt;
+    4980             :             }
+    4981      570957 :             if (std::isnan(s)) {
+    4982             : 
+    4983             :                 cnt = 0;
+    4984             :                 s = -right;
+    4985             :                 i__1 = *n - 1;
+    4986           0 :                 for (j = 1; j <= i__1; ++j) {
+    4987           0 :                     dplus = d__[j] + s;
+    4988           0 :                     if (dplus < 0.) {
+    4989           0 :                         ++cnt;
+    4990             :                     }
+    4991           0 :                     tmp = lld[j] / dplus;
+    4992           0 :                     if (std::abs(tmp)<PLUMED_GMX_DOUBLE_MIN) {
+    4993           0 :                         s = lld[j] - right;
+    4994             :                     } else {
+    4995           0 :                         s = s * tmp - right;
+    4996             :                     }
+    4997             :                 }
+    4998           0 :                 dplus = d__[*n] + s;
+    4999           0 :                 if (dplus < 0.) {
+    5000           0 :                     ++cnt;
+    5001             :                 }
+    5002             :             }
+    5003      570957 :             if (cnt < i__) {
+    5004          16 :                 right += werr[ii] * fac;
+    5005          16 :                 fac *= 2.;
+    5006          16 :                 goto L60;
+    5007             :             }
+    5008             :             cnt = (cnt<i2) ? cnt : i2;
+    5009      570941 :             ++nint;
+    5010      570941 :             k = nleft << 1;
+    5011      570941 :             work[k - 1] = left;
+    5012      570941 :             work[k] = right;
+    5013      570941 :             i__ = cnt + 1;
+    5014      570941 :             iwork[k - 1] = i__;
+    5015      570941 :             iwork[k] = cnt;
+    5016      570941 :             if (prev != nleft - 1) {
+    5017          70 :                 work[k - 2] = left;
+    5018             :             }
+    5019             :             prev = nleft;
+    5020             :         } else {
+    5021           0 :             right = work[i__ * 2];
+    5022             : 
+    5023           0 :             ++iwork[k - 1];
+    5024             :             prev = i__;
+    5025           0 :             ++i__;
+    5026             :         }
+    5027      570941 :         goto L30;
+    5028             :     }
+    5029      570075 :     if (i__ <= *n && iwork[(i__ << 1) - 1] != -1) {
+    5030      490516 :         work[(i__ << 1) - 1] = work[prev * 2];
+    5031             :     }
+    5032             : 
+    5033       79559 : L80:
+    5034    29309946 :     prev = i1 - 1;
+    5035             :     olnint = nint;
+    5036             :     i__ = i1;
+    5037             :     i__1 = olnint;
+    5038    58621440 :     for (p = 1; p <= i__1; ++p) {
+    5039    29311494 :         k = i__ << 1;
+    5040    29311494 :         left = work[k - 1];
+    5041    29311494 :         right = work[k];
+    5042    29311494 :         next = iwork[k - 1];
+    5043    29311494 :         nright = iwork[k];
+    5044    29311494 :         mid = (left + right) * .5;
+    5045    29311494 :         width = right - mid;
+    5046             :         d__1 = std::abs(left);
+    5047             :         d__2 = std::abs(right);
+    5048    29311494 :         tmp = (d__1>d__2) ? d__1 : d__2;
+    5049             : 
+    5050             :         gap = 0.;
+    5051    29311494 :         if (i__ == nright) {
+    5052    29070832 :             if (prev > 0 && next <= *n) {
+    5053        2391 :                 d__1 = left - work[k - 2], d__2 = work[k + 1] - right;
+    5054        2391 :                 gap = (d__1<d__2) ? d__1 : d__2;
+    5055    29068441 :             } else if (prev > 0) {
+    5056     4055695 :                 gap = left - work[k - 2];
+    5057    25012746 :             } else if (next <= *n) {
+    5058    25012746 :                 gap = work[k + 1] - right;
+    5059             :             }
+    5060             :         }
+    5061    29311494 :         d__1 = *rtol1 * gap, d__2 = *rtol2 * tmp;
+    5062    32850190 :         if (width < ((d__1>d__2) ? d__1 : d__2)) {
+    5063      570941 :             --nint;
+    5064      570941 :             iwork[k - 1] = 0;
+    5065             :             kk = k;
+    5066             :             i__2 = nright;
+    5067      570941 :             for (j = i__ + 1; j <= i__2; ++j) {
+    5068           0 :                 kk += 2;
+    5069           0 :                 iwork[kk - 1] = 0;
+    5070           0 :                 work[kk - 1] = left;
+    5071           0 :                 work[kk] = right;
+    5072           0 :                 wgap[j - 1 - *offset] = 0.;
+    5073             :             }
+    5074      570941 :             if (i1 == i__) {
+    5075             :                 i1 = next;
+    5076             :             } else {
+    5077         831 :                 iwork[(prev << 1) - 1] = next;
+    5078             :             }
+    5079             :             i__ = next;
+    5080      570941 :             continue;
+    5081             :         }
+    5082             :         prev = i__;
+    5083             : 
+    5084    28740553 :         s = -mid;
+    5085             :         cnt = 0;
+    5086    28740553 :         i__2 = *n - 1;
+    5087   114232446 :         for (j = 1; j <= i__2; ++j) {
+    5088    85491893 :             dplus = d__[j] + s;
+    5089    85491893 :             s = s * lld[j] / dplus - mid;
+    5090    85491893 :             if (dplus < 0.) {
+    5091    15245063 :                 ++cnt;
+    5092             :             }
+    5093             :         }
+    5094    28740553 :         dplus = d__[*n] + s;
+    5095    28740553 :         if (dplus < 0.) {
+    5096    12605225 :             ++cnt;
+    5097             :         }
+    5098    28740553 :         if (std::isnan(s)) {
+    5099             :             cnt = 0;
+    5100             :             s = -mid;
+    5101             :             i__2 = *n - 1;
+    5102           0 :             for (j = 1; j <= i__2; ++j) {
+    5103           0 :                 dplus = d__[j] + s;
+    5104           0 :                 if (dplus < 0.) {
+    5105           0 :                     ++cnt;
+    5106             :                 }
+    5107           0 :                 tmp = lld[j] / dplus;
+    5108           0 :                 if (std::abs(tmp)<PLUMED_GMX_DOUBLE_MIN) {
+    5109           0 :                     s = lld[j] - mid;
+    5110             :                 } else {
+    5111           0 :                     s = s * tmp - mid;
+    5112             :                 }
+    5113             :             }
+    5114           0 :             dplus = d__[*n] + s;
+    5115           0 :             if (dplus < 0.) {
+    5116           0 :                 ++cnt;
+    5117             :             }
+    5118             :         }
+    5119    28740553 :         i__2 = i__ - 1, i__3 = (nright<cnt) ? nright : cnt;
+    5120             :         cnt = (i__2>i__3) ? i__2 : i__3;
+    5121    28740553 :         if (cnt == i__ - 1) {
+    5122    13873599 :             work[k - 1] = mid;
+    5123    14866954 :         } else if (cnt == nright) {
+    5124    14658815 :             work[k] = mid;
+    5125             :         } else {
+    5126      208139 :             iwork[k] = cnt;
+    5127      208139 :             ++cnt;
+    5128      208139 :             iwork[k - 1] = cnt;
+    5129      208139 :             kk = cnt << 1;
+    5130      208139 :             iwork[kk - 1] = next;
+    5131      208139 :             iwork[kk] = nright;
+    5132      208139 :             work[k] = mid;
+    5133      208139 :             work[kk - 1] = mid;
+    5134      208139 :             work[kk] = right;
+    5135             :             prev = cnt;
+    5136      208139 :             if (cnt - 1 > i__) {
+    5137       30298 :                 work[kk - 2] = mid;
+    5138             :             }
+    5139      208139 :             if (cnt > *ifirst && cnt <= *ilast) {
+    5140           0 :                 ++nint;
+    5141      208139 :             } else if (cnt <= *ifirst) {
+    5142             :                 i1 = cnt;
+    5143             :             }
+    5144             :         }
+    5145             :         i__ = next;
+    5146             :     }
+    5147    29309946 :     if (nint > 0) {
+    5148    28739871 :         goto L80;
+    5149             :     }
+    5150      570075 :     i__1 = *ilast;
+    5151     1141016 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+    5152      570941 :         k = i__ << 1;
+    5153      570941 :         ii = i__ - *offset;
+    5154      570941 :         if (iwork[k - 1] != -1) {
+    5155      570941 :             w[ii] = (work[k - 1] + work[k]) * .5;
+    5156      570941 :             werr[ii] = work[k] - w[ii];
+    5157      570941 :             if (i__ != *ilast) {
+    5158         866 :                 wgap[ii] = work[k + 1] - work[k];
+    5159             :             }
+    5160             :         }
+    5161             :     }
+    5162             : 
+    5163      570075 :     return;
+    5164             : 
+    5165             : } 
+    5166             : }
+    5167             : }
+    5168             : #include <cctype>
+    5169             : #include <cmath>
+    5170             : 
+    5171             : #include "real.h"
+    5172             : 
+    5173             : #include "blas/blas.h"
+    5174             : #include "lapack.h"
+    5175             : #include "lapack_limits.h"
+    5176             : 
+    5177             : 
+    5178             : 
+    5179             : #include "blas/blas.h"
+    5180             : namespace PLMD{
+    5181             : namespace lapack{
+    5182             : using namespace blas;
+    5183             : void
+    5184      570005 : PLUMED_BLAS_F77_FUNC(dlarrex,DLARREX)(const char *range,
+    5185             :          int *n, 
+    5186             :          double *vl, 
+    5187             :          double *vu, 
+    5188             :          int *il, 
+    5189             :          int *iu, 
+    5190             :          double *d__, 
+    5191             :          double *e, 
+    5192             :          double *tol, 
+    5193             :          int *nsplit, 
+    5194             :          int *isplit, 
+    5195             :          int *m, 
+    5196             :          double *w, 
+    5197             :          int *iblock, 
+    5198             :          int *indexw, 
+    5199             :          double *gersch, 
+    5200             :          double *work,
+    5201             :          int *iwork, 
+    5202             :          int *info)
+    5203             : {
+    5204             :     int i__1, i__2, i__3;
+    5205             :     double d__1, d__2;
+    5206      570005 :     int c__1 = 1;
+    5207      570005 :     int c__0 = 0;
+    5208             : 
+    5209             :     int i__, j, k;
+    5210             :     double s, gl;
+    5211             :     int in;
+    5212             :     double gu;
+    5213             :     int cnt;
+    5214             :     double eps, tau, nrm, tmp, vvl, vvu, offd;
+    5215             :     int iend, jblk, till, itmp;
+    5216             :     double rtol, delta, sigma;
+    5217             :     int iinfo;
+    5218             :     double width;
+    5219             :     int ibegin;
+    5220             :     int irange;
+    5221             :     double sgndef;
+    5222             :     int maxcnt;
+    5223      570005 :     --iwork;
+    5224      570005 :     --work;
+    5225      570005 :     --gersch;
+    5226      570005 :     --indexw;
+    5227      570005 :     --iblock;
+    5228      570005 :     --w;
+    5229      570005 :     --isplit;
+    5230      570005 :     --e;
+    5231      570005 :     --d__;
+    5232             : 
+    5233             :     sigma = 0;
+    5234             :     irange = 0;
+    5235             :     sgndef = 0;
+    5236             :     maxcnt = 0;
+    5237             : 
+    5238      570005 :     *info = 0;
+    5239             : 
+    5240      570005 :     if (*range=='A' || *range=='a')
+    5241             :         irange = 1;
+    5242      562531 :     else if (*range=='V' || *range=='v')
+    5243             :         irange = 2;
+    5244      562531 :     else if (*range=='I' || *range=='i')
+    5245             :         irange = 3;
+    5246             :     
+    5247             : 
+    5248      570005 :     *m = 0;
+    5249             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    5250             : 
+    5251      570005 :     *nsplit = 1;
+    5252      570005 :     i__1 = *n - 1;
+    5253     2254417 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5254     1684412 :         if (std::abs(e[i__]) <= *tol) {
+    5255         665 :             isplit[*nsplit] = i__;
+    5256         665 :             ++(*nsplit);
+    5257             :         }
+    5258             :     }
+    5259      570005 :     isplit[*nsplit] = *n;
+    5260             : 
+    5261             :     ibegin = 1;
+    5262      570005 :     i__1 = *nsplit;
+    5263     1140675 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+    5264      570670 :         iend = isplit[jblk];
+    5265      570670 :         if (ibegin == iend) {
+    5266         665 :             ++(*m);
+    5267         665 :             w[*m] = d__[ibegin];
+    5268         665 :             iblock[*m] = jblk;
+    5269         665 :             indexw[*m] = 1;
+    5270         665 :             e[iend] = 0.;
+    5271         665 :             ibegin = iend + 1;
+    5272         665 :             goto L170;
+    5273             :         }
+    5274      570005 :         in = iend - ibegin + 1;
+    5275             : 
+    5276      570005 :         gl = d__[ibegin] - std::abs(e[ibegin]);
+    5277      570005 :         gu = d__[ibegin] + std::abs(e[ibegin]);
+    5278      570005 :         gersch[(ibegin << 1) - 1] = gl;
+    5279      570005 :         gersch[ibegin * 2] = gu;
+    5280      570005 :         gersch[(iend << 1) - 1] = d__[iend] - std::abs(e[iend - 1]);
+    5281      570005 :         gersch[iend * 2] = d__[iend] + std::abs(e[iend - 1]);
+    5282      570005 :         d__1 = gersch[(iend << 1) - 1];
+    5283      570005 :         gl = (d__1<gl) ? d__1 : gl;
+    5284             :         d__1 = gersch[iend * 2];
+    5285      570005 :         gu = (d__1>gu) ? d__1 : gu;
+    5286      570005 :         i__2 = iend - 1;
+    5287     1683747 :         for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+    5288     1113742 :             offd = std::abs(e[i__ - 1]) + std::abs(e[i__]);
+    5289     1113742 :             gersch[(i__ << 1) - 1] = d__[i__] - offd;
+    5290             :             d__1 = gersch[(i__ << 1) - 1];
+    5291     1113742 :             gl = (d__1<gl) ? d__1 : gl;
+    5292     1113742 :             gersch[i__ * 2] = d__[i__] + offd;
+    5293             :             d__1 = gersch[i__ * 2];
+    5294     1113742 :             gu = (d__1>gu) ? d__1 : gu;
+    5295             :         }
+    5296             :         d__1 = std::abs(gl), d__2 = std::abs(gu);
+    5297      570005 :         nrm = (d__1>d__2) ? d__1 : d__2;
+    5298             : 
+    5299      570005 :         width = gu - gl;
+    5300             :         i__2 = iend - 1;
+    5301     2253752 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+    5302     1683747 :             work[i__] = e[i__] * e[i__];
+    5303             :         }
+    5304     1710015 :         for (j = 1; j <= 2; ++j) {
+    5305     1140010 :             if (j == 1) {
+    5306      570005 :                 tau = gl + width * .25;
+    5307             :             } else {
+    5308      570005 :                 tau = gu - width * .25;
+    5309             :             }
+    5310     1140010 :             tmp = d__[ibegin] - tau;
+    5311     1140010 :             if (tmp < 0.) {
+    5312      596319 :                 cnt = 1;
+    5313             :             } else {
+    5314      543691 :                 cnt = 0;
+    5315             :             }
+    5316     1140010 :             i__2 = iend;
+    5317     4507504 :             for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+    5318     3367494 :                 tmp = d__[i__] - tau - work[i__ - 1] / tmp;
+    5319     3367494 :                 if (tmp < 0.) {
+    5320     1585161 :                     ++cnt;
+    5321             :                 }
+    5322             :             }
+    5323     1140010 :             if (cnt == 0) {
+    5324             :                 gl = tau;
+    5325     1140010 :             } else if (cnt == in) {
+    5326             :                 gu = tau;
+    5327             :             }
+    5328     1140010 :             if (j == 1) {
+    5329             :                 maxcnt = cnt;
+    5330             :                 sigma = gl;
+    5331             :                 sgndef = 1.;
+    5332             :             } else {
+    5333      570005 :                 if (in - cnt > maxcnt) {
+    5334             :                     sigma = gu;
+    5335             :                     sgndef = -1.;
+    5336             :                 }
+    5337             :             }
+    5338             :         }
+    5339             : 
+    5340      570005 :         work[in * 3] = 1.;
+    5341             :         delta = eps;
+    5342      570005 :         tau = sgndef * nrm;
+    5343      570005 : L60:
+    5344      570005 :         sigma -= delta * tau;
+    5345      570005 :         work[1] = d__[ibegin] - sigma;
+    5346             :         j = ibegin;
+    5347      570005 :         i__2 = in - 1;
+    5348     2253752 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5349     1683747 :             work[(in << 1) + i__] = 1. / work[i__];
+    5350     1683747 :             tmp = e[j] * work[(in << 1) + i__];
+    5351     1683747 :             work[i__ + 1] = d__[j + 1] - sigma - tmp * e[j];
+    5352     1683747 :             work[in + i__] = tmp;
+    5353     1683747 :             ++j;
+    5354             :         }
+    5355     2823757 :         for (i__ = in; i__ >= 1; --i__) {
+    5356     2253752 :             tmp = sgndef * work[i__];
+    5357     2253752 :         if (tmp < 0. || std::abs(work[(in << 1) + i__])<PLUMED_GMX_DOUBLE_MIN || std::isnan(tmp)) {
+    5358           0 :                 delta *= 2.;
+    5359           0 :                 goto L60;
+    5360             :             }
+    5361             :         }
+    5362             : 
+    5363      570005 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+    5364      570005 :         i__2 = in - 1;
+    5365      570005 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+    5366      570005 :         i__2 = in - 1;
+    5367     2253752 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5368     1683747 :             work[in * 3 + i__] = work[i__] * work[in + i__];
+    5369     1683747 :             work[(in << 2) + i__] = work[in * 3 + i__] * work[in + i__];
+    5370             :         }
+    5371      570005 :         if (sgndef > 0.) {
+    5372      490446 :             cnt = 1;
+    5373      490446 :             work[1] = (gl + gu) / 2. - sigma;
+    5374      490446 :             work[in + 1] = 0.;
+    5375      490446 :             work[(in << 1) + 1] = (gu - gl) / 2.;
+    5376             :         } else {
+    5377       79559 :             cnt = in;
+    5378       79559 :             work[in] = (gl + gu) / 2. - sigma;
+    5379       79559 :             work[in * 2] = 0.;
+    5380       79559 :             work[in * 3] = (gu - gl) / 2.;
+    5381             :         }
+    5382      570005 :         rtol = eps * 4.;
+    5383      570005 :         PLUMED_BLAS_F77_FUNC(dlarrbx,DLARRBX)(&in, &d__[ibegin], &e[ibegin], &work[in * 3 + 1], &work[(in <<
+    5384      570005 :                  2) + 1], &cnt, &cnt, &rtol, &rtol, &c__0, &work[1], &work[in 
+    5385      570005 :                 + 1], &work[(in << 1) + 1], &work[in * 5 + 1], &iwork[1], &
+    5386             :                 iinfo);
+    5387      570005 :         if (sgndef > 0.) {
+    5388      490446 :             tau = work[1] - work[(in << 1) + 1];
+    5389             :         } else {
+    5390       79559 :             tau = work[in] + work[in * 3];
+    5391             :         }
+    5392             : 
+    5393      570005 :         work[in * 3] = 1.;
+    5394             :         delta = eps * 2.;
+    5395      570005 : L100:
+    5396      570005 :         tau *= 1. - delta;
+    5397             : 
+    5398      570005 :         s = -tau;
+    5399             :         j = ibegin;
+    5400      570005 :         i__2 = in - 1;
+    5401     2253752 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5402     1683747 :             work[i__] = d__[j] + s;
+    5403     1683747 :             work[(in << 1) + i__] = 1. / work[i__];
+    5404     1683747 :             work[in + i__] = e[j] * d__[j] * work[(in << 1) + i__];
+    5405     1683747 :             s = s * work[in + i__] * e[j] - tau;
+    5406     1683747 :             ++j;
+    5407             :         }
+    5408      570005 :         work[in] = d__[iend] + s;
+    5409             : 
+    5410     2823757 :         for (i__ = in; i__ >= 1; --i__) {
+    5411     2253752 :             tmp = sgndef * work[i__];
+    5412     2253752 :             if (tmp < 0. || std::abs(work[(in << 1) + i__])<PLUMED_GMX_DOUBLE_MIN || std::isnan(tmp)) {
+    5413           0 :                 delta *= 2.;
+    5414           0 :                 goto L100;
+    5415             :             }
+    5416             :         }
+    5417             : 
+    5418      570005 :         sigma += tau;
+    5419      570005 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+    5420      570005 :         i__2 = in - 1;
+    5421      570005 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+    5422      570005 :         e[iend] = sigma;
+    5423      570005 :         tmp = (double) in * 4. * eps * (std::abs(sigma) + std::abs(tau));
+    5424             :         i__2 = iend;
+    5425     2823757 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+    5426     2253752 :             gersch[(i__ << 1) - 1] = gersch[(i__ << 1) - 1] - sigma - tmp;
+    5427     2253752 :             gersch[i__ * 2] = gersch[i__ * 2] - sigma + tmp;
+    5428             :         }
+    5429             : 
+    5430             :         j = ibegin;
+    5431      570005 :         i__2 = in - 1;
+    5432     2253752 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5433     1683747 :             work[(i__ << 1) - 1] = std::abs(d__[j]);
+    5434     1683747 :             work[i__ * 2] = e[j] * e[j] * work[(i__ << 1) - 1];
+    5435     1683747 :             ++j;
+    5436             :         }
+    5437      570005 :         work[(in << 1) - 1] = std::abs(d__[iend]);
+    5438             : 
+    5439      570005 :         PLUMED_BLAS_F77_FUNC(dlasq2,DLASQ2)(&in, &work[1], info);
+    5440      570005 :         if (*info != 0) {
+    5441             :             return;
+    5442             :         }
+    5443             : 
+    5444      570005 :         if (sgndef > 0.) {
+    5445      490446 :             i__2 = in;
+    5446     2426202 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5447     1935756 :                 ++(*m);
+    5448     1935756 :                 w[*m] = work[in - i__ + 1];
+    5449     1935756 :                 iblock[*m] = jblk;
+    5450     1935756 :                 indexw[*m] = i__;
+    5451             :             }
+    5452             :         } else {
+    5453       79559 :             i__2 = in;
+    5454      397555 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5455      317996 :                 ++(*m);
+    5456      317996 :                 w[*m] = -work[i__];
+    5457      317996 :                 iblock[*m] = jblk;
+    5458      317996 :                 indexw[*m] = i__;
+    5459             :             }
+    5460             :         }
+    5461      570005 :         ibegin = iend + 1;
+    5462      570670 : L170:
+    5463             :         ;
+    5464             :     }
+    5465      570005 :     if (irange == 2) {
+    5466           0 :         *m = 0;
+    5467             :         ibegin = 1;
+    5468           0 :         i__1 = *nsplit;
+    5469           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+    5470           0 :             iend = isplit[i__];
+    5471           0 :             vvl = *vl - e[iend];
+    5472           0 :             vvu = *vu - e[iend];
+    5473           0 :             i__2 = iend;
+    5474           0 :             for (j = ibegin; j <= i__2; ++j) {
+    5475           0 :                 if (vvl <= w[j] && w[j] <= vvu) {
+    5476           0 :                     ++(*m);
+    5477           0 :                     w[*m] = w[j];
+    5478           0 :                     iblock[*m] = i__;
+    5479           0 :                     indexw[*m] = j - ibegin + 1;
+    5480             :                 }
+    5481             :             }
+    5482           0 :             ibegin = iend + 1;
+    5483             :         }
+    5484      570005 :     } else if (irange == 3) {
+    5485      562531 :         *m = *iu - *il + 1;
+    5486      562531 :         if (*nsplit == 1) {
+    5487             :             i__1 = *m;
+    5488     1139915 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5489      577394 :                 w[i__] = w[*il + i__ - 1];
+    5490      577394 :                 indexw[i__] = *il + i__ - 1;
+    5491             :             }
+    5492             :         } else {
+    5493             :             ibegin = 1;
+    5494             :             i__1 = *nsplit;
+    5495         679 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5496         669 :                 iend = isplit[i__];
+    5497         669 :                 i__2 = iend;
+    5498        1439 :                 for (j = ibegin; j <= i__2; ++j) {
+    5499         770 :                     work[j] = w[j] + e[iend];
+    5500             :                 }
+    5501         669 :                 ibegin = iend + 1;
+    5502             :             }
+    5503          10 :             i__1 = *n;
+    5504         780 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5505         770 :                 iwork[i__] = i__;
+    5506         770 :                 iwork[*n + i__] = iblock[i__];
+    5507             :             }
+    5508          10 :             PLUMED_BLAS_F77_FUNC(dlasrt2,DLASRT2)("I", n, &work[1], &iwork[1], &iinfo);
+    5509          10 :             i__1 = *m;
+    5510         777 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5511         767 :                 itmp = iwork[*il + i__ - 1];
+    5512         767 :                 work[i__] = w[itmp];
+    5513         767 :                 iblock[i__] = iwork[*n + itmp];
+    5514             :             }
+    5515          10 :             i__1 = *m;
+    5516         777 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5517         767 :                 iwork[*n + i__] = iwork[*il + i__ - 1];
+    5518         767 :                 iwork[i__] = i__;
+    5519             :             }
+    5520          10 :             PLUMED_BLAS_F77_FUNC(ilasrt2,ILASRT2)("I", m, &iblock[1], &iwork[1], &iinfo);
+    5521             :             j = 1;
+    5522          10 :             itmp = iblock[j];
+    5523          10 :             cnt = iwork[*n + iwork[j]];
+    5524          10 :             if (itmp == 1) {
+    5525             :                 ibegin = 1;
+    5526             :             } else {
+    5527           0 :                 ibegin = isplit[itmp - 1] + 1;
+    5528             :             }
+    5529          10 :             i__1 = *m;
+    5530         777 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    5531         767 :                 w[i__] = work[iwork[i__]];
+    5532         767 :                 if (iblock[i__] != itmp || i__ == *m) {
+    5533         668 :                     if (iblock[i__] == itmp) {
+    5534          10 :                         till = *m;
+    5535             :                     } else {
+    5536         658 :                         till = i__ - 1;
+    5537             :                     }
+    5538         668 :                     i__2 = till - j + 1;
+    5539         668 :                     PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("I", &i__2, &w[j], &iinfo);
+    5540         668 :                     cnt = cnt - ibegin + 1;
+    5541         668 :                     i__2 = till;
+    5542        1435 :                     for (k = j; k <= i__2; ++k) {
+    5543         767 :                         indexw[k] = cnt + k - j;
+    5544             :                     }
+    5545             :                     j = i__;
+    5546         668 :                     itmp = iblock[j];
+    5547         668 :                     cnt = iwork[*n + iwork[j]];
+    5548         668 :                     ibegin = isplit[itmp - 1] + 1;
+    5549         668 :                     if (i__ == *m && till < *m) {
+    5550           0 :                         indexw[*m] = cnt - ibegin + 1;
+    5551             :                     }
+    5552             :                 } else {
+    5553          99 :                     i__2 = cnt, i__3 = iwork[*n + iwork[i__]];
+    5554          99 :                     cnt = (i__2<i__3) ? i__2 : i__3;
+    5555             :                 }
+    5556             :             }
+    5557             :         }
+    5558             :     }
+    5559             : 
+    5560             :     return;
+    5561             : 
+    5562             : }
+    5563             : 
+    5564             : 
+    5565             : }
+    5566             : }
+    5567             : #include <cmath>
+    5568             : 
+    5569             : #include "real.h"
+    5570             : 
+    5571             : #include "blas/blas.h"
+    5572             : #include "lapack.h"
+    5573             : #include "lapack_limits.h"
+    5574             : 
+    5575             : 
+    5576             : #include "blas/blas.h"
+    5577             : namespace PLMD{
+    5578             : namespace lapack{
+    5579             : using namespace blas;
+    5580             : void
+    5581          70 : PLUMED_BLAS_F77_FUNC(dlarrfx,DLARRFX)(int *n, 
+    5582             :         double *d__, 
+    5583             :         double *l, 
+    5584             :         double *ld, 
+    5585             :         double *lld, 
+    5586             :         int *ifirst, 
+    5587             :         int *ilast, 
+    5588             :         double *w, 
+    5589             :         double *sigma, 
+    5590             :         double *dplus, 
+    5591             :         double *lplus, 
+    5592             :         double *work,
+    5593             :         int *info)
+    5594             : {
+    5595          70 :     int i1 = 1;
+    5596             :     int i__1;
+    5597             :     double d__2, d__3;
+    5598             : 
+    5599             :     int i__;
+    5600             :     double s, eps, tmp, dmax1, dmax2, delta;
+    5601          70 :     --work;
+    5602          70 :     --lplus;
+    5603          70 :     --dplus;
+    5604          70 :     --w;
+    5605             :     --lld;
+    5606          70 :     --ld;
+    5607          70 :     --l;
+    5608          70 :     --d__;
+    5609          70 :     *info = 0;
+    5610             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    5611          70 :     *sigma = w[*ifirst];
+    5612             :     delta = eps * 2.;
+    5613             : 
+    5614          70 : L10:
+    5615          70 :     s = -(*sigma);
+    5616          70 :     dplus[1] = d__[1] + s;
+    5617             :     dmax1 = std::abs(dplus[1]);
+    5618          70 :     i__1 = *n - 1;
+    5619       28278 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5620       28208 :         lplus[i__] = ld[i__] / dplus[i__];
+    5621       28208 :         s = s * lplus[i__] * l[i__] - *sigma;
+    5622       28208 :         dplus[i__ + 1] = d__[i__ + 1] + s;
+    5623             :         d__2 = dmax1, d__3 = std::abs(dplus[i__ + 1]);
+    5624       28208 :         dmax1 = (d__2>d__3) ? d__2 : d__3;
+    5625             :     }
+    5626          70 :     if (std::isnan(dmax1)) {
+    5627           0 :         *sigma -= std::abs(*sigma) * delta;
+    5628           0 :         delta *= 2.;
+    5629           0 :         goto L10;
+    5630             :     }
+    5631             : 
+    5632          70 :     tmp = w[*ilast];
+    5633             :     delta = eps * 2.;
+    5634          70 : L30:
+    5635          70 :     s = -tmp;
+    5636          70 :     work[1] = d__[1] + s;
+    5637             :     dmax2 = std::abs(work[1]);
+    5638          70 :     i__1 = *n - 1;
+    5639       28278 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5640       28208 :         work[*n + i__] = ld[i__] / work[i__];
+    5641       28208 :         s = s * work[*n + i__] * l[i__] - tmp;
+    5642       28208 :         work[i__ + 1] = d__[i__ + 1] + s;
+    5643             :         d__2 = dmax2, d__3 = std::abs(work[i__ + 1]);
+    5644       28208 :         dmax2 = (d__2>d__3) ? d__2 : d__3;
+    5645             :     }
+    5646          70 :     if (std::isnan(dmax2)) {
+    5647           0 :         tmp += std::abs(tmp) * delta;
+    5648           0 :         delta *= 2.;
+    5649           0 :         goto L30;
+    5650             :     }
+    5651          70 :     if (dmax2 < dmax1) {
+    5652          36 :         *sigma = tmp;
+    5653          36 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &work[1], &i1, &dplus[1], &i1);
+    5654          36 :         i__1 = *n - 1;
+    5655          36 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &work[*n + 1], &i1, &lplus[1], &i1);
+    5656             :     }
+    5657             : 
+    5658          70 :     return;
+    5659             : }
+    5660             : }
+    5661             : }
+    5662             : #include <cmath>
+    5663             : 
+    5664             : #include "real.h"
+    5665             : 
+    5666             : #include "blas/blas.h"
+    5667             : #include "lapack.h"
+    5668             : #include "lapack_limits.h"
+    5669             : 
+    5670             : 
+    5671             : #include "blas/blas.h"
+    5672             : namespace PLMD{
+    5673             : namespace lapack{
+    5674             : using namespace blas;
+    5675             : void
+    5676      569961 : PLUMED_BLAS_F77_FUNC(dlarrvx,DLARRVX)(int *n, 
+    5677             :         double *d__, 
+    5678             :         double *l, 
+    5679             :         int *isplit,
+    5680             :         int *m, 
+    5681             :         double *w,
+    5682             :         int *iblock, 
+    5683             :         int *indexw, 
+    5684             :         double *gersch, 
+    5685             :         double *tol, 
+    5686             :         double *z__, 
+    5687             :         int *ldz, 
+    5688             :         int *isuppz, 
+    5689             :         double *work, 
+    5690             :         int *iwork, 
+    5691             :         int *info)
+    5692             : {
+    5693             :     int z_dim1, z_offset, i__1, i__2, i__3, i__4, i__5, i__6;
+    5694             :     double d__1, d__2;
+    5695      569961 :     double c_b5 = 0.;
+    5696      569961 :     int c__1 = 1;
+    5697      569961 :     int c__2 = 2;
+    5698             : 
+    5699             :     int i__, j, k, p, q;
+    5700             :     int im, in;
+    5701             :     double gap, eps, tmp;
+    5702             :     int zto;
+    5703             :     double ztz;
+    5704             :     int iend, jblk;
+    5705             :     int wend, iter, temp[1], ktot;
+    5706             :     int itmp1, itmp2;
+    5707             :     int indld;
+    5708             :     double sigma;
+    5709             :     int ndone, iinfo, iindr;
+    5710             :     double resid;
+    5711             :     int nomgs;
+    5712             :     int nclus;
+    5713             :     int zfrom, iindc1, iindc2;
+    5714             :     double lambda;
+    5715             :     int ibegin;
+    5716             :     int indgap, indlld;
+    5717             :     double mingma;
+    5718             :     int oldien, oldncl, wbegin;
+    5719             :     double relgap;
+    5720             :     int oldcls;
+    5721             :     int ndepth, inderr, iindwk;
+    5722             :     int newcls, oldfst;
+    5723             :     double minrgp=0.0;
+    5724             :     int indwrk, oldlst;
+    5725             :     double reltol;
+    5726             :     int newfrs, newftt, parity;
+    5727             :     double mgstol, nrminv, rqcorr;
+    5728             :     int newlst, newsiz;
+    5729             : 
+    5730             : 
+    5731      569961 :     --d__;
+    5732      569961 :     --l;
+    5733             :     --isplit;
+    5734      569961 :     --w;
+    5735      569961 :     --iblock;
+    5736      569961 :     --indexw;
+    5737             :     --gersch;
+    5738      569961 :     z_dim1 = *ldz;
+    5739      569961 :     z_offset = 1 + z_dim1;
+    5740      569961 :     z__ -= z_offset;
+    5741      569961 :     --isuppz;
+    5742      569961 :     --work;
+    5743      569961 :     --iwork;
+    5744             : 
+    5745      569961 :     inderr = *n;
+    5746      569961 :     indld = *n << 1;
+    5747      569961 :     indlld = *n * 3;
+    5748      569961 :     indgap = *n << 2;
+    5749      569961 :     indwrk = *n * 5 + 1;
+    5750             : 
+    5751             :     iindr = *n;
+    5752             :     iindc1 = *n << 1;
+    5753             :     iindc2 = *n * 3;
+    5754      569961 :     iindwk = (*n << 2) + 1;
+    5755             : 
+    5756             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    5757             : 
+    5758             :     i__1 = *n << 1;
+    5759     5078531 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    5760     4508570 :         iwork[i__] = 0;
+    5761             :     }
+    5762      569961 :     PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("Full", n, m, &c_b5, &c_b5, &z__[z_offset], ldz);
+    5763             :     mgstol = eps * 100.;
+    5764             : 
+    5765             :     ibegin = 1;
+    5766             :     wbegin = 1;
+    5767      569961 :     i__1 = iblock[*m];
+    5768     1140586 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+    5769      570625 :         iend = isplit[jblk];
+    5770             : 
+    5771      570625 :         wend = wbegin - 1;
+    5772     1178150 : L171:
+    5773     1178150 :         if (wend < *m) {
+    5774      608189 :             if (iblock[wend + 1] == jblk) {
+    5775      607525 :                 ++wend;
+    5776      607525 :                 goto L171;
+    5777             :             }
+    5778             :         }
+    5779      570625 :         if (wend < wbegin) {
+    5780           0 :             ibegin = iend + 1;
+    5781           0 :             continue;
+    5782             :         }
+    5783             : 
+    5784      570625 :         if (ibegin == iend) {
+    5785         665 :             z__[ibegin + wbegin * z_dim1] = 1.;
+    5786         665 :             isuppz[(wbegin << 1) - 1] = ibegin;
+    5787         665 :             isuppz[wbegin * 2] = ibegin;
+    5788         665 :             ibegin = iend + 1;
+    5789         665 :             wbegin = wend + 1;
+    5790         665 :             continue;
+    5791             :         }
+    5792      569960 :         oldien = ibegin - 1;
+    5793      569960 :         in = iend - oldien;
+    5794      569960 :         d__1 = .001, d__2 = 1. / (double) in;
+    5795      569960 :         reltol = (d__1<d__2) ? d__1 : d__2;
+    5796      569960 :         im = wend - wbegin + 1;
+    5797      569960 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&im, &w[wbegin], &c__1, &work[1], &c__1);
+    5798      569960 :         i__2 = im - 1;
+    5799      606860 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    5800       36900 :             work[inderr + i__] = eps * std::abs(work[i__]);
+    5801       36900 :             work[indgap + i__] = work[i__ + 1] - work[i__];
+    5802             :         }
+    5803      569960 :         work[inderr + im] = eps * std::abs(work[im]);
+    5804      569960 :         d__2 = std::abs(work[im]);
+    5805      569960 :         work[indgap + im] = (d__2>eps) ? d__2 : eps;
+    5806             :         ndone = 0;
+    5807             : 
+    5808             :         ndepth = 0;
+    5809             :         parity = 1;
+    5810             :         nclus = 1;
+    5811      569960 :         iwork[iindc1 + 1] = 1;
+    5812      569960 :         iwork[iindc1 + 2] = im;
+    5813             : 
+    5814     1139927 : L40:
+    5815     1139927 :         if (ndone < im) {
+    5816             :             oldncl = nclus;
+    5817             :             nclus = 0;
+    5818      569967 :             parity = 1 - parity;
+    5819      569967 :             if (parity == 0) {
+    5820             :                 oldcls = iindc1;
+    5821             :                 newcls = iindc2;
+    5822             :             } else {
+    5823             :                 oldcls = iindc2;
+    5824             :                 newcls = iindc1;
+    5825             :             }
+    5826             :             i__2 = oldncl;
+    5827     1139997 :             for (i__ = 1; i__ <= i__2; ++i__) {
+    5828             : 
+    5829      570030 :                 j = oldcls + (i__ << 1);
+    5830      570030 :                 oldfst = iwork[j - 1];
+    5831      570030 :                 oldlst = iwork[j];
+    5832      570030 :                 if (ndepth > 0) {
+    5833          70 :                     j = wbegin + oldfst - 1;
+    5834          70 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&in, &z__[ibegin + j * z_dim1], &c__1, &d__[ibegin]
+    5835             :                             , &c__1);
+    5836          70 :                     i__3 = in - 1;
+    5837          70 :                     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__3, &z__[ibegin + (j + 1) * z_dim1], &c__1, &l[
+    5838             :                             ibegin], &c__1);
+    5839          70 :                     PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("Full", &in, &c__2, &c_b5, &c_b5, &z__[ibegin + j 
+    5840             :                             * z_dim1], ldz);
+    5841             :                 }
+    5842             :                 k = ibegin;
+    5843      570030 :                 i__3 = in - 1;
+    5844     2281895 :                 for (j = 1; j <= i__3; ++j) {
+    5845     1711865 :                     tmp = d__[k] * l[k];
+    5846     1711865 :                     work[indld + j] = tmp;
+    5847     1711865 :                     work[indlld + j] = tmp * l[k];
+    5848     1711865 :                     ++k;
+    5849             :                 }
+    5850      570030 :                 if (ndepth > 0) {
+    5851             : 
+    5852          70 :                     p = indexw[wbegin - 1 + oldfst];
+    5853          70 :                     q = indexw[wbegin - 1 + oldlst];
+    5854          70 :                     d__1 = eps * 4.;
+    5855          70 :                     i__3 = p - oldfst;
+    5856          70 :                     PLUMED_BLAS_F77_FUNC(dlarrbx,DLARRBX)(&in, &d__[ibegin], &l[ibegin], &work[indld + 1], &
+    5857          70 :                             work[indlld + 1], &p, &q, &reltol, &d__1, &i__3, &
+    5858          70 :                             work[1], &work[indgap + 1], &work[inderr + 1], &
+    5859          70 :                             work[indwrk + in], &iwork[iindwk], &iinfo);
+    5860             :                 }
+    5861      570030 :                 newfrs = oldfst;
+    5862      570030 :                 i__3 = oldlst;
+    5863     1177826 :                 for (j = oldfst; j <= i__3; ++j) {
+    5864      607796 :                     if (j == oldlst || work[indgap + j] >= 
+    5865       37766 :                         reltol * std::abs(work[j])) {
+    5866      606930 :                         newlst = j;
+    5867             :                     } else {
+    5868             : 
+    5869         866 :                         relgap = work[indgap + j] / std::abs(work[j]);
+    5870         866 :                         if (j == newfrs) {
+    5871             :                             minrgp = relgap;
+    5872             :                         } else {
+    5873         796 :                             minrgp = (minrgp<relgap) ? minrgp : relgap;
+    5874             :                         }
+    5875         866 :                         continue;
+    5876             :                     }
+    5877      606930 :                     newsiz = newlst - newfrs + 1;
+    5878      606930 :                     newftt = wbegin + newfrs - 1;
+    5879      606930 :                     nomgs = newsiz == 1 || newsiz > 1 || minrgp < mgstol;
+    5880      606930 :                     if (newsiz > 1 && nomgs) {
+    5881             : 
+    5882          70 :                         PLUMED_BLAS_F77_FUNC(dlarrfx,DLARRFX)(&in, &d__[ibegin], &l[ibegin], &work[indld + 
+    5883          70 :                                 1], &work[indlld + 1], &newfrs, &newlst, &
+    5884          70 :                                 work[1], &sigma, &z__[ibegin + newftt * 
+    5885          70 :                                 z_dim1], &z__[ibegin + (newftt + 1) * z_dim1],
+    5886          70 :                                  &work[indwrk], info);
+    5887          70 :                         if (*info == 0) {
+    5888          70 :                             tmp = eps * std::abs(sigma);
+    5889          70 :                             i__4 = newlst;
+    5890        1006 :                             for (k = newfrs; k <= i__4; ++k) {
+    5891         936 :                                 work[k] -= sigma;
+    5892         936 :                                 d__1 = work[indgap + k];
+    5893         936 :                                 work[indgap + k] = (d__1>tmp) ? d__1 : tmp;
+    5894         936 :                                 work[inderr + k] += tmp;
+    5895             :                             }
+    5896          70 :                             ++nclus;
+    5897          70 :                             k = newcls + (nclus << 1);
+    5898          70 :                             iwork[k - 1] = newfrs;
+    5899          70 :                             iwork[k] = newlst;
+    5900             :                         } else {
+    5901           0 :                             *info = 0;
+    5902           0 :                             if (minrgp < mgstol) {
+    5903           0 :                                 work[indwrk] = d__[ibegin];
+    5904           0 :                                 i__4 = in - 1;
+    5905           0 :                                 for (k = 1; k <= i__4; ++k) {
+    5906           0 :                                     work[indwrk + k] = d__[ibegin + k] + work[
+    5907           0 :                                             indlld + k];
+    5908             :                                 }
+    5909           0 :                                 i__4 = newsiz;
+    5910           0 :                                 for (k = 1; k <= i__4; ++k) {
+    5911           0 :                                     iwork[iindwk + k - 1] = 1;
+    5912             :                                 }
+    5913           0 :                                 i__4 = newlst;
+    5914           0 :                                 for (k = newfrs; k <= i__4; ++k) {
+    5915           0 :                                     isuppz[2*(oldien + k) - 1] = 1;
+    5916           0 :                                     isuppz[(oldien + k) * 2] = in;
+    5917             :                                 }
+    5918           0 :                                 temp[0] = in;
+    5919           0 :                                 PLUMED_BLAS_F77_FUNC(dstein,DSTEIN)(&in, &work[indwrk], &work[indld + 1], 
+    5920           0 :                                         &newsiz, &work[newfrs], &iwork[iindwk]
+    5921             :                                         , temp, &z__[ibegin + newftt * z_dim1]
+    5922           0 :                                         , ldz, &work[indwrk + in], &iwork[
+    5923           0 :                                         iindwk + in], &iwork[iindwk + (in*2)], &iinfo);
+    5924           0 :                                 if (iinfo != 0) {
+    5925           0 :                                     *info = 2;
+    5926           0 :                                     return;
+    5927             :                                 }
+    5928           0 :                                 ndone += newsiz;
+    5929             :                             }
+    5930             :                         }
+    5931             :                     } else {
+    5932             :                         ktot = newftt;
+    5933             :                         i__4 = newlst;
+    5934     1213720 :                         for (k = newfrs; k <= i__4; ++k) {
+    5935             :                             iter = 0;
+    5936      608131 : L90:
+    5937      608131 :                             lambda = work[k];
+    5938             : 
+    5939      608131 :                             PLUMED_BLAS_F77_FUNC(dlar1vx,DLAR1VX)(&in, &c__1, &in, &lambda, &d__[ibegin], &
+    5940      608131 :                                     l[ibegin], &work[indld + 1], &work[indlld 
+    5941      608131 :                                     + 1], &w[wbegin + k - 1], &gersch[(oldien 
+    5942      608131 :                                     << 1) + 1], &z__[ibegin + ktot * z_dim1], 
+    5943      608131 :                                     &ztz, &mingma, &iwork[iindr + ktot], &
+    5944      608131 :                                     isuppz[(ktot << 1) - 1], &work[indwrk]);
+    5945      608131 :                             tmp = 1. / ztz;
+    5946      608131 :                             nrminv =  std::sqrt(tmp);
+    5947      608131 :                             resid = std::abs(mingma) * nrminv;
+    5948      608131 :                             rqcorr = mingma * tmp;
+    5949      608131 :                             if (k == in) {
+    5950       21044 :                                 gap = work[indgap + k - 1];
+    5951      587087 :                             } else if (k == 1) {
+    5952      570466 :                                 gap = work[indgap + k];
+    5953             :                             } else {
+    5954       16621 :                                 d__1 = work[indgap + k - 1], d__2 = work[
+    5955       16621 :                                         indgap + k];
+    5956       16621 :                                 gap = (d__1<d__2) ? d__1 : d__2;
+    5957             :                             }
+    5958      608131 :                             ++iter;
+    5959      608131 :                             if (resid > *tol * gap && std::abs(rqcorr) > eps * 4. *
+    5960        8164 :                                      std::abs(lambda)) {
+    5961        1283 :                                 work[k] = lambda + rqcorr;
+    5962        1283 :                                 if (iter < 8) {
+    5963        1271 :                                     goto L90;
+    5964             :                                 }
+    5965             :                             }
+    5966      606860 :                             iwork[ktot] = 1;
+    5967      606860 :                             if (newsiz == 1) {
+    5968      606860 :                                 ++ndone;
+    5969             :                             }
+    5970      606860 :                             zfrom = isuppz[(ktot << 1) - 1];
+    5971      606860 :                             zto = isuppz[ktot * 2];
+    5972      606860 :                             i__5 = zto - zfrom + 1;
+    5973      606860 :                             PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__5, &nrminv, &z__[ibegin + zfrom - 1 + 
+    5974      606860 :                                     ktot * z_dim1], &c__1);
+    5975      606860 :                             ++ktot;
+    5976             :                         }
+    5977      606860 :                         if (newsiz > 1) {
+    5978           0 :                             itmp1 = isuppz[(newftt << 1) - 1];
+    5979           0 :                             itmp2 = isuppz[newftt * 2];
+    5980           0 :                             ktot = oldien + newlst;
+    5981             :                             i__4 = ktot;
+    5982           0 :                             for (p = newftt + 1; p <= i__4; ++p) {
+    5983           0 :                                 i__5 = p - 1;
+    5984           0 :                                 for (q = newftt; q <= i__5; ++q) {
+    5985           0 :                                     tmp = -PLUMED_BLAS_F77_FUNC(ddot,DDOT)(&in, &z__[ibegin + p * 
+    5986           0 :                                             z_dim1], &c__1, &z__[ibegin + q * 
+    5987           0 :                                             z_dim1], &c__1);
+    5988           0 :                                     PLUMED_BLAS_F77_FUNC(daxpy,DAXPY)(&in, &tmp, &z__[ibegin + q * 
+    5989           0 :                                             z_dim1], &c__1, &z__[ibegin + p * 
+    5990           0 :                                             z_dim1], &c__1);
+    5991             :                                 }
+    5992           0 :                                 tmp = 1. / PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(&in, &z__[ibegin + p * 
+    5993           0 :                                         z_dim1], &c__1);
+    5994           0 :                                 PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&in, &tmp, &z__[ibegin + p * z_dim1], &
+    5995             :                                         c__1);
+    5996           0 :                                 i__5 = itmp1, i__6 = isuppz[(p << 1) - 1];
+    5997             :                                 itmp1 = (i__5<i__6) ? i__5 : i__6;
+    5998           0 :                                 i__5 = itmp2, i__6 = isuppz[p * 2];
+    5999             :                                 itmp2 = (i__5>i__6) ? i__5 : i__6;
+    6000             :                             }
+    6001             :                             i__4 = ktot;
+    6002           0 :                             for (p = newftt; p <= i__4; ++p) {
+    6003           0 :                                 isuppz[(p << 1) - 1] = itmp1;
+    6004           0 :                                 isuppz[p * 2] = itmp2;
+    6005             :                             }
+    6006           0 :                             ndone += newsiz;
+    6007             :                         }
+    6008             :                     }
+    6009      606930 :                     newfrs = j + 1;
+    6010             :                 }
+    6011             :             }
+    6012      569967 :             ++ndepth;
+    6013      569967 :             goto L40;
+    6014             :         }
+    6015      569960 :         j = wbegin << 1;
+    6016             :         i__2 = wend;
+    6017     1176820 :         for (i__ = wbegin; i__ <= i__2; ++i__) {
+    6018      606860 :             isuppz[j - 1] += oldien;
+    6019      606860 :             isuppz[j] += oldien;
+    6020      606860 :             j += 2;
+    6021             : 
+    6022             :         }
+    6023      569960 :         ibegin = iend + 1;
+    6024      569960 :         wbegin = wend + 1;
+    6025             :     }
+    6026             : 
+    6027             :     return;
+    6028             : 
+    6029             : } 
+    6030             : }
+    6031             : }
+    6032             : #include <cmath>
+    6033             : #include "lapack.h"
+    6034             : #include "lapack_limits.h"
+    6035             : 
+    6036             : #include "real.h"
+    6037             : 
+    6038             : #include "blas/blas.h"
+    6039             : namespace PLMD{
+    6040             : namespace lapack{
+    6041             : using namespace blas;
+    6042             : void
+    6043       90519 : PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(double *f,
+    6044             :         double *g,
+    6045             :         double *cs,
+    6046             :         double *sn,
+    6047             :         double *r)
+    6048             : {
+    6049             :   double minval,safemin, safemin2, safemx2, eps;
+    6050             :   double f1,g1,f1a,g1a,scale;
+    6051             :   int i,n,count;
+    6052             : 
+    6053             :   eps = PLUMED_GMX_DOUBLE_EPS;
+    6054             :   minval = PLUMED_GMX_DOUBLE_MIN;
+    6055             :   safemin = minval*(1.0+eps);
+    6056             :   n = static_cast<int>(0.5*std::log( safemin/eps ) / std::log(2.0));
+    6057             :   safemin2 = std::pow(2.0,static_cast<double>(n));
+    6058             : 
+    6059             :   safemx2 = 1.0 / safemin2;
+    6060             : 
+    6061       90519 :   if(std::abs(*g)<PLUMED_GMX_DOUBLE_MIN) {
+    6062           0 :     *cs = 1.0;
+    6063           0 :     *sn = 0.0;
+    6064           0 :     *r = *f;
+    6065       90519 :   } else if (std::abs(*f)<PLUMED_GMX_DOUBLE_MIN) {
+    6066           1 :     *cs = 0.0;
+    6067           1 :     *sn = 1.0;
+    6068           1 :     *r = *g;
+    6069             :   } else {
+    6070             :     f1 = *f;
+    6071             :     g1 = *g;
+    6072             :     f1a = std::abs(f1);
+    6073             :     g1a = std::abs(g1);
+    6074       90518 :     scale = (f1a > g1a) ? f1a : g1a;
+    6075       90518 :     if(scale >= safemx2) {
+    6076             :       count = 0;
+    6077           0 :       while(scale >= safemx2) {
+    6078           0 :         count++;
+    6079           0 :         f1 *= safemin2;
+    6080           0 :         g1 *= safemin2;
+    6081             :         f1a = std::abs(f1);
+    6082             :         g1a = std::abs(g1);
+    6083           0 :         scale = (f1a > g1a) ? f1a : g1a;
+    6084             :       }
+    6085           0 :       *r =  std::sqrt(f1*f1 + g1*g1);
+    6086           0 :       *cs = f1 / *r;
+    6087           0 :       *sn = g1 / *r;
+    6088           0 :       for(i=0;i<count;i++)
+    6089           0 :         *r *= safemx2;
+    6090       90518 :     } else if (scale<=safemin2) {
+    6091             :       count = 0;
+    6092           0 :       while(scale <= safemin2) {
+    6093           0 :         count++;
+    6094           0 :         f1 *= safemx2;
+    6095           0 :         g1 *= safemx2;
+    6096             :         f1a = std::abs(f1);
+    6097             :         g1a = std::abs(g1);
+    6098           0 :         scale = (f1a > g1a) ? f1a : g1a;
+    6099             :       }
+    6100           0 :       *r =  std::sqrt(f1*f1 + g1*g1);
+    6101           0 :       *cs = f1 / *r;
+    6102           0 :       *sn = g1 / *r;
+    6103           0 :       for(i=0;i<count;i++)
+    6104           0 :         *r *= safemin2;
+    6105             :     } else {
+    6106       90518 :       *r =  std::sqrt(f1*f1 + g1*g1);
+    6107       90518 :       *cs = f1 / *r;
+    6108       90518 :       *sn = g1 / *r;
+    6109             :     }
+    6110       90518 :     if(std::abs(*f)>std::abs(*g) && *cs<0.0) {
+    6111       18497 :       *cs *= -1.0;
+    6112       18497 :       *sn *= -1.0;
+    6113       18497 :       *r  *= -1.0;
+    6114             :     }
+    6115             :   }
+    6116       90519 :   return;
+    6117             : }
+    6118             :       
+    6119             : }
+    6120             : }
+    6121             : #include <cmath>
+    6122             : #include "lapack.h"
+    6123             : 
+    6124             : #include "blas/blas.h"
+    6125             : namespace PLMD{
+    6126             : namespace lapack{
+    6127             : using namespace blas;
+    6128             : void
+    6129           0 : PLUMED_BLAS_F77_FUNC(dlaruv,DLARUV)(int *iseed, int *n, double *x)
+    6130             : {
+    6131             :   const int
+    6132           0 :     mm[512] = {
+    6133             :       494,2637,255,2008,1253,
+    6134             :       3344,4084,1739,3143,3468,688,1657,1238,3166,1292,3422,1270,2016,
+    6135             :       154,2862,697,1706,491,931,1444,444,3577,3944,2184,1661,3482,657,
+    6136             :       3023,3618,1267,1828,164,3798,3087,2400,2870,3876,1905,1593,1797,
+    6137             :       1234,3460,328,2861,1950,617,2070,3331,769,1558,2412,2800,189,287,
+    6138             :       2045,1227,2838,209,2770,3654,3993,192,2253,3491,2889,2857,2094,
+    6139             :       1818,688,1407,634,3231,815,3524,1914,516,164,303,2144,3480,119,
+    6140             :       3357,837,2826,2332,2089,3780,1700,3712,150,2000,3375,1621,3090,
+    6141             :       3765,1149,3146,33,3082,2741,359,3316,1749,185,2784,2202,2199,1364,
+    6142             :       1244,2020,3160,2785,2772,1217,1822,1245,2252,3904,2774,997,2573,
+    6143             :       1148,545,322,789,1440,752,2859,123,1848,643,2405,2638,2344,46,
+    6144             :       3814,913,3649,339,3808,822,2832,3078,3633,2970,637,2249,2081,4019,
+    6145             :       1478,242,481,2075,4058,622,3376,812,234,641,4005,1122,3135,2640,
+    6146             :       2302,40,1832,2247,2034,2637,1287,1691,496,1597,2394,2584,1843,336,
+    6147             :       1472,2407,433,2096,1761,2810,566,442,41,1238,1086,603,840,3168,
+    6148             :       1499,1084,3438,2408,1589,2391,288,26,512,1456,171,1677,2657,2270,
+    6149             :       2587,2961,1970,1817,676,1410,3723,2803,3185,184,663,499,3784,1631,
+    6150             :       1925,3912,1398,1349,1441,2224,2411,1907,3192,2786,382,37,759,2948,
+    6151             :       1862,3802,2423,2051,2295,1332,1832,2405,3638,3661,327,3660,716,
+    6152             :       1842,3987,1368,1848,2366,2508,3754,1766,3572,2893,307,1297,3966,
+    6153             :       758,2598,3406,2922,1038,2934,2091,2451,1580,1958,2055,1507,1078,
+    6154             :       3273,17,854,2916,3971,2889,3831,2621,1541,893,736,3992,787,2125,
+    6155             :       2364,2460,257,1574,3912,1216,3248,3401,2124,2762,149,2245,166,466,
+    6156             :       4018,1399,190,2879,153,2320,18,712,2159,2318,2091,3443,1510,449,
+    6157             :       1956,2201,3137,3399,1321,2271,3667,2703,629,2365,2431,1113,3922,
+    6158             :       2554,184,2099,3228,4012,1921,3452,3901,572,3309,3171,817,3039,
+    6159             :       1696,1256,3715,2077,3019,1497,1101,717,51,981,1978,1813,3881,76,
+    6160             :       3846,3694,1682,124,1660,3997,479,1141,886,3514,1301,3604,1888,
+    6161             :       1836,1990,2058,692,1194,20,3285,2046,2107,3508,3525,3801,2549,
+    6162             :       1145,2253,305,3301,1065,3133,2913,3285,1241,1197,3729,2501,1673,
+    6163             :       541,2753,949,2361,1165,4081,2725,3305,3069,3617,3733,409,2157,
+    6164             :       1361,3973,1865,2525,1409,3445,3577,77,3761,2149,1449,3005,225,85,
+    6165             :       3673,3117,3089,1349,2057,413,65,1845,697,3085,3441,1573,3689,2941,
+    6166             :       929,533,2841,4077,721,2821,2249,2397,2817,245,1913,1997,3121,997,
+    6167             :       1833,2877,1633,981,2009,941,2449,197,2441,285,1473,2741,3129,909,
+    6168             :       2801,421,4073,2813,2337,1429,1177,1901,81,1669,2633,2269,129,1141,
+    6169             :       249,3917,2481,3941,2217,2749,3041,1877,345,2861,1809,3141,2825,
+    6170             :       157,2881,3637,1465,2829,2161,3365,361,2685,3745,2325,3609,3821,
+    6171             :       3537,517,3017,2141,1537 
+    6172             :     };
+    6173             : 
+    6174             :     int i__1;
+    6175             : 
+    6176             :     int i__, i1, i2, i3, i4, it1, it2, it3, it4;
+    6177             : 
+    6178             : 
+    6179             :     --iseed;
+    6180             :     --x;
+    6181             : 
+    6182             :     it1 = it2 = it3 = it4 = 0;
+    6183             : 
+    6184           0 :     i1 = iseed[1];
+    6185           0 :     i2 = iseed[2];
+    6186           0 :     i3 = iseed[3];
+    6187           0 :     i4 = iseed[4];
+    6188             : 
+    6189           0 :     i__1 = (*n<128) ? *n : 128;
+    6190           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    6191             : 
+    6192           0 :         it4 = i4 * mm[i__ + 383];
+    6193           0 :         it3 = it4 / 4096;
+    6194           0 :         it4 -= it3 << 12;
+    6195           0 :         it3 = it3 + i3 * mm[i__ + 383] + i4 * mm[i__ + 255];
+    6196           0 :         it2 = it3 / 4096;
+    6197           0 :         it3 -= it2 << 12;
+    6198           0 :         it2 = it2 + i2 * mm[i__ + 383] + i3 * mm[i__ + 255] + 
+    6199           0 :           i4 * mm[i__ + 127];
+    6200           0 :         it1 = it2 / 4096;
+    6201           0 :         it2 -= it1 << 12;
+    6202           0 :         it1 = it1 + i1 * mm[i__ + 383] + i2 * mm[i__ + 255] + 
+    6203           0 :           i3 * mm[i__ + 127] + i4 * mm[i__ - 1];
+    6204           0 :         it1 %= 4096;
+    6205             : 
+    6206           0 :         x[i__] = ((double) it1 + ((double) it2 + ((double) it3 + (
+    6207           0 :                 double) it4 * 2.44140625e-4) * 2.44140625e-4) * 
+    6208           0 :                 2.44140625e-4) * 2.44140625e-4;
+    6209             :     }
+    6210             : 
+    6211           0 :     iseed[1] = it1;
+    6212           0 :     iseed[2] = it2;
+    6213           0 :     iseed[3] = it3;
+    6214           0 :     iseed[4] = it4;
+    6215           0 :     return;
+    6216             : 
+    6217             : } 
+    6218             : }
+    6219             : }
+    6220             : #include <cmath>
+    6221             : #include "real.h"
+    6222             : 
+    6223             : #include "lapack.h"
+    6224             : 
+    6225             : #include "blas/blas.h"
+    6226             : namespace PLMD{
+    6227             : namespace lapack{
+    6228             : using namespace blas;
+    6229             : void
+    6230        4552 : PLUMED_BLAS_F77_FUNC(dlas2,DLAS2)(double *f,
+    6231             :        double *g,
+    6232             :        double *h,
+    6233             :        double *ssmin,
+    6234             :        double *ssmax)
+    6235             : {
+    6236        4552 :   double fa = std::abs(*f);
+    6237        4552 :   double ga = std::abs(*g);
+    6238        4552 :   double ha = std::abs(*h);
+    6239             :   double fhmin,fhmax,tmax,tmin,tmp1,tmp2;
+    6240             :   double as,at,au,c;
+    6241             : 
+    6242        4552 :   fhmin = (fa<ha) ? fa : ha;
+    6243        4552 :   fhmax = (fa>ha) ? fa : ha;
+    6244             :   
+    6245        4552 :   if(std::abs(fhmin)<PLUMED_GMX_DOUBLE_MIN) {
+    6246           0 :     *ssmin = 0.0;
+    6247           0 :     if(std::abs(fhmax)<PLUMED_GMX_DOUBLE_MIN) 
+    6248           0 :       *ssmax = ga;
+    6249             :     else {
+    6250           0 :       tmax = (fhmax>ga) ? fhmax : ga;
+    6251           0 :       tmin = (fhmax<ga) ? fhmax : ga;
+    6252           0 :       tmp1 = tmin / tmax;
+    6253           0 :       tmp1 = tmp1 * tmp1;
+    6254           0 :       *ssmax = tmax* std::sqrt(1.0 + tmp1);
+    6255             :     }
+    6256             :   } else {
+    6257        4552 :     if(ga<fhmax) {
+    6258        4526 :       as = 1.0 + fhmin / fhmax;
+    6259        4526 :       at = (fhmax-fhmin) / fhmax;
+    6260        4526 :       au = (ga/fhmax);
+    6261        4526 :       au = au * au;
+    6262        4526 :       c = 2.0 / (  std::sqrt(as*as+au) + std::sqrt(at*at+au) );
+    6263        4526 :       *ssmin = fhmin * c;
+    6264        4526 :       *ssmax = fhmax / c;
+    6265             :     } else {
+    6266          26 :       au = fhmax / ga;
+    6267          26 :       if(std::abs(au)<PLUMED_GMX_DOUBLE_MIN) {
+    6268           0 :         *ssmin = (fhmin*fhmax)/ga;
+    6269           0 :         *ssmax = ga;
+    6270             :       } else {
+    6271          26 :         as = 1.0 + fhmin / fhmax;
+    6272          26 :         at = (fhmax-fhmin)/fhmax;
+    6273          26 :         tmp1 = as*au;
+    6274          26 :         tmp2 = at*au;
+    6275          26 :         c = 1.0 / (  std::sqrt(1.0+tmp1*tmp1) + std::sqrt(1.0+tmp2*tmp2));
+    6276          26 :         *ssmin = (fhmin*c)*au;
+    6277          26 :         *ssmin = *ssmin + *ssmin;
+    6278          26 :         *ssmax = ga / (c+c);
+    6279             :       }
+    6280             :     }
+    6281             :   }
+    6282        4552 :   return;
+    6283             : }
+    6284             : }
+    6285             : }
+    6286             : #include <cctype>
+    6287             : #include <cmath>
+    6288             : #include "real.h"
+    6289             : 
+    6290             : #include "lapack.h"
+    6291             : #include "lapack_limits.h"
+    6292             : 
+    6293             : 
+    6294             : #include "blas/blas.h"
+    6295             : namespace PLMD{
+    6296             : namespace lapack{
+    6297             : using namespace blas;
+    6298             : void
+    6299         264 : PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)(const char *type,
+    6300             :                         int *kl,
+    6301             :                         int *ku,
+    6302             :                         double *cfrom,
+    6303             :                         double *cto,
+    6304             :                         int *m,
+    6305             :                         int *n,
+    6306             :                         double *a,
+    6307             :                         int *lda,
+    6308             :                         int *info)
+    6309             : {
+    6310         264 :   const char ch=std::toupper(*type);
+    6311             :   int i,j,k,l,k1,k2,k3,k4;
+    6312             :   int done=0;
+    6313             :   double minval,smlnum,bignum;
+    6314             :   double cfromc, ctoc, cfrom1, cto1, mul;
+    6315             : 
+    6316         264 :   if(*n<=0 || *m<=0)
+    6317             :     return;
+    6318             : 
+    6319             :   minval = PLUMED_GMX_DOUBLE_MIN;
+    6320             :   smlnum = minval / PLUMED_GMX_DOUBLE_EPS;
+    6321             :   bignum = 1.0 / smlnum;
+    6322             : 
+    6323         264 :   cfromc = *cfrom;
+    6324         264 :   ctoc   = *cto;
+    6325             : 
+    6326         528 :   while(!done) {
+    6327             :     
+    6328         264 :     cfrom1 = cfromc * smlnum;
+    6329         264 :     cto1   = ctoc / bignum;
+    6330             : 
+    6331         264 :     if(std::abs(cfrom1)>std::abs(ctoc) && std::abs(ctoc)>PLUMED_GMX_DOUBLE_MIN) {
+    6332             :       mul = smlnum;
+    6333             :       done = 0;
+    6334             :       cfromc = cfrom1;
+    6335         264 :     } else if(std::abs(cto1)>std::abs(cfromc)) {
+    6336             :       mul = bignum;
+    6337             :       done = 0;
+    6338             :       ctoc = cto1;
+    6339             :     } else {
+    6340         264 :       mul = ctoc / cfromc;
+    6341             :       done = 1;
+    6342             :     }
+    6343             : 
+    6344         264 :     switch(ch) {
+    6345             :     case 'G': 
+    6346             :       /* Full matrix */
+    6347         528 :       for(j=0;j<*n;j++)
+    6348       14544 :         for(i=0;i<*m;i++)
+    6349       14280 :           a[j*(*lda)+i] *= mul;
+    6350             :       break;
+    6351             : 
+    6352             :     case 'L': 
+    6353             :       /* Lower triangular matrix */
+    6354           0 :       for(j=0;j<*n;j++)
+    6355           0 :         for(i=j;i<*m;i++)
+    6356           0 :           a[j*(*lda)+i] *= mul;
+    6357             :       break;
+    6358             : 
+    6359             :     case 'U': 
+    6360             :       /* Upper triangular matrix */
+    6361           0 :       for(j=0;j<*n;j++) {
+    6362           0 :         k = (j < (*m-1)) ? j : (*m-1);
+    6363           0 :         for(i=0;i<=k;i++)
+    6364           0 :           a[j*(*lda)+i] *= mul;
+    6365             :       }
+    6366             :       break;
+    6367             : 
+    6368             :     case 'H': 
+    6369             :       /* Upper Hessenberg matrix */
+    6370           0 :       for(j=0;j<*n;j++) {
+    6371           0 :         k = ((j+1) < (*m-1)) ? (j+1) : (*m-1);
+    6372           0 :         for(i=0;i<=k;i++)
+    6373           0 :           a[j*(*lda)+i] *= mul;
+    6374             :       }
+    6375             :       break;
+    6376             : 
+    6377           0 :     case 'B': 
+    6378             :       /* Symmetric band matrix, lower bandwidth KL, upper KU,
+    6379             :        * only the lower half stored.
+    6380             :        */
+    6381           0 :       k3 = *kl;
+    6382           0 :       k4 = *n - 1;
+    6383           0 :       for(j=0;j<*n;j++) {
+    6384           0 :         k = (k3 < (k4-j)) ? k3 : (k4-j);
+    6385           0 :         for(i=0;i<=k;i++)
+    6386           0 :           a[j*(*lda)+i] *= mul;
+    6387             :       }
+    6388             :       break;
+    6389             : 
+    6390           0 :     case 'Q': 
+    6391             :       /* Symmetric band matrix, lower bandwidth KL, upper KU,
+    6392             :        * only the upper half stored.
+    6393             :        */
+    6394           0 :       k1 = *ku;
+    6395             :       k3 = *ku;
+    6396           0 :       for(j=0;j<*n;j++) {
+    6397           0 :         k = ((k1-j) > 0) ? (k1-j) : 0;
+    6398           0 :         for(i=k;i<=k3;i++)
+    6399           0 :           a[j*(*lda)+i] *= mul;
+    6400             :       }
+    6401             :       break;
+    6402             : 
+    6403           0 :     case 'Z': 
+    6404             :       /* Band matrix, lower bandwidth KL, upper KU. */
+    6405             : 
+    6406           0 :       k1 = *kl + *ku;
+    6407             :       k2 = *kl;
+    6408           0 :       k3 = 2*(*kl) + *ku;
+    6409           0 :       k4 = *kl + *ku - 1 + *m;
+    6410           0 :       for(j=0;j<*n;j++) {
+    6411           0 :         k = ((k1-j) > k2) ? (k1-j) : k2;
+    6412           0 :         l = (k3 < (k4-j)) ? k3 : (k4-j);
+    6413           0 :         for(i=k;i<=l;i++)
+    6414           0 :           a[j*(*lda)+i] *= mul;
+    6415             :       }
+    6416             :       break;
+    6417             : 
+    6418           0 :     default:
+    6419           0 :       *info = -1;
+    6420           0 :       return;
+    6421             :     }
+    6422             :   } /* finished */
+    6423             : 
+    6424         264 :   *info = 0;
+    6425         264 :   return;
+    6426             : }
+    6427             : }
+    6428             : }
+    6429             : #include "lapack.h"
+    6430             : 
+    6431             : #include "blas/blas.h"
+    6432             : namespace PLMD{
+    6433             : namespace lapack{
+    6434             : using namespace blas;
+    6435             : void 
+    6436          29 : PLUMED_BLAS_F77_FUNC(dlasd0,DLASD0)(int *n, 
+    6437             :         int *sqre, 
+    6438             :         double *d__, 
+    6439             :         double *e, 
+    6440             :         double *u, 
+    6441             :         int *ldu, 
+    6442             :         double *vt, 
+    6443             :         int *ldvt,
+    6444             :         int *smlsiz, 
+    6445             :         int *iwork,
+    6446             :         double *work, 
+    6447             :         int *info)
+    6448             : {
+    6449             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+    6450             : 
+    6451             :     int i__, j, m, i1, ic, lf, nd, ll, nl, nr, im1, ncc, nlf, nrf, 
+    6452             :             iwk, lvl, ndb1, nlp1, nrp1;
+    6453             :     double beta;
+    6454             :     int idxq, nlvl;
+    6455             :     double alpha;
+    6456             :     int inode, ndiml, idxqc, ndimr, itemp, sqrei;
+    6457          29 :     int c__0 = 0;
+    6458             : 
+    6459             : 
+    6460          29 :     --d__;
+    6461          29 :     --e;
+    6462          29 :     u_dim1 = *ldu;
+    6463          29 :     u_offset = 1 + u_dim1;
+    6464          29 :     u -= u_offset;
+    6465          29 :     vt_dim1 = *ldvt;
+    6466          29 :     vt_offset = 1 + vt_dim1;
+    6467          29 :     vt -= vt_offset;
+    6468          29 :     --iwork;
+    6469             :     --work;
+    6470             : 
+    6471          29 :     *info = 0;
+    6472             : 
+    6473          29 :     if (*n < 0) {
+    6474           0 :         *info = -1;
+    6475          29 :     } else if (*sqre < 0 || *sqre > 1) {
+    6476           0 :         *info = -2;
+    6477             :     }
+    6478             : 
+    6479          29 :     m = *n + *sqre;
+    6480             : 
+    6481          29 :     if (*ldu < *n) {
+    6482           0 :         *info = -6;
+    6483          29 :     } else if (*ldvt < m) {
+    6484           0 :         *info = -8;
+    6485          29 :     } else if (*smlsiz < 3) {
+    6486           0 :         *info = -9;
+    6487             :     }
+    6488          29 :     if (*info != 0) {
+    6489             :         return;
+    6490             :     }
+    6491             : 
+    6492          29 :     if (*n <= *smlsiz) {
+    6493           0 :         PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U", sqre, n, &m, n, &c__0, &d__[1], &e[1], &vt[vt_offset], 
+    6494             :                 ldvt, &u[u_offset], ldu, &u[u_offset], ldu, &work[1], info);
+    6495           0 :         return;
+    6496             :     }
+    6497             : 
+    6498             :     inode = 1;
+    6499          29 :     ndiml = inode + *n;
+    6500          29 :     ndimr = ndiml + *n;
+    6501          29 :     idxq = ndimr + *n;
+    6502          29 :     iwk = idxq + *n;
+    6503          29 :     PLUMED_BLAS_F77_FUNC(dlasdt,DLASDT)(n, &nlvl, &nd, &iwork[inode], &iwork[ndiml], &iwork[ndimr], 
+    6504             :             smlsiz);
+    6505             : 
+    6506          29 :     ndb1 = (nd + 1) / 2;
+    6507          29 :     ncc = 0;
+    6508             :     i__1 = nd;
+    6509          73 :     for (i__ = ndb1; i__ <= i__1; ++i__) {
+    6510             : 
+    6511          44 :         i1 = i__ - 1;
+    6512          44 :         ic = iwork[inode + i1];
+    6513          44 :         nl = iwork[ndiml + i1];
+    6514          44 :         nlp1 = nl + 1;
+    6515          44 :         nr = iwork[ndimr + i1];
+    6516          44 :         nrp1 = nr + 1;
+    6517          44 :         nlf = ic - nl;
+    6518          44 :         nrf = ic + 1;
+    6519          44 :         sqrei = 1;
+    6520          44 :         PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U", &sqrei, &nl, &nlp1, &nl, &ncc, &d__[nlf], &e[nlf], &vt[
+    6521          44 :                 nlf + nlf * vt_dim1], ldvt, &u[nlf + nlf * u_dim1], ldu, &u[
+    6522          44 :                 nlf + nlf * u_dim1], ldu, &work[1], info);
+    6523          44 :         if (*info != 0) {
+    6524             :             return;
+    6525             :         }
+    6526          44 :         itemp = idxq + nlf - 2;
+    6527          44 :         i__2 = nl;
+    6528         732 :         for (j = 1; j <= i__2; ++j) {
+    6529         688 :             iwork[itemp + j] = j;
+    6530             :         }
+    6531          44 :         if (i__ == nd) {
+    6532          29 :             sqrei = *sqre;
+    6533             :         } else {
+    6534          15 :             sqrei = 1;
+    6535             :         }
+    6536          44 :         nrp1 = nr + sqrei;
+    6537          44 :         PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U", &sqrei, &nr, &nrp1, &nr, &ncc, &d__[nrf], &e[nrf], &vt[
+    6538          44 :                 nrf + nrf * vt_dim1], ldvt, &u[nrf + nrf * u_dim1], ldu, &u[
+    6539          44 :                 nrf + nrf * u_dim1], ldu, &work[1], info);
+    6540          44 :         if (*info != 0) {
+    6541             :             return;
+    6542             :         }
+    6543          44 :         itemp = idxq + ic;
+    6544          44 :         i__2 = nr;
+    6545         716 :         for (j = 1; j <= i__2; ++j) {
+    6546         672 :             iwork[itemp + j - 1] = j;
+    6547             :         }
+    6548             :     }
+    6549             : 
+    6550          62 :     for (lvl = nlvl; lvl >= 1; --lvl) {
+    6551             : 
+    6552          33 :         if (lvl == 1) {
+    6553             :             lf = 1;
+    6554             :             ll = 1;
+    6555             :         } else {
+    6556           4 :             i__1 = lvl - 1;
+    6557           4 :             lf = (1 << i__1);
+    6558           4 :             ll = (lf << 1) - 1;
+    6559             :         }
+    6560             :         i__1 = ll;
+    6561          92 :         for (i__ = lf; i__ <= i__1; ++i__) {
+    6562          59 :             im1 = i__ - 1;
+    6563          59 :             ic = iwork[inode + im1];
+    6564          59 :             nl = iwork[ndiml + im1];
+    6565          59 :             nr = iwork[ndimr + im1];
+    6566          59 :             nlf = ic - nl;
+    6567          59 :             if (*sqre == 0 && i__ == ll) {
+    6568          33 :                 sqrei = *sqre;
+    6569             :             } else {
+    6570          26 :                 sqrei = 1;
+    6571             :             }
+    6572          59 :             idxqc = idxq + nlf - 1;
+    6573          59 :             alpha = d__[ic];
+    6574          59 :             beta = e[ic];
+    6575          59 :             PLUMED_BLAS_F77_FUNC(dlasd1,DLASD1)(&nl, &nr, &sqrei, &d__[nlf], &alpha, &beta, &u[nlf + nlf *
+    6576          59 :                      u_dim1], ldu, &vt[nlf + nlf * vt_dim1], ldvt, &iwork[
+    6577          59 :                     idxqc], &iwork[iwk], &work[1], info);
+    6578          59 :             if (*info != 0) {
+    6579             :                 return;
+    6580             :             }
+    6581             :         }
+    6582             :     }
+    6583             : 
+    6584             :     return;
+    6585             : 
+    6586             : }
+    6587             : }
+    6588             : }
+    6589             : #include <cmath>
+    6590             : #include "lapack.h"
+    6591             : 
+    6592             : #include "blas/blas.h"
+    6593             : namespace PLMD{
+    6594             : namespace lapack{
+    6595             : using namespace blas;
+    6596             : void 
+    6597          59 : PLUMED_BLAS_F77_FUNC(dlasd1,DLASD1)(int *nl, 
+    6598             :         int *nr, 
+    6599             :         int *sqre, 
+    6600             :         double *d__, 
+    6601             :         double *alpha, 
+    6602             :         double *beta, 
+    6603             :         double *u, 
+    6604             :         int *ldu, 
+    6605             :         double *vt, 
+    6606             :         int *ldvt, 
+    6607             :         int *idxq, 
+    6608             :         int *iwork, 
+    6609             :         double *work, 
+    6610             :         int *info)
+    6611             : {
+    6612             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1;
+    6613             :     double d__1, d__2;
+    6614             : 
+    6615             :     int i__, k, m, n, n1, n2, iq, iz, iu2, ldq, idx, ldu2, ivt2, 
+    6616             :             idxc, idxp, ldvt2;
+    6617             :     int isigma;
+    6618             :     double orgnrm;
+    6619             :     int coltyp;
+    6620          59 :     int c__0 = 0;
+    6621          59 :     double one = 1.0;
+    6622          59 :     int c__1 = 1;
+    6623          59 :     int c_n1 = -1;
+    6624             : 
+    6625          59 :     --d__;
+    6626             :     u_dim1 = *ldu;
+    6627             :     u_offset = 1 + u_dim1;
+    6628             :     u -= u_offset;
+    6629             :     vt_dim1 = *ldvt;
+    6630             :     vt_offset = 1 + vt_dim1;
+    6631             :     vt -= vt_offset;
+    6632             :     --idxq;
+    6633          59 :     --iwork;
+    6634          59 :     --work;
+    6635             : 
+    6636          59 :     *info = 0;
+    6637             : 
+    6638          59 :     if (*nl < 1) {
+    6639           0 :         *info = -1;
+    6640          59 :     } else if (*nr < 1) {
+    6641           0 :         *info = -2;
+    6642          59 :     } else if (*sqre < 0 || *sqre > 1) {
+    6643           0 :         *info = -3;
+    6644             :     }
+    6645          59 :     if (*info != 0) {
+    6646             :         return;
+    6647             :     }
+    6648             : 
+    6649          59 :     n = *nl + *nr + 1;
+    6650          59 :     m = n + *sqre;
+    6651             : 
+    6652             : 
+    6653          59 :     ldu2 = n;
+    6654          59 :     ldvt2 = m;
+    6655             : 
+    6656             :     iz = 1;
+    6657          59 :     isigma = iz + m;
+    6658          59 :     iu2 = isigma + n;
+    6659          59 :     ivt2 = iu2 + ldu2 * n;
+    6660          59 :     iq = ivt2 + ldvt2 * m;
+    6661             : 
+    6662             :     idx = 1;
+    6663          59 :     idxc = idx + n;
+    6664          59 :     coltyp = idxc + n;
+    6665          59 :     idxp = coltyp + n;
+    6666             : 
+    6667          59 :     d__1 = std::abs(*alpha);
+    6668          59 :     d__2 = std::abs(*beta);
+    6669          59 :     orgnrm = (d__1>d__2) ? d__1 : d__2;
+    6670          59 :     d__[*nl + 1] = 0.;
+    6671             :     i__1 = n;
+    6672        3452 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    6673        3393 :         if (std::abs(d__[i__]) > orgnrm) {
+    6674        1098 :             orgnrm = std::abs(d__[i__]);
+    6675             :         }
+    6676             :     }
+    6677          59 :     PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &orgnrm, &one, &n, &c__1, &d__[1], &n, info);
+    6678          59 :     *alpha /= orgnrm;
+    6679          59 :     *beta /= orgnrm;
+    6680             : 
+    6681          59 :     PLUMED_BLAS_F77_FUNC(dlasd2,DLASD2)(nl, nr, sqre, &k, &d__[1], &work[iz], alpha, beta, &u[u_offset], 
+    6682          59 :             ldu, &vt[vt_offset], ldvt, &work[isigma], &work[iu2], &ldu2, &
+    6683          59 :             work[ivt2], &ldvt2, &iwork[idxp], &iwork[idx], &iwork[idxc], &
+    6684          59 :             idxq[1], &iwork[coltyp], info);
+    6685             : 
+    6686          59 :     ldq = k;
+    6687          59 :     PLUMED_BLAS_F77_FUNC(dlasd3,DLASD3)(nl, nr, sqre, &k, &d__[1], &work[iq], &ldq, &work[isigma], &u[
+    6688             :             u_offset], ldu, &work[iu2], &ldu2, &vt[vt_offset], ldvt, &work[
+    6689             :             ivt2], &ldvt2, &iwork[idxc], &iwork[coltyp], &work[iz], info);
+    6690          59 :     if (*info != 0) {
+    6691             :         return;
+    6692             :     }
+    6693          59 :     PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &one, &orgnrm, &n, &c__1, &d__[1], &n, info);
+    6694             : 
+    6695          59 :     n1 = k;
+    6696          59 :     n2 = n - k;
+    6697          59 :     PLUMED_BLAS_F77_FUNC(dlamrg,DLAMRG)(&n1, &n2, &d__[1], &c__1, &c_n1, &idxq[1]);
+    6698             : 
+    6699             :     return;
+    6700             : 
+    6701             : }
+    6702             : }
+    6703             : }
+    6704             : #include <cmath>
+    6705             : #include "blas/blas.h"
+    6706             : #include "lapack.h"
+    6707             : #include "lapack_limits.h"
+    6708             : 
+    6709             : #include "real.h"
+    6710             : 
+    6711             : #include "blas/blas.h"
+    6712             : namespace PLMD{
+    6713             : namespace lapack{
+    6714             : using namespace blas;
+    6715             : void 
+    6716          59 : PLUMED_BLAS_F77_FUNC(dlasd2,DLASD2)(int *nl, 
+    6717             :                         int *nr, 
+    6718             :                         int *sqre, 
+    6719             :                         int *k, 
+    6720             :                         double *d__, 
+    6721             :                         double *z__, 
+    6722             :                         double *alpha, 
+    6723             :                         double *beta, 
+    6724             :                         double *u, 
+    6725             :                         int *ldu, 
+    6726             :                         double *vt, 
+    6727             :                         int *ldvt, 
+    6728             :                         double *dsigma, 
+    6729             :                         double *u2, 
+    6730             :                         int *ldu2, 
+    6731             :                         double *vt2, 
+    6732             :                         int *ldvt2, 
+    6733             :                         int *idxp, 
+    6734             :                         int *idx, 
+    6735             :                         int *idxc, 
+    6736             :                         int *idxq, 
+    6737             :                         int *coltyp, 
+    6738             :                         int *info)
+    6739             : {
+    6740             :     int u_dim1, u_offset, u2_dim1, u2_offset, vt_dim1, vt_offset;
+    6741             :     int vt2_dim1, vt2_offset, i__1;
+    6742             :     double d__1, d__2;
+    6743             : 
+    6744             :     double c__;
+    6745             :     int i__, j, m, n;
+    6746             :     double s;
+    6747             :     int k2;
+    6748             :     double z1;
+    6749             :     int ct, jp;
+    6750             :     double eps, tau, tol;
+    6751             :     int psm[4], nlp1, nlp2, idxi, idxj;
+    6752             :     int ctot[4], idxjp;
+    6753             :     int jprev = 0;
+    6754             :     double hlftol;
+    6755          59 :     double zero = 0.0;
+    6756          59 :     int c__1 = 1;
+    6757             : 
+    6758             : 
+    6759          59 :     --d__;
+    6760          59 :     --z__;
+    6761          59 :     u_dim1 = *ldu;
+    6762          59 :     u_offset = 1 + u_dim1;
+    6763          59 :     u -= u_offset;
+    6764          59 :     vt_dim1 = *ldvt;
+    6765          59 :     vt_offset = 1 + vt_dim1;
+    6766          59 :     vt -= vt_offset;
+    6767          59 :     --dsigma;
+    6768          59 :     u2_dim1 = *ldu2;
+    6769          59 :     u2_offset = 1 + u2_dim1;
+    6770          59 :     u2 -= u2_offset;
+    6771          59 :     vt2_dim1 = *ldvt2;
+    6772          59 :     vt2_offset = 1 + vt2_dim1;
+    6773          59 :     vt2 -= vt2_offset;
+    6774          59 :     --idxp;
+    6775          59 :     --idx;
+    6776          59 :     --idxc;
+    6777          59 :     --idxq;
+    6778          59 :     --coltyp;
+    6779             : 
+    6780          59 :     *info = 0;
+    6781             : 
+    6782          59 :     n = *nl + *nr + 1;
+    6783          59 :     m = n + *sqre;
+    6784             : 
+    6785          59 :     nlp1 = *nl + 1;
+    6786          59 :     nlp2 = *nl + 2;
+    6787             : 
+    6788          59 :     z1 = *alpha * vt[nlp1 + nlp1 * vt_dim1];
+    6789          59 :     z__[1] = z1;
+    6790        1739 :     for (i__ = *nl; i__ >= 1; --i__) {
+    6791        1680 :         z__[i__ + 1] = *alpha * vt[i__ + nlp1 * vt_dim1];
+    6792        1680 :         d__[i__ + 1] = d__[i__];
+    6793        1680 :         idxq[i__ + 1] = idxq[i__] + 1;
+    6794             :     }
+    6795             : 
+    6796             :     i__1 = m;
+    6797        1739 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+    6798        1680 :         z__[i__] = *beta * vt[i__ + nlp2 * vt_dim1];
+    6799             :     }
+    6800             : 
+    6801             :     i__1 = nlp1;
+    6802        1739 :     for (i__ = 2; i__ <= i__1; ++i__) {
+    6803        1680 :         coltyp[i__] = 1;
+    6804             :     }
+    6805          59 :     i__1 = n;
+    6806        1713 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+    6807        1654 :         coltyp[i__] = 2;
+    6808             :     }
+    6809             : 
+    6810             :     i__1 = n;
+    6811        1713 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+    6812        1654 :         idxq[i__] += nlp1;
+    6813             :     }
+    6814             : 
+    6815             :     i__1 = n;
+    6816        3393 :     for (i__ = 2; i__ <= i__1; ++i__) {
+    6817        3334 :         dsigma[i__] = d__[idxq[i__]];
+    6818        3334 :         u2[i__ + u2_dim1] = z__[idxq[i__]];
+    6819        3334 :         idxc[i__] = coltyp[idxq[i__]];
+    6820             :     }
+    6821             : 
+    6822          59 :     PLUMED_BLAS_F77_FUNC(dlamrg,DLAMRG)(nl, nr, &dsigma[2], &c__1, &c__1, &idx[2]);
+    6823             : 
+    6824          59 :     i__1 = n;
+    6825        3393 :     for (i__ = 2; i__ <= i__1; ++i__) {
+    6826        3334 :         idxi = idx[i__] + 1;
+    6827        3334 :         d__[i__] = dsigma[idxi];
+    6828        3334 :         z__[i__] = u2[idxi + u2_dim1];
+    6829        3334 :         coltyp[i__] = idxc[idxi];
+    6830             :     }
+    6831             : 
+    6832             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    6833          59 :     d__1 = std::abs(*alpha), d__2 = std::abs(*beta);
+    6834          59 :     tol = (d__1 > d__2) ? d__1 : d__2;
+    6835          59 :     d__2 = std::abs(d__[n]);
+    6836          59 :     tol = eps * 8. * ((d__2 > tol) ? d__2 : tol);
+    6837             : 
+    6838          59 :     *k = 1;
+    6839          59 :     k2 = n + 1;
+    6840             :     i__1 = n;
+    6841          79 :     for (j = 2; j <= i__1; ++j) {
+    6842          79 :         if (std::abs(z__[j]) <= tol) {
+    6843             : 
+    6844          20 :             --k2;
+    6845          20 :             idxp[k2] = j;
+    6846          20 :             coltyp[j] = 4;
+    6847          20 :             if (j == n) {
+    6848           0 :                 goto L120;
+    6849             :             }
+    6850             :         } else {
+    6851             :             jprev = j;
+    6852          59 :             goto L90;
+    6853             :         }
+    6854             :     }
+    6855          59 : L90:
+    6856             :     j = jprev;
+    6857        3314 : L100:
+    6858        3314 :     ++j;
+    6859        3314 :     if (j > n) {
+    6860          59 :         goto L110;
+    6861             :     }
+    6862        3255 :     if (std::abs(z__[j]) <= tol) {
+    6863             : 
+    6864         122 :         --k2;
+    6865         122 :         idxp[k2] = j;
+    6866         122 :         coltyp[j] = 4;
+    6867             :     } else {
+    6868             : 
+    6869        3133 :         if (std::abs(d__[j] - d__[jprev]) <= tol) {
+    6870             : 
+    6871           0 :             s = z__[jprev];
+    6872           0 :             c__ = z__[j];
+    6873             : 
+    6874           0 :             tau = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(&c__, &s);
+    6875           0 :             c__ /= tau;
+    6876           0 :             s = -s / tau;
+    6877           0 :             z__[j] = tau;
+    6878           0 :             z__[jprev] = 0.;
+    6879             : 
+    6880           0 :             idxjp = idxq[idx[jprev] + 1];
+    6881           0 :             idxj = idxq[idx[j] + 1];
+    6882           0 :             if (idxjp <= nlp1) {
+    6883           0 :                 --idxjp;
+    6884             :             }
+    6885           0 :             if (idxj <= nlp1) {
+    6886           0 :                 --idxj;
+    6887             :             }
+    6888           0 :             PLUMED_BLAS_F77_FUNC(drot,DROT)(&n, &u[idxjp * u_dim1 + 1], &c__1, &u[idxj * u_dim1 + 1], &
+    6889             :                     c__1, &c__, &s);
+    6890           0 :             PLUMED_BLAS_F77_FUNC(drot,DROT)(&m, &vt[idxjp + vt_dim1], ldvt, &vt[idxj + vt_dim1], ldvt, &
+    6891             :                     c__, &s);
+    6892           0 :             if (coltyp[j] != coltyp[jprev]) {
+    6893           0 :                 coltyp[j] = 3;
+    6894             :             }
+    6895           0 :             coltyp[jprev] = 4;
+    6896           0 :             --k2;
+    6897           0 :             idxp[k2] = jprev;
+    6898             :             jprev = j;
+    6899             :         } else {
+    6900        3133 :             ++(*k);
+    6901        3133 :             u2[*k + u2_dim1] = z__[jprev];
+    6902        3133 :             dsigma[*k] = d__[jprev];
+    6903        3133 :             idxp[*k] = jprev;
+    6904             :             jprev = j;
+    6905             :         }
+    6906             :     }
+    6907        3255 :     goto L100;
+    6908             : L110:
+    6909             : 
+    6910          59 :     ++(*k);
+    6911          59 :     u2[*k + u2_dim1] = z__[jprev];
+    6912          59 :     dsigma[*k] = d__[jprev];
+    6913          59 :     idxp[*k] = jprev;
+    6914             : 
+    6915             : L120:
+    6916             : 
+    6917         295 :     for (j = 1; j <= 4; ++j) {
+    6918         236 :         ctot[j - 1] = 0;
+    6919             :     }
+    6920          59 :     i__1 = n;
+    6921        3393 :     for (j = 2; j <= i__1; ++j) {
+    6922        3334 :         ct = coltyp[j];
+    6923        3334 :         ++ctot[ct - 1];
+    6924             :     }
+    6925             : 
+    6926          59 :     psm[0] = 2;
+    6927          59 :     psm[1] = ctot[0] + 2;
+    6928          59 :     psm[2] = psm[1] + ctot[1];
+    6929          59 :     psm[3] = psm[2] + ctot[2];
+    6930             : 
+    6931             :     i__1 = n;
+    6932        3393 :     for (j = 2; j <= i__1; ++j) {
+    6933        3334 :         jp = idxp[j];
+    6934        3334 :         ct = coltyp[jp];
+    6935        3334 :         idxc[psm[ct - 1]] = j;
+    6936        3334 :         ++psm[ct - 1];
+    6937             :     }
+    6938             : 
+    6939             :     i__1 = n;
+    6940        3393 :     for (j = 2; j <= i__1; ++j) {
+    6941        3334 :         jp = idxp[j];
+    6942        3334 :         dsigma[j] = d__[jp];
+    6943        3334 :         idxj = idxq[idx[idxp[idxc[j]]] + 1];
+    6944        3334 :         if (idxj <= nlp1) {
+    6945        1680 :             --idxj;
+    6946             :         }
+    6947        3334 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&n, &u[idxj * u_dim1 + 1], &c__1, &u2[j * u2_dim1 + 1], &c__1);
+    6948        3334 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&m, &vt[idxj + vt_dim1], ldvt, &vt2[j + vt2_dim1], ldvt2);
+    6949             :     }
+    6950             : 
+    6951          59 :     dsigma[1] = 0.;
+    6952          59 :     hlftol = tol / 2.;
+    6953          59 :     if (std::abs(dsigma[2]) <= hlftol) {
+    6954           5 :         dsigma[2] = hlftol;
+    6955             :     }
+    6956          59 :     if (m > n) {
+    6957          26 :         z__[1] = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(&z1, &z__[m]);
+    6958          26 :         if (z__[1] <= tol) {
+    6959           0 :             c__ = 1.;
+    6960           0 :             s = 0.;
+    6961           0 :             z__[1] = tol;
+    6962             :         } else {
+    6963          26 :             c__ = z1 / z__[1];
+    6964          26 :             s = z__[m] / z__[1];
+    6965             :         }
+    6966             :     } else {
+    6967          33 :         if (std::abs(z1) <= tol) {
+    6968           0 :             z__[1] = tol;
+    6969             :         } else {
+    6970          33 :             z__[1] = z1;
+    6971             :         }
+    6972             :     }
+    6973             : 
+    6974          59 :     i__1 = *k - 1;
+    6975          59 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &u2[u2_dim1 + 2], &c__1, &z__[2], &c__1);
+    6976             : 
+    6977          59 :     PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", &n, &c__1, &zero, &zero, &u2[u2_offset], ldu2);
+    6978          59 :     u2[nlp1 + u2_dim1] = 1.;
+    6979          59 :     if (m > n) {
+    6980             :         i__1 = nlp1;
+    6981         803 :         for (i__ = 1; i__ <= i__1; ++i__) {
+    6982         777 :             vt[m + i__ * vt_dim1] = -s * vt[nlp1 + i__ * vt_dim1];
+    6983         777 :             vt2[i__ * vt2_dim1 + 1] = c__ * vt[nlp1 + i__ * vt_dim1];
+    6984             :         }
+    6985          26 :         i__1 = m;
+    6986         785 :         for (i__ = nlp2; i__ <= i__1; ++i__) {
+    6987         759 :             vt2[i__ * vt2_dim1 + 1] = s * vt[m + i__ * vt_dim1];
+    6988         759 :             vt[m + i__ * vt_dim1] = c__ * vt[m + i__ * vt_dim1];
+    6989             :         }
+    6990             :     } else {
+    6991          33 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&m, &vt[nlp1 + vt_dim1], ldvt, &vt2[vt2_dim1 + 1], ldvt2);
+    6992             :     }
+    6993          59 :     if (m > n) {
+    6994          26 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&m, &vt[m + vt_dim1], ldvt, &vt2[m + vt2_dim1], ldvt2);
+    6995             :     }
+    6996             : 
+    6997          59 :     if (n > *k) {
+    6998          26 :         i__1 = n - *k;
+    6999          26 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &dsigma[*k + 1], &c__1, &d__[*k + 1], &c__1);
+    7000          26 :         i__1 = n - *k;
+    7001          26 :         PLUMED_BLAS_F77_FUNC(dlacpy,DLACPY)("A", &n, &i__1, &u2[(*k + 1) * u2_dim1 + 1], ldu2, &u[(*k + 1)
+    7002          26 :                  * u_dim1 + 1], ldu);
+    7003          26 :         i__1 = n - *k;
+    7004          26 :         PLUMED_BLAS_F77_FUNC(dlacpy,DLACPY)("A", &i__1, &m, &vt2[*k + 1 + vt2_dim1], ldvt2, &vt[*k + 1 + 
+    7005          26 :                 vt_dim1], ldvt);
+    7006             :     }
+    7007         295 :     for (j = 1; j <= 4; ++j) {
+    7008         236 :         coltyp[j] = ctot[j - 1];
+    7009             :     }
+    7010             : 
+    7011          59 :     return;
+    7012             : 
+    7013             : }
+    7014             : 
+    7015             : 
+    7016             : }
+    7017             : }
+    7018             : #include <cmath>
+    7019             : #include "blas/blas.h"
+    7020             : #include "lapack.h"
+    7021             : 
+    7022             : #include "blas/blas.h"
+    7023             : namespace PLMD{
+    7024             : namespace lapack{
+    7025             : using namespace blas;
+    7026             : void 
+    7027          59 : PLUMED_BLAS_F77_FUNC(dlasd3,DLASD3)(int *nl, 
+    7028             :         int *nr,
+    7029             :         int *sqre, 
+    7030             :         int *k, 
+    7031             :         double *d__, 
+    7032             :         double *q, 
+    7033             :         int *ldq, 
+    7034             :         double *dsigma, 
+    7035             :         double *u, 
+    7036             :         int *ldu, 
+    7037             :         double *u2, 
+    7038             :         int *ldu2, 
+    7039             :         double *vt, 
+    7040             :         int *ldvt, 
+    7041             :         double *vt2, 
+    7042             :         int *ldvt2, 
+    7043             :         int *idxc, 
+    7044             :         int *ctot, 
+    7045             :         double *z__, 
+    7046             :         int *info)
+    7047             : {
+    7048             :     int q_dim1, q_offset, u_dim1, u_offset, u2_dim1, u2_offset, vt_dim1, 
+    7049             :             vt_offset, vt2_dim1, vt2_offset, i__1, i__2;
+    7050             :     double d__2;
+    7051             : 
+    7052             :     int i__, j, m, n, jc;
+    7053             :     double rho;
+    7054             :     int nlp1, nlp2, nrp1;
+    7055             :     double temp;
+    7056             :     int ctemp;
+    7057             :     int ktemp;
+    7058          59 :     int c__1 = 1;
+    7059          59 :     int c__0 = 0;
+    7060          59 :     double zero = 0.0;
+    7061          59 :     double one = 1.0;
+    7062             : 
+    7063             :     --d__;
+    7064          59 :     q_dim1 = *ldq;
+    7065          59 :     q_offset = 1 + q_dim1;
+    7066          59 :     q -= q_offset;
+    7067          59 :     --dsigma;
+    7068          59 :     u_dim1 = *ldu;
+    7069          59 :     u_offset = 1 + u_dim1;
+    7070          59 :     u -= u_offset;
+    7071          59 :     u2_dim1 = *ldu2;
+    7072          59 :     u2_offset = 1 + u2_dim1;
+    7073          59 :     u2 -= u2_offset;
+    7074          59 :     vt_dim1 = *ldvt;
+    7075          59 :     vt_offset = 1 + vt_dim1;
+    7076          59 :     vt -= vt_offset;
+    7077          59 :     vt2_dim1 = *ldvt2;
+    7078          59 :     vt2_offset = 1 + vt2_dim1;
+    7079          59 :     vt2 -= vt2_offset;
+    7080          59 :     --idxc;
+    7081             :     --ctot;
+    7082          59 :     --z__;
+    7083             : 
+    7084             :     /* Function Body */
+    7085          59 :     *info = 0;
+    7086             : 
+    7087          59 :     if (*nl < 1) {
+    7088           0 :         *info = -1;
+    7089          59 :     } else if (*nr < 1) {
+    7090           0 :         *info = -2;
+    7091          59 :     } else if (*sqre != 1 && *sqre != 0) {
+    7092           0 :         *info = -3;
+    7093             :     }
+    7094             : 
+    7095          59 :     n = *nl + *nr + 1;
+    7096          59 :     m = n + *sqre;
+    7097          59 :     nlp1 = *nl + 1;
+    7098          59 :     nlp2 = *nl + 2;
+    7099             : 
+    7100          59 :     if (*k == 1) {
+    7101           0 :         d__[1] = std::abs(z__[1]);
+    7102           0 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&m, &vt2[vt2_dim1 + 1], ldvt2, &vt[vt_dim1 + 1], ldvt);
+    7103           0 :         if (z__[1] > 0.) {
+    7104           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&n, &u2[u2_dim1 + 1], &c__1, &u[u_dim1 + 1], &c__1);
+    7105             :         } else {
+    7106           0 :             i__1 = n;
+    7107           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+    7108           0 :                 u[i__ + u_dim1] = -u2[i__ + u2_dim1];
+    7109             :             }
+    7110             :         }
+    7111           0 :         return;
+    7112             :     }
+    7113             : 
+    7114          59 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(k, &z__[1], &c__1, &q[q_offset], &c__1);
+    7115             : 
+    7116          59 :     rho = PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(k, &z__[1], &c__1);
+    7117          59 :     PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &rho, &one, k, &c__1, &z__[1], k, info);
+    7118          59 :     rho *= rho;
+    7119             : 
+    7120             : 
+    7121          59 :     i__1 = *k;
+    7122        3310 :     for (j = 1; j <= i__1; ++j) {
+    7123        3251 :         PLUMED_BLAS_F77_FUNC(dlasd4,DLASD4)(k, &j, &dsigma[1], &z__[1], &u[j * u_dim1 + 1], &rho, &d__[j],
+    7124        3251 :                  &vt[j * vt_dim1 + 1], info);
+    7125             : 
+    7126        3251 :         if (*info != 0) {
+    7127             :             return;
+    7128             :         }
+    7129             :     }
+    7130             : 
+    7131          59 :     i__1 = *k;
+    7132        3310 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    7133        3251 :         z__[i__] = u[i__ + *k * u_dim1] * vt[i__ + *k * vt_dim1];
+    7134             :         i__2 = i__ - 1;
+    7135      212011 :         for (j = 1; j <= i__2; ++j) {
+    7136      208760 :             z__[i__] *= u[i__ + j * u_dim1] * vt[i__ + j * vt_dim1] / (dsigma[
+    7137      208760 :                     i__] - dsigma[j]) / (dsigma[i__] + dsigma[j]);
+    7138             :         }
+    7139        3251 :         i__2 = *k - 1;
+    7140      212011 :         for (j = i__; j <= i__2; ++j) {
+    7141      208760 :             z__[i__] *= u[i__ + j * u_dim1] * vt[i__ + j * vt_dim1] / (dsigma[
+    7142      208760 :                     i__] - dsigma[j + 1]) / (dsigma[i__] + dsigma[j + 1]);
+    7143             :         }
+    7144        3251 :         d__2 =  std::sqrt(std::abs(z__[i__]));
+    7145        3251 :         z__[i__] = (q[i__ + q_dim1] > 0) ? d__2 : -d__2;
+    7146             :     }
+    7147             : 
+    7148          59 :     i__1 = *k;
+    7149        3310 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    7150        3251 :         vt[i__ * vt_dim1 + 1] = z__[1] / u[i__ * u_dim1 + 1] / vt[i__ * 
+    7151        3251 :                 vt_dim1 + 1];
+    7152        3251 :         u[i__ * u_dim1 + 1] = -1.;
+    7153        3251 :         i__2 = *k;
+    7154      420771 :         for (j = 2; j <= i__2; ++j) {
+    7155      417520 :             vt[j + i__ * vt_dim1] = z__[j] / u[j + i__ * u_dim1] / vt[j + i__ 
+    7156      417520 :                     * vt_dim1];
+    7157      417520 :             u[j + i__ * u_dim1] = dsigma[j] * vt[j + i__ * vt_dim1];
+    7158             :         }
+    7159        3251 :         temp = PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(k, &u[i__ * u_dim1 + 1], &c__1);
+    7160        3251 :         q[i__ * q_dim1 + 1] = u[i__ * u_dim1 + 1] / temp;
+    7161        3251 :         i__2 = *k;
+    7162      420771 :         for (j = 2; j <= i__2; ++j) {
+    7163      417520 :             jc = idxc[j];
+    7164      417520 :             q[j + i__ * q_dim1] = u[jc + i__ * u_dim1] / temp;
+    7165             :         }
+    7166             :     }
+    7167             : 
+    7168          59 :     if (*k == 2) {
+    7169           0 :         PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", &n, k, k, &one, &u2[u2_offset], ldu2, &q[q_offset],
+    7170             :                  ldq, &zero, &u[u_offset], ldu);
+    7171           0 :         goto L100;
+    7172             :     }
+    7173          59 :     if (ctot[1] > 0) {
+    7174          59 :         PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", nl, k, &ctot[1], &one, &u2[(u2_dim1 << 1) + 1], 
+    7175          59 :                 ldu2, &q[q_dim1 + 2], ldq, &zero, &u[u_dim1 + 1], ldu);
+    7176          59 :         if (ctot[3] > 0) {
+    7177           0 :             ktemp = ctot[1] + 2 + ctot[2];
+    7178           0 :             PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", nl, k, &ctot[3], &one, &u2[ktemp * u2_dim1 + 1]
+    7179           0 :                     , ldu2, &q[ktemp + q_dim1], ldq, &one, &u[u_dim1 + 1], 
+    7180             :                     ldu);
+    7181             :         }
+    7182           0 :     } else if (ctot[3] > 0) {
+    7183           0 :         ktemp = ctot[1] + 2 + ctot[2];
+    7184           0 :         PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", nl, k, &ctot[3], &one, &u2[ktemp * u2_dim1 + 1], 
+    7185           0 :                 ldu2, &q[ktemp + q_dim1], ldq, &zero, &u[u_dim1 + 1], ldu);
+    7186             :     } else {
+    7187           0 :         PLUMED_BLAS_F77_FUNC(dlacpy,DLACPY)("F", nl, k, &u2[u2_offset], ldu2, &u[u_offset], ldu);
+    7188             :     }
+    7189          59 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(k, &q[q_dim1 + 1], ldq, &u[nlp1 + u_dim1], ldu);
+    7190          59 :     ktemp = ctot[1] + 2;
+    7191          59 :     ctemp = ctot[2] + ctot[3];
+    7192          59 :     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", nr, k, &ctemp, &one, &u2[nlp2 + ktemp * u2_dim1], ldu2,
+    7193          59 :              &q[ktemp + q_dim1], ldq, &zero, &u[nlp2 + u_dim1], ldu);
+    7194             : 
+    7195          59 : L100:
+    7196          59 :     i__1 = *k;
+    7197        3310 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    7198        3251 :         temp = PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(k, &vt[i__ * vt_dim1 + 1], &c__1);
+    7199        3251 :         q[i__ + q_dim1] = vt[i__ * vt_dim1 + 1] / temp;
+    7200        3251 :         i__2 = *k;
+    7201      420771 :         for (j = 2; j <= i__2; ++j) {
+    7202      417520 :             jc = idxc[j];
+    7203      417520 :             q[i__ + j * q_dim1] = vt[jc + i__ * vt_dim1] / temp;
+    7204             :         }
+    7205             :     }
+    7206             : 
+    7207          59 :     if (*k == 2) {
+    7208           0 :         PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", k, &m, k, &one, &q[q_offset], ldq, &vt2[vt2_offset]
+    7209             :                 , ldvt2, &zero, &vt[vt_offset], ldvt);
+    7210           0 :         return;
+    7211             :     }
+    7212          59 :     ktemp = ctot[1] + 1;
+    7213          59 :     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", k, &nlp1, &ktemp, &one, &q[q_dim1 + 1], ldq, &vt2[
+    7214          59 :             vt2_dim1 + 1], ldvt2, &zero, &vt[vt_dim1 + 1], ldvt);
+    7215          59 :     ktemp = ctot[1] + 2 + ctot[2];
+    7216          59 :     if (ktemp <= *ldvt2) {
+    7217          49 :         PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", k, &nlp1, &ctot[3], &one, &q[ktemp * q_dim1 + 1], 
+    7218          49 :                 ldq, &vt2[ktemp + vt2_dim1], ldvt2, &one, &vt[vt_dim1 + 1], 
+    7219             :                 ldvt);
+    7220             :     }
+    7221             : 
+    7222          59 :     ktemp = ctot[1] + 1;
+    7223          59 :     nrp1 = *nr + *sqre;
+    7224          59 :     if (ktemp > 1) {
+    7225          59 :         i__1 = *k;
+    7226        3310 :         for (i__ = 1; i__ <= i__1; ++i__) {
+    7227        3251 :             q[i__ + ktemp * q_dim1] = q[i__ + q_dim1];
+    7228             :         }
+    7229          59 :         i__1 = m;
+    7230        1739 :         for (i__ = nlp2; i__ <= i__1; ++i__) {
+    7231        1680 :             vt2[ktemp + i__ * vt2_dim1] = vt2[i__ * vt2_dim1 + 1];
+    7232             :         }
+    7233             :     }
+    7234          59 :     ctemp = ctot[2] + 1 + ctot[3];
+    7235          59 :     PLUMED_BLAS_F77_FUNC(dgemm,DGEMM)("N", "N", k, &nrp1, &ctemp, &one, &q[ktemp * q_dim1 + 1], ldq, &
+    7236          59 :             vt2[ktemp + nlp2 * vt2_dim1], ldvt2, &zero, &vt[nlp2 * vt_dim1 + 
+    7237          59 :             1], ldvt);
+    7238             : 
+    7239             :     return;
+    7240             : 
+    7241             : 
+    7242             : }
+    7243             : 
+    7244             : 
+    7245             : }
+    7246             : }
+    7247             : #include <cmath>
+    7248             : #include "lapack.h"
+    7249             : #include "lapack_limits.h"
+    7250             : 
+    7251             : #include "real.h"
+    7252             : 
+    7253             : #include "blas/blas.h"
+    7254             : namespace PLMD{
+    7255             : namespace lapack{
+    7256             : using namespace blas;
+    7257             : void 
+    7258        3251 : PLUMED_BLAS_F77_FUNC(dlasd4,DLASD4)(int *n, 
+    7259             :         int *i__, 
+    7260             :         double *d__, 
+    7261             :         double *z__, 
+    7262             :         double *delta, 
+    7263             :         double *rho, 
+    7264             :         double *sigma, 
+    7265             :         double *work, 
+    7266             :         int *info)
+    7267             : {
+    7268             :     int i__1;
+    7269             :     double d__1;
+    7270             : 
+    7271             :     double a, b, c__;
+    7272             :     int j;
+    7273             :     double w, dd[3];
+    7274             :     int ii;
+    7275             :     double dw, zz[3];
+    7276             :     int ip1;
+    7277             :     double eta, phi, eps, tau, psi;
+    7278             :     int iim1, iip1;
+    7279             :     double dphi, dpsi;
+    7280             :     int iter;
+    7281             :     double temp, prew, sg2lb, sg2ub, temp1, temp2, dtiim, delsq, 
+    7282             :             dtiip;
+    7283             :     int niter;
+    7284             :     double dtisq;
+    7285             :     int swtch;
+    7286             :     double dtnsq;
+    7287             :     double delsq2, dtnsq1;
+    7288             :     int swtch3;
+    7289             :     int orgati;
+    7290             :     double erretm, dtipsq, rhoinv;
+    7291             : 
+    7292        3251 :     --work;
+    7293        3251 :     --delta;
+    7294        3251 :     --z__;
+    7295        3251 :     --d__;
+    7296             : 
+    7297        3251 :     *info = 0;
+    7298        3251 :     if (*n == 1) {
+    7299             : 
+    7300           0 :         *sigma =  std::sqrt(d__[1] * d__[1] + *rho * z__[1] * z__[1]);
+    7301           0 :         delta[1] = 1.;
+    7302           0 :         work[1] = 1.;
+    7303           0 :         return;
+    7304             :     }
+    7305        3251 :     if (*n == 2) {
+    7306           0 :         PLUMED_BLAS_F77_FUNC(dlasd5,DLASD5)(i__, &d__[1], &z__[1], &delta[1], rho, sigma, &work[1]);
+    7307           0 :         return;
+    7308             :     }
+    7309             : 
+    7310             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    7311        3251 :     rhoinv = 1. / *rho;
+    7312             : 
+    7313        3251 :     if (*i__ == *n) {
+    7314             : 
+    7315          59 :         ii = *n - 1;
+    7316          59 :         niter = 1;
+    7317             : 
+    7318          59 :         temp = *rho / 2.;
+    7319             : 
+    7320          59 :         temp1 = temp / (d__[*n] +  std::sqrt(d__[*n] * d__[*n] + temp));
+    7321          59 :         i__1 = *n;
+    7322        3310 :         for (j = 1; j <= i__1; ++j) {
+    7323        3251 :             work[j] = d__[j] + d__[*n] + temp1;
+    7324        3251 :             delta[j] = d__[j] - d__[*n] - temp1;
+    7325             :         }
+    7326             : 
+    7327             :         psi = 0.;
+    7328          59 :         i__1 = *n - 2;
+    7329        3192 :         for (j = 1; j <= i__1; ++j) {
+    7330        3133 :             psi += z__[j] * z__[j] / (delta[j] * work[j]);
+    7331             :         }
+    7332             : 
+    7333          59 :         c__ = rhoinv + psi;
+    7334          59 :         w = c__ + z__[ii] * z__[ii] / (delta[ii] * work[ii]) + z__[*n] * z__[*
+    7335          59 :                 n] / (delta[*n] * work[*n]);
+    7336             : 
+    7337          59 :         if (w <= 0.) {
+    7338           0 :             temp1 =  std::sqrt(d__[*n] * d__[*n] + *rho);
+    7339           0 :             temp = z__[*n - 1] * z__[*n - 1] / ((d__[*n - 1] + temp1) * (d__[*
+    7340           0 :                     n] - d__[*n - 1] + *rho / (d__[*n] + temp1))) + z__[*n] * 
+    7341           0 :                     z__[*n] / *rho;
+    7342             : 
+    7343           0 :             if (c__ <= temp) {
+    7344             :                 tau = *rho;
+    7345             :             } else {
+    7346           0 :                 delsq = (d__[*n] - d__[*n - 1]) * (d__[*n] + d__[*n - 1]);
+    7347           0 :                 a = -c__ * delsq + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[*
+    7348             :                         n];
+    7349           0 :                 b = z__[*n] * z__[*n] * delsq;
+    7350           0 :                 if (a < 0.) {
+    7351           0 :                     tau = b * 2. / ( std::sqrt(a * a + b * 4. * c__) - a);
+    7352             :                 } else {
+    7353           0 :                     tau = (a +  std::sqrt(a * a + b * 4. * c__)) / (c__ * 2.);
+    7354             :                 }
+    7355             :             }
+    7356             : 
+    7357             :         } else {
+    7358          59 :             delsq = (d__[*n] - d__[*n - 1]) * (d__[*n] + d__[*n - 1]);
+    7359          59 :             a = -c__ * delsq + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[*n];
+    7360          59 :             b = z__[*n] * z__[*n] * delsq;
+    7361             : 
+    7362          59 :             if (a < 0.) {
+    7363          59 :                 tau = b * 2. / ( std::sqrt(a * a + b * 4. * c__) - a);
+    7364             :             } else {
+    7365           0 :                 tau = (a +  std::sqrt(a * a + b * 4. * c__)) / (c__ * 2.);
+    7366             :             }
+    7367             : 
+    7368             :         }
+    7369             : 
+    7370          59 :         eta = tau / (d__[*n] +  std::sqrt(d__[*n] * d__[*n] + tau));
+    7371             : 
+    7372          59 :         *sigma = d__[*n] + eta;
+    7373          59 :         i__1 = *n;
+    7374        3310 :         for (j = 1; j <= i__1; ++j) {
+    7375        3251 :             delta[j] = d__[j] - d__[*i__] - eta;
+    7376        3251 :             work[j] = d__[j] + d__[*i__] + eta;
+    7377             :         }
+    7378             : 
+    7379             :         dpsi = 0.;
+    7380             :         psi = 0.;
+    7381             :         erretm = 0.;
+    7382             :         i__1 = ii;
+    7383        3251 :         for (j = 1; j <= i__1; ++j) {
+    7384        3192 :             temp = z__[j] / (delta[j] * work[j]);
+    7385        3192 :             psi += z__[j] * temp;
+    7386        3192 :             dpsi += temp * temp;
+    7387        3192 :             erretm += psi;
+    7388             :         }
+    7389             :         erretm = std::abs(erretm);
+    7390             : 
+    7391          59 :         temp = z__[*n] / (delta[*n] * work[*n]);
+    7392          59 :         phi = z__[*n] * temp;
+    7393          59 :         dphi = temp * temp;
+    7394          59 :         erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (dpsi 
+    7395          59 :                 + dphi);
+    7396             : 
+    7397          59 :         w = rhoinv + phi + psi;
+    7398             : 
+    7399          59 :         if (std::abs(w) <= eps * erretm) {
+    7400           0 :             goto L240;
+    7401             :         }
+    7402             : 
+    7403          59 :         ++niter;
+    7404          59 :         dtnsq1 = work[*n - 1] * delta[*n - 1];
+    7405             :         dtnsq = work[*n] * delta[*n];
+    7406          59 :         c__ = w - dtnsq1 * dpsi - dtnsq * dphi;
+    7407          59 :         a = (dtnsq + dtnsq1) * w - dtnsq * dtnsq1 * (dpsi + dphi);
+    7408          59 :         b = dtnsq * dtnsq1 * w;
+    7409          59 :         if (c__ < 0.) {
+    7410           0 :             c__ = std::abs(c__);
+    7411             :         }
+    7412          59 :         if ( std::abs(c__)<PLUMED_GMX_DOUBLE_MIN) {
+    7413           0 :             eta = *rho - *sigma * *sigma;
+    7414          59 :         } else if (a >= 0.) {
+    7415           1 :             eta = (a +  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__  * 2.);
+    7416             :         } else {
+    7417          58 :           eta = b * 2. / (a -  std::sqrt(std::abs(a * a - b * 4. * c__)));
+    7418             :         }
+    7419             : 
+    7420          59 :         if (w * eta > 0.) {
+    7421           0 :             eta = -w / (dpsi + dphi);
+    7422             :         }
+    7423          59 :         temp = eta - dtnsq;
+    7424          59 :         if (temp > *rho) {
+    7425           0 :             eta = *rho + dtnsq;
+    7426             :         }
+    7427             : 
+    7428          59 :         tau += eta;
+    7429          59 :         eta /= *sigma +  std::sqrt(eta + *sigma * *sigma);
+    7430          59 :         i__1 = *n;
+    7431        3310 :         for (j = 1; j <= i__1; ++j) {
+    7432        3251 :             delta[j] -= eta;
+    7433        3251 :             work[j] += eta;
+    7434             :         }
+    7435             : 
+    7436          59 :         *sigma += eta;
+    7437             : 
+    7438             :         dpsi = 0.;
+    7439             :         psi = 0.;
+    7440             :         erretm = 0.;
+    7441             :         i__1 = ii;
+    7442        3251 :         for (j = 1; j <= i__1; ++j) {
+    7443        3192 :             temp = z__[j] / (work[j] * delta[j]);
+    7444        3192 :             psi += z__[j] * temp;
+    7445        3192 :             dpsi += temp * temp;
+    7446        3192 :             erretm += psi;
+    7447             :         }
+    7448             :         erretm = std::abs(erretm);
+    7449             : 
+    7450          59 :         temp = z__[*n] / (work[*n] * delta[*n]);
+    7451          59 :         phi = z__[*n] * temp;
+    7452          59 :         dphi = temp * temp;
+    7453          59 :         erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (dpsi 
+    7454          59 :                 + dphi);
+    7455             : 
+    7456          59 :         w = rhoinv + phi + psi;
+    7457             : 
+    7458             :         iter = niter + 1;
+    7459             : 
+    7460         113 :         for (niter = iter; niter <= 20; ++niter) {
+    7461             : 
+    7462         113 :             if (std::abs(w) <= eps * erretm) {
+    7463          59 :                 goto L240;
+    7464             :             }
+    7465          54 :             dtnsq1 = work[*n - 1] * delta[*n - 1];
+    7466          54 :             dtnsq = work[*n] * delta[*n];
+    7467          54 :             c__ = w - dtnsq1 * dpsi - dtnsq * dphi;
+    7468          54 :             a = (dtnsq + dtnsq1) * w - dtnsq1 * dtnsq * (dpsi + dphi);
+    7469          54 :             b = dtnsq1 * dtnsq * w;
+    7470          54 :             if (a >= 0.) {
+    7471           0 :                 eta = (a +  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+    7472             :             } else {
+    7473          54 :               eta = b * 2. / (a -  std::sqrt(std::abs(a * a - b * 4. * c__)));
+    7474             :             }
+    7475             : 
+    7476          54 :             if (w * eta > 0.) {
+    7477           0 :                 eta = -w / (dpsi + dphi);
+    7478             :             }
+    7479          54 :             temp = eta - dtnsq;
+    7480          54 :             if (temp <= 0.) {
+    7481           0 :                 eta /= 2.;
+    7482             :             }
+    7483             : 
+    7484          54 :             tau += eta;
+    7485          54 :             eta /= *sigma +  std::sqrt(eta + *sigma * *sigma);
+    7486          54 :             i__1 = *n;
+    7487        1745 :             for (j = 1; j <= i__1; ++j) {
+    7488        1691 :                 delta[j] -= eta;
+    7489        1691 :                 work[j] += eta;
+    7490             :             }
+    7491             : 
+    7492          54 :             *sigma += eta;
+    7493             : 
+    7494             :             dpsi = 0.;
+    7495             :             psi = 0.;
+    7496             :             erretm = 0.;
+    7497             :             i__1 = ii;
+    7498        1691 :             for (j = 1; j <= i__1; ++j) {
+    7499        1637 :                 temp = z__[j] / (work[j] * delta[j]);
+    7500        1637 :                 psi += z__[j] * temp;
+    7501        1637 :                 dpsi += temp * temp;
+    7502        1637 :                 erretm += psi;
+    7503             :             }
+    7504             :             erretm = std::abs(erretm);
+    7505             : 
+    7506          54 :             temp = z__[*n] / (work[*n] * delta[*n]);
+    7507          54 :             phi = z__[*n] * temp;
+    7508          54 :             dphi = temp * temp;
+    7509          54 :             erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (
+    7510          54 :                     dpsi + dphi);
+    7511             : 
+    7512          54 :             w = rhoinv + phi + psi;
+    7513             :         }
+    7514             : 
+    7515           0 :         *info = 1;
+    7516           0 :         goto L240;
+    7517             : 
+    7518             :     } else {
+    7519             : 
+    7520        3192 :         niter = 1;
+    7521        3192 :         ip1 = *i__ + 1;
+    7522             : 
+    7523        3192 :         delsq = (d__[ip1] - d__[*i__]) * (d__[ip1] + d__[*i__]);
+    7524        3192 :         delsq2 = delsq / 2.;
+    7525        3192 :         temp = delsq2 / (d__[*i__] +  std::sqrt(d__[*i__] * d__[*i__] + delsq2));
+    7526        3192 :         i__1 = *n;
+    7527      420712 :         for (j = 1; j <= i__1; ++j) {
+    7528      417520 :             work[j] = d__[j] + d__[*i__] + temp;
+    7529      417520 :             delta[j] = d__[j] - d__[*i__] - temp;
+    7530             :         }
+    7531             : 
+    7532             :         psi = 0.;
+    7533        3192 :         i__1 = *i__ - 1;
+    7534      208760 :         for (j = 1; j <= i__1; ++j) {
+    7535      205568 :             psi += z__[j] * z__[j] / (work[j] * delta[j]);
+    7536             :         }
+    7537             : 
+    7538             :         phi = 0.;
+    7539        3192 :         i__1 = *i__ + 2;
+    7540      208760 :         for (j = *n; j >= i__1; --j) {
+    7541      205568 :             phi += z__[j] * z__[j] / (work[j] * delta[j]);
+    7542             :         }
+    7543        3192 :         c__ = rhoinv + psi + phi;
+    7544        3192 :         w = c__ + z__[*i__] * z__[*i__] / (work[*i__] * delta[*i__]) + z__[
+    7545        3192 :                 ip1] * z__[ip1] / (work[ip1] * delta[ip1]);
+    7546             : 
+    7547        3192 :         if (w > 0.) {
+    7548             : 
+    7549        1684 :             orgati = 1;
+    7550             :             sg2lb = 0.;
+    7551             :             sg2ub = delsq2;
+    7552        1684 :             a = c__ * delsq + z__[*i__] * z__[*i__] + z__[ip1] * z__[ip1];
+    7553        1684 :             b = z__[*i__] * z__[*i__] * delsq;
+    7554        1684 :             if (a > 0.) {
+    7555        1655 :                 tau = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+    7556             :             } else {
+    7557          29 :                 tau = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+    7558             :             }
+    7559        1684 :             eta = tau / (d__[*i__] +  std::sqrt(d__[*i__] * d__[*i__] + tau));
+    7560             :         } else {
+    7561             : 
+    7562        1508 :             orgati = 0;
+    7563        1508 :             sg2lb = -delsq2;
+    7564             :             sg2ub = 0.;
+    7565        1508 :             a = c__ * delsq - z__[*i__] * z__[*i__] - z__[ip1] * z__[ip1];
+    7566        1508 :             b = z__[ip1] * z__[ip1] * delsq;
+    7567        1508 :             if (a < 0.) {
+    7568        1480 :                 tau = b * 2. / (a -  std::sqrt(std::abs(a * a + b * 4. * c__)));
+    7569             :             } else {
+    7570          28 :                 tau = -(a +  std::sqrt(std::abs(a * a + b * 4. * c__))) /       (c__ * 2.);
+    7571             :             }
+    7572        1508 :             eta = tau / (d__[ip1] +  std::sqrt(std::abs(d__[ip1] * d__[ip1] + tau)));
+    7573             :         }
+    7574             : 
+    7575        3192 :         if (orgati) {
+    7576        1684 :             ii = *i__;
+    7577        1684 :             *sigma = d__[*i__] + eta;
+    7578        1684 :             i__1 = *n;
+    7579      220971 :             for (j = 1; j <= i__1; ++j) {
+    7580      219287 :                 work[j] = d__[j] + d__[*i__] + eta;
+    7581      219287 :                 delta[j] = d__[j] - d__[*i__] - eta;
+    7582             :             }
+    7583             :         } else {
+    7584        1508 :             ii = *i__ + 1;
+    7585        1508 :             *sigma = d__[ip1] + eta;
+    7586        1508 :             i__1 = *n;
+    7587      199741 :             for (j = 1; j <= i__1; ++j) {
+    7588      198233 :                 work[j] = d__[j] + d__[ip1] + eta;
+    7589      198233 :                 delta[j] = d__[j] - d__[ip1] - eta;
+    7590             :             }
+    7591             :         }
+    7592        3192 :         iim1 = ii - 1;
+    7593        3192 :         iip1 = ii + 1;
+    7594             : 
+    7595             :         dpsi = 0.;
+    7596             :         psi = 0.;
+    7597             :         erretm = 0.;
+    7598             :         i__1 = iim1;
+    7599      210268 :         for (j = 1; j <= i__1; ++j) {
+    7600      207076 :             temp = z__[j] / (work[j] * delta[j]);
+    7601      207076 :             psi += z__[j] * temp;
+    7602      207076 :             dpsi += temp * temp;
+    7603      207076 :             erretm += psi;
+    7604             :         }
+    7605             :         erretm = std::abs(erretm);
+    7606             : 
+    7607             :         dphi = 0.;
+    7608             :         phi = 0.;
+    7609             :         i__1 = iip1;
+    7610      210444 :         for (j = *n; j >= i__1; --j) {
+    7611      207252 :             temp = z__[j] / (work[j] * delta[j]);
+    7612      207252 :             phi += z__[j] * temp;
+    7613      207252 :             dphi += temp * temp;
+    7614      207252 :             erretm += phi;
+    7615             :         }
+    7616             : 
+    7617        3192 :         w = rhoinv + phi + psi;
+    7618             : 
+    7619             :         swtch3 = 0;
+    7620        3192 :         if (orgati) {
+    7621        1684 :             if (w < 0.) {
+    7622             :                 swtch3 = 1;
+    7623             :             }
+    7624             :         } else {
+    7625        1508 :             if (w > 0.) {
+    7626             :                 swtch3 = 1;
+    7627             :             }
+    7628             :         }
+    7629        3192 :         if (ii == 1 || ii == *n) {
+    7630             :             swtch3 = 0;
+    7631             :         }
+    7632             : 
+    7633        3192 :         temp = z__[ii] / (work[ii] * delta[ii]);
+    7634        3192 :         dw = dpsi + dphi + temp * temp;
+    7635        3192 :         temp = z__[ii] * temp;
+    7636        3192 :         w += temp;
+    7637        3192 :         erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. + 
+    7638        3192 :                 std::abs(tau) * dw;
+    7639             : 
+    7640        3192 :         if (std::abs(w) <= eps * erretm) {
+    7641           7 :             goto L240;
+    7642             :         }
+    7643             : 
+    7644        3185 :         if (w <= 0.) {
+    7645        1683 :             sg2lb = (sg2lb > tau) ? sg2lb : tau;
+    7646             :         } else {
+    7647        1502 :             sg2ub = (sg2ub < tau) ? sg2ub : tau;
+    7648             :         }
+    7649             : 
+    7650        3185 :         ++niter;
+    7651        3185 :         if (! swtch3) {
+    7652        2843 :             dtipsq = work[ip1] * delta[ip1];
+    7653        2843 :             dtisq = work[*i__] * delta[*i__];
+    7654        2843 :             if (orgati) {
+    7655        1510 :                 d__1 = z__[*i__] / dtisq;
+    7656        1510 :                 c__ = w - dtipsq * dw + delsq * (d__1 * d__1);
+    7657             :             } else {
+    7658        1333 :                 d__1 = z__[ip1] / dtipsq;
+    7659        1333 :                 c__ = w - dtisq * dw - delsq * (d__1 * d__1);
+    7660             :             }
+    7661        2843 :             a = (dtipsq + dtisq) * w - dtipsq * dtisq * dw;
+    7662        2843 :             b = dtipsq * dtisq * w;
+    7663        2843 :             if ( std::abs(c__)<PLUMED_GMX_DOUBLE_MIN) {
+    7664          23 :                 if ( std::abs(a)<PLUMED_GMX_DOUBLE_MIN) {
+    7665           0 :                     if (orgati) {
+    7666           0 :                         a = z__[*i__] * z__[*i__] + dtipsq * dtipsq * (dpsi + 
+    7667             :                                 dphi);
+    7668             :                     } else {
+    7669           0 :                         a = z__[ip1] * z__[ip1] + dtisq * dtisq * (dpsi + 
+    7670             :                                 dphi);
+    7671             :                     }
+    7672             :                 }
+    7673          23 :                 eta = b / a;
+    7674        2820 :             } else if (a <= 0.) {
+    7675           0 :                 eta = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+    7676             :             } else {
+    7677        2820 :                 eta = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+    7678             :             }
+    7679             :         } else {
+    7680             : 
+    7681         342 :             dtiim = work[iim1] * delta[iim1];
+    7682         342 :             dtiip = work[iip1] * delta[iip1];
+    7683         342 :             temp = rhoinv + psi + phi;
+    7684         342 :             if (orgati) {
+    7685         173 :                 temp1 = z__[iim1] / dtiim;
+    7686         173 :                 temp1 *= temp1;
+    7687         173 :                 c__ = temp - dtiip * (dpsi + dphi) - (d__[iim1] - d__[iip1]) *
+    7688         173 :                          (d__[iim1] + d__[iip1]) * temp1;
+    7689         173 :                 zz[0] = z__[iim1] * z__[iim1];
+    7690         173 :                 if (dpsi < temp1) {
+    7691           0 :                     zz[2] = dtiip * dtiip * dphi;
+    7692             :                 } else {
+    7693         173 :                     zz[2] = dtiip * dtiip * (dpsi - temp1 + dphi);
+    7694             :                 }
+    7695             :             } else {
+    7696         169 :                 temp1 = z__[iip1] / dtiip;
+    7697         169 :                 temp1 *= temp1;
+    7698         169 :                 c__ = temp - dtiim * (dpsi + dphi) - (d__[iip1] - d__[iim1]) *
+    7699         169 :                          (d__[iim1] + d__[iip1]) * temp1;
+    7700         169 :                 if (dphi < temp1) {
+    7701           0 :                     zz[0] = dtiim * dtiim * dpsi;
+    7702             :                 } else {
+    7703         169 :                     zz[0] = dtiim * dtiim * (dpsi + (dphi - temp1));
+    7704             :                 }
+    7705         169 :                 zz[2] = z__[iip1] * z__[iip1];
+    7706             :             }
+    7707         342 :             zz[1] = z__[ii] * z__[ii];
+    7708         342 :             dd[0] = dtiim;
+    7709         342 :             dd[1] = delta[ii] * work[ii];
+    7710         342 :             dd[2] = dtiip;
+    7711         342 :             PLUMED_BLAS_F77_FUNC(dlaed6,DLAED6)(&niter, &orgati, &c__, dd, zz, &w, &eta, info);
+    7712         342 :             if (*info != 0) {
+    7713           0 :                 goto L240;
+    7714             :             }
+    7715             :         }
+    7716             : 
+    7717        3185 :         if (w * eta >= 0.) {
+    7718           0 :             eta = -w / dw;
+    7719             :         }
+    7720        3185 :         if (orgati) {
+    7721        1683 :             temp1 = work[*i__] * delta[*i__];
+    7722        1683 :             temp = eta - temp1;
+    7723             :         } else {
+    7724        1502 :             temp1 = work[ip1] * delta[ip1];
+    7725        1502 :             temp = eta - temp1;
+    7726             :         }
+    7727        3185 :         if (temp > sg2ub || temp < sg2lb) {
+    7728           0 :             if (w < 0.) {
+    7729           0 :                 eta = (sg2ub - tau) / 2.;
+    7730             :             } else {
+    7731           0 :                 eta = (sg2lb - tau) / 2.;
+    7732             :             }
+    7733             :         }
+    7734             : 
+    7735        3185 :         tau += eta;
+    7736        3185 :         eta /= *sigma +  std::sqrt(*sigma * *sigma + eta);
+    7737             : 
+    7738             :         prew = w;
+    7739             : 
+    7740        3185 :         *sigma += eta;
+    7741        3185 :         i__1 = *n;
+    7742      419753 :         for (j = 1; j <= i__1; ++j) {
+    7743      416568 :             work[j] += eta;
+    7744      416568 :             delta[j] -= eta;
+    7745             :         }
+    7746             : 
+    7747             :         dpsi = 0.;
+    7748             :         psi = 0.;
+    7749             :         erretm = 0.;
+    7750             :         i__1 = iim1;
+    7751      210255 :         for (j = 1; j <= i__1; ++j) {
+    7752      207070 :             temp = z__[j] / (work[j] * delta[j]);
+    7753      207070 :             psi += z__[j] * temp;
+    7754      207070 :             dpsi += temp * temp;
+    7755      207070 :             erretm += psi;
+    7756             :         }
+    7757             :         erretm = std::abs(erretm);
+    7758             : 
+    7759             :         dphi = 0.;
+    7760             :         phi = 0.;
+    7761             :         i__1 = iip1;
+    7762      209498 :         for (j = *n; j >= i__1; --j) {
+    7763      206313 :             temp = z__[j] / (work[j] * delta[j]);
+    7764      206313 :             phi += z__[j] * temp;
+    7765      206313 :             dphi += temp * temp;
+    7766      206313 :             erretm += phi;
+    7767             :         }
+    7768             : 
+    7769        3185 :         temp = z__[ii] / (work[ii] * delta[ii]);
+    7770        3185 :         dw = dpsi + dphi + temp * temp;
+    7771        3185 :         temp = z__[ii] * temp;
+    7772        3185 :         w = rhoinv + phi + psi + temp;
+    7773        3185 :         erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. + 
+    7774        3185 :                 std::abs(tau) * dw;
+    7775             : 
+    7776        3185 :         if (w <= 0.) {
+    7777        1672 :             sg2lb = (sg2lb > tau) ? sg2lb : tau;
+    7778             :         } else {
+    7779        1513 :             sg2ub = (sg2ub < tau) ? sg2ub : tau;
+    7780             :         }
+    7781             : 
+    7782             :         swtch = 0;
+    7783        3185 :         if (orgati) {
+    7784        1683 :             if (-w > std::abs(prew) / 10.) {
+    7785             :                 swtch = 1;
+    7786             :             }
+    7787             :         } else {
+    7788        1502 :             if (w > std::abs(prew) / 10.) {
+    7789             :                 swtch = 1;
+    7790             :             }
+    7791             :         }
+    7792             : 
+    7793        3185 :         iter = niter + 1;
+    7794             : 
+    7795        9406 :         for (niter = iter; niter <= 20; ++niter) {
+    7796             : 
+    7797        9406 :             if (std::abs(w) <= eps * erretm) {
+    7798        3185 :                 goto L240;
+    7799             :             }
+    7800             : 
+    7801        6221 :             if (! swtch3) {
+    7802        5176 :                 dtipsq = work[ip1] * delta[ip1];
+    7803        5176 :                 dtisq = work[*i__] * delta[*i__];
+    7804        5176 :                 if (! swtch) {
+    7805        5069 :                     if (orgati) {
+    7806        2626 :                         d__1 = z__[*i__] / dtisq;
+    7807        2626 :                         c__ = w - dtipsq * dw + delsq * (d__1 * d__1);
+    7808             :                     } else {
+    7809        2443 :                         d__1 = z__[ip1] / dtipsq;
+    7810        2443 :                         c__ = w - dtisq * dw - delsq * (d__1 * d__1);
+    7811             :                     }
+    7812             :                 } else {
+    7813         107 :                     temp = z__[ii] / (work[ii] * delta[ii]);
+    7814         107 :                     if (orgati) {
+    7815          69 :                         dpsi += temp * temp;
+    7816             :                     } else {
+    7817          38 :                         dphi += temp * temp;
+    7818             :                     }
+    7819         107 :                     c__ = w - dtisq * dpsi - dtipsq * dphi;
+    7820             :                 }
+    7821        5176 :                 a = (dtipsq + dtisq) * w - dtipsq * dtisq * dw;
+    7822        5176 :                 b = dtipsq * dtisq * w;
+    7823        5176 :                 if (std::abs(c__)<PLUMED_GMX_DOUBLE_MIN) {
+    7824           0 :                     if (std::abs(a)<PLUMED_GMX_DOUBLE_MIN) {
+    7825           0 :                         if (! swtch) {
+    7826           0 :                             if (orgati) {
+    7827           0 :                                 a = z__[*i__] * z__[*i__] + dtipsq * dtipsq * 
+    7828           0 :                                         (dpsi + dphi);
+    7829             :                             } else {
+    7830           0 :                                 a = z__[ip1] * z__[ip1] + dtisq * dtisq * (
+    7831           0 :                                         dpsi + dphi);
+    7832             :                             }
+    7833             :                         } else {
+    7834           0 :                             a = dtisq * dtisq * dpsi + dtipsq * dtipsq * dphi;
+    7835             :                         }
+    7836             :                     }
+    7837           0 :                     eta = b / a;
+    7838        5176 :                 } else if (a <= 0.) {
+    7839           0 :                   eta = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+    7840             :                 } else {
+    7841        5176 :                   eta = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+    7842             :                 }
+    7843             :             } else {
+    7844             : 
+    7845        1045 :                 dtiim = work[iim1] * delta[iim1];
+    7846        1045 :                 dtiip = work[iip1] * delta[iip1];
+    7847        1045 :                 temp = rhoinv + psi + phi;
+    7848        1045 :                 if (swtch) {
+    7849         250 :                     c__ = temp - dtiim * dpsi - dtiip * dphi;
+    7850         250 :                     zz[0] = dtiim * dtiim * dpsi;
+    7851         250 :                     zz[2] = dtiip * dtiip * dphi;
+    7852             :                 } else {
+    7853         795 :                     if (orgati) {
+    7854         399 :                         temp1 = z__[iim1] / dtiim;
+    7855         399 :                         temp1 *= temp1;
+    7856         399 :                         temp2 = (d__[iim1] - d__[iip1]) * (d__[iim1] + d__[
+    7857             :                                 iip1]) * temp1;
+    7858         399 :                         c__ = temp - dtiip * (dpsi + dphi) - temp2;
+    7859         399 :                         zz[0] = z__[iim1] * z__[iim1];
+    7860         399 :                         if (dpsi < temp1) {
+    7861           0 :                             zz[2] = dtiip * dtiip * dphi;
+    7862             :                         } else {
+    7863         399 :                             zz[2] = dtiip * dtiip * (dpsi - temp1 + dphi);
+    7864             :                         }
+    7865             :                     } else {
+    7866         396 :                         temp1 = z__[iip1] / dtiip;
+    7867         396 :                         temp1 *= temp1;
+    7868         396 :                         temp2 = (d__[iip1] - d__[iim1]) * (d__[iim1] + d__[
+    7869             :                                 iip1]) * temp1;
+    7870         396 :                         c__ = temp - dtiim * (dpsi + dphi) - temp2;
+    7871         396 :                         if (dphi < temp1) {
+    7872           0 :                             zz[0] = dtiim * dtiim * dpsi;
+    7873             :                         } else {
+    7874         396 :                             zz[0] = dtiim * dtiim * (dpsi + (dphi - temp1));
+    7875             :                         }
+    7876         396 :                         zz[2] = z__[iip1] * z__[iip1];
+    7877             :                     }
+    7878             :                 }
+    7879        1045 :                 dd[0] = dtiim;
+    7880        1045 :                 dd[1] = delta[ii] * work[ii];
+    7881        1045 :                 dd[2] = dtiip;
+    7882        1045 :                 PLUMED_BLAS_F77_FUNC(dlaed6,DLAED6)(&niter, &orgati, &c__, dd, zz, &w, &eta, info);
+    7883        1045 :                 if (*info != 0) {
+    7884           0 :                     goto L240;
+    7885             :                 }
+    7886             :             }
+    7887             : 
+    7888        6221 :             if (w * eta >= 0.) {
+    7889           0 :                 eta = -w / dw;
+    7890             :             }
+    7891        6221 :             if (orgati) {
+    7892        3228 :                 temp1 = work[*i__] * delta[*i__];
+    7893        3228 :                 temp = eta - temp1;
+    7894             :             } else {
+    7895        2993 :                 temp1 = work[ip1] * delta[ip1];
+    7896        2993 :                 temp = eta - temp1;
+    7897             :             }
+    7898        6221 :             if (temp > sg2ub || temp < sg2lb) {
+    7899           1 :                 if (w < 0.) {
+    7900           1 :                     eta = (sg2ub - tau) / 2.;
+    7901             :                 } else {
+    7902           0 :                     eta = (sg2lb - tau) / 2.;
+    7903             :                 }
+    7904             :             }
+    7905             : 
+    7906        6221 :             tau += eta;
+    7907        6221 :             eta /= *sigma +  std::sqrt(*sigma * *sigma + eta);
+    7908             : 
+    7909        6221 :             *sigma += eta;
+    7910        6221 :             i__1 = *n;
+    7911      819441 :             for (j = 1; j <= i__1; ++j) {
+    7912      813220 :                 work[j] += eta;
+    7913      813220 :                 delta[j] -= eta;
+    7914             :             }
+    7915             : 
+    7916             :             prew = w;
+    7917             : 
+    7918             :             dpsi = 0.;
+    7919             :             psi = 0.;
+    7920             :             erretm = 0.;
+    7921             :             i__1 = iim1;
+    7922      391937 :             for (j = 1; j <= i__1; ++j) {
+    7923      385716 :                 temp = z__[j] / (work[j] * delta[j]);
+    7924      385716 :                 psi += z__[j] * temp;
+    7925      385716 :                 dpsi += temp * temp;
+    7926      385716 :                 erretm += psi;
+    7927             :             }
+    7928             :             erretm = std::abs(erretm);
+    7929             : 
+    7930             :             dphi = 0.;
+    7931             :             phi = 0.;
+    7932             :             i__1 = iip1;
+    7933      427504 :             for (j = *n; j >= i__1; --j) {
+    7934      421283 :                 temp = z__[j] / (work[j] * delta[j]);
+    7935      421283 :                 phi += z__[j] * temp;
+    7936      421283 :                 dphi += temp * temp;
+    7937      421283 :                 erretm += phi;
+    7938             :             }
+    7939             : 
+    7940        6221 :             temp = z__[ii] / (work[ii] * delta[ii]);
+    7941        6221 :             dw = dpsi + dphi + temp * temp;
+    7942        6221 :             temp = z__[ii] * temp;
+    7943        6221 :             w = rhoinv + phi + psi + temp;
+    7944        6221 :             erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. 
+    7945        6221 :                     + std::abs(tau) * dw;
+    7946        6221 :             if (w * prew > 0. && std::abs(w) > std::abs(prew) / 10.) {
+    7947           2 :                 swtch = ! swtch;
+    7948             :             }
+    7949             : 
+    7950        6221 :             if (w <= 0.) {
+    7951        3250 :                 sg2lb = (sg2lb > tau) ? sg2lb : tau;
+    7952             :             } else {
+    7953        2971 :                 sg2ub = (sg2ub < tau) ? sg2ub : tau;
+    7954             :             }
+    7955             :         }
+    7956             : 
+    7957           0 :         *info = 1;
+    7958             : 
+    7959             :     }
+    7960             : 
+    7961        3251 : L240:
+    7962             :     return;
+    7963             : 
+    7964             : } 
+    7965             : }
+    7966             : }
+    7967             : #include <cmath>
+    7968             : #include "lapack.h"
+    7969             : 
+    7970             : #include "blas/blas.h"
+    7971             : namespace PLMD{
+    7972             : namespace lapack{
+    7973             : using namespace blas;
+    7974             : void 
+    7975           0 : PLUMED_BLAS_F77_FUNC(dlasd5,DLASD5)(int *i__, 
+    7976             :         double *d__, 
+    7977             :         double *z__, 
+    7978             :         double *delta, 
+    7979             :         double *rho, 
+    7980             :         double *dsigma, 
+    7981             :         double *work)
+    7982             : {
+    7983             :     double b, c__, w, del, tau, delsq;
+    7984             : 
+    7985             :     --work;
+    7986             :     --delta;
+    7987             :     --z__;
+    7988             :     --d__;
+    7989             : 
+    7990           0 :     del = d__[2] - d__[1];
+    7991           0 :     delsq = del * (d__[2] + d__[1]);
+    7992           0 :     if (*i__ == 1) {
+    7993           0 :         w = *rho * 4. * (z__[2] * z__[2] / (d__[1] + d__[2] * 3.) - z__[1] * 
+    7994           0 :                 z__[1] / (d__[1] * 3. + d__[2])) / del + 1.;
+    7995           0 :         if (w > 0.) {
+    7996           0 :             b = delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+    7997           0 :             c__ = *rho * z__[1] * z__[1] * delsq;
+    7998             : 
+    7999           0 :             tau = c__ * 2. / (b +  std::sqrt(std::abs(b * b - c__ * 4.)));
+    8000             : 
+    8001           0 :             tau /= d__[1] +  std::sqrt(d__[1] * d__[1] + tau);
+    8002           0 :             *dsigma = d__[1] + tau;
+    8003           0 :             delta[1] = -tau;
+    8004           0 :             delta[2] = del - tau;
+    8005           0 :             work[1] = d__[1] * 2. + tau;
+    8006           0 :             work[2] = d__[1] + tau + d__[2];
+    8007             :         } else {
+    8008           0 :             b = -delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+    8009           0 :             c__ = *rho * z__[2] * z__[2] * delsq;
+    8010             : 
+    8011           0 :             if (b > 0.) {
+    8012           0 :                 tau = c__ * -2. / (b +  std::sqrt(b * b + c__ * 4.));
+    8013             :             } else {
+    8014           0 :                 tau = (b -  std::sqrt(b * b + c__ * 4.)) / 2.;
+    8015             :             }
+    8016             : 
+    8017           0 :             tau /= d__[2] +  std::sqrt(std::abs(d__[2] * d__[2] + tau));
+    8018           0 :             *dsigma = d__[2] + tau;
+    8019           0 :             delta[1] = -(del + tau);
+    8020           0 :             delta[2] = -tau;
+    8021           0 :             work[1] = d__[1] + tau + d__[2];
+    8022           0 :             work[2] = d__[2] * 2. + tau;
+    8023             :         }
+    8024             :     } else {
+    8025             : 
+    8026           0 :         b = -delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+    8027           0 :         c__ = *rho * z__[2] * z__[2] * delsq;
+    8028             : 
+    8029           0 :         if (b > 0.) {
+    8030           0 :             tau = (b +  std::sqrt(b * b + c__ * 4.)) / 2.;
+    8031             :         } else {
+    8032           0 :             tau = c__ * 2. / (-b +  std::sqrt(b * b + c__ * 4.));
+    8033             :         }
+    8034           0 :         tau /= d__[2] +  std::sqrt(d__[2] * d__[2] + tau);
+    8035           0 :         *dsigma = d__[2] + tau;
+    8036           0 :         delta[1] = -(del + tau);
+    8037           0 :         delta[2] = -tau;
+    8038           0 :         work[1] = d__[1] + tau + d__[2];
+    8039           0 :         work[2] = d__[2] * 2. + tau;
+    8040             :     }
+    8041           0 :     return;
+    8042             : 
+    8043             : } 
+    8044             : }
+    8045             : }
+    8046             : #include <cmath>
+    8047             : #include "blas/blas.h"
+    8048             : #include "lapack.h"
+    8049             : 
+    8050             : #include "blas/blas.h"
+    8051             : namespace PLMD{
+    8052             : namespace lapack{
+    8053             : using namespace blas;
+    8054             : void 
+    8055           0 : PLUMED_BLAS_F77_FUNC(dlasd6,DLASD6)(int *icompq, 
+    8056             :         int *nl, 
+    8057             :         int *nr, 
+    8058             :         int *sqre, 
+    8059             :         double *d__, 
+    8060             :         double *vf, 
+    8061             :         double *vl, 
+    8062             :         double *alpha, 
+    8063             :         double *beta, 
+    8064             :         int *idxq, 
+    8065             :         int *perm, 
+    8066             :         int *givptr, 
+    8067             :         int *givcol, 
+    8068             :         int *ldgcol, 
+    8069             :         double *givnum,
+    8070             :         int *ldgnum, 
+    8071             :         double *poles, 
+    8072             :         double *difl, 
+    8073             :         double *difr, 
+    8074             :         double *z__, 
+    8075             :         int *k, 
+    8076             :         double *c__, 
+    8077             :         double *s, 
+    8078             :         double *work, 
+    8079             :         int *iwork, 
+    8080             :         int *info)
+    8081             : {
+    8082             :     int givcol_dim1, givcol_offset, givnum_dim1, givnum_offset, 
+    8083             :             poles_dim1, poles_offset, i__1;
+    8084             :     double d__1, d__2;
+    8085             : 
+    8086             :     int i__, m, n, n1, n2, iw, idx, idxc, idxp, ivfw, ivlw;
+    8087             :     int isigma;
+    8088             :     double orgnrm;
+    8089           0 :     int c__0 = 0;
+    8090           0 :     double one = 1.0;
+    8091           0 :     int c__1 = 1;
+    8092           0 :     int c_n1 = -1;
+    8093             : 
+    8094           0 :     --d__;
+    8095             :     --vf;
+    8096             :     --vl;
+    8097             :     --idxq;
+    8098             :     --perm;
+    8099             :     givcol_dim1 = *ldgcol;
+    8100             :     givcol_offset = 1 + givcol_dim1;
+    8101             :     givcol -= givcol_offset;
+    8102           0 :     poles_dim1 = *ldgnum;
+    8103           0 :     poles_offset = 1 + poles_dim1;
+    8104           0 :     poles -= poles_offset;
+    8105             :     givnum_dim1 = *ldgnum;
+    8106             :     givnum_offset = 1 + givnum_dim1;
+    8107             :     givnum -= givnum_offset;
+    8108             :     --difl;
+    8109             :     --difr;
+    8110             :     --z__;
+    8111           0 :     --work;
+    8112             :     --iwork;
+    8113             : 
+    8114           0 :     *info = 0;
+    8115           0 :     n = *nl + *nr + 1;
+    8116           0 :     m = n + *sqre;
+    8117             : 
+    8118             :     isigma = 1;
+    8119           0 :     iw = isigma + n;
+    8120           0 :     ivfw = iw + m;
+    8121           0 :     ivlw = ivfw + m;
+    8122             : 
+    8123             :     idx = 1;
+    8124             :     idxc = idx + n;
+    8125           0 :     idxp = idxc + n;
+    8126             : 
+    8127           0 :     d__1 = std::abs(*alpha); 
+    8128           0 :     d__2 = std::abs(*beta);
+    8129           0 :     orgnrm = (d__1 > d__2) ? d__1 : d__2;
+    8130           0 :     d__[*nl + 1] = 0.;
+    8131             :     i__1 = n;
+    8132           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    8133           0 :       d__1 = std::abs(d__[i__]);
+    8134           0 :         if (d__1 > orgnrm)
+    8135           0 :             orgnrm = d__1;
+    8136             :     }
+    8137           0 :     PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &orgnrm, &one, &n, &c__1, &d__[1], &n, info);
+    8138           0 :     *alpha /= orgnrm;
+    8139           0 :     *beta /= orgnrm;
+    8140             : 
+    8141           0 :     PLUMED_BLAS_F77_FUNC(dlasd7,DLASD7)(icompq, nl, nr, sqre, k, &d__[1], &z__[1], &work[iw], &vf[1], &
+    8142           0 :             work[ivfw], &vl[1], &work[ivlw], alpha, beta, &work[isigma], &
+    8143           0 :             iwork[idx], &iwork[idxp], &idxq[1], &perm[1], givptr, &givcol[
+    8144             :             givcol_offset], ldgcol, &givnum[givnum_offset], ldgnum, c__, s, 
+    8145             :             info);
+    8146             : 
+    8147           0 :     PLUMED_BLAS_F77_FUNC(dlasd8,DLASD8)(icompq, k, &d__[1], &z__[1], &vf[1], &vl[1], &difl[1], &difr[1], 
+    8148             :             ldgnum, &work[isigma], &work[iw], info);
+    8149             : 
+    8150           0 :     if (*icompq == 1) {
+    8151           0 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(k, &d__[1], &c__1, &poles[poles_dim1 + 1], &c__1);
+    8152           0 :         PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(k, &work[isigma], &c__1, &poles[(poles_dim1 << 1) + 1], &c__1);
+    8153             :     }
+    8154             : 
+    8155           0 :     PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &one, &orgnrm, &n, &c__1, &d__[1], &n, info);
+    8156             : 
+    8157           0 :     n1 = *k;
+    8158           0 :     n2 = n - *k;
+    8159           0 :     PLUMED_BLAS_F77_FUNC(dlamrg,DLAMRG)(&n1, &n2, &d__[1], &c__1, &c_n1, &idxq[1]);
+    8160             : 
+    8161           0 :     return;
+    8162             : 
+    8163             : }
+    8164             : 
+    8165             : 
+    8166             : }
+    8167             : }
+    8168             : #include <cmath>
+    8169             : #include "real.h"
+    8170             : 
+    8171             : #include "blas/blas.h"
+    8172             : #include "lapack.h"
+    8173             : #include "lapack_limits.h"
+    8174             : 
+    8175             : #include "blas/blas.h"
+    8176             : namespace PLMD{
+    8177             : namespace lapack{
+    8178             : using namespace blas;
+    8179             : void 
+    8180           0 : PLUMED_BLAS_F77_FUNC(dlasd7,DLASD7)(int *icompq, 
+    8181             :         int *nl, 
+    8182             :         int *nr, 
+    8183             :         int *sqre, 
+    8184             :         int *k, 
+    8185             :         double *d__, 
+    8186             :         double *z__, 
+    8187             :         double *zw, 
+    8188             :         double *vf, 
+    8189             :         double *vfw,
+    8190             :         double *vl, 
+    8191             :         double *vlw,
+    8192             :         double *alpha, 
+    8193             :         double *beta,
+    8194             :         double *dsigma, 
+    8195             :         int *idx, 
+    8196             :         int *idxp,
+    8197             :         int *idxq, 
+    8198             :         int *perm, 
+    8199             :         int *givptr,
+    8200             :         int *givcol, 
+    8201             :         int *ldgcol, 
+    8202             :         double *givnum,
+    8203             :         int *ldgnum, 
+    8204             :         double *c__, 
+    8205             :         double *s, 
+    8206             :         int *info)
+    8207             : {
+    8208             :     int givcol_dim1, givcol_offset, givnum_dim1, givnum_offset, i__1;
+    8209             :     double d__1, d__2;
+    8210             : 
+    8211             :     int i__, j, m, n, k2;
+    8212             :     double z1;
+    8213             :     int jp;
+    8214             :     double eps, tau, tol;
+    8215             :     int nlp1, nlp2, idxi, idxj;
+    8216             :     int idxjp;
+    8217             :     int jprev = 0;
+    8218             :     double hlftol;
+    8219           0 :     int c__1 = 1;
+    8220             : 
+    8221           0 :     --d__;
+    8222           0 :     --z__;
+    8223           0 :     --zw;
+    8224           0 :     --vf;
+    8225           0 :     --vfw;
+    8226           0 :     --vl;
+    8227           0 :     --vlw;
+    8228           0 :     --dsigma;
+    8229           0 :     --idx;
+    8230           0 :     --idxp;
+    8231           0 :     --idxq;
+    8232           0 :     --perm;
+    8233           0 :     givcol_dim1 = *ldgcol;
+    8234           0 :     givcol_offset = 1 + givcol_dim1;
+    8235           0 :     givcol -= givcol_offset;
+    8236           0 :     givnum_dim1 = *ldgnum;
+    8237           0 :     givnum_offset = 1 + givnum_dim1;
+    8238           0 :     givnum -= givnum_offset;
+    8239             : 
+    8240           0 :     *info = 0;
+    8241           0 :     n = *nl + *nr + 1;
+    8242           0 :     m = n + *sqre;
+    8243             : 
+    8244           0 :     nlp1 = *nl + 1;
+    8245           0 :     nlp2 = *nl + 2;
+    8246           0 :     if (*icompq == 1) {
+    8247           0 :         *givptr = 0;
+    8248             :     }
+    8249             : 
+    8250           0 :     z1 = *alpha * vl[nlp1];
+    8251           0 :     vl[nlp1] = 0.;
+    8252           0 :     tau = vf[nlp1];
+    8253           0 :     for (i__ = *nl; i__ >= 1; --i__) {
+    8254           0 :         z__[i__ + 1] = *alpha * vl[i__];
+    8255           0 :         vl[i__] = 0.;
+    8256           0 :         vf[i__ + 1] = vf[i__];
+    8257           0 :         d__[i__ + 1] = d__[i__];
+    8258           0 :         idxq[i__ + 1] = idxq[i__] + 1;
+    8259             :     }
+    8260           0 :     vf[1] = tau;
+    8261             : 
+    8262             :     i__1 = m;
+    8263           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+    8264           0 :         z__[i__] = *beta * vf[i__];
+    8265           0 :         vf[i__] = 0.;
+    8266             :     }
+    8267           0 :     i__1 = n;
+    8268           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+    8269           0 :         idxq[i__] += nlp1;
+    8270             :     }
+    8271             : 
+    8272             :     i__1 = n;
+    8273           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+    8274           0 :         dsigma[i__] = d__[idxq[i__]];
+    8275           0 :         zw[i__] = z__[idxq[i__]];
+    8276           0 :         vfw[i__] = vf[idxq[i__]];
+    8277           0 :         vlw[i__] = vl[idxq[i__]];
+    8278             :     }
+    8279             : 
+    8280           0 :     PLUMED_BLAS_F77_FUNC(dlamrg,DLAMRG)(nl, nr, &dsigma[2], &c__1, &c__1, &idx[2]);
+    8281             : 
+    8282           0 :     i__1 = n;
+    8283           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+    8284           0 :         idxi = idx[i__] + 1;
+    8285           0 :         d__[i__] = dsigma[idxi];
+    8286           0 :         z__[i__] = zw[idxi];
+    8287           0 :         vf[i__] = vfw[idxi];
+    8288           0 :         vl[i__] = vlw[idxi];
+    8289             :     }
+    8290             : 
+    8291             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    8292             : 
+    8293           0 :     d__1 = std::abs(*alpha);
+    8294           0 :     d__2 = std::abs(*beta);
+    8295           0 :     tol = (d__1>d__2) ? d__1 : d__2;
+    8296           0 :     d__2 = std::abs(d__[n]);
+    8297           0 :     tol = eps * 64. * ((d__2>tol) ? d__2 : tol);
+    8298             : 
+    8299           0 :     *k = 1;
+    8300           0 :     k2 = n + 1;
+    8301             :     i__1 = n;
+    8302           0 :     for (j = 2; j <= i__1; ++j) {
+    8303           0 :         if (std::abs(z__[j]) <= tol) {
+    8304             : 
+    8305           0 :             --k2;
+    8306           0 :             idxp[k2] = j;
+    8307           0 :             if (j == n) {
+    8308           0 :                 goto L100;
+    8309             :             }
+    8310             :         } else {
+    8311             :             jprev = j;
+    8312           0 :             goto L70;
+    8313             :         }
+    8314             :     }
+    8315           0 : L70:
+    8316             :     j = jprev;
+    8317           0 : L80:
+    8318           0 :     ++j;
+    8319           0 :     if (j > n) {
+    8320           0 :         goto L90;
+    8321             :     }
+    8322           0 :     if (std::abs(z__[j]) <= tol) {
+    8323             : 
+    8324           0 :         --k2;
+    8325           0 :         idxp[k2] = j;
+    8326             :     } else {
+    8327             : 
+    8328           0 :         if (std::abs(d__[j] - d__[jprev]) <= tol) {
+    8329             : 
+    8330           0 :             *s = z__[jprev];
+    8331           0 :             *c__ = z__[j];
+    8332             : 
+    8333           0 :             tau = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(c__, s);
+    8334           0 :             z__[j] = tau;
+    8335           0 :             z__[jprev] = 0.;
+    8336           0 :             *c__ /= tau;
+    8337           0 :             *s = -(*s) / tau;
+    8338             : 
+    8339             : 
+    8340           0 :             if (*icompq == 1) {
+    8341           0 :                 ++(*givptr);
+    8342           0 :                 idxjp = idxq[idx[jprev] + 1];
+    8343           0 :                 idxj = idxq[idx[j] + 1];
+    8344           0 :                 if (idxjp <= nlp1) {
+    8345           0 :                     --idxjp;
+    8346             :                 }
+    8347           0 :                 if (idxj <= nlp1) {
+    8348           0 :                     --idxj;
+    8349             :                 }
+    8350           0 :                 givcol[*givptr + (givcol_dim1 << 1)] = idxjp;
+    8351           0 :                 givcol[*givptr + givcol_dim1] = idxj;
+    8352           0 :                 givnum[*givptr + (givnum_dim1 << 1)] = *c__;
+    8353           0 :                 givnum[*givptr + givnum_dim1] = *s;
+    8354             :             }
+    8355           0 :             PLUMED_BLAS_F77_FUNC(drot,DROT)(&c__1, &vf[jprev], &c__1, &vf[j], &c__1, c__, s);
+    8356           0 :             PLUMED_BLAS_F77_FUNC(drot,DROT)(&c__1, &vl[jprev], &c__1, &vl[j], &c__1, c__, s);
+    8357           0 :             --k2;
+    8358           0 :             idxp[k2] = jprev;
+    8359             :             jprev = j;
+    8360             :         } else {
+    8361           0 :             ++(*k);
+    8362           0 :             zw[*k] = z__[jprev];
+    8363           0 :             dsigma[*k] = d__[jprev];
+    8364           0 :             idxp[*k] = jprev;
+    8365             :             jprev = j;
+    8366             :         }
+    8367             :     }
+    8368           0 :     goto L80;
+    8369             : L90:
+    8370             : 
+    8371           0 :     ++(*k);
+    8372           0 :     zw[*k] = z__[jprev];
+    8373           0 :     dsigma[*k] = d__[jprev];
+    8374           0 :     idxp[*k] = jprev;
+    8375             : 
+    8376           0 : L100:
+    8377             : 
+    8378           0 :     i__1 = n;
+    8379           0 :     for (j = 2; j <= i__1; ++j) {
+    8380           0 :         jp = idxp[j];
+    8381           0 :         dsigma[j] = d__[jp];
+    8382           0 :         vfw[j] = vf[jp];
+    8383           0 :         vlw[j] = vl[jp];
+    8384             :     }
+    8385           0 :     if (*icompq == 1) {
+    8386             :         i__1 = n;
+    8387           0 :         for (j = 2; j <= i__1; ++j) {
+    8388           0 :             jp = idxp[j];
+    8389           0 :             perm[j] = idxq[idx[jp] + 1];
+    8390           0 :             if (perm[j] <= nlp1) {
+    8391           0 :                 --perm[j];
+    8392             :             }
+    8393             :         }
+    8394             :     }
+    8395           0 :     i__1 = n - *k;
+    8396           0 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &dsigma[*k + 1], &c__1, &d__[*k + 1], &c__1);
+    8397             : 
+    8398           0 :     dsigma[1] = 0.;
+    8399           0 :     hlftol = tol / 2.;
+    8400           0 :     if (std::abs(dsigma[2]) <= hlftol) {
+    8401           0 :         dsigma[2] = hlftol;
+    8402             :     }
+    8403           0 :     if (m > n) {
+    8404           0 :         z__[1] = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(&z1, &z__[m]);
+    8405           0 :         if (z__[1] <= tol) {
+    8406           0 :             *c__ = 1.;
+    8407           0 :             *s = 0.;
+    8408           0 :             z__[1] = tol;
+    8409             :         } else {
+    8410           0 :             *c__ = z1 / z__[1];
+    8411           0 :             *s = -z__[m] / z__[1];
+    8412             :         }
+    8413           0 :         PLUMED_BLAS_F77_FUNC(drot,DROT)(&c__1, &vf[m], &c__1, &vf[1], &c__1, c__, s);
+    8414           0 :         PLUMED_BLAS_F77_FUNC(drot,DROT)(&c__1, &vl[m], &c__1, &vl[1], &c__1, c__, s);
+    8415             :     } else {
+    8416           0 :         if (std::abs(z1) <= tol) {
+    8417           0 :             z__[1] = tol;
+    8418             :         } else {
+    8419           0 :             z__[1] = z1;
+    8420             :         }
+    8421             :     }
+    8422             : 
+    8423           0 :     i__1 = *k - 1;
+    8424           0 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &zw[2], &c__1, &z__[2], &c__1);
+    8425           0 :     i__1 = n - 1;
+    8426           0 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &vfw[2], &c__1, &vf[2], &c__1);
+    8427           0 :     i__1 = n - 1;
+    8428           0 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &vlw[2], &c__1, &vl[2], &c__1);
+    8429             : 
+    8430           0 :     return;
+    8431             : 
+    8432             : }
+    8433             : 
+    8434             : 
+    8435             : }
+    8436             : }
+    8437             : #include <cmath>
+    8438             : #include "blas/blas.h"
+    8439             : #include "lapack.h"
+    8440             : 
+    8441             : #include "blas/blas.h"
+    8442             : namespace PLMD{
+    8443             : namespace lapack{
+    8444             : using namespace blas;
+    8445             : void 
+    8446           0 : PLUMED_BLAS_F77_FUNC(dlasd8,DLASD8)(int *icompq, 
+    8447             :         int *k, 
+    8448             :         double *d__, 
+    8449             :         double *z__, 
+    8450             :         double *vf, 
+    8451             :         double *vl, 
+    8452             :         double *difl, 
+    8453             :         double *difr, 
+    8454             :         int *lddifr, 
+    8455             :         double *dsigma, 
+    8456             :         double *work, 
+    8457             :         int *info)
+    8458             : {
+    8459             :     int difr_dim1, difr_offset, i__1, i__2;
+    8460             :     double d__2;
+    8461             : 
+    8462             :     int i__, j;
+    8463             :     double dj, rho;
+    8464             :     int iwk1, iwk2, iwk3;
+    8465             :     double temp;
+    8466             :     int iwk2i, iwk3i;
+    8467             :     double diflj, difrj, dsigj;
+    8468             :     double dsigjp;
+    8469           0 :     int c__1 = 1;
+    8470           0 :     int c__0 = 0;
+    8471           0 :     double one = 1.;
+    8472             : 
+    8473             :     /* avoid warnings on high gcc optimization levels */
+    8474             :     difrj = dsigjp = 0;
+    8475             : 
+    8476           0 :      --d__;
+    8477           0 :     --z__;
+    8478             :     --vf;
+    8479             :     --vl;
+    8480           0 :     --difl;
+    8481           0 :     difr_dim1 = *lddifr;
+    8482           0 :     difr_offset = 1 + difr_dim1;
+    8483           0 :     difr -= difr_offset;
+    8484           0 :     --dsigma;
+    8485           0 :     --work;
+    8486             : 
+    8487           0 :     *info = 0;
+    8488             : 
+    8489           0 :     if (*k == 1) {
+    8490           0 :         d__[1] = std::abs(z__[1]);
+    8491           0 :         difl[1] = d__[1];
+    8492           0 :         if (*icompq == 1) {
+    8493           0 :             difl[2] = 1.;
+    8494           0 :             difr[(difr_dim1 << 1) + 1] = 1.;
+    8495             :         }
+    8496           0 :         return;
+    8497             :     }
+    8498             : 
+    8499             :     iwk1 = 1;
+    8500           0 :     iwk2 = iwk1 + *k;
+    8501           0 :     iwk3 = iwk2 + *k;
+    8502             :     iwk2i = iwk2 - 1;
+    8503           0 :     iwk3i = iwk3 - 1;
+    8504             : 
+    8505           0 :     rho = PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(k, &z__[1], &c__1);
+    8506           0 :     PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &rho, &one, k, &c__1, &z__[1], k, info);
+    8507           0 :     rho *= rho;
+    8508             : 
+    8509           0 :     PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", k, &c__1, &one, &one, &work[iwk3], k);
+    8510             : 
+    8511           0 :     i__1 = *k;
+    8512           0 :     for (j = 1; j <= i__1; ++j) {
+    8513           0 :         PLUMED_BLAS_F77_FUNC(dlasd4,DLASD4)(k, &j, &dsigma[1], &z__[1], &work[iwk1], &rho, &d__[j], &work[
+    8514           0 :                 iwk2], info);
+    8515             : 
+    8516           0 :         if (*info != 0) {
+    8517             :             return;
+    8518             :         }
+    8519           0 :         work[iwk3i + j] = work[iwk3i + j] * work[j] * work[iwk2i + j];
+    8520           0 :         difl[j] = -work[j];
+    8521           0 :         difr[j + difr_dim1] = -work[j + 1];
+    8522             :         i__2 = j - 1;
+    8523           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    8524           0 :             work[iwk3i + i__] = work[iwk3i + i__] * work[i__] * work[iwk2i + 
+    8525           0 :                     i__] / (dsigma[i__] - dsigma[j]) / (dsigma[i__] + dsigma[
+    8526             :                     j]);
+    8527             :         }
+    8528           0 :         i__2 = *k;
+    8529           0 :         for (i__ = j + 1; i__ <= i__2; ++i__) {
+    8530           0 :             work[iwk3i + i__] = work[iwk3i + i__] * work[i__] * work[iwk2i + 
+    8531           0 :                     i__] / (dsigma[i__] - dsigma[j]) / (dsigma[i__] + dsigma[
+    8532             :                     j]);
+    8533             :         }
+    8534             :     }
+    8535             : 
+    8536           0 :     i__1 = *k;
+    8537           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    8538           0 :         d__2 =  std::sqrt(std::abs(work[iwk3i + i__]));
+    8539           0 :         z__[i__] = (z__[i__] > 0) ? d__2 : -d__2;
+    8540             :     }
+    8541             : 
+    8542           0 :     i__1 = *k;
+    8543           0 :     for (j = 1; j <= i__1; ++j) {
+    8544           0 :         diflj = difl[j];
+    8545           0 :         dj = d__[j];
+    8546           0 :         dsigj = -dsigma[j];
+    8547           0 :         if (j < *k) {
+    8548           0 :             difrj = -difr[j + difr_dim1];
+    8549           0 :             dsigjp = -dsigma[j + 1];
+    8550             :         }
+    8551           0 :         work[j] = -z__[j] / diflj / (dsigma[j] + dj);
+    8552             :         i__2 = j - 1;
+    8553           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+    8554           0 :         work[i__] = z__[i__] / (dsigma[i__] + dsigj - diflj) / ( dsigma[i__] + dj);
+    8555             :         }
+    8556           0 :         i__2 = *k;
+    8557           0 :         for (i__ = j + 1; i__ <= i__2; ++i__) {
+    8558           0 :             work[i__] = z__[i__] / (dsigma[i__] + dsigjp - difrj) / (dsigma[i__] + dj);
+    8559             :         }
+    8560           0 :         temp = PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(k, &work[1], &c__1);
+    8561           0 :         work[iwk2i + j] = PLUMED_BLAS_F77_FUNC(ddot,DDOT)(k, &work[1], &c__1, &vf[1], &c__1) / temp;
+    8562           0 :         work[iwk3i + j] = PLUMED_BLAS_F77_FUNC(ddot,DDOT)(k, &work[1], &c__1, &vl[1], &c__1) / temp;
+    8563           0 :         if (*icompq == 1) {
+    8564           0 :             difr[j + (difr_dim1 << 1)] = temp;
+    8565             :         }
+    8566             :     }
+    8567             : 
+    8568           0 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(k, &work[iwk2], &c__1, &vf[1], &c__1);
+    8569           0 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(k, &work[iwk3], &c__1, &vl[1], &c__1);
+    8570             : 
+    8571             :     return;
+    8572             : 
+    8573             : } 
+    8574             : }
+    8575             : }
+    8576             : #include "blas/blas.h"
+    8577             : #include "lapack.h"
+    8578             : 
+    8579             : #include "blas/blas.h"
+    8580             : namespace PLMD{
+    8581             : namespace lapack{
+    8582             : using namespace blas;
+    8583             : void 
+    8584           0 : PLUMED_BLAS_F77_FUNC(dlasda,DLASDA)(int *icompq, 
+    8585             :         int *smlsiz, 
+    8586             :         int *n, 
+    8587             :         int *sqre, 
+    8588             :         double *d__, 
+    8589             :         double *e, 
+    8590             :         double *u, 
+    8591             :         int *ldu, 
+    8592             :         double *vt, 
+    8593             :         int *k, 
+    8594             :         double *difl, 
+    8595             :         double *difr, 
+    8596             :         double *z__, 
+    8597             :         double *poles, 
+    8598             :         int *givptr, 
+    8599             :         int *givcol, 
+    8600             :         int *ldgcol, 
+    8601             :         int *perm, 
+    8602             :         double *givnum, 
+    8603             :         double *c__, 
+    8604             :         double *s, 
+    8605             :         double *work, 
+    8606             :         int *iwork, 
+    8607             :         int *info)
+    8608             : {
+    8609             :     int givcol_dim1, givcol_offset, perm_dim1, perm_offset, difl_dim1, 
+    8610             :             difl_offset, difr_dim1, difr_offset, givnum_dim1, givnum_offset, 
+    8611             :             poles_dim1, poles_offset, u_dim1, u_offset, vt_dim1, vt_offset, 
+    8612             :             z_dim1, z_offset, i__1, i__2;
+    8613             : 
+    8614             :     int i__, j, m, i1, ic, lf, nd, ll, nl, vf, nr, vl, im1, ncc, 
+    8615             :             nlf, nrf, vfi, iwk, vli, lvl, nru, ndb1, nlp1, lvl2, nrp1;
+    8616             :     double beta;
+    8617             :     int idxq, nlvl;
+    8618             :     double alpha;
+    8619             :     int inode, ndiml, ndimr, idxqi, itemp;
+    8620             :     int sqrei;
+    8621             :     int nwork1, nwork2;
+    8622             :     int smlszp;
+    8623           0 :     int c__0 = 0;
+    8624           0 :     double zero = 0.0;
+    8625           0 :     double one = 1.;
+    8626           0 :     int c__1 = 1;
+    8627           0 :     --d__;
+    8628           0 :     --e;
+    8629           0 :     givnum_dim1 = *ldu;
+    8630           0 :     givnum_offset = 1 + givnum_dim1;
+    8631           0 :     givnum -= givnum_offset;
+    8632             :     poles_dim1 = *ldu;
+    8633             :     poles_offset = 1 + poles_dim1;
+    8634             :     poles -= poles_offset;
+    8635             :     z_dim1 = *ldu;
+    8636             :     z_offset = 1 + z_dim1;
+    8637             :     z__ -= z_offset;
+    8638             :     difr_dim1 = *ldu;
+    8639             :     difr_offset = 1 + difr_dim1;
+    8640             :     difr -= difr_offset;
+    8641             :     difl_dim1 = *ldu;
+    8642             :     difl_offset = 1 + difl_dim1;
+    8643             :     difl -= difl_offset;
+    8644             :     vt_dim1 = *ldu;
+    8645             :     vt_offset = 1 + vt_dim1;
+    8646           0 :     vt -= vt_offset;
+    8647             :     u_dim1 = *ldu;
+    8648             :     u_offset = 1 + u_dim1;
+    8649           0 :     u -= u_offset;
+    8650             :     --k;
+    8651             :     --givptr;
+    8652           0 :     perm_dim1 = *ldgcol;
+    8653           0 :     perm_offset = 1 + perm_dim1;
+    8654           0 :     perm -= perm_offset;
+    8655             :     givcol_dim1 = *ldgcol;
+    8656             :     givcol_offset = 1 + givcol_dim1;
+    8657             :     givcol -= givcol_offset;
+    8658             :     --c__;
+    8659             :     --s;
+    8660           0 :     --work;
+    8661           0 :     --iwork;
+    8662           0 :     *info = 0;
+    8663             : 
+    8664           0 :     m = *n + *sqre;
+    8665             : 
+    8666           0 :     if (*n <= *smlsiz) {
+    8667           0 :         if (*icompq == 0) {
+    8668           0 :             PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U", sqre, n, &c__0, &c__0, &c__0, &d__[1], &e[1], &vt[
+    8669             :                     vt_offset], ldu, &u[u_offset], ldu, &u[u_offset], ldu, &
+    8670             :                     work[1], info);
+    8671             :         } else {
+    8672           0 :             PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U", sqre, n, &m, n, &c__0, &d__[1], &e[1], &vt[vt_offset]
+    8673             :                     , ldu, &u[u_offset], ldu, &u[u_offset], ldu, &work[1], 
+    8674             :                     info);
+    8675             :         }
+    8676           0 :         return;
+    8677             :     }
+    8678             : 
+    8679             :     inode = 1;
+    8680           0 :     ndiml = inode + *n;
+    8681           0 :     ndimr = ndiml + *n;
+    8682           0 :     idxq = ndimr + *n;
+    8683           0 :     iwk = idxq + *n;
+    8684             : 
+    8685           0 :     ncc = 0;
+    8686           0 :     nru = 0;
+    8687             : 
+    8688           0 :     smlszp = *smlsiz + 1;
+    8689             :     vf = 1;
+    8690           0 :     vl = vf + m;
+    8691           0 :     nwork1 = vl + m;
+    8692           0 :     nwork2 = nwork1 + smlszp * smlszp;
+    8693             : 
+    8694           0 :     PLUMED_BLAS_F77_FUNC(dlasdt,DLASDT)(n, &nlvl, &nd, &iwork[inode], &iwork[ndiml], &iwork[ndimr], 
+    8695             :             smlsiz);
+    8696             : 
+    8697           0 :     ndb1 = (nd + 1) / 2;
+    8698             :     i__1 = nd;
+    8699           0 :     for (i__ = ndb1; i__ <= i__1; ++i__) {
+    8700           0 :         i1 = i__ - 1;
+    8701           0 :         ic = iwork[inode + i1];
+    8702           0 :         nl = iwork[ndiml + i1];
+    8703           0 :         nlp1 = nl + 1;
+    8704           0 :         nr = iwork[ndimr + i1];
+    8705           0 :         nlf = ic - nl;
+    8706           0 :         nrf = ic + 1;
+    8707           0 :         idxqi = idxq + nlf - 2;
+    8708             :         vfi = vf + nlf - 1;
+    8709           0 :         vli = vl + nlf - 1;
+    8710           0 :         sqrei = 1;
+    8711           0 :         if (*icompq == 0) {
+    8712           0 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", &nlp1, &nlp1, &zero, &one, &work[nwork1], &smlszp);
+    8713           0 :             PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U", &sqrei, &nl, &nlp1, &nru, &ncc, &d__[nlf], &e[nlf], &
+    8714             :                     work[nwork1], &smlszp, &work[nwork2], &nl, &work[nwork2], 
+    8715           0 :                     &nl, &work[nwork2], info);
+    8716           0 :             itemp = nwork1 + nl * smlszp;
+    8717           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&nlp1, &work[nwork1], &c__1, &work[vfi], &c__1);
+    8718           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&nlp1, &work[itemp], &c__1, &work[vli], &c__1);
+    8719             :         } else {
+    8720           0 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", &nl, &nl, &zero, &one, &u[nlf + u_dim1], ldu);
+    8721           0 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", &nlp1, &nlp1, &zero, &one, &vt[nlf + vt_dim1], 
+    8722             :                     ldu);
+    8723           0 :             PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U", &sqrei, &nl, &nlp1, &nl, &ncc, &d__[nlf], &e[nlf], &
+    8724             :                     vt[nlf + vt_dim1], ldu, &u[nlf + u_dim1], ldu, &u[nlf + 
+    8725           0 :                     u_dim1], ldu, &work[nwork1], info);
+    8726           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&nlp1, &vt[nlf + vt_dim1], &c__1, &work[vfi], &c__1);
+    8727           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&nlp1, &vt[nlf + nlp1 * vt_dim1], &c__1, &work[vli], &c__1)
+    8728             :                     ;
+    8729             :         }
+    8730           0 :         if (*info != 0) {
+    8731             :             return;
+    8732             :         }
+    8733           0 :         i__2 = nl;
+    8734           0 :         for (j = 1; j <= i__2; ++j) {
+    8735           0 :             iwork[idxqi + j] = j;
+    8736             :         }
+    8737           0 :         if (i__ == nd && *sqre == 0) {
+    8738           0 :             sqrei = 0;
+    8739             :         } else {
+    8740           0 :             sqrei = 1;
+    8741             :         }
+    8742           0 :         idxqi += nlp1;
+    8743           0 :         vfi += nlp1;
+    8744           0 :         vli += nlp1;
+    8745           0 :         nrp1 = nr + sqrei;
+    8746           0 :         if (*icompq == 0) {
+    8747           0 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", &nrp1, &nrp1, &zero, &one, &work[nwork1], &smlszp);
+    8748           0 :             PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U", &sqrei, &nr, &nrp1, &nru, &ncc, &d__[nrf], &e[nrf], &
+    8749             :                     work[nwork1], &smlszp, &work[nwork2], &nr, &work[nwork2], 
+    8750           0 :                     &nr, &work[nwork2], info);
+    8751           0 :             itemp = nwork1 + (nrp1 - 1) * smlszp;
+    8752           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&nrp1, &work[nwork1], &c__1, &work[vfi], &c__1);
+    8753           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&nrp1, &work[itemp], &c__1, &work[vli], &c__1);
+    8754             :         } else {
+    8755           0 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", &nr, &nr, &zero, &one, &u[nrf + u_dim1], ldu);
+    8756           0 :             PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("A", &nrp1, &nrp1, &zero, &one, &vt[nrf + vt_dim1], 
+    8757             :                     ldu);
+    8758           0 :             PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)("U", &sqrei, &nr, &nrp1, &nr, &ncc, &d__[nrf], &e[nrf], &
+    8759             :                     vt[nrf + vt_dim1], ldu, &u[nrf + u_dim1], ldu, &u[nrf + 
+    8760           0 :                     u_dim1], ldu, &work[nwork1], info);
+    8761           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&nrp1, &vt[nrf + vt_dim1], &c__1, &work[vfi], &c__1);
+    8762           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&nrp1, &vt[nrf + nrp1 * vt_dim1], &c__1, &work[vli], &c__1)
+    8763             :                     ;
+    8764             :         }
+    8765           0 :         if (*info != 0) {
+    8766             :             return;
+    8767             :         }
+    8768           0 :         i__2 = nr;
+    8769           0 :         for (j = 1; j <= i__2; ++j) {
+    8770           0 :             iwork[idxqi + j] = j;
+    8771             :         }
+    8772             :     }
+    8773             : 
+    8774           0 :     j = (1 << nlvl);
+    8775             : 
+    8776           0 :     for (lvl = nlvl; lvl >= 1; --lvl) {
+    8777           0 :         lvl2 = (lvl << 1) - 1;
+    8778             : 
+    8779           0 :         if (lvl == 1) {
+    8780             :             lf = 1;
+    8781             :             ll = 1;
+    8782             :         } else {
+    8783           0 :             lf = (1 << (lvl-1));
+    8784           0 :             ll = (lf << 1) - 1;
+    8785             :         }
+    8786             :         i__1 = ll;
+    8787           0 :         for (i__ = lf; i__ <= i__1; ++i__) {
+    8788           0 :             im1 = i__ - 1;
+    8789           0 :             ic = iwork[inode + im1];
+    8790           0 :             nl = iwork[ndiml + im1];
+    8791           0 :             nr = iwork[ndimr + im1];
+    8792           0 :             nlf = ic - nl;
+    8793           0 :             if (i__ == ll) {
+    8794           0 :                 sqrei = *sqre;
+    8795             :             } else {
+    8796           0 :                 sqrei = 1;
+    8797             :             }
+    8798             :             vfi = vf + nlf - 1;
+    8799           0 :             vli = vl + nlf - 1;
+    8800           0 :             idxqi = idxq + nlf - 1;
+    8801           0 :             alpha = d__[ic];
+    8802           0 :             beta = e[ic];
+    8803           0 :             if (*icompq == 0) {
+    8804           0 :                 PLUMED_BLAS_F77_FUNC(dlasd6,DLASD6)(icompq, &nl, &nr, &sqrei, &d__[nlf], &work[vfi], &
+    8805           0 :                         work[vli], &alpha, &beta, &iwork[idxqi], &perm[
+    8806             :                         perm_offset], &givptr[1], &givcol[givcol_offset], 
+    8807             :                         ldgcol, &givnum[givnum_offset], ldu, &poles[
+    8808             :                         poles_offset], &difl[difl_offset], &difr[difr_offset],
+    8809           0 :                          &z__[z_offset], &k[1], &c__[1], &s[1], &work[nwork1],
+    8810           0 :                          &iwork[iwk], info);
+    8811             :             } else {
+    8812           0 :                 --j;
+    8813           0 :                 PLUMED_BLAS_F77_FUNC(dlasd6,DLASD6)(icompq, &nl, &nr, &sqrei, &d__[nlf], &work[vfi], &
+    8814           0 :                         work[vli], &alpha, &beta, &iwork[idxqi], &perm[nlf + 
+    8815           0 :                         lvl * perm_dim1], &givptr[j], &givcol[nlf + lvl2 * 
+    8816             :                         givcol_dim1], ldgcol, &givnum[nlf + lvl2 * 
+    8817             :                         givnum_dim1], ldu, &poles[nlf + lvl2 * poles_dim1], &
+    8818           0 :                         difl[nlf + lvl * difl_dim1], &difr[nlf + lvl2 * 
+    8819           0 :                         difr_dim1], &z__[nlf + lvl * z_dim1], &k[j], &c__[j], 
+    8820           0 :                         &s[j], &work[nwork1], &iwork[iwk], info);
+    8821             :             }
+    8822           0 :             if (*info != 0) {
+    8823             :                 return;
+    8824             :             }
+    8825             :         }
+    8826             :     }
+    8827             : 
+    8828             :     return;
+    8829             : 
+    8830             : }
+    8831             : 
+    8832             : 
+    8833             : }
+    8834             : }
+    8835             : #include <cctype>
+    8836             : 
+    8837             : #include "blas/blas.h"
+    8838             : #include "lapack.h"
+    8839             : 
+    8840             : 
+    8841             : #include "blas/blas.h"
+    8842             : namespace PLMD{
+    8843             : namespace lapack{
+    8844             : using namespace blas;
+    8845             : void 
+    8846         155 : PLUMED_BLAS_F77_FUNC(dlasdq,DLASDQ)(const char *uplo,
+    8847             :                         int *sqre,
+    8848             :                         int *n,
+    8849             :                         int *ncvt,
+    8850             :                         int *nru,
+    8851             :                         int *ncc,
+    8852             :                         double *d__,
+    8853             :                         double *e, 
+    8854             :                         double *vt, 
+    8855             :                         int *ldvt, 
+    8856             :                         double *u,
+    8857             :                         int *ldu, 
+    8858             :                         double *c__,
+    8859             :                         int *ldc,
+    8860             :                         double *work, 
+    8861             :                         int *info)
+    8862             : {
+    8863         155 :     const char xuplo=std::toupper(*uplo);
+    8864             :     int c_dim1, c_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, 
+    8865             :             i__2;
+    8866         155 :     int c__1 = 1;
+    8867             :     int itmp1,itmp2;
+    8868             :     int i__, j;
+    8869             :     double r__, cs, sn;
+    8870             :     int np1, isub;
+    8871             :     double smin;
+    8872             :     int sqre1;
+    8873             :     int iuplo;
+    8874             :     int rotate;
+    8875             : 
+    8876         155 :     --d__;
+    8877         155 :     --e;
+    8878         155 :     vt_dim1 = *ldvt;
+    8879         155 :     vt_offset = 1 + vt_dim1;
+    8880         155 :     vt -= vt_offset;
+    8881         155 :     u_dim1 = *ldu;
+    8882         155 :     u_offset = 1 + u_dim1;
+    8883         155 :     u -= u_offset;
+    8884         155 :     c_dim1 = *ldc;
+    8885         155 :     c_offset = 1 + c_dim1;
+    8886         155 :     c__ -= c_offset;
+    8887         155 :     --work;
+    8888             : 
+    8889         155 :     *info = 0;
+    8890             :     iuplo = 0;
+    8891         155 :     if (xuplo == 'U') {
+    8892             :         iuplo = 1;
+    8893             :     }
+    8894         155 :     if (xuplo == 'L') {
+    8895             :         iuplo = 2;
+    8896             :     }
+    8897             :     
+    8898         155 :     itmp1 = (*n > 1) ? *n : 1;
+    8899         155 :     itmp2 = (*nru > 1) ? *nru : 1;
+    8900         155 :     if (iuplo == 0) {
+    8901           0 :         *info = -1;
+    8902         155 :     } else if (*sqre < 0 || *sqre > 1) {
+    8903           0 :         *info = -2;
+    8904         155 :     } else if (*n < 0) {
+    8905           0 :         *info = -3;
+    8906         155 :     } else if (*ncvt < 0) {
+    8907           0 :         *info = -4;
+    8908         155 :     } else if (*nru < 0) {
+    8909           0 :         *info = -5;
+    8910         155 :     } else if (*ncc < 0) {
+    8911           0 :         *info = -6;
+    8912         155 :     } else if ((*ncvt == 0 && *ldvt < 1) || (*ncvt > 0 && *ldvt < itmp1)) {
+    8913           0 :         *info = -10;
+    8914         155 :     } else if (*ldu < itmp2) {
+    8915           0 :         *info = -12;
+    8916         155 :     } else if ((*ncc == 0 && *ldc < 1) || (*ncc > 0 && *ldc < itmp1)) {
+    8917           0 :         *info = -14;
+    8918             :     }
+    8919         155 :     if (*info != 0) {
+    8920             :         return;
+    8921             :     }
+    8922         155 :     if (*n == 0) {
+    8923             :         return;
+    8924             :     }
+    8925             : 
+    8926         155 :     rotate = *ncvt > 0 || *nru > 0 || *ncc > 0;
+    8927         155 :     np1 = *n + 1;
+    8928         155 :     sqre1 = *sqre;
+    8929             : 
+    8930         155 :     if (iuplo == 1 && sqre1 == 1) {
+    8931             :         i__1 = *n - 1;
+    8932         903 :         for (i__ = 1; i__ <= i__1; ++i__) {
+    8933         844 :             PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+    8934         844 :             d__[i__] = r__;
+    8935         844 :             e[i__] = sn * d__[i__ + 1];
+    8936         844 :             d__[i__ + 1] = cs * d__[i__ + 1];
+    8937         844 :             if (rotate) {
+    8938         844 :                 work[i__] = cs;
+    8939         844 :                 work[*n + i__] = sn;
+    8940             :             }
+    8941             :         }
+    8942          59 :         PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&d__[*n], &e[*n], &cs, &sn, &r__);
+    8943          59 :         d__[*n] = r__;
+    8944          59 :         e[*n] = 0.f;
+    8945          59 :         if (rotate) {
+    8946          59 :             work[*n] = cs;
+    8947          59 :             work[*n + *n] = sn;
+    8948             :         }
+    8949             :         iuplo = 2;
+    8950             :         sqre1 = 0;
+    8951             : 
+    8952          59 :         if (*ncvt > 0) {
+    8953          59 :             PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "F", &np1, ncvt, &work[1], &work[np1], &vt[
+    8954             :                     vt_offset], ldvt);
+    8955             :         }
+    8956             :     }
+    8957          96 :     if (iuplo == 2) {
+    8958          59 :         i__1 = *n - 1;
+    8959         903 :         for (i__ = 1; i__ <= i__1; ++i__) {
+    8960         844 :             PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+    8961         844 :             d__[i__] = r__;
+    8962         844 :             e[i__] = sn * d__[i__ + 1];
+    8963         844 :             d__[i__ + 1] = cs * d__[i__ + 1];
+    8964         844 :             if (rotate) {
+    8965         844 :                 work[i__] = cs;
+    8966         844 :                 work[*n + i__] = sn;
+    8967             :             }
+    8968             :         }
+    8969             : 
+    8970          59 :         if (sqre1 == 1) {
+    8971           0 :             PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&d__[*n], &e[*n], &cs, &sn, &r__);
+    8972           0 :             d__[*n] = r__;
+    8973           0 :             if (rotate) {
+    8974           0 :                 work[*n] = cs;
+    8975           0 :                 work[*n + *n] = sn;
+    8976             :             }
+    8977             :         }
+    8978          59 :         if (*nru > 0) {
+    8979          59 :             if (sqre1 == 0) {
+    8980          59 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "F", nru, n, &work[1], &work[np1], &u[
+    8981             :                         u_offset], ldu);
+    8982             :             } else {
+    8983           0 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "F", nru, &np1, &work[1], &work[np1], &u[
+    8984             :                         u_offset], ldu);
+    8985             :             }
+    8986             :         }
+    8987          59 :         if (*ncc > 0) {
+    8988           0 :             if (sqre1 == 0) {
+    8989           0 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "F", n, ncc, &work[1], &work[np1], &c__[
+    8990             :                         c_offset], ldc);
+    8991             :             } else {
+    8992           0 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("L", "V", "F", &np1, ncc, &work[1], &work[np1], &c__[
+    8993             :                         c_offset], ldc);
+    8994             :             }
+    8995             :         }
+    8996             :     }
+    8997             : 
+    8998         155 :     PLUMED_BLAS_F77_FUNC(dbdsqr,DBDSQR)("U", n, ncvt, nru, ncc, &d__[1], &e[1], &vt[vt_offset], ldvt, &u[
+    8999             :             u_offset], ldu, &c__[c_offset], ldc, &work[1], info);
+    9000             : 
+    9001         155 :     i__1 = *n;
+    9002        2635 :     for (i__ = 1; i__ <= i__1; ++i__) {
+    9003             : 
+    9004             :         isub = i__;
+    9005        2480 :         smin = d__[i__];
+    9006        2480 :         i__2 = *n;
+    9007       22277 :         for (j = i__ + 1; j <= i__2; ++j) {
+    9008       19797 :             if (d__[j] < smin) {
+    9009             :                 isub = j;
+    9010             :                 smin = d__[j];
+    9011             :             }
+    9012             :         }
+    9013        2480 :         if (isub != i__) {
+    9014        1181 :             d__[isub] = d__[i__];
+    9015        1181 :             d__[i__] = smin;
+    9016        1181 :             if (*ncvt > 0) {
+    9017        1181 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(ncvt, &vt[isub + vt_dim1], ldvt, &vt[i__ + vt_dim1], 
+    9018             :                         ldvt);
+    9019             :             }
+    9020        1181 :             if (*nru > 0) {
+    9021        1181 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(nru, &u[isub * u_dim1 + 1], &c__1, &u[i__ * u_dim1 + 1]
+    9022             :                         , &c__1);
+    9023             :             }
+    9024        1181 :             if (*ncc > 0) {
+    9025           0 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(ncc, &c__[isub + c_dim1], ldc, &c__[i__ + c_dim1], ldc)
+    9026             :                         ;
+    9027             :             }
+    9028             :         }
+    9029             :     }
+    9030             : 
+    9031             :     return;
+    9032             : }
+    9033             : 
+    9034             : 
+    9035             : }
+    9036             : }
+    9037             : #include <cmath>
+    9038             : #include "lapack.h"
+    9039             : 
+    9040             : #include "blas/blas.h"
+    9041             : namespace PLMD{
+    9042             : namespace lapack{
+    9043             : using namespace blas;
+    9044             : void
+    9045          29 : PLUMED_BLAS_F77_FUNC(dlasdt,DLASDT)(int *n,
+    9046             :         int *lvl,
+    9047             :         int *nd,
+    9048             :         int *inode,
+    9049             :         int *ndiml,
+    9050             :         int *ndimr,
+    9051             :         int *msub)
+    9052             : {
+    9053          29 :   int maxn = (*n > 1) ? *n : 1;
+    9054             :   double temp;
+    9055             :   int i,il,ir,llst,nlvl,ncrnt;
+    9056             : 
+    9057          29 :   temp = std::log( ((double) maxn) / ((double)(*msub+1))) / std::log(2.0);
+    9058             :   
+    9059          29 :   *lvl = 1 + (int) temp;
+    9060             : 
+    9061          29 :   i = *n / 2;
+    9062          29 :   inode[0] = i + 1;
+    9063          29 :   ndiml[0] = i;
+    9064          29 :   ndimr[0] = *n - i - 1;
+    9065             :   il = -1;
+    9066             :   ir = 0;
+    9067             :   llst = 1;
+    9068             : 
+    9069          33 :   for(nlvl=1;nlvl<*lvl;nlvl++) {
+    9070          19 :     for(i=0;i<llst;i++) {
+    9071          15 :       il += 2;
+    9072          15 :       ir += 2;
+    9073          15 :       ncrnt = llst + i - 1;
+    9074          15 :       ndiml[il] = ndiml[ncrnt] / 2;
+    9075          15 :       ndimr[il] = ndiml[ncrnt] - ndiml[il] - 1;
+    9076          15 :       inode[il] = inode[ncrnt] - ndimr[il] - 1;
+    9077          15 :       ndiml[ir] = ndimr[ncrnt] / 2;
+    9078          15 :       ndimr[ir] = ndimr[ncrnt] - ndiml[ir] - 1;
+    9079          15 :       inode[ir] = inode[ncrnt] + ndiml[ir] + 1;
+    9080             :     }
+    9081           4 :     llst *= 2;
+    9082             :   }
+    9083          29 :   *nd = llst*2 - 1;
+    9084          29 :   return;
+    9085             : }
+    9086             : }
+    9087             : }
+    9088             : #include <cctype>
+    9089             : #include "lapack.h"
+    9090             : 
+    9091             : 
+    9092             : #include "blas/blas.h"
+    9093             : namespace PLMD{
+    9094             : namespace lapack{
+    9095             : using namespace blas;
+    9096             : void
+    9097      570473 : PLUMED_BLAS_F77_FUNC(dlaset,DLASET)(const char *uplo,
+    9098             :         int *m,
+    9099             :         int *n,
+    9100             :         double *alpha,
+    9101             :         double *beta,
+    9102             :         double *a,
+    9103             :         int *lda)
+    9104             : {
+    9105             :   int i,j,k;
+    9106      570473 :   const char ch=std::toupper(*uplo);
+    9107             : 
+    9108      570473 :   if(ch=='U') {
+    9109           0 :     for(j=1;j<*n;j++) {
+    9110           0 :       k = (j < *m) ? j : *m;
+    9111           0 :       for(i=0;i<k;i++)
+    9112           0 :         a[j*(*lda)+i] = *alpha;
+    9113             :     }
+    9114      570473 :   } else if(ch=='L') {
+    9115           1 :     k = (*m < *n) ? *m : *n;
+    9116           2 :     for(j=0;j<k;j++) {
+    9117           1 :       for(i=j+1;i<*m;i++)
+    9118           0 :         a[j*(*lda)+i] = *alpha;
+    9119             :     }
+    9120             :   } else {
+    9121     1185826 :     for(j=0;j<*n;j++) {
+    9122     4343188 :       for(i=0;i<*m;i++)
+    9123     3727834 :         a[j*(*lda)+i] = *alpha;
+    9124             :     }    
+    9125             :   }
+    9126             : 
+    9127      570473 :   k = (*m < *n) ? *m : *n;
+    9128     1185828 :   for(i=0;i<k;i++)
+    9129      615355 :     a[i*(*lda)+i] = *beta;
+    9130      570473 : }
+    9131             : }
+    9132             : }
+    9133             : #include <cmath>
+    9134             : #include "blas/blas.h"
+    9135             : #include "lapack.h"
+    9136             : #include "lapack_limits.h"
+    9137             : 
+    9138             : #include "real.h"
+    9139             : 
+    9140             : #include "blas/blas.h"
+    9141             : namespace PLMD{
+    9142             : namespace lapack{
+    9143             : using namespace blas;
+    9144             : void
+    9145           0 : PLUMED_BLAS_F77_FUNC(dlasq1,DLASQ1)(int *n,
+    9146             :         double *d,
+    9147             :         double *e,
+    9148             :         double *work,
+    9149             :         int *info)
+    9150             : {
+    9151           0 :   double sigmx = 0.0;
+    9152             :   int i,j,k,iinfo;
+    9153             :   double minval,safemin;
+    9154             :   double dtemp,scale;
+    9155             :   double eps;
+    9156             : 
+    9157             :   eps = PLUMED_GMX_DOUBLE_EPS;
+    9158             :   minval = PLUMED_GMX_DOUBLE_MIN;
+    9159             :   safemin = minval*(1.0+PLUMED_GMX_DOUBLE_EPS);
+    9160           0 :   *info = 0;
+    9161             : 
+    9162           0 :   if(*n<0) {
+    9163           0 :     *info = -2;
+    9164           0 :     return;
+    9165             :   }
+    9166             :   
+    9167           0 :   for(i=0;i<*n-1;i++) {
+    9168           0 :     d[i] = std::abs(d[i]);
+    9169           0 :     dtemp = std::abs(e[i]);
+    9170           0 :     if(dtemp>sigmx)
+    9171           0 :       sigmx=dtemp;
+    9172             :   }
+    9173           0 :   d[*n-1] = std::abs(d[*n-1]);
+    9174             :   
+    9175           0 :   if(std::abs(sigmx)<PLUMED_GMX_DOUBLE_MIN) {
+    9176           0 :     PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("D",n,d,&iinfo);
+    9177           0 :     return;
+    9178             :   }
+    9179             : 
+    9180           0 :   for(i=0;i<*n;i++) {
+    9181           0 :     if(d[i]>sigmx)
+    9182           0 :       sigmx=d[i];
+    9183             :   }
+    9184             : 
+    9185             :   /* Copy d and e into work (z format) and scale.
+    9186             :    * Squaring input data makes scaling by a power of the
+    9187             :    * radix pointless.
+    9188             :    */
+    9189           0 :   scale =  std::sqrt(eps/safemin);
+    9190           0 :   i = 1;
+    9191           0 :   j = 2;
+    9192           0 :   PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n,d,&i,work,&j);
+    9193           0 :   k = *n-1;
+    9194           0 :   PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&k,e,&i,work+1,&j);
+    9195           0 :   i = 0;
+    9196           0 :   j = 2*(*n)-1;
+    9197           0 :   k = 1;
+    9198           0 :   PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G",&i,&i,&sigmx,&scale,&j,&k,work,&j,&iinfo);
+    9199             : 
+    9200             : 
+    9201             :   /* Compute q and e elements */
+    9202           0 :   for(i=0;i<2*(*n)-1;i++)
+    9203           0 :     work[i] = work[i]*work[i];
+    9204             : 
+    9205           0 :   work[2*(*n)-1] = 0.0;
+    9206             : 
+    9207           0 :   PLUMED_BLAS_F77_FUNC(dlasq2,DLASQ2)(n,work,info);
+    9208             : 
+    9209           0 :   j = 0;
+    9210           0 :   k = 1;
+    9211           0 :   if(*info==0) {
+    9212           0 :     for(i=0;i<*n;i++)
+    9213           0 :       d[i]= std::sqrt(work[i]);
+    9214           0 :     PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G",&j,&j,&scale,&sigmx,n,&k,d,n,&iinfo);
+    9215             :   }
+    9216             :   return;
+    9217             : }
+    9218             : }
+    9219             : }
+    9220             : #include <cmath>
+    9221             : #include "lapack.h"
+    9222             : #include "lapack_limits.h"
+    9223             : 
+    9224             : #include "real.h"
+    9225             : 
+    9226             : #ifdef _MSC_VER
+    9227             : #pragma warning(disable: 4723) /*division by zero - is used on purpose here*/
+    9228             : #endif
+    9229             : 
+    9230             : #include "blas/blas.h"
+    9231             : namespace PLMD{
+    9232             : namespace lapack{
+    9233             : using namespace blas;
+    9234             : void 
+    9235      570005 : PLUMED_BLAS_F77_FUNC(dlasq2,DLASQ2)(int *n, 
+    9236             :                         double *z__, 
+    9237             :                         int *info)
+    9238             : {
+    9239             :     int i__1, i__2, i__3;
+    9240             :     double d__1, d__2;
+    9241             : 
+    9242             :     double d__, e;
+    9243             :     int k;
+    9244             :     double s, t;
+    9245             :     int i0, i4, n0, pp;
+    9246             :     double dee, eps, tol;
+    9247             :     int ipn4;
+    9248             :     double tol2;
+    9249             :     int ieee;
+    9250             :     int nbig;
+    9251             :     double dmin__, emin, emax;
+    9252             :     int kmin, ndiv, iter;
+    9253             :     double qmin, temp, qmax, zmax;
+    9254             :     int splt, nfail;
+    9255             :     double desig, trace, sigma;
+    9256             :     int iinfo;
+    9257             :     double deemin;
+    9258             :     int iwhila, iwhilb;
+    9259             :     double oldemn, safmin, minval;
+    9260             :     double posinf,neginf,negzro,newzro;
+    9261             :     double zero = 0.0;
+    9262             :     double one = 1.0;
+    9263             : 
+    9264      570005 :     --z__;
+    9265             : 
+    9266      570005 :     *info = 0;
+    9267             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    9268             :     minval = PLUMED_GMX_DOUBLE_MIN;
+    9269             :     safmin = minval*(1.0+eps);
+    9270             : 
+    9271             :     tol = eps * 100.;
+    9272             : 
+    9273             :     d__1 = tol;
+    9274             :     tol2 = d__1 * d__1;
+    9275             : 
+    9276      570005 :     if (*n < 0) {
+    9277           0 :         *info = -1;
+    9278           0 :         return;
+    9279      570005 :     } else if (*n == 0) {
+    9280             :         return;
+    9281      570005 :     } else if (*n == 1) {
+    9282             : 
+    9283           0 :         if (z__[1] < 0.) {
+    9284           0 :             *info = -201;
+    9285             :         }
+    9286           0 :         return;
+    9287      570005 :     } else if (*n == 2) {
+    9288             : 
+    9289       13359 :         if (z__[2] < 0. || z__[3] < 0.) {
+    9290           0 :             *info = -2;
+    9291           0 :             return;
+    9292       13359 :         } else if (z__[3] > z__[1]) {
+    9293             :             d__ = z__[3];
+    9294           0 :             z__[3] = z__[1];
+    9295           0 :             z__[1] = d__;
+    9296             :         }
+    9297       13359 :         z__[5] = z__[1] + z__[2] + z__[3];
+    9298       13359 :         if (z__[2] > z__[3] * tol2) {
+    9299       13359 :             t = (z__[1] - z__[3] + z__[2]) * .5;
+    9300       13359 :             s = z__[3] * (z__[2] / t);
+    9301       13359 :             if (s <= t) {
+    9302       13359 :                 s = z__[3] * (z__[2] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+    9303             :             } else {
+    9304           0 :                 s = z__[3] * (z__[2] / (t +  std::sqrt(t) * std::sqrt(t + s)));
+    9305             :             }
+    9306       13359 :             t = z__[1] + (s + z__[2]);
+    9307       13359 :             z__[3] *= z__[1] / t;
+    9308       13359 :             z__[1] = t;
+    9309             :         }
+    9310       13359 :         z__[2] = z__[3];
+    9311       13359 :         z__[6] = z__[2] + z__[1];
+    9312       13359 :         return;
+    9313             :     }
+    9314      556646 :     z__[*n * 2] = 0.;
+    9315      556646 :     emin = z__[2];
+    9316      556646 :     qmax = 0.;
+    9317             :     zmax = 0.;
+    9318             :     d__ = 0.;
+    9319             :     e = 0.;
+    9320             : 
+    9321      556646 :     i__1 = 2*(*n - 1);
+    9322     2227034 :     for (k = 1; k <= i__1; k += 2) {
+    9323     1670388 :         if (z__[k] < 0.) {
+    9324           0 :             *info = -(k + 200);
+    9325           0 :             return;
+    9326     1670388 :         } else if (z__[k + 1] < 0.) {
+    9327           0 :             *info = -(k + 201);
+    9328           0 :             return;
+    9329             :         }
+    9330     1670388 :         d__ += z__[k];
+    9331     1670388 :         e += z__[k + 1];
+    9332     1670388 :         d__1 = qmax, d__2 = z__[k];
+    9333     1670388 :         qmax = (d__1>d__2) ? d__1 : d__2;
+    9334             :         d__1 = emin, d__2 = z__[k + 1];
+    9335     1670388 :         emin = (d__1<d__2) ? d__1 : d__2;
+    9336     1670388 :         d__1 = (qmax>zmax) ? qmax : zmax;
+    9337             :         d__2 = z__[k + 1];
+    9338     1670388 :         zmax = (d__1>d__2) ? d__1 : d__2;
+    9339             :     }
+    9340      556646 :     if (z__[(*n << 1) - 1] < 0.) {
+    9341           0 :         *info = -((*n << 1) + 199);
+    9342           0 :         return;
+    9343             :     }
+    9344      556646 :     d__ += z__[(*n << 1) - 1];
+    9345      556646 :     d__1 = qmax, d__2 = z__[(*n << 1) - 1];
+    9346      556657 :     qmax = (d__1>d__2) ? d__1 : d__2;
+    9347             : 
+    9348      556646 :     if (std::abs(e)<PLUMED_GMX_DOUBLE_MIN) {
+    9349             :         i__1 = *n;
+    9350           0 :         for (k = 2; k <= i__1; ++k) {
+    9351           0 :             z__[k] = z__[(k << 1) - 1];
+    9352             :         }
+    9353           0 :         PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("D", n, &z__[1], &iinfo);
+    9354           0 :         z__[(*n << 1) - 1] = d__;
+    9355           0 :         return;
+    9356             :     }
+    9357             : 
+    9358      556646 :     trace = d__ + e;
+    9359             : 
+    9360      556646 :     if (std::abs(trace)<PLUMED_GMX_DOUBLE_MIN) {
+    9361           0 :         z__[(*n << 1) - 1] = 0.;
+    9362           0 :         return;
+    9363             :     }
+    9364             : 
+    9365      556646 :     ieee = 1;
+    9366      556646 :     posinf = one/zero;
+    9367      556646 :     if(posinf<=1.0)
+    9368           0 :       ieee = 0;
+    9369             :     neginf = -one/zero;
+    9370      556646 :     if(neginf>=0.0)
+    9371           0 :       ieee = 0;
+    9372      556646 :     negzro = one/(neginf+one);
+    9373      556646 :     if(std::abs(negzro)>PLUMED_GMX_DOUBLE_MIN)
+    9374           0 :       ieee = 0;
+    9375      556646 :     neginf = one/negzro;
+    9376      556646 :     if(neginf>=0)
+    9377           0 :       ieee = 0;
+    9378      556646 :     newzro = negzro + zero;
+    9379      556646 :     if(std::abs(newzro-zero)>PLUMED_GMX_DOUBLE_MIN)
+    9380           0 :       ieee = 0;
+    9381      556646 :     posinf = one /newzro;
+    9382      556646 :     if(posinf<=one)
+    9383           0 :       ieee = 0;
+    9384      556646 :     neginf = neginf*posinf;
+    9385      556646 :     if(neginf>=zero)
+    9386           0 :       ieee = 0;
+    9387      556646 :     posinf = posinf*posinf;
+    9388      556646 :     if(posinf<=1.0)
+    9389           0 :       ieee = 0;
+    9390             : 
+    9391     2783680 :     for (k = *n << 1; k >= 2; k += -2) {
+    9392     2227034 :         z__[k * 2] = 0.;
+    9393     2227034 :         z__[(k << 1) - 1] = z__[k];
+    9394     2227034 :         z__[(k << 1) - 2] = 0.;
+    9395     2227034 :         z__[(k << 1) - 3] = z__[k - 1];
+    9396             :     }
+    9397             : 
+    9398      556646 :     i0 = 1;
+    9399      556646 :     n0 = *n;
+    9400             : 
+    9401      556646 :     if (z__[(i0 << 2) - 3] * 1.5 < z__[(n0 << 2) - 3]) {
+    9402         121 :         ipn4 = 4*(i0 + n0);
+    9403         121 :         i__1 = 2*(i0 + n0 - 1);
+    9404         362 :         for (i4 = i0 << 2; i4 <= i__1; i4 += 4) {
+    9405         241 :             temp = z__[i4 - 3];
+    9406         241 :             z__[i4 - 3] = z__[ipn4 - i4 - 3];
+    9407         241 :             z__[ipn4 - i4 - 3] = temp;
+    9408         241 :             temp = z__[i4 - 1];
+    9409         241 :             z__[i4 - 1] = z__[ipn4 - i4 - 5];
+    9410         241 :             z__[ipn4 - i4 - 5] = temp;
+    9411             :         }
+    9412             :     }
+    9413             : 
+    9414      556646 :     pp = 0;
+    9415             : 
+    9416     1669938 :     for (k = 1; k <= 2; ++k) {
+    9417             : 
+    9418     1113292 :         d__ = z__[(n0 << 2) + pp - 3];
+    9419     1113292 :         i__1 = (i0 << 2) + pp;
+    9420     4454068 :         for (i4 = 4*(n0 - 1) + pp; i4 >= i__1; i4 += -4) {
+    9421     3340776 :             if (z__[i4 - 1] <= tol2 * d__) {
+    9422           4 :                 z__[i4 - 1] = -0.;
+    9423           4 :                 d__ = z__[i4 - 3];
+    9424             :             } else {
+    9425     3340772 :                 d__ = z__[i4 - 3] * (d__ / (d__ + z__[i4 - 1]));
+    9426             :             }
+    9427             :         }
+    9428             : 
+    9429     1113292 :         emin = z__[(i0 << 2) + pp + 1];
+    9430     1113292 :         d__ = z__[(i0 << 2) + pp - 3];
+    9431             :         i__1 = 4*(n0 - 1) + pp;
+    9432     4454068 :         for (i4 = (i0 << 2) + pp; i4 <= i__1; i4 += 4) {
+    9433     3340776 :             z__[i4 - (pp << 1) - 2] = d__ + z__[i4 - 1];
+    9434     3340776 :             if (z__[i4 - 1] <= tol2 * d__) {
+    9435          23 :                 z__[i4 - 1] = -0.;
+    9436          23 :                 z__[i4 - (pp << 1) - 2] = d__;
+    9437          23 :                 z__[i4 - (pp << 1)] = 0.;
+    9438          23 :                 d__ = z__[i4 + 1];
+    9439     3340753 :             } else if (safmin * z__[i4 + 1] < z__[i4 - (pp << 1) - 2] && 
+    9440     3340753 :                     safmin * z__[i4 - (pp << 1) - 2] < z__[i4 + 1]) {
+    9441     3340749 :                 temp = z__[i4 + 1] / z__[i4 - (pp << 1) - 2];
+    9442     3340749 :                 z__[i4 - (pp << 1)] = z__[i4 - 1] * temp;
+    9443     3340749 :                 d__ *= temp;
+    9444             :             } else {
+    9445           4 :                 z__[i4 - (pp << 1)] = z__[i4 + 1] * (z__[i4 - 1] / z__[i4 - (
+    9446             :                         pp << 1) - 2]);
+    9447           4 :                 d__ = z__[i4 + 1] * (d__ / z__[i4 - (pp << 1) - 2]);
+    9448             :             }
+    9449     3340776 :             d__1 = emin, d__2 = z__[i4 - (pp << 1)];
+    9450     3340776 :             emin = (d__1<d__2) ? d__1 : d__2;
+    9451             :         }
+    9452     1113292 :         z__[(n0 << 2) - pp - 2] = d__;
+    9453             : 
+    9454             : 
+    9455     1113292 :         qmax = z__[(i0 << 2) - pp - 2];
+    9456     1113292 :         i__1 = (n0 << 2) - pp - 2;
+    9457     4454068 :         for (i4 = (i0 << 2) - pp + 2; i4 <= i__1; i4 += 4) {
+    9458     3340776 :             d__1 = qmax, d__2 = z__[i4];
+    9459     4475362 :             qmax = (d__1>d__2) ? d__1 : d__2;
+    9460             :         }
+    9461             : 
+    9462     1113292 :         pp = 1 - pp;
+    9463             :     }
+    9464             : 
+    9465      556646 :     iter = 2;
+    9466      556646 :     nfail = 0;
+    9467      556646 :     ndiv = 2*(n0 - i0);
+    9468             : 
+    9469      556646 :     i__1 = *n + 1;
+    9470     1113431 :     for (iwhila = 1; iwhila <= i__1; ++iwhila) {
+    9471     1113431 :         if (n0 < 1) {
+    9472      556646 :             goto L170;
+    9473             :         }
+    9474             : 
+    9475      556785 :         desig = 0.;
+    9476      556785 :         if (n0 == *n) {
+    9477      556646 :             sigma = 0.;
+    9478             :         } else {
+    9479         139 :             sigma = -z__[(n0 << 2) - 1];
+    9480             :         }
+    9481      556785 :         if (sigma < 0.) {
+    9482           0 :             *info = 1;
+    9483           0 :             return;
+    9484             :         }
+    9485             : 
+    9486             :         emax = 0.;
+    9487      556785 :         if (n0 > i0) {
+    9488      556646 :             emin = std::abs(z__[(n0 << 2) - 5]);
+    9489             :         } else {
+    9490             :             emin = 0.;
+    9491             :         }
+    9492      556785 :         qmin = z__[(n0 << 2) - 3];
+    9493      556785 :         qmax = qmin;
+    9494     2232253 :         for (i4 = n0 << 2; i4 >= 8; i4 += -4) {
+    9495     1675581 :             if (z__[i4 - 5] <= 0.) {
+    9496         113 :                 goto L100;
+    9497             :             }
+    9498     1675468 :             if (qmin >= emax * 4.) {
+    9499     1116325 :                 d__1 = qmin, d__2 = z__[i4 - 3];
+    9500     1116325 :                 qmin = (d__1<d__2) ? d__1 : d__2;
+    9501             :                 d__1 = emax, d__2 = z__[i4 - 5];
+    9502     1116325 :                 emax = (d__1>d__2) ? d__1 : d__2;
+    9503             :             }
+    9504     1675468 :             d__1 = qmax, d__2 = z__[i4 - 7] + z__[i4 - 5];
+    9505     1675468 :             qmax = (d__1>d__2) ? d__1 : d__2;
+    9506             :             d__1 = emin, d__2 = z__[i4 - 5];
+    9507     1675468 :             emin = (d__1<d__2) ? d__1 : d__2;
+    9508             :         }
+    9509             :         i4 = 4;
+    9510             : 
+    9511      556785 : L100:
+    9512      556785 :         i0 = i4 / 4;
+    9513      556785 :         pp = 0;
+    9514             : 
+    9515      556785 :         if (n0 - i0 > 1) {
+    9516      556741 :             dee = z__[(i0 << 2) - 3];
+    9517             :             deemin = dee;
+    9518             :             kmin = i0;
+    9519      556741 :             i__2 = (n0 << 2) - 3;
+    9520     2788944 :             for (i4 = (i0 << 2) - 3; i4 <= i__2; i4 += 4) {
+    9521     2232203 :                 dee = z__[i4] * (dee / (dee + z__[i4 - 2]));
+    9522     2232203 :                 if (dee <= deemin) {
+    9523             :                     deemin = dee;
+    9524     1206050 :                     kmin = (i4 + 3) / 4;
+    9525             :                 }
+    9526             :             }
+    9527      556741 :             if (2*(kmin - i0) < n0 - kmin && deemin <= z__[(n0 << 2) - 3] * 
+    9528             :                     .5) {
+    9529        7987 :                 ipn4 = 4*(i0 + n0);
+    9530        7987 :                 pp = 2;
+    9531        7987 :                 i__2 = 2*(i0 + n0 - 1);
+    9532       25756 :                 for (i4 = i0 << 2; i4 <= i__2; i4 += 4) {
+    9533       17769 :                     temp = z__[i4 - 3];
+    9534       17769 :                     z__[i4 - 3] = z__[ipn4 - i4 - 3];
+    9535       17769 :                     z__[ipn4 - i4 - 3] = temp;
+    9536       17769 :                     temp = z__[i4 - 2];
+    9537       17769 :                     z__[i4 - 2] = z__[ipn4 - i4 - 2];
+    9538       17769 :                     z__[ipn4 - i4 - 2] = temp;
+    9539       17769 :                     temp = z__[i4 - 1];
+    9540       17769 :                     z__[i4 - 1] = z__[ipn4 - i4 - 5];
+    9541       17769 :                     z__[ipn4 - i4 - 5] = temp;
+    9542       17769 :                     temp = z__[i4];
+    9543       17769 :                     z__[i4] = z__[ipn4 - i4 - 4];
+    9544       17769 :                     z__[ipn4 - i4 - 4] = temp;
+    9545             :                 }
+    9546             :             }
+    9547             :         }
+    9548             : 
+    9549             : 
+    9550      556785 :         d__1 = 0., d__2 = qmin -  std::sqrt(qmin) * 2. * std::sqrt(emax);
+    9551      556785 :         dmin__ = -((d__1>d__2) ? d__1 : d__2);
+    9552             : 
+    9553      556785 :         nbig = (n0 - i0 + 1) * 30;
+    9554             :         i__2 = nbig;
+    9555    13682315 :         for (iwhilb = 1; iwhilb <= i__2; ++iwhilb) {
+    9556    13682315 :             if (i0 > n0) {
+    9557      556785 :                 goto L150;
+    9558             :             }
+    9559             : 
+    9560    13125530 :             PLUMED_BLAS_F77_FUNC(dlasq3,DLASQ3)(&i0, &n0, &z__[1], &pp, &dmin__, &sigma, &desig, &qmax, &
+    9561             :                     nfail, &iter, &ndiv, &ieee);
+    9562             : 
+    9563    13125530 :             pp = 1 - pp;
+    9564             : 
+    9565    13125530 :             if (pp == 0 && n0 - i0 >= 3) {
+    9566      162509 :                 if (z__[n0 * 4] <= tol2 * qmax || z__[(n0 << 2) - 1] <= tol2 *
+    9567             :                          sigma) {
+    9568         301 :                     splt = i0 - 1;
+    9569         301 :                     qmax = z__[(i0 << 2) - 3];
+    9570         301 :                     emin = z__[(i0 << 2) - 1];
+    9571         301 :                     oldemn = z__[i0 * 4];
+    9572         301 :                     i__3 = 4*(n0 - 3);
+    9573       41906 :                     for (i4 = i0 << 2; i4 <= i__3; i4 += 4) {
+    9574       41605 :                         if (z__[i4] <= tol2 * z__[i4 - 3] || z__[i4 - 1] <= 
+    9575       41576 :                                 tol2 * sigma) {
+    9576         116 :                             z__[i4 - 1] = -sigma;
+    9577         116 :                             splt = i4 / 4;
+    9578         116 :                             qmax = 0.;
+    9579         116 :                             emin = z__[i4 + 3];
+    9580         116 :                             oldemn = z__[i4 + 4];
+    9581             :                         } else {
+    9582       41489 :                             d__1 = qmax, d__2 = z__[i4 + 1];
+    9583       41489 :                             qmax = (d__1>d__2) ? d__1 : d__2;
+    9584             :                             d__1 = emin, d__2 = z__[i4 - 1];
+    9585       41489 :                             emin = (d__1<d__2) ? d__1 : d__2;
+    9586             :                             d__1 = oldemn, d__2 = z__[i4];
+    9587       41489 :                             oldemn = (d__1<d__2) ? d__1 : d__2;
+    9588             :                         }
+    9589             :                     }
+    9590         301 :                     z__[(n0 << 2) - 1] = emin;
+    9591         301 :                     z__[n0 * 4] = oldemn;
+    9592         301 :                     i0 = splt + 1;
+    9593             :                 }
+    9594             :             }
+    9595             :         }
+    9596             : 
+    9597           0 :         *info = 2;
+    9598           0 :         return;
+    9599             : 
+    9600             : L150:
+    9601             :         ;
+    9602             :     }
+    9603             : 
+    9604           0 :     *info = 3;
+    9605           0 :     return;
+    9606             : 
+    9607             : 
+    9608             : L170:
+    9609             : 
+    9610      556646 :     i__1 = *n;
+    9611     2227034 :     for (k = 2; k <= i__1; ++k) {
+    9612     1670388 :         z__[k] = z__[(k << 2) - 3];
+    9613             :     }
+    9614             : 
+    9615      556646 :     PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("D", n, &z__[1], &iinfo);
+    9616             : 
+    9617             :     e = 0.;
+    9618     2783680 :     for (k = *n; k >= 1; --k) {
+    9619     2227034 :         e += z__[k];
+    9620             :     }
+    9621             : 
+    9622             : 
+    9623      556646 :     z__[(*n << 1) + 1] = trace;
+    9624      556646 :     z__[(*n << 1) + 2] = e;
+    9625      556646 :     z__[(*n << 1) + 3] = (double) iter;
+    9626      556646 :     i__1 = *n;
+    9627      556646 :     z__[(*n << 1) + 4] = (double) ndiv / (double) (i__1 * i__1);
+    9628      556646 :     z__[(*n << 1) + 5] = nfail * 100. / (double) iter;
+    9629             : 
+    9630      556646 :     return;
+    9631             : 
+    9632             : }
+    9633             : 
+    9634             : 
+    9635             : 
+    9636             : }
+    9637             : }
+    9638             : #include <cmath>
+    9639             : #include "real.h"
+    9640             : 
+    9641             : #include "lapack.h"
+    9642             : #include "lapack_limits.h"
+    9643             : 
+    9644             : #include "blas/blas.h"
+    9645             : namespace PLMD{
+    9646             : namespace lapack{
+    9647             : using namespace blas;
+    9648             : void
+    9649    13125530 : PLUMED_BLAS_F77_FUNC(dlasq3,DLASQ3)(int *i0, 
+    9650             :                         int *n0, 
+    9651             :                         double *z__, 
+    9652             :                         int *pp, 
+    9653             :                         double *dmin__, 
+    9654             :                         double *sigma,
+    9655             :                         double *desig,
+    9656             :                         double *qmax, 
+    9657             :                         int *nfail, 
+    9658             :                         int *iter, 
+    9659             :                         int *ndiv, 
+    9660             :         int *ieee)
+    9661             : {
+    9662             : 
+    9663    13125530 :     int ttype = 0;
+    9664    13125530 :     double dmin1 = 0.;
+    9665    13125530 :     double dmin2 = 0.;
+    9666    13125530 :     double dn = 0.;
+    9667    13125530 :     double dn1 = 0.;
+    9668    13125530 :     double dn2 = 0.;
+    9669    13125530 :     double tau = 0.;
+    9670             : 
+    9671             :     int i__1;
+    9672             :     double d__1, d__2;
+    9673             :     double s, t;
+    9674             :     int j4, nn;
+    9675             :     double eps, tol;
+    9676             :     int n0in, ipn4;
+    9677             :     double tol2, temp;
+    9678    13125530 :     --z__;
+    9679             : 
+    9680    13125530 :     n0in = *n0;
+    9681             :     eps = PLUMED_GMX_DOUBLE_EPS;
+    9682             :     tol = eps * 100.;
+    9683             :     d__1 = tol;
+    9684             :     tol2 = d__1 * d__1;
+    9685             : 
+    9686             : 
+    9687     1670174 : L10:
+    9688             : 
+    9689    14795704 :     if (*n0 < *i0) {
+    9690             :         return;
+    9691             :     }
+    9692    14238919 :     if (*n0 == *i0) {
+    9693          82 :         goto L20;
+    9694             :     }
+    9695    14238837 :     nn = (*n0 << 2) + *pp;
+    9696    14238837 :     if (*n0 == *i0 + 1) {
+    9697      556703 :         goto L40;
+    9698             :     }
+    9699             : 
+    9700    13682134 :     if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) - 
+    9701    12568902 :             4] > tol2 * z__[nn - 7]) {
+    9702    12568902 :         goto L30;
+    9703             :     }
+    9704             : 
+    9705     1113232 : L20:
+    9706             : 
+    9707     1113314 :     z__[(*n0 << 2) - 3] = z__[(*n0 << 2) + *pp - 3] + *sigma;
+    9708     1113314 :     --(*n0);
+    9709     1113314 :     goto L10;
+    9710             : 
+    9711             : L30:
+    9712             : 
+    9713    12568902 :     if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[
+    9714    12568745 :             nn - 11]) {
+    9715    12568745 :         goto L50;
+    9716             :     }
+    9717             : 
+    9718         157 : L40:
+    9719             : 
+    9720      556860 :     if (z__[nn - 3] > z__[nn - 7]) {
+    9721             :         s = z__[nn - 3];
+    9722       21586 :         z__[nn - 3] = z__[nn - 7];
+    9723       21586 :         z__[nn - 7] = s;
+    9724             :     }
+    9725      556860 :     if (z__[nn - 5] > z__[nn - 3] * tol2) {
+    9726      556860 :         t = (z__[nn - 7] - z__[nn - 3] + z__[nn - 5]) * .5;
+    9727      556860 :         s = z__[nn - 3] * (z__[nn - 5] / t);
+    9728      556860 :         if (s <= t) {
+    9729      539402 :             s = z__[nn - 3] * (z__[nn - 5] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+    9730             :         } else {
+    9731       17458 :             s = z__[nn - 3] * (z__[nn - 5] / (t +  std::sqrt(t) * std::sqrt(t + s)));
+    9732             :         }
+    9733      556860 :         t = z__[nn - 7] + (s + z__[nn - 5]);
+    9734      556860 :         z__[nn - 3] *= z__[nn - 7] / t;
+    9735      556860 :         z__[nn - 7] = t;
+    9736             :     }
+    9737      556860 :     z__[(*n0 << 2) - 7] = z__[nn - 7] + *sigma;
+    9738      556860 :     z__[(*n0 << 2) - 3] = z__[nn - 3] + *sigma;
+    9739      556860 :     *n0 += -2;
+    9740      556860 :     goto L10;
+    9741             : 
+    9742             : L50:
+    9743    12568745 :     if (*pp == 2) {
+    9744        7987 :         *pp = 0;
+    9745             :     }
+    9746             : 
+    9747    12568745 :     if (*dmin__ <= 0. || *n0 < n0in) {
+    9748     1113378 :         if (z__[(*i0 << 2) + *pp - 3] * 1.5 < z__[(*n0 << 2) + *pp - 3]) {
+    9749      299487 :             ipn4 = 4*(*i0 + *n0);
+    9750      299487 :             i__1 = 2*(*i0 + *n0 - 1);
+    9751      608758 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+    9752      309271 :                 temp = z__[j4 - 3];
+    9753      309271 :                 z__[j4 - 3] = z__[ipn4 - j4 - 3];
+    9754      309271 :                 z__[ipn4 - j4 - 3] = temp;
+    9755      309271 :                 temp = z__[j4 - 2];
+    9756      309271 :                 z__[j4 - 2] = z__[ipn4 - j4 - 2];
+    9757      309271 :                 z__[ipn4 - j4 - 2] = temp;
+    9758      309271 :                 temp = z__[j4 - 1];
+    9759      309271 :                 z__[j4 - 1] = z__[ipn4 - j4 - 5];
+    9760      309271 :                 z__[ipn4 - j4 - 5] = temp;
+    9761      309271 :                 temp = z__[j4];
+    9762      309271 :                 z__[j4] = z__[ipn4 - j4 - 4];
+    9763      309271 :                 z__[ipn4 - j4 - 4] = temp;
+    9764             :             }
+    9765      299487 :             if (*n0 - *i0 <= 4) {
+    9766      299438 :                 z__[(*n0 << 2) + *pp - 1] = z__[(*i0 << 2) + *pp - 1];
+    9767      299438 :                 z__[(*n0 << 2) - *pp] = z__[(*i0 << 2) - *pp];
+    9768             :             }
+    9769      299487 :             d__1 = dmin2, d__2 = z__[(*n0 << 2) + *pp - 1];
+    9770      299487 :             dmin2 = ((d__1<d__2) ? d__1 : d__2);
+    9771      299487 :             d__1 = z__[(*n0 << 2) + *pp - 1], d__2 = z__[(*i0 << 2) + *pp - 1]
+    9772      299487 :                     , d__1 = ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) + *pp + 3];
+    9773      299487 :             z__[(*n0 << 2) + *pp - 1] = ((d__1<d__2) ? d__1 : d__2);
+    9774      299487 :             d__1 = z__[(*n0 << 2) - *pp], d__2 = z__[(*i0 << 2) - *pp], d__1 =
+    9775      299487 :                      ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) - *pp + 4];
+    9776      299487 :             z__[(*n0 << 2) - *pp] = ((d__1<d__2) ? d__1 : d__2);
+    9777      299487 :             d__1 = *qmax;
+    9778      299487 :             d__2 = z__[(*i0 << 2) + *pp - 3];
+    9779      299487 :             d__1 = (d__1>d__2) ? d__1 : d__2;
+    9780      299487 :             d__2 = z__[(*i0 << 2) + *pp + 1];
+    9781      299487 :             *qmax = ((d__1>d__2) ? d__1 : d__2);
+    9782      299487 :             *dmin__ = -0.;
+    9783             :         }
+    9784             :     }
+    9785             : 
+    9786             : 
+    9787    12568745 :     PLUMED_BLAS_F77_FUNC(dlasq4,DLASQ4)(i0, n0, &z__[1], pp, &n0in, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+    9788             :             dn2, &tau, &ttype);
+    9789             : 
+    9790    12568749 : L70:
+    9791             : 
+    9792    12568749 :     PLUMED_BLAS_F77_FUNC(dlasq5,DLASQ5)(i0, n0, &z__[1], pp, &tau, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+    9793             :             dn2, ieee);
+    9794             : 
+    9795    12568749 :     *ndiv += *n0 - *i0 + 2;
+    9796    12568749 :     ++(*iter);
+    9797             : 
+    9798    12568749 :     if (*dmin__ >= 0. && dmin1 > 0.) {
+    9799             : 
+    9800    12568745 :         goto L90;
+    9801             : 
+    9802           4 :     } else if (*dmin__ < 0. && dmin1 > 0. && z__[4*(*n0 - 1) - *pp] < tol *
+    9803           6 :              (*sigma + dn1) && std::abs(dn) < tol * *sigma) {
+    9804             : 
+    9805           0 :         z__[4*(*n0 - 1) - *pp + 2] = 0.;
+    9806           0 :         *dmin__ = 0.;
+    9807           0 :         goto L90;
+    9808           4 :     } else if (*dmin__ < 0.) {
+    9809             : 
+    9810           4 :         ++(*nfail);
+    9811           4 :         if (ttype < -22) {
+    9812             : 
+    9813           0 :             tau = 0.;
+    9814           4 :         } else if (dmin1 > 0.) {
+    9815             : 
+    9816           2 :             tau = (tau + *dmin__) * (1. - eps * 2.);
+    9817           2 :             ttype += -11;
+    9818             :         } else {
+    9819             : 
+    9820           2 :             tau *= .25;
+    9821           2 :             ttype += -12;
+    9822             :         }
+    9823           4 :         goto L70;
+    9824             :     }
+    9825             :     else {
+    9826             :         
+    9827           0 :         goto L80;
+    9828             :     }
+    9829             : 
+    9830             : L80:
+    9831           0 :     PLUMED_BLAS_F77_FUNC(dlasq6,DLASQ6)(i0, n0, &z__[1], pp, dmin__, &dmin1, &dmin2, &dn, &dn1, &dn2);
+    9832           0 :     *ndiv += *n0 - *i0 + 2;
+    9833           0 :     ++(*iter);
+    9834           0 :     tau = 0.;
+    9835             : 
+    9836    12568745 : L90:
+    9837    12568745 :     if (tau < *sigma) {
+    9838    10899809 :         *desig += tau;
+    9839    10899809 :         t = *sigma + *desig;
+    9840    10899809 :         *desig -= t - *sigma;
+    9841             :     } else {
+    9842     1668936 :         t = *sigma + tau;
+    9843     1668936 :         *desig = *sigma - (t - tau) + *desig;
+    9844             :     }
+    9845    12568745 :     *sigma = t;
+    9846             : 
+    9847    12568745 :     return;
+    9848             : }
+    9849             : }
+    9850             : }
+    9851             : #include <cmath>
+    9852             : #include "real.h"
+    9853             : 
+    9854             : #include "lapack.h"
+    9855             : 
+    9856             : #include "blas/blas.h"
+    9857             : namespace PLMD{
+    9858             : namespace lapack{
+    9859             : using namespace blas;
+    9860             : void 
+    9861    12568745 : PLUMED_BLAS_F77_FUNC(dlasq4,DLASQ4)(int *i0, 
+    9862             :         int *n0, 
+    9863             :         double *z__, 
+    9864             :         int *pp, 
+    9865             :         int *n0in, 
+    9866             :         double *dmin__, 
+    9867             :         double *dmin1, 
+    9868             :         double *dmin2, 
+    9869             :         double *dn, 
+    9870             :         double *dn1, 
+    9871             :         double *dn2, 
+    9872             :         double *tau, 
+    9873             :         int *ttype)
+    9874             : {
+    9875             :     double g = 0.;
+    9876             :     int i__1;
+    9877             :     double d__1, d__2;
+    9878             : 
+    9879             :     double s, a2, b1, b2;
+    9880             :     int i4, nn, np;
+    9881             :     double gam, gap1, gap2;
+    9882             : 
+    9883             : 
+    9884    12568745 :     if (*dmin__ <= 0.) {
+    9885      848265 :         *tau = -(*dmin__);
+    9886      848265 :         *ttype = -1;
+    9887      848265 :         return;
+    9888             :     }
+    9889             : 
+    9890             :     s = 0.0;
+    9891             : 
+    9892    11720480 :     nn = (*n0 << 2) + *pp;
+    9893    11720480 :     if (*n0in == *n0) {
+    9894             : 
+    9895    11455367 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin__ + *dn) ||
+    9896    11455367 :          std::abs(*dmin__ - *dn1)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin__ + *dn1)) {
+    9897             : 
+    9898           0 :             b1 =  std::sqrt(z__[nn - 3]) * std::sqrt(z__[nn - 5]);
+    9899           0 :             b2 =  std::sqrt(z__[nn - 7]) * std::sqrt(z__[nn - 9]);
+    9900           0 :             a2 = z__[nn - 7] + z__[nn - 5];
+    9901             : 
+    9902           0 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin__ + *dn) &&
+    9903           0 :              std::abs(*dmin1 - *dn1)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin1 + *dn1)) {
+    9904             : 
+    9905           0 :             gap2 = *dmin2 - a2 - *dmin2 * .25;
+    9906           0 :                 if (gap2 > 0. && gap2 > b2) {
+    9907           0 :                     gap1 = a2 - *dn - b2 / gap2 * b2;
+    9908             :                 } else {
+    9909           0 :                     gap1 = a2 - *dn - (b1 + b2);
+    9910             :                 }
+    9911           0 :                 if (gap1 > 0. && gap1 > b1) {
+    9912           0 :                     d__1 = *dn - b1 / gap1 * b1, d__2 = *dmin__ * .5;
+    9913           0 :                     s = (d__1>d__2) ? d__1 : d__2;
+    9914           0 :                     *ttype = -2;
+    9915             :                 } else {
+    9916             :                     s = 0.;
+    9917           0 :                     if (*dn > b1) {
+    9918           0 :                         s = *dn - b1;
+    9919             :                     }
+    9920           0 :                     if (a2 > b1 + b2) {
+    9921           0 :                         d__1 = s, d__2 = a2 - (b1 + b2);
+    9922           0 :                         s = (d__1<d__2) ? d__1 : d__2;
+    9923             :                     }
+    9924           0 :                     d__1 = s, d__2 = *dmin__ * .333;
+    9925           0 :                     s = (d__1>d__2) ? d__1 : d__2;
+    9926           0 :                     *ttype = -3;
+    9927             :                 }
+    9928             :             } else {
+    9929             : 
+    9930             : 
+    9931           0 :                 *ttype = -4;
+    9932           0 :                 s = *dmin__ * .25;
+    9933           0 :                 if (std::abs(*dmin__ - *dn)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin__ + *dn)) {
+    9934             :                     gam = *dn;
+    9935             :                     a2 = 0.;
+    9936           0 :                     if (z__[nn - 5] > z__[nn - 7]) {
+    9937             :                         return;
+    9938             :                     }
+    9939           0 :                     b2 = z__[nn - 5] / z__[nn - 7];
+    9940           0 :                     np = nn - 9;
+    9941             :                 } else {
+    9942           0 :                     np = nn - (*pp << 1);
+    9943           0 :                     gam = *dn1;
+    9944           0 :                     if (z__[np - 4] > z__[np - 2]) {
+    9945             :                         return;
+    9946             :                     }
+    9947           0 :                     a2 = z__[np - 4] / z__[np - 2];
+    9948           0 :                     if (z__[nn - 9] > z__[nn - 11]) {
+    9949             :                         return;
+    9950             :                     }
+    9951           0 :                     b2 = z__[nn - 9] / z__[nn - 11];
+    9952           0 :                     np = nn - 13;
+    9953             :                 }
+    9954             : 
+    9955             : 
+    9956           0 :                 a2 += b2;
+    9957           0 :                 i__1 = (*i0 << 2) - 1 + *pp;
+    9958           0 :                 for (i4 = np; i4 >= i__1; i4 += -4) {
+    9959           0 :                     if (std::abs(b2)<PLUMED_GMX_DOUBLE_MIN) {
+    9960           0 :                         goto L20;
+    9961             :                     }
+    9962             :                     b1 = b2;
+    9963           0 :                     if (z__[i4] > z__[i4 - 2]) {
+    9964             :                         return;
+    9965             :                     }
+    9966           0 :                     b2 *= z__[i4] / z__[i4 - 2];
+    9967           0 :                     a2 += b2;
+    9968           0 :                     if (((b2>b1) ? b2 : b1) * 100. < a2 || .563 < a2) {
+    9969           0 :                         goto L20;
+    9970             :                     }
+    9971             :                 }
+    9972           0 : L20:
+    9973           0 :                 a2 *= 1.05;
+    9974             : 
+    9975             : 
+    9976           0 :                 if (a2 < .563) {
+    9977           0 :                     s = gam * (1. -  std::sqrt(a2)) / (a2 + 1.);
+    9978             :                 }
+    9979             :             }
+    9980    11455367 :         } else if (std::abs(*dmin__ - *dn2)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin__ + *dn2)) {
+    9981             : 
+    9982           0 :             *ttype = -5;
+    9983           0 :             s = *dmin__ * .25;
+    9984             : 
+    9985           0 :             np = nn - (*pp << 1);
+    9986           0 :             b1 = z__[np - 2];
+    9987           0 :             b2 = z__[np - 6];
+    9988           0 :             gam = *dn2;
+    9989           0 :             if (z__[np - 8] > b2 || z__[np - 4] > b1) {
+    9990             :                 return;
+    9991             :             }
+    9992           0 :             a2 = z__[np - 8] / b2 * (z__[np - 4] / b1 + 1.);
+    9993             : 
+    9994             : 
+    9995           0 :             if (*n0 - *i0 > 2) {
+    9996           0 :                 b2 = z__[nn - 13] / z__[nn - 15];
+    9997           0 :                 a2 += b2;
+    9998           0 :                 i__1 = (*i0 << 2) - 1 + *pp;
+    9999           0 :                 for (i4 = nn - 17; i4 >= i__1; i4 += -4) {
+   10000           0 :                     if (std::abs(b2)<PLUMED_GMX_DOUBLE_MIN) {
+   10001           0 :                         goto L40;
+   10002             :                     }
+   10003             :                     b1 = b2;
+   10004           0 :                     if (z__[i4] > z__[i4 - 2]) {
+   10005             :                         return;
+   10006             :                     }
+   10007           0 :                     b2 *= z__[i4] / z__[i4 - 2];
+   10008           0 :                     a2 += b2;
+   10009           0 :                     if (((b2>b1) ? b2 : b1) * 100. < a2 || .563 < a2) {
+   10010           0 :                         goto L40;
+   10011             :                     }
+   10012             :                 }
+   10013           0 : L40:
+   10014           0 :                 a2 *= 1.05;
+   10015             :             }
+   10016             : 
+   10017           0 :             if (a2 < .563) {
+   10018           0 :                 s = gam * (1. -  std::sqrt(a2)) / (a2 + 1.);
+   10019             :             }
+   10020             :         } else {
+   10021             : 
+   10022    11455367 :             if (*ttype == -6) {
+   10023             :                 g += (1. - g) * .333;
+   10024    11455367 :             } else if (*ttype == -18) {
+   10025             :                 g = .083250000000000005;
+   10026             :             } else {
+   10027             :                 g = .25;
+   10028             :             }
+   10029    11455367 :             s = g * *dmin__;
+   10030    11455367 :             *ttype = -6;
+   10031             :         }
+   10032             : 
+   10033      265113 :     } else if (*n0in == *n0 + 1) {
+   10034             : 
+   10035      265004 :         if ( std::abs(*dmin1 - *dn1)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin1 + *dn1) &&
+   10036           0 :              std::abs(*dmin2 - *dn2)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin2 + *dn2)) {
+   10037             : 
+   10038           0 :             *ttype = -7;
+   10039           0 :             s = *dmin1 * .333;
+   10040           0 :             if (z__[nn - 5] > z__[nn - 7]) {
+   10041             :                 return;
+   10042             :             }
+   10043           0 :             b1 = z__[nn - 5] / z__[nn - 7];
+   10044             :             b2 = b1;
+   10045           0 :             if (std::abs(b2)<PLUMED_GMX_DOUBLE_MIN) {
+   10046           0 :                 goto L60;
+   10047             :             }
+   10048           0 :             i__1 = (*i0 << 2) - 1 + *pp;
+   10049           0 :             for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
+   10050             :                 a2 = b1;
+   10051           0 :                 if (z__[i4] > z__[i4 - 2]) {
+   10052             :                     return;
+   10053             :                 }
+   10054           0 :                 b1 *= z__[i4] / z__[i4 - 2];
+   10055           0 :                 b2 += b1;
+   10056           0 :                 if (((a2>b1) ? a2 : b1) * 100. < b2) {
+   10057           0 :                     goto L60;
+   10058             :                 }
+   10059             :             }
+   10060           0 : L60:
+   10061           0 :             b2 =  std::sqrt(b2 * 1.05);
+   10062             :             d__1 = b2;
+   10063           0 :             a2 = *dmin1 / (d__1 * d__1 + 1.);
+   10064           0 :             gap2 = *dmin2 * .5 - a2;
+   10065           0 :             if (gap2 > 0. && gap2 > b2 * a2) {
+   10066           0 :                 d__1 = s, d__2 = a2 * (1. - a2 * 1.01 * (b2 / gap2) * b2);
+   10067           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   10068             :             } else {
+   10069           0 :                 d__1 = s, d__2 = a2 * (1. - b2 * 1.01);
+   10070           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   10071           0 :                 *ttype = -8;
+   10072             :             }
+   10073             :         } else {
+   10074             : 
+   10075      265004 :             s = *dmin1 * .25;
+   10076      265004 :             if (std::abs(*dmin1 - *dn1)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin1 + *dn1)) {
+   10077           0 :                 s = *dmin1 * .5;
+   10078             :             }
+   10079      265004 :             *ttype = -9;
+   10080             :         }
+   10081             : 
+   10082         109 :     } else if (*n0in == *n0 + 2) {
+   10083             : 
+   10084         108 :         if (std::abs(*dmin2 - *dn2)<PLUMED_GMX_DOUBLE_EPS*std::abs(*dmin2 + *dn2) &&
+   10085           0 :         z__[nn - 5] * 2. < z__[nn - 7]) {
+   10086           0 :             *ttype = -10;
+   10087           0 :             s = *dmin2 * .333;
+   10088           0 :             if (z__[nn - 5] > z__[nn - 7]) {
+   10089             :                 return;
+   10090             :             }
+   10091           0 :             b1 = z__[nn - 5] / z__[nn - 7];
+   10092             :             b2 = b1;
+   10093           0 :             if (std::abs(b2)<PLUMED_GMX_DOUBLE_MIN) {
+   10094           0 :                 goto L80;
+   10095             :             }
+   10096           0 :             i__1 = (*i0 << 2) - 1 + *pp;
+   10097           0 :             for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
+   10098           0 :                 if (z__[i4] > z__[i4 - 2]) {
+   10099             :                     return;
+   10100             :                 }
+   10101           0 :                 b1 *= z__[i4] / z__[i4 - 2];
+   10102           0 :                 b2 += b1;
+   10103           0 :                 if (b1 * 100. < b2) {
+   10104           0 :                     goto L80;
+   10105             :                 }
+   10106             :             }
+   10107           0 : L80:
+   10108           0 :             b2 =  std::sqrt(b2 * 1.05);
+   10109             :             d__1 = b2;
+   10110           0 :             a2 = *dmin2 / (d__1 * d__1 + 1.);
+   10111           0 :             gap2 = z__[nn - 7] + z__[nn - 9] -  std::sqrt(z__[nn - 11]) * std::sqrt(z__[
+   10112             :                     nn - 9]) - a2;
+   10113           0 :             if (gap2 > 0. && gap2 > b2 * a2) {
+   10114           0 :                 d__1 = s, d__2 = a2 * (1. - a2 * 1.01 * (b2 / gap2) * b2);
+   10115           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   10116             :             } else {
+   10117           0 :                 d__1 = s, d__2 = a2 * (1. - b2 * 1.01);
+   10118           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   10119             :             }
+   10120             :         } else {
+   10121         108 :             s = *dmin2 * .25;
+   10122         108 :             *ttype = -11;
+   10123             :         }
+   10124           1 :     } else if (*n0in > *n0 + 2) {
+   10125             : 
+   10126             :         s = 0.;
+   10127           1 :         *ttype = -12;
+   10128             :     }
+   10129             : 
+   10130    11720480 :     *tau = s;
+   10131    11720480 :     return;
+   10132             : 
+   10133             : }
+   10134             : 
+   10135             : 
+   10136             : }
+   10137             : }
+   10138             : #include <cmath>
+   10139             : #include "lapack.h"
+   10140             : 
+   10141             : #include "blas/blas.h"
+   10142             : namespace PLMD{
+   10143             : namespace lapack{
+   10144             : using namespace blas;
+   10145             : void
+   10146    12568749 : PLUMED_BLAS_F77_FUNC(dlasq5,DLASQ5)(int *i0, 
+   10147             :         int *n0,
+   10148             :         double *z__, 
+   10149             :         int *pp, 
+   10150             :         double *tau,
+   10151             :         double *dmin__, 
+   10152             :         double *dmin1, 
+   10153             :         double *dmin2, 
+   10154             :         double *dn,
+   10155             :         double *dnm1, 
+   10156             :         double *dnm2,
+   10157             :         int *ieee)
+   10158             : {
+   10159             :     int i__1;
+   10160             :     double d__1, d__2;
+   10161             : 
+   10162             :     double d__;
+   10163             :     int    j4, j4p2;
+   10164             :     double emin, temp;
+   10165             : 
+   10166    12568749 :     --z__;
+   10167             : 
+   10168    12568749 :     if (*n0 - *i0 - 1 <= 0) {
+   10169             :         return;
+   10170             :     }
+   10171             : 
+   10172    12568749 :     j4 = (*i0 << 2) + *pp - 3;
+   10173    12568749 :     emin = z__[j4 + 4];
+   10174    12568749 :     d__ = z__[j4] - *tau;
+   10175    12568749 :     *dmin__ = d__;
+   10176    12568749 :     *dmin1 = -z__[j4];
+   10177             : 
+   10178    12568749 :     if (*ieee) {
+   10179             : 
+   10180    12568749 :         if (*pp == 0) {
+   10181     6430785 :             i__1 = 4*(*n0 - 3);
+   10182     7707670 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10183     1276885 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   10184     1276885 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   10185     1276885 :                 d__ = d__ * temp - *tau;
+   10186     1276885 :                 if(d__<*dmin__)
+   10187      328486 :                   *dmin__ = d__;
+   10188     1276885 :                 z__[j4] = z__[j4 - 1] * temp;
+   10189             :                 d__1 = z__[j4];
+   10190     1276885 :                 if(d__1<emin)
+   10191             :                   emin = d__1;
+   10192             :             }
+   10193             :         } else {
+   10194     6137964 :             i__1 = 4*(*n0 - 3);
+   10195     7015847 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10196      877883 :                 z__[j4 - 3] = d__ + z__[j4];
+   10197      877883 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   10198      877883 :                 d__ = d__ * temp - *tau;
+   10199      877883 :                 if(d__<*dmin__)
+   10200      239960 :                   *dmin__ = d__;
+   10201      877883 :                 z__[j4 - 1] = z__[j4] * temp;
+   10202             :                 d__1 = z__[j4 - 1];
+   10203      877883 :                 if(d__1<emin)
+   10204             :                   emin = d__1;
+   10205             :             }
+   10206             :         }
+   10207             : 
+   10208    12568749 :         *dnm2 = d__;
+   10209    12568749 :         *dmin2 = *dmin__;
+   10210    12568749 :         j4 = 4*(*n0 - 2) - *pp;
+   10211    12568749 :         j4p2 = j4 + (*pp << 1) - 1;
+   10212    12568749 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   10213    12568749 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10214    12568749 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   10215    12568749 :         if(*dnm1<*dmin__)
+   10216     9958642 :           *dmin__ = *dnm1;
+   10217             : 
+   10218    12568749 :         *dmin1 = *dmin__;
+   10219    12568749 :         j4 += 4;
+   10220    12568749 :         j4p2 = j4 + (*pp << 1) - 1;
+   10221    12568749 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   10222    12568749 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10223    12568749 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   10224    12568749 :         if(*dn<*dmin__)
+   10225    12019811 :           *dmin__ = *dn;
+   10226             : 
+   10227             :     } else {
+   10228             : 
+   10229           0 :         if (*pp == 0) {
+   10230           0 :             i__1 = 4*(*n0 - 3);
+   10231           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10232           0 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   10233           0 :                 if (d__ < 0.) {
+   10234             :                     return;
+   10235             :                 } else {
+   10236           0 :                     z__[j4] = z__[j4 + 1] * (z__[j4 - 1] / z__[j4 - 2]);
+   10237           0 :                     d__ = z__[j4 + 1] * (d__ / z__[j4 - 2]) - *tau;
+   10238             :                 }
+   10239           0 :                 if(d__<*dmin__)
+   10240           0 :                   *dmin__ = d__;
+   10241           0 :                 d__1 = emin, d__2 = z__[j4];
+   10242           0 :                 emin = (d__1<d__2) ? d__1 : d__2;
+   10243             :             }
+   10244             :         } else {
+   10245           0 :             i__1 = 4*(*n0 - 3);
+   10246           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10247           0 :                 z__[j4 - 3] = d__ + z__[j4];
+   10248           0 :                 if (d__ < 0.) {
+   10249             :                     return;
+   10250             :                 } else {
+   10251           0 :                     z__[j4 - 1] = z__[j4 + 2] * (z__[j4] / z__[j4 - 3]);
+   10252           0 :                     d__ = z__[j4 + 2] * (d__ / z__[j4 - 3]) - *tau;
+   10253             :                 }
+   10254           0 :                 if(d__<*dmin__)
+   10255           0 :                   *dmin__ = d__;
+   10256           0 :                 d__1 = emin, d__2 = z__[j4 - 1];
+   10257           0 :                 emin = (d__1<d__2) ? d__1 : d__2;
+   10258             :             }
+   10259             :         }
+   10260             : 
+   10261           0 :         *dnm2 = d__;
+   10262           0 :         *dmin2 = *dmin__;
+   10263           0 :         j4 = 4*(*n0 - 2) - *pp;
+   10264           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   10265           0 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   10266           0 :         if (*dnm2 < 0.) {
+   10267             :             return;
+   10268             :         } else {
+   10269           0 :             z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10270           0 :             *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   10271             :         }
+   10272           0 :         if(*dnm1<*dmin__)
+   10273           0 :           *dmin__ = *dnm1;
+   10274             : 
+   10275           0 :         *dmin1 = *dmin__;
+   10276           0 :         j4 += 4;
+   10277           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   10278           0 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   10279           0 :         if (*dnm1 < 0.) {
+   10280             :             return;
+   10281             :         } else {
+   10282           0 :             z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10283           0 :             *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   10284             :         }
+   10285           0 :         if(*dn<*dmin__)
+   10286           0 :           *dmin__ = *dn;
+   10287             : 
+   10288             :     }
+   10289             : 
+   10290    12568749 :     z__[j4 + 2] = *dn;
+   10291    12568749 :     z__[(*n0 << 2) - *pp] = emin;
+   10292    12568749 :     return;
+   10293             : 
+   10294             : }
+   10295             : 
+   10296             : }
+   10297             : }
+   10298             : #include <cmath>
+   10299             : #include "lapack.h"
+   10300             : #include "lapack_limits.h"
+   10301             : 
+   10302             : #include "real.h"
+   10303             : 
+   10304             : #include "blas/blas.h"
+   10305             : namespace PLMD{
+   10306             : namespace lapack{
+   10307             : using namespace blas;
+   10308             : void 
+   10309           0 : PLUMED_BLAS_F77_FUNC(dlasq6,DLASQ6)(int *i0, 
+   10310             :         int *n0, 
+   10311             :         double *z__, 
+   10312             :         int *pp, 
+   10313             :         double *dmin__, 
+   10314             :         double *dmin1, 
+   10315             :         double *dmin2,
+   10316             :         double *dn, 
+   10317             :         double *dnm1, 
+   10318             :         double *dnm2)
+   10319             : {
+   10320             :     int i__1;
+   10321             :     double d__1, d__2;
+   10322             : 
+   10323             :     /* Local variables */
+   10324             :     double d__;
+   10325             :     int j4, j4p2;
+   10326             :     double emin, temp;
+   10327             :     const double safemin = PLUMED_GMX_DOUBLE_MIN*(1.0+PLUMED_GMX_DOUBLE_EPS);
+   10328             : 
+   10329           0 :     --z__;
+   10330             : 
+   10331           0 :     if (*n0 - *i0 - 1 <= 0) {
+   10332             :         return;
+   10333             :     }
+   10334             : 
+   10335           0 :     j4 = (*i0 << 2) + *pp - 3;
+   10336           0 :     emin = z__[j4 + 4];
+   10337           0 :     d__ = z__[j4];
+   10338           0 :     *dmin__ = d__;
+   10339             : 
+   10340           0 :     if (*pp == 0) {
+   10341           0 :         i__1 = 4*(*n0 - 3);
+   10342           0 :         for (j4 = *i0*4; j4 <= i__1; j4 += 4) {
+   10343           0 :             z__[j4 - 2] = d__ + z__[j4 - 1];
+   10344           0 :             if (std::abs(z__[j4 - 2])<PLUMED_GMX_DOUBLE_MIN) {
+   10345           0 :                 z__[j4] = 0.;
+   10346           0 :                 d__ = z__[j4 + 1];
+   10347           0 :                 *dmin__ = d__;
+   10348             :                 emin = 0.;
+   10349           0 :             } else if (safemin * z__[j4 + 1] < z__[j4 - 2] && safemin * z__[j4 
+   10350             :                     - 2] < z__[j4 + 1]) {
+   10351           0 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   10352           0 :                 z__[j4] = z__[j4 - 1] * temp;
+   10353           0 :                 d__ *= temp;
+   10354             :             } else {
+   10355           0 :                 z__[j4] = z__[j4 + 1] * (z__[j4 - 1] / z__[j4 - 2]);
+   10356           0 :                 d__ = z__[j4 + 1] * (d__ / z__[j4 - 2]);
+   10357             :             }
+   10358           0 :             if(d__<*dmin__)
+   10359           0 :               *dmin__ = d__;
+   10360             : 
+   10361           0 :             d__1 = emin, d__2 = z__[j4];
+   10362           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   10363             :         }
+   10364             :     } else {
+   10365           0 :         i__1 = 4*(*n0 - 3);
+   10366           0 :         for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   10367           0 :             z__[j4 - 3] = d__ + z__[j4];
+   10368           0 :             if (std::abs(z__[j4 - 3])<PLUMED_GMX_DOUBLE_MIN) {
+   10369           0 :                 z__[j4 - 1] = 0.;
+   10370           0 :                 d__ = z__[j4 + 2];
+   10371           0 :                 *dmin__ = d__;
+   10372             :                 emin = 0.;
+   10373           0 :             } else if (safemin * z__[j4 + 2] < z__[j4 - 3] && safemin * z__[j4 
+   10374             :                     - 3] < z__[j4 + 2]) {
+   10375           0 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   10376           0 :                 z__[j4 - 1] = z__[j4] * temp;
+   10377           0 :                 d__ *= temp;
+   10378             :             } else {
+   10379           0 :                 z__[j4 - 1] = z__[j4 + 2] * (z__[j4] / z__[j4 - 3]);
+   10380           0 :                 d__ = z__[j4 + 2] * (d__ / z__[j4 - 3]);
+   10381             :             }
+   10382           0 :             if(d__<*dmin__)
+   10383           0 :               *dmin__ = d__;
+   10384           0 :             d__1 = emin, d__2 = z__[j4 - 1];
+   10385           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   10386             :         }
+   10387             :     }
+   10388             : 
+   10389           0 :     *dnm2 = d__;
+   10390           0 :     *dmin2 = *dmin__;
+   10391           0 :     j4 = 4*(*n0 - 2) - *pp;
+   10392           0 :     j4p2 = j4 + (*pp << 1) - 1;
+   10393           0 :     z__[j4 - 2] = *dnm2 + z__[j4p2];
+   10394           0 :     if (std::abs(z__[j4 - 2])<PLUMED_GMX_DOUBLE_MIN) {
+   10395           0 :         z__[j4] = 0.;
+   10396           0 :         *dnm1 = z__[j4p2 + 2];
+   10397           0 :         *dmin__ = *dnm1;
+   10398             :         emin = 0.;
+   10399           0 :     } else if (safemin * z__[j4p2 + 2] < z__[j4 - 2] && safemin * z__[j4 - 2] < 
+   10400             :             z__[j4p2 + 2]) {
+   10401           0 :         temp = z__[j4p2 + 2] / z__[j4 - 2];
+   10402           0 :         z__[j4] = z__[j4p2] * temp;
+   10403           0 :         *dnm1 = *dnm2 * temp;
+   10404             :     } else {
+   10405           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10406           0 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]);
+   10407             :     }
+   10408           0 :     if(*dnm1<*dmin__)
+   10409           0 :       *dmin__ = *dnm1;
+   10410             : 
+   10411           0 :     *dmin1 = *dmin__;
+   10412           0 :     j4 += 4;
+   10413           0 :     j4p2 = j4 + (*pp << 1) - 1;
+   10414           0 :     z__[j4 - 2] = *dnm1 + z__[j4p2];
+   10415           0 :     if (std::abs(z__[j4 - 2])<PLUMED_GMX_DOUBLE_MIN) {
+   10416           0 :         z__[j4] = 0.;
+   10417           0 :         *dn = z__[j4p2 + 2];
+   10418           0 :         *dmin__ = *dn;
+   10419             :         emin = 0.;
+   10420           0 :     } else if (safemin * z__[j4p2 + 2] < z__[j4 - 2] && safemin * z__[j4 - 2] < 
+   10421             :             z__[j4p2 + 2]) {
+   10422           0 :         temp = z__[j4p2 + 2] / z__[j4 - 2];
+   10423           0 :         z__[j4] = z__[j4p2] * temp;
+   10424           0 :         *dn = *dnm1 * temp;
+   10425             :     } else {
+   10426           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   10427           0 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]);
+   10428             :     }
+   10429           0 :     if(*dn<*dmin__)
+   10430           0 :       *dmin__ = *dn;
+   10431             : 
+   10432           0 :     z__[j4 + 2] = *dn;
+   10433           0 :     z__[(*n0 << 2) - *pp] = emin;
+   10434           0 :     return;
+   10435             : 
+   10436             : 
+   10437             : } 
+   10438             : }
+   10439             : }
+   10440             : #include <cmath>
+   10441             : 
+   10442             : #include "real.h"
+   10443             : #include "lapack.h"
+   10444             : 
+   10445             : #include "blas/blas.h"
+   10446             : namespace PLMD{
+   10447             : namespace lapack{
+   10448             : using namespace blas;
+   10449             : void 
+   10450        9382 : PLUMED_BLAS_F77_FUNC(dlasr,DLASR)(const char *side, 
+   10451             :        const char *pivot, 
+   10452             :        const char *direct, 
+   10453             :        int *m,
+   10454             :        int *n, 
+   10455             :        double *c__, 
+   10456             :        double *s, 
+   10457             :        double *a, 
+   10458             :        int *lda)
+   10459             : {
+   10460             :     /* System generated locals */
+   10461             :     int a_dim1, a_offset, i__1, i__2;
+   10462             : 
+   10463             :     /* Local variables */
+   10464             :     int i__, j;
+   10465             :     double temp;
+   10466             :     double ctemp, stemp;
+   10467             : 
+   10468        9382 :     --c__;
+   10469        9382 :     --s;
+   10470        9382 :     a_dim1 = *lda;
+   10471        9382 :     a_offset = 1 + a_dim1;
+   10472        9382 :     a -= a_offset;
+   10473             : 
+   10474             :     /* Function Body */
+   10475             : 
+   10476        9382 :     if (*m == 0 || *n == 0) {
+   10477             :         return;
+   10478             :     }
+   10479        9382 :     if (*side=='L' || *side=='l') {
+   10480             : 
+   10481        4691 :         if (*pivot=='V' || *pivot=='v') {
+   10482        4691 :             if (*direct=='F' || *direct=='f') {
+   10483             :                 i__1 = *m - 1;
+   10484       49675 :                 for (j = 1; j <= i__1; ++j) {
+   10485       45017 :                     ctemp = c__[j];
+   10486       45017 :                     stemp = s[j];
+   10487       45017 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10488       45017 :                         i__2 = *n;
+   10489      861025 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   10490      816008 :                             temp = a[j + 1 + i__ * a_dim1];
+   10491      816008 :                             a[j + 1 + i__ * a_dim1] = ctemp * temp - stemp * 
+   10492      816008 :                                     a[j + i__ * a_dim1];
+   10493      816008 :                             a[j + i__ * a_dim1] = stemp * temp + ctemp * a[j 
+   10494      816008 :                                     + i__ * a_dim1];
+   10495             :                         }
+   10496             :                     }
+   10497             :                 }
+   10498          33 :             } else if (*direct=='B' || *direct=='b') {
+   10499         305 :                 for (j = *m - 1; j >= 1; --j) {
+   10500         272 :                     ctemp = c__[j];
+   10501         272 :                     stemp = s[j];
+   10502         272 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10503         272 :                         i__1 = *n;
+   10504        4080 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   10505        3808 :                             temp = a[j + 1 + i__ * a_dim1];
+   10506        3808 :                             a[j + 1 + i__ * a_dim1] = ctemp * temp - stemp * 
+   10507        3808 :                                     a[j + i__ * a_dim1];
+   10508        3808 :                             a[j + i__ * a_dim1] = stemp * temp + ctemp * a[j 
+   10509        3808 :                                     + i__ * a_dim1];
+   10510             :                         }
+   10511             :                     }
+   10512             :                 }
+   10513             :             }
+   10514           0 :         } else if (*pivot=='T' || *pivot=='t') {
+   10515           0 :             if (*direct=='F' || *direct=='f') {
+   10516             :                 i__1 = *m;
+   10517           0 :                 for (j = 2; j <= i__1; ++j) {
+   10518           0 :                     ctemp = c__[j - 1];
+   10519           0 :                     stemp = s[j - 1];
+   10520           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10521           0 :                         i__2 = *n;
+   10522           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   10523           0 :                             temp = a[j + i__ * a_dim1];
+   10524           0 :                             a[j + i__ * a_dim1] = ctemp * temp - stemp * a[
+   10525           0 :                                     i__ * a_dim1 + 1];
+   10526           0 :                             a[i__ * a_dim1 + 1] = stemp * temp + ctemp * a[
+   10527           0 :                                     i__ * a_dim1 + 1];
+   10528             :                         }
+   10529             :                     }
+   10530             :                 }
+   10531           0 :             } else if (*direct=='B' || *direct=='b') {
+   10532           0 :                 for (j = *m; j >= 2; --j) {
+   10533           0 :                     ctemp = c__[j - 1];
+   10534           0 :                     stemp = s[j - 1];
+   10535           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10536           0 :                         i__1 = *n;
+   10537           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   10538           0 :                             temp = a[j + i__ * a_dim1];
+   10539           0 :                             a[j + i__ * a_dim1] = ctemp * temp - stemp * a[
+   10540           0 :                                     i__ * a_dim1 + 1];
+   10541           0 :                             a[i__ * a_dim1 + 1] = stemp * temp + ctemp * a[
+   10542           0 :                                     i__ * a_dim1 + 1];
+   10543             :                         }
+   10544             :                     }
+   10545             :                 }
+   10546             :             }
+   10547           0 :         } else if (*pivot=='B' || *pivot=='b') {
+   10548           0 :             if (*direct=='F' || *direct=='f') {
+   10549             :                 i__1 = *m - 1;
+   10550           0 :                 for (j = 1; j <= i__1; ++j) {
+   10551           0 :                     ctemp = c__[j];
+   10552           0 :                     stemp = s[j];
+   10553           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10554           0 :                         i__2 = *n;
+   10555           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   10556           0 :                             temp = a[j + i__ * a_dim1];
+   10557           0 :                             a[j + i__ * a_dim1] = stemp * a[*m + i__ * a_dim1]
+   10558           0 :                                      + ctemp * temp;
+   10559           0 :                             a[*m + i__ * a_dim1] = ctemp * a[*m + i__ * 
+   10560           0 :                                     a_dim1] - stemp * temp;
+   10561             :                         }
+   10562             :                     }
+   10563             :                 }
+   10564           0 :             } else if (*direct=='B' || *direct=='b') {
+   10565           0 :                 for (j = *m - 1; j >= 1; --j) {
+   10566           0 :                     ctemp = c__[j];
+   10567           0 :                     stemp = s[j];
+   10568           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10569           0 :                         i__1 = *n;
+   10570           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   10571           0 :                             temp = a[j + i__ * a_dim1];
+   10572           0 :                             a[j + i__ * a_dim1] = stemp * a[*m + i__ * a_dim1]
+   10573           0 :                                      + ctemp * temp;
+   10574           0 :                             a[*m + i__ * a_dim1] = ctemp * a[*m + i__ * 
+   10575           0 :                                     a_dim1] - stemp * temp;
+   10576             :                         }
+   10577             :                     }
+   10578             :                 }
+   10579             :             }
+   10580             :         }
+   10581        4691 :     } else if (*side=='R' || *side=='r') {
+   10582             : 
+   10583        4691 :         if (*pivot=='V' || *pivot=='v') {
+   10584        4691 :             if (*direct=='F' || *direct=='f') {
+   10585             :                 i__1 = *n - 1;
+   10586       49616 :                 for (j = 1; j <= i__1; ++j) {
+   10587       44958 :                     ctemp = c__[j];
+   10588       44958 :                     stemp = s[j];
+   10589       44958 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10590       44958 :                         i__2 = *m;
+   10591      843208 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   10592      798250 :                             temp = a[i__ + (j + 1) * a_dim1];
+   10593      798250 :                             a[i__ + (j + 1) * a_dim1] = ctemp * temp - stemp *
+   10594      798250 :                                      a[i__ + j * a_dim1];
+   10595      798250 :                             a[i__ + j * a_dim1] = stemp * temp + ctemp * a[
+   10596      798250 :                                     i__ + j * a_dim1];
+   10597             :                         }
+   10598             :                     }
+   10599             :                 }
+   10600          33 :             } else if (*direct=='B' || *direct=='b') {
+   10601         305 :                 for (j = *n - 1; j >= 1; --j) {
+   10602         272 :                     ctemp = c__[j];
+   10603         272 :                     stemp = s[j];
+   10604         272 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10605         272 :                         i__1 = *m;
+   10606        4080 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   10607        3808 :                             temp = a[i__ + (j + 1) * a_dim1];
+   10608        3808 :                             a[i__ + (j + 1) * a_dim1] = ctemp * temp - stemp *
+   10609        3808 :                                      a[i__ + j * a_dim1];
+   10610        3808 :                             a[i__ + j * a_dim1] = stemp * temp + ctemp * a[
+   10611        3808 :                                     i__ + j * a_dim1];
+   10612             :                         }
+   10613             :                     }
+   10614             :                 }
+   10615             :             }
+   10616           0 :         } else if (*pivot=='T' || *pivot=='t') {
+   10617           0 :             if (*direct=='F' || *direct=='f') {
+   10618             :                 i__1 = *n;
+   10619           0 :                 for (j = 2; j <= i__1; ++j) {
+   10620           0 :                     ctemp = c__[j - 1];
+   10621           0 :                     stemp = s[j - 1];
+   10622           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10623           0 :                         i__2 = *m;
+   10624           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   10625           0 :                             temp = a[i__ + j * a_dim1];
+   10626           0 :                             a[i__ + j * a_dim1] = ctemp * temp - stemp * a[
+   10627           0 :                                     i__ + a_dim1];
+   10628           0 :                             a[i__ + a_dim1] = stemp * temp + ctemp * a[i__ + 
+   10629           0 :                                     a_dim1];
+   10630             :                         }
+   10631             :                     }
+   10632             :                 }
+   10633           0 :             } else if (*direct=='B' || *direct=='b') {
+   10634           0 :                 for (j = *n; j >= 2; --j) {
+   10635           0 :                     ctemp = c__[j - 1];
+   10636           0 :                     stemp = s[j - 1];
+   10637           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10638           0 :                         i__1 = *m;
+   10639           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   10640           0 :                             temp = a[i__ + j * a_dim1];
+   10641           0 :                             a[i__ + j * a_dim1] = ctemp * temp - stemp * a[
+   10642           0 :                                     i__ + a_dim1];
+   10643           0 :                             a[i__ + a_dim1] = stemp * temp + ctemp * a[i__ + 
+   10644           0 :                                     a_dim1];
+   10645             :                         }
+   10646             :                     }
+   10647             :                 }
+   10648             :             }
+   10649           0 :         } else if (*pivot=='B' || *pivot=='b') {
+   10650           0 :             if (*direct=='F' || *direct=='f') {
+   10651             :                 i__1 = *n - 1;
+   10652           0 :                 for (j = 1; j <= i__1; ++j) {
+   10653           0 :                     ctemp = c__[j];
+   10654           0 :                     stemp = s[j];
+   10655           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10656           0 :                         i__2 = *m;
+   10657           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   10658           0 :                             temp = a[i__ + j * a_dim1];
+   10659           0 :                             a[i__ + j * a_dim1] = stemp * a[i__ + *n * a_dim1]
+   10660           0 :                                      + ctemp * temp;
+   10661           0 :                             a[i__ + *n * a_dim1] = ctemp * a[i__ + *n * 
+   10662           0 :                                     a_dim1] - stemp * temp;
+   10663             :                         }
+   10664             :                     }
+   10665             :                 }
+   10666           0 :             } else if (*direct=='B' || *direct=='b') {
+   10667           0 :                 for (j = *n - 1; j >= 1; --j) {
+   10668           0 :                     ctemp = c__[j];
+   10669           0 :                     stemp = s[j];
+   10670           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_DOUBLE_EPS || std::abs(stemp)>PLUMED_GMX_DOUBLE_MIN) {
+   10671           0 :                         i__1 = *m;
+   10672           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   10673           0 :                             temp = a[i__ + j * a_dim1];
+   10674           0 :                             a[i__ + j * a_dim1] = stemp * a[i__ + *n * a_dim1]
+   10675           0 :                                      + ctemp * temp;
+   10676           0 :                             a[i__ + *n * a_dim1] = ctemp * a[i__ + *n * 
+   10677           0 :                                     a_dim1] - stemp * temp;
+   10678             :                         }
+   10679             :                     }
+   10680             :                 }
+   10681             :             }
+   10682             :         }
+   10683             :     }
+   10684             : 
+   10685             :     return;
+   10686             : 
+   10687             : }
+   10688             : 
+   10689             : 
+   10690             : }
+   10691             : }
+   10692             : #include "lapack.h"
+   10693             : 
+   10694             : #include "blas/blas.h"
+   10695             : namespace PLMD{
+   10696             : namespace lapack{
+   10697             : using namespace blas;
+   10698             : void 
+   10699      557314 : PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)(const char *id, 
+   10700             :         int *n, 
+   10701             :         double *d__, 
+   10702             :         int *info)
+   10703             : {
+   10704             :     int i__1, i__2;
+   10705             : 
+   10706             :     int i__, j;
+   10707             :     double d1, d2, d3;
+   10708             :     int dir;
+   10709             :     double tmp;
+   10710             :     int endd;
+   10711             :     int stack[64];
+   10712             :     double dmnmx;
+   10713             :     int start;
+   10714             :     int stkpnt;
+   10715             : 
+   10716      557314 :     --d__;
+   10717             : 
+   10718      557314 :     *info = 0;
+   10719             :     dir = -1;
+   10720      557314 :     if (*id=='D' || *id=='d') 
+   10721             :         dir = 0;
+   10722         668 :     else if (*id=='I' || *id=='i') 
+   10723             :         dir = 1;
+   10724             :    
+   10725             :     if (dir == -1) {
+   10726           0 :         *info = -1;
+   10727      557314 :     } else if (*n < 0) {
+   10728           0 :         *info = -2;
+   10729             :     }
+   10730      557314 :     if (*info != 0) {
+   10731             :         return;
+   10732             :     }
+   10733      557314 :     if (*n <= 1) {
+   10734             :         return;
+   10735             :     }
+   10736             : 
+   10737             :     stkpnt = 1;
+   10738      556655 :     stack[0] = 1;
+   10739      556655 :     stack[1] = *n;
+   10740      556773 : L10:
+   10741      556773 :     start = stack[(stkpnt << 1) - 2];
+   10742      556773 :     endd = stack[(stkpnt << 1) - 1];
+   10743      556773 :     --stkpnt;
+   10744      556773 :     if (endd - start <= 20 && endd - start > 0) {
+   10745             : 
+   10746             : 
+   10747      556714 :         if (dir == 0) {
+   10748             : 
+   10749             :             i__1 = endd;
+   10750     2227034 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10751             :                 i__2 = start + 1;
+   10752     1670332 :                 for (j = i__; j >= i__2; --j) {
+   10753     1670332 :                     if (d__[j] > d__[j - 1]) {
+   10754             :                         dmnmx = d__[j];
+   10755           0 :                         d__[j] = d__[j - 1];
+   10756           0 :                         d__[j - 1] = dmnmx;
+   10757             :                     } else {
+   10758     1670332 :                         goto L30;
+   10759             :                     }
+   10760             :                 }
+   10761     1670332 : L30:
+   10762             :                 ;
+   10763             :             }
+   10764             : 
+   10765             :         } else {
+   10766             : 
+   10767             :             i__1 = endd;
+   10768         108 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10769             :                 i__2 = start + 1;
+   10770          96 :                 for (j = i__; j >= i__2; --j) {
+   10771          96 :                     if (d__[j] < d__[j - 1]) {
+   10772             :                         dmnmx = d__[j];
+   10773           0 :                         d__[j] = d__[j - 1];
+   10774           0 :                         d__[j - 1] = dmnmx;
+   10775             :                     } else {
+   10776          96 :                         goto L50;
+   10777             :                     }
+   10778             :                 }
+   10779          96 : L50:
+   10780             :                 ;
+   10781             :             }
+   10782             : 
+   10783             :         }
+   10784             : 
+   10785          59 :     } else if (endd - start > 20) {
+   10786             : 
+   10787          59 :         d1 = d__[start];
+   10788          59 :         d2 = d__[endd];
+   10789          59 :         i__ = (start + endd) / 2;
+   10790          59 :         d3 = d__[i__];
+   10791          59 :         if (d1 < d2) {
+   10792           3 :             if (d3 < d1) {
+   10793             :                 dmnmx = d1;
+   10794           3 :             } else if (d3 < d2) {
+   10795             :                 dmnmx = d3;
+   10796             :             } else {
+   10797             :                 dmnmx = d2;
+   10798             :             }
+   10799             :         } else {
+   10800          56 :             if (d3 < d2) {
+   10801             :                 dmnmx = d2;
+   10802          56 :             } else if (d3 < d1) {
+   10803             :                 dmnmx = d3;
+   10804             :             } else {
+   10805             :                 dmnmx = d1;
+   10806             :             }
+   10807             :         }
+   10808             : 
+   10809          59 :         if (dir == 0) {
+   10810             : 
+   10811          56 :             i__ = start - 1;
+   10812          56 :             j = endd + 1;
+   10813        1944 : L60:
+   10814        1944 : L70:
+   10815        2000 :             --j;
+   10816        2000 :             if (d__[j] < dmnmx) {
+   10817        1944 :                 goto L70;
+   10818             :             }
+   10819          56 : L80:
+   10820        1980 :             ++i__;
+   10821        1980 :             if (d__[i__] > dmnmx) {
+   10822        1924 :                 goto L80;
+   10823             :             }
+   10824          56 :             if (i__ < j) {
+   10825             :                 tmp = d__[i__];
+   10826           0 :                 d__[i__] = d__[j];
+   10827           0 :                 d__[j] = tmp;
+   10828           0 :                 goto L60;
+   10829             :             }
+   10830          56 :             if (j - start > endd - j - 1) {
+   10831             :                 ++stkpnt;
+   10832             :                 stack[(stkpnt << 1) - 2] = start;
+   10833          36 :                 stack[(stkpnt << 1) - 1] = j;
+   10834          36 :                 ++stkpnt;
+   10835          36 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   10836          36 :                 stack[(stkpnt << 1) - 1] = endd;
+   10837             :             } else {
+   10838             :                 ++stkpnt;
+   10839          20 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   10840          20 :                 stack[(stkpnt << 1) - 1] = endd;
+   10841          20 :                 ++stkpnt;
+   10842          20 :                 stack[(stkpnt << 1) - 2] = start;
+   10843          20 :                 stack[(stkpnt << 1) - 1] = j;
+   10844             :             }
+   10845             :         } else {
+   10846             : 
+   10847           3 :             i__ = start - 1;
+   10848           3 :             j = endd + 1;
+   10849          61 : L90:
+   10850          61 : L100:
+   10851          64 :             --j;
+   10852          64 :             if (d__[j] > dmnmx) {
+   10853          61 :                 goto L100;
+   10854             :             }
+   10855           3 : L110:
+   10856          63 :             ++i__;
+   10857          63 :             if (d__[i__] < dmnmx) {
+   10858          60 :                 goto L110;
+   10859             :             }
+   10860           3 :             if (i__ < j) {
+   10861             :                 tmp = d__[i__];
+   10862           0 :                 d__[i__] = d__[j];
+   10863           0 :                 d__[j] = tmp;
+   10864           0 :                 goto L90;
+   10865             :             }
+   10866           3 :             if (j - start > endd - j - 1) {
+   10867             :                 ++stkpnt;
+   10868             :                 stack[(stkpnt << 1) - 2] = start;
+   10869           2 :                 stack[(stkpnt << 1) - 1] = j;
+   10870           2 :                 ++stkpnt;
+   10871           2 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   10872           2 :                 stack[(stkpnt << 1) - 1] = endd;
+   10873             :             } else {
+   10874             :                 ++stkpnt;
+   10875           1 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   10876           1 :                 stack[(stkpnt << 1) - 1] = endd;
+   10877           1 :                 ++stkpnt;
+   10878           1 :                 stack[(stkpnt << 1) - 2] = start;
+   10879           1 :                 stack[(stkpnt << 1) - 1] = j;
+   10880             :             }
+   10881             :         }
+   10882             :     }
+   10883      556773 :     if (stkpnt > 0) {
+   10884         118 :         goto L10;
+   10885             :     }
+   10886             :     return;
+   10887             : 
+   10888             : }
+   10889             : }
+   10890             : }
+   10891             : #include "lapack.h"
+   10892             : #include "blas/blas.h"
+   10893             : namespace PLMD{
+   10894             : namespace lapack{
+   10895             : using namespace blas;
+   10896             : 
+   10897          10 : void PLUMED_BLAS_F77_FUNC(dlasrt2,DLASRT2)(const char *id, 
+   10898             :               int *n, 
+   10899             :               double *d__, 
+   10900             :               int * key, 
+   10901             :               int *info)
+   10902             : {
+   10903             :     int i__1, i__2;
+   10904             : 
+   10905             :     int i__, j;
+   10906             :     double d1, d2, d3;
+   10907             :     int dir;
+   10908             :     double tmp;
+   10909             :     int endd;
+   10910             :     int stack[64];
+   10911             :     double dmnmx;
+   10912             :     int start;
+   10913             :     int tmpkey, stkpnt;
+   10914             : 
+   10915          10 :     --key;
+   10916          10 :     --d__;
+   10917             : 
+   10918          10 :     *info = 0;
+   10919             :     dir = -1;
+   10920          10 :     if (*id=='D' || *id=='d')
+   10921             :         dir = 0;
+   10922          10 :     else if (*id=='I' || *id=='i')
+   10923             :         dir = 1;
+   10924             :     
+   10925             :     if (dir == -1) {
+   10926           0 :         *info = -1;
+   10927          10 :     } else if (*n < 0) {
+   10928           0 :         *info = -2;
+   10929             :     }
+   10930          10 :     if (*info != 0) {
+   10931             :         return;
+   10932             :     }
+   10933             : 
+   10934          10 :     if (*n <= 1) {
+   10935             :         return;
+   10936             :     }
+   10937             : 
+   10938             :     stkpnt = 1;
+   10939          10 :     stack[0] = 1;
+   10940          10 :     stack[1] = *n;
+   10941          10 : L10:
+   10942          10 :     start = stack[(stkpnt << 1) - 2];
+   10943          10 :     endd = stack[(stkpnt << 1) - 1];
+   10944          10 :     --stkpnt;
+   10945          10 :     if (endd - start > 0) {
+   10946             : 
+   10947          10 :         if (dir == 0) {
+   10948             : 
+   10949             :             i__1 = endd;
+   10950           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10951             :                 i__2 = start + 1;
+   10952           0 :                 for (j = i__; j >= i__2; --j) {
+   10953           0 :                     if (d__[j] > d__[j - 1]) {
+   10954             :                         dmnmx = d__[j];
+   10955           0 :                         d__[j] = d__[j - 1];
+   10956           0 :                         d__[j - 1] = dmnmx;
+   10957           0 :                         tmpkey = key[j];
+   10958           0 :                         key[j] = key[j - 1];
+   10959           0 :                         key[j - 1] = tmpkey;
+   10960             :                     } else {
+   10961             :                         break;
+   10962             :                     }
+   10963             :                 }
+   10964             :             }
+   10965             : 
+   10966             :         } else {
+   10967             : 
+   10968             :             i__1 = endd;
+   10969         770 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   10970             :                 i__2 = start + 1;
+   10971       14898 :                 for (j = i__; j >= i__2; --j) {
+   10972       14832 :                     if (d__[j] < d__[j - 1]) {
+   10973             :                         dmnmx = d__[j];
+   10974       14138 :                         d__[j] = d__[j - 1];
+   10975       14138 :                         d__[j - 1] = dmnmx;
+   10976       14138 :                         tmpkey = key[j];
+   10977       14138 :                         key[j] = key[j - 1];
+   10978       14138 :                         key[j - 1] = tmpkey;
+   10979             :                     } else {
+   10980             :                         break;
+   10981             :                     }
+   10982             :                 }
+   10983             :             }
+   10984             : 
+   10985             :         }
+   10986             : 
+   10987           0 :     } else if (endd - start > 20) {
+   10988             : 
+   10989           0 :         d1 = d__[start];
+   10990           0 :         d2 = d__[endd];
+   10991           0 :         i__ = (start + endd) / 2;
+   10992           0 :         d3 = d__[i__];
+   10993           0 :         if (d1 < d2) {
+   10994           0 :             if (d3 < d1) {
+   10995             :                 dmnmx = d1;
+   10996           0 :             } else if (d3 < d2) {
+   10997             :                 dmnmx = d3;
+   10998             :             } else {
+   10999             :                 dmnmx = d2;
+   11000             :             }
+   11001             :         } else {
+   11002           0 :             if (d3 < d2) {
+   11003             :                 dmnmx = d2;
+   11004           0 :             } else if (d3 < d1) {
+   11005             :                 dmnmx = d3;
+   11006             :             } else {
+   11007             :                 dmnmx = d1;
+   11008             :             }
+   11009             :         }
+   11010             : 
+   11011           0 :         if (dir == 0) {
+   11012             : 
+   11013           0 :             i__ = start - 1;
+   11014           0 :             j = endd + 1;
+   11015           0 : L60:
+   11016           0 : L70:
+   11017           0 :             --j;
+   11018           0 :             if (d__[j] < dmnmx) {
+   11019           0 :                 goto L70;
+   11020             :             }
+   11021           0 : L80:
+   11022           0 :             ++i__;
+   11023           0 :             if (d__[i__] > dmnmx) {
+   11024           0 :                 goto L80;
+   11025             :             }
+   11026           0 :             if (i__ < j) {
+   11027             :                 tmp = d__[i__];
+   11028           0 :                 d__[i__] = d__[j];
+   11029           0 :                 d__[j] = tmp;
+   11030           0 :                 tmpkey = key[j];
+   11031           0 :                 key[j] = key[i__];
+   11032           0 :                 key[i__] = tmpkey;
+   11033           0 :                 goto L60;
+   11034             :             }
+   11035           0 :             if (j - start > endd - j - 1) {
+   11036             :                 ++stkpnt;
+   11037             :                 stack[(stkpnt << 1) - 2] = start;
+   11038           0 :                 stack[(stkpnt << 1) - 1] = j;
+   11039           0 :                 ++stkpnt;
+   11040           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   11041           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   11042             :             } else {
+   11043             :                 ++stkpnt;
+   11044           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   11045           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   11046           0 :                 ++stkpnt;
+   11047           0 :                 stack[(stkpnt << 1) - 2] = start;
+   11048           0 :                 stack[(stkpnt << 1) - 1] = j;
+   11049             :             }
+   11050             :         } else {
+   11051             : 
+   11052           0 :             i__ = start - 1;
+   11053           0 :             j = endd + 1;
+   11054           0 : L90:
+   11055           0 : L100:
+   11056           0 :             --j;
+   11057           0 :             if (d__[j] > dmnmx) {
+   11058           0 :                 goto L100;
+   11059             :             }
+   11060           0 : L110:
+   11061           0 :             ++i__;
+   11062           0 :             if (d__[i__] < dmnmx) {
+   11063           0 :                 goto L110;
+   11064             :             }
+   11065           0 :             if (i__ < j) {
+   11066             :                 tmp = d__[i__];
+   11067           0 :                 d__[i__] = d__[j];
+   11068           0 :                 d__[j] = tmp;
+   11069           0 :                 tmpkey = key[j];
+   11070           0 :                 key[j] = key[i__];
+   11071           0 :                 key[i__] = tmpkey;
+   11072           0 :                 goto L90;
+   11073             :             }
+   11074           0 :             if (j - start > endd - j - 1) {
+   11075             :                 ++stkpnt;
+   11076             :                 stack[(stkpnt << 1) - 2] = start;
+   11077           0 :                 stack[(stkpnt << 1) - 1] = j;
+   11078           0 :                 ++stkpnt;
+   11079           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   11080           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   11081             :             } else {
+   11082             :                 ++stkpnt;
+   11083           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   11084           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   11085           0 :                 ++stkpnt;
+   11086           0 :                 stack[(stkpnt << 1) - 2] = start;
+   11087           0 :                 stack[(stkpnt << 1) - 1] = j;
+   11088             :             }
+   11089             :         }
+   11090             :     }
+   11091          10 :     if (stkpnt > 0) {
+   11092           0 :         goto L10;
+   11093             :     }
+   11094             : 
+   11095             :     return;
+   11096             : }
+   11097             : }
+   11098             : }
+   11099             : #include <cmath>
+   11100             : #include "real.h"
+   11101             : #include "lapack.h"
+   11102             : 
+   11103             : #include "blas/blas.h"
+   11104             : namespace PLMD{
+   11105             : namespace lapack{
+   11106             : using namespace blas;
+   11107             : void
+   11108           0 : PLUMED_BLAS_F77_FUNC(dlassq,DLASSQ)(int *n,
+   11109             :                         double *x,
+   11110             :                         int *incx,
+   11111             :                         double *scale,
+   11112             :                         double *sumsq)
+   11113             : {
+   11114             :   int ix;
+   11115             :   double absxi,t;
+   11116             : 
+   11117           0 :   if(*n>0) {
+   11118           0 :     for(ix=0;ix<=(*n-1)*(*incx);ix+=*incx) {
+   11119           0 :       if(std::abs(x[ix])>PLUMED_GMX_DOUBLE_MIN) {
+   11120             :         absxi = std::abs(x[ix]);
+   11121           0 :         if(*scale<absxi) {
+   11122           0 :           t = *scale/absxi;
+   11123           0 :           t = t*t;
+   11124           0 :           *sumsq = 1.0 + (*sumsq)*t;
+   11125           0 :           *scale = absxi;
+   11126             :         } else {
+   11127           0 :           t = absxi/(*scale);
+   11128           0 :           *sumsq += t*t;
+   11129             :         }
+   11130             :       }
+   11131             :     }
+   11132             :   }
+   11133           0 :   return;
+   11134             : }
+   11135             : }
+   11136             : }
+   11137             : #include <cmath>
+   11138             : #include "lapack.h"
+   11139             : #include "lapack_limits.h"
+   11140             : 
+   11141             : #include "real.h"
+   11142             : 
+   11143             : #include "blas/blas.h"
+   11144             : namespace PLMD{
+   11145             : namespace lapack{
+   11146             : using namespace blas;
+   11147             : void 
+   11148         180 : PLUMED_BLAS_F77_FUNC(dlasv2,DLASV2)(double *f, 
+   11149             :                         double *g, 
+   11150             :                         double *h__, 
+   11151             :                         double *ssmin, 
+   11152             :                         double *ssmax, 
+   11153             :                         double *snr, 
+   11154             :                         double *csr, 
+   11155             :                         double *snl, 
+   11156             :                         double *csl)
+   11157             : {
+   11158             :     double d__1;
+   11159             : 
+   11160             :     double a, d__, l, m, r__, s, t, fa, ga, ha, ft, gt, ht, mm, tt,
+   11161             :              clt, crt, slt, srt;
+   11162             :     int pmax;
+   11163             :     double temp;
+   11164             :     int swap;
+   11165             :     double tsign=1.0;
+   11166             :     int gasmal;
+   11167             : 
+   11168         180 :     ft = *f;
+   11169             :     fa = std::abs(ft);
+   11170         180 :     ht = *h__;
+   11171             :     ha = std::abs(*h__);
+   11172             : 
+   11173             :     pmax = 1;
+   11174             :     swap = ha > fa;
+   11175         180 :     if (swap) {
+   11176             :         pmax = 3;
+   11177             :         temp = ft;
+   11178             :         ft = ht;
+   11179             :         ht = temp;
+   11180             :         temp = fa;
+   11181             :         fa = ha;
+   11182             :         ha = temp;
+   11183             : 
+   11184             :     }
+   11185         180 :     gt = *g;
+   11186             :     ga = std::abs(gt);
+   11187         180 :     if (std::abs(ga)<PLUMED_GMX_DOUBLE_MIN) {
+   11188             : 
+   11189           0 :         *ssmin = ha;
+   11190           0 :         *ssmax = fa;
+   11191             :         clt = 1.;
+   11192             :         crt = 1.;
+   11193             :         slt = 0.;
+   11194             :         srt = 0.;
+   11195             :     } else {
+   11196             :         gasmal = 1;
+   11197         180 :         if (ga > fa) {
+   11198             :             pmax = 2;
+   11199           1 :             if (fa / ga < PLUMED_GMX_DOUBLE_EPS) {
+   11200             : 
+   11201             :                 gasmal = 0;
+   11202           0 :                 *ssmax = ga;
+   11203           0 :                 if (ha > 1.) {
+   11204           0 :                     *ssmin = fa / (ga / ha);
+   11205             :                 } else {
+   11206           0 :                     *ssmin = fa / ga * ha;
+   11207             :                 }
+   11208             :                 clt = 1.;
+   11209           0 :                 slt = ht / gt;
+   11210             :                 srt = 1.;
+   11211           0 :                 crt = ft / gt;
+   11212             :             }
+   11213             :         }
+   11214         180 :         if (gasmal) {
+   11215             : 
+   11216         180 :             d__ = fa - ha;
+   11217         180 :             if ( std::abs( fa - d__ )<PLUMED_GMX_DOUBLE_EPS*std::abs( fa + d__ )) {
+   11218             :                 l = 1.;
+   11219             :             } else {
+   11220         180 :                 l = d__ / fa;
+   11221             :             }
+   11222             : 
+   11223         180 :             m = gt / ft;
+   11224         180 :             t = 2. - l;
+   11225             : 
+   11226         180 :             mm = m * m;
+   11227         180 :             tt = t * t;
+   11228         180 :             s =  std::sqrt(tt + mm);
+   11229             : 
+   11230         180 :             if ( std::abs(l)<PLUMED_GMX_DOUBLE_MIN) {
+   11231             :                 r__ = std::abs(m);
+   11232             :             } else {
+   11233         180 :                 r__ =  std::sqrt(l * l + mm);
+   11234             :             }
+   11235         180 :             a = (s + r__) * .5;
+   11236             : 
+   11237         180 :             *ssmin = ha / a;
+   11238         180 :             *ssmax = fa * a;
+   11239         180 :             if ( std::abs(mm)<PLUMED_GMX_DOUBLE_MIN) {
+   11240             : 
+   11241           0 :                 if (std::abs(l)<PLUMED_GMX_DOUBLE_MIN) {
+   11242           0 :                     t = ( (ft>0) ? 2.0 : -2.0) * ( (gt>0) ? 1.0 : -1.0);
+   11243             :                 } else {
+   11244           0 :                     t = gt / ( (ft>0) ? d__ : -d__) + m / t;
+   11245             :                 }
+   11246             :             } else {
+   11247         180 :                 t = (m / (s + t) + m / (r__ + l)) * (a + 1.);
+   11248             :             }
+   11249         180 :             l =  std::sqrt(t * t + 4.);
+   11250         180 :             crt = 2. / l;
+   11251         180 :             srt = t / l;
+   11252         180 :             clt = (crt + srt * m) / a;
+   11253         180 :             slt = ht / ft * srt / a;
+   11254             :         }
+   11255             :     }
+   11256         180 :     if (swap) {
+   11257          12 :         *csl = srt;
+   11258          12 :         *snl = crt;
+   11259          12 :         *csr = slt;
+   11260          12 :         *snr = clt;
+   11261             :     } else {
+   11262         168 :         *csl = clt;
+   11263         168 :         *snl = slt;
+   11264         168 :         *csr = crt;
+   11265         168 :         *snr = srt;
+   11266             :     }
+   11267             : 
+   11268         180 :     if (pmax == 1) {
+   11269         187 :         tsign = ( (*csr>0) ? 1.0 : -1.0) * ( (*csl>0) ? 1.0 : -1.0) * ( (*f>0) ? 1.0 : -1.0);
+   11270             :     }
+   11271         180 :     if (pmax == 2) {
+   11272           2 :         tsign = ( (*snr>0) ? 1.0 : -1.0) * ( (*csl>0) ? 1.0 : -1.0) * ( (*g>0) ? 1.0 : -1.0);
+   11273             :     }
+   11274         180 :     if (pmax == 3) {
+   11275          16 :         tsign = ( (*snr>0) ? 1.0 : -1.0) * ( (*snl>0) ? 1.0 : -1.0) * ( (*h__>0) ? 1.0 : -1.0);
+   11276             :     }
+   11277         180 :     if(tsign<0)
+   11278          25 :       *ssmax *= -1.0;
+   11279         205 :     d__1 = tsign * ( (*f>0) ? 1.0 : -1.0) * ( (*h__>0) ? 1.0 : -1.0);
+   11280         180 :     if(d__1<0)
+   11281          65 :       *ssmin *= -1.0;
+   11282         180 :     return;
+   11283             : 
+   11284             : }
+   11285             : }
+   11286             : }
+   11287             : #include "lapack.h"
+   11288             : 
+   11289             : /* LAPACK */
+   11290             : #include "blas/blas.h"
+   11291             : namespace PLMD{
+   11292             : namespace lapack{
+   11293             : using namespace blas;
+   11294             : void
+   11295           0 : PLUMED_BLAS_F77_FUNC(dlaswp,DLASWP)(int *n,
+   11296             :         double *a,
+   11297             :         int *lda,
+   11298             :         int *k1,
+   11299             :         int *k2,
+   11300             :         int *ipiv,
+   11301             :         int *incx)
+   11302             : {
+   11303             :   int ix0,i1,i2,inc,n32;
+   11304             :   int ix,i,j,ip,k;
+   11305             :   double temp;
+   11306             : 
+   11307           0 :   if(*incx>0) {
+   11308           0 :     ix0 = *k1 - 1;
+   11309             :     i1 = *k1 - 1;
+   11310           0 :     i2 = *k2;
+   11311             :     inc = 1;
+   11312           0 :   } else if(*incx<0) {
+   11313           0 :     ix0 = *incx * (1- *k2);
+   11314           0 :     i1 = *k2 - 1;
+   11315           0 :     i2 = *k1;
+   11316             :     inc = -1;
+   11317             :   } else
+   11318             :     return;
+   11319             : 
+   11320           0 :   n32 = *n / 32;
+   11321             :   
+   11322           0 :   n32 *= 32;
+   11323             : 
+   11324             : 
+   11325           0 :   if(n32!=0) {
+   11326           0 :     for(j=0;j<n32;j+=32) {
+   11327             :       ix = ix0;
+   11328           0 :       for(i=i1;i<i2;i+=inc,ix+=*incx) {
+   11329           0 :         ip = ipiv[ix] - 1;
+   11330           0 :         if(ip != i) {
+   11331           0 :           for(k=j;k<j+32;k++) {
+   11332           0 :             temp = a[(k)*(*lda)+i];
+   11333           0 :             a[(k)*(*lda)+i] = a[(k)*(*lda)+ip];
+   11334           0 :             a[(k)*(*lda)+ip] = temp;
+   11335             :           }
+   11336             :         }
+   11337             :       }
+   11338             :     }
+   11339             :   }
+   11340           0 :   if(n32!=*n) {
+   11341             :     ix = ix0;
+   11342           0 :     for(i=i1;i<i2;i+=inc,ix+=*incx) {
+   11343           0 :       ip = ipiv[ix] - 1;
+   11344           0 :       if(ip != i) {
+   11345           0 :         for(k=n32;k<*n;k++) {
+   11346           0 :             temp = a[(k)*(*lda)+i];
+   11347           0 :             a[(k)*(*lda)+i] = a[(k)*(*lda)+ip];
+   11348           0 :             a[(k)*(*lda)+ip] = temp;
+   11349             :         }
+   11350             :       }
+   11351             :     }
+   11352             :   }
+   11353             :   return;
+   11354             : }
+   11355             : }
+   11356             : }
+   11357             : #include <cctype>
+   11358             : #include "blas/blas.h"
+   11359             : #include "lapack.h"
+   11360             : #include "lapack_limits.h"
+   11361             : 
+   11362             : 
+   11363             : #include "blas/blas.h"
+   11364             : namespace PLMD{
+   11365             : namespace lapack{
+   11366             : using namespace blas;
+   11367             : void
+   11368          19 : PLUMED_BLAS_F77_FUNC(dlatrd,DLATRD)(const char *  uplo,
+   11369             :        int  *   n,
+   11370             :        int  *   nb,
+   11371             :        double * a,
+   11372             :        int *    lda,
+   11373             :        double * e,
+   11374             :        double * tau,
+   11375             :        double * w,
+   11376             :        int *    ldw)
+   11377             : {
+   11378             :   int i,iw;
+   11379             :   int ti1,ti2,ti3;
+   11380             :   double one,zero,minusone,alpha;
+   11381          19 :   const char ch=std::toupper(*uplo);
+   11382             : 
+   11383          19 :   one=1.0;
+   11384          19 :   minusone=-1.0;
+   11385          19 :   zero=0.0;
+   11386             : 
+   11387          19 :   if(*n<=0)
+   11388             :     return;
+   11389             : 
+   11390          19 :   if(ch=='U') {
+   11391         532 :     for(i=*n;i>=(*n-*nb+1);i--) {
+   11392         513 :       iw = i -*n + *nb;
+   11393             :       
+   11394         513 :       if(i<*n) {
+   11395         494 :         ti1 = *n-i;
+   11396         494 :         ti2 = 1;
+   11397             :         /* BLAS */
+   11398         494 :         PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("N",&i,&ti1,&minusone, &(a[ i*(*lda) + 0]),lda,&(w[iw*(*ldw)+(i-1)]),
+   11399         494 :                ldw,&one, &(a[ (i-1)*(*lda) + 0]), &ti2);
+   11400             :         /* BLAS */
+   11401         494 :         PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("N",&i,&ti1,&minusone, &(w[ iw*(*ldw) + 0]),ldw,&(a[i*(*lda)+(i-1)]),
+   11402         494 :                lda,&one, &(a[ (i-1)*(*lda) + 0]), &ti2);
+   11403             :       }
+   11404             : 
+   11405         513 :       if(i>1) {
+   11406             :         /*  Generate elementary reflector H(i) to annihilate
+   11407             :          *              A(1:i-2,i) 
+   11408             :          */
+   11409         513 :         ti1 = i-1;
+   11410         513 :         ti2 = 1;
+   11411             : 
+   11412             :         /* LAPACK */
+   11413         513 :         PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&ti1,&(a[(i-1)*(*lda)+(i-2)]),&(a[(i-1)*(*lda)+0]),&ti2,&(tau[i-2]));
+   11414             :       
+   11415         513 :         e[i-2] = a[(i-1)*(*lda)+(i-2)];
+   11416         513 :         a[(i-1)*(*lda)+(i-2)] = 1.0;
+   11417             : 
+   11418             :         /* Compute W(1:i-1,i) */
+   11419         513 :         ti1 = i-1;
+   11420         513 :         ti2 = 1;
+   11421             : 
+   11422             :         /* BLAS */
+   11423         513 :         PLUMED_BLAS_F77_FUNC(dsymv,DSYMV)("U",&ti1,&one,a,lda,&(a[(i-1)*(*lda)+0]),&ti2,&zero,
+   11424         513 :                &(w[(iw-1)*(*ldw)+0]),&ti2);
+   11425         513 :         if(i<*n) {
+   11426         494 :           ti1 = i-1;
+   11427         494 :           ti2 = *n-i;
+   11428         494 :           ti3 = 1;
+   11429             :           /* BLAS */
+   11430         494 :           PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("T",&ti1,&ti2,&one,&(w[iw*(*ldw)+0]),ldw,&(a[(i-1)*(*lda)+0]),&ti3,
+   11431         494 :                  &zero,&(w[(iw-1)*(*ldw)+i]),&ti3);
+   11432             :         
+   11433             :           /* BLAS */
+   11434         494 :           PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("N",&ti1,&ti2,&minusone,&(a[i*(*lda)+0]),lda,&(w[(iw-1)*(*ldw)+i]),&ti3,
+   11435         494 :                  &one,&(w[(iw-1)*(*ldw)+0]),&ti3);
+   11436             :         
+   11437             :           /* BLAS */
+   11438         494 :           PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("T",&ti1,&ti2,&one,&(a[i*(*lda)+0]),lda,&(a[(i-1)*(*lda)+0]),&ti3,
+   11439         494 :                  &zero,&(w[(iw-1)*(*ldw)+i]),&ti3);
+   11440             :         
+   11441             :           /* BLAS */
+   11442         494 :           PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("N",&ti1,&ti2,&minusone,&(w[iw*(*ldw)+0]),ldw,&(w[(iw-1)*(*ldw)+i]),&ti3,
+   11443         494 :                  &one,&(w[(iw-1)*(*ldw)+0]),&ti3);
+   11444             :         }
+   11445             :       
+   11446         513 :         ti1 = i-1;
+   11447         513 :         ti2 = 1;
+   11448             :         /* BLAS */
+   11449         513 :         PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&ti1,&(tau[i-2]),&(w[(iw-1)*(*ldw)+0]),&ti2);
+   11450             :       
+   11451        1026 :         alpha = -0.5*tau[i-2]*PLUMED_BLAS_F77_FUNC(ddot,DDOT)(&ti1,&(w[(iw-1)*(*ldw)+0]),&ti2,
+   11452         513 :                                     &(a[(i-1)*(*lda)+0]),&ti2);
+   11453             :       
+   11454             :         /* BLAS */
+   11455         513 :         PLUMED_BLAS_F77_FUNC(daxpy,DAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+0]),&ti2,&(w[(iw-1)*(*ldw)+0]),&ti2);
+   11456             : 
+   11457             :       }
+   11458             :     }
+   11459             :   } else {
+   11460             :     /* lower */
+   11461           0 :     for(i=1;i<=*nb;i++) {
+   11462             : 
+   11463           0 :       ti1 = *n-i+1;
+   11464           0 :       ti2 = i-1;
+   11465           0 :       ti3 = 1;
+   11466             :       /* BLAS */
+   11467           0 :       PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("N",&ti1,&ti2,&minusone, &(a[ i-1 ]),lda,&(w[ i-1 ]),
+   11468           0 :                ldw,&one, &(a[ (i-1)*(*lda) + (i-1)]), &ti3);
+   11469             :       /* BLAS */
+   11470           0 :       PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("N",&ti1,&ti2,&minusone, &(w[ i-1 ]),ldw,&(a[ i-1 ]),
+   11471           0 :                lda,&one, &(a[ (i-1)*(*lda) + (i-1)]), &ti3);
+   11472             : 
+   11473           0 :       if(i<*n) {
+   11474           0 :         ti1 = *n - i;
+   11475           0 :         ti2 = (*n < i+2 ) ? *n : (i+2);
+   11476           0 :         ti3 = 1;
+   11477             :         /* LAPACK */
+   11478           0 :         PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&ti1,&(a[(i-1)*(*lda)+(i)]),&(a[(i-1)*(*lda)+(ti2-1)]),&ti3,&(tau[i-1]));
+   11479           0 :         e[i-1] = a[(i-1)*(*lda)+(i)];
+   11480           0 :         a[(i-1)*(*lda)+(i)] = 1.0;
+   11481             :         
+   11482           0 :         ti1 = *n - i;
+   11483           0 :         ti2 = 1;
+   11484           0 :         PLUMED_BLAS_F77_FUNC(dsymv,DSYMV)("L",&ti1,&one,&(a[i*(*lda)+i]),lda,&(a[(i-1)*(*lda)+i]),&ti2,
+   11485           0 :                &zero,&(w[(i-1)*(*ldw)+i]),&ti2);
+   11486           0 :         ti1 = *n - i;
+   11487           0 :         ti2 = i-1;
+   11488           0 :         ti3 = 1;
+   11489             :         /* BLAS */
+   11490           0 :         PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("T",&ti1,&ti2,&one,&(w[ i ]),ldw,&(a[(i-1)*(*lda)+i]),&ti3,
+   11491           0 :                &zero,&(w[(i-1)*(*ldw)+0]),&ti3);
+   11492             :         
+   11493             :         /* BLAS */
+   11494           0 :         PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("N",&ti1,&ti2,&minusone,&(a[ i ]),lda,&(w[(i-1)*(*ldw)+0]),&ti3,
+   11495           0 :                &one,&(w[(i-1)*(*ldw)+i]),&ti3);
+   11496             :         
+   11497             :         /* BLAS */
+   11498           0 :         PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("T",&ti1,&ti2,&one,&(a[ i ]),lda,&(a[(i-1)*(*lda)+i]),&ti3,
+   11499           0 :                &zero,&(w[(i-1)*(*ldw)+0]),&ti3);
+   11500             :         
+   11501             :         /* BLAS */
+   11502           0 :         PLUMED_BLAS_F77_FUNC(dgemv,DGEMV)("N",&ti1,&ti2,&minusone,&(w[ i ]),ldw,&(w[(i-1)*(*ldw)+0]),&ti3,
+   11503           0 :                &one,&(w[(i-1)*(*ldw)+i]),&ti3);
+   11504             : 
+   11505           0 :         PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&ti1,&(tau[i-1]),&(w[(i-1)*(*ldw)+i]),&ti3);
+   11506           0 :         alpha = -0.5*tau[i-1]*PLUMED_BLAS_F77_FUNC(ddot,DDOT)(&ti1,&(w[(i-1)*(*ldw)+i]),&ti3,
+   11507           0 :                                    &(a[(i-1)*(*lda)+i]),&ti3);
+   11508             :         
+   11509           0 :         PLUMED_BLAS_F77_FUNC(daxpy,DAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+i]),&ti3,&(w[(i-1)*(*ldw)+i]),&ti3);
+   11510             :       }
+   11511             :     }
+   11512             :   }
+   11513             :   return;
+   11514             : }
+   11515             :         
+   11516             : 
+   11517             : 
+   11518             :   
+   11519             : }
+   11520             : }
+   11521             : #include <cmath>
+   11522             : 
+   11523             : #include "blas/blas.h"
+   11524             : #include "lapack.h"
+   11525             : 
+   11526             : #include "blas/blas.h"
+   11527             : namespace PLMD{
+   11528             : namespace lapack{
+   11529             : using namespace blas;
+   11530             : void 
+   11531           1 : PLUMED_BLAS_F77_FUNC(dorg2r,DORG2R)(int *m, 
+   11532             :                         int *n,
+   11533             :                         int *k, 
+   11534             :                         double *a, 
+   11535             :                         int *lda,
+   11536             :                         double *tau,
+   11537             :                         double *work,
+   11538             :                         int *info)
+   11539             : {
+   11540             :     int a_dim1, a_offset, i__1, i__2;
+   11541             :     double r__1;
+   11542           1 :     int c__1 = 1;
+   11543             : 
+   11544             :     int i__, j, l;
+   11545             : 
+   11546           1 :     a_dim1 = *lda;
+   11547           1 :     a_offset = 1 + a_dim1;
+   11548           1 :     a -= a_offset;
+   11549           1 :     --tau;
+   11550             :     --work;
+   11551             : 
+   11552           1 :     *info = 0;
+   11553             : 
+   11554           1 :     if (*n <= 0) {
+   11555             :         return;
+   11556             :     }
+   11557             : 
+   11558           1 :     i__1 = *n;
+   11559           2 :     for (j = *k + 1; j <= i__1; ++j) {
+   11560           1 :         i__2 = *m;
+   11561           4 :         for (l = 1; l <= i__2; ++l) {
+   11562           3 :             a[l + j * a_dim1] = 0.0;
+   11563             :         }
+   11564           1 :         a[j + j * a_dim1] = 1.0;
+   11565             :     }
+   11566           3 :     for (i__ = *k; i__ >= 1; --i__) {
+   11567           2 :         if (i__ < *n) {
+   11568           2 :             a[i__ + i__ * a_dim1] = 1.0;
+   11569           2 :             i__1 = *m - i__ + 1;
+   11570           2 :             i__2 = *n - i__;
+   11571           2 :             PLUMED_BLAS_F77_FUNC(dlarf,DLARF)("L", &i__1, &i__2, &a[i__ + i__ * a_dim1], &c__1, 
+   11572           2 :                               &tau[i__], &a[i__ + (i__ + 1) * a_dim1], lda, &work[1]);
+   11573             :         }
+   11574           2 :         if (i__ < *m) {
+   11575           2 :             i__1 = *m - i__;
+   11576           2 :             r__1 = -tau[i__];
+   11577           2 :             PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__1, &r__1, &a[i__ + 1 + i__ * a_dim1], &c__1);
+   11578             :         }
+   11579           2 :         a[i__ + i__ * a_dim1] = 1.0 - tau[i__];
+   11580           2 :         i__1 = i__ - 1;
+   11581           3 :         for (l = 1; l <= i__1; ++l) {
+   11582           1 :             a[l + i__ * a_dim1] = 0.0;
+   11583             :         }
+   11584             :     }
+   11585             :     return;
+   11586             : 
+   11587             : }
+   11588             : 
+   11589             : 
+   11590             : }
+   11591             : }
+   11592             : #include "lapack.h"
+   11593             : #include "lapack_limits.h"
+   11594             : 
+   11595             : #include "blas/blas.h"
+   11596             : namespace PLMD{
+   11597             : namespace lapack{
+   11598             : using namespace blas;
+   11599             : void
+   11600           0 : PLUMED_BLAS_F77_FUNC(dorgbr,DORGBR)(const char *vect,
+   11601             :         int *m,
+   11602             :         int *n,
+   11603             :         int *k,
+   11604             :         double *a,
+   11605             :         int *lda,
+   11606             :         double *tau,
+   11607             :         double *work,
+   11608             :         int *lwork,
+   11609             :         int *info)
+   11610             : {
+   11611             :   int wantq,iinfo,j,i,i1,wrksz;
+   11612           0 :   int mn = (*m < *n) ? *m : *n;
+   11613             : 
+   11614           0 :   wantq = (*vect=='Q' || *vect=='q');
+   11615             : 
+   11616           0 :   *info = 0;
+   11617           0 :   wrksz = mn*DORGBR_BLOCKSIZE;
+   11618           0 :   if(*lwork==-1) {
+   11619           0 :     work[0] = wrksz;
+   11620           0 :     return;
+   11621             :   }
+   11622             :   
+   11623           0 :   if(*m==0 || *n==0)
+   11624             :     return;
+   11625             : 
+   11626           0 :   if(wantq) {
+   11627           0 :     if(*m>=*k)
+   11628           0 :       PLUMED_BLAS_F77_FUNC(dorgqr,DORGQR)(m,n,k,a,lda,tau,work,lwork,&iinfo);
+   11629             :     else {
+   11630           0 :       for(j=*m;j>=2;j--) {
+   11631           0 :         a[(j-1)*(*lda)+0] = 0.0;
+   11632           0 :         for(i=j+1;i<=*m;i++)
+   11633           0 :           a[(j-1)*(*lda)+(i-1)] = a[(j-2)*(*lda)+(i-1)]; 
+   11634             :       }
+   11635           0 :       a[0] = 1.0;
+   11636           0 :       for(i=2;i<=*m;i++)
+   11637           0 :         a[i-1] = 0.0;
+   11638           0 :       if(*m>1) {
+   11639           0 :         i1 = *m-1;
+   11640           0 :         PLUMED_BLAS_F77_FUNC(dorgqr,DORGQR)(&i1,&i1,&i1,&(a[*lda+1]),lda,tau,work,lwork,&iinfo);
+   11641             :       }
+   11642             :     }
+   11643             :   } else {
+   11644           0 :     if(*k<*n)
+   11645           0 :       PLUMED_BLAS_F77_FUNC(dorglq,DORGLQ)(m,n,k,a,lda,tau,work,lwork,&iinfo);
+   11646             :     else {
+   11647           0 :       a[0] = 1.0;
+   11648           0 :       for(i=2;i<=*m;i++)
+   11649           0 :         a[i-1] = 0.0;
+   11650           0 :       for(j=2;j<=*n;j++) {
+   11651           0 :         for(i=j-1;i>=2;i--)
+   11652           0 :           a[(j-1)*(*lda)+(i-1)] = a[(j-1)*(*lda)+(i-2)]; 
+   11653           0 :         a[(j-1)*(*lda)+0] = 0.0;
+   11654             :       }
+   11655           0 :       if(*n>1) {
+   11656           0 :         i1 = *n-1;
+   11657           0 :         PLUMED_BLAS_F77_FUNC(dorglq,DORGLQ)(&i1,&i1,&i1,&(a[*lda+1]),lda,tau,work,lwork,&iinfo);
+   11658             :       }
+   11659             :     }
+   11660             :   }
+   11661           0 :   work[0] = wrksz;
+   11662           0 :   return;
+   11663             : }
+   11664             :  
+   11665             : }
+   11666             : }
+   11667             : #include "blas/blas.h"
+   11668             : #include "lapack.h"
+   11669             : 
+   11670             : #include "blas/blas.h"
+   11671             : namespace PLMD{
+   11672             : namespace lapack{
+   11673             : using namespace blas;
+   11674             : void
+   11675           0 : PLUMED_BLAS_F77_FUNC(dorgl2,DORGL2)(int *m,
+   11676             :                         int *n, 
+   11677             :                         int *k, 
+   11678             :                         double *a, 
+   11679             :                         int *lda, 
+   11680             :                         double *tau, 
+   11681             :                         double *work, 
+   11682             :                         int *info)
+   11683             : {
+   11684             :     int a_dim1, a_offset, i__1, i__2;
+   11685             :     double r__1;
+   11686             : 
+   11687             :     int i__, j, l;
+   11688             : 
+   11689           0 :     a_dim1 = *lda;
+   11690           0 :     a_offset = 1 + a_dim1;
+   11691           0 :     a -= a_offset;
+   11692           0 :     --tau;
+   11693             :     --work;
+   11694             : 
+   11695           0 :     i__ = (*m > 1) ? *m : 1;
+   11696             :     
+   11697           0 :     *info = 0;
+   11698           0 :     if (*m < 0) {
+   11699           0 :         *info = -1;
+   11700           0 :     } else if (*n < *m) {
+   11701           0 :         *info = -2;
+   11702           0 :     } else if (*k < 0 || *k > *m) {
+   11703           0 :         *info = -3;
+   11704           0 :     } else if (*lda < i__) {
+   11705           0 :         *info = -5;
+   11706             :     }
+   11707           0 :     if (*info != 0) {
+   11708             :         return;
+   11709             :     }
+   11710           0 :     if (*m <= 0) {
+   11711             :         return;
+   11712             :     }
+   11713             : 
+   11714           0 :     if (*k < *m) {
+   11715           0 :         i__1 = *n;
+   11716           0 :         for (j = 1; j <= i__1; ++j) {
+   11717           0 :             i__2 = *m;
+   11718           0 :             for (l = *k + 1; l <= i__2; ++l) {
+   11719           0 :                 a[l + j * a_dim1] = 0.0;
+   11720             :             }
+   11721           0 :             if (j > *k && j <= *m) {
+   11722           0 :                 a[j + j * a_dim1] = 1.0;
+   11723             :             }
+   11724             :         }
+   11725             :     }
+   11726             : 
+   11727           0 :     for (i__ = *k; i__ >= 1; --i__) {
+   11728           0 :         if (i__ < *n) {
+   11729           0 :             if (i__ < *m) {
+   11730           0 :                 a[i__ + i__ * a_dim1] = 1.0;
+   11731           0 :                 i__1 = *m - i__;
+   11732           0 :                 i__2 = *n - i__ + 1;
+   11733           0 :                 PLUMED_BLAS_F77_FUNC(dlarf,DLARF)("R", &i__1, &i__2, &a[i__ + i__ * a_dim1], lda, 
+   11734           0 :                &tau[i__], &a[i__ + 1 + i__ * a_dim1], lda, &work[1]);
+   11735             :             }
+   11736           0 :             i__1 = *n - i__;
+   11737           0 :             r__1 = -tau[i__];
+   11738           0 :             PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__1, &r__1, &a[i__ + (i__ + 1) * a_dim1], lda);
+   11739             :         }
+   11740           0 :         a[i__ + i__ * a_dim1] = 1.0 - tau[i__];
+   11741           0 :         i__1 = i__ - 1;
+   11742           0 :         for (l = 1; l <= i__1; ++l) {
+   11743           0 :             a[i__ + l * a_dim1] = 0.0;
+   11744             :         }
+   11745             :     }
+   11746             :     return;
+   11747             : 
+   11748             : }
+   11749             : 
+   11750             : 
+   11751             : 
+   11752             : }
+   11753             : }
+   11754             : #include "lapack.h"
+   11755             : 
+   11756             : #define DORGLQ_BLOCKSIZE    32
+   11757             : #define DORGLQ_MINBLOCKSIZE 2
+   11758             : #define DORGLQ_CROSSOVER    128
+   11759             : 
+   11760             : 
+   11761             : #include "blas/blas.h"
+   11762             : namespace PLMD{
+   11763             : namespace lapack{
+   11764             : using namespace blas;
+   11765             : void 
+   11766           0 : PLUMED_BLAS_F77_FUNC(dorglq,DORGLQ)(int *m, 
+   11767             :         int *n, 
+   11768             :         int *k, 
+   11769             :         double *a, 
+   11770             :         int *lda, 
+   11771             :         double *tau, 
+   11772             :         double *work, 
+   11773             :         int *lwork, 
+   11774             :         int *info)
+   11775             : {
+   11776             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   11777             : 
+   11778             :     int i__, j, l, ib, nb, ki, kk, nx, iws, nbmin, iinfo;
+   11779             : 
+   11780             :     int ldwork, lwkopt;
+   11781             :     int lquery;
+   11782             :     
+   11783           0 :     a_dim1 = *lda;
+   11784           0 :     a_offset = 1 + a_dim1;
+   11785           0 :     a -= a_offset;
+   11786           0 :     --tau;
+   11787             :     --work;
+   11788             : 
+   11789           0 :     *info = 0;
+   11790             :     ki = 0;
+   11791             :     nb = DORGLQ_BLOCKSIZE;
+   11792           0 :     lwkopt = (*m) * nb;
+   11793           0 :     work[1] = (double) lwkopt;
+   11794           0 :     lquery = *lwork == -1;
+   11795           0 :     if (*m < 0) {
+   11796           0 :         *info = -1;
+   11797           0 :     } else if (*n < *m) {
+   11798           0 :         *info = -2;
+   11799           0 :     } else if (*k < 0 || *k > *m) {
+   11800           0 :         *info = -3;
+   11801           0 :     } else if (*lda < (*m)) {
+   11802           0 :         *info = -5;
+   11803           0 :     } else if (*lwork < (*m) && ! lquery) {
+   11804           0 :         *info = -8;
+   11805             :     }
+   11806           0 :     if (*info != 0) {
+   11807             :         i__1 = -(*info);
+   11808             :         return;
+   11809           0 :     } else if (lquery) {
+   11810             :         return;
+   11811             :     }
+   11812             : 
+   11813           0 :     if (*m <= 0) {
+   11814           0 :         work[1] = 1.;
+   11815           0 :         return;
+   11816             :     }
+   11817             : 
+   11818             :     nbmin = 2;
+   11819             :     nx = 0;
+   11820             :     iws = *m;
+   11821           0 :     if (nb > 1 && nb < *k) {
+   11822             : 
+   11823             :         nx = DORGLQ_CROSSOVER;
+   11824           0 :         if (nx < *k) {
+   11825             : 
+   11826           0 :             ldwork = *m;
+   11827           0 :             iws = ldwork * nb;
+   11828           0 :             if (*lwork < iws) {
+   11829             : 
+   11830           0 :                 nb = *lwork / ldwork;
+   11831             :                 nbmin = DORGLQ_MINBLOCKSIZE;
+   11832             :             }
+   11833             :         }
+   11834             :     }
+   11835             : 
+   11836           0 :     if (nb >= nbmin && nb < *k && nx < *k) {
+   11837             : 
+   11838           0 :         ki = (*k - nx - 1) / nb * nb;
+   11839           0 :         i__1 = *k, i__2 = ki + nb;
+   11840             :         kk = (i__1<i__2) ? i__1 : i__2;
+   11841             : 
+   11842           0 :         i__1 = kk;
+   11843           0 :         for (j = 1; j <= i__1; ++j) {
+   11844           0 :             i__2 = *m;
+   11845           0 :             for (i__ = kk + 1; i__ <= i__2; ++i__) {
+   11846           0 :                 a[i__ + j * a_dim1] = 0.;
+   11847             :             }
+   11848             :         }
+   11849             :     } else {
+   11850             :         kk = 0;
+   11851             :     }
+   11852           0 :     if (kk < *m) {
+   11853           0 :         i__1 = *m - kk;
+   11854           0 :         i__2 = *n - kk;
+   11855           0 :         i__3 = *k - kk;
+   11856           0 :         PLUMED_BLAS_F77_FUNC(dorgl2,DORGL2)(&i__1, &i__2, &i__3, &a[kk + 1 + (kk + 1) * a_dim1], lda, &
+   11857           0 :                 tau[kk + 1], &work[1], &iinfo);
+   11858             :     }
+   11859             : 
+   11860           0 :     if (kk > 0) {
+   11861             : 
+   11862           0 :         i__1 = -nb;
+   11863           0 :         for (i__ = ki + 1; i__1 < 0 ? i__ >= 1 : i__ <= 1; i__ += i__1) {
+   11864           0 :             i__2 = nb, i__3 = *k - i__ + 1;
+   11865           0 :             ib = (i__2<i__3) ? i__2 : i__3;
+   11866           0 :             if (i__ + ib <= *m) {
+   11867             : 
+   11868           0 :                 i__2 = *n - i__ + 1;
+   11869           0 :                 PLUMED_BLAS_F77_FUNC(dlarft,DLARFT)("Forward", "Rowwise", &i__2, &ib, &a[i__ + i__ * 
+   11870           0 :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   11871             : 
+   11872           0 :                 i__2 = *m - i__ - ib + 1;
+   11873           0 :                 i__3 = *n - i__ + 1;
+   11874           0 :                 PLUMED_BLAS_F77_FUNC(dlarfb,DLARFB)("Right", "Transpose", "Forward", "Rowwise", &i__2, &
+   11875             :                         i__3, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+   11876           0 :                         ldwork, &a[i__ + ib + i__ * a_dim1], lda, &work[ib + 
+   11877           0 :                         1], &ldwork);
+   11878             :             }
+   11879             : 
+   11880           0 :             i__2 = *n - i__ + 1;
+   11881           0 :             PLUMED_BLAS_F77_FUNC(dorgl2,DORGL2)(&ib, &i__2, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &
+   11882             :                     work[1], &iinfo);
+   11883             : 
+   11884           0 :             i__2 = i__ - 1;
+   11885           0 :             for (j = 1; j <= i__2; ++j) {
+   11886           0 :                 i__3 = i__ + ib - 1;
+   11887           0 :                 for (l = i__; l <= i__3; ++l) {
+   11888           0 :                     a[l + j * a_dim1] = 0.;
+   11889             :                 }
+   11890             :             }
+   11891             :         }
+   11892             :     }
+   11893             : 
+   11894           0 :     work[1] = (double) iws;
+   11895           0 :     return;
+   11896             : 
+   11897             : }
+   11898             : 
+   11899             : 
+   11900             : }
+   11901             : }
+   11902             : #include "lapack.h"
+   11903             : #include "lapack_limits.h"
+   11904             : 
+   11905             : 
+   11906             : #include "blas/blas.h"
+   11907             : namespace PLMD{
+   11908             : namespace lapack{
+   11909             : using namespace blas;
+   11910             : void 
+   11911           1 : PLUMED_BLAS_F77_FUNC(dorgqr,DORGQR)(int *m, 
+   11912             :         int *n, 
+   11913             :         int *k, 
+   11914             :         double *a, 
+   11915             :         int *lda, 
+   11916             :         double *tau, 
+   11917             :         double *work, 
+   11918             :         int *lwork, 
+   11919             :         int *info)
+   11920             : {
+   11921             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   11922             : 
+   11923             :     int i__, j, l, ib, nb, ki, kk, nx, iws, nbmin, iinfo;
+   11924             :     int ldwork, lwkopt;
+   11925             :     int lquery;
+   11926             :  
+   11927           1 :     a_dim1 = *lda;
+   11928           1 :     a_offset = 1 + a_dim1;
+   11929           1 :     a -= a_offset;
+   11930           1 :     --tau;
+   11931             :     --work;
+   11932             : 
+   11933             :     ki = 0;
+   11934           1 :     *info = 0;
+   11935             :     nb = DORGQR_BLOCKSIZE;
+   11936           1 :     lwkopt = (*n) * nb;
+   11937           1 :     work[1] = (double) lwkopt;
+   11938           1 :     lquery = *lwork == -1;
+   11939           1 :     if (*m < 0) {
+   11940           0 :         *info = -1;
+   11941           1 :     } else if (*n < 0 || *n > *m) {
+   11942           0 :         *info = -2;
+   11943           1 :     } else if (*k < 0 || *k > *n) {
+   11944           0 :         *info = -3;
+   11945           1 :     } else if (*lda < (*m)) {
+   11946           0 :         *info = -5;
+   11947           1 :     } else if (*lwork < (*n) && ! lquery) {
+   11948           0 :         *info = -8;
+   11949             :     }
+   11950           1 :     if (*info != 0) {
+   11951             :         i__1 = -(*info);
+   11952             :         return;
+   11953           1 :     } else if (lquery) {
+   11954             :         return;
+   11955             :     }
+   11956             : 
+   11957           1 :     if (*n <= 0) {
+   11958           0 :         work[1] = 1.;
+   11959           0 :         return;
+   11960             :     }
+   11961             : 
+   11962             :     nbmin = 2;
+   11963             :     nx = 0;
+   11964             :     iws = *n;
+   11965           1 :     if (nb > 1 && nb < *k) {
+   11966             : 
+   11967             :         nx = DORGQR_CROSSOVER;
+   11968           0 :         if (nx < *k) {
+   11969             : 
+   11970           0 :             ldwork = *n;
+   11971           0 :             iws = ldwork * nb;
+   11972           0 :             if (*lwork < iws) {
+   11973             : 
+   11974           0 :                 nb = *lwork / ldwork;
+   11975             :                 nbmin = DORGQR_MINBLOCKSIZE;
+   11976             :             }
+   11977             :         }
+   11978             :     }
+   11979             : 
+   11980           1 :     if (nb >= nbmin && nb < *k && nx < *k) {
+   11981             : 
+   11982           0 :         ki = (*k - nx - 1) / nb * nb;
+   11983           0 :         i__1 = *k, i__2 = ki + nb;
+   11984             :         kk = (i__1<i__2) ? i__1 : i__2;
+   11985             : 
+   11986           0 :         i__1 = *n;
+   11987           0 :         for (j = kk + 1; j <= i__1; ++j) {
+   11988           0 :             i__2 = kk;
+   11989           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   11990           0 :                 a[i__ + j * a_dim1] = 0.;
+   11991             :             }
+   11992             :         }
+   11993             :     } else {
+   11994             :         kk = 0;
+   11995             :     }
+   11996             : 
+   11997           1 :     if (kk < *n) {
+   11998           1 :         i__1 = *m - kk;
+   11999           1 :         i__2 = *n - kk;
+   12000           1 :         i__3 = *k - kk;
+   12001           1 :         PLUMED_BLAS_F77_FUNC(dorg2r,DORG2R)(&i__1, &i__2, &i__3, &a[kk + 1 + (kk + 1) * a_dim1], lda, &
+   12002           1 :                 tau[kk + 1], &work[1], &iinfo);
+   12003             :     }
+   12004             : 
+   12005           1 :     if (kk > 0) {
+   12006             : 
+   12007           0 :         i__1 = -nb;
+   12008           0 :         for (i__ = ki + 1; i__1 < 0 ? i__ >= 1 : i__ <= 1; i__ += i__1) {
+   12009           0 :             i__2 = nb, i__3 = *k - i__ + 1;
+   12010           0 :             ib = (i__2<i__3) ? i__2 : i__3;
+   12011           0 :             if (i__ + ib <= *n) {
+   12012             : 
+   12013           0 :                 i__2 = *m - i__ + 1;
+   12014           0 :                 PLUMED_BLAS_F77_FUNC(dlarft,DLARFT)("Forward", "Columnwise", &i__2, &ib, &a[i__ + i__ * 
+   12015           0 :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   12016             : 
+   12017           0 :                 i__2 = *m - i__ + 1;
+   12018           0 :                 i__3 = *n - i__ - ib + 1;
+   12019           0 :                 PLUMED_BLAS_F77_FUNC(dlarfb,DLARFB)("Left", "No transpose", "Forward", "Columnwise", &
+   12020             :                         i__2, &i__3, &ib, &a[i__ + i__ * a_dim1], lda, &work[
+   12021           0 :                         1], &ldwork, &a[i__ + (i__ + ib) * a_dim1], lda, &
+   12022           0 :                         work[ib + 1], &ldwork);
+   12023             :             }
+   12024             : 
+   12025           0 :             i__2 = *m - i__ + 1;
+   12026           0 :             PLUMED_BLAS_F77_FUNC(dorg2r,DORG2R)(&i__2, &ib, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &
+   12027             :                     work[1], &iinfo);
+   12028             : 
+   12029           0 :             i__2 = i__ + ib - 1;
+   12030           0 :             for (j = i__; j <= i__2; ++j) {
+   12031           0 :                 i__3 = i__ - 1;
+   12032           0 :                 for (l = 1; l <= i__3; ++l) {
+   12033           0 :                     a[l + j * a_dim1] = 0.;
+   12034             :                 }
+   12035             :             }
+   12036             :         }
+   12037             :     }
+   12038             : 
+   12039           1 :     work[1] = (double) iws;
+   12040           1 :     return;
+   12041             : 
+   12042             : } 
+   12043             : }
+   12044             : }
+   12045             : #include "lapack.h"
+   12046             : 
+   12047             : #include "blas/blas.h"
+   12048             : namespace PLMD{
+   12049             : namespace lapack{
+   12050             : using namespace blas;
+   12051             : void
+   12052      569949 : PLUMED_BLAS_F77_FUNC(dorm2l,DORM2L)(const char *side, 
+   12053             :         const char *trans, 
+   12054             :         int *m, 
+   12055             :         int *n, 
+   12056             :         int *k, 
+   12057             :         double *a,
+   12058             :         int *lda, 
+   12059             :         double *tau,
+   12060             :         double *c__,
+   12061             :         int *ldc, 
+   12062             :         double *work, 
+   12063             :         int *info)
+   12064             : {
+   12065             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2;
+   12066      569949 :     int c__1 = 1;
+   12067             : 
+   12068             :     int i__, i1, i2, i3, mi, ni, nq;
+   12069             :     double aii;
+   12070             :     int left;
+   12071             :     int notran;
+   12072             : 
+   12073      569949 :     a_dim1 = *lda;
+   12074      569949 :     a_offset = 1 + a_dim1;
+   12075      569949 :     a -= a_offset;
+   12076             :     --tau;
+   12077             :     c_dim1 = *ldc;
+   12078             :     c_offset = 1 + c_dim1;
+   12079             :     c__ -= c_offset;
+   12080             :     --work;
+   12081             : 
+   12082             :     /* Function Body */
+   12083      569949 :     *info = 0;
+   12084      569949 :     left = (*side=='L' || *side=='l');
+   12085      569949 :     notran = (*trans=='N' || *trans=='n');
+   12086             : 
+   12087      569949 :     if (left) {
+   12088      569949 :         nq = *m;
+   12089             :     } else {
+   12090           0 :         nq = *n;
+   12091             :     }
+   12092             :     if (*info != 0) {
+   12093             :         return;
+   12094             :     }
+   12095             : 
+   12096      569949 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12097             :         return;
+   12098             :     }
+   12099             : 
+   12100      569949 :     if ((left && notran) || (! left && ! notran)) {
+   12101             :         i1 = 1;
+   12102             :         i2 = *k;
+   12103             :         i3 = 1;
+   12104             :     } else {
+   12105             :         i1 = *k;
+   12106             :         i2 = 1;
+   12107             :         i3 = -1;
+   12108             :     }
+   12109             : 
+   12110      569949 :     if (left) {
+   12111      569949 :         ni = *n;
+   12112             :     } else {
+   12113           0 :         mi = *m;
+   12114             :     }
+   12115             : 
+   12116             :     i__1 = i2;
+   12117             :     i__2 = i3;
+   12118     2252669 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   12119     1682720 :         if (left) {
+   12120             : 
+   12121     1682720 :             mi = *m - *k + i__;
+   12122             :         } else {
+   12123             : 
+   12124           0 :             ni = *n - *k + i__;
+   12125             :         }
+   12126             : 
+   12127     1682720 :         aii = a[nq - *k + i__ + i__ * a_dim1];
+   12128     1682720 :         a[nq - *k + i__ + i__ * a_dim1] = 1.;
+   12129     1682720 :         PLUMED_BLAS_F77_FUNC(dlarf,DLARF)(side, &mi, &ni, &a[i__ * a_dim1 + 1], &c__1, &tau[i__], &c__[
+   12130             :                 c_offset], ldc, &work[1]);
+   12131     1682720 :         a[nq - *k + i__ + i__ * a_dim1] = aii;
+   12132             :     }
+   12133             :     return;
+   12134             : }
+   12135             : }
+   12136             : }
+   12137             : #include "lapack.h"
+   12138             : 
+   12139             : #include "blas/blas.h"
+   12140             : namespace PLMD{
+   12141             : namespace lapack{
+   12142             : using namespace blas;
+   12143             : void 
+   12144          79 : PLUMED_BLAS_F77_FUNC(dorm2r,DORM2R)(const char *side, 
+   12145             :         const char *trans, 
+   12146             :         int *m, 
+   12147             :         int *n, 
+   12148             :         int *k, 
+   12149             :         double *a, 
+   12150             :         int *lda, 
+   12151             :         double *tau, 
+   12152             :         double *c__, 
+   12153             :         int *ldc, 
+   12154             :         double *work, 
+   12155             :         int *info)
+   12156             : {
+   12157             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2;
+   12158             : 
+   12159             :     int i__, i1, i2, i3, ic, jc, mi, ni;
+   12160             :     double aii;
+   12161             :     int left;
+   12162             :     int notran;
+   12163          79 :     int c__1 = 1;
+   12164             : 
+   12165          79 :     a_dim1 = *lda;
+   12166          79 :     a_offset = 1 + a_dim1;
+   12167          79 :     a -= a_offset;
+   12168             :     --tau;
+   12169          79 :     c_dim1 = *ldc;
+   12170          79 :     c_offset = 1 + c_dim1;
+   12171          79 :     c__ -= c_offset;
+   12172             :     --work;
+   12173          79 :     *info = 0;
+   12174          79 :     left = (*side=='L' || *side=='l');
+   12175          79 :     notran = (*trans=='N' || *trans=='n');
+   12176             : 
+   12177             :     ic = jc = 0;
+   12178             : 
+   12179          79 :     if (*m <= 0 || *n <= 0 || *k <= 0) {
+   12180             :         return;
+   12181             :     }
+   12182             : 
+   12183          79 :     if ((left && !notran) || (!left && notran)) {
+   12184             :         i1 = 1;
+   12185             :         i2 = *k;
+   12186             :         i3 = 1;
+   12187             :     } else {
+   12188             :         i1 = *k;
+   12189             :         i2 = 1;
+   12190             :         i3 = -1;
+   12191             :     }
+   12192             : 
+   12193          79 :     if (left) {
+   12194          79 :         ni = *n;
+   12195             :         jc = 1;
+   12196             :     } else {
+   12197           0 :         mi = *m;
+   12198             :         ic = 1;
+   12199             :     }
+   12200             : 
+   12201             :     i__1 = i2;
+   12202             :     i__2 = i3;
+   12203        1547 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   12204        1468 :         if (left) {
+   12205             : 
+   12206        1468 :             mi = *m - i__ + 1;
+   12207             :             ic = i__;
+   12208             :         } else {
+   12209             : 
+   12210           0 :             ni = *n - i__ + 1;
+   12211             :             jc = i__;
+   12212             :         }
+   12213             : 
+   12214             : 
+   12215        1468 :         aii = a[i__ + i__ * a_dim1];
+   12216        1468 :         a[i__ + i__ * a_dim1] = 1.;
+   12217        1468 :         PLUMED_BLAS_F77_FUNC(dlarf,DLARF)(side, &mi, &ni, &a[i__ + i__ * a_dim1], &c__1, &tau[i__], &c__[
+   12218        1468 :                 ic + jc * c_dim1], ldc, &work[1]);
+   12219        1468 :         a[i__ + i__ * a_dim1] = aii;
+   12220             :     }
+   12221             :     return;
+   12222             : 
+   12223             : } 
+   12224             : }
+   12225             : }
+   12226             : #include "lapack.h"
+   12227             : #include "lapack_limits.h"
+   12228             : 
+   12229             : #include "blas/blas.h"
+   12230             : namespace PLMD{
+   12231             : namespace lapack{
+   12232             : using namespace blas;
+   12233             : void 
+   12234         192 : PLUMED_BLAS_F77_FUNC(dormbr,DORMBR)(const char *vect, 
+   12235             :         const char *side, 
+   12236             :         const char *trans, 
+   12237             :         int *m, 
+   12238             :         int *n, 
+   12239             :         int *k, 
+   12240             :         double *a, 
+   12241             :         int *lda, 
+   12242             :         double *tau, 
+   12243             :         double *c__, 
+   12244             :         int *ldc, 
+   12245             :         double *work, 
+   12246             :         int *lwork, 
+   12247             :         int *info)
+   12248             : {
+   12249             :     int a_dim1, a_offset, c_dim1, c_offset, i__1;
+   12250             :  
+   12251             : 
+   12252             :     int i1, i2, nb, mi, ni, nq, nw;
+   12253             :     int left;
+   12254             :     int iinfo;
+   12255             :     int notran;
+   12256             :     int applyq;
+   12257             :     char transt[1];
+   12258             :     int lwkopt;
+   12259             :     int lquery;
+   12260             : 
+   12261         192 :     a_dim1 = *lda;
+   12262         192 :     a_offset = 1 + a_dim1;
+   12263         192 :     a -= a_offset;
+   12264             :     --tau;
+   12265         192 :     c_dim1 = *ldc;
+   12266         192 :     c_offset = 1 + c_dim1;
+   12267         192 :     c__ -= c_offset;
+   12268             :     --work;
+   12269         192 :     *info = 0;
+   12270         192 :     applyq = (*vect=='Q' || *vect=='q');
+   12271         192 :     left = (*side=='L' || *side=='l');
+   12272         192 :     notran = (*trans=='N' || *trans=='n');
+   12273         192 :     lquery = *lwork == -1;
+   12274             : 
+   12275         192 :     if (left) {
+   12276          96 :         nq = *m;
+   12277          96 :         nw = *n;
+   12278             :     } else {
+   12279          96 :         nq = *n;
+   12280          96 :         nw = *m;
+   12281             :     }
+   12282             : 
+   12283             :     nb = DORMQR_BLOCKSIZE;
+   12284         192 :     lwkopt = nw * nb;
+   12285         192 :     work[1] = (double) lwkopt;
+   12286             :     
+   12287         192 :     if (*info != 0) {
+   12288             :         i__1 = -(*info);
+   12289             :         return;
+   12290         192 :     } else if (lquery) {
+   12291             :         return;
+   12292             :     }
+   12293             : 
+   12294         192 :     work[1] = 1.;
+   12295         192 :     if (*m == 0 || *n == 0) {
+   12296             :         return;
+   12297             :     }
+   12298             : 
+   12299         192 :     if (applyq) {
+   12300             : 
+   12301          96 :         if (nq >= *k) {
+   12302             : 
+   12303          96 :             PLUMED_BLAS_F77_FUNC(dormqr,DORMQR)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   12304             :                     c_offset], ldc, &work[1], lwork, &iinfo);
+   12305           0 :         } else if (nq > 1) {
+   12306             : 
+   12307           0 :             if (left) {
+   12308           0 :                 mi = *m - 1;
+   12309           0 :                 ni = *n;
+   12310             :                 i1 = 2;
+   12311             :                 i2 = 1;
+   12312             :             } else {
+   12313           0 :                 mi = *m;
+   12314           0 :                 ni = *n - 1;
+   12315             :                 i1 = 1;
+   12316             :                 i2 = 2;
+   12317             :             }
+   12318           0 :             i__1 = nq - 1;
+   12319           0 :             PLUMED_BLAS_F77_FUNC(dormqr,DORMQR)(side, trans, &mi, &ni, &i__1, &a[a_dim1 + 2], lda, &tau[1]
+   12320           0 :                     , &c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &iinfo);
+   12321             :         }
+   12322             :     } else {
+   12323             : 
+   12324          96 :         if (notran) {
+   12325           0 :             *(unsigned char *)transt = 'T';
+   12326             :         } else {
+   12327          96 :             *(unsigned char *)transt = 'N';
+   12328             :         }
+   12329          96 :         if (nq > *k) {
+   12330             : 
+   12331           0 :             PLUMED_BLAS_F77_FUNC(dormlq,DORMLQ)(side, transt, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   12332             :                     c_offset], ldc, &work[1], lwork, &iinfo);
+   12333          96 :         } else if (nq > 1) {
+   12334             : 
+   12335          96 :             if (left) {
+   12336           0 :                 mi = *m - 1;
+   12337           0 :                 ni = *n;
+   12338             :                 i1 = 2;
+   12339             :                 i2 = 1;
+   12340             :             } else {
+   12341          96 :                 mi = *m;
+   12342          96 :                 ni = *n - 1;
+   12343             :                 i1 = 1;
+   12344             :                 i2 = 2;
+   12345             :             }
+   12346          96 :             i__1 = nq - 1;
+   12347          96 :             PLUMED_BLAS_F77_FUNC(dormlq,DORMLQ)(side, transt, &mi, &ni, &i__1, &a[(a_dim1 << 1) + 1], lda,
+   12348          96 :                      &tau[1], &c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &
+   12349             :                     iinfo);
+   12350             :         }
+   12351             :     }
+   12352         192 :     work[1] = (double) lwkopt;
+   12353         192 :     return;
+   12354             : 
+   12355             : 
+   12356             : }
+   12357             : 
+   12358             : 
+   12359             : }
+   12360             : }
+   12361             : #include <cctype>
+   12362             : #include "lapack.h"
+   12363             : #include "real.h"
+   12364             : 
+   12365             : #include "blas/blas.h"
+   12366             : namespace PLMD{
+   12367             : namespace lapack{
+   12368             : using namespace blas;
+   12369             : void
+   12370          83 : PLUMED_BLAS_F77_FUNC(dorml2,DORML2)(const char *side,
+   12371             :         const char *trans,
+   12372             :         int *m,
+   12373             :         int *n,
+   12374             :         int *k,
+   12375             :         double *a,
+   12376             :         int *lda,
+   12377             :         double *tau,
+   12378             :         double *c,
+   12379             :         int *ldc,
+   12380             :         double *work,
+   12381             :     int *info)
+   12382             : {
+   12383          83 :   const char xside=std::toupper(*side);
+   12384          83 :   const char xtrans=std::toupper(*trans);
+   12385             :   int i,i1,i2,i3,ni,mi,ic,jc;
+   12386             :   double aii;
+   12387             : 
+   12388          83 :   if(*m<=0 || *n<=0 || *k<=0)
+   12389             :     return;
+   12390             : 
+   12391             :   ic = jc = 0;
+   12392             : 
+   12393          83 :   if((xside=='L' && xtrans=='N') || (xside!='L' && xtrans!='N')) {
+   12394             :     i1 = 0;
+   12395             :     i2 = *k;
+   12396             :     i3 = 1;
+   12397             :   } else {
+   12398          83 :     i1 = *k-1;
+   12399             :     i2 = -1;
+   12400             :     i3 = -1;
+   12401             :   }
+   12402             :   
+   12403          83 :   if(xside=='L') {
+   12404           0 :     ni = *n;
+   12405             :     jc = 0;
+   12406             :   } else {
+   12407          83 :     mi = *m;
+   12408             :     ic = 0;
+   12409             :   }
+   12410             : 
+   12411        1600 :   for(i=i1;i!=i2;i+=i3) {
+   12412        1517 :     if(xside=='L') {
+   12413           0 :       mi = *m - i;
+   12414             :       ic = i;
+   12415             :     } else {
+   12416        1517 :       ni = *n - i;
+   12417             :       jc = i;
+   12418             :     }
+   12419        1517 :     aii = a[i*(*lda)+i];
+   12420        1517 :     a[i*(*lda)+i] = 1.0;
+   12421        1517 :     PLUMED_BLAS_F77_FUNC(dlarf,DLARF)(side,&mi,&ni,&(a[i*(*lda)+i]),lda,tau+i,
+   12422        1517 :            &(c[jc*(*ldc)+ic]),ldc,work);
+   12423        1517 :     a[i*(*lda)+i] = aii;
+   12424             :   }
+   12425             :   return;
+   12426             : }
+   12427             :              
+   12428             : }
+   12429             : }
+   12430             : #include "lapack.h"
+   12431             : #include "lapack_limits.h"
+   12432             : 
+   12433             : 
+   12434             : #include "blas/blas.h"
+   12435             : namespace PLMD{
+   12436             : namespace lapack{
+   12437             : using namespace blas;
+   12438             : void 
+   12439          96 : PLUMED_BLAS_F77_FUNC(dormlq,DORMLQ)(const char *side, 
+   12440             :         const char *trans,
+   12441             :         int *m, 
+   12442             :         int *n, 
+   12443             :         int *k,
+   12444             :         double *a,
+   12445             :         int *lda, 
+   12446             :         double *tau, 
+   12447             :         double *c__, 
+   12448             :         int *ldc, 
+   12449             :         double *work, 
+   12450             :         int *lwork, 
+   12451             :         int *info)
+   12452             : {
+   12453             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, 
+   12454             :             i__5;
+   12455             :   
+   12456             : 
+   12457             :     int i__;
+   12458             :     double t[4160]      /* was [65][64] */;
+   12459             :     int i1, i2, i3, ib, ic, jc, nb, mi, ni, nq, nw, iws;
+   12460             :     int left;
+   12461             :     int nbmin, iinfo;
+   12462             :     int notran;
+   12463             :     int ldwork;
+   12464             :     char transt[1];
+   12465             :     int lwkopt;
+   12466             :     int lquery;
+   12467          96 :     int ldt = 65;
+   12468             : 
+   12469          96 :     a_dim1 = *lda;
+   12470          96 :     a_offset = 1 + a_dim1;
+   12471          96 :     a -= a_offset;
+   12472             :     --tau;
+   12473          96 :     c_dim1 = *ldc;
+   12474          96 :     c_offset = 1 + c_dim1;
+   12475          96 :     c__ -= c_offset;
+   12476             :     --work;
+   12477             : 
+   12478             :     ic = jc = 0;
+   12479             : 
+   12480          96 :     *info = 0;
+   12481          96 :     left = (*side=='L' || *side=='l');
+   12482          96 :     notran = (*trans=='N' || *trans=='n');
+   12483          96 :     lquery = *lwork == -1;
+   12484             : 
+   12485          96 :     if (left) {
+   12486           0 :         nq = *m;
+   12487           0 :         nw = *n;
+   12488             :     } else {
+   12489          96 :         nq = *n;
+   12490          96 :         nw = *m;
+   12491             :     }
+   12492             : 
+   12493             :     nb = DORMLQ_BLOCKSIZE;
+   12494          96 :     lwkopt = nw * nb;
+   12495          96 :     work[1] = (double) lwkopt;
+   12496             :     
+   12497          96 :     if (*info != 0) {
+   12498             :         return;
+   12499          96 :     } else if (lquery) {
+   12500             :         return;
+   12501             :     }
+   12502             : 
+   12503          96 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12504           0 :         work[1] = 1.;
+   12505           0 :         return;
+   12506             :     }
+   12507             : 
+   12508             :     nbmin = 2;
+   12509          96 :     ldwork = nw;
+   12510          96 :     if (nb > 1 && nb < *k) {
+   12511             :         iws = nw * nb;
+   12512          13 :         if (*lwork < iws) {
+   12513           0 :             nb = *lwork / ldwork;
+   12514             :             nbmin = DORMLQ_MINBLOCKSIZE;
+   12515             :         }
+   12516             :     }
+   12517             : 
+   12518          96 :     if (nb < nbmin || nb >= *k) {
+   12519             : 
+   12520             : 
+   12521          83 :         PLUMED_BLAS_F77_FUNC(dorml2,DORML2)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   12522             :                 c_offset], ldc, &work[1], &iinfo);
+   12523             :     } else {
+   12524             : 
+   12525          13 :         if ((left && notran) || (!left && !notran)) {
+   12526             :             i1 = 1;
+   12527             :             i2 = *k;
+   12528             :             i3 = nb;
+   12529             :         } else {
+   12530          13 :             i1 = (*k - 1) / nb * nb + 1;
+   12531             :             i2 = 1;
+   12532          13 :             i3 = -nb;
+   12533             :         }
+   12534             : 
+   12535          13 :         if (left) {
+   12536           0 :             ni = *n;
+   12537             :             jc = 1;
+   12538             :         } else {
+   12539          13 :             mi = *m;
+   12540             :             ic = 1;
+   12541             :         }
+   12542             : 
+   12543          13 :         if (notran) {
+   12544          13 :             *(unsigned char *)transt = 'T';
+   12545             :         } else {
+   12546           0 :             *(unsigned char *)transt = 'N';
+   12547             :         }
+   12548             : 
+   12549             :         i__1 = i2;
+   12550             :         i__2 = i3;
+   12551          53 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   12552          40 :             i__4 = nb, i__5 = *k - i__ + 1;
+   12553          40 :             ib = (i__4<i__5) ? i__4 : i__5;
+   12554             : 
+   12555          40 :             i__4 = nq - i__ + 1;
+   12556          40 :             PLUMED_BLAS_F77_FUNC(dlarft,DLARFT)("Forward", "Rowwise", &i__4, &ib, &a[i__ + i__ * a_dim1], 
+   12557          40 :                     lda, &tau[i__], t, &ldt);
+   12558          40 :             if (left) {
+   12559             : 
+   12560           0 :                 mi = *m - i__ + 1;
+   12561             :                 ic = i__;
+   12562             :             } else {
+   12563             : 
+   12564          40 :                 ni = *n - i__ + 1;
+   12565             :                 jc = i__;
+   12566             :             }
+   12567             : 
+   12568          40 :             PLUMED_BLAS_F77_FUNC(dlarfb,DLARFB)(side, transt, "Forward", "Rowwise", &mi, &ni, &ib, &a[i__ 
+   12569          40 :                     + i__ * a_dim1], lda, t, &ldt, &c__[ic + jc * c_dim1], 
+   12570             :                     ldc, &work[1], &ldwork);
+   12571             :         }
+   12572             :     }
+   12573          96 :     work[1] = (double) lwkopt;
+   12574          96 :     return;
+   12575             : 
+   12576             : }
+   12577             : 
+   12578             : 
+   12579             : }
+   12580             : }
+   12581             : #include "lapack.h"
+   12582             : #include "lapack_limits.h"
+   12583             : 
+   12584             : #include "blas/blas.h"
+   12585             : namespace PLMD{
+   12586             : namespace lapack{
+   12587             : using namespace blas;
+   12588             : void
+   12589      569961 : PLUMED_BLAS_F77_FUNC(dormql,DORMQL)(const char *side, const char *trans, int *m, int *n, 
+   12590             :         int *k, double *a, int *lda, double *tau, double *
+   12591             :         c__, int *ldc, double *work, int *lwork, int *info)
+   12592             : {
+   12593             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, i__5;
+   12594      569961 :     int c__65 = 65;
+   12595             : 
+   12596             :     int i__;
+   12597             :     double t[4160];
+   12598             :     int i1, i2, i3, ib, nb, mi, ni, nq, nw, iws;
+   12599             :     int left;
+   12600             :     int nbmin, iinfo;
+   12601             :     int notran;
+   12602             :     int ldwork, lwkopt;
+   12603             :     int lquery;
+   12604             : 
+   12605             : 
+   12606      569961 :     a_dim1 = *lda;
+   12607      569961 :     a_offset = 1 + a_dim1;
+   12608      569961 :     a -= a_offset;
+   12609             :     --tau;
+   12610             :     c_dim1 = *ldc;
+   12611             :     c_offset = 1 + c_dim1;
+   12612             :     c__ -= c_offset;
+   12613             :     --work;
+   12614             : 
+   12615      569961 :     *info = 0;
+   12616      569961 :     left = (*side=='L' || *side=='l');
+   12617      569961 :     notran = (*trans=='N' || *trans=='n');
+   12618      569961 :     lquery = *lwork == -1;
+   12619             : 
+   12620      569961 :     if (left) {
+   12621      569961 :         nq = *m;
+   12622      569961 :         nw = *n;
+   12623             :     } else {
+   12624           0 :         nq = *n;
+   12625           0 :         nw = *m;
+   12626             :     }
+   12627             : 
+   12628             :     nb = DORMQL_BLOCKSIZE;
+   12629      569961 :     lwkopt = nw * nb;
+   12630      569961 :     work[1] = (double) lwkopt;
+   12631             :     
+   12632      569961 :     if (*info != 0) {
+   12633             :         return;
+   12634      569961 :     } else if (lquery) {
+   12635             :         return;
+   12636             :     }
+   12637             : 
+   12638      569961 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12639           0 :         work[1] = 1.;
+   12640           0 :         return;
+   12641             :     }
+   12642             : 
+   12643             :     nbmin = 2;
+   12644      569961 :     ldwork = nw;
+   12645      569961 :     if (nb > 1 && nb < *k) {
+   12646             :         iws = nw * nb;
+   12647          12 :         if (*lwork < iws) {
+   12648           0 :             nb = *lwork / ldwork;
+   12649             :             nbmin = DORMQL_MINBLOCKSIZE;
+   12650             :         }
+   12651             :     }
+   12652             : 
+   12653      569961 :     if (nb < nbmin || nb >= *k) {
+   12654             : 
+   12655      569949 :         PLUMED_BLAS_F77_FUNC(dorm2l,DORM2L)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   12656             :                 c_offset], ldc, &work[1], &iinfo);
+   12657             :     } else {
+   12658             : 
+   12659          12 :         if ((left && notran) || (! left && ! notran)) {
+   12660             :             i1 = 1;
+   12661             :             i2 = *k;
+   12662             :             i3 = nb;
+   12663             :         } else {
+   12664           0 :             i1 = (*k - 1) / nb * nb + 1;
+   12665             :             i2 = 1;
+   12666           0 :             i3 = -nb;
+   12667             :         }
+   12668             : 
+   12669          12 :         if (left) {
+   12670          12 :             ni = *n;
+   12671             :         } else {
+   12672           0 :             mi = *m;
+   12673             :         }
+   12674             : 
+   12675             :         i__1 = i2;
+   12676             :         i__2 = i3;
+   12677          71 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   12678          59 :             i__4 = nb, i__5 = *k - i__ + 1;
+   12679          59 :             ib = (i__4<i__5) ? i__4 : i__5;
+   12680             : 
+   12681          59 :             i__4 = nq - *k + i__ + ib - 1;
+   12682          59 :             PLUMED_BLAS_F77_FUNC(dlarft,DLARFT)("Backward", "Columnwise", &i__4, &ib, &a[i__ * a_dim1 + 1]
+   12683          59 :                     , lda, &tau[i__], t, &c__65);
+   12684          59 :             if (left) {
+   12685             : 
+   12686          59 :                 mi = *m - *k + i__ + ib - 1;
+   12687             :             } else {
+   12688             : 
+   12689           0 :                 ni = *n - *k + i__ + ib - 1;
+   12690             :             }
+   12691             : 
+   12692          59 :             PLUMED_BLAS_F77_FUNC(dlarfb,DLARFB)(side, trans, "Backward", "Columnwise", &mi, &ni, &ib, &a[
+   12693             :                     i__ * a_dim1 + 1], lda, t, &c__65, &c__[c_offset], ldc, &
+   12694             :                     work[1], &ldwork);
+   12695             :         }
+   12696             :     }
+   12697      569961 :     work[1] = (double) lwkopt;
+   12698      569961 :     return;
+   12699             : 
+   12700             : }
+   12701             : 
+   12702             : 
+   12703             : }
+   12704             : }
+   12705             : #include "lapack.h"
+   12706             : #include "lapack_limits.h"
+   12707             : 
+   12708             : #include "blas/blas.h"
+   12709             : namespace PLMD{
+   12710             : namespace lapack{
+   12711             : using namespace blas;
+   12712             : void 
+   12713          96 : PLUMED_BLAS_F77_FUNC(dormqr,DORMQR)(const char *side, 
+   12714             :         const char *trans, 
+   12715             :         int *m, 
+   12716             :         int *n, 
+   12717             :         int *k, 
+   12718             :         double *a, 
+   12719             :         int *lda, 
+   12720             :         double *tau, 
+   12721             :         double *c__, 
+   12722             :         int *ldc, 
+   12723             :         double *work, 
+   12724             :         int *lwork, 
+   12725             :         int *info)
+   12726             : {
+   12727             :    int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, i__5;
+   12728             : 
+   12729             :     int i__;
+   12730             :     double t[4160];
+   12731             :     int i1, i2, i3, ib, ic, jc, nb, mi, ni, nq, nw, iws;
+   12732             :     int left;
+   12733             :     int nbmin, iinfo;
+   12734             :     int notran;
+   12735             :     int ldwork, lwkopt;
+   12736             :     int lquery;
+   12737          96 :     int ldt = 65;
+   12738             : 
+   12739          96 :     a_dim1 = *lda;
+   12740          96 :     a_offset = 1 + a_dim1;
+   12741          96 :     a -= a_offset;
+   12742             :     --tau;
+   12743          96 :     c_dim1 = *ldc;
+   12744          96 :     c_offset = 1 + c_dim1;
+   12745          96 :     c__ -= c_offset;
+   12746             :     --work;
+   12747             : 
+   12748          96 :     *info = 0;
+   12749          96 :     left = (*side=='L' || *side=='l');
+   12750          96 :     notran = (*trans=='N' || *trans=='n');
+   12751          96 :     lquery = *lwork == -1;
+   12752             : 
+   12753          96 :     if (left) {
+   12754          96 :         nq = *m;
+   12755          96 :         nw = *n;
+   12756             :     } else {
+   12757           0 :         nq = *n;
+   12758           0 :         nw = *m;
+   12759             :     }
+   12760             : 
+   12761             :      ic = jc = 0;
+   12762             :      nb = DORMQR_BLOCKSIZE;
+   12763          96 :      lwkopt = nw * nb;
+   12764          96 :      work[1] = (double) lwkopt;
+   12765             : 
+   12766          96 :     if (*info != 0) {
+   12767             :         return;
+   12768          96 :     } else if (lquery) {
+   12769             :       return;
+   12770             :     }
+   12771             : 
+   12772          96 :     if (*m == 0 || *n == 0 || *k == 0) {
+   12773           0 :         work[1] = 1.;
+   12774           0 :         return;
+   12775             :     }
+   12776             : 
+   12777             :     nbmin = 2;
+   12778          96 :     ldwork = nw;
+   12779          96 :     if (nb > 1 && nb < *k) {
+   12780             :         iws = nw * nb;
+   12781          17 :         if (*lwork < iws) {
+   12782           0 :             nb = *lwork / ldwork;
+   12783             :             nbmin = DORMQR_MINBLOCKSIZE;
+   12784             :         }
+   12785             :     }
+   12786             : 
+   12787          96 :     if (nb < nbmin || nb >= *k) {
+   12788             : 
+   12789          79 :         PLUMED_BLAS_F77_FUNC(dorm2r,DORM2R)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   12790             :                 c_offset], ldc, &work[1], &iinfo);
+   12791             :     } else {
+   12792             : 
+   12793          17 :         if ((left && !notran) || (!left && notran)) {
+   12794             :             i1 = 1;
+   12795             :             i2 = *k;
+   12796             :             i3 = nb;
+   12797             :         } else {
+   12798          17 :             i1 = (*k - 1) / nb * nb + 1;
+   12799             :             i2 = 1;
+   12800          17 :             i3 = -nb;
+   12801             :         }
+   12802             : 
+   12803          17 :         if (left) {
+   12804          17 :             ni = *n;
+   12805             :             jc = 1;
+   12806             :         } else {
+   12807           0 :             mi = *m;
+   12808             :             ic = 1;
+   12809             :         }
+   12810             : 
+   12811             :         i__1 = i2;
+   12812             :         i__2 = i3;
+   12813          65 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   12814          48 :             i__4 = nb, i__5 = *k - i__ + 1;
+   12815          48 :             ib = (i__4<i__5) ? i__4 : i__5;
+   12816             : 
+   12817          48 :             i__4 = nq - i__ + 1;
+   12818          48 :             PLUMED_BLAS_F77_FUNC(dlarft,DLARFT)("Forward", "Columnwise", &i__4, &ib, &a[i__ + i__ * 
+   12819          48 :                     a_dim1], lda, &tau[i__], t, &ldt);
+   12820          48 :             if (left) {
+   12821             : 
+   12822          48 :                 mi = *m - i__ + 1;
+   12823             :                 ic = i__;
+   12824             :             } else {
+   12825           0 :                 ni = *n - i__ + 1;
+   12826             :                 jc = i__;
+   12827             :             }
+   12828             : 
+   12829          48 :             PLUMED_BLAS_F77_FUNC(dlarfb,DLARFB)(side, trans, "Forward", "Columnwise", &mi, &ni, &ib, &a[
+   12830          48 :                     i__ + i__ * a_dim1], lda, t, &ldt, &c__[ic + jc * 
+   12831             :                     c_dim1], ldc, &work[1], &ldwork);
+   12832             :         }
+   12833             :     }
+   12834          96 :     work[1] = (double) lwkopt;
+   12835          96 :     return;
+   12836             : 
+   12837             : 
+   12838             : }
+   12839             : 
+   12840             : 
+   12841             : }
+   12842             : }
+   12843             : #include "lapack.h"
+   12844             : #include "lapack_limits.h"
+   12845             : 
+   12846             : 
+   12847             : #include "blas/blas.h"
+   12848             : namespace PLMD{
+   12849             : namespace lapack{
+   12850             : using namespace blas;
+   12851             : void
+   12852      569961 : PLUMED_BLAS_F77_FUNC(dormtr,DORMTR)(const char *side, 
+   12853             :         const char *uplo,
+   12854             :         const char *trans, 
+   12855             :         int *m, 
+   12856             :         int *n,
+   12857             :         double *a, 
+   12858             :         int *lda, 
+   12859             :         double *tau, 
+   12860             :         double *c__, 
+   12861             :         int *ldc,
+   12862             :         double *work, 
+   12863             :         int *lwork, 
+   12864             :         int *info)
+   12865             : {
+   12866             :     int a_dim1, a_offset, c_dim1, c_offset, i__2;
+   12867             : 
+   12868             :     int i1, i2, nb, mi, ni, nq, nw;
+   12869             :     int left;
+   12870             :     int iinfo;
+   12871             :     int upper;
+   12872             :     int lwkopt;
+   12873             :     int lquery;
+   12874             : 
+   12875             : 
+   12876      569961 :     a_dim1 = *lda;
+   12877      569961 :     a_offset = 1 + a_dim1;
+   12878      569961 :     a -= a_offset;
+   12879             :     --tau;
+   12880      569961 :     c_dim1 = *ldc;
+   12881      569961 :     c_offset = 1 + c_dim1;
+   12882      569961 :     c__ -= c_offset;
+   12883             :     --work;
+   12884             : 
+   12885      569961 :     *info = 0;
+   12886      569961 :     left = (*side=='L' || *side=='l');
+   12887      569961 :     upper = (*uplo=='U' || *uplo=='u');
+   12888      569961 :     lquery = *lwork == -1;
+   12889             : 
+   12890      569961 :     if (left) {
+   12891      569961 :         nq = *m;
+   12892      569961 :         nw = *n;
+   12893             :     } else {
+   12894           0 :         nq = *n;
+   12895           0 :         nw = *m;
+   12896             :     }
+   12897             : 
+   12898             : 
+   12899             :     nb = DORMQL_BLOCKSIZE;
+   12900      569961 :     lwkopt = nw * nb;
+   12901      569961 :     work[1] = (double) lwkopt;
+   12902             :     
+   12903      569961 :     if (*info != 0) {
+   12904             :         i__2 = -(*info);
+   12905             :         return;
+   12906      569961 :     } else if (lquery) {
+   12907             :         return;
+   12908             :     }
+   12909             : 
+   12910      569961 :     if (*m == 0 || *n == 0 || nq == 1) {
+   12911           0 :         work[1] = 1.;
+   12912           0 :         return;
+   12913             :     }
+   12914             : 
+   12915      569961 :     if (left) {
+   12916      569961 :         mi = *m - 1;
+   12917      569961 :         ni = *n;
+   12918             :     } else {
+   12919           0 :         mi = *m;
+   12920           0 :         ni = *n - 1;
+   12921             :     }
+   12922             : 
+   12923      569961 :     if (upper) {
+   12924      569961 :         i__2 = nq - 1;
+   12925      569961 :         PLUMED_BLAS_F77_FUNC(dormql,DORMQL)(side, trans, &mi, &ni, &i__2, &a[(a_dim1 << 1) + 1], lda, &
+   12926             :                 tau[1], &c__[c_offset], ldc, &work[1], lwork, &iinfo);
+   12927             :     } else {
+   12928           0 :         if (left) {
+   12929             :             i1 = 2;
+   12930             :             i2 = 1;
+   12931             :         } else {
+   12932             :             i1 = 1;
+   12933             :             i2 = 2;
+   12934             :         }
+   12935           0 :         i__2 = nq - 1;
+   12936           0 :         PLUMED_BLAS_F77_FUNC(dormqr,DORMQR)(side, trans, &mi, &ni, &i__2, &a[a_dim1 + 2], lda, &tau[1], &
+   12937           0 :                 c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &iinfo);
+   12938             :     }
+   12939      569961 :     work[1] = (double) lwkopt;
+   12940      569961 :     return;
+   12941             : 
+   12942             : }
+   12943             : 
+   12944             : 
+   12945             : }
+   12946             : }
+   12947             : #include <cmath>
+   12948             : #include "lapack.h"
+   12949             : #include "lapack_limits.h"
+   12950             : 
+   12951             : #include "real.h"
+   12952             : 
+   12953             : #include "blas/blas.h"
+   12954             : namespace PLMD{
+   12955             : namespace lapack{
+   12956             : using namespace blas;
+   12957             : void
+   12958           0 : PLUMED_BLAS_F77_FUNC(dstebz,DSTEBZ)(const char *range, 
+   12959             :                         const char *order,
+   12960             :                         int *n,
+   12961             :                         double *vl, 
+   12962             :                         double *vu, 
+   12963             :                         int *il,
+   12964             :                         int *iu,
+   12965             :                         double *abstol, 
+   12966             :                         double *d__,
+   12967             :                         double *e,
+   12968             :                         int *m, 
+   12969             :                         int *nsplit, 
+   12970             :                         double *w,
+   12971             :                         int *iblock,
+   12972             :                         int *isplit,
+   12973             :                         double *work, 
+   12974             :                         int *iwork, 
+   12975             :                         int *info)
+   12976             : {
+   12977             :     int i__1, i__2, i__3;
+   12978             :     double d__1, d__2, d__3, d__4, d__5;
+   12979           0 :     int c__1 = 1;
+   12980           0 :     int c__3 = 3;
+   12981           0 :     int c__2 = 2;
+   12982           0 :     int c__0 = 0;
+   12983             : 
+   12984             :     int j, ib, jb, ie, je, nb;
+   12985             :     double gl;
+   12986             :     int im, in;
+   12987             :     double gu;
+   12988             :     int iw;
+   12989             :     double wl, wu;
+   12990             :     int nwl;
+   12991             :     double ulp, wlu, wul;
+   12992             :     int nwu;
+   12993             :     double tmp1, tmp2;
+   12994             :     int iend, ioff, iout, itmp1, jdisc;
+   12995             :     int iinfo;
+   12996             :     double atoli;
+   12997             :     int iwoff;
+   12998             :     double bnorm;
+   12999             :     int itmax;
+   13000             :     double wkill, rtoli, tnorm;
+   13001             :     int ibegin;
+   13002             :     int irange, idiscl;
+   13003             :     int idumma[1];
+   13004             :     int idiscu, iorder;
+   13005             :     int ncnvrg;
+   13006             :     double pivmin;
+   13007             :     int toofew;
+   13008             :     const double safemn = PLUMED_GMX_DOUBLE_MIN*(1.0+PLUMED_GMX_DOUBLE_EPS);
+   13009             : 
+   13010           0 :     --iwork;
+   13011           0 :     --work;
+   13012           0 :     --isplit;
+   13013           0 :     --iblock;
+   13014           0 :     --w;
+   13015           0 :     --e;
+   13016           0 :     --d__;
+   13017             : 
+   13018           0 :     *info = 0;
+   13019             : 
+   13020           0 :     if (*range=='A' || *range=='a') {
+   13021             :         irange = 1;
+   13022           0 :     } else if (*range=='V' || *range=='v') {
+   13023             :         irange = 2;
+   13024             :     } else if (*range=='I' || *range=='i') {
+   13025             :         irange = 3;
+   13026             :     } else {
+   13027             :         irange = 0;
+   13028             :     }
+   13029             : 
+   13030           0 :     if (*order=='B' || *order=='b') {
+   13031             :         iorder = 2;
+   13032           0 :     } else if (*order=='E' || *order=='e') {
+   13033             :         iorder = 1;
+   13034             :     } else {
+   13035             :         iorder = 0;
+   13036             :     }
+   13037             : 
+   13038           0 :     if (irange <= 0) {
+   13039           0 :         *info = -1;
+   13040           0 :     } else if (iorder <= 0) {
+   13041           0 :         *info = -2;
+   13042           0 :     } else if (*n < 0) {
+   13043           0 :         *info = -3;
+   13044           0 :     } else if (irange == 2) {
+   13045           0 :         if (*vl >= *vu) {
+   13046           0 :             *info = -5;
+   13047             :         }
+   13048           0 :     } else if (irange == 3 && (*il < 1 || *il > (*n))) {
+   13049           0 :         *info = -6;
+   13050           0 :     } else if (irange == 3 && (*iu < ((*n<*il) ? *n : *il) || *iu > *n)) {
+   13051           0 :         *info = -7;
+   13052             :     }
+   13053             : 
+   13054           0 :     if (*info != 0) {
+   13055             :         return;
+   13056             :     }
+   13057             : 
+   13058           0 :     *info = 0;
+   13059             :     ncnvrg = 0;
+   13060             :     toofew = 0;
+   13061             : 
+   13062           0 :     *m = 0;
+   13063           0 :     if (*n == 0) {
+   13064             :         return;
+   13065             :     }
+   13066             : 
+   13067           0 :     if (irange == 3 && *il == 1 && *iu == *n) {
+   13068             :         irange = 1;
+   13069             :     }
+   13070             : 
+   13071             :     ulp = 2*PLUMED_GMX_DOUBLE_EPS;
+   13072           0 :     rtoli = ulp * 2.;
+   13073             :     nb = DSTEBZ_BLOCKSIZE;
+   13074             :     // cppcheck-suppress knownConditionTrueFalse
+   13075             :     if (nb <= 1) {
+   13076           0 :         nb = 0;
+   13077             :     }
+   13078             : 
+   13079           0 :     if (*n == 1) {
+   13080           0 :         *nsplit = 1;
+   13081           0 :         isplit[1] = 1;
+   13082           0 :         if (irange == 2 && (*vl >= d__[1] || *vu < d__[1])) {
+   13083           0 :             *m = 0;
+   13084             :         } else {
+   13085           0 :             w[1] = d__[1];
+   13086           0 :             iblock[1] = 1;
+   13087           0 :             *m = 1;
+   13088             :         }
+   13089           0 :         return;
+   13090             :     }
+   13091             : 
+   13092           0 :     *nsplit = 1;
+   13093           0 :     work[*n] = 0.;
+   13094           0 :     pivmin = 1.;
+   13095           0 :     i__1 = *n;
+   13096           0 :     for (j = 2; j <= i__1; ++j) {
+   13097           0 :         d__1 = e[j - 1];
+   13098           0 :         tmp1 = d__1 * d__1;
+   13099             :         d__2 = ulp;
+   13100           0 :         if (std::abs(d__[j] * d__[j - 1]) * (d__2 * d__2) + safemn 
+   13101             :                 > tmp1) {
+   13102           0 :             isplit[*nsplit] = j - 1;
+   13103           0 :             ++(*nsplit);
+   13104           0 :             work[j - 1] = 0.;
+   13105             :         } else {
+   13106           0 :             work[j - 1] = tmp1;
+   13107           0 :             pivmin = (pivmin>tmp1) ? pivmin : tmp1;
+   13108             :         }
+   13109             :     }
+   13110           0 :     isplit[*nsplit] = *n;
+   13111           0 :     pivmin *= safemn;
+   13112             : 
+   13113           0 :     if (irange == 3) {
+   13114             : 
+   13115           0 :         gu = d__[1];
+   13116             :         gl = d__[1];
+   13117             :         tmp1 = 0.;
+   13118             : 
+   13119             :         i__1 = *n - 1;
+   13120           0 :         for (j = 1; j <= i__1; ++j) {
+   13121           0 :             tmp2 =  std::sqrt(work[j]);
+   13122           0 :             d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
+   13123           0 :             gu = (d__1>d__2) ? d__1 : d__2;
+   13124           0 :             d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
+   13125           0 :             gl = (d__1<d__2) ? d__1 : d__2;
+   13126             :             tmp1 = tmp2;
+   13127             :         }
+   13128             : 
+   13129           0 :         d__1 = gu, d__2 = d__[*n] + tmp1;
+   13130           0 :         gu = (d__1>d__2) ? d__1 : d__2;
+   13131           0 :         d__1 = gl, d__2 = d__[*n] - tmp1;
+   13132           0 :         gl = (d__1<d__2) ? d__1 : d__2;
+   13133             :         d__1 = std::abs(gl);
+   13134             :         d__2 = std::abs(gu);
+   13135           0 :         tnorm = (d__1>d__2) ? d__1 : d__2;
+   13136           0 :         gl = gl - tnorm * 2. * ulp * *n - pivmin * 4.;
+   13137           0 :         gu = gu + tnorm * 2. * ulp * *n + pivmin * 2.;
+   13138             : 
+   13139           0 :         itmax = (int) ((std::log(tnorm + pivmin) - std::log(pivmin)) / std::log(2.)) + 2;
+   13140           0 :         if (*abstol <= 0.) {
+   13141           0 :             atoli = ulp * tnorm;
+   13142             :         } else {
+   13143           0 :             atoli = *abstol;
+   13144             :         }
+   13145             : 
+   13146           0 :         work[*n + 1] = gl;
+   13147           0 :         work[*n + 2] = gl;
+   13148           0 :         work[*n + 3] = gu;
+   13149           0 :         work[*n + 4] = gu;
+   13150           0 :         work[*n + 5] = gl;
+   13151           0 :         work[*n + 6] = gu;
+   13152           0 :         iwork[1] = -1;
+   13153           0 :         iwork[2] = -1;
+   13154           0 :         iwork[3] = *n + 1;
+   13155           0 :         iwork[4] = *n + 1;
+   13156           0 :         iwork[5] = *il - 1;
+   13157           0 :         iwork[6] = *iu;
+   13158             : 
+   13159           0 :         PLUMED_BLAS_F77_FUNC(dlaebz,DLAEBZ)(&c__3, &itmax, n, &c__2, &c__2, &nb, &atoli, &rtoli, &pivmin, 
+   13160           0 :                 &d__[1], &e[1], &work[1], &iwork[5], &work[*n + 1], &work[*n 
+   13161           0 :                 + 5], &iout, &iwork[1], &w[1], &iblock[1], &iinfo);
+   13162             : 
+   13163           0 :         if (iwork[6] == *iu) {
+   13164           0 :             wl = work[*n + 1];
+   13165           0 :             wlu = work[*n + 3];
+   13166           0 :             nwl = iwork[1];
+   13167           0 :             wu = work[*n + 4];
+   13168           0 :             wul = work[*n + 2];
+   13169           0 :             nwu = iwork[4];
+   13170             :         } else {
+   13171           0 :             wl = work[*n + 2];
+   13172           0 :             wlu = work[*n + 4];
+   13173           0 :             nwl = iwork[2];
+   13174           0 :             wu = work[*n + 3];
+   13175           0 :             wul = work[*n + 1];
+   13176           0 :             nwu = iwork[3];
+   13177             :         }
+   13178             : 
+   13179           0 :         if (nwl < 0 || nwl >= *n || nwu < 1 || nwu > *n) {
+   13180           0 :             *info = 4;
+   13181           0 :             return;
+   13182             :         }
+   13183             :     } else {
+   13184             : 
+   13185             : 
+   13186             :       /* avoid warnings for high gcc optimization */
+   13187             :       wlu = wul = 1.0;
+   13188             : 
+   13189           0 :         d__3 = std::abs(d__[1]) + std::abs(e[1]);
+   13190           0 :         d__4 = std::abs(d__[*n]) + std::abs(e[*n - 1]);
+   13191           0 :         tnorm = (d__3>d__4) ? d__3 : d__4;
+   13192             : 
+   13193             :         i__1 = *n - 1;
+   13194           0 :         for (j = 2; j <= i__1; ++j) {
+   13195             :             d__4 = tnorm;
+   13196           0 :             d__5 = std::abs(d__[j]) + std::abs(e[j - 1]) + std::abs(e[j]);
+   13197           0 :             tnorm = (d__4>d__5) ? d__4 : d__5;
+   13198             :         }
+   13199             : 
+   13200           0 :         if (*abstol <= 0.) {
+   13201           0 :             atoli = ulp * tnorm;
+   13202             :         } else {
+   13203           0 :             atoli = *abstol;
+   13204             :         }
+   13205             : 
+   13206           0 :         if (irange == 2) {
+   13207           0 :             wl = *vl;
+   13208           0 :             wu = *vu;
+   13209             :         } else {
+   13210             :             wl = 0.;
+   13211             :             wu = 0.;
+   13212             :         }
+   13213             :     }
+   13214             : 
+   13215           0 :     *m = 0;
+   13216             :     iend = 0;
+   13217           0 :     *info = 0;
+   13218             :     nwl = 0;
+   13219             :     nwu = 0;
+   13220             : 
+   13221           0 :     i__1 = *nsplit;
+   13222           0 :     for (jb = 1; jb <= i__1; ++jb) {
+   13223             :         ioff = iend;
+   13224           0 :         ibegin = ioff + 1;
+   13225           0 :         iend = isplit[jb];
+   13226           0 :         in = iend - ioff;
+   13227             : 
+   13228           0 :         if (in == 1) {
+   13229             : 
+   13230           0 :             if (irange == 1 || wl >= d__[ibegin] - pivmin) {
+   13231           0 :                 ++nwl;
+   13232             :             }
+   13233           0 :             if (irange == 1 || wu >= d__[ibegin] - pivmin) {
+   13234           0 :                 ++nwu;
+   13235             :             }
+   13236           0 :             if (irange == 1 || ((wl < d__[ibegin] - pivmin) && (wu >= d__[ibegin] - pivmin))) {
+   13237           0 :                 ++(*m);
+   13238           0 :                 w[*m] = d__[ibegin];
+   13239           0 :                 iblock[*m] = jb;
+   13240             :             }
+   13241             :         } else {
+   13242             : 
+   13243           0 :             gu = d__[ibegin];
+   13244             :             gl = d__[ibegin];
+   13245             :             tmp1 = 0.;
+   13246             : 
+   13247             :             i__2 = iend - 1;
+   13248           0 :             for (j = ibegin; j <= i__2; ++j) {
+   13249           0 :                 tmp2 = std::abs(e[j]);
+   13250           0 :                 d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
+   13251           0 :                 gu = (d__1>d__2) ? d__1 : d__2;
+   13252           0 :                 d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
+   13253           0 :                 gl = (d__1<d__2) ? d__1 : d__2;
+   13254             :                 tmp1 = tmp2;
+   13255             :             }
+   13256             : 
+   13257           0 :             d__1 = gu, d__2 = d__[iend] + tmp1;
+   13258           0 :             gu = (d__1>d__2) ? d__1 : d__2;
+   13259           0 :             d__1 = gl, d__2 = d__[iend] - tmp1;
+   13260           0 :             gl = (d__1<d__2) ? d__1 : d__2;
+   13261             :             d__1 = std::abs(gl);
+   13262             :             d__2 = std::abs(gu);
+   13263           0 :             bnorm = (d__1>d__2) ? d__1 : d__2;
+   13264           0 :             gl = gl - bnorm * 2. * ulp * in - pivmin * 2.;
+   13265           0 :             gu = gu + bnorm * 2. * ulp * in + pivmin * 2.;
+   13266             : 
+   13267           0 :             if (*abstol <= 0.) {
+   13268             :                 d__1 = std::abs(gl);
+   13269             :                 d__2 = std::abs(gu);
+   13270           0 :                 atoli = ulp * ((d__1>d__2) ? d__1 : d__2);
+   13271             :             } else {
+   13272           0 :                 atoli = *abstol;
+   13273             :             }
+   13274             : 
+   13275           0 :             if (irange > 1) {
+   13276           0 :                 if (gu < wl) {
+   13277           0 :                     nwl += in;
+   13278           0 :                     nwu += in;
+   13279             :                 }
+   13280             :                 gl = (gl>wl) ? gl : wl;
+   13281             :                 gu = (gu<wu) ? gu : wu;
+   13282             :                 if (gl >= gu) {
+   13283             :                 }
+   13284           0 :                 continue;
+   13285             :             }
+   13286             : 
+   13287           0 :             work[*n + 1] = gl;
+   13288           0 :             work[*n + in + 1] = gu;
+   13289           0 :             PLUMED_BLAS_F77_FUNC(dlaebz,DLAEBZ)(&c__1, &c__0, &in, &in, &c__1, &nb, &atoli, &rtoli, &
+   13290             :                     pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
+   13291           0 :                     work[*n + 1], &work[*n + (in << 1) + 1], &im, &iwork[1], &
+   13292           0 :                     w[*m + 1], &iblock[*m + 1], &iinfo);
+   13293             : 
+   13294           0 :             nwl += iwork[1];
+   13295           0 :             nwu += iwork[in + 1];
+   13296           0 :             iwoff = *m - iwork[1];
+   13297             : 
+   13298           0 :             itmax = (int) ((std::log(gu - gl + pivmin) - std::log(pivmin)) / std::log(2.)
+   13299           0 :                     ) + 2;
+   13300           0 :             PLUMED_BLAS_F77_FUNC(dlaebz,DLAEBZ)(&c__2, &itmax, &in, &in, &c__1, &nb, &atoli, &rtoli, &
+   13301             :                     pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
+   13302           0 :                     work[*n + 1], &work[*n + (in << 1) + 1], &iout, &iwork[1],
+   13303           0 :                      &w[*m + 1], &iblock[*m + 1], &iinfo);
+   13304             : 
+   13305           0 :             i__2 = iout;
+   13306           0 :             for (j = 1; j <= i__2; ++j) {
+   13307           0 :                 tmp1 = (work[j + *n] + work[j + in + *n]) * .5;
+   13308             : 
+   13309           0 :                 if (j > iout - iinfo) {
+   13310             :                     ncnvrg = 1;
+   13311           0 :                     ib = -jb;
+   13312             :                 } else {
+   13313             :                     ib = jb;
+   13314             :                 }
+   13315           0 :                 i__3 = iwork[j + in] + iwoff;
+   13316           0 :                 for (je = iwork[j] + 1 + iwoff; je <= i__3; ++je) {
+   13317           0 :                     w[je] = tmp1;
+   13318           0 :                     iblock[je] = ib;
+   13319             :                 }
+   13320             :             }
+   13321             : 
+   13322           0 :             *m += im;
+   13323             :         }
+   13324             :     }
+   13325             : 
+   13326           0 :     if (irange == 3) {
+   13327           0 :         im = 0;
+   13328           0 :         idiscl = *il - 1 - nwl;
+   13329           0 :         idiscu = nwu - *iu;
+   13330             : 
+   13331           0 :         if (idiscl > 0 || idiscu > 0) {
+   13332           0 :             i__1 = *m;
+   13333           0 :             for (je = 1; je <= i__1; ++je) {
+   13334           0 :                 if (w[je] <= wlu && idiscl > 0) {
+   13335           0 :                     --idiscl;
+   13336           0 :                 } else if (w[je] >= wul && idiscu > 0) {
+   13337           0 :                     --idiscu;
+   13338             :                 } else {
+   13339           0 :                     ++im;
+   13340           0 :                     w[im] = w[je];
+   13341           0 :                     iblock[im] = iblock[je];
+   13342             :                 }
+   13343             :             }
+   13344           0 :             *m = im;
+   13345             :         }
+   13346           0 :         if (idiscl > 0 || idiscu > 0) {
+   13347             : 
+   13348           0 :             if (idiscl > 0) {
+   13349             :                 wkill = wu;
+   13350             :                 i__1 = idiscl;
+   13351           0 :                 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
+   13352             :                     iw = 0;
+   13353           0 :                     i__2 = *m;
+   13354           0 :                     for (je = 1; je <= i__2; ++je) {
+   13355           0 :                         if (iblock[je] != 0 && (w[je] < wkill || iw == 0)) {
+   13356             :                             iw = je;
+   13357             :                             wkill = w[je];
+   13358             :                         }
+   13359             :                     }
+   13360           0 :                     iblock[iw] = 0;
+   13361             :                 }
+   13362             :             }
+   13363           0 :             if (idiscu > 0) {
+   13364             : 
+   13365             :                 wkill = wl;
+   13366             :                 i__1 = idiscu;
+   13367           0 :                 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
+   13368             :                     iw = 0;
+   13369           0 :                     i__2 = *m;
+   13370           0 :                     for (je = 1; je <= i__2; ++je) {
+   13371           0 :                         if (iblock[je] != 0 && (w[je] > wkill || iw == 0)) {
+   13372             :                             iw = je;
+   13373             :                             wkill = w[je];
+   13374             :                         }
+   13375             :                     }
+   13376           0 :                     iblock[iw] = 0;
+   13377             :                 }
+   13378             :             }
+   13379           0 :             im = 0;
+   13380           0 :             i__1 = *m;
+   13381           0 :             for (je = 1; je <= i__1; ++je) {
+   13382           0 :                 if (iblock[je] != 0) {
+   13383           0 :                     ++im;
+   13384           0 :                     w[im] = w[je];
+   13385           0 :                     iblock[im] = iblock[je];
+   13386             :                 }
+   13387             :             }
+   13388           0 :             *m = im;
+   13389             :         }
+   13390           0 :         if (idiscl < 0 || idiscu < 0) {
+   13391             :             toofew = 1;
+   13392             :         }
+   13393             :     }
+   13394             : 
+   13395           0 :     if (iorder == 1 && *nsplit > 1) {
+   13396           0 :         i__1 = *m - 1;
+   13397           0 :         for (je = 1; je <= i__1; ++je) {
+   13398             :             ie = 0;
+   13399           0 :             tmp1 = w[je];
+   13400           0 :             i__2 = *m;
+   13401           0 :             for (j = je + 1; j <= i__2; ++j) {
+   13402           0 :                 if (w[j] < tmp1) {
+   13403             :                     ie = j;
+   13404             :                     tmp1 = w[j];
+   13405             :                 }
+   13406             :             }
+   13407             : 
+   13408           0 :             if (ie != 0) {
+   13409           0 :                 itmp1 = iblock[ie];
+   13410           0 :                 w[ie] = w[je];
+   13411           0 :                 iblock[ie] = iblock[je];
+   13412           0 :                 w[je] = tmp1;
+   13413           0 :                 iblock[je] = itmp1;
+   13414             :             }
+   13415             :         }
+   13416             :     }
+   13417             : 
+   13418           0 :     *info = 0;
+   13419           0 :     if (ncnvrg) {
+   13420           0 :         ++(*info);
+   13421             :     }
+   13422           0 :     if (toofew) {
+   13423           0 :         *info += 2;
+   13424             :     }
+   13425             :     return;
+   13426             : 
+   13427             : }
+   13428             : 
+   13429             : 
+   13430             : }
+   13431             : }
+   13432             : #include <cmath>
+   13433             : #include "blas/blas.h"
+   13434             : #include "lapack.h"
+   13435             : #include "lapack_limits.h"
+   13436             : 
+   13437             : #include "real.h"
+   13438             : 
+   13439             : #include "blas/blas.h"
+   13440             : namespace PLMD{
+   13441             : namespace lapack{
+   13442             : using namespace blas;
+   13443             : void
+   13444      570005 : PLUMED_BLAS_F77_FUNC(dstegr,DSTEGR)(const char *jobz, 
+   13445             :         const char *range, 
+   13446             :         int *n, 
+   13447             :         double *d__, 
+   13448             :         double *e, 
+   13449             :         double *vl, 
+   13450             :         double *vu, 
+   13451             :         int *il, 
+   13452             :         int *iu, 
+   13453             :         double *abstol, 
+   13454             :         int *m, 
+   13455             :         double *w, 
+   13456             :         double *z__, 
+   13457             :         int *ldz, 
+   13458             :         int *isuppz,
+   13459             :         double *work, 
+   13460             :         int *lwork, 
+   13461             :         int *iwork, 
+   13462             :         int *liwork, 
+   13463             :         int *info)
+   13464             : {
+   13465             :     int z_dim1, z_offset, i__1, i__2;
+   13466             :     double d__1, d__2;
+   13467      570005 :     int c__1 = 1;
+   13468             : 
+   13469             :     int i__, j;
+   13470             :     int jj;
+   13471             :     double eps, tol, tmp, rmin, rmax;
+   13472             :     int itmp;
+   13473             :     double tnrm;
+   13474             :     double scale;
+   13475             :     int iinfo, iindw;
+   13476             :     int lwmin;
+   13477             :     int wantz;
+   13478             :     int iindbl;
+   13479             :     int valeig,alleig,indeig;
+   13480             :     double safmin,minval;
+   13481             :     double bignum;
+   13482             :     int iindwk, indgrs;
+   13483             :     double thresh;
+   13484             :     int iinspl, indwrk, liwmin, nsplit;
+   13485             :     double smlnum;
+   13486             :     int lquery;
+   13487             : 
+   13488             : 
+   13489             :     --d__;
+   13490             :     --e;
+   13491      570005 :     --w;
+   13492      570005 :     z_dim1 = *ldz;
+   13493      570005 :     z_offset = 1 + z_dim1;
+   13494      570005 :     z__ -= z_offset;
+   13495      570005 :     --isuppz;
+   13496      570005 :     --work;
+   13497      570005 :     --iwork;
+   13498             : 
+   13499      570005 :     wantz = (*jobz=='V' || *jobz=='v');
+   13500      570005 :     alleig = (*range=='A' || *range=='a');
+   13501      570005 :     valeig = (*range=='V' || *range=='v');
+   13502      570005 :     indeig = (*range=='I' || *range=='i');
+   13503             : 
+   13504      570005 :     lquery = *lwork == -1 || *liwork == -1;
+   13505      570005 :     lwmin = *n * 17;
+   13506      570005 :     liwmin = *n * 10;
+   13507             : 
+   13508      570005 :     *info = 0;
+   13509      570005 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   13510           0 :         *info = -1;
+   13511      570005 :     } else if (! (alleig || valeig || indeig)) {
+   13512           0 :         *info = -2;
+   13513      570005 :     } else if (*n < 0) {
+   13514           0 :         *info = -3;
+   13515      570005 :     } else if (valeig && *n > 0 && *vu <= *vl) {
+   13516           0 :         *info = -7;
+   13517      570005 :     } else if (indeig && (*il < 1 || *il > *n)) {
+   13518           0 :         *info = -8;
+   13519      570005 :     } else if (indeig && (*iu < *il || *iu > *n)) {
+   13520           0 :         *info = -9;
+   13521      570005 :     } else if (*ldz < 1 || (wantz && *ldz < *n)) {
+   13522           0 :         *info = -14;
+   13523      570005 :     } else if (*lwork < lwmin && ! lquery) {
+   13524           0 :         *info = -17;
+   13525      570005 :     } else if (*liwork < liwmin && ! lquery) {
+   13526           0 :         *info = -19;
+   13527             :     }
+   13528      570005 :     if (*info == 0) {
+   13529      570005 :         work[1] = (double) lwmin;
+   13530      570005 :         iwork[1] = liwmin;
+   13531             :     }
+   13532             : 
+   13533      570005 :     if (*info != 0) {
+   13534             :         i__1 = -(*info);
+   13535             :         return;
+   13536      570005 :     } else if (lquery) {
+   13537             :         return;
+   13538             :     }
+   13539             : 
+   13540      570005 :     *m = 0;
+   13541      570005 :     if (*n == 0) {
+   13542             :         return;
+   13543             :     }
+   13544             : 
+   13545      570005 :     if (*n == 1) {
+   13546           0 :         if (alleig || indeig) {
+   13547           0 :             *m = 1;
+   13548           0 :             w[1] = d__[1];
+   13549             :         } else {
+   13550           0 :             if (*vl < d__[1] && *vu >= d__[1]) {
+   13551           0 :                 *m = 1;
+   13552           0 :                 w[1] = d__[1];
+   13553             :             }
+   13554             :         }
+   13555           0 :         if (wantz) {
+   13556           0 :             z__[z_dim1 + 1] = 1.;
+   13557             :         }
+   13558           0 :         return;
+   13559             :     }
+   13560             : 
+   13561             :     minval = PLUMED_GMX_DOUBLE_MIN;
+   13562             :     safmin = minval*(1.0+PLUMED_GMX_DOUBLE_EPS);
+   13563             :     eps = PLUMED_GMX_DOUBLE_EPS;
+   13564             :     smlnum = safmin / eps;
+   13565             :     bignum = 1. / smlnum;
+   13566             :     rmin =  std::sqrt(smlnum);
+   13567      570005 :     d__1 =  std::sqrt(bignum), d__2 = 1. / std::sqrt(sqrt(safmin));
+   13568             :     rmax = (d__1<d__2) ? d__1 : d__2;
+   13569      570005 :     scale = 1.;
+   13570      570005 :     tnrm = PLUMED_BLAS_F77_FUNC(dlanst,DLANST)("M", n, &d__[1], &e[1]);
+   13571      570005 :     if (tnrm > 0. && tnrm < rmin) {
+   13572           0 :         scale = rmin / tnrm;
+   13573      570005 :     } else if (tnrm > rmax) {
+   13574           0 :         scale = rmax / tnrm;
+   13575             :     }
+   13576      570005 :     if ( std::abs(scale-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+   13577           0 :         PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(n, &scale, &d__[1], &c__1);
+   13578           0 :         i__1 = *n - 1;
+   13579           0 :         PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__1, &scale, &e[1], &c__1);
+   13580           0 :         tnrm *= scale;
+   13581             :     }
+   13582             :     indgrs = 1;
+   13583      570005 :     indwrk = (*n << 1) + 1;
+   13584             : 
+   13585             :     iinspl = 1;
+   13586      570005 :     iindbl = *n + 1;
+   13587             :     iindw = (*n << 1) + 1;
+   13588      570005 :     iindwk = *n * 3 + 1;
+   13589             : 
+   13590      570005 :     thresh = eps * tnrm;
+   13591      570005 :     PLUMED_BLAS_F77_FUNC(dlarrex,DLARREX)(range, n, vl, vu, il, iu, &d__[1], &e[1], &thresh, &nsplit, &
+   13592      570005 :             iwork[iinspl], m, &w[1], &iwork[iindbl], &iwork[iindw], &work[
+   13593      570005 :             indgrs], &work[indwrk], &iwork[iindwk], &iinfo);
+   13594             :     
+   13595      570005 :     if (iinfo != 0) {
+   13596           0 :         *info = 1;
+   13597           0 :         return;
+   13598             :     }
+   13599             : 
+   13600      570005 :     if (wantz) {
+   13601      569961 :         d__1 = *abstol, d__2 = (double) (*n) * eps;
+   13602      569961 :         tol = (d__1>d__2) ? d__1 : d__2;
+   13603      569961 :         PLUMED_BLAS_F77_FUNC(dlarrvx,DLARRVX)(n, &d__[1], &e[1], &iwork[iinspl], m, &w[1], &iwork[iindbl], &
+   13604             :                 iwork[iindw], &work[indgrs], &tol, &z__[z_offset], ldz, &
+   13605             :                 isuppz[1], &work[indwrk], &iwork[iindwk], &iinfo);
+   13606      569961 :         if (iinfo != 0) {
+   13607           0 :             *info = 2;
+   13608           0 :             return;
+   13609             :         }
+   13610             :     }
+   13611             : 
+   13612      570005 :     i__1 = *m;
+   13613     1177662 :     for (j = 1; j <= i__1; ++j) {
+   13614      607657 :         itmp = iwork[iindbl + j - 1];
+   13615      607657 :         w[j] += e[iwork[iinspl + itmp - 1]];
+   13616             :     } 
+   13617             : 
+   13618      570005 :     if (std::abs(scale-1.0)>PLUMED_GMX_DOUBLE_EPS) {
+   13619           0 :         d__1 = 1. / scale;
+   13620           0 :         PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(m, &d__1, &w[1], &c__1);
+   13621             :     }
+   13622      570005 :     if (nsplit > 1) {
+   13623          16 :         i__1 = *m - 1;
+   13624         791 :         for (j = 1; j <= i__1; ++j) {
+   13625             :             i__ = 0;
+   13626         775 :             tmp = w[j];
+   13627         775 :             i__2 = *m;
+   13628       35106 :             for (jj = j + 1; jj <= i__2; ++jj) {
+   13629       34331 :                 if (w[jj] < tmp) {
+   13630             :                     i__ = jj;
+   13631             :                     tmp = w[jj];
+   13632             :                 }
+   13633             :             }
+   13634         775 :             if (i__ != 0) {
+   13635         638 :                 w[i__] = w[j];
+   13636         638 :                 w[j] = tmp;
+   13637         638 :                 if (wantz) {
+   13638         638 :                     PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 
+   13639         638 :                             + 1], &c__1);
+   13640         638 :                     itmp = isuppz[(i__ << 1) - 1];
+   13641         638 :                     isuppz[(i__ << 1) - 1] = isuppz[(j << 1) - 1];
+   13642         638 :                     isuppz[(j << 1) - 1] = itmp;
+   13643         638 :                     itmp = isuppz[i__ * 2];
+   13644         638 :                     isuppz[i__ * 2] = isuppz[j * 2];
+   13645         638 :                     isuppz[j * 2] = itmp;
+   13646             :                 }
+   13647             :             }
+   13648             :         }
+   13649             :     }
+   13650             : 
+   13651      570005 :     work[1] = (double) lwmin;
+   13652      570005 :     iwork[1] = liwmin;
+   13653      570005 :     return;
+   13654             : 
+   13655             : } 
+   13656             : }
+   13657             : }
+   13658             : #include <cmath>
+   13659             : #include "blas/blas.h"
+   13660             : #include "lapack.h"
+   13661             : #include "lapack_limits.h"
+   13662             : 
+   13663             : #include "real.h"
+   13664             : 
+   13665             : #include "blas/blas.h"
+   13666             : namespace PLMD{
+   13667             : namespace lapack{
+   13668             : using namespace blas;
+   13669             : void
+   13670           0 : PLUMED_BLAS_F77_FUNC(dstein,DSTEIN)(int *n, 
+   13671             :         double *d__, 
+   13672             :         double *e, 
+   13673             :         int *m, 
+   13674             :         double *w, 
+   13675             :         int *iblock,
+   13676             :         int *isplit, 
+   13677             :         double *z__,
+   13678             :         int *ldz, 
+   13679             :         double *work,
+   13680             :         int *iwork, 
+   13681             :         int *ifail,
+   13682             :         int *info)
+   13683             : {
+   13684             :     int z_dim1, z_offset, i__1, i__2, i__3;
+   13685             :     double d__2, d__3, d__4, d__5;
+   13686             : 
+   13687             :     int i__, j, b1, j1, bn;
+   13688             :     double xj, scl, eps, sep, nrm, tol;
+   13689             :     int its;
+   13690             :     double xjm, ztr, eps1;
+   13691             :     int jblk, nblk;
+   13692             :     int jmax;
+   13693             : 
+   13694             :     int iseed[4], gpind, iinfo;
+   13695             :     double ortol;
+   13696             :     int indrv1, indrv2, indrv3, indrv4, indrv5;
+   13697             :     int nrmchk;
+   13698             :     int blksiz;
+   13699             :     double onenrm, dtpcrt, pertol;
+   13700           0 :     int c__2 = 2;
+   13701           0 :     int c__1 = 1;
+   13702           0 :     int c_n1 = -1;
+   13703             : 
+   13704           0 :     --d__;
+   13705           0 :     --e;
+   13706           0 :     --w;
+   13707           0 :     --iblock;
+   13708           0 :     --isplit;
+   13709           0 :     z_dim1 = *ldz;
+   13710           0 :     z_offset = 1 + z_dim1;
+   13711           0 :     z__ -= z_offset;
+   13712           0 :     --work;
+   13713             :     --iwork;
+   13714           0 :     --ifail;
+   13715             : 
+   13716           0 :     *info = 0;
+   13717             : 
+   13718             :     xjm = 0.0;
+   13719           0 :     i__1 = *m;
+   13720           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   13721           0 :         ifail[i__] = 0;
+   13722             :     }
+   13723             : 
+   13724           0 :     if (*n < 0) {
+   13725           0 :         *info = -1;
+   13726           0 :     } else if (*m < 0 || *m > *n) {
+   13727           0 :         *info = -4;
+   13728           0 :     } else if (*ldz < (*n)) {
+   13729           0 :         *info = -9;
+   13730             :     } else {
+   13731             :         i__1 = *m;
+   13732           0 :         for (j = 2; j <= i__1; ++j) {
+   13733           0 :             if (iblock[j] < iblock[j - 1]) {
+   13734           0 :                 *info = -6;
+   13735           0 :                 break;
+   13736             :             }
+   13737           0 :             if (iblock[j] == iblock[j - 1] && w[j] < w[j - 1]) {
+   13738           0 :                 *info = -5;
+   13739           0 :                 break;
+   13740             :             }
+   13741             :         }
+   13742             :     }
+   13743             : 
+   13744           0 :     if (*info != 0) {
+   13745             :         return;
+   13746             :     }
+   13747             : 
+   13748           0 :     if (*n == 0 || *m == 0) {
+   13749             :         return;
+   13750           0 :     } else if (*n == 1) {
+   13751           0 :         z__[z_dim1 + 1] = 1.;
+   13752           0 :         return;
+   13753             :     }
+   13754             : 
+   13755             :     eps = PLUMED_GMX_DOUBLE_EPS;
+   13756             : 
+   13757           0 :     for (i__ = 1; i__ <= 4; ++i__) {
+   13758           0 :         iseed[i__ - 1] = 1;
+   13759             :     }
+   13760             : 
+   13761             :     indrv1 = 0;
+   13762             :     indrv2 = indrv1 + *n;
+   13763           0 :     indrv3 = indrv2 + *n;
+   13764           0 :     indrv4 = indrv3 + *n;
+   13765           0 :     indrv5 = indrv4 + *n;
+   13766             : 
+   13767             :     j1 = 1;
+   13768           0 :     i__1 = iblock[*m];
+   13769           0 :     for (nblk = 1; nblk <= i__1; ++nblk) {
+   13770             : 
+   13771           0 :         if (nblk == 1) {
+   13772             :             b1 = 1;
+   13773             :         } else {
+   13774           0 :             b1 = isplit[nblk - 1] + 1;
+   13775             :         }
+   13776           0 :         bn = isplit[nblk];
+   13777           0 :         blksiz = bn - b1 + 1;
+   13778           0 :         if (blksiz == 1) {
+   13779           0 :             continue;
+   13780             :         }
+   13781             :         gpind = b1;
+   13782             : 
+   13783           0 :         onenrm = std::abs(d__[b1]) + std::abs(e[b1]);
+   13784             :         d__3 = onenrm;
+   13785           0 :         d__4 = std::abs(d__[bn]) + std::abs(e[bn - 1]);
+   13786           0 :         onenrm = (d__3>d__4) ? d__3 : d__4;
+   13787             :         i__2 = bn - 1;
+   13788           0 :         for (i__ = b1 + 1; i__ <= i__2; ++i__) {
+   13789             :           d__4 = onenrm;
+   13790           0 :           d__5 = std::abs(d__[i__]) + std::abs(e[i__ - 1]) + std::abs(e[i__]);
+   13791           0 :             onenrm = (d__4>d__5) ? d__4 : d__5;
+   13792             :         }
+   13793           0 :         ortol = onenrm * .001;
+   13794             : 
+   13795           0 :         dtpcrt =  std::sqrt(.1 / blksiz);
+   13796             : 
+   13797             :         jblk = 0;
+   13798           0 :         i__2 = *m;
+   13799           0 :         for (j = j1; j <= i__2; ++j) {
+   13800           0 :             if (iblock[j] != nblk) {
+   13801             :                 j1 = j;
+   13802             :                 break;
+   13803             :             }
+   13804           0 :             ++jblk;
+   13805           0 :             xj = w[j];
+   13806             : 
+   13807           0 :             if (blksiz == 1) {
+   13808           0 :                 work[indrv1 + 1] = 1.;
+   13809           0 :                 goto L120;
+   13810             :             }
+   13811             : 
+   13812           0 :             if (jblk > 1) {
+   13813           0 :                 eps1 = std::abs(eps * xj);
+   13814           0 :                 pertol = eps1 * 10.;
+   13815           0 :                 sep = xj - xjm;
+   13816           0 :                 if (sep < pertol) {
+   13817           0 :                     xj = xjm + pertol;
+   13818             :                 }
+   13819             :             }
+   13820             : 
+   13821             :             its = 0;
+   13822             :             nrmchk = 0;
+   13823             : 
+   13824           0 :             PLUMED_BLAS_F77_FUNC(dlarnv,DLARNV)(&c__2, iseed, &blksiz, &work[indrv1 + 1]);
+   13825             : 
+   13826           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&blksiz, &d__[b1], &c__1, &work[indrv4 + 1], &c__1);
+   13827           0 :             i__3 = blksiz - 1;
+   13828           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__3, &e[b1], &c__1, &work[indrv2 + 2], &c__1);
+   13829           0 :             i__3 = blksiz - 1;
+   13830           0 :             PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__3, &e[b1], &c__1, &work[indrv3 + 1], &c__1);
+   13831             : 
+   13832           0 :             tol = 0.;
+   13833           0 :             PLUMED_BLAS_F77_FUNC(dlagtf,DLAGTF)(&blksiz, &work[indrv4 + 1], &xj, &work[indrv2 + 2], &work[
+   13834           0 :                     indrv3 + 1], &tol, &work[indrv5 + 1], &iwork[1], &iinfo);
+   13835             : 
+   13836           0 : L70:
+   13837           0 :             ++its;
+   13838           0 :             if (its > 5) {
+   13839           0 :                 goto L100;
+   13840             :             }
+   13841             : 
+   13842             :             d__2 = eps;
+   13843           0 :             d__3 = std::abs(work[indrv4 + blksiz]);
+   13844           0 :             scl = blksiz * onenrm * ((d__2>d__3) ? d__2 : d__3) / PLUMED_BLAS_F77_FUNC(dasum,DASUM)(&blksiz, &work[
+   13845             :                     indrv1 + 1], &c__1);
+   13846           0 :             PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&blksiz, &scl, &work[indrv1 + 1], &c__1);
+   13847             : 
+   13848           0 :             PLUMED_BLAS_F77_FUNC(dlagts,DLAGTS)(&c_n1, &blksiz, &work[indrv4 + 1], &work[indrv2 + 2], &
+   13849             :                     work[indrv3 + 1], &work[indrv5 + 1], &iwork[1], &work[
+   13850             :                     indrv1 + 1], &tol, &iinfo);
+   13851             : 
+   13852           0 :             if (jblk == 1) {
+   13853           0 :                 goto L90;
+   13854             :             }
+   13855           0 :             if (std::abs(xj - xjm) > ortol) {
+   13856             :                 gpind = j;
+   13857             :             }
+   13858           0 :             if (gpind != j) {
+   13859           0 :                 i__3 = j - 1;
+   13860           0 :                 for (i__ = gpind; i__ <= i__3; ++i__) {
+   13861           0 :                     ztr = -PLUMED_BLAS_F77_FUNC(ddot,DDOT)(&blksiz, &work[indrv1 + 1], &c__1, &z__[b1 + 
+   13862           0 :                             i__ * z_dim1], &c__1);
+   13863           0 :                     PLUMED_BLAS_F77_FUNC(daxpy,DAXPY)(&blksiz, &ztr, &z__[b1 + i__ * z_dim1], &c__1, &
+   13864             :                             work[indrv1 + 1], &c__1);
+   13865             :                 }
+   13866             :             }
+   13867             : 
+   13868           0 : L90:
+   13869           0 :             jmax = PLUMED_BLAS_F77_FUNC(idamax,IDAMAX)(&blksiz, &work[indrv1 + 1], &c__1);
+   13870           0 :             nrm = std::abs(work[indrv1 + jmax]);
+   13871             : 
+   13872           0 :             if (nrm < dtpcrt) {
+   13873           0 :                 goto L70;
+   13874             :             }
+   13875           0 :             ++nrmchk;
+   13876           0 :             if (nrmchk < 3) {
+   13877           0 :                 goto L70;
+   13878             :             }
+   13879             : 
+   13880           0 :             goto L110;
+   13881             : 
+   13882             : L100:
+   13883           0 :             ++(*info);
+   13884           0 :             ifail[*info] = j;
+   13885             : 
+   13886           0 : L110:
+   13887           0 :             scl = 1. / PLUMED_BLAS_F77_FUNC(dnrm2,DNRM2)(&blksiz, &work[indrv1 + 1], &c__1);
+   13888           0 :             jmax = PLUMED_BLAS_F77_FUNC(idamax,IDAMAX)(&blksiz, &work[indrv1 + 1], &c__1);
+   13889           0 :             if (work[indrv1 + jmax] < 0.) {
+   13890           0 :                 scl = -scl;
+   13891             :             }
+   13892           0 :             PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&blksiz, &scl, &work[indrv1 + 1], &c__1);
+   13893           0 : L120:
+   13894           0 :             i__3 = *n;
+   13895           0 :             for (i__ = 1; i__ <= i__3; ++i__) {
+   13896           0 :                 z__[i__ + j * z_dim1] = 0.;
+   13897             :             }
+   13898           0 :             i__3 = blksiz;
+   13899           0 :             for (i__ = 1; i__ <= i__3; ++i__) {
+   13900           0 :                 z__[b1 + i__ - 1 + j * z_dim1] = work[indrv1 + i__];
+   13901             :             }
+   13902             : 
+   13903           0 :             xjm = xj;
+   13904             :         }
+   13905             :     }
+   13906             : 
+   13907             :     return;
+   13908             : 
+   13909             : }
+   13910             : 
+   13911             : 
+   13912             : }
+   13913             : }
+   13914             : #include <cmath>
+   13915             : #include "real.h"
+   13916             : 
+   13917             : #include "blas/blas.h"
+   13918             : #include "lapack.h"
+   13919             : #include "lapack_limits.h"
+   13920             : 
+   13921             : #include "blas/blas.h"
+   13922             : namespace PLMD{
+   13923             : namespace lapack{
+   13924             : using namespace blas;
+   13925             : void
+   13926           0 : PLUMED_BLAS_F77_FUNC(dsteqr,DSTEQR)(const char *    compz, 
+   13927             :         int *     n, 
+   13928             :         double *  d__, 
+   13929             :         double *  e, 
+   13930             :         double *  z__, 
+   13931             :         int *     ldz, 
+   13932             :         double *  work, 
+   13933             :         int *     info)
+   13934             : {
+   13935           0 :     double c_b9 = 0.;
+   13936           0 :     double c_b10 = 1.;
+   13937           0 :     int c__0 = 0;
+   13938           0 :     int c__1 = 1;
+   13939           0 :     int c__2 = 2;
+   13940             :     int z_dim1, z_offset, i__1, i__2;
+   13941             :     double d__1, d__2;
+   13942             : 
+   13943             :     double b, c__, f, g;
+   13944             :     int i__, j, k, l, m;
+   13945             :     double p, r__, s;
+   13946             :     int l1, ii, mm, lm1, mm1, nm1;
+   13947             :     double rt1, rt2, eps;
+   13948             :     int lsv;
+   13949             :     double tst, eps2;
+   13950             :     int lend, jtot;
+   13951             :     double anorm;
+   13952             :     int lendm1, lendp1;
+   13953             :     int iscale;
+   13954             :     double safmin,minval;
+   13955             :     double safmax;
+   13956             :     int lendsv;
+   13957             :     double ssfmin;
+   13958             :     int nmaxit, icompz;
+   13959             :     double ssfmax;
+   13960             : 
+   13961             : 
+   13962           0 :     --d__;
+   13963           0 :     --e;
+   13964           0 :     z_dim1 = *ldz;
+   13965           0 :     z_offset = 1 + z_dim1;
+   13966           0 :     z__ -= z_offset;
+   13967           0 :     --work;
+   13968             : 
+   13969           0 :     *info = 0;
+   13970             : 
+   13971           0 :     if (*compz=='N' || *compz=='n') {
+   13972             :         icompz = 0;
+   13973           0 :     } else if (*compz=='V' || *compz=='v') {
+   13974             :         icompz = 1;
+   13975             :     } else if (*compz=='I' || *compz=='i') {
+   13976             :         icompz = 2;
+   13977             :     } else {
+   13978             :         icompz = -1;
+   13979             :     }
+   13980             :     if (icompz < 0) {
+   13981           0 :         *info = -1;
+   13982           0 :     } else if (*n < 0) {
+   13983           0 :         *info = -2;
+   13984           0 :     } else if (*ldz < 1 || (icompz > 0 && *ldz < ((*n>1) ? *n : 1))) {
+   13985           0 :         *info = -6;
+   13986             :     }
+   13987           0 :     if (*info != 0) {
+   13988             :         return;
+   13989             :     }
+   13990             : 
+   13991             : 
+   13992           0 :     if (*n == 0) {
+   13993             :         return;
+   13994             :     }
+   13995             : 
+   13996           0 :     if (*n == 1) {
+   13997           0 :         if (icompz == 2) {
+   13998           0 :             z__[z_dim1 + 1] = 1.;
+   13999             :         }
+   14000           0 :         return;
+   14001             :     }
+   14002             : 
+   14003             :     eps = PLUMED_GMX_DOUBLE_EPS;
+   14004             :     d__1 = eps;
+   14005             :     eps2 = d__1 * d__1;
+   14006             :     minval = PLUMED_GMX_DOUBLE_MIN;
+   14007             :     safmin = minval*(1.0+PLUMED_GMX_DOUBLE_EPS);
+   14008             : 
+   14009             :     safmax = 1. / safmin;
+   14010           0 :     ssfmax =  std::sqrt(safmax) / 3.;
+   14011           0 :     ssfmin =  std::sqrt(safmin) / eps2;
+   14012             : 
+   14013           0 :     if (icompz == 2) {
+   14014           0 :         PLUMED_BLAS_F77_FUNC(dlaset,DLASET)("Full", n, n, &c_b9, &c_b10, &z__[z_offset], ldz);
+   14015             :     }
+   14016             : 
+   14017           0 :     nmaxit = *n * 30;
+   14018             :     jtot = 0;
+   14019             : 
+   14020             :     l1 = 1;
+   14021           0 :     nm1 = *n - 1;
+   14022             : 
+   14023           0 : L10:
+   14024           0 :     if (l1 > *n) {
+   14025           0 :         goto L160;
+   14026             :     }
+   14027           0 :     if (l1 > 1) {
+   14028           0 :         e[l1 - 1] = 0.;
+   14029             :     }
+   14030           0 :     if (l1 <= nm1) {
+   14031           0 :         i__1 = nm1;
+   14032           0 :         for (m = l1; m <= i__1; ++m) {
+   14033           0 :             tst = std::abs(e[m]);
+   14034           0 :             if (std::abs(tst)<PLUMED_GMX_DOUBLE_MIN) {
+   14035           0 :                 goto L30;
+   14036             :             }
+   14037           0 :             if (tst <=  std::sqrt(std::abs(d__[m])) * std::sqrt(std::abs(d__[m + 1])) * eps) {
+   14038           0 :                 e[m] = 0.;
+   14039           0 :                 goto L30;
+   14040             :             }
+   14041             :         }
+   14042             :     }
+   14043           0 :     m = *n;
+   14044             : 
+   14045           0 : L30:
+   14046             :     l = l1;
+   14047             :     lsv = l;
+   14048             :     lend = m;
+   14049             :     lendsv = lend;
+   14050           0 :     l1 = m + 1;
+   14051           0 :     if (lend == l) {
+   14052           0 :         goto L10;
+   14053             :     }
+   14054             : 
+   14055           0 :     i__1 = lend - l + 1;
+   14056           0 :     anorm = PLUMED_BLAS_F77_FUNC(dlanst,DLANST)("I", &i__1, &d__[l], &e[l]);
+   14057             :     iscale = 0;
+   14058           0 :     if (std::abs(anorm)<PLUMED_GMX_DOUBLE_MIN) {
+   14059           0 :         goto L10;
+   14060             :     }
+   14061           0 :     if (anorm > ssfmax) {
+   14062             :         iscale = 1;
+   14063           0 :         i__1 = lend - l + 1;
+   14064           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, 
+   14065             :                 info);
+   14066           0 :         i__1 = lend - l;
+   14067           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, 
+   14068             :                 info);
+   14069           0 :     } else if (anorm < ssfmin) {
+   14070             :         iscale = 2;
+   14071           0 :         i__1 = lend - l + 1;
+   14072           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, 
+   14073             :                 info);
+   14074           0 :         i__1 = lend - l;
+   14075           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, 
+   14076             :                 info);
+   14077             :     }
+   14078             : 
+   14079           0 :     if (std::abs(d__[lend]) < std::abs(d__[l])) {
+   14080             :         lend = lsv;
+   14081             :         l = lendsv;
+   14082             :     }
+   14083             : 
+   14084           0 :     if (lend > l) {
+   14085             : 
+   14086           0 : L40:
+   14087           0 :         if (l != lend) {
+   14088           0 :             lendm1 = lend - 1;
+   14089           0 :             i__1 = lendm1;
+   14090           0 :             for (m = l; m <= i__1; ++m) {
+   14091           0 :                 d__2 = std::abs(e[m]);
+   14092           0 :                 tst = d__2 * d__2;
+   14093           0 :                 if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m+ 1]) + safmin) {
+   14094           0 :                     goto L60;
+   14095             :                 }
+   14096             :             }
+   14097             :         }
+   14098             : 
+   14099             :         m = lend;
+   14100             : 
+   14101           0 : L60:
+   14102           0 :         if (m < lend) {
+   14103           0 :             e[m] = 0.;
+   14104             :         }
+   14105           0 :         p = d__[l];
+   14106           0 :         if (m == l) {
+   14107           0 :             goto L80;
+   14108             :         }
+   14109             : 
+   14110           0 :         if (m == l + 1) {
+   14111           0 :             if (icompz > 0) {
+   14112           0 :                 PLUMED_BLAS_F77_FUNC(dlaev2,DLAEV2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2, &c__, &s);
+   14113           0 :                 work[l] = c__;
+   14114           0 :                 work[*n - 1 + l] = s;
+   14115           0 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "B", n, &c__2, &work[l], &work[*n - 1 + l], &
+   14116           0 :                         z__[l * z_dim1 + 1], ldz);
+   14117             :             } else {
+   14118           0 :                 PLUMED_BLAS_F77_FUNC(dlae2,DLAE2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2);
+   14119             :             }
+   14120           0 :             d__[l] = rt1;
+   14121           0 :             d__[l + 1] = rt2;
+   14122           0 :             e[l] = 0.;
+   14123           0 :             l += 2;
+   14124           0 :             if (l <= lend) {
+   14125           0 :                 goto L40;
+   14126             :             }
+   14127           0 :             goto L140;
+   14128             :         }
+   14129             : 
+   14130           0 :         if (jtot == nmaxit) {
+   14131           0 :             goto L140;
+   14132             :         }
+   14133           0 :         ++jtot;
+   14134             : 
+   14135           0 :         g = (d__[l + 1] - p) / (e[l] * 2.);
+   14136           0 :         r__ = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(&g, &c_b10);
+   14137           0 :         g = d__[m] - p + e[l] / (g + ( (g>0) ? r__ : -r__ ) );
+   14138             : 
+   14139           0 :         s = 1.;
+   14140           0 :         c__ = 1.;
+   14141             :         p = 0.;
+   14142             : 
+   14143           0 :         mm1 = m - 1;
+   14144           0 :         i__1 = l;
+   14145           0 :         for (i__ = mm1; i__ >= i__1; --i__) {
+   14146           0 :             f = s * e[i__];
+   14147           0 :             b = c__ * e[i__];
+   14148           0 :             PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&g, &f, &c__, &s, &r__);
+   14149           0 :             if (i__ != m - 1) {
+   14150           0 :                 e[i__ + 1] = r__;
+   14151             :             }
+   14152           0 :             g = d__[i__ + 1] - p;
+   14153           0 :             r__ = (d__[i__] - g) * s + c__ * 2. * b;
+   14154           0 :             p = s * r__;
+   14155           0 :             d__[i__ + 1] = g + p;
+   14156           0 :             g = c__ * r__ - b;
+   14157             : 
+   14158           0 :             if (icompz > 0) {
+   14159           0 :                 work[i__] = c__;
+   14160           0 :                 work[*n - 1 + i__] = -s;
+   14161             :             }
+   14162             :         }
+   14163             : 
+   14164           0 :         if (icompz > 0) {
+   14165           0 :             mm = m - l + 1;
+   14166           0 :             PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "B", n, &mm, &work[l], &work[*n - 1 + l], &z__[l 
+   14167           0 :                     * z_dim1 + 1], ldz);
+   14168             :         }
+   14169             : 
+   14170           0 :         d__[l] -= p;
+   14171           0 :         e[l] = g;
+   14172           0 :         goto L40;
+   14173             : 
+   14174             : L80:
+   14175             :         d__[l] = p;
+   14176             : 
+   14177           0 :         ++l;
+   14178           0 :         if (l <= lend) {
+   14179           0 :             goto L40;
+   14180             :         }
+   14181           0 :         goto L140;
+   14182             : 
+   14183             :     } else {
+   14184             : 
+   14185           0 : L90:
+   14186           0 :         if (l != lend) {
+   14187           0 :             lendp1 = lend + 1;
+   14188           0 :             i__1 = lendp1;
+   14189           0 :             for (m = l; m >= i__1; --m) {
+   14190           0 :                 d__2 = std::abs(e[m - 1]);
+   14191           0 :                 tst = d__2 * d__2;
+   14192           0 :                 if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m- 1]) + safmin) {
+   14193           0 :                     goto L110;
+   14194             :                 }
+   14195             :             }
+   14196             :         }
+   14197             : 
+   14198             :         m = lend;
+   14199             : 
+   14200           0 : L110:
+   14201           0 :         if (m > lend) {
+   14202           0 :             e[m - 1] = 0.;
+   14203             :         }
+   14204           0 :         p = d__[l];
+   14205           0 :         if (m == l) {
+   14206           0 :             goto L130;
+   14207             :         }
+   14208           0 :         if (m == l - 1) {
+   14209           0 :             if (icompz > 0) {
+   14210           0 :                 PLUMED_BLAS_F77_FUNC(dlaev2,DLAEV2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2, &c__, &s)
+   14211             :                         ;
+   14212           0 :                 work[m] = c__;
+   14213           0 :                 work[*n - 1 + m] = s;
+   14214           0 :                 PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "F", n, &c__2, &work[m], &work[*n - 1 + m], &
+   14215           0 :                         z__[(l - 1) * z_dim1 + 1], ldz);
+   14216             :             } else {
+   14217           0 :                 PLUMED_BLAS_F77_FUNC(dlae2,DLAE2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2);
+   14218             :             }
+   14219           0 :             d__[l - 1] = rt1;
+   14220           0 :             d__[l] = rt2;
+   14221           0 :             e[l - 1] = 0.;
+   14222           0 :             l += -2;
+   14223           0 :             if (l >= lend) {
+   14224           0 :                 goto L90;
+   14225             :             }
+   14226           0 :             goto L140;
+   14227             :         }
+   14228             : 
+   14229           0 :         if (jtot == nmaxit) {
+   14230           0 :             goto L140;
+   14231             :         }
+   14232           0 :         ++jtot;
+   14233             : 
+   14234           0 :         g = (d__[l - 1] - p) / (e[l - 1] * 2.);
+   14235           0 :         r__ = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(&g, &c_b10);
+   14236           0 :         g = d__[m] - p + e[l - 1] / (g + ( (g>0) ? r__ : -r__ ));
+   14237             : 
+   14238           0 :         s = 1.;
+   14239           0 :         c__ = 1.;
+   14240             :         p = 0.;
+   14241             : 
+   14242             :         lm1 = l - 1;
+   14243           0 :         i__1 = lm1;
+   14244           0 :         for (i__ = m; i__ <= i__1; ++i__) {
+   14245           0 :             f = s * e[i__];
+   14246           0 :             b = c__ * e[i__];
+   14247           0 :             PLUMED_BLAS_F77_FUNC(dlartg,DLARTG)(&g, &f, &c__, &s, &r__);
+   14248           0 :             if (i__ != m) {
+   14249           0 :                 e[i__ - 1] = r__;
+   14250             :             }
+   14251           0 :             g = d__[i__] - p;
+   14252           0 :             r__ = (d__[i__ + 1] - g) * s + c__ * 2. * b;
+   14253           0 :             p = s * r__;
+   14254           0 :             d__[i__] = g + p;
+   14255           0 :             g = c__ * r__ - b;
+   14256             : 
+   14257           0 :             if (icompz > 0) {
+   14258           0 :                 work[i__] = c__;
+   14259           0 :                 work[*n - 1 + i__] = s;
+   14260             :             }
+   14261             :         }
+   14262             : 
+   14263           0 :         if (icompz > 0) {
+   14264           0 :             mm = l - m + 1;
+   14265           0 :             PLUMED_BLAS_F77_FUNC(dlasr,DLASR)("R", "V", "F", n, &mm, &work[m], &work[*n - 1 + m], &z__[m 
+   14266           0 :                     * z_dim1 + 1], ldz);
+   14267             :         }
+   14268             : 
+   14269           0 :         d__[l] -= p;
+   14270           0 :         e[lm1] = g;
+   14271           0 :         goto L90;
+   14272             : 
+   14273             : L130:
+   14274             :         d__[l] = p;
+   14275             : 
+   14276           0 :         --l;
+   14277           0 :         if (l >= lend) {
+   14278           0 :             goto L90;
+   14279             :         }
+   14280           0 :         goto L140;
+   14281             : 
+   14282             :     }
+   14283             : 
+   14284           0 : L140:
+   14285           0 :     if (iscale == 1) {
+   14286           0 :         i__1 = lendsv - lsv + 1;
+   14287           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], 
+   14288             :                 n, info);
+   14289           0 :         i__1 = lendsv - lsv;
+   14290           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &e[lsv], n, 
+   14291             :                 info);
+   14292           0 :     } else if (iscale == 2) {
+   14293           0 :         i__1 = lendsv - lsv + 1;
+   14294           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], 
+   14295             :                 n, info);
+   14296           0 :         i__1 = lendsv - lsv;
+   14297           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &e[lsv], n, 
+   14298             :                 info);
+   14299             :     }
+   14300             : 
+   14301           0 :     if (jtot < nmaxit) {
+   14302           0 :         goto L10;
+   14303             :     }
+   14304           0 :     i__1 = *n - 1;
+   14305           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   14306           0 :         if (std::abs(e[i__])>PLUMED_GMX_DOUBLE_MIN) {
+   14307           0 :             ++(*info);
+   14308             :         }
+   14309             :     }
+   14310           0 :     goto L190;
+   14311             : 
+   14312             : L160:
+   14313           0 :     if (icompz == 0) {
+   14314             : 
+   14315           0 :         PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("I", n, &d__[1], info);
+   14316             : 
+   14317             :     } else {
+   14318             : 
+   14319           0 :         i__1 = *n;
+   14320           0 :         for (ii = 2; ii <= i__1; ++ii) {
+   14321           0 :             i__ = ii - 1;
+   14322             :             k = i__;
+   14323           0 :             p = d__[i__];
+   14324           0 :             i__2 = *n;
+   14325           0 :             for (j = ii; j <= i__2; ++j) {
+   14326           0 :                 if (d__[j] < p) {
+   14327             :                     k = j;
+   14328             :                     p = d__[j];
+   14329             :                 }
+   14330             :             }
+   14331           0 :             if (k != i__) {
+   14332           0 :                 d__[k] = d__[i__];
+   14333           0 :                 d__[i__] = p;
+   14334           0 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[k * z_dim1 + 1],
+   14335             :                          &c__1);
+   14336             :             }
+   14337             :         }
+   14338             :     }
+   14339             : 
+   14340           0 : L190:
+   14341             :     return;
+   14342             : }
+   14343             : 
+   14344             : 
+   14345             : }
+   14346             : }
+   14347             : #include <cmath>
+   14348             : #include "lapack.h"
+   14349             : #include "lapack_limits.h"
+   14350             : 
+   14351             : #include "real.h"
+   14352             : 
+   14353             : #include "blas/blas.h"
+   14354             : namespace PLMD{
+   14355             : namespace lapack{
+   14356             : using namespace blas;
+   14357             : void
+   14358           0 : PLUMED_BLAS_F77_FUNC(dsterf,DSTERF)(int *n, 
+   14359             :         double *d__, 
+   14360             :         double *e, 
+   14361             :         int *info)
+   14362             : {
+   14363             :     int i__1;
+   14364             :     double d__1;
+   14365             : 
+   14366             :     double c__;
+   14367             :     int i__, l, m;
+   14368             :     double p, r__, s;
+   14369             :     int l1;
+   14370             :     double bb, rt1, rt2, eps, rte;
+   14371             :     int lsv;
+   14372             :     double eps2, oldc;
+   14373             :     int lend, jtot;
+   14374             :     double gamma, alpha, sigma, anorm;
+   14375             :       int iscale;
+   14376             :     double oldgam;
+   14377             :     double safmax;
+   14378             :     int lendsv;
+   14379             :     double ssfmin;
+   14380             :     int nmaxit;
+   14381             :     double ssfmax;
+   14382           0 :     int c__0 = 0;
+   14383           0 :     int c__1 = 1;
+   14384           0 :     double c_b32 = 1.;
+   14385             :     const double safmin = PLUMED_GMX_DOUBLE_MIN*(1.0+PLUMED_GMX_DOUBLE_EPS);
+   14386             : 
+   14387           0 :     --e;
+   14388           0 :     --d__;
+   14389             : 
+   14390           0 :     *info = 0;
+   14391             : 
+   14392           0 :     if (*n < 0) {
+   14393           0 :         *info = -1;
+   14394             :         i__1 = -(*info);
+   14395           0 :         return;
+   14396             :     }
+   14397           0 :     if (*n <= 1) {
+   14398             :         return;
+   14399             :     }
+   14400             : 
+   14401             :     eps = PLUMED_GMX_DOUBLE_EPS;
+   14402             :     d__1 = eps;
+   14403             :     eps2 = d__1 * d__1;
+   14404             :     safmax = 1. / safmin;
+   14405           0 :     ssfmax =  std::sqrt(safmax) / 3.;
+   14406           0 :     ssfmin =  std::sqrt(safmin) / eps2;
+   14407             : 
+   14408           0 :     nmaxit = *n * 30;
+   14409           0 :     sigma = 0.;
+   14410             :     jtot = 0;
+   14411             : 
+   14412             :     l1 = 1;
+   14413             : 
+   14414           0 : L10:
+   14415           0 :     if (l1 > *n) {
+   14416           0 :       PLUMED_BLAS_F77_FUNC(dlasrt,DLASRT)("I", n, &d__[1], info);
+   14417           0 :       return;
+   14418             :     }
+   14419           0 :     if (l1 > 1) {
+   14420           0 :         e[l1 - 1] = 0.;
+   14421             :     }
+   14422           0 :     i__1 = *n - 1;
+   14423           0 :     for (m = l1; m <= i__1; ++m) {
+   14424           0 :         if (std::abs(e[m]) <=  std::sqrt(std::abs(d__[m])) * 
+   14425           0 :                  std::sqrt(std::abs(d__[m + 1])) * eps) {
+   14426           0 :             e[m] = 0.;
+   14427           0 :             goto L30;
+   14428             :         }
+   14429             :     }
+   14430           0 :     m = *n;
+   14431             : 
+   14432           0 : L30:
+   14433             :     l = l1;
+   14434             :     lsv = l;
+   14435             :     lend = m;
+   14436             :     lendsv = lend;
+   14437           0 :     l1 = m + 1;
+   14438           0 :     if (lend == l) {
+   14439           0 :         goto L10;
+   14440             :     }
+   14441             : 
+   14442           0 :     i__1 = lend - l + 1;
+   14443           0 :     anorm = PLUMED_BLAS_F77_FUNC(dlanst,DLANST)("I", &i__1, &d__[l], &e[l]);
+   14444             :     iscale = 0;
+   14445           0 :     if (anorm > ssfmax) {
+   14446             :         iscale = 1;
+   14447           0 :         i__1 = lend - l + 1;
+   14448           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, 
+   14449             :                 info);
+   14450           0 :         i__1 = lend - l;
+   14451           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, 
+   14452             :                 info);
+   14453           0 :     } else if (anorm < ssfmin) {
+   14454             :         iscale = 2;
+   14455           0 :         i__1 = lend - l + 1;
+   14456           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, 
+   14457             :                 info);
+   14458           0 :         i__1 = lend - l;
+   14459           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, 
+   14460             :                 info);
+   14461             :     }
+   14462             : 
+   14463           0 :     i__1 = lend - 1;
+   14464           0 :     for (i__ = l; i__ <= i__1; ++i__) {
+   14465           0 :         d__1 = e[i__];
+   14466           0 :         e[i__] = d__1 * d__1;
+   14467             :     }
+   14468             : 
+   14469           0 :     if (std::abs(d__[lend]) < std::abs(d__[l])) {
+   14470             :         lend = lsv;
+   14471             :         l = lendsv;
+   14472             :     }
+   14473             : 
+   14474           0 :     if (lend >= l) {
+   14475             : 
+   14476           0 : L50:
+   14477           0 :         if (l != lend) {
+   14478           0 :             i__1 = lend - 1;
+   14479           0 :             for (m = l; m <= i__1; ++m) {
+   14480           0 :                 if (std::abs(e[m]) <= eps2 * std::abs(d__[m] * d__[m + 1])) {
+   14481           0 :                     goto L70;
+   14482             :                 }
+   14483             :             }
+   14484             :         }
+   14485             :         m = lend;
+   14486             : 
+   14487           0 : L70:
+   14488           0 :         if (m < lend) {
+   14489           0 :             e[m] = 0.;
+   14490             :         }
+   14491           0 :         p = d__[l];
+   14492           0 :         if (m == l) {
+   14493           0 :             goto L90;
+   14494             :         }
+   14495           0 :         if (m == l + 1) {
+   14496           0 :             rte =  std::sqrt(e[l]);
+   14497           0 :             PLUMED_BLAS_F77_FUNC(dlae2,DLAE2)(&d__[l], &rte, &d__[l + 1], &rt1, &rt2);
+   14498           0 :             d__[l] = rt1;
+   14499           0 :             d__[l + 1] = rt2;
+   14500           0 :             e[l] = 0.;
+   14501           0 :             l += 2;
+   14502           0 :             if (l <= lend) {
+   14503           0 :                 goto L50;
+   14504             :             }
+   14505           0 :             goto L150;
+   14506             :         }
+   14507             : 
+   14508           0 :         if (jtot == nmaxit) {
+   14509           0 :             goto L150;
+   14510             :         }
+   14511           0 :         ++jtot;
+   14512             : 
+   14513           0 :         rte =  std::sqrt(e[l]);
+   14514           0 :         sigma = (d__[l + 1] - p) / (rte * 2.);
+   14515           0 :         r__ = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(&sigma, &c_b32);
+   14516           0 :         sigma = p - rte / (sigma + ( (sigma>0) ? r__ : -r__));
+   14517             : 
+   14518             :         c__ = 1.;
+   14519             :         s = 0.;
+   14520           0 :         gamma = d__[m] - sigma;
+   14521           0 :         p = gamma * gamma;
+   14522             : 
+   14523           0 :         i__1 = l;
+   14524           0 :         for (i__ = m - 1; i__ >= i__1; --i__) {
+   14525           0 :             bb = e[i__];
+   14526           0 :             r__ = p + bb;
+   14527           0 :             if (i__ != m - 1) {
+   14528           0 :                 e[i__ + 1] = s * r__;
+   14529             :             }
+   14530             :             oldc = c__;
+   14531           0 :             c__ = p / r__;
+   14532           0 :             s = bb / r__;
+   14533             :             oldgam = gamma;
+   14534           0 :             alpha = d__[i__];
+   14535           0 :             gamma = c__ * (alpha - sigma) - s * oldgam;
+   14536           0 :             d__[i__ + 1] = oldgam + (alpha - gamma);
+   14537           0 :             if (std::abs(c__)>PLUMED_GMX_DOUBLE_MIN) {
+   14538           0 :                 p = gamma * gamma / c__;
+   14539             :             } else {
+   14540           0 :                 p = oldc * bb;
+   14541             :             }
+   14542             :         }
+   14543             : 
+   14544           0 :         e[l] = s * p;
+   14545           0 :         d__[l] = sigma + gamma;
+   14546           0 :         goto L50;
+   14547             : 
+   14548             : L90:
+   14549             :         d__[l] = p;
+   14550             : 
+   14551           0 :         ++l;
+   14552           0 :         if (l <= lend) {
+   14553           0 :             goto L50;
+   14554             :         }
+   14555           0 :         goto L150;
+   14556             : 
+   14557             :     } else {
+   14558             : 
+   14559           0 : L100:
+   14560           0 :         i__1 = lend + 1;
+   14561           0 :         for (m = l; m >= i__1; --m) {
+   14562           0 :             if (std::abs(e[m - 1]) <= eps2 * std::abs(d__[m] * d__[m - 1])) {
+   14563           0 :                 goto L120;
+   14564             :             }
+   14565             :         }
+   14566             :         m = lend;
+   14567             : 
+   14568           0 : L120:
+   14569           0 :         if (m > lend) {
+   14570           0 :             e[m - 1] = 0.;
+   14571             :         }
+   14572           0 :         p = d__[l];
+   14573           0 :         if (m == l) {
+   14574           0 :             goto L140;
+   14575             :         }
+   14576             : 
+   14577           0 :         if (m == l - 1) {
+   14578           0 :             rte =  std::sqrt(e[l - 1]);
+   14579           0 :             PLUMED_BLAS_F77_FUNC(dlae2,DLAE2)(&d__[l], &rte, &d__[l - 1], &rt1, &rt2);
+   14580           0 :             d__[l] = rt1;
+   14581           0 :             d__[l - 1] = rt2;
+   14582           0 :             e[l - 1] = 0.;
+   14583           0 :             l += -2;
+   14584           0 :             if (l >= lend) {
+   14585           0 :                 goto L100;
+   14586             :             }
+   14587           0 :             goto L150;
+   14588             :         }
+   14589             : 
+   14590           0 :         if (jtot == nmaxit) {
+   14591           0 :             goto L150;
+   14592             :         }
+   14593           0 :         ++jtot;
+   14594             : 
+   14595           0 :         rte =  std::sqrt(e[l - 1]);
+   14596           0 :         sigma = (d__[l - 1] - p) / (rte * 2.);
+   14597           0 :         r__ = PLUMED_BLAS_F77_FUNC(dlapy2,DLAPY2)(&sigma, &c_b32);
+   14598           0 :         sigma = p - rte / (sigma + ( (sigma>0) ? r__ : -r__));
+   14599             : 
+   14600             :         c__ = 1.;
+   14601             :         s = 0.;
+   14602           0 :         gamma = d__[m] - sigma;
+   14603           0 :         p = gamma * gamma;
+   14604             : 
+   14605           0 :         i__1 = l - 1;
+   14606           0 :         for (i__ = m; i__ <= i__1; ++i__) {
+   14607           0 :             bb = e[i__];
+   14608           0 :             r__ = p + bb;
+   14609           0 :             if (i__ != m) {
+   14610           0 :                 e[i__ - 1] = s * r__;
+   14611             :             }
+   14612             :             oldc = c__;
+   14613           0 :             c__ = p / r__;
+   14614           0 :             s = bb / r__;
+   14615             :             oldgam = gamma;
+   14616           0 :             alpha = d__[i__ + 1];
+   14617           0 :             gamma = c__ * (alpha - sigma) - s * oldgam;
+   14618           0 :             d__[i__] = oldgam + (alpha - gamma);
+   14619           0 :             if (std::abs(c__)>PLUMED_GMX_DOUBLE_MIN) {
+   14620           0 :                 p = gamma * gamma / c__;
+   14621             :             } else {
+   14622           0 :                 p = oldc * bb;
+   14623             :             }
+   14624             :         }
+   14625             : 
+   14626           0 :         e[l - 1] = s * p;
+   14627           0 :         d__[l] = sigma + gamma;
+   14628           0 :         goto L100;
+   14629             : 
+   14630             : L140:
+   14631             :         d__[l] = p;
+   14632             : 
+   14633           0 :         --l;
+   14634           0 :         if (l >= lend) {
+   14635           0 :             goto L100;
+   14636             :         }
+   14637           0 :         goto L150;
+   14638             : 
+   14639             :     }
+   14640             : 
+   14641           0 : L150:
+   14642           0 :     if (iscale == 1) {
+   14643           0 :         i__1 = lendsv - lsv + 1;
+   14644           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], 
+   14645             :                 n, info);
+   14646             :     }
+   14647           0 :     if (iscale == 2) {
+   14648           0 :         i__1 = lendsv - lsv + 1;
+   14649           0 :         PLUMED_BLAS_F77_FUNC(dlascl,DLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], 
+   14650             :                 n, info);
+   14651             :     }
+   14652             : 
+   14653           0 :     if (jtot < nmaxit) {
+   14654           0 :         goto L10;
+   14655             :     }
+   14656           0 :     i__1 = *n - 1;
+   14657           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   14658           0 :         if (std::abs(e[i__])>PLUMED_GMX_DOUBLE_MIN) {
+   14659           0 :             ++(*info);
+   14660             :         }
+   14661             :     }
+   14662             :     return;
+   14663             : }
+   14664             : 
+   14665             : 
+   14666             : }
+   14667             : }
+   14668             : #include "lapack.h"
+   14669             : 
+   14670             : 
+   14671             : /* Normally, DSTEVR is the LAPACK wrapper which calls one
+   14672             :  * of the eigenvalue methods. However, our code includes a
+   14673             :  * version of DSTEGR which is never than LAPACK 3.0 and can
+   14674             :  * handle requests for a subset of eigenvalues/vectors too,
+   14675             :  * and it should not need to call DSTEIN.
+   14676             :  * Just in case somebody has a faster version in their lapack
+   14677             :  * library we still call the driver routine, but in our own
+   14678             :  * case this is just a wrapper to dstegr.
+   14679             :  */
+   14680             : #include "blas/blas.h"
+   14681             : namespace PLMD{
+   14682             : namespace lapack{
+   14683             : using namespace blas;
+   14684             : void
+   14685           0 : PLUMED_BLAS_F77_FUNC(dstevr,DSTEVR)(const char *jobz, 
+   14686             :         const char *range,
+   14687             :         int *n,
+   14688             :         double *d,
+   14689             :         double *e,
+   14690             :         double *vl, 
+   14691             :         double *vu,
+   14692             :         int *il, 
+   14693             :         int *iu, 
+   14694             :         double *abstol,
+   14695             :         int *m,
+   14696             :         double *w, 
+   14697             :         double *z,
+   14698             :         int *ldz,
+   14699             :         int *isuppz, 
+   14700             :         double *work, 
+   14701             :         int *lwork, 
+   14702             :         int *iwork,
+   14703             :         int *liwork, 
+   14704             :         int *info)
+   14705             : {
+   14706           0 :   PLUMED_BLAS_F77_FUNC(dstegr,DSTEGR)(jobz, range, n, d, e, vl, vu, il, iu, abstol, m, w,
+   14707             :           z, ldz, isuppz, work, lwork, iwork, liwork, info);
+   14708             :   
+   14709             : 
+   14710           0 :     return;
+   14711             : 
+   14712             : }
+   14713             : 
+   14714             : 
+   14715             : }
+   14716             : }
+   14717             : #include <cmath>
+   14718             : 
+   14719             : #include "real.h"
+   14720             : 
+   14721             : #include "blas/blas.h"
+   14722             : #include "lapack.h"
+   14723             : #include "lapack_limits.h"
+   14724             : 
+   14725             : #include "blas/blas.h"
+   14726             : namespace PLMD{
+   14727             : namespace lapack{
+   14728             : using namespace blas;
+   14729             : void
+   14730      584792 : PLUMED_BLAS_F77_FUNC(dsyevr,DSYEVR)(const char *jobz, const char *range, const char *uplo, int *n, 
+   14731             :         double *a, int *lda, double *vl, double *vu, int *
+   14732             :         il, int *iu, double *abstol, int *m, double *w, 
+   14733             :         double *z__, int *ldz, int *isuppz, double *work, 
+   14734             :         int *lwork, int *iwork, int *liwork, int *info)
+   14735             : {
+   14736             :     /* System generated locals */
+   14737             :     int a_dim1, a_offset, z_dim1, z_offset, i__1, i__2;
+   14738             :     double d__1, d__2;
+   14739             : 
+   14740             :     /* Local variables */
+   14741      584792 :     int c__1 = 1;
+   14742             :     int i__, j, nb, jj;
+   14743             :     double eps, tmp1;
+   14744             :     int indd, inde;
+   14745             :     double anrm;
+   14746             :     int imax;
+   14747             :     double rmin, rmax;
+   14748             :     int itmp1, inddd, indee;
+   14749             :     double sigma;
+   14750             :     int iinfo;
+   14751             :     int indwk;
+   14752             :     int lwmin;
+   14753             :     int lower, wantz;
+   14754             :     int alleig, indeig;
+   14755             :     int iscale, indibl, indifl;
+   14756             :     int valeig;
+   14757             :     double safmin,minval;
+   14758             :     double bignum;
+   14759             :     int indtau;
+   14760             :     int indwkn;
+   14761             :     int liwmin;
+   14762             :     int llwrkn, llwork;
+   14763             :     double smlnum;
+   14764             :     int lwkopt;
+   14765             :     int lquery;
+   14766             :     
+   14767             :     /* Parameter adjustments */
+   14768      584792 :     a_dim1 = *lda;
+   14769      584792 :     a_offset = 1 + a_dim1;
+   14770      584792 :     a -= a_offset;
+   14771      584792 :     --w;
+   14772      584792 :     z_dim1 = *ldz;
+   14773      584792 :     z_offset = 1 + z_dim1;
+   14774      584792 :     z__ -= z_offset;
+   14775             :     --isuppz;
+   14776      584792 :     --work;
+   14777      584792 :     --iwork;
+   14778             : 
+   14779      584792 :     lower = (*uplo=='L' || *uplo=='l');
+   14780      584792 :     wantz = (*jobz=='V' || *jobz=='v');
+   14781      584792 :     alleig = (*range=='A' || *range=='a');
+   14782      584792 :     valeig = (*range=='V' || *range=='v');
+   14783      584792 :     indeig = (*range=='I' || *range=='i');
+   14784             : 
+   14785             :     indibl = 0;
+   14786      584792 :     lquery = *lwork == -1 || *liwork == -1;
+   14787             : 
+   14788             :     i__1 = 1;
+   14789      584792 :     i__2 = *n * 26;
+   14790             : 
+   14791      584792 :     if(*n>0) 
+   14792             :       lwmin = *n * 26;
+   14793             :     else
+   14794             :       lwmin = 1;
+   14795             : 
+   14796      584792 :     if(*n>0) 
+   14797      584792 :       liwmin = *n * 10;
+   14798             :     else
+   14799             :       liwmin = 1;
+   14800             : 
+   14801      584792 :     *info = 0;
+   14802      584792 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   14803           0 :         *info = -1;
+   14804      584792 :     } else if (! (alleig || valeig || indeig)) {
+   14805           0 :         *info = -2;
+   14806      584792 :     } else if (! (lower || (*uplo=='U' || *uplo=='u'))) {
+   14807           0 :         *info = -3;
+   14808      584792 :     } else if (*n < 0) {
+   14809           0 :         *info = -4;
+   14810      584792 :     } else if (*lda < ((*n>1) ? *n : 1) ) {
+   14811           0 :         *info = -6;
+   14812             :     } else {
+   14813      584792 :         if (valeig) {
+   14814           0 :             if (*n > 0 && *vu <= *vl) {
+   14815           0 :                 *info = -8;
+   14816             :             }
+   14817      584792 :         } else if (indeig) {
+   14818      577318 :           if (*il < 1 || *il > ((*n>1) ? *n : 1)) {
+   14819           0 :                 *info = -9;
+   14820      577318 :             } else if (*iu < ((*n<*il) ? *n : *il) || *iu > *n) {
+   14821           0 :                 *info = -10;
+   14822             :             }
+   14823             :         }
+   14824             :     }
+   14825      584792 :     if (*info == 0) {
+   14826      584792 :       if (*ldz < 1 || (wantz && *ldz < *n)) {
+   14827           0 :             *info = -15;
+   14828      584792 :         } else if (*lwork < lwmin && ! lquery) {
+   14829           0 :             *info = -18;
+   14830      584792 :         } else if (*liwork < liwmin && ! lquery) {
+   14831           0 :             *info = -20;
+   14832             :         }
+   14833             :     }
+   14834             : 
+   14835      584792 :     if (*info == 0) {
+   14836             :       nb = 32;
+   14837             :       /* Computing MAX */
+   14838      584792 :       i__1 = (nb + 1) * *n;
+   14839             :       lwkopt = (i__1>lwmin) ? i__1 : lwmin;
+   14840      584792 :       work[1] = (double) lwkopt;
+   14841      584792 :       iwork[1] = liwmin;
+   14842             :     } else 
+   14843             :       return;
+   14844             : 
+   14845      584792 :     if (lquery) 
+   14846             :         return;
+   14847             :     
+   14848      570593 :     *m = 0;
+   14849      570593 :     if (*n == 0) {
+   14850           0 :         work[1] = 1.;
+   14851           0 :         return;
+   14852             :     }
+   14853             : 
+   14854      570593 :     if (*n == 1) {
+   14855         588 :         work[1] = 7.;
+   14856         588 :         if (alleig || indeig) {
+   14857         588 :             *m = 1;
+   14858         588 :             w[1] = a[a_dim1 + 1];
+   14859             :         } else {
+   14860           0 :             if (*vl < a[a_dim1 + 1] && *vu >= a[a_dim1 + 1]) {
+   14861           0 :                 *m = 1;
+   14862           0 :                 w[1] = a[a_dim1 + 1];
+   14863             :             }
+   14864             :         }
+   14865         588 :         if (wantz) {
+   14866         586 :             z__[z_dim1 + 1] = 1.;
+   14867             :         }
+   14868         588 :         return;
+   14869             :     }
+   14870             :     minval = PLUMED_GMX_DOUBLE_MIN;
+   14871             :     safmin = minval*(1.0+PLUMED_GMX_DOUBLE_EPS);
+   14872             :     eps = PLUMED_GMX_DOUBLE_EPS;
+   14873             : 
+   14874             :     smlnum = safmin / eps;
+   14875             :     bignum = 1. / smlnum;
+   14876             :     rmin =  std::sqrt(smlnum);
+   14877             : 
+   14878      570005 :     d__1 =  std::sqrt(bignum), d__2 = 1. / std::sqrt(sqrt(safmin));
+   14879             :     rmax = (d__1<d__2) ? d__1 : d__2;
+   14880             : 
+   14881             :     iscale = 0;
+   14882      570005 :     anrm = PLUMED_BLAS_F77_FUNC(dlansy,DLANSY)("M", uplo, n, &a[a_offset], lda, &work[1]);
+   14883      570005 :     if (anrm > 0. && anrm < rmin) {
+   14884             :         iscale = 1;
+   14885           0 :         sigma = rmin / anrm;
+   14886      570005 :     } else if (anrm > rmax) {
+   14887             :         iscale = 1;
+   14888           0 :         sigma = rmax / anrm; 
+   14889             :     }
+   14890             :     if (iscale == 1) {
+   14891           0 :         if (lower) {
+   14892           0 :             i__1 = *n;
+   14893           0 :             for (j = 1; j <= i__1; ++j) {
+   14894           0 :                 i__2 = *n - j + 1;
+   14895           0 :                 PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__2, &sigma, &a[j + j * a_dim1], &c__1);
+   14896             :             }
+   14897             :         } else {
+   14898           0 :             i__1 = *n;
+   14899           0 :             for (j = 1; j <= i__1; ++j) {
+   14900           0 :                 PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&j, &sigma, &a[j * a_dim1 + 1], &c__1);
+   14901             : 
+   14902             :             }
+   14903             :         }
+   14904             :     }
+   14905             : 
+   14906             :     indtau = 1;
+   14907      570005 :     inde = indtau + *n;
+   14908      570005 :     indd = inde + *n;
+   14909      570005 :     indee = indd + *n;
+   14910      570005 :     inddd = indee + *n;
+   14911      570005 :     indifl = inddd + *n;
+   14912      570005 :     indwk = indifl + *n;
+   14913      570005 :     llwork = *lwork - indwk + 1;
+   14914      570005 :     PLUMED_BLAS_F77_FUNC(dsytrd,DSYTRD)(uplo, n, &a[a_offset], lda, &work[indd], &work[inde], &work[
+   14915      570005 :             indtau], &work[indwk], &llwork, &iinfo);
+   14916             : 
+   14917      570005 :     i__1 = *n - 1;
+   14918      570005 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(&i__1, &work[inde], &c__1, &work[indee], &c__1);
+   14919      570005 :     PLUMED_BLAS_F77_FUNC(dcopy,DCOPY)(n, &work[indd], &c__1, &work[inddd], &c__1);
+   14920             : 
+   14921      570005 :     PLUMED_BLAS_F77_FUNC(dstegr,DSTEGR)(jobz, range, n, &work[inddd], &work[indee], vl, vu, il, iu, 
+   14922             :             abstol, m, &w[1], &z__[z_offset], ldz, &isuppz[1], 
+   14923             :             &work[indwk], lwork, &iwork[1], liwork, info);
+   14924      570005 :     if (wantz && *info == 0) {
+   14925             :       indwkn = inde;
+   14926      569961 :       llwrkn = *lwork - indwkn + 1;
+   14927      569961 :       PLUMED_BLAS_F77_FUNC(dormtr,DORMTR)("L", uplo, "N", n, m, &a[a_offset], lda, &work[indtau]
+   14928             :               , &z__[z_offset], ldz, &work[indwkn], &llwrkn, &iinfo);
+   14929             :     }
+   14930             : 
+   14931      570005 :     if (*info != 0) 
+   14932             :       return;
+   14933             : 
+   14934      570005 :     if (iscale == 1) {
+   14935             :         if (*info == 0) {
+   14936           0 :             imax = *m;
+   14937             :         } else {
+   14938             :             imax = *info - 1;
+   14939             :         }
+   14940           0 :         d__1 = 1. / sigma;
+   14941           0 :         PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&imax, &d__1, &w[1], &c__1);
+   14942             :     }
+   14943             : 
+   14944      570005 :     if (wantz) {
+   14945      569961 :         i__1 = *m - 1;
+   14946             :         
+   14947      607525 :         for (j = 1; j <= i__1; ++j) {
+   14948             :             i__ = 0;
+   14949       37564 :             tmp1 = w[j];
+   14950       37564 :             i__2 = *m;
+   14951      291771 :             for (jj = j + 1; jj <= i__2; ++jj) {
+   14952      254207 :                 if (w[jj] < tmp1) {
+   14953             :                     i__ = jj;
+   14954             :                     tmp1 = w[jj];
+   14955             :                 }
+   14956             :             }
+   14957             : 
+   14958       37564 :             if (i__ != 0) {
+   14959           0 :                 itmp1 = iwork[indibl + i__ - 1];
+   14960           0 :                 w[i__] = w[j];
+   14961           0 :                 iwork[indibl + i__ - 1] = iwork[indibl + j - 1];
+   14962           0 :                 w[j] = tmp1;
+   14963           0 :                 iwork[indibl + j - 1] = itmp1;
+   14964           0 :                 PLUMED_BLAS_F77_FUNC(dswap,DSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 + 1],
+   14965             :                          &c__1);
+   14966             :             }
+   14967             :         }
+   14968             :     }
+   14969             : 
+   14970      570005 :     work[1] = (double) lwkopt;
+   14971      570005 :     iwork[1] = liwmin;
+   14972      570005 :     return;
+   14973             : 
+   14974             : }
+   14975             : }
+   14976             : }
+   14977             : #include <cctype>
+   14978             : #include <cmath>
+   14979             : 
+   14980             : #include "real.h"
+   14981             : 
+   14982             : #include "blas/blas.h"
+   14983             : #include "lapack.h"
+   14984             : 
+   14985             : #include "blas/blas.h"
+   14986             : namespace PLMD{
+   14987             : namespace lapack{
+   14988             : using namespace blas;
+   14989             : void
+   14990      570005 : PLUMED_BLAS_F77_FUNC(dsytd2,DSYTD2)(const char *    uplo,
+   14991             :         int *     n,
+   14992             :         double *  a,
+   14993             :         int *     lda,
+   14994             :         double *  d,
+   14995             :         double *  e,
+   14996             :         double *  tau,
+   14997             :     int *     info)
+   14998             : {
+   14999             :   double minusone,zero;
+   15000             :   double taui,alpha,tmp;
+   15001             :   int ti1,ti2,ti3,i;
+   15002      570005 :   const char ch=std::toupper(*uplo);
+   15003             : 
+   15004      570005 :   zero = 0.0;
+   15005      570005 :   minusone = -1.0;
+   15006             : 
+   15007      570005 :   if(*n<=0)
+   15008             :     return;
+   15009             : 
+   15010      570005 :   if(ch=='U') {
+   15011     2253904 :     for(i=*n-1;i>=1;i--) {
+   15012             : 
+   15013     1683899 :       ti1 = 1;
+   15014     1683899 :       PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&i,&(a[i*(*lda)+(i-1)]),&(a[i*(*lda)+0]),&ti1,&taui);
+   15015     1683899 :       e[i-1] = a[i*(*lda) + (i-1)];
+   15016     1683899 :       if(std::abs(taui)>PLUMED_GMX_DOUBLE_MIN) {
+   15017     1113894 :         a[i*(*lda)+(i-1)] = 1.0;
+   15018             :       
+   15019     1113894 :         ti1 = 1;
+   15020     1113894 :         PLUMED_BLAS_F77_FUNC(dsymv,DSYMV)("U",&i,&taui,a,lda,&(a[i*(*lda)+0]),&ti1,&zero,tau,&ti1);
+   15021             : 
+   15022     1113894 :         tmp = PLUMED_BLAS_F77_FUNC(ddot,DDOT)(&i,tau,&ti1,&(a[i*(*lda)+0]),&ti1);
+   15023             : 
+   15024     1113894 :         alpha = -0.5*taui*tmp;
+   15025             : 
+   15026     1113894 :         PLUMED_BLAS_F77_FUNC(daxpy,DAXPY)(&i,&alpha,&(a[i*(*lda)+0]),&ti1,tau,&ti1);
+   15027             : 
+   15028     1113894 :         PLUMED_BLAS_F77_FUNC(dsyr2,DSYR2)("U",&i,&minusone,&(a[i*(*lda)+0]),&ti1,tau,&ti1,a,lda);
+   15029             : 
+   15030     1113894 :         a[i*(*lda)+(i-1)] = e[i-1]; 
+   15031             : 
+   15032             :       }
+   15033     1683899 :       d[i] = a[i*(*lda)+i];
+   15034     1683899 :       tau[i-1] = taui;
+   15035             :     }
+   15036      570005 :     d[0] = a[0];
+   15037             :     
+   15038             :   } else {
+   15039             :     /* lower */
+   15040             : 
+   15041           0 :     for(i=1;i<*n;i++) {
+   15042             : 
+   15043           0 :       ti1 = *n - i;
+   15044           0 :       ti2 = ( *n < i+2) ? *n : i+2;
+   15045           0 :       ti3 = 1;
+   15046           0 :       PLUMED_BLAS_F77_FUNC(dlarfg,DLARFG)(&ti1,&(a[(i-1)*(*lda)+(i)]),&(a[(i-1)*(*lda)+ti2-1]),&ti3,&taui);
+   15047             : 
+   15048           0 :       e[i-1] = a[(i-1)*(*lda) + (i)];
+   15049             : 
+   15050           0 :       if(std::abs(taui)>PLUMED_GMX_DOUBLE_MIN) {
+   15051           0 :         a[(i-1)*(*lda)+(i)] = 1.0;
+   15052             :       
+   15053           0 :         ti1 = *n - i;
+   15054           0 :         ti2 = 1;
+   15055           0 :         PLUMED_BLAS_F77_FUNC(dsymv,DSYMV)(uplo,&ti1,&taui,&(a[i*(*lda)+i]),lda,&(a[(i-1)*(*lda)+i]),
+   15056             :                &ti2,&zero,&(tau[i-1]),&ti2);
+   15057             :         
+   15058           0 :         tmp = PLUMED_BLAS_F77_FUNC(ddot,DDOT)(&ti1,&(tau[i-1]),&ti2,&(a[(i-1)*(*lda)+i]),&ti2);
+   15059             : 
+   15060           0 :         alpha = -0.5*taui*tmp;
+   15061             : 
+   15062           0 :         PLUMED_BLAS_F77_FUNC(daxpy,DAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+i]),&ti2,&(tau[i-1]),&ti2);
+   15063             : 
+   15064           0 :         PLUMED_BLAS_F77_FUNC(dsyr2,DSYR2)(uplo,&ti1,&minusone,&(a[(i-1)*(*lda)+i]),&ti2,&(tau[i-1]),&ti2,
+   15065           0 :                &(a[(i)*(*lda)+i]),lda);
+   15066             : 
+   15067           0 :         a[(i-1)*(*lda)+(i)] = e[i-1]; 
+   15068             : 
+   15069             :       }
+   15070           0 :       d[i-1] = a[(i-1)*(*lda)+i-1];
+   15071           0 :       tau[i-1] = taui;
+   15072             :     }
+   15073           0 :     d[*n-1] = a[(*n-1)*(*lda)+(*n-1)];
+   15074             :  
+   15075             :   }
+   15076             :   return;
+   15077             : }
+   15078             : }
+   15079             : }
+   15080             : #include "blas/blas.h"
+   15081             : #include "lapack.h"
+   15082             : #include "lapack_limits.h"
+   15083             : 
+   15084             : #include "blas/blas.h"
+   15085             : namespace PLMD{
+   15086             : namespace lapack{
+   15087             : using namespace blas;
+   15088             : void
+   15089      570005 : PLUMED_BLAS_F77_FUNC(dsytrd,DSYTRD)(const char *uplo, int *n, double *a, int *
+   15090             :         lda, double *d__, double *e, double *tau, double *
+   15091             :         work, int *lwork, int *info)
+   15092             : {
+   15093             :     /* System generated locals */
+   15094             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   15095             : 
+   15096             :     /* Local variables */
+   15097             :     int i__, j, nb, kk, nx, iws;
+   15098             :     int nbmin, iinfo;
+   15099             :     int upper;
+   15100             :     int ldwork, lwkopt;
+   15101             :     int lquery;
+   15102      570005 :     double c_b22 = -1.;
+   15103      570005 :     double c_b23 = 1.;
+   15104             : 
+   15105             : 
+   15106             :     /* Parameter adjustments */
+   15107      570005 :     a_dim1 = *lda;
+   15108      570005 :     a_offset = 1 + a_dim1;
+   15109      570005 :     a -= a_offset;
+   15110      570005 :     --d__;
+   15111      570005 :     --e;
+   15112      570005 :     --tau;
+   15113             :     --work;
+   15114             : 
+   15115             :     /* Function Body */
+   15116      570005 :     *info = 0;
+   15117      570005 :     upper = (*uplo=='U' || *uplo=='u');
+   15118      570005 :     lquery = (*lwork == -1);
+   15119             : 
+   15120      570005 :     if (! upper && ! (*uplo=='L' || *uplo=='l')) {
+   15121           0 :         *info = -1;
+   15122      570005 :     } else if (*n < 0) {
+   15123           0 :         *info = -2;
+   15124      570005 :     } else if (*lda < ((1>*n) ? 1 : *n)) {
+   15125           0 :         *info = -4;
+   15126      570005 :     } else if (*lwork < 1 && ! lquery) {
+   15127           0 :         *info = -9;
+   15128             :     }
+   15129             : 
+   15130      570005 :     if (*info == 0) {
+   15131             : 
+   15132      570005 :       nb = DSYTRD_BLOCKSIZE;
+   15133      570005 :       lwkopt = *n * nb;
+   15134      570005 :       work[1] = (double) lwkopt;
+   15135             :     } else
+   15136             :       return;
+   15137             : 
+   15138      570005 :     if (lquery) 
+   15139             :       return;
+   15140             :   
+   15141      570005 :     if (*n == 0) {
+   15142           0 :         work[1] = 1.;
+   15143           0 :         return;
+   15144             :     }
+   15145             : 
+   15146             :     nx = *n;
+   15147      570005 :     if (nb > 1 && nb < *n) {
+   15148             : 
+   15149             :         nx = DSYTRD_CROSSOVER;
+   15150          12 :         if (nx < *n) {
+   15151             : 
+   15152           2 :             ldwork = *n;
+   15153           2 :             iws = ldwork * nb;
+   15154           2 :             if (*lwork < iws) {
+   15155             : 
+   15156           2 :                 i__1 = *lwork / ldwork;
+   15157           2 :                 nb = (i__1>1) ? i__1 : 1;
+   15158             :                 nbmin = DSYTRD_MINBLOCKSIZE;
+   15159           2 :                 if (nb < nbmin) {
+   15160             :                     nx = *n;
+   15161             :                 }
+   15162             :             }
+   15163             :         } else {
+   15164             :             nx = *n;
+   15165             :         }
+   15166             :     } else {
+   15167      569993 :         nb = 1;
+   15168             :     }
+   15169             : 
+   15170      570005 :     if (upper) {
+   15171             : 
+   15172      570005 :         kk = *n - (*n - nx + nb - 1) / nb * nb;
+   15173      570005 :         i__1 = kk + 1;
+   15174             :         i__2 = -nb;
+   15175      570024 :         for (i__ = *n - nb + 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += 
+   15176             :                 i__2) {
+   15177             : 
+   15178          19 :             i__3 = i__ + nb - 1;
+   15179          19 :             PLUMED_BLAS_F77_FUNC(dlatrd,DLATRD)(uplo, &i__3, &nb, &a[a_offset], lda, &e[1], &tau[1], &
+   15180             :                     work[1], &ldwork);
+   15181             : 
+   15182          19 :             i__3 = i__ - 1;
+   15183          19 :             PLUMED_BLAS_F77_FUNC(dsyr2k,DSYR2K)(uplo, "No transpose", &i__3, &nb, &c_b22, &a[i__ * a_dim1 
+   15184          19 :                     + 1], lda, &work[1], &ldwork, &c_b23, &a[a_offset], lda);
+   15185             : 
+   15186          19 :             i__3 = i__ + nb - 1;
+   15187         532 :             for (j = i__; j <= i__3; ++j) {
+   15188         513 :                 a[j - 1 + j * a_dim1] = e[j - 1];
+   15189         513 :                 d__[j] = a[j + j * a_dim1];
+   15190             : 
+   15191             :             }
+   15192             : 
+   15193             :         }
+   15194             : 
+   15195      570005 :         PLUMED_BLAS_F77_FUNC(dsytd2,DSYTD2)(uplo, &kk, &a[a_offset], lda, &d__[1], &e[1], &tau[1], &iinfo);
+   15196             :     } else {
+   15197             : 
+   15198           0 :         i__2 = *n - nx;
+   15199           0 :         i__1 = nb;
+   15200           0 :         for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__1) {
+   15201             : 
+   15202             : 
+   15203           0 :             i__3 = *n - i__ + 1;
+   15204           0 :             PLUMED_BLAS_F77_FUNC(dlatrd,DLATRD)(uplo, &i__3, &nb, &a[i__ + i__ * a_dim1], lda, &e[i__], &
+   15205           0 :                     tau[i__], &work[1], &ldwork);
+   15206             : 
+   15207           0 :             i__3 = *n - i__ - nb + 1;
+   15208           0 :             PLUMED_BLAS_F77_FUNC(dsyr2k,DSYR2K)(uplo, "No transpose", &i__3, &nb, &c_b22, &a[i__ + nb + 
+   15209           0 :                     i__ * a_dim1], lda, &work[nb + 1], &ldwork, &c_b23, &a[
+   15210           0 :                     i__ + nb + (i__ + nb) * a_dim1], lda);
+   15211             : 
+   15212             : 
+   15213           0 :             i__3 = i__ + nb - 1;
+   15214           0 :             for (j = i__; j <= i__3; ++j) {
+   15215           0 :                 a[j + 1 + j * a_dim1] = e[j];
+   15216           0 :                 d__[j] = a[j + j * a_dim1];
+   15217             : 
+   15218             :             }
+   15219             : 
+   15220             :         }
+   15221             : 
+   15222             : 
+   15223           0 :         i__1 = *n - i__ + 1;
+   15224           0 :         PLUMED_BLAS_F77_FUNC(dsytd2,DSYTD2)(uplo, &i__1, &a[i__ + i__ * a_dim1], lda, &d__[i__], &e[i__], 
+   15225           0 :                 &tau[i__], &iinfo);
+   15226             :     }
+   15227             : 
+   15228      570005 :     work[1] = (double) lwkopt;
+   15229      570005 :     return;
+   15230             : 
+   15231             : }
+   15232             : 
+   15233             : 
+   15234             : }
+   15235             : }
+   15236             : #include "blas/blas.h"
+   15237             : #include "lapack.h"
+   15238             : #include "lapack_limits.h"
+   15239             : 
+   15240             : #include "blas/blas.h"
+   15241             : namespace PLMD{
+   15242             : namespace lapack{
+   15243             : using namespace blas;
+   15244             : void
+   15245          57 : PLUMED_BLAS_F77_FUNC(dtrti2,DTRTI2)(const char *uplo,
+   15246             :         const char *diag, 
+   15247             :         int *n, 
+   15248             :         double *a,
+   15249             :         int *lda,
+   15250             :         int *info)
+   15251             : {
+   15252             :     int a_dim1, a_offset, i__1, i__2;
+   15253             : 
+   15254             :     int j;
+   15255             :     double ajj;
+   15256             :     int upper, nounit;
+   15257          57 :     int c__1 = 1;
+   15258             : 
+   15259             : 
+   15260          57 :     a_dim1 = *lda;
+   15261          57 :     a_offset = 1 + a_dim1;
+   15262          57 :     a -= a_offset;
+   15263             : 
+   15264          57 :     *info = 0;
+   15265          57 :     upper = (*uplo=='U' || *uplo=='u');
+   15266          57 :     nounit = (*diag=='N' || *diag=='n');
+   15267             : 
+   15268             :     if (*info != 0) {
+   15269             :         i__1 = -(*info);
+   15270             :         return;
+   15271             :     }
+   15272             : 
+   15273          57 :     if (upper) {
+   15274             : 
+   15275          57 :         i__1 = *n;
+   15276         171 :         for (j = 1; j <= i__1; ++j) {
+   15277         114 :             if (nounit) {
+   15278         114 :                 a[j + j * a_dim1] = 1. / a[j + j * a_dim1];
+   15279         114 :                 ajj = -a[j + j * a_dim1];
+   15280             :             } else {
+   15281           0 :                 ajj = -1.;
+   15282             :             }
+   15283             : 
+   15284         114 :             i__2 = j - 1;
+   15285         114 :             PLUMED_BLAS_F77_FUNC(dtrmv,DTRMV)("Upper", "No transpose", diag, &i__2, &a[a_offset], lda, &
+   15286         114 :                     a[j * a_dim1 + 1], &c__1);
+   15287         114 :             i__2 = j - 1;
+   15288         114 :             PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__2, &ajj, &a[j * a_dim1 + 1], &c__1);
+   15289             :         }
+   15290             :     } else {
+   15291             : 
+   15292           0 :         for (j = *n; j >= 1; --j) {
+   15293           0 :             if (nounit) {
+   15294           0 :                 a[j + j * a_dim1] = 1. / a[j + j * a_dim1];
+   15295           0 :                 ajj = -a[j + j * a_dim1];
+   15296             :             } else {
+   15297           0 :                 ajj = -1.;
+   15298             :             }
+   15299           0 :             if (j < *n) {
+   15300             : 
+   15301           0 :                 i__1 = *n - j;
+   15302           0 :                 PLUMED_BLAS_F77_FUNC(dtrmv,DTRMV)("Lower", "No transpose", diag, &i__1, &a[j + 1 + (j + 
+   15303           0 :                         1) * a_dim1], lda, &a[j + 1 + j * a_dim1], &c__1);
+   15304           0 :                 i__1 = *n - j;
+   15305           0 :                 PLUMED_BLAS_F77_FUNC(dscal,DSCAL)(&i__1, &ajj, &a[j + 1 + j * a_dim1], &c__1);
+   15306             :             }
+   15307             :         }
+   15308             :     }
+   15309             :     return;
+   15310             : }
+   15311             : }
+   15312             : }
+   15313             : #include <cmath>
+   15314             : #include "blas/blas.h"
+   15315             : #include "lapack.h"
+   15316             : #include "lapack_limits.h"
+   15317             : 
+   15318             : #include "real.h"
+   15319             : 
+   15320             : #include "blas/blas.h"
+   15321             : namespace PLMD{
+   15322             : namespace lapack{
+   15323             : using namespace blas;
+   15324             : void
+   15325          57 : PLUMED_BLAS_F77_FUNC(dtrtri,DTRTRI)(const char *uplo,
+   15326             :         const char *diag, 
+   15327             :         int *n,
+   15328             :         double *a, 
+   15329             :         int *lda,
+   15330             :         int *info)
+   15331             : {
+   15332             :     int a_dim1, a_offset, i__1, i__3, i__4, i__5;
+   15333             :     int j, jb, nb, nn;
+   15334          57 :     double c_b18 = 1.;
+   15335          57 :     double c_b22 = -1.;
+   15336             : 
+   15337             :     int upper;
+   15338             :     int nounit;
+   15339             : 
+   15340          57 :     a_dim1 = *lda;
+   15341          57 :     a_offset = 1 + a_dim1;
+   15342          57 :     a -= a_offset;
+   15343             : 
+   15344          57 :     *info = 0;
+   15345          57 :     upper = (*uplo=='U' || *uplo=='u');
+   15346          57 :     nounit = (*diag=='N' || *diag=='n');
+   15347             : 
+   15348             :     if (*info != 0) {
+   15349             :         i__1 = -(*info);
+   15350             :         return;
+   15351             :     }
+   15352             : 
+   15353          57 :     if (*n == 0) {
+   15354             :         return;
+   15355             :     }
+   15356             : 
+   15357          57 :     if (nounit) {
+   15358          57 :         i__1 = *n;
+   15359         171 :         for (*info = 1; *info <= i__1; ++(*info)) {
+   15360         114 :             if (std::abs(a[*info + *info * a_dim1])<PLUMED_GMX_DOUBLE_MIN) {
+   15361             :                 return;
+   15362             :             }
+   15363             :         }
+   15364          57 :         *info = 0;
+   15365             :     }
+   15366             : 
+   15367             :     nb = DTRTRI_BLOCKSIZE;
+   15368          57 :     if (nb <= 1 || nb >= *n) {
+   15369             : 
+   15370          57 :         PLUMED_BLAS_F77_FUNC(dtrti2,DTRTI2)(uplo, diag, n, &a[a_offset], lda, info);
+   15371             :     } else {
+   15372             : 
+   15373           0 :         if (upper) {
+   15374             : 
+   15375           0 :             i__1 = *n;
+   15376             :             i__3 = nb;
+   15377           0 :             for (j = 1; i__3 < 0 ? j >= i__1 : j <= i__1; j += i__3) {
+   15378           0 :                 i__4 = nb, i__5 = *n - j + 1;
+   15379           0 :                 jb = (i__4<i__5) ? i__4 : i__5;
+   15380             : 
+   15381           0 :                 i__4 = j - 1;
+   15382           0 :                 PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Left", "Upper", "No transpose", diag, &i__4, &jb, &
+   15383           0 :                         c_b18, &a[a_offset], lda, &a[j * a_dim1 + 1], lda);
+   15384           0 :                 i__4 = j - 1;
+   15385           0 :                 PLUMED_BLAS_F77_FUNC(dtrsm,DTRSM)("Right", "Upper", "No transpose", diag, &i__4, &jb, &
+   15386           0 :                         c_b22, &a[j + j * a_dim1], lda, &a[j * a_dim1 + 1], 
+   15387             :                         lda);
+   15388             : 
+   15389           0 :                 PLUMED_BLAS_F77_FUNC(dtrti2,DTRTI2)("Upper", diag, &jb, &a[j + j * a_dim1], lda, info);
+   15390             :             }
+   15391             :         } else {
+   15392             : 
+   15393           0 :             nn = (*n - 1) / nb * nb + 1;
+   15394             :             i__3 = -nb;
+   15395           0 :             for (j = nn; i__3 < 0 ? j >= 1 : j <= 1; j += i__3) {
+   15396           0 :                 i__1 = nb, i__4 = *n - j + 1;
+   15397           0 :                 jb = (i__1<i__4) ? i__1 : i__4;
+   15398           0 :                 if (j + jb <= *n) {
+   15399             : 
+   15400           0 :                     i__1 = *n - j - jb + 1;
+   15401           0 :                     PLUMED_BLAS_F77_FUNC(dtrmm,DTRMM)("Left", "Lower", "No transpose", diag, &i__1, &jb, 
+   15402           0 :                             &c_b18, &a[j + jb + (j + jb) * a_dim1], lda, &a[j 
+   15403           0 :                             + jb + j * a_dim1], lda);
+   15404           0 :                     i__1 = *n - j - jb + 1;
+   15405           0 :                     PLUMED_BLAS_F77_FUNC(dtrsm,DTRSM)("Right", "Lower", "No transpose", diag, &i__1, &jb,
+   15406           0 :                              &c_b22, &a[j + j * a_dim1], lda, &a[j + jb + j * 
+   15407           0 :                             a_dim1], lda);
+   15408             :                 }
+   15409             : 
+   15410           0 :                 PLUMED_BLAS_F77_FUNC(dtrti2,DTRTI2)("Lower", diag, &jb, &a[j + j * a_dim1], lda, info);
+   15411             :             }
+   15412             :         }
+   15413             :     }
+   15414             :     return;
+   15415             : }
+   15416             : 
+   15417             : 
+   15418             : }
+   15419             : }
+   15420             : #include "lapack.h"
+   15421             : 
+   15422             : #include "blas/blas.h"
+   15423             : namespace PLMD{
+   15424             : namespace lapack{
+   15425             : using namespace blas;
+   15426             : void 
+   15427          10 : PLUMED_BLAS_F77_FUNC(ilasrt2,ILASRT2)(const char *id, 
+   15428             :          int *n, 
+   15429             :          int *d__, 
+   15430             :          int *key, 
+   15431             :          int *info)
+   15432             : {
+   15433             :     int i__1, i__2;
+   15434             :     int i__, j, d1, d2, d3, dir, tmp, endd;
+   15435             :     int stack[64], dmnmx, start;
+   15436             :     int tmpkey, stkpnt;
+   15437             : 
+   15438          10 :     --key;
+   15439          10 :     --d__;
+   15440             : 
+   15441          10 :     *info = 0;
+   15442             :     dir = -1;
+   15443          10 :     if (*id=='D' || *id=='d') 
+   15444             :         dir = 0;
+   15445          10 :     else if (*id=='I' || *id=='i') 
+   15446             :         dir = 1;
+   15447             :     
+   15448             :     if (dir == -1) {
+   15449           0 :         *info = -1;
+   15450          10 :     } else if (*n < 0) {
+   15451           0 :         *info = -2;
+   15452             :     }
+   15453          10 :     if (*info != 0) {
+   15454             :         return;
+   15455             :     }
+   15456             : 
+   15457          10 :     if (*n <= 1) {
+   15458             :         return;
+   15459             :     }
+   15460             : 
+   15461             :     stkpnt = 1;
+   15462           9 :     stack[0] = 1;
+   15463           9 :     stack[1] = *n;
+   15464           9 : L10:
+   15465           9 :     start = stack[(stkpnt << 1) - 2];
+   15466           9 :     endd = stack[(stkpnt << 1) - 1];
+   15467           9 :     --stkpnt;
+   15468           9 :     if (endd - start > 0) {
+   15469             : 
+   15470           9 :         if (dir == 0) {
+   15471             : 
+   15472             :             i__1 = endd;
+   15473           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   15474             :                 i__2 = start + 1;
+   15475           0 :                 for (j = i__; j >= i__2; --j) {
+   15476           0 :                     if (d__[j] > d__[j - 1]) {
+   15477             :                         dmnmx = d__[j];
+   15478           0 :                         d__[j] = d__[j - 1];
+   15479           0 :                         d__[j - 1] = dmnmx;
+   15480           0 :                         tmpkey = key[j];
+   15481           0 :                         key[j] = key[j - 1];
+   15482           0 :                         key[j - 1] = tmpkey;
+   15483             :                     } else {
+   15484           0 :                         goto L30;
+   15485             :                     }
+   15486             :                 }
+   15487           0 : L30:
+   15488             :                 ;
+   15489             :             }
+   15490             : 
+   15491             :         } else {
+   15492             : 
+   15493             :             i__1 = endd;
+   15494         766 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   15495             :                 i__2 = start + 1;
+   15496       14895 :                 for (j = i__; j >= i__2; --j) {
+   15497       14829 :                     if (d__[j] < d__[j - 1]) {
+   15498             :                         dmnmx = d__[j];
+   15499       14138 :                         d__[j] = d__[j - 1];
+   15500       14138 :                         d__[j - 1] = dmnmx;
+   15501       14138 :                         tmpkey = key[j];
+   15502       14138 :                         key[j] = key[j - 1];
+   15503       14138 :                         key[j - 1] = tmpkey;
+   15504             :                     } else {
+   15505         691 :                         goto L50;
+   15506             :                     }
+   15507             :                 }
+   15508         757 : L50:
+   15509             :                 ;
+   15510             :             }
+   15511             : 
+   15512             :         }
+   15513             : 
+   15514           0 :     } else if (endd - start > 20) {
+   15515             : 
+   15516           0 :         d1 = d__[start];
+   15517           0 :         d2 = d__[endd];
+   15518           0 :         i__ = (start + endd) / 2;
+   15519           0 :         d3 = d__[i__];
+   15520           0 :         if (d1 < d2) {
+   15521           0 :             if (d3 < d1) {
+   15522             :                 dmnmx = d1;
+   15523             :             } else if (d3 < d2) {
+   15524             :                 dmnmx = d3;
+   15525             :             } else {
+   15526             :                 dmnmx = d2;
+   15527             :             }
+   15528             :         } else {
+   15529           0 :             if (d3 < d2) {
+   15530             :                 dmnmx = d2;
+   15531             :             } else if (d3 < d1) {
+   15532             :                 dmnmx = d3;
+   15533             :             } else {
+   15534             :                 dmnmx = d1;
+   15535             :             }
+   15536             :         }
+   15537             : 
+   15538           0 :         if (dir == 0) {
+   15539             : 
+   15540           0 :             i__ = start - 1;
+   15541           0 :             j = endd + 1;
+   15542           0 : L60:
+   15543           0 : L70:
+   15544           0 :             --j;
+   15545           0 :             if (d__[j] < dmnmx) {
+   15546           0 :                 goto L70;
+   15547             :             }
+   15548           0 : L80:
+   15549           0 :             ++i__;
+   15550           0 :             if (d__[i__] > dmnmx) {
+   15551           0 :                 goto L80;
+   15552             :             }
+   15553           0 :             if (i__ < j) {
+   15554             :                 tmp = d__[i__];
+   15555           0 :                 d__[i__] = d__[j];
+   15556           0 :                 d__[j] = tmp;
+   15557           0 :                 tmpkey = key[j];
+   15558           0 :                 key[j] = key[i__];
+   15559           0 :                 key[i__] = tmpkey;
+   15560           0 :                 goto L60;
+   15561             :             }
+   15562           0 :             if (j - start > endd - j - 1) {
+   15563             :                 ++stkpnt;
+   15564             :                 stack[(stkpnt << 1) - 2] = start;
+   15565           0 :                 stack[(stkpnt << 1) - 1] = j;
+   15566           0 :                 ++stkpnt;
+   15567           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   15568           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   15569             :             } else {
+   15570             :                 ++stkpnt;
+   15571           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   15572           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   15573           0 :                 ++stkpnt;
+   15574           0 :                 stack[(stkpnt << 1) - 2] = start;
+   15575           0 :                 stack[(stkpnt << 1) - 1] = j;
+   15576             :             }
+   15577             :         } else {
+   15578             : 
+   15579           0 :             i__ = start - 1;
+   15580           0 :             j = endd + 1;
+   15581           0 : L90:
+   15582           0 : L100:
+   15583           0 :             --j;
+   15584           0 :             if (d__[j] > dmnmx) {
+   15585           0 :                 goto L100;
+   15586             :             }
+   15587           0 : L110:
+   15588           0 :             ++i__;
+   15589           0 :             if (d__[i__] < dmnmx) {
+   15590           0 :                 goto L110;
+   15591             :             }
+   15592           0 :             if (i__ < j) {
+   15593             :                 tmp = d__[i__];
+   15594           0 :                 d__[i__] = d__[j];
+   15595           0 :                 d__[j] = tmp;
+   15596           0 :                 tmpkey = key[j];
+   15597           0 :                 key[j] = key[i__];
+   15598           0 :                 key[i__] = tmpkey;
+   15599           0 :                 goto L90;
+   15600             :             }
+   15601           0 :             if (j - start > endd - j - 1) {
+   15602             :                 ++stkpnt;
+   15603             :                 stack[(stkpnt << 1) - 2] = start;
+   15604           0 :                 stack[(stkpnt << 1) - 1] = j;
+   15605           0 :                 ++stkpnt;
+   15606           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   15607           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   15608             :             } else {
+   15609             :                 ++stkpnt;
+   15610           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   15611           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   15612           0 :                 ++stkpnt;
+   15613           0 :                 stack[(stkpnt << 1) - 2] = start;
+   15614           0 :                 stack[(stkpnt << 1) - 1] = j;
+   15615             :             }
+   15616             :         }
+   15617             :     }
+   15618           9 :     if (stkpnt > 0) {
+   15619           0 :         goto L10;
+   15620             :     }
+   15621             : 
+   15622             : 
+   15623             :     return;
+   15624             : }
+   15625             : }
+   15626             : }
+   15627             : #include <cctype>
+   15628             : #include <cmath>
+   15629             : #include "blas/blas.h"
+   15630             : #include "lapack.h"
+   15631             : #include "lapack_limits.h"
+   15632             : 
+   15633             : #include "real.h"
+   15634             : 
+   15635             : #include "blas/blas.h"
+   15636             : namespace PLMD{
+   15637             : namespace lapack{
+   15638             : using namespace blas;
+   15639             : void
+   15640           0 : PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)(const char *uplo, 
+   15641             :         const char *compq, 
+   15642             :         int *n,
+   15643             :         float *d__, 
+   15644             :         float *e, 
+   15645             :         float *u, 
+   15646             :         int *ldu,
+   15647             :         float *vt, 
+   15648             :         int *ldvt,
+   15649             :         float *q,
+   15650             :         int *iq,
+   15651             :         float *work, 
+   15652             :         int *iwork, 
+   15653             :         int *info)
+   15654             : {
+   15655             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+   15656             :     int i__, j, k;
+   15657             :     float p, r__;
+   15658             :     int z__, ic, ii, kk;
+   15659             :     float cs;
+   15660             :     int is, iu;
+   15661             :     float sn;
+   15662             :     int nm1;
+   15663             :     float eps;
+   15664             :     int ivt, difl, difr, ierr, perm, mlvl, sqre;
+   15665             :     int poles, iuplo, nsize, start;
+   15666             :     int givcol;
+   15667             :     int icompq;
+   15668             :     float orgnrm;
+   15669             :     int givnum, givptr, qstart, smlsiz, wstart, smlszp;
+   15670           0 :     float zero = 0.0;
+   15671           0 :     float one = 1.0;
+   15672           0 :     int c_0 = 0;
+   15673           0 :     int c_1 = 1;
+   15674             : 
+   15675           0 :     --d__;
+   15676           0 :     --e;
+   15677           0 :     u_dim1 = *ldu;
+   15678           0 :     u_offset = 1 + u_dim1;
+   15679           0 :     u -= u_offset;
+   15680           0 :     vt_dim1 = *ldvt;
+   15681           0 :     vt_offset = 1 + vt_dim1;
+   15682           0 :     vt -= vt_offset;
+   15683           0 :     --q;
+   15684           0 :     --iq;
+   15685           0 :     --work;
+   15686             :     --iwork;
+   15687             : 
+   15688             :     k = iu = z__ = ic = is = ivt = difl = difr = perm = 0;
+   15689             :     poles = givnum = givptr = givcol = 0;
+   15690             :     
+   15691           0 :     smlsiz = DBDSDC_SMALLSIZE;
+   15692           0 :     *info = 0;
+   15693             : 
+   15694           0 :     iuplo = (*uplo=='U' || *uplo=='u') ? 1 : 2;
+   15695             : 
+   15696           0 :     switch(*compq) {
+   15697           0 :     case 'n':
+   15698             :     case 'N':
+   15699           0 :       icompq = 0;
+   15700           0 :       break;
+   15701           0 :     case 'p':
+   15702             :     case 'P':
+   15703           0 :       icompq = 1;
+   15704           0 :       break;
+   15705           0 :     case 'i':
+   15706             :     case 'I':
+   15707           0 :       icompq = 2;
+   15708           0 :       break;
+   15709             :     default:
+   15710             :       return;
+   15711             :     }
+   15712             : 
+   15713           0 :     if (*n <= 0) 
+   15714             :         return;
+   15715             :     
+   15716           0 :     if (*n == 1) {
+   15717           0 :         if (icompq == 1) {
+   15718           0 :           q[1] = (d__[1]>0) ? 1.0 : -1.0;
+   15719           0 :           q[smlsiz * *n + 1] = 1.;
+   15720           0 :         } else if (icompq == 2) {
+   15721           0 :           u[u_dim1 + 1] = (d__[1]>0) ? 1.0 : -1.0;
+   15722           0 :           vt[vt_dim1 + 1] = 1.;
+   15723             :         }
+   15724           0 :         d__[1] = std::abs(d__[1]);
+   15725           0 :         return;
+   15726             :     }
+   15727           0 :     nm1 = *n - 1;
+   15728             :     wstart = 1;
+   15729             :     qstart = 3;
+   15730           0 :     if (icompq == 1) {
+   15731           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &d__[1], &c_1, &q[1], &c_1);
+   15732           0 :         i__1 = *n - 1;
+   15733           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &e[1], &c_1, &q[*n + 1], &c_1);
+   15734             :     }
+   15735           0 :     if (iuplo == 2) {
+   15736             :         qstart = 5;
+   15737           0 :         wstart = (*n << 1) - 1;
+   15738           0 :         i__1 = *n - 1;
+   15739           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   15740           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   15741           0 :             d__[i__] = r__;
+   15742           0 :             e[i__] = sn * d__[i__ + 1];
+   15743           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   15744           0 :             if (icompq == 1) {
+   15745           0 :                 q[i__ + (*n << 1)] = cs;
+   15746           0 :                 q[i__ + *n * 3] = sn;
+   15747           0 :             } else if (icompq == 2) {
+   15748           0 :                 work[i__] = cs;
+   15749           0 :                 work[nm1 + i__] = -sn;
+   15750             :             }
+   15751             :         }
+   15752             :     }
+   15753           0 :     if (icompq == 0) {
+   15754           0 :       PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U",&c_0,n,&c_0,&c_0,&c_0,&d__[1],&e[1],&vt[vt_offset],ldvt,
+   15755           0 :               &u[u_offset], ldu, &u[u_offset], ldu, &work[wstart], info);
+   15756           0 :         goto L40;
+   15757             :     }
+   15758           0 :     if (*n <= smlsiz) {
+   15759           0 :         if (icompq == 2) {
+   15760           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &u[u_offset], ldu);
+   15761           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &vt[vt_offset], ldvt);
+   15762           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U",&c_0,n,n,n,&c_0,&d__[1],&e[1],&vt[vt_offset],ldvt,
+   15763           0 :                     &u[u_offset],ldu,&u[u_offset],ldu,&work[wstart],info);
+   15764           0 :         } else if (icompq == 1) {
+   15765             :             iu = 1;
+   15766           0 :             ivt = iu + *n;
+   15767           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &q[iu + (qstart - 1) * *n], n);
+   15768           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &q[ivt + (qstart - 1) * *n], n);
+   15769           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &c_0, n, n, n, &c_0, &d__[1], &e[1], 
+   15770           0 :                     &q[ivt + (qstart - 1) * *n], n, &q[iu + (qstart - 1) * *n], 
+   15771           0 :                     n, &q[iu + (qstart - 1) * *n], n, &work[wstart], info);
+   15772             :         }
+   15773           0 :         goto L40;
+   15774             :     }
+   15775             : 
+   15776           0 :     if (icompq == 2) {
+   15777           0 :         PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &u[u_offset], ldu);
+   15778           0 :         PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", n, n, &zero, &one, &vt[vt_offset], ldvt);
+   15779             :     }
+   15780             : 
+   15781           0 :     orgnrm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("M", n, &d__[1], &e[1]);
+   15782           0 :     if ( std::abs(orgnrm)<PLUMED_GMX_FLOAT_MIN) {
+   15783             :         return;
+   15784             :     }
+   15785           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c_0, &c_0, &orgnrm, &one, n, &c_1, &d__[1], n, &ierr);
+   15786           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c_0, &c_0, &orgnrm, &one, &nm1, &c_1, &e[1], &nm1, &ierr);
+   15787             : 
+   15788             :     eps = PLUMED_GMX_FLOAT_EPS;
+   15789             : 
+   15790           0 :     mlvl = (int) (std::log((float) (*n) / (float) (smlsiz + 1)) / std::log(2.)) + 1;
+   15791             :     smlszp = smlsiz + 1;
+   15792             : 
+   15793           0 :     if (icompq == 1) {
+   15794             :         iu = 1;
+   15795             :         ivt = smlsiz + 1;
+   15796           0 :         difl = ivt + smlszp;
+   15797           0 :         difr = difl + mlvl;
+   15798           0 :         z__ = difr + (mlvl << 1);
+   15799           0 :         ic = z__ + mlvl;
+   15800           0 :         is = ic + 1;
+   15801           0 :         poles = is + 1;
+   15802           0 :         givnum = poles + (mlvl << 1);
+   15803             : 
+   15804             :         k = 1;
+   15805             :         givptr = 2;
+   15806             :         perm = 3;
+   15807           0 :         givcol = perm + mlvl;
+   15808             :     }
+   15809             : 
+   15810           0 :     i__1 = *n;
+   15811           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   15812           0 :         if (std::abs(d__[i__]) < eps) 
+   15813           0 :             d__[i__] = (d__[i__]>0) ? eps : -eps;
+   15814             :     }
+   15815             : 
+   15816             :     start = 1;
+   15817           0 :     sqre = 0;
+   15818             : 
+   15819           0 :     i__1 = nm1;
+   15820           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   15821           0 :         if (std::abs(e[i__]) < eps || i__ == nm1) {
+   15822           0 :             if (i__ < nm1) {
+   15823           0 :                 nsize = i__ - start + 1;
+   15824           0 :             } else if (std::abs(e[i__]) >= eps) {
+   15825           0 :                 nsize = *n - start + 1;
+   15826             :             } else {
+   15827           0 :                 nsize = i__ - start + 1;
+   15828           0 :                 if (icompq == 2) {
+   15829           0 :                     u[*n + *n * u_dim1] = (d__[*n]>0) ? 1.0 : -1.0; 
+   15830           0 :                     vt[*n + *n * vt_dim1] = 1.;
+   15831           0 :                 } else if (icompq == 1) {
+   15832           0 :                     q[*n + (qstart - 1) * *n] = (d__[*n]>0) ? 1.0 : -1.0; 
+   15833           0 :                     q[*n + (smlsiz + qstart - 1) * *n] = 1.;
+   15834             :                 }
+   15835           0 :                 d__[*n] = std::abs(d__[*n]);
+   15836             :             }
+   15837           0 :             if (icompq == 2) {
+   15838           0 :                 PLUMED_BLAS_F77_FUNC(slasd0,SLASD0)(&nsize, &sqre, &d__[start], &e[start], 
+   15839           0 :                         &u[start + start * u_dim1], ldu, 
+   15840           0 :                         &vt[start + start * vt_dim1], 
+   15841           0 :                         ldvt, &smlsiz, &iwork[1], &work[wstart], info);
+   15842             :             } else {
+   15843           0 :                 PLUMED_BLAS_F77_FUNC(slasda,SLASDA)(&icompq, &smlsiz, &nsize, &sqre, &d__[start], 
+   15844           0 :                         &e[start], &q[start + (iu + qstart - 2) * *n], n, 
+   15845           0 :                         &q[start + (ivt + qstart - 2) * *n], &iq[start + k * *n],
+   15846           0 :                         &q[start + (difl + qstart - 2) * *n], 
+   15847           0 :                         &q[start + (difr + qstart - 2) * *n], 
+   15848           0 :                         &q[start + (z__ + qstart - 2) * *n], 
+   15849           0 :                         &q[start + (poles + qstart - 2) * *n], 
+   15850           0 :                         &iq[start + givptr * *n], &iq[start + givcol * *n], n, 
+   15851           0 :                         &iq[start + perm * *n], 
+   15852           0 :                         &q[start + (givnum + qstart - 2) * *n], 
+   15853           0 :                         &q[start + (ic + qstart - 2) * *n], 
+   15854           0 :                         &q[start + (is + qstart - 2) * *n], &work[wstart], 
+   15855             :                         &iwork[1], info);
+   15856           0 :                 if (*info != 0) {
+   15857             :                     return;
+   15858             :                 }
+   15859             :             }
+   15860           0 :             start = i__ + 1;
+   15861             :         }
+   15862             :     }
+   15863           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c_0, &c_0, &one, &orgnrm, n, &c_1, &d__[1], n, &ierr);
+   15864           0 : L40:
+   15865           0 :     i__1 = *n;
+   15866           0 :     for (ii = 2; ii <= i__1; ++ii) {
+   15867           0 :         i__ = ii - 1;
+   15868             :         kk = i__;
+   15869           0 :         p = d__[i__];
+   15870           0 :         i__2 = *n;
+   15871           0 :         for (j = ii; j <= i__2; ++j) {
+   15872           0 :             if (d__[j] > p) {
+   15873             :                 kk = j;
+   15874             :                 p = d__[j];
+   15875             :             }
+   15876             :         }
+   15877           0 :         if (kk != i__) {
+   15878           0 :             d__[kk] = d__[i__];
+   15879           0 :             d__[i__] = p;
+   15880           0 :             if (icompq == 1) {
+   15881           0 :                 iq[i__] = kk;
+   15882           0 :             } else if (icompq == 2) {
+   15883           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &u[i__ * u_dim1 + 1],&c_1,&u[kk*u_dim1+1],&c_1);
+   15884           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &vt[i__ + vt_dim1], ldvt, &vt[kk + vt_dim1], ldvt);
+   15885             :             }
+   15886           0 :         } else if (icompq == 1) {
+   15887           0 :             iq[i__] = i__;
+   15888             :         }
+   15889             :     }
+   15890           0 :     if (icompq == 1) {
+   15891           0 :         if (iuplo == 1) {
+   15892           0 :             iq[*n] = 1;
+   15893             :         } else {
+   15894           0 :             iq[*n] = 0;
+   15895             :         }
+   15896             :     }
+   15897           0 :     if (iuplo == 2 && icompq == 2) {
+   15898           0 :         PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", n, n, &work[1], &work[*n], &u[u_offset], ldu);
+   15899             :     }
+   15900             : 
+   15901             :     return;
+   15902             : }
+   15903             : }
+   15904             : }
+   15905             : #include <cctype>
+   15906             : #include <cmath>
+   15907             : 
+   15908             : #include "blas/blas.h"
+   15909             : #include "lapack.h"
+   15910             : 
+   15911             : #include "real.h"
+   15912             : 
+   15913             : #include "blas/blas.h"
+   15914             : namespace PLMD{
+   15915             : namespace lapack{
+   15916             : using namespace blas;
+   15917             : void 
+   15918           0 : PLUMED_BLAS_F77_FUNC(sbdsqr,SBDSQR)(const char *uplo,
+   15919             :                         int *n,
+   15920             :                         int *ncvt,
+   15921             :                         int *nru, 
+   15922             :                         int *ncc, 
+   15923             :                         float *d__,
+   15924             :                         float *e,
+   15925             :                         float *vt, 
+   15926             :                         int *ldvt,
+   15927             :                         float *u, 
+   15928             :                         int *ldu,
+   15929             :                         float *c__, 
+   15930             :                         int *ldc,
+   15931             :                         float *work,
+   15932             :                         int *info)
+   15933             : {
+   15934           0 :     const char xuplo = std::toupper(*uplo);
+   15935             :     int c_dim1, c_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, 
+   15936             :             i__2;
+   15937             :     float r__1, r__2, r__3, r__4;
+   15938             :     float c_b15 = -.125;
+   15939             : 
+   15940           0 :     int c__1 = 1;
+   15941             :     float c_b49 = 1.f;
+   15942           0 :     float c_b72 = -1.f;
+   15943             : 
+   15944             :     float f, g, h__;
+   15945             :     int i__, j, m;
+   15946             :     float r__, cs;
+   15947             :     int ll;
+   15948             :     float sn, mu;
+   15949             :     int nm1, nm12, nm13, lll;
+   15950             :     float eps, sll, tol, abse;
+   15951             :     int idir;
+   15952             :     float abss;
+   15953             :     int oldm;
+   15954             :     float cosl;
+   15955             :     int isub, iter;
+   15956             :     float unfl, sinl, cosr, smin, smax, sinr;
+   15957             :     float oldcs;
+   15958             :     int oldll;
+   15959           0 :     float shift, sigmn, oldsn = 0.;
+   15960             :     int maxit;
+   15961             :     float sminl;
+   15962             :     float sigmx;
+   15963             :     int lower;
+   15964             :     float sminoa;
+   15965             :     float thresh;
+   15966             :     int rotate;
+   15967             :     float tolmul;
+   15968             :     int itmp1,itmp2;
+   15969             :     
+   15970           0 :     --d__;
+   15971           0 :     --e;
+   15972           0 :     vt_dim1 = *ldvt;
+   15973           0 :     vt_offset = 1 + vt_dim1;
+   15974           0 :     vt -= vt_offset;
+   15975           0 :     u_dim1 = *ldu;
+   15976           0 :     u_offset = 1 + u_dim1;
+   15977           0 :     u -= u_offset;
+   15978           0 :     c_dim1 = *ldc;
+   15979           0 :     c_offset = 1 + c_dim1;
+   15980           0 :     c__ -= c_offset;
+   15981           0 :     --work;
+   15982             : 
+   15983           0 :     *info = 0;
+   15984             :     
+   15985           0 :     itmp1 = (*n > 1) ? *n : 1;
+   15986           0 :     itmp2 = (*nru > 1) ? *nru : 1;
+   15987             :     
+   15988             :     lower = (xuplo == 'L');
+   15989           0 :     if ( (xuplo!='U') && !lower) {
+   15990           0 :         *info = -1;
+   15991           0 :     } else if (*n < 0) {
+   15992           0 :         *info = -2;
+   15993           0 :     } else if (*ncvt < 0) {
+   15994           0 :         *info = -3;
+   15995           0 :     } else if (*nru < 0) {
+   15996           0 :         *info = -4;
+   15997           0 :     } else if (*ncc < 0) {
+   15998           0 :         *info = -5;
+   15999           0 :     } else if ( ((*ncvt == 0) && (*ldvt < 1)) || ((*ncvt > 0) && (*ldvt < itmp1)) ) {
+   16000           0 :         *info = -9;
+   16001           0 :     } else if (*ldu < itmp2) {
+   16002           0 :         *info = -11;
+   16003           0 :     } else if ( ((*ncc == 0) && (*ldc < 1)) || ((*ncc > 0) && (*ldc < itmp1))) {
+   16004           0 :         *info = -13;
+   16005             :     }
+   16006           0 :     if (*info != 0) {
+   16007             :         return;
+   16008             :     }
+   16009           0 :     if (*n == 0) {
+   16010             :         return;
+   16011             :     }
+   16012           0 :     if (*n == 1) {
+   16013           0 :         goto L160;
+   16014             :     }
+   16015             : 
+   16016           0 :     rotate = *ncvt > 0 || *nru > 0 || *ncc > 0;
+   16017             : 
+   16018             :     if (! rotate) {
+   16019           0 :         PLUMED_BLAS_F77_FUNC(slasq1,SLASQ1)(n, &d__[1], &e[1], &work[1], info);
+   16020           0 :         return;
+   16021             :     }
+   16022             : 
+   16023           0 :     nm1 = *n - 1;
+   16024           0 :     nm12 = nm1 + nm1;
+   16025           0 :     nm13 = nm12 + nm1;
+   16026             :     idir = 0;
+   16027             : 
+   16028             :     eps = PLUMED_GMX_FLOAT_EPS;
+   16029             :     unfl = PLUMED_GMX_FLOAT_MIN/PLUMED_GMX_FLOAT_EPS;
+   16030             : 
+   16031           0 :     if (lower) {
+   16032           0 :         i__1 = *n - 1;
+   16033           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   16034           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   16035           0 :             d__[i__] = r__;
+   16036           0 :             e[i__] = sn * d__[i__ + 1];
+   16037           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   16038           0 :             work[i__] = cs;
+   16039           0 :             work[nm1 + i__] = sn;
+   16040             :         }
+   16041             : 
+   16042           0 :         if (*nru > 0) {
+   16043           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, n, &work[1], &work[*n], &u[u_offset], 
+   16044             :                     ldu);
+   16045             :         }
+   16046           0 :         if (*ncc > 0) {
+   16047           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", n, ncc, &work[1], &work[*n], &c__[c_offset],
+   16048             :                      ldc);
+   16049             :         }
+   16050             :     }
+   16051             : 
+   16052             :     r__3 = 100.f, r__4 = std::pow(static_cast<float>(PLUMED_GMX_FLOAT_EPS),c_b15);
+   16053           0 :     r__1 = 10.f, r__2 = (r__3<r__4) ? r__3 : r__4;
+   16054             :     tolmul = (r__1>r__2) ? r__1 : r__2;
+   16055             :     tol = tolmul * eps;
+   16056             :     smax = 0.f;
+   16057           0 :     i__1 = *n;
+   16058           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16059           0 :         r__2 = smax, r__3 = (r__1 = d__[i__], std::abs(r__1));
+   16060           0 :         smax = (r__2>r__3) ? r__2 : r__3;
+   16061             :     }
+   16062           0 :     i__1 = *n - 1;
+   16063           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16064           0 :         r__2 = smax, r__3 = (r__1 = e[i__], std::abs(r__1));
+   16065           0 :         smax = (r__2>r__3) ? r__2 : r__3;
+   16066             :     }
+   16067             :     sminl = 0.f;
+   16068             :     if (tol >= 0.f) {
+   16069           0 :         sminoa = std::abs(d__[1]);
+   16070           0 :         if (sminoa == 0.f) {
+   16071           0 :             goto L50;
+   16072             :         }
+   16073             :         mu = sminoa;
+   16074           0 :         i__1 = *n;
+   16075           0 :         for (i__ = 2; i__ <= i__1; ++i__) {
+   16076           0 :             mu = (r__2 = d__[i__], std::abs(r__2)) * (mu / (mu + (r__1 = e[i__ - 
+   16077           0 :                     1], std::abs(r__1))));
+   16078           0 :             sminoa = (sminoa<mu) ? sminoa : mu;
+   16079           0 :             if (sminoa == 0.f) {
+   16080           0 :                 goto L50;
+   16081             :             }
+   16082             :         }
+   16083           0 : L50:
+   16084           0 :         sminoa /=  std::sqrt((float) (*n));
+   16085           0 :         r__1 = tol * sminoa, r__2 = *n * 6 * *n * unfl;
+   16086           0 :         thresh = (r__1>r__2) ? r__1 : r__2;
+   16087             :     } else {
+   16088             :         r__1 = std::abs(tol) * smax, r__2 = *n * 6 * *n * unfl;
+   16089             :         thresh = (r__1>r__2) ? r__1 : r__2;
+   16090             :     }
+   16091             :     maxit = *n * 6 * *n;
+   16092             :     iter = 0;
+   16093             :     oldll = -1;
+   16094             :     oldm = -1;
+   16095             :     m = *n;
+   16096             : 
+   16097           0 : L60:
+   16098             : 
+   16099           0 :     if (m <= 1) {
+   16100           0 :         goto L160;
+   16101             :     }
+   16102           0 :     if (iter > maxit) {
+   16103           0 :         goto L200;
+   16104             :     }
+   16105             : 
+   16106             :     if (tol < 0.f && (r__1 = d__[m], std::abs(r__1)) <= thresh) {
+   16107             :         d__[m] = 0.f;
+   16108             :     }
+   16109           0 :     smax = (r__1 = d__[m], std::abs(r__1));
+   16110             :     smin = smax;
+   16111           0 :     i__1 = m - 1;
+   16112           0 :     for (lll = 1; lll <= i__1; ++lll) {
+   16113           0 :         ll = m - lll;
+   16114           0 :         abss = (r__1 = d__[ll], std::abs(r__1));
+   16115           0 :         abse = (r__1 = e[ll], std::abs(r__1));
+   16116             :         if (tol < 0.f && abss <= thresh) {
+   16117             :             d__[ll] = 0.f;
+   16118             :         }
+   16119           0 :         if (abse <= thresh) {
+   16120           0 :             goto L80;
+   16121             :         }
+   16122           0 :         smin = (smin<abss) ? smin : abss;
+   16123           0 :         r__1 = (smax>abss) ? smax : abss;
+   16124           0 :         smax = (r__1>abse) ? r__1 : abse;
+   16125             :     }
+   16126             :     ll = 0;
+   16127           0 :     goto L90;
+   16128             : L80:
+   16129           0 :     e[ll] = 0.f;
+   16130           0 :     if (ll == m - 1) {
+   16131             :         --m;
+   16132           0 :         goto L60;
+   16133             :     }
+   16134           0 : L90:
+   16135           0 :     ++ll;
+   16136           0 :     if (ll == m - 1) {
+   16137           0 :         PLUMED_BLAS_F77_FUNC(slasv2,SLASV2)(&d__[m - 1], &e[m - 1], &d__[m], &sigmn, &sigmx, &sinr, &cosr,
+   16138             :                  &sinl, &cosl);
+   16139           0 :         d__[m - 1] = sigmx;
+   16140           0 :         e[m - 1] = 0.f;
+   16141           0 :         d__[m] = sigmn;
+   16142           0 :         if (*ncvt > 0) {
+   16143           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(ncvt, &vt[m - 1 + vt_dim1], ldvt, &vt[m + vt_dim1], ldvt, &
+   16144             :                     cosr, &sinr);
+   16145             :         }
+   16146           0 :         if (*nru > 0) {
+   16147           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(nru, &u[(m - 1) * u_dim1 + 1], &c__1, &u[m * u_dim1 + 1], &
+   16148             :                     c__1, &cosl, &sinl);
+   16149             :         }
+   16150           0 :         if (*ncc > 0) {
+   16151           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(ncc, &c__[m - 1 + c_dim1], ldc, &c__[m + c_dim1], ldc, &
+   16152             :                     cosl, &sinl);
+   16153             :         }
+   16154           0 :         m += -2;
+   16155           0 :         goto L60;
+   16156             :     }
+   16157           0 :     if (ll > oldm || m < oldll) {
+   16158           0 :         if ((r__1 = d__[ll], std::abs(r__1)) >= (r__2 = d__[m], std::abs(r__2))) {
+   16159             :             idir = 1;
+   16160             :         } else {
+   16161             :             idir = 2;
+   16162             :         }
+   16163             :     }
+   16164           0 :     if (idir == 1) {
+   16165             : 
+   16166           0 :         if( (std::abs(e[m-1]) <= std::abs(tol) * std::abs(d__[m])) ||
+   16167             :             (tol<0.0 && std::abs(e[m-1])<=thresh)) {
+   16168           0 :             e[m - 1] = 0.f;
+   16169           0 :             goto L60;
+   16170             :         }
+   16171             :         if (tol >= 0.f) {
+   16172           0 :             mu = (r__1 = d__[ll], std::abs(r__1));
+   16173             :             sminl = mu;
+   16174             :             i__1 = m - 1;
+   16175           0 :             for (lll = ll; lll <= i__1; ++lll) {
+   16176           0 :                 if ((r__1 = e[lll], std::abs(r__1)) <= tol * mu) {
+   16177           0 :                     e[lll] = 0.f;
+   16178           0 :                     goto L60;
+   16179             :                 }
+   16180           0 :                 mu = (r__2 = d__[lll + 1], std::abs(r__2)) * (mu / (mu + (r__1 = 
+   16181             :                         e[lll], std::abs(r__1))));
+   16182           0 :                 sminl = (sminl<mu) ? sminl : mu;
+   16183             :             }
+   16184             :         }
+   16185             :     } else {
+   16186           0 :         if( (std::abs(e[ll]) <= std::abs(tol)*std::abs(d__[ll])) ||
+   16187             :             (tol<0.0 && std::abs(e[ll])<=thresh)) {
+   16188           0 :             e[ll] = 0.f;
+   16189           0 :             goto L60;
+   16190             :         }
+   16191             :         if (tol >= 0.f) {
+   16192           0 :             mu = (r__1 = d__[m], std::abs(r__1));
+   16193             :             sminl = mu;
+   16194           0 :             i__1 = ll;
+   16195           0 :             for (lll = m - 1; lll >= i__1; --lll) {
+   16196           0 :                 if ((r__1 = e[lll], std::abs(r__1)) <= tol * mu) {
+   16197           0 :                     e[lll] = 0.f;
+   16198           0 :                     goto L60;
+   16199             :                 }
+   16200           0 :                 mu = (r__2 = d__[lll], std::abs(r__2)) * (mu / (mu + (r__1 = e[
+   16201             :                         lll], std::abs(r__1))));
+   16202           0 :                 sminl = (sminl<mu) ? sminl : mu;
+   16203             :             }
+   16204             :         }
+   16205             :     }
+   16206             :     oldll = ll;
+   16207             :     oldm = m;
+   16208             : 
+   16209           0 :     r__1 = eps, r__2 = tol * .01f;
+   16210           0 :     if (tol >= 0.f && *n * tol * (sminl / smax) <= ((r__1>r__2) ? r__1 : r__2)) {
+   16211           0 :         shift = 0.f;
+   16212             :     } else {
+   16213           0 :         if (idir == 1) {
+   16214           0 :             sll = (r__1 = d__[ll], std::abs(r__1));
+   16215           0 :             PLUMED_BLAS_F77_FUNC(slas2,SLAS2)(&d__[m - 1], &e[m - 1], &d__[m], &shift, &r__);
+   16216             :         } else {
+   16217           0 :             sll = (r__1 = d__[m], std::abs(r__1));
+   16218           0 :             PLUMED_BLAS_F77_FUNC(slas2,SLAS2)(&d__[ll], &e[ll], &d__[ll + 1], &shift, &r__);
+   16219             :         }
+   16220           0 :         if (sll > 0.f) {
+   16221           0 :             r__1 = shift / sll;
+   16222           0 :             if (r__1 * r__1 < eps) {
+   16223           0 :                 shift = 0.f;
+   16224             :             }
+   16225             :         }
+   16226             :     }
+   16227           0 :     iter = iter + m - ll;
+   16228           0 :     if (shift == 0.f) {
+   16229           0 :         if (idir == 1) {
+   16230           0 :             cs = 1.f;
+   16231           0 :             oldcs = 1.f;
+   16232           0 :             i__1 = m - 1;
+   16233           0 :             for (i__ = ll; i__ <= i__1; ++i__) {
+   16234           0 :                 r__1 = d__[i__] * cs;
+   16235           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &e[i__], &cs, &sn, &r__);
+   16236           0 :                 if (i__ > ll) {
+   16237           0 :                     e[i__ - 1] = oldsn * r__;
+   16238             :                 }
+   16239           0 :                 r__1 = oldcs * r__;
+   16240           0 :                 r__2 = d__[i__ + 1] * sn;
+   16241           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
+   16242           0 :                 work[i__ - ll + 1] = cs;
+   16243           0 :                 work[i__ - ll + 1 + nm1] = sn;
+   16244           0 :                 work[i__ - ll + 1 + nm12] = oldcs;
+   16245           0 :                 work[i__ - ll + 1 + nm13] = oldsn;
+   16246             :             }
+   16247           0 :             h__ = d__[m] * cs;
+   16248           0 :             d__[m] = h__ * oldcs;
+   16249           0 :             e[m - 1] = h__ * oldsn;
+   16250           0 :             if (*ncvt > 0) {
+   16251           0 :                 i__1 = m - ll + 1;
+   16252           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt[
+   16253           0 :                         ll + vt_dim1], ldvt);
+   16254             :             }
+   16255           0 :             if (*nru > 0) {
+   16256           0 :                 i__1 = m - ll + 1;
+   16257           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13 
+   16258           0 :                         + 1], &u[ll * u_dim1 + 1], ldu);
+   16259             :             }
+   16260           0 :             if (*ncc > 0) {
+   16261           0 :                 i__1 = m - ll + 1;
+   16262           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13 
+   16263           0 :                         + 1], &c__[ll + c_dim1], ldc);
+   16264             :             }
+   16265           0 :             if ((r__1 = e[m - 1], std::abs(r__1)) <= thresh) {
+   16266           0 :                 e[m - 1] = 0.f;
+   16267             :             }
+   16268             :         } else {
+   16269           0 :             cs = 1.f;
+   16270           0 :             oldcs = 1.f;
+   16271           0 :             i__1 = ll + 1;
+   16272           0 :             for (i__ = m; i__ >= i__1; --i__) {
+   16273           0 :                 r__1 = d__[i__] * cs;
+   16274           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &e[i__ - 1], &cs, &sn, &r__);
+   16275           0 :                 if (i__ < m) {
+   16276           0 :                     e[i__] = oldsn * r__;
+   16277             :                 }
+   16278           0 :                 r__1 = oldcs * r__;
+   16279           0 :                 r__2 = d__[i__ - 1] * sn;
+   16280           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&r__1, &r__2, &oldcs, &oldsn, &d__[i__]);
+   16281           0 :                 work[i__ - ll] = cs;
+   16282           0 :                 work[i__ - ll + nm1] = -sn;
+   16283           0 :                 work[i__ - ll + nm12] = oldcs;
+   16284           0 :                 work[i__ - ll + nm13] = -oldsn;
+   16285             :             }
+   16286           0 :             h__ = d__[ll] * cs;
+   16287           0 :             d__[ll] = h__ * oldcs;
+   16288           0 :             e[ll] = h__ * oldsn;
+   16289           0 :             if (*ncvt > 0) {
+   16290           0 :                 i__1 = m - ll + 1;
+   16291           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[
+   16292           0 :                         nm13 + 1], &vt[ll + vt_dim1], ldvt);
+   16293             :             }
+   16294           0 :             if (*nru > 0) {
+   16295           0 :                 i__1 = m - ll + 1;
+   16296           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u[ll *
+   16297           0 :                          u_dim1 + 1], ldu);
+   16298             :             }
+   16299           0 :             if (*ncc > 0) {
+   16300           0 :                 i__1 = m - ll + 1;
+   16301           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c__[
+   16302           0 :                         ll + c_dim1], ldc);
+   16303             :             }
+   16304           0 :             if ((r__1 = e[ll], std::abs(r__1)) <= thresh) {
+   16305           0 :                 e[ll] = 0.f;
+   16306             :             }
+   16307             :         }
+   16308             :     } else {
+   16309             : 
+   16310           0 :         if (idir == 1) {
+   16311           0 :             f = ((r__1 = d__[ll], std::abs(r__1)) - shift) * ( ((d__[ll] > 0) ? c_b49 : -c_b49) + shift / d__[ll]);
+   16312           0 :             g = e[ll];
+   16313           0 :             i__1 = m - 1;
+   16314           0 :             for (i__ = ll; i__ <= i__1; ++i__) {
+   16315           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosr, &sinr, &r__);
+   16316           0 :                 if (i__ > ll) {
+   16317           0 :                     e[i__ - 1] = r__;
+   16318             :                 }
+   16319           0 :                 f = cosr * d__[i__] + sinr * e[i__];
+   16320           0 :                 e[i__] = cosr * e[i__] - sinr * d__[i__];
+   16321           0 :                 g = sinr * d__[i__ + 1];
+   16322           0 :                 d__[i__ + 1] = cosr * d__[i__ + 1];
+   16323           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosl, &sinl, &r__);
+   16324           0 :                 d__[i__] = r__;
+   16325           0 :                 f = cosl * e[i__] + sinl * d__[i__ + 1];
+   16326           0 :                 d__[i__ + 1] = cosl * d__[i__ + 1] - sinl * e[i__];
+   16327           0 :                 if (i__ < m - 1) {
+   16328           0 :                     g = sinl * e[i__ + 1];
+   16329           0 :                     e[i__ + 1] = cosl * e[i__ + 1];
+   16330             :                 }
+   16331           0 :                 work[i__ - ll + 1] = cosr;
+   16332           0 :                 work[i__ - ll + 1 + nm1] = sinr;
+   16333           0 :                 work[i__ - ll + 1 + nm12] = cosl;
+   16334           0 :                 work[i__ - ll + 1 + nm13] = sinl;
+   16335             :             }
+   16336           0 :             e[m - 1] = f;
+   16337             : 
+   16338           0 :             if (*ncvt > 0) {
+   16339           0 :                 i__1 = m - ll + 1;
+   16340           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncvt, &work[1], &work[*n], &vt[
+   16341           0 :                         ll + vt_dim1], ldvt);
+   16342             :             }
+   16343           0 :             if (*nru > 0) {
+   16344           0 :                 i__1 = m - ll + 1;
+   16345           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, &i__1, &work[nm12 + 1], &work[nm13 
+   16346           0 :                         + 1], &u[ll * u_dim1 + 1], ldu);
+   16347             :             }
+   16348           0 :             if (*ncc > 0) {
+   16349           0 :                 i__1 = m - ll + 1;
+   16350           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &i__1, ncc, &work[nm12 + 1], &work[nm13 
+   16351           0 :                         + 1], &c__[ll + c_dim1], ldc);
+   16352             :             }
+   16353           0 :             if ((r__1 = e[m - 1], std::abs(r__1)) <= thresh) {
+   16354           0 :                 e[m - 1] = 0.f;
+   16355             :             }
+   16356             :         } else {
+   16357             : 
+   16358           0 :             f = ((r__1 = d__[m], std::abs(r__1)) - shift) * ( ((d__[m] > 0) ? c_b49 : -c_b49) + shift / d__[m]);
+   16359           0 :             g = e[m - 1];
+   16360           0 :             i__1 = ll + 1;
+   16361           0 :             for (i__ = m; i__ >= i__1; --i__) {
+   16362           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosr, &sinr, &r__);
+   16363           0 :                 if (i__ < m) {
+   16364           0 :                     e[i__] = r__;
+   16365             :                 }
+   16366           0 :                 f = cosr * d__[i__] + sinr * e[i__ - 1];
+   16367           0 :                 e[i__ - 1] = cosr * e[i__ - 1] - sinr * d__[i__];
+   16368           0 :                 g = sinr * d__[i__ - 1];
+   16369           0 :                 d__[i__ - 1] = cosr * d__[i__ - 1];
+   16370           0 :                 PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&f, &g, &cosl, &sinl, &r__);
+   16371           0 :                 d__[i__] = r__;
+   16372           0 :                 f = cosl * e[i__ - 1] + sinl * d__[i__ - 1];
+   16373           0 :                 d__[i__ - 1] = cosl * d__[i__ - 1] - sinl * e[i__ - 1];
+   16374           0 :                 if (i__ > ll + 1) {
+   16375           0 :                     g = sinl * e[i__ - 2];
+   16376           0 :                     e[i__ - 2] = cosl * e[i__ - 2];
+   16377             :                 }
+   16378           0 :                 work[i__ - ll] = cosr;
+   16379           0 :                 work[i__ - ll + nm1] = -sinr;
+   16380           0 :                 work[i__ - ll + nm12] = cosl;
+   16381           0 :                 work[i__ - ll + nm13] = -sinl;
+   16382             :             }
+   16383           0 :             e[ll] = f;
+   16384             : 
+   16385           0 :             if ((r__1 = e[ll], std::abs(r__1)) <= thresh) {
+   16386           0 :                 e[ll] = 0.f;
+   16387             :             }
+   16388           0 :             if (*ncvt > 0) {
+   16389           0 :                 i__1 = m - ll + 1;
+   16390           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncvt, &work[nm12 + 1], &work[
+   16391           0 :                         nm13 + 1], &vt[ll + vt_dim1], ldvt);
+   16392             :             }
+   16393           0 :             if (*nru > 0) {
+   16394           0 :                 i__1 = m - ll + 1;
+   16395           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", nru, &i__1, &work[1], &work[*n], &u[ll *
+   16396           0 :                          u_dim1 + 1], ldu);
+   16397             :             }
+   16398           0 :             if (*ncc > 0) {
+   16399           0 :                 i__1 = m - ll + 1;
+   16400           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "B", &i__1, ncc, &work[1], &work[*n], &c__[
+   16401           0 :                         ll + c_dim1], ldc);
+   16402             :             }
+   16403             :         }
+   16404             :     }
+   16405             : 
+   16406           0 :     goto L60;
+   16407             : 
+   16408           0 : L160:
+   16409           0 :     i__1 = *n;
+   16410           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16411           0 :         if (d__[i__] < 0.f) {
+   16412           0 :             d__[i__] = -d__[i__];
+   16413             : 
+   16414           0 :             if (*ncvt > 0) {
+   16415           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(ncvt, &c_b72, &vt[i__ + vt_dim1], ldvt);
+   16416             :             }
+   16417             :         }
+   16418             :     }
+   16419             : 
+   16420           0 :     i__1 = *n - 1;
+   16421           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16422             : 
+   16423             :         isub = 1;
+   16424           0 :         smin = d__[1];
+   16425           0 :         i__2 = *n + 1 - i__;
+   16426           0 :         for (j = 2; j <= i__2; ++j) {
+   16427           0 :             if (d__[j] <= smin) {
+   16428             :                 isub = j;
+   16429             :                 smin = d__[j];
+   16430             :             }
+   16431             :         }
+   16432           0 :         if (isub != *n + 1 - i__) {
+   16433           0 :             d__[isub] = d__[*n + 1 - i__];
+   16434           0 :             d__[*n + 1 - i__] = smin;
+   16435           0 :             if (*ncvt > 0) {
+   16436           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncvt, &vt[isub + vt_dim1], ldvt, &vt[*n + 1 - i__ + 
+   16437           0 :                         vt_dim1], ldvt);
+   16438             :             }
+   16439           0 :             if (*nru > 0) {
+   16440           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(nru, &u[isub * u_dim1 + 1], &c__1, &u[(*n + 1 - i__) * 
+   16441           0 :                         u_dim1 + 1], &c__1);
+   16442             :             }
+   16443           0 :             if (*ncc > 0) {
+   16444           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncc, &c__[isub + c_dim1], ldc, &c__[*n + 1 - i__ + 
+   16445           0 :                         c_dim1], ldc);
+   16446             :             }
+   16447             :         }
+   16448             :     }
+   16449           0 :     goto L220;
+   16450             : 
+   16451             : L200:
+   16452           0 :     *info = 0;
+   16453           0 :     i__1 = *n - 1;
+   16454           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16455           0 :         if (e[i__] != 0.f) {
+   16456           0 :             ++(*info);
+   16457             :         }
+   16458             :     }
+   16459           0 : L220:
+   16460             :     return;
+   16461             : 
+   16462             : }
+   16463             : 
+   16464             : 
+   16465             : }
+   16466             : }
+   16467             : #include "lapack.h"
+   16468             : 
+   16469             : #include "blas/blas.h"
+   16470             : namespace PLMD{
+   16471             : namespace lapack{
+   16472             : using namespace blas;
+   16473             : void
+   16474           0 : PLUMED_BLAS_F77_FUNC(sgebd2,SGEBD2)(int *m,
+   16475             :         int *n,
+   16476             :         float *a,
+   16477             :         int *lda,
+   16478             :         float *d,
+   16479             :         float *e,
+   16480             :         float *tauq,
+   16481             :         float *taup,
+   16482             :         float *work,
+   16483             :         int *info)
+   16484             : {
+   16485             : 
+   16486             :   int i,i1,i2,i3;
+   16487             : 
+   16488           0 :     *info = 0;
+   16489             : 
+   16490           0 :   if(*m>=*n) {
+   16491             :     /* reduce to upper bidiag. form */
+   16492           0 :     for(i=0;i<*n;i++) {
+   16493           0 :       i1 = *m - i;
+   16494           0 :       i2 = ( (i+1) < (*m-1)) ? (i+1) : (*m-1);
+   16495           0 :       i3 = 1;
+   16496           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i*(*lda)+i2]),&i3,&(tauq[i]));
+   16497           0 :       d[i] = a[i*(*lda)+i];
+   16498           0 :       a[i*(*lda)+i] = 1.0;
+   16499           0 :       i2 = *n - i - 1;
+   16500           0 :       PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L",&i1,&i2,&(a[i*(*lda)+i]),&i3,&(tauq[i]),&(a[(i+1)*(*lda)+i]),lda,work);
+   16501           0 :       a[i*(*lda)+i] = d[i];
+   16502             : 
+   16503           0 :       if(i<(*n-1)) {
+   16504             : 
+   16505           0 :         i1 = *n - i -1;
+   16506           0 :         i2 = ( (i+2) < (*n-1)) ? (i+2) : (*n-1); 
+   16507           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[(i+1)*(*lda)+i]),&(a[i2*(*lda)+i]),lda,&(taup[i]));
+   16508             : 
+   16509           0 :         e[i] = a[(i+1)*(*lda)+i];
+   16510           0 :         a[(i+1)*(*lda)+i] = 1.0;
+   16511             : 
+   16512           0 :         i1 = *m - i - 1;
+   16513           0 :         i2 = *n - i - 1;
+   16514           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R",&i1,&i2,&(a[(i+1)*(*lda)+i]),lda,&(taup[i]),&(a[(i+1)*(*lda)+i+1]),lda,work);
+   16515           0 :         a[(i+1)*(*lda)+i] = e[i];
+   16516             :       } else
+   16517           0 :         taup[i] = 0.0;
+   16518             :     }
+   16519             :   } else {
+   16520             :     /* reduce to lower bidiag. form */
+   16521           0 :     for(i=0;i<*m;i++) {
+   16522           0 :       i1 = *n - i;
+   16523           0 :       i2 = ( (i+1) < (*n-1)) ? (i+1) : (*n-1);
+   16524           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i2*(*lda)+i]),lda,&(taup[i]));
+   16525           0 :       d[i] = a[i*(*lda)+i];
+   16526           0 :       a[i*(*lda)+i] = 1.0;
+   16527             : 
+   16528           0 :       i2 = *m - i - 1;
+   16529           0 :       i3 = ( (i+1) < (*m-1)) ? (i+1) : (*m-1);
+   16530           0 :       PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R",&i2,&i1,&(a[i*(*lda)+i]),lda,&(taup[i]),&(a[(i)*(*lda)+i3]),lda,work);
+   16531           0 :       a[i*(*lda)+i] = d[i];
+   16532             : 
+   16533           0 :       if(i<(*m-1)) {
+   16534             : 
+   16535           0 :         i1 = *m - i - 1;
+   16536           0 :         i2 = ( (i+2) < (*m-1)) ? (i+2) : (*m-1);
+   16537           0 :         i3 = 1;
+   16538           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[(i)*(*lda)+i+1]),&(a[i*(*lda)+i2]),&i3,&(tauq[i]));
+   16539             : 
+   16540           0 :         e[i] = a[(i)*(*lda)+i+1];
+   16541           0 :         a[(i)*(*lda)+i+1] = 1.0;
+   16542             : 
+   16543           0 :         i1 = *m - i - 1;
+   16544           0 :         i2 = *n - i - 1;
+   16545           0 :         i3 = 1;
+   16546           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L",&i1,&i2,&(a[(i)*(*lda)+i+1]),&i3,&(tauq[i]),&(a[(i+1)*(*lda)+i+1]),lda,work);
+   16547           0 :         a[(i)*(*lda)+i+1] = e[i];
+   16548             :       } else
+   16549           0 :         tauq[i] = 0.0;
+   16550             :     }
+   16551             :   }
+   16552           0 :   return;
+   16553             : }
+   16554             : }
+   16555             : }
+   16556             : #include "lapack.h"
+   16557             : #include "blas/blas.h"
+   16558             : #include "lapack_limits.h"
+   16559             : 
+   16560             : 
+   16561             : #include "blas/blas.h"
+   16562             : namespace PLMD{
+   16563             : namespace lapack{
+   16564             : using namespace blas;
+   16565             : void
+   16566           0 : PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(int *m, 
+   16567             :         int *n, 
+   16568             :         float *a, 
+   16569             :         int *lda, 
+   16570             :         float *d__, 
+   16571             :         float *e,
+   16572             :         float *tauq, 
+   16573             :         float *taup,
+   16574             :         float *work, 
+   16575             :         int *lwork,
+   16576             :         int *info)
+   16577             : {
+   16578             :     /* System generated locals */
+   16579             :     int a_dim1, a_offset, i_1, i_2, i_3, i_4;
+   16580             : 
+   16581             :     /* Local variables */
+   16582             :     int i_, j, nx,nb;
+   16583             :     float ws;
+   16584             :     int nbmin, iinfo, minmn;
+   16585             :     int ldwrkx, ldwrky;
+   16586           0 :     float one = 1.0;
+   16587           0 :     float minusone = -1.0;
+   16588             : 
+   16589           0 :     a_dim1 = *lda;
+   16590           0 :     a_offset = 1 + a_dim1;
+   16591           0 :     a -= a_offset;
+   16592           0 :     --d__;
+   16593           0 :     --e;
+   16594           0 :     --tauq;
+   16595           0 :     --taup;
+   16596           0 :     --work;
+   16597             : 
+   16598           0 :     nb = DGEBRD_BLOCKSIZE;
+   16599           0 :     *info = 0;
+   16600           0 :     if (*lwork==-1) {
+   16601           0 :       work[1] = (float) ( (*m + *n) * nb);
+   16602           0 :       return;
+   16603             :     }
+   16604           0 :     minmn = (*m < *n) ? *m : *n;
+   16605           0 :     if (minmn == 0) {
+   16606           0 :       work[1] = 1.;
+   16607           0 :       return;
+   16608             :     }
+   16609             : 
+   16610           0 :     ws = (*m > *n) ? *m : *n;
+   16611           0 :     ldwrkx = *m;
+   16612           0 :     ldwrky = *n;
+   16613             : 
+   16614           0 :     if (nb > 1 && nb < minmn) {
+   16615             :         nx = DGEBRD_CROSSOVER;
+   16616           0 :         if (nx < minmn) {
+   16617           0 :             ws = (float) ((*m + *n) * nb);
+   16618           0 :             if ((float) (*lwork) < ws) {
+   16619             :               nbmin = DGEBRD_MINBLOCKSIZE;
+   16620           0 :                 if (*lwork >= (*m + *n) * nbmin) {
+   16621           0 :                     nb = *lwork / (*m + *n);
+   16622             :                 } else {
+   16623           0 :                     nb = 1;
+   16624             :                     nx = minmn;
+   16625             :                 }
+   16626             :             }
+   16627             :         }
+   16628             :     } else {
+   16629             :         nx = minmn;
+   16630             :     }
+   16631             : 
+   16632           0 :     i_1 = minmn - nx;
+   16633           0 :     i_2 = nb;
+   16634           0 :     for (i_ = 1; i_2 < 0 ? i_ >= i_1 : i_ <= i_1; i_ += i_2) {
+   16635             : 
+   16636           0 :         i_3 = *m - i_ + 1;
+   16637           0 :         i_4 = *n - i_ + 1;
+   16638           0 :         PLUMED_BLAS_F77_FUNC(slabrd,SLABRD)(&i_3, &i_4, &nb, &a[i_ + i_ * a_dim1], lda, &d__[i_], 
+   16639           0 :                 &e[i_], &tauq[i_], &taup[i_], &work[1], &ldwrkx, 
+   16640           0 :                 &work[ldwrkx * nb + 1], &ldwrky);
+   16641             : 
+   16642           0 :         i_3 = *m - i_ - nb + 1;
+   16643           0 :         i_4 = *n - i_ - nb + 1;
+   16644           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "T", &i_3, &i_4, &nb, &minusone, 
+   16645           0 :                &a[i_ + nb + i_ * a_dim1], lda, &work[ldwrkx * nb + nb + 1],
+   16646           0 :                &ldwrky, &one, &a[i_ + nb + (i_ + nb) * a_dim1], lda);
+   16647           0 :         i_3 = *m - i_ - nb + 1;
+   16648           0 :         i_4 = *n - i_ - nb + 1;
+   16649           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", &i_3, &i_4, &nb, &minusone, &work[nb + 1], &ldwrkx,
+   16650           0 :                &a[i_ + (i_ + nb) * a_dim1], lda, &one, 
+   16651           0 :                &a[i_ + nb + (i_ + nb) * a_dim1], lda);
+   16652             : 
+   16653           0 :         if (*m >= *n) {
+   16654           0 :             i_3 = i_ + nb - 1;
+   16655           0 :             for (j = i_; j <= i_3; ++j) {
+   16656           0 :                 a[j + j * a_dim1] = d__[j];
+   16657           0 :                 a[j + (j + 1) * a_dim1] = e[j];
+   16658             :             }
+   16659             :         } else {
+   16660           0 :             i_3 = i_ + nb - 1;
+   16661           0 :             for (j = i_; j <= i_3; ++j) {
+   16662           0 :                 a[j + j * a_dim1] = d__[j];
+   16663           0 :                 a[j + 1 + j * a_dim1] = e[j];
+   16664             :             }
+   16665             :         }
+   16666             :     }
+   16667             : 
+   16668           0 :     i_2 = *m - i_ + 1;
+   16669           0 :     i_1 = *n - i_ + 1;
+   16670           0 :     PLUMED_BLAS_F77_FUNC(sgebd2,SGEBD2)(&i_2, &i_1, &a[i_ + i_ * a_dim1], lda, &d__[i_], &e[i_], &
+   16671           0 :             tauq[i_], &taup[i_], &work[1], &iinfo);
+   16672           0 :     work[1] = ws;
+   16673           0 :     return;
+   16674             : 
+   16675             : }
+   16676             : }
+   16677             : }
+   16678             : #include "lapack.h"
+   16679             : 
+   16680             : #include "blas/blas.h"
+   16681             : namespace PLMD{
+   16682             : namespace lapack{
+   16683             : using namespace blas;
+   16684             : void 
+   16685           0 : PLUMED_BLAS_F77_FUNC(sgelq2,SGELQ2)(int *m, 
+   16686             :                         int *n, 
+   16687             :                         float *a,
+   16688             :                         int *lda, 
+   16689             :                         float *tau, 
+   16690             :                         float *work, 
+   16691             :                         int *info)
+   16692             : {
+   16693             :     /* System generated locals */
+   16694             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+   16695             : 
+   16696             :     /* Local variables */
+   16697             :     int i__, k;
+   16698             :     float aii;
+   16699             : 
+   16700           0 :     a_dim1 = *lda;
+   16701           0 :     a_offset = 1 + a_dim1;
+   16702           0 :     a -= a_offset;
+   16703           0 :     --tau;
+   16704             :     --work;
+   16705             : 
+   16706           0 :     *info = 0;
+   16707             :     
+   16708           0 :     i__4 = (*m > 1) ? *m : 1;
+   16709             :     
+   16710           0 :     if (*m < 0) {
+   16711           0 :         *info = -1;
+   16712           0 :     } else if (*n < 0) {
+   16713           0 :         *info = -2;
+   16714           0 :     } else if (*lda < i__4) {
+   16715           0 :         *info = -4;
+   16716             :     }
+   16717           0 :     if (*info != 0) {
+   16718             :         return;
+   16719             :     }
+   16720             : 
+   16721             :     
+   16722           0 :     k = (*m < *n ) ? *m : *n;
+   16723             :     i__1 = k;
+   16724           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   16725           0 :         i__2 = *n - i__ + 1;
+   16726           0 :         i__3 = i__ + 1;
+   16727             :     i__4 = (i__3 < *n) ? i__3 : *n;
+   16728           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + i__ * a_dim1], &a[i__ + i__4 * a_dim1],
+   16729           0 :             lda, &tau[i__]);
+   16730           0 :         if (i__ < *m) {
+   16731           0 :             aii = a[i__ + i__ * a_dim1];
+   16732           0 :             a[i__ + i__ * a_dim1] = 1.f;
+   16733           0 :             i__2 = *m - i__;
+   16734           0 :             i__3 = *n - i__ + 1;
+   16735           0 :             PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R", &i__2, &i__3, &a[i__ + i__ * a_dim1], lda, 
+   16736           0 :                &tau[i__], &a[i__ + 1 + i__ * a_dim1], lda, &work[1]);
+   16737           0 :             a[i__ + i__ * a_dim1] = aii;
+   16738             :         }
+   16739             :     }
+   16740             :     return;
+   16741             : }
+   16742             : 
+   16743             : 
+   16744             : }
+   16745             : }
+   16746             : #include <cmath>
+   16747             : #include "lapack.h"
+   16748             : #include "lapack_limits.h"
+   16749             : 
+   16750             : 
+   16751             : 
+   16752             : #include "blas/blas.h"
+   16753             : namespace PLMD{
+   16754             : namespace lapack{
+   16755             : using namespace blas;
+   16756             : void
+   16757           0 : PLUMED_BLAS_F77_FUNC(sgelqf,SGELQF)(int *m,
+   16758             :         int *n, 
+   16759             :         float *a, 
+   16760             :         int *lda, 
+   16761             :         float *tau,
+   16762             :         float *work, 
+   16763             :         int *lwork, 
+   16764             :         int *info)
+   16765             : {
+   16766             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+   16767             : 
+   16768             :     int i__, k, ib, nb, nx, iws, nbmin, iinfo;
+   16769             :     int ldwork, lwkopt;
+   16770             : 
+   16771           0 :     a_dim1 = *lda;
+   16772           0 :     a_offset = 1 + a_dim1;
+   16773           0 :     a -= a_offset;
+   16774           0 :     --tau;
+   16775             :     --work;
+   16776             : 
+   16777           0 :     *info = 0;
+   16778             :     nb = DGELQF_BLOCKSIZE;
+   16779           0 :     lwkopt = *m * nb;
+   16780           0 :     work[1] = (float) lwkopt;
+   16781             : 
+   16782           0 :     if (*lwork==-1) {
+   16783             :         return;
+   16784             :     }
+   16785             : 
+   16786           0 :     k =(*m < *n) ? *m : *n;
+   16787           0 :     if (k == 0) {
+   16788           0 :         work[1] = 1.;
+   16789           0 :         return;
+   16790             :     }
+   16791             : 
+   16792             :     nbmin = 2;
+   16793             :     nx = 0;
+   16794             :     iws = *m;
+   16795           0 :     if (nb > 1 && nb < k) {
+   16796             :         nx = DGELQF_CROSSOVER;
+   16797           0 :         if (nx < k) {
+   16798           0 :             ldwork = *m;
+   16799           0 :             iws = ldwork * nb;
+   16800           0 :             if (*lwork < iws) {
+   16801             : 
+   16802           0 :                 nb = *lwork / ldwork;
+   16803             :                 nbmin = DGELQF_MINBLOCKSIZE;
+   16804             :             }
+   16805             :         }
+   16806             :     }
+   16807             : 
+   16808           0 :     if (nb >= nbmin && nb < k && nx < k) {
+   16809             : 
+   16810           0 :         i__1 = k - nx;
+   16811           0 :         i__2 = nb;
+   16812           0 :         for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   16813           0 :             i__3 = k - i__ + 1;
+   16814           0 :             ib = (i__3 < nb) ? i__3 : nb;
+   16815             : 
+   16816           0 :             i__3 = *n - i__ + 1;
+   16817           0 :             PLUMED_BLAS_F77_FUNC(sgelq2,SGELQ2)(&ib, &i__3, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[
+   16818             :                     1], &iinfo);
+   16819           0 :             if (i__ + ib <= *m) {
+   16820             : 
+   16821           0 :                 i__3 = *n - i__ + 1;
+   16822           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Rowwise", &i__3, &ib, &a[i__ + i__ * 
+   16823             :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   16824             : 
+   16825           0 :                 i__3 = *m - i__ - ib + 1;
+   16826           0 :                 i__4 = *n - i__ + 1;
+   16827           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Right", "No transpose", "Forward", "Rowwise", &i__3, 
+   16828             :                         &i__4, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+   16829           0 :                         ldwork, &a[i__ + ib + i__ * a_dim1], lda, &work[ib + 
+   16830           0 :                         1], &ldwork);
+   16831             :             }
+   16832             :         }
+   16833             :     } else {
+   16834             :         i__ = 1;
+   16835             :     }
+   16836             : 
+   16837           0 :     if (i__ <= k) {
+   16838           0 :         i__2 = *m - i__ + 1;
+   16839           0 :         i__1 = *n - i__ + 1;
+   16840           0 :         PLUMED_BLAS_F77_FUNC(sgelq2,SGELQ2)(&i__2, &i__1, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[1]
+   16841             :                 , &iinfo);
+   16842             :     }
+   16843             : 
+   16844           0 :     work[1] = (float) iws;
+   16845           0 :     return;
+   16846             : 
+   16847             : }
+   16848             : }
+   16849             : }
+   16850             : #include "lapack.h"
+   16851             : 
+   16852             : 
+   16853             : #include "blas/blas.h"
+   16854             : namespace PLMD{
+   16855             : namespace lapack{
+   16856             : using namespace blas;
+   16857             : void
+   16858           0 : PLUMED_BLAS_F77_FUNC(sgeqr2,SGEQR2)(int *m,
+   16859             :         int *n,
+   16860             :         float *a,
+   16861             :         int *lda,
+   16862             :         float *tau,
+   16863             :         float *work,
+   16864             :         int *info)
+   16865             : {
+   16866           0 :   int k = (*m < *n) ? *m : *n;
+   16867             :   int i,i1,i2,i3;
+   16868             :   float aii;
+   16869             : 
+   16870           0 :   *info = 0;
+   16871             :   
+   16872           0 :   for(i=0;i<k;i++) {
+   16873           0 :     i1 = *m - i;
+   16874           0 :     i2 = ( (i+1) < (*m-1) ) ? (i+1) : (*m-1);
+   16875           0 :     i3 = 1;
+   16876           0 :     PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i1,&(a[i*(*lda)+i]),&(a[i*(*lda)+i2]),&i3,&(tau[i]));
+   16877           0 :     if(i<(*n-1)) {
+   16878           0 :       aii = a[i*(*lda)+i];
+   16879           0 :       a[i*(*lda)+i] = 1.0;
+   16880           0 :       i2 = *n - i - 1;
+   16881           0 :       PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L",&i1,&i2,&(a[i*(*lda)+i]),&i3,&(tau[i]),
+   16882           0 :              &(a[(i+1)*(*lda)+i]),lda,work);
+   16883           0 :       a[i*(*lda)+i] = aii;
+   16884             :     }
+   16885             :   }
+   16886           0 :   return;
+   16887             : }
+   16888             : }
+   16889             : }
+   16890             : #include "lapack.h"
+   16891             : #include "lapack_limits.h"
+   16892             : 
+   16893             : #include "blas/blas.h"
+   16894             : namespace PLMD{
+   16895             : namespace lapack{
+   16896             : using namespace blas;
+   16897             : void 
+   16898           0 : PLUMED_BLAS_F77_FUNC(sgeqrf,SGEQRF)(int *m, 
+   16899             :         int *n, 
+   16900             :         float *a, 
+   16901             :         int *lda, 
+   16902             :         float *tau,
+   16903             :         float *work, 
+   16904             :         int *lwork, 
+   16905             :         int *info)
+   16906             : {
+   16907             :     int a_dim1, a_offset, i__1, i__2, i__3, i__4;
+   16908             : 
+   16909             :     int i__, k, ib, nb, nx, iws, nbmin, iinfo;
+   16910             :     int ldwork, lwkopt;
+   16911             : 
+   16912           0 :     a_dim1 = *lda;
+   16913           0 :     a_offset = 1 + a_dim1;
+   16914           0 :     a -= a_offset;
+   16915           0 :     --tau;
+   16916             :     --work;
+   16917             : 
+   16918           0 :     *info = 0;
+   16919             :     nb = DGEQRF_BLOCKSIZE;
+   16920           0 :     lwkopt = *n * nb;
+   16921           0 :     work[1] = (float) lwkopt;
+   16922           0 :         if (*lwork==-1)
+   16923             :         return;
+   16924             :     
+   16925             : 
+   16926           0 :     k = (*m < *n) ? *m : *n;
+   16927           0 :     if (k == 0) {
+   16928           0 :         work[1] = 1.;
+   16929           0 :         return;
+   16930             :     }
+   16931             : 
+   16932             :     nbmin = 2;
+   16933             :     nx = 0;
+   16934             :     iws = *n;
+   16935           0 :     if (nb > 1 && nb < k) {
+   16936             :         
+   16937             :       nx = DGEQRF_CROSSOVER;
+   16938           0 :         if (nx < k) {
+   16939             : 
+   16940           0 :             ldwork = *n;
+   16941           0 :             iws = ldwork * nb;
+   16942           0 :             if (*lwork < iws) {
+   16943             : 
+   16944           0 :                 nb = *lwork / ldwork;
+   16945             :                 nbmin = DGEQRF_MINBLOCKSIZE;
+   16946             :             }
+   16947             :         }
+   16948             :     }
+   16949             : 
+   16950           0 :     if (nb >= nbmin && nb < k && nx < k) {
+   16951           0 :         i__1 = k - nx;
+   16952           0 :         i__2 = nb;
+   16953           0 :         for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   16954             : 
+   16955           0 :             i__3 = k - i__ + 1;
+   16956           0 :             ib = (i__3 < nb) ? i__3 : nb;
+   16957             : 
+   16958           0 :             i__3 = *m - i__ + 1;
+   16959           0 :             PLUMED_BLAS_F77_FUNC(sgeqr2,SGEQR2)(&i__3, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[
+   16960             :                     1], &iinfo);
+   16961           0 :             if (i__ + ib <= *n) {
+   16962             : 
+   16963           0 :                 i__3 = *m - i__ + 1;
+   16964           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Columnwise", &i__3, &ib, &a[i__ + i__ * 
+   16965             :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   16966             : 
+   16967           0 :                 i__3 = *m - i__ + 1;
+   16968           0 :                 i__4 = *n - i__ - ib + 1;
+   16969           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Left", "Transpose", "Forward", "Columnwise", &i__3, &
+   16970             :                         i__4, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+   16971           0 :                         ldwork, &a[i__ + (i__ + ib) * a_dim1], lda, &work[ib 
+   16972           0 :                         + 1], &ldwork);
+   16973             :             }
+   16974             :         }
+   16975             :     } else {
+   16976             :         i__ = 1;
+   16977             :     }
+   16978             : 
+   16979           0 :     if (i__ <= k) {
+   16980           0 :         i__2 = *m - i__ + 1;
+   16981           0 :         i__1 = *n - i__ + 1;
+   16982           0 :         PLUMED_BLAS_F77_FUNC(sgeqr2,SGEQR2)(&i__2, &i__1, &a[i__ + i__ * a_dim1], lda, &tau[i__], &work[1]
+   16983             :                 , &iinfo);
+   16984             :     }
+   16985             : 
+   16986           0 :     work[1] = (float) iws;
+   16987           0 :     return;
+   16988             : 
+   16989             : } 
+   16990             : 
+   16991             : }
+   16992             : }
+   16993             : #include <cmath>
+   16994             : #include "real.h"
+   16995             : 
+   16996             : 
+   16997             : #include "blas/blas.h"
+   16998             : #include "lapack.h"
+   16999             : #include "lapack_limits.h"
+   17000             : 
+   17001             : #include "blas/blas.h"
+   17002             : namespace PLMD{
+   17003             : namespace lapack{
+   17004             : using namespace blas;
+   17005             : void
+   17006           0 : PLUMED_BLAS_F77_FUNC(sgesdd,SGESDD)(const char *jobz, 
+   17007             :                         int *m, 
+   17008             :                         int *n, 
+   17009             :                         float *a, 
+   17010             :                         int *lda, 
+   17011             :                         float *s,
+   17012             :                         float *u, 
+   17013             :                         int *ldu, 
+   17014             :                         float *vt, 
+   17015             :                         int *ldvt, 
+   17016             :                         float *work,
+   17017             :                         int *lwork, 
+   17018             :                         int *iwork, 
+   17019             :                         int *info)
+   17020             : {
+   17021             :     int a_dim1, a_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+   17022             : 
+   17023             :     int ie, iu;
+   17024             :     float dum[1], eps;
+   17025             :     int ivt, iscl;
+   17026             :     float anrm;
+   17027             :     int idum[1], ierr, itau;
+   17028             :     int minmn, wrkbl, itaup, itauq, mnthr;
+   17029             :     int nwork;
+   17030             :     int wntqn;
+   17031             :     int bdspac;
+   17032             :     float bignum;
+   17033             :     int ldwrku, maxwrk, ldwkvt;
+   17034             :     float smlnum,minval, safemin;
+   17035             :     int lquery;
+   17036           0 :     int c__0 = 0;
+   17037           0 :     int c__1 = 1;
+   17038           0 :     float zero = 0.0;
+   17039           0 :     float one = 1.0;
+   17040             : 
+   17041             : 
+   17042           0 :     a_dim1 = *lda;
+   17043           0 :     a_offset = 1 + a_dim1;
+   17044           0 :     a -= a_offset;
+   17045             :     --s;
+   17046           0 :     u_dim1 = *ldu;
+   17047           0 :     u_offset = 1 + u_dim1;
+   17048           0 :     u -= u_offset;
+   17049           0 :     vt_dim1 = *ldvt;
+   17050           0 :     vt_offset = 1 + vt_dim1;
+   17051           0 :     vt -= vt_offset;
+   17052           0 :     --work;
+   17053             :     --iwork;
+   17054             : 
+   17055           0 :     *info = 0;
+   17056           0 :     minmn = (*m < *n) ? *m : *n;
+   17057           0 :     mnthr = (int) (minmn * 11. / 6.);
+   17058           0 :     wntqn = (*jobz=='o' || *jobz=='O');
+   17059             : 
+   17060             :     maxwrk = 1;
+   17061           0 :     lquery = *lwork == -1;
+   17062             : 
+   17063           0 :     if (*info == 0 && *m > 0 && *n > 0) {
+   17064           0 :         if (*m >= *n) {
+   17065             : 
+   17066           0 :             if (wntqn) {
+   17067           0 :                 bdspac = *n * 7;
+   17068             :             } else {
+   17069           0 :                 bdspac = *n * 3 * *n + (*n << 2);
+   17070             :             }
+   17071           0 :             if (*m >= mnthr) {
+   17072           0 :                 if (wntqn) {
+   17073             : 
+   17074           0 :                     wrkbl = *n * 67;
+   17075           0 :                     i__1 = wrkbl, i__2 = bdspac + *n;
+   17076             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17077             :                 } else {
+   17078             : 
+   17079           0 :                     wrkbl = *n * 67;
+   17080           0 :                     i__1 = wrkbl, i__2 = *n + (*m << 5);
+   17081             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17082           0 :                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
+   17083             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17084           0 :                     maxwrk = wrkbl + *n * *n;
+   17085             :                 }
+   17086             :             } else {
+   17087             : 
+   17088           0 :                 wrkbl = *n * 3 + (*m + *n*32);
+   17089           0 :                 if (wntqn) {
+   17090           0 :                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
+   17091             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17092             :                 } else {
+   17093           0 :                     i__1 = maxwrk, i__2 = bdspac + *n * 3;
+   17094             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17095             :                 }
+   17096             :             }
+   17097             :         } else {
+   17098             : 
+   17099           0 :             if (wntqn) {
+   17100           0 :                 bdspac = *m * 7;
+   17101             :             } else {
+   17102           0 :                 bdspac = *m * 3 * *m + (*m*4);
+   17103             :             }
+   17104           0 :             if (*n >= mnthr) {
+   17105           0 :                 if (wntqn) {
+   17106             : 
+   17107           0 :                     wrkbl = *m * 67;
+   17108           0 :                     i__1 = wrkbl, i__2 = bdspac + *m;
+   17109             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17110             :                 } else {
+   17111             : 
+   17112           0 :                     wrkbl = *m * 67;
+   17113           0 :                     i__1 = wrkbl, i__2 = *m + (*n*32);
+   17114             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17115             : 
+   17116           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+   17117             :                     wrkbl = (i__1 > i__2) ? i__1 : i__2;
+   17118           0 :                     maxwrk = wrkbl + *m * *m;
+   17119             :                 }
+   17120             :             } else {
+   17121           0 :                 wrkbl = *m * 3 + (*m + *n*32);
+   17122           0 :                 if (wntqn) {
+   17123           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+   17124             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17125             :                 } else {
+   17126           0 :                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
+   17127             :                     maxwrk = (i__1 > i__2) ? i__1 : i__2;
+   17128             :                 }
+   17129             :             }
+   17130             :         }
+   17131           0 :         work[1] = (float) maxwrk;
+   17132             :     }
+   17133             :     
+   17134           0 :     if( lquery != 0)
+   17135             :     {
+   17136             :         return;
+   17137             :     }
+   17138             :     
+   17139           0 :     if (*m == 0 || *n == 0) {
+   17140           0 :         if (*lwork >= 1) {
+   17141           0 :             work[1] = 1.;
+   17142             :         }
+   17143           0 :         return;
+   17144             :     }
+   17145             :     eps = PLUMED_GMX_FLOAT_EPS;
+   17146             :     minval = PLUMED_GMX_FLOAT_MIN;
+   17147             :     safemin = minval / eps;
+   17148           0 :     smlnum =  std::sqrt(safemin) / eps;
+   17149             : 
+   17150             : 
+   17151           0 :     bignum = 1. / smlnum;
+   17152             : 
+   17153             : 
+   17154           0 :     anrm = PLUMED_BLAS_F77_FUNC(slange,SLANGE)("M", m, n, &a[a_offset], lda, dum);
+   17155             :     iscl = 0;
+   17156           0 :     if (anrm > 0. && anrm < smlnum) {
+   17157             :         iscl = 1;
+   17158           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&c__0,&c__0,&anrm,&smlnum,m,n,&a[a_offset],lda,&ierr);
+   17159           0 :     } else if (anrm > bignum) {
+   17160             :         iscl = 1;
+   17161           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&c__0,&c__0,&anrm,&bignum,m,n,&a[a_offset],lda,&ierr);
+   17162             :     }
+   17163             : 
+   17164           0 :     if (*m >= *n) {
+   17165           0 :         if (*m >= mnthr) {
+   17166             : 
+   17167           0 :             if (wntqn) {
+   17168             : 
+   17169             :                 itau = 1;
+   17170           0 :                 nwork = itau + *n;
+   17171             : 
+   17172           0 :                 i__1 = *lwork - nwork + 1;
+   17173           0 :                 PLUMED_BLAS_F77_FUNC(sgeqrf,SGEQRF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17174             :                         i__1, &ierr);
+   17175             : 
+   17176           0 :                 i__1 = *n - 1;
+   17177           0 :                 i__2 = *n - 1;
+   17178           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("L", &i__1, &i__2, &zero, &zero, &a[a_dim1 + 2], 
+   17179             :                         lda);
+   17180             :                 ie = 1;
+   17181           0 :                 itauq = ie + *n;
+   17182           0 :                 itaup = itauq + *n;
+   17183           0 :                 nwork = itaup + *n;
+   17184             : 
+   17185           0 :                 i__1 = *lwork - nwork + 1;
+   17186           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17187           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17188           0 :                 nwork = ie + *n;
+   17189             : 
+   17190           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17191           0 :                          dum, idum, &work[nwork], &iwork[1], info);
+   17192             : 
+   17193             :             } else {
+   17194             :                 iu = 1;
+   17195             : 
+   17196           0 :                 ldwrku = *n;
+   17197           0 :                 itau = iu + ldwrku * *n;
+   17198           0 :                 nwork = itau + *n;
+   17199             : 
+   17200           0 :                 i__1 = *lwork - nwork + 1;
+   17201           0 :                 PLUMED_BLAS_F77_FUNC(sgeqrf,SGEQRF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17202             :                         i__1, &ierr);
+   17203           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("L", m, n, &a[a_offset], lda, &u[u_offset], ldu);
+   17204             : 
+   17205           0 :                 i__1 = *lwork - nwork + 1;
+   17206           0 :                 PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(m, m, n, &u[u_offset], ldu, &work[itau], &work[nwork],
+   17207             :                          &i__1, &ierr);
+   17208             : 
+   17209           0 :                 i__1 = *n - 1;
+   17210           0 :                 i__2 = *n - 1;
+   17211           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("L", &i__1, &i__2, &zero, &zero, &a[a_dim1 + 2], 
+   17212             :                         lda);
+   17213             :                 ie = itau;
+   17214           0 :                 itauq = ie + *n;
+   17215           0 :                 itaup = itauq + *n;
+   17216           0 :                 nwork = itaup + *n;
+   17217             : 
+   17218           0 :                 i__1 = *lwork - nwork + 1;
+   17219           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17220           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17221             : 
+   17222           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "I", n, &s[1], &work[ie], &work[iu], n, &vt[
+   17223             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+   17224             :                         info);
+   17225             : 
+   17226           0 :                 i__1 = *lwork - nwork + 1;
+   17227           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", n, n, n, &a[a_offset], lda, &work[
+   17228             :                         itauq], &work[iu], &ldwrku, &work[nwork], &i__1, &
+   17229             :                         ierr);
+   17230           0 :                 i__1 = *lwork - nwork + 1;
+   17231           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
+   17232             :                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
+   17233             :                         ierr);
+   17234             : 
+   17235           0 :                 PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", m, n, n, &one, &u[u_offset], ldu, &work[iu]
+   17236             :                         , &ldwrku, &zero, &a[a_offset], lda);
+   17237             : 
+   17238           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("F", m, n, &a[a_offset], lda, &u[u_offset], ldu);
+   17239             : 
+   17240             :             }
+   17241             : 
+   17242             :         } else {
+   17243             :             ie = 1;
+   17244           0 :             itauq = ie + *n;
+   17245           0 :             itaup = itauq + *n;
+   17246           0 :             nwork = itaup + *n;
+   17247             : 
+   17248           0 :             i__1 = *lwork - nwork + 1;
+   17249           0 :             PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
+   17250           0 :                     work[itaup], &work[nwork], &i__1, &ierr);
+   17251           0 :             if (wntqn) {
+   17252             : 
+   17253           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17254             :                          dum, idum, &work[nwork], &iwork[1], info);
+   17255             :             } else {
+   17256             : 
+   17257           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", m, m, &zero, &zero, &u[u_offset], ldu);
+   17258           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
+   17259             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+   17260             :                         info);
+   17261             : 
+   17262           0 :                 i__1 = *m - *n;
+   17263           0 :                 i__2 = *m - *n;
+   17264           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", &i__1, &i__2, &zero, &one, &u[*n + 1 + (*n + 
+   17265           0 :                         1) * u_dim1], ldu);
+   17266             : 
+   17267           0 :                 i__1 = *lwork - nwork + 1;
+   17268           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
+   17269             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+   17270           0 :                 i__1 = *lwork - nwork + 1;
+   17271           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
+   17272             :                         itaup], &vt[vt_offset],ldvt,&work[nwork],&i__1,&ierr);
+   17273             :             }
+   17274             : 
+   17275             :         }
+   17276             : 
+   17277             :     } else {
+   17278             : 
+   17279           0 :         if (*n >= mnthr) {
+   17280             : 
+   17281           0 :             if (wntqn) {
+   17282             : 
+   17283             :                 itau = 1;
+   17284           0 :                 nwork = itau + *m;
+   17285             : 
+   17286           0 :                 i__1 = *lwork - nwork + 1;
+   17287           0 :                 PLUMED_BLAS_F77_FUNC(sgelqf,SGELQF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17288             :                         i__1, &ierr);
+   17289             : 
+   17290           0 :                 i__1 = *m - 1;
+   17291           0 :                 i__2 = *m - 1;
+   17292           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("U", &i__1, &i__2, &zero, &zero, &a[(a_dim1*2) + 
+   17293           0 :                         1], lda);
+   17294             :                 ie = 1;
+   17295           0 :                 itauq = ie + *m;
+   17296           0 :                 itaup = itauq + *m;
+   17297           0 :                 nwork = itaup + *m;
+   17298             : 
+   17299           0 :                 i__1 = *lwork - nwork + 1;
+   17300           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17301           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17302           0 :                 nwork = ie + *m;
+   17303             : 
+   17304           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17305           0 :                          dum, idum, &work[nwork], &iwork[1], info);
+   17306             : 
+   17307             :             } else {
+   17308             : 
+   17309             :                 ivt = 1;
+   17310             : 
+   17311           0 :                 ldwkvt = *m;
+   17312           0 :                 itau = ivt + ldwkvt * *m;
+   17313           0 :                 nwork = itau + *m;
+   17314             : 
+   17315           0 :                 i__1 = *lwork - nwork + 1;
+   17316           0 :                 PLUMED_BLAS_F77_FUNC(sgelqf,SGELQF)(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
+   17317             :                         i__1, &ierr);
+   17318           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
+   17319             : 
+   17320           0 :                 i__1 = *lwork - nwork + 1;
+   17321           0 :                 PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[
+   17322             :                         nwork], &i__1, &ierr);
+   17323             : 
+   17324           0 :                 i__1 = *m - 1;
+   17325           0 :                 i__2 = *m - 1;
+   17326           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("U", &i__1, &i__2, &zero, &zero, &a[(a_dim1*2) + 
+   17327           0 :                         1], lda);
+   17328             :                 ie = itau;
+   17329           0 :                 itauq = ie + *m;
+   17330           0 :                 itaup = itauq + *m;
+   17331           0 :                 nwork = itaup + *m;
+   17332             : 
+   17333           0 :                 i__1 = *lwork - nwork + 1;
+   17334           0 :                 PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
+   17335           0 :                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
+   17336             : 
+   17337           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
+   17338             :                         work[ivt], &ldwkvt, dum, idum, &work[nwork], &iwork[1]
+   17339             :                         , info);
+   17340             : 
+   17341           0 :                 i__1 = *lwork - nwork + 1;
+   17342           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", m, m, m, &a[a_offset], lda, &work[
+   17343             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+   17344           0 :                 i__1 = *lwork - nwork + 1;
+   17345           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", m, m, m, &a[a_offset], lda, &work[
+   17346             :                         itaup], &work[ivt], &ldwkvt, &work[nwork], &i__1, &
+   17347             :                         ierr);
+   17348             : 
+   17349           0 :                 PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", m, n, m, &one, &work[ivt], &ldwkvt, &vt[
+   17350             :                         vt_offset], ldvt, &zero, &a[a_offset], lda);
+   17351             : 
+   17352           0 :                 PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("F", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
+   17353             : 
+   17354             :             }
+   17355             : 
+   17356             :         } else {
+   17357             : 
+   17358             :             ie = 1;
+   17359           0 :             itauq = ie + *m;
+   17360           0 :             itaup = itauq + *m;
+   17361           0 :             nwork = itaup + *m;
+   17362             : 
+   17363           0 :             i__1 = *lwork - nwork + 1;
+   17364           0 :             PLUMED_BLAS_F77_FUNC(sgebrd,SGEBRD)(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
+   17365           0 :                     work[itaup], &work[nwork], &i__1, &ierr);
+   17366           0 :             if (wntqn) {
+   17367             : 
+   17368           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("L", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
+   17369             :                          dum, idum, &work[nwork], &iwork[1], info);
+   17370             :             } else {
+   17371           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", n, n, &zero, &zero, &vt[vt_offset], ldvt);
+   17372           0 :                 PLUMED_BLAS_F77_FUNC(sbdsdc,SBDSDC)("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
+   17373             :                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
+   17374             :                         info);
+   17375             : 
+   17376           0 :                 i__1 = *n - *m;
+   17377           0 :                 i__2 = *n - *m;
+   17378           0 :                 PLUMED_BLAS_F77_FUNC(slaset,SLASET)("F", &i__1, &i__2, &zero, &one, &vt[*m + 1 + (*m + 
+   17379           0 :                         1) * vt_dim1], ldvt);
+   17380             : 
+   17381           0 :                 i__1 = *lwork - nwork + 1;
+   17382           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
+   17383             :                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
+   17384           0 :                 i__1 = *lwork - nwork + 1;
+   17385           0 :                 PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
+   17386             :                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
+   17387             :                         ierr);
+   17388             :             }
+   17389             : 
+   17390             :         }
+   17391             : 
+   17392             :     }
+   17393             : 
+   17394           0 :     if (iscl == 1) {
+   17395           0 :         if (anrm > bignum) {
+   17396           0 :             PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &bignum, &anrm, &minmn, &c__1, &s[1], &
+   17397             :                     minmn, &ierr);
+   17398             :         }
+   17399           0 :         if (anrm < smlnum) {
+   17400           0 :             PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &smlnum, &anrm, &minmn, &c__1, &s[1], &
+   17401             :                     minmn, &ierr);
+   17402             :         }
+   17403             :     }
+   17404             : 
+   17405           0 :     work[1] = (float) maxwrk;
+   17406             : 
+   17407           0 :     return;
+   17408             : 
+   17409             : }
+   17410             : 
+   17411             : 
+   17412             : }
+   17413             : }
+   17414             : #include <cmath>
+   17415             : #include "real.h"
+   17416             : 
+   17417             : #include "blas/blas.h"
+   17418             : #include "lapack.h"
+   17419             : 
+   17420             : 
+   17421             : #include "blas/blas.h"
+   17422             : namespace PLMD{
+   17423             : namespace lapack{
+   17424             : using namespace blas;
+   17425             : void
+   17426           0 : PLUMED_BLAS_F77_FUNC(sgetf2,SGETF2)(int *m,
+   17427             :         int *n,
+   17428             :         float *a,
+   17429             :         int *lda,
+   17430             :         int *ipiv,
+   17431             :         int *info)
+   17432             : {
+   17433             :   int j,jp,k,t1,t2,t3;
+   17434             :   float minusone;
+   17435             :   float tmp;
+   17436             : 
+   17437           0 :   minusone = -1.0;
+   17438             : 
+   17439           0 :   if(*m<=0 || *n<=0)
+   17440             :     return;
+   17441             : 
+   17442             :   k = (*m < *n) ? *m : *n;
+   17443           0 :   for(j=1;j<=k;j++) {
+   17444           0 :     t1 = *m-j+1;
+   17445           0 :     t2 = 1;
+   17446           0 :     jp = j - 1 + PLUMED_BLAS_F77_FUNC(isamax,ISAMAX)(&t1,&(a[(j-1)*(*lda)+(j-1)]),&t2);
+   17447           0 :     ipiv[j-1] = jp;
+   17448           0 :     if( std::abs(a[(j-1)*(*lda)+(jp-1)])>PLUMED_GMX_FLOAT_MIN ) {
+   17449           0 :       if(jp != j)
+   17450           0 :         PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n,&(a[ j-1 ]),lda,&(a[ jp-1 ]),lda);
+   17451             :       
+   17452           0 :       if(j<*m) {
+   17453           0 :         t1 = *m-j;
+   17454           0 :         t2 = 1;
+   17455           0 :         tmp = 1.0/a[(j-1)*(*lda)+(j-1)];
+   17456           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&t1,&tmp,&(a[(j-1)*(*lda)+(j)]),&t2);
+   17457             :       }
+   17458             :     } else {
+   17459           0 :       *info = j;
+   17460             :     }
+   17461             : 
+   17462           0 :     if(j<k) {
+   17463           0 :       t1 = *m-j;
+   17464           0 :       t2 = *n-j;
+   17465           0 :       t3 = 1;
+   17466           0 :       PLUMED_BLAS_F77_FUNC(sger,SGER)(&t1,&t2,&minusone,&(a[(j-1)*(*lda)+(j)]),&t3,
+   17467           0 :             &(a[(j)*(*lda)+(j-1)]),lda, &(a[(j)*(*lda)+(j)]),lda);
+   17468             :     }
+   17469             :   }
+   17470             :   return;
+   17471             : }
+   17472             : }
+   17473             : }
+   17474             : #include "blas/blas.h"
+   17475             : #include "lapack.h"
+   17476             : #include "lapack_limits.h"
+   17477             : 
+   17478             : #include "blas/blas.h"
+   17479             : namespace PLMD{
+   17480             : namespace lapack{
+   17481             : using namespace blas;
+   17482             : void
+   17483           0 : PLUMED_BLAS_F77_FUNC(sgetrf,SGETRF)(int *m,
+   17484             :         int *n,
+   17485             :         float *a,
+   17486             :         int *lda,
+   17487             :         int *ipiv,
+   17488             :         int *info)
+   17489             : {
+   17490             :   int mindim,jb;
+   17491             :   int i,j,k,l;
+   17492             :   int iinfo;
+   17493           0 :   float minusone = -1.0;
+   17494           0 :   float one = 1.0;
+   17495             : 
+   17496           0 :   if(*m<=0 || *n<=0)
+   17497           0 :     return;
+   17498             : 
+   17499           0 :   *info = 0;
+   17500             : 
+   17501           0 :   mindim = (*m < *n) ? *m : *n;
+   17502             : 
+   17503           0 :   if(DGETRF_BLOCKSIZE>=mindim) {
+   17504             : 
+   17505             :     /* unblocked code */
+   17506           0 :     PLUMED_BLAS_F77_FUNC(sgetf2,SGETF2)(m,n,a,lda,ipiv,info);
+   17507             : 
+   17508             :   } else {
+   17509             : 
+   17510             :     /* blocked case */
+   17511             : 
+   17512           0 :     for(j=1;j<=mindim;j+=DGETRF_BLOCKSIZE) {
+   17513           0 :       jb = ( DGETRF_BLOCKSIZE < (mindim-j+1)) ? DGETRF_BLOCKSIZE : (mindim-j+1);
+   17514             :       /* factor diag. and subdiag blocks and test for singularity */
+   17515           0 :       k = *m-j+1;
+   17516           0 :       PLUMED_BLAS_F77_FUNC(sgetf2,SGETF2)(&k,&jb,&(a[(j-1)*(*lda)+(j-1)]),lda,&(ipiv[j-1]),&iinfo);
+   17517             :       
+   17518           0 :       if(*info==0 && iinfo>0)
+   17519           0 :         *info = iinfo + j - 1;
+   17520             : 
+   17521             :       /* adjust pivot indices */
+   17522           0 :       k = (*m < (j+jb-1)) ? *m : (j+jb-1);
+   17523           0 :       for(i=j;i<=k;i++)
+   17524           0 :         ipiv[i-1] += j - 1;
+   17525             : 
+   17526             :       /* Apply to columns 1 throughj j-1 */
+   17527           0 :       k = j - 1;
+   17528           0 :       i = j + jb - 1;
+   17529           0 :       l = 1;
+   17530           0 :       PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(&k,a,lda,&j,&i,ipiv,&l);
+   17531           0 :       if((j+jb)<=*n) {
+   17532             :         /* Apply to cols. j+jb through n */
+   17533           0 :         k = *n-j-jb+1;
+   17534           0 :         i = j+jb-1;
+   17535           0 :         l = 1;
+   17536           0 :         PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(&k,&(a[(j+jb-1)*(*lda)+0]),lda,&j,&i,ipiv,&l);
+   17537             :         /* Compute block row of U */
+   17538           0 :         k = *n-j-jb+1;
+   17539           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left","Lower","No transpose","Unit",&jb,&k,&one,
+   17540           0 :                &(a[(j-1)*(*lda)+(j-1)]),lda,&(a[(j+jb-1)*(*lda)+(j-1)]),lda);
+   17541             : 
+   17542           0 :         if((j+jb)<=*m) {
+   17543             :           /* Update trailing submatrix */
+   17544           0 :           k = *m-j-jb+1;
+   17545           0 :           i = *n-j-jb+1;
+   17546           0 :           PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose","No transpose",&k,&i,&jb,&minusone,
+   17547           0 :                  &(a[(j-1)*(*lda)+(j+jb-1)]),lda,
+   17548           0 :                  &(a[(j+jb-1)*(*lda)+(j-1)]),lda,&one,
+   17549           0 :                  &(a[(j+jb-1)*(*lda)+(j+jb-1)]),lda);
+   17550             :         }
+   17551             : 
+   17552             :       }
+   17553             :     }
+   17554             :   }
+   17555             : }
+   17556             : }
+   17557             : }
+   17558             : #include "blas/blas.h"
+   17559             : #include "lapack.h"
+   17560             : #include "lapack_limits.h"
+   17561             : 
+   17562             : #include "blas/blas.h"
+   17563             : namespace PLMD{
+   17564             : namespace lapack{
+   17565             : using namespace blas;
+   17566             : void
+   17567           0 : PLUMED_BLAS_F77_FUNC(sgetri,SGETRI)(int *n, 
+   17568             :         float *a, 
+   17569             :         int *lda, 
+   17570             :         int *ipiv, 
+   17571             :         float *work, 
+   17572             :         int *lwork, 
+   17573             :         int *info)
+   17574             : {
+   17575             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   17576             : 
+   17577             :     int i__, j, jb, nb, jj, jp, nn, iws;
+   17578             :     int nbmin;
+   17579             :     int ldwork;
+   17580             :     int lwkopt;
+   17581           0 :     int c__1 = 1;
+   17582           0 :     float c_b20 = -1.;
+   17583           0 :     float c_b22 = 1.;
+   17584             : 
+   17585           0 :     a_dim1 = *lda;
+   17586           0 :     a_offset = 1 + a_dim1;
+   17587           0 :     a -= a_offset;
+   17588             :     --ipiv;
+   17589           0 :     --work;
+   17590             : 
+   17591           0 :     *info = 0;
+   17592             :     nb = DGETRI_BLOCKSIZE;
+   17593           0 :     lwkopt = *n * nb;
+   17594           0 :     work[1] = (float) lwkopt;
+   17595             : 
+   17596           0 :     if (*n < 0) {
+   17597           0 :         *info = -1;
+   17598           0 :     } else if (*lda < (*n)) {
+   17599           0 :         *info = -3;
+   17600           0 :     } else if (*lwork < (*n) && *lwork!=-1) {
+   17601           0 :         *info = -6;
+   17602             :     }
+   17603           0 :     if (*info != 0) {
+   17604             :         i__1 = -(*info);
+   17605             :         return;
+   17606           0 :     } else if (*lwork == -1) {
+   17607             :         return;
+   17608             :     }
+   17609             : 
+   17610           0 :     if (*n == 0) {
+   17611             :         return;
+   17612             :     }
+   17613             : 
+   17614           0 :     PLUMED_BLAS_F77_FUNC(strtri,STRTRI)("Upper", "Non-unit", n, &a[a_offset], lda, info);
+   17615           0 :     if (*info > 0) {
+   17616             :         return;
+   17617             :     }
+   17618             : 
+   17619             :     nbmin = 2;
+   17620           0 :     ldwork = *n;
+   17621           0 :     if (nb > 1 && nb < *n) {
+   17622           0 :         i__1 = ldwork * nb;
+   17623           0 :         iws = (i__1>1) ? i__1 : 1;
+   17624           0 :         if (*lwork < iws) {
+   17625           0 :             nb = *lwork / ldwork;
+   17626             :             nbmin = DGETRI_MINBLOCKSIZE;
+   17627             :         }
+   17628             :     } else {
+   17629             :         iws = *n;
+   17630             :     }
+   17631             : 
+   17632           0 :     if (nb < nbmin || nb >= *n) {
+   17633             : 
+   17634           0 :         for (j = *n; j >= 1; --j) {
+   17635             : 
+   17636           0 :             i__1 = *n;
+   17637           0 :             for (i__ = j + 1; i__ <= i__1; ++i__) {
+   17638           0 :                 work[i__] = a[i__ + j * a_dim1];
+   17639           0 :                 a[i__ + j * a_dim1] = 0.;
+   17640             :             }
+   17641             : 
+   17642           0 :             if (j < *n) {
+   17643           0 :                 i__1 = *n - j;
+   17644           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", n, &i__1, &c_b20, &a[(j + 1) * a_dim1 
+   17645           0 :                         + 1], lda, &work[j + 1], &c__1, &c_b22, &a[j * a_dim1 
+   17646           0 :                         + 1], &c__1);
+   17647             :             }
+   17648             :         }
+   17649             :     } else {
+   17650             : 
+   17651           0 :         nn = (*n - 1) / nb * nb + 1;
+   17652           0 :         i__1 = -nb;
+   17653           0 :         for (j = nn; i__1 < 0 ? j >= 1 : j <= 1; j += i__1) {
+   17654           0 :             i__2 = nb, i__3 = *n - j + 1;
+   17655           0 :             jb = (i__2<i__3) ? i__2 : i__3;
+   17656             : 
+   17657           0 :             i__2 = j + jb - 1;
+   17658           0 :             for (jj = j; jj <= i__2; ++jj) {
+   17659           0 :                 i__3 = *n;
+   17660           0 :                 for (i__ = jj + 1; i__ <= i__3; ++i__) {
+   17661           0 :                     work[i__ + (jj - j) * ldwork] = a[i__ + jj * a_dim1];
+   17662           0 :                     a[i__ + jj * a_dim1] = 0.;
+   17663             :                 }
+   17664             :             }
+   17665             : 
+   17666           0 :             if (j + jb <= *n) {
+   17667           0 :                 i__2 = *n - j - jb + 1;
+   17668           0 :                 PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", n, &jb, &i__2, &c_b20, 
+   17669           0 :                         &a[(j + jb) * a_dim1 + 1], lda, &work[j + jb], &
+   17670           0 :                         ldwork, &c_b22, &a[j * a_dim1 + 1], lda);
+   17671             :             }
+   17672           0 :             PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Right", "Lower", "No transpose", "Unit", n, &jb, &c_b22, &
+   17673           0 :                     work[j], &ldwork, &a[j * a_dim1 + 1], lda);
+   17674             :         }
+   17675             :     }
+   17676             : 
+   17677           0 :     for (j = *n - 1; j >= 1; --j) {
+   17678           0 :         jp = ipiv[j];
+   17679           0 :         if (jp != j) {
+   17680           0 :             PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &a[j * a_dim1 + 1], &c__1, &a[jp * a_dim1 + 1], &c__1);
+   17681             :         }
+   17682             :     }
+   17683             : 
+   17684           0 :     work[1] = (float) iws;
+   17685           0 :     return;
+   17686             : 
+   17687             : }
+   17688             : 
+   17689             : 
+   17690             : }
+   17691             : }
+   17692             : #include "blas/blas.h"
+   17693             : #include "lapack.h"
+   17694             : 
+   17695             : #include "blas/blas.h"
+   17696             : namespace PLMD{
+   17697             : namespace lapack{
+   17698             : using namespace blas;
+   17699             : void
+   17700           0 : PLUMED_BLAS_F77_FUNC(sgetrs,SGETRS)(const char *trans, 
+   17701             :         int *n, 
+   17702             :         int *nrhs, 
+   17703             :         float *a, 
+   17704             :         int *lda, 
+   17705             :         int *ipiv,
+   17706             :         float *b, 
+   17707             :         int *ldb, 
+   17708             :         int *info)
+   17709             : {
+   17710             :     int a_dim1, a_offset, b_dim1, b_offset;
+   17711             :     int notran;
+   17712           0 :     int c__1 = 1;
+   17713           0 :     int c_n1 = -1;
+   17714           0 :     float one = 1.0;
+   17715             : 
+   17716             :     a_dim1 = *lda;
+   17717             :     a_offset = 1 + a_dim1;
+   17718             :     a -= a_offset;
+   17719             :     --ipiv;
+   17720             :     b_dim1 = *ldb;
+   17721             :     b_offset = 1 + b_dim1;
+   17722             :     b -= b_offset;
+   17723             : 
+   17724           0 :     *info = 0;
+   17725           0 :     notran = (*trans=='N' || *trans=='n');
+   17726             : 
+   17727           0 :     if (*n <= 0 || *nrhs <= 0) 
+   17728             :         return;
+   17729             : 
+   17730           0 :     if (notran) {
+   17731           0 :         PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c__1);
+   17732           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Lower", "No transpose", "Unit", n, nrhs, &one, 
+   17733             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17734             : 
+   17735           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Upper", "No transpose", "Non-unit", n, nrhs, &one, 
+   17736             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17737             :     } else {
+   17738           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Upper", "Transpose", "Non-unit", n, nrhs, &one, 
+   17739             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17740           0 :         PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Left", "Lower", "Transpose", "Unit", n, nrhs, &one, 
+   17741             :                &a[a_offset], lda, &b[b_offset], ldb);
+   17742             : 
+   17743           0 :         PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(nrhs, &b[b_offset], ldb, &c__1, n, &ipiv[1], &c_n1);
+   17744             :     }
+   17745             : 
+   17746             :     return;
+   17747             : 
+   17748             : } 
+   17749             : }
+   17750             : }
+   17751             : #include <cmath>
+   17752             : #include "blas/blas.h"
+   17753             : #include "lapack.h"
+   17754             : 
+   17755             : 
+   17756             : #include "blas/blas.h"
+   17757             : namespace PLMD{
+   17758             : namespace lapack{
+   17759             : using namespace blas;
+   17760             : void 
+   17761           0 : PLUMED_BLAS_F77_FUNC(slabrd,SLABRD)(int *m, 
+   17762             :         int *n, 
+   17763             :         int *nb,
+   17764             :         float *a, 
+   17765             :         int *lda, 
+   17766             :         float *d__,
+   17767             :         float *e,
+   17768             :         float *tauq, 
+   17769             :         float *taup,
+   17770             :         float *x,
+   17771             :         int *ldx,
+   17772             :         float *y,
+   17773             :         int *ldy)
+   17774             : {
+   17775             :     int a_dim1, a_offset, x_dim1, x_offset, y_dim1, y_offset;
+   17776             :     int i__1, i__2, i__3;
+   17777           0 :     float one = 1.0;
+   17778           0 :     float minusone = -1.0;
+   17779           0 :     float zero = 0.0;
+   17780           0 :     int c__1 = 1;
+   17781             :     int i__;
+   17782             : 
+   17783           0 :     a_dim1 = *lda;
+   17784           0 :     a_offset = 1 + a_dim1;
+   17785           0 :     a -= a_offset;
+   17786           0 :     --d__;
+   17787           0 :     --e;
+   17788           0 :     --tauq;
+   17789           0 :     --taup;
+   17790           0 :     x_dim1 = *ldx;
+   17791           0 :     x_offset = 1 + x_dim1;
+   17792           0 :     x -= x_offset;
+   17793           0 :     y_dim1 = *ldy;
+   17794           0 :     y_offset = 1 + y_dim1;
+   17795           0 :     y -= y_offset;
+   17796             : 
+   17797           0 :     if (*m <= 0 || *n <= 0) {
+   17798             :         return;
+   17799             :     }
+   17800             : 
+   17801           0 :     if (*m >= *n) {
+   17802             : 
+   17803           0 :         i__1 = *nb;
+   17804           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   17805             : 
+   17806           0 :             i__2 = *m - i__ + 1;
+   17807           0 :             i__3 = i__ - 1;
+   17808           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + a_dim1], lda,
+   17809           0 :                      &y[i__ + y_dim1], ldy, &one, &a[i__ + i__ * a_dim1], &c__1);
+   17810           0 :             i__2 = *m - i__ + 1;
+   17811           0 :             i__3 = i__ - 1;
+   17812           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + x_dim1], ldx,
+   17813           0 :                    &a[i__*a_dim1+1],&c__1,&one,&a[i__+i__*a_dim1],&c__1);
+   17814             : 
+   17815           0 :             i__2 = *m - i__ + 1;
+   17816           0 :             i__3 = i__ + 1;
+   17817           0 :             if(*m<i__3)
+   17818           0 :               i__3 = *m;
+   17819           0 :             PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + i__ * a_dim1], &a[i__3 + i__ * a_dim1], 
+   17820           0 :                     &c__1, &tauq[i__]);
+   17821           0 :             d__[i__] = a[i__ + i__ * a_dim1];
+   17822           0 :             if (i__ < *n) {
+   17823           0 :                 a[i__ + i__ * a_dim1] = 1.;
+   17824             : 
+   17825           0 :                 i__2 = *m - i__ + 1;
+   17826           0 :                 i__3 = *n - i__;
+   17827           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + (i__ + 1) * 
+   17828           0 :                         a_dim1], lda, &a[i__ + i__ * a_dim1], &c__1, &zero, &
+   17829           0 :                         y[i__ + 1 + i__ * y_dim1], &c__1);
+   17830           0 :                 i__2 = *m - i__ + 1;
+   17831           0 :                 i__3 = i__ - 1;
+   17832           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + a_dim1], 
+   17833           0 :                         lda, &a[i__ + i__ * a_dim1], &c__1, &zero, &y[i__ * 
+   17834           0 :                         y_dim1 + 1], &c__1);
+   17835           0 :                 i__2 = *n - i__;
+   17836           0 :                 i__3 = i__ - 1;
+   17837           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + 1 + 
+   17838           0 :                         y_dim1], ldy, &y[i__ * y_dim1 + 1], &c__1, &one, &y[
+   17839           0 :                         i__ + 1 + i__ * y_dim1], &c__1);
+   17840           0 :                 i__2 = *m - i__ + 1;
+   17841           0 :                 i__3 = i__ - 1;
+   17842           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &x[i__ + x_dim1], 
+   17843           0 :                         ldx, &a[i__ + i__ * a_dim1], &c__1, &zero, &y[i__ * 
+   17844           0 :                         y_dim1 + 1], &c__1);
+   17845           0 :                 i__2 = i__ - 1;
+   17846           0 :                 i__3 = *n - i__;
+   17847           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &minusone, &a[(i__ + 1) * 
+   17848           0 :                         a_dim1 + 1], lda, &y[i__ * y_dim1 + 1], &c__1, &one, 
+   17849           0 :                         &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17850           0 :                 i__2 = *n - i__;
+   17851           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &tauq[i__], &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17852             : 
+   17853           0 :                 i__2 = *n - i__;
+   17854           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__, &minusone, &y[i__ + 1 + 
+   17855           0 :                         y_dim1], ldy, &a[i__ + a_dim1], lda, &one, &a[i__ + (
+   17856           0 :                         i__ + 1) * a_dim1], lda);
+   17857           0 :                 i__2 = i__ - 1;
+   17858           0 :                 i__3 = *n - i__;
+   17859           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &minusone, &a[(i__ + 1) * 
+   17860           0 :                         a_dim1 + 1], lda, &x[i__ + x_dim1], ldx, &one, &a[
+   17861           0 :                         i__ + (i__ + 1) * a_dim1], lda);
+   17862             : 
+   17863           0 :                 i__2 = *n - i__;
+   17864           0 :                 i__3 = i__ + 2;
+   17865           0 :                 if(*n<i__3)
+   17866           0 :                   i__3 = *n;
+   17867           0 :                 PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + (i__ + 1) * a_dim1], 
+   17868           0 :                         &a[i__ + i__3 * a_dim1], lda, &taup[i__]);
+   17869           0 :                 e[i__] = a[i__ + (i__ + 1) * a_dim1];
+   17870           0 :                 a[i__ + (i__ + 1) * a_dim1] = 1.;
+   17871             : 
+   17872           0 :                 i__2 = *m - i__;
+   17873           0 :                 i__3 = *n - i__;
+   17874           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &one, &a[i__ + 1 + (i__ 
+   17875           0 :                         + 1) * a_dim1], lda, &a[i__ + (i__ + 1) * a_dim1], 
+   17876           0 :                         lda, &zero, &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17877           0 :                 i__2 = *n - i__;
+   17878           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__, &one, &y[i__ + 1 + y_dim1], 
+   17879           0 :                         ldy, &a[i__ + (i__ + 1) * a_dim1], lda, &zero, &x[
+   17880           0 :                         i__ * x_dim1 + 1], &c__1);
+   17881           0 :                 i__2 = *m - i__;
+   17882           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__, &minusone, &a[i__ + 1 + 
+   17883           0 :                         a_dim1], lda, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17884           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17885           0 :                 i__2 = i__ - 1;
+   17886           0 :                 i__3 = *n - i__;
+   17887           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &one, &a[(i__ + 1) * 
+   17888           0 :                         a_dim1 + 1], lda, &a[i__ + (i__ + 1) * a_dim1], lda, &
+   17889           0 :                         zero, &x[i__ * x_dim1 + 1], &c__1);
+   17890           0 :                 i__2 = *m - i__;
+   17891           0 :                 i__3 = i__ - 1;
+   17892           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + 1 + 
+   17893           0 :                         x_dim1], ldx, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17894           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17895           0 :                 i__2 = *m - i__;
+   17896           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &taup[i__], &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17897             :             }
+   17898             :         }
+   17899             :     } else {
+   17900             : 
+   17901           0 :         i__1 = *nb;
+   17902           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   17903             : 
+   17904           0 :             i__2 = *n - i__ + 1;
+   17905           0 :             i__3 = i__ - 1;
+   17906           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + y_dim1], ldy,
+   17907           0 :                      &a[i__ + a_dim1], lda, &one, &a[i__ + i__ * a_dim1],lda);
+   17908           0 :             i__2 = i__ - 1;
+   17909           0 :             i__3 = *n - i__ + 1;
+   17910           0 :             PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &minusone, &a[i__ * a_dim1 + 1], 
+   17911           0 :                     lda, &x[i__ + x_dim1], ldx, &one,&a[i__+i__*a_dim1],lda);
+   17912             : 
+   17913           0 :             i__2 = *n - i__ + 1;
+   17914           0 :             i__3 = i__ + 1;
+   17915           0 :             if(*n<i__3)
+   17916           0 :               i__3 = *n;
+   17917           0 :             PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + i__ * a_dim1], 
+   17918           0 :                     &a[i__ + i__3 * a_dim1], lda, &taup[i__]);
+   17919           0 :             d__[i__] = a[i__ + i__ * a_dim1];
+   17920           0 :             if (i__ < *m) {
+   17921           0 :                 a[i__ + i__ * a_dim1] = 1.;
+   17922             : 
+   17923           0 :                 i__2 = *m - i__;
+   17924           0 :                 i__3 = *n - i__ + 1;
+   17925           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose",&i__2,&i__3,&one,&a[i__+1+i__*a_dim1], 
+   17926             :                        lda, &a[i__ + i__ * a_dim1], lda, &zero, 
+   17927           0 :                        &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17928           0 :                 i__2 = *n - i__ + 1;
+   17929           0 :                 i__3 = i__ - 1;
+   17930           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &y[i__ + y_dim1], 
+   17931           0 :                         ldy, &a[i__ + i__ * a_dim1], lda, &zero, &x[i__ * 
+   17932           0 :                         x_dim1 + 1], &c__1);
+   17933           0 :                 i__2 = *m - i__;
+   17934           0 :                 i__3 = i__ - 1;
+   17935           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + 1 + 
+   17936           0 :                         a_dim1], lda, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17937           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17938           0 :                 i__2 = i__ - 1;
+   17939           0 :                 i__3 = *n - i__ + 1;
+   17940           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &one, &a[i__ * a_dim1 + 
+   17941           0 :                         1], lda, &a[i__ + i__ * a_dim1], lda, &zero, &x[i__ *
+   17942           0 :                          x_dim1 + 1], &c__1);
+   17943           0 :                 i__2 = *m - i__;
+   17944           0 :                 i__3 = i__ - 1;
+   17945           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &x[i__ + 1 + 
+   17946           0 :                         x_dim1], ldx, &x[i__ * x_dim1 + 1], &c__1, &one, &x[
+   17947           0 :                         i__ + 1 + i__ * x_dim1], &c__1);
+   17948           0 :                 i__2 = *m - i__;
+   17949           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &taup[i__], &x[i__ + 1 + i__ * x_dim1], &c__1);
+   17950             : 
+   17951           0 :                 i__2 = *m - i__;
+   17952           0 :                 i__3 = i__ - 1;
+   17953           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &a[i__ + 1 + 
+   17954           0 :                         a_dim1], lda, &y[i__ + y_dim1], ldy, &one, &a[i__ + 
+   17955           0 :                         1 + i__ * a_dim1], &c__1);
+   17956           0 :                 i__2 = *m - i__;
+   17957           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__, &minusone, &x[i__ + 1 + 
+   17958           0 :                         x_dim1], ldx, &a[i__ * a_dim1 + 1], &c__1, &one, &a[
+   17959           0 :                         i__ + 1 + i__ * a_dim1], &c__1);
+   17960             : 
+   17961           0 :                 i__2 = *m - i__;
+   17962           0 :                 i__3 = i__ + 2;
+   17963           0 :                 if(*m<i__3)
+   17964           0 :                   i__3 = *m;
+   17965           0 :                 PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i__2, &a[i__ + 1 + i__ * a_dim1], 
+   17966           0 :                         &a[i__3 + i__ * a_dim1], &c__1, &tauq[i__]);
+   17967           0 :                 e[i__] = a[i__ + 1 + i__ * a_dim1];
+   17968           0 :                 a[i__ + 1 + i__ * a_dim1] = 1.;
+   17969             : 
+   17970           0 :                 i__2 = *m - i__;
+   17971           0 :                 i__3 = *n - i__;
+   17972           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + 1 + (i__ + 
+   17973           0 :                         1) * a_dim1], lda, &a[i__ + 1 + i__ * a_dim1], &c__1, 
+   17974           0 :                         &zero, &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17975           0 :                 i__2 = *m - i__;
+   17976           0 :                 i__3 = i__ - 1;
+   17977           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &one, &a[i__ + 1 + a_dim1],
+   17978           0 :                          lda, &a[i__ + 1 + i__ * a_dim1], &c__1, &zero, &y[
+   17979           0 :                         i__ * y_dim1 + 1], &c__1);
+   17980           0 :                 i__2 = *n - i__;
+   17981           0 :                 i__3 = i__ - 1;
+   17982           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &minusone, &y[i__ + 1 + 
+   17983           0 :                         y_dim1], ldy, &y[i__ * y_dim1 + 1], &c__1, &one, &y[
+   17984           0 :                         i__ + 1 + i__ * y_dim1], &c__1);
+   17985           0 :                 i__2 = *m - i__;
+   17986           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__, &one, &x[i__ + 1 + x_dim1], 
+   17987           0 :                         ldx, &a[i__ + 1 + i__ * a_dim1], &c__1, &zero, &y[
+   17988           0 :                         i__ * y_dim1 + 1], &c__1);
+   17989           0 :                 i__2 = *n - i__;
+   17990           0 :                 PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__, &i__2, &minusone, &a[(i__ + 1) * a_dim1 
+   17991           0 :                         + 1], lda, &y[i__ * y_dim1 + 1], &c__1, &one, &y[i__ 
+   17992           0 :                         + 1 + i__ * y_dim1], &c__1);
+   17993           0 :                 i__2 = *n - i__;
+   17994           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &tauq[i__], &y[i__ + 1 + i__ * y_dim1], &c__1);
+   17995             :             }
+   17996             :         }
+   17997             :     }
+   17998             :     return;
+   17999             : } 
+   18000             : 
+   18001             : }
+   18002             : }
+   18003             : #include <cctype>
+   18004             : #include "lapack.h"
+   18005             : 
+   18006             : /* LAPACK */
+   18007             : #include "blas/blas.h"
+   18008             : namespace PLMD{
+   18009             : namespace lapack{
+   18010             : using namespace blas;
+   18011             : void
+   18012           0 : PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)(const char *uplo,
+   18013             :         int *m,
+   18014             :         int *n,
+   18015             :         float *a,
+   18016             :         int *lda,
+   18017             :         float *b,
+   18018             :         int *ldb)
+   18019             : {
+   18020             :   int i,j,minjm;
+   18021           0 :   const char ch=std::toupper(*uplo);
+   18022             : 
+   18023           0 :   if(ch=='U') {
+   18024           0 :     for(j=0;j<*n;j++) {
+   18025           0 :       minjm = (j < (*m-1)) ? j : (*m-1);
+   18026           0 :       for(i=0;i<=minjm;i++)
+   18027           0 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+   18028             :     }
+   18029           0 :   } else if(ch=='L') {
+   18030           0 :     for(j=0;j<*n;j++) {
+   18031           0 :       for(i=j;i<*m;i++)
+   18032           0 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+   18033             :     }
+   18034             :   } else {
+   18035           0 :     for(j=0;j<*n;j++) {
+   18036           0 :       for(i=0;i<*m;i++)
+   18037           0 :         b[j*(*ldb)+i] = a[j*(*lda)+i];
+   18038             :     }    
+   18039             :   }
+   18040           0 : }
+   18041             : }
+   18042             : }
+   18043             : #include <cmath>
+   18044             : #include "lapack.h"
+   18045             : 
+   18046             : 
+   18047             : #include "blas/blas.h"
+   18048             : namespace PLMD{
+   18049             : namespace lapack{
+   18050             : using namespace blas;
+   18051             : void
+   18052           0 : PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(float *a, 
+   18053             :        float *b,
+   18054             :        float *c__, 
+   18055             :        float *rt1, 
+   18056             :        float *rt2)
+   18057             : {
+   18058             :     float d__1;
+   18059             :     float ab, df, tb, sm, rt, adf, acmn, acmx;
+   18060             : 
+   18061             : 
+   18062           0 :     sm = *a + *c__;
+   18063           0 :     df = *a - *c__;
+   18064             :     adf = std::abs(df);
+   18065           0 :     tb = *b + *b;
+   18066             :     ab = std::abs(tb);
+   18067           0 :     if (std::abs(*a) > std::abs(*c__)) {
+   18068             :         acmx = *a;
+   18069             :         acmn = *c__;
+   18070             :     } else {
+   18071             :         acmx = *c__;
+   18072             :         acmn = *a;
+   18073             :     }
+   18074           0 :     if (adf > ab) {
+   18075           0 :         d__1 = ab / adf;
+   18076           0 :         rt = adf *  std::sqrt(d__1 * d__1 + 1.);
+   18077           0 :     } else if (adf < ab) {
+   18078           0 :         d__1 = adf / ab;
+   18079           0 :         rt = ab *  std::sqrt(d__1 * d__1 + 1.);
+   18080             :     } else {
+   18081             : 
+   18082           0 :         rt = ab *  std::sqrt(2.);
+   18083             :     }
+   18084           0 :     if (sm < 0.) {
+   18085           0 :         *rt1 = (sm - rt) * .5;
+   18086           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18087           0 :     } else if (sm > 0.) {
+   18088           0 :         *rt1 = (sm + rt) * .5;
+   18089           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18090             :     } else {
+   18091           0 :         *rt1 = rt * .5;
+   18092           0 :         *rt2 = rt * -.5;
+   18093             :     }
+   18094           0 :     return;
+   18095             : 
+   18096             : }
+   18097             : 
+   18098             : 
+   18099             : }
+   18100             : }
+   18101             : #include <cmath>
+   18102             : #include "lapack.h"
+   18103             : 
+   18104             : #include "blas/blas.h"
+   18105             : namespace PLMD{
+   18106             : namespace lapack{
+   18107             : using namespace blas;
+   18108             : void
+   18109           0 : PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(int *ijob,
+   18110             :         int *nitmax,
+   18111             :         int *n, 
+   18112             :         int *mmax,
+   18113             :         int *minp,
+   18114             :         int *nbmin,
+   18115             :         float *abstol, 
+   18116             :         float *reltol, 
+   18117             :         float *pivmin, 
+   18118             :         float *d__,
+   18119             :         float *e,
+   18120             :         float *e2, 
+   18121             :         int *nval,
+   18122             :         float *ab, 
+   18123             :         float *c__, 
+   18124             :         int *mout, 
+   18125             :         int *nab,
+   18126             :         float *work,
+   18127             :         int *iwork, 
+   18128             :         int *info)
+   18129             : {
+   18130             :     int nab_dim1, nab_offset, ab_dim1, ab_offset, i__1, i__2, i__3, i__4, 
+   18131             :             i__5, i__6;
+   18132             :     float d__1, d__2, d__3, d__4;
+   18133             : 
+   18134             :     int j, kf, ji, kl, jp, jit;
+   18135             :     float tmp1, tmp2;
+   18136             :     int itmp1, itmp2, kfnew, klnew;
+   18137             : 
+   18138           0 :     nab_dim1 = *mmax;
+   18139           0 :     nab_offset = 1 + nab_dim1;
+   18140           0 :     nab -= nab_offset;
+   18141             :     ab_dim1 = *mmax;
+   18142             :     ab_offset = 1 + ab_dim1;
+   18143           0 :     ab -= ab_offset;
+   18144           0 :     --d__;
+   18145             :     --e;
+   18146           0 :     --e2;
+   18147           0 :     --nval;
+   18148           0 :     --c__;
+   18149           0 :     --work;
+   18150           0 :     --iwork;
+   18151             : 
+   18152           0 :     *info = 0;
+   18153           0 :     if (*ijob < 1 || *ijob > 3) {
+   18154           0 :         *info = -1;
+   18155           0 :         return;
+   18156             :     }
+   18157             : 
+   18158           0 :     if (*ijob == 1) {
+   18159             : 
+   18160           0 :         *mout = 0;
+   18161             : 
+   18162           0 :         i__1 = *minp;
+   18163           0 :         for (ji = 1; ji <= i__1; ++ji) {
+   18164           0 :             for (jp = 1; jp <= 2; ++jp) {
+   18165           0 :                 tmp1 = d__[1] - ab[ji + jp * ab_dim1];
+   18166           0 :                 if (std::abs(tmp1) < *pivmin) {
+   18167           0 :                     tmp1 = -(*pivmin);
+   18168             :                 }
+   18169           0 :                 nab[ji + jp * nab_dim1] = 0;
+   18170           0 :                 if (tmp1 <= 0.) {
+   18171           0 :                     nab[ji + jp * nab_dim1] = 1;
+   18172             :                 }
+   18173             : 
+   18174           0 :                 i__2 = *n;
+   18175           0 :                 for (j = 2; j <= i__2; ++j) {
+   18176           0 :                     tmp1 = d__[j] - e2[j - 1] / tmp1 - ab[ji + jp * ab_dim1];
+   18177           0 :                     if (std::abs(tmp1) < *pivmin) {
+   18178           0 :                         tmp1 = -(*pivmin);
+   18179             :                     }
+   18180           0 :                     if (tmp1 <= 0.) {
+   18181           0 :                         ++nab[ji + jp * nab_dim1];
+   18182             :                     }
+   18183             :                 }
+   18184             :             }
+   18185           0 :             *mout = *mout + nab[ji + (nab_dim1 << 1)] - nab[ji + nab_dim1];
+   18186             :         }
+   18187             :         return;
+   18188             :     }
+   18189             : 
+   18190             :     kf = 1;
+   18191           0 :     kl = *minp;
+   18192             : 
+   18193           0 :     if (*ijob == 2) {
+   18194             :         i__1 = *minp;
+   18195           0 :         for (ji = 1; ji <= i__1; ++ji) {
+   18196           0 :             c__[ji] = (ab[ji + ab_dim1] + ab[ji + (ab_dim1 << 1)]) * .5;
+   18197             :         }
+   18198             :     }
+   18199             : 
+   18200           0 :     i__1 = *nitmax;
+   18201           0 :     for (jit = 1; jit <= i__1; ++jit) {
+   18202             : 
+   18203           0 :         if (kl - kf + 1 >= *nbmin && *nbmin > 0) {
+   18204             : 
+   18205             :             i__2 = kl;
+   18206           0 :             for (ji = kf; ji <= i__2; ++ji) {
+   18207             : 
+   18208           0 :                 work[ji] = d__[1] - c__[ji];
+   18209           0 :                 iwork[ji] = 0;
+   18210           0 :                 if (work[ji] <= *pivmin) {
+   18211           0 :                     iwork[ji] = 1;
+   18212           0 :                     d__1 = work[ji], d__2 = -(*pivmin);
+   18213           0 :                     work[ji] = (d__1<d__2) ? d__1 : d__2;
+   18214             :                 }
+   18215             : 
+   18216           0 :                 i__3 = *n;
+   18217           0 :                 for (j = 2; j <= i__3; ++j) {
+   18218           0 :                     work[ji] = d__[j] - e2[j - 1] / work[ji] - c__[ji];
+   18219           0 :                     if (work[ji] <= *pivmin) {
+   18220           0 :                         ++iwork[ji];
+   18221           0 :                         d__1 = work[ji], d__2 = -(*pivmin);
+   18222           0 :                         work[ji] = (d__1<d__2) ? d__1 : d__2;
+   18223             :                     }
+   18224             :                 }
+   18225             :             }
+   18226             : 
+   18227           0 :             if (*ijob <= 2) {
+   18228             : 
+   18229             :                 klnew = kl;
+   18230             :                 i__2 = kl;
+   18231           0 :                 for (ji = kf; ji <= i__2; ++ji) {
+   18232             : 
+   18233           0 :                   i__5 = nab[ji + nab_dim1];
+   18234           0 :                   i__6 = iwork[ji];
+   18235           0 :                   i__3 = nab[ji + (nab_dim1 << 1)];
+   18236             :                   i__4 = (i__5>i__6) ? i__5 : i__6;
+   18237           0 :                     iwork[ji] = (i__3<i__4) ? i__3 : i__4;
+   18238             : 
+   18239           0 :                     if (iwork[ji] == nab[ji + (nab_dim1 << 1)]) {
+   18240             : 
+   18241           0 :                         ab[ji + (ab_dim1 << 1)] = c__[ji];
+   18242             : 
+   18243           0 :                     } else if (iwork[ji] == nab[ji + nab_dim1]) {
+   18244             : 
+   18245           0 :                         ab[ji + ab_dim1] = c__[ji];
+   18246             :                     } else {
+   18247           0 :                         ++klnew;
+   18248           0 :                         if (klnew <= *mmax) {
+   18249             : 
+   18250           0 :                             ab[klnew + (ab_dim1 << 1)] = ab[ji + (ab_dim1 << 
+   18251           0 :                                     1)];
+   18252           0 :                             nab[klnew + (nab_dim1 << 1)] = nab[ji + (nab_dim1 
+   18253           0 :                                     << 1)];
+   18254           0 :                             ab[klnew + ab_dim1] = c__[ji];
+   18255           0 :                             nab[klnew + nab_dim1] = iwork[ji];
+   18256           0 :                             ab[ji + (ab_dim1 << 1)] = c__[ji];
+   18257           0 :                             nab[ji + (nab_dim1 << 1)] = iwork[ji];
+   18258             :                         } else {
+   18259           0 :                             *info = *mmax + 1;
+   18260             :                         }
+   18261             :                     }
+   18262             :                 }
+   18263           0 :                 if (*info != 0) {
+   18264             :                     return;
+   18265             :                 }
+   18266             :                 kl = klnew;
+   18267             :             } else {
+   18268             : 
+   18269             :                 i__2 = kl;
+   18270           0 :                 for (ji = kf; ji <= i__2; ++ji) {
+   18271           0 :                     if (iwork[ji] <= nval[ji]) {
+   18272           0 :                         ab[ji + ab_dim1] = c__[ji];
+   18273           0 :                         nab[ji + nab_dim1] = iwork[ji];
+   18274             :                     }
+   18275           0 :                     if (iwork[ji] >= nval[ji]) {
+   18276           0 :                         ab[ji + (ab_dim1 << 1)] = c__[ji];
+   18277           0 :                         nab[ji + (nab_dim1 << 1)] = iwork[ji];
+   18278             :                     }
+   18279             :                 }
+   18280             :             }
+   18281             : 
+   18282             :         } else {
+   18283             : 
+   18284             :             klnew = kl;
+   18285             :             i__2 = kl;
+   18286           0 :             for (ji = kf; ji <= i__2; ++ji) {
+   18287             : 
+   18288           0 :                 tmp1 = c__[ji];
+   18289           0 :                 tmp2 = d__[1] - tmp1;
+   18290             :                 itmp1 = 0;
+   18291           0 :                 if (tmp2 <= *pivmin) {
+   18292             :                     itmp1 = 1;
+   18293           0 :                     d__1 = tmp2, d__2 = -(*pivmin);
+   18294           0 :                     tmp2 = (d__1<d__2) ? d__1 : d__2;
+   18295             :                 }
+   18296             : 
+   18297           0 :                 i__3 = *n;
+   18298           0 :                 for (j = 2; j <= i__3; ++j) {
+   18299           0 :                     tmp2 = d__[j] - e2[j - 1] / tmp2 - tmp1;
+   18300           0 :                     if (tmp2 <= *pivmin) {
+   18301           0 :                         ++itmp1;
+   18302           0 :                         d__1 = tmp2, d__2 = -(*pivmin);
+   18303           0 :                         tmp2 = (d__1<d__2) ? d__1 : d__2;
+   18304             :                     }
+   18305             :                 }
+   18306             : 
+   18307           0 :                 if (*ijob <= 2) {
+   18308             : 
+   18309           0 :                     i__5 = nab[ji + nab_dim1];
+   18310           0 :                     i__3 = nab[ji + (nab_dim1 << 1)];
+   18311             :                     i__4 = (i__5>itmp1) ? i__5 : itmp1;
+   18312             :                     itmp1 = (i__3<i__4) ? i__3 : i__4;
+   18313             : 
+   18314           0 :                     if (itmp1 == nab[ji + (nab_dim1 << 1)]) {
+   18315             : 
+   18316           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+   18317             : 
+   18318           0 :                     } else if (itmp1 == nab[ji + nab_dim1]) {
+   18319             : 
+   18320           0 :                         ab[ji + ab_dim1] = tmp1;
+   18321           0 :                     } else if (klnew < *mmax) {
+   18322             : 
+   18323           0 :                         ++klnew;
+   18324           0 :                         ab[klnew + (ab_dim1 << 1)] = ab[ji + (ab_dim1 << 1)];
+   18325           0 :                         nab[klnew + (nab_dim1 << 1)] = nab[ji + (nab_dim1 << 
+   18326           0 :                                 1)];
+   18327           0 :                         ab[klnew + ab_dim1] = tmp1;
+   18328           0 :                         nab[klnew + nab_dim1] = itmp1;
+   18329           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+   18330           0 :                         nab[ji + (nab_dim1 << 1)] = itmp1;
+   18331             :                     } else {
+   18332           0 :                         *info = *mmax + 1;
+   18333           0 :                         return;
+   18334             :                     }
+   18335             :                 } else {
+   18336             : 
+   18337           0 :                     if (itmp1 <= nval[ji]) {
+   18338           0 :                         ab[ji + ab_dim1] = tmp1;
+   18339           0 :                         nab[ji + nab_dim1] = itmp1;
+   18340             :                     }
+   18341           0 :                     if (itmp1 >= nval[ji]) {
+   18342           0 :                         ab[ji + (ab_dim1 << 1)] = tmp1;
+   18343           0 :                         nab[ji + (nab_dim1 << 1)] = itmp1;
+   18344             :                     }
+   18345             :                 }
+   18346             :             }
+   18347             :             kl = klnew;
+   18348             : 
+   18349             :         }
+   18350             : 
+   18351             :         kfnew = kf;
+   18352             :         i__2 = kl;
+   18353           0 :         for (ji = kf; ji <= i__2; ++ji) {
+   18354           0 :             tmp1 = std::abs(ab[ji + (ab_dim1 << 1)] - ab[ji + ab_dim1]);
+   18355             :             d__3 = std::abs(ab[ji + (ab_dim1 << 1)]);
+   18356             :             d__4 = std::abs(ab[ji + ab_dim1]);
+   18357           0 :             tmp2 = (d__3>d__4) ? d__3 : d__4;
+   18358           0 :             d__1 = (*abstol>*pivmin) ? *abstol : *pivmin;
+   18359           0 :             d__2 = *reltol * tmp2;
+   18360           0 :             if (tmp1 < ((d__1>d__2) ? d__1 : d__2) || nab[ji + nab_dim1] >= nab[ji + (
+   18361           0 :                     nab_dim1 << 1)]) {
+   18362             : 
+   18363           0 :                 if (ji > kfnew) {
+   18364             :                     tmp1 = ab[ji + ab_dim1];
+   18365             :                     tmp2 = ab[ji + (ab_dim1 << 1)];
+   18366           0 :                     itmp1 = nab[ji + nab_dim1];
+   18367           0 :                     itmp2 = nab[ji + (nab_dim1 << 1)];
+   18368           0 :                     ab[ji + ab_dim1] = ab[kfnew + ab_dim1];
+   18369           0 :                     ab[ji + (ab_dim1 << 1)] = ab[kfnew + (ab_dim1 << 1)];
+   18370           0 :                     nab[ji + nab_dim1] = nab[kfnew + nab_dim1];
+   18371           0 :                     nab[ji + (nab_dim1 << 1)] = nab[kfnew + (nab_dim1 << 1)];
+   18372           0 :                     ab[kfnew + ab_dim1] = tmp1;
+   18373           0 :                     ab[kfnew + (ab_dim1 << 1)] = tmp2;
+   18374           0 :                     nab[kfnew + nab_dim1] = itmp1;
+   18375           0 :                     nab[kfnew + (nab_dim1 << 1)] = itmp2;
+   18376           0 :                     if (*ijob == 3) {
+   18377           0 :                         itmp1 = nval[ji];
+   18378           0 :                         nval[ji] = nval[kfnew];
+   18379           0 :                         nval[kfnew] = itmp1;
+   18380             :                     }
+   18381             :                 }
+   18382           0 :                 ++kfnew;
+   18383             :             }
+   18384             :         }
+   18385             :         kf = kfnew;
+   18386             : 
+   18387             :         i__2 = kl;
+   18388           0 :         for (ji = kf; ji <= i__2; ++ji) {
+   18389           0 :             c__[ji] = (ab[ji + ab_dim1] + ab[ji + (ab_dim1 << 1)]) * .5;
+   18390             :         }
+   18391             : 
+   18392           0 :         if (kf > kl) {
+   18393             :             break;
+   18394             :         }
+   18395             :     }
+   18396             : 
+   18397           0 :     i__1 = kl + 1 - kf;
+   18398           0 :     if(i__1>0)
+   18399           0 :       *info = i__1;
+   18400             : 
+   18401           0 :     *mout = kl;
+   18402             : 
+   18403           0 :     return;
+   18404             : 
+   18405             : }
+   18406             : 
+   18407             : 
+   18408             : }
+   18409             : }
+   18410             : #include <cmath>
+   18411             : 
+   18412             : #include "lapack.h"
+   18413             : 
+   18414             : #include "real.h"
+   18415             : 
+   18416             : #include "blas/blas.h"
+   18417             : namespace PLMD{
+   18418             : namespace lapack{
+   18419             : using namespace blas;
+   18420             : void
+   18421           0 : PLUMED_BLAS_F77_FUNC(slaed6,SLAED6)(int *kniter, 
+   18422             :                         int *orgati, 
+   18423             :                         float *rho, 
+   18424             :                         float *d__,
+   18425             :                         float *z__, 
+   18426             :                         float *finit, 
+   18427             :                         float *tau, 
+   18428             :                         int *info)
+   18429             : {
+   18430             :     int i__1;
+   18431             :     float r__1, r__2, r__3, r__4;
+   18432             : 
+   18433             :     float a, b, c__, f;
+   18434             :     int i__;
+   18435             :     float fc, df, ddf, eta, eps, base;
+   18436             :     int iter;
+   18437             :     float temp, temp1, temp2, temp3, temp4;
+   18438             :     int scale;
+   18439             :     int niter;
+   18440             :     float small1, small2, sminv1, sminv2, dscale[3], sclfac;
+   18441             :     float zscale[3], erretm;
+   18442             :     float safemin;
+   18443             :     float sclinv = 0;
+   18444             :     
+   18445           0 :     --z__;
+   18446           0 :     --d__;
+   18447             : 
+   18448           0 :     *info = 0;
+   18449             : 
+   18450             :     niter = 1;
+   18451           0 :     *tau = 0.f;
+   18452           0 :     if (*kniter == 2) {
+   18453           0 :         if (*orgati) {
+   18454           0 :             temp = (d__[3] - d__[2]) / 2.f;
+   18455           0 :             c__ = *rho + z__[1] / (d__[1] - d__[2] - temp);
+   18456           0 :             a = c__ * (d__[2] + d__[3]) + z__[2] + z__[3];
+   18457           0 :             b = c__ * d__[2] * d__[3] + z__[2] * d__[3] + z__[3] * d__[2];
+   18458             :         } else {
+   18459           0 :             temp = (d__[1] - d__[2]) / 2.f;
+   18460           0 :             c__ = *rho + z__[3] / (d__[3] - d__[2] - temp);
+   18461           0 :             a = c__ * (d__[1] + d__[2]) + z__[1] + z__[2];
+   18462           0 :             b = c__ * d__[1] * d__[2] + z__[1] * d__[2] + z__[2] * d__[1];
+   18463             :         }
+   18464           0 :         r__1 = std::abs(a), r__2 = std::abs(b), r__1 = ((r__1>r__2)? r__1:r__2), r__2 = std::abs(c__);
+   18465           0 :         temp = (r__1>r__2) ? r__1 : r__2;
+   18466           0 :         a /= temp;
+   18467           0 :         b /= temp;
+   18468           0 :         c__ /= temp;
+   18469           0 :         if (c__ == 0.f) {
+   18470           0 :             *tau = b / a;
+   18471           0 :         } else if (a <= 0.f) {
+   18472           0 :             *tau = (a -  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1)))) / (
+   18473           0 :                     c__ * 2.f);
+   18474             :         } else {
+   18475           0 :             *tau = b * 2.f / (a +  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1))));
+   18476             :         }
+   18477             : 
+   18478           0 :         temp = *rho + z__[1] / (d__[1] - *tau) + z__[2] / (d__[2] - *tau) + 
+   18479           0 :                 z__[3] / (d__[3] - *tau);
+   18480           0 :         if (std::abs(*finit) <= std::abs(temp)) {
+   18481           0 :             *tau = 0.f;
+   18482             :         }
+   18483             :     }
+   18484             : 
+   18485             :     eps = PLUMED_GMX_FLOAT_EPS;
+   18486             :     base = 2;
+   18487             :     safemin = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   18488             :     i__1 = static_cast<int>(std::log(safemin) / std::log(base) / 3.f);
+   18489             :     small1 = std::pow(base, static_cast<float>(i__1));
+   18490             :     sminv1 = 1.f / small1;
+   18491             :     small2 = small1 * small1;
+   18492             :     sminv2 = sminv1 * sminv1;
+   18493             : 
+   18494           0 :     if (*orgati) {
+   18495           0 :         r__3 = (r__1 = d__[2] - *tau, std::abs(r__1)), r__4 = (r__2 = d__[3] - *
+   18496             :                 tau, std::abs(r__2));
+   18497           0 :         temp = (r__3<r__4) ? r__3 : r__4;
+   18498             :     } else {
+   18499           0 :         r__3 = (r__1 = d__[1] - *tau, std::abs(r__1)), r__4 = (r__2 = d__[2] - *
+   18500             :                 tau, std::abs(r__2));
+   18501           0 :         temp = (r__3<r__4) ? r__3 : r__4;
+   18502             :     }
+   18503             :     scale = 0;
+   18504           0 :     if (temp <= small1) {
+   18505             :         scale = 1;
+   18506           0 :         if (temp <= small2) {
+   18507             : 
+   18508             :             sclfac = sminv2;
+   18509             :             sclinv = small2;
+   18510             :         } else {
+   18511             : 
+   18512             :             sclfac = sminv1;
+   18513             :             sclinv = small1;
+   18514             : 
+   18515             :         }
+   18516             : 
+   18517           0 :         for (i__ = 1; i__ <= 3; ++i__) {
+   18518           0 :             dscale[i__ - 1] = d__[i__] * sclfac;
+   18519           0 :             zscale[i__ - 1] = z__[i__] * sclfac;
+   18520             :         }
+   18521           0 :         *tau *= sclfac;
+   18522             :     } else {
+   18523             : 
+   18524           0 :         for (i__ = 1; i__ <= 3; ++i__) {
+   18525           0 :             dscale[i__ - 1] = d__[i__];
+   18526           0 :             zscale[i__ - 1] = z__[i__];
+   18527             :         }
+   18528             :     }
+   18529             :     fc = 0.f;
+   18530             :     df = 0.f;
+   18531             :     ddf = 0.f;
+   18532           0 :     for (i__ = 1; i__ <= 3; ++i__) {
+   18533           0 :         temp = 1.f / (dscale[i__ - 1] - *tau);
+   18534           0 :         temp1 = zscale[i__ - 1] * temp;
+   18535           0 :         temp2 = temp1 * temp;
+   18536           0 :         temp3 = temp2 * temp;
+   18537           0 :         fc += temp1 / dscale[i__ - 1];
+   18538           0 :         df += temp2;
+   18539           0 :         ddf += temp3;
+   18540             :     }
+   18541           0 :     f = *finit + *tau * fc;
+   18542             : 
+   18543           0 :     if (std::abs(f) <= 0.f) {
+   18544           0 :         goto L60;
+   18545             :     }
+   18546             :     iter = niter + 1;
+   18547           0 :     for (niter = iter; niter <= 20; ++niter) {
+   18548           0 :         if (*orgati) {
+   18549           0 :             temp1 = dscale[1] - *tau;
+   18550           0 :             temp2 = dscale[2] - *tau;
+   18551             :         } else {
+   18552           0 :             temp1 = dscale[0] - *tau;
+   18553           0 :             temp2 = dscale[1] - *tau;
+   18554             :         }
+   18555           0 :         a = (temp1 + temp2) * f - temp1 * temp2 * df;
+   18556           0 :         b = temp1 * temp2 * f;
+   18557           0 :         c__ = f - (temp1 + temp2) * df + temp1 * temp2 * ddf;
+   18558           0 :         r__1 = std::abs(a), r__2 = std::abs(b), r__1 = ((r__1>r__2)? r__1:r__2), r__2 = std::abs(c__);
+   18559           0 :         temp = (r__1>r__2) ? r__1 : r__2;
+   18560           0 :         a /= temp;
+   18561           0 :         b /= temp;
+   18562           0 :         c__ /= temp;
+   18563           0 :         if (c__ == 0.f) {
+   18564           0 :             eta = b / a;
+   18565           0 :         } else if (a <= 0.f) {
+   18566           0 :             eta = (a -  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs(r__1)))) / ( c__ * 2.f);
+   18567             :         } else {
+   18568           0 :             eta = b * 2.f / (a +  std::sqrt((r__1 = a * a - b * 4.f * c__, std::abs( r__1))));
+   18569             :         }
+   18570           0 :         if (f * eta >= 0.f) {
+   18571           0 :             eta = -f / df;
+   18572             :         }
+   18573           0 :         temp = eta + *tau;
+   18574           0 :         if (*orgati) {
+   18575           0 :             if (eta > 0.f && temp >= dscale[2]) {
+   18576           0 :                 eta = (dscale[2] - *tau) / 2.f;
+   18577             :             }
+   18578             : 
+   18579           0 :             if (eta < 0.f && temp <= dscale[1]) {
+   18580           0 :                 eta = (dscale[1] - *tau) / 2.f;
+   18581             :             }
+   18582             :         } else {
+   18583           0 :             if (eta > 0.f && temp >= dscale[1]) {
+   18584           0 :                 eta = (dscale[1] - *tau) / 2.f;
+   18585             :             }
+   18586           0 :             if (eta < 0.f && temp <= dscale[0]) {
+   18587           0 :                 eta = (dscale[0] - *tau) / 2.f;
+   18588             :             }
+   18589             :         }
+   18590           0 :         *tau += eta;
+   18591             :         fc = 0.f;
+   18592             :         erretm = 0.f;
+   18593             :         df = 0.f;
+   18594             :         ddf = 0.f;
+   18595           0 :         for (i__ = 1; i__ <= 3; ++i__) {
+   18596           0 :             temp = 1.f / (dscale[i__ - 1] - *tau);
+   18597           0 :             temp1 = zscale[i__ - 1] * temp;
+   18598           0 :             temp2 = temp1 * temp;
+   18599           0 :             temp3 = temp2 * temp;
+   18600           0 :             temp4 = temp1 / dscale[i__ - 1];
+   18601           0 :             fc += temp4;
+   18602           0 :             erretm += std::abs(temp4);
+   18603           0 :             df += temp2;
+   18604           0 :             ddf += temp3;
+   18605             :         }
+   18606           0 :         f = *finit + *tau * fc;
+   18607           0 :         erretm = (std::abs(*finit) + std::abs(*tau) * erretm) * 8.f + std::abs(*tau) * df;
+   18608           0 :         if (std::abs(f) <= eps * erretm) {
+   18609           0 :             goto L60;
+   18610             :         }
+   18611             :     }
+   18612           0 :     *info = 1;
+   18613           0 : L60:
+   18614           0 :     if (scale) {
+   18615           0 :         *tau *= sclinv;
+   18616             :     }
+   18617           0 :     return;
+   18618             : } 
+   18619             : 
+   18620             : 
+   18621             : }
+   18622             : }
+   18623             : #include <cmath>
+   18624             : #include "real.h"
+   18625             : 
+   18626             : #include "lapack.h"
+   18627             : 
+   18628             : 
+   18629             : #include "blas/blas.h"
+   18630             : namespace PLMD{
+   18631             : namespace lapack{
+   18632             : using namespace blas;
+   18633             : void
+   18634           0 : PLUMED_BLAS_F77_FUNC(slaev2,SLAEV2)(float *   a, 
+   18635             :         float *   b, 
+   18636             :         float *   c__, 
+   18637             :         float *   rt1, 
+   18638             :         float *   rt2, 
+   18639             :         float *   cs1, 
+   18640             :         float *   sn1)
+   18641             : {
+   18642             :     float d__1;
+   18643             : 
+   18644             :     float ab, df, cs, ct, tb, sm, tn, rt, adf, acs;
+   18645             :     int sgn1, sgn2;
+   18646             :     float acmn, acmx;
+   18647             : 
+   18648           0 :     sm = *a + *c__;
+   18649           0 :     df = *a - *c__;
+   18650             :     adf = std::abs(df);
+   18651           0 :     tb = *b + *b;
+   18652             :     ab = std::abs(tb);
+   18653           0 :     if (std::abs(*a) > std::abs(*c__)) {
+   18654             :         acmx = *a;
+   18655             :         acmn = *c__;
+   18656             :     } else {
+   18657             :         acmx = *c__;
+   18658             :         acmn = *a;
+   18659             :     }
+   18660           0 :     if (adf > ab) {
+   18661           0 :         d__1 = ab / adf;
+   18662           0 :         rt = adf *  std::sqrt(d__1 * d__1 + 1.);
+   18663           0 :     } else if (adf < ab) {
+   18664           0 :         d__1 = adf / ab;
+   18665           0 :         rt = ab *  std::sqrt(d__1 * d__1 + 1.);
+   18666             :     } else {
+   18667             : 
+   18668           0 :         rt = ab *  std::sqrt(2.);
+   18669             :     }
+   18670           0 :     if (sm < 0.) {
+   18671           0 :         *rt1 = (sm - rt) * .5;
+   18672             :         sgn1 = -1;
+   18673             : 
+   18674           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18675           0 :     } else if (sm > 0.) {
+   18676           0 :         *rt1 = (sm + rt) * .5;
+   18677             :         sgn1 = 1;
+   18678           0 :         *rt2 = acmx / *rt1 * acmn - *b / *rt1 * *b;
+   18679             :     } else {
+   18680           0 :         *rt1 = rt * .5;
+   18681           0 :         *rt2 = rt * -.5;
+   18682             :         sgn1 = 1;
+   18683             :     }
+   18684           0 :     if (df >= 0.) {
+   18685           0 :         cs = df + rt;
+   18686             :         sgn2 = 1;
+   18687             :     } else {
+   18688           0 :         cs = df - rt;
+   18689             :         sgn2 = -1;
+   18690             :     }
+   18691             :     acs = std::abs(cs);
+   18692           0 :     if (acs > ab) {
+   18693           0 :         ct = -tb / cs;
+   18694           0 :         *sn1 = 1. /  std::sqrt(ct * ct + 1.);
+   18695           0 :         *cs1 = ct * *sn1;
+   18696             :     } else {
+   18697           0 :         if (std::abs(ab)<PLUMED_GMX_FLOAT_MIN) {
+   18698           0 :             *cs1 = 1.;
+   18699           0 :             *sn1 = 0.;
+   18700             :         } else {
+   18701           0 :             tn = -cs / tb;
+   18702           0 :             *cs1 = 1. /  std::sqrt(tn * tn + 1.);
+   18703           0 :             *sn1 = tn * *cs1;
+   18704             :         }
+   18705             :     }
+   18706           0 :     if (sgn1 == sgn2) {
+   18707           0 :         tn = *cs1;
+   18708           0 :         *cs1 = -(*sn1);
+   18709           0 :         *sn1 = tn;
+   18710             :     }
+   18711           0 :     return;
+   18712             : 
+   18713             : }
+   18714             : 
+   18715             : 
+   18716             : }
+   18717             : }
+   18718             : #include <cmath>
+   18719             : #include "real.h"
+   18720             : 
+   18721             : #include "lapack.h"
+   18722             : #include "lapack_limits.h"
+   18723             : 
+   18724             : 
+   18725             : 
+   18726             : #include "blas/blas.h"
+   18727             : namespace PLMD{
+   18728             : namespace lapack{
+   18729             : using namespace blas;
+   18730             : void
+   18731           0 : PLUMED_BLAS_F77_FUNC(slagtf,SLAGTF)(int *n, 
+   18732             :         float *a, 
+   18733             :         float *lambda, 
+   18734             :         float *b, 
+   18735             :         float *c__, 
+   18736             :         float *tol, 
+   18737             :         float *d__, 
+   18738             :         int *in, 
+   18739             :         int *info)
+   18740             : {
+   18741             :     int i__1;
+   18742             : 
+   18743             :     int k;
+   18744             :     float tl, eps, piv1, piv2, temp, mult, scale1, scale2;
+   18745             : 
+   18746           0 :     --in;
+   18747           0 :     --d__;
+   18748           0 :     --c__;
+   18749           0 :     --b;
+   18750           0 :     --a;
+   18751             : 
+   18752           0 :     *info = 0;
+   18753           0 :     if (*n < 0) {
+   18754           0 :         *info = -1;
+   18755           0 :         return;
+   18756             :     }
+   18757             : 
+   18758           0 :     if (*n == 0) 
+   18759             :         return;
+   18760             :     
+   18761           0 :     a[1] -= *lambda;
+   18762           0 :     in[*n] = 0;
+   18763           0 :     if (*n == 1) {
+   18764           0 :         if (std::abs(a[1])<PLUMED_GMX_FLOAT_MIN) {
+   18765           0 :             in[1] = 1;
+   18766             :         }
+   18767           0 :         return;
+   18768             :     }
+   18769             : 
+   18770             :     eps = PLUMED_GMX_FLOAT_EPS;
+   18771             : 
+   18772           0 :     tl = (*tol>eps) ? *tol : eps;
+   18773           0 :     scale1 = std::abs(a[1]) + std::abs(b[1]);
+   18774             :     i__1 = *n - 1;
+   18775           0 :     for (k = 1; k <= i__1; ++k) {
+   18776           0 :         a[k + 1] -= *lambda;
+   18777           0 :         scale2 = std::abs(c__[k]) + std::abs(a[k + 1]);
+   18778           0 :         if (k < *n - 1) {
+   18779           0 :             scale2 += std::abs(b[k + 1]);
+   18780             :         }
+   18781           0 :         if (std::abs(a[k])<PLUMED_GMX_FLOAT_MIN) {
+   18782             :             piv1 = 0.;
+   18783             :         } else {
+   18784           0 :             piv1 = std::abs(a[k]) / scale1;
+   18785             :         }
+   18786           0 :         if (std::abs(c__[k])<PLUMED_GMX_FLOAT_MIN) {
+   18787           0 :             in[k] = 0;
+   18788             :             piv2 = 0.;
+   18789             :             scale1 = scale2;
+   18790           0 :             if (k < *n - 1) {
+   18791           0 :                 d__[k] = 0.;
+   18792             :             }
+   18793             :         } else {
+   18794           0 :             piv2 = std::abs(c__[k]) / scale2;
+   18795           0 :             if (piv2 <= piv1) {
+   18796           0 :                 in[k] = 0;
+   18797             :                 scale1 = scale2;
+   18798           0 :                 c__[k] /= a[k];
+   18799           0 :                 a[k + 1] -= c__[k] * b[k];
+   18800           0 :                 if (k < *n - 1) {
+   18801           0 :                     d__[k] = 0.;
+   18802             :                 }
+   18803             :             } else {
+   18804           0 :                 in[k] = 1;
+   18805           0 :                 mult = a[k] / c__[k];
+   18806           0 :                 a[k] = c__[k];
+   18807           0 :                 temp = a[k + 1];
+   18808           0 :                 a[k + 1] = b[k] - mult * temp;
+   18809           0 :                 if (k < *n - 1) {
+   18810           0 :                     d__[k] = b[k + 1];
+   18811           0 :                     b[k + 1] = -mult * d__[k];
+   18812             :                 }
+   18813           0 :                 b[k] = temp;
+   18814           0 :                 c__[k] = mult;
+   18815             :             }
+   18816             :         }
+   18817           0 :         if (((piv1>piv2) ? piv1 : piv2) <= tl && in[*n] == 0) {
+   18818           0 :             in[*n] = k;
+   18819             :         }
+   18820             :     }
+   18821           0 :     if (std::abs(a[*n]) <= scale1 * tl && in[*n] == 0) {
+   18822           0 :         in[*n] = *n;
+   18823             :     }
+   18824             : 
+   18825             :     return;
+   18826             : 
+   18827             : }
+   18828             : 
+   18829             : 
+   18830             : }
+   18831             : }
+   18832             : #include <stdlib.h>
+   18833             : #include <cmath>
+   18834             : #include "real.h"
+   18835             : 
+   18836             : #include "lapack.h"
+   18837             : #include "lapack_limits.h"
+   18838             : 
+   18839             : 
+   18840             : #include "blas/blas.h"
+   18841             : namespace PLMD{
+   18842             : namespace lapack{
+   18843             : using namespace blas;
+   18844             : void
+   18845           0 : PLUMED_BLAS_F77_FUNC(slagts,SLAGTS)(int *job, 
+   18846             :         int *n, 
+   18847             :         float *a, 
+   18848             :         float *b, 
+   18849             :         float *c__, 
+   18850             :         float *d__, 
+   18851             :         int *in, 
+   18852             :         float *y, 
+   18853             :         float *tol, 
+   18854             :         int *info)
+   18855             : {
+   18856             :     int i__1;
+   18857             :     float d__1, d__2, d__4, d__5;
+   18858             : 
+   18859             :     int k;
+   18860             :     float ak, eps, temp, pert, absak, sfmin;
+   18861             :     float bignum,minval;
+   18862           0 :     --y;
+   18863           0 :     --in;
+   18864           0 :     --d__;
+   18865           0 :     --c__;
+   18866           0 :     --b;
+   18867           0 :     --a;
+   18868             : 
+   18869           0 :     *info = 0;
+   18870           0 :     if (abs(*job) > 2 || *job == 0) {
+   18871           0 :         *info = -1;
+   18872           0 :     } else if (*n < 0) {
+   18873           0 :         *info = -2;
+   18874             :     }
+   18875           0 :     if (*info != 0) {
+   18876             :         return;
+   18877             :     }
+   18878             : 
+   18879           0 :     if (*n == 0) {
+   18880             :         return;
+   18881             :     }
+   18882             :     eps = PLUMED_GMX_FLOAT_EPS;
+   18883             :     minval = PLUMED_GMX_FLOAT_MIN;
+   18884             :     sfmin = minval / eps;
+   18885             : 
+   18886             :     bignum = 1. / sfmin;
+   18887             : 
+   18888           0 :     if (*job < 0) {
+   18889           0 :         if (*tol <= 0.) {
+   18890           0 :             *tol = std::abs(a[1]);
+   18891           0 :             if (*n > 1) {
+   18892             :                 d__1 = *tol;
+   18893           0 :                 d__2 = std::abs(a[2]);
+   18894           0 :                 d__1 = (d__1>d__2) ? d__1 : d__2;
+   18895           0 :                 d__2 = std::abs(b[1]);
+   18896           0 :                 *tol = (d__1>d__2) ? d__1 : d__2;
+   18897             :             }
+   18898           0 :             i__1 = *n;
+   18899           0 :             for (k = 3; k <= i__1; ++k) {
+   18900           0 :               d__4 = *tol;
+   18901           0 :               d__5 = std::abs(a[k]);
+   18902           0 :               d__4 = (d__4>d__5) ? d__4 : d__5;
+   18903           0 :               d__5 = std::abs(b[k - 1]);
+   18904           0 :               d__4 = (d__4>d__5) ? d__4 : d__5;
+   18905           0 :               d__5 = std::abs(d__[k - 2]);
+   18906           0 :               *tol = (d__4>d__5) ? d__4 : d__5;
+   18907             :             }
+   18908           0 :             *tol *= eps;
+   18909           0 :             if (std::abs(*tol)<PLUMED_GMX_FLOAT_MIN) {
+   18910           0 :                 *tol = eps;
+   18911             :             }
+   18912             :         }
+   18913             :     }
+   18914             : 
+   18915           0 :     if (1 == abs(*job)) {
+   18916           0 :         i__1 = *n;
+   18917           0 :         for (k = 2; k <= i__1; ++k) {
+   18918           0 :             if (in[k - 1] == 0) {
+   18919           0 :                 y[k] -= c__[k - 1] * y[k - 1];
+   18920             :             } else {
+   18921           0 :                 temp = y[k - 1];
+   18922           0 :                 y[k - 1] = y[k];
+   18923           0 :                 y[k] = temp - c__[k - 1] * y[k];
+   18924             :             }
+   18925             :         }
+   18926           0 :         if (*job == 1) {
+   18927           0 :             for (k = *n; k >= 1; --k) {
+   18928           0 :                 if (k <= *n - 2) {
+   18929           0 :                     temp = y[k] - b[k] * y[k + 1] - d__[k] * y[k + 2];
+   18930           0 :                 } else if (k == *n - 1) {
+   18931           0 :                     temp = y[k] - b[k] * y[k + 1];
+   18932             :                 } else {
+   18933           0 :                     temp = y[k];
+   18934             :                 }
+   18935           0 :                 ak = a[k];
+   18936             :                 absak = std::abs(ak);
+   18937           0 :                 if (absak < 1.) {
+   18938           0 :                     if (absak < sfmin) {
+   18939           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   18940           0 :                             *info = k;
+   18941           0 :                             return;
+   18942             :                         } else {
+   18943           0 :                             temp *= bignum;
+   18944           0 :                             ak *= bignum;
+   18945             :                         }
+   18946           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   18947           0 :                         *info = k;
+   18948           0 :                         return;
+   18949             :                     }
+   18950             :                 }
+   18951           0 :                 y[k] = temp / ak;
+   18952             :             }
+   18953             :         } else {
+   18954           0 :             for (k = *n; k >= 1; --k) {
+   18955           0 :                 if (k + 2 <= *n) {
+   18956           0 :                     temp = y[k] - b[k] * y[k + 1] - d__[k] * y[k + 2];
+   18957           0 :                 } else if (k + 1 == *n) {
+   18958           0 :                     temp = y[k] - b[k] * y[k + 1];
+   18959             :                 } else {
+   18960           0 :                     temp = y[k];
+   18961             :                 }
+   18962           0 :                 ak = a[k];
+   18963             : 
+   18964           0 :                 pert = *tol;
+   18965           0 :                 if(ak<0)
+   18966           0 :                   pert *= -1.0;
+   18967           0 : L40:
+   18968             :                 absak = std::abs(ak);
+   18969           0 :                 if (absak < 1.) {
+   18970           0 :                     if (absak < sfmin) {
+   18971           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   18972           0 :                             ak += pert;
+   18973           0 :                             pert *= 2;
+   18974           0 :                             goto L40;
+   18975             :                         } else {
+   18976           0 :                             temp *= bignum;
+   18977           0 :                             ak *= bignum;
+   18978             :                         }
+   18979           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   18980           0 :                         ak += pert;
+   18981           0 :                         pert *= 2;
+   18982           0 :                         goto L40;
+   18983             :                     }
+   18984             :                 }
+   18985           0 :                 y[k] = temp / ak;
+   18986             :             }
+   18987             :         }
+   18988             :     } else {
+   18989             : 
+   18990           0 :         if (*job == 2) {
+   18991           0 :             i__1 = *n;
+   18992           0 :             for (k = 1; k <= i__1; ++k) {
+   18993           0 :                 if (k >= 3) {
+   18994           0 :                     temp = y[k] - b[k - 1] * y[k - 1] - d__[k - 2] * y[k - 2];
+   18995           0 :                 } else if (k == 2) {
+   18996           0 :                     temp = y[k] - b[k - 1] * y[k - 1];
+   18997             :                 } else {
+   18998           0 :                     temp = y[k];
+   18999             :                 }
+   19000           0 :                 ak = a[k];
+   19001             :                 absak = std::abs(ak);
+   19002           0 :                 if (absak < 1.) {
+   19003           0 :                     if (absak < sfmin) {
+   19004           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   19005           0 :                             *info = k;
+   19006           0 :                             return;
+   19007             :                         } else {
+   19008           0 :                             temp *= bignum;
+   19009           0 :                             ak *= bignum;
+   19010             :                         }
+   19011           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   19012           0 :                         *info = k;
+   19013           0 :                         return;
+   19014             :                     }
+   19015             :                 }
+   19016           0 :                 y[k] = temp / ak;
+   19017             :             }
+   19018             :         } else {
+   19019           0 :             i__1 = *n;
+   19020           0 :             for (k = 1; k <= i__1; ++k) {
+   19021           0 :                 if (k >= 3) {
+   19022           0 :                     temp = y[k] - b[k - 1] * y[k - 1] - d__[k - 2] * y[k - 2];
+   19023           0 :                 } else if (k == 2) {
+   19024           0 :                     temp = y[k] - b[k - 1] * y[k - 1];
+   19025             :                 } else {
+   19026           0 :                     temp = y[k];
+   19027             :                 }
+   19028           0 :                 ak = a[k];
+   19029             : 
+   19030           0 :                 pert = *tol;
+   19031           0 :                 if(ak<0)
+   19032           0 :                   pert *= -1.0;
+   19033             : 
+   19034           0 : L70:
+   19035             :                 absak = std::abs(ak);
+   19036           0 :                 if (absak < 1.) {
+   19037           0 :                     if (absak < sfmin) {
+   19038           0 :                         if (std::abs(absak)<PLUMED_GMX_FLOAT_MIN || std::abs(temp) * sfmin > absak) {
+   19039           0 :                             ak += pert;
+   19040           0 :                             pert *= 2;
+   19041           0 :                             goto L70;
+   19042             :                         } else {
+   19043           0 :                             temp *= bignum;
+   19044           0 :                             ak *= bignum;
+   19045             :                         }
+   19046           0 :                     } else if (std::abs(temp) > absak * bignum) {
+   19047           0 :                         ak += pert;
+   19048           0 :                         pert *= 2;
+   19049           0 :                         goto L70;
+   19050             :                     }
+   19051             :                 }
+   19052           0 :                 y[k] = temp / ak;
+   19053             :             }
+   19054             :         }
+   19055             : 
+   19056           0 :         for (k = *n; k >= 2; --k) {
+   19057           0 :             if (in[k - 1] == 0) {
+   19058           0 :                 y[k - 1] -= c__[k - 1] * y[k];
+   19059             :             } else {
+   19060           0 :                 temp = y[k - 1];
+   19061           0 :                 y[k - 1] = y[k];
+   19062           0 :                 y[k] = temp - c__[k - 1] * y[k];
+   19063             :             }
+   19064             :         }
+   19065             :     }
+   19066             : 
+   19067             :     return;
+   19068             : }
+   19069             : 
+   19070             : 
+   19071             : }
+   19072             : }
+   19073             : #include "lapack.h"
+   19074             : 
+   19075             : 
+   19076             : /* LAPACK */
+   19077             : 
+   19078             : 
+   19079             : #include "blas/blas.h"
+   19080             : namespace PLMD{
+   19081             : namespace lapack{
+   19082             : using namespace blas;
+   19083             : void
+   19084           0 : PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(int *n1,
+   19085             :                         int *n2,
+   19086             :                         float *a,
+   19087             :                         int *dtrd1,
+   19088             :                         int *dtrd2,
+   19089             :                         int *index)
+   19090             : {
+   19091           0 :   int n1sv = *n1;
+   19092           0 :   int n2sv = *n2;
+   19093             :   int i,ind1,ind2;
+   19094             : 
+   19095           0 :   if(*dtrd1>0)
+   19096             :     ind1 = 0;
+   19097             :   else
+   19098           0 :     ind1 = *n1-1;
+   19099             : 
+   19100           0 :   if(*dtrd2>0)
+   19101             :     ind2 = *n1;
+   19102             :   else
+   19103           0 :     ind2 = *n1+*n2-1;
+   19104             : 
+   19105             :   i = 0;
+   19106             :   
+   19107           0 :   while(n1sv>0 && n2sv>0) {
+   19108           0 :     if(a[ind1]<=a[ind2]) {
+   19109           0 :       index[i] = ind1 + 1;
+   19110           0 :       i++;
+   19111           0 :       ind1 += *dtrd1;
+   19112           0 :       n1sv--;
+   19113             :     } else {
+   19114           0 :       index[i] = ind2 + 1;
+   19115           0 :       i++;
+   19116           0 :       ind2 += *dtrd2;
+   19117           0 :       n2sv--;
+   19118             :     }
+   19119             :   }
+   19120             : 
+   19121           0 :   if(n1sv==0) {
+   19122           0 :     for(n1sv=1;n1sv<=n2sv;n1sv++) {
+   19123           0 :       index[i] = ind2 + 1;
+   19124           0 :       i++;
+   19125           0 :       ind2 += *dtrd2;
+   19126             :     } 
+   19127             :   } else {
+   19128           0 :     for(n2sv=1;n2sv<=n1sv;n2sv++) {
+   19129           0 :       index[i] = ind1 + 1;
+   19130           0 :       i++;
+   19131           0 :       ind1 += *dtrd1;
+   19132             :     } 
+   19133             :   }
+   19134           0 :   return;
+   19135             : }
+   19136             : }
+   19137             : }
+   19138             : #include <cctype>
+   19139             : #include <cmath>
+   19140             : 
+   19141             : #include "lapack.h"
+   19142             : 
+   19143             : 
+   19144             : #include "blas/blas.h"
+   19145             : namespace PLMD{
+   19146             : namespace lapack{
+   19147             : using namespace blas;
+   19148             : float
+   19149           0 : PLUMED_BLAS_F77_FUNC(slange,SLANGE)(const char *norm,
+   19150             :         int *m,
+   19151             :         int *n,
+   19152             :         float *a,
+   19153             :         int *lda,
+   19154             :         float *work)
+   19155             : {
+   19156           0 :   const char ch=std::toupper(*norm);
+   19157             :   float dtemp,sum,max,val,scale;
+   19158             :   int i,j;
+   19159             : 
+   19160           0 :   switch(ch) {
+   19161             :   case 'M':
+   19162             :     max = 0.0;
+   19163           0 :     for(j=0;j<*n;j++)
+   19164           0 :       for(i=0;i<*m;i++) {
+   19165           0 :         dtemp = std::abs(a[j*(*lda)+i]);
+   19166           0 :         if(dtemp>max)
+   19167             :           max = dtemp;
+   19168             :       }
+   19169             :     val = max;
+   19170             :     break;
+   19171             : 
+   19172             :   case 'O':
+   19173             :   case '1':
+   19174             :     max = 0.0;
+   19175           0 :     for(j=0;j<*n;j++) {
+   19176           0 :       sum = 0.0;
+   19177           0 :       for(i=0;i<*m;i++) 
+   19178           0 :         sum += std::abs(a[j*(*lda)+i]);
+   19179           0 :       if(sum>max)
+   19180             :         max = sum;
+   19181             :     }
+   19182             :     val = max;
+   19183             :     break;
+   19184             : 
+   19185           0 :   case 'I':
+   19186           0 :     for(i=0;i<*m;i++)
+   19187           0 :       work[i] = 0.0;
+   19188           0 :     for(j=0;j<*n;j++)
+   19189           0 :       for(i=0;i<*m;i++)
+   19190           0 :         work[i] += std::abs(a[j*(*lda)+i]);
+   19191             :     max = 0;
+   19192           0 :     for(i=0;i<*m;i++)
+   19193           0 :       if(work[i]>max)
+   19194             :         max=work[i];
+   19195             :     val = max;
+   19196             :     break;
+   19197             : 
+   19198           0 :   case 'F':
+   19199             :   case 'E':
+   19200           0 :     scale = 0.0;
+   19201           0 :     sum   = 1.0;
+   19202           0 :     i = 1;
+   19203           0 :     for(j=0;j<*n;j++) 
+   19204           0 :       PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(m,&(a[j*(*lda)+0]),&i,&scale,&sum);
+   19205           0 :     val = scale* std::sqrt(sum);
+   19206           0 :     break;
+   19207             : 
+   19208             :   default:
+   19209             :     val = 0.0;
+   19210             :     break;
+   19211             :   }
+   19212           0 :   return val;
+   19213             : }
+   19214             : }
+   19215             : }
+   19216             : #include <cctype>
+   19217             : #include <cmath>
+   19218             : 
+   19219             : #include "lapack.h"
+   19220             : 
+   19221             : 
+   19222             : #include "blas/blas.h"
+   19223             : namespace PLMD{
+   19224             : namespace lapack{
+   19225             : using namespace blas;
+   19226             : float
+   19227           0 : PLUMED_BLAS_F77_FUNC(slanst,SLANST)(const char *norm,
+   19228             :         int *n,
+   19229             :         float *d,
+   19230             :         float *e)
+   19231             : {
+   19232           0 :   const char ch=std::toupper(*norm);
+   19233             :   float dtemp,max,val,scale,sum;
+   19234             :   int i,j;
+   19235             : 
+   19236             : 
+   19237           0 :   if(*n<=0)
+   19238             :     return 0.0;
+   19239             :   
+   19240           0 :   switch(ch) {
+   19241           0 :   case 'M':
+   19242           0 :     max = std::abs(d[*n-1]);
+   19243           0 :       for(i=0;i<(*n-1);i++) {
+   19244           0 :         dtemp = std::abs(d[i]);
+   19245           0 :         if(dtemp>max)
+   19246             :           max = dtemp;
+   19247           0 :         dtemp = std::abs(e[i]);
+   19248           0 :         if(dtemp>max)
+   19249             :           max = dtemp;
+   19250             :       }
+   19251             :     val = max;
+   19252             :     break;
+   19253             :     
+   19254           0 :   case 'O':
+   19255             :   case '1':
+   19256             :   case 'I':
+   19257             : 
+   19258           0 :     if(*n==1)
+   19259           0 :       val = std::abs(d[0]);
+   19260             :     else {
+   19261           0 :       max = std::abs(d[0]) + std::abs(e[0]);
+   19262           0 :       dtemp = std::abs(e[*n-2]) + std::abs(d[*n-1]);
+   19263           0 :       if(dtemp>max)
+   19264             :         max = dtemp;
+   19265           0 :       for(i=1;i<(*n-1);i++) {
+   19266           0 :         dtemp = std::abs(d[i]) + std::abs(e[i]) + std::abs(e[i-1]);
+   19267           0 :         if(dtemp>max)
+   19268             :           max = dtemp;
+   19269             :       }
+   19270             :       val = max;
+   19271             :     }
+   19272             :     break;
+   19273             : 
+   19274           0 :   case 'F':
+   19275             :   case 'E':
+   19276           0 :     scale = 0.0;
+   19277           0 :     sum   = 1.0;
+   19278           0 :     i = *n-1;
+   19279           0 :     j = 1;
+   19280           0 :     if(*n>1) {
+   19281           0 :       PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(&i,e,&j,&scale,&sum);
+   19282           0 :       sum *= 2;
+   19283             :     }
+   19284           0 :     PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(n,d,&j,&scale,&sum);
+   19285           0 :     val = scale *  std::sqrt(sum);
+   19286           0 :     break;
+   19287             :     
+   19288             :   default:
+   19289             :     val = 0.0;
+   19290             :     break;
+   19291             :   }
+   19292             :   return val;
+   19293             : }
+   19294             : }
+   19295             : }
+   19296             : #include <cmath>
+   19297             : 
+   19298             : 
+   19299             : #include "lapack.h"
+   19300             : 
+   19301             : #include "blas/blas.h"
+   19302             : namespace PLMD{
+   19303             : namespace lapack{
+   19304             : using namespace blas;
+   19305             : float 
+   19306           0 : PLUMED_BLAS_F77_FUNC(slansy,SLANSY)(const char *norm, const char *uplo, int *n, float *a, int 
+   19307             :         *lda, float *work)
+   19308             : {
+   19309             :     /* System generated locals */
+   19310             :     int a_dim1, a_offset, i__1, i__2;
+   19311             :     float ret_val, d__1, d__2, d__3;
+   19312           0 :     int c__1 = 1;
+   19313             : 
+   19314             :     /* Local variables */
+   19315             :     int i__, j;
+   19316             :     float sum, absa, scale;
+   19317             :     float value =0.0;
+   19318             : 
+   19319           0 :     a_dim1 = *lda;
+   19320           0 :     a_offset = 1 + a_dim1;
+   19321           0 :     a -= a_offset;
+   19322           0 :     --work;
+   19323             : 
+   19324           0 :     if (*n == 0) {
+   19325             :         value = 0.;
+   19326           0 :     } else if (*norm=='M' || *norm=='m') {
+   19327             : 
+   19328             :         value = 0.;
+   19329           0 :         if (*uplo=='U' || *uplo=='u') {
+   19330           0 :             i__1 = *n;
+   19331           0 :             for (j = 1; j <= i__1; ++j) {
+   19332             :                 i__2 = j;
+   19333           0 :                 for (i__ = 1; i__ <= i__2; ++i__) {
+   19334             :                   d__2 = value;
+   19335           0 :                   d__3 = std::abs(a[i__ + j * a_dim1]);
+   19336           0 :                   value = (d__2>d__3) ? d__2 : d__3;
+   19337             :                 }
+   19338             :             }
+   19339             :         } else {
+   19340           0 :             i__1 = *n;
+   19341           0 :             for (j = 1; j <= i__1; ++j) {
+   19342             :                 i__2 = *n;
+   19343           0 :                 for (i__ = j; i__ <= i__2; ++i__) {
+   19344             :                   d__2 = value;
+   19345           0 :                   d__3 = std::abs(a[i__ + j * a_dim1]);
+   19346           0 :                     value =  (d__2>d__3) ? d__2 : d__3;
+   19347             :                 }
+   19348             :             }
+   19349             :         }
+   19350           0 :     } else if (*norm=='I' || *norm=='i' || *norm=='O' || *norm=='o' || *norm=='1') {
+   19351             : 
+   19352             :         value = 0.;
+   19353           0 :         if (*uplo=='U' || *uplo=='u') {
+   19354           0 :             i__1 = *n;
+   19355           0 :             for (j = 1; j <= i__1; ++j) {
+   19356           0 :                 sum = 0.;
+   19357           0 :                 i__2 = j - 1;
+   19358           0 :                 for (i__ = 1; i__ <= i__2; ++i__) {
+   19359           0 :                     absa = std::abs(a[i__ + j * a_dim1]);
+   19360           0 :                     sum += absa;
+   19361           0 :                     work[i__] += absa;
+   19362             :                 }
+   19363           0 :                 work[j] = sum + std::abs(a[j + j * a_dim1]);
+   19364             :             }
+   19365           0 :             i__1 = *n;
+   19366           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   19367           0 :                 d__1 = value, d__2 = work[i__];
+   19368           0 :                 value =  (d__1>d__2) ? d__1 : d__2;
+   19369             :             }
+   19370             :         } else {
+   19371             :             i__1 = *n;
+   19372           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   19373           0 :                 work[i__] = 0.;
+   19374             :             }
+   19375           0 :             i__1 = *n;
+   19376           0 :             for (j = 1; j <= i__1; ++j) {
+   19377           0 :                 sum = work[j] + std::abs(a[j + j * a_dim1]);
+   19378           0 :                 i__2 = *n;
+   19379           0 :                 for (i__ = j + 1; i__ <= i__2; ++i__) {
+   19380           0 :                     absa = std::abs(a[i__ + j * a_dim1]);
+   19381           0 :                     sum += absa;
+   19382           0 :                     work[i__] += absa;
+   19383             :                 }
+   19384           0 :                 if(sum>value)
+   19385             :                   value = sum;
+   19386             :             }
+   19387             :         }
+   19388             :     } else if (*norm=='F' || *norm=='f' || *norm=='E' || *norm=='e') {
+   19389             : 
+   19390           0 :         scale = 0.;
+   19391           0 :         sum = 1.;
+   19392           0 :         if (*uplo=='U' || *uplo=='u') {
+   19393           0 :             i__1 = *n;
+   19394           0 :             for (j = 2; j <= i__1; ++j) {
+   19395           0 :                 i__2 = j - 1;
+   19396           0 :                 PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(&i__2, &a[j * a_dim1 + 1], &c__1, &scale, &sum);
+   19397             :             }
+   19398             :         } else {
+   19399           0 :             i__1 = *n - 1;
+   19400           0 :             for (j = 1; j <= i__1; ++j) {
+   19401           0 :                 i__2 = *n - j;
+   19402           0 :                 PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(&i__2, &a[j + 1 + j * a_dim1], &c__1, &scale, &sum);
+   19403             :             }
+   19404             :         }
+   19405           0 :         sum *= 2;
+   19406           0 :         i__1 = *lda + 1;
+   19407           0 :         PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(n, &a[a_offset], &i__1, &scale, &sum);
+   19408           0 :         value = scale *  std::sqrt(sum);
+   19409             :     }
+   19410             : 
+   19411             :     ret_val = value;
+   19412           0 :     return ret_val;
+   19413             : }
+   19414             : 
+   19415             : 
+   19416             : }
+   19417             : }
+   19418             : #include <cmath>
+   19419             : #include "lapack.h"
+   19420             : 
+   19421             : #include "real.h"
+   19422             : 
+   19423             : #include "blas/blas.h"
+   19424             : namespace PLMD{
+   19425             : namespace lapack{
+   19426             : using namespace blas;
+   19427             : float
+   19428           1 : PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(float * x, float * y)
+   19429             : {
+   19430             :   float xabs,yabs;
+   19431             :   float w,z;
+   19432             : 
+   19433           1 :   xabs = std::abs(*x);
+   19434           1 :   yabs = std::abs(*y);
+   19435             :   
+   19436           1 :   if(xabs>yabs) {
+   19437             :     w = xabs;
+   19438             :     z = yabs;
+   19439             :   } else {
+   19440             :     w = yabs;
+   19441             :     z = xabs;
+   19442             :   }
+   19443             : 
+   19444           1 :   if( std::abs(z)<PLUMED_GMX_FLOAT_MIN) 
+   19445             :     return w;
+   19446             :   else {
+   19447           1 :     z = z/w;
+   19448           1 :     return w* std::sqrt(1.0+z*z);
+   19449             :   }
+   19450             : }
+   19451             :   
+   19452             : }
+   19453             : }
+   19454             : #include <cmath>
+   19455             : 
+   19456             : #include "real.h"
+   19457             : 
+   19458             : #include "lapack.h"
+   19459             : #include "lapack_limits.h"
+   19460             : #include "blas/blas.h"
+   19461             : namespace PLMD{
+   19462             : namespace lapack{
+   19463             : using namespace blas;
+   19464             : 
+   19465           0 : void PLUMED_BLAS_F77_FUNC(slar1vx,SLAR1VX)(int *n, 
+   19466             :               int *b1, 
+   19467             :               int *bn,
+   19468             :               float *sigma, 
+   19469             :               float *d__, 
+   19470             :               float *l, 
+   19471             :               float *ld, 
+   19472             :               float *lld, 
+   19473             :               float *eval, 
+   19474             :               float *gersch, 
+   19475             :               float *z__, 
+   19476             :               float *ztz, 
+   19477             :               float *mingma, 
+   19478             :               int *r__, 
+   19479             :               int *isuppz, 
+   19480             :               float *work)
+   19481             : {
+   19482             :     int i__1;
+   19483             : 
+   19484             :     int i__, j;
+   19485             :     float s;
+   19486             :     int r1, r2;
+   19487             :     int to;
+   19488             :     float eps, tmp;
+   19489             :     int indp, inds, from;
+   19490             :     float dplus;
+   19491             :     int sawnan;
+   19492             :     int indumn;
+   19493             :     float dminus;
+   19494             : 
+   19495           0 :     --work;
+   19496             :     --isuppz;
+   19497           0 :     --z__;
+   19498           0 :     --gersch;
+   19499           0 :     --lld;
+   19500           0 :     --ld;
+   19501           0 :     --l;
+   19502           0 :     --d__;
+   19503             : 
+   19504             :     /* Function Body */
+   19505             :     eps = PLUMED_GMX_FLOAT_EPS;
+   19506           0 :     if (*r__ == 0) {
+   19507             : 
+   19508           0 :         r1 = *b1;
+   19509           0 :         r2 = *bn;
+   19510             :         i__1 = *bn;
+   19511           0 :         for (i__ = *b1; i__ <= i__1; ++i__) {
+   19512           0 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+   19513             :                 r1 = i__;
+   19514           0 :                 goto L20;
+   19515             :             }
+   19516             :         }
+   19517           0 :         goto L40;
+   19518             : L20:
+   19519             :         i__1 = *b1;
+   19520           0 :         for (i__ = *bn; i__ >= i__1; --i__) {
+   19521           0 :             if (*eval >= gersch[(i__ << 1) - 1] && *eval <= gersch[i__ * 2]) {
+   19522             :                 r2 = i__;
+   19523           0 :                 goto L40;
+   19524             :             }
+   19525             :         }
+   19526             :     } else {
+   19527             :         r1 = *r__;
+   19528             :         r2 = *r__;
+   19529             :     }
+   19530             : 
+   19531           0 : L40:
+   19532           0 :     indumn = *n;
+   19533           0 :     inds = (*n << 1) + 1;
+   19534           0 :     indp = *n * 3 + 1;
+   19535             :     sawnan = 0;
+   19536             : 
+   19537           0 :     if (*b1 == 1) {
+   19538           0 :         work[inds] = 0.;
+   19539             :     } else {
+   19540           0 :         work[inds] = lld[*b1 - 1];
+   19541             :     }
+   19542           0 :     s = work[inds] - *sigma;
+   19543             :     i__1 = r2 - 1;
+   19544           0 :     for (i__ = *b1; i__ <= i__1; ++i__) {
+   19545           0 :         dplus = d__[i__] + s;
+   19546           0 :         work[i__] = ld[i__] / dplus;
+   19547           0 :         work[inds + i__] = s * work[i__] * l[i__];
+   19548           0 :         s = work[inds + i__] - *sigma;
+   19549             :     }
+   19550             : 
+   19551           0 :     if (std::isnan(s)) {
+   19552             : 
+   19553             :         sawnan = 1;
+   19554           0 :         j = *b1 + 1;
+   19555           0 : L60:
+   19556           0 :     if (!std::isnan(work[inds + j])) {
+   19557           0 :             ++j;
+   19558           0 :             goto L60;
+   19559             :         }
+   19560           0 :         work[inds + j] = lld[j];
+   19561           0 :         s = work[inds + j] - *sigma;
+   19562             :         i__1 = r2 - 1;
+   19563           0 :         for (i__ = j + 1; i__ <= i__1; ++i__) {
+   19564           0 :             dplus = d__[i__] + s;
+   19565           0 :             work[i__] = ld[i__] / dplus;
+   19566           0 :             if (std::abs(work[i__])<PLUMED_GMX_FLOAT_MIN) {
+   19567           0 :                 work[inds + i__] = lld[i__];
+   19568             :             } else {
+   19569           0 :                 work[inds + i__] = s * work[i__] * l[i__];
+   19570             :             }
+   19571           0 :             s = work[inds + i__] - *sigma;
+   19572             :         }
+   19573             :     }
+   19574             : 
+   19575           0 :     work[indp + *bn - 1] = d__[*bn] - *sigma;
+   19576             :     i__1 = r1;
+   19577           0 :     for (i__ = *bn - 1; i__ >= i__1; --i__) {
+   19578           0 :         dminus = lld[i__] + work[indp + i__];
+   19579           0 :         tmp = d__[i__] / dminus;
+   19580           0 :         work[indumn + i__] = l[i__] * tmp;
+   19581           0 :         work[indp + i__ - 1] = work[indp + i__] * tmp - *sigma;
+   19582             :     }
+   19583           0 :     tmp = work[indp + r1 - 1];
+   19584           0 :     if (std::isnan(tmp)) {
+   19585             : 
+   19586             :         sawnan = 1;
+   19587           0 :         j = *bn - 3;
+   19588           0 : L90:
+   19589           0 :     if (!std::isnan(work[indp + j])) {
+   19590           0 :             --j;
+   19591           0 :             goto L90;
+   19592             :         }
+   19593           0 :         work[indp + j] = d__[j + 1] - *sigma;
+   19594             :         i__1 = r1;
+   19595           0 :         for (i__ = j; i__ >= i__1; --i__) {
+   19596           0 :             dminus = lld[i__] + work[indp + i__];
+   19597           0 :             tmp = d__[i__] / dminus;
+   19598           0 :             work[indumn + i__] = l[i__] * tmp;
+   19599           0 :             if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   19600           0 :                 work[indp + i__ - 1] = d__[i__] - *sigma;
+   19601             :             } else {
+   19602           0 :                 work[indp + i__ - 1] = work[indp + i__] * tmp - *sigma;
+   19603             :             }
+   19604             :         }
+   19605             :     }
+   19606             : 
+   19607           0 :     *mingma = work[inds + r1 - 1] + work[indp + r1 - 1];
+   19608           0 :     if (std::abs(*mingma)<PLUMED_GMX_FLOAT_MIN) {
+   19609           0 :         *mingma = eps * work[inds + r1 - 1];
+   19610             :     }
+   19611           0 :     *r__ = r1;
+   19612             :     i__1 = r2 - 1;
+   19613           0 :     for (i__ = r1; i__ <= i__1; ++i__) {
+   19614           0 :         tmp = work[inds + i__] + work[indp + i__];
+   19615           0 :         if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   19616           0 :             tmp = eps * work[inds + i__];
+   19617             :         }
+   19618           0 :         if (std::abs(tmp) < std::abs(*mingma)) {
+   19619           0 :             *mingma = tmp;
+   19620           0 :             *r__ = i__ + 1;
+   19621             :         }
+   19622             :     }
+   19623             : 
+   19624           0 :     isuppz[1] = *b1;
+   19625           0 :     isuppz[2] = *bn;
+   19626           0 :     z__[*r__] = 1.;
+   19627           0 :     *ztz = 1.;
+   19628           0 :     if (! sawnan) {
+   19629           0 :         from = *r__ - 1;
+   19630           0 :         i__1 = *r__ - 32;
+   19631           0 :         to = (i__1>(*b1)) ? i__1 : (*b1);
+   19632             : L120:
+   19633           0 :         if (from >= *b1) {
+   19634             :             i__1 = to;
+   19635           0 :             for (i__ = from; i__ >= i__1; --i__) {
+   19636           0 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+   19637           0 :                 *ztz += z__[i__] * z__[i__];
+   19638             :             }
+   19639           0 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to + 1]) <= eps) {
+   19640           0 :                 isuppz[1] = to + 2;
+   19641             :             } else {
+   19642           0 :                 from = to - 1;
+   19643           0 :                 i__1 = to - 32;
+   19644           0 :                 to = (i__1>*b1) ? i__1 : *b1;
+   19645           0 :                 goto L120;
+   19646             :             }
+   19647             :         }
+   19648           0 :         from = *r__ + 1;
+   19649           0 :         i__1 = *r__ + 32;
+   19650           0 :         to = (i__1<*bn) ? i__1 : *bn;
+   19651             : L140:
+   19652           0 :         if (from <= *bn) {
+   19653             :             i__1 = to;
+   19654           0 :             for (i__ = from; i__ <= i__1; ++i__) {
+   19655           0 :                 z__[i__] = -(work[indumn + i__ - 1] * z__[i__ - 1]);
+   19656           0 :                 *ztz += z__[i__] * z__[i__];
+   19657             :             }
+   19658           0 :             if (std::abs(z__[to]) <= eps && std::abs(z__[to - 1]) <= eps) {
+   19659           0 :                 isuppz[2] = to - 2;
+   19660             :             } else {
+   19661           0 :                 from = to + 1;
+   19662           0 :                 i__1 = to + 32;
+   19663           0 :                 to = (i__1<*bn) ? i__1 : *bn;
+   19664           0 :                 goto L140;
+   19665             :             }
+   19666             :         }
+   19667             :     } else {
+   19668           0 :         i__1 = *b1;
+   19669           0 :         for (i__ = *r__ - 1; i__ >= i__1; --i__) {
+   19670           0 :             if (std::abs(z__[i__ + 1])<PLUMED_GMX_FLOAT_MIN) {
+   19671           0 :                 z__[i__] = -(ld[i__ + 1] / ld[i__]) * z__[i__ + 2];
+   19672             :             } else {
+   19673           0 :                 z__[i__] = -(work[i__] * z__[i__ + 1]);
+   19674             :             }
+   19675           0 :             if (std::abs(z__[i__]) <= eps && std::abs(z__[i__ + 1]) <= eps) {
+   19676           0 :                 isuppz[1] = i__ + 2;
+   19677           0 :                 goto L170;
+   19678             :             }
+   19679           0 :             *ztz += z__[i__] * z__[i__];
+   19680             :         }
+   19681           0 : L170:
+   19682           0 :         i__1 = *bn - 1;
+   19683           0 :         for (i__ = *r__; i__ <= i__1; ++i__) {
+   19684           0 :             if (std::abs(z__[i__])<PLUMED_GMX_FLOAT_MIN) {
+   19685           0 :                 z__[i__ + 1] = -(ld[i__ - 1] / ld[i__]) * z__[i__ - 1];
+   19686             :             } else {
+   19687           0 :                 z__[i__ + 1] = -(work[indumn + i__] * z__[i__]);
+   19688             :             }
+   19689           0 :             if (std::abs(z__[i__]) <= eps && std::abs(z__[i__ + 1]) <= eps) {
+   19690           0 :                 isuppz[2] = i__ - 1;
+   19691           0 :                 break;
+   19692             :             }
+   19693           0 :             *ztz += z__[i__ + 1] * z__[i__ + 1];
+   19694             :         }
+   19695             :     }
+   19696             : 
+   19697           0 :     return;
+   19698             : 
+   19699             : }
+   19700             : 
+   19701             : 
+   19702             : }
+   19703             : }
+   19704             : #include <cctype>
+   19705             : #include <cmath>
+   19706             : 
+   19707             : #include "blas/blas.h"
+   19708             : #include "lapack.h"
+   19709             : 
+   19710             : #include "real.h"
+   19711             : 
+   19712             : #include "blas/blas.h"
+   19713             : namespace PLMD{
+   19714             : namespace lapack{
+   19715             : using namespace blas;
+   19716             : void
+   19717           0 : PLUMED_BLAS_F77_FUNC(slarf,SLARF)(const char *side,
+   19718             :        int *m,
+   19719             :        int *n,
+   19720             :        float *v,
+   19721             :        int *incv,
+   19722             :        float *tau,
+   19723             :        float *c,
+   19724             :        int *ldc,
+   19725             :        float *work)
+   19726             : {
+   19727           0 :   const char ch=std::toupper(*side);
+   19728           0 :   float one = 1.0;
+   19729           0 :   float zero = 0.0;
+   19730           0 :   float minustau = -(*tau);
+   19731           0 :   int i1 = 1;
+   19732             : 
+   19733             : 
+   19734           0 :   if(ch=='L') {
+   19735           0 :     if(std::abs(*tau)>PLUMED_GMX_FLOAT_MIN) {
+   19736           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+   19737           0 :       PLUMED_BLAS_F77_FUNC(sger,SGER)(m,n,&minustau,v,incv,work,&i1,c,ldc);
+   19738             :     }
+   19739             :   } else {
+   19740           0 :     if(std::abs(*tau)>PLUMED_GMX_FLOAT_MIN) {
+   19741           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",m,n,&one,c,ldc,v,incv,&zero,work,&i1);
+   19742           0 :       PLUMED_BLAS_F77_FUNC(sger,SGER)(m,n,&minustau,work,&i1,v,incv,c,ldc);
+   19743             :     }
+   19744             :   }
+   19745           0 :   return;
+   19746             : }
+   19747             : }
+   19748             : }
+   19749             : #include "blas/blas.h"
+   19750             : #include "lapack.h"
+   19751             : 
+   19752             : 
+   19753             : #include "blas/blas.h"
+   19754             : namespace PLMD{
+   19755             : namespace lapack{
+   19756             : using namespace blas;
+   19757             : void 
+   19758           0 : PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(const char *side, 
+   19759             :         const char *trans, 
+   19760             :         const char *direct, 
+   19761             :         const char *storev, 
+   19762             :         int *m, 
+   19763             :         int *n, 
+   19764             :         int *k, 
+   19765             :         float *v, 
+   19766             :         int *ldv, 
+   19767             :         float *t, 
+   19768             :         int *ldt, 
+   19769             :         float *c__,
+   19770             :         int *ldc, 
+   19771             :         float *work, 
+   19772             :         int *ldwork)
+   19773             : {
+   19774             :     int c_dim1, c_offset, t_dim1, t_offset, v_dim1, v_offset, work_dim1, 
+   19775             :             work_offset, i__1, i__2;
+   19776             : 
+   19777             :     int i__, j;
+   19778             :     char transt[1];
+   19779           0 :     int c__1 = 1;
+   19780           0 :     float one = 1.0;
+   19781           0 :     float minusone = -1.0;
+   19782             : 
+   19783           0 :     v_dim1 = *ldv;
+   19784           0 :     v_offset = 1 + v_dim1;
+   19785           0 :     v -= v_offset;
+   19786             :     t_dim1 = *ldt;
+   19787             :     t_offset = 1 + t_dim1;
+   19788             :     t -= t_offset;
+   19789           0 :     c_dim1 = *ldc;
+   19790           0 :     c_offset = 1 + c_dim1;
+   19791           0 :     c__ -= c_offset;
+   19792           0 :     work_dim1 = *ldwork;
+   19793           0 :     work_offset = 1 + work_dim1;
+   19794           0 :     work -= work_offset;
+   19795             : 
+   19796           0 :     if (*m <= 0 || *n <= 0) {
+   19797             :         return;
+   19798             :     }
+   19799           0 :     if (*trans=='N' || *trans=='n') {
+   19800           0 :       *(unsigned char *)transt = 'T';
+   19801             :     } else {
+   19802           0 :         *(unsigned char *)transt = 'N';
+   19803             :     }
+   19804             :     
+   19805           0 :     if (*storev=='C' || *storev=='c') {
+   19806             : 
+   19807           0 :         if (*direct=='F' || *direct=='f') {
+   19808           0 :           if (*side=='l' || *side=='L') {
+   19809             : 
+   19810           0 :                 i__1 = *k;
+   19811           0 :                 for (j = 1; j <= i__1; ++j) {
+   19812           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[j + c_dim1], ldc, &work[j * work_dim1 + 1],
+   19813             :                              &c__1);
+   19814             :                 }
+   19815             : 
+   19816           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", n, k, &one,
+   19817             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   19818           0 :                 if (*m > *k) {
+   19819             : 
+   19820           0 :                     i__1 = *m - *k;
+   19821           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "No transpose", n, k, &i__1, &one, &
+   19822           0 :                             c__[*k + 1 + c_dim1], ldc, &v[*k + 1 + v_dim1], 
+   19823             :                             ldv, &one, &work[work_offset], ldwork);
+   19824             :                 }
+   19825             : 
+   19826           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", transt, "Non-unit", n, k, &one, &t[
+   19827             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19828             : 
+   19829           0 :                 if (*m > *k) {
+   19830           0 :                     i__1 = *m - *k;
+   19831           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", &i__1, n, k, &minusone, &
+   19832           0 :                             v[*k + 1 + v_dim1], ldv, &work[work_offset], 
+   19833           0 :                             ldwork, &one, &c__[*k + 1 + c_dim1], ldc);
+   19834             :                 }
+   19835             : 
+   19836           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", n, k, &one, &
+   19837             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   19838             : 
+   19839           0 :                 i__1 = *k;
+   19840           0 :                 for (j = 1; j <= i__1; ++j) {
+   19841           0 :                     i__2 = *n;
+   19842           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19843           0 :                         c__[j + i__ * c_dim1] -= work[i__ + j * work_dim1];
+   19844             :                     }
+   19845             :                 }
+   19846             : 
+   19847           0 :             } else if (*side=='r' || *side=='R') {
+   19848             : 
+   19849           0 :                 i__1 = *k;
+   19850           0 :                 for (j = 1; j <= i__1; ++j) {
+   19851           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[j * c_dim1 + 1], &c__1, &work[j * 
+   19852           0 :                             work_dim1 + 1], &c__1);
+   19853             :                 }
+   19854             : 
+   19855           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", m, k, &one,
+   19856             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   19857           0 :                 if (*n > *k) {
+   19858             : 
+   19859           0 :                     i__1 = *n - *k;
+   19860           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, k, &i__1, &
+   19861           0 :                             one, &c__[(*k + 1) * c_dim1 + 1], ldc, &v[*k + 
+   19862           0 :                             1 + v_dim1], ldv, &one, &work[work_offset], 
+   19863             :                             ldwork);
+   19864             :                 }
+   19865             : 
+   19866           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", trans, "Non-unit", m, k, &one, &t[
+   19867             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19868             : 
+   19869           0 :                 if (*n > *k) {
+   19870           0 :                     i__1 = *n - *k;
+   19871           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, &i__1, k, &minusone, &
+   19872           0 :                             work[work_offset], ldwork, &v[*k + 1 + v_dim1], 
+   19873           0 :                             ldv, &one, &c__[(*k + 1) * c_dim1 + 1], ldc);
+   19874             :                 }
+   19875             : 
+   19876           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", m, k, &one, &
+   19877             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   19878             : 
+   19879           0 :                 i__1 = *k;
+   19880           0 :                 for (j = 1; j <= i__1; ++j) {
+   19881           0 :                     i__2 = *m;
+   19882           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19883           0 :                         c__[i__ + j * c_dim1] -= work[i__ + j * work_dim1];
+   19884             :                     }
+   19885             :                 }
+   19886             :             }
+   19887             : 
+   19888             :         } else {
+   19889             : 
+   19890           0 :           if (*side=='l' || *side=='L') {
+   19891           0 :                 i__1 = *k;
+   19892           0 :                 for (j = 1; j <= i__1; ++j) {
+   19893           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[*m - *k + j + c_dim1], ldc, &work[j * 
+   19894           0 :                             work_dim1 + 1], &c__1);
+   19895             :                 }
+   19896             : 
+   19897           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", n, k, &one,
+   19898           0 :                          &v[*m - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19899             :                         ldwork);
+   19900           0 :                 if (*m > *k) {
+   19901           0 :                     i__1 = *m - *k;
+   19902           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "No transpose", n, k, &i__1, &one, &
+   19903             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+   19904             :                             work[work_offset], ldwork);
+   19905             :                 }
+   19906             : 
+   19907           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", transt, "Non-unit", n, k, &one, &t[
+   19908             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19909             : 
+   19910           0 :                 if (*m > *k) {
+   19911             : 
+   19912           0 :                     i__1 = *m - *k;
+   19913           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", &i__1, n, k, &minusone, &
+   19914             :                             v[v_offset], ldv, &work[work_offset], ldwork, &
+   19915             :                             one, &c__[c_offset], ldc)
+   19916             :                             ;
+   19917             :                 }
+   19918             : 
+   19919           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", n, k, &one, &
+   19920           0 :                         v[*m - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19921             :                         ldwork);
+   19922             : 
+   19923           0 :                 i__1 = *k;
+   19924           0 :                 for (j = 1; j <= i__1; ++j) {
+   19925           0 :                     i__2 = *n;
+   19926           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19927           0 :                         c__[*m - *k + j + i__ * c_dim1] -= work[i__ + j * 
+   19928           0 :                                 work_dim1];
+   19929             :                     }
+   19930             :                 }
+   19931             : 
+   19932           0 :             } else if (*side=='r' || *side=='R') {
+   19933           0 :                 i__1 = *k;
+   19934           0 :                 for (j = 1; j <= i__1; ++j) {
+   19935           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[(*n - *k + j) * c_dim1 + 1], &c__1, &work[
+   19936           0 :                             j * work_dim1 + 1], &c__1);
+   19937             :                 }
+   19938             : 
+   19939           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", m, k, &one,
+   19940           0 :                          &v[*n - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19941             :                         ldwork);
+   19942           0 :                 if (*n > *k) {
+   19943           0 :                     i__1 = *n - *k;
+   19944           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, k, &i__1, &
+   19945             :                             one, &c__[c_offset], ldc, &v[v_offset], ldv, &
+   19946             :                             one, &work[work_offset], ldwork);
+   19947             :                 }
+   19948           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", trans, "Non-unit", m, k, &one, &t[
+   19949             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19950           0 :                 if (*n > *k) {
+   19951           0 :                     i__1 = *n - *k;
+   19952           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, &i__1, k, &minusone, &
+   19953             :                             work[work_offset], ldwork, &v[v_offset], ldv, &
+   19954             :                             one, &c__[c_offset], ldc)
+   19955             :                             ;
+   19956             :                 }
+   19957           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", m, k, &one, &
+   19958           0 :                         v[*n - *k + 1 + v_dim1], ldv, &work[work_offset], 
+   19959             :                         ldwork);
+   19960           0 :                 i__1 = *k;
+   19961           0 :                 for (j = 1; j <= i__1; ++j) {
+   19962           0 :                     i__2 = *m;
+   19963           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   19964           0 :                         c__[i__ + (*n - *k + j) * c_dim1] -= work[i__ + j * 
+   19965           0 :                                 work_dim1];
+   19966             :                     }
+   19967             :                 }
+   19968             :             }
+   19969             :         }
+   19970             : 
+   19971           0 :     } else  if (*storev=='r' || *storev=='R') {
+   19972           0 :       if (*direct=='F' || *direct=='f') {
+   19973           0 :           if (*side=='l' || *side=='L') {
+   19974           0 :                 i__1 = *k;
+   19975           0 :                 for (j = 1; j <= i__1; ++j) {
+   19976           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[j + c_dim1], ldc, &work[j * work_dim1 + 1],
+   19977             :                              &c__1);
+   19978             :                 }
+   19979           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", n, k, &one, &
+   19980             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   19981           0 :                 if (*m > *k) {
+   19982           0 :                     i__1 = *m - *k;
+   19983           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", n, k, &i__1, &one, &
+   19984           0 :                             c__[*k + 1 + c_dim1], ldc, &v[(*k + 1) * v_dim1 + 
+   19985           0 :                             1], ldv, &one, &work[work_offset], ldwork);
+   19986             :                 }
+   19987             : 
+   19988           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", transt, "Non-unit", n, k, &one, &t[
+   19989             :                         t_offset], ldt, &work[work_offset], ldwork);
+   19990           0 :                 if (*m > *k) {
+   19991             : 
+   19992           0 :                     i__1 = *m - *k;
+   19993           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", &i__1, n, k, &minusone, &v[(
+   19994           0 :                             *k + 1) * v_dim1 + 1], ldv, &work[work_offset], 
+   19995           0 :                             ldwork, &one, &c__[*k + 1 + c_dim1], ldc);
+   19996             :                 }
+   19997             : 
+   19998           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", n, k, &one,
+   19999             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   20000             : 
+   20001           0 :                 i__1 = *k;
+   20002           0 :                 for (j = 1; j <= i__1; ++j) {
+   20003           0 :                     i__2 = *n;
+   20004           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20005           0 :                         c__[j + i__ * c_dim1] -= work[i__ + j * work_dim1];
+   20006             :                     }
+   20007             :                 }
+   20008             : 
+   20009           0 :             } else if (*side=='r' || *side=='R') {
+   20010             : 
+   20011           0 :                 i__1 = *k;
+   20012           0 :                 for (j = 1; j <= i__1; ++j) {
+   20013           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[j * c_dim1 + 1], &c__1, &work[j * 
+   20014           0 :                             work_dim1 + 1], &c__1);
+   20015             :                 }
+   20016             : 
+   20017           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "Transpose", "Unit", m, k, &one, &
+   20018             :                         v[v_offset], ldv, &work[work_offset], ldwork);
+   20019           0 :                 if (*n > *k) {
+   20020             : 
+   20021           0 :                     i__1 = *n - *k;
+   20022           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, k, &i__1, &one, &
+   20023           0 :                             c__[(*k + 1) * c_dim1 + 1], ldc, &v[(*k + 1) * 
+   20024           0 :                             v_dim1 + 1], ldv, &one, &work[work_offset], 
+   20025             :                             ldwork);
+   20026             :                 }
+   20027             : 
+   20028           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", trans, "Non-unit", m, k, &one, &t[
+   20029             :                         t_offset], ldt, &work[work_offset], ldwork);
+   20030             : 
+   20031           0 :                 if (*n > *k) {
+   20032             : 
+   20033           0 :                     i__1 = *n - *k;
+   20034           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, &i__1, k, &
+   20035           0 :                             minusone, &work[work_offset], ldwork, &v[(*k + 1) * 
+   20036           0 :                             v_dim1 + 1], ldv, &one, &c__[(*k + 1) * c_dim1 
+   20037           0 :                             + 1], ldc);
+   20038             :                 }
+   20039           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Upper", "No transpose", "Unit", m, k, &one,
+   20040             :                          &v[v_offset], ldv, &work[work_offset], ldwork);
+   20041           0 :                 i__1 = *k;
+   20042           0 :                 for (j = 1; j <= i__1; ++j) {
+   20043           0 :                     i__2 = *m;
+   20044           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20045           0 :                         c__[i__ + j * c_dim1] -= work[i__ + j * work_dim1];
+   20046             :                     }
+   20047             :                 }
+   20048             : 
+   20049             :             }
+   20050             : 
+   20051             :         } else {
+   20052             : 
+   20053           0 :             if (*side=='l' || *side=='L') {
+   20054             : 
+   20055           0 :                 i__1 = *k;
+   20056           0 :                 for (j = 1; j <= i__1; ++j) {
+   20057           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &c__[*m - *k + j + c_dim1], ldc, &work[j * 
+   20058           0 :                             work_dim1 + 1], &c__1);
+   20059             :                 }
+   20060             : 
+   20061           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", n, k, &one, &
+   20062           0 :                         v[(*m - *k + 1) * v_dim1 + 1], ldv, &work[work_offset]
+   20063             :                         , ldwork);
+   20064           0 :                 if (*m > *k) {
+   20065             : 
+   20066           0 :                     i__1 = *m - *k;
+   20067           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", n, k, &i__1, &one, &
+   20068             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+   20069             :                             work[work_offset], ldwork);
+   20070             :                 }
+   20071             : 
+   20072           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", transt, "Non-unit", n, k, &one, &t[
+   20073             :                         t_offset], ldt, &work[work_offset], ldwork);
+   20074             : 
+   20075           0 :                 if (*m > *k) {
+   20076             : 
+   20077           0 :                     i__1 = *m - *k;
+   20078           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("Transpose", "Transpose", &i__1, n, k, &minusone, &v[
+   20079             :                             v_offset], ldv, &work[work_offset], ldwork, &
+   20080             :                             one, &c__[c_offset], ldc);
+   20081             :                 }
+   20082             : 
+   20083           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", n, k, &one,
+   20084           0 :                          &v[(*m - *k + 1) * v_dim1 + 1], ldv, &work[
+   20085             :                         work_offset], ldwork);
+   20086             : 
+   20087           0 :                 i__1 = *k;
+   20088           0 :                 for (j = 1; j <= i__1; ++j) {
+   20089           0 :                     i__2 = *n;
+   20090           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20091           0 :                         c__[*m - *k + j + i__ * c_dim1] -= work[i__ + j * 
+   20092           0 :                                 work_dim1];
+   20093             :                     }
+   20094             :                 }
+   20095             : 
+   20096           0 :             } else if (*side=='r' || *side=='R') {
+   20097             : 
+   20098           0 :                 i__1 = *k;
+   20099           0 :                 for (j = 1; j <= i__1; ++j) {
+   20100           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(m, &c__[(*n - *k + j) * c_dim1 + 1], &c__1, &work[
+   20101           0 :                             j * work_dim1 + 1], &c__1);
+   20102             :                 }
+   20103             : 
+   20104           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "Transpose", "Unit", m, k, &one, &
+   20105           0 :                         v[(*n - *k + 1) * v_dim1 + 1], ldv, &work[work_offset]
+   20106             :                         , ldwork);
+   20107           0 :                 if (*n > *k) {
+   20108             : 
+   20109           0 :                     i__1 = *n - *k;
+   20110           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "Transpose", m, k, &i__1, &one, &
+   20111             :                             c__[c_offset], ldc, &v[v_offset], ldv, &one, &
+   20112             :                             work[work_offset], ldwork);
+   20113             :                 }
+   20114             : 
+   20115           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", trans, "Non-unit", m, k, &one, &t[
+   20116             :                         t_offset], ldt, &work[work_offset], ldwork);
+   20117             : 
+   20118           0 :                 if (*n > *k) {
+   20119             : 
+   20120           0 :                     i__1 = *n - *k;
+   20121           0 :                     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("No transpose", "No transpose", m, &i__1, k, &
+   20122             :                             minusone, &work[work_offset], ldwork, &v[v_offset], 
+   20123             :                             ldv, &one, &c__[c_offset], ldc);
+   20124             :                 }
+   20125             : 
+   20126           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Right", "Lower", "No transpose", "Unit", m, k, &one,
+   20127           0 :                          &v[(*n - *k + 1) * v_dim1 + 1], ldv, &work[
+   20128             :                         work_offset], ldwork);
+   20129             : 
+   20130           0 :                 i__1 = *k;
+   20131           0 :                 for (j = 1; j <= i__1; ++j) {
+   20132           0 :                     i__2 = *m;
+   20133           0 :                     for (i__ = 1; i__ <= i__2; ++i__) {
+   20134           0 :                         c__[i__ + (*n - *k + j) * c_dim1] -= work[i__ + j * 
+   20135           0 :                                 work_dim1];
+   20136             :                     }
+   20137             :                 }
+   20138             : 
+   20139             :             }
+   20140             : 
+   20141             :         }
+   20142             :     }
+   20143             : 
+   20144             :     return;
+   20145             : 
+   20146             : 
+   20147             : }
+   20148             : 
+   20149             : }
+   20150             : }
+   20151             : #include <cmath>
+   20152             : #include "real.h"
+   20153             : 
+   20154             : #include "blas/blas.h"
+   20155             : #include "lapack.h"
+   20156             : #include "lapack_limits.h"
+   20157             : 
+   20158             : 
+   20159             : #include "blas/blas.h"
+   20160             : namespace PLMD{
+   20161             : namespace lapack{
+   20162             : using namespace blas;
+   20163             : void
+   20164           0 : PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(int   *n,
+   20165             :                         float *alpha,
+   20166             :                         float *x,
+   20167             :                         int    *incx,
+   20168             :                         float *tau)
+   20169             : {
+   20170             :   float xnorm,t;
+   20171             :   int    ti1,knt,j;
+   20172             :   float minval,safmin,rsafmn,beta;
+   20173             : 
+   20174           0 :   if(*n<=1) {
+   20175           0 :     *tau = 0;
+   20176           0 :     return;
+   20177             :   }
+   20178             : 
+   20179           0 :   ti1 = *n-1;
+   20180             : 
+   20181           0 :   xnorm = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&ti1,x,incx);
+   20182             : 
+   20183           0 :   if(std::abs(xnorm)<PLUMED_GMX_FLOAT_MIN) {
+   20184           0 :     *tau = 0.0;
+   20185             :   } else {
+   20186             : 
+   20187           0 :     t = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(alpha,&xnorm);
+   20188             : 
+   20189           0 :     if(*alpha<0)
+   20190             :       beta = t;
+   20191             :     else
+   20192           0 :       beta = -t;
+   20193             : 
+   20194             :     minval = PLUMED_GMX_FLOAT_MIN;
+   20195             :     
+   20196             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS) / PLUMED_GMX_FLOAT_EPS;
+   20197             : 
+   20198             :         
+   20199           0 :     if(std::abs(beta)<safmin) {
+   20200             : 
+   20201             :       knt = 0;
+   20202           0 :       rsafmn = 1.0 / safmin;
+   20203             :       
+   20204           0 :       while(std::abs(beta)<safmin) {
+   20205           0 :         knt++;
+   20206           0 :         ti1 = *n-1;
+   20207           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&rsafmn,x,incx);
+   20208           0 :         beta *= rsafmn;
+   20209           0 :         *alpha *= rsafmn;
+   20210             :       }
+   20211             :       
+   20212             :       /* safmin <= beta <= 1 now */
+   20213           0 :       ti1 = *n-1;
+   20214           0 :       xnorm = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&ti1,x,incx);
+   20215           0 :       t = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(alpha,&xnorm);
+   20216             :       
+   20217           0 :       if(*alpha<0)
+   20218             :         beta = t;
+   20219             :       else
+   20220           0 :         beta = -t;
+   20221             :       
+   20222           0 :       *tau = (beta-*alpha)/beta;
+   20223             : 
+   20224           0 :       ti1= *n-1;
+   20225           0 :       t = 1.0/(*alpha-beta);
+   20226           0 :       PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&t,x,incx);
+   20227             :    
+   20228           0 :       *alpha = beta;
+   20229           0 :       for(j=0;j<knt;j++)
+   20230           0 :         *alpha *= safmin;
+   20231             :     } else {
+   20232           0 :       *tau = (beta-*alpha)/beta;
+   20233           0 :       ti1= *n-1;
+   20234           0 :       t = 1.0/(*alpha-beta);
+   20235           0 :       PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&t,x,incx);
+   20236           0 :       *alpha = beta;
+   20237             :     }
+   20238             :   }
+   20239             :    
+   20240             :   return;
+   20241             : }
+   20242             : }
+   20243             : }
+   20244             : #include <cmath>
+   20245             : #include "real.h"
+   20246             : 
+   20247             : #include "blas/blas.h"
+   20248             : #include "lapack.h"
+   20249             : 
+   20250             : #include "blas/blas.h"
+   20251             : namespace PLMD{
+   20252             : namespace lapack{
+   20253             : using namespace blas;
+   20254             : void 
+   20255           0 : PLUMED_BLAS_F77_FUNC(slarft,SLARFT)(const char *direct, 
+   20256             :         const char *storev, 
+   20257             :         int *n, 
+   20258             :         int *k, 
+   20259             :         float *v, 
+   20260             :         int *ldv, 
+   20261             :         float *tau, 
+   20262             :         float *t, 
+   20263             :         int *ldt)
+   20264             : {
+   20265             :     /* System generated locals */
+   20266             :     int t_dim1, t_offset, v_dim1, v_offset, i__1, i__2, i__3;
+   20267             :     float d__1;
+   20268             : 
+   20269             :     /* Local variables */
+   20270             :     int i__, j;
+   20271             :     float vii;
+   20272           0 :     int c__1 = 1;
+   20273           0 :     float zero = 0.0;
+   20274             : 
+   20275           0 :     v_dim1 = *ldv;
+   20276           0 :     v_offset = 1 + v_dim1;
+   20277           0 :     v -= v_offset;
+   20278           0 :     --tau;
+   20279           0 :     t_dim1 = *ldt;
+   20280           0 :     t_offset = 1 + t_dim1;
+   20281           0 :     t -= t_offset;
+   20282             : 
+   20283           0 :     if (*n == 0) {
+   20284             :         return;
+   20285             :     }
+   20286             : 
+   20287           0 :     if (*direct=='F' || *direct=='f') {
+   20288           0 :         i__1 = *k;
+   20289           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   20290           0 :             if (std::abs(tau[i__])<PLUMED_GMX_FLOAT_MIN) {
+   20291             : 
+   20292           0 :                 i__2 = i__;
+   20293           0 :                 for (j = 1; j <= i__2; ++j) {
+   20294           0 :                     t[j + i__ * t_dim1] = 0.;
+   20295             :                 }
+   20296             :             } else {
+   20297             : 
+   20298           0 :                 vii = v[i__ + i__ * v_dim1];
+   20299           0 :                 v[i__ + i__ * v_dim1] = 1.;
+   20300           0 :                 if (*storev=='C' || *storev=='c') {
+   20301             : 
+   20302           0 :                     i__2 = *n - i__ + 1;
+   20303           0 :                     i__3 = i__ - 1;
+   20304           0 :                     d__1 = -tau[i__];
+   20305           0 :                     PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__2, &i__3, &d__1, &v[i__ + v_dim1],
+   20306             :                              ldv, &v[i__ + i__ * v_dim1], &c__1, &zero, &t[
+   20307           0 :                             i__ * t_dim1 + 1], &c__1);
+   20308             :                 } else {
+   20309             : 
+   20310           0 :                     i__2 = i__ - 1;
+   20311           0 :                     i__3 = *n - i__ + 1;
+   20312           0 :                     d__1 = -tau[i__];
+   20313           0 :                     PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__2, &i__3, &d__1, &v[i__ * 
+   20314           0 :                             v_dim1 + 1], ldv, &v[i__ + i__ * v_dim1], ldv, &
+   20315           0 :                             zero, &t[i__ * t_dim1 + 1], &c__1);
+   20316             :                 }
+   20317           0 :                 v[i__ + i__ * v_dim1] = vii;
+   20318             : 
+   20319             : 
+   20320           0 :                 i__2 = i__ - 1;
+   20321           0 :                 PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Upper", "No transpose", "Non-unit", &i__2, &t[
+   20322           0 :                         t_offset], ldt, &t[i__ * t_dim1 + 1], &c__1);
+   20323           0 :                 t[i__ + i__ * t_dim1] = tau[i__];
+   20324             :             }
+   20325             :         }
+   20326             :     } else {
+   20327           0 :         for (i__ = *k; i__ >= 1; --i__) {
+   20328           0 :             if (std::abs(tau[i__])<PLUMED_GMX_FLOAT_MIN) {
+   20329             : 
+   20330           0 :                 i__1 = *k;
+   20331           0 :                 for (j = i__; j <= i__1; ++j) {
+   20332           0 :                     t[j + i__ * t_dim1] = 0.;
+   20333             :                 }
+   20334             :             } else {
+   20335             : 
+   20336           0 :                 if (i__ < *k) {
+   20337           0 :                     if (*storev=='C' || *storev=='c') {
+   20338           0 :                         vii = v[*n - *k + i__ + i__ * v_dim1];
+   20339           0 :                         v[*n - *k + i__ + i__ * v_dim1] = 1.;
+   20340             : 
+   20341           0 :                         i__1 = *n - *k + i__;
+   20342           0 :                         i__2 = *k - i__;
+   20343           0 :                         d__1 = -tau[i__];
+   20344           0 :                         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("Transpose", &i__1, &i__2, &d__1, &v[(i__ + 1) 
+   20345           0 :                                 * v_dim1 + 1], ldv, &v[i__ * v_dim1 + 1], &
+   20346           0 :                                 c__1, &zero, &t[i__ + 1 + i__ * t_dim1], &
+   20347             :                                 c__1);
+   20348           0 :                         v[*n - *k + i__ + i__ * v_dim1] = vii;
+   20349             :                     } else {
+   20350           0 :                         vii = v[i__ + (*n - *k + i__) * v_dim1];
+   20351           0 :                         v[i__ + (*n - *k + i__) * v_dim1] = 1.;
+   20352             : 
+   20353           0 :                         i__1 = *k - i__;
+   20354           0 :                         i__2 = *n - *k + i__;
+   20355           0 :                         d__1 = -tau[i__];
+   20356           0 :                         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("No transpose", &i__1, &i__2, &d__1, &v[i__ + 
+   20357           0 :                                 1 + v_dim1], ldv, &v[i__ + v_dim1], ldv, &
+   20358           0 :                                 zero, &t[i__ + 1 + i__ * t_dim1], &c__1);
+   20359           0 :                         v[i__ + (*n - *k + i__) * v_dim1] = vii;
+   20360             :                     }
+   20361             : 
+   20362           0 :                     i__1 = *k - i__;
+   20363           0 :                     PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Lower", "No transpose", "Non-unit", &i__1, &t[i__ 
+   20364           0 :                             + 1 + (i__ + 1) * t_dim1], ldt, &t[i__ + 1 + i__ *
+   20365           0 :                              t_dim1], &c__1)
+   20366             :                             ;
+   20367             :                 }
+   20368           0 :                 t[i__ + i__ * t_dim1] = tau[i__];
+   20369             :             }
+   20370             :         }
+   20371             :     }
+   20372             :     return;
+   20373             : 
+   20374             : 
+   20375             : }
+   20376             : }
+   20377             : }
+   20378             : #include <cmath>
+   20379             : #include "lapack.h"
+   20380             : 
+   20381             : #include "blas/blas.h"
+   20382             : namespace PLMD{
+   20383             : namespace lapack{
+   20384             : using namespace blas;
+   20385             : void
+   20386           0 : PLUMED_BLAS_F77_FUNC(slarnv,SLARNV)(int *idist, 
+   20387             :         int *iseed, 
+   20388             :         int *n, 
+   20389             :         float *x)
+   20390             : {
+   20391             :     int i__1, i__2, i__3;
+   20392             : 
+   20393             :     int i__;
+   20394             :     float u[128];
+   20395             :     int il, iv, il2;
+   20396             : 
+   20397           0 :     --x;
+   20398             :     --iseed;
+   20399             : 
+   20400           0 :     i__1 = *n;
+   20401           0 :     for (iv = 1; iv <= i__1; iv += 64) {
+   20402           0 :         i__2 = 64, i__3 = *n - iv + 1;
+   20403             :         il = (i__2<i__3) ? i__2 : i__3;
+   20404           0 :         if (*idist == 3) {
+   20405           0 :             il2 = il << 1;
+   20406             :         } else {
+   20407           0 :             il2 = il;
+   20408             :         }
+   20409             : 
+   20410           0 :         PLUMED_BLAS_F77_FUNC(slaruv,SLARUV)(&iseed[1], &il2, u);
+   20411             : 
+   20412           0 :         if (*idist == 1) {
+   20413             : 
+   20414             :             i__2 = il;
+   20415           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   20416           0 :                 x[iv + i__ - 1] = u[i__ - 1];
+   20417             :             }
+   20418           0 :         } else if (*idist == 2) {
+   20419             : 
+   20420             :             i__2 = il;
+   20421           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   20422           0 :                 x[iv + i__ - 1] = u[i__ - 1] * 2. - 1.;
+   20423             :             }
+   20424           0 :         } else if (*idist == 3) {
+   20425             : 
+   20426             :             i__2 = il;
+   20427           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   20428           0 :                 x[iv + i__ - 1] =  std::sqrt(std::log(u[(i__ << 1) - 2]) * -2.) * 
+   20429           0 :                   std::cos(u[(i__ << 1) - 1] * (float)6.2831853071795864769252867663);
+   20430             :             }
+   20431             :         }
+   20432             :     }
+   20433           0 :     return;
+   20434             : 
+   20435             : }
+   20436             : }
+   20437             : }
+   20438             : #include <cmath>
+   20439             : 
+   20440             : #include "real.h"
+   20441             : 
+   20442             : #include "lapack.h"
+   20443             : #include "lapack_limits.h"
+   20444             : 
+   20445             : #include "blas/blas.h"
+   20446             : namespace PLMD{
+   20447             : namespace lapack{
+   20448             : using namespace blas;
+   20449             : void
+   20450           0 : PLUMED_BLAS_F77_FUNC(slarrbx,SLARRBX)(int *n, 
+   20451             :          float *d__, 
+   20452             :          float *l, 
+   20453             :          float *ld, 
+   20454             :          float *lld, 
+   20455             :          int *ifirst, 
+   20456             :          int *ilast, 
+   20457             :          float *rtol1, 
+   20458             :          float *rtol2, 
+   20459             :          int *offset, 
+   20460             :          float *w, 
+   20461             :          float *wgap, 
+   20462             :          float *werr, 
+   20463             :          float *work,
+   20464             :          int *iwork, 
+   20465             :          int *info)
+   20466             : {
+   20467             :     int i__1, i__2, i__3;
+   20468             :     float d__1, d__2;
+   20469             : 
+   20470             :     int i__, j, k, p;
+   20471             :     float s;
+   20472             :     int i1, i2, ii, kk;
+   20473             :     float fac, gap, mid;
+   20474             :     int cnt;
+   20475             :     float tmp, left;
+   20476             :     int nint, prev, next, nleft;
+   20477             :     float right, width, dplus;
+   20478             :     int nright, olnint;
+   20479             :     k = 0;
+   20480             :     right = 0.0;
+   20481             : 
+   20482           0 :     --iwork;
+   20483           0 :     --work;
+   20484           0 :     --werr;
+   20485           0 :     --wgap;
+   20486           0 :     --w;
+   20487           0 :     --lld;
+   20488             :     --ld;
+   20489             :     --l;
+   20490           0 :     --d__;
+   20491             : 
+   20492           0 :     *info = 0;
+   20493           0 :     i__1 = *n << 1;
+   20494           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   20495           0 :         iwork[i__] = 0;
+   20496             :     }
+   20497           0 :     i1 = *ifirst;
+   20498             :     i2 = *ifirst;
+   20499             :     prev = 0;
+   20500           0 :     i__1 = *ilast;
+   20501           0 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+   20502           0 :         k = i__ << 1;
+   20503           0 :         iwork[k - 1] = 1;
+   20504             :         i2 = i__;
+   20505             :     }
+   20506             : 
+   20507             :     i__ = i1;
+   20508             :     nint = 0;
+   20509           0 : L30:
+   20510           0 :     if (i__ <= i2) {
+   20511           0 :         ii = i__ - *offset;
+   20512           0 :         if (iwork[(i__ << 1) - 1] == 1) {
+   20513             :             fac = 1.;
+   20514           0 :             left = w[ii] - werr[ii];
+   20515             : 
+   20516             : 
+   20517           0 : L40:
+   20518           0 :             if (i__ > i1 && left <= right) {
+   20519             :                 left = right;
+   20520           0 :                 cnt = i__ - 1;
+   20521             :             } else {
+   20522           0 :                 s = -left;
+   20523             :                 cnt = 0;
+   20524           0 :                 i__1 = *n - 1;
+   20525           0 :                 for (j = 1; j <= i__1; ++j) {
+   20526           0 :                     dplus = d__[j] + s;
+   20527           0 :                     s = s * lld[j] / dplus - left;
+   20528           0 :                     if (dplus < 0.) {
+   20529           0 :                         ++cnt;
+   20530             :                     }
+   20531             :                 }
+   20532           0 :                 dplus = d__[*n] + s;
+   20533           0 :                 if (dplus < 0.) {
+   20534           0 :                     ++cnt;
+   20535             :                 }
+   20536           0 :                 if (std::isnan(s)) {
+   20537             : 
+   20538             :                     cnt = 0;
+   20539             :                     s = -left;
+   20540             :                     i__1 = *n - 1;
+   20541           0 :                     for (j = 1; j <= i__1; ++j) {
+   20542           0 :                         dplus = d__[j] + s;
+   20543           0 :                         if (dplus < 0.) {
+   20544           0 :                             ++cnt;
+   20545             :                         }
+   20546           0 :                         tmp = lld[j] / dplus;
+   20547           0 :                         if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   20548           0 :                             s = lld[j] - left;
+   20549             :                         } else {
+   20550           0 :                             s = s * tmp - left;
+   20551             :                         }
+   20552             :                     }
+   20553           0 :                     dplus = d__[*n] + s;
+   20554           0 :                     if (dplus < 0.) {
+   20555           0 :                         ++cnt;
+   20556             :                     }
+   20557             :                 }
+   20558           0 :                 if (cnt > i__ - 1) {
+   20559           0 :                     left -= werr[ii] * fac;
+   20560           0 :                     fac *= 2.;
+   20561           0 :                     goto L40;
+   20562             :                 }
+   20563             :             }
+   20564           0 :             nleft = cnt + 1;
+   20565             :             i1 = (i1<nleft) ? i1 : nleft;
+   20566             :             fac = 1.;
+   20567           0 :             right = w[ii] + werr[ii];
+   20568           0 : L60:
+   20569           0 :             s = -right;
+   20570             :             cnt = 0;
+   20571           0 :             i__1 = *n - 1;
+   20572           0 :             for (j = 1; j <= i__1; ++j) {
+   20573           0 :                 dplus = d__[j] + s;
+   20574           0 :                 s = s * lld[j] / dplus - right;
+   20575           0 :                 if (dplus < 0.) {
+   20576           0 :                     ++cnt;
+   20577             :                 }
+   20578             :             }
+   20579           0 :             dplus = d__[*n] + s;
+   20580           0 :             if (dplus < 0.) {
+   20581           0 :                 ++cnt;
+   20582             :             }
+   20583           0 :             if (std::isnan(s)) {
+   20584             : 
+   20585             :                 cnt = 0;
+   20586             :                 s = -right;
+   20587             :                 i__1 = *n - 1;
+   20588           0 :                 for (j = 1; j <= i__1; ++j) {
+   20589           0 :                     dplus = d__[j] + s;
+   20590           0 :                     if (dplus < 0.) {
+   20591           0 :                         ++cnt;
+   20592             :                     }
+   20593           0 :                     tmp = lld[j] / dplus;
+   20594           0 :                     if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   20595           0 :                         s = lld[j] - right;
+   20596             :                     } else {
+   20597           0 :                         s = s * tmp - right;
+   20598             :                     }
+   20599             :                 }
+   20600           0 :                 dplus = d__[*n] + s;
+   20601           0 :                 if (dplus < 0.) {
+   20602           0 :                     ++cnt;
+   20603             :                 }
+   20604             :             }
+   20605           0 :             if (cnt < i__) {
+   20606           0 :                 right += werr[ii] * fac;
+   20607           0 :                 fac *= 2.;
+   20608           0 :                 goto L60;
+   20609             :             }
+   20610             :             cnt = (cnt<i2) ? cnt : i2;
+   20611           0 :             ++nint;
+   20612           0 :             k = nleft << 1;
+   20613           0 :             work[k - 1] = left;
+   20614           0 :             work[k] = right;
+   20615           0 :             i__ = cnt + 1;
+   20616           0 :             iwork[k - 1] = i__;
+   20617           0 :             iwork[k] = cnt;
+   20618           0 :             if (prev != nleft - 1) {
+   20619           0 :                 work[k - 2] = left;
+   20620             :             }
+   20621             :             prev = nleft;
+   20622             :         } else {
+   20623           0 :             right = work[i__ * 2];
+   20624             : 
+   20625           0 :             ++iwork[k - 1];
+   20626             :             prev = i__;
+   20627           0 :             ++i__;
+   20628             :         }
+   20629           0 :         goto L30;
+   20630             :     }
+   20631           0 :     if (i__ <= *n && iwork[(i__ << 1) - 1] != -1) {
+   20632           0 :         work[(i__ << 1) - 1] = work[prev * 2];
+   20633             :     }
+   20634             : 
+   20635           0 : L80:
+   20636           0 :     prev = i1 - 1;
+   20637             :     olnint = nint;
+   20638             :     i__ = i1;
+   20639             :     i__1 = olnint;
+   20640           0 :     for (p = 1; p <= i__1; ++p) {
+   20641           0 :         k = i__ << 1;
+   20642           0 :         left = work[k - 1];
+   20643           0 :         right = work[k];
+   20644           0 :         next = iwork[k - 1];
+   20645           0 :         nright = iwork[k];
+   20646           0 :         mid = (left + right) * .5;
+   20647           0 :         width = right - mid;
+   20648             :         d__1 = std::abs(left);
+   20649             :         d__2 = std::abs(right);
+   20650           0 :         tmp = (d__1>d__2) ? d__1 : d__2;
+   20651             : 
+   20652             :         gap = 0.;
+   20653           0 :         if (i__ == nright) {
+   20654           0 :             if (prev > 0 && next <= *n) {
+   20655           0 :                 d__1 = left - work[k - 2], d__2 = work[k + 1] - right;
+   20656           0 :                 gap = (d__1<d__2) ? d__1 : d__2;
+   20657           0 :             } else if (prev > 0) {
+   20658           0 :                 gap = left - work[k - 2];
+   20659           0 :             } else if (next <= *n) {
+   20660           0 :                 gap = work[k + 1] - right;
+   20661             :             }
+   20662             :         }
+   20663           0 :         d__1 = *rtol1 * gap, d__2 = *rtol2 * tmp;
+   20664           0 :         if (width < ((d__1>d__2) ? d__1 : d__2)) {
+   20665           0 :             --nint;
+   20666           0 :             iwork[k - 1] = 0;
+   20667             :             kk = k;
+   20668             :             i__2 = nright;
+   20669           0 :             for (j = i__ + 1; j <= i__2; ++j) {
+   20670           0 :                 kk += 2;
+   20671           0 :                 iwork[kk - 1] = 0;
+   20672           0 :                 work[kk - 1] = left;
+   20673           0 :                 work[kk] = right;
+   20674           0 :                 wgap[j - 1 - *offset] = 0.;
+   20675             :             }
+   20676           0 :             if (i1 == i__) {
+   20677             :                 i1 = next;
+   20678             :             } else {
+   20679           0 :                 iwork[(prev << 1) - 1] = next;
+   20680             :             }
+   20681             :             i__ = next;
+   20682           0 :             continue;
+   20683             :         }
+   20684             :         prev = i__;
+   20685             : 
+   20686           0 :         s = -mid;
+   20687             :         cnt = 0;
+   20688           0 :         i__2 = *n - 1;
+   20689           0 :         for (j = 1; j <= i__2; ++j) {
+   20690           0 :             dplus = d__[j] + s;
+   20691           0 :             s = s * lld[j] / dplus - mid;
+   20692           0 :             if (dplus < 0.) {
+   20693           0 :                 ++cnt;
+   20694             :             }
+   20695             :         }
+   20696           0 :         dplus = d__[*n] + s;
+   20697           0 :         if (dplus < 0.) {
+   20698           0 :             ++cnt;
+   20699             :         }
+   20700           0 :         if (std::isnan(s)) {
+   20701             :             cnt = 0;
+   20702             :             s = -mid;
+   20703             :             i__2 = *n - 1;
+   20704           0 :             for (j = 1; j <= i__2; ++j) {
+   20705           0 :                 dplus = d__[j] + s;
+   20706           0 :                 if (dplus < 0.) {
+   20707           0 :                     ++cnt;
+   20708             :                 }
+   20709           0 :                 tmp = lld[j] / dplus;
+   20710           0 :                 if (std::abs(tmp)<PLUMED_GMX_FLOAT_MIN) {
+   20711           0 :                     s = lld[j] - mid;
+   20712             :                 } else {
+   20713           0 :                     s = s * tmp - mid;
+   20714             :                 }
+   20715             :             }
+   20716           0 :             dplus = d__[*n] + s;
+   20717           0 :             if (dplus < 0.) {
+   20718           0 :                 ++cnt;
+   20719             :             }
+   20720             :         }
+   20721           0 :         i__2 = i__ - 1, i__3 = (nright<cnt) ? nright : cnt;
+   20722             :         cnt = (i__2>i__3) ? i__2 : i__3;
+   20723           0 :         if (cnt == i__ - 1) {
+   20724           0 :             work[k - 1] = mid;
+   20725           0 :         } else if (cnt == nright) {
+   20726           0 :             work[k] = mid;
+   20727             :         } else {
+   20728           0 :             iwork[k] = cnt;
+   20729           0 :             ++cnt;
+   20730           0 :             iwork[k - 1] = cnt;
+   20731           0 :             kk = cnt << 1;
+   20732           0 :             iwork[kk - 1] = next;
+   20733           0 :             iwork[kk] = nright;
+   20734           0 :             work[k] = mid;
+   20735           0 :             work[kk - 1] = mid;
+   20736           0 :             work[kk] = right;
+   20737             :             prev = cnt;
+   20738           0 :             if (cnt - 1 > i__) {
+   20739           0 :                 work[kk - 2] = mid;
+   20740             :             }
+   20741           0 :             if (cnt > *ifirst && cnt <= *ilast) {
+   20742           0 :                 ++nint;
+   20743           0 :             } else if (cnt <= *ifirst) {
+   20744             :                 i1 = cnt;
+   20745             :             }
+   20746             :         }
+   20747             :         i__ = next;
+   20748             :     }
+   20749           0 :     if (nint > 0) {
+   20750           0 :         goto L80;
+   20751             :     }
+   20752           0 :     i__1 = *ilast;
+   20753           0 :     for (i__ = *ifirst; i__ <= i__1; ++i__) {
+   20754           0 :         k = i__ << 1;
+   20755           0 :         ii = i__ - *offset;
+   20756           0 :         if (iwork[k - 1] != -1) {
+   20757           0 :             w[ii] = (work[k - 1] + work[k]) * .5;
+   20758           0 :             werr[ii] = work[k] - w[ii];
+   20759           0 :             if (i__ != *ilast) {
+   20760           0 :                 wgap[ii] = work[k + 1] - work[k];
+   20761             :             }
+   20762             :         }
+   20763             :     }
+   20764             : 
+   20765           0 :     return;
+   20766             : 
+   20767             : } 
+   20768             : }
+   20769             : }
+   20770             : #include <cctype>
+   20771             : #include <cmath>
+   20772             : 
+   20773             : #include "real.h"
+   20774             : 
+   20775             : #include "blas/blas.h"
+   20776             : #include "lapack.h"
+   20777             : #include "lapack_limits.h"
+   20778             : 
+   20779             : 
+   20780             : 
+   20781             : #include "blas/blas.h"
+   20782             : namespace PLMD{
+   20783             : namespace lapack{
+   20784             : using namespace blas;
+   20785             : void
+   20786           0 : PLUMED_BLAS_F77_FUNC(slarrex,SLARREX)(const char *range,
+   20787             :          int *n, 
+   20788             :          float *vl, 
+   20789             :          float *vu, 
+   20790             :          int *il, 
+   20791             :          int *iu, 
+   20792             :          float *d__, 
+   20793             :          float *e, 
+   20794             :          float *tol, 
+   20795             :          int *nsplit, 
+   20796             :          int *isplit, 
+   20797             :          int *m, 
+   20798             :          float *w, 
+   20799             :          int *iblock, 
+   20800             :          int *indexw, 
+   20801             :          float *gersch, 
+   20802             :          float *work,
+   20803             :          int *iwork, 
+   20804             :          int *info)
+   20805             : {
+   20806             :     int i__1, i__2, i__3;
+   20807             :     float d__1, d__2;
+   20808           0 :     int c__1 = 1;
+   20809           0 :     int c__0 = 0;
+   20810             : 
+   20811             :     int i__, j, k;
+   20812             :     float s, gl;
+   20813             :     int in;
+   20814             :     float gu;
+   20815             :     int cnt;
+   20816             :     float eps, tau, nrm, tmp, vvl, vvu, offd;
+   20817             :     int iend, jblk, till, itmp;
+   20818             :     float rtol, delta, sigma;
+   20819             :     int iinfo;
+   20820             :     float width;
+   20821             :     int ibegin;
+   20822             :     int irange;
+   20823             :     float sgndef;
+   20824             :     int maxcnt;
+   20825           0 :     --iwork;
+   20826           0 :     --work;
+   20827           0 :     --gersch;
+   20828           0 :     --indexw;
+   20829           0 :     --iblock;
+   20830           0 :     --w;
+   20831           0 :     --isplit;
+   20832           0 :     --e;
+   20833           0 :     --d__;
+   20834             : 
+   20835             :     sigma = 0;
+   20836             :     irange = 0;
+   20837             :     sgndef = 0;
+   20838             :     maxcnt = 0;
+   20839             : 
+   20840           0 :     *info = 0;
+   20841             : 
+   20842           0 :     if (*range=='A' || *range=='a')
+   20843             :         irange = 1;
+   20844           0 :     else if (*range=='V' || *range=='v')
+   20845             :         irange = 2;
+   20846           0 :     else if (*range=='I' || *range=='i')
+   20847             :         irange = 3;
+   20848             :     
+   20849             : 
+   20850           0 :     *m = 0;
+   20851             :     eps = PLUMED_GMX_FLOAT_EPS;
+   20852             : 
+   20853           0 :     *nsplit = 1;
+   20854           0 :     i__1 = *n - 1;
+   20855           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   20856           0 :         if (std::abs(e[i__]) <= *tol) {
+   20857           0 :             isplit[*nsplit] = i__;
+   20858           0 :             ++(*nsplit);
+   20859             :         }
+   20860             :     }
+   20861           0 :     isplit[*nsplit] = *n;
+   20862             : 
+   20863             :     ibegin = 1;
+   20864           0 :     i__1 = *nsplit;
+   20865           0 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+   20866           0 :         iend = isplit[jblk];
+   20867           0 :         if (ibegin == iend) {
+   20868           0 :             ++(*m);
+   20869           0 :             w[*m] = d__[ibegin];
+   20870           0 :             iblock[*m] = jblk;
+   20871           0 :             indexw[*m] = 1;
+   20872           0 :             e[iend] = 0.;
+   20873           0 :             ibegin = iend + 1;
+   20874           0 :             goto L170;
+   20875             :         }
+   20876           0 :         in = iend - ibegin + 1;
+   20877             : 
+   20878           0 :         gl = d__[ibegin] - std::abs(e[ibegin]);
+   20879           0 :         gu = d__[ibegin] + std::abs(e[ibegin]);
+   20880           0 :         gersch[(ibegin << 1) - 1] = gl;
+   20881           0 :         gersch[ibegin * 2] = gu;
+   20882           0 :         gersch[(iend << 1) - 1] = d__[iend] - std::abs(e[iend - 1]);
+   20883           0 :         gersch[iend * 2] = d__[iend] + std::abs(e[iend - 1]);
+   20884           0 :         d__1 = gersch[(iend << 1) - 1];
+   20885           0 :         gl = (d__1<gl) ? d__1 : gl;
+   20886             :         d__1 = gersch[iend * 2];
+   20887           0 :         gu = (d__1>gu) ? d__1 : gu;
+   20888           0 :         i__2 = iend - 1;
+   20889           0 :         for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+   20890           0 :             offd = std::abs(e[i__ - 1]) + std::abs(e[i__]);
+   20891           0 :             gersch[(i__ << 1) - 1] = d__[i__] - offd;
+   20892             :             d__1 = gersch[(i__ << 1) - 1];
+   20893           0 :             gl = (d__1<gl) ? d__1 : gl;
+   20894           0 :             gersch[i__ * 2] = d__[i__] + offd;
+   20895             :             d__1 = gersch[i__ * 2];
+   20896           0 :             gu = (d__1>gu) ? d__1 : gu;
+   20897             :         }
+   20898             :         d__1 = std::abs(gl), d__2 = std::abs(gu);
+   20899           0 :         nrm = (d__1>d__2) ? d__1 : d__2;
+   20900             : 
+   20901           0 :         width = gu - gl;
+   20902             :         i__2 = iend - 1;
+   20903           0 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+   20904           0 :             work[i__] = e[i__] * e[i__];
+   20905             :         }
+   20906           0 :         for (j = 1; j <= 2; ++j) {
+   20907           0 :             if (j == 1) {
+   20908           0 :                 tau = gl + width * .25;
+   20909             :             } else {
+   20910           0 :                 tau = gu - width * .25;
+   20911             :             }
+   20912           0 :             tmp = d__[ibegin] - tau;
+   20913           0 :             if (tmp < 0.) {
+   20914           0 :                 cnt = 1;
+   20915             :             } else {
+   20916           0 :                 cnt = 0;
+   20917             :             }
+   20918           0 :             i__2 = iend;
+   20919           0 :             for (i__ = ibegin + 1; i__ <= i__2; ++i__) {
+   20920           0 :                 tmp = d__[i__] - tau - work[i__ - 1] / tmp;
+   20921           0 :                 if (tmp < 0.) {
+   20922           0 :                     ++cnt;
+   20923             :                 }
+   20924             :             }
+   20925           0 :             if (cnt == 0) {
+   20926             :                 gl = tau;
+   20927           0 :             } else if (cnt == in) {
+   20928             :                 gu = tau;
+   20929             :             }
+   20930           0 :             if (j == 1) {
+   20931             :                 maxcnt = cnt;
+   20932             :                 sigma = gl;
+   20933             :                 sgndef = 1.;
+   20934             :             } else {
+   20935           0 :                 if (in - cnt > maxcnt) {
+   20936             :                     sigma = gu;
+   20937             :                     sgndef = -1.;
+   20938             :                 }
+   20939             :             }
+   20940             :         }
+   20941             : 
+   20942           0 :         work[in * 3] = 1.;
+   20943             :         delta = eps;
+   20944           0 :         tau = sgndef * nrm;
+   20945           0 : L60:
+   20946           0 :         sigma -= delta * tau;
+   20947           0 :         work[1] = d__[ibegin] - sigma;
+   20948             :         j = ibegin;
+   20949           0 :         i__2 = in - 1;
+   20950           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   20951           0 :             work[(in << 1) + i__] = 1. / work[i__];
+   20952           0 :             tmp = e[j] * work[(in << 1) + i__];
+   20953           0 :             work[i__ + 1] = d__[j + 1] - sigma - tmp * e[j];
+   20954           0 :             work[in + i__] = tmp;
+   20955           0 :             ++j;
+   20956             :         }
+   20957           0 :         for (i__ = in; i__ >= 1; --i__) {
+   20958           0 :             tmp = sgndef * work[i__];
+   20959           0 :             if (tmp < 0. || std::abs(work[(in << 1) + i__])<PLUMED_GMX_FLOAT_MIN || std::isnan(tmp)) {
+   20960           0 :                 delta *= 2.;
+   20961           0 :                 goto L60;
+   20962             :             }
+   20963             :         }
+   20964             : 
+   20965           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+   20966           0 :         i__2 = in - 1;
+   20967           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+   20968           0 :         i__2 = in - 1;
+   20969           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   20970           0 :             work[in * 3 + i__] = work[i__] * work[in + i__];
+   20971           0 :             work[(in << 2) + i__] = work[in * 3 + i__] * work[in + i__];
+   20972             :         }
+   20973           0 :         if (sgndef > 0.) {
+   20974           0 :             cnt = 1;
+   20975           0 :             work[1] = (gl + gu) / 2. - sigma;
+   20976           0 :             work[in + 1] = 0.;
+   20977           0 :             work[(in << 1) + 1] = (gu - gl) / 2.;
+   20978             :         } else {
+   20979           0 :             cnt = in;
+   20980           0 :             work[in] = (gl + gu) / 2. - sigma;
+   20981           0 :             work[in * 2] = 0.;
+   20982           0 :             work[in * 3] = (gu - gl) / 2.;
+   20983             :         }
+   20984           0 :         rtol = eps * 4.;
+   20985           0 :         PLUMED_BLAS_F77_FUNC(slarrbx,SLARRBX)(&in, &d__[ibegin], &e[ibegin], &work[in * 3 + 1], &work[(in <<
+   20986           0 :                  2) + 1], &cnt, &cnt, &rtol, &rtol, &c__0, &work[1], &work[in 
+   20987           0 :                 + 1], &work[(in << 1) + 1], &work[in * 5 + 1], &iwork[1], &
+   20988             :                 iinfo);
+   20989           0 :         if (sgndef > 0.) {
+   20990           0 :             tau = work[1] - work[(in << 1) + 1];
+   20991             :         } else {
+   20992           0 :             tau = work[in] + work[in * 3];
+   20993             :         }
+   20994             : 
+   20995           0 :         work[in * 3] = 1.;
+   20996             :         delta = eps * 2.;
+   20997           0 : L100:
+   20998           0 :         tau *= 1. - delta;
+   20999             : 
+   21000           0 :         s = -tau;
+   21001             :         j = ibegin;
+   21002           0 :         i__2 = in - 1;
+   21003           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   21004           0 :             work[i__] = d__[j] + s;
+   21005           0 :             work[(in << 1) + i__] = 1. / work[i__];
+   21006           0 :             work[in + i__] = e[j] * d__[j] * work[(in << 1) + i__];
+   21007           0 :             s = s * work[in + i__] * e[j] - tau;
+   21008           0 :             ++j;
+   21009             :         }
+   21010           0 :         work[in] = d__[iend] + s;
+   21011             : 
+   21012           0 :         for (i__ = in; i__ >= 1; --i__) {
+   21013           0 :             tmp = sgndef * work[i__];
+   21014           0 :             if (tmp < 0. || std::abs(work[(in << 1) + i__])<PLUMED_GMX_FLOAT_MIN || std::isnan(tmp)) {
+   21015           0 :                 delta *= 2.;
+   21016           0 :                 goto L100;
+   21017             :             }
+   21018             :         }
+   21019             : 
+   21020           0 :         sigma += tau;
+   21021           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&in, &work[1], &c__1, &d__[ibegin], &c__1);
+   21022           0 :         i__2 = in - 1;
+   21023           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
+   21024           0 :         e[iend] = sigma;
+   21025           0 :         tmp = (float) in * 4. * eps * (std::abs(sigma) + std::abs(tau));
+   21026             :         i__2 = iend;
+   21027           0 :         for (i__ = ibegin; i__ <= i__2; ++i__) {
+   21028           0 :             gersch[(i__ << 1) - 1] = gersch[(i__ << 1) - 1] - sigma - tmp;
+   21029           0 :             gersch[i__ * 2] = gersch[i__ * 2] - sigma + tmp;
+   21030             :         }
+   21031             : 
+   21032             :         j = ibegin;
+   21033           0 :         i__2 = in - 1;
+   21034           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   21035           0 :             work[(i__ << 1) - 1] = std::abs(d__[j]);
+   21036           0 :             work[i__ * 2] = e[j] * e[j] * work[(i__ << 1) - 1];
+   21037           0 :             ++j;
+   21038             :         }
+   21039           0 :         work[(in << 1) - 1] = std::abs(d__[iend]);
+   21040             : 
+   21041           0 :         PLUMED_BLAS_F77_FUNC(slasq2,SLASQ2)(&in, &work[1], info);
+   21042           0 :         if (*info != 0) {
+   21043             :             return;
+   21044             :         }
+   21045             : 
+   21046           0 :         if (sgndef > 0.) {
+   21047           0 :             i__2 = in;
+   21048           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   21049           0 :                 ++(*m);
+   21050           0 :                 w[*m] = work[in - i__ + 1];
+   21051           0 :                 iblock[*m] = jblk;
+   21052           0 :                 indexw[*m] = i__;
+   21053             :             }
+   21054             :         } else {
+   21055           0 :             i__2 = in;
+   21056           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   21057           0 :                 ++(*m);
+   21058           0 :                 w[*m] = -work[i__];
+   21059           0 :                 iblock[*m] = jblk;
+   21060           0 :                 indexw[*m] = i__;
+   21061             :             }
+   21062             :         }
+   21063           0 :         ibegin = iend + 1;
+   21064           0 : L170:
+   21065             :         ;
+   21066             :     }
+   21067           0 :     if (irange == 2) {
+   21068           0 :         *m = 0;
+   21069             :         ibegin = 1;
+   21070           0 :         i__1 = *nsplit;
+   21071           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   21072           0 :             iend = isplit[i__];
+   21073           0 :             vvl = *vl - e[iend];
+   21074           0 :             vvu = *vu - e[iend];
+   21075           0 :             i__2 = iend;
+   21076           0 :             for (j = ibegin; j <= i__2; ++j) {
+   21077           0 :                 if (vvl <= w[j] && w[j] <= vvu) {
+   21078           0 :                     ++(*m);
+   21079           0 :                     w[*m] = w[j];
+   21080           0 :                     iblock[*m] = i__;
+   21081           0 :                     indexw[*m] = j - ibegin + 1;
+   21082             :                 }
+   21083             :             }
+   21084           0 :             ibegin = iend + 1;
+   21085             :         }
+   21086           0 :     } else if (irange == 3) {
+   21087           0 :         *m = *iu - *il + 1;
+   21088           0 :         if (*nsplit == 1) {
+   21089             :             i__1 = *m;
+   21090           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21091           0 :                 w[i__] = w[*il + i__ - 1];
+   21092           0 :                 indexw[i__] = *il + i__ - 1;
+   21093             :             }
+   21094             :         } else {
+   21095             :             ibegin = 1;
+   21096             :             i__1 = *nsplit;
+   21097           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21098           0 :                 iend = isplit[i__];
+   21099           0 :                 i__2 = iend;
+   21100           0 :                 for (j = ibegin; j <= i__2; ++j) {
+   21101           0 :                     work[j] = w[j] + e[iend];
+   21102             :                 }
+   21103           0 :                 ibegin = iend + 1;
+   21104             :             }
+   21105           0 :             i__1 = *n;
+   21106           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21107           0 :                 iwork[i__] = i__;
+   21108           0 :                 iwork[*n + i__] = iblock[i__];
+   21109             :             }
+   21110           0 :             PLUMED_BLAS_F77_FUNC(slasrt2,SLASRT2)("I", n, &work[1], &iwork[1], &iinfo);
+   21111           0 :             i__1 = *m;
+   21112           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21113           0 :                 itmp = iwork[*il + i__ - 1];
+   21114           0 :                 work[i__] = w[itmp];
+   21115           0 :                 iblock[i__] = iwork[*n + itmp];
+   21116             :             }
+   21117           0 :             i__1 = *m;
+   21118           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21119           0 :                 iwork[*n + i__] = iwork[*il + i__ - 1];
+   21120           0 :                 iwork[i__] = i__;
+   21121             :             }
+   21122           0 :             PLUMED_BLAS_F77_FUNC(ilasrt2,ILASRT2)("I", m, &iblock[1], &iwork[1], &iinfo);
+   21123             :             j = 1;
+   21124           0 :             itmp = iblock[j];
+   21125           0 :             cnt = iwork[*n + iwork[j]];
+   21126           0 :             if (itmp == 1) {
+   21127             :                 ibegin = 1;
+   21128             :             } else {
+   21129           0 :                 ibegin = isplit[itmp - 1] + 1;
+   21130             :             }
+   21131           0 :             i__1 = *m;
+   21132           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   21133           0 :                 w[i__] = work[iwork[i__]];
+   21134           0 :                 if (iblock[i__] != itmp || i__ == *m) {
+   21135           0 :                     if (iblock[i__] == itmp) {
+   21136           0 :                         till = *m;
+   21137             :                     } else {
+   21138           0 :                         till = i__ - 1;
+   21139             :                     }
+   21140           0 :                     i__2 = till - j + 1;
+   21141           0 :                     PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("I", &i__2, &w[j], &iinfo);
+   21142           0 :                     cnt = cnt - ibegin + 1;
+   21143           0 :                     i__2 = till;
+   21144           0 :                     for (k = j; k <= i__2; ++k) {
+   21145           0 :                         indexw[k] = cnt + k - j;
+   21146             :                     }
+   21147             :                     j = i__;
+   21148           0 :                     itmp = iblock[j];
+   21149           0 :                     cnt = iwork[*n + iwork[j]];
+   21150           0 :                     ibegin = isplit[itmp - 1] + 1;
+   21151           0 :                     if (i__ == *m && till < *m) {
+   21152           0 :                         indexw[*m] = cnt - ibegin + 1;
+   21153             :                     }
+   21154             :                 } else {
+   21155           0 :                     i__2 = cnt, i__3 = iwork[*n + iwork[i__]];
+   21156           0 :                     cnt = (i__2<i__3) ? i__2 : i__3;
+   21157             :                 }
+   21158             :             }
+   21159             :         }
+   21160             :     }
+   21161             : 
+   21162             :     return;
+   21163             : 
+   21164             : }
+   21165             : 
+   21166             : 
+   21167             : }
+   21168             : }
+   21169             : #include <cmath>
+   21170             : 
+   21171             : #include "real.h"
+   21172             : 
+   21173             : #include "blas/blas.h"
+   21174             : #include "lapack.h"
+   21175             : #include "lapack_limits.h"
+   21176             : 
+   21177             : 
+   21178             : #include "blas/blas.h"
+   21179             : namespace PLMD{
+   21180             : namespace lapack{
+   21181             : using namespace blas;
+   21182             : void
+   21183           0 : PLUMED_BLAS_F77_FUNC(slarrfx,SLARRFX)(int *n, 
+   21184             :         float *d__, 
+   21185             :         float *l, 
+   21186             :         float *ld, 
+   21187             :         float *lld, 
+   21188             :         int *ifirst, 
+   21189             :         int *ilast, 
+   21190             :         float *w, 
+   21191             :         float *sigma, 
+   21192             :         float *dplus, 
+   21193             :         float *lplus, 
+   21194             :         float *work,
+   21195             :         int *info)
+   21196             : {
+   21197           0 :     int i1 = 1;
+   21198             :     int i__1;
+   21199             :     float d__2, d__3;
+   21200             : 
+   21201             :     int i__;
+   21202             :     float s, eps, tmp, dmax1, dmax2, delta;
+   21203           0 :     --work;
+   21204           0 :     --lplus;
+   21205           0 :     --dplus;
+   21206           0 :     --w;
+   21207             :     --lld;
+   21208           0 :     --ld;
+   21209           0 :     --l;
+   21210           0 :     --d__;
+   21211           0 :     *info = 0;
+   21212             :     eps = PLUMED_GMX_FLOAT_EPS;
+   21213           0 :     *sigma = w[*ifirst];
+   21214             :     delta = eps * 2.;
+   21215             : 
+   21216           0 : L10:
+   21217           0 :     s = -(*sigma);
+   21218           0 :     dplus[1] = d__[1] + s;
+   21219             :     dmax1 = std::abs(dplus[1]);
+   21220           0 :     i__1 = *n - 1;
+   21221           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21222           0 :         lplus[i__] = ld[i__] / dplus[i__];
+   21223           0 :         s = s * lplus[i__] * l[i__] - *sigma;
+   21224           0 :         dplus[i__ + 1] = d__[i__ + 1] + s;
+   21225             :         d__2 = dmax1, d__3 = std::abs(dplus[i__ + 1]);
+   21226           0 :         dmax1 = (d__2>d__3) ? d__2 : d__3;
+   21227             :     }
+   21228           0 :     if (std::isnan(dmax1)) {
+   21229           0 :         *sigma -= std::abs(*sigma) * delta;
+   21230           0 :         delta *= 2.;
+   21231           0 :         goto L10;
+   21232             :     }
+   21233             : 
+   21234           0 :     tmp = w[*ilast];
+   21235             :     delta = eps * 2.;
+   21236           0 : L30:
+   21237           0 :     s = -tmp;
+   21238           0 :     work[1] = d__[1] + s;
+   21239             :     dmax2 = std::abs(work[1]);
+   21240           0 :     i__1 = *n - 1;
+   21241           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21242           0 :         work[*n + i__] = ld[i__] / work[i__];
+   21243           0 :         s = s * work[*n + i__] * l[i__] - tmp;
+   21244           0 :         work[i__ + 1] = d__[i__ + 1] + s;
+   21245             :         d__2 = dmax2, d__3 = std::abs(work[i__ + 1]);
+   21246           0 :         dmax2 = (d__2>d__3) ? d__2 : d__3;
+   21247             :     }
+   21248           0 :     if (std::isnan(dmax2)) {
+   21249           0 :         tmp += std::abs(tmp) * delta;
+   21250           0 :         delta *= 2.;
+   21251           0 :         goto L30;
+   21252             :     }
+   21253           0 :     if (dmax2 < dmax1) {
+   21254           0 :         *sigma = tmp;
+   21255           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &work[1], &i1, &dplus[1], &i1);
+   21256           0 :         i__1 = *n - 1;
+   21257           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &work[*n + 1], &i1, &lplus[1], &i1);
+   21258             :     }
+   21259             : 
+   21260           0 :     return;
+   21261             : }
+   21262             : }
+   21263             : }
+   21264             : #include <cmath>
+   21265             : 
+   21266             : #include "real.h"
+   21267             : 
+   21268             : #include "blas/blas.h"
+   21269             : #include "lapack.h"
+   21270             : #include "lapack_limits.h"
+   21271             : 
+   21272             : 
+   21273             : #include "blas/blas.h"
+   21274             : namespace PLMD{
+   21275             : namespace lapack{
+   21276             : using namespace blas;
+   21277             : void
+   21278           0 : PLUMED_BLAS_F77_FUNC(slarrvx,SLARRVX)(int *n, 
+   21279             :         float *d__, 
+   21280             :         float *l, 
+   21281             :         int *isplit,
+   21282             :         int *m, 
+   21283             :         float *w,
+   21284             :         int *iblock, 
+   21285             :         int *indexw, 
+   21286             :         float *gersch, 
+   21287             :         float *tol, 
+   21288             :         float *z__, 
+   21289             :         int *ldz, 
+   21290             :         int *isuppz, 
+   21291             :         float *work, 
+   21292             :         int *iwork, 
+   21293             :         int *info)
+   21294             : {
+   21295             :     int z_dim1, z_offset, i__1, i__2, i__3, i__4, i__5, i__6;
+   21296             :     float d__1, d__2;
+   21297           0 :     float c_b5 = 0.;
+   21298           0 :     int c__1 = 1;
+   21299           0 :     int c__2 = 2;
+   21300             : 
+   21301             :     int i__, j, k, p, q;
+   21302             :     int im, in;
+   21303             :     float gap, eps, tmp;
+   21304             :     int zto;
+   21305             :     float ztz;
+   21306             :     int iend, jblk;
+   21307             :     int wend, iter, temp[1], ktot;
+   21308             :     int itmp1, itmp2;
+   21309             :     int indld;
+   21310             :     float sigma;
+   21311             :     int ndone, iinfo, iindr;
+   21312             :     float resid;
+   21313             :     int nomgs;
+   21314             :     int nclus;
+   21315             :     int zfrom, iindc1, iindc2;
+   21316             :     float lambda;
+   21317             :     int ibegin;
+   21318             :     int indgap, indlld;
+   21319             :     float mingma;
+   21320             :     int oldien, oldncl, wbegin;
+   21321             :     float relgap;
+   21322             :     int oldcls;
+   21323             :     int ndepth, inderr, iindwk;
+   21324             :     int newcls, oldfst;
+   21325             :     float minrgp=0.0;
+   21326             :     int indwrk, oldlst;
+   21327             :     float reltol;
+   21328             :     int newfrs, newftt, parity;
+   21329             :     float mgstol, nrminv, rqcorr;
+   21330             :     int newlst, newsiz;
+   21331             : 
+   21332             : 
+   21333           0 :     --d__;
+   21334           0 :     --l;
+   21335             :     --isplit;
+   21336           0 :     --w;
+   21337           0 :     --iblock;
+   21338           0 :     --indexw;
+   21339             :     --gersch;
+   21340           0 :     z_dim1 = *ldz;
+   21341           0 :     z_offset = 1 + z_dim1;
+   21342           0 :     z__ -= z_offset;
+   21343           0 :     --isuppz;
+   21344           0 :     --work;
+   21345           0 :     --iwork;
+   21346             : 
+   21347           0 :     inderr = *n;
+   21348           0 :     indld = *n << 1;
+   21349           0 :     indlld = *n * 3;
+   21350           0 :     indgap = *n << 2;
+   21351           0 :     indwrk = *n * 5 + 1;
+   21352             : 
+   21353             :     iindr = *n;
+   21354             :     iindc1 = *n << 1;
+   21355             :     iindc2 = *n * 3;
+   21356           0 :     iindwk = (*n << 2) + 1;
+   21357             : 
+   21358             :     eps = PLUMED_GMX_FLOAT_EPS;
+   21359             : 
+   21360             :     i__1 = *n << 1;
+   21361           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21362           0 :         iwork[i__] = 0;
+   21363             :     }
+   21364           0 :     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("Full", n, m, &c_b5, &c_b5, &z__[z_offset], ldz);
+   21365             :     mgstol = eps * 100.;
+   21366             : 
+   21367             :     ibegin = 1;
+   21368             :     wbegin = 1;
+   21369           0 :     i__1 = iblock[*m];
+   21370           0 :     for (jblk = 1; jblk <= i__1; ++jblk) {
+   21371           0 :         iend = isplit[jblk];
+   21372             : 
+   21373           0 :         wend = wbegin - 1;
+   21374           0 : L171:
+   21375           0 :         if (wend < *m) {
+   21376           0 :             if (iblock[wend + 1] == jblk) {
+   21377           0 :                 ++wend;
+   21378           0 :                 goto L171;
+   21379             :             }
+   21380             :         }
+   21381           0 :         if (wend < wbegin) {
+   21382           0 :             ibegin = iend + 1;
+   21383           0 :             continue;
+   21384             :         }
+   21385             : 
+   21386           0 :         if (ibegin == iend) {
+   21387           0 :             z__[ibegin + wbegin * z_dim1] = 1.;
+   21388           0 :             isuppz[(wbegin << 1) - 1] = ibegin;
+   21389           0 :             isuppz[wbegin * 2] = ibegin;
+   21390           0 :             ibegin = iend + 1;
+   21391           0 :             wbegin = wend + 1;
+   21392           0 :             continue;
+   21393             :         }
+   21394           0 :         oldien = ibegin - 1;
+   21395           0 :         in = iend - oldien;
+   21396           0 :         d__1 = .001, d__2 = 1. / (float) in;
+   21397           0 :         reltol = (d__1<d__2) ? d__1 : d__2;
+   21398           0 :         im = wend - wbegin + 1;
+   21399           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&im, &w[wbegin], &c__1, &work[1], &c__1);
+   21400           0 :         i__2 = im - 1;
+   21401           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   21402           0 :             work[inderr + i__] = eps * std::abs(work[i__]);
+   21403           0 :             work[indgap + i__] = work[i__ + 1] - work[i__];
+   21404             :         }
+   21405           0 :         work[inderr + im] = eps * std::abs(work[im]);
+   21406           0 :         d__2 = std::abs(work[im]);
+   21407           0 :         work[indgap + im] = (d__2>eps) ? d__2 : eps;
+   21408             :         ndone = 0;
+   21409             : 
+   21410             :         ndepth = 0;
+   21411             :         parity = 1;
+   21412             :         nclus = 1;
+   21413           0 :         iwork[iindc1 + 1] = 1;
+   21414           0 :         iwork[iindc1 + 2] = im;
+   21415             : 
+   21416           0 : L40:
+   21417           0 :         if (ndone < im) {
+   21418             :             oldncl = nclus;
+   21419             :             nclus = 0;
+   21420           0 :             parity = 1 - parity;
+   21421           0 :             if (parity == 0) {
+   21422             :                 oldcls = iindc1;
+   21423             :                 newcls = iindc2;
+   21424             :             } else {
+   21425             :                 oldcls = iindc2;
+   21426             :                 newcls = iindc1;
+   21427             :             }
+   21428             :             i__2 = oldncl;
+   21429           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   21430             : 
+   21431           0 :                 j = oldcls + (i__ << 1);
+   21432           0 :                 oldfst = iwork[j - 1];
+   21433           0 :                 oldlst = iwork[j];
+   21434           0 :                 if (ndepth > 0) {
+   21435           0 :                     j = wbegin + oldfst - 1;
+   21436           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&in, &z__[ibegin + j * z_dim1], &c__1, &d__[ibegin]
+   21437             :                             , &c__1);
+   21438           0 :                     i__3 = in - 1;
+   21439           0 :                     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__3, &z__[ibegin + (j + 1) * z_dim1], &c__1, &l[
+   21440             :                             ibegin], &c__1);
+   21441           0 :                     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("Full", &in, &c__2, &c_b5, &c_b5, &z__[ibegin + j 
+   21442             :                             * z_dim1], ldz);
+   21443             :                 }
+   21444             :                 k = ibegin;
+   21445           0 :                 i__3 = in - 1;
+   21446           0 :                 for (j = 1; j <= i__3; ++j) {
+   21447           0 :                     tmp = d__[k] * l[k];
+   21448           0 :                     work[indld + j] = tmp;
+   21449           0 :                     work[indlld + j] = tmp * l[k];
+   21450           0 :                     ++k;
+   21451             :                 }
+   21452           0 :                 if (ndepth > 0) {
+   21453             : 
+   21454           0 :                     p = indexw[wbegin - 1 + oldfst];
+   21455           0 :                     q = indexw[wbegin - 1 + oldlst];
+   21456           0 :                     d__1 = eps * 4.;
+   21457           0 :                     i__3 = p - oldfst;
+   21458           0 :                     PLUMED_BLAS_F77_FUNC(slarrbx,SLARRBX)(&in, &d__[ibegin], &l[ibegin], &work[indld + 1], &
+   21459           0 :                             work[indlld + 1], &p, &q, &reltol, &d__1, &i__3, &
+   21460           0 :                             work[1], &work[indgap + 1], &work[inderr + 1], &
+   21461           0 :                             work[indwrk + in], &iwork[iindwk], &iinfo);
+   21462             :                 }
+   21463           0 :                 newfrs = oldfst;
+   21464           0 :                 i__3 = oldlst;
+   21465           0 :                 for (j = oldfst; j <= i__3; ++j) {
+   21466           0 :                     if (j == oldlst || work[indgap + j] >= 
+   21467           0 :                         reltol * std::abs(work[j])) {
+   21468           0 :                         newlst = j;
+   21469             :                     } else {
+   21470             : 
+   21471           0 :                         relgap = work[indgap + j] / std::abs(work[j]);
+   21472           0 :                         if (j == newfrs) {
+   21473             :                             minrgp = relgap;
+   21474             :                         } else {
+   21475           0 :                             minrgp = (minrgp<relgap) ? minrgp : relgap;
+   21476             :                         }
+   21477           0 :                         continue;
+   21478             :                     }
+   21479           0 :                     newsiz = newlst - newfrs + 1;
+   21480           0 :                     newftt = wbegin + newfrs - 1;
+   21481           0 :                     nomgs = newsiz == 1 || newsiz > 1 || minrgp < mgstol;
+   21482           0 :                     if (newsiz > 1 && nomgs) {
+   21483             : 
+   21484           0 :                         PLUMED_BLAS_F77_FUNC(slarrfx,SLARRFX)(&in, &d__[ibegin], &l[ibegin], &work[indld + 
+   21485           0 :                                 1], &work[indlld + 1], &newfrs, &newlst, &
+   21486           0 :                                 work[1], &sigma, &z__[ibegin + newftt * 
+   21487           0 :                                 z_dim1], &z__[ibegin + (newftt + 1) * z_dim1],
+   21488           0 :                                  &work[indwrk], info);
+   21489           0 :                         if (*info == 0) {
+   21490           0 :                             tmp = eps * std::abs(sigma);
+   21491           0 :                             i__4 = newlst;
+   21492           0 :                             for (k = newfrs; k <= i__4; ++k) {
+   21493           0 :                                 work[k] -= sigma;
+   21494           0 :                                 d__1 = work[indgap + k];
+   21495           0 :                                 work[indgap + k] = (d__1>tmp) ? d__1 : tmp;
+   21496           0 :                                 work[inderr + k] += tmp;
+   21497             :                             }
+   21498           0 :                             ++nclus;
+   21499           0 :                             k = newcls + (nclus << 1);
+   21500           0 :                             iwork[k - 1] = newfrs;
+   21501           0 :                             iwork[k] = newlst;
+   21502             :                         } else {
+   21503           0 :                             *info = 0;
+   21504           0 :                             if (minrgp < mgstol) {
+   21505             : 
+   21506           0 :                                 work[indwrk] = d__[ibegin];
+   21507           0 :                                 i__4 = in - 1;
+   21508           0 :                                 for (k = 1; k <= i__4; ++k) {
+   21509           0 :                                     work[indwrk + k] = d__[ibegin + k] + work[
+   21510           0 :                                             indlld + k];
+   21511             :                                 }
+   21512           0 :                                 i__4 = newsiz;
+   21513           0 :                                 for (k = 1; k <= i__4; ++k) {
+   21514           0 :                                     iwork[iindwk + k - 1] = 1;
+   21515             :                                 }
+   21516           0 :                                 i__4 = newlst;
+   21517           0 :                                 for (k = newfrs; k <= i__4; ++k) {
+   21518           0 :                                     isuppz[2*(oldien + k) - 1] = 1;
+   21519           0 :                                     isuppz[(oldien + k) * 2] = in;
+   21520             :                                 }
+   21521           0 :                                 temp[0] = in;
+   21522           0 :                                 PLUMED_BLAS_F77_FUNC(sstein,SSTEIN)(&in, &work[indwrk], &work[indld + 1], 
+   21523           0 :                                         &newsiz, &work[newfrs], &iwork[iindwk]
+   21524             :                                         , temp, &z__[ibegin + newftt * z_dim1]
+   21525           0 :                                         , ldz, &work[indwrk + in], &iwork[
+   21526           0 :                                         iindwk + in], &iwork[iindwk + (in*2)], &iinfo);
+   21527           0 :                                 if (iinfo != 0) {
+   21528           0 :                                     *info = 2;
+   21529           0 :                                     return;
+   21530             :                                 }
+   21531           0 :                                 ndone += newsiz;
+   21532             :                             }
+   21533             :                         }
+   21534             :                     } else {
+   21535             :                         ktot = newftt;
+   21536             :                         i__4 = newlst;
+   21537           0 :                         for (k = newfrs; k <= i__4; ++k) {
+   21538             :                             iter = 0;
+   21539           0 : L90:
+   21540           0 :                             lambda = work[k];
+   21541             : 
+   21542           0 :                             PLUMED_BLAS_F77_FUNC(slar1vx,SLAR1VX)(&in, &c__1, &in, &lambda, &d__[ibegin], &
+   21543           0 :                                     l[ibegin], &work[indld + 1], &work[indlld 
+   21544           0 :                                     + 1], &w[wbegin + k - 1], &gersch[(oldien 
+   21545           0 :                                     << 1) + 1], &z__[ibegin + ktot * z_dim1], 
+   21546           0 :                                     &ztz, &mingma, &iwork[iindr + ktot], &
+   21547           0 :                                     isuppz[(ktot << 1) - 1], &work[indwrk]);
+   21548           0 :                             tmp = 1. / ztz;
+   21549           0 :                             nrminv =  std::sqrt(tmp);
+   21550           0 :                             resid = std::abs(mingma) * nrminv;
+   21551           0 :                             rqcorr = mingma * tmp;
+   21552           0 :                             if (k == in) {
+   21553           0 :                                 gap = work[indgap + k - 1];
+   21554           0 :                             } else if (k == 1) {
+   21555           0 :                                 gap = work[indgap + k];
+   21556             :                             } else {
+   21557           0 :                                 d__1 = work[indgap + k - 1], d__2 = work[
+   21558           0 :                                         indgap + k];
+   21559           0 :                                 gap = (d__1<d__2) ? d__1 : d__2;
+   21560             :                             }
+   21561           0 :                             ++iter;
+   21562           0 :                             if (resid > *tol * gap && std::abs(rqcorr) > eps * 4. *
+   21563           0 :                                      std::abs(lambda)) {
+   21564           0 :                                 work[k] = lambda + rqcorr;
+   21565           0 :                                 if (iter < 8) {
+   21566           0 :                                     goto L90;
+   21567             :                                 }
+   21568             :                             }
+   21569           0 :                             iwork[ktot] = 1;
+   21570           0 :                             if (newsiz == 1) {
+   21571           0 :                                 ++ndone;
+   21572             :                             }
+   21573           0 :                             zfrom = isuppz[(ktot << 1) - 1];
+   21574           0 :                             zto = isuppz[ktot * 2];
+   21575           0 :                             i__5 = zto - zfrom + 1;
+   21576           0 :                             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__5, &nrminv, &z__[ibegin + zfrom - 1 + 
+   21577           0 :                                     ktot * z_dim1], &c__1);
+   21578           0 :                             ++ktot;
+   21579             :                         }
+   21580           0 :                         if (newsiz > 1) {
+   21581           0 :                             itmp1 = isuppz[(newftt << 1) - 1];
+   21582           0 :                             itmp2 = isuppz[newftt * 2];
+   21583           0 :                             ktot = oldien + newlst;
+   21584             :                             i__4 = ktot;
+   21585           0 :                             for (p = newftt + 1; p <= i__4; ++p) {
+   21586           0 :                                 i__5 = p - 1;
+   21587           0 :                                 for (q = newftt; q <= i__5; ++q) {
+   21588           0 :                                     tmp = -PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&in, &z__[ibegin + p * 
+   21589           0 :                                             z_dim1], &c__1, &z__[ibegin + q * 
+   21590           0 :                                             z_dim1], &c__1);
+   21591           0 :                                     PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&in, &tmp, &z__[ibegin + q * 
+   21592           0 :                                             z_dim1], &c__1, &z__[ibegin + p * 
+   21593           0 :                                             z_dim1], &c__1);
+   21594             :                                 }
+   21595           0 :                                 tmp = 1. / PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&in, &z__[ibegin + p * 
+   21596           0 :                                         z_dim1], &c__1);
+   21597           0 :                                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&in, &tmp, &z__[ibegin + p * z_dim1], &
+   21598             :                                         c__1);
+   21599           0 :                                 i__5 = itmp1, i__6 = isuppz[(p << 1) - 1];
+   21600             :                                 itmp1 = (i__5<i__6) ? i__5 : i__6;
+   21601           0 :                                 i__5 = itmp2, i__6 = isuppz[p * 2];
+   21602             :                                 itmp2 = (i__5>i__6) ? i__5 : i__6;
+   21603             :                             }
+   21604             :                             i__4 = ktot;
+   21605           0 :                             for (p = newftt; p <= i__4; ++p) {
+   21606           0 :                                 isuppz[(p << 1) - 1] = itmp1;
+   21607           0 :                                 isuppz[p * 2] = itmp2;
+   21608             :                             }
+   21609           0 :                             ndone += newsiz;
+   21610             :                         }
+   21611             :                     }
+   21612           0 :                     newfrs = j + 1;
+   21613             :                 }
+   21614             :             }
+   21615           0 :             ++ndepth;
+   21616           0 :             goto L40;
+   21617             :         }
+   21618           0 :         j = wbegin << 1;
+   21619             :         i__2 = wend;
+   21620           0 :         for (i__ = wbegin; i__ <= i__2; ++i__) {
+   21621           0 :             isuppz[j - 1] += oldien;
+   21622           0 :             isuppz[j] += oldien;
+   21623           0 :             j += 2;
+   21624             : 
+   21625             :         }
+   21626           0 :         ibegin = iend + 1;
+   21627           0 :         wbegin = wend + 1;
+   21628             :     }
+   21629             : 
+   21630             :     return;
+   21631             : 
+   21632             : } 
+   21633             : }
+   21634             : }
+   21635             : #include <cmath>
+   21636             : #include "lapack.h"
+   21637             : #include "lapack_limits.h"
+   21638             : 
+   21639             : #include "real.h"
+   21640             : 
+   21641             : #include "blas/blas.h"
+   21642             : namespace PLMD{
+   21643             : namespace lapack{
+   21644             : using namespace blas;
+   21645             : void
+   21646           0 : PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(float *f,
+   21647             :         float *g,
+   21648             :         float *cs,
+   21649             :         float *sn,
+   21650             :         float *r)
+   21651             : {
+   21652             :   float minval,safemin, safemin2, safemx2, eps;
+   21653             :   float f1,g1,f1a,g1a,scale;
+   21654             :   int i,n,count;
+   21655             : 
+   21656             :   eps = PLUMED_GMX_FLOAT_EPS;
+   21657             :   minval = PLUMED_GMX_FLOAT_MIN;
+   21658             :   safemin = minval*(1.0+eps);
+   21659             :   n = static_cast<int>(0.5*std::log( safemin/eps ) / std::log(2.0));
+   21660             :   safemin2 = std::pow(static_cast<float>(2.0),static_cast<float>(n));
+   21661             : 
+   21662             :   safemx2 = 1.0 / safemin2;
+   21663             : 
+   21664           0 :   if(std::abs(*g)<PLUMED_GMX_FLOAT_MIN) {
+   21665           0 :     *cs = 1.0;
+   21666           0 :     *sn = 0.0;
+   21667           0 :     *r = *f;
+   21668           0 :   } else if (std::abs(*f)<PLUMED_GMX_FLOAT_MIN) {
+   21669           0 :     *cs = 0.0;
+   21670           0 :     *sn = 1.0;
+   21671           0 :     *r = *g;
+   21672             :   } else {
+   21673             :     f1 = *f;
+   21674             :     g1 = *g;
+   21675             :     f1a = std::abs(f1);
+   21676             :     g1a = std::abs(g1);
+   21677           0 :     scale = (f1a > g1a) ? f1a : g1a;
+   21678           0 :     if(scale >= safemx2) {
+   21679             :       count = 0;
+   21680           0 :       while(scale >= safemx2) {
+   21681           0 :         count++;
+   21682           0 :         f1 *= safemin2;
+   21683           0 :         g1 *= safemin2;
+   21684             :         f1a = std::abs(f1);
+   21685             :         g1a = std::abs(g1);
+   21686           0 :         scale = (f1a > g1a) ? f1a : g1a;
+   21687             :       }
+   21688           0 :       *r =  std::sqrt(f1*f1 + g1*g1);
+   21689           0 :       *cs = f1 / *r;
+   21690           0 :       *sn = g1 / *r;
+   21691           0 :       for(i=0;i<count;i++)
+   21692           0 :         *r *= safemx2;
+   21693           0 :     } else if (scale<=safemin2) {
+   21694             :       count = 0;
+   21695           0 :       while(scale <= safemin2) {
+   21696           0 :         count++;
+   21697           0 :         f1 *= safemx2;
+   21698           0 :         g1 *= safemx2;
+   21699             :         f1a = std::abs(f1);
+   21700             :         g1a = std::abs(g1);
+   21701           0 :         scale = (f1a > g1a) ? f1a : g1a;
+   21702             :       }
+   21703           0 :       *r =  std::sqrt(f1*f1 + g1*g1);
+   21704           0 :       *cs = f1 / *r;
+   21705           0 :       *sn = g1 / *r;
+   21706           0 :       for(i=0;i<count;i++)
+   21707           0 :         *r *= safemin2;
+   21708             :     } else {
+   21709           0 :       *r =  std::sqrt(f1*f1 + g1*g1);
+   21710           0 :       *cs = f1 / *r;
+   21711           0 :       *sn = g1 / *r;
+   21712             :     }
+   21713           0 :     if(std::abs(*f)>std::abs(*g) && *cs<0.0) {
+   21714           0 :       *cs *= -1.0;
+   21715           0 :       *sn *= -1.0;
+   21716           0 :       *r  *= -1.0;
+   21717             :     }
+   21718             :   }
+   21719           0 :   return;
+   21720             : }
+   21721             :       
+   21722             : }
+   21723             : }
+   21724             : #include <cmath>
+   21725             : #include "lapack.h"
+   21726             : 
+   21727             : #include "blas/blas.h"
+   21728             : namespace PLMD{
+   21729             : namespace lapack{
+   21730             : using namespace blas;
+   21731             : void
+   21732           0 : PLUMED_BLAS_F77_FUNC(slaruv,SLARUV)(int *iseed, int *n, float *x)
+   21733             : {
+   21734             :   const int
+   21735           0 :     mm[512] = {
+   21736             :       494,2637,255,2008,1253,
+   21737             :       3344,4084,1739,3143,3468,688,1657,1238,3166,1292,3422,1270,2016,
+   21738             :       154,2862,697,1706,491,931,1444,444,3577,3944,2184,1661,3482,657,
+   21739             :       3023,3618,1267,1828,164,3798,3087,2400,2870,3876,1905,1593,1797,
+   21740             :       1234,3460,328,2861,1950,617,2070,3331,769,1558,2412,2800,189,287,
+   21741             :       2045,1227,2838,209,2770,3654,3993,192,2253,3491,2889,2857,2094,
+   21742             :       1818,688,1407,634,3231,815,3524,1914,516,164,303,2144,3480,119,
+   21743             :       3357,837,2826,2332,2089,3780,1700,3712,150,2000,3375,1621,3090,
+   21744             :       3765,1149,3146,33,3082,2741,359,3316,1749,185,2784,2202,2199,1364,
+   21745             :       1244,2020,3160,2785,2772,1217,1822,1245,2252,3904,2774,997,2573,
+   21746             :       1148,545,322,789,1440,752,2859,123,1848,643,2405,2638,2344,46,
+   21747             :       3814,913,3649,339,3808,822,2832,3078,3633,2970,637,2249,2081,4019,
+   21748             :       1478,242,481,2075,4058,622,3376,812,234,641,4005,1122,3135,2640,
+   21749             :       2302,40,1832,2247,2034,2637,1287,1691,496,1597,2394,2584,1843,336,
+   21750             :       1472,2407,433,2096,1761,2810,566,442,41,1238,1086,603,840,3168,
+   21751             :       1499,1084,3438,2408,1589,2391,288,26,512,1456,171,1677,2657,2270,
+   21752             :       2587,2961,1970,1817,676,1410,3723,2803,3185,184,663,499,3784,1631,
+   21753             :       1925,3912,1398,1349,1441,2224,2411,1907,3192,2786,382,37,759,2948,
+   21754             :       1862,3802,2423,2051,2295,1332,1832,2405,3638,3661,327,3660,716,
+   21755             :       1842,3987,1368,1848,2366,2508,3754,1766,3572,2893,307,1297,3966,
+   21756             :       758,2598,3406,2922,1038,2934,2091,2451,1580,1958,2055,1507,1078,
+   21757             :       3273,17,854,2916,3971,2889,3831,2621,1541,893,736,3992,787,2125,
+   21758             :       2364,2460,257,1574,3912,1216,3248,3401,2124,2762,149,2245,166,466,
+   21759             :       4018,1399,190,2879,153,2320,18,712,2159,2318,2091,3443,1510,449,
+   21760             :       1956,2201,3137,3399,1321,2271,3667,2703,629,2365,2431,1113,3922,
+   21761             :       2554,184,2099,3228,4012,1921,3452,3901,572,3309,3171,817,3039,
+   21762             :       1696,1256,3715,2077,3019,1497,1101,717,51,981,1978,1813,3881,76,
+   21763             :       3846,3694,1682,124,1660,3997,479,1141,886,3514,1301,3604,1888,
+   21764             :       1836,1990,2058,692,1194,20,3285,2046,2107,3508,3525,3801,2549,
+   21765             :       1145,2253,305,3301,1065,3133,2913,3285,1241,1197,3729,2501,1673,
+   21766             :       541,2753,949,2361,1165,4081,2725,3305,3069,3617,3733,409,2157,
+   21767             :       1361,3973,1865,2525,1409,3445,3577,77,3761,2149,1449,3005,225,85,
+   21768             :       3673,3117,3089,1349,2057,413,65,1845,697,3085,3441,1573,3689,2941,
+   21769             :       929,533,2841,4077,721,2821,2249,2397,2817,245,1913,1997,3121,997,
+   21770             :       1833,2877,1633,981,2009,941,2449,197,2441,285,1473,2741,3129,909,
+   21771             :       2801,421,4073,2813,2337,1429,1177,1901,81,1669,2633,2269,129,1141,
+   21772             :       249,3917,2481,3941,2217,2749,3041,1877,345,2861,1809,3141,2825,
+   21773             :       157,2881,3637,1465,2829,2161,3365,361,2685,3745,2325,3609,3821,
+   21774             :       3537,517,3017,2141,1537 
+   21775             :     };
+   21776             : 
+   21777             :     int i__1;
+   21778             : 
+   21779             :     int i__, i1, i2, i3, i4, it1, it2, it3, it4;
+   21780             : 
+   21781             : 
+   21782             :     --iseed;
+   21783             :     --x;
+   21784             : 
+   21785             :     it1 = it2 = it3 = it4 = 0;
+   21786             : 
+   21787           0 :     i1 = iseed[1];
+   21788           0 :     i2 = iseed[2];
+   21789           0 :     i3 = iseed[3];
+   21790           0 :     i4 = iseed[4];
+   21791             : 
+   21792           0 :     i__1 = (*n<128) ? *n : 128;
+   21793           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   21794             : 
+   21795           0 :         it4 = i4 * mm[i__ + 383];
+   21796           0 :         it3 = it4 / 4096;
+   21797           0 :         it4 -= it3 << 12;
+   21798           0 :         it3 = it3 + i3 * mm[i__ + 383] + i4 * mm[i__ + 255];
+   21799           0 :         it2 = it3 / 4096;
+   21800           0 :         it3 -= it2 << 12;
+   21801           0 :         it2 = it2 + i2 * mm[i__ + 383] + i3 * mm[i__ + 255] + 
+   21802           0 :           i4 * mm[i__ + 127];
+   21803           0 :         it1 = it2 / 4096;
+   21804           0 :         it2 -= it1 << 12;
+   21805           0 :         it1 = it1 + i1 * mm[i__ + 383] + i2 * mm[i__ + 255] + 
+   21806           0 :           i3 * mm[i__ + 127] + i4 * mm[i__ - 1];
+   21807           0 :         it1 %= 4096;
+   21808             : 
+   21809           0 :         x[i__] = ((float) it1 + ((float) it2 + ((float) it3 + (
+   21810           0 :                 float) it4 * 2.44140625e-4) * 2.44140625e-4) * 
+   21811           0 :                 2.44140625e-4) * 2.44140625e-4;
+   21812             :     }
+   21813             : 
+   21814           0 :     iseed[1] = it1;
+   21815           0 :     iseed[2] = it2;
+   21816           0 :     iseed[3] = it3;
+   21817           0 :     iseed[4] = it4;
+   21818           0 :     return;
+   21819             : 
+   21820             : } 
+   21821             : }
+   21822             : }
+   21823             : #include <cmath>
+   21824             : #include "real.h"
+   21825             : 
+   21826             : #include "lapack.h"
+   21827             : 
+   21828             : #include "blas/blas.h"
+   21829             : namespace PLMD{
+   21830             : namespace lapack{
+   21831             : using namespace blas;
+   21832             : void
+   21833           0 : PLUMED_BLAS_F77_FUNC(slas2,SLAS2)(float *f,
+   21834             :        float *g,
+   21835             :        float *h,
+   21836             :        float *ssmin,
+   21837             :        float *ssmax)
+   21838             : {
+   21839           0 :   float fa = std::abs(*f);
+   21840           0 :   float ga = std::abs(*g);
+   21841           0 :   float ha = std::abs(*h);
+   21842             :   float fhmin,fhmax,tmax,tmin,tmp1,tmp2;
+   21843             :   float as,at,au,c;
+   21844             : 
+   21845           0 :   fhmin = (fa<ha) ? fa : ha;
+   21846           0 :   fhmax = (fa>ha) ? fa : ha;
+   21847             :   
+   21848           0 :   if(std::abs(fhmin)<PLUMED_GMX_FLOAT_MIN) {
+   21849           0 :     *ssmin = 0.0;
+   21850           0 :     if(std::abs(fhmax)<PLUMED_GMX_FLOAT_MIN) 
+   21851           0 :       *ssmax = ga;
+   21852             :     else {
+   21853           0 :       tmax = (fhmax>ga) ? fhmax : ga;
+   21854           0 :       tmin = (fhmax<ga) ? fhmax : ga;
+   21855           0 :       tmp1 = tmin / tmax;
+   21856           0 :       tmp1 = tmp1 * tmp1;
+   21857           0 :       *ssmax = tmax* std::sqrt(1.0 + tmp1);
+   21858             :     }
+   21859             :   } else {
+   21860           0 :     if(ga<fhmax) {
+   21861           0 :       as = 1.0 + fhmin / fhmax;
+   21862           0 :       at = (fhmax-fhmin) / fhmax;
+   21863           0 :       au = (ga/fhmax);
+   21864           0 :       au = au * au;
+   21865           0 :       c = 2.0 / (  std::sqrt(as*as+au) + std::sqrt(at*at+au) );
+   21866           0 :       *ssmin = fhmin * c;
+   21867           0 :       *ssmax = fhmax / c;
+   21868             :     } else {
+   21869           0 :       au = fhmax / ga;
+   21870           0 :       if(std::abs(au)<PLUMED_GMX_FLOAT_MIN) {
+   21871           0 :         *ssmin = (fhmin*fhmax)/ga;
+   21872           0 :         *ssmax = ga;
+   21873             :       } else {
+   21874           0 :         as = 1.0 + fhmin / fhmax;
+   21875           0 :         at = (fhmax-fhmin)/fhmax;
+   21876           0 :         tmp1 = as*au;
+   21877           0 :         tmp2 = at*au;
+   21878           0 :         c = 1.0 / (  std::sqrt(1.0+tmp1*tmp1) + std::sqrt(1.0+tmp2*tmp2));
+   21879           0 :         *ssmin = (fhmin*c)*au;
+   21880           0 :         *ssmin = *ssmin + *ssmin;
+   21881           0 :         *ssmax = ga / (c+c);
+   21882             :       }
+   21883             :     }
+   21884             :   }
+   21885           0 :   return;
+   21886             : }
+   21887             : }
+   21888             : }
+   21889             : #include <cctype>
+   21890             : #include <cmath>
+   21891             : #include "real.h"
+   21892             : 
+   21893             : #include "lapack.h"
+   21894             : #include "lapack_limits.h"
+   21895             : 
+   21896             : 
+   21897             : #include "blas/blas.h"
+   21898             : namespace PLMD{
+   21899             : namespace lapack{
+   21900             : using namespace blas;
+   21901             : void
+   21902           0 : PLUMED_BLAS_F77_FUNC(slascl,SLASCL)(const char *type,
+   21903             :                         int *kl,
+   21904             :                         int *ku,
+   21905             :                         float *cfrom,
+   21906             :                         float *cto,
+   21907             :                         int *m,
+   21908             :                         int *n,
+   21909             :                         float *a,
+   21910             :                         int *lda,
+   21911             :                         int *info)
+   21912             : {
+   21913           0 :   const char ch=std::toupper(*type);
+   21914             :   int i,j,k,l,k1,k2,k3,k4;
+   21915             :   int done=0;
+   21916             :   float minval,smlnum,bignum;
+   21917             :   float cfromc, ctoc, cfrom1, cto1, mul;
+   21918             : 
+   21919           0 :   if(*n<=0 || *m<=0)
+   21920             :     return;
+   21921             : 
+   21922             :   minval = PLUMED_GMX_FLOAT_MIN;
+   21923             :   smlnum = minval / PLUMED_GMX_FLOAT_EPS;
+   21924             :   bignum = 1.0 / smlnum;
+   21925             : 
+   21926           0 :   cfromc = *cfrom;
+   21927           0 :   ctoc   = *cto;
+   21928             : 
+   21929           0 :   while(!done) {
+   21930             :     
+   21931           0 :     cfrom1 = cfromc * smlnum;
+   21932           0 :     cto1   = ctoc / bignum;
+   21933             : 
+   21934           0 :     if(std::abs(cfrom1)>std::abs(ctoc) && std::abs(ctoc)>PLUMED_GMX_FLOAT_MIN) {
+   21935             :       mul = smlnum;
+   21936             :       done = 0;
+   21937             :       cfromc = cfrom1;
+   21938           0 :     } else if(std::abs(cto1)>std::abs(cfromc)) {
+   21939             :       mul = bignum;
+   21940             :       done = 0;
+   21941             :       ctoc = cto1;
+   21942             :     } else {
+   21943           0 :       mul = ctoc / cfromc;
+   21944             :       done = 1;
+   21945             :     }
+   21946             : 
+   21947           0 :     switch(ch) {
+   21948             :     case 'G': 
+   21949             :       /* Full matrix */
+   21950           0 :       for(j=0;j<*n;j++)
+   21951           0 :         for(i=0;i<*m;i++)
+   21952           0 :           a[j*(*lda)+i] *= mul;
+   21953             :       break;
+   21954             : 
+   21955             :     case 'L': 
+   21956             :       /* Lower triangular matrix */
+   21957           0 :       for(j=0;j<*n;j++)
+   21958           0 :         for(i=j;i<*m;i++)
+   21959           0 :           a[j*(*lda)+i] *= mul;
+   21960             :       break;
+   21961             : 
+   21962             :     case 'U': 
+   21963             :       /* Upper triangular matrix */
+   21964           0 :       for(j=0;j<*n;j++) {
+   21965           0 :         k = (j < (*m-1)) ? j : (*m-1);
+   21966           0 :         for(i=0;i<=k;i++)
+   21967           0 :           a[j*(*lda)+i] *= mul;
+   21968             :       }
+   21969             :       break;
+   21970             : 
+   21971             :     case 'H': 
+   21972             :       /* Upper Hessenberg matrix */
+   21973           0 :       for(j=0;j<*n;j++) {
+   21974           0 :         k = ((j+1) < (*m-1)) ? (j+1) : (*m-1);
+   21975           0 :         for(i=0;i<=k;i++)
+   21976           0 :           a[j*(*lda)+i] *= mul;
+   21977             :       }
+   21978             :       break;
+   21979             : 
+   21980           0 :     case 'B': 
+   21981             :       /* Symmetric band matrix, lower bandwidth KL, upper KU,
+   21982             :        * only the lower half stored.
+   21983             :        */
+   21984           0 :       k3 = *kl;
+   21985           0 :       k4 = *n - 1;
+   21986           0 :       for(j=0;j<*n;j++) {
+   21987           0 :         k = (k3 < (k4-j)) ? k3 : (k4-j);
+   21988           0 :         for(i=0;i<=k;i++)
+   21989           0 :           a[j*(*lda)+i] *= mul;
+   21990             :       }
+   21991             :       break;
+   21992             : 
+   21993           0 :     case 'Q': 
+   21994             :       /* Symmetric band matrix, lower bandwidth KL, upper KU,
+   21995             :        * only the upper half stored.
+   21996             :        */
+   21997           0 :       k1 = *ku;
+   21998             :       k3 = *ku;
+   21999           0 :       for(j=0;j<*n;j++) {
+   22000           0 :         k = ((k1-j) > 0) ? (k1-j) : 0;
+   22001           0 :         for(i=k;i<=k3;i++)
+   22002           0 :           a[j*(*lda)+i] *= mul;
+   22003             :       }
+   22004             :       break;
+   22005             : 
+   22006           0 :     case 'Z': 
+   22007             :       /* Band matrix, lower bandwidth KL, upper KU. */
+   22008             : 
+   22009           0 :       k1 = *kl + *ku;
+   22010             :       k2 = *kl;
+   22011           0 :       k3 = 2*(*kl) + *ku;
+   22012           0 :       k4 = *kl + *ku - 1 + *m;
+   22013           0 :       for(j=0;j<*n;j++) {
+   22014           0 :         k = ((k1-j) > k2) ? (k1-j) : k2;
+   22015           0 :         l = (k3 < (k4-j)) ? k3 : (k4-j);
+   22016           0 :         for(i=k;i<=l;i++)
+   22017           0 :           a[j*(*lda)+i] *= mul;
+   22018             :       }
+   22019             :       break;
+   22020             : 
+   22021           0 :     default:
+   22022           0 :       *info = -1;
+   22023           0 :       return;
+   22024             :     }
+   22025             :   } /* finished */
+   22026             : 
+   22027           0 :   *info = 0;
+   22028           0 :   return;
+   22029             : }
+   22030             : }
+   22031             : }
+   22032             : #include "lapack.h"
+   22033             : 
+   22034             : #include "blas/blas.h"
+   22035             : namespace PLMD{
+   22036             : namespace lapack{
+   22037             : using namespace blas;
+   22038             : void 
+   22039           0 : PLUMED_BLAS_F77_FUNC(slasd0,SLASD0)(int *n, 
+   22040             :         int *sqre, 
+   22041             :         float *d__, 
+   22042             :         float *e, 
+   22043             :         float *u, 
+   22044             :         int *ldu, 
+   22045             :         float *vt, 
+   22046             :         int *ldvt,
+   22047             :         int *smlsiz, 
+   22048             :         int *iwork,
+   22049             :         float *work, 
+   22050             :         int *info)
+   22051             : {
+   22052             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1, i__2;
+   22053             : 
+   22054             :     int i__, j, m, i1, ic, lf, nd, ll, nl, nr, im1, ncc, nlf, nrf, 
+   22055             :             iwk, lvl, ndb1, nlp1, nrp1;
+   22056             :     float beta;
+   22057             :     int idxq, nlvl;
+   22058             :     float alpha;
+   22059             :     int inode, ndiml, idxqc, ndimr, itemp, sqrei;
+   22060           0 :     int c__0 = 0;
+   22061             : 
+   22062             : 
+   22063           0 :     --d__;
+   22064           0 :     --e;
+   22065           0 :     u_dim1 = *ldu;
+   22066           0 :     u_offset = 1 + u_dim1;
+   22067           0 :     u -= u_offset;
+   22068           0 :     vt_dim1 = *ldvt;
+   22069           0 :     vt_offset = 1 + vt_dim1;
+   22070           0 :     vt -= vt_offset;
+   22071           0 :     --iwork;
+   22072             :     --work;
+   22073             : 
+   22074           0 :     *info = 0;
+   22075             : 
+   22076           0 :     if (*n < 0) {
+   22077           0 :         *info = -1;
+   22078           0 :     } else if (*sqre < 0 || *sqre > 1) {
+   22079           0 :         *info = -2;
+   22080             :     }
+   22081             : 
+   22082           0 :     m = *n + *sqre;
+   22083             : 
+   22084           0 :     if (*ldu < *n) {
+   22085           0 :         *info = -6;
+   22086           0 :     } else if (*ldvt < m) {
+   22087           0 :         *info = -8;
+   22088           0 :     } else if (*smlsiz < 3) {
+   22089           0 :         *info = -9;
+   22090             :     }
+   22091           0 :     if (*info != 0) {
+   22092             :         return;
+   22093             :     }
+   22094             : 
+   22095           0 :     if (*n <= *smlsiz) {
+   22096           0 :         PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", sqre, n, &m, n, &c__0, &d__[1], &e[1], &vt[vt_offset], 
+   22097             :                 ldvt, &u[u_offset], ldu, &u[u_offset], ldu, &work[1], info);
+   22098           0 :         return;
+   22099             :     }
+   22100             : 
+   22101             :     inode = 1;
+   22102           0 :     ndiml = inode + *n;
+   22103           0 :     ndimr = ndiml + *n;
+   22104           0 :     idxq = ndimr + *n;
+   22105           0 :     iwk = idxq + *n;
+   22106           0 :     PLUMED_BLAS_F77_FUNC(slasdt,SLASDT)(n, &nlvl, &nd, &iwork[inode], &iwork[ndiml], &iwork[ndimr], 
+   22107             :             smlsiz);
+   22108             : 
+   22109           0 :     ndb1 = (nd + 1) / 2;
+   22110           0 :     ncc = 0;
+   22111             :     i__1 = nd;
+   22112           0 :     for (i__ = ndb1; i__ <= i__1; ++i__) {
+   22113             : 
+   22114           0 :         i1 = i__ - 1;
+   22115           0 :         ic = iwork[inode + i1];
+   22116           0 :         nl = iwork[ndiml + i1];
+   22117           0 :         nlp1 = nl + 1;
+   22118           0 :         nr = iwork[ndimr + i1];
+   22119           0 :         nrp1 = nr + 1;
+   22120           0 :         nlf = ic - nl;
+   22121           0 :         nrf = ic + 1;
+   22122           0 :         sqrei = 1;
+   22123           0 :         PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nl, &nlp1, &nl, &ncc, &d__[nlf], &e[nlf], &vt[
+   22124           0 :                 nlf + nlf * vt_dim1], ldvt, &u[nlf + nlf * u_dim1], ldu, &u[
+   22125           0 :                 nlf + nlf * u_dim1], ldu, &work[1], info);
+   22126           0 :         if (*info != 0) {
+   22127             :             return;
+   22128             :         }
+   22129           0 :         itemp = idxq + nlf - 2;
+   22130           0 :         i__2 = nl;
+   22131           0 :         for (j = 1; j <= i__2; ++j) {
+   22132           0 :             iwork[itemp + j] = j;
+   22133             :         }
+   22134           0 :         if (i__ == nd) {
+   22135           0 :             sqrei = *sqre;
+   22136             :         } else {
+   22137           0 :             sqrei = 1;
+   22138             :         }
+   22139           0 :         nrp1 = nr + sqrei;
+   22140           0 :         PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nr, &nrp1, &nr, &ncc, &d__[nrf], &e[nrf], &vt[
+   22141           0 :                 nrf + nrf * vt_dim1], ldvt, &u[nrf + nrf * u_dim1], ldu, &u[
+   22142           0 :                 nrf + nrf * u_dim1], ldu, &work[1], info);
+   22143           0 :         if (*info != 0) {
+   22144             :             return;
+   22145             :         }
+   22146           0 :         itemp = idxq + ic;
+   22147           0 :         i__2 = nr;
+   22148           0 :         for (j = 1; j <= i__2; ++j) {
+   22149           0 :             iwork[itemp + j - 1] = j;
+   22150             :         }
+   22151             :     }
+   22152             : 
+   22153           0 :     for (lvl = nlvl; lvl >= 1; --lvl) {
+   22154             : 
+   22155           0 :         if (lvl == 1) {
+   22156             :             lf = 1;
+   22157             :             ll = 1;
+   22158             :         } else {
+   22159           0 :             i__1 = lvl - 1;
+   22160           0 :             lf = (1 << i__1);
+   22161           0 :             ll = (lf << 1) - 1;
+   22162             :         }
+   22163             :         i__1 = ll;
+   22164           0 :         for (i__ = lf; i__ <= i__1; ++i__) {
+   22165           0 :             im1 = i__ - 1;
+   22166           0 :             ic = iwork[inode + im1];
+   22167           0 :             nl = iwork[ndiml + im1];
+   22168           0 :             nr = iwork[ndimr + im1];
+   22169           0 :             nlf = ic - nl;
+   22170           0 :             if (*sqre == 0 && i__ == ll) {
+   22171           0 :                 sqrei = *sqre;
+   22172             :             } else {
+   22173           0 :                 sqrei = 1;
+   22174             :             }
+   22175           0 :             idxqc = idxq + nlf - 1;
+   22176           0 :             alpha = d__[ic];
+   22177           0 :             beta = e[ic];
+   22178           0 :             PLUMED_BLAS_F77_FUNC(slasd1,SLASD1)(&nl, &nr, &sqrei, &d__[nlf], &alpha, &beta, &u[nlf + nlf *
+   22179           0 :                      u_dim1], ldu, &vt[nlf + nlf * vt_dim1], ldvt, &iwork[
+   22180           0 :                     idxqc], &iwork[iwk], &work[1], info);
+   22181           0 :             if (*info != 0) {
+   22182             :                 return;
+   22183             :             }
+   22184             :         }
+   22185             :     }
+   22186             : 
+   22187             :     return;
+   22188             : 
+   22189             : }
+   22190             : }
+   22191             : }
+   22192             : #include <cmath>
+   22193             : #include "lapack.h"
+   22194             : 
+   22195             : #include "blas/blas.h"
+   22196             : namespace PLMD{
+   22197             : namespace lapack{
+   22198             : using namespace blas;
+   22199             : void 
+   22200           0 : PLUMED_BLAS_F77_FUNC(slasd1,SLASD1)(int *nl, 
+   22201             :         int *nr, 
+   22202             :         int *sqre, 
+   22203             :         float *d__, 
+   22204             :         float *alpha, 
+   22205             :         float *beta, 
+   22206             :         float *u, 
+   22207             :         int *ldu, 
+   22208             :         float *vt, 
+   22209             :         int *ldvt, 
+   22210             :         int *idxq, 
+   22211             :         int *iwork, 
+   22212             :         float *work, 
+   22213             :         int *info)
+   22214             : {
+   22215             :     int u_dim1, u_offset, vt_dim1, vt_offset, i__1;
+   22216             :     float d__1, d__2;
+   22217             : 
+   22218             :     int i__, k, m, n, n1, n2, iq, iz, iu2, ldq, idx, ldu2, ivt2, 
+   22219             :             idxc, idxp, ldvt2;
+   22220             :     int isigma;
+   22221             :     float orgnrm;
+   22222             :     int coltyp;
+   22223           0 :     int c__0 = 0;
+   22224           0 :     float one = 1.0;
+   22225           0 :     int c__1 = 1;
+   22226           0 :     int c_n1 = -1;
+   22227             : 
+   22228           0 :     --d__;
+   22229             :     u_dim1 = *ldu;
+   22230             :     u_offset = 1 + u_dim1;
+   22231             :     u -= u_offset;
+   22232             :     vt_dim1 = *ldvt;
+   22233             :     vt_offset = 1 + vt_dim1;
+   22234             :     vt -= vt_offset;
+   22235             :     --idxq;
+   22236           0 :     --iwork;
+   22237           0 :     --work;
+   22238             : 
+   22239           0 :     *info = 0;
+   22240             : 
+   22241           0 :     if (*nl < 1) {
+   22242           0 :         *info = -1;
+   22243           0 :     } else if (*nr < 1) {
+   22244           0 :         *info = -2;
+   22245           0 :     } else if (*sqre < 0 || *sqre > 1) {
+   22246           0 :         *info = -3;
+   22247             :     }
+   22248           0 :     if (*info != 0) {
+   22249             :         return;
+   22250             :     }
+   22251             : 
+   22252           0 :     n = *nl + *nr + 1;
+   22253           0 :     m = n + *sqre;
+   22254             : 
+   22255             : 
+   22256           0 :     ldu2 = n;
+   22257           0 :     ldvt2 = m;
+   22258             : 
+   22259             :     iz = 1;
+   22260           0 :     isigma = iz + m;
+   22261           0 :     iu2 = isigma + n;
+   22262           0 :     ivt2 = iu2 + ldu2 * n;
+   22263           0 :     iq = ivt2 + ldvt2 * m;
+   22264             : 
+   22265             :     idx = 1;
+   22266           0 :     idxc = idx + n;
+   22267           0 :     coltyp = idxc + n;
+   22268           0 :     idxp = coltyp + n;
+   22269             : 
+   22270           0 :     d__1 = std::abs(*alpha);
+   22271           0 :     d__2 = std::abs(*beta);
+   22272           0 :     orgnrm = (d__1>d__2) ? d__1 : d__2;
+   22273           0 :     d__[*nl + 1] = 0.;
+   22274             :     i__1 = n;
+   22275           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22276           0 :         if (std::abs(d__[i__]) > orgnrm) {
+   22277           0 :             orgnrm = std::abs(d__[i__]);
+   22278             :         }
+   22279             :     }
+   22280           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &orgnrm, &one, &n, &c__1, &d__[1], &n, info);
+   22281           0 :     *alpha /= orgnrm;
+   22282           0 :     *beta /= orgnrm;
+   22283             : 
+   22284           0 :     PLUMED_BLAS_F77_FUNC(slasd2,SLASD2)(nl, nr, sqre, &k, &d__[1], &work[iz], alpha, beta, &u[u_offset], 
+   22285           0 :             ldu, &vt[vt_offset], ldvt, &work[isigma], &work[iu2], &ldu2, &
+   22286           0 :             work[ivt2], &ldvt2, &iwork[idxp], &iwork[idx], &iwork[idxc], &
+   22287           0 :             idxq[1], &iwork[coltyp], info);
+   22288             : 
+   22289           0 :     ldq = k;
+   22290           0 :     PLUMED_BLAS_F77_FUNC(slasd3,SLASD3)(nl, nr, sqre, &k, &d__[1], &work[iq], &ldq, &work[isigma], &u[
+   22291             :             u_offset], ldu, &work[iu2], &ldu2, &vt[vt_offset], ldvt, &work[
+   22292             :             ivt2], &ldvt2, &iwork[idxc], &iwork[coltyp], &work[iz], info);
+   22293           0 :     if (*info != 0) {
+   22294             :         return;
+   22295             :     }
+   22296           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &one, &orgnrm, &n, &c__1, &d__[1], &n, info);
+   22297             : 
+   22298           0 :     n1 = k;
+   22299           0 :     n2 = n - k;
+   22300           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(&n1, &n2, &d__[1], &c__1, &c_n1, &idxq[1]);
+   22301             : 
+   22302             :     return;
+   22303             : 
+   22304             : }
+   22305             : }
+   22306             : }
+   22307             : #include <cmath>
+   22308             : #include "blas/blas.h"
+   22309             : #include "lapack.h"
+   22310             : #include "lapack_limits.h"
+   22311             : 
+   22312             : #include "real.h"
+   22313             : 
+   22314             : #include "blas/blas.h"
+   22315             : namespace PLMD{
+   22316             : namespace lapack{
+   22317             : using namespace blas;
+   22318             : void 
+   22319           0 : PLUMED_BLAS_F77_FUNC(slasd2,SLASD2)(int *nl, 
+   22320             :                         int *nr, 
+   22321             :                         int *sqre, 
+   22322             :                         int *k, 
+   22323             :                         float *d__, 
+   22324             :                         float *z__, 
+   22325             :                         float *alpha, 
+   22326             :                         float *beta, 
+   22327             :                         float *u, 
+   22328             :                         int *ldu, 
+   22329             :                         float *vt, 
+   22330             :                         int *ldvt, 
+   22331             :                         float *dsigma, 
+   22332             :                         float *u2, 
+   22333             :                         int *ldu2, 
+   22334             :                         float *vt2, 
+   22335             :                         int *ldvt2, 
+   22336             :                         int *idxp, 
+   22337             :                         int *idx, 
+   22338             :                         int *idxc, 
+   22339             :                         int *idxq, 
+   22340             :                         int *coltyp, 
+   22341             :                         int *info)
+   22342             : {
+   22343             :     int u_dim1, u_offset, u2_dim1, u2_offset, vt_dim1, vt_offset;
+   22344             :     int vt2_dim1, vt2_offset, i__1;
+   22345             :     float d__1, d__2;
+   22346             : 
+   22347             :     float c__;
+   22348             :     int i__, j, m, n;
+   22349             :     float s;
+   22350             :     int k2;
+   22351             :     float z1;
+   22352             :     int ct, jp;
+   22353             :     float eps, tau, tol;
+   22354             :     int psm[4], nlp1, nlp2, idxi, idxj;
+   22355             :     int ctot[4], idxjp;
+   22356             :     int jprev = 0;
+   22357             :     float hlftol;
+   22358           0 :     float zero = 0.0;
+   22359           0 :     int c__1 = 1;
+   22360             : 
+   22361             : 
+   22362           0 :     --d__;
+   22363           0 :     --z__;
+   22364           0 :     u_dim1 = *ldu;
+   22365           0 :     u_offset = 1 + u_dim1;
+   22366           0 :     u -= u_offset;
+   22367           0 :     vt_dim1 = *ldvt;
+   22368           0 :     vt_offset = 1 + vt_dim1;
+   22369           0 :     vt -= vt_offset;
+   22370           0 :     --dsigma;
+   22371           0 :     u2_dim1 = *ldu2;
+   22372           0 :     u2_offset = 1 + u2_dim1;
+   22373           0 :     u2 -= u2_offset;
+   22374           0 :     vt2_dim1 = *ldvt2;
+   22375           0 :     vt2_offset = 1 + vt2_dim1;
+   22376           0 :     vt2 -= vt2_offset;
+   22377           0 :     --idxp;
+   22378           0 :     --idx;
+   22379           0 :     --idxc;
+   22380           0 :     --idxq;
+   22381           0 :     --coltyp;
+   22382             : 
+   22383           0 :     *info = 0;
+   22384             : 
+   22385           0 :     n = *nl + *nr + 1;
+   22386           0 :     m = n + *sqre;
+   22387             : 
+   22388           0 :     nlp1 = *nl + 1;
+   22389           0 :     nlp2 = *nl + 2;
+   22390             : 
+   22391           0 :     z1 = *alpha * vt[nlp1 + nlp1 * vt_dim1];
+   22392           0 :     z__[1] = z1;
+   22393           0 :     for (i__ = *nl; i__ >= 1; --i__) {
+   22394           0 :         z__[i__ + 1] = *alpha * vt[i__ + nlp1 * vt_dim1];
+   22395           0 :         d__[i__ + 1] = d__[i__];
+   22396           0 :         idxq[i__ + 1] = idxq[i__] + 1;
+   22397             :     }
+   22398             : 
+   22399             :     i__1 = m;
+   22400           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22401           0 :         z__[i__] = *beta * vt[i__ + nlp2 * vt_dim1];
+   22402             :     }
+   22403             : 
+   22404             :     i__1 = nlp1;
+   22405           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   22406           0 :         coltyp[i__] = 1;
+   22407             :     }
+   22408           0 :     i__1 = n;
+   22409           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22410           0 :         coltyp[i__] = 2;
+   22411             :     }
+   22412             : 
+   22413             :     i__1 = n;
+   22414           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22415           0 :         idxq[i__] += nlp1;
+   22416             :     }
+   22417             : 
+   22418             :     i__1 = n;
+   22419           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   22420           0 :         dsigma[i__] = d__[idxq[i__]];
+   22421           0 :         u2[i__ + u2_dim1] = z__[idxq[i__]];
+   22422           0 :         idxc[i__] = coltyp[idxq[i__]];
+   22423             :     }
+   22424             : 
+   22425           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(nl, nr, &dsigma[2], &c__1, &c__1, &idx[2]);
+   22426             : 
+   22427           0 :     i__1 = n;
+   22428           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   22429           0 :         idxi = idx[i__] + 1;
+   22430           0 :         d__[i__] = dsigma[idxi];
+   22431           0 :         z__[i__] = u2[idxi + u2_dim1];
+   22432           0 :         coltyp[i__] = idxc[idxi];
+   22433             :     }
+   22434             : 
+   22435             :     eps = PLUMED_GMX_FLOAT_EPS;
+   22436           0 :     d__1 = std::abs(*alpha), d__2 = std::abs(*beta);
+   22437           0 :     tol = (d__1 > d__2) ? d__1 : d__2;
+   22438           0 :     d__2 = std::abs(d__[n]);
+   22439           0 :     tol = eps * 8. * ((d__2 > tol) ? d__2 : tol);
+   22440             : 
+   22441           0 :     *k = 1;
+   22442           0 :     k2 = n + 1;
+   22443             :     i__1 = n;
+   22444           0 :     for (j = 2; j <= i__1; ++j) {
+   22445           0 :         if (std::abs(z__[j]) <= tol) {
+   22446             : 
+   22447           0 :             --k2;
+   22448           0 :             idxp[k2] = j;
+   22449           0 :             coltyp[j] = 4;
+   22450           0 :             if (j == n) {
+   22451           0 :                 goto L120;
+   22452             :             }
+   22453             :         } else {
+   22454             :             jprev = j;
+   22455           0 :             goto L90;
+   22456             :         }
+   22457             :     }
+   22458           0 : L90:
+   22459             :     j = jprev;
+   22460           0 : L100:
+   22461           0 :     ++j;
+   22462           0 :     if (j > n) {
+   22463           0 :         goto L110;
+   22464             :     }
+   22465           0 :     if (std::abs(z__[j]) <= tol) {
+   22466             : 
+   22467           0 :         --k2;
+   22468           0 :         idxp[k2] = j;
+   22469           0 :         coltyp[j] = 4;
+   22470             :     } else {
+   22471             : 
+   22472           0 :         if (std::abs(d__[j] - d__[jprev]) <= tol) {
+   22473             : 
+   22474           0 :             s = z__[jprev];
+   22475           0 :             c__ = z__[j];
+   22476             : 
+   22477           0 :             tau = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&c__, &s);
+   22478           0 :             c__ /= tau;
+   22479           0 :             s = -s / tau;
+   22480           0 :             z__[j] = tau;
+   22481           0 :             z__[jprev] = 0.;
+   22482             : 
+   22483           0 :             idxjp = idxq[idx[jprev] + 1];
+   22484           0 :             idxj = idxq[idx[j] + 1];
+   22485           0 :             if (idxjp <= nlp1) {
+   22486           0 :                 --idxjp;
+   22487             :             }
+   22488           0 :             if (idxj <= nlp1) {
+   22489           0 :                 --idxj;
+   22490             :             }
+   22491           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&n, &u[idxjp * u_dim1 + 1], &c__1, &u[idxj * u_dim1 + 1], &
+   22492             :                     c__1, &c__, &s);
+   22493           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&m, &vt[idxjp + vt_dim1], ldvt, &vt[idxj + vt_dim1], ldvt, &
+   22494             :                     c__, &s);
+   22495           0 :             if (coltyp[j] != coltyp[jprev]) {
+   22496           0 :                 coltyp[j] = 3;
+   22497             :             }
+   22498           0 :             coltyp[jprev] = 4;
+   22499           0 :             --k2;
+   22500           0 :             idxp[k2] = jprev;
+   22501             :             jprev = j;
+   22502             :         } else {
+   22503           0 :             ++(*k);
+   22504           0 :             u2[*k + u2_dim1] = z__[jprev];
+   22505           0 :             dsigma[*k] = d__[jprev];
+   22506           0 :             idxp[*k] = jprev;
+   22507             :             jprev = j;
+   22508             :         }
+   22509             :     }
+   22510           0 :     goto L100;
+   22511             : L110:
+   22512             : 
+   22513           0 :     ++(*k);
+   22514           0 :     u2[*k + u2_dim1] = z__[jprev];
+   22515           0 :     dsigma[*k] = d__[jprev];
+   22516           0 :     idxp[*k] = jprev;
+   22517             : 
+   22518             : L120:
+   22519             : 
+   22520           0 :     for (j = 1; j <= 4; ++j) {
+   22521           0 :         ctot[j - 1] = 0;
+   22522             :     }
+   22523           0 :     i__1 = n;
+   22524           0 :     for (j = 2; j <= i__1; ++j) {
+   22525           0 :         ct = coltyp[j];
+   22526           0 :         ++ctot[ct - 1];
+   22527             :     }
+   22528             : 
+   22529           0 :     psm[0] = 2;
+   22530           0 :     psm[1] = ctot[0] + 2;
+   22531           0 :     psm[2] = psm[1] + ctot[1];
+   22532           0 :     psm[3] = psm[2] + ctot[2];
+   22533             : 
+   22534             :     i__1 = n;
+   22535           0 :     for (j = 2; j <= i__1; ++j) {
+   22536           0 :         jp = idxp[j];
+   22537           0 :         ct = coltyp[jp];
+   22538           0 :         idxc[psm[ct - 1]] = j;
+   22539           0 :         ++psm[ct - 1];
+   22540             :     }
+   22541             : 
+   22542             :     i__1 = n;
+   22543           0 :     for (j = 2; j <= i__1; ++j) {
+   22544           0 :         jp = idxp[j];
+   22545           0 :         dsigma[j] = d__[jp];
+   22546           0 :         idxj = idxq[idx[idxp[idxc[j]]] + 1];
+   22547           0 :         if (idxj <= nlp1) {
+   22548           0 :             --idxj;
+   22549             :         }
+   22550           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&n, &u[idxj * u_dim1 + 1], &c__1, &u2[j * u2_dim1 + 1], &c__1);
+   22551           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt[idxj + vt_dim1], ldvt, &vt2[j + vt2_dim1], ldvt2);
+   22552             :     }
+   22553             : 
+   22554           0 :     dsigma[1] = 0.;
+   22555           0 :     hlftol = tol / 2.;
+   22556           0 :     if (std::abs(dsigma[2]) <= hlftol) {
+   22557           0 :         dsigma[2] = hlftol;
+   22558             :     }
+   22559           0 :     if (m > n) {
+   22560           0 :         z__[1] = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&z1, &z__[m]);
+   22561           0 :         if (z__[1] <= tol) {
+   22562           0 :             c__ = 1.;
+   22563           0 :             s = 0.;
+   22564           0 :             z__[1] = tol;
+   22565             :         } else {
+   22566           0 :             c__ = z1 / z__[1];
+   22567           0 :             s = z__[m] / z__[1];
+   22568             :         }
+   22569             :     } else {
+   22570           0 :         if (std::abs(z1) <= tol) {
+   22571           0 :             z__[1] = tol;
+   22572             :         } else {
+   22573           0 :             z__[1] = z1;
+   22574             :         }
+   22575             :     }
+   22576             : 
+   22577           0 :     i__1 = *k - 1;
+   22578           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &u2[u2_dim1 + 2], &c__1, &z__[2], &c__1);
+   22579             : 
+   22580           0 :     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &n, &c__1, &zero, &zero, &u2[u2_offset], ldu2);
+   22581           0 :     u2[nlp1 + u2_dim1] = 1.;
+   22582           0 :     if (m > n) {
+   22583             :         i__1 = nlp1;
+   22584           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   22585           0 :             vt[m + i__ * vt_dim1] = -s * vt[nlp1 + i__ * vt_dim1];
+   22586           0 :             vt2[i__ * vt2_dim1 + 1] = c__ * vt[nlp1 + i__ * vt_dim1];
+   22587             :         }
+   22588           0 :         i__1 = m;
+   22589           0 :         for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22590           0 :             vt2[i__ * vt2_dim1 + 1] = s * vt[m + i__ * vt_dim1];
+   22591           0 :             vt[m + i__ * vt_dim1] = c__ * vt[m + i__ * vt_dim1];
+   22592             :         }
+   22593             :     } else {
+   22594           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt[nlp1 + vt_dim1], ldvt, &vt2[vt2_dim1 + 1], ldvt2);
+   22595             :     }
+   22596           0 :     if (m > n) {
+   22597           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt[m + vt_dim1], ldvt, &vt2[m + vt2_dim1], ldvt2);
+   22598             :     }
+   22599             : 
+   22600           0 :     if (n > *k) {
+   22601           0 :         i__1 = n - *k;
+   22602           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &dsigma[*k + 1], &c__1, &d__[*k + 1], &c__1);
+   22603           0 :         i__1 = n - *k;
+   22604           0 :         PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("A", &n, &i__1, &u2[(*k + 1) * u2_dim1 + 1], ldu2, &u[(*k + 1)
+   22605           0 :                  * u_dim1 + 1], ldu);
+   22606           0 :         i__1 = n - *k;
+   22607           0 :         PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("A", &i__1, &m, &vt2[*k + 1 + vt2_dim1], ldvt2, &vt[*k + 1 + 
+   22608           0 :                 vt_dim1], ldvt);
+   22609             :     }
+   22610           0 :     for (j = 1; j <= 4; ++j) {
+   22611           0 :         coltyp[j] = ctot[j - 1];
+   22612             :     }
+   22613             : 
+   22614           0 :     return;
+   22615             : 
+   22616             : }
+   22617             : 
+   22618             : 
+   22619             : }
+   22620             : }
+   22621             : #include <cmath>
+   22622             : #include "blas/blas.h"
+   22623             : #include "lapack.h"
+   22624             : 
+   22625             : #include "blas/blas.h"
+   22626             : namespace PLMD{
+   22627             : namespace lapack{
+   22628             : using namespace blas;
+   22629             : void 
+   22630           0 : PLUMED_BLAS_F77_FUNC(slasd3,SLASD3)(int *nl, 
+   22631             :         int *nr,
+   22632             :         int *sqre, 
+   22633             :         int *k, 
+   22634             :         float *d__, 
+   22635             :         float *q, 
+   22636             :         int *ldq, 
+   22637             :         float *dsigma, 
+   22638             :         float *u, 
+   22639             :         int *ldu, 
+   22640             :         float *u2, 
+   22641             :         int *ldu2, 
+   22642             :         float *vt, 
+   22643             :         int *ldvt, 
+   22644             :         float *vt2, 
+   22645             :         int *ldvt2, 
+   22646             :         int *idxc, 
+   22647             :         int *ctot, 
+   22648             :         float *z__, 
+   22649             :         int *info)
+   22650             : {
+   22651             :     int q_dim1, q_offset, u_dim1, u_offset, u2_dim1, u2_offset, vt_dim1, 
+   22652             :             vt_offset, vt2_dim1, vt2_offset, i__1, i__2;
+   22653             :     float d__2;
+   22654             : 
+   22655             :     int i__, j, m, n, jc;
+   22656             :     float rho;
+   22657             :     int nlp1, nlp2, nrp1;
+   22658             :     float temp;
+   22659             :     int ctemp;
+   22660             :     int ktemp;
+   22661           0 :     int c__1 = 1;
+   22662           0 :     int c__0 = 0;
+   22663           0 :     float zero = 0.0;
+   22664           0 :     float one = 1.0;
+   22665             : 
+   22666             :     --d__;
+   22667           0 :     q_dim1 = *ldq;
+   22668           0 :     q_offset = 1 + q_dim1;
+   22669           0 :     q -= q_offset;
+   22670           0 :     --dsigma;
+   22671           0 :     u_dim1 = *ldu;
+   22672           0 :     u_offset = 1 + u_dim1;
+   22673           0 :     u -= u_offset;
+   22674           0 :     u2_dim1 = *ldu2;
+   22675           0 :     u2_offset = 1 + u2_dim1;
+   22676           0 :     u2 -= u2_offset;
+   22677           0 :     vt_dim1 = *ldvt;
+   22678           0 :     vt_offset = 1 + vt_dim1;
+   22679           0 :     vt -= vt_offset;
+   22680           0 :     vt2_dim1 = *ldvt2;
+   22681           0 :     vt2_offset = 1 + vt2_dim1;
+   22682           0 :     vt2 -= vt2_offset;
+   22683           0 :     --idxc;
+   22684             :     --ctot;
+   22685           0 :     --z__;
+   22686             : 
+   22687             :     /* Function Body */
+   22688           0 :     *info = 0;
+   22689             : 
+   22690           0 :     if (*nl < 1) {
+   22691           0 :         *info = -1;
+   22692           0 :     } else if (*nr < 1) {
+   22693           0 :         *info = -2;
+   22694           0 :     } else if (*sqre != 1 && *sqre != 0) {
+   22695           0 :         *info = -3;
+   22696             :     }
+   22697             : 
+   22698           0 :     n = *nl + *nr + 1;
+   22699           0 :     m = n + *sqre;
+   22700           0 :     nlp1 = *nl + 1;
+   22701           0 :     nlp2 = *nl + 2;
+   22702             : 
+   22703           0 :     if (*k == 1) {
+   22704           0 :         d__[1] = std::abs(z__[1]);
+   22705           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&m, &vt2[vt2_dim1 + 1], ldvt2, &vt[vt_dim1 + 1], ldvt);
+   22706           0 :         if (z__[1] > 0.) {
+   22707           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&n, &u2[u2_dim1 + 1], &c__1, &u[u_dim1 + 1], &c__1);
+   22708             :         } else {
+   22709           0 :             i__1 = n;
+   22710           0 :             for (i__ = 1; i__ <= i__1; ++i__) {
+   22711           0 :                 u[i__ + u_dim1] = -u2[i__ + u2_dim1];
+   22712             :             }
+   22713             :         }
+   22714           0 :         return;
+   22715             :     }
+   22716             : 
+   22717           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &z__[1], &c__1, &q[q_offset], &c__1);
+   22718             : 
+   22719           0 :     rho = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &z__[1], &c__1);
+   22720           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &rho, &one, k, &c__1, &z__[1], k, info);
+   22721           0 :     rho *= rho;
+   22722             : 
+   22723             : 
+   22724           0 :     i__1 = *k;
+   22725           0 :     for (j = 1; j <= i__1; ++j) {
+   22726           0 :         PLUMED_BLAS_F77_FUNC(slasd4,SLASD4)(k, &j, &dsigma[1], &z__[1], &u[j * u_dim1 + 1], &rho, &d__[j],
+   22727           0 :                  &vt[j * vt_dim1 + 1], info);
+   22728             : 
+   22729           0 :         if (*info != 0) {
+   22730             :             return;
+   22731             :         }
+   22732             :     }
+   22733             : 
+   22734           0 :     i__1 = *k;
+   22735           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22736           0 :         z__[i__] = u[i__ + *k * u_dim1] * vt[i__ + *k * vt_dim1];
+   22737             :         i__2 = i__ - 1;
+   22738           0 :         for (j = 1; j <= i__2; ++j) {
+   22739           0 :             z__[i__] *= u[i__ + j * u_dim1] * vt[i__ + j * vt_dim1] / (dsigma[
+   22740           0 :                     i__] - dsigma[j]) / (dsigma[i__] + dsigma[j]);
+   22741             :         }
+   22742           0 :         i__2 = *k - 1;
+   22743           0 :         for (j = i__; j <= i__2; ++j) {
+   22744           0 :             z__[i__] *= u[i__ + j * u_dim1] * vt[i__ + j * vt_dim1] / (dsigma[
+   22745           0 :                     i__] - dsigma[j + 1]) / (dsigma[i__] + dsigma[j + 1]);
+   22746             :         }
+   22747           0 :         d__2 =  std::sqrt(std::abs(z__[i__]));
+   22748           0 :         z__[i__] = (q[i__ + q_dim1] > 0) ? d__2 : -d__2;
+   22749             :     }
+   22750             : 
+   22751           0 :     i__1 = *k;
+   22752           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22753           0 :         vt[i__ * vt_dim1 + 1] = z__[1] / u[i__ * u_dim1 + 1] / vt[i__ * 
+   22754           0 :                 vt_dim1 + 1];
+   22755           0 :         u[i__ * u_dim1 + 1] = -1.;
+   22756           0 :         i__2 = *k;
+   22757           0 :         for (j = 2; j <= i__2; ++j) {
+   22758           0 :             vt[j + i__ * vt_dim1] = z__[j] / u[j + i__ * u_dim1] / vt[j + i__ 
+   22759           0 :                     * vt_dim1];
+   22760           0 :             u[j + i__ * u_dim1] = dsigma[j] * vt[j + i__ * vt_dim1];
+   22761             :         }
+   22762           0 :         temp = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &u[i__ * u_dim1 + 1], &c__1);
+   22763           0 :         q[i__ * q_dim1 + 1] = u[i__ * u_dim1 + 1] / temp;
+   22764           0 :         i__2 = *k;
+   22765           0 :         for (j = 2; j <= i__2; ++j) {
+   22766           0 :             jc = idxc[j];
+   22767           0 :             q[j + i__ * q_dim1] = u[jc + i__ * u_dim1] / temp;
+   22768             :         }
+   22769             :     }
+   22770             : 
+   22771           0 :     if (*k == 2) {
+   22772           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", &n, k, k, &one, &u2[u2_offset], ldu2, &q[q_offset],
+   22773             :                  ldq, &zero, &u[u_offset], ldu);
+   22774           0 :         goto L100;
+   22775             :     }
+   22776           0 :     if (ctot[1] > 0) {
+   22777           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nl, k, &ctot[1], &one, &u2[(u2_dim1 << 1) + 1], 
+   22778           0 :                 ldu2, &q[q_dim1 + 2], ldq, &zero, &u[u_dim1 + 1], ldu);
+   22779           0 :         if (ctot[3] > 0) {
+   22780           0 :             ktemp = ctot[1] + 2 + ctot[2];
+   22781           0 :             PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nl, k, &ctot[3], &one, &u2[ktemp * u2_dim1 + 1]
+   22782           0 :                     , ldu2, &q[ktemp + q_dim1], ldq, &one, &u[u_dim1 + 1], 
+   22783             :                     ldu);
+   22784             :         }
+   22785           0 :     } else if (ctot[3] > 0) {
+   22786           0 :         ktemp = ctot[1] + 2 + ctot[2];
+   22787           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nl, k, &ctot[3], &one, &u2[ktemp * u2_dim1 + 1], 
+   22788           0 :                 ldu2, &q[ktemp + q_dim1], ldq, &zero, &u[u_dim1 + 1], ldu);
+   22789             :     } else {
+   22790           0 :         PLUMED_BLAS_F77_FUNC(slacpy,SLACPY)("F", nl, k, &u2[u2_offset], ldu2, &u[u_offset], ldu);
+   22791             :     }
+   22792           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &q[q_dim1 + 1], ldq, &u[nlp1 + u_dim1], ldu);
+   22793           0 :     ktemp = ctot[1] + 2;
+   22794           0 :     ctemp = ctot[2] + ctot[3];
+   22795           0 :     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", nr, k, &ctemp, &one, &u2[nlp2 + ktemp * u2_dim1], ldu2,
+   22796           0 :              &q[ktemp + q_dim1], ldq, &zero, &u[nlp2 + u_dim1], ldu);
+   22797             : 
+   22798           0 : L100:
+   22799           0 :     i__1 = *k;
+   22800           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   22801           0 :         temp = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &vt[i__ * vt_dim1 + 1], &c__1);
+   22802           0 :         q[i__ + q_dim1] = vt[i__ * vt_dim1 + 1] / temp;
+   22803           0 :         i__2 = *k;
+   22804           0 :         for (j = 2; j <= i__2; ++j) {
+   22805           0 :             jc = idxc[j];
+   22806           0 :             q[i__ + j * q_dim1] = vt[jc + i__ * vt_dim1] / temp;
+   22807             :         }
+   22808             :     }
+   22809             : 
+   22810           0 :     if (*k == 2) {
+   22811           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &m, k, &one, &q[q_offset], ldq, &vt2[vt2_offset]
+   22812             :                 , ldvt2, &zero, &vt[vt_offset], ldvt);
+   22813           0 :         return;
+   22814             :     }
+   22815           0 :     ktemp = ctot[1] + 1;
+   22816           0 :     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &nlp1, &ktemp, &one, &q[q_dim1 + 1], ldq, &vt2[
+   22817           0 :             vt2_dim1 + 1], ldvt2, &zero, &vt[vt_dim1 + 1], ldvt);
+   22818           0 :     ktemp = ctot[1] + 2 + ctot[2];
+   22819           0 :     if (ktemp <= *ldvt2) {
+   22820           0 :         PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &nlp1, &ctot[3], &one, &q[ktemp * q_dim1 + 1], 
+   22821           0 :                 ldq, &vt2[ktemp + vt2_dim1], ldvt2, &one, &vt[vt_dim1 + 1], 
+   22822             :                 ldvt);
+   22823             :     }
+   22824             : 
+   22825           0 :     ktemp = ctot[1] + 1;
+   22826           0 :     nrp1 = *nr + *sqre;
+   22827           0 :     if (ktemp > 1) {
+   22828           0 :         i__1 = *k;
+   22829           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   22830           0 :             q[i__ + ktemp * q_dim1] = q[i__ + q_dim1];
+   22831             :         }
+   22832           0 :         i__1 = m;
+   22833           0 :         for (i__ = nlp2; i__ <= i__1; ++i__) {
+   22834           0 :             vt2[ktemp + i__ * vt2_dim1] = vt2[i__ * vt2_dim1 + 1];
+   22835             :         }
+   22836             :     }
+   22837           0 :     ctemp = ctot[2] + 1 + ctot[3];
+   22838           0 :     PLUMED_BLAS_F77_FUNC(sgemm,SGEMM)("N", "N", k, &nrp1, &ctemp, &one, &q[ktemp * q_dim1 + 1], ldq, &
+   22839           0 :             vt2[ktemp + nlp2 * vt2_dim1], ldvt2, &zero, &vt[nlp2 * vt_dim1 + 
+   22840           0 :             1], ldvt);
+   22841             : 
+   22842             :     return;
+   22843             : 
+   22844             : 
+   22845             : }
+   22846             : 
+   22847             : 
+   22848             : }
+   22849             : }
+   22850             : #include <cmath>
+   22851             : #include "lapack.h"
+   22852             : #include "lapack_limits.h"
+   22853             : 
+   22854             : #include "real.h"
+   22855             : 
+   22856             : #include "blas/blas.h"
+   22857             : namespace PLMD{
+   22858             : namespace lapack{
+   22859             : using namespace blas;
+   22860             : void 
+   22861           0 : PLUMED_BLAS_F77_FUNC(slasd4,SLASD4)(int *n, 
+   22862             :         int *i__, 
+   22863             :         float *d__, 
+   22864             :         float *z__, 
+   22865             :         float *delta, 
+   22866             :         float *rho, 
+   22867             :         float *sigma, 
+   22868             :         float *work, 
+   22869             :         int *info)
+   22870             : {
+   22871             :     int i__1;
+   22872             :     float d__1;
+   22873             : 
+   22874             :     float a, b, c__;
+   22875             :     int j;
+   22876             :     float w, dd[3];
+   22877             :     int ii;
+   22878             :     float dw, zz[3];
+   22879             :     int ip1;
+   22880             :     float eta, phi, eps, tau, psi;
+   22881             :     int iim1, iip1;
+   22882             :     float dphi, dpsi;
+   22883             :     int iter;
+   22884             :     float temp, prew, sg2lb, sg2ub, temp1, temp2, dtiim, delsq, 
+   22885             :             dtiip;
+   22886             :     int niter;
+   22887             :     float dtisq;
+   22888             :     int swtch;
+   22889             :     float dtnsq;
+   22890             :     float delsq2, dtnsq1;
+   22891             :     int swtch3;
+   22892             :     int orgati;
+   22893             :     float erretm, dtipsq, rhoinv;
+   22894             : 
+   22895           0 :     --work;
+   22896           0 :     --delta;
+   22897           0 :     --z__;
+   22898           0 :     --d__;
+   22899             : 
+   22900           0 :     *info = 0;
+   22901           0 :     if (*n == 1) {
+   22902             : 
+   22903           0 :         *sigma =  std::sqrt(d__[1] * d__[1] + *rho * z__[1] * z__[1]);
+   22904           0 :         delta[1] = 1.;
+   22905           0 :         work[1] = 1.;
+   22906           0 :         return;
+   22907             :     }
+   22908           0 :     if (*n == 2) {
+   22909           0 :         PLUMED_BLAS_F77_FUNC(slasd5,SLASD5)(i__, &d__[1], &z__[1], &delta[1], rho, sigma, &work[1]);
+   22910           0 :         return;
+   22911             :     }
+   22912             : 
+   22913             :     eps = PLUMED_GMX_FLOAT_EPS;
+   22914           0 :     rhoinv = 1. / *rho;
+   22915             : 
+   22916           0 :     if (*i__ == *n) {
+   22917             : 
+   22918           0 :         ii = *n - 1;
+   22919           0 :         niter = 1;
+   22920             : 
+   22921           0 :         temp = *rho / 2.;
+   22922             : 
+   22923           0 :         temp1 = temp / (d__[*n] +  std::sqrt(d__[*n] * d__[*n] + temp));
+   22924           0 :         i__1 = *n;
+   22925           0 :         for (j = 1; j <= i__1; ++j) {
+   22926           0 :             work[j] = d__[j] + d__[*n] + temp1;
+   22927           0 :             delta[j] = d__[j] - d__[*n] - temp1;
+   22928             :         }
+   22929             : 
+   22930             :         psi = 0.;
+   22931           0 :         i__1 = *n - 2;
+   22932           0 :         for (j = 1; j <= i__1; ++j) {
+   22933           0 :             psi += z__[j] * z__[j] / (delta[j] * work[j]);
+   22934             :         }
+   22935             : 
+   22936           0 :         c__ = rhoinv + psi;
+   22937           0 :         w = c__ + z__[ii] * z__[ii] / (delta[ii] * work[ii]) + z__[*n] * z__[*
+   22938           0 :                 n] / (delta[*n] * work[*n]);
+   22939             : 
+   22940           0 :         if (w <= 0.) {
+   22941           0 :             temp1 =  std::sqrt(d__[*n] * d__[*n] + *rho);
+   22942           0 :             temp = z__[*n - 1] * z__[*n - 1] / ((d__[*n - 1] + temp1) * (d__[*
+   22943           0 :                     n] - d__[*n - 1] + *rho / (d__[*n] + temp1))) + z__[*n] * 
+   22944           0 :                     z__[*n] / *rho;
+   22945             : 
+   22946           0 :             if (c__ <= temp) {
+   22947             :                 tau = *rho;
+   22948             :             } else {
+   22949           0 :                 delsq = (d__[*n] - d__[*n - 1]) * (d__[*n] + d__[*n - 1]);
+   22950           0 :                 a = -c__ * delsq + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[*
+   22951             :                         n];
+   22952           0 :                 b = z__[*n] * z__[*n] * delsq;
+   22953           0 :                 if (a < 0.) {
+   22954           0 :                     tau = b * 2. / ( std::sqrt(a * a + b * 4. * c__) - a);
+   22955             :                 } else {
+   22956           0 :                     tau = (a +  std::sqrt(a * a + b * 4. * c__)) / (c__ * 2.);
+   22957             :                 }
+   22958             :             }
+   22959             : 
+   22960             :         } else {
+   22961           0 :             delsq = (d__[*n] - d__[*n - 1]) * (d__[*n] + d__[*n - 1]);
+   22962           0 :             a = -c__ * delsq + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[*n];
+   22963           0 :             b = z__[*n] * z__[*n] * delsq;
+   22964             : 
+   22965           0 :             if (a < 0.) {
+   22966           0 :                 tau = b * 2. / ( std::sqrt(a * a + b * 4. * c__) - a);
+   22967             :             } else {
+   22968           0 :                 tau = (a +  std::sqrt(a * a + b * 4. * c__)) / (c__ * 2.);
+   22969             :             }
+   22970             : 
+   22971             :         }
+   22972             : 
+   22973           0 :         eta = tau / (d__[*n] +  std::sqrt(d__[*n] * d__[*n] + tau));
+   22974             : 
+   22975           0 :         *sigma = d__[*n] + eta;
+   22976           0 :         i__1 = *n;
+   22977           0 :         for (j = 1; j <= i__1; ++j) {
+   22978           0 :             delta[j] = d__[j] - d__[*i__] - eta;
+   22979           0 :             work[j] = d__[j] + d__[*i__] + eta;
+   22980             :         }
+   22981             : 
+   22982             :         dpsi = 0.;
+   22983             :         psi = 0.;
+   22984             :         erretm = 0.;
+   22985             :         i__1 = ii;
+   22986           0 :         for (j = 1; j <= i__1; ++j) {
+   22987           0 :             temp = z__[j] / (delta[j] * work[j]);
+   22988           0 :             psi += z__[j] * temp;
+   22989           0 :             dpsi += temp * temp;
+   22990           0 :             erretm += psi;
+   22991             :         }
+   22992             :         erretm = std::abs(erretm);
+   22993             : 
+   22994           0 :         temp = z__[*n] / (delta[*n] * work[*n]);
+   22995           0 :         phi = z__[*n] * temp;
+   22996           0 :         dphi = temp * temp;
+   22997           0 :         erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (dpsi 
+   22998           0 :                 + dphi);
+   22999             : 
+   23000           0 :         w = rhoinv + phi + psi;
+   23001             : 
+   23002           0 :         if (std::abs(w) <= eps * erretm) {
+   23003           0 :             goto L240;
+   23004             :         }
+   23005             : 
+   23006           0 :         ++niter;
+   23007           0 :         dtnsq1 = work[*n - 1] * delta[*n - 1];
+   23008             :         dtnsq = work[*n] * delta[*n];
+   23009           0 :         c__ = w - dtnsq1 * dpsi - dtnsq * dphi;
+   23010           0 :         a = (dtnsq + dtnsq1) * w - dtnsq * dtnsq1 * (dpsi + dphi);
+   23011           0 :         b = dtnsq * dtnsq1 * w;
+   23012           0 :         if (c__ < 0.) {
+   23013           0 :             c__ = std::abs(c__);
+   23014             :         }
+   23015           0 :         if ( std::abs(c__)<PLUMED_GMX_FLOAT_MIN) {
+   23016           0 :             eta = *rho - *sigma * *sigma;
+   23017           0 :         } else if (a >= 0.) {
+   23018           0 :             eta = (a +  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__  * 2.);
+   23019             :         } else {
+   23020           0 :           eta = b * 2. / (a -  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23021             :         }
+   23022             : 
+   23023           0 :         if (w * eta > 0.) {
+   23024           0 :             eta = -w / (dpsi + dphi);
+   23025             :         }
+   23026           0 :         temp = eta - dtnsq;
+   23027           0 :         if (temp > *rho) {
+   23028           0 :             eta = *rho + dtnsq;
+   23029             :         }
+   23030             : 
+   23031           0 :         tau += eta;
+   23032           0 :         eta /= *sigma +  std::sqrt(eta + *sigma * *sigma);
+   23033           0 :         i__1 = *n;
+   23034           0 :         for (j = 1; j <= i__1; ++j) {
+   23035           0 :             delta[j] -= eta;
+   23036           0 :             work[j] += eta;
+   23037             :         }
+   23038             : 
+   23039           0 :         *sigma += eta;
+   23040             : 
+   23041             :         dpsi = 0.;
+   23042             :         psi = 0.;
+   23043             :         erretm = 0.;
+   23044             :         i__1 = ii;
+   23045           0 :         for (j = 1; j <= i__1; ++j) {
+   23046           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23047           0 :             psi += z__[j] * temp;
+   23048           0 :             dpsi += temp * temp;
+   23049           0 :             erretm += psi;
+   23050             :         }
+   23051             :         erretm = std::abs(erretm);
+   23052             : 
+   23053           0 :         temp = z__[*n] / (work[*n] * delta[*n]);
+   23054           0 :         phi = z__[*n] * temp;
+   23055           0 :         dphi = temp * temp;
+   23056           0 :         erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (dpsi 
+   23057           0 :                 + dphi);
+   23058             : 
+   23059           0 :         w = rhoinv + phi + psi;
+   23060             : 
+   23061             :         iter = niter + 1;
+   23062             : 
+   23063           0 :         for (niter = iter; niter <= 20; ++niter) {
+   23064             : 
+   23065           0 :             if (std::abs(w) <= eps * erretm) {
+   23066           0 :                 goto L240;
+   23067             :             }
+   23068           0 :             dtnsq1 = work[*n - 1] * delta[*n - 1];
+   23069           0 :             dtnsq = work[*n] * delta[*n];
+   23070           0 :             c__ = w - dtnsq1 * dpsi - dtnsq * dphi;
+   23071           0 :             a = (dtnsq + dtnsq1) * w - dtnsq1 * dtnsq * (dpsi + dphi);
+   23072           0 :             b = dtnsq1 * dtnsq * w;
+   23073           0 :             if (a >= 0.) {
+   23074           0 :                 eta = (a +  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23075             :             } else {
+   23076           0 :               eta = b * 2. / (a -  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23077             :             }
+   23078             : 
+   23079           0 :             if (w * eta > 0.) {
+   23080           0 :                 eta = -w / (dpsi + dphi);
+   23081             :             }
+   23082           0 :             temp = eta - dtnsq;
+   23083           0 :             if (temp <= 0.) {
+   23084           0 :                 eta /= 2.;
+   23085             :             }
+   23086             : 
+   23087           0 :             tau += eta;
+   23088           0 :             eta /= *sigma +  std::sqrt(eta + *sigma * *sigma);
+   23089           0 :             i__1 = *n;
+   23090           0 :             for (j = 1; j <= i__1; ++j) {
+   23091           0 :                 delta[j] -= eta;
+   23092           0 :                 work[j] += eta;
+   23093             :             }
+   23094             : 
+   23095           0 :             *sigma += eta;
+   23096             : 
+   23097             :             dpsi = 0.;
+   23098             :             psi = 0.;
+   23099             :             erretm = 0.;
+   23100             :             i__1 = ii;
+   23101           0 :             for (j = 1; j <= i__1; ++j) {
+   23102           0 :                 temp = z__[j] / (work[j] * delta[j]);
+   23103           0 :                 psi += z__[j] * temp;
+   23104           0 :                 dpsi += temp * temp;
+   23105           0 :                 erretm += psi;
+   23106             :             }
+   23107             :             erretm = std::abs(erretm);
+   23108             : 
+   23109           0 :             temp = z__[*n] / (work[*n] * delta[*n]);
+   23110           0 :             phi = z__[*n] * temp;
+   23111           0 :             dphi = temp * temp;
+   23112           0 :             erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + std::abs(tau) * (
+   23113           0 :                     dpsi + dphi);
+   23114             : 
+   23115           0 :             w = rhoinv + phi + psi;
+   23116             :         }
+   23117             : 
+   23118           0 :         *info = 1;
+   23119           0 :         goto L240;
+   23120             : 
+   23121             :     } else {
+   23122             : 
+   23123           0 :         niter = 1;
+   23124           0 :         ip1 = *i__ + 1;
+   23125             : 
+   23126           0 :         delsq = (d__[ip1] - d__[*i__]) * (d__[ip1] + d__[*i__]);
+   23127           0 :         delsq2 = delsq / 2.;
+   23128           0 :         temp = delsq2 / (d__[*i__] +  std::sqrt(d__[*i__] * d__[*i__] + delsq2));
+   23129           0 :         i__1 = *n;
+   23130           0 :         for (j = 1; j <= i__1; ++j) {
+   23131           0 :             work[j] = d__[j] + d__[*i__] + temp;
+   23132           0 :             delta[j] = d__[j] - d__[*i__] - temp;
+   23133             :         }
+   23134             : 
+   23135             :         psi = 0.;
+   23136           0 :         i__1 = *i__ - 1;
+   23137           0 :         for (j = 1; j <= i__1; ++j) {
+   23138           0 :             psi += z__[j] * z__[j] / (work[j] * delta[j]);
+   23139             :         }
+   23140             : 
+   23141             :         phi = 0.;
+   23142           0 :         i__1 = *i__ + 2;
+   23143           0 :         for (j = *n; j >= i__1; --j) {
+   23144           0 :             phi += z__[j] * z__[j] / (work[j] * delta[j]);
+   23145             :         }
+   23146           0 :         c__ = rhoinv + psi + phi;
+   23147           0 :         w = c__ + z__[*i__] * z__[*i__] / (work[*i__] * delta[*i__]) + z__[
+   23148           0 :                 ip1] * z__[ip1] / (work[ip1] * delta[ip1]);
+   23149             : 
+   23150           0 :         if (w > 0.) {
+   23151             : 
+   23152           0 :             orgati = 1;
+   23153             :             sg2lb = 0.;
+   23154             :             sg2ub = delsq2;
+   23155           0 :             a = c__ * delsq + z__[*i__] * z__[*i__] + z__[ip1] * z__[ip1];
+   23156           0 :             b = z__[*i__] * z__[*i__] * delsq;
+   23157           0 :             if (a > 0.) {
+   23158           0 :                 tau = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23159             :             } else {
+   23160           0 :                 tau = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23161             :             }
+   23162           0 :             eta = tau / (d__[*i__] +  std::sqrt(d__[*i__] * d__[*i__] + tau));
+   23163             :         } else {
+   23164             : 
+   23165           0 :             orgati = 0;
+   23166           0 :             sg2lb = -delsq2;
+   23167             :             sg2ub = 0.;
+   23168           0 :             a = c__ * delsq - z__[*i__] * z__[*i__] - z__[ip1] * z__[ip1];
+   23169           0 :             b = z__[ip1] * z__[ip1] * delsq;
+   23170           0 :             if (a < 0.) {
+   23171           0 :                 tau = b * 2. / (a -  std::sqrt(std::abs(a * a + b * 4. * c__)));
+   23172             :             } else {
+   23173           0 :                 tau = -(a +  std::sqrt(std::abs(a * a + b * 4. * c__))) /       (c__ * 2.);
+   23174             :             }
+   23175           0 :             eta = tau / (d__[ip1] +  std::sqrt(std::abs(d__[ip1] * d__[ip1] + tau)));
+   23176             :         }
+   23177             : 
+   23178           0 :         if (orgati) {
+   23179           0 :             ii = *i__;
+   23180           0 :             *sigma = d__[*i__] + eta;
+   23181           0 :             i__1 = *n;
+   23182           0 :             for (j = 1; j <= i__1; ++j) {
+   23183           0 :                 work[j] = d__[j] + d__[*i__] + eta;
+   23184           0 :                 delta[j] = d__[j] - d__[*i__] - eta;
+   23185             :             }
+   23186             :         } else {
+   23187           0 :             ii = *i__ + 1;
+   23188           0 :             *sigma = d__[ip1] + eta;
+   23189           0 :             i__1 = *n;
+   23190           0 :             for (j = 1; j <= i__1; ++j) {
+   23191           0 :                 work[j] = d__[j] + d__[ip1] + eta;
+   23192           0 :                 delta[j] = d__[j] - d__[ip1] - eta;
+   23193             :             }
+   23194             :         }
+   23195           0 :         iim1 = ii - 1;
+   23196           0 :         iip1 = ii + 1;
+   23197             : 
+   23198             :         dpsi = 0.;
+   23199             :         psi = 0.;
+   23200             :         erretm = 0.;
+   23201             :         i__1 = iim1;
+   23202           0 :         for (j = 1; j <= i__1; ++j) {
+   23203           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23204           0 :             psi += z__[j] * temp;
+   23205           0 :             dpsi += temp * temp;
+   23206           0 :             erretm += psi;
+   23207             :         }
+   23208             :         erretm = std::abs(erretm);
+   23209             : 
+   23210             :         dphi = 0.;
+   23211             :         phi = 0.;
+   23212             :         i__1 = iip1;
+   23213           0 :         for (j = *n; j >= i__1; --j) {
+   23214           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23215           0 :             phi += z__[j] * temp;
+   23216           0 :             dphi += temp * temp;
+   23217           0 :             erretm += phi;
+   23218             :         }
+   23219             : 
+   23220           0 :         w = rhoinv + phi + psi;
+   23221             : 
+   23222             :         swtch3 = 0;
+   23223           0 :         if (orgati) {
+   23224           0 :             if (w < 0.) {
+   23225             :                 swtch3 = 1;
+   23226             :             }
+   23227             :         } else {
+   23228           0 :             if (w > 0.) {
+   23229             :                 swtch3 = 1;
+   23230             :             }
+   23231             :         }
+   23232           0 :         if (ii == 1 || ii == *n) {
+   23233             :             swtch3 = 0;
+   23234             :         }
+   23235             : 
+   23236           0 :         temp = z__[ii] / (work[ii] * delta[ii]);
+   23237           0 :         dw = dpsi + dphi + temp * temp;
+   23238           0 :         temp = z__[ii] * temp;
+   23239           0 :         w += temp;
+   23240           0 :         erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. + 
+   23241           0 :                 std::abs(tau) * dw;
+   23242             : 
+   23243           0 :         if (std::abs(w) <= eps * erretm) {
+   23244           0 :             goto L240;
+   23245             :         }
+   23246             : 
+   23247           0 :         if (w <= 0.) {
+   23248           0 :             sg2lb = (sg2lb > tau) ? sg2lb : tau;
+   23249             :         } else {
+   23250           0 :             sg2ub = (sg2ub < tau) ? sg2ub : tau;
+   23251             :         }
+   23252             : 
+   23253           0 :         ++niter;
+   23254           0 :         if (! swtch3) {
+   23255           0 :             dtipsq = work[ip1] * delta[ip1];
+   23256           0 :             dtisq = work[*i__] * delta[*i__];
+   23257           0 :             if (orgati) {
+   23258           0 :                 d__1 = z__[*i__] / dtisq;
+   23259           0 :                 c__ = w - dtipsq * dw + delsq * (d__1 * d__1);
+   23260             :             } else {
+   23261           0 :                 d__1 = z__[ip1] / dtipsq;
+   23262           0 :                 c__ = w - dtisq * dw - delsq * (d__1 * d__1);
+   23263             :             }
+   23264           0 :             a = (dtipsq + dtisq) * w - dtipsq * dtisq * dw;
+   23265           0 :             b = dtipsq * dtisq * w;
+   23266           0 :             if ( std::abs(c__)<PLUMED_GMX_FLOAT_MIN) {
+   23267           0 :                 if ( std::abs(a)<PLUMED_GMX_FLOAT_MIN) {
+   23268           0 :                     if (orgati) {
+   23269           0 :                         a = z__[*i__] * z__[*i__] + dtipsq * dtipsq * (dpsi + 
+   23270             :                                 dphi);
+   23271             :                     } else {
+   23272           0 :                         a = z__[ip1] * z__[ip1] + dtisq * dtisq * (dpsi + 
+   23273             :                                 dphi);
+   23274             :                     }
+   23275             :                 }
+   23276           0 :                 eta = b / a;
+   23277           0 :             } else if (a <= 0.) {
+   23278           0 :                 eta = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23279             :             } else {
+   23280           0 :                 eta = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23281             :             }
+   23282             :         } else {
+   23283             : 
+   23284           0 :             dtiim = work[iim1] * delta[iim1];
+   23285           0 :             dtiip = work[iip1] * delta[iip1];
+   23286           0 :             temp = rhoinv + psi + phi;
+   23287           0 :             if (orgati) {
+   23288           0 :                 temp1 = z__[iim1] / dtiim;
+   23289           0 :                 temp1 *= temp1;
+   23290           0 :                 c__ = temp - dtiip * (dpsi + dphi) - (d__[iim1] - d__[iip1]) *
+   23291           0 :                          (d__[iim1] + d__[iip1]) * temp1;
+   23292           0 :                 zz[0] = z__[iim1] * z__[iim1];
+   23293           0 :                 if (dpsi < temp1) {
+   23294           0 :                     zz[2] = dtiip * dtiip * dphi;
+   23295             :                 } else {
+   23296           0 :                     zz[2] = dtiip * dtiip * (dpsi - temp1 + dphi);
+   23297             :                 }
+   23298             :             } else {
+   23299           0 :                 temp1 = z__[iip1] / dtiip;
+   23300           0 :                 temp1 *= temp1;
+   23301           0 :                 c__ = temp - dtiim * (dpsi + dphi) - (d__[iip1] - d__[iim1]) *
+   23302           0 :                          (d__[iim1] + d__[iip1]) * temp1;
+   23303           0 :                 if (dphi < temp1) {
+   23304           0 :                     zz[0] = dtiim * dtiim * dpsi;
+   23305             :                 } else {
+   23306           0 :                     zz[0] = dtiim * dtiim * (dpsi + (dphi - temp1));
+   23307             :                 }
+   23308           0 :                 zz[2] = z__[iip1] * z__[iip1];
+   23309             :             }
+   23310           0 :             zz[1] = z__[ii] * z__[ii];
+   23311           0 :             dd[0] = dtiim;
+   23312           0 :             dd[1] = delta[ii] * work[ii];
+   23313           0 :             dd[2] = dtiip;
+   23314           0 :             PLUMED_BLAS_F77_FUNC(slaed6,SLAED6)(&niter, &orgati, &c__, dd, zz, &w, &eta, info);
+   23315           0 :             if (*info != 0) {
+   23316           0 :                 goto L240;
+   23317             :             }
+   23318             :         }
+   23319             : 
+   23320           0 :         if (w * eta >= 0.) {
+   23321           0 :             eta = -w / dw;
+   23322             :         }
+   23323           0 :         if (orgati) {
+   23324           0 :             temp1 = work[*i__] * delta[*i__];
+   23325           0 :             temp = eta - temp1;
+   23326             :         } else {
+   23327           0 :             temp1 = work[ip1] * delta[ip1];
+   23328           0 :             temp = eta - temp1;
+   23329             :         }
+   23330           0 :         if (temp > sg2ub || temp < sg2lb) {
+   23331           0 :             if (w < 0.) {
+   23332           0 :                 eta = (sg2ub - tau) / 2.;
+   23333             :             } else {
+   23334           0 :                 eta = (sg2lb - tau) / 2.;
+   23335             :             }
+   23336             :         }
+   23337             : 
+   23338           0 :         tau += eta;
+   23339           0 :         eta /= *sigma +  std::sqrt(*sigma * *sigma + eta);
+   23340             : 
+   23341             :         prew = w;
+   23342             : 
+   23343           0 :         *sigma += eta;
+   23344           0 :         i__1 = *n;
+   23345           0 :         for (j = 1; j <= i__1; ++j) {
+   23346           0 :             work[j] += eta;
+   23347           0 :             delta[j] -= eta;
+   23348             :         }
+   23349             : 
+   23350             :         dpsi = 0.;
+   23351             :         psi = 0.;
+   23352             :         erretm = 0.;
+   23353             :         i__1 = iim1;
+   23354           0 :         for (j = 1; j <= i__1; ++j) {
+   23355           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23356           0 :             psi += z__[j] * temp;
+   23357           0 :             dpsi += temp * temp;
+   23358           0 :             erretm += psi;
+   23359             :         }
+   23360             :         erretm = std::abs(erretm);
+   23361             : 
+   23362             :         dphi = 0.;
+   23363             :         phi = 0.;
+   23364             :         i__1 = iip1;
+   23365           0 :         for (j = *n; j >= i__1; --j) {
+   23366           0 :             temp = z__[j] / (work[j] * delta[j]);
+   23367           0 :             phi += z__[j] * temp;
+   23368           0 :             dphi += temp * temp;
+   23369           0 :             erretm += phi;
+   23370             :         }
+   23371             : 
+   23372           0 :         temp = z__[ii] / (work[ii] * delta[ii]);
+   23373           0 :         dw = dpsi + dphi + temp * temp;
+   23374           0 :         temp = z__[ii] * temp;
+   23375           0 :         w = rhoinv + phi + psi + temp;
+   23376           0 :         erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. + 
+   23377           0 :                 std::abs(tau) * dw;
+   23378             : 
+   23379           0 :         if (w <= 0.) {
+   23380           0 :             sg2lb = (sg2lb > tau) ? sg2lb : tau;
+   23381             :         } else {
+   23382           0 :             sg2ub = (sg2ub < tau) ? sg2ub : tau;
+   23383             :         }
+   23384             : 
+   23385             :         swtch = 0;
+   23386           0 :         if (orgati) {
+   23387           0 :             if (-w > std::abs(prew) / 10.) {
+   23388             :                 swtch = 1;
+   23389             :             }
+   23390             :         } else {
+   23391           0 :             if (w > std::abs(prew) / 10.) {
+   23392             :                 swtch = 1;
+   23393             :             }
+   23394             :         }
+   23395             : 
+   23396           0 :         iter = niter + 1;
+   23397             : 
+   23398           0 :         for (niter = iter; niter <= 20; ++niter) {
+   23399             : 
+   23400           0 :             if (std::abs(w) <= eps * erretm) {
+   23401           0 :                 goto L240;
+   23402             :             }
+   23403             : 
+   23404           0 :             if (! swtch3) {
+   23405           0 :                 dtipsq = work[ip1] * delta[ip1];
+   23406           0 :                 dtisq = work[*i__] * delta[*i__];
+   23407           0 :                 if (! swtch) {
+   23408           0 :                     if (orgati) {
+   23409           0 :                         d__1 = z__[*i__] / dtisq;
+   23410           0 :                         c__ = w - dtipsq * dw + delsq * (d__1 * d__1);
+   23411             :                     } else {
+   23412           0 :                         d__1 = z__[ip1] / dtipsq;
+   23413           0 :                         c__ = w - dtisq * dw - delsq * (d__1 * d__1);
+   23414             :                     }
+   23415             :                 } else {
+   23416           0 :                     temp = z__[ii] / (work[ii] * delta[ii]);
+   23417           0 :                     if (orgati) {
+   23418           0 :                         dpsi += temp * temp;
+   23419             :                     } else {
+   23420           0 :                         dphi += temp * temp;
+   23421             :                     }
+   23422           0 :                     c__ = w - dtisq * dpsi - dtipsq * dphi;
+   23423             :                 }
+   23424           0 :                 a = (dtipsq + dtisq) * w - dtipsq * dtisq * dw;
+   23425           0 :                 b = dtipsq * dtisq * w;
+   23426           0 :                 if (std::abs(c__)<PLUMED_GMX_FLOAT_MIN) {
+   23427           0 :                     if (std::abs(a)<PLUMED_GMX_FLOAT_MIN) {
+   23428           0 :                         if (! swtch) {
+   23429           0 :                             if (orgati) {
+   23430           0 :                                 a = z__[*i__] * z__[*i__] + dtipsq * dtipsq * 
+   23431           0 :                                         (dpsi + dphi);
+   23432             :                             } else {
+   23433           0 :                                 a = z__[ip1] * z__[ip1] + dtisq * dtisq * (
+   23434           0 :                                         dpsi + dphi);
+   23435             :                             }
+   23436             :                         } else {
+   23437           0 :                             a = dtisq * dtisq * dpsi + dtipsq * dtipsq * dphi;
+   23438             :                         }
+   23439             :                     }
+   23440           0 :                     eta = b / a;
+   23441           0 :                 } else if (a <= 0.) {
+   23442           0 :                   eta = (a -  std::sqrt(std::abs(a * a - b * 4. * c__))) / (c__ * 2.);
+   23443             :                 } else {
+   23444           0 :                   eta = b * 2. / (a +  std::sqrt(std::abs(a * a - b * 4. * c__)));
+   23445             :                 }
+   23446             :             } else {
+   23447             : 
+   23448           0 :                 dtiim = work[iim1] * delta[iim1];
+   23449           0 :                 dtiip = work[iip1] * delta[iip1];
+   23450           0 :                 temp = rhoinv + psi + phi;
+   23451           0 :                 if (swtch) {
+   23452           0 :                     c__ = temp - dtiim * dpsi - dtiip * dphi;
+   23453           0 :                     zz[0] = dtiim * dtiim * dpsi;
+   23454           0 :                     zz[2] = dtiip * dtiip * dphi;
+   23455             :                 } else {
+   23456           0 :                     if (orgati) {
+   23457           0 :                         temp1 = z__[iim1] / dtiim;
+   23458           0 :                         temp1 *= temp1;
+   23459           0 :                         temp2 = (d__[iim1] - d__[iip1]) * (d__[iim1] + d__[
+   23460             :                                 iip1]) * temp1;
+   23461           0 :                         c__ = temp - dtiip * (dpsi + dphi) - temp2;
+   23462           0 :                         zz[0] = z__[iim1] * z__[iim1];
+   23463           0 :                         if (dpsi < temp1) {
+   23464           0 :                             zz[2] = dtiip * dtiip * dphi;
+   23465             :                         } else {
+   23466           0 :                             zz[2] = dtiip * dtiip * (dpsi - temp1 + dphi);
+   23467             :                         }
+   23468             :                     } else {
+   23469           0 :                         temp1 = z__[iip1] / dtiip;
+   23470           0 :                         temp1 *= temp1;
+   23471           0 :                         temp2 = (d__[iip1] - d__[iim1]) * (d__[iim1] + d__[
+   23472             :                                 iip1]) * temp1;
+   23473           0 :                         c__ = temp - dtiim * (dpsi + dphi) - temp2;
+   23474           0 :                         if (dphi < temp1) {
+   23475           0 :                             zz[0] = dtiim * dtiim * dpsi;
+   23476             :                         } else {
+   23477           0 :                             zz[0] = dtiim * dtiim * (dpsi + (dphi - temp1));
+   23478             :                         }
+   23479           0 :                         zz[2] = z__[iip1] * z__[iip1];
+   23480             :                     }
+   23481             :                 }
+   23482           0 :                 dd[0] = dtiim;
+   23483           0 :                 dd[1] = delta[ii] * work[ii];
+   23484           0 :                 dd[2] = dtiip;
+   23485           0 :                 PLUMED_BLAS_F77_FUNC(slaed6,SLAED6)(&niter, &orgati, &c__, dd, zz, &w, &eta, info);
+   23486           0 :                 if (*info != 0) {
+   23487           0 :                     goto L240;
+   23488             :                 }
+   23489             :             }
+   23490             : 
+   23491           0 :             if (w * eta >= 0.) {
+   23492           0 :                 eta = -w / dw;
+   23493             :             }
+   23494           0 :             if (orgati) {
+   23495           0 :                 temp1 = work[*i__] * delta[*i__];
+   23496           0 :                 temp = eta - temp1;
+   23497             :             } else {
+   23498           0 :                 temp1 = work[ip1] * delta[ip1];
+   23499           0 :                 temp = eta - temp1;
+   23500             :             }
+   23501           0 :             if (temp > sg2ub || temp < sg2lb) {
+   23502           0 :                 if (w < 0.) {
+   23503           0 :                     eta = (sg2ub - tau) / 2.;
+   23504             :                 } else {
+   23505           0 :                     eta = (sg2lb - tau) / 2.;
+   23506             :                 }
+   23507             :             }
+   23508             : 
+   23509           0 :             tau += eta;
+   23510           0 :             eta /= *sigma +  std::sqrt(*sigma * *sigma + eta);
+   23511             : 
+   23512           0 :             *sigma += eta;
+   23513           0 :             i__1 = *n;
+   23514           0 :             for (j = 1; j <= i__1; ++j) {
+   23515           0 :                 work[j] += eta;
+   23516           0 :                 delta[j] -= eta;
+   23517             :             }
+   23518             : 
+   23519             :             prew = w;
+   23520             : 
+   23521             :             dpsi = 0.;
+   23522             :             psi = 0.;
+   23523             :             erretm = 0.;
+   23524             :             i__1 = iim1;
+   23525           0 :             for (j = 1; j <= i__1; ++j) {
+   23526           0 :                 temp = z__[j] / (work[j] * delta[j]);
+   23527           0 :                 psi += z__[j] * temp;
+   23528           0 :                 dpsi += temp * temp;
+   23529           0 :                 erretm += psi;
+   23530             :             }
+   23531             :             erretm = std::abs(erretm);
+   23532             : 
+   23533             :             dphi = 0.;
+   23534             :             phi = 0.;
+   23535             :             i__1 = iip1;
+   23536           0 :             for (j = *n; j >= i__1; --j) {
+   23537           0 :                 temp = z__[j] / (work[j] * delta[j]);
+   23538           0 :                 phi += z__[j] * temp;
+   23539           0 :                 dphi += temp * temp;
+   23540           0 :                 erretm += phi;
+   23541             :             }
+   23542             : 
+   23543           0 :             temp = z__[ii] / (work[ii] * delta[ii]);
+   23544           0 :             dw = dpsi + dphi + temp * temp;
+   23545           0 :             temp = z__[ii] * temp;
+   23546           0 :             w = rhoinv + phi + psi + temp;
+   23547           0 :             erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + std::abs(temp) * 3. 
+   23548           0 :                     + std::abs(tau) * dw;
+   23549           0 :             if (w * prew > 0. && std::abs(w) > std::abs(prew) / 10.) {
+   23550           0 :                 swtch = ! swtch;
+   23551             :             }
+   23552             : 
+   23553           0 :             if (w <= 0.) {
+   23554           0 :                 sg2lb = (sg2lb > tau) ? sg2lb : tau;
+   23555             :             } else {
+   23556           0 :                 sg2ub = (sg2ub < tau) ? sg2ub : tau;
+   23557             :             }
+   23558             :         }
+   23559             : 
+   23560           0 :         *info = 1;
+   23561             : 
+   23562             :     }
+   23563             : 
+   23564           0 : L240:
+   23565             :     return;
+   23566             : 
+   23567             : } 
+   23568             : }
+   23569             : }
+   23570             : #include <cmath>
+   23571             : #include "lapack.h"
+   23572             : 
+   23573             : #include "blas/blas.h"
+   23574             : namespace PLMD{
+   23575             : namespace lapack{
+   23576             : using namespace blas;
+   23577             : void 
+   23578           0 : PLUMED_BLAS_F77_FUNC(slasd5,SLASD5)(int *i__, 
+   23579             :         float *d__, 
+   23580             :         float *z__, 
+   23581             :         float *delta, 
+   23582             :         float *rho, 
+   23583             :         float *dsigma, 
+   23584             :         float *work)
+   23585             : {
+   23586             :     float b, c__, w, del, tau, delsq;
+   23587             : 
+   23588             :     --work;
+   23589             :     --delta;
+   23590             :     --z__;
+   23591             :     --d__;
+   23592             : 
+   23593           0 :     del = d__[2] - d__[1];
+   23594           0 :     delsq = del * (d__[2] + d__[1]);
+   23595           0 :     if (*i__ == 1) {
+   23596           0 :         w = *rho * 4. * (z__[2] * z__[2] / (d__[1] + d__[2] * 3.) - z__[1] * 
+   23597           0 :                 z__[1] / (d__[1] * 3. + d__[2])) / del + 1.;
+   23598           0 :         if (w > 0.) {
+   23599           0 :             b = delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+   23600           0 :             c__ = *rho * z__[1] * z__[1] * delsq;
+   23601             : 
+   23602           0 :             tau = c__ * 2. / (b +  std::sqrt(std::abs(b * b - c__ * 4.)));
+   23603             : 
+   23604           0 :             tau /= d__[1] +  std::sqrt(d__[1] * d__[1] + tau);
+   23605           0 :             *dsigma = d__[1] + tau;
+   23606           0 :             delta[1] = -tau;
+   23607           0 :             delta[2] = del - tau;
+   23608           0 :             work[1] = d__[1] * 2. + tau;
+   23609           0 :             work[2] = d__[1] + tau + d__[2];
+   23610             :         } else {
+   23611           0 :             b = -delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+   23612           0 :             c__ = *rho * z__[2] * z__[2] * delsq;
+   23613             : 
+   23614           0 :             if (b > 0.) {
+   23615           0 :                 tau = c__ * -2. / (b +  std::sqrt(b * b + c__ * 4.));
+   23616             :             } else {
+   23617           0 :                 tau = (b -  std::sqrt(b * b + c__ * 4.)) / 2.;
+   23618             :             }
+   23619             : 
+   23620           0 :             tau /= d__[2] +  std::sqrt(std::abs(d__[2] * d__[2] + tau));
+   23621           0 :             *dsigma = d__[2] + tau;
+   23622           0 :             delta[1] = -(del + tau);
+   23623           0 :             delta[2] = -tau;
+   23624           0 :             work[1] = d__[1] + tau + d__[2];
+   23625           0 :             work[2] = d__[2] * 2. + tau;
+   23626             :         }
+   23627             :     } else {
+   23628             : 
+   23629           0 :         b = -delsq + *rho * (z__[1] * z__[1] + z__[2] * z__[2]);
+   23630           0 :         c__ = *rho * z__[2] * z__[2] * delsq;
+   23631             : 
+   23632           0 :         if (b > 0.) {
+   23633           0 :             tau = (b +  std::sqrt(b * b + c__ * 4.)) / 2.;
+   23634             :         } else {
+   23635           0 :             tau = c__ * 2. / (-b +  std::sqrt(b * b + c__ * 4.));
+   23636             :         }
+   23637           0 :         tau /= d__[2] +  std::sqrt(d__[2] * d__[2] + tau);
+   23638           0 :         *dsigma = d__[2] + tau;
+   23639           0 :         delta[1] = -(del + tau);
+   23640           0 :         delta[2] = -tau;
+   23641           0 :         work[1] = d__[1] + tau + d__[2];
+   23642           0 :         work[2] = d__[2] * 2. + tau;
+   23643             :     }
+   23644           0 :     return;
+   23645             : 
+   23646             : } 
+   23647             : }
+   23648             : }
+   23649             : #include <cmath>
+   23650             : #include "blas/blas.h"
+   23651             : #include "lapack.h"
+   23652             : 
+   23653             : #include "blas/blas.h"
+   23654             : namespace PLMD{
+   23655             : namespace lapack{
+   23656             : using namespace blas;
+   23657             : void 
+   23658           0 : PLUMED_BLAS_F77_FUNC(slasd6,SLASD6)(int *icompq, 
+   23659             :         int *nl, 
+   23660             :         int *nr, 
+   23661             :         int *sqre, 
+   23662             :         float *d__, 
+   23663             :         float *vf, 
+   23664             :         float *vl, 
+   23665             :         float *alpha, 
+   23666             :         float *beta, 
+   23667             :         int *idxq, 
+   23668             :         int *perm, 
+   23669             :         int *givptr, 
+   23670             :         int *givcol, 
+   23671             :         int *ldgcol, 
+   23672             :         float *givnum,
+   23673             :         int *ldgnum, 
+   23674             :         float *poles, 
+   23675             :         float *difl, 
+   23676             :         float *difr, 
+   23677             :         float *z__, 
+   23678             :         int *k, 
+   23679             :         float *c__, 
+   23680             :         float *s, 
+   23681             :         float *work, 
+   23682             :         int *iwork, 
+   23683             :         int *info)
+   23684             : {
+   23685             :     int givcol_dim1, givcol_offset, givnum_dim1, givnum_offset, 
+   23686             :             poles_dim1, poles_offset, i__1;
+   23687             :     float d__1, d__2;
+   23688             : 
+   23689             :     int i__, m, n, n1, n2, iw, idx, idxc, idxp, ivfw, ivlw;
+   23690             :     int isigma;
+   23691             :     float orgnrm;
+   23692           0 :     int c__0 = 0;
+   23693           0 :     float one = 1.0;
+   23694           0 :     int c__1 = 1;
+   23695           0 :     int c_n1 = -1;
+   23696             : 
+   23697           0 :     --d__;
+   23698             :     --vf;
+   23699             :     --vl;
+   23700             :     --idxq;
+   23701             :     --perm;
+   23702             :     givcol_dim1 = *ldgcol;
+   23703             :     givcol_offset = 1 + givcol_dim1;
+   23704             :     givcol -= givcol_offset;
+   23705           0 :     poles_dim1 = *ldgnum;
+   23706           0 :     poles_offset = 1 + poles_dim1;
+   23707           0 :     poles -= poles_offset;
+   23708             :     givnum_dim1 = *ldgnum;
+   23709             :     givnum_offset = 1 + givnum_dim1;
+   23710             :     givnum -= givnum_offset;
+   23711             :     --difl;
+   23712             :     --difr;
+   23713             :     --z__;
+   23714           0 :     --work;
+   23715             :     --iwork;
+   23716             : 
+   23717           0 :     *info = 0;
+   23718           0 :     n = *nl + *nr + 1;
+   23719           0 :     m = n + *sqre;
+   23720             : 
+   23721             :     isigma = 1;
+   23722           0 :     iw = isigma + n;
+   23723           0 :     ivfw = iw + m;
+   23724           0 :     ivlw = ivfw + m;
+   23725             : 
+   23726             :     idx = 1;
+   23727             :     idxc = idx + n;
+   23728           0 :     idxp = idxc + n;
+   23729             : 
+   23730           0 :     d__1 = std::abs(*alpha); 
+   23731           0 :     d__2 = std::abs(*beta);
+   23732           0 :     orgnrm = (d__1 > d__2) ? d__1 : d__2;
+   23733           0 :     d__[*nl + 1] = 0.;
+   23734             :     i__1 = n;
+   23735           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   23736           0 :       d__1 = std::abs(d__[i__]);
+   23737           0 :         if (d__1 > orgnrm)
+   23738           0 :             orgnrm = d__1;
+   23739             :     }
+   23740           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &orgnrm, &one, &n, &c__1, &d__[1], &n, info);
+   23741           0 :     *alpha /= orgnrm;
+   23742           0 :     *beta /= orgnrm;
+   23743             : 
+   23744           0 :     PLUMED_BLAS_F77_FUNC(slasd7,SLASD7)(icompq, nl, nr, sqre, k, &d__[1], &z__[1], &work[iw], &vf[1], &
+   23745           0 :             work[ivfw], &vl[1], &work[ivlw], alpha, beta, &work[isigma], &
+   23746           0 :             iwork[idx], &iwork[idxp], &idxq[1], &perm[1], givptr, &givcol[
+   23747             :             givcol_offset], ldgcol, &givnum[givnum_offset], ldgnum, c__, s, 
+   23748             :             info);
+   23749             : 
+   23750           0 :     PLUMED_BLAS_F77_FUNC(slasd8,SLASD8)(icompq, k, &d__[1], &z__[1], &vf[1], &vl[1], &difl[1], &difr[1], 
+   23751             :             ldgnum, &work[isigma], &work[iw], info);
+   23752             : 
+   23753           0 :     if (*icompq == 1) {
+   23754           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &d__[1], &c__1, &poles[poles_dim1 + 1], &c__1);
+   23755           0 :         PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &work[isigma], &c__1, &poles[(poles_dim1 << 1) + 1], &c__1);
+   23756             :     }
+   23757             : 
+   23758           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &one, &orgnrm, &n, &c__1, &d__[1], &n, info);
+   23759             : 
+   23760           0 :     n1 = *k;
+   23761           0 :     n2 = n - *k;
+   23762           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(&n1, &n2, &d__[1], &c__1, &c_n1, &idxq[1]);
+   23763             : 
+   23764           0 :     return;
+   23765             : 
+   23766             : }
+   23767             : 
+   23768             : 
+   23769             : }
+   23770             : }
+   23771             : #include <cmath>
+   23772             : #include "real.h"
+   23773             : 
+   23774             : #include "blas/blas.h"
+   23775             : #include "lapack.h"
+   23776             : #include "lapack_limits.h"
+   23777             : 
+   23778             : #include "blas/blas.h"
+   23779             : namespace PLMD{
+   23780             : namespace lapack{
+   23781             : using namespace blas;
+   23782             : void 
+   23783           0 : PLUMED_BLAS_F77_FUNC(slasd7,SLASD7)(int *icompq, 
+   23784             :         int *nl, 
+   23785             :         int *nr, 
+   23786             :         int *sqre, 
+   23787             :         int *k, 
+   23788             :         float *d__, 
+   23789             :         float *z__, 
+   23790             :         float *zw, 
+   23791             :         float *vf, 
+   23792             :         float *vfw,
+   23793             :         float *vl, 
+   23794             :         float *vlw,
+   23795             :         float *alpha, 
+   23796             :         float *beta,
+   23797             :         float *dsigma, 
+   23798             :         int *idx, 
+   23799             :         int *idxp,
+   23800             :         int *idxq, 
+   23801             :         int *perm, 
+   23802             :         int *givptr,
+   23803             :         int *givcol, 
+   23804             :         int *ldgcol, 
+   23805             :         float *givnum,
+   23806             :         int *ldgnum, 
+   23807             :         float *c__, 
+   23808             :         float *s, 
+   23809             :         int *info)
+   23810             : {
+   23811             :     int givcol_dim1, givcol_offset, givnum_dim1, givnum_offset, i__1;
+   23812             :     float d__1, d__2;
+   23813             : 
+   23814             :     int i__, j, m, n, k2;
+   23815             :     float z1;
+   23816             :     int jp;
+   23817             :     float eps, tau, tol;
+   23818             :     int nlp1, nlp2, idxi, idxj;
+   23819             :     int idxjp;
+   23820             :     int jprev = 0;
+   23821             :     float hlftol;
+   23822           0 :     int c__1 = 1;
+   23823             : 
+   23824           0 :     --d__;
+   23825           0 :     --z__;
+   23826           0 :     --zw;
+   23827           0 :     --vf;
+   23828           0 :     --vfw;
+   23829           0 :     --vl;
+   23830           0 :     --vlw;
+   23831           0 :     --dsigma;
+   23832           0 :     --idx;
+   23833           0 :     --idxp;
+   23834           0 :     --idxq;
+   23835           0 :     --perm;
+   23836           0 :     givcol_dim1 = *ldgcol;
+   23837           0 :     givcol_offset = 1 + givcol_dim1;
+   23838           0 :     givcol -= givcol_offset;
+   23839           0 :     givnum_dim1 = *ldgnum;
+   23840           0 :     givnum_offset = 1 + givnum_dim1;
+   23841           0 :     givnum -= givnum_offset;
+   23842             : 
+   23843           0 :     *info = 0;
+   23844           0 :     n = *nl + *nr + 1;
+   23845           0 :     m = n + *sqre;
+   23846             : 
+   23847           0 :     nlp1 = *nl + 1;
+   23848           0 :     nlp2 = *nl + 2;
+   23849           0 :     if (*icompq == 1) {
+   23850           0 :         *givptr = 0;
+   23851             :     }
+   23852             : 
+   23853           0 :     z1 = *alpha * vl[nlp1];
+   23854           0 :     vl[nlp1] = 0.;
+   23855           0 :     tau = vf[nlp1];
+   23856           0 :     for (i__ = *nl; i__ >= 1; --i__) {
+   23857           0 :         z__[i__ + 1] = *alpha * vl[i__];
+   23858           0 :         vl[i__] = 0.;
+   23859           0 :         vf[i__ + 1] = vf[i__];
+   23860           0 :         d__[i__ + 1] = d__[i__];
+   23861           0 :         idxq[i__ + 1] = idxq[i__] + 1;
+   23862             :     }
+   23863           0 :     vf[1] = tau;
+   23864             : 
+   23865             :     i__1 = m;
+   23866           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   23867           0 :         z__[i__] = *beta * vf[i__];
+   23868           0 :         vf[i__] = 0.;
+   23869             :     }
+   23870           0 :     i__1 = n;
+   23871           0 :     for (i__ = nlp2; i__ <= i__1; ++i__) {
+   23872           0 :         idxq[i__] += nlp1;
+   23873             :     }
+   23874             : 
+   23875             :     i__1 = n;
+   23876           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   23877           0 :         dsigma[i__] = d__[idxq[i__]];
+   23878           0 :         zw[i__] = z__[idxq[i__]];
+   23879           0 :         vfw[i__] = vf[idxq[i__]];
+   23880           0 :         vlw[i__] = vl[idxq[i__]];
+   23881             :     }
+   23882             : 
+   23883           0 :     PLUMED_BLAS_F77_FUNC(slamrg,SLAMRG)(nl, nr, &dsigma[2], &c__1, &c__1, &idx[2]);
+   23884             : 
+   23885           0 :     i__1 = n;
+   23886           0 :     for (i__ = 2; i__ <= i__1; ++i__) {
+   23887           0 :         idxi = idx[i__] + 1;
+   23888           0 :         d__[i__] = dsigma[idxi];
+   23889           0 :         z__[i__] = zw[idxi];
+   23890           0 :         vf[i__] = vfw[idxi];
+   23891           0 :         vl[i__] = vlw[idxi];
+   23892             :     }
+   23893             : 
+   23894             :     eps = PLUMED_GMX_FLOAT_EPS;
+   23895             : 
+   23896           0 :     d__1 = std::abs(*alpha);
+   23897           0 :     d__2 = std::abs(*beta);
+   23898           0 :     tol = (d__1>d__2) ? d__1 : d__2;
+   23899           0 :     d__2 = std::abs(d__[n]);
+   23900           0 :     tol = eps * 64. * ((d__2>tol) ? d__2 : tol);
+   23901             : 
+   23902           0 :     *k = 1;
+   23903           0 :     k2 = n + 1;
+   23904             :     i__1 = n;
+   23905           0 :     for (j = 2; j <= i__1; ++j) {
+   23906           0 :         if (std::abs(z__[j]) <= tol) {
+   23907             : 
+   23908           0 :             --k2;
+   23909           0 :             idxp[k2] = j;
+   23910           0 :             if (j == n) {
+   23911           0 :                 goto L100;
+   23912             :             }
+   23913             :         } else {
+   23914             :             jprev = j;
+   23915           0 :             goto L70;
+   23916             :         }
+   23917             :     }
+   23918           0 : L70:
+   23919             :     j = jprev;
+   23920           0 : L80:
+   23921           0 :     ++j;
+   23922           0 :     if (j > n) {
+   23923           0 :         goto L90;
+   23924             :     }
+   23925           0 :     if (std::abs(z__[j]) <= tol) {
+   23926             : 
+   23927           0 :         --k2;
+   23928           0 :         idxp[k2] = j;
+   23929             :     } else {
+   23930             : 
+   23931           0 :         if (std::abs(d__[j] - d__[jprev]) <= tol) {
+   23932             : 
+   23933           0 :             *s = z__[jprev];
+   23934           0 :             *c__ = z__[j];
+   23935             : 
+   23936           0 :             tau = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(c__, s);
+   23937           0 :             z__[j] = tau;
+   23938           0 :             z__[jprev] = 0.;
+   23939           0 :             *c__ /= tau;
+   23940           0 :             *s = -(*s) / tau;
+   23941             : 
+   23942             : 
+   23943           0 :             if (*icompq == 1) {
+   23944           0 :                 ++(*givptr);
+   23945           0 :                 idxjp = idxq[idx[jprev] + 1];
+   23946           0 :                 idxj = idxq[idx[j] + 1];
+   23947           0 :                 if (idxjp <= nlp1) {
+   23948           0 :                     --idxjp;
+   23949             :                 }
+   23950           0 :                 if (idxj <= nlp1) {
+   23951           0 :                     --idxj;
+   23952             :                 }
+   23953           0 :                 givcol[*givptr + (givcol_dim1 << 1)] = idxjp;
+   23954           0 :                 givcol[*givptr + givcol_dim1] = idxj;
+   23955           0 :                 givnum[*givptr + (givnum_dim1 << 1)] = *c__;
+   23956           0 :                 givnum[*givptr + givnum_dim1] = *s;
+   23957             :             }
+   23958           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vf[jprev], &c__1, &vf[j], &c__1, c__, s);
+   23959           0 :             PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vl[jprev], &c__1, &vl[j], &c__1, c__, s);
+   23960           0 :             --k2;
+   23961           0 :             idxp[k2] = jprev;
+   23962             :             jprev = j;
+   23963             :         } else {
+   23964           0 :             ++(*k);
+   23965           0 :             zw[*k] = z__[jprev];
+   23966           0 :             dsigma[*k] = d__[jprev];
+   23967           0 :             idxp[*k] = jprev;
+   23968             :             jprev = j;
+   23969             :         }
+   23970             :     }
+   23971           0 :     goto L80;
+   23972             : L90:
+   23973             : 
+   23974           0 :     ++(*k);
+   23975           0 :     zw[*k] = z__[jprev];
+   23976           0 :     dsigma[*k] = d__[jprev];
+   23977           0 :     idxp[*k] = jprev;
+   23978             : 
+   23979           0 : L100:
+   23980             : 
+   23981           0 :     i__1 = n;
+   23982           0 :     for (j = 2; j <= i__1; ++j) {
+   23983           0 :         jp = idxp[j];
+   23984           0 :         dsigma[j] = d__[jp];
+   23985           0 :         vfw[j] = vf[jp];
+   23986           0 :         vlw[j] = vl[jp];
+   23987             :     }
+   23988           0 :     if (*icompq == 1) {
+   23989             :         i__1 = n;
+   23990           0 :         for (j = 2; j <= i__1; ++j) {
+   23991           0 :             jp = idxp[j];
+   23992           0 :             perm[j] = idxq[idx[jp] + 1];
+   23993           0 :             if (perm[j] <= nlp1) {
+   23994           0 :                 --perm[j];
+   23995             :             }
+   23996             :         }
+   23997             :     }
+   23998           0 :     i__1 = n - *k;
+   23999           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &dsigma[*k + 1], &c__1, &d__[*k + 1], &c__1);
+   24000             : 
+   24001           0 :     dsigma[1] = 0.;
+   24002           0 :     hlftol = tol / 2.;
+   24003           0 :     if (std::abs(dsigma[2]) <= hlftol) {
+   24004           0 :         dsigma[2] = hlftol;
+   24005             :     }
+   24006           0 :     if (m > n) {
+   24007           0 :         z__[1] = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&z1, &z__[m]);
+   24008           0 :         if (z__[1] <= tol) {
+   24009           0 :             *c__ = 1.;
+   24010           0 :             *s = 0.;
+   24011           0 :             z__[1] = tol;
+   24012             :         } else {
+   24013           0 :             *c__ = z1 / z__[1];
+   24014           0 :             *s = -z__[m] / z__[1];
+   24015             :         }
+   24016           0 :         PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vf[m], &c__1, &vf[1], &c__1, c__, s);
+   24017           0 :         PLUMED_BLAS_F77_FUNC(srot,SROT)(&c__1, &vl[m], &c__1, &vl[1], &c__1, c__, s);
+   24018             :     } else {
+   24019           0 :         if (std::abs(z1) <= tol) {
+   24020           0 :             z__[1] = tol;
+   24021             :         } else {
+   24022           0 :             z__[1] = z1;
+   24023             :         }
+   24024             :     }
+   24025             : 
+   24026           0 :     i__1 = *k - 1;
+   24027           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &zw[2], &c__1, &z__[2], &c__1);
+   24028           0 :     i__1 = n - 1;
+   24029           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &vfw[2], &c__1, &vf[2], &c__1);
+   24030           0 :     i__1 = n - 1;
+   24031           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &vlw[2], &c__1, &vl[2], &c__1);
+   24032             : 
+   24033           0 :     return;
+   24034             : 
+   24035             : }
+   24036             : 
+   24037             : 
+   24038             : }
+   24039             : }
+   24040             : #include <cmath>
+   24041             : #include "blas/blas.h"
+   24042             : #include "lapack.h"
+   24043             : 
+   24044             : #include "blas/blas.h"
+   24045             : namespace PLMD{
+   24046             : namespace lapack{
+   24047             : using namespace blas;
+   24048             : void 
+   24049           0 : PLUMED_BLAS_F77_FUNC(slasd8,SLASD8)(int *icompq, 
+   24050             :         int *k, 
+   24051             :         float *d__, 
+   24052             :         float *z__, 
+   24053             :         float *vf, 
+   24054             :         float *vl, 
+   24055             :         float *difl, 
+   24056             :         float *difr, 
+   24057             :         int *lddifr, 
+   24058             :         float *dsigma, 
+   24059             :         float *work, 
+   24060             :         int *info)
+   24061             : {
+   24062             :     int difr_dim1, difr_offset, i__1, i__2;
+   24063             :     float d__2;
+   24064             : 
+   24065             :     int i__, j;
+   24066             :     float dj, rho;
+   24067             :     int iwk1, iwk2, iwk3;
+   24068             :     float temp;
+   24069             :     int iwk2i, iwk3i;
+   24070             :     float diflj, difrj, dsigj;
+   24071             :     float dsigjp;
+   24072           0 :     int c__1 = 1;
+   24073           0 :     int c__0 = 0;
+   24074           0 :     float one = 1.;
+   24075             : 
+   24076             :     /* avoid warnings on high gcc optimization levels */
+   24077             :     difrj = dsigjp = 0;
+   24078             : 
+   24079           0 :      --d__;
+   24080           0 :     --z__;
+   24081             :     --vf;
+   24082             :     --vl;
+   24083           0 :     --difl;
+   24084           0 :     difr_dim1 = *lddifr;
+   24085           0 :     difr_offset = 1 + difr_dim1;
+   24086           0 :     difr -= difr_offset;
+   24087           0 :     --dsigma;
+   24088           0 :     --work;
+   24089             : 
+   24090           0 :     *info = 0;
+   24091             : 
+   24092           0 :     if (*k == 1) {
+   24093           0 :         d__[1] = std::abs(z__[1]);
+   24094           0 :         difl[1] = d__[1];
+   24095           0 :         if (*icompq == 1) {
+   24096           0 :             difl[2] = 1.;
+   24097           0 :             difr[(difr_dim1 << 1) + 1] = 1.;
+   24098             :         }
+   24099           0 :         return;
+   24100             :     }
+   24101             : 
+   24102             :     iwk1 = 1;
+   24103           0 :     iwk2 = iwk1 + *k;
+   24104           0 :     iwk3 = iwk2 + *k;
+   24105             :     iwk2i = iwk2 - 1;
+   24106           0 :     iwk3i = iwk3 - 1;
+   24107             : 
+   24108           0 :     rho = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &z__[1], &c__1);
+   24109           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &rho, &one, k, &c__1, &z__[1], k, info);
+   24110           0 :     rho *= rho;
+   24111             : 
+   24112           0 :     PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", k, &c__1, &one, &one, &work[iwk3], k);
+   24113             : 
+   24114           0 :     i__1 = *k;
+   24115           0 :     for (j = 1; j <= i__1; ++j) {
+   24116           0 :         PLUMED_BLAS_F77_FUNC(slasd4,SLASD4)(k, &j, &dsigma[1], &z__[1], &work[iwk1], &rho, &d__[j], &work[
+   24117           0 :                 iwk2], info);
+   24118             : 
+   24119           0 :         if (*info != 0) {
+   24120             :             return;
+   24121             :         }
+   24122           0 :         work[iwk3i + j] = work[iwk3i + j] * work[j] * work[iwk2i + j];
+   24123           0 :         difl[j] = -work[j];
+   24124           0 :         difr[j + difr_dim1] = -work[j + 1];
+   24125             :         i__2 = j - 1;
+   24126           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   24127           0 :             work[iwk3i + i__] = work[iwk3i + i__] * work[i__] * work[iwk2i + 
+   24128           0 :                     i__] / (dsigma[i__] - dsigma[j]) / (dsigma[i__] + dsigma[
+   24129             :                     j]);
+   24130             :         }
+   24131           0 :         i__2 = *k;
+   24132           0 :         for (i__ = j + 1; i__ <= i__2; ++i__) {
+   24133           0 :             work[iwk3i + i__] = work[iwk3i + i__] * work[i__] * work[iwk2i + 
+   24134           0 :                     i__] / (dsigma[i__] - dsigma[j]) / (dsigma[i__] + dsigma[
+   24135             :                     j]);
+   24136             :         }
+   24137             :     }
+   24138             : 
+   24139           0 :     i__1 = *k;
+   24140           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   24141           0 :         d__2 =  std::sqrt(std::abs(work[iwk3i + i__]));
+   24142           0 :         z__[i__] = (z__[i__] > 0) ? d__2 : -d__2;
+   24143             :     }
+   24144             : 
+   24145           0 :     i__1 = *k;
+   24146           0 :     for (j = 1; j <= i__1; ++j) {
+   24147           0 :         diflj = difl[j];
+   24148           0 :         dj = d__[j];
+   24149           0 :         dsigj = -dsigma[j];
+   24150           0 :         if (j < *k) {
+   24151           0 :             difrj = -difr[j + difr_dim1];
+   24152           0 :             dsigjp = -dsigma[j + 1];
+   24153             :         }
+   24154           0 :         work[j] = -z__[j] / diflj / (dsigma[j] + dj);
+   24155             :         i__2 = j - 1;
+   24156           0 :         for (i__ = 1; i__ <= i__2; ++i__) {
+   24157           0 :           work[i__] = z__[i__] / (dsigma[i__] + dsigj - diflj) / ( dsigma[i__] + dj);
+   24158             :         }
+   24159           0 :         i__2 = *k;
+   24160           0 :         for (i__ = j + 1; i__ <= i__2; ++i__) {
+   24161           0 :             work[i__] = z__[i__] / (dsigma[i__] + dsigjp - difrj) / (dsigma[i__] + dj);
+   24162             :         }
+   24163           0 :         temp = PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(k, &work[1], &c__1);
+   24164           0 :         work[iwk2i + j] = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(k, &work[1], &c__1, &vf[1], &c__1) / temp;
+   24165           0 :         work[iwk3i + j] = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(k, &work[1], &c__1, &vl[1], &c__1) / temp;
+   24166           0 :         if (*icompq == 1) {
+   24167           0 :             difr[j + (difr_dim1 << 1)] = temp;
+   24168             :         }
+   24169             :     }
+   24170             : 
+   24171           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &work[iwk2], &c__1, &vf[1], &c__1);
+   24172           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(k, &work[iwk3], &c__1, &vl[1], &c__1);
+   24173             : 
+   24174             :     return;
+   24175             : 
+   24176             : } 
+   24177             : }
+   24178             : }
+   24179             : #include "blas/blas.h"
+   24180             : #include "lapack.h"
+   24181             : 
+   24182             : #include "blas/blas.h"
+   24183             : namespace PLMD{
+   24184             : namespace lapack{
+   24185             : using namespace blas;
+   24186             : void 
+   24187           0 : PLUMED_BLAS_F77_FUNC(slasda,SLASDA)(int *icompq, 
+   24188             :         int *smlsiz, 
+   24189             :         int *n, 
+   24190             :         int *sqre, 
+   24191             :         float *d__, 
+   24192             :         float *e, 
+   24193             :         float *u, 
+   24194             :         int *ldu, 
+   24195             :         float *vt, 
+   24196             :         int *k, 
+   24197             :         float *difl, 
+   24198             :         float *difr, 
+   24199             :         float *z__, 
+   24200             :         float *poles, 
+   24201             :         int *givptr, 
+   24202             :         int *givcol, 
+   24203             :         int *ldgcol, 
+   24204             :         int *perm, 
+   24205             :         float *givnum, 
+   24206             :         float *c__, 
+   24207             :         float *s, 
+   24208             :         float *work, 
+   24209             :         int *iwork, 
+   24210             :         int *info)
+   24211             : {
+   24212             :     int givcol_dim1, givcol_offset, perm_dim1, perm_offset, difl_dim1, 
+   24213             :             difl_offset, difr_dim1, difr_offset, givnum_dim1, givnum_offset, 
+   24214             :             poles_dim1, poles_offset, u_dim1, u_offset, vt_dim1, vt_offset, 
+   24215             :             z_dim1, z_offset, i__1, i__2;
+   24216             : 
+   24217             :     int i__, j, m, i1, ic, lf, nd, ll, nl, vf, nr, vl, im1, ncc, 
+   24218             :             nlf, nrf, vfi, iwk, vli, lvl, nru, ndb1, nlp1, lvl2, nrp1;
+   24219             :     float beta;
+   24220             :     int idxq, nlvl;
+   24221             :     float alpha;
+   24222             :     int inode, ndiml, ndimr, idxqi, itemp;
+   24223             :     int sqrei;
+   24224             :     int nwork1, nwork2;
+   24225             :     int smlszp;
+   24226           0 :     int c__0 = 0;
+   24227           0 :     float zero = 0.0;
+   24228           0 :     float one = 1.;
+   24229           0 :     int c__1 = 1;
+   24230           0 :     --d__;
+   24231           0 :     --e;
+   24232           0 :     givnum_dim1 = *ldu;
+   24233           0 :     givnum_offset = 1 + givnum_dim1;
+   24234           0 :     givnum -= givnum_offset;
+   24235             :     poles_dim1 = *ldu;
+   24236             :     poles_offset = 1 + poles_dim1;
+   24237             :     poles -= poles_offset;
+   24238             :     z_dim1 = *ldu;
+   24239             :     z_offset = 1 + z_dim1;
+   24240             :     z__ -= z_offset;
+   24241             :     difr_dim1 = *ldu;
+   24242             :     difr_offset = 1 + difr_dim1;
+   24243             :     difr -= difr_offset;
+   24244             :     difl_dim1 = *ldu;
+   24245             :     difl_offset = 1 + difl_dim1;
+   24246             :     difl -= difl_offset;
+   24247             :     vt_dim1 = *ldu;
+   24248             :     vt_offset = 1 + vt_dim1;
+   24249           0 :     vt -= vt_offset;
+   24250             :     u_dim1 = *ldu;
+   24251             :     u_offset = 1 + u_dim1;
+   24252           0 :     u -= u_offset;
+   24253             :     --k;
+   24254             :     --givptr;
+   24255           0 :     perm_dim1 = *ldgcol;
+   24256           0 :     perm_offset = 1 + perm_dim1;
+   24257           0 :     perm -= perm_offset;
+   24258             :     givcol_dim1 = *ldgcol;
+   24259             :     givcol_offset = 1 + givcol_dim1;
+   24260             :     givcol -= givcol_offset;
+   24261             :     --c__;
+   24262             :     --s;
+   24263           0 :     --work;
+   24264           0 :     --iwork;
+   24265           0 :     *info = 0;
+   24266             : 
+   24267           0 :     m = *n + *sqre;
+   24268             : 
+   24269           0 :     if (*n <= *smlsiz) {
+   24270           0 :         if (*icompq == 0) {
+   24271           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", sqre, n, &c__0, &c__0, &c__0, &d__[1], &e[1], &vt[
+   24272             :                     vt_offset], ldu, &u[u_offset], ldu, &u[u_offset], ldu, &
+   24273             :                     work[1], info);
+   24274             :         } else {
+   24275           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", sqre, n, &m, n, &c__0, &d__[1], &e[1], &vt[vt_offset]
+   24276             :                     , ldu, &u[u_offset], ldu, &u[u_offset], ldu, &work[1], 
+   24277             :                     info);
+   24278             :         }
+   24279           0 :         return;
+   24280             :     }
+   24281             : 
+   24282             :     inode = 1;
+   24283           0 :     ndiml = inode + *n;
+   24284           0 :     ndimr = ndiml + *n;
+   24285           0 :     idxq = ndimr + *n;
+   24286           0 :     iwk = idxq + *n;
+   24287             : 
+   24288           0 :     ncc = 0;
+   24289           0 :     nru = 0;
+   24290             : 
+   24291           0 :     smlszp = *smlsiz + 1;
+   24292             :     vf = 1;
+   24293           0 :     vl = vf + m;
+   24294           0 :     nwork1 = vl + m;
+   24295           0 :     nwork2 = nwork1 + smlszp * smlszp;
+   24296             : 
+   24297           0 :     PLUMED_BLAS_F77_FUNC(slasdt,SLASDT)(n, &nlvl, &nd, &iwork[inode], &iwork[ndiml], &iwork[ndimr], 
+   24298             :             smlsiz);
+   24299             : 
+   24300           0 :     ndb1 = (nd + 1) / 2;
+   24301             :     i__1 = nd;
+   24302           0 :     for (i__ = ndb1; i__ <= i__1; ++i__) {
+   24303           0 :         i1 = i__ - 1;
+   24304           0 :         ic = iwork[inode + i1];
+   24305           0 :         nl = iwork[ndiml + i1];
+   24306           0 :         nlp1 = nl + 1;
+   24307           0 :         nr = iwork[ndimr + i1];
+   24308           0 :         nlf = ic - nl;
+   24309           0 :         nrf = ic + 1;
+   24310           0 :         idxqi = idxq + nlf - 2;
+   24311             :         vfi = vf + nlf - 1;
+   24312           0 :         vli = vl + nlf - 1;
+   24313           0 :         sqrei = 1;
+   24314           0 :         if (*icompq == 0) {
+   24315           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nlp1, &nlp1, &zero, &one, &work[nwork1], &smlszp);
+   24316           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nl, &nlp1, &nru, &ncc, &d__[nlf], &e[nlf], &
+   24317             :                     work[nwork1], &smlszp, &work[nwork2], &nl, &work[nwork2], 
+   24318           0 :                     &nl, &work[nwork2], info);
+   24319           0 :             itemp = nwork1 + nl * smlszp;
+   24320           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &work[nwork1], &c__1, &work[vfi], &c__1);
+   24321           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &work[itemp], &c__1, &work[vli], &c__1);
+   24322             :         } else {
+   24323           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nl, &nl, &zero, &one, &u[nlf + u_dim1], ldu);
+   24324           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nlp1, &nlp1, &zero, &one, &vt[nlf + vt_dim1], 
+   24325             :                     ldu);
+   24326           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nl, &nlp1, &nl, &ncc, &d__[nlf], &e[nlf], &
+   24327             :                     vt[nlf + vt_dim1], ldu, &u[nlf + u_dim1], ldu, &u[nlf + 
+   24328           0 :                     u_dim1], ldu, &work[nwork1], info);
+   24329           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &vt[nlf + vt_dim1], &c__1, &work[vfi], &c__1);
+   24330           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nlp1, &vt[nlf + nlp1 * vt_dim1], &c__1, &work[vli], &c__1)
+   24331             :                     ;
+   24332             :         }
+   24333           0 :         if (*info != 0) {
+   24334             :             return;
+   24335             :         }
+   24336           0 :         i__2 = nl;
+   24337           0 :         for (j = 1; j <= i__2; ++j) {
+   24338           0 :             iwork[idxqi + j] = j;
+   24339             :         }
+   24340           0 :         if (i__ == nd && *sqre == 0) {
+   24341           0 :             sqrei = 0;
+   24342             :         } else {
+   24343           0 :             sqrei = 1;
+   24344             :         }
+   24345           0 :         idxqi += nlp1;
+   24346           0 :         vfi += nlp1;
+   24347           0 :         vli += nlp1;
+   24348           0 :         nrp1 = nr + sqrei;
+   24349           0 :         if (*icompq == 0) {
+   24350           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nrp1, &nrp1, &zero, &one, &work[nwork1], &smlszp);
+   24351           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nr, &nrp1, &nru, &ncc, &d__[nrf], &e[nrf], &
+   24352             :                     work[nwork1], &smlszp, &work[nwork2], &nr, &work[nwork2], 
+   24353           0 :                     &nr, &work[nwork2], info);
+   24354           0 :             itemp = nwork1 + (nrp1 - 1) * smlszp;
+   24355           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &work[nwork1], &c__1, &work[vfi], &c__1);
+   24356           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &work[itemp], &c__1, &work[vli], &c__1);
+   24357             :         } else {
+   24358           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nr, &nr, &zero, &one, &u[nrf + u_dim1], ldu);
+   24359           0 :             PLUMED_BLAS_F77_FUNC(slaset,SLASET)("A", &nrp1, &nrp1, &zero, &one, &vt[nrf + vt_dim1], 
+   24360             :                     ldu);
+   24361           0 :             PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)("U", &sqrei, &nr, &nrp1, &nr, &ncc, &d__[nrf], &e[nrf], &
+   24362             :                     vt[nrf + vt_dim1], ldu, &u[nrf + u_dim1], ldu, &u[nrf + 
+   24363           0 :                     u_dim1], ldu, &work[nwork1], info);
+   24364           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &vt[nrf + vt_dim1], &c__1, &work[vfi], &c__1);
+   24365           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&nrp1, &vt[nrf + nrp1 * vt_dim1], &c__1, &work[vli], &c__1)
+   24366             :                     ;
+   24367             :         }
+   24368           0 :         if (*info != 0) {
+   24369             :             return;
+   24370             :         }
+   24371           0 :         i__2 = nr;
+   24372           0 :         for (j = 1; j <= i__2; ++j) {
+   24373           0 :             iwork[idxqi + j] = j;
+   24374             :         }
+   24375             :     }
+   24376             : 
+   24377           0 :     j = (1 << nlvl);
+   24378             : 
+   24379           0 :     for (lvl = nlvl; lvl >= 1; --lvl) {
+   24380           0 :         lvl2 = (lvl << 1) - 1;
+   24381             : 
+   24382           0 :         if (lvl == 1) {
+   24383             :             lf = 1;
+   24384             :             ll = 1;
+   24385             :         } else {
+   24386           0 :             lf = (1 << (lvl-1));
+   24387           0 :             ll = (lf << 1) - 1;
+   24388             :         }
+   24389             :         i__1 = ll;
+   24390           0 :         for (i__ = lf; i__ <= i__1; ++i__) {
+   24391           0 :             im1 = i__ - 1;
+   24392           0 :             ic = iwork[inode + im1];
+   24393           0 :             nl = iwork[ndiml + im1];
+   24394           0 :             nr = iwork[ndimr + im1];
+   24395           0 :             nlf = ic - nl;
+   24396           0 :             if (i__ == ll) {
+   24397           0 :                 sqrei = *sqre;
+   24398             :             } else {
+   24399           0 :                 sqrei = 1;
+   24400             :             }
+   24401             :             vfi = vf + nlf - 1;
+   24402           0 :             vli = vl + nlf - 1;
+   24403           0 :             idxqi = idxq + nlf - 1;
+   24404           0 :             alpha = d__[ic];
+   24405           0 :             beta = e[ic];
+   24406           0 :             if (*icompq == 0) {
+   24407           0 :                 PLUMED_BLAS_F77_FUNC(slasd6,SLASD6)(icompq, &nl, &nr, &sqrei, &d__[nlf], &work[vfi], &
+   24408           0 :                         work[vli], &alpha, &beta, &iwork[idxqi], &perm[
+   24409             :                         perm_offset], &givptr[1], &givcol[givcol_offset], 
+   24410             :                         ldgcol, &givnum[givnum_offset], ldu, &poles[
+   24411             :                         poles_offset], &difl[difl_offset], &difr[difr_offset],
+   24412           0 :                          &z__[z_offset], &k[1], &c__[1], &s[1], &work[nwork1],
+   24413           0 :                          &iwork[iwk], info);
+   24414             :             } else {
+   24415           0 :                 --j;
+   24416           0 :                 PLUMED_BLAS_F77_FUNC(slasd6,SLASD6)(icompq, &nl, &nr, &sqrei, &d__[nlf], &work[vfi], &
+   24417           0 :                         work[vli], &alpha, &beta, &iwork[idxqi], &perm[nlf + 
+   24418           0 :                         lvl * perm_dim1], &givptr[j], &givcol[nlf + lvl2 * 
+   24419             :                         givcol_dim1], ldgcol, &givnum[nlf + lvl2 * 
+   24420             :                         givnum_dim1], ldu, &poles[nlf + lvl2 * poles_dim1], &
+   24421           0 :                         difl[nlf + lvl * difl_dim1], &difr[nlf + lvl2 * 
+   24422           0 :                         difr_dim1], &z__[nlf + lvl * z_dim1], &k[j], &c__[j], 
+   24423           0 :                         &s[j], &work[nwork1], &iwork[iwk], info);
+   24424             :             }
+   24425           0 :             if (*info != 0) {
+   24426             :                 return;
+   24427             :             }
+   24428             :         }
+   24429             :     }
+   24430             : 
+   24431             :     return;
+   24432             : 
+   24433             : }
+   24434             : 
+   24435             : 
+   24436             : }
+   24437             : }
+   24438             : #include <cctype>
+   24439             : 
+   24440             : #include "blas/blas.h"
+   24441             : #include "lapack.h"
+   24442             : 
+   24443             : 
+   24444             : #include "blas/blas.h"
+   24445             : namespace PLMD{
+   24446             : namespace lapack{
+   24447             : using namespace blas;
+   24448             : void 
+   24449           0 : PLUMED_BLAS_F77_FUNC(slasdq,SLASDQ)(const char *uplo,
+   24450             :                         int *sqre,
+   24451             :                         int *n,
+   24452             :                         int *ncvt,
+   24453             :                         int *nru,
+   24454             :                         int *ncc,
+   24455             :                         float *d__,
+   24456             :                         float *e, 
+   24457             :                         float *vt, 
+   24458             :                         int *ldvt, 
+   24459             :                         float *u,
+   24460             :                         int *ldu, 
+   24461             :                         float *c__,
+   24462             :                         int *ldc,
+   24463             :                         float *work, 
+   24464             :                         int *info)
+   24465             : {
+   24466           0 :     const char xuplo=std::toupper(*uplo);
+   24467             :     int c_dim1, c_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, 
+   24468             :             i__2;
+   24469           0 :     int c__1 = 1;
+   24470             :     int itmp1,itmp2;
+   24471             :     int i__, j;
+   24472             :     float r__, cs, sn;
+   24473             :     int np1, isub;
+   24474             :     float smin;
+   24475             :     int sqre1;
+   24476             :     int iuplo;
+   24477             :     int rotate;
+   24478             : 
+   24479           0 :     --d__;
+   24480           0 :     --e;
+   24481           0 :     vt_dim1 = *ldvt;
+   24482           0 :     vt_offset = 1 + vt_dim1;
+   24483           0 :     vt -= vt_offset;
+   24484           0 :     u_dim1 = *ldu;
+   24485           0 :     u_offset = 1 + u_dim1;
+   24486           0 :     u -= u_offset;
+   24487           0 :     c_dim1 = *ldc;
+   24488           0 :     c_offset = 1 + c_dim1;
+   24489           0 :     c__ -= c_offset;
+   24490           0 :     --work;
+   24491             : 
+   24492           0 :     *info = 0;
+   24493             :     iuplo = 0;
+   24494           0 :     if (xuplo == 'U') {
+   24495             :         iuplo = 1;
+   24496             :     }
+   24497           0 :     if (xuplo == 'L') {
+   24498             :         iuplo = 2;
+   24499             :     }
+   24500             :     
+   24501           0 :     itmp1 = (*n > 1) ? *n : 1;
+   24502           0 :     itmp2 = (*nru > 1) ? *nru : 1;
+   24503           0 :     if (iuplo == 0) {
+   24504           0 :         *info = -1;
+   24505           0 :     } else if (*sqre < 0 || *sqre > 1) {
+   24506           0 :         *info = -2;
+   24507           0 :     } else if (*n < 0) {
+   24508           0 :         *info = -3;
+   24509           0 :     } else if (*ncvt < 0) {
+   24510           0 :         *info = -4;
+   24511           0 :     } else if (*nru < 0) {
+   24512           0 :         *info = -5;
+   24513           0 :     } else if (*ncc < 0) {
+   24514           0 :         *info = -6;
+   24515           0 :     } else if ( (*ncvt == 0 && *ldvt < 1) || (*ncvt > 0 && *ldvt < itmp1)) {
+   24516           0 :         *info = -10;
+   24517           0 :     } else if (*ldu < itmp2) {
+   24518           0 :         *info = -12;
+   24519           0 :     } else if ((*ncc == 0 && *ldc < 1) || (*ncc > 0 && *ldc < itmp1)) {
+   24520           0 :         *info = -14;
+   24521             :     }
+   24522           0 :     if (*info != 0) {
+   24523             :         return;
+   24524             :     }
+   24525           0 :     if (*n == 0) {
+   24526             :         return;
+   24527             :     }
+   24528             : 
+   24529           0 :     rotate = *ncvt > 0 || *nru > 0 || *ncc > 0;
+   24530           0 :     np1 = *n + 1;
+   24531           0 :     sqre1 = *sqre;
+   24532             : 
+   24533           0 :     if (iuplo == 1 && sqre1 == 1) {
+   24534             :         i__1 = *n - 1;
+   24535           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   24536           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   24537           0 :             d__[i__] = r__;
+   24538           0 :             e[i__] = sn * d__[i__ + 1];
+   24539           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   24540           0 :             if (rotate) {
+   24541           0 :                 work[i__] = cs;
+   24542           0 :                 work[*n + i__] = sn;
+   24543             :             }
+   24544             :         }
+   24545           0 :         PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[*n], &e[*n], &cs, &sn, &r__);
+   24546           0 :         d__[*n] = r__;
+   24547           0 :         e[*n] = 0.f;
+   24548           0 :         if (rotate) {
+   24549           0 :             work[*n] = cs;
+   24550           0 :             work[*n + *n] = sn;
+   24551             :         }
+   24552             :         iuplo = 2;
+   24553             :         sqre1 = 0;
+   24554             : 
+   24555           0 :         if (*ncvt > 0) {
+   24556           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &np1, ncvt, &work[1], &work[np1], &vt[
+   24557             :                     vt_offset], ldvt);
+   24558             :         }
+   24559             :     }
+   24560           0 :     if (iuplo == 2) {
+   24561           0 :         i__1 = *n - 1;
+   24562           0 :         for (i__ = 1; i__ <= i__1; ++i__) {
+   24563           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[i__], &e[i__], &cs, &sn, &r__);
+   24564           0 :             d__[i__] = r__;
+   24565           0 :             e[i__] = sn * d__[i__ + 1];
+   24566           0 :             d__[i__ + 1] = cs * d__[i__ + 1];
+   24567           0 :             if (rotate) {
+   24568           0 :                 work[i__] = cs;
+   24569           0 :                 work[*n + i__] = sn;
+   24570             :             }
+   24571             :         }
+   24572             : 
+   24573           0 :         if (sqre1 == 1) {
+   24574           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&d__[*n], &e[*n], &cs, &sn, &r__);
+   24575           0 :             d__[*n] = r__;
+   24576           0 :             if (rotate) {
+   24577           0 :                 work[*n] = cs;
+   24578           0 :                 work[*n + *n] = sn;
+   24579             :             }
+   24580             :         }
+   24581           0 :         if (*nru > 0) {
+   24582           0 :             if (sqre1 == 0) {
+   24583           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, n, &work[1], &work[np1], &u[
+   24584             :                         u_offset], ldu);
+   24585             :             } else {
+   24586           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", nru, &np1, &work[1], &work[np1], &u[
+   24587             :                         u_offset], ldu);
+   24588             :             }
+   24589             :         }
+   24590           0 :         if (*ncc > 0) {
+   24591           0 :             if (sqre1 == 0) {
+   24592           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", n, ncc, &work[1], &work[np1], &c__[
+   24593             :                         c_offset], ldc);
+   24594             :             } else {
+   24595           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("L", "V", "F", &np1, ncc, &work[1], &work[np1], &c__[
+   24596             :                         c_offset], ldc);
+   24597             :             }
+   24598             :         }
+   24599             :     }
+   24600             : 
+   24601           0 :     PLUMED_BLAS_F77_FUNC(sbdsqr,SBDSQR)("U", n, ncvt, nru, ncc, &d__[1], &e[1], &vt[vt_offset], ldvt, &u[
+   24602             :             u_offset], ldu, &c__[c_offset], ldc, &work[1], info);
+   24603             : 
+   24604           0 :     i__1 = *n;
+   24605           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   24606             : 
+   24607             :         isub = i__;
+   24608           0 :         smin = d__[i__];
+   24609           0 :         i__2 = *n;
+   24610           0 :         for (j = i__ + 1; j <= i__2; ++j) {
+   24611           0 :             if (d__[j] < smin) {
+   24612             :                 isub = j;
+   24613             :                 smin = d__[j];
+   24614             :             }
+   24615             :         }
+   24616           0 :         if (isub != i__) {
+   24617           0 :             d__[isub] = d__[i__];
+   24618           0 :             d__[i__] = smin;
+   24619           0 :             if (*ncvt > 0) {
+   24620           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncvt, &vt[isub + vt_dim1], ldvt, &vt[i__ + vt_dim1], 
+   24621             :                         ldvt);
+   24622             :             }
+   24623           0 :             if (*nru > 0) {
+   24624           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(nru, &u[isub * u_dim1 + 1], &c__1, &u[i__ * u_dim1 + 1]
+   24625             :                         , &c__1);
+   24626             :             }
+   24627           0 :             if (*ncc > 0) {
+   24628           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(ncc, &c__[isub + c_dim1], ldc, &c__[i__ + c_dim1], ldc)
+   24629             :                         ;
+   24630             :             }
+   24631             :         }
+   24632             :     }
+   24633             : 
+   24634             :     return;
+   24635             : }
+   24636             : 
+   24637             : 
+   24638             : }
+   24639             : }
+   24640             : #include <cmath>
+   24641             : #include "lapack.h"
+   24642             : 
+   24643             : #include "blas/blas.h"
+   24644             : namespace PLMD{
+   24645             : namespace lapack{
+   24646             : using namespace blas;
+   24647             : void
+   24648           0 : PLUMED_BLAS_F77_FUNC(slasdt,SLASDT)(int *n,
+   24649             :         int *lvl,
+   24650             :         int *nd,
+   24651             :         int *inode,
+   24652             :         int *ndiml,
+   24653             :         int *ndimr,
+   24654             :         int *msub)
+   24655             : {
+   24656           0 :   int maxn = (*n > 1) ? *n : 1;
+   24657             :   float temp;
+   24658             :   int i,il,ir,llst,nlvl,ncrnt;
+   24659             : 
+   24660           0 :   temp = std::log( ((float) maxn) / ((float)(*msub+1))) / std::log(2.0);
+   24661             :   
+   24662           0 :   *lvl = 1 + (int) temp;
+   24663             : 
+   24664           0 :   i = *n / 2;
+   24665           0 :   inode[0] = i + 1;
+   24666           0 :   ndiml[0] = i;
+   24667           0 :   ndimr[0] = *n - i - 1;
+   24668             :   il = -1;
+   24669             :   ir = 0;
+   24670             :   llst = 1;
+   24671             : 
+   24672           0 :   for(nlvl=1;nlvl<*lvl;nlvl++) {
+   24673           0 :     for(i=0;i<llst;i++) {
+   24674           0 :       il += 2;
+   24675           0 :       ir += 2;
+   24676           0 :       ncrnt = llst + i - 1;
+   24677           0 :       ndiml[il] = ndiml[ncrnt] / 2;
+   24678           0 :       ndimr[il] = ndiml[ncrnt] - ndiml[il] - 1;
+   24679           0 :       inode[il] = inode[ncrnt] - ndimr[il] - 1;
+   24680           0 :       ndiml[ir] = ndimr[ncrnt] / 2;
+   24681           0 :       ndimr[ir] = ndimr[ncrnt] - ndiml[ir] - 1;
+   24682           0 :       inode[ir] = inode[ncrnt] + ndiml[ir] + 1;
+   24683             :     }
+   24684           0 :     llst *= 2;
+   24685             :   }
+   24686           0 :   *nd = llst*2 - 1;
+   24687           0 :   return;
+   24688             : }
+   24689             : }
+   24690             : }
+   24691             : #include <cctype>
+   24692             : #include "lapack.h"
+   24693             : 
+   24694             : 
+   24695             : #include "blas/blas.h"
+   24696             : namespace PLMD{
+   24697             : namespace lapack{
+   24698             : using namespace blas;
+   24699             : void
+   24700           0 : PLUMED_BLAS_F77_FUNC(slaset,SLASET)(const char *uplo,
+   24701             :         int *m,
+   24702             :         int *n,
+   24703             :         float *alpha,
+   24704             :         float *beta,
+   24705             :         float *a,
+   24706             :         int *lda)
+   24707             : {
+   24708             :   int i,j,k;
+   24709           0 :   const char ch=std::toupper(*uplo);
+   24710             : 
+   24711           0 :   if(ch=='U') {
+   24712           0 :     for(j=1;j<*n;j++) {
+   24713           0 :       k = (j < *m) ? j : *m;
+   24714           0 :       for(i=0;i<k;i++)
+   24715           0 :         a[j*(*lda)+i] = *alpha;
+   24716             :     }
+   24717           0 :   } else if(ch=='L') {
+   24718           0 :     k = (*m < *n) ? *m : *n;
+   24719           0 :     for(j=0;j<k;j++) {
+   24720           0 :       for(i=j+1;i<*m;i++)
+   24721           0 :         a[j*(*lda)+i] = *alpha;
+   24722             :     }
+   24723             :   } else {
+   24724           0 :     for(j=0;j<*n;j++) {
+   24725           0 :       for(i=0;i<*m;i++)
+   24726           0 :         a[j*(*lda)+i] = *alpha;
+   24727             :     }    
+   24728             :   }
+   24729             : 
+   24730           0 :   k = (*m < *n) ? *m : *n;
+   24731           0 :   for(i=0;i<k;i++)
+   24732           0 :     a[i*(*lda)+i] = *beta;
+   24733           0 : }
+   24734             : }
+   24735             : }
+   24736             : #include <cmath>
+   24737             : #include "blas/blas.h"
+   24738             : #include "lapack.h"
+   24739             : #include "lapack_limits.h"
+   24740             : 
+   24741             : #include "real.h"
+   24742             : 
+   24743             : #include "blas/blas.h"
+   24744             : namespace PLMD{
+   24745             : namespace lapack{
+   24746             : using namespace blas;
+   24747             : void
+   24748           0 : PLUMED_BLAS_F77_FUNC(slasq1,SLASQ1)(int *n,
+   24749             :         float *d,
+   24750             :         float *e,
+   24751             :         float *work,
+   24752             :         int *info)
+   24753             : {
+   24754           0 :   float sigmx = 0.0;
+   24755             :   int i,j,k,iinfo;
+   24756             :   float minval,safemin;
+   24757             :   float dtemp,scale;
+   24758             :   float eps;
+   24759             : 
+   24760             :   eps = PLUMED_GMX_FLOAT_EPS;
+   24761             :   minval = PLUMED_GMX_FLOAT_MIN;
+   24762             :   safemin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   24763           0 :   *info = 0;
+   24764             : 
+   24765           0 :   if(*n<0) {
+   24766           0 :     *info = -2;
+   24767           0 :     return;
+   24768             :   }
+   24769             :   
+   24770           0 :   for(i=0;i<*n-1;i++) {
+   24771           0 :     d[i] = std::abs(d[i]);
+   24772           0 :     dtemp = std::abs(e[i]);
+   24773           0 :     if(dtemp>sigmx)
+   24774           0 :       sigmx=dtemp;
+   24775             :   }
+   24776           0 :   d[*n-1] = std::abs(d[*n-1]);
+   24777             :   
+   24778           0 :   if(std::abs(sigmx)<PLUMED_GMX_FLOAT_MIN) {
+   24779           0 :     PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("D",n,d,&iinfo);
+   24780           0 :     return;
+   24781             :   }
+   24782             : 
+   24783           0 :   for(i=0;i<*n;i++) {
+   24784           0 :     if(d[i]>sigmx)
+   24785           0 :       sigmx=d[i];
+   24786             :   }
+   24787             : 
+   24788             :   /* Copy d and e into work (z format) and scale.
+   24789             :    * Squaring input data makes scaling by a power of the
+   24790             :    * radix pointless.
+   24791             :    */
+   24792           0 :   scale =  std::sqrt(eps/safemin);
+   24793           0 :   i = 1;
+   24794           0 :   j = 2;
+   24795           0 :   PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n,d,&i,work,&j);
+   24796           0 :   k = *n-1;
+   24797           0 :   PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&k,e,&i,work+1,&j);
+   24798           0 :   i = 0;
+   24799           0 :   j = 2*(*n)-1;
+   24800           0 :   k = 1;
+   24801           0 :   PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&i,&i,&sigmx,&scale,&j,&k,work,&j,&iinfo);
+   24802             : 
+   24803             : 
+   24804             :   /* Compute q and e elements */
+   24805           0 :   for(i=0;i<2*(*n)-1;i++)
+   24806           0 :     work[i] = work[i]*work[i];
+   24807             : 
+   24808           0 :   work[2*(*n)-1] = 0.0;
+   24809             : 
+   24810           0 :   PLUMED_BLAS_F77_FUNC(slasq2,SLASQ2)(n,work,info);
+   24811             : 
+   24812           0 :   j = 0;
+   24813           0 :   k = 1;
+   24814           0 :   if(*info==0) {
+   24815           0 :     for(i=0;i<*n;i++)
+   24816           0 :       d[i]= std::sqrt(work[i]);
+   24817           0 :     PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G",&j,&j,&scale,&sigmx,n,&k,d,n,&iinfo);
+   24818             :   }
+   24819             :   return;
+   24820             : }
+   24821             : }
+   24822             : }
+   24823             : #include <cmath>
+   24824             : #include "lapack.h"
+   24825             : #include "lapack_limits.h"
+   24826             : 
+   24827             : #include "real.h"
+   24828             : 
+   24829             : #ifdef _MSC_VER
+   24830             : #pragma warning(disable: 4723) /*division by zero - is used on purpose here*/
+   24831             : #endif
+   24832             : 
+   24833             : #include "blas/blas.h"
+   24834             : namespace PLMD{
+   24835             : namespace lapack{
+   24836             : using namespace blas;
+   24837             : void 
+   24838           0 : PLUMED_BLAS_F77_FUNC(slasq2,SLASQ2)(int *n, 
+   24839             :                         float *z__, 
+   24840             :                         int *info)
+   24841             : {
+   24842             :     int i__1, i__2, i__3;
+   24843             :     float d__1, d__2;
+   24844             : 
+   24845             :     float d__, e;
+   24846             :     int k;
+   24847             :     float s, t;
+   24848             :     int i0, i4, n0, pp;
+   24849             :     float dee, eps, tol;
+   24850             :     int ipn4;
+   24851             :     float tol2;
+   24852             :     int ieee;
+   24853             :     int nbig;
+   24854             :     float dmin__, emin, emax;
+   24855             :     int kmin, ndiv, iter;
+   24856             :     float qmin, temp, qmax, zmax;
+   24857             :     int splt, nfail;
+   24858             :     float desig, trace, sigma;
+   24859             :     int iinfo;
+   24860             :     float deemin;
+   24861             :     int iwhila, iwhilb;
+   24862             :     float oldemn, safmin, minval;
+   24863             :     float posinf,neginf,negzro,newzro;
+   24864             :     float zero = 0.0;
+   24865             :     float one = 1.0;
+   24866             : 
+   24867           0 :     --z__;
+   24868             : 
+   24869           0 :     *info = 0;
+   24870             :     eps = PLUMED_GMX_FLOAT_EPS;
+   24871             :     minval = PLUMED_GMX_FLOAT_MIN;
+   24872             :     safmin = minval*(1.0+eps);
+   24873             : 
+   24874             :     tol = eps * 100.;
+   24875             : 
+   24876             :     d__1 = tol;
+   24877             :     tol2 = d__1 * d__1;
+   24878             : 
+   24879           0 :     if (*n < 0) {
+   24880           0 :         *info = -1;
+   24881           0 :         return;
+   24882           0 :     } else if (*n == 0) {
+   24883             :         return;
+   24884           0 :     } else if (*n == 1) {
+   24885             : 
+   24886           0 :         if (z__[1] < 0.) {
+   24887           0 :             *info = -201;
+   24888             :         }
+   24889           0 :         return;
+   24890           0 :     } else if (*n == 2) {
+   24891             : 
+   24892           0 :         if (z__[2] < 0. || z__[3] < 0.) {
+   24893           0 :             *info = -2;
+   24894           0 :             return;
+   24895           0 :         } else if (z__[3] > z__[1]) {
+   24896             :             d__ = z__[3];
+   24897           0 :             z__[3] = z__[1];
+   24898           0 :             z__[1] = d__;
+   24899             :         }
+   24900           0 :         z__[5] = z__[1] + z__[2] + z__[3];
+   24901           0 :         if (z__[2] > z__[3] * tol2) {
+   24902           0 :             t = (z__[1] - z__[3] + z__[2]) * .5;
+   24903           0 :             s = z__[3] * (z__[2] / t);
+   24904           0 :             if (s <= t) {
+   24905           0 :                 s = z__[3] * (z__[2] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+   24906             :             } else {
+   24907           0 :                 s = z__[3] * (z__[2] / (t +  std::sqrt(t) * std::sqrt(t + s)));
+   24908             :             }
+   24909           0 :             t = z__[1] + (s + z__[2]);
+   24910           0 :             z__[3] *= z__[1] / t;
+   24911           0 :             z__[1] = t;
+   24912             :         }
+   24913           0 :         z__[2] = z__[3];
+   24914           0 :         z__[6] = z__[2] + z__[1];
+   24915           0 :         return;
+   24916             :     }
+   24917           0 :     z__[*n * 2] = 0.;
+   24918           0 :     emin = z__[2];
+   24919           0 :     qmax = 0.;
+   24920             :     zmax = 0.;
+   24921             :     d__ = 0.;
+   24922             :     e = 0.;
+   24923             : 
+   24924           0 :     i__1 = 2*(*n - 1);
+   24925           0 :     for (k = 1; k <= i__1; k += 2) {
+   24926           0 :         if (z__[k] < 0.) {
+   24927           0 :             *info = -(k + 200);
+   24928           0 :             return;
+   24929           0 :         } else if (z__[k + 1] < 0.) {
+   24930           0 :             *info = -(k + 201);
+   24931           0 :             return;
+   24932             :         }
+   24933           0 :         d__ += z__[k];
+   24934           0 :         e += z__[k + 1];
+   24935           0 :         d__1 = qmax, d__2 = z__[k];
+   24936           0 :         qmax = (d__1>d__2) ? d__1 : d__2;
+   24937             :         d__1 = emin, d__2 = z__[k + 1];
+   24938           0 :         emin = (d__1<d__2) ? d__1 : d__2;
+   24939           0 :         d__1 = (qmax>zmax) ? qmax : zmax;
+   24940             :         d__2 = z__[k + 1];
+   24941           0 :         zmax = (d__1>d__2) ? d__1 : d__2;
+   24942             :     }
+   24943           0 :     if (z__[(*n << 1) - 1] < 0.) {
+   24944           0 :         *info = -((*n << 1) + 199);
+   24945           0 :         return;
+   24946             :     }
+   24947           0 :     d__ += z__[(*n << 1) - 1];
+   24948           0 :     d__1 = qmax, d__2 = z__[(*n << 1) - 1];
+   24949           0 :     qmax = (d__1>d__2) ? d__1 : d__2;
+   24950             : 
+   24951           0 :     if (std::abs(e)<PLUMED_GMX_FLOAT_MIN) {
+   24952             :         i__1 = *n;
+   24953           0 :         for (k = 2; k <= i__1; ++k) {
+   24954           0 :             z__[k] = z__[(k << 1) - 1];
+   24955             :         }
+   24956           0 :         PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("D", n, &z__[1], &iinfo);
+   24957           0 :         z__[(*n << 1) - 1] = d__;
+   24958           0 :         return;
+   24959             :     }
+   24960             : 
+   24961           0 :     trace = d__ + e;
+   24962             : 
+   24963           0 :     if (std::abs(trace)<PLUMED_GMX_FLOAT_MIN) {
+   24964           0 :         z__[(*n << 1) - 1] = 0.;
+   24965           0 :         return;
+   24966             :     }
+   24967             : 
+   24968           0 :     ieee = 1;
+   24969           0 :     posinf = one/zero;
+   24970           0 :     if(posinf<=1.0)
+   24971           0 :       ieee = 0;
+   24972             :     neginf = -one/zero;
+   24973           0 :     if(neginf>=0.0)
+   24974           0 :       ieee = 0;
+   24975           0 :     negzro = one/(neginf+one);
+   24976           0 :     if(std::abs(negzro)>PLUMED_GMX_FLOAT_MIN)
+   24977           0 :       ieee = 0;
+   24978           0 :     neginf = one/negzro;
+   24979           0 :     if(neginf>=0)
+   24980           0 :       ieee = 0;
+   24981           0 :     newzro = negzro + zero;
+   24982           0 :     if(std::abs(newzro-zero)>PLUMED_GMX_FLOAT_MIN)
+   24983           0 :       ieee = 0;
+   24984           0 :     posinf = one /newzro;
+   24985           0 :     if(posinf<=one)
+   24986           0 :       ieee = 0;
+   24987           0 :     neginf = neginf*posinf;
+   24988           0 :     if(neginf>=zero)
+   24989           0 :       ieee = 0;
+   24990           0 :     posinf = posinf*posinf;
+   24991           0 :     if(posinf<=1.0)
+   24992           0 :       ieee = 0;
+   24993             : 
+   24994           0 :     for (k = *n << 1; k >= 2; k += -2) {
+   24995           0 :         z__[k * 2] = 0.;
+   24996           0 :         z__[(k << 1) - 1] = z__[k];
+   24997           0 :         z__[(k << 1) - 2] = 0.;
+   24998           0 :         z__[(k << 1) - 3] = z__[k - 1];
+   24999             :     }
+   25000             : 
+   25001           0 :     i0 = 1;
+   25002           0 :     n0 = *n;
+   25003             : 
+   25004           0 :     if (z__[(i0 << 2) - 3] * 1.5 < z__[(n0 << 2) - 3]) {
+   25005           0 :         ipn4 = 4*(i0 + n0);
+   25006           0 :         i__1 = 2*(i0 + n0 - 1);
+   25007           0 :         for (i4 = i0 << 2; i4 <= i__1; i4 += 4) {
+   25008           0 :             temp = z__[i4 - 3];
+   25009           0 :             z__[i4 - 3] = z__[ipn4 - i4 - 3];
+   25010           0 :             z__[ipn4 - i4 - 3] = temp;
+   25011           0 :             temp = z__[i4 - 1];
+   25012           0 :             z__[i4 - 1] = z__[ipn4 - i4 - 5];
+   25013           0 :             z__[ipn4 - i4 - 5] = temp;
+   25014             :         }
+   25015             :     }
+   25016             : 
+   25017           0 :     pp = 0;
+   25018             : 
+   25019           0 :     for (k = 1; k <= 2; ++k) {
+   25020             : 
+   25021           0 :         d__ = z__[(n0 << 2) + pp - 3];
+   25022           0 :         i__1 = (i0 << 2) + pp;
+   25023           0 :         for (i4 = 4*(n0 - 1) + pp; i4 >= i__1; i4 += -4) {
+   25024           0 :             if (z__[i4 - 1] <= tol2 * d__) {
+   25025           0 :                 z__[i4 - 1] = -0.;
+   25026           0 :                 d__ = z__[i4 - 3];
+   25027             :             } else {
+   25028           0 :                 d__ = z__[i4 - 3] * (d__ / (d__ + z__[i4 - 1]));
+   25029             :             }
+   25030             :         }
+   25031             : 
+   25032           0 :         emin = z__[(i0 << 2) + pp + 1];
+   25033           0 :         d__ = z__[(i0 << 2) + pp - 3];
+   25034             :         i__1 = 4*(n0 - 1) + pp;
+   25035           0 :         for (i4 = (i0 << 2) + pp; i4 <= i__1; i4 += 4) {
+   25036           0 :             z__[i4 - (pp << 1) - 2] = d__ + z__[i4 - 1];
+   25037           0 :             if (z__[i4 - 1] <= tol2 * d__) {
+   25038           0 :                 z__[i4 - 1] = -0.;
+   25039           0 :                 z__[i4 - (pp << 1) - 2] = d__;
+   25040           0 :                 z__[i4 - (pp << 1)] = 0.;
+   25041           0 :                 d__ = z__[i4 + 1];
+   25042           0 :             } else if (safmin * z__[i4 + 1] < z__[i4 - (pp << 1) - 2] && 
+   25043           0 :                     safmin * z__[i4 - (pp << 1) - 2] < z__[i4 + 1]) {
+   25044           0 :                 temp = z__[i4 + 1] / z__[i4 - (pp << 1) - 2];
+   25045           0 :                 z__[i4 - (pp << 1)] = z__[i4 - 1] * temp;
+   25046           0 :                 d__ *= temp;
+   25047             :             } else {
+   25048           0 :                 z__[i4 - (pp << 1)] = z__[i4 + 1] * (z__[i4 - 1] / z__[i4 - (
+   25049             :                         pp << 1) - 2]);
+   25050           0 :                 d__ = z__[i4 + 1] * (d__ / z__[i4 - (pp << 1) - 2]);
+   25051             :             }
+   25052           0 :             d__1 = emin, d__2 = z__[i4 - (pp << 1)];
+   25053           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25054             :         }
+   25055           0 :         z__[(n0 << 2) - pp - 2] = d__;
+   25056             : 
+   25057             : 
+   25058           0 :         qmax = z__[(i0 << 2) - pp - 2];
+   25059           0 :         i__1 = (n0 << 2) - pp - 2;
+   25060           0 :         for (i4 = (i0 << 2) - pp + 2; i4 <= i__1; i4 += 4) {
+   25061           0 :             d__1 = qmax, d__2 = z__[i4];
+   25062           0 :             qmax = (d__1>d__2) ? d__1 : d__2;
+   25063             :         }
+   25064             : 
+   25065           0 :         pp = 1 - pp;
+   25066             :     }
+   25067             : 
+   25068           0 :     iter = 2;
+   25069           0 :     nfail = 0;
+   25070           0 :     ndiv = 2*(n0 - i0);
+   25071             : 
+   25072           0 :     i__1 = *n + 1;
+   25073           0 :     for (iwhila = 1; iwhila <= i__1; ++iwhila) {
+   25074           0 :         if (n0 < 1) {
+   25075           0 :             goto L170;
+   25076             :         }
+   25077             : 
+   25078           0 :         desig = 0.;
+   25079           0 :         if (n0 == *n) {
+   25080           0 :             sigma = 0.;
+   25081             :         } else {
+   25082           0 :             sigma = -z__[(n0 << 2) - 1];
+   25083             :         }
+   25084           0 :         if (sigma < 0.) {
+   25085           0 :             *info = 1;
+   25086           0 :             return;
+   25087             :         }
+   25088             : 
+   25089             :         emax = 0.;
+   25090           0 :         if (n0 > i0) {
+   25091           0 :             emin = std::abs(z__[(n0 << 2) - 5]);
+   25092             :         } else {
+   25093             :             emin = 0.;
+   25094             :         }
+   25095           0 :         qmin = z__[(n0 << 2) - 3];
+   25096           0 :         qmax = qmin;
+   25097           0 :         for (i4 = n0 << 2; i4 >= 8; i4 += -4) {
+   25098           0 :             if (z__[i4 - 5] <= 0.) {
+   25099           0 :                 goto L100;
+   25100             :             }
+   25101           0 :             if (qmin >= emax * 4.) {
+   25102           0 :                 d__1 = qmin, d__2 = z__[i4 - 3];
+   25103           0 :                 qmin = (d__1<d__2) ? d__1 : d__2;
+   25104             :                 d__1 = emax, d__2 = z__[i4 - 5];
+   25105           0 :                 emax = (d__1>d__2) ? d__1 : d__2;
+   25106             :             }
+   25107           0 :             d__1 = qmax, d__2 = z__[i4 - 7] + z__[i4 - 5];
+   25108           0 :             qmax = (d__1>d__2) ? d__1 : d__2;
+   25109             :             d__1 = emin, d__2 = z__[i4 - 5];
+   25110           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25111             :         }
+   25112             :         i4 = 4;
+   25113             : 
+   25114           0 : L100:
+   25115           0 :         i0 = i4 / 4;
+   25116           0 :         pp = 0;
+   25117             : 
+   25118           0 :         if (n0 - i0 > 1) {
+   25119           0 :             dee = z__[(i0 << 2) - 3];
+   25120             :             deemin = dee;
+   25121             :             kmin = i0;
+   25122           0 :             i__2 = (n0 << 2) - 3;
+   25123           0 :             for (i4 = (i0 << 2) - 3; i4 <= i__2; i4 += 4) {
+   25124           0 :                 dee = z__[i4] * (dee / (dee + z__[i4 - 2]));
+   25125           0 :                 if (dee <= deemin) {
+   25126             :                     deemin = dee;
+   25127           0 :                     kmin = (i4 + 3) / 4;
+   25128             :                 }
+   25129             :             }
+   25130           0 :             if (2*(kmin - i0) < n0 - kmin && deemin <= z__[(n0 << 2) - 3] * 
+   25131             :                     .5) {
+   25132           0 :                 ipn4 = 4*(i0 + n0);
+   25133           0 :                 pp = 2;
+   25134           0 :                 i__2 = 2*(i0 + n0 - 1);
+   25135           0 :                 for (i4 = i0 << 2; i4 <= i__2; i4 += 4) {
+   25136           0 :                     temp = z__[i4 - 3];
+   25137           0 :                     z__[i4 - 3] = z__[ipn4 - i4 - 3];
+   25138           0 :                     z__[ipn4 - i4 - 3] = temp;
+   25139           0 :                     temp = z__[i4 - 2];
+   25140           0 :                     z__[i4 - 2] = z__[ipn4 - i4 - 2];
+   25141           0 :                     z__[ipn4 - i4 - 2] = temp;
+   25142           0 :                     temp = z__[i4 - 1];
+   25143           0 :                     z__[i4 - 1] = z__[ipn4 - i4 - 5];
+   25144           0 :                     z__[ipn4 - i4 - 5] = temp;
+   25145           0 :                     temp = z__[i4];
+   25146           0 :                     z__[i4] = z__[ipn4 - i4 - 4];
+   25147           0 :                     z__[ipn4 - i4 - 4] = temp;
+   25148             :                 }
+   25149             :             }
+   25150             :         }
+   25151             : 
+   25152             : 
+   25153           0 :         d__1 = 0., d__2 = qmin -  std::sqrt(qmin) * 2. * std::sqrt(emax);
+   25154           0 :         dmin__ = -((d__1>d__2) ? d__1 : d__2);
+   25155             : 
+   25156           0 :         nbig = (n0 - i0 + 1) * 30;
+   25157             :         i__2 = nbig;
+   25158           0 :         for (iwhilb = 1; iwhilb <= i__2; ++iwhilb) {
+   25159           0 :             if (i0 > n0) {
+   25160           0 :                 goto L150;
+   25161             :             }
+   25162             : 
+   25163           0 :             PLUMED_BLAS_F77_FUNC(slasq3,SLASQ3)(&i0, &n0, &z__[1], &pp, &dmin__, &sigma, &desig, &qmax, &
+   25164             :                     nfail, &iter, &ndiv, &ieee);
+   25165             : 
+   25166           0 :             pp = 1 - pp;
+   25167             : 
+   25168           0 :             if (pp == 0 && n0 - i0 >= 3) {
+   25169           0 :                 if (z__[n0 * 4] <= tol2 * qmax || z__[(n0 << 2) - 1] <= tol2 *
+   25170             :                          sigma) {
+   25171           0 :                     splt = i0 - 1;
+   25172           0 :                     qmax = z__[(i0 << 2) - 3];
+   25173           0 :                     emin = z__[(i0 << 2) - 1];
+   25174           0 :                     oldemn = z__[i0 * 4];
+   25175           0 :                     i__3 = 4*(n0 - 3);
+   25176           0 :                     for (i4 = i0 << 2; i4 <= i__3; i4 += 4) {
+   25177           0 :                         if (z__[i4] <= tol2 * z__[i4 - 3] || z__[i4 - 1] <= 
+   25178           0 :                                 tol2 * sigma) {
+   25179           0 :                             z__[i4 - 1] = -sigma;
+   25180           0 :                             splt = i4 / 4;
+   25181           0 :                             qmax = 0.;
+   25182           0 :                             emin = z__[i4 + 3];
+   25183           0 :                             oldemn = z__[i4 + 4];
+   25184             :                         } else {
+   25185           0 :                             d__1 = qmax, d__2 = z__[i4 + 1];
+   25186           0 :                             qmax = (d__1>d__2) ? d__1 : d__2;
+   25187             :                             d__1 = emin, d__2 = z__[i4 - 1];
+   25188           0 :                             emin = (d__1<d__2) ? d__1 : d__2;
+   25189             :                             d__1 = oldemn, d__2 = z__[i4];
+   25190           0 :                             oldemn = (d__1<d__2) ? d__1 : d__2;
+   25191             :                         }
+   25192             :                     }
+   25193           0 :                     z__[(n0 << 2) - 1] = emin;
+   25194           0 :                     z__[n0 * 4] = oldemn;
+   25195           0 :                     i0 = splt + 1;
+   25196             :                 }
+   25197             :             }
+   25198             :         }
+   25199             : 
+   25200           0 :         *info = 2;
+   25201           0 :         return;
+   25202             : 
+   25203             : L150:
+   25204             :         ;
+   25205             :     }
+   25206             : 
+   25207           0 :     *info = 3;
+   25208           0 :     return;
+   25209             : 
+   25210             : 
+   25211             : L170:
+   25212             : 
+   25213           0 :     i__1 = *n;
+   25214           0 :     for (k = 2; k <= i__1; ++k) {
+   25215           0 :         z__[k] = z__[(k << 2) - 3];
+   25216             :     }
+   25217             : 
+   25218           0 :     PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("D", n, &z__[1], &iinfo);
+   25219             : 
+   25220             :     e = 0.;
+   25221           0 :     for (k = *n; k >= 1; --k) {
+   25222           0 :         e += z__[k];
+   25223             :     }
+   25224             : 
+   25225             : 
+   25226           0 :     z__[(*n << 1) + 1] = trace;
+   25227           0 :     z__[(*n << 1) + 2] = e;
+   25228           0 :     z__[(*n << 1) + 3] = (float) iter;
+   25229           0 :     i__1 = *n;
+   25230           0 :     z__[(*n << 1) + 4] = (float) ndiv / (float) (i__1 * i__1);
+   25231           0 :     z__[(*n << 1) + 5] = nfail * 100. / (float) iter;
+   25232             : 
+   25233           0 :     return;
+   25234             : 
+   25235             : }
+   25236             : 
+   25237             : 
+   25238             : 
+   25239             : }
+   25240             : }
+   25241             : #include <cmath>
+   25242             : #include "real.h"
+   25243             : 
+   25244             : #include "lapack.h"
+   25245             : #include "lapack_limits.h"
+   25246             : 
+   25247             : #include "blas/blas.h"
+   25248             : namespace PLMD{
+   25249             : namespace lapack{
+   25250             : using namespace blas;
+   25251             : void
+   25252           0 : PLUMED_BLAS_F77_FUNC(slasq3,SLASQ3)(int *i0, 
+   25253             :                         int *n0, 
+   25254             :                         float *z__, 
+   25255             :                         int *pp, 
+   25256             :                         float *dmin__, 
+   25257             :                         float *sigma,
+   25258             :                         float *desig,
+   25259             :                         float *qmax, 
+   25260             :                         int *nfail, 
+   25261             :                         int *iter, 
+   25262             :                         int *ndiv, 
+   25263             :         int *ieee)
+   25264             : {
+   25265             : 
+   25266           0 :     int ttype = 0;
+   25267           0 :     float dmin1 = 0.;
+   25268           0 :     float dmin2 = 0.;
+   25269           0 :     float dn = 0.;
+   25270           0 :     float dn1 = 0.;
+   25271           0 :     float dn2 = 0.;
+   25272           0 :     float tau = 0.;
+   25273             : 
+   25274             :     int i__1;
+   25275             :     float d__1, d__2;
+   25276             :     float s, t;
+   25277             :     int j4, nn;
+   25278             :     float eps, tol;
+   25279             :     int n0in, ipn4;
+   25280             :     float tol2, temp;
+   25281           0 :     --z__;
+   25282             : 
+   25283           0 :     n0in = *n0;
+   25284             :     eps = PLUMED_GMX_FLOAT_EPS;
+   25285             :     tol = eps * 100.;
+   25286             :     d__1 = tol;
+   25287             :     tol2 = d__1 * d__1;
+   25288             : 
+   25289             : 
+   25290           0 : L10:
+   25291             : 
+   25292           0 :     if (*n0 < *i0) {
+   25293             :         return;
+   25294             :     }
+   25295           0 :     if (*n0 == *i0) {
+   25296           0 :         goto L20;
+   25297             :     }
+   25298           0 :     nn = (*n0 << 2) + *pp;
+   25299           0 :     if (*n0 == *i0 + 1) {
+   25300           0 :         goto L40;
+   25301             :     }
+   25302             : 
+   25303           0 :     if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) - 
+   25304           0 :             4] > tol2 * z__[nn - 7]) {
+   25305           0 :         goto L30;
+   25306             :     }
+   25307             : 
+   25308           0 : L20:
+   25309             : 
+   25310           0 :     z__[(*n0 << 2) - 3] = z__[(*n0 << 2) + *pp - 3] + *sigma;
+   25311           0 :     --(*n0);
+   25312           0 :     goto L10;
+   25313             : 
+   25314             : L30:
+   25315             : 
+   25316           0 :     if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[
+   25317           0 :             nn - 11]) {
+   25318           0 :         goto L50;
+   25319             :     }
+   25320             : 
+   25321           0 : L40:
+   25322             : 
+   25323           0 :     if (z__[nn - 3] > z__[nn - 7]) {
+   25324             :         s = z__[nn - 3];
+   25325           0 :         z__[nn - 3] = z__[nn - 7];
+   25326           0 :         z__[nn - 7] = s;
+   25327             :     }
+   25328           0 :     if (z__[nn - 5] > z__[nn - 3] * tol2) {
+   25329           0 :         t = (z__[nn - 7] - z__[nn - 3] + z__[nn - 5]) * .5;
+   25330           0 :         s = z__[nn - 3] * (z__[nn - 5] / t);
+   25331           0 :         if (s <= t) {
+   25332           0 :             s = z__[nn - 3] * (z__[nn - 5] / (t * ( std::sqrt(s / t + 1.) + 1.)));
+   25333             :         } else {
+   25334           0 :             s = z__[nn - 3] * (z__[nn - 5] / (t +  std::sqrt(t) * std::sqrt(t + s)));
+   25335             :         }
+   25336           0 :         t = z__[nn - 7] + (s + z__[nn - 5]);
+   25337           0 :         z__[nn - 3] *= z__[nn - 7] / t;
+   25338           0 :         z__[nn - 7] = t;
+   25339             :     }
+   25340           0 :     z__[(*n0 << 2) - 7] = z__[nn - 7] + *sigma;
+   25341           0 :     z__[(*n0 << 2) - 3] = z__[nn - 3] + *sigma;
+   25342           0 :     *n0 += -2;
+   25343           0 :     goto L10;
+   25344             : 
+   25345             : L50:
+   25346           0 :     if (*pp == 2) {
+   25347           0 :         *pp = 0;
+   25348             :     }
+   25349             : 
+   25350           0 :     if (*dmin__ <= 0. || *n0 < n0in) {
+   25351           0 :         if (z__[(*i0 << 2) + *pp - 3] * 1.5 < z__[(*n0 << 2) + *pp - 3]) {
+   25352           0 :             ipn4 = 4*(*i0 + *n0);
+   25353           0 :             i__1 = 2*(*i0 + *n0 - 1);
+   25354           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25355           0 :                 temp = z__[j4 - 3];
+   25356           0 :                 z__[j4 - 3] = z__[ipn4 - j4 - 3];
+   25357           0 :                 z__[ipn4 - j4 - 3] = temp;
+   25358           0 :                 temp = z__[j4 - 2];
+   25359           0 :                 z__[j4 - 2] = z__[ipn4 - j4 - 2];
+   25360           0 :                 z__[ipn4 - j4 - 2] = temp;
+   25361           0 :                 temp = z__[j4 - 1];
+   25362           0 :                 z__[j4 - 1] = z__[ipn4 - j4 - 5];
+   25363           0 :                 z__[ipn4 - j4 - 5] = temp;
+   25364           0 :                 temp = z__[j4];
+   25365           0 :                 z__[j4] = z__[ipn4 - j4 - 4];
+   25366           0 :                 z__[ipn4 - j4 - 4] = temp;
+   25367             :             }
+   25368           0 :             if (*n0 - *i0 <= 4) {
+   25369           0 :                 z__[(*n0 << 2) + *pp - 1] = z__[(*i0 << 2) + *pp - 1];
+   25370           0 :                 z__[(*n0 << 2) - *pp] = z__[(*i0 << 2) - *pp];
+   25371             :             }
+   25372           0 :             d__1 = dmin2, d__2 = z__[(*n0 << 2) + *pp - 1];
+   25373           0 :             dmin2 = ((d__1<d__2) ? d__1 : d__2);
+   25374           0 :             d__1 = z__[(*n0 << 2) + *pp - 1], d__2 = z__[(*i0 << 2) + *pp - 1]
+   25375           0 :                     , d__1 = ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) + *pp + 3];
+   25376           0 :             z__[(*n0 << 2) + *pp - 1] = ((d__1<d__2) ? d__1 : d__2);
+   25377           0 :             d__1 = z__[(*n0 << 2) - *pp], d__2 = z__[(*i0 << 2) - *pp], d__1 =
+   25378           0 :                      ((d__1<d__2) ? d__1 : d__2), d__2 = z__[(*i0 << 2) - *pp + 4];
+   25379           0 :             z__[(*n0 << 2) - *pp] = ((d__1<d__2) ? d__1 : d__2);
+   25380           0 :             d__1 = *qmax;
+   25381           0 :             d__2 = z__[(*i0 << 2) + *pp - 3];
+   25382           0 :             d__1 = (d__1>d__2) ? d__1 : d__2;
+   25383           0 :             d__2 = z__[(*i0 << 2) + *pp + 1];
+   25384           0 :             *qmax = ((d__1>d__2) ? d__1 : d__2);
+   25385           0 :             *dmin__ = -0.;
+   25386             :         }
+   25387             :     }
+   25388             : 
+   25389             : 
+   25390           0 :     PLUMED_BLAS_F77_FUNC(slasq4,SLASQ4)(i0, n0, &z__[1], pp, &n0in, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+   25391             :             dn2, &tau, &ttype);
+   25392             : 
+   25393           0 : L70:
+   25394             : 
+   25395           0 :     PLUMED_BLAS_F77_FUNC(slasq5,SLASQ5)(i0, n0, &z__[1], pp, &tau, dmin__, &dmin1, &dmin2, &dn, &dn1, &
+   25396             :             dn2, ieee);
+   25397             : 
+   25398           0 :     *ndiv += *n0 - *i0 + 2;
+   25399           0 :     ++(*iter);
+   25400             : 
+   25401           0 :     if (*dmin__ >= 0. && dmin1 > 0.) {
+   25402             : 
+   25403           0 :         goto L90;
+   25404             : 
+   25405           0 :     } else if (*dmin__ < 0. && dmin1 > 0. && z__[4*(*n0 - 1) - *pp] < tol *
+   25406           0 :              (*sigma + dn1) && std::abs(dn) < tol * *sigma) {
+   25407             : 
+   25408           0 :         z__[4*(*n0 - 1) - *pp + 2] = 0.;
+   25409           0 :         *dmin__ = 0.;
+   25410           0 :         goto L90;
+   25411           0 :     } else if (*dmin__ < 0.) {
+   25412             : 
+   25413           0 :         ++(*nfail);
+   25414           0 :         if (ttype < -22) {
+   25415             : 
+   25416           0 :             tau = 0.;
+   25417           0 :         } else if (dmin1 > 0.) {
+   25418             : 
+   25419           0 :             tau = (tau + *dmin__) * (1. - eps * 2.);
+   25420           0 :             ttype += -11;
+   25421             :         } else {
+   25422             : 
+   25423           0 :             tau *= .25;
+   25424           0 :             ttype += -12;
+   25425             :         }
+   25426           0 :         goto L70;
+   25427             :     }
+   25428             :     else {
+   25429             :         
+   25430           0 :         goto L80;
+   25431             :     }
+   25432             : 
+   25433             : L80:
+   25434           0 :     PLUMED_BLAS_F77_FUNC(slasq6,SLASQ6)(i0, n0, &z__[1], pp, dmin__, &dmin1, &dmin2, &dn, &dn1, &dn2);
+   25435           0 :     *ndiv += *n0 - *i0 + 2;
+   25436           0 :     ++(*iter);
+   25437           0 :     tau = 0.;
+   25438             : 
+   25439           0 : L90:
+   25440           0 :     if (tau < *sigma) {
+   25441           0 :         *desig += tau;
+   25442           0 :         t = *sigma + *desig;
+   25443           0 :         *desig -= t - *sigma;
+   25444             :     } else {
+   25445           0 :         t = *sigma + tau;
+   25446           0 :         *desig = *sigma - (t - tau) + *desig;
+   25447             :     }
+   25448           0 :     *sigma = t;
+   25449             : 
+   25450           0 :     return;
+   25451             : }
+   25452             : }
+   25453             : }
+   25454             : #include <cmath>
+   25455             : #include "real.h"
+   25456             : 
+   25457             : #include "lapack.h"
+   25458             : 
+   25459             : #include "blas/blas.h"
+   25460             : namespace PLMD{
+   25461             : namespace lapack{
+   25462             : using namespace blas;
+   25463             : void 
+   25464           0 : PLUMED_BLAS_F77_FUNC(slasq4,SLASQ4)(int *i0, 
+   25465             :         int *n0, 
+   25466             :         float *z__, 
+   25467             :         int *pp, 
+   25468             :         int *n0in, 
+   25469             :         float *dmin__, 
+   25470             :         float *dmin1, 
+   25471             :         float *dmin2, 
+   25472             :         float *dn, 
+   25473             :         float *dn1, 
+   25474             :         float *dn2, 
+   25475             :         float *tau, 
+   25476             :         int *ttype)
+   25477             : {
+   25478             :     float g = 0.;
+   25479             :     int i__1;
+   25480             :     float d__1, d__2;
+   25481             : 
+   25482             :     float s, a2, b1, b2;
+   25483             :     int i4, nn, np;
+   25484             :     float gam, gap1, gap2;
+   25485             : 
+   25486             : 
+   25487           0 :     if (*dmin__ <= 0.) {
+   25488           0 :         *tau = -(*dmin__);
+   25489           0 :         *ttype = -1;
+   25490           0 :         return;
+   25491             :     }
+   25492             : 
+   25493             :     s = 0.0;
+   25494             : 
+   25495           0 :     nn = (*n0 << 2) + *pp;
+   25496           0 :     if (*n0in == *n0) {
+   25497             : 
+   25498           0 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn) ||
+   25499           0 :          std::abs(*dmin__ - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn1)) {
+   25500             : 
+   25501           0 :             b1 =  std::sqrt(z__[nn - 3]) * std::sqrt(z__[nn - 5]);
+   25502           0 :             b2 =  std::sqrt(z__[nn - 7]) * std::sqrt(z__[nn - 9]);
+   25503           0 :             a2 = z__[nn - 7] + z__[nn - 5];
+   25504             : 
+   25505           0 :         if ( std::abs(*dmin__ - *dn)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn) &&
+   25506           0 :              std::abs(*dmin1 - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin1 + *dn1)) {
+   25507             : 
+   25508           0 :             gap2 = *dmin2 - a2 - *dmin2 * .25;
+   25509           0 :                 if (gap2 > 0. && gap2 > b2) {
+   25510           0 :                     gap1 = a2 - *dn - b2 / gap2 * b2;
+   25511             :                 } else {
+   25512           0 :                     gap1 = a2 - *dn - (b1 + b2);
+   25513             :                 }
+   25514           0 :                 if (gap1 > 0. && gap1 > b1) {
+   25515           0 :                     d__1 = *dn - b1 / gap1 * b1, d__2 = *dmin__ * .5;
+   25516           0 :                     s = (d__1>d__2) ? d__1 : d__2;
+   25517           0 :                     *ttype = -2;
+   25518             :                 } else {
+   25519             :                     s = 0.;
+   25520           0 :                     if (*dn > b1) {
+   25521           0 :                         s = *dn - b1;
+   25522             :                     }
+   25523           0 :                     if (a2 > b1 + b2) {
+   25524           0 :                         d__1 = s, d__2 = a2 - (b1 + b2);
+   25525           0 :                         s = (d__1<d__2) ? d__1 : d__2;
+   25526             :                     }
+   25527           0 :                     d__1 = s, d__2 = *dmin__ * .333;
+   25528           0 :                     s = (d__1>d__2) ? d__1 : d__2;
+   25529           0 :                     *ttype = -3;
+   25530             :                 }
+   25531             :             } else {
+   25532             : 
+   25533             : 
+   25534           0 :                 *ttype = -4;
+   25535           0 :                 s = *dmin__ * .25;
+   25536           0 :                 if (std::abs(*dmin__ - *dn)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn)) {
+   25537             :                     gam = *dn;
+   25538             :                     a2 = 0.;
+   25539           0 :                     if (z__[nn - 5] > z__[nn - 7]) {
+   25540             :                         return;
+   25541             :                     }
+   25542           0 :                     b2 = z__[nn - 5] / z__[nn - 7];
+   25543           0 :                     np = nn - 9;
+   25544             :                 } else {
+   25545           0 :                     np = nn - (*pp << 1);
+   25546           0 :                     gam = *dn1;
+   25547           0 :                     if (z__[np - 4] > z__[np - 2]) {
+   25548             :                         return;
+   25549             :                     }
+   25550           0 :                     a2 = z__[np - 4] / z__[np - 2];
+   25551           0 :                     if (z__[nn - 9] > z__[nn - 11]) {
+   25552             :                         return;
+   25553             :                     }
+   25554           0 :                     b2 = z__[nn - 9] / z__[nn - 11];
+   25555           0 :                     np = nn - 13;
+   25556             :                 }
+   25557             : 
+   25558             : 
+   25559           0 :                 a2 += b2;
+   25560           0 :                 i__1 = (*i0 << 2) - 1 + *pp;
+   25561           0 :                 for (i4 = np; i4 >= i__1; i4 += -4) {
+   25562           0 :                     if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25563           0 :                         goto L20;
+   25564             :                     }
+   25565             :                     b1 = b2;
+   25566           0 :                     if (z__[i4] > z__[i4 - 2]) {
+   25567             :                         return;
+   25568             :                     }
+   25569           0 :                     b2 *= z__[i4] / z__[i4 - 2];
+   25570           0 :                     a2 += b2;
+   25571           0 :                     if (((b2>b1) ? b2 : b1) * 100. < a2 || .563 < a2) {
+   25572           0 :                         goto L20;
+   25573             :                     }
+   25574             :                 }
+   25575           0 : L20:
+   25576           0 :                 a2 *= 1.05;
+   25577             : 
+   25578             : 
+   25579           0 :                 if (a2 < .563) {
+   25580           0 :                     s = gam * (1. -  std::sqrt(a2)) / (a2 + 1.);
+   25581             :                 }
+   25582             :             }
+   25583           0 :         } else if (std::abs(*dmin__ - *dn2)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin__ + *dn2)) {
+   25584             : 
+   25585           0 :             *ttype = -5;
+   25586           0 :             s = *dmin__ * .25;
+   25587             : 
+   25588           0 :             np = nn - (*pp << 1);
+   25589           0 :             b1 = z__[np - 2];
+   25590           0 :             b2 = z__[np - 6];
+   25591           0 :             gam = *dn2;
+   25592           0 :             if (z__[np - 8] > b2 || z__[np - 4] > b1) {
+   25593             :                 return;
+   25594             :             }
+   25595           0 :             a2 = z__[np - 8] / b2 * (z__[np - 4] / b1 + 1.);
+   25596             : 
+   25597             : 
+   25598           0 :             if (*n0 - *i0 > 2) {
+   25599           0 :                 b2 = z__[nn - 13] / z__[nn - 15];
+   25600           0 :                 a2 += b2;
+   25601           0 :                 i__1 = (*i0 << 2) - 1 + *pp;
+   25602           0 :                 for (i4 = nn - 17; i4 >= i__1; i4 += -4) {
+   25603           0 :                     if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25604           0 :                         goto L40;
+   25605             :                     }
+   25606             :                     b1 = b2;
+   25607           0 :                     if (z__[i4] > z__[i4 - 2]) {
+   25608             :                         return;
+   25609             :                     }
+   25610           0 :                     b2 *= z__[i4] / z__[i4 - 2];
+   25611           0 :                     a2 += b2;
+   25612           0 :                     if (((b2>b1) ? b2 : b1) * 100. < a2 || .563 < a2) {
+   25613           0 :                         goto L40;
+   25614             :                     }
+   25615             :                 }
+   25616           0 : L40:
+   25617           0 :                 a2 *= 1.05;
+   25618             :             }
+   25619             : 
+   25620           0 :             if (a2 < .563) {
+   25621           0 :                 s = gam * (1. -  std::sqrt(a2)) / (a2 + 1.);
+   25622             :             }
+   25623             :         } else {
+   25624             : 
+   25625           0 :             if (*ttype == -6) {
+   25626             :                 g += (1. - g) * .333;
+   25627           0 :             } else if (*ttype == -18) {
+   25628             :                 g = .083250000000000005;
+   25629             :             } else {
+   25630             :                 g = .25;
+   25631             :             }
+   25632           0 :             s = g * *dmin__;
+   25633           0 :             *ttype = -6;
+   25634             :         }
+   25635             : 
+   25636           0 :     } else if (*n0in == *n0 + 1) {
+   25637             : 
+   25638           0 :         if ( std::abs(*dmin1 - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin1 + *dn1) &&
+   25639           0 :              std::abs(*dmin2 - *dn2)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin2 + *dn2)) {
+   25640             : 
+   25641           0 :             *ttype = -7;
+   25642           0 :             s = *dmin1 * .333;
+   25643           0 :             if (z__[nn - 5] > z__[nn - 7]) {
+   25644             :                 return;
+   25645             :             }
+   25646           0 :             b1 = z__[nn - 5] / z__[nn - 7];
+   25647             :             b2 = b1;
+   25648           0 :             if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25649           0 :                 goto L60;
+   25650             :             }
+   25651           0 :             i__1 = (*i0 << 2) - 1 + *pp;
+   25652           0 :             for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
+   25653             :                 a2 = b1;
+   25654           0 :                 if (z__[i4] > z__[i4 - 2]) {
+   25655             :                     return;
+   25656             :                 }
+   25657           0 :                 b1 *= z__[i4] / z__[i4 - 2];
+   25658           0 :                 b2 += b1;
+   25659           0 :                 if (((a2>b1) ? a2 : b1) * 100. < b2) {
+   25660           0 :                     goto L60;
+   25661             :                 }
+   25662             :             }
+   25663           0 : L60:
+   25664           0 :             b2 =  std::sqrt(b2 * 1.05);
+   25665             :             d__1 = b2;
+   25666           0 :             a2 = *dmin1 / (d__1 * d__1 + 1.);
+   25667           0 :             gap2 = *dmin2 * .5 - a2;
+   25668           0 :             if (gap2 > 0. && gap2 > b2 * a2) {
+   25669           0 :                 d__1 = s, d__2 = a2 * (1. - a2 * 1.01 * (b2 / gap2) * b2);
+   25670           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25671             :             } else {
+   25672           0 :                 d__1 = s, d__2 = a2 * (1. - b2 * 1.01);
+   25673           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25674           0 :                 *ttype = -8;
+   25675             :             }
+   25676             :         } else {
+   25677             : 
+   25678           0 :             s = *dmin1 * .25;
+   25679           0 :             if (std::abs(*dmin1 - *dn1)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin1 + *dn1)) {
+   25680           0 :                 s = *dmin1 * .5;
+   25681             :             }
+   25682           0 :             *ttype = -9;
+   25683             :         }
+   25684             : 
+   25685           0 :     } else if (*n0in == *n0 + 2) {
+   25686             : 
+   25687           0 :         if (std::abs(*dmin2 - *dn2)<PLUMED_GMX_FLOAT_EPS*std::abs(*dmin2 + *dn2) &&
+   25688           0 :         z__[nn - 5] * 2. < z__[nn - 7]) {
+   25689           0 :             *ttype = -10;
+   25690           0 :             s = *dmin2 * .333;
+   25691           0 :             if (z__[nn - 5] > z__[nn - 7]) {
+   25692             :                 return;
+   25693             :             }
+   25694           0 :             b1 = z__[nn - 5] / z__[nn - 7];
+   25695             :             b2 = b1;
+   25696           0 :             if (std::abs(b2)<PLUMED_GMX_FLOAT_MIN) {
+   25697           0 :                 goto L80;
+   25698             :             }
+   25699           0 :             i__1 = (*i0 << 2) - 1 + *pp;
+   25700           0 :             for (i4 = (*n0 << 2) - 9 + *pp; i4 >= i__1; i4 += -4) {
+   25701           0 :                 if (z__[i4] > z__[i4 - 2]) {
+   25702             :                     return;
+   25703             :                 }
+   25704           0 :                 b1 *= z__[i4] / z__[i4 - 2];
+   25705           0 :                 b2 += b1;
+   25706           0 :                 if (b1 * 100. < b2) {
+   25707           0 :                     goto L80;
+   25708             :                 }
+   25709             :             }
+   25710           0 : L80:
+   25711           0 :             b2 =  std::sqrt(b2 * 1.05);
+   25712             :             d__1 = b2;
+   25713           0 :             a2 = *dmin2 / (d__1 * d__1 + 1.);
+   25714           0 :             gap2 = z__[nn - 7] + z__[nn - 9] -  std::sqrt(z__[nn - 11]) * std::sqrt(z__[
+   25715             :                     nn - 9]) - a2;
+   25716           0 :             if (gap2 > 0. && gap2 > b2 * a2) {
+   25717           0 :                 d__1 = s, d__2 = a2 * (1. - a2 * 1.01 * (b2 / gap2) * b2);
+   25718           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25719             :             } else {
+   25720           0 :                 d__1 = s, d__2 = a2 * (1. - b2 * 1.01);
+   25721           0 :                 s = (d__1>d__2) ? d__1 : d__2;
+   25722             :             }
+   25723             :         } else {
+   25724           0 :             s = *dmin2 * .25;
+   25725           0 :             *ttype = -11;
+   25726             :         }
+   25727           0 :     } else if (*n0in > *n0 + 2) {
+   25728             : 
+   25729             :         s = 0.;
+   25730           0 :         *ttype = -12;
+   25731             :     }
+   25732             : 
+   25733           0 :     *tau = s;
+   25734           0 :     return;
+   25735             : 
+   25736             : }
+   25737             : 
+   25738             : 
+   25739             : }
+   25740             : }
+   25741             : #include <cmath>
+   25742             : #include "lapack.h"
+   25743             : 
+   25744             : #include "blas/blas.h"
+   25745             : namespace PLMD{
+   25746             : namespace lapack{
+   25747             : using namespace blas;
+   25748             : void
+   25749           0 : PLUMED_BLAS_F77_FUNC(slasq5,SLASQ5)(int *i0, 
+   25750             :         int *n0,
+   25751             :         float *z__, 
+   25752             :         int *pp, 
+   25753             :         float *tau,
+   25754             :         float *dmin__, 
+   25755             :         float *dmin1, 
+   25756             :         float *dmin2, 
+   25757             :         float *dn,
+   25758             :         float *dnm1, 
+   25759             :         float *dnm2,
+   25760             :         int *ieee)
+   25761             : {
+   25762             :     int i__1;
+   25763             :     float d__1, d__2;
+   25764             : 
+   25765             :     float d__;
+   25766             :     int j4, j4p2;
+   25767             :     float emin, temp;
+   25768             : 
+   25769           0 :     --z__;
+   25770             : 
+   25771           0 :     if (*n0 - *i0 - 1 <= 0) {
+   25772             :         return;
+   25773             :     }
+   25774             : 
+   25775           0 :     j4 = (*i0 << 2) + *pp - 3;
+   25776           0 :     emin = z__[j4 + 4];
+   25777           0 :     d__ = z__[j4] - *tau;
+   25778           0 :     *dmin__ = d__;
+   25779           0 :     *dmin1 = -z__[j4];
+   25780             : 
+   25781           0 :     if (*ieee) {
+   25782             : 
+   25783           0 :         if (*pp == 0) {
+   25784           0 :             i__1 = 4*(*n0 - 3);
+   25785           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25786           0 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   25787           0 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   25788           0 :                 d__ = d__ * temp - *tau;
+   25789           0 :                 if(d__<*dmin__)
+   25790           0 :                   *dmin__ = d__;
+   25791           0 :                 z__[j4] = z__[j4 - 1] * temp;
+   25792             :                 d__1 = z__[j4];
+   25793           0 :                 if(d__1<emin)
+   25794             :                   emin = d__1;
+   25795             :             }
+   25796             :         } else {
+   25797           0 :             i__1 = 4*(*n0 - 3);
+   25798           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25799           0 :                 z__[j4 - 3] = d__ + z__[j4];
+   25800           0 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   25801           0 :                 d__ = d__ * temp - *tau;
+   25802           0 :                 if(d__<*dmin__)
+   25803           0 :                   *dmin__ = d__;
+   25804           0 :                 z__[j4 - 1] = z__[j4] * temp;
+   25805             :                 d__1 = z__[j4 - 1];
+   25806           0 :                 if(d__1<emin)
+   25807             :                   emin = d__1;
+   25808             :             }
+   25809             :         }
+   25810             : 
+   25811           0 :         *dnm2 = d__;
+   25812           0 :         *dmin2 = *dmin__;
+   25813           0 :         j4 = 4*(*n0 - 2) - *pp;
+   25814           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25815           0 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   25816           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25817           0 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   25818           0 :         if(*dnm1<*dmin__)
+   25819           0 :           *dmin__ = *dnm1;
+   25820             : 
+   25821           0 :         *dmin1 = *dmin__;
+   25822           0 :         j4 += 4;
+   25823           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25824           0 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   25825           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25826           0 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   25827           0 :         if(*dn<*dmin__)
+   25828           0 :           *dmin__ = *dn;
+   25829             : 
+   25830             :     } else {
+   25831             : 
+   25832           0 :         if (*pp == 0) {
+   25833           0 :             i__1 = 4*(*n0 - 3);
+   25834           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25835           0 :                 z__[j4 - 2] = d__ + z__[j4 - 1];
+   25836           0 :                 if (d__ < 0.) {
+   25837             :                     return;
+   25838             :                 } else {
+   25839           0 :                     z__[j4] = z__[j4 + 1] * (z__[j4 - 1] / z__[j4 - 2]);
+   25840           0 :                     d__ = z__[j4 + 1] * (d__ / z__[j4 - 2]) - *tau;
+   25841             :                 }
+   25842           0 :                 if(d__<*dmin__)
+   25843           0 :                   *dmin__ = d__;
+   25844           0 :                 d__1 = emin, d__2 = z__[j4];
+   25845           0 :                 emin = (d__1<d__2) ? d__1 : d__2;
+   25846             :             }
+   25847             :         } else {
+   25848           0 :             i__1 = 4*(*n0 - 3);
+   25849           0 :             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25850           0 :                 z__[j4 - 3] = d__ + z__[j4];
+   25851           0 :                 if (d__ < 0.) {
+   25852             :                     return;
+   25853             :                 } else {
+   25854           0 :                     z__[j4 - 1] = z__[j4 + 2] * (z__[j4] / z__[j4 - 3]);
+   25855           0 :                     d__ = z__[j4 + 2] * (d__ / z__[j4 - 3]) - *tau;
+   25856             :                 }
+   25857           0 :                 if(d__<*dmin__)
+   25858           0 :                   *dmin__ = d__;
+   25859           0 :                 d__1 = emin, d__2 = z__[j4 - 1];
+   25860           0 :                 emin = (d__1<d__2) ? d__1 : d__2;
+   25861             :             }
+   25862             :         }
+   25863             : 
+   25864           0 :         *dnm2 = d__;
+   25865           0 :         *dmin2 = *dmin__;
+   25866           0 :         j4 = 4*(*n0 - 2) - *pp;
+   25867           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25868           0 :         z__[j4 - 2] = *dnm2 + z__[j4p2];
+   25869           0 :         if (*dnm2 < 0.) {
+   25870             :             return;
+   25871             :         } else {
+   25872           0 :             z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25873           0 :             *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]) - *tau;
+   25874             :         }
+   25875           0 :         if(*dnm1<*dmin__)
+   25876           0 :           *dmin__ = *dnm1;
+   25877             : 
+   25878           0 :         *dmin1 = *dmin__;
+   25879           0 :         j4 += 4;
+   25880           0 :         j4p2 = j4 + (*pp << 1) - 1;
+   25881           0 :         z__[j4 - 2] = *dnm1 + z__[j4p2];
+   25882           0 :         if (*dnm1 < 0.) {
+   25883             :             return;
+   25884             :         } else {
+   25885           0 :             z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   25886           0 :             *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]) - *tau;
+   25887             :         }
+   25888           0 :         if(*dn<*dmin__)
+   25889           0 :           *dmin__ = *dn;
+   25890             : 
+   25891             :     }
+   25892             : 
+   25893           0 :     z__[j4 + 2] = *dn;
+   25894           0 :     z__[(*n0 << 2) - *pp] = emin;
+   25895           0 :     return;
+   25896             : 
+   25897             : }
+   25898             : 
+   25899             : }
+   25900             : }
+   25901             : #include <cmath>
+   25902             : #include "lapack.h"
+   25903             : #include "lapack_limits.h"
+   25904             : 
+   25905             : #include "real.h"
+   25906             : 
+   25907             : #include "blas/blas.h"
+   25908             : namespace PLMD{
+   25909             : namespace lapack{
+   25910             : using namespace blas;
+   25911             : void 
+   25912           0 : PLUMED_BLAS_F77_FUNC(slasq6,SLASQ6)(int *i0, 
+   25913             :         int *n0, 
+   25914             :         float *z__, 
+   25915             :         int *pp, 
+   25916             :         float *dmin__, 
+   25917             :         float *dmin1, 
+   25918             :         float *dmin2,
+   25919             :         float *dn, 
+   25920             :         float *dnm1, 
+   25921             :         float *dnm2)
+   25922             : {
+   25923             :     int i__1;
+   25924             :     float d__1, d__2;
+   25925             : 
+   25926             :     /* Local variables */
+   25927             :     float d__;
+   25928             :     int j4, j4p2;
+   25929             :     float emin, temp;
+   25930             :     const float safemin = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   25931             : 
+   25932           0 :     --z__;
+   25933             : 
+   25934           0 :     if (*n0 - *i0 - 1 <= 0) {
+   25935             :         return;
+   25936             :     }
+   25937             : 
+   25938           0 :     j4 = (*i0 << 2) + *pp - 3;
+   25939           0 :     emin = z__[j4 + 4];
+   25940           0 :     d__ = z__[j4];
+   25941           0 :     *dmin__ = d__;
+   25942             : 
+   25943           0 :     if (*pp == 0) {
+   25944           0 :         i__1 = 4*(*n0 - 3);
+   25945           0 :         for (j4 = *i0*4; j4 <= i__1; j4 += 4) {
+   25946           0 :             z__[j4 - 2] = d__ + z__[j4 - 1];
+   25947           0 :             if (std::abs(z__[j4 - 2])<PLUMED_GMX_FLOAT_MIN) {
+   25948           0 :                 z__[j4] = 0.;
+   25949           0 :                 d__ = z__[j4 + 1];
+   25950           0 :                 *dmin__ = d__;
+   25951             :                 emin = 0.;
+   25952           0 :             } else if (safemin * z__[j4 + 1] < z__[j4 - 2] && safemin * z__[j4 
+   25953             :                     - 2] < z__[j4 + 1]) {
+   25954           0 :                 temp = z__[j4 + 1] / z__[j4 - 2];
+   25955           0 :                 z__[j4] = z__[j4 - 1] * temp;
+   25956           0 :                 d__ *= temp;
+   25957             :             } else {
+   25958           0 :                 z__[j4] = z__[j4 + 1] * (z__[j4 - 1] / z__[j4 - 2]);
+   25959           0 :                 d__ = z__[j4 + 1] * (d__ / z__[j4 - 2]);
+   25960             :             }
+   25961           0 :             if(d__<*dmin__)
+   25962           0 :               *dmin__ = d__;
+   25963             : 
+   25964           0 :             d__1 = emin, d__2 = z__[j4];
+   25965           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25966             :         }
+   25967             :     } else {
+   25968           0 :         i__1 = 4*(*n0 - 3);
+   25969           0 :         for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
+   25970           0 :             z__[j4 - 3] = d__ + z__[j4];
+   25971           0 :             if (std::abs(z__[j4 - 3])<PLUMED_GMX_FLOAT_MIN) {
+   25972           0 :                 z__[j4 - 1] = 0.;
+   25973           0 :                 d__ = z__[j4 + 2];
+   25974           0 :                 *dmin__ = d__;
+   25975             :                 emin = 0.;
+   25976           0 :             } else if (safemin * z__[j4 + 2] < z__[j4 - 3] && safemin * z__[j4 
+   25977             :                     - 3] < z__[j4 + 2]) {
+   25978           0 :                 temp = z__[j4 + 2] / z__[j4 - 3];
+   25979           0 :                 z__[j4 - 1] = z__[j4] * temp;
+   25980           0 :                 d__ *= temp;
+   25981             :             } else {
+   25982           0 :                 z__[j4 - 1] = z__[j4 + 2] * (z__[j4] / z__[j4 - 3]);
+   25983           0 :                 d__ = z__[j4 + 2] * (d__ / z__[j4 - 3]);
+   25984             :             }
+   25985           0 :             if(d__<*dmin__)
+   25986           0 :               *dmin__ = d__;
+   25987           0 :             d__1 = emin, d__2 = z__[j4 - 1];
+   25988           0 :             emin = (d__1<d__2) ? d__1 : d__2;
+   25989             :         }
+   25990             :     }
+   25991             : 
+   25992           0 :     *dnm2 = d__;
+   25993           0 :     *dmin2 = *dmin__;
+   25994           0 :     j4 = 4*(*n0 - 2) - *pp;
+   25995           0 :     j4p2 = j4 + (*pp << 1) - 1;
+   25996           0 :     z__[j4 - 2] = *dnm2 + z__[j4p2];
+   25997           0 :     if (std::abs(z__[j4 - 2])<PLUMED_GMX_FLOAT_MIN) {
+   25998           0 :         z__[j4] = 0.;
+   25999           0 :         *dnm1 = z__[j4p2 + 2];
+   26000           0 :         *dmin__ = *dnm1;
+   26001             :         emin = 0.;
+   26002           0 :     } else if (safemin * z__[j4p2 + 2] < z__[j4 - 2] && safemin * z__[j4 - 2] < 
+   26003             :             z__[j4p2 + 2]) {
+   26004           0 :         temp = z__[j4p2 + 2] / z__[j4 - 2];
+   26005           0 :         z__[j4] = z__[j4p2] * temp;
+   26006           0 :         *dnm1 = *dnm2 * temp;
+   26007             :     } else {
+   26008           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   26009           0 :         *dnm1 = z__[j4p2 + 2] * (*dnm2 / z__[j4 - 2]);
+   26010             :     }
+   26011           0 :     if(*dnm1<*dmin__)
+   26012           0 :       *dmin__ = *dnm1;
+   26013             : 
+   26014           0 :     *dmin1 = *dmin__;
+   26015           0 :     j4 += 4;
+   26016           0 :     j4p2 = j4 + (*pp << 1) - 1;
+   26017           0 :     z__[j4 - 2] = *dnm1 + z__[j4p2];
+   26018           0 :     if (std::abs(z__[j4 - 2])<PLUMED_GMX_FLOAT_MIN) {
+   26019           0 :         z__[j4] = 0.;
+   26020           0 :         *dn = z__[j4p2 + 2];
+   26021           0 :         *dmin__ = *dn;
+   26022             :         emin = 0.;
+   26023           0 :     } else if (safemin * z__[j4p2 + 2] < z__[j4 - 2] && safemin * z__[j4 - 2] < 
+   26024             :             z__[j4p2 + 2]) {
+   26025           0 :         temp = z__[j4p2 + 2] / z__[j4 - 2];
+   26026           0 :         z__[j4] = z__[j4p2] * temp;
+   26027           0 :         *dn = *dnm1 * temp;
+   26028             :     } else {
+   26029           0 :         z__[j4] = z__[j4p2 + 2] * (z__[j4p2] / z__[j4 - 2]);
+   26030           0 :         *dn = z__[j4p2 + 2] * (*dnm1 / z__[j4 - 2]);
+   26031             :     }
+   26032           0 :     if(*dn<*dmin__)
+   26033           0 :       *dmin__ = *dn;
+   26034             : 
+   26035           0 :     z__[j4 + 2] = *dn;
+   26036           0 :     z__[(*n0 << 2) - *pp] = emin;
+   26037           0 :     return;
+   26038             : 
+   26039             : 
+   26040             : } 
+   26041             : }
+   26042             : }
+   26043             : #include <cmath>
+   26044             : 
+   26045             : #include "real.h"
+   26046             : #include "lapack.h"
+   26047             : 
+   26048             : #include "blas/blas.h"
+   26049             : namespace PLMD{
+   26050             : namespace lapack{
+   26051             : using namespace blas;
+   26052             : void 
+   26053           0 : PLUMED_BLAS_F77_FUNC(slasr,SLASR)(const char *side, 
+   26054             :        const char *pivot, 
+   26055             :        const char *direct, 
+   26056             :        int *m,
+   26057             :        int *n, 
+   26058             :        float *c__, 
+   26059             :        float *s, 
+   26060             :        float *a, 
+   26061             :        int *lda)
+   26062             : {
+   26063             :     /* System generated locals */
+   26064             :     int a_dim1, a_offset, i__1, i__2;
+   26065             : 
+   26066             :     /* Local variables */
+   26067             :     int i__, j;
+   26068             :     float temp;
+   26069             :     float ctemp, stemp;
+   26070             : 
+   26071           0 :     --c__;
+   26072           0 :     --s;
+   26073           0 :     a_dim1 = *lda;
+   26074           0 :     a_offset = 1 + a_dim1;
+   26075           0 :     a -= a_offset;
+   26076             : 
+   26077             :     /* Function Body */
+   26078             : 
+   26079           0 :     if (*m == 0 || *n == 0) {
+   26080             :         return;
+   26081             :     }
+   26082           0 :     if (*side=='L' || *side=='l') {
+   26083             : 
+   26084           0 :         if (*pivot=='V' || *pivot=='v') {
+   26085           0 :             if (*direct=='F' || *direct=='f') {
+   26086             :                 i__1 = *m - 1;
+   26087           0 :                 for (j = 1; j <= i__1; ++j) {
+   26088           0 :                     ctemp = c__[j];
+   26089           0 :                     stemp = s[j];
+   26090           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26091           0 :                         i__2 = *n;
+   26092           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26093           0 :                             temp = a[j + 1 + i__ * a_dim1];
+   26094           0 :                             a[j + 1 + i__ * a_dim1] = ctemp * temp - stemp * 
+   26095           0 :                                     a[j + i__ * a_dim1];
+   26096           0 :                             a[j + i__ * a_dim1] = stemp * temp + ctemp * a[j 
+   26097           0 :                                     + i__ * a_dim1];
+   26098             :                         }
+   26099             :                     }
+   26100             :                 }
+   26101           0 :             } else if (*direct=='B' || *direct=='b') {
+   26102           0 :                 for (j = *m - 1; j >= 1; --j) {
+   26103           0 :                     ctemp = c__[j];
+   26104           0 :                     stemp = s[j];
+   26105           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26106           0 :                         i__1 = *n;
+   26107           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26108           0 :                             temp = a[j + 1 + i__ * a_dim1];
+   26109           0 :                             a[j + 1 + i__ * a_dim1] = ctemp * temp - stemp * 
+   26110           0 :                                     a[j + i__ * a_dim1];
+   26111           0 :                             a[j + i__ * a_dim1] = stemp * temp + ctemp * a[j 
+   26112           0 :                                     + i__ * a_dim1];
+   26113             :                         }
+   26114             :                     }
+   26115             :                 }
+   26116             :             }
+   26117           0 :         } else if (*pivot=='T' || *pivot=='t') {
+   26118           0 :             if (*direct=='F' || *direct=='f') {
+   26119             :                 i__1 = *m;
+   26120           0 :                 for (j = 2; j <= i__1; ++j) {
+   26121           0 :                     ctemp = c__[j - 1];
+   26122           0 :                     stemp = s[j - 1];
+   26123           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26124           0 :                         i__2 = *n;
+   26125           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26126           0 :                             temp = a[j + i__ * a_dim1];
+   26127           0 :                             a[j + i__ * a_dim1] = ctemp * temp - stemp * a[
+   26128           0 :                                     i__ * a_dim1 + 1];
+   26129           0 :                             a[i__ * a_dim1 + 1] = stemp * temp + ctemp * a[
+   26130           0 :                                     i__ * a_dim1 + 1];
+   26131             :                         }
+   26132             :                     }
+   26133             :                 }
+   26134           0 :             } else if (*direct=='B' || *direct=='b') {
+   26135           0 :                 for (j = *m; j >= 2; --j) {
+   26136           0 :                     ctemp = c__[j - 1];
+   26137           0 :                     stemp = s[j - 1];
+   26138           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26139           0 :                         i__1 = *n;
+   26140           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26141           0 :                             temp = a[j + i__ * a_dim1];
+   26142           0 :                             a[j + i__ * a_dim1] = ctemp * temp - stemp * a[
+   26143           0 :                                     i__ * a_dim1 + 1];
+   26144           0 :                             a[i__ * a_dim1 + 1] = stemp * temp + ctemp * a[
+   26145           0 :                                     i__ * a_dim1 + 1];
+   26146             :                         }
+   26147             :                     }
+   26148             :                 }
+   26149             :             }
+   26150           0 :         } else if (*pivot=='B' || *pivot=='b') {
+   26151           0 :             if (*direct=='F' || *direct=='f') {
+   26152             :                 i__1 = *m - 1;
+   26153           0 :                 for (j = 1; j <= i__1; ++j) {
+   26154           0 :                     ctemp = c__[j];
+   26155           0 :                     stemp = s[j];
+   26156           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26157           0 :                         i__2 = *n;
+   26158           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26159           0 :                             temp = a[j + i__ * a_dim1];
+   26160           0 :                             a[j + i__ * a_dim1] = stemp * a[*m + i__ * a_dim1]
+   26161           0 :                                      + ctemp * temp;
+   26162           0 :                             a[*m + i__ * a_dim1] = ctemp * a[*m + i__ * 
+   26163           0 :                                     a_dim1] - stemp * temp;
+   26164             :                         }
+   26165             :                     }
+   26166             :                 }
+   26167           0 :             } else if (*direct=='B' || *direct=='b') {
+   26168           0 :                 for (j = *m - 1; j >= 1; --j) {
+   26169           0 :                     ctemp = c__[j];
+   26170           0 :                     stemp = s[j];
+   26171           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26172           0 :                         i__1 = *n;
+   26173           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26174           0 :                             temp = a[j + i__ * a_dim1];
+   26175           0 :                             a[j + i__ * a_dim1] = stemp * a[*m + i__ * a_dim1]
+   26176           0 :                                      + ctemp * temp;
+   26177           0 :                             a[*m + i__ * a_dim1] = ctemp * a[*m + i__ * 
+   26178           0 :                                     a_dim1] - stemp * temp;
+   26179             :                         }
+   26180             :                     }
+   26181             :                 }
+   26182             :             }
+   26183             :         }
+   26184           0 :     } else if (*side=='R' || *side=='r') {
+   26185             : 
+   26186           0 :         if (*pivot=='V' || *pivot=='v') {
+   26187           0 :             if (*direct=='F' || *direct=='f') {
+   26188             :                 i__1 = *n - 1;
+   26189           0 :                 for (j = 1; j <= i__1; ++j) {
+   26190           0 :                     ctemp = c__[j];
+   26191           0 :                     stemp = s[j];
+   26192           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26193           0 :                         i__2 = *m;
+   26194           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26195           0 :                             temp = a[i__ + (j + 1) * a_dim1];
+   26196           0 :                             a[i__ + (j + 1) * a_dim1] = ctemp * temp - stemp *
+   26197           0 :                                      a[i__ + j * a_dim1];
+   26198           0 :                             a[i__ + j * a_dim1] = stemp * temp + ctemp * a[
+   26199           0 :                                     i__ + j * a_dim1];
+   26200             :                         }
+   26201             :                     }
+   26202             :                 }
+   26203           0 :             } else if (*direct=='B' || *direct=='b') {
+   26204           0 :                 for (j = *n - 1; j >= 1; --j) {
+   26205           0 :                     ctemp = c__[j];
+   26206           0 :                     stemp = s[j];
+   26207           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26208           0 :                         i__1 = *m;
+   26209           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26210           0 :                             temp = a[i__ + (j + 1) * a_dim1];
+   26211           0 :                             a[i__ + (j + 1) * a_dim1] = ctemp * temp - stemp *
+   26212           0 :                                      a[i__ + j * a_dim1];
+   26213           0 :                             a[i__ + j * a_dim1] = stemp * temp + ctemp * a[
+   26214           0 :                                     i__ + j * a_dim1];
+   26215             :                         }
+   26216             :                     }
+   26217             :                 }
+   26218             :             }
+   26219           0 :         } else if (*pivot=='T' || *pivot=='t') {
+   26220           0 :             if (*direct=='F' || *direct=='f') {
+   26221             :                 i__1 = *n;
+   26222           0 :                 for (j = 2; j <= i__1; ++j) {
+   26223           0 :                     ctemp = c__[j - 1];
+   26224           0 :                     stemp = s[j - 1];
+   26225           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26226           0 :                         i__2 = *m;
+   26227           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26228           0 :                             temp = a[i__ + j * a_dim1];
+   26229           0 :                             a[i__ + j * a_dim1] = ctemp * temp - stemp * a[
+   26230           0 :                                     i__ + a_dim1];
+   26231           0 :                             a[i__ + a_dim1] = stemp * temp + ctemp * a[i__ + 
+   26232           0 :                                     a_dim1];
+   26233             :                         }
+   26234             :                     }
+   26235             :                 }
+   26236           0 :             } else if (*direct=='B' || *direct=='b') {
+   26237           0 :                 for (j = *n; j >= 2; --j) {
+   26238           0 :                     ctemp = c__[j - 1];
+   26239           0 :                     stemp = s[j - 1];
+   26240           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26241           0 :                         i__1 = *m;
+   26242           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26243           0 :                             temp = a[i__ + j * a_dim1];
+   26244           0 :                             a[i__ + j * a_dim1] = ctemp * temp - stemp * a[
+   26245           0 :                                     i__ + a_dim1];
+   26246           0 :                             a[i__ + a_dim1] = stemp * temp + ctemp * a[i__ + 
+   26247           0 :                                     a_dim1];
+   26248             :                         }
+   26249             :                     }
+   26250             :                 }
+   26251             :             }
+   26252           0 :         } else if (*pivot=='B' || *pivot=='b') {
+   26253           0 :             if (*direct=='F' || *direct=='f') {
+   26254             :                 i__1 = *n - 1;
+   26255           0 :                 for (j = 1; j <= i__1; ++j) {
+   26256           0 :                     ctemp = c__[j];
+   26257           0 :                     stemp = s[j];
+   26258           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26259           0 :                         i__2 = *m;
+   26260           0 :                         for (i__ = 1; i__ <= i__2; ++i__) {
+   26261           0 :                             temp = a[i__ + j * a_dim1];
+   26262           0 :                             a[i__ + j * a_dim1] = stemp * a[i__ + *n * a_dim1]
+   26263           0 :                                      + ctemp * temp;
+   26264           0 :                             a[i__ + *n * a_dim1] = ctemp * a[i__ + *n * 
+   26265           0 :                                     a_dim1] - stemp * temp;
+   26266             :                         }
+   26267             :                     }
+   26268             :                 }
+   26269           0 :             } else if (*direct=='B' || *direct=='b') {
+   26270           0 :                 for (j = *n - 1; j >= 1; --j) {
+   26271           0 :                     ctemp = c__[j];
+   26272           0 :                     stemp = s[j];
+   26273           0 :                     if (std::abs(ctemp-1.0)>PLUMED_GMX_FLOAT_EPS || std::abs(stemp)>PLUMED_GMX_FLOAT_MIN) {
+   26274           0 :                         i__1 = *m;
+   26275           0 :                         for (i__ = 1; i__ <= i__1; ++i__) {
+   26276           0 :                             temp = a[i__ + j * a_dim1];
+   26277           0 :                             a[i__ + j * a_dim1] = stemp * a[i__ + *n * a_dim1]
+   26278           0 :                                      + ctemp * temp;
+   26279           0 :                             a[i__ + *n * a_dim1] = ctemp * a[i__ + *n * 
+   26280           0 :                                     a_dim1] - stemp * temp;
+   26281             :                         }
+   26282             :                     }
+   26283             :                 }
+   26284             :             }
+   26285             :         }
+   26286             :     }
+   26287             : 
+   26288             :     return;
+   26289             : 
+   26290             : }
+   26291             : 
+   26292             : 
+   26293             : }
+   26294             : }
+   26295             : #include "lapack.h"
+   26296             : 
+   26297             : #include "blas/blas.h"
+   26298             : namespace PLMD{
+   26299             : namespace lapack{
+   26300             : using namespace blas;
+   26301             : void 
+   26302           0 : PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)(const char *id, 
+   26303             :         int *n, 
+   26304             :         float *d__, 
+   26305             :         int *info)
+   26306             : {
+   26307             :     int i__1, i__2;
+   26308             : 
+   26309             :     int i__, j;
+   26310             :     float d1, d2, d3;
+   26311             :     int dir;
+   26312             :     float tmp;
+   26313             :     int endd;
+   26314             :     int stack[64];
+   26315             :     float dmnmx;
+   26316             :     int start;
+   26317             :     int stkpnt;
+   26318             : 
+   26319           0 :     --d__;
+   26320             : 
+   26321           0 :     *info = 0;
+   26322             :     dir = -1;
+   26323           0 :     if (*id=='D' || *id=='d') 
+   26324             :         dir = 0;
+   26325           0 :     else if (*id=='I' || *id=='i') 
+   26326             :         dir = 1;
+   26327             :    
+   26328             :     if (dir == -1) {
+   26329           0 :         *info = -1;
+   26330           0 :     } else if (*n < 0) {
+   26331           0 :         *info = -2;
+   26332             :     }
+   26333           0 :     if (*info != 0) {
+   26334             :         return;
+   26335             :     }
+   26336           0 :     if (*n <= 1) {
+   26337             :         return;
+   26338             :     }
+   26339             : 
+   26340             :     stkpnt = 1;
+   26341           0 :     stack[0] = 1;
+   26342           0 :     stack[1] = *n;
+   26343           0 : L10:
+   26344           0 :     start = stack[(stkpnt << 1) - 2];
+   26345           0 :     endd = stack[(stkpnt << 1) - 1];
+   26346           0 :     --stkpnt;
+   26347           0 :     if (endd - start <= 20 && endd - start > 0) {
+   26348             : 
+   26349             : 
+   26350           0 :         if (dir == 0) {
+   26351             : 
+   26352             :             i__1 = endd;
+   26353           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26354             :                 i__2 = start + 1;
+   26355           0 :                 for (j = i__; j >= i__2; --j) {
+   26356           0 :                     if (d__[j] > d__[j - 1]) {
+   26357             :                         dmnmx = d__[j];
+   26358           0 :                         d__[j] = d__[j - 1];
+   26359           0 :                         d__[j - 1] = dmnmx;
+   26360             :                     } else {
+   26361           0 :                         goto L30;
+   26362             :                     }
+   26363             :                 }
+   26364           0 : L30:
+   26365             :                 ;
+   26366             :             }
+   26367             : 
+   26368             :         } else {
+   26369             : 
+   26370             :             i__1 = endd;
+   26371           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26372             :                 i__2 = start + 1;
+   26373           0 :                 for (j = i__; j >= i__2; --j) {
+   26374           0 :                     if (d__[j] < d__[j - 1]) {
+   26375             :                         dmnmx = d__[j];
+   26376           0 :                         d__[j] = d__[j - 1];
+   26377           0 :                         d__[j - 1] = dmnmx;
+   26378             :                     } else {
+   26379           0 :                         goto L50;
+   26380             :                     }
+   26381             :                 }
+   26382           0 : L50:
+   26383             :                 ;
+   26384             :             }
+   26385             : 
+   26386             :         }
+   26387             : 
+   26388           0 :     } else if (endd - start > 20) {
+   26389             : 
+   26390           0 :         d1 = d__[start];
+   26391           0 :         d2 = d__[endd];
+   26392           0 :         i__ = (start + endd) / 2;
+   26393           0 :         d3 = d__[i__];
+   26394           0 :         if (d1 < d2) {
+   26395           0 :             if (d3 < d1) {
+   26396             :                 dmnmx = d1;
+   26397           0 :             } else if (d3 < d2) {
+   26398             :                 dmnmx = d3;
+   26399             :             } else {
+   26400             :                 dmnmx = d2;
+   26401             :             }
+   26402             :         } else {
+   26403           0 :             if (d3 < d2) {
+   26404             :                 dmnmx = d2;
+   26405           0 :             } else if (d3 < d1) {
+   26406             :                 dmnmx = d3;
+   26407             :             } else {
+   26408             :                 dmnmx = d1;
+   26409             :             }
+   26410             :         }
+   26411             : 
+   26412           0 :         if (dir == 0) {
+   26413             : 
+   26414           0 :             i__ = start - 1;
+   26415           0 :             j = endd + 1;
+   26416           0 : L60:
+   26417           0 : L70:
+   26418           0 :             --j;
+   26419           0 :             if (d__[j] < dmnmx) {
+   26420           0 :                 goto L70;
+   26421             :             }
+   26422           0 : L80:
+   26423           0 :             ++i__;
+   26424           0 :             if (d__[i__] > dmnmx) {
+   26425           0 :                 goto L80;
+   26426             :             }
+   26427           0 :             if (i__ < j) {
+   26428             :                 tmp = d__[i__];
+   26429           0 :                 d__[i__] = d__[j];
+   26430           0 :                 d__[j] = tmp;
+   26431           0 :                 goto L60;
+   26432             :             }
+   26433           0 :             if (j - start > endd - j - 1) {
+   26434             :                 ++stkpnt;
+   26435             :                 stack[(stkpnt << 1) - 2] = start;
+   26436           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26437           0 :                 ++stkpnt;
+   26438           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26439           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26440             :             } else {
+   26441             :                 ++stkpnt;
+   26442           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26443           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26444           0 :                 ++stkpnt;
+   26445           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26446           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26447             :             }
+   26448             :         } else {
+   26449             : 
+   26450           0 :             i__ = start - 1;
+   26451           0 :             j = endd + 1;
+   26452           0 : L90:
+   26453           0 : L100:
+   26454           0 :             --j;
+   26455           0 :             if (d__[j] > dmnmx) {
+   26456           0 :                 goto L100;
+   26457             :             }
+   26458           0 : L110:
+   26459           0 :             ++i__;
+   26460           0 :             if (d__[i__] < dmnmx) {
+   26461           0 :                 goto L110;
+   26462             :             }
+   26463           0 :             if (i__ < j) {
+   26464             :                 tmp = d__[i__];
+   26465           0 :                 d__[i__] = d__[j];
+   26466           0 :                 d__[j] = tmp;
+   26467           0 :                 goto L90;
+   26468             :             }
+   26469           0 :             if (j - start > endd - j - 1) {
+   26470             :                 ++stkpnt;
+   26471             :                 stack[(stkpnt << 1) - 2] = start;
+   26472           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26473           0 :                 ++stkpnt;
+   26474           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26475           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26476             :             } else {
+   26477             :                 ++stkpnt;
+   26478           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26479           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26480           0 :                 ++stkpnt;
+   26481           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26482           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26483             :             }
+   26484             :         }
+   26485             :     }
+   26486           0 :     if (stkpnt > 0) {
+   26487           0 :         goto L10;
+   26488             :     }
+   26489             :     return;
+   26490             : 
+   26491             : }
+   26492             : }
+   26493             : }
+   26494             : #include "lapack.h"
+   26495             : #include "blas/blas.h"
+   26496             : namespace PLMD{
+   26497             : namespace lapack{
+   26498             : using namespace blas;
+   26499             : 
+   26500           0 : void PLUMED_BLAS_F77_FUNC(slasrt2,SLASRT2)(const char *id, 
+   26501             :               int *n, 
+   26502             :               float *d__, 
+   26503             :               int * key, 
+   26504             :               int *info)
+   26505             : {
+   26506             :     int i__1, i__2;
+   26507             : 
+   26508             :     int i__, j;
+   26509             :     float d1, d2, d3;
+   26510             :     int dir;
+   26511             :     float tmp;
+   26512             :     int endd;
+   26513             :     int stack[64];
+   26514             :     float dmnmx;
+   26515             :     int start;
+   26516             :     int tmpkey, stkpnt;
+   26517             : 
+   26518           0 :     --key;
+   26519           0 :     --d__;
+   26520             : 
+   26521           0 :     *info = 0;
+   26522             :     dir = -1;
+   26523           0 :     if (*id=='D' || *id=='d')
+   26524             :         dir = 0;
+   26525           0 :     else if (*id=='I' || *id=='i')
+   26526             :         dir = 1;
+   26527             :     
+   26528             :     if (dir == -1) {
+   26529           0 :         *info = -1;
+   26530           0 :     } else if (*n < 0) {
+   26531           0 :         *info = -2;
+   26532             :     }
+   26533           0 :     if (*info != 0) {
+   26534             :         return;
+   26535             :     }
+   26536             : 
+   26537           0 :     if (*n <= 1) {
+   26538             :         return;
+   26539             :     }
+   26540             : 
+   26541             :     stkpnt = 1;
+   26542           0 :     stack[0] = 1;
+   26543           0 :     stack[1] = *n;
+   26544           0 : L10:
+   26545           0 :     start = stack[(stkpnt << 1) - 2];
+   26546           0 :     endd = stack[(stkpnt << 1) - 1];
+   26547           0 :     --stkpnt;
+   26548           0 :     if (endd - start > 0) {
+   26549             : 
+   26550           0 :         if (dir == 0) {
+   26551             : 
+   26552             :             i__1 = endd;
+   26553           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26554             :                 i__2 = start + 1;
+   26555           0 :                 for (j = i__; j >= i__2; --j) {
+   26556           0 :                     if (d__[j] > d__[j - 1]) {
+   26557             :                         dmnmx = d__[j];
+   26558           0 :                         d__[j] = d__[j - 1];
+   26559           0 :                         d__[j - 1] = dmnmx;
+   26560           0 :                         tmpkey = key[j];
+   26561           0 :                         key[j] = key[j - 1];
+   26562           0 :                         key[j - 1] = tmpkey;
+   26563             :                     } else {
+   26564             :                         break;
+   26565             :                     }
+   26566             :                 }
+   26567             :             }
+   26568             : 
+   26569             :         } else {
+   26570             : 
+   26571             :             i__1 = endd;
+   26572           0 :             for (i__ = start + 1; i__ <= i__1; ++i__) {
+   26573             :                 i__2 = start + 1;
+   26574           0 :                 for (j = i__; j >= i__2; --j) {
+   26575           0 :                     if (d__[j] < d__[j - 1]) {
+   26576             :                         dmnmx = d__[j];
+   26577           0 :                         d__[j] = d__[j - 1];
+   26578           0 :                         d__[j - 1] = dmnmx;
+   26579           0 :                         tmpkey = key[j];
+   26580           0 :                         key[j] = key[j - 1];
+   26581           0 :                         key[j - 1] = tmpkey;
+   26582             :                     } else {
+   26583             :                         break;
+   26584             :                     }
+   26585             :                 }
+   26586             :             }
+   26587             : 
+   26588             :         }
+   26589             : 
+   26590           0 :     } else if (endd - start > 20) {
+   26591             : 
+   26592           0 :         d1 = d__[start];
+   26593           0 :         d2 = d__[endd];
+   26594           0 :         i__ = (start + endd) / 2;
+   26595           0 :         d3 = d__[i__];
+   26596           0 :         if (d1 < d2) {
+   26597           0 :             if (d3 < d1) {
+   26598             :                 dmnmx = d1;
+   26599           0 :             } else if (d3 < d2) {
+   26600             :                 dmnmx = d3;
+   26601             :             } else {
+   26602             :                 dmnmx = d2;
+   26603             :             }
+   26604             :         } else {
+   26605           0 :             if (d3 < d2) {
+   26606             :                 dmnmx = d2;
+   26607           0 :             } else if (d3 < d1) {
+   26608             :                 dmnmx = d3;
+   26609             :             } else {
+   26610             :                 dmnmx = d1;
+   26611             :             }
+   26612             :         }
+   26613             : 
+   26614           0 :         if (dir == 0) {
+   26615             : 
+   26616           0 :             i__ = start - 1;
+   26617           0 :             j = endd + 1;
+   26618           0 : L60:
+   26619           0 : L70:
+   26620           0 :             --j;
+   26621           0 :             if (d__[j] < dmnmx) {
+   26622           0 :                 goto L70;
+   26623             :             }
+   26624           0 : L80:
+   26625           0 :             ++i__;
+   26626           0 :             if (d__[i__] > dmnmx) {
+   26627           0 :                 goto L80;
+   26628             :             }
+   26629           0 :             if (i__ < j) {
+   26630             :                 tmp = d__[i__];
+   26631           0 :                 d__[i__] = d__[j];
+   26632           0 :                 d__[j] = tmp;
+   26633           0 :                 tmpkey = key[j];
+   26634           0 :                 key[j] = key[i__];
+   26635           0 :                 key[i__] = tmpkey;
+   26636           0 :                 goto L60;
+   26637             :             }
+   26638           0 :             if (j - start > endd - j - 1) {
+   26639             :                 ++stkpnt;
+   26640             :                 stack[(stkpnt << 1) - 2] = start;
+   26641           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26642           0 :                 ++stkpnt;
+   26643           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26644           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26645             :             } else {
+   26646             :                 ++stkpnt;
+   26647           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26648           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26649           0 :                 ++stkpnt;
+   26650           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26651           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26652             :             }
+   26653             :         } else {
+   26654             : 
+   26655           0 :             i__ = start - 1;
+   26656           0 :             j = endd + 1;
+   26657           0 : L90:
+   26658           0 : L100:
+   26659           0 :             --j;
+   26660           0 :             if (d__[j] > dmnmx) {
+   26661           0 :                 goto L100;
+   26662             :             }
+   26663           0 : L110:
+   26664           0 :             ++i__;
+   26665           0 :             if (d__[i__] < dmnmx) {
+   26666           0 :                 goto L110;
+   26667             :             }
+   26668           0 :             if (i__ < j) {
+   26669             :                 tmp = d__[i__];
+   26670           0 :                 d__[i__] = d__[j];
+   26671           0 :                 d__[j] = tmp;
+   26672           0 :                 tmpkey = key[j];
+   26673           0 :                 key[j] = key[i__];
+   26674           0 :                 key[i__] = tmpkey;
+   26675           0 :                 goto L90;
+   26676             :             }
+   26677           0 :             if (j - start > endd - j - 1) {
+   26678             :                 ++stkpnt;
+   26679             :                 stack[(stkpnt << 1) - 2] = start;
+   26680           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26681           0 :                 ++stkpnt;
+   26682           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26683           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26684             :             } else {
+   26685             :                 ++stkpnt;
+   26686           0 :                 stack[(stkpnt << 1) - 2] = j + 1;
+   26687           0 :                 stack[(stkpnt << 1) - 1] = endd;
+   26688           0 :                 ++stkpnt;
+   26689           0 :                 stack[(stkpnt << 1) - 2] = start;
+   26690           0 :                 stack[(stkpnt << 1) - 1] = j;
+   26691             :             }
+   26692             :         }
+   26693             :     }
+   26694           0 :     if (stkpnt > 0) {
+   26695           0 :         goto L10;
+   26696             :     }
+   26697             : 
+   26698             :     return;
+   26699             : }
+   26700             : }
+   26701             : }
+   26702             : #include <cmath>
+   26703             : #include "real.h"
+   26704             : #include "lapack.h"
+   26705             : 
+   26706             : #include "blas/blas.h"
+   26707             : namespace PLMD{
+   26708             : namespace lapack{
+   26709             : using namespace blas;
+   26710             : void
+   26711           0 : PLUMED_BLAS_F77_FUNC(slassq,SLASSQ)(int *n,
+   26712             :                         float *x,
+   26713             :                         int *incx,
+   26714             :                         float *scale,
+   26715             :                         float *sumsq)
+   26716             : {
+   26717             :   int ix;
+   26718             :   float absxi,t;
+   26719             : 
+   26720           0 :   if(*n>0) {
+   26721           0 :     for(ix=0;ix<=(*n-1)*(*incx);ix+=*incx) {
+   26722           0 :       if(std::abs(x[ix])>PLUMED_GMX_FLOAT_MIN) {
+   26723             :         absxi = std::abs(x[ix]);
+   26724           0 :         if(*scale<absxi) {
+   26725           0 :           t = *scale/absxi;
+   26726           0 :           t = t*t;
+   26727           0 :           *sumsq = 1.0 + (*sumsq)*t;
+   26728           0 :           *scale = absxi;
+   26729             :         } else {
+   26730           0 :           t = absxi/(*scale);
+   26731           0 :           *sumsq += t*t;
+   26732             :         }
+   26733             :       }
+   26734             :     }
+   26735             :   }
+   26736           0 :   return;
+   26737             : }
+   26738             : }
+   26739             : }
+   26740             : #include <cmath>
+   26741             : #include "lapack.h"
+   26742             : #include "lapack_limits.h"
+   26743             : 
+   26744             : #include "real.h"
+   26745             : 
+   26746             : #include "blas/blas.h"
+   26747             : namespace PLMD{
+   26748             : namespace lapack{
+   26749             : using namespace blas;
+   26750             : void 
+   26751           0 : PLUMED_BLAS_F77_FUNC(slasv2,SLASV2)(float *f, 
+   26752             :                         float *g, 
+   26753             :                         float *h__, 
+   26754             :                         float *ssmin, 
+   26755             :                         float *ssmax, 
+   26756             :                         float *snr, 
+   26757             :                         float *csr, 
+   26758             :                         float *snl, 
+   26759             :                         float *csl)
+   26760             : {
+   26761             :     float d__1;
+   26762             : 
+   26763             :     float a, d__, l, m, r__, s, t, fa, ga, ha, ft, gt, ht, mm, tt,
+   26764             :              clt, crt, slt, srt;
+   26765             :     int pmax;
+   26766             :     float temp;
+   26767             :     int swap;
+   26768             :     float tsign=1.0;
+   26769             :     int gasmal;
+   26770             : 
+   26771           0 :     ft = *f;
+   26772             :     fa = std::abs(ft);
+   26773           0 :     ht = *h__;
+   26774             :     ha = std::abs(*h__);
+   26775             : 
+   26776             :     pmax = 1;
+   26777             :     swap = ha > fa;
+   26778           0 :     if (swap) {
+   26779             :         pmax = 3;
+   26780             :         temp = ft;
+   26781             :         ft = ht;
+   26782             :         ht = temp;
+   26783             :         temp = fa;
+   26784             :         fa = ha;
+   26785             :         ha = temp;
+   26786             : 
+   26787             :     }
+   26788           0 :     gt = *g;
+   26789             :     ga = std::abs(gt);
+   26790           0 :     if (std::abs(ga)<PLUMED_GMX_FLOAT_MIN) {
+   26791             : 
+   26792           0 :         *ssmin = ha;
+   26793           0 :         *ssmax = fa;
+   26794             :         clt = 1.;
+   26795             :         crt = 1.;
+   26796             :         slt = 0.;
+   26797             :         srt = 0.;
+   26798             :     } else {
+   26799             :         gasmal = 1;
+   26800           0 :         if (ga > fa) {
+   26801             :             pmax = 2;
+   26802           0 :             if (fa / ga < PLUMED_GMX_FLOAT_EPS) {
+   26803             : 
+   26804             :                 gasmal = 0;
+   26805           0 :                 *ssmax = ga;
+   26806           0 :                 if (ha > 1.) {
+   26807           0 :                     *ssmin = fa / (ga / ha);
+   26808             :                 } else {
+   26809           0 :                     *ssmin = fa / ga * ha;
+   26810             :                 }
+   26811             :                 clt = 1.;
+   26812           0 :                 slt = ht / gt;
+   26813             :                 srt = 1.;
+   26814           0 :                 crt = ft / gt;
+   26815             :             }
+   26816             :         }
+   26817           0 :         if (gasmal) {
+   26818             : 
+   26819           0 :             d__ = fa - ha;
+   26820           0 :             if ( std::abs( fa - d__ )<PLUMED_GMX_FLOAT_EPS*std::abs( fa + d__ )) {
+   26821             :                 l = 1.;
+   26822             :             } else {
+   26823           0 :                 l = d__ / fa;
+   26824             :             }
+   26825             : 
+   26826           0 :             m = gt / ft;
+   26827           0 :             t = 2. - l;
+   26828             : 
+   26829           0 :             mm = m * m;
+   26830           0 :             tt = t * t;
+   26831           0 :             s =  std::sqrt(tt + mm);
+   26832             : 
+   26833           0 :             if ( std::abs(l)<PLUMED_GMX_FLOAT_MIN) {
+   26834             :                 r__ = std::abs(m);
+   26835             :             } else {
+   26836           0 :                 r__ =  std::sqrt(l * l + mm);
+   26837             :             }
+   26838           0 :             a = (s + r__) * .5;
+   26839             : 
+   26840           0 :             *ssmin = ha / a;
+   26841           0 :             *ssmax = fa * a;
+   26842           0 :             if ( std::abs(mm)<PLUMED_GMX_FLOAT_MIN) {
+   26843             : 
+   26844           0 :                 if (std::abs(l)<PLUMED_GMX_FLOAT_MIN) {
+   26845           0 :                     t = ( (ft>0) ? 2.0 : -2.0) * ( (gt>0) ? 1.0 : -1.0);
+   26846             :                 } else {
+   26847           0 :                     t = gt / ( (ft>0) ? d__ : -d__) + m / t;
+   26848             :                 }
+   26849             :             } else {
+   26850           0 :                 t = (m / (s + t) + m / (r__ + l)) * (a + 1.);
+   26851             :             }
+   26852           0 :             l =  std::sqrt(t * t + 4.);
+   26853           0 :             crt = 2. / l;
+   26854           0 :             srt = t / l;
+   26855           0 :             clt = (crt + srt * m) / a;
+   26856           0 :             slt = ht / ft * srt / a;
+   26857             :         }
+   26858             :     }
+   26859           0 :     if (swap) {
+   26860           0 :         *csl = srt;
+   26861           0 :         *snl = crt;
+   26862           0 :         *csr = slt;
+   26863           0 :         *snr = clt;
+   26864             :     } else {
+   26865           0 :         *csl = clt;
+   26866           0 :         *snl = slt;
+   26867           0 :         *csr = crt;
+   26868           0 :         *snr = srt;
+   26869             :     }
+   26870             : 
+   26871           0 :     if (pmax == 1) {
+   26872           0 :         tsign = ( (*csr>0) ? 1.0 : -1.0) * ( (*csl>0) ? 1.0 : -1.0) * ( (*f>0) ? 1.0 : -1.0);
+   26873             :     }
+   26874           0 :     if (pmax == 2) {
+   26875           0 :         tsign = ( (*snr>0) ? 1.0 : -1.0) * ( (*csl>0) ? 1.0 : -1.0) * ( (*g>0) ? 1.0 : -1.0);
+   26876             :     }
+   26877           0 :     if (pmax == 3) {
+   26878           0 :         tsign = ( (*snr>0) ? 1.0 : -1.0) * ( (*snl>0) ? 1.0 : -1.0) * ( (*h__>0) ? 1.0 : -1.0);
+   26879             :     }
+   26880           0 :     if(tsign<0)
+   26881           0 :       *ssmax *= -1.0;
+   26882           0 :     d__1 = tsign * ( (*f>0) ? 1.0 : -1.0) * ( (*h__>0) ? 1.0 : -1.0);
+   26883           0 :     if(d__1<0)
+   26884           0 :       *ssmin *= -1.0;
+   26885           0 :     return;
+   26886             : 
+   26887             : }
+   26888             : }
+   26889             : }
+   26890             : #include "lapack.h"
+   26891             : 
+   26892             : /* LAPACK */
+   26893             : #include "blas/blas.h"
+   26894             : namespace PLMD{
+   26895             : namespace lapack{
+   26896             : using namespace blas;
+   26897             : void
+   26898           0 : PLUMED_BLAS_F77_FUNC(slaswp,SLASWP)(int *n,
+   26899             :         float *a,
+   26900             :         int *lda,
+   26901             :         int *k1,
+   26902             :         int *k2,
+   26903             :         int *ipiv,
+   26904             :         int *incx)
+   26905             : {
+   26906             :   int ix0,i1,i2,inc,n32;
+   26907             :   int ix,i,j,ip,k;
+   26908             :   float temp;
+   26909             : 
+   26910           0 :   if(*incx>0) {
+   26911           0 :     ix0 = *k1 - 1;
+   26912             :     i1 = *k1 - 1;
+   26913           0 :     i2 = *k2;
+   26914             :     inc = 1;
+   26915           0 :   } else if(*incx<0) {
+   26916           0 :     ix0 = *incx * (1- *k2);
+   26917           0 :     i1 = *k2 - 1;
+   26918           0 :     i2 = *k1;
+   26919             :     inc = -1;
+   26920             :   } else
+   26921             :     return;
+   26922             : 
+   26923           0 :   n32 = *n / 32;
+   26924             :   
+   26925           0 :   n32 *= 32;
+   26926             : 
+   26927             : 
+   26928           0 :   if(n32!=0) {
+   26929           0 :     for(j=0;j<n32;j+=32) {
+   26930             :       ix = ix0;
+   26931           0 :       for(i=i1;i<i2;i+=inc,ix+=*incx) {
+   26932           0 :         ip = ipiv[ix] - 1;
+   26933           0 :         if(ip != i) {
+   26934           0 :           for(k=j;k<j+32;k++) {
+   26935           0 :             temp = a[(k)*(*lda)+i];
+   26936           0 :             a[(k)*(*lda)+i] = a[(k)*(*lda)+ip];
+   26937           0 :             a[(k)*(*lda)+ip] = temp;
+   26938             :           }
+   26939             :         }
+   26940             :       }
+   26941             :     }
+   26942             :   }
+   26943           0 :   if(n32!=*n) {
+   26944             :     ix = ix0;
+   26945           0 :     for(i=i1;i<i2;i+=inc,ix+=*incx) {
+   26946           0 :       ip = ipiv[ix] - 1;
+   26947           0 :       if(ip != i) {
+   26948           0 :         for(k=n32;k<*n;k++) {
+   26949           0 :             temp = a[(k)*(*lda)+i];
+   26950           0 :             a[(k)*(*lda)+i] = a[(k)*(*lda)+ip];
+   26951           0 :             a[(k)*(*lda)+ip] = temp;
+   26952             :         }
+   26953             :       }
+   26954             :     }
+   26955             :   }
+   26956             :   return;
+   26957             : }
+   26958             : }
+   26959             : }
+   26960             : #include <cctype>
+   26961             : #include "blas/blas.h"
+   26962             : #include "lapack.h"
+   26963             : #include "lapack_limits.h"
+   26964             : 
+   26965             : 
+   26966             : #include "blas/blas.h"
+   26967             : namespace PLMD{
+   26968             : namespace lapack{
+   26969             : using namespace blas;
+   26970             : void
+   26971           0 : PLUMED_BLAS_F77_FUNC(slatrd,SLATRD)(const char *  uplo,
+   26972             :        int  *   n,
+   26973             :        int  *   nb,
+   26974             :        float * a,
+   26975             :        int *    lda,
+   26976             :        float * e,
+   26977             :        float * tau,
+   26978             :        float * w,
+   26979             :        int *    ldw)
+   26980             : {
+   26981             :   int i,iw;
+   26982             :   int ti1,ti2,ti3;
+   26983             :   float one,zero,minusone,alpha;
+   26984           0 :   const char ch=std::toupper(*uplo);
+   26985             : 
+   26986           0 :   one=1.0;
+   26987           0 :   minusone=-1.0;
+   26988           0 :   zero=0.0;
+   26989             : 
+   26990           0 :   if(*n<=0)
+   26991             :     return;
+   26992             : 
+   26993           0 :   if(ch=='U') {
+   26994           0 :     for(i=*n;i>=(*n-*nb+1);i--) {
+   26995           0 :       iw = i -*n + *nb;
+   26996             :       
+   26997           0 :       if(i<*n) {
+   26998           0 :         ti1 = *n-i;
+   26999           0 :         ti2 = 1;
+   27000             :         /* BLAS */
+   27001           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&i,&ti1,&minusone, &(a[ i*(*lda) + 0]),lda,&(w[iw*(*ldw)+(i-1)]),
+   27002           0 :                ldw,&one, &(a[ (i-1)*(*lda) + 0]), &ti2);
+   27003             :         /* BLAS */
+   27004           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&i,&ti1,&minusone, &(w[ iw*(*ldw) + 0]),ldw,&(a[i*(*lda)+(i-1)]),
+   27005           0 :                lda,&one, &(a[ (i-1)*(*lda) + 0]), &ti2);
+   27006             :       }
+   27007             : 
+   27008           0 :       if(i>1) {
+   27009             :         /*  Generate elementary reflector H(i) to annihilate
+   27010             :          *              A(1:i-2,i) 
+   27011             :          */
+   27012           0 :         ti1 = i-1;
+   27013           0 :         ti2 = 1;
+   27014             : 
+   27015             :         /* LAPACK */
+   27016           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&ti1,&(a[(i-1)*(*lda)+(i-2)]),&(a[(i-1)*(*lda)+0]),&ti2,&(tau[i-2]));
+   27017             :       
+   27018           0 :         e[i-2] = a[(i-1)*(*lda)+(i-2)];
+   27019           0 :         a[(i-1)*(*lda)+(i-2)] = 1.0;
+   27020             : 
+   27021             :         /* Compute W(1:i-1,i) */
+   27022           0 :         ti1 = i-1;
+   27023           0 :         ti2 = 1;
+   27024             : 
+   27025             :         /* BLAS */
+   27026           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)("U",&ti1,&one,a,lda,&(a[(i-1)*(*lda)+0]),&ti2,&zero,
+   27027           0 :                &(w[(iw-1)*(*ldw)+0]),&ti2);
+   27028           0 :         if(i<*n) {
+   27029           0 :           ti1 = i-1;
+   27030           0 :           ti2 = *n-i;
+   27031           0 :           ti3 = 1;
+   27032             :           /* BLAS */
+   27033           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(w[iw*(*ldw)+0]),ldw,&(a[(i-1)*(*lda)+0]),&ti3,
+   27034           0 :                  &zero,&(w[(iw-1)*(*ldw)+i]),&ti3);
+   27035             :         
+   27036             :           /* BLAS */
+   27037           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(a[i*(*lda)+0]),lda,&(w[(iw-1)*(*ldw)+i]),&ti3,
+   27038           0 :                  &one,&(w[(iw-1)*(*ldw)+0]),&ti3);
+   27039             :         
+   27040             :           /* BLAS */
+   27041           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(a[i*(*lda)+0]),lda,&(a[(i-1)*(*lda)+0]),&ti3,
+   27042           0 :                  &zero,&(w[(iw-1)*(*ldw)+i]),&ti3);
+   27043             :         
+   27044             :           /* BLAS */
+   27045           0 :           PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(w[iw*(*ldw)+0]),ldw,&(w[(iw-1)*(*ldw)+i]),&ti3,
+   27046           0 :                  &one,&(w[(iw-1)*(*ldw)+0]),&ti3);
+   27047             :         }
+   27048             :       
+   27049           0 :         ti1 = i-1;
+   27050           0 :         ti2 = 1;
+   27051             :         /* BLAS */
+   27052           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&(tau[i-2]),&(w[(iw-1)*(*ldw)+0]),&ti2);
+   27053             :       
+   27054           0 :         alpha = -0.5*tau[i-2]*PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&ti1,&(w[(iw-1)*(*ldw)+0]),&ti2,
+   27055           0 :                                     &(a[(i-1)*(*lda)+0]),&ti2);
+   27056             :       
+   27057             :         /* BLAS */
+   27058           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+0]),&ti2,&(w[(iw-1)*(*ldw)+0]),&ti2);
+   27059             : 
+   27060             :       }
+   27061             :     }
+   27062             :   } else {
+   27063             :     /* lower */
+   27064           0 :     for(i=1;i<=*nb;i++) {
+   27065             : 
+   27066           0 :       ti1 = *n-i+1;
+   27067           0 :       ti2 = i-1;
+   27068           0 :       ti3 = 1;
+   27069             :       /* BLAS */
+   27070           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone, &(a[ i-1 ]),lda,&(w[ i-1 ]),
+   27071           0 :                ldw,&one, &(a[ (i-1)*(*lda) + (i-1)]), &ti3);
+   27072             :       /* BLAS */
+   27073           0 :       PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone, &(w[ i-1 ]),ldw,&(a[ i-1 ]),
+   27074           0 :                lda,&one, &(a[ (i-1)*(*lda) + (i-1)]), &ti3);
+   27075             : 
+   27076           0 :       if(i<*n) {
+   27077           0 :         ti1 = *n - i;
+   27078           0 :         ti2 = (*n < i+2 ) ? *n : (i+2);
+   27079           0 :         ti3 = 1;
+   27080             :         /* LAPACK */
+   27081           0 :         PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&ti1,&(a[(i-1)*(*lda)+(i)]),&(a[(i-1)*(*lda)+(ti2-1)]),&ti3,&(tau[i-1]));
+   27082           0 :         e[i-1] = a[(i-1)*(*lda)+(i)];
+   27083           0 :         a[(i-1)*(*lda)+(i)] = 1.0;
+   27084             :         
+   27085           0 :         ti1 = *n - i;
+   27086           0 :         ti2 = 1;
+   27087           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)("L",&ti1,&one,&(a[i*(*lda)+i]),lda,&(a[(i-1)*(*lda)+i]),&ti2,
+   27088           0 :                &zero,&(w[(i-1)*(*ldw)+i]),&ti2);
+   27089           0 :         ti1 = *n - i;
+   27090           0 :         ti2 = i-1;
+   27091           0 :         ti3 = 1;
+   27092             :         /* BLAS */
+   27093           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(w[ i ]),ldw,&(a[(i-1)*(*lda)+i]),&ti3,
+   27094           0 :                &zero,&(w[(i-1)*(*ldw)+0]),&ti3);
+   27095             :         
+   27096             :         /* BLAS */
+   27097           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(a[ i ]),lda,&(w[(i-1)*(*ldw)+0]),&ti3,
+   27098           0 :                &one,&(w[(i-1)*(*ldw)+i]),&ti3);
+   27099             :         
+   27100             :         /* BLAS */
+   27101           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("T",&ti1,&ti2,&one,&(a[ i ]),lda,&(a[(i-1)*(*lda)+i]),&ti3,
+   27102           0 :                &zero,&(w[(i-1)*(*ldw)+0]),&ti3);
+   27103             :         
+   27104             :         /* BLAS */
+   27105           0 :         PLUMED_BLAS_F77_FUNC(sgemv,SGEMV)("N",&ti1,&ti2,&minusone,&(w[ i ]),ldw,&(w[(i-1)*(*ldw)+0]),&ti3,
+   27106           0 :                &one,&(w[(i-1)*(*ldw)+i]),&ti3);
+   27107             : 
+   27108           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&ti1,&(tau[i-1]),&(w[(i-1)*(*ldw)+i]),&ti3);
+   27109           0 :         alpha = -0.5*tau[i-1]*PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&ti1,&(w[(i-1)*(*ldw)+i]),&ti3,
+   27110           0 :                                    &(a[(i-1)*(*lda)+i]),&ti3);
+   27111             :         
+   27112           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+i]),&ti3,&(w[(i-1)*(*ldw)+i]),&ti3);
+   27113             :       }
+   27114             :     }
+   27115             :   }
+   27116             :   return;
+   27117             : }
+   27118             :         
+   27119             : 
+   27120             : 
+   27121             :   
+   27122             : }
+   27123             : }
+   27124             : #include <cmath>
+   27125             : 
+   27126             : #include "blas/blas.h"
+   27127             : #include "lapack.h"
+   27128             : 
+   27129             : #include "blas/blas.h"
+   27130             : namespace PLMD{
+   27131             : namespace lapack{
+   27132             : using namespace blas;
+   27133             : void 
+   27134           0 : PLUMED_BLAS_F77_FUNC(sorg2r,SORG2R)(int *m, 
+   27135             :                         int *n,
+   27136             :                         int *k, 
+   27137             :                         float *a, 
+   27138             :                         int *lda,
+   27139             :                         float *tau,
+   27140             :                         float *work,
+   27141             :                         int *info)
+   27142             : {
+   27143             :     int a_dim1, a_offset, i__1, i__2;
+   27144             :     float r__1;
+   27145           0 :     int c__1 = 1;
+   27146             : 
+   27147             :     int i__, j, l;
+   27148             : 
+   27149           0 :     a_dim1 = *lda;
+   27150           0 :     a_offset = 1 + a_dim1;
+   27151           0 :     a -= a_offset;
+   27152           0 :     --tau;
+   27153             :     --work;
+   27154             : 
+   27155           0 :     *info = 0;
+   27156             : 
+   27157           0 :     if (*n <= 0) {
+   27158             :         return;
+   27159             :     }
+   27160             : 
+   27161           0 :     i__1 = *n;
+   27162           0 :     for (j = *k + 1; j <= i__1; ++j) {
+   27163           0 :         i__2 = *m;
+   27164           0 :         for (l = 1; l <= i__2; ++l) {
+   27165           0 :             a[l + j * a_dim1] = 0.0;
+   27166             :         }
+   27167           0 :         a[j + j * a_dim1] = 1.0;
+   27168             :     }
+   27169           0 :     for (i__ = *k; i__ >= 1; --i__) {
+   27170           0 :         if (i__ < *n) {
+   27171           0 :             a[i__ + i__ * a_dim1] = 1.0;
+   27172           0 :             i__1 = *m - i__ + 1;
+   27173           0 :             i__2 = *n - i__;
+   27174           0 :             PLUMED_BLAS_F77_FUNC(slarf,SLARF)("L", &i__1, &i__2, &a[i__ + i__ * a_dim1], &c__1, 
+   27175           0 :                               &tau[i__], &a[i__ + (i__ + 1) * a_dim1], lda, &work[1]);
+   27176             :         }
+   27177           0 :         if (i__ < *m) {
+   27178           0 :             i__1 = *m - i__;
+   27179           0 :             r__1 = -tau[i__];
+   27180           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &r__1, &a[i__ + 1 + i__ * a_dim1], &c__1);
+   27181             :         }
+   27182           0 :         a[i__ + i__ * a_dim1] = 1.0 - tau[i__];
+   27183           0 :         i__1 = i__ - 1;
+   27184           0 :         for (l = 1; l <= i__1; ++l) {
+   27185           0 :             a[l + i__ * a_dim1] = 0.0;
+   27186             :         }
+   27187             :     }
+   27188             :     return;
+   27189             : 
+   27190             : }
+   27191             : 
+   27192             : 
+   27193             : }
+   27194             : }
+   27195             : #include "lapack.h"
+   27196             : #include "lapack_limits.h"
+   27197             : 
+   27198             : #include "blas/blas.h"
+   27199             : namespace PLMD{
+   27200             : namespace lapack{
+   27201             : using namespace blas;
+   27202             : void
+   27203           0 : PLUMED_BLAS_F77_FUNC(sorgbr,SORGBR)(const char *vect,
+   27204             :         int *m,
+   27205             :         int *n,
+   27206             :         int *k,
+   27207             :         float *a,
+   27208             :         int *lda,
+   27209             :         float *tau,
+   27210             :         float *work,
+   27211             :         int *lwork,
+   27212             :         int *info)
+   27213             : {
+   27214             :   int wantq,iinfo,j,i,i1,wrksz;
+   27215           0 :   int mn = (*m < *n) ? *m : *n;
+   27216             : 
+   27217           0 :   wantq = (*vect=='Q' || *vect=='q');
+   27218             : 
+   27219           0 :   *info = 0;
+   27220           0 :   wrksz = mn*DORGBR_BLOCKSIZE;
+   27221           0 :   if(*lwork==-1) {
+   27222           0 :     work[0] = wrksz;
+   27223           0 :     return;
+   27224             :   }
+   27225             :   
+   27226           0 :   if(*m==0 || *n==0)
+   27227             :     return;
+   27228             : 
+   27229           0 :   if(wantq) {
+   27230           0 :     if(*m>=*k)
+   27231           0 :       PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(m,n,k,a,lda,tau,work,lwork,&iinfo);
+   27232             :     else {
+   27233           0 :       for(j=*m;j>=2;j--) {
+   27234           0 :         a[(j-1)*(*lda)+0] = 0.0;
+   27235           0 :         for(i=j+1;i<=*m;i++)
+   27236           0 :           a[(j-1)*(*lda)+(i-1)] = a[(j-2)*(*lda)+(i-1)]; 
+   27237             :       }
+   27238           0 :       a[0] = 1.0;
+   27239           0 :       for(i=2;i<=*m;i++)
+   27240           0 :         a[i-1] = 0.0;
+   27241           0 :       if(*m>1) {
+   27242           0 :         i1 = *m-1;
+   27243           0 :         PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(&i1,&i1,&i1,&(a[*lda+1]),lda,tau,work,lwork,&iinfo);
+   27244             :       }
+   27245             :     }
+   27246             :   } else {
+   27247           0 :     if(*k<*n)
+   27248           0 :       PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(m,n,k,a,lda,tau,work,lwork,&iinfo);
+   27249             :     else {
+   27250           0 :       a[0] = 1.0;
+   27251           0 :       for(i=2;i<=*m;i++)
+   27252           0 :         a[i-1] = 0.0;
+   27253           0 :       for(j=2;j<=*n;j++) {
+   27254           0 :         for(i=j-1;i>=2;i--)
+   27255           0 :           a[(j-1)*(*lda)+(i-1)] = a[(j-1)*(*lda)+(i-2)]; 
+   27256           0 :         a[(j-1)*(*lda)+0] = 0.0;
+   27257             :       }
+   27258           0 :       if(*n>1) {
+   27259           0 :         i1 = *n-1;
+   27260           0 :         PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(&i1,&i1,&i1,&(a[*lda+1]),lda,tau,work,lwork,&iinfo);
+   27261             :       }
+   27262             :     }
+   27263             :   }
+   27264           0 :   work[0] = wrksz;
+   27265           0 :   return;
+   27266             : }
+   27267             :  
+   27268             : }
+   27269             : }
+   27270             : #include "blas/blas.h"
+   27271             : #include "lapack.h"
+   27272             : 
+   27273             : #include "blas/blas.h"
+   27274             : namespace PLMD{
+   27275             : namespace lapack{
+   27276             : using namespace blas;
+   27277             : void
+   27278           0 : PLUMED_BLAS_F77_FUNC(sorgl2,SORGL2)(int *m,
+   27279             :                         int *n, 
+   27280             :                         int *k, 
+   27281             :                         float *a, 
+   27282             :                         int *lda, 
+   27283             :                         float *tau, 
+   27284             :                         float *work, 
+   27285             :                         int *info)
+   27286             : {
+   27287             :     int a_dim1, a_offset, i__1, i__2;
+   27288             :     float r__1;
+   27289             : 
+   27290             :     int i__, j, l;
+   27291             : 
+   27292           0 :     a_dim1 = *lda;
+   27293           0 :     a_offset = 1 + a_dim1;
+   27294           0 :     a -= a_offset;
+   27295           0 :     --tau;
+   27296             :     --work;
+   27297             : 
+   27298           0 :     i__ = (*m > 1) ? *m : 1;
+   27299             :     
+   27300           0 :     *info = 0;
+   27301           0 :     if (*m < 0) {
+   27302           0 :         *info = -1;
+   27303           0 :     } else if (*n < *m) {
+   27304           0 :         *info = -2;
+   27305           0 :     } else if (*k < 0 || *k > *m) {
+   27306           0 :         *info = -3;
+   27307           0 :     } else if (*lda < i__) {
+   27308           0 :         *info = -5;
+   27309             :     }
+   27310           0 :     if (*info != 0) {
+   27311             :         return;
+   27312             :     }
+   27313           0 :     if (*m <= 0) {
+   27314             :         return;
+   27315             :     }
+   27316             : 
+   27317           0 :     if (*k < *m) {
+   27318           0 :         i__1 = *n;
+   27319           0 :         for (j = 1; j <= i__1; ++j) {
+   27320           0 :             i__2 = *m;
+   27321           0 :             for (l = *k + 1; l <= i__2; ++l) {
+   27322           0 :                 a[l + j * a_dim1] = 0.0;
+   27323             :             }
+   27324           0 :             if (j > *k && j <= *m) {
+   27325           0 :                 a[j + j * a_dim1] = 1.0;
+   27326             :             }
+   27327             :         }
+   27328             :     }
+   27329             : 
+   27330           0 :     for (i__ = *k; i__ >= 1; --i__) {
+   27331           0 :         if (i__ < *n) {
+   27332           0 :             if (i__ < *m) {
+   27333           0 :                 a[i__ + i__ * a_dim1] = 1.0;
+   27334           0 :                 i__1 = *m - i__;
+   27335           0 :                 i__2 = *n - i__ + 1;
+   27336           0 :                 PLUMED_BLAS_F77_FUNC(slarf,SLARF)("R", &i__1, &i__2, &a[i__ + i__ * a_dim1], lda, 
+   27337           0 :                &tau[i__], &a[i__ + 1 + i__ * a_dim1], lda, &work[1]);
+   27338             :             }
+   27339           0 :             i__1 = *n - i__;
+   27340           0 :             r__1 = -tau[i__];
+   27341           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &r__1, &a[i__ + (i__ + 1) * a_dim1], lda);
+   27342             :         }
+   27343           0 :         a[i__ + i__ * a_dim1] = 1.0 - tau[i__];
+   27344           0 :         i__1 = i__ - 1;
+   27345           0 :         for (l = 1; l <= i__1; ++l) {
+   27346           0 :             a[i__ + l * a_dim1] = 0.0;
+   27347             :         }
+   27348             :     }
+   27349             :     return;
+   27350             : 
+   27351             : }
+   27352             : 
+   27353             : 
+   27354             : 
+   27355             : }
+   27356             : }
+   27357             : #include "lapack.h"
+   27358             : 
+   27359             : #define SORGLQ_BLOCKSIZE    32
+   27360             : #define SORGLQ_MINBLOCKSIZE 2
+   27361             : #define SORGLQ_CROSSOVER    128
+   27362             : 
+   27363             : 
+   27364             : #include "blas/blas.h"
+   27365             : namespace PLMD{
+   27366             : namespace lapack{
+   27367             : using namespace blas;
+   27368             : void 
+   27369           0 : PLUMED_BLAS_F77_FUNC(sorglq,SORGLQ)(int *m, 
+   27370             :         int *n, 
+   27371             :         int *k, 
+   27372             :         float *a, 
+   27373             :         int *lda, 
+   27374             :         float *tau, 
+   27375             :         float *work, 
+   27376             :         int *lwork, 
+   27377             :         int *info)
+   27378             : {
+   27379             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   27380             : 
+   27381             :     int i__, j, l, ib, nb, ki, kk, nx, iws, nbmin, iinfo;
+   27382             : 
+   27383             :     int ldwork, lwkopt;
+   27384             :     int lquery;
+   27385             :     
+   27386           0 :     a_dim1 = *lda;
+   27387           0 :     a_offset = 1 + a_dim1;
+   27388           0 :     a -= a_offset;
+   27389           0 :     --tau;
+   27390             :     --work;
+   27391             : 
+   27392           0 :     *info = 0;
+   27393             :     ki = 0;
+   27394             :     nb = SORGLQ_BLOCKSIZE;
+   27395           0 :     lwkopt = (*m) * nb;
+   27396           0 :     work[1] = (float) lwkopt;
+   27397           0 :     lquery = *lwork == -1;
+   27398           0 :     if (*m < 0) {
+   27399           0 :         *info = -1;
+   27400           0 :     } else if (*n < *m) {
+   27401           0 :         *info = -2;
+   27402           0 :     } else if (*k < 0 || *k > *m) {
+   27403           0 :         *info = -3;
+   27404           0 :     } else if (*lda < (*m)) {
+   27405           0 :         *info = -5;
+   27406           0 :     } else if (*lwork < (*m) && ! lquery) {
+   27407           0 :         *info = -8;
+   27408             :     }
+   27409           0 :     if (*info != 0) {
+   27410             :         i__1 = -(*info);
+   27411             :         return;
+   27412           0 :     } else if (lquery) {
+   27413             :         return;
+   27414             :     }
+   27415             : 
+   27416           0 :     if (*m <= 0) {
+   27417           0 :         work[1] = 1.;
+   27418           0 :         return;
+   27419             :     }
+   27420             : 
+   27421             :     nbmin = 2;
+   27422             :     nx = 0;
+   27423             :     iws = *m;
+   27424           0 :     if (nb > 1 && nb < *k) {
+   27425             : 
+   27426             :         nx = SORGLQ_CROSSOVER;
+   27427           0 :         if (nx < *k) {
+   27428             : 
+   27429           0 :             ldwork = *m;
+   27430           0 :             iws = ldwork * nb;
+   27431           0 :             if (*lwork < iws) {
+   27432             : 
+   27433           0 :                 nb = *lwork / ldwork;
+   27434             :                 nbmin = SORGLQ_MINBLOCKSIZE;
+   27435             :             }
+   27436             :         }
+   27437             :     }
+   27438             : 
+   27439           0 :     if (nb >= nbmin && nb < *k && nx < *k) {
+   27440             : 
+   27441           0 :         ki = (*k - nx - 1) / nb * nb;
+   27442           0 :         i__1 = *k, i__2 = ki + nb;
+   27443             :         kk = (i__1<i__2) ? i__1 : i__2;
+   27444             : 
+   27445           0 :         i__1 = kk;
+   27446           0 :         for (j = 1; j <= i__1; ++j) {
+   27447           0 :             i__2 = *m;
+   27448           0 :             for (i__ = kk + 1; i__ <= i__2; ++i__) {
+   27449           0 :                 a[i__ + j * a_dim1] = 0.;
+   27450             :             }
+   27451             :         }
+   27452             :     } else {
+   27453             :         kk = 0;
+   27454             :     }
+   27455           0 :     if (kk < *m) {
+   27456           0 :         i__1 = *m - kk;
+   27457           0 :         i__2 = *n - kk;
+   27458           0 :         i__3 = *k - kk;
+   27459           0 :         PLUMED_BLAS_F77_FUNC(sorgl2,SORGL2)(&i__1, &i__2, &i__3, &a[kk + 1 + (kk + 1) * a_dim1], lda, &
+   27460           0 :                 tau[kk + 1], &work[1], &iinfo);
+   27461             :     }
+   27462             : 
+   27463           0 :     if (kk > 0) {
+   27464             : 
+   27465           0 :         i__1 = -nb;
+   27466           0 :         for (i__ = ki + 1; i__1 < 0 ? i__ >= 1 : i__ <= 1; i__ += i__1) {
+   27467           0 :             i__2 = nb, i__3 = *k - i__ + 1;
+   27468           0 :             ib = (i__2<i__3) ? i__2 : i__3;
+   27469           0 :             if (i__ + ib <= *m) {
+   27470             : 
+   27471           0 :                 i__2 = *n - i__ + 1;
+   27472           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Rowwise", &i__2, &ib, &a[i__ + i__ * 
+   27473           0 :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   27474             : 
+   27475           0 :                 i__2 = *m - i__ - ib + 1;
+   27476           0 :                 i__3 = *n - i__ + 1;
+   27477           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Right", "Transpose", "Forward", "Rowwise", &i__2, &
+   27478             :                         i__3, &ib, &a[i__ + i__ * a_dim1], lda, &work[1], &
+   27479           0 :                         ldwork, &a[i__ + ib + i__ * a_dim1], lda, &work[ib + 
+   27480           0 :                         1], &ldwork);
+   27481             :             }
+   27482             : 
+   27483           0 :             i__2 = *n - i__ + 1;
+   27484           0 :             PLUMED_BLAS_F77_FUNC(sorgl2,SORGL2)(&ib, &i__2, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &
+   27485             :                     work[1], &iinfo);
+   27486             : 
+   27487           0 :             i__2 = i__ - 1;
+   27488           0 :             for (j = 1; j <= i__2; ++j) {
+   27489           0 :                 i__3 = i__ + ib - 1;
+   27490           0 :                 for (l = i__; l <= i__3; ++l) {
+   27491           0 :                     a[l + j * a_dim1] = 0.;
+   27492             :                 }
+   27493             :             }
+   27494             :         }
+   27495             :     }
+   27496             : 
+   27497           0 :     work[1] = (float) iws;
+   27498           0 :     return;
+   27499             : 
+   27500             : }
+   27501             : 
+   27502             : 
+   27503             : }
+   27504             : }
+   27505             : #include "lapack.h"
+   27506             : #include "lapack_limits.h"
+   27507             : 
+   27508             : 
+   27509             : #include "blas/blas.h"
+   27510             : namespace PLMD{
+   27511             : namespace lapack{
+   27512             : using namespace blas;
+   27513             : void 
+   27514           0 : PLUMED_BLAS_F77_FUNC(sorgqr,SORGQR)(int *m, 
+   27515             :         int *n, 
+   27516             :         int *k, 
+   27517             :         float *a, 
+   27518             :         int *lda, 
+   27519             :         float *tau, 
+   27520             :         float *work, 
+   27521             :         int *lwork, 
+   27522             :         int *info)
+   27523             : {
+   27524             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   27525             : 
+   27526             :     int i__, j, l, ib, nb, ki, kk, nx, iws, nbmin, iinfo;
+   27527             :     int ldwork, lwkopt;
+   27528             :     int lquery;
+   27529             :  
+   27530           0 :     a_dim1 = *lda;
+   27531           0 :     a_offset = 1 + a_dim1;
+   27532           0 :     a -= a_offset;
+   27533           0 :     --tau;
+   27534             :     --work;
+   27535             : 
+   27536             :     ki = 0;
+   27537           0 :     *info = 0;
+   27538             :     nb = DORGQR_BLOCKSIZE;
+   27539           0 :     lwkopt = (*n) * nb;
+   27540           0 :     work[1] = (float) lwkopt;
+   27541           0 :     lquery = *lwork == -1;
+   27542           0 :     if (*m < 0) {
+   27543           0 :         *info = -1;
+   27544           0 :     } else if (*n < 0 || *n > *m) {
+   27545           0 :         *info = -2;
+   27546           0 :     } else if (*k < 0 || *k > *n) {
+   27547           0 :         *info = -3;
+   27548           0 :     } else if (*lda < (*m)) {
+   27549           0 :         *info = -5;
+   27550           0 :     } else if (*lwork < (*n) && ! lquery) {
+   27551           0 :         *info = -8;
+   27552             :     }
+   27553           0 :     if (*info != 0) {
+   27554             :         i__1 = -(*info);
+   27555             :         return;
+   27556           0 :     } else if (lquery) {
+   27557             :         return;
+   27558             :     }
+   27559             : 
+   27560           0 :     if (*n <= 0) {
+   27561           0 :         work[1] = 1.;
+   27562           0 :         return;
+   27563             :     }
+   27564             : 
+   27565             :     nbmin = 2;
+   27566             :     nx = 0;
+   27567             :     iws = *n;
+   27568           0 :     if (nb > 1 && nb < *k) {
+   27569             : 
+   27570             :         nx = DORGQR_CROSSOVER;
+   27571           0 :         if (nx < *k) {
+   27572             : 
+   27573           0 :             ldwork = *n;
+   27574           0 :             iws = ldwork * nb;
+   27575           0 :             if (*lwork < iws) {
+   27576             : 
+   27577           0 :                 nb = *lwork / ldwork;
+   27578             :                 nbmin = DORGQR_MINBLOCKSIZE;
+   27579             :             }
+   27580             :         }
+   27581             :     }
+   27582             : 
+   27583           0 :     if (nb >= nbmin && nb < *k && nx < *k) {
+   27584             : 
+   27585           0 :         ki = (*k - nx - 1) / nb * nb;
+   27586           0 :         i__1 = *k, i__2 = ki + nb;
+   27587             :         kk = (i__1<i__2) ? i__1 : i__2;
+   27588             : 
+   27589           0 :         i__1 = *n;
+   27590           0 :         for (j = kk + 1; j <= i__1; ++j) {
+   27591           0 :             i__2 = kk;
+   27592           0 :             for (i__ = 1; i__ <= i__2; ++i__) {
+   27593           0 :                 a[i__ + j * a_dim1] = 0.;
+   27594             :             }
+   27595             :         }
+   27596             :     } else {
+   27597             :         kk = 0;
+   27598             :     }
+   27599             : 
+   27600           0 :     if (kk < *n) {
+   27601           0 :         i__1 = *m - kk;
+   27602           0 :         i__2 = *n - kk;
+   27603           0 :         i__3 = *k - kk;
+   27604           0 :         PLUMED_BLAS_F77_FUNC(sorg2r,SORG2R)(&i__1, &i__2, &i__3, &a[kk + 1 + (kk + 1) * a_dim1], lda, &
+   27605           0 :                 tau[kk + 1], &work[1], &iinfo);
+   27606             :     }
+   27607             : 
+   27608           0 :     if (kk > 0) {
+   27609             : 
+   27610           0 :         i__1 = -nb;
+   27611           0 :         for (i__ = ki + 1; i__1 < 0 ? i__ >= 1 : i__ <= 1; i__ += i__1) {
+   27612           0 :             i__2 = nb, i__3 = *k - i__ + 1;
+   27613           0 :             ib = (i__2<i__3) ? i__2 : i__3;
+   27614           0 :             if (i__ + ib <= *n) {
+   27615             : 
+   27616           0 :                 i__2 = *m - i__ + 1;
+   27617           0 :                 PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Columnwise", &i__2, &ib, &a[i__ + i__ * 
+   27618           0 :                         a_dim1], lda, &tau[i__], &work[1], &ldwork);
+   27619             : 
+   27620           0 :                 i__2 = *m - i__ + 1;
+   27621           0 :                 i__3 = *n - i__ - ib + 1;
+   27622           0 :                 PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)("Left", "No transpose", "Forward", "Columnwise", &
+   27623             :                         i__2, &i__3, &ib, &a[i__ + i__ * a_dim1], lda, &work[
+   27624           0 :                         1], &ldwork, &a[i__ + (i__ + ib) * a_dim1], lda, &
+   27625           0 :                         work[ib + 1], &ldwork);
+   27626             :             }
+   27627             : 
+   27628           0 :             i__2 = *m - i__ + 1;
+   27629           0 :             PLUMED_BLAS_F77_FUNC(sorg2r,SORG2R)(&i__2, &ib, &ib, &a[i__ + i__ * a_dim1], lda, &tau[i__], &
+   27630             :                     work[1], &iinfo);
+   27631             : 
+   27632           0 :             i__2 = i__ + ib - 1;
+   27633           0 :             for (j = i__; j <= i__2; ++j) {
+   27634           0 :                 i__3 = i__ - 1;
+   27635           0 :                 for (l = 1; l <= i__3; ++l) {
+   27636           0 :                     a[l + j * a_dim1] = 0.;
+   27637             :                 }
+   27638             :             }
+   27639             :         }
+   27640             :     }
+   27641             : 
+   27642           0 :     work[1] = (float) iws;
+   27643           0 :     return;
+   27644             : 
+   27645             : } 
+   27646             : }
+   27647             : }
+   27648             : #include "lapack.h"
+   27649             : 
+   27650             : #include "blas/blas.h"
+   27651             : namespace PLMD{
+   27652             : namespace lapack{
+   27653             : using namespace blas;
+   27654             : void
+   27655           0 : PLUMED_BLAS_F77_FUNC(sorm2l,SORM2L)(const char *side, 
+   27656             :         const char *trans, 
+   27657             :         int *m, 
+   27658             :         int *n, 
+   27659             :         int *k, 
+   27660             :         float *a,
+   27661             :         int *lda, 
+   27662             :         float *tau,
+   27663             :         float *c__,
+   27664             :         int *ldc, 
+   27665             :         float *work, 
+   27666             :         int *info)
+   27667             : {
+   27668             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2;
+   27669           0 :     int c__1 = 1;
+   27670             : 
+   27671             :     int i__, i1, i2, i3, mi, ni, nq;
+   27672             :     float aii;
+   27673             :     int left;
+   27674             :     int notran;
+   27675             : 
+   27676           0 :     a_dim1 = *lda;
+   27677           0 :     a_offset = 1 + a_dim1;
+   27678           0 :     a -= a_offset;
+   27679             :     --tau;
+   27680             :     c_dim1 = *ldc;
+   27681             :     c_offset = 1 + c_dim1;
+   27682             :     c__ -= c_offset;
+   27683             :     --work;
+   27684             : 
+   27685             :     /* Function Body */
+   27686           0 :     *info = 0;
+   27687           0 :     left = (*side=='L' || *side=='l');
+   27688           0 :     notran = (*trans=='N' || *trans=='n');
+   27689             : 
+   27690           0 :     if (left) {
+   27691           0 :         nq = *m;
+   27692             :     } else {
+   27693           0 :         nq = *n;
+   27694             :     }
+   27695             :     if (*info != 0) {
+   27696             :         return;
+   27697             :     }
+   27698             : 
+   27699           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   27700             :         return;
+   27701             :     }
+   27702             : 
+   27703           0 :     if ((left && notran) || (! left && ! notran)) {
+   27704             :         i1 = 1;
+   27705             :         i2 = *k;
+   27706             :         i3 = 1;
+   27707             :     } else {
+   27708             :         i1 = *k;
+   27709             :         i2 = 1;
+   27710             :         i3 = -1;
+   27711             :     }
+   27712             : 
+   27713           0 :     if (left) {
+   27714           0 :         ni = *n;
+   27715             :     } else {
+   27716           0 :         mi = *m;
+   27717             :     }
+   27718             : 
+   27719             :     i__1 = i2;
+   27720             :     i__2 = i3;
+   27721           0 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   27722           0 :         if (left) {
+   27723             : 
+   27724           0 :             mi = *m - *k + i__;
+   27725             :         } else {
+   27726             : 
+   27727           0 :             ni = *n - *k + i__;
+   27728             :         }
+   27729             : 
+   27730           0 :         aii = a[nq - *k + i__ + i__ * a_dim1];
+   27731           0 :         a[nq - *k + i__ + i__ * a_dim1] = 1.;
+   27732           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)(side, &mi, &ni, &a[i__ * a_dim1 + 1], &c__1, &tau[i__], &c__[
+   27733             :                 c_offset], ldc, &work[1]);
+   27734           0 :         a[nq - *k + i__ + i__ * a_dim1] = aii;
+   27735             :     }
+   27736             :     return;
+   27737             : }
+   27738             : }
+   27739             : }
+   27740             : #include "lapack.h"
+   27741             : 
+   27742             : #include "blas/blas.h"
+   27743             : namespace PLMD{
+   27744             : namespace lapack{
+   27745             : using namespace blas;
+   27746             : void 
+   27747           0 : PLUMED_BLAS_F77_FUNC(sorm2r,SORM2R)(const char *side, 
+   27748             :         const char *trans, 
+   27749             :         int *m, 
+   27750             :         int *n, 
+   27751             :         int *k, 
+   27752             :         float *a, 
+   27753             :         int *lda, 
+   27754             :         float *tau, 
+   27755             :         float *c__, 
+   27756             :         int *ldc, 
+   27757             :         float *work, 
+   27758             :         int *info)
+   27759             : {
+   27760             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2;
+   27761             : 
+   27762             :     int i__, i1, i2, i3, ic, jc, mi, ni;
+   27763             :     float aii;
+   27764             :     int left;
+   27765             :     int notran;
+   27766           0 :     int c__1 = 1;
+   27767             : 
+   27768           0 :     a_dim1 = *lda;
+   27769           0 :     a_offset = 1 + a_dim1;
+   27770           0 :     a -= a_offset;
+   27771             :     --tau;
+   27772           0 :     c_dim1 = *ldc;
+   27773           0 :     c_offset = 1 + c_dim1;
+   27774           0 :     c__ -= c_offset;
+   27775             :     --work;
+   27776           0 :     *info = 0;
+   27777           0 :     left = (*side=='L' || *side=='l');
+   27778           0 :     notran = (*trans=='N' || *trans=='n');
+   27779             : 
+   27780             :     ic = jc = 0;
+   27781             : 
+   27782           0 :     if (*m <= 0 || *n <= 0 || *k <= 0) {
+   27783             :         return;
+   27784             :     }
+   27785             : 
+   27786           0 :     if ((left && !notran) || (!left && notran)) {
+   27787             :         i1 = 1;
+   27788             :         i2 = *k;
+   27789             :         i3 = 1;
+   27790             :     } else {
+   27791             :         i1 = *k;
+   27792             :         i2 = 1;
+   27793             :         i3 = -1;
+   27794             :     }
+   27795             : 
+   27796           0 :     if (left) {
+   27797           0 :         ni = *n;
+   27798             :         jc = 1;
+   27799             :     } else {
+   27800           0 :         mi = *m;
+   27801             :         ic = 1;
+   27802             :     }
+   27803             : 
+   27804             :     i__1 = i2;
+   27805             :     i__2 = i3;
+   27806           0 :     for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   27807           0 :         if (left) {
+   27808             : 
+   27809           0 :             mi = *m - i__ + 1;
+   27810             :             ic = i__;
+   27811             :         } else {
+   27812             : 
+   27813           0 :             ni = *n - i__ + 1;
+   27814             :             jc = i__;
+   27815             :         }
+   27816             : 
+   27817             : 
+   27818           0 :         aii = a[i__ + i__ * a_dim1];
+   27819           0 :         a[i__ + i__ * a_dim1] = 1.;
+   27820           0 :         PLUMED_BLAS_F77_FUNC(slarf,SLARF)(side, &mi, &ni, &a[i__ + i__ * a_dim1], &c__1, &tau[i__], &c__[
+   27821           0 :                 ic + jc * c_dim1], ldc, &work[1]);
+   27822           0 :         a[i__ + i__ * a_dim1] = aii;
+   27823             :     }
+   27824             :     return;
+   27825             : 
+   27826             : } 
+   27827             : }
+   27828             : }
+   27829             : #include "lapack.h"
+   27830             : #include "lapack_limits.h"
+   27831             : 
+   27832             : #include "blas/blas.h"
+   27833             : namespace PLMD{
+   27834             : namespace lapack{
+   27835             : using namespace blas;
+   27836             : void 
+   27837           0 : PLUMED_BLAS_F77_FUNC(sormbr,SORMBR)(const char *vect, 
+   27838             :         const char *side, 
+   27839             :         const char *trans, 
+   27840             :         int *m, 
+   27841             :         int *n, 
+   27842             :         int *k, 
+   27843             :         float *a, 
+   27844             :         int *lda, 
+   27845             :         float *tau, 
+   27846             :         float *c__, 
+   27847             :         int *ldc, 
+   27848             :         float *work, 
+   27849             :         int *lwork, 
+   27850             :         int *info)
+   27851             : {
+   27852             :     int a_dim1, a_offset, c_dim1, c_offset, i__1;
+   27853             :  
+   27854             : 
+   27855             :     int i1, i2, nb, mi, ni, nq, nw;
+   27856             :     int left;
+   27857             :     int iinfo;
+   27858             :     int notran;
+   27859             :     int applyq;
+   27860             :     char transt[1];
+   27861             :     int lwkopt;
+   27862             :     int lquery;
+   27863             : 
+   27864           0 :     a_dim1 = *lda;
+   27865           0 :     a_offset = 1 + a_dim1;
+   27866           0 :     a -= a_offset;
+   27867             :     --tau;
+   27868           0 :     c_dim1 = *ldc;
+   27869           0 :     c_offset = 1 + c_dim1;
+   27870           0 :     c__ -= c_offset;
+   27871             :     --work;
+   27872           0 :     *info = 0;
+   27873           0 :     applyq = (*vect=='Q' || *vect=='q');
+   27874           0 :     left = (*side=='L' || *side=='l');
+   27875           0 :     notran = (*trans=='N' || *trans=='n');
+   27876           0 :     lquery = *lwork == -1;
+   27877             : 
+   27878           0 :     if (left) {
+   27879           0 :         nq = *m;
+   27880           0 :         nw = *n;
+   27881             :     } else {
+   27882           0 :         nq = *n;
+   27883           0 :         nw = *m;
+   27884             :     }
+   27885             : 
+   27886             :     nb = DORMQR_BLOCKSIZE;
+   27887           0 :     lwkopt = nw * nb;
+   27888           0 :     work[1] = (float) lwkopt;
+   27889             :     
+   27890           0 :     if (*info != 0) {
+   27891             :         i__1 = -(*info);
+   27892             :         return;
+   27893           0 :     } else if (lquery) {
+   27894             :         return;
+   27895             :     }
+   27896             : 
+   27897           0 :     work[1] = 1.;
+   27898           0 :     if (*m == 0 || *n == 0) {
+   27899             :         return;
+   27900             :     }
+   27901             : 
+   27902           0 :     if (applyq) {
+   27903             : 
+   27904           0 :         if (nq >= *k) {
+   27905             : 
+   27906           0 :             PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   27907             :                     c_offset], ldc, &work[1], lwork, &iinfo);
+   27908           0 :         } else if (nq > 1) {
+   27909             : 
+   27910           0 :             if (left) {
+   27911           0 :                 mi = *m - 1;
+   27912           0 :                 ni = *n;
+   27913             :                 i1 = 2;
+   27914             :                 i2 = 1;
+   27915             :             } else {
+   27916           0 :                 mi = *m;
+   27917           0 :                 ni = *n - 1;
+   27918             :                 i1 = 1;
+   27919             :                 i2 = 2;
+   27920             :             }
+   27921           0 :             i__1 = nq - 1;
+   27922           0 :             PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(side, trans, &mi, &ni, &i__1, &a[a_dim1 + 2], lda, &tau[1]
+   27923           0 :                     , &c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &iinfo);
+   27924             :         }
+   27925             :     } else {
+   27926             : 
+   27927           0 :         if (notran) {
+   27928           0 :             *(unsigned char *)transt = 'T';
+   27929             :         } else {
+   27930           0 :             *(unsigned char *)transt = 'N';
+   27931             :         }
+   27932           0 :         if (nq > *k) {
+   27933             : 
+   27934           0 :             PLUMED_BLAS_F77_FUNC(sormlq,SORMLQ)(side, transt, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   27935             :                     c_offset], ldc, &work[1], lwork, &iinfo);
+   27936           0 :         } else if (nq > 1) {
+   27937             : 
+   27938           0 :             if (left) {
+   27939           0 :                 mi = *m - 1;
+   27940           0 :                 ni = *n;
+   27941             :                 i1 = 2;
+   27942             :                 i2 = 1;
+   27943             :             } else {
+   27944           0 :                 mi = *m;
+   27945           0 :                 ni = *n - 1;
+   27946             :                 i1 = 1;
+   27947             :                 i2 = 2;
+   27948             :             }
+   27949           0 :             i__1 = nq - 1;
+   27950           0 :             PLUMED_BLAS_F77_FUNC(sormlq,SORMLQ)(side, transt, &mi, &ni, &i__1, &a[(a_dim1 << 1) + 1], lda,
+   27951           0 :                      &tau[1], &c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &
+   27952             :                     iinfo);
+   27953             :         }
+   27954             :     }
+   27955           0 :     work[1] = (float) lwkopt;
+   27956           0 :     return;
+   27957             : 
+   27958             : 
+   27959             : }
+   27960             : 
+   27961             : 
+   27962             : }
+   27963             : }
+   27964             : #include <cctype>
+   27965             : #include "real.h"
+   27966             : #include "lapack.h"
+   27967             : 
+   27968             : #include "blas/blas.h"
+   27969             : namespace PLMD{
+   27970             : namespace lapack{
+   27971             : using namespace blas;
+   27972             : void
+   27973           0 : PLUMED_BLAS_F77_FUNC(sorml2,SORML2)(const char *side,
+   27974             :                         const char *trans,
+   27975             :                         int *m,
+   27976             :                         int *n,
+   27977             :                         int *k,
+   27978             :                         float *a,
+   27979             :                         int *lda,
+   27980             :                         float *tau,
+   27981             :                         float *c,
+   27982             :                         int *ldc,
+   27983             :                         float *work,
+   27984             :                         int *info)
+   27985             : {
+   27986           0 :   const char xside=std::toupper(*side);
+   27987           0 :   const char xtrans=std::toupper(*trans);
+   27988             :   int i,i1,i2,i3,ni,mi,ic,jc;
+   27989             :   float aii;
+   27990             : 
+   27991           0 :   if(*m<=0 || *n<=0 || *k<=0)
+   27992             :     return;
+   27993             : 
+   27994             :   ic = jc = 0;
+   27995             : 
+   27996           0 :   if((xside=='L' && xtrans=='N') || (xside!='L' && xtrans!='N')) {
+   27997             :     i1 = 0;
+   27998             :     i2 = *k;
+   27999             :     i3 = 1;
+   28000             :   } else {
+   28001           0 :     i1 = *k-1;
+   28002             :     i2 = -1;
+   28003             :     i3 = -1;
+   28004             :   }
+   28005             :   
+   28006           0 :   if(xside=='L') {
+   28007           0 :     ni = *n;
+   28008             :     jc = 0;
+   28009             :   } else {
+   28010           0 :     mi = *m;
+   28011             :     ic = 0;
+   28012             :   }
+   28013             : 
+   28014           0 :   for(i=i1;i!=i2;i+=i3) {
+   28015           0 :     if(xside=='L') {
+   28016           0 :       mi = *m - i;
+   28017             :       ic = i;
+   28018             :     } else {
+   28019           0 :       ni = *n - i;
+   28020             :       jc = i;
+   28021             :     }
+   28022           0 :     aii = a[i*(*lda)+i];
+   28023           0 :     a[i*(*lda)+i] = 1.0;
+   28024           0 :     PLUMED_BLAS_F77_FUNC(slarf,SLARF)(side,&mi,&ni,&(a[i*(*lda)+i]),lda,tau+i,
+   28025           0 :            &(c[jc*(*ldc)+ic]),ldc,work);
+   28026           0 :     a[i*(*lda)+i] = aii;
+   28027             :   }
+   28028             :   return;
+   28029             : }
+   28030             :              
+   28031             : }
+   28032             : }
+   28033             : #include "lapack.h"
+   28034             : #include "lapack_limits.h"
+   28035             : 
+   28036             : 
+   28037             : #include "blas/blas.h"
+   28038             : namespace PLMD{
+   28039             : namespace lapack{
+   28040             : using namespace blas;
+   28041             : void 
+   28042           0 : PLUMED_BLAS_F77_FUNC(sormlq,SORMLQ)(const char *side, 
+   28043             :         const char *trans,
+   28044             :         int *m, 
+   28045             :         int *n, 
+   28046             :         int *k,
+   28047             :         float *a,
+   28048             :         int *lda, 
+   28049             :         float *tau, 
+   28050             :         float *c__, 
+   28051             :         int *ldc, 
+   28052             :         float *work, 
+   28053             :         int *lwork, 
+   28054             :         int *info)
+   28055             : {
+   28056             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, 
+   28057             :             i__5;
+   28058             :   
+   28059             : 
+   28060             :     int i__;
+   28061             :     float t[4160]       /* was [65][64] */;
+   28062             :     int i1, i2, i3, ib, ic, jc, nb, mi, ni, nq, nw, iws;
+   28063             :     int left;
+   28064             :     int nbmin, iinfo;
+   28065             :     int notran;
+   28066             :     int ldwork;
+   28067             :     char transt[1];
+   28068             :     int lwkopt;
+   28069             :     int lquery;
+   28070           0 :     int ldt = 65;
+   28071             : 
+   28072           0 :     a_dim1 = *lda;
+   28073           0 :     a_offset = 1 + a_dim1;
+   28074           0 :     a -= a_offset;
+   28075             :     --tau;
+   28076           0 :     c_dim1 = *ldc;
+   28077           0 :     c_offset = 1 + c_dim1;
+   28078           0 :     c__ -= c_offset;
+   28079             :     --work;
+   28080             : 
+   28081             :     ic = jc = 0;
+   28082             : 
+   28083           0 :     *info = 0;
+   28084           0 :     left = (*side=='L' || *side=='l');
+   28085           0 :     notran = (*trans=='N' || *trans=='n');
+   28086           0 :     lquery = *lwork == -1;
+   28087             : 
+   28088           0 :     if (left) {
+   28089           0 :         nq = *m;
+   28090           0 :         nw = *n;
+   28091             :     } else {
+   28092           0 :         nq = *n;
+   28093           0 :         nw = *m;
+   28094             :     }
+   28095             : 
+   28096             :     nb = DORMLQ_BLOCKSIZE;
+   28097           0 :     lwkopt = nw * nb;
+   28098           0 :     work[1] = (float) lwkopt;
+   28099             :     
+   28100           0 :     if (*info != 0) {
+   28101             :         return;
+   28102           0 :     } else if (lquery) {
+   28103             :         return;
+   28104             :     }
+   28105             : 
+   28106           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   28107           0 :         work[1] = 1.;
+   28108           0 :         return;
+   28109             :     }
+   28110             : 
+   28111             :     nbmin = 2;
+   28112           0 :     ldwork = nw;
+   28113           0 :     if (nb > 1 && nb < *k) {
+   28114             :         iws = nw * nb;
+   28115           0 :         if (*lwork < iws) {
+   28116           0 :             nb = *lwork / ldwork;
+   28117             :             nbmin = DORMLQ_MINBLOCKSIZE;
+   28118             :         }
+   28119             :     }
+   28120             : 
+   28121           0 :     if (nb < nbmin || nb >= *k) {
+   28122             : 
+   28123             : 
+   28124           0 :         PLUMED_BLAS_F77_FUNC(sorml2,SORML2)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   28125             :                 c_offset], ldc, &work[1], &iinfo);
+   28126             :     } else {
+   28127             : 
+   28128           0 :         if ((left && notran) || (!left && !notran)) {
+   28129             :             i1 = 1;
+   28130             :             i2 = *k;
+   28131             :             i3 = nb;
+   28132             :         } else {
+   28133           0 :             i1 = (*k - 1) / nb * nb + 1;
+   28134             :             i2 = 1;
+   28135           0 :             i3 = -nb;
+   28136             :         }
+   28137             : 
+   28138           0 :         if (left) {
+   28139           0 :             ni = *n;
+   28140             :             jc = 1;
+   28141             :         } else {
+   28142           0 :             mi = *m;
+   28143             :             ic = 1;
+   28144             :         }
+   28145             : 
+   28146           0 :         if (notran) {
+   28147           0 :             *(unsigned char *)transt = 'T';
+   28148             :         } else {
+   28149           0 :             *(unsigned char *)transt = 'N';
+   28150             :         }
+   28151             : 
+   28152             :         i__1 = i2;
+   28153             :         i__2 = i3;
+   28154           0 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   28155           0 :             i__4 = nb, i__5 = *k - i__ + 1;
+   28156           0 :             ib = (i__4<i__5) ? i__4 : i__5;
+   28157             : 
+   28158           0 :             i__4 = nq - i__ + 1;
+   28159           0 :             PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Rowwise", &i__4, &ib, &a[i__ + i__ * a_dim1], 
+   28160           0 :                     lda, &tau[i__], t, &ldt);
+   28161           0 :             if (left) {
+   28162             : 
+   28163           0 :                 mi = *m - i__ + 1;
+   28164             :                 ic = i__;
+   28165             :             } else {
+   28166             : 
+   28167           0 :                 ni = *n - i__ + 1;
+   28168             :                 jc = i__;
+   28169             :             }
+   28170             : 
+   28171           0 :             PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(side, transt, "Forward", "Rowwise", &mi, &ni, &ib, &a[i__ 
+   28172           0 :                     + i__ * a_dim1], lda, t, &ldt, &c__[ic + jc * c_dim1], 
+   28173             :                     ldc, &work[1], &ldwork);
+   28174             :         }
+   28175             :     }
+   28176           0 :     work[1] = (float) lwkopt;
+   28177           0 :     return;
+   28178             : 
+   28179             : }
+   28180             : 
+   28181             : 
+   28182             : }
+   28183             : }
+   28184             : #include "lapack.h"
+   28185             : #include "lapack_limits.h"
+   28186             : 
+   28187             : #include "blas/blas.h"
+   28188             : namespace PLMD{
+   28189             : namespace lapack{
+   28190             : using namespace blas;
+   28191             : void
+   28192           0 : PLUMED_BLAS_F77_FUNC(sormql,SORMQL)(const char *side, const char *trans, int *m, int *n, 
+   28193             :         int *k, float *a, int *lda, float *tau, float *
+   28194             :         c__, int *ldc, float *work, int *lwork, int *info)
+   28195             : {
+   28196             :     int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, i__5;
+   28197           0 :     int c__65 = 65;
+   28198             : 
+   28199             :     int i__;
+   28200             :     float t[4160];
+   28201             :     int i1, i2, i3, ib, nb, mi, ni, nq, nw, iws;
+   28202             :     int left;
+   28203             :     int nbmin, iinfo;
+   28204             :     int notran;
+   28205             :     int ldwork, lwkopt;
+   28206             :     int lquery;
+   28207             : 
+   28208             : 
+   28209           0 :     a_dim1 = *lda;
+   28210           0 :     a_offset = 1 + a_dim1;
+   28211           0 :     a -= a_offset;
+   28212             :     --tau;
+   28213             :     c_dim1 = *ldc;
+   28214             :     c_offset = 1 + c_dim1;
+   28215             :     c__ -= c_offset;
+   28216             :     --work;
+   28217             : 
+   28218           0 :     *info = 0;
+   28219           0 :     left = (*side=='L' || *side=='l');
+   28220           0 :     notran = (*trans=='N' || *trans=='n');
+   28221           0 :     lquery = *lwork == -1;
+   28222             : 
+   28223           0 :     if (left) {
+   28224           0 :         nq = *m;
+   28225           0 :         nw = *n;
+   28226             :     } else {
+   28227           0 :         nq = *n;
+   28228           0 :         nw = *m;
+   28229             :     }
+   28230             : 
+   28231             :     nb = DORMQL_BLOCKSIZE;
+   28232           0 :     lwkopt = nw * nb;
+   28233           0 :     work[1] = (float) lwkopt;
+   28234             :     
+   28235           0 :     if (*info != 0) {
+   28236             :         return;
+   28237           0 :     } else if (lquery) {
+   28238             :         return;
+   28239             :     }
+   28240             : 
+   28241           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   28242           0 :         work[1] = 1.;
+   28243           0 :         return;
+   28244             :     }
+   28245             : 
+   28246             :     nbmin = 2;
+   28247           0 :     ldwork = nw;
+   28248           0 :     if (nb > 1 && nb < *k) {
+   28249             :         iws = nw * nb;
+   28250           0 :         if (*lwork < iws) {
+   28251           0 :             nb = *lwork / ldwork;
+   28252             :             nbmin = DORMQL_MINBLOCKSIZE;
+   28253             :         }
+   28254             :     }
+   28255             : 
+   28256           0 :     if (nb < nbmin || nb >= *k) {
+   28257             : 
+   28258           0 :         PLUMED_BLAS_F77_FUNC(sorm2l,SORM2L)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   28259             :                 c_offset], ldc, &work[1], &iinfo);
+   28260             :     } else {
+   28261             : 
+   28262           0 :         if ((left && notran) || (! left && ! notran)) {
+   28263             :             i1 = 1;
+   28264             :             i2 = *k;
+   28265             :             i3 = nb;
+   28266             :         } else {
+   28267           0 :             i1 = (*k - 1) / nb * nb + 1;
+   28268             :             i2 = 1;
+   28269           0 :             i3 = -nb;
+   28270             :         }
+   28271             : 
+   28272           0 :         if (left) {
+   28273           0 :             ni = *n;
+   28274             :         } else {
+   28275           0 :             mi = *m;
+   28276             :         }
+   28277             : 
+   28278             :         i__1 = i2;
+   28279             :         i__2 = i3;
+   28280           0 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   28281           0 :             i__4 = nb, i__5 = *k - i__ + 1;
+   28282           0 :             ib = (i__4<i__5) ? i__4 : i__5;
+   28283             : 
+   28284           0 :             i__4 = nq - *k + i__ + ib - 1;
+   28285           0 :             PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Backward", "Columnwise", &i__4, &ib, &a[i__ * a_dim1 + 1]
+   28286           0 :                     , lda, &tau[i__], t, &c__65);
+   28287           0 :             if (left) {
+   28288             : 
+   28289           0 :                 mi = *m - *k + i__ + ib - 1;
+   28290             :             } else {
+   28291             : 
+   28292           0 :                 ni = *n - *k + i__ + ib - 1;
+   28293             :             }
+   28294             : 
+   28295           0 :             PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(side, trans, "Backward", "Columnwise", &mi, &ni, &ib, &a[
+   28296             :                     i__ * a_dim1 + 1], lda, t, &c__65, &c__[c_offset], ldc, &
+   28297             :                     work[1], &ldwork);
+   28298             :         }
+   28299             :     }
+   28300           0 :     work[1] = (float) lwkopt;
+   28301           0 :     return;
+   28302             : 
+   28303             : }
+   28304             : 
+   28305             : 
+   28306             : }
+   28307             : }
+   28308             : #include "lapack.h"
+   28309             : #include "lapack_limits.h"
+   28310             : 
+   28311             : #include "blas/blas.h"
+   28312             : namespace PLMD{
+   28313             : namespace lapack{
+   28314             : using namespace blas;
+   28315             : void 
+   28316           0 : PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(const char *side, 
+   28317             :         const char *trans, 
+   28318             :         int *m, 
+   28319             :         int *n, 
+   28320             :         int *k, 
+   28321             :         float *a, 
+   28322             :         int *lda, 
+   28323             :         float *tau, 
+   28324             :         float *c__, 
+   28325             :         int *ldc, 
+   28326             :         float *work, 
+   28327             :         int *lwork, 
+   28328             :         int *info)
+   28329             : {
+   28330             :    int a_dim1, a_offset, c_dim1, c_offset, i__1, i__2, i__4, i__5;
+   28331             : 
+   28332             :     int i__;
+   28333             :     float t[4160];
+   28334             :     int i1, i2, i3, ib, ic, jc, nb, mi, ni, nq, nw, iws;
+   28335             :     int left;
+   28336             :     int nbmin, iinfo;
+   28337             :     int notran;
+   28338             :     int ldwork, lwkopt;
+   28339             :     int lquery;
+   28340           0 :     int ldt = 65;
+   28341             : 
+   28342           0 :     a_dim1 = *lda;
+   28343           0 :     a_offset = 1 + a_dim1;
+   28344           0 :     a -= a_offset;
+   28345             :     --tau;
+   28346           0 :     c_dim1 = *ldc;
+   28347           0 :     c_offset = 1 + c_dim1;
+   28348           0 :     c__ -= c_offset;
+   28349             :     --work;
+   28350             : 
+   28351           0 :     *info = 0;
+   28352           0 :     left = (*side=='L' || *side=='l');
+   28353           0 :     notran = (*trans=='N' || *trans=='n');
+   28354           0 :     lquery = *lwork == -1;
+   28355             : 
+   28356           0 :     if (left) {
+   28357           0 :         nq = *m;
+   28358           0 :         nw = *n;
+   28359             :     } else {
+   28360           0 :         nq = *n;
+   28361           0 :         nw = *m;
+   28362             :     }
+   28363             : 
+   28364             :      ic = jc = 0;
+   28365             :      nb = DORMQR_BLOCKSIZE;
+   28366           0 :      lwkopt = nw * nb;
+   28367           0 :      work[1] = (float) lwkopt;
+   28368             : 
+   28369           0 :     if (*info != 0) {
+   28370             :         return;
+   28371           0 :     } else if (lquery) {
+   28372             :       return;
+   28373             :     }
+   28374             : 
+   28375           0 :     if (*m == 0 || *n == 0 || *k == 0) {
+   28376           0 :         work[1] = 1.;
+   28377           0 :         return;
+   28378             :     }
+   28379             : 
+   28380             :     nbmin = 2;
+   28381           0 :     ldwork = nw;
+   28382           0 :     if (nb > 1 && nb < *k) {
+   28383             :         iws = nw * nb;
+   28384           0 :         if (*lwork < iws) {
+   28385           0 :             nb = *lwork / ldwork;
+   28386             :             nbmin = DORMQR_MINBLOCKSIZE;
+   28387             :         }
+   28388             :     }
+   28389             : 
+   28390           0 :     if (nb < nbmin || nb >= *k) {
+   28391             : 
+   28392           0 :         PLUMED_BLAS_F77_FUNC(sorm2r,SORM2R)(side, trans, m, n, k, &a[a_offset], lda, &tau[1], &c__[
+   28393             :                 c_offset], ldc, &work[1], &iinfo);
+   28394             :     } else {
+   28395             : 
+   28396           0 :         if ((left && !notran) || (!left && notran)) {
+   28397             :             i1 = 1;
+   28398             :             i2 = *k;
+   28399             :             i3 = nb;
+   28400             :         } else {
+   28401           0 :             i1 = (*k - 1) / nb * nb + 1;
+   28402             :             i2 = 1;
+   28403           0 :             i3 = -nb;
+   28404             :         }
+   28405             : 
+   28406           0 :         if (left) {
+   28407           0 :             ni = *n;
+   28408             :             jc = 1;
+   28409             :         } else {
+   28410           0 :             mi = *m;
+   28411             :             ic = 1;
+   28412             :         }
+   28413             : 
+   28414             :         i__1 = i2;
+   28415             :         i__2 = i3;
+   28416           0 :         for (i__ = i1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += i__2) {
+   28417           0 :             i__4 = nb, i__5 = *k - i__ + 1;
+   28418           0 :             ib = (i__4<i__5) ? i__4 : i__5;
+   28419             : 
+   28420           0 :             i__4 = nq - i__ + 1;
+   28421           0 :             PLUMED_BLAS_F77_FUNC(slarft,SLARFT)("Forward", "Columnwise", &i__4, &ib, &a[i__ + i__ * 
+   28422           0 :                     a_dim1], lda, &tau[i__], t, &ldt);
+   28423           0 :             if (left) {
+   28424             : 
+   28425           0 :                 mi = *m - i__ + 1;
+   28426             :                 ic = i__;
+   28427             :             } else {
+   28428           0 :                 ni = *n - i__ + 1;
+   28429             :                 jc = i__;
+   28430             :             }
+   28431             : 
+   28432           0 :             PLUMED_BLAS_F77_FUNC(slarfb,SLARFB)(side, trans, "Forward", "Columnwise", &mi, &ni, &ib, &a[
+   28433           0 :                     i__ + i__ * a_dim1], lda, t, &ldt, &c__[ic + jc * 
+   28434             :                     c_dim1], ldc, &work[1], &ldwork);
+   28435             :         }
+   28436             :     }
+   28437           0 :     work[1] = (float) lwkopt;
+   28438           0 :     return;
+   28439             : 
+   28440             : 
+   28441             : }
+   28442             : 
+   28443             : 
+   28444             : }
+   28445             : }
+   28446             : #include "lapack.h"
+   28447             : #include "lapack_limits.h"
+   28448             : 
+   28449             : 
+   28450             : #include "blas/blas.h"
+   28451             : namespace PLMD{
+   28452             : namespace lapack{
+   28453             : using namespace blas;
+   28454             : void
+   28455           0 : PLUMED_BLAS_F77_FUNC(sormtr,SORMTR)(const char *side, 
+   28456             :         const char *uplo,
+   28457             :         const char *trans, 
+   28458             :         int *m, 
+   28459             :         int *n,
+   28460             :         float *a, 
+   28461             :         int *lda, 
+   28462             :         float *tau, 
+   28463             :         float *c__, 
+   28464             :         int *ldc,
+   28465             :         float *work, 
+   28466             :         int *lwork, 
+   28467             :         int *info)
+   28468             : {
+   28469             :     int a_dim1, a_offset, c_dim1, c_offset, i__2;
+   28470             : 
+   28471             :     int i1, i2, nb, mi, ni, nq, nw;
+   28472             :     int left;
+   28473             :     int iinfo;
+   28474             :     int upper;
+   28475             :     int lwkopt;
+   28476             :     int lquery;
+   28477             : 
+   28478             : 
+   28479           0 :     a_dim1 = *lda;
+   28480           0 :     a_offset = 1 + a_dim1;
+   28481           0 :     a -= a_offset;
+   28482             :     --tau;
+   28483           0 :     c_dim1 = *ldc;
+   28484           0 :     c_offset = 1 + c_dim1;
+   28485           0 :     c__ -= c_offset;
+   28486             :     --work;
+   28487             : 
+   28488           0 :     *info = 0;
+   28489           0 :     left = (*side=='L' || *side=='l');
+   28490           0 :     upper = (*uplo=='U' || *uplo=='u');
+   28491           0 :     lquery = *lwork == -1;
+   28492             : 
+   28493           0 :     if (left) {
+   28494           0 :         nq = *m;
+   28495           0 :         nw = *n;
+   28496             :     } else {
+   28497           0 :         nq = *n;
+   28498           0 :         nw = *m;
+   28499             :     }
+   28500             : 
+   28501             : 
+   28502             :     nb = DORMQL_BLOCKSIZE;
+   28503           0 :     lwkopt = nw * nb;
+   28504           0 :     work[1] = (float) lwkopt;
+   28505             :     
+   28506           0 :     if (*info != 0) {
+   28507             :         i__2 = -(*info);
+   28508             :         return;
+   28509           0 :     } else if (lquery) {
+   28510             :         return;
+   28511             :     }
+   28512             : 
+   28513           0 :     if (*m == 0 || *n == 0 || nq == 1) {
+   28514           0 :         work[1] = 1.;
+   28515           0 :         return;
+   28516             :     }
+   28517             : 
+   28518           0 :     if (left) {
+   28519           0 :         mi = *m - 1;
+   28520           0 :         ni = *n;
+   28521             :     } else {
+   28522           0 :         mi = *m;
+   28523           0 :         ni = *n - 1;
+   28524             :     }
+   28525             : 
+   28526           0 :     if (upper) {
+   28527           0 :         i__2 = nq - 1;
+   28528           0 :         PLUMED_BLAS_F77_FUNC(sormql,SORMQL)(side, trans, &mi, &ni, &i__2, &a[(a_dim1 << 1) + 1], lda, &
+   28529             :                 tau[1], &c__[c_offset], ldc, &work[1], lwork, &iinfo);
+   28530             :     } else {
+   28531           0 :         if (left) {
+   28532             :             i1 = 2;
+   28533             :             i2 = 1;
+   28534             :         } else {
+   28535             :             i1 = 1;
+   28536             :             i2 = 2;
+   28537             :         }
+   28538           0 :         i__2 = nq - 1;
+   28539           0 :         PLUMED_BLAS_F77_FUNC(sormqr,SORMQR)(side, trans, &mi, &ni, &i__2, &a[a_dim1 + 2], lda, &tau[1], &
+   28540           0 :                 c__[i1 + i2 * c_dim1], ldc, &work[1], lwork, &iinfo);
+   28541             :     }
+   28542           0 :     work[1] = (float) lwkopt;
+   28543           0 :     return;
+   28544             : 
+   28545             : }
+   28546             : 
+   28547             : 
+   28548             : }
+   28549             : }
+   28550             : #include <cmath>
+   28551             : #include "lapack.h"
+   28552             : #include "lapack_limits.h"
+   28553             : 
+   28554             : #include "real.h"
+   28555             : 
+   28556             : #include "blas/blas.h"
+   28557             : namespace PLMD{
+   28558             : namespace lapack{
+   28559             : using namespace blas;
+   28560             : void
+   28561           0 : PLUMED_BLAS_F77_FUNC(sstebz,SSTEBZ)(const char *range, 
+   28562             :                         const char *order,
+   28563             :                         int *n,
+   28564             :                         float *vl, 
+   28565             :                         float *vu, 
+   28566             :                         int *il,
+   28567             :                         int *iu,
+   28568             :                         float *abstol, 
+   28569             :                         float *d__,
+   28570             :                         float *e,
+   28571             :                         int *m, 
+   28572             :                         int *nsplit, 
+   28573             :                         float *w,
+   28574             :                         int *iblock,
+   28575             :                         int *isplit,
+   28576             :                         float *work, 
+   28577             :                         int *iwork, 
+   28578             :                         int *info)
+   28579             : {
+   28580             :     int i__1, i__2, i__3;
+   28581             :     float d__1, d__2, d__3, d__4, d__5;
+   28582           0 :     int c__1 = 1;
+   28583           0 :     int c__3 = 3;
+   28584           0 :     int c__2 = 2;
+   28585           0 :     int c__0 = 0;
+   28586             : 
+   28587             :     int j, ib, jb, ie, je, nb;
+   28588             :     float gl;
+   28589             :     int im, in;
+   28590             :     float gu;
+   28591             :     int iw;
+   28592             :     float wl, wu;
+   28593             :     int nwl;
+   28594             :     float ulp, wlu, wul;
+   28595             :     int nwu;
+   28596             :     float tmp1, tmp2;
+   28597             :     int iend, ioff, iout, itmp1, jdisc;
+   28598             :     int iinfo;
+   28599             :     float atoli;
+   28600             :     int iwoff;
+   28601             :     float bnorm;
+   28602             :     int itmax;
+   28603             :     float wkill, rtoli, tnorm;
+   28604             :     int ibegin;
+   28605             :     int irange, idiscl;
+   28606             :     int idumma[1];
+   28607             :     int idiscu, iorder;
+   28608             :     int ncnvrg;
+   28609             :     float pivmin;
+   28610             :     int toofew;
+   28611             :     const float safemn = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   28612             : 
+   28613           0 :     --iwork;
+   28614           0 :     --work;
+   28615           0 :     --isplit;
+   28616           0 :     --iblock;
+   28617           0 :     --w;
+   28618           0 :     --e;
+   28619           0 :     --d__;
+   28620             : 
+   28621           0 :     *info = 0;
+   28622             : 
+   28623           0 :     if (*range=='A' || *range=='a') {
+   28624             :         irange = 1;
+   28625           0 :     } else if (*range=='V' || *range=='v') {
+   28626             :         irange = 2;
+   28627             :     } else if (*range=='I' || *range=='i') {
+   28628             :         irange = 3;
+   28629             :     } else {
+   28630             :         irange = 0;
+   28631             :     }
+   28632             : 
+   28633           0 :     if (*order=='B' || *order=='b') {
+   28634             :         iorder = 2;
+   28635           0 :     } else if (*order=='E' || *order=='e') {
+   28636             :         iorder = 1;
+   28637             :     } else {
+   28638             :         iorder = 0;
+   28639             :     }
+   28640             : 
+   28641           0 :     if (irange <= 0) {
+   28642           0 :         *info = -1;
+   28643           0 :     } else if (iorder <= 0) {
+   28644           0 :         *info = -2;
+   28645           0 :     } else if (*n < 0) {
+   28646           0 :         *info = -3;
+   28647           0 :     } else if (irange == 2) {
+   28648           0 :         if (*vl >= *vu) {
+   28649           0 :             *info = -5;
+   28650             :         }
+   28651           0 :     } else if (irange == 3 && (*il < 1 || *il > (*n))) {
+   28652           0 :         *info = -6;
+   28653           0 :     } else if (irange == 3 && (*iu < ((*n<*il) ? *n : *il) || *iu > *n)) {
+   28654           0 :         *info = -7;
+   28655             :     }
+   28656             : 
+   28657           0 :     if (*info != 0) {
+   28658             :         return;
+   28659             :     }
+   28660             : 
+   28661           0 :     *info = 0;
+   28662             :     ncnvrg = 0;
+   28663             :     toofew = 0;
+   28664             : 
+   28665           0 :     *m = 0;
+   28666           0 :     if (*n == 0) {
+   28667             :         return;
+   28668             :     }
+   28669             : 
+   28670           0 :     if (irange == 3 && *il == 1 && *iu == *n) {
+   28671             :         irange = 1;
+   28672             :     }
+   28673             : 
+   28674             :     ulp = 2*PLUMED_GMX_FLOAT_EPS;
+   28675           0 :     rtoli = ulp * 2.;
+   28676             :     nb = DSTEBZ_BLOCKSIZE;
+   28677             :     // cppcheck-suppress knownConditionTrueFalse
+   28678             :     if (nb <= 1) {
+   28679           0 :         nb = 0;
+   28680             :     }
+   28681             : 
+   28682           0 :     if (*n == 1) {
+   28683           0 :         *nsplit = 1;
+   28684           0 :         isplit[1] = 1;
+   28685           0 :         if (irange == 2 && (*vl >= d__[1] || *vu < d__[1])) {
+   28686           0 :             *m = 0;
+   28687             :         } else {
+   28688           0 :             w[1] = d__[1];
+   28689           0 :             iblock[1] = 1;
+   28690           0 :             *m = 1;
+   28691             :         }
+   28692           0 :         return;
+   28693             :     }
+   28694             : 
+   28695           0 :     *nsplit = 1;
+   28696           0 :     work[*n] = 0.;
+   28697           0 :     pivmin = 1.;
+   28698           0 :     i__1 = *n;
+   28699           0 :     for (j = 2; j <= i__1; ++j) {
+   28700           0 :         d__1 = e[j - 1];
+   28701           0 :         tmp1 = d__1 * d__1;
+   28702             :         d__2 = ulp;
+   28703           0 :         if (std::abs(d__[j] * d__[j - 1]) * (d__2 * d__2) + safemn 
+   28704             :                 > tmp1) {
+   28705           0 :             isplit[*nsplit] = j - 1;
+   28706           0 :             ++(*nsplit);
+   28707           0 :             work[j - 1] = 0.;
+   28708             :         } else {
+   28709           0 :             work[j - 1] = tmp1;
+   28710           0 :             pivmin = (pivmin>tmp1) ? pivmin : tmp1;
+   28711             :         }
+   28712             :     }
+   28713           0 :     isplit[*nsplit] = *n;
+   28714           0 :     pivmin *= safemn;
+   28715             : 
+   28716           0 :     if (irange == 3) {
+   28717             : 
+   28718           0 :         gu = d__[1];
+   28719             :         gl = d__[1];
+   28720             :         tmp1 = 0.;
+   28721             : 
+   28722             :         i__1 = *n - 1;
+   28723           0 :         for (j = 1; j <= i__1; ++j) {
+   28724           0 :             tmp2 =  std::sqrt(work[j]);
+   28725           0 :             d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
+   28726           0 :             gu = (d__1>d__2) ? d__1 : d__2;
+   28727           0 :             d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
+   28728           0 :             gl = (d__1<d__2) ? d__1 : d__2;
+   28729             :             tmp1 = tmp2;
+   28730             :         }
+   28731             : 
+   28732           0 :         d__1 = gu, d__2 = d__[*n] + tmp1;
+   28733           0 :         gu = (d__1>d__2) ? d__1 : d__2;
+   28734           0 :         d__1 = gl, d__2 = d__[*n] - tmp1;
+   28735           0 :         gl = (d__1<d__2) ? d__1 : d__2;
+   28736             :         d__1 = std::abs(gl);
+   28737             :         d__2 = std::abs(gu);
+   28738           0 :         tnorm = (d__1>d__2) ? d__1 : d__2;
+   28739           0 :         gl = gl - tnorm * 2. * ulp * *n - pivmin * 4.;
+   28740           0 :         gu = gu + tnorm * 2. * ulp * *n + pivmin * 2.;
+   28741             : 
+   28742           0 :         itmax = (int) ((std::log(tnorm + pivmin) - std::log(pivmin)) / std::log(2.)) + 2;
+   28743           0 :         if (*abstol <= 0.) {
+   28744           0 :             atoli = ulp * tnorm;
+   28745             :         } else {
+   28746           0 :             atoli = *abstol;
+   28747             :         }
+   28748             : 
+   28749           0 :         work[*n + 1] = gl;
+   28750           0 :         work[*n + 2] = gl;
+   28751           0 :         work[*n + 3] = gu;
+   28752           0 :         work[*n + 4] = gu;
+   28753           0 :         work[*n + 5] = gl;
+   28754           0 :         work[*n + 6] = gu;
+   28755           0 :         iwork[1] = -1;
+   28756           0 :         iwork[2] = -1;
+   28757           0 :         iwork[3] = *n + 1;
+   28758           0 :         iwork[4] = *n + 1;
+   28759           0 :         iwork[5] = *il - 1;
+   28760           0 :         iwork[6] = *iu;
+   28761             : 
+   28762           0 :         PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(&c__3, &itmax, n, &c__2, &c__2, &nb, &atoli, &rtoli, &pivmin, 
+   28763           0 :                 &d__[1], &e[1], &work[1], &iwork[5], &work[*n + 1], &work[*n 
+   28764           0 :                 + 5], &iout, &iwork[1], &w[1], &iblock[1], &iinfo);
+   28765             : 
+   28766           0 :         if (iwork[6] == *iu) {
+   28767           0 :             wl = work[*n + 1];
+   28768           0 :             wlu = work[*n + 3];
+   28769           0 :             nwl = iwork[1];
+   28770           0 :             wu = work[*n + 4];
+   28771           0 :             wul = work[*n + 2];
+   28772           0 :             nwu = iwork[4];
+   28773             :         } else {
+   28774           0 :             wl = work[*n + 2];
+   28775           0 :             wlu = work[*n + 4];
+   28776           0 :             nwl = iwork[2];
+   28777           0 :             wu = work[*n + 3];
+   28778           0 :             wul = work[*n + 1];
+   28779           0 :             nwu = iwork[3];
+   28780             :         }
+   28781             : 
+   28782           0 :         if (nwl < 0 || nwl >= *n || nwu < 1 || nwu > *n) {
+   28783           0 :             *info = 4;
+   28784           0 :             return;
+   28785             :         }
+   28786             :     } else {
+   28787             : 
+   28788             : 
+   28789             :       /* avoid warnings for high gcc optimization */
+   28790             :       wlu = wul = 1.0;
+   28791             : 
+   28792           0 :         d__3 = std::abs(d__[1]) + std::abs(e[1]);
+   28793           0 :         d__4 = std::abs(d__[*n]) + std::abs(e[*n - 1]);
+   28794           0 :         tnorm = (d__3>d__4) ? d__3 : d__4;
+   28795             : 
+   28796             :         i__1 = *n - 1;
+   28797           0 :         for (j = 2; j <= i__1; ++j) {
+   28798             :             d__4 = tnorm;
+   28799           0 :             d__5 = std::abs(d__[j]) + std::abs(e[j - 1]) + std::abs(e[j]);
+   28800           0 :             tnorm = (d__4>d__5) ? d__4 : d__5;
+   28801             :         }
+   28802             : 
+   28803           0 :         if (*abstol <= 0.) {
+   28804           0 :             atoli = ulp * tnorm;
+   28805             :         } else {
+   28806           0 :             atoli = *abstol;
+   28807             :         }
+   28808             : 
+   28809           0 :         if (irange == 2) {
+   28810           0 :             wl = *vl;
+   28811           0 :             wu = *vu;
+   28812             :         } else {
+   28813             :             wl = 0.;
+   28814             :             wu = 0.;
+   28815             :         }
+   28816             :     }
+   28817             : 
+   28818           0 :     *m = 0;
+   28819             :     iend = 0;
+   28820           0 :     *info = 0;
+   28821             :     nwl = 0;
+   28822             :     nwu = 0;
+   28823             : 
+   28824           0 :     i__1 = *nsplit;
+   28825           0 :     for (jb = 1; jb <= i__1; ++jb) {
+   28826             :         ioff = iend;
+   28827           0 :         ibegin = ioff + 1;
+   28828           0 :         iend = isplit[jb];
+   28829           0 :         in = iend - ioff;
+   28830             : 
+   28831           0 :         if (in == 1) {
+   28832             : 
+   28833           0 :             if (irange == 1 || wl >= d__[ibegin] - pivmin) {
+   28834           0 :                 ++nwl;
+   28835             :             }
+   28836           0 :             if (irange == 1 || wu >= d__[ibegin] - pivmin) {
+   28837           0 :                 ++nwu;
+   28838             :             }
+   28839           0 :             if (irange == 1 || ((wl < d__[ibegin] - pivmin) && (wu >= d__[ibegin] - pivmin))) {
+   28840           0 :                 ++(*m);
+   28841           0 :                 w[*m] = d__[ibegin];
+   28842           0 :                 iblock[*m] = jb;
+   28843             :             }
+   28844             :         } else {
+   28845             : 
+   28846           0 :             gu = d__[ibegin];
+   28847             :             gl = d__[ibegin];
+   28848             :             tmp1 = 0.;
+   28849             : 
+   28850             :             i__2 = iend - 1;
+   28851           0 :             for (j = ibegin; j <= i__2; ++j) {
+   28852           0 :                 tmp2 = std::abs(e[j]);
+   28853           0 :                 d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
+   28854           0 :                 gu = (d__1>d__2) ? d__1 : d__2;
+   28855           0 :                 d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
+   28856           0 :                 gl = (d__1<d__2) ? d__1 : d__2;
+   28857             :                 tmp1 = tmp2;
+   28858             :             }
+   28859             : 
+   28860           0 :             d__1 = gu, d__2 = d__[iend] + tmp1;
+   28861           0 :             gu = (d__1>d__2) ? d__1 : d__2;
+   28862           0 :             d__1 = gl, d__2 = d__[iend] - tmp1;
+   28863           0 :             gl = (d__1<d__2) ? d__1 : d__2;
+   28864             :             d__1 = std::abs(gl);
+   28865             :             d__2 = std::abs(gu);
+   28866           0 :             bnorm = (d__1>d__2) ? d__1 : d__2;
+   28867           0 :             gl = gl - bnorm * 2. * ulp * in - pivmin * 2.;
+   28868           0 :             gu = gu + bnorm * 2. * ulp * in + pivmin * 2.;
+   28869             : 
+   28870           0 :             if (*abstol <= 0.) {
+   28871             :                 d__1 = std::abs(gl);
+   28872             :                 d__2 = std::abs(gu);
+   28873           0 :                 atoli = ulp * ((d__1>d__2) ? d__1 : d__2);
+   28874             :             } else {
+   28875           0 :                 atoli = *abstol;
+   28876             :             }
+   28877             : 
+   28878           0 :             if (irange > 1) {
+   28879           0 :                 if (gu < wl) {
+   28880           0 :                     nwl += in;
+   28881           0 :                     nwu += in;
+   28882             :                 }
+   28883             :                 gl = (gl>wl) ? gl : wl;
+   28884             :                 gu = (gu<wu) ? gu : wu;
+   28885             :                 if (gl >= gu) {
+   28886             :                 }
+   28887           0 :                 continue;
+   28888             :             }
+   28889             : 
+   28890           0 :             work[*n + 1] = gl;
+   28891           0 :             work[*n + in + 1] = gu;
+   28892           0 :             PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(&c__1, &c__0, &in, &in, &c__1, &nb, &atoli, &rtoli, &
+   28893             :                     pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
+   28894           0 :                     work[*n + 1], &work[*n + (in << 1) + 1], &im, &iwork[1], &
+   28895           0 :                     w[*m + 1], &iblock[*m + 1], &iinfo);
+   28896             : 
+   28897           0 :             nwl += iwork[1];
+   28898           0 :             nwu += iwork[in + 1];
+   28899           0 :             iwoff = *m - iwork[1];
+   28900             : 
+   28901           0 :             itmax = (int) ((log(gu - gl + pivmin) - log(pivmin)) / log(2.)
+   28902           0 :                     ) + 2;
+   28903           0 :             PLUMED_BLAS_F77_FUNC(slaebz,SLAEBZ)(&c__2, &itmax, &in, &in, &c__1, &nb, &atoli, &rtoli, &
+   28904             :                     pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
+   28905           0 :                     work[*n + 1], &work[*n + (in << 1) + 1], &iout, &iwork[1],
+   28906           0 :                      &w[*m + 1], &iblock[*m + 1], &iinfo);
+   28907             : 
+   28908           0 :             i__2 = iout;
+   28909           0 :             for (j = 1; j <= i__2; ++j) {
+   28910           0 :                 tmp1 = (work[j + *n] + work[j + in + *n]) * .5;
+   28911             : 
+   28912           0 :                 if (j > iout - iinfo) {
+   28913             :                     ncnvrg = 1;
+   28914           0 :                     ib = -jb;
+   28915             :                 } else {
+   28916             :                     ib = jb;
+   28917             :                 }
+   28918           0 :                 i__3 = iwork[j + in] + iwoff;
+   28919           0 :                 for (je = iwork[j] + 1 + iwoff; je <= i__3; ++je) {
+   28920           0 :                     w[je] = tmp1;
+   28921           0 :                     iblock[je] = ib;
+   28922             :                 }
+   28923             :             }
+   28924             : 
+   28925           0 :             *m += im;
+   28926             :         }
+   28927             :     }
+   28928             : 
+   28929           0 :     if (irange == 3) {
+   28930           0 :         im = 0;
+   28931           0 :         idiscl = *il - 1 - nwl;
+   28932           0 :         idiscu = nwu - *iu;
+   28933             : 
+   28934           0 :         if (idiscl > 0 || idiscu > 0) {
+   28935           0 :             i__1 = *m;
+   28936           0 :             for (je = 1; je <= i__1; ++je) {
+   28937           0 :                 if (w[je] <= wlu && idiscl > 0) {
+   28938           0 :                     --idiscl;
+   28939           0 :                 } else if (w[je] >= wul && idiscu > 0) {
+   28940           0 :                     --idiscu;
+   28941             :                 } else {
+   28942           0 :                     ++im;
+   28943           0 :                     w[im] = w[je];
+   28944           0 :                     iblock[im] = iblock[je];
+   28945             :                 }
+   28946             :             }
+   28947           0 :             *m = im;
+   28948             :         }
+   28949           0 :         if (idiscl > 0 || idiscu > 0) {
+   28950             : 
+   28951           0 :             if (idiscl > 0) {
+   28952             :                 wkill = wu;
+   28953             :                 i__1 = idiscl;
+   28954           0 :                 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
+   28955             :                     iw = 0;
+   28956           0 :                     i__2 = *m;
+   28957           0 :                     for (je = 1; je <= i__2; ++je) {
+   28958           0 :                         if (iblock[je] != 0 && (w[je] < wkill || iw == 0)) {
+   28959             :                             iw = je;
+   28960             :                             wkill = w[je];
+   28961             :                         }
+   28962             :                     }
+   28963           0 :                     iblock[iw] = 0;
+   28964             :                 }
+   28965             :             }
+   28966           0 :             if (idiscu > 0) {
+   28967             : 
+   28968             :                 wkill = wl;
+   28969             :                 i__1 = idiscu;
+   28970           0 :                 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
+   28971             :                     iw = 0;
+   28972           0 :                     i__2 = *m;
+   28973           0 :                     for (je = 1; je <= i__2; ++je) {
+   28974           0 :                         if (iblock[je] != 0 && (w[je] > wkill || iw == 0)) {
+   28975             :                             iw = je;
+   28976             :                             wkill = w[je];
+   28977             :                         }
+   28978             :                     }
+   28979           0 :                     iblock[iw] = 0;
+   28980             :                 }
+   28981             :             }
+   28982           0 :             im = 0;
+   28983           0 :             i__1 = *m;
+   28984           0 :             for (je = 1; je <= i__1; ++je) {
+   28985           0 :                 if (iblock[je] != 0) {
+   28986           0 :                     ++im;
+   28987           0 :                     w[im] = w[je];
+   28988           0 :                     iblock[im] = iblock[je];
+   28989             :                 }
+   28990             :             }
+   28991           0 :             *m = im;
+   28992             :         }
+   28993           0 :         if (idiscl < 0 || idiscu < 0) {
+   28994             :             toofew = 1;
+   28995             :         }
+   28996             :     }
+   28997             : 
+   28998           0 :     if (iorder == 1 && *nsplit > 1) {
+   28999           0 :         i__1 = *m - 1;
+   29000           0 :         for (je = 1; je <= i__1; ++je) {
+   29001             :             ie = 0;
+   29002           0 :             tmp1 = w[je];
+   29003           0 :             i__2 = *m;
+   29004           0 :             for (j = je + 1; j <= i__2; ++j) {
+   29005           0 :                 if (w[j] < tmp1) {
+   29006             :                     ie = j;
+   29007             :                     tmp1 = w[j];
+   29008             :                 }
+   29009             :             }
+   29010             : 
+   29011           0 :             if (ie != 0) {
+   29012           0 :                 itmp1 = iblock[ie];
+   29013           0 :                 w[ie] = w[je];
+   29014           0 :                 iblock[ie] = iblock[je];
+   29015           0 :                 w[je] = tmp1;
+   29016           0 :                 iblock[je] = itmp1;
+   29017             :             }
+   29018             :         }
+   29019             :     }
+   29020             : 
+   29021           0 :     *info = 0;
+   29022           0 :     if (ncnvrg) {
+   29023           0 :         ++(*info);
+   29024             :     }
+   29025           0 :     if (toofew) {
+   29026           0 :         *info += 2;
+   29027             :     }
+   29028             :     return;
+   29029             : 
+   29030             : }
+   29031             : 
+   29032             : 
+   29033             : }
+   29034             : }
+   29035             : #include <cmath>
+   29036             : #include "blas/blas.h"
+   29037             : #include "lapack.h"
+   29038             : #include "lapack_limits.h"
+   29039             : 
+   29040             : #include "real.h"
+   29041             : 
+   29042             : #include "blas/blas.h"
+   29043             : namespace PLMD{
+   29044             : namespace lapack{
+   29045             : using namespace blas;
+   29046             : void
+   29047           0 : PLUMED_BLAS_F77_FUNC(sstegr,SSTEGR)(const char *jobz, 
+   29048             :         const char *range, 
+   29049             :         int *n, 
+   29050             :         float *d__, 
+   29051             :         float *e, 
+   29052             :         float *vl, 
+   29053             :         float *vu, 
+   29054             :         int *il, 
+   29055             :         int *iu, 
+   29056             :         float *abstol, 
+   29057             :         int *m, 
+   29058             :         float *w, 
+   29059             :         float *z__, 
+   29060             :         int *ldz, 
+   29061             :         int *isuppz,
+   29062             :         float *work, 
+   29063             :         int *lwork, 
+   29064             :         int *iwork, 
+   29065             :         int *liwork, 
+   29066             :         int *info)
+   29067             : {
+   29068             :     int z_dim1, z_offset, i__1, i__2;
+   29069             :     float d__1, d__2;
+   29070           0 :     int c__1 = 1;
+   29071             : 
+   29072             :     int i__, j;
+   29073             :     int jj;
+   29074             :     float eps, tol, tmp, rmin, rmax;
+   29075             :     int itmp;
+   29076             :     float tnrm;
+   29077             :     float scale;
+   29078             :     int iinfo, iindw;
+   29079             :     int lwmin;
+   29080             :     int wantz;
+   29081             :     int iindbl;
+   29082             :     int valeig,alleig,indeig;
+   29083             :     float safmin,minval;
+   29084             :     float bignum;
+   29085             :     int iindwk, indgrs;
+   29086             :     float thresh;
+   29087             :     int iinspl, indwrk, liwmin, nsplit;
+   29088             :     float smlnum;
+   29089             :     int lquery;
+   29090             : 
+   29091             : 
+   29092             :     --d__;
+   29093             :     --e;
+   29094           0 :     --w;
+   29095           0 :     z_dim1 = *ldz;
+   29096           0 :     z_offset = 1 + z_dim1;
+   29097           0 :     z__ -= z_offset;
+   29098           0 :     --isuppz;
+   29099           0 :     --work;
+   29100           0 :     --iwork;
+   29101             : 
+   29102           0 :     wantz = (*jobz=='V' || *jobz=='v');
+   29103           0 :     alleig = (*range=='A' || *range=='a');
+   29104           0 :     valeig = (*range=='V' || *range=='v');
+   29105           0 :     indeig = (*range=='I' || *range=='i');
+   29106             : 
+   29107           0 :     lquery = *lwork == -1 || *liwork == -1;
+   29108           0 :     lwmin = *n * 17;
+   29109           0 :     liwmin = *n * 10;
+   29110             : 
+   29111           0 :     *info = 0;
+   29112           0 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   29113           0 :         *info = -1;
+   29114           0 :     } else if (! (alleig || valeig || indeig)) {
+   29115           0 :         *info = -2;
+   29116           0 :     } else if (*n < 0) {
+   29117           0 :         *info = -3;
+   29118           0 :     } else if (valeig && *n > 0 && *vu <= *vl) {
+   29119           0 :         *info = -7;
+   29120           0 :     } else if (indeig && (*il < 1 || *il > *n)) {
+   29121           0 :         *info = -8;
+   29122           0 :     } else if (indeig && (*iu < *il || *iu > *n)) {
+   29123           0 :         *info = -9;
+   29124           0 :     } else if (*ldz < 1 || (wantz && *ldz < *n)) {
+   29125           0 :         *info = -14;
+   29126           0 :     } else if (*lwork < lwmin && ! lquery) {
+   29127           0 :         *info = -17;
+   29128           0 :     } else if (*liwork < liwmin && ! lquery) {
+   29129           0 :         *info = -19;
+   29130             :     }
+   29131           0 :     if (*info == 0) {
+   29132           0 :         work[1] = (float) lwmin;
+   29133           0 :         iwork[1] = liwmin;
+   29134             :     }
+   29135             : 
+   29136           0 :     if (*info != 0) {
+   29137             :         i__1 = -(*info);
+   29138             :         return;
+   29139           0 :     } else if (lquery) {
+   29140             :         return;
+   29141             :     }
+   29142             : 
+   29143           0 :     *m = 0;
+   29144           0 :     if (*n == 0) {
+   29145             :         return;
+   29146             :     }
+   29147             : 
+   29148           0 :     if (*n == 1) {
+   29149           0 :         if (alleig || indeig) {
+   29150           0 :             *m = 1;
+   29151           0 :             w[1] = d__[1];
+   29152             :         } else {
+   29153           0 :             if (*vl < d__[1] && *vu >= d__[1]) {
+   29154           0 :                 *m = 1;
+   29155           0 :                 w[1] = d__[1];
+   29156             :             }
+   29157             :         }
+   29158           0 :         if (wantz) {
+   29159           0 :             z__[z_dim1 + 1] = 1.;
+   29160             :         }
+   29161           0 :         return;
+   29162             :     }
+   29163             : 
+   29164             :     minval = PLUMED_GMX_FLOAT_MIN;
+   29165             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   29166             :     eps = PLUMED_GMX_FLOAT_EPS;
+   29167             :     smlnum = safmin / eps;
+   29168             :     bignum = 1. / smlnum;
+   29169             :     rmin =  std::sqrt(smlnum);
+   29170           0 :     d__1 =  std::sqrt(bignum), d__2 = 1. / std::sqrt(sqrt(safmin));
+   29171             :     rmax = (d__1<d__2) ? d__1 : d__2;
+   29172           0 :     scale = 1.;
+   29173           0 :     tnrm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("M", n, &d__[1], &e[1]);
+   29174           0 :     if (tnrm > 0. && tnrm < rmin) {
+   29175           0 :         scale = rmin / tnrm;
+   29176           0 :     } else if (tnrm > rmax) {
+   29177           0 :         scale = rmax / tnrm;
+   29178             :     }
+   29179           0 :     if ( std::abs(scale-1.0)>PLUMED_GMX_FLOAT_EPS) {
+   29180           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(n, &scale, &d__[1], &c__1);
+   29181           0 :         i__1 = *n - 1;
+   29182           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &scale, &e[1], &c__1);
+   29183           0 :         tnrm *= scale;
+   29184             :     }
+   29185             :     indgrs = 1;
+   29186           0 :     indwrk = (*n << 1) + 1;
+   29187             : 
+   29188             :     iinspl = 1;
+   29189           0 :     iindbl = *n + 1;
+   29190             :     iindw = (*n << 1) + 1;
+   29191           0 :     iindwk = *n * 3 + 1;
+   29192             : 
+   29193           0 :     thresh = eps * tnrm;
+   29194           0 :     PLUMED_BLAS_F77_FUNC(slarrex,SLARREX)(range, n, vl, vu, il, iu, &d__[1], &e[1], &thresh, &nsplit, &
+   29195           0 :             iwork[iinspl], m, &w[1], &iwork[iindbl], &iwork[iindw], &work[
+   29196           0 :             indgrs], &work[indwrk], &iwork[iindwk], &iinfo);
+   29197             :     
+   29198           0 :     if (iinfo != 0) {
+   29199           0 :         *info = 1;
+   29200           0 :         return;
+   29201             :     }
+   29202             : 
+   29203           0 :     if (wantz) {
+   29204           0 :         d__1 = *abstol, d__2 = (float) (*n) * eps;
+   29205           0 :         tol = (d__1>d__2) ? d__1 : d__2;
+   29206           0 :         PLUMED_BLAS_F77_FUNC(slarrvx,SLARRVX)(n, &d__[1], &e[1], &iwork[iinspl], m, &w[1], &iwork[iindbl], &
+   29207             :                 iwork[iindw], &work[indgrs], &tol, &z__[z_offset], ldz, &
+   29208             :                 isuppz[1], &work[indwrk], &iwork[iindwk], &iinfo);
+   29209           0 :         if (iinfo != 0) {
+   29210           0 :             *info = 2;
+   29211           0 :             return;
+   29212             :         }
+   29213             :     }
+   29214             : 
+   29215           0 :     i__1 = *m;
+   29216           0 :     for (j = 1; j <= i__1; ++j) {
+   29217           0 :         itmp = iwork[iindbl + j - 1];
+   29218           0 :         w[j] += e[iwork[iinspl + itmp - 1]];
+   29219             :     } 
+   29220             : 
+   29221           0 :     if (std::abs(scale-1.0)>PLUMED_GMX_FLOAT_EPS) {
+   29222           0 :         d__1 = 1. / scale;
+   29223           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(m, &d__1, &w[1], &c__1);
+   29224             :     }
+   29225           0 :     if (nsplit > 1) {
+   29226           0 :         i__1 = *m - 1;
+   29227           0 :         for (j = 1; j <= i__1; ++j) {
+   29228             :             i__ = 0;
+   29229           0 :             tmp = w[j];
+   29230           0 :             i__2 = *m;
+   29231           0 :             for (jj = j + 1; jj <= i__2; ++jj) {
+   29232           0 :                 if (w[jj] < tmp) {
+   29233             :                     i__ = jj;
+   29234             :                     tmp = w[jj];
+   29235             :                 }
+   29236             :             }
+   29237           0 :             if (i__ != 0) {
+   29238           0 :                 w[i__] = w[j];
+   29239           0 :                 w[j] = tmp;
+   29240           0 :                 if (wantz) {
+   29241           0 :                     PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 
+   29242           0 :                             + 1], &c__1);
+   29243           0 :                     itmp = isuppz[(i__ << 1) - 1];
+   29244           0 :                     isuppz[(i__ << 1) - 1] = isuppz[(j << 1) - 1];
+   29245           0 :                     isuppz[(j << 1) - 1] = itmp;
+   29246           0 :                     itmp = isuppz[i__ * 2];
+   29247           0 :                     isuppz[i__ * 2] = isuppz[j * 2];
+   29248           0 :                     isuppz[j * 2] = itmp;
+   29249             :                 }
+   29250             :             }
+   29251             :         }
+   29252             :     }
+   29253             : 
+   29254           0 :     work[1] = (float) lwmin;
+   29255           0 :     iwork[1] = liwmin;
+   29256           0 :     return;
+   29257             : 
+   29258             : } 
+   29259             : }
+   29260             : }
+   29261             : #include <cmath>
+   29262             : #include "blas/blas.h"
+   29263             : #include "lapack.h"
+   29264             : #include "lapack_limits.h"
+   29265             : 
+   29266             : #include "real.h"
+   29267             : 
+   29268             : #include "blas/blas.h"
+   29269             : namespace PLMD{
+   29270             : namespace lapack{
+   29271             : using namespace blas;
+   29272             : void
+   29273           0 : PLUMED_BLAS_F77_FUNC(sstein,SSTEIN)(int *n, 
+   29274             :         float *d__, 
+   29275             :         float *e, 
+   29276             :         int *m, 
+   29277             :         float *w, 
+   29278             :         int *iblock,
+   29279             :         int *isplit, 
+   29280             :         float *z__,
+   29281             :         int *ldz, 
+   29282             :         float *work,
+   29283             :         int *iwork, 
+   29284             :         int *ifail,
+   29285             :         int *info)
+   29286             : {
+   29287             :     int z_dim1, z_offset, i__1, i__2, i__3;
+   29288             :     float d__2, d__3, d__4, d__5;
+   29289             : 
+   29290             :     int i__, j, b1, j1, bn;
+   29291             :     float xj, scl, eps, sep, nrm, tol;
+   29292             :     int its;
+   29293             :     float xjm, ztr, eps1;
+   29294             :     int jblk, nblk;
+   29295             :     int jmax;
+   29296             : 
+   29297             :     int iseed[4], gpind, iinfo;
+   29298             :     float ortol;
+   29299             :     int indrv1, indrv2, indrv3, indrv4, indrv5;
+   29300             :     int nrmchk;
+   29301             :     int blksiz;
+   29302             :     float onenrm, dtpcrt, pertol;
+   29303           0 :     int c__2 = 2;
+   29304           0 :     int c__1 = 1;
+   29305           0 :     int c_n1 = -1;
+   29306             : 
+   29307           0 :     --d__;
+   29308           0 :     --e;
+   29309           0 :     --w;
+   29310           0 :     --iblock;
+   29311           0 :     --isplit;
+   29312           0 :     z_dim1 = *ldz;
+   29313           0 :     z_offset = 1 + z_dim1;
+   29314           0 :     z__ -= z_offset;
+   29315           0 :     --work;
+   29316             :     --iwork;
+   29317           0 :     --ifail;
+   29318             : 
+   29319           0 :     *info = 0;
+   29320             : 
+   29321             :     xjm = 0.0;
+   29322           0 :     i__1 = *m;
+   29323           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   29324           0 :         ifail[i__] = 0;
+   29325             :     }
+   29326             : 
+   29327           0 :     if (*n < 0) {
+   29328           0 :         *info = -1;
+   29329           0 :     } else if (*m < 0 || *m > *n) {
+   29330           0 :         *info = -4;
+   29331           0 :     } else if (*ldz < (*n)) {
+   29332           0 :         *info = -9;
+   29333             :     } else {
+   29334             :         i__1 = *m;
+   29335           0 :         for (j = 2; j <= i__1; ++j) {
+   29336           0 :             if (iblock[j] < iblock[j - 1]) {
+   29337           0 :                 *info = -6;
+   29338           0 :                 break;
+   29339             :             }
+   29340           0 :             if (iblock[j] == iblock[j - 1] && w[j] < w[j - 1]) {
+   29341           0 :                 *info = -5;
+   29342           0 :                 break;
+   29343             :             }
+   29344             :         }
+   29345             :     }
+   29346             : 
+   29347           0 :     if (*info != 0) {
+   29348             :         return;
+   29349             :     }
+   29350             : 
+   29351           0 :     if (*n == 0 || *m == 0) {
+   29352             :         return;
+   29353           0 :     } else if (*n == 1) {
+   29354           0 :         z__[z_dim1 + 1] = 1.;
+   29355           0 :         return;
+   29356             :     }
+   29357             : 
+   29358             :     eps = PLUMED_GMX_FLOAT_EPS;
+   29359             : 
+   29360           0 :     for (i__ = 1; i__ <= 4; ++i__) {
+   29361           0 :         iseed[i__ - 1] = 1;
+   29362             :     }
+   29363             : 
+   29364             :     indrv1 = 0;
+   29365             :     indrv2 = indrv1 + *n;
+   29366           0 :     indrv3 = indrv2 + *n;
+   29367           0 :     indrv4 = indrv3 + *n;
+   29368           0 :     indrv5 = indrv4 + *n;
+   29369             : 
+   29370             :     j1 = 1;
+   29371           0 :     i__1 = iblock[*m];
+   29372           0 :     for (nblk = 1; nblk <= i__1; ++nblk) {
+   29373             : 
+   29374           0 :         if (nblk == 1) {
+   29375             :             b1 = 1;
+   29376             :         } else {
+   29377           0 :             b1 = isplit[nblk - 1] + 1;
+   29378             :         }
+   29379           0 :         bn = isplit[nblk];
+   29380           0 :         blksiz = bn - b1 + 1;
+   29381           0 :         if (blksiz == 1) {
+   29382           0 :             continue;
+   29383             :         }
+   29384             :         gpind = b1;
+   29385             : 
+   29386           0 :         onenrm = std::abs(d__[b1]) + std::abs(e[b1]);
+   29387             :         d__3 = onenrm;
+   29388           0 :         d__4 = std::abs(d__[bn]) + std::abs(e[bn - 1]);
+   29389           0 :         onenrm = (d__3>d__4) ? d__3 : d__4;
+   29390             :         i__2 = bn - 1;
+   29391           0 :         for (i__ = b1 + 1; i__ <= i__2; ++i__) {
+   29392             :           d__4 = onenrm;
+   29393           0 :           d__5 = std::abs(d__[i__]) + std::abs(e[i__ - 1]) + std::abs(e[i__]);
+   29394           0 :             onenrm = (d__4>d__5) ? d__4 : d__5;
+   29395             :         }
+   29396           0 :         ortol = onenrm * .001;
+   29397             : 
+   29398           0 :         dtpcrt =  std::sqrt(.1 / blksiz);
+   29399             : 
+   29400             :         jblk = 0;
+   29401           0 :         i__2 = *m;
+   29402           0 :         for (j = j1; j <= i__2; ++j) {
+   29403           0 :             if (iblock[j] != nblk) {
+   29404             :                 j1 = j;
+   29405             :                 break;
+   29406             :             }
+   29407           0 :             ++jblk;
+   29408           0 :             xj = w[j];
+   29409             : 
+   29410           0 :             if (blksiz == 1) {
+   29411           0 :                 work[indrv1 + 1] = 1.;
+   29412           0 :                 goto L120;
+   29413             :             }
+   29414             : 
+   29415           0 :             if (jblk > 1) {
+   29416           0 :                 eps1 = std::abs(eps * xj);
+   29417           0 :                 pertol = eps1 * 10.;
+   29418           0 :                 sep = xj - xjm;
+   29419           0 :                 if (sep < pertol) {
+   29420           0 :                     xj = xjm + pertol;
+   29421             :                 }
+   29422             :             }
+   29423             : 
+   29424             :             its = 0;
+   29425             :             nrmchk = 0;
+   29426             : 
+   29427           0 :             PLUMED_BLAS_F77_FUNC(slarnv,SLARNV)(&c__2, iseed, &blksiz, &work[indrv1 + 1]);
+   29428             : 
+   29429           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&blksiz, &d__[b1], &c__1, &work[indrv4 + 1], &c__1);
+   29430           0 :             i__3 = blksiz - 1;
+   29431           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__3, &e[b1], &c__1, &work[indrv2 + 2], &c__1);
+   29432           0 :             i__3 = blksiz - 1;
+   29433           0 :             PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__3, &e[b1], &c__1, &work[indrv3 + 1], &c__1);
+   29434             : 
+   29435           0 :             tol = 0.;
+   29436           0 :             PLUMED_BLAS_F77_FUNC(slagtf,SLAGTF)(&blksiz, &work[indrv4 + 1], &xj, &work[indrv2 + 2], &work[
+   29437           0 :                     indrv3 + 1], &tol, &work[indrv5 + 1], &iwork[1], &iinfo);
+   29438             : 
+   29439           0 : L70:
+   29440           0 :             ++its;
+   29441           0 :             if (its > 5) {
+   29442           0 :                 goto L100;
+   29443             :             }
+   29444             : 
+   29445             :             d__2 = eps;
+   29446           0 :             d__3 = std::abs(work[indrv4 + blksiz]);
+   29447           0 :             scl = blksiz * onenrm * ((d__2>d__3) ? d__2 : d__3) / PLUMED_BLAS_F77_FUNC(sasum,SASUM)(&blksiz, &work[
+   29448             :                     indrv1 + 1], &c__1);
+   29449           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&blksiz, &scl, &work[indrv1 + 1], &c__1);
+   29450             : 
+   29451           0 :             PLUMED_BLAS_F77_FUNC(slagts,SLAGTS)(&c_n1, &blksiz, &work[indrv4 + 1], &work[indrv2 + 2], &
+   29452             :                     work[indrv3 + 1], &work[indrv5 + 1], &iwork[1], &work[
+   29453             :                     indrv1 + 1], &tol, &iinfo);
+   29454             : 
+   29455           0 :             if (jblk == 1) {
+   29456           0 :                 goto L90;
+   29457             :             }
+   29458           0 :             if (std::abs(xj - xjm) > ortol) {
+   29459             :                 gpind = j;
+   29460             :             }
+   29461           0 :             if (gpind != j) {
+   29462           0 :                 i__3 = j - 1;
+   29463           0 :                 for (i__ = gpind; i__ <= i__3; ++i__) {
+   29464           0 :                     ztr = -PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&blksiz, &work[indrv1 + 1], &c__1, &z__[b1 + 
+   29465           0 :                             i__ * z_dim1], &c__1);
+   29466           0 :                     PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&blksiz, &ztr, &z__[b1 + i__ * z_dim1], &c__1, &
+   29467             :                             work[indrv1 + 1], &c__1);
+   29468             :                 }
+   29469             :             }
+   29470             : 
+   29471           0 : L90:
+   29472           0 :             jmax = PLUMED_BLAS_F77_FUNC(isamax,ISAMAX)(&blksiz, &work[indrv1 + 1], &c__1);
+   29473           0 :             nrm = std::abs(work[indrv1 + jmax]);
+   29474             : 
+   29475           0 :             if (nrm < dtpcrt) {
+   29476           0 :                 goto L70;
+   29477             :             }
+   29478           0 :             ++nrmchk;
+   29479           0 :             if (nrmchk < 3) {
+   29480           0 :                 goto L70;
+   29481             :             }
+   29482             : 
+   29483           0 :             goto L110;
+   29484             : 
+   29485             : L100:
+   29486           0 :             ++(*info);
+   29487           0 :             ifail[*info] = j;
+   29488             : 
+   29489           0 : L110:
+   29490           0 :             scl = 1. / PLUMED_BLAS_F77_FUNC(snrm2,SNRM2)(&blksiz, &work[indrv1 + 1], &c__1);
+   29491           0 :             jmax = PLUMED_BLAS_F77_FUNC(isamax,ISAMAX)(&blksiz, &work[indrv1 + 1], &c__1);
+   29492           0 :             if (work[indrv1 + jmax] < 0.) {
+   29493           0 :                 scl = -scl;
+   29494             :             }
+   29495           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&blksiz, &scl, &work[indrv1 + 1], &c__1);
+   29496           0 : L120:
+   29497           0 :             i__3 = *n;
+   29498           0 :             for (i__ = 1; i__ <= i__3; ++i__) {
+   29499           0 :                 z__[i__ + j * z_dim1] = 0.;
+   29500             :             }
+   29501           0 :             i__3 = blksiz;
+   29502           0 :             for (i__ = 1; i__ <= i__3; ++i__) {
+   29503           0 :                 z__[b1 + i__ - 1 + j * z_dim1] = work[indrv1 + i__];
+   29504             :             }
+   29505             : 
+   29506           0 :             xjm = xj;
+   29507             :         }
+   29508             :     }
+   29509             : 
+   29510             :     return;
+   29511             : 
+   29512             : }
+   29513             : 
+   29514             : 
+   29515             : }
+   29516             : }
+   29517             : #include <cmath>
+   29518             : #include "real.h"
+   29519             : 
+   29520             : #include "blas/blas.h"
+   29521             : #include "lapack.h"
+   29522             : #include "lapack_limits.h"
+   29523             : 
+   29524             : #include "blas/blas.h"
+   29525             : namespace PLMD{
+   29526             : namespace lapack{
+   29527             : using namespace blas;
+   29528             : void
+   29529           0 : PLUMED_BLAS_F77_FUNC(ssteqr,SSTEQR)(const char *    compz, 
+   29530             :                         int *     n, 
+   29531             :                         float *  d__, 
+   29532             :                         float *  e, 
+   29533             :                         float *  z__, 
+   29534             :                         int *     ldz, 
+   29535             :                         float *  work, 
+   29536             :                         int *     info)
+   29537             : {
+   29538           0 :     float c_b9 = 0.;
+   29539           0 :     float c_b10 = 1.;
+   29540           0 :     int c__0 = 0;
+   29541           0 :     int c__1 = 1;
+   29542           0 :     int c__2 = 2;
+   29543             :     int z_dim1, z_offset, i__1, i__2;
+   29544             :     float d__1, d__2;
+   29545             : 
+   29546             :     float b, c__, f, g;
+   29547             :     int i__, j, k, l, m;
+   29548             :     float p, r__, s;
+   29549             :     int l1, ii, mm, lm1, mm1, nm1;
+   29550             :     float rt1, rt2, eps;
+   29551             :     int lsv;
+   29552             :     float tst, eps2;
+   29553             :     int lend, jtot;
+   29554             :     float anorm;
+   29555             :     int lendm1, lendp1;
+   29556             :     int iscale;
+   29557             :     float safmin,minval;
+   29558             :     float safmax;
+   29559             :     int lendsv;
+   29560             :     float ssfmin;
+   29561             :     int nmaxit, icompz;
+   29562             :     float ssfmax;
+   29563             : 
+   29564             : 
+   29565           0 :     --d__;
+   29566           0 :     --e;
+   29567           0 :     z_dim1 = *ldz;
+   29568           0 :     z_offset = 1 + z_dim1;
+   29569           0 :     z__ -= z_offset;
+   29570           0 :     --work;
+   29571             : 
+   29572           0 :     *info = 0;
+   29573             : 
+   29574           0 :     if (*compz=='N' || *compz=='n') {
+   29575             :         icompz = 0;
+   29576           0 :     } else if (*compz=='V' || *compz=='v') {
+   29577             :         icompz = 1;
+   29578             :     } else if (*compz=='I' || *compz=='i') {
+   29579             :         icompz = 2;
+   29580             :     } else {
+   29581             :         icompz = -1;
+   29582             :     }
+   29583             :     if (icompz < 0) {
+   29584           0 :         *info = -1;
+   29585           0 :     } else if (*n < 0) {
+   29586           0 :         *info = -2;
+   29587           0 :     } else if (*ldz < 1 || (icompz > 0 && *ldz < ((*n>1) ? *n : 1))) {
+   29588           0 :         *info = -6;
+   29589             :     }
+   29590           0 :     if (*info != 0) {
+   29591             :         return;
+   29592             :     }
+   29593             : 
+   29594             : 
+   29595           0 :     if (*n == 0) {
+   29596             :         return;
+   29597             :     }
+   29598             : 
+   29599           0 :     if (*n == 1) {
+   29600           0 :         if (icompz == 2) {
+   29601           0 :             z__[z_dim1 + 1] = 1.;
+   29602             :         }
+   29603           0 :         return;
+   29604             :     }
+   29605             : 
+   29606             :     eps = PLUMED_GMX_FLOAT_EPS;
+   29607             :     d__1 = eps;
+   29608             :     eps2 = d__1 * d__1;
+   29609             :     minval = PLUMED_GMX_FLOAT_MIN;
+   29610             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   29611             : 
+   29612             :     safmax = 1. / safmin;
+   29613           0 :     ssfmax =  std::sqrt(safmax) / 3.;
+   29614           0 :     ssfmin =  std::sqrt(safmin) / eps2;
+   29615             : 
+   29616           0 :     if (icompz == 2) {
+   29617           0 :         PLUMED_BLAS_F77_FUNC(slaset,SLASET)("Full", n, n, &c_b9, &c_b10, &z__[z_offset], ldz);
+   29618             :     }
+   29619             : 
+   29620           0 :     nmaxit = *n * 30;
+   29621             :     jtot = 0;
+   29622             : 
+   29623             :     l1 = 1;
+   29624           0 :     nm1 = *n - 1;
+   29625             : 
+   29626           0 : L10:
+   29627           0 :     if (l1 > *n) {
+   29628           0 :         goto L160;
+   29629             :     }
+   29630           0 :     if (l1 > 1) {
+   29631           0 :         e[l1 - 1] = 0.;
+   29632             :     }
+   29633           0 :     if (l1 <= nm1) {
+   29634           0 :         i__1 = nm1;
+   29635           0 :         for (m = l1; m <= i__1; ++m) {
+   29636           0 :             tst = std::abs(e[m]);
+   29637           0 :             if (std::abs(tst)<PLUMED_GMX_FLOAT_MIN) {
+   29638           0 :                 goto L30;
+   29639             :             }
+   29640           0 :             if (tst <=  std::sqrt(std::abs(d__[m])) * std::sqrt(std::abs(d__[m + 1])) * eps) {
+   29641           0 :                 e[m] = 0.;
+   29642           0 :                 goto L30;
+   29643             :             }
+   29644             :         }
+   29645             :     }
+   29646           0 :     m = *n;
+   29647             : 
+   29648           0 : L30:
+   29649             :     l = l1;
+   29650             :     lsv = l;
+   29651             :     lend = m;
+   29652             :     lendsv = lend;
+   29653           0 :     l1 = m + 1;
+   29654           0 :     if (lend == l) {
+   29655           0 :         goto L10;
+   29656             :     }
+   29657             : 
+   29658           0 :     i__1 = lend - l + 1;
+   29659           0 :     anorm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("I", &i__1, &d__[l], &e[l]);
+   29660             :     iscale = 0;
+   29661           0 :     if (std::abs(anorm)<PLUMED_GMX_FLOAT_MIN) {
+   29662           0 :         goto L10;
+   29663             :     }
+   29664           0 :     if (anorm > ssfmax) {
+   29665             :         iscale = 1;
+   29666           0 :         i__1 = lend - l + 1;
+   29667           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, 
+   29668             :                 info);
+   29669           0 :         i__1 = lend - l;
+   29670           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, 
+   29671             :                 info);
+   29672           0 :     } else if (anorm < ssfmin) {
+   29673             :         iscale = 2;
+   29674           0 :         i__1 = lend - l + 1;
+   29675           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, 
+   29676             :                 info);
+   29677           0 :         i__1 = lend - l;
+   29678           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, 
+   29679             :                 info);
+   29680             :     }
+   29681             : 
+   29682           0 :     if (std::abs(d__[lend]) < std::abs(d__[l])) {
+   29683             :         lend = lsv;
+   29684             :         l = lendsv;
+   29685             :     }
+   29686             : 
+   29687           0 :     if (lend > l) {
+   29688             : 
+   29689           0 : L40:
+   29690           0 :         if (l != lend) {
+   29691           0 :             lendm1 = lend - 1;
+   29692           0 :             i__1 = lendm1;
+   29693           0 :             for (m = l; m <= i__1; ++m) {
+   29694           0 :                 d__2 = std::abs(e[m]);
+   29695           0 :                 tst = d__2 * d__2;
+   29696           0 :                 if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m+ 1]) + safmin) {
+   29697           0 :                     goto L60;
+   29698             :                 }
+   29699             :             }
+   29700             :         }
+   29701             : 
+   29702             :         m = lend;
+   29703             : 
+   29704           0 : L60:
+   29705           0 :         if (m < lend) {
+   29706           0 :             e[m] = 0.;
+   29707             :         }
+   29708           0 :         p = d__[l];
+   29709           0 :         if (m == l) {
+   29710           0 :             goto L80;
+   29711             :         }
+   29712             : 
+   29713           0 :         if (m == l + 1) {
+   29714           0 :             if (icompz > 0) {
+   29715           0 :                 PLUMED_BLAS_F77_FUNC(slaev2,SLAEV2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2, &c__, &s);
+   29716           0 :                 work[l] = c__;
+   29717           0 :                 work[*n - 1 + l] = s;
+   29718           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", n, &c__2, &work[l], &work[*n - 1 + l], &
+   29719           0 :                         z__[l * z_dim1 + 1], ldz);
+   29720             :             } else {
+   29721           0 :                 PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l], &e[l], &d__[l + 1], &rt1, &rt2);
+   29722             :             }
+   29723           0 :             d__[l] = rt1;
+   29724           0 :             d__[l + 1] = rt2;
+   29725           0 :             e[l] = 0.;
+   29726           0 :             l += 2;
+   29727           0 :             if (l <= lend) {
+   29728           0 :                 goto L40;
+   29729             :             }
+   29730           0 :             goto L140;
+   29731             :         }
+   29732             : 
+   29733           0 :         if (jtot == nmaxit) {
+   29734           0 :             goto L140;
+   29735             :         }
+   29736           0 :         ++jtot;
+   29737             : 
+   29738           0 :         g = (d__[l + 1] - p) / (e[l] * 2.);
+   29739           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&g, &c_b10);
+   29740           0 :         g = d__[m] - p + e[l] / (g + ( (g>0) ? r__ : -r__ ) );
+   29741             : 
+   29742           0 :         s = 1.;
+   29743           0 :         c__ = 1.;
+   29744             :         p = 0.;
+   29745             : 
+   29746           0 :         mm1 = m - 1;
+   29747           0 :         i__1 = l;
+   29748           0 :         for (i__ = mm1; i__ >= i__1; --i__) {
+   29749           0 :             f = s * e[i__];
+   29750           0 :             b = c__ * e[i__];
+   29751           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&g, &f, &c__, &s, &r__);
+   29752           0 :             if (i__ != m - 1) {
+   29753           0 :                 e[i__ + 1] = r__;
+   29754             :             }
+   29755           0 :             g = d__[i__ + 1] - p;
+   29756           0 :             r__ = (d__[i__] - g) * s + c__ * 2. * b;
+   29757           0 :             p = s * r__;
+   29758           0 :             d__[i__ + 1] = g + p;
+   29759           0 :             g = c__ * r__ - b;
+   29760             : 
+   29761           0 :             if (icompz > 0) {
+   29762           0 :                 work[i__] = c__;
+   29763           0 :                 work[*n - 1 + i__] = -s;
+   29764             :             }
+   29765             :         }
+   29766             : 
+   29767           0 :         if (icompz > 0) {
+   29768           0 :             mm = m - l + 1;
+   29769           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "B", n, &mm, &work[l], &work[*n - 1 + l], &z__[l 
+   29770           0 :                     * z_dim1 + 1], ldz);
+   29771             :         }
+   29772             : 
+   29773           0 :         d__[l] -= p;
+   29774           0 :         e[l] = g;
+   29775           0 :         goto L40;
+   29776             : 
+   29777             : L80:
+   29778             :         d__[l] = p;
+   29779             : 
+   29780           0 :         ++l;
+   29781           0 :         if (l <= lend) {
+   29782           0 :             goto L40;
+   29783             :         }
+   29784           0 :         goto L140;
+   29785             : 
+   29786             :     } else {
+   29787             : 
+   29788           0 : L90:
+   29789           0 :         if (l != lend) {
+   29790           0 :             lendp1 = lend + 1;
+   29791           0 :             i__1 = lendp1;
+   29792           0 :             for (m = l; m >= i__1; --m) {
+   29793           0 :                 d__2 = std::abs(e[m - 1]);
+   29794           0 :                 tst = d__2 * d__2;
+   29795           0 :                 if (tst <= eps2 * std::abs(d__[m]) * std::abs(d__[m- 1]) + safmin) {
+   29796           0 :                     goto L110;
+   29797             :                 }
+   29798             :             }
+   29799             :         }
+   29800             : 
+   29801             :         m = lend;
+   29802             : 
+   29803           0 : L110:
+   29804           0 :         if (m > lend) {
+   29805           0 :             e[m - 1] = 0.;
+   29806             :         }
+   29807           0 :         p = d__[l];
+   29808           0 :         if (m == l) {
+   29809           0 :             goto L130;
+   29810             :         }
+   29811           0 :         if (m == l - 1) {
+   29812           0 :             if (icompz > 0) {
+   29813           0 :                 PLUMED_BLAS_F77_FUNC(slaev2,SLAEV2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2, &c__, &s)
+   29814             :                         ;
+   29815           0 :                 work[m] = c__;
+   29816           0 :                 work[*n - 1 + m] = s;
+   29817           0 :                 PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", n, &c__2, &work[m], &work[*n - 1 + m], &
+   29818           0 :                         z__[(l - 1) * z_dim1 + 1], ldz);
+   29819             :             } else {
+   29820           0 :                 PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l - 1], &e[l - 1], &d__[l], &rt1, &rt2);
+   29821             :             }
+   29822           0 :             d__[l - 1] = rt1;
+   29823           0 :             d__[l] = rt2;
+   29824           0 :             e[l - 1] = 0.;
+   29825           0 :             l += -2;
+   29826           0 :             if (l >= lend) {
+   29827           0 :                 goto L90;
+   29828             :             }
+   29829           0 :             goto L140;
+   29830             :         }
+   29831             : 
+   29832           0 :         if (jtot == nmaxit) {
+   29833           0 :             goto L140;
+   29834             :         }
+   29835           0 :         ++jtot;
+   29836             : 
+   29837           0 :         g = (d__[l - 1] - p) / (e[l - 1] * 2.);
+   29838           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&g, &c_b10);
+   29839           0 :         g = d__[m] - p + e[l - 1] / (g + ( (g>0) ? r__ : -r__ ));
+   29840             : 
+   29841           0 :         s = 1.;
+   29842           0 :         c__ = 1.;
+   29843             :         p = 0.;
+   29844             : 
+   29845             :         lm1 = l - 1;
+   29846           0 :         i__1 = lm1;
+   29847           0 :         for (i__ = m; i__ <= i__1; ++i__) {
+   29848           0 :             f = s * e[i__];
+   29849           0 :             b = c__ * e[i__];
+   29850           0 :             PLUMED_BLAS_F77_FUNC(slartg,SLARTG)(&g, &f, &c__, &s, &r__);
+   29851           0 :             if (i__ != m) {
+   29852           0 :                 e[i__ - 1] = r__;
+   29853             :             }
+   29854           0 :             g = d__[i__] - p;
+   29855           0 :             r__ = (d__[i__ + 1] - g) * s + c__ * 2. * b;
+   29856           0 :             p = s * r__;
+   29857           0 :             d__[i__] = g + p;
+   29858           0 :             g = c__ * r__ - b;
+   29859             : 
+   29860           0 :             if (icompz > 0) {
+   29861           0 :                 work[i__] = c__;
+   29862           0 :                 work[*n - 1 + i__] = s;
+   29863             :             }
+   29864             :         }
+   29865             : 
+   29866           0 :         if (icompz > 0) {
+   29867           0 :             mm = l - m + 1;
+   29868           0 :             PLUMED_BLAS_F77_FUNC(slasr,SLASR)("R", "V", "F", n, &mm, &work[m], &work[*n - 1 + m], &z__[m 
+   29869           0 :                     * z_dim1 + 1], ldz);
+   29870             :         }
+   29871             : 
+   29872           0 :         d__[l] -= p;
+   29873           0 :         e[lm1] = g;
+   29874           0 :         goto L90;
+   29875             : 
+   29876             : L130:
+   29877             :         d__[l] = p;
+   29878             : 
+   29879           0 :         --l;
+   29880           0 :         if (l >= lend) {
+   29881           0 :             goto L90;
+   29882             :         }
+   29883           0 :         goto L140;
+   29884             : 
+   29885             :     }
+   29886             : 
+   29887           0 : L140:
+   29888           0 :     if (iscale == 1) {
+   29889           0 :         i__1 = lendsv - lsv + 1;
+   29890           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], 
+   29891             :                 n, info);
+   29892           0 :         i__1 = lendsv - lsv;
+   29893           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &e[lsv], n, 
+   29894             :                 info);
+   29895           0 :     } else if (iscale == 2) {
+   29896           0 :         i__1 = lendsv - lsv + 1;
+   29897           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], 
+   29898             :                 n, info);
+   29899           0 :         i__1 = lendsv - lsv;
+   29900           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &e[lsv], n, 
+   29901             :                 info);
+   29902             :     }
+   29903             : 
+   29904           0 :     if (jtot < nmaxit) {
+   29905           0 :         goto L10;
+   29906             :     }
+   29907           0 :     i__1 = *n - 1;
+   29908           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   29909           0 :         if (std::abs(e[i__])>PLUMED_GMX_FLOAT_MIN) {
+   29910           0 :             ++(*info);
+   29911             :         }
+   29912             :     }
+   29913           0 :     goto L190;
+   29914             : 
+   29915             : L160:
+   29916           0 :     if (icompz == 0) {
+   29917             : 
+   29918           0 :         PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("I", n, &d__[1], info);
+   29919             : 
+   29920             :     } else {
+   29921             : 
+   29922           0 :         i__1 = *n;
+   29923           0 :         for (ii = 2; ii <= i__1; ++ii) {
+   29924           0 :             i__ = ii - 1;
+   29925             :             k = i__;
+   29926           0 :             p = d__[i__];
+   29927           0 :             i__2 = *n;
+   29928           0 :             for (j = ii; j <= i__2; ++j) {
+   29929           0 :                 if (d__[j] < p) {
+   29930             :                     k = j;
+   29931             :                     p = d__[j];
+   29932             :                 }
+   29933             :             }
+   29934           0 :             if (k != i__) {
+   29935           0 :                 d__[k] = d__[i__];
+   29936           0 :                 d__[i__] = p;
+   29937           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[k * z_dim1 + 1],
+   29938             :                          &c__1);
+   29939             :             }
+   29940             :         }
+   29941             :     }
+   29942             : 
+   29943           0 : L190:
+   29944             :     return;
+   29945             : }
+   29946             : 
+   29947             : 
+   29948             : }
+   29949             : }
+   29950             : #include <cmath>
+   29951             : #include "lapack.h"
+   29952             : #include "lapack_limits.h"
+   29953             : 
+   29954             : #include "real.h"
+   29955             : 
+   29956             : #include "blas/blas.h"
+   29957             : namespace PLMD{
+   29958             : namespace lapack{
+   29959             : using namespace blas;
+   29960             : void
+   29961           0 : PLUMED_BLAS_F77_FUNC(ssterf,SSTERF)(int *n, 
+   29962             :         float *d__, 
+   29963             :         float *e, 
+   29964             :         int *info)
+   29965             : {
+   29966             :     int i__1;
+   29967             :     float d__1;
+   29968             : 
+   29969             :     float c__;
+   29970             :     int i__, l, m;
+   29971             :     float p, r__, s;
+   29972             :     int l1;
+   29973             :     float bb, rt1, rt2, eps, rte;
+   29974             :     int lsv;
+   29975             :     float eps2, oldc;
+   29976             :     int lend, jtot;
+   29977             :     float gamma, alpha, sigma, anorm;
+   29978             :       int iscale;
+   29979             :     float oldgam;
+   29980             :     float safmax;
+   29981             :     int lendsv;
+   29982             :     float ssfmin;
+   29983             :     int nmaxit;
+   29984             :     float ssfmax;
+   29985           0 :     int c__0 = 0;
+   29986           0 :     int c__1 = 1;
+   29987           0 :     float c_b32 = 1.;
+   29988             :     const float safmin = PLUMED_GMX_FLOAT_MIN*(1.0+PLUMED_GMX_FLOAT_EPS);
+   29989             : 
+   29990           0 :     --e;
+   29991           0 :     --d__;
+   29992             : 
+   29993           0 :     *info = 0;
+   29994             : 
+   29995           0 :     if (*n < 0) {
+   29996           0 :         *info = -1;
+   29997             :         i__1 = -(*info);
+   29998           0 :         return;
+   29999             :     }
+   30000           0 :     if (*n <= 1) {
+   30001             :         return;
+   30002             :     }
+   30003             : 
+   30004             :     eps = PLUMED_GMX_FLOAT_EPS;
+   30005             :     d__1 = eps;
+   30006             :     eps2 = d__1 * d__1;
+   30007             :     safmax = 1. / safmin;
+   30008           0 :     ssfmax =  std::sqrt(safmax) / 3.;
+   30009           0 :     ssfmin =  std::sqrt(safmin) / eps2;
+   30010             : 
+   30011           0 :     nmaxit = *n * 30;
+   30012           0 :     sigma = 0.;
+   30013             :     jtot = 0;
+   30014             : 
+   30015             :     l1 = 1;
+   30016             : 
+   30017           0 : L10:
+   30018           0 :     if (l1 > *n) {
+   30019           0 :       PLUMED_BLAS_F77_FUNC(slasrt,SLASRT)("I", n, &d__[1], info);
+   30020           0 :       return;
+   30021             :     }
+   30022           0 :     if (l1 > 1) {
+   30023           0 :         e[l1 - 1] = 0.;
+   30024             :     }
+   30025           0 :     i__1 = *n - 1;
+   30026           0 :     for (m = l1; m <= i__1; ++m) {
+   30027           0 :         if (std::abs(e[m]) <=  std::sqrt(std::abs(d__[m])) * 
+   30028           0 :                  std::sqrt(std::abs(d__[m + 1])) * eps) {
+   30029           0 :             e[m] = 0.;
+   30030           0 :             goto L30;
+   30031             :         }
+   30032             :     }
+   30033           0 :     m = *n;
+   30034             : 
+   30035           0 : L30:
+   30036             :     l = l1;
+   30037             :     lsv = l;
+   30038             :     lend = m;
+   30039             :     lendsv = lend;
+   30040           0 :     l1 = m + 1;
+   30041           0 :     if (lend == l) {
+   30042           0 :         goto L10;
+   30043             :     }
+   30044             : 
+   30045           0 :     i__1 = lend - l + 1;
+   30046           0 :     anorm = PLUMED_BLAS_F77_FUNC(slanst,SLANST)("I", &i__1, &d__[l], &e[l]);
+   30047             :     iscale = 0;
+   30048           0 :     if (anorm > ssfmax) {
+   30049             :         iscale = 1;
+   30050           0 :         i__1 = lend - l + 1;
+   30051           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &d__[l], n, 
+   30052             :                 info);
+   30053           0 :         i__1 = lend - l;
+   30054           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmax, &i__1, &c__1, &e[l], n, 
+   30055             :                 info);
+   30056           0 :     } else if (anorm < ssfmin) {
+   30057             :         iscale = 2;
+   30058           0 :         i__1 = lend - l + 1;
+   30059           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &d__[l], n, 
+   30060             :                 info);
+   30061           0 :         i__1 = lend - l;
+   30062           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &anorm, &ssfmin, &i__1, &c__1, &e[l], n, 
+   30063             :                 info);
+   30064             :     }
+   30065             : 
+   30066           0 :     i__1 = lend - 1;
+   30067           0 :     for (i__ = l; i__ <= i__1; ++i__) {
+   30068           0 :         d__1 = e[i__];
+   30069           0 :         e[i__] = d__1 * d__1;
+   30070             :     }
+   30071             : 
+   30072           0 :     if (std::abs(d__[lend]) < std::abs(d__[l])) {
+   30073             :         lend = lsv;
+   30074             :         l = lendsv;
+   30075             :     }
+   30076             : 
+   30077           0 :     if (lend >= l) {
+   30078             : 
+   30079           0 : L50:
+   30080           0 :         if (l != lend) {
+   30081           0 :             i__1 = lend - 1;
+   30082           0 :             for (m = l; m <= i__1; ++m) {
+   30083           0 :                 if (std::abs(e[m]) <= eps2 * std::abs(d__[m] * d__[m + 1])) {
+   30084           0 :                     goto L70;
+   30085             :                 }
+   30086             :             }
+   30087             :         }
+   30088             :         m = lend;
+   30089             : 
+   30090           0 : L70:
+   30091           0 :         if (m < lend) {
+   30092           0 :             e[m] = 0.;
+   30093             :         }
+   30094           0 :         p = d__[l];
+   30095           0 :         if (m == l) {
+   30096           0 :             goto L90;
+   30097             :         }
+   30098           0 :         if (m == l + 1) {
+   30099           0 :             rte =  std::sqrt(e[l]);
+   30100           0 :             PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l], &rte, &d__[l + 1], &rt1, &rt2);
+   30101           0 :             d__[l] = rt1;
+   30102           0 :             d__[l + 1] = rt2;
+   30103           0 :             e[l] = 0.;
+   30104           0 :             l += 2;
+   30105           0 :             if (l <= lend) {
+   30106           0 :                 goto L50;
+   30107             :             }
+   30108           0 :             goto L150;
+   30109             :         }
+   30110             : 
+   30111           0 :         if (jtot == nmaxit) {
+   30112           0 :             goto L150;
+   30113             :         }
+   30114           0 :         ++jtot;
+   30115             : 
+   30116           0 :         rte =  std::sqrt(e[l]);
+   30117           0 :         sigma = (d__[l + 1] - p) / (rte * 2.);
+   30118           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&sigma, &c_b32);
+   30119           0 :         sigma = p - rte / (sigma + ( (sigma>0) ? r__ : -r__));
+   30120             : 
+   30121             :         c__ = 1.;
+   30122             :         s = 0.;
+   30123           0 :         gamma = d__[m] - sigma;
+   30124           0 :         p = gamma * gamma;
+   30125             : 
+   30126           0 :         i__1 = l;
+   30127           0 :         for (i__ = m - 1; i__ >= i__1; --i__) {
+   30128           0 :             bb = e[i__];
+   30129           0 :             r__ = p + bb;
+   30130           0 :             if (i__ != m - 1) {
+   30131           0 :                 e[i__ + 1] = s * r__;
+   30132             :             }
+   30133             :             oldc = c__;
+   30134           0 :             c__ = p / r__;
+   30135           0 :             s = bb / r__;
+   30136             :             oldgam = gamma;
+   30137           0 :             alpha = d__[i__];
+   30138           0 :             gamma = c__ * (alpha - sigma) - s * oldgam;
+   30139           0 :             d__[i__ + 1] = oldgam + (alpha - gamma);
+   30140           0 :             if (std::abs(c__)>PLUMED_GMX_FLOAT_MIN) {
+   30141           0 :                 p = gamma * gamma / c__;
+   30142             :             } else {
+   30143           0 :                 p = oldc * bb;
+   30144             :             }
+   30145             :         }
+   30146             : 
+   30147           0 :         e[l] = s * p;
+   30148           0 :         d__[l] = sigma + gamma;
+   30149           0 :         goto L50;
+   30150             : 
+   30151             : L90:
+   30152             :         d__[l] = p;
+   30153             : 
+   30154           0 :         ++l;
+   30155           0 :         if (l <= lend) {
+   30156           0 :             goto L50;
+   30157             :         }
+   30158           0 :         goto L150;
+   30159             : 
+   30160             :     } else {
+   30161             : 
+   30162           0 : L100:
+   30163           0 :         i__1 = lend + 1;
+   30164           0 :         for (m = l; m >= i__1; --m) {
+   30165           0 :             if (std::abs(e[m - 1]) <= eps2 * std::abs(d__[m] * d__[m - 1])) {
+   30166           0 :                 goto L120;
+   30167             :             }
+   30168             :         }
+   30169             :         m = lend;
+   30170             : 
+   30171           0 : L120:
+   30172           0 :         if (m > lend) {
+   30173           0 :             e[m - 1] = 0.;
+   30174             :         }
+   30175           0 :         p = d__[l];
+   30176           0 :         if (m == l) {
+   30177           0 :             goto L140;
+   30178             :         }
+   30179             : 
+   30180           0 :         if (m == l - 1) {
+   30181           0 :             rte =  std::sqrt(e[l - 1]);
+   30182           0 :             PLUMED_BLAS_F77_FUNC(slae2,SLAE2)(&d__[l], &rte, &d__[l - 1], &rt1, &rt2);
+   30183           0 :             d__[l] = rt1;
+   30184           0 :             d__[l - 1] = rt2;
+   30185           0 :             e[l - 1] = 0.;
+   30186           0 :             l += -2;
+   30187           0 :             if (l >= lend) {
+   30188           0 :                 goto L100;
+   30189             :             }
+   30190           0 :             goto L150;
+   30191             :         }
+   30192             : 
+   30193           0 :         if (jtot == nmaxit) {
+   30194           0 :             goto L150;
+   30195             :         }
+   30196           0 :         ++jtot;
+   30197             : 
+   30198           0 :         rte =  std::sqrt(e[l - 1]);
+   30199           0 :         sigma = (d__[l - 1] - p) / (rte * 2.);
+   30200           0 :         r__ = PLUMED_BLAS_F77_FUNC(slapy2,SLAPY2)(&sigma, &c_b32);
+   30201           0 :         sigma = p - rte / (sigma + ( (sigma>0) ? r__ : -r__));
+   30202             : 
+   30203             :         c__ = 1.;
+   30204             :         s = 0.;
+   30205           0 :         gamma = d__[m] - sigma;
+   30206           0 :         p = gamma * gamma;
+   30207             : 
+   30208           0 :         i__1 = l - 1;
+   30209           0 :         for (i__ = m; i__ <= i__1; ++i__) {
+   30210           0 :             bb = e[i__];
+   30211           0 :             r__ = p + bb;
+   30212           0 :             if (i__ != m) {
+   30213           0 :                 e[i__ - 1] = s * r__;
+   30214             :             }
+   30215             :             oldc = c__;
+   30216           0 :             c__ = p / r__;
+   30217           0 :             s = bb / r__;
+   30218             :             oldgam = gamma;
+   30219           0 :             alpha = d__[i__ + 1];
+   30220           0 :             gamma = c__ * (alpha - sigma) - s * oldgam;
+   30221           0 :             d__[i__] = oldgam + (alpha - gamma);
+   30222           0 :             if (std::abs(c__)>PLUMED_GMX_FLOAT_MIN) {
+   30223           0 :                 p = gamma * gamma / c__;
+   30224             :             } else {
+   30225           0 :                 p = oldc * bb;
+   30226             :             }
+   30227             :         }
+   30228             : 
+   30229           0 :         e[l - 1] = s * p;
+   30230           0 :         d__[l] = sigma + gamma;
+   30231           0 :         goto L100;
+   30232             : 
+   30233             : L140:
+   30234             :         d__[l] = p;
+   30235             : 
+   30236           0 :         --l;
+   30237           0 :         if (l >= lend) {
+   30238           0 :             goto L100;
+   30239             :         }
+   30240           0 :         goto L150;
+   30241             : 
+   30242             :     }
+   30243             : 
+   30244           0 : L150:
+   30245           0 :     if (iscale == 1) {
+   30246           0 :         i__1 = lendsv - lsv + 1;
+   30247           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmax, &anorm, &i__1, &c__1, &d__[lsv], 
+   30248             :                 n, info);
+   30249             :     }
+   30250           0 :     if (iscale == 2) {
+   30251           0 :         i__1 = lendsv - lsv + 1;
+   30252           0 :         PLUMED_BLAS_F77_FUNC(slascl,SLASCL)("G", &c__0, &c__0, &ssfmin, &anorm, &i__1, &c__1, &d__[lsv], 
+   30253             :                 n, info);
+   30254             :     }
+   30255             : 
+   30256           0 :     if (jtot < nmaxit) {
+   30257           0 :         goto L10;
+   30258             :     }
+   30259           0 :     i__1 = *n - 1;
+   30260           0 :     for (i__ = 1; i__ <= i__1; ++i__) {
+   30261           0 :         if (std::abs(e[i__])>PLUMED_GMX_FLOAT_MIN) {
+   30262           0 :             ++(*info);
+   30263             :         }
+   30264             :     }
+   30265             :     return;
+   30266             : }
+   30267             : 
+   30268             : 
+   30269             : }
+   30270             : }
+   30271             : #include "lapack.h"
+   30272             : 
+   30273             : 
+   30274             : /* Normally, SSTEVR is the LAPACK wrapper which calls one
+   30275             :  * of the eigenvalue methods. However, our code includes a
+   30276             :  * version of SSTEGR which is never than LAPACK 3.0 and can
+   30277             :  * handle requests for a subset of eigenvalues/vectors too,
+   30278             :  * and it should not need to call SSTEIN.
+   30279             :  * Just in case somebody has a faster version in their lapack
+   30280             :  * library we still call the driver routine, but in our own
+   30281             :  * case this is just a wrapper to sstegr.
+   30282             :  */
+   30283             : #include "blas/blas.h"
+   30284             : namespace PLMD{
+   30285             : namespace lapack{
+   30286             : using namespace blas;
+   30287             : void
+   30288           0 : PLUMED_BLAS_F77_FUNC(sstevr,SSTEVR)(const char *jobz, 
+   30289             :                         const char *range,
+   30290             :                         int *n,
+   30291             :                         float *d,
+   30292             :                         float *e,
+   30293             :                         float *vl, 
+   30294             :                         float *vu,
+   30295             :                         int *il, 
+   30296             :                         int *iu, 
+   30297             :                         float *abstol,
+   30298             :                         int *m,
+   30299             :                         float *w, 
+   30300             :                         float *z,
+   30301             :                         int *ldz,
+   30302             :                         int *isuppz, 
+   30303             :                         float *work, 
+   30304             :                         int *lwork, 
+   30305             :                         int *iwork,
+   30306             :                         int *liwork, 
+   30307             :                         int *info)
+   30308             : {
+   30309           0 :   PLUMED_BLAS_F77_FUNC(sstegr,SSTEGR)(jobz, range, n, d, e, vl, vu, il, iu, abstol, m, w,
+   30310             :           z, ldz, isuppz, work, lwork, iwork, liwork, info);
+   30311             :   
+   30312             : 
+   30313           0 :     return;
+   30314             : 
+   30315             : }
+   30316             : 
+   30317             : 
+   30318             : }
+   30319             : }
+   30320             : #include <cmath>
+   30321             : 
+   30322             : #include "real.h"
+   30323             : 
+   30324             : #include "blas/blas.h"
+   30325             : #include "lapack.h"
+   30326             : #include "lapack_limits.h"
+   30327             : 
+   30328             : #include "blas/blas.h"
+   30329             : namespace PLMD{
+   30330             : namespace lapack{
+   30331             : using namespace blas;
+   30332             : void
+   30333           0 : PLUMED_BLAS_F77_FUNC(ssyevr,SSYEVR)(const char *jobz, const char *range, const char *uplo, int *n, 
+   30334             :         float *a, int *lda, float *vl, float *vu, int *
+   30335             :         il, int *iu, float *abstol, int *m, float *w, 
+   30336             :         float *z__, int *ldz, int *isuppz, float *work, 
+   30337             :         int *lwork, int *iwork, int *liwork, int *info)
+   30338             : {
+   30339             :     /* System generated locals */
+   30340             :     int a_dim1, a_offset, z_dim1, z_offset, i__1, i__2;
+   30341             :     float d__1, d__2;
+   30342             : 
+   30343             :     /* Local variables */
+   30344           0 :     int c__1 = 1;
+   30345             :     int i__, j, nb, jj;
+   30346             :     float eps, tmp1;
+   30347             :     int indd, inde;
+   30348             :     float anrm;
+   30349             :     int imax;
+   30350             :     float rmin, rmax;
+   30351             :     int itmp1, inddd, indee;
+   30352             :     float sigma;
+   30353             :     int iinfo;
+   30354             :     int indwk;
+   30355             :     int lwmin;
+   30356             :     int lower, wantz;
+   30357             :     int alleig, indeig;
+   30358             :     int iscale, indibl, indifl;
+   30359             :     int valeig;
+   30360             :     float safmin,minval;
+   30361             :     float bignum;
+   30362             :     int indtau;
+   30363             :     int indwkn;
+   30364             :     int liwmin;
+   30365             :     int llwrkn, llwork;
+   30366             :     float smlnum;
+   30367             :     int lwkopt;
+   30368             :     int lquery;
+   30369             :     
+   30370             :     /* Parameter adjustments */
+   30371           0 :     a_dim1 = *lda;
+   30372           0 :     a_offset = 1 + a_dim1;
+   30373           0 :     a -= a_offset;
+   30374           0 :     --w;
+   30375           0 :     z_dim1 = *ldz;
+   30376           0 :     z_offset = 1 + z_dim1;
+   30377           0 :     z__ -= z_offset;
+   30378             :     --isuppz;
+   30379           0 :     --work;
+   30380           0 :     --iwork;
+   30381             : 
+   30382           0 :     lower = (*uplo=='L' || *uplo=='l');
+   30383           0 :     wantz = (*jobz=='V' || *jobz=='v');
+   30384           0 :     alleig = (*range=='A' || *range=='a');
+   30385           0 :     valeig = (*range=='V' || *range=='v');
+   30386           0 :     indeig = (*range=='I' || *range=='i');
+   30387             : 
+   30388             :     indibl = 0;
+   30389           0 :     lquery = *lwork == -1 || *liwork == -1;
+   30390             : 
+   30391             :     i__1 = 1;
+   30392           0 :     i__2 = *n * 26;
+   30393             : 
+   30394           0 :     if(*n>0) 
+   30395             :       lwmin = *n * 26;
+   30396             :     else
+   30397             :       lwmin = 1;
+   30398             : 
+   30399           0 :     if(*n>0) 
+   30400           0 :       liwmin = *n * 10;
+   30401             :     else
+   30402             :       liwmin = 1;
+   30403             : 
+   30404           0 :     *info = 0;
+   30405           0 :     if (! (wantz || (*jobz=='N' || *jobz=='n'))) {
+   30406           0 :         *info = -1;
+   30407           0 :     } else if (! (alleig || valeig || indeig)) {
+   30408           0 :         *info = -2;
+   30409           0 :     } else if (! (lower || (*uplo=='U' || *uplo=='u'))) {
+   30410           0 :         *info = -3;
+   30411           0 :     } else if (*n < 0) {
+   30412           0 :         *info = -4;
+   30413           0 :     } else if (*lda < ((*n>1) ? *n : 1) ) {
+   30414           0 :         *info = -6;
+   30415             :     } else {
+   30416           0 :         if (valeig) {
+   30417           0 :             if (*n > 0 && *vu <= *vl) {
+   30418           0 :                 *info = -8;
+   30419             :             }
+   30420           0 :         } else if (indeig) {
+   30421           0 :           if (*il < 1 || *il > ((*n>1) ? *n : 1)) {
+   30422           0 :                 *info = -9;
+   30423           0 :             } else if (*iu < ((*n<*il) ? *n : *il) || *iu > *n) {
+   30424           0 :                 *info = -10;
+   30425             :             }
+   30426             :         }
+   30427             :     }
+   30428           0 :     if (*info == 0) {
+   30429           0 :       if (*ldz < 1 || (wantz && *ldz < *n)) {
+   30430           0 :             *info = -15;
+   30431           0 :         } else if (*lwork < lwmin && ! lquery) {
+   30432           0 :             *info = -18;
+   30433           0 :         } else if (*liwork < liwmin && ! lquery) {
+   30434           0 :             *info = -20;
+   30435             :         }
+   30436             :     }
+   30437             : 
+   30438           0 :     if (*info == 0) {
+   30439             :       nb = 32;
+   30440             :       /* Computing MAX */
+   30441           0 :       i__1 = (nb + 1) * *n;
+   30442             :       lwkopt = (i__1>lwmin) ? i__1 : lwmin;
+   30443           0 :       work[1] = (float) lwkopt;
+   30444           0 :       iwork[1] = liwmin;
+   30445             :     } else 
+   30446             :       return;
+   30447             : 
+   30448           0 :     if (lquery) 
+   30449             :         return;
+   30450             :     
+   30451           0 :     *m = 0;
+   30452           0 :     if (*n == 0) {
+   30453           0 :         work[1] = 1.;
+   30454           0 :         return;
+   30455             :     }
+   30456             : 
+   30457           0 :     if (*n == 1) {
+   30458           0 :         work[1] = 7.;
+   30459           0 :         if (alleig || indeig) {
+   30460           0 :             *m = 1;
+   30461           0 :             w[1] = a[a_dim1 + 1];
+   30462             :         } else {
+   30463           0 :             if (*vl < a[a_dim1 + 1] && *vu >= a[a_dim1 + 1]) {
+   30464           0 :                 *m = 1;
+   30465           0 :                 w[1] = a[a_dim1 + 1];
+   30466             :             }
+   30467             :         }
+   30468           0 :         if (wantz) {
+   30469           0 :             z__[z_dim1 + 1] = 1.;
+   30470             :         }
+   30471           0 :         return;
+   30472             :     }
+   30473             :     minval = PLUMED_GMX_FLOAT_MIN;
+   30474             :     safmin = minval*(1.0+PLUMED_GMX_FLOAT_EPS);
+   30475             :     eps = PLUMED_GMX_FLOAT_EPS;
+   30476             : 
+   30477             :     smlnum = safmin / eps;
+   30478             :     bignum = 1. / smlnum;
+   30479             :     rmin =  std::sqrt(smlnum);
+   30480             : 
+   30481           0 :     d__1 =  std::sqrt(bignum), d__2 = 1. / std::sqrt(sqrt(safmin));
+   30482             :     rmax = (d__1<d__2) ? d__1 : d__2;
+   30483             : 
+   30484             :     iscale = 0;
+   30485           0 :     anrm = PLUMED_BLAS_F77_FUNC(slansy,SLANSY)("M", uplo, n, &a[a_offset], lda, &work[1]);
+   30486           0 :     if (anrm > 0. && anrm < rmin) {
+   30487             :         iscale = 1;
+   30488           0 :         sigma = rmin / anrm;
+   30489           0 :     } else if (anrm > rmax) {
+   30490             :         iscale = 1;
+   30491           0 :         sigma = rmax / anrm; 
+   30492             :     }
+   30493             :     if (iscale == 1) {
+   30494           0 :         if (lower) {
+   30495           0 :             i__1 = *n;
+   30496           0 :             for (j = 1; j <= i__1; ++j) {
+   30497           0 :                 i__2 = *n - j + 1;
+   30498           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &sigma, &a[j + j * a_dim1], &c__1);
+   30499             :             }
+   30500             :         } else {
+   30501           0 :             i__1 = *n;
+   30502           0 :             for (j = 1; j <= i__1; ++j) {
+   30503           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&j, &sigma, &a[j * a_dim1 + 1], &c__1);
+   30504             : 
+   30505             :             }
+   30506             :         }
+   30507             :     }
+   30508             : 
+   30509             :     indtau = 1;
+   30510           0 :     inde = indtau + *n;
+   30511           0 :     indd = inde + *n;
+   30512           0 :     indee = indd + *n;
+   30513           0 :     inddd = indee + *n;
+   30514           0 :     indifl = inddd + *n;
+   30515           0 :     indwk = indifl + *n;
+   30516           0 :     llwork = *lwork - indwk + 1;
+   30517           0 :     PLUMED_BLAS_F77_FUNC(ssytrd,SSYTRD)(uplo, n, &a[a_offset], lda, &work[indd], &work[inde], &work[
+   30518           0 :             indtau], &work[indwk], &llwork, &iinfo);
+   30519             : 
+   30520           0 :     i__1 = *n - 1;
+   30521           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(&i__1, &work[inde], &c__1, &work[indee], &c__1);
+   30522           0 :     PLUMED_BLAS_F77_FUNC(scopy,SCOPY)(n, &work[indd], &c__1, &work[inddd], &c__1);
+   30523             : 
+   30524           0 :     PLUMED_BLAS_F77_FUNC(sstegr,SSTEGR)(jobz, range, n, &work[inddd], &work[indee], vl, vu, il, iu, 
+   30525             :             abstol, m, &w[1], &z__[z_offset], ldz, &isuppz[1], 
+   30526             :             &work[indwk], lwork, &iwork[1], liwork, info);
+   30527           0 :     if (wantz && *info == 0) {
+   30528             :       indwkn = inde;
+   30529           0 :       llwrkn = *lwork - indwkn + 1;
+   30530           0 :       PLUMED_BLAS_F77_FUNC(sormtr,SORMTR)("L", uplo, "N", n, m, &a[a_offset], lda, &work[indtau]
+   30531             :               , &z__[z_offset], ldz, &work[indwkn], &llwrkn, &iinfo);
+   30532             :     }
+   30533             : 
+   30534           0 :     if (*info != 0) 
+   30535             :       return;
+   30536             : 
+   30537           0 :     if (iscale == 1) {
+   30538             :         if (*info == 0) {
+   30539           0 :             imax = *m;
+   30540             :         } else {
+   30541             :             imax = *info - 1;
+   30542             :         }
+   30543           0 :         d__1 = 1. / sigma;
+   30544           0 :         PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&imax, &d__1, &w[1], &c__1);
+   30545             :     }
+   30546             : 
+   30547           0 :     if (wantz) {
+   30548           0 :         i__1 = *m - 1;
+   30549             :         
+   30550           0 :         for (j = 1; j <= i__1; ++j) {
+   30551             :             i__ = 0;
+   30552           0 :             tmp1 = w[j];
+   30553           0 :             i__2 = *m;
+   30554           0 :             for (jj = j + 1; jj <= i__2; ++jj) {
+   30555           0 :                 if (w[jj] < tmp1) {
+   30556             :                     i__ = jj;
+   30557             :                     tmp1 = w[jj];
+   30558             :                 }
+   30559             :             }
+   30560             : 
+   30561           0 :             if (i__ != 0) {
+   30562           0 :                 itmp1 = iwork[indibl + i__ - 1];
+   30563           0 :                 w[i__] = w[j];
+   30564           0 :                 iwork[indibl + i__ - 1] = iwork[indibl + j - 1];
+   30565           0 :                 w[j] = tmp1;
+   30566           0 :                 iwork[indibl + j - 1] = itmp1;
+   30567           0 :                 PLUMED_BLAS_F77_FUNC(sswap,SSWAP)(n, &z__[i__ * z_dim1 + 1], &c__1, &z__[j * z_dim1 + 1],
+   30568             :                          &c__1);
+   30569             :             }
+   30570             :         }
+   30571             :     }
+   30572             : 
+   30573           0 :     work[1] = (float) lwkopt;
+   30574           0 :     iwork[1] = liwmin;
+   30575           0 :     return;
+   30576             : 
+   30577             : }
+   30578             : }
+   30579             : }
+   30580             : #include <cctype>
+   30581             : #include <cmath>
+   30582             : 
+   30583             : #include "real.h"
+   30584             : 
+   30585             : #include "blas/blas.h"
+   30586             : #include "lapack.h"
+   30587             : 
+   30588             : #include "blas/blas.h"
+   30589             : namespace PLMD{
+   30590             : namespace lapack{
+   30591             : using namespace blas;
+   30592             : void
+   30593           0 : PLUMED_BLAS_F77_FUNC(ssytd2,SSYTD2)(const char *    uplo,
+   30594             :         int *     n,
+   30595             :         float *  a,
+   30596             :         int *     lda,
+   30597             :         float *  d,
+   30598             :         float *  e,
+   30599             :         float *  tau,
+   30600             :     int *     info)
+   30601             : {
+   30602             :   float minusone,zero;
+   30603             :   float taui,alpha,tmp;
+   30604             :   int ti1,ti2,ti3,i;
+   30605           0 :   const char ch=std::toupper(*uplo);
+   30606             : 
+   30607           0 :   zero = 0.0;
+   30608           0 :   minusone = -1.0;
+   30609             : 
+   30610           0 :   if(*n<=0)
+   30611             :     return;
+   30612             : 
+   30613           0 :   if(ch=='U') {
+   30614           0 :     for(i=*n-1;i>=1;i--) {
+   30615             : 
+   30616           0 :       ti1 = 1;
+   30617           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&i,&(a[i*(*lda)+(i-1)]),&(a[i*(*lda)+0]),&ti1,&taui);
+   30618           0 :       e[i-1] = a[i*(*lda) + (i-1)];
+   30619           0 :       if(std::abs(taui)>PLUMED_GMX_FLOAT_MIN) {
+   30620           0 :         a[i*(*lda)+(i-1)] = 1.0;
+   30621             :       
+   30622           0 :         ti1 = 1;
+   30623           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)("U",&i,&taui,a,lda,&(a[i*(*lda)+0]),&ti1,&zero,tau,&ti1);
+   30624             : 
+   30625           0 :         tmp = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&i,tau,&ti1,&(a[i*(*lda)+0]),&ti1);
+   30626             : 
+   30627           0 :         alpha = -0.5*taui*tmp;
+   30628             : 
+   30629           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&i,&alpha,&(a[i*(*lda)+0]),&ti1,tau,&ti1);
+   30630             : 
+   30631           0 :         PLUMED_BLAS_F77_FUNC(ssyr2,SSYR2)("U",&i,&minusone,&(a[i*(*lda)+0]),&ti1,tau,&ti1,a,lda);
+   30632             : 
+   30633           0 :         a[i*(*lda)+(i-1)] = e[i-1]; 
+   30634             : 
+   30635             :       }
+   30636           0 :       d[i] = a[i*(*lda)+i];
+   30637           0 :       tau[i-1] = taui;
+   30638             :     }
+   30639           0 :     d[0] = a[0];
+   30640             :     
+   30641             :   } else {
+   30642             :     /* lower */
+   30643             : 
+   30644           0 :     for(i=1;i<*n;i++) {
+   30645             : 
+   30646           0 :       ti1 = *n - i;
+   30647           0 :       ti2 = ( *n < i+2) ? *n : i+2;
+   30648           0 :       ti3 = 1;
+   30649           0 :       PLUMED_BLAS_F77_FUNC(slarfg,SLARFG)(&ti1,&(a[(i-1)*(*lda)+(i)]),&(a[(i-1)*(*lda)+ti2-1]),&ti3,&taui);
+   30650             : 
+   30651           0 :       e[i-1] = a[(i-1)*(*lda) + (i)];
+   30652             : 
+   30653           0 :       if(std::abs(taui)>PLUMED_GMX_FLOAT_MIN) {
+   30654           0 :         a[(i-1)*(*lda)+(i)] = 1.0;
+   30655             :       
+   30656           0 :         ti1 = *n - i;
+   30657           0 :         ti2 = 1;
+   30658           0 :         PLUMED_BLAS_F77_FUNC(ssymv,SSYMV)(uplo,&ti1,&taui,&(a[i*(*lda)+i]),lda,&(a[(i-1)*(*lda)+i]),
+   30659             :                &ti2,&zero,&(tau[i-1]),&ti2);
+   30660             :         
+   30661           0 :         tmp = PLUMED_BLAS_F77_FUNC(sdot,SDOT)(&ti1,&(tau[i-1]),&ti2,&(a[(i-1)*(*lda)+i]),&ti2);
+   30662             : 
+   30663           0 :         alpha = -0.5*taui*tmp;
+   30664             : 
+   30665           0 :         PLUMED_BLAS_F77_FUNC(saxpy,SAXPY)(&ti1,&alpha,&(a[(i-1)*(*lda)+i]),&ti2,&(tau[i-1]),&ti2);
+   30666             : 
+   30667           0 :         PLUMED_BLAS_F77_FUNC(ssyr2,SSYR2)(uplo,&ti1,&minusone,&(a[(i-1)*(*lda)+i]),&ti2,&(tau[i-1]),&ti2,
+   30668           0 :                &(a[(i)*(*lda)+i]),lda);
+   30669             : 
+   30670           0 :         a[(i-1)*(*lda)+(i)] = e[i-1]; 
+   30671             : 
+   30672             :       }
+   30673           0 :       d[i-1] = a[(i-1)*(*lda)+i-1];
+   30674           0 :       tau[i-1] = taui;
+   30675             :     }
+   30676           0 :     d[*n-1] = a[(*n-1)*(*lda)+(*n-1)];
+   30677             :  
+   30678             :   }
+   30679             :   return;
+   30680             : }
+   30681             : }
+   30682             : }
+   30683             : #include "blas/blas.h"
+   30684             : #include "lapack.h"
+   30685             : #include "lapack_limits.h"
+   30686             : 
+   30687             : #include "blas/blas.h"
+   30688             : namespace PLMD{
+   30689             : namespace lapack{
+   30690             : using namespace blas;
+   30691             : void
+   30692           0 : PLUMED_BLAS_F77_FUNC(ssytrd,SSYTRD)(const char *uplo, int *n, float *a, int *
+   30693             :         lda, float *d__, float *e, float *tau, float *
+   30694             :         work, int *lwork, int *info)
+   30695             : {
+   30696             :     /* System generated locals */
+   30697             :     int a_dim1, a_offset, i__1, i__2, i__3;
+   30698             : 
+   30699             :     /* Local variables */
+   30700             :     int i__, j, nb, kk, nx, iws;
+   30701             :     int nbmin, iinfo;
+   30702             :     int upper;
+   30703             :     int ldwork, lwkopt;
+   30704             :     int lquery;
+   30705           0 :     float c_b22 = -1.;
+   30706           0 :     float c_b23 = 1.;
+   30707             : 
+   30708             : 
+   30709             :     /* Parameter adjustments */
+   30710           0 :     a_dim1 = *lda;
+   30711           0 :     a_offset = 1 + a_dim1;
+   30712           0 :     a -= a_offset;
+   30713           0 :     --d__;
+   30714           0 :     --e;
+   30715           0 :     --tau;
+   30716             :     --work;
+   30717             : 
+   30718             :     /* Function Body */
+   30719           0 :     *info = 0;
+   30720           0 :     upper = (*uplo=='U' || *uplo=='u');
+   30721           0 :     lquery = (*lwork == -1);
+   30722             : 
+   30723           0 :     if (! upper && ! (*uplo=='L' || *uplo=='l')) {
+   30724           0 :         *info = -1;
+   30725           0 :     } else if (*n < 0) {
+   30726           0 :         *info = -2;
+   30727           0 :     } else if (*lda < ((1>*n) ? 1 : *n)) {
+   30728           0 :         *info = -4;
+   30729           0 :     } else if (*lwork < 1 && ! lquery) {
+   30730           0 :         *info = -9;
+   30731             :     }
+   30732             : 
+   30733           0 :     if (*info == 0) {
+   30734             : 
+   30735           0 :       nb = DSYTRD_BLOCKSIZE;
+   30736           0 :       lwkopt = *n * nb;
+   30737           0 :       work[1] = (float) lwkopt;
+   30738             :     } else
+   30739             :       return;
+   30740             : 
+   30741           0 :     if (lquery) 
+   30742             :       return;
+   30743             :   
+   30744           0 :     if (*n == 0) {
+   30745           0 :         work[1] = 1.;
+   30746           0 :         return;
+   30747             :     }
+   30748             : 
+   30749             :     nx = *n;
+   30750           0 :     if (nb > 1 && nb < *n) {
+   30751             : 
+   30752             :         nx = DSYTRD_CROSSOVER;
+   30753           0 :         if (nx < *n) {
+   30754             : 
+   30755           0 :             ldwork = *n;
+   30756           0 :             iws = ldwork * nb;
+   30757           0 :             if (*lwork < iws) {
+   30758             : 
+   30759           0 :                 i__1 = *lwork / ldwork;
+   30760           0 :                 nb = (i__1>1) ? i__1 : 1;
+   30761             :                 nbmin = DSYTRD_MINBLOCKSIZE;
+   30762           0 :                 if (nb < nbmin) {
+   30763             :                     nx = *n;
+   30764             :                 }
+   30765             :             }
+   30766             :         } else {
+   30767             :             nx = *n;
+   30768             :         }
+   30769             :     } else {
+   30770           0 :         nb = 1;
+   30771             :     }
+   30772             : 
+   30773           0 :     if (upper) {
+   30774             : 
+   30775           0 :         kk = *n - (*n - nx + nb - 1) / nb * nb;
+   30776           0 :         i__1 = kk + 1;
+   30777             :         i__2 = -nb;
+   30778           0 :         for (i__ = *n - nb + 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += 
+   30779             :                 i__2) {
+   30780             : 
+   30781           0 :             i__3 = i__ + nb - 1;
+   30782           0 :             PLUMED_BLAS_F77_FUNC(slatrd,SLATRD)(uplo, &i__3, &nb, &a[a_offset], lda, &e[1], &tau[1], &
+   30783             :                     work[1], &ldwork);
+   30784             : 
+   30785           0 :             i__3 = i__ - 1;
+   30786           0 :             PLUMED_BLAS_F77_FUNC(ssyr2k,SSYR2K)(uplo, "No transpose", &i__3, &nb, &c_b22, &a[i__ * a_dim1 
+   30787           0 :                     + 1], lda, &work[1], &ldwork, &c_b23, &a[a_offset], lda);
+   30788             : 
+   30789           0 :             i__3 = i__ + nb - 1;
+   30790           0 :             for (j = i__; j <= i__3; ++j) {
+   30791           0 :                 a[j - 1 + j * a_dim1] = e[j - 1];
+   30792           0 :                 d__[j] = a[j + j * a_dim1];
+   30793             : 
+   30794             :             }
+   30795             : 
+   30796             :         }
+   30797             : 
+   30798           0 :         PLUMED_BLAS_F77_FUNC(ssytd2,SSYTD2)(uplo, &kk, &a[a_offset], lda, &d__[1], &e[1], &tau[1], &iinfo);
+   30799             :     } else {
+   30800             : 
+   30801           0 :         i__2 = *n - nx;
+   30802           0 :         i__1 = nb;
+   30803           0 :         for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ += i__1) {
+   30804             : 
+   30805             : 
+   30806           0 :             i__3 = *n - i__ + 1;
+   30807           0 :             PLUMED_BLAS_F77_FUNC(slatrd,SLATRD)(uplo, &i__3, &nb, &a[i__ + i__ * a_dim1], lda, &e[i__], &
+   30808           0 :                     tau[i__], &work[1], &ldwork);
+   30809             : 
+   30810           0 :             i__3 = *n - i__ - nb + 1;
+   30811           0 :             PLUMED_BLAS_F77_FUNC(ssyr2k,SSYR2K)(uplo, "No transpose", &i__3, &nb, &c_b22, &a[i__ + nb + 
+   30812           0 :                     i__ * a_dim1], lda, &work[nb + 1], &ldwork, &c_b23, &a[
+   30813           0 :                     i__ + nb + (i__ + nb) * a_dim1], lda);
+   30814             : 
+   30815             : 
+   30816           0 :             i__3 = i__ + nb - 1;
+   30817           0 :             for (j = i__; j <= i__3; ++j) {
+   30818           0 :                 a[j + 1 + j * a_dim1] = e[j];
+   30819           0 :                 d__[j] = a[j + j * a_dim1];
+   30820             : 
+   30821             :             }
+   30822             : 
+   30823             :         }
+   30824             : 
+   30825             : 
+   30826           0 :         i__1 = *n - i__ + 1;
+   30827           0 :         PLUMED_BLAS_F77_FUNC(ssytd2,SSYTD2)(uplo, &i__1, &a[i__ + i__ * a_dim1], lda, &d__[i__], &e[i__], 
+   30828           0 :                 &tau[i__], &iinfo);
+   30829             :     }
+   30830             : 
+   30831           0 :     work[1] = (float) lwkopt;
+   30832           0 :     return;
+   30833             : 
+   30834             : }
+   30835             : 
+   30836             : 
+   30837             : }
+   30838             : }
+   30839             : #include "blas/blas.h"
+   30840             : #include "lapack.h"
+   30841             : #include "lapack_limits.h"
+   30842             : 
+   30843             : #include "blas/blas.h"
+   30844             : namespace PLMD{
+   30845             : namespace lapack{
+   30846             : using namespace blas;
+   30847             : void
+   30848           0 : PLUMED_BLAS_F77_FUNC(strti2,STRTI2)(const char *uplo,
+   30849             :         const char *diag, 
+   30850             :         int *n, 
+   30851             :         float *a,
+   30852             :         int *lda,
+   30853             :         int *info)
+   30854             : {
+   30855             :     int a_dim1, a_offset, i__1, i__2;
+   30856             : 
+   30857             :     int j;
+   30858             :     float ajj;
+   30859             :     int upper, nounit;
+   30860           0 :     int c__1 = 1;
+   30861             : 
+   30862             : 
+   30863           0 :     a_dim1 = *lda;
+   30864           0 :     a_offset = 1 + a_dim1;
+   30865           0 :     a -= a_offset;
+   30866             : 
+   30867           0 :     *info = 0;
+   30868           0 :     upper = (*uplo=='U' || *uplo=='u');
+   30869           0 :     nounit = (*diag=='N' || *diag=='n');
+   30870             : 
+   30871             :     if (*info != 0) {
+   30872             :         i__1 = -(*info);
+   30873             :         return;
+   30874             :     }
+   30875             : 
+   30876           0 :     if (upper) {
+   30877             : 
+   30878           0 :         i__1 = *n;
+   30879           0 :         for (j = 1; j <= i__1; ++j) {
+   30880           0 :             if (nounit) {
+   30881           0 :                 a[j + j * a_dim1] = 1. / a[j + j * a_dim1];
+   30882           0 :                 ajj = -a[j + j * a_dim1];
+   30883             :             } else {
+   30884           0 :                 ajj = -1.;
+   30885             :             }
+   30886             : 
+   30887           0 :             i__2 = j - 1;
+   30888           0 :             PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Upper", "No transpose", diag, &i__2, &a[a_offset], lda, &
+   30889           0 :                     a[j * a_dim1 + 1], &c__1);
+   30890           0 :             i__2 = j - 1;
+   30891           0 :             PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__2, &ajj, &a[j * a_dim1 + 1], &c__1);
+   30892             :         }
+   30893             :     } else {
+   30894             : 
+   30895           0 :         for (j = *n; j >= 1; --j) {
+   30896           0 :             if (nounit) {
+   30897           0 :                 a[j + j * a_dim1] = 1. / a[j + j * a_dim1];
+   30898           0 :                 ajj = -a[j + j * a_dim1];
+   30899             :             } else {
+   30900           0 :                 ajj = -1.;
+   30901             :             }
+   30902           0 :             if (j < *n) {
+   30903             : 
+   30904           0 :                 i__1 = *n - j;
+   30905           0 :                 PLUMED_BLAS_F77_FUNC(strmv,STRMV)("Lower", "No transpose", diag, &i__1, &a[j + 1 + (j + 
+   30906           0 :                         1) * a_dim1], lda, &a[j + 1 + j * a_dim1], &c__1);
+   30907           0 :                 i__1 = *n - j;
+   30908           0 :                 PLUMED_BLAS_F77_FUNC(sscal,SSCAL)(&i__1, &ajj, &a[j + 1 + j * a_dim1], &c__1);
+   30909             :             }
+   30910             :         }
+   30911             :     }
+   30912             :     return;
+   30913             : }
+   30914             : }
+   30915             : }
+   30916             : #include <cmath>
+   30917             : #include "blas/blas.h"
+   30918             : #include "lapack.h"
+   30919             : #include "lapack_limits.h"
+   30920             : 
+   30921             : #include "real.h"
+   30922             : 
+   30923             : #include "blas/blas.h"
+   30924             : namespace PLMD{
+   30925             : namespace lapack{
+   30926             : using namespace blas;
+   30927             : void
+   30928           0 : PLUMED_BLAS_F77_FUNC(strtri,STRTRI)(const char *uplo,
+   30929             :         const char *diag, 
+   30930             :         int *n,
+   30931             :         float *a, 
+   30932             :         int *lda,
+   30933             :         int *info)
+   30934             : {
+   30935             :     int a_dim1, a_offset, i__1, i__3, i__4, i__5;
+   30936             :     int j, jb, nb, nn;
+   30937           0 :     float c_b18 = 1.;
+   30938           0 :     float c_b22 = -1.;
+   30939             : 
+   30940             :     int upper;
+   30941             :     int nounit;
+   30942             : 
+   30943           0 :     a_dim1 = *lda;
+   30944           0 :     a_offset = 1 + a_dim1;
+   30945           0 :     a -= a_offset;
+   30946             : 
+   30947           0 :     *info = 0;
+   30948           0 :     upper = (*uplo=='U' || *uplo=='u');
+   30949           0 :     nounit = (*diag=='N' || *diag=='n');
+   30950             : 
+   30951             :     if (*info != 0) {
+   30952             :         i__1 = -(*info);
+   30953             :         return;
+   30954             :     }
+   30955             : 
+   30956           0 :     if (*n == 0) {
+   30957             :         return;
+   30958             :     }
+   30959             : 
+   30960           0 :     if (nounit) {
+   30961           0 :         i__1 = *n;
+   30962           0 :         for (*info = 1; *info <= i__1; ++(*info)) {
+   30963           0 :             if (std::abs(a[*info + *info * a_dim1])<PLUMED_GMX_FLOAT_MIN) {
+   30964             :                 return;
+   30965             :             }
+   30966             :         }
+   30967           0 :         *info = 0;
+   30968             :     }
+   30969             : 
+   30970             :     nb = DTRTRI_BLOCKSIZE;
+   30971           0 :     if (nb <= 1 || nb >= *n) {
+   30972             : 
+   30973           0 :         PLUMED_BLAS_F77_FUNC(strti2,STRTI2)(uplo, diag, n, &a[a_offset], lda, info);
+   30974             :     } else {
+   30975             : 
+   30976           0 :         if (upper) {
+   30977             : 
+   30978           0 :             i__1 = *n;
+   30979             :             i__3 = nb;
+   30980           0 :             for (j = 1; i__3 < 0 ? j >= i__1 : j <= i__1; j += i__3) {
+   30981           0 :                 i__4 = nb, i__5 = *n - j + 1;
+   30982           0 :                 jb = (i__4<i__5) ? i__4 : i__5;
+   30983             : 
+   30984           0 :                 i__4 = j - 1;
+   30985           0 :                 PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Left", "Upper", "No transpose", diag, &i__4, &jb, &
+   30986           0 :                         c_b18, &a[a_offset], lda, &a[j * a_dim1 + 1], lda);
+   30987           0 :                 i__4 = j - 1;
+   30988           0 :                 PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Right", "Upper", "No transpose", diag, &i__4, &jb, &
+   30989           0 :                         c_b22, &a[j + j * a_dim1], lda, &a[j * a_dim1 + 1], 
+   30990             :                         lda);
+   30991             : 
+   30992           0 :                 PLUMED_BLAS_F77_FUNC(strti2,STRTI2)("Upper", diag, &jb, &a[j + j * a_dim1], lda, info);
+   30993             :             }
+   30994             :         } else {
+   30995             : 
+   30996           0 :             nn = (*n - 1) / nb * nb + 1;
+   30997             :             i__3 = -nb;
+   30998           0 :             for (j = nn; i__3 < 0 ? j >= 1 : j <= 1; j += i__3) {
+   30999           0 :                 i__1 = nb, i__4 = *n - j + 1;
+   31000           0 :                 jb = (i__1<i__4) ? i__1 : i__4;
+   31001           0 :                 if (j + jb <= *n) {
+   31002             : 
+   31003           0 :                     i__1 = *n - j - jb + 1;
+   31004           0 :                     PLUMED_BLAS_F77_FUNC(strmm,STRMM)("Left", "Lower", "No transpose", diag, &i__1, &jb, 
+   31005           0 :                             &c_b18, &a[j + jb + (j + jb) * a_dim1], lda, &a[j 
+   31006           0 :                             + jb + j * a_dim1], lda);
+   31007           0 :                     i__1 = *n - j - jb + 1;
+   31008           0 :                     PLUMED_BLAS_F77_FUNC(strsm,STRSM)("Right", "Lower", "No transpose", diag, &i__1, &jb,
+   31009           0 :                              &c_b22, &a[j + j * a_dim1], lda, &a[j + jb + j * 
+   31010           0 :                             a_dim1], lda);
+   31011             :                 }
+   31012             : 
+   31013           0 :                 PLUMED_BLAS_F77_FUNC(strti2,STRTI2)("Lower", diag, &jb, &a[j + j * a_dim1], lda, info);
+   31014             :             }
+   31015             :         }
+   31016             :     }
+   31017             :     return;
+   31018             : }
+   31019             : 
+   31020             : 
+   31021             : }
+   31022             : }
+   31023             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.cpp.func-sort-c.html b/coverage-libs/lepton/CompiledExpression.cpp.func-sort-c.html new file mode 100644 index 000000000000..60b0c9e24508 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.func-sort-c.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22423197.0 %
Date:2024-02-22 21:58:47Functions:181994.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18CompiledExpressionC2ERKS1_0
_ZN4PLMDL18generateTwoArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_S4_PFdddE12
_ZZN4PLMD6lepton9useAsmJitEvENKUlvE_clEv71
_ZNK4PLMD6lepton18CompiledExpression12getVariablesB5cxx11Ev526
_ZN4PLMD6lepton18CompiledExpression20setVariableLocationsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPdSt4lessIS8_ESaISt4pairIKS8_S9_EEE1136
_ZN4PLMD6lepton18CompiledExpressionC2ERKNS0_16ParsedExpressionE1136
_ZN4PLMD6lepton18CompiledExpressionaSERKS1_1136
_ZN4PLMD6lepton18CompiledExpressionC2Ev1164
_ZN4PLMDL21generateSingleArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_PFddE1426
_ZN4PLMD6lepton18CompiledExpression15generateJitCodeEv1948
_ZN4PLMD6lepton16AsmJitRuntimePtrC2Ev2300
_ZN4PLMD6lepton16AsmJitRuntimePtrD2Ev2300
_ZN4PLMD6lepton18CompiledExpressionD2Ev2300
_ZN4PLMD6lepton18CompiledExpression20getVariableReferenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3743
_ZN4PLMD6lepton9useAsmJitEv5877
_ZN4PLMD6lepton18CompiledExpression17compileExpressionERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE8589
_ZN4PLMD6lepton18CompiledExpression13findTempIndexERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE16042
_ZN4PLMDL17evaluateOperationEPNS_6lepton9OperationEPd10695248
_ZNK4PLMD6lepton18CompiledExpression8evaluateEv12901536
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.cpp.func.html b/coverage-libs/lepton/CompiledExpression.cpp.func.html new file mode 100644 index 000000000000..a548216473b6 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.func.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22423197.0 %
Date:2024-02-22 21:58:47Functions:181994.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16AsmJitRuntimePtrC2Ev2300
_ZN4PLMD6lepton16AsmJitRuntimePtrD2Ev2300
_ZN4PLMD6lepton18CompiledExpression13findTempIndexERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE16042
_ZN4PLMD6lepton18CompiledExpression15generateJitCodeEv1948
_ZN4PLMD6lepton18CompiledExpression17compileExpressionERKNS0_18ExpressionTreeNodeERSt6vectorISt4pairIS2_iESaIS7_EE8589
_ZN4PLMD6lepton18CompiledExpression20getVariableReferenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3743
_ZN4PLMD6lepton18CompiledExpression20setVariableLocationsERSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPdSt4lessIS8_ESaISt4pairIKS8_S9_EEE1136
_ZN4PLMD6lepton18CompiledExpressionC2ERKNS0_16ParsedExpressionE1136
_ZN4PLMD6lepton18CompiledExpressionC2ERKS1_0
_ZN4PLMD6lepton18CompiledExpressionC2Ev1164
_ZN4PLMD6lepton18CompiledExpressionD2Ev2300
_ZN4PLMD6lepton18CompiledExpressionaSERKS1_1136
_ZN4PLMD6lepton9useAsmJitEv5877
_ZN4PLMDL17evaluateOperationEPNS_6lepton9OperationEPd10695248
_ZN4PLMDL18generateTwoArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_S4_PFdddE12
_ZN4PLMDL21generateSingleArgCallERNS_6asmjit11X86CompilerERNS0_6X86XmmES4_PFddE1426
_ZNK4PLMD6lepton18CompiledExpression12getVariablesB5cxx11Ev526
_ZNK4PLMD6lepton18CompiledExpression8evaluateEv12901536
_ZZN4PLMD6lepton9useAsmJitEvENKUlvE_clEv71
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.cpp.gcov.html b/coverage-libs/lepton/CompiledExpression.cpp.gcov.html new file mode 100644 index 000000000000..0a14f4ddb9e9 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.cpp.gcov.html @@ -0,0 +1,586 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22423197.0 %
Date:2024-02-22 21:58:47Functions:181994.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * -------------------------------------------------------------------------- *
+       3             :  *                                   Lepton                                   *
+       4             :  * -------------------------------------------------------------------------- *
+       5             :  * This is part of the Lepton expression parser originating from              *
+       6             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+       7             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+       8             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+       9             :  *                                                                            *
+      10             :  * Portions copyright (c) 2013-2016 Stanford University and the Authors.      *
+      11             :  * Authors: Peter Eastman                                                     *
+      12             :  * Contributors:                                                              *
+      13             :  *                                                                            *
+      14             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      15             :  * copy of this software and associated documentation files (the "Software"), *
+      16             :  * to deal in the Software without restriction, including without limitation  *
+      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      18             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      19             :  * Software is furnished to do so, subject to the following conditions:       *
+      20             :  *                                                                            *
+      21             :  * The above copyright notice and this permission notice shall be included in *
+      22             :  * all copies or substantial portions of the Software.                        *
+      23             :  *                                                                            *
+      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      27             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      28             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      29             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      30             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      31             :  * -------------------------------------------------------------------------- *
+      32             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      33             : /* -------------------------------------------------------------------------- *
+      34             :  *                                   lepton                                   *
+      35             :  * -------------------------------------------------------------------------- *
+      36             :  * This is part of the lepton expression parser originating from              *
+      37             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+      38             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+      39             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+      40             :  *                                                                            *
+      41             :  * Portions copyright (c) 2013-2019 Stanford University and the Authors.      *
+      42             :  * Authors: Peter Eastman                                                     *
+      43             :  * Contributors:                                                              *
+      44             :  *                                                                            *
+      45             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      46             :  * copy of this software and associated documentation files (the "Software"), *
+      47             :  * to deal in the Software without restriction, including without limitation  *
+      48             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      49             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      50             :  * Software is furnished to do so, subject to the following conditions:       *
+      51             :  *                                                                            *
+      52             :  * The above copyright notice and this permission notice shall be included in *
+      53             :  * all copies or substantial portions of the Software.                        *
+      54             :  *                                                                            *
+      55             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      56             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      57             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      58             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      59             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      60             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      61             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      62             :  * -------------------------------------------------------------------------- */
+      63             : 
+      64             : #include "CompiledExpression.h"
+      65             : #include "Operation.h"
+      66             : #include "ParsedExpression.h"
+      67             : #ifdef __PLUMED_HAS_ASMJIT
+      68             :     #include "asmjit/asmjit.h"
+      69             : #endif
+      70             : #include <utility>
+      71             : 
+      72             : namespace PLMD {
+      73             : using namespace lepton;
+      74             : using namespace std;
+      75             : #ifdef __PLUMED_HAS_ASMJIT
+      76             :     using namespace asmjit;
+      77             : #endif
+      78             : 
+      79        5877 : bool lepton::useAsmJit() {
+      80             : #ifdef __PLUMED_HAS_ASMJIT
+      81          71 :   static const bool use=[](){
+      82          71 :     if(auto s=std::getenv("PLUMED_USE_ASMJIT")) {
+      83           2 :       auto ss=std::string(s);
+      84           2 :       if(ss=="yes") return true;
+      85           1 :       if(ss=="no") return false;
+      86           0 :       throw Exception("PLUMED_USE_ASMJIT variable is set to " + ss + "; should be yes or no");
+      87             :     }
+      88             :     return true; // by default use asmjit
+      89        5877 :   }();
+      90        5877 :   return use;
+      91             : #else
+      92             :   return false;
+      93             : #endif
+      94             : }
+      95             : 
+      96        2300 : AsmJitRuntimePtr::AsmJitRuntimePtr()
+      97             : #ifdef __PLUMED_HAS_ASMJIT
+      98        2300 :   : ptr(useAsmJit()?new asmjit::JitRuntime:nullptr)
+      99             : #endif
+     100        2300 : {}
+     101             : 
+     102        2300 : AsmJitRuntimePtr::~AsmJitRuntimePtr()
+     103             : {
+     104             : #ifdef __PLUMED_HAS_ASMJIT
+     105        2300 :   if(useAsmJit()) delete static_cast<asmjit::JitRuntime*>(ptr);
+     106             : #endif
+     107        2300 : }
+     108             : 
+     109        1164 : CompiledExpression::CompiledExpression() : jitCode(NULL) {
+     110        1164 : }
+     111             : 
+     112        1136 : CompiledExpression::CompiledExpression(const ParsedExpression& expression) : jitCode(NULL) {
+     113        1136 :     ParsedExpression expr = expression.optimize(); // Just in case it wasn't already optimized.
+     114             :     vector<pair<ExpressionTreeNode, int> > temps;
+     115        1136 :     compileExpression(expr.getRootNode(), temps);
+     116             :     int maxArguments = 1;
+     117        6805 :     for (int i = 0; i < (int) operation.size(); i++)
+     118        5669 :         if (operation[i]->getNumArguments() > maxArguments)
+     119         623 :             maxArguments = operation[i]->getNumArguments();
+     120        1136 :     argValues.resize(maxArguments);
+     121             : #ifdef __PLUMED_HAS_ASMJIT
+     122        1136 :     if(useAsmJit()) generateJitCode();
+     123             : #endif
+     124        2272 : }
+     125             : 
+     126        2300 : CompiledExpression::~CompiledExpression() {
+     127       13638 :     for (int i = 0; i < (int) operation.size(); i++)
+     128       11338 :         if (operation[i] != NULL)
+     129       11338 :             delete operation[i];
+     130        4600 : }
+     131             : 
+     132           0 : CompiledExpression::CompiledExpression(const CompiledExpression& expression) : jitCode(NULL) {
+     133           0 :     *this = expression;
+     134           0 : }
+     135             : 
+     136        1136 : CompiledExpression& CompiledExpression::operator=(const CompiledExpression& expression) {
+     137        1136 :     arguments = expression.arguments;
+     138        1136 :     target = expression.target;
+     139             :     variableIndices = expression.variableIndices;
+     140             :     variableNames = expression.variableNames;
+     141        1136 :     workspace.resize(expression.workspace.size());
+     142        1136 :     argValues.resize(expression.argValues.size());
+     143        1136 :     operation.resize(expression.operation.size());
+     144        6805 :     for (int i = 0; i < (int) operation.size(); i++)
+     145        5669 :         operation[i] = expression.operation[i]->clone();
+     146        1136 :     setVariableLocations(variablePointers);
+     147        1136 :     return *this;
+     148             : }
+     149             : 
+     150        8589 : void CompiledExpression::compileExpression(const ExpressionTreeNode& node, vector<pair<ExpressionTreeNode, int> >& temps) {
+     151        8589 :     if (findTempIndex(node, temps) != -1)
+     152        1767 :         return; // We have already processed a node identical to this one.
+     153             :     
+     154             :     // Process the child nodes.
+     155             :     
+     156             :     vector<int> args;
+     157       14275 :     for (int i = 0; i < node.getChildren().size(); i++) {
+     158        7453 :         compileExpression(node.getChildren()[i], temps);
+     159        7453 :         args.push_back(findTempIndex(node.getChildren()[i], temps));
+     160             :     }
+     161             :     
+     162             :     // Process this node.
+     163             :     
+     164        6822 :     if (node.getOperation().getId() == Operation::VARIABLE) {
+     165        1153 :         variableIndices[node.getOperation().getName()] = (int) workspace.size();
+     166        2306 :         variableNames.insert(node.getOperation().getName());
+     167             :     }
+     168             :     else {
+     169        5669 :         int stepIndex = (int) arguments.size();
+     170        5669 :         arguments.push_back(vector<int>());
+     171        5669 :         target.push_back((int) workspace.size());
+     172        5669 :         operation.push_back(node.getOperation().clone());
+     173        5669 :         if (args.size() == 0)
+     174         247 :             arguments[stepIndex].push_back(0); // The value won't actually be used.  We just need something there.
+     175             :         else {
+     176             :             // If the arguments are sequential, we can just pass a pointer to the first one.
+     177             :             
+     178             :             bool sequential = true;
+     179        7453 :             for (int i = 1; i < args.size(); i++)
+     180        2031 :                 if (args[i] != args[i-1]+1)
+     181             :                     sequential = false;
+     182        5422 :             if (sequential)
+     183        4198 :                 arguments[stepIndex].push_back(args[0]);
+     184             :             else
+     185        1224 :                 arguments[stepIndex] = args;
+     186             :         }
+     187             :     }
+     188        6822 :     temps.push_back(make_pair(node, (int) workspace.size()));
+     189        6822 :     workspace.push_back(0.0);
+     190             : }
+     191             : 
+     192       16042 : int CompiledExpression::findTempIndex(const ExpressionTreeNode& node, vector<pair<ExpressionTreeNode, int> >& temps) {
+     193       64196 :     for (int i = 0; i < (int) temps.size(); i++)
+     194       57374 :         if (temps[i].first == node)
+     195             :             return i;
+     196             :     return -1;
+     197             : }
+     198             : 
+     199         526 : const set<string>& CompiledExpression::getVariables() const {
+     200         526 :     return variableNames;
+     201             : }
+     202             : 
+     203        3743 : double& CompiledExpression::getVariableReference(const string& name) {
+     204             :     map<string, double*>::iterator pointer = variablePointers.find(name);
+     205        3743 :     if (pointer != variablePointers.end())
+     206           0 :         return *pointer->second;
+     207             :     map<string, int>::iterator index = variableIndices.find(name);
+     208        3743 :     if (index == variableIndices.end())
+     209        1100 :         throw Exception("getVariableReference: Unknown variable '"+name+"'");
+     210        3193 :     return workspace[index->second];
+     211             : }
+     212             : 
+     213        1136 : void CompiledExpression::setVariableLocations(map<string, double*>& variableLocations) {
+     214             :   variablePointers = variableLocations;
+     215        1136 :   static const bool asmjit=useAsmJit();
+     216        1136 :   if(asmjit) {
+     217             : #ifdef __PLUMED_HAS_ASMJIT
+     218             :     // Rebuild the JIT code.
+     219             :     
+     220         974 :     if (workspace.size() > 0)
+     221         974 :         generateJitCode();
+     222             : #endif
+     223             :   } else {
+     224             :     // Make a list of all variables we will need to copy before evaluating the expression.
+     225             :     
+     226         162 :     variablesToCopy.clear();
+     227         292 :     for (map<string, int>::const_iterator iter = variableIndices.begin(); iter != variableIndices.end(); ++iter) {
+     228         130 :         map<string, double*>::iterator pointer = variablePointers.find(iter->first);
+     229         130 :         if (pointer != variablePointers.end())
+     230           0 :             variablesToCopy.push_back(make_pair(&workspace[iter->second], pointer->second));
+     231             :     }
+     232             :   }
+     233        1136 : }
+     234             : 
+     235    12901536 : double CompiledExpression::evaluate() const {
+     236    12901536 :     static const bool asmjit=useAsmJit();
+     237             : #ifdef __PLUMED_HAS_ASMJIT
+     238    12901536 :     if(asmjit) return ((double (*)()) jitCode)();
+     239             : #endif
+     240       16362 :     for (int i = 0; i < variablesToCopy.size(); i++)
+     241           0 :         *variablesToCopy[i].first = *variablesToCopy[i].second;
+     242             : 
+     243             :     // Loop over the operations and evaluate each one.
+     244             :     
+     245       49288 :     for (int step = 0; step < operation.size(); step++) {
+     246             :         const vector<int>& args = arguments[step];
+     247       32926 :         if (args.size() == 1)
+     248       30098 :             workspace[target[step]] = operation[step]->evaluate(&workspace[args[0]], dummyVariables);
+     249             :         else {
+     250        8888 :             for (int i = 0; i < args.size(); i++)
+     251        6060 :                 argValues[i] = workspace[args[i]];
+     252        2828 :             workspace[target[step]] = operation[step]->evaluate(&argValues[0], dummyVariables);
+     253             :         }
+     254             :     }
+     255       16362 :     return workspace[workspace.size()-1];
+     256             : }
+     257             : 
+     258             : #ifdef __PLUMED_HAS_ASMJIT
+     259    10695248 : static double evaluateOperation(Operation* op, double* args) {
+     260    10695248 :     static map<string, double> dummyVariables;
+     261    10695248 :     return op->evaluate(args, dummyVariables);
+     262             : }
+     263             : 
+     264             : static void generateSingleArgCall(X86Compiler& c, X86Xmm& dest, X86Xmm& arg, double (*function)(double));
+     265             : static void generateTwoArgCall(X86Compiler& c, X86Xmm& dest, X86Xmm& arg1, X86Xmm& arg2, double (*function)(double, double));
+     266             : 
+     267        1948 : void CompiledExpression::generateJitCode() {
+     268        1948 :     CodeHolder code;
+     269             :     auto & runtime(*static_cast<asmjit::JitRuntime*>(runtimeptr.get()));
+     270        1948 :     code.init(runtime.getCodeInfo());
+     271        1948 :     X86Compiler c(&code);
+     272        1948 :     c.addFunc(FuncSignature0<double>());
+     273        1948 :     vector<X86Xmm> workspaceVar(workspace.size());
+     274       14680 :     for (int i = 0; i < (int) workspaceVar.size(); i++)
+     275       12732 :         workspaceVar[i] = c.newXmmSd();
+     276             :     X86Gp argsPointer = c.newIntPtr();
+     277        1948 :     c.mov(argsPointer, imm_ptr(&argValues[0]));
+     278             :     
+     279             :     // Load the arguments into variables.
+     280             :     
+     281        3994 :     for (set<string>::const_iterator iter = variableNames.begin(); iter != variableNames.end(); ++iter) {
+     282             :         map<string, int>::iterator index = variableIndices.find(*iter);
+     283             :         X86Gp variablePointer = c.newIntPtr();
+     284        4092 :         c.mov(variablePointer, imm_ptr(&getVariableReference(index->first)));
+     285        2046 :         c.movsd(workspaceVar[index->second], x86::ptr(variablePointer, 0, 0));
+     286             :     }
+     287             : 
+     288             :     // Make a list of all constants that will be needed for evaluation.
+     289             :     
+     290        1948 :     vector<int> operationConstantIndex(operation.size(), -1);
+     291       12634 :     for (int step = 0; step < (int) operation.size(); step++) {
+     292             :         // Find the constant value (if any) used by this operation.
+     293             :         
+     294       10686 :         Operation& op = *operation[step];
+     295             :         double value;
+     296       10686 :         if (op.getId() == Operation::CONSTANT)
+     297         346 :             value = dynamic_cast<Operation::Constant&>(op).getValue();
+     298       10340 :         else if (op.getId() == Operation::ADD_CONSTANT)
+     299         846 :             value = dynamic_cast<Operation::AddConstant&>(op).getValue();
+     300        9494 :         else if (op.getId() == Operation::MULTIPLY_CONSTANT)
+     301        2884 :             value = dynamic_cast<Operation::MultiplyConstant&>(op).getValue();
+     302        6610 :         else if (op.getId() == Operation::RECIPROCAL)
+     303         148 :             value = 1.0;
+     304        6462 :         else if (op.getId() == Operation::STEP)
+     305          74 :             value = 1.0;
+     306        6388 :         else if (op.getId() == Operation::DELTA)
+     307          40 :             value = 1.0/0.0;
+     308        6348 :         else if (op.getId() == Operation::NANDELTA)
+     309           6 :             value = std::numeric_limits<double>::quiet_NaN();
+     310             :         else
+     311        6342 :             continue;
+     312             :         
+     313             :         // See if we already have a variable for this constant.
+     314             :         
+     315        9234 :         for (int i = 0; i < (int) constants.size(); i++)
+     316        5446 :             if (value == constants[i]) {
+     317         556 :                 operationConstantIndex[step] = i;
+     318         556 :                 break;
+     319             :             }
+     320        4344 :         if (operationConstantIndex[step] == -1) {
+     321        3788 :             operationConstantIndex[step] = constants.size();
+     322        3788 :             constants.push_back(value);
+     323             :         }
+     324             :     }
+     325             :     
+     326             :     // Load constants into variables.
+     327             :     
+     328        1948 :     vector<X86Xmm> constantVar(constants.size());
+     329        1948 :     if (constants.size() > 0) {
+     330             :         X86Gp constantsPointer = c.newIntPtr();
+     331        1626 :         c.mov(constantsPointer, imm_ptr(&constants[0]));
+     332        5414 :         for (int i = 0; i < (int) constants.size(); i++) {
+     333        3788 :             constantVar[i] = c.newXmmSd();
+     334        3788 :             c.movsd(constantVar[i], x86::ptr(constantsPointer, 8*i, 0));
+     335             :         }
+     336             :     }
+     337             :     
+     338             :     // Evaluate the operations.
+     339             :     
+     340       12634 :     for (int step = 0; step < (int) operation.size(); step++) {
+     341       10686 :         Operation& op = *operation[step];
+     342       10686 :         vector<int> args = arguments[step];
+     343       10686 :         if (args.size() == 1) {
+     344             :             // One or more sequential arguments.  Fill out the list.
+     345             :             
+     346        9822 :             for (int i = 1; i < op.getNumArguments(); i++)
+     347        1528 :                 args.push_back(args[0]+i);
+     348             :         }
+     349             :         
+     350             :         // Generate instructions to execute this operation.
+     351             :         
+     352       10686 :         switch (op.getId()) {
+     353         346 :             case Operation::CONSTANT:
+     354         346 :                 c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     355       10476 :                 break;
+     356             :             case Operation::ADD:
+     357        1140 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     358        1140 :                 c.addsd(workspaceVar[target[step]], workspaceVar[args[1]]);
+     359             :                 break;
+     360             :             case Operation::SUBTRACT:
+     361         862 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     362         862 :                 c.subsd(workspaceVar[target[step]], workspaceVar[args[1]]);
+     363             :                 break;
+     364             :             case Operation::MULTIPLY:
+     365        1736 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     366        1736 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[1]]);
+     367             :                 break;
+     368             :             case Operation::DIVIDE:
+     369         122 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     370         122 :                 c.divsd(workspaceVar[target[step]], workspaceVar[args[1]]);
+     371             :                 break;
+     372             :             case Operation::POWER:
+     373           4 :                 generateTwoArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], workspaceVar[args[1]], pow);
+     374             :                 break;
+     375         128 :             case Operation::NEGATE:
+     376         128 :                 c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]);
+     377         128 :                 c.subsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     378             :                 break;
+     379             :             case Operation::SQRT:
+     380         126 :                 c.sqrtsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     381             :                 break;
+     382             :             case Operation::EXP:
+     383          56 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], exp);
+     384             :                 break;
+     385             :             case Operation::LOG:
+     386           2 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], log);
+     387             :                 break;
+     388             :             case Operation::SIN:
+     389         508 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sin);
+     390             :                 break;
+     391             :             case Operation::COS:
+     392         800 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], cos);
+     393             :                 break;
+     394             :             case Operation::TAN:
+     395           4 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], tan);
+     396             :                 break;
+     397             :             case Operation::ASIN:
+     398           2 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], asin);
+     399             :                 break;
+     400             :             case Operation::ACOS:
+     401           2 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], acos);
+     402             :                 break;
+     403             :             case Operation::ATAN:
+     404           2 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], atan);
+     405             :                 break;
+     406             :             case Operation::ATAN2:
+     407           8 :                 generateTwoArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], workspaceVar[args[1]], atan2);
+     408             :                 break;
+     409             :             case Operation::SINH:
+     410           4 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], sinh);
+     411             :                 break;
+     412             :             case Operation::COSH:
+     413           4 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], cosh);
+     414             :                 break;
+     415             :             case Operation::TANH:
+     416           6 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], tanh);
+     417             :                 break;
+     418             :             case Operation::ASINH:
+     419           2 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], asinh);
+     420             :                 break;
+     421             :             case Operation::ACOSH:
+     422           2 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], acosh);
+     423             :                 break;
+     424             :             case Operation::ATANH:
+     425           2 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], atanh);
+     426             :                 break;
+     427          74 :             case Operation::STEP:
+     428          74 :                 c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]);
+     429          74 :                 c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(18)); // Comparison mode is _CMP_LE_OQ = 18
+     430          74 :                 c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     431             :                 break;
+     432          40 :             case Operation::DELTA:
+     433          40 :                 c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]);
+     434          40 :                 c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(16)); // Comparison mode is _CMP_EQ_OS = 16
+     435          40 :                 c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     436             :                 break;
+     437           6 :             case Operation::NANDELTA:
+     438           6 :                 c.xorps(workspaceVar[target[step]], workspaceVar[target[step]]);
+     439           6 :                 c.cmpsd(workspaceVar[target[step]], workspaceVar[args[0]], imm(16)); // Comparison mode is _CMP_EQ_OS = 16
+     440           6 :                 c.andps(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     441             :                 break;
+     442             :             case Operation::SQUARE:
+     443         514 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     444         514 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     445             :                 break;
+     446             :             case Operation::CUBE:
+     447          66 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     448          66 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     449          66 :                 c.mulsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     450             :                 break;
+     451         148 :             case Operation::RECIPROCAL:
+     452         148 :                 c.movsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     453         148 :                 c.divsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     454             :                 break;
+     455             :             case Operation::ADD_CONSTANT:
+     456         846 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     457         846 :                 c.addsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     458             :                 break;
+     459             :             case Operation::MULTIPLY_CONSTANT:
+     460        2884 :                 c.movsd(workspaceVar[target[step]], workspaceVar[args[0]]);
+     461        2884 :                 c.mulsd(workspaceVar[target[step]], constantVar[operationConstantIndex[step]]);
+     462             :                 break;
+     463             :             case Operation::ABS:
+     464          26 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], fabs);
+     465             :                 break;
+     466             :             case Operation::FLOOR:
+     467           2 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], floor);
+     468             :                 break;
+     469             :             case Operation::CEIL:
+     470           2 :                 generateSingleArgCall(c, workspaceVar[target[step]], workspaceVar[args[0]], ceil);
+     471             :                 break;
+     472             :             default:
+     473             :                 // Just invoke evaluateOperation().
+     474             :                 
+     475         476 :                 for (int i = 0; i < (int) args.size(); i++)
+     476         266 :                     c.movsd(x86::ptr(argsPointer, 8*i, 0), workspaceVar[args[i]]);
+     477             :                 X86Gp fn = c.newIntPtr();
+     478         210 :                 c.mov(fn, imm_ptr((void*) evaluateOperation));
+     479         210 :                 CCFuncCall* call = c.call(fn, FuncSignature2<double, Operation*, double*>());
+     480         210 :                 call->setArg(0, imm_ptr(&op));
+     481         210 :                 call->setArg(1, imm_ptr(&argValues[0]));
+     482         210 :                 call->setRet(0, workspaceVar[target[step]]);
+     483             :         }
+     484             :     }
+     485        1948 :     c.ret(workspaceVar[workspace.size()-1]);
+     486        1948 :     c.endFunc();
+     487        1948 :     c.finalize();
+     488        1948 :     runtime.add(&jitCode, &code);
+     489        1948 : }
+     490             : 
+     491        1426 : void generateSingleArgCall(X86Compiler& c, X86Xmm& dest, X86Xmm& arg, double (*function)(double)) {
+     492             :     X86Gp fn = c.newIntPtr();
+     493        1426 :     c.mov(fn, imm_ptr((void*) function));
+     494        1426 :     CCFuncCall* call = c.call(fn, FuncSignature1<double, double>());
+     495             :     call->setArg(0, arg);
+     496             :     call->setRet(0, dest);
+     497        1426 : }
+     498             : 
+     499          12 : void generateTwoArgCall(X86Compiler& c, X86Xmm& dest, X86Xmm& arg1, X86Xmm& arg2, double (*function)(double, double)) {
+     500             :     X86Gp fn = c.newIntPtr();
+     501          12 :     c.mov(fn, imm_ptr((void*) function));
+     502          24 :     CCFuncCall* call = c.call(fn, FuncSignature2<double, double, double>());
+     503             :     call->setArg(0, arg1);
+     504             :     call->setArg(1, arg2);
+     505             :     call->setRet(0, dest);
+     506          12 : }
+     507             : 
+     508             : #endif
+     509             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.h.func-sort-c.html b/coverage-libs/lepton/CompiledExpression.h.func-sort-c.html new file mode 100644 index 000000000000..4ec37c92f55f --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.h.func.html b/coverage-libs/lepton/CompiledExpression.h.func.html new file mode 100644 index 000000000000..3bb4283f6836 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/CompiledExpression.h.gcov.html b/coverage-libs/lepton/CompiledExpression.h.gcov.html new file mode 100644 index 000000000000..0b383172db49 --- /dev/null +++ b/coverage-libs/lepton/CompiledExpression.h.gcov.html @@ -0,0 +1,241 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/CompiledExpression.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - CompiledExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * -------------------------------------------------------------------------- *
+       3             :  *                                   Lepton                                   *
+       4             :  * -------------------------------------------------------------------------- *
+       5             :  * This is part of the Lepton expression parser originating from              *
+       6             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+       7             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+       8             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+       9             :  *                                                                            *
+      10             :  * Portions copyright (c) 2013-2016 Stanford University and the Authors.      *
+      11             :  * Authors: Peter Eastman                                                     *
+      12             :  * Contributors:                                                              *
+      13             :  *                                                                            *
+      14             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      15             :  * copy of this software and associated documentation files (the "Software"), *
+      16             :  * to deal in the Software without restriction, including without limitation  *
+      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      18             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      19             :  * Software is furnished to do so, subject to the following conditions:       *
+      20             :  *                                                                            *
+      21             :  * The above copyright notice and this permission notice shall be included in *
+      22             :  * all copies or substantial portions of the Software.                        *
+      23             :  *                                                                            *
+      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      27             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      28             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      29             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      30             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      31             :  * -------------------------------------------------------------------------- *
+      32             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      33             : #ifndef __PLUMED_lepton_CompiledExpression_h
+      34             : #define __PLUMED_lepton_CompiledExpression_h
+      35             : 
+      36             : /* -------------------------------------------------------------------------- *
+      37             :  *                                   lepton                                   *
+      38             :  * -------------------------------------------------------------------------- *
+      39             :  * This is part of the lepton expression parser originating from              *
+      40             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+      41             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+      42             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+      43             :  *                                                                            *
+      44             :  * Portions copyright (c) 2013-2019 Stanford University and the Authors.      *
+      45             :  * Authors: Peter Eastman                                                     *
+      46             :  * Contributors:                                                              *
+      47             :  *                                                                            *
+      48             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      49             :  * copy of this software and associated documentation files (the "Software"), *
+      50             :  * to deal in the Software without restriction, including without limitation  *
+      51             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      52             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      53             :  * Software is furnished to do so, subject to the following conditions:       *
+      54             :  *                                                                            *
+      55             :  * The above copyright notice and this permission notice shall be included in *
+      56             :  * all copies or substantial portions of the Software.                        *
+      57             :  *                                                                            *
+      58             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      59             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      60             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      61             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      62             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      63             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      64             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      65             :  * -------------------------------------------------------------------------- */
+      66             : 
+      67             : #include "ExpressionTreeNode.h"
+      68             : #include "windowsIncludes.h"
+      69             : #include <map>
+      70             : #include <set>
+      71             : #include <string>
+      72             : #include <utility>
+      73             : #include <vector>
+      74             : 
+      75             : namespace PLMD {
+      76             : namespace lepton {
+      77             : 
+      78             : bool useAsmJit();
+      79             : 
+      80             : // Utility class.
+      81             : // Implement an unique pointer to asmjit::JitRuntime.
+      82             : // Needed to decouple asmjit header file from this one.
+      83             : class AsmJitRuntimePtr {
+      84             : /// if ASMJIT is not defined, just set the pointer to null
+      85             :   void* ptr=nullptr;
+      86             : public:
+      87             : /// constructor
+      88             :   AsmJitRuntimePtr();
+      89             : /// destructor
+      90             :   ~AsmJitRuntimePtr();
+      91             : /// deleted copy constructor
+      92             :   AsmJitRuntimePtr(const AsmJitRuntimePtr&) = delete;
+      93             : /// deleted assignment
+      94             :   AsmJitRuntimePtr & operator=(const AsmJitRuntimePtr&) = delete;
+      95             : /// get the pointer
+      96             :   void* get() {
+      97        1948 :     return ptr;
+      98             :   }
+      99             : };
+     100             : 
+     101             : class Operation;
+     102             : class ParsedExpression;
+     103             : 
+     104             : /**
+     105             :  * A CompiledExpression is a highly optimized representation of an expression for cases when you want to evaluate
+     106             :  * it many times as quickly as possible.  You should treat it as an opaque object; none of the internal representation
+     107             :  * is visible.
+     108             :  * 
+     109             :  * A CompiledExpression is created by calling createCompiledExpression() on a ParsedExpression.
+     110             :  * 
+     111             :  * WARNING: CompiledExpression is NOT thread safe.  You should never access a CompiledExpression from two threads at
+     112             :  * the same time.
+     113             :  */
+     114             : 
+     115             : class LEPTON_EXPORT CompiledExpression {
+     116             : public:
+     117             :     CompiledExpression();
+     118             :     CompiledExpression(const CompiledExpression& expression);
+     119             :     ~CompiledExpression();
+     120             :     CompiledExpression& operator=(const CompiledExpression& expression);
+     121             :     /**
+     122             :      * Get the names of all variables used by this expression.
+     123             :      */
+     124             :     const std::set<std::string>& getVariables() const;
+     125             :     /**
+     126             :      * Get a reference to the memory location where the value of a particular variable is stored.  This can be used
+     127             :      * to set the value of the variable before calling evaluate().
+     128             :      */
+     129             :     double& getVariableReference(const std::string& name);
+     130             :     /**
+     131             :      * You can optionally specify the memory locations from which the values of variables should be read.
+     132             :      * This is useful, for example, when several expressions all use the same variable.  You can then set
+     133             :      * the value of that variable in one place, and it will be seen by all of them.
+     134             :      */
+     135             :     void setVariableLocations(std::map<std::string, double*>& variableLocations);
+     136             :     /**
+     137             :      * Evaluate the expression.  The values of all variables should have been set before calling this.
+     138             :      */
+     139             :     double evaluate() const;
+     140             : private:
+     141             :     friend class ParsedExpression;
+     142             :     CompiledExpression(const ParsedExpression& expression);
+     143             :     void compileExpression(const ExpressionTreeNode& node, std::vector<std::pair<ExpressionTreeNode, int> >& temps);
+     144             :     int findTempIndex(const ExpressionTreeNode& node, std::vector<std::pair<ExpressionTreeNode, int> >& temps);
+     145             :     std::map<std::string, double*> variablePointers;
+     146             :     std::vector<std::pair<double*, double*> > variablesToCopy;
+     147             :     std::vector<std::vector<int> > arguments;
+     148             :     std::vector<int> target;
+     149             :     std::vector<Operation*> operation;
+     150             :     std::map<std::string, int> variableIndices;
+     151             :     std::set<std::string> variableNames;
+     152             :     mutable std::vector<double> workspace;
+     153             :     mutable std::vector<double> argValues;
+     154             :     std::map<std::string, double> dummyVariables;
+     155             :     void* jitCode;
+     156             :     void generateJitCode();
+     157             :     std::vector<double> constants;
+     158             :     AsmJitRuntimePtr runtimeptr;
+     159             : };
+     160             : 
+     161             : } // namespace lepton
+     162             : } // namespace PLMD
+     163             : 
+     164             : #endif /*LEPTON_COMPILED_EXPRESSION_H_*/
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Exception.h.func-sort-c.html b/coverage-libs/lepton/Exception.h.func-sort-c.html new file mode 100644 index 000000000000..4e4299c09b42 --- /dev/null +++ b/coverage-libs/lepton/Exception.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Exception.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:66100.0 %
Date:2024-02-22 21:58:47Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9ExceptionD0Ev0
_ZNK4PLMD6lepton9Exception4whatEv20
_ZN4PLMD6lepton9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE611
_ZN4PLMD6lepton9ExceptionD2Ev611
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Exception.h.func.html b/coverage-libs/lepton/Exception.h.func.html new file mode 100644 index 000000000000..d1a1ee63f09b --- /dev/null +++ b/coverage-libs/lepton/Exception.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Exception.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:66100.0 %
Date:2024-02-22 21:58:47Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE611
_ZN4PLMD6lepton9ExceptionD0Ev0
_ZN4PLMD6lepton9ExceptionD2Ev611
_ZNK4PLMD6lepton9Exception4whatEv20
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Exception.h.gcov.html b/coverage-libs/lepton/Exception.h.gcov.html new file mode 100644 index 000000000000..a4840437fd6a --- /dev/null +++ b/coverage-libs/lepton/Exception.h.gcov.html @@ -0,0 +1,170 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Exception.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:66100.0 %
Date:2024-02-22 21:58:47Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * -------------------------------------------------------------------------- *
+       3             :  *                                   Lepton                                   *
+       4             :  * -------------------------------------------------------------------------- *
+       5             :  * This is part of the Lepton expression parser originating from              *
+       6             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+       7             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+       8             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+       9             :  *                                                                            *
+      10             :  * Portions copyright (c) 2013-2016 Stanford University and the Authors.      *
+      11             :  * Authors: Peter Eastman                                                     *
+      12             :  * Contributors:                                                              *
+      13             :  *                                                                            *
+      14             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      15             :  * copy of this software and associated documentation files (the "Software"), *
+      16             :  * to deal in the Software without restriction, including without limitation  *
+      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      18             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      19             :  * Software is furnished to do so, subject to the following conditions:       *
+      20             :  *                                                                            *
+      21             :  * The above copyright notice and this permission notice shall be included in *
+      22             :  * all copies or substantial portions of the Software.                        *
+      23             :  *                                                                            *
+      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      27             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      28             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      29             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      30             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      31             :  * -------------------------------------------------------------------------- *
+      32             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      33             : #ifndef __PLUMED_lepton_Exception_h
+      34             : #define __PLUMED_lepton_Exception_h
+      35             : 
+      36             : /* -------------------------------------------------------------------------- *
+      37             :  *                                   lepton                                   *
+      38             :  * -------------------------------------------------------------------------- *
+      39             :  * This is part of the lepton expression parser originating from              *
+      40             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+      41             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+      42             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+      43             :  *                                                                            *
+      44             :  * Portions copyright (c) 2009 Stanford University and the Authors.           *
+      45             :  * Authors: Peter Eastman                                                     *
+      46             :  * Contributors:                                                              *
+      47             :  *                                                                            *
+      48             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      49             :  * copy of this software and associated documentation files (the "Software"), *
+      50             :  * to deal in the Software without restriction, including without limitation  *
+      51             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      52             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      53             :  * Software is furnished to do so, subject to the following conditions:       *
+      54             :  *                                                                            *
+      55             :  * The above copyright notice and this permission notice shall be included in *
+      56             :  * all copies or substantial portions of the Software.                        *
+      57             :  *                                                                            *
+      58             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      59             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      60             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      61             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      62             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      63             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      64             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      65             :  * -------------------------------------------------------------------------- */
+      66             : 
+      67             : #include <exception>
+      68             : #include <string>
+      69             : 
+      70             : namespace PLMD {
+      71             : namespace lepton {
+      72             : 
+      73             : /**
+      74             :  * This class is used for all exceptions thrown by lepton.
+      75             :  */
+      76             : 
+      77             : class Exception : public std::exception {
+      78             : public:
+      79         611 :     Exception(const std::string& message) : message(message) {
+      80         611 :     }
+      81         611 :     ~Exception() throw() {
+      82         611 :     }
+      83          20 :     const char* what() const throw() {
+      84          20 :         return message.c_str();
+      85             :     }
+      86             : private:
+      87             :     std::string message;
+      88             : };
+      89             : 
+      90             : } // namespace lepton
+      91             : } // namespace PLMD
+      92             : 
+      93             : #endif /*LEPTON_EXCEPTION_H_*/
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionProgram.cpp.func-sort-c.html b/coverage-libs/lepton/ExpressionProgram.cpp.func-sort-c.html new file mode 100644 index 000000000000..ef2679877307 --- /dev/null +++ b/coverage-libs/lepton/ExpressionProgram.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionProgram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionProgram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0520.0 %
Date:2024-02-22 21:58:47Functions:0120.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton17ExpressionProgram12buildProgramERKNS0_18ExpressionTreeNodeE0
_ZN4PLMD6lepton17ExpressionProgram12setOperationEiPNS0_9OperationE0
_ZN4PLMD6lepton17ExpressionProgramC2ERKNS0_16ParsedExpressionE0
_ZN4PLMD6lepton17ExpressionProgramC2ERKS1_0
_ZN4PLMD6lepton17ExpressionProgramC2Ev0
_ZN4PLMD6lepton17ExpressionProgramD2Ev0
_ZN4PLMD6lepton17ExpressionProgramaSERKS1_0
_ZNK4PLMD6lepton17ExpressionProgram12getOperationEi0
_ZNK4PLMD6lepton17ExpressionProgram12getStackSizeEv0
_ZNK4PLMD6lepton17ExpressionProgram16getNumOperationsEv0
_ZNK4PLMD6lepton17ExpressionProgram8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE0
_ZNK4PLMD6lepton17ExpressionProgram8evaluateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionProgram.cpp.func.html b/coverage-libs/lepton/ExpressionProgram.cpp.func.html new file mode 100644 index 000000000000..5978586d1ec0 --- /dev/null +++ b/coverage-libs/lepton/ExpressionProgram.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionProgram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionProgram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0520.0 %
Date:2024-02-22 21:58:47Functions:0120.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton17ExpressionProgram12buildProgramERKNS0_18ExpressionTreeNodeE0
_ZN4PLMD6lepton17ExpressionProgram12setOperationEiPNS0_9OperationE0
_ZN4PLMD6lepton17ExpressionProgramC2ERKNS0_16ParsedExpressionE0
_ZN4PLMD6lepton17ExpressionProgramC2ERKS1_0
_ZN4PLMD6lepton17ExpressionProgramC2Ev0
_ZN4PLMD6lepton17ExpressionProgramD2Ev0
_ZN4PLMD6lepton17ExpressionProgramaSERKS1_0
_ZNK4PLMD6lepton17ExpressionProgram12getOperationEi0
_ZNK4PLMD6lepton17ExpressionProgram12getStackSizeEv0
_ZNK4PLMD6lepton17ExpressionProgram16getNumOperationsEv0
_ZNK4PLMD6lepton17ExpressionProgram8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE0
_ZNK4PLMD6lepton17ExpressionProgram8evaluateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionProgram.cpp.gcov.html b/coverage-libs/lepton/ExpressionProgram.cpp.gcov.html new file mode 100644 index 000000000000..ed553a2a7351 --- /dev/null +++ b/coverage-libs/lepton/ExpressionProgram.cpp.gcov.html @@ -0,0 +1,221 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionProgram.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionProgram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0520.0 %
Date:2024-02-22 21:58:47Functions:0120.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * -------------------------------------------------------------------------- *
+       3             :  *                                   Lepton                                   *
+       4             :  * -------------------------------------------------------------------------- *
+       5             :  * This is part of the Lepton expression parser originating from              *
+       6             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+       7             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+       8             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+       9             :  *                                                                            *
+      10             :  * Portions copyright (c) 2013-2016 Stanford University and the Authors.      *
+      11             :  * Authors: Peter Eastman                                                     *
+      12             :  * Contributors:                                                              *
+      13             :  *                                                                            *
+      14             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      15             :  * copy of this software and associated documentation files (the "Software"), *
+      16             :  * to deal in the Software without restriction, including without limitation  *
+      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      18             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      19             :  * Software is furnished to do so, subject to the following conditions:       *
+      20             :  *                                                                            *
+      21             :  * The above copyright notice and this permission notice shall be included in *
+      22             :  * all copies or substantial portions of the Software.                        *
+      23             :  *                                                                            *
+      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      27             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      28             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      29             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      30             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      31             :  * -------------------------------------------------------------------------- *
+      32             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      33             : /* -------------------------------------------------------------------------- *
+      34             :  *                                   lepton                                   *
+      35             :  * -------------------------------------------------------------------------- *
+      36             :  * This is part of the lepton expression parser originating from              *
+      37             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+      38             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+      39             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+      40             :  *                                                                            *
+      41             :  * Portions copyright (c) 2009-2018 Stanford University and the Authors.      *
+      42             :  * Authors: Peter Eastman                                                     *
+      43             :  * Contributors:                                                              *
+      44             :  *                                                                            *
+      45             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      46             :  * copy of this software and associated documentation files (the "Software"), *
+      47             :  * to deal in the Software without restriction, including without limitation  *
+      48             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      49             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      50             :  * Software is furnished to do so, subject to the following conditions:       *
+      51             :  *                                                                            *
+      52             :  * The above copyright notice and this permission notice shall be included in *
+      53             :  * all copies or substantial portions of the Software.                        *
+      54             :  *                                                                            *
+      55             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      56             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      57             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      58             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      59             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      60             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      61             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      62             :  * -------------------------------------------------------------------------- */
+      63             : 
+      64             : #include "ExpressionProgram.h"
+      65             : #include "Operation.h"
+      66             : #include "ParsedExpression.h"
+      67             : 
+      68             : namespace PLMD {
+      69             : using namespace lepton;
+      70             : using namespace std;
+      71             : 
+      72           0 : ExpressionProgram::ExpressionProgram() : maxArgs(0), stackSize(0) {
+      73           0 : }
+      74             : 
+      75           0 : ExpressionProgram::ExpressionProgram(const ParsedExpression& expression) : maxArgs(0), stackSize(0) {
+      76           0 :     buildProgram(expression.getRootNode());
+      77             :     int currentStackSize = 0;
+      78           0 :     for (int i = 0; i < (int) operations.size(); i++) {
+      79           0 :         int args = operations[i]->getNumArguments();
+      80           0 :         if (args > maxArgs)
+      81           0 :             maxArgs = args;
+      82           0 :         currentStackSize += 1-args;
+      83           0 :         if (currentStackSize > stackSize)
+      84           0 :             stackSize = currentStackSize;
+      85             :     }
+      86           0 : }
+      87             : 
+      88           0 : ExpressionProgram::~ExpressionProgram() {
+      89           0 :     for (int i = 0; i < (int) operations.size(); i++)
+      90           0 :         delete operations[i];
+      91           0 : }
+      92             : 
+      93           0 : ExpressionProgram::ExpressionProgram(const ExpressionProgram& program) {
+      94           0 :     *this = program;
+      95           0 : }
+      96             : 
+      97           0 : ExpressionProgram& ExpressionProgram::operator=(const ExpressionProgram& program) {
+      98           0 :     maxArgs = program.maxArgs;
+      99           0 :     stackSize = program.stackSize;
+     100           0 :     operations.resize(program.operations.size());
+     101           0 :     for (int i = 0; i < (int) operations.size(); i++)
+     102           0 :         operations[i] = program.operations[i]->clone();
+     103           0 :     return *this;
+     104             : }
+     105             : 
+     106           0 : void ExpressionProgram::buildProgram(const ExpressionTreeNode& node) {
+     107           0 :     for (int i = (int) node.getChildren().size()-1; i >= 0; i--)
+     108           0 :         buildProgram(node.getChildren()[i]);
+     109           0 :     operations.push_back(node.getOperation().clone());
+     110           0 : }
+     111             : 
+     112           0 : int ExpressionProgram::getNumOperations() const {
+     113           0 :     return (int) operations.size();
+     114             : }
+     115             : 
+     116           0 : const Operation& ExpressionProgram::getOperation(int index) const {
+     117           0 :     return *operations[index];
+     118             : }
+     119             : 
+     120           0 : void ExpressionProgram::setOperation(int index, Operation* operation) {
+     121           0 :     delete operations[index];
+     122           0 :     operations[index] = operation;
+     123           0 : }
+     124             : 
+     125           0 : int ExpressionProgram::getStackSize() const {
+     126           0 :     return stackSize;
+     127             : }
+     128             : 
+     129           0 : double ExpressionProgram::evaluate() const {
+     130           0 :     return evaluate(map<string, double>());
+     131             : }
+     132             : 
+     133           0 : double ExpressionProgram::evaluate(const std::map<std::string, double>& variables) const {
+     134           0 :     vector<double> stack(stackSize+1);
+     135           0 :     int stackPointer = stackSize;
+     136           0 :     for (int i = 0; i < (int) operations.size(); i++) {
+     137           0 :         int numArgs = operations[i]->getNumArguments();
+     138           0 :         double result = operations[i]->evaluate(&stack[stackPointer], variables);
+     139           0 :         stackPointer += numArgs-1;
+     140           0 :         stack[stackPointer] = result;
+     141             :     }
+     142           0 :     return stack[stackSize-1];
+     143             : }
+     144             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionTreeNode.cpp.func-sort-c.html b/coverage-libs/lepton/ExpressionTreeNode.cpp.func-sort-c.html new file mode 100644 index 000000000000..e8937a308a13 --- /dev/null +++ b/coverage-libs/lepton/ExpressionTreeNode.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionTreeNode.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionTreeNode.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:687294.4 %
Date:2024-02-22 21:58:47Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_4104
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_S5_8433
_ZN4PLMD6lepton18ExpressionTreeNodeC2EOS1_31689
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKSt6vectorIS1_SaIS1_EE57700
_ZN4PLMD6lepton18ExpressionTreeNodeaSERKS1_64603
_ZNK4PLMD6lepton18ExpressionTreeNode10assignTagsERSt6vectorIPKS1_SaIS4_EE79706
_ZNK4PLMD6lepton18ExpressionTreeNodeeqERKS1_86035
_ZNK4PLMD6lepton18ExpressionTreeNodeneERKS1_119413
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationE2021173
_ZN4PLMD6lepton18ExpressionTreeNodeaSEOS1_2094661
_ZN4PLMD6lepton18ExpressionTreeNodeC2Ev2136840
_ZN4PLMD6lepton18ExpressionTreeNodeC2ERKS1_2753562
_ZNK4PLMD6lepton18ExpressionTreeNode12getOperationEv4894636
_ZNK4PLMD6lepton18ExpressionTreeNode11getChildrenEv5837189
_ZN4PLMD6lepton18ExpressionTreeNodeD2Ev7013501
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html b/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html new file mode 100644 index 000000000000..1db2cbb03d9c --- /dev/null +++ b/coverage-libs/lepton/ExpressionTreeNode.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionTreeNode.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionTreeNode.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:687294.4 %
Date:2024-02-22 21:58:47Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton18ExpressionTreeNodeC2EOS1_31689
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationE2021173
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_4104
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKS1_S5_8433
_ZN4PLMD6lepton18ExpressionTreeNodeC2EPNS0_9OperationERKSt6vectorIS1_SaIS1_EE57700
_ZN4PLMD6lepton18ExpressionTreeNodeC2ERKS1_2753562
_ZN4PLMD6lepton18ExpressionTreeNodeC2Ev2136840
_ZN4PLMD6lepton18ExpressionTreeNodeD2Ev7013501
_ZN4PLMD6lepton18ExpressionTreeNodeaSEOS1_2094661
_ZN4PLMD6lepton18ExpressionTreeNodeaSERKS1_64603
_ZNK4PLMD6lepton18ExpressionTreeNode10assignTagsERSt6vectorIPKS1_SaIS4_EE79706
_ZNK4PLMD6lepton18ExpressionTreeNode11getChildrenEv5837189
_ZNK4PLMD6lepton18ExpressionTreeNode12getOperationEv4894636
_ZNK4PLMD6lepton18ExpressionTreeNodeeqERKS1_86035
_ZNK4PLMD6lepton18ExpressionTreeNodeneERKS1_119413
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html b/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html new file mode 100644 index 000000000000..655680703c21 --- /dev/null +++ b/coverage-libs/lepton/ExpressionTreeNode.cpp.gcov.html @@ -0,0 +1,264 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ExpressionTreeNode.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ExpressionTreeNode.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:687294.4 %
Date:2024-02-22 21:58:47Functions:1515100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * -------------------------------------------------------------------------- *
+       3             :  *                                   Lepton                                   *
+       4             :  * -------------------------------------------------------------------------- *
+       5             :  * This is part of the Lepton expression parser originating from              *
+       6             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+       7             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+       8             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+       9             :  *                                                                            *
+      10             :  * Portions copyright (c) 2013-2016 Stanford University and the Authors.      *
+      11             :  * Authors: Peter Eastman                                                     *
+      12             :  * Contributors:                                                              *
+      13             :  *                                                                            *
+      14             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      15             :  * copy of this software and associated documentation files (the "Software"), *
+      16             :  * to deal in the Software without restriction, including without limitation  *
+      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      18             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      19             :  * Software is furnished to do so, subject to the following conditions:       *
+      20             :  *                                                                            *
+      21             :  * The above copyright notice and this permission notice shall be included in *
+      22             :  * all copies or substantial portions of the Software.                        *
+      23             :  *                                                                            *
+      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      27             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      28             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      29             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      30             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      31             :  * -------------------------------------------------------------------------- *
+      32             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      33             : /* -------------------------------------------------------------------------- *
+      34             :  *                                   lepton                                   *
+      35             :  * -------------------------------------------------------------------------- *
+      36             :  * This is part of the lepton expression parser originating from              *
+      37             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+      38             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+      39             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+      40             :  *                                                                            *
+      41             :  * Portions copyright (c) 2009-2021 Stanford University and the Authors.      *
+      42             :  * Authors: Peter Eastman                                                     *
+      43             :  * Contributors:                                                              *
+      44             :  *                                                                            *
+      45             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      46             :  * copy of this software and associated documentation files (the "Software"), *
+      47             :  * to deal in the Software without restriction, including without limitation  *
+      48             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      49             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      50             :  * Software is furnished to do so, subject to the following conditions:       *
+      51             :  *                                                                            *
+      52             :  * The above copyright notice and this permission notice shall be included in *
+      53             :  * all copies or substantial portions of the Software.                        *
+      54             :  *                                                                            *
+      55             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      56             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      57             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      58             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      59             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      60             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      61             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      62             :  * -------------------------------------------------------------------------- */
+      63             : 
+      64             : #include "ExpressionTreeNode.h"
+      65             : #include "Exception.h"
+      66             : #include "Operation.h"
+      67             : #include <utility>
+      68             : 
+      69             : namespace PLMD {
+      70             : using namespace lepton;
+      71             : using namespace std;
+      72             : 
+      73       57700 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const vector<ExpressionTreeNode>& children) : operation(operation), children(children) {
+      74       57700 :     if (operation->getNumArguments() != children.size())
+      75           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      76       57700 : }
+      77             : 
+      78        8433 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const ExpressionTreeNode& child1, const ExpressionTreeNode& child2) : operation(operation) {
+      79        8433 :     children.push_back(child1);
+      80        8433 :     children.push_back(child2);
+      81        8433 :     if (operation->getNumArguments() != children.size())
+      82           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      83        8433 : }
+      84             : 
+      85        4104 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation, const ExpressionTreeNode& child) : operation(operation) {
+      86        4104 :     children.push_back(child);
+      87        4104 :     if (operation->getNumArguments() != children.size())
+      88           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      89        4104 : }
+      90             : 
+      91     2021173 : ExpressionTreeNode::ExpressionTreeNode(Operation* operation) : operation(operation) {
+      92     2021173 :     if (operation->getNumArguments() != children.size())
+      93           0 :         throw Exception("wrong number of arguments to function: "+operation->getName());
+      94     2021173 : }
+      95             : 
+      96     2753562 : ExpressionTreeNode::ExpressionTreeNode(const ExpressionTreeNode& node) : operation(node.operation == NULL ? NULL : node.operation->clone()), children(node.getChildren()) {
+      97     2753562 : }
+      98             : 
+      99       31689 : ExpressionTreeNode::ExpressionTreeNode(ExpressionTreeNode&& node) : operation(node.operation), children(move(node.children)) {
+     100       31689 :     node.operation = NULL;
+     101             :     node.children.clear();
+     102       31689 : }
+     103             : 
+     104     2136840 : ExpressionTreeNode::ExpressionTreeNode() : operation(NULL) {
+     105     2136840 : }
+     106             : 
+     107     7013501 : ExpressionTreeNode::~ExpressionTreeNode() {
+     108     7013501 :     if (operation != NULL)
+     109     4887083 :         delete operation;
+     110     7013501 : }
+     111             : 
+     112      119413 : bool ExpressionTreeNode::operator!=(const ExpressionTreeNode& node) const {
+     113      119413 :     if (node.getOperation() != getOperation())
+     114             :         return true;
+     115       61697 :     if (getOperation().isSymmetric() && getChildren().size() == 2) {
+     116        9882 :         if (getChildren()[0] == node.getChildren()[0] && getChildren()[1] == node.getChildren()[1])
+     117             :             return false;
+     118        3556 :         if (getChildren()[0] == node.getChildren()[1] && getChildren()[1] == node.getChildren()[0])
+     119             :             return false;
+     120        3556 :         return true;
+     121             :     }
+     122       82904 :     for (int i = 0; i < (int) getChildren().size(); i++)
+     123       33378 :         if (getChildren()[i] != node.getChildren()[i])
+     124             :             return true;
+     125             :     return false;
+     126             : }
+     127             : 
+     128       86035 : bool ExpressionTreeNode::operator==(const ExpressionTreeNode& node) const {
+     129       86035 :     return !(*this != node);
+     130             : }
+     131             : 
+     132       64603 : ExpressionTreeNode& ExpressionTreeNode::operator=(const ExpressionTreeNode& node) {
+     133       64603 :     if (operation != NULL)
+     134       11673 :         delete operation;
+     135       64603 :     operation = node.getOperation().clone();
+     136       64603 :     children = node.getChildren();
+     137       64603 :     return *this;
+     138             : }
+     139             : 
+     140     2094661 : ExpressionTreeNode& ExpressionTreeNode::operator=(ExpressionTreeNode&& node) {
+     141     2094661 :     if (operation != NULL)
+     142       10819 :         delete operation;
+     143     2094661 :     operation = node.operation;
+     144     2094661 :     children = move(node.children);
+     145     2094661 :     node.operation = NULL;
+     146             :     node.children.clear();
+     147     2094661 :     return *this;
+     148             : }
+     149             : 
+     150     4894636 : const Operation& ExpressionTreeNode::getOperation() const {
+     151     4894636 :     return *operation;
+     152             : }
+     153             : 
+     154     5837189 : const vector<ExpressionTreeNode>& ExpressionTreeNode::getChildren() const {
+     155     5837189 :     return children;
+     156             : }
+     157             : 
+     158       79706 : void ExpressionTreeNode::assignTags(vector<const ExpressionTreeNode*>& examples) const {
+     159             :     // Assign tag values to all nodes in a tree, such that two nodes have the same
+     160             :     // tag if and only if they (and all their children) are equal.  This is used to
+     161             :     // optimize other operations.
+     162             : 
+     163       79706 :     int numTags = examples.size();
+     164      153265 :     for (const ExpressionTreeNode& child : getChildren())
+     165       73559 :         child.assignTags(examples);
+     166       79706 :     if (numTags == examples.size()) {
+     167             :         // All the children matched existing tags, so possibly this node does too.
+     168             :         
+     169      226626 :         for (int i = 0; i < examples.size(); i++) {
+     170      206772 :             const ExpressionTreeNode& example = *examples[i];
+     171      206772 :             bool matches = (getChildren().size() == example.getChildren().size() && getOperation() == example.getOperation());
+     172      232773 :             for (int j = 0; matches && j < getChildren().size(); j++)
+     173       26001 :                 if (getChildren()[j].tag != example.getChildren()[j].tag)
+     174             :                     matches = false;
+     175      206772 :             if (matches) {
+     176       30735 :                 tag = i;
+     177       30735 :                 return;
+     178             :             }
+     179             :         }
+     180             :     }
+     181             :     
+     182             :     // This node does not match any previous node, so assign a new tag.
+     183             :     
+     184       48971 :     tag = examples.size();
+     185       48971 :     examples.push_back(this);
+     186             : }
+     187             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.cpp.func-sort-c.html b/coverage-libs/lepton/Operation.cpp.func-sort-c.html new file mode 100644 index 000000000000..f9f5291d39a3 --- /dev/null +++ b/coverage-libs/lepton/Operation.cpp.func-sort-c.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:26731584.8 %
Date:2024-02-22 21:58:47Functions:535793.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6lepton9Operation11AddConstant13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD6lepton9Operation13PowerConstant13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD6lepton9Operation16MultiplyConstant13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD6lepton9Operation6Custom13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD6lepton9Operation10Reciprocal13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Cot13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Csc13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Erf13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Log13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Sec13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Tan13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Acos13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Acot13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Acsc13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Asec13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Asin13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Atan13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Ceil13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Cosh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Coth13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Csch13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Cube13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Erfc13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Sech13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Sinh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Tanh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Acosh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Acoth13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Acsch13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Asech13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Asinh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Atanh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Delta13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Floor13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation6Square13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation8Nandelta13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Abs13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZNK4PLMD6lepton9Operation3Exp13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZNK4PLMD6lepton9Operation3Max13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZNK4PLMD6lepton9Operation3Min13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZNK4PLMD6lepton9Operation5Atan213differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD6lepton9Operation6Negate13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11
_ZNK4PLMD6lepton9Operation6Select13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE12
_ZNK4PLMD6lepton9Operation4Step13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13
_ZNK4PLMD6lepton9Operation4Sqrt13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE41
_ZNK4PLMD6lepton9Operation3Sin13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE56
_ZNK4PLMD6lepton9Operation5Power13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE111
_ZNK4PLMD6lepton9Operation6Divide13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE128
_ZNK4PLMD6lepton9Operation3Cos13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE198
_ZNK4PLMD6lepton9Operation3Erf8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Erfc8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation8Subtract13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE340
_ZNK4PLMD6lepton9Operation3Add13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE577
_ZNK4PLMD6lepton9Operation8Constant13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1114
_ZNK4PLMD6lepton9Operation8Variable13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1120
_ZNK4PLMD6lepton9Operation8Multiply13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1226
_ZN4PLMDL6isZeroERKNS_6lepton18ExpressionTreeNodeE4762
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.cpp.func.html b/coverage-libs/lepton/Operation.cpp.func.html new file mode 100644 index 000000000000..4ae1c88f2ce5 --- /dev/null +++ b/coverage-libs/lepton/Operation.cpp.func.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:26731584.8 %
Date:2024-02-22 21:58:47Functions:535793.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDL6isZeroERKNS_6lepton18ExpressionTreeNodeE4762
_ZNK4PLMD6lepton9Operation10Reciprocal13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation11AddConstant13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD6lepton9Operation13PowerConstant13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD6lepton9Operation16MultiplyConstant13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD6lepton9Operation3Abs13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZNK4PLMD6lepton9Operation3Add13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE577
_ZNK4PLMD6lepton9Operation3Cos13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE198
_ZNK4PLMD6lepton9Operation3Cot13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Csc13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Erf13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Erf8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation3Exp13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZNK4PLMD6lepton9Operation3Log13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Max13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZNK4PLMD6lepton9Operation3Min13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZNK4PLMD6lepton9Operation3Sec13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation3Sin13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE56
_ZNK4PLMD6lepton9Operation3Tan13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Acos13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Acot13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Acsc13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Asec13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Asin13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Atan13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Ceil13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Cosh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Coth13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Csch13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Cube13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Erfc13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Erfc8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Sech13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Sinh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation4Sqrt13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE41
_ZNK4PLMD6lepton9Operation4Step13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13
_ZNK4PLMD6lepton9Operation4Tanh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Acosh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Acoth13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Acsch13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Asech13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Asinh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Atan213differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD6lepton9Operation5Atanh13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Delta13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Floor13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation5Power13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE111
_ZNK4PLMD6lepton9Operation6Custom13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD6lepton9Operation6Divide13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE128
_ZNK4PLMD6lepton9Operation6Negate13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11
_ZNK4PLMD6lepton9Operation6Select13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE12
_ZNK4PLMD6lepton9Operation6Square13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation8Constant13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1114
_ZNK4PLMD6lepton9Operation8Multiply13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1226
_ZNK4PLMD6lepton9Operation8Nandelta13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD6lepton9Operation8Subtract13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE340
_ZNK4PLMD6lepton9Operation8Variable13differentiateERKSt6vectorINS0_18ExpressionTreeNodeESaIS4_EES8_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1120
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.cpp.gcov.html b/coverage-libs/lepton/Operation.cpp.gcov.html new file mode 100644 index 000000000000..74208dfb9d39 --- /dev/null +++ b/coverage-libs/lepton/Operation.cpp.gcov.html @@ -0,0 +1,747 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:26731584.8 %
Date:2024-02-22 21:58:47Functions:535793.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * -------------------------------------------------------------------------- *
+       3             :  *                                   Lepton                                   *
+       4             :  * -------------------------------------------------------------------------- *
+       5             :  * This is part of the Lepton expression parser originating from              *
+       6             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+       7             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+       8             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+       9             :  *                                                                            *
+      10             :  * Portions copyright (c) 2013-2016 Stanford University and the Authors.      *
+      11             :  * Authors: Peter Eastman                                                     *
+      12             :  * Contributors:                                                              *
+      13             :  *                                                                            *
+      14             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      15             :  * copy of this software and associated documentation files (the "Software"), *
+      16             :  * to deal in the Software without restriction, including without limitation  *
+      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      18             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      19             :  * Software is furnished to do so, subject to the following conditions:       *
+      20             :  *                                                                            *
+      21             :  * The above copyright notice and this permission notice shall be included in *
+      22             :  * all copies or substantial portions of the Software.                        *
+      23             :  *                                                                            *
+      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      27             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      28             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      29             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      30             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      31             :  * -------------------------------------------------------------------------- *
+      32             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      33             : 
+      34             : /* -------------------------------------------------------------------------- *
+      35             :  *                                   lepton                                   *
+      36             :  * -------------------------------------------------------------------------- *
+      37             :  * This is part of the lepton expression parser originating from              *
+      38             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+      39             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+      40             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+      41             :  *                                                                            *
+      42             :  * Portions copyright (c) 2009-2021 Stanford University and the Authors.      *
+      43             :  * Authors: Peter Eastman                                                     *
+      44             :  * Contributors:                                                              *
+      45             :  *                                                                            *
+      46             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      47             :  * copy of this software and associated documentation files (the "Software"), *
+      48             :  * to deal in the Software without restriction, including without limitation  *
+      49             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      50             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      51             :  * Software is furnished to do so, subject to the following conditions:       *
+      52             :  *                                                                            *
+      53             :  * The above copyright notice and this permission notice shall be included in *
+      54             :  * all copies or substantial portions of the Software.                        *
+      55             :  *                                                                            *
+      56             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      57             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      58             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      59             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      60             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      61             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      62             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      63             :  * -------------------------------------------------------------------------- */
+      64             : 
+      65             : #include "Operation.h"
+      66             : #include "ExpressionTreeNode.h"
+      67             : #include "MSVC_erfc.h"
+      68             : 
+      69             : namespace PLMD {
+      70             : using namespace lepton;
+      71             : using namespace std;
+      72             : 
+      73        4762 : static bool isZero(const ExpressionTreeNode& node) {
+      74        4762 :     if (node.getOperation().getId() != Operation::CONSTANT)
+      75             :         return false;
+      76        2791 :     return dynamic_cast<const Operation::Constant&>(node.getOperation()).getValue() == 0.0;
+      77             : }
+      78             : 
+      79         202 : double Operation::Erf::evaluate(double* args, const map<string, double>& variables) const {
+      80         202 :     return erf(args[0]);
+      81             : }
+      82             : 
+      83         202 : double Operation::Erfc::evaluate(double* args, const map<string, double>& variables) const {
+      84         202 :     return erfc(args[0]);
+      85             : }
+      86             : 
+      87        1114 : ExpressionTreeNode Operation::Constant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+      88        1114 :     return ExpressionTreeNode(new Operation::Constant(0.0));
+      89             : }
+      90             : 
+      91        1120 : ExpressionTreeNode Operation::Variable::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+      92        1120 :     if (variable == name)
+      93         595 :         return ExpressionTreeNode(new Operation::Constant(1.0));
+      94         525 :     return ExpressionTreeNode(new Operation::Constant(0.0));
+      95             : }
+      96             : 
+      97           0 : ExpressionTreeNode Operation::Custom::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+      98           0 :     if (function->getNumArguments() == 0)
+      99           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     100           0 :     ExpressionTreeNode result;
+     101             :     bool foundTerm = false;
+     102           0 :     for (int i = 0; i < getNumArguments(); i++) {
+     103           0 :         if (!isZero(childDerivs[i])) {
+     104           0 :             if (foundTerm)
+     105           0 :                 result = ExpressionTreeNode(new Operation::Add(),
+     106             :                                             result,
+     107           0 :                                             ExpressionTreeNode(new Operation::Multiply(), ExpressionTreeNode(new Operation::Custom(*this, i), children), childDerivs[i]));
+     108             :             else {
+     109           0 :                 result = ExpressionTreeNode(new Operation::Multiply(), ExpressionTreeNode(new Operation::Custom(*this, i), children), childDerivs[i]);
+     110             :                 foundTerm = true;
+     111             :             }
+     112             :         }
+     113             :     }
+     114           0 :     if (foundTerm)
+     115           0 :         return result;
+     116           0 :     return ExpressionTreeNode(new Operation::Constant(0.0));
+     117           0 : }
+     118             : 
+     119         577 : ExpressionTreeNode Operation::Add::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     120         577 :     if (isZero(childDerivs[0]))
+     121         124 :         return childDerivs[1];
+     122         453 :     if (isZero(childDerivs[1]))
+     123         360 :         return childDerivs[0];
+     124          93 :     return ExpressionTreeNode(new Operation::Add(), childDerivs[0], childDerivs[1]);
+     125             : }
+     126             : 
+     127         340 : ExpressionTreeNode Operation::Subtract::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     128         340 :     if (isZero(childDerivs[0])) {
+     129          75 :         if (isZero(childDerivs[1]))
+     130          60 :             return ExpressionTreeNode(new Operation::Constant(0.0));
+     131          15 :         return ExpressionTreeNode(new Operation::Negate(), childDerivs[1]);
+     132             :     }
+     133         265 :     if (isZero(childDerivs[1]))
+     134          66 :         return childDerivs[0];
+     135         199 :     return ExpressionTreeNode(new Operation::Subtract(), childDerivs[0], childDerivs[1]);
+     136             : }
+     137             : 
+     138        1226 : ExpressionTreeNode Operation::Multiply::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     139        1226 :     if (isZero(childDerivs[0])) {
+     140         902 :         if (isZero(childDerivs[1]))
+     141         313 :             return ExpressionTreeNode(new Operation::Constant(0.0));
+     142         589 :         return ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]);
+     143             :     }
+     144         324 :     if (isZero(childDerivs[1]))
+     145          26 :         return ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]);
+     146         298 :     return ExpressionTreeNode(new Operation::Add(),
+     147         596 :                               ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]),
+     148         894 :                               ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]));
+     149             : }
+     150             : 
+     151         128 : ExpressionTreeNode Operation::Divide::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     152         128 :     ExpressionTreeNode subexp;
+     153         128 :     if (isZero(childDerivs[0])) {
+     154          99 :         if (isZero(childDerivs[1]))
+     155          68 :             return ExpressionTreeNode(new Operation::Constant(0.0));
+     156          31 :         subexp = ExpressionTreeNode(new Operation::Negate(), ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]));
+     157             :     }
+     158          29 :     else if (isZero(childDerivs[1]))
+     159          16 :         subexp = ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]);
+     160             :     else
+     161          26 :         subexp = ExpressionTreeNode(new Operation::Subtract(),
+     162          26 :                                                  ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]),
+     163          39 :                                                  ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1]));
+     164          60 :     return ExpressionTreeNode(new Operation::Divide(), subexp, ExpressionTreeNode(new Operation::Square(), children[1]));
+     165         128 : }
+     166             : 
+     167         111 : ExpressionTreeNode Operation::Power::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     168         111 :     return ExpressionTreeNode(new Operation::Add(),
+     169         222 :                               ExpressionTreeNode(new Operation::Multiply(),
+     170         222 :                                                  ExpressionTreeNode(new Operation::Multiply(),
+     171             :                                                                     children[1],
+     172         222 :                                                                     ExpressionTreeNode(new Operation::Power(),
+     173         222 :                                                                                        children[0], ExpressionTreeNode(new Operation::AddConstant(-1.0), children[1]))),
+     174             :                                                  childDerivs[0]),
+     175         222 :                               ExpressionTreeNode(new Operation::Multiply(),
+     176         222 :                                                  ExpressionTreeNode(new Operation::Multiply(),
+     177         222 :                                                                     ExpressionTreeNode(new Operation::Log(), children[0]),
+     178         222 :                                                                     ExpressionTreeNode(new Operation::Power(), children[0], children[1])),
+     179         222 :                                                  childDerivs[1]));
+     180             : }
+     181             : 
+     182          11 : ExpressionTreeNode Operation::Negate::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     183          11 :     if (isZero(childDerivs[0]))
+     184           3 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     185           8 :     return ExpressionTreeNode(new Operation::Negate(), childDerivs[0]);
+     186             : }
+     187             : 
+     188          41 : ExpressionTreeNode Operation::Sqrt::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     189          41 :     if (isZero(childDerivs[0]))
+     190           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     191          41 :     return ExpressionTreeNode(new Operation::Multiply(),
+     192          82 :                               ExpressionTreeNode(new Operation::MultiplyConstant(0.5),
+     193          82 :                                                  ExpressionTreeNode(new Operation::Reciprocal(),
+     194          82 :                                                                     ExpressionTreeNode(new Operation::Sqrt(), children[0]))),
+     195          41 :                               childDerivs[0]);
+     196             : }
+     197             : 
+     198           3 : ExpressionTreeNode Operation::Exp::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     199           3 :     if (isZero(childDerivs[0]))
+     200           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     201           3 :     return ExpressionTreeNode(new Operation::Multiply(),
+     202           6 :                               ExpressionTreeNode(new Operation::Exp(), children[0]),
+     203           3 :                               childDerivs[0]);
+     204             : }
+     205             : 
+     206           2 : ExpressionTreeNode Operation::Log::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     207           2 :     if (isZero(childDerivs[0]))
+     208           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     209           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     210           4 :                               ExpressionTreeNode(new Operation::Reciprocal(), children[0]),
+     211           2 :                               childDerivs[0]);
+     212             : }
+     213             : 
+     214          56 : ExpressionTreeNode Operation::Sin::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     215          56 :     if (isZero(childDerivs[0]))
+     216           2 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     217          54 :     return ExpressionTreeNode(new Operation::Multiply(),
+     218         108 :                               ExpressionTreeNode(new Operation::Cos(), children[0]),
+     219          54 :                               childDerivs[0]);
+     220             : }
+     221             : 
+     222         198 : ExpressionTreeNode Operation::Cos::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     223         198 :     if (isZero(childDerivs[0]))
+     224           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     225         198 :     return ExpressionTreeNode(new Operation::Multiply(),
+     226         396 :                               ExpressionTreeNode(new Operation::Negate(),
+     227         396 :                                                  ExpressionTreeNode(new Operation::Sin(), children[0])),
+     228         198 :                               childDerivs[0]);
+     229             : }
+     230             : 
+     231           2 : ExpressionTreeNode Operation::Sec::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     232           2 :     if (isZero(childDerivs[0]))
+     233           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     234           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     235           4 :                               ExpressionTreeNode(new Operation::Multiply(),
+     236           4 :                                                  ExpressionTreeNode(new Operation::Sec(), children[0]),
+     237           4 :                                                  ExpressionTreeNode(new Operation::Tan(), children[0])),
+     238           2 :                               childDerivs[0]);
+     239             : }
+     240             : 
+     241           2 : ExpressionTreeNode Operation::Csc::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     242           2 :     if (isZero(childDerivs[0]))
+     243           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     244           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     245           4 :                               ExpressionTreeNode(new Operation::Negate(),
+     246           4 :                                                  ExpressionTreeNode(new Operation::Multiply(),
+     247           4 :                                                                     ExpressionTreeNode(new Operation::Csc(), children[0]),
+     248           4 :                                                                     ExpressionTreeNode(new Operation::Cot(), children[0]))),
+     249           2 :                               childDerivs[0]);
+     250             : }
+     251             : 
+     252           2 : ExpressionTreeNode Operation::Tan::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     253           2 :     if (isZero(childDerivs[0]))
+     254           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     255           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     256           4 :                               ExpressionTreeNode(new Operation::Square(),
+     257           4 :                                                  ExpressionTreeNode(new Operation::Sec(), children[0])),
+     258           2 :                               childDerivs[0]);
+     259             : }
+     260             : 
+     261           2 : ExpressionTreeNode Operation::Cot::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     262           2 :     if (isZero(childDerivs[0]))
+     263           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     264           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     265           4 :                               ExpressionTreeNode(new Operation::Negate(),
+     266           4 :                                                  ExpressionTreeNode(new Operation::Square(),
+     267           4 :                                                                     ExpressionTreeNode(new Operation::Csc(), children[0]))),
+     268           2 :                               childDerivs[0]);
+     269             : }
+     270             : 
+     271           2 : ExpressionTreeNode Operation::Asin::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     272           2 :     if (isZero(childDerivs[0]))
+     273           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     274           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     275           4 :                               ExpressionTreeNode(new Operation::Reciprocal(),
+     276           4 :                                                  ExpressionTreeNode(new Operation::Sqrt(),
+     277           4 :                                                                     ExpressionTreeNode(new Operation::Subtract(),
+     278           4 :                                                                                        ExpressionTreeNode(new Operation::Constant(1.0)),
+     279           4 :                                                                                        ExpressionTreeNode(new Operation::Square(), children[0])))),
+     280           2 :                               childDerivs[0]);
+     281             : }
+     282             : 
+     283           2 : ExpressionTreeNode Operation::Acos::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     284           2 :     if (isZero(childDerivs[0]))
+     285           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     286           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     287           4 :                               ExpressionTreeNode(new Operation::Negate(),
+     288           4 :                                                  ExpressionTreeNode(new Operation::Reciprocal(),
+     289           4 :                                                                     ExpressionTreeNode(new Operation::Sqrt(),
+     290           4 :                                                                                        ExpressionTreeNode(new Operation::Subtract(),
+     291           4 :                                                                                                           ExpressionTreeNode(new Operation::Constant(1.0)),
+     292           4 :                                                                                                           ExpressionTreeNode(new Operation::Square(), children[0]))))),
+     293           2 :                               childDerivs[0]);
+     294             : }
+     295             : 
+     296           2 : ExpressionTreeNode Operation::Atan::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     297           2 :     if (isZero(childDerivs[0]))
+     298           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     299           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     300           4 :                               ExpressionTreeNode(new Operation::Reciprocal(),
+     301           4 :                                                  ExpressionTreeNode(new Operation::AddConstant(1.0),
+     302           4 :                                                                     ExpressionTreeNode(new Operation::Square(), children[0]))),
+     303           2 :                               childDerivs[0]);
+     304             : }
+     305             : 
+     306           8 : ExpressionTreeNode Operation::Atan2::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     307           8 :     return ExpressionTreeNode(new Operation::Divide(),
+     308          16 :                               ExpressionTreeNode(new Operation::Subtract(),
+     309          16 :                                                  ExpressionTreeNode(new Operation::Multiply(), children[1], childDerivs[0]),
+     310          16 :                                                  ExpressionTreeNode(new Operation::Multiply(), children[0], childDerivs[1])),
+     311          16 :                               ExpressionTreeNode(new Operation::Add(),
+     312          16 :                                                  ExpressionTreeNode(new Operation::Square(), children[0]),
+     313          24 :                                                  ExpressionTreeNode(new Operation::Square(), children[1])));
+     314             : }
+     315             : 
+     316           2 : ExpressionTreeNode Operation::Sinh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     317           2 :     if (isZero(childDerivs[0]))
+     318           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     319           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     320           4 :                               ExpressionTreeNode(new Operation::Cosh(),
+     321             :                                                  children[0]),
+     322           2 :                               childDerivs[0]);
+     323             : }
+     324             : 
+     325           2 : ExpressionTreeNode Operation::Cosh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     326           2 :     if (isZero(childDerivs[0]))
+     327           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     328           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     329           4 :                               ExpressionTreeNode(new Operation::Sinh(),
+     330             :                                                  children[0]),
+     331           2 :                               childDerivs[0]);
+     332             : }
+     333             : 
+     334           2 : ExpressionTreeNode Operation::Tanh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     335           2 :     if (isZero(childDerivs[0]))
+     336           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     337           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     338           4 :                               ExpressionTreeNode(new Operation::Subtract(),
+     339           4 :                                                  ExpressionTreeNode(new Operation::Constant(1.0)),
+     340           4 :                                                  ExpressionTreeNode(new Operation::Square(),
+     341           4 :                                                                     ExpressionTreeNode(new Operation::Tanh(), children[0]))),
+     342           2 :                               childDerivs[0]);
+     343             : }
+     344             : 
+     345           2 : ExpressionTreeNode Operation::Erf::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     346           2 :     if (isZero(childDerivs[0]))
+     347           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     348           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     349           4 :                               ExpressionTreeNode(new Operation::Multiply(),
+     350           4 :                                                  ExpressionTreeNode(new Operation::Constant(2.0/sqrt(M_PI))),
+     351           4 :                                                  ExpressionTreeNode(new Operation::Exp(),
+     352           4 :                                                                     ExpressionTreeNode(new Operation::Negate(),
+     353           4 :                                                                                        ExpressionTreeNode(new Operation::Square(), children[0])))),
+     354           2 :                               childDerivs[0]);
+     355             : }
+     356             : 
+     357           2 : ExpressionTreeNode Operation::Erfc::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     358           2 :     if (isZero(childDerivs[0]))
+     359           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     360           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     361           4 :                               ExpressionTreeNode(new Operation::Multiply(),
+     362           4 :                                                  ExpressionTreeNode(new Operation::Constant(-2.0/sqrt(M_PI))),
+     363           4 :                                                  ExpressionTreeNode(new Operation::Exp(),
+     364           4 :                                                                     ExpressionTreeNode(new Operation::Negate(),
+     365           4 :                                                                                        ExpressionTreeNode(new Operation::Square(), children[0])))),
+     366           2 :                               childDerivs[0]);
+     367             : }
+     368             : 
+     369          13 : ExpressionTreeNode Operation::Step::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     370          13 :     return ExpressionTreeNode(new Operation::Delta(),children[0]);
+     371             : }
+     372             : 
+     373           2 : ExpressionTreeNode Operation::Delta::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     374           2 :     return ExpressionTreeNode(new Operation::Nandelta(), children[0]);
+     375             : }
+     376             : 
+     377           2 : ExpressionTreeNode Operation::Nandelta::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     378           2 :     return ExpressionTreeNode(new Operation::Nandelta(), children[0]);
+     379             : }
+     380             : 
+     381           2 : ExpressionTreeNode Operation::Square::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     382           2 :     if (isZero(childDerivs[0]))
+     383           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     384           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     385           4 :                               ExpressionTreeNode(new Operation::MultiplyConstant(2.0),
+     386             :                                                  children[0]),
+     387           2 :                               childDerivs[0]);
+     388             : }
+     389             : 
+     390           2 : ExpressionTreeNode Operation::Cube::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     391           2 :     if (isZero(childDerivs[0]))
+     392           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     393           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     394           4 :                               ExpressionTreeNode(new Operation::MultiplyConstant(3.0),
+     395           4 :                                                  ExpressionTreeNode(new Operation::Square(), children[0])),
+     396           2 :                               childDerivs[0]);
+     397             : }
+     398             : 
+     399           2 : ExpressionTreeNode Operation::Reciprocal::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     400           2 :     if (isZero(childDerivs[0]))
+     401           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     402           2 :     return ExpressionTreeNode(new Operation::Multiply(),
+     403           4 :                               ExpressionTreeNode(new Operation::Negate(),
+     404           4 :                                                  ExpressionTreeNode(new Operation::Reciprocal(),
+     405           4 :                                                                     ExpressionTreeNode(new Operation::Square(), children[0]))),
+     406           2 :                               childDerivs[0]);
+     407             : }
+     408             : 
+     409           0 : ExpressionTreeNode Operation::AddConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     410           0 :     return childDerivs[0];
+     411             : }
+     412             : 
+     413           0 : ExpressionTreeNode Operation::MultiplyConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     414           0 :     if (isZero(childDerivs[0]))
+     415           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     416           0 :     return ExpressionTreeNode(new Operation::MultiplyConstant(value),
+     417           0 :                               childDerivs[0]);
+     418             : }
+     419             : 
+     420           0 : ExpressionTreeNode Operation::PowerConstant::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     421           0 :     if (isZero(childDerivs[0]))
+     422           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     423           0 :     return ExpressionTreeNode(new Operation::Multiply(),
+     424           0 :                               ExpressionTreeNode(new Operation::MultiplyConstant(value),
+     425           0 :                                                  ExpressionTreeNode(new Operation::PowerConstant(value-1),
+     426             :                                                                     children[0])),
+     427           0 :                               childDerivs[0]);
+     428             : }
+     429             : 
+     430           4 : ExpressionTreeNode Operation::Min::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     431           4 :     ExpressionTreeNode step(new Operation::Step(),
+     432           8 :                             ExpressionTreeNode(new Operation::Subtract(), children[0], children[1]));
+     433          20 :     return ExpressionTreeNode(new Operation::Select(), {step, childDerivs[1], childDerivs[0]});
+     434           4 : }
+     435             : 
+     436           4 : ExpressionTreeNode Operation::Max::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     437           4 :     ExpressionTreeNode step(new Operation::Step(),
+     438           8 :                             ExpressionTreeNode(new Operation::Subtract(), children[0], children[1]));
+     439          20 :     return ExpressionTreeNode(new Operation::Select(), {step, childDerivs[0], childDerivs[1]});
+     440           4 : }
+     441             : 
+     442           3 : ExpressionTreeNode Operation::Abs::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     443           3 :     if (isZero(childDerivs[0]))
+     444           0 :         return ExpressionTreeNode(new Operation::Constant(0.0));
+     445           3 :     ExpressionTreeNode step(new Operation::Step(), children[0]);
+     446           3 :     return ExpressionTreeNode(new Operation::Multiply(),
+     447             :                               childDerivs[0],
+     448           6 :                               ExpressionTreeNode(new Operation::AddConstant(-1),
+     449           9 :                                                  ExpressionTreeNode(new Operation::MultiplyConstant(2), step)));
+     450           3 : }
+     451             : 
+     452           2 : ExpressionTreeNode Operation::Floor::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     453           2 :     return ExpressionTreeNode(new Operation::Constant(0.0));
+     454             : }
+     455             : 
+     456           2 : ExpressionTreeNode Operation::Ceil::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     457           2 :     return ExpressionTreeNode(new Operation::Constant(0.0));
+     458             : }
+     459             : 
+     460          12 : ExpressionTreeNode Operation::Select::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     461             :     vector<ExpressionTreeNode> derivChildren;
+     462          12 :     derivChildren.push_back(children[0]);
+     463          12 :     derivChildren.push_back(childDerivs[1]);
+     464          12 :     derivChildren.push_back(childDerivs[2]);
+     465          24 :     return ExpressionTreeNode(new Operation::Select(), derivChildren);
+     466          12 : }
+     467             : 
+     468             : #define LEPTON_CONST(x) ExpressionTreeNode(new Operation::Constant(x))
+     469             : #define LEPTON_OP1(name,x) ExpressionTreeNode(new Operation::name(),x)
+     470             : #define LEPTON_OP2(name,x,y) ExpressionTreeNode(new Operation::name(),x,y)
+     471             : #define LEPTON_ADD_CONST(x,y) ExpressionTreeNode(new Operation::AddConstant(x),y)
+     472             : 
+     473           2 : ExpressionTreeNode Operation::Acot::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     474             :     return
+     475           2 :       LEPTON_OP2(Multiply,
+     476             :         LEPTON_OP1(Negate,
+     477             :           LEPTON_OP1(Reciprocal,
+     478             :             LEPTON_ADD_CONST(1.0,
+     479             :               LEPTON_OP1(Square,children[0])
+     480             :             )
+     481             :           )
+     482             :         ),
+     483             :         childDerivs[0]
+     484             :       );
+     485             : }
+     486             : 
+     487           2 : ExpressionTreeNode Operation::Asec::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     488             :     return
+     489           2 :       LEPTON_OP2(Multiply,
+     490             :         LEPTON_OP1(Reciprocal,
+     491             :           LEPTON_OP2(Multiply,
+     492             :             LEPTON_OP1(Abs,children[0]),
+     493             :             LEPTON_OP1(Sqrt,
+     494             :               LEPTON_OP2(Subtract,
+     495             :                 LEPTON_OP1(Square,children[0]),
+     496             :                 LEPTON_CONST(1.0)
+     497             :               )
+     498             :             )
+     499             :           )
+     500             :         ),
+     501             :         childDerivs[0]
+     502             :       );
+     503             : }
+     504             : 
+     505           2 : ExpressionTreeNode Operation::Acsc::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     506             :     return
+     507           2 :     LEPTON_OP2(Multiply,
+     508             :       LEPTON_OP1(Negate,
+     509             :         LEPTON_OP1(Reciprocal,
+     510             :           LEPTON_OP2(Multiply,
+     511             :             LEPTON_OP1(Abs,children[0]),
+     512             :             LEPTON_OP1(Sqrt,
+     513             :               LEPTON_OP2(Subtract,
+     514             :                 LEPTON_OP1(Square,children[0]),
+     515             :                 LEPTON_CONST(1.0)
+     516             :               )
+     517             :             )
+     518             :           )
+     519             :         )
+     520             :       ),
+     521             :       childDerivs[0]
+     522             :     );
+     523             : }
+     524             : 
+     525           2 : ExpressionTreeNode Operation::Coth::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     526             :     return
+     527           2 :     LEPTON_OP2(Multiply,
+     528             :       LEPTON_OP2(Subtract,
+     529             :         LEPTON_CONST(1.0),
+     530             :         LEPTON_OP1(Square,
+     531             :           LEPTON_OP1(Coth,children[0])
+     532             :         )
+     533             :       ),
+     534             :       childDerivs[0]
+     535             :     );
+     536             : }
+     537             : 
+     538           2 : ExpressionTreeNode Operation::Sech::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     539             :     return
+     540           2 :     LEPTON_OP2(Multiply,
+     541             :       LEPTON_OP1(Negate,
+     542             :         LEPTON_OP2(Multiply,
+     543             :           LEPTON_OP1(Tanh,children[0]),
+     544             :           LEPTON_OP1(Sech,children[0])
+     545             :         )
+     546             :       ),
+     547             :       childDerivs[0]
+     548             :     );
+     549             : }
+     550             : 
+     551           2 : ExpressionTreeNode Operation::Csch::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     552             :     return
+     553           2 :     LEPTON_OP2(Multiply,
+     554             :       LEPTON_OP1(Negate,
+     555             :         LEPTON_OP2(Multiply,
+     556             :           LEPTON_OP1(Coth,children[0]),
+     557             :           LEPTON_OP1(Csch,children[0])
+     558             :         )
+     559             :       ),
+     560             :       childDerivs[0]
+     561             :     );
+     562             : }
+     563             : 
+     564           2 : ExpressionTreeNode Operation::Acosh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     565             :     return
+     566           2 :     LEPTON_OP2(Multiply,
+     567             :       LEPTON_OP1(Reciprocal,
+     568             :         LEPTON_OP1(Sqrt,
+     569             :           LEPTON_OP2(Subtract,
+     570             :             LEPTON_OP1(Square,children[0]),
+     571             :             LEPTON_CONST(1.0)
+     572             :           )
+     573             :         )
+     574             :       ),
+     575             :       childDerivs[0]
+     576             :     );
+     577             : }
+     578             : 
+     579           2 : ExpressionTreeNode Operation::Atanh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     580             :     return
+     581           2 :     LEPTON_OP2(Multiply,
+     582             :       LEPTON_OP1(Reciprocal,
+     583             :         LEPTON_OP2(Subtract,
+     584             :           LEPTON_CONST(1.0),
+     585             :           LEPTON_OP1(Square,children[0])
+     586             :         )
+     587             :       ),
+     588             :       childDerivs[0]
+     589             :     );
+     590             : }
+     591             : 
+     592           2 : ExpressionTreeNode Operation::Asinh::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     593             :     return
+     594           2 :     LEPTON_OP2(Multiply,
+     595             :       LEPTON_OP1(Reciprocal,
+     596             :         LEPTON_OP1(Sqrt,
+     597             :           LEPTON_ADD_CONST(1.0,
+     598             :             LEPTON_OP1(Square,children[0])
+     599             :           )
+     600             :         )
+     601             :       ),
+     602             :       childDerivs[0]
+     603             :     );
+     604             : }
+     605             : 
+     606           2 : ExpressionTreeNode Operation::Acoth::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     607             :     return
+     608           2 :     LEPTON_OP2(Multiply,
+     609             :       LEPTON_OP1(Reciprocal,
+     610             :         LEPTON_OP2(Subtract,
+     611             :           LEPTON_CONST(1.0),
+     612             :           LEPTON_OP1(Square,children[0])
+     613             :         )
+     614             :       ),
+     615             :       childDerivs[0]
+     616             :     );
+     617             : }
+     618             : 
+     619           2 : ExpressionTreeNode Operation::Asech::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     620             :     return
+     621           2 :     LEPTON_OP2(Multiply,
+     622             :       LEPTON_OP1(Negate,
+     623             :         LEPTON_OP1(Reciprocal,
+     624             :           LEPTON_OP2(Multiply,
+     625             :             children[0],
+     626             :             LEPTON_OP2(Multiply,
+     627             :               LEPTON_ADD_CONST(1.0,
+     628             :                 children[0]
+     629             :               ),
+     630             :               LEPTON_OP1(Sqrt,
+     631             :                 LEPTON_OP2(Divide,
+     632             :                   LEPTON_OP2(Subtract,
+     633             :                     LEPTON_CONST(1.0),
+     634             :                     children[0]
+     635             :                   ),
+     636             :                   LEPTON_ADD_CONST(1.0,
+     637             :                     children[0]
+     638             :                   )
+     639             :                 )
+     640             :               )
+     641             :             )
+     642             :           )
+     643             :         )
+     644             :       ),
+     645             :       childDerivs[0]
+     646             :     );
+     647             : }
+     648             : 
+     649           2 : ExpressionTreeNode Operation::Acsch::differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const {
+     650             :     return
+     651           2 :     LEPTON_OP2(Multiply,
+     652             :       LEPTON_OP1(Negate,
+     653             :         LEPTON_OP1(Reciprocal,
+     654             :           LEPTON_OP2(Multiply,
+     655             :             LEPTON_OP1(Square,children[0]),
+     656             :             LEPTON_OP1(Sqrt,
+     657             :               LEPTON_ADD_CONST(1.0,
+     658             :                 LEPTON_OP1(Reciprocal,
+     659             :                   LEPTON_OP1(Square,children[0])
+     660             :                 )
+     661             :               )
+     662             :             )
+     663             :           )
+     664             :         )
+     665             :       ),
+     666             :       childDerivs[0]
+     667             :     );
+     668             : }
+     669             : 
+     670             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.h.func-sort-c.html b/coverage-libs/lepton/Operation.h.func-sort-c.html new file mode 100644 index 000000000000..4d2a6d367fd1 --- /dev/null +++ b/coverage-libs/lepton/Operation.h.func-sort-c.html @@ -0,0 +1,1233 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:53055695.3 %
Date:2024-02-22 21:58:47Functions:28029096.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9Operation6CustomC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionE0
_ZN4PLMD6lepton9Operation6CustomC2ERKS2_i0
_ZN4PLMD6lepton9Operation6CustomD0Ev0
_ZN4PLMD6lepton9Operation6CustomD2Ev0
_ZNK4PLMD6lepton9Operation6Custom15getNumArgumentsEv0
_ZNK4PLMD6lepton9Operation6Custom5cloneEv0
_ZNK4PLMD6lepton9Operation6Custom5getIdEv0
_ZNK4PLMD6lepton9Operation6Custom7getNameB5cxx11Ev0
_ZNK4PLMD6lepton9Operation6Custom8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE0
_ZNK4PLMD6lepton9Operation6CustomneERKS1_0
_ZNK4PLMD6lepton9Operation3Erf7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation3Log7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Acos7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Acot7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Acsc7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Asec7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Asin7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Atan7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Ceil7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Erfc7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Acosh7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Acoth7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Acsch7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Asech7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Asinh7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Atanh7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Floor7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation3Cot7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Max7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Min7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Tan7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Cosh7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Csch7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Sech7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Sinh7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation5Power15isInfixOperatorEv4
_ZNK4PLMD6lepton9Operation5Power7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Csc7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation3Sec7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation4Coth7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation4Tanh7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation8Nandelta7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation5Atan27getNameB5cxx11Ev8
_ZNK4PLMD6lepton9Operation5Delta7getNameB5cxx11Ev8
_ZNK4PLMD6lepton9Operation4Step7getNameB5cxx11Ev17
_ZNK4PLMD6lepton9Operation3Abs7getNameB5cxx11Ev18
_ZNK4PLMD6lepton9Operation3Erf15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Acot15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Acsc15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Asec15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Ceil15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Erfc15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Acosh15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Acoth15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Acsch15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Asech15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Asinh15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Atanh15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Floor15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Acos15getNumArgumentsEv20
_ZNK4PLMD6lepton9Operation4Asin15getNumArgumentsEv20
_ZNK4PLMD6lepton9Operation4Atan15getNumArgumentsEv20
_ZNK4PLMD6lepton9Operation4Cube7getNameB5cxx11Ev23
_ZNK4PLMD6lepton9Operation6Select7getNameB5cxx11Ev24
_ZNK4PLMD6lepton9Operation3Exp7getNameB5cxx11Ev28
_ZNK4PLMD6lepton9Operation3Erf5cloneEv30
_ZNK4PLMD6lepton9Operation4Acot5cloneEv30
_ZNK4PLMD6lepton9Operation4Acsc5cloneEv30
_ZNK4PLMD6lepton9Operation4Asec5cloneEv30
_ZNK4PLMD6lepton9Operation4Ceil5cloneEv30
_ZNK4PLMD6lepton9Operation4Erfc5cloneEv30
_ZNK4PLMD6lepton9Operation5Acosh5cloneEv30
_ZNK4PLMD6lepton9Operation5Acoth5cloneEv30
_ZNK4PLMD6lepton9Operation5Acsch5cloneEv30
_ZNK4PLMD6lepton9Operation5Asech5cloneEv30
_ZNK4PLMD6lepton9Operation5Asinh5cloneEv30
_ZNK4PLMD6lepton9Operation5Atanh5cloneEv30
_ZNK4PLMD6lepton9Operation5Floor5cloneEv30
_ZNK4PLMD6lepton9Operation8Variable8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE30
_ZNK4PLMD6lepton9Operation4Acos5cloneEv34
_ZNK4PLMD6lepton9Operation4Asin5cloneEv34
_ZNK4PLMD6lepton9Operation4Atan5cloneEv34
_ZNK4PLMD6lepton9Operation3Cot15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation3Tan15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation4Cosh15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation4Csch15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation4Sech15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation4Sinh15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation13PowerConstant7getNameB5cxx11Ev37
_ZNK4PLMD6lepton9Operation3Erf5getIdEv40
_ZNK4PLMD6lepton9Operation4Acot5getIdEv40
_ZNK4PLMD6lepton9Operation4Acsc5getIdEv40
_ZNK4PLMD6lepton9Operation4Asec5getIdEv40
_ZNK4PLMD6lepton9Operation4Ceil5getIdEv40
_ZNK4PLMD6lepton9Operation4Erfc5getIdEv40
_ZNK4PLMD6lepton9Operation5Acosh5getIdEv40
_ZNK4PLMD6lepton9Operation5Acoth5getIdEv40
_ZNK4PLMD6lepton9Operation5Acsch5getIdEv40
_ZNK4PLMD6lepton9Operation5Asech5getIdEv40
_ZNK4PLMD6lepton9Operation5Asinh5getIdEv40
_ZNK4PLMD6lepton9Operation5Atanh5getIdEv40
_ZNK4PLMD6lepton9Operation5Floor5getIdEv40
_ZNK4PLMD6lepton9Operation3Max15getNumArgumentsEv44
_ZNK4PLMD6lepton9Operation3Min15getNumArgumentsEv44
_ZNK4PLMD6lepton9Operation4Acos5getIdEv46
_ZNK4PLMD6lepton9Operation4Asin5getIdEv46
_ZNK4PLMD6lepton9Operation4Atan5getIdEv46
_ZNK4PLMD6lepton9Operation6Divide15isInfixOperatorEv50
_ZNK4PLMD6lepton9Operation6Divide7getNameB5cxx11Ev50
_ZNK4PLMD6lepton9Operation8Nandelta15getNumArgumentsEv50
_ZNK4PLMD6lepton9Operation3Csc15getNumArgumentsEv54
_ZNK4PLMD6lepton9Operation3Sec15getNumArgumentsEv54
_ZNK4PLMD6lepton9Operation4Coth15getNumArgumentsEv54
_ZNK4PLMD6lepton9Operation4Tanh15getNumArgumentsEv54
_ZNK4PLMD6lepton9Operation3Max5cloneEv60
_ZNK4PLMD6lepton9Operation3Min5cloneEv60
_ZNK4PLMD6lepton9Operation6Negate7getNameB5cxx11Ev70
_ZNK4PLMD6lepton9Operation13PowerConstant15isInfixOperatorEv74
_ZNK4PLMD6lepton9Operation4Cosh5cloneEv78
_ZNK4PLMD6lepton9Operation4Sinh5cloneEv78
_ZNK4PLMD6lepton9Operation3Max5getIdEv80
_ZNK4PLMD6lepton9Operation3Min5getIdEv80
_ZNK4PLMD6lepton9Operation10Reciprocal7getNameB5cxx11Ev81
_ZNK4PLMD6lepton9Operation4Sqrt7getNameB5cxx11Ev83
_ZNK4PLMD6lepton9Operation4Cosh5getIdEv88
_ZNK4PLMD6lepton9Operation4Sinh5getIdEv88
_ZNK4PLMD6lepton9Operation5Atan215getNumArgumentsEv88
_ZNK4PLMD6lepton9Operation8Nandelta5cloneEv90
_ZNK4PLMD6lepton9Operation4Acos8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation4Asin8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation4Atan8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation4Ceil8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation5Acosh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation5Asinh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation5Atanh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation5Floor8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation3Tan5cloneEv104
_ZNK4PLMD6lepton9Operation3Log8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE108
_ZNK4PLMD6lepton9Operation5Atan25cloneEv120
_ZNK4PLMD6lepton9Operation8Nandelta5getIdEv120
_ZNK4PLMD6lepton9Operation3Cot5cloneEv134
_ZNK4PLMD6lepton9Operation4Csch5cloneEv134
_ZNK4PLMD6lepton9Operation4Sech5cloneEv134
_ZNK4PLMD6lepton9Operation3Tan5getIdEv140
_ZNK4PLMD6lepton9Operation3Cot5getIdEv146
_ZNK4PLMD6lepton9Operation4Csch5getIdEv146
_ZNK4PLMD6lepton9Operation4Sech5getIdEv146
_ZNK4PLMD6lepton9Operation3Abs15getNumArgumentsEv160
_ZNK4PLMD6lepton9Operation5Atan25getIdEv160
_ZNK4PLMD6lepton9Operation5Delta15getNumArgumentsEv182
_ZNK4PLMD6lepton9Operation3Sec5cloneEv184
_ZNK4PLMD6lepton9Operation3Tan8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Acot8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Acsc8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Asec8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Cosh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Cube8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Sinh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation5Acoth8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation5Acsch8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation5Asech8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation5Delta8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation3Cos8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation5Power8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation3Sin8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE206
_ZNK4PLMD6lepton9Operation3Sec5getIdEv214
_ZNK4PLMD6lepton9Operation3Csc5getIdEv224
_ZNK4PLMD6lepton9Operation4Coth5getIdEv228
_ZNK4PLMD6lepton9Operation4Tanh5getIdEv228
_ZNK4PLMD6lepton9Operation3Csc5cloneEv240
_ZNK4PLMD6lepton9Operation4Coth5cloneEv242
_ZNK4PLMD6lepton9Operation4Tanh5cloneEv242
_ZNK4PLMD6lepton9Operation8Constant7getNameB5cxx11Ev243
_ZNK4PLMD6lepton9Operation4Cube15getNumArgumentsEv256
_ZNK4PLMD6lepton9Operation6Select15getNumArgumentsEv280
_ZNK4PLMD6lepton9Operation4Tanh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE303
_ZNK4PLMD6lepton9Operation8Nandelta8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE303
_ZNK4PLMD6lepton9Operation3Exp15getNumArgumentsEv308
_ZNK4PLMD6lepton9Operation4Step15getNumArgumentsEv361
_ZNK4PLMD6lepton9Operation6Square7getNameB5cxx11Ev374
_ZNK4PLMD6lepton9Operation6Select5cloneEv400
_ZNK4PLMD6lepton9Operation3Cot8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation3Max8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation3Min8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation4Csch8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation4Sech8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation5Atan28evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation3Exp8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE405
_ZNK4PLMD6lepton9Operation3Add8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE413
_ZNK4PLMD6lepton9Operation8Subtract15isInfixOperatorEv431
_ZNK4PLMD6lepton9Operation8Subtract7getNameB5cxx11Ev431
_ZNK4PLMD6lepton9Operation3Log15getNumArgumentsEv442
_ZNK4PLMD6lepton9Operation13PowerConstant15getNumArgumentsEv454
_ZNK4PLMD6lepton9Operation3Abs8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE505
_ZNK4PLMD6lepton9Operation6Select5getIdEv516
_ZNK4PLMD6lepton9Operation13PowerConstantneERKS1_572
_ZNK4PLMD6lepton9Operation3Csc8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE606
_ZNK4PLMD6lepton9Operation3Sec8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE606
_ZNK4PLMD6lepton9Operation4Coth8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE606
_ZNK4PLMD6lepton9Operation4Step8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE606
_ZNK4PLMD6lepton9Operation3Add15isInfixOperatorEv614
_ZNK4PLMD6lepton9Operation3Add7getNameB5cxx11Ev614
_ZNK4PLMD6lepton9Operation6Divide8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE668
_ZNK4PLMD6lepton9Operation3Sin7getNameB5cxx11Ev734
_ZNK4PLMD6lepton9Operation11AddConstant7getNameB5cxx11Ev792
_ZNK4PLMD6lepton9Operation4Sqrt15getNumArgumentsEv797
_ZNK4PLMD6lepton9Operation10Reciprocal15getNumArgumentsEv834
_ZNK4PLMD6lepton9Operation8Multiply15isInfixOperatorEv838
_ZNK4PLMD6lepton9Operation8Multiply7getNameB5cxx11Ev838
_ZNK4PLMD6lepton9Operation3Abs5getIdEv846
_ZNK4PLMD6lepton9Operation3Exp5cloneEv924
_ZNK4PLMD6lepton9Operation3Abs5cloneEv976
_ZNK4PLMD6lepton9Operation4Cube5cloneEv1055
_ZNK4PLMD6lepton9Operation5Delta5cloneEv1107
_ZNK4PLMD6lepton9Operation4Sqrt8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1111
_ZNK4PLMD6lepton9Operation3Cos7getNameB5cxx11Ev1118
_ZNK4PLMD6lepton9Operation5Power15getNumArgumentsEv1168
_ZNK4PLMD6lepton9Operation8Subtract8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1284
_ZNK4PLMD6lepton9Operation4Cube5getIdEv1405
_ZNK4PLMD6lepton9Operation16MultiplyConstant7getNameB5cxx11Ev1412
_ZNK4PLMD6lepton9Operation6Negate8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1439
_ZNK4PLMD6lepton9Operation8Multiply8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1441
_ZNK4PLMD6lepton9Operation3Exp5getIdEv1495
_ZNK4PLMD6lepton9Operation6Divide15getNumArgumentsEv1721
_ZNK4PLMD6lepton9Operation3Log5getIdEv1832
_ZNK4PLMD6lepton9Operation13PowerConstant5getIdEv2047
_ZNK4PLMD6lepton9Operation10Reciprocal8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2121
_ZNK4PLMD6lepton9Operation13PowerConstant5cloneEv2229
_ZNK4PLMD6lepton9Operation6Square15getNumArgumentsEv2333
_ZNK4PLMD6lepton9Operation6Negate15getNumArgumentsEv2336
_ZNK4PLMD6lepton9Operation5Delta5getIdEv2395
_ZNK4PLMD6lepton9Operation4Step5cloneEv2422
_ZNK4PLMD6lepton9Operation6Select8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2432
_ZNK4PLMD6lepton9Operation16MultiplyConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2626
_ZNK4PLMD6lepton9Operation11AddConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2705
_ZNK4PLMD6lepton9Operation6Square8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3155
_ZNK4PLMD6lepton9Operation3Sin15getNumArgumentsEv3286
_ZNK4PLMD6lepton9Operation11AddConstant15getNumArgumentsEv3461
_ZNK4PLMD6lepton9Operation3Add11isSymmetricEv3592
_ZNK4PLMD6lepton9Operation3Log5cloneEv3637
_ZNK4PLMD6lepton9Operation10Reciprocal5getIdEv4059
_ZNK4PLMD6lepton9Operation4Step5getIdEv4261
_ZNK4PLMD6lepton9Operation10Reciprocal5cloneEv4372
_ZNK4PLMD6lepton9Operation5Power5getIdEv4509
_ZNK4PLMD6lepton9Operation4Sqrt5getIdEv4653
_ZNK4PLMD6lepton9Operation4Sqrt5cloneEv5491
_ZNK4PLMD6lepton9Operation6Divide5getIdEv5521
_ZNK4PLMD6lepton9Operation3Cos15getNumArgumentsEv5835
_ZNK4PLMD6lepton9Operation8Multiply11isSymmetricEv6290
_ZNK4PLMD6lepton9Operation8Subtract15getNumArgumentsEv6657
_ZNK4PLMD6lepton9Operation3Add15getNumArgumentsEv7429
_ZNK4PLMD6lepton9Operation8Variable7getNameB5cxx11Ev9018
_ZNK4PLMD6lepton9Operation8Variable15getNumArgumentsEv9142
_ZNK4PLMD6lepton9Operation5Power5cloneEv9169
_ZNK4PLMD6lepton9Operation11AddConstantneERKS1_10039
_ZNK4PLMD6lepton9Operation16MultiplyConstant15getNumArgumentsEv11256
_ZNK4PLMD6lepton9Operation6Divide5cloneEv11742
_ZNK4PLMD6lepton9Operation11AddConstant5getIdEv11904
_ZNK4PLMD6lepton9Operation6Negate5getIdEv12854
_ZNK4PLMD6lepton9Operation15isInfixOperatorEv15950
_ZNK4PLMD6lepton9Operation8Multiply15getNumArgumentsEv18815
_ZNK4PLMD6lepton9Operation6Square5getIdEv19443
_ZNK4PLMD6lepton9Operation6Square5cloneEv20360
_ZNK4PLMD6lepton9Operation6Negate5cloneEv23162
_ZNK4PLMD6lepton9Operation8Subtract5getIdEv25401
_ZNK4PLMD6lepton9Operation8Constant5getIdEv27219
_ZNK4PLMD6lepton9Operation8Variable5getIdEv30578
_ZNK4PLMD6lepton9Operation8Subtract5cloneEv31327
_ZNK4PLMD6lepton9Operation8ConstantneERKS1_31550
_ZNK4PLMD6lepton9Operation16MultiplyConstantneERKS1_35217
_ZNK4PLMD6lepton9Operation11AddConstant5cloneEv37127
_ZNK4PLMD6lepton9Operation3Add5getIdEv40244
_ZNK4PLMD6lepton9Operation3Add5cloneEv41274
_ZNK4PLMD6lepton9Operation8VariableneERKS1_45589
_ZNK4PLMD6lepton9Operation3Sin5getIdEv49117
_ZNK4PLMD6lepton9Operation11isSymmetricEv51815
_ZNK4PLMD6lepton9Operation3Sin5cloneEv52638
_ZNK4PLMD6lepton9Operation16MultiplyConstant5getIdEv54125
_ZNK4PLMD6lepton9Operation16MultiplyConstant5cloneEv55327
_ZNK4PLMD6lepton9Operation3Cos5getIdEv64872
_ZNK4PLMD6lepton9Operation3Cos5cloneEv76543
_ZNK4PLMD6lepton9Operation8Multiply5getIdEv83355
_ZNK4PLMD6lepton9OperationneERKS1_101640
_ZNK4PLMD6lepton9OperationeqERKS1_105194
_ZNK4PLMD6lepton9Operation8Multiply5cloneEv115826
_ZNK4PLMD6lepton9Operation8Variable5cloneEv240199
_ZNK4PLMD6lepton9Operation8Constant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2019547
_ZNK4PLMD6lepton9Operation8Constant15getNumArgumentsEv2029059
_ZNK4PLMD6lepton9Operation8Constant5cloneEv2145791
_ZNK4PLMD6lepton9Operation13PowerConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE10691410
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.h.func.html b/coverage-libs/lepton/Operation.h.func.html new file mode 100644 index 000000000000..bdf8dee31e58 --- /dev/null +++ b/coverage-libs/lepton/Operation.h.func.html @@ -0,0 +1,1233 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:53055695.3 %
Date:2024-02-22 21:58:47Functions:28029096.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton9Operation6CustomC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionE0
_ZN4PLMD6lepton9Operation6CustomC2ERKS2_i0
_ZN4PLMD6lepton9Operation6CustomD0Ev0
_ZN4PLMD6lepton9Operation6CustomD2Ev0
_ZNK4PLMD6lepton9Operation10Reciprocal15getNumArgumentsEv834
_ZNK4PLMD6lepton9Operation10Reciprocal5cloneEv4372
_ZNK4PLMD6lepton9Operation10Reciprocal5getIdEv4059
_ZNK4PLMD6lepton9Operation10Reciprocal7getNameB5cxx11Ev81
_ZNK4PLMD6lepton9Operation10Reciprocal8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2121
_ZNK4PLMD6lepton9Operation11AddConstant15getNumArgumentsEv3461
_ZNK4PLMD6lepton9Operation11AddConstant5cloneEv37127
_ZNK4PLMD6lepton9Operation11AddConstant5getIdEv11904
_ZNK4PLMD6lepton9Operation11AddConstant7getNameB5cxx11Ev792
_ZNK4PLMD6lepton9Operation11AddConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2705
_ZNK4PLMD6lepton9Operation11AddConstantneERKS1_10039
_ZNK4PLMD6lepton9Operation11isSymmetricEv51815
_ZNK4PLMD6lepton9Operation13PowerConstant15getNumArgumentsEv454
_ZNK4PLMD6lepton9Operation13PowerConstant15isInfixOperatorEv74
_ZNK4PLMD6lepton9Operation13PowerConstant5cloneEv2229
_ZNK4PLMD6lepton9Operation13PowerConstant5getIdEv2047
_ZNK4PLMD6lepton9Operation13PowerConstant7getNameB5cxx11Ev37
_ZNK4PLMD6lepton9Operation13PowerConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE10691410
_ZNK4PLMD6lepton9Operation13PowerConstantneERKS1_572
_ZNK4PLMD6lepton9Operation15isInfixOperatorEv15950
_ZNK4PLMD6lepton9Operation16MultiplyConstant15getNumArgumentsEv11256
_ZNK4PLMD6lepton9Operation16MultiplyConstant5cloneEv55327
_ZNK4PLMD6lepton9Operation16MultiplyConstant5getIdEv54125
_ZNK4PLMD6lepton9Operation16MultiplyConstant7getNameB5cxx11Ev1412
_ZNK4PLMD6lepton9Operation16MultiplyConstant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2626
_ZNK4PLMD6lepton9Operation16MultiplyConstantneERKS1_35217
_ZNK4PLMD6lepton9Operation3Abs15getNumArgumentsEv160
_ZNK4PLMD6lepton9Operation3Abs5cloneEv976
_ZNK4PLMD6lepton9Operation3Abs5getIdEv846
_ZNK4PLMD6lepton9Operation3Abs7getNameB5cxx11Ev18
_ZNK4PLMD6lepton9Operation3Abs8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE505
_ZNK4PLMD6lepton9Operation3Add11isSymmetricEv3592
_ZNK4PLMD6lepton9Operation3Add15getNumArgumentsEv7429
_ZNK4PLMD6lepton9Operation3Add15isInfixOperatorEv614
_ZNK4PLMD6lepton9Operation3Add5cloneEv41274
_ZNK4PLMD6lepton9Operation3Add5getIdEv40244
_ZNK4PLMD6lepton9Operation3Add7getNameB5cxx11Ev614
_ZNK4PLMD6lepton9Operation3Add8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE413
_ZNK4PLMD6lepton9Operation3Cos15getNumArgumentsEv5835
_ZNK4PLMD6lepton9Operation3Cos5cloneEv76543
_ZNK4PLMD6lepton9Operation3Cos5getIdEv64872
_ZNK4PLMD6lepton9Operation3Cos7getNameB5cxx11Ev1118
_ZNK4PLMD6lepton9Operation3Cos8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation3Cot15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation3Cot5cloneEv134
_ZNK4PLMD6lepton9Operation3Cot5getIdEv146
_ZNK4PLMD6lepton9Operation3Cot7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Cot8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation3Csc15getNumArgumentsEv54
_ZNK4PLMD6lepton9Operation3Csc5cloneEv240
_ZNK4PLMD6lepton9Operation3Csc5getIdEv224
_ZNK4PLMD6lepton9Operation3Csc7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation3Csc8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE606
_ZNK4PLMD6lepton9Operation3Erf15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation3Erf5cloneEv30
_ZNK4PLMD6lepton9Operation3Erf5getIdEv40
_ZNK4PLMD6lepton9Operation3Erf7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation3Exp15getNumArgumentsEv308
_ZNK4PLMD6lepton9Operation3Exp5cloneEv924
_ZNK4PLMD6lepton9Operation3Exp5getIdEv1495
_ZNK4PLMD6lepton9Operation3Exp7getNameB5cxx11Ev28
_ZNK4PLMD6lepton9Operation3Exp8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE405
_ZNK4PLMD6lepton9Operation3Log15getNumArgumentsEv442
_ZNK4PLMD6lepton9Operation3Log5cloneEv3637
_ZNK4PLMD6lepton9Operation3Log5getIdEv1832
_ZNK4PLMD6lepton9Operation3Log7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation3Log8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE108
_ZNK4PLMD6lepton9Operation3Max15getNumArgumentsEv44
_ZNK4PLMD6lepton9Operation3Max5cloneEv60
_ZNK4PLMD6lepton9Operation3Max5getIdEv80
_ZNK4PLMD6lepton9Operation3Max7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Max8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation3Min15getNumArgumentsEv44
_ZNK4PLMD6lepton9Operation3Min5cloneEv60
_ZNK4PLMD6lepton9Operation3Min5getIdEv80
_ZNK4PLMD6lepton9Operation3Min7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Min8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation3Sec15getNumArgumentsEv54
_ZNK4PLMD6lepton9Operation3Sec5cloneEv184
_ZNK4PLMD6lepton9Operation3Sec5getIdEv214
_ZNK4PLMD6lepton9Operation3Sec7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation3Sec8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE606
_ZNK4PLMD6lepton9Operation3Sin15getNumArgumentsEv3286
_ZNK4PLMD6lepton9Operation3Sin5cloneEv52638
_ZNK4PLMD6lepton9Operation3Sin5getIdEv49117
_ZNK4PLMD6lepton9Operation3Sin7getNameB5cxx11Ev734
_ZNK4PLMD6lepton9Operation3Sin8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE206
_ZNK4PLMD6lepton9Operation3Tan15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation3Tan5cloneEv104
_ZNK4PLMD6lepton9Operation3Tan5getIdEv140
_ZNK4PLMD6lepton9Operation3Tan7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation3Tan8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Acos15getNumArgumentsEv20
_ZNK4PLMD6lepton9Operation4Acos5cloneEv34
_ZNK4PLMD6lepton9Operation4Acos5getIdEv46
_ZNK4PLMD6lepton9Operation4Acos7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Acos8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation4Acot15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Acot5cloneEv30
_ZNK4PLMD6lepton9Operation4Acot5getIdEv40
_ZNK4PLMD6lepton9Operation4Acot7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Acot8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Acsc15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Acsc5cloneEv30
_ZNK4PLMD6lepton9Operation4Acsc5getIdEv40
_ZNK4PLMD6lepton9Operation4Acsc7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Acsc8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Asec15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Asec5cloneEv30
_ZNK4PLMD6lepton9Operation4Asec5getIdEv40
_ZNK4PLMD6lepton9Operation4Asec7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Asec8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Asin15getNumArgumentsEv20
_ZNK4PLMD6lepton9Operation4Asin5cloneEv34
_ZNK4PLMD6lepton9Operation4Asin5getIdEv46
_ZNK4PLMD6lepton9Operation4Asin7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Asin8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation4Atan15getNumArgumentsEv20
_ZNK4PLMD6lepton9Operation4Atan5cloneEv34
_ZNK4PLMD6lepton9Operation4Atan5getIdEv46
_ZNK4PLMD6lepton9Operation4Atan7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Atan8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation4Ceil15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Ceil5cloneEv30
_ZNK4PLMD6lepton9Operation4Ceil5getIdEv40
_ZNK4PLMD6lepton9Operation4Ceil7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Ceil8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation4Cosh15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation4Cosh5cloneEv78
_ZNK4PLMD6lepton9Operation4Cosh5getIdEv88
_ZNK4PLMD6lepton9Operation4Cosh7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Cosh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Coth15getNumArgumentsEv54
_ZNK4PLMD6lepton9Operation4Coth5cloneEv242
_ZNK4PLMD6lepton9Operation4Coth5getIdEv228
_ZNK4PLMD6lepton9Operation4Coth7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation4Coth8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE606
_ZNK4PLMD6lepton9Operation4Csch15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation4Csch5cloneEv134
_ZNK4PLMD6lepton9Operation4Csch5getIdEv146
_ZNK4PLMD6lepton9Operation4Csch7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Csch8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation4Cube15getNumArgumentsEv256
_ZNK4PLMD6lepton9Operation4Cube5cloneEv1055
_ZNK4PLMD6lepton9Operation4Cube5getIdEv1405
_ZNK4PLMD6lepton9Operation4Cube7getNameB5cxx11Ev23
_ZNK4PLMD6lepton9Operation4Cube8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Erfc15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation4Erfc5cloneEv30
_ZNK4PLMD6lepton9Operation4Erfc5getIdEv40
_ZNK4PLMD6lepton9Operation4Erfc7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation4Sech15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation4Sech5cloneEv134
_ZNK4PLMD6lepton9Operation4Sech5getIdEv146
_ZNK4PLMD6lepton9Operation4Sech7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Sech8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation4Sinh15getNumArgumentsEv36
_ZNK4PLMD6lepton9Operation4Sinh5cloneEv78
_ZNK4PLMD6lepton9Operation4Sinh5getIdEv88
_ZNK4PLMD6lepton9Operation4Sinh7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation4Sinh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation4Sqrt15getNumArgumentsEv797
_ZNK4PLMD6lepton9Operation4Sqrt5cloneEv5491
_ZNK4PLMD6lepton9Operation4Sqrt5getIdEv4653
_ZNK4PLMD6lepton9Operation4Sqrt7getNameB5cxx11Ev83
_ZNK4PLMD6lepton9Operation4Sqrt8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1111
_ZNK4PLMD6lepton9Operation4Step15getNumArgumentsEv361
_ZNK4PLMD6lepton9Operation4Step5cloneEv2422
_ZNK4PLMD6lepton9Operation4Step5getIdEv4261
_ZNK4PLMD6lepton9Operation4Step7getNameB5cxx11Ev17
_ZNK4PLMD6lepton9Operation4Step8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE606
_ZNK4PLMD6lepton9Operation4Tanh15getNumArgumentsEv54
_ZNK4PLMD6lepton9Operation4Tanh5cloneEv242
_ZNK4PLMD6lepton9Operation4Tanh5getIdEv228
_ZNK4PLMD6lepton9Operation4Tanh7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation4Tanh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE303
_ZNK4PLMD6lepton9Operation5Acosh15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Acosh5cloneEv30
_ZNK4PLMD6lepton9Operation5Acosh5getIdEv40
_ZNK4PLMD6lepton9Operation5Acosh7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Acosh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation5Acoth15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Acoth5cloneEv30
_ZNK4PLMD6lepton9Operation5Acoth5getIdEv40
_ZNK4PLMD6lepton9Operation5Acoth7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Acoth8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation5Acsch15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Acsch5cloneEv30
_ZNK4PLMD6lepton9Operation5Acsch5getIdEv40
_ZNK4PLMD6lepton9Operation5Acsch7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Acsch8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation5Asech15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Asech5cloneEv30
_ZNK4PLMD6lepton9Operation5Asech5getIdEv40
_ZNK4PLMD6lepton9Operation5Asech7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Asech8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation5Asinh15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Asinh5cloneEv30
_ZNK4PLMD6lepton9Operation5Asinh5getIdEv40
_ZNK4PLMD6lepton9Operation5Asinh7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Asinh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation5Atan215getNumArgumentsEv88
_ZNK4PLMD6lepton9Operation5Atan25cloneEv120
_ZNK4PLMD6lepton9Operation5Atan25getIdEv160
_ZNK4PLMD6lepton9Operation5Atan27getNameB5cxx11Ev8
_ZNK4PLMD6lepton9Operation5Atan28evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE404
_ZNK4PLMD6lepton9Operation5Atanh15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Atanh5cloneEv30
_ZNK4PLMD6lepton9Operation5Atanh5getIdEv40
_ZNK4PLMD6lepton9Operation5Atanh7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Atanh8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation5Delta15getNumArgumentsEv182
_ZNK4PLMD6lepton9Operation5Delta5cloneEv1107
_ZNK4PLMD6lepton9Operation5Delta5getIdEv2395
_ZNK4PLMD6lepton9Operation5Delta7getNameB5cxx11Ev8
_ZNK4PLMD6lepton9Operation5Delta8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE202
_ZNK4PLMD6lepton9Operation5Floor15getNumArgumentsEv18
_ZNK4PLMD6lepton9Operation5Floor5cloneEv30
_ZNK4PLMD6lepton9Operation5Floor5getIdEv40
_ZNK4PLMD6lepton9Operation5Floor7getNameB5cxx11Ev2
_ZNK4PLMD6lepton9Operation5Floor8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE101
_ZNK4PLMD6lepton9Operation5Power15getNumArgumentsEv1168
_ZNK4PLMD6lepton9Operation5Power15isInfixOperatorEv4
_ZNK4PLMD6lepton9Operation5Power5cloneEv9169
_ZNK4PLMD6lepton9Operation5Power5getIdEv4509
_ZNK4PLMD6lepton9Operation5Power7getNameB5cxx11Ev4
_ZNK4PLMD6lepton9Operation5Power8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE204
_ZNK4PLMD6lepton9Operation6Custom15getNumArgumentsEv0
_ZNK4PLMD6lepton9Operation6Custom5cloneEv0
_ZNK4PLMD6lepton9Operation6Custom5getIdEv0
_ZNK4PLMD6lepton9Operation6Custom7getNameB5cxx11Ev0
_ZNK4PLMD6lepton9Operation6Custom8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE0
_ZNK4PLMD6lepton9Operation6CustomneERKS1_0
_ZNK4PLMD6lepton9Operation6Divide15getNumArgumentsEv1721
_ZNK4PLMD6lepton9Operation6Divide15isInfixOperatorEv50
_ZNK4PLMD6lepton9Operation6Divide5cloneEv11742
_ZNK4PLMD6lepton9Operation6Divide5getIdEv5521
_ZNK4PLMD6lepton9Operation6Divide7getNameB5cxx11Ev50
_ZNK4PLMD6lepton9Operation6Divide8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE668
_ZNK4PLMD6lepton9Operation6Negate15getNumArgumentsEv2336
_ZNK4PLMD6lepton9Operation6Negate5cloneEv23162
_ZNK4PLMD6lepton9Operation6Negate5getIdEv12854
_ZNK4PLMD6lepton9Operation6Negate7getNameB5cxx11Ev70
_ZNK4PLMD6lepton9Operation6Negate8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1439
_ZNK4PLMD6lepton9Operation6Select15getNumArgumentsEv280
_ZNK4PLMD6lepton9Operation6Select5cloneEv400
_ZNK4PLMD6lepton9Operation6Select5getIdEv516
_ZNK4PLMD6lepton9Operation6Select7getNameB5cxx11Ev24
_ZNK4PLMD6lepton9Operation6Select8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2432
_ZNK4PLMD6lepton9Operation6Square15getNumArgumentsEv2333
_ZNK4PLMD6lepton9Operation6Square5cloneEv20360
_ZNK4PLMD6lepton9Operation6Square5getIdEv19443
_ZNK4PLMD6lepton9Operation6Square7getNameB5cxx11Ev374
_ZNK4PLMD6lepton9Operation6Square8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE3155
_ZNK4PLMD6lepton9Operation8Constant15getNumArgumentsEv2029059
_ZNK4PLMD6lepton9Operation8Constant5cloneEv2145791
_ZNK4PLMD6lepton9Operation8Constant5getIdEv27219
_ZNK4PLMD6lepton9Operation8Constant7getNameB5cxx11Ev243
_ZNK4PLMD6lepton9Operation8Constant8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE2019547
_ZNK4PLMD6lepton9Operation8ConstantneERKS1_31550
_ZNK4PLMD6lepton9Operation8Multiply11isSymmetricEv6290
_ZNK4PLMD6lepton9Operation8Multiply15getNumArgumentsEv18815
_ZNK4PLMD6lepton9Operation8Multiply15isInfixOperatorEv838
_ZNK4PLMD6lepton9Operation8Multiply5cloneEv115826
_ZNK4PLMD6lepton9Operation8Multiply5getIdEv83355
_ZNK4PLMD6lepton9Operation8Multiply7getNameB5cxx11Ev838
_ZNK4PLMD6lepton9Operation8Multiply8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1441
_ZNK4PLMD6lepton9Operation8Nandelta15getNumArgumentsEv50
_ZNK4PLMD6lepton9Operation8Nandelta5cloneEv90
_ZNK4PLMD6lepton9Operation8Nandelta5getIdEv120
_ZNK4PLMD6lepton9Operation8Nandelta7getNameB5cxx11Ev6
_ZNK4PLMD6lepton9Operation8Nandelta8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE303
_ZNK4PLMD6lepton9Operation8Subtract15getNumArgumentsEv6657
_ZNK4PLMD6lepton9Operation8Subtract15isInfixOperatorEv431
_ZNK4PLMD6lepton9Operation8Subtract5cloneEv31327
_ZNK4PLMD6lepton9Operation8Subtract5getIdEv25401
_ZNK4PLMD6lepton9Operation8Subtract7getNameB5cxx11Ev431
_ZNK4PLMD6lepton9Operation8Subtract8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE1284
_ZNK4PLMD6lepton9Operation8Variable15getNumArgumentsEv9142
_ZNK4PLMD6lepton9Operation8Variable5cloneEv240199
_ZNK4PLMD6lepton9Operation8Variable5getIdEv30578
_ZNK4PLMD6lepton9Operation8Variable7getNameB5cxx11Ev9018
_ZNK4PLMD6lepton9Operation8Variable8evaluateEPdRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISA_ESaISt4pairIKSA_dEEE30
_ZNK4PLMD6lepton9Operation8VariableneERKS1_45589
_ZNK4PLMD6lepton9OperationeqERKS1_105194
_ZNK4PLMD6lepton9OperationneERKS1_101640
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Operation.h.gcov.html b/coverage-libs/lepton/Operation.h.gcov.html new file mode 100644 index 000000000000..b7064f8e25b9 --- /dev/null +++ b/coverage-libs/lepton/Operation.h.gcov.html @@ -0,0 +1,1379 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Operation.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Operation.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:53055695.3 %
Date:2024-02-22 21:58:47Functions:28029096.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * -------------------------------------------------------------------------- *
+       3             :  *                                   Lepton                                   *
+       4             :  * -------------------------------------------------------------------------- *
+       5             :  * This is part of the Lepton expression parser originating from              *
+       6             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+       7             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+       8             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+       9             :  *                                                                            *
+      10             :  * Portions copyright (c) 2013-2016 Stanford University and the Authors.      *
+      11             :  * Authors: Peter Eastman                                                     *
+      12             :  * Contributors:                                                              *
+      13             :  *                                                                            *
+      14             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      15             :  * copy of this software and associated documentation files (the "Software"), *
+      16             :  * to deal in the Software without restriction, including without limitation  *
+      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      18             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      19             :  * Software is furnished to do so, subject to the following conditions:       *
+      20             :  *                                                                            *
+      21             :  * The above copyright notice and this permission notice shall be included in *
+      22             :  * all copies or substantial portions of the Software.                        *
+      23             :  *                                                                            *
+      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      27             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      28             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      29             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      30             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      31             :  * -------------------------------------------------------------------------- *
+      32             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      33             : #ifndef __PLUMED_lepton_Operation_h
+      34             : #define __PLUMED_lepton_Operation_h
+      35             : 
+      36             : /* -------------------------------------------------------------------------- *
+      37             :  *                                   lepton                                   *
+      38             :  * -------------------------------------------------------------------------- *
+      39             :  * This is part of the lepton expression parser originating from              *
+      40             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+      41             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+      42             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+      43             :  *                                                                            *
+      44             :  * Portions copyright (c) 2009-2019 Stanford University and the Authors.      *
+      45             :  * Authors: Peter Eastman                                                     *
+      46             :  * Contributors:                                                              *
+      47             :  *                                                                            *
+      48             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      49             :  * copy of this software and associated documentation files (the "Software"), *
+      50             :  * to deal in the Software without restriction, including without limitation  *
+      51             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      52             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      53             :  * Software is furnished to do so, subject to the following conditions:       *
+      54             :  *                                                                            *
+      55             :  * The above copyright notice and this permission notice shall be included in *
+      56             :  * all copies or substantial portions of the Software.                        *
+      57             :  *                                                                            *
+      58             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      59             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      60             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      61             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      62             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      63             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      64             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      65             :  * -------------------------------------------------------------------------- */
+      66             : 
+      67             : #include "windowsIncludes.h"
+      68             : #include "CustomFunction.h"
+      69             : #include "Exception.h"
+      70             : #include <cmath>
+      71             : #include <map>
+      72             : #include <string>
+      73             : #include <vector>
+      74             : #include <sstream>
+      75             : #include <algorithm>
+      76             : #include <limits>
+      77             : 
+      78             : namespace PLMD {
+      79             : namespace lepton {
+      80             : 
+      81             : class ExpressionTreeNode;
+      82             : 
+      83             : /**
+      84             :  * An Operation represents a single step in the evaluation of an expression, such as a function,
+      85             :  * an operator, or a constant value.  Each Operation takes some number of values as arguments
+      86             :  * and produces a single value.
+      87             :  *
+      88             :  * This is an abstract class with subclasses for specific operations.
+      89             :  */
+      90             : 
+      91             : class LEPTON_EXPORT Operation {
+      92             : public:
+      93             :     virtual ~Operation() {
+      94             :     }
+      95             :     /**
+      96             :      * This enumeration lists all Operation subclasses.  This is provided so that switch statements
+      97             :      * can be used when processing or analyzing parsed expressions.
+      98             :      */
+      99             :     enum Id {CONSTANT, VARIABLE, CUSTOM, ADD, SUBTRACT, MULTIPLY, DIVIDE, POWER, NEGATE, SQRT, EXP, LOG,
+     100             :              SIN, COS, SEC, CSC, TAN, COT, ASIN, ACOS, ATAN, ATAN2, SINH, COSH, TANH, ERF, ERFC, STEP, DELTA, NANDELTA, SQUARE, CUBE, RECIPROCAL,
+     101             :              ADD_CONSTANT, MULTIPLY_CONSTANT, POWER_CONSTANT, MIN, MAX, ABS, FLOOR, CEIL, SELECT,
+     102             :              ACOT, ASEC, ACSC, COTH, SECH, CSCH, ASINH, ACOSH, ATANH, ACOTH, ASECH, ACSCH};
+     103             :     /**
+     104             :      * Get the name of this Operation.
+     105             :      */
+     106             :     virtual std::string getName() const = 0;
+     107             :     /**
+     108             :      * Get this Operation's ID.
+     109             :      */
+     110             :     virtual Id getId() const = 0;
+     111             :     /**
+     112             :      * Get the number of arguments this operation expects.
+     113             :      */
+     114             :     virtual int getNumArguments() const = 0;
+     115             :     /**
+     116             :      * Create a clone of this Operation.
+     117             :      */
+     118             :     virtual Operation* clone() const = 0;
+     119             :     /**
+     120             :      * Perform the computation represented by this operation.
+     121             :      *
+     122             :      * @param args        the array of arguments
+     123             :      * @param variables   a map containing the values of all variables
+     124             :      * @return the result of performing the computation.
+     125             :      */
+     126             :     virtual double evaluate(double* args, const std::map<std::string, double>& variables) const = 0;
+     127             :     /**
+     128             :      * Return an ExpressionTreeNode which represents the analytic derivative of this Operation with respect to a variable.
+     129             :      *
+     130             :      * @param children     the child nodes
+     131             :      * @param childDerivs  the derivatives of the child nodes with respect to the variable
+     132             :      * @param variable     the variable with respect to which the derivate should be taken
+     133             :      */
+     134             :     virtual ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const = 0;
+     135             :     /**
+     136             :      * Get whether this operation should be displayed with infix notation.
+     137             :      */
+     138       15950 :     virtual bool isInfixOperator() const {
+     139       15950 :         return false;
+     140             :     }
+     141             :     /**
+     142             :      * Get whether this is a symmetric binary operation, such that exchanging its arguments
+     143             :      * does not affect the result.
+     144             :      */
+     145       51815 :     virtual bool isSymmetric() const {
+     146       51815 :         return false;
+     147             :     }
+     148      101640 :     virtual bool operator!=(const Operation& op) const {
+     149      101640 :         return op.getId() != getId();
+     150             :     }
+     151      105194 :     virtual bool operator==(const Operation& op) const {
+     152      105194 :         return !(*this != op);
+     153             :     }
+     154             :     class Constant;
+     155             :     class Variable;
+     156             :     class Custom;
+     157             :     class Add;
+     158             :     class Subtract;
+     159             :     class Multiply;
+     160             :     class Divide;
+     161             :     class Power;
+     162             :     class Negate;
+     163             :     class Sqrt;
+     164             :     class Exp;
+     165             :     class Log;
+     166             :     class Sin;
+     167             :     class Cos;
+     168             :     class Sec;
+     169             :     class Csc;
+     170             :     class Tan;
+     171             :     class Cot;
+     172             :     class Asin;
+     173             :     class Acos;
+     174             :     class Atan;
+     175             :     class Atan2;
+     176             :     class Sinh;
+     177             :     class Cosh;
+     178             :     class Tanh;
+     179             :     class Erf;
+     180             :     class Erfc;
+     181             :     class Step;
+     182             :     class Delta;
+     183             :     class Nandelta;
+     184             :     class Square;
+     185             :     class Cube;
+     186             :     class Reciprocal;
+     187             :     class AddConstant;
+     188             :     class MultiplyConstant;
+     189             :     class PowerConstant;
+     190             :     class Min;
+     191             :     class Max;
+     192             :     class Abs;
+     193             :     class Floor;
+     194             :     class Ceil;
+     195             :     class Select;
+     196             :     class Acot;
+     197             :     class Asec;
+     198             :     class Acsc;
+     199             :     class Coth;
+     200             :     class Sech;
+     201             :     class Csch;
+     202             :     class Asinh;
+     203             :     class Acosh;
+     204             :     class Atanh;
+     205             :     class Acoth;
+     206             :     class Asech;
+     207             :     class Acsch;
+     208             : };
+     209             : 
+     210             : class LEPTON_EXPORT Operation::Constant : public Operation {
+     211             : public:
+     212     2017868 :     Constant(double value) : value(value) {
+     213             :     }
+     214         243 :     std::string getName() const {
+     215         243 :         std::stringstream name;
+     216         243 :         name << value;
+     217         243 :         return name.str();
+     218         243 :     }
+     219       27219 :     Id getId() const {
+     220       27219 :         return CONSTANT;
+     221             :     }
+     222     2029059 :     int getNumArguments() const {
+     223     2029059 :         return 0;
+     224             :     }
+     225     2145791 :     Operation* clone() const {
+     226     2145791 :         return new Constant(value);
+     227             :     }
+     228     2019547 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     229     2019547 :         return value;
+     230             :     }
+     231             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     232             :     double getValue() const {
+     233        6457 :         return value;
+     234             :     }
+     235       31550 :     bool operator!=(const Operation& op) const {
+     236       31550 :         const Constant* o = dynamic_cast<const Constant*>(&op);
+     237       31550 :         return (o == NULL || o->value != value);
+     238             :     }
+     239             : private:
+     240             :     double value;
+     241             : };
+     242             : 
+     243             : class LEPTON_EXPORT Operation::Variable : public Operation {
+     244             : public:
+     245      243504 :     Variable(const std::string& name) : name(name) {
+     246      243504 :     }
+     247        9018 :     std::string getName() const {
+     248        9018 :         return name;
+     249             :     }
+     250       30578 :     Id getId() const {
+     251       30578 :         return VARIABLE;
+     252             :     }
+     253        9142 :     int getNumArguments() const {
+     254        9142 :         return 0;
+     255             :     }
+     256      240199 :     Operation* clone() const {
+     257      480398 :         return new Variable(name);
+     258             :     }
+     259          30 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     260          30 :         std::map<std::string, double>::const_iterator iter = variables.find(name);
+     261          30 :         if (iter == variables.end())
+     262          44 :             throw Exception("No value specified for variable "+name);
+     263           8 :         return iter->second;
+     264             :     }
+     265             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     266       45589 :     bool operator!=(const Operation& op) const {
+     267       45589 :         const Variable* o = dynamic_cast<const Variable*>(&op);
+     268       45589 :         return (o == NULL || o->name != name);
+     269             :     }
+     270             : private:
+     271             :     std::string name;
+     272             : };
+     273             : 
+     274             : class LEPTON_EXPORT Operation::Custom : public Operation {
+     275             : public:
+     276           0 :     Custom(const std::string& name, CustomFunction* function) : name(name), function(function), isDerivative(false), derivOrder(function->getNumArguments(), 0) {
+     277           0 :     }
+     278             :     Custom(const std::string& name, CustomFunction* function, const std::vector<int>& derivOrder) : name(name), function(function), isDerivative(false), derivOrder(derivOrder) {
+     279             :         for (int order : derivOrder)
+     280             :             if (order != 0)
+     281             :                 isDerivative = true;
+     282             :     }
+     283           0 :     Custom(const Custom& base, int derivIndex) : name(base.name), function(base.function->clone()), isDerivative(true), derivOrder(base.derivOrder) {
+     284           0 :         derivOrder[derivIndex]++;
+     285           0 :     }
+     286           0 :     ~Custom() {
+     287           0 :         delete function;
+     288           0 :     }
+     289           0 :     std::string getName() const {
+     290           0 :         return name;
+     291             :     }
+     292           0 :     Id getId() const {
+     293           0 :         return CUSTOM;
+     294             :     }
+     295           0 :     int getNumArguments() const {
+     296           0 :         return function->getNumArguments();
+     297             :     }
+     298           0 :     Operation* clone() const {
+     299           0 :         Custom* clone = new Custom(name, function->clone());
+     300           0 :         clone->isDerivative = isDerivative;
+     301           0 :         clone->derivOrder = derivOrder;
+     302           0 :         return clone;
+     303             :     }
+     304           0 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     305           0 :         if (isDerivative)
+     306           0 :             return function->evaluateDerivative(args, &derivOrder[0]);
+     307           0 :         return function->evaluate(args);
+     308             :     }
+     309             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     310             :     const std::vector<int>& getDerivOrder() const {
+     311             :         return derivOrder;
+     312             :     }
+     313           0 :     bool operator!=(const Operation& op) const {
+     314           0 :         const Custom* o = dynamic_cast<const Custom*>(&op);
+     315           0 :         return (o == NULL || o->name != name || o->isDerivative != isDerivative || o->derivOrder != derivOrder);
+     316             :     }
+     317             : private:
+     318             :     std::string name;
+     319             :     CustomFunction* function;
+     320             :     bool isDerivative;
+     321             :     std::vector<int> derivOrder;
+     322             : };
+     323             : 
+     324             : class LEPTON_EXPORT Operation::Add : public Operation {
+     325             : public:
+     326        1593 :     Add() {
+     327             :     }
+     328         614 :     std::string getName() const {
+     329         614 :         return "+";
+     330             :     }
+     331       40244 :     Id getId() const {
+     332       40244 :         return ADD;
+     333             :     }
+     334        7429 :     int getNumArguments() const {
+     335        7429 :         return 2;
+     336             :     }
+     337       41274 :     Operation* clone() const {
+     338       41274 :         return new Add();
+     339             :     }
+     340         413 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     341         413 :         return args[0]+args[1];
+     342             :     }
+     343             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     344         614 :     bool isInfixOperator() const {
+     345         614 :         return true;
+     346             :     }
+     347        3592 :     bool isSymmetric() const {
+     348        3592 :         return true;
+     349             :     }
+     350             : };
+     351             : 
+     352             : class LEPTON_EXPORT Operation::Subtract : public Operation {
+     353             : public:
+     354        1134 :     Subtract() {
+     355             :     }
+     356         431 :     std::string getName() const {
+     357         431 :         return "-";
+     358             :     }
+     359       25401 :     Id getId() const {
+     360       25401 :         return SUBTRACT;
+     361             :     }
+     362        6657 :     int getNumArguments() const {
+     363        6657 :         return 2;
+     364             :     }
+     365       31327 :     Operation* clone() const {
+     366       31327 :         return new Subtract();
+     367             :     }
+     368        1284 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     369        1284 :         return args[0]-args[1];
+     370             :     }
+     371             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     372         431 :     bool isInfixOperator() const {
+     373         431 :         return true;
+     374             :     }
+     375             : };
+     376             : 
+     377             : class LEPTON_EXPORT Operation::Multiply : public Operation {
+     378             : public:
+     379        4712 :     Multiply() {
+     380             :     }
+     381         838 :     std::string getName() const {
+     382         838 :         return "*";
+     383             :     }
+     384       83355 :     Id getId() const {
+     385       83355 :         return MULTIPLY;
+     386             :     }
+     387       18815 :     int getNumArguments() const {
+     388       18815 :         return 2;
+     389             :     }
+     390      115826 :     Operation* clone() const {
+     391      115826 :         return new Multiply();
+     392             :     }
+     393        1441 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     394        1441 :         return args[0]*args[1];
+     395             :     }
+     396             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     397         838 :     bool isInfixOperator() const {
+     398         838 :         return true;
+     399             :     }
+     400        6290 :     bool isSymmetric() const {
+     401        6290 :         return true;
+     402             :     }
+     403             : };
+     404             : 
+     405             : class LEPTON_EXPORT Operation::Divide : public Operation {
+     406             : public:
+     407         554 :     Divide() {
+     408             :     }
+     409          50 :     std::string getName() const {
+     410          50 :         return "/";
+     411             :     }
+     412        5521 :     Id getId() const {
+     413        5521 :         return DIVIDE;
+     414             :     }
+     415        1721 :     int getNumArguments() const {
+     416        1721 :         return 2;
+     417             :     }
+     418       11742 :     Operation* clone() const {
+     419       11742 :         return new Divide();
+     420             :     }
+     421         668 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     422         668 :         return args[0]/args[1];
+     423             :     }
+     424             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     425          50 :     bool isInfixOperator() const {
+     426          50 :         return true;
+     427             :     }
+     428             : };
+     429             : 
+     430             : class LEPTON_EXPORT Operation::Power : public Operation {
+     431             : public:
+     432         440 :     Power() {
+     433             :     }
+     434           4 :     std::string getName() const {
+     435           4 :         return "^";
+     436             :     }
+     437        4509 :     Id getId() const {
+     438        4509 :         return POWER;
+     439             :     }
+     440        1168 :     int getNumArguments() const {
+     441        1168 :         return 2;
+     442             :     }
+     443        9169 :     Operation* clone() const {
+     444        9169 :         return new Power();
+     445             :     }
+     446         204 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     447         204 :         return std::pow(args[0], args[1]);
+     448             :     }
+     449             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     450           4 :     bool isInfixOperator() const {
+     451           4 :         return true;
+     452             :     }
+     453             : };
+     454             : 
+     455             : class LEPTON_EXPORT Operation::Negate : public Operation {
+     456             : public:
+     457         357 :     Negate() {
+     458             :     }
+     459          70 :     std::string getName() const {
+     460          70 :         return "-";
+     461             :     }
+     462       12854 :     Id getId() const {
+     463       12854 :         return NEGATE;
+     464             :     }
+     465        2336 :     int getNumArguments() const {
+     466        2336 :         return 1;
+     467             :     }
+     468       23162 :     Operation* clone() const {
+     469       23162 :         return new Negate();
+     470             :     }
+     471        1439 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     472        1439 :         return -args[0];
+     473             :     }
+     474             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     475             : };
+     476             : 
+     477             : class LEPTON_EXPORT Operation::Sqrt : public Operation {
+     478             : public:
+     479         122 :     Sqrt() {
+     480             :     }
+     481          83 :     std::string getName() const {
+     482          83 :         return "sqrt";
+     483             :     }
+     484        4653 :     Id getId() const {
+     485        4653 :         return SQRT;
+     486             :     }
+     487         797 :     int getNumArguments() const {
+     488         797 :         return 1;
+     489             :     }
+     490        5491 :     Operation* clone() const {
+     491        5491 :         return new Sqrt();
+     492             :     }
+     493        1111 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     494        1111 :         return std::sqrt(args[0]);
+     495             :     }
+     496             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     497             : };
+     498             : 
+     499             : class LEPTON_EXPORT Operation::Exp : public Operation {
+     500             : public:
+     501          34 :     Exp() {
+     502             :     }
+     503          28 :     std::string getName() const {
+     504          28 :         return "exp";
+     505             :     }
+     506        1495 :     Id getId() const {
+     507        1495 :         return EXP;
+     508             :     }
+     509         308 :     int getNumArguments() const {
+     510         308 :         return 1;
+     511             :     }
+     512         924 :     Operation* clone() const {
+     513         924 :         return new Exp();
+     514             :     }
+     515         405 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     516         405 :         return std::exp(args[0]);
+     517             :     }
+     518             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     519             : };
+     520             : 
+     521             : class LEPTON_EXPORT Operation::Log : public Operation {
+     522             : public:
+     523         116 :     Log() {
+     524             :     }
+     525           2 :     std::string getName() const {
+     526           2 :         return "log";
+     527             :     }
+     528        1832 :     Id getId() const {
+     529        1832 :         return LOG;
+     530             :     }
+     531         442 :     int getNumArguments() const {
+     532         442 :         return 1;
+     533             :     }
+     534        3637 :     Operation* clone() const {
+     535        3637 :         return new Log();
+     536             :     }
+     537         108 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     538         108 :         return std::log(args[0]);
+     539             :     }
+     540             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     541             : };
+     542             : 
+     543             : class LEPTON_EXPORT Operation::Sin : public Operation {
+     544             : public:
+     545         315 :     Sin() {
+     546             :     }
+     547         734 :     std::string getName() const {
+     548         734 :         return "sin";
+     549             :     }
+     550       49117 :     Id getId() const {
+     551       49117 :         return SIN;
+     552             :     }
+     553        3286 :     int getNumArguments() const {
+     554        3286 :         return 1;
+     555             :     }
+     556       52638 :     Operation* clone() const {
+     557       52638 :         return new Sin();
+     558             :     }
+     559         206 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     560         206 :         return std::sin(args[0]);
+     561             :     }
+     562             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     563             : };
+     564             : 
+     565             : class LEPTON_EXPORT Operation::Cos : public Operation {
+     566             : public:
+     567        1319 :     Cos() {
+     568             :     }
+     569        1118 :     std::string getName() const {
+     570        1118 :         return "cos";
+     571             :     }
+     572       64872 :     Id getId() const {
+     573       64872 :         return COS;
+     574             :     }
+     575        5835 :     int getNumArguments() const {
+     576        5835 :         return 1;
+     577             :     }
+     578       76543 :     Operation* clone() const {
+     579       76543 :         return new Cos();
+     580             :     }
+     581         204 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     582         204 :         return std::cos(args[0]);
+     583             :     }
+     584             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     585             : };
+     586             : 
+     587             : class LEPTON_EXPORT Operation::Sec : public Operation {
+     588             : public:
+     589           8 :     Sec() {
+     590             :     }
+     591           6 :     std::string getName() const {
+     592           6 :         return "sec";
+     593             :     }
+     594         214 :     Id getId() const {
+     595         214 :         return SEC;
+     596             :     }
+     597          54 :     int getNumArguments() const {
+     598          54 :         return 1;
+     599             :     }
+     600         184 :     Operation* clone() const {
+     601         184 :         return new Sec();
+     602             :     }
+     603         606 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     604         606 :         return 1.0/std::cos(args[0]);
+     605             :     }
+     606             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     607             : };
+     608             : 
+     609             : class LEPTON_EXPORT Operation::Csc : public Operation {
+     610             : public:
+     611           8 :     Csc() {
+     612             :     }
+     613           6 :     std::string getName() const {
+     614           6 :         return "csc";
+     615             :     }
+     616         224 :     Id getId() const {
+     617         224 :         return CSC;
+     618             :     }
+     619          54 :     int getNumArguments() const {
+     620          54 :         return 1;
+     621             :     }
+     622         240 :     Operation* clone() const {
+     623         240 :         return new Csc();
+     624             :     }
+     625         606 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     626         606 :         return 1.0/std::sin(args[0]);
+     627             :     }
+     628             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     629             : };
+     630             : 
+     631             : class LEPTON_EXPORT Operation::Tan : public Operation {
+     632             : public:
+     633           6 :     Tan() {
+     634             :     }
+     635           4 :     std::string getName() const {
+     636           4 :         return "tan";
+     637             :     }
+     638         140 :     Id getId() const {
+     639         140 :         return TAN;
+     640             :     }
+     641          36 :     int getNumArguments() const {
+     642          36 :         return 1;
+     643             :     }
+     644         104 :     Operation* clone() const {
+     645         104 :         return new Tan();
+     646             :     }
+     647         202 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     648         202 :         return std::tan(args[0]);
+     649             :     }
+     650             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     651             : };
+     652             : 
+     653             : class LEPTON_EXPORT Operation::Cot : public Operation {
+     654             : public:
+     655           6 :     Cot() {
+     656             :     }
+     657           4 :     std::string getName() const {
+     658           4 :         return "cot";
+     659             :     }
+     660         146 :     Id getId() const {
+     661         146 :         return COT;
+     662             :     }
+     663          36 :     int getNumArguments() const {
+     664          36 :         return 1;
+     665             :     }
+     666         134 :     Operation* clone() const {
+     667         134 :         return new Cot();
+     668             :     }
+     669         404 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     670         404 :         return 1.0/std::tan(args[0]);
+     671             :     }
+     672             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     673             : };
+     674             : 
+     675             : class LEPTON_EXPORT Operation::Asin : public Operation {
+     676             : public:
+     677          38 :     Asin() {
+     678             :     }
+     679           2 :     std::string getName() const {
+     680           2 :         return "asin";
+     681             :     }
+     682          46 :     Id getId() const {
+     683          46 :         return ASIN;
+     684             :     }
+     685          20 :     int getNumArguments() const {
+     686          20 :         return 1;
+     687             :     }
+     688          34 :     Operation* clone() const {
+     689          34 :         return new Asin();
+     690             :     }
+     691         101 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     692         101 :         return std::asin(args[0]);
+     693             :     }
+     694             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     695             : };
+     696             : 
+     697             : class LEPTON_EXPORT Operation::Acos : public Operation {
+     698             : public:
+     699          38 :     Acos() {
+     700             :     }
+     701           2 :     std::string getName() const {
+     702           2 :         return "acos";
+     703             :     }
+     704          46 :     Id getId() const {
+     705          46 :         return ACOS;
+     706             :     }
+     707          20 :     int getNumArguments() const {
+     708          20 :         return 1;
+     709             :     }
+     710          34 :     Operation* clone() const {
+     711          34 :         return new Acos();
+     712             :     }
+     713         101 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     714         101 :         return std::acos(args[0]);
+     715             :     }
+     716             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     717             : };
+     718             : 
+     719             : class LEPTON_EXPORT Operation::Atan : public Operation {
+     720             : public:
+     721          38 :     Atan() {
+     722             :     }
+     723           2 :     std::string getName() const {
+     724           2 :         return "atan";
+     725             :     }
+     726          46 :     Id getId() const {
+     727          46 :         return ATAN;
+     728             :     }
+     729          20 :     int getNumArguments() const {
+     730          20 :         return 1;
+     731             :     }
+     732          34 :     Operation* clone() const {
+     733          34 :         return new Atan();
+     734             :     }
+     735         101 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     736         101 :         return std::atan(args[0]);
+     737             :     }
+     738             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     739             : };
+     740             : 
+     741             : class LEPTON_EXPORT Operation::Atan2 : public Operation {
+     742             : public:
+     743         136 :     Atan2() {
+     744             :     }
+     745           8 :     std::string getName() const {
+     746           8 :         return "atan2";
+     747             :     }
+     748         160 :     Id getId() const {
+     749         160 :         return ATAN2;
+     750             :     }
+     751          88 :     int getNumArguments() const {
+     752          88 :         return 2;
+     753             :     }
+     754         120 :     Operation* clone() const {
+     755         120 :         return new Atan2();
+     756             :     }
+     757         404 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     758         404 :         return std::atan2(args[0], args[1]);
+     759             :     }
+     760             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     761             : };
+     762             : 
+     763             : class LEPTON_EXPORT Operation::Sinh : public Operation {
+     764             : public:
+     765           6 :     Sinh() {
+     766             :     }
+     767           4 :     std::string getName() const {
+     768           4 :         return "sinh";
+     769             :     }
+     770          88 :     Id getId() const {
+     771          88 :         return SINH;
+     772             :     }
+     773          36 :     int getNumArguments() const {
+     774          36 :         return 1;
+     775             :     }
+     776          78 :     Operation* clone() const {
+     777          78 :         return new Sinh();
+     778             :     }
+     779         202 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     780         202 :         return std::sinh(args[0]);
+     781             :     }
+     782             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     783             : };
+     784             : 
+     785             : class LEPTON_EXPORT Operation::Cosh : public Operation {
+     786             : public:
+     787           6 :     Cosh() {
+     788             :     }
+     789           4 :     std::string getName() const {
+     790           4 :         return "cosh";
+     791             :     }
+     792          88 :     Id getId() const {
+     793          88 :         return COSH;
+     794             :     }
+     795          36 :     int getNumArguments() const {
+     796          36 :         return 1;
+     797             :     }
+     798          78 :     Operation* clone() const {
+     799          78 :         return new Cosh();
+     800             :     }
+     801         202 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     802         202 :         return std::cosh(args[0]);
+     803             :     }
+     804             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     805             : };
+     806             : 
+     807             : class LEPTON_EXPORT Operation::Tanh : public Operation {
+     808             : public:
+     809           8 :     Tanh() {
+     810             :     }
+     811           6 :     std::string getName() const {
+     812           6 :         return "tanh";
+     813             :     }
+     814         228 :     Id getId() const {
+     815         228 :         return TANH;
+     816             :     }
+     817          54 :     int getNumArguments() const {
+     818          54 :         return 1;
+     819             :     }
+     820         242 :     Operation* clone() const {
+     821         242 :         return new Tanh();
+     822             :     }
+     823         303 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     824         303 :         return std::tanh(args[0]);
+     825             :     }
+     826             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     827             : };
+     828             : 
+     829             : class LEPTON_EXPORT Operation::Erf : public Operation {
+     830             : public:
+     831          34 :     Erf() {
+     832             :     }
+     833           2 :     std::string getName() const {
+     834           2 :         return "erf";
+     835             :     }
+     836          40 :     Id getId() const {
+     837          40 :         return ERF;
+     838             :     }
+     839          18 :     int getNumArguments() const {
+     840          18 :         return 1;
+     841             :     }
+     842          30 :     Operation* clone() const {
+     843          30 :         return new Erf();
+     844             :     }
+     845             :     double evaluate(double* args, const std::map<std::string, double>& variables) const;
+     846             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     847             : };
+     848             : 
+     849             : class LEPTON_EXPORT Operation::Erfc : public Operation {
+     850             : public:
+     851          34 :     Erfc() {
+     852             :     }
+     853           2 :     std::string getName() const {
+     854           2 :         return "erfc";
+     855             :     }
+     856          40 :     Id getId() const {
+     857          40 :         return ERFC;
+     858             :     }
+     859          18 :     int getNumArguments() const {
+     860          18 :         return 1;
+     861             :     }
+     862          30 :     Operation* clone() const {
+     863          30 :         return new Erfc();
+     864             :     }
+     865             :     double evaluate(double* args, const std::map<std::string, double>& variables) const;
+     866             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     867             : };
+     868             : 
+     869             : class LEPTON_EXPORT Operation::Step : public Operation {
+     870             : public:
+     871          39 :     Step() {
+     872             :     }
+     873          17 :     std::string getName() const {
+     874          17 :         return "step";
+     875             :     }
+     876        4261 :     Id getId() const {
+     877        4261 :         return STEP;
+     878             :     }
+     879         361 :     int getNumArguments() const {
+     880         361 :         return 1;
+     881             :     }
+     882        2422 :     Operation* clone() const {
+     883        2422 :         return new Step();
+     884             :     }
+     885         606 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     886         606 :         return (args[0] >= 0.0 ? 1.0 : 0.0);
+     887             :     }
+     888             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     889             : };
+     890             : 
+     891             : class LEPTON_EXPORT Operation::Delta : public Operation {
+     892             : public:
+     893          17 :     Delta() {
+     894             :     }
+     895           8 :     std::string getName() const {
+     896           8 :         return "delta";
+     897             :     }
+     898        2395 :     Id getId() const {
+     899        2395 :         return DELTA;
+     900             :     }
+     901         182 :     int getNumArguments() const {
+     902         182 :         return 1;
+     903             :     }
+     904        1107 :     Operation* clone() const {
+     905        1107 :         return new Delta();
+     906             :     }
+     907         202 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     908         202 :         return (args[0] == 0.0 ? 1.0/0.0 : 0.0);
+     909             :     }
+     910             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     911             : };
+     912             : 
+     913             : class LEPTON_EXPORT Operation::Nandelta : public Operation {
+     914             : public:
+     915           8 :     Nandelta() {
+     916             :     }
+     917           6 :     std::string getName() const {
+     918           6 :         return "nandelta";
+     919             :     }
+     920         120 :     Id getId() const {
+     921         120 :         return NANDELTA;
+     922             :     }
+     923          50 :     int getNumArguments() const {
+     924          50 :         return 1;
+     925             :     }
+     926          90 :     Operation* clone() const {
+     927          90 :         return new Nandelta();
+     928             :     }
+     929         303 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     930         303 :         return (args[0] == 0.0 ? std::numeric_limits<double>::quiet_NaN() : 0.0);
+     931             :     }
+     932             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     933             : };
+     934             : 
+     935             : class LEPTON_EXPORT Operation::Square : public Operation {
+     936             : public:
+     937         378 :     Square() {
+     938             :     }
+     939         374 :     std::string getName() const {
+     940         374 :         return "square";
+     941             :     }
+     942       19443 :     Id getId() const {
+     943       19443 :         return SQUARE;
+     944             :     }
+     945        2333 :     int getNumArguments() const {
+     946        2333 :         return 1;
+     947             :     }
+     948       20360 :     Operation* clone() const {
+     949       20360 :         return new Square();
+     950             :     }
+     951        3155 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     952        3155 :         return args[0]*args[0];
+     953             :     }
+     954             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     955             : };
+     956             : 
+     957             : class LEPTON_EXPORT Operation::Cube : public Operation {
+     958             : public:
+     959        1107 :     Cube() {
+     960             :     }
+     961          23 :     std::string getName() const {
+     962          23 :         return "cube";
+     963             :     }
+     964        1405 :     Id getId() const {
+     965        1405 :         return CUBE;
+     966             :     }
+     967         256 :     int getNumArguments() const {
+     968         256 :         return 1;
+     969             :     }
+     970        1055 :     Operation* clone() const {
+     971        1055 :         return new Cube();
+     972             :     }
+     973         202 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     974         202 :         return args[0]*args[0]*args[0];
+     975             :     }
+     976             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     977             : };
+     978             : 
+     979             : class LEPTON_EXPORT Operation::Reciprocal : public Operation {
+     980             : public:
+     981          93 :     Reciprocal() {
+     982             :     }
+     983          81 :     std::string getName() const {
+     984          81 :         return "recip";
+     985             :     }
+     986        4059 :     Id getId() const {
+     987        4059 :         return RECIPROCAL;
+     988             :     }
+     989         834 :     int getNumArguments() const {
+     990         834 :         return 1;
+     991             :     }
+     992        4372 :     Operation* clone() const {
+     993        4372 :         return new Reciprocal();
+     994             :     }
+     995        2121 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+     996        2121 :         return 1.0/args[0];
+     997             :     }
+     998             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+     999             : };
+    1000             : 
+    1001             : class LEPTON_EXPORT Operation::AddConstant : public Operation {
+    1002             : public:
+    1003         534 :     AddConstant(double value) : value(value) {
+    1004             :     }
+    1005         792 :     std::string getName() const {
+    1006         792 :         std::stringstream name;
+    1007         792 :         name << value << "+";
+    1008         792 :         return name.str();
+    1009         792 :     }
+    1010       11904 :     Id getId() const {
+    1011       11904 :         return ADD_CONSTANT;
+    1012             :     }
+    1013        3461 :     int getNumArguments() const {
+    1014        3461 :         return 1;
+    1015             :     }
+    1016       37127 :     Operation* clone() const {
+    1017       37127 :         return new AddConstant(value);
+    1018             :     }
+    1019        2705 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1020        2705 :         return args[0]+value;
+    1021             :     }
+    1022             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+    1023             :     double getValue() const {
+    1024         846 :         return value;
+    1025             :     }
+    1026       10039 :     bool operator!=(const Operation& op) const {
+    1027       10039 :         const AddConstant* o = dynamic_cast<const AddConstant*>(&op);
+    1028       10039 :         return (o == NULL || o->value != value);
+    1029             :     }
+    1030             : private:
+    1031             :     double value;
+    1032             : };
+    1033             : 
+    1034             : class LEPTON_EXPORT Operation::MultiplyConstant : public Operation {
+    1035             : public:
+    1036        2135 :     MultiplyConstant(double value) : value(value) {
+    1037             :     }
+    1038        1412 :     std::string getName() const {
+    1039        1412 :         std::stringstream name;
+    1040        1412 :         name << value << "*";
+    1041        1412 :         return name.str();
+    1042        1412 :     }
+    1043       54125 :     Id getId() const {
+    1044       54125 :         return MULTIPLY_CONSTANT;
+    1045             :     }
+    1046       11256 :     int getNumArguments() const {
+    1047       11256 :         return 1;
+    1048             :     }
+    1049       55327 :     Operation* clone() const {
+    1050       55327 :         return new MultiplyConstant(value);
+    1051             :     }
+    1052        2626 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1053        2626 :         return args[0]*value;
+    1054             :     }
+    1055             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+    1056             :     double getValue() const {
+    1057        3550 :         return value;
+    1058             :     }
+    1059       35217 :     bool operator!=(const Operation& op) const {
+    1060       35217 :         const MultiplyConstant* o = dynamic_cast<const MultiplyConstant*>(&op);
+    1061       35217 :         return (o == NULL || o->value != value);
+    1062             :     }
+    1063             : private:
+    1064             :     double value;
+    1065             : };
+    1066             : 
+    1067             : class LEPTON_EXPORT Operation::PowerConstant : public Operation {
+    1068             : public:
+    1069        2298 :     PowerConstant(double value) : value(value) {
+    1070        2298 :         intValue = (int) value;
+    1071          69 :         isIntPower = (intValue == value);
+    1072             :     }
+    1073          37 :     std::string getName() const {
+    1074          37 :         std::stringstream name;
+    1075          37 :         name << "^" << value;
+    1076          37 :         return name.str();
+    1077          37 :     }
+    1078        2047 :     Id getId() const {
+    1079        2047 :         return POWER_CONSTANT;
+    1080             :     }
+    1081         454 :     int getNumArguments() const {
+    1082         454 :         return 1;
+    1083             :     }
+    1084        2229 :     Operation* clone() const {
+    1085        2229 :         return new PowerConstant(value);
+    1086             :     }
+    1087    10691410 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1088    10691410 :         if (isIntPower) {
+    1089             :             // Integer powers can be computed much more quickly by repeated multiplication.
+    1090             :             
+    1091    10687191 :             int exponent = intValue;
+    1092    10687191 :             double base = args[0];
+    1093    10687191 :             if (exponent < 0) {
+    1094         804 :                 exponent = -exponent;
+    1095         804 :                 base = 1.0/base;
+    1096             :             }
+    1097             :             double result = 1.0;
+    1098    42750671 :             while (exponent != 0) {
+    1099    32063480 :                 if ((exponent&1) == 1)
+    1100    23423887 :                     result *= base;
+    1101    32063480 :                 base *= base;
+    1102    32063480 :                 exponent = exponent>>1;
+    1103             :            }
+    1104             :            return result;
+    1105             :         }
+    1106             :         else
+    1107        4219 :         return std::pow(args[0], value);
+    1108             :     }
+    1109             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+    1110             :     double getValue() const {
+    1111             :         return value;
+    1112             :     }
+    1113         572 :     bool operator!=(const Operation& op) const {
+    1114         572 :         const PowerConstant* o = dynamic_cast<const PowerConstant*>(&op);
+    1115         572 :         return (o == NULL || o->value != value);
+    1116             :     }
+    1117          74 :     bool isInfixOperator() const {
+    1118          74 :         return true;
+    1119             :     }
+    1120             : private:
+    1121             :     double value;
+    1122             :     int intValue;
+    1123             :     bool isIntPower;
+    1124             : };
+    1125             : 
+    1126             : class LEPTON_EXPORT Operation::Min : public Operation {
+    1127             : public:
+    1128          68 :     Min() {
+    1129             :     }
+    1130           4 :     std::string getName() const {
+    1131           4 :         return "min";
+    1132             :     }
+    1133          80 :     Id getId() const {
+    1134          80 :         return MIN;
+    1135             :     }
+    1136          44 :     int getNumArguments() const {
+    1137          44 :         return 2;
+    1138             :     }
+    1139          60 :     Operation* clone() const {
+    1140          60 :         return new Min();
+    1141             :     }
+    1142         404 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1143             :         // parens around (std::min) are workaround for horrible microsoft max/min macro trouble
+    1144         404 :         return (std::min)(args[0], args[1]);
+    1145             :     }
+    1146             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+    1147             : };
+    1148             : 
+    1149             : class LEPTON_EXPORT Operation::Max : public Operation {
+    1150             : public:
+    1151          68 :     Max() {
+    1152             :     }
+    1153           4 :     std::string getName() const {
+    1154           4 :         return "max";
+    1155             :     }
+    1156          80 :     Id getId() const {
+    1157          80 :         return MAX;
+    1158             :     }
+    1159          44 :     int getNumArguments() const {
+    1160          44 :         return 2;
+    1161             :     }
+    1162          60 :     Operation* clone() const {
+    1163          60 :         return new Max();
+    1164             :     }
+    1165         404 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1166             :         // parens around (std::min) are workaround for horrible microsoft max/min macro trouble
+    1167         404 :         return (std::max)(args[0], args[1]);
+    1168             :     }
+    1169             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+    1170             : };
+    1171             : 
+    1172             : class LEPTON_EXPORT Operation::Abs : public Operation {
+    1173             : public:
+    1174          21 :     Abs() {
+    1175             :     }
+    1176          18 :     std::string getName() const {
+    1177          18 :         return "abs";
+    1178             :     }
+    1179         846 :     Id getId() const {
+    1180         846 :         return ABS;
+    1181             :     }
+    1182         160 :     int getNumArguments() const {
+    1183         160 :         return 1;
+    1184             :     }
+    1185         976 :     Operation* clone() const {
+    1186         976 :         return new Abs();
+    1187             :     }
+    1188         505 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1189         505 :         return std::abs(args[0]);
+    1190             :     }
+    1191             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+    1192             : };
+    1193             : 
+    1194             : class LEPTON_EXPORT Operation::Floor : public Operation {
+    1195             : public:
+    1196             : 
+    1197          34 :     Floor() {
+    1198             :     }
+    1199           2 :     std::string getName() const {
+    1200           2 :         return "floor";
+    1201             :     }
+    1202          40 :     Id getId() const {
+    1203          40 :         return FLOOR;
+    1204             :     }
+    1205          18 :     int getNumArguments() const {
+    1206          18 :         return 1;
+    1207             :     }
+    1208          30 :     Operation* clone() const {
+    1209          30 :         return new Floor();
+    1210             :     }
+    1211         101 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1212         101 :         return std::floor(args[0]);
+    1213             :     }
+    1214             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+    1215             : };
+    1216             : 
+    1217             : class LEPTON_EXPORT Operation::Ceil : public Operation {
+    1218             : public:
+    1219          34 :     Ceil() {
+    1220             :     }
+    1221           2 :     std::string getName() const {
+    1222           2 :         return "ceil";
+    1223             :     }
+    1224          40 :     Id getId() const {
+    1225          40 :         return CEIL;
+    1226             :     }
+    1227          18 :     int getNumArguments() const {
+    1228          18 :         return 1;
+    1229             :     }
+    1230          30 :     Operation* clone() const {
+    1231          30 :         return new Ceil();
+    1232             :     }
+    1233         101 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1234         101 :         return std::ceil(args[0]);
+    1235             :     }
+    1236             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+    1237             : };
+    1238             : 
+    1239             : class LEPTON_EXPORT Operation::Select : public Operation {
+    1240             : public:
+    1241          44 :     Select() {
+    1242             :     }
+    1243          24 :     std::string getName() const {
+    1244          24 :         return "select";
+    1245             :     }
+    1246         516 :     Id getId() const {
+    1247         516 :         return SELECT;
+    1248             :     }
+    1249         280 :     int getNumArguments() const {
+    1250         280 :         return 3;
+    1251             :     }
+    1252         400 :     Operation* clone() const {
+    1253         400 :         return new Select();
+    1254             :     }
+    1255        2432 :     double evaluate(double* args, const std::map<std::string, double>& variables) const {
+    1256        2432 :         return (args[0] != 0.0 ? args[1] : args[2]);
+    1257             :     }
+    1258             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const;
+    1259             : };
+    1260             : 
+    1261             : #define LEPTON_CLASS_OPERATION(Name,name,NAME,nargs,impl) \
+    1262             : class LEPTON_EXPORT Operation::Name : public Operation { \
+    1263             : public: \
+    1264             :     Name() { \
+    1265             :     } \
+    1266             :     std::string getName() const { \
+    1267             :         return #name; \
+    1268             :     } \
+    1269             :     Id getId() const { \
+    1270             :         return NAME; \
+    1271             :     } \
+    1272             :     int getNumArguments() const { \
+    1273             :         return nargs; \
+    1274             :     } \
+    1275             :     Operation* clone() const { \
+    1276             :         return new Name(); \
+    1277             :     } \
+    1278             :     double evaluate(double* args, const std::map<std::string, double>& variables) const { \
+    1279             :         return impl; \
+    1280             :     } \
+    1281             :     ExpressionTreeNode differentiate(const std::vector<ExpressionTreeNode>& children, const std::vector<ExpressionTreeNode>& childDerivs, const std::string& variable) const; \
+    1282             : }
+    1283             : 
+    1284         296 : LEPTON_CLASS_OPERATION(Acot,acot,ACOT,1,std::atan(1.0/args[0]));
+    1285         296 : LEPTON_CLASS_OPERATION(Asec,asec,ASEC,1,std::acos(1.0/args[0]));
+    1286         296 : LEPTON_CLASS_OPERATION(Acsc,acsc,ACSC,1,std::asin(1.0/args[0]));
+    1287        1144 : LEPTON_CLASS_OPERATION(Coth,coth,ACOT,1,1.0/std::tanh(args[0]));
+    1288         730 : LEPTON_CLASS_OPERATION(Sech,sech,SECH,1,1.0/std::cosh(args[0]));
+    1289         730 : LEPTON_CLASS_OPERATION(Csch,csch,CSCH,1,1.0/std::sinh(args[0]));
+    1290             : 
+    1291         195 : LEPTON_CLASS_OPERATION(Asinh,asinh,ASINH,1,std::asinh(args[0]));
+    1292         195 : LEPTON_CLASS_OPERATION(Acosh,acosh,ACOSH,1,std::acosh(args[0]));
+    1293         195 : LEPTON_CLASS_OPERATION(Atanh,atanh,ATANH,1,std::atanh(args[0]));
+    1294             : 
+    1295         296 : LEPTON_CLASS_OPERATION(Acoth,acoth,ACOTH,1,0.5*std::log((args[0]+1.0)/(args[0]-1.0)));
+    1296         296 : LEPTON_CLASS_OPERATION(Asech,asech,ASECH,1,std::log(std::sqrt(1.0/args[0]-1.0)*std::sqrt(1.0/args[0]+1.0)+1.0/args[0]));
+    1297         296 : LEPTON_CLASS_OPERATION(Acsch,acsch,ACSCH,1,std::log(1.0/args[0]+std::sqrt(1.0/(args[0]*args[0])+1.0)));
+    1298             : 
+    1299             : } // namespace lepton
+    1300             : } // namespace PLMD
+    1301             : 
+    1302             : #endif /*LEPTON_OPERATION_H_*/
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.cpp.func-sort-c.html b/coverage-libs/lepton/ParsedExpression.cpp.func-sort-c.html new file mode 100644 index 000000000000..9d89064584d6 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.cpp.func-sort-c.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22125786.0 %
Date:2024-02-22 21:58:47Functions:162176.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16ParsedExpression19renameNodeVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_St4lessISB_ESaISt4pairIKSB_SB_EEE0
_ZN4PLMD6lepton16ParsedExpressionC2Ev0
_ZNK4PLMD6lepton16ParsedExpression13createProgramEv0
_ZNK4PLMD6lepton16ParsedExpression15renameVariablesERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_St4lessIS8_ESaISt4pairIKS8_S8_EEE0
_ZNK4PLMD6lepton16ParsedExpression8evaluateEv0
_ZNK4PLMD6lepton16ParsedExpression13differentiateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE597
_ZN4PLMD6leptonlsERSoRKNS0_16ParsedExpressionE1088
_ZNK4PLMD6lepton16ParsedExpression8optimizeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE1112
_ZNK4PLMD6lepton16ParsedExpression24createCompiledExpressionEv1136
_ZNK4PLMD6lepton16ParsedExpression8optimizeEv1136
_ZN4PLMD6lepton16ParsedExpression16getConstantValueERKNS0_18ExpressionTreeNodeE3320
_ZN4PLMD6lepton16ParsedExpression13differentiateERKNS0_18ExpressionTreeNodeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE5818
_ZN4PLMD6leptonlsERSoRKNS0_18ExpressionTreeNodeE9949
_ZN4PLMD6lepton16ParsedExpression20preevaluateVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE19812
_ZN4PLMD6lepton16ParsedExpression34precalculateConstantSubexpressionsERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE22789
_ZN4PLMD6lepton16ParsedExpression27substituteSimplerExpressionERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE25877
_ZN4PLMD6lepton16ParsedExpression10isConstantERKNS0_18ExpressionTreeNodeE29780
_ZNK4PLMD6lepton16ParsedExpression8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE2008077
_ZN4PLMD6lepton16ParsedExpressionC2ERKNS0_18ExpressionTreeNodeE2012034
_ZN4PLMD6lepton16ParsedExpression8evaluateERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE2012733
_ZNK4PLMD6lepton16ParsedExpression11getRootNodeEv2013743
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.cpp.func.html b/coverage-libs/lepton/ParsedExpression.cpp.func.html new file mode 100644 index 000000000000..ff5f4b7b7fa6 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.cpp.func.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22125786.0 %
Date:2024-02-22 21:58:47Functions:162176.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton16ParsedExpression10isConstantERKNS0_18ExpressionTreeNodeE29780
_ZN4PLMD6lepton16ParsedExpression13differentiateERKNS0_18ExpressionTreeNodeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE5818
_ZN4PLMD6lepton16ParsedExpression16getConstantValueERKNS0_18ExpressionTreeNodeE3320
_ZN4PLMD6lepton16ParsedExpression19renameNodeVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_St4lessISB_ESaISt4pairIKSB_SB_EEE0
_ZN4PLMD6lepton16ParsedExpression20preevaluateVariablesERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE19812
_ZN4PLMD6lepton16ParsedExpression27substituteSimplerExpressionERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE25877
_ZN4PLMD6lepton16ParsedExpression34precalculateConstantSubexpressionsERKNS0_18ExpressionTreeNodeERSt3mapIiS2_St4lessIiESaISt4pairIKiS2_EEE22789
_ZN4PLMD6lepton16ParsedExpression8evaluateERKNS0_18ExpressionTreeNodeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessISB_ESaISt4pairIKSB_dEEE2012733
_ZN4PLMD6lepton16ParsedExpressionC2ERKNS0_18ExpressionTreeNodeE2012034
_ZN4PLMD6lepton16ParsedExpressionC2Ev0
_ZN4PLMD6leptonlsERSoRKNS0_16ParsedExpressionE1088
_ZN4PLMD6leptonlsERSoRKNS0_18ExpressionTreeNodeE9949
_ZNK4PLMD6lepton16ParsedExpression11getRootNodeEv2013743
_ZNK4PLMD6lepton16ParsedExpression13createProgramEv0
_ZNK4PLMD6lepton16ParsedExpression13differentiateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE597
_ZNK4PLMD6lepton16ParsedExpression15renameVariablesERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_St4lessIS8_ESaISt4pairIKS8_S8_EEE0
_ZNK4PLMD6lepton16ParsedExpression24createCompiledExpressionEv1136
_ZNK4PLMD6lepton16ParsedExpression8evaluateERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE2008077
_ZNK4PLMD6lepton16ParsedExpression8evaluateEv0
_ZNK4PLMD6lepton16ParsedExpression8optimizeERKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdSt4lessIS8_ESaISt4pairIKS8_dEEE1112
_ZNK4PLMD6lepton16ParsedExpression8optimizeEv1136
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.cpp.gcov.html b/coverage-libs/lepton/ParsedExpression.cpp.gcov.html new file mode 100644 index 000000000000..03af0ee876ba --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.cpp.gcov.html @@ -0,0 +1,528 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:22125786.0 %
Date:2024-02-22 21:58:47Functions:162176.2 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * -------------------------------------------------------------------------- *
+       3             :  *                                   Lepton                                   *
+       4             :  * -------------------------------------------------------------------------- *
+       5             :  * This is part of the Lepton expression parser originating from              *
+       6             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+       7             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+       8             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+       9             :  *                                                                            *
+      10             :  * Portions copyright (c) 2013-2016 Stanford University and the Authors.      *
+      11             :  * Authors: Peter Eastman                                                     *
+      12             :  * Contributors:                                                              *
+      13             :  *                                                                            *
+      14             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      15             :  * copy of this software and associated documentation files (the "Software"), *
+      16             :  * to deal in the Software without restriction, including without limitation  *
+      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      18             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      19             :  * Software is furnished to do so, subject to the following conditions:       *
+      20             :  *                                                                            *
+      21             :  * The above copyright notice and this permission notice shall be included in *
+      22             :  * all copies or substantial portions of the Software.                        *
+      23             :  *                                                                            *
+      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      27             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      28             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      29             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      30             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      31             :  * -------------------------------------------------------------------------- *
+      32             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      33             : /* -------------------------------------------------------------------------- *
+      34             :  *                                   lepton                                   *
+      35             :  * -------------------------------------------------------------------------- *
+      36             :  * This is part of the lepton expression parser originating from              *
+      37             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+      38             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+      39             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+      40             :  *                                                                            *
+      41             :  * Portions copyright (c) 2009-2021 Stanford University and the Authors.      *
+      42             :  * Authors: Peter Eastman                                                     *
+      43             :  * Contributors:                                                              *
+      44             :  *                                                                            *
+      45             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      46             :  * copy of this software and associated documentation files (the "Software"), *
+      47             :  * to deal in the Software without restriction, including without limitation  *
+      48             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      49             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      50             :  * Software is furnished to do so, subject to the following conditions:       *
+      51             :  *                                                                            *
+      52             :  * The above copyright notice and this permission notice shall be included in *
+      53             :  * all copies or substantial portions of the Software.                        *
+      54             :  *                                                                            *
+      55             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      56             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      57             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      58             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      59             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      60             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      61             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      62             :  * -------------------------------------------------------------------------- */
+      63             : 
+      64             : #include "ParsedExpression.h"
+      65             : #include "CompiledExpression.h"
+      66             : #include "ExpressionProgram.h"
+      67             : #include "Operation.h"
+      68             : #include <limits>
+      69             : #include <vector>
+      70             : 
+      71             : namespace PLMD {
+      72             : using namespace lepton;
+      73             : using namespace std;
+      74             : 
+      75           0 : ParsedExpression::ParsedExpression() : rootNode(ExpressionTreeNode()) {
+      76           0 : }
+      77             : 
+      78     2012034 : ParsedExpression::ParsedExpression(const ExpressionTreeNode& rootNode) : rootNode(rootNode) {
+      79     2012034 : }
+      80             : 
+      81     2013743 : const ExpressionTreeNode& ParsedExpression::getRootNode() const {
+      82     2013743 :     if (&rootNode.getOperation() == NULL)
+      83           0 :         throw Exception("Illegal call to an initialized ParsedExpression");
+      84     2013743 :     return rootNode;
+      85             : }
+      86             : 
+      87           0 : double ParsedExpression::evaluate() const {
+      88           0 :     return evaluate(getRootNode(), map<string, double>());
+      89             : }
+      90             : 
+      91     2008077 : double ParsedExpression::evaluate(const map<string, double>& variables) const {
+      92     2008077 :     return evaluate(getRootNode(), variables);
+      93             : }
+      94             : 
+      95     2012733 : double ParsedExpression::evaluate(const ExpressionTreeNode& node, const map<string, double>& variables) {
+      96     2012733 :     int numArgs = (int) node.getChildren().size();
+      97     4024836 :     vector<double> args(max(numArgs, 1));
+      98     2013849 :     for (int i = 0; i < numArgs; i++)
+      99        1121 :         args[i] = evaluate(node.getChildren()[i], variables);
+     100     4025434 :     return node.getOperation().evaluate(&args[0], variables);
+     101             : }
+     102             : 
+     103        1136 : ParsedExpression ParsedExpression::optimize() const {
+     104        1136 :     ExpressionTreeNode result = getRootNode();
+     105             :     vector<const ExpressionTreeNode*> examples;
+     106        1136 :     result.assignTags(examples);
+     107             :     map<int, ExpressionTreeNode> nodeCache;
+     108        1136 :     result = precalculateConstantSubexpressions(result, nodeCache);
+     109             :     while (true) {
+     110             :         examples.clear();
+     111        1136 :         result.assignTags(examples);
+     112             :         nodeCache.clear();
+     113        1136 :         ExpressionTreeNode simplified = substituteSimplerExpression(result, nodeCache);
+     114        1136 :         if (simplified == result)
+     115             :             break;
+     116           0 :         result = simplified;
+     117        1136 :     }
+     118        2272 :     return ParsedExpression(result);
+     119        1136 : }
+     120             : 
+     121        1112 : ParsedExpression ParsedExpression::optimize(const map<string, double>& variables) const {
+     122        1112 :     ExpressionTreeNode result = preevaluateVariables(getRootNode(), variables);
+     123             :     vector<const ExpressionTreeNode*> examples;
+     124        1112 :     result.assignTags(examples);
+     125             :     map<int, ExpressionTreeNode> nodeCache;
+     126        1112 :     result = precalculateConstantSubexpressions(result, nodeCache);
+     127             :     while (true) {
+     128             :         examples.clear();
+     129        2166 :         result.assignTags(examples);
+     130             :         nodeCache.clear();
+     131        2166 :         ExpressionTreeNode simplified = substituteSimplerExpression(result, nodeCache);
+     132        2166 :         if (simplified == result)
+     133             :             break;
+     134        1054 :         result = simplified;
+     135        2166 :     }
+     136        2224 :     return ParsedExpression(result);
+     137        1112 : }
+     138             : 
+     139       19812 : ExpressionTreeNode ParsedExpression::preevaluateVariables(const ExpressionTreeNode& node, const map<string, double>& variables) {
+     140       19812 :     if (node.getOperation().getId() == Operation::VARIABLE) {
+     141        3866 :         const Operation::Variable& var = dynamic_cast<const Operation::Variable&>(node.getOperation());
+     142        7732 :         map<string, double>::const_iterator iter = variables.find(var.getName());
+     143        3866 :         if (iter == variables.end())
+     144        3460 :             return node;
+     145         406 :         return ExpressionTreeNode(new Operation::Constant(iter->second));
+     146             :     }
+     147       15946 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     148       34646 :     for (int i = 0; i < (int) children.size(); i++)
+     149       18700 :         children[i] = preevaluateVariables(node.getChildren()[i], variables);
+     150       15946 :     return ExpressionTreeNode(node.getOperation().clone(), children);
+     151       15946 : }
+     152             : 
+     153       22789 : ExpressionTreeNode ParsedExpression::precalculateConstantSubexpressions(const ExpressionTreeNode& node, map<int, ExpressionTreeNode>& nodeCache) {
+     154       22789 :     auto cached = nodeCache.find(node.tag);
+     155       22789 :     if (cached != nodeCache.end())
+     156        4728 :         return cached->second;
+     157       18061 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     158       38602 :     for (int i = 0; i < (int) children.size(); i++)
+     159       20541 :         children[i] = precalculateConstantSubexpressions(node.getChildren()[i], nodeCache);
+     160       18061 :     ExpressionTreeNode result = ExpressionTreeNode(node.getOperation().clone(), children);
+     161       18061 :     if (node.getOperation().getId() == Operation::VARIABLE || node.getOperation().getId() == Operation::CUSTOM) {
+     162        2326 :         nodeCache[node.tag] = result;
+     163        2326 :         return result;
+     164             :     }
+     165       18370 :     for (int i = 0; i < (int) children.size(); i++)
+     166       14835 :         if (children[i].getOperation().getId() != Operation::CONSTANT) {
+     167       12200 :             nodeCache[node.tag] = result;
+     168       12200 :             return result;
+     169             :         }
+     170        3535 :     result = ExpressionTreeNode(new Operation::Constant(evaluate(result, map<string, double>())));
+     171        3535 :     nodeCache[node.tag] = result;
+     172        3535 :     return result;
+     173       18061 : }
+     174             : 
+     175       25877 : ExpressionTreeNode ParsedExpression::substituteSimplerExpression(const ExpressionTreeNode& node, map<int, ExpressionTreeNode>& nodeCache) {
+     176       25877 :     vector<ExpressionTreeNode> children(node.getChildren().size());
+     177       55709 :     for (int i = 0; i < (int) children.size(); i++) {
+     178       29832 :         const ExpressionTreeNode& child = node.getChildren()[i];
+     179       29832 :         auto cached = nodeCache.find(child.tag);
+     180       29832 :         if (cached == nodeCache.end()) {
+     181       22575 :             children[i] = substituteSimplerExpression(child, nodeCache);
+     182       22575 :             nodeCache[child.tag] = children[i];
+     183             :         }
+     184             :         else
+     185        7257 :             children[i] = cached->second;
+     186             :     }
+     187             :     
+     188             :     // Collect some info on constant expressions in children
+     189       25877 :     bool first_const = children.size() > 0 && isConstant(children[0]); // is first child constant?
+     190       25877 :     bool second_const = children.size() > 1 && isConstant(children[1]); ; // is second child constant?   
+     191             :     double first, second; // if yes, value of first and second child
+     192       25877 :     if (first_const)
+     193        1699 :         first = getConstantValue(children[0]);
+     194       25877 :     if (second_const)
+     195        1621 :         second = getConstantValue(children[1]);
+     196             : 
+     197       25877 :     switch (node.getOperation().getId()) {
+     198        2410 :         case Operation::ADD:
+     199             :         {
+     200        2410 :             if (first_const) {
+     201          74 :                 if (first == 0.0) { // Add 0
+     202          54 :                     return children[1];
+     203             :                 } else { // Add a constant
+     204          20 :                     return ExpressionTreeNode(new Operation::AddConstant(first), children[1]);
+     205             :                 }
+     206             :             }
+     207        2336 :             if (second_const) {
+     208         354 :                 if (second == 0.0) { // Add 0
+     209         104 :                     return children[0];
+     210             :                 } else { // Add a constant
+     211         250 :                     return ExpressionTreeNode(new Operation::AddConstant(second), children[0]);
+     212             :                 }
+     213             :             }
+     214        1982 :             if (children[1].getOperation().getId() == Operation::NEGATE) // a+(-b) = a-b
+     215           2 :                 return ExpressionTreeNode(new Operation::Subtract(), children[0], children[1].getChildren()[0]);
+     216        1980 :             if (children[0].getOperation().getId() == Operation::NEGATE) // (-a)+b = b-a
+     217           2 :                 return ExpressionTreeNode(new Operation::Subtract(), children[1], children[0].getChildren()[0]);
+     218             :             break;
+     219             :         }
+     220             :         case Operation::SUBTRACT:
+     221             :         {
+     222        1649 :             if (children[0] == children[1])
+     223           2 :                 return ExpressionTreeNode(new Operation::Constant(0.0)); // Subtracting anything from itself is 0
+     224        1647 :             if (first_const) {
+     225          84 :                 if (first == 0.0) // Subtract from 0
+     226           4 :                     return ExpressionTreeNode(new Operation::Negate(), children[1]);
+     227             :             }
+     228        1643 :             if (second_const) {
+     229         143 :                 if (second == 0.0) { // Subtract 0
+     230           5 :                     return children[0];
+     231             :                 } else { // Subtract a constant
+     232         138 :                     return ExpressionTreeNode(new Operation::AddConstant(-second), children[0]);
+     233             :                 }
+     234             :             }
+     235        1500 :             if (children[1].getOperation().getId() == Operation::NEGATE) // a-(-b) = a+b
+     236           2 :                 return ExpressionTreeNode(new Operation::Add(), children[0], children[1].getChildren()[0]);
+     237             :             break;
+     238             :         }
+     239        5421 :         case Operation::MULTIPLY:
+     240             :         {   
+     241        5421 :             if ((first_const && first == 0.0) || (second_const && second == 0.0)) // Multiply by 0
+     242         182 :                 return ExpressionTreeNode(new Operation::Constant(0.0));
+     243        5239 :             if (first_const && first == 1.0) // Multiply by 1
+     244          18 :                 return children[1];
+     245        5221 :             if (second_const && second == 1.0) // Multiply by 1
+     246         489 :                 return children[0];
+     247        4732 :             if (first_const) { // Multiply by a constant
+     248        1388 :                 if (children[1].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine two multiplies into a single one
+     249          24 :                     return ExpressionTreeNode(new Operation::MultiplyConstant(first*dynamic_cast<const Operation::MultiplyConstant*>(&children[1].getOperation())->getValue()), children[1].getChildren()[0]);
+     250        1364 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(first), children[1]);
+     251             :             }
+     252        3344 :             if (second_const) { // Multiply by a constant
+     253          23 :                 if (children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine two multiplies into a single one
+     254           1 :                     return ExpressionTreeNode(new Operation::MultiplyConstant(second*dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()), children[0].getChildren()[0]);
+     255          22 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(second), children[0]);
+     256             :             }
+     257        3321 :             if (children[0].getOperation().getId() == Operation::NEGATE && children[1].getOperation().getId() == Operation::NEGATE) // The two negations cancel
+     258           0 :                 return ExpressionTreeNode(new Operation::Multiply(), children[0].getChildren()[0], children[1].getChildren()[0]);
+     259        3321 :             if (children[0].getOperation().getId() == Operation::NEGATE && children[1].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Negate the constant
+     260           0 :                 return ExpressionTreeNode(new Operation::Multiply(), children[0].getChildren()[0], ExpressionTreeNode(new Operation::MultiplyConstant(-dynamic_cast<const Operation::MultiplyConstant*>(&children[1].getOperation())->getValue()), children[1].getChildren()[0]));
+     261        3321 :             if (children[1].getOperation().getId() == Operation::NEGATE && children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Negate the constant
+     262         192 :                 return ExpressionTreeNode(new Operation::Multiply(), ExpressionTreeNode(new Operation::MultiplyConstant(-dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()), children[0].getChildren()[0]), children[1].getChildren()[0]);
+     263        3129 :             if (children[0].getOperation().getId() == Operation::NEGATE) // Pull the negation out so it can possibly be optimized further
+     264           2 :                 return ExpressionTreeNode(new Operation::Negate(), ExpressionTreeNode(new Operation::Multiply(), children[0].getChildren()[0], children[1]));
+     265        3127 :             if (children[1].getOperation().getId() == Operation::NEGATE) // Pull the negation out so it can possibly be optimized further
+     266           0 :                 return ExpressionTreeNode(new Operation::Negate(), ExpressionTreeNode(new Operation::Multiply(), children[0], children[1].getChildren()[0]));
+     267        3127 :             if (children[1].getOperation().getId() == Operation::RECIPROCAL) // a*(1/b) = a/b
+     268           0 :                 return ExpressionTreeNode(new Operation::Divide(), children[0], children[1].getChildren()[0]);
+     269        3127 :             if (children[0].getOperation().getId() == Operation::RECIPROCAL) // (1/a)*b = b/a
+     270           2 :                 return ExpressionTreeNode(new Operation::Divide(), children[1], children[0].getChildren()[0]);
+     271        3125 :             if (children[0] == children[1])
+     272         134 :                 return ExpressionTreeNode(new Operation::Square(), children[0]); // x*x = square(x)
+     273        2991 :             if (children[0].getOperation().getId() == Operation::SQUARE && children[0].getChildren()[0] == children[1])
+     274           2 :                 return ExpressionTreeNode(new Operation::Cube(), children[1]); // x*x*x = cube(x)
+     275        2989 :             if (children[1].getOperation().getId() == Operation::SQUARE && children[1].getChildren()[0] == children[0])
+     276           0 :                 return ExpressionTreeNode(new Operation::Cube(), children[0]); // x*x*x = cube(x)
+     277             :             break;
+     278             :         }
+     279             :         case Operation::DIVIDE:
+     280             :         {
+     281         243 :             if (children[0] == children[1])
+     282           2 :                 return ExpressionTreeNode(new Operation::Constant(1.0)); // Dividing anything from itself is 0
+     283         241 :             if (first_const && first == 0.0) // 0 divided by something
+     284           6 :                 return ExpressionTreeNode(new Operation::Constant(0.0));
+     285         235 :             if (first_const && first == 1.0) // 1 divided by something
+     286          18 :                 return ExpressionTreeNode(new Operation::Reciprocal(), children[1]);
+     287         217 :             if (second_const && second == 1.0) // Divide by 1
+     288           0 :                 return children[0];
+     289         217 :             if (second_const) {
+     290          35 :                 if (children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine a multiply and a divide into one multiply
+     291           0 :                     return ExpressionTreeNode(new Operation::MultiplyConstant(dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()/second), children[0].getChildren()[0]);
+     292          35 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(1.0/second), children[0]); // Replace a divide with a multiply
+     293             :             }
+     294         182 :             if (children[0].getOperation().getId() == Operation::NEGATE && children[1].getOperation().getId() == Operation::NEGATE) // The two negations cancel
+     295           0 :                 return ExpressionTreeNode(new Operation::Divide(), children[0].getChildren()[0], children[1].getChildren()[0]);
+     296         182 :             if (children[1].getOperation().getId() == Operation::NEGATE && children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Negate the constant
+     297           0 :                 return ExpressionTreeNode(new Operation::Divide(), ExpressionTreeNode(new Operation::MultiplyConstant(-dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()), children[0].getChildren()[0]), children[1].getChildren()[0]);
+     298         182 :             if (children[0].getOperation().getId() == Operation::NEGATE) // Pull the negation out so it can possibly be optimized further
+     299          22 :                 return ExpressionTreeNode(new Operation::Negate(), ExpressionTreeNode(new Operation::Divide(), children[0].getChildren()[0], children[1]));
+     300         160 :             if (children[1].getOperation().getId() == Operation::NEGATE) // Pull the negation out so it can possibly be optimized further
+     301           0 :                 return ExpressionTreeNode(new Operation::Negate(), ExpressionTreeNode(new Operation::Divide(), children[0], children[1].getChildren()[0]));
+     302         160 :             if (children[1].getOperation().getId() == Operation::RECIPROCAL) // a/(1/b) = a*b
+     303           2 :                 return ExpressionTreeNode(new Operation::Multiply(), children[0], children[1].getChildren()[0]);
+     304             :             break;
+     305             :         }
+     306         329 :         case Operation::POWER:
+     307             :         {
+     308         329 :             if (first_const && first == 0.0) // 0 to any power is 0
+     309           6 :                 return ExpressionTreeNode(new Operation::Constant(0.0));
+     310         323 :             if (first_const && first == 1.0) // 1 to any power is 1
+     311           6 :                 return ExpressionTreeNode(new Operation::Constant(1.0));
+     312         317 :             if (second_const) { // Constant exponent
+     313         305 :                 if (second == 0.0) // x^0 = 1
+     314           0 :                     return ExpressionTreeNode(new Operation::Constant(1.0));
+     315         305 :                 if (second == 1.0) // x^1 = x
+     316          59 :                     return children[0];
+     317         246 :                 if (second == -1.0) // x^-1 = recip(x)
+     318           0 :                     return ExpressionTreeNode(new Operation::Reciprocal(), children[0]);
+     319         246 :                 if (second == 2.0) // x^2 = square(x)
+     320         124 :                     return ExpressionTreeNode(new Operation::Square(), children[0]);
+     321         122 :                 if (second == 3.0) // x^3 = cube(x)
+     322          46 :                     return ExpressionTreeNode(new Operation::Cube(), children[0]);
+     323          76 :                 if (second == 0.5) // x^0.5 = sqrt(x)
+     324           7 :                     return ExpressionTreeNode(new Operation::Sqrt(), children[0]);
+     325             :                 // Constant power
+     326          69 :                 return ExpressionTreeNode(new Operation::PowerConstant(second), children[0]);
+     327             :             }
+     328             :             break;
+     329             :         }
+     330             :         case Operation::NEGATE:
+     331             :         {
+     332         640 :             if (children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine a multiply and a negate into a single multiply
+     333          10 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(-dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()), children[0].getChildren()[0]);
+     334         630 :             if (first_const) // Negate a constant
+     335           0 :                 return ExpressionTreeNode(new Operation::Constant(-first));
+     336         630 :             if (children[0].getOperation().getId() == Operation::NEGATE) // The two negations cancel
+     337           0 :                 return children[0].getChildren()[0];
+     338             :             break;
+     339             :         }
+     340             :         case Operation::MULTIPLY_CONSTANT:
+     341             :         {
+     342        3644 :             if (children[0].getOperation().getId() == Operation::MULTIPLY_CONSTANT) // Combine two multiplies into a single one
+     343           0 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(dynamic_cast<const Operation::MultiplyConstant*>(&node.getOperation())->getValue()*dynamic_cast<const Operation::MultiplyConstant*>(&children[0].getOperation())->getValue()), children[0].getChildren()[0]);
+     344        3644 :             if (first_const) // Multiply two constants
+     345           0 :                 return ExpressionTreeNode(new Operation::Constant(dynamic_cast<const Operation::MultiplyConstant*>(&node.getOperation())->getValue()*getConstantValue(children[0])));
+     346        3644 :             if (children[0].getOperation().getId() == Operation::NEGATE) // Combine a multiply and a negate into a single multiply
+     347         439 :                 return ExpressionTreeNode(new Operation::MultiplyConstant(-dynamic_cast<const Operation::MultiplyConstant*>(&node.getOperation())->getValue()), children[0].getChildren()[0]);
+     348             :             break;
+     349             :         }
+     350             :         case Operation::SQRT:
+     351             :         {
+     352         221 :             if (children[0].getOperation().getId() == Operation::SQUARE) // sqrt(square(x)) = abs(x)
+     353           4 :                 return ExpressionTreeNode(new Operation::Abs(), children[0].getChildren()[0]);
+     354             :         }
+     355             :         case Operation::SQUARE:
+     356             :         {
+     357         875 :             if (children[0].getOperation().getId() == Operation::SQRT) // square(sqrt(x)) = x
+     358          27 :                 return children[0].getChildren()[0];
+     359             :         }
+     360             :         default:
+     361             :         {
+     362             :             // If operation ID is not one of the above,
+     363             :             // we don't substitute a simpler expression.
+     364             :             break;
+     365             :         }
+     366             : 
+     367             :     }
+     368       21980 :     return ExpressionTreeNode(node.getOperation().clone(), children);
+     369       25877 : }
+     370             : 
+     371         597 : ParsedExpression ParsedExpression::differentiate(const string& variable) const {
+     372             :     vector<const ExpressionTreeNode*> examples;
+     373         597 :     getRootNode().assignTags(examples);
+     374             :     map<int, ExpressionTreeNode> nodeCache;
+     375        1194 :     return differentiate(getRootNode(), variable, nodeCache);
+     376             : }
+     377             : 
+     378        5818 : ExpressionTreeNode ParsedExpression::differentiate(const ExpressionTreeNode& node, const string& variable, map<int, ExpressionTreeNode>& nodeCache) {
+     379        5818 :     auto cached = nodeCache.find(node.tag);
+     380        5818 :     if (cached != nodeCache.end())
+     381         785 :         return cached->second;
+     382        5033 :     vector<ExpressionTreeNode> childDerivs(node.getChildren().size());
+     383       10254 :     for (int i = 0; i < (int) childDerivs.size(); i++)
+     384        5221 :         childDerivs[i] = differentiate(node.getChildren()[i], variable, nodeCache);
+     385        5033 :     ExpressionTreeNode result = node.getOperation().differentiate(node.getChildren(), childDerivs, variable);
+     386        5033 :     nodeCache[node.tag] = result;
+     387        5033 :     return result;
+     388        5033 : }
+     389             : 
+     390       29780 : bool ParsedExpression::isConstant(const ExpressionTreeNode& node) {
+     391       29780 :     return (node.getOperation().getId() == Operation::CONSTANT);
+     392             : }
+     393             : 
+     394        3320 : double ParsedExpression::getConstantValue(const ExpressionTreeNode& node) {
+     395        3320 :     if (node.getOperation().getId() != Operation::CONSTANT) {
+     396           0 :         throw Exception("getConstantValue called on a non-constant ExpressionNode");
+     397             :     }
+     398        3320 :     return dynamic_cast<const Operation::Constant&>(node.getOperation()).getValue();
+     399             : }
+     400             : 
+     401           0 : ExpressionProgram ParsedExpression::createProgram() const {
+     402           0 :     return ExpressionProgram(*this);
+     403             : }
+     404             : 
+     405        1136 : CompiledExpression ParsedExpression::createCompiledExpression() const {
+     406        1136 :     return CompiledExpression(*this);
+     407             : }
+     408             : 
+     409           0 : ParsedExpression ParsedExpression::renameVariables(const map<string, string>& replacements) const {
+     410           0 :     return ParsedExpression(renameNodeVariables(getRootNode(), replacements));
+     411             : }
+     412             : 
+     413           0 : ExpressionTreeNode ParsedExpression::renameNodeVariables(const ExpressionTreeNode& node, const map<string, string>& replacements) {
+     414           0 :     if (node.getOperation().getId() == Operation::VARIABLE) {
+     415           0 :         map<string, string>::const_iterator replace = replacements.find(node.getOperation().getName());
+     416           0 :         if (replace != replacements.end())
+     417           0 :             return ExpressionTreeNode(new Operation::Variable(replace->second));
+     418             :     }
+     419             :     vector<ExpressionTreeNode> children;
+     420           0 :     for (int i = 0; i < (int) node.getChildren().size(); i++)
+     421           0 :         children.push_back(renameNodeVariables(node.getChildren()[i], replacements));
+     422           0 :     return ExpressionTreeNode(node.getOperation().clone(), children);
+     423           0 : }
+     424             : 
+     425        9949 : ostream& lepton::operator<<(ostream& out, const ExpressionTreeNode& node) {
+     426        9949 :     if (node.getOperation().isInfixOperator() && node.getChildren().size() == 2) {
+     427        5811 :         out << "(" << node.getChildren()[0] << ")" << node.getOperation().getName() << "(" << node.getChildren()[1] << ")";
+     428             :     }
+     429        8012 :     else if (node.getOperation().isInfixOperator() && node.getChildren().size() == 1) {
+     430          74 :         out << "(" << node.getChildren()[0] << ")" << node.getOperation().getName();
+     431             :     }
+     432             :     else {
+     433        7975 :         out << node.getOperation().getName();
+     434        7975 :         if (node.getChildren().size() > 0) {
+     435        4886 :             out << "(";
+     436        9836 :             for (int i = 0; i < (int) node.getChildren().size(); i++) {
+     437        4950 :                 if (i > 0)
+     438          64 :                     out << ", ";
+     439        4950 :                 out << node.getChildren()[i];
+     440             :             }
+     441        4886 :             out << ")";
+     442             :         }
+     443             :     }
+     444        9949 :     return out;
+     445             : }
+     446             : 
+     447        1088 : ostream& lepton::operator<<(ostream& out, const ParsedExpression& exp) {
+     448        1088 :     out << exp.getRootNode();
+     449        1088 :     return out;
+     450             : }
+     451             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.h.func-sort-c.html b/coverage-libs/lepton/ParsedExpression.h.func-sort-c.html new file mode 100644 index 000000000000..149f9e2caf1c --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.h.func.html b/coverage-libs/lepton/ParsedExpression.h.func.html new file mode 100644 index 000000000000..a881f44cf994 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/ParsedExpression.h.gcov.html b/coverage-libs/lepton/ParsedExpression.h.gcov.html new file mode 100644 index 000000000000..312994529492 --- /dev/null +++ b/coverage-libs/lepton/ParsedExpression.h.gcov.html @@ -0,0 +1,242 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/ParsedExpression.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - ParsedExpression.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:11100.0 %
Date:2024-02-22 21:58:47Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * -------------------------------------------------------------------------- *
+       3             :  *                                   Lepton                                   *
+       4             :  * -------------------------------------------------------------------------- *
+       5             :  * This is part of the Lepton expression parser originating from              *
+       6             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+       7             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+       8             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+       9             :  *                                                                            *
+      10             :  * Portions copyright (c) 2013-2016 Stanford University and the Authors.      *
+      11             :  * Authors: Peter Eastman                                                     *
+      12             :  * Contributors:                                                              *
+      13             :  *                                                                            *
+      14             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      15             :  * copy of this software and associated documentation files (the "Software"), *
+      16             :  * to deal in the Software without restriction, including without limitation  *
+      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      18             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      19             :  * Software is furnished to do so, subject to the following conditions:       *
+      20             :  *                                                                            *
+      21             :  * The above copyright notice and this permission notice shall be included in *
+      22             :  * all copies or substantial portions of the Software.                        *
+      23             :  *                                                                            *
+      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      27             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      28             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      29             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      30             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      31             :  * -------------------------------------------------------------------------- *
+      32             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      33             : #ifndef __PLUMED_lepton_ParsedExpression_h
+      34             : #define __PLUMED_lepton_ParsedExpression_h
+      35             : 
+      36             : /* -------------------------------------------------------------------------- *
+      37             :  *                                   lepton                                   *
+      38             :  * -------------------------------------------------------------------------- *
+      39             :  * This is part of the lepton expression parser originating from              *
+      40             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+      41             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+      42             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+      43             :  *                                                                            *
+      44             :  * Portions copyright (c) 2009=2021 Stanford University and the Authors.      *
+      45             :  * Authors: Peter Eastman                                                     *
+      46             :  * Contributors:                                                              *
+      47             :  *                                                                            *
+      48             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      49             :  * copy of this software and associated documentation files (the "Software"), *
+      50             :  * to deal in the Software without restriction, including without limitation  *
+      51             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      52             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      53             :  * Software is furnished to do so, subject to the following conditions:       *
+      54             :  *                                                                            *
+      55             :  * The above copyright notice and this permission notice shall be included in *
+      56             :  * all copies or substantial portions of the Software.                        *
+      57             :  *                                                                            *
+      58             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      59             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      60             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      61             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      62             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      63             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      64             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      65             :  * -------------------------------------------------------------------------- */
+      66             : 
+      67             : #include "ExpressionTreeNode.h"
+      68             : #include "windowsIncludes.h"
+      69             : #include <map>
+      70             : #include <string>
+      71             : 
+      72             : namespace PLMD {
+      73             : namespace lepton {
+      74             : 
+      75             : class CompiledExpression;
+      76             : class ExpressionProgram;
+      77             : 
+      78             : /**
+      79             :  * This class represents the result of parsing an expression.  It provides methods for working with the
+      80             :  * expression in various ways, such as evaluating it, getting the tree representation of the expresson, etc.
+      81             :  */
+      82             : 
+      83     2011426 : class LEPTON_EXPORT ParsedExpression {
+      84             : public:
+      85             :     /**
+      86             :      * Create an uninitialized ParsedExpression.  This exists so that ParsedExpressions can be put in STL containers.
+      87             :      * Doing anything with it will produce an exception.
+      88             :      */
+      89             :     ParsedExpression();
+      90             :     /**
+      91             :      * Create a ParsedExpression.  Normally you will not call this directly.  Instead, use the Parser class
+      92             :      * to parse expression.
+      93             :      */
+      94             :     ParsedExpression(const ExpressionTreeNode& rootNode);
+      95             :     /**
+      96             :      * Get the root node of the expression's abstract syntax tree.
+      97             :      */
+      98             :     const ExpressionTreeNode& getRootNode() const;
+      99             :     /**
+     100             :      * Evaluate the expression.  If the expression involves any variables, this method will throw an exception.
+     101             :      */
+     102             :     double evaluate() const;
+     103             :     /**
+     104             :      * Evaluate the expression.
+     105             :      *
+     106             :      * @param variables    a map specifying the values of all variables that appear in the expression.  If any
+     107             :      *                     variable appears in the expression but is not included in this map, an exception
+     108             :      *                     will be thrown.
+     109             :      */
+     110             :     double evaluate(const std::map<std::string, double>& variables) const;
+     111             :     /**
+     112             :      * Create a new ParsedExpression which produces the same result as this one, but is faster to evaluate.
+     113             :      */
+     114             :     ParsedExpression optimize() const;
+     115             :     /**
+     116             :      * Create a new ParsedExpression which produces the same result as this one, but is faster to evaluate.
+     117             :      *
+     118             :      * @param variables    a map specifying values for a subset of variables that appear in the expression.
+     119             :      *                     All occurrences of these variables in the expression are replaced with the values
+     120             :      *                     specified.
+     121             :      */
+     122             :     ParsedExpression optimize(const std::map<std::string, double>& variables) const;
+     123             :     /**
+     124             :      * Create a new ParsedExpression which is the analytic derivative of this expression with respect to a
+     125             :      * particular variable.
+     126             :      *
+     127             :      * @param variable     the variable with respect to which the derivate should be taken
+     128             :      */
+     129             :     ParsedExpression differentiate(const std::string& variable) const;
+     130             :     /**
+     131             :      * Create an ExpressionProgram that represents the same calculation as this expression.
+     132             :      */
+     133             :     ExpressionProgram createProgram() const;
+     134             :     /**
+     135             :      * Create a CompiledExpression that represents the same calculation as this expression.
+     136             :      */
+     137             :     CompiledExpression createCompiledExpression() const;
+     138             :     /**
+     139             :      * Create a new ParsedExpression which is identical to this one, except that the names of some
+     140             :      * variables have been changed.
+     141             :      *
+     142             :      * @param replacements    a map whose keys are the names of variables, and whose values are the
+     143             :      *                        new names to replace them with
+     144             :      */
+     145             :     ParsedExpression renameVariables(const std::map<std::string, std::string>& replacements) const;
+     146             : private:
+     147             :     static double evaluate(const ExpressionTreeNode& node, const std::map<std::string, double>& variables);
+     148             :     static ExpressionTreeNode preevaluateVariables(const ExpressionTreeNode& node, const std::map<std::string, double>& variables);
+     149             :     static ExpressionTreeNode precalculateConstantSubexpressions(const ExpressionTreeNode& node, std::map<int, ExpressionTreeNode>& nodeCache);
+     150             :     static ExpressionTreeNode substituteSimplerExpression(const ExpressionTreeNode& node, std::map<int, ExpressionTreeNode>& nodeCache);
+     151             :     static ExpressionTreeNode differentiate(const ExpressionTreeNode& node, const std::string& variable, std::map<int, ExpressionTreeNode>& nodeCache);
+     152             :     static bool isConstant(const ExpressionTreeNode& node);
+     153             :     static double getConstantValue(const ExpressionTreeNode& node);
+     154             :     static ExpressionTreeNode renameNodeVariables(const ExpressionTreeNode& node, const std::map<std::string, std::string>& replacements);
+     155             :     ExpressionTreeNode rootNode;
+     156             : };
+     157             : 
+     158             : LEPTON_EXPORT std::ostream& operator<<(std::ostream& out, const ExpressionTreeNode& node);
+     159             : 
+     160             : LEPTON_EXPORT std::ostream& operator<<(std::ostream& out, const ParsedExpression& exp);
+     161             : 
+     162             : } // namespace lepton
+     163             : } // namespace PLMD
+     164             : 
+     165             : #endif /*LEPTON_PARSED_EXPRESSION_H_*/
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Parser.cpp.func-sort-c.html b/coverage-libs/lepton/Parser.cpp.func-sort-c.html new file mode 100644 index 000000000000..416a409b4390 --- /dev/null +++ b/coverage-libs/lepton/Parser.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Parser.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Parser.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27529892.3 %
Date:2024-02-22 21:58:47Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton6Parser4trimERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEEENKUlvE_clEv40
_ZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE1693
_ZN4PLMD6lepton6Parser20getOperatorOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5036
_ZN4PLMD6lepton9ConstantsB5cxx11Ev2009189
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009208
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE2009208
_ZN4PLMD6lepton6Parser8tokenizeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009212
_ZN4PLMD6lepton6Parser15parsePrecedenceERKSt6vectorINS0_10ParseTokenESaIS3_EERiRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionESt4lessISF_ESaISt4pairIKSF_SH_EEERKS9_ISF_NS0_18ExpressionTreeNodeESJ_SaISK_ISL_SR_EEEi2016749
_ZN4PLMD6lepton6Parser12getNextTokenERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi2024272
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Parser.cpp.func.html b/coverage-libs/lepton/Parser.cpp.func.html new file mode 100644 index 000000000000..88fe9d2e2e61 --- /dev/null +++ b/coverage-libs/lepton/Parser.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Parser.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Parser.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27529892.3 %
Date:2024-02-22 21:58:47Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6lepton6Parser12getNextTokenERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi2024272
_ZN4PLMD6lepton6Parser15parsePrecedenceERKSt6vectorINS0_10ParseTokenESaIS3_EERiRKSt3mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_14CustomFunctionESt4lessISF_ESaISt4pairIKSF_SH_EEERKS9_ISF_NS0_18ExpressionTreeNodeESJ_SaISK_ISL_SR_EEEi2016749
_ZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE1693
_ZN4PLMD6lepton6Parser20getOperatorOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE5036
_ZN4PLMD6lepton6Parser4trimERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009208
_ZN4PLMD6lepton6Parser5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEE2009208
_ZN4PLMD6lepton6Parser8tokenizeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2009212
_ZN4PLMD6lepton9ConstantsB5cxx11Ev2009189
_ZZN4PLMD6lepton6Parser20getFunctionOperationERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt3mapIS7_PNS0_14CustomFunctionESt4lessIS7_ESaISt4pairIS8_SC_EEEENKUlvE_clEv40
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/Parser.cpp.gcov.html b/coverage-libs/lepton/Parser.cpp.gcov.html new file mode 100644 index 000000000000..8774cc909511 --- /dev/null +++ b/coverage-libs/lepton/Parser.cpp.gcov.html @@ -0,0 +1,585 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton/Parser.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - lepton - Parser.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:27529892.3 %
Date:2024-02-22 21:58:47Functions:1010100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * -------------------------------------------------------------------------- *
+       3             :  *                                   Lepton                                   *
+       4             :  * -------------------------------------------------------------------------- *
+       5             :  * This is part of the Lepton expression parser originating from              *
+       6             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+       7             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+       8             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+       9             :  *                                                                            *
+      10             :  * Portions copyright (c) 2013-2016 Stanford University and the Authors.      *
+      11             :  * Authors: Peter Eastman                                                     *
+      12             :  * Contributors:                                                              *
+      13             :  *                                                                            *
+      14             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      15             :  * copy of this software and associated documentation files (the "Software"), *
+      16             :  * to deal in the Software without restriction, including without limitation  *
+      17             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      18             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      19             :  * Software is furnished to do so, subject to the following conditions:       *
+      20             :  *                                                                            *
+      21             :  * The above copyright notice and this permission notice shall be included in *
+      22             :  * all copies or substantial portions of the Software.                        *
+      23             :  *                                                                            *
+      24             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      25             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      26             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      27             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      28             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      29             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      30             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      31             :  * -------------------------------------------------------------------------- *
+      32             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      33             : /* -------------------------------------------------------------------------- *
+      34             :  *                                   lepton                                   *
+      35             :  * -------------------------------------------------------------------------- *
+      36             :  * This is part of the lepton expression parser originating from              *
+      37             :  * Simbios, the NIH National Center for Physics-Based Simulation of           *
+      38             :  * Biological Structures at Stanford, funded under the NIH Roadmap for        *
+      39             :  * Medical Research, grant U54 GM072970. See https://simtk.org.               *
+      40             :  *                                                                            *
+      41             :  * Portions copyright (c) 2009-2019 Stanford University and the Authors.      *
+      42             :  * Authors: Peter Eastman                                                     *
+      43             :  * Contributors:                                                              *
+      44             :  *                                                                            *
+      45             :  * Permission is hereby granted, free of charge, to any person obtaining a    *
+      46             :  * copy of this software and associated documentation files (the "Software"), *
+      47             :  * to deal in the Software without restriction, including without limitation  *
+      48             :  * the rights to use, copy, modify, merge, publish, distribute, sublicense,   *
+      49             :  * and/or sell copies of the Software, and to permit persons to whom the      *
+      50             :  * Software is furnished to do so, subject to the following conditions:       *
+      51             :  *                                                                            *
+      52             :  * The above copyright notice and this permission notice shall be included in *
+      53             :  * all copies or substantial portions of the Software.                        *
+      54             :  *                                                                            *
+      55             :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR *
+      56             :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,   *
+      57             :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL    *
+      58             :  * THE AUTHORS, CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,    *
+      59             :  * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR      *
+      60             :  * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE  *
+      61             :  * USE OR OTHER DEALINGS IN THE SOFTWARE.                                     *
+      62             :  * -------------------------------------------------------------------------- */
+      63             : 
+      64             : #include "Parser.h"
+      65             : #include "CustomFunction.h"
+      66             : #include "Exception.h"
+      67             : #include "ExpressionTreeNode.h"
+      68             : #include "Operation.h"
+      69             : #include "ParsedExpression.h"
+      70             : #include <cctype>
+      71             : #include <iostream>
+      72             : 
+      73             : namespace PLMD {
+      74             : using namespace lepton;
+      75             : using namespace std;
+      76             : 
+      77             : namespace lepton {
+      78             : 
+      79             : static const string Digits = "0123456789";
+      80             : static const string Operators = "+-*/^";
+      81             : static const bool LeftAssociative[] = {true, true, true, true, false};
+      82             : static const int Precedence[] = {0, 0, 1, 1, 3};
+      83             : static const Operation::Id OperationId[] = {Operation::ADD, Operation::SUBTRACT, Operation::MULTIPLY, Operation::DIVIDE, Operation::POWER};
+      84             : 
+      85     2009189 : const std::map<std::string, double> & Constants() {
+      86             :   static const std::map<std::string, double> constants = {
+      87             :   {"e", std::exp(1.0)},
+      88             :   {"log2e", 1.0/std::log(2.0)},
+      89             :   {"log10e", 1.0/std::log(10.0)},
+      90             :   {"ln2", std::log(2.0)},
+      91             :   {"ln10", std::log(10.0)},
+      92             :   {"pi", 3.14159265358979323844},
+      93             :   {"pi_2", 3.14159265358979323844*0.5},
+      94             :   {"pi_4", 3.14159265358979323844*0.25},
+      95             : //  {"1_pi", 1.0/pi},
+      96             : //  {"2_pi", 2.0/pi},
+      97             : //  {"2_sqrtpi", 2.0/std::sqrt(pi)},
+      98             :   {"sqrt2", std::sqrt(2.0)},
+      99             :   {"sqrt1_2", std::sqrt(0.5)}
+     100     2010223 :   };
+     101     2009189 :   return constants;
+     102             : }
+     103             : 
+     104             : }
+     105             : 
+     106             : 
+     107     6111977 : class lepton::ParseToken {
+     108             : public:
+     109             :     enum Type {Number, Operator, Variable, Function, LeftParen, RightParen, Comma, Whitespace};
+     110             : 
+     111     2024272 :     ParseToken(string text, Type type) : text(text), type(type) {
+     112             :     }
+     113             :     const string& getText() const {
+     114          15 :         return text;
+     115             :     }
+     116             :     Type getType() const {
+     117       13167 :         return type;
+     118             :     }
+     119             : private:
+     120             :     string text;
+     121             :     Type type;
+     122             : };
+     123             : 
+     124           8 : string Parser::trim(const string& expression) {
+     125             :     // Remove leading and trailing spaces.
+     126             :     
+     127             :     int start, end;
+     128          12 :     for (start = 0; start < (int) expression.size() && isspace(expression[start]); start++)
+     129             :         ;
+     130           8 :     for (end = (int) expression.size()-1; end > start && isspace(expression[end]); end--)
+     131             :         ;
+     132           8 :     if (start == end && isspace(expression[end]))
+     133           0 :         return "";
+     134           8 :     return expression.substr(start, end-start+1);
+     135             : }
+     136             : 
+     137     2024272 : ParseToken Parser::getNextToken(const string& expression, int start) {
+     138     2024272 :     char c = expression[start];
+     139     2024272 :     if (c == '(')
+     140        1350 :         return ParseToken("(", ParseToken::LeftParen);
+     141     2023597 :     if (c == ')')
+     142        4736 :         return ParseToken(")", ParseToken::RightParen);
+     143     2021229 :     if (c == ',')
+     144         160 :         return ParseToken(",", ParseToken::Comma);
+     145     2021149 :     if (Operators.find(c) != string::npos)
+     146        5089 :         return ParseToken(string(1, c), ParseToken::Operator);
+     147     2016060 :     if (isspace(c)) {
+     148             :         // White space
+     149             : 
+     150          28 :         for (int pos = start+1; pos < (int) expression.size(); pos++) {
+     151          21 :             if (!isspace(expression[pos]))
+     152          42 :                 return ParseToken(expression.substr(start, pos-start), ParseToken::Whitespace);
+     153             :         }
+     154          14 :         return ParseToken(expression.substr(start, string::npos), ParseToken::Whitespace);
+     155             :     }
+     156     2016032 :     if (c == '.' || Digits.find(c) != string::npos) {
+     157             :         // A number
+     158             : 
+     159     2011015 :         bool foundDecimal = (c == '.');
+     160             :         bool foundExp = false;
+     161             :         int pos;
+     162    20090528 :         for (pos = start+1; pos < (int) expression.size(); pos++) {
+     163    18082169 :             c = expression[pos];
+     164    18082169 :             if (Digits.find(c) != string::npos)
+     165    16069233 :                 continue;
+     166     2012936 :             if (c == '.' && !foundDecimal) {
+     167             :                 foundDecimal = true;
+     168     2010276 :                 continue;
+     169             :             }
+     170        2660 :             if ((c == 'e' || c == 'E') && !foundExp) {
+     171             :                 foundExp = true;
+     172           4 :                 if (pos < (int) expression.size()-1 && (expression[pos+1] == '-' || expression[pos+1] == '+'))
+     173             :                     pos++;
+     174           4 :                 continue;
+     175             :             }
+     176             :             break;
+     177             :         }
+     178     4022030 :         return ParseToken(expression.substr(start, pos-start), ParseToken::Number);
+     179             :     }
+     180             : 
+     181             :     // A variable, function, or left parenthesis
+     182             : 
+     183       14882 :     for (int pos = start; pos < (int) expression.size(); pos++) {
+     184       14659 :         c = expression[pos];
+     185       14659 :         if (c == '(')
+     186        3386 :             return ParseToken(expression.substr(start, pos-start+1), ParseToken::Function);
+     187       12966 :         if (Operators.find(c) != string::npos || c == ',' || c == ')' || isspace(c))
+     188        6202 :             return ParseToken(expression.substr(start, pos-start), ParseToken::Variable);
+     189             :     }
+     190         446 :     return ParseToken(expression.substr(start, string::npos), ParseToken::Variable);
+     191             : }
+     192             : 
+     193     2009212 : vector<ParseToken> Parser::tokenize(const string& expression) {
+     194             :     vector<ParseToken> tokens;
+     195             :     int pos = 0;
+     196     4033484 :     while (pos < (int) expression.size()) {
+     197     2024272 :         ParseToken token = getNextToken(expression, pos);
+     198     2024272 :         if (token.getType() != ParseToken::Whitespace)
+     199     2024244 :             tokens.push_back(token);
+     200     2024272 :         pos += (int) token.getText().size();
+     201             :     }
+     202     2009212 :     return tokens;
+     203           0 : }
+     204             : 
+     205     2009208 : ParsedExpression Parser::parse(const string& expression) {
+     206     4018397 :     return parse(expression, map<string, CustomFunction*>());
+     207             : }
+     208             : 
+     209     2009208 : ParsedExpression Parser::parse(const string& expression, const map<string, CustomFunction*>& customFunctions) {
+     210             :     try {
+     211             :         // First split the expression into subexpressions.
+     212             : 
+     213     2009208 :         string primaryExpression = expression;
+     214             :         vector<string> subexpressions;
+     215             :         while (true) {
+     216             :             string::size_type pos = primaryExpression.find_last_of(';');
+     217     2009212 :             if (pos == string::npos)
+     218             :                 break;
+     219           8 :             string sub = trim(primaryExpression.substr(pos+1));
+     220           4 :             if (sub.size() > 0)
+     221           4 :                 subexpressions.push_back(sub);
+     222           8 :             primaryExpression = primaryExpression.substr(0, pos);
+     223           4 :         }
+     224             : 
+     225             :         // Parse the subexpressions.
+     226             : 
+     227             :         map<string, ExpressionTreeNode> subexpDefs;
+     228     2009212 :         for (int i = 0; i < (int) subexpressions.size(); i++) {
+     229           4 :             string::size_type equalsPos = subexpressions[i].find('=');
+     230           4 :             if (equalsPos == string::npos)
+     231           0 :                 throw Exception("subexpression does not specify a name");
+     232          27 :             string name = trim(subexpressions[i].substr(0, equalsPos));
+     233           4 :             if (name.size() == 0)
+     234           0 :                 throw Exception("subexpression does not specify a name");
+     235           4 :             vector<ParseToken> tokens = tokenize(subexpressions[i].substr(equalsPos+1));
+     236           4 :             int pos = 0;
+     237           4 :             subexpDefs[name] = parsePrecedence(tokens, pos, customFunctions, subexpDefs, 0);
+     238           4 :             if (pos != tokens.size())
+     239           0 :                 throw Exception("unexpected text at end of subexpression: "+tokens[pos].getText());
+     240           4 :         }
+     241             : 
+     242             :         // Now parse the primary expression.
+     243             : 
+     244     2009208 :         vector<ParseToken> tokens = tokenize(primaryExpression);
+     245     2009208 :         int pos = 0;
+     246     2009208 :         ExpressionTreeNode result = parsePrecedence(tokens, pos, customFunctions, subexpDefs, 0);
+     247     2009204 :         if (pos != tokens.size())
+     248          30 :             throw Exception("unexpected text at end of expression: "+tokens[pos].getText());
+     249     4018378 :         return ParsedExpression(result);
+     250     4018431 :     }
+     251          19 :     catch (Exception& ex) {
+     252          38 :         throw Exception("Parse error in expression \""+expression+"\": "+ex.what());
+     253          19 :     }
+     254             : }
+     255             : 
+     256     2016749 : ExpressionTreeNode Parser::parsePrecedence(const vector<ParseToken>& tokens, int& pos, const map<string, CustomFunction*>& customFunctions,
+     257             :             const map<string, ExpressionTreeNode>& subexpressionDefs, int precedence) {
+     258     2016749 :     if (pos == tokens.size())
+     259           8 :         throw Exception("unexpected end of expression");
+     260             : 
+     261             :     // Parse the next value (number, variable, function, parenthesized expression)
+     262             : 
+     263             :     ParseToken token = tokens[pos];
+     264     2016745 :     ExpressionTreeNode result;
+     265     2016745 :     if (token.getType() == ParseToken::Number) {
+     266             :         double value;
+     267     4022030 :         stringstream(token.getText()) >> value;
+     268     2011015 :         result = ExpressionTreeNode(new Operation::Constant(value));
+     269     2011015 :         pos++;
+     270             :     }
+     271        5730 :     else if (token.getType() == ParseToken::Variable) {
+     272             :         map<string, ExpressionTreeNode>::const_iterator subexp = subexpressionDefs.find(token.getText());
+     273        3309 :         if (subexp == subexpressionDefs.end()) {
+     274        3305 :             Operation* op = new Operation::Variable(token.getText());
+     275        3305 :             result = ExpressionTreeNode(op);
+     276             :         }
+     277             :         else
+     278           4 :             result = subexp->second;
+     279        3309 :         pos++;
+     280             :     }
+     281        2421 :     else if (token.getType() == ParseToken::LeftParen) {
+     282         675 :         pos++;
+     283         675 :         result = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 0);
+     284         675 :         if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen)
+     285           0 :             throw Exception("unbalanced parentheses");
+     286         675 :         pos++;
+     287             :     }
+     288        1746 :     else if (token.getType() == ParseToken::Function) {
+     289        1693 :         pos++;
+     290             :         vector<ExpressionTreeNode> args;
+     291             :         bool moreArgs;
+     292        1773 :         do {
+     293        3546 :             args.push_back(parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 0));
+     294        1773 :             moreArgs = (pos < (int) tokens.size() && tokens[pos].getType() == ParseToken::Comma);
+     295             :             if (moreArgs)
+     296          80 :                 pos++;
+     297             :         } while (moreArgs);
+     298        1693 :         if (pos == tokens.size() || tokens[pos].getType() != ParseToken::RightParen)
+     299           0 :             throw Exception("unbalanced parentheses");
+     300        1693 :         pos++;
+     301        1693 :         Operation* op = getFunctionOperation(token.getText(), customFunctions);
+     302             :         try {
+     303        1693 :             result = ExpressionTreeNode(op, args);
+     304             :         }
+     305           0 :         catch (...) {
+     306           0 :             delete op;
+     307           0 :             throw;
+     308           0 :         }
+     309        1693 :     }
+     310         106 :     else if (token.getType() == ParseToken::Operator && token.getText() == "-") {
+     311          53 :         pos++;
+     312          53 :         ExpressionTreeNode toNegate = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, 2);
+     313          53 :         result = ExpressionTreeNode(new Operation::Negate(), toNegate);
+     314          53 :     }
+     315             :     else
+     316           0 :         throw Exception("unexpected token: "+token.getText());
+     317             : 
+     318             :     // Now deal with the next binary operator.
+     319             : 
+     320     2021781 :     while (pos < (int) tokens.size() && tokens[pos].getType() == ParseToken::Operator) {
+     321             :         token = tokens[pos];
+     322        7336 :         int opIndex = (int) Operators.find(token.getText());
+     323        7336 :         int opPrecedence = Precedence[opIndex];
+     324        7336 :         if (opPrecedence < precedence)
+     325        2300 :             return result;
+     326        5036 :         pos++;
+     327        5036 :         ExpressionTreeNode arg = parsePrecedence(tokens, pos, customFunctions, subexpressionDefs, LeftAssociative[opIndex] ? opPrecedence+1 : opPrecedence);
+     328        5036 :         Operation* op = getOperatorOperation(token.getText());
+     329             :         try {
+     330        5036 :             result = ExpressionTreeNode(op, result, arg);
+     331             :         }
+     332           0 :         catch (...) {
+     333           0 :             delete op;
+     334           0 :             throw;
+     335           0 :         }
+     336        5036 :     }
+     337             :     return result;
+     338           0 : }
+     339             : 
+     340        5036 : Operation* Parser::getOperatorOperation(const std::string& name) {
+     341        5036 :     switch (OperationId[Operators.find(name)]) {
+     342        1081 :         case Operation::ADD:
+     343        1081 :             return new Operation::Add();
+     344         882 :         case Operation::SUBTRACT:
+     345         882 :             return new Operation::Subtract();
+     346        2395 :         case Operation::MULTIPLY:
+     347        2395 :             return new Operation::Multiply();
+     348         460 :         case Operation::DIVIDE:
+     349         460 :             return new Operation::Divide();
+     350         218 :         case Operation::POWER:
+     351         218 :             return new Operation::Power();
+     352           0 :         default:
+     353           0 :             throw Exception("unknown operator");
+     354             :     }
+     355             : }
+     356             : 
+     357        1693 : Operation* Parser::getFunctionOperation(const std::string& name, const map<string, CustomFunction*>& customFunctions) {
+     358             : 
+     359          40 :     const static map<string, Operation::Id> opMap = []() {
+     360             :         map<string, Operation::Id> opMap;
+     361          40 :         opMap["sqrt"] = Operation::SQRT;
+     362          40 :         opMap["exp"] = Operation::EXP;
+     363          40 :         opMap["log"] = Operation::LOG;
+     364          40 :         opMap["sin"] = Operation::SIN;
+     365          40 :         opMap["cos"] = Operation::COS;
+     366          40 :         opMap["sec"] = Operation::SEC;
+     367          40 :         opMap["csc"] = Operation::CSC;
+     368          40 :         opMap["tan"] = Operation::TAN;
+     369          40 :         opMap["cot"] = Operation::COT;
+     370          40 :         opMap["asin"] = Operation::ASIN;
+     371          40 :         opMap["acos"] = Operation::ACOS;
+     372          40 :         opMap["atan"] = Operation::ATAN;
+     373          40 :         opMap["atan2"] = Operation::ATAN2;
+     374          40 :         opMap["sinh"] = Operation::SINH;
+     375          40 :         opMap["cosh"] = Operation::COSH;
+     376          40 :         opMap["tanh"] = Operation::TANH;
+     377          40 :         opMap["erf"] = Operation::ERF;
+     378          40 :         opMap["erfc"] = Operation::ERFC;
+     379          40 :         opMap["step"] = Operation::STEP;
+     380          40 :         opMap["delta"] = Operation::DELTA;
+     381          40 :         opMap["nandelta"] = Operation::NANDELTA;
+     382          40 :         opMap["square"] = Operation::SQUARE;
+     383          40 :         opMap["cube"] = Operation::CUBE;
+     384          40 :         opMap["recip"] = Operation::RECIPROCAL;
+     385          40 :         opMap["min"] = Operation::MIN;
+     386          40 :         opMap["max"] = Operation::MAX;
+     387          40 :         opMap["abs"] = Operation::ABS;
+     388          40 :         opMap["floor"] = Operation::FLOOR;
+     389          40 :         opMap["ceil"] = Operation::CEIL;
+     390          40 :         opMap["select"] = Operation::SELECT;
+     391          40 :         opMap["acot"] = Operation::ACOT;
+     392          40 :         opMap["asec"] = Operation::ASEC;
+     393          40 :         opMap["acsc"] = Operation::ACSC;
+     394          40 :         opMap["coth"] = Operation::COTH;
+     395          40 :         opMap["sech"] = Operation::SECH;
+     396          40 :         opMap["csch"] = Operation::CSCH;
+     397          40 :         opMap["asinh"] = Operation::ASINH;
+     398          40 :         opMap["acosh"] = Operation::ACOSH;
+     399          40 :         opMap["atanh"] = Operation::ATANH;
+     400          40 :         opMap["acoth"] = Operation::ACOTH;
+     401          40 :         opMap["asech"] = Operation::ASECH;
+     402          40 :         opMap["acsch"] = Operation::ACSCH;
+     403          40 :         opMap["atan2"] = Operation::ATAN2;
+     404          40 :         return opMap;
+     405        1693 :     }();
+     406        1693 :     string trimmed = name.substr(0, name.size()-1);
+     407             : 
+     408             :     // First check custom functions.
+     409             : 
+     410             :     map<string, CustomFunction*>::const_iterator custom = customFunctions.find(trimmed);
+     411        1693 :     if (custom != customFunctions.end())
+     412           0 :         return new Operation::Custom(trimmed, custom->second->clone());
+     413             : 
+     414             :     // Now try standard functions.
+     415             : 
+     416             :     map<string, Operation::Id>::const_iterator iter = opMap.find(trimmed);
+     417        1693 :     if (iter == opMap.end())
+     418           0 :         throw Exception("unknown function: "+trimmed);
+     419        1693 :     switch (iter->second) {
+     420          58 :         case Operation::SQRT:
+     421          58 :             return new Operation::Sqrt();
+     422          27 :         case Operation::EXP:
+     423          27 :             return new Operation::Exp();
+     424           5 :         case Operation::LOG:
+     425           5 :             return new Operation::Log();
+     426         117 :         case Operation::SIN:
+     427         117 :             return new Operation::Sin();
+     428        1265 :         case Operation::COS:
+     429        1265 :             return new Operation::Cos();
+     430           4 :         case Operation::SEC:
+     431           4 :             return new Operation::Sec();
+     432           4 :         case Operation::CSC:
+     433           4 :             return new Operation::Csc();
+     434           4 :         case Operation::TAN:
+     435           4 :             return new Operation::Tan();
+     436           4 :         case Operation::COT:
+     437           4 :             return new Operation::Cot();
+     438           4 :         case Operation::ASIN:
+     439           4 :             return new Operation::Asin();
+     440           4 :         case Operation::ACOS:
+     441           4 :             return new Operation::Acos();
+     442           4 :         case Operation::ATAN:
+     443           4 :             return new Operation::Atan();
+     444          16 :         case Operation::ATAN2:
+     445          16 :             return new Operation::Atan2();
+     446           4 :         case Operation::SINH:
+     447           4 :             return new Operation::Sinh();
+     448           4 :         case Operation::COSH:
+     449           4 :             return new Operation::Cosh();
+     450           4 :         case Operation::TANH:
+     451           4 :             return new Operation::Tanh();
+     452           4 :         case Operation::ERF:
+     453           4 :             return new Operation::Erf();
+     454           4 :         case Operation::ERFC:
+     455           4 :             return new Operation::Erfc();
+     456          28 :         case Operation::STEP:
+     457          28 :             return new Operation::Step();
+     458           4 :         case Operation::DELTA:
+     459           4 :             return new Operation::Delta();
+     460           4 :         case Operation::NANDELTA:
+     461           4 :             return new Operation::Nandelta();
+     462           4 :         case Operation::SQUARE:
+     463           4 :             return new Operation::Square();
+     464           4 :         case Operation::CUBE:
+     465           4 :             return new Operation::Cube();
+     466           4 :         case Operation::RECIPROCAL:
+     467           4 :             return new Operation::Reciprocal();
+     468           8 :         case Operation::MIN:
+     469           8 :             return new Operation::Min();
+     470           8 :         case Operation::MAX:
+     471           8 :             return new Operation::Max();
+     472          13 :         case Operation::ABS:
+     473          13 :             return new Operation::Abs();
+     474           4 :         case Operation::FLOOR:
+     475           4 :             return new Operation::Floor();
+     476           4 :         case Operation::CEIL:
+     477           4 :             return new Operation::Ceil();
+     478          24 :         case Operation::SELECT:
+     479          24 :             return new Operation::Select();
+     480           4 :         case Operation::ACOT:
+     481           4 :             return new Operation::Acot();
+     482           4 :         case Operation::ASEC:
+     483           4 :             return new Operation::Asec();
+     484           4 :         case Operation::ACSC:
+     485           4 :             return new Operation::Acsc();
+     486           4 :         case Operation::COTH:
+     487           4 :             return new Operation::Coth();
+     488           4 :         case Operation::SECH:
+     489           4 :             return new Operation::Sech();
+     490           4 :         case Operation::CSCH:
+     491           4 :             return new Operation::Csch();
+     492           4 :         case Operation::ASINH:
+     493           4 :             return new Operation::Asinh();
+     494           4 :         case Operation::ACOSH:
+     495           4 :             return new Operation::Acosh();
+     496           4 :         case Operation::ATANH:
+     497           4 :             return new Operation::Atanh();
+     498           4 :         case Operation::ACOTH:
+     499           4 :             return new Operation::Acoth();
+     500           4 :         case Operation::ASECH:
+     501           4 :             return new Operation::Asech();
+     502           4 :         case Operation::ACSCH:
+     503           4 :             return new Operation::Acsch();
+     504           0 :         default:
+     505           0 :             throw Exception("unknown function");
+     506             :     }
+     507             : }
+     508             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/index-sort-f.html b/coverage-libs/lepton/index-sort-f.html new file mode 100644 index 000000000000..c31af9bc39ff --- /dev/null +++ b/coverage-libs/lepton/index-sort-f.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - leptonHitTotalCoverage
Test:plumed test coverage (other modules)Lines:1593178989.0 %
Date:2024-02-22 21:58:47Functions:39542892.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ExpressionProgram.cpp +
0.0%
+
0.0 %0 / 520.0 %0 / 12
Exception.h +
100.0%
+
100.0 %6 / 675.0 %3 / 4
ParsedExpression.cpp +
86.0%86.0%
+
86.0 %221 / 25776.2 %16 / 21
Operation.cpp +
84.8%84.8%
+
84.8 %267 / 31593.0 %53 / 57
CompiledExpression.cpp +
97.0%97.0%
+
97.0 %224 / 23194.7 %18 / 19
Operation.h +
95.3%95.3%
+
95.3 %530 / 55696.6 %280 / 290
ParsedExpression.h +
100.0%
+
100.0 %1 / 1-0 / 0
CompiledExpression.h +
100.0%
+
100.0 %1 / 1-0 / 0
Parser.cpp +
92.3%92.3%
+
92.3 %275 / 298100.0 %10 / 10
ExpressionTreeNode.cpp +
94.4%94.4%
+
94.4 %68 / 72100.0 %15 / 15
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/index-sort-l.html b/coverage-libs/lepton/index-sort-l.html new file mode 100644 index 000000000000..00646d663614 --- /dev/null +++ b/coverage-libs/lepton/index-sort-l.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - leptonHitTotalCoverage
Test:plumed test coverage (other modules)Lines:1593178989.0 %
Date:2024-02-22 21:58:47Functions:39542892.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ExpressionProgram.cpp +
0.0%
+
0.0 %0 / 520.0 %0 / 12
Operation.cpp +
84.8%84.8%
+
84.8 %267 / 31593.0 %53 / 57
ParsedExpression.cpp +
86.0%86.0%
+
86.0 %221 / 25776.2 %16 / 21
Parser.cpp +
92.3%92.3%
+
92.3 %275 / 298100.0 %10 / 10
ExpressionTreeNode.cpp +
94.4%94.4%
+
94.4 %68 / 72100.0 %15 / 15
Operation.h +
95.3%95.3%
+
95.3 %530 / 55696.6 %280 / 290
CompiledExpression.cpp +
97.0%97.0%
+
97.0 %224 / 23194.7 %18 / 19
ParsedExpression.h +
100.0%
+
100.0 %1 / 1-0 / 0
CompiledExpression.h +
100.0%
+
100.0 %1 / 1-0 / 0
Exception.h +
100.0%
+
100.0 %6 / 675.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/lepton/index.html b/coverage-libs/lepton/index.html new file mode 100644 index 000000000000..73388a1ccf0e --- /dev/null +++ b/coverage-libs/lepton/index.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - lepton + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - leptonHitTotalCoverage
Test:plumed test coverage (other modules)Lines:1593178989.0 %
Date:2024-02-22 21:58:47Functions:39542892.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
CompiledExpression.cpp +
97.0%97.0%
+
97.0 %224 / 23194.7 %18 / 19
CompiledExpression.h +
100.0%
+
100.0 %1 / 1-0 / 0
Exception.h +
100.0%
+
100.0 %6 / 675.0 %3 / 4
ExpressionProgram.cpp +
0.0%
+
0.0 %0 / 520.0 %0 / 12
ExpressionTreeNode.cpp +
94.4%94.4%
+
94.4 %68 / 72100.0 %15 / 15
Operation.cpp +
84.8%84.8%
+
84.8 %267 / 31593.0 %53 / 57
Operation.h +
95.3%95.3%
+
95.3 %530 / 55696.6 %280 / 290
ParsedExpression.cpp +
86.0%86.0%
+
86.0 %221 / 25776.2 %16 / 21
ParsedExpression.h +
100.0%
+
100.0 %1 / 1-0 / 0
Parser.cpp +
92.3%92.3%
+
92.3 %275 / 298100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/Gromacs.h.func-sort-c.html b/coverage-libs/molfile/Gromacs.h.func-sort-c.html new file mode 100644 index 000000000000..199553ed4061 --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/Gromacs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - Gromacs.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:34275045.6 %
Date:2024-02-22 21:58:47Functions:223661.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL10g96_headerEPNS0_7md_fileEPciPf0
_ZN4PLMD7molfileL10gro_headerEPNS0_7md_fileEPciPfPii0
_ZN4PLMD7molfileL11mdio_errmsgEi0
_ZN4PLMD7molfileL11put_trx_intEPNS0_7md_fileEi0
_ZN4PLMD7molfileL11strip_whiteEPc0
_ZN4PLMD7molfileL12g96_timestepEPNS0_7md_fileEPNS0_5md_tsE0
_ZN4PLMD7molfileL12gro_timestepEPNS0_7md_fileEPNS0_5md_tsE0
_ZN4PLMD7molfileL12put_trx_realEPNS0_7md_fileEf0
_ZN4PLMD7molfileL13mdio_readlineEPNS0_7md_fileEPcii0
_ZN4PLMD7molfileL13xtc_sizeofintEi0
_ZN4PLMD7molfileL14g96_countatomsEPNS0_7md_fileE0
_ZN4PLMD7molfileL14put_trx_stringEPNS0_7md_fileEPKc0
_ZN4PLMD7molfileL7g96_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL7gro_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL10trx_stringEPNS0_7md_fileEPci155
_ZN4PLMD7molfileL12trx_timestepEPNS0_7md_fileEPNS0_5md_tsE155
_ZN4PLMD7molfileL10trx_headerEPNS0_7md_fileEi160
_ZN4PLMD7molfileL10mdio_closeEPNS0_7md_fileE195
_ZN4PLMD7molfileL10mdio_errnoEv195
_ZN4PLMD7molfileL11mdio_headerEPNS0_7md_fileEPNS0_9md_headerE195
_ZN4PLMD7molfileL9mdio_openEPKcii195
_ZN4PLMD7molfileL7trx_intEPNS0_7md_fileEPi2485
_ZN4PLMD7molfileL14xtc_sizeofintsEiPj10026
_ZN4PLMD7molfileL8xtc_dataEPNS0_7md_fileEPci10026
_ZN4PLMD7molfileL12xtc_3dfcoordEPNS0_7md_fileEPfPiS3_18107
_ZN4PLMD7molfileL11mdio_tsfreeEPNS0_5md_tsEi18257
_ZN4PLMD7molfileL12mdio_readboxEPNS0_6md_boxEPfS3_S3_18257
_ZN4PLMD7molfileL12xtc_timestepEPNS0_7md_fileEPNS0_5md_tsE18297
_ZN4PLMD7molfileL13mdio_timestepEPNS0_7md_fileEPNS0_5md_tsE18452
_ZN4PLMD7molfileL7xtc_intEPNS0_7md_fileEPi153206
_ZN4PLMD7molfileL9xtc_floatEPNS0_7md_fileEPf215339
_ZN4PLMD7molfileL11trx_rvectorEPNS0_7md_fileEPf486150
_ZN4PLMD7molfileL8trx_realEPNS0_7md_fileEPf1458760
_ZN4PLMD7molfileL15xtc_receiveintsEPiiiPjS1_1951818
_ZN4PLMD7molfileL13mdio_seterrorEi2371101
_ZN4PLMD7molfileL15xtc_receivebitsEPii9197946
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/Gromacs.h.func.html b/coverage-libs/molfile/Gromacs.h.func.html new file mode 100644 index 000000000000..94136a909990 --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.func.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/Gromacs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - Gromacs.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:34275045.6 %
Date:2024-02-22 21:58:47Functions:223661.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL10g96_headerEPNS0_7md_fileEPciPf0
_ZN4PLMD7molfileL10gro_headerEPNS0_7md_fileEPciPfPii0
_ZN4PLMD7molfileL10mdio_closeEPNS0_7md_fileE195
_ZN4PLMD7molfileL10mdio_errnoEv195
_ZN4PLMD7molfileL10trx_headerEPNS0_7md_fileEi160
_ZN4PLMD7molfileL10trx_stringEPNS0_7md_fileEPci155
_ZN4PLMD7molfileL11mdio_errmsgEi0
_ZN4PLMD7molfileL11mdio_headerEPNS0_7md_fileEPNS0_9md_headerE195
_ZN4PLMD7molfileL11mdio_tsfreeEPNS0_5md_tsEi18257
_ZN4PLMD7molfileL11put_trx_intEPNS0_7md_fileEi0
_ZN4PLMD7molfileL11strip_whiteEPc0
_ZN4PLMD7molfileL11trx_rvectorEPNS0_7md_fileEPf486150
_ZN4PLMD7molfileL12g96_timestepEPNS0_7md_fileEPNS0_5md_tsE0
_ZN4PLMD7molfileL12gro_timestepEPNS0_7md_fileEPNS0_5md_tsE0
_ZN4PLMD7molfileL12mdio_readboxEPNS0_6md_boxEPfS3_S3_18257
_ZN4PLMD7molfileL12put_trx_realEPNS0_7md_fileEf0
_ZN4PLMD7molfileL12trx_timestepEPNS0_7md_fileEPNS0_5md_tsE155
_ZN4PLMD7molfileL12xtc_3dfcoordEPNS0_7md_fileEPfPiS3_18107
_ZN4PLMD7molfileL12xtc_timestepEPNS0_7md_fileEPNS0_5md_tsE18297
_ZN4PLMD7molfileL13mdio_readlineEPNS0_7md_fileEPcii0
_ZN4PLMD7molfileL13mdio_seterrorEi2371101
_ZN4PLMD7molfileL13mdio_timestepEPNS0_7md_fileEPNS0_5md_tsE18452
_ZN4PLMD7molfileL13xtc_sizeofintEi0
_ZN4PLMD7molfileL14g96_countatomsEPNS0_7md_fileE0
_ZN4PLMD7molfileL14put_trx_stringEPNS0_7md_fileEPKc0
_ZN4PLMD7molfileL14xtc_sizeofintsEiPj10026
_ZN4PLMD7molfileL15xtc_receivebitsEPii9197946
_ZN4PLMD7molfileL15xtc_receiveintsEPiiiPjS1_1951818
_ZN4PLMD7molfileL7g96_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL7gro_recEPNS0_7md_fileEPNS0_7md_atomE0
_ZN4PLMD7molfileL7trx_intEPNS0_7md_fileEPi2485
_ZN4PLMD7molfileL7xtc_intEPNS0_7md_fileEPi153206
_ZN4PLMD7molfileL8trx_realEPNS0_7md_fileEPf1458760
_ZN4PLMD7molfileL8xtc_dataEPNS0_7md_fileEPci10026
_ZN4PLMD7molfileL9mdio_openEPKcii195
_ZN4PLMD7molfileL9xtc_floatEPNS0_7md_fileEPf215339
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/Gromacs.h.gcov.html b/coverage-libs/molfile/Gromacs.h.gcov.html new file mode 100644 index 000000000000..e863df0e632f --- /dev/null +++ b/coverage-libs/molfile/Gromacs.h.gcov.html @@ -0,0 +1,2090 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/Gromacs.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - Gromacs.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:34275045.6 %
Date:2024-02-22 21:58:47Functions:223661.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : University of Illinois Open Source License
+       3             : Copyright 2003 Theoretical and Computational Biophysics Group, 
+       4             : All rights reserved.
+       5             : 
+       6             : Developed by:           Theoretical and Computational Biophysics Group
+       7             :                         University of Illinois at Urbana-Champaign
+       8             :                         http://www.ks.uiuc.edu/
+       9             : 
+      10             : Permission is hereby granted, free of charge, to any person obtaining a copy of
+      11             : this software and associated documentation files (the Software), to deal with 
+      12             : the Software without restriction, including without limitation the rights to 
+      13             : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+      14             : of the Software, and to permit persons to whom the Software is furnished to 
+      15             : do so, subject to the following conditions:
+      16             : 
+      17             : Redistributions of source code must retain the above copyright notice, 
+      18             : this list of conditions and the following disclaimers.
+      19             : 
+      20             : Redistributions in binary form must reproduce the above copyright notice, 
+      21             : this list of conditions and the following disclaimers in the documentation 
+      22             : and/or other materials provided with the distribution.
+      23             : 
+      24             : Neither the names of Theoretical and Computational Biophysics Group, 
+      25             : University of Illinois at Urbana-Champaign, nor the names of its contributors 
+      26             : may be used to endorse or promote products derived from this Software without 
+      27             : specific prior written permission.
+      28             : 
+      29             : THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+      30             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+      31             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
+      32             : THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
+      33             : OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+      34             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
+      35             : OTHER DEALINGS WITH THE SOFTWARE.
+      36             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      37             : #ifndef __PLUMED_molfile_Gromacs_h
+      38             : #define __PLUMED_molfile_Gromacs_h
+      39             : /***************************************************************************
+      40             :  *cr
+      41             :  *cr            (C) Copyright 1995-2016 The Board of Trustees of the
+      42             :  *cr                        University of Illinois
+      43             :  *cr                         All Rights Reserved
+      44             :  *cr
+      45             :  ***************************************************************************/
+      46             : /***************************************************************************
+      47             :  * RCS INFORMATION:
+      48             :  *      $RCSfile: Gromacs.h,v $
+      49             :  *      $Author: johns $       $Locker:  $             $State: Exp $
+      50             :  *      $Revision: 1.36 $       $Date: 2020/01/09 16:21:28 $
+      51             :  ***************************************************************************/
+      52             : 
+      53             : /*
+      54             :  * GROMACS file format reader for VMD
+      55             :  *
+      56             :  * This code provides a high level I/O library for reading
+      57             :  * and writing the following file formats:
+      58             :  *      gro     GROMACS format or trajectory
+      59             :  *      g96     GROMOS-96 format or trajectory
+      60             :  *      trj     Trajectory - x, v and f (binary, full precision)
+      61             :  *      trr     Trajectory - x, v and f (binary, full precision, portable)
+      62             :  *      xtc     Trajectory - x only (compressed, portable, any precision)
+      63             :  *      top
+      64             :  * Currently supported: gro trj trr g96 [xtc]
+      65             :  *
+      66             :  * TODO list
+      67             :  *   o  velocities are ignored because VMD doesn't use them, but some other 
+      68             :  *      program might ...
+      69             :  *   o  gro_rec() assumes positions in .gro files are nanometers and
+      70             :  *      converts to angstroms, whereas they really could be any unit
+      71             :  */
+      72             : 
+      73             : #ifndef GROMACS_H
+      74             : #define GROMACS_H
+      75             : 
+      76             : #include <math.h>
+      77             : #include <stdio.h>
+      78             : #include <stdlib.h>
+      79             : #include <string.h>
+      80             : #include <ctype.h>
+      81             : 
+      82             : #if defined(_AIX)
+      83             : #include <strings.h>
+      84             : #endif
+      85             : 
+      86             : #include "endianswap.h"
+      87             : 
+      88             : namespace PLMD{
+      89             : namespace molfile{
+      90             : 
+      91             : #if defined(WIN32) || defined(WIN64)
+      92             : #define strcasecmp stricmp
+      93             : #endif
+      94             : 
+      95             : #ifndef M_PI_2
+      96             : #define M_PI_2 1.57079632679489661922
+      97             : #endif
+      98             : 
+      99             : // Error codes for mdio_errno
+     100             : #define MDIO_SUCCESS            0
+     101             : #define MDIO_BADFORMAT          1
+     102             : #define MDIO_EOF                2
+     103             : #define MDIO_BADPARAMS          3
+     104             : #define MDIO_IOERROR            4
+     105             : #define MDIO_BADPRECISION       5
+     106             : #define MDIO_BADMALLOC          6
+     107             : #define MDIO_CANTOPEN           7
+     108             : #define MDIO_BADEXTENSION       8
+     109             : #define MDIO_UNKNOWNFMT         9
+     110             : #define MDIO_CANTCLOSE          10
+     111             : #define MDIO_WRONGFORMAT        11
+     112             : #define MDIO_SIZEERROR          12
+     113             : #define MDIO_UNKNOWNERROR       1000
+     114             : 
+     115             : #define MDIO_READ       0
+     116             : #define MDIO_WRITE      1
+     117             : 
+     118             : #define MDIO_MAX_ERRVAL         11
+     119             : 
+     120             : // Format extensions
+     121             : const char *mdio_fmtexts[] = {
+     122             :     "",
+     123             :     ".gro",
+     124             :     ".trr",
+     125             :     ".g96",
+     126             :     ".trj",
+     127             :     ".xtc",
+     128             :     NULL
+     129             : };
+     130             : 
+     131             : 
+     132             : static int mdio_errcode;        // Last error code
+     133             : 
+     134             : #define TRX_MAGIC       1993    // Magic number for .trX files
+     135             : #define XTC_MAGIC       1995    // Magic number for .xtc files
+     136             : #define MAX_GRO_LINE    500     // Maximum line length of .gro files
+     137             : #define MAX_G96_LINE    500     // Maximum line length of .g96 files
+     138             : #define MAX_TRX_TITLE   80      // Maximum length of a title in .trX
+     139             : #define MAX_MDIO_TITLE  80      // Maximum supported title length
+     140             : #define ANGS_PER_NM     10      // Unit conversion factor
+     141             : #define ANGS2_PER_NM2   100     // Unit conversion factor
+     142             : 
+     143             : 
+     144             : // All the supported file types and their respective extensions
+     145             : #define MDFMT_GRO               1
+     146             : #define MDFMT_TRR               2
+     147             : #define MDFMT_G96               3
+     148             : #define MDFMT_TRJ               4
+     149             : #define MDFMT_XTC               5
+     150             : 
+     151             : 
+     152             : // A structure to hold .trX file format header information. This
+     153             : // is an optional member of the md_file structure that is used
+     154             : // when .trX files are being dealt with.
+     155             : typedef struct {
+     156             :         int version;            // File version number
+     157             :         char title[MAX_TRX_TITLE + 1];  // File title
+     158             :         int ir_size;
+     159             :         int e_size;
+     160             :         int box_size;
+     161             :         int vir_size;
+     162             :         int pres_size;
+     163             :         int top_size;
+     164             :         int sym_size;
+     165             :         int x_size;             // Positions of atoms
+     166             :         int v_size;             // Velocities of atoms
+     167             :         int f_size;
+     168             :         int natoms;             // Number of atoms in the system
+     169             :         int step;
+     170             :         int nre;
+     171             :         float t;
+     172             :         float lambda;
+     173             : } trx_hdr;
+     174             : 
+     175             : 
+     176             : // A generic i/o structure that contains information about the
+     177             : // file itself and the input/output state
+     178             : typedef struct {
+     179             :         FILE *  f;      // Pointer to the file
+     180             :         int     fmt;    // The file format
+     181             :         int     prec;   // Real number precision
+     182             :         int     rev;    // Reverse endiannism?
+     183             :         trx_hdr * trx;  // Trx files require a great deal more
+     184             :                         // header data to be stored.
+     185             : } md_file;
+     186             : 
+     187             : 
+     188             : // A format-independent structure to hold header data from files
+     189             : typedef struct {
+     190             :         char title[MAX_MDIO_TITLE + 1];
+     191             :         int natoms;
+     192             :         float timeval;
+     193             : } md_header;
+     194             : 
+     195             : 
+     196             : // A format-independent structure to hold unit cell data
+     197             : typedef struct {
+     198             :   float A, B, C, alpha, beta, gamma;
+     199             : } md_box;
+     200             : 
+     201             : 
+     202             : // Timestep information
+     203             : typedef struct {
+     204             :         float *pos;     // Position array (3 * natoms)
+     205             :         //float *vel;   // Velocity array ** (VMD doesn't use this) **
+     206             :         //float *f;     // Force array ** (VMD doesn't use this) **
+     207             :         //float *box;   // Computational box ** (VMD doesn't use this) **
+     208             :         int natoms;     // Number of atoms
+     209             :         int step;       // Simulation step
+     210             :         float time;     // Time of simulation
+     211             :   md_box *box;
+     212             : } md_ts;
+     213             : 
+     214             : 
+     215             : // Atom information
+     216             : typedef struct {
+     217             :         char resid[7];          // Residue index number
+     218             :         char resname[7];        // Residue name
+     219             :         int atomnum;            // Atom index number
+     220             :         char atomname[7];       // Atom name
+     221             :         float pos[3];           // Position array (3 * natoms)
+     222             :         //float vel[3]; // Velocity array ** (VMD doesn't use this) **
+     223             : } md_atom;
+     224             : 
+     225             : 
+     226             : // Open a molecular dynamics file. The second parameter specifies
+     227             : // the format of the file. If it is zero, the format is determined
+     228             : // from the file extension. the third argument (if given) decides
+     229             : // whether to read (==0) or to write (!= 0).
+     230             : // using a default argument set to read for backward compatibility.
+     231             : static md_file *mdio_open(const char *, const int, const int=MDIO_READ);
+     232             : 
+     233             : // Closes a molecular dynamics file.
+     234             : static int mdio_close(md_file *);
+     235             : 
+     236             : 
+     237             : // Format-independent file I/O routines
+     238             : static int mdio_header(md_file *, md_header *);
+     239             : static int mdio_timestep(md_file *, md_ts *);
+     240             : 
+     241             : 
+     242             : // .gro file functions
+     243             : static int gro_header(md_file *, char *, int, float *, int *, int = 1);
+     244             : static int gro_rec(md_file *, md_atom *);
+     245             : static int gro_timestep(md_file *, md_ts *);
+     246             : 
+     247             : 
+     248             : // .trX file functions
+     249             : static int trx_header(md_file *, int = 0);
+     250             : static int trx_int(md_file *, int *);
+     251             : static int trx_real(md_file *, float *);
+     252             : 
+     253             : static int trx_rvector(md_file *, float *);
+     254             : static int trx_string(md_file *, char *, int);
+     255             : static int trx_timestep(md_file *, md_ts *);
+     256             : 
+     257             : // .g96 file functions
+     258             : static int g96_header(md_file *, char *, int, float *);
+     259             : static int g96_timestep(md_file *, md_ts *);
+     260             : static int g96_rec(md_file *, md_atom *);
+     261             : static int g96_countatoms(md_file *);
+     262             : 
+     263             : 
+     264             : // .xtc file functions
+     265             : static int xtc_int(md_file *, int *);
+     266             : static int xtc_float(md_file *, float *);
+     267             : /* 
+     268             : static int xtc_receivebits(int *, int);
+     269             : static void xtc_receiveints(int *, int, int, const unsigned *, int *);
+     270             : */
+     271             : static int xtc_timestep(md_file *, md_ts *);
+     272             : static int xtc_3dfcoord(md_file *, float *, int *, float *);
+     273             : 
+     274             : 
+     275             : // Error reporting functions
+     276             : static int mdio_errno(void);
+     277             : static const char *mdio_errmsg(int);
+     278             : static int mdio_seterror(int);
+     279             : 
+     280             : 
+     281             : // Miscellaneous functions
+     282             : static int strip_white(char *);
+     283             : static int mdio_readline(md_file *, char *, int, int = 1);
+     284             : static int mdio_tsfree(md_ts *, int = 0);
+     285             : static int mdio_readbox(md_box *, float *, float *, float *);
+     286             : 
+     287             : 
+     288             : 
+     289             : static int xtc_receivebits(int *, int);
+     290             : 
+     291             : // Error descriptions for mdio_errno
+     292             : static const char *mdio_errdescs[] = {
+     293             :         "no error",
+     294             :         "file does not match format",
+     295             :         "unexpected end-of-file reached",
+     296             :         "function called with bad parameters",
+     297             :         "file i/o error",
+     298             :         "unsupported precision",
+     299             :         "out of memory",
+     300             :         "cannot open file",
+     301             :         "bad file extension",
+     302             :         "unknown file format",
+     303             :         "cannot close file",
+     304             :         "wrong file format for this function",
+     305             :         "binary i/o error: sizeof(int) != 4",
+     306             :         NULL
+     307             : };
+     308             : 
+     309             : /*! \fn static inline bool host_is_little_endian(void)
+     310             :  * detect endiannes of host machine. returns true on little endian machines. */
+     311             : static inline int host_is_little_endian(void) 
+     312             : {
+     313             :   const union { unsigned char c[4]; unsigned int i; } 
+     314             :   fixed = { { 0x10 , 0x20 , 0x40 , 0x80 } };
+     315             :   const unsigned int i = 0x80402010U;
+     316             :         
+     317             :   if (fixed.i == i) {
+     318             :     return 1;
+     319             :   }
+     320             :   return 0;
+     321             : }
+     322             : 
+     323             : 
+     324             : 
+     325             : // Open a molecular dynamics file. The second parameter specifies
+     326             : // the format of the file. If it is zero, the format is determined
+     327             : // from the file extension.
+     328         195 : md_file *mdio_open(const char *fn, const int fmt, const int rw) {
+     329             :         md_file *mf;
+     330             : 
+     331         195 :         if (!fn) {
+     332           0 :                 mdio_seterror(MDIO_BADPARAMS);
+     333           0 :                 return NULL;
+     334             :         }
+     335             : 
+     336             :         // Allocate memory
+     337         195 :         mf = (md_file *) malloc(sizeof(md_file));
+     338         195 :         if (!mf) {
+     339           0 :                 mdio_seterror(MDIO_BADMALLOC);
+     340           0 :                 return NULL;
+     341             :         }
+     342             : 
+     343             :         // Zero out the structure
+     344             :         memset(mf, 0, sizeof(md_file));
+     345             : 
+     346             :         // Determine the file type from the extension
+     347         195 :         if (!fmt) {
+     348             :                 char *p;
+     349             :                 int n;
+     350             : 
+     351             :                 // Seek to the extension part of the filename
+     352           0 :                 for (p = (char *) &fn[strlen(fn) - 1]; *p != '.' && p > fn; p--);
+     353           0 :                 if (p == fn) {
+     354           0 :                         free(mf);
+     355           0 :                         mdio_seterror(MDIO_BADEXTENSION);
+     356           0 :                         return NULL;
+     357             :                 }
+     358             : 
+     359             :                 // Check the extension against known extensions
+     360           0 :                 for (n = 1; mdio_fmtexts[n]; n++)
+     361           0 :                         if (!strcasecmp(p, mdio_fmtexts[n])) break;
+     362             : 
+     363             :                 // If !mdio_fmtexts[n], we failed (unknown ext)
+     364           0 :                 if (!mdio_fmtexts[n]) {
+     365           0 :                         free(mf);
+     366           0 :                         mdio_seterror(MDIO_UNKNOWNFMT);
+     367           0 :                         return NULL;
+     368             :                 }
+     369             : 
+     370             :                 // All set
+     371           0 :                 mf->fmt = n;
+     372             :         }
+     373             :         else {
+     374         195 :                 mf->fmt = fmt;
+     375             :         }
+     376             : 
+     377             :         // Differentiate between binary and ascii files. Also,
+     378             :         // .trX files need a header information structure allocated.
+     379         195 :         switch (mf->fmt) {
+     380           0 :     case MDFMT_GRO:
+     381             :         case MDFMT_G96: /* fallthrough */
+     382           0 :         if (rw) 
+     383           0 :             mf->f = fopen(fn, "wt");
+     384             :         else
+     385           0 :             mf->f = fopen(fn, "rt");
+     386             : 
+     387             :                 break;
+     388           5 :         case MDFMT_TRR:
+     389             :         case MDFMT_TRJ: /* fallthrough */
+     390             :                 // Allocate the trx header data struct
+     391           5 :                 mf->trx = (trx_hdr *) malloc(sizeof(trx_hdr));
+     392           5 :                 if (!mf->trx) {
+     393           0 :                         free(mf);
+     394           0 :                         mdio_seterror(MDIO_BADMALLOC);
+     395           0 :                         return NULL;
+     396             :                 }
+     397             :                 memset(mf->trx, 0, sizeof(trx_hdr));
+     398         195 :         case MDFMT_XTC:  /* fallthrough */
+     399             :                 // Finally, open the file
+     400         195 :         if (rw)
+     401           0 :             mf->f = fopen(fn, "wb");
+     402             :         else
+     403         195 :             mf->f = fopen(fn, "rb");
+     404             : 
+     405             :                 break;
+     406           0 :         default:
+     407           0 :                 free(mf);
+     408           0 :                 mdio_seterror(MDIO_UNKNOWNFMT);
+     409           0 :                 return NULL;
+     410             :         }
+     411             : 
+     412             :         // Check for opening error
+     413         195 :         if (!mf->f) {
+     414           0 :                 if (mf->trx) free(mf->trx);
+     415           0 :                 free(mf);
+     416           0 :                 mdio_seterror(MDIO_CANTOPEN);
+     417           0 :                 return NULL;
+     418             :         }
+     419             : 
+     420             :         // File is opened, we're all set!
+     421         195 :         mdio_seterror(MDIO_SUCCESS);
+     422         195 :         return mf;
+     423             : }
+     424             : 
+     425             : 
+     426             : // Closes a molecular dynamics file.
+     427         195 : static int mdio_close(md_file *mf) {
+     428         195 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+     429             : 
+     430         195 :         if (fclose(mf->f) == EOF) return mdio_seterror(MDIO_CANTCLOSE);
+     431             : 
+     432             :         // Free the dynamically allocated memory
+     433         195 :         if (mf->trx) free(mf->trx);
+     434         195 :         free(mf);
+     435         195 :         return mdio_seterror(MDIO_SUCCESS);
+     436             : }
+     437             : 
+     438             : 
+     439             : // Returns the last error code reported by any of the mdio functions
+     440         195 : static int mdio_errno(void) {
+     441         195 :         return mdio_errcode;
+     442             : }
+     443             : 
+     444             : 
+     445             : // Returns a textual message regarding an mdio error code
+     446           0 : static const char *mdio_errmsg(int n) {
+     447           0 :         if (n < 0 || n > MDIO_MAX_ERRVAL) return (char *) "unknown error";
+     448           0 :         else return mdio_errdescs[n];
+     449             : }
+     450             : 
+     451             : 
+     452             : // Sets the error code and returns an appropriate return value
+     453             : // for the calling function to return to its parent
+     454     2371101 : static int mdio_seterror(int code) {
+     455     2371101 :         mdio_errcode = code;
+     456     2371101 :         return code ? -1 : 0;
+     457             : }
+     458             : 
+     459             : 
+     460             : // Reads a line from the text file, strips leading/trailing whitespace
+     461             : // and newline, checks for errors, and returns the number of characters
+     462             : // in the string on success or -1 on error.
+     463           0 : static int mdio_readline(md_file *mf, char *buf, int n, int strip) {
+     464           0 :         if (!buf || n < 1 || !mf) return mdio_seterror(MDIO_BADPARAMS);
+     465             : 
+     466             :         // Read the line
+     467           0 :         fgets(buf, n, mf->f);
+     468             : 
+     469             :         // End of file reached?
+     470           0 :         if (feof(mf->f)) return mdio_seterror(MDIO_EOF);
+     471             : 
+     472             :         // File I/O error?
+     473           0 :         if (ferror(mf->f)) return mdio_seterror(MDIO_IOERROR);
+     474             : 
+     475             :         // comment line?
+     476           0 :         if (buf[0] == '#') return mdio_readline(mf,buf,n,strip);
+     477             : 
+     478             :         // Strip whitespace
+     479           0 :         if (strip) strip_white(buf);
+     480             : 
+     481           0 :         return strlen(buf);
+     482             : }
+     483             : 
+     484             : 
+     485             : // Strips leading and trailing whitespace from a string. Tabs,
+     486             : // spaces, newlines and carriage returns are stripped. Example:
+     487             : // "\n   hello\t \r" becomes "hello".
+     488           0 : static int strip_white(char *buf) {
+     489             :         int i, j, k;
+     490             : 
+     491             :         // Protect against NULL pointer
+     492           0 :         if (!buf) return -1;
+     493           0 :         if (!strlen(buf)) return -1;
+     494             : 
+     495             :         // Kill trailing whitespace first
+     496           0 :         for (i = strlen(buf) - 1;
+     497           0 :              buf[i] == ' ' || buf[i] == '\t' ||
+     498           0 :              buf[i] == '\n' || buf[i] == '\r';
+     499             :              i--)
+     500           0 :                 buf[i] = 0;
+     501             : 
+     502             :         // Skip past leading whitespace
+     503           0 :         for (i = 0; buf[i] == ' ' || buf[i] == '\t' ||
+     504           0 :              buf[i] == '\n' || buf[i] == '\r'; i++);
+     505           0 :         if (i) {
+     506             :                 k = 0;
+     507           0 :                 for (j = i; buf[j]; j++)
+     508           0 :                         buf[k++] = buf[j];
+     509           0 :                 buf[k] = 0;
+     510             :         }
+     511             : 
+     512           0 :         return strlen(buf);
+     513             : }
+     514             : 
+     515             : 
+     516             : // Frees the memory allocated in a ts structure. The holderror
+     517             : // parameter defaults to zero. Programs that are calling this
+     518             : // function because of an error reported by another function should
+     519             : // set holderror so that mdio_tsfree() does not overwrite the error
+     520             : // code with mdio_seterror().
+     521       18257 : static int mdio_tsfree(md_ts *ts, int holderror) {
+     522       18257 :         if (!ts) {
+     523           0 :                 if (holderror) return -1;
+     524           0 :                 else return mdio_seterror(MDIO_BADPARAMS);
+     525             :         }
+     526             : 
+     527       18257 :         if (ts->pos && ts->natoms > 0) free(ts->pos);
+     528             : 
+     529       18257 :   if (ts->box) free(ts->box);
+     530             : 
+     531       18257 :         if (holderror) return -1;
+     532       18257 :         else return mdio_seterror(MDIO_SUCCESS);
+     533             : }
+     534             : 
+     535             : 
+     536             : // Converts box basis vectors to A, B, C, alpha, beta, and gamma.  
+     537             : // Stores values in md_box struct, which should be allocated before calling
+     538             : // this function.
+     539       18257 : static int mdio_readbox(md_box *box, float *x, float *y, float *z) {
+     540             :   float A, B, C;
+     541             : 
+     542       18257 :   if (!box) {
+     543           0 :     return mdio_seterror(MDIO_BADPARAMS);
+     544             :   }
+     545             : 
+     546             :   // A, B, C are the lengths of the x, y, z vectors, respectively
+     547       18257 :   A = sqrt( x[0]*x[0] + x[1]*x[1] + x[2]*x[2] ) * ANGS_PER_NM;
+     548       18257 :   B = sqrt( y[0]*y[0] + y[1]*y[1] + y[2]*y[2] ) * ANGS_PER_NM;
+     549       18257 :   C = sqrt( z[0]*z[0] + z[1]*z[1] + z[2]*z[2] ) * ANGS_PER_NM;
+     550       18257 :   if ((A<=0) || (B<=0) || (C<=0)) {
+     551             :     /* Use zero-length box size and set angles to 90. */
+     552           0 :     box->A = box->B = box->C = 0;
+     553           0 :     box->alpha = box->beta = box->gamma = 90;
+     554             :   } else {
+     555       18257 :     box->A = A;
+     556       18257 :     box->B = B;
+     557       18257 :     box->C = C;
+     558             :   
+     559             :     // gamma, beta, alpha are the angles between the x & y, x & z, y & z
+     560             :     // vectors, respectively
+     561       18257 :     box->gamma = acos( (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])*ANGS2_PER_NM2/(A*B) ) * 90.0/M_PI_2;
+     562       18257 :     box->beta = acos( (x[0]*z[0]+x[1]*z[1]+x[2]*z[2])*ANGS2_PER_NM2/(A*C) ) * 90.0/M_PI_2;
+     563       18257 :     box->alpha = acos( (y[0]*z[0]+y[1]*z[1]+y[2]*z[2])*ANGS2_PER_NM2/(B*C) ) * 90.0/M_PI_2; 
+     564             :   }
+     565       18257 :   return mdio_seterror(MDIO_SUCCESS);
+     566             : }
+     567             : 
+     568             : 
+     569             : // Reads the header of a file (format independent)
+     570         195 : static int mdio_header(md_file *mf, md_header *mdh) {
+     571             :         int n;
+     572         195 :         if (!mf || !mdh) return mdio_seterror(MDIO_BADPARAMS);
+     573         195 :         if (!mf->f) return mdio_seterror(MDIO_BADPARAMS);
+     574             : 
+     575         195 :         switch (mf->fmt) {
+     576           0 :         case MDFMT_GRO:
+     577           0 :                 if (gro_header(mf, mdh->title, MAX_MDIO_TITLE,
+     578             :                 &mdh->timeval, &mdh->natoms, 1) < 0)
+     579           0 :                         return -1;
+     580             :                 return 0;
+     581             : 
+     582           5 :         case MDFMT_TRR: 
+     583             :         case MDFMT_TRJ: /* fallthrough */
+     584           5 :                 if (trx_header(mf, 1) < 0) return -1;
+     585           5 :                 mdh->natoms = mf->trx->natoms;
+     586           5 :                 mdh->timeval = (float) mf->trx->t;
+     587           5 :                 strncpy(mdh->title, mf->trx->title, MAX_MDIO_TITLE);
+     588           5 :                 return 0;
+     589             : 
+     590           0 :         case MDFMT_G96:
+     591           0 :                 if (g96_header(mf, mdh->title, MAX_MDIO_TITLE,
+     592             :                 &mdh->timeval) < 0) return -1;
+     593           0 :                 mdh->natoms = -1;
+     594           0 :                 return 0;
+     595             : 
+     596             :         case MDFMT_XTC:
+     597             :                 memset(mdh, 0, sizeof(md_header));
+     598             :                 // Check magic number
+     599         190 :                 if (xtc_int(mf, &n) < 0) return -1;
+     600         190 :                 if (n != XTC_MAGIC) return mdio_seterror(MDIO_BADFORMAT);
+     601             : 
+     602             :                 // Get number of atoms
+     603         190 :                 if (xtc_int(mf, &n) < 0) return -1;
+     604         190 :                 mdh->natoms = n;
+     605         190 :                 rewind(mf->f);
+     606             :                 return 0;
+     607             : 
+     608           0 :         default:
+     609           0 :                 return mdio_seterror(MDIO_UNKNOWNFMT);
+     610             :         }
+     611             : }
+     612             : 
+     613             : 
+     614             : // Reads in a timestep from a file (format independent)
+     615       18452 : static int mdio_timestep(md_file *mf, md_ts *ts) {
+     616       18452 :         if (!mf || !ts) return mdio_seterror(MDIO_BADPARAMS);
+     617       18452 :         if (!mf->f) return mdio_seterror(MDIO_BADPARAMS);
+     618             : 
+     619       18452 :         switch (mf->fmt) {
+     620           0 :         case MDFMT_GRO:
+     621           0 :                 return gro_timestep(mf, ts);
+     622             : 
+     623         155 :         case MDFMT_TRR:
+     624             :         case MDFMT_TRJ: /* fallthrough */
+     625         155 :                 return trx_timestep(mf, ts);
+     626             : 
+     627           0 :         case MDFMT_G96:
+     628           0 :                 return g96_timestep(mf, ts);
+     629             : 
+     630       18297 :         case MDFMT_XTC:
+     631       18297 :                 return xtc_timestep(mf, ts);
+     632             : 
+     633           0 :         default:
+     634           0 :                 return mdio_seterror(MDIO_UNKNOWNFMT);
+     635             :         }
+     636             : }
+     637             : 
+     638             : 
+     639             : 
+     640           0 : static int g96_header(md_file *mf, char *title, int titlelen, float *timeval) {
+     641             :         char buf[MAX_G96_LINE + 1];
+     642             :         char *p;
+     643             : 
+     644             :         // Check parameters
+     645           0 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+     646             : 
+     647             :         // The header consists of blocks. The title block
+     648             :         // is mandatory, and a TIMESTEP block is optional.
+     649             :         // Example:
+     650             :         //
+     651             :         // TITLE
+     652             :         // Generated by trjconv :  t=  90.00000
+     653             :         // more title info
+     654             :         // .
+     655             :         // .
+     656             :         // .
+     657             :         // END
+     658             :         // .
+     659             :         // .
+     660             :         // .
+     661             : 
+     662           0 :         if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) return -1;
+     663           0 :         if (strcasecmp(buf, "TITLE")) return mdio_seterror(MDIO_BADFORMAT);
+     664             : 
+     665             :         // Read in the title itself
+     666           0 :         if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) return -1;
+     667             : 
+     668             :         // The timevalue can be included in the title string
+     669             :         // after a "t=" prefix.
+     670           0 :         if ((p = (char *) strstr(buf, "t="))) {
+     671             :                 char *q = p;
+     672           0 :                 *(q--) = 0;
+     673             : 
+     674             :                 // Skip the `t=' and strip whitespace from
+     675             :                 // the resulting strings
+     676           0 :                 p += 2;
+     677           0 :                 strip_white(p);
+     678           0 :                 strip_white(buf);
+     679             : 
+     680             :                 // Grab the timevalue from the title string
+     681           0 :                 if (timeval) *timeval = (float) atof(p);
+     682             :         }
+     683             :         else {
+     684             :                 // No timevalue - just copy the string and strip
+     685             :                 // any leading/trailing whitespace
+     686           0 :                 if (timeval) *timeval = 0;
+     687           0 :                 strip_white(buf);
+     688             :         }
+     689             : 
+     690             :         // Copy the title string
+     691           0 :         if (title && titlelen) strncpy(title, buf, titlelen);
+     692             : 
+     693             :         // Now ignore subsequent title lines and get the END string
+     694           0 :         while (strcasecmp(buf, "END"))
+     695           0 :                 if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) return -1;
+     696             : 
+     697             :         // Done!
+     698           0 :         return mdio_seterror(MDIO_SUCCESS);
+     699             : }
+     700             : 
+     701             : 
+     702             : // Used to determine the number of atoms in a g96 file, because
+     703             : // VMD needs to know this for some reason.
+     704           0 : static int g96_countatoms(md_file *mf) {
+     705             :         char buf[MAX_G96_LINE + 1];
+     706             :         int natoms;
+     707             :         int n;
+     708             :         long fpos;
+     709             :         float lastf;
+     710             : 
+     711           0 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+     712             : 
+     713           0 :         fpos = ftell(mf->f);
+     714             : 
+     715             :         natoms = 0;
+     716             :         for (;;) {
+     717           0 :                 if (mdio_readline(mf, buf, MAX_G96_LINE + 1, 0) < 0)
+     718             :                         break;
+     719           0 :                 n = sscanf(buf, "%*6c%*6c%*6c%*6c %*f %*f %f", &lastf);
+     720           0 :                 if (n == 1) natoms++;
+     721             :                 else {
+     722           0 :                         strip_white(buf);
+     723           0 :                         if (!strcasecmp(buf, "END")) break;
+     724             :                 }
+     725             :         }
+     726             : 
+     727           0 :         fseek(mf->f, fpos, SEEK_SET);
+     728           0 :         return natoms;
+     729             : }
+     730             : 
+     731             : 
+     732             : // Reads an atom line from the G96 file
+     733           0 : static int g96_rec(md_file *mf, md_atom *ma) {
+     734             :         char buf[MAX_G96_LINE + 1];
+     735             :         char atomnum[7];
+     736             :         int n;
+     737             : 
+     738             :         // Check parameters
+     739           0 :         if (!mf || !ma) return mdio_seterror(MDIO_BADPARAMS);
+     740             : 
+     741             :         // Read in a line, assuming it is an atom line
+     742             :         do {
+     743           0 :                 if (mdio_readline(mf, buf, MAX_G96_LINE + 1, 0) < 0) return -1;
+     744           0 :         } while (buf[0] == '#' || strlen(buf) == 0);
+     745             : 
+     746           0 :         n = sscanf(buf, "%6c%6c%6c%6c %f %f %f",
+     747           0 :                 ma->resid, ma->resname, ma->atomname, atomnum,
+     748             :                 &ma->pos[0], &ma->pos[1], &ma->pos[2]);
+     749           0 :         if (n == 7) {
+     750           0 :                 atomnum[6] = 0;
+     751           0 :                 ma->resid[6] = 0;
+     752           0 :                 ma->resname[6] = 0;
+     753           0 :                 ma->atomname[6] = 0;
+     754             : 
+     755           0 :                 strip_white(atomnum);
+     756           0 :                 strip_white(ma->resid);
+     757           0 :                 strip_white(ma->resname);
+     758           0 :                 strip_white(ma->atomname);
+     759             : 
+     760           0 :                 ma->atomnum = atoi(atomnum);
+     761             : 
+     762           0 :                 ma->pos[0] *= ANGS_PER_NM;
+     763           0 :                 ma->pos[1] *= ANGS_PER_NM;
+     764           0 :                 ma->pos[2] *= ANGS_PER_NM;
+     765             : 
+     766           0 :                 return 0;
+     767             :         }
+     768             : 
+     769           0 :         return mdio_seterror(MDIO_BADFORMAT);
+     770             : }
+     771             : 
+     772             : 
+     773             : // Reads a timestep from a G96 file and stores the data in
+     774             : // the generic md_ts structure. Returns 0 on success or a
+     775             : // negative number on error and sets mdio_errcode.
+     776           0 : static int g96_timestep(md_file *mf, md_ts *ts) {
+     777             :         char            buf[MAX_G96_LINE + 1];
+     778             :         char            stripbuf[MAX_G96_LINE + 1];
+     779             :         float           pos[3], x[3], y[3], z[3], *currAtom;
+     780             :         long            fpos;
+     781             :         int             n, i, boxItems;
+     782             : 
+     783             :         // Check parameters
+     784           0 :         if (!mf || !ts) return mdio_seterror(MDIO_BADPARAMS);
+     785             : 
+     786             :   // Allocate data space for the timestep, using the number of atoms
+     787             :   // determined by open_g96_read().
+     788           0 :         ts->pos = (float *) malloc(sizeof(float) * 3 * ts->natoms);
+     789           0 :         if (!ts->pos) {
+     790           0 :                 return mdio_seterror(MDIO_BADMALLOC);
+     791             :         }
+     792             :   currAtom = ts->pos;
+     793             : 
+     794             :         // The timesteps follow the header in a fixed block
+     795             :         // format:
+     796             :         //
+     797             :         // TIMESTEP
+     798             :         //         <step number> <time value>
+     799             :         // END
+     800             :         // POSITIONRED
+     801             :         //     <x float> <y float> <z float>
+     802             :         //     .         .         .
+     803             :         //     .         .         .
+     804             :         //     .         .         .
+     805             :         // END
+     806             :         // VELOCITYRED
+     807             :         //     <x float> <y float> <z float>
+     808             :         //     .         .         .
+     809             :         //     .         .         .
+     810             :         //     .         .         .
+     811             :         // END
+     812             :         // BOX
+     813             :         //     <x float> <y float> <z float>
+     814             :         // END
+     815             :         //
+     816             :         // -----
+     817             :         //
+     818             :         // The TIMESTEP, VELOCITY and BOX blocks are optional.
+     819             :         // Floats are written in 15.9 precision.
+     820             :         //
+     821             :         // Reference: GROMACS 2.0 user manual
+     822             :         //            http://rugmd4.chem.rug.nl/~gmx/online2.0/g96.html
+     823             : 
+     824             :         // First, look for an (optional) title block and skip it
+     825           0 :         if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) return -1;
+     826             : 
+     827           0 :   if (!strcasecmp(buf, "TITLE")) {
+     828             :     // skip over the text until we reach 'END'
+     829           0 :     while (strcasecmp(buf, "END")) {
+     830           0 :       if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) return -1;
+     831             :     }
+     832             : 
+     833             :     // Read in the next line
+     834           0 :     if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) return -1;
+     835             :   }
+     836             : 
+     837             :         // Next, look for a timestep block
+     838           0 :         if (!strcasecmp(buf, "TIMESTEP")) {
+     839             :                 // Read in the value line
+     840           0 :                 if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) return -1;
+     841             : 
+     842             :                 // Extract the time value and the timestep index
+     843           0 :                 n = sscanf(buf, "%d %f", &ts->step, &ts->time);
+     844           0 :                 if (n != 2) return mdio_seterror(MDIO_BADFORMAT);
+     845             : 
+     846             :                 // Read the "END" line
+     847           0 :                 if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) return -1;
+     848           0 :                 if (strcasecmp(buf, "END"))
+     849           0 :                         return mdio_seterror(MDIO_BADFORMAT);
+     850             : 
+     851             :                 // Read in the next line
+     852           0 :                 if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) return -1;
+     853             :         }
+     854             :         else {
+     855             :                 // No timestep specified -- set to zero
+     856           0 :                 ts->step = 0;
+     857           0 :                 ts->time = 0;
+     858             :         }
+     859             : 
+     860             :         // At this point a POSITION or POSITIONRED block
+     861             :         // is REQUIRED by the format
+     862           0 :         if (!strcasecmp(buf, "POSITIONRED")) {
+     863             : 
+     864             :     // So now we read in some atoms
+     865             :     i = 0;
+     866           0 :                 while (i < ts->natoms) {
+     867             :                         // Read in an atom
+     868           0 :                         if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0)
+     869             :                                 return -1;
+     870             :  
+     871             :       // We shouldn't reach the end yet
+     872           0 :       if (!strcasecmp(buf, "END"))
+     873           0 :         return mdio_seterror(MDIO_BADFORMAT);
+     874             : 
+     875             :                         // Get the x,y,z coordinates
+     876           0 :                         n = sscanf(buf, "%f %f %f", &pos[0], &pos[1], &pos[2]);
+     877             :       
+     878             :       // Ignore improperly formatted lines
+     879           0 :                         if (n == 3) {
+     880           0 :                                 pos[0] *= ANGS_PER_NM;
+     881           0 :                                 pos[1] *= ANGS_PER_NM;
+     882           0 :                                 pos[2] *= ANGS_PER_NM;
+     883             : 
+     884             :                                 // Copy the atom data into the array
+     885             :                                 memcpy(currAtom, pos, sizeof(float) * 3);
+     886           0 :         currAtom += 3;
+     887           0 :         i++;
+     888             :                         }
+     889             :                 }
+     890             :         }
+     891           0 :         else if (!strcasecmp(buf, "POSITION") || !strcasecmp(buf, "REFPOSITION")) {
+     892             :                 /*
+     893             :                 char resnum[7];
+     894             :                 char resname[7];
+     895             :                 char atomname[7];
+     896             :                 char atomnum[7];
+     897             :                 */
+     898             : 
+     899             :                 // So now we read in some atoms
+     900             :     i = 0;
+     901           0 :                 while (i < ts->natoms) {
+     902             :                         // Read in the first line
+     903           0 :                         if (mdio_readline(mf, buf, MAX_G96_LINE + 1, 0) < 0)
+     904             :                                 return -1;
+     905             :  
+     906             :       // We shouldn't reach the end yet
+     907             :       strcpy(stripbuf, buf);
+     908           0 :       strip_white(stripbuf); 
+     909           0 :       if (!strcasecmp(stripbuf, "END"))
+     910           0 :         return mdio_seterror(MDIO_BADFORMAT);
+     911             : 
+     912             :                         // Get the x,y,z coordinates and name data
+     913           0 :                         n = sscanf(buf, "%*6c%*6c%*6c%*6c %f %f %f",
+     914             :                                 &pos[0], &pos[1], &pos[2]);
+     915             : 
+     916             :       // Ignore improperly formatted lines
+     917           0 :                         if (n == 3) {
+     918           0 :                                 pos[0] *= ANGS_PER_NM;
+     919           0 :                                 pos[1] *= ANGS_PER_NM;
+     920           0 :                                 pos[2] *= ANGS_PER_NM;
+     921             : 
+     922             :                                 // Copy the atom data into the linked list item
+     923             :                                 memcpy(currAtom, pos, sizeof(float) * 3);
+     924           0 :                                 currAtom += 3;
+     925           0 :         i++;
+     926             :                         }
+     927             :                 }
+     928             :         }
+     929             :         else {
+     930           0 :                 return mdio_seterror(MDIO_BADFORMAT);
+     931             :         }
+     932             : 
+     933             :   // Read the END keyword
+     934           0 :   if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0)
+     935             :     return -1;
+     936           0 :   if (strcasecmp(buf, "END"))
+     937           0 :     return mdio_seterror(MDIO_BADFORMAT);
+     938             : 
+     939             :         // ... another problem: there may or may not be a VELOCITY
+     940             :         // block or a BOX block, so we need to read one line beyond
+     941             :         // the POSITION block to determine this. If neither VEL. nor
+     942             :         // BOX are present we've read a line too far and infringed
+     943             :         // on the next timestep, so we need to keep track of the
+     944             :         // position now for a possible fseek() later to backtrack.
+     945           0 :         fpos = ftell(mf->f);
+     946             : 
+     947             :         // Now we must read in the velocities and the box, if present
+     948           0 :         if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) {
+     949             :     // It's okay if we end the file here; any other errors need to be
+     950             :     // reported.
+     951           0 :     if (mdio_errcode == MDIO_EOF) 
+     952           0 :       return mdio_seterror(MDIO_SUCCESS);
+     953             :     else 
+     954             :       return -1;
+     955             :   }
+     956             : 
+     957             :         // Is there a velocity block present ?
+     958           0 :         if (!strcasecmp(buf, "VELOCITY") || !strcasecmp(buf, "VELOCITYRED")) {
+     959             :                 // Ignore all the coordinates - VMD doesn't use them
+     960             :                 for (;;) {
+     961           0 :                         if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0)
+     962             :                                 return -1;
+     963           0 :                         if (!strcasecmp(buf, "END")) break;
+     964             :                 }
+     965             : 
+     966             :                 // Again, record our position because we may need
+     967             :                 // to fseek here later if we read too far.
+     968           0 :                 fpos = ftell(mf->f);
+     969             : 
+     970             :                 // Go ahead and read the next line.
+     971           0 :                 if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) return -1;
+     972             :         }
+     973             : 
+     974             :         // Is there a box present ?
+     975           0 :         if (!strcasecmp(buf, "BOX")) {
+     976           0 :                 if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) return -1;
+     977           0 :     boxItems = sscanf(buf, " %f %f %f %f %f %f %f %f %f", 
+     978             :                &x[0], &y[1], &z[2], &x[1], &x[2], &y[0], &y[2], &z[0], &z[1]);
+     979           0 :     if (boxItems == 3) {
+     980           0 :       x[1] = x[2] = 0;
+     981           0 :       y[0] = y[2] = 0;
+     982           0 :       z[0] = z[1] = 0;
+     983             :     }
+     984           0 :     else if (boxItems != 9) 
+     985           0 :       return mdio_seterror(MDIO_BADFORMAT);
+     986             : 
+     987             :     // Allocate the box and convert the vectors.
+     988           0 :     ts->box = (md_box *) malloc(sizeof(md_box));
+     989           0 :     if (mdio_readbox(ts->box, x, y, z) < 0) {
+     990           0 :       free(ts->box);
+     991           0 :       ts->box = NULL;
+     992           0 :       return mdio_seterror(MDIO_BADFORMAT);
+     993             :     }
+     994             : 
+     995           0 :                 if (mdio_readline(mf, buf, MAX_G96_LINE + 1) < 0) {
+     996           0 :       free(ts->box);
+     997           0 :       ts->box = NULL;
+     998           0 :       return -1;
+     999             :     }
+    1000           0 :                 if (strcasecmp(buf, "END")) {
+    1001           0 :       free(ts->box);
+    1002           0 :       ts->box = NULL;
+    1003           0 :                         return mdio_seterror(MDIO_BADFORMAT);
+    1004             :     }
+    1005             :         }
+    1006             :         else {
+    1007             :                 // We have read too far, so fseek back to the
+    1008             :                 // last known safe position so we don't return
+    1009             :                 // with the file pointer set infringing on the
+    1010             :                 // next timestep data.
+    1011           0 :                 fseek(mf->f, fpos, SEEK_SET);
+    1012             :         }
+    1013             : 
+    1014             :         // We're done!
+    1015           0 :         return mdio_seterror(MDIO_SUCCESS);
+    1016             : }
+    1017             : 
+    1018             : 
+    1019             : // Attempts to read header data from a GROMACS structure file
+    1020             : // The GROMACS header format is as follows (fixed, 2 lines ASCII):
+    1021             : // <title> [ n= <timevalue> ]
+    1022             : //     <num atoms>
+    1023           0 : static int gro_header(md_file *mf, char *title, int titlelen, float *timeval,
+    1024             :                int *natoms, int rewind) {
+    1025             :   char buf[MAX_GRO_LINE + 1];
+    1026             :   long fpos;
+    1027             :   char *p;
+    1028             : 
+    1029             :   // Check parameters
+    1030           0 :   if (!mf)
+    1031           0 :     return mdio_seterror(MDIO_BADPARAMS);
+    1032             : 
+    1033             :   // Get the current file position for rewinding later
+    1034           0 :   fpos = ftell(mf->f);
+    1035             : 
+    1036             :   // The header consists of 2 lines - get the first line
+    1037           0 :   if (mdio_readline(mf, buf, MAX_GRO_LINE + 1) < 0) return -1;
+    1038             : 
+    1039             :   // The timevalue can be included in the title string
+    1040             :   // after a "t=" prefix.
+    1041           0 :   if ((p = (char *) strstr(buf, "t="))) {
+    1042             :     char *q = p;
+    1043           0 :     *(q--) = 0;
+    1044             : 
+    1045             :     // Skip the `t=' and strip whitespace from
+    1046             :     // the resulting strings
+    1047           0 :     p += 2;
+    1048           0 :     strip_white(p);
+    1049           0 :     strip_white(buf);
+    1050             : 
+    1051             :     // Grab the timevalue from the title string
+    1052           0 :     if (timeval) *timeval = (float) atof(p);
+    1053             :   } else {
+    1054             :     // No timevalue - just copy the string
+    1055           0 :     if (timeval) *timeval = 0;
+    1056             :   }
+    1057             : 
+    1058             :   // Copy the title string
+    1059           0 :   if (title && titlelen) strncpy(title, buf, titlelen);
+    1060             : 
+    1061             :   // Get the second line and grab the number of atoms
+    1062           0 :   if (mdio_readline(mf, buf, MAX_GRO_LINE + 1) < 0) return -1;
+    1063             : 
+    1064             :   // Store the number of atoms
+    1065           0 :   if (natoms && (!(*natoms = atoi(buf))))
+    1066           0 :     return mdio_seterror(MDIO_BADFORMAT);
+    1067             : 
+    1068             :   // Now we rewind the file so that subsequent calls to
+    1069             :   // gro_timestep() will succeed. gro_timestep() requires
+    1070             :   // the header to be at the current file pointer.
+    1071           0 :   if (rewind)
+    1072           0 :     fseek(mf->f, fpos, SEEK_SET);
+    1073             : 
+    1074             :   return 0; // Done!
+    1075             : }
+    1076             : 
+    1077             : 
+    1078             : // Reads one atom record from a GROMACS file. Returns GMX_SUCCESS
+    1079             : // on success or a negative number on error.
+    1080             : //
+    1081             : // Record format (one line, fixed):
+    1082             : //    rrrrrRRRRRaaaaaAAAAA <x pos> <y pos> <z pos> <x vel> <y vel> <z vel>
+    1083             : //
+    1084             : //    r = residue number
+    1085             : //    R = residue name
+    1086             : //    a = atom name
+    1087             : //    A = atom number
+    1088             : //
+    1089           0 : static int gro_rec(md_file *mf, md_atom *ma) {
+    1090             :   char buf[MAX_GRO_LINE + 1];
+    1091             :   char atomnum[6];
+    1092             :   char xposc[12], yposc[12], zposc[12];
+    1093             :   int n;
+    1094             : 
+    1095           0 :   if (!mf)
+    1096           0 :     return mdio_seterror(MDIO_BADPARAMS);
+    1097             : 
+    1098             :   do {
+    1099           0 :     if (mdio_readline(mf, buf, MAX_GRO_LINE + 1, 0) < 0)
+    1100             :       return -1;
+    1101           0 :   } while (buf[0] == '#' || !strlen(buf));
+    1102             : 
+    1103             :   // Read in the fields
+    1104           0 :   n = sscanf(buf, "%5c%5c%5c%5c%8c%8c%8c", 
+    1105           0 :              ma->resid, ma->resname, ma->atomname, atomnum, 
+    1106             :              xposc, yposc, zposc);
+    1107             : 
+    1108           0 :   if (n != 7)
+    1109           0 :     return mdio_seterror(MDIO_BADFORMAT);
+    1110             : 
+    1111             :   // Null terminate the strings
+    1112           0 :   ma->resname[5] = 0;
+    1113           0 :   ma->atomname[5] = 0;
+    1114           0 :   ma->resid[5] = 0;
+    1115           0 :   atomnum[5] = 0;
+    1116           0 :   xposc[8] = 0;
+    1117           0 :   yposc[8] = 0;
+    1118           0 :   zposc[8] = 0;
+    1119             :  
+    1120           0 :   if ((sscanf(xposc, "%f", &ma->pos[0]) != 1) ||
+    1121           0 :       (sscanf(yposc, "%f", &ma->pos[1]) != 1) ||
+    1122           0 :       (sscanf(zposc, "%f", &ma->pos[2]) != 1)) {
+    1123           0 :     return mdio_seterror(MDIO_BADFORMAT);
+    1124             :   }
+    1125             : 
+    1126             :   // Convert strings to numbers
+    1127           0 :   strip_white(atomnum);
+    1128           0 :   ma->atomnum = atoi(atomnum);
+    1129             : 
+    1130             :   // Convert nanometers to angstroms
+    1131           0 :   ma->pos[0] *= ANGS_PER_NM;
+    1132           0 :   ma->pos[1] *= ANGS_PER_NM;
+    1133           0 :   ma->pos[2] *= ANGS_PER_NM;
+    1134             : 
+    1135             :   // Strip leading and trailing whitespace
+    1136           0 :   strip_white(ma->atomname);
+    1137           0 :   strip_white(ma->resname);
+    1138           0 :   strip_white(ma->resid);
+    1139             : 
+    1140           0 :   return 0;
+    1141             : }
+    1142             : 
+    1143             : 
+    1144             : // Reads in a timestep from a .gro file. Ignores the data
+    1145             : // not needed for a timestep, so is a little faster than
+    1146             : // calling gro_rec() for each atom. Also reads in the
+    1147             : // header block.
+    1148             : //
+    1149           0 : static int gro_timestep(md_file *mf, md_ts *ts) {
+    1150             :         char buf[MAX_GRO_LINE + 1];
+    1151             :         long coord;
+    1152             :         int i, n, boxItems;
+    1153             :   float x[3], y[3], z[3];
+    1154             :   char xposc[12], yposc[12], zposc[12];
+    1155             : 
+    1156           0 :   if (!mf || !ts) 
+    1157           0 :     return mdio_seterror(MDIO_BADPARAMS);
+    1158             : 
+    1159           0 :   if (gro_header(mf, NULL, 0, &ts->time, &ts->natoms, 0) < 0)
+    1160             :     return -1;
+    1161             : 
+    1162           0 :   ts->pos = (float *) malloc(3 * sizeof(float) * ts->natoms);
+    1163           0 :   if (!ts->pos)
+    1164           0 :     return mdio_seterror(MDIO_BADMALLOC);
+    1165             : 
+    1166             :   coord = 0;
+    1167           0 :   for (i = 0; i < ts->natoms; i++) {
+    1168           0 :     if (mdio_readline(mf, buf, MAX_GRO_LINE + 1, 0) < 0) {
+    1169           0 :       free(ts->pos);
+    1170           0 :       return -1;
+    1171             :     }
+    1172             :         
+    1173           0 :     n = sscanf(buf, "%*5c%*5c%*5c%*5c%8c%8c%8c", xposc, yposc, zposc);
+    1174           0 :     if (n != 3) 
+    1175           0 :       return mdio_seterror(MDIO_BADFORMAT);
+    1176             : 
+    1177           0 :     if ((sscanf(xposc, "%f", &ts->pos[coord    ]) != 1) ||
+    1178           0 :         (sscanf(yposc, "%f", &ts->pos[coord + 1]) != 1) ||
+    1179           0 :         (sscanf(zposc, "%f", &ts->pos[coord + 2]) != 1)) {
+    1180           0 :       return mdio_seterror(MDIO_BADFORMAT);
+    1181             :     }
+    1182             : 
+    1183           0 :     ts->pos[coord    ] *= ANGS_PER_NM;
+    1184           0 :     ts->pos[coord + 1] *= ANGS_PER_NM;
+    1185           0 :     ts->pos[coord + 2] *= ANGS_PER_NM;
+    1186             : 
+    1187           0 :     coord += 3;
+    1188             :   }
+    1189             : 
+    1190             :   // Read the box, stored as three vectors representing its edges
+    1191           0 :   if (mdio_readline(mf, buf, MAX_GRO_LINE + 1, 0) < 0) {
+    1192           0 :     free(ts->pos);
+    1193           0 :     return -1;
+    1194             :   }
+    1195             : 
+    1196           0 :   boxItems = sscanf(buf, " %f %f %f %f %f %f %f %f %f", 
+    1197             :              &x[0], &y[1], &z[2], &x[1], &x[2], &y[0], &y[2], &z[0], &z[1]);
+    1198             : 
+    1199             :   // File may only include three scalars for the box information -- if
+    1200             :   // that's the case, the box is orthoganal.
+    1201           0 :   if (boxItems == 3) {
+    1202           0 :     x[1] = x[2] = 0;
+    1203           0 :     y[0] = y[2] = 0;
+    1204           0 :     z[0] = z[1] = 0;
+    1205           0 :   } else if (boxItems != 9) {
+    1206           0 :     free(ts->pos);
+    1207           0 :     return -1;
+    1208             :   }
+    1209             : 
+    1210             :   // Allocate the box and convert the vectors.
+    1211           0 :   ts->box = (md_box *) malloc(sizeof(md_box));
+    1212           0 :   if (mdio_readbox(ts->box, x, y, z) < 0) {
+    1213           0 :     free(ts->pos);
+    1214           0 :     free(ts->box);
+    1215           0 :     ts->box = NULL;
+    1216           0 :     return -1;
+    1217             :   }
+    1218             : 
+    1219             :   return 0;
+    1220             : }
+    1221             : 
+    1222             : 
+    1223             : // Attempts to read header data from a .trX trajectory file
+    1224             : //
+    1225             : // The .trX header format is as follows:
+    1226             : //
+    1227             : //      4 bytes         - magic number (0x07C9)
+    1228             : //      ...
+    1229             : //
+    1230         160 : static int trx_header(md_file *mf, int rewind) {
+    1231             :         int magic;
+    1232             :         trx_hdr *hdr;
+    1233             :         long fpos;
+    1234             : 
+    1235         160 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1236             : 
+    1237             :         // In case we need to rewind
+    1238         160 :         fpos = ftell(mf->f);
+    1239             : 
+    1240             :         // We need to store some data to the trX header data
+    1241             :         // structure inside the md_file structure
+    1242         160 :         hdr = mf->trx;
+    1243         160 :         if (!mf->trx) return mdio_seterror(MDIO_BADPARAMS);
+    1244             : 
+    1245             :         // Read the magic number
+    1246         160 :         if (trx_int(mf, &magic) < 0) return -1;
+    1247         155 :         if (magic != TRX_MAGIC) {
+    1248             :                 // Try reverse endianism
+    1249           5 :                 swap4_aligned(&magic, 1);
+    1250           5 :                 if (magic != TRX_MAGIC) return mdio_seterror(MDIO_BADFORMAT);
+    1251             : 
+    1252             :                 // Enable byte swapping (actually works, too!)
+    1253           5 :                 mf->rev = 1;
+    1254             :         }
+    1255             : 
+    1256             :         // Read the version number. 
+    1257             :         // XXX. this is not the version number, but the storage size
+    1258             :         // of the following XDR encoded string.
+    1259             :         // the 'title' string is in fact the version identifier.
+    1260             :         // since VMD does not use any of that, it does no harm,
+    1261             :         // but is should still be fixed occasionally. AK 2005/01/08.
+    1262             : 
+    1263         155 :         if(mf->fmt!=MDFMT_TRJ) {
+    1264             :                 // It appears that TRJ files either don't contain a version
+    1265             :                 // number or don't have a length-delimiter on the string,
+    1266             :                 // whereas TRR files do contain both.  Thus, with TRJ, we just
+    1267             :                 // assume that the version number is the string length and 
+    1268             :                 // just hope for the best. -- WLD 2006/07/09
+    1269         155 :                 if (trx_int(mf, &hdr->version) < 0) return -1;
+    1270             :         }
+    1271             : 
+    1272             :         // Read in the title string
+    1273         155 :         if (trx_string(mf, hdr->title, MAX_TRX_TITLE) < 0)
+    1274             :                 return -1;
+    1275             : 
+    1276             :         // Read in some size data
+    1277         155 :         if (trx_int(mf, &hdr->ir_size) < 0) return -1;
+    1278         155 :         if (trx_int(mf, &hdr->e_size) < 0) return -1;
+    1279         155 :         if (trx_int(mf, &hdr->box_size) < 0) return -1;
+    1280         155 :         if (trx_int(mf, &hdr->vir_size) < 0) return -1;
+    1281         155 :         if (trx_int(mf, &hdr->pres_size) < 0) return -1;
+    1282         155 :         if (trx_int(mf, &hdr->top_size) < 0) return -1;
+    1283         155 :         if (trx_int(mf, &hdr->sym_size) < 0) return -1;
+    1284         155 :         if (trx_int(mf, &hdr->x_size) < 0) return -1;
+    1285         155 :         if (trx_int(mf, &hdr->v_size) < 0) return -1;
+    1286         155 :         if (trx_int(mf, &hdr->f_size) < 0) return -1;
+    1287         155 :         if (trx_int(mf, &hdr->natoms) < 0) return -1;
+    1288         155 :         if (trx_int(mf, &hdr->step) < 0) return -1;
+    1289         155 :         if (trx_int(mf, &hdr->nre) < 0) return -1;
+    1290             : 
+    1291             :         // Make sure there are atoms...
+    1292         155 :         if (!hdr->natoms) return mdio_seterror(MDIO_BADFORMAT);
+    1293             : 
+    1294             :         // Try to determine precision (float? double?)
+    1295         155 :         if (hdr->x_size) mf->prec = hdr->x_size / (hdr->natoms * 3);
+    1296           0 :         else if (hdr->v_size) mf->prec = hdr->v_size / (hdr->natoms * 3);
+    1297           0 :         else if (hdr->f_size) mf->prec = hdr->f_size / (hdr->natoms * 3);
+    1298           0 :         else return mdio_seterror(MDIO_BADPRECISION);
+    1299             : 
+    1300         155 :         if (mf->prec != sizeof(float) && mf->prec != sizeof(double)) {
+    1301             :                 // We have no data types this size! The
+    1302             :                 // file must've been generated on another
+    1303             :                 // platform
+    1304           0 :                 return mdio_seterror(MDIO_BADPRECISION);
+    1305             :         }
+    1306             : 
+    1307             :         // Read in timestep and lambda
+    1308         155 :         if (trx_real(mf, &hdr->t) < 0) return -1;
+    1309         155 :         if (trx_real(mf, &hdr->lambda) < 0) return -1;
+    1310             : 
+    1311             :         // Rewind if necessary
+    1312         155 :         if (rewind) fseek(mf->f, fpos, SEEK_SET);
+    1313             : 
+    1314             :         return 0;
+    1315             : }
+    1316             : 
+    1317             : 
+    1318             : // Reads in an integer and stores it in y. Returns GMX_SUCCESS
+    1319             : // on success or a negative number on error.
+    1320        2485 : static int trx_int(md_file *mf, int *y) {
+    1321        2485 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1322             : 
+    1323             :         // sanity check.
+    1324             :         if (sizeof(int) != 4) return mdio_seterror(MDIO_SIZEERROR);
+    1325             : 
+    1326        2485 :         if (y) {
+    1327        4970 :                 if (fread(y, 4, 1, mf->f) != 1)
+    1328           5 :                         return mdio_seterror(MDIO_IOERROR);
+    1329        2480 :                 if (mf->rev) swap4_aligned(y, 1);
+    1330             :         }
+    1331           0 :         else if (fseek(mf->f, 4, SEEK_CUR) != 0)
+    1332           0 :                 return mdio_seterror(MDIO_IOERROR);
+    1333             : 
+    1334        2480 :         return mdio_seterror(MDIO_SUCCESS);
+    1335             : }
+    1336             : 
+    1337             : 
+    1338             : // Reads in either a float or a double, depending on the
+    1339             : // precision, and stores that number in y. Returns
+    1340             : // GMX_SUCCESS on success or a negative number on error.
+    1341     1458760 : static int trx_real(md_file *mf, float *y) {
+    1342             :         double x;
+    1343             : 
+    1344     1458760 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1345             : 
+    1346     1458760 :         switch (mf->prec) {
+    1347     1458760 :                 case sizeof(float):
+    1348     1458760 :                         if (!y) {
+    1349           0 :                                 if (fseek(mf->f, mf->prec, SEEK_CUR) != 0)
+    1350           0 :                                         return mdio_seterror(MDIO_IOERROR);
+    1351             :                         } else {
+    1352     2917520 :                                 if (fread(y, mf->prec, 1, mf->f) != 1)
+    1353           0 :                                         return mdio_seterror(MDIO_IOERROR);
+    1354     1458760 :                                 if (mf->rev) swap4_aligned(y, 1);
+    1355             :                         }
+    1356     1458760 :                         return mdio_seterror(MDIO_SUCCESS);
+    1357             : 
+    1358           0 :                 case sizeof(double):
+    1359           0 :                         if (!y) {
+    1360           0 :                                 if (fseek(mf->f, mf->prec, SEEK_CUR) != 0)
+    1361           0 :                                         return mdio_seterror(MDIO_IOERROR);
+    1362             :                         } else {
+    1363           0 :                                 if (fread(&x, mf->prec, 1, mf->f) != 1)
+    1364           0 :                                         return mdio_seterror(MDIO_IOERROR);
+    1365           0 :                                 if (mf->rev) swap8_aligned(&x, 1);
+    1366           0 :                                 *y = (float) x;
+    1367             :                         }
+    1368           0 :                         return mdio_seterror(MDIO_SUCCESS);
+    1369             : 
+    1370           0 :                 default:
+    1371           0 :                         return mdio_seterror(MDIO_BADPRECISION);
+    1372             :         }
+    1373             : 
+    1374             : }
+    1375             : 
+    1376             : 
+    1377             : // Reads in a real-valued vector (taking precision into account).
+    1378             : // Stores the vector in vec, and returns GMX_SUCCESS on success
+    1379             : // or a negative number on error.
+    1380      486150 : static int trx_rvector(md_file *mf, float *vec) {
+    1381      486150 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1382             : 
+    1383      486150 :         if (!vec) {
+    1384           0 :                 if (trx_real(mf, NULL) < 0) return -1;
+    1385           0 :                 if (trx_real(mf, NULL) < 0) return -1;
+    1386           0 :                 if (trx_real(mf, NULL) < 0) return -1;
+    1387           0 :                 return mdio_seterror(MDIO_SUCCESS);
+    1388             :         } else {
+    1389      486150 :                 if (trx_real(mf, &vec[0]) < 0) return -1;
+    1390      486150 :                 if (trx_real(mf, &vec[1]) < 0) return -1;
+    1391      486150 :                 if (trx_real(mf, &vec[2]) < 0) return -1;
+    1392      486150 :                 return mdio_seterror(MDIO_SUCCESS);
+    1393             :         }
+    1394             : }
+    1395             : 
+    1396             : 
+    1397             : // Reads in a string by first reading an integer containing the
+    1398             : // string's length, then reading in the string itself and storing
+    1399             : // it in str. If the length is greater than max, it is truncated
+    1400             : // and the rest of the string is skipped in the file. Returns the
+    1401             : // length of the string on success or a negative number on error.
+    1402         155 : static int trx_string(md_file *mf, char *str, int max) {
+    1403             :         int size;
+    1404             :   size_t ssize;
+    1405             : 
+    1406         155 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1407             : 
+    1408         155 :         if (trx_int(mf, &size) < 0) return -1;
+    1409         155 :   ssize = (size_t)size;
+    1410             : 
+    1411         155 :         if (str && size <= max) {
+    1412         310 :                 if (fread(str, 1, size, mf->f) != ssize)
+    1413           0 :                         return mdio_seterror(MDIO_IOERROR);
+    1414         155 :                 str[size] = 0;
+    1415         155 :                 return size;
+    1416           0 :         } else if (str) {
+    1417           0 :                 if (fread(str, 1, max, mf->f) != ssize)
+    1418           0 :                         return mdio_seterror(MDIO_IOERROR);
+    1419           0 :                 if (fseek(mf->f, size - max, SEEK_CUR) != 0)
+    1420           0 :                         return mdio_seterror(MDIO_IOERROR);
+    1421           0 :                 str[max] = 0;
+    1422           0 :                 return max;
+    1423             :         } else {
+    1424           0 :                 if (fseek(mf->f, size, SEEK_CUR) != 0)
+    1425           0 :                         return mdio_seterror(MDIO_IOERROR);
+    1426             :                 return 0;
+    1427             :         }
+    1428             : }
+    1429             : 
+    1430             : 
+    1431             : // Reads in a timestep frame from the .trX file and returns the
+    1432             : // data in a timestep structure. Returns NULL on error.
+    1433         155 : static int trx_timestep(md_file *mf, md_ts *ts) {
+    1434             :   int i;
+    1435             :   float x[3], y[3], z[3];
+    1436             :   trx_hdr *hdr;
+    1437             : 
+    1438         155 :   if (!mf || !ts) return mdio_seterror(MDIO_BADPARAMS);
+    1439         155 :   if (mf->fmt != MDFMT_TRJ && mf->fmt != MDFMT_TRR)
+    1440           0 :     return mdio_seterror(MDIO_WRONGFORMAT);
+    1441             : 
+    1442             :   // Read the header
+    1443         155 :   if (trx_header(mf) < 0) return -1;
+    1444             : 
+    1445             :   // We need some data from the trX header
+    1446         150 :   hdr = mf->trx;
+    1447         150 :   if (!hdr) return mdio_seterror(MDIO_BADPARAMS);
+    1448             : 
+    1449         150 :   if (hdr->box_size) { // XXX need to check value of box_size!!
+    1450         150 :     if (trx_rvector(mf, x) < 0) return -1;
+    1451         150 :     if (trx_rvector(mf, y) < 0) return -1;
+    1452         150 :     if (trx_rvector(mf, z) < 0) return -1;
+    1453             : 
+    1454             :     // Allocate the box and convert the vectors.
+    1455         150 :     ts->box = (md_box *) malloc(sizeof(md_box));
+    1456         150 :     if (mdio_readbox(ts->box, x, y, z) < 0) {
+    1457           0 :       free(ts->box);
+    1458           0 :       ts->box = NULL;
+    1459           0 :       return -1;
+    1460             :     }
+    1461             :   }
+    1462             : 
+    1463         150 :   if (hdr->vir_size) {
+    1464           0 :     if (trx_rvector(mf, NULL) < 0) return -1;
+    1465           0 :     if (trx_rvector(mf, NULL) < 0) return -1;
+    1466           0 :     if (trx_rvector(mf, NULL) < 0) return -1;
+    1467             :   }
+    1468             : 
+    1469         150 :   if (hdr->pres_size) {
+    1470           0 :     if (trx_rvector(mf, NULL) < 0) return -1;
+    1471           0 :     if (trx_rvector(mf, NULL) < 0) return -1;
+    1472           0 :     if (trx_rvector(mf, NULL) < 0) return -1;
+    1473             :   }
+    1474             : 
+    1475         150 :   if (hdr->x_size) {
+    1476         150 :     ts->pos = (float *) malloc(sizeof(float) * 3 * hdr->natoms);
+    1477         150 :     if (!ts->pos) 
+    1478           0 :       return mdio_seterror(MDIO_BADMALLOC);
+    1479             : 
+    1480         150 :     ts->natoms = hdr->natoms;
+    1481      485850 :     for (i = 0; i < hdr->natoms; i++) {
+    1482      485700 :       if (trx_rvector(mf, &ts->pos[i * 3]) < 0) {
+    1483           0 :         mdio_tsfree(ts, 1);
+    1484           0 :         return -1;
+    1485             :       }
+    1486             : 
+    1487      485700 :       ts->pos[i * 3    ] *= ANGS_PER_NM;
+    1488      485700 :       ts->pos[i * 3 + 1] *= ANGS_PER_NM;
+    1489      485700 :       ts->pos[i * 3 + 2] *= ANGS_PER_NM;
+    1490             :     }
+    1491             :   }
+    1492             : 
+    1493         150 :   if (hdr->v_size) {
+    1494           0 :     for (i = 0; i < hdr->natoms; i++) {
+    1495           0 :       if (trx_rvector(mf, NULL) < 0) {
+    1496           0 :         mdio_tsfree(ts, 1);
+    1497           0 :         return -1;
+    1498             :       }
+    1499             :     }
+    1500             :   }
+    1501             : 
+    1502         150 :   if (hdr->f_size) {
+    1503           0 :     for (i = 0; i < hdr->natoms; i++) {
+    1504           0 :       if (trx_rvector(mf, NULL) < 0) {
+    1505           0 :         mdio_tsfree(ts, 1);
+    1506           0 :         return -1;
+    1507             :       }
+    1508             :     }
+    1509             :   }
+    1510             : 
+    1511         150 :   return mdio_seterror(MDIO_SUCCESS);
+    1512             : }
+    1513             : 
+    1514             : 
+    1515             : // writes an int in big endian. Returns GMX_SUCCESS
+    1516             : // on success or a negative number on error.
+    1517           0 : static int put_trx_int(md_file *mf, int y) {
+    1518           0 :       if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1519             : 
+    1520             :       // sanity check.
+    1521             :       if (sizeof(int) != 4) return mdio_seterror(MDIO_SIZEERROR);
+    1522             : 
+    1523           0 :       if (mf->rev) swap4_aligned(&y, 1);
+    1524           0 :       if (fwrite(&y, 4, 1, mf->f) != 1)
+    1525           0 :     return mdio_seterror(MDIO_IOERROR);
+    1526             : 
+    1527           0 :   return mdio_seterror(MDIO_SUCCESS);
+    1528             : }
+    1529             : 
+    1530             : // writes a real in big-endian. Returns GMX_SUCCESS
+    1531             : // on success or a negative number on error.
+    1532           0 : static int put_trx_real(md_file *mf, float y) {
+    1533           0 :       if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1534             : 
+    1535           0 :       if (mf->rev) swap4_aligned(&y, 1);
+    1536           0 :       if (fwrite(&y, 4, 1, mf->f) != 1)
+    1537           0 :         return mdio_seterror(MDIO_IOERROR);
+    1538             : 
+    1539           0 :       return mdio_seterror(MDIO_SUCCESS);
+    1540             : }
+    1541             : 
+    1542             : 
+    1543             : // writes an xdr encoded string. Returns GMX_SUCCESS
+    1544             : // on success or a negative number on error.
+    1545           0 : static int put_trx_string(md_file *mf, const char *s) {
+    1546           0 :         if (!mf || !s) return mdio_seterror(MDIO_BADPARAMS);
+    1547             :         
+    1548             :         // write: size of object, string length, string data
+    1549           0 :         size_t len = strlen(s);
+    1550           0 :         if ( put_trx_int(mf, len+1)
+    1551           0 :              || put_trx_int(mf, len)
+    1552           0 :              || (fwrite(s, len, 1, mf->f) != 1))
+    1553           0 :           return mdio_seterror(MDIO_IOERROR);
+    1554             : 
+    1555           0 :         return mdio_seterror(MDIO_SUCCESS);
+    1556             : }
+    1557             : 
+    1558             : 
+    1559             : // xtc_int() - reads an integer from an xtc file
+    1560      153206 : static int xtc_int(md_file *mf, int *i) {
+    1561             :         unsigned char c[4];
+    1562             : 
+    1563      153206 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1564             :         // sanity check.
+    1565             :         if (sizeof(int) != 4) return mdio_seterror(MDIO_SIZEERROR);
+    1566             : 
+    1567      153206 :         if (fread(c, 1, 4, mf->f) != 4) {
+    1568         190 :                 if (feof(mf->f)) return mdio_seterror(MDIO_EOF);
+    1569           0 :                 else if (ferror(mf->f)) return mdio_seterror(MDIO_IOERROR);
+    1570           0 :                 else return mdio_seterror(MDIO_UNKNOWNERROR);
+    1571             :         }
+    1572             : 
+    1573      153016 :         if (i) *i = c[3] + (c[2] << 8) + (c[1] << 16) + (c[0] << 24);
+    1574      153016 :         return mdio_seterror(MDIO_SUCCESS);
+    1575             : }
+    1576             : 
+    1577             : 
+    1578             : // xtc_float() - reads a float from an xtc file
+    1579      215339 : static int xtc_float(md_file *mf, float *f) {
+    1580             :         unsigned char c[4];
+    1581             :         int i;
+    1582             : 
+    1583      215339 :         if (!mf) return mdio_seterror(MDIO_BADPARAMS);
+    1584             : 
+    1585      215339 :         if (fread(c, 1, 4, mf->f) != 4) {
+    1586           0 :                 if (feof(mf->f)) return mdio_seterror(MDIO_EOF);
+    1587           0 :                 else if (ferror(mf->f)) return mdio_seterror(MDIO_IOERROR);
+    1588           0 :                 else return mdio_seterror(MDIO_UNKNOWNERROR);
+    1589             :         }
+    1590             : 
+    1591      215339 :         if (f) {
+    1592             :                 // By reading the number in as an integer and then
+    1593             :                 // copying it to a floating point number we can
+    1594             :                 // ensure proper endianness
+    1595      215339 :                 i = c[3] + (c[2] << 8) + (c[1] << 16) + (c[0] << 24);
+    1596             :                 memcpy(f, &i, 4);
+    1597             :         }
+    1598      215339 :         return mdio_seterror(MDIO_SUCCESS);
+    1599             : }
+    1600             : 
+    1601             : 
+    1602             : // xtc_data() - reads a specific amount of data from an xtc
+    1603             : // file using the xdr format.
+    1604       10026 : static int xtc_data(md_file *mf, char *buf, int len) {
+    1605       10026 :         if (!mf || len < 1) return mdio_seterror(MDIO_BADPARAMS);
+    1606       10026 :   size_t slen = (size_t)len;
+    1607       10026 :         if (buf) {
+    1608       20052 :                 if (fread(buf, 1, slen, mf->f) != slen) {
+    1609           0 :                         if (feof(mf->f)) return mdio_seterror(MDIO_EOF);
+    1610           0 :                         if (ferror(mf->f)) return mdio_seterror(MDIO_IOERROR);
+    1611           0 :                         else return mdio_seterror(MDIO_UNKNOWNERROR);
+    1612             :                 }
+    1613       10026 :                 if (len % 4) {
+    1614        7771 :                         if (fseek(mf->f, 4 - (len % 4), SEEK_CUR)) {
+    1615           0 :                                 if (feof(mf->f)) return mdio_seterror(MDIO_EOF);
+    1616           0 :                                 if (ferror(mf->f)) return mdio_seterror(MDIO_IOERROR);
+    1617           0 :                                 else return mdio_seterror(MDIO_UNKNOWNERROR);
+    1618             :                         }
+    1619             :                 }
+    1620             :         }
+    1621             :         else {
+    1622             :                 int newlen;
+    1623             :                 newlen = len;
+    1624           0 :                 if (len % 4) newlen += (4 - (len % 4));
+    1625           0 :                 if (fseek(mf->f, newlen, SEEK_CUR)) {
+    1626           0 :                         if (feof(mf->f)) return mdio_seterror(MDIO_EOF);
+    1627           0 :                         if (ferror(mf->f)) return mdio_seterror(MDIO_IOERROR);
+    1628           0 :                         else return mdio_seterror(MDIO_UNKNOWNERROR);
+    1629             :                 }
+    1630             :         }
+    1631             :         return len;
+    1632             : }
+    1633             : 
+    1634             : 
+    1635             : // xtc_timestep() - reads a timestep from an .xtc file.
+    1636       18297 : static int xtc_timestep(md_file *mf, md_ts *ts) {
+    1637             :         int n;
+    1638             :         float f, x[3], y[3], z[3];
+    1639             : 
+    1640       18297 :         int size = 0; // explicitly initialized to zero.
+    1641             :         float precision;
+    1642             : 
+    1643       18297 :         if (!mf || !ts) return mdio_seterror(MDIO_BADPARAMS);
+    1644       18297 :         if (!mf->f) return mdio_seterror(MDIO_BADPARAMS);
+    1645       18297 :         if (mf->fmt != MDFMT_XTC) return mdio_seterror(MDIO_WRONGFORMAT);
+    1646             : 
+    1647             :         // Check magic number
+    1648       18297 :         if (xtc_int(mf, &n) < 0) return -1;
+    1649       18107 :         if (n != XTC_MAGIC) return mdio_seterror(MDIO_BADFORMAT);
+    1650             : 
+    1651             :         // Get number of atoms
+    1652       18107 :         if (xtc_int(mf, &n) < 0) return -1;
+    1653       18107 :         ts->natoms = n;
+    1654             : 
+    1655             :         // Get the simulation step
+    1656       18107 :         if (xtc_int(mf, &n) < 0) return -1;
+    1657       18107 :         ts->step = n;
+    1658             : 
+    1659             :         // Get the time value
+    1660       18107 :         if (xtc_float(mf, &f) < 0) return -1;
+    1661       18107 :         ts->time = f;
+    1662             : 
+    1663             :         // Read the basis vectors of the box
+    1664       36214 :   if ( (xtc_float(mf, &x[0]) < 0) ||
+    1665       36214 :        (xtc_float(mf, &x[1]) < 0) ||
+    1666       36214 :        (xtc_float(mf, &x[2]) < 0) ||
+    1667       36214 :        (xtc_float(mf, &y[0]) < 0) ||
+    1668       36214 :        (xtc_float(mf, &y[1]) < 0) ||
+    1669       36214 :        (xtc_float(mf, &y[2]) < 0) ||
+    1670       36214 :        (xtc_float(mf, &z[0]) < 0) ||
+    1671       54321 :        (xtc_float(mf, &z[1]) < 0) ||
+    1672       18107 :        (xtc_float(mf, &z[2]) < 0) )
+    1673           0 :     return -1;
+    1674             :   // Allocate the box and convert the vectors.
+    1675       18107 :   ts->box = (md_box *) malloc(sizeof(md_box));
+    1676       18107 :   if (mdio_readbox(ts->box, x, y, z) < 0) {
+    1677           0 :     free(ts->box);
+    1678           0 :     ts->box = NULL;
+    1679           0 :     return -1;
+    1680             :   }
+    1681             : 
+    1682       18107 :         ts->pos = (float *) malloc(sizeof(float) * 3 * ts->natoms);
+    1683       18107 :         if (!ts->pos) return mdio_seterror(MDIO_BADMALLOC);
+    1684       18107 :         n = xtc_3dfcoord(mf, ts->pos, &size, &precision);
+    1685       18107 :         if (n < 0) return -1;
+    1686             : 
+    1687             :         /* Now we're left with the job of scaling... */
+    1688     5897804 :         for (n = 0; n < ts->natoms * 3; n++)
+    1689     5879697 :                 ts->pos[n] *= ANGS_PER_NM;
+    1690             : 
+    1691       18107 :         return mdio_seterror(MDIO_SUCCESS);
+    1692             : }
+    1693             : 
+    1694             : 
+    1695             : ///////////////////////////////////////////////////////////////////////
+    1696             : // This algorithm is an implementation of the 3dfcoord algorithm
+    1697             : // written by Frans van Hoesel (hoesel@chem.rug.nl) as part of the
+    1698             : // Europort project in 1995.
+    1699             : ///////////////////////////////////////////////////////////////////////
+    1700             : 
+    1701             : // integer table used in decompression
+    1702             : static int xtc_magicints[] = {
+    1703             :         0, 0, 0, 0, 0, 0, 0, 0, 0,8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
+    1704             :         80, 101, 128, 161, 203, 256, 322, 406, 512, 645, 812, 1024, 1290,
+    1705             :         1625, 2048, 2580, 3250, 4096, 5060, 6501, 8192, 10321, 13003, 16384,
+    1706             :         20642, 26007, 32768, 41285, 52015, 65536, 82570, 104031, 131072,
+    1707             :         165140, 208063, 262144, 330280, 416127, 524287, 660561, 832255,
+    1708             :         1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 4194304,
+    1709             :         5284491, 6658042, 8388607, 10568983, 13316085, 16777216 };
+    1710             : 
+    1711             : #define FIRSTIDX 9
+    1712             : /* note that magicints[FIRSTIDX-1] == 0 */
+    1713             : #define LASTIDX (sizeof(xtc_magicints) / sizeof(*xtc_magicints))
+    1714             : 
+    1715             : 
+    1716             : // returns the number of bits in the binary expansion of
+    1717             : // the given integer.
+    1718           0 : static int xtc_sizeofint(int size) {
+    1719             :         unsigned int num = 1;
+    1720           0 :   unsigned int ssize = (unsigned int)size;
+    1721             :         int nbits = 0;
+    1722             : 
+    1723           0 :         while (ssize >= num && nbits < 32) {
+    1724           0 :                 nbits++;
+    1725           0 :                 num <<= 1;
+    1726             :         }
+    1727           0 :         return nbits;
+    1728             : }
+    1729             : 
+    1730             : // calculates the number of bits a set of integers, when compressed,
+    1731             : // will take up.
+    1732       10026 : static int xtc_sizeofints(int nints, unsigned int *sizes) {
+    1733             :         int i;
+    1734             :   unsigned int num;
+    1735             :         unsigned int nbytes, nbits, bytes[32], bytecnt, tmp;
+    1736             :         nbytes = 1;
+    1737       10026 :         bytes[0] = 1;
+    1738             :         nbits = 0;
+    1739       40104 :         for (i=0; i < nints; i++) {  
+    1740             :                 tmp = 0;
+    1741       90442 :                 for (bytecnt = 0; bytecnt < nbytes; bytecnt++) {
+    1742       60364 :                         tmp = bytes[bytecnt] * sizes[i] + tmp;
+    1743       60364 :                         bytes[bytecnt] = tmp & 0xff;
+    1744       60364 :                         tmp >>= 8;
+    1745             :                 }
+    1746       63044 :                 while (tmp != 0) {
+    1747       32966 :                         bytes[bytecnt++] = tmp & 0xff;
+    1748       32966 :                         tmp >>= 8;
+    1749             :                 }
+    1750             :                 nbytes = bytecnt;
+    1751             :         }
+    1752             :         num = 1;
+    1753       10026 :         nbytes--;
+    1754       44885 :         while (bytes[nbytes] >= num) {
+    1755       34859 :                 nbits++;
+    1756       34859 :                 num *= 2;
+    1757             :         }
+    1758       10026 :         return nbits + nbytes * 8;
+    1759             : }
+    1760             : 
+    1761             : // reads bits from a buffer.    
+    1762     9197946 : static int xtc_receivebits(int *buf, int nbits) {
+    1763             :         int cnt, num; 
+    1764             :         unsigned int lastbits, lastbyte;
+    1765             :         unsigned char * cbuf;
+    1766     9197946 :         int mask = (1 << nbits) -1;
+    1767             : 
+    1768     9197946 :         cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
+    1769     9197946 :         cnt = buf[0];
+    1770     9197946 :         lastbits = (unsigned int) buf[1];
+    1771     9197946 :         lastbyte = (unsigned int) buf[2];
+    1772             : 
+    1773             :         num = 0;
+    1774    15534423 :         while (nbits >= 8) {
+    1775     6336477 :                 lastbyte = ( lastbyte << 8 ) | cbuf[cnt++];
+    1776     6336477 :                 num |=  (lastbyte >> lastbits) << (nbits - 8);
+    1777             :                 nbits -=8;
+    1778             :         }
+    1779     9197946 :         if (nbits > 0) {
+    1780     2861469 :                 if (lastbits < (unsigned int)nbits) {
+    1781     1261744 :                         lastbits += 8;
+    1782     1261744 :                         lastbyte = (lastbyte << 8) | cbuf[cnt++];
+    1783             :                 }
+    1784     2861469 :                 lastbits -= nbits;
+    1785     2861469 :                 num |= (lastbyte >> lastbits) & ((1 << nbits) -1);
+    1786             :         }
+    1787     9197946 :         num &= mask;
+    1788     9197946 :         buf[0] = cnt;
+    1789     9197946 :         buf[1] = lastbits;
+    1790     9197946 :         buf[2] = lastbyte;
+    1791     9197946 :         return num; 
+    1792             : }
+    1793             : 
+    1794             : // decompresses small integers from the buffer
+    1795             : // sizes parameter has to be non-zero to prevent divide-by-zero
+    1796     1951818 : static void xtc_receiveints(int *buf, const int nints, int nbits,
+    1797             :                         unsigned int *sizes, int *nums) {
+    1798             :         int bytes[32];
+    1799             :         int i, j, nbytes, p, num;
+    1800             : 
+    1801     1951818 :         bytes[1] = bytes[2] = bytes[3] = 0;
+    1802             :         nbytes = 0;
+    1803     8236092 :         while (nbits > 8) {
+    1804     6284274 :                 bytes[nbytes++] = xtc_receivebits(buf, 8);
+    1805     6284274 :                 nbits -= 8;
+    1806             :         }
+    1807     1951818 :         if (nbits > 0) {
+    1808     1951818 :                 bytes[nbytes++] = xtc_receivebits(buf, nbits);
+    1809             :         }
+    1810     5855454 :         for (i = nints-1; i > 0; i--) {
+    1811             :                 num = 0;
+    1812    20375820 :                 for (j = nbytes-1; j >=0; j--) {
+    1813    16472184 :                         num = (num << 8) | bytes[j];
+    1814    16472184 :                         p = num / sizes[i];
+    1815    16472184 :                         bytes[j] = p;
+    1816    16472184 :                         num = num - p * sizes[i];
+    1817             :                 }
+    1818     3903636 :                 nums[i] = num;
+    1819             :         }
+    1820     1951818 :         nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
+    1821     1951818 : }
+    1822             : 
+    1823             : // function that actually reads and writes compressed coordinates    
+    1824       18107 : static int xtc_3dfcoord(md_file *mf, float *fp, int *size, float *precision) {
+    1825             :         static int *ip = NULL;
+    1826             :         static int oldsize;
+    1827             :         static int *buf;
+    1828             : 
+    1829             :         int minint[3], maxint[3], *lip;
+    1830             :         int smallidx;
+    1831             :         unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3;
+    1832             :         int flag, k;
+    1833             :         int small, smaller, i, is_smaller, run;
+    1834             :         float *lfp;
+    1835             :         int tmp, *thiscoord,  prevcoord[3];
+    1836             : 
+    1837             :         int bufsize, lsize;
+    1838             :         unsigned int bitsize;
+    1839             :         float inv_precision;
+    1840             : 
+    1841             :         /* avoid uninitialized data compiler warnings */
+    1842             :         bitsizeint[0] = 0;
+    1843             :         bitsizeint[1] = 0;
+    1844             :         bitsizeint[2] = 0;
+    1845             : 
+    1846       18107 :         if (xtc_int(mf, &lsize) < 0) return -1;
+    1847             : 
+    1848       18107 :         if (*size != 0 && lsize != *size) return mdio_seterror(MDIO_BADFORMAT);
+    1849             : 
+    1850       18107 :         *size = lsize;
+    1851       18107 :         size3 = *size * 3;
+    1852       18107 :         if (*size <= 9) {
+    1853       16162 :                 for (i = 0; i < *size; i++) {
+    1854        8081 :                         if (xtc_float(mf, fp + (3 * i)) < 0) return -1;
+    1855        8081 :                         if (xtc_float(mf, fp + (3 * i) + 1) < 0) return -1;
+    1856        8081 :                         if (xtc_float(mf, fp + (3 * i) + 2) < 0) return -1;
+    1857             :                 }
+    1858             :                 return *size;
+    1859             :         }
+    1860       10026 :         xtc_float(mf, precision);
+    1861       10026 :         if (ip == NULL) {
+    1862         109 :                 ip = (int *)malloc(size3 * sizeof(*ip));
+    1863         109 :                 if (ip == NULL) return mdio_seterror(MDIO_BADMALLOC);
+    1864         109 :                 bufsize = (int) (size3 * 1.2);
+    1865         109 :                 buf = (int *)malloc(bufsize * sizeof(*buf));
+    1866         109 :                 if (buf == NULL) return mdio_seterror(MDIO_BADMALLOC);
+    1867         109 :                 oldsize = *size;
+    1868        9917 :         } else if (*size > oldsize) {
+    1869           0 :                 ip = (int *)realloc(ip, size3 * sizeof(*ip));
+    1870           0 :                 if (ip == NULL) return mdio_seterror(MDIO_BADMALLOC);
+    1871           0 :                 bufsize = (int) (size3 * 1.2);
+    1872           0 :                 buf = (int *)realloc(buf, bufsize * sizeof(*buf));
+    1873           0 :                 if (buf == NULL) return mdio_seterror(MDIO_BADMALLOC);
+    1874           0 :                 oldsize = *size;
+    1875             :         }
+    1876       10026 :         buf[0] = buf[1] = buf[2] = 0;
+    1877             : 
+    1878       10026 :         xtc_int(mf, &(minint[0]));
+    1879       10026 :         xtc_int(mf, &(minint[1]));
+    1880       10026 :         xtc_int(mf, &(minint[2]));
+    1881             : 
+    1882       10026 :         xtc_int(mf, &(maxint[0]));
+    1883       10026 :         xtc_int(mf, &(maxint[1]));
+    1884       10026 :         xtc_int(mf, &(maxint[2]));
+    1885             :                 
+    1886       10026 :         sizeint[0] = maxint[0] - minint[0]+1;
+    1887       10026 :         sizeint[1] = maxint[1] - minint[1]+1;
+    1888       10026 :         sizeint[2] = maxint[2] - minint[2]+1;
+    1889             :         
+    1890             :         /* check if one of the sizes is to big to be multiplied */
+    1891       10026 :         if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff) {
+    1892           0 :                 bitsizeint[0] = xtc_sizeofint(sizeint[0]);
+    1893           0 :                 bitsizeint[1] = xtc_sizeofint(sizeint[1]);
+    1894           0 :                 bitsizeint[2] = xtc_sizeofint(sizeint[2]);
+    1895             :                 bitsize = 0; /* flag the use of large sizes */
+    1896             :         } else {
+    1897       10026 :                 bitsize = xtc_sizeofints(3, sizeint);
+    1898             :         }
+    1899             : 
+    1900       10026 :         xtc_int(mf, &smallidx);
+    1901       10026 :         smaller = xtc_magicints[FIRSTIDX > smallidx - 1 ? FIRSTIDX : smallidx - 1] / 2;
+    1902       10026 :         small = xtc_magicints[smallidx] / 2;
+    1903       10026 :         sizesmall[0] = sizesmall[1] = sizesmall[2] = xtc_magicints[smallidx];
+    1904             : 
+    1905             :         /* check for zero values that would yield corrupted data */
+    1906       10026 :         if ( !sizesmall[0] || !sizesmall[1] || !sizesmall[2] ) {
+    1907             :                 printf("XTC corrupted, sizesmall==0 (case 1)\n");
+    1908           0 :                 return -1;
+    1909             :         }
+    1910             : 
+    1911             : 
+    1912             :         /* buf[0] holds the length in bytes */
+    1913       10026 :         if (xtc_int(mf, &(buf[0])) < 0) return -1;
+    1914             : 
+    1915       10026 :         if (xtc_data(mf, (char *) &buf[3], (int) buf[0]) < 0) return -1;
+    1916             : 
+    1917       10026 :         buf[0] = buf[1] = buf[2] = 0;
+    1918             : 
+    1919             :         lfp = fp;
+    1920       10026 :         inv_precision = 1.0f / (*precision);
+    1921             :         run = 0;
+    1922             :         i = 0;
+    1923       10026 :         lip = ip;
+    1924      742980 :         while (i < lsize) {
+    1925      732954 :                 thiscoord = (int *)(lip) + i * 3;
+    1926             : 
+    1927      732954 :                 if (bitsize == 0) {
+    1928           0 :                         thiscoord[0] = xtc_receivebits(buf, bitsizeint[0]);
+    1929           0 :                         thiscoord[1] = xtc_receivebits(buf, bitsizeint[1]);
+    1930           0 :                         thiscoord[2] = xtc_receivebits(buf, bitsizeint[2]);
+    1931             :                 } else {
+    1932      732954 :                         xtc_receiveints(buf, 3, bitsize, sizeint, thiscoord);
+    1933             :                 }
+    1934             : 
+    1935      732954 :                 i++;
+    1936      732954 :                 thiscoord[0] += minint[0];
+    1937      732954 :                 thiscoord[1] += minint[1];
+    1938      732954 :                 thiscoord[2] += minint[2];
+    1939             : 
+    1940             :                 prevcoord[0] = thiscoord[0];
+    1941             :                 prevcoord[1] = thiscoord[1];
+    1942             :                 prevcoord[2] = thiscoord[2];
+    1943             :  
+    1944             : 
+    1945      732954 :                 flag = xtc_receivebits(buf, 1);
+    1946             :                 is_smaller = 0;
+    1947      732954 :                 if (flag == 1) {
+    1948      228900 :                         run = xtc_receivebits(buf, 5);
+    1949      228900 :                         is_smaller = run % 3;
+    1950      228900 :                         run -= is_smaller;
+    1951      228900 :                         is_smaller--;
+    1952             :                 }
+    1953      732954 :                 if (run > 0) {
+    1954      317750 :                         thiscoord += 3;
+    1955     1536614 :                         for (k = 0; k < run; k+=3) {
+    1956     1218864 :                                 xtc_receiveints(buf, 3, smallidx, sizesmall, thiscoord);
+    1957     1218864 :                                 i++;
+    1958     1218864 :                                 thiscoord[0] += prevcoord[0] - small;
+    1959     1218864 :                                 thiscoord[1] += prevcoord[1] - small;
+    1960     1218864 :                                 thiscoord[2] += prevcoord[2] - small;
+    1961     1218864 :                                 if (k == 0) {
+    1962             :                                         /* interchange first with second atom for better
+    1963             :                                          * compression of water molecules
+    1964             :                                          */
+    1965      317750 :                                         tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
+    1966             :                                         prevcoord[0] = tmp;
+    1967      317750 :                                         tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
+    1968             :                                         prevcoord[1] = tmp;
+    1969      317750 :                                         tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
+    1970             :                                         prevcoord[2] = tmp;
+    1971      317750 :                                         *lfp++ = prevcoord[0] * inv_precision;
+    1972      317750 :                                         *lfp++ = prevcoord[1] * inv_precision;
+    1973      317750 :                                         *lfp++ = prevcoord[2] * inv_precision;
+    1974             : 
+    1975      317750 :                                         if ( !sizesmall[0] || !sizesmall[1] || !sizesmall[2] ) {
+    1976             :                                                 printf("XTC corrupted, sizesmall==0 (case 2)\n");
+    1977           0 :                                                 return -1;
+    1978             :                                         }
+    1979             : 
+    1980             :                                 } else {
+    1981             :                                         prevcoord[0] = thiscoord[0];
+    1982             :                                         prevcoord[1] = thiscoord[1];
+    1983             :                                         prevcoord[2] = thiscoord[2];
+    1984             :                                 }
+    1985     1218864 :                                 *lfp++ = thiscoord[0] * inv_precision;
+    1986     1218864 :                                 *lfp++ = thiscoord[1] * inv_precision;
+    1987     1218864 :                                 *lfp++ = thiscoord[2] * inv_precision;
+    1988             :                         }
+    1989             :                 } else {
+    1990      415204 :                         *lfp++ = thiscoord[0] * inv_precision;
+    1991      415204 :                         *lfp++ = thiscoord[1] * inv_precision;
+    1992      415204 :                         *lfp++ = thiscoord[2] * inv_precision;          
+    1993             :                 }
+    1994      732954 :                 smallidx += is_smaller;
+    1995      732954 :                 if (is_smaller < 0) {
+    1996             :                         small = smaller;
+    1997       48962 :                         if (smallidx > FIRSTIDX) {
+    1998       48962 :                                 smaller = xtc_magicints[smallidx - 1] /2;
+    1999             :                         } else {
+    2000             :                                 smaller = 0;
+    2001             :                         }
+    2002      683992 :                 } else if (is_smaller > 0) {
+    2003             :                         smaller = small;
+    2004      114456 :                         small = xtc_magicints[smallidx] / 2;
+    2005             :                 }
+    2006      732954 :                 sizesmall[0] = sizesmall[1] = sizesmall[2] = xtc_magicints[smallidx] ;
+    2007             :         }
+    2008             :         return 1;
+    2009             : }
+    2010             : }
+    2011             : }
+    2012             : #endif
+    2013             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/crdplugin.cpp.func-sort-c.html b/coverage-libs/molfile/crdplugin.cpp.func-sort-c.html new file mode 100644 index 000000000000..7de8beaa4132 --- /dev/null +++ b/coverage-libs/molfile/crdplugin.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/crdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - crdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:558564.7 %
Date:2024-02-22 21:58:47Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_crdplugin_finiEv0
_ZN4PLMD7molfileL14open_crd_writeEPKcS2_i0
_ZN4PLMD7molfileL15close_crd_writeEPv0
_ZN4PLMD7molfileL18write_crd_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL13open_crd_readEPKcS2_Pi2
_ZN4PLMD7molfileL14close_crd_readEPv2
_ZN4PLMD7molfileL17read_crd_timestepEPviPNS0_18molfile_timestep_tE5
_ZN4PLMD7molfile22molfile_crdplugin_initEv8374
_ZN4PLMD7molfile26molfile_crdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8374
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/crdplugin.cpp.func.html b/coverage-libs/molfile/crdplugin.cpp.func.html new file mode 100644 index 000000000000..5b064cbbab0b --- /dev/null +++ b/coverage-libs/molfile/crdplugin.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/crdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - crdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:558564.7 %
Date:2024-02-22 21:58:47Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_crdplugin_finiEv0
_ZN4PLMD7molfile22molfile_crdplugin_initEv8374
_ZN4PLMD7molfile26molfile_crdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8374
_ZN4PLMD7molfileL13open_crd_readEPKcS2_Pi2
_ZN4PLMD7molfileL14close_crd_readEPv2
_ZN4PLMD7molfileL14open_crd_writeEPKcS2_i0
_ZN4PLMD7molfileL15close_crd_writeEPv0
_ZN4PLMD7molfileL17read_crd_timestepEPviPNS0_18molfile_timestep_tE5
_ZN4PLMD7molfileL18write_crd_timestepEPvPKNS0_18molfile_timestep_tE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/crdplugin.cpp.gcov.html b/coverage-libs/molfile/crdplugin.cpp.gcov.html new file mode 100644 index 000000000000..bfd1e04d35e0 --- /dev/null +++ b/coverage-libs/molfile/crdplugin.cpp.gcov.html @@ -0,0 +1,339 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/crdplugin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - crdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:558564.7 %
Date:2024-02-22 21:58:47Functions:5955.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : University of Illinois Open Source License
+       3             : Copyright 2003 Theoretical and Computational Biophysics Group, 
+       4             : All rights reserved.
+       5             : 
+       6             : Developed by:           Theoretical and Computational Biophysics Group
+       7             :                         University of Illinois at Urbana-Champaign
+       8             :                         http://www.ks.uiuc.edu/
+       9             : 
+      10             : Permission is hereby granted, free of charge, to any person obtaining a copy of
+      11             : this software and associated documentation files (the Software), to deal with 
+      12             : the Software without restriction, including without limitation the rights to 
+      13             : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+      14             : of the Software, and to permit persons to whom the Software is furnished to 
+      15             : do so, subject to the following conditions:
+      16             : 
+      17             : Redistributions of source code must retain the above copyright notice, 
+      18             : this list of conditions and the following disclaimers.
+      19             : 
+      20             : Redistributions in binary form must reproduce the above copyright notice, 
+      21             : this list of conditions and the following disclaimers in the documentation 
+      22             : and/or other materials provided with the distribution.
+      23             : 
+      24             : Neither the names of Theoretical and Computational Biophysics Group, 
+      25             : University of Illinois at Urbana-Champaign, nor the names of its contributors 
+      26             : may be used to endorse or promote products derived from this Software without 
+      27             : specific prior written permission.
+      28             : 
+      29             : THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+      30             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+      31             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
+      32             : THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
+      33             : OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+      34             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
+      35             : OTHER DEALINGS WITH THE SOFTWARE.
+      36             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      37             : #if defined(__PLUMED_HAS_MOLFILE_PLUGINS) && ! defined(__PLUMED_HAS_EXTERNAL_MOLFILE_PLUGINS)
+      38             : /***************************************************************************
+      39             :  *cr
+      40             :  *cr            (C) Copyright 1995-2009 The Board of Trustees of the
+      41             :  *cr                        University of Illinois
+      42             :  *cr                         All Rights Reserved
+      43             :  *cr
+      44             :  ***************************************************************************/
+      45             : 
+      46             : /***************************************************************************
+      47             :  * RCS INFORMATION:
+      48             :  *
+      49             :  *      $RCSfile: crdplugin.c,v $
+      50             :  *      $Author: johns $       $Locker:  $             $State: Exp $
+      51             :  *      $Revision: 1.39 $       $Date: 2013/04/13 03:29:48 $
+      52             :  *
+      53             :  ***************************************************************************/
+      54             : 
+      55             : /*
+      56             :  * TODO: This plugin should probably be merged with the 'rst7' plugin, since
+      57             :  *       the differences between them are minor, and there's no logical reason
+      58             :  *       for them to be implemented completely independently as they are now.
+      59             :  *       The major differences in formatting are in regard to the 6F12.7 (rst7)
+      60             :  *       versus 10F8.3 (crd) ascii floating point conversion modes. 
+      61             :  */
+      62             : 
+      63             : #include "largefiles.h"   /* platform dependent 64-bit file I/O defines */
+      64             : 
+      65             : #include <stdio.h>
+      66             : #include <stdlib.h>
+      67             : #include <string.h>
+      68             : #include "molfile_plugin.h"
+      69             : 
+      70             : namespace PLMD{
+      71             : namespace molfile{
+      72             : 
+      73             : typedef struct {
+      74             :   FILE *file;
+      75             :   int has_box;
+      76             :   int numatoms;
+      77             : } crddata;
+      78             :  
+      79           2 : static void *open_crd_read(const char *filename, const char *filetype, 
+      80             :     int *natoms) {
+      81             :  
+      82             :   FILE *fd;
+      83             :   crddata *data;
+      84             :  
+      85           2 :   fd = fopen(filename, "rb");
+      86           2 :   if (!fd) return NULL;
+      87             :   
+      88             :   /* first line is title, so skip past it */
+      89         162 :   while (getc(fd) != '\n');
+      90             : 
+      91             :   /* 
+      92             :    * CRD's don't store the number of atoms in the timestep, so we assume that
+      93             :    * the application will determine this for us.  
+      94             :    */
+      95           2 :   data = (crddata *)malloc(sizeof(crddata));
+      96           2 :   data->file = fd;
+      97           2 :   *natoms = MOLFILE_NUMATOMS_UNKNOWN;
+      98             :   /* filetype "crd" has no box; filetype "crdbox" does. */
+      99           2 :   data->has_box = strcmp(filetype, "crd"); 
+     100           2 :   return data;
+     101             : }
+     102             : 
+     103             : /*
+     104             :  * CRD files with box info are indistinguishable from regular CRD's.  
+     105             :  * We regard CRD's with box info as a different file format.
+     106             :  * CRD's don't tell how many atoms there are in each frame.  We therefore
+     107             :  * rely on the numatoms field in the molfile_timestep_t parameter.
+     108             :  */
+     109           5 : static int read_crd_timestep(void *mydata, int natoms, molfile_timestep_t *ts) {
+     110             :   crddata *crd = (crddata *)mydata;
+     111             :   int i, j;
+     112             :   float x, y, z;
+     113             :   float a, b, c;
+     114             : 
+     115             :   /* Read in the atom coordinates */
+     116       21382 :   for (i=0; i<natoms; i++) {
+     117       21379 :     j = fscanf(crd->file, "%f %f %f", &x, &y, &z);
+     118       21379 :     if (j == EOF) {
+     119             :       return MOLFILE_ERROR;
+     120       21377 :     } else if (j <= 0) {
+     121           0 :       fprintf(stderr, "Problem reading CRD file\n");
+     122           0 :       return MOLFILE_ERROR;
+     123             :     }
+     124             : 
+     125             :     /* only save coords if we're given a valid ts pointer */ 
+     126             :     /* otherwise assume that VMD wants us to skip it.     */
+     127       21377 :     if (ts != NULL) {
+     128       21377 :       ts->coords[3*i  ] = x;
+     129       21377 :       ts->coords[3*i+1] = y;
+     130       21377 :       ts->coords[3*i+2] = z;
+     131             :     }
+     132             :   }
+     133             : 
+     134             : 
+     135             :   /* Read the PBC box info. */
+     136           3 :   if (crd->has_box) {
+     137           2 :     j = fscanf(crd->file, "%f %f %f", &a, &b, &c);
+     138           2 :     if (j == EOF) {
+     139             :       printf("EOF in box\n");
+     140           0 :       return MOLFILE_ERROR;
+     141           2 :     } else if (j <= 0) {
+     142             :       printf("Problem reading box part of CRD file, scanf returned %d\n",j);
+     143           0 :       return MOLFILE_ERROR;
+     144             :     }
+     145             : 
+     146             :     /* only save coords if we're given a valid ts pointer */ 
+     147             :     /* otherwise assume that VMD wants us to skip it.     */
+     148           2 :     if (ts != NULL) {
+     149           2 :       ts->A = a;
+     150           2 :       ts->B = b;
+     151           2 :       ts->C = c;
+     152             : 
+     153             :       /* XXX periodic cell angles are only stored in the PARM file */
+     154             :       /* we should probably retrieve these from the already-loaded */
+     155             :       /* molecule when possible.                                   */
+     156           2 :       ts->alpha = 90.0;
+     157           2 :       ts->beta  = 90.0;
+     158           2 :       ts->gamma = 90.0;
+     159             :     }
+     160             :   }
+     161             : 
+     162             :   return MOLFILE_SUCCESS;
+     163             : }
+     164             :     
+     165           2 : static void close_crd_read(void *mydata) {
+     166             :   crddata *crd = (crddata *)mydata;
+     167           2 :   fclose(crd->file);
+     168           2 :   free(crd);
+     169           2 : }
+     170             : 
+     171           0 : static void *open_crd_write(const char *path, const char *filetype,
+     172             :     int natoms) {
+     173             :   crddata *crd;
+     174             :   FILE *fd;
+     175             : 
+     176           0 :   fd = fopen(path, "wb");
+     177           0 :   if (!fd) {
+     178           0 :     fprintf(stderr, "Could not open file %s for writing\n", path);
+     179           0 :     return NULL;
+     180             :   }
+     181             :   fprintf(fd, "TITLE : Created by VMD with %d atoms\n", natoms);
+     182             :   
+     183           0 :   crd = (crddata *)malloc(sizeof(crddata));
+     184           0 :   crd->file = fd;
+     185           0 :   crd->numatoms = natoms;
+     186           0 :   crd->has_box = strcmp(filetype, "crd"); 
+     187           0 :   return crd;
+     188             : }    
+     189             :   
+     190           0 : static int write_crd_timestep(void *v, const molfile_timestep_t *ts) {
+     191             :   crddata *crd = (crddata *)v;
+     192             :   int i;
+     193             :   int lfdone=0;
+     194           0 :   const int ndata = crd->numatoms * 3;
+     195             : 
+     196           0 :   for (i=0; i<ndata; i++) {
+     197             :     lfdone = 0;
+     198           0 :     fprintf(crd->file, "%8.3f", ts->coords[i]);
+     199           0 :     if ((i+1) % 10 == 0) {
+     200           0 :       fprintf(crd->file, "\n"); 
+     201             :       lfdone = 1;
+     202             :     }
+     203             :   }
+     204           0 :   if (!lfdone)
+     205           0 :     fprintf(crd->file, "\n"); 
+     206             :     
+     207           0 :   if (crd->has_box) {
+     208           0 :     fprintf (crd->file, "%8.3f%8.3f%8.3f\n", ts->A, ts->B, ts->C);
+     209             :   }
+     210             : 
+     211           0 :   return MOLFILE_SUCCESS;
+     212             : }
+     213             : 
+     214           0 : static void close_crd_write(void *v) {
+     215             :   crddata *crd = (crddata *)v;
+     216           0 :   fclose(crd->file);
+     217           0 :   free(crd);
+     218           0 : }
+     219             : 
+     220             : /* registration stuff */
+     221             :     
+     222             : static molfile_plugin_t plugin;
+     223             : static molfile_plugin_t crdboxplugin;
+     224             : 
+     225        8374 : VMDPLUGIN_API int VMDPLUGIN_init(void) { 
+     226             :   memset(&plugin, 0, sizeof(molfile_plugin_t));
+     227        8374 :   plugin.abiversion = vmdplugin_ABIVERSION;
+     228        8374 :   plugin.type = MOLFILE_PLUGIN_TYPE;
+     229        8374 :   plugin.name = "crd";
+     230        8374 :   plugin.prettyname = "AMBER Coordinates";
+     231        8374 :   plugin.author = "Justin Gullingsrud, John Stone";
+     232             :   plugin.majorv = 0;
+     233        8374 :   plugin.minorv = 9;
+     234        8374 :   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
+     235        8374 :   plugin.filename_extension = "mdcrd,crd";
+     236        8374 :   plugin.open_file_read = open_crd_read;
+     237        8374 :   plugin.read_next_timestep = read_crd_timestep;
+     238        8374 :   plugin.close_file_read = close_crd_read;
+     239        8374 :   plugin.open_file_write = open_crd_write;
+     240        8374 :   plugin.write_timestep = write_crd_timestep;
+     241        8374 :   plugin.close_file_write = close_crd_write;
+     242             : 
+     243             :   memcpy(&crdboxplugin, &plugin, sizeof(molfile_plugin_t));
+     244        8374 :   crdboxplugin.name = "crdbox";
+     245        8374 :   crdboxplugin.prettyname = "AMBER Coordinates with Periodic Box";
+     246             : 
+     247        8374 :   return VMDPLUGIN_SUCCESS; 
+     248             : }
+     249             : 
+     250        8374 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     251        8374 :   (*cb)(v, (vmdplugin_t *)&plugin);
+     252        8374 :   (*cb)(v, (vmdplugin_t *)&crdboxplugin);
+     253        8374 :   return VMDPLUGIN_SUCCESS;
+     254             : }
+     255             : 
+     256           0 : VMDPLUGIN_API int VMDPLUGIN_fini(void) { return VMDPLUGIN_SUCCESS; }
+     257             : 
+     258             : }
+     259             : }
+     260             : 
+     261             : #endif
+     262             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/dcdplugin.cpp.func-sort-c.html b/coverage-libs/molfile/dcdplugin.cpp.func-sort-c.html new file mode 100644 index 000000000000..168fdbd72f8d --- /dev/null +++ b/coverage-libs/molfile/dcdplugin.cpp.func-sort-c.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/dcdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - dcdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:20146143.6 %
Date:2024-02-22 21:58:47Functions:101952.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_dcdplugin_finiEv0
_ZN4PLMD7molfileL12skip_dcdstepEiiii0
_ZN4PLMD7molfileL13write_dcdstepEiiiiPKfS2_S2_PKdi0
_ZN4PLMD7molfileL14open_dcd_writeEPKcS2_i0
_ZN4PLMD7molfileL14print_dcderrorEPKci0
_ZN4PLMD7molfileL14write_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL15write_dcdheaderEiPKciiidii0
_ZN4PLMD7molfileL16close_file_writeEPv0
_ZN4PLMD7molfileL16read_fixed_atomsEiiiPKiiPKfPfS5_i0
_ZN4PLMD7molfileL13open_dcd_readEPKcS2_Pi1
_ZN4PLMD7molfileL14close_dcd_readEPiPf1
_ZN4PLMD7molfileL14read_dcdheaderEiPiS1_S1_S1_PdS1_PS1_PPfS1_S1_1
_ZN4PLMD7molfileL15close_file_readEPv1
_ZN4PLMD7molfileL12read_dcdstepEiiPfS1_S1_S1_iiPiS1_ii21
_ZN4PLMD7molfileL16read_charmm_4dimEiii21
_ZN4PLMD7molfileL22read_charmm_extrablockEiiiPf21
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE22
_ZN4PLMD7molfile22molfile_dcdplugin_initEv8374
_ZN4PLMD7molfile26molfile_dcdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8374
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/dcdplugin.cpp.func.html b/coverage-libs/molfile/dcdplugin.cpp.func.html new file mode 100644 index 000000000000..90c6179e9147 --- /dev/null +++ b/coverage-libs/molfile/dcdplugin.cpp.func.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/dcdplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - dcdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:20146143.6 %
Date:2024-02-22 21:58:47Functions:101952.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_dcdplugin_finiEv0
_ZN4PLMD7molfile22molfile_dcdplugin_initEv8374
_ZN4PLMD7molfile26molfile_dcdplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8374
_ZN4PLMD7molfileL12read_dcdstepEiiPfS1_S1_S1_iiPiS1_ii21
_ZN4PLMD7molfileL12skip_dcdstepEiiii0
_ZN4PLMD7molfileL13open_dcd_readEPKcS2_Pi1
_ZN4PLMD7molfileL13write_dcdstepEiiiiPKfS2_S2_PKdi0
_ZN4PLMD7molfileL14close_dcd_readEPiPf1
_ZN4PLMD7molfileL14open_dcd_writeEPKcS2_i0
_ZN4PLMD7molfileL14print_dcderrorEPKci0
_ZN4PLMD7molfileL14read_dcdheaderEiPiS1_S1_S1_PdS1_PS1_PPfS1_S1_1
_ZN4PLMD7molfileL14write_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL15close_file_readEPv1
_ZN4PLMD7molfileL15write_dcdheaderEiPKciiidii0
_ZN4PLMD7molfileL16close_file_writeEPv0
_ZN4PLMD7molfileL16read_charmm_4dimEiii21
_ZN4PLMD7molfileL16read_fixed_atomsEiiiPKiiPKfPfS5_i0
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE22
_ZN4PLMD7molfileL22read_charmm_extrablockEiiiPf21
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/dcdplugin.cpp.gcov.html b/coverage-libs/molfile/dcdplugin.cpp.gcov.html new file mode 100644 index 000000000000..79d17ae30772 --- /dev/null +++ b/coverage-libs/molfile/dcdplugin.cpp.gcov.html @@ -0,0 +1,1394 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/dcdplugin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - dcdplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:20146143.6 %
Date:2024-02-22 21:58:47Functions:101952.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : University of Illinois Open Source License
+       3             : Copyright 2003 Theoretical and Computational Biophysics Group, 
+       4             : All rights reserved.
+       5             : 
+       6             : Developed by:           Theoretical and Computational Biophysics Group
+       7             :                         University of Illinois at Urbana-Champaign
+       8             :                         http://www.ks.uiuc.edu/
+       9             : 
+      10             : Permission is hereby granted, free of charge, to any person obtaining a copy of
+      11             : this software and associated documentation files (the Software), to deal with 
+      12             : the Software without restriction, including without limitation the rights to 
+      13             : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+      14             : of the Software, and to permit persons to whom the Software is furnished to 
+      15             : do so, subject to the following conditions:
+      16             : 
+      17             : Redistributions of source code must retain the above copyright notice, 
+      18             : this list of conditions and the following disclaimers.
+      19             : 
+      20             : Redistributions in binary form must reproduce the above copyright notice, 
+      21             : this list of conditions and the following disclaimers in the documentation 
+      22             : and/or other materials provided with the distribution.
+      23             : 
+      24             : Neither the names of Theoretical and Computational Biophysics Group, 
+      25             : University of Illinois at Urbana-Champaign, nor the names of its contributors 
+      26             : may be used to endorse or promote products derived from this Software without 
+      27             : specific prior written permission.
+      28             : 
+      29             : THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+      30             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+      31             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
+      32             : THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
+      33             : OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+      34             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
+      35             : OTHER DEALINGS WITH THE SOFTWARE.
+      36             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      37             : #if defined(__PLUMED_HAS_MOLFILE_PLUGINS) && ! defined(__PLUMED_HAS_EXTERNAL_MOLFILE_PLUGINS)
+      38             : /***************************************************************************
+      39             :  *cr                                                                       
+      40             :  *cr            (C) Copyright 1995-2016 The Board of Trustees of the           
+      41             :  *cr                        University of Illinois                       
+      42             :  *cr                         All Rights Reserved                        
+      43             :  *cr                                                                   
+      44             :  ***************************************************************************/
+      45             : 
+      46             : /***************************************************************************
+      47             :  * RCS INFORMATION:
+      48             :  *
+      49             :  *      $RCSfile: dcdplugin.c,v $
+      50             :  *      $Author: johns $       $Locker:  $             $State: Exp $
+      51             :  *      $Revision: 1.88 $       $Date: 2020/12/17 17:14:07 $
+      52             :  *
+      53             :  ***************************************************************************
+      54             :  * DESCRIPTION:
+      55             :  *   Code for reading and writing CHARMM, NAMD, and X-PLOR format 
+      56             :  *   molecular dynamic trajectory files.
+      57             :  *
+      58             :  * TODO:
+      59             :  *   Integrate improvements from the NAMD source tree
+      60             :  *    - NAMD's writer code has better type-correctness for the sizes
+      61             :  *      of "int".  NAMD uses "int32" explicitly, which is required on
+      62             :  *      machines like the T3E.  VMD's version of the code doesn't do that
+      63             :  *      presently.
+      64             :  *
+      65             :  *  Try various alternative I/O API options:
+      66             :  *   - use mmap(), with read-once flags
+      67             :  *   - use O_DIRECT open mode on new revs of Linux kernel 
+      68             :  *   - use directio() call on a file descriptor to enable on Solaris
+      69             :  *   - use aio_open()/read()/write()
+      70             :  *   - use readv/writev() etc.
+      71             :  *
+      72             :  *  Standalone test binary compilation flags:
+      73             :  *  cc -fast -xarch=v9a -I../../include -DTEST_DCDPLUGIN dcdplugin.c \
+      74             :  *    -o ~/bin/readdcd -lm
+      75             :  *
+      76             :  *  Profiling flags:
+      77             :  *  cc -xpg -fast -xarch=v9a -g -I../../include -DTEST_DCDPLUGIN dcdplugin.c \
+      78             :  *    -o ~/bin/readdcd -lm
+      79             :  *
+      80             :  ***************************************************************************/
+      81             : 
+      82             : #include "largefiles.h"   /* platform dependent 64-bit file I/O defines */
+      83             : #include "fastio.h"       /* must come before others, for O_DIRECT...   */
+      84             : 
+      85             : #include <stdio.h>
+      86             : #include <sys/stat.h>
+      87             : #include <sys/types.h>
+      88             : #include <stdlib.h>
+      89             : #include <stddef.h>
+      90             : #include <string.h>
+      91             : #include <math.h>
+      92             : #include <time.h>
+      93             : #include "endianswap.h"
+      94             : #include "molfile_plugin.h"
+      95             : 
+      96             : namespace PLMD{
+      97             : namespace molfile{
+      98             : 
+      99             : #ifndef M_PI_2
+     100             : #define M_PI_2 1.57079632679489661922
+     101             : #endif
+     102             : 
+     103             : #define RECSCALE32BIT 1
+     104             : #define RECSCALE64BIT 2
+     105             : #define RECSCALEMAX   2
+     106             : 
+     107             : typedef struct {
+     108             :   fio_fd fd;
+     109             :   int natoms;
+     110             :   int nsets;
+     111             :   int setsread;
+     112             :   int istart;
+     113             :   int nsavc;
+     114             :   double delta;
+     115             :   int nfixed;
+     116             :   float *x, *y, *z;
+     117             :   int *freeind;
+     118             :   float *fixedcoords;
+     119             :   int reverse;
+     120             :   int charmm;  
+     121             :   int first;
+     122             :   int with_unitcell;
+     123             : } dcdhandle;
+     124             : 
+     125             : /* Define error codes that may be returned by the DCD routines */
+     126             : #define DCD_SUCCESS      0  /* No problems                     */
+     127             : #define DCD_EOF         -1  /* Normal EOF                      */
+     128             : #define DCD_DNE         -2  /* DCD file does not exist         */
+     129             : #define DCD_OPENFAILED  -3  /* Open of DCD file failed         */
+     130             : #define DCD_BADREAD     -4  /* read call on DCD file failed    */
+     131             : #define DCD_BADEOF      -5  /* premature EOF found in DCD file */
+     132             : #define DCD_BADFORMAT   -6  /* format of DCD file is wrong     */
+     133             : #define DCD_FILEEXISTS  -7  /* output file already exists      */
+     134             : #define DCD_BADMALLOC   -8  /* malloc failed                   */
+     135             : #define DCD_BADWRITE    -9  /* write call on DCD file failed   */
+     136             : 
+     137             : /* Define feature flags for this DCD file */
+     138             : #define DCD_IS_XPLOR        0x00
+     139             : #define DCD_IS_CHARMM       0x01
+     140             : #define DCD_HAS_4DIMS       0x02
+     141             : #define DCD_HAS_EXTRA_BLOCK 0x04
+     142             : #define DCD_HAS_64BIT_REC   0x08
+     143             : 
+     144             : /* defines used by write_dcdstep */
+     145             : #define NFILE_POS 8L
+     146             : #define NSTEP_POS 20L
+     147             : 
+     148             : /* READ Macro to make porting easier */
+     149             : #define READ(fd, buf, size)  fio_fread(((void *) buf), (size), 1, (fd))
+     150             : 
+     151             : /* WRITE Macro to make porting easier */
+     152             : #define WRITE(fd, buf, size) fio_fwrite(((void *) buf), (size), 1, (fd))
+     153             : 
+     154             : /* XXX This is broken - fread never returns -1 */
+     155             : #define CHECK_FREAD(X, msg) if (X==-1) { return(DCD_BADREAD); }
+     156             : #define CHECK_FEOF(X, msg)  if (X==0)  { return(DCD_BADEOF); }
+     157             : 
+     158             : 
+     159             : /* print DCD error in a human readable way */
+     160           0 : static void print_dcderror(const char *func, int errcode) {
+     161             :   const char *errstr;
+     162             : 
+     163           0 :   switch (errcode) {
+     164             :     case DCD_EOF:         errstr = "end of file"; break;
+     165           0 :     case DCD_DNE:         errstr = "file not found"; break;
+     166           0 :     case DCD_OPENFAILED:  errstr = "file open failed"; break;
+     167           0 :     case DCD_BADREAD:     errstr = "error during read"; break;
+     168           0 :     case DCD_BADEOF:      errstr = "premature end of file"; break;
+     169           0 :     case DCD_BADFORMAT:   errstr = "corruption or unrecognized file structure"; break;
+     170           0 :     case DCD_FILEEXISTS:  errstr = "output file already exists"; break;
+     171           0 :     case DCD_BADMALLOC:   errstr = "memory allocation failed"; break;
+     172           0 :     case DCD_BADWRITE:    errstr = "error during write"; break;
+     173           0 :     case DCD_SUCCESS:     
+     174             :     default:
+     175             :       errstr = "no error";
+     176           0 :       break;
+     177             :   } 
+     178             :   printf("dcdplugin) %s: %s\n", func, errstr); 
+     179           0 : }
+     180             : 
+     181             : 
+     182             : /*
+     183             :  * Read the header information from a dcd file.
+     184             :  * Input: fd - a file struct opened for binary reading.
+     185             :  * Output: 0 on success, negative error code on failure.
+     186             :  * Side effects: *natoms set to number of atoms per frame
+     187             :  *               *nsets set to number of frames in dcd file
+     188             :  *               *istart set to starting timestep of dcd file
+     189             :  *               *nsavc set to timesteps between dcd saves
+     190             :  *               *delta set to value of trajectory timestep
+     191             :  *               *nfixed set to number of fixed atoms 
+     192             :  *               *freeind may be set to heap-allocated space
+     193             :  *               *reverse set to one if reverse-endian, zero if not.
+     194             :  *               *charmm set to internal code for handling charmm data.
+     195             :  */
+     196           1 : static int read_dcdheader(fio_fd fd, int *N, int *NSET, int *ISTART, 
+     197             :                    int *NSAVC, double *DELTA, int *NAMNF, 
+     198             :                    int **FREEINDEXES, float **fixedcoords, int *reverseEndian, 
+     199             :                    int *charmm)
+     200             : {
+     201             :   unsigned int input_integer[2];  /* buffer space */
+     202             :   int i, ret_val, rec_scale;
+     203             :   char hdrbuf[84];    /* char buffer used to store header */
+     204             :   int NTITLE;
+     205             :   int dcdcordmagic;
+     206             :   int hugefile = 0;
+     207             :   char *corp = (char *) &dcdcordmagic;
+     208             : 
+     209             :   /* coordinate dcd file magic string 'CORD' */
+     210             :   corp[0] = 'C';
+     211             :   corp[1] = 'O';
+     212             :   corp[2] = 'R';
+     213             :   corp[3] = 'D';
+     214             : 
+     215             :   /* First thing in the file should be an 84.
+     216             :    * some 64-bit compiles have a 64-bit record length indicator,
+     217             :    * so we have to read two ints and check in a more complicated 
+     218             :    * way. :-( */
+     219           1 :   ret_val = READ(fd, input_integer, 2*sizeof(unsigned int));
+     220           1 :   CHECK_FREAD(ret_val, "reading first int from dcd file");
+     221           1 :   CHECK_FEOF(ret_val, "reading first int from dcd file");
+     222             : 
+     223             :   /* Check magic number in file header and determine byte order*/
+     224           1 :   if ((input_integer[0]+input_integer[1]) == 84) {
+     225           0 :     *reverseEndian=0;
+     226             :     rec_scale=RECSCALE64BIT;
+     227             :     printf("dcdplugin) detected CHARMM -i8 64-bit DCD file of native endianness\n");
+     228           1 :   } else if (input_integer[0] == 84 && input_integer[1] == dcdcordmagic) {
+     229           1 :     *reverseEndian=0;
+     230             :     rec_scale=RECSCALE32BIT;
+     231             :     printf("dcdplugin) detected standard 32-bit DCD file of native endianness\n");
+     232             :   } else {
+     233             :     /* now try reverse endian */
+     234           0 :     swap4_aligned(input_integer, 2); /* will have to unswap magic if 32-bit */
+     235           0 :     if ((input_integer[0]+input_integer[1]) == 84) {
+     236           0 :       *reverseEndian=1;
+     237             :       rec_scale=RECSCALE64BIT;
+     238             :       printf("dcdplugin) detected CHARMM -i8 64-bit DCD file of opposite endianness\n");
+     239             :     } else {
+     240           0 :       swap4_aligned(&input_integer[1], 1); /* unswap magic (see above) */
+     241           0 :       if (input_integer[0] == 84 && input_integer[1] == dcdcordmagic) {
+     242           0 :         *reverseEndian=1;
+     243             :         rec_scale=RECSCALE32BIT;
+     244             :         printf("dcdplugin) detected standard 32-bit DCD file of opposite endianness\n");
+     245             :       } else {
+     246             :         /* not simply reversed endianism or -i8, something rather more evil */
+     247             :         printf("dcdplugin) unrecognized DCD header:\n");
+     248           0 :         printf("dcdplugin)   [0]: %10d  [1]: %10d\n", input_integer[0], input_integer[1]);
+     249           0 :         printf("dcdplugin)   [0]: 0x%08x  [1]: 0x%08x\n", input_integer[0], input_integer[1]);
+     250           0 :         return DCD_BADFORMAT;
+     251             : 
+     252             :       }
+     253             :     }
+     254             :   }
+     255             : 
+     256             :   /* check for magic string, in case of long record markers */
+     257             :   if (rec_scale == RECSCALE64BIT) { 
+     258           0 :     ret_val = READ(fd, input_integer, sizeof(unsigned int));
+     259           0 :     if (input_integer[0] != dcdcordmagic) {
+     260             :       printf("dcdplugin) failed to find CORD magic in CHARMM -i8 64-bit DCD file\n");
+     261           0 :       return DCD_BADFORMAT;
+     262             :     }
+     263             :   }
+     264             : 
+     265             :   /* Buffer the entire header for random access */
+     266           1 :   ret_val = READ(fd, hdrbuf, 80);
+     267           1 :   CHECK_FREAD(ret_val, "buffering header");
+     268           1 :   CHECK_FEOF(ret_val, "buffering header");
+     269             : 
+     270             :   /* CHARMm-genereate DCD files set the last integer in the     */
+     271             :   /* header, which is unused by X-PLOR, to its version number.  */
+     272             :   /* Checking if this is nonzero tells us this is a CHARMm file */
+     273             :   /* and to look for other CHARMm flags.                        */
+     274           1 :   if (*((int *) (hdrbuf + 76)) != 0) {
+     275           1 :     (*charmm) = DCD_IS_CHARMM;
+     276           1 :     if (*((int *) (hdrbuf + 40)) != 0)
+     277           1 :       (*charmm) |= DCD_HAS_EXTRA_BLOCK;
+     278             : 
+     279           1 :     if (*((int *) (hdrbuf + 44)) == 1)
+     280           0 :       (*charmm) |= DCD_HAS_4DIMS;
+     281             : 
+     282           1 :     if (rec_scale == RECSCALE64BIT)
+     283           0 :       (*charmm) |= DCD_HAS_64BIT_REC;
+     284             :   
+     285             :   } else {
+     286           0 :     (*charmm) = DCD_IS_XPLOR; /* must be an X-PLOR format DCD file */
+     287             :   }
+     288             : 
+     289           1 :   if (*charmm & DCD_IS_CHARMM) {
+     290             :     /* CHARMM and NAMD versions 2.1b1 and later */
+     291             :     printf("dcdplugin) CHARMM format DCD file (also NAMD 2.1 and later)\n");
+     292             :   } else {
+     293             :     /* CHARMM and NAMD versions prior to 2.1b1  */
+     294             :     printf("dcdplugin) X-PLOR format DCD file (also NAMD 2.0 and earlier)\n");
+     295             :   }
+     296             : 
+     297             :   /* Store the number of sets of coordinates (NSET) */
+     298           1 :   (*NSET) = *((int *) (hdrbuf));
+     299           1 :   if (*reverseEndian) swap4_unaligned(NSET, 1);
+     300             : 
+     301             :   /* Store ISTART, the starting timestep */
+     302           1 :   (*ISTART) = *((int *) (hdrbuf + 4));
+     303           1 :   if (*reverseEndian) swap4_unaligned(ISTART, 1);
+     304             : 
+     305             :   /* Store NSAVC, the number of timesteps between dcd saves */
+     306           1 :   (*NSAVC) = *((int *) (hdrbuf + 8));
+     307           1 :   if (*reverseEndian) swap4_unaligned(NSAVC, 1);
+     308             : 
+     309             :   /* Store NAMNF, the number of fixed atoms */
+     310           1 :   (*NAMNF) = *((int *) (hdrbuf + 32));
+     311           1 :   if (*reverseEndian) swap4_unaligned(NAMNF, 1);
+     312             : 
+     313             :   /* Read in the timestep, DELTA */
+     314             :   /* Note: DELTA is stored as a double with X-PLOR but as a float with CHARMm */
+     315           1 :   if ((*charmm) & DCD_IS_CHARMM) {
+     316             :     float ftmp;
+     317           1 :     ftmp = *((float *)(hdrbuf+36)); /* is this safe on Alpha? */
+     318           1 :     if (*reverseEndian)
+     319           0 :       swap4_aligned(&ftmp, 1);
+     320             : 
+     321           1 :     *DELTA = (double)ftmp;
+     322             :   } else {
+     323           0 :     (*DELTA) = *((double *)(hdrbuf + 36));
+     324           0 :     if (*reverseEndian) swap8_unaligned(DELTA, 1);
+     325             :   }
+     326             : 
+     327             :   /* Get the end size of the first block */
+     328           1 :   ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
+     329           1 :   CHECK_FREAD(ret_val, "reading second 84 from dcd file");
+     330           1 :   CHECK_FEOF(ret_val, "reading second 84 from dcd file");
+     331           1 :   if (*reverseEndian) swap4_aligned(input_integer, rec_scale);
+     332             : 
+     333           1 :   if (rec_scale == RECSCALE64BIT) {
+     334           0 :     if ((input_integer[0]+input_integer[1]) != 84) {
+     335             :       return DCD_BADFORMAT;
+     336             :     }
+     337             :   } else {
+     338           1 :     if (input_integer[0] != 84) {
+     339             :       return DCD_BADFORMAT;
+     340             :     }
+     341             :   }
+     342             :   
+     343             :   /* Read in the size of the next block */
+     344           1 :   input_integer[1] = 0;
+     345           1 :   ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
+     346           1 :   CHECK_FREAD(ret_val, "reading size of title block");
+     347           1 :   CHECK_FEOF(ret_val, "reading size of title block");
+     348           1 :   if (*reverseEndian) swap4_aligned(input_integer, rec_scale);
+     349             : 
+     350           1 :   if ((((input_integer[0]+input_integer[1])-4) % 80) == 0) {
+     351             :     /* Read NTITLE, the number of 80 character title strings there are */
+     352           1 :     ret_val = READ(fd, &NTITLE, sizeof(int));
+     353           1 :     CHECK_FREAD(ret_val, "reading NTITLE");
+     354           1 :     CHECK_FEOF(ret_val, "reading NTITLE");
+     355           1 :     if (*reverseEndian) swap4_aligned(&NTITLE, 1);
+     356             : 
+     357           1 :     if (NTITLE < 0) {
+     358             :       printf("dcdplugin) WARNING: Bogus NTITLE value: %d (hex: %08x)\n", 
+     359             :              NTITLE, NTITLE);
+     360           0 :       return DCD_BADFORMAT;
+     361             :     }
+     362             : 
+     363           1 :     if (NTITLE > 1000) {
+     364             :       printf("dcdplugin) WARNING: Bogus NTITLE value: %d (hex: %08x)\n", 
+     365             :              NTITLE, NTITLE);
+     366           0 :       if (NTITLE == 1095062083) {
+     367             :         printf("dcdplugin) WARNING: Broken Vega ZZ 2.4.0 DCD file detected\n");
+     368             :         printf("dcdplugin) Assuming 2 title lines, good luck...\n");
+     369           0 :         NTITLE = 2;
+     370             :       } else {
+     371             :         printf("dcdplugin) Assuming zero title lines, good luck...\n");
+     372           0 :         NTITLE = 0;
+     373             :       }
+     374             :     }
+     375             : 
+     376           3 :     for (i=0; i<NTITLE; i++) {
+     377           2 :       fio_fseek(fd, 80, FIO_SEEK_CUR);
+     378             :       CHECK_FEOF(ret_val, "reading TITLE");
+     379             :     }
+     380             : 
+     381             :     /* Get the ending size for this block */
+     382           1 :     ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
+     383           1 :     CHECK_FREAD(ret_val, "reading size of title block");
+     384           1 :     CHECK_FEOF(ret_val, "reading size of title block");
+     385             :   } else {
+     386             :     return DCD_BADFORMAT;
+     387             :   }
+     388             : 
+     389             :   /* Read in an integer '4' */
+     390           1 :   input_integer[1] = 0;
+     391           1 :   ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
+     392             :   
+     393           1 :   CHECK_FREAD(ret_val, "reading a '4'");
+     394           1 :   CHECK_FEOF(ret_val, "reading a '4'");
+     395           1 :   if (*reverseEndian) swap4_aligned(input_integer, rec_scale);
+     396             : 
+     397           1 :   if ((input_integer[0]+input_integer[1]) != 4) {
+     398             :     return DCD_BADFORMAT;
+     399             :   }
+     400             : 
+     401             :   /* Read in the number of atoms */
+     402           1 :   ret_val = READ(fd, N, sizeof(int));
+     403           1 :   CHECK_FREAD(ret_val, "reading number of atoms");
+     404           1 :   CHECK_FEOF(ret_val, "reading number of atoms");
+     405           1 :   if (*reverseEndian) swap4_aligned(N, 1);
+     406             : 
+     407           1 :   if (*N > (1L<<30)) {
+     408             :     hugefile=1;
+     409             :     printf("dcdplugin) ***\n");
+     410             :     printf("dcdplugin) *** Trajectory contains over 2^30 atoms.\n");
+     411             :     printf("dcdplugin) *** Huge file integer wraparound handling enabled.\n");
+     412             :     printf("dcdplugin) ***\n");
+     413             :   }
+     414             : 
+     415             :   /* Read in an integer '4' */
+     416           1 :   input_integer[1] = 0;
+     417           1 :   ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
+     418           1 :   CHECK_FREAD(ret_val, "reading a '4'");
+     419           1 :   CHECK_FEOF(ret_val, "reading a '4'");
+     420           1 :   if (*reverseEndian) swap4_aligned(input_integer, rec_scale);
+     421             : 
+     422           1 :   if ((input_integer[0]+input_integer[1]) != 4) {
+     423             :     return DCD_BADFORMAT;
+     424             :   }
+     425             : 
+     426           1 :   *FREEINDEXES = NULL;
+     427           1 :   *fixedcoords = NULL;
+     428           1 :   if (*NAMNF != 0) {
+     429           0 :     (*FREEINDEXES) = (int *) calloc((((ptrdiff_t)(*N))-(*NAMNF)), sizeof(int));
+     430           0 :     if (*FREEINDEXES == NULL)
+     431             :       return DCD_BADMALLOC;
+     432             : 
+     433           0 :     *fixedcoords = (float *) calloc(((ptrdiff_t)(*N))*4L - (*NAMNF), sizeof(float));
+     434           0 :     if (*fixedcoords == NULL)
+     435             :       return DCD_BADMALLOC;
+     436             : 
+     437             :     /* Read in index array size */
+     438           0 :     input_integer[1]=0;
+     439           0 :     ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
+     440           0 :     CHECK_FREAD(ret_val, "reading size of index array");
+     441           0 :     CHECK_FEOF(ret_val, "reading size of index array");
+     442           0 :     if (*reverseEndian) swap4_aligned(input_integer, rec_scale);
+     443             : 
+     444             :     /* when we have more then 2^30 atoms, tests like this one */
+     445             :     /* are no longer meaningful and have to be bypassed...    */
+     446           0 :     if (!hugefile && ((input_integer[0]+input_integer[1]) != ((*N)-(*NAMNF))*4L)) {
+     447             :       return DCD_BADFORMAT;
+     448             :     }
+     449             : 
+     450           0 :     ret_val = READ(fd, (*FREEINDEXES), ((ptrdiff_t) ((*N)-(*NAMNF)))*sizeof(int));
+     451           0 :     CHECK_FREAD(ret_val, "reading size of index array");
+     452           0 :     CHECK_FEOF(ret_val, "reading size of index array");
+     453             : 
+     454           0 :     if (*reverseEndian)
+     455           0 :       swap4_aligned((*FREEINDEXES), ((*N)-(*NAMNF)));
+     456             : 
+     457           0 :     input_integer[1]=0;
+     458           0 :     ret_val = READ(fd, input_integer, rec_scale*sizeof(int));
+     459           0 :     CHECK_FREAD(ret_val, "reading size of index array");
+     460           0 :     CHECK_FEOF(ret_val, "reading size of index array");
+     461           0 :     if (*reverseEndian) swap4_aligned(input_integer, rec_scale);
+     462             : 
+     463             :     /* when we have more then 2^30 atoms, tests like this one */
+     464             :     /* are no longer meaningful and have to be bypassed...    */
+     465           0 :     if (!hugefile && ((input_integer[0]+input_integer[1]) != ((*N)-(*NAMNF))*4L)) {
+     466           0 :       return DCD_BADFORMAT;
+     467             :     }
+     468             :   }
+     469             : 
+     470             :   return DCD_SUCCESS;
+     471             : }
+     472             : 
+     473             : 
+     474          21 : static int read_charmm_extrablock(fio_fd fd, int charmm, int reverseEndian,
+     475             :                                   float *unitcell) {
+     476             :   int i, input_integer[2], rec_scale;
+     477             : 
+     478          21 :   if (charmm & DCD_HAS_64BIT_REC) {
+     479             :     rec_scale = RECSCALE64BIT;
+     480             :   } else {
+     481             :     rec_scale = RECSCALE32BIT;
+     482             :   }
+     483             : 
+     484          21 :   if ((charmm & DCD_IS_CHARMM) && (charmm & DCD_HAS_EXTRA_BLOCK)) {
+     485             :     /* Leading integer must be 48 */
+     486          21 :     input_integer[1] = 0;
+     487          21 :     if (fio_fread(input_integer, sizeof(int), rec_scale, fd) != rec_scale)
+     488             :       return DCD_BADREAD; 
+     489          21 :     if (reverseEndian) swap4_aligned(input_integer, rec_scale);
+     490          21 :     if ((input_integer[0]+input_integer[1]) == 48) {
+     491             :       double tmp[6];
+     492          21 :       if (fio_fread(tmp, 48, 1, fd) != 1) return DCD_BADREAD;
+     493          21 :       if (reverseEndian) 
+     494           0 :         swap8_aligned(tmp, 6);
+     495         147 :       for (i=0; i<6; i++) unitcell[i] = (float)tmp[i];
+     496             :     } else {
+     497             :       /* unrecognized block, just skip it */
+     498           0 :       if (fio_fseek(fd, (input_integer[0]+input_integer[1]), FIO_SEEK_CUR)) return DCD_BADREAD;
+     499             :     }
+     500          21 :     if (fio_fread(input_integer, sizeof(int), rec_scale, fd) != rec_scale) return DCD_BADREAD; 
+     501             :   } 
+     502             : 
+     503             :   return DCD_SUCCESS;
+     504             : }
+     505             : 
+     506             : 
+     507           0 : static int read_fixed_atoms(fio_fd fd, int N, int num_free, const int *indexes,
+     508             :                             int reverseEndian, const float *fixedcoords, 
+     509             :                             float *freeatoms, float *pos, int charmm) {
+     510             :   int i, input_integer[2], rec_scale;
+     511             :   
+     512           0 :   if(charmm & DCD_HAS_64BIT_REC) {
+     513             :     rec_scale=RECSCALE64BIT;
+     514             :   } else {
+     515             :     rec_scale=RECSCALE32BIT;
+     516             :   }
+     517             :   
+     518             :   /* Read leading integer */
+     519           0 :   input_integer[1]=0;
+     520           0 :   if (fio_fread(input_integer, sizeof(int), rec_scale, fd) != rec_scale) return DCD_BADREAD;
+     521           0 :   if (reverseEndian) swap4_aligned(input_integer, rec_scale);
+     522           0 :   if ((input_integer[0]+input_integer[1]) != 4L*num_free) return DCD_BADFORMAT;
+     523             :   
+     524             :   /* Read free atom coordinates */
+     525           0 :   if (fio_fread(freeatoms, 4L*num_free, 1, fd) != 1) return DCD_BADREAD;
+     526           0 :   if (reverseEndian)
+     527           0 :     swap4_aligned(freeatoms, num_free);
+     528             : 
+     529             :   /* Copy fixed and free atom coordinates into position buffer */
+     530           0 :   memcpy(pos, fixedcoords, 4L*N);
+     531           0 :   for (i=0; i<num_free; i++)
+     532           0 :     pos[indexes[i]-1] = freeatoms[i];
+     533             : 
+     534             :   /* Read trailing integer */ 
+     535           0 :   input_integer[1]=0;
+     536           0 :   if (fio_fread(input_integer, sizeof(int), rec_scale, fd) != rec_scale) return DCD_BADREAD;
+     537           0 :   if (reverseEndian) swap4_aligned(input_integer, rec_scale);
+     538           0 :   if ((input_integer[0]+input_integer[1]) != 4L*num_free) return DCD_BADFORMAT;
+     539             : 
+     540             :   return DCD_SUCCESS;
+     541             : }
+     542             :  
+     543             :  
+     544          21 : static int read_charmm_4dim(fio_fd fd, int charmm, int reverseEndian) {
+     545             :   int input_integer[2], rec_scale;
+     546             : 
+     547          21 :   if (charmm & DCD_HAS_64BIT_REC) {
+     548             :     rec_scale=RECSCALE64BIT;
+     549             :   } else {
+     550             :     rec_scale=RECSCALE32BIT;
+     551             :   }
+     552             :     
+     553             :   /* If this is a CHARMm file and contains a 4th dimension block, */
+     554             :   /* we must skip past it to avoid problems                       */
+     555          21 :   if ((charmm & DCD_IS_CHARMM) && (charmm & DCD_HAS_4DIMS)) {
+     556           0 :     input_integer[1]=0;
+     557           0 :     if (fio_fread(input_integer, sizeof(int), rec_scale, fd) != rec_scale) return DCD_BADREAD;  
+     558           0 :     if (reverseEndian) swap4_aligned(input_integer, rec_scale);
+     559           0 :     if (fio_fseek(fd, (input_integer[0]+input_integer[1]), FIO_SEEK_CUR)) return DCD_BADREAD;
+     560           0 :     if (fio_fread(input_integer, sizeof(int), rec_scale, fd) != rec_scale) return DCD_BADREAD;  
+     561             :   }
+     562             : 
+     563             :   return DCD_SUCCESS;
+     564             : }
+     565             : 
+     566             : 
+     567             : /* 
+     568             :  * Read a dcd timestep from a dcd file
+     569             :  * Input: fd - a file struct opened for binary reading, from which the 
+     570             :  *             header information has already been read.
+     571             :  *        natoms, nfixed, first, *freeind, reverse, charmm - the corresponding 
+     572             :  *             items as set by read_dcdheader
+     573             :  *        first - true if this is the first frame we are reading.
+     574             :  *        x, y, z: space for natoms each of floats.
+     575             :  *        unitcell - space for six floats to hold the unit cell data.  
+     576             :  *                   Not set if no unit cell data is present.
+     577             :  * Output: 0 on success, negative error code on failure.
+     578             :  * Side effects: x, y, z contain the coordinates for the timestep read.
+     579             :  *               unitcell holds unit cell data if present.
+     580             :  */
+     581          21 : static int read_dcdstep(fio_fd fd, int N, float *X, float *Y, float *Z, 
+     582             :                         float *unitcell, int num_fixed,
+     583             :                         int first, int *indexes, float *fixedcoords, 
+     584             :                         int reverseEndian, int charmm) {
+     585             :   int ret_val;    /* Return value from read */
+     586             :   ptrdiff_t rec_scale;
+     587          21 :   int hugefile = (N > (1L<<30)) ? 1 : 0;
+     588             :   int check_reclen = 1; /* Enable Fortran record length value safety checks */
+     589             : 
+     590             :   /* Fortran record length checks disabled for huge files or user request */
+     591          21 :   if (hugefile || (getenv("VMDDCDNOCHECKRECLEN") != NULL))
+     592             :     check_reclen = 0;
+     593             :  
+     594          21 :   if (charmm & DCD_HAS_64BIT_REC) {
+     595             :     rec_scale=RECSCALE64BIT;
+     596             :   } else {
+     597             :     rec_scale=RECSCALE32BIT;
+     598             :   }
+     599             :   
+     600          21 :   if ((num_fixed==0) || first) {
+     601             :     /* temp storage for reading formatting info */
+     602             :     /* note: has to be max size we'll ever use  */
+     603             :     int tmpbuf[6L*RECSCALEMAX]; 
+     604             : 
+     605             :     fio_iovec iov[7];   /* I/O vector for fio_readv() call          */
+     606             :     int i;
+     607             : 
+     608             :     /* if there are no fixed atoms or this is the first timestep read */
+     609             :     /* then we read all coordinates normally.                         */
+     610             : 
+     611             :     /* read the charmm periodic cell information */
+     612             :     /* XXX this too should be read together with the other items in a */
+     613             :     /*     single fio_readv() call in order to prevent lots of extra  */
+     614             :     /*     kernel/user context switches.                              */
+     615          21 :     ret_val = read_charmm_extrablock(fd, charmm, reverseEndian, unitcell);
+     616          21 :     if (ret_val) return ret_val;
+     617             : 
+     618             :     /* setup the I/O vector for the call to fio_readv() */
+     619             :     iov[0].iov_base = (fio_caddr_t) &tmpbuf[0]; /* read format integer    */
+     620          21 :     iov[0].iov_len  = rec_scale*sizeof(int);
+     621             : 
+     622             :     iov[1].iov_base = (fio_caddr_t) X;          /* read X coordinates     */
+     623          21 :     iov[1].iov_len  = sizeof(float)*N;
+     624             : 
+     625          21 :     iov[2].iov_base = (fio_caddr_t) &tmpbuf[1*rec_scale]; /* read 2 format integers */
+     626          21 :     iov[2].iov_len  = rec_scale*sizeof(int) * 2L;
+     627             : 
+     628             :     iov[3].iov_base = (fio_caddr_t) Y;          /* read Y coordinates     */
+     629             :     iov[3].iov_len  = sizeof(float)*N;
+     630             : 
+     631          21 :     iov[4].iov_base = (fio_caddr_t) &tmpbuf[3L*rec_scale]; /* read 2 format integers */
+     632             :     iov[4].iov_len  = rec_scale*sizeof(int) * 2L;
+     633             : 
+     634             :     iov[5].iov_base = (fio_caddr_t) Z;          /* read Y coordinates     */
+     635             :     iov[5].iov_len  = sizeof(float)*N;
+     636             : 
+     637          21 :     iov[6].iov_base = (fio_caddr_t) &tmpbuf[5L*rec_scale]; /* read format integer    */
+     638             :     iov[6].iov_len  = rec_scale*sizeof(int);
+     639             : 
+     640             : #if 1
+     641             :     /* Use fall-back code instead of readv():                            */
+     642             :     /*  Some platforms implement readv() as user level code in libc,     */
+     643             :     /*  and due to POSIX atomicity requirements for readv()/writev(),    */
+     644             :     /*  they may copy data to internal temp buffers, which can kill      */
+     645             :     /*  performance, and in cases when doing single I/O ops on large,    */
+     646             :     /*  buffers, e.g. > 2GB, can fail with shorts reads or writes...     */
+     647             :     /*  On such platforms it is best to avoid using readv()/writev()...  */
+     648             :     {
+     649             :       int readcnt = 0;
+     650          21 :       readcnt =  fio_fread(iov[0].iov_base, iov[0].iov_len, 1, fd);
+     651          21 :       readcnt += fio_fread(iov[1].iov_base, iov[1].iov_len, 1, fd);
+     652          21 :       readcnt += fio_fread(iov[2].iov_base, iov[2].iov_len, 1, fd);
+     653          21 :       readcnt += fio_fread(iov[3].iov_base, iov[3].iov_len, 1, fd);
+     654          21 :       readcnt += fio_fread(iov[4].iov_base, iov[4].iov_len, 1, fd);
+     655          21 :       readcnt += fio_fread(iov[5].iov_base, iov[5].iov_len, 1, fd);
+     656          21 :       readcnt += fio_fread(iov[6].iov_base, iov[6].iov_len, 1, fd);
+     657             : 
+     658             :       /* if all records read correctly, then the reads are okay */
+     659          21 :       if (readcnt != 7)
+     660             :         return DCD_BADREAD;
+     661             :     }
+     662             : #else
+     663             :     /* check number of bytes actually read            */
+     664             :     if (fio_readv(fd, &iov[0], 7) != ((fio_size_t) (rec_scale*6L*sizeof(int) + 3L*N*sizeof(float))))
+     665             :       return DCD_BADREAD;
+     666             : #endif
+     667             : 
+     668             :     /* convert endianism if necessary */
+     669          21 :     if (reverseEndian) {
+     670           0 :       swap4_aligned(&tmpbuf[0], rec_scale*6L);
+     671           0 :       swap4_aligned(X, N);
+     672           0 :       swap4_aligned(Y, N);
+     673           0 :       swap4_aligned(Z, N);
+     674             :     }
+     675             : 
+     676             :     /* when we have more then 2^30 atoms, tests like this one */
+     677             :     /* are no longer meaningful and have to be bypassed...    */
+     678          21 :     if (check_reclen) {
+     679             :       /* double-check the fortran format size values for safety */
+     680          21 :       if (rec_scale == 1) {
+     681         147 :         for (i=0; i<6; i++) {
+     682         126 :           if (tmpbuf[i] != sizeof(float)*N) return DCD_BADFORMAT;
+     683             :         }
+     684             :       } else {
+     685           0 :         for (i=0; i<6; i++) {
+     686           0 :           if ((tmpbuf[2L*i]+tmpbuf[2L*i+1L]) != sizeof(float)*N) return DCD_BADFORMAT;
+     687             :         }
+     688             :       }
+     689             :     }
+     690             : 
+     691             :     /* copy fixed atom coordinates into fixedcoords array if this was the */
+     692             :     /* first timestep, to be used from now on.  We just copy all atoms.   */
+     693          21 :     if (num_fixed && first) {
+     694             :       memcpy(fixedcoords, X, N*sizeof(float));
+     695           0 :       memcpy(fixedcoords+N, Y, N*sizeof(float));
+     696           0 :       memcpy(fixedcoords+2L*N, Z, N*sizeof(float));
+     697             :     }
+     698             : 
+     699             :     /* read in the optional charmm 4th array */
+     700             :     /* XXX this too should be read together with the other items in a */
+     701             :     /*     single fio_readv() call in order to prevent lots of extra  */
+     702             :     /*     kernel/user context switches.                              */
+     703          21 :     ret_val = read_charmm_4dim(fd, charmm, reverseEndian);
+     704          21 :     if (ret_val) return ret_val;
+     705             :   } else {
+     706             :     /* if there are fixed atoms, and this isn't the first frame, then we */
+     707             :     /* only read in the non-fixed atoms for all subsequent timesteps.    */
+     708           0 :     ret_val = read_charmm_extrablock(fd, charmm, reverseEndian, unitcell);
+     709           0 :     if (ret_val) return ret_val;
+     710           0 :     ret_val = read_fixed_atoms(fd, N, N-num_fixed, indexes, reverseEndian,
+     711           0 :                                fixedcoords, fixedcoords+3L*N, X, charmm);
+     712           0 :     if (ret_val) return ret_val;
+     713           0 :     ret_val = read_fixed_atoms(fd, N, N-num_fixed, indexes, reverseEndian,
+     714           0 :                                fixedcoords+N, fixedcoords+3L*N, Y, charmm);
+     715           0 :     if (ret_val) return ret_val;
+     716           0 :     ret_val = read_fixed_atoms(fd, N, N-num_fixed, indexes, reverseEndian,
+     717           0 :                                fixedcoords+2*N, fixedcoords+3L*N, Z, charmm);
+     718           0 :     if (ret_val) return ret_val;
+     719           0 :     ret_val = read_charmm_4dim(fd, charmm, reverseEndian);
+     720           0 :     if (ret_val) return ret_val;
+     721             :   }
+     722             : 
+     723             :   return DCD_SUCCESS;
+     724             : }
+     725             : 
+     726             : 
+     727             : /* 
+     728             :  * Skip past a timestep.  If there are fixed atoms, this cannot be used with
+     729             :  * the first timestep.  
+     730             :  * Input: fd - a file struct from which the header has already been read
+     731             :  *        natoms - number of atoms per timestep
+     732             :  *        nfixed - number of fixed atoms
+     733             :  *        charmm - charmm flags as returned by read_dcdheader
+     734             :  * Output: 0 on success, negative error code on failure.
+     735             :  * Side effects: One timestep will be skipped; fd will be positioned at the
+     736             :  *               next timestep.
+     737             :  */
+     738           0 : static int skip_dcdstep(fio_fd fd, int natoms, int nfixed, int charmm) {
+     739             :   ptrdiff_t seekoffset = 0;
+     740             :   ptrdiff_t rec_scale;
+     741             : 
+     742           0 :   if (charmm & DCD_HAS_64BIT_REC) {
+     743             :     rec_scale=RECSCALE64BIT;
+     744             :   } else {
+     745             :     rec_scale=RECSCALE32BIT;
+     746             :   }
+     747             : 
+     748             :   /* Skip charmm extra block */
+     749           0 :   if ((charmm & DCD_IS_CHARMM) && (charmm & DCD_HAS_EXTRA_BLOCK)) {
+     750           0 :     seekoffset += 4L*rec_scale + 48L + 4L*rec_scale;
+     751             :   }
+     752             : 
+     753             :   /* For each atom set, seek past an int, the free atoms, and another int. */
+     754           0 :   seekoffset += 3L * (2L*rec_scale + natoms - nfixed) * 4L;
+     755             : 
+     756             :   /* Assume that charmm 4th dim is the same size as the other three. */
+     757           0 :   if ((charmm & DCD_IS_CHARMM) && (charmm & DCD_HAS_4DIMS)) {
+     758           0 :     seekoffset += (2L*rec_scale + natoms - nfixed) * 4L;
+     759             :   }
+     760             :  
+     761           0 :   if (fio_fseek(fd, seekoffset, FIO_SEEK_CUR)) return DCD_BADEOF;
+     762             : 
+     763             :   return DCD_SUCCESS;
+     764             : }
+     765             : 
+     766             : 
+     767             : /* 
+     768             :  * Write a timestep to a dcd file
+     769             :  * Input: fd - a file struct for which a dcd header has already been written
+     770             :  *       curframe: Count of frames written to this file, starting with 1.
+     771             :  *        curstep: Count of timesteps elapsed = istart + curframe * nsavc.
+     772             :  *         natoms: number of elements in x, y, z arrays
+     773             :  *        x, y, z: pointers to atom coordinates
+     774             :  * Output: 0 on success, negative error code on failure.
+     775             :  * Side effects: coordinates are written to the dcd file.
+     776             :  */
+     777           0 : static int write_dcdstep(fio_fd fd, int curframe, int curstep, int N, 
+     778             :                   const float *X, const float *Y, const float *Z, 
+     779             :                   const double *unitcell, int charmm) {
+     780             :   int out_integer;
+     781             : 
+     782           0 :   if (charmm) {
+     783             :     /* write out optional unit cell */
+     784           0 :     if (unitcell != NULL) {
+     785             :       out_integer = 48; /* 48 bytes (6 floats) */
+     786           0 :       fio_write_int32(fd, out_integer);
+     787           0 :       WRITE(fd, unitcell, out_integer);
+     788           0 :       fio_write_int32(fd, out_integer);
+     789             :     }
+     790             :   }
+     791             : 
+     792             :   /* write out coordinates */
+     793           0 :   out_integer = N*4; /* N*4 bytes per X/Y/Z array (N floats per array) */
+     794           0 :   fio_write_int32(fd, out_integer);
+     795           0 :   if (fio_fwrite((void *) X, out_integer, 1, fd) != 1) return DCD_BADWRITE;
+     796           0 :   fio_write_int32(fd, out_integer);
+     797           0 :   fio_write_int32(fd, out_integer);
+     798           0 :   if (fio_fwrite((void *) Y, out_integer, 1, fd) != 1) return DCD_BADWRITE;
+     799           0 :   fio_write_int32(fd, out_integer);
+     800           0 :   fio_write_int32(fd, out_integer);
+     801           0 :   if (fio_fwrite((void *) Z, out_integer, 1, fd) != 1) return DCD_BADWRITE;
+     802           0 :   fio_write_int32(fd, out_integer);
+     803             : 
+     804             :   /* update the DCD header information */
+     805           0 :   fio_fseek(fd, NFILE_POS, FIO_SEEK_SET);
+     806           0 :   fio_write_int32(fd, curframe);
+     807           0 :   fio_fseek(fd, NSTEP_POS, FIO_SEEK_SET);
+     808           0 :   fio_write_int32(fd, curstep);
+     809           0 :   fio_fseek(fd, 0, FIO_SEEK_END);
+     810             : 
+     811           0 :   return DCD_SUCCESS;
+     812             : }
+     813             : 
+     814             : 
+     815             : /*
+     816             :  * Write a header for a new dcd file
+     817             :  * Input: fd - file struct opened for binary writing
+     818             :  *        remarks - string to be put in the remarks section of the header.  
+     819             :  *                  The string will be truncated to 70 characters.
+     820             :  *        natoms, istart, nsavc, delta - see comments in read_dcdheader
+     821             :  * Output: 0 on success, negative error code on failure.
+     822             :  * Side effects: Header information is written to the dcd file.
+     823             :  */
+     824           0 : static int write_dcdheader(fio_fd fd, const char *remarks, int N, 
+     825             :                     int ISTART, int NSAVC, double DELTA, int with_unitcell,
+     826             :                     int charmm) {
+     827             :   int out_integer;
+     828             :   float out_float;
+     829             :   char title_string[200];
+     830             :   time_t cur_time;
+     831             :   struct tm *tmbuf;
+     832             :   char time_str[81];
+     833             : 
+     834           0 :   out_integer = 84;
+     835           0 :   WRITE(fd, (char *) & out_integer, sizeof(int));
+     836             :   strcpy(title_string, "CORD");
+     837           0 :   WRITE(fd, title_string, 4);
+     838           0 :   fio_write_int32(fd, 0);      /* Number of frames in file, none written yet   */
+     839           0 :   fio_write_int32(fd, ISTART); /* Starting timestep                            */
+     840           0 :   fio_write_int32(fd, NSAVC);  /* Timesteps between frames written to the file */
+     841           0 :   fio_write_int32(fd, 0);      /* Number of timesteps in simulation            */
+     842           0 :   fio_write_int32(fd, 0);      /* NAMD writes NSTEP or ISTART - NSAVC here?    */
+     843           0 :   fio_write_int32(fd, 0);
+     844           0 :   fio_write_int32(fd, 0);
+     845           0 :   fio_write_int32(fd, 0);
+     846           0 :   fio_write_int32(fd, 0);
+     847           0 :   if (charmm) {
+     848           0 :     out_float = DELTA;
+     849           0 :     WRITE(fd, (char *) &out_float, sizeof(float));
+     850           0 :     if (with_unitcell) {
+     851           0 :       fio_write_int32(fd, 1);
+     852             :     } else {
+     853           0 :       fio_write_int32(fd, 0);
+     854             :     }
+     855             :   } else {
+     856           0 :     WRITE(fd, (char *) &DELTA, sizeof(double));
+     857             :   }
+     858           0 :   fio_write_int32(fd, 0);
+     859           0 :   fio_write_int32(fd, 0);
+     860           0 :   fio_write_int32(fd, 0);
+     861           0 :   fio_write_int32(fd, 0);
+     862           0 :   fio_write_int32(fd, 0);
+     863           0 :   fio_write_int32(fd, 0);
+     864           0 :   fio_write_int32(fd, 0);
+     865           0 :   fio_write_int32(fd, 0);
+     866           0 :   if (charmm) {
+     867           0 :     fio_write_int32(fd, 24); /* Pretend to be CHARMM version 24 */
+     868             :   } else {
+     869           0 :     fio_write_int32(fd, 0);
+     870             :   }
+     871           0 :   fio_write_int32(fd, 84);
+     872           0 :   fio_write_int32(fd, 164);
+     873           0 :   fio_write_int32(fd, 2);
+     874             : 
+     875             :   strncpy(title_string, remarks, 80);
+     876           0 :   title_string[79] = '\0';
+     877           0 :   WRITE(fd, title_string, 80);
+     878             : 
+     879           0 :   cur_time=time(NULL);
+     880           0 :   tmbuf=localtime(&cur_time);
+     881           0 :   strftime(time_str, 80, "REMARKS Created %d %B, %Y at %R", tmbuf);
+     882           0 :   WRITE(fd, time_str, 80);
+     883             : 
+     884           0 :   fio_write_int32(fd, 164);
+     885           0 :   fio_write_int32(fd, 4);
+     886           0 :   fio_write_int32(fd, N);
+     887           0 :   fio_write_int32(fd, 4);
+     888             : 
+     889           0 :   return DCD_SUCCESS;
+     890             : }
+     891             : 
+     892             : 
+     893             : /*
+     894             :  * clean up dcd data
+     895             :  * Input: nfixed, freeind - elements as returned by read_dcdheader
+     896             :  * Output: None
+     897             :  * Side effects: Space pointed to by freeind is freed if necessary.
+     898             :  */
+     899           1 : static void close_dcd_read(int *indexes, float *fixedcoords) {
+     900           1 :   free(indexes);
+     901           1 :   free(fixedcoords);
+     902           1 : }
+     903             : 
+     904             : 
+     905           1 : static void *open_dcd_read(const char *path, const char *filetype, 
+     906             :     int *natoms) {
+     907             :   dcdhandle *dcd;
+     908             :   fio_fd fd;
+     909             :   int rc;
+     910             :   struct stat stbuf;
+     911             : 
+     912           1 :   if (!path) return NULL;
+     913             : 
+     914             : #if !(defined(_MSC_VER) && defined(FASTIO_NATIVEWIN32))
+     915             :   /* See if the file exists, and get its size */
+     916             :   memset(&stbuf, 0, sizeof(struct stat));
+     917           1 :   if (stat(path, &stbuf)) {
+     918             :     printf("dcdplugin) Could not access file '%s'.\n", path);
+     919           0 :     return NULL;
+     920             :   }
+     921             : #endif
+     922             : 
+     923           1 :   if (fio_open(path, FIO_READ, &fd) < 0) {
+     924             :     printf("dcdplugin) Could not open file '%s' for reading.\n", path);
+     925           0 :     return NULL;
+     926             :   }
+     927             : 
+     928           1 :   dcd = (dcdhandle *)malloc(sizeof(dcdhandle));
+     929             :   memset(dcd, 0, sizeof(dcdhandle));
+     930           1 :   dcd->fd = fd;
+     931             : 
+     932           1 :   if ((rc = read_dcdheader(dcd->fd, &dcd->natoms, &dcd->nsets, &dcd->istart, 
+     933             :          &dcd->nsavc, &dcd->delta, &dcd->nfixed, &dcd->freeind, 
+     934             :          &dcd->fixedcoords, &dcd->reverse, &dcd->charmm))) {
+     935           0 :     print_dcderror("read_dcdheader", rc);
+     936           0 :     fio_fclose(dcd->fd);
+     937           0 :     free(dcd);
+     938           0 :     return NULL;
+     939             :   }
+     940             : 
+     941             :   /*
+     942             :    * Check that the file is big enough to really hold the number of sets
+     943             :    * it claims to have.  Then we'll use nsets to keep track of where EOF
+     944             :    * should be.
+     945             :    */
+     946             :   {
+     947             :     fio_size_t ndims, firstframesize, framesize, extrablocksize;
+     948             :     fio_size_t trjsize, filesize, curpos;
+     949             :     int newnsets;
+     950             : 
+     951           1 :     extrablocksize = dcd->charmm & DCD_HAS_EXTRA_BLOCK ? 48 + 8 : 0;
+     952           1 :     ndims = dcd->charmm & DCD_HAS_4DIMS ? 4 : 3;
+     953           1 :     firstframesize = (dcd->natoms+2) * ndims * sizeof(float) + extrablocksize;
+     954           1 :     framesize = (dcd->natoms-dcd->nfixed+2) * ndims * sizeof(float) 
+     955           1 :       + extrablocksize;
+     956             : 
+     957             :     /* 
+     958             :      * It's safe to use ftell, even though ftell returns a long, because the 
+     959             :      * header size is < 4GB.
+     960             :      */
+     961             : 
+     962           1 :     curpos = fio_ftell(dcd->fd); /* save current offset (end of header) */
+     963             : 
+     964             : #if defined(_MSC_VER) && defined(FASTIO_NATIVEWIN32)
+     965             :     /* the stat() call is not 64-bit savvy on Windows             */
+     966             :     /* so we have to use the fastio fseek/ftell routines for this */
+     967             :     /* until we add a portable filesize routine for this purpose  */
+     968             :     fio_fseek(dcd->fd, 0, FIO_SEEK_END);       /* seek to end of file */
+     969             :     filesize = fio_ftell(dcd->fd);
+     970             :     fio_fseek(dcd->fd, curpos, FIO_SEEK_SET);  /* return to end of header */
+     971             : #else
+     972           1 :     filesize = stbuf.st_size; /* this works ok on Unix machines */
+     973             : #endif
+     974           1 :     trjsize = filesize - curpos - firstframesize;
+     975           1 :     if (trjsize < 0) {
+     976             :       printf("dcdplugin) file '%s' appears to contain no timesteps.\n", path);
+     977           0 :       fio_fclose(dcd->fd);
+     978           0 :       free(dcd);
+     979           0 :       return NULL;
+     980             :     }
+     981             : 
+     982           1 :     newnsets = trjsize / framesize + 1;
+     983             : 
+     984           1 :     if (dcd->nsets > 0 && newnsets != dcd->nsets) {
+     985             :       printf("dcdplugin) Warning: DCD header claims %d frames, but \n"
+     986             :              "dcdplugin) file size (%ld) indicates there are actually \n"
+     987             :              "%d frames of size (%ld)\n", 
+     988             :              dcd->nsets, trjsize, newnsets, framesize);
+     989             :     }
+     990             : 
+     991           1 :     dcd->nsets = newnsets; 
+     992           1 :     dcd->setsread = 0;
+     993             :   }
+     994             : 
+     995           1 :   dcd->first = 1;
+     996           1 :   dcd->x = (float *)malloc(dcd->natoms * sizeof(float));
+     997           1 :   dcd->y = (float *)malloc(dcd->natoms * sizeof(float));
+     998           1 :   dcd->z = (float *)malloc(dcd->natoms * sizeof(float));
+     999           1 :   if (!dcd->x || !dcd->y || !dcd->z) {
+    1000             :     printf("dcdplugin) Unable to allocate space for %d atoms.\n", dcd->natoms);
+    1001           0 :     if (dcd->x)
+    1002           0 :       free(dcd->x);
+    1003           0 :     if (dcd->y)
+    1004           0 :       free(dcd->y);
+    1005           0 :     if (dcd->z)
+    1006           0 :       free(dcd->z);
+    1007           0 :     fio_fclose(dcd->fd);
+    1008           0 :     free(dcd);
+    1009           0 :     return NULL;
+    1010             :   }
+    1011           1 :   *natoms = dcd->natoms;
+    1012           1 :   return dcd;
+    1013             : }
+    1014             : 
+    1015             : 
+    1016          22 : static int read_next_timestep(void *v, int natoms, molfile_timestep_t *ts) {
+    1017             :   dcdhandle *dcd;
+    1018             :   int i, j, rc;
+    1019             :   float unitcell[6];
+    1020          22 :   unitcell[0] = unitcell[2] = unitcell[5] = 0.0f;
+    1021          22 :   unitcell[1] = unitcell[3] = unitcell[4] = 90.0f;
+    1022             :   dcd = (dcdhandle *)v;
+    1023             : 
+    1024             :   /* Check for EOF here; that way all EOF's encountered later must be errors */
+    1025          22 :   if (dcd->setsread == dcd->nsets) return MOLFILE_EOF;
+    1026          21 :   dcd->setsread++;
+    1027          21 :   if (!ts) {
+    1028           0 :     if (dcd->first && dcd->nfixed) {
+    1029             :       /* We can't just skip it because we need the fixed atom coordinates */
+    1030           0 :       rc = read_dcdstep(dcd->fd, dcd->natoms, dcd->x, dcd->y, dcd->z, 
+    1031             :           unitcell, dcd->nfixed, dcd->first, dcd->freeind, dcd->fixedcoords, 
+    1032             :              dcd->reverse, dcd->charmm);
+    1033           0 :       dcd->first = 0;
+    1034           0 :       return rc; /* XXX this needs to be updated */
+    1035             :     }
+    1036           0 :     dcd->first = 0;
+    1037             :     /* XXX this needs to be changed */
+    1038           0 :     return skip_dcdstep(dcd->fd, dcd->natoms, dcd->nfixed, dcd->charmm);
+    1039             :   }
+    1040          21 :   rc = read_dcdstep(dcd->fd, dcd->natoms, dcd->x, dcd->y, dcd->z, unitcell,
+    1041             :              dcd->nfixed, dcd->first, dcd->freeind, dcd->fixedcoords, 
+    1042             :              dcd->reverse, dcd->charmm);
+    1043          21 :   dcd->first = 0;
+    1044          21 :   if (rc < 0) {  
+    1045           0 :     print_dcderror("read_dcdstep", rc);
+    1046           0 :     return MOLFILE_ERROR;
+    1047             :   }
+    1048             : 
+    1049             :   /* copy timestep data from plugin-local buffers to VMD's buffer */
+    1050             :   /* XXX 
+    1051             :    *   This code is still the root of all evil.  Just doing this extra copy
+    1052             :    *   cuts the I/O rate of the DCD reader from 728 MB/sec down to
+    1053             :    *   394 MB/sec when reading from a ram filesystem.  
+    1054             :    *   For a physical disk filesystem, the I/O rate goes from 
+    1055             :    *   187 MB/sec down to 122 MB/sec.  Clearly this extra copy has to go.
+    1056             :    */
+    1057             :   {
+    1058          21 :     int natoms = dcd->natoms;
+    1059          21 :     float *nts = ts->coords;
+    1060          21 :     const float *bufx = dcd->x;
+    1061          21 :     const float *bufy = dcd->y;
+    1062          21 :     const float *bufz = dcd->z;
+    1063             : 
+    1064         483 :     for (i=0, j=0; i<natoms; i++, j+=3) {
+    1065         462 :       nts[j    ] = bufx[i];
+    1066         462 :       nts[j + 1] = bufy[i];
+    1067         462 :       nts[j + 2] = bufz[i];
+    1068             :     }
+    1069             :   }
+    1070             : 
+    1071          21 :   ts->A = unitcell[0];
+    1072          21 :   ts->B = unitcell[2];
+    1073          21 :   ts->C = unitcell[5];
+    1074             : 
+    1075          21 :   if (unitcell[1] >= -1.0 && unitcell[1] <= 1.0 &&
+    1076          21 :       unitcell[3] >= -1.0 && unitcell[3] <= 1.0 &&
+    1077          21 :       unitcell[4] >= -1.0 && unitcell[4] <= 1.0) {
+    1078             :     /* This file was generated by CHARMM, or by NAMD > 2.5, with the angle */
+    1079             :     /* cosines of the periodic cell angles written to the DCD file.        */ 
+    1080             :     /* This formulation improves rounding behavior for orthogonal cells    */
+    1081             :     /* so that the angles end up at precisely 90 degrees, unlike acos().   */
+    1082          21 :     ts->alpha = 90.0 - asin(unitcell[4]) * 90.0 / M_PI_2; /* cosBC */
+    1083          21 :     ts->beta  = 90.0 - asin(unitcell[3]) * 90.0 / M_PI_2; /* cosAC */
+    1084          21 :     ts->gamma = 90.0 - asin(unitcell[1]) * 90.0 / M_PI_2; /* cosAB */
+    1085             :   } else {
+    1086             :     /* This file was likely generated by NAMD 2.5 and the periodic cell    */
+    1087             :     /* angles are specified in degrees rather than angle cosines.          */
+    1088           0 :     ts->alpha = unitcell[4]; /* angle between B and C */
+    1089           0 :     ts->beta  = unitcell[3]; /* angle between A and C */
+    1090           0 :     ts->gamma = unitcell[1]; /* angle between A and B */
+    1091             :   }
+    1092             :  
+    1093             :   return MOLFILE_SUCCESS;
+    1094             : }
+    1095             :  
+    1096             : 
+    1097           1 : static void close_file_read(void *v) {
+    1098             :   dcdhandle *dcd = (dcdhandle *)v;
+    1099           1 :   close_dcd_read(dcd->freeind, dcd->fixedcoords);
+    1100           1 :   fio_fclose(dcd->fd);
+    1101           1 :   free(dcd->x);
+    1102           1 :   free(dcd->y);
+    1103           1 :   free(dcd->z);
+    1104           1 :   free(dcd); 
+    1105           1 : }
+    1106             : 
+    1107             : 
+    1108           0 : static void *open_dcd_write(const char *path, const char *filetype, 
+    1109             :     int natoms) {
+    1110             :   dcdhandle *dcd;
+    1111             :   fio_fd fd;
+    1112             :   int rc;
+    1113             :   int istart, nsavc;
+    1114             :   double delta;
+    1115             :   int with_unitcell;
+    1116             :   int charmm;
+    1117             : 
+    1118           0 :   if (fio_open(path, FIO_WRITE, &fd) < 0) {
+    1119             :     printf("dcdplugin) Could not open file '%s' for writing\n", path);
+    1120           0 :     return NULL;
+    1121             :   }
+    1122             : 
+    1123           0 :   dcd = (dcdhandle *)malloc(sizeof(dcdhandle));
+    1124             :   memset(dcd, 0, sizeof(dcdhandle));
+    1125           0 :   dcd->fd = fd;
+    1126             : 
+    1127             :   istart = 0;             /* starting timestep of DCD file                  */
+    1128             :   nsavc = 1;              /* number of timesteps between written DCD frames */
+    1129             :   delta = 1.0;            /* length of a timestep                           */
+    1130             : 
+    1131           0 :   if (getenv("VMDDCDWRITEXPLORFORMAT") != NULL) {
+    1132             :     with_unitcell = 0;      /* no unit cell info */
+    1133             :     charmm = DCD_IS_XPLOR;  /* X-PLOR format */
+    1134             :     printf("dcdplugin) WARNING: Writing DCD file in X-PLOR format, \n");
+    1135             :     printf("dcdplugin) WARNING: unit cell information will be lost!\n");
+    1136             :   } else {
+    1137             :     with_unitcell = 1;      /* contains unit cell infor (Charmm format) */
+    1138             :     charmm = DCD_IS_CHARMM; /* charmm-formatted DCD file                */ 
+    1139             :     if (with_unitcell) 
+    1140             :       charmm |= DCD_HAS_EXTRA_BLOCK;
+    1141             :   }
+    1142             :  
+    1143           0 :   rc = write_dcdheader(dcd->fd, "Created by DCD plugin", natoms, 
+    1144             :                        istart, nsavc, delta, with_unitcell, charmm);
+    1145             : 
+    1146           0 :   if (rc < 0) {
+    1147           0 :     print_dcderror("write_dcdheader", rc);
+    1148           0 :     fio_fclose(dcd->fd);
+    1149           0 :     free(dcd);
+    1150           0 :     return NULL;
+    1151             :   }
+    1152             : 
+    1153           0 :   dcd->natoms = natoms;
+    1154           0 :   dcd->nsets = 0;
+    1155           0 :   dcd->istart = istart;
+    1156           0 :   dcd->nsavc = nsavc;
+    1157           0 :   dcd->with_unitcell = with_unitcell;
+    1158           0 :   dcd->charmm = charmm;
+    1159           0 :   dcd->x = (float *)malloc(natoms * sizeof(float));
+    1160           0 :   dcd->y = (float *)malloc(natoms * sizeof(float));
+    1161           0 :   dcd->z = (float *)malloc(natoms * sizeof(float));
+    1162           0 :   return dcd;
+    1163             : }
+    1164             : 
+    1165             : 
+    1166           0 : static int write_timestep(void *v, const molfile_timestep_t *ts) { 
+    1167             :   dcdhandle *dcd = (dcdhandle *)v;
+    1168             :   int i, rc, curstep;
+    1169           0 :   float *pos = ts->coords;
+    1170             :   double unitcell[6];
+    1171           0 :   unitcell[0] = unitcell[2] = unitcell[5] = 0.0f;
+    1172           0 :   unitcell[1] = unitcell[3] = unitcell[4] = 90.0f;
+    1173             : 
+    1174             :   /* copy atom coords into separate X/Y/Z arrays for writing */
+    1175           0 :   for (i=0; i<dcd->natoms; i++) {
+    1176           0 :     dcd->x[i] = *(pos++); 
+    1177           0 :     dcd->y[i] = *(pos++); 
+    1178           0 :     dcd->z[i] = *(pos++); 
+    1179             :   }
+    1180           0 :   dcd->nsets++;
+    1181           0 :   curstep = dcd->istart + dcd->nsets * dcd->nsavc;
+    1182             : 
+    1183           0 :   unitcell[0] = ts->A;
+    1184           0 :   unitcell[2] = ts->B;
+    1185           0 :   unitcell[5] = ts->C;
+    1186           0 :   unitcell[1] = sin((M_PI_2 / 90.0) * (90.0 - ts->gamma)); /* cosAB */
+    1187           0 :   unitcell[3] = sin((M_PI_2 / 90.0) * (90.0 - ts->beta));  /* cosAC */
+    1188           0 :   unitcell[4] = sin((M_PI_2 / 90.0) * (90.0 - ts->alpha)); /* cosBC */
+    1189             : 
+    1190           0 :   rc = write_dcdstep(dcd->fd, dcd->nsets, curstep, dcd->natoms, 
+    1191           0 :                      dcd->x, dcd->y, dcd->z,
+    1192           0 :                      dcd->with_unitcell ? unitcell : NULL,
+    1193             :                      dcd->charmm);
+    1194           0 :   if (rc < 0) {
+    1195           0 :     print_dcderror("write_dcdstep", rc);
+    1196           0 :     return MOLFILE_ERROR;
+    1197             :   }
+    1198             : 
+    1199             :   return MOLFILE_SUCCESS;
+    1200             : }
+    1201             : 
+    1202           0 : static void close_file_write(void *v) {
+    1203             :   dcdhandle *dcd = (dcdhandle *)v;
+    1204           0 :   fio_fclose(dcd->fd);
+    1205           0 :   free(dcd->x);
+    1206           0 :   free(dcd->y);
+    1207           0 :   free(dcd->z);
+    1208           0 :   free(dcd);
+    1209           0 : }
+    1210             : 
+    1211             : 
+    1212             : /*
+    1213             :  * Initialization stuff here
+    1214             :  */
+    1215             : static molfile_plugin_t plugin;
+    1216             : 
+    1217        8374 : VMDPLUGIN_API int VMDPLUGIN_init() {
+    1218             :   memset(&plugin, 0, sizeof(molfile_plugin_t));
+    1219        8374 :   plugin.abiversion = vmdplugin_ABIVERSION;
+    1220        8374 :   plugin.type = MOLFILE_PLUGIN_TYPE;
+    1221        8374 :   plugin.name = "dcd";
+    1222        8374 :   plugin.prettyname = "CHARMM,NAMD,XPLOR DCD Trajectory";
+    1223        8374 :   plugin.author = "Axel Kohlmeyer, Justin Gullingsrud, John Stone";
+    1224        8374 :   plugin.majorv = 1;
+    1225        8374 :   plugin.minorv = 18;
+    1226        8374 :   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
+    1227        8374 :   plugin.filename_extension = "dcd";
+    1228        8374 :   plugin.open_file_read = open_dcd_read;
+    1229        8374 :   plugin.read_next_timestep = read_next_timestep;
+    1230        8374 :   plugin.close_file_read = close_file_read;
+    1231        8374 :   plugin.open_file_write = open_dcd_write;
+    1232        8374 :   plugin.write_timestep = write_timestep;
+    1233        8374 :   plugin.close_file_write = close_file_write;
+    1234        8374 :   return VMDPLUGIN_SUCCESS;
+    1235             : }
+    1236             : 
+    1237        8374 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+    1238        8374 :   (*cb)(v, (vmdplugin_t *)&plugin);
+    1239        8374 :   return VMDPLUGIN_SUCCESS;
+    1240             : }
+    1241             : 
+    1242           0 : VMDPLUGIN_API int VMDPLUGIN_fini() {
+    1243           0 :   return VMDPLUGIN_SUCCESS;
+    1244             : }
+    1245             : 
+    1246             : }
+    1247             : }
+    1248             : 
+    1249             :   
+    1250             : #ifdef TEST_DCDPLUGIN
+    1251             : 
+    1252             : #include <sys/time.h>
+    1253             : 
+    1254             : /* get the time of day from the system clock, and store it (in seconds) */
+    1255             : double time_of_day(void) {
+    1256             : #if defined(_MSC_VER)
+    1257             :   double t;
+    1258             : 
+    1259             :   t = GetTickCount();
+    1260             :   t = t / 1000.0;
+    1261             : 
+    1262             :   return t;
+    1263             : #else
+    1264             :   struct timeval tm;
+    1265             :   struct timezone tz;
+    1266             : 
+    1267             :   gettimeofday(&tm, &tz);
+    1268             :   return((double)(tm.tv_sec) + (double)(tm.tv_usec)/1000000.0);
+    1269             : #endif
+    1270             : }
+    1271             : 
+    1272             : int main(int argc, char *argv[]) {
+    1273             :   molfile_timestep_t timestep;
+    1274             :   void *v;
+    1275             :   dcdhandle *dcd;
+    1276             :   int i, natoms;
+    1277             :   float sizeMB =0.0, totalMB = 0.0;
+    1278             :   double starttime, endtime, totaltime = 0.0;
+    1279             : 
+    1280             :   while (--argc) {
+    1281             :     ++argv; 
+    1282             :     natoms = 0;
+    1283             :     v = open_dcd_read(*argv, "dcd", &natoms);
+    1284             :     if (!v) {
+    1285             :       fprintf(stderr, "main) open_dcd_read failed for file %s\n", *argv);
+    1286             :       return 1;
+    1287             :     }
+    1288             :     dcd = (dcdhandle *)v;
+    1289             :     sizeMB = ((natoms * 3.0) * dcd->nsets * 4.0) / (1024.0 * 1024.0);
+    1290             :     totalMB += sizeMB; 
+    1291             :     printf("main) file: %s\n", *argv);
+    1292             :     printf("  %d atoms, %d frames, size: %6.1fMB\n", natoms, dcd->nsets, sizeMB);
+    1293             : 
+    1294             :     starttime = time_of_day();
+    1295             :     timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
+    1296             :     for (i=0; i<dcd->nsets; i++) {
+    1297             :       int rc = read_next_timestep(v, natoms, &timestep);
+    1298             :       if (rc) {
+    1299             :         fprintf(stderr, "error in read_next_timestep on frame %d\n", i);
+    1300             :         return 1;
+    1301             :       }
+    1302             :     }
+    1303             :     endtime = time_of_day();
+    1304             :     close_file_read(v);
+    1305             :     totaltime += endtime - starttime;
+    1306             :     printf("  Time: %5.1f seconds\n", endtime - starttime);
+    1307             :     printf("  Speed: %5.1f MB/sec, %5.1f timesteps/sec\n", sizeMB / (endtime - starttime), (dcd->nsets / (endtime - starttime)));
+    1308             :   }
+    1309             :   printf("Overall Size: %6.1f MB\n", totalMB);
+    1310             :   printf("Overall Time: %6.1f seconds\n", totaltime);
+    1311             :   printf("Overall Speed: %5.1f MB/sec\n", totalMB / totaltime);
+    1312             :   return 0;
+    1313             : }
+    1314             :       
+    1315             : #endif
+    1316             : 
+    1317             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/endianswap.h.func-sort-c.html b/coverage-libs/molfile/endianswap.h.func-sort-c.html new file mode 100644 index 000000000000..bb8076fac784 --- /dev/null +++ b/coverage-libs/molfile/endianswap.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/endianswap.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - endianswap.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:64812.5 %
Date:2024-02-22 21:58:47Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL13swap8_alignedEPvl0
_ZN4PLMD7molfileL15swap4_unalignedEPvl0
_ZN4PLMD7molfileL15swap8_unalignedEPvl0
_ZN4PLMD7molfileL13swap4_alignedEPvl1461240
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/endianswap.h.func.html b/coverage-libs/molfile/endianswap.h.func.html new file mode 100644 index 000000000000..c780589e7402 --- /dev/null +++ b/coverage-libs/molfile/endianswap.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/endianswap.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - endianswap.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:64812.5 %
Date:2024-02-22 21:58:47Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL13swap4_alignedEPvl1461240
_ZN4PLMD7molfileL13swap8_alignedEPvl0
_ZN4PLMD7molfileL15swap4_unalignedEPvl0
_ZN4PLMD7molfileL15swap8_unalignedEPvl0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/endianswap.h.gcov.html b/coverage-libs/molfile/endianswap.h.gcov.html new file mode 100644 index 000000000000..10b15ee25255 --- /dev/null +++ b/coverage-libs/molfile/endianswap.h.gcov.html @@ -0,0 +1,294 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/endianswap.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - endianswap.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:64812.5 %
Date:2024-02-22 21:58:47Functions:1425.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : University of Illinois Open Source License
+       3             : Copyright 2003 Theoretical and Computational Biophysics Group, 
+       4             : All rights reserved.
+       5             : 
+       6             : Developed by:           Theoretical and Computational Biophysics Group
+       7             :                         University of Illinois at Urbana-Champaign
+       8             :                         http://www.ks.uiuc.edu/
+       9             : 
+      10             : Permission is hereby granted, free of charge, to any person obtaining a copy of
+      11             : this software and associated documentation files (the Software), to deal with 
+      12             : the Software without restriction, including without limitation the rights to 
+      13             : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+      14             : of the Software, and to permit persons to whom the Software is furnished to 
+      15             : do so, subject to the following conditions:
+      16             : 
+      17             : Redistributions of source code must retain the above copyright notice, 
+      18             : this list of conditions and the following disclaimers.
+      19             : 
+      20             : Redistributions in binary form must reproduce the above copyright notice, 
+      21             : this list of conditions and the following disclaimers in the documentation 
+      22             : and/or other materials provided with the distribution.
+      23             : 
+      24             : Neither the names of Theoretical and Computational Biophysics Group, 
+      25             : University of Illinois at Urbana-Champaign, nor the names of its contributors 
+      26             : may be used to endorse or promote products derived from this Software without 
+      27             : specific prior written permission.
+      28             : 
+      29             : THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+      30             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+      31             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
+      32             : THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
+      33             : OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+      34             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
+      35             : OTHER DEALINGS WITH THE SOFTWARE.
+      36             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      37             : #ifndef __PLUMED_molfile_endianswap_h
+      38             : #define __PLUMED_molfile_endianswap_h
+      39             : namespace PLMD{
+      40             : namespace molfile{
+      41             : /***************************************************************************
+      42             :  *cr
+      43             :  *cr            (C) Copyright 1995-2016 The Board of Trustees of the
+      44             :  *cr                        University of Illinois
+      45             :  *cr                         All Rights Reserved
+      46             :  *cr
+      47             :  ***************************************************************************/
+      48             : /***************************************************************************
+      49             :  * RCS INFORMATION:
+      50             :  *
+      51             :  *      $RCSfile: endianswap.h,v $
+      52             :  *      $Author: johns $       $Locker:  $             $State: Exp $
+      53             :  *      $Revision: 1.8 $       $Date: 2020/10/21 18:03:15 $
+      54             :  *
+      55             :  ***************************************************************************
+      56             :  * DESCRIPTION:
+      57             :  *   Byte swapping routines used in various plugins
+      58             :  *   There are two versions of each routine, one that's safe to use in
+      59             :  *   all cases (but is slow) and one that is only safe to use on memory 
+      60             :  *   addresses that are aligned to the word size that's being byte-swapped
+      61             :  *   but are much much much faster.  Use the aligned versions of these
+      62             :  *   routines whenever possible.  The 'ndata' length count parameters and
+      63             :  *   internal loops should be safe to use on huge memory arrays on 64-bit
+      64             :  *   machines.
+      65             :  *
+      66             :  ***************************************************************************/
+      67             : 
+      68             : #ifndef ENDIAN_SWAP_H
+      69             : #define ENDIAN_SWAP_H
+      70             : 
+      71             : #include <stddef.h>
+      72             : 
+      73             : /* works on unaligned 2-byte quantities */
+      74             : static void swap2_unaligned(void *v, ptrdiff_t ndata) {
+      75             :   ptrdiff_t i;
+      76             :   char * dataptr = (char *) v;
+      77             :   char tmp;
+      78             : 
+      79             :   for (i = 0; i < ndata-1; i += 2) {
+      80             :     tmp = dataptr[i];
+      81             :     dataptr[i] = dataptr[i+1];
+      82             :     dataptr[i+1] = tmp;
+      83             :   }
+      84             : }
+      85             : 
+      86             : 
+      87             : /* works on unaligned 4-byte quantities */
+      88           0 : static void swap4_unaligned(void *v, ptrdiff_t ndata) {
+      89             :   ptrdiff_t i;
+      90             :   char *dataptr;
+      91             :   char tmp;
+      92             : 
+      93             :   dataptr = (char *) v; 
+      94           0 :   for (i=0; i<ndata; i++) {
+      95           0 :     tmp = dataptr[0];
+      96           0 :     dataptr[0] = dataptr[3];
+      97           0 :     dataptr[3] = tmp;
+      98           0 :     tmp = dataptr[1];
+      99           0 :     dataptr[1] = dataptr[2];
+     100           0 :     dataptr[2] = tmp;
+     101           0 :     dataptr += 4;
+     102             :   }
+     103           0 : }
+     104             : 
+     105             : 
+     106             : /* works on unaligned 8-byte quantities */
+     107           0 : static void swap8_unaligned(void *v, ptrdiff_t ndata) {
+     108             :   char *data = (char *) v;
+     109             :   ptrdiff_t i;
+     110             :   char byteArray[8];
+     111             :   char *bytePointer;
+     112             : 
+     113           0 :   for (i=0; i<ndata; i++) {
+     114           0 :     bytePointer = data + (i<<3);
+     115           0 :     byteArray[0]  =  *bytePointer;
+     116           0 :     byteArray[1]  =  *(bytePointer+1);
+     117           0 :     byteArray[2]  =  *(bytePointer+2);
+     118           0 :     byteArray[3]  =  *(bytePointer+3);
+     119           0 :     byteArray[4]  =  *(bytePointer+4);
+     120           0 :     byteArray[5]  =  *(bytePointer+5);
+     121           0 :     byteArray[6]  =  *(bytePointer+6);
+     122           0 :     byteArray[7]  =  *(bytePointer+7);
+     123             : 
+     124           0 :     *bytePointer     = byteArray[7];
+     125           0 :     *(bytePointer+1) = byteArray[6];
+     126           0 :     *(bytePointer+2) = byteArray[5];
+     127           0 :     *(bytePointer+3) = byteArray[4];
+     128           0 :     *(bytePointer+4) = byteArray[3];
+     129           0 :     *(bytePointer+5) = byteArray[2];
+     130           0 :     *(bytePointer+6) = byteArray[1];
+     131           0 :     *(bytePointer+7) = byteArray[0];
+     132             :   }
+     133           0 : }
+     134             : 
+     135             : 
+     136             : /* Only works with aligned 2-byte quantities, will cause a bus error */
+     137             : /* on some platforms if used on unaligned data.                      */
+     138             : static void swap2_aligned(void *v, ptrdiff_t ndata) {
+     139             :   short *data = (short *) v;
+     140             :   ptrdiff_t i;
+     141             :   short *N; 
+     142             : 
+     143             :   for (i=0; i<ndata; i++) {
+     144             :     N = data + i;
+     145             :     *N=(((*N>>8)&0xff) | ((*N&0xff)<<8));  
+     146             :   }
+     147             : }
+     148             : 
+     149             : 
+     150             : /* Only works with aligned 4-byte quantities, will cause a bus error */
+     151             : /* on some platforms if used on unaligned data.                      */
+     152     1461240 : static void swap4_aligned(void *v, ptrdiff_t ndata) {
+     153             :   int *data = (int *) v;
+     154             :   ptrdiff_t i;
+     155             :   int *N;
+     156     2922480 :   for (i=0; i<ndata; i++) {
+     157     1461240 :     N = data + i;
+     158     1461240 :     *N=(((*N>>24)&0xff) | ((*N&0xff)<<24) | 
+     159     1461240 :         ((*N>>8)&0xff00) | ((*N&0xff00)<<8));
+     160             :   }
+     161     1461240 : }
+     162             : 
+     163             : 
+     164             : /* Only works with aligned 8-byte quantities, will cause a bus error */
+     165             : /* on some platforms if used on unaligned data.                      */
+     166           0 : static void swap8_aligned(void *v, ptrdiff_t ndata) {
+     167             :   /* Use int* internally to prevent bugs caused by some compilers */
+     168             :   /* and hardware that would potentially load data into an FP reg */
+     169             :   /* and hose everything, such as the old "jmemcpy()" bug in NAMD */
+     170             :   int *data = (int *) v;  
+     171             :   ptrdiff_t i;
+     172             :   int *N; 
+     173             :   int t0, t1;
+     174             : 
+     175           0 :   for (i=0; i<ndata; i++) {
+     176           0 :     N = data + (i<<1);
+     177           0 :     t0 = N[0];
+     178           0 :     t0=(((t0>>24)&0xff) | ((t0&0xff)<<24) | 
+     179           0 :         ((t0>>8)&0xff00) | ((t0&0xff00)<<8));
+     180             : 
+     181           0 :     t1 = N[1];
+     182           0 :     t1=(((t1>>24)&0xff) | ((t1&0xff)<<24) | 
+     183           0 :         ((t1>>8)&0xff00) | ((t1&0xff00)<<8));
+     184             : 
+     185           0 :     N[0] = t1; 
+     186           0 :     N[1] = t0; 
+     187             :   }
+     188           0 : }
+     189             : 
+     190             : #if 0
+     191             : /* Other implementations that might be faster in some cases */
+     192             : 
+     193             : /* swaps the endianism of an eight byte word. */
+     194             : void mdio_swap8(double *i) {
+     195             :         char c;
+     196             :         char *n;
+     197             :         n = (char *) i;
+     198             :         c = n[0];
+     199             :         n[0] = n[7];
+     200             :         n[7] = c;
+     201             :         c = n[1];
+     202             :         n[1] = n[6];
+     203             :         n[6] = c;
+     204             :         c = n[2];
+     205             :         n[2] = n[5];
+     206             :         n[5] = c;
+     207             :         c = n[3];
+     208             :         n[3] = n[4];
+     209             :         n[4] = c;
+     210             : }
+     211             : 
+     212             : #endif
+     213             : 
+     214             : #endif
+     215             : }
+     216             : }
+     217             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/fastio.h.func-sort-c.html b/coverage-libs/molfile/fastio.h.func-sort-c.html new file mode 100644 index 000000000000..0222c47b5dbe --- /dev/null +++ b/coverage-libs/molfile/fastio.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/fastio.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - fastio.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:193455.9 %
Date:2024-02-22 21:58:47Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL10fio_fwriteEPvlli0
_ZN4PLMD7molfileL15fio_write_int32Eii0
_ZN4PLMD7molfileL10fio_fcloseEi1
_ZN4PLMD7molfileL8fio_openEPKciPi1
_ZN4PLMD7molfileL9fio_ftellEi1
_ZN4PLMD7molfileL9fio_fseekEili2
_ZN4PLMD7molfileL9fio_freadEPvlli219
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/fastio.h.func.html b/coverage-libs/molfile/fastio.h.func.html new file mode 100644 index 000000000000..9c1544ee5b24 --- /dev/null +++ b/coverage-libs/molfile/fastio.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/fastio.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - fastio.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:193455.9 %
Date:2024-02-22 21:58:47Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL10fio_fcloseEi1
_ZN4PLMD7molfileL10fio_fwriteEPvlli0
_ZN4PLMD7molfileL15fio_write_int32Eii0
_ZN4PLMD7molfileL8fio_openEPKciPi1
_ZN4PLMD7molfileL9fio_freadEPvlli219
_ZN4PLMD7molfileL9fio_fseekEili2
_ZN4PLMD7molfileL9fio_ftellEi1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/fastio.h.gcov.html b/coverage-libs/molfile/fastio.h.gcov.html new file mode 100644 index 000000000000..ba6179d498f7 --- /dev/null +++ b/coverage-libs/molfile/fastio.h.gcov.html @@ -0,0 +1,760 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/fastio.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - fastio.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:193455.9 %
Date:2024-02-22 21:58:47Functions:5771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : University of Illinois Open Source License
+       3             : Copyright 2003 Theoretical and Computational Biophysics Group, 
+       4             : All rights reserved.
+       5             : 
+       6             : Developed by:           Theoretical and Computational Biophysics Group
+       7             :                         University of Illinois at Urbana-Champaign
+       8             :                         http://www.ks.uiuc.edu/
+       9             : 
+      10             : Permission is hereby granted, free of charge, to any person obtaining a copy of
+      11             : this software and associated documentation files (the Software), to deal with 
+      12             : the Software without restriction, including without limitation the rights to 
+      13             : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+      14             : of the Software, and to permit persons to whom the Software is furnished to 
+      15             : do so, subject to the following conditions:
+      16             : 
+      17             : Redistributions of source code must retain the above copyright notice, 
+      18             : this list of conditions and the following disclaimers.
+      19             : 
+      20             : Redistributions in binary form must reproduce the above copyright notice, 
+      21             : this list of conditions and the following disclaimers in the documentation 
+      22             : and/or other materials provided with the distribution.
+      23             : 
+      24             : Neither the names of Theoretical and Computational Biophysics Group, 
+      25             : University of Illinois at Urbana-Champaign, nor the names of its contributors 
+      26             : may be used to endorse or promote products derived from this Software without 
+      27             : specific prior written permission.
+      28             : 
+      29             : THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+      30             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+      31             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
+      32             : THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
+      33             : OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+      34             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
+      35             : OTHER DEALINGS WITH THE SOFTWARE.
+      36             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      37             : #ifndef __PLUMED_molfile_fastio_h
+      38             : #define __PLUMED_molfile_fastio_h
+      39             : /***************************************************************************
+      40             :  *cr
+      41             :  *cr            (C) Copyright 1995-2016 The Board of Trustees of the
+      42             :  *cr                        University of Illinois
+      43             :  *cr                         All Rights Reserved
+      44             :  *cr
+      45             :  ***************************************************************************/
+      46             : /***************************************************************************
+      47             :  * RCS INFORMATION:
+      48             :  *
+      49             :  *      $RCSfile: fastio.h,v $
+      50             :  *      $Author: johns $       $Locker:  $             $State: Exp $
+      51             :  *      $Revision: 1.34 $       $Date: 2016/11/28 05:01:53 $
+      52             :  *
+      53             :  ***************************************************************************
+      54             :  * DESCRIPTION:
+      55             :  *   This is a simple abstraction layer for system-dependent I/O calls
+      56             :  * that allow plugins to do binary I/O using the fastest possible method.
+      57             :  *
+      58             :  * This code is intended for use by binary trajectory reader plugins that
+      59             :  * work with multi-gigabyte data sets, reading only binary data.
+      60             :  *
+      61             :  ***************************************************************************/
+      62             : 
+      63             : #define FIO_READ    0x01
+      64             : #define FIO_WRITE   0x02
+      65             : #define FIO_DIRECT  0x04 /* emulate Unix O_DIRECT flag */
+      66             :  
+      67             : /* Compiling on windows */
+      68             : #if defined(_MSC_VER) || defined(__MINGW32__)
+      69             : 
+      70             : #if 1 
+      71             : /* use native Windows I/O calls */
+      72             : #define FASTIO_NATIVEWIN32 1
+      73             : 
+      74             : #include <stdio.h>
+      75             : #include <string.h>
+      76             : #include <windows.h>
+      77             : 
+      78             : namespace PLMD{
+      79             : namespace molfile{
+      80             : 
+      81             : typedef HANDLE fio_fd;
+      82             : typedef LONGLONG fio_size_t;
+      83             : typedef void * fio_caddr_t;
+      84             : 
+      85             : typedef struct {
+      86             :   fio_caddr_t iov_base;
+      87             :   int iov_len;
+      88             : } fio_iovec;
+      89             : 
+      90             : 
+      91             : #define FIO_SEEK_CUR  FILE_CURRENT
+      92             : #define FIO_SEEK_SET  FILE_BEGIN
+      93             : #define FIO_SEEK_END  FILE_END
+      94             : 
+      95             : static int fio_win32convertfilename(const char *filename, char *newfilename, int maxlen) {
+      96             :   int i;
+      97             :   int len=strlen(filename);
+      98             :  
+      99             :   if ((len + 1) >= maxlen)
+     100             :     return -1;
+     101             :    
+     102             :   for (i=0; i<len; i++) {
+     103             :     if (filename[i] == '/')
+     104             :       newfilename[i] = '\\';
+     105             :     else
+     106             :       newfilename[i] = filename[i];
+     107             :   }
+     108             :   newfilename[len] = '\0'; /* NUL terminate the string */
+     109             : 
+     110             :   return 0;
+     111             : }
+     112             : 
+     113             : static int fio_open(const char *filename, int mode, fio_fd *fd) {
+     114             :   HANDLE fp;
+     115             :   char winfilename[8192];
+     116             :   DWORD access;
+     117             :   DWORD sharing;
+     118             :   LPSECURITY_ATTRIBUTES security;
+     119             :   DWORD createmode;
+     120             :   DWORD flags;
+     121             : 
+     122             :   if (fio_win32convertfilename(filename, winfilename, sizeof(winfilename)))
+     123             :     return -1;  
+     124             : 
+     125             :   access = 0;
+     126             :   if (mode & FIO_READ)
+     127             :     access |= GENERIC_READ;
+     128             :   if (mode & FIO_WRITE)
+     129             :     access |= GENERIC_WRITE;
+     130             : #if 0
+     131             :   access = FILE_ALL_ACCESS; /* XXX hack if above modes fail */
+     132             : #endif
+     133             : #if 1
+     134             :   if (mode & FIO_DIRECT)
+     135             :     flags = FILE_FLAG_NO_BUFFERING;
+     136             :   else
+     137             :     flags = FILE_ATTRIBUTE_NORMAL;
+     138             : #else
+     139             :   if (mode & FIO_DIRECT)
+     140             :     return -1; /* not supported yet */
+     141             : #endif
+     142             : 
+     143             :   sharing = 0;       /* disallow sharing with other processes  */
+     144             :   security = NULL;   /* child processes don't inherit anything */
+     145             : 
+     146             :   /* since we never append, blow away anything that's already there */
+     147             :   if (mode & FIO_WRITE)
+     148             :     createmode = CREATE_ALWAYS;
+     149             :   else 
+     150             :     createmode = OPEN_EXISTING;
+     151             : 
+     152             :   fp = CreateFile(winfilename, access, sharing, security, 
+     153             :                   createmode, flags, NULL);
+     154             : 
+     155             :   if (fp == NULL) {
+     156             :     return -1;
+     157             :   } else {
+     158             :     *fd = fp;
+     159             :     return 0;
+     160             :   }
+     161             : }
+     162             : 
+     163             : 
+     164             : static int fio_fclose(fio_fd fd) {
+     165             :   BOOL rc;
+     166             :   rc = CloseHandle(fd);
+     167             :   if (rc) 
+     168             :     return 0;
+     169             :   else 
+     170             :     return -1;
+     171             : }
+     172             : 
+     173             : static fio_size_t fio_fread(void *ptr, fio_size_t size, 
+     174             :                             fio_size_t nitems, fio_fd fd) {
+     175             :   BOOL rc;
+     176             :   DWORD len;
+     177             :   DWORD readlen;
+     178             : 
+     179             :   len = size * nitems;
+     180             : 
+     181             :   rc = ReadFile(fd, ptr, len, &readlen, NULL);
+     182             :   if (rc) {
+     183             :     if (readlen == len)
+     184             :       return nitems;
+     185             :     else 
+     186             :       return 0;
+     187             :   } else {
+     188             :     return 0;
+     189             :   }
+     190             : }
+     191             : 
+     192             : static fio_size_t fio_readv(fio_fd fd, const fio_iovec * iov, int iovcnt) {
+     193             :   int i;
+     194             :   fio_size_t len = 0; 
+     195             : 
+     196             :   for (i=0; i<iovcnt; i++) {
+     197             :     fio_size_t rc = fio_fread(iov[i].iov_base, iov[i].iov_len, 1, fd);
+     198             :     if (rc != 1)
+     199             :       break;
+     200             :     len += iov[i].iov_len;
+     201             :   }
+     202             : 
+     203             :   return len;
+     204             : }
+     205             : 
+     206             : static fio_size_t fio_fwrite(void *ptr, fio_size_t size, 
+     207             :                              fio_size_t nitems, fio_fd fd) {
+     208             :   BOOL rc;
+     209             :   DWORD len;
+     210             :   DWORD writelen;
+     211             : 
+     212             :   len = size * nitems; 
+     213             :  
+     214             :   rc = WriteFile(fd, ptr, len, &writelen, NULL);
+     215             :   if (rc) {
+     216             :     if (writelen == len)
+     217             :       return nitems;
+     218             :     else
+     219             :       return 0;
+     220             :   } else {
+     221             :     return 0;
+     222             :   }
+     223             : }
+     224             : 
+     225             : static fio_size_t fio_fseek(fio_fd fd, fio_size_t offset, int whence) {
+     226             : #if 1
+     227             :   /* code that works with older MSVC6 compilers */
+     228             :   LONGLONG finaloffset;
+     229             :   LARGE_INTEGER bigint;
+     230             :   LARGE_INTEGER finalint;
+     231             : 
+     232             :   bigint.QuadPart = offset;
+     233             :   finalint = bigint;      /* set the high part, which will be overwritten */
+     234             :   finalint.LowPart = SetFilePointer(fd, bigint.LowPart, &finalint.HighPart, whence);
+     235             :   if (finalint.LowPart == -1) {
+     236             :     /* if (finalint.LowPart == INVALID_SET_FILE_POINTER) { */
+     237             :     /* INVALID_SET_FILE_POINTER is a possible "ok" low order result when */
+     238             :     /* working with 64-bit offsets, so we have to also check the system  */
+     239             :     /* error value for this thread to be sure */
+     240             :     if (GetLastError() != ERROR_SUCCESS) {
+     241             :       return -1;
+     242             :     }
+     243             :   } 
+     244             : 
+     245             :   finaloffset = finalint.QuadPart;
+     246             :   return 0;
+     247             : #else
+     248             :   BOOL rc;
+     249             :   LONGLONG finaloffset;
+     250             : 
+     251             :   /* SetFilePointerEx() only exists with new .NET compilers */
+     252             :   rc = SetFilePointerEx(fd, offset, &finaloffset, whence);
+     253             : 
+     254             :   if (rc) 
+     255             :     return 0;
+     256             :   else
+     257             :     return -1;
+     258             : #endif
+     259             : }
+     260             : 
+     261             : static fio_size_t fio_ftell(fio_fd fd) {
+     262             :   /* code that works with older MSVC6 compilers */
+     263             :   LONGLONG finaloffset;
+     264             :   LARGE_INTEGER bigint;
+     265             :   LARGE_INTEGER finalint;
+     266             : 
+     267             :   bigint.QuadPart = 0;
+     268             :   finalint = bigint;      /* set the high part, which will be overwritten */
+     269             : 
+     270             :   finalint.LowPart = SetFilePointer(fd, bigint.LowPart, &finalint.HighPart, FILE_CURRENT);
+     271             :   if (finalint.LowPart == -1) {
+     272             :     /* if (finalint.LowPart == INVALID_SET_FILE_POINTER) { */
+     273             :     /* INVALID_SET_FILE_POINTER is a possible "ok" low order result when */
+     274             :     /* working with 64-bit offsets, so we have to also check the system  */
+     275             :     /* error value for this thread to be sure */
+     276             :     if (GetLastError() != ERROR_SUCCESS) {
+     277             :       return -1;
+     278             :     }
+     279             :   }
+     280             : 
+     281             :   finaloffset = finalint.QuadPart;
+     282             : 
+     283             :   return finaloffset;
+     284             : }
+     285             : 
+     286             : 
+     287             : #else
+     288             : 
+     289             : /* Version for machines with plain old ANSI C  */
+     290             : 
+     291             : #include <stdio.h>
+     292             : #include <string.h>
+     293             : 
+     294             : typedef FILE * fio_fd;
+     295             : typedef size_t fio_size_t;  /* MSVC doesn't uinversally support ssize_t */
+     296             : typedef void * fio_caddr_t; /* MSVC doesn't universally support caddr_t */
+     297             : 
+     298             : typedef struct {
+     299             :   fio_caddr_t iov_base;
+     300             :   int iov_len;
+     301             : } fio_iovec;
+     302             : 
+     303             : #define FIO_SEEK_CUR SEEK_CUR
+     304             : #define FIO_SEEK_SET SEEK_SET
+     305             : #define FIO_SEEK_END SEEK_END
+     306             : 
+     307             : static int fio_open(const char *filename, int mode, fio_fd *fd) {
+     308             :   char * modestr;
+     309             :   FILE *fp;
+     310             : 
+     311             :   if (mode & FIO_READ) 
+     312             :     modestr = "rb";
+     313             : 
+     314             :   if (mode & FIO_WRITE) 
+     315             :     modestr = "wb";
+     316             : 
+     317             :   if (mode & FIO_DIRECT)
+     318             :     return -1; /* not supported yet */
+     319             :  
+     320             :   fp = fopen(filename, modestr);
+     321             :   if (fp == NULL) {
+     322             :     return -1;
+     323             :   } else {
+     324             :     *fd = fp;
+     325             :     return 0;
+     326             :   }
+     327             : }
+     328             : 
+     329             : static int fio_fclose(fio_fd fd) {
+     330             :   return fclose(fd);
+     331             : }
+     332             : 
+     333             : static fio_size_t fio_fread(void *ptr, fio_size_t size, 
+     334             :                             fio_size_t nitems, fio_fd fd) {
+     335             :   return fread(ptr, size, nitems, fd);
+     336             : }
+     337             : 
+     338             : static fio_size_t fio_readv(fio_fd fd, const fio_iovec * iov, int iovcnt) {
+     339             :   int i;
+     340             :   fio_size_t len = 0; 
+     341             : 
+     342             :   for (i=0; i<iovcnt; i++) {
+     343             :     fio_size_t rc = fread(iov[i].iov_base, iov[i].iov_len, 1, fd);
+     344             :     if (rc != 1)
+     345             :       break;
+     346             :     len += iov[i].iov_len;
+     347             :   }
+     348             : 
+     349             :   return len;
+     350             : }
+     351             : 
+     352             : static fio_size_t fio_fwrite(void *ptr, fio_size_t size, 
+     353             :                              fio_size_t nitems, fio_fd fd) {
+     354             :   return fwrite(ptr, size, nitems, fd);
+     355             : }
+     356             : 
+     357             : static fio_size_t fio_fseek(fio_fd fd, fio_size_t offset, int whence) {
+     358             :   return fseek(fd, offset, whence);
+     359             : }
+     360             : 
+     361             : static fio_size_t fio_ftell(fio_fd fd) {
+     362             :   return ftell(fd);
+     363             : }
+     364             : #endif /* plain ANSI C */
+     365             : 
+     366             : }
+     367             : }
+     368             : 
+     369             : #else 
+     370             : 
+     371             : /* Version for UNIX machines */
+     372             : #if defined(__linux)
+     373             : #ifndef _GNU_SOURCE
+     374             : #define _GNU_SOURCE            /* required for O_DIRECT */
+     375             : #endif
+     376             : #endif
+     377             : #include <unistd.h>
+     378             : #include <stdio.h>
+     379             : #include <sys/types.h>
+     380             : #include <sys/stat.h>
+     381             : #include <fcntl.h>
+     382             : #include <string.h>
+     383             : 
+     384             : namespace PLMD{
+     385             : namespace molfile{
+     386             : 
+     387             : typedef int fio_fd;
+     388             : typedef off_t fio_size_t;      /* off_t is 64-bits with LFS builds */
+     389             : 
+     390             : /*
+     391             :  * Enable use of kernel readv() if available and reliable
+     392             :  *
+     393             :  * Note: Some Linux implementations incorporate readv() code in libc 
+     394             :  * that does userspace copying of I/O vectors to internal temporary
+     395             :  * buffers in order to meet the atomicity requirements of the POSIX standard.
+     396             :  * Such copies make the use of vectorized I/O APIs much less useful for
+     397             :  * large trajectory files because the internal buffer allocations can fail
+     398             :  * badly when performing large aggregate I/O operations.  It may be that
+     399             :  * other implementations of vector I/O have similar problems, and in these
+     400             :  * cases it is probably best not to use it at all, and to fall back to 
+     401             :  * non-vectorized I/O APIs to avoid such extra copies.
+     402             :  */
+     403             : #if defined(__sun) || defined(__APPLE_CC__) || defined(__linux)
+     404             : #define USE_KERNEL_READV 1
+     405             : #endif
+     406             : 
+     407             : typedef void * fio_caddr_t;
+     408             : 
+     409             : }
+     410             : }
+     411             : 
+     412             : #if defined(USE_KERNEL_READV)
+     413             : #include <errno.h>
+     414             : #include <sys/uio.h>
+     415             : namespace PLMD{
+     416             : namespace molfile{
+     417             : typedef struct iovec fio_iovec;
+     418             : }
+     419             : }
+     420             : #else
+     421             : 
+     422             : namespace PLMD{
+     423             : namespace molfile{
+     424             : typedef struct {
+     425             :   fio_caddr_t iov_base;
+     426             :   int iov_len;
+     427             : } fio_iovec;
+     428             : }
+     429             : }
+     430             : #endif
+     431             : 
+     432             : #define FIO_SEEK_CUR SEEK_CUR
+     433             : #define FIO_SEEK_SET SEEK_SET
+     434             : #define FIO_SEEK_END SEEK_END
+     435             : 
+     436             : namespace PLMD{
+     437             : namespace molfile{
+     438             : 
+     439           1 : static int fio_open(const char *filename, int mode, fio_fd *fd) {
+     440             :   int nfd;
+     441             :   int oflag = 0;
+     442             :   
+     443             :   if (mode & FIO_READ) 
+     444             :     oflag = O_RDONLY;
+     445             : 
+     446           1 :   if (mode & FIO_WRITE) 
+     447             :     oflag = O_WRONLY | O_CREAT | O_TRUNC;
+     448             : 
+     449             : #if defined(__linux)
+     450             :   /* enable direct I/O, requires block-aligned buffers and I/O sizes */
+     451           1 :   if (mode & FIO_DIRECT)
+     452           0 :     oflag |= O_DIRECT;
+     453             : #else
+     454             :   if (mode & FIO_DIRECT)
+     455             :     return -1; /* not supported yet */
+     456             : #endif
+     457             : 
+     458             :   nfd = open(filename, oflag, 0666);
+     459           1 :   if (nfd < 0) {
+     460             :     return -1;
+     461             :   } else {
+     462           1 :     *fd = nfd;
+     463           1 :     return 0;
+     464             :   }
+     465             : }
+     466             : 
+     467           1 : static int fio_fclose(fio_fd fd) {
+     468           1 :   return close(fd);
+     469             : }
+     470             : 
+     471         219 : static fio_size_t fio_fread(void *ptr, fio_size_t size, 
+     472             :                             fio_size_t nitems, fio_fd fd) {
+     473             :   fio_size_t i;
+     474             :   fio_size_t len = 0; 
+     475             :   fio_size_t cnt = 0;
+     476             : 
+     477             : #if 1
+     478             :   /*
+     479             :    * On Linux individual calls to read() can end up doing short reads when
+     480             :    * reading more than 2GB in a single read call, even on 64-bit machines.  
+     481             :    * For large structures, e.g. 240M-atoms or larger, we have to use a loop
+     482             :    * to continue reading into the memory buffer until completion.
+     483             :    */ 
+     484         438 :   for (i=0; i<nitems; i++) {
+     485             :     fio_size_t szleft = size;
+     486             :     fio_size_t rc = 0;
+     487         438 :     for (szleft=size; szleft > 0; szleft -= rc) {
+     488         219 :       rc = read(fd, ((char*) ptr) + (cnt*size) + (size-szleft), szleft);
+     489         219 :        if (rc == 0) {
+     490             :           return cnt;  /* end of file scenario */
+     491             :        }
+     492             : //      if (rc != szleft) {
+     493             : //        printf("fio_fread(): rc %ld  sz: %ld\n", rc, szleft);
+     494             : //      }
+     495         219 :       if (rc < 0) {
+     496             :         printf("fio_fread(): rc %ld  sz: %ld\n", rc, size);
+     497           0 :         perror("  perror fio_fread(): ");
+     498           0 :         break;
+     499             :       }
+     500             :     }
+     501             :     len += rc;
+     502         219 :     cnt++;
+     503             :   }
+     504             : #else
+     505             :   for (i=0; i<nitems; i++) {
+     506             :     fio_size_t rc = read(fd, (void*) (((char *) ptr) + (cnt * size)), size);
+     507             :     if (rc != size) {
+     508             : //      printf("fio_fread(): rc %ld  sz: %ld\n", rc, size);
+     509             : //      perror("  perror fio_fread(): ");
+     510             :       break;
+     511             :     }
+     512             :     len += rc;
+     513             :     cnt++;
+     514             :   }
+     515             : #endif
+     516             : 
+     517             :   return cnt;
+     518             : }
+     519             : 
+     520             : static fio_size_t fio_readv(fio_fd fd, const fio_iovec * iov, int iovcnt) {
+     521             :   fio_size_t len;
+     522             :   int i;
+     523             : 
+     524             : #if 0
+     525             :   fio_size_t tlen;
+     526             :   for (tlen=0,i=0; i<iovcnt; i++) {
+     527             :     tlen += iov[i].iov_len;
+     528             :   }
+     529             : 
+     530             : #if defined(USE_KERNEL_READV)
+     531             :   len = readv(fd, iov, iovcnt);
+     532             :   if (len != tlen) {
+     533             :     printf("fio_readv(): readv() rc: %ld  sz: %ld\n", len, tlen);
+     534             :     printf("fio_readv(): readv() errno %d\n", errno);
+     535             :   }
+     536             : 
+     537             :   if ((len < 0 && errno == ENOSYS) ||
+     538             :       (len != tlen && errno == EINVAL)) 
+     539             : #endif
+     540             :   {
+     541             :     /* XXX this loop doesn't meet the atomicity requirements of
+     542             :      *     real POSIX readv(), since we don't need that feature 
+     543             :      */
+     544             :     len = 0; 
+     545             :     for (i=0; i<iovcnt; i++) {
+     546             :       void *ptr = iov[i].iov_base;
+     547             :       fio_size_t sz = iov[i].iov_len;
+     548             :       fio_size_t szleft = sz;
+     549             :       fio_size_t rc=0;
+     550             : 
+     551             :       for (szleft=sz; szleft > 0; szleft -= rc) {
+     552             :         rc = read(fd, ((char*) ptr)+(sz-szleft), szleft);
+     553             :         if (rc == 0) {
+     554             :           return len;  /* end of file scenario */
+     555             :         }
+     556             :         if (rc != szleft) {
+     557             :           printf("fio_readv(): read() rc %ld  sz: %ld\n", rc, szleft);
+     558             :         }
+     559             :         if (rc < 0) {
+     560             :           printf("fio_readv(): read() rc %ld  sz: %ld\n", rc, szleft);
+     561             :           perror("  perror fio_readv(): ");
+     562             :           break;
+     563             :         }
+     564             :       }
+     565             :       len += iov[i].iov_len;
+     566             :     }
+     567             :   }
+     568             : #else
+     569             : #if defined(USE_KERNEL_READV)
+     570             :   len = readv(fd, iov, iovcnt);
+     571             :   if (len < 0 && errno == ENOSYS)
+     572             : #endif
+     573             :   {
+     574             :     /* XXX this loop doesn't meet the atomicity requirements of
+     575             :      *     real POSIX readv(), since we don't need that feature 
+     576             :      */
+     577             :     len = 0; 
+     578             :     for (i=0; i<iovcnt; i++) {
+     579             :       fio_size_t rc = read(fd, iov[i].iov_base, iov[i].iov_len);
+     580             :       if (rc != iov[i].iov_len)
+     581             :         break;
+     582             :       len += iov[i].iov_len;
+     583             :     }
+     584             :   }
+     585             : #endif
+     586             : 
+     587             :   return len;
+     588             : }
+     589             : 
+     590           0 : static fio_size_t fio_fwrite(void *ptr, fio_size_t size, 
+     591             :                              fio_size_t nitems, fio_fd fd) {
+     592             :   fio_size_t i;
+     593             :   fio_size_t len = 0; 
+     594             :   fio_size_t cnt = 0;
+     595             : 
+     596             : #if 1
+     597             :   /*
+     598             :    * On Linux individual calls to write() can end up doing short writes when
+     599             :    * writing more than 2GB in a single write call, even on 64-bit machines.  
+     600             :    * For large structures, e.g. 240M-atoms or larger, we have to use a loop
+     601             :    * to continue writing the memory buffer until completion.
+     602             :    */ 
+     603             :   int writecalls=0;
+     604           0 :   for (i=0; i<nitems; i++) {
+     605             :     fio_size_t szleft = size;
+     606             :     fio_size_t rc = 0;
+     607           0 :     for (szleft=size; szleft > 0; szleft -= rc) {
+     608             :       fio_size_t writesz = szleft;
+     609             : 
+     610             : #if 0
+     611             :       /* On some kernel versions write calls beyond 2GB may not do */
+     612             :       /* a partial write and may just return an error immediately. */
+     613             :       /* Clamp maximum write size to 1GB per write call.           */
+     614             :       if (writesz > (1024L * 1024L * 1024L))
+     615             :         writesz = (1024L * 1024L * 1024L);
+     616             : #endif
+     617             : 
+     618           0 :       writecalls++;
+     619           0 :       rc = write(fd, ((char*) ptr)+(size-szleft), writesz);
+     620           0 :       if (rc < 0) {
+     621             :         printf("fio_fwrite(): rc %ld  sz: %ld  szleft: %ld  calls: %d\n", 
+     622             :                rc, size, szleft, writecalls);
+     623           0 :         perror("  perror fio_fwrite(): ");
+     624           0 :         return cnt;
+     625             :       }
+     626             :     }
+     627             :     len += rc;
+     628           0 :     cnt++;
+     629             :   }
+     630             : #else
+     631             :   for (i=0; i<nitems; i++) {
+     632             :     fio_size_t rc = write(fd, ptr, size);
+     633             :     if (rc != size) {
+     634             :       printf("fio_fwrite(): rc %ld  sz: %ld\n", rc, size);
+     635             :       perror("  perror fio_fwrite(): ");
+     636             :       break;
+     637             :     }
+     638             :     len += rc;
+     639             :     cnt++;
+     640             :   }
+     641             : #endif
+     642             : 
+     643             :   return cnt;
+     644             : }
+     645             : 
+     646           2 : static fio_size_t fio_fseek(fio_fd fd, fio_size_t offset, int whence) {
+     647           2 :  if (lseek(fd, offset, whence) >= 0)
+     648             :    return 0;  /* success (emulate behavior of fseek) */
+     649             :  else 
+     650           0 :    return -1; /* failure (emulate behavior of fseek) */
+     651             : }
+     652             : 
+     653           1 : static fio_size_t fio_ftell(fio_fd fd) {
+     654           1 :   return lseek(fd, 0, SEEK_CUR);
+     655             : }
+     656             : 
+     657             : }
+     658             : }
+     659             : 
+     660             : #endif
+     661             : 
+     662             : namespace PLMD{
+     663             : namespace molfile{
+     664             : 
+     665             : 
+     666             : /* higher level routines that are OS independent */
+     667             : 
+     668           0 : static int fio_write_int32(fio_fd fd, int i) {
+     669           0 :   return (fio_fwrite(&i, 4, 1, fd) != 1);
+     670             : }
+     671             : 
+     672             : static int fio_read_int32(fio_fd fd, int *i) {
+     673             :   return (fio_fread(i, 4, 1, fd) != 1);
+     674             : }
+     675             : 
+     676             : static int fio_write_str(fio_fd fd, const char *str) {
+     677             :   int len = strlen(str);
+     678             :   return (fio_fwrite((void *) str, len, 1, fd) != 1);
+     679             : }
+     680             : 
+     681             : }
+     682             : }
+     683             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/gromacsplugin.cpp.func-sort-c.html b/coverage-libs/molfile/gromacsplugin.cpp.func-sort-c.html new file mode 100644 index 000000000000..0ecbb8e47a9c --- /dev/null +++ b/coverage-libs/molfile/gromacsplugin.cpp.func-sort-c.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/gromacsplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - gromacsplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10736029.7 %
Date:2024-02-22 21:58:47Functions:52321.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile26molfile_gromacsplugin_finiEv0
_ZN4PLMD7molfileL13open_g96_readEPKcS2_Pi0
_ZN4PLMD7molfileL13open_gro_readEPKcS2_Pi0
_ZN4PLMD7molfileL14close_g96_readEPv0
_ZN4PLMD7molfileL14close_gro_readEPv0
_ZN4PLMD7molfileL14open_gro_writeEPKcS2_i0
_ZN4PLMD7molfileL14open_trr_writeEPKcS2_i0
_ZN4PLMD7molfileL15close_gro_writeEPv0
_ZN4PLMD7molfileL15close_trr_writeEPv0
_ZN4PLMD7molfileL17read_g96_timestepEPviPNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL17read_gro_timestepEPviPNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL18read_g96_structureEPvPiPNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL18read_gro_structureEPvPiPNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL18write_gro_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL18write_trr_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL19write_gro_structureEPviPKNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL26read_gro_molecule_metadataEPvPPNS0_18molfile_metadata_tE0
_ZN4PLMD7molfileL27convert_vmd_box_for_writingEPKNS0_18molfile_timestep_tEPfS4_S4_0
_ZN4PLMD7molfileL13open_trr_readEPKcS2_Pi195
_ZN4PLMD7molfileL14close_trr_readEPv195
_ZN4PLMD7molfile26molfile_gromacsplugin_initEv8374
_ZN4PLMD7molfile30molfile_gromacsplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8374
_ZN4PLMD7molfileL17read_trr_timestepEPviPNS0_18molfile_timestep_tE18452
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/gromacsplugin.cpp.func.html b/coverage-libs/molfile/gromacsplugin.cpp.func.html new file mode 100644 index 000000000000..0a5a287dec3e --- /dev/null +++ b/coverage-libs/molfile/gromacsplugin.cpp.func.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/gromacsplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - gromacsplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10736029.7 %
Date:2024-02-22 21:58:47Functions:52321.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile26molfile_gromacsplugin_finiEv0
_ZN4PLMD7molfile26molfile_gromacsplugin_initEv8374
_ZN4PLMD7molfile30molfile_gromacsplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8374
_ZN4PLMD7molfileL13open_g96_readEPKcS2_Pi0
_ZN4PLMD7molfileL13open_gro_readEPKcS2_Pi0
_ZN4PLMD7molfileL13open_trr_readEPKcS2_Pi195
_ZN4PLMD7molfileL14close_g96_readEPv0
_ZN4PLMD7molfileL14close_gro_readEPv0
_ZN4PLMD7molfileL14close_trr_readEPv195
_ZN4PLMD7molfileL14open_gro_writeEPKcS2_i0
_ZN4PLMD7molfileL14open_trr_writeEPKcS2_i0
_ZN4PLMD7molfileL15close_gro_writeEPv0
_ZN4PLMD7molfileL15close_trr_writeEPv0
_ZN4PLMD7molfileL17read_g96_timestepEPviPNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL17read_gro_timestepEPviPNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL17read_trr_timestepEPviPNS0_18molfile_timestep_tE18452
_ZN4PLMD7molfileL18read_g96_structureEPvPiPNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL18read_gro_structureEPvPiPNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL18write_gro_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL18write_trr_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL19write_gro_structureEPviPKNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL26read_gro_molecule_metadataEPvPPNS0_18molfile_metadata_tE0
_ZN4PLMD7molfileL27convert_vmd_box_for_writingEPKNS0_18molfile_timestep_tEPfS4_S4_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/gromacsplugin.cpp.gcov.html b/coverage-libs/molfile/gromacsplugin.cpp.gcov.html new file mode 100644 index 000000000000..3e48a283f0ac --- /dev/null +++ b/coverage-libs/molfile/gromacsplugin.cpp.gcov.html @@ -0,0 +1,937 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/gromacsplugin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - gromacsplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10736029.7 %
Date:2024-02-22 21:58:47Functions:52321.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : University of Illinois Open Source License
+       3             : Copyright 2003 Theoretical and Computational Biophysics Group, 
+       4             : All rights reserved.
+       5             : 
+       6             : Developed by:           Theoretical and Computational Biophysics Group
+       7             :                         University of Illinois at Urbana-Champaign
+       8             :                         http://www.ks.uiuc.edu/
+       9             : 
+      10             : Permission is hereby granted, free of charge, to any person obtaining a copy of
+      11             : this software and associated documentation files (the Software), to deal with 
+      12             : the Software without restriction, including without limitation the rights to 
+      13             : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+      14             : of the Software, and to permit persons to whom the Software is furnished to 
+      15             : do so, subject to the following conditions:
+      16             : 
+      17             : Redistributions of source code must retain the above copyright notice, 
+      18             : this list of conditions and the following disclaimers.
+      19             : 
+      20             : Redistributions in binary form must reproduce the above copyright notice, 
+      21             : this list of conditions and the following disclaimers in the documentation 
+      22             : and/or other materials provided with the distribution.
+      23             : 
+      24             : Neither the names of Theoretical and Computational Biophysics Group, 
+      25             : University of Illinois at Urbana-Champaign, nor the names of its contributors 
+      26             : may be used to endorse or promote products derived from this Software without 
+      27             : specific prior written permission.
+      28             : 
+      29             : THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+      30             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+      31             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
+      32             : THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
+      33             : OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+      34             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
+      35             : OTHER DEALINGS WITH THE SOFTWARE.
+      36             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      37             : #if defined(__PLUMED_HAS_MOLFILE_PLUGINS) && ! defined(__PLUMED_HAS_EXTERNAL_MOLFILE_PLUGINS)
+      38             : /***************************************************************************
+      39             :  *cr
+      40             :  *cr            (C) Copyright 1995-2016 The Board of Trustees of the
+      41             :  *cr                        University of Illinois
+      42             :  *cr                         All Rights Reserved
+      43             :  *cr
+      44             :  ***************************************************************************/
+      45             : 
+      46             : /***************************************************************************
+      47             :  * RCS INFORMATION:
+      48             :  *
+      49             :  *      $RCSfile: gromacsplugin.C,v $
+      50             :  *      $Author: johns $       $Locker:  $             $State: Exp $
+      51             :  *      $Revision: 1.54 $       $Date: 2017/05/20 05:37:53 $
+      52             :  *
+      53             :  ***************************************************************************/
+      54             : 
+      55             : #include "largefiles.h"   /* platform dependent 64-bit file I/O defines */
+      56             : 
+      57             : #include <math.h>
+      58             : #include <stdio.h>
+      59             : #include <stdlib.h>
+      60             : #include <string.h>
+      61             : #include <ctype.h>
+      62             : #include "Gromacs.h"
+      63             : #include "molfile_plugin.h"
+      64             : 
+      65             : #if defined(_AIX)
+      66             : #include <strings.h>
+      67             : #endif
+      68             : 
+      69             : namespace PLMD{
+      70             : namespace molfile{
+      71             : 
+      72             : #ifndef M_PI
+      73             : #define M_PI           3.14159265358979323846
+      74             : #endif
+      75             : 
+      76             : #if defined(WIN32) || defined(WIN64)
+      77             : #define strcasecmp stricmp
+      78             : #endif
+      79             : 
+      80             : typedef struct {
+      81             :   md_file *mf;
+      82             :   int natoms;
+      83             :   int step;
+      84             :   float timeval;
+      85             :   molfile_atom_t *atomlist;
+      86             :   molfile_metadata_t *meta;
+      87             : } gmxdata;
+      88             : 
+      89           0 : static void convert_vmd_box_for_writing(const molfile_timestep_t *ts, float *x, float *y, float *z)
+      90             : {
+      91             : //     const float sa = sin((double)ts->alpha/180.0*M_PI);
+      92           0 :     const float ca = cos((double)ts->alpha/180.0*M_PI);
+      93           0 :     const float cb = cos((double)ts->beta/180.0*M_PI);
+      94           0 :     const float cg = cos((double)ts->gamma/180.0*M_PI);
+      95           0 :     const float sg = sin((double)ts->gamma/180.0*M_PI);
+      96             : 
+      97           0 :     x[0] = ts->A / ANGS_PER_NM;
+      98           0 :     y[0] = 0.0;
+      99           0 :     z[0] = 0.0;
+     100           0 :     x[1] = ts->B*cg / ANGS_PER_NM; // ts->B*ca when writing trr?!
+     101           0 :     y[1] = ts->B*sg / ANGS_PER_NM; // ts->B*sa when writing trr?!
+     102           0 :     z[1] = 0.0;
+     103           0 :     x[2] = ts->C*cb / ANGS_PER_NM;
+     104           0 :     y[2] = (ts->C / ANGS_PER_NM)*(ca - cb*cg)/sg;
+     105           0 :     z[2] = (ts->C / ANGS_PER_NM)*sqrt((double)(1.0 + 2.0*ca*cb*cg
+     106           0 :                                - ca*ca - cb*cb - cg*cg)/(1.0 - cg*cg));
+     107           0 : }
+     108             : 
+     109           0 : static void *open_gro_read(const char *filename, const char *,
+     110             :     int *natoms) {
+     111             : 
+     112             :     md_file *mf;
+     113             :     md_header mdh;
+     114             :     gmxdata *gmx;
+     115             : 
+     116           0 :     mf = mdio_open(filename, MDFMT_GRO);
+     117           0 :     if (!mf) {
+     118           0 :         fprintf(stderr, "gromacsplugin) Cannot open file '%s', %s\n",
+     119             :                 filename, mdio_errmsg(mdio_errno()));
+     120           0 :         return NULL;
+     121             :     }
+     122             : 
+     123             :     // read in the header data (careful not to rewind!)
+     124           0 :     if (gro_header(mf, mdh.title, MAX_MDIO_TITLE,
+     125             :     &mdh.timeval, &mdh.natoms, 0) < 0) {
+     126           0 :         fprintf(stderr, "gromacsplugin) Cannot read header fromm '%s', %s\n",
+     127             :                 filename, mdio_errmsg(mdio_errno()));
+     128             :             // XXX should free the file handle...
+     129           0 :         return NULL;
+     130             :     }
+     131           0 :     *natoms = mdh.natoms;
+     132           0 :     gmx = new gmxdata;
+     133             :     memset(gmx,0,sizeof(gmxdata));
+     134           0 :     gmx->mf = mf;
+     135           0 :     gmx->natoms = mdh.natoms;
+     136           0 :     gmx->meta = new molfile_metadata_t;
+     137             :     memset(gmx->meta,0,sizeof(molfile_metadata_t));
+     138           0 :     strncpy(gmx->meta->title, mdh.title, 80);
+     139           0 :     gmx->timeval = mdh.timeval;
+     140           0 :     return gmx;
+     141             : }
+     142             : 
+     143           0 : static int read_gro_structure(void *mydata, int *optflags,
+     144             :     molfile_atom_t *atoms) {
+     145             : 
+     146             :   md_atom ma;
+     147             :   char buf[MAX_GRO_LINE + 1];
+     148             :   gmxdata *gmx = (gmxdata *)mydata;
+     149             : 
+     150           0 :   *optflags = MOLFILE_NOOPTIONS; // no optional data
+     151             : 
+     152             :   // read in each atom and add it into the molecule
+     153           0 :   for (int i = 0; i < gmx->natoms; i++) {
+     154           0 :     molfile_atom_t *atom = atoms+i;
+     155           0 :     if (gro_rec(gmx->mf, &ma) < 0) {
+     156           0 :       fprintf(stderr, "gromacsplugin) Error reading atom %d from file, %s\n",
+     157             :               i+1, mdio_errmsg(mdio_errno()));
+     158           0 :       return MOLFILE_ERROR;
+     159             :     }
+     160           0 :     strcpy(atom->name, ma.atomname);
+     161           0 :     strcpy(atom->type, ma.atomname);
+     162           0 :     strcpy(atom->resname, ma.resname);
+     163           0 :     atom->resid = atoi(ma.resid);
+     164           0 :     atom->chain[0] = '\0';
+     165           0 :     atom->segid[0] = '\0';
+     166             :   }
+     167             : 
+     168           0 :   if (mdio_readline(gmx->mf, buf, MAX_GRO_LINE + 1, 0) < 0) {
+     169           0 :     fprintf(stderr, "gromacsplugin) Warning, error reading box, %s\n",
+     170             :             mdio_errmsg(mdio_errno()));
+     171             :   }
+     172             : 
+     173           0 :   rewind(gmx->mf->f);
+     174             :   return MOLFILE_SUCCESS;
+     175             : }
+     176             : 
+     177           0 : static int read_gro_molecule_metadata(void *v, molfile_metadata_t **metadata) {
+     178             :   gmxdata *gmx = (gmxdata *)v;
+     179           0 :   *metadata = gmx->meta;
+     180           0 :   return MOLFILE_SUCCESS;
+     181             : }
+     182             : 
+     183           0 : static int read_gro_timestep(void *v, int natoms, molfile_timestep_t *ts) {
+     184             :   gmxdata *gmx = (gmxdata *)v;
+     185             :   md_ts mdts;
+     186             :   memset(&mdts, 0, sizeof(md_ts));
+     187           0 :   mdts.natoms = natoms;
+     188             : 
+     189           0 :   if (mdio_timestep(gmx->mf, &mdts) < 0)
+     190             :     return MOLFILE_ERROR;
+     191           0 :   if (ts) {
+     192           0 :     memcpy(ts->coords, mdts.pos, 3 * sizeof(float) * gmx->natoms);
+     193           0 :     if (mdts.box) {
+     194           0 :       ts->A = mdts.box->A;
+     195           0 :       ts->B = mdts.box->B;
+     196           0 :       ts->C = mdts.box->C;
+     197           0 :       ts->alpha = mdts.box->alpha;
+     198           0 :       ts->beta = mdts.box->beta;
+     199           0 :       ts->gamma = mdts.box->gamma;
+     200             :     }
+     201             :   }
+     202           0 :   mdio_tsfree(&mdts);
+     203           0 :   return MOLFILE_SUCCESS;
+     204             : }
+     205             : 
+     206           0 : static void close_gro_read(void *v) {
+     207             :   gmxdata *gmx = (gmxdata *)v;
+     208           0 :   mdio_close(gmx->mf);
+     209           0 :   delete gmx->meta;
+     210           0 :   delete gmx;
+     211           0 : }
+     212             : 
+     213             : // open file for writing
+     214           0 : static void *open_gro_write(const char *filename, const char *filetype,
+     215             :     int natoms) {
+     216             : 
+     217             :     md_file *mf;
+     218             :     gmxdata *gmx;
+     219             : 
+     220           0 :     mf = mdio_open(filename, MDFMT_GRO, MDIO_WRITE);
+     221           0 :     if (!mf) {
+     222           0 :         fprintf(stderr, "gromacsplugin) Cannot open file '%s', %s\n",
+     223             :                 filename, mdio_errmsg(mdio_errno()));
+     224           0 :         return NULL;
+     225             :     }
+     226           0 :     gmx = new gmxdata;
+     227             :     memset(gmx,0,sizeof(gmxdata));
+     228           0 :     gmx->mf = mf;
+     229           0 :     gmx->natoms = natoms;
+     230             :     gmx->step   = 0;
+     231           0 :     gmx->meta = new molfile_metadata_t;
+     232             :     memset(gmx->meta,0,sizeof(molfile_metadata_t));
+     233             :     gmx->meta->title[0] = '\0';
+     234             : 
+     235           0 :     return gmx;
+     236             : }
+     237             : 
+     238           0 : static int write_gro_structure(void *v, int optflags,
+     239             :     const molfile_atom_t *atoms) {
+     240             : 
+     241             :   gmxdata *gmx = (gmxdata *)v;
+     242           0 :   int natoms = gmx->natoms;
+     243           0 :   gmx->atomlist = (molfile_atom_t *)malloc(natoms*sizeof(molfile_atom_t));
+     244             :   memcpy(gmx->atomlist, atoms, natoms*sizeof(molfile_atom_t));
+     245             : 
+     246           0 :   return MOLFILE_SUCCESS;
+     247             : }
+     248             : 
+     249           0 : static int write_gro_timestep(void *v, const molfile_timestep_t *ts) {
+     250             :   gmxdata *gmx = (gmxdata *)v;
+     251             :   const molfile_atom_t *atom;
+     252             :   const float *pos, *vel;
+     253             :   float x[3], y[3], z[3];
+     254             :   int i;
+     255             : 
+     256           0 :   if (gmx->natoms == 0)
+     257             :     return MOLFILE_SUCCESS;
+     258             : 
+     259           0 :   atom = gmx->atomlist;
+     260           0 :   pos = ts->coords;
+     261           0 :   vel = ts->velocities;
+     262             : 
+     263             :   /* The title cannot be written */
+     264             : /*  fprintf(gmx->mf->f, "%s", gmx->meta->title);*/
+     265             :   /* Write a dummy title instead */
+     266           0 :   fprintf(gmx->mf->f, "generated by VMD");
+     267             : #if vmdplugin_ABIVERSION > 10
+     268           0 :   fprintf(gmx->mf->f, ", t= %f", ts->physical_time);
+     269             : #endif
+     270           0 :   fprintf(gmx->mf->f, "\n");
+     271             : 
+     272           0 :   fprintf(gmx->mf->f, "%d\n", gmx->natoms);
+     273           0 :   for (i=0; i<gmx->natoms; i++)
+     274             :   {
+     275           0 :      fprintf(gmx->mf->f, "%5d%-5s%5s%5d%8.3f%8.3f%8.3f",
+     276           0 :              atom->resid, atom->resname, atom->name,
+     277           0 :              (i+1) % 100000, // GRO format only supports indices up to 99999
+     278             :                              // but since GROMACS ignores indices, modular
+     279             :                              // arithmetic prevents formatting problems for 
+     280             :                              // very large structures
+     281           0 :              pos[0] / ANGS_PER_NM, pos[1] / ANGS_PER_NM, pos[2] / ANGS_PER_NM);
+     282           0 :      if(vel)
+     283             :      {
+     284           0 :          fprintf(gmx->mf->f, "%8.4f%8.4f%8.4f", vel[0] / ANGS_PER_NM, vel[1] / ANGS_PER_NM, vel[2] / ANGS_PER_NM);
+     285           0 :          vel += 3;
+     286             :      }
+     287           0 :      fprintf(gmx->mf->f, "\n");
+     288           0 :      ++atom;
+     289           0 :      pos += 3;
+     290             :   }
+     291           0 :   convert_vmd_box_for_writing(ts, x, y, z);
+     292           0 :   fprintf(gmx->mf->f, "%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f%10.5f\n", x[0], y[1], z[2], y[0], z[0], x[1], z[1], x[2], y[2]);
+     293             : 
+     294             :   return MOLFILE_SUCCESS;
+     295             : }
+     296             : 
+     297           0 : static void close_gro_write(void *v) {
+     298             :   gmxdata *gmx = (gmxdata *)v;
+     299           0 :   mdio_close(gmx->mf);
+     300           0 :   free(gmx->atomlist);
+     301           0 :   delete gmx->meta;
+     302           0 :   delete gmx;
+     303           0 : }
+     304             : 
+     305             : 
+     306           0 : static void *open_g96_read(const char *filename, const char *,
+     307             :     int *natoms) {
+     308             : 
+     309             :     md_file *mf;
+     310             :     md_header mdh;
+     311             :     char gbuf[MAX_G96_LINE + 1];
+     312             : 
+     313           0 :     mf = mdio_open(filename, MDFMT_G96);
+     314           0 :     if (!mf) {
+     315           0 :         fprintf(stderr, "gromacsplugin) Cannot open file '%s', %s\n",
+     316             :                 filename, mdio_errmsg(mdio_errno()));
+     317           0 :         return NULL;
+     318             :     }
+     319             : 
+     320             :         // read in the header data
+     321           0 :         if (g96_header(mf, mdh.title, MAX_MDIO_TITLE, &mdh.timeval) < 0) {
+     322           0 :             fprintf(stderr, "gromacsplugin) Cannot read header from '%s', %s\n",
+     323             :                     filename, mdio_errmsg(mdio_errno()));
+     324           0 :             return NULL;
+     325             :         }
+     326             : 
+     327             :         // First, look for a timestep block
+     328           0 :         if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0) {
+     329           0 :             fprintf(stderr, "gromacsplugin) Cannot read header from '%s', %s\n",
+     330             :                     filename, mdio_errmsg(mdio_errno()));
+     331           0 :             return NULL;
+     332             :         }
+     333           0 :         if (!strcasecmp(gbuf, "TIMESTEP")) {
+     334             :             // Read in the value line and the END line, and the next
+     335           0 :             if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0 ||
+     336           0 :                 mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0 ||
+     337           0 :                 mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0) {
+     338           0 :               fprintf(stderr, "gromacsplugin) Cannot read header from '%s', %s\n",
+     339             :                       filename, mdio_errmsg(mdio_errno()));
+     340           0 :               return NULL;
+     341             :             }
+     342             :         }
+     343           0 :         if (strcasecmp(gbuf, "POSITION") && strcasecmp(gbuf, "REFPOSITION")) {
+     344           0 :           fprintf(stderr, "gromacsplugin) No structure information in file %s\n", filename);
+     345           0 :           return NULL;
+     346             :         }
+     347           0 :         *natoms = g96_countatoms(mf);
+     348             : 
+     349           0 :         gmxdata *gmx = new gmxdata;
+     350             :         memset(gmx,0,sizeof(gmxdata));
+     351           0 :         gmx->mf = mf;
+     352           0 :         gmx->natoms = *natoms; 
+     353           0 :         return gmx;
+     354             : }
+     355             : 
+     356           0 : static int read_g96_structure(void *mydata, int *optflags,
+     357             :     molfile_atom_t *atoms) {
+     358             : 
+     359             :     char gbuf[MAX_G96_LINE + 1];
+     360             :     gmxdata *gmx = (gmxdata *)mydata;
+     361             :     md_atom ma;
+     362           0 :     md_file *mf = gmx->mf;
+     363             : 
+     364           0 :     *optflags = MOLFILE_NOOPTIONS; // no optional data
+     365             : 
+     366           0 :         for (int i = 0; i < gmx->natoms; i++) {
+     367           0 :             molfile_atom_t *atom = atoms+i;
+     368           0 :             if (g96_rec(mf, &ma) < 0) {
+     369           0 :                 fprintf(stderr, "gromacsplugin) Error reading atom %d from file, %s\n",
+     370             :                   i+1, mdio_errmsg(mdio_errno()));
+     371           0 :                 return MOLFILE_ERROR;
+     372             :             }
+     373           0 :             strcpy(atom->name, ma.atomname);
+     374           0 :             strcpy(atom->type, ma.atomname);
+     375           0 :             strcpy(atom->resname, ma.resname);
+     376           0 :             atom->resid = atoi(ma.resid);
+     377           0 :             atom->chain[0] = '\0';
+     378           0 :             atom->segid[0] = '\0';
+     379             :         }
+     380             : 
+     381           0 :         if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0) {
+     382           0 :             fprintf(stderr, "gromacsplugin) Warning, error reading END record, %s\n",
+     383             :                 mdio_errmsg(mdio_errno()));
+     384             :         }
+     385             : 
+     386             :             // ... another problem: there may or may not be a VELOCITY
+     387             :             // block or a BOX block, so we need to read one line beyond
+     388             :             // the POSITION block to determine this. If neither VEL. nor
+     389             :             // BOX are present we've read a line too far and infringed
+     390             :             // on the next timestep, so we need to keep track of the
+     391             :             // position now for a possible fseek() later to backtrack.
+     392           0 :             long fpos = ftell(mf->f);
+     393             : 
+     394             :             // Now we must read in the velocities and the box, if present
+     395           0 :             if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) >= 0) {
+     396             : 
+     397             :                 // Is there a velocity block present ?
+     398           0 :                 if (!strcasecmp(gbuf, "VELOCITY") || !strcasecmp(gbuf, "VELOCITYRED")) {
+     399             :                         // Ignore all the coordinates - VMD doesn't use them
+     400             :                         for (;;) {
+     401           0 :                                 if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0)
+     402             :                                         return MOLFILE_ERROR;
+     403           0 :                                 if (!strcasecmp(gbuf, "END")) break;
+     404             :                         }
+     405             : 
+     406             :                         // Again, record our position because we may need
+     407             :                         // to fseek here later if we read too far.
+     408           0 :                         fpos = ftell(mf->f);
+     409             : 
+     410             :                         // Go ahead and read the next line.
+     411           0 :                         if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0)
+     412             :                     return MOLFILE_ERROR;
+     413             :                 }
+     414             : 
+     415             :                 // Is there a box present ?
+     416           0 :                 if (!strcasecmp(gbuf, "BOX")) {
+     417             :                         // Ignore the box coordinates at this time.
+     418           0 :                         if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0)
+     419             :                     return MOLFILE_ERROR;
+     420           0 :                         if (mdio_readline(mf, gbuf, MAX_G96_LINE + 1) < 0)
+     421             :                     return MOLFILE_ERROR;
+     422           0 :                         if (strcasecmp(gbuf, "END"))
+     423             :                     return MOLFILE_ERROR;
+     424             :                 }
+     425             :                 else {
+     426             :                         // We have read too far, so fseek back to the
+     427             :                         // last known safe position so we don't return
+     428             :                         // with the file pointer set infringing on the
+     429             :                         // next timestep data.
+     430           0 :                         fseek(mf->f, fpos, SEEK_SET);
+     431             :                 }
+     432             :         }
+     433             :         else {
+     434             :             // Go ahead and rewind for good measure
+     435           0 :             fseek(mf->f, fpos, SEEK_SET);
+     436             :         }
+     437           0 :         rewind(mf->f);
+     438             :         return MOLFILE_SUCCESS;
+     439             : }
+     440             : 
+     441           0 : static int read_g96_timestep(void *v, int natoms, molfile_timestep_t *ts) {
+     442             : 
+     443             :   gmxdata *gmx = (gmxdata *)v;
+     444             :   md_ts mdts;
+     445             :   memset(&mdts, 0, sizeof(md_ts));
+     446           0 :   mdts.natoms = natoms;
+     447             : 
+     448           0 :   if (mdio_timestep(gmx->mf, &mdts) < 0)
+     449             :     return MOLFILE_ERROR;
+     450           0 :   if (ts) {
+     451           0 :     memcpy(ts->coords, mdts.pos, 3 * sizeof(float) * gmx->natoms);
+     452           0 :     if (mdts.box) {
+     453           0 :       ts->A = mdts.box->A;
+     454           0 :       ts->B = mdts.box->B;
+     455           0 :       ts->C = mdts.box->C;
+     456           0 :       ts->alpha = mdts.box->alpha;
+     457           0 :       ts->beta = mdts.box->beta;
+     458           0 :       ts->gamma = mdts.box->gamma;
+     459             :     }
+     460             :   }
+     461           0 :   mdio_tsfree(&mdts);
+     462           0 :   return MOLFILE_SUCCESS;
+     463             : }
+     464             : 
+     465           0 : static void close_g96_read(void *v) {
+     466             :   gmxdata *gmx = (gmxdata *)v;
+     467           0 :   mdio_close(gmx->mf);
+     468           0 :   delete gmx;
+     469           0 : }
+     470             : 
+     471             : 
+     472             : //
+     473             : // TRR and XTC files
+     474             : //
+     475             : 
+     476         195 : static void *open_trr_read(const char *filename, const char *filetype,
+     477             :     int *natoms) {
+     478             : 
+     479             :     md_file *mf;
+     480             :     md_header mdh;
+     481             :     gmxdata *gmx;
+     482             :     int format;
+     483             : 
+     484         195 :     if (!strcmp(filetype, "trr"))
+     485             :       format = MDFMT_TRR;
+     486         190 :     else if (!strcmp(filetype, "trj"))
+     487             :       format = MDFMT_TRJ;
+     488         190 :     else if (!strcmp(filetype, "xtc"))
+     489             :       format = MDFMT_XTC;
+     490             :     else
+     491             :       return NULL;
+     492             : 
+     493         195 :     mf = mdio_open(filename, format);
+     494         195 :     if (!mf) {
+     495           0 :         fprintf(stderr, "gromacsplugin) Cannot open file '%s', %s\n",
+     496             :                 filename, mdio_errmsg(mdio_errno()));
+     497           0 :         return NULL;
+     498             :     }
+     499         195 :     if (mdio_header(mf, &mdh) < 0) {
+     500           0 :         mdio_close(mf);
+     501           0 :         fprintf(stderr, "gromacsplugin) Cannot read header fromm '%s', %s\n",
+     502             :                 filename, mdio_errmsg(mdio_errno()));
+     503           0 :         return NULL;
+     504             :     }
+     505         195 :     *natoms = mdh.natoms;
+     506         195 :     gmx = new gmxdata;
+     507             :     memset(gmx,0,sizeof(gmxdata));
+     508         195 :     gmx->mf = mf;
+     509         195 :     gmx->natoms = mdh.natoms;
+     510         195 :     return gmx;
+     511             : }
+     512             : 
+     513       18452 : static int read_trr_timestep(void *v, int natoms, molfile_timestep_t *ts) {
+     514             :   gmxdata *gmx = (gmxdata *)v;
+     515             :   md_ts mdts;
+     516             :   memset(&mdts, 0, sizeof(md_ts));
+     517       18452 :   mdts.natoms = natoms;
+     518             : 
+     519       18452 :   if (mdio_timestep(gmx->mf, &mdts) < 0) {
+     520         195 :     if (mdio_errno() == MDIO_EOF || mdio_errno() == MDIO_IOERROR) {
+     521             :       // XXX Lame, why does mdio treat IOERROR like EOF?
+     522             :       return MOLFILE_ERROR;
+     523             :     }
+     524           0 :     fprintf(stderr, "gromacsplugin) Error reading timestep, %s\n",
+     525             :             mdio_errmsg(mdio_errno()));
+     526           0 :     return MOLFILE_ERROR;
+     527             :   }
+     528       18257 :   if (mdts.natoms != gmx->natoms) {
+     529           0 :     fprintf(stderr, "gromacsplugin) Timestep in file contains wrong number of atoms\n");
+     530           0 :     fprintf(stderr, "gromacsplugin) Found %d, expected %d\n", mdts.natoms, gmx->natoms);
+     531           0 :     mdio_tsfree(&mdts);
+     532           0 :     return MOLFILE_ERROR;
+     533             :   }
+     534             : 
+     535       18257 :   if (ts) {
+     536       18257 :     if (mdts.pos) 
+     537       18257 :       memcpy(ts->coords, mdts.pos, 3 * sizeof(float) * gmx->natoms);
+     538             :     else 
+     539             :       printf("gromacsplugin) Warning: skipping empty timestep!\n");
+     540             : 
+     541       18257 :     if (mdts.box) {
+     542       18257 :       ts->A = mdts.box->A;
+     543       18257 :       ts->B = mdts.box->B;
+     544       18257 :       ts->C = mdts.box->C;
+     545       18257 :       ts->alpha = mdts.box->alpha;
+     546       18257 :       ts->beta = mdts.box->beta;
+     547       18257 :       ts->gamma = mdts.box->gamma;
+     548             :     }
+     549             :   }
+     550       18257 :   mdio_tsfree(&mdts);
+     551       18257 :   return MOLFILE_SUCCESS;
+     552             : }
+     553             : 
+     554         195 : static void close_trr_read(void *v) {
+     555             :   gmxdata *gmx = (gmxdata *)v;
+     556         195 :   mdio_close(gmx->mf);
+     557         195 :   delete gmx;
+     558         195 : }
+     559             : 
+     560             : // open file for writing
+     561           0 : static void *open_trr_write(const char *filename, const char *filetype,
+     562             :     int natoms) {
+     563             : 
+     564             :     md_file *mf;
+     565             :     gmxdata *gmx;
+     566             :     int format;
+     567             : 
+     568           0 :     if (!strcmp(filetype, "trr"))
+     569             :       format = MDFMT_TRR;
+     570           0 :     else if (!strcmp(filetype, "xtc"))
+     571             :       format = MDFMT_XTC;
+     572             :     else
+     573             :       return NULL;
+     574             : 
+     575           0 :     mf = mdio_open(filename, format, MDIO_WRITE);
+     576           0 :     if (!mf) {
+     577           0 :         fprintf(stderr, "gromacsplugin) Cannot open file '%s', %s\n",
+     578             :                 filename, mdio_errmsg(mdio_errno()));
+     579           0 :         return NULL;
+     580             :     }
+     581           0 :     gmx = new gmxdata;
+     582             :     memset(gmx,0,sizeof(gmxdata));
+     583           0 :     gmx->mf = mf;
+     584           0 :     gmx->natoms = natoms;
+     585             :     // set some parameters for the output stream:
+     586             :     // start at step 0, convert to big-endian, write single precision.
+     587             :     gmx->step   = 0;
+     588           0 :     gmx->mf->rev = host_is_little_endian();
+     589           0 :     gmx->mf->prec = sizeof(float);
+     590           0 :     return gmx;
+     591             : }
+     592             : 
+     593             : // write a trr timestep. the file format has a header with each record
+     594           0 : static int write_trr_timestep(void *mydata, const molfile_timestep_t *ts)
+     595             : {
+     596             :   const float nm=0.1;
+     597             : 
+     598             :   gmxdata *gmx = (gmxdata *)mydata;
+     599             : 
+     600             :   // determine and write header from structure info.
+     601             :   // write trr header. XXX: move this to Gromacs.h ??
+     602           0 :   if (gmx->mf->fmt == MDFMT_TRR) {
+     603             :     int i;
+     604             : 
+     605           0 :     if ( put_trx_int(gmx->mf, TRX_MAGIC)            // ID
+     606           0 :          || put_trx_string(gmx->mf, "GMX_trn_file") // version
+     607           0 :          || put_trx_int(gmx->mf, 0)                 // ir_size (ignored)
+     608           0 :          || put_trx_int(gmx->mf, 0)                 // e_size (ignored)
+     609           0 :          || put_trx_int(gmx->mf, 9*sizeof(float))   // box
+     610           0 :          || put_trx_int(gmx->mf, 0)                 // vir_size (ignored)
+     611           0 :          || put_trx_int(gmx->mf, 0)                 // pres_size (ignored)
+     612           0 :          || put_trx_int(gmx->mf, 0)                 // top_size (ignored)
+     613           0 :          || put_trx_int(gmx->mf, 0)                 // sym_size (ignored)
+     614           0 :          || put_trx_int(gmx->mf, 3*sizeof(float)*gmx->natoms) // coordinates
+     615           0 :          || put_trx_int(gmx->mf, 0)                 // no velocities
+     616           0 :          || put_trx_int(gmx->mf, 0)                 // no forces
+     617           0 :          || put_trx_int(gmx->mf, gmx->natoms)       // number of atoms
+     618           0 :          || put_trx_int(gmx->mf, gmx->step)         // current step number
+     619           0 :          || put_trx_int(gmx->mf, 0)                 // nre (ignored)
+     620           0 :          || put_trx_real(gmx->mf, 0.1*gmx->step)    // current time. (dummy value: 0.1)
+     621           0 :          || put_trx_real(gmx->mf, 0.0))             // current lambda
+     622           0 :       return MOLFILE_ERROR;
+     623             : 
+     624             :     // set up box according to the VMD unitcell conventions.
+     625             :     // the a-vector is collinear with the x-axis and
+     626             :     // the b-vector is in the xy-plane.
+     627           0 :     const float sa = sin((double)ts->alpha/180.0*M_PI);
+     628           0 :     const float ca = cos((double)ts->alpha/180.0*M_PI);
+     629           0 :     const float cb = cos((double)ts->beta/180.0*M_PI);
+     630           0 :     const float cg = cos((double)ts->gamma/180.0*M_PI);
+     631           0 :     const float sg = sin((double)ts->gamma/180.0*M_PI);
+     632             :     float box[9];
+     633           0 :     box[0] = ts->A;    box[1] = 0.0;      box[2] = 0.0;
+     634           0 :     box[3] = ts->B*ca; box[4] = ts->B*sa; box[5] = 0.0;
+     635           0 :     box[6] = ts->C*cb; box[7] = ts->C*(ca - cb*cg)/sg;
+     636           0 :     box[8] = ts->C*sqrt((double)(1.0 + 2.0*ca*cb*cg
+     637           0 :                                  - ca*ca - cb*cb - cg*cg)/(1.0 - cg*cg));
+     638             : 
+     639           0 :     for (i=0; i<9; ++i) {
+     640           0 :       if (put_trx_real(gmx->mf, box[i]*nm))
+     641             :         return MOLFILE_ERROR;
+     642             :     }
+     643             : #ifdef TEST_TRR_PLUGIN
+     644             :     fprintf(stderr, "gromacsplugin) box is:\n %f %f %f\n %f %f %f\n %f %f %f\n\n",
+     645             :             box[0], box[1], box[2], box[3], box[4], box[5], box[6], box[7], box[8]);
+     646             : #endif
+     647             : 
+     648             :     // write coordinates
+     649           0 :     for (i=0; i<(3*gmx->natoms); ++i) {
+     650           0 :       if (put_trx_real(gmx->mf, ts->coords[i]*nm))
+     651             :         return MOLFILE_ERROR;
+     652             :     }
+     653             :   } else {
+     654           0 :     fprintf(stderr, "gromacsplugin) only .trr is supported for writing\n");
+     655           0 :     return MOLFILE_ERROR;
+     656             :   }
+     657             : 
+     658           0 :   ++ gmx->step;
+     659           0 :   return MOLFILE_SUCCESS;
+     660             :   }
+     661             : 
+     662             : 
+     663           0 : static void close_trr_write(void *v) {
+     664             :   gmxdata *gmx = (gmxdata *)v;
+     665           0 :   mdio_close(gmx->mf);
+     666           0 :   delete gmx;
+     667           0 : }
+     668             : 
+     669             : #define GROMACS_PLUGIN_MAJOR_VERSION 1
+     670             : #define GROMACS_PLUGIN_MINOR_VERSION 3 
+     671             : 
+     672             : //
+     673             : // plugin registration stuff below
+     674             : //
+     675             : 
+     676             : static molfile_plugin_t gro_plugin;
+     677             : static molfile_plugin_t g96_plugin;
+     678             : static molfile_plugin_t trr_plugin;
+     679             : static molfile_plugin_t xtc_plugin;
+     680             : static molfile_plugin_t trj_plugin;
+     681             : 
+     682             : 
+     683        8374 : VMDPLUGIN_API int VMDPLUGIN_init() {
+     684             :   // GRO plugin init
+     685             :   memset(&gro_plugin, 0, sizeof(molfile_plugin_t));
+     686        8374 :   gro_plugin.abiversion = vmdplugin_ABIVERSION;
+     687        8374 :   gro_plugin.type = MOLFILE_PLUGIN_TYPE;
+     688        8374 :   gro_plugin.name = "gro";
+     689        8374 :   gro_plugin.prettyname = "Gromacs GRO";
+     690        8374 :   gro_plugin.author = "David Norris, Justin Gullingsrud, Magnus Lundborg";
+     691        8374 :   gro_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     692        8374 :   gro_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     693             :   gro_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     694        8374 :   gro_plugin.filename_extension = "gro";
+     695        8374 :   gro_plugin.open_file_read = open_gro_read;
+     696        8374 :   gro_plugin.read_structure = read_gro_structure;
+     697        8374 :   gro_plugin.read_next_timestep = read_gro_timestep;
+     698        8374 :   gro_plugin.close_file_read = close_gro_read;
+     699        8374 :   gro_plugin.open_file_write = open_gro_write;
+     700        8374 :   gro_plugin.write_structure = write_gro_structure;
+     701        8374 :   gro_plugin.write_timestep = write_gro_timestep;
+     702        8374 :   gro_plugin.close_file_write = close_gro_write;
+     703        8374 :   gro_plugin.read_molecule_metadata = read_gro_molecule_metadata;
+     704             : 
+     705             :   // G96 plugin init
+     706             :   memset(&g96_plugin, 0, sizeof(molfile_plugin_t));
+     707        8374 :   g96_plugin.abiversion = vmdplugin_ABIVERSION;
+     708        8374 :   g96_plugin.type = MOLFILE_PLUGIN_TYPE;
+     709        8374 :   g96_plugin.name = "g96";
+     710        8374 :   g96_plugin.prettyname = "Gromacs g96";
+     711        8374 :   g96_plugin.author = "David Norris, Justin Gullingsrud";
+     712        8374 :   g96_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     713        8374 :   g96_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     714             :   g96_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     715        8374 :   g96_plugin.filename_extension = "g96";
+     716        8374 :   g96_plugin.open_file_read = open_g96_read;
+     717        8374 :   g96_plugin.read_structure = read_g96_structure;
+     718        8374 :   g96_plugin.read_next_timestep = read_g96_timestep;
+     719        8374 :   g96_plugin.close_file_read = close_g96_read;
+     720             : 
+     721             :   // TRR plugin
+     722             :   memset(&trr_plugin, 0, sizeof(molfile_plugin_t));
+     723        8374 :   trr_plugin.abiversion = vmdplugin_ABIVERSION;
+     724        8374 :   trr_plugin.type = MOLFILE_PLUGIN_TYPE;
+     725        8374 :   trr_plugin.name = "trr";
+     726        8374 :   trr_plugin.prettyname = "Gromacs TRR Trajectory";
+     727        8374 :   trr_plugin.author = "David Norris, Justin Gullingsrud, Axel Kohlmeyer";
+     728        8374 :   trr_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     729        8374 :   trr_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     730             :   trr_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     731        8374 :   trr_plugin.filename_extension = "trr";
+     732        8374 :   trr_plugin.open_file_read = open_trr_read;
+     733        8374 :   trr_plugin.read_next_timestep = read_trr_timestep;
+     734        8374 :   trr_plugin.close_file_read = close_trr_read;
+     735        8374 :   trr_plugin.open_file_write = open_trr_write;
+     736        8374 :   trr_plugin.write_timestep = write_trr_timestep;
+     737        8374 :   trr_plugin.close_file_write = close_trr_write;
+     738             : 
+     739             :   // XTC plugin 
+     740             :   memset(&xtc_plugin, 0, sizeof(molfile_plugin_t));
+     741        8374 :   xtc_plugin.abiversion = vmdplugin_ABIVERSION;
+     742        8374 :   xtc_plugin.type = MOLFILE_PLUGIN_TYPE;
+     743        8374 :   xtc_plugin.name = "xtc";
+     744        8374 :   xtc_plugin.prettyname = "Gromacs XTC Compressed Trajectory";
+     745        8374 :   xtc_plugin.author = "David Norris, Justin Gullingsrud";
+     746        8374 :   xtc_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     747        8374 :   xtc_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     748             :   xtc_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     749        8374 :   xtc_plugin.filename_extension = "xtc";
+     750        8374 :   xtc_plugin.open_file_read = open_trr_read;
+     751        8374 :   xtc_plugin.read_next_timestep = read_trr_timestep;
+     752        8374 :   xtc_plugin.close_file_read = close_trr_read;
+     753             : 
+     754             :   // TRJ plugin
+     755             :   memset(&trj_plugin, 0, sizeof(molfile_plugin_t));
+     756        8374 :   trj_plugin.abiversion = vmdplugin_ABIVERSION;
+     757        8374 :   trj_plugin.type = MOLFILE_PLUGIN_TYPE;
+     758        8374 :   trj_plugin.name = "trj";
+     759        8374 :   trj_plugin.prettyname = "Gromacs TRJ Trajectory";
+     760        8374 :   trj_plugin.author = "David Norris, Justin Gullingsrud";
+     761        8374 :   trj_plugin.majorv = GROMACS_PLUGIN_MAJOR_VERSION;
+     762        8374 :   trj_plugin.minorv = GROMACS_PLUGIN_MINOR_VERSION;
+     763             :   trj_plugin.is_reentrant = VMDPLUGIN_THREADUNSAFE;
+     764        8374 :   trj_plugin.filename_extension = "trj";
+     765        8374 :   trj_plugin.open_file_read = open_trr_read;
+     766        8374 :   trj_plugin.read_next_timestep = read_trr_timestep;
+     767        8374 :   trj_plugin.close_file_read = close_trr_read;
+     768             : 
+     769        8374 :   return 0;
+     770             : }
+     771             : 
+     772        8374 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     773        8374 :   (*cb)(v, (vmdplugin_t *)&gro_plugin);
+     774        8374 :   (*cb)(v, (vmdplugin_t *)&g96_plugin);
+     775        8374 :   (*cb)(v, (vmdplugin_t *)&trr_plugin);
+     776        8374 :   (*cb)(v, (vmdplugin_t *)&trj_plugin);
+     777        8374 :   (*cb)(v, (vmdplugin_t *)&xtc_plugin);
+     778        8374 :   return 0;
+     779             : }
+     780             : 
+     781           0 : VMDPLUGIN_API int VMDPLUGIN_fini() {
+     782           0 :   return 0;
+     783             : }
+     784             : 
+     785             : }
+     786             : }
+     787             : 
+     788             : 
+     789             : #ifdef TEST_G96_PLUGIN
+     790             : 
+     791             : int main(int argc, char *argv[]) {
+     792             :   int natoms;
+     793             : 
+     794             :   molfile_timestep_t timestep;
+     795             :   void *v;
+     796             :   int i;
+     797             : 
+     798             :   if (argc < 2) return 1;
+     799             :   while (--argc) {
+     800             :     ++argv;
+     801             :     v = open_g96_read(*argv, "g96", &natoms);
+     802             :     if (!v) {
+     803             :       fprintf(stderr, "open_g96_read failed for file %s\n", *argv);
+     804             :       return 1;
+     805             :     }
+     806             :     timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
+     807             :     i = 0;
+     808             :     while(!read_g96_timestep(v, natoms, &timestep)) {
+     809             :       ++i;
+     810             :     }
+     811             :     fprintf(stderr, "ended read_g96_timestep on step %d\n", i);
+     812             :     free(timestep.coords);
+     813             :     close_g96_read(v);
+     814             :   }
+     815             :   return 0;
+     816             : }
+     817             : 
+     818             : #endif
+     819             : 
+     820             : #ifdef TEST_TRR_PLUGIN
+     821             : 
+     822             : int main(int argc, char *argv[]) {
+     823             :   int natoms;
+     824             : 
+     825             :   molfile_timestep_t timestep;
+     826             :   void *v, *w;
+     827             :   int i;
+     828             : 
+     829             :   if (argc != 3) return 1;
+     830             :   v = open_trr_read(argv[1], "trr", &natoms);
+     831             :   if (!v) {
+     832             :     fprintf(stderr, "open_trr_read failed for file %s\n", argv[1]);
+     833             :     return 1;
+     834             :   }
+     835             :   timestep.coords = (float *)malloc(3*sizeof(float)*natoms);
+     836             :   w = open_trr_write(argv[2], "trr", natoms);
+     837             :   if (!w) {
+     838             :     fprintf(stderr, "open_trr_write failed for file %s\n", argv[2]);
+     839             :     return 1;
+     840             :   }
+     841             : 
+     842             :   i = 0;
+     843             :   while(!read_trr_timestep(v, natoms, &timestep)) {
+     844             :     ++i;
+     845             :     if (write_trr_timestep(w, &timestep)) {
+     846             :       fprintf(stderr, "write error\n");
+     847             :       return 1;
+     848             :     }
+     849             :   }
+     850             : 
+     851             :   fprintf(stderr, "ended read_trr_timestep on step %d\n", i);
+     852             :   free(timestep.coords);
+     853             :   close_trr_read(v);
+     854             :   close_trr_write(w);
+     855             :   return 0;
+     856             : }
+     857             : 
+     858             : #endif
+     859             : 
+     860             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/index-sort-f.html b/coverage-libs/molfile/index-sort-f.html new file mode 100644 index 000000000000..f1f48f045677 --- /dev/null +++ b/coverage-libs/molfile/index-sort-f.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:861210440.9 %
Date:2024-02-22 21:58:47Functions:5612445.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
periodic_table.h +
0.0%
+
0.0 %0 / 200.0 %0 / 4
gromacsplugin.cpp +
29.7%29.7%
+
29.7 %107 / 36021.7 %5 / 23
endianswap.h +
12.5%12.5%
+
12.5 %6 / 4825.0 %1 / 4
pdbplugin.cpp +
41.2%41.2%
+
41.2 %87 / 21135.7 %5 / 14
readpdb.h +
32.6%32.6%
+
32.6 %44 / 13537.5 %3 / 8
dcdplugin.cpp +
43.6%43.6%
+
43.6 %201 / 46152.6 %10 / 19
crdplugin.cpp +
64.7%64.7%
+
64.7 %55 / 8555.6 %5 / 9
Gromacs.h +
45.6%45.6%
+
45.6 %342 / 75061.1 %22 / 36
fastio.h +
55.9%55.9%
+
55.9 %19 / 3471.4 %5 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/index-sort-l.html b/coverage-libs/molfile/index-sort-l.html new file mode 100644 index 000000000000..675106ed6c8d --- /dev/null +++ b/coverage-libs/molfile/index-sort-l.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:861210440.9 %
Date:2024-02-22 21:58:47Functions:5612445.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
periodic_table.h +
0.0%
+
0.0 %0 / 200.0 %0 / 4
endianswap.h +
12.5%12.5%
+
12.5 %6 / 4825.0 %1 / 4
gromacsplugin.cpp +
29.7%29.7%
+
29.7 %107 / 36021.7 %5 / 23
readpdb.h +
32.6%32.6%
+
32.6 %44 / 13537.5 %3 / 8
pdbplugin.cpp +
41.2%41.2%
+
41.2 %87 / 21135.7 %5 / 14
dcdplugin.cpp +
43.6%43.6%
+
43.6 %201 / 46152.6 %10 / 19
Gromacs.h +
45.6%45.6%
+
45.6 %342 / 75061.1 %22 / 36
fastio.h +
55.9%55.9%
+
55.9 %19 / 3471.4 %5 / 7
crdplugin.cpp +
64.7%64.7%
+
64.7 %55 / 8555.6 %5 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/index.html b/coverage-libs/molfile/index.html new file mode 100644 index 000000000000..6df997ea5de0 --- /dev/null +++ b/coverage-libs/molfile/index.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:861210440.9 %
Date:2024-02-22 21:58:47Functions:5612445.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Gromacs.h +
45.6%45.6%
+
45.6 %342 / 75061.1 %22 / 36
crdplugin.cpp +
64.7%64.7%
+
64.7 %55 / 8555.6 %5 / 9
dcdplugin.cpp +
43.6%43.6%
+
43.6 %201 / 46152.6 %10 / 19
endianswap.h +
12.5%12.5%
+
12.5 %6 / 4825.0 %1 / 4
fastio.h +
55.9%55.9%
+
55.9 %19 / 3471.4 %5 / 7
gromacsplugin.cpp +
29.7%29.7%
+
29.7 %107 / 36021.7 %5 / 23
pdbplugin.cpp +
41.2%41.2%
+
41.2 %87 / 21135.7 %5 / 14
periodic_table.h +
0.0%
+
0.0 %0 / 200.0 %0 / 4
readpdb.h +
32.6%32.6%
+
32.6 %44 / 13537.5 %3 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/pdbplugin.cpp.func-sort-c.html b/coverage-libs/molfile/pdbplugin.cpp.func-sort-c.html new file mode 100644 index 000000000000..80e845a33028 --- /dev/null +++ b/coverage-libs/molfile/pdbplugin.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/pdbplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - pdbplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8721141.2 %
Date:2024-02-22 21:58:47Functions:51435.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_pdbplugin_finiEv0
_ZN4PLMD7molfileL10read_bondsEPvPiPS2_S3_PPfS3_S2_PPPc0
_ZN4PLMD7molfileL12write_cryst1EP8_IO_FILEPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL14write_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL15open_file_writeEPKcS2_i0
_ZN4PLMD7molfileL15write_structureEPviPKNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL16close_file_writeEPv0
_ZN4PLMD7molfileL18read_pdb_structureEPvPiPNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL22read_molecule_metadataEPvPPNS0_18molfile_metadata_tE0
_ZN4PLMD7molfileL13open_pdb_readEPKcS2_Pi53
_ZN4PLMD7molfileL14close_pdb_readEPv53
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE117
_ZN4PLMD7molfile22molfile_pdbplugin_initEv8374
_ZN4PLMD7molfile26molfile_pdbplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8374
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/pdbplugin.cpp.func.html b/coverage-libs/molfile/pdbplugin.cpp.func.html new file mode 100644 index 000000000000..07a096e6b552 --- /dev/null +++ b/coverage-libs/molfile/pdbplugin.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/pdbplugin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - pdbplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8721141.2 %
Date:2024-02-22 21:58:47Functions:51435.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfile22molfile_pdbplugin_finiEv0
_ZN4PLMD7molfile22molfile_pdbplugin_initEv8374
_ZN4PLMD7molfile26molfile_pdbplugin_registerEPvPFiS1_PNS0_11vmdplugin_tEE8374
_ZN4PLMD7molfileL10read_bondsEPvPiPS2_S3_PPfS3_S2_PPPc0
_ZN4PLMD7molfileL12write_cryst1EP8_IO_FILEPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL13open_pdb_readEPKcS2_Pi53
_ZN4PLMD7molfileL14close_pdb_readEPv53
_ZN4PLMD7molfileL14write_timestepEPvPKNS0_18molfile_timestep_tE0
_ZN4PLMD7molfileL15open_file_writeEPKcS2_i0
_ZN4PLMD7molfileL15write_structureEPviPKNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL16close_file_writeEPv0
_ZN4PLMD7molfileL18read_next_timestepEPviPNS0_18molfile_timestep_tE117
_ZN4PLMD7molfileL18read_pdb_structureEPvPiPNS0_14molfile_atom_tE0
_ZN4PLMD7molfileL22read_molecule_metadataEPvPPNS0_18molfile_metadata_tE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/pdbplugin.cpp.gcov.html b/coverage-libs/molfile/pdbplugin.cpp.gcov.html new file mode 100644 index 000000000000..781ef4090b2d --- /dev/null +++ b/coverage-libs/molfile/pdbplugin.cpp.gcov.html @@ -0,0 +1,725 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/pdbplugin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - pdbplugin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:8721141.2 %
Date:2024-02-22 21:58:47Functions:51435.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : University of Illinois Open Source License
+       3             : Copyright 2003 Theoretical and Computational Biophysics Group, 
+       4             : All rights reserved.
+       5             : 
+       6             : Developed by:           Theoretical and Computational Biophysics Group
+       7             :                         University of Illinois at Urbana-Champaign
+       8             :                         http://www.ks.uiuc.edu/
+       9             : 
+      10             : Permission is hereby granted, free of charge, to any person obtaining a copy of
+      11             : this software and associated documentation files (the Software), to deal with 
+      12             : the Software without restriction, including without limitation the rights to 
+      13             : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+      14             : of the Software, and to permit persons to whom the Software is furnished to 
+      15             : do so, subject to the following conditions:
+      16             : 
+      17             : Redistributions of source code must retain the above copyright notice, 
+      18             : this list of conditions and the following disclaimers.
+      19             : 
+      20             : Redistributions in binary form must reproduce the above copyright notice, 
+      21             : this list of conditions and the following disclaimers in the documentation 
+      22             : and/or other materials provided with the distribution.
+      23             : 
+      24             : Neither the names of Theoretical and Computational Biophysics Group, 
+      25             : University of Illinois at Urbana-Champaign, nor the names of its contributors 
+      26             : may be used to endorse or promote products derived from this Software without 
+      27             : specific prior written permission.
+      28             : 
+      29             : THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+      30             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+      31             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
+      32             : THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
+      33             : OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+      34             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
+      35             : OTHER DEALINGS WITH THE SOFTWARE.
+      36             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      37             : #if defined(__PLUMED_HAS_MOLFILE_PLUGINS) && ! defined(__PLUMED_HAS_EXTERNAL_MOLFILE_PLUGINS)
+      38             : /***************************************************************************
+      39             :  *cr
+      40             :  *cr            (C) Copyright 1995-2016 The Board of Trustees of the
+      41             :  *cr                        University of Illinois
+      42             :  *cr                         All Rights Reserved
+      43             :  *cr
+      44             :  ***************************************************************************/
+      45             : 
+      46             : /***************************************************************************
+      47             :  * RCS INFORMATION:
+      48             :  *
+      49             :  *      $RCSfile: pdbplugin.c,v $
+      50             :  *      $Author: johns $       $Locker:  $             $State: Exp $
+      51             :  *      $Revision: 1.73 $       $Date: 2016/11/28 05:01:54 $
+      52             :  *
+      53             :  ***************************************************************************/
+      54             : 
+      55             : /*
+      56             :  * PDB file format specifications:
+      57             :  *   http://www.rcsb.org/pdb/static.do?p=file_formats/pdb/index.html
+      58             :  */
+      59             : 
+      60             : #include "largefiles.h"   /* platform dependent 64-bit file I/O defines */
+      61             : 
+      62             : #include "molfile_plugin.h"
+      63             : #include "readpdb.h"
+      64             : #include "periodic_table.h"
+      65             : #include <stdio.h>
+      66             : #include <stdlib.h>
+      67             : #include <string.h>
+      68             : 
+      69             : namespace PLMD{
+      70             : namespace molfile{
+      71             : 
+      72             : /*
+      73             :  * API functions start here
+      74             :  */
+      75             : 
+      76             : typedef struct {
+      77             :   FILE *fd;
+      78             :   int first_frame;
+      79             :   int natoms;
+      80             :   molfile_atom_t *atomlist;
+      81             :   molfile_metadata_t *meta;
+      82             :   int nconect;
+      83             :   int nbonds, maxbnum;
+      84             :   int *from, *to, *idxmap;
+      85             : } pdbdata;
+      86             : 
+      87          53 : static void *open_pdb_read(const char *filepath, const char *filetype, 
+      88             :     int *natoms) {
+      89             :   FILE *fd;
+      90             :   pdbdata *pdb;
+      91             :   char pdbstr[PDB_BUFFER_LENGTH];
+      92             :   int indx, nconect;
+      93             : 
+      94          53 :   fd = fopen(filepath, "r");
+      95          53 :   if (!fd) 
+      96             :     return NULL;
+      97          53 :   pdb = (pdbdata *)malloc(sizeof(pdbdata));
+      98          53 :   pdb->fd = fd;
+      99          53 :   pdb->meta = (molfile_metadata_t *) malloc(sizeof(molfile_metadata_t));
+     100             :   memset(pdb->meta, 0, sizeof(molfile_metadata_t));
+     101             : 
+     102             :   pdb->meta->remarklen = 0;
+     103             :   pdb->meta->remarks = NULL;
+     104             : 
+     105          53 :   *natoms=0;
+     106             :   nconect=0;
+     107             :   do {
+     108      102465 :     indx = read_pdb_record(pdb->fd, pdbstr);
+     109      102465 :     if (indx == PDB_ATOM) {
+     110      102222 :       *natoms += 1;
+     111         243 :     } else if (indx == PDB_CONECT) {
+     112           0 :       nconect++;
+     113         243 :     } else if (indx == PDB_HEADER) {
+     114           0 :       get_pdb_header(pdbstr, pdb->meta->accession, pdb->meta->date, NULL);
+     115           0 :       if (strlen(pdb->meta->accession) > 0) 
+     116           0 :         strcpy(pdb->meta->database, "PDB");
+     117         243 :     } else if (indx == PDB_REMARK || indx == PDB_CONECT || indx == PDB_UNKNOWN) {
+     118         156 :       int len=strlen(pdbstr);
+     119         156 :       int newlen = len + pdb->meta->remarklen;
+     120             : 
+     121         156 :       char *newstr=(char*)realloc(pdb->meta->remarks, newlen + 1);
+     122         156 :       if (newstr != NULL) {
+     123         156 :         pdb->meta->remarks = newstr;
+     124         156 :         pdb->meta->remarks[pdb->meta->remarklen] = '\0';
+     125         156 :         memcpy(pdb->meta->remarks + pdb->meta->remarklen, pdbstr, len);
+     126         156 :         pdb->meta->remarks[newlen] = '\0';
+     127         156 :         pdb->meta->remarklen = newlen;
+     128             :       }
+     129             :     }
+     130             :  
+     131      102465 :   } while (indx != PDB_END && indx != PDB_EOF);
+     132             : 
+     133             :   /* If no atoms were found, this is probably not a PDB file! */
+     134          53 :   if (!*natoms) {
+     135           0 :     fprintf(stderr, "PDB file '%s' contains no atoms.\n", filepath);
+     136           0 :     if (pdb->meta->remarks != NULL)
+     137           0 :       free(pdb->meta->remarks);
+     138           0 :     if (pdb->meta != NULL)
+     139           0 :       free(pdb->meta);
+     140           0 :     free(pdb);
+     141           0 :     return NULL;
+     142             :   }
+     143             : 
+     144          53 :   rewind(pdb->fd); /* if ok, rewind file and prepare to parse it for real */
+     145          53 :   pdb->natoms = *natoms;
+     146          53 :   pdb->nconect = nconect;
+     147          53 :   pdb->nbonds = 0;
+     148          53 :   pdb->maxbnum = 0;
+     149          53 :   pdb->from = NULL;
+     150          53 :   pdb->to = NULL;
+     151          53 :   pdb->idxmap = NULL;
+     152          53 :   pdb->atomlist = NULL;
+     153             : 
+     154             : #if defined(VMDUSECONECTRECORDS)
+     155             :   /* allocate atom index translation table if we have 99,999 atoms or less */
+     156             :   /* and we have conect records to process                                 */
+     157          53 :   if (pdb->natoms < 100000 && pdb->nconect > 0) {
+     158           0 :     pdb->idxmap = (int *) malloc(100000 * sizeof(int));
+     159             :     memset(pdb->idxmap, 0, 100000 * sizeof(int));
+     160             :   }
+     161             : #endif
+     162             :  
+     163             :   return pdb; 
+     164             : }
+     165             : 
+     166           0 : static int read_pdb_structure(void *mydata, int *optflags, 
+     167             :     molfile_atom_t *atoms) { 
+     168             :   pdbdata *pdb = (pdbdata *)mydata;
+     169             :   molfile_atom_t *atom;
+     170             :   char pdbrec[PDB_BUFFER_LENGTH];
+     171             :   int i, rectype, atomserial, pteidx;
+     172             :   char ridstr[8];
+     173             :   char elementsymbol[3];
+     174             :   int badptecount = 0;
+     175           0 :   long fpos = ftell(pdb->fd);
+     176             : 
+     177           0 :   *optflags = MOLFILE_INSERTION | MOLFILE_OCCUPANCY | MOLFILE_BFACTOR |
+     178             :               MOLFILE_ALTLOC | MOLFILE_ATOMICNUMBER | MOLFILE_BONDSSPECIAL;
+     179             : 
+     180             :   i = 0;
+     181             :   do {
+     182           0 :     rectype = read_pdb_record(pdb->fd, pdbrec);
+     183           0 :     switch (rectype) {
+     184           0 :     case PDB_ATOM:
+     185           0 :       atom = atoms+i;
+     186           0 :       get_pdb_fields(pdbrec, strlen(pdbrec), &atomserial, 
+     187           0 :           atom->name, atom->resname, atom->chain, atom->segid, 
+     188           0 :           ridstr, atom->insertion, atom->altloc, elementsymbol,
+     189             :           NULL, NULL, NULL, &atom->occupancy, &atom->bfactor);
+     190             : 
+     191           0 :       if (pdb->idxmap != NULL && atomserial < 100000) {
+     192           0 :         pdb->idxmap[atomserial] = i; /* record new serial number translation */ 
+     193             :       }
+     194             :  
+     195           0 :       atom->resid = atoi(ridstr);
+     196             : 
+     197             :       /* determine atomic number from the element symbol */
+     198           0 :       pteidx = get_pte_idx_from_string(elementsymbol);
+     199           0 :       atom->atomicnumber = pteidx;
+     200           0 :       if (pteidx != 0) {
+     201           0 :         atom->mass = get_pte_mass(pteidx);
+     202           0 :         atom->radius = get_pte_vdw_radius(pteidx);
+     203             :       } else {
+     204           0 :         badptecount++; /* unrecognized element */
+     205             :       }
+     206             :  
+     207           0 :       strcpy(atom->type, atom->name);
+     208           0 :       i++;
+     209           0 :       break;
+     210             : 
+     211           0 :     case PDB_CONECT:
+     212             :       /* only read CONECT records for structures where we know they can */
+     213             :       /* be valid for all of the atoms in the structure                 */
+     214           0 :       if (pdb->idxmap != NULL) {
+     215           0 :         get_pdb_conect(pdbrec, pdb->natoms, pdb->idxmap, 
+     216             :                        &pdb->maxbnum, &pdb->nbonds, &pdb->from, &pdb->to);
+     217             :       }
+     218             :       break;
+     219             : 
+     220             :     default:
+     221             :       /* other record types are ignored in the structure callback */
+     222             :       /* and are dealt with in the timestep callback or elsewhere */
+     223             :       break;
+     224             :     }
+     225           0 :   } while (rectype != PDB_END && rectype != PDB_EOF);
+     226             : 
+     227           0 :   fseek(pdb->fd, fpos, SEEK_SET);
+     228             : 
+     229             :   /* if all atoms are recognized, set the mass and radius flags too,  */
+     230             :   /* otherwise let VMD guess these for itself using it's own methods  */
+     231           0 :   if (badptecount == 0) {
+     232           0 :     *optflags |= MOLFILE_MASS | MOLFILE_RADIUS;
+     233             :   }
+     234             : 
+     235           0 :   return MOLFILE_SUCCESS;
+     236             : }
+     237             : 
+     238           0 : static int read_bonds(void *v, int *nbonds, int **fromptr, int **toptr, 
+     239             :                       float ** bondorder,int **bondtype, 
+     240             :                       int *nbondtypes, char ***bondtypename) {
+     241             :   pdbdata *pdb = (pdbdata *)v;
+     242             :   
+     243           0 :   *nbonds = 0;
+     244           0 :   *fromptr = NULL;
+     245           0 :   *toptr = NULL;
+     246           0 :   *bondorder = NULL; /* PDB files don't have bond order information */
+     247           0 :   *bondtype = NULL;
+     248           0 :   *nbondtypes = 0;
+     249           0 :   *bondtypename = NULL;
+     250             : 
+     251             : /* The newest plugin API allows us to return CONECT records as 
+     252             :  * additional bonds above and beyond what the distance search returns.
+     253             :  * Without that feature, we otherwise have to check completeness and
+     254             :  * ignore them if they don't look to be fully specified for this molecule */
+     255             : #if !defined(MOLFILE_BONDSSPECIAL)
+     256             :   if (pdb->natoms >= 100000) {
+     257             :     printf("pdbplugin) Warning: more than 99,999 atoms, ignored CONECT records\n");
+     258             :     return MOLFILE_SUCCESS;
+     259             :   } else if (((float) pdb->nconect / (float) pdb->natoms) <= 0.85) {
+     260             :     printf("pdbplugin) Warning: Probable incomplete bond structure specified,\n");
+     261             :     printf("pdbplugin)          ignoring CONECT records\n");
+     262             :     return MOLFILE_SUCCESS;
+     263             :   } else if (pdb->nconect == 0) {
+     264             :     return MOLFILE_SUCCESS;
+     265             :   }
+     266             : #endif
+     267             : 
+     268           0 :   *nbonds = pdb->nbonds;
+     269           0 :   *fromptr = pdb->from;
+     270           0 :   *toptr = pdb->to;
+     271             : 
+     272           0 :   return MOLFILE_SUCCESS;
+     273             : }
+     274             : 
+     275             : 
+     276             : /* 
+     277             :  * 
+     278             :  */
+     279         117 : static int read_next_timestep(void *v, int natoms, molfile_timestep_t *ts) {
+     280             :   pdbdata *pdb = (pdbdata *)v;
+     281             :   char pdbstr[PDB_BUFFER_LENGTH];
+     282             :   int indx, i;
+     283             :   float *x, *y, *z;
+     284             :   float occup, bfac;
+     285         117 :   if (pdb->natoms == 0) 
+     286             :     return MOLFILE_ERROR; /* EOF */
+     287         117 :   if (ts) {
+     288         117 :     x = ts->coords;
+     289         117 :     y = x+1;
+     290         117 :     z = x+2;
+     291             :   } else {
+     292             :     x = y = z = 0;
+     293             :   } 
+     294             :   i = 0;
+     295             :   do {
+     296      106645 :     indx = read_pdb_record(pdb->fd, pdbstr);
+     297      106645 :     if((indx == PDB_END || indx == PDB_EOF) && (i < pdb->natoms)) {
+     298             :       return MOLFILE_ERROR;
+     299      106592 :     } else if(indx == PDB_ATOM) {
+     300      106320 :       if(i++ >= pdb->natoms) {
+     301             :         break;      
+     302             :       }
+     303             :       /* just get the coordinates, and store them */
+     304      106320 :       if (ts) {
+     305      106320 :         get_pdb_coordinates(pdbstr, x, y, z, &occup, &bfac);
+     306      106320 :         x += 3;
+     307      106320 :         y += 3;
+     308      106320 :         z += 3;
+     309             :       } 
+     310         272 :     } else if (indx == PDB_CRYST1) {
+     311          36 :       if (ts) {
+     312          36 :         get_pdb_cryst1(pdbstr, &ts->alpha, &ts->beta, &ts->gamma,
+     313             :                                &ts->A, &ts->B, &ts->C);
+     314             :       }
+     315             :     }
+     316      106592 :   } while(!(indx == PDB_END || indx == PDB_EOF));
+     317             : 
+     318             :   return MOLFILE_SUCCESS;
+     319             : }
+     320             : 
+     321          53 : static void close_pdb_read(void *v) { 
+     322             :   pdbdata *pdb = (pdbdata *)v;
+     323          53 :   if (pdb->fd != NULL)
+     324          53 :     fclose(pdb->fd);
+     325          53 :   if (pdb->idxmap != NULL)
+     326           0 :     free(pdb->idxmap);
+     327          53 :   if (pdb->meta->remarks != NULL)
+     328          42 :     free(pdb->meta->remarks);
+     329          53 :   if (pdb->meta != NULL) 
+     330          53 :     free(pdb->meta);
+     331          53 :   free(pdb);
+     332          53 : }
+     333             : 
+     334           0 : static void *open_file_write(const char *path, const char *filetype, 
+     335             :     int natoms) {
+     336             : 
+     337             :   FILE *fd;
+     338             :   pdbdata *pdb;
+     339           0 :   fd = fopen(path, "w");
+     340           0 :   if (!fd) {
+     341           0 :     fprintf(stderr, "Unable to open file %s for writing\n", path);
+     342           0 :     return NULL;
+     343             :   }
+     344           0 :   pdb = (pdbdata *)malloc(sizeof(pdbdata));
+     345           0 :   pdb->fd = fd;
+     346           0 :   pdb->natoms = natoms; 
+     347           0 :   pdb->atomlist = NULL;
+     348           0 :   pdb->first_frame = 1;
+     349           0 :   return pdb;
+     350             : }
+     351             :  
+     352           0 : static int write_structure(void *v, int optflags, 
+     353             :     const molfile_atom_t *atoms) {
+     354             : 
+     355             :   int i;
+     356             :   pdbdata *pdb = (pdbdata *)v;
+     357           0 :   int natoms = pdb->natoms;
+     358           0 :   pdb->atomlist = (molfile_atom_t *)malloc(natoms*sizeof(molfile_atom_t));
+     359             :   memcpy(pdb->atomlist, atoms, natoms*sizeof(molfile_atom_t));
+     360             : 
+     361             :   /* If occ, bfactor, and insertion aren't given, we assign defaultvalues. */
+     362           0 :   if (!(optflags & MOLFILE_OCCUPANCY)) {
+     363           0 :     for (i=0; i<natoms; i++) pdb->atomlist[i].occupancy = 0.0f;
+     364             :   }
+     365           0 :   if (!(optflags & MOLFILE_BFACTOR)) {
+     366           0 :     for (i=0; i<natoms; i++) pdb->atomlist[i].bfactor= 0.0f;
+     367             :   }
+     368           0 :   if (!(optflags & MOLFILE_INSERTION)) {
+     369           0 :     for (i=0; i<natoms; i++) {
+     370           0 :       pdb->atomlist[i].insertion[0] =' ';
+     371           0 :       pdb->atomlist[i].insertion[1] ='\0';
+     372             :     }
+     373             :   }
+     374           0 :   if (!(optflags & MOLFILE_ALTLOC)) {
+     375           0 :     for (i=0; i<natoms; i++) {
+     376           0 :       pdb->atomlist[i].altloc[0]=' ';
+     377           0 :       pdb->atomlist[i].altloc[1]='\0';
+     378             :     }
+     379             :   }
+     380           0 :   if (!(optflags & MOLFILE_ATOMICNUMBER)) {
+     381           0 :     for (i=0; i<natoms; i++) pdb->atomlist[i].atomicnumber = 0;
+     382             :   }
+     383             : 
+     384             :   /* TODO: put bonds into CONECT records? */
+     385           0 :   return MOLFILE_SUCCESS;
+     386             : }
+     387             : 
+     388             : /* SEQRES records look like this:
+     389             : 
+     390             : COLUMNS        DATA TYPE       FIELD         DEFINITION
+     391             : ---------------------------------------------------------------------------------
+     392             :  1 -  6        Record name     "SEQRES"
+     393             : 
+     394             :  9 - 10        Integer         serNum        Serial number of the SEQRES record
+     395             :                                              for the current chain.  Starts at 1
+     396             :                                              and increments by one each line.
+     397             :                                              Reset to 1 for each chain.
+     398             : 
+     399             : 12             Character       chainID       Chain identifier.  This may be any
+     400             :                                              single legal character, including a
+     401             :                                              blank which is used if there is
+     402             :                                              only one chain.
+     403             : 
+     404             : 14 - 17        Integer         numRes        Number of residues in the chain.
+     405             :                                              This value is repeated on every
+     406             :                                              record.
+     407             : 
+     408             : 20 - 22        Residue name    resName       Residue name.
+     409             : 
+     410             : 24 - 26        Residue name    resName       Residue name.
+     411             : 
+     412             : ... and so forth out to 68-70, for a total of 13 in each line (except possibly
+     413             : the last.
+     414             : 
+     415             : source:
+     416             : http://www.rcsb.org/pdb/file_formats/pdb/pdbguide2.2/part_35.html
+     417             : */
+     418             : 
+     419             : /*
+     420             :  * However, we don't use them right now because of several issues that
+     421             :  * can't presently be resolved satisfactorily in VMD:
+     422             : 
+     423             : According to the RCSB, SEQRES records have to contain all residues, not
+     424             : just those in the structure, which means VMD will usually produce incorrect
+     425             : output and there's nothing we can do about it.  The RCSB actually specifies
+     426             : that all residues in the chain have to present in the SEQRES records, even
+     427             : if they're not in the structure.
+     428             :   
+     429             : We can never know which residues to output.  Our current system of outputting   
+     430             : everything is just terrible when you have 20,000 waters in your system; we
+     431             : have to fix this immediately.  We could almost get away with making a hash
+     432             : table of the names of protein and nucleic acid residues and only write chains
+     433             : containing those residues.  However, there's this little snippet from the
+     434             : specification:
+     435             :   
+     436             : * Heterogens which are integrated into the backbone of the chain are listed
+     437             :   as being part of the chain and are included in the SEQRES records for
+     438             :   that chain.
+     439             :   
+     440             : That means that we can never know what might appear in the sequence unless we
+     441             : also read HET records and keep track of them in VMD as well.  We shouldn't 
+     442             : get people depending on such fallible SEQRES records.
+     443             :   
+     444             : And of course, there's the fact that no other program that we know of besides   
+     445             : CE needs these SEQRES records.
+     446             : 
+     447             :  * Uncomment the write_seqres line in write_timestep to turn them back on.
+     448             :  */
+     449             : 
+     450             : 
+     451             : #if 0
+     452             : static void write_seqres(FILE * fd, int natoms, const molfile_atom_t *atomlist) {
+     453             :   int i=0;
+     454             :   while (i < natoms) {
+     455             :     int k, serNum;
+     456             :     int j = i;
+     457             :     int ires, nres = 1;
+     458             :     int resid = atomlist[i].resid;
+     459             :     /* Count up the number of residues in the chain */
+     460             :     const char *chain = atomlist[i].chain;
+     461             :     while (j < natoms && !strcmp(chain, atomlist[j].chain)) {
+     462             :       if (resid != atomlist[j].resid) {
+     463             :         nres++;
+     464             :         resid = atomlist[j].resid;
+     465             :       }
+     466             :       j++;
+     467             :     }
+     468             :     /* There are nres residues in the chain, from atoms i to j. */
+     469             :     serNum = 1;
+     470             :     ires = 1;
+     471             :     resid = atomlist[i].resid;
+     472             :     fprintf(fd, "SEQRES  %2d %c %4d  ",  serNum, chain[0], nres);
+     473             :     serNum = 2;
+     474             :     fprintf(fd, "%3s ", atomlist[i].resname);
+     475             :     for (k=i; k<j; k++) {
+     476             :       if (resid != atomlist[k].resid) {
+     477             :         resid = atomlist[k].resid;
+     478             :         if (!(ires % 13)) {
+     479             :           fprintf(fd, "\nSEQRES  %2d %c %4d  ",  serNum, chain[0], nres);
+     480             :           serNum++;
+     481             :         }
+     482             :         fprintf(fd, "%3s ", atomlist[k].resname);
+     483             :         ires++;
+     484             :       }
+     485             :     }
+     486             :     i = j;
+     487             :     fprintf(fd, "\n");
+     488             :   }
+     489             : }
+     490             : #endif
+     491             : 
+     492             : /*
+     493             : CRYST1 records look like this:
+     494             : The CRYST1 record presents the unit cell parameters, space group, and Z value. If the structure was not determined by crystallographic means, CRYST1 simply defines a unit cube. 
+     495             : 
+     496             : 
+     497             : Record Format 
+     498             : 
+     499             : COLUMNS       DATA TYPE      FIELD         DEFINITION
+     500             : -------------------------------------------------------------
+     501             :  1 -  6       Record name    "CRYST1"
+     502             : 
+     503             :  7 - 15       Real(9.3)      a             a (Angstroms).
+     504             : 
+     505             : 16 - 24       Real(9.3)      b             b (Angstroms).
+     506             : 
+     507             : 25 - 33       Real(9.3)      c             c (Angstroms).
+     508             : 
+     509             : 34 - 40       Real(7.2)      alpha         alpha (degrees).
+     510             : 
+     511             : 41 - 47       Real(7.2)      beta          beta (degrees).
+     512             : 
+     513             : 48 - 54       Real(7.2)      gamma         gamma (degrees).
+     514             : 
+     515             : 56 - 66       LString        sGroup        Space group.
+     516             : 
+     517             : 67 - 70       Integer        z             Z value.
+     518             : 
+     519             : * If the coordinate entry describes a structure determined by a technique
+     520             : other than crystallography, CRYST1 contains a = b = c = 1.0, alpha =
+     521             : beta = gamma = 90 degrees, space group = P 1, and Z = 1.
+     522             : 
+     523             : We will use "P 1" and "1" for space group and z value, as recommended, but
+     524             : we'll populate the other fields with the unit cell information we do have.
+     525             : 
+     526             : */
+     527             :   
+     528           0 : static void write_cryst1(FILE *fd, const molfile_timestep_t *ts) {
+     529           0 :   fprintf(fd, "CRYST1%9.3f%9.3f%9.3f%7.2f%7.2f%7.2f P 1           1\n", 
+     530           0 :     ts->A, ts->B, ts->C, ts->alpha, ts->beta, ts->gamma);
+     531           0 : }
+     532             : 
+     533             : 
+     534           0 : static int write_timestep(void *v, const molfile_timestep_t *ts) {
+     535             :   pdbdata *pdb = (pdbdata *)v; 
+     536             :   const molfile_atom_t *atom;
+     537             :   const float *pos;
+     538             :   int i;
+     539             :   char elementsymbol[3];
+     540             : 
+     541           0 :   if (pdb->natoms == 0)
+     542             :     return MOLFILE_SUCCESS;
+     543             : 
+     544           0 :   if (pdb->first_frame) {
+     545             :     /* Turn off SEQRES writing for now; see comments above.
+     546             :     write_seqres(pdb->fd, pdb->natoms, pdb->atomlist);
+     547             :     */
+     548           0 :     write_cryst1(pdb->fd, ts);
+     549           0 :     pdb->first_frame = 0;
+     550             :   }
+     551           0 :   atom = pdb->atomlist;
+     552           0 :   pos = ts->coords;
+     553           0 :   for (i=0; i<pdb->natoms; i++) {
+     554             :     /*
+     555             :      * The 8.3 format for position, occupancy, and bfactor permits values 
+     556             :      * only in the range of -999.9994 to 9999.9994 (so that they round
+     557             :      * to the range [-999.999, 9999.999]).  If values fall outside of that
+     558             :      * range, fail and emit an error message rather than generate a
+     559             :      * misformatted PDB file.
+     560             :      */
+     561             : #define PDBBAD(x) ((x) < -999.9994f || (x) > 9999.9994f)
+     562           0 :     if (PDBBAD(pos[0]) || PDBBAD(pos[1]) || PDBBAD(pos[2]) ||
+     563           0 :                 PDBBAD(atom->occupancy) || PDBBAD(atom->bfactor)) {
+     564           0 :             fprintf(stderr, "PDB WRITE ERROR: Position, occupancy, or b-factor (beta) for atom %d\n", i);
+     565           0 :       fprintf(stderr, "                 cannot be written in PDB format.\n");
+     566           0 :       fprintf(stderr, "                 File will be truncated.\n");
+     567           0 :       return MOLFILE_ERROR;
+     568             :     }
+     569             : 
+     570             :     /* check the atomicnumber and format the atomic element symbol string */
+     571           0 :     strcpy(elementsymbol, (atom->atomicnumber < 1) ? "  " : get_pte_label(atom->atomicnumber));
+     572           0 :     elementsymbol[0] = toupper(elementsymbol[0]);
+     573           0 :     elementsymbol[1] = toupper(elementsymbol[1]);
+     574             :  
+     575           0 :     if (!write_raw_pdb_record(pdb->fd,  
+     576           0 :         "ATOM  ", i+1, atom->name, atom->resname, atom->resid, 
+     577           0 :         atom->insertion, atom->altloc, elementsymbol,
+     578             :         pos[0], pos[1], pos[2], 
+     579           0 :         atom->occupancy, atom->bfactor, atom->chain, atom->segid)) {
+     580           0 :       fprintf(stderr, 
+     581             :           "PDB: Error encountered writing atom %d; file may be incomplete.\n",
+     582             :           i+1);
+     583           0 :       return MOLFILE_ERROR;
+     584             :     }
+     585           0 :     ++atom;
+     586           0 :     pos += 3;
+     587             :   }
+     588           0 :   fprintf(pdb->fd, "END\n");
+     589             : 
+     590             :   return MOLFILE_SUCCESS;
+     591             : }
+     592             :  
+     593           0 : static void close_file_write(void *v) {
+     594             :   pdbdata *pdb = (pdbdata *)v; 
+     595           0 :   fclose(pdb->fd);
+     596           0 :   free(pdb->atomlist);
+     597           0 :   free(pdb);
+     598           0 : }
+     599             : 
+     600           0 : static int read_molecule_metadata(void *v, molfile_metadata_t **metadata) {
+     601             :   pdbdata *pdb = (pdbdata *)v; 
+     602           0 :   *metadata = pdb->meta;
+     603           0 :   return MOLFILE_SUCCESS;
+     604             : }
+     605             : 
+     606             : /*
+     607             :  * Initialization stuff down here
+     608             :  */
+     609             : 
+     610             : static molfile_plugin_t plugin;
+     611             :  
+     612        8374 : VMDPLUGIN_API int VMDPLUGIN_init() {
+     613             :   memset(&plugin, 0, sizeof(molfile_plugin_t));
+     614        8374 :   plugin.abiversion = vmdplugin_ABIVERSION;
+     615        8374 :   plugin.type = MOLFILE_PLUGIN_TYPE;
+     616        8374 :   plugin.name = "pdb";
+     617        8374 :   plugin.prettyname = "PDB";
+     618        8374 :   plugin.author = "Justin Gullingsrud, John Stone";
+     619        8374 :   plugin.majorv = 1;
+     620        8374 :   plugin.minorv = 16;
+     621        8374 :   plugin.is_reentrant = VMDPLUGIN_THREADSAFE;
+     622        8374 :   plugin.filename_extension = "pdb,ent";
+     623        8374 :   plugin.open_file_read = open_pdb_read;
+     624        8374 :   plugin.read_structure = read_pdb_structure;
+     625        8374 :   plugin.read_bonds = read_bonds;
+     626        8374 :   plugin.read_next_timestep = read_next_timestep;
+     627        8374 :   plugin.close_file_read = close_pdb_read;
+     628        8374 :   plugin.open_file_write = open_file_write;
+     629        8374 :   plugin.write_structure = write_structure;
+     630        8374 :   plugin.write_timestep = write_timestep;
+     631        8374 :   plugin.close_file_write = close_file_write;
+     632        8374 :   plugin.read_molecule_metadata = read_molecule_metadata;
+     633        8374 :   return VMDPLUGIN_SUCCESS;
+     634             : }
+     635             : 
+     636        8374 : VMDPLUGIN_API int VMDPLUGIN_register(void *v, vmdplugin_register_cb cb) {
+     637        8374 :   (*cb)(v, (vmdplugin_t *)&plugin);
+     638        8374 :   return VMDPLUGIN_SUCCESS;
+     639             : }
+     640             : 
+     641           0 : VMDPLUGIN_API int VMDPLUGIN_fini() {
+     642           0 :   return VMDPLUGIN_SUCCESS;
+     643             : }
+     644             : 
+     645             : }
+     646             : }
+     647             : 
+     648             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/periodic_table.h.func-sort-c.html b/coverage-libs/molfile/periodic_table.h.func-sort-c.html new file mode 100644 index 000000000000..4ba4363fe100 --- /dev/null +++ b/coverage-libs/molfile/periodic_table.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/periodic_table.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - periodic_table.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0200.0 %
Date:2024-02-22 21:58:47Functions:040.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL12get_pte_massEi0
_ZN4PLMD7molfileL13get_pte_labelEi0
_ZN4PLMD7molfileL18get_pte_vdw_radiusEi0
_ZN4PLMD7molfileL23get_pte_idx_from_stringEPKc0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/periodic_table.h.func.html b/coverage-libs/molfile/periodic_table.h.func.html new file mode 100644 index 000000000000..8bdfae9796e9 --- /dev/null +++ b/coverage-libs/molfile/periodic_table.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/periodic_table.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - periodic_table.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0200.0 %
Date:2024-02-22 21:58:47Functions:040.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL12get_pte_massEi0
_ZN4PLMD7molfileL13get_pte_labelEi0
_ZN4PLMD7molfileL18get_pte_vdw_radiusEi0
_ZN4PLMD7molfileL23get_pte_idx_from_stringEPKc0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/periodic_table.h.gcov.html b/coverage-libs/molfile/periodic_table.h.gcov.html new file mode 100644 index 000000000000..dc0ed775e560 --- /dev/null +++ b/coverage-libs/molfile/periodic_table.h.gcov.html @@ -0,0 +1,325 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/periodic_table.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - periodic_table.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:0200.0 %
Date:2024-02-22 21:58:47Functions:040.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : University of Illinois Open Source License
+       3             : Copyright 2003 Theoretical and Computational Biophysics Group, 
+       4             : All rights reserved.
+       5             : 
+       6             : Developed by:           Theoretical and Computational Biophysics Group
+       7             :                         University of Illinois at Urbana-Champaign
+       8             :                         http://www.ks.uiuc.edu/
+       9             : 
+      10             : Permission is hereby granted, free of charge, to any person obtaining a copy of
+      11             : this software and associated documentation files (the Software), to deal with 
+      12             : the Software without restriction, including without limitation the rights to 
+      13             : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+      14             : of the Software, and to permit persons to whom the Software is furnished to 
+      15             : do so, subject to the following conditions:
+      16             : 
+      17             : Redistributions of source code must retain the above copyright notice, 
+      18             : this list of conditions and the following disclaimers.
+      19             : 
+      20             : Redistributions in binary form must reproduce the above copyright notice, 
+      21             : this list of conditions and the following disclaimers in the documentation 
+      22             : and/or other materials provided with the distribution.
+      23             : 
+      24             : Neither the names of Theoretical and Computational Biophysics Group, 
+      25             : University of Illinois at Urbana-Champaign, nor the names of its contributors 
+      26             : may be used to endorse or promote products derived from this Software without 
+      27             : specific prior written permission.
+      28             : 
+      29             : THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+      30             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+      31             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
+      32             : THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
+      33             : OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+      34             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
+      35             : OTHER DEALINGS WITH THE SOFTWARE.
+      36             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      37             : #ifndef __PLUMED_molfile_periodic_table_h
+      38             : #define __PLUMED_molfile_periodic_table_h
+      39             : /***************************************************************************
+      40             :  * RCS INFORMATION:
+      41             :  *
+      42             :  *      $RCSfile: periodic_table.h,v $
+      43             :  *      $Author: johns $       $Locker:  $             $State: Exp $
+      44             :  *      $Revision: 1.12 $       $Date: 2009/01/21 17:45:41 $
+      45             :  *
+      46             :  ***************************************************************************/
+      47             : 
+      48             : /*
+      49             :  * periodic table of elements and helper functions to convert
+      50             :  * ordinal numbers to labels and back.
+      51             :  * all tables and functions are declared static, so that it
+      52             :  * can be safely included by all plugins that may need it.
+      53             :  *
+      54             :  * 2002-2009 akohlmey@cmm.chem.upenn.edu, vmd@ks.uiuc.edu
+      55             :  */
+      56             : 
+      57             : #include <string.h>
+      58             : #include <ctype.h>
+      59             : 
+      60             : namespace PLMD{
+      61             : namespace molfile{
+      62             : /* periodic table of elements for translation of ordinal to atom type */
+      63             : static const char *pte_label[] = { 
+      64             :     "X",  "H",  "He", "Li", "Be", "B",  "C",  "N",  "O",  "F",  "Ne",
+      65             :     "Na", "Mg", "Al", "Si", "P" , "S",  "Cl", "Ar", "K",  "Ca", "Sc",
+      66             :     "Ti", "V",  "Cr", "Mn", "Fe", "Co", "Ni", "Cu", "Zn", "Ga", "Ge", 
+      67             :     "As", "Se", "Br", "Kr", "Rb", "Sr", "Y",  "Zr", "Nb", "Mo", "Tc",
+      68             :     "Ru", "Rh", "Pd", "Ag", "Cd", "In", "Sn", "Sb", "Te", "I",  "Xe",
+      69             :     "Cs", "Ba", "La", "Ce", "Pr", "Nd", "Pm", "Sm", "Eu", "Gd", "Tb",
+      70             :     "Dy", "Ho", "Er", "Tm", "Yb", "Lu", "Hf", "Ta", "W",  "Re", "Os",
+      71             :     "Ir", "Pt", "Au", "Hg", "Tl", "Pb", "Bi", "Po", "At", "Rn", "Fr",
+      72             :     "Ra", "Ac", "Th", "Pa", "U",  "Np", "Pu", "Am", "Cm", "Bk", "Cf",
+      73             :     "Es", "Fm", "Md", "No", "Lr", "Rf", "Db", "Sg", "Bh", "Hs", "Mt",
+      74             :     "Ds", "Rg"
+      75             : };
+      76             : static const int nr_pte_entries = sizeof(pte_label) / sizeof(char *);
+      77             : 
+      78             : /* corresponding table of masses. */
+      79             : static const float pte_mass[] = { 
+      80             :     /* X  */ 0.00000, 1.00794, 4.00260, 6.941, 9.012182, 10.811,  
+      81             :     /* C  */ 12.0107, 14.0067, 15.9994, 18.9984032, 20.1797, 
+      82             :     /* Na */ 22.989770, 24.3050, 26.981538, 28.0855, 30.973761,
+      83             :     /* S  */ 32.065, 35.453, 39.948, 39.0983, 40.078, 44.955910,
+      84             :     /* Ti */ 47.867, 50.9415, 51.9961, 54.938049, 55.845, 58.9332,
+      85             :     /* Ni */ 58.6934, 63.546, 65.409, 69.723, 72.64, 74.92160, 
+      86             :     /* Se */ 78.96, 79.904, 83.798, 85.4678, 87.62, 88.90585, 
+      87             :     /* Zr */ 91.224, 92.90638, 95.94, 98.0, 101.07, 102.90550,
+      88             :     /* Pd */ 106.42, 107.8682, 112.411, 114.818, 118.710, 121.760, 
+      89             :     /* Te */ 127.60, 126.90447, 131.293, 132.90545, 137.327, 
+      90             :     /* La */ 138.9055, 140.116, 140.90765, 144.24, 145.0, 150.36,
+      91             :     /* Eu */ 151.964, 157.25, 158.92534, 162.500, 164.93032, 
+      92             :     /* Er */ 167.259, 168.93421, 173.04, 174.967, 178.49, 180.9479,
+      93             :     /* W  */ 183.84, 186.207, 190.23, 192.217, 195.078, 196.96655, 
+      94             :     /* Hg */ 200.59, 204.3833, 207.2, 208.98038, 209.0, 210.0, 222.0, 
+      95             :     /* Fr */ 223.0, 226.0, 227.0, 232.0381, 231.03588, 238.02891,
+      96             :     /* Np */ 237.0, 244.0, 243.0, 247.0, 247.0, 251.0, 252.0, 257.0,
+      97             :     /* Md */ 258.0, 259.0, 262.0, 261.0, 262.0, 266.0, 264.0, 269.0,
+      98             :     /* Mt */ 268.0, 271.0, 272.0
+      99             : };
+     100             : 
+     101             : /*
+     102             :  * corresponding table of VDW radii.
+     103             :  * van der Waals radii are taken from A. Bondi, 
+     104             :  * J. Phys. Chem., 68, 441 - 452, 1964, 
+     105             :  * except the value for H, which is taken from R.S. Rowland & R. Taylor, 
+     106             :  * J.Phys.Chem., 100, 7384 - 7391, 1996. Radii that are not available in 
+     107             :  * either of these publications have RvdW = 2.00 Å.
+     108             :  * The radii for Ions (Na, K, Cl, Ca, Mg, and Cs are based on the CHARMM27 
+     109             :  * Rmin/2 parameters for (SOD, POT, CLA, CAL, MG, CES) by default.
+     110             :  */
+     111             : static const float pte_vdw_radius[] = { 
+     112             :     /* X  */ 1.5, 1.2, 1.4, 1.82, 2.0, 2.0,  
+     113             :     /* C  */ 1.7, 1.55, 1.52, 1.47, 1.54, 
+     114             :     /* Na */ 1.36, 1.18, 2.0, 2.1, 1.8,
+     115             :     /* S  */ 1.8, 2.27, 1.88, 1.76, 1.37, 2.0,
+     116             :     /* Ti */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     117             :     /* Ni */ 1.63, 1.4, 1.39, 1.07, 2.0, 1.85,
+     118             :     /* Se */ 1.9, 1.85, 2.02, 2.0, 2.0, 2.0, 
+     119             :     /* Zr */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     120             :     /* Pd */ 1.63, 1.72, 1.58, 1.93, 2.17, 2.0, 
+     121             :     /* Te */ 2.06, 1.98, 2.16, 2.1, 2.0,
+     122             :     /* La */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     123             :     /* Eu */ 2.0, 2.0, 2.0, 2.0, 2.0,
+     124             :     /* Er */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     125             :     /* W  */ 2.0, 2.0, 2.0, 2.0, 1.72, 1.66,
+     126             :     /* Hg */ 1.55, 1.96, 2.02, 2.0, 2.0, 2.0, 2.0,
+     127             :     /* Fr */ 2.0, 2.0, 2.0, 2.0, 2.0, 1.86,
+     128             :     /* Np */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     129             :     /* Md */ 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0,
+     130             :     /* Mt */ 2.0, 2.0, 2.0
+     131             : };
+     132             : 
+     133             : /* lookup functions */
+     134             : 
+     135           0 : static const char *get_pte_label(const int idx)
+     136             : {
+     137           0 :     if ((idx < 1) || (idx >= nr_pte_entries)) return pte_label[0];
+     138             : 
+     139           0 :     return pte_label[idx];
+     140             : }
+     141             : 
+     142           0 : static float get_pte_mass(const int idx)
+     143             : {
+     144           0 :     if ((idx < 1) || (idx >= nr_pte_entries)) return pte_mass[0];
+     145             : 
+     146           0 :     return pte_mass[idx];
+     147             : }
+     148             : 
+     149           0 : static float get_pte_vdw_radius(const int idx)
+     150             : {
+     151           0 :     if ((idx < 1) || (idx >= nr_pte_entries)) return pte_vdw_radius[0];
+     152             : 
+     153             : #if 1
+     154             :     /* Replace with Hydrogen radius with an "all-atom" radius */
+     155           0 :     if (idx == 1)
+     156             :       return 1.0;    /* H  */
+     157             : #else
+     158             :     /* Replace with old VMD atom radii values */
+     159             :     switch (idx) {
+     160             :       case  1: return 1.0;    /* H  */
+     161             :       case  6: return 1.5;    /* C  */
+     162             :       case  7: return 1.4;    /* N  */
+     163             :       case  8: return 1.3;    /* O  */
+     164             :       case  9: return 1.2;    /* F  */
+     165             :       case 15: return 1.5;    /* P  */
+     166             :       case 16: return 1.9;    /* S  */ 
+     167             :     }
+     168             : #endif
+     169             : 
+     170           0 :     return pte_vdw_radius[idx];
+     171             : }
+     172             : 
+     173             : static int get_pte_idx(const char *label)
+     174             : {
+     175             :     int i;
+     176             :     char atom[3];
+     177             :     
+     178             :     /* zap string */
+     179             :     atom[0] = (char) 0;
+     180             :     atom[1] = (char) 0;
+     181             :     atom[2] = (char) 0;
+     182             :     /* if we don't have a null-pointer, there must be at least two 
+     183             :      * chars, which is all we need. we convert to the capitalization 
+     184             :      * convention of the table above during assignment. */
+     185             :     if (label != NULL) {
+     186             :         atom[0] = (char) toupper((int) label[0]);
+     187             :         atom[1] = (char) tolower((int) label[1]);
+     188             :     }
+     189             :     /* discard numbers in atom label */
+     190             :     if (isdigit(atom[1])) atom[1] = (char) 0;
+     191             :     
+     192             :     for (i=0; i < nr_pte_entries; ++i) {
+     193             :         if ( (pte_label[i][0] == atom[0])
+     194             :              && (pte_label[i][1] == atom[1]) ) return i;
+     195             :     }
+     196             :     
+     197             :     return 0;
+     198             : }
+     199             : 
+     200           0 : static int get_pte_idx_from_string(const char *label) {
+     201             :   int i, ind;
+     202             :   char atom[3];
+     203             : 
+     204           0 :   if (label != NULL) {
+     205             :     /* zap string */
+     206           0 :     atom[0] = atom[1] = atom[2] = '\0';
+     207             : 
+     208           0 :     for (ind=0,i=0; (ind<2) && (label[i]!='\0'); i++) {
+     209           0 :       if (label[i] != ' ') {
+     210           0 :         atom[ind] = toupper(label[i]);
+     211           0 :         ind++;
+     212             :       }
+     213             :     }
+     214             : 
+     215           0 :     if (ind < 1)
+     216             :       return 0; /* no non-whitespace characters */
+     217             :  
+     218           0 :     for (i=0; i < nr_pte_entries; ++i) {
+     219           0 :       if ((toupper(pte_label[i][0]) == atom[0]) && (toupper(pte_label[i][1]) == atom[1])) 
+     220             :         return i;
+     221             :     }
+     222             :   }  
+     223             : 
+     224             :   return 0;
+     225             : }
+     226             : 
+     227             : #if 0
+     228             : #include <stdio.h>
+     229             : 
+     230             : int main() {
+     231             :   int i;
+     232             : 
+     233             :   printf("Periodic table check/dump\n");
+     234             :   printf("  Table contains data for %d elements\n", nr_pte_entries);
+     235             :   printf("   Mass table size check: %d\n", sizeof(pte_mass) / sizeof(float));
+     236             :   printf("    VDW table size check: %d\n", sizeof(pte_vdw_radius) / sizeof(float));
+     237             :   printf("\n");
+     238             :   printf("Symbol Num    Mass   rVDW\n");
+     239             :   for (i=0; i<nr_pte_entries; i++) {
+     240             :     printf("   %-2s  %3d  %6.2f  %4.2f\n",
+     241             :       get_pte_label(i), i, get_pte_mass(i), get_pte_vdw_radius(i));
+     242             :   } 
+     243             :   return 0;
+     244             : }
+     245             : #endif
+     246             : }
+     247             : }
+     248             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/readpdb.h.func-sort-c.html b/coverage-libs/molfile/readpdb.h.func-sort-c.html new file mode 100644 index 000000000000..33faf5f31e60 --- /dev/null +++ b/coverage-libs/molfile/readpdb.h.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/readpdb.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - readpdb.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4413532.6 %
Date:2024-02-22 21:58:47Functions:3837.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL14get_pdb_conectEPKciPiS3_S3_PS3_S4_0
_ZN4PLMD7molfileL14get_pdb_fieldsEPKciPiPcS4_S4_S4_S4_S4_S4_S4_PfS5_S5_S5_S5_0
_ZN4PLMD7molfileL14get_pdb_headerEPKcPcS3_S3_0
_ZN4PLMD7molfileL20write_raw_pdb_recordEP8_IO_FILEPKciS4_S4_iS4_S4_S4_fffffS4_S4_0
_ZN4PLMD7molfileL23adjust_pdb_field_stringEPc0
_ZN4PLMD7molfileL14get_pdb_cryst1EPKcPfS3_S3_S3_S3_S3_36
_ZN4PLMD7molfileL19get_pdb_coordinatesEPKcPfS3_S3_S3_S3_106320
_ZN4PLMD7molfileL15read_pdb_recordEP8_IO_FILEPc209110
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/readpdb.h.func.html b/coverage-libs/molfile/readpdb.h.func.html new file mode 100644 index 000000000000..77cd7cad2680 --- /dev/null +++ b/coverage-libs/molfile/readpdb.h.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/readpdb.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - readpdb.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4413532.6 %
Date:2024-02-22 21:58:47Functions:3837.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7molfileL14get_pdb_conectEPKciPiS3_S3_PS3_S4_0
_ZN4PLMD7molfileL14get_pdb_cryst1EPKcPfS3_S3_S3_S3_S3_36
_ZN4PLMD7molfileL14get_pdb_fieldsEPKciPiPcS4_S4_S4_S4_S4_S4_S4_PfS5_S5_S5_S5_0
_ZN4PLMD7molfileL14get_pdb_headerEPKcPcS3_S3_0
_ZN4PLMD7molfileL15read_pdb_recordEP8_IO_FILEPc209110
_ZN4PLMD7molfileL19get_pdb_coordinatesEPKcPfS3_S3_S3_S3_106320
_ZN4PLMD7molfileL20write_raw_pdb_recordEP8_IO_FILEPKciS4_S4_iS4_S4_S4_fffffS4_S4_0
_ZN4PLMD7molfileL23adjust_pdb_field_stringEPc0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/molfile/readpdb.h.gcov.html b/coverage-libs/molfile/readpdb.h.gcov.html new file mode 100644 index 000000000000..76e5c96f9bbb --- /dev/null +++ b/coverage-libs/molfile/readpdb.h.gcov.html @@ -0,0 +1,524 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - molfile/readpdb.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - molfile - readpdb.h (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:4413532.6 %
Date:2024-02-22 21:58:47Functions:3837.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : University of Illinois Open Source License
+       3             : Copyright 2003 Theoretical and Computational Biophysics Group, 
+       4             : All rights reserved.
+       5             : 
+       6             : Developed by:           Theoretical and Computational Biophysics Group
+       7             :                         University of Illinois at Urbana-Champaign
+       8             :                         http://www.ks.uiuc.edu/
+       9             : 
+      10             : Permission is hereby granted, free of charge, to any person obtaining a copy of
+      11             : this software and associated documentation files (the Software), to deal with 
+      12             : the Software without restriction, including without limitation the rights to 
+      13             : use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 
+      14             : of the Software, and to permit persons to whom the Software is furnished to 
+      15             : do so, subject to the following conditions:
+      16             : 
+      17             : Redistributions of source code must retain the above copyright notice, 
+      18             : this list of conditions and the following disclaimers.
+      19             : 
+      20             : Redistributions in binary form must reproduce the above copyright notice, 
+      21             : this list of conditions and the following disclaimers in the documentation 
+      22             : and/or other materials provided with the distribution.
+      23             : 
+      24             : Neither the names of Theoretical and Computational Biophysics Group, 
+      25             : University of Illinois at Urbana-Champaign, nor the names of its contributors 
+      26             : may be used to endorse or promote products derived from this Software without 
+      27             : specific prior written permission.
+      28             : 
+      29             : THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+      30             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+      31             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL 
+      32             : THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR 
+      33             : OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 
+      34             : ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 
+      35             : OTHER DEALINGS WITH THE SOFTWARE.
+      36             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      37             : #ifndef __PLUMED_molfile_readpdb_h
+      38             : #define __PLUMED_molfile_readpdb_h
+      39             : /***************************************************************************
+      40             :  *cr
+      41             :  *cr            (C) Copyright 1995-2016 The Board of Trustees of the
+      42             :  *cr                        University of Illinois
+      43             :  *cr                         All Rights Reserved
+      44             :  *cr
+      45             :  ***************************************************************************/
+      46             : 
+      47             : /***************************************************************************
+      48             :  * RCS INFORMATION:
+      49             :  *
+      50             :  *      $RCSfile: readpdb.h,v $
+      51             :  *      $Author: johns $       $Locker:  $             $State: Exp $
+      52             :  *      $Revision: 1.43 $       $Date: 2016/11/28 05:01:54 $
+      53             :  *
+      54             :  ***************************************************************************/
+      55             : 
+      56             : #ifndef READ_PDB_H
+      57             : #define READ_PDB_H
+      58             : 
+      59             : #include <stdio.h>
+      60             : #include <stdlib.h>
+      61             : #include <string.h>
+      62             : 
+      63             : namespace PLMD{
+      64             : namespace molfile{
+      65             : 
+      66             : #define PDB_RECORD_LENGTH   80   /* actual record size */
+      67             : #define PDB_BUFFER_LENGTH   83   /* size need to buffer + CR, LF, and NUL */
+      68             : 
+      69             : #define VMDUSECONECTRECORDS 1
+      70             : 
+      71             : /*  record type defines */
+      72             : enum {
+      73             :   PDB_HEADER, PDB_REMARK, PDB_ATOM, PDB_CONECT, PDB_UNKNOWN, PDB_END, PDB_EOF, PDB_CRYST1
+      74             : };
+      75             : 
+      76             : /* read the next record from the specified pdb file, and put the string found
+      77             :    in the given string pointer (the caller must provide adequate (81 chars)
+      78             :    buffer space); return the type of record found
+      79             : */
+      80      209110 : static int read_pdb_record(FILE *f, char *retStr) {
+      81             :   int ch;
+      82             :   char inbuf[PDB_BUFFER_LENGTH]; /* space for line + cr + lf + NUL */
+      83             :   int recType = PDB_UNKNOWN;
+      84             :  
+      85             :   /* XXX This PDB record reading code breaks with files that use
+      86             :    * Mac or DOS style line breaks with ctrl-M characters.  We need
+      87             :    * to replace the use of fgets() and comparisons against \n with
+      88             :    * code that properly handles the other cases.
+      89             :    */
+      90             :  
+      91             :   /* read the next line, including any ending cr/lf char */
+      92      209110 :   if (inbuf != fgets(inbuf, PDB_RECORD_LENGTH + 2, f)) {
+      93          53 :     retStr[0] = '\0';
+      94             :     recType = PDB_EOF;
+      95             :   } else {
+      96             : #if 0
+      97             :     /* XXX disabled this code since \n chars are desirable in remarks */
+      98             :     /* and to make the behavior consistent with webpdbplugin          */
+      99             : 
+     100             :     /* remove the newline character, if there is one */
+     101             :     if (inbuf[strlen(inbuf)-1] == '\n')
+     102             :       inbuf[strlen(inbuf)-1] = '\0';
+     103             : #endif
+     104             : 
+     105             :     /* atom records are the most common */
+     106      209057 :     if (!strncmp(inbuf, "ATOM ",  5) || !strncmp(inbuf, "HETATM", 6)) {
+     107             :       /* Note that by only comparing 5 chars for "ATOM " rather than 6,     */
+     108             :       /* we allow PDB files containing > 99,999 atoms generated by AMBER    */
+     109             :       /* to load which would otherwise fail.  Not needed for HETATM since   */
+     110             :       /* those aren't going to show up in files produced for/by MD engines. */
+     111             :       recType = PDB_ATOM;
+     112         515 :     } else if (!strncmp(inbuf, "CONECT", 6)) {
+     113             :       recType = PDB_CONECT;
+     114         515 :     } else if (!strncmp(inbuf, "REMARK", 6)) {
+     115             :       recType = PDB_REMARK;
+     116         409 :     } else if (!strncmp(inbuf, "CRYST1", 6)) {
+     117             :       recType = PDB_CRYST1;
+     118         339 :     } else if (!strncmp(inbuf, "HEADER", 6)) {
+     119             :       recType = PDB_HEADER;
+     120         339 :     } else if (!strncmp(inbuf, "END", 3)) {  /* very permissive */
+     121             :       /* XXX we treat any "ENDxxx" record as an end, to simplify testing */
+     122             :       /*     since we don't remove trailing '\n' chars                   */
+     123             : 
+     124             :       /* the only two legal END records are "END   " and "ENDMDL" */
+     125             :       recType = PDB_END;
+     126             :     } 
+     127             : 
+     128             : #if 0
+     129             :     /* XXX disable record type checking for now */
+     130             :     if (recType == PDB_ATOM || 
+     131             :         recType == PDB_CONECT || 
+     132             :         recType == PDB_REMARK || 
+     133             :         recType == PDB_HEADER || 
+     134             :         recType == PDB_CRYST1) {
+     135             :       strcpy(retStr, inbuf);
+     136             :     } else {
+     137             :       retStr[0] = '\0';
+     138             :     }
+     139             : #else
+     140             :     strcpy(retStr, inbuf);
+     141             : #endif
+     142             :   }
+     143             : 
+     144             :   /* read the '\r', if there was one */
+     145      209110 :   ch = fgetc(f);
+     146      209110 :   if (ch != '\r')
+     147      209110 :     ungetc(ch, f);
+     148             :   
+     149      209110 :   return recType;
+     150             : }
+     151             : 
+     152             : 
+     153             : /* Extract the alpha/beta/gamma a/b/c unit cell info from a CRYST1 record */
+     154          36 : static void get_pdb_cryst1(const char *record, 
+     155             :                            float *alpha, float *beta, float *gamma, 
+     156             :                            float *a, float *b, float *c) {
+     157             :   char tmp[PDB_RECORD_LENGTH+3]; /* space for line + cr + lf + NUL */
+     158             :   char ch, *s;
+     159             :   memset(tmp, 0, sizeof(tmp));
+     160             :   strncpy(tmp, record, PDB_RECORD_LENGTH);
+     161             : 
+     162          36 :   s = tmp+6 ;          ch = tmp[15]; tmp[15] = 0;
+     163          36 :   *a = (float) atof(s);
+     164          36 :   s = tmp+15; *s = ch; ch = tmp[24]; tmp[24] = 0;
+     165          36 :   *b = (float) atof(s);
+     166          36 :   s = tmp+24; *s = ch; ch = tmp[33]; tmp[33] = 0;
+     167          36 :   *c = (float) atof(s);
+     168          36 :   s = tmp+33; *s = ch; ch = tmp[40]; tmp[40] = 0;
+     169          36 :   *alpha = (float) atof(s);
+     170          36 :   s = tmp+40; *s = ch; ch = tmp[47]; tmp[47] = 0;
+     171          36 :   *beta = (float) atof(s);
+     172          36 :   s = tmp+47; *s = ch; ch = tmp[54]; tmp[54] = 0;
+     173          36 :   *gamma = (float) atof(s);
+     174          36 : }
+     175             : 
+     176             : 
+     177             : /* Extract the x,y,z coords, occupancy, and beta from an ATOM record */
+     178      106320 : static void get_pdb_coordinates(const char *record, 
+     179             :                                 float *x, float *y, float *z,
+     180             :                                 float *occup, float *beta) {
+     181             :   char numstr[50]; /* store all fields in one array to save memset calls */
+     182             :   memset(numstr, 0, sizeof(numstr));
+     183             : 
+     184      106320 :   if (x != NULL) {
+     185      106320 :     strncpy(numstr, record + 30, 8);
+     186      106320 :     *x = (float) atof(numstr);
+     187             :   }
+     188             : 
+     189      106320 :   if (y != NULL) {
+     190      106320 :     strncpy(numstr+10, record + 38, 8);
+     191      106320 :     *y = (float) atof(numstr+10);
+     192             :   }
+     193             : 
+     194      106320 :   if (z != NULL) {
+     195      106320 :     strncpy(numstr+20, record + 46, 8);
+     196      106320 :     *z = (float) atof(numstr+20);
+     197             :   }
+     198             : 
+     199      106320 :   if (occup != NULL) {
+     200      106320 :     strncpy(numstr+30, record + 54, 6);
+     201      106320 :     *occup = (float) atof(numstr+30);
+     202             :   }
+     203             : 
+     204      106320 :   if (beta != NULL) {
+     205      106320 :     strncpy(numstr+40, record + 60, 6);
+     206      106320 :     *beta = (float) atof(numstr+40);
+     207             :   }
+     208      106320 : }
+     209             : 
+     210             : 
+     211             : /* remove leading and trailing spaces from PDB fields */
+     212           0 : static void adjust_pdb_field_string(char *field) {
+     213             :   int i, len;
+     214             : 
+     215           0 :   len = strlen(field);
+     216           0 :   while (len > 0 && field[len-1] == ' ') {
+     217           0 :     field[len-1] = '\0';
+     218           0 :     len--;
+     219             :   }
+     220             : 
+     221           0 :   while (len > 0 && field[0] == ' ') {
+     222           0 :     for (i=0; i < len; i++)
+     223           0 :       field[i] = field[i+1];
+     224           0 :     len--;
+     225             :   }
+     226           0 : }
+     227             : 
+     228           0 : static void get_pdb_header(const char *record, char *pdbcode, char *date,
+     229             :                            char *classification) {
+     230           0 :   if (date != NULL) {
+     231           0 :     strncpy(date, record + 50, 9);
+     232           0 :     date[9] = '\0';
+     233             :   }
+     234             : 
+     235           0 :   if (classification != NULL) {
+     236           0 :     strncpy(classification, record + 10, 40);
+     237           0 :     classification[40] = '\0';
+     238             :   }
+     239             : 
+     240           0 :   if (pdbcode != NULL) {
+     241           0 :     strncpy(pdbcode, record + 62, 4);
+     242           0 :     pdbcode[4] = '\0';
+     243           0 :     adjust_pdb_field_string(pdbcode); /* remove spaces from accession code */
+     244             :   }
+     245           0 : }
+     246             : 
+     247             : 
+     248           0 : static void get_pdb_conect(const char *record, int natoms, int *idxmap,
+     249             :                            int *maxbnum, int *nbonds, int **from, int **to) {
+     250             :   int bondto[11], numbonds, i;
+     251             : 
+     252           0 :   int reclen = strlen(record);
+     253           0 :   for (numbonds=0, i=0; i<11; i++) {
+     254             :     char bondstr[6];
+     255             :     const int fieldwidth = 5;
+     256           0 :     int start = 6 + i*fieldwidth;
+     257           0 :     int end = start + fieldwidth;
+     258             : 
+     259           0 :     if (end >= reclen)
+     260             :       break;
+     261             : 
+     262           0 :     memcpy(bondstr, record + start, fieldwidth);
+     263           0 :     bondstr[5] = '\0';
+     264           0 :     if (sscanf(bondstr, "%d", &bondto[numbonds]) < 0)
+     265             :       break;
+     266           0 :     numbonds++; 
+     267             :   }
+     268             : 
+     269           0 :   for (i=0; i<numbonds; i++) {
+     270             :     /* only add one bond per pair, PDBs list them redundantly */ 
+     271           0 :     if (bondto[i] > bondto[0]) {
+     272           0 :       int newnbonds = *nbonds + 1; /* add a new bond */
+     273             : 
+     274             :       /* allocate more bondlist space if necessary */
+     275           0 :       if (newnbonds >= *maxbnum) {
+     276             :         int newmax;
+     277             :         int *newfromlist, *newtolist;
+     278           0 :         newmax = (newnbonds + 11) * 1.25;
+     279             : 
+     280           0 :         newfromlist = (int *) realloc(*from, newmax * sizeof(int));
+     281           0 :         newtolist = (int *) realloc(*to, newmax * sizeof(int));
+     282             : 
+     283           0 :         if (newfromlist != NULL || newtolist != NULL) {
+     284           0 :           *maxbnum = newmax;
+     285           0 :           *from = newfromlist;
+     286           0 :           *to = newtolist;
+     287             :         } else {
+     288             :           printf("readpdb) failed to allocate memory for bondlists\n");
+     289           0 :           return; /* abort */
+     290             :         }
+     291             :       }
+     292             : 
+     293           0 :       *nbonds = newnbonds;
+     294           0 :       (*from)[newnbonds-1] = idxmap[bondto[0]] + 1;
+     295           0 :       (*to)[newnbonds-1] = idxmap[bondto[i]] + 1;
+     296             :     }
+     297             :   }
+     298             : }
+     299             : 
+     300             : /* ATOM field format according to PDB standard v2.2
+     301             :   COLUMNS        DATA TYPE       FIELD         DEFINITION
+     302             : ---------------------------------------------------------------------------------
+     303             :  1 -  6        Record name     "ATOM  "
+     304             :  7 - 11        Integer         serial        Atom serial number.
+     305             : 13 - 16        Atom            name          Atom name.
+     306             : 17             Character       altLoc        Alternate location indicator.
+     307             : 18 - 20        Residue name    resName       Residue name.
+     308             : 22             Character       chainID       Chain identifier.
+     309             : 23 - 26        Integer         resSeq        Residue sequence number.
+     310             : 27             AChar           iCode         Code for insertion of residues.
+     311             : 31 - 38        Real(8.3)       x             Orthogonal coordinates for X in Angstroms.
+     312             : 39 - 46        Real(8.3)       y             Orthogonal coordinates for Y in Angstroms.
+     313             : 47 - 54        Real(8.3)       z             Orthogonal coordinates for Z in Angstroms.
+     314             : 55 - 60        Real(6.2)       occupancy     Occupancy.
+     315             : 61 - 66        Real(6.2)       tempFactor    Temperature factor.
+     316             : 73 - 76        LString(4)      segID         Segment identifier, left-justified.
+     317             : 77 - 78        LString(2)      element       Element symbol, right-justified.
+     318             : 79 - 80        LString(2)      charge        Charge on the atom.
+     319             :  */
+     320             : 
+     321             : /* Break a pdb ATOM record into its fields.  The user must provide the
+     322             :    necessary space to store the atom name, residue name, and segment name.
+     323             :    Character strings will be null-terminated.
+     324             : */
+     325           0 : static void get_pdb_fields(const char *record, int reclength, int *serial,
+     326             :                            char *name, char *resname, char *chain, 
+     327             :                            char *segname, char *resid, char *insertion, 
+     328             :                            char *altloc, char *elementsymbol,
+     329             :                            float *x, float *y, float *z, 
+     330             :                            float *occup, float *beta) {
+     331             :   char serialbuf[6];
+     332             : 
+     333             :   /* get atom serial number */
+     334           0 :   strncpy(serialbuf, record + 6, 5);
+     335           0 :   serialbuf[5] = '\0';
+     336           0 :   *serial = 0;
+     337           0 :   sscanf(serialbuf, "%5d", serial);
+     338             :   
+     339             :   /* get atom name */
+     340           0 :   strncpy(name, record + 12, 4);
+     341           0 :   name[4] = '\0';
+     342           0 :   adjust_pdb_field_string(name); /* remove spaces from the name */
+     343             : 
+     344             :   /* get alternate location identifier */
+     345           0 :   strncpy(altloc, record + 16, 1);
+     346           0 :   altloc[1] = '\0';
+     347             : 
+     348             :   /* get residue name */
+     349           0 :   strncpy(resname, record + 17, 4);
+     350           0 :   resname[4] = '\0';
+     351           0 :   adjust_pdb_field_string(resname); /* remove spaces from the resname */
+     352             : 
+     353             :   /* get chain name */
+     354           0 :   chain[0] = record[21];
+     355           0 :   chain[1] = '\0';
+     356             : 
+     357             :   /* get residue id number */
+     358           0 :   strncpy(resid, record + 22, 4);
+     359           0 :   resid[4] = '\0';
+     360           0 :   adjust_pdb_field_string(resid); /* remove spaces from the resid */
+     361             : 
+     362             :   /* get the insertion code */
+     363           0 :   insertion[0] = record[26];
+     364           0 :   insertion[1] = '\0';
+     365             : 
+     366             :   /* get x, y, and z coordinates */
+     367           0 :   get_pdb_coordinates(record, x, y, z, occup, beta);
+     368             : 
+     369             :   /* get segment name */
+     370           0 :   if (reclength >= 73) {
+     371           0 :     strncpy(segname, record + 72, 4);
+     372           0 :     segname[4] = '\0';
+     373           0 :     adjust_pdb_field_string(segname); /* remove spaces from the segname */
+     374             :   } else {
+     375           0 :     segname[0] = '\0';
+     376             :   }
+     377             : 
+     378             :   /* get the atomic element symbol */
+     379           0 :   if (reclength >= 77) {
+     380           0 :     strncpy(elementsymbol, record + 76, 2);
+     381           0 :     elementsymbol[2] = '\0';
+     382             :   } else {
+     383           0 :     elementsymbol[0] = '\0';
+     384             :   }
+     385           0 : }  
+     386             : 
+     387             : 
+     388             : /* Write PDB data to given file descriptor; return success. */
+     389           0 : static int write_raw_pdb_record(FILE *fd, const char *recordname,
+     390             :     int index,const char *atomname, const char *resname,int resid, 
+     391             :     const char *insertion, const char *altloc, const char *elementsymbol,
+     392             :     float x, float y, float z, float occ, float beta, 
+     393             :     const char *chain, const char *segname) {
+     394             :   int rc;
+     395             :   char indexbuf[32];
+     396             :   char residbuf[32];
+     397             :   char segnamebuf[5];
+     398             :   char resnamebuf[5];
+     399             :   char altlocchar;
+     400             : 
+     401             :   /* XXX                                                          */
+     402             :   /* if the atom or residue indices exceed the legal PDB spec, we */
+     403             :   /* start emitting asterisks or hexadecimal strings rather than  */
+     404             :   /* aborting.  This is not really legal, but is an accepted hack */
+     405             :   /* among various other programs that deal with large PDB files  */
+     406             :   /* If we run out of hexadecimal indices, then we just print     */
+     407             :   /* asterisks.                                                   */
+     408           0 :   if (index < 100000) {
+     409             :     snprintf(indexbuf, 32, "%5d", index);
+     410           0 :   } else if (index < 1048576) {
+     411             :     snprintf(indexbuf, 32, "%05x", index);
+     412             :   } else {
+     413             :     snprintf(indexbuf, 32, "*****");
+     414             :   }
+     415             : 
+     416           0 :   if (resid < 10000) {
+     417             :     snprintf(residbuf, 32, "%4d", resid);
+     418           0 :   } else if (resid < 65536) {
+     419             :     snprintf(residbuf, 32, "%04x", resid);
+     420             :   } else { 
+     421             :     snprintf(residbuf, 32, "****");
+     422             :   }
+     423             : 
+     424           0 :   altlocchar = altloc[0];
+     425           0 :   if (altlocchar == '\0') {
+     426             :     altlocchar = ' ';
+     427             :   }
+     428             : 
+     429             :   /* make sure the segname or resname do not overflow the format */ 
+     430             :   strncpy(segnamebuf,segname,4);
+     431           0 :   segnamebuf[4] = '\0';
+     432             :   strncpy(resnamebuf,resname,4);
+     433           0 :   resnamebuf[4] = '\0';
+     434             : 
+     435             :  
+     436           0 :   rc = fprintf(fd,
+     437             :          "%-6s%5s %4s%c%-4s%c%4s%c   %8.3f%8.3f%8.3f%6.2f%6.2f      %-4s%2s\n",
+     438           0 :          recordname, indexbuf, atomname, altlocchar, resnamebuf, chain[0], 
+     439           0 :          residbuf, insertion[0], x, y, z, occ, beta, segnamebuf, elementsymbol);
+     440             : 
+     441           0 :   return (rc > 0);
+     442             : }
+     443             : 
+     444             : }
+     445             : }
+     446             : #endif
+     447             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/ruby.png b/coverage-libs/ruby.png new file mode 100644 index 0000000000000000000000000000000000000000..991b6d4ec9e78be165e3ef757eed1aada287364d GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^FceV#7`HfI^%F z9+AZi4BSE>%y{W;-5;PJOS+@4BLl<6e(pbstUx|nfKQ0)e^Y%R^MdiLxj>4`)5S5Q b;#P73kj=!v_*DHKNFRfztDnm{r-UW|iOwIS literal 0 HcmV?d00001 diff --git a/coverage-libs/snow.png b/coverage-libs/snow.png new file mode 100644 index 0000000000000000000000000000000000000000..2cdae107fceec6e7f02ac7acb4a34a82a540caa5 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^MM!lvI6;R0X`wF|Ns97GD8ntt^-nBo-U3d c6}OTTfNUlP#;5A{K>8RwUHx3vIVCg!071?oo&W#< literal 0 HcmV?d00001 diff --git a/coverage-libs/updown.png b/coverage-libs/updown.png new file mode 100644 index 0000000000000000000000000000000000000000..aa56a238b3e6c435265250f9266cd1b8caba0f20 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^AT}Qd8;}%R+`Ae`*?77*hG?8mPH5^{)z4*}Q$iB}huR`+ literal 0 HcmV?d00001 diff --git a/coverage-libs/xdrfile/index-sort-f.html b/coverage-libs/xdrfile/index-sort-f.html new file mode 100644 index 000000000000..6e41f4978183 --- /dev/null +++ b/coverage-libs/xdrfile/index-sort-f.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:563116648.3 %
Date:2024-02-22 21:58:47Functions:439346.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
xdrfile.cpp +
45.8%45.8%
+
45.8 %432 / 94338.3 %31 / 81
xdrfile_xtc.cpp +
81.8%81.8%
+
81.8 %27 / 33100.0 %5 / 5
xdrfile_trr.cpp +
54.7%54.7%
+
54.7 %104 / 190100.0 %7 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/index-sort-l.html b/coverage-libs/xdrfile/index-sort-l.html new file mode 100644 index 000000000000..4e37957e1247 --- /dev/null +++ b/coverage-libs/xdrfile/index-sort-l.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:563116648.3 %
Date:2024-02-22 21:58:47Functions:439346.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
xdrfile.cpp +
45.8%45.8%
+
45.8 %432 / 94338.3 %31 / 81
xdrfile_trr.cpp +
54.7%54.7%
+
54.7 %104 / 190100.0 %7 / 7
xdrfile_xtc.cpp +
81.8%81.8%
+
81.8 %27 / 33100.0 %5 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/index.html b/coverage-libs/xdrfile/index.html new file mode 100644 index 000000000000..60e0b7e9bdec --- /dev/null +++ b/coverage-libs/xdrfile/index.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfileHitTotalCoverage
Test:plumed test coverage (other modules)Lines:563116648.3 %
Date:2024-02-22 21:58:47Functions:439346.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
xdrfile.cpp +
45.8%45.8%
+
45.8 %432 / 94338.3 %31 / 81
xdrfile_trr.cpp +
54.7%54.7%
+
54.7 %104 / 190100.0 %7 / 7
xdrfile_xtc.cpp +
81.8%81.8%
+
81.8 %27 / 33100.0 %5 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile.cpp.func-sort-c.html b/coverage-libs/xdrfile/xdrfile.cpp.func-sort-c.html new file mode 100644 index 000000000000..21a520046779 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile.cpp.func-sort-c.html @@ -0,0 +1,397 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:43294345.8 %
Date:2024-02-22 21:58:47Functions:318138.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile10xdrrshort_EPiPsS1_S1_0
_ZN4PLMD7xdrfile10xdrruchar_EPiPhS1_S1_0
_ZN4PLMD7xdrfile10xdrwshort_EPiPsS1_S1_0
_ZN4PLMD7xdrfile10xdrwuchar_EPiPhS1_S1_0
_ZN4PLMD7xdrfile11xdrrdouble_EPiPdS1_S1_0
_ZN4PLMD7xdrfile11xdrropaque_EPiPcS1_S1_0
_ZN4PLMD7xdrfile11xdrrsingle_EPiPfS1_S1_0
_ZN4PLMD7xdrfile11xdrrstring_EPiPcS1_i0
_ZN4PLMD7xdrfile11xdrrushort_EPiPtS1_S1_0
_ZN4PLMD7xdrfile11xdrwdouble_EPiPdS1_S1_0
_ZN4PLMD7xdrfile11xdrwopaque_EPiPcS1_S1_0
_ZN4PLMD7xdrfile11xdrwsingle_EPiPfS1_S1_0
_ZN4PLMD7xdrfile11xdrwstring_EPiPcS1_i0
_ZN4PLMD7xdrfile11xdrwushort_EPiPtS1_S1_0
_ZN4PLMD7xdrfile17xdrfile_read_charEPciPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile17xdrfile_read_uintEPjiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_read_shortEPsiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_read_ucharEPhiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_write_charEPciPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_write_uintEPjiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_read_doubleEPdiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_read_ushortEPtiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_write_shortEPsiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_write_ucharEPhiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile20xdrfile_write_doubleEPdiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile20xdrfile_write_ushortEPtiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile29xdrfile_compress_coord_doubleEPdidPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile31xdrfile_decompress_coord_doubleEPdPiS1_PNS0_7XDRFILEE0
_ZN4PLMD7xdrfile6xddcd_EPiPdS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrccd_EPiPdS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrccs_EPiPfS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrdcs_EPiPfS1_S2_S1_0
_ZN4PLMD7xdrfile8xdropen_EPiPcS2_ii0
_ZN4PLMD7xdrfile8xdrrint_EPiS1_S1_S1_0
_ZN4PLMD7xdrfile8xdrwint_EPiS1_S1_S1_0
_ZN4PLMD7xdrfile9xdrclose_EPi0
_ZN4PLMD7xdrfile9xdrrchar_EPiPcS1_S1_0
_ZN4PLMD7xdrfile9xdrruint_EPiPjS1_S1_0
_ZN4PLMD7xdrfile9xdrwchar_EPiPcS1_S1_0
_ZN4PLMD7xdrfile9xdrwuint_EPiPjS1_S1_0
_ZN4PLMD7xdrfileL10xdr_doubleEPNS0_3XDREPd0
_ZN4PLMD7xdrfileL10xdr_u_charEPNS0_3XDREPh0
_ZN4PLMD7xdrfileL11xdr_u_shortEPNS0_3XDREPt0
_ZN4PLMD7xdrfileL15xdrstdio_getposEPNS0_3XDRE0
_ZN4PLMD7xdrfileL15xdrstdio_setposEPNS0_3XDREj0
_ZN4PLMD7xdrfileL7ctofstrEPciS1_0
_ZN4PLMD7xdrfileL7ftocstrEPciS1_i0
_ZN4PLMD7xdrfileL8xdr_charEPNS0_3XDREPc0
_ZN4PLMD7xdrfileL9sizeofintEi0
_ZN4PLMD7xdrfileL9xdr_shortEPNS0_3XDREPs0
_ZN4PLMD7xdrfile12xdrfile_openEPKcS2_20
_ZN4PLMD7xdrfile13xdrfile_closeEPNS0_7XDRFILEE20
_ZN4PLMD7xdrfileL15xdrstdio_createEPNS0_3XDREP8_IO_FILENS0_6xdr_opE20
_ZN4PLMD7xdrfileL16xdrstdio_destroyEPNS0_3XDRE20
_ZN4PLMD7xdrfile19xdrfile_read_opaqueEPciPNS0_7XDRFILEE28
_ZN4PLMD7xdrfile30xdrfile_decompress_coord_floatEPfPiS1_PNS0_7XDRFILEE28
_ZN4PLMD7xdrfile19xdrfile_read_stringEPciPNS0_7XDRFILEE39
_ZN4PLMD7xdrfile20xdrfile_write_stringEPcPNS0_7XDRFILEE48
_ZN4PLMD7xdrfile20xdrfile_write_opaqueEPciPNS0_7XDRFILEE60
_ZN4PLMD7xdrfile28xdrfile_compress_coord_floatEPfifPNS0_7XDRFILEE72
_ZN4PLMD7xdrfileL10xdr_stringEPNS0_3XDREPPcj87
_ZN4PLMD7xdrfileL9xdr_u_intEPNS0_3XDREPj87
_ZN4PLMD7xdrfileL10sizeofintsEiPj88
_ZN4PLMD7xdrfileL17xdrstdio_getbytesEPNS0_3XDREPcj89
_ZN4PLMD7xdrfileL17xdrstdio_putbytesEPNS0_3XDREPcj147
_ZN4PLMD7xdrfile19xdrfile_write_floatEPfiPNS0_7XDRFILEE174
_ZN4PLMD7xdrfileL10xdr_opaqueEPNS0_3XDREPcj175
_ZN4PLMD7xdrfile18xdrfile_read_floatEPfiPNS0_7XDRFILEE470
_ZN4PLMD7xdrfile17xdrfile_write_intEPiiPNS0_7XDRFILEE620
_ZN4PLMD7xdrfile16xdrfile_read_intEPiiPNS0_7XDRFILEE1448
_ZN4PLMD7xdrfileL10decodeintsEPiiiPjS1_1936
_ZN4PLMD7xdrfileL7xdr_intEPNS0_3XDREPi2420
_ZN4PLMD7xdrfileL10encodeintsEPiiiPjS2_3960
_ZN4PLMD7xdrfileL9xdr_ntohlEi4054
_ZN4PLMD7xdrfileL16xdrstdio_getlongEPNS0_3XDREPi4059
_ZN4PLMD7xdrfileL16xdrstdio_putlongEPNS0_3XDREPi9972
_ZN4PLMD7xdrfileL9xdr_htonlEi9972
_ZN4PLMD7xdrfileL9xdr_floatEPNS0_3XDREPf11524
_ZN4PLMD7xdrfileL13xdr_swapbytesEi14026
_ZN4PLMD7xdrfileL10decodebitsEPii14579
_ZN4PLMD7xdrfileL10encodebitsEPiii21991
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile.cpp.func.html b/coverage-libs/xdrfile/xdrfile.cpp.func.html new file mode 100644 index 000000000000..69dad9dc691d --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile.cpp.func.html @@ -0,0 +1,397 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:43294345.8 %
Date:2024-02-22 21:58:47Functions:318138.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile10xdrrshort_EPiPsS1_S1_0
_ZN4PLMD7xdrfile10xdrruchar_EPiPhS1_S1_0
_ZN4PLMD7xdrfile10xdrwshort_EPiPsS1_S1_0
_ZN4PLMD7xdrfile10xdrwuchar_EPiPhS1_S1_0
_ZN4PLMD7xdrfile11xdrrdouble_EPiPdS1_S1_0
_ZN4PLMD7xdrfile11xdrropaque_EPiPcS1_S1_0
_ZN4PLMD7xdrfile11xdrrsingle_EPiPfS1_S1_0
_ZN4PLMD7xdrfile11xdrrstring_EPiPcS1_i0
_ZN4PLMD7xdrfile11xdrrushort_EPiPtS1_S1_0
_ZN4PLMD7xdrfile11xdrwdouble_EPiPdS1_S1_0
_ZN4PLMD7xdrfile11xdrwopaque_EPiPcS1_S1_0
_ZN4PLMD7xdrfile11xdrwsingle_EPiPfS1_S1_0
_ZN4PLMD7xdrfile11xdrwstring_EPiPcS1_i0
_ZN4PLMD7xdrfile11xdrwushort_EPiPtS1_S1_0
_ZN4PLMD7xdrfile12xdrfile_openEPKcS2_20
_ZN4PLMD7xdrfile13xdrfile_closeEPNS0_7XDRFILEE20
_ZN4PLMD7xdrfile16xdrfile_read_intEPiiPNS0_7XDRFILEE1448
_ZN4PLMD7xdrfile17xdrfile_read_charEPciPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile17xdrfile_read_uintEPjiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile17xdrfile_write_intEPiiPNS0_7XDRFILEE620
_ZN4PLMD7xdrfile18xdrfile_read_floatEPfiPNS0_7XDRFILEE470
_ZN4PLMD7xdrfile18xdrfile_read_shortEPsiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_read_ucharEPhiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_write_charEPciPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile18xdrfile_write_uintEPjiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_read_doubleEPdiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_read_opaqueEPciPNS0_7XDRFILEE28
_ZN4PLMD7xdrfile19xdrfile_read_stringEPciPNS0_7XDRFILEE39
_ZN4PLMD7xdrfile19xdrfile_read_ushortEPtiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_write_floatEPfiPNS0_7XDRFILEE174
_ZN4PLMD7xdrfile19xdrfile_write_shortEPsiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile19xdrfile_write_ucharEPhiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile20xdrfile_write_doubleEPdiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile20xdrfile_write_opaqueEPciPNS0_7XDRFILEE60
_ZN4PLMD7xdrfile20xdrfile_write_stringEPcPNS0_7XDRFILEE48
_ZN4PLMD7xdrfile20xdrfile_write_ushortEPtiPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile28xdrfile_compress_coord_floatEPfifPNS0_7XDRFILEE72
_ZN4PLMD7xdrfile29xdrfile_compress_coord_doubleEPdidPNS0_7XDRFILEE0
_ZN4PLMD7xdrfile30xdrfile_decompress_coord_floatEPfPiS1_PNS0_7XDRFILEE28
_ZN4PLMD7xdrfile31xdrfile_decompress_coord_doubleEPdPiS1_PNS0_7XDRFILEE0
_ZN4PLMD7xdrfile6xddcd_EPiPdS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrccd_EPiPdS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrccs_EPiPfS1_S2_S1_0
_ZN4PLMD7xdrfile7xdrdcs_EPiPfS1_S2_S1_0
_ZN4PLMD7xdrfile8xdropen_EPiPcS2_ii0
_ZN4PLMD7xdrfile8xdrrint_EPiS1_S1_S1_0
_ZN4PLMD7xdrfile8xdrwint_EPiS1_S1_S1_0
_ZN4PLMD7xdrfile9xdrclose_EPi0
_ZN4PLMD7xdrfile9xdrrchar_EPiPcS1_S1_0
_ZN4PLMD7xdrfile9xdrruint_EPiPjS1_S1_0
_ZN4PLMD7xdrfile9xdrwchar_EPiPcS1_S1_0
_ZN4PLMD7xdrfile9xdrwuint_EPiPjS1_S1_0
_ZN4PLMD7xdrfileL10decodebitsEPii14579
_ZN4PLMD7xdrfileL10decodeintsEPiiiPjS1_1936
_ZN4PLMD7xdrfileL10encodebitsEPiii21991
_ZN4PLMD7xdrfileL10encodeintsEPiiiPjS2_3960
_ZN4PLMD7xdrfileL10sizeofintsEiPj88
_ZN4PLMD7xdrfileL10xdr_doubleEPNS0_3XDREPd0
_ZN4PLMD7xdrfileL10xdr_opaqueEPNS0_3XDREPcj175
_ZN4PLMD7xdrfileL10xdr_stringEPNS0_3XDREPPcj87
_ZN4PLMD7xdrfileL10xdr_u_charEPNS0_3XDREPh0
_ZN4PLMD7xdrfileL11xdr_u_shortEPNS0_3XDREPt0
_ZN4PLMD7xdrfileL13xdr_swapbytesEi14026
_ZN4PLMD7xdrfileL15xdrstdio_createEPNS0_3XDREP8_IO_FILENS0_6xdr_opE20
_ZN4PLMD7xdrfileL15xdrstdio_getposEPNS0_3XDRE0
_ZN4PLMD7xdrfileL15xdrstdio_setposEPNS0_3XDREj0
_ZN4PLMD7xdrfileL16xdrstdio_destroyEPNS0_3XDRE20
_ZN4PLMD7xdrfileL16xdrstdio_getlongEPNS0_3XDREPi4059
_ZN4PLMD7xdrfileL16xdrstdio_putlongEPNS0_3XDREPi9972
_ZN4PLMD7xdrfileL17xdrstdio_getbytesEPNS0_3XDREPcj89
_ZN4PLMD7xdrfileL17xdrstdio_putbytesEPNS0_3XDREPcj147
_ZN4PLMD7xdrfileL7ctofstrEPciS1_0
_ZN4PLMD7xdrfileL7ftocstrEPciS1_i0
_ZN4PLMD7xdrfileL7xdr_intEPNS0_3XDREPi2420
_ZN4PLMD7xdrfileL8xdr_charEPNS0_3XDREPc0
_ZN4PLMD7xdrfileL9sizeofintEi0
_ZN4PLMD7xdrfileL9xdr_floatEPNS0_3XDREPf11524
_ZN4PLMD7xdrfileL9xdr_htonlEi9972
_ZN4PLMD7xdrfileL9xdr_ntohlEi4054
_ZN4PLMD7xdrfileL9xdr_shortEPNS0_3XDREPs0
_ZN4PLMD7xdrfileL9xdr_u_intEPNS0_3XDREPj87
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile.cpp.gcov.html b/coverage-libs/xdrfile/xdrfile.cpp.gcov.html new file mode 100644 index 000000000000..a8d003ba3755 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile.cpp.gcov.html @@ -0,0 +1,2725 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:43294345.8 %
Date:2024-02-22 21:58:47Functions:318138.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2009-2014, Erik Lindahl & David van der Spoel
+       3             : All rights reserved.
+       4             : 
+       5             : Redistribution and use in source and binary forms, with or without
+       6             : modification, are permitted provided that the following conditions are met:
+       7             : 
+       8             : 1. Redistributions of source code must retain the above copyright notice, this
+       9             : list of conditions and the following disclaimer.
+      10             : 
+      11             : 2. Redistributions in binary form must reproduce the above copyright notice,
+      12             : this list of conditions and the following disclaimer in the documentation
+      13             : and/or other materials provided with the distribution.
+      14             : 
+      15             : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+      16             : AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+      17             : IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+      18             : DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+      19             : FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+      20             : DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+      21             : SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+      22             : CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+      23             : OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+      24             : OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+      25             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      26             : /* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- 
+      27             :  *
+      28             :  * $Id$
+      29             :  *
+      30             :  /* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
+      31             :  *
+      32             :  * $Id$
+      33             :  *
+      34             :  * Copyright (c) 2009-2014, Erik Lindahl & David van der Spoel
+      35             :  * All rights reserved.
+      36             :  *
+      37             :  * Redistribution and use in source and binary forms, with or without
+      38             :  * modification, are permitted provided that the following conditions are met:
+      39             :  *
+      40             :  * 1. Redistributions of source code must retain the above copyright notice, this
+      41             :  * list of conditions and the following disclaimer.
+      42             :  *
+      43             :  * 2. Redistributions in binary form must reproduce the above copyright notice,
+      44             :  * this list of conditions and the following disclaimer in the documentation
+      45             :  * and/or other materials provided with the distribution.
+      46             :  *
+      47             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+      48             :  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+      49             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+      50             :  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+      51             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+      52             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+      53             :  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+      54             :  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+      55             :  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+      56             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+      57             :  */
+      58             : 
+      59             : /* Get HAVE_RPC_XDR_H, F77_FUNC from config.h if available */
+      60             : #ifdef HAVE_CONFIG_H
+      61             : #include <config.h>
+      62             : #endif
+      63             : 
+      64             : #include <stdio.h>
+      65             : #include <stdlib.h>
+      66             : #include <string.h>
+      67             : #include <math.h>
+      68             : #include <limits.h>
+      69             : 
+      70             : #define _FILE_OFFSET_BITS  64
+      71             : 
+      72             : /* get fixed-width types if we are using ANSI C99 */
+      73             : #ifdef HAVE_STDINT_H
+      74             : #  include <stdint.h>
+      75             : #elif (defined HAVE_INTTYPES_H)
+      76             : #  include <inttypes.h>
+      77             : #endif
+      78             : 
+      79             : 
+      80             : #ifdef HAVE_RPC_XDR_H
+      81             : #  include <rpc/rpc.h>
+      82             : #  include <rpc/xdr.h>
+      83             : #endif
+      84             : 
+      85             : #include "xdrfile.h"
+      86             : 
+      87             : /* Default FORTRAN name mangling is: lower case name, append underscore */
+      88             : #ifndef F77_FUNC
+      89             : #define F77_FUNC(name,NAME) name ## _
+      90             : #endif
+      91             : 
+      92             : namespace PLMD
+      93             : {
+      94             : namespace xdrfile
+      95             : {
+      96             : 
+      97             :  const char *exdr_message[exdrNR] = {
+      98             :         "OK", 
+      99             :         "Header",
+     100             :         "String", 
+     101             :         "Double",
+     102             :         "Integer",
+     103             :         "Float",
+     104             :         "Unsigned integer",
+     105             :         "Compressed 3D coordinate",
+     106             :         "Closing file",
+     107             :         "Magic number",
+     108             :         "Not enough memory",
+     109             :         "End of file",
+     110             :         "File not found" 
+     111             : };
+     112             : 
+     113             : /*
+     114             :  * Declare our own XDR routines statically if no libraries are present.
+     115             :  * Actual implementation is at the end of this file.
+     116             :  *
+     117             :  * We don't want the low-level XDR implementation as part of the Gromacs
+     118             :  * documentation, so skip it for doxygen too...
+     119             :  */
+     120             : #if (!defined HAVE_RPC_XDR_H && !defined DOXYGEN)
+     121             : 
+     122             : enum xdr_op
+     123             : {
+     124             :         XDR_ENCODE = 0,
+     125             :         XDR_DECODE = 1,
+     126             :         XDR_FREE   = 2
+     127             : };
+     128             : 
+     129             : 
+     130             : /* We need integer types that are guaranteed to be 4 bytes wide.
+     131             :  * If ANSI C99 headers were included they are already defined
+     132             :  * as int32_t and uint32_t. Check, and if not define them ourselves.
+     133             :  * Since it is just our workaround for missing ANSI C99 types, avoid adding
+     134             :  * it to the doxygen documentation.
+     135             :  */
+     136             : #if !(defined INT32_MAX || defined DOXYGEN)
+     137             : #    if (INT_MAX == 2147483647)
+     138             : #        define int32_t int
+     139             : #        define uint32_t unsigned int
+     140             : #        define INT32_MAX 2147483647
+     141             : #    elif (LONG_MAX == 2147483647)
+     142             : #        define int32_t long
+     143             : #        define uint32_t unsigned long
+     144             : #        define INT32_MAX 2147483647L
+     145             : #    else
+     146             : #        error ERROR: No 32 bit wide integer type found!
+     147             : #        error Use system XDR libraries instead, or update xdrfile.c
+     148             : #    endif
+     149             : #endif
+     150             : 
+     151             : typedef struct XDR XDR;
+     152             : 
+     153             : struct XDR
+     154             : {
+     155             :         enum xdr_op x_op;               
+     156             :         struct xdr_ops
+     157             :         {
+     158             :                 int (*x_getlong) (XDR *__xdrs, int32_t *__lp);
+     159             :                 int (*x_putlong) (XDR *__xdrs, int32_t *__lp);
+     160             :                 int (*x_getbytes) (XDR *__xdrs, char *__addr, unsigned int __len);
+     161             :                 int (*x_putbytes) (XDR *__xdrs, char *__addr, unsigned int __len);
+     162             :                 /* two next routines are not 64-bit IO safe - don't use! */
+     163             :                 unsigned int (*x_getpostn) (XDR *__xdrs); 
+     164             :                 int (*x_setpostn) (XDR *__xdrs, unsigned int __pos);
+     165             :                 void (*x_destroy) (XDR *__xdrs); 
+     166             :         } 
+     167             :     *x_ops;         
+     168             :         char *x_private;
+     169             : };
+     170             : 
+     171             : static int  xdr_char        (XDR *xdrs, char *ip);
+     172             : static int  xdr_u_char      (XDR *xdrs, unsigned char *ip);
+     173             : static int  xdr_short       (XDR *xdrs, short *ip);
+     174             : static int  xdr_u_short     (XDR *xdrs, unsigned short *ip);
+     175             : static int  xdr_int         (XDR *xdrs, int *ip);
+     176             : static int  xdr_u_int       (XDR *xdrs, unsigned int *ip);
+     177             : static int  xdr_float       (XDR *xdrs, float *ip);
+     178             : static int  xdr_double      (XDR *xdrs, double *ip);
+     179             : static int  xdr_string      (XDR *xdrs, char **ip, unsigned int maxsize);
+     180             : static int  xdr_opaque      (XDR *xdrs, char *cp, unsigned int cnt);
+     181             : static void xdrstdio_create (XDR *xdrs, FILE *fp, enum xdr_op xop);
+     182             : 
+     183             : #define xdr_getpos(xdrs)                                \
+     184             :         (*(xdrs)->x_ops->x_getpostn)(xdrs)
+     185             : #define xdr_setpos(xdrs, pos)                           \
+     186             :         (*(xdrs)->x_ops->x_setpostn)(xdrs, pos)
+     187             : #define xdr_destroy(xdrs)                                       \
+     188             :         do {                                                    \
+     189             :                 if ((xdrs)->x_ops->x_destroy)                   \
+     190             :                         (*(xdrs)->x_ops->x_destroy)(xdrs);      \
+     191             :         } while (0)
+     192             : #endif /* end of our own XDR declarations */
+     193             : 
+     194             : 
+     195             : 
+     196             : 
+     197             : 
+     198             : /** Contents of the abstract XDRFILE data structure.
+     199             :  *
+     200             :  *  @internal
+     201             :  * 
+     202             :  *  This structure is used to provide an XDR file interface that is
+     203             :  *  virtual identical to the standard UNIX fopen/fread/fwrite/fclose.
+     204             :  */
+     205             : struct XDRFILE 
+     206             : { 
+     207             :     FILE *   fp;       /**< pointer to standard C library file handle */
+     208             :     XDR *    xdr;      /**< pointer to corresponding XDR handle       */
+     209             :     char     mode;     /**< r=read, w=write, a=append                 */
+     210             :     int *    buf1;     /**< Buffer for internal use                   */
+     211             :     int      buf1size; /**< Current allocated length of buf1          */    
+     212             :     int *    buf2;     /**< Buffer for internal use                   */
+     213             :     int      buf2size; /**< Current allocated length of buf2          */ 
+     214             : };
+     215             : 
+     216             : 
+     217             : 
+     218             : 
+     219             : /*************************************************************
+     220             :  * Implementation of higher-level routines to read/write     * 
+     221             :  * portable data based on the XDR standard. These should be  *
+     222             :  * called from C - see further down for Fortran77 wrappers.  *
+     223             :  *************************************************************/
+     224             : 
+     225             : XDRFILE *
+     226          20 : xdrfile_open(const char *path, const char *mode)
+     227             : {
+     228             :         char newmode[5];
+     229             :         enum xdr_op xdrmode;
+     230             :         XDRFILE *xfp;
+     231             :   
+     232             :         /* make sure XDR files are opened in binary mode... */
+     233          20 :         if(*mode=='w' || *mode=='W') 
+     234             :     {
+     235             :                 snprintf(newmode,5,"wb+");
+     236             :                 xdrmode=XDR_ENCODE;
+     237          10 :         } else if(*mode == 'a' || *mode == 'A') 
+     238             :     {
+     239             :                 snprintf(newmode,5,"ab+");
+     240             :                 xdrmode = XDR_ENCODE;
+     241          10 :         } else if(*mode == 'r' || *mode == 'R')
+     242             :     {
+     243             :                 snprintf(newmode,5,"rb");
+     244             :                 xdrmode = XDR_DECODE;
+     245             :         } else /* cannot determine mode */
+     246             :                 return NULL;
+     247             :   
+     248          20 :         if((xfp=(XDRFILE *)malloc(sizeof(XDRFILE)))==NULL)
+     249             :                 return NULL;
+     250          20 :         if((xfp->fp=fopen(path,newmode))==NULL)
+     251             :     {
+     252           0 :                 free(xfp);
+     253           0 :                 return NULL;
+     254             :         }
+     255          20 :         if((xfp->xdr=(XDR *)malloc(sizeof(XDR)))==NULL) 
+     256             :     {
+     257           0 :                 fclose(xfp->fp);
+     258           0 :                 free(xfp);
+     259           0 :                 return NULL;
+     260             :         }
+     261          20 :         xfp->mode=*mode;
+     262          20 :         xdrstdio_create((XDR *)(xfp->xdr),xfp->fp,xdrmode);
+     263          20 :         xfp->buf1 = xfp->buf2 = NULL;
+     264          20 :         xfp->buf1size = xfp->buf2size = 0;
+     265          20 :         return xfp;
+     266             : }
+     267             : 
+     268             : int 
+     269          20 : xdrfile_close(XDRFILE *xfp)
+     270             : {
+     271             :         int ret=exdrCLOSE;
+     272          20 :         if(xfp) 
+     273             :     {
+     274             :                 /* flush and destroy XDR stream */
+     275          20 :                 if(xfp->xdr)
+     276          20 :                         xdr_destroy((XDR *)(xfp->xdr));
+     277          20 :                 free(xfp->xdr);
+     278             :                 /* close the file */
+     279          20 :                 ret=fclose(xfp->fp);
+     280          20 :                 if(xfp->buf1size)
+     281           7 :                         free(xfp->buf1);
+     282          20 :                 if(xfp->buf2size)
+     283           7 :                         free(xfp->buf2);
+     284          20 :                 free(xfp);
+     285             :         }
+     286          20 :         return ret; /* return 0 if ok */
+     287             : }
+     288             : 
+     289             : 
+     290             : 
+     291             : int 
+     292        1448 : xdrfile_read_int(int *ptr, int ndata, XDRFILE* xfp) 
+     293             : {
+     294             :         int i=0;
+     295             : 
+     296             :         /* read write is encoded in the XDR struct */
+     297        3005 :         while(i<ndata && xdr_int((XDR *)(xfp->xdr),ptr+i))
+     298        1557 :                 i++;
+     299             :   
+     300        1448 :         return i;
+     301             : }
+     302             : 
+     303             : int 
+     304         620 : xdrfile_write_int(int *ptr, int ndata, XDRFILE* xfp) 
+     305             : {
+     306             :         int i=0;
+     307             :   
+     308             :         /* read write is encoded in the XDR struct */  
+     309        1478 :         while(i<ndata && xdr_int((XDR *)(xfp->xdr),ptr+i))
+     310         858 :                 i++;
+     311         620 :         return i;
+     312             : }
+     313             : 
+     314             : 
+     315             : int 
+     316           0 : xdrfile_read_uint(unsigned int *ptr, int ndata, XDRFILE* xfp) 
+     317             : {
+     318             :         int i=0;
+     319             : 
+     320             :         /* read write is encoded in the XDR struct */
+     321           0 :         while(i<ndata && xdr_u_int((XDR *)(xfp->xdr),ptr+i))
+     322           0 :                 i++;
+     323             :   
+     324           0 :         return i;
+     325             : }
+     326             : 
+     327             : int 
+     328           0 : xdrfile_write_uint(unsigned int *ptr, int ndata, XDRFILE* xfp) 
+     329             : {
+     330             :         int i=0;
+     331             :   
+     332             :         /* read write is encoded in the XDR struct */  
+     333           0 :         while(i<ndata && xdr_u_int((XDR *)(xfp->xdr),ptr+i))
+     334           0 :                 i++;
+     335           0 :         return i;
+     336             : }
+     337             : 
+     338             : int 
+     339           0 : xdrfile_read_char(char *ptr, int ndata, XDRFILE* xfp) 
+     340             : {
+     341             :         int i=0;
+     342             : 
+     343             :         /* read write is encoded in the XDR struct */
+     344           0 :         while(i<ndata && xdr_char((XDR *)(xfp->xdr),ptr+i))
+     345           0 :                 i++;
+     346             :   
+     347           0 :         return i;
+     348             : }
+     349             : 
+     350             : int 
+     351           0 : xdrfile_write_char(char *ptr, int ndata, XDRFILE* xfp) 
+     352             : {
+     353             :         int i=0;
+     354             :   
+     355             :         /* read write is encoded in the XDR struct */  
+     356           0 :         while(i<ndata && xdr_char((XDR *)(xfp->xdr),ptr+i))
+     357           0 :                 i++;
+     358           0 :         return i;
+     359             : }
+     360             : 
+     361             : 
+     362             : int 
+     363           0 : xdrfile_read_uchar(unsigned char *ptr, int ndata, XDRFILE* xfp) 
+     364             : {
+     365             :         int i=0;
+     366             : 
+     367             :         /* read write is encoded in the XDR struct */
+     368           0 :         while(i<ndata && xdr_u_char((XDR *)(xfp->xdr),ptr+i))
+     369           0 :                 i++;
+     370             :   
+     371           0 :         return i;
+     372             : }
+     373             : 
+     374             : int 
+     375           0 : xdrfile_write_uchar(unsigned char *ptr, int ndata, XDRFILE* xfp) 
+     376             : {
+     377             :         int i=0;
+     378             :   
+     379             :         /* read write is encoded in the XDR struct */  
+     380           0 :         while(i<ndata && xdr_u_char((XDR *)(xfp->xdr),ptr+i))
+     381           0 :                 i++;
+     382           0 :         return i;
+     383             : }
+     384             : 
+     385             : int 
+     386           0 : xdrfile_read_short(short *ptr, int ndata, XDRFILE* xfp) 
+     387             : {
+     388             :         int i=0;
+     389             : 
+     390             :         /* read write is encoded in the XDR struct */
+     391           0 :         while(i<ndata && xdr_short((XDR *)(xfp->xdr),ptr+i))
+     392           0 :                 i++;
+     393             :   
+     394           0 :         return i;
+     395             : }
+     396             : 
+     397             : int 
+     398           0 : xdrfile_write_short(short *ptr, int ndata, XDRFILE* xfp) 
+     399             : {
+     400             :         int i=0;
+     401             :   
+     402             :         /* read write is encoded in the XDR struct */  
+     403           0 :         while(i<ndata && xdr_short((XDR *)(xfp->xdr),ptr+i))
+     404           0 :                 i++;
+     405           0 :         return i;
+     406             : }
+     407             : 
+     408             : 
+     409             : int 
+     410           0 : xdrfile_read_ushort(unsigned short *ptr, int ndata, XDRFILE* xfp) 
+     411             : {
+     412             :         int i=0;
+     413             : 
+     414             :         /* read write is encoded in the XDR struct */
+     415           0 :         while(i<ndata && xdr_u_short((XDR *)(xfp->xdr),ptr+i))
+     416           0 :                 i++;
+     417             :   
+     418           0 :         return i;
+     419             : }
+     420             : 
+     421             : int 
+     422           0 : xdrfile_write_ushort(unsigned short *ptr, int ndata, XDRFILE* xfp) 
+     423             : {
+     424             :         int i=0;
+     425             :   
+     426             :         /* read write is encoded in the XDR struct */  
+     427           0 :         while(i<ndata && xdr_u_short((XDR *)(xfp->xdr),ptr+i))
+     428           0 :                 i++;
+     429           0 :         return i;
+     430             : }
+     431             : 
+     432             : int 
+     433         470 : xdrfile_read_float(float *ptr, int ndata, XDRFILE* xfp) 
+     434             : {
+     435             :         int i=0;
+     436             :         /* read write is encoded in the XDR struct */
+     437       11832 :         while(i<ndata && xdr_float((XDR *)(xfp->xdr),ptr+i))
+     438       11362 :                 i++;
+     439         470 :         return i;
+     440             : }
+     441             : 
+     442             : int 
+     443         174 : xdrfile_write_float(float *ptr, int ndata, XDRFILE* xfp) 
+     444             : {
+     445             :         int i=0;
+     446             :         /* read write is encoded in the XDR struct */  
+     447         336 :         while(i<ndata && xdr_float((XDR *)(xfp->xdr),ptr+i))
+     448         162 :                 i++;
+     449         174 :         return i;
+     450             : }
+     451             : 
+     452             : int 
+     453           0 : xdrfile_read_double(double *ptr, int ndata, XDRFILE* xfp) 
+     454             : {
+     455             :         int i=0;
+     456             :         /* read write is encoded in the XDR struct */
+     457           0 :         while(i<ndata && xdr_double((XDR *)(xfp->xdr),ptr+i))
+     458           0 :                 i++;
+     459           0 :         return i;
+     460             : }
+     461             : 
+     462             : int 
+     463           0 : xdrfile_write_double(double *ptr, int ndata, XDRFILE* xfp) 
+     464             : {
+     465             :         int i=0;
+     466             :         /* read write is encoded in the XDR struct */  
+     467           0 :         while(i<ndata && xdr_double((XDR *)(xfp->xdr),ptr+i))
+     468           0 :                 i++;
+     469           0 :         return i;
+     470             : }
+     471             : 
+     472             : int
+     473          39 : xdrfile_read_string(char *ptr, int maxlen, XDRFILE* xfp)
+     474             : {
+     475             :         int i;
+     476          39 :         if(xdr_string((XDR *)(xfp->xdr),&ptr,maxlen)) {
+     477             :                 i=0;
+     478         507 :                 while(i<maxlen && ptr[i]!=0)
+     479         468 :                         i++;
+     480          39 :                 if(i==maxlen)
+     481             :                         return maxlen;
+     482             :                 else
+     483          39 :                         return i+1;
+     484             :         } else
+     485             :                 return 0;
+     486             : }
+     487             : 
+     488             : int
+     489          48 : xdrfile_write_string(char *ptr, XDRFILE* xfp)
+     490             : {
+     491          48 :         int len=strlen(ptr)+1;
+     492             :   
+     493          48 :         if(xdr_string((XDR *)(xfp->xdr),&ptr,len)) 
+     494             :                 return len;
+     495             :         else
+     496           0 :                 return 0;
+     497             : }
+     498             : 
+     499             : 
+     500             : int
+     501          28 : xdrfile_read_opaque(char *ptr, int cnt, XDRFILE* xfp)
+     502             : {
+     503          28 :         if(xdr_opaque((XDR *)(xfp->xdr),ptr,cnt))
+     504             :                 return cnt;
+     505             :         else 
+     506           0 :                 return 0;
+     507             : }
+     508             : 
+     509             : 
+     510             : int
+     511          60 : xdrfile_write_opaque(char *ptr, int cnt, XDRFILE* xfp)
+     512             : {
+     513          60 :         if(xdr_opaque((XDR *)(xfp->xdr),ptr,cnt))
+     514             :                 return cnt;
+     515             :         else
+     516           0 :                 return 0;
+     517             : }
+     518             : 
+     519             : 
+     520             : /* Internal support routines for reading/writing compressed coordinates 
+     521             :  * sizeofint - calculate smallest number of bits necessary
+     522             :  * to represent a certain integer.
+     523             :  */
+     524             : static int 
+     525           0 : sizeofint(int size) {
+     526             :     unsigned int num = 1;
+     527             :     int num_of_bits = 0;
+     528             :     
+     529           0 :     while (size >= num && num_of_bits < 32) 
+     530             :     {
+     531           0 :                 num_of_bits++;
+     532           0 :                 num <<= 1;
+     533             :     }
+     534           0 :     return num_of_bits;
+     535             : }
+     536             : 
+     537             : 
+     538             : /*
+     539             :  * sizeofints - calculate 'bitsize' of compressed ints
+     540             :  *
+     541             :  * given a number of small unsigned integers and the maximum value
+     542             :  * return the number of bits needed to read or write them with the
+     543             :  * routines encodeints/decodeints. You need this parameter when
+     544             :  * calling those routines. 
+     545             :  * (However, in some cases we can just use the variable 'smallidx' 
+     546             :  * which is the exact number of bits, and them we dont need to call
+     547             :  * this routine).
+     548             :  */
+     549             : static int 
+     550          88 : sizeofints(int num_of_ints, unsigned int sizes[]) 
+     551             : {
+     552             :     int i, num;
+     553             :     unsigned int num_of_bytes, num_of_bits, bytes[32], bytecnt, tmp;
+     554             :     num_of_bytes = 1;
+     555          88 :     bytes[0] = 1;
+     556             :     num_of_bits = 0;
+     557         352 :     for (i=0; i < num_of_ints; i++)
+     558             :     {   
+     559             :                 tmp = 0;
+     560         876 :                 for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++)
+     561             :         {
+     562         612 :                         tmp = bytes[bytecnt] * sizes[i] + tmp;
+     563         612 :                         bytes[bytecnt] = tmp & 0xff;
+     564         612 :                         tmp >>= 8;
+     565             :                 }
+     566         612 :                 while (tmp != 0) 
+     567             :         {
+     568         348 :                         bytes[bytecnt++] = tmp & 0xff;
+     569         348 :                         tmp >>= 8;
+     570             :                 }
+     571             :                 num_of_bytes = bytecnt;
+     572             :     }
+     573             :     num = 1;
+     574          88 :     num_of_bytes--;
+     575         497 :     while (bytes[num_of_bytes] >= num) 
+     576             :     {
+     577         409 :                 num_of_bits++;
+     578         409 :                 num *= 2;
+     579             :     }
+     580          88 :     return num_of_bits + num_of_bytes * 8;
+     581             : 
+     582             : }
+     583             :     
+     584             : 
+     585             : /*
+     586             :  * encodebits - encode num into buf using the specified number of bits
+     587             :  *
+     588             :  * This routines appends the value of num to the bits already present in
+     589             :  * the array buf. You need to give it the number of bits to use and you had
+     590             :  * better make sure that this number of bits is enough to hold the value.
+     591             :  * Num must also be positive.
+     592             :  */
+     593             : static void 
+     594       21991 : encodebits(int buf[], int num_of_bits, int num) 
+     595             : {
+     596             :     
+     597             :     unsigned int cnt, lastbyte;
+     598             :     int lastbits;
+     599             :     unsigned char * cbuf;
+     600             :     
+     601       21991 :     cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
+     602       21991 :     cnt = (unsigned int) buf[0];
+     603       21991 :     lastbits = buf[1];
+     604       21991 :     lastbyte =(unsigned int) buf[2];
+     605       38553 :     while (num_of_bits >= 8)
+     606             :     {
+     607       16562 :                 lastbyte = (lastbyte << 8) | ((num >> (num_of_bits -8)) /* & 0xff*/);
+     608       16562 :                 cbuf[cnt++] = lastbyte >> lastbits;
+     609             :                 num_of_bits -= 8;
+     610             :     }
+     611       21991 :     if (num_of_bits > 0)
+     612             :     {
+     613        4729 :                 lastbyte = (lastbyte << num_of_bits) | num;
+     614        4729 :                 lastbits += num_of_bits;
+     615        4729 :                 if (lastbits >= 8) 
+     616             :         {
+     617        1916 :                         lastbits -= 8;
+     618        1916 :                         cbuf[cnt++] = lastbyte >> lastbits;
+     619             :                 }
+     620             :     }
+     621       21991 :     buf[0] = cnt;
+     622       21991 :     buf[1] = lastbits;
+     623       21991 :     buf[2] = lastbyte;
+     624       21991 :     if (lastbits>0) 
+     625             :     {
+     626       19395 :                 cbuf[cnt] = lastbyte << (8 - lastbits);
+     627             :     }
+     628       21991 : }
+     629             : 
+     630             : /*
+     631             :  * encodeints - encode a small set of small integers in compressed format
+     632             :  *
+     633             :  * this routine is used internally by xdr3dfcoord, to encode a set of
+     634             :  * small integers to the buffer for writing to a file.
+     635             :  * Multiplication with fixed (specified maximum) sizes is used to get
+     636             :  * to one big, multibyte integer. Allthough the routine could be
+     637             :  * modified to handle sizes bigger than 16777216, or more than just
+     638             :  * a few integers, this is not done because the gain in compression
+     639             :  * isn't worth the effort. Note that overflowing the multiplication
+     640             :  * or the byte buffer (32 bytes) is unchecked and whould cause bad results.
+     641             :  * THese things are checked in the calling routines, so make sure not
+     642             :  * to remove those checks...
+     643             :  */
+     644             :  
+     645             : static void 
+     646        3960 : encodeints(int buf[], int num_of_ints, int num_of_bits,
+     647             :                    unsigned int sizes[], unsigned int nums[]) 
+     648             : {
+     649             : 
+     650             :     int i;
+     651             :     unsigned int bytes[32], num_of_bytes, bytecnt, tmp;
+     652             : 
+     653        3960 :     tmp = nums[0];
+     654             :     num_of_bytes = 0;
+     655             :     do 
+     656             :     {
+     657        7242 :                 bytes[num_of_bytes++] = tmp & 0xff;
+     658        7242 :                 tmp >>= 8;
+     659        7242 :     } while (tmp != 0);
+     660             : 
+     661       11880 :     for (i = 1; i < num_of_ints; i++) 
+     662             :     {
+     663        7920 :                 if (nums[i] >= sizes[i])
+     664             :         {
+     665           0 :                         fprintf(stderr,"major breakdown in encodeints - num %u doesn't "
+     666             :                                         "match size %u\n", nums[i], sizes[i]);
+     667           0 :                         abort();
+     668             :                 }
+     669             :                 /* use one step multiply */    
+     670             :                 tmp = nums[i];
+     671       28600 :                 for (bytecnt = 0; bytecnt < num_of_bytes; bytecnt++) 
+     672             :         {
+     673       20680 :                         tmp = bytes[bytecnt] * sizes[i] + tmp;
+     674       20680 :                         bytes[bytecnt] = tmp & 0xff;
+     675       20680 :                         tmp >>= 8;
+     676             :                 }
+     677       20013 :                 while (tmp != 0)
+     678             :         {
+     679       12093 :                         bytes[bytecnt++] = tmp & 0xff;
+     680       12093 :                         tmp >>= 8;
+     681             :                 }
+     682             :                 num_of_bytes = bytecnt;
+     683             :     }
+     684        3960 :     if (num_of_bits >= num_of_bytes * 8) 
+     685             :     {
+     686        7225 :                 for (i = 0; i < num_of_bytes; i++) 
+     687             :         {
+     688        6040 :                         encodebits(buf, 8, bytes[i]);
+     689             :                 }
+     690        1185 :                 encodebits(buf, num_of_bits - num_of_bytes * 8, 0);
+     691             :     } 
+     692             :     else
+     693             :     {
+     694       13295 :                 for (i = 0; i < num_of_bytes-1; i++)
+     695             :         {
+     696       10520 :                         encodebits(buf, 8, bytes[i]);
+     697             :                 }
+     698        2775 :                 encodebits(buf, num_of_bits- (num_of_bytes -1) * 8, bytes[i]);
+     699             :     }
+     700        3960 : }
+     701             : 
+     702             : 
+     703             : /*
+     704             :  * decodebits - decode number from buf using specified number of bits
+     705             :  * 
+     706             :  * extract the number of bits from the array buf and construct an integer
+     707             :  * from it. Return that value.
+     708             :  *
+     709             :  */
+     710             : 
+     711             : static int 
+     712       14579 : decodebits(int buf[], int num_of_bits) 
+     713             : {
+     714             : 
+     715             :     int cnt, num; 
+     716             :     unsigned int lastbits, lastbyte;
+     717             :     unsigned char * cbuf;
+     718       14579 :     int mask = (1 << num_of_bits) -1;
+     719             : 
+     720       14579 :     cbuf = ((unsigned char *)buf) + 3 * sizeof(*buf);
+     721       14579 :     cnt = buf[0];
+     722       14579 :     lastbits = (unsigned int) buf[1];
+     723       14579 :     lastbyte = (unsigned int) buf[2];
+     724             :     
+     725             :     num = 0;
+     726       26636 :     while (num_of_bits >= 8)
+     727             :     {
+     728       12057 :                 lastbyte = ( lastbyte << 8 ) | cbuf[cnt++];
+     729       12057 :                 num |=  (lastbyte >> lastbits) << (num_of_bits - 8);
+     730             :                 num_of_bits -=8;
+     731             :     }
+     732       14579 :     if (num_of_bits > 0) 
+     733             :     {
+     734        2522 :                 if (lastbits < num_of_bits) 
+     735             :         {
+     736         998 :                         lastbits += 8;
+     737         998 :                         lastbyte = (lastbyte << 8) | cbuf[cnt++];
+     738             :                 }
+     739        2522 :                 lastbits -= num_of_bits;
+     740        2522 :                 num |= (lastbyte >> lastbits) & ((1 << num_of_bits) -1);
+     741             :     }
+     742       14579 :     num &= mask;
+     743       14579 :     buf[0] = cnt;
+     744       14579 :     buf[1] = lastbits;
+     745       14579 :     buf[2] = lastbyte;
+     746       14579 :     return num; 
+     747             : }
+     748             : 
+     749             : /*
+     750             :  * decodeints - decode 'small' integers from the buf array
+     751             :  *
+     752             :  * this routine is the inverse from encodeints() and decodes the small integers
+     753             :  * written to buf by calculating the remainder and doing divisions with
+     754             :  * the given sizes[]. You need to specify the total number of bits to be
+     755             :  * used from buf in num_of_bits.
+     756             :  *
+     757             :  */
+     758             : 
+     759             : static void 
+     760        1936 : decodeints(int buf[], int num_of_ints, int num_of_bits,
+     761             :                    unsigned int sizes[], int nums[])
+     762             : {
+     763             : 
+     764             :         int bytes[32];
+     765             :         int i, j, num_of_bytes, p, num;
+     766             :   
+     767        1936 :         bytes[1] = bytes[2] = bytes[3] = 0;
+     768             :         num_of_bytes = 0;
+     769       13916 :         while (num_of_bits > 8)
+     770             :     {
+     771       11980 :                 bytes[num_of_bytes++] = decodebits(buf, 8);
+     772       11980 :                 num_of_bits -= 8;
+     773             :         }
+     774        1936 :         if (num_of_bits > 0)
+     775             :     {
+     776        1936 :                 bytes[num_of_bytes++] = decodebits(buf, num_of_bits);
+     777             :         }
+     778        5808 :         for (i = num_of_ints-1; i > 0; i--) 
+     779             :     {
+     780             :                 num = 0;
+     781       31704 :                 for (j = num_of_bytes-1; j >=0; j--) 
+     782             :         {
+     783       27832 :                         num = (num << 8) | bytes[j];
+     784       27832 :                         p = num / sizes[i];
+     785       27832 :                         bytes[j] = p;
+     786       27832 :                         num = num - p * sizes[i];
+     787             :                 }
+     788        3872 :                 nums[i] = num;
+     789             :         }
+     790        1936 :         nums[0] = bytes[0] | (bytes[1] << 8) | (bytes[2] << 16) | (bytes[3] << 24);
+     791        1936 : }
+     792             :     
+     793             : 
+     794             : static const int magicints[] = 
+     795             : {
+     796             :     0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
+     797             :     80, 101, 128, 161, 203, 256, 322, 406, 512, 645, 812, 1024, 1290,
+     798             :     1625, 2048, 2580, 3250, 4096, 5060, 6501, 8192, 10321, 13003, 
+     799             :     16384, 20642, 26007, 32768, 41285, 52015, 65536,82570, 104031, 
+     800             :     131072, 165140, 208063, 262144, 330280, 416127, 524287, 660561, 
+     801             :     832255, 1048576, 1321122, 1664510, 2097152, 2642245, 3329021, 
+     802             :     4194304, 5284491, 6658042, 8388607, 10568983, 13316085, 16777216 
+     803             : };
+     804             : 
+     805             : #define FIRSTIDX 9
+     806             : /* note that magicints[FIRSTIDX-1] == 0 */
+     807             : #define LASTIDX (sizeof(magicints) / sizeof(*magicints))
+     808             : 
+     809             : /* Compressed coordinate routines - modified from the original
+     810             :  * implementation by Frans v. Hoesel to make them threadsafe.
+     811             :  */
+     812             : int
+     813          28 : xdrfile_decompress_coord_float(float     *ptr,
+     814             :                                                            int       *size,
+     815             :                                                            float     *precision,
+     816             :                                                            XDRFILE*   xfp)
+     817             : {
+     818             :         int minint[3], maxint[3], *lip;
+     819             :         int smallidx, minidx, maxidx;
+     820             :         unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3;
+     821             :         int k, *buf1, *buf2, lsize, flag;
+     822             :         int smallnum, smaller, larger, i, is_smaller, run;
+     823             :         float *lfp, inv_precision;
+     824             :         int tmp, *thiscoord,  prevcoord[3];
+     825             :         unsigned int bitsize;
+     826             :   
+     827             :     bitsizeint[0] = 0;
+     828             :     bitsizeint[1] = 0;
+     829             :     bitsizeint[2] = 0;
+     830             : 
+     831          28 :         if(xfp==NULL || ptr==NULL)
+     832             :                 return -1;
+     833          28 :         tmp=xdrfile_read_int(&lsize,1,xfp);
+     834          28 :         if(tmp==0)
+     835             :                 return -1; /* return if we could not read size */
+     836          28 :         if (*size < lsize) 
+     837             :     {
+     838           0 :                 fprintf(stderr, "Requested to decompress %d coords, file contains %d\n",
+     839             :                                 *size, lsize);
+     840           0 :                 return -1;
+     841             :         }
+     842          28 :         *size = lsize;
+     843          28 :         size3 = *size * 3;
+     844          28 :         if(size3>xfp->buf1size) 
+     845             :     {
+     846           2 :                 if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL) 
+     847             :         {
+     848           0 :                         fprintf(stderr,"Cannot allocate memory for decompressing coordinates.\n");
+     849           0 :                         return -1; 
+     850             :                 }
+     851           2 :                 xfp->buf1size=size3;
+     852           2 :                 xfp->buf2size=size3*1.2;
+     853           2 :                 if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL)
+     854             :         {
+     855           0 :                         fprintf(stderr,"Cannot allocate memory for decompressing coordinates.\n");
+     856           0 :                         return -1;
+     857             :                 }
+     858             :         }
+     859             :         /* Dont bother with compression for three atoms or less */
+     860          28 :         if(*size<=9) 
+     861             :     {
+     862           0 :                 return xdrfile_read_float(ptr,size3,xfp)/3;
+     863             :                 /* return number of coords, not floats */
+     864             :         }
+     865             :         /* Compression-time if we got here. Read precision first */
+     866          28 :         xdrfile_read_float(precision,1,xfp);
+     867             :   
+     868             :         /* avoid repeated pointer dereferencing. */
+     869          28 :         buf1=xfp->buf1; 
+     870          28 :         buf2=xfp->buf2;
+     871             :         /* buf2[0-2] are special and do not contain actual data */
+     872          28 :         buf2[0] = buf2[1] = buf2[2] = 0;
+     873          28 :         xdrfile_read_int(minint,3,xfp);
+     874          28 :         xdrfile_read_int(maxint,3,xfp);
+     875             :   
+     876          28 :         sizeint[0] = maxint[0] - minint[0]+1;
+     877          28 :         sizeint[1] = maxint[1] - minint[1]+1;
+     878          28 :         sizeint[2] = maxint[2] - minint[2]+1;
+     879             :         
+     880             :         /* check if one of the sizes is to big to be multiplied */
+     881          28 :         if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
+     882             :     {
+     883           0 :                 bitsizeint[0] = sizeofint(sizeint[0]);
+     884           0 :                 bitsizeint[1] = sizeofint(sizeint[1]);
+     885           0 :                 bitsizeint[2] = sizeofint(sizeint[2]);
+     886             :                 bitsize = 0; /* flag the use of large sizes */
+     887             :         }
+     888             :     else 
+     889             :     {
+     890          28 :                 bitsize = sizeofints(3, sizeint);
+     891             :         }
+     892             :         
+     893          28 :         if (xdrfile_read_int(&smallidx,1,xfp) == 0) 
+     894             :                 return 0; /* not sure what has happened here or why we return... */
+     895          28 :         tmp=smallidx+8;
+     896             :         maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
+     897             :         minidx = maxidx - 8; /* often this equal smallidx */
+     898          28 :         tmp = smallidx-1;
+     899          28 :         tmp = (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
+     900          28 :         smaller = magicints[tmp] / 2;
+     901          28 :         smallnum = magicints[smallidx] / 2;
+     902          28 :         sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
+     903             :         larger = magicints[maxidx];
+     904             : 
+     905             :         /* buf2[0] holds the length in bytes */
+     906             :   
+     907          28 :         if (xdrfile_read_int(buf2,1,xfp) == 0)
+     908             :                 return 0;
+     909          28 :         if (xdrfile_read_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp) == 0)
+     910             :                 return 0;
+     911          28 :         buf2[0] = buf2[1] = buf2[2] = 0;
+     912             :   
+     913             :         lfp = ptr;
+     914          28 :         inv_precision = 1.0 / * precision;
+     915             :         run = 0;
+     916             :         i = 0;
+     917             :         lip = buf1;
+     918         387 :         while ( i < lsize ) 
+     919             :     {
+     920         359 :                 thiscoord = (int *)(lip) + i * 3;
+     921             :     
+     922         359 :                 if (bitsize == 0) 
+     923             :         {
+     924           0 :                         thiscoord[0] = decodebits(buf2, bitsizeint[0]);
+     925           0 :                         thiscoord[1] = decodebits(buf2, bitsizeint[1]);
+     926           0 :                         thiscoord[2] = decodebits(buf2, bitsizeint[2]);
+     927             :                 }
+     928             :         else
+     929             :         {
+     930         359 :                         decodeints(buf2, 3, bitsize, sizeint, thiscoord);
+     931             :                 }
+     932             :     
+     933         359 :                 i++;
+     934         359 :                 thiscoord[0] += minint[0];
+     935         359 :                 thiscoord[1] += minint[1];
+     936         359 :                 thiscoord[2] += minint[2];
+     937             :     
+     938             :                 prevcoord[0] = thiscoord[0];
+     939             :                 prevcoord[1] = thiscoord[1];
+     940             :                 prevcoord[2] = thiscoord[2];
+     941             :     
+     942         359 :                 flag = decodebits(buf2, 1);
+     943             :                 is_smaller = 0;
+     944         359 :                 if (flag == 1) 
+     945             :         {
+     946         304 :                         run = decodebits(buf2, 5);
+     947         304 :                         is_smaller = run % 3;
+     948         304 :                         run -= is_smaller;
+     949         304 :                         is_smaller--;
+     950             :                 }
+     951         359 :                 if (run > 0)
+     952             :         {
+     953         241 :                         thiscoord += 3;
+     954        1818 :                         for (k = 0; k < run; k+=3) 
+     955             :             {
+     956        1577 :                                 decodeints(buf2, 3, smallidx, sizesmall, thiscoord);
+     957        1577 :                                 i++;
+     958        1577 :                                 thiscoord[0] += prevcoord[0] - smallnum;
+     959        1577 :                                 thiscoord[1] += prevcoord[1] - smallnum;
+     960        1577 :                                 thiscoord[2] += prevcoord[2] - smallnum;
+     961        1577 :                                 if (k == 0) {
+     962             :                                         /* interchange first with second atom for better
+     963             :                                          * compression of water molecules
+     964             :                                          */
+     965         241 :                                         tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
+     966             :                                         prevcoord[0] = tmp;
+     967         241 :                                         tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
+     968             :                                         prevcoord[1] = tmp;
+     969         241 :                                         tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
+     970             :                                         prevcoord[2] = tmp;
+     971         241 :                                         *lfp++ = prevcoord[0] * inv_precision;
+     972         241 :                                         *lfp++ = prevcoord[1] * inv_precision;
+     973         241 :                                         *lfp++ = prevcoord[2] * inv_precision;
+     974             :                                 } else {
+     975             :                                         prevcoord[0] = thiscoord[0];
+     976             :                                         prevcoord[1] = thiscoord[1];
+     977             :                                         prevcoord[2] = thiscoord[2];
+     978             :                                 }
+     979        1577 :                                 *lfp++ = thiscoord[0] * inv_precision;
+     980        1577 :                                 *lfp++ = thiscoord[1] * inv_precision;
+     981        1577 :                                 *lfp++ = thiscoord[2] * inv_precision;
+     982             :                         }
+     983             :                 } 
+     984             :         else
+     985             :         {
+     986         118 :                         *lfp++ = thiscoord[0] * inv_precision;
+     987         118 :                         *lfp++ = thiscoord[1] * inv_precision;
+     988         118 :                         *lfp++ = thiscoord[2] * inv_precision;          
+     989             :                 }
+     990         359 :                 smallidx += is_smaller;
+     991         359 :                 if (is_smaller < 0) 
+     992             :         {
+     993             :                         smallnum = smaller;
+     994             :             
+     995          38 :                         if (smallidx > FIRSTIDX) 
+     996             :             {
+     997          38 :                                 smaller = magicints[smallidx - 1] /2;
+     998             :                         } 
+     999             :             else 
+    1000             :             {
+    1001             :                                 smaller = 0;
+    1002             :                         }
+    1003             :                 } 
+    1004         321 :         else if (is_smaller > 0)
+    1005             :         {
+    1006             :                         smaller = smallnum;
+    1007         230 :                         smallnum = magicints[smallidx] / 2;
+    1008             :                 }
+    1009         359 :                 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
+    1010             :         }
+    1011          28 :         return *size;
+    1012             : }
+    1013             : 
+    1014             : int
+    1015          72 : xdrfile_compress_coord_float(float   *ptr,
+    1016             :                                                          int      size,
+    1017             :                                                          float    precision,
+    1018             :                                                          XDRFILE* xfp)
+    1019             : {
+    1020             :         int minint[3], maxint[3], mindiff, *lip, diff;
+    1021             :         int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
+    1022             :         int minidx, maxidx;
+    1023             :         unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
+    1024             :         int k, *buf1, *buf2;
+    1025             :         int smallnum, smaller, larger, i, j, is_small, is_smaller, run, prevrun;
+    1026             :         float *lfp, lf;
+    1027             :         int tmp, tmpsum, *thiscoord,  prevcoord[3];
+    1028             :         unsigned int tmpcoord[30];
+    1029             :         int errval=1;
+    1030             :         unsigned int bitsize;
+    1031             :   
+    1032          72 :         if(xfp==NULL)
+    1033             :                 return -1;
+    1034          72 :         size3=3*size;
+    1035             :     
+    1036             :     bitsizeint[0] = 0;
+    1037             :     bitsizeint[1] = 0;
+    1038             :     bitsizeint[2] = 0;
+    1039             : 
+    1040          72 :         if(size3>xfp->buf1size)
+    1041             :     {
+    1042           5 :                 if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL) 
+    1043             :         {
+    1044           0 :                         fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
+    1045           0 :                         return -1;
+    1046             :                 }
+    1047           5 :                 xfp->buf1size=size3;
+    1048           5 :                 xfp->buf2size=size3*1.2;
+    1049           5 :                 if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL)
+    1050             :         {
+    1051           0 :                         fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
+    1052           0 :                         return -1;
+    1053             :                 }
+    1054             :         }
+    1055          72 :         if(xdrfile_write_int(&size,1,xfp)==0)
+    1056             :                 return -1; /* return if we could not write size */
+    1057             :         /* Dont bother with compression for three atoms or less */
+    1058          72 :         if(size<=9) 
+    1059             :     {
+    1060          12 :                 return xdrfile_write_float(ptr,size3,xfp)/3;
+    1061             :                 /* return number of coords, not floats */
+    1062             :         }
+    1063             :         /* Compression-time if we got here. Write precision first */
+    1064          60 :         if (precision <= 0)
+    1065           0 :                 precision = 1000;
+    1066          60 :         xdrfile_write_float(&precision,1,xfp);
+    1067             :         /* avoid repeated pointer dereferencing. */
+    1068          60 :         buf1=xfp->buf1; 
+    1069          60 :         buf2=xfp->buf2;
+    1070             :         /* buf2[0-2] are special and do not contain actual data */
+    1071          60 :         buf2[0] = buf2[1] = buf2[2] = 0;
+    1072          60 :         minint[0] = minint[1] = minint[2] = INT_MAX;
+    1073          60 :         maxint[0] = maxint[1] = maxint[2] = INT_MIN;
+    1074             :         prevrun = -1;
+    1075             :         lfp = ptr;
+    1076             :         lip = buf1;
+    1077             :         mindiff = INT_MAX;
+    1078             :         oldlint1 = oldlint2 = oldlint3 = 0;
+    1079        4020 :         while(lfp < ptr + size3 )
+    1080             :     {
+    1081             :                 /* find nearest integer */
+    1082        3960 :                 if (*lfp >= 0.0)
+    1083          35 :                         lf = *lfp * precision + 0.5;
+    1084             :                 else
+    1085        3925 :                         lf = *lfp * precision - 0.5;
+    1086        3960 :                 if (fabs(lf) > INT_MAX-2) 
+    1087             :         {
+    1088             :                         /* scaling would cause overflow */
+    1089           0 :                         fprintf(stderr,"Internal overflow compressing coordinates.\n");
+    1090             :                         errval=0;
+    1091             :                 }
+    1092        3960 :                 lint1 = lf;
+    1093        3960 :                 if (lint1 < minint[0]) minint[0] = lint1;
+    1094        3960 :                 if (lint1 > maxint[0]) maxint[0] = lint1;
+    1095        3960 :                 *lip++ = lint1;
+    1096             :                 lfp++;
+    1097        3960 :                 if (*lfp >= 0.0)
+    1098           4 :                         lf = *lfp * precision + 0.5;
+    1099             :                 else
+    1100        3956 :                         lf = *lfp * precision - 0.5;
+    1101        3960 :                 if (fabs(lf) > INT_MAX-2)
+    1102             :         {
+    1103             :                         /* scaling would cause overflow */
+    1104           0 :                         fprintf(stderr,"Internal overflow compressing coordinates.\n");
+    1105             :                         errval=0;
+    1106             :                 }
+    1107        3960 :                 lint2 = lf;
+    1108        3960 :                 if (lint2 < minint[1]) minint[1] = lint2;
+    1109        3960 :                 if (lint2 > maxint[1]) maxint[1] = lint2;
+    1110        3960 :                 *lip++ = lint2;
+    1111             :                 lfp++;
+    1112        3960 :                 if (*lfp >= 0.0)
+    1113        3960 :                         lf = *lfp * precision + 0.5;
+    1114             :                 else
+    1115           0 :                         lf = *lfp * precision - 0.5;
+    1116             :                 if (fabs(lf) > INT_MAX-2) 
+    1117             :         {
+    1118             :                         errval=0;      
+    1119             :                 }
+    1120        3960 :                 lint3 = lf;
+    1121        3960 :                 if (lint3 < minint[2]) minint[2] = lint3;
+    1122        3960 :                 if (lint3 > maxint[2]) maxint[2] = lint3;
+    1123        3960 :                 *lip++ = lint3;
+    1124        3960 :                 lfp++;
+    1125        3960 :                 diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
+    1126        3960 :                 if (diff < mindiff && lfp > ptr + 3)
+    1127             :                         mindiff = diff;
+    1128             :                 oldlint1 = lint1;
+    1129             :                 oldlint2 = lint2;
+    1130             :                 oldlint3 = lint3;
+    1131             :         }  
+    1132          60 :         xdrfile_write_int(minint,3,xfp);
+    1133          60 :         xdrfile_write_int(maxint,3,xfp);
+    1134             :   
+    1135          60 :         if ((float)maxint[0] - (float)minint[0] >= INT_MAX-2 ||
+    1136          60 :                 (float)maxint[1] - (float)minint[1] >= INT_MAX-2 ||
+    1137          60 :                 (float)maxint[2] - (float)minint[2] >= INT_MAX-2) {
+    1138             :                 /* turning value in unsigned by subtracting minint
+    1139             :                  * would cause overflow
+    1140             :                  */
+    1141           0 :                 fprintf(stderr,"Internal overflow compressing coordinates.\n");
+    1142             :                 errval=0;
+    1143             :         }
+    1144          60 :         sizeint[0] = maxint[0] - minint[0]+1;
+    1145          60 :         sizeint[1] = maxint[1] - minint[1]+1;
+    1146          60 :         sizeint[2] = maxint[2] - minint[2]+1;
+    1147             :   
+    1148             :         /* check if one of the sizes is to big to be multiplied */
+    1149          60 :         if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
+    1150             :     {
+    1151           0 :                 bitsizeint[0] = sizeofint(sizeint[0]);
+    1152           0 :                 bitsizeint[1] = sizeofint(sizeint[1]);
+    1153           0 :                 bitsizeint[2] = sizeofint(sizeint[2]);
+    1154             :                 bitsize = 0; /* flag the use of large sizes */
+    1155             :         }
+    1156             :     else
+    1157             :     {
+    1158          60 :                 bitsize = sizeofints(3, sizeint);
+    1159             :         }
+    1160             :         lip = buf1;
+    1161             :         luip = (unsigned int *) buf1;
+    1162          60 :         smallidx = FIRSTIDX;
+    1163        1046 :         while (smallidx < LASTIDX && magicints[smallidx] < mindiff)
+    1164             :     {
+    1165         986 :                 smallidx++;
+    1166             :         }
+    1167          60 :         xdrfile_write_int(&smallidx,1,xfp);
+    1168          60 :         tmp=smallidx+8;
+    1169          60 :         maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
+    1170          60 :         minidx = maxidx - 8; /* often this equal smallidx */
+    1171          60 :         tmp=smallidx-1;
+    1172          60 :         tmp= (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
+    1173          60 :         smaller = magicints[tmp] / 2;
+    1174          60 :         smallnum = magicints[smallidx] / 2;
+    1175          60 :         sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
+    1176          60 :         larger = magicints[maxidx] / 2;
+    1177             :         i = 0;
+    1178         814 :         while (i < size) 
+    1179             :     {
+    1180             :                 is_small = 0;
+    1181         754 :                 thiscoord = (int *)(luip) + i * 3;
+    1182         754 :                 if (smallidx < maxidx && i >= 1 &&
+    1183         531 :                         abs(thiscoord[0] - prevcoord[0]) < larger &&
+    1184         531 :                         abs(thiscoord[1] - prevcoord[1]) < larger &&
+    1185         531 :                         abs(thiscoord[2] - prevcoord[2]) < larger) {
+    1186             :                         is_smaller = 1;
+    1187             :                 } 
+    1188         223 :         else if (smallidx > minidx) 
+    1189             :         {
+    1190             :                         is_smaller = -1;
+    1191             :                 }
+    1192             :         else
+    1193             :         {
+    1194             :                         is_smaller = 0;
+    1195             :                 }
+    1196         754 :                 if (i + 1 < size) 
+    1197             :         {
+    1198         738 :                         if (abs(thiscoord[0] - thiscoord[3]) < smallnum &&
+    1199         651 :                                 abs(thiscoord[1] - thiscoord[4]) < smallnum &&
+    1200         580 :                                 abs(thiscoord[2] - thiscoord[5]) < smallnum) 
+    1201             :             {
+    1202             :                                 /* interchange first with second atom for better
+    1203             :                                  * compression of water molecules
+    1204             :                                  */
+    1205         532 :                                 tmp = thiscoord[0]; thiscoord[0] = thiscoord[3];
+    1206         532 :                                 thiscoord[3] = tmp;
+    1207         532 :                                 tmp = thiscoord[1]; thiscoord[1] = thiscoord[4];
+    1208         532 :                                 thiscoord[4] = tmp;
+    1209         532 :                                 tmp = thiscoord[2]; thiscoord[2] = thiscoord[5];
+    1210         532 :                                 thiscoord[5] = tmp;
+    1211             :                                 is_small = 1;
+    1212             :                         } 
+    1213             :                 }
+    1214         754 :                 tmpcoord[0] = thiscoord[0] - minint[0];
+    1215         754 :                 tmpcoord[1] = thiscoord[1] - minint[1];
+    1216         754 :                 tmpcoord[2] = thiscoord[2] - minint[2];
+    1217         754 :                 if (bitsize == 0) 
+    1218             :         {
+    1219           0 :                         encodebits(buf2, bitsizeint[0], tmpcoord[0]);
+    1220           0 :                         encodebits(buf2, bitsizeint[1], tmpcoord[1]);
+    1221           0 :                         encodebits(buf2, bitsizeint[2], tmpcoord[2]);
+    1222             :                 } 
+    1223             :         else
+    1224             :         {
+    1225         754 :                         encodeints(buf2, 3, bitsize, sizeint, tmpcoord);
+    1226             :                 }
+    1227         754 :                 prevcoord[0] = thiscoord[0];
+    1228         754 :                 prevcoord[1] = thiscoord[1];
+    1229         754 :                 prevcoord[2] = thiscoord[2];
+    1230         754 :                 thiscoord = thiscoord + 3;
+    1231             :                 i++;
+    1232             : 
+    1233             :                 run = 0;
+    1234         754 :                 if (is_small == 0 && is_smaller == -1)
+    1235             :                         is_smaller = 0;
+    1236        3960 :                 while (is_small && run < 8*3)
+    1237             :         {
+    1238             :                         tmpsum=0;
+    1239       12824 :                         for(j=0;j<3;j++) 
+    1240             :             {
+    1241        9618 :                                 tmp=thiscoord[j] - prevcoord[j];
+    1242        9618 :                                 tmpsum+=tmp*tmp;
+    1243             :                         }
+    1244        3206 :                         if (is_smaller == -1 && tmpsum >= smaller * smaller)
+    1245             :             {
+    1246             :                                 is_smaller = 0;
+    1247             :                         }
+    1248             :       
+    1249        3206 :                         tmpcoord[run++] = thiscoord[0] - prevcoord[0] + smallnum;
+    1250        3206 :                         tmpcoord[run++] = thiscoord[1] - prevcoord[1] + smallnum;
+    1251        3206 :                         tmpcoord[run++] = thiscoord[2] - prevcoord[2] + smallnum;
+    1252             :       
+    1253        3206 :                         prevcoord[0] = thiscoord[0];
+    1254        3206 :                         prevcoord[1] = thiscoord[1];
+    1255        3206 :                         prevcoord[2] = thiscoord[2];
+    1256             :       
+    1257        3206 :                         i++;
+    1258        3206 :                         thiscoord = thiscoord + 3;
+    1259             :                         is_small = 0;
+    1260        3206 :                         if (i < size &&
+    1261        3162 :                                 abs(thiscoord[0] - prevcoord[0]) < smallnum &&
+    1262        3083 :                                 abs(thiscoord[1] - prevcoord[1]) < smallnum &&
+    1263        3027 :                                 abs(thiscoord[2] - prevcoord[2]) < smallnum)
+    1264             :             {
+    1265             :                                 is_small = 1;
+    1266             :                         }
+    1267             :                 }
+    1268         754 :                 if (run != prevrun || is_smaller != 0) 
+    1269             :         {
+    1270             :                         prevrun = run;
+    1271         717 :                         encodebits(buf2, 1, 1); /* flag the change in run-length */
+    1272         717 :                         encodebits(buf2, 5, run+is_smaller+1);
+    1273             :                 } 
+    1274             :         else 
+    1275             :         {
+    1276          37 :                         encodebits(buf2, 1, 0); /* flag the fact that runlength did not change */
+    1277             :                 }
+    1278        3960 :                 for (k=0; k < run; k+=3) 
+    1279             :         {
+    1280        3206 :                         encodeints(buf2, 3, smallidx, sizesmall, &tmpcoord[k]);     
+    1281             :                 }
+    1282         754 :                 if (is_smaller != 0) 
+    1283             :         {
+    1284         652 :                         smallidx += is_smaller;
+    1285         652 :                         if (is_smaller < 0) 
+    1286             :             {
+    1287             :                                 smallnum = smaller;
+    1288         121 :                                 smaller = magicints[smallidx-1] / 2;
+    1289             :                         } 
+    1290             :             else 
+    1291             :             {
+    1292             :                                 smaller = smallnum;
+    1293         531 :                                 smallnum = magicints[smallidx] / 2;
+    1294             :                         }
+    1295         652 :                         sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
+    1296             :                 }   
+    1297             :         }
+    1298          60 :         if (buf2[1] != 0) buf2[0]++;
+    1299          60 :         xdrfile_write_int(buf2,1,xfp); /* buf2[0] holds the length in bytes */
+    1300          60 :         tmp=xdrfile_write_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp);
+    1301          60 :         if(tmp==(unsigned int)buf2[0])
+    1302          60 :                 return size;
+    1303             :         else
+    1304             :                 return -1;
+    1305             : }
+    1306             : 
+    1307             : 
+    1308             : int
+    1309           0 : xdrfile_decompress_coord_double(double     *ptr, 
+    1310             :                                                                 int        *size,
+    1311             :                                                                 double     *precision,
+    1312             :                                                                 XDRFILE*   xfp)
+    1313             : {
+    1314             :         int minint[3], maxint[3], *lip;
+    1315             :         int smallidx, minidx, maxidx;
+    1316             :         unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3;
+    1317             :         int k, *buf1, *buf2, lsize, flag;
+    1318             :         int smallnum, smaller, larger, i, is_smaller, run;
+    1319             :         double *lfp, inv_precision;
+    1320             :         float float_prec, tmpdata[30];
+    1321             :         int tmp, *thiscoord,  prevcoord[3];
+    1322             :         unsigned int bitsize;
+    1323             :   
+    1324             :     bitsizeint[0] = 0;
+    1325             :     bitsizeint[1] = 0;
+    1326             :     bitsizeint[2] = 0;
+    1327             : 
+    1328           0 :         if(xfp==NULL || ptr==NULL)
+    1329             :                 return -1;
+    1330           0 :         tmp=xdrfile_read_int(&lsize,1,xfp);
+    1331           0 :         if(tmp==0)
+    1332             :                 return -1; /* return if we could not read size */
+    1333           0 :         if (*size < lsize) 
+    1334             :     {
+    1335           0 :                 fprintf(stderr, "Requested to decompress %d coords, file contains %d\n",
+    1336             :                                 *size, lsize);
+    1337           0 :                 return -1;
+    1338             :         }
+    1339           0 :         *size = lsize;
+    1340           0 :         size3 = *size * 3;
+    1341           0 :         if(size3>xfp->buf1size) 
+    1342             :     {
+    1343           0 :                 if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL) 
+    1344             :         {
+    1345           0 :                         fprintf(stderr,"Cannot allocate memory for decompression coordinates.\n");
+    1346           0 :                         return -1; 
+    1347             :                 }
+    1348           0 :                 xfp->buf1size=size3;
+    1349           0 :                 xfp->buf2size=size3*1.2;
+    1350           0 :                 if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL)
+    1351             :         {
+    1352           0 :                         fprintf(stderr,"Cannot allocate memory for decompressing coordinates.\n");
+    1353           0 :                         return -1;
+    1354             :                 }
+    1355             :         }
+    1356             :         /* Dont bother with compression for three atoms or less */
+    1357           0 :         if(*size<=9)
+    1358             :     {
+    1359           0 :                 tmp=xdrfile_read_float(tmpdata,size3,xfp);
+    1360           0 :                 for(i=0;i<9*3;i++)
+    1361           0 :                         ptr[i]=tmpdata[i];
+    1362           0 :                 return tmp/3;
+    1363             :                 /* return number of coords, not floats */
+    1364             :         }
+    1365             :         /* Compression-time if we got here. Read precision first */
+    1366           0 :         xdrfile_read_float(&float_prec,1,xfp);
+    1367           0 :         *precision=float_prec;
+    1368             :         /* avoid repeated pointer dereferencing. */
+    1369           0 :         buf1=xfp->buf1; 
+    1370           0 :         buf2=xfp->buf2;
+    1371             :         /* buf2[0-2] are special and do not contain actual data */
+    1372           0 :         buf2[0] = buf2[1] = buf2[2] = 0;
+    1373           0 :         xdrfile_read_int(minint,3,xfp);
+    1374           0 :         xdrfile_read_int(maxint,3,xfp);
+    1375             :   
+    1376           0 :         sizeint[0] = maxint[0] - minint[0]+1;
+    1377           0 :         sizeint[1] = maxint[1] - minint[1]+1;
+    1378           0 :         sizeint[2] = maxint[2] - minint[2]+1;
+    1379             :         
+    1380             :         /* check if one of the sizes is to big to be multiplied */
+    1381           0 :         if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff)
+    1382             :     {
+    1383           0 :                 bitsizeint[0] = sizeofint(sizeint[0]);
+    1384           0 :                 bitsizeint[1] = sizeofint(sizeint[1]);
+    1385           0 :                 bitsizeint[2] = sizeofint(sizeint[2]);
+    1386             :                 bitsize = 0; /* flag the use of large sizes */
+    1387             :         }
+    1388             :     else 
+    1389             :     {
+    1390           0 :                 bitsize = sizeofints(3, sizeint);
+    1391             :         }
+    1392             :         
+    1393           0 :         if (xdrfile_read_int(&smallidx,1,xfp) == 0) 
+    1394             :                 return 0;
+    1395           0 :         tmp=smallidx+8;
+    1396             :         maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
+    1397             :         minidx = maxidx - 8; /* often this equal smallidx */
+    1398           0 :         tmp = smallidx-1;
+    1399           0 :         tmp = (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
+    1400           0 :         smaller = magicints[tmp] / 2;
+    1401           0 :         smallnum = magicints[smallidx] / 2;
+    1402           0 :         sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
+    1403             :         larger = magicints[maxidx];
+    1404             : 
+    1405             :         /* buf2[0] holds the length in bytes */
+    1406             :   
+    1407           0 :         if (xdrfile_read_int(buf2,1,xfp) == 0)
+    1408             :                 return 0;
+    1409           0 :         if (xdrfile_read_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp) == 0)
+    1410             :                 return 0;
+    1411           0 :         buf2[0] = buf2[1] = buf2[2] = 0;
+    1412             :   
+    1413             :         lfp = ptr;
+    1414           0 :         inv_precision = 1.0 / * precision;
+    1415             :         run = 0;
+    1416             :         i = 0;
+    1417             :         lip = buf1;
+    1418           0 :         while ( i < lsize ) 
+    1419             :     {
+    1420           0 :                 thiscoord = (int *)(lip) + i * 3;
+    1421             :     
+    1422           0 :                 if (bitsize == 0) 
+    1423             :         {
+    1424           0 :                         thiscoord[0] = decodebits(buf2, bitsizeint[0]);
+    1425           0 :                         thiscoord[1] = decodebits(buf2, bitsizeint[1]);
+    1426           0 :                         thiscoord[2] = decodebits(buf2, bitsizeint[2]);
+    1427             :                 } else {
+    1428           0 :                         decodeints(buf2, 3, bitsize, sizeint, thiscoord);
+    1429             :                 }
+    1430             :     
+    1431           0 :                 i++;
+    1432           0 :                 thiscoord[0] += minint[0];
+    1433           0 :                 thiscoord[1] += minint[1];
+    1434           0 :                 thiscoord[2] += minint[2];
+    1435             :     
+    1436             :                 prevcoord[0] = thiscoord[0];
+    1437             :                 prevcoord[1] = thiscoord[1];
+    1438             :                 prevcoord[2] = thiscoord[2];
+    1439             :     
+    1440           0 :                 flag = decodebits(buf2, 1);
+    1441             :                 is_smaller = 0;
+    1442           0 :                 if (flag == 1) 
+    1443             :         {
+    1444           0 :                         run = decodebits(buf2, 5);
+    1445           0 :                         is_smaller = run % 3;
+    1446           0 :                         run -= is_smaller;
+    1447           0 :                         is_smaller--;
+    1448             :                 }
+    1449           0 :                 if (run > 0) 
+    1450             :         {
+    1451           0 :                         thiscoord += 3;
+    1452           0 :                         for (k = 0; k < run; k+=3) 
+    1453             :             {
+    1454           0 :                                 decodeints(buf2, 3, smallidx, sizesmall, thiscoord);
+    1455           0 :                                 i++;
+    1456           0 :                                 thiscoord[0] += prevcoord[0] - smallnum;
+    1457           0 :                                 thiscoord[1] += prevcoord[1] - smallnum;
+    1458           0 :                                 thiscoord[2] += prevcoord[2] - smallnum;
+    1459           0 :                                 if (k == 0)
+    1460             :                 {
+    1461             :                                         /* interchange first with second atom for better
+    1462             :                                          * compression of water molecules
+    1463             :                                          */
+    1464           0 :                                         tmp = thiscoord[0]; thiscoord[0] = prevcoord[0];
+    1465             :                                         prevcoord[0] = tmp;
+    1466           0 :                                         tmp = thiscoord[1]; thiscoord[1] = prevcoord[1];
+    1467             :                                         prevcoord[1] = tmp;
+    1468           0 :                                         tmp = thiscoord[2]; thiscoord[2] = prevcoord[2];
+    1469             :                                         prevcoord[2] = tmp;
+    1470           0 :                                         *lfp++ = prevcoord[0] * inv_precision;
+    1471           0 :                                         *lfp++ = prevcoord[1] * inv_precision;
+    1472           0 :                                         *lfp++ = prevcoord[2] * inv_precision;
+    1473             :                                 }
+    1474             :                 else 
+    1475             :                 {
+    1476             :                                         prevcoord[0] = thiscoord[0];
+    1477             :                                         prevcoord[1] = thiscoord[1];
+    1478             :                                         prevcoord[2] = thiscoord[2];
+    1479             :                                 }
+    1480           0 :                                 *lfp++ = thiscoord[0] * inv_precision;
+    1481           0 :                                 *lfp++ = thiscoord[1] * inv_precision;
+    1482           0 :                                 *lfp++ = thiscoord[2] * inv_precision;
+    1483             :                         }
+    1484             :                 } else {
+    1485           0 :                         *lfp++ = thiscoord[0] * inv_precision;
+    1486           0 :                         *lfp++ = thiscoord[1] * inv_precision;
+    1487           0 :                         *lfp++ = thiscoord[2] * inv_precision;          
+    1488             :                 }
+    1489           0 :                 smallidx += is_smaller;
+    1490           0 :                 if (is_smaller < 0) {
+    1491             :                         smallnum = smaller;
+    1492           0 :                         if (smallidx > FIRSTIDX) {
+    1493           0 :                                 smaller = magicints[smallidx - 1] /2;
+    1494             :                         } else {
+    1495             :                                 smaller = 0;
+    1496             :                         }
+    1497           0 :                 } else if (is_smaller > 0) {
+    1498             :                         smaller = smallnum;
+    1499           0 :                         smallnum = magicints[smallidx] / 2;
+    1500             :                 }
+    1501           0 :                 sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx] ;
+    1502             :         }
+    1503           0 :         return *size;
+    1504             : }
+    1505             : 
+    1506             : int
+    1507           0 : xdrfile_compress_coord_double(double   *ptr,
+    1508             :                                                           int      size,
+    1509             :                                                           double    precision,
+    1510             :                                                           XDRFILE* xfp)
+    1511             : {
+    1512             :         int minint[3], maxint[3], mindiff, *lip, diff;
+    1513             :         int lint1, lint2, lint3, oldlint1, oldlint2, oldlint3, smallidx;
+    1514             :         int minidx, maxidx;
+    1515             :         unsigned sizeint[3], sizesmall[3], bitsizeint[3], size3, *luip;
+    1516             :         int k, *buf1, *buf2;
+    1517             :         int smallnum, smaller, larger, i, j, is_small, is_smaller, run, prevrun;
+    1518             :         double *lfp;
+    1519             :         float float_prec, lf,tmpdata[30];
+    1520             :         int tmp, tmpsum, *thiscoord,  prevcoord[3];
+    1521             :         unsigned int tmpcoord[30];
+    1522             :         int errval=1;
+    1523             :         unsigned int bitsize;
+    1524             :   
+    1525             :     bitsizeint[0] = 0;
+    1526             :     bitsizeint[1] = 0;
+    1527             :     bitsizeint[2] = 0;
+    1528             : 
+    1529           0 :         if(xfp==NULL)
+    1530             :                 return -1;
+    1531           0 :         size3=3*size;
+    1532           0 :         if(size3>xfp->buf1size) {
+    1533           0 :                 if((xfp->buf1=(int *)malloc(sizeof(int)*size3))==NULL) {
+    1534           0 :                         fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
+    1535           0 :                         return -1;
+    1536             :                 }
+    1537           0 :                 xfp->buf1size=size3;
+    1538           0 :                 xfp->buf2size=size3*1.2;
+    1539           0 :                 if((xfp->buf2=(int *)malloc(sizeof(int)*xfp->buf2size))==NULL) {
+    1540           0 :                         fprintf(stderr,"Cannot allocate memory for compressing coordinates.\n");
+    1541           0 :                         return -1;
+    1542             :                 }
+    1543             :         }
+    1544           0 :         if(xdrfile_write_int(&size,1,xfp)==0)
+    1545             :                 return -1; /* return if we could not write size */
+    1546             :         /* Dont bother with compression for three atoms or less */
+    1547           0 :         if(size<=9) {
+    1548           0 :                 for(i=0;i<9*3;i++)
+    1549           0 :                         tmpdata[i]=ptr[i];
+    1550           0 :                 return xdrfile_write_float(tmpdata,size3,xfp)/3;
+    1551             :                 /* return number of coords, not floats */
+    1552             :         }
+    1553             :         /* Compression-time if we got here. Write precision first */
+    1554           0 :         if (precision <= 0)
+    1555             :                 precision = 1000;
+    1556           0 :         float_prec=precision;
+    1557           0 :         xdrfile_write_float(&float_prec,1,xfp);
+    1558             :         /* avoid repeated pointer dereferencing. */
+    1559           0 :         buf1=xfp->buf1; 
+    1560           0 :         buf2=xfp->buf2;
+    1561             :         /* buf2[0-2] are special and do not contain actual data */
+    1562           0 :         buf2[0] = buf2[1] = buf2[2] = 0;
+    1563           0 :         minint[0] = minint[1] = minint[2] = INT_MAX;
+    1564           0 :         maxint[0] = maxint[1] = maxint[2] = INT_MIN;
+    1565             :         prevrun = -1;
+    1566             :         lfp = ptr;
+    1567             :         lip = buf1;
+    1568             :         mindiff = INT_MAX;
+    1569             :         oldlint1 = oldlint2 = oldlint3 = 0;
+    1570           0 :         while(lfp < ptr + size3 ) {
+    1571             :                 /* find nearest integer */
+    1572           0 :                 if (*lfp >= 0.0)
+    1573           0 :                         lf = (float)*lfp * float_prec + 0.5;
+    1574             :                 else
+    1575           0 :                         lf = (float)*lfp * float_prec - 0.5;
+    1576           0 :                 if (fabs(lf) > INT_MAX-2) {
+    1577             :                         /* scaling would cause overflow */
+    1578           0 :                         fprintf(stderr,"Internal overflow compressing coordinates.\n");
+    1579             :                         errval=0;
+    1580             :                 }
+    1581           0 :                 lint1 = lf;
+    1582           0 :                 if (lint1 < minint[0]) minint[0] = lint1;
+    1583           0 :                 if (lint1 > maxint[0]) maxint[0] = lint1;
+    1584           0 :                 *lip++ = lint1;
+    1585             :                 lfp++;
+    1586           0 :                 if (*lfp >= 0.0)
+    1587           0 :                         lf = (float)*lfp * float_prec + 0.5;
+    1588             :                 else
+    1589           0 :                         lf = (float)*lfp * float_prec - 0.5;
+    1590           0 :                 if (fabs(lf) > INT_MAX-2) {
+    1591             :                         /* scaling would cause overflow */
+    1592           0 :                         fprintf(stderr,"Internal overflow compressing coordinates.\n");
+    1593             :                         errval=0;
+    1594             :                 }
+    1595           0 :                 lint2 = lf;
+    1596           0 :                 if (lint2 < minint[1]) minint[1] = lint2;
+    1597           0 :                 if (lint2 > maxint[1]) maxint[1] = lint2;
+    1598           0 :                 *lip++ = lint2;
+    1599             :                 lfp++;
+    1600           0 :                 if (*lfp >= 0.0)
+    1601           0 :                         lf = (float)*lfp * float_prec + 0.5;
+    1602             :                 else
+    1603           0 :                         lf = (float)*lfp * float_prec - 0.5;
+    1604             :                 if (fabs(lf) > INT_MAX-2) {
+    1605             :                         errval=0;      
+    1606             :                 }
+    1607           0 :                 lint3 = lf;
+    1608           0 :                 if (lint3 < minint[2]) minint[2] = lint3;
+    1609           0 :                 if (lint3 > maxint[2]) maxint[2] = lint3;
+    1610           0 :                 *lip++ = lint3;
+    1611           0 :                 lfp++;
+    1612           0 :                 diff = abs(oldlint1-lint1)+abs(oldlint2-lint2)+abs(oldlint3-lint3);
+    1613           0 :                 if (diff < mindiff && lfp > ptr + 3)
+    1614             :                         mindiff = diff;
+    1615             :                 oldlint1 = lint1;
+    1616             :                 oldlint2 = lint2;
+    1617             :                 oldlint3 = lint3;
+    1618             :         }  
+    1619           0 :         xdrfile_write_int(minint,3,xfp);
+    1620           0 :         xdrfile_write_int(maxint,3,xfp);
+    1621             :   
+    1622           0 :         if ((float)maxint[0] - (float)minint[0] >= INT_MAX-2 ||
+    1623           0 :                 (float)maxint[1] - (float)minint[1] >= INT_MAX-2 ||
+    1624           0 :                 (float)maxint[2] - (float)minint[2] >= INT_MAX-2) {
+    1625             :                 /* turning value in unsigned by subtracting minint
+    1626             :                  * would cause overflow
+    1627             :                  */
+    1628           0 :                 fprintf(stderr,"Internal overflow compressing coordinates.\n");
+    1629             :                 errval=0;
+    1630             :         }
+    1631           0 :         sizeint[0] = maxint[0] - minint[0]+1;
+    1632           0 :         sizeint[1] = maxint[1] - minint[1]+1;
+    1633           0 :         sizeint[2] = maxint[2] - minint[2]+1;
+    1634             :   
+    1635             :         /* check if one of the sizes is to big to be multiplied */
+    1636           0 :         if ((sizeint[0] | sizeint[1] | sizeint[2] ) > 0xffffff) {
+    1637           0 :                 bitsizeint[0] = sizeofint(sizeint[0]);
+    1638           0 :                 bitsizeint[1] = sizeofint(sizeint[1]);
+    1639           0 :                 bitsizeint[2] = sizeofint(sizeint[2]);
+    1640             :                 bitsize = 0; /* flag the use of large sizes */
+    1641             :         } else {
+    1642           0 :                 bitsize = sizeofints(3, sizeint);
+    1643             :         }
+    1644             :         lip = buf1;
+    1645             :         luip = (unsigned int *) buf1;
+    1646           0 :         smallidx = FIRSTIDX;
+    1647           0 :         while (smallidx < LASTIDX && magicints[smallidx] < mindiff) {
+    1648           0 :                 smallidx++;
+    1649             :         }
+    1650           0 :         xdrfile_write_int(&smallidx,1,xfp);
+    1651           0 :         tmp=smallidx+8;
+    1652           0 :         maxidx = (LASTIDX<tmp) ? LASTIDX : tmp;
+    1653           0 :         minidx = maxidx - 8; /* often this equal smallidx */
+    1654           0 :         tmp=smallidx-1;
+    1655           0 :         tmp= (FIRSTIDX>tmp) ? FIRSTIDX : tmp;
+    1656           0 :         smaller = magicints[tmp] / 2;
+    1657           0 :         smallnum = magicints[smallidx] / 2;
+    1658           0 :         sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
+    1659           0 :         larger = magicints[maxidx] / 2;
+    1660             :         i = 0;
+    1661           0 :         while (i < size) {
+    1662             :                 is_small = 0;
+    1663           0 :                 thiscoord = (int *)(luip) + i * 3;
+    1664           0 :                 if (smallidx < maxidx && i >= 1 &&
+    1665           0 :                         abs(thiscoord[0] - prevcoord[0]) < larger &&
+    1666           0 :                         abs(thiscoord[1] - prevcoord[1]) < larger &&
+    1667           0 :                         abs(thiscoord[2] - prevcoord[2]) < larger) {
+    1668             :                         is_smaller = 1;
+    1669           0 :                 } else if (smallidx > minidx) {
+    1670             :                         is_smaller = -1;
+    1671             :                 } else {
+    1672             :                         is_smaller = 0;
+    1673             :                 }
+    1674           0 :                 if (i + 1 < size) {
+    1675           0 :                         if (abs(thiscoord[0] - thiscoord[3]) < smallnum &&
+    1676           0 :                                 abs(thiscoord[1] - thiscoord[4]) < smallnum &&
+    1677           0 :                                 abs(thiscoord[2] - thiscoord[5]) < smallnum) {
+    1678             :                                 /* interchange first with second atom for better
+    1679             :                                  * compression of water molecules
+    1680             :                                  */
+    1681           0 :                                 tmp = thiscoord[0]; thiscoord[0] = thiscoord[3];
+    1682           0 :                                 thiscoord[3] = tmp;
+    1683           0 :                                 tmp = thiscoord[1]; thiscoord[1] = thiscoord[4];
+    1684           0 :                                 thiscoord[4] = tmp;
+    1685           0 :                                 tmp = thiscoord[2]; thiscoord[2] = thiscoord[5];
+    1686           0 :                                 thiscoord[5] = tmp;
+    1687             :                                 is_small = 1;
+    1688             :                         } 
+    1689             :                 }
+    1690           0 :                 tmpcoord[0] = thiscoord[0] - minint[0];
+    1691           0 :                 tmpcoord[1] = thiscoord[1] - minint[1];
+    1692           0 :                 tmpcoord[2] = thiscoord[2] - minint[2];
+    1693           0 :                 if (bitsize == 0) {
+    1694           0 :                         encodebits(buf2, bitsizeint[0], tmpcoord[0]);
+    1695           0 :                         encodebits(buf2, bitsizeint[1], tmpcoord[1]);
+    1696           0 :                         encodebits(buf2, bitsizeint[2], tmpcoord[2]);
+    1697             :                 } else {
+    1698           0 :                         encodeints(buf2, 3, bitsize, sizeint, tmpcoord);
+    1699             :                 }
+    1700           0 :                 prevcoord[0] = thiscoord[0];
+    1701           0 :                 prevcoord[1] = thiscoord[1];
+    1702           0 :                 prevcoord[2] = thiscoord[2];
+    1703           0 :                 thiscoord = thiscoord + 3;
+    1704             :                 i++;
+    1705             : 
+    1706             :                 run = 0;
+    1707           0 :                 if (is_small == 0 && is_smaller == -1)
+    1708             :                         is_smaller = 0;
+    1709           0 :                 while (is_small && run < 8*3) {
+    1710             :                         tmpsum=0;
+    1711           0 :                         for(j=0;j<3;j++) {
+    1712           0 :                                 tmp=thiscoord[j] - prevcoord[j];
+    1713           0 :                                 tmpsum+=tmp*tmp;
+    1714             :                         }
+    1715           0 :                         if (is_smaller == -1 && tmpsum >= smaller * smaller) {
+    1716             :                                 is_smaller = 0;
+    1717             :                         }
+    1718             :       
+    1719           0 :                         tmpcoord[run++] = thiscoord[0] - prevcoord[0] + smallnum;
+    1720           0 :                         tmpcoord[run++] = thiscoord[1] - prevcoord[1] + smallnum;
+    1721           0 :                         tmpcoord[run++] = thiscoord[2] - prevcoord[2] + smallnum;
+    1722             :       
+    1723           0 :                         prevcoord[0] = thiscoord[0];
+    1724           0 :                         prevcoord[1] = thiscoord[1];
+    1725           0 :                         prevcoord[2] = thiscoord[2];
+    1726             :       
+    1727           0 :                         i++;
+    1728           0 :                         thiscoord = thiscoord + 3;
+    1729             :                         is_small = 0;
+    1730           0 :                         if (i < size &&
+    1731           0 :                                 abs(thiscoord[0] - prevcoord[0]) < smallnum &&
+    1732           0 :                                 abs(thiscoord[1] - prevcoord[1]) < smallnum &&
+    1733           0 :                                 abs(thiscoord[2] - prevcoord[2]) < smallnum) {
+    1734             :                                 is_small = 1;
+    1735             :                         }
+    1736             :                 }
+    1737           0 :                 if (run != prevrun || is_smaller != 0) {
+    1738             :                         prevrun = run;
+    1739           0 :                         encodebits(buf2, 1, 1); /* flag the change in run-length */
+    1740           0 :                         encodebits(buf2, 5, run+is_smaller+1);
+    1741             :                 } else {
+    1742           0 :                         encodebits(buf2, 1, 0); /* flag the fact that runlength did not change */
+    1743             :                 }
+    1744           0 :                 for (k=0; k < run; k+=3) {
+    1745           0 :                         encodeints(buf2, 3, smallidx, sizesmall, &tmpcoord[k]);     
+    1746             :                 }
+    1747           0 :                 if (is_smaller != 0) {
+    1748           0 :                         smallidx += is_smaller;
+    1749           0 :                         if (is_smaller < 0) {
+    1750             :                                 smallnum = smaller;
+    1751           0 :                                 smaller = magicints[smallidx-1] / 2;
+    1752             :                         } else {
+    1753             :                                 smaller = smallnum;
+    1754           0 :                                 smallnum = magicints[smallidx] / 2;
+    1755             :                         }
+    1756           0 :                         sizesmall[0] = sizesmall[1] = sizesmall[2] = magicints[smallidx];
+    1757             :                 }   
+    1758             :         }
+    1759           0 :         if (buf2[1] != 0) buf2[0]++;
+    1760           0 :         xdrfile_write_int(buf2,1,xfp); /* buf2[0] holds the length in bytes */
+    1761           0 :         tmp=xdrfile_write_opaque((char *)&(buf2[3]),(unsigned int)buf2[0],xfp);
+    1762           0 :         if(tmp==(unsigned int)buf2[0])
+    1763           0 :                 return size;
+    1764             :         else
+    1765             :                 return -1; 
+    1766             : }
+    1767             : 
+    1768             : 
+    1769             : /* Dont try do document Fortran interface, since
+    1770             :  * Doxygen barfs at the F77_FUNC macro 
+    1771             :  */
+    1772             : #ifndef DOXYGEN 
+    1773             : 
+    1774             : /*************************************************************
+    1775             :  * Fortran77 interface for reading/writing portable data     *
+    1776             :  * The routine are not threadsafe when called from Fortran   *
+    1777             :  * (as they are when called from C) unless you compile with  *
+    1778             :  * this file with posix thread support.                      *
+    1779             :  * Note that these are not multithread-safe.                 * 
+    1780             :  *************************************************************/
+    1781             : #define MAX_FORTRAN_XDR 1024
+    1782             : static XDRFILE *f77xdr[MAX_FORTRAN_XDR]; /* array of file handles */
+    1783             : static int      f77init = 1;             /* zero array first time */
+    1784             : 
+    1785             : /* internal to this file: C<-->Fortran string conversion */
+    1786             : static int ftocstr(char *dest, int dest_len, char *src, int src_len);
+    1787             : static int ctofstr(char *dest, int dest_len, char *src);
+    1788             : 
+    1789             : 
+    1790             : void
+    1791           0 : F77_FUNC(xdropen,XDROPEN)(int *fid, char *filename, char *mode,
+    1792             :                                                   int fn_len, int mode_len)
+    1793             : {
+    1794             :         char cfilename[512];
+    1795             :         char cmode[5];
+    1796             :         int i;
+    1797             :   
+    1798             :         /* zero array at first invocation */
+    1799           0 :         if(f77init) {
+    1800           0 :                 for(i=0;i<MAX_FORTRAN_XDR;i++)
+    1801           0 :                         f77xdr[i]=NULL;
+    1802           0 :                 f77init=0;
+    1803             :         }
+    1804             :         i=0;
+    1805             :   
+    1806             :         /* nf77xdr is always smaller or equal to MAX_FORTRAN_XDR */
+    1807           0 :         while(i<MAX_FORTRAN_XDR && f77xdr[i]!=NULL)
+    1808           0 :                 i++;
+    1809           0 :         if(i==MAX_FORTRAN_XDR) {
+    1810           0 :                 *fid = -1;
+    1811           0 :         } else if (ftocstr(cfilename, sizeof(cfilename), filename, fn_len)) {
+    1812           0 :                 *fid = -1;
+    1813           0 :         } else if (ftocstr(cmode, sizeof(cmode), mode,mode_len)) {
+    1814           0 :                 *fid = -1;
+    1815             :         } else {
+    1816           0 :                 f77xdr[i]=xdrfile_open(cfilename,cmode);
+    1817             :                 /* return the index in the array as a fortran file handle */
+    1818           0 :                 *fid=i; 
+    1819             :         }
+    1820           0 : }
+    1821             : 
+    1822             : void
+    1823           0 : F77_FUNC(xdrclose,XDRCLOSE)(int *fid)
+    1824             : {
+    1825             :     /* first close it */
+    1826           0 :     xdrfile_close(f77xdr[*fid]);
+    1827             :     /* the remove it from file handle list */
+    1828           0 :     f77xdr[*fid]=NULL;
+    1829           0 : }
+    1830             : 
+    1831             : 
+    1832             : void
+    1833           0 : F77_FUNC(xdrrint,XDRRINT)(int *fid, int *data, int *ndata, int *ret)
+    1834             : {
+    1835           0 :         *ret = xdrfile_read_int(data,*ndata,f77xdr[*fid]);
+    1836           0 : }
+    1837             : 
+    1838             : void
+    1839           0 : F77_FUNC(xdrwint,XDRWINT)(int *fid, int *data, int *ndata, int *ret)
+    1840             : {
+    1841           0 :         *ret = xdrfile_write_int(data,*ndata,f77xdr[*fid]);
+    1842           0 : }
+    1843             : 
+    1844             : void
+    1845           0 : F77_FUNC(xdrruint,XDRRUINT)(int *fid, unsigned int *data, int *ndata, int *ret)
+    1846             : {
+    1847           0 :         *ret = xdrfile_read_uint(data,*ndata,f77xdr[*fid]);
+    1848           0 : }
+    1849             : 
+    1850             : void
+    1851           0 : F77_FUNC(xdrwuint,XDRWUINT)(int *fid, unsigned int *data, int *ndata, int *ret)
+    1852             : {
+    1853           0 :         *ret = xdrfile_write_uint(data,*ndata,f77xdr[*fid]);
+    1854           0 : }
+    1855             : 
+    1856             : void
+    1857           0 : F77_FUNC(xdrrchar,XDRRCHAR)(int *fid, char *ip, int *ndata, int *ret)
+    1858             : {
+    1859           0 :         *ret = xdrfile_read_char(ip,*ndata,f77xdr[*fid]);
+    1860           0 : }
+    1861             : 
+    1862             : void
+    1863           0 : F77_FUNC(xdrwchar,XDRWCHAR)(int *fid, char *ip, int *ndata, int *ret)
+    1864             : {
+    1865           0 :         *ret = xdrfile_write_char(ip,*ndata,f77xdr[*fid]);
+    1866           0 : }
+    1867             : 
+    1868             : void
+    1869           0 : F77_FUNC(xdrruchar,XDRRUCHAR)(int *fid, unsigned char *ip, int *ndata, int *ret)
+    1870             : {
+    1871           0 :         *ret = xdrfile_read_uchar(ip,*ndata,f77xdr[*fid]);
+    1872           0 : }
+    1873             : 
+    1874             : void
+    1875           0 : F77_FUNC(xdrwuchar,XDRWUCHAR)(int *fid, unsigned char *ip, int *ndata, int *ret)
+    1876             : {
+    1877           0 :         *ret = xdrfile_write_uchar(ip,*ndata,f77xdr[*fid]);
+    1878           0 : }
+    1879             : 
+    1880             : void
+    1881           0 : F77_FUNC(xdrrshort,XDRRSHORT)(int *fid, short *ip, int *ndata, int *ret)
+    1882             : {
+    1883           0 :         *ret = xdrfile_read_short(ip,*ndata,f77xdr[*fid]);
+    1884           0 : }
+    1885             : 
+    1886             : void
+    1887           0 : F77_FUNC(xdrwshort,XDRWSHORT)(int *fid, short *ip, int *ndata, int *ret)
+    1888             : {
+    1889           0 :         *ret = xdrfile_write_short(ip,*ndata,f77xdr[*fid]);
+    1890           0 : }
+    1891             : 
+    1892             : void
+    1893           0 : F77_FUNC(xdrrushort,XDRRUSHORT)(int *fid, unsigned short *ip, int *ndata, int *ret)
+    1894             : {
+    1895           0 :         *ret = xdrfile_read_ushort(ip,*ndata,f77xdr[*fid]);
+    1896           0 : }
+    1897             : 
+    1898             : void
+    1899           0 : F77_FUNC(xdrwushort,XDRWUSHORT)(int *fid, unsigned short *ip, int *ndata, int *ret)
+    1900             : {
+    1901           0 :         *ret = xdrfile_write_ushort(ip,*ndata,f77xdr[*fid]);
+    1902           0 : }
+    1903             : 
+    1904             : void
+    1905           0 : F77_FUNC(xdrrsingle,XDRRSINGLE)(int *fid, float *data, int *ndata, int *ret)
+    1906             : {
+    1907           0 :         *ret = xdrfile_read_float(data,*ndata,f77xdr[*fid]);
+    1908           0 : }
+    1909             : 
+    1910             : void
+    1911           0 : F77_FUNC(xdrwsingle,XDRWSINGLE)(int *fid, float *data, int *ndata, int *ret)
+    1912             : {
+    1913           0 :         *ret = xdrfile_write_float(data,*ndata,f77xdr[*fid]);
+    1914           0 : }
+    1915             : 
+    1916             : void
+    1917           0 : F77_FUNC(xdrrdouble,XDRRDOUBLE)(int *fid, double *data, int *ndata, int *ret)
+    1918             : {
+    1919           0 :         *ret = xdrfile_read_double(data,*ndata,f77xdr[*fid]);
+    1920           0 : }
+    1921             : 
+    1922             : void
+    1923           0 : F77_FUNC(xdrwdouble,XDRWDOUBLE)(int *fid, double *data, int *ndata, int *ret)
+    1924             : {
+    1925           0 :         *ret = xdrfile_write_double(data,*ndata,f77xdr[*fid]);
+    1926           0 : }
+    1927             : 
+    1928           0 : static int ftocstr(char *dest, int destlen, char *src, int srclen)
+    1929             : {
+    1930             :     char *p;
+    1931             : 
+    1932           0 :     p = src + srclen;
+    1933           0 :     while ( --p >= src && *p == ' ' );
+    1934           0 :     srclen = p - src + 1;
+    1935             :     destlen--;
+    1936           0 :     dest[0] = 0;
+    1937           0 :     if (srclen > destlen)
+    1938             :                 return 1;
+    1939           0 :     while (srclen--)
+    1940           0 :                 (*dest++ = *src++);
+    1941           0 :     *dest = '\0';
+    1942           0 :     return 0;
+    1943             : }
+    1944             : 
+    1945             : 
+    1946           0 : static int ctofstr(char *dest, int destlen, char *src)
+    1947             : {
+    1948           0 :     while (destlen && *src) {
+    1949           0 :         *dest++ = *src++;
+    1950           0 :         destlen--;
+    1951             :     }
+    1952           0 :     while (destlen--)
+    1953           0 :         *dest++ = ' ';
+    1954           0 :     return 0;
+    1955             : }
+    1956             : 
+    1957             : 
+    1958             : void
+    1959           0 : F77_FUNC(xdrrstring,XDRRSTRING)(int *fid, char *str, int *ret, int len)
+    1960             : {
+    1961             :         char *cstr;
+    1962             :   
+    1963           0 :         if((cstr=(char*)malloc((len+1)*sizeof(char)))==NULL) {
+    1964           0 :                 *ret = 0;
+    1965           0 :                 return;
+    1966             :         }
+    1967           0 :         if (ftocstr(cstr, len+1, str, len)) {
+    1968           0 :                 *ret = 0;
+    1969           0 :                 free(cstr);
+    1970           0 :                 return;
+    1971             :         }
+    1972             :   
+    1973           0 :         *ret = xdrfile_read_string(cstr, len+1,f77xdr[*fid]);
+    1974           0 :         ctofstr( str, len , cstr);
+    1975           0 :         free(cstr);
+    1976             : }
+    1977             : 
+    1978             : void
+    1979           0 : F77_FUNC(xdrwstring,XDRWSTRING)(int *fid, char *str, int *ret, int len)
+    1980             : {
+    1981             :         char *cstr;
+    1982             :   
+    1983           0 :         if((cstr=(char*)malloc((len+1)*sizeof(char)))==NULL) {
+    1984           0 :                 *ret = 0;
+    1985           0 :                 return;
+    1986             :         }
+    1987           0 :         if (ftocstr(cstr, len+1, str, len)) {
+    1988           0 :                 *ret = 0;
+    1989           0 :                 free(cstr);
+    1990           0 :                 return;
+    1991             :         }
+    1992             :   
+    1993           0 :         *ret = xdrfile_write_string(cstr, f77xdr[*fid]);
+    1994           0 :         ctofstr( str, len , cstr);
+    1995           0 :         free(cstr);
+    1996             : }
+    1997             : 
+    1998             : void
+    1999           0 : F77_FUNC(xdrropaque,XDRROPAQUE)(int *fid, char *data, int *ndata, int *ret)
+    2000             : {
+    2001           0 :         *ret = xdrfile_read_opaque(data,*ndata,f77xdr[*fid]);
+    2002           0 : }
+    2003             : 
+    2004             : void
+    2005           0 : F77_FUNC(xdrwopaque,XDRWOPAQUE)(int *fid, char *data, int *ndata, int *ret)
+    2006             : {
+    2007           0 :         *ret = xdrfile_write_opaque(data,*ndata,f77xdr[*fid]);
+    2008           0 : }
+    2009             : 
+    2010             : 
+    2011             : /* Write single-precision compressed 3d coordinates */
+    2012             : void
+    2013           0 : F77_FUNC(xdrccs,XDRCCS)(int *fid, float *data, int *ncoord, 
+    2014             :                                                 float *precision, int *ret)
+    2015             : {
+    2016           0 :     *ret = xdrfile_compress_coord_float(data,*ncoord,*precision,f77xdr[*fid]);
+    2017           0 : }
+    2018             : 
+    2019             : 
+    2020             : /* Read single-precision compressed 3d coordinates */
+    2021             : void
+    2022           0 : F77_FUNC(xdrdcs,XDRDCS)(int *fid, float *data, int *ncoord, 
+    2023             :                                                 float *precision, int *ret)
+    2024             : {
+    2025           0 :         *ret = xdrfile_decompress_coord_float(data,ncoord,precision,f77xdr[*fid]);
+    2026           0 : }
+    2027             : 
+    2028             : 
+    2029             : /* Write compressed 3d coordinates from double precision data */
+    2030             : void
+    2031           0 : F77_FUNC(xdrccd,XDRCCD)(int *fid, double *data, int *ncoord, 
+    2032             :                                                 double *precision, int *ret)
+    2033             : {
+    2034           0 :         *ret = xdrfile_compress_coord_double(data,*ncoord,*precision,f77xdr[*fid]);
+    2035           0 : }
+    2036             : 
+    2037             : /* Read compressed 3d coordinates into double precision data */
+    2038             : void
+    2039           0 : F77_FUNC(xddcd,XDRDCD)(int *fid, double *data, int *ncoord, 
+    2040             :                                            double *precision, int *ret)
+    2041             : {
+    2042           0 :     *ret = xdrfile_decompress_coord_double(data,ncoord,precision,f77xdr[*fid]);
+    2043           0 : }
+    2044             : 
+    2045             : 
+    2046             : 
+    2047             : 
+    2048             : 
+    2049             : 
+    2050             : 
+    2051             : #endif /* DOXYGEN */
+    2052             : 
+    2053             : /*************************************************************
+    2054             :  * End of higher-level routines - dont change things below!  *
+    2055             :  *************************************************************/
+    2056             : 
+    2057             : 
+    2058             : 
+    2059             : 
+    2060             : 
+    2061             : 
+    2062             : 
+    2063             : 
+    2064             : 
+    2065             : 
+    2066             : 
+    2067             : 
+    2068             : 
+    2069             : 
+    2070             : 
+    2071             : 
+    2072             : 
+    2073             : 
+    2074             : 
+    2075             : 
+    2076             : /*************************************************************
+    2077             :  * The rest of this file contains our own implementation     *
+    2078             :  * of the XDR calls in case you are compiling without them.  *
+    2079             :  * You do NOT want to change things here since it would make *
+    2080             :  * things incompatible with the standard RPC/XDR routines.   *
+    2081             :  *************************************************************/
+    2082             : #ifndef HAVE_RPC_XDR_H
+    2083             : 
+    2084             : /*
+    2085             :  * What follows is a modified version of the Sun XDR code. For reference
+    2086             :  * we include their copyright and license:
+    2087             :  * 
+    2088             :  * Sun RPC is a product of Sun Microsystems, Inc. and is provided for
+    2089             :  * unrestricted use provided that this legend is included on all tape
+    2090             :  * media and as a part of the software program in whole or part.  Users
+    2091             :  * may copy or modify Sun RPC without charge, but are not authorized
+    2092             :  * to license or distribute it to anyone else except as part of a product or
+    2093             :  * program developed by the user.
+    2094             :  *
+    2095             :  * SUN RPC IS PROVIDED AS IS WITH NO WARRANTIES OF ANY KIND INCLUDING THE
+    2096             :  * WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+    2097             :  * PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE OR TRADE PRACTICE.
+    2098             :  *
+    2099             :  * Sun RPC is provided with no support and without any obligation on the
+    2100             :  * part of Sun Microsystems, Inc. to assist in its use, correction,
+    2101             :  * modification or enhancement.
+    2102             :  *
+    2103             :  * SUN MICROSYSTEMS, INC. SHALL HAVE NO LIABILITY WITH RESPECT TO THE
+    2104             :  * INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY SUN RPC
+    2105             :  * OR ANY PART THEREOF.
+    2106             :  *
+    2107             :  * In no event will Sun Microsystems, Inc. be liable for any lost revenue
+    2108             :  * or profits or other special, indirect and consequential damages, even if
+    2109             :  * Sun has been advised of the possibility of such damages.
+    2110             :  *
+    2111             :  * Sun Microsystems, Inc.
+    2112             :  * 2550 Garcia Avenue
+    2113             :  * Mountain View, California  94043
+    2114             :  */
+    2115             : 
+    2116             : /* INT_MAX is defined in limits.h according to ANSI C */
+    2117             : #if (INT_MAX > 2147483647)
+    2118             : #    error Error: Cannot use builtin XDR support when size of int
+    2119             : #    error is larger than 4 bytes. Use your system XDR libraries 
+    2120             : #    error instead, or modify the source code in xdrfile.c
+    2121             : #endif /* Check for 4 byte int type */
+    2122             : 
+    2123             : 
+    2124             : 
+    2125             : 
+    2126             : 
+    2127             : typedef int (*xdrproc_t) (XDR *, void *,...);
+    2128             : 
+    2129             : #define xdr_getlong(xdrs, longp)                        \
+    2130             :         (*(xdrs)->x_ops->x_getlong)(xdrs, longp)
+    2131             : #define xdr_putlong(xdrs, longp)                        \
+    2132             :         (*(xdrs)->x_ops->x_putlong)(xdrs, longp)
+    2133             : #define xdr_getbytes(xdrs, addr, len)                   \
+    2134             :         (*(xdrs)->x_ops->x_getbytes)(xdrs, addr, len)
+    2135             : #define xdr_putbytes(xdrs, addr, len)                   \
+    2136             :         (*(xdrs)->x_ops->x_putbytes)(xdrs, addr, len)
+    2137             : 
+    2138             : #define BYTES_PER_XDR_UNIT 4 
+    2139             : static char xdr_zero[BYTES_PER_XDR_UNIT] = {0, 0, 0, 0};
+    2140             : 
+    2141             : static int32_t
+    2142       14026 : xdr_swapbytes(int32_t x)
+    2143             : {
+    2144             :         int32_t y,i;
+    2145             :         char *px=(char *)&x;
+    2146             :         char *py=(char *)&y;
+    2147             :   
+    2148       70130 :         for(i=0;i<4;i++)
+    2149       56104 :                 py[i]=px[3-i];
+    2150             :   
+    2151       14026 :         return y;
+    2152             : }
+    2153             : 
+    2154             : static int32_t
+    2155        9972 : xdr_htonl(int32_t x)
+    2156             : {
+    2157             :         int s=0x1234;
+    2158             :         if( *((char *)&s)==(char)0x34) {
+    2159             :                 /* smallendian,swap bytes */
+    2160        9972 :                 return xdr_swapbytes(x);
+    2161             :         } else {
+    2162             :                 /* bigendian, do nothing */
+    2163             :                 return x;
+    2164             :         }
+    2165             : }
+    2166             : 
+    2167             : static int32_t
+    2168        4054 : xdr_ntohl(int x)
+    2169             : {
+    2170             :         int s=0x1234;
+    2171             :         if( *((char *)&s)==(char)0x34) {
+    2172             :                 /* smallendian, swap bytes */
+    2173        4054 :                 return xdr_swapbytes(x);
+    2174             :         } else {
+    2175             :                 /* bigendian, do nothing */
+    2176             :                 return x;
+    2177             :         }
+    2178             : }
+    2179             : 
+    2180             : static int
+    2181        2420 : xdr_int (XDR *xdrs, int *ip)
+    2182             : {
+    2183             :         int32_t i32;
+    2184             : 
+    2185        2420 :         switch (xdrs->x_op)
+    2186             :                 {
+    2187        1488 :                 case XDR_ENCODE:
+    2188        1488 :                         i32 = (int32_t) *ip;
+    2189        1488 :                         return xdr_putlong (xdrs, &i32);
+    2190             : 
+    2191         932 :                 case XDR_DECODE:
+    2192         932 :                         if (!xdr_getlong (xdrs, &i32))
+    2193             :                                 {
+    2194             :                                         return 0;
+    2195             :                                 }
+    2196         927 :                         *ip = (int) i32;
+    2197             :                 case XDR_FREE:
+    2198             :                         return 1;
+    2199             :                 }
+    2200             :         return 0;
+    2201             : }
+    2202             : 
+    2203             : static int
+    2204          87 : xdr_u_int (XDR *xdrs, unsigned int *up)
+    2205             : {
+    2206             :         uint32_t ui32;
+    2207             : 
+    2208          87 :         switch (xdrs->x_op)
+    2209             :                 {
+    2210          48 :                 case XDR_ENCODE:
+    2211          48 :                         ui32 = (uint32_t) * up;
+    2212          48 :                         return xdr_putlong (xdrs, (int32_t *)&ui32);
+    2213             : 
+    2214          39 :                 case XDR_DECODE:
+    2215          39 :                         if (!xdr_getlong (xdrs, (int32_t *)&ui32))
+    2216             :                                 {
+    2217             :                                         return 0;
+    2218             :                                 }
+    2219          39 :                         *up = (uint32_t) ui32;
+    2220             :                 case XDR_FREE:
+    2221             :                         return 1;
+    2222             :                 }
+    2223             :         return 0;
+    2224             : }
+    2225             : 
+    2226             : static int
+    2227           0 : xdr_short (XDR *xdrs, short *sp)
+    2228             : {
+    2229             :         int32_t i32;
+    2230             : 
+    2231           0 :         switch (xdrs->x_op)
+    2232             :                 {
+    2233           0 :                 case XDR_ENCODE:
+    2234           0 :                         i32 = (int32_t) *sp;
+    2235           0 :                         return xdr_putlong (xdrs, &i32);
+    2236             : 
+    2237           0 :                 case XDR_DECODE:
+    2238           0 :                         if (!xdr_getlong (xdrs, &i32))
+    2239             :                                 {
+    2240             :                                         return 0;
+    2241             :                                 }
+    2242           0 :                         *sp = (short) i32;
+    2243           0 :                         return 1;
+    2244             : 
+    2245             :                 case XDR_FREE:
+    2246             :                         return 1;
+    2247             :                 }
+    2248           0 :         return 0;
+    2249             : }
+    2250             : 
+    2251             : static int
+    2252           0 : xdr_u_short (XDR *xdrs, unsigned short *sp)
+    2253             : {
+    2254             :         uint32_t ui32;
+    2255             : 
+    2256           0 :         switch (xdrs->x_op)
+    2257             :                 {
+    2258           0 :                 case XDR_ENCODE:
+    2259           0 :                         ui32 = (uint32_t) *sp;
+    2260           0 :                         return xdr_putlong (xdrs, (int32_t *)&ui32);
+    2261             : 
+    2262           0 :                 case XDR_DECODE:
+    2263           0 :                         if (!xdr_getlong (xdrs, (int32_t *)&ui32))
+    2264             :                                 {
+    2265             :                                         return 0;
+    2266             :                                 }
+    2267           0 :                         *sp = (unsigned short) ui32;
+    2268           0 :                         return 1;
+    2269             : 
+    2270             :                 case XDR_FREE:
+    2271             :                         return 1;
+    2272             :                 }
+    2273           0 :         return 0;
+    2274             : }
+    2275             : 
+    2276             : static int
+    2277           0 : xdr_char (XDR *xdrs, char *cp)
+    2278             : {
+    2279             :         int i;
+    2280             : 
+    2281           0 :         i = (*cp);
+    2282           0 :         if (!xdr_int (xdrs, &i))
+    2283             :                 {
+    2284             :                         return 0;
+    2285             :                 }
+    2286           0 :         *cp = i;
+    2287           0 :         return 1;
+    2288             : }
+    2289             : 
+    2290             : static int
+    2291           0 : xdr_u_char (XDR *xdrs, unsigned char *cp)
+    2292             : {
+    2293             :         unsigned int u;
+    2294             : 
+    2295           0 :         u = (*cp);
+    2296           0 :         if (!xdr_u_int (xdrs, &u))
+    2297             :                 {
+    2298             :                         return 0;
+    2299             :                 }
+    2300           0 :         *cp = u;
+    2301           0 :         return 1;
+    2302             : }
+    2303             : 
+    2304             : /*
+    2305             :  * XDR opaque data
+    2306             :  * Allows the specification of a fixed size sequence of opaque bytes.
+    2307             :  * cp points to the opaque object and cnt gives the byte length.
+    2308             :  */
+    2309             : static int
+    2310         175 : xdr_opaque (XDR *xdrs, char *cp, unsigned int cnt)
+    2311             : {
+    2312             :         unsigned int rndup;
+    2313             :         static char crud[BYTES_PER_XDR_UNIT];
+    2314             : 
+    2315             :         /*
+    2316             :          * if no data we are done
+    2317             :          */
+    2318         175 :         if (cnt == 0)
+    2319             :                 return 1;
+    2320             : 
+    2321             :         /*
+    2322             :          * round byte count to full xdr units
+    2323             :          */
+    2324         175 :         rndup = cnt % BYTES_PER_XDR_UNIT;
+    2325         175 :         if (rndup > 0)
+    2326          61 :                 rndup = BYTES_PER_XDR_UNIT - rndup;
+    2327             : 
+    2328         175 :         switch (xdrs->x_op)
+    2329             :                 {
+    2330          67 :                 case XDR_DECODE:
+    2331          67 :                         if (!xdr_getbytes (xdrs, cp, cnt))
+    2332             :                                 {
+    2333             :                                         return 0;
+    2334             :                                 }
+    2335          67 :                         if (rndup == 0)
+    2336             :                                 return 1;
+    2337          22 :                         return xdr_getbytes (xdrs, (char *)crud, rndup);
+    2338             : 
+    2339         108 :                 case XDR_ENCODE:
+    2340         108 :                         if (!xdr_putbytes (xdrs, cp, cnt))
+    2341             :                                 {
+    2342             :                                         return 0;
+    2343             :                                 }
+    2344         108 :                         if (rndup == 0)
+    2345             :                                 return 1;
+    2346          39 :                         return xdr_putbytes (xdrs, xdr_zero, rndup);
+    2347             : 
+    2348             :                 case XDR_FREE:
+    2349             :                         return 1;
+    2350             :                 }
+    2351             : #undef BYTES_PER_XDR_UNIT
+    2352           0 :         return 0;
+    2353             : }
+    2354             : 
+    2355             : 
+    2356             : /*
+    2357             :  * XDR null terminated ASCII strings
+    2358             :  */
+    2359             : static int
+    2360          87 : xdr_string (XDR *xdrs, char **cpp, unsigned int maxsize)
+    2361             : {
+    2362          87 :         char *sp = *cpp;        /* sp is the actual string pointer */
+    2363             :         unsigned int size;
+    2364             :         unsigned int nodesize;
+    2365             : 
+    2366             :         /*
+    2367             :          * first deal with the length since xdr strings are counted-strings
+    2368             :          */
+    2369          87 :         switch (xdrs->x_op)
+    2370             :                 {
+    2371           0 :                 case XDR_FREE:
+    2372           0 :                         if (sp == NULL)
+    2373             :                                 {
+    2374             :                                         return 1;               /* already free */
+    2375             :                                 }
+    2376             :                         /* fall through... */
+    2377             :                 case XDR_ENCODE:
+    2378          48 :                         if (sp == NULL)
+    2379             :                                 return 0;
+    2380          48 :                         size = strlen (sp);
+    2381          48 :                         break;
+    2382             :                 case XDR_DECODE:
+    2383             :                         break;
+    2384             :                 }
+    2385          87 :         if (!xdr_u_int (xdrs, &size))
+    2386             :                 {
+    2387             :                         return 0;
+    2388             :                 }
+    2389          87 :         if (size > maxsize)
+    2390             :                 {
+    2391             :                         return 0;
+    2392             :                 }
+    2393          87 :         nodesize = size + 1;
+    2394             : 
+    2395             :         /*
+    2396             :          * now deal with the actual bytes
+    2397             :          */
+    2398          87 :         switch (xdrs->x_op)
+    2399             :                 {
+    2400          39 :                 case XDR_DECODE:
+    2401          39 :                         if (nodesize == 0)
+    2402             :                                 {
+    2403             :                                         return 1;
+    2404             :                                 }
+    2405          39 :                         if (sp == NULL)
+    2406           0 :                                 *cpp = sp = (char *) malloc (nodesize);
+    2407          39 :                         if (sp == NULL)
+    2408             :                                 {
+    2409           0 :                                         (void) fputs ("xdr_string: out of memory\n", stderr);
+    2410           0 :                                         return 0;
+    2411             :                                 }
+    2412          39 :                         sp[size] = 0;
+    2413             :                         /* fall into ... */
+    2414             : 
+    2415          87 :                 case XDR_ENCODE:
+    2416          87 :                         return xdr_opaque (xdrs, sp, size);
+    2417             : 
+    2418           0 :                 case XDR_FREE:
+    2419           0 :                         free (sp);
+    2420           0 :                         *cpp = NULL;
+    2421           0 :                         return 1;
+    2422             :                 }
+    2423             :         return 0;
+    2424             : }
+    2425             : 
+    2426             : 
+    2427             : 
+    2428             : /* Floating-point stuff */
+    2429             : 
+    2430             : static int
+    2431       11524 : xdr_float(XDR *xdrs, float *fp)
+    2432             : {
+    2433       11524 :         switch (xdrs->x_op) {
+    2434             : 
+    2435             :         case XDR_ENCODE:
+    2436             :                 if (sizeof(float) == sizeof(int32_t))
+    2437        8436 :                         return (xdr_putlong(xdrs, (int32_t *) (void*) fp));
+    2438             :                 else if (sizeof(float) == sizeof(int)) {
+    2439             :                         int32_t tmp = *(int *) (void*) fp;
+    2440             :                         return (xdr_putlong(xdrs, &tmp));
+    2441             :                 }
+    2442             :                 break;
+    2443             : 
+    2444             :         case XDR_DECODE:
+    2445             :                 if (sizeof(float) == sizeof(int32_t))
+    2446        3088 :                         return (xdr_getlong(xdrs, (int32_t *) (void*) fp));
+    2447             :                 else if (sizeof(float) == sizeof(int)) {
+    2448             :                         int32_t tmp;
+    2449             :                         if (xdr_getlong(xdrs, &tmp)) {
+    2450             :                                 *(int *) (void*)fp = tmp;
+    2451             :                                 return (1);
+    2452             :                         }
+    2453             :                 }
+    2454             :                 break;
+    2455             : 
+    2456             :         case XDR_FREE:
+    2457             :                 return (1);
+    2458             :         }
+    2459           0 :         return (0);
+    2460             : }
+    2461             : 
+    2462             : 
+    2463             : static int
+    2464           0 : xdr_double(XDR *xdrs, double *dp)
+    2465             : {
+    2466             :     /* Gromacs detects floating-point stuff at compile time, which is faster */
+    2467             : #ifdef GROMACS
+    2468             : #  ifndef FLOAT_FORMAT_IEEE754 
+    2469             : #    error non-IEEE floating point system, or you defined GROMACS yourself...
+    2470             : #  endif
+    2471             :     int LSW;
+    2472             : #  ifdef IEEE754_BIG_ENDIAN_WORD_ORDER 
+    2473             :     int LSW=1;
+    2474             : #  else
+    2475             :     int LSW=0;
+    2476             : #  endif /* Big endian word order */
+    2477             : #else 
+    2478             :     /* Outside Gromacs we rely on dynamic detection of FP order. */
+    2479             :     int LSW; /* Least significant fp word */
+    2480             : 
+    2481             :     double x=0.987654321; /* Just a number */
+    2482             :     unsigned char ix = *((char *)&x);
+    2483             :     
+    2484             :     /* Possible representations in IEEE double precision: 
+    2485             :      * (S=small endian, B=big endian)
+    2486             :      *  
+    2487             :      * Byte order, Word order, Hex
+    2488             :      *     S           S       b8 56 0e 3c dd 9a ef 3f    
+    2489             :      *     B           S       3c 0e 56 b8 3f ef 9a dd
+    2490             :      *     S           B       dd 9a ef 3f b8 56 0e 3c
+    2491             :      *     B           B       3f ef 9a dd 3c 0e 56 b8
+    2492             :      */ 
+    2493             :     if(ix==0xdd || ix==0x3f)
+    2494             :                 LSW=1;  /* Big endian word order */
+    2495             :     else if(ix==0xb8 || ix==0x3c)
+    2496             :                 LSW=0;  /* Small endian word order */
+    2497             :     else { /* Catch strange errors */
+    2498             :                 fprintf(stderr,"Cannot detect floating-point word order.\n"
+    2499             :                                 "Do you have a non-IEEE system?\n"
+    2500             :                                 "Use system XDR libraries or fix xdr_double().\n");
+    2501             :                 abort();
+    2502             :     }
+    2503             : #endif /* end of dynamic detection of fp word order */
+    2504             : 
+    2505           0 :         switch (xdrs->x_op) {
+    2506             :     
+    2507             :         case XDR_ENCODE:
+    2508             :                 if (2*sizeof(int32_t) == sizeof(double)) {
+    2509             :                         int32_t *lp = (int32_t *) (void*) dp;
+    2510           0 :                         return (xdr_putlong(xdrs, lp+!LSW) &&
+    2511           0 :                                         xdr_putlong(xdrs, lp+LSW));
+    2512             :                 } else if (2*sizeof(int) == sizeof(double)) {
+    2513             :                         int *ip = (int *) (void*) dp;
+    2514             :                         int32_t tmp[2];
+    2515             :                         tmp[0] = ip[!LSW];
+    2516             :                         tmp[1] = ip[LSW];
+    2517             :                         return (xdr_putlong(xdrs, tmp) &&
+    2518             :                                         xdr_putlong(xdrs, tmp+1));
+    2519             :                 }
+    2520             :                 break;
+    2521             :     
+    2522             :         case XDR_DECODE:
+    2523             :                 if (2*sizeof(int32_t) == sizeof(double)) {
+    2524             :                         int32_t *lp = (int32_t *) (void*) dp;
+    2525           0 :                         return (xdr_getlong(xdrs, lp+!LSW) &&
+    2526           0 :                                         xdr_getlong(xdrs, lp+LSW));
+    2527             :                 } else if (2*sizeof(int) == sizeof(double)) {
+    2528             :                         int *ip = (int *) (void*) dp;
+    2529             :                         int32_t tmp[2];
+    2530             :                         if (xdr_getlong(xdrs, tmp+!LSW) &&
+    2531             :                                 xdr_getlong(xdrs, tmp+LSW)) {
+    2532             :                                 ip[0] = tmp[0];
+    2533             :                                 ip[1] = tmp[1];
+    2534             :                                 return (1);
+    2535             :                         }
+    2536             :                 }
+    2537             :                 break;
+    2538             :     
+    2539             :         case XDR_FREE:
+    2540             :                 return (1);
+    2541             :         }
+    2542           0 :         return (0);
+    2543             : }
+    2544             : 
+    2545             : 
+    2546             : static int xdrstdio_getlong (XDR *, int32_t *);
+    2547             : static int xdrstdio_putlong (XDR *, int32_t *);
+    2548             : static int xdrstdio_getbytes (XDR *, char *, unsigned int);
+    2549             : static int xdrstdio_putbytes (XDR *, char *, unsigned int);
+    2550             : static unsigned int xdrstdio_getpos (XDR *);
+    2551             : static int xdrstdio_setpos (XDR *, unsigned int);
+    2552             : static void xdrstdio_destroy (XDR *);
+    2553             : 
+    2554             : /*
+    2555             :  * Ops vector for stdio type XDR
+    2556             :  */
+    2557             : static const XDR::xdr_ops xdrstdio_ops =
+    2558             :         {
+    2559             :                 xdrstdio_getlong,               /* deserialize a long int */
+    2560             :                 xdrstdio_putlong,               /* serialize a long int */
+    2561             :                 xdrstdio_getbytes,              /* deserialize counted bytes */
+    2562             :                 xdrstdio_putbytes,      /* serialize counted bytes */
+    2563             :                 xdrstdio_getpos,                /* get offset in the stream */
+    2564             :                 xdrstdio_setpos,                /* set offset in the stream */
+    2565             :                 xdrstdio_destroy,               /* destroy stream */
+    2566             :         };
+    2567             : 
+    2568             : /*
+    2569             :  * Initialize a stdio xdr stream.
+    2570             :  * Sets the xdr stream handle xdrs for use on the stream file.
+    2571             :  * Operation flag is set to op.
+    2572             :  */
+    2573             : static void
+    2574          20 : xdrstdio_create (XDR *xdrs, FILE *file, enum xdr_op op)
+    2575             : {
+    2576          20 :         xdrs->x_op = op;
+    2577             : 
+    2578          20 :         xdrs->x_ops = (XDR::xdr_ops *) &xdrstdio_ops;
+    2579          20 :         xdrs->x_private = (char *) file;
+    2580          20 : }
+    2581             : 
+    2582             : /*
+    2583             :  * Destroy a stdio xdr stream.
+    2584             :  * Cleans up the xdr stream handle xdrs previously set up by xdrstdio_create.
+    2585             :  */
+    2586             : static void
+    2587          20 : xdrstdio_destroy (XDR *xdrs)
+    2588             : {
+    2589          20 :         (void) fflush ((FILE *) xdrs->x_private);
+    2590             :         /* xx should we close the file ?? */
+    2591          20 : }
+    2592             : 
+    2593             : static int
+    2594        4059 : xdrstdio_getlong (XDR *xdrs, int32_t *lp)
+    2595             : {
+    2596             :         int32_t mycopy;
+    2597             : 
+    2598        4059 :         if (fread ((char *) & mycopy, 4, 1, (FILE *) xdrs->x_private) != 1)
+    2599             :                 return 0;
+    2600        4054 :         *lp = (int32_t) xdr_ntohl (mycopy);
+    2601        4054 :         return 1;
+    2602             : }
+    2603             : 
+    2604             : static int
+    2605        9972 : xdrstdio_putlong (XDR *xdrs, int32_t *lp)
+    2606             : {
+    2607        9972 :         int32_t mycopy = xdr_htonl (*lp);
+    2608             :         lp = &mycopy;
+    2609        9972 :         if (fwrite ((char *) lp, 4, 1, (FILE *) xdrs->x_private) != 1)
+    2610           0 :                 return 0;
+    2611             :         return 1;
+    2612             : }
+    2613             : 
+    2614             : static int
+    2615          89 : xdrstdio_getbytes (XDR *xdrs, char *addr, unsigned int len)
+    2616             : {
+    2617         178 :         if ((len != 0) && (fread (addr, (int) len, 1,
+    2618          89 :                                                           (FILE *) xdrs->x_private) != 1))
+    2619           0 :                 return 0;
+    2620             :         return 1;
+    2621             : }
+    2622             : 
+    2623             : static int
+    2624         147 : xdrstdio_putbytes (XDR *xdrs, char *addr, unsigned int len)
+    2625             : {
+    2626         294 :         if ((len != 0) && (fwrite (addr, (int) len, 1,
+    2627         147 :                                                            (FILE *) xdrs->x_private) != 1)) 
+    2628           0 :                 return 0;
+    2629             :         return 1;
+    2630             : }
+    2631             : 
+    2632             : /* 32 bit fileseek operations */
+    2633             : static unsigned int
+    2634           0 : xdrstdio_getpos (XDR *xdrs)
+    2635             : {
+    2636           0 :         return (unsigned int) ftell ((FILE *) xdrs->x_private);
+    2637             : }
+    2638             : 
+    2639             : static int
+    2640           0 : xdrstdio_setpos (XDR *xdrs, unsigned int pos)
+    2641             : {
+    2642           0 :         return fseek ((FILE *) xdrs->x_private, pos, 0) < 0 ? 0 : 1;
+    2643             : }
+    2644             : 
+    2645             : #endif /* HAVE_RPC_XDR_H not defined */
+    2646             : 
+    2647             : }
+    2648             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile_trr.cpp.func-sort-c.html b/coverage-libs/xdrfile/xdrfile_trr.cpp.func-sort-c.html new file mode 100644 index 000000000000..f19a578728d9 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_trr.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_trr.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_trr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10419054.7 %
Date:2024-02-22 21:58:47Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile15read_trr_natomsEPcPi3
_ZN4PLMD7xdrfile8read_trrEPNS0_7XDRFILEEiPiPfS4_PA3_fS6_S6_S6_39
_ZN4PLMD7xdrfile9write_trrEPNS0_7XDRFILEEiiffPA3_fS4_S4_S4_48
_ZN4PLMD7xdrfileL7do_htrnEPNS0_7XDRFILEEiPNS0_11t_trnheaderEPA3_fS6_S6_S6_84
_ZN4PLMD7xdrfileL10nFloatSizeEPNS0_11t_trnheaderEPi87
_ZN4PLMD7xdrfileL6do_trnEPNS0_7XDRFILEEiPiPfS4_PA3_fS3_S6_S6_S6_87
_ZN4PLMD7xdrfileL12do_trnheaderEPNS0_7XDRFILEEiPNS0_11t_trnheaderE90
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile_trr.cpp.func.html b/coverage-libs/xdrfile/xdrfile_trr.cpp.func.html new file mode 100644 index 000000000000..fbdc4ab22c52 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_trr.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_trr.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_trr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10419054.7 %
Date:2024-02-22 21:58:47Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile15read_trr_natomsEPcPi3
_ZN4PLMD7xdrfile8read_trrEPNS0_7XDRFILEEiPiPfS4_PA3_fS6_S6_S6_39
_ZN4PLMD7xdrfile9write_trrEPNS0_7XDRFILEEiiffPA3_fS4_S4_S4_48
_ZN4PLMD7xdrfileL10nFloatSizeEPNS0_11t_trnheaderEPi87
_ZN4PLMD7xdrfileL12do_trnheaderEPNS0_7XDRFILEEiPNS0_11t_trnheaderE90
_ZN4PLMD7xdrfileL6do_trnEPNS0_7XDRFILEEiPiPfS4_PA3_fS3_S6_S6_S6_87
_ZN4PLMD7xdrfileL7do_htrnEPNS0_7XDRFILEEiPNS0_11t_trnheaderEPA3_fS6_S6_S6_84
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile_trr.cpp.gcov.html b/coverage-libs/xdrfile/xdrfile_trr.cpp.gcov.html new file mode 100644 index 000000000000..0be334300799 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_trr.cpp.gcov.html @@ -0,0 +1,606 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_trr.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_trr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:10419054.7 %
Date:2024-02-22 21:58:47Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2009-2014, Erik Lindahl & David van der Spoel
+       3             : All rights reserved.
+       4             : 
+       5             : Redistribution and use in source and binary forms, with or without
+       6             : modification, are permitted provided that the following conditions are met:
+       7             : 
+       8             : 1. Redistributions of source code must retain the above copyright notice, this
+       9             : list of conditions and the following disclaimer.
+      10             : 
+      11             : 2. Redistributions in binary form must reproduce the above copyright notice,
+      12             : this list of conditions and the following disclaimer in the documentation
+      13             : and/or other materials provided with the distribution.
+      14             : 
+      15             : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+      16             : AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+      17             : IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+      18             : DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+      19             : FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+      20             : DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+      21             : SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+      22             : CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+      23             : OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+      24             : OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+      25             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      26             : /* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- 
+      27             :  *
+      28             :  * $Id$
+      29             :  *
+      30             :  /* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*-
+      31             :  *
+      32             :  * $Id$
+      33             :  *
+      34             :  * Copyright (c) 2009-2014, Erik Lindahl & David van der Spoel
+      35             :  * All rights reserved.
+      36             :  *
+      37             :  * Redistribution and use in source and binary forms, with or without
+      38             :  * modification, are permitted provided that the following conditions are met:
+      39             :  *
+      40             :  * 1. Redistributions of source code must retain the above copyright notice, this
+      41             :  * list of conditions and the following disclaimer.
+      42             :  *
+      43             :  * 2. Redistributions in binary form must reproduce the above copyright notice,
+      44             :  * this list of conditions and the following disclaimer in the documentation
+      45             :  * and/or other materials provided with the distribution.
+      46             :  *
+      47             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+      48             :  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+      49             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+      50             :  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+      51             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+      52             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+      53             :  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+      54             :  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+      55             :  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+      56             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+      57             :  */
+      58             : 
+      59             : #include <stdlib.h>
+      60             : #include <string.h>
+      61             : 
+      62             : #ifdef HAVE_CONFIG_H
+      63             : #include "config.h"
+      64             : #endif
+      65             : 
+      66             : #include "xdrfile.h"
+      67             : #include "xdrfile_trr.h"
+      68             : 
+      69             : #define BUFSIZE         128
+      70             : #define GROMACS_MAGIC   1993
+      71             : 
+      72             : namespace PLMD {
+      73             : namespace xdrfile {
+      74             : 
+      75             : typedef struct          /* This struct describes the order and the      */
+      76             : /* sizes of the structs in a trjfile, sizes are given in bytes. */
+      77             : {
+      78             :     mybool  bDouble;        /* Double precision?                            */
+      79             :     int ir_size;        /* Backward compatibility                       */
+      80             :     int e_size;         /* Backward compatibility                       */
+      81             :     int box_size;       /* Non zero if a box is present                 */
+      82             :     int   vir_size;       /* Backward compatibility                     */
+      83             :     int   pres_size;      /* Backward compatibility                     */
+      84             :     int top_size;       /* Backward compatibility                       */
+      85             :     int sym_size;       /* Backward compatibility                       */
+      86             :     int x_size;         /* Non zero if coordinates are present          */
+      87             :     int v_size;         /* Non zero if velocities are present           */
+      88             :     int f_size;         /* Non zero if forces are present               */
+      89             : 
+      90             :     int natoms;         /* The total number of atoms                    */
+      91             :     int step;           /* Current step number                          */
+      92             :     int nre;            /* Backward compatibility                       */
+      93             :     float       tf;             /* Current time                                 */
+      94             :     float       lambdaf;                /* Current value of lambda                      */
+      95             :     double      td;             /* Current time                                 */
+      96             :     double      lambdad;                /* Current value of lambda                      */
+      97             : } t_trnheader;
+      98             : 
+      99          87 : static int nFloatSize(t_trnheader *sh,int *nflsz)
+     100             : {
+     101             :     int nflsize=0;
+     102             :   
+     103          87 :     if (sh->box_size)
+     104          87 :         nflsize = sh->box_size/(DIM*DIM);
+     105           0 :     else if (sh->x_size)
+     106           0 :         nflsize = sh->x_size/(sh->natoms*DIM);
+     107           0 :     else if (sh->v_size)
+     108           0 :         nflsize = sh->v_size/(sh->natoms*DIM);
+     109           0 :     else if (sh->f_size)
+     110           0 :         nflsize = sh->f_size/(sh->natoms*DIM);
+     111             :     else 
+     112             :         return exdrHEADER;
+     113             :   
+     114          87 :     if (((nflsize != sizeof(float)) && (nflsize != sizeof(double))))
+     115             :         return exdrHEADER;
+     116             :       
+     117          87 :     *nflsz = nflsize;
+     118             :   
+     119          87 :     return exdrOK;
+     120             : }
+     121             : 
+     122          90 : static int do_trnheader(XDRFILE *xd,mybool bRead,t_trnheader *sh)
+     123             : {
+     124          90 :         int magic=GROMACS_MAGIC;
+     125             :         int nflsz,slen,result;
+     126             :         const char *version = "GMX_trn_file";
+     127             :         char buf[BUFSIZE];
+     128             :   
+     129          90 :         if (xdrfile_read_int(&magic,1,xd) != 1)
+     130             :                 return exdrINT;
+     131             :   
+     132          87 :         if (bRead) 
+     133             :     {
+     134          39 :         if (xdrfile_read_int(&slen,1,xd) != 1)
+     135             :             return exdrINT;
+     136          39 :         if (slen != strlen(version)+1)
+     137             :             return exdrSTRING;
+     138          39 :         if (xdrfile_read_string(buf,BUFSIZE,xd) <= 0)
+     139             :             return exdrSTRING;
+     140             :     }
+     141             :         else 
+     142             :     {
+     143          48 :         slen = strlen(version)+1;
+     144          48 :         if (xdrfile_read_int(&slen,1,xd) != 1)
+     145             :             return exdrINT;
+     146          48 :         if (xdrfile_write_string(const_cast<char*>(version),xd) != (strlen(version)+1) )
+     147             :             return exdrSTRING;
+     148             :     }
+     149          87 :         if (xdrfile_read_int(&sh->ir_size,1,xd) != 1)
+     150             :                 return exdrINT;
+     151          87 :         if (xdrfile_read_int(&sh->e_size,1,xd) != 1)
+     152             :                 return exdrINT;
+     153          87 :         if (xdrfile_read_int(&sh->box_size,1,xd) != 1)
+     154             :                 return exdrINT;
+     155          87 :         if (xdrfile_read_int(&sh->vir_size,1,xd) != 1)
+     156             :                 return exdrINT;
+     157          87 :         if (xdrfile_read_int(&sh->pres_size,1,xd) != 1)
+     158             :                 return exdrINT;
+     159          87 :         if (xdrfile_read_int(&sh->top_size,1,xd) != 1)
+     160             :                 return exdrINT;
+     161          87 :         if (xdrfile_read_int(&sh->sym_size,1,xd) != 1)
+     162             :                 return exdrINT;
+     163          87 :         if (xdrfile_read_int(&sh->x_size,1,xd) != 1)
+     164             :                 return exdrINT;
+     165          87 :         if (xdrfile_read_int(&sh->v_size,1,xd) != 1)
+     166             :                 return exdrINT;
+     167          87 :         if (xdrfile_read_int(&sh->f_size,1,xd) != 1)
+     168             :                 return exdrINT;
+     169          87 :         if (xdrfile_read_int(&sh->natoms,1,xd) != 1)
+     170             :                 return exdrINT;
+     171             :         
+     172          87 :         if ((result = nFloatSize(sh,&nflsz)) != exdrOK)
+     173             :                 return result;
+     174          87 :         sh->bDouble = (nflsz == sizeof(double));
+     175             :         
+     176          87 :         if (xdrfile_read_int(&sh->step,1,xd) != 1)
+     177             :                 return exdrINT;
+     178          87 :         if (xdrfile_read_int(&sh->nre,1,xd) != 1)
+     179             :                 return exdrINT;
+     180          87 :         if (sh->bDouble) 
+     181             :     {
+     182           0 :         if (xdrfile_read_double(&sh->td,1,xd) != 1)
+     183             :             return exdrDOUBLE;
+     184           0 :         sh->tf = sh->td;
+     185           0 :         if (xdrfile_read_double(&sh->lambdad,1,xd) != 1)
+     186             :             return exdrDOUBLE;
+     187           0 :         sh->lambdaf = sh->lambdad;
+     188             :     }
+     189             :         else 
+     190             :     {
+     191          87 :         if (xdrfile_read_float(&sh->tf,1,xd) != 1)
+     192             :             return exdrFLOAT;
+     193          87 :         sh->td = sh->tf;
+     194          87 :         if (xdrfile_read_float(&sh->lambdaf,1,xd) != 1)
+     195             :             return exdrFLOAT;
+     196          87 :         sh->lambdad = sh->lambdaf;
+     197             :     }
+     198             :   
+     199             :     return exdrOK;
+     200             : }
+     201             : 
+     202          84 : static int do_htrn(XDRFILE *xd,mybool bRead,t_trnheader *sh,
+     203             :                                    matrix box,rvec *x,rvec *v,rvec *f)
+     204             : {
+     205             :         double pvd[DIM*DIM];
+     206             :         double *dx=NULL;
+     207             :         float  pvf[DIM*DIM];
+     208             :         float  *fx=NULL;
+     209             :         int    i,j;
+     210             :         
+     211          84 :         if (sh->bDouble) 
+     212             :         {
+     213           0 :                 if (sh->box_size != 0) 
+     214             :         {
+     215           0 :             if (!bRead) 
+     216             :             {
+     217           0 :                 for(i=0; (i<DIM); i++)
+     218           0 :                     for(j=0; (j<DIM); j++)
+     219           0 :                         if (NULL != box)
+     220             :                         {
+     221           0 :                             pvd[i*DIM+j] = box[i][j];
+     222             :                         }
+     223             :             }
+     224           0 :             if (xdrfile_read_double(pvd,DIM*DIM,xd) == DIM*DIM) 
+     225             :             {
+     226           0 :                 for(i=0; (i<DIM); i++)
+     227           0 :                     for(j=0; (j<DIM); j++)
+     228           0 :                         if (NULL != box)
+     229             :                         {
+     230           0 :                             box[i][j] = pvd[i*DIM+j];
+     231             :                         }
+     232             :             }
+     233             :             else
+     234             :                 return exdrDOUBLE;
+     235             :         }
+     236             :                         
+     237           0 :                 if (sh->vir_size != 0) 
+     238             :         {
+     239           0 :             if (xdrfile_read_double(pvd,DIM*DIM,xd) != DIM*DIM) 
+     240             :                 return exdrDOUBLE;
+     241             :         }
+     242             :                 
+     243           0 :                 if (sh->pres_size!= 0) 
+     244             :         {
+     245           0 :             if (xdrfile_read_double(pvd,DIM*DIM,xd) != DIM*DIM) 
+     246             :                 return exdrDOUBLE;
+     247             :         }
+     248             :                 
+     249           0 :                 if ((sh->x_size != 0) || (sh->v_size != 0) || (sh->f_size != 0)) {
+     250           0 :                         dx = (double *)calloc(sh->natoms*DIM,sizeof(dx[0]));
+     251           0 :                         if (NULL == dx)
+     252             :                                 return exdrNOMEM;
+     253             :                 }
+     254           0 :                 if (sh->x_size   != 0) 
+     255             :         {
+     256           0 :             if (!bRead) 
+     257             :             {
+     258           0 :                 for(i=0; (i<sh->natoms); i++)
+     259           0 :                     for(j=0; (j<DIM); j++)
+     260           0 :                         if (NULL != x)
+     261             :                         {
+     262           0 :                             dx[i*DIM+j] = x[i][j];
+     263             :                         }
+     264             :             }
+     265           0 :             if (xdrfile_read_double(dx,sh->natoms*DIM,xd) == sh->natoms*DIM)
+     266             :             {
+     267           0 :                 if (bRead) 
+     268             :                 {
+     269           0 :                     for(i=0; (i<sh->natoms); i++)
+     270           0 :                         for(j=0; (j<DIM); j++)
+     271           0 :                             if (NULL != x)
+     272             :                             {
+     273           0 :                                 x[i][j] = dx[i*DIM+j];
+     274             :                             }
+     275             :                 }
+     276             :             }
+     277             :             else
+     278             :                 return exdrDOUBLE;
+     279             :         }
+     280           0 :                 if (sh->v_size   != 0) 
+     281             :         {
+     282           0 :             if (!bRead) 
+     283             :             {
+     284           0 :                 for(i=0; (i<sh->natoms); i++)
+     285           0 :                     for(j=0; (j<DIM); j++)
+     286           0 :                         if (NULL != x)
+     287             :                         {
+     288           0 :                             dx[i*DIM+j] = v[i][j];
+     289             :                         }
+     290             :             }
+     291           0 :             if (xdrfile_read_double(dx,sh->natoms*DIM,xd) == sh->natoms*DIM)
+     292             :             {
+     293           0 :                 for(i=0; (i<sh->natoms); i++)
+     294           0 :                     for(j=0; (j<DIM); j++)
+     295           0 :                         if (NULL != v)
+     296             :                         {
+     297           0 :                             v[i][j] = dx[i*DIM+j];
+     298             :                         }
+     299             :             }
+     300             :             else
+     301             :                 return exdrDOUBLE;
+     302             :         }
+     303           0 :                 if (sh->f_size   != 0) 
+     304             :         {
+     305           0 :             if (!bRead) 
+     306             :             {
+     307           0 :                 for(i=0; (i<sh->natoms); i++)
+     308           0 :                     for(j=0; (j<DIM); j++)
+     309           0 :                         if (NULL != x)
+     310             :                         {
+     311           0 :                             dx[i*DIM+j] = f[i][j];
+     312             :                         }
+     313             :             }
+     314           0 :             if (xdrfile_read_double(dx,sh->natoms*DIM,xd) == sh->natoms*DIM)
+     315             :             {
+     316           0 :                 for(i=0; (i<sh->natoms); i++)
+     317             :                 {
+     318           0 :                     for(j=0; (j<DIM); j++)
+     319             :                     {
+     320           0 :                         if (NULL != f)
+     321             :                         {
+     322           0 :                             f[i][j] = dx[i*DIM+j];
+     323             :                         }
+     324             :                     }
+     325             :                 }
+     326             :             }
+     327             :             else
+     328             :                 return exdrDOUBLE;
+     329             :         }
+     330           0 :                 if ((sh->x_size != 0) || (sh->v_size != 0) || (sh->f_size != 0)) {
+     331           0 :                         free(dx);
+     332             :                 }
+     333             :         }
+     334             :         else
+     335             :                 /* Float */
+     336             :         {
+     337          84 :                 if (sh->box_size != 0) 
+     338             :         {
+     339          84 :             if (!bRead) 
+     340             :             {
+     341         192 :                 for(i=0; (i<DIM); i++)
+     342         576 :                     for(j=0; (j<DIM); j++)
+     343         432 :                         if (NULL != box)
+     344             :                         {
+     345         432 :                             pvf[i*DIM+j] = box[i][j];
+     346             :                         }
+     347             :             }
+     348          84 :             if (xdrfile_read_float(pvf,DIM*DIM,xd) == DIM*DIM) 
+     349             :             {
+     350         336 :                 for(i=0; (i<DIM); i++)
+     351             :                 {
+     352        1008 :                     for(j=0; (j<DIM); j++)
+     353             :                     {
+     354         756 :                         if (NULL != box)
+     355             :                         {
+     356         756 :                             box[i][j] = pvf[i*DIM+j];
+     357             :                         }
+     358             :                     }
+     359             :                 }
+     360             :             }
+     361             :             else
+     362             :                 return exdrFLOAT;
+     363             :         }
+     364             :                         
+     365          84 :                 if (sh->vir_size != 0) 
+     366             :         {
+     367           0 :             if (xdrfile_read_float(pvf,DIM*DIM,xd) != DIM*DIM) 
+     368             :                 return exdrFLOAT;
+     369             :         }
+     370             :                 
+     371          84 :                 if (sh->pres_size!= 0) 
+     372             :         {
+     373           0 :             if (xdrfile_read_float(pvf,DIM*DIM,xd) != DIM*DIM) 
+     374             :                 return exdrFLOAT;
+     375             :         }
+     376             :                 
+     377          84 :                 if ((sh->x_size != 0) || (sh->v_size != 0) || (sh->f_size != 0)) {
+     378          84 :                         fx = (float *)calloc(sh->natoms*DIM,sizeof(fx[0]));
+     379          84 :                         if (NULL == fx)
+     380             :                                 return exdrNOMEM;
+     381             :                 }
+     382          84 :                 if (sh->x_size   != 0) 
+     383             :         {
+     384          84 :             if (!bRead) 
+     385             :             {
+     386        2424 :                 for(i=0; (i<sh->natoms); i++)
+     387        9504 :                     for(j=0; (j<DIM); j++)
+     388        7128 :                         if (NULL != x)
+     389             :                         {
+     390        7128 :                             fx[i*DIM+j] = x[i][j];
+     391             :                         }
+     392             :             }
+     393          84 :             if (xdrfile_read_float(fx,sh->natoms*DIM,xd) == sh->natoms*DIM)
+     394             :             {
+     395          84 :                 if (bRead) 
+     396             :                 {
+     397         828 :                     for(i=0; (i<sh->natoms); i++)
+     398        3168 :                         for(j=0; (j<DIM); j++)
+     399        2376 :                             if (NULL != x)
+     400        2376 :                                 x[i][j] = fx[i*DIM+j];
+     401             :                 }
+     402             :             }
+     403             :             else
+     404             :                 return exdrFLOAT;
+     405             :         }
+     406          84 :                 if (sh->v_size   != 0) 
+     407             :         {
+     408           0 :             if (!bRead) 
+     409             :             {
+     410           0 :                 for(i=0; (i<sh->natoms); i++)
+     411           0 :                     for(j=0; (j<DIM); j++)
+     412           0 :                         if (NULL != x)
+     413             :                         {
+     414           0 :                             fx[i*DIM+j] = v[i][j];
+     415             :                         }
+     416             :             }
+     417           0 :             if (xdrfile_read_float(fx,sh->natoms*DIM,xd) == sh->natoms*DIM)
+     418             :             {
+     419           0 :                 for(i=0; (i<sh->natoms); i++)
+     420           0 :                     for(j=0; (j<DIM); j++)
+     421           0 :                         if (NULL != v)
+     422           0 :                             v[i][j] = fx[i*DIM+j];
+     423             :             }
+     424             :             else
+     425             :                 return exdrFLOAT;
+     426             :         }
+     427          84 :                 if (sh->f_size   != 0) 
+     428             :         {
+     429           0 :            if (!bRead) 
+     430             :             {
+     431           0 :                 for(i=0; (i<sh->natoms); i++)
+     432           0 :                     for(j=0; (j<DIM); j++)
+     433           0 :                         if (NULL != x)
+     434             :                         {
+     435           0 :                             fx[i*DIM+j] = f[i][j];
+     436             :                         }
+     437             :             }
+     438           0 :              if (xdrfile_read_float(fx,sh->natoms*DIM,xd) == sh->natoms*DIM)
+     439             :             {
+     440           0 :                 for(i=0; (i<sh->natoms); i++)
+     441           0 :                     for(j=0; (j<DIM); j++)
+     442           0 :                         if (NULL != f)
+     443           0 :                             f[i][j] = fx[i*DIM+j];
+     444             :             }
+     445             :             else
+     446             :                 return exdrFLOAT;
+     447             :         }
+     448          84 :                 if ((sh->x_size != 0) || (sh->v_size != 0) || (sh->f_size != 0)) {
+     449          84 :                         free(fx);
+     450             :                 }
+     451             :         }
+     452             :         return exdrOK;
+     453             : }
+     454             : 
+     455          87 : static int do_trn(XDRFILE *xd,mybool bRead,int *step,float *t,float *lambda,
+     456             :                                   matrix box,int *natoms,rvec *x,rvec *v,rvec *f)
+     457             : {
+     458             :     t_trnheader *sh;
+     459             :     int result;
+     460             :   
+     461          87 :     sh = (t_trnheader *)calloc(1,sizeof(*sh));
+     462             :   
+     463          87 :     if (!bRead) {
+     464          48 :         sh->box_size = (NULL != box) ? sizeof(matrix):0;
+     465          48 :         sh->x_size   = ((NULL != x) ? (*natoms*sizeof(x[0])):0);
+     466          48 :         sh->v_size   = ((NULL != v) ? (*natoms*sizeof(v[0])):0);
+     467          48 :         sh->f_size   = ((NULL != f) ? (*natoms*sizeof(f[0])):0);
+     468          48 :         sh->natoms = *natoms;
+     469          48 :         sh->step   = *step;
+     470          48 :         sh->nre    = 0;
+     471          48 :         sh->td      = *t;
+     472          48 :         sh->lambdad = *lambda;
+     473          48 :         sh->tf      = *t;
+     474          48 :         sh->lambdaf = *lambda;
+     475             :     }
+     476          87 :     if ((result = do_trnheader(xd,bRead,sh)) != exdrOK)
+     477             :         return result;
+     478          84 :     if (bRead) {
+     479          36 :         *natoms = sh->natoms;
+     480          36 :         *step   = sh->step;
+     481          36 :         *t      = sh->td;
+     482          36 :         *lambda = sh->lambdad;
+     483             :     }
+     484          84 :     if ((result = do_htrn(xd,bRead,sh,box,x,v,f)) != exdrOK)
+     485             :         return result;
+     486             : 
+     487          84 :     free(sh);
+     488             :   
+     489          84 :     return exdrOK;
+     490             : }
+     491             : 
+     492             : /************************************************************
+     493             :  *
+     494             :  *  The following routines are the exported ones
+     495             :  *
+     496             :  ************************************************************/
+     497             :  
+     498           3 : int read_trr_natoms(char *fn,int *natoms)
+     499             : {
+     500             :         XDRFILE *xd;
+     501             :         t_trnheader sh;
+     502             :         int  result;
+     503             :         
+     504           3 :         xd = xdrfile_open(fn,"r");
+     505           3 :         if (NULL == xd)
+     506             :                 return exdrFILENOTFOUND;
+     507           3 :         if ((result = do_trnheader(xd,1,&sh)) != exdrOK)
+     508             :                 return result;
+     509           3 :         xdrfile_close(xd);
+     510           3 :         *natoms = sh.natoms;
+     511             :         
+     512           3 :         return exdrOK;
+     513             : }
+     514             : 
+     515          48 : int write_trr(XDRFILE *xd,int natoms,int step,float t,float lambda,
+     516             :                           matrix box,rvec *x,rvec *v,rvec *f)
+     517             : {
+     518          48 :         return do_trn(xd,0,&step,&t,&lambda,box,&natoms,x,v,f);
+     519             : }
+     520             : 
+     521          39 : int read_trr(XDRFILE *xd,int natoms,int *step,float *t,float *lambda,
+     522             :                          matrix box,rvec *x,rvec *v,rvec *f)
+     523             : {
+     524          39 :         return do_trn(xd,1,step,t,lambda,box,&natoms,x,v,f);
+     525             : }
+     526             : 
+     527             : }
+     528             : }
+     529             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile_xtc.cpp.func-sort-c.html b/coverage-libs/xdrfile/xdrfile_xtc.cpp.func-sort-c.html new file mode 100644 index 000000000000..267b27f15109 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_xtc.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_xtc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_xtc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:273381.8 %
Date:2024-02-22 21:58:47Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile15read_xtc_natomsEPcPi2
_ZN4PLMD7xdrfile8read_xtcEPNS0_7XDRFILEEiPiPfPA3_fS6_S4_30
_ZN4PLMD7xdrfile9write_xtcEPNS0_7XDRFILEEiifPA3_fS4_f72
_ZN4PLMD7xdrfileL9xtc_coordEPNS0_7XDRFILEEPiPA3_fS5_Pfi100
_ZN4PLMD7xdrfileL10xtc_headerEPNS0_7XDRFILEEPiS3_Pfi104
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile_xtc.cpp.func.html b/coverage-libs/xdrfile/xdrfile_xtc.cpp.func.html new file mode 100644 index 000000000000..bebf12a53bb7 --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_xtc.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_xtc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_xtc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:273381.8 %
Date:2024-02-22 21:58:47Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7xdrfile15read_xtc_natomsEPcPi2
_ZN4PLMD7xdrfile8read_xtcEPNS0_7XDRFILEEiPiPfPA3_fS6_S4_30
_ZN4PLMD7xdrfile9write_xtcEPNS0_7XDRFILEEiifPA3_fS4_f72
_ZN4PLMD7xdrfileL10xtc_headerEPNS0_7XDRFILEEPiS3_Pfi104
_ZN4PLMD7xdrfileL9xtc_coordEPNS0_7XDRFILEEPiPA3_fS5_Pfi100
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage-libs/xdrfile/xdrfile_xtc.cpp.gcov.html b/coverage-libs/xdrfile/xdrfile_xtc.cpp.gcov.html new file mode 100644 index 000000000000..94407652272b --- /dev/null +++ b/coverage-libs/xdrfile/xdrfile_xtc.cpp.gcov.html @@ -0,0 +1,242 @@ + + + + + + + + LCOV - plumed test coverage (other modules) - xdrfile/xdrfile_xtc.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - xdrfile - xdrfile_xtc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverage (other modules)Lines:273381.8 %
Date:2024-02-22 21:58:47Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2009-2014, Erik Lindahl & David van der Spoel
+       3             : All rights reserved.
+       4             : 
+       5             : Redistribution and use in source and binary forms, with or without
+       6             : modification, are permitted provided that the following conditions are met:
+       7             : 
+       8             : 1. Redistributions of source code must retain the above copyright notice, this
+       9             : list of conditions and the following disclaimer.
+      10             : 
+      11             : 2. Redistributions in binary form must reproduce the above copyright notice,
+      12             : this list of conditions and the following disclaimer in the documentation
+      13             : and/or other materials provided with the distribution.
+      14             : 
+      15             : THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+      16             : AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+      17             : IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+      18             : DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+      19             : FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+      20             : DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+      21             : SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+      22             : CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+      23             : OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+      24             : OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+      25             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      26             : /* -*- mode: c; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- 
+      27             :  *
+      28             :  * $Id$
+      29             :  *
+      30             :  * Copyright (c) 2009-2014, Erik Lindahl & David van der Spoel
+      31             :  * All rights reserved.
+      32             :  *
+      33             :  * Redistribution and use in source and binary forms, with or without
+      34             :  * modification, are permitted provided that the following conditions are met:
+      35             :  *
+      36             :  * 1. Redistributions of source code must retain the above copyright notice, this
+      37             :  * list of conditions and the following disclaimer.
+      38             :  *
+      39             :  * 2. Redistributions in binary form must reproduce the above copyright notice,
+      40             :  * this list of conditions and the following disclaimer in the documentation
+      41             :  * and/or other materials provided with the distribution.
+      42             :  *
+      43             :  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+      44             :  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+      45             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+      46             :  * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+      47             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+      48             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+      49             :  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+      50             :  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+      51             :  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+      52             :  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+      53             :  */
+      54             :  
+      55             : #include <stdlib.h>
+      56             : #include "xdrfile.h"
+      57             : #include "xdrfile_xtc.h"
+      58             :         
+      59             : #define MAGIC 1995
+      60             : 
+      61             : namespace PLMD {
+      62             : namespace xdrfile {
+      63             : 
+      64             : enum { FALSE, TRUE };
+      65             : 
+      66         104 : static int xtc_header(XDRFILE *xd,int *natoms,int *step,float *time,mybool bRead)
+      67             : {
+      68             :         int result,magic,n=1;
+      69             :         
+      70             :         /* Note: read is same as write. He he he */
+      71         104 :         magic  = MAGIC;
+      72         104 :         if ((result = xdrfile_write_int(&magic,n,xd)) != n)
+      73             :                 {
+      74           2 :                         if (bRead)
+      75             :                                 return exdrENDOFFILE;
+      76             :                         else
+      77           0 :                                 return exdrINT;
+      78             :                 }
+      79         102 :         if (magic != MAGIC)
+      80             :                 return exdrMAGIC;
+      81         102 :         if ((result = xdrfile_write_int(natoms,n,xd)) != n)
+      82             :                 return exdrINT;
+      83         102 :         if ((result = xdrfile_write_int(step,n,xd)) != n)
+      84             :                 return exdrINT;
+      85         102 :         if ((result = xdrfile_write_float(time,n,xd)) != n)
+      86           0 :                 return exdrFLOAT;
+      87             :         
+      88             :         return exdrOK;
+      89             : }
+      90             : 
+      91         100 : static int xtc_coord(XDRFILE *xd,int *natoms,matrix box,rvec *x,float *prec,
+      92             :                                          mybool bRead)
+      93             : {
+      94             :         int i,j,result;
+      95             :     
+      96             :         /* box */
+      97         100 :         result = xdrfile_read_float(box[0],DIM*DIM,xd);
+      98         100 :         if (DIM*DIM != result)
+      99             :                 return exdrFLOAT;
+     100             :         else 
+     101             :                 {
+     102         100 :                         if (bRead)
+     103             :                                 {
+     104          28 :                                         result = xdrfile_decompress_coord_float(x[0],natoms,prec,xd); 
+     105          28 :                                         if (result != *natoms)
+     106           0 :                                                 return exdr3DX;
+     107             :                                 }
+     108             :                         else
+     109             :                                 {
+     110          72 :                                         result = xdrfile_compress_coord_float(x[0],*natoms,*prec,xd); 
+     111          72 :                                         if (result != *natoms)
+     112           0 :                                                 return exdr3DX;
+     113             :                                 }
+     114             :                 }
+     115             :         return exdrOK;
+     116             : }
+     117             : 
+     118           2 : int read_xtc_natoms(char *fn,int *natoms)
+     119             : {
+     120             :         XDRFILE *xd;
+     121             :         int step,result;
+     122             :         float time;
+     123             :         
+     124           2 :         xd = xdrfile_open(fn,"r");
+     125           2 :         if (NULL == xd)
+     126             :                 return exdrFILENOTFOUND;
+     127           2 :         result = xtc_header(xd,natoms,&step,&time,TRUE);
+     128           2 :         xdrfile_close(xd);
+     129             :         
+     130             :         return result;
+     131             : }
+     132             : 
+     133          30 : int read_xtc(XDRFILE *xd,
+     134             :                          int natoms,int *step,float *time,
+     135             :                          matrix box,rvec *x,float *prec)
+     136             : /* Read subsequent frames */
+     137             : {
+     138             :         int result;
+     139             :   
+     140          30 :         if ((result = xtc_header(xd,&natoms,step,time,TRUE)) != exdrOK)
+     141             :                 return result;
+     142             :           
+     143          28 :         if ((result = xtc_coord(xd,&natoms,box,x,prec,1)) != exdrOK)
+     144           0 :                 return result;
+     145             :   
+     146             :         return exdrOK;
+     147             : }
+     148             : 
+     149          72 : int write_xtc(XDRFILE *xd,
+     150             :                           int natoms,int step,float time,
+     151             :                           matrix box,rvec *x,float prec)
+     152             : /* Write a frame to xtc file */
+     153             : {
+     154             :         int result;
+     155             :   
+     156          72 :         if ((result = xtc_header(xd,&natoms,&step,&time,FALSE)) != exdrOK)
+     157             :                 return result;
+     158             : 
+     159          72 :         if ((result = xtc_coord(xd,&natoms,box,x,&prec,0)) != exdrOK)
+     160           0 :                 return result;
+     161             :   
+     162             :         return exdrOK;
+     163             : }
+     164             : }
+     165             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.cpp.func-sort-c.html b/coverage/adjmat/ActionWithInputMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..d96562308fcd --- /dev/null +++ b/coverage/adjmat/ActionWithInputMatrix.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithInputMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithInputMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7070100.0 %
Date:2024-02-22 21:58:45Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ActionWithInputMatrixC1ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat21ActionWithInputMatrix18getBaseMultiColvarERKj7
_ZN4PLMD6adjmat21ActionWithInputMatrixC2ERKNS_13ActionOptionsE27
_ZNK4PLMD6adjmat21ActionWithInputMatrix23getNumberOfAtomsInGroupERKj34
_ZN4PLMD6adjmat21ActionWithInputMatrix16registerKeywordsERNS_8KeywordsE37
_ZNK4PLMD6adjmat21ActionWithInputMatrix20getNumberOfNodeTypesEv66
_ZNK4PLMD6adjmat21ActionWithInputMatrix29getAbsoluteIndexOfCentralAtomERKj504
_ZNK4PLMD6adjmat21ActionWithInputMatrix24addConnectionDerivativesERKjS3_RNS_10MultiValueES5_1440
_ZNK4PLMD6adjmat21ActionWithInputMatrix19getInputDerivativesERKjRKbRKNS_11multicolvar13AtomValuePackE1679
_ZNK4PLMD6adjmat21ActionWithInputMatrix12getInputDataERKjRKbRKNS_11multicolvar13AtomValuePackERSt6vectorIdSaIdEE2004
_ZNK4PLMD6adjmat21ActionWithInputMatrix21getNumberOfQuantitiesEv2181
_ZN4PLMD6adjmat21ActionWithInputMatrix22getNumberOfDerivativesEv13250
_ZNK4PLMD6adjmat21ActionWithInputMatrix23retrieveConnectionValueERKjS3_RSt6vectorIdSaIdEE46452
_ZNK4PLMD6adjmat21ActionWithInputMatrix29getPositionOfAtomForLinkCellsERKj54763
_ZNK4PLMD6adjmat21ActionWithInputMatrix18getAdjacencyVesselEv78058
_ZNK4PLMD6adjmat21ActionWithInputMatrix16getNumberOfNodesEv16261547
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.cpp.func.html b/coverage/adjmat/ActionWithInputMatrix.cpp.func.html new file mode 100644 index 000000000000..4d87b78645c3 --- /dev/null +++ b/coverage/adjmat/ActionWithInputMatrix.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithInputMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithInputMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7070100.0 %
Date:2024-02-22 21:58:45Functions:151693.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ActionWithInputMatrix16registerKeywordsERNS_8KeywordsE37
_ZN4PLMD6adjmat21ActionWithInputMatrix22getNumberOfDerivativesEv13250
_ZN4PLMD6adjmat21ActionWithInputMatrixC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat21ActionWithInputMatrixC2ERKNS_13ActionOptionsE27
_ZNK4PLMD6adjmat21ActionWithInputMatrix12getInputDataERKjRKbRKNS_11multicolvar13AtomValuePackERSt6vectorIdSaIdEE2004
_ZNK4PLMD6adjmat21ActionWithInputMatrix16getNumberOfNodesEv16261547
_ZNK4PLMD6adjmat21ActionWithInputMatrix18getAdjacencyVesselEv78058
_ZNK4PLMD6adjmat21ActionWithInputMatrix18getBaseMultiColvarERKj7
_ZNK4PLMD6adjmat21ActionWithInputMatrix19getInputDerivativesERKjRKbRKNS_11multicolvar13AtomValuePackE1679
_ZNK4PLMD6adjmat21ActionWithInputMatrix20getNumberOfNodeTypesEv66
_ZNK4PLMD6adjmat21ActionWithInputMatrix21getNumberOfQuantitiesEv2181
_ZNK4PLMD6adjmat21ActionWithInputMatrix23getNumberOfAtomsInGroupERKj34
_ZNK4PLMD6adjmat21ActionWithInputMatrix23retrieveConnectionValueERKjS3_RSt6vectorIdSaIdEE46452
_ZNK4PLMD6adjmat21ActionWithInputMatrix24addConnectionDerivativesERKjS3_RNS_10MultiValueES5_1440
_ZNK4PLMD6adjmat21ActionWithInputMatrix29getAbsoluteIndexOfCentralAtomERKj504
_ZNK4PLMD6adjmat21ActionWithInputMatrix29getPositionOfAtomForLinkCellsERKj54763
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.cpp.gcov.html b/coverage/adjmat/ActionWithInputMatrix.cpp.gcov.html new file mode 100644 index 000000000000..8cf54665111c --- /dev/null +++ b/coverage/adjmat/ActionWithInputMatrix.cpp.gcov.html @@ -0,0 +1,231 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithInputMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithInputMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7070100.0 %
Date:2024-02-22 21:58:45Functions:151693.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithInputMatrix.h"
+      23             : #include "AdjacencyMatrixVessel.h"
+      24             : #include "AdjacencyMatrixBase.h"
+      25             : #include "vesselbase/ActionWithVessel.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace adjmat {
+      31             : 
+      32          37 : void ActionWithInputMatrix::registerKeywords( Keywords& keys ) {
+      33          37 :   MultiColvarBase::registerKeywords( keys );
+      34          74 :   keys.add("compulsory","MATRIX","the action that calculates the adjacency matrix vessel we would like to analyze");
+      35          37 : }
+      36             : 
+      37             : 
+      38          27 : ActionWithInputMatrix::ActionWithInputMatrix(const ActionOptions& ao):
+      39             :   Action(ao),
+      40             :   MultiColvarBase(ao),
+      41          27 :   mymatrix(NULL)
+      42             : {
+      43          27 :   matsums=true;
+      44          54 :   if( keywords.exists("MATRIX") ) {
+      45             :     std::vector<AtomNumber> fake_atoms;
+      46          50 :     if( !parseMultiColvarAtomList("MATRIX",-1,fake_atoms ) ) error("unable to interpret input matrix");
+      47          25 :     if( mybasemulticolvars.size()!=1 ) error("should be exactly one matrix input");
+      48             : 
+      49             :     // Retrieve the adjacency matrix of interest
+      50          25 :     for(unsigned i=0; i<mybasemulticolvars[0]->getNumberOfVessels(); ++i) {
+      51          25 :       mymatrix = dynamic_cast<AdjacencyMatrixVessel*>( mybasemulticolvars[0]->getPntrToVessel(i) );
+      52          25 :       if( mymatrix ) break ;
+      53             :     }
+      54          25 :     if( !mymatrix ) error( mybasemulticolvars[0]->getLabel() + " does not calculate an adjacency matrix");
+      55             : 
+      56          25 :     atom_lab.resize(0); unsigned nnodes; // Delete all the atom labels that have been created
+      57          25 :     if( mymatrix->undirectedGraph() ) nnodes = (mymatrix->function)->ablocks[0].size();
+      58           2 :     else nnodes = (mymatrix->function)->ablocks[0].size() + (mymatrix->function)->ablocks[1].size();
+      59        6816 :     for(unsigned i=0; i<nnodes; ++i) atom_lab.push_back( std::pair<unsigned,unsigned>( 1, i ) );
+      60             :   }
+      61          27 : }
+      62             : 
+      63       13250 : unsigned ActionWithInputMatrix::getNumberOfDerivatives() {
+      64       13250 :   return (mymatrix->function)->getNumberOfDerivatives();
+      65             : }
+      66             : 
+      67    16261547 : unsigned ActionWithInputMatrix::getNumberOfNodes() const {
+      68    16261547 :   return (mymatrix->function)->ablocks[0].size();
+      69             : }
+      70             : 
+      71       78058 : AdjacencyMatrixVessel* ActionWithInputMatrix::getAdjacencyVessel() const {
+      72       78058 :   return mymatrix;
+      73             : }
+      74             : 
+      75         504 : AtomNumber ActionWithInputMatrix::getAbsoluteIndexOfCentralAtom(const unsigned& i) const {
+      76         504 :   return (mymatrix->function)->getAbsoluteIndexOfCentralAtom(i);
+      77             : }
+      78             : 
+      79       46452 : double ActionWithInputMatrix::retrieveConnectionValue( const unsigned& i, const unsigned& j, std::vector<double>& vals ) const {
+      80       46452 :   if( !mymatrix->matrixElementIsActive( i, j ) ) return 0;
+      81       25360 :   unsigned myelem = mymatrix->getStoreIndexFromMatrixIndices( i, j );
+      82             : 
+      83             :   // unsigned vi; double df;
+      84       25360 :   mymatrix->retrieveValueWithIndex( myelem, false, vals );
+      85       25360 :   return vals[0]*vals[1];       // (mymatrix->function)->transformStoredValues( vals, vi, df );
+      86             : }
+      87             : 
+      88        2004 : void ActionWithInputMatrix::getInputData( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms, std::vector<double>& orient0 ) const {
+      89        2004 :   if( (mymatrix->function)->mybasemulticolvars.size()==0  ) {
+      90         305 :     std::vector<double> tvals( mymatrix->getNumberOfComponents() ); orient0.assign(orient0.size(),0);
+      91       38263 :     for(unsigned i=0; i<mymatrix->getNumberOfColumns(); ++i) {
+      92       37958 :       if( mymatrix->undirectedGraph() && ind==i ) continue;
+      93       37678 :       orient0[1]+=retrieveConnectionValue( ind, i, tvals );
+      94             :     }
+      95         305 :     orient0[0]=1.0; return;
+      96             :   }
+      97        1699 :   (mymatrix->function)->getInputData( ind, normed, myatoms, orient0 );
+      98             : }
+      99             : 
+     100        1440 : void ActionWithInputMatrix::addConnectionDerivatives( const unsigned& i, const unsigned& j, MultiValue& myvals, MultiValue& myvout ) const {
+     101        1440 :   if( !mymatrix->matrixElementIsActive( i, j ) ) return;
+     102        1440 :   unsigned myelem = mymatrix->getStoreIndexFromMatrixIndices( i, j );
+     103             :   // Get derivatives and add
+     104        1440 :   mymatrix->retrieveDerivatives( myelem, false, myvals );
+     105       31086 :   for(unsigned jd=0; jd<myvals.getNumberActive(); ++jd) {
+     106       29646 :     unsigned ider=myvals.getActiveIndex(jd);
+     107       29646 :     myvout.addDerivative( 1, ider, myvals.getDerivative( 1, ider ) );
+     108             :   }
+     109             : }
+     110             : 
+     111        1679 : MultiValue& ActionWithInputMatrix::getInputDerivatives( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const {
+     112        1679 :   if( (mymatrix->function)->mybasemulticolvars.size()==0  ) {
+     113          90 :     MultiValue& myder=mymatrix->getTemporyMultiValue(0);
+     114          90 :     if( myder.getNumberOfValues()!=2 || myder.getNumberOfDerivatives()!=(mymatrix->function)->getNumberOfDerivatives() ) {
+     115           3 :       myder.resize( 2, (mymatrix->function)->getNumberOfDerivatives() );
+     116             :     }
+     117          90 :     myder.clearAll();
+     118          90 :     MultiValue myvals( (mymatrix->function)->getNumberOfQuantities(), (mymatrix->function)->getNumberOfDerivatives() );
+     119         885 :     for(unsigned i=0; i<mymatrix->getNumberOfColumns(); ++i) {
+     120         795 :       if( mymatrix->undirectedGraph() && ind==i ) continue;
+     121         730 :       addConnectionDerivatives( ind, i, myvals, myder );
+     122             :     }
+     123             :     myder.updateDynamicList(); return myder;
+     124          90 :   }
+     125        1589 :   return (mymatrix->function)->getInputDerivatives( ind, normed, myatoms );
+     126             : }
+     127             : 
+     128          66 : unsigned ActionWithInputMatrix::getNumberOfNodeTypes() const {
+     129          66 :   unsigned size = (mymatrix->function)->mybasemulticolvars.size();
+     130             :   if( size==0 ) return 1;
+     131             :   return size;
+     132             : }
+     133             : 
+     134        2181 : unsigned ActionWithInputMatrix::getNumberOfQuantities() const {
+     135        2181 :   if( (mymatrix->function)->mybasemulticolvars.size()==0 ) return 2;
+     136        2082 :   return (mymatrix->function)->mybasemulticolvars[0]->getNumberOfQuantities();
+     137             : }
+     138             : 
+     139          34 : unsigned ActionWithInputMatrix::getNumberOfAtomsInGroup( const unsigned& igrp ) const {
+     140             :   plumed_dbg_assert( igrp<(mymatrix->function)->mybasemulticolvars.size() );
+     141          34 :   return (mymatrix->function)->mybasemulticolvars[igrp]->getFullNumberOfTasks();
+     142             : }
+     143             : 
+     144           7 : multicolvar::MultiColvarBase* ActionWithInputMatrix::getBaseMultiColvar( const unsigned& igrp ) const {
+     145             :   plumed_dbg_assert( igrp<(mymatrix->function)->mybasemulticolvars.size() );
+     146           7 :   return (mymatrix->function)->mybasemulticolvars[igrp];
+     147             : }
+     148             : 
+     149       54763 : Vector ActionWithInputMatrix::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
+     150       54763 :   return (getAdjacencyVessel()->function)->getPositionOfAtomForLinkCells( iatom );
+     151             : }
+     152             : 
+     153             : }
+     154             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.h.func-sort-c.html b/coverage/adjmat/ActionWithInputMatrix.h.func-sort-c.html new file mode 100644 index 000000000000..d1fba37e1404 --- /dev/null +++ b/coverage/adjmat/ActionWithInputMatrix.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithInputMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithInputMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat21ActionWithInputMatrix7computeERKjRNS_11multicolvar13AtomValuePackE0
_ZN4PLMD6adjmat21ActionWithInputMatrix10isPeriodicEv80
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.h.func.html b/coverage/adjmat/ActionWithInputMatrix.h.func.html new file mode 100644 index 000000000000..0d0c8d59dc24 --- /dev/null +++ b/coverage/adjmat/ActionWithInputMatrix.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithInputMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithInputMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21ActionWithInputMatrix10isPeriodicEv80
_ZNK4PLMD6adjmat21ActionWithInputMatrix7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ActionWithInputMatrix.h.gcov.html b/coverage/adjmat/ActionWithInputMatrix.h.gcov.html new file mode 100644 index 000000000000..130deb24d6f1 --- /dev/null +++ b/coverage/adjmat/ActionWithInputMatrix.h.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ActionWithInputMatrix.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ActionWithInputMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_adjmat_ActionWithInputMatrix_h
+      23             : #define __PLUMED_adjmat_ActionWithInputMatrix_h
+      24             : 
+      25             : #include "core/ActionWithValue.h"
+      26             : #include "core/ActionAtomistic.h"
+      27             : #include "multicolvar/MultiColvarBase.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace adjmat {
+      31             : 
+      32             : class AdjacencyMatrixVessel;
+      33             : 
+      34             : class ActionWithInputMatrix : public multicolvar::MultiColvarBase {
+      35             : protected:
+      36             : /// The vessel that holds the adjacency matrix
+      37             :   AdjacencyMatrixVessel* mymatrix;
+      38             : /// Get number of base multicolvar types
+      39             :   unsigned getNumberOfNodeTypes() const ;
+      40             : /// Get number of atoms in each base multicolvar
+      41             :   unsigned getNumberOfAtomsInGroup( const unsigned& igrp ) const ;
+      42             : /// Get a pointer to the igrp th base multicolvar
+      43             :   multicolvar::MultiColvarBase* getBaseMultiColvar( const unsigned& igrp ) const ;
+      44             : public:
+      45             :   static void registerKeywords( Keywords& keys );
+      46             :   explicit ActionWithInputMatrix(const ActionOptions&);
+      47             : /// Retrieve the vessel that holds the adjacency matrix
+      48             :   AdjacencyMatrixVessel* getAdjacencyVessel() const ;
+      49             : /// Retrieve the value of the connection
+      50             :   double retrieveConnectionValue( const unsigned& i, const unsigned& j, std::vector<double>& vals ) const ;
+      51             : /// Get the vector for task ind
+      52             :   void getInputData( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms, std::vector<double>& orient0 ) const override;
+      53             : /// Add the derivatives on a connection
+      54             :   void addConnectionDerivatives( const unsigned& i, const unsigned& j, MultiValue& myvals, MultiValue& myvout ) const ;
+      55             : /// Get vector derivatives
+      56             :   MultiValue& getInputDerivatives( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const override;
+      57             :   unsigned getNumberOfDerivatives() override;
+      58             : ///  Get the number of rows/cols in the adjacency matrix vessel
+      59             :   virtual unsigned getNumberOfNodes() const;
+      60          80 :   bool isPeriodic() override { return false; }
+      61             :   unsigned getNumberOfQuantities() const override;
+      62             : ///
+      63             :   AtomNumber getAbsoluteIndexOfCentralAtom(const unsigned& i) const override;
+      64             : /// No loop over tasks for ActionWithInputMatrix
+      65           0 :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const override { plumed_error(); }
+      66             : ///
+      67             :   Vector getPositionOfAtomForLinkCells( const unsigned& iatom ) const override;
+      68             : };
+      69             : 
+      70             : }
+      71             : }
+      72             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..a39e7c8e6416 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AdjacencyMatrixBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AdjacencyMatrixBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8510085.0 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBase24recalculateMatrixElementERKjRNS_10MultiValueE0
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19AdjacencyMatrixBase25readMaxThreeSpeciesMatrixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_S9_RKb10
_ZN4PLMD6adjmat19AdjacencyMatrixBase23readMaxTwoSpeciesMatrixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RKb13
_ZN4PLMD6adjmat19AdjacencyMatrixBase17finishMatrixSetupERKbRKSt6vectorINS_10AtomNumberESaIS5_EE23
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC2ERKNS_13ActionOptionsE23
_ZNK4PLMD6adjmat19AdjacencyMatrixBase22retrieveTypeDimensionsERjS2_S2_24
_ZN4PLMD6adjmat19AdjacencyMatrixBase16registerKeywordsERNS_8KeywordsE35
_ZN4PLMD6adjmat19AdjacencyMatrixBase27parseConnectionDescriptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbRKj46
_ZNK4PLMD6adjmat19AdjacencyMatrixBase20getNumberOfNodeTypesEv132
_ZNK4PLMD6adjmat19AdjacencyMatrixBase21getSizeOfInputVectorsEv5807
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html new file mode 100644 index 000000000000..650d0b2ce345 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AdjacencyMatrixBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AdjacencyMatrixBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8510085.0 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBase16registerKeywordsERNS_8KeywordsE35
_ZN4PLMD6adjmat19AdjacencyMatrixBase17finishMatrixSetupERKbRKSt6vectorINS_10AtomNumberESaIS5_EE23
_ZN4PLMD6adjmat19AdjacencyMatrixBase23readMaxTwoSpeciesMatrixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RKb13
_ZN4PLMD6adjmat19AdjacencyMatrixBase24recalculateMatrixElementERKjRNS_10MultiValueE0
_ZN4PLMD6adjmat19AdjacencyMatrixBase25readMaxThreeSpeciesMatrixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_S9_RKb10
_ZN4PLMD6adjmat19AdjacencyMatrixBase27parseConnectionDescriptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbRKj46
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19AdjacencyMatrixBaseC2ERKNS_13ActionOptionsE23
_ZNK4PLMD6adjmat19AdjacencyMatrixBase20getNumberOfNodeTypesEv132
_ZNK4PLMD6adjmat19AdjacencyMatrixBase21getSizeOfInputVectorsEv5807
_ZNK4PLMD6adjmat19AdjacencyMatrixBase22retrieveTypeDimensionsERjS2_S2_24
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html b/coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html new file mode 100644 index 000000000000..48a8121eca65 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.cpp.gcov.html @@ -0,0 +1,274 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AdjacencyMatrixBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AdjacencyMatrixBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8510085.0 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AdjacencyMatrixBase.h"
+      23             : #include "multicolvar/BridgedMultiColvarFunction.h"
+      24             : #include "multicolvar/AtomValuePack.h"
+      25             : #include "multicolvar/CatomPack.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace adjmat {
+      31             : 
+      32          35 : void AdjacencyMatrixBase::registerKeywords( Keywords& keys ) {
+      33          35 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      34          70 :   keys.remove("LOWMEM"); keys.use("HIGHMEM");
+      35          35 : }
+      36             : 
+      37          23 : AdjacencyMatrixBase::AdjacencyMatrixBase(const ActionOptions& ao):
+      38             :   Action(ao),
+      39             :   MultiColvarBase(ao),
+      40          23 :   connect_id(0),
+      41          23 :   no_third_dim_accum(true),
+      42          23 :   mat(NULL)
+      43             : {
+      44          46 :   log<<"  Bibliography "<<plumed.cite("Tribello, Giberti, Sosso, Salvalaglio and Parrinello, J. Chem. Theory Comput. 13, 1317 (2017)")<<"\n";
+      45          23 : }
+      46             : 
+      47          46 : void AdjacencyMatrixBase::parseConnectionDescriptions( const std::string& key, const bool& multiple, const unsigned& nrow_t ) {
+      48          46 :   if( getNumberOfNodeTypes()==1 || (getNumberOfNodeTypes()==2 && nrow_t==1) ) {
+      49             :     std::vector<std::string> sw;
+      50          45 :     if( !multiple ) {
+      51          44 :       sw.resize(1); parse(key,sw[0]);
+      52          44 :       if(sw[0].length()==0) error("could not find " + key + " keyword");
+      53             :     } else {
+      54             :       std::string input;
+      55           2 :       for(int i=1;; i++) {
+      56           3 :         if( !parseNumbered(key, i, input ) ) break;
+      57           2 :         sw.push_back( input );
+      58             :       }
+      59             :     }
+      60          45 :     setupConnector( connect_id, 0, 0, sw );
+      61          45 :   } else {
+      62           1 :     if( multiple ) error("keyword " + key + " does not work with multiple input strings");
+      63             :     unsigned nr, nc;
+      64           1 :     if( nrow_t==0 ) {
+      65           1 :       nr=nc=getNumberOfNodeTypes();
+      66             :     } else {
+      67           0 :       nr=nrow_t; nc = getNumberOfNodeTypes() - nr;
+      68             :     }
+      69           3 :     for(unsigned i=0; i<nr; ++i) {
+      70             :       // Retrieve the base number
+      71             :       unsigned ibase;
+      72           2 :       if( nc<10 ) {
+      73           2 :         ibase=(i+1)*10;
+      74           0 :       } else if ( nc<100 ) {
+      75           0 :         ibase=(i+1)*100;
+      76             :       } else {
+      77           0 :         error("wow this is an error I never would have expected");
+      78             :       }
+      79             : 
+      80           5 :       for(unsigned j=i; j<nc; ++j) {
+      81           3 :         std::vector<std::string> sw(1); parseNumbered(key,ibase+j+1,sw[0]);
+      82           3 :         if(sw[0].length()==0) {
+      83           0 :           std::string num; Tools::convert(ibase+j+1,num);
+      84           0 :           error("could not find " + key + num + " keyword. Need one " + key + " keyword for each distinct base-multicolvar-pair type");
+      85             :         }
+      86           3 :         setupConnector( connect_id, i, j, sw );
+      87           3 :       }
+      88             :     }
+      89             :   }
+      90          46 :   connect_id++;
+      91          46 : }
+      92             : 
+      93        5807 : unsigned AdjacencyMatrixBase::getSizeOfInputVectors() const {
+      94        5807 :   if( mybasemulticolvars.size()==0 ) return 2;
+      95             : 
+      96        5807 :   unsigned nq = mybasemulticolvars[0]->getNumberOfQuantities();
+      97        5807 :   for(unsigned i=1; i<mybasemulticolvars.size(); ++i) {
+      98           0 :     if( mybasemulticolvars[i]->getNumberOfQuantities()!=nq ) error("mismatch between vectors in base colvars");
+      99             :   }
+     100             :   return nq;
+     101             : }
+     102             : 
+     103         132 : unsigned AdjacencyMatrixBase::getNumberOfNodeTypes() const {
+     104         132 :   unsigned size=mybasemulticolvars.size();
+     105             :   if( size==0 ) return 1;
+     106             :   return size;
+     107             : }
+     108             : 
+     109          24 : void AdjacencyMatrixBase::retrieveTypeDimensions( unsigned& nrows, unsigned& ncols, unsigned& ntype ) const {
+     110          24 :   bool allsame=(ablocks[0].size()==ablocks[1].size());
+     111          24 :   if( allsame ) {
+     112        6952 :     for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     113        6929 :       if( ablocks[0][i]!=ablocks[1][i] ) allsame=false;
+     114             :     }
+     115             :   }
+     116             : 
+     117          24 :   if( allsame ) {
+     118          23 :     std::vector<unsigned> types(1); types[0]=atom_lab[ablocks[0][0]].first;
+     119        6929 :     for(unsigned i=1; i<ablocks[0].size(); ++i) {
+     120             :       bool found = false;
+     121        6913 :       for(unsigned j=0; j<types.size(); ++j) {
+     122        6912 :         if( atom_lab[ablocks[0][i]].first==types[j] ) { found=true; break; }
+     123             :       }
+     124        6906 :       if( !found ) types.push_back( atom_lab[ablocks[0][i]].first );
+     125             :     }
+     126          23 :     ntype=0; nrows=ncols=types.size();
+     127             :   } else {
+     128           1 :     std::vector<unsigned> types(1); types[0]=atom_lab[ablocks[0][0]].first;
+     129           5 :     for(unsigned i=1; i<ablocks[0].size(); ++i) {
+     130             :       bool found = false;
+     131           4 :       for(unsigned j=0; j<types.size(); ++j) {
+     132           4 :         if( atom_lab[ablocks[0][i]].first==types[j] ) { found=true; break; }
+     133             :       }
+     134           4 :       if( !found ) types.push_back( atom_lab[ablocks[0][i]].first );
+     135             :     }
+     136           1 :     nrows=ntype=types.size();
+     137          11 :     for(unsigned i=0; i<ablocks[1].size(); ++i) {
+     138             :       bool found = false;
+     139          10 :       for(unsigned j=0; j<types.size(); ++j) {
+     140          10 :         if( atom_lab[ablocks[1][i]].first==types[j] ) { found=true; break; }
+     141             :       }
+     142          10 :       if( !found ) types.push_back( atom_lab[ablocks[1][i]].first );
+     143             :     }
+     144           1 :     if( types.size()==nrows ) { ntype=0; ncols=1; plumed_assert( types.size()==1 && atom_lab[ablocks[0][0]].first==0 ); }
+     145           0 :     else ncols = types.size() - ntype;
+     146             :   }
+     147          24 : }
+     148             : 
+     149          23 : void AdjacencyMatrixBase::finishMatrixSetup( const bool& symmetric, const std::vector<AtomNumber>& all_atoms ) {
+     150             :   std::string param;
+     151          23 :   if( symmetric && ablocks[0].size()==ablocks[1].size() ) param="SYMMETRIC";
+     152          23 :   if( !symmetric ) {
+     153           4 :     bool usehbonds=( ablocks[0].size()==ablocks[1].size() );
+     154           4 :     if( usehbonds ) {
+     155         138 :       for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     156         134 :         if( ablocks[0][i]!=ablocks[1][i] ) { usehbonds = false; break; }
+     157             :       }
+     158           4 :       if( usehbonds ) param="HBONDS";
+     159             :     }
+     160             :   }
+     161             : 
+     162          46 :   vesselbase::VesselOptions da("","",0,param,this);
+     163          23 :   Keywords keys; AdjacencyMatrixVessel::registerKeywords( keys );
+     164          23 :   vesselbase::VesselOptions da2(da,keys);
+     165             :   auto ves=Tools::make_unique<AdjacencyMatrixVessel>(da2);
+     166          23 :   addVessel( std::move( ves ) );
+     167          23 :   setupMultiColvarBase( all_atoms );
+     168          46 : }
+     169             : 
+     170          13 : void AdjacencyMatrixBase::readMaxTwoSpeciesMatrix( const std::string& key0, const std::string& key1, const std::string& key2, const bool& symmetric ) {
+     171          13 :   std::vector<AtomNumber> all_atoms; readTwoGroups( key0, key1, key2, all_atoms );
+     172          13 :   finishMatrixSetup( symmetric, all_atoms );
+     173          13 : }
+     174             : 
+     175          10 : void AdjacencyMatrixBase::readMaxThreeSpeciesMatrix( const std::string& key0, const std::string& key1, const std::string& key2, const std::string& keym, const bool& symmetric ) {
+     176          10 :   std::vector<AtomNumber> all_atoms; readGroupKeywords( key0, key1, key2, keym, true, symmetric, all_atoms );
+     177          10 :   finishMatrixSetup( symmetric, all_atoms );
+     178          10 : }
+     179             : 
+     180             : // Maybe put this back GAT to check that it is returning an atom number that is one of the nodes
+     181             : // and not a hydrogen if we are doing HBPAMM
+     182             : // AtomNumber AdjacencyMatrixBase::getAbsoluteIndexOfCentralAtom(const unsigned& i) const {
+     183             : //   plumed_dbg_assert( i<myinputdata.getFullNumberOfBaseTasks() );
+     184             : //   return myinputdata.getAtomicIndex( i );
+     185             : // }
+     186             : 
+     187           0 : void AdjacencyMatrixBase::recalculateMatrixElement( const unsigned& myelem, MultiValue& myvals ) {
+     188           0 :   std::vector<unsigned> myatoms; decodeIndexToAtoms( getTaskCode( myelem ), myatoms );
+     189           0 :   unsigned i=myatoms[0], j=myatoms[1];
+     190           0 :   for(unsigned k=bookeeping(i,j).first; k<bookeeping(i,j).second; ++k) {
+     191           0 :     if( !taskIsCurrentlyActive(k) ) continue;
+     192           0 :     performTask( k, getTaskCode(k), myvals );  // This may not accumulate as we would like  GAT
+     193             :   }
+     194           0 : }
+     195             : 
+     196             : }
+     197             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.h.func-sort-c.html b/coverage/adjmat/AdjacencyMatrixBase.h.func-sort-c.html new file mode 100644 index 000000000000..4d90aad172c0 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AdjacencyMatrixBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AdjacencyMatrixBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBase10isPeriodicEv25
_ZNK4PLMD6adjmat19AdjacencyMatrixBase29getAbsoluteIndexOfCentralAtomERKj504
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.h.func.html b/coverage/adjmat/AdjacencyMatrixBase.h.func.html new file mode 100644 index 000000000000..2d44d5b8ded2 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AdjacencyMatrixBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AdjacencyMatrixBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19AdjacencyMatrixBase10isPeriodicEv25
_ZNK4PLMD6adjmat19AdjacencyMatrixBase29getAbsoluteIndexOfCentralAtomERKj504
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html b/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html new file mode 100644 index 000000000000..ef875e2c9fc2 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixBase.h.gcov.html @@ -0,0 +1,182 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AdjacencyMatrixBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AdjacencyMatrixBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_adjmat_AdjacencyMatrixBase_h
+      23             : #define __PLUMED_adjmat_AdjacencyMatrixBase_h
+      24             : 
+      25             : #include "multicolvar/MultiColvarBase.h"
+      26             : #include "AdjacencyMatrixVessel.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace adjmat {
+      30             : 
+      31             : class AdjacencyMatrixBase : public multicolvar::MultiColvarBase {
+      32             :   friend class AdjacencyMatrixVessel;
+      33             :   friend class ActionWithInputMatrix;
+      34             :   friend class MatrixColumnSums;
+      35             :   friend class MatrixRowSums;
+      36             : private:
+      37             : /// Used for read in of multiple connection descriptors
+      38             :   unsigned connect_id;
+      39             : /// Do we need to separate out the tasks for the third atoms
+      40             :   bool no_third_dim_accum;
+      41             : /// This is the vessel that stores the adjacency matrix
+      42             :   AdjacencyMatrixVessel* mat;
+      43             : /// This is used within AdjacencyMatrixVessel to recalculate matrix elements
+      44             : /// which is useful when we are operating with lowmem
+      45             :   void recalculateMatrixElement( const unsigned& myelem, MultiValue& myvals );
+      46             : /// Finish the setup of the matrix
+      47             :   void finishMatrixSetup( const bool& symmetric, const std::vector<AtomNumber>& all_atoms );
+      48             : protected:
+      49             : /// Read in a matrix involving a maximum of two species
+      50             :   void readMaxTwoSpeciesMatrix( const std::string& key0, const std::string& key1, const std::string& key2, const bool& symmetric );
+      51             : /// Read in a matrix involving a maximum of three species
+      52             :   void readMaxThreeSpeciesMatrix( const std::string& key0, const std::string& key1, const std::string& key2, const std::string& keym, const bool& symmetric );
+      53             : /// Get the dimensions of the matrix of types
+      54             :   void retrieveTypeDimensions( unsigned& nrows, unsigned& ncols, unsigned& ntype ) const ;
+      55             : /// Retrieve the vessel that holds the adjacency matrix
+      56             :   AdjacencyMatrixVessel* getAdjacencyVessel();
+      57             : /// Put the indices of the matrix elements in current atoms
+      58             :   void setMatrixIndexesForTask( const unsigned& ii );
+      59             : /// Add derivatives to a matrix element
+      60             :   void addDerivativesOnMatrixElement( const unsigned& ielem, const unsigned& jrow, const double& df, Matrix<double>& der );
+      61             : /// Read in the information on the connectors
+      62             :   void parseConnectionDescriptions( const std::string& key, const bool& multiple, const unsigned& nrow_t );
+      63             : protected:
+      64             : /// Get the number of nodes of different types
+      65             :   unsigned getNumberOfNodeTypes() const ;
+      66             : /// Get the size of the vectors that were stored in the base colvars
+      67             :   unsigned getSizeOfInputVectors() const ;
+      68             : /// Return the group this atom is a part of
+      69             :   unsigned getBaseColvarNumber( const unsigned& ) const ;
+      70             : public:
+      71             :   static void registerKeywords( Keywords& keys );
+      72             :   explicit AdjacencyMatrixBase(const ActionOptions&);
+      73             : /// Create the connection object
+      74             :   virtual void setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) = 0;
+      75             : /// None of these things are allowed
+      76          25 :   bool isPeriodic() { return false; }
+      77             :   Vector getCentralAtom() { plumed_merror("cannot find central atoms for adjacency matrix actions"); }
+      78             : /// Get the atom number
+      79             :   AtomNumber getAbsoluteIndexOfCentralAtom( const unsigned& i ) const ;
+      80             : };
+      81             : 
+      82             : inline
+      83             : AdjacencyMatrixVessel* AdjacencyMatrixBase::getAdjacencyVessel() {
+      84             :   return mat;
+      85             : }
+      86             : 
+      87             : inline
+      88             : unsigned AdjacencyMatrixBase::getBaseColvarNumber( const unsigned& inum ) const {
+      89   224925223 :   if( atom_lab[inum].first>0 ) return atom_lab[inum].first-1;
+      90             :   return 0;
+      91             : }
+      92             : 
+      93             : inline
+      94         504 : AtomNumber AdjacencyMatrixBase::getAbsoluteIndexOfCentralAtom( const unsigned& iatom ) const {
+      95         504 :   if( atom_lab[iatom].first>0 ) {
+      96         156 :     unsigned mmc=atom_lab[ iatom ].first - 1;
+      97         156 :     return mybasemulticolvars[mmc]->getAbsoluteIndexOfCentralAtom( atom_lab[iatom].second );
+      98             :   }
+      99         348 :   return ActionAtomistic::getAbsoluteIndex( atom_lab[iatom].second );
+     100             : }
+     101             : 
+     102             : }
+     103             : }
+     104             : 
+     105             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixVessel.cpp.func-sort-c.html b/coverage/adjmat/AdjacencyMatrixVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..052167e311ac --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixVessel.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AdjacencyMatrixVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AdjacencyMatrixVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717891.0 %
Date:2024-02-22 21:58:45Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel17nodesAreConnectedERKjS3_0
_ZN4PLMD6adjmat21AdjacencyMatrixVessel16retrieveEdgeListERjRSt6vectorISt4pairIjjESaIS5_EE4
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel22getCutoffForConnectionEv8
_ZN4PLMD6adjmat21AdjacencyMatrixVessel14retrieveMatrixERNS_11DynamicListIjEERNS_6MatrixIdEE17
_ZN4PLMD6adjmat21AdjacencyMatrixVessel15getMatrixActionEv17
_ZN4PLMD6adjmat21AdjacencyMatrixVessel16registerKeywordsERNS_8KeywordsE23
_ZN4PLMD6adjmat21AdjacencyMatrixVesselC2ERKNS_10vesselbase13VesselOptionsE23
_ZN4PLMD6adjmat21AdjacencyMatrixVessel22retrieveAdjacencyListsERSt6vectorIjSaIjEERNS_6MatrixIjEE24
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel11isSymmetricEv775
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel15getNumberOfRowsEv1596
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel16getMatrixIndicesERKjRjS4_24491
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel18getNumberOfColumnsEv39153
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel21matrixElementIsActiveERKjS3_47892
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel15undirectedGraphEv72251
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel30getStoreIndexFromMatrixIndicesERKjS3_74692
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixVessel.cpp.func.html b/coverage/adjmat/AdjacencyMatrixVessel.cpp.func.html new file mode 100644 index 000000000000..76a01cd3e09c --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixVessel.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AdjacencyMatrixVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AdjacencyMatrixVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717891.0 %
Date:2024-02-22 21:58:45Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat21AdjacencyMatrixVessel14retrieveMatrixERNS_11DynamicListIjEERNS_6MatrixIdEE17
_ZN4PLMD6adjmat21AdjacencyMatrixVessel15getMatrixActionEv17
_ZN4PLMD6adjmat21AdjacencyMatrixVessel16registerKeywordsERNS_8KeywordsE23
_ZN4PLMD6adjmat21AdjacencyMatrixVessel16retrieveEdgeListERjRSt6vectorISt4pairIjjESaIS5_EE4
_ZN4PLMD6adjmat21AdjacencyMatrixVessel22retrieveAdjacencyListsERSt6vectorIjSaIjEERNS_6MatrixIjEE24
_ZN4PLMD6adjmat21AdjacencyMatrixVesselC2ERKNS_10vesselbase13VesselOptionsE23
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel11isSymmetricEv775
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel15getNumberOfRowsEv1596
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel15undirectedGraphEv72251
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel16getMatrixIndicesERKjRjS4_24491
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel17nodesAreConnectedERKjS3_0
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel18getNumberOfColumnsEv39153
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel21matrixElementIsActiveERKjS3_47892
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel22getCutoffForConnectionEv8
_ZNK4PLMD6adjmat21AdjacencyMatrixVessel30getStoreIndexFromMatrixIndicesERKjS3_74692
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AdjacencyMatrixVessel.cpp.gcov.html b/coverage/adjmat/AdjacencyMatrixVessel.cpp.gcov.html new file mode 100644 index 000000000000..7a80bdb267f0 --- /dev/null +++ b/coverage/adjmat/AdjacencyMatrixVessel.cpp.gcov.html @@ -0,0 +1,231 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AdjacencyMatrixVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AdjacencyMatrixVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717891.0 %
Date:2024-02-22 21:58:45Functions:141593.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AdjacencyMatrixVessel.h"
+      23             : #include "AdjacencyMatrixBase.h"
+      24             : #include "vesselbase/ActionWithVessel.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace adjmat {
+      28             : 
+      29          23 : void AdjacencyMatrixVessel::registerKeywords( Keywords& keys ) {
+      30          23 :   StoreDataVessel::registerKeywords(keys);
+      31          46 :   keys.addFlag("SYMMETRIC",false,"is the matrix symmetric");
+      32          46 :   keys.addFlag("HBONDS",false,"can we think of the matrix as a undirected graph");
+      33          23 : }
+      34             : 
+      35          23 : AdjacencyMatrixVessel::AdjacencyMatrixVessel( const vesselbase::VesselOptions& da ):
+      36          23 :   StoreDataVessel(da)
+      37             : {
+      38          23 :   function=dynamic_cast<AdjacencyMatrixBase*>( getAction() );
+      39          23 :   plumed_assert( function );
+      40          46 :   parseFlag("SYMMETRIC",symmetric); parseFlag("HBONDS",hbonds);
+      41          23 :   if( symmetric && hbonds ) error("matrix should be either symmetric or hbonds");
+      42          23 :   if( symmetric && function->ablocks[0].size()!=function->ablocks[1].size() ) error("matrix is supposed to be symmetric but nrows!=ncols");
+      43          23 :   if( hbonds &&  function->ablocks[0].size()!=function->ablocks[1].size() ) error("matrix is supposed to be hbonds but nrows!=ncols");
+      44          23 : }
+      45             : 
+      46         775 : bool AdjacencyMatrixVessel::isSymmetric() const {
+      47         775 :   return symmetric;
+      48             : }
+      49             : 
+      50       72251 : bool AdjacencyMatrixVessel::undirectedGraph() const {
+      51       72251 :   return ( symmetric || hbonds );
+      52             : }
+      53             : 
+      54        1596 : unsigned AdjacencyMatrixVessel::getNumberOfRows() const {
+      55        1596 :   return function->ablocks[0].size();
+      56             : }
+      57             : 
+      58       39153 : unsigned AdjacencyMatrixVessel::getNumberOfColumns() const {
+      59       39153 :   return function->ablocks[1].size();
+      60             : }
+      61             : 
+      62       47892 : bool AdjacencyMatrixVessel::matrixElementIsActive( const unsigned& ielem, const unsigned& jelem ) const {
+      63       47892 :   return StoreDataVessel::storedValueIsActive( getStoreIndexFromMatrixIndices( ielem, jelem ) );
+      64             : }
+      65             : 
+      66       74692 : unsigned AdjacencyMatrixVessel::getStoreIndexFromMatrixIndices( const unsigned& ielem, const unsigned& jelem ) const {
+      67       74692 :   if( !symmetric && !hbonds ) return (function->ablocks[1].size())*ielem + jelem;
+      68       72692 :   if( !symmetric ) {
+      69             :     plumed_dbg_assert( ielem!=jelem );
+      70       32256 :     if( jelem<ielem ) return (function->ablocks[1].size()-1)*ielem + jelem;
+      71       16128 :     return (function->ablocks[1].size()-1)*ielem + jelem - 1;
+      72             :   }
+      73       40436 :   if( ielem>jelem ) return 0.5*ielem*(ielem-1)+jelem;
+      74       17363 :   return 0.5*jelem*(jelem-1) + ielem;
+      75             : }
+      76             : 
+      77          17 : AdjacencyMatrixBase* AdjacencyMatrixVessel::getMatrixAction() {
+      78          17 :   return function;
+      79             : }
+      80             : 
+      81       24491 : void AdjacencyMatrixVessel::getMatrixIndices( const unsigned& code, unsigned& i, unsigned& j ) const {
+      82       24491 :   std::vector<unsigned> myatoms; function->decodeIndexToAtoms( function->getTaskCode(code), myatoms );
+      83       24491 :   i=myatoms[0]; j=myatoms[1];
+      84       24491 :   if( !undirectedGraph() ) j -= function->ablocks[0].size(); // Have to remove number of columns as returns number in ablocks[1]
+      85       24491 : }
+      86             : 
+      87          17 : void AdjacencyMatrixVessel::retrieveMatrix( DynamicList<unsigned>& myactive_elements, Matrix<double>& mymatrix ) {
+      88          17 :   myactive_elements.deactivateAll(); std::vector<double> vals( getNumberOfComponents() );
+      89        1564 :   for(unsigned i=0; i<getNumberOfStoredValues(); ++i) {
+      90        1547 :     retrieveSequentialValue( i, false, vals );
+      91        1547 :     if( vals[0]<epsilon ) continue ;
+      92             : 
+      93        1547 :     myactive_elements.activate(i);
+      94        1547 :     unsigned j, k; getMatrixIndices( function->getPositionInFullTaskList(i), k, j );
+      95             : 
+      96        1547 :     if( symmetric ) mymatrix(k,j)=mymatrix(j,k)=vals[0]*vals[1];
+      97           0 :     else mymatrix(k,j)=vals[0]*vals[1];
+      98             :   }
+      99          17 :   myactive_elements.updateActiveMembers();
+     100          17 : }
+     101             : 
+     102          24 : void AdjacencyMatrixVessel::retrieveAdjacencyLists( std::vector<unsigned>& nneigh, Matrix<unsigned>& adj_list ) {
+     103             :   plumed_dbg_assert( undirectedGraph() );
+     104             :   // Currently everything has zero neighbors
+     105        8217 :   for(unsigned i=0; i<nneigh.size(); ++i) nneigh[i]=0;
+     106             : 
+     107             :   // And set up the adjacency list
+     108          24 :   std::vector<double> myvals( getNumberOfComponents() );
+     109      214258 :   for(unsigned i=0; i<getNumberOfStoredValues(); ++i) {
+     110             :     // Check if atoms are connected
+     111      214234 :     retrieveSequentialValue( i, false, myvals );
+     112      214234 :     if( myvals[0]<epsilon || myvals[1]<epsilon ) continue ;
+     113             : 
+     114       15013 :     unsigned j, k; getMatrixIndices( function->getPositionInFullTaskList(i), k, j );
+     115             : 
+     116       15013 :     if( nneigh[j]>=adj_list.ncols() || nneigh[k]>=adj_list.ncols() ) error("adjacency lists are not large enough, increase maxconnections");
+     117             :     // Store if atoms are connected
+     118             :     // unsigned j, k; getMatrixIndices( i, k, j );
+     119       15013 :     adj_list(k,nneigh[k])=j; nneigh[k]++;
+     120       15013 :     adj_list(j,nneigh[j])=k; nneigh[j]++;
+     121             :   }
+     122          24 : }
+     123             : 
+     124           4 : void AdjacencyMatrixVessel::retrieveEdgeList( unsigned& nedge, std::vector<std::pair<unsigned,unsigned> >& edge_list ) {
+     125           4 :   plumed_dbg_assert( undirectedGraph() ); nedge=0;
+     126           4 :   std::vector<double> myvals( getNumberOfComponents() );
+     127           4 :   if( getNumberOfStoredValues()>edge_list.size() ) error("adjacency lists are not large enough, increase maxconnections");
+     128             : 
+     129      124576 :   for(unsigned i=0; i<getNumberOfStoredValues(); ++i) {
+     130             :     // Check if atoms are connected
+     131      124572 :     retrieveSequentialValue( i, false, myvals );
+     132      124572 :     if( myvals[0]<epsilon || myvals[1]<epsilon ) continue ;
+     133             : 
+     134        6384 :     getMatrixIndices( function->getPositionInFullTaskList(i), edge_list[nedge].first, edge_list[nedge].second );
+     135        6384 :     nedge++;
+     136             :   }
+     137           4 : }
+     138             : 
+     139           0 : bool AdjacencyMatrixVessel::nodesAreConnected( const unsigned& iatom, const unsigned& jatom ) const {
+     140           0 :   if( !matrixElementIsActive( iatom, jatom ) ) return false;
+     141           0 :   unsigned ind=getStoreIndexFromMatrixIndices( iatom, jatom );
+     142             : 
+     143           0 :   std::vector<double> myvals( getNumberOfComponents() );
+     144           0 :   retrieveValueWithIndex( ind, false, myvals );
+     145           0 :   return ( myvals[0]>epsilon && myvals[1]>epsilon );
+     146             : }
+     147             : 
+     148           8 : double AdjacencyMatrixVessel::getCutoffForConnection() const {
+     149           8 :   return function->getLinkCellCutoff();
+     150             : }
+     151             : 
+     152             : }
+     153             : }
+     154             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AlignedMatrixBase.cpp.func-sort-c.html b/coverage/adjmat/AlignedMatrixBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..1ab4be8755b4 --- /dev/null +++ b/coverage/adjmat/AlignedMatrixBase.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AlignedMatrixBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AlignedMatrixBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:445088.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17AlignedMatrixBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat17AlignedMatrixBaseC2ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat17AlignedMatrixBase14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE2
_ZN4PLMD6adjmat17AlignedMatrixBase16registerKeywordsERNS_8KeywordsE5
_ZNK4PLMD6adjmat17AlignedMatrixBase7computeERKjRNS_11multicolvar13AtomValuePackE5806
_ZNK4PLMD6adjmat17AlignedMatrixBase15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE57063
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AlignedMatrixBase.cpp.func.html b/coverage/adjmat/AlignedMatrixBase.cpp.func.html new file mode 100644 index 000000000000..1d2d764d4604 --- /dev/null +++ b/coverage/adjmat/AlignedMatrixBase.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AlignedMatrixBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AlignedMatrixBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:445088.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17AlignedMatrixBase14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE2
_ZN4PLMD6adjmat17AlignedMatrixBase16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6adjmat17AlignedMatrixBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat17AlignedMatrixBaseC2ERKNS_13ActionOptionsE1
_ZNK4PLMD6adjmat17AlignedMatrixBase15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE57063
_ZNK4PLMD6adjmat17AlignedMatrixBase7computeERKjRNS_11multicolvar13AtomValuePackE5806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/AlignedMatrixBase.cpp.gcov.html b/coverage/adjmat/AlignedMatrixBase.cpp.gcov.html new file mode 100644 index 000000000000..9e34413c1e52 --- /dev/null +++ b/coverage/adjmat/AlignedMatrixBase.cpp.gcov.html @@ -0,0 +1,194 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/AlignedMatrixBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - AlignedMatrixBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:445088.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AlignedMatrixBase.h"
+      23             : #include "multicolvar/AtomValuePack.h"
+      24             : #include "tools/SwitchingFunction.h"
+      25             : #include "tools/Matrix.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace adjmat {
+      29             : 
+      30           5 : void AlignedMatrixBase::registerKeywords( Keywords& keys ) {
+      31           5 :   AdjacencyMatrixBase::registerKeywords( keys );
+      32          10 :   keys.add("atoms","ATOMS","The list of molecules for which you would like to calculate the contact matrix.  The molecules involved must "
+      33             :            "have an orientation so your list will be a list of the labels of \\ref mcolv or \\ref multicolvarfunction "
+      34             :            "as PLUMED calculates the orientations of molecules within these operations.  Please note also that the majority "
+      35             :            "of \\ref mcolv and \\ref multicolvarfunction do not calculate a molecular orientation.");
+      36          10 :   keys.add("atoms-1","ATOMSA","The list of molecules that you would like to use for the rows of the contact matrix.  The molecules involved must "
+      37             :            "have an orientation so your list will be a list of the labels of \\ref mcolv or \\ref multicolvarfunction "
+      38             :            "as PLUMED calculates the orientations of molecules within these operations.  Please note also that the majority "
+      39             :            "of \\ref mcolv and \\ref multicolvarfunction do not calculate a molecular orientation.");
+      40          10 :   keys.add("atoms-1","ATOMSB","The list of molecules that you would like to use for the columns of the contact matrix.  The molecules involved must "
+      41             :            "have an orientation so your list will be a list of the labels of \\ref mcolv or \\ref multicolvarfunction "
+      42             :            "as PLUMED calculates the orientations of molecules within these operations.  Please note also that the majority "
+      43             :            "of \\ref mcolv and \\ref multicolvarfunction do not calculate a molecular orientation.");
+      44          10 :   keys.add("numbered","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      45             :            "The following provides information on the \\ref switchingfunction that are available.");
+      46           5 : }
+      47             : 
+      48           1 : AlignedMatrixBase::AlignedMatrixBase( const ActionOptions& ao ):
+      49             :   Action(ao),
+      50           1 :   AdjacencyMatrixBase(ao)
+      51             : {
+      52             :   // Read in the atomic positions
+      53           2 :   readMaxTwoSpeciesMatrix( "ATOMS", "ATOMSA", "ATOMSB", true );
+      54           1 :   unsigned nrows, ncols; retrieveTypeDimensions( nrows, ncols, ncol_t );
+      55           1 :   if( mybasemulticolvars.size()==0 ) error("cannot use atom indices as input to this variable / input was not specified");
+      56           1 :   if( getSizeOfInputVectors()<3 ) error("base multicolvars do not calculate an orientation");
+      57             :   // Read in the switching function
+      58           1 :   switchingFunction.resize( nrows, ncols );
+      59           2 :   parseConnectionDescriptions("SWITCH",false,ncol_t);
+      60             : 
+      61             :   // Find the largest sf cutoff
+      62           1 :   double sfmax=switchingFunction(0,0).get_dmax();
+      63           2 :   for(unsigned i=0; i<getNumberOfNodeTypes(); ++i) {
+      64           2 :     for(unsigned j=0; j<getNumberOfNodeTypes(); ++j) {
+      65           1 :       double tsf=switchingFunction(i,j).get_dmax();
+      66           1 :       if( tsf>sfmax ) sfmax=tsf;
+      67             :     }
+      68             :   }
+      69             :   // And set the link cell cutoff
+      70           1 :   setLinkCellCutoff( sfmax );
+      71           1 : }
+      72             : 
+      73           2 : void AlignedMatrixBase::setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+      74           2 :   plumed_assert( id<2 );
+      75           2 :   if( id==0 ) {
+      76           1 :     plumed_assert( desc.size()==1 ); std::string errors; switchingFunction(j,i).set(desc[0],errors);
+      77           1 :     if( errors.length()!=0 ) error("problem reading switching function in SWITCH keywrd description " + errors);
+      78           1 :     if( j!=i) switchingFunction(i,j).set(desc[0],errors);
+      79           2 :     log.printf("  %u th and %u th multicolvar groups must be within %s\n",i+1,j+1,(switchingFunction(i,j).description()).c_str() );
+      80           1 :   } else if( id==1 ) {
+      81           1 :     readOrientationConnector( i, j, desc );
+      82             :   }
+      83           2 : }
+      84             : 
+      85       57063 : double AlignedMatrixBase::calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+      86       57063 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+      87      171189 :   if( distance.modulo2()<switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) )-ncol_t ).get_dmax2() ) return 1.0;
+      88             :   return 0.0;
+      89             : }
+      90             : 
+      91        5806 : double AlignedMatrixBase::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+      92        5806 :   unsigned ncomp=getSizeOfInputVectors(); Vector ddistance;
+      93        5806 :   std::vector<double> orient0(ncomp), orient1(ncomp), dorient0(ncomp), dorient1(ncomp);
+      94        5806 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+      95        5806 :   getInputData( 0, true, myatoms, orient0 ); getInputData( 1, true, myatoms, orient1 );
+      96       17418 :   double f_dot = computeVectorFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) )-ncol_t,
+      97             :                                         distance, orient0, orient1, ddistance, dorient0, dorient1 );
+      98             : 
+      99             :   // Retrieve the weight of the connection
+     100       11612 :   double dfunc, sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) )-ncol_t ).calculate( distance.modulo(), dfunc );
+     101             : 
+     102        5806 :   if( !doNotCalculateDerivatives() ) {
+     103           0 :     addAtomDerivatives( 1, 0, (-dfunc)*f_dot*distance - sw*ddistance, myatoms );
+     104           0 :     addAtomDerivatives( 1, 1, (+dfunc)*f_dot*distance + sw*ddistance, myatoms );
+     105           0 :     myatoms.addBoxDerivatives( 1, (-dfunc)*f_dot*Tensor(distance,distance) - sw*extProduct( distance, ddistance ) );
+     106             : 
+     107             :     // Add derivatives of orientation
+     108           0 :     for(unsigned k=2; k<orient0.size(); ++k) { dorient0[k]*=sw; dorient1[k]*=sw; }
+     109           0 :     mergeInputDerivatives( 1, 2, orient0.size(), 0, dorient0, getInputDerivatives( 0, true, myatoms ), myatoms );
+     110           0 :     mergeInputDerivatives( 1, 2, orient1.size(), 1, dorient1, getInputDerivatives( 1, true, myatoms ), myatoms );
+     111             :   }
+     112       11612 :   return sw*f_dot;
+     113             : }
+     114             : 
+     115             : }
+     116             : }
+     117             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.cpp.func-sort-c.html b/coverage/adjmat/ClusterAnalysisBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..a06e84b2ab72 --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterAnalysisBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterAnalysisBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444891.7 %
Date:2024-02-22 21:58:45Functions:121580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19ClusterAnalysisBaseC1ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat19ClusterAnalysisBase12areConnectedERKjS3_0
_ZNK4PLMD6adjmat19ClusterAnalysisBase22getCutoffForConnectionEv0
_ZNK4PLMD6adjmat19ClusterAnalysisBase12nodeIsActiveERKj1
_ZNK4PLMD6adjmat19ClusterAnalysisBase19getNumberOfClustersEv4
_ZN4PLMD6adjmat19ClusterAnalysisBase17turnOnDerivativesEv8
_ZN4PLMD6adjmat19ClusterAnalysisBase10isPeriodicEv11
_ZN4PLMD6adjmat19ClusterAnalysisBaseC2ERKNS_13ActionOptionsE54
_ZN4PLMD6adjmat19ClusterAnalysisBase16registerKeywordsERNS_8KeywordsE62
_ZNK4PLMD6adjmat19ClusterAnalysisBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE66
_ZNK4PLMD6adjmat19ClusterAnalysisBase26getNodePropertyDerivativesERKjRNS_10MultiValueE1604
_ZNK4PLMD6adjmat19ClusterAnalysisBase19getPropertiesOfNodeERKjRSt6vectorIdSaIdEE1801
_ZNK4PLMD6adjmat19ClusterAnalysisBase29getPositionOfAtomForLinkCellsERKj1975
_ZNK4PLMD6adjmat19ClusterAnalysisBase21getNumberOfQuantitiesEv2073
_ZNK4PLMD6adjmat19ClusterAnalysisBase16getNumberOfNodesEv15981876
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.cpp.func.html b/coverage/adjmat/ClusterAnalysisBase.cpp.func.html new file mode 100644 index 000000000000..aff4d5cd8d9c --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterAnalysisBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterAnalysisBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444891.7 %
Date:2024-02-22 21:58:45Functions:121580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19ClusterAnalysisBase10isPeriodicEv11
_ZN4PLMD6adjmat19ClusterAnalysisBase16registerKeywordsERNS_8KeywordsE62
_ZN4PLMD6adjmat19ClusterAnalysisBase17turnOnDerivativesEv8
_ZN4PLMD6adjmat19ClusterAnalysisBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19ClusterAnalysisBaseC2ERKNS_13ActionOptionsE54
_ZNK4PLMD6adjmat19ClusterAnalysisBase12areConnectedERKjS3_0
_ZNK4PLMD6adjmat19ClusterAnalysisBase12nodeIsActiveERKj1
_ZNK4PLMD6adjmat19ClusterAnalysisBase16getNumberOfNodesEv15981876
_ZNK4PLMD6adjmat19ClusterAnalysisBase19getNumberOfClustersEv4
_ZNK4PLMD6adjmat19ClusterAnalysisBase19getPropertiesOfNodeERKjRSt6vectorIdSaIdEE1801
_ZNK4PLMD6adjmat19ClusterAnalysisBase21getNumberOfQuantitiesEv2073
_ZNK4PLMD6adjmat19ClusterAnalysisBase22getCutoffForConnectionEv0
_ZNK4PLMD6adjmat19ClusterAnalysisBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE66
_ZNK4PLMD6adjmat19ClusterAnalysisBase26getNodePropertyDerivativesERKjRNS_10MultiValueE1604
_ZNK4PLMD6adjmat19ClusterAnalysisBase29getPositionOfAtomForLinkCellsERKj1975
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.cpp.gcov.html b/coverage/adjmat/ClusterAnalysisBase.cpp.gcov.html new file mode 100644 index 000000000000..9e1c22ec585e --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.cpp.gcov.html @@ -0,0 +1,183 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterAnalysisBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterAnalysisBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444891.7 %
Date:2024-02-22 21:58:45Functions:121580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ClusterAnalysisBase.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace adjmat {
+      26             : 
+      27          62 : void ClusterAnalysisBase::registerKeywords( Keywords& keys ) {
+      28          62 :   MultiColvarBase::registerKeywords( keys );
+      29         124 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+      30          62 : }
+      31             : 
+      32          54 : ClusterAnalysisBase::ClusterAnalysisBase(const ActionOptions& ao):
+      33             :   Action(ao),
+      34             :   MultiColvarBase(ao),
+      35         108 :   myfvals(0,0),
+      36          54 :   myfatoms( myfvals, this ),
+      37          54 :   myclusters(NULL)
+      38             : {
+      39             :   // This makes these colvars behave appropriately with dump and analysis
+      40          54 :   matsums=usespecies=true; std::vector<AtomNumber> fake_atoms;
+      41             :   // Find what action we are taking the clusters from
+      42         108 :   if( !parseMultiColvarAtomList("CLUSTERS",-1,fake_atoms ) ) error("unable to interpret input CLUSTERS" );
+      43          54 :   if( mybasemulticolvars.size()!=1 ) error("should be exactly one multicolvar input");
+      44          54 :   atom_lab.resize(0); myclusters = dynamic_cast<ClusteringBase*>( mybasemulticolvars[0] );
+      45          54 :   if( !myclusters ) error("input label is not that of a DFS object");
+      46             :   // Setup the atom pack
+      47          54 :   myfatoms.setNumberOfAtoms( myclusters->getNumberOfNodes() );
+      48          54 :   myfvals.getIndices().resize( myclusters->getNumberOfNodes() );
+      49       33703 :   for(unsigned i=0; i<myclusters->getNumberOfNodes(); ++i) myfatoms.setAtomIndex( i, i );
+      50          54 : }
+      51             : 
+      52           8 : void ClusterAnalysisBase::turnOnDerivatives() {
+      53             :   // Check for dubious vessels
+      54          18 :   for(unsigned i=0; i<getNumberOfVessels(); ++i) {
+      55          20 :     if( getPntrToVessel(i)->getName()=="MEAN" ) error("MEAN of cluster is not differentiable");
+      56          20 :     if( getPntrToVessel(i)->getName()=="VMEAN" ) error("VMEAN of cluster is not differentiable");
+      57             :   }
+      58           8 :   MultiColvarBase::turnOnDerivatives();
+      59           8 : }
+      60             : 
+      61        2073 : unsigned ClusterAnalysisBase::getNumberOfQuantities() const {
+      62        2073 :   return myclusters->getNumberOfQuantities();
+      63             : }
+      64             : 
+      65    15981876 : unsigned ClusterAnalysisBase::getNumberOfNodes() const {
+      66    15981876 :   return myclusters->getNumberOfNodes();
+      67             : }
+      68             : 
+      69           4 : unsigned ClusterAnalysisBase::getNumberOfClusters() const {
+      70           4 :   return myclusters->getNumberOfClusters();
+      71             : }
+      72             : 
+      73          11 : bool ClusterAnalysisBase::isPeriodic() {
+      74          11 :   return mybasemulticolvars[0]->isPeriodic();
+      75             : }
+      76             : 
+      77          66 : void ClusterAnalysisBase::retrieveAtomsInCluster( const unsigned& clust, std::vector<unsigned>& myatoms ) const {
+      78          66 :   myclusters->retrieveAtomsInCluster( clust, myatoms );
+      79          66 : }
+      80             : 
+      81           1 : bool ClusterAnalysisBase::nodeIsActive( const unsigned& ind ) const {
+      82           1 :   return myclusters->isCurrentlyActive( ind );
+      83             : }
+      84             : 
+      85        1801 : void ClusterAnalysisBase::getPropertiesOfNode( const unsigned& ind, std::vector<double>& vals ) const {
+      86        1801 :   myclusters->getInputData( ind, false, myfatoms, vals );
+      87        1801 : }
+      88             : 
+      89        1604 : void ClusterAnalysisBase::getNodePropertyDerivatives( const unsigned& ind, MultiValue& myvals ) const {
+      90        1604 :   myvals=myclusters->getInputDerivatives( ind, false, myfatoms );
+      91        1604 : }
+      92             : 
+      93        1975 : Vector ClusterAnalysisBase::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
+      94        1975 :   return myclusters->getPositionOfAtomForLinkCells( iatom );
+      95             : }
+      96             : 
+      97           0 : double ClusterAnalysisBase::getCutoffForConnection() const {
+      98           0 :   return myclusters->getCutoffForConnection();
+      99             : }
+     100             : 
+     101           0 : bool ClusterAnalysisBase::areConnected( const unsigned& ind1, const unsigned& ind2 ) const {
+     102           0 :   return myclusters->areConnected( ind1, ind2 );
+     103             : }
+     104             : 
+     105             : }
+     106             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.h.func-sort-c.html b/coverage/adjmat/ClusterAnalysisBase.h.func-sort-c.html new file mode 100644 index 000000000000..d78365f80e96 --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterAnalysisBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterAnalysisBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat19ClusterAnalysisBase7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.h.func.html b/coverage/adjmat/ClusterAnalysisBase.h.func.html new file mode 100644 index 000000000000..abf8eed631eb --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterAnalysisBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterAnalysisBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD6adjmat19ClusterAnalysisBase7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterAnalysisBase.h.gcov.html b/coverage/adjmat/ClusterAnalysisBase.h.gcov.html new file mode 100644 index 000000000000..98ee4f1100f8 --- /dev/null +++ b/coverage/adjmat/ClusterAnalysisBase.h.gcov.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterAnalysisBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterAnalysisBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_adjmat_ClusterAnalysisBase_h
+      23             : #define __PLUMED_adjmat_ClusterAnalysisBase_h
+      24             : 
+      25             : #include "ClusteringBase.h"
+      26             : #include "multicolvar/MultiColvarBase.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace adjmat {
+      30             : 
+      31             : class ClusterAnalysisBase : public multicolvar::MultiColvarBase {
+      32             : private:
+      33             :   MultiValue myfvals;
+      34             :   multicolvar::AtomValuePack myfatoms;
+      35             :   ClusteringBase* myclusters;
+      36             : protected:
+      37             :   unsigned getNumberOfNodes() const ;
+      38             :   unsigned getNumberOfClusters() const ;
+      39             :   void retrieveAtomsInCluster( const unsigned& clust, std::vector<unsigned>& myatoms ) const ;
+      40             :   bool nodeIsActive( const unsigned& ind ) const ;
+      41             :   double getCutoffForConnection() const ;
+      42             :   bool areConnected( const unsigned& ind1, const unsigned& ind2 ) const ;
+      43             :   void getPropertiesOfNode( const unsigned& ind, std::vector<double>& vals ) const ;
+      44             :   void getNodePropertyDerivatives( const unsigned& ind, MultiValue& myvals ) const ;
+      45             : public:
+      46             :   static void registerKeywords( Keywords& keys );
+      47             :   explicit ClusterAnalysisBase(const ActionOptions&);
+      48             :   unsigned getNumberOfQuantities() const override;
+      49             :   bool isPeriodic() override;
+      50             :   void turnOnDerivatives() override;
+      51             :   void setupActiveTaskSet( std::vector<unsigned>& active_tasks, const std::string& input_label ) {}
+      52             :   Vector getPositionOfAtomForLinkCells( const unsigned& ) const override;
+      53           0 :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const override { plumed_error(); }
+      54             : };
+      55             : 
+      56             : }
+      57             : }
+      58             : #endif
+      59             : 
+      60             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterDiameter.cpp.func-sort-c.html b/coverage/adjmat/ClusterDiameter.cpp.func-sort-c.html new file mode 100644 index 000000000000..68b66367877e --- /dev/null +++ b/coverage/adjmat/ClusterDiameter.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterDiameter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterDiameter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:262892.9 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat15ClusterDiameter17turnOnDerivativesEv0
_ZN4PLMD6adjmat15ClusterDiameterC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat15ClusterDiameter9calculateEv2
_ZN4PLMD6adjmat15ClusterDiameterC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat15ClusterDiameter16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD6adjmat15ClusterDiameter11performTaskERKjS3_RNS_10MultiValueE2016
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterDiameter.cpp.func.html b/coverage/adjmat/ClusterDiameter.cpp.func.html new file mode 100644 index 000000000000..86777a942756 --- /dev/null +++ b/coverage/adjmat/ClusterDiameter.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterDiameter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterDiameter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:262892.9 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat15ClusterDiameter16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat15ClusterDiameter17turnOnDerivativesEv0
_ZN4PLMD6adjmat15ClusterDiameter9calculateEv2
_ZN4PLMD6adjmat15ClusterDiameterC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat15ClusterDiameterC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat15ClusterDiameter11performTaskERKjS3_RNS_10MultiValueE2016
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterDiameter.cpp.gcov.html b/coverage/adjmat/ClusterDiameter.cpp.gcov.html new file mode 100644 index 000000000000..df8a0b17cf00 --- /dev/null +++ b/coverage/adjmat/ClusterDiameter.cpp.gcov.html @@ -0,0 +1,207 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterDiameter.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterDiameter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:262892.9 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ClusterAnalysisBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC CONCOMP CLUSTER_DIAMETER
+      26             : /*
+      27             : Print out the diameter of one of the connected components
+      28             : 
+      29             : As discussed in the section of the manual on \ref contactmatrix a useful tool for developing complex collective variables is the notion of the
+      30             : so called adjacency matrix.  An adjacency matrix is an \f$N \times N\f$ matrix in which the \f$i\f$th, \f$j\f$th element tells you whether
+      31             : or not the \f$i\f$th and \f$j\f$th atoms/molecules from a set of \f$N\f$ atoms/molecules are adjacent or not.  When analyzing these matrix
+      32             : we can treat them as a graph and find connected components using some clustering algorithm.  This action is used in tandem with this form of analysis
+      33             : to output the largest of the distances between the pairs of atoms that are connected together in a particular connected component.  It is important to
+      34             : note that the quantity that is output by this action cannot be differentiated.  As such it cannot be used as a collective variable in a biased simulation.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The following input uses PLUMED to calculate a adjacency matrix that connects a pair of atoms if they both have a coordination number that is greater
+      39             : than 2.0 and if they are within 6.0 nm of each other.  Depth first search clustering is used to find the connected components in this matrix.  The distance
+      40             : between every pair of atoms that are within the largest of the clusters found is then calculated and the largest of these distances is output to a file named
+      41             : colvar.
+      42             : 
+      43             : \plumedfile
+      44             : # Calculate coordination numbers
+      45             : c1: COORDINATIONNUMBER SPECIES=1-512 SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0}
+      46             : # Select coordination numbers that are more than 2.0
+      47             : cf: MFILTER_MORE DATA=c1 SWITCH={RATIONAL D_0=2.0 R_0=0.1} LOWMEM
+      48             : # Build a contact matrix
+      49             : mat: CONTACT_MATRIX ATOMS=cf SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0}
+      50             : # Find largest cluster
+      51             : dfs: DFSCLUSTERING MATRIX=mat
+      52             : clust1: CLUSTER_PROPERTIES CLUSTERS=dfs CLUSTER=1
+      53             : dia: CLUSTER_DIAMETER CLUSTERS=dfs CLUSTER=1
+      54             : PRINT ARG=dia FILE=colvar
+      55             : \endplumedfile
+      56             : 
+      57             : */
+      58             : //+ENDPLUMEDOC
+      59             : 
+      60             : namespace PLMD {
+      61             : namespace adjmat {
+      62             : 
+      63             : class ClusterDiameter : public ClusterAnalysisBase {
+      64             : private:
+      65             : /// The cluster we are looking for
+      66             :   unsigned clustr;
+      67             : public:
+      68             : /// Create manual
+      69             :   static void registerKeywords( Keywords& keys );
+      70             : /// Constructor
+      71             :   explicit ClusterDiameter(const ActionOptions&);
+      72             : ///
+      73             :   void calculate() override;
+      74             : ///
+      75             :   void performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const override;
+      76             : ///
+      77             :   void turnOnDerivatives() override;
+      78             : };
+      79             : 
+      80             : PLUMED_REGISTER_ACTION(ClusterDiameter,"CLUSTER_DIAMETER")
+      81             : 
+      82           4 : void ClusterDiameter::registerKeywords( Keywords& keys ) {
+      83           4 :   ClusterAnalysisBase::registerKeywords( keys );
+      84           8 :   keys.add("compulsory","CLUSTER","1","which cluster would you like to look at 1 is the largest cluster, 2 is the second largest, 3 is the the third largest and so on.");
+      85           4 : }
+      86             : 
+      87           2 : ClusterDiameter::ClusterDiameter(const ActionOptions&ao):
+      88             :   Action(ao),
+      89           2 :   ClusterAnalysisBase(ao)
+      90             : {
+      91             :   // Find out which cluster we want
+      92           2 :   parse("CLUSTER",clustr);
+      93             : 
+      94           2 :   if( clustr<1 ) error("cannot look for a cluster larger than the largest cluster");
+      95           2 :   if( clustr>getNumberOfNodes() ) error("cluster selected is invalid - too few atoms in system");
+      96             : 
+      97             :   // Create the task list
+      98        3994 :   for(unsigned  i=0; i<getNumberOfNodes(); ++i) {
+      99     7972024 :     for(unsigned j=0; j<getNumberOfNodes(); ++j) addTaskToList( i*getNumberOfNodes() + j );
+     100             :   }
+     101             :   // Now create a highest vessel
+     102           4 :   addVessel("HIGHEST", "", -1); std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     103           2 : }
+     104             : 
+     105           0 : void ClusterDiameter::turnOnDerivatives() {
+     106           0 :   error("cannot calculate derivatives of cluster radius.  This quantity is not differentiable");
+     107             : }
+     108             : 
+     109           2 : void ClusterDiameter::calculate() {
+     110             :   // Retrieve the atoms in the largest cluster
+     111           2 :   std::vector<unsigned> myatoms; retrieveAtomsInCluster( clustr, myatoms );
+     112             :   // Activate the relevant tasks
+     113           2 :   deactivateAllTasks();
+     114         128 :   for(unsigned i=1; i<myatoms.size(); ++i) {
+     115        4158 :     for(unsigned j=0; j<i; ++j) taskFlags[ myatoms[i]*getNumberOfNodes() + myatoms[j] ] = 1;
+     116             :   }
+     117           2 :   lockContributors();
+     118             :   // Now do the calculation
+     119           2 :   runAllTasks();
+     120           2 : }
+     121             : 
+     122        2016 : void ClusterDiameter::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     123        2016 :   unsigned iatom=std::floor(current/getNumberOfNodes()), jatom = current - iatom*getNumberOfNodes();
+     124        2016 :   Vector distance=getSeparation( getPosition(iatom), getPosition(jatom) );
+     125        2016 :   double dd = distance.modulo();
+     126             :   myvals.setValue( 0, 1.0 ); myvals.setValue( 1, dd );
+     127        2016 : }
+     128             : 
+     129             : }
+     130             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterDistribution.cpp.func-sort-c.html b/coverage/adjmat/ClusterDistribution.cpp.func-sort-c.html new file mode 100644 index 000000000000..c7904b3466f8 --- /dev/null +++ b/coverage/adjmat/ClusterDistribution.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424887.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19ClusterDistributionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat19ClusterDistribution9calculateEv1
_ZN4PLMD6adjmat19ClusterDistributionC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat19ClusterDistribution16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD6adjmat19ClusterDistribution11performTaskERKjS3_RNS_10MultiValueE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterDistribution.cpp.func.html b/coverage/adjmat/ClusterDistribution.cpp.func.html new file mode 100644 index 000000000000..ffaafd460d01 --- /dev/null +++ b/coverage/adjmat/ClusterDistribution.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424887.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat19ClusterDistribution16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat19ClusterDistribution9calculateEv1
_ZN4PLMD6adjmat19ClusterDistributionC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat19ClusterDistributionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat19ClusterDistribution11performTaskERKjS3_RNS_10MultiValueE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterDistribution.cpp.gcov.html b/coverage/adjmat/ClusterDistribution.cpp.gcov.html new file mode 100644 index 000000000000..3908fcd9b016 --- /dev/null +++ b/coverage/adjmat/ClusterDistribution.cpp.gcov.html @@ -0,0 +1,237 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterDistribution.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424887.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ClusterAnalysisBase.h"
+      23             : #include "AdjacencyMatrixVessel.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/SwitchingFunction.h"
+      26             : 
+      27             : //+PLUMEDOC CONCOMP CLUSTER_DISTRIBUTION
+      28             : /*
+      29             : Calculate functions of the distribution of properties in your connected components.
+      30             : 
+      31             : This collective variable was developed for looking at nucleation phenomena, where you are
+      32             : interested in using studying the behavior of atoms in small aggregates or nuclei.  In these sorts of
+      33             : problems you might be interested in the distribution of the sizes of the clusters in your system.
+      34             : A detailed description of this CV can be found in \cite tribello-clustering.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The input provided below calculates the local q6 Steinhardt parameter on each atom.  The coordination number
+      39             : that atoms with a high value for the local q6 Steinhardt parameter have with other atoms that have a high
+      40             : value for the local q6 Steinhardt parameter is then computed.  A contact matrix is then computed that measures
+      41             : whether atoms atoms \f$i\f$ and \f$j\f$ have a high value for this coordination number and if they are within
+      42             : 3.6 nm of each other.  The connected components of this matrix are then found using a depth first clustering
+      43             : algorithm on the corresponding graph. The number of components in this graph that contain more than 27 atoms is then computed.
+      44             : As discussed in \cite tribello-clustering an input similar to this one was used to analyze the formation of a polycrystal of GeTe from amorphous
+      45             : GeTe.
+      46             : 
+      47             : \plumedfile
+      48             : q6: Q6 SPECIES=1-300 SWITCH={GAUSSIAN D_0=5.29 R_0=0.01 D_MAX=5.3} LOWMEM
+      49             : lq6: LOCAL_Q6 SPECIES=q6 SWITCH={GAUSSIAN D_0=5.29 R_0=0.01 D_MAX=5.3} LOWMEM
+      50             : flq6: MFILTER_MORE DATA=lq6 SWITCH={GAUSSIAN D_0=0.19 R_0=0.01 D_MAX=0.2}
+      51             : cc: COORDINATIONNUMBER SPECIES=flq6 SWITCH={GAUSSIAN D_0=3.59 R_0=0.01 D_MAX=3.6}
+      52             : fcc: MFILTER_MORE DATA=cc SWITCH={GAUSSIAN D_0=5.99 R_0=0.01 D_MAX=6.0}
+      53             : mat: CONTACT_MATRIX ATOMS=fcc SWITCH={GAUSSIAN D_0=3.59 R_0=0.01 D_MAX=3.6}
+      54             : dfs: DFSCLUSTERING MATRIX=mat
+      55             : nclust: CLUSTER_DISTRIBUTION CLUSTERS=dfs TRANSFORM={GAUSSIAN D_0=5.99 R_0=0.01 D_MAX=6.0} MORE_THAN={GAUSSIAN D_0=26.99 R_0=0.01 D_MAX=27}
+      56             : PRINT ARG=nclust.* FILE=colvar
+      57             : \endplumedfile
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : namespace PLMD {
+      63             : namespace adjmat {
+      64             : 
+      65             : class ClusterDistribution : public ClusterAnalysisBase {
+      66             : private:
+      67             :   unsigned nderivatives;
+      68             : ///
+      69             :   bool use_switch, inverse;
+      70             : //
+      71             :   SwitchingFunction sf;
+      72             : public:
+      73             : /// Create manual
+      74             :   static void registerKeywords( Keywords& keys );
+      75             : /// Constructor
+      76             :   explicit ClusterDistribution(const ActionOptions&);
+      77             : /// Do the calculation
+      78             :   void calculate() override;
+      79             : /// We can use ActionWithVessel to run all the calculation
+      80             :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override;
+      81             : };
+      82             : 
+      83             : PLUMED_REGISTER_ACTION(ClusterDistribution,"CLUSTER_DISTRIBUTION")
+      84             : 
+      85           3 : void ClusterDistribution::registerKeywords( Keywords& keys ) {
+      86           3 :   ClusterAnalysisBase::registerKeywords( keys );
+      87           6 :   keys.add("compulsory","TRANSFORM","none","the switching function to use to convert the crystallinity parameter to a number between zero and one");
+      88           6 :   keys.addFlag("INVERSE_TRANSFORM",false,"when TRANSFORM appears alone the input symmetry functions, \\f$x\\f$ are transformed used \\f$1-s(x)\\f$ "
+      89             :                "where \\f$s(x)\\f$ is a switching function.  When this option is used you instead transform using \\f$s(x)\\f$ only.");
+      90           9 :   keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("BETWEEN");
+      91          12 :   keys.use("HISTOGRAM"); keys.use("ALT_MIN"); keys.use("MIN"); keys.use("MAX");
+      92           3 : }
+      93             : 
+      94           1 : ClusterDistribution::ClusterDistribution(const ActionOptions&ao):
+      95             :   Action(ao),
+      96             :   ClusterAnalysisBase(ao),
+      97           1 :   nderivatives(0)
+      98             : {
+      99           1 :   use_switch=false;
+     100           2 :   std::string input, errors; parse("TRANSFORM",input);
+     101           1 :   if( input!="none" ) {
+     102           0 :     use_switch=true; sf.set( input, errors );
+     103           0 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     104             :   }
+     105           1 :   parseFlag("INVERSE_TRANSFORM",inverse);
+     106           1 :   if( inverse && !use_switch ) error("INVERSE_TRANSFORM option was specified but no TRANSOFRM switching function was given");
+     107             : 
+     108             :   // Create all tasks by copying those from underlying DFS object (which is actually MultiColvar)
+     109           7 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) addTaskToList(i);
+     110             : 
+     111             :   // And now finish the setup of everything in the base
+     112           1 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     113           1 : }
+     114             : 
+     115           1 : void ClusterDistribution::calculate() {
+     116             :   // Activate the relevant tasks
+     117           1 :   nderivatives = getNumberOfDerivatives();
+     118           1 :   deactivateAllTasks();
+     119           4 :   for(unsigned i=0; i<getNumberOfClusters(); ++i) taskFlags[i]=1;
+     120           1 :   lockContributors();
+     121             :   // Now do the calculation
+     122           1 :   runAllTasks();
+     123           1 : }
+     124             : 
+     125           3 : void ClusterDistribution::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     126           3 :   std::vector<unsigned> myatoms; retrieveAtomsInCluster( current+1, myatoms );
+     127             :   // This deals with filters
+     128           3 :   if( myatoms.size()==1 && !nodeIsActive(myatoms[0]) ) return ;
+     129             : 
+     130           3 :   std::vector<double> vals( getNumberOfQuantities() );
+     131           3 :   MultiValue tvals( getNumberOfQuantities(), nderivatives );
+     132             : 
+     133             :   // And this builds everything for this particular atom
+     134             :   double vv, df, tval=0;
+     135           9 :   for(unsigned j=0; j<myatoms.size(); ++j) {
+     136           6 :     unsigned i=myatoms[j];
+     137           6 :     getPropertiesOfNode( i, vals );
+     138           6 :     if( use_switch && !inverse ) {
+     139           0 :       vv = 1.0 - sf.calculate( vals[1], df );
+     140           0 :       tval += vals[0]*vv; df=-df*vals[1];
+     141           6 :     } else if( use_switch ) {
+     142           0 :       vv = sf.calculate( vals[1], df );
+     143           0 :       tval += vals[0]*vv; df=df*vals[1];
+     144             :     } else {
+     145           6 :       tval += vals[0]*vals[1]; df=1.; vv=vals[1];
+     146             :     }
+     147           6 :     if( !doNotCalculateDerivatives() ) {
+     148           6 :       getNodePropertyDerivatives( i, tvals );
+     149         168 :       for(unsigned k=0; k<tvals.getNumberActive(); ++k) {
+     150         162 :         unsigned kat=tvals.getActiveIndex(k);
+     151         162 :         myvals.addDerivative( 1, kat, vals[0]*df*tvals.getDerivative(1,kat) + vv*tvals.getDerivative(0,kat) );
+     152             :       }
+     153           6 :       tvals.clearAll();
+     154             :     }
+     155             :   }
+     156             :   myvals.setValue( 0, 1.0 ); myvals.setValue( 1, tval );
+     157           3 : }
+     158             : 
+     159             : }
+     160             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterProperties.cpp.func-sort-c.html b/coverage/adjmat/ClusterProperties.cpp.func-sort-c.html new file mode 100644 index 000000000000..dac706533131 --- /dev/null +++ b/coverage/adjmat/ClusterProperties.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterProperties.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterProperties.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17ClusterPropertiesC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat17ClusterPropertiesC1ERKNS_13ActionOptionsE27
_ZN4PLMD6adjmat17ClusterProperties16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD6adjmat17ClusterProperties9calculateEv34
_ZNK4PLMD6adjmat17ClusterProperties11performTaskERKjS3_RNS_10MultiValueE1795
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterProperties.cpp.func.html b/coverage/adjmat/ClusterProperties.cpp.func.html new file mode 100644 index 000000000000..ac0671428d4a --- /dev/null +++ b/coverage/adjmat/ClusterProperties.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterProperties.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterProperties.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat17ClusterProperties16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD6adjmat17ClusterProperties9calculateEv34
_ZN4PLMD6adjmat17ClusterPropertiesC1ERKNS_13ActionOptionsE27
_ZN4PLMD6adjmat17ClusterPropertiesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat17ClusterProperties11performTaskERKjS3_RNS_10MultiValueE1795
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterProperties.cpp.gcov.html b/coverage/adjmat/ClusterProperties.cpp.gcov.html new file mode 100644 index 000000000000..1dd95fce2eee --- /dev/null +++ b/coverage/adjmat/ClusterProperties.cpp.gcov.html @@ -0,0 +1,198 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterProperties.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterProperties.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ClusterAnalysisBase.h"
+      23             : #include "AdjacencyMatrixVessel.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : //+PLUMEDOC CONCOMP CLUSTER_PROPERTIES
+      27             : /*
+      28             : Calculate properties of the distribution of some quantities that are part of a connected component
+      29             : 
+      30             : This collective variable was developed for looking at nucleation phenomena, where you are
+      31             : interested in using studying the behavior of atoms in small aggregates or nuclei.  In these sorts of
+      32             : problems you might be interested in the degree the atoms in a nucleus have adopted their crystalline
+      33             : structure or (in the case of heterogeneous nucleation of a solute from a solvent) you might be
+      34             : interested in how many atoms are present in the largest cluster \cite tribello-clustering.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The input below calculates the coordination numbers of atoms 1-100 and then computes the an adjacency
+      39             : matrix whose elements measures whether atoms \f$i\f$ and \f$j\f$ are within 0.55 nm of each other.  The action
+      40             : labelled dfs then treats the elements of this matrix as zero or ones and thus thinks of the matrix as defining
+      41             : a graph.  This dfs action then finds the largest connected component in this graph.  The sum of the coordination
+      42             : numbers for the atoms in this largest connected component are then computed and this quantity is output to a colvar
+      43             : file.  The way this input can be used is described in detail in \cite tribello-clustering.
+      44             : 
+      45             : \plumedfile
+      46             : lq: COORDINATIONNUMBER SPECIES=1-100 SWITCH={CUBIC D_0=0.45  D_MAX=0.55} LOWMEM
+      47             : cm: CONTACT_MATRIX ATOMS=lq  SWITCH={CUBIC D_0=0.45  D_MAX=0.55}
+      48             : dfs: DFSCLUSTERING MATRIX=cm
+      49             : clust1: CLUSTER_PROPERTIES CLUSTERS=dfs CLUSTER=1 SUM
+      50             : PRINT ARG=clust1.* FILE=colvar
+      51             : \endplumedfile
+      52             : 
+      53             : */
+      54             : //+ENDPLUMEDOC
+      55             : 
+      56             : namespace PLMD {
+      57             : namespace adjmat {
+      58             : 
+      59             : class ClusterProperties : public ClusterAnalysisBase {
+      60             : private:
+      61             : /// The cluster we are looking for
+      62             :   unsigned clustr;
+      63             : public:
+      64             : /// Create manual
+      65             :   static void registerKeywords( Keywords& keys );
+      66             : /// Constructor
+      67             :   explicit ClusterProperties(const ActionOptions&);
+      68             : /// Do the calculation
+      69             :   void calculate() override;
+      70             : /// We can use ActionWithVessel to run all the calculation
+      71             :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override;
+      72             : };
+      73             : 
+      74             : PLUMED_REGISTER_ACTION(ClusterProperties,"CLUSTER_PROPERTIES")
+      75             : 
+      76          29 : void ClusterProperties::registerKeywords( Keywords& keys ) {
+      77          29 :   ClusterAnalysisBase::registerKeywords( keys );
+      78          58 :   keys.add("compulsory","CLUSTER","1","which cluster would you like to look at 1 is the largest cluster, 2 is the second largest, 3 is the the third largest and so on.");
+      79          87 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN");
+      80          87 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+      81          87 :   if( keys.reserved("VSUM") ) keys.use("VSUM");
+      82         116 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS"); keys.use("ALT_MIN");
+      83         145 :   keys.use("MIN"); keys.use("MAX"); keys.use("SUM"); keys.use("LOWEST"); keys.use("HIGHEST");
+      84          29 : }
+      85             : 
+      86          27 : ClusterProperties::ClusterProperties(const ActionOptions&ao):
+      87             :   Action(ao),
+      88          27 :   ClusterAnalysisBase(ao)
+      89             : {
+      90             :   // Find out which cluster we want
+      91          27 :   parse("CLUSTER",clustr);
+      92             : 
+      93          27 :   if( clustr<1 ) error("cannot look for a cluster larger than the largest cluster");
+      94          27 :   if( clustr>getNumberOfNodes() ) error("cluster selected is invalid - too few atoms in system");
+      95             : 
+      96             :   // Create all tasks by copying those from underlying DFS object (which is actually MultiColvar)
+      97       18214 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) addTaskToList(i);
+      98             : 
+      99             :   // And now finish the setup of everything in the base
+     100          27 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     101          27 : }
+     102             : 
+     103          34 : void ClusterProperties::calculate() {
+     104             :   // Retrieve the atoms in the largest cluster
+     105          34 :   std::vector<unsigned> myatoms; retrieveAtomsInCluster( clustr, myatoms );
+     106             :   // Activate the relevant tasks
+     107          34 :   deactivateAllTasks();
+     108        1373 :   for(unsigned i=0; i<myatoms.size(); ++i) taskFlags[myatoms[i]]=1;
+     109          34 :   lockContributors();
+     110             :   // Now do the calculation
+     111          34 :   runAllTasks();
+     112          34 : }
+     113             : 
+     114        1795 : void ClusterProperties::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     115        1795 :   std::vector<double> vals( myvals.getNumberOfValues() ); getPropertiesOfNode( current, vals );
+     116        1795 :   if( !doNotCalculateDerivatives() ) getNodePropertyDerivatives( current, myvals );
+     117        5385 :   for(unsigned k=0; k<vals.size(); ++k) myvals.setValue( k, vals[k] );
+     118        1795 : }
+     119             : 
+     120             : }
+     121             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterSize.cpp.func-sort-c.html b/coverage/adjmat/ClusterSize.cpp.func-sort-c.html new file mode 100644 index 000000000000..fa85ddb9571c --- /dev/null +++ b/coverage/adjmat/ClusterSize.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterSize.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterSize.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:161984.2 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11ClusterSize17turnOnDerivativesEv0
_ZN4PLMD6adjmat11ClusterSizeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat11ClusterSize11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD6adjmat11ClusterSizeC1ERKNS_13ActionOptionsE24
_ZN4PLMD6adjmat11ClusterSize16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD6adjmat11ClusterSize9calculateEv27
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterSize.cpp.func.html b/coverage/adjmat/ClusterSize.cpp.func.html new file mode 100644 index 000000000000..628c6c589808 --- /dev/null +++ b/coverage/adjmat/ClusterSize.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterSize.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterSize.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:161984.2 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11ClusterSize16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD6adjmat11ClusterSize17turnOnDerivativesEv0
_ZN4PLMD6adjmat11ClusterSize9calculateEv27
_ZN4PLMD6adjmat11ClusterSizeC1ERKNS_13ActionOptionsE24
_ZN4PLMD6adjmat11ClusterSizeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat11ClusterSize11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterSize.cpp.gcov.html b/coverage/adjmat/ClusterSize.cpp.gcov.html new file mode 100644 index 000000000000..ef747b7acd28 --- /dev/null +++ b/coverage/adjmat/ClusterSize.cpp.gcov.html @@ -0,0 +1,190 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterSize.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterSize.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:161984.2 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ClusterAnalysisBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC CONCOMP CLUSTER_NATOMS
+      26             : /*
+      27             : Gives the number of atoms in the connected component
+      28             : 
+      29             : As discussed in the section of the manual on \ref contactmatrix a useful tool for developing complex collective variables is the notion of the
+      30             : so called adjacency matrix.  An adjacency matrix is an \f$N \times N\f$ matrix in which the \f$i\f$th, \f$j\f$th element tells you whether
+      31             : or not the \f$i\f$th and \f$j\f$th atoms/molecules from a set of \f$N\f$ atoms/molecules are adjacent or not.  When analyzing these matrix
+      32             : we can treat them as a graph and find connected components using some clustering algorithm.  This action is used in tandem with this form of analysis
+      33             : to output the number of atoms that are connected together in a particular connected component.  It is important to note that the quantity that is
+      34             : output by this action cannot be differentiated.  As such it cannot be used as a collective variable in a biased simulation.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The following input uses PLUMED to calculate a adjacency matrix that connects a pair of atoms if they both have a coordination number that is greater
+      39             : than 2.0 and if they are within 6.0 nm of each other.  Depth first search clustering is used to find the connected components in this matrix and then
+      40             : the number of atoms in the largest cluster is found.  This quantity is then output to a file called colvar
+      41             : 
+      42             : \plumedfile
+      43             : # Calculate coordination numbers
+      44             : c1: COORDINATIONNUMBER SPECIES=1-512 SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0}
+      45             : # Select coordination numbers that are more than 2.0
+      46             : cf: MFILTER_MORE DATA=c1 SWITCH={RATIONAL D_0=2.0 R_0=0.1} LOWMEM
+      47             : # Build a contact matrix
+      48             : mat: CONTACT_MATRIX ATOMS=cf SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0}
+      49             : # Find largest cluster
+      50             : dfs: DFSCLUSTERING MATRIX=mat
+      51             : clust1: CLUSTER_PROPERTIES CLUSTERS=dfs CLUSTER=1
+      52             : nat: CLUSTER_NATOMS CLUSTERS=dfs CLUSTER=1
+      53             : PRINT ARG=nat FILE=COLVAR
+      54             : \endplumedfile
+      55             : 
+      56             : */
+      57             : //+ENDPLUMEDOC
+      58             : 
+      59             : namespace PLMD {
+      60             : namespace adjmat {
+      61             : 
+      62             : class ClusterSize : public ClusterAnalysisBase {
+      63             : private:
+      64             : /// The cluster we are looking for
+      65             :   unsigned clustr;
+      66             : public:
+      67             : /// Create manual
+      68             :   static void registerKeywords( Keywords& keys );
+      69             : /// Constructor
+      70             :   explicit ClusterSize(const ActionOptions&);
+      71             : ///
+      72             :   void calculate() override;
+      73             : ///
+      74           0 :   void performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const override { plumed_error(); }
+      75             : ///
+      76             :   void turnOnDerivatives() override;
+      77             : };
+      78             : 
+      79             : PLUMED_REGISTER_ACTION(ClusterSize,"CLUSTER_NATOMS")
+      80             : 
+      81          26 : void ClusterSize::registerKeywords( Keywords& keys ) {
+      82          26 :   ClusterAnalysisBase::registerKeywords( keys );
+      83          52 :   keys.add("compulsory","CLUSTER","1","which cluster would you like to look at 1 is the largest cluster, 2 is the second largest, 3 is the the third largest and so on.");
+      84          26 : }
+      85             : 
+      86          24 : ClusterSize::ClusterSize(const ActionOptions&ao):
+      87             :   Action(ao),
+      88          24 :   ClusterAnalysisBase(ao)
+      89             : {
+      90             :   // Find out which cluster we want
+      91          24 :   parse("CLUSTER",clustr);
+      92             : 
+      93          24 :   if( clustr<1 ) error("cannot look for a cluster larger than the largest cluster");
+      94          24 :   if( clustr>getNumberOfNodes() ) error("cluster selected is invalid - too few atoms in system");
+      95             : 
+      96             :   // Create all tasks by copying those from underlying DFS object (which is actually MultiColvar)
+      97       11488 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) addTaskToList(i);
+      98             :   // And now finish the setup of everything in the base
+      99          24 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     100          48 :   addValue(); setNotPeriodic();
+     101          24 : }
+     102             : 
+     103           0 : void ClusterSize::turnOnDerivatives() {
+     104           0 :   error("cannot calculate derivatives of number of atoms in cluster.  This quantity is not differentiable");
+     105             : }
+     106             : 
+     107          27 : void ClusterSize::calculate() {
+     108             :   // Retrieve the atoms in the largest cluster
+     109          27 :   std::vector<unsigned> myatoms; retrieveAtomsInCluster( clustr, myatoms ); setValue( myatoms.size() );
+     110          27 : }
+     111             : 
+     112             : }
+     113             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterWithSurface.cpp.func-sort-c.html b/coverage/adjmat/ClusterWithSurface.cpp.func-sort-c.html new file mode 100644 index 000000000000..b9013978f4d6 --- /dev/null +++ b/coverage/adjmat/ClusterWithSurface.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterWithSurface.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterWithSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485685.7 %
Date:2024-02-22 21:58:45Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat18ClusterWithSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat18ClusterWithSurface12getInputDataERKjRKbRKNS_11multicolvar13AtomValuePackERSt6vectorIdSaIdEE0
_ZNK4PLMD6adjmat18ClusterWithSurface19getInputDerivativesERKjRKbRKNS_11multicolvar13AtomValuePackE0
_ZNK4PLMD6adjmat18ClusterWithSurface29getPositionOfAtomForLinkCellsERKj0
_ZN4PLMD6adjmat18ClusterWithSurface17performClusteringEv2
_ZN4PLMD6adjmat18ClusterWithSurfaceC1ERKNS_13ActionOptionsE2
_ZNK4PLMD6adjmat18ClusterWithSurface22getCutoffForConnectionEv2
_ZN4PLMD6adjmat18ClusterWithSurface16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat18ClusterWithSurface22getNumberOfDerivativesEv4
_ZNK4PLMD6adjmat18ClusterWithSurface22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE6
_ZNK4PLMD6adjmat18ClusterWithSurface21getNumberOfQuantitiesEv14
_ZNK4PLMD6adjmat18ClusterWithSurface29getAbsoluteIndexOfCentralAtomERKj128
_ZNK4PLMD6adjmat18ClusterWithSurface16getNumberOfNodesEv16155834
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterWithSurface.cpp.func.html b/coverage/adjmat/ClusterWithSurface.cpp.func.html new file mode 100644 index 000000000000..87c0d4c5f3d2 --- /dev/null +++ b/coverage/adjmat/ClusterWithSurface.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterWithSurface.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterWithSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485685.7 %
Date:2024-02-22 21:58:45Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat18ClusterWithSurface16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat18ClusterWithSurface17performClusteringEv2
_ZN4PLMD6adjmat18ClusterWithSurface22getNumberOfDerivativesEv4
_ZN4PLMD6adjmat18ClusterWithSurfaceC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat18ClusterWithSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat18ClusterWithSurface12getInputDataERKjRKbRKNS_11multicolvar13AtomValuePackERSt6vectorIdSaIdEE0
_ZNK4PLMD6adjmat18ClusterWithSurface16getNumberOfNodesEv16155834
_ZNK4PLMD6adjmat18ClusterWithSurface19getInputDerivativesERKjRKbRKNS_11multicolvar13AtomValuePackE0
_ZNK4PLMD6adjmat18ClusterWithSurface21getNumberOfQuantitiesEv14
_ZNK4PLMD6adjmat18ClusterWithSurface22getCutoffForConnectionEv2
_ZNK4PLMD6adjmat18ClusterWithSurface22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE6
_ZNK4PLMD6adjmat18ClusterWithSurface29getAbsoluteIndexOfCentralAtomERKj128
_ZNK4PLMD6adjmat18ClusterWithSurface29getPositionOfAtomForLinkCellsERKj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusterWithSurface.cpp.gcov.html b/coverage/adjmat/ClusterWithSurface.cpp.gcov.html new file mode 100644 index 000000000000..133e12c4d7fa --- /dev/null +++ b/coverage/adjmat/ClusterWithSurface.cpp.gcov.html @@ -0,0 +1,270 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusterWithSurface.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusterWithSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485685.7 %
Date:2024-02-22 21:58:45Functions:91369.2 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ClusteringBase.h"
+      23             : #include "AdjacencyMatrixVessel.h"
+      24             : #include "AdjacencyMatrixBase.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : //+PLUMEDOC MATRIXF CLUSTER_WITHSURFACE
+      28             : /*
+      29             : Take a connected component that was found using a clustering algorithm and create a new cluster that contains those atoms that are in the cluster together with those atoms that are within a certain cutoff of the cluster.
+      30             : 
+      31             : As discussed in the section of the manual on \ref contactmatrix a useful tool for developing complex collective variables is the notion of the
+      32             : so called adjacency matrix.  An adjacency matrix is an \f$N \times N\f$ matrix in which the \f$i\f$th, \f$j\f$th element tells you whether
+      33             : or not the \f$i\f$th and \f$j\f$th atoms/molecules from a set of \f$N\f$ atoms/molecules are adjacent or not.  When analyzing these matrix
+      34             : we can treat them as a graph and find connected components using some clustering algorithm.  This action is used in tandem with this form of analysis
+      35             : and takes one of the connected components that was found during this analysis and creates a new cluster that includes all the atoms within the
+      36             : connected component that was found together that were within a certain cutoff distance of the atoms in the connected component.  This form of analysis
+      37             : has been used successfully in the forward flux sampling simulations described in this paper \cite gab-ice-kaolinite
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : The following input uses PLUMED to calculate a adjacency matrix that connects a pair of atoms if they both have a coordination number that is less
+      42             : than 13.5 and if they are within 0.38 nm of each other.  Depth first search clustering is used to find the connected components in this matrix.  The
+      43             : number of atoms with indices that are between 1 and 1996 and that are either in the second largest cluster or that are within within 0.3 nm of one of the
+      44             : atoms within the the second largest cluster are then counted and this number of atoms is output to a file called size.  In addition the indices of the atoms
+      45             : that were counted are output to a file called dfs2.dat.
+      46             : 
+      47             : \plumedfile
+      48             : c1: COORDINATIONNUMBER SPECIES=1-1996 SWITCH={CUBIC D_0=0.34 D_MAX=0.38}
+      49             : cf: MFILTER_LESS DATA=c1 SWITCH={CUBIC D_0=13 D_MAX=13.5}
+      50             : mat: CONTACT_MATRIX ATOMS=cf SWITCH={CUBIC D_0=0.34 D_MAX=0.38}
+      51             : dfs: DFSCLUSTERING MATRIX=mat
+      52             : clust2a: CLUSTER_WITHSURFACE CLUSTERS=dfs RCUT_SURF=0.3
+      53             : size2a: CLUSTER_NATOMS CLUSTERS=clust2a CLUSTER=2
+      54             : PRINT ARG=size2a FILE=size FMT=%8.4f
+      55             : OUTPUT_CLUSTER CLUSTERS=clust2a CLUSTER=2 FILE=dfs2.dat
+      56             : \endplumedfile
+      57             : 
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : namespace PLMD {
+      63             : namespace adjmat {
+      64             : 
+      65             : class ClusterWithSurface : public ClusteringBase {
+      66             : private:
+      67             : /// The clusters that we are adding surface atoms to
+      68             :   ClusteringBase* myclusters;
+      69             : /// The cutoff for surface atoms
+      70             :   double rcut_surf2;
+      71             : public:
+      72             : /// Create manual
+      73             :   static void registerKeywords( Keywords& keys );
+      74             : /// Constructor
+      75             :   explicit ClusterWithSurface(const ActionOptions&);
+      76             : ///
+      77             :   unsigned getNumberOfDerivatives() override;
+      78             : ///
+      79             :   unsigned getNumberOfNodes() const override;
+      80             : ///
+      81             :   AtomNumber getAbsoluteIndexOfCentralAtom(const unsigned& i) const override;
+      82             : ///
+      83             :   void retrieveAtomsInCluster( const unsigned& clust, std::vector<unsigned>& myatoms ) const override;
+      84             : ///
+      85             :   void getInputData( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms, std::vector<double>& orient0 ) const override;
+      86             : ///
+      87             :   MultiValue& getInputDerivatives( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const override;
+      88             : ///
+      89             :   unsigned getNumberOfQuantities() const override;
+      90             : /// Do the calculation
+      91           2 :   void performClustering() override {};
+      92             : ///
+      93             :   double  getCutoffForConnection() const override;
+      94             : ///
+      95             :   Vector getPositionOfAtomForLinkCells( const unsigned& taskIndex ) const override;
+      96             : };
+      97             : 
+      98             : PLUMED_REGISTER_ACTION(ClusterWithSurface,"CLUSTER_WITHSURFACE")
+      99             : 
+     100           4 : void ClusterWithSurface::registerKeywords( Keywords& keys ) {
+     101           4 :   ClusteringBase::registerKeywords( keys );
+     102           4 :   keys.remove("MATRIX");
+     103           8 :   keys.add("compulsory","CLUSTERS","the label of the action that does the clustering");
+     104           8 :   keys.add("compulsory","RCUT_SURF","you also have the option to find the atoms on the surface of the cluster.  An atom must be within this distance of one of the atoms "
+     105             :            "of the cluster in order to be considered a surface atom");
+     106           4 : }
+     107             : 
+     108           2 : ClusterWithSurface::ClusterWithSurface(const ActionOptions&ao):
+     109             :   Action(ao),
+     110           2 :   ClusteringBase(ao)
+     111             : {
+     112             :   std::vector<AtomNumber> fake_atoms;
+     113           4 :   if( !parseMultiColvarAtomList("CLUSTERS",-1,fake_atoms ) ) error("unable to find CLUSTERS input");
+     114           2 :   if( mybasemulticolvars.size()!=1 ) error("should be exactly one multicolvar input");
+     115             : 
+     116             :   // Retrieve the adjacency matrix of interest
+     117           2 :   atom_lab.resize(0); myclusters = dynamic_cast<ClusteringBase*>( mybasemulticolvars[0] );
+     118           2 :   if( !myclusters ) error( mybasemulticolvars[0]->getLabel() + " does not calculate clusters");
+     119             : 
+     120             :   // Setup switching function for surface atoms
+     121           2 :   double rcut_surf; parse("RCUT_SURF",rcut_surf);
+     122           2 :   if( rcut_surf>0 ) log.printf("  counting surface atoms that are within %f of the cluster atoms \n",rcut_surf);
+     123           2 :   rcut_surf2=rcut_surf*rcut_surf;
+     124             : 
+     125             :   // And now finish the setup of everything in the base
+     126           2 :   setupMultiColvarBase( fake_atoms );
+     127           2 : }
+     128             : 
+     129           4 : unsigned ClusterWithSurface::getNumberOfDerivatives() {
+     130           4 :   return myclusters->getNumberOfDerivatives();
+     131             : }
+     132             : 
+     133    16155834 : unsigned ClusterWithSurface::getNumberOfNodes() const {
+     134    16155834 :   return myclusters->getNumberOfNodes();
+     135             : }
+     136             : 
+     137         128 : AtomNumber ClusterWithSurface::getAbsoluteIndexOfCentralAtom(const unsigned& i) const {
+     138         128 :   return myclusters->getAbsoluteIndexOfCentralAtom(i);
+     139             : }
+     140             : 
+     141           0 : void ClusterWithSurface::getInputData( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms, std::vector<double>& orient0 ) const {
+     142           0 :   myclusters->getInputData( ind, normed, myatoms, orient0 );
+     143           0 : }
+     144             : 
+     145           0 : MultiValue& ClusterWithSurface::getInputDerivatives( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const {
+     146           0 :   return myclusters->getInputDerivatives( ind, normed, myatoms );
+     147             : }
+     148             : 
+     149          14 : unsigned ClusterWithSurface::getNumberOfQuantities() const {
+     150          14 :   return myclusters->getNumberOfQuantities();
+     151             : }
+     152             : 
+     153           2 : double  ClusterWithSurface::getCutoffForConnection() const {
+     154           2 :   double tcut = myclusters->getCutoffForConnection();
+     155           2 :   if( tcut>std::sqrt(rcut_surf2) ) return tcut;
+     156           0 :   return std::sqrt(rcut_surf2);
+     157             : }
+     158             : 
+     159           6 : void ClusterWithSurface::retrieveAtomsInCluster( const unsigned& clust, std::vector<unsigned>& myatoms ) const {
+     160           6 :   std::vector<unsigned> tmpat; myclusters->retrieveAtomsInCluster( clust, tmpat );
+     161             : 
+     162             :   // Prevent double counting
+     163           6 :   std::vector<bool> incluster( getNumberOfNodes(), false );
+     164          90 :   for(unsigned i=0; i<tmpat.size(); ++i) incluster[tmpat[i]]=true;
+     165             : 
+     166             :   // Find the atoms in the the clusters
+     167           6 :   std::vector<bool> surface_atom( getNumberOfNodes(), false );
+     168          90 :   for(unsigned i=0; i<tmpat.size(); ++i) {
+     169      167748 :     for(unsigned j=0; j<getNumberOfNodes(); ++j) {
+     170      167664 :       if( incluster[j] ) continue;
+     171      166488 :       double dist2=getSeparation( getPosition(tmpat[i]), getPosition(j) ).modulo2();
+     172      166488 :       if( dist2<rcut_surf2 ) { surface_atom[j]=true; }
+     173             :     }
+     174             :   }
+     175             :   unsigned nsurf_at=0;
+     176       11982 :   for(unsigned j=0; j<getNumberOfNodes(); ++j) {
+     177       11976 :     if( surface_atom[j] ) nsurf_at++;
+     178             :   }
+     179           6 :   myatoms.resize( nsurf_at + tmpat.size() );
+     180          90 :   for(unsigned i=0; i<tmpat.size(); ++i) myatoms[i]=tmpat[i];
+     181           6 :   unsigned nn=tmpat.size();
+     182       11982 :   for(unsigned j=0; j<getNumberOfNodes(); ++j) {
+     183       11976 :     if( surface_atom[j] ) { myatoms[nn]=j; nn++; }
+     184             :   }
+     185           6 :   plumed_assert( nn==myatoms.size() );
+     186           6 : }
+     187             : 
+     188           0 : Vector ClusterWithSurface::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
+     189           0 :   return myclusters->getPositionOfAtomForLinkCells( iatom );
+     190             : }
+     191             : 
+     192             : }
+     193             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.cpp.func-sort-c.html b/coverage/adjmat/ClusteringBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..1804a2b49a40 --- /dev/null +++ b/coverage/adjmat/ClusteringBase.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusteringBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusteringBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293193.5 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBaseC1ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat14ClusteringBase12areConnectedERKjS3_0
_ZN4PLMD6adjmat14ClusteringBase17turnOnDerivativesEv8
_ZNK4PLMD6adjmat14ClusteringBase22getCutoffForConnectionEv8
_ZN4PLMD6adjmat14ClusteringBaseC2ERKNS_13ActionOptionsE17
_ZN4PLMD6adjmat14ClusteringBase16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD6adjmat14ClusteringBase9calculateEv26
_ZNK4PLMD6adjmat14ClusteringBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE74
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.cpp.func.html b/coverage/adjmat/ClusteringBase.cpp.func.html new file mode 100644 index 000000000000..7d69cad50b3b --- /dev/null +++ b/coverage/adjmat/ClusteringBase.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusteringBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusteringBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293193.5 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBase16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD6adjmat14ClusteringBase17turnOnDerivativesEv8
_ZN4PLMD6adjmat14ClusteringBase9calculateEv26
_ZN4PLMD6adjmat14ClusteringBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat14ClusteringBaseC2ERKNS_13ActionOptionsE17
_ZNK4PLMD6adjmat14ClusteringBase12areConnectedERKjS3_0
_ZNK4PLMD6adjmat14ClusteringBase22getCutoffForConnectionEv8
_ZNK4PLMD6adjmat14ClusteringBase22retrieveAtomsInClusterERKjRSt6vectorIjSaIjEE74
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.cpp.gcov.html b/coverage/adjmat/ClusteringBase.cpp.gcov.html new file mode 100644 index 000000000000..e39fff2cb920 --- /dev/null +++ b/coverage/adjmat/ClusteringBase.cpp.gcov.html @@ -0,0 +1,160 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusteringBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusteringBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293193.5 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ClusteringBase.h"
+      23             : #include "AdjacencyMatrixBase.h"
+      24             : #include "AdjacencyMatrixVessel.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace adjmat {
+      28             : 
+      29          21 : void ClusteringBase::registerKeywords( Keywords& keys ) {
+      30          21 :   ActionWithInputMatrix::registerKeywords( keys );
+      31          21 : }
+      32             : 
+      33          17 : ClusteringBase::ClusteringBase(const ActionOptions&ao):
+      34             :   Action(ao),
+      35             :   ActionWithInputMatrix(ao),
+      36          17 :   number_of_cluster(-1)
+      37             : {
+      38          17 :   if( getAdjacencyVessel() ) {
+      39          15 :     cluster_sizes.resize(getNumberOfNodes()); which_cluster.resize(getNumberOfNodes());
+      40          15 :     if( getNumberOfNodeTypes()!=1 ) error("should only be running clustering with one base multicolvar in function");
+      41          15 :     if( !getAdjacencyVessel()->undirectedGraph() ) error("input contact matrix is incompatible with clustering");
+      42             :   }
+      43          34 :   if( keywords.exists("MATRIX") ) {
+      44          15 :     std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+      45             :   }
+      46          17 : }
+      47             : 
+      48           8 : void ClusteringBase::turnOnDerivatives() {
+      49             :   // Check base multicolvar isn't density probably other things shouldn't be allowed here as well
+      50           8 :   if( (getAdjacencyVessel()->getMatrixAction())->getNumberOfBaseMultiColvars()>0 ) {
+      51           7 :     if( getBaseMultiColvar(0)->isDensity() ) error("DFS clustering cannot be differentiated if base multicolvar is DENSITY");
+      52             :   }
+      53             : 
+      54             :   // Ensure that derivatives are turned on in base classes
+      55           8 :   ActionWithInputMatrix::turnOnDerivatives();
+      56           8 : }
+      57             : 
+      58          26 : void ClusteringBase::calculate() {
+      59             :   // All the clusters have zero size initially
+      60        8219 :   for(unsigned i=0; i<cluster_sizes.size(); ++i) { cluster_sizes[i].first=0; cluster_sizes[i].second=i; }
+      61             :   // Do the clustering bit
+      62          26 :   performClustering();
+      63             :   // Order the clusters in the system by size (this returns ascending order )
+      64          26 :   std::sort( cluster_sizes.begin(), cluster_sizes.end() );
+      65          26 : }
+      66             : 
+      67          74 : void ClusteringBase::retrieveAtomsInCluster( const unsigned& clust, std::vector<unsigned>& myatoms ) const {
+      68          74 :   unsigned n=0; myatoms.resize( cluster_sizes[cluster_sizes.size() - clust].first );
+      69       45287 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) {
+      70       45213 :     if( which_cluster[i]==cluster_sizes[cluster_sizes.size() - clust].second ) { myatoms[n]=i; n++; }
+      71             :   }
+      72          74 : }
+      73             : 
+      74           0 : bool ClusteringBase::areConnected( const unsigned& iatom, const unsigned& jatom ) const {
+      75           0 :   return getAdjacencyVessel()->nodesAreConnected( iatom, jatom );
+      76             : }
+      77             : 
+      78           8 : double ClusteringBase::getCutoffForConnection() const {
+      79           8 :   return getAdjacencyVessel()->getCutoffForConnection();
+      80             : }
+      81             : 
+      82             : }
+      83             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.h.func-sort-c.html b/coverage/adjmat/ClusteringBase.h.func-sort-c.html new file mode 100644 index 000000000000..7a2f3c02d1c6 --- /dev/null +++ b/coverage/adjmat/ClusteringBase.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusteringBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusteringBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBase5applyEv26
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.h.func.html b/coverage/adjmat/ClusteringBase.h.func.html new file mode 100644 index 000000000000..940391142cf0 --- /dev/null +++ b/coverage/adjmat/ClusteringBase.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusteringBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusteringBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14ClusteringBase5applyEv26
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ClusteringBase.h.gcov.html b/coverage/adjmat/ClusteringBase.h.gcov.html new file mode 100644 index 000000000000..3f848cb34538 --- /dev/null +++ b/coverage/adjmat/ClusteringBase.h.gcov.html @@ -0,0 +1,147 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ClusteringBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ClusteringBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_adjmat_ClusteringBase_h
+      23             : #define __PLUMED_adjmat_ClusteringBase_h
+      24             : 
+      25             : #include "ActionWithInputMatrix.h"
+      26             : #include "multicolvar/AtomValuePack.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace adjmat {
+      30             : 
+      31             : class ClusteringBase : public ActionWithInputMatrix {
+      32             : protected:
+      33             : /// Vector that stores the sizes of the current set of clusters
+      34             :   std::vector< std::pair<unsigned,unsigned> > cluster_sizes;
+      35             : /// Used to identify the cluster we are working on
+      36             :   int number_of_cluster;
+      37             : /// Vector that identifies the cluster each atom belongs to
+      38             :   std::vector<unsigned> which_cluster;
+      39             : public:
+      40             : /// Create manual
+      41             :   static void registerKeywords( Keywords& keys );
+      42             : /// Constructor
+      43             :   explicit ClusteringBase(const ActionOptions&);
+      44             : /// This checks whether derivatives can be computed given the base multicolvar
+      45             :   void turnOnDerivatives() override;
+      46             : /// Are these two atoms connected
+      47             :   bool areConnected( const unsigned& iatom, const unsigned& jatom ) const ;
+      48             : /// Do the calculation
+      49             :   void calculate() override;
+      50             : /// Do the clustering
+      51             :   virtual void performClustering()=0;
+      52             : /// Get the number of clusters that have been found
+      53             :   unsigned getNumberOfClusters() const ;
+      54             : /// Get the atoms in one of the clusters
+      55             :   virtual void retrieveAtomsInCluster( const unsigned& clust, std::vector<unsigned>& myatoms ) const ;
+      56             : /// Do nothing for apply here
+      57          26 :   void apply() override {}
+      58             : /// Get the cutoff
+      59             :   virtual double getCutoffForConnection() const ;
+      60             : };
+      61             : 
+      62             : inline
+      63             : unsigned ClusteringBase::getNumberOfClusters() const {
+      64           4 :   return number_of_cluster + 1;
+      65             : }
+      66             : 
+      67             : }
+      68             : }
+      69             : 
+      70             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactAlignedMatrix.cpp.func-sort-c.html b/coverage/adjmat/ContactAlignedMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..a41f42492f39 --- /dev/null +++ b/coverage/adjmat/ContactAlignedMatrix.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ContactAlignedMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ContactAlignedMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42119.0 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat20ContactAlignedMatrix24readOrientationConnectorERKjS3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE0
_ZN4PLMD6adjmat20ContactAlignedMatrixC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat20ContactAlignedMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat20ContactAlignedMatrix21computeVectorFunctionERKjS3_RKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_0
_ZN4PLMD6adjmat20ContactAlignedMatrix16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactAlignedMatrix.cpp.func.html b/coverage/adjmat/ContactAlignedMatrix.cpp.func.html new file mode 100644 index 000000000000..c7d6c3055da3 --- /dev/null +++ b/coverage/adjmat/ContactAlignedMatrix.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ContactAlignedMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ContactAlignedMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42119.0 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat20ContactAlignedMatrix16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6adjmat20ContactAlignedMatrix24readOrientationConnectorERKjS3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE0
_ZN4PLMD6adjmat20ContactAlignedMatrixC1ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat20ContactAlignedMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat20ContactAlignedMatrix21computeVectorFunctionERKjS3_RKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactAlignedMatrix.cpp.gcov.html b/coverage/adjmat/ContactAlignedMatrix.cpp.gcov.html new file mode 100644 index 000000000000..4fd84d270bc3 --- /dev/null +++ b/coverage/adjmat/ContactAlignedMatrix.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ContactAlignedMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ContactAlignedMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42119.0 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AlignedMatrixBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Matrix.h"
+      25             : 
+      26             : //+PLUMEDOC MATRIX ALIGNED_MATRIX
+      27             : /*
+      28             : Adjacency matrix in which two molecule are adjacent if they are within a certain cutoff and if they have the same orientation.
+      29             : 
+      30             : As discussed in the section of the manual on \ref contactmatrix a useful tool for developing complex collective variables is the notion of the
+      31             : so called adjacency matrix.  An adjacency matrix is an \f$N \times N\f$ matrix in which the \f$i\f$th, \f$j\f$th element tells you whether
+      32             : or not the \f$i\f$th and \f$j\f$th atoms/molecules from a set of \f$N\f$ atoms/molecules are adjacent or not.  These matrices can then be further
+      33             : analyzed using a number of other algorithms as is detailed in \cite tribello-clustering.
+      34             : 
+      35             : For this action the elements of the adjacency matrix are calculated using:
+      36             : 
+      37             : \f[
+      38             : a_{ij} = \sigma_1( |\mathbf{r}_{ij}| ) \sigma_2( \mathbf{v}_i . \mathbf{v}_j )
+      39             : \f]
+      40             : 
+      41             : This form of adjacency matrix can only be used if the input species are objects that lie at a point in space and that have an orientation, \f$\mathbf{v}\f$.
+      42             : These orientations might represent the
+      43             : orientation of a molecule, which could be calculated using \ref MOLECULES or \ref PLANES, or it might be the complex vectors calculated using the
+      44             : Steinhardt parameters \ref Q3, \ref Q4 or \ref Q6.  In the expression above \f$\mathbf{r}_{ij}\f$ is the vector connecting the points in space
+      45             : where objects \f$i\f$ and \f$j\f$ find themselves and \f$\sigma_1\f$ is a \ref switchingfunction that acts upon the magnitude of this vector.
+      46             : \f$\sigma_2\f$ is a second \ref switchingfunction that acts on the dot product of the directors of the vectors that define the orientations of
+      47             : objects \f$i\f$ and \f$j\f$.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : The example input below is necessarily but gives you an idea of what can be achieved using this action.
+      52             : The orientations and positions of four molecules are defined using the \ref MOLECULES action as the position of the
+      53             : centers of mass of the two atoms specified and the direction of the vector connecting the two atoms that were specified.
+      54             : A \f$4 \times 4\f$ matrix is then computed using the formula above.  The \f$ij\f$-element of this matrix tells us whether
+      55             : or not atoms \f$i\f$ and \f$j\f$ are within 0.1 nm of each other and whether or not the dot-product of their orientation vectors
+      56             : is greater than 0.5.  The sum of the rows of this matrix are then computed.  The sums of the \f$i\f$th row of this matrix tells us how
+      57             : many of the molecules that are within the first coordination sphere of molecule \f$i\f$ have an orientation that is similar to that of
+      58             : molecule \f$i\f$.  We thus calculate the number of these "coordination numbers" that are greater than 1.0 and output this quantity to a file.
+      59             : 
+      60             : \plumedfile
+      61             : m1: MOLECULES MOL1=1,2 MOL2=3,4 MOL3=5,6 MOL4=7,8
+      62             : mat: ALIGNED_MATRIX ATOMS=m1 SWITCH={RATIONAL R_0=0.1} ORIENTATION_SWITCH={RATIONAL R_0=0.1 D_MAX=0.5}
+      63             : row: ROWSUMS MATRIX=mat MORE_THAN={RATIONAL D_0=1.0 R_0=0.1}
+      64             : PRINT ARG=row.* FILE=colvar
+      65             : \endplumedfile
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : namespace PLMD {
+      71             : namespace adjmat {
+      72             : 
+      73             : class ContactAlignedMatrix : public AlignedMatrixBase {
+      74             : private:
+      75             :   Matrix<SwitchingFunction> sf;
+      76             : public:
+      77             :   ///
+      78             :   static void registerKeywords( Keywords& keys );
+      79             :   ///
+      80             :   explicit ContactAlignedMatrix(const ActionOptions&);
+      81             :   void readOrientationConnector( const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) override;
+      82             :   double computeVectorFunction( const unsigned& iv, const unsigned& jv,
+      83             :                                 const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+      84             :                                 Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const override;
+      85             : };
+      86             : 
+      87             : PLUMED_REGISTER_ACTION(ContactAlignedMatrix,"ALIGNED_MATRIX")
+      88             : 
+      89           2 : void ContactAlignedMatrix::registerKeywords( Keywords& keys ) {
+      90           2 :   AlignedMatrixBase::registerKeywords( keys );
+      91           4 :   keys.add("numbered","ORIENTATION_SWITCH","A switching function that transforms the dot product of the input vectors.");
+      92           2 : }
+      93             : 
+      94           0 : ContactAlignedMatrix::ContactAlignedMatrix( const ActionOptions& ao ):
+      95             :   Action(ao),
+      96           0 :   AlignedMatrixBase(ao)
+      97             : {
+      98           0 :   unsigned nrows, ncols, ig; retrieveTypeDimensions( nrows, ncols, ig );
+      99           0 :   sf.resize( nrows, ncols );
+     100           0 :   parseConnectionDescriptions("ORIENTATION_SWITCH",false,0);
+     101           0 : }
+     102             : 
+     103           0 : void ContactAlignedMatrix::readOrientationConnector( const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+     104           0 :   plumed_assert( desc.size()==1 ); std::string errors; sf(j,i).set(desc[0],errors);
+     105           0 :   if( j!=i ) sf(i,j).set(desc[0],errors);
+     106           0 :   log.printf("  vectors in %u th and %u th groups must have a dot product that is greater than %s \n",i+1,j+1,(sf(i,j).description()).c_str() );
+     107           0 : }
+     108             : 
+     109           0 : double ContactAlignedMatrix::computeVectorFunction( const unsigned& iv, const unsigned& jv,
+     110             :     const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+     111             :     Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const {
+     112           0 :   double dot_df, dot=0; dconn.zero();
+     113           0 :   for(unsigned k=2; k<vec1.size(); ++k) dot+=vec1[k]*vec2[k];
+     114           0 :   double f_dot = sf(iv,jv).calculate( dot, dot_df );
+     115           0 :   for(unsigned k=2; k<vec1.size(); ++k) { dvec1[k]=dot_df*vec2[k]; dvec2[k]=dot_df*vec1[k]; }
+     116           0 :   return f_dot;
+     117             : }
+     118             : 
+     119             : }
+     120             : }
+     121             : 
+     122             : 
+     123             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrix.cpp.func-sort-c.html b/coverage/adjmat/ContactMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..4d9abadbb78f --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ContactMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ContactMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13ContactMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat13ContactMatrixC1ERKNS_13ActionOptionsE12
_ZN4PLMD6adjmat13ContactMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE14
_ZN4PLMD6adjmat13ContactMatrix16registerKeywordsERNS_8KeywordsE14
_ZNK4PLMD6adjmat13ContactMatrix7computeERKjRNS_11multicolvar13AtomValuePackE28888
_ZNK4PLMD6adjmat13ContactMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE55746
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrix.cpp.func.html b/coverage/adjmat/ContactMatrix.cpp.func.html new file mode 100644 index 000000000000..8c91ebeb97d4 --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ContactMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ContactMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13ContactMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE14
_ZN4PLMD6adjmat13ContactMatrix16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6adjmat13ContactMatrixC1ERKNS_13ActionOptionsE12
_ZN4PLMD6adjmat13ContactMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat13ContactMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE55746
_ZNK4PLMD6adjmat13ContactMatrix7computeERKjRNS_11multicolvar13AtomValuePackE28888
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/ContactMatrix.cpp.gcov.html b/coverage/adjmat/ContactMatrix.cpp.gcov.html new file mode 100644 index 000000000000..4f8a64af2297 --- /dev/null +++ b/coverage/adjmat/ContactMatrix.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/ContactMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - ContactMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AdjacencyMatrixBase.h"
+      23             : #include "multicolvar/AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/SwitchingFunction.h"
+      26             : #include "tools/Matrix.h"
+      27             : 
+      28             : //+PLUMEDOC MATRIX CONTACT_MATRIX
+      29             : /*
+      30             : Adjacency matrix in which two atoms are adjacent if they are within a certain cutoff.
+      31             : 
+      32             : As discussed in the section of the manual on \ref contactmatrix a useful tool for developing complex collective variables is the notion of the
+      33             : so called adjacency matrix.  An adjacency matrix is an \f$N \times N\f$ matrix in which the \f$i\f$th, \f$j\f$th element tells you whether
+      34             : or not the \f$i\f$th and \f$j\f$th atoms/molecules from a set of \f$N\f$ atoms/molecules are adjacent or not.  These matrices can then be further
+      35             : analyzed using a number of other algorithms as is detailed in \cite tribello-clustering.
+      36             : 
+      37             : For this action the elements of the contact matrix are calculated using:
+      38             : 
+      39             : \f[
+      40             :  a_{ij} = \sigma( |\mathbf{r}_{ij}| )
+      41             : \f]
+      42             : 
+      43             : where \f$|\mathbf{r}_{ij}|\f$ is the magnitude of the vector connecting atoms \f$i\f$ and \f$j\f$ and where \f$\sigma\f$ is a \ref switchingfunction.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : The input shown below calculates a \f$6 \times 6\f$ matrix whose elements are equal to one if atom \f$i\f$ and atom \f$j\f$ are within 0.3 nm
+      48             : of each other and which is zero otherwise.  The columns in this matrix are then summed so as to give the coordination number for each atom.
+      49             : The final quantity output in the colvar file is thus the average coordination number.
+      50             : 
+      51             : \plumedfile
+      52             : mat: CONTACT_MATRIX ATOMS=1-6 SWITCH={EXP D_0=0.2 R_0=0.1 D_MAX=0.66}
+      53             : COLUMNSUMS MATRIX=mat MEAN LABEL=csums
+      54             : PRINT ARG=csums.* FILE=colvar
+      55             : \endplumedfile
+      56             : 
+      57             : */
+      58             : //+ENDPLUMEDOC
+      59             : 
+      60             : 
+      61             : namespace PLMD {
+      62             : namespace adjmat {
+      63             : 
+      64             : class ContactMatrix : public AdjacencyMatrixBase {
+      65             : private:
+      66             : /// Number of types that are in rows
+      67             :   unsigned ncol_t;
+      68             : /// switching function
+      69             :   Matrix<SwitchingFunction> switchingFunction;
+      70             : public:
+      71             : /// Create manual
+      72             :   static void registerKeywords( Keywords& keys );
+      73             : /// Constructor
+      74             :   explicit ContactMatrix(const ActionOptions&);
+      75             : /// Create the ith, ith switching function
+      76             :   void setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) override;
+      77             : /// This actually calculates the value of the contact function
+      78             :   double calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const override;
+      79             : /// This does nothing
+      80             :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const override;
+      81             : };
+      82             : 
+      83             : PLUMED_REGISTER_ACTION(ContactMatrix,"CONTACT_MATRIX")
+      84             : 
+      85          14 : void ContactMatrix::registerKeywords( Keywords& keys ) {
+      86          14 :   AdjacencyMatrixBase::registerKeywords( keys );
+      87          28 :   keys.add("atoms","ATOMS","The list of atoms for which you would like to calculate the contact matrix.  The atoms involved must be specified "
+      88             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      89             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      90             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      91             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      92          28 :   keys.add("numbered","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      93             :            "The following provides information on the \\ref switchingfunction that are available. ");
+      94             : // I added these keywords so I can test the results I get for column and row sums against output from COORDINATIONNUMBERS
+      95             : /// These  should never be used in production as I think they will be much slower than COORDINATIONNUMBERS
+      96          42 :   keys.add("hidden","ATOMSA",""); keys.add("hidden","ATOMSB","");
+      97          14 : }
+      98             : 
+      99          12 : ContactMatrix::ContactMatrix( const ActionOptions& ao ):
+     100             :   Action(ao),
+     101          12 :   AdjacencyMatrixBase(ao)
+     102             : {
+     103             :   // Read in the atoms and setup the matrix
+     104          24 :   readMaxTwoSpeciesMatrix( "ATOMS", "ATOMSA", "ATOMSB", true );
+     105          12 :   unsigned nrows, ncols; retrieveTypeDimensions( nrows, ncols, ncol_t );
+     106          12 :   switchingFunction.resize( nrows, ncols );
+     107             :   // Read in the switching functions
+     108          24 :   parseConnectionDescriptions("SWITCH",false,ncol_t);
+     109             : 
+     110             :   // Find the largest sf cutoff
+     111          12 :   double sfmax=switchingFunction(0,0).get_dmax();
+     112          25 :   for(unsigned i=0; i<switchingFunction.nrows(); ++i) {
+     113          28 :     for(unsigned j=0; j<switchingFunction.ncols(); ++j) {
+     114          15 :       double tsf=switchingFunction(i,j).get_dmax();
+     115          15 :       if( tsf>sfmax ) sfmax=tsf;
+     116             :     }
+     117             :   }
+     118             :   // And set the link cell cutoff
+     119          12 :   setLinkCellCutoff( sfmax );
+     120          12 : }
+     121             : 
+     122          14 : void ContactMatrix::setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+     123          14 :   plumed_assert( id==0 && desc.size()==1 ); std::string errors; switchingFunction(j,i).set(desc[0],errors);
+     124          14 :   if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     125          14 :   if( j!=i) switchingFunction(i,j).set(desc[0],errors);
+     126          28 :   log.printf("  %u th and %u th multicolvar groups must be within %s\n",i+1,j+1,(switchingFunction(i,j).description()).c_str() );
+     127          14 : }
+     128             : 
+     129       55746 : double ContactMatrix::calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+     130       55746 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     131      166288 :   if( distance.modulo2()<switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) - ncol_t ).get_dmax2() ) return 1.0;
+     132             :   return 0.0;
+     133             : }
+     134             : 
+     135       28888 : double ContactMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     136       28888 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     137             :   double dfunc;
+     138       57301 :   double sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) - ncol_t ).calculate( distance.modulo(), dfunc );
+     139             : 
+     140       28888 :   if( !doNotCalculateDerivatives() ) {
+     141       28654 :     addAtomDerivatives( 1, 0, (-dfunc)*distance, myatoms );
+     142       28654 :     addAtomDerivatives( 1, 1, (+dfunc)*distance, myatoms );
+     143       28654 :     myatoms.addBoxDerivatives( 1, (-dfunc)*Tensor(distance,distance) );
+     144             :   }
+     145       28888 :   return sw;
+     146             : }
+     147             : 
+     148             : }
+     149             : }
+     150             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DFSClustering.cpp.func-sort-c.html b/coverage/adjmat/DFSClustering.cpp.func-sort-c.html new file mode 100644 index 000000000000..00fc968d08a3 --- /dev/null +++ b/coverage/adjmat/DFSClustering.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DFSClustering.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DFSClustering.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13DFSClusteringC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat13DFSClusteringC1ERKNS_13ActionOptionsE15
_ZN4PLMD6adjmat13DFSClustering16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD6adjmat13DFSClustering17performClusteringEv24
_ZN4PLMD6adjmat13DFSClustering7exploreERKj8193
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DFSClustering.cpp.func.html b/coverage/adjmat/DFSClustering.cpp.func.html new file mode 100644 index 000000000000..ee13c753e311 --- /dev/null +++ b/coverage/adjmat/DFSClustering.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DFSClustering.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DFSClustering.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13DFSClustering16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD6adjmat13DFSClustering17performClusteringEv24
_ZN4PLMD6adjmat13DFSClustering7exploreERKj8193
_ZN4PLMD6adjmat13DFSClusteringC1ERKNS_13ActionOptionsE15
_ZN4PLMD6adjmat13DFSClusteringC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DFSClustering.cpp.gcov.html b/coverage/adjmat/DFSClustering.cpp.gcov.html new file mode 100644 index 000000000000..42332e2a5c95 --- /dev/null +++ b/coverage/adjmat/DFSClustering.cpp.gcov.html @@ -0,0 +1,238 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DFSClustering.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DFSClustering.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ClusteringBase.h"
+      23             : #include "AdjacencyMatrixVessel.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : #ifdef __PLUMED_HAS_BOOST_GRAPH
+      27             : #include <boost/graph/adjacency_list.hpp>
+      28             : #include <boost/graph/connected_components.hpp>
+      29             : #include <boost/graph/graph_utility.hpp>
+      30             : #endif
+      31             : 
+      32             : //+PLUMEDOC MATRIXF DFSCLUSTERING
+      33             : /*
+      34             : Find the connected components of the matrix using the depth first search clustering algorithm.
+      35             : 
+      36             : As discussed in the section of the manual on \ref contactmatrix a useful tool for developing complex collective variables is the notion of the
+      37             : so called adjacency matrix.  An adjacency matrix is an \f$N \times N\f$ matrix in which the \f$i\f$th, \f$j\f$th element tells you whether
+      38             : or not the \f$i\f$th and \f$j\f$th atoms/molecules from a set of \f$N\f$ atoms/molecules are adjacent or not.  As detailed in \cite tribello-clustering
+      39             : these matrices provide a representation of a graph and can thus can be analyzed using tools from graph theory.  This particular action performs
+      40             : a depth first search clustering to find the connected components of this graph.  You can read more about depth first search here:
+      41             : 
+      42             : https://en.wikipedia.org/wiki/Depth-first_search
+      43             : 
+      44             : This action is useful if you are looking at a phenomenon such as nucleation where the aim is to detect the sizes of the crystalline nuclei that have formed
+      45             : in your simulation cell.
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : The input below calculates the coordination numbers of atoms 1-100 and then computes the an adjacency
+      50             : matrix whose elements measures whether atoms \f$i\f$ and \f$j\f$ are within 0.55 nm of each other.  The action
+      51             : labelled dfs then treats the elements of this matrix as zero or ones and thus thinks of the matrix as defining
+      52             : a graph.  This dfs action then finds the largest connected component in this graph.  The sum of the coordination
+      53             : numbers for the atoms in this largest connected component are then computed and this quantity is output to a colvar
+      54             : file.  The way this input can be used is described in detail in \cite tribello-clustering.
+      55             : 
+      56             : \plumedfile
+      57             : lq: COORDINATIONNUMBER SPECIES=1-100 SWITCH={CUBIC D_0=0.45  D_MAX=0.55} LOWMEM
+      58             : cm: CONTACT_MATRIX ATOMS=lq  SWITCH={CUBIC D_0=0.45  D_MAX=0.55}
+      59             : dfs: DFSCLUSTERING MATRIX=cm
+      60             : clust1: CLUSTER_PROPERTIES CLUSTERS=dfs CLUSTER=1 SUM
+      61             : PRINT ARG=clust1.* FILE=colvar
+      62             : \endplumedfile
+      63             : 
+      64             : */
+      65             : //+ENDPLUMEDOC
+      66             : 
+      67             : namespace PLMD {
+      68             : namespace adjmat {
+      69             : 
+      70             : class DFSClustering : public ClusteringBase {
+      71             : private:
+      72             : #ifdef __PLUMED_HAS_BOOST_GRAPH
+      73             : /// The list of edges in the graph
+      74             :   std::vector<std::pair<unsigned,unsigned> > edge_list;
+      75             : #else
+      76             : /// The number of neighbors each atom has
+      77             :   std::vector<unsigned> nneigh;
+      78             : /// The adjacency list
+      79             :   Matrix<unsigned> adj_list;
+      80             : /// The color that tells us whether a node has been visited
+      81             :   std::vector<unsigned> color;
+      82             : /// The recursive function at the heart of this method
+      83             :   int explore( const unsigned& index );
+      84             : #endif
+      85             : public:
+      86             : /// Create manual
+      87             :   static void registerKeywords( Keywords& keys );
+      88             : /// Constructor
+      89             :   explicit DFSClustering(const ActionOptions&);
+      90             : /// Do the clustering
+      91             :   void performClustering() override;
+      92             : };
+      93             : 
+      94             : PLUMED_REGISTER_ACTION(DFSClustering,"DFSCLUSTERING")
+      95             : 
+      96          17 : void DFSClustering::registerKeywords( Keywords& keys ) {
+      97          17 :   ClusteringBase::registerKeywords( keys );
+      98          34 :   keys.add("compulsory","MAXCONNECT","0","maximum number of connections that can be formed by any given node in the graph. "
+      99             :            "By default this is set equal to zero and the number of connections is set equal to the number "
+     100             :            "of nodes.  You only really need to set this if you are working with a very large system and "
+     101             :            "memory is at a premium");
+     102          17 : }
+     103             : 
+     104          15 : DFSClustering::DFSClustering(const ActionOptions&ao):
+     105             :   Action(ao),
+     106          15 :   ClusteringBase(ao)
+     107             : {
+     108          15 :   unsigned maxconnections; parse("MAXCONNECT",maxconnections);
+     109             : #ifdef __PLUMED_HAS_BOOST_GRAPH
+     110             :   if( maxconnections>0 ) edge_list.resize( getNumberOfNodes()*maxconnections );
+     111             :   else edge_list.resize(0.5*getNumberOfNodes()*(getNumberOfNodes()-1));
+     112             : #else
+     113          15 :   nneigh.resize( getNumberOfNodes() ); color.resize(getNumberOfNodes());
+     114          15 :   if( maxconnections>0 ) adj_list.resize(getNumberOfNodes(),maxconnections);
+     115          15 :   else adj_list.resize(getNumberOfNodes(),getNumberOfNodes());
+     116             : #endif
+     117          15 : }
+     118             : 
+     119          24 : void DFSClustering::performClustering() {
+     120             : #ifdef __PLUMED_HAS_BOOST_GRAPH
+     121             :   // Get the list of edges
+     122             :   unsigned nedges=0; getAdjacencyVessel()->retrieveEdgeList( nedges, edge_list );
+     123             : 
+     124             :   // Build the graph using boost
+     125             :   boost::adjacency_list<boost::vecS,boost::vecS,boost::undirectedS> sg(&edge_list[0],&edge_list[nedges],getNumberOfNodes());
+     126             : 
+     127             :   // Find the connected components using boost (-1 here for compatibility with non-boost version)
+     128             :   number_of_cluster=boost::connected_components(sg,&which_cluster[0]) - 1;
+     129             : 
+     130             :   // And work out the size of each cluster
+     131             :   for(unsigned i=0; i<which_cluster.size(); ++i) cluster_sizes[which_cluster[i]].first++;
+     132             : #else
+     133             :   // Get the adjacency matrix
+     134          24 :   getAdjacencyVessel()->retrieveAdjacencyLists( nneigh, adj_list );
+     135             : 
+     136             :   // Perform clustering
+     137          24 :   number_of_cluster=-1; color.assign(color.size(),0);
+     138        8217 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) {
+     139        8193 :     if( color[i]==0 ) { number_of_cluster++; color[i]=explore(i); }
+     140             :   }
+     141             : #endif
+     142          24 : }
+     143             : 
+     144             : #ifndef __PLUMED_HAS_BOOST_GRAPH
+     145        8193 : int DFSClustering::explore( const unsigned& index ) {
+     146             : 
+     147        8193 :   color[index]=1;
+     148       38219 :   for(unsigned i=0; i<nneigh[index]; ++i) {
+     149       30026 :     unsigned j=adj_list(index,i);
+     150       30026 :     if( color[j]==0 ) color[j]=explore(j);
+     151             :   }
+     152             : 
+     153             :   // Count the size of the cluster
+     154        8193 :   cluster_sizes[number_of_cluster].first++;
+     155        8193 :   which_cluster[index] = number_of_cluster;
+     156        8193 :   return color[index];
+     157             : }
+     158             : #endif
+     159             : 
+     160             : }
+     161             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DumpGraph.cpp.func-sort-c.html b/coverage/adjmat/DumpGraph.cpp.func-sort-c.html new file mode 100644 index 000000000000..a89d02eca298 --- /dev/null +++ b/coverage/adjmat/DumpGraph.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DumpGraph.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DumpGraph.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3434100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat9DumpGraphC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat9DumpGraph5applyEv4
_ZN4PLMD6adjmat9DumpGraph6updateEv4
_ZN4PLMD6adjmat9DumpGraph9calculateEv4
_ZN4PLMD6adjmat9DumpGraphC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat9DumpGraph16registerKeywordsERNS_8KeywordsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DumpGraph.cpp.func.html b/coverage/adjmat/DumpGraph.cpp.func.html new file mode 100644 index 000000000000..7c589372633e --- /dev/null +++ b/coverage/adjmat/DumpGraph.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DumpGraph.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DumpGraph.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3434100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat9DumpGraph16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6adjmat9DumpGraph5applyEv4
_ZN4PLMD6adjmat9DumpGraph6updateEv4
_ZN4PLMD6adjmat9DumpGraph9calculateEv4
_ZN4PLMD6adjmat9DumpGraphC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat9DumpGraphC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/DumpGraph.cpp.gcov.html b/coverage/adjmat/DumpGraph.cpp.gcov.html new file mode 100644 index 000000000000..5b2b7f320c72 --- /dev/null +++ b/coverage/adjmat/DumpGraph.cpp.gcov.html @@ -0,0 +1,191 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/DumpGraph.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - DumpGraph.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3434100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "AdjacencyMatrixVessel.h"
+      25             : #include "AdjacencyMatrixBase.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "tools/OFile.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace adjmat {
+      32             : 
+      33             : //+PLUMEDOC CONCOMP DUMPGRAPH
+      34             : /*
+      35             : Write out the connectivity of the nodes in the graph in dot format.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : 
+      43             : class DumpGraph : public ActionPilot {
+      44             : private:
+      45             : ///
+      46             :   size_t maxconnections;
+      47             : /// The vessel that contains the graph
+      48             :   AdjacencyMatrixVessel* mymatrix;
+      49             : /// The name of the file on which we are outputting the graph
+      50             :   std::string filename;
+      51             : public:
+      52             : /// Create manual
+      53             :   static void registerKeywords( Keywords& keys );
+      54             : /// Constructor
+      55             :   explicit DumpGraph( const ActionOptions& );
+      56             : /// Calculate and apply do nothing
+      57           4 :   void calculate() override {};
+      58           4 :   void apply() override {};
+      59             : /// Update will do the output
+      60             :   void update() override;
+      61             : };
+      62             : 
+      63             : PLUMED_REGISTER_ACTION(DumpGraph,"DUMPGRAPH")
+      64             : 
+      65           6 : void DumpGraph::registerKeywords( Keywords& keys ) {
+      66           6 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      67          12 :   keys.add("compulsory","MATRIX","the action that calculates the adjacency matrix vessel we would like to analyze");
+      68          12 :   keys.add("compulsory","STRIDE","1","the frequency with which you would like to output the graph");
+      69          12 :   keys.add("compulsory","FILE","the name of the file on which to output the data");
+      70          12 :   keys.add("compulsory","MAXCONNECT","0","maximum number of connections that can be formed by any given node in the graph. "
+      71             :            "By default this is set equal to zero and the number of connections is set equal to the number "
+      72             :            "of nodes.  You only really need to set this if you are working with a very large system and "
+      73             :            "memory is at a premium");
+      74             : 
+      75           6 : }
+      76             : 
+      77           4 : DumpGraph::DumpGraph( const ActionOptions& ao):
+      78             :   Action(ao),
+      79             :   ActionPilot(ao),
+      80           4 :   mymatrix(NULL)
+      81             : {
+      82           8 :   parse("MAXCONNECT",maxconnections); std::string mstring; parse("MATRIX",mstring);
+      83           4 :   AdjacencyMatrixBase* mm = plumed.getActionSet().selectWithLabel<AdjacencyMatrixBase*>( mstring );
+      84           4 :   if( !mm ) error("found no action in set with label " + mstring + " that calculates matrix");
+      85           4 :   log.printf("  printing graph for matrix calculated by action %s\n", mm->getLabel().c_str() );
+      86             : 
+      87             :   // Retrieve the adjacency matrix of interest
+      88           4 :   for(unsigned i=0; i<mm->getNumberOfVessels(); ++i) {
+      89           4 :     mymatrix = dynamic_cast<AdjacencyMatrixVessel*>( mm->getPntrToVessel(i) );
+      90           4 :     if( mymatrix ) break ;
+      91             :   }
+      92           4 :   if( !mymatrix ) error( mm->getLabel() + " does not calculate an adjacency matrix");
+      93           4 :   if( !mymatrix->isSymmetric() ) error("input contact matrix must be symmetric");
+      94           4 :   if( maxconnections==0 ) maxconnections=mymatrix->getNumberOfRows();
+      95           4 :   parse("FILE",filename);
+      96           4 :   log.printf("  printing graph to file named %s \n",filename.c_str() );
+      97           4 :   checkRead();
+      98           4 : }
+      99             : 
+     100           4 : void DumpGraph::update() {
+     101           4 :   OFile ofile; ofile.link(*this); ofile.setBackupString("graph");
+     102           4 :   ofile.open( filename ); ofile.printf("graph G { \n");
+     103             :   // Print all nodes
+     104        1336 :   for(unsigned i=0; i<mymatrix->getNumberOfRows(); ++i) ofile.printf("%u [label=\"%u\"];\n",i,i);
+     105             :   // Now retrieve connectivitives
+     106           4 :   unsigned nedge; std::vector<std::pair<unsigned,unsigned> > edge_list( mymatrix->getNumberOfRows()*maxconnections );
+     107           4 :   mymatrix->retrieveEdgeList( nedge, edge_list );
+     108        6388 :   for(unsigned i=0; i<nedge; ++i) ofile.printf("%u -- %u \n", edge_list[i].first, edge_list[i].second );
+     109           4 :   ofile.printf("} \n");
+     110           4 : }
+     111             : 
+     112             : }
+     113             : }
+     114             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html b/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..2a9e7d0385ca --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/HbondMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - HbondMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687097.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11HBondMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat11HBondMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat11HBondMatrix16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat11HBondMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE6
_ZNK4PLMD6adjmat11HBondMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE4038
_ZNK4PLMD6adjmat11HBondMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
_ZNK4PLMD6adjmat11HBondMatrix17calculateForThreeERKjS3_S3_RKNS_13VectorGenericILj3EEERKdS9_RNS_11multicolvar13AtomValuePackE516132
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/HbondMatrix.cpp.func.html b/coverage/adjmat/HbondMatrix.cpp.func.html new file mode 100644 index 000000000000..893bc4248039 --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/HbondMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - HbondMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687097.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat11HBondMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE6
_ZN4PLMD6adjmat11HBondMatrix16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6adjmat11HBondMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD6adjmat11HBondMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat11HBondMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE4038
_ZNK4PLMD6adjmat11HBondMatrix17calculateForThreeERKjS3_S3_RKNS_13VectorGenericILj3EEERKdS9_RNS_11multicolvar13AtomValuePackE516132
_ZNK4PLMD6adjmat11HBondMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/HbondMatrix.cpp.gcov.html b/coverage/adjmat/HbondMatrix.cpp.gcov.html new file mode 100644 index 000000000000..5d801d70b3ce --- /dev/null +++ b/coverage/adjmat/HbondMatrix.cpp.gcov.html @@ -0,0 +1,309 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/HbondMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - HbondMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687097.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AdjacencyMatrixBase.h"
+      23             : #include "multicolvar/AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/SwitchingFunction.h"
+      26             : #include "tools/HistogramBead.h"
+      27             : #include "tools/Angle.h"
+      28             : #include "tools/Matrix.h"
+      29             : 
+      30             : //+PLUMEDOC MATRIX HBOND_MATRIX
+      31             : /*
+      32             : Adjacency matrix in which two atoms are adjacent if there is a hydrogen bond between them.
+      33             : 
+      34             : As discussed in the section of the manual on \ref contactmatrix a useful tool for developing complex collective variables is the notion of the
+      35             : so called adjacency matrix.  An adjacency matrix is an \f$N \times N\f$ matrix in which the \f$i\f$th, \f$j\f$th element tells you whether
+      36             : or not the \f$i\f$th and \f$j\f$th atoms/molecules from a set of \f$N\f$ atoms/molecules are adjacent or not.  These matrices can then be further
+      37             : analyzed using a number of other algorithms as is detailed in \cite tribello-clustering.
+      38             : 
+      39             : For this action the elements of the adjacency matrix are calculated using:
+      40             : 
+      41             : \f[
+      42             : a_{ij} = \sigma_{oo}( |\mathbf{r}_{ij}| ) \sum_{k=1}^N \sigma_{oh}( |\mathbf{r}_{ik}| ) \sigma_{\theta}( \theta_{kij} )
+      43             : \f]
+      44             : 
+      45             : This expression was derived by thinking about how to detect if there is a hydrogen bond between atoms \f$i\f$ and \f$j\f$.  The notion is that
+      46             : if the hydrogen bond is present atoms \f$i\f$ and \f$j\f$ should be within a certain cutoff distance.  In addition, there should be a hydrogen
+      47             : within a certain cutoff distance of atom \f$i\f$ and this hydrogen should lie on or close to the vector connecting atoms \f$i\f$ and \f$j\f$.
+      48             : As such \f$\sigma_{oo}( |\mathbf{r}_{ij}| )\f$ is a \ref switchingfunction that acts on the modulus of the vector connecting atom \f$i\f$ to atom
+      49             : \f$j\f$.  The sum over \f$k\f$ then runs over all the hydrogen atoms that are specified using using HYDROGEN keyword.  \f$\sigma_{oh}(|\mathbf{r}_{ik}|)\f$
+      50             : is a \ref switchingfunction that acts on the modulus of the vector connecting atom \f$i\f$ to atom \f$k\f$ and \f$\sigma_{\theta}(\theta_{kij})\f$
+      51             : is a \ref switchingfunction that acts on the angle between the vector connecting atoms \f$i\f$ and \f$j\f$ and the vector connecting atoms \f$i\f$ and
+      52             : \f$k\f$.
+      53             : 
+      54             : It is important to note that hydrogen bonds, unlike regular bonds, are asymmetric. In other words, the hydrogen atom does not sit at the
+      55             : mid point between the two other atoms in this three-center bond.  As a result of this adjacency matrices calculated using \ref HBOND_MATRIX are not
+      56             : symmetric like those calculated by \ref CONTACT_MATRIX.  One consequence of this fact is that the quantities found by performing \ref ROWSUMS and
+      57             : \ref COLUMNSUMS on a square \ref HBOND_MATRIX are not the same as they would be if you performed \ref ROWSUMS and
+      58             : \ref COLUMNSUMS on a square \ref CONTACT_MATRIX.
+      59             : 
+      60             : \par Examples
+      61             : 
+      62             : The following input can be used to analyze the number of hydrogen bonds each of the oxygen atoms in a box of water participates in.  Each
+      63             : water molecule can participate in a hydrogen bond in one of two ways.  It can either donate one of its hydrogen atom to the neighboring oxygen or
+      64             : it can accept a bond between the hydrogen of a neighboring water molecule and its own oxygen.  The input below allows you to output information
+      65             : on the number of hydrogen bonds each of the water molecules donates and accepts.  This information is output in two xyz files which each contain
+      66             : five columns of data.  The first four of these columns are a label for the atom and the x, y and z position of the oxygen.  The last column is then
+      67             : the number of accepted/donated hydrogen bonds.
+      68             : 
+      69             : \plumedfile
+      70             : mat: HBOND_MATRIX ATOMS=1-192:3 HYDROGENS=2-192:3,3-192:3 SWITCH={RATIONAL R_0=3.20} HSWITCH={RATIONAL R_0=2.30} ASWITCH={RATIONAL R_0=0.167pi} SUM
+      71             : rsums: ROWSUMS MATRIX=mat MEAN
+      72             : csums: COLUMNSUMS MATRIX=mat MEAN
+      73             : DUMPMULTICOLVAR DATA=rsums FILE=donors.xyz
+      74             : DUMPMULTICOLVAR DATA=csums FILE=acceptors.xyz
+      75             : \endplumedfile
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : 
+      81             : namespace PLMD {
+      82             : namespace adjmat {
+      83             : 
+      84             : class HBondMatrix : public AdjacencyMatrixBase {
+      85             : private:
+      86             :   unsigned ndonor_types;
+      87             : /// switching function
+      88             :   Matrix<SwitchingFunction> distanceOOSwitch;
+      89             :   Matrix<SwitchingFunction> distanceOHSwitch;
+      90             :   Matrix<SwitchingFunction> angleSwitch;
+      91             : public:
+      92             : /// Create manual
+      93             :   static void registerKeywords( Keywords& keys );
+      94             : /// Constructor
+      95             :   explicit HBondMatrix(const ActionOptions&);
+      96             : /// Create the ith, ith switching function
+      97             :   void setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) override;
+      98             : /// This actually calculates the value of the contact function
+      99             :   double calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const override;
+     100             : /// This does nothing
+     101             :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const override;
+     102             : ///
+     103             :   double calculateForThree( const unsigned& iat, const unsigned& ano, const unsigned& dno, const Vector& ood,
+     104             :                             const double& ood_df, const double& ood_sw, multicolvar::AtomValuePack& myatoms ) const;
+     105             : };
+     106             : 
+     107             : PLUMED_REGISTER_ACTION(HBondMatrix,"HBOND_MATRIX")
+     108             : 
+     109           4 : void HBondMatrix::registerKeywords( Keywords& keys ) {
+     110           4 :   AdjacencyMatrixBase::registerKeywords( keys );
+     111           8 :   keys.add("atoms","ATOMS","The list of atoms which can be part of a hydrogen bond.  When this command is used the set of atoms that can donate a "
+     112             :            "hydrogen bond is assumed to be the same as the set of atoms that can form hydrogen bonds.  The atoms involved must be specified "
+     113             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+     114             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+     115             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+     116             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+     117           8 :   keys.add("atoms","HYDROGENS","The list of hydrogen atoms that can form part of a hydrogen bond.  The atoms must be specified using a comma separated list, "
+     118             :            "an index range or by using a \\ref GROUP.  A list of hydrogen atoms is always required even if you specify the other atoms using "
+     119             :            "DONORS and ACCEPTORS as described below.");
+     120           8 :   keys.add("atoms-2","DONORS","The list of atoms which can donate a hydrogen bond.  The atoms involved must be specified "
+     121             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+     122             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+     123             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+     124             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+     125           8 :   keys.add("atoms-2","ACCEPTORS","The list of atoms which can accept a hydrogen bond.  The atoms involved must be specified "
+     126             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+     127             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+     128             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+     129             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+     130           8 :   keys.add("numbered","SWITCH","The \\ref switchingfunction that specifies how close a pair of atoms must be together for there to be a hydrogen bond between them");
+     131           8 :   keys.add("numbered","HSWITCH","The \\ref switchingfunction that specifies how close the hydrogen must be to the donor atom of the hydrogen bond for it to be "
+     132             :            "considered a hydrogen bond");
+     133           8 :   keys.add("numbered","ASWITCH","A \\ref switchingfunction that is used to specify what the angle between the vector connecting the donor atom to the acceptor atom and "
+     134             :            "the vector connecting the donor atom to the hydrogen must be in order for it considered to be a hydrogen bond");
+     135           4 :   keys.use("SUM");
+     136           4 : }
+     137             : 
+     138           2 : HBondMatrix::HBondMatrix( const ActionOptions& ao ):
+     139             :   Action(ao),
+     140           2 :   AdjacencyMatrixBase(ao)
+     141             : {
+     142           4 :   readMaxThreeSpeciesMatrix( "ATOMS", "DONORS", "ACCEPTORS", "HYDROGENS", false );
+     143           2 :   unsigned nrows, ncols; retrieveTypeDimensions( nrows, ncols, ndonor_types );
+     144           2 :   distanceOOSwitch.resize( nrows, ncols ); distanceOHSwitch.resize( nrows, ncols ); angleSwitch.resize( nrows, ncols );
+     145           2 :   parseConnectionDescriptions("SWITCH",false,ndonor_types);
+     146           2 :   parseConnectionDescriptions("HSWITCH",false,ndonor_types);
+     147           4 :   parseConnectionDescriptions("ASWITCH",false,ndonor_types);
+     148             : 
+     149             :   // Find the largest sf cutoff
+     150           2 :   double sfmax=distanceOOSwitch(0,0).get_dmax();
+     151           4 :   for(unsigned i=0; i<getNumberOfNodeTypes(); ++i) {
+     152           4 :     for(unsigned j=0; j<getNumberOfNodeTypes(); ++j) {
+     153           2 :       double tsf=distanceOOSwitch(i,j).get_dmax();
+     154           2 :       if( tsf>sfmax ) sfmax=tsf;
+     155             :     }
+     156             :   }
+     157             :   // Set the link cell cutoff
+     158           2 :   setLinkCellCutoff( sfmax );
+     159           2 : }
+     160             : 
+     161           6 : void HBondMatrix::setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+     162           6 :   plumed_assert( id<3 && desc.size()==1 );
+     163           6 :   if( id==0 ) {
+     164           2 :     std::string errors; distanceOOSwitch(j,i).set(desc[0],errors);
+     165           2 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     166           2 :     if( j!=i) distanceOOSwitch(i,j).set(desc[0],errors);
+     167           4 :     log.printf("  atoms of type %u and %u must be within %s\n",i+1,j+1,(distanceOOSwitch(i,j).description()).c_str() );
+     168           4 :   } else if( id==1 ) {
+     169           2 :     std::string errors; distanceOHSwitch(j,i).set(desc[0],errors);
+     170           2 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     171           2 :     if( j!=i) distanceOHSwitch(i,j).set(desc[0],errors);
+     172           4 :     log.printf("  for atoms of type %u and %u the OH distance must be less than %s \n",i+1,j+1,(distanceOHSwitch(i,j).description()).c_str() );
+     173           2 :   } else if( id==2 ) {
+     174           2 :     std::string errors; angleSwitch(j,i).set(desc[0],errors);
+     175           2 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     176           2 :     if( j!=i) angleSwitch(i,j).set(desc[0],errors);
+     177           4 :     log.printf("  for atoms of type %u and %u the OOH angle must be less than %s \n",i+1,j+1,(angleSwitch(i,j).description()).c_str() );
+     178             :   }
+     179           6 : }
+     180             : 
+     181        4038 : double HBondMatrix::calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+     182             :   // Ensure we skip diagonal elements of square matrix
+     183        4038 :   if( myatoms.getIndex(0)==myatoms.getIndex(1) ) return 0.0;
+     184             : 
+     185        4038 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     186        8076 :   if( distance.modulo2()<distanceOOSwitch( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax2() ) return 1.0;
+     187             :   return 0.0;
+     188             : }
+     189             : 
+     190        4038 : double HBondMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     191        4038 :   Vector ood = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) ); double ood_l = ood.modulo(); // acceptor - donor
+     192             :   double ood_df, ood_sw=distanceOOSwitch( getBaseColvarNumber( myatoms.getIndex(0) ),
+     193        4038 :                                           getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( ood_l, ood_df );
+     194             : 
+     195             :   // Get the base colvar numbers
+     196        4038 :   unsigned ano, dno = getBaseColvarNumber( myatoms.getIndex(0) );
+     197        8076 :   if( ndonor_types==0 ) ano = getBaseColvarNumber( myatoms.getIndex(1) );
+     198           0 :   else ano = getBaseColvarNumber( myatoms.getIndex(1) ) - ndonor_types;
+     199             : 
+     200             :   double value=0;
+     201        4038 :   if( myatoms.getNumberOfAtoms()>3 ) {
+     202      520170 :     for(unsigned i=2; i<myatoms.getNumberOfAtoms(); ++i) value+=calculateForThree( i, ano, dno, ood, ood_df, ood_sw,  myatoms );
+     203             :   } else {
+     204             :     plumed_dbg_assert( myatoms.getNumberOfAtoms()==3 );
+     205           0 :     value=calculateForThree( 2, ano, dno, ood, ood_df, ood_sw, myatoms );
+     206             :   }
+     207        4038 :   return value;
+     208             : }
+     209             : 
+     210      516132 : double HBondMatrix::calculateForThree( const unsigned& iat, const unsigned& ano, const unsigned& dno, const Vector& ood,
+     211             :                                        const double& ood_df, const double& ood_sw, multicolvar::AtomValuePack& myatoms ) const {
+     212      516132 :   Vector ohd=getSeparation( myatoms.getPosition(0), myatoms.getPosition(iat) ); double ohd_l=ohd.modulo();
+     213             :   double ohd_df, ohd_sw=distanceOHSwitch( getBaseColvarNumber( myatoms.getIndex(0) ),
+     214      516132 :                                           getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( ohd_l, ohd_df );
+     215             : 
+     216      516132 :   Angle a; Vector ood_adf, ohd_adf; double angle=a.compute( ood, ohd, ood_adf, ohd_adf );
+     217             :   double angle_df, angle_sw=angleSwitch( getBaseColvarNumber( myatoms.getIndex(0) ),
+     218      516132 :                                          getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( angle, angle_df );
+     219             : 
+     220      516132 :   if( !doNotCalculateDerivatives() ) {
+     221          36 :     addAtomDerivatives( 1, 0, angle_sw*ohd_sw*(-ood_df)*ood + angle_sw*ood_sw*(-ohd_df)*ohd + ood_sw*ohd_sw*angle_df*angle*(-ood_adf-ohd_adf), myatoms );
+     222          36 :     addAtomDerivatives( 1, 1, angle_sw*ohd_sw*(+ood_df)*ood + ood_sw*ohd_sw*angle_df*angle*ood_adf, myatoms );
+     223          36 :     addAtomDerivatives( 1, iat, angle_sw*ood_sw*(+ohd_df)*ohd + ood_sw*ohd_sw*angle_df*angle*ohd_adf, myatoms );
+     224          72 :     myatoms.addBoxDerivatives( 1, angle_sw*ohd_sw*(-ood_df)*Tensor(ood,ood) + angle_sw*ood_sw*(-ohd_df)*Tensor(ohd,ohd)
+     225         108 :                                -ood_sw*ohd_sw*angle_df*angle*(Tensor(ood,ood_adf)+Tensor(ohd,ohd_adf)) );
+     226             :   }
+     227      516132 :   return ood_sw*ohd_sw*angle_sw;
+     228             : }
+     229             : 
+     230             : }
+     231             : }
+     232             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixColumnSums.cpp.func-sort-c.html b/coverage/adjmat/MatrixColumnSums.cpp.func-sort-c.html new file mode 100644 index 000000000000..cebb5648cd62 --- /dev/null +++ b/coverage/adjmat/MatrixColumnSums.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixColumnSums.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixColumnSums.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16MatrixColumnSumsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat16MatrixColumnSumsC1ERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat16MatrixColumnSums16registerKeywordsERNS_8KeywordsE7
_ZNK4PLMD6adjmat16MatrixColumnSums7computeERKjRNS_11multicolvar13AtomValuePackE238
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixColumnSums.cpp.func.html b/coverage/adjmat/MatrixColumnSums.cpp.func.html new file mode 100644 index 000000000000..7846af109427 --- /dev/null +++ b/coverage/adjmat/MatrixColumnSums.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixColumnSums.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixColumnSums.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat16MatrixColumnSums16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6adjmat16MatrixColumnSumsC1ERKNS_13ActionOptionsE5
_ZN4PLMD6adjmat16MatrixColumnSumsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat16MatrixColumnSums7computeERKjRNS_11multicolvar13AtomValuePackE238
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixColumnSums.cpp.gcov.html b/coverage/adjmat/MatrixColumnSums.cpp.gcov.html new file mode 100644 index 000000000000..dcbd5e391f41 --- /dev/null +++ b/coverage/adjmat/MatrixColumnSums.cpp.gcov.html @@ -0,0 +1,199 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixColumnSums.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixColumnSums.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithInputMatrix.h"
+      23             : #include "multicolvar/AtomValuePack.h"
+      24             : #include "AdjacencyMatrixVessel.h"
+      25             : #include "AdjacencyMatrixBase.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/ActionSet.h"
+      29             : 
+      30             : //+PLUMEDOC MATRIXF COLUMNSUMS
+      31             : /*
+      32             : Sum the columns of a contact matrix
+      33             : 
+      34             : As discussed in the section of the manual on \ref contactmatrix a useful tool for developing complex collective variables is the notion of the
+      35             : so called adjacency matrix.  An adjacency matrix is an \f$N \times N\f$ matrix in which the \f$i\f$th, \f$j\f$th element tells you whether
+      36             : or not the \f$i\f$th and \f$j\f$th atoms/molecules from a set of \f$N\f$ atoms/molecules are adjacent or not.  This action allows you to calculate
+      37             : the sum of the columns in this adjacency matrix and to then calculate further functions of these quantities.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : The first instruction in the following input file tells PLUMED to compute a \f$10 \times 10\f$ matrix in which the \f$ij\f$-element
+      42             : tells you whether atoms \f$i\f$ and \f$j\f$ are within 1.0 nm of each other.  The numbers in each of this rows are then added together
+      43             : and the average value is computed.  As such the following input provides an alternative method for calculating the coordination numbers
+      44             : of atoms 1 to 10.
+      45             : 
+      46             : \plumedfile
+      47             : mat: CONTACT_MATRIX ATOMS=1-10 SWITCH={RATIONAL R_0=1.0}
+      48             : rsums: COLUMNSUMS MATRIX=mat MEAN
+      49             : PRINT ARG=rsums.* FILE=colvar
+      50             : \endplumedfile
+      51             : 
+      52             : The following input demonstrates another way that an average coordination number can be computed.  This input calculates the number of atoms
+      53             : with indices between 1 and 5 that are within the first coordination spheres of each of the atoms within indices between 6 and 15.  The average
+      54             : coordination number is then calculated from these fifteen coordination numbers and this quantity is output to a file.
+      55             : 
+      56             : \plumedfile
+      57             : mat2: CONTACT_MATRIX ATOMSA=1-5 ATOMSB=6-15 SWITCH={RATIONAL R_0=1.0}
+      58             : rsums: COLUMNSUMS MATRIX=mat2 MEAN
+      59             : PRINT ARG=rsums.* FILE=colvar
+      60             : \endplumedfile
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : namespace PLMD {
+      66             : namespace adjmat {
+      67             : 
+      68             : class MatrixColumnSums : public ActionWithInputMatrix {
+      69             : public:
+      70             :   static void registerKeywords( Keywords& keys );
+      71             :   explicit MatrixColumnSums(const ActionOptions&);
+      72             :   double compute( const unsigned& tinded, multicolvar::AtomValuePack& myatoms ) const override;
+      73             : };
+      74             : 
+      75             : PLUMED_REGISTER_ACTION(MatrixColumnSums,"COLUMNSUMS")
+      76             : 
+      77           7 : void MatrixColumnSums::registerKeywords( Keywords& keys ) {
+      78           7 :   ActionWithInputMatrix::registerKeywords( keys );
+      79          21 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      80          28 :   keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN");
+      81          28 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      82           7 : }
+      83             : 
+      84           5 : MatrixColumnSums::MatrixColumnSums(const ActionOptions& ao):
+      85             :   Action(ao),
+      86           5 :   ActionWithInputMatrix(ao)
+      87             : {
+      88           5 :   if( (mymatrix->getMatrixAction())->mybasemulticolvars.size()>0 ) error("matrix row sums should only be calculated when inputs are atoms");
+      89             :   // Setup the tasks
+      90           5 :   unsigned ncols = mymatrix->getNumberOfColumns();
+      91           5 :   ablocks.resize(1); ablocks[0].resize( ncols );
+      92         155 :   for(unsigned i=0; i<ncols; ++i) addTaskToList( i );
+      93             :   // Set the positions - this is only used when getting positions for central atoms
+      94           5 :   if( mymatrix->undirectedGraph() ) {
+      95         144 :     for(unsigned i=0; i<ncols; ++i) ablocks[0][i]=i;
+      96             :   } else {
+      97          11 :     for(unsigned i=0; i<ncols; ++i) ablocks[0][i]=mymatrix->getNumberOfRows() + i;
+      98             :   }
+      99           5 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     100           5 : }
+     101             : 
+     102         238 : double MatrixColumnSums::compute( const unsigned& tinded, multicolvar::AtomValuePack& myatoms ) const {
+     103         238 :   double sum=0.0; std::vector<double> tvals( mymatrix->getNumberOfComponents() );
+     104         238 :   unsigned nrows = mymatrix->getNumberOfRows();
+     105        9200 :   for(unsigned i=0; i<nrows; ++i) {
+     106        8962 :     if( mymatrix->undirectedGraph() && tinded==i ) continue;
+     107        8774 :     sum+=retrieveConnectionValue( i, tinded, tvals );
+     108             :   }
+     109             : 
+     110         238 :   if( !doNotCalculateDerivatives() ) {
+     111         110 :     MultiValue myvals( mymatrix->getNumberOfComponents(), myatoms.getNumberOfDerivatives() );
+     112             :     MultiValue& myvout=myatoms.getUnderlyingMultiValue();
+     113         880 :     for(unsigned i=0; i<nrows; ++i) {
+     114         770 :       if( mymatrix->isSymmetric() && tinded==i ) continue ;
+     115         710 :       addConnectionDerivatives( i, tinded, myvals, myvout );
+     116             :     }
+     117         110 :   }
+     118         238 :   return sum;
+     119             : }
+     120             : 
+     121             : }
+     122             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixRowSums.cpp.func-sort-c.html b/coverage/adjmat/MatrixRowSums.cpp.func-sort-c.html new file mode 100644 index 000000000000..eab657f3b4f3 --- /dev/null +++ b/coverage/adjmat/MatrixRowSums.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixRowSums.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixRowSums.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13MatrixRowSumsC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat13MatrixRowSumsC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat13MatrixRowSums16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD6adjmat13MatrixRowSums7computeERKjRNS_11multicolvar13AtomValuePackE203
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixRowSums.cpp.func.html b/coverage/adjmat/MatrixRowSums.cpp.func.html new file mode 100644 index 000000000000..3b8acd776683 --- /dev/null +++ b/coverage/adjmat/MatrixRowSums.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixRowSums.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixRowSums.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13MatrixRowSums16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6adjmat13MatrixRowSumsC1ERKNS_13ActionOptionsE4
_ZN4PLMD6adjmat13MatrixRowSumsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat13MatrixRowSums7computeERKjRNS_11multicolvar13AtomValuePackE203
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/MatrixRowSums.cpp.gcov.html b/coverage/adjmat/MatrixRowSums.cpp.gcov.html new file mode 100644 index 000000000000..482d6fb7202a --- /dev/null +++ b/coverage/adjmat/MatrixRowSums.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/MatrixRowSums.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - MatrixRowSums.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithInputMatrix.h"
+      23             : #include "multicolvar/AtomValuePack.h"
+      24             : #include "AdjacencyMatrixVessel.h"
+      25             : #include "AdjacencyMatrixBase.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/ActionSet.h"
+      29             : 
+      30             : //+PLUMEDOC MATRIXF ROWSUMS
+      31             : /*
+      32             : Sum the rows of a adjacency matrix.
+      33             : 
+      34             : As discussed in the section of the manual on \ref contactmatrix a useful tool for developing complex collective variables is the notion of the
+      35             : so called adjacency matrix.  An adjacency matrix is an \f$N \times N\f$ matrix in which the \f$i\f$th, \f$j\f$th element tells you whether
+      36             : or not the \f$i\f$th and \f$j\f$th atoms/molecules from a set of \f$N\f$ atoms/molecules are adjacent or not.  This action allows you to calculate
+      37             : the sum of the rows in this adjacency matrix and to then calculate further functions of these quantities.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : The first instruction in the following input file tells PLUMED to compute a \f$10 \times 10\f$ matrix in which the \f$ij\f$-element
+      42             : tells you whether atoms \f$i\f$ and \f$j\f$ are within 1.0 nm of each other.  The numbers in each of this rows are then added together
+      43             : and the average value is computed.  As such the following input provides an alternative method for calculating the coordination numbers
+      44             : of atoms 1 to 10.
+      45             : 
+      46             : \plumedfile
+      47             : mat: CONTACT_MATRIX ATOMS=1-10 SWITCH={RATIONAL R_0=1.0}
+      48             : rsums: ROWSUMS MATRIX=mat MEAN
+      49             : PRINT ARG=rsums.* FILE=colvar
+      50             : \endplumedfile
+      51             : 
+      52             : The following input demonstrates another way that an average coordination number can be computed.  This input calculates the number of atoms
+      53             : with indices between 6 and 15 that are within the first coordination spheres of each of the atoms within indices between 1 and 5.  The average
+      54             : coordination number is then calculated from these five coordination numbers and this quantity is output to a file.
+      55             : 
+      56             : \plumedfile
+      57             : mat2: CONTACT_MATRIX ATOMSA=1-5 ATOMSB=6-15 SWITCH={RATIONAL R_0=1.0}
+      58             : rsums: ROWSUMS MATRIX=mat2 MEAN
+      59             : PRINT ARG=rsums.* FILE=colvar
+      60             : \endplumedfile
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : namespace PLMD {
+      66             : namespace adjmat {
+      67             : 
+      68             : class MatrixRowSums : public ActionWithInputMatrix {
+      69             : public:
+      70             :   static void registerKeywords( Keywords& keys );
+      71             :   explicit MatrixRowSums(const ActionOptions&);
+      72             :   double compute( const unsigned& tinded, multicolvar::AtomValuePack& myatoms ) const override;
+      73             : };
+      74             : 
+      75             : PLUMED_REGISTER_ACTION(MatrixRowSums,"ROWSUMS")
+      76             : 
+      77           6 : void MatrixRowSums::registerKeywords( Keywords& keys ) {
+      78           6 :   ActionWithInputMatrix::registerKeywords( keys );
+      79          18 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      80          24 :   keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN");
+      81          24 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      82           6 : }
+      83             : 
+      84           4 : MatrixRowSums::MatrixRowSums(const ActionOptions& ao):
+      85             :   Action(ao),
+      86           4 :   ActionWithInputMatrix(ao)
+      87             : {
+      88           4 :   if( (mymatrix->getMatrixAction())->mybasemulticolvars.size()>0 ) warning("matrix row may be problematic when inputs are not atoms");
+      89             :   // Setup the tasks
+      90           4 :   unsigned nrows = mymatrix->getNumberOfRows();
+      91           4 :   ablocks.resize(1); ablocks[0].resize( nrows );
+      92         147 :   for(unsigned i=0; i<nrows; ++i) { ablocks[0][i]=i; addTaskToList( i ); }
+      93           4 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+      94           4 : }
+      95             : 
+      96         203 : double MatrixRowSums::compute( const unsigned& tinded, multicolvar::AtomValuePack& myatoms ) const {
+      97         203 :   std::vector<double> tvals( mymatrix->getNumberOfComponents() );
+      98         203 :   getInputData( tinded, false, myatoms, tvals ); double fval=tvals[1];
+      99             : 
+     100         203 :   if( !doNotCalculateDerivatives() ) {
+     101          75 :     tvals.assign( tvals.size(), 0 ); tvals[1]=1.0;
+     102          75 :     mergeInputDerivatives( 1, 1, 2, tinded, tvals, getInputDerivatives( tinded, false, myatoms ), myatoms );
+     103             :   }
+     104         203 :   return fval;
+     105             : }
+     106             : 
+     107             : }
+     108             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/OutputCluster.cpp.func-sort-c.html b/coverage/adjmat/OutputCluster.cpp.func-sort-c.html new file mode 100644 index 000000000000..6379b56394f0 --- /dev/null +++ b/coverage/adjmat/OutputCluster.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/OutputCluster.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - OutputCluster.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:408646.5 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13OutputCluster11explore_dfsERKj0
_ZN4PLMD6adjmat13OutputCluster7exploreERKjS3_0
_ZN4PLMD6adjmat13OutputClusterC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat13OutputCluster5applyEv8
_ZN4PLMD6adjmat13OutputCluster6updateEv8
_ZN4PLMD6adjmat13OutputCluster9calculateEv8
_ZN4PLMD6adjmat13OutputClusterC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat13OutputCluster16registerKeywordsERNS_8KeywordsE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/OutputCluster.cpp.func.html b/coverage/adjmat/OutputCluster.cpp.func.html new file mode 100644 index 000000000000..5618780f0842 --- /dev/null +++ b/coverage/adjmat/OutputCluster.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/OutputCluster.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - OutputCluster.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:408646.5 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat13OutputCluster11explore_dfsERKj0
_ZN4PLMD6adjmat13OutputCluster16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6adjmat13OutputCluster5applyEv8
_ZN4PLMD6adjmat13OutputCluster6updateEv8
_ZN4PLMD6adjmat13OutputCluster7exploreERKjS3_0
_ZN4PLMD6adjmat13OutputCluster9calculateEv8
_ZN4PLMD6adjmat13OutputClusterC1ERKNS_13ActionOptionsE8
_ZN4PLMD6adjmat13OutputClusterC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/OutputCluster.cpp.gcov.html b/coverage/adjmat/OutputCluster.cpp.gcov.html new file mode 100644 index 000000000000..6dba57c061c5 --- /dev/null +++ b/coverage/adjmat/OutputCluster.cpp.gcov.html @@ -0,0 +1,310 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/OutputCluster.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - OutputCluster.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:408646.5 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ClusteringBase.h"
+      23             : #include "tools/OFile.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "core/ActionPilot.h"
+      27             : #include "core/ActionRegister.h"
+      28             : 
+      29             : //+PLUMEDOC CONCOMP OUTPUT_CLUSTER
+      30             : /*
+      31             : Output the indices of the atoms in one of the clusters identified by a clustering object
+      32             : 
+      33             : This action provides one way of getting output from a \ref DFSCLUSTERING calculation.
+      34             : The output in question here is either
+      35             : 
+      36             : - a file that contains a list of the atom indices that form part of one of the clusters that was identified using \ref DFSCLUSTERING
+      37             : - an xyz file containing the positions of the atoms in one of the the clusters that was identified using \ref DFSCLUSTERING
+      38             : 
+      39             : Notice also that if you choose to output an xyz file you can ask PLUMED to try to reconstruct the cluster
+      40             : taking the periodic boundary conditions into account by using the MAKE_WHOLE flag.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : The input shown below identifies those atoms with a coordination number less than 13
+      45             : and then constructs a contact matrix that describes the connectivity between the atoms
+      46             : that satisfy this criteria.  The DFS algorithm is then used to find the connected components
+      47             : in this matrix and the indices of the atoms in the largest connected component are then output
+      48             : to a file.
+      49             : 
+      50             : \plumedfile
+      51             : c1: COORDINATIONNUMBER SPECIES=1-1996 SWITCH={CUBIC D_0=0.34 D_MAX=0.38}
+      52             : cf: MFILTER_LESS DATA=c1 SWITCH={CUBIC D_0=13 D_MAX=13.5}
+      53             : mat: CONTACT_MATRIX ATOMS=cf SWITCH={CUBIC D_0=0.34 D_MAX=0.38}
+      54             : dfs: DFSCLUSTERING MATRIX=mat
+      55             : OUTPUT_CLUSTER CLUSTERS=dfs CLUSTER=1 FILE=dfs.dat
+      56             : \endplumedfile
+      57             : 
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : namespace PLMD {
+      62             : namespace adjmat {
+      63             : 
+      64             : class OutputCluster : public ActionPilot {
+      65             : private:
+      66             :   bool makewhole, output_xyz;
+      67             :   OFile ofile;
+      68             :   ClusteringBase* myclusters;
+      69             :   double rcut2;
+      70             :   unsigned clustr, maxdepth, maxgoes;
+      71             :   std::vector<bool> visited;
+      72             :   std::vector<unsigned> myatoms;
+      73             :   std::vector<Vector> atomsin;
+      74             :   std::vector<unsigned> nneigh;
+      75             :   Matrix<unsigned> adj_list;
+      76             :   int number_of_cluster;
+      77             :   std::vector< std::pair<unsigned,unsigned> > cluster_sizes;
+      78             :   std::vector<unsigned> which_cluster;
+      79             :   bool explore_dfs( const unsigned& index );
+      80             :   void explore( const unsigned& index, const unsigned& depth );
+      81             : public:
+      82             :   static void registerKeywords( Keywords& keys );
+      83             :   explicit OutputCluster(const ActionOptions&);
+      84           8 :   void calculate() override {}
+      85           8 :   void apply() override {}
+      86             :   void update() override;
+      87             : };
+      88             : 
+      89             : PLUMED_REGISTER_ACTION(OutputCluster,"OUTPUT_CLUSTER")
+      90             : 
+      91          10 : void OutputCluster::registerKeywords( Keywords& keys ) {
+      92          10 :   Action::registerKeywords( keys );
+      93          10 :   ActionPilot::registerKeywords( keys );
+      94          20 :   keys.add("compulsory","CLUSTERS","the action that performed the clustering");
+      95          20 :   keys.add("compulsory","CLUSTER","1","which cluster would you like to look at 1 is the largest cluster, 2 is the second largest, 3 is the the third largest and so on");
+      96          20 :   keys.add("compulsory","STRIDE","1","the frequency with which you would like to output the atoms in the cluster");
+      97          20 :   keys.add("compulsory","FILE","the name of the file on which to output the details of the cluster");
+      98          20 :   keys.add("compulsory","MAXDEPTH","6","maximum depth for searches over paths to reconstruct clusters for PBC");
+      99          20 :   keys.add("compulsory","MAXGOES","200","number of times to run searches to reconstruct clusters");
+     100          20 :   keys.addFlag("MAKE_WHOLE",false,"reconstruct the clusters and remove all periodic boundary conditions.");
+     101          10 : }
+     102             : 
+     103           8 : OutputCluster::OutputCluster(const ActionOptions& ao):
+     104             :   Action(ao),
+     105             :   ActionPilot(ao),
+     106           8 :   myclusters(NULL)
+     107             : {
+     108             :   // Setup output file
+     109          16 :   ofile.link(*this); std::string file; parse("FILE",file);
+     110           8 :   if( file.length()==0 ) error("output file name was not specified");
+     111             :   // Search for xyz extension
+     112           8 :   output_xyz=false;
+     113           8 :   if( file.find(".")!=std::string::npos ) {
+     114             :     std::size_t dot=file.find_first_of('.');
+     115          16 :     if( file.substr(dot+1)=="xyz" ) output_xyz=true;
+     116             :   }
+     117             : 
+     118           8 :   ofile.open(file); log.printf("  on file %s \n",file.c_str());
+     119          24 :   parseFlag("MAKE_WHOLE",makewhole); parse("MAXDEPTH",maxdepth); parse("MAXGOES",maxgoes);
+     120           8 :   if( makewhole && !output_xyz) error("MAKE_WHOLE flag is not compatible with output of non-xyz files");
+     121             : 
+     122             :   // Find what action we are taking the clusters from
+     123           8 :   std::vector<std::string> matname(1); parse("CLUSTERS",matname[0]);
+     124           8 :   myclusters = plumed.getActionSet().selectWithLabel<ClusteringBase*>( matname[0] );
+     125           8 :   if( !myclusters ) error( matname[0] + " does not calculate perform a clustering of the atomic positions");
+     126             :   // N.B. the +0.3 is a fudge factor.  Reconstrucing PBC doesnt work without this GAT
+     127           8 :   addDependency( myclusters ); double rcut=myclusters->getCutoffForConnection() + 0.3; rcut2=rcut*rcut;
+     128             : 
+     129             :   // Read in the cluster we are calculating
+     130           8 :   parse("CLUSTER",clustr);
+     131           8 :   if( clustr<1 ) error("cannot look for a cluster larger than the largest cluster");
+     132           8 :   if( clustr>myclusters->getNumberOfNodes() ) error("cluster selected is invalid - too few atoms in system");
+     133           8 :   log.printf("  outputting atoms in %u th largest cluster found by %s \n",clustr,matname[0].c_str() );
+     134          16 : }
+     135             : 
+     136           8 : void OutputCluster::update() {
+     137           8 :   myclusters->retrieveAtomsInCluster( clustr, myatoms );
+     138           8 :   if( output_xyz ) {
+     139           0 :     ofile.printf("%u \n",static_cast<unsigned>(myatoms.size()));
+     140           0 :     ofile.printf("atoms in %u th largest cluster \n",clustr );
+     141           0 :     if( makewhole ) {
+     142             :       // Retrieve the atom positions
+     143           0 :       atomsin.resize( myatoms.size() );
+     144           0 :       for(unsigned i=0; i<myatoms.size(); ++i) atomsin[i]=myclusters->getPositionOfAtomForLinkCells( myatoms[i] );
+     145             :       // Build a connectivity matrix neglecting the pbc
+     146           0 :       nneigh.resize( myatoms.size(), 0 ); adj_list.resize( myatoms.size(), myatoms.size() );
+     147           0 :       for(unsigned i=1; i<myatoms.size(); ++i) {
+     148           0 :         for(unsigned j=0; j<i; ++j) {
+     149           0 :           if( delta( atomsin[i], atomsin[j] ).modulo2()<=rcut2 ) { adj_list(i,nneigh[i])=j; adj_list(j,nneigh[j])=i; nneigh[i]++; nneigh[j]++; }
+     150             :         }
+     151             :       }
+     152             :       // Use DFS to find the largest cluster not broken by PBC
+     153           0 :       number_of_cluster=-1; visited.resize( myatoms.size(), false );
+     154           0 :       cluster_sizes.resize( myatoms.size() ); which_cluster.resize( myatoms.size() );
+     155           0 :       for(unsigned i=0; i<cluster_sizes.size(); ++i) { cluster_sizes[i].first=0; cluster_sizes[i].second=i; }
+     156             : 
+     157           0 :       for(unsigned i=0; i<myatoms.size(); ++i) {
+     158           0 :         if( !visited[i] ) { number_of_cluster++; visited[i]=explore_dfs(i); }
+     159             :       }
+     160           0 :       std::sort( cluster_sizes.begin(), cluster_sizes.end() );
+     161             : 
+     162             :       // Now set visited so that only those atoms in largest cluster will be start points for PBCing
+     163             :       visited.assign( visited.size(), false );
+     164           0 :       for(unsigned i=0; i<myatoms.size(); ++i) {
+     165           0 :         if( which_cluster[i]==cluster_sizes[cluster_sizes.size()-1].second ) visited[i]=true;
+     166             :       }
+     167             : 
+     168             :       // Now retrieve the original connectivity matrix (including pbc)
+     169           0 :       nneigh.assign( nneigh.size(), 0 );
+     170           0 :       for(unsigned i=1; i<myatoms.size(); ++i) {
+     171           0 :         for(unsigned j=0; j<i; ++j) {
+     172           0 :           if( myclusters->areConnected( myatoms[i], myatoms[j] ) ) { adj_list(i,nneigh[i])=j; adj_list(j,nneigh[j])=i; nneigh[i]++; nneigh[j]++; }
+     173             :         }
+     174             :       }
+     175             : 
+     176             :       // Now find broken bonds and run iterative deepening depth first search to reconstruct
+     177           0 :       for(unsigned jj=0; jj<maxgoes; ++jj) {
+     178             : 
+     179           0 :         for(unsigned j=0; j<myatoms.size(); ++j) {
+     180           0 :           if( !visited[j] ) continue;
+     181             : 
+     182           0 :           for(unsigned k=0; k<nneigh[j]; ++k) {
+     183           0 :             if( delta( atomsin[j],atomsin[adj_list(j,k)] ).modulo2()>rcut2 ) {
+     184             :               visited[j]=true;
+     185           0 :               for(unsigned depth=0; depth<=maxdepth; ++depth) explore( j, depth );
+     186             :             }
+     187             :           }
+     188             :         }
+     189             :       }
+     190             :       // And print final positions
+     191           0 :       for(unsigned i=0; i<myatoms.size(); ++i) ofile.printf( "X %f %f %f \n", atomsin[i][0], atomsin[i][1], atomsin[i][2] );
+     192             :     } else {
+     193           0 :       for(unsigned i=0; i<myatoms.size(); ++i) {
+     194           0 :         Vector pos=myclusters->getPositionOfAtomForLinkCells( myatoms[i] );
+     195           0 :         ofile.printf( "X %f %f %f \n", pos[0], pos[1], pos[2] );
+     196             :       }
+     197             :     }
+     198             :   } else {
+     199           8 :     ofile.printf("CLUSTERING RESULTS AT TIME %f : NUMBER OF ATOMS IN %u TH LARGEST CLUSTER EQUALS %u \n",getTime(),clustr,static_cast<unsigned>(myatoms.size()) );
+     200           8 :     ofile.printf("INDICES OF ATOMS : ");
+     201         512 :     for(unsigned i=0; i<myatoms.size(); ++i) ofile.printf("%d ",(myclusters->getAbsoluteIndexOfCentralAtom(myatoms[i])).index());
+     202           8 :     ofile.printf("\n");
+     203             :   }
+     204           8 : }
+     205             : 
+     206           0 : void OutputCluster::explore( const unsigned& index, const unsigned& depth ) {
+     207           0 :   if( depth==0 ) return ;
+     208             : 
+     209           0 :   for(unsigned i=0; i<nneigh[index]; ++i) {
+     210           0 :     unsigned j=adj_list(index,i); visited[j]=true;
+     211           0 :     Vector svec=myclusters->pbcDistance( atomsin[index], atomsin[j] );
+     212           0 :     atomsin[j] = atomsin[index] + svec;
+     213           0 :     explore( j, depth-1 );
+     214             :   }
+     215             : }
+     216             : 
+     217           0 : bool OutputCluster::explore_dfs( const unsigned& index ) {
+     218           0 :   visited[index]=true;
+     219           0 :   for(unsigned i=0; i<nneigh[index]; ++i) {
+     220           0 :     unsigned j=adj_list(index,i);
+     221           0 :     if( !visited[j] ) visited[j]=explore_dfs(j);
+     222             :   }
+     223             : 
+     224             :   // Count the size of the cluster
+     225           0 :   cluster_sizes[number_of_cluster].first++;
+     226           0 :   which_cluster[index] = number_of_cluster;
+     227           0 :   return visited[index];
+     228             : }
+     229             : 
+     230             : }
+     231             : }
+     232             : 
+     233             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/SMACMatrix.cpp.func-sort-c.html b/coverage/adjmat/SMACMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..71993fb6f1c9 --- /dev/null +++ b/coverage/adjmat/SMACMatrix.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/SMACMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - SMACMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3434100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat10SMACMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat10SMACMatrix24readOrientationConnectorERKjS3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE1
_ZN4PLMD6adjmat10SMACMatrixC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat10SMACMatrix16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD6adjmat10SMACMatrix21computeVectorFunctionERKjS3_RKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_5806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/SMACMatrix.cpp.func.html b/coverage/adjmat/SMACMatrix.cpp.func.html new file mode 100644 index 000000000000..0debb4588f5b --- /dev/null +++ b/coverage/adjmat/SMACMatrix.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/SMACMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - SMACMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3434100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat10SMACMatrix16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat10SMACMatrix24readOrientationConnectorERKjS3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE1
_ZN4PLMD6adjmat10SMACMatrixC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat10SMACMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat10SMACMatrix21computeVectorFunctionERKjS3_RKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_5806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/SMACMatrix.cpp.gcov.html b/coverage/adjmat/SMACMatrix.cpp.gcov.html new file mode 100644 index 000000000000..3b1ad4a8b4da --- /dev/null +++ b/coverage/adjmat/SMACMatrix.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/SMACMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - SMACMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3434100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AlignedMatrixBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/KernelFunctions.h"
+      25             : #include "tools/Torsion.h"
+      26             : #include "tools/Matrix.h"
+      27             : 
+      28             : //+PLUMEDOC MATRIX SMAC_MATRIX
+      29             : /*
+      30             : Adjacency matrix in which two molecules are adjacent if they are within a certain cutoff and if the angle between them is within certain ranges.
+      31             : 
+      32             : In this case the elements of the adjacency matrix are calculated using:
+      33             : 
+      34             : \f[
+      35             : A_{ij} = \sigma(r_{ij}) \sum_n K_n(\theta_{ij})
+      36             : \f]
+      37             : 
+      38             : In this expression \f$r_{ij}\f$ is the distance between molecule \f$i\f$ and molecule \f$j\f$ and \f$\sigma(r_{ij}\f$ is a
+      39             : \ref switchingfunction that acts on this distance.  The $K_n functions are \ref kernelfunctions that take the torsion angle, \f$\theta_{ij}\f$, between the
+      40             : internal orientation vectors for molecules \f$i\f$ and \f$j\f$ as input.  These kernel functions should be set so that they are
+      41             : equal to one when the relative orientation of the molecules are as they are in the solid and equal to zero otherwise.
+      42             : As the above matrix element is a product of functions it is only equal to one when the centers of mass of molecules \f$i\f$ and\f$j\f$
+      43             : are with a certain distance of each other and when the molecules are aligned in some desirable way.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : In the following example an adjacency matrix is constructed in which the \f$(i,j)\f$ element is equal to one if
+      48             : molecules \f$i\f$ and \f$j\f$ are within 6 angstroms of each other and if the torsional angle between the orientations
+      49             : of these molecules is close to 0 or \f$\pi\f$.  The various connected components of this matrix are determined using the
+      50             : \ref DFSCLUSTERING algorithm and then the size of the largest cluster of connects molecules is output to a colvar file
+      51             : 
+      52             : \plumedfile
+      53             : UNITS LENGTH=A
+      54             : 
+      55             : MOLECULES ...
+      56             : MOL1=1,2,1
+      57             : MOL2=5,6,5
+      58             : MOL3=9,10,9
+      59             : MOL4=13,14,13
+      60             : MOL5=17,18,17
+      61             : LABEL=m1
+      62             : ... MOLECULES
+      63             : 
+      64             : SMAC_MATRIX ...
+      65             :    ATOMS=m1 SWITCH={RATIONAL D_0=5.99 R_0=0.1 D_MAX=6.0}
+      66             :    KERNEL1={TRIANGULAR CENTER=0 SIGMA=1.0} KERNEL2={TRIANGULAR CENTER=pi SIGMA=0.6}
+      67             :    LABEL=smac
+      68             : ... SMAC_MATRIX
+      69             : 
+      70             : dfs1: DFSCLUSTERING MATRIX=smac
+      71             : cc2: CLUSTER_NATOMS CLUSTERS=dfs1 CLUSTER=1
+      72             : PRINT ARG=cc2 FILE=colvar
+      73             : \endplumedfile
+      74             : 
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : 
+      78             : namespace PLMD {
+      79             : namespace adjmat {
+      80             : 
+      81             : class SMACMatrix : public AlignedMatrixBase {
+      82             : private:
+      83             :   Matrix<std::vector<KernelFunctions> > kernels;
+      84             : public:
+      85             :   ///
+      86             :   static void registerKeywords( Keywords& keys );
+      87             :   ///
+      88             :   explicit SMACMatrix(const ActionOptions&);
+      89             :   void readOrientationConnector( const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) override;
+      90             :   double computeVectorFunction( const unsigned& iv, const unsigned& jv,
+      91             :                                 const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+      92             :                                 Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const override;
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(SMACMatrix,"SMAC_MATRIX")
+      96             : 
+      97           3 : void SMACMatrix::registerKeywords( Keywords& keys ) {
+      98           3 :   AlignedMatrixBase::registerKeywords( keys );
+      99           6 :   keys.add("numbered","KERNEL","The various kernels that are used to determine whether or not the molecules are aligned");
+     100           3 : }
+     101             : 
+     102           1 : SMACMatrix::SMACMatrix( const ActionOptions& ao ):
+     103             :   Action(ao),
+     104           1 :   AlignedMatrixBase(ao)
+     105             : {
+     106           1 :   unsigned nrows, ncols, ig; retrieveTypeDimensions( nrows, ncols, ig );
+     107           1 :   kernels.resize( nrows, ncols ); parseConnectionDescriptions("KERNEL",true,0);
+     108           1 : }
+     109             : 
+     110           1 : void SMACMatrix::readOrientationConnector( const unsigned& iv, const unsigned& jv, const std::vector<std::string>& desc ) {
+     111           3 :   for(int i=0; i<desc.size(); i++) {
+     112           2 :     KernelFunctions mykernel( desc[i] );
+     113           2 :     kernels(iv,jv).push_back( mykernel );
+     114           2 :     if( jv!=iv ) kernels(jv,iv).push_back( mykernel );
+     115             :   }
+     116           1 :   if( kernels(iv,jv).size()==0 ) error("no kernels defined");
+     117           1 : }
+     118             : 
+     119        5806 : double SMACMatrix::computeVectorFunction( const unsigned& iv, const unsigned& jv,
+     120             :     const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+     121             :     Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const {
+     122             : 
+     123        5806 :   unsigned nvectors = ( vec1.size() - 2 ) / 3; plumed_assert( (vec1.size()-2)%3==0 );
+     124        5806 :   std::vector<Vector> dv1(nvectors), dv2(nvectors), tdconn(nvectors); Torsion t; std::vector<Vector> v1(nvectors), v2(nvectors);
+     125             :   std::vector<std::unique_ptr<Value>> pos;
+     126       17418 :   for(unsigned i=0; i<nvectors; ++i) { pos.emplace_back( Tools::make_unique<Value>() ); pos[i]->setDomain( "-pi", "pi" ); }
+     127             : 
+     128       11612 :   for(unsigned j=0; j<nvectors; ++j) {
+     129       23224 :     for(unsigned k=0; k<3; ++k) {
+     130       17418 :       v1[j][k]=vec1[2+3*j+k]; v2[j][k]=vec2[2+3*j+k];
+     131             :     }
+     132        5806 :     double angle = t.compute( v1[j], conn, v2[j], dv1[j], tdconn[j], dv2[j] );
+     133             :     pos[j]->set( angle );
+     134             :   }
+     135             : 
+     136        5806 :   double ans=0; std::vector<double> deriv( nvectors ), df( nvectors, 0 );
+     137             : 
+     138        5806 :   auto pos_ptr=Tools::unique2raw(pos);
+     139             : 
+     140       17418 :   for(unsigned i=0; i<kernels(iv,jv).size(); ++i) {
+     141       11612 :     ans += kernels(iv,jv)[i].evaluate( pos_ptr, deriv );
+     142       23224 :     for(unsigned j=0; j<nvectors; ++j) df[j] += deriv[j];
+     143             :   }
+     144       11612 :   dconn.zero(); for(unsigned j=0; j<nvectors; ++j) dconn += df[j]*tdconn[j];
+     145       11612 :   for(unsigned j=0; j<nvectors; ++j) {
+     146       23224 :     for(unsigned k=0; k<3; ++k) { dvec1[2+3*j+k]=df[j]*dv1[j][k]; dvec2[2+3*j+k]=df[j]*dv2[j][k]; }
+     147             :   }
+     148        5806 :   return ans;
+     149        5806 : }
+     150             : 
+     151             : }
+     152             : }
+     153             : 
+     154             : 
+     155             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Sprint.cpp.func-sort-c.html b/coverage/adjmat/Sprint.cpp.func-sort-c.html new file mode 100644 index 000000000000..6cb49cd06097 --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Sprint.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Sprint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626496.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat6SprintC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat6SprintC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat6Sprint16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat6Sprint5applyEv17
_ZN4PLMD6adjmat6Sprint9calculateEv17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Sprint.cpp.func.html b/coverage/adjmat/Sprint.cpp.func.html new file mode 100644 index 000000000000..53928224ac4d --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Sprint.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Sprint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626496.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat6Sprint16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6adjmat6Sprint5applyEv17
_ZN4PLMD6adjmat6Sprint9calculateEv17
_ZN4PLMD6adjmat6SprintC1ERKNS_13ActionOptionsE1
_ZN4PLMD6adjmat6SprintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/Sprint.cpp.gcov.html b/coverage/adjmat/Sprint.cpp.gcov.html new file mode 100644 index 000000000000..2743409ecf0a --- /dev/null +++ b/coverage/adjmat/Sprint.cpp.gcov.html @@ -0,0 +1,306 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/Sprint.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - Sprint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626496.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithInputMatrix.h"
+      23             : #include "AdjacencyMatrixVessel.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : //+PLUMEDOC MATRIXF SPRINT
+      27             : /*
+      28             : Calculate SPRINT topological variables from an adjacency matrix.
+      29             : 
+      30             : The SPRINT topological variables are calculated from the largest eigenvalue, \f$\lambda\f$ of
+      31             : an \f$n\times n\f$ adjacency matrix and its corresponding eigenvector, \f$\mathbf{V}\f$, using:
+      32             : 
+      33             : \f[
+      34             : s_i = \sqrt{n} \lambda v_i
+      35             : \f]
+      36             : 
+      37             : You can use different quantities to measure whether or not two given atoms/molecules are
+      38             : adjacent or not in the adjacency matrix.  The simplest measure of adjacency is is whether
+      39             : two atoms/molecules are within some cutoff of each other.  Further complexity can be added by
+      40             : insisting that two molecules are adjacent if they are within a certain distance of each
+      41             : other and if they have similar orientations.
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : This example input calculates the 7 SPRINT coordinates for a 7 atom cluster of Lennard-Jones
+      46             : atoms and prints their values to a file.  In this input the SPRINT coordinates are calculated
+      47             : in the manner described in \cite Pietrucci2011 so two atoms are adjacent if they are within a cutoff:
+      48             : 
+      49             : \plumedfile
+      50             : DENSITY SPECIES=1-7 LABEL=d1
+      51             : CONTACT_MATRIX ATOMS=d1 SWITCH={RATIONAL R_0=0.1} LABEL=mat
+      52             : SPRINT MATRIX=mat LABEL=ss
+      53             : PRINT ARG=ss.* FILE=colvar
+      54             : \endplumedfile
+      55             : 
+      56             : This example input calculates the 14 SPRINT coordinates for a molecule composed of 7 hydrogen and
+      57             : 7 carbon atoms.  Once again two atoms are adjacent if they are within a cutoff:
+      58             : 
+      59             : \plumedfile
+      60             : DENSITY SPECIES=1-7 LABEL=c
+      61             : DENSITY SPECIES=8-14 LABEL=h
+      62             : 
+      63             : CONTACT_MATRIX ...
+      64             :   ATOMS=c,h
+      65             :   SWITCH11={RATIONAL R_0=2.6 NN=6 MM=12}
+      66             :   SWITCH12={RATIONAL R_0=2.2 NN=6 MM=12}
+      67             :   SWITCH22={RATIONAL R_0=2.2 NN=6 MM=12}
+      68             :   LABEL=mat
+      69             : ... CONTACT_MATRIX
+      70             : 
+      71             : SPRINT MATRIX=mat LABEL=ss
+      72             : 
+      73             : PRINT ARG=ss.* FILE=colvar
+      74             : \endplumedfile
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : 
+      80             : namespace PLMD {
+      81             : namespace adjmat {
+      82             : 
+      83             : class Sprint : public ActionWithInputMatrix {
+      84             : private:
+      85             : /// Square root of number of atoms
+      86             :   double sqrtn;
+      87             : /// Vector that stores eigenvalues
+      88             :   std::vector<double> eigvals;
+      89             : /// This is used to speed up the calculation of derivatives
+      90             :   DynamicList<unsigned> active_elements;
+      91             : /// Vector that stores max eigenvector
+      92             :   std::vector< std::pair<double,int> > maxeig;
+      93             : /// Adjacency matrix
+      94             :   Matrix<double> thematrix;
+      95             : /// Matrix that stores eigenvectors
+      96             :   Matrix<double> eigenvecs;
+      97             : public:
+      98             : /// Create manual
+      99             :   static void registerKeywords( Keywords& keys );
+     100             : /// Constructor
+     101             :   explicit Sprint(const ActionOptions&);
+     102             : /// Do the matrix calculation
+     103             :   void calculate() override;
+     104             : /// Sprint needs its only apply routine as it creates values
+     105             :   void apply() override;
+     106             : };
+     107             : 
+     108             : PLUMED_REGISTER_ACTION(Sprint,"SPRINT")
+     109             : 
+     110           3 : void Sprint::registerKeywords( Keywords& keys ) {
+     111           3 :   ActionWithInputMatrix::registerKeywords( keys );
+     112           3 :   componentsAreNotOptional(keys);
+     113           6 :   keys.addOutputComponent("coord","default","all \\f$n\\f$ sprint coordinates are calculated and then stored in increasing order. "
+     114             :                           "the smallest sprint coordinate will be labeled <em>label</em>.coord-0, "
+     115             :                           "the second smallest will be labelled <em>label</em>.coord-1 and so on");
+     116           3 : }
+     117             : 
+     118           1 : Sprint::Sprint(const ActionOptions&ao):
+     119             :   Action(ao),
+     120             :   ActionWithInputMatrix(ao),
+     121           1 :   eigvals( getNumberOfNodes() ),
+     122           1 :   maxeig( getNumberOfNodes() ),
+     123           1 :   thematrix( getNumberOfNodes(), getNumberOfNodes() ),
+     124           3 :   eigenvecs( getNumberOfNodes(), getNumberOfNodes() )
+     125             : {
+     126             :   // Check on setup
+     127             :   // if( getNumberOfVessels()!=1 ) error("there should be no vessel keywords");
+     128             :   // Check for bad colvar input ( we  are going to get rid of this because we are going to have input adjacency matrix in future )
+     129             :   // for(unsigned i=0;i<getNumberOfAtomGroups();++i){
+     130             :   //    /// Check me GAT
+     131             :   //    // if( !getBaseMultiColvar(i)->hasDifferentiableOrientation() ) error("cannot use multicolvar of type " + getBaseMultiColvar(i)->getName() );
+     132             :   // }
+     133             : 
+     134           1 :   if( !getAdjacencyVessel()->isSymmetric() ) error("input contact matrix is not symmetric");
+     135           1 :   std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms );
+     136             : 
+     137             :   // Create all the values
+     138           1 :   sqrtn = std::sqrt( static_cast<double>( getNumberOfNodes() ) );
+     139          15 :   for(unsigned i=0; i<getNumberOfNodes(); ++i) {
+     140          14 :     std::string num; Tools::convert(i,num);
+     141          28 :     addComponentWithDerivatives("coord-"+num);
+     142          14 :     componentIsNotPeriodic("coord-"+num);
+     143          14 :     getPntrToComponent(i)->resizeDerivatives( getNumberOfDerivatives() );
+     144             :   }
+     145             : 
+     146             :   // Setup the dynamic list to hold all the tasks
+     147           1 :   unsigned ntriangle = 0.5*getNumberOfNodes()*(getNumberOfNodes()-1);
+     148          92 :   for(unsigned i=0; i<ntriangle; ++i) active_elements.addIndexToList( i );
+     149           1 : }
+     150             : 
+     151          17 : void Sprint::calculate() {
+     152             :   // Get the adjacency matrix
+     153          17 :   getAdjacencyVessel()->retrieveMatrix( active_elements, thematrix );
+     154             :   // Diagonalize it
+     155          17 :   diagMat( thematrix, eigvals, eigenvecs );
+     156             :   // Get the maximum eigevalue
+     157          17 :   double lambda = eigvals[ getNumberOfNodes()-1 ];
+     158             :   // Get the corresponding eigenvector
+     159         255 :   for(unsigned j=0; j<maxeig.size(); ++j) {
+     160         238 :     maxeig[j].first = std::fabs( eigenvecs( getNumberOfNodes()-1, j ) );
+     161         238 :     maxeig[j].second = j;
+     162             :     // Must make all components of principle eigenvector +ve
+     163         238 :     eigenvecs( getNumberOfNodes()-1, j ) = maxeig[j].first;
+     164             :   }
+     165             : 
+     166             :   // Reorder each block of eigevectors
+     167             :   unsigned startnum=0;
+     168          51 :   for(unsigned j=0; j<getNumberOfNodeTypes(); ++j) {
+     169          34 :     unsigned nthis = getNumberOfAtomsInGroup(j);
+     170             :     // Sort into ascending order
+     171          34 :     std::sort( maxeig.begin() + startnum, maxeig.begin() + startnum + nthis );
+     172             :     // Used so we can do sorting in blocks
+     173          34 :     startnum += nthis;
+     174             :   }
+     175             :   // Set the sprint coordinates
+     176         255 :   for(int icomp=0; icomp<getNumberOfComponents(); ++icomp) {
+     177         238 :     getPntrToComponent(icomp)->set( sqrtn*lambda*maxeig[icomp].first );
+     178             :   }
+     179             : 
+     180             :   // Parallelism
+     181             :   unsigned rank, stride;
+     182          17 :   if( serialCalculation() ) { stride=1; rank=0; }
+     183          17 :   else { rank=comm.Get_rank(); stride=comm.Get_size(); }
+     184             : 
+     185             :   // Derivatives
+     186          17 :   MultiValue myvals( 2, getNumberOfDerivatives() );
+     187          17 :   Matrix<double> mymat_ders( getNumberOfComponents(), getNumberOfDerivatives() );
+     188             :   // std::vector<unsigned> catoms(2);
+     189          17 :   unsigned nval = getNumberOfNodes(); mymat_ders=0;
+     190        1564 :   for(unsigned i=rank; i<active_elements.getNumberActive(); i+=stride) {
+     191        1547 :     unsigned j, k; getAdjacencyVessel()->getMatrixIndices( active_elements[i], j, k );
+     192        1547 :     double tmp1 = 2 * eigenvecs(nval-1,j)*eigenvecs(nval-1,k);
+     193       23205 :     for(int icomp=0; icomp<getNumberOfComponents(); ++icomp) {
+     194             :       double tmp2 = 0.;
+     195      303212 :       for(unsigned n=0; n<nval-1; ++n) { // Need care on following line
+     196      281554 :         tmp2 += eigenvecs(n,maxeig[icomp].second) * ( eigenvecs(n,j)*eigenvecs(nval-1,k) + eigenvecs(n,k)*eigenvecs(nval-1,j) ) / ( lambda - eigvals[n] );
+     197             :       }
+     198       21658 :       double prefactor=sqrtn*( tmp1*maxeig[icomp].first + tmp2*lambda );
+     199       21658 :       getAdjacencyVessel()->retrieveDerivatives( active_elements[i], false, myvals );
+     200      346528 :       for(unsigned jd=0; jd<myvals.getNumberActive(); ++jd) {
+     201             :         unsigned ider=myvals.getActiveIndex(jd);
+     202      324870 :         mymat_ders( icomp, ider ) += prefactor*myvals.getDerivative( 1, ider );
+     203             :       }
+     204             :     }
+     205             :   }
+     206          17 :   if( !serialCalculation() ) comm.Sum( mymat_ders );
+     207             : 
+     208         255 :   for(int j=0; j<getNumberOfComponents(); ++j) {
+     209         238 :     Value* val=getPntrToComponent(j);
+     210       12376 :     for(unsigned i=0; i<getNumberOfDerivatives(); ++i) val->addDerivative( i, mymat_ders(j,i) );
+     211             :   }
+     212          17 : }
+     213             : 
+     214          17 : void Sprint::apply() {
+     215             :   bool hasforce=false;
+     216          17 :   std::vector<double> forces( 3*getNumberOfAtoms() + 9 );
+     217          17 :   std::vector<double> fforces( 3*getNumberOfAtoms() + 9, 0 );
+     218         255 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     219         238 :     if( getPntrToComponent(i)->applyForce( forces ) ) {
+     220           0 :       hasforce=true; for(unsigned j=0; j<fforces.size(); ++j) fforces[j] += forces[j];
+     221             :     }
+     222             :   }
+     223          17 :   if( hasforce ) {
+     224           0 :     unsigned ind=0; setForcesOnAtoms( fforces, ind );
+     225             :   }
+     226          17 : }
+     227             : 
+     228             : }
+     229             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html b/coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..53a8c795f830 --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/TopologyMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - TopologyMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:155155100.0 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14TopologyMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD6adjmat14TopologyMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat14TopologyMatrix16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6adjmat14TopologyMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE24
_ZNK4PLMD6adjmat14TopologyMatrix21getNumberOfQuantitiesEv100
_ZNK4PLMD6adjmat14TopologyMatrix7computeERKjRNS_11multicolvar13AtomValuePackE9616
_ZNK4PLMD6adjmat14TopologyMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE31203
_ZNK4PLMD6adjmat14TopologyMatrix22calculateForThreeAtomsERKjRKNS_13VectorGenericILj3EEERKdRNS_13HistogramBeadERNS_11multicolvar13AtomValuePackE117917799
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TopologyMatrix.cpp.func.html b/coverage/adjmat/TopologyMatrix.cpp.func.html new file mode 100644 index 000000000000..7f07be5e0e9b --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/TopologyMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - TopologyMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:155155100.0 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6adjmat14TopologyMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE24
_ZN4PLMD6adjmat14TopologyMatrix16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD6adjmat14TopologyMatrixC1ERKNS_13ActionOptionsE6
_ZN4PLMD6adjmat14TopologyMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6adjmat14TopologyMatrix15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE31203
_ZNK4PLMD6adjmat14TopologyMatrix21getNumberOfQuantitiesEv100
_ZNK4PLMD6adjmat14TopologyMatrix22calculateForThreeAtomsERKjRKNS_13VectorGenericILj3EEERKdRNS_13HistogramBeadERNS_11multicolvar13AtomValuePackE117917799
_ZNK4PLMD6adjmat14TopologyMatrix7computeERKjRNS_11multicolvar13AtomValuePackE9616
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/TopologyMatrix.cpp.gcov.html b/coverage/adjmat/TopologyMatrix.cpp.gcov.html new file mode 100644 index 000000000000..aa535afa53d3 --- /dev/null +++ b/coverage/adjmat/TopologyMatrix.cpp.gcov.html @@ -0,0 +1,401 @@ + + + + + + + + LCOV - plumed test coverage - adjmat/TopologyMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmat - TopologyMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:155155100.0 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AdjacencyMatrixBase.h"
+      23             : #include "multicolvar/AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/SwitchingFunction.h"
+      26             : #include "tools/HistogramBead.h"
+      27             : #include "tools/Matrix.h"
+      28             : 
+      29             : //+PLUMEDOC MATRIX TOPOLOGY_MATRIX
+      30             : /*
+      31             : Adjacency matrix in which two atoms are adjacent if they are connected topologically
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : 
+      36             : */
+      37             : //+ENDPLUMEDOC
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace adjmat {
+      41             : 
+      42             : class TopologyMatrix : public AdjacencyMatrixBase {
+      43             : private:
+      44             : /// The width to use for the kernel density estimation and the
+      45             : /// sizes of the bins to be used in kernel density estimation
+      46             :   double sigma;
+      47             :   std::string kerneltype;
+      48             : /// The maximum number of bins that will be used
+      49             : /// This is calculated based on the dmax of the switching functions
+      50             :   unsigned maxbins;
+      51             : /// The volume of the cells
+      52             :   Matrix<double> cell_volume;
+      53             : /// switching function
+      54             :   Matrix<SwitchingFunction> switchingFunction;
+      55             :   Matrix<SwitchingFunction> cylinder_sw;
+      56             :   Matrix<SwitchingFunction> low_sf;
+      57             :   double beadrad, lsfmax;
+      58             :   Matrix<double> binw_mat;
+      59             :   SwitchingFunction threshold_switch;
+      60             : public:
+      61             : /// Create manual
+      62             :   static void registerKeywords( Keywords& keys );
+      63             : /// Constructor
+      64             :   explicit TopologyMatrix(const ActionOptions&);
+      65             : /// Get the number of quantities that we must compute
+      66             :   unsigned getNumberOfQuantities() const override;
+      67             : /// Create the ith, ith switching function
+      68             :   void setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) override;
+      69             : /// This actually calculates the value of the contact function
+      70             :   double calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const override;
+      71             : /// This does nothing
+      72             :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const override;
+      73             : /// Calculate the contribution from one of the atoms in the third element of the pack
+      74             :   void calculateForThreeAtoms( const unsigned& iat, const Vector& d1, const double& d1_len,
+      75             :                                HistogramBead& bead, multicolvar::AtomValuePack& myatoms ) const ;
+      76             : };
+      77             : 
+      78             : PLUMED_REGISTER_ACTION(TopologyMatrix,"TOPOLOGY_MATRIX")
+      79             : 
+      80           8 : void TopologyMatrix::registerKeywords( Keywords& keys ) {
+      81           8 :   AdjacencyMatrixBase::registerKeywords( keys );
+      82          16 :   keys.add("atoms","NODES","The list of atoms for which you would like to calculate the contact matrix.  The atoms involved must be specified "
+      83             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      84             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      85             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      86             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      87          16 :   keys.add("atoms","ATOMS","");
+      88          16 :   keys.add("numbered","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      89             :            "The following provides information on the \\ref switchingfunction that are available.");
+      90          16 :   keys.add("numbered","RADIUS","");
+      91          16 :   keys.add("numbered","CYLINDER_SWITCH","a switching function on the distance from the center of the cylinder");
+      92          16 :   keys.add("numbered","BIN_SIZE","the size to use for the bins");
+      93          16 :   keys.add("compulsory","DENSITY_THRESHOLD","");
+      94          16 :   keys.add("compulsory","SIGMA","the width of the function to be used for kernel density estimation");
+      95          16 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      96          16 :   keys.add("hidden","FAKE","");
+      97           8 : }
+      98             : 
+      99           6 : TopologyMatrix::TopologyMatrix( const ActionOptions& ao ):
+     100             :   Action(ao),
+     101             :   AdjacencyMatrixBase(ao),
+     102          12 :   maxbins(0)
+     103             : {
+     104          12 :   readMaxThreeSpeciesMatrix("NODES", "FAKE", "FAKE", "ATOMS", true );
+     105           6 :   unsigned nrows, ncols, ndonor_types; retrieveTypeDimensions( nrows, ncols, ndonor_types );
+     106           6 :   switchingFunction.resize( nrows, ncols ); parseConnectionDescriptions("SWITCH",false,ndonor_types);
+     107           6 :   cylinder_sw.resize( nrows, ncols ); parseConnectionDescriptions("RADIUS",false,ndonor_types);
+     108           6 :   low_sf.resize( nrows, ncols ); parseConnectionDescriptions("CYLINDER_SWITCH",false,ndonor_types);
+     109           6 :   binw_mat.resize( nrows, ncols ); cell_volume.resize( nrows, ncols );
+     110           6 :   parseConnectionDescriptions("BIN_SIZE",false,ndonor_types);
+     111             :   // Read in stuff for grid
+     112          18 :   parse("SIGMA",sigma); parse("KERNEL",kerneltype);
+     113             :   // Read in threshold for density cutoff
+     114           6 :   std::string errors, thresh_sw_str; parse("DENSITY_THRESHOLD",thresh_sw_str);
+     115           6 :   threshold_switch.set(thresh_sw_str, errors );
+     116           6 :   if( errors.length()>0 ) error("errors in DENSITY_THRESHOLD switching function : " + errors );
+     117           6 :   log.printf("  threshold on density of atoms in cylinder equals %s\n",threshold_switch.description().c_str() );
+     118             : 
+     119          12 :   for(unsigned i=0; i<getNumberOfNodeTypes(); ++i) {
+     120          12 :     for(unsigned j=0; j<getNumberOfNodeTypes(); ++j) {
+     121           6 :       double r=cylinder_sw(i,j).get_d0() + cylinder_sw(i,j).get_r0();
+     122           6 :       cell_volume(i,j)=binw_mat(i,j)*pi*r*r;
+     123             :     }
+     124             :   }
+     125             : 
+     126             :   // Find the largest sf cutoff
+     127           6 :   lsfmax=low_sf(0,0).get_dmax();
+     128           6 :   double sfmax=switchingFunction(0,0).get_dmax();
+     129           6 :   double rfmax=cylinder_sw(0,0).get_dmax();
+     130          12 :   for(unsigned i=0; i<getNumberOfNodeTypes(); ++i) {
+     131          12 :     for(unsigned j=0; j<getNumberOfNodeTypes(); ++j) {
+     132           6 :       double tsf=switchingFunction(i,j).get_dmax();
+     133           6 :       if( tsf>sfmax ) sfmax=tsf;
+     134           6 :       double rsf=cylinder_sw(i,j).get_dmax();
+     135           6 :       if( rsf>rfmax ) rfmax=rsf;
+     136           6 :       double lsf=low_sf(i,j).get_dmax();
+     137           6 :       if( lsf>lsfmax ) lsfmax=lsf;
+     138             :     }
+     139             :   }
+     140             :   // Get the width of the bead
+     141           6 :   HistogramBead bead; bead.isNotPeriodic();
+     142           6 :   bead.setKernelType( kerneltype ); bead.set( 0.0, 1.0, sigma );
+     143           6 :   beadrad = bead.getCutoff();
+     144             : 
+     145             :   // Set the link cell cutoff
+     146           6 :   log.printf("  setting cutoff %f \n", sfmax );
+     147           6 :   setLinkCellCutoff( sfmax, std::numeric_limits<double>::max() );
+     148             : 
+     149             :   double maxsize=0;
+     150          12 :   for(unsigned i=0; i<getNumberOfNodeTypes(); ++i) {
+     151          12 :     for(unsigned j=0; j<getNumberOfNodeTypes(); ++j) {
+     152           6 :       if( binw_mat(i,j)>maxsize ) maxsize=binw_mat(i,j);
+     153             :     }
+     154             :   }
+     155             :   // Set the maximum number of bins that we will need to compute
+     156           6 :   maxbins = std::floor( sfmax / maxsize ) + 1;
+     157             :   // Need to resize functions again here to ensure that vector sizes
+     158             :   // are set correctly in AdjacencyMatrixVessel
+     159           6 :   resizeFunctions();
+     160           6 : }
+     161             : 
+     162         100 : unsigned TopologyMatrix::getNumberOfQuantities() const {
+     163         100 :   return maxbins+3;
+     164             : }
+     165             : 
+     166          24 : void TopologyMatrix::setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+     167          24 :   plumed_assert( id<4 );
+     168          24 :   if( id==0 ) {
+     169           6 :     std::string errors; switchingFunction(j,i).set(desc[0],errors);
+     170           6 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     171           6 :     if( j!=i) switchingFunction(i,j).set(desc[0],errors);
+     172          12 :     log.printf("  %u th and %u th multicolvar groups must be within %s\n",i+1,j+1,(switchingFunction(i,j).description()).c_str() );
+     173          18 :   } else if( id==1 ) {
+     174           6 :     std::string errors; cylinder_sw(j,i).set(desc[0],errors);
+     175           6 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     176           6 :     if( j!=i) cylinder_sw(i,j).set(desc[0],errors);
+     177          12 :     log.printf("  there must be not atoms within the cylinder connections atoms of multicolvar groups %u th and %u th.  This cylinder has radius %s \n",i+1,j+1,(cylinder_sw(i,j).description()).c_str() );
+     178          12 :   } else if( id==2 ) {
+     179           6 :     std::string errors; low_sf(j,i).set(desc[0],errors);
+     180           6 :     if( errors.length()!=0 ) error("problem reading switching function description " + errors);
+     181           6 :     if( j!=i ) low_sf(i,j).set(desc[0],errors);
+     182          12 :     log.printf("  %u th and %u th multicolvar groups must be further apart than %s\n",i+1,j+1,(low_sf(j,i).description()).c_str() );
+     183           6 :   } else if( id==3 ) {
+     184           6 :     Tools::convert( desc[0], binw_mat(j,i) );
+     185           6 :     if( i!=j ) binw_mat(i,j)=binw_mat(j,i);
+     186           6 :     log.printf("  cylinder for %u th and %u th multicolvar groups is split into bins of length %f \n",i,j,binw_mat(i,j) );
+     187             :   }
+     188          24 : }
+     189             : 
+     190       31203 : double TopologyMatrix::calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+     191       31203 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     192       62406 :   if( distance.modulo2()<switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax2() ) return 1.0;
+     193             :   return 0.0;
+     194             : }
+     195             : 
+     196        9616 : double TopologyMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     197        9616 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( kerneltype );
+     198             : 
+     199             :   // Initialise to zero density on all bins
+     200       48200 :   for(unsigned bin=0; bin<maxbins; ++bin) myatoms.setValue(bin+1,0);
+     201             :   // Calculate whether or not atoms 1 and 2 are within cutoff (can use delta here as pbc are done in atom setup)
+     202        9616 :   Vector d1 = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) ); double d1_len = d1.modulo();
+     203        9616 :   d1 = d1 / d1_len;  // Convert vector into director
+     204        9616 :   AtomNumber a1 = myatoms.getAbsoluteIndex( 0 );
+     205        9616 :   AtomNumber a2 = myatoms.getAbsoluteIndex( 1 );
+     206   117927415 :   for(unsigned i=2; i<myatoms.getNumberOfAtoms(); ++i) {
+     207   117917799 :     AtomNumber a3 = myatoms.getAbsoluteIndex( i );
+     208   117917799 :     if( a3!=a1 && a3!=a2 ) calculateForThreeAtoms( i, d1, d1_len, bead, myatoms );
+     209             :   }
+     210             :   // std::vector<double> binvals( 1+maxbins ); for(unsigned i=1;i<maxbins;++i) binvals[i]=myatoms.getValue(i);
+     211             :   // unsigned ii; double fdf;
+     212             :   //std::cout<<"HELLO DENSITY "<<myatoms.getIndex(0)<<" "<<myatoms.getIndex(1)<<" "<<transformStoredValues( binvals, ii, fdf )<<std::endl;
+     213             : 
+     214             :   // Now find the element for which the density is maximal
+     215             :   unsigned vout=2; double max=myatoms.getValue( 2 );
+     216       38584 :   for(unsigned i=3; i<myatoms.getUnderlyingMultiValue().getNumberOfValues()-1; ++i) {
+     217       28968 :     if( myatoms.getValue(i)>max ) { max=myatoms.getValue(i); vout=i; }
+     218             :   }
+     219             :   // Calculate value and derivative of switching function between atoms 1 and 2
+     220             :   double dfuncl, sw = switchingFunction( getBaseColvarNumber( myatoms.getIndex(0) ),
+     221        9616 :                                          getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( d1_len, dfuncl );
+     222             :   // Transform the density
+     223        9616 :   double df, tsw = threshold_switch.calculate( max, df );
+     224        9616 :   if( !doNotCalculateDerivatives() ) {
+     225             :     // Factor of d1_len is required here because d1 is normalized
+     226          60 :     d1 *= d1_len;
+     227          60 :     addAtomDerivatives( 2+maxbins, 0, -dfuncl*d1, myatoms );
+     228          60 :     addAtomDerivatives( 2+maxbins, 1, dfuncl*d1, myatoms );
+     229          60 :     myatoms.addBoxDerivatives( 2+maxbins, (-dfuncl)*Tensor(d1,d1) );
+     230             :     // Update active atoms so that next bit works
+     231          60 :     updateActiveAtoms( myatoms );
+     232             :     // Now finish caclulation of derivatives
+     233             :     MultiValue& myvals=myatoms.getUnderlyingMultiValue();
+     234       13029 :     for(unsigned jd=0; jd<myvals.getNumberActive(); ++jd) {
+     235       12969 :       unsigned ider=myvals.getActiveIndex(jd);
+     236       12969 :       myvals.addDerivative( 1, ider, sw*df*max*myvals.getDerivative( vout, ider ) + tsw*myvals.getDerivative( 2+maxbins, ider ) );
+     237             :     }
+     238             :   }
+     239        9616 :   return sw*tsw;
+     240             : }
+     241             : 
+     242   117917799 : void TopologyMatrix::calculateForThreeAtoms( const unsigned& iat, const Vector& d1, const double& d1_len,
+     243             :     HistogramBead& bead, multicolvar::AtomValuePack& myatoms ) const {
+     244             :   // Calculate if there are atoms in the cylinder (can use delta here as pbc are done in atom setup)
+     245   117917799 :   Vector d2 = getSeparation( myatoms.getPosition(0), myatoms.getPosition(iat) );
+     246             :   // Now calculate projection of d2 on d1
+     247   117917799 :   double proj=dotProduct(d2,d1);
+     248             :   // This tells us if we are outside the end of the cylinder
+     249   117917799 :   double excess = proj - d1_len;
+     250             :   // Return if we are outside of the cylinder as calculated based on excess
+     251   175974631 :   if( excess>low_sf( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax() ) return;
+     252             :   // Find the length of the cylinder
+     253    81802351 :   double binw = binw_mat( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) );
+     254    81802351 :   double lcylinder = (std::floor( d1_len / binw ) + 1)*binw;
+     255             :   // Return if the projection is outside the length of interest
+     256    81802351 :   if( proj<-bead.getCutoff() || proj>(lcylinder+bead.getCutoff()) ) return;
+     257             : 
+     258             :   // Calculate the excess swiching function
+     259    23745519 :   double edf, eval = low_sf( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).calculate( excess, edf );
+     260             :   // Calculate the projection on the perpendicular distance from the center of the tube
+     261    23745519 :   double cm = d2.modulo2() - proj*proj;
+     262             : 
+     263             :   // Now calculate the density in the cylinder
+     264    23745519 :   if( cm<cylinder_sw( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) ).get_dmax2() ) {
+     265             :     double dfuncr, val = cylinder_sw( getBaseColvarNumber( myatoms.getIndex(0) ),
+     266      104467 :                                       getBaseColvarNumber( myatoms.getIndex(1) ) ).calculateSqr( cm, dfuncr );
+     267      104467 :     double cellv = cell_volume( getBaseColvarNumber( myatoms.getIndex(0) ), getBaseColvarNumber( myatoms.getIndex(1) ) );
+     268      104467 :     Vector dc1, dc2, dc3, dd1, dd2, dd3, de1, de2, de3;
+     269      104467 :     if( !doNotCalculateDerivatives() ) {
+     270        4023 :       Tensor d1_a1;
+     271             :       // Derivative of director connecting atom1 - atom2 wrt the position of atom 1
+     272        4023 :       d1_a1(0,0) = ( -(d1[1]*d1[1]+d1[2]*d1[2])/d1_len );   // dx/dx
+     273        4023 :       d1_a1(0,1) = (  d1[0]*d1[1]/d1_len );                 // dx/dy
+     274        4023 :       d1_a1(0,2) = (  d1[0]*d1[2]/d1_len );                 // dx/dz
+     275        4023 :       d1_a1(1,0) = (  d1[1]*d1[0]/d1_len );                 // dy/dx
+     276        4023 :       d1_a1(1,1) = ( -(d1[0]*d1[0]+d1[2]*d1[2])/d1_len );   // dy/dy
+     277        4023 :       d1_a1(1,2) = (  d1[1]*d1[2]/d1_len );
+     278        4023 :       d1_a1(2,0) = (  d1[2]*d1[0]/d1_len );
+     279        4023 :       d1_a1(2,1) = (  d1[2]*d1[1]/d1_len );
+     280        4023 :       d1_a1(2,2) = ( -(d1[1]*d1[1]+d1[0]*d1[0])/d1_len );
+     281             : 
+     282             :       // Calculate derivatives of dot product
+     283        4023 :       dd1 = matmul(d2, d1_a1) - d1;
+     284        4023 :       dd2 = matmul(d2, -d1_a1);
+     285        4023 :       dd3 = d1;
+     286             : 
+     287             :       // Calculate derivatives of cross product
+     288        4023 :       dc1 = dfuncr*( -d2 - proj*dd1 );
+     289        4023 :       dc2 = dfuncr*( -proj*dd2 );
+     290        4023 :       dc3 = dfuncr*( d2 - proj*dd3 );
+     291             : 
+     292             :       // Calculate derivatives of excess
+     293        4023 :       de1 = edf*excess*( dd1 + d1 );
+     294        4023 :       de2 = edf*excess*( dd2 - d1 );
+     295        4023 :       de3 = edf*excess*dd3;
+     296             :     }
+     297             : 
+     298      104467 :     Vector pos1 = myatoms.getPosition(0) + d1_len*d1;
+     299      104467 :     Vector pos2 = myatoms.getPosition(0) + d2;
+     300      104467 :     Vector g1derivf,g2derivf,lderivf; Tensor vir;
+     301      530381 :     for(unsigned bin=0; bin<maxbins; ++bin) {
+     302      425914 :       bead.set( bin*binw, (bin+1)*binw, sigma );
+     303      425914 :       if( proj<(bin*binw-bead.getCutoff()) || proj>binw*(bin+1)+bead.getCutoff() ) continue;
+     304      132418 :       double der, contr=bead.calculateWithCutoff( proj, der ) / cellv; der /= cellv;
+     305      132418 :       myatoms.addValue( 2+bin, contr*val*eval );
+     306             : 
+     307      132418 :       if( !doNotCalculateDerivatives() ) {
+     308        5835 :         g1derivf=contr*eval*dc1 + val*eval*der*dd1 + contr*val*de1;
+     309        5835 :         addAtomDerivatives( 2+bin, 0, g1derivf, myatoms );
+     310        5835 :         g2derivf=contr*eval*dc2 + val*eval*der*dd2 + contr*val*de2;
+     311        5835 :         addAtomDerivatives( 2+bin, 1, g2derivf, myatoms );
+     312        5835 :         lderivf=contr*eval*dc3 + val*eval*der*dd3 + contr*val*de3;
+     313        5835 :         addAtomDerivatives( 2+bin, iat, lderivf, myatoms );
+     314             :         // Virial
+     315        5835 :         vir = -Tensor( myatoms.getPosition(0), g1derivf ) - Tensor( pos1, g2derivf ) - Tensor( pos2, lderivf );
+     316        5835 :         myatoms.addBoxDerivatives( 2+bin, vir );
+     317             :       }
+     318             :     }
+     319             :   }
+     320             : }
+     321             : 
+     322             : }
+     323             : }
+     324             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/index-sort-f.html b/coverage/adjmat/index-sort-f.html new file mode 100644 index 000000000000..94588d51a757 --- /dev/null +++ b/coverage/adjmat/index-sort-f.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:1023114589.3 %
Date:2024-02-22 21:58:45Functions:13617577.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ClusterAnalysisBase.h +
0.0%
+
0.0 %0 / 10.0 %0 / 1
ContactAlignedMatrix.cpp +
19.0%19.0%
+
19.0 %4 / 2120.0 %1 / 5
ActionWithInputMatrix.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
ClusterSize.cpp +
84.2%84.2%
+
84.2 %16 / 1950.0 %3 / 6
OutputCluster.cpp +
46.5%46.5%
+
46.5 %40 / 8662.5 %5 / 8
ClusterDiameter.cpp +
92.9%92.9%
+
92.9 %26 / 2866.7 %4 / 6
ClusterWithSurface.cpp +
85.7%85.7%
+
85.7 %48 / 5669.2 %9 / 13
MatrixRowSums.cpp +
100.0%
+
100.0 %21 / 2175.0 %3 / 4
MatrixColumnSums.cpp +
100.0%
+
100.0 %30 / 3075.0 %3 / 4
ClusteringBase.cpp +
93.5%93.5%
+
93.5 %29 / 3175.0 %6 / 8
ClusterDistribution.cpp +
87.5%87.5%
+
87.5 %42 / 4880.0 %4 / 5
Sprint.cpp +
96.9%96.9%
+
96.9 %62 / 6480.0 %4 / 5
SMACMatrix.cpp +
100.0%
+
100.0 %34 / 3480.0 %4 / 5
ClusterProperties.cpp +
100.0%
+
100.0 %29 / 2980.0 %4 / 5
DFSClustering.cpp +
100.0%
+
100.0 %25 / 2580.0 %4 / 5
ClusterAnalysisBase.cpp +
91.7%91.7%
+
91.7 %44 / 4880.0 %12 / 15
AdjacencyMatrixBase.cpp +
85.0%85.0%
+
85.0 %85 / 10081.8 %9 / 11
AlignedMatrixBase.cpp +
88.0%88.0%
+
88.0 %44 / 5083.3 %5 / 6
DumpGraph.cpp +
100.0%
+
100.0 %34 / 3483.3 %5 / 6
ContactMatrix.cpp +
100.0%
+
100.0 %36 / 3683.3 %5 / 6
HbondMatrix.cpp +
97.1%97.1%
+
97.1 %68 / 7085.7 %6 / 7
TopologyMatrix.cpp +
100.0%
+
100.0 %155 / 15587.5 %7 / 8
AdjacencyMatrixVessel.cpp +
91.0%91.0%
+
91.0 %71 / 7893.3 %14 / 15
ActionWithInputMatrix.cpp +
100.0%
+
100.0 %70 / 7093.8 %15 / 16
ClusteringBase.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
AdjacencyMatrixBase.h +
100.0%
+
100.0 %7 / 7100.0 %2 / 2
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/index-sort-l.html b/coverage/adjmat/index-sort-l.html new file mode 100644 index 000000000000..1caa7b33a720 --- /dev/null +++ b/coverage/adjmat/index-sort-l.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:1023114589.3 %
Date:2024-02-22 21:58:45Functions:13617577.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ClusterAnalysisBase.h +
0.0%
+
0.0 %0 / 10.0 %0 / 1
ContactAlignedMatrix.cpp +
19.0%19.0%
+
19.0 %4 / 2120.0 %1 / 5
OutputCluster.cpp +
46.5%46.5%
+
46.5 %40 / 8662.5 %5 / 8
ActionWithInputMatrix.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
ClusterSize.cpp +
84.2%84.2%
+
84.2 %16 / 1950.0 %3 / 6
AdjacencyMatrixBase.cpp +
85.0%85.0%
+
85.0 %85 / 10081.8 %9 / 11
ClusterWithSurface.cpp +
85.7%85.7%
+
85.7 %48 / 5669.2 %9 / 13
ClusterDistribution.cpp +
87.5%87.5%
+
87.5 %42 / 4880.0 %4 / 5
AlignedMatrixBase.cpp +
88.0%88.0%
+
88.0 %44 / 5083.3 %5 / 6
AdjacencyMatrixVessel.cpp +
91.0%91.0%
+
91.0 %71 / 7893.3 %14 / 15
ClusterAnalysisBase.cpp +
91.7%91.7%
+
91.7 %44 / 4880.0 %12 / 15
ClusterDiameter.cpp +
92.9%92.9%
+
92.9 %26 / 2866.7 %4 / 6
ClusteringBase.cpp +
93.5%93.5%
+
93.5 %29 / 3175.0 %6 / 8
Sprint.cpp +
96.9%96.9%
+
96.9 %62 / 6480.0 %4 / 5
HbondMatrix.cpp +
97.1%97.1%
+
97.1 %68 / 7085.7 %6 / 7
ClusteringBase.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
AdjacencyMatrixBase.h +
100.0%
+
100.0 %7 / 7100.0 %2 / 2
MatrixRowSums.cpp +
100.0%
+
100.0 %21 / 2175.0 %3 / 4
DFSClustering.cpp +
100.0%
+
100.0 %25 / 2580.0 %4 / 5
ClusterProperties.cpp +
100.0%
+
100.0 %29 / 2980.0 %4 / 5
MatrixColumnSums.cpp +
100.0%
+
100.0 %30 / 3075.0 %3 / 4
SMACMatrix.cpp +
100.0%
+
100.0 %34 / 3480.0 %4 / 5
DumpGraph.cpp +
100.0%
+
100.0 %34 / 3483.3 %5 / 6
ContactMatrix.cpp +
100.0%
+
100.0 %36 / 3683.3 %5 / 6
ActionWithInputMatrix.cpp +
100.0%
+
100.0 %70 / 7093.8 %15 / 16
TopologyMatrix.cpp +
100.0%
+
100.0 %155 / 15587.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/adjmat/index.html b/coverage/adjmat/index.html new file mode 100644 index 000000000000..ac58753bfe18 --- /dev/null +++ b/coverage/adjmat/index.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - adjmat + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - adjmatHitTotalCoverage
Test:plumed test coverageLines:1023114589.3 %
Date:2024-02-22 21:58:45Functions:13617577.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionWithInputMatrix.cpp +
100.0%
+
100.0 %70 / 7093.8 %15 / 16
ActionWithInputMatrix.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
AdjacencyMatrixBase.cpp +
85.0%85.0%
+
85.0 %85 / 10081.8 %9 / 11
AdjacencyMatrixBase.h +
100.0%
+
100.0 %7 / 7100.0 %2 / 2
AdjacencyMatrixVessel.cpp +
91.0%91.0%
+
91.0 %71 / 7893.3 %14 / 15
AlignedMatrixBase.cpp +
88.0%88.0%
+
88.0 %44 / 5083.3 %5 / 6
ClusterAnalysisBase.cpp +
91.7%91.7%
+
91.7 %44 / 4880.0 %12 / 15
ClusterAnalysisBase.h +
0.0%
+
0.0 %0 / 10.0 %0 / 1
ClusterDiameter.cpp +
92.9%92.9%
+
92.9 %26 / 2866.7 %4 / 6
ClusterDistribution.cpp +
87.5%87.5%
+
87.5 %42 / 4880.0 %4 / 5
ClusterProperties.cpp +
100.0%
+
100.0 %29 / 2980.0 %4 / 5
ClusterSize.cpp +
84.2%84.2%
+
84.2 %16 / 1950.0 %3 / 6
ClusterWithSurface.cpp +
85.7%85.7%
+
85.7 %48 / 5669.2 %9 / 13
ClusteringBase.cpp +
93.5%93.5%
+
93.5 %29 / 3175.0 %6 / 8
ClusteringBase.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
ContactAlignedMatrix.cpp +
19.0%19.0%
+
19.0 %4 / 2120.0 %1 / 5
ContactMatrix.cpp +
100.0%
+
100.0 %36 / 3683.3 %5 / 6
DFSClustering.cpp +
100.0%
+
100.0 %25 / 2580.0 %4 / 5
DumpGraph.cpp +
100.0%
+
100.0 %34 / 3483.3 %5 / 6
HbondMatrix.cpp +
97.1%97.1%
+
97.1 %68 / 7085.7 %6 / 7
MatrixColumnSums.cpp +
100.0%
+
100.0 %30 / 3075.0 %3 / 4
MatrixRowSums.cpp +
100.0%
+
100.0 %21 / 2175.0 %3 / 4
OutputCluster.cpp +
46.5%46.5%
+
46.5 %40 / 8662.5 %5 / 8
SMACMatrix.cpp +
100.0%
+
100.0 %34 / 3480.0 %4 / 5
Sprint.cpp +
96.9%96.9%
+
96.9 %62 / 6480.0 %4 / 5
TopologyMatrix.cpp +
100.0%
+
100.0 %155 / 15587.5 %7 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/amber.png b/coverage/amber.png new file mode 100644 index 0000000000000000000000000000000000000000..2cab170d8359081983a4e343848dfe06bc490f12 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^G2tW}LqE04T&+ z;1OBOz`!j8!i<;h*8KqrvZOouIx;Y9?C1WI$O`1M1^9%x{(levWG + + + + + + + LCOV - plumed test coverage - analysis/AnalysisBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AnalysisBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313296.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12AnalysisBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12AnalysisBase6updateEv39
_ZN4PLMD8analysis12AnalysisBase16getArgumentNamesB5cxx11Ev50
_ZN4PLMD8analysis12AnalysisBase12runFinalJobsEv107
_ZN4PLMD8analysis12AnalysisBaseC2ERKNS_13ActionOptionsE109
_ZN4PLMD8analysis12AnalysisBase16registerKeywordsERNS_8KeywordsE149
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AnalysisBase.cpp.func.html b/coverage/analysis/AnalysisBase.cpp.func.html new file mode 100644 index 000000000000..2a33069ebeaf --- /dev/null +++ b/coverage/analysis/AnalysisBase.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - analysis/AnalysisBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AnalysisBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313296.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12AnalysisBase12runFinalJobsEv107
_ZN4PLMD8analysis12AnalysisBase16getArgumentNamesB5cxx11Ev50
_ZN4PLMD8analysis12AnalysisBase16registerKeywordsERNS_8KeywordsE149
_ZN4PLMD8analysis12AnalysisBase6updateEv39
_ZN4PLMD8analysis12AnalysisBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis12AnalysisBaseC2ERKNS_13ActionOptionsE109
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AnalysisBase.cpp.gcov.html b/coverage/analysis/AnalysisBase.cpp.gcov.html new file mode 100644 index 000000000000..05c166005663 --- /dev/null +++ b/coverage/analysis/AnalysisBase.cpp.gcov.html @@ -0,0 +1,159 @@ + + + + + + + + LCOV - plumed test coverage - analysis/AnalysisBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AnalysisBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313296.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AnalysisBase.h"
+      23             : #include "ReadAnalysisFrames.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace analysis {
+      29             : 
+      30         149 : void AnalysisBase::registerKeywords( Keywords& keys ) {
+      31         149 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      32         149 :   ActionWithValue::registerKeywords( keys ); ActionAtomistic::registerKeywords( keys );
+      33         149 :   ActionWithArguments::registerKeywords( keys ); keys.remove("NUMERICAL_DERIVATIVES");
+      34         447 :   ActionWithVessel::registerKeywords( keys ); keys.remove("TOL"); keys.reset_style("TIMINGS","hidden"); keys.isAnalysis();
+      35         298 :   keys.add("atoms-2","USE_OUTPUT_DATA_FROM","use the output of the analysis performed by this object as input to your new analysis object");
+      36         149 : }
+      37             : 
+      38         109 : AnalysisBase::AnalysisBase(const ActionOptions&ao):
+      39             :   Action(ao),
+      40             :   ActionPilot(ao),
+      41             :   ActionWithValue(ao),
+      42             :   ActionAtomistic(ao),
+      43             :   ActionWithArguments(ao),
+      44             :   ActionWithVessel(ao),
+      45         109 :   my_input_data(NULL)
+      46             : {
+      47             :   // We have an if statement here so that this doesn't break with READ_DISSIMILARITIES
+      48         218 :   if( keywords.exists("USE_OUTPUT_DATA_FROM") ) {
+      49          78 :     std::string datastr; parse("USE_OUTPUT_DATA_FROM",datastr);
+      50         156 :     if( keywords.style("USE_OUTPUT_DATA_FROM","atoms") && datastr.length()==0 ) error("input analysis action was not specified use USE_OUTPUT_DATA_FROM");
+      51          78 :     if( datastr.length()>0 ) {
+      52          77 :       my_input_data=plumed.getActionSet().selectWithLabel<AnalysisBase*>( datastr );
+      53          77 :       log.printf("  performing analysis on output from %s \n",datastr.c_str() );
+      54          77 :       if( !my_input_data ) error("could not find analysis action named " + datastr );
+      55          77 :       addDependency( my_input_data );
+      56             :     }
+      57             :   }
+      58         109 : }
+      59             : 
+      60          50 : std::vector<std::string> AnalysisBase::getArgumentNames() {
+      61          50 :   std::vector<Value*> arg_p( getArgumentList() );
+      62          50 :   std::vector<std::string> argn( arg_p.size() );
+      63         124 :   for(unsigned i=0; i<arg_p.size(); ++i) {
+      64          74 :     plumed_assert( i<argn.size() && i<arg_p.size() );
+      65          74 :     argn[i]=arg_p[i]->getName();
+      66             :   }
+      67          50 :   return argn;
+      68           0 : }
+      69             : 
+      70          39 : void AnalysisBase::update() {
+      71          39 :   if( getStep()==0 || ( getStride()>0 && !onStep() ) ) return;
+      72             :   // And do the analysis
+      73          30 :   performAnalysis();
+      74             : }
+      75             : 
+      76         107 : void AnalysisBase::runFinalJobs() {
+      77         107 :   if( getStride()>0 ) return;
+      78          69 :   performAnalysis();
+      79             : }
+      80             : 
+      81             : }
+      82             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AnalysisBase.h.func-sort-c.html b/coverage/analysis/AnalysisBase.h.func-sort-c.html new file mode 100644 index 000000000000..4e476e949d46 --- /dev/null +++ b/coverage/analysis/AnalysisBase.h.func-sort-c.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - analysis/AnalysisBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AnalysisBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243372.7 %
Date:2024-02-22 21:58:45Functions:131968.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12AnalysisBase10isPeriodicEv0
_ZN4PLMD8analysis12AnalysisBase22getNumberOfDerivativesEv0
_ZN4PLMD8analysis12AnalysisBase29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZNK4PLMD8analysis12AnalysisBase11usingMemoryEv0
_ZNK4PLMD8analysis12AnalysisBase13getMetricNameB5cxx11Ev0
_ZNK4PLMD8analysis12AnalysisBase16getNormalizationEv0
_ZNK4PLMD8analysis12AnalysisBase14getAtomIndexesEv14
_ZN4PLMD8analysis12AnalysisBase15getArgumentListEv22
_ZNK4PLMD8analysis12AnalysisBase27getDissimilarityInstructionB5cxx11Ev841
_ZNK4PLMD8analysis12AnalysisBase22dissimilaritiesWereSetEv848
_ZN4PLMD8analysis12AnalysisBase12lockRequestsEv7546
_ZN4PLMD8analysis12AnalysisBase14unlockRequestsEv7546
_ZN4PLMD8analysis12AnalysisBase5applyEv7546
_ZN4PLMD8analysis12AnalysisBase9calculateEv7546
_ZNK4PLMD8analysis12AnalysisBase21getNumberOfDataPointsEv360092
_ZNK4PLMD8analysis12AnalysisBase23getDataPointIndexInBaseERKj375002
_ZN4PLMD8analysis12AnalysisBase13getStoredDataERKjRKb522156
_ZN4PLMD8analysis12AnalysisBase16getDissimilarityERKjS3_659376
_ZN4PLMD8analysis12AnalysisBase9getWeightERKj40113999
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AnalysisBase.h.func.html b/coverage/analysis/AnalysisBase.h.func.html new file mode 100644 index 000000000000..8b6567e10d35 --- /dev/null +++ b/coverage/analysis/AnalysisBase.h.func.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - analysis/AnalysisBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AnalysisBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243372.7 %
Date:2024-02-22 21:58:45Functions:131968.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis12AnalysisBase10isPeriodicEv0
_ZN4PLMD8analysis12AnalysisBase12lockRequestsEv7546
_ZN4PLMD8analysis12AnalysisBase13getStoredDataERKjRKb522156
_ZN4PLMD8analysis12AnalysisBase14unlockRequestsEv7546
_ZN4PLMD8analysis12AnalysisBase15getArgumentListEv22
_ZN4PLMD8analysis12AnalysisBase16getDissimilarityERKjS3_659376
_ZN4PLMD8analysis12AnalysisBase22getNumberOfDerivativesEv0
_ZN4PLMD8analysis12AnalysisBase29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD8analysis12AnalysisBase5applyEv7546
_ZN4PLMD8analysis12AnalysisBase9calculateEv7546
_ZN4PLMD8analysis12AnalysisBase9getWeightERKj40113999
_ZNK4PLMD8analysis12AnalysisBase11usingMemoryEv0
_ZNK4PLMD8analysis12AnalysisBase13getMetricNameB5cxx11Ev0
_ZNK4PLMD8analysis12AnalysisBase14getAtomIndexesEv14
_ZNK4PLMD8analysis12AnalysisBase16getNormalizationEv0
_ZNK4PLMD8analysis12AnalysisBase21getNumberOfDataPointsEv360092
_ZNK4PLMD8analysis12AnalysisBase22dissimilaritiesWereSetEv848
_ZNK4PLMD8analysis12AnalysisBase23getDataPointIndexInBaseERKj375002
_ZNK4PLMD8analysis12AnalysisBase27getDissimilarityInstructionB5cxx11Ev841
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AnalysisBase.h.gcov.html b/coverage/analysis/AnalysisBase.h.gcov.html new file mode 100644 index 000000000000..6c4f7ea0d271 --- /dev/null +++ b/coverage/analysis/AnalysisBase.h.gcov.html @@ -0,0 +1,257 @@ + + + + + + + + LCOV - plumed test coverage - analysis/AnalysisBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AnalysisBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243372.7 %
Date:2024-02-22 21:58:45Functions:131968.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_analysis_AnalysisBase_h
+      23             : #define __PLUMED_analysis_AnalysisBase_h
+      24             : 
+      25             : #include "core/ActionPilot.h"
+      26             : #include "core/ActionAtomistic.h"
+      27             : #include "core/ActionWithArguments.h"
+      28             : #include "core/ActionWithValue.h"
+      29             : #include "vesselbase/ActionWithVessel.h"
+      30             : #include "DataCollectionObject.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : class ReferenceConfiguration;
+      35             : 
+      36             : namespace analysis {
+      37             : 
+      38             : /**
+      39             : \ingroup INHERIT
+      40             : This is the abstract base class to use for implementing new methods for analyzing the trajectory. You can find
+      41             : \ref AddingAnAnalysis "information" on how to use it to implement new analysis methods here.
+      42             : 
+      43             : */
+      44             : 
+      45             : class AnalysisBase :
+      46             :   public ActionPilot,
+      47             :   public ActionWithValue,
+      48             :   public ActionAtomistic,
+      49             :   public ActionWithArguments,
+      50             :   public vesselbase::ActionWithVessel
+      51             : {
+      52             :   friend class ReselectLandmarks;
+      53             :   friend class ReadDissimilarityMatrix;
+      54             : protected:
+      55             : /// The Analysis action that we are reusing data from
+      56             :   AnalysisBase* my_input_data;
+      57             : public:
+      58             :   static void registerKeywords( Keywords& keys );
+      59             :   explicit AnalysisBase(const ActionOptions&);
+      60             : /// These are required because we inherit from both ActionAtomistic and ActionWithArguments
+      61             :   void lockRequests() override;
+      62             :   void unlockRequests() override;
+      63             : /// Return the number of data points
+      64             :   virtual unsigned getNumberOfDataPoints() const ;
+      65             : /// Return the index of the data point in the base class
+      66             :   virtual unsigned getDataPointIndexInBase( const unsigned& idata ) const ;
+      67             : /// Return the weight of the ith point
+      68             :   virtual double getWeight( const unsigned& idata );
+      69             : /// Get the name of the metric that is being used
+      70             :   virtual std::string getMetricName() const ;
+      71             : /// Are we using memory in this calculation this affects the weights of points
+      72             :   virtual bool usingMemory() const ;
+      73             : /// Return the normalisation constant for the calculation
+      74             :   virtual double getNormalization() const ;
+      75             : /// Ensures that dissimilarities were set somewhere
+      76             :   virtual bool dissimilaritiesWereSet() const ;
+      77             : /// Get the information on how dissimilarities were calculated for output PDB
+      78             :   virtual std::string getDissimilarityInstruction() const ;
+      79             : /// Get the squared dissimilarity between two reference configurations
+      80             :   virtual double getDissimilarity( const unsigned& i, const unsigned& j );
+      81             : /// Get the indices of the atoms that have been stored
+      82             :   virtual const std::vector<AtomNumber>& getAtomIndexes() const ;
+      83             : /// Overwrite getArguments so we get arguments from underlying class
+      84             :   virtual std::vector<Value*> getArgumentList();
+      85             : /// Get the list of argument names in the base
+      86             :   std::vector<std::string> getArgumentNames();
+      87             : /// Get a reference configuration (in dimensionality reduction this returns the projection)
+      88             :   virtual DataCollectionObject& getStoredData( const unsigned& idata, const bool& calcdist );
+      89             : /// This actually performs the analysis
+      90             :   virtual void performAnalysis()=0;
+      91             : /// These overwrite things from inherited classes (this is a bit of a fudge)
+      92           0 :   bool isPeriodic() override { plumed_error(); }
+      93           0 :   unsigned getNumberOfDerivatives() override { plumed_error(); }
+      94           0 :   void calculateNumericalDerivatives( ActionWithValue* a=NULL ) override { plumed_error(); }
+      95             : /// Calculate and apply do nothing all analysis is done during update step
+      96        7546 :   void calculate() override {}
+      97        7546 :   void apply() override {}
+      98             : /// This will call the analysis to be performed
+      99             :   void update() override;
+     100             : /// This calls the analysis to be performed in the final step of the calculation
+     101             : /// i.e. when use_all_data is true
+     102             :   void runFinalJobs() override;
+     103             : };
+     104             : 
+     105             : inline
+     106        7546 : void AnalysisBase::lockRequests() {
+     107             :   ActionAtomistic::lockRequests();
+     108             :   ActionWithArguments::lockRequests();
+     109        7546 : }
+     110             : 
+     111             : inline
+     112        7546 : void AnalysisBase::unlockRequests() {
+     113             :   ActionAtomistic::unlockRequests();
+     114             :   ActionWithArguments::unlockRequests();
+     115        7546 : }
+     116             : 
+     117             : inline
+     118      360092 : unsigned AnalysisBase::getNumberOfDataPoints() const {
+     119      360137 :   return my_input_data->getNumberOfDataPoints();
+     120             : }
+     121             : 
+     122             : inline
+     123      375002 : unsigned AnalysisBase::getDataPointIndexInBase( const unsigned& idata ) const {
+     124      500004 :   return my_input_data->getDataPointIndexInBase( idata );
+     125             : }
+     126             : 
+     127             : inline
+     128           0 : std::string AnalysisBase::getMetricName() const {
+     129           0 :   return my_input_data->getMetricName();
+     130             : }
+     131             : 
+     132             : inline
+     133    40113999 : double AnalysisBase::getWeight( const unsigned& idata ) {
+     134    40113999 :   return my_input_data->getWeight( idata );
+     135             : }
+     136             : 
+     137             : inline
+     138           0 : bool AnalysisBase::usingMemory() const {
+     139           0 :   return my_input_data->usingMemory();
+     140             : }
+     141             : 
+     142             : inline
+     143           0 : double AnalysisBase::getNormalization() const {
+     144           0 :   return my_input_data->getNormalization();
+     145             : }
+     146             : 
+     147             : inline
+     148         848 : bool AnalysisBase::dissimilaritiesWereSet() const {
+     149         877 :   return my_input_data->dissimilaritiesWereSet();
+     150             : }
+     151             : 
+     152             : inline
+     153      659376 : double AnalysisBase::getDissimilarity( const unsigned& i, const unsigned& j ) {
+     154      721705 :   return my_input_data->getDissimilarity( i, j );
+     155             : }
+     156             : 
+     157             : inline
+     158          22 : std::vector<Value*> AnalysisBase::getArgumentList() {
+     159          24 :   return my_input_data->getArgumentList();
+     160             : }
+     161             : 
+     162             : inline
+     163      522156 : DataCollectionObject& AnalysisBase::getStoredData( const unsigned& idata, const bool& calcdist ) {
+     164      526340 :   return my_input_data->getStoredData( idata, calcdist );
+     165             : }
+     166             : 
+     167             : inline
+     168          14 : const std::vector<AtomNumber>& AnalysisBase::getAtomIndexes() const {
+     169          14 :   return my_input_data->getAtomIndexes();
+     170             : }
+     171             : 
+     172             : inline
+     173         841 : std::string AnalysisBase::getDissimilarityInstruction() const {
+     174         841 :   return my_input_data->getDissimilarityInstruction();
+     175             : }
+     176             : 
+     177             : }
+     178             : }
+     179             : 
+     180             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Average.cpp.func-sort-c.html b/coverage/analysis/Average.cpp.func-sort-c.html new file mode 100644 index 000000000000..821a05a24f07 --- /dev/null +++ b/coverage/analysis/Average.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Average.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Average.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:263183.9 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis7Average10isPeriodicEv0
_ZN4PLMD8analysis7AverageC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis7Average11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis7Average17accumulateAverageERNS_10MultiValueE0
_ZN4PLMD8analysis7AverageC1ERKNS_13ActionOptionsE3
_ZN4PLMD8analysis7Average16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD8analysis7Average15finishAveragingEv1022
_ZN4PLMD8analysis7Average17performOperationsERKb1022
_ZN4PLMD8analysis7Average5applyEv1025
_ZN4PLMD8analysis7Average9calculateEv1025
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Average.cpp.func.html b/coverage/analysis/Average.cpp.func.html new file mode 100644 index 000000000000..5809729bbfb2 --- /dev/null +++ b/coverage/analysis/Average.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Average.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Average.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:263183.9 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis7Average10isPeriodicEv0
_ZN4PLMD8analysis7Average15finishAveragingEv1022
_ZN4PLMD8analysis7Average16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD8analysis7Average17performOperationsERKb1022
_ZN4PLMD8analysis7Average5applyEv1025
_ZN4PLMD8analysis7Average9calculateEv1025
_ZN4PLMD8analysis7AverageC1ERKNS_13ActionOptionsE3
_ZN4PLMD8analysis7AverageC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis7Average11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis7Average17accumulateAverageERNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Average.cpp.gcov.html b/coverage/analysis/Average.cpp.gcov.html new file mode 100644 index 000000000000..937e151bc4bc --- /dev/null +++ b/coverage/analysis/Average.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Average.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Average.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:263183.9 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "vesselbase/ActionWithAveraging.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "AverageVessel.h"
+      25             : 
+      26             : //+PLUMEDOC GRIDCALC AVERAGE
+      27             : /*
+      28             : Calculate the ensemble average of a collective variable
+      29             : 
+      30             : The ensemble average for a non-periodic, collective variable, \f$s\f$ is given by the following expression:
+      31             : 
+      32             : \f[
+      33             : \langle s \rangle = \frac{ \sum_{t'=0}^t w(t') s(t') }{ \sum_{t'=0}^t w(t') }
+      34             : \f]
+      35             : 
+      36             : Here the sum runs over a the trajectory and \f$s(t')\f$ is used to denote the value of the collective variable
+      37             : at time \f$t'\f$.  The final quantity evaluated is a weighted
+      38             : average as the weights, \f$w(t')\f$, allow us to negate the effect any bias might have on the region of phase space
+      39             : sampled by the system.  This is discussed in the section of the manual on \ref Analysis.
+      40             : 
+      41             : When the variable is periodic (e.g. \ref TORSION) and has a value, \f$s\f$, in \f$a \le s \le b\f$ the ensemble average is evaluated using:
+      42             : 
+      43             : \f[
+      44             : \langle s \rangle = a + \frac{b - a}{2\pi} \arctan \left[ \frac{ \sum_{t'=0}^t w(t') \sin\left( \frac{2\pi [s(t')-a]}{b - a} \right) }{ \sum_{t'=0}^t w(t') \cos\left( \frac{2\pi [s(t')-a]}{b - a} \right) } \right]
+      45             : \f]
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : The following example calculates the ensemble average for the distance between atoms 1 and 2
+      50             : and output this to a file called COLVAR.  In this example it is assumed that no bias is acting
+      51             : on the system and that the weights, \f$w(t')\f$ in the formulas above can thus all be set equal
+      52             : to one.
+      53             : 
+      54             : \plumedfile
+      55             : d1: DISTANCE ATOMS=1,2
+      56             : d1a: AVERAGE ARG=d1
+      57             : PRINT ARG=d1a FILE=colvar STRIDE=100
+      58             : \endplumedfile
+      59             : 
+      60             : The following example calculates the ensemble average for the torsional angle involving atoms 1, 2, 3 and 4.
+      61             : At variance with the previous example this quantity is periodic so the second formula in the above introduction
+      62             : is used to calculate the average.  Furthermore, by using the CLEAR keyword we have specified that block averages
+      63             : are to be calculated.  Consequently, after 100 steps all the information acquired thus far in the simulation is
+      64             : forgotten and the process of averaging is begun again.  The quantities output in the colvar file are thus the
+      65             : block averages taken over the first 100 frames of the trajectory, the block average over the second 100 frames
+      66             : of trajectory and so on.
+      67             : 
+      68             : \plumedfile
+      69             : t1: TORSION ATOMS=1,2,3,4
+      70             : t1a: AVERAGE ARG=t1 CLEAR=100
+      71             : PRINT ARG=t1a FILE=colvar STRIDE=100
+      72             : \endplumedfile
+      73             : 
+      74             : This third example incorporates a bias.  Notice that the effect the bias has on the ensemble average is removed by taking
+      75             : advantage of the \ref REWEIGHT_BIAS method.  The final ensemble averages output to the file are thus block ensemble averages for the
+      76             : unbiased canonical ensemble at a temperature of 300 K.
+      77             : 
+      78             : \plumedfile
+      79             : t1: TORSION ATOMS=1,2,3,4
+      80             : RESTRAINT ARG=t1 AT=pi KAPPA=100.
+      81             : ww: REWEIGHT_BIAS TEMP=300
+      82             : t1a: AVERAGE ARG=t1 LOGWEIGHTS=ww CLEAR=100
+      83             : PRINT ARG=t1a FILE=colvar STRIDE=100
+      84             : \endplumedfile
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : namespace PLMD {
+      90             : namespace analysis {
+      91             : 
+      92             : class Average : public vesselbase::ActionWithAveraging {
+      93             : private:
+      94             :   AverageVessel* myaverage;
+      95             : public:
+      96             :   static void registerKeywords( Keywords& keys );
+      97             :   explicit Average( const ActionOptions& );
+      98        1025 :   void calculate() override {}
+      99        1025 :   void apply() override {}
+     100             :   void performOperations( const bool& from_update ) override;
+     101             :   void finishAveraging() override;
+     102           0 :   bool isPeriodic() override { return false; }
+     103           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override { plumed_error(); }
+     104             :   void accumulateAverage( MultiValue& myvals ) const override;
+     105             : };
+     106             : 
+     107             : PLUMED_REGISTER_ACTION(Average,"AVERAGE")
+     108             : 
+     109           5 : void Average::registerKeywords( Keywords& keys ) {
+     110           5 :   vesselbase::ActionWithAveraging::registerKeywords( keys ); keys.use("ARG");
+     111          10 :   keys.remove("SERIAL"); keys.remove("LOWMEM");
+     112           5 : }
+     113             : 
+     114           3 : Average::Average( const ActionOptions& ao ):
+     115             :   Action(ao),
+     116           3 :   ActionWithAveraging(ao)
+     117             : {
+     118           6 :   addValue(); // Create a value so that we can output the average
+     119           3 :   if( getNumberOfArguments()!=1 ) error("only one quantity can be averaged at a time");
+     120             :   std::string instring;
+     121           3 :   if( getPntrToArgument(0)->isPeriodic() ) {
+     122           1 :     std::string min, max; getPntrToArgument(0)->getDomain(min,max);
+     123           2 :     instring = "PERIODIC=" + min + "," + max; setPeriodic( min, max );
+     124             :   } else {
+     125           2 :     setNotPeriodic();
+     126             :   }
+     127             :   // Create a vessel to hold the average
+     128           6 :   vesselbase::VesselOptions da("myaverage","",-1,instring,this);
+     129           3 :   Keywords keys; AverageVessel::registerKeywords( keys );
+     130           3 :   vesselbase::VesselOptions dar( da, keys );
+     131             :   auto average=Tools::make_unique<AverageVessel>(dar);
+     132           3 :   myaverage = average.get();
+     133           3 :   setAveragingAction( std::move(average), false );
+     134           6 : }
+     135             : 
+     136        1022 : void Average::performOperations( const bool& from_update ) {
+     137        1022 :   myaverage->accumulate( cweight, getArgument(0) );
+     138        1022 : }
+     139             : 
+     140           0 : void Average::accumulateAverage( MultiValue& myvals ) const {
+     141             :   plumed_dbg_assert( myvals.getNumberOfValues()==3 );
+     142           0 :   myaverage->accumulate( myvals.get(0), myvals.get(1) );
+     143           0 : }
+     144             : 
+     145        1022 : void Average::finishAveraging() {
+     146        1022 :   setValue( myaverage->getAverage() );
+     147        1022 : }
+     148             : 
+     149             : }
+     150             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.cpp.func-sort-c.html b/coverage/analysis/AverageVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..fdc7d846ff3f --- /dev/null +++ b/coverage/analysis/AverageVessel.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - analysis/AverageVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AverageVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222491.7 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8analysis13AverageVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE0
_ZN4PLMD8analysis13AverageVessel16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8analysis13AverageVessel6resizeEv3
_ZN4PLMD8analysis13AverageVesselC2ERKNS_10vesselbase13VesselOptionsE3
_ZN4PLMD8analysis13AverageVessel10accumulateERKdS3_1022
_ZNK4PLMD8analysis13AverageVessel10getAverageEv1022
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.cpp.func.html b/coverage/analysis/AverageVessel.cpp.func.html new file mode 100644 index 000000000000..2ff676d5e217 --- /dev/null +++ b/coverage/analysis/AverageVessel.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - analysis/AverageVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AverageVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222491.7 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13AverageVessel10accumulateERKdS3_1022
_ZN4PLMD8analysis13AverageVessel16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8analysis13AverageVessel6resizeEv3
_ZN4PLMD8analysis13AverageVesselC2ERKNS_10vesselbase13VesselOptionsE3
_ZNK4PLMD8analysis13AverageVessel10getAverageEv1022
_ZNK4PLMD8analysis13AverageVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.cpp.gcov.html b/coverage/analysis/AverageVessel.cpp.gcov.html new file mode 100644 index 000000000000..4536e243d570 --- /dev/null +++ b/coverage/analysis/AverageVessel.cpp.gcov.html @@ -0,0 +1,140 @@ + + + + + + + + LCOV - plumed test coverage - analysis/AverageVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AverageVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222491.7 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AverageVessel.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace analysis {
+      26             : 
+      27           3 : void AverageVessel::registerKeywords( Keywords& keys ) {
+      28           3 :   vesselbase::AveragingVessel::registerKeywords( keys );
+      29           6 :   keys.add("optional","PERIODIC","is the quantity being averaged periodic and what is its domain");
+      30           3 : }
+      31             : 
+      32           3 : AverageVessel::AverageVessel( const vesselbase::VesselOptions& da):
+      33           3 :   AveragingVessel(da)
+      34             : {
+      35           6 :   parseVector("PERIODIC",domain);
+      36           3 :   plumed_assert( domain.size()==2 || domain.size()==0 );
+      37           3 : }
+      38             : 
+      39           3 : void AverageVessel::resize() {
+      40             :   resizeBuffer(0);
+      41           3 :   if( domain.size()==2 ) setDataSize(2);
+      42           2 :   else setDataSize(1);
+      43           3 : }
+      44             : 
+      45        1022 : void AverageVessel::accumulate( const double& weight, const double& val ) {
+      46        1022 :   if( domain.size()==2 ) {
+      47             :     // Average with Berry Phase
+      48          11 :     double tval = 2*pi*( val - domain[0] ) / ( domain[1] - domain[0] );
+      49          11 :     addDataElement( 0, weight*std::sin(tval) ); addDataElement( 1, weight*std::cos(tval) );
+      50        1011 :   } else addDataElement( 0, weight*val );
+      51        1022 : }
+      52             : 
+      53        1022 : double AverageVessel::getAverage() const {
+      54        1022 :   if( domain.size()==2 ) return domain[0] + (( domain[1] - domain[0] )*std::atan2( getDataElement(0), getDataElement(1) ) / (2*pi));
+      55        1011 :   return getDataElement(0);
+      56             : }
+      57             : 
+      58           0 : void AverageVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+      59           0 :   plumed_error();
+      60             : }
+      61             : 
+      62             : }
+      63             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.h.func-sort-c.html b/coverage/analysis/AverageVessel.h.func-sort-c.html new file mode 100644 index 000000000000..71af8444992d --- /dev/null +++ b/coverage/analysis/AverageVessel.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - analysis/AverageVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AverageVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13AverageVessel11descriptionB5cxx11Ev3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.h.func.html b/coverage/analysis/AverageVessel.h.func.html new file mode 100644 index 000000000000..8faa8eabef37 --- /dev/null +++ b/coverage/analysis/AverageVessel.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - analysis/AverageVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AverageVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13AverageVessel11descriptionB5cxx11Ev3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/AverageVessel.h.gcov.html b/coverage/analysis/AverageVessel.h.gcov.html new file mode 100644 index 000000000000..506465f3fab9 --- /dev/null +++ b/coverage/analysis/AverageVessel.h.gcov.html @@ -0,0 +1,128 @@ + + + + + + + + LCOV - plumed test coverage - analysis/AverageVessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - AverageVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_analysis_AverageVessel_h
+      23             : #define __PLUMED_analysis_AverageVessel_h
+      24             : 
+      25             : #include "vesselbase/AveragingVessel.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace analysis {
+      29             : 
+      30             : class AverageVessel : public vesselbase::AveragingVessel {
+      31             : private:
+      32             :   std::vector<double> domain;
+      33             : public:
+      34             :   /// keywords
+      35             :   static void registerKeywords( Keywords& keys );
+      36             : /// Constructor
+      37             :   explicit AverageVessel( const vesselbase::VesselOptions& );
+      38             : /// Set the size of the data vessel
+      39             :   void resize() override;
+      40             : /// This does nothing
+      41             :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const override;
+      42           3 :   std::string description() override { return ""; }
+      43             : /// Accumulate the average
+      44             :   void accumulate( const double& weight, const double& val );
+      45             : /// Get the average value
+      46             :   double getAverage() const ;
+      47             : };
+      48             : 
+      49             : }
+      50             : }
+      51             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Committor.cpp.func-sort-c.html b/coverage/analysis/Committor.cpp.func-sort-c.html new file mode 100644 index 000000000000..9ac4dd8790d1 --- /dev/null +++ b/coverage/analysis/Committor.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Committor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Committor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis9CommittorC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis9CommittorC1ERKNS_13ActionOptionsE9
_ZN4PLMD8analysis9Committor16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD8analysis9Committor5applyEv30
_ZN4PLMD8analysis9Committor9calculateEv30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Committor.cpp.func.html b/coverage/analysis/Committor.cpp.func.html new file mode 100644 index 000000000000..4cb8359892fa --- /dev/null +++ b/coverage/analysis/Committor.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Committor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Committor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis9Committor16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD8analysis9Committor5applyEv30
_ZN4PLMD8analysis9Committor9calculateEv30
_ZN4PLMD8analysis9CommittorC1ERKNS_13ActionOptionsE9
_ZN4PLMD8analysis9CommittorC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Committor.cpp.gcov.html b/coverage/analysis/Committor.cpp.gcov.html new file mode 100644 index 000000000000..581d50184e24 --- /dev/null +++ b/coverage/analysis/Committor.cpp.gcov.html @@ -0,0 +1,268 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Committor.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Committor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace analysis {
+      30             : 
+      31             : //+PLUMEDOC PRINTANALYSIS COMMITTOR
+      32             : /*
+      33             : Does a committor analysis.
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : The following input monitors two torsional angles during a simulation,
+      38             : defines two basins (A and B) as a function of the two torsion angles and
+      39             : stops the simulation when it falls in one of the two. In the log
+      40             : file will be shown the latest values for the CVs and the basin reached.
+      41             : \plumedfile
+      42             : TORSION ATOMS=1,2,3,4 LABEL=r1
+      43             : TORSION ATOMS=2,3,4,5 LABEL=r2
+      44             : COMMITTOR ...
+      45             :   ARG=r1,r2
+      46             :   STRIDE=10
+      47             :   BASIN_LL1=0.15,0.20
+      48             :   BASIN_UL1=0.25,0.40
+      49             :   BASIN_LL2=-0.25,-0.40
+      50             :   BASIN_UL2=-0.15,-0.20
+      51             : ... COMMITTOR
+      52             : \endplumedfile
+      53             : 
+      54             : */
+      55             : //+ENDPLUMEDOC
+      56             : 
+      57             : class Committor :
+      58             :   public ActionPilot,
+      59             :   public ActionWithArguments
+      60             : {
+      61             : private:
+      62             :   std::string file;
+      63             :   OFile ofile;
+      64             :   std::string fmt;
+      65             :   std::vector< std::vector<double> > lowerlimits;
+      66             :   std::vector< std::vector<double> > upperlimits;
+      67             :   unsigned nbasins;
+      68             :   unsigned basin;
+      69             :   bool doNotStop;
+      70             : public:
+      71             :   static void registerKeywords( Keywords& keys );
+      72             :   explicit Committor(const ActionOptions&ao);
+      73             :   void calculate() override;
+      74          30 :   void apply() override {}
+      75             : };
+      76             : 
+      77             : PLUMED_REGISTER_ACTION(Committor,"COMMITTOR")
+      78             : 
+      79          11 : void Committor::registerKeywords( Keywords& keys ) {
+      80          11 :   Action::registerKeywords(keys);
+      81          11 :   ActionPilot::registerKeywords(keys);
+      82          11 :   ActionWithArguments::registerKeywords(keys);
+      83          11 :   keys.use("ARG");
+      84          22 :   keys.add("numbered", "BASIN_LL","List of lower limits for basin #");
+      85          22 :   keys.add("numbered", "BASIN_UL","List of upper limits for basin #");
+      86          33 :   keys.reset_style("BASIN_LL","compulsory"); keys.reset_style("BASIN_UL","compulsory");
+      87          22 :   keys.add("compulsory","STRIDE","1","the frequency with which the CVs are analyzed");
+      88          22 :   keys.add("optional","FILE","the name of the file on which to output the reached basin");
+      89          22 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+      90          22 :   keys.addFlag("NOSTOP",false,"if true do not stop the simulation when reaching a basin but just keep track of it");
+      91          11 : }
+      92             : 
+      93           9 : Committor::Committor(const ActionOptions&ao):
+      94             :   Action(ao),
+      95             :   ActionPilot(ao),
+      96             :   ActionWithArguments(ao),
+      97           9 :   fmt("%f"),
+      98             :   basin(0),
+      99          18 :   doNotStop(false)
+     100             : {
+     101           9 :   ofile.link(*this);
+     102          18 :   parse("FILE",file);
+     103           9 :   if(file.length()>0) {
+     104           2 :     ofile.open(file);
+     105           2 :     log.printf("  on file %s\n",file.c_str());
+     106             :   } else {
+     107           7 :     log.printf("  on plumed log file\n");
+     108           7 :     ofile.link(log);
+     109             :   }
+     110           9 :   parse("FMT",fmt);
+     111           9 :   fmt=" "+fmt;
+     112           9 :   log.printf("  with format %s\n",fmt.c_str());
+     113             : 
+     114          13 :   for(unsigned b=1;; ++b ) {
+     115             :     std::vector<double> tmpl, tmpu;
+     116          22 :     parseNumberedVector("BASIN_LL", b, tmpl );
+     117          44 :     parseNumberedVector("BASIN_UL", b, tmpu );
+     118          22 :     if( tmpl.empty() && tmpu.empty() ) break;
+     119          13 :     if( tmpl.size()!=getNumberOfArguments()) error("Wrong number of values for BASIN_LL: they should be equal to the number of arguments");
+     120          13 :     if( tmpu.size()!=getNumberOfArguments()) error("Wrong number of values for BASIN_UL: they should be equal to the number of arguments");
+     121          13 :     lowerlimits.push_back(tmpl);
+     122          13 :     upperlimits.push_back(tmpu);
+     123          13 :     nbasins=b;
+     124          13 :   }
+     125             : 
+     126           9 :   parseFlag("NOSTOP", doNotStop);
+     127             : 
+     128           9 :   checkRead();
+     129             : 
+     130             : 
+     131          22 :   for(unsigned b=0; b<nbasins; b++) {
+     132          13 :     log.printf("  BASIN %u definition:\n", b+1);
+     133          32 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     134          19 :       if(lowerlimits[b][i]>upperlimits[b][i]) error("COMMITTOR: UPPER bounds must always be greater than LOWER bounds");
+     135          19 :       log.printf(" %f - %f\n", lowerlimits[b][i], upperlimits[b][i]);
+     136             :     }
+     137          13 :     if(doNotStop) log.printf(" COMMITOR will keep track of the visited basins without stopping the simulations\n");
+     138             :   }
+     139             : 
+     140          20 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) ofile.setupPrintValue( getPntrToArgument(i) );
+     141           9 : }
+     142             : 
+     143          30 : void Committor::calculate() {
+     144             :   std::vector<unsigned> inbasin;
+     145          30 :   inbasin.assign (nbasins,1);
+     146             : 
+     147             :   // check if current configuration belongs to a basin
+     148         106 :   for(unsigned b=0; b<nbasins; ++b) {
+     149         221 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     150         145 :       if(getArgument(i)>lowerlimits[b][i]&&getArgument(i)<upperlimits[b][i]) {
+     151             :         inbasin[b]*=1;
+     152             :       } else {
+     153          80 :         inbasin[b]*=0;
+     154             :       }
+     155             :     }
+     156             :   }
+     157             : 
+     158             :   // check in which basin we are if any and if this is the same or a new one
+     159             :   bool inonebasin = false;
+     160          71 :   for(unsigned b=0; b<nbasins; ++b) {
+     161          61 :     if(inbasin[b]==1) {
+     162          20 :       if(basin!=(b+1)) {
+     163          15 :         basin = b+1;
+     164          15 :         ofile.fmtField(" %f");
+     165          15 :         ofile.printField("time",getTime());
+     166          38 :         for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     167          23 :           ofile.fmtField(fmt);
+     168          23 :           ofile.printField( getPntrToArgument(i), getArgument(i) );
+     169             :         }
+     170          15 :         ofile.printField("basin", static_cast<int> (b+1));
+     171          15 :         ofile.printField();
+     172             :       }
+     173             :       inonebasin = true;
+     174             :       break;
+     175             :     }
+     176             :   }
+     177          10 :   if(!inonebasin) basin = 0;
+     178             : 
+     179             :   // then check if the simulation should be stopped
+     180          30 :   if(inonebasin&&(!doNotStop)) {
+     181           8 :     std::string num; Tools::convert( basin, num );
+     182           8 :     std::string str = "COMMITTED TO BASIN " + num;
+     183           8 :     ofile.addConstantField(str);
+     184           8 :     ofile.printField();
+     185           8 :     ofile.flush();
+     186           8 :     plumed.stop();
+     187             :   }
+     188          30 : }
+     189             : 
+     190             : }
+     191             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.cpp.func-sort-c.html b/coverage/analysis/DataCollectionObject.cpp.func-sort-c.html new file mode 100644 index 000000000000..ea75a657cf3e --- /dev/null +++ b/coverage/analysis/DataCollectionObject.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/DataCollectionObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - DataCollectionObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis20DataCollectionObject16setAtomPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EE7556
_ZN4PLMD8analysis20DataCollectionObject30setAtomNumbersAndArgumentNamesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_10AtomNumberESaISB_EERKSA_IS7_SaIS7_EE7556
_ZN4PLMD8analysis20DataCollectionObject11setArgumentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKd16321
_ZN4PLMD8analysis20DataCollectionObject17transferDataToPDBERNS_3PDBE522438
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.cpp.func.html b/coverage/analysis/DataCollectionObject.cpp.func.html new file mode 100644 index 000000000000..02e7a49bc674 --- /dev/null +++ b/coverage/analysis/DataCollectionObject.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/DataCollectionObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - DataCollectionObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis20DataCollectionObject11setArgumentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKd16321
_ZN4PLMD8analysis20DataCollectionObject16setAtomPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EE7556
_ZN4PLMD8analysis20DataCollectionObject17transferDataToPDBERNS_3PDBE522438
_ZN4PLMD8analysis20DataCollectionObject30setAtomNumbersAndArgumentNamesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorINS_10AtomNumberESaISB_EERKSA_IS7_SaIS7_EE7556
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.cpp.gcov.html b/coverage/analysis/DataCollectionObject.cpp.gcov.html new file mode 100644 index 000000000000..15a303ed018e --- /dev/null +++ b/coverage/analysis/DataCollectionObject.cpp.gcov.html @@ -0,0 +1,140 @@ + + + + + + + + LCOV - plumed test coverage - analysis/DataCollectionObject.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - DataCollectionObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DataCollectionObject.h"
+      23             : #include "tools/PDB.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace analysis {
+      27             : 
+      28        7556 : void DataCollectionObject::setAtomNumbersAndArgumentNames( const std::string& action_label, const std::vector<AtomNumber>& ind, const std::vector<std::string>& arg_names ) {
+      29        7556 :   myaction=action_label; indices.resize( ind.size() ); positions.resize( indices.size() );
+      30       21193 :   for(unsigned i=0; i<ind.size(); ++i) indices[i]=ind[i];
+      31       16583 :   for(unsigned i=0; i<arg_names.size(); ++i) args.insert( std::pair<std::string,double>( arg_names[i], 0.0 ) );
+      32        7556 : }
+      33             : 
+      34        7556 : void DataCollectionObject::setAtomPositions( const std::vector<Vector>& pos ) {
+      35             :   plumed_dbg_assert( pos.size()==positions.size() && pos.size()==indices.size() );
+      36       21193 :   for(unsigned i=0; i<positions.size(); ++i) positions[i]=pos[i];
+      37        7556 : }
+      38             : 
+      39       16321 : void DataCollectionObject::setArgument( const std::string& name, const double& value ) {
+      40             :   std::map<std::string,double>::iterator it = args.find(name);
+      41       16321 :   if( it!=args.end() ) it->second = value;
+      42        6694 :   else args.insert( std::pair<std::string,double>( name, value ) );
+      43       16321 : }
+      44             : 
+      45      522438 : bool DataCollectionObject::transferDataToPDB( PDB& mypdb ) {
+      46             :   // Check if PDB contains argument names
+      47      522438 :   std::vector<std::string> pdb_args( mypdb.getArgumentNames() );
+      48             :   // Now set the argument values
+      49             :   std::map<std::string,double>::iterator it;
+      50     2024164 :   for(unsigned i=0; i<pdb_args.size(); ++i) {
+      51             :     it=args.find( pdb_args[i] );
+      52     1501726 :     if( it==args.end() ) return false;
+      53     1501726 :     mypdb.setArgumentValue( pdb_args[i], it->second );
+      54             :   }
+      55             :   // Now set the atomic positions
+      56      522438 :   std::vector<AtomNumber> pdb_pos( mypdb.getAtomNumbers() );
+      57      522438 :   if( pdb_pos.size()==positions.size() ) mypdb.setAtomPositions( positions );
+      58       29720 :   else if( pdb_pos.size()>0 ) plumed_merror("This feature is currently not ready");
+      59             :   return true;
+      60      522438 : }
+      61             : 
+      62             : }
+      63             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.h.func-sort-c.html b/coverage/analysis/DataCollectionObject.h.func-sort-c.html new file mode 100644 index 000000000000..5874302a4a54 --- /dev/null +++ b/coverage/analysis/DataCollectionObject.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - analysis/DataCollectionObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - DataCollectionObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4580.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8analysis20DataCollectionObject16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6517
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.h.func.html b/coverage/analysis/DataCollectionObject.h.func.html new file mode 100644 index 000000000000..6aa676ad48b0 --- /dev/null +++ b/coverage/analysis/DataCollectionObject.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - analysis/DataCollectionObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - DataCollectionObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4580.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8analysis20DataCollectionObject16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6517
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/DataCollectionObject.h.gcov.html b/coverage/analysis/DataCollectionObject.h.gcov.html new file mode 100644 index 000000000000..52303a4c6685 --- /dev/null +++ b/coverage/analysis/DataCollectionObject.h.gcov.html @@ -0,0 +1,156 @@ + + + + + + + + LCOV - plumed test coverage - analysis/DataCollectionObject.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - DataCollectionObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4580.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_analysis_DataCollectionObject_h
+      23             : #define __PLUMED_analysis_DataCollectionObject_h
+      24             : 
+      25             : #include <map>
+      26             : #include <vector>
+      27             : #include "tools/Vector.h"
+      28             : #include "tools/AtomNumber.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : class PDB;
+      33             : 
+      34             : namespace analysis {
+      35             : 
+      36             : class DataCollectionObject {
+      37             :   friend class ReadAnalysisFrames;
+      38             : private:
+      39             : /// The label of the action in which the data is stored
+      40             :   std::string myaction;
+      41             : /// The list of atom numbers that are stored in the object
+      42             :   std::vector<AtomNumber> indices;
+      43             : /// The list of atomic positions
+      44             :   std::vector<Vector> positions;
+      45             : /// The map containing the arguments that we are storing
+      46             :   std::map<std::string,double> args;
+      47             : public:
+      48             : /// Set the names and atom numbers
+      49             :   void setAtomNumbersAndArgumentNames( const std::string& action_label, const std::vector<AtomNumber>& ind, const std::vector<std::string>& arg_names );
+      50             : /// Set the positions of all the atoms
+      51             :   void setAtomPositions( const std::vector<Vector>& pos );
+      52             : /// Set the value of one of the arguments
+      53             :   void setArgument( const std::string& name, const double& value );
+      54             : /// Return one of the atomic positions
+      55             :   Vector getAtomPosition( const AtomNumber& ind ) const ;
+      56             : /// Get the value of one of the arguments
+      57             :   double getArgumentValue( const std::string& name ) const ;
+      58             : /// Transfer the data inside the object to a PDB object
+      59             :   bool transferDataToPDB( PDB& mypdb );
+      60             : };
+      61             : 
+      62             : inline
+      63             : Vector DataCollectionObject::getAtomPosition( const AtomNumber& ind ) const {
+      64             :   return positions[ind.index()];
+      65             : }
+      66             : 
+      67             : inline
+      68        6517 : double DataCollectionObject::getArgumentValue( const std::string& name ) const {
+      69             :   std::map<std::string,double>::const_iterator it = args.find(name);
+      70        6517 :   if( it != args.end() ) return it->second;
+      71        2106 :   std::size_t dot=name.find_first_of('.'); std::string a=name.substr(0,dot);
+      72        4212 :   if( a==myaction ) return args.find( name.substr(dot+1) )->second;
+      73           0 :   else plumed_merror("could not find required data in collection object");
+      74             : }
+      75             : 
+      76             : }
+      77             : }
+      78             : 
+      79             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func-sort-c.html b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..12e2a3d6ed80 --- /dev/null +++ b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - analysis/EuclideanDissimilarityMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - EuclideanDissimilarityMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:495983.1 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis28EuclideanDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD8analysis28EuclideanDissimilarityMatrixC1ERKNS_13ActionOptionsE13
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix15performAnalysisEv20
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix27getDissimilarityInstructionB5cxx11Ev413
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix22dissimilaritiesWereSetEv436
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix16getDissimilarityERKjS3_611659
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func.html b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func.html new file mode 100644 index 000000000000..9d5332def3db --- /dev/null +++ b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - analysis/EuclideanDissimilarityMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - EuclideanDissimilarityMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:495983.1 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix15performAnalysisEv20
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix16getDissimilarityERKjS3_611659
_ZN4PLMD8analysis28EuclideanDissimilarityMatrix16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD8analysis28EuclideanDissimilarityMatrixC1ERKNS_13ActionOptionsE13
_ZN4PLMD8analysis28EuclideanDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix22dissimilaritiesWereSetEv436
_ZNK4PLMD8analysis28EuclideanDissimilarityMatrix27getDissimilarityInstructionB5cxx11Ev413
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/EuclideanDissimilarityMatrix.cpp.gcov.html b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.gcov.html new file mode 100644 index 000000000000..c10f2001a891 --- /dev/null +++ b/coverage/analysis/EuclideanDissimilarityMatrix.cpp.gcov.html @@ -0,0 +1,223 @@ + + + + + + + + LCOV - plumed test coverage - analysis/EuclideanDissimilarityMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - EuclideanDissimilarityMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:495983.1 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AnalysisBase.h"
+      23             : #include "tools/PDB.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "reference/MetricRegister.h"
+      26             : #include "reference/ReferenceConfiguration.h"
+      27             : 
+      28             : //+PLUMEDOC ANALYSIS EUCLIDEAN_DISSIMILARITIES
+      29             : /*
+      30             : Calculate the matrix of dissimilarities between a trajectory of atomic configurations.
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace analysis {
+      39             : 
+      40             : class EuclideanDissimilarityMatrix : public AnalysisBase {
+      41             : private:
+      42             :   PDB mypdb;
+      43             :   std::string mtype;
+      44             :   Matrix<double> dissimilarities;
+      45             : public:
+      46             :   static void registerKeywords( Keywords& keys );
+      47             :   explicit EuclideanDissimilarityMatrix( const ActionOptions& ao );
+      48             : /// Do the analysis
+      49             :   void performAnalysis() override;
+      50             : /// This ensures that classes that use this data know that dissimilarities were set
+      51         436 :   bool dissimilaritiesWereSet() const override { return true; }
+      52             : /// Get information on how to calculate dissimilarities
+      53             :   std::string getDissimilarityInstruction() const override;
+      54             : /// Get the squared dissimilarity between two reference configurations
+      55             :   double getDissimilarity( const unsigned& i, const unsigned& j ) override;
+      56             : /// This is just to deal with ActionWithVessel
+      57           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override { plumed_error(); }
+      58             : };
+      59             : 
+      60             : PLUMED_REGISTER_ACTION(EuclideanDissimilarityMatrix,"EUCLIDEAN_DISSIMILARITIES")
+      61             : 
+      62          15 : void EuclideanDissimilarityMatrix::registerKeywords( Keywords& keys ) {
+      63          45 :   AnalysisBase::registerKeywords( keys ); keys.use("ARG"); keys.reset_style("ARG","optional");
+      64          30 :   keys.add("compulsory","METRIC","EUCLIDEAN","the method that you are going to use to measure the distances between points");
+      65          30 :   keys.add("atoms","ATOMS","the list of atoms that you are going to use in the measure of distance that you are using");
+      66          15 : }
+      67             : 
+      68          13 : EuclideanDissimilarityMatrix::EuclideanDissimilarityMatrix( const ActionOptions& ao ):
+      69             :   Action(ao),
+      70          13 :   AnalysisBase(ao)
+      71             : {
+      72          26 :   parse("METRIC",mtype); std::vector<AtomNumber> atoms;
+      73          13 :   if( my_input_data->getNumberOfAtoms()>0 ) {
+      74           6 :     parseAtomList("ATOMS",atoms);
+      75           3 :     if( atoms.size()!=0 ) {
+      76           0 :       mypdb.setAtomNumbers( atoms );
+      77           0 :       for(unsigned i=0; i<atoms.size(); ++i) {
+      78             :         bool found=false;
+      79           0 :         for(unsigned j=0; j<my_input_data->getAtomIndexes().size(); ++j) {
+      80           0 :           if( my_input_data->getAtomIndexes()[j]==atoms[i] ) { found=true; break; }
+      81             :         }
+      82           0 :         if( !found ) {
+      83           0 :           std::string num; Tools::convert( atoms[i].serial(), num );
+      84           0 :           error("atom number " + num + " is not stored in any action that has been input");
+      85             :         }
+      86             :       }
+      87           0 :       mypdb.addBlockEnd( atoms.size() );
+      88           3 :     } else if( getNumberOfArguments()==0 ) {
+      89           1 :       mypdb.setAtomNumbers( my_input_data->getAtomIndexes() );
+      90           1 :       mypdb.addBlockEnd( my_input_data->getAtomIndexes().size() );
+      91           1 :       if( mtype=="EUCLIDEAN" ) mtype="OPTIMAL";
+      92             :     }
+      93             :   }
+      94          13 :   log.printf("  measuring distances using %s metric \n",mtype.c_str() );
+      95          13 :   if( my_input_data->getArgumentNames().size()>0 ) {
+      96          12 :     if( getNumberOfArguments()==0 && atoms.size()==0 ) {
+      97          10 :       std::vector<std::string> argnames( my_input_data->getArgumentNames() );
+      98          10 :       mypdb.setArgumentNames( argnames ); requestArguments( my_input_data->getArgumentList() );
+      99          10 :     } else {
+     100           2 :       std::vector<Value*> myargs( getArguments() );
+     101           2 :       std::vector<std::string> inargnames( my_input_data->getArgumentNames() );
+     102           2 :       std::vector<std::string> argnames( myargs.size() );
+     103           6 :       for(unsigned i=0; i<myargs.size(); ++i) {
+     104           4 :         argnames[i]=myargs[i]->getName();
+     105             :         bool found=false;
+     106           6 :         for(unsigned j=0; j<inargnames.size(); ++j) {
+     107           6 :           if( argnames[i]==inargnames[j] ) { found=true; break; }
+     108             :         }
+     109           4 :         if( !found ) error("input named " + my_input_data->getLabel() + " does not store/calculate quantity named " + argnames[i] );
+     110             :       }
+     111           2 :       mypdb.setArgumentNames( argnames ); requestArguments( myargs );
+     112           2 :     }
+     113             :   }
+     114          13 : }
+     115             : 
+     116          20 : void EuclideanDissimilarityMatrix::performAnalysis() {
+     117             :   // Resize dissimilarities matrix and set all elements to zero
+     118          20 :   if( !usingLowMem() ) {
+     119          20 :     dissimilarities.resize( getNumberOfDataPoints(), getNumberOfDataPoints() ); dissimilarities=0;
+     120             :   }
+     121          20 : }
+     122             : 
+     123         413 : std::string EuclideanDissimilarityMatrix::getDissimilarityInstruction() const {
+     124         413 :   return "TYPE=" + mtype;
+     125             : }
+     126             : 
+     127      611659 : double EuclideanDissimilarityMatrix::getDissimilarity( const unsigned& iframe, const unsigned& jframe ) {
+     128             :   plumed_dbg_assert( iframe<getNumberOfDataPoints() && jframe<getNumberOfDataPoints() );
+     129      611659 :   if( !usingLowMem() ) {
+     130      611659 :     if( dissimilarities(iframe,jframe)>0. ) { return dissimilarities(iframe,jframe); }
+     131             :   }
+     132      256165 :   if( iframe!=jframe ) {
+     133             :     double dd;
+     134      255613 :     getStoredData( iframe, true ).transferDataToPDB( mypdb );
+     135      255613 :     auto myref1=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     136      255613 :     getStoredData( jframe, true ).transferDataToPDB( mypdb );
+     137      255613 :     auto myref2=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     138      255613 :     if( !usingLowMem() ) dd=dissimilarities(iframe,jframe) = dissimilarities(jframe,iframe) = distance( getPbc(), getArguments(), myref1.get(), myref2.get(), true );
+     139           0 :     else dd=distance( getPbc(), getArguments(), myref1.get(), myref2.get(), true );
+     140             :     return dd;
+     141      255613 :   }
+     142             :   return 0.0;
+     143             : }
+     144             : 
+     145             : }
+     146             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/FarthestPointSampling.cpp.func-sort-c.html b/coverage/analysis/FarthestPointSampling.cpp.func-sort-c.html new file mode 100644 index 000000000000..8dbeb65154d4 --- /dev/null +++ b/coverage/analysis/FarthestPointSampling.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/FarthestPointSampling.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - FarthestPointSampling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21FarthestPointSamplingC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis21FarthestPointSampling15selectLandmarksEv1
_ZN4PLMD8analysis21FarthestPointSamplingC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis21FarthestPointSampling16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/FarthestPointSampling.cpp.func.html b/coverage/analysis/FarthestPointSampling.cpp.func.html new file mode 100644 index 000000000000..42dffe734ea5 --- /dev/null +++ b/coverage/analysis/FarthestPointSampling.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/FarthestPointSampling.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - FarthestPointSampling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21FarthestPointSampling15selectLandmarksEv1
_ZN4PLMD8analysis21FarthestPointSampling16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8analysis21FarthestPointSamplingC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis21FarthestPointSamplingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/FarthestPointSampling.cpp.gcov.html b/coverage/analysis/FarthestPointSampling.cpp.gcov.html new file mode 100644 index 000000000000..ea0b1d1fd36e --- /dev/null +++ b/coverage/analysis/FarthestPointSampling.cpp.gcov.html @@ -0,0 +1,168 @@ + + + + + + + + LCOV - plumed test coverage - analysis/FarthestPointSampling.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - FarthestPointSampling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "LandmarkSelectionBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Random.h"
+      25             : 
+      26             : //+PLUMEDOC LANDMARKS LANDMARK_SELECT_FPS
+      27             : /*
+      28             : Select a set of landmarks using farthest point sampling.
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace analysis {
+      37             : 
+      38             : class FarthestPointSampling : public LandmarkSelectionBase {
+      39             : private:
+      40             :   unsigned seed;
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             :   explicit FarthestPointSampling( const ActionOptions& ao );
+      44             :   void selectLandmarks() override;
+      45             : };
+      46             : 
+      47             : PLUMED_REGISTER_ACTION(FarthestPointSampling,"LANDMARK_SELECT_FPS")
+      48             : 
+      49           3 : void FarthestPointSampling::registerKeywords( Keywords& keys ) {
+      50           3 :   LandmarkSelectionBase::registerKeywords(keys);
+      51           6 :   keys.add("compulsory","SEED","1234","a random number seed");
+      52           3 : }
+      53             : 
+      54           1 : FarthestPointSampling::FarthestPointSampling( const ActionOptions& ao ):
+      55             :   Action(ao),
+      56           1 :   LandmarkSelectionBase(ao)
+      57             : {
+      58           1 :   if( !dissimilaritiesWereSet() ) error("dissimilarities have not been calcualted in input action");
+      59           1 :   parse("SEED",seed);
+      60           1 : }
+      61             : 
+      62           1 : void FarthestPointSampling::selectLandmarks() {
+      63           1 :   std::vector<unsigned> landmarks( getNumberOfDataPoints() );
+      64             : 
+      65             :   // Select first point at random
+      66           1 :   Random random; random.setSeed(-seed); double rand=random.RandU01();
+      67           1 :   landmarks[0] = std::floor( my_input_data->getNumberOfDataPoints()*rand );
+      68           1 :   selectFrame( landmarks[0] );
+      69             : 
+      70             :   // Now find distance to all other points (N.B. We can use squared distances here for speed)
+      71           1 :   Matrix<double> distances( getNumberOfDataPoints(), my_input_data->getNumberOfDataPoints() );
+      72          14 :   for(unsigned i=0; i<my_input_data->getNumberOfDataPoints(); ++i) distances(0,i) = my_input_data->getDissimilarity( landmarks[0], i );
+      73             : 
+      74             :   // Now find all other landmarks
+      75           3 :   for(unsigned i=1; i<getNumberOfDataPoints(); ++i) {
+      76             :     // Find point that has the largest minimum distance from the landmarks selected thus far
+      77             :     double maxd=0;
+      78          28 :     for(unsigned j=0; j<my_input_data->getNumberOfDataPoints(); ++j) {
+      79          26 :       double mind=distances(0,j);
+      80          39 :       for(unsigned k=1; k<i; ++k) {
+      81          13 :         if( distances(k,j)<mind ) { mind=distances(k,j); }
+      82             :       }
+      83          26 :       if( mind>maxd ) { maxd=mind; landmarks[i]=j; }
+      84             :     }
+      85           2 :     selectFrame( landmarks[i] );
+      86          28 :     for(unsigned k=0; k<my_input_data->getNumberOfDataPoints(); ++k) distances(i,k) = my_input_data->getDissimilarity( landmarks[i], k );
+      87             :   }
+      88           1 : }
+      89             : 
+      90             : }
+      91             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Histogram.cpp.func-sort-c.html b/coverage/analysis/Histogram.cpp.func-sort-c.html new file mode 100644 index 000000000000..ff9ccb313e3d --- /dev/null +++ b/coverage/analysis/Histogram.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Histogram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Histogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:20220797.6 %
Date:2024-02-22 21:58:45Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis9Histogram10isPeriodicEv0
_ZN4PLMD8analysis9HistogramC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis9Histogram17performOperationsERKb5
_ZN4PLMD8analysis9Histogram17turnOnDerivativesEv8
_ZN4PLMD8analysis9HistogramC1ERKNS_13ActionOptionsE34
_ZN4PLMD8analysis9Histogram16registerKeywordsERNS_8KeywordsE36
_ZN4PLMD8analysis9Histogram19prepareForAveragingEv115
_ZNK4PLMD8analysis9Histogram10threadSafeEv121
_ZN4PLMD8analysis9Histogram5applyEv133
_ZN4PLMD8analysis9Histogram15finishAveragingEv135
_ZNK4PLMD8analysis9Histogram21getNumberOfQuantitiesEv462
_ZN4PLMD8analysis9Histogram22getNumberOfDerivativesEv728
_ZNK4PLMD8analysis9Histogram7computeERKjRNS_10MultiValueE15404
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Histogram.cpp.func.html b/coverage/analysis/Histogram.cpp.func.html new file mode 100644 index 000000000000..f7c5aef2d1ba --- /dev/null +++ b/coverage/analysis/Histogram.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Histogram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Histogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:20220797.6 %
Date:2024-02-22 21:58:45Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis9Histogram10isPeriodicEv0
_ZN4PLMD8analysis9Histogram15finishAveragingEv135
_ZN4PLMD8analysis9Histogram16registerKeywordsERNS_8KeywordsE36
_ZN4PLMD8analysis9Histogram17performOperationsERKb5
_ZN4PLMD8analysis9Histogram17turnOnDerivativesEv8
_ZN4PLMD8analysis9Histogram19prepareForAveragingEv115
_ZN4PLMD8analysis9Histogram22getNumberOfDerivativesEv728
_ZN4PLMD8analysis9Histogram5applyEv133
_ZN4PLMD8analysis9HistogramC1ERKNS_13ActionOptionsE34
_ZN4PLMD8analysis9HistogramC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis9Histogram10threadSafeEv121
_ZNK4PLMD8analysis9Histogram21getNumberOfQuantitiesEv462
_ZNK4PLMD8analysis9Histogram7computeERKjRNS_10MultiValueE15404
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/Histogram.cpp.gcov.html b/coverage/analysis/Histogram.cpp.gcov.html new file mode 100644 index 000000000000..d48bdac74be0 --- /dev/null +++ b/coverage/analysis/Histogram.cpp.gcov.html @@ -0,0 +1,612 @@ + + + + + + + + LCOV - plumed test coverage - analysis/Histogram.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - Histogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:20220797.6 %
Date:2024-02-22 21:58:45Functions:111384.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/KernelFunctions.h"
+      24             : #include "gridtools/ActionWithGrid.h"
+      25             : #include "vesselbase/ActionWithVessel.h"
+      26             : #include "vesselbase/StoreDataVessel.h"
+      27             : #include "multicolvar/MultiColvarBase.h"
+      28             : #include "core/PlumedMain.h"
+      29             : #include "core/ActionSet.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace analysis {
+      33             : 
+      34             : //+PLUMEDOC GRIDCALC HISTOGRAM
+      35             : /*
+      36             : Accumulate the average probability density along a few CVs from a trajectory.
+      37             : 
+      38             : When using this method it is supposed that you have some collective variable \f$\zeta\f$ that
+      39             : gives a reasonable description of some physical or chemical phenomenon.  As an example of what we
+      40             : mean by this suppose you wish to examine the following SN2 reaction:
+      41             : 
+      42             : \f[
+      43             :  \textrm{OH}^- + \textrm{CH}_3Cl  \rightarrow \textrm{CH}_3OH + \textrm{Cl}^-
+      44             : \f]
+      45             : 
+      46             : The distance between the chlorine atom and the carbon is an excellent collective variable, \f$\zeta\f$,
+      47             : in this case because this distance is short for the reactant, \f$\textrm{CH}_3Cl\f$, because the carbon
+      48             : and chlorine are chemically bonded, and because it is long for the product state when these two atoms are
+      49             : not chemically bonded.  We thus might want to accumulate the probability density, \f$P(\zeta)\f$, as a function of this distance
+      50             : as this will provide us with information about the overall likelihood of the reaction.   Furthermore, the
+      51             : free energy, \f$F(\zeta)\f$, is related to this probability density via:
+      52             : 
+      53             : \f[
+      54             : F(\zeta) = - k_B T \ln P(\zeta)
+      55             : \f]
+      56             : 
+      57             : Accumulating these probability densities is precisely what this Action can be used to do.  Furthermore, the conversion
+      58             : of the histogram to the free energy can be achieved by using the method \ref CONVERT_TO_FES.
+      59             : 
+      60             : We calculate histograms within PLUMED using a method known as kernel density estimation, which you can read more about here:
+      61             : 
+      62             : https://en.wikipedia.org/wiki/Kernel_density_estimation
+      63             : 
+      64             : In PLUMED the value of \f$\zeta\f$ at each discrete instant in time in the trajectory is accumulated.  A kernel, \f$K(\zeta-\zeta(t'),\sigma)\f$,
+      65             : centered at the current value, \f$\zeta(t)\f$, of this quantity is generated with a bandwidth \f$\sigma\f$, which
+      66             : is set by the user.  These kernels are then used to accumulate the ensemble average for the probability density:
+      67             : 
+      68             : \f[
+      69             : \langle P(\zeta) \rangle = \frac{ \sum_{t'=0}^t w(t') K(\zeta-\zeta(t'),\sigma) }{ \sum_{t'=0}^t w(t') }
+      70             : \f]
+      71             : 
+      72             : Here the sums run over a portion of the trajectory specified by the user.  The final quantity evaluated is a weighted
+      73             : average as the weights, \f$w(t')\f$, allow us to negate the effect any bias might have on the region of phase space
+      74             : sampled by the system.  This is discussed in the section of the manual on \ref Analysis.
+      75             : 
+      76             : A discrete analogue of kernel density estimation can also be used.  In this analogue the kernels in the above formula
+      77             : are replaced by Dirac delta functions.   When this method is used the final function calculated is no longer a probability
+      78             : density - it is instead a probability mass function as each element of the function tells you the value of an integral
+      79             : between two points on your grid rather than the value of a (continuous) function on a grid.
+      80             : 
+      81             : Additional material and examples can be also found in the tutorials \ref lugano-1.
+      82             : 
+      83             : \par A note on block averaging and errors
+      84             : 
+      85             : Some particularly important
+      86             : issues related to the convergence of histograms and the estimation of error bars around the ensemble averages you calculate are covered in \ref trieste-2.
+      87             : The technique for estimating error bars that is known as block averaging is introduced in this tutorial.  The essence of this technique is that
+      88             : the trajectory is split into a set of blocks and separate ensemble averages are calculated from each separate block of data.  If \f$\{A_i\}\f$ is
+      89             : the set of \f$N\f$ block averages that are obtained from this technique then the final error bar is calculated as:
+      90             : 
+      91             : \f[
+      92             : \textrm{error} = \sqrt{ \frac{1}{N} \frac{1}{N-1} \sum_{i=1}^N (A_i^2 - \langle A \rangle )^2 } \qquad \textrm{where} \qquad \langle A \rangle = \frac{1}{N} \sum_{i=1}^N A_i
+      93             : \f]
+      94             : 
+      95             : If the simulation is biased and reweighting is performed then life is a little more complex as each of the block averages should be calculated as a
+      96             : weighted average.  Furthermore, the weights should be taken into account when the final ensemble and error bars are calculated.  As such the error should be:
+      97             : 
+      98             : \f[
+      99             : \textrm{error} = \sqrt{ \frac{1}{N} \frac{\sum_{i=1}^N W_i }{\sum_{i=1}^N W_i - \sum_{i=1}^N W_i^2 / \sum_{i=1}^N W_i} \sum_{i=1}^N W_i (A_i^2 - \langle A \rangle )^2 }
+     100             : \f]
+     101             : 
+     102             : where \f$W_i\f$ is the sum of all the weights for the \f$i\f$th block of data.
+     103             : 
+     104             : If we wish to calculate a normalized histogram we must calculate ensemble averages from our biased simulation using:
+     105             : \f[
+     106             :  \langle H(x) \rangle = \frac{\sum_{t=1}^M w_t K( x - x_t,\sigma) }{\sum_{t=1}^M w_t}
+     107             : \f]
+     108             : where the sums runs over the trajectory, \f$w_t\f$ is the weight of the \f$t\f$th trajectory frame, \f$x_t\f$ is the value of the CV for the \f$t\f$th
+     109             : trajectory frame and \f$K\f$ is a kernel function centered on \f$x_t\f$ with bandwidth \f$\sigma\f$.  The quantity that is evaluated is the value of the
+     110             : normalized histogram at point \f$x\f$.  The following ensemble average will be calculated if you use the NORMALIZATION=true option in HISTOGRAM.
+     111             : If the ensemble average is calculated in this way we must calculate the associated error bars from our block averages using the second of the expressions
+     112             : above.
+     113             : 
+     114             : A number of works have shown that when biased simulations are performed it is often better to calculate an estimate of the histogram that is not normalized using:
+     115             : \f[
+     116             : \langle H(x) \rangle = \frac{1}{M} \sum_{t=1}^M w_t K( x - x_t,\sigma)
+     117             : \f]
+     118             : instead of the expression above.  As such this is what is done by default in HISTOGRAM or if the NORMALIZATION=ndata option is used.
+     119             : When the histogram is calculated in this second way the first of the two formula above can be used when calculating error bars from
+     120             : block averages.
+     121             : 
+     122             : \par Examples
+     123             : 
+     124             : The following input monitors two torsional angles during a simulation
+     125             : and outputs a continuous histogram as a function of them at the end of the simulation.
+     126             : \plumedfile
+     127             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     128             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     129             : HISTOGRAM ...
+     130             :   ARG=r1,r2
+     131             :   GRID_MIN=-3.14,-3.14
+     132             :   GRID_MAX=3.14,3.14
+     133             :   GRID_BIN=200,200
+     134             :   BANDWIDTH=0.05,0.05
+     135             :   LABEL=hh
+     136             : ... HISTOGRAM
+     137             : 
+     138             : DUMPGRID GRID=hh FILE=histo
+     139             : \endplumedfile
+     140             : 
+     141             : The following input monitors two torsional angles during a simulation
+     142             : and outputs a discrete histogram as a function of them at the end of the simulation.
+     143             : \plumedfile
+     144             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     145             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     146             : HISTOGRAM ...
+     147             :   ARG=r1,r2
+     148             :   KERNEL=DISCRETE
+     149             :   GRID_MIN=-3.14,-3.14
+     150             :   GRID_MAX=3.14,3.14
+     151             :   GRID_BIN=200,200
+     152             :   LABEL=hh
+     153             : ... HISTOGRAM
+     154             : 
+     155             : DUMPGRID GRID=hh FILE=histo
+     156             : \endplumedfile
+     157             : 
+     158             : The following input monitors two torsional angles during a simulation
+     159             : and outputs the histogram accumulated thus far every 100000 steps.
+     160             : \plumedfile
+     161             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     162             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     163             : HISTOGRAM ...
+     164             :   ARG=r1,r2
+     165             :   GRID_MIN=-3.14,-3.14
+     166             :   GRID_MAX=3.14,3.14
+     167             :   GRID_BIN=200,200
+     168             :   BANDWIDTH=0.05,0.05
+     169             :   LABEL=hh
+     170             : ... HISTOGRAM
+     171             : 
+     172             : DUMPGRID GRID=hh FILE=histo STRIDE=100000
+     173             : \endplumedfile
+     174             : 
+     175             : The following input monitors two torsional angles during a simulation
+     176             : and outputs a separate histogram for each 100000 steps worth of trajectory.
+     177             : Notice how the CLEAR keyword is used here and how it is not used in the
+     178             : previous example.
+     179             : 
+     180             : \plumedfile
+     181             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     182             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     183             : HISTOGRAM ...
+     184             :   ARG=r1,r2 CLEAR=100000
+     185             :   GRID_MIN=-3.14,-3.14
+     186             :   GRID_MAX=3.14,3.14
+     187             :   GRID_BIN=200,200
+     188             :   BANDWIDTH=0.05,0.05
+     189             :   LABEL=hh
+     190             : ... HISTOGRAM
+     191             : 
+     192             : DUMPGRID GRID=hh FILE=histo STRIDE=100000
+     193             : \endplumedfile
+     194             : 
+     195             : */
+     196             : //+ENDPLUMEDOC
+     197             : 
+     198             : class Histogram : public gridtools::ActionWithGrid {
+     199             : private:
+     200             :   double ww;
+     201             :   bool in_apply, mvectors;
+     202             :   std::unique_ptr<KernelFunctions> kernel;
+     203             :   std::vector<double> forcesToApply, finalForces;
+     204             :   std::vector<vesselbase::ActionWithVessel*> myvessels;
+     205             :   std::vector<vesselbase::StoreDataVessel*> stashes;
+     206             : // this is a plain pointer since this object is now owned
+     207             :   gridtools::HistogramOnGrid* myhist;
+     208             : public:
+     209             :   static void registerKeywords( Keywords& keys );
+     210             :   explicit Histogram(const ActionOptions&ao);
+     211             :   unsigned getNumberOfQuantities() const override;
+     212             :   void prepareForAveraging() override;
+     213             :   void performOperations( const bool& from_update ) override;
+     214             :   void finishAveraging() override;
+     215         121 :   bool threadSafe() const override { return !in_apply; }
+     216           0 :   bool isPeriodic() override { return false; }
+     217             :   unsigned getNumberOfDerivatives() override;
+     218             :   void turnOnDerivatives() override;
+     219             :   void compute( const unsigned&, MultiValue& ) const override;
+     220             :   void apply() override;
+     221             : };
+     222             : 
+     223             : PLUMED_REGISTER_ACTION(Histogram,"HISTOGRAM")
+     224             : 
+     225          36 : void Histogram::registerKeywords( Keywords& keys ) {
+     226          72 :   gridtools::ActionWithGrid::registerKeywords( keys ); keys.use("ARG"); keys.remove("NORMALIZATION");
+     227          72 :   keys.add("compulsory","NORMALIZATION","ndata","This controls how the data is normalized it can be set equal to true, false or ndata.  See above for an explanation");
+     228          72 :   keys.add("optional","DATA","input data from action with vessel and compute histogram");
+     229          72 :   keys.add("optional","VECTORS","input three dimensional vectors for computing histogram");
+     230          72 :   keys.add("compulsory","GRID_MIN","the lower bounds for the grid");
+     231          72 :   keys.add("compulsory","GRID_MAX","the upper bounds for the grid");
+     232          72 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     233          72 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     234          72 :   keys.use("UPDATE_FROM"); keys.use("UPDATE_UNTIL");
+     235          36 : }
+     236             : 
+     237          34 : Histogram::Histogram(const ActionOptions&ao):
+     238             :   Action(ao),
+     239             :   ActionWithGrid(ao),
+     240          34 :   ww(0.0),
+     241          34 :   in_apply(false),
+     242          34 :   mvectors(false)
+     243             : {
+     244             :   // Read in arguments
+     245          34 :   if( getNumberOfArguments()==0 ) {
+     246          16 :     std::string vlab; parse("VECTORS",vlab);
+     247           8 :     if( vlab.length()>0 ) {
+     248           2 :       ActionWithVessel* myv = plumed.getActionSet().selectWithLabel<ActionWithVessel*>( vlab );
+     249           2 :       if( !myv ) error("action labelled " + vlab + " does not exist or is not an ActionWithVessel");
+     250           2 :       myvessels.push_back( myv ); stashes.push_back( myv->buildDataStashes( NULL ) );
+     251           2 :       addDependency( myv ); mvectors=true;
+     252           2 :       if( myv->getNumberOfQuantities()!=5 ) error("can only compute histograms for three dimensional vectors");
+     253           2 :       log.printf("  for vector quantities calculated by %s \n", vlab.c_str() );
+     254             :     } else {
+     255          12 :       std::vector<std::string> mlab; parseVector("DATA",mlab);
+     256           6 :       if( mlab.size()>0 ) {
+     257          16 :         for(unsigned i=0; i<mlab.size(); ++i) {
+     258          10 :           ActionWithVessel* myv = plumed.getActionSet().selectWithLabel<ActionWithVessel*>( mlab[i] );
+     259          10 :           if( !myv ) error("action labelled " + mlab[i] + " does not exist or is not an ActionWithVessel");
+     260          10 :           myvessels.push_back( myv ); stashes.push_back( myv->buildDataStashes( NULL ) );
+     261             :           // log.printf("  for all base quantities calculated by %s \n",myvessel->getLabel().c_str() );
+     262             :           // Add the dependency
+     263          10 :           addDependency( myv );
+     264             :         }
+     265           6 :         unsigned nvals = myvessels[0]->getFullNumberOfTasks();
+     266          10 :         for(unsigned i=1; i<mlab.size(); ++i) {
+     267           4 :           if( nvals!=myvessels[i]->getFullNumberOfTasks() ) error("mismatched number of quantities calculated by actions input to histogram");
+     268             :         }
+     269           6 :         log.printf("  for all base quantities calculated by %s ", myvessels[0]->getLabel().c_str() );
+     270          10 :         for(unsigned i=1; i<mlab.size(); ++i) log.printf(", %s \n", myvessels[i]->getLabel().c_str() );
+     271           6 :         log.printf("\n");
+     272             :       } else {
+     273           0 :         error("input data is missing use ARG/VECTORS/DATA");
+     274             :       }
+     275           6 :     }
+     276             :   }
+     277             : 
+     278             :   // Read stuff for grid
+     279             :   unsigned narg = getNumberOfArguments();
+     280          34 :   if( myvessels.size()>0 ) narg=myvessels.size();
+     281             :   // Input of name and labels
+     282          34 :   std::string vstring="COMPONENTS=" + getLabel();
+     283          34 :   if( mvectors ) {
+     284             :     vstring += " COORDINATES=x,y,z PBC=F,F,F";
+     285          32 :   } else if( myvessels.size()>0 ) {
+     286           6 :     vstring += " COORDINATES=" + myvessels[0]->getLabel();
+     287          10 :     for(unsigned i=1; i<myvessels.size(); ++i) vstring +="," + myvessels[i]->getLabel();
+     288             :     // Input for PBC
+     289           6 :     if( myvessels[0]->isPeriodic() ) vstring+=" PBC=T";
+     290             :     else vstring+=" PBC=F";
+     291          10 :     for(unsigned i=1; i<myvessels.size(); ++i) {
+     292           4 :       if( myvessels[i]->isPeriodic() ) vstring+=",T";
+     293             :       else vstring+=",F";
+     294             :     }
+     295             :   } else {
+     296          26 :     vstring += " COORDINATES=" + getPntrToArgument(0)->getName();
+     297          35 :     for(unsigned i=1; i<getNumberOfArguments(); ++i) vstring += "," + getPntrToArgument(i)->getName();
+     298             :     // Input for PBC
+     299          26 :     if( getPntrToArgument(0)->isPeriodic() ) vstring+=" PBC=T";
+     300             :     else vstring+=" PBC=F";
+     301          35 :     for(unsigned i=1; i<getNumberOfArguments(); ++i) {
+     302           9 :       if( getPntrToArgument(i)->isPeriodic() ) vstring+=",T";
+     303             :       else vstring+=",F";
+     304             :     }
+     305             :   }
+     306             :   // And create the grid
+     307          34 :   auto grid=createGrid( "histogram", vstring );
+     308             :   // notice that createGrid also sets mygrid=grid.get()
+     309          68 :   if( mygrid->getType()=="flat" ) {
+     310          32 :     if( mvectors ) error("computing histogram for three dimensional vectors but grid is not of fibonacci type - use CONCENTRATION");
+     311          32 :     std::vector<std::string> gmin( narg ), gmax( narg );
+     312          96 :     parseVector("GRID_MIN",gmin); parseVector("GRID_MAX",gmax);
+     313          64 :     std::vector<unsigned> nbin; parseVector("GRID_BIN",nbin);
+     314          64 :     std::vector<double> gspacing; parseVector("GRID_SPACING",gspacing);
+     315          32 :     if( nbin.size()!=narg && gspacing.size()!=narg ) {
+     316           0 :       error("GRID_BIN or GRID_SPACING must be set");
+     317             :     }
+     318          32 :     mygrid->setBounds( gmin, gmax, nbin, gspacing );
+     319          32 :   } else {
+     320           4 :     std::vector<unsigned> nbin; parseVector("GRID_BIN",nbin);
+     321           2 :     if( nbin.size()!=1 ) error("should only be one index for number of bins with spherical grid");
+     322           4 :     if( mygrid->getType()=="fibonacci" ) mygrid->setupFibonacciGrid( nbin[0] );
+     323             :   }
+     324          34 :   myhist = dynamic_cast<gridtools::HistogramOnGrid*>( mygrid );
+     325          34 :   plumed_assert( myhist );
+     326          34 :   if( myvessels.size()>0 ) {
+     327             :     // Create a task list
+     328          72 :     for(unsigned i=0; i<myvessels[0]->getFullNumberOfTasks(); ++i) addTaskToList(i);
+     329           8 :     setAveragingAction( std::move(grid), true );
+     330             :   } else if( storeThenAverage() ) {
+     331           7 :     setAveragingAction( std::move(grid), true );
+     332             :   } else {
+     333             :     // Create a task list
+     334        9256 :     for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) addTaskToList(i);
+     335          19 :     myhist->addOneKernelEachTimeOnly();
+     336          19 :     setAveragingAction( std::move(grid), myhist->noDiscreteKernels() );
+     337             :   }
+     338          34 :   checkRead();
+     339          68 : }
+     340             : 
+     341           8 : void Histogram::turnOnDerivatives() {
+     342           8 :   ActionWithGrid::turnOnDerivatives();
+     343             :   std::vector<AtomNumber> all_atoms, tmp_atoms;
+     344          20 :   for(unsigned i=0; i<myvessels.size(); ++i) {
+     345          12 :     multicolvar::MultiColvarBase* mbase=dynamic_cast<multicolvar::MultiColvarBase*>( myvessels[i] );
+     346          12 :     if( !mbase ) error("do not know how to get histogram derivatives for actions of type " + myvessels[i]->getName() );
+     347             :     // cppcheck-suppress nullPointerRedundantCheck
+     348          12 :     tmp_atoms = mbase->getAbsoluteIndexes();
+     349         482 :     for(unsigned j=0; j<tmp_atoms.size(); ++j) all_atoms.push_back( tmp_atoms[j] );
+     350             :     // Make a tempory multi value so we can avoid vector resizing
+     351          12 :     stashes[i]->resizeTemporyMultiValues( 1 );
+     352             :   }
+     353           8 :   ActionAtomistic::requestAtoms( all_atoms );
+     354           8 :   finalForces.resize( 3*all_atoms.size() + 9 );
+     355           8 :   forcesToApply.resize( 3*all_atoms.size() + 9*myvessels.size() );
+     356             :   // And make sure we still have the dependencies which are cleared by requestAtoms
+     357          20 :   for(unsigned i=0; i<myvessels.size(); ++i) addDependency( myvessels[i] );
+     358             :   // And resize the histogram so that we have a place to store the forces
+     359           8 :   in_apply=true; mygrid->resize(); in_apply=false;
+     360           8 : }
+     361             : 
+     362         728 : unsigned Histogram::getNumberOfDerivatives() {
+     363         728 :   if( in_apply ) {
+     364             :     unsigned nder=0;
+     365         540 :     for(unsigned i=0; i<myvessels.size(); ++i) nder += myvessels[i]->getNumberOfDerivatives();
+     366             :     return nder;
+     367             :   }
+     368         506 :   return getNumberOfArguments();
+     369             : }
+     370             : 
+     371         462 : unsigned Histogram::getNumberOfQuantities() const {
+     372         462 :   if( mvectors ) return myvessels[0]->getNumberOfQuantities();
+     373         416 :   else if( myvessels.size()>0 ) return myvessels.size()+2;
+     374         294 :   return ActionWithAveraging::getNumberOfQuantities();
+     375             : }
+     376             : 
+     377         115 : void Histogram::prepareForAveraging() {
+     378         115 :   if( myvessels.size()>0 ) {
+     379          36 :     deactivateAllTasks(); double norm=0;
+     380         332 :     for(unsigned i=0; i<stashes[0]->getNumberOfStoredValues(); ++i) {
+     381         296 :       std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() );
+     382         296 :       stashes[0]->retrieveSequentialValue( i, false, cvals );
+     383         296 :       unsigned itask=myvessels[0]->getActiveTask(i); double tnorm = cvals[0];
+     384         444 :       for(unsigned j=1; j<myvessels.size(); ++j) {
+     385         148 :         if( myvessels[j]->getActiveTask(i)!=itask ) error("mismatched task identities in histogram suggests histogram is meaningless");
+     386         148 :         if( cvals.size()!=myvessels[j]->getNumberOfQuantities() ) cvals.resize( myvessels[j]->getNumberOfQuantities() );
+     387         148 :         stashes[j]->retrieveSequentialValue( i, false, cvals ); tnorm *= cvals[0];
+     388             :       }
+     389         296 :       norm += tnorm; taskFlags[i]=1;
+     390             :     }
+     391          36 :     lockContributors();
+     392             :     // Sort out normalization of histogram
+     393          36 :     if( !noNormalization() ) ww = cweight / norm;
+     394           5 :     else ww = cweight;
+     395             :   } else if( !storeThenAverage() ) {
+     396             :     // Now fetch the kernel and the active points
+     397          72 :     std::vector<double> point( getNumberOfArguments() );
+     398         180 :     for(unsigned i=0; i<point.size(); ++i) point[i]=getArgument(i);
+     399          72 :     unsigned num_neigh; std::vector<unsigned> neighbors(1);
+     400         144 :     kernel=myhist->getKernelAndNeighbors( point, num_neigh, neighbors );
+     401             : 
+     402          72 :     if( num_neigh>1 ) {
+     403             :       // Activate relevant tasks
+     404          67 :       deactivateAllTasks();
+     405       14975 :       for(unsigned i=0; i<num_neigh; ++i) taskFlags[neighbors[i]]=1;
+     406          67 :       lockContributors();
+     407             :     } else {
+     408             :       // This is used when we are not doing kernel density evaluation
+     409           5 :       mygrid->addToGridElement( neighbors[0], 0, cweight );
+     410             :     }
+     411             :   }
+     412         115 : }
+     413             : 
+     414           5 : void Histogram::performOperations( const bool& from_update ) { if( myvessels.size()==0 ) plumed_dbg_assert( !myhist->noDiscreteKernels() ); }
+     415             : 
+     416         135 : void Histogram::finishAveraging() {
+     417         135 :   if( myvessels.size()==0 ) kernel.reset();
+     418         135 : }
+     419             : 
+     420       15404 : void Histogram::compute( const unsigned& current, MultiValue& myvals ) const {
+     421       15404 :   if( mvectors ) {
+     422         140 :     std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() );
+     423         140 :     stashes[0]->retrieveSequentialValue( current, true, cvals );
+     424         560 :     for(unsigned i=2; i<myvessels[0]->getNumberOfQuantities(); ++i) myvals.setValue( i-1, cvals[i] );
+     425         140 :     myvals.setValue( 0, cvals[0] ); myvals.setValue( myvessels[0]->getNumberOfQuantities() - 1, ww );
+     426         140 :     if( in_apply ) {
+     427          50 :       MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
+     428          99 :       if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
+     429          49 :           tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
+     430           1 :         tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
+     431          50 :       stashes[0]->retrieveDerivatives( stashes[0]->getTrueIndex(current), true, tmpval );
+     432         350 :       for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
+     433         300 :         unsigned jder=tmpval.getActiveIndex(j); myvals.addDerivative( 0, jder, tmpval.getDerivative(0, jder) );
+     434        1200 :         for(unsigned i=2; i<myvessels[0]->getNumberOfQuantities(); ++i) myvals.addDerivative( i-1, jder, tmpval.getDerivative(i, jder) );
+     435             :       }
+     436             :       myvals.updateDynamicList();
+     437             :     }
+     438       15264 :   } else if( myvessels.size()>0 ) {
+     439         356 :     std::vector<double> cvals( myvessels[0]->getNumberOfQuantities() );
+     440         356 :     stashes[0]->retrieveSequentialValue( current, false, cvals );
+     441         356 :     unsigned derbase=0; double totweight=cvals[0], tnorm = cvals[0]; myvals.setValue( 1, cvals[1] );
+     442             :     // Get the derivatives as well if we are in apply
+     443         356 :     if( in_apply ) {
+     444             :       // This bit gets the total weight
+     445         150 :       double weight0 = cvals[0];  // Store the current weight
+     446         250 :       for(unsigned j=1; j<myvessels.size(); ++j) {
+     447         100 :         stashes[j]->retrieveSequentialValue( current, false, cvals ); totweight *= cvals[0];
+     448             :       }
+     449             :       // And this bit the derivatives
+     450         150 :       MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
+     451         297 :       if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
+     452         147 :           tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
+     453           3 :         tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
+     454         150 :       stashes[0]->retrieveDerivatives( stashes[0]->getTrueIndex(current), false, tmpval );
+     455       31590 :       for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
+     456       31440 :         unsigned jder=tmpval.getActiveIndex(j);
+     457       31440 :         myvals.addDerivative( 1, jder, tmpval.getDerivative(1,jder) );
+     458       31440 :         myvals.addDerivative( 0, jder, (totweight/weight0)*tmpval.getDerivative(0,jder) );
+     459             :       }
+     460         150 :       derbase = myvessels[0]->getNumberOfDerivatives();
+     461             :     }
+     462         604 :     for(unsigned i=1; i<myvessels.size(); ++i) {
+     463         248 :       if( cvals.size()!=myvessels[i]->getNumberOfQuantities() ) cvals.resize( myvessels[i]->getNumberOfQuantities() );
+     464         248 :       stashes[i]->retrieveSequentialValue( current, false, cvals );
+     465         248 :       tnorm *= cvals[0]; myvals.setValue( 1+i, cvals[1] );
+     466             :       // Get the derivatives as well if we are in apply
+     467         248 :       if( in_apply ) {
+     468         100 :         MultiValue& tmpval = stashes[0]->getTemporyMultiValue(0);
+     469         200 :         if( tmpval.getNumberOfValues()!=myvessels[0]->getNumberOfQuantities() ||
+     470         100 :             tmpval.getNumberOfDerivatives()!=myvessels[0]->getNumberOfDerivatives() )
+     471           0 :           tmpval.resize( myvessels[0]->getNumberOfQuantities(), myvessels[0]->getNumberOfDerivatives() );
+     472         100 :         stashes[i]->retrieveDerivatives( stashes[i]->getTrueIndex(current), false, tmpval );
+     473        1090 :         for(unsigned j=0; j<tmpval.getNumberActive(); ++j) {
+     474             :           unsigned jder=tmpval.getActiveIndex(j);
+     475         990 :           myvals.addDerivative( 1+i, derbase+jder, tmpval.getDerivative(1,jder) );
+     476         990 :           myvals.addDerivative( 0, derbase+jder, (totweight/cvals[0])*tmpval.getDerivative(0,jder) );
+     477             :         }
+     478         100 :         derbase += myvessels[i]->getNumberOfDerivatives();
+     479             :       }
+     480             :     }
+     481         356 :     myvals.setValue( 0, tnorm ); myvals.setValue( 1+myvessels.size(), ww );
+     482         356 :     if( in_apply ) myvals.updateDynamicList();
+     483             :   } else {
+     484       14908 :     plumed_assert( !in_apply );
+     485       14908 :     std::vector<std::unique_ptr<Value>> vv( myhist->getVectorOfValues() );
+     486       14908 :     std::vector<double> val( getNumberOfArguments() ), der( getNumberOfArguments() );
+     487             :     // Retrieve the location of the grid point at which we are evaluating the kernel
+     488       14908 :     mygrid->getGridPointCoordinates( current, val );
+     489       14908 :     if( kernel ) {
+     490       54492 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) vv[i]->set( val[i] );
+     491             :       // Evaluate the histogram at the relevant grid point and set the values
+     492       29816 :       double vvh = kernel->evaluate( Tools::unique2raw(vv), der,true); myvals.setValue( 1, vvh );
+     493             :     } else {
+     494           0 :       plumed_merror("normalisation of vectors does not work with arguments and spherical grids");
+     495             :       // Evalulate dot product
+     496             :       double dot=0; for(unsigned j=0; j<getNumberOfArguments(); ++j) { dot+=val[j]*getArgument(j); der[j]=val[j]; }
+     497             :       // Von misses distribution for concentration parameter
+     498             :       double newval = (myhist->von_misses_norm)*std::exp( (myhist->von_misses_concentration)*dot ); myvals.setValue( 1, newval );
+     499             :       // And final derivatives
+     500             :       for(unsigned j=0; j<getNumberOfArguments(); ++j) der[j] *= (myhist->von_misses_concentration)*newval;
+     501             :     }
+     502             :     // Set the derivatives and delete the vector of values
+     503       54492 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) { myvals.setDerivative( 1, i, der[i] ); }
+     504       14908 :   }
+     505       15404 : }
+     506             : 
+     507         133 : void Histogram::apply() {
+     508         133 :   if( !myhist->wasForced() ) return ;
+     509          20 :   in_apply=true;
+     510             :   // Run the loop to calculate the forces
+     511          20 :   runAllTasks(); finishAveraging();
+     512             :   // We now need to retrieve the buffer and set the forces on the atoms
+     513          20 :   myhist->applyForce( forcesToApply );
+     514             :   // Now make the forces make sense for the virial
+     515          20 :   unsigned fbase=0, tbase=0, vbase = getNumberOfDerivatives() - myvessels.size()*9;
+     516         200 :   for(unsigned i=vbase; i<vbase+9; ++i) finalForces[i]=0.0;
+     517          50 :   for(unsigned i=0; i<myvessels.size(); ++i) {
+     518        3555 :     for(unsigned j=0; j<myvessels[i]->getNumberOfDerivatives()-9; ++j) {
+     519        3525 :       finalForces[fbase + j] = forcesToApply[tbase + j];
+     520             :     }
+     521             :     unsigned k=0;
+     522         300 :     for(unsigned j=myvessels[i]->getNumberOfDerivatives()-9; j<myvessels[i]->getNumberOfDerivatives(); ++j) {
+     523         270 :       finalForces[vbase + k] += forcesToApply[tbase + j]; k++;
+     524             :     }
+     525          30 :     fbase += myvessels[i]->getNumberOfDerivatives() - 9;
+     526          30 :     tbase += myvessels[i]->getNumberOfDerivatives();
+     527             :   }
+     528             :   // And set the final forces on the atoms
+     529          20 :   unsigned ind=0; setForcesOnAtoms( finalForces, ind );
+     530             :   // Reset everything for next regular loop
+     531          20 :   in_apply=false;
+     532             : }
+     533             : 
+     534             : }
+     535             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.cpp.func-sort-c.html b/coverage/analysis/LandmarkSelectionBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..aefeef78960c --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkSelectionBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkSelectionBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4141100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21LandmarkSelectionBaseC1ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis21LandmarkSelectionBase15voronoiAnalysisERKSt6vectorIjSaIjEERS2_IdSaIdEERS4_8
_ZN4PLMD8analysis21LandmarkSelectionBaseC2ERKNS_13ActionOptionsE10
_ZN4PLMD8analysis21LandmarkSelectionBase15performAnalysisEv12
_ZN4PLMD8analysis21LandmarkSelectionBase16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD8analysis21LandmarkSelectionBase11selectFrameERKj291
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.cpp.func.html b/coverage/analysis/LandmarkSelectionBase.cpp.func.html new file mode 100644 index 000000000000..228c3f27beb4 --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkSelectionBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkSelectionBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4141100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21LandmarkSelectionBase11selectFrameERKj291
_ZN4PLMD8analysis21LandmarkSelectionBase15performAnalysisEv12
_ZN4PLMD8analysis21LandmarkSelectionBase16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD8analysis21LandmarkSelectionBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis21LandmarkSelectionBaseC2ERKNS_13ActionOptionsE10
_ZNK4PLMD8analysis21LandmarkSelectionBase15voronoiAnalysisERKSt6vectorIjSaIjEERS2_IdSaIdEERS4_8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.cpp.gcov.html b/coverage/analysis/LandmarkSelectionBase.cpp.gcov.html new file mode 100644 index 000000000000..a4859d0446bd --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.cpp.gcov.html @@ -0,0 +1,163 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkSelectionBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkSelectionBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4141100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "LandmarkSelectionBase.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace analysis {
+      26             : 
+      27          20 : void LandmarkSelectionBase::registerKeywords( Keywords& keys ) {
+      28          20 :   AnalysisBase::registerKeywords( keys );
+      29          40 :   keys.add("compulsory","NLANDMARKS","the number of landmarks that you would like to select");
+      30          40 :   keys.addFlag("NOVORONOI",false,"do not do a Voronoi analysis of the data to determine weights of final points");
+      31          40 :   keys.addFlag("IGNORE_WEIGHTS",false,"ignore the weights in the underlying analysis object");
+      32          20 : }
+      33             : 
+      34          10 : LandmarkSelectionBase::LandmarkSelectionBase( const ActionOptions& ao ):
+      35             :   Action(ao),
+      36             :   AnalysisBase(ao),
+      37          10 :   nlandmarks(0)
+      38             : {
+      39          29 :   if( keywords.exists("NLANDMARKS") ) parse("NLANDMARKS",nlandmarks);
+      40          10 :   log.printf("  selecting %u landmark points \n",nlandmarks);
+      41          10 :   lweights.resize( nlandmarks );
+      42             : 
+      43          10 :   parseFlag("NOVORONOI",novoronoi);
+      44          18 :   if( !novoronoi && !dissimilaritiesWereSet() ) error("cannot calculate voronoi weights without dissimilarity mesaure");
+      45             : 
+      46          10 :   if( !novoronoi ) log.printf("  ascribing weights to landmarks using voronoi analysis\n");
+      47           2 :   else log.printf("  ascribing weights of original points to landmark\n");
+      48          10 : }
+      49             : 
+      50         291 : void LandmarkSelectionBase::selectFrame( const unsigned& iframe ) {
+      51         291 :   landmark_indices.push_back( iframe );
+      52         291 : }
+      53             : 
+      54          12 : void LandmarkSelectionBase::performAnalysis() {
+      55          12 :   landmark_indices.resize(0); selectLandmarks();
+      56             :   plumed_dbg_assert( nlandmarks==getNumberOfDataPoints() );
+      57          12 :   if( lweights.size()!=nlandmarks ) lweights.resize( nlandmarks );
+      58             : 
+      59          12 :   if( !novoronoi ) {
+      60           8 :     lweights.assign(lweights.size(),0.0);
+      61           8 :     std::vector<unsigned> tmpass( my_input_data->getNumberOfDataPoints() );
+      62           8 :     voronoiAnalysis( landmark_indices, lweights, tmpass );
+      63             :   } else {
+      64          18 :     for(unsigned i=0; i<nlandmarks; ++i) lweights[i]=my_input_data->getWeight( landmark_indices[i] );
+      65             :   }
+      66          12 : }
+      67             : 
+      68           8 : void LandmarkSelectionBase::voronoiAnalysis( const std::vector<unsigned>& myindices, std::vector<double>& lweights, std::vector<unsigned>& assignments ) const {
+      69             :   plumed_dbg_assert( myindices.size()==lweights.size() && assignments.size()==my_input_data->getNumberOfDataPoints() );
+      70           8 :   lweights.assign( lweights.size(), 0 );
+      71           8 :   unsigned rank=comm.Get_rank(), size=comm.Get_size();
+      72         567 :   for(unsigned i=rank; i<my_input_data->getNumberOfDataPoints(); i+=size) {
+      73         559 :     assignments[i]=0;
+      74         559 :     double mindist=my_input_data->getDissimilarity( i, myindices[0] );
+      75      125239 :     for(unsigned j=1; j<nlandmarks; ++j) {
+      76      124680 :       double dist=my_input_data->getDissimilarity( i, myindices[j] );
+      77      124680 :       if( dist<mindist ) { mindist=dist; assignments[i]=j; }
+      78             :     }
+      79         559 :     lweights[ assignments[i] ] += my_input_data->getWeight(i);
+      80             :   }
+      81           8 :   comm.Sum( &lweights[0], lweights.size() );
+      82           8 :   comm.Sum( &assignments[0], assignments.size() );
+      83           8 : }
+      84             : 
+      85             : }
+      86             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.h.func-sort-c.html b/coverage/analysis/LandmarkSelectionBase.h.func-sort-c.html new file mode 100644 index 000000000000..fc287227c085 --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkSelectionBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkSelectionBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101190.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD8analysis21LandmarkSelectionBase11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD8analysis21LandmarkSelectionBase13getStoredDataERKjRKb531
_ZN4PLMD8analysis21LandmarkSelectionBase16getDissimilarityERKjS3_62329
_ZNK4PLMD8analysis21LandmarkSelectionBase23getDataPointIndexInBaseERKj125002
_ZNK4PLMD8analysis21LandmarkSelectionBase21getNumberOfDataPointsEv126447
_ZN4PLMD8analysis21LandmarkSelectionBase9getWeightERKj8361301
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.h.func.html b/coverage/analysis/LandmarkSelectionBase.h.func.html new file mode 100644 index 000000000000..23e0ac707222 --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkSelectionBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkSelectionBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101190.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis21LandmarkSelectionBase13getStoredDataERKjRKb531
_ZN4PLMD8analysis21LandmarkSelectionBase16getDissimilarityERKjS3_62329
_ZN4PLMD8analysis21LandmarkSelectionBase9getWeightERKj8361301
_ZNK4PLMD8analysis21LandmarkSelectionBase11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis21LandmarkSelectionBase21getNumberOfDataPointsEv126447
_ZNK4PLMD8analysis21LandmarkSelectionBase23getDataPointIndexInBaseERKj125002
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkSelectionBase.h.gcov.html b/coverage/analysis/LandmarkSelectionBase.h.gcov.html new file mode 100644 index 000000000000..615a45678cf2 --- /dev/null +++ b/coverage/analysis/LandmarkSelectionBase.h.gcov.html @@ -0,0 +1,170 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkSelectionBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkSelectionBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101190.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_analysis_LandmarkSelectionBase_h
+      23             : #define __PLUMED_analysis_LandmarkSelectionBase_h
+      24             : 
+      25             : #include "AnalysisBase.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace analysis {
+      29             : 
+      30             : class LandmarkSelectionBase : public AnalysisBase {
+      31             :   friend class ReselectLandmarks;
+      32             : private:
+      33             : /// The number of landmarks we are selecting
+      34             :   unsigned nlandmarks;
+      35             : /// The weights of the landmark points
+      36             :   std::vector<double> lweights;
+      37             : /// The indices of the landmarks in the original data set
+      38             :   std::vector<unsigned> landmark_indices;
+      39             : /// How do we treat weights
+      40             :   bool novoronoi, noweights;
+      41             : protected:
+      42             : /// Transfer frame i in the underlying action to the object we are going to analyze
+      43             :   void selectFrame( const unsigned& );
+      44             : /// Do a voronoi analysis
+      45             :   void voronoiAnalysis( const std::vector<unsigned>& myindices, std::vector<double>& lweights, std::vector<unsigned>& assignments ) const ;
+      46             : public:
+      47             :   static void registerKeywords( Keywords& keys );
+      48             :   explicit LandmarkSelectionBase( const ActionOptions& ao );
+      49             : /// Return the number of data points
+      50             :   unsigned getNumberOfDataPoints() const override;
+      51             : /// Return the index of the data point in the base class
+      52             :   unsigned getDataPointIndexInBase( const unsigned& idata ) const override;
+      53             : /// Get the weight
+      54             :   double getWeight( const unsigned& idata ) override;
+      55             : /// Get a reference configuration
+      56             :   DataCollectionObject& getStoredData( const unsigned& idat, const bool& calcdist ) override;
+      57             : /// Select landmark configurations
+      58             :   void performAnalysis() override;
+      59             :   virtual void selectLandmarks()=0;
+      60             : /// Get the squared dissimilarity between two reference configurations
+      61             :   double getDissimilarity( const unsigned& i, const unsigned& j ) override;
+      62             : /// This does nothing - it just ensures the final class is not abstract
+      63           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override { plumed_error(); }
+      64             : };
+      65             : 
+      66             : inline
+      67      126447 : unsigned LandmarkSelectionBase::getNumberOfDataPoints() const {
+      68      126447 :   return nlandmarks;
+      69             : }
+      70             : 
+      71             : inline
+      72      125002 : unsigned LandmarkSelectionBase::getDataPointIndexInBase( const unsigned& idata ) const {
+      73      125002 :   return AnalysisBase::getDataPointIndexInBase( landmark_indices[idata] );
+      74             : }
+      75             : 
+      76             : inline
+      77     8361301 : double LandmarkSelectionBase::getWeight( const unsigned& idata ) {
+      78     8361301 :   return lweights[idata];
+      79             : }
+      80             : 
+      81             : inline
+      82         531 : DataCollectionObject& LandmarkSelectionBase::getStoredData( const unsigned& idat, const bool& calcdist ) {
+      83         531 :   return AnalysisBase::getStoredData( landmark_indices[idat], calcdist );
+      84             : }
+      85             : 
+      86             : inline
+      87       62329 : double LandmarkSelectionBase::getDissimilarity( const unsigned& i, const unsigned& j ) {
+      88       62329 :   return AnalysisBase::getDissimilarity( landmark_indices[i], landmark_indices[j] );
+      89             : }
+      90             : 
+      91             : }
+      92             : }
+      93             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkStaged.cpp.func-sort-c.html b/coverage/analysis/LandmarkStaged.cpp.func-sort-c.html new file mode 100644 index 000000000000..71de42e2f978 --- /dev/null +++ b/coverage/analysis/LandmarkStaged.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkStaged.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkStaged.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:54610.9 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis14LandmarkStaged15selectLandmarksEv0
_ZN4PLMD8analysis14LandmarkStagedC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis14LandmarkStagedC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis14LandmarkStaged16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkStaged.cpp.func.html b/coverage/analysis/LandmarkStaged.cpp.func.html new file mode 100644 index 000000000000..23959ae65739 --- /dev/null +++ b/coverage/analysis/LandmarkStaged.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkStaged.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkStaged.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:54610.9 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis14LandmarkStaged15selectLandmarksEv0
_ZN4PLMD8analysis14LandmarkStaged16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8analysis14LandmarkStagedC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis14LandmarkStagedC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/LandmarkStaged.cpp.gcov.html b/coverage/analysis/LandmarkStaged.cpp.gcov.html new file mode 100644 index 000000000000..e52cfc274986 --- /dev/null +++ b/coverage/analysis/LandmarkStaged.cpp.gcov.html @@ -0,0 +1,212 @@ + + + + + + + + LCOV - plumed test coverage - analysis/LandmarkStaged.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - LandmarkStaged.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:54610.9 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "LandmarkSelectionBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Random.h"
+      25             : #include <iostream>
+      26             : 
+      27             : //+PLUMEDOC LANDMARKS LANDMARK_SELECT_STAGED
+      28             : /*
+      29             : Select a set of landmarks using the staged algorithm.
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace analysis {
+      39             : 
+      40             : class LandmarkStaged : public LandmarkSelectionBase {
+      41             : private:
+      42             :   unsigned seed;
+      43             :   double gamma;
+      44             : public:
+      45             :   static void registerKeywords( Keywords& keys );
+      46             :   explicit LandmarkStaged( const ActionOptions& ao );
+      47             :   void selectLandmarks() override;
+      48             : };
+      49             : 
+      50             : PLUMED_REGISTER_ACTION(LandmarkStaged,"LANDMARK_SELECT_STAGED")
+      51             : 
+      52           2 : void LandmarkStaged::registerKeywords( Keywords& keys ) {
+      53           2 :   LandmarkSelectionBase::registerKeywords(keys);
+      54           4 :   keys.add("compulsory","GAMMA","the gamma parameter to be used in weights");
+      55           4 :   keys.add("compulsory","SEED","1234","a random number seed");
+      56           2 : }
+      57             : 
+      58           0 : LandmarkStaged::LandmarkStaged( const ActionOptions& ao ):
+      59             :   Action(ao),
+      60           0 :   LandmarkSelectionBase(ao)
+      61             : {
+      62           0 :   parse("SEED",seed); parse("GAMMA",gamma);
+      63           0 :   log.printf("  probability of selecting voronoi polyhedra equal to exp(-weight/%f) \n", gamma );
+      64           0 : }
+      65             : 
+      66           0 : void LandmarkStaged::selectLandmarks() {
+      67           0 :   unsigned int n = getNumberOfDataPoints(); // The number of landmarks to pick
+      68           0 :   unsigned int N = my_input_data->getNumberOfDataPoints();  // The total number of frames we can choose from
+      69           0 :   unsigned int m = static_cast<int>( std::sqrt(n*N) );
+      70           0 :   std::vector<unsigned> fpslandmarks(m);
+      71             :   // Select first point at random
+      72           0 :   Random random; random.setSeed(-seed); double rand=random.RandU01();
+      73           0 :   fpslandmarks[0] = std::floor( N*rand );
+      74             : 
+      75             :   // using FPS we want to find m landmarks where m = sqrt(nN)
+      76             :   // Now find distance to all other points
+      77             :   Matrix<double> distances( m, N );
+      78           0 :   for(unsigned int i=0; i<N; ++i) {
+      79           0 :     distances(0,i) = my_input_data->getDissimilarity( fpslandmarks[0], i );
+      80             :   }
+      81             : 
+      82             :   // Now find all other landmarks
+      83           0 :   for(unsigned i=1; i<m; ++i) {
+      84             :     // Find point that has the largest minimum distance from the landmarks selected thus far
+      85             :     double maxd=0;
+      86           0 :     for(unsigned j=0; j<N; ++j) {
+      87           0 :       double mind=distances(0,j);
+      88           0 :       for(unsigned k=1; k<i; ++k) {
+      89           0 :         if( distances(k,j)<mind ) { mind=distances(k,j); }
+      90             :       }
+      91           0 :       if( mind>maxd ) { maxd=mind; fpslandmarks[i]=j; }
+      92             :     }
+      93           0 :     for(unsigned k=0; k<N; ++k) distances(i,k) = my_input_data->getDissimilarity( fpslandmarks[i], k );
+      94             :   }
+      95             : 
+      96             :   // Initial FPS selection of m landmarks completed
+      97             :   // Now find voronoi weights of these m points
+      98           0 :   std::vector<unsigned> poly_assign( N );
+      99           0 :   std::vector<double> weights( m, 0 );
+     100           0 :   voronoiAnalysis( fpslandmarks, weights, poly_assign );
+     101             : 
+     102             :   //Calculate total weight of voronoi polyhedras
+     103           0 :   double vweight=0; for(unsigned i=0; i<m; i++) vweight += std::exp( -weights[i] / gamma );
+     104             : 
+     105           0 :   std::vector<bool> selected(N, false); unsigned ncount=0;
+     106           0 :   while ( ncount<n) {
+     107             : //  generate random number and check which point it belongs to. select only it was not selected before
+     108           0 :     double rand = vweight*random.RandU01();
+     109             :     double running_vweight=0;
+     110           0 :     for(unsigned jpoly=0; jpoly<m; ++jpoly) {
+     111           0 :       running_vweight+=std::exp( -weights[jpoly] / gamma );
+     112           0 :       if( running_vweight>=rand ) {
+     113             :         double tweight=0;
+     114           0 :         for(unsigned i=0; i<poly_assign.size(); ++i) {
+     115           0 :           if( poly_assign[i]==jpoly ) tweight += getWeight( i );
+     116             :         }
+     117           0 :         double rand_poly = tweight*random.RandU01();
+     118             :         double running_tweight=0;
+     119           0 :         for(unsigned i=0; i<N; ++i) {
+     120           0 :           if( poly_assign[i]==jpoly ) {
+     121           0 :             running_tweight += getWeight( i );
+     122           0 :             if( running_tweight>=rand_poly && !selected[i] ) {
+     123           0 :               selectFrame(i); selected[i]=true; ncount++; break;
+     124           0 :             } else if( running_tweight>=rand_poly ) {
+     125             :               break;
+     126             :             }
+     127             :           }
+     128             :         }
+     129             :       }
+     130             :     }
+     131             :   }
+     132           0 : }
+     133             : 
+     134             : }
+     135             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputColvarFile.cpp.func-sort-c.html b/coverage/analysis/OutputColvarFile.cpp.func-sort-c.html new file mode 100644 index 000000000000..9add26a717e8 --- /dev/null +++ b/coverage/analysis/OutputColvarFile.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - analysis/OutputColvarFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - OutputColvarFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:464797.9 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis16OutputColvarFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis16OutputColvarFile11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD8analysis16OutputColvarFileC1ERKNS_13ActionOptionsE20
_ZN4PLMD8analysis16OutputColvarFile16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD8analysis16OutputColvarFile15performAnalysisEv24
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputColvarFile.cpp.func.html b/coverage/analysis/OutputColvarFile.cpp.func.html new file mode 100644 index 000000000000..883f510005aa --- /dev/null +++ b/coverage/analysis/OutputColvarFile.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - analysis/OutputColvarFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - OutputColvarFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:464797.9 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis16OutputColvarFile15performAnalysisEv24
_ZN4PLMD8analysis16OutputColvarFile16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD8analysis16OutputColvarFileC1ERKNS_13ActionOptionsE20
_ZN4PLMD8analysis16OutputColvarFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis16OutputColvarFile11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputColvarFile.cpp.gcov.html b/coverage/analysis/OutputColvarFile.cpp.gcov.html new file mode 100644 index 000000000000..75a49a3aa55f --- /dev/null +++ b/coverage/analysis/OutputColvarFile.cpp.gcov.html @@ -0,0 +1,203 @@ + + + + + + + + LCOV - plumed test coverage - analysis/OutputColvarFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - OutputColvarFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:464797.9 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AnalysisBase.h"
+      23             : #include "reference/ReferenceAtoms.h"
+      24             : #include "reference/ReferenceArguments.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace analysis {
+      30             : 
+      31             : //+PLUMEDOC ANALYSIS OUTPUT_ANALYSIS_DATA_TO_COLVAR
+      32             : /*
+      33             : This can be used to output the data that has been stored in an Analysis object.
+      34             : 
+      35             : The most useful application of this method is to output all projections of all the
+      36             : points that were stored in an analysis object that performs some form of dimensionality
+      37             : reduction.  If you use the USE_DIMRED_DATA_FROM option below projections of all the
+      38             : stored points will be output to a file.  The positions of these projections will be calculated
+      39             : using that dimensionality reduction algorithms out-of-sample extension algorithm.
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : */
+      44             : //+ENDPLUMEDOC
+      45             : 
+      46             : class OutputColvarFile : public AnalysisBase {
+      47             : private:
+      48             :   std::string fmt;
+      49             :   std::string filename;
+      50             :   bool output_for_all_replicas;
+      51             :   std::vector<unsigned> preps;
+      52             :   std::vector<std::string> req_vals;
+      53             : public:
+      54             :   static void registerKeywords( Keywords& keys );
+      55             :   explicit OutputColvarFile( const ActionOptions& );
+      56           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override { plumed_error(); }
+      57             :   void performAnalysis() override;
+      58             : };
+      59             : 
+      60             : PLUMED_REGISTER_ACTION(OutputColvarFile,"OUTPUT_ANALYSIS_DATA_TO_COLVAR")
+      61             : 
+      62          22 : void OutputColvarFile::registerKeywords( Keywords& keys ) {
+      63          22 :   AnalysisBase::registerKeywords( keys ); keys.use("ARG");
+      64          44 :   keys.add("compulsory","FILE","the name of the file to output to");
+      65          44 :   keys.add("compulsory","REPLICA","0","the replicas for which you would like to output this information");
+      66          44 :   keys.add("compulsory","STRIDE","0","the frequency with which to perform the required analysis and to output the data.  The default value of 0 tells plumed to use all the data");
+      67          44 :   keys.add("optional","FMT","the format to output the data using");
+      68          22 : }
+      69             : 
+      70          20 : OutputColvarFile::OutputColvarFile( const ActionOptions& ao ):
+      71             :   Action(ao),
+      72             :   AnalysisBase(ao),
+      73          40 :   fmt("%f"),
+      74          20 :   output_for_all_replicas(false)
+      75             : {
+      76          60 :   parse("FILE",filename); parse("FMT",fmt);
+      77          40 :   if( !getRestart() ) { OFile ofile; ofile.link(*this); ofile.setBackupString("analysis"); ofile.backupAllFiles(filename); }
+      78          20 :   log.printf("  printing data to file named %s \n",filename.c_str() );
+      79          20 :   if( getArguments().size()==0 ) {
+      80          12 :     std::vector<std::string> tmp_vals( my_input_data->getArgumentNames() );
+      81          30 :     req_vals.resize( tmp_vals.size() ); for(unsigned i=0; i<tmp_vals.size(); ++i) req_vals[i]=tmp_vals[i];
+      82          12 :   } else {
+      83          32 :     req_vals.resize( getArguments().size() ); for(unsigned i=0; i<req_vals.size(); ++i) req_vals[i]=getPntrToArgument(i)->getName();
+      84             :   }
+      85          20 :   if( req_vals.size()==0 ) {
+      86           6 :     log.printf("  outputting weights from input action \n");
+      87             :   } else {
+      88          14 :     log.printf("  outputting %s", req_vals[0].c_str() );
+      89          22 :     for(unsigned i=1; i<req_vals.size(); ++i) log.printf(",", req_vals[i].c_str() );
+      90          14 :     log.printf("\n");
+      91             :   }
+      92          40 :   std::string rep_data; parse("REPLICA",rep_data);
+      93          20 :   if( rep_data=="all" ) output_for_all_replicas=true;
+      94          20 :   else { preps.resize(1); Tools::convert( rep_data, preps[0] ); }
+      95          20 :   if( output_for_all_replicas ) log.printf("  outputting files for all replicas \n");
+      96             :   else {
+      97          20 :     log.printf("  outputting data for replicas ");
+      98          40 :     for(unsigned i=0; i<preps.size(); ++i) log.printf("%d ", preps[i] );
+      99             :   }
+     100          20 : }
+     101             : 
+     102          24 : void OutputColvarFile::performAnalysis() {
+     103          24 :   if( !output_for_all_replicas ) {
+     104          24 :     bool found=false; unsigned myrep=plumed.multi_sim_comm.Get_rank();
+     105          29 :     for(unsigned i=0; i<preps.size(); ++i) {
+     106          24 :       if( myrep==preps[i] ) { found=true; break; }
+     107             :     }
+     108          24 :     if( !found ) return;
+     109             :   }
+     110             :   // Output the embedding as long lists of data
+     111          19 :   OFile gfile; gfile.link(*this);
+     112          19 :   gfile.setBackupString("analysis");
+     113          19 :   gfile.fmtField(fmt+" ");
+     114          19 :   gfile.open( filename );
+     115             : 
+     116             :   // Print embedding coordinates
+     117        2599 :   for(unsigned i=0; i<getNumberOfDataPoints(); ++i) {
+     118        2580 :     const DataCollectionObject& mydata=getStoredData(i, false);
+     119        6989 :     for(unsigned j=0; j<req_vals.size(); ++j) gfile.printField( req_vals[j], mydata.getArgumentValue(req_vals[j]) );
+     120        5160 :     gfile.printField( "weight", getWeight(i) ); gfile.printField();
+     121             :   }
+     122          19 :   gfile.close();
+     123          19 : }
+     124             : 
+     125             : }
+     126             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputPDBFile.cpp.func-sort-c.html b/coverage/analysis/OutputPDBFile.cpp.func-sort-c.html new file mode 100644 index 000000000000..fe4e155d3d0b --- /dev/null +++ b/coverage/analysis/OutputPDBFile.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - analysis/OutputPDBFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - OutputPDBFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:282996.6 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13OutputPDBFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis13OutputPDBFile11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD8analysis13OutputPDBFileC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13OutputPDBFile15performAnalysisEv8
_ZN4PLMD8analysis13OutputPDBFile16registerKeywordsERNS_8KeywordsE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputPDBFile.cpp.func.html b/coverage/analysis/OutputPDBFile.cpp.func.html new file mode 100644 index 000000000000..5cb53ab506aa --- /dev/null +++ b/coverage/analysis/OutputPDBFile.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - analysis/OutputPDBFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - OutputPDBFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:282996.6 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13OutputPDBFile15performAnalysisEv8
_ZN4PLMD8analysis13OutputPDBFile16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8analysis13OutputPDBFileC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13OutputPDBFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis13OutputPDBFile11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/OutputPDBFile.cpp.gcov.html b/coverage/analysis/OutputPDBFile.cpp.gcov.html new file mode 100644 index 000000000000..3ad1fbc68284 --- /dev/null +++ b/coverage/analysis/OutputPDBFile.cpp.gcov.html @@ -0,0 +1,176 @@ + + + + + + + + LCOV - plumed test coverage - analysis/OutputPDBFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - OutputPDBFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:282996.6 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AnalysisBase.h"
+      23             : #include "reference/ReferenceAtoms.h"
+      24             : #include "reference/ReferenceArguments.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/GenericMolInfo.h"
+      29             : #include "tools/PDB.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace analysis {
+      33             : 
+      34             : //+PLUMEDOC ANALYSIS OUTPUT_ANALYSIS_DATA_TO_PDB
+      35             : /*
+      36             : This can be used to output the data that has been stored in an Analysis object.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : */
+      41             : //+ENDPLUMEDOC
+      42             : 
+      43             : class OutputPDBFile : public AnalysisBase {
+      44             : private:
+      45             :   PDB mypdb;
+      46             :   std::string fmt;
+      47             :   std::string filename;
+      48             : public:
+      49             :   static void registerKeywords( Keywords& keys );
+      50             :   explicit OutputPDBFile( const ActionOptions& );
+      51           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override { plumed_error(); }
+      52             :   void performAnalysis() override;
+      53             : };
+      54             : 
+      55             : PLUMED_REGISTER_ACTION(OutputPDBFile,"OUTPUT_ANALYSIS_DATA_TO_PDB")
+      56             : 
+      57           8 : void OutputPDBFile::registerKeywords( Keywords& keys ) {
+      58           8 :   AnalysisBase::registerKeywords( keys );
+      59          16 :   keys.add("compulsory","FILE","the name of the file to output to");
+      60          16 :   keys.add("optional","FMT","the format to use in the output file");
+      61          16 :   keys.add("compulsory","STRIDE","0","the frequency with which to perform the required analysis and to output the data.  The default value of 0 tells plumed to use all the data");
+      62           8 : }
+      63             : 
+      64           6 : OutputPDBFile::OutputPDBFile( const ActionOptions& ao ):
+      65             :   Action(ao),
+      66             :   AnalysisBase(ao),
+      67           6 :   fmt("%f")
+      68             : {
+      69             :   // Get setup the pdb
+      70           6 :   mypdb.setAtomNumbers( my_input_data->getAtomIndexes() );
+      71           6 :   mypdb.setArgumentNames( my_input_data->getArgumentNames() );
+      72             : 
+      73             :   // Find a moldata object
+      74           6 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      75          12 :   if( ! moldat ) warning("PDB output files do not have atom types unless you use MOLDATA");
+      76             : 
+      77          18 :   parse("FILE",filename); parse("FMT",fmt);
+      78          12 :   if( !getRestart() ) { OFile ofile; ofile.link(*this); ofile.setBackupString("analysis"); ofile.backupAllFiles(filename); }
+      79           6 :   log.printf("  printing data to file named %s \n",filename.c_str() );
+      80           6 : }
+      81             : 
+      82           8 : void OutputPDBFile::performAnalysis() {
+      83             :   // Find a moldata object
+      84           8 :   auto* mymoldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      85             :   // Output the embedding in plumed pdb format
+      86          16 :   OFile afile; afile.link(*this); afile.setBackupString("analysis"); std::size_t psign=fmt.find("%");
+      87          16 :   afile.open( filename ); std::string descr="REMARK WEIGHT=%-" + fmt.substr(psign+1) + "\n";
+      88         426 :   for(unsigned j=0; j<getNumberOfDataPoints(); ++j) {
+      89         418 :     afile.printf("DESCRIPTION: analysis data from calculation done by %s at time %f \n",getLabel().c_str(),getTime() );
+      90         836 :     if( dissimilaritiesWereSet() ) afile.printf("REMARK %s \n", getDissimilarityInstruction().c_str() );
+      91         418 :     afile.printf(descr.c_str(),getWeight(j) ); getStoredData(j,false).transferDataToPDB( mypdb );
+      92         418 :     if( usingNaturalUnits() ) mypdb.print( 1.0, mymoldat, afile, fmt );
+      93          18 :     else mypdb.print( getUnits().getLength()/0.1, mymoldat, afile, fmt );
+      94             :   }
+      95           8 :   afile.close();
+      96           8 : }
+      97             : 
+      98             : }
+      99             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/PrintDissimilarityMatrix.cpp.func-sort-c.html b/coverage/analysis/PrintDissimilarityMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..d16f0a31396f --- /dev/null +++ b/coverage/analysis/PrintDissimilarityMatrix.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - analysis/PrintDissimilarityMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - PrintDissimilarityMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis24PrintDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis24PrintDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD8analysis24PrintDissimilarityMatrixC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis24PrintDissimilarityMatrix15performAnalysisEv9
_ZN4PLMD8analysis24PrintDissimilarityMatrix16registerKeywordsERNS_8KeywordsE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/PrintDissimilarityMatrix.cpp.func.html b/coverage/analysis/PrintDissimilarityMatrix.cpp.func.html new file mode 100644 index 000000000000..ee1bb98fa86d --- /dev/null +++ b/coverage/analysis/PrintDissimilarityMatrix.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - analysis/PrintDissimilarityMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - PrintDissimilarityMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis24PrintDissimilarityMatrix15performAnalysisEv9
_ZN4PLMD8analysis24PrintDissimilarityMatrix16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD8analysis24PrintDissimilarityMatrixC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis24PrintDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis24PrintDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/PrintDissimilarityMatrix.cpp.gcov.html b/coverage/analysis/PrintDissimilarityMatrix.cpp.gcov.html new file mode 100644 index 000000000000..fe6047f45013 --- /dev/null +++ b/coverage/analysis/PrintDissimilarityMatrix.cpp.gcov.html @@ -0,0 +1,159 @@ + + + + + + + + LCOV - plumed test coverage - analysis/PrintDissimilarityMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - PrintDissimilarityMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "tools/OFile.h"
+      23             : #include "AnalysisBase.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : //+PLUMEDOC ANALYSIS PRINT_DISSIMILARITY_MATRIX
+      27             : /*
+      28             : Print the matrix of dissimilarities between a trajectory of atomic configurations.
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace analysis {
+      38             : 
+      39             : class PrintDissimilarityMatrix : public AnalysisBase {
+      40             : private:
+      41             :   std::string fmt;
+      42             :   std::string fname;
+      43             : public:
+      44             :   static void registerKeywords( Keywords& keys );
+      45             :   explicit PrintDissimilarityMatrix( const ActionOptions& ao );
+      46             :   void performAnalysis() override;
+      47           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override { plumed_error(); }
+      48             : };
+      49             : 
+      50             : PLUMED_REGISTER_ACTION(PrintDissimilarityMatrix,"PRINT_DISSIMILARITY_MATRIX")
+      51             : 
+      52          10 : void PrintDissimilarityMatrix::registerKeywords( Keywords& keys ) {
+      53          10 :   AnalysisBase::registerKeywords( keys );
+      54          20 :   keys.add("compulsory","FILE","name of file on which to output the data");
+      55          20 :   keys.add("optional","FMT","the format to use for the output of numbers");
+      56          20 :   keys.add("compulsory","STRIDE","0","the frequency with which to perform the required analysis and to output the data.  The default value of 0 tells plumed to use all the data");
+      57          10 : }
+      58             : 
+      59           8 : PrintDissimilarityMatrix::PrintDissimilarityMatrix( const ActionOptions& ao ):
+      60             :   Action(ao),
+      61             :   AnalysisBase(ao),
+      62           8 :   fmt("%f")
+      63             : {
+      64           8 :   if( !dissimilaritiesWereSet() ) error("dissimilarities have not been set in base classes");
+      65             : 
+      66          24 :   parse("FILE",fname); parse("FMT",fmt);
+      67          16 :   if( !getRestart() ) { OFile ofile; ofile.link(*this); ofile.setBackupString("analysis"); ofile.backupAllFiles(fname); }
+      68           8 :   log.printf("  printing to file named %s with formt %s \n",fname.c_str(), fmt.c_str() );
+      69           8 : }
+      70             : 
+      71           9 : void PrintDissimilarityMatrix::performAnalysis() {
+      72           9 :   std::string ofmt=" "+fmt;
+      73          18 :   OFile ofile; ofile.setBackupString("analysis"); ofile.open(fname);
+      74          69 :   for(unsigned i=0; i<getNumberOfDataPoints(); ++i) {
+      75         574 :     for(unsigned j=0; j<getNumberOfDataPoints(); ++j) ofile.printf(ofmt.c_str(), sqrt( my_input_data->getDissimilarity( i,j ) ) );
+      76          60 :     ofile.printf("\n");
+      77             :   }
+      78           9 :   ofile.close();
+      79          18 : }
+      80             : 
+      81             : }
+      82             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.cpp.func-sort-c.html b/coverage/analysis/ReadAnalysisFrames.cpp.func-sort-c.html new file mode 100644 index 000000000000..cd556c8046de --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReadAnalysisFrames.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReadAnalysisFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:737794.8 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis18ReadAnalysisFramesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis18ReadAnalysisFrames27getDissimilarityInstructionB5cxx11Ev5
_ZNK4PLMD8analysis18ReadAnalysisFrames14getAtomIndexesEv12
_ZN4PLMD8analysis18ReadAnalysisFrames16calculateWeightsEv26
_ZN4PLMD8analysis18ReadAnalysisFramesC1ERKNS_13ActionOptionsE30
_ZN4PLMD8analysis18ReadAnalysisFrames16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD8analysis18ReadAnalysisFrames15getArgumentListEv62
_ZN4PLMD8analysis18ReadAnalysisFrames6updateEv7500
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.cpp.func.html b/coverage/analysis/ReadAnalysisFrames.cpp.func.html new file mode 100644 index 000000000000..52027d34f5ae --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReadAnalysisFrames.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReadAnalysisFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:737794.8 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis18ReadAnalysisFrames15getArgumentListEv62
_ZN4PLMD8analysis18ReadAnalysisFrames16calculateWeightsEv26
_ZN4PLMD8analysis18ReadAnalysisFrames16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD8analysis18ReadAnalysisFrames6updateEv7500
_ZN4PLMD8analysis18ReadAnalysisFramesC1ERKNS_13ActionOptionsE30
_ZN4PLMD8analysis18ReadAnalysisFramesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis18ReadAnalysisFrames14getAtomIndexesEv12
_ZNK4PLMD8analysis18ReadAnalysisFrames27getDissimilarityInstructionB5cxx11Ev5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.cpp.gcov.html b/coverage/analysis/ReadAnalysisFrames.cpp.gcov.html new file mode 100644 index 000000000000..5b4b476e48ff --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.cpp.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReadAnalysisFrames.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReadAnalysisFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:737794.8 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ReadAnalysisFrames.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : //+PLUMEDOC ANALYSIS COLLECT_FRAMES
+      28             : /*
+      29             : This allows you to convert a trajectory and a dissimilarity matrix into a dissimilarity object
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace analysis {
+      38             : 
+      39             : PLUMED_REGISTER_ACTION(ReadAnalysisFrames,"COLLECT_FRAMES")
+      40             : 
+      41          32 : void ReadAnalysisFrames::registerKeywords( Keywords& keys ) {
+      42          32 :   AnalysisBase::registerKeywords( keys );
+      43          96 :   keys.remove("SERIAL"); keys.remove("USE_OUTPUT_DATA_FROM"); keys.use("ARG");
+      44          64 :   keys.add("atoms-1","ATOMS","the atoms whose positions we are tracking for the purpose of analyzing the data");
+      45          64 :   keys.add("atoms-1","STRIDE","the frequency with which data should be stored for analysis.  By default data is collected on every step");
+      46          64 :   keys.add("compulsory","CLEAR","0","the frequency with which data should all be deleted and restarted");
+      47          64 :   keys.add("optional","LOGWEIGHTS","list of actions that calculates log weights that should be used to weight configurations when calculating averages");
+      48          32 :   ActionWithValue::useCustomisableComponents( keys );
+      49          32 : }
+      50             : 
+      51          30 : ReadAnalysisFrames::ReadAnalysisFrames( const ActionOptions& ao ):
+      52             :   Action(ao),
+      53             :   AnalysisBase(ao),
+      54          30 :   clearonnextstep(false),
+      55          30 :   wham_pointer(NULL),
+      56          30 :   weights_calculated(false)
+      57             : {
+      58          30 :   parse("CLEAR",clearstride);
+      59          30 :   if( clearstride!=0 ) log.printf("  clearing stored data every %u steps\n",clearstride);
+      60             :   // Get the names of the argumes
+      61          30 :   argument_names.resize( getNumberOfArguments() );
+      62          64 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) argument_names[i]=getPntrToArgument(i)->getName();
+      63             :   // Find the atom numbers to read in
+      64          60 :   parseAtomList("ATOMS",atom_numbers);
+      65          30 :   if( atom_numbers.size()>0 ) {
+      66           5 :     log.printf("  monitoring positions of atoms ");
+      67          79 :     for(unsigned i=0; i<atom_numbers.size(); ++i) log.printf("%d ",atom_numbers[i].serial() );
+      68           5 :     log.printf("\n"); requestAtoms(atom_numbers);
+      69             :   }
+      70             : 
+      71             :   // Get stuff for any reweighting that should go on
+      72          60 :   std::vector<std::string> wwstr; parseVector("LOGWEIGHTS",wwstr);
+      73          30 :   if( wwstr.size()>0 ) log.printf("  reweighting using weights from ");
+      74          30 :   std::vector<Value*> arg( ActionWithArguments::getArguments() );
+      75          42 :   for(unsigned i=0; i<wwstr.size(); ++i) {
+      76          12 :     ActionWithValue* val = plumed.getActionSet().selectWithLabel<ActionWithValue*>(wwstr[i]);
+      77          12 :     if( !val ) error("could not find value named");
+      78          12 :     weight_vals.push_back( val->copyOutput(val->getLabel()) );
+      79          12 :     arg.push_back( val->copyOutput(val->getLabel()) );
+      80          12 :     log.printf("%s ",wwstr[i].c_str() );
+      81             :   }
+      82          30 :   if( wwstr.size()>0 ) {
+      83          12 :     log.printf("\n");
+      84          12 :     wham_pointer = dynamic_cast<bias::ReweightBase*>( weight_vals[0]->getPntrToAction() );
+      85          12 :     if( !wham_pointer ) wham_pointer = NULL;
+      86          12 :     else if( !wham_pointer->buildsWeightStore() ) wham_pointer = NULL;
+      87          12 :     if( wham_pointer && weight_vals.size()!=1 ) error("can only extract weights from one wham object");
+      88          18 :   } else log.printf("  weights are all equal to one\n");
+      89          30 :   requestArguments( arg );
+      90             : 
+      91             :   // Now add fake components to the underlying ActionWithValue for the arguments
+      92          64 :   for(unsigned i=0; i<argument_names.size(); ++i) { addComponent( argument_names[i] ); componentIsNotPeriodic( argument_names[i] ); }
+      93          30 : }
+      94             : 
+      95          62 : std::vector<Value*> ReadAnalysisFrames::getArgumentList() {
+      96          62 :   std::vector<Value*> arg_vals( ActionWithArguments::getArguments() );
+      97          68 :   for(unsigned i=0; i<weight_vals.size(); ++i) arg_vals.erase(arg_vals.end()-1);
+      98          62 :   return arg_vals;
+      99             : }
+     100             : 
+     101           5 : std::string ReadAnalysisFrames::getDissimilarityInstruction() const {
+     102           5 :   return "TYPE=UNKNOWN";
+     103             : }
+     104             : 
+     105          12 : const std::vector<AtomNumber>& ReadAnalysisFrames::getAtomIndexes() const {
+     106          12 :   return getAbsoluteIndexes();
+     107             : }
+     108             : 
+     109          26 : void ReadAnalysisFrames::calculateWeights() {
+     110          26 :   weights_calculated=true;
+     111          26 :   weights.resize( logweights.size() );
+     112          26 :   if( weight_vals.empty() ) {
+     113        3261 :     for(unsigned i=0; i<logweights.size(); ++i) weights[i]=1.0;
+     114             :   } else {
+     115           7 :     if( wham_pointer ) {
+     116           7 :       wham_pointer->calculateWeights( logweights.size() );
+     117        2464 :       for(unsigned i=0; i<logweights.size(); ++i) weights[i]=wham_pointer->getWeight(i);
+     118             :     } else {
+     119             :       // Find the maximum weight
+     120           0 :       double maxweight=logweights[0];
+     121           0 :       for(unsigned i=1; i<getNumberOfDataPoints(); ++i) {
+     122           0 :         if(logweights[i]>maxweight) maxweight=logweights[i];
+     123             :       }
+     124             :       // Calculate weights (no memory) -- business here with maxweight is to prevent overflows
+     125           0 :       for(unsigned i=0; i<logweights.size(); ++i) weights[i]=std::exp( logweights[i]-maxweight );
+     126             :     }
+     127             :   }
+     128          26 : }
+     129             : 
+     130        7500 : void ReadAnalysisFrames::update() {
+     131        7500 :   if( getStep()==0 ) return;
+     132             :   // Delete everything we stored now that it has been analyzed
+     133        7472 :   if( clearonnextstep ) {
+     134           5 :     my_data_stash.clear(); my_data_stash.resize(0);
+     135          10 :     logweights.clear(); logweights.resize(0);
+     136           5 :     if( wham_pointer ) wham_pointer->clearData();
+     137           5 :     clearonnextstep=false;
+     138             :   }
+     139             : 
+     140             :   // Get the weight and store it in the weights array
+     141       11684 :   double ww=0; for(unsigned i=0; i<weight_vals.size(); ++i) ww+=weight_vals[i]->get();
+     142        7472 :   weights_calculated=false; logweights.push_back(ww);
+     143             : 
+     144             :   // Now create the data collection object and push it back to be stored
+     145        7472 :   unsigned index = my_data_stash.size(); my_data_stash.push_back( DataCollectionObject() );
+     146        7472 :   my_data_stash[index].setAtomNumbersAndArgumentNames( getLabel(), atom_numbers, argument_names );
+     147        7472 :   my_data_stash[index].setAtomPositions( getPositions() );
+     148       16079 :   for(unsigned i=0; i<argument_names.size(); ++i) my_data_stash[index].setArgument( argument_names[i], getArgument(i) );
+     149             : 
+     150        7472 :   if( clearstride>0 ) {
+     151         475 :     if( getStep()%clearstride==0 ) clearonnextstep=true;
+     152             :   }
+     153             : }
+     154             : 
+     155             : }
+     156             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.h.func-sort-c.html b/coverage/analysis/ReadAnalysisFrames.h.func-sort-c.html new file mode 100644 index 000000000000..0f1b4c52c79c --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReadAnalysisFrames.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReadAnalysisFrames.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91369.2 %
Date:2024-02-22 21:58:45Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis18ReadAnalysisFrames15performAnalysisEv0
_ZNK4PLMD8analysis18ReadAnalysisFrames11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis18ReadAnalysisFrames22dissimilaritiesWereSetEv0
_ZNK4PLMD8analysis18ReadAnalysisFrames21getNumberOfDataPointsEv37013
_ZNK4PLMD8analysis18ReadAnalysisFrames23getDataPointIndexInBaseERKj125002
_ZN4PLMD8analysis18ReadAnalysisFrames13getStoredDataERKjRKb522672
_ZN4PLMD8analysis18ReadAnalysisFrames9getWeightERKj7777606
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.h.func.html b/coverage/analysis/ReadAnalysisFrames.h.func.html new file mode 100644 index 000000000000..a1008357e47e --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReadAnalysisFrames.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReadAnalysisFrames.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91369.2 %
Date:2024-02-22 21:58:45Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis18ReadAnalysisFrames13getStoredDataERKjRKb522672
_ZN4PLMD8analysis18ReadAnalysisFrames15performAnalysisEv0
_ZN4PLMD8analysis18ReadAnalysisFrames9getWeightERKj7777606
_ZNK4PLMD8analysis18ReadAnalysisFrames11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis18ReadAnalysisFrames21getNumberOfDataPointsEv37013
_ZNK4PLMD8analysis18ReadAnalysisFrames22dissimilaritiesWereSetEv0
_ZNK4PLMD8analysis18ReadAnalysisFrames23getDataPointIndexInBaseERKj125002
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadAnalysisFrames.h.gcov.html b/coverage/analysis/ReadAnalysisFrames.h.gcov.html new file mode 100644 index 000000000000..e6bc9d9c3c1f --- /dev/null +++ b/coverage/analysis/ReadAnalysisFrames.h.gcov.html @@ -0,0 +1,183 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReadAnalysisFrames.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReadAnalysisFrames.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91369.2 %
Date:2024-02-22 21:58:45Functions:4757.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_analysis_ReadAnalysisFrames_h
+      23             : #define __PLUMED_analysis_ReadAnalysisFrames_h
+      24             : 
+      25             : #include "AnalysisBase.h"
+      26             : #include "bias/ReweightBase.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace analysis {
+      30             : 
+      31             : class ReadAnalysisFrames : public AnalysisBase {
+      32             : private:
+      33             : /// The frequency with which to clear the data stash
+      34             :   unsigned clearstride;
+      35             :   bool clearonnextstep;
+      36             : /// The list of argument names that we are storing
+      37             :   std::vector<std::string> argument_names;
+      38             : /// The list of atom numbers that we are storing
+      39             :   std::vector<AtomNumber> atom_numbers;
+      40             : /// The biases we are using in reweighting and the args we store them separately
+      41             :   std::vector<Value*> weight_vals;
+      42             : /// The object that calculates weights using WHAM
+      43             :   bias::ReweightBase* wham_pointer;
+      44             : /// The weights of all the data points
+      45             :   bool weights_calculated;
+      46             :   std::vector<double> logweights, weights;
+      47             : /// The data that has been collected from the trajectory
+      48             :   std::vector<DataCollectionObject> my_data_stash;
+      49             : /// Calculate the weights of the various points from the logweights
+      50             :   void calculateWeights();
+      51             : public:
+      52             :   static void registerKeywords( Keywords& keys );
+      53             :   explicit ReadAnalysisFrames( const ActionOptions& ao );
+      54             :   void update() override;
+      55             : /// This does nothing
+      56           0 :   void performAnalysis() override {}
+      57             : /// This does nothing - it just ensures the final class is not abstract
+      58           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override { plumed_error(); }
+      59             : /// Get the number of data points
+      60             :   unsigned getNumberOfDataPoints() const override;
+      61             : /// Get the index of the data point
+      62             :   unsigned getDataPointIndexInBase( const unsigned& idata ) const override;
+      63             : /// Get the input arguments
+      64             :   std::vector<Value*> getArgumentList() override;
+      65             : /// Have dissimilarities between thses objects been calculated
+      66             :   bool dissimilaritiesWereSet() const override;
+      67             : /// How are dissimilarities calcualted is not known
+      68             :   std::string getDissimilarityInstruction() const override;
+      69             : /// Get the weight of one of the objects
+      70             :   double getWeight( const unsigned& idat ) override;
+      71             : /// Get the reference configuration
+      72             :   DataCollectionObject & getStoredData( const unsigned& idata, const bool& calcdist ) override;
+      73             : /// Get the list of atoms that are being stored
+      74             :   const std::vector<AtomNumber>& getAtomIndexes() const override;
+      75             : };
+      76             : 
+      77             : inline
+      78       37013 : unsigned ReadAnalysisFrames::getNumberOfDataPoints() const {
+      79       37013 :   return my_data_stash.size();
+      80             : }
+      81             : 
+      82             : inline
+      83      125002 : unsigned ReadAnalysisFrames::getDataPointIndexInBase( const unsigned& idata ) const {
+      84      125002 :   return idata;
+      85             : }
+      86             : 
+      87             : inline
+      88           0 : bool ReadAnalysisFrames::dissimilaritiesWereSet() const {
+      89           0 :   return false;
+      90             : }
+      91             : 
+      92             : inline
+      93     7777606 : double ReadAnalysisFrames::getWeight( const unsigned& idat ) {
+      94     7777606 :   if( !weights_calculated ) calculateWeights();
+      95     7777606 :   return weights[idat];
+      96             : }
+      97             : 
+      98             : inline
+      99      522672 : DataCollectionObject & ReadAnalysisFrames::getStoredData( const unsigned& idata, const bool& calcdist ) {
+     100             :   plumed_dbg_assert( idata<my_data_stash.size() );
+     101      522672 :   return my_data_stash[idata];
+     102             : }
+     103             : 
+     104             : }
+     105             : }
+     106             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadDissimilarityMatrix.cpp.func-sort-c.html b/coverage/analysis/ReadDissimilarityMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..34d8b4cba453 --- /dev/null +++ b/coverage/analysis/ReadDissimilarityMatrix.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReadDissimilarityMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReadDissimilarityMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:516282.3 %
Date:2024-02-22 21:58:45Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis23ReadDissimilarityMatrix15performAnalysisEv0
_ZN4PLMD8analysis23ReadDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis23ReadDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis23ReadDissimilarityMatrix23getDataPointIndexInBaseERKj0
_ZN4PLMD8analysis23ReadDissimilarityMatrix12runFinalJobsEv2
_ZN4PLMD8analysis23ReadDissimilarityMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD8analysis23ReadDissimilarityMatrix16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8analysis23ReadDissimilarityMatrix13getStoredDataERKjRKb5
_ZN4PLMD8analysis23ReadDissimilarityMatrix6updateEv7
_ZNK4PLMD8analysis23ReadDissimilarityMatrix22dissimilaritiesWereSetEv11
_ZN4PLMD8analysis23ReadDissimilarityMatrix9getWeightERKj18
_ZNK4PLMD8analysis23ReadDissimilarityMatrix21getNumberOfDataPointsEv257
_ZN4PLMD8analysis23ReadDissimilarityMatrix16getDissimilarityERKjS3_334
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadDissimilarityMatrix.cpp.func.html b/coverage/analysis/ReadDissimilarityMatrix.cpp.func.html new file mode 100644 index 000000000000..440ebda459f4 --- /dev/null +++ b/coverage/analysis/ReadDissimilarityMatrix.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReadDissimilarityMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReadDissimilarityMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:516282.3 %
Date:2024-02-22 21:58:45Functions:91369.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis23ReadDissimilarityMatrix12runFinalJobsEv2
_ZN4PLMD8analysis23ReadDissimilarityMatrix13getStoredDataERKjRKb5
_ZN4PLMD8analysis23ReadDissimilarityMatrix15performAnalysisEv0
_ZN4PLMD8analysis23ReadDissimilarityMatrix16getDissimilarityERKjS3_334
_ZN4PLMD8analysis23ReadDissimilarityMatrix16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8analysis23ReadDissimilarityMatrix6updateEv7
_ZN4PLMD8analysis23ReadDissimilarityMatrix9getWeightERKj18
_ZN4PLMD8analysis23ReadDissimilarityMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD8analysis23ReadDissimilarityMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD8analysis23ReadDissimilarityMatrix11performTaskERKjS3_RNS_10MultiValueE0
_ZNK4PLMD8analysis23ReadDissimilarityMatrix21getNumberOfDataPointsEv257
_ZNK4PLMD8analysis23ReadDissimilarityMatrix22dissimilaritiesWereSetEv11
_ZNK4PLMD8analysis23ReadDissimilarityMatrix23getDataPointIndexInBaseERKj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReadDissimilarityMatrix.cpp.gcov.html b/coverage/analysis/ReadDissimilarityMatrix.cpp.gcov.html new file mode 100644 index 000000000000..4acba29135dc --- /dev/null +++ b/coverage/analysis/ReadDissimilarityMatrix.cpp.gcov.html @@ -0,0 +1,244 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReadDissimilarityMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReadDissimilarityMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:516282.3 %
Date:2024-02-22 21:58:45Functions:91369.2 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AnalysisBase.h"
+      23             : #include "ReadAnalysisFrames.h"
+      24             : #include "reference/ReferenceConfiguration.h"
+      25             : #include "reference/MetricRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/ActionRegister.h"
+      29             : #include "core/ActionSetup.h"
+      30             : #include "core/ActionForInterface.h"
+      31             : #include "tools/IFile.h"
+      32             : 
+      33             : //+PLUMEDOC ANALYSIS READ_DISSIMILARITY_MATRIX
+      34             : /*
+      35             : Read a matrix of dissimilarities between a trajectory of atomic configurations from a file.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : */
+      40             : //+ENDPLUMEDOC
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace analysis {
+      44             : 
+      45             : class ReadDissimilarityMatrix : public AnalysisBase {
+      46             : private:
+      47             :   unsigned nnodes;
+      48             :   std::vector<DataCollectionObject> fake_data;
+      49             :   std::string fname, wfile;
+      50             : //  Matrix<double> dissimilarities;
+      51             :   std::vector<std::vector<double> > dissimilarities;
+      52             :   std::vector<double> weights;
+      53             : public:
+      54             :   static void registerKeywords( Keywords& keys );
+      55             :   explicit ReadDissimilarityMatrix( const ActionOptions& ao );
+      56             :   unsigned getNumberOfDataPoints() const override;
+      57             : // Return the index of the data point in the base class
+      58             :   unsigned getDataPointIndexInBase( const unsigned& idata ) const override;
+      59             : /// This gives an error as if we read in the matrix we dont have the coordinates
+      60             :   DataCollectionObject& getStoredData( const unsigned& idata, const bool& calcdist ) override;
+      61             : /// Tell everyone we have dissimilarities
+      62          11 :   bool dissimilaritiesWereSet() const override { return true; }
+      63             : /// Get the dissimilarity between two data points
+      64             :   double getDissimilarity( const unsigned&, const unsigned& ) override;
+      65             : /// Get the weight from the input file
+      66             :   double getWeight( const unsigned& idata ) override;
+      67             : /// Just tell plumed to stop
+      68             :   void update() override;
+      69             : /// Read in the dissimilarity matrix
+      70             :   void runFinalJobs() override;
+      71             : /// This does nothing
+      72           0 :   void performAnalysis() override {};
+      73             : /// Overwrite virtual function in base class
+      74           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override { plumed_error(); }
+      75             : };
+      76             : 
+      77             : PLUMED_REGISTER_ACTION(ReadDissimilarityMatrix,"READ_DISSIMILARITY_MATRIX")
+      78             : 
+      79           4 : void ReadDissimilarityMatrix::registerKeywords( Keywords& keys ) {
+      80           4 :   AnalysisBase::registerKeywords( keys );
+      81           8 :   keys.add("compulsory","FILE","an input file containing the matrix of dissimilarities");
+      82           8 :   keys.add("optional","WFILE","input file containing weights of points");
+      83           8 :   keys.reset_style("USE_OUTPUT_DATA_FROM","optional");
+      84           4 : }
+      85             : 
+      86           2 : ReadDissimilarityMatrix::ReadDissimilarityMatrix( const ActionOptions& ao ):
+      87             :   Action(ao),
+      88             :   AnalysisBase(ao),
+      89           2 :   nnodes(1)
+      90             : {
+      91           2 :   setStride(1); // Set the stride equal to one to ensure we don't get stuck in an infinite loop
+      92           2 :   std::vector<ActionSetup*> setupActions=plumed.getActionSet().select<ActionSetup*>();
+      93           2 :   std::vector<ActionForInterface*> interActions=plumed.getActionSet().select<ActionForInterface*>();
+      94           2 :   if( my_input_data && (plumed.getActionSet().size()-setupActions.size()-interActions.size())!=1 ) error("should only be this action and the READ_ANALYSIS_FRAMES command in the input file");
+      95           2 :   if( !my_input_data && plumed.getActionSet().size()!=interActions.size() ) error("read dissimilarity matrix command must be at top of input file");
+      96             : 
+      97           2 :   parse("FILE",fname);
+      98           2 :   log.printf("  reading dissimilarity matrix from file %s \n",fname.c_str() );
+      99           4 :   parse("WFILE",wfile);
+     100             : 
+     101           2 :   if( wfile.length()>0 ) log.printf("  reading weights of nodes from file named %s \n",wfile.c_str() );
+     102           2 :   else log.printf("  setting weights of all nodes equal to one\n");
+     103           2 : }
+     104             : 
+     105           7 : void ReadDissimilarityMatrix::update() { if(!my_input_data) plumed.stop(); }
+     106             : 
+     107           2 : void ReadDissimilarityMatrix::runFinalJobs() {
+     108           2 :   IFile mfile; mfile.open(fname);
+     109             :   // Read in first line
+     110           2 :   std::vector<std::string> words; nnodes=0;
+     111           4 :   while( nnodes==0 ) {
+     112           2 :     Tools::getParsedLine( mfile, words );
+     113           2 :     nnodes=words.size();
+     114             :   }
+     115             : 
+     116           2 :   std::vector<double> tmpdis( nnodes );
+     117          20 :   for(unsigned j=0; j<nnodes; ++j) Tools::convert( words[j], tmpdis[j] );
+     118           2 :   dissimilarities.push_back( tmpdis );
+     119             : 
+     120          18 :   while( Tools::getParsedLine( mfile, words ) ) {
+     121          16 :     if( words.size()!=nnodes ) error("bad formatting in matrix file");
+     122         192 :     for(unsigned j=0; j<nnodes; ++j) Tools::convert( words[j], tmpdis[j] );
+     123          16 :     dissimilarities.push_back( tmpdis );
+     124             :   }
+     125           2 :   mfile.close();
+     126           2 :   if( my_input_data && dissimilarities.size()!=getNumberOfDataPoints() ) {
+     127           0 :     error("mismatch between number of data points in trajectory and the dimensions of the dissimilarity matrix");
+     128             :   }
+     129           2 :   if( !my_input_data ) fake_data.resize( dissimilarities.size() );
+     130             : 
+     131           2 :   weights.resize( dissimilarities.size() );
+     132           2 :   if( wfile.length()>0 ) {
+     133           0 :     IFile wfilef; wfilef.open(wfile);
+     134           0 :     for(unsigned i=0; i<weights.size(); ++i) {
+     135           0 :       Tools::getParsedLine( wfilef, words ); Tools::convert( words[0], weights[i] );
+     136             :     }
+     137           0 :     wfilef.close();
+     138           0 :   } else {
+     139           2 :     weights.assign(weights.size(),1.0);
+     140             :   }
+     141           2 : }
+     142             : 
+     143         257 : unsigned ReadDissimilarityMatrix::getNumberOfDataPoints() const {
+     144         302 :   if( my_input_data ) return AnalysisBase::getNumberOfDataPoints();
+     145         212 :   return dissimilarities.size();
+     146             : }
+     147             : 
+     148           0 : unsigned ReadDissimilarityMatrix::getDataPointIndexInBase( const unsigned& idata ) const {
+     149           0 :   return idata;
+     150             : }
+     151             : 
+     152         334 : double ReadDissimilarityMatrix::getDissimilarity( const unsigned& iframe, const unsigned& jframe ) {
+     153         334 :   return dissimilarities[iframe][jframe]*dissimilarities[iframe][jframe];
+     154             : }
+     155             : 
+     156           5 : DataCollectionObject& ReadDissimilarityMatrix::getStoredData( const unsigned& idata, const bool& calcdist ) {
+     157           5 :   plumed_massert( !calcdist, "cannot calc dist as this data was read in from input");
+     158          10 :   if( my_input_data ) return AnalysisBase::getStoredData( idata, calcdist );
+     159           0 :   return fake_data[idata];
+     160             : }
+     161             : 
+     162          18 : double ReadDissimilarityMatrix::getWeight( const unsigned& idata ) {
+     163          18 :   plumed_assert( idata<dissimilarities.size() ); return weights[idata];
+     164             : }
+     165             : 
+     166             : }
+     167             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReselectLandmarks.cpp.func-sort-c.html b/coverage/analysis/ReselectLandmarks.cpp.func-sort-c.html new file mode 100644 index 000000000000..6a5d2b77e684 --- /dev/null +++ b/coverage/analysis/ReselectLandmarks.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReselectLandmarks.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReselectLandmarks.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis17ReselectLandmarksC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis17ReselectLandmarks15selectLandmarksEv1
_ZN4PLMD8analysis17ReselectLandmarksC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis17ReselectLandmarks16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReselectLandmarks.cpp.func.html b/coverage/analysis/ReselectLandmarks.cpp.func.html new file mode 100644 index 000000000000..245933eb24c8 --- /dev/null +++ b/coverage/analysis/ReselectLandmarks.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReselectLandmarks.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReselectLandmarks.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis17ReselectLandmarks15selectLandmarksEv1
_ZN4PLMD8analysis17ReselectLandmarks16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8analysis17ReselectLandmarksC1ERKNS_13ActionOptionsE1
_ZN4PLMD8analysis17ReselectLandmarksC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/ReselectLandmarks.cpp.gcov.html b/coverage/analysis/ReselectLandmarks.cpp.gcov.html new file mode 100644 index 000000000000..4b67e465cfc7 --- /dev/null +++ b/coverage/analysis/ReselectLandmarks.cpp.gcov.html @@ -0,0 +1,151 @@ + + + + + + + + LCOV - plumed test coverage - analysis/ReselectLandmarks.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - ReselectLandmarks.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "LandmarkSelectionBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "tools/Random.h"
+      27             : 
+      28             : //+PLUMEDOC LANDMARKS RESELECT_LANDMARKS
+      29             : /*
+      30             : This allows us to use one measure in landmark selection and a different measure in dimensionality reduction
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace analysis {
+      39             : 
+      40             : class ReselectLandmarks : public LandmarkSelectionBase {
+      41             : private:
+      42             :   LandmarkSelectionBase* mylandmarks;
+      43             : public:
+      44             :   static void registerKeywords( Keywords& keys );
+      45             :   explicit ReselectLandmarks( const ActionOptions& ao );
+      46             :   void selectLandmarks() override;
+      47             : };
+      48             : 
+      49             : PLUMED_REGISTER_ACTION(ReselectLandmarks,"RESELECT_LANDMARKS")
+      50             : 
+      51           3 : void ReselectLandmarks::registerKeywords( Keywords& keys ) {
+      52           3 :   LandmarkSelectionBase::registerKeywords(keys);
+      53           3 :   keys.remove("NLANDMARKS");
+      54           6 :   keys.add("compulsory","LANDMARKS","the action that selects the landmarks that you want to reselect using this action");
+      55           3 : }
+      56             : 
+      57           1 : ReselectLandmarks::ReselectLandmarks( const ActionOptions& ao ):
+      58             :   Action(ao),
+      59           1 :   LandmarkSelectionBase(ao)
+      60             : {
+      61           1 :   std::string datastr; parse("LANDMARKS",datastr);
+      62           1 :   mylandmarks = plumed.getActionSet().selectWithLabel<LandmarkSelectionBase*>( datastr );
+      63           1 :   if( !mylandmarks ) error("input to LANDMARKS is not a landmark selection action");
+      64           1 :   nlandmarks = mylandmarks->nlandmarks;
+      65             : 
+      66           1 :   if( (mylandmarks->my_input_data)->getNumberOfDataPoints()!=my_input_data->getNumberOfDataPoints() ) error("mismatch between amount of landmark class and base class");
+      67           1 : }
+      68             : 
+      69           1 : void ReselectLandmarks::selectLandmarks() {
+      70           3 :   for(unsigned i=0; i<mylandmarks->getNumberOfDataPoints(); ++i) selectFrame( mylandmarks->getDataPointIndexInBase(i) );
+      71           1 : }
+      72             : 
+      73             : }
+      74             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectRandomFrames.cpp.func-sort-c.html b/coverage/analysis/SelectRandomFrames.cpp.func-sort-c.html new file mode 100644 index 000000000000..d526ae674e04 --- /dev/null +++ b/coverage/analysis/SelectRandomFrames.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/SelectRandomFrames.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - SelectRandomFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41921.1 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis18SelectRandomFrames15selectLandmarksEv0
_ZN4PLMD8analysis18SelectRandomFramesC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis18SelectRandomFramesC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis18SelectRandomFrames16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectRandomFrames.cpp.func.html b/coverage/analysis/SelectRandomFrames.cpp.func.html new file mode 100644 index 000000000000..1bb1632a53d6 --- /dev/null +++ b/coverage/analysis/SelectRandomFrames.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/SelectRandomFrames.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - SelectRandomFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41921.1 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis18SelectRandomFrames15selectLandmarksEv0
_ZN4PLMD8analysis18SelectRandomFrames16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8analysis18SelectRandomFramesC1ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis18SelectRandomFramesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectRandomFrames.cpp.gcov.html b/coverage/analysis/SelectRandomFrames.cpp.gcov.html new file mode 100644 index 000000000000..ba170dc2f60e --- /dev/null +++ b/coverage/analysis/SelectRandomFrames.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - analysis/SelectRandomFrames.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - SelectRandomFrames.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41921.1 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "LandmarkSelectionBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Random.h"
+      25             : 
+      26             : //+PLUMEDOC LANDMARKS LANDMARK_SELECT_RANDOM
+      27             : /*
+      28             : Select a random set of landmarks from a large set of configurations.
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace analysis {
+      37             : 
+      38             : class SelectRandomFrames : public LandmarkSelectionBase {
+      39             : private:
+      40             :   unsigned seed;
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             :   explicit SelectRandomFrames( const ActionOptions& ao );
+      44             :   void selectLandmarks() override;
+      45             : };
+      46             : 
+      47             : PLUMED_REGISTER_ACTION(SelectRandomFrames,"LANDMARK_SELECT_RANDOM")
+      48             : 
+      49           2 : void SelectRandomFrames::registerKeywords( Keywords& keys ) {
+      50           2 :   LandmarkSelectionBase::registerKeywords(keys);
+      51           4 :   keys.add("compulsory","SEED","1234","a random number seed");
+      52           2 : }
+      53             : 
+      54           0 : SelectRandomFrames::SelectRandomFrames( const ActionOptions& ao ):
+      55             :   Action(ao),
+      56           0 :   LandmarkSelectionBase(ao)
+      57             : {
+      58           0 :   parse("SEED",seed);
+      59           0 : }
+      60             : 
+      61           0 : void SelectRandomFrames::selectLandmarks() {
+      62           0 :   Random r; r.setSeed(-seed);
+      63           0 :   unsigned nframe=my_input_data->getNumberOfDataPoints();
+      64           0 :   unsigned nland=getNumberOfDataPoints();
+      65             : 
+      66           0 :   std::vector<bool> selected( nframe, false );
+      67             : 
+      68             :   unsigned fcount=0;
+      69           0 :   while (fcount<nland) {
+      70           0 :     unsigned iframe = std::floor( r.U01()*nframe );
+      71           0 :     if (!selected[iframe]) {
+      72             :       selected[iframe]=true;
+      73           0 :       selectFrame( iframe );
+      74           0 :       ++fcount;
+      75             :     }
+      76             :   }
+      77           0 : }
+      78             : 
+      79             : }
+      80             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectWithStride.cpp.func-sort-c.html b/coverage/analysis/SelectWithStride.cpp.func-sort-c.html new file mode 100644 index 000000000000..35276d9a9a9d --- /dev/null +++ b/coverage/analysis/SelectWithStride.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/SelectWithStride.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - SelectWithStride.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis16SelectWithStrideC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis16SelectWithStrideC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis16SelectWithStride15selectLandmarksEv10
_ZN4PLMD8analysis16SelectWithStride16registerKeywordsERNS_8KeywordsE10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectWithStride.cpp.func.html b/coverage/analysis/SelectWithStride.cpp.func.html new file mode 100644 index 000000000000..186704661398 --- /dev/null +++ b/coverage/analysis/SelectWithStride.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - analysis/SelectWithStride.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - SelectWithStride.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis16SelectWithStride15selectLandmarksEv10
_ZN4PLMD8analysis16SelectWithStride16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD8analysis16SelectWithStrideC1ERKNS_13ActionOptionsE8
_ZN4PLMD8analysis16SelectWithStrideC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/SelectWithStride.cpp.gcov.html b/coverage/analysis/SelectWithStride.cpp.gcov.html new file mode 100644 index 000000000000..8214402a7b07 --- /dev/null +++ b/coverage/analysis/SelectWithStride.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + + LCOV - plumed test coverage - analysis/SelectWithStride.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - SelectWithStride.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "LandmarkSelectionBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC LANDMARKS LANDMARK_SELECT_STRIDE
+      26             : /*
+      27             : Select every \f$k\f$th landmark from the trajectory.
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace analysis {
+      36             : 
+      37             : class SelectWithStride : public LandmarkSelectionBase {
+      38             : public:
+      39             :   static void registerKeywords( Keywords& keys );
+      40             :   explicit SelectWithStride( const ActionOptions& ao );
+      41             :   void selectLandmarks() override;
+      42             : };
+      43             : 
+      44             : PLUMED_REGISTER_ACTION(SelectWithStride,"LANDMARK_SELECT_STRIDE")
+      45             : 
+      46          10 : void SelectWithStride::registerKeywords( Keywords& keys ) {
+      47          10 :   LandmarkSelectionBase::registerKeywords( keys );
+      48          10 : }
+      49             : 
+      50           8 : SelectWithStride::SelectWithStride( const ActionOptions& ao ):
+      51             :   Action(ao),
+      52           8 :   LandmarkSelectionBase(ao)
+      53             : {
+      54           8 : }
+      55             : 
+      56          10 : void SelectWithStride::selectLandmarks() {
+      57          10 :   unsigned stride = std::floor( my_input_data->getNumberOfDataPoints() / getNumberOfDataPoints() ), max=stride*getNumberOfDataPoints();
+      58         296 :   for(unsigned i=0; i<max; i+=stride) selectFrame( i );
+      59          10 : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamHistogram.cpp.func-sort-c.html b/coverage/analysis/WhamHistogram.cpp.func-sort-c.html new file mode 100644 index 000000000000..6ddd098fb281 --- /dev/null +++ b/coverage/analysis/WhamHistogram.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - analysis/WhamHistogram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - WhamHistogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13WhamHistogramC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis13WhamHistogramC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13WhamHistogram16registerKeywordsERNS_8KeywordsE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamHistogram.cpp.func.html b/coverage/analysis/WhamHistogram.cpp.func.html new file mode 100644 index 000000000000..3487cb1b9778 --- /dev/null +++ b/coverage/analysis/WhamHistogram.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - analysis/WhamHistogram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - WhamHistogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis13WhamHistogram16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8analysis13WhamHistogramC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis13WhamHistogramC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamHistogram.cpp.gcov.html b/coverage/analysis/WhamHistogram.cpp.gcov.html new file mode 100644 index 000000000000..bd841b292d2b --- /dev/null +++ b/coverage/analysis/WhamHistogram.cpp.gcov.html @@ -0,0 +1,199 @@ + + + + + + + + LCOV - plumed test coverage - analysis/WhamHistogram.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - WhamHistogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace analysis {
+      27             : 
+      28             : //+PLUMEDOC REWEIGHTING WHAM_HISTOGRAM
+      29             : /*
+      30             : This can be used to output the a histogram using the weighted histogram technique
+      31             : 
+      32             : This shortcut action allows you to calculate a histogram using the weighted histogram
+      33             : analysis technique.  For more detail on how this the weights for configurations are
+      34             : computed see \ref REWEIGHT_WHAM
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The following input can be used to analyze the output from a series of umbrella sampling calculations.
+      39             : The trajectory from each of the simulations run with the different biases should be concatenated into a
+      40             : single trajectory before running the following analysis script on the concatenated trajectory using PLUMED
+      41             : driver.  The umbrella sampling simulations that will be analyzed using the script below applied a harmonic
+      42             : restraint that restrained the torsional angle involving atoms 5, 7, 9 and 15 to particular values.  The script
+      43             : below calculates the reweighting weights for each of the trajectories and then applies the binless WHAM algorithm
+      44             : to determine a weight for each configuration in the concatenated trajectory.  A histogram is then constructed from
+      45             : the configurations visited and their weights.  This histogram is then converted into a free energy surface and output
+      46             : to a file called fes.dat
+      47             : 
+      48             : \plumedfile
+      49             : #SETTINGS NREPLICAS=4
+      50             : phi: TORSION ATOMS=5,7,9,15
+      51             : psi: TORSION ATOMS=7,9,15,17
+      52             : rp: RESTRAINT ARG=phi KAPPA=50.0 ...
+      53             :   AT=@replicas:{
+      54             :         -3.00000000000000000000
+      55             :         -1.45161290322580645168
+      56             :         .09677419354838709664
+      57             :         1.64516129032258064496
+      58             :      }
+      59             : ...
+      60             : 
+      61             : hh: WHAM_HISTOGRAM ARG=phi BIAS=rp.bias TEMP=300 GRID_MIN=-pi GRID_MAX=pi GRID_BIN=50
+      62             : fes: CONVERT_TO_FES GRID=hh TEMP=300
+      63             : DUMPGRID GRID=fes FILE=fes.dat
+      64             : \endplumedfile
+      65             : 
+      66             : The script above must be run with multiple replicas using the following command:
+      67             : 
+      68             : \verbatim
+      69             : mpirun -np 4 plumed driver --mf_xtc alltraj.xtc --multi 4
+      70             : \endverbatim
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : 
+      75             : class WhamHistogram : public ActionShortcut {
+      76             : public:
+      77             :   static void registerKeywords( Keywords& keys );
+      78             :   explicit WhamHistogram( const ActionOptions& );
+      79             : };
+      80             : 
+      81             : PLUMED_REGISTER_ACTION(WhamHistogram,"WHAM_HISTOGRAM")
+      82             : 
+      83           8 : void WhamHistogram::registerKeywords( Keywords& keys ) {
+      84           8 :   ActionShortcut::registerKeywords( keys );
+      85          16 :   keys.add("compulsory","ARG","the arguments that you would like to make the histogram for");
+      86          16 :   keys.add("compulsory","BIAS","*.bias","the value of the biases to use when performing WHAM");
+      87          16 :   keys.add("compulsory","TEMP","the temperature at which the simulation was run");
+      88          16 :   keys.add("compulsory","STRIDE","1","the frequency with which the data should be stored to perform WHAM");
+      89          16 :   keys.add("compulsory","GRID_MIN","the minimum to use for the grid");
+      90          16 :   keys.add("compulsory","GRID_MAX","the maximum to use for the grid");
+      91          16 :   keys.add("compulsory","GRID_BIN","the number of bins to use for the grid");
+      92          16 :   keys.add("optional","BANDWIDTH","the bandwidth for kernel density estimation");
+      93           8 : }
+      94             : 
+      95             : 
+      96           6 : WhamHistogram::WhamHistogram( const ActionOptions& ao ) :
+      97             :   Action(ao),
+      98           6 :   ActionShortcut(ao)
+      99             : {
+     100             :   // Input for REWEIGHT_WHAM
+     101           6 :   std::string rew_line = getShortcutLabel() + "_weights: REWEIGHT_WHAM";
+     102          18 :   std::string bias; parse("BIAS",bias); rew_line += " ARG=" + bias;
+     103          12 :   std::string temp; parse("TEMP",temp); rew_line += " TEMP=" + temp;
+     104           6 :   readInputLine( rew_line );
+     105             :   // Input for COLLECT_FRAMES
+     106          12 :   std::string col_line = getShortcutLabel() + "_collect: COLLECT_FRAMES LOGWEIGHTS=" + getShortcutLabel() + "_weights";
+     107          18 :   std::string stride; parse("STRIDE",stride); col_line += " STRIDE=" + stride;
+     108          12 :   std::string arg; parse("ARG",arg); col_line += " ARG=" + arg;
+     109           6 :   readInputLine( col_line );
+     110             :   // Input for HISTOGRAM
+     111          12 :   std::string histo_line = getShortcutLabel() + ": HISTOGRAM ARG=" + getShortcutLabel() + "_collect.*";
+     112          18 :   std::string min; parse("GRID_MIN",min); histo_line += " GRID_MIN=" + min;
+     113          18 :   std::string max; parse("GRID_MAX",max); histo_line += " GRID_MAX=" + max;
+     114          12 :   std::string bin; parse("GRID_BIN",bin); histo_line += " GRID_BIN=" + bin;
+     115          12 :   std::string bw=""; parse("BANDWIDTH",bw);
+     116           6 :   if( bw!="" ) histo_line += " BANDWIDTH=" + bw;
+     117             :   else histo_line += " KERNEL=DISCRETE";
+     118           6 :   readInputLine( histo_line );
+     119           6 : }
+     120             : 
+     121             : }
+     122             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamWeights.cpp.func-sort-c.html b/coverage/analysis/WhamWeights.cpp.func-sort-c.html new file mode 100644 index 000000000000..b63acdcb51fe --- /dev/null +++ b/coverage/analysis/WhamWeights.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - analysis/WhamWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - WhamWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis11WhamWeightsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8analysis11WhamWeightsC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis11WhamWeights16registerKeywordsERNS_8KeywordsE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamWeights.cpp.func.html b/coverage/analysis/WhamWeights.cpp.func.html new file mode 100644 index 000000000000..b3de455e9604 --- /dev/null +++ b/coverage/analysis/WhamWeights.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - analysis/WhamWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - WhamWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8analysis11WhamWeights16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD8analysis11WhamWeightsC1ERKNS_13ActionOptionsE6
_ZN4PLMD8analysis11WhamWeightsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/WhamWeights.cpp.gcov.html b/coverage/analysis/WhamWeights.cpp.gcov.html new file mode 100644 index 000000000000..49003bfd2a4f --- /dev/null +++ b/coverage/analysis/WhamWeights.cpp.gcov.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - analysis/WhamWeights.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysis - WhamWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace analysis {
+      27             : 
+      28             : //+PLUMEDOC REWEIGHTING WHAM_WEIGHTS
+      29             : /*
+      30             : Calculate and output weights for configurations using the weighted histogram analysis method.
+      31             : 
+      32             : This shortcut action allows you to calculate and output weights computed using the weighted histogram
+      33             : analysis technique.  For more detail on how this technique works see \ref REWEIGHT_WHAM
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : The following input can be used to analyze the output from a series of umbrella sampling calculations.
+      38             : The trajectory from each of the simulations run with the different biases should be concatenated into a
+      39             : single trajectory before running the following analysis script on the concatenated trajectory using PLUMED
+      40             : driver.  The umbrella sampling simulations that will be analyzed using the script below applied a harmonic
+      41             : restraint that restrained the torsional angle involving atoms 5, 7, 9 and 15 to particular values.  The script
+      42             : below calculates the reweighting weights for each of the trajectories and then applies the binless WHAM algorithm
+      43             : to determine a weight for each configuration in the concatenated trajectory.
+      44             : 
+      45             : \plumedfile
+      46             : #SETTINGS NREPLICAS=4
+      47             : phi: TORSION ATOMS=5,7,9,15
+      48             : rp: RESTRAINT ARG=phi KAPPA=50.0 ...
+      49             :   AT=@replicas:{
+      50             :         -3.00000000000000000000
+      51             :         -1.45161290322580645168
+      52             :         .09677419354838709664
+      53             :         1.64516129032258064496
+      54             :      }
+      55             : ...
+      56             : 
+      57             : WHAM_WEIGHTS BIAS=rp.bias TEMP=300 FILE=wham-weights
+      58             : \endplumedfile
+      59             : 
+      60             : The script above must be run with multiple replicas using the following command:
+      61             : 
+      62             : \verbatim
+      63             : mpirun -np 4 plumed driver --mf_xtc alltraj.xtc --multi 4
+      64             : \endverbatim
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : class WhamWeights : public ActionShortcut {
+      70             : public:
+      71             :   static void registerKeywords( Keywords& keys );
+      72             :   explicit WhamWeights( const ActionOptions& );
+      73             : };
+      74             : 
+      75             : PLUMED_REGISTER_ACTION(WhamWeights,"WHAM_WEIGHTS")
+      76             : 
+      77           8 : void WhamWeights::registerKeywords( Keywords& keys ) {
+      78           8 :   ActionShortcut::registerKeywords( keys ); keys.remove("LABEL");
+      79          16 :   keys.add("compulsory","BIAS","*.bias","the value of the biases to use when performing WHAM");
+      80          16 :   keys.add("compulsory","TEMP","the temperature at which the simulation was run");
+      81          16 :   keys.add("compulsory","STRIDE","1","the frequency with which the bias should be stored to perform WHAM");
+      82          16 :   keys.add("compulsory","FILE","the file on which to output the WHAM weights");
+      83          16 :   keys.add("optional","FMT","the format to use for the real numbers in the output file");
+      84           8 : }
+      85             : 
+      86           6 : WhamWeights::WhamWeights( const ActionOptions& ao ) :
+      87             :   Action(ao),
+      88           6 :   ActionShortcut(ao)
+      89             : {
+      90             :   // Input for REWEIGHT_WHAM
+      91           6 :   std::string rew_line = getShortcutLabel() + "_weights: REWEIGHT_WHAM";
+      92          18 :   std::string bias; parse("BIAS",bias); rew_line += " ARG=" + bias;
+      93          12 :   std::string temp; parse("TEMP",temp); rew_line += " TEMP=" + temp;
+      94           6 :   readInputLine( rew_line );
+      95             :   // Input for COLLECT_FRAMES
+      96          12 :   std::string col_line = getShortcutLabel() + "_collect: COLLECT_FRAMES LOGWEIGHTS=" + getShortcutLabel() + "_weights";
+      97          12 :   std::string stride; parse("STRIDE",stride); col_line += " STRIDE=" + stride;
+      98           6 :   readInputLine( col_line );
+      99             :   // Input for line to output data
+     100          12 :   std::string out_line="OUTPUT_ANALYSIS_DATA_TO_COLVAR USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_collect";
+     101          12 :   std::string file; parse("FILE",file); out_line += " FILE=" + file;
+     102          12 :   std::string fmt="%f"; parse("FMT",fmt); out_line += " FMT=" + fmt;
+     103           6 :   readInputLine( out_line );
+     104           6 : }
+     105             : 
+     106             : }
+     107             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/index-sort-f.html b/coverage/analysis/index-sort-f.html new file mode 100644 index 000000000000..f9568b76d3e6 --- /dev/null +++ b/coverage/analysis/index-sort-f.html @@ -0,0 +1,334 @@ + + + + + + + + LCOV - plumed test coverage - analysis + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysisHitTotalCoverage
Test:plumed test coverageLines:84395588.3 %
Date:2024-02-22 21:58:45Functions:11015471.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LandmarkStaged.cpp +
10.9%10.9%
+
10.9 %5 / 4625.0 %1 / 4
SelectRandomFrames.cpp +
21.1%21.1%
+
21.1 %4 / 1925.0 %1 / 4
ReadAnalysisFrames.h +
69.2%69.2%
+
69.2 %9 / 1357.1 %4 / 7
PrintDissimilarityMatrix.cpp +
95.5%95.5%
+
95.5 %21 / 2260.0 %3 / 5
OutputPDBFile.cpp +
96.6%96.6%
+
96.6 %28 / 2960.0 %3 / 5
OutputColvarFile.cpp +
97.9%97.9%
+
97.9 %46 / 4760.0 %3 / 5
Average.cpp +
83.9%83.9%
+
83.9 %26 / 3160.0 %6 / 10
WhamHistogram.cpp +
100.0%
+
100.0 %29 / 2966.7 %2 / 3
WhamWeights.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
AnalysisBase.h +
72.7%72.7%
+
72.7 %24 / 3368.4 %13 / 19
ReadDissimilarityMatrix.cpp +
82.3%82.3%
+
82.3 %51 / 6269.2 %9 / 13
ReselectLandmarks.cpp +
100.0%
+
100.0 %16 / 1675.0 %3 / 4
FarthestPointSampling.cpp +
100.0%
+
100.0 %25 / 2575.0 %3 / 4
SelectWithStride.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
EuclideanDissimilarityMatrix.cpp +
83.1%83.1%
+
83.1 %49 / 5975.0 %6 / 8
Committor.cpp +
100.0%
+
100.0 %73 / 7380.0 %4 / 5
AverageVessel.cpp +
91.7%91.7%
+
91.7 %22 / 2483.3 %5 / 6
AnalysisBase.cpp +
96.9%96.9%
+
96.9 %31 / 3283.3 %5 / 6
LandmarkSelectionBase.h +
90.9%90.9%
+
90.9 %10 / 1183.3 %5 / 6
LandmarkSelectionBase.cpp +
100.0%
+
100.0 %41 / 4183.3 %5 / 6
Histogram.cpp +
97.6%97.6%
+
97.6 %202 / 20784.6 %11 / 13
ReadAnalysisFrames.cpp +
94.8%94.8%
+
94.8 %73 / 7787.5 %7 / 8
DataCollectionObject.h +
80.0%80.0%
+
80.0 %4 / 5100.0 %1 / 1
AverageVessel.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
DataCollectionObject.cpp +
100.0%
+
100.0 %21 / 21100.0 %4 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/index-sort-l.html b/coverage/analysis/index-sort-l.html new file mode 100644 index 000000000000..cc5489682667 --- /dev/null +++ b/coverage/analysis/index-sort-l.html @@ -0,0 +1,334 @@ + + + + + + + + LCOV - plumed test coverage - analysis + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysisHitTotalCoverage
Test:plumed test coverageLines:84395588.3 %
Date:2024-02-22 21:58:45Functions:11015471.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LandmarkStaged.cpp +
10.9%10.9%
+
10.9 %5 / 4625.0 %1 / 4
SelectRandomFrames.cpp +
21.1%21.1%
+
21.1 %4 / 1925.0 %1 / 4
ReadAnalysisFrames.h +
69.2%69.2%
+
69.2 %9 / 1357.1 %4 / 7
AnalysisBase.h +
72.7%72.7%
+
72.7 %24 / 3368.4 %13 / 19
DataCollectionObject.h +
80.0%80.0%
+
80.0 %4 / 5100.0 %1 / 1
ReadDissimilarityMatrix.cpp +
82.3%82.3%
+
82.3 %51 / 6269.2 %9 / 13
EuclideanDissimilarityMatrix.cpp +
83.1%83.1%
+
83.1 %49 / 5975.0 %6 / 8
Average.cpp +
83.9%83.9%
+
83.9 %26 / 3160.0 %6 / 10
LandmarkSelectionBase.h +
90.9%90.9%
+
90.9 %10 / 1183.3 %5 / 6
AverageVessel.cpp +
91.7%91.7%
+
91.7 %22 / 2483.3 %5 / 6
ReadAnalysisFrames.cpp +
94.8%94.8%
+
94.8 %73 / 7787.5 %7 / 8
PrintDissimilarityMatrix.cpp +
95.5%95.5%
+
95.5 %21 / 2260.0 %3 / 5
OutputPDBFile.cpp +
96.6%96.6%
+
96.6 %28 / 2960.0 %3 / 5
AnalysisBase.cpp +
96.9%96.9%
+
96.9 %31 / 3283.3 %5 / 6
Histogram.cpp +
97.6%97.6%
+
97.6 %202 / 20784.6 %11 / 13
OutputColvarFile.cpp +
97.9%97.9%
+
97.9 %46 / 4760.0 %3 / 5
AverageVessel.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
SelectWithStride.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
ReselectLandmarks.cpp +
100.0%
+
100.0 %16 / 1675.0 %3 / 4
DataCollectionObject.cpp +
100.0%
+
100.0 %21 / 21100.0 %4 / 4
WhamWeights.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
FarthestPointSampling.cpp +
100.0%
+
100.0 %25 / 2575.0 %3 / 4
WhamHistogram.cpp +
100.0%
+
100.0 %29 / 2966.7 %2 / 3
LandmarkSelectionBase.cpp +
100.0%
+
100.0 %41 / 4183.3 %5 / 6
Committor.cpp +
100.0%
+
100.0 %73 / 7380.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/analysis/index.html b/coverage/analysis/index.html new file mode 100644 index 000000000000..999da63559ae --- /dev/null +++ b/coverage/analysis/index.html @@ -0,0 +1,334 @@ + + + + + + + + LCOV - plumed test coverage - analysis + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - analysisHitTotalCoverage
Test:plumed test coverageLines:84395588.3 %
Date:2024-02-22 21:58:45Functions:11015471.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AnalysisBase.cpp +
96.9%96.9%
+
96.9 %31 / 3283.3 %5 / 6
AnalysisBase.h +
72.7%72.7%
+
72.7 %24 / 3368.4 %13 / 19
Average.cpp +
83.9%83.9%
+
83.9 %26 / 3160.0 %6 / 10
AverageVessel.cpp +
91.7%91.7%
+
91.7 %22 / 2483.3 %5 / 6
AverageVessel.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
Committor.cpp +
100.0%
+
100.0 %73 / 7380.0 %4 / 5
DataCollectionObject.cpp +
100.0%
+
100.0 %21 / 21100.0 %4 / 4
DataCollectionObject.h +
80.0%80.0%
+
80.0 %4 / 5100.0 %1 / 1
EuclideanDissimilarityMatrix.cpp +
83.1%83.1%
+
83.1 %49 / 5975.0 %6 / 8
FarthestPointSampling.cpp +
100.0%
+
100.0 %25 / 2575.0 %3 / 4
Histogram.cpp +
97.6%97.6%
+
97.6 %202 / 20784.6 %11 / 13
LandmarkSelectionBase.cpp +
100.0%
+
100.0 %41 / 4183.3 %5 / 6
LandmarkSelectionBase.h +
90.9%90.9%
+
90.9 %10 / 1183.3 %5 / 6
LandmarkStaged.cpp +
10.9%10.9%
+
10.9 %5 / 4625.0 %1 / 4
OutputColvarFile.cpp +
97.9%97.9%
+
97.9 %46 / 4760.0 %3 / 5
OutputPDBFile.cpp +
96.6%96.6%
+
96.6 %28 / 2960.0 %3 / 5
PrintDissimilarityMatrix.cpp +
95.5%95.5%
+
95.5 %21 / 2260.0 %3 / 5
ReadAnalysisFrames.cpp +
94.8%94.8%
+
94.8 %73 / 7787.5 %7 / 8
ReadAnalysisFrames.h +
69.2%69.2%
+
69.2 %9 / 1357.1 %4 / 7
ReadDissimilarityMatrix.cpp +
82.3%82.3%
+
82.3 %51 / 6269.2 %9 / 13
ReselectLandmarks.cpp +
100.0%
+
100.0 %16 / 1675.0 %3 / 4
SelectRandomFrames.cpp +
21.1%21.1%
+
21.1 %4 / 1925.0 %1 / 4
SelectWithStride.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
WhamHistogram.cpp +
100.0%
+
100.0 %29 / 2966.7 %2 / 3
WhamWeights.cpp +
100.0%
+
100.0 %22 / 2266.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/annfunc/ANN.cpp.func-sort-c.html b/coverage/annfunc/ANN.cpp.func-sort-c.html new file mode 100644 index 000000000000..1a6484ab77b4 --- /dev/null +++ b/coverage/annfunc/ANN.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - annfunc/ANN.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfunc - ANN.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13313797.1 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7annfunc3ANNC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function7annfunc3ANNC1ERKNS_13ActionOptionsE5
_ZN4PLMD8function7annfunc3ANN16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8function7annfunc3ANN30calculate_output_of_each_layerERKSt6vectorIdSaIdEE1638
_ZN4PLMD8function7annfunc3ANN9calculateEv1638
_ZN4PLMD8function7annfunc3ANN9back_propERSt6vectorIS3_IdSaIdEESaIS5_EEi2184
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/annfunc/ANN.cpp.func.html b/coverage/annfunc/ANN.cpp.func.html new file mode 100644 index 000000000000..cf87bbfa7f50 --- /dev/null +++ b/coverage/annfunc/ANN.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - annfunc/ANN.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfunc - ANN.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13313797.1 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7annfunc3ANN16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD8function7annfunc3ANN30calculate_output_of_each_layerERKSt6vectorIdSaIdEE1638
_ZN4PLMD8function7annfunc3ANN9back_propERSt6vectorIS3_IdSaIdEESaIS5_EEi2184
_ZN4PLMD8function7annfunc3ANN9calculateEv1638
_ZN4PLMD8function7annfunc3ANNC1ERKNS_13ActionOptionsE5
_ZN4PLMD8function7annfunc3ANNC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/annfunc/ANN.cpp.gcov.html b/coverage/annfunc/ANN.cpp.gcov.html new file mode 100644 index 000000000000..c56e9088a715 --- /dev/null +++ b/coverage/annfunc/ANN.cpp.gcov.html @@ -0,0 +1,474 @@ + + + + + + + + LCOV - plumed test coverage - annfunc/ANN.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfunc - ANN.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13313797.1 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : MIT License
+       3             : 
+       4             : Copyright (c) 2019 Wei Chen and Andrew Ferguson
+       5             : 
+       6             : Permission is hereby granted, free of charge, to any person obtaining a copy
+       7             : of this software and associated documentation files (the "Software"), to deal
+       8             : in the Software without restriction, including without limitation the rights
+       9             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+      10             : copies of the Software, and to permit persons to whom the Software is
+      11             : furnished to do so, subject to the following conditions:
+      12             : 
+      13             : The above copyright notice and this permission notice shall be included in all
+      14             : copies or substantial portions of the Software.
+      15             : 
+      16             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+      17             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+      18             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+      19             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+      20             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+      21             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+      22             : SOFTWARE.
+      23             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      24             : #include "function/Function.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "cassert"
+      27             : 
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : #include <iostream>
+      31             : // #include <stdio.h>
+      32             : 
+      33             : using namespace std;
+      34             : 
+      35             : // #define DEBUG
+      36             : // #define DEBUG_2
+      37             : // #define DEBUG_3
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace function {
+      41             : namespace annfunc {
+      42             : 
+      43             : //+PLUMEDOC ANNMOD_Function ANN
+      44             : /*
+      45             : Calculates the ANN-function.
+      46             : 
+      47             : This module implements ANN class, which is a subclass of Function class.
+      48             : ANN class takes multi-dimensional arrays as inputs for a fully-connected feedforward neural network
+      49             : with specified neural network weights and generates corresponding outputs.
+      50             : The ANN outputs can be used as collective variables, inputs for other collective variables,
+      51             : or inputs for data analysis tools.
+      52             : 
+      53             : \par Examples
+      54             : 
+      55             : Assume we have an ANN with numbers of nodes being [2, 3, 1], and weights connecting layer 0 and 1 are
+      56             : 
+      57             : [[1,2], [3,4], [5,6]]
+      58             : 
+      59             : weights connecting layer 1 and 2 are
+      60             : 
+      61             : [[7,8,9]]
+      62             : 
+      63             : Bias for layer 1 and 2 are [10, 11, 12] and [13], respectively.
+      64             : 
+      65             : All activation functions are Tanh.
+      66             : 
+      67             : Then if input variables are l_0_out_0, l_0_out_1, the corresponding ANN function object can be defined using
+      68             : following plumed script:
+      69             : 
+      70             : \plumedfile
+      71             : ANN ...
+      72             : LABEL=ann
+      73             : ARG=l_0_out_0,l_0_out_1
+      74             : NUM_LAYERS=3
+      75             : NUM_NODES=2,3,1
+      76             : ACTIVATIONS=Tanh,Tanh
+      77             : WEIGHTS0=1,2,3,4,5,6
+      78             : WEIGHTS1=7,8,9
+      79             : BIASES0=10,11,12
+      80             : BIASES1=13
+      81             : ... ANN
+      82             : \endplumedfile
+      83             : 
+      84             : To access its components, we use "ann.node-0", "ann.node-1", ..., which represents the components of neural network outputs.
+      85             : 
+      86             : 
+      87             : */
+      88             : //+ENDPLUMEDOC
+      89             : 
+      90             : class ANN : public Function
+      91             : {
+      92             : private:
+      93             :   int num_layers;
+      94             :   vector<int> num_nodes;
+      95             :   vector<string> activations;   // activation functions
+      96             :   vector<vector<double> > weights;  // flattened weight arrays
+      97             :   vector<vector<double> > biases;
+      98             :   vector<vector<double> > output_of_each_layer;
+      99             :   vector<vector<double> > input_of_each_layer;
+     100             :   vector<double** > coeff;  // weight matrix arrays, reshaped from "weights"
+     101             : 
+     102             : public:
+     103             :   static void registerKeywords( Keywords& keys );
+     104             :   explicit ANN(const ActionOptions&);
+     105             :   virtual void calculate();
+     106             :   void calculate_output_of_each_layer(const vector<double>& input);
+     107             :   void back_prop(vector<vector<double> >& derivatives_of_each_layer, int index_of_output_component);
+     108             : };
+     109             : 
+     110             : PLUMED_REGISTER_ACTION(ANN,"ANN")
+     111             : 
+     112           7 : void ANN::registerKeywords( Keywords& keys ) {
+     113           7 :   Function::registerKeywords(keys);
+     114          14 :   keys.use("ARG"); keys.use("PERIODIC");
+     115          14 :   keys.add("compulsory", "NUM_LAYERS", "number of layers of the neural network");
+     116          14 :   keys.add("compulsory", "NUM_NODES", "numbers of nodes in each layer of the neural network");
+     117          14 :   keys.add("compulsory", "ACTIVATIONS", "activation functions for the neural network");
+     118          14 :   keys.add("numbered", "WEIGHTS", "flattened weight arrays connecting adjacent layers, "
+     119             :            "WEIGHTS0 represents flattened weight array connecting layer 0 and layer 1, "
+     120             :            "WEIGHTS1 represents flattened weight array connecting layer 1 and layer 2, ...");
+     121          14 :   keys.add("numbered", "BIASES", "bias array for each layer of the neural network, "
+     122             :            "BIASES0 represents bias array for layer 1, BIASES1 represents bias array for layer 2, ...");
+     123             :   // since v2.2 plumed requires all components be registered
+     124          14 :   keys.addOutputComponent("node", "default", "components of ANN outputs");
+     125           7 : }
+     126             : 
+     127           5 : ANN::ANN(const ActionOptions&ao):
+     128             :   Action(ao),
+     129           5 :   Function(ao)
+     130             : {
+     131           5 :   parse("NUM_LAYERS", num_layers);
+     132           5 :   num_nodes = vector<int>(num_layers);
+     133          10 :   activations = vector<string>(num_layers - 1);
+     134          10 :   output_of_each_layer = vector<vector<double> >(num_layers);
+     135          10 :   input_of_each_layer = vector<vector<double> >(num_layers);
+     136           5 :   coeff = vector<double** >(num_layers - 1);
+     137           5 :   parseVector("NUM_NODES", num_nodes);
+     138           5 :   parseVector("ACTIVATIONS", activations);
+     139           5 :   log.printf("\nactivations = ");
+     140          15 :   for (const auto & ss: activations) {
+     141          10 :     log.printf("%s, ", ss.c_str());
+     142             :   }
+     143           5 :   log.printf("\nnum_nodes = ");
+     144          20 :   for (auto ss: num_nodes) {
+     145          15 :     log.printf("%d, ", ss);
+     146             :   }
+     147             :   vector<double> temp_single_coeff, temp_single_bias;
+     148          10 :   for (int ii = 0; ; ii ++) {
+     149             :     // parse coeff
+     150          30 :     if( !parseNumberedVector("WEIGHTS", ii, temp_single_coeff) ) {
+     151           5 :       temp_single_coeff=weights[ii-1];
+     152             :       break;
+     153             :     }
+     154          10 :     weights.push_back(temp_single_coeff);
+     155          10 :     log.printf("size of temp_single_coeff = %lu\n", temp_single_coeff.size());
+     156          10 :     log.printf("size of weights = %lu\n", weights.size());
+     157             :     // parse bias
+     158          20 :     if( !parseNumberedVector("BIASES", ii, temp_single_bias) ) {
+     159           0 :       temp_single_bias=biases[ii-1];
+     160             :     }
+     161          10 :     biases.push_back(temp_single_bias);
+     162          10 :     log.printf("size of temp_single_bias = %lu\n", temp_single_bias.size());
+     163          10 :     log.printf("size of biases = %lu\n", biases.size());
+     164             :   }
+     165             : 
+     166           5 :   if(getNumberOfArguments() != num_nodes[0]) {
+     167           0 :     error("Number of arguments is wrong");
+     168             :   }
+     169             : 
+     170           5 :   auto temp_coeff = weights;
+     171          15 :   for (int ii = 0; ii < num_layers - 1; ii ++) {
+     172             :     int num_of_rows, num_of_cols; // num of rows/cols for the coeff matrix of this connection
+     173          10 :     num_of_rows = num_nodes[ii + 1];
+     174          10 :     num_of_cols = num_nodes[ii];
+     175             :     assert (num_of_rows * num_of_cols == temp_coeff[ii].size()); // check whether the size matches
+     176             :     // create a 2d array to hold coefficients
+     177          10 :     coeff[ii] = new double*[num_of_rows];
+     178          32 :     for (int kk = 0; kk < num_of_rows; kk ++) {
+     179          22 :       coeff[ii][kk] = new double[num_of_cols];
+     180             :     }
+     181          61 :     for (int jj = 0; jj < temp_coeff[ii].size(); jj ++) {
+     182          51 :       coeff[ii][jj / num_of_cols][jj % num_of_cols] = temp_coeff[ii][jj];
+     183             :     }
+     184             :   }
+     185             :   // check coeff
+     186          15 :   for (int ii = 0; ii < num_layers - 1; ii ++) {
+     187          10 :     log.printf("coeff %d = \n", ii);
+     188          32 :     for (int jj = 0; jj < num_nodes[ii + 1]; jj ++) {
+     189          73 :       for (int kk = 0; kk < num_nodes[ii]; kk ++) {
+     190          51 :         log.printf("%f ", coeff[ii][jj][kk]);
+     191             :       }
+     192          22 :       log.printf("\n");
+     193             :     }
+     194             :   }
+     195             :   // check bias
+     196          15 :   for (int ii = 0; ii < num_layers - 1; ii ++) {
+     197          10 :     log.printf("bias %d = \n", ii);
+     198          32 :     for (int jj = 0; jj < num_nodes[ii + 1]; jj ++) {
+     199          22 :       log.printf("%f ", biases[ii][jj]);
+     200             :     }
+     201          10 :     log.printf("\n");
+     202             :   }
+     203           5 :   log.printf("initialization ended\n");
+     204             :   // create components
+     205          12 :   for (int ii = 0; ii < num_nodes[num_layers - 1]; ii ++) {
+     206           7 :     string name_of_this_component = "node-" + to_string(ii);
+     207           7 :     addComponentWithDerivatives(name_of_this_component);
+     208           7 :     componentIsNotPeriodic(name_of_this_component);
+     209             :   }
+     210           5 :   checkRead();
+     211          10 : }
+     212             : 
+     213        1638 : void ANN::calculate_output_of_each_layer(const vector<double>& input) {
+     214             :   // first layer
+     215        1638 :   output_of_each_layer[0] = input;
+     216             :   // following layers
+     217        4914 :   for(int ii = 1; ii < num_nodes.size(); ii ++) {
+     218        3276 :     output_of_each_layer[ii].resize(num_nodes[ii]);
+     219        3276 :     input_of_each_layer[ii].resize(num_nodes[ii]);
+     220             :     // first calculate input
+     221       10374 :     for (int jj = 0; jj < num_nodes[ii]; jj ++) {
+     222        7098 :       input_of_each_layer[ii][jj] = biases[ii - 1][jj];  // add bias term
+     223       23478 :       for (int kk = 0; kk < num_nodes[ii - 1]; kk ++) {
+     224       16380 :         input_of_each_layer[ii][jj] += coeff[ii - 1][jj][kk] * output_of_each_layer[ii - 1][kk];
+     225             :       }
+     226             :     }
+     227             :     // then get output
+     228        3276 :     if (activations[ii - 1] == string("Linear")) {
+     229        1092 :       for(int jj = 0; jj < num_nodes[ii]; jj ++) {
+     230         546 :         output_of_each_layer[ii][jj] = input_of_each_layer[ii][jj];
+     231             :       }
+     232             :     }
+     233        2730 :     else if (activations[ii - 1] == string("Tanh")) {
+     234        7644 :       for(int jj = 0; jj < num_nodes[ii]; jj ++) {
+     235        5460 :         output_of_each_layer[ii][jj] = tanh(input_of_each_layer[ii][jj]);
+     236             :       }
+     237             :     }
+     238         546 :     else if (activations[ii - 1] == string("Circular")) {
+     239             :       assert (num_nodes[ii] % 2 == 0);
+     240        1092 :       for(int jj = 0; jj < num_nodes[ii] / 2; jj ++) {
+     241         546 :         double radius = sqrt(input_of_each_layer[ii][2 * jj] * input_of_each_layer[ii][2 * jj]
+     242         546 :                              +input_of_each_layer[ii][2 * jj + 1] * input_of_each_layer[ii][2 * jj + 1]);
+     243         546 :         output_of_each_layer[ii][2 * jj] = input_of_each_layer[ii][2 * jj] / radius;
+     244         546 :         output_of_each_layer[ii][2 * jj + 1] = input_of_each_layer[ii][2 * jj + 1] / radius;
+     245             : 
+     246             :       }
+     247             :     }
+     248             :     else {
+     249             :       printf("layer type not found!\n\n");
+     250           0 :       return;
+     251             :     }
+     252             :   }
+     253             : #ifdef DEBUG_2
+     254             :   // print out the result for debugging
+     255             :   printf("output_of_each_layer = \n");
+     256             :   // for (int ii = num_layers - 1; ii < num_layers; ii ++) {
+     257             :   for (int ii = 0; ii < num_layers; ii ++) {
+     258             :     printf("layer[%d]: ", ii);
+     259             :     if (ii != 0) {
+     260             :       cout << activations[ii - 1] << "\t";
+     261             :     }
+     262             :     else {
+     263             :       cout << "input \t" ;
+     264             :     }
+     265             :     for (int jj = 0; jj < num_nodes[ii]; jj ++) {
+     266             :       printf("%lf\t", output_of_each_layer[ii][jj]);
+     267             :     }
+     268             :     printf("\n");
+     269             :   }
+     270             :   printf("\n");
+     271             : #endif
+     272             :   return;
+     273             : }
+     274             : 
+     275        2184 : void ANN::back_prop(vector<vector<double> >& derivatives_of_each_layer, int index_of_output_component) {
+     276        2184 :   derivatives_of_each_layer = output_of_each_layer;  // the data structure and size should be the same, so I simply deep copy it
+     277             :   // first calculate derivatives for bottleneck layer
+     278        5460 :   for (int ii = 0; ii < num_nodes[num_nodes.size() - 1]; ii ++ ) {
+     279        3276 :     if (ii == index_of_output_component) {
+     280        2184 :       derivatives_of_each_layer[num_nodes.size() - 1][ii] = 1;
+     281             :     }
+     282             :     else {
+     283        1092 :       derivatives_of_each_layer[num_nodes.size() - 1][ii] = 0;
+     284             :     }
+     285             :   }
+     286             :   // the use back propagation to calculate derivatives for previous layers
+     287        6552 :   for (int jj = num_nodes.size() - 2; jj >= 0; jj --) {
+     288        4368 :     if (activations[jj] == string("Circular")) {
+     289             :       vector<double> temp_derivative_of_input_for_this_layer;
+     290        1092 :       temp_derivative_of_input_for_this_layer.resize(num_nodes[jj + 1]);
+     291             : #ifdef DEBUG
+     292             :       assert (num_nodes[jj + 1] % 2 == 0);
+     293             : #endif
+     294             :       // first calculate the derivative of input from derivative of output of this circular layer
+     295        2184 :       for(int ii = 0; ii < num_nodes[jj + 1] / 2; ii ++) {
+     296             :         // printf("size of input_of_each_layer[%d] = %d\n",jj,  input_of_each_layer[jj].size());
+     297        1092 :         double x_p = input_of_each_layer[jj + 1][2 * ii];
+     298        1092 :         double x_q = input_of_each_layer[jj + 1][2 * ii + 1];
+     299        1092 :         double radius = sqrt(x_p * x_p + x_q * x_q);
+     300        1092 :         temp_derivative_of_input_for_this_layer[2 * ii] = x_q / (radius * radius * radius)
+     301        1092 :             * (x_q * derivatives_of_each_layer[jj + 1][2 * ii]
+     302        1092 :                - x_p * derivatives_of_each_layer[jj + 1][2 * ii + 1]);
+     303        1092 :         temp_derivative_of_input_for_this_layer[2 * ii + 1] = x_p / (radius * radius * radius)
+     304        1092 :             * (x_p * derivatives_of_each_layer[jj + 1][2 * ii + 1]
+     305        1092 :                - x_q * derivatives_of_each_layer[jj + 1][2 * ii]);
+     306             :       }
+     307             : #ifdef DEBUG
+     308             :       for (int mm = 0; mm < num_nodes[jj + 1]; mm ++) {
+     309             :         printf("temp_derivative_of_input_for_this_layer[%d] = %lf\n", mm, temp_derivative_of_input_for_this_layer[mm]);
+     310             :         printf("derivatives_of_each_layer[%d + 1][%d] = %lf\n", jj, mm, derivatives_of_each_layer[jj + 1][mm]);
+     311             :       }
+     312             : #endif
+     313             :       // the calculate the derivative of output of layer jj, from derivative of input of layer (jj + 1)
+     314        4368 :       for (int mm = 0; mm < num_nodes[jj]; mm ++) {
+     315        3276 :         derivatives_of_each_layer[jj][mm] = 0;
+     316        9828 :         for (int kk = 0; kk < num_nodes[jj + 1]; kk ++) {
+     317        6552 :           derivatives_of_each_layer[jj][mm] += coeff[jj][kk][mm] \
+     318        6552 :                                                * temp_derivative_of_input_for_this_layer[kk];
+     319             : #ifdef DEBUG
+     320             :           printf("derivatives_of_each_layer[%d][%d] = %lf\n", jj, mm, derivatives_of_each_layer[jj][mm]);
+     321             :           printf("coeff[%d][%d][%d] = %lf\n", jj, kk, mm, coeff[jj][kk][mm]);
+     322             : #endif
+     323             :         }
+     324             :       }
+     325             :       // TODO: should be fine, pass all tests, although there seems to be some problems here previously
+     326             :     }
+     327             :     else {
+     328       10920 :       for (int mm = 0; mm < num_nodes[jj]; mm ++) {
+     329        7644 :         derivatives_of_each_layer[jj][mm] = 0;
+     330       24024 :         for (int kk = 0; kk < num_nodes[jj + 1]; kk ++) {
+     331       16380 :           if (activations[jj] == string("Tanh")) {
+     332             :             // printf("tanh\n");
+     333       14742 :             derivatives_of_each_layer[jj][mm] += derivatives_of_each_layer[jj + 1][kk] \
+     334       14742 :                                                  * coeff[jj][kk][mm] \
+     335       14742 :                                                  * (1 - output_of_each_layer[jj + 1][kk] * output_of_each_layer[jj + 1][kk]);
+     336             :           }
+     337        1638 :           else if (activations[jj] == string("Linear")) {
+     338             :             // printf("linear\n");
+     339        1638 :             derivatives_of_each_layer[jj][mm] += derivatives_of_each_layer[jj + 1][kk] \
+     340        1638 :                                                  * coeff[jj][kk][mm] \
+     341        1638 :                                                  * 1;
+     342             :           }
+     343             :           else {
+     344             :             printf("layer type not found!\n\n");
+     345           0 :             return;
+     346             :           }
+     347             :         }
+     348             :       }
+     349             :     }
+     350             :   }
+     351             : #ifdef DEBUG
+     352             :   // print out the result for debugging
+     353             :   printf("derivatives_of_each_layer = \n");
+     354             :   for (int ii = 0; ii < num_layers; ii ++) {
+     355             :     printf("layer[%d]: ", ii);
+     356             :     for (int jj = 0; jj < num_nodes[ii]; jj ++) {
+     357             :       printf("%lf\t", derivatives_of_each_layer[ii][jj]);
+     358             :     }
+     359             :     printf("\n");
+     360             :   }
+     361             :   printf("\n");
+     362             : #endif
+     363             :   return;
+     364             : }
+     365             : 
+     366        1638 : void ANN::calculate() {
+     367             : 
+     368        1638 :   vector<double> input_layer_data(num_nodes[0]);
+     369        4914 :   for (int ii = 0; ii < num_nodes[0]; ii ++) {
+     370        3276 :     input_layer_data[ii] = getArgument(ii);
+     371             :   }
+     372             : 
+     373        1638 :   calculate_output_of_each_layer(input_layer_data);
+     374             :   vector<vector<double> > derivatives_of_each_layer;
+     375             : 
+     376        3822 :   for (int ii = 0; ii < num_nodes[num_layers - 1]; ii ++) {
+     377        2184 :     back_prop(derivatives_of_each_layer, ii);
+     378        2184 :     string name_of_this_component = "node-" + to_string(ii);
+     379        2184 :     Value* value_new=getPntrToComponent(name_of_this_component);
+     380        2184 :     value_new -> set(output_of_each_layer[num_layers - 1][ii]);
+     381        6552 :     for (int jj = 0; jj < num_nodes[0]; jj ++) {
+     382        4368 :       value_new -> setDerivative(jj, derivatives_of_each_layer[0][jj]);  // TODO: setDerivative or addDerivative?
+     383             :     }
+     384             : #ifdef DEBUG_3
+     385             :     printf("derivatives = ");
+     386             :     for (int jj = 0; jj < num_nodes[0]; jj ++) {
+     387             :       printf("%f ", value_new -> getDerivative(jj));
+     388             :     }
+     389             :     printf("\n");
+     390             : #endif
+     391             :   }
+     392             : 
+     393        3276 : }
+     394             : 
+     395             : }
+     396             : }
+     397             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/annfunc/index-sort-f.html b/coverage/annfunc/index-sort-f.html new file mode 100644 index 000000000000..ada44e7a837d --- /dev/null +++ b/coverage/annfunc/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - annfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfuncHitTotalCoverage
Test:plumed test coverageLines:13313797.1 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ANN.cpp +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/annfunc/index-sort-l.html b/coverage/annfunc/index-sort-l.html new file mode 100644 index 000000000000..dd77c4664c37 --- /dev/null +++ b/coverage/annfunc/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - annfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfuncHitTotalCoverage
Test:plumed test coverageLines:13313797.1 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ANN.cpp +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/annfunc/index.html b/coverage/annfunc/index.html new file mode 100644 index 000000000000..f4e0b25394e6 --- /dev/null +++ b/coverage/annfunc/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - annfunc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - annfuncHitTotalCoverage
Test:plumed test coverageLines:13313797.1 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ANN.cpp +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ABMD.cpp.func-sort-c.html b/coverage/bias/ABMD.cpp.func-sort-c.html new file mode 100644 index 000000000000..37e5687280a7 --- /dev/null +++ b/coverage/bias/ABMD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ABMD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ABMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6262100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4ABMDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias4ABMDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias4ABMD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias4ABMD9calculateEv5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ABMD.cpp.func.html b/coverage/bias/ABMD.cpp.func.html new file mode 100644 index 000000000000..e79623b75625 --- /dev/null +++ b/coverage/bias/ABMD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ABMD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ABMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6262100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4ABMD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias4ABMD9calculateEv5
_ZN4PLMD4bias4ABMDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias4ABMDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ABMD.cpp.gcov.html b/coverage/bias/ABMD.cpp.gcov.html new file mode 100644 index 000000000000..9ffb939eaa86 --- /dev/null +++ b/coverage/bias/ABMD.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + + LCOV - plumed test coverage - bias/ABMD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ABMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6262100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : #include "tools/Random.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include <ctime>
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace bias {
+      29             : 
+      30             : //+PLUMEDOC BIAS ABMD
+      31             : /*
+      32             : Adds a ratchet-and-pawl like restraint on one or more variables.
+      33             : 
+      34             : This action can be used to evolve a system towards a target value in
+      35             : CV space using an harmonic potential moving with the thermal fluctuations of the CV
+      36             : \cite ballone \cite provasi10abmd \cite camilloni11abmd. The biasing potential in this
+      37             : method is as follows:
+      38             : 
+      39             : \f$
+      40             : V(\rho(t)) = \left \{ \begin{array}{ll} \frac{K}{2}\left(\rho(t)-\rho_m(t)\right)^2, &\rho(t)>\rho_m(t)\\
+      41             :               0, & \rho(t)\le\rho_m(t), \end{array} \right .
+      42             : \f$
+      43             : 
+      44             : 
+      45             : where
+      46             : 
+      47             : 
+      48             : \f$
+      49             : \rho(t)=\left(CV(t)-TO\right)^2
+      50             : \f$
+      51             : 
+      52             : 
+      53             : and
+      54             : 
+      55             : 
+      56             : \f$
+      57             : \rho_m(t)=\min_{0\le\tau\le t}\rho(\tau)+\eta(t)
+      58             : \f$.
+      59             : 
+      60             : The method is based on the introduction of a biasing potential which is zero when
+      61             : the system is moving towards the desired arrival point and which damps the
+      62             : fluctuations when the system attempts to move in the opposite direction. As in the
+      63             : case of the ratchet and pawl system, propelled by thermal motion of the solvent
+      64             : molecules, the biasing potential does not exert work on the system. \f$\eta(t)\f$ is
+      65             : an additional white noise acting on the minimum position of the bias.
+      66             : 
+      67             : \par Examples
+      68             : 
+      69             : The following input sets up two biases, one on the distance between atoms 3 and 5
+      70             : and another on the distance between atoms 2 and 4. The two target values are defined
+      71             : using TO and the two strength using KAPPA. The total energy of the bias is printed.
+      72             : \plumedfile
+      73             : DISTANCE ATOMS=3,5 LABEL=d1
+      74             : DISTANCE ATOMS=2,4 LABEL=d2
+      75             : ABMD ARG=d1,d2 TO=1.0,1.5 KAPPA=5.0,5.0 LABEL=abmd
+      76             : PRINT ARG=abmd.bias,abmd.d1_min,abmd.d2_min
+      77             : \endplumedfile
+      78             : 
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : 
+      82             : class ABMD : public Bias {
+      83             :   std::vector<double> to;
+      84             :   std::vector<double> min;
+      85             :   std::vector<double> kappa;
+      86             :   std::vector<double> temp;
+      87             :   std::vector<int> seed;
+      88             :   std::vector<Random> random;
+      89             : public:
+      90             :   explicit ABMD(const ActionOptions&);
+      91             :   void calculate() override;
+      92             :   static void registerKeywords(Keywords& keys);
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(ABMD,"ABMD")
+      96             : 
+      97           3 : void ABMD::registerKeywords(Keywords& keys) {
+      98           3 :   Bias::registerKeywords(keys);
+      99           3 :   keys.use("ARG");
+     100           6 :   keys.add("compulsory","TO","The array of target values");
+     101           6 :   keys.add("compulsory","KAPPA","The array of force constants.");
+     102           6 :   keys.add("optional","MIN","Array of starting values for the bias (set rho_m(t), otherwise it is set using the current value of ARG)");
+     103           6 :   keys.add("optional","NOISE","Array of white noise intensities (add a temperature to the ABMD)");
+     104           6 :   keys.add("optional","SEED","Array of seeds for the white noise (add a temperature to the ABMD)");
+     105           6 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+     106           6 :   keys.addOutputComponent("_min","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     107             :                           " These quantities will be named with the arguments of the bias followed by "
+     108             :                           "the character string _min. These quantities tell the user the minimum value assumed by rho_m(t).");
+     109           3 : }
+     110             : 
+     111           1 : ABMD::ABMD(const ActionOptions&ao):
+     112             :   PLUMED_BIAS_INIT(ao),
+     113           2 :   to(getNumberOfArguments(),0.0),
+     114           1 :   min(getNumberOfArguments(),-1.0),
+     115           1 :   kappa(getNumberOfArguments(),0.0),
+     116           1 :   temp(getNumberOfArguments(),0.0),
+     117           1 :   seed(getNumberOfArguments(),std::time(0)),
+     118           2 :   random(getNumberOfArguments())
+     119             : {
+     120             :   // Note : parseVector will check that number of arguments is correct
+     121           1 :   parseVector("KAPPA",kappa);
+     122           2 :   parseVector("MIN",min);
+     123           1 :   if(min.size()==0) min.assign(getNumberOfArguments(),-1.0);
+     124           1 :   if(min.size()!=getNumberOfArguments()) error("MIN array should have the same size as ARG array");
+     125           1 :   parseVector("NOISE",temp);
+     126           1 :   parseVector("SEED",seed);
+     127           1 :   parseVector("TO",to);
+     128           1 :   checkRead();
+     129             : 
+     130           1 :   log.printf("  min");
+     131           2 :   for(unsigned i=0; i<min.size(); i++) log.printf(" %f",min[i]);
+     132           1 :   log.printf("\n");
+     133           1 :   log.printf("  to");
+     134           2 :   for(unsigned i=0; i<to.size(); i++) log.printf(" %f",to[i]);
+     135           1 :   log.printf("\n");
+     136           1 :   log.printf("  with force constant");
+     137           2 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     138           1 :   log.printf("\n");
+     139             : 
+     140           2 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     141           1 :     std::string str_min=getPntrToArgument(i)->getName()+"_min";
+     142           2 :     addComponent(str_min); componentIsNotPeriodic(str_min);
+     143           1 :     if(min[i]!=-1.0) getPntrToComponent(str_min)->set(min[i]);
+     144             :   }
+     145           2 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {random[i].setSeed(-seed[i]);}
+     146           2 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     147           1 : }
+     148             : 
+     149             : 
+     150           5 : void ABMD::calculate() {
+     151             :   double ene=0.0;
+     152             :   double totf2=0.0;
+     153          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     154           5 :     const double cv=difference(i,to[i],getArgument(i));
+     155           5 :     const double cv2=cv*cv;
+     156           5 :     const double k=kappa[i];
+     157             :     double noise=0.;
+     158           5 :     double diff=temp[i];
+     159           5 :     if(diff>0) {
+     160           5 :       noise = 2.*random[i].Gaussian()*diff;
+     161           5 :       if(cv2<=diff) { diff=0.; temp[i]=0.; }
+     162             :     }
+     163             : 
+     164             :     // min < 0 means that the variable has not been used in the input file, so the current position of the CV is used
+     165             :     // cv2 < min means that the collective variable is nearer to the target value than at any other previous time so
+     166             :     // min is set to the CV value
+     167           5 :     if(min[i]<0.||cv2<min[i]) {
+     168           1 :       min[i] = cv2;
+     169             :     } else {
+     170             :       // otherwise a noise is added to the minimum value
+     171           4 :       min[i] += noise;
+     172           4 :       const double f = -2.*k*(cv2-min[i])*cv;
+     173           4 :       setOutputForce(i,f);
+     174           4 :       ene += 0.5*k*(cv2-min[i])*(cv2-min[i]);
+     175           4 :       totf2+=f*f;
+     176             :     }
+     177           5 :     getPntrToComponent(i+1)->set(min[i]);
+     178             :   }
+     179           5 :   setBias(ene);
+     180           5 :   getPntrToComponent("force2")->set(totf2);
+     181           5 : }
+     182             : 
+     183             : }
+     184             : }
+     185             : 
+     186             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.cpp.func-sort-c.html b/coverage/bias/Bias.cpp.func-sort-c.html new file mode 100644 index 000000000000..8fc941c7e356 --- /dev/null +++ b/coverage/bias/Bias.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/Bias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4BiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias4BiasC2ERKNS_13ActionOptionsE683
_ZN4PLMD4bias4Bias16registerKeywordsERNS_8KeywordsE734
_ZN4PLMD4bias4Bias5applyEv78589
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.cpp.func.html b/coverage/bias/Bias.cpp.func.html new file mode 100644 index 000000000000..c78341ed3825 --- /dev/null +++ b/coverage/bias/Bias.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/Bias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias16registerKeywordsERNS_8KeywordsE734
_ZN4PLMD4bias4Bias5applyEv78589
_ZN4PLMD4bias4BiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias4BiasC2ERKNS_13ActionOptionsE683
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.cpp.gcov.html b/coverage/bias/Bias.cpp.gcov.html new file mode 100644 index 000000000000..a4a0715b54de --- /dev/null +++ b/coverage/bias/Bias.cpp.gcov.html @@ -0,0 +1,170 @@ + + + + + + + + LCOV - plumed test coverage - bias/Bias.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : 
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace bias {
+      27             : 
+      28         683 : Bias::Bias(const ActionOptions&ao):
+      29             :   Action(ao),
+      30             :   ActionPilot(ao),
+      31             :   ActionWithValue(ao),
+      32             :   ActionWithArguments(ao),
+      33         683 :   outputForces(getNumberOfArguments(),0.0)
+      34             : {
+      35        1360 :   addComponentWithDerivatives("bias");
+      36         680 :   componentIsNotPeriodic("bias");
+      37         680 :   valueBias=getPntrToComponent("bias");
+      38             : 
+      39         680 :   if(getStride()>1) {
+      40           3 :     log<<"  multiple time step "<<getStride()<<" ";
+      41           6 :     log<<cite("Ferrarotti, Bottaro, Perez-Villa, and Bussi, J. Chem. Theory Comput. 11, 139 (2015)")<<"\n";
+      42             :   }
+      43        4498 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      44        3818 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+      45             :   }
+      46             : 
+      47         680 :   ActionWithValue::turnOnDerivatives();
+      48         683 : }
+      49             : 
+      50         734 : void Bias::registerKeywords( Keywords& keys ) {
+      51         734 :   Action::registerKeywords(keys);
+      52         734 :   ActionPilot::registerKeywords(keys);
+      53         734 :   ActionWithValue::registerKeywords(keys);
+      54         734 :   ActionWithArguments::registerKeywords(keys);
+      55        1468 :   keys.add("hidden","STRIDE","the frequency with which the forces due to the bias should be calculated.  This can be used to correctly set up multistep algorithms");
+      56         734 :   componentsAreNotOptional(keys);
+      57        1468 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+      58         734 : }
+      59             : 
+      60       78589 : void Bias::apply() {
+      61       78589 :   const unsigned noa=getNumberOfArguments();
+      62       78589 :   const unsigned ncp=getNumberOfComponents();
+      63             : 
+      64       78589 :   if(onStep()) {
+      65       78589 :     double gstr = static_cast<double>(getStride());
+      66      224529 :     for(unsigned i=0; i<noa; ++i) {
+      67      145940 :       getPntrToArgument(i)->addForce(gstr*outputForces[i]);
+      68             :     }
+      69             :   }
+      70             : 
+      71       78589 :   f.assign(noa,0.0);
+      72       78589 :   forces.resize(noa);
+      73             : 
+      74             :   bool at_least_one_forced=false;
+      75      398308 :   for(unsigned i=0; i<ncp; ++i) {
+      76      319719 :     if(getPntrToComponent(i)->applyForce(forces)) {
+      77             :       at_least_one_forced=true;
+      78         913 :       for(unsigned j=0; j<noa; j++) f[j]+=forces[j];
+      79             :     }
+      80             :   }
+      81             : 
+      82       78589 :   if(at_least_one_forced && !onStep()) error("you are biasing a bias with an inconsistent STRIDE");
+      83             : 
+      84       79430 :   if(at_least_one_forced) for(unsigned i=0; i<noa; ++i) {
+      85         559 :       getPntrToArgument(i)->addForce(f[i]);
+      86             :     }
+      87             : 
+      88       78589 : }
+      89             : 
+      90             : }
+      91             : }
+      92             : 
+      93             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.h.func-sort-c.html b/coverage/bias/Bias.h.func-sort-c.html new file mode 100644 index 000000000000..f61cc5f7b60a --- /dev/null +++ b/coverage/bias/Bias.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - bias/Bias.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias22getNumberOfDerivativesEv796
_ZN4PLMD4bias4Bias7setBiasEd78336
_ZN4PLMD4bias4Bias14setOutputForceEid144949
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.h.func.html b/coverage/bias/Bias.h.func.html new file mode 100644 index 000000000000..8649e988b1cc --- /dev/null +++ b/coverage/bias/Bias.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - bias/Bias.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias4Bias14setOutputForceEid144949
_ZN4PLMD4bias4Bias22getNumberOfDerivativesEv796
_ZN4PLMD4bias4Bias7setBiasEd78336
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Bias.h.gcov.html b/coverage/bias/Bias.h.gcov.html new file mode 100644 index 000000000000..34419868594a --- /dev/null +++ b/coverage/bias/Bias.h.gcov.html @@ -0,0 +1,160 @@ + + + + + + + + LCOV - plumed test coverage - bias/Bias.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Bias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_bias_Bias_h
+      23             : #define __PLUMED_bias_Bias_h
+      24             : 
+      25             : #include "core/ActionPilot.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : #include "core/ActionWithArguments.h"
+      28             : 
+      29             : #define PLUMED_BIAS_INIT(ao) Action(ao),Bias(ao)
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace bias {
+      33             : 
+      34             : /**
+      35             : \ingroup INHERIT
+      36             : This is the abstract base class to use for implementing new simulation biases, within it there is
+      37             : information as to how to go about implementing a new bias.
+      38             : */
+      39             : 
+      40             : class Bias :
+      41             :   public ActionPilot,
+      42             :   public ActionWithValue,
+      43             :   public ActionWithArguments
+      44             : {
+      45             : /// the vector of the forces
+      46             :   std::vector<double> outputForces;
+      47             : /// the pointer to the bias component
+      48             :   Value *valueBias;
+      49             :   std::vector<double> f;
+      50             :   std::vector<double> forces;
+      51             : protected:
+      52             : /// set the force from the bias on argument i, this automatically set the partial derivative of the bias with respect to i to -f
+      53             :   void setOutputForce(int i,double f);
+      54             : /// set the value of the bias
+      55             :   void setBias(double bias);
+      56             : public:
+      57             :   static void registerKeywords(Keywords&);
+      58             :   explicit Bias(const ActionOptions&ao);
+      59             :   void apply() override;
+      60             :   unsigned getNumberOfDerivatives() override;
+      61             : };
+      62             : 
+      63             : inline
+      64      144949 : void Bias::setOutputForce(int i,double f) {
+      65      144979 :   outputForces[i]=f;
+      66      144979 :   valueBias->addDerivative(i,-f);
+      67      144949 : }
+      68             : 
+      69             : inline
+      70       78336 : void Bias::setBias(double bias) {
+      71       78336 :   valueBias->set(bias);
+      72       78336 : }
+      73             : 
+      74             : inline
+      75         796 : unsigned Bias::getNumberOfDerivatives() {
+      76         796 :   return getNumberOfArguments();
+      77             : }
+      78             : 
+      79             : }
+      80             : }
+      81             : 
+      82             : #endif
+      83             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/BiasValue.cpp.func-sort-c.html b/coverage/bias/BiasValue.cpp.func-sort-c.html new file mode 100644 index 000000000000..53d1b703aea0 --- /dev/null +++ b/coverage/bias/BiasValue.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/BiasValue.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - BiasValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9BiasValueC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias9BiasValueC1ERKNS_13ActionOptionsE33
_ZN4PLMD4bias9BiasValue16registerKeywordsERNS_8KeywordsE35
_ZN4PLMD4bias9BiasValue9calculateEv473
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/BiasValue.cpp.func.html b/coverage/bias/BiasValue.cpp.func.html new file mode 100644 index 000000000000..2cd4405730fe --- /dev/null +++ b/coverage/bias/BiasValue.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/BiasValue.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - BiasValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9BiasValue16registerKeywordsERNS_8KeywordsE35
_ZN4PLMD4bias9BiasValue9calculateEv473
_ZN4PLMD4bias9BiasValueC1ERKNS_13ActionOptionsE33
_ZN4PLMD4bias9BiasValueC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/BiasValue.cpp.gcov.html b/coverage/bias/BiasValue.cpp.gcov.html new file mode 100644 index 000000000000..082f0d3ed7f7 --- /dev/null +++ b/coverage/bias/BiasValue.cpp.gcov.html @@ -0,0 +1,194 @@ + + + + + + + + LCOV - plumed test coverage - bias/BiasValue.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - BiasValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace bias {
+      27             : 
+      28             : //+PLUMEDOC BIAS BIASVALUE
+      29             : /*
+      30             : Takes the value of one variable and use it as a bias
+      31             : 
+      32             : This is the simplest possible bias: the bias potential is equal to a collective variable.
+      33             : It is useful to create custom biasing potential, e.g. applying a function (see \ref Function)
+      34             : to some collective variable then using the value of this function directly as a bias.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The following input tells plumed to use the value of the distance between atoms 3 and 5
+      39             : and the value of the distance between atoms 2 and 4 as biases.
+      40             : It then tells plumed to print the energy of the restraint
+      41             : \plumedfile
+      42             : DISTANCE ATOMS=3,5 LABEL=d1
+      43             : DISTANCE ATOMS=3,6 LABEL=d2
+      44             : BIASVALUE ARG=d1,d2 LABEL=b
+      45             : PRINT ARG=d1,d2,b.d1_bias,b.d2_bias
+      46             : \endplumedfile
+      47             : 
+      48             : Another thing one can do is asking one system to follow
+      49             : a circle in sin/cos according a  time dependence
+      50             : 
+      51             : \plumedfile
+      52             : t: TIME
+      53             : # this just print cos and sin of time
+      54             : cos: MATHEVAL ARG=t VAR=t FUNC=cos(t) PERIODIC=NO
+      55             : sin: MATHEVAL ARG=t VAR=t FUNC=sin(t) PERIODIC=NO
+      56             : c1: COM ATOMS=1,2
+      57             : c2: COM ATOMS=3,4
+      58             : d: DISTANCE COMPONENTS ATOMS=c1,c2
+      59             : PRINT ARG=t,cos,sin,d.x,d.y,d.z STRIDE=1 FILE=colvar FMT=%8.4f
+      60             : # this calculates sine and cosine of a projected component of distance
+      61             : mycos:  MATHEVAL ARG=d.x,d.y  VAR=x,y   FUNC=x/sqrt(x*x+y*y) PERIODIC=NO
+      62             : mysin:  MATHEVAL ARG=d.x,d.y  VAR=x,y   FUNC=y/sqrt(x*x+y*y) PERIODIC=NO
+      63             : # this creates a moving spring so that the system follows a circle-like dynamics
+      64             : # but it is not a bias, it is a simple value now
+      65             : vv1:  MATHEVAL ARG=mycos,mysin,cos,sin VAR=mc,ms,c,s  FUNC=100*((mc-c)^2+(ms-s)^2) PERIODIC=NO
+      66             : # this takes the value calculated with matheval and uses as a bias
+      67             : cc: BIASVALUE ARG=vv1
+      68             : # some printout
+      69             : PRINT ARG=t,cos,sin,d.x,d.y,d.z,mycos,mysin,cc.vv1_bias STRIDE=1 FILE=colvar FMT=%8.4f
+      70             : \endplumedfile
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : 
+      75             : class BiasValue : public Bias {
+      76             : public:
+      77             :   explicit BiasValue(const ActionOptions&);
+      78             :   void calculate() override;
+      79             :   static void registerKeywords(Keywords& keys);
+      80             : };
+      81             : 
+      82             : PLUMED_REGISTER_ACTION(BiasValue,"BIASVALUE")
+      83             : 
+      84          35 : void BiasValue::registerKeywords(Keywords& keys) {
+      85          35 :   Bias::registerKeywords(keys);
+      86          35 :   keys.use("ARG");
+      87             :   // Should be _bias below
+      88          70 :   keys.addOutputComponent("_bias","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+      89             :                           "these quantities will named with  the arguments of the bias followed by "
+      90             :                           "the character string _bias. These quantities tell the user how much the bias is "
+      91             :                           "due to each of the colvars.");
+      92          35 : }
+      93             : 
+      94          33 : BiasValue::BiasValue(const ActionOptions&ao):
+      95          33 :   PLUMED_BIAS_INIT(ao)
+      96             : {
+      97          33 :   checkRead();
+      98             :   // add one bias for each argument
+      99          67 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     100          34 :     std::string ss=getPntrToArgument(i)->getName()+"_bias";
+     101          68 :     addComponent(ss); componentIsNotPeriodic(ss);
+     102             :   }
+     103          33 : }
+     104             : 
+     105         473 : void BiasValue::calculate() {
+     106             :   double bias=0.0;
+     107         952 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     108             :     double val; val=getArgument(i);
+     109         479 :     getPntrToComponent(i+1)->set(val);
+     110         479 :     setOutputForce(i,-1.);
+     111         479 :     bias+=val;
+     112             :   }
+     113         473 :   setBias(bias);
+     114         473 : }
+     115             : 
+     116             : }
+     117             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ExtendedLagrangian.cpp.func-sort-c.html b/coverage/bias/ExtendedLagrangian.cpp.func-sort-c.html new file mode 100644 index 000000000000..9b0b1c507f79 --- /dev/null +++ b/coverage/bias/ExtendedLagrangian.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - bias/ExtendedLagrangian.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ExtendedLagrangian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:909198.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias18ExtendedLagrangianC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias18ExtendedLagrangianC1ERKNS_13ActionOptionsE2
_ZN4PLMD4bias18ExtendedLagrangian16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4bias18ExtendedLagrangian6updateEv24
_ZN4PLMD4bias18ExtendedLagrangian9calculateEv24
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ExtendedLagrangian.cpp.func.html b/coverage/bias/ExtendedLagrangian.cpp.func.html new file mode 100644 index 000000000000..ec3052db2f30 --- /dev/null +++ b/coverage/bias/ExtendedLagrangian.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - bias/ExtendedLagrangian.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ExtendedLagrangian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:909198.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias18ExtendedLagrangian16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4bias18ExtendedLagrangian6updateEv24
_ZN4PLMD4bias18ExtendedLagrangian9calculateEv24
_ZN4PLMD4bias18ExtendedLagrangianC1ERKNS_13ActionOptionsE2
_ZN4PLMD4bias18ExtendedLagrangianC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ExtendedLagrangian.cpp.gcov.html b/coverage/bias/ExtendedLagrangian.cpp.gcov.html new file mode 100644 index 000000000000..cad444ba80d0 --- /dev/null +++ b/coverage/bias/ExtendedLagrangian.cpp.gcov.html @@ -0,0 +1,339 @@ + + + + + + + + LCOV - plumed test coverage - bias/ExtendedLagrangian.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ExtendedLagrangian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:909198.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Random.h"
+      25             : #include "core/PlumedMain.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace bias {
+      29             : 
+      30             : //+PLUMEDOC BIAS EXTENDED_LAGRANGIAN
+      31             : /*
+      32             : Add extended Lagrangian.
+      33             : 
+      34             : This action can be used to create fictitious collective variables coupled to the real ones.
+      35             : Given \f$x_i\f$ the \f$i\f$th argument of this bias potential, potential
+      36             : and kinetic contributions are added to the energy of the system as
+      37             : \f[
+      38             :   V=\sum_i \frac{k_i}{2} (x_i-s_i)^2 + \sum_i \frac{\dot{s}_i^2}{2m_i}
+      39             : \f].
+      40             : 
+      41             : The resulting potential is thus similar to a \ref RESTRAINT,
+      42             : but the restraint center moved with time following Hamiltonian
+      43             : dynamics with mass \f$m_i\f$.
+      44             : 
+      45             : This bias potential accepts thus vectorial keywords (one element per argument)
+      46             : to define the coupling constant (KAPPA) and a relaxation time \f$tau\f$ (TAU).
+      47             : The mass is them computed as \f$m=k(\frac{\tau}{2\pi})^2\f$.
+      48             : 
+      49             : Notice that this action creates several components.
+      50             : The ones named XX_fict are the fictitious coordinates. It is possible
+      51             : to add further forces on them by means of other bias potential,
+      52             : e.g. to obtain an indirect \ref METAD as in \cite continua .
+      53             : Also notice that the velocities of the fictitious coordinates
+      54             : are reported (XX_vfict). However, printed velocities are the ones
+      55             : at the previous step.
+      56             : 
+      57             : It is also possible to provide a non-zero friction (one value per component).
+      58             : This is then used to implement a Langevin thermostat, so as to implement
+      59             : TAMD/dAFED method \cite Maragliano2006 \cite AbramsJ2008 . Notice that
+      60             : here a massive Langevin thermostat is used, whereas usually
+      61             : TAMD employs an overamped Langevin dynamics and dAFED
+      62             : a Gaussian thermostat.
+      63             : 
+      64             : \warning
+      65             : The bias potential is reported in the component bias.
+      66             : Notice that this bias potential, although formally compatible with
+      67             : replica exchange framework, probably does not work as expected in that case.
+      68             : Indeed, since fictitious coordinates are not swapped upon exchange,
+      69             : acceptace can be expected to be extremely low unless (by chance) two neighboring
+      70             : replicas have the fictitious variables located properly in space.
+      71             : 
+      72             : \warning
+      73             : \ref RESTART is not properly supported by this action. Indeed,
+      74             : at every start the position of the fictitious variable is reset to the value
+      75             : of the real variable, and its velocity is set to zero.
+      76             : This is not expected to introduce big errors, but certainly is
+      77             : introducing a small inconsistency between a single long run
+      78             : and many shorter runs.
+      79             : 
+      80             : \par Examples
+      81             : 
+      82             : The following input tells plumed to perform a metadynamics
+      83             : with an extended Lagrangian on two torsional angles.
+      84             : \plumedfile
+      85             : phi: TORSION ATOMS=5,7,9,15
+      86             : psi: TORSION ATOMS=7,9,15,17
+      87             : ex: EXTENDED_LAGRANGIAN ARG=phi,psi KAPPA=20,20.0 TAU=0.1,0.1
+      88             : METAD ARG=ex.phi_fict,ex.psi_fict PACE=100 SIGMA=0.35,0.35 HEIGHT=0.1
+      89             : # monitor the two variables
+      90             : PRINT STRIDE=10 ARG=phi,psi,ex.phi_fict,ex.psi_fict FILE=COLVAR
+      91             : \endplumedfile
+      92             : 
+      93             : The following input tells plumed to perform a TAMD (or dAFED)
+      94             : calculation on two torsional angles, keeping the two variables
+      95             : at a fictitious temperature of 3000K with a Langevin thermostat
+      96             : with friction 10
+      97             : \plumedfile
+      98             : phi: TORSION ATOMS=5,7,9,15
+      99             : psi: TORSION ATOMS=7,9,15,17
+     100             : ex: EXTENDED_LAGRANGIAN ARG=phi,psi KAPPA=20,20.0 TAU=0.1,0.1 FRICTION=10,10 TEMP=3000
+     101             : # monitor the two variables
+     102             : PRINT STRIDE=10 ARG=phi,psi,ex.phi_fict,ex.psi_fict FILE=COLVAR
+     103             : \endplumedfile
+     104             : 
+     105             : */
+     106             : //+ENDPLUMEDOC
+     107             : 
+     108             : class ExtendedLagrangian : public Bias {
+     109             :   bool firsttime;
+     110             :   std::vector<double> fict;
+     111             :   std::vector<double> vfict;
+     112             :   std::vector<double> vfict_laststep;
+     113             :   std::vector<double> ffict;
+     114             :   std::vector<double> kappa;
+     115             :   std::vector<double> tau;
+     116             :   std::vector<double> friction;
+     117             :   std::vector<Value*> fictValue;
+     118             :   std::vector<Value*> vfictValue;
+     119             :   double kbt;
+     120             :   Random rand;
+     121             : public:
+     122             :   explicit ExtendedLagrangian(const ActionOptions&);
+     123             :   void calculate() override;
+     124             :   void update() override;
+     125             :   static void registerKeywords(Keywords& keys);
+     126             : };
+     127             : 
+     128             : PLUMED_REGISTER_ACTION(ExtendedLagrangian,"EXTENDED_LAGRANGIAN")
+     129             : 
+     130           4 : void ExtendedLagrangian::registerKeywords(Keywords& keys) {
+     131           4 :   Bias::registerKeywords(keys);
+     132           4 :   keys.use("ARG");
+     133           8 :   keys.add("compulsory","KAPPA","specifies that the restraint is harmonic and what the values of the force constants on each of the variables are");
+     134           8 :   keys.add("compulsory","TAU","specifies that the restraint is harmonic and what the values of the force constants on each of the variables are");
+     135           8 :   keys.add("compulsory","FRICTION","0.0","add a friction to the variable");
+     136           8 :   keys.add("optional","TEMP","the system temperature - needed when FRICTION is present. If not provided will be taken from MD code (if available)");
+     137           4 :   componentsAreNotOptional(keys);
+     138           8 :   keys.addOutputComponent("_fict","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     139             :                           "These quantities will named with the arguments of the bias followed by "
+     140             :                           "the character string _tilde. It is possible to add forces on these variable.");
+     141           8 :   keys.addOutputComponent("_vfict","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     142             :                           "These quantities will named with the arguments of the bias followed by "
+     143             :                           "the character string _tilde. It is NOT possible to add forces on these variable.");
+     144           4 : }
+     145             : 
+     146           2 : ExtendedLagrangian::ExtendedLagrangian(const ActionOptions&ao):
+     147             :   PLUMED_BIAS_INIT(ao),
+     148           2 :   firsttime(true),
+     149           4 :   fict(getNumberOfArguments(),0.0),
+     150           2 :   vfict(getNumberOfArguments(),0.0),
+     151           2 :   vfict_laststep(getNumberOfArguments(),0.0),
+     152           2 :   ffict(getNumberOfArguments(),0.0),
+     153           2 :   kappa(getNumberOfArguments(),0.0),
+     154           2 :   tau(getNumberOfArguments(),0.0),
+     155           2 :   friction(getNumberOfArguments(),0.0),
+     156           2 :   fictValue(getNumberOfArguments(),NULL),
+     157           2 :   vfictValue(getNumberOfArguments(),NULL),
+     158           4 :   kbt(0.0)
+     159             : {
+     160           2 :   parseVector("TAU",tau);
+     161           2 :   parseVector("FRICTION",friction);
+     162           2 :   parseVector("KAPPA",kappa);
+     163           2 :   kbt=getkBT(); checkRead();
+     164             : 
+     165           2 :   log.printf("  with harmonic force constant");
+     166           6 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     167           2 :   log.printf("\n");
+     168             : 
+     169           2 :   log.printf("  with relaxation time");
+     170           6 :   for(unsigned i=0; i<tau.size(); i++) log.printf(" %f",tau[i]);
+     171           2 :   log.printf("\n");
+     172             : 
+     173             :   bool hasFriction=false;
+     174           6 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) if(friction[i]>0.0) hasFriction=true;
+     175             : 
+     176           2 :   if(hasFriction) {
+     177           2 :     log.printf("  with friction");
+     178           6 :     for(unsigned i=0; i<friction.size(); i++) log.printf(" %f",friction[i]);
+     179           2 :     log.printf("\n");
+     180             :   }
+     181             : 
+     182           2 :   log.printf("  and kbt");
+     183           2 :   log.printf(" %f",kbt);
+     184           2 :   log.printf("\n");
+     185             : 
+     186           6 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     187           4 :     std::string comp=getPntrToArgument(i)->getName()+"_fict";
+     188           8 :     addComponentWithDerivatives(comp);
+     189           4 :     if(getPntrToArgument(i)->isPeriodic()) {
+     190             :       std::string a,b;
+     191           4 :       getPntrToArgument(i)->getDomain(a,b);
+     192           4 :       componentIsPeriodic(comp,a,b);
+     193           0 :     } else componentIsNotPeriodic(comp);
+     194           4 :     fictValue[i]=getPntrToComponent(comp);
+     195           8 :     comp=getPntrToArgument(i)->getName()+"_vfict";
+     196           4 :     addComponent(comp);
+     197           4 :     componentIsNotPeriodic(comp);
+     198           4 :     vfictValue[i]=getPntrToComponent(comp);
+     199             :   }
+     200             : 
+     201           4 :   log<<"  Bibliography "<<plumed.cite("Iannuzzi, Laio, and Parrinello, Phys. Rev. Lett. 90, 238302 (2003)");
+     202           2 :   if(hasFriction) {
+     203           4 :     log<<plumed.cite("Maragliano and Vanden-Eijnden, Chem. Phys. Lett. 426, 168 (2006)");
+     204           4 :     log<<plumed.cite("Abrams and Tuckerman, J. Phys. Chem. B 112, 15742 (2008)");
+     205             :   }
+     206           2 :   log<<"\n";
+     207           2 : }
+     208             : 
+     209             : 
+     210          24 : void ExtendedLagrangian::calculate() {
+     211             : 
+     212          24 :   if(firsttime) {
+     213           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     214           4 :       fict[i]=getArgument(i);
+     215             :     }
+     216           2 :     firsttime=false;
+     217             :   }
+     218             :   double ene=0.0;
+     219          72 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     220          48 :     const double cv=difference(i,fict[i],getArgument(i));
+     221          48 :     const double k=kappa[i];
+     222          48 :     const double f=-k*cv;
+     223          48 :     ene+=0.5*k*cv*cv;
+     224          48 :     setOutputForce(i,f);
+     225          48 :     ffict[i]=-f;
+     226             :   };
+     227          24 :   setBias(ene);
+     228          72 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     229          48 :     fict[i]=fictValue[i]->bringBackInPbc(fict[i]);
+     230          48 :     fictValue[i]->set(fict[i]);
+     231          48 :     vfictValue[i]->set(vfict_laststep[i]);
+     232             :   }
+     233          24 : }
+     234             : 
+     235          24 : void ExtendedLagrangian::update() {
+     236          24 :   double dt=getTimeStep()*getStride();
+     237          72 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     238          48 :     double mass=kappa[i]*tau[i]*tau[i]/(4*pi*pi); // should be k/omega**2
+     239          48 :     double c1=std::exp(-0.5*friction[i]*dt);
+     240          48 :     double c2=std::sqrt(kbt*(1.0-c1*c1)/mass);
+     241             : // consider additional forces on the fictitious particle
+     242             : // (e.g. MetaD stuff)
+     243          48 :     ffict[i]+=fictValue[i]->getForce();
+     244             : 
+     245             : // update velocity (half step)
+     246          48 :     vfict[i]+=ffict[i]*0.5*dt/mass;
+     247             : // thermostat (half step)
+     248          48 :     vfict[i]=c1*vfict[i]+c2*rand.Gaussian();
+     249             : // save full step velocity to be dumped at next step
+     250          48 :     vfict_laststep[i]=vfict[i];
+     251             : // thermostat (half step)
+     252          48 :     vfict[i]=c1*vfict[i]+c2*rand.Gaussian();
+     253             : // update velocity (half step)
+     254          48 :     vfict[i]+=ffict[i]*0.5*dt/mass;
+     255             : // update position (full step)
+     256          48 :     fict[i]+=vfict[i]*dt;
+     257             :   }
+     258          24 : }
+     259             : 
+     260             : }
+     261             : 
+     262             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/External.cpp.func-sort-c.html b/coverage/bias/External.cpp.func-sort-c.html new file mode 100644 index 000000000000..f60030aa3a94 --- /dev/null +++ b/coverage/bias/External.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/External.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - External.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias8ExternalC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias8ExternalC1ERKNS_13ActionOptionsE2
_ZN4PLMD4bias8External16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4bias8External9calculateEv5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/External.cpp.func.html b/coverage/bias/External.cpp.func.html new file mode 100644 index 000000000000..e66e8b727d59 --- /dev/null +++ b/coverage/bias/External.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/External.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - External.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias8External16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4bias8External9calculateEv5
_ZN4PLMD4bias8ExternalC1ERKNS_13ActionOptionsE2
_ZN4PLMD4bias8ExternalC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/External.cpp.gcov.html b/coverage/bias/External.cpp.gcov.html new file mode 100644 index 000000000000..b08486b8446e --- /dev/null +++ b/coverage/bias/External.cpp.gcov.html @@ -0,0 +1,257 @@ + + + + + + + + LCOV - plumed test coverage - bias/External.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - External.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Grid.h"
+      25             : #include "tools/Exception.h"
+      26             : #include "tools/File.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace bias {
+      30             : 
+      31             : //+PLUMEDOC BIAS EXTERNAL
+      32             : /*
+      33             : Calculate a restraint that is defined on a grid that is read during start up
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : The following is an input for a calculation with an external potential that is
+      38             : defined in the file bias.dat and that acts on the distance between atoms 3 and 5.
+      39             : \plumedfile
+      40             : DISTANCE ATOMS=3,5 LABEL=d1
+      41             : EXTERNAL ARG=d1 FILE=bias.grid LABEL=external
+      42             : \endplumedfile
+      43             : 
+      44             : The bias.grid will then look something like this:
+      45             : \auxfile{bias.grid}
+      46             : #! FIELDS d1 external.bias der_d1
+      47             : #! SET min_d1 1.14
+      48             : #! SET max_d1 1.32
+      49             : #! SET nbins_d1 6
+      50             : #! SET periodic_d1 false
+      51             :    1.1400   0.0031   0.1101
+      52             :    1.1700   0.0086   0.2842
+      53             :    1.2000   0.0222   0.6648
+      54             :    1.2300   0.0521   1.4068
+      55             :    1.2600   0.1120   2.6873
+      56             :    1.2900   0.2199   4.6183
+      57             :    1.3200   0.3948   7.1055
+      58             : \endauxfile
+      59             : 
+      60             : This should then be followed by the value of the potential and its derivative
+      61             : at 100 equally spaced points along the distance between 0 and 1.
+      62             : 
+      63             : You can also include grids that are a function of more than one collective
+      64             : variable.  For instance the following would be the input for an external
+      65             : potential acting on two torsional angles:
+      66             : \plumedfile
+      67             : TORSION ATOMS=4,5,6,7 LABEL=t1
+      68             : TORSION ATOMS=6,7,8,9 LABEL=t2
+      69             : EXTERNAL ARG=t1,t2 FILE=bias2.grid LABEL=ext
+      70             : \endplumedfile
+      71             : 
+      72             : The file bias2.grid for this calculation would need to look something like this:
+      73             : \auxfile{bias2.grid}
+      74             : #! FIELDS t1 t2 ext.bias der_t1 der_t2
+      75             : #! SET min_t1 -pi
+      76             : #! SET max_t1 pi
+      77             : #! SET nbins_t1 3
+      78             : #! SET periodic_t1 true
+      79             : #! SET min_t2 -pi
+      80             : #! SET max_t2 pi
+      81             : #! SET nbins_t2 3
+      82             : #! SET periodic_t2 true
+      83             :  -3.141593 -3.141593 0.000000 -0.000000 -0.000000
+      84             :  -1.047198 -3.141593 0.000000 0.000000 -0.000000
+      85             :  1.047198 -3.141593 0.000000 -0.000000 -0.000000
+      86             : 
+      87             :  -3.141593 -1.047198 0.000000 -0.000000 0.000000
+      88             :  -1.047198 -1.047198 0.007922 0.033185 0.033185
+      89             :  1.047198 -1.047198 0.007922 -0.033185 0.033185
+      90             : 
+      91             :  -3.141593 1.047198 0.000000 -0.000000 -0.000000
+      92             :  -1.047198 1.047198 0.007922 0.033185 -0.033185
+      93             :  1.047198 1.047198 0.007922 -0.033185 -0.033185
+      94             : \endauxfile
+      95             : 
+      96             : This would be then followed by 100 blocks of data.  In the first block of data the
+      97             : value of t1 (the value in the first column) is kept fixed and the value of
+      98             : the function is given at 100 equally spaced values for t2 between \f$-pi\f$ and \f$+pi\f$.  In the
+      99             : second block of data t1 is fixed at \f$-pi + \frac{2pi}{100}\f$ and the value of the function is
+     100             : given at 100 equally spaced values for t2 between \f$-pi\f$ and \f$+pi\f$. In the third block of
+     101             : data the same is done but t1 is fixed at \f$-pi + \frac{4pi}{100}\f$ and so on until you get to
+     102             : the one hundredth block of data where t1 is fixed at \f$+pi\f$.
+     103             : 
+     104             : Please note the order that the order of arguments in the plumed.dat file must be the same as
+     105             : the order of arguments in the header of the grid file.
+     106             : */
+     107             : //+ENDPLUMEDOC
+     108             : 
+     109             : class External : public Bias {
+     110             : 
+     111             : private:
+     112             :   std::unique_ptr<GridBase> BiasGrid_;
+     113             :   double scale_;
+     114             : 
+     115             : public:
+     116             :   explicit External(const ActionOptions&);
+     117             :   void calculate() override;
+     118             :   static void registerKeywords(Keywords& keys);
+     119             : };
+     120             : 
+     121             : PLUMED_REGISTER_ACTION(External,"EXTERNAL")
+     122             : 
+     123           4 : void External::registerKeywords(Keywords& keys) {
+     124           4 :   Bias::registerKeywords(keys);
+     125           4 :   keys.use("ARG");
+     126           8 :   keys.add("compulsory","FILE","the name of the file containing the external potential.");
+     127           8 :   keys.addFlag("NOSPLINE",false,"specifies that no spline interpolation is to be used when calculating the energy and forces due to the external potential");
+     128           8 :   keys.addFlag("SPARSE",false,"specifies that the external potential uses a sparse grid");
+     129           8 :   keys.add("compulsory","SCALE","1.0","a factor that multiplies the external potential, useful to invert free energies");
+     130           4 : }
+     131             : 
+     132           2 : External::External(const ActionOptions& ao):
+     133           2 :   PLUMED_BIAS_INIT(ao)
+     134             : {
+     135             :   std::string filename;
+     136           4 :   parse("FILE",filename);
+     137           2 :   if( filename.length()==0 ) error("No external potential file was specified");
+     138           2 :   bool sparsegrid=false;
+     139           2 :   parseFlag("SPARSE",sparsegrid);
+     140           2 :   bool nospline=false;
+     141           2 :   parseFlag("NOSPLINE",nospline);
+     142           2 :   bool spline=!nospline;
+     143           3 :   parse("SCALE",scale_);
+     144             : 
+     145           2 :   checkRead();
+     146             : 
+     147           2 :   log.printf("  External potential from file %s\n",filename.c_str());
+     148           2 :   log.printf("  Multiplied by %lf\n",scale_);
+     149           2 :   if(spline) {log.printf("  External potential uses spline interpolation\n");}
+     150           2 :   if(sparsegrid) {log.printf("  External potential uses sparse grid\n");}
+     151             : 
+     152             : // read grid
+     153           2 :   IFile gridfile; gridfile.open(filename);
+     154           1 :   std::string funcl=getLabel() + ".bias";
+     155           2 :   BiasGrid_=GridBase::create(funcl,getArguments(),gridfile,sparsegrid,spline,true);
+     156           1 :   if(BiasGrid_->getDimension()!=getNumberOfArguments()) error("mismatch between dimensionality of input grid and number of arguments");
+     157           3 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     158           4 :     if( getPntrToArgument(i)->isPeriodic()!=BiasGrid_->getIsPeriodic()[i] ) error("periodicity mismatch between arguments and input bias");
+     159             :   }
+     160           6 : }
+     161             : 
+     162           5 : void External::calculate()
+     163             : {
+     164           5 :   unsigned ncv=getNumberOfArguments();
+     165           5 :   std::vector<double> cv(ncv), der(ncv);
+     166             : 
+     167          15 :   for(unsigned i=0; i<ncv; ++i) {cv[i]=getArgument(i);}
+     168             : 
+     169           5 :   double ene=scale_*BiasGrid_->getValueAndDerivatives(cv,der);
+     170             : 
+     171           5 :   setBias(ene);
+     172             : 
+     173          15 :   for(unsigned i=0; i<ncv; ++i) {
+     174          10 :     const double f=-scale_*der[i];
+     175          10 :     setOutputForce(i,f);
+     176             :   }
+     177           5 : }
+     178             : 
+     179             : }
+     180             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/LWalls.cpp.func-sort-c.html b/coverage/bias/LWalls.cpp.func-sort-c.html new file mode 100644 index 000000000000..ac3e71f0daac --- /dev/null +++ b/coverage/bias/LWalls.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/LWalls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - LWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6LWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias6LWallsC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias6LWalls16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias6LWalls9calculateEv5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/LWalls.cpp.func.html b/coverage/bias/LWalls.cpp.func.html new file mode 100644 index 000000000000..ef92f72bf6dd --- /dev/null +++ b/coverage/bias/LWalls.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/LWalls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - LWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6LWalls16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias6LWalls9calculateEv5
_ZN4PLMD4bias6LWallsC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias6LWallsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/LWalls.cpp.gcov.html b/coverage/bias/LWalls.cpp.gcov.html new file mode 100644 index 000000000000..09e237fa884a --- /dev/null +++ b/coverage/bias/LWalls.cpp.gcov.html @@ -0,0 +1,225 @@ + + + + + + + + LCOV - plumed test coverage - bias/LWalls.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - LWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace bias {
+      27             : 
+      28             : //+PLUMEDOC BIAS LOWER_WALLS
+      29             : /*
+      30             : Defines a wall for the value of one or more collective variables,
+      31             :  which limits the region of the phase space accessible during the simulation.
+      32             : 
+      33             : The restraining potential starts acting on the system when the value of the CV is greater
+      34             : (in the case of UPPER_WALLS) or lower (in the case of LOWER_WALLS) than a certain limit \f$a_i\f$ (AT)
+      35             : minus an offset \f$o_i\f$ (OFFSET).
+      36             : The expression for the bias due to the wall is given by:
+      37             : 
+      38             : \f$
+      39             :   \sum_i {k_i}((x_i-a_i+o_i)/s_i)^e_i
+      40             : \f$
+      41             : 
+      42             : \f$k_i\f$ (KAPPA) is an energy constant in internal unit of the code, \f$s_i\f$ (EPS) a rescaling factor and
+      43             : \f$e_i\f$ (EXP) the exponent determining the power law. By default: EXP = 2, EPS = 1.0, OFFSET = 0.
+      44             : 
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : The following input tells plumed to add both a lower and an upper walls on the distance
+      49             : between atoms 3 and 5 and the distance between atoms 2 and 4. The lower and upper limits
+      50             : are defined at different values. The strength of the walls is the same for the four cases.
+      51             : It also tells plumed to print the energy of the walls.
+      52             : \plumedfile
+      53             : DISTANCE ATOMS=3,5 LABEL=d1
+      54             : DISTANCE ATOMS=2,4 LABEL=d2
+      55             : UPPER_WALLS ARG=d1,d2 AT=1.0,1.5 KAPPA=150.0,150.0 EXP=2,2 EPS=1,1 OFFSET=0,0 LABEL=uwall
+      56             : LOWER_WALLS ARG=d1,d2 AT=0.0,1.0 KAPPA=150.0,150.0 EXP=2,2 EPS=1,1 OFFSET=0,0 LABEL=lwall
+      57             : PRINT ARG=uwall.bias,lwall.bias
+      58             : \endplumedfile
+      59             : (See also \ref DISTANCE and \ref PRINT).
+      60             : 
+      61             : */
+      62             : //+ENDPLUMEDOC
+      63             : 
+      64             : class LWalls : public Bias {
+      65             :   std::vector<double> at;
+      66             :   std::vector<double> kappa;
+      67             :   std::vector<double> exp;
+      68             :   std::vector<double> eps;
+      69             :   std::vector<double> offset;
+      70             : public:
+      71             :   explicit LWalls(const ActionOptions&);
+      72             :   void calculate() override;
+      73             :   static void registerKeywords(Keywords& keys);
+      74             : };
+      75             : 
+      76             : PLUMED_REGISTER_ACTION(LWalls,"LOWER_WALLS")
+      77             : 
+      78           3 : void LWalls::registerKeywords(Keywords& keys) {
+      79           3 :   Bias::registerKeywords(keys);
+      80           3 :   keys.use("ARG");
+      81           6 :   keys.add("compulsory","AT","the positions of the wall. The a_i in the expression for a wall.");
+      82           6 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      83           6 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      84           6 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      85           6 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      86           6 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      87           3 : }
+      88             : 
+      89           1 : LWalls::LWalls(const ActionOptions&ao):
+      90             :   PLUMED_BIAS_INIT(ao),
+      91           2 :   at(getNumberOfArguments(),0),
+      92           1 :   kappa(getNumberOfArguments(),0.0),
+      93           1 :   exp(getNumberOfArguments(),2.0),
+      94           1 :   eps(getNumberOfArguments(),1.0),
+      95           2 :   offset(getNumberOfArguments(),0.0)
+      96             : {
+      97             :   // Note sizes of these vectors are automatically checked by parseVector :-)
+      98           1 :   parseVector("OFFSET",offset);
+      99           1 :   parseVector("EPS",eps);
+     100           1 :   parseVector("EXP",exp);
+     101           1 :   parseVector("KAPPA",kappa);
+     102           1 :   parseVector("AT",at);
+     103           1 :   checkRead();
+     104             : 
+     105           1 :   log.printf("  at");
+     106           2 :   for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
+     107           1 :   log.printf("\n");
+     108           1 :   log.printf("  with an offset");
+     109           2 :   for(unsigned i=0; i<offset.size(); i++) log.printf(" %f",offset[i]);
+     110           1 :   log.printf("\n");
+     111           1 :   log.printf("  with force constant");
+     112           2 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     113           1 :   log.printf("\n");
+     114           1 :   log.printf("  and exponent");
+     115           2 :   for(unsigned i=0; i<exp.size(); i++) log.printf(" %f",exp[i]);
+     116           1 :   log.printf("\n");
+     117           1 :   log.printf("  rescaled");
+     118           2 :   for(unsigned i=0; i<eps.size(); i++) log.printf(" %f",eps[i]);
+     119           1 :   log.printf("\n");
+     120             : 
+     121           2 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     122           1 : }
+     123             : 
+     124           5 : void LWalls::calculate() {
+     125             :   double ene = 0.0;
+     126             :   double totf2 = 0.0;
+     127          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     128             :     double f = 0.0;
+     129           5 :     const double cv=difference(i,at[i],getArgument(i));
+     130           5 :     const double off=offset[i];
+     131           5 :     const double epsilon=eps[i];
+     132           5 :     const double lscale = (cv-off)/epsilon;
+     133           5 :     if( lscale < 0.) {
+     134           5 :       const double k=kappa[i];
+     135           5 :       const double exponent=exp[i];
+     136           5 :       double power = std::pow( lscale, exponent );
+     137           5 :       f = -( k / epsilon ) * exponent * power / lscale;
+     138           5 :       ene += k * power;
+     139           5 :       totf2 += f * f;
+     140             :     }
+     141           5 :     setOutputForce(i,f);
+     142             :   }
+     143           5 :   setBias(ene);
+     144           5 :   getPntrToComponent("force2")->set(totf2);
+     145           5 : }
+     146             : 
+     147             : }
+     148             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MaxEnt.cpp.func-sort-c.html b/coverage/bias/MaxEnt.cpp.func-sort-c.html new file mode 100644 index 000000000000..adfba0e26688 --- /dev/null +++ b/coverage/bias/MaxEnt.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - bias/MaxEnt.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - MaxEnt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22523396.6 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6MaxEntC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias6MaxEnt15ReadLagrangiansERNS_5IFileE37
_ZN4PLMD4bias6MaxEntC1ERKNS_13ActionOptionsE50
_ZN4PLMD4bias6MaxEnt16registerKeywordsERNS_8KeywordsE52
_ZN4PLMD4bias6MaxEnt13update_lambdaEv550
_ZN4PLMD4bias6MaxEnt16WriteLagrangiansERSt6vectorIdSaIdEERNS_5OFileE550
_ZN4PLMD4bias6MaxEnt6updateEv5050
_ZN4PLMD4bias6MaxEnt9calculateEv5050
_ZN4PLMD4bias6MaxEnt13compute_errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd5302
_ZN4PLMD4bias6MaxEnt23check_lambda_boundariesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd5302
_ZN4PLMD4bias6MaxEnt14convert_lambdaERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd119118
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MaxEnt.cpp.func.html b/coverage/bias/MaxEnt.cpp.func.html new file mode 100644 index 000000000000..e8abc8cb3138 --- /dev/null +++ b/coverage/bias/MaxEnt.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - bias/MaxEnt.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - MaxEnt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22523396.6 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6MaxEnt13compute_errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd5302
_ZN4PLMD4bias6MaxEnt13update_lambdaEv550
_ZN4PLMD4bias6MaxEnt14convert_lambdaERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd119118
_ZN4PLMD4bias6MaxEnt15ReadLagrangiansERNS_5IFileE37
_ZN4PLMD4bias6MaxEnt16WriteLagrangiansERSt6vectorIdSaIdEERNS_5OFileE550
_ZN4PLMD4bias6MaxEnt16registerKeywordsERNS_8KeywordsE52
_ZN4PLMD4bias6MaxEnt23check_lambda_boundariesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd5302
_ZN4PLMD4bias6MaxEnt6updateEv5050
_ZN4PLMD4bias6MaxEnt9calculateEv5050
_ZN4PLMD4bias6MaxEntC1ERKNS_13ActionOptionsE50
_ZN4PLMD4bias6MaxEntC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MaxEnt.cpp.gcov.html b/coverage/bias/MaxEnt.cpp.gcov.html new file mode 100644 index 000000000000..7457ce38334b --- /dev/null +++ b/coverage/bias/MaxEnt.cpp.gcov.html @@ -0,0 +1,561 @@ + + + + + + + + LCOV - plumed test coverage - bias/MaxEnt.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - MaxEnt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22523396.6 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/ActionWithValue.h"
+      26             : #include "tools/Communicator.h"
+      27             : #include "tools/File.h"
+      28             : 
+      29             : // The original implementation of this method was contributed
+      30             : // by Andrea Cesari (andreacesari90@gmail.com).
+      31             : // Copyright has been then transferred to PLUMED developers
+      32             : // (see https://github.com/plumed/plumed2/blob/master/.github/CONTRIBUTING.md)
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace bias {
+      36             : 
+      37             : //+PLUMEDOC BIAS MAXENT
+      38             : /*
+      39             : Add a linear biasing potential on one or more variables that satisfies a maximum entropy principle.
+      40             : 
+      41             : Add a linear biasing potential on one or more variables \f$f_{i}\left(\boldsymbol{x}\right)\f$ satisfying the maximum entropy principle as proposed in Ref. \cite cesari2016maxent .
+      42             : 
+      43             : \warning
+      44             :     Notice that syntax is still under revision and might change
+      45             : 
+      46             : The resulting biasing potential is given by:
+      47             : \f[
+      48             :   V_{BIAS}(\boldsymbol{x},t)=K_{B}T\sum_{i=1}^{\#arguments}f_{i}(\boldsymbol{x},t)\lambda_{i}(t)
+      49             : \f]
+      50             : Lagrangian multipliers \f$ \lambda_{i}\f$ are updated, every PACE steps, according to the following update rule:
+      51             : \f[
+      52             : \lambda_{i}=\lambda_{i}+\frac{k_{i}}{1+\frac{t}{\tau_{i}}}\left(f_{exp,i}+\xi_{i}\lambda_{i}-f_{i}(\boldsymbol{x})\right)
+      53             : \f]
+      54             : \f$k\f$ set the initial value of the learning rate and its units are \f$[observable]^{-2}ps^{-1}\f$. This can be set with the keyword KAPPA.
+      55             : The number of components for any KAPPA vector must be equal to the number of arguments of the action.
+      56             : 
+      57             : Variable \f$ \xi_{i}(\lambda) \f$ is related to the chosen prior to model experimental errors. If a GAUSSIAN prior is used then:
+      58             : \f[
+      59             : \xi_{i}(\lambda)=-\lambda_{i}\sigma^{2}
+      60             : \f]
+      61             : where \f$ \sigma \f$ is the typical expected error on the observable \f$ f_i\f$.
+      62             : For a LAPLACE prior:
+      63             : \f[
+      64             : \xi_{i}(\lambda)=-\frac{\lambda_{i}\sigma^{2}}{1-\frac{\lambda^{2}\sigma^{2}}{2}}
+      65             : 
+      66             : \f]
+      67             : The value of \f$ \xi(\lambda,t)\f$ is written in output as a component named: argument name followed by the string _error.
+      68             : Setting \f$ \sigma =0\f$ is equivalent to enforce a pure Maximum Entropy restraint without any noise modelling.
+      69             : This method can be also used to enforce inequality restraint as shown in following examples.
+      70             : 
+      71             : Notice that a similar method is available as \ref EDS, although with different features and using a different optimization algorithm.
+      72             : 
+      73             : \par Examples
+      74             : 
+      75             : The following input tells plumed to restrain the distance between atoms 7 and 15
+      76             : and the distance between atoms 2 and 19, at different equilibrium
+      77             : values, and to print the energy of the restraint.
+      78             : Lagrangian multiplier will be printed on a file called restraint.LAGMULT with a stride set by the variable PACE to 200ps.
+      79             : Moreover plumed will compute the average of each Lagrangian multiplier in the window [TSTART,TEND] and use that to continue the simulations with fixed Lagrangian multipliers.
+      80             : \plumedfile
+      81             : DISTANCE ATOMS=7,15 LABEL=d1
+      82             : DISTANCE ATOMS=2,19 LABEL=d2
+      83             : MAXENT ...
+      84             : ARG=d1,d2
+      85             : TYPE=EQUAL
+      86             : AT=0.2,0.5
+      87             : KAPPA=35000.0,35000.0
+      88             : TAU=0.02,0.02
+      89             : PACE=200
+      90             : TSTART=100
+      91             : TEND=500
+      92             : LABEL=restraint
+      93             : ... MAXENT
+      94             : PRINT ARG=restraint.bias
+      95             : \endplumedfile
+      96             : Lagrangian multipliers will be printed on a file called restraint.bias
+      97             : The following input tells plumed to restrain the distance between atoms 7 and 15
+      98             : to be greater than 0.2 and to print the energy of the restraint
+      99             : \plumedfile
+     100             : DISTANCE ATOMS=7,15 LABEL=d
+     101             : MAXENT ARG=d TYPE=INEQUAL> AT=0.02 KAPPA=35000.0 TAU=3 LABEL=restraint
+     102             : PRINT ARG=restraint.bias
+     103             : \endplumedfile
+     104             : 
+     105             : (See also \ref DISTANCE and \ref PRINT).
+     106             : 
+     107             : */
+     108             : //+ENDPLUMEDOC
+     109             : 
+     110             : class MaxEnt : public Bias {
+     111             :   std::vector<double> at;
+     112             :   std::vector<double> kappa;
+     113             :   std::vector<double> lambda;
+     114             :   std::vector<double> avgx;
+     115             :   std::vector<double> work;
+     116             :   std::vector<double> oldlambda;
+     117             :   std::vector<double> tau;
+     118             :   std::vector<double> avglambda;
+     119             :   std::vector<double> avglambda_restart;
+     120             :   std::vector<double> expected_eps;
+     121             :   std::vector<double> apply_weights;
+     122             :   double sigma;
+     123             :   double tstart;
+     124             :   double tend;
+     125             :   double avgstep; //current number of samples over which to compute the average. Check if could be replaced bu getStep()
+     126             :   long long int pace_;
+     127             :   long long int stride_;
+     128             :   double totalWork;
+     129             :   double BetaReweightBias;
+     130             :   double simtemp;
+     131             :   std::vector<ActionWithValue*> biases;
+     132             :   std::string type;
+     133             :   std::string error_type;
+     134             :   double alpha;
+     135             :   double avg_counter;
+     136             :   int learn_replica;
+     137             :   Value* valueForce2;
+     138             :   Value* valueWork;
+     139             :   OFile lagmultOfile_;
+     140             :   IFile ifile;
+     141             :   std::string lagmultfname;
+     142             :   std::string ifilesnames;
+     143             :   std::string fmt;
+     144             :   bool isFirstStep;
+     145             :   bool reweight;
+     146             :   bool no_broadcast;
+     147             :   bool printFirstStep;
+     148             :   std::vector<bool> done_average;
+     149             :   int myrep,nrep;
+     150             : public:
+     151             :   explicit MaxEnt(const ActionOptions&);
+     152             :   void calculate() override;
+     153             :   void update() override;
+     154             :   void update_lambda();
+     155             :   static void registerKeywords(Keywords& keys);
+     156             :   void ReadLagrangians(IFile &ifile);
+     157             :   void WriteLagrangians(std::vector<double> &lagmult,OFile &file);
+     158             :   double compute_error(const std::string &err_type,double l);
+     159             :   double convert_lambda(const std::string &type,double lold);
+     160             :   void check_lambda_boundaries(const std::string &err_type,double &l);
+     161             : };
+     162             : PLUMED_REGISTER_ACTION(MaxEnt,"MAXENT")
+     163             : 
+     164          52 : void MaxEnt::registerKeywords(Keywords& keys) {
+     165          52 :   Bias::registerKeywords(keys);
+     166          52 :   componentsAreNotOptional(keys);
+     167          52 :   keys.use("ARG");
+     168         104 :   keys.add("compulsory","KAPPA","0.0","specifies the initial value for the learning rate");
+     169         104 :   keys.add("compulsory","TAU","Specify the dumping time for the learning rate.");
+     170         104 :   keys.add("compulsory","TYPE","specify the restraint type. "
+     171             :            "EQUAL to restrain the variable at a given equilibrium value "
+     172             :            "INEQUAL< to restrain the variable to be smaller than a given value "
+     173             :            "INEQUAL> to restrain the variable to be greater than a given value");
+     174         104 :   keys.add("optional","ERROR_TYPE","specify the prior on the error to use."
+     175             :            "GAUSSIAN: use a Gaussian prior "
+     176             :            "LAPLACE: use a Laplace prior");
+     177         104 :   keys.add("optional","TSTART","time from where to start averaging the Lagrangian multiplier. By default no average is computed, hence lambda is updated every PACE steps");
+     178         104 :   keys.add("optional","TEND","time in ps where to stop to compute the average of Lagrangian multiplier. From this time until the end of the simulation Lagrangian multipliers are kept fix to the average computed between TSTART and TEND;");
+     179         104 :   keys.add("optional","ALPHA","default=1.0; To be used with LAPLACE KEYWORD, allows to choose a prior function proportional to a Gaussian times an exponential function. ALPHA=1 correspond to the LAPLACE prior.");
+     180         104 :   keys.add("compulsory","AT","the position of the restraint");
+     181         104 :   keys.add("optional","SIGMA","The typical errors expected on observable");
+     182         104 :   keys.add("optional","FILE","Lagrangian multipliers output file. The default name is: label name followed by the string .LAGMULT ");
+     183         104 :   keys.add("optional","LEARN_REPLICA","In a multiple replica environment specify which is the reference replica. By default replica 0 will be used.");
+     184         104 :   keys.add("optional","APPLY_WEIGHTS","Vector of weights containing 1 in correspondence of each replica that will receive the Lagrangian multiplier from the current one.");
+     185         104 :   keys.add("optional","PACE","the frequency for Lagrangian multipliers update");
+     186         104 :   keys.add("optional","PRINT_STRIDE","stride of Lagrangian multipliers output file. If no STRIDE is passed they are written every time they are updated (PACE).");
+     187         104 :   keys.add("optional","FMT","specify format for Lagrangian multipliers files (useful to decrease the number of digits in regtests)");
+     188         104 :   keys.addFlag("REWEIGHT",false,"to be used with plumed driver in order to reweight a trajectory a posteriori");
+     189         104 :   keys.addFlag("NO_BROADCAST",false,"If active will avoid Lagrangian multipliers to be communicated to other replicas.");
+     190         104 :   keys.add("optional","TEMP","the system temperature.  This is required if you are reweighting.");
+     191         104 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+     192         104 :   keys.addOutputComponent("work","default","the instantaneous value of the work done by the biasing force");
+     193         104 :   keys.addOutputComponent("_work","default","the instantaneous value of the work done by the biasing force for each argument. "
+     194             :                           "These quantities will named with the arguments of the bias followed by "
+     195             :                           "the character string _work.");
+     196         104 :   keys.addOutputComponent("_error","default","Instantaneous values of the discrepancy between the observable and the restraint center");
+     197         104 :   keys.addOutputComponent("_coupling","default","Instantaneous values of Lagrangian multipliers. They are also written by default in a separate output file.");
+     198          52 :   keys.use("RESTART");
+     199          52 : }
+     200          50 : MaxEnt::MaxEnt(const ActionOptions&ao):
+     201             :   PLUMED_BIAS_INIT(ao),
+     202         100 :   at(getNumberOfArguments()),
+     203          50 :   kappa(getNumberOfArguments(),0.0),
+     204          50 :   lambda(getNumberOfArguments(),0.0),
+     205          50 :   avgx(getNumberOfArguments(),0.0),
+     206          50 :   oldlambda(getNumberOfArguments(),0.0),
+     207          50 :   tau(getNumberOfArguments(),getTimeStep()),
+     208          50 :   avglambda(getNumberOfArguments(),0.0),
+     209          50 :   avglambda_restart(getNumberOfArguments(),0.0),
+     210          50 :   expected_eps(getNumberOfArguments(),0.0),
+     211          50 :   sigma(0.0),
+     212          50 :   pace_(100),
+     213          50 :   stride_(100),
+     214          50 :   alpha(1.0),
+     215          50 :   avg_counter(0.0),
+     216          50 :   isFirstStep(true),
+     217          50 :   reweight(false),
+     218          50 :   no_broadcast(false),
+     219          50 :   printFirstStep(true),
+     220         150 :   done_average(getNumberOfArguments(),false)
+     221             : {
+     222          50 :   if(comm.Get_rank()==0) nrep=multi_sim_comm.Get_size();
+     223          50 :   if(comm.Get_rank()==0) myrep=multi_sim_comm.Get_rank();
+     224          50 :   comm.Bcast(nrep,0);
+     225          50 :   comm.Bcast(myrep,0);
+     226          50 :   parseFlag("NO_BROADCAST",no_broadcast);
+     227             :   //if(no_broadcast){
+     228             :   //for(int irep=0;irep<nrep;irep++){
+     229             :   //  if(irep!=myrep)
+     230             :   //    apply_weights[irep]=0.0;}
+     231             :   //}
+     232          50 :   avgstep=1.0;
+     233          50 :   tstart=-1.0;
+     234          50 :   tend=-1.0;
+     235          50 :   totalWork=0.0;
+     236          50 :   learn_replica=0;
+     237             : 
+     238          50 :   parse("LEARN_REPLICA",learn_replica);
+     239         100 :   parseVector("APPLY_WEIGHTS",apply_weights);
+     240          50 :   if(apply_weights.size()==0) apply_weights.resize(nrep,1.0);
+     241          50 :   parseVector("KAPPA",kappa);
+     242          50 :   parseVector("AT",at);
+     243          50 :   parseVector("TAU",tau);
+     244         100 :   parse("TYPE",type);
+     245             :   error_type="GAUSSIAN";
+     246          50 :   parse("ERROR_TYPE",error_type);
+     247          50 :   parse("ALPHA",alpha);
+     248          50 :   parse("SIGMA",sigma);
+     249          50 :   parse("TSTART",tstart);
+     250          50 :   if(tstart <0 && tstart != -1.0) error("TSTART should be a positive number");
+     251          50 :   parse("TEND",tend);
+     252          50 :   if(tend<0 && tend != -1.0) error("TSTART should be a positive number");
+     253          50 :   if(tend<tstart) error("TEND should be >= TSTART");
+     254          50 :   lagmultfname=getLabel()+".LAGMULT";
+     255          50 :   parse("FILE",lagmultfname);
+     256          50 :   parse("FMT",fmt);
+     257          50 :   parse("PACE",pace_);
+     258          50 :   if(pace_<=0 ) error("frequency for Lagrangian multipliers update (PACE) is nonsensical");
+     259          50 :   stride_=pace_;  //if no STRIDE is passed, then Lagrangian multipliers willbe printed at each update
+     260          50 :   parse("PRINT_STRIDE",stride_);
+     261          50 :   if(stride_<=0 ) error("frequency for Lagrangian multipliers printing (STRIDE) is nonsensical");
+     262          50 :   simtemp=getkBT();
+     263          50 :   parseFlag("REWEIGHT",reweight);
+     264          50 :   if(simtemp<=0 && reweight) error("Set the temperature (TEMP) if you want to do reweighting.");
+     265             : 
+     266          50 :   checkRead();
+     267             : 
+     268          50 :   log.printf("  at");
+     269         532 :   for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
+     270          50 :   log.printf("\n");
+     271          50 :   log.printf("  with initial learning rate for optimization of");
+     272         532 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     273          50 :   log.printf("\n");
+     274          50 :   log.printf("Dumping times for the learning rates are (ps): ");
+     275         532 :   for(unsigned i=0; i<tau.size(); i++) log.printf(" %f",tau[i]);
+     276          50 :   log.printf("\n");
+     277          50 :   log.printf("Lagrangian multipliers are updated every %lld steps (PACE)\n",pace_);
+     278          50 :   log.printf("Lagrangian multipliers output file %s\n",lagmultfname.c_str());
+     279          50 :   log.printf("Lagrangian multipliers are written every %lld steps (PRINT_STRIDE)\n",stride_);
+     280          50 :   if(fmt.length()>0)
+     281          50 :     log.printf("The format for real number in Lagrangian multipliers file is %s\n",fmt.c_str());
+     282          50 :   if(tstart >-1.0 && tend>-1.0)
+     283          14 :     log.printf("Lagrangian multipliers are averaged from %lf ps to %lf ps\n",tstart,tend);
+     284          50 :   if(no_broadcast)
+     285           0 :     log.printf("Using NO_BROADCAST options. Lagrangian multipliers will not be comunicated to other replicas.\n");
+     286             :   //for(int irep=0;irep<nrep;irep++){
+     287             :   //  if(apply_weights[irep]!=0)
+     288             :   //    log.printf("%d",irep);
+     289             :   //  }
+     290         150 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     291         100 :   addComponent("work"); componentIsNotPeriodic("work");
+     292          50 :   valueForce2=getPntrToComponent("force2");
+     293          50 :   valueWork=getPntrToComponent("work");
+     294             : 
+     295             :   std::string comp;
+     296         532 :   for(unsigned i=0; i< getNumberOfArguments() ; i++) {
+     297         964 :     comp=getPntrToArgument(i)->getName()+"_coupling";
+     298         964 :     addComponent(comp); componentIsNotPeriodic(comp);
+     299         964 :     comp=getPntrToArgument(i)->getName()+"_work";
+     300         964 :     addComponent(comp); componentIsNotPeriodic(comp);
+     301         482 :     work.push_back(0.); // initialize the work value
+     302         964 :     comp=getPntrToArgument(i)->getName()+"_error";
+     303         964 :     addComponent(comp); componentIsNotPeriodic(comp);
+     304             :   }
+     305             :   std::string fname;
+     306             :   fname=lagmultfname;
+     307          50 :   ifile.link(*this);
+     308          50 :   if(ifile.FileExist(fname)) {
+     309          37 :     ifile.open(fname);
+     310          37 :     if(getRestart()) {
+     311          37 :       log.printf("  Restarting from: %s\n",fname.c_str());
+     312          37 :       ReadLagrangians(ifile);
+     313          37 :       printFirstStep=false;
+     314             :     }
+     315          37 :     ifile.reset(false);
+     316             :   }
+     317             : 
+     318          50 :   lagmultOfile_.link(*this);
+     319          50 :   lagmultOfile_.open(fname);
+     320         100 :   if(fmt.length()>0) {fmt=" "+fmt; lagmultOfile_.fmtField(fmt);}
+     321          50 : }
+     322             : ////MEMBER FUNCTIONS
+     323          37 : void MaxEnt::ReadLagrangians(IFile &ifile)
+     324             : {
+     325             :   double dummy;
+     326         888 :   while(ifile.scanField("time",dummy)) {
+     327        4708 :     for(unsigned j=0; j<getNumberOfArguments(); ++j) {
+     328        4301 :       ifile.scanField(getPntrToArgument(j)->getName()+"_coupling",lambda[j]);
+     329        4301 :       if(dummy>=tstart && dummy <=tend)
+     330          42 :         avglambda[j]+=lambda[j];
+     331        4301 :       if(dummy>=tend) {
+     332        4231 :         avglambda[j]=lambda[j];
+     333             :         done_average[j]=true;
+     334             :       }
+     335             :     }
+     336         407 :     if(dummy>=tstart && dummy <=tend)
+     337           6 :       avg_counter++;
+     338         407 :     ifile.scanField();
+     339             :   }
+     340          37 : }
+     341         550 : void MaxEnt::WriteLagrangians(std::vector<double> &lagmult,OFile &file) {
+     342         550 :   if(printFirstStep) {
+     343         143 :     unsigned ncv=getNumberOfArguments();
+     344         143 :     file.printField("time",getTimeStep()*getStep());
+     345        1144 :     for(unsigned i=0; i<ncv; ++i)
+     346        2002 :       file.printField(getPntrToArgument(i)->getName()+"_coupling",lagmult[i]);
+     347         143 :     file.printField();
+     348             :   } else {
+     349         407 :     if(!isFirstStep) {
+     350         370 :       unsigned ncv=getNumberOfArguments();
+     351         370 :       file.printField("time",getTimeStep()*getStep());
+     352        4280 :       for(unsigned i=0; i<ncv; ++i)
+     353        7820 :         file.printField(getPntrToArgument(i)->getName()+"_coupling",lagmult[i]);
+     354         370 :       file.printField();
+     355             :     }
+     356             :   }
+     357         550 : }
+     358        5302 : double MaxEnt::compute_error(const std::string &err_type,double l) {
+     359        5302 :   double sigma2=std::pow(sigma,2.0);
+     360        5302 :   double l2=convert_lambda(type,l);
+     361             :   double return_error=0;
+     362        5302 :   if(err_type=="GAUSSIAN" && sigma!=0.0)
+     363           0 :     return_error=-l2*sigma2;
+     364             :   else {
+     365        5302 :     if(err_type=="LAPLACE" && sigma!=0) {
+     366        5302 :       return_error=-l2*sigma2/(1.0-l2*l2*sigma2/(alpha+1));
+     367             :     }
+     368             :   }
+     369        5302 :   return return_error;
+     370             : }
+     371      119118 : double MaxEnt::convert_lambda(const std::string &type,double lold) {
+     372             :   double return_lambda=0;
+     373      119118 :   if(type=="EQUAL")
+     374             :     return_lambda=lold;
+     375             :   else {
+     376        5302 :     if(type=="INEQUAL>") {
+     377           0 :       if(lold>0.0)
+     378             :         return_lambda=0.0;
+     379             :       else
+     380             :         return_lambda=lold;
+     381             :     }
+     382             :     else {
+     383        5302 :       if(type=="INEQUAL<") {
+     384           0 :         if(lold<0.0)
+     385             :           return_lambda=0.0;
+     386             :         else
+     387             :           return_lambda=lold;
+     388             :       }
+     389             :     }
+     390             :   }
+     391      119118 :   return return_lambda;
+     392             : }
+     393        5302 : void MaxEnt::check_lambda_boundaries(const std::string &err_type,double &l) {
+     394        5302 :   if(err_type=="LAPLACE" && sigma !=0 ) {
+     395        5302 :     double l2=convert_lambda(err_type,l);
+     396        5302 :     if(l2 <-(std::sqrt(alpha+1)/sigma-0.01)) {
+     397           0 :       l=-(std::sqrt(alpha+1)/sigma-0.01);
+     398           0 :       log.printf("Lambda exceeded the allowed range\n");
+     399             :     }
+     400        5302 :     if(l2>(std::sqrt(alpha+1)/sigma-0.01)) {
+     401           0 :       l=std::sqrt(alpha+1)/sigma-0.01;
+     402           0 :       log.printf("Lambda exceeded the allowed range\n");
+     403             :     }
+     404             :   }
+     405        5302 : }
+     406             : 
+     407         550 : void MaxEnt::update_lambda() {
+     408             : 
+     409             :   double totalWork_=0.0;
+     410         550 :   const double time=getTime();
+     411         550 :   const double step=getStep();
+     412         550 :   double KbT=simtemp;
+     413             :   double learning_rate;
+     414         550 :   if(reweight)
+     415         396 :     BetaReweightBias=plumed.getBias()/KbT;
+     416             :   else
+     417         154 :     BetaReweightBias=0.0;
+     418             : 
+     419        5852 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     420        5302 :     const double k=kappa[i];
+     421        5302 :     double cv=(getArgument(i)+compute_error(error_type,lambda[i])-at[i]);
+     422        5302 :     if(reweight)
+     423        4224 :       learning_rate=1.0*k/(1+step/tau[i]);
+     424             :     else
+     425        1078 :       learning_rate=1.0*k/(1+time/tau[i]);
+     426        5302 :     lambda[i]+=learning_rate*cv*std::exp(-BetaReweightBias); //update Lagrangian multipliers and reweight them if REWEIGHT is set
+     427        5302 :     check_lambda_boundaries(error_type,lambda[i]);      //check that Lagrangians multipliers not exceed the allowed range
+     428        5890 :     if(time>=tstart && time <=tend && !done_average[i]) {
+     429         546 :       avglambda[i]+=convert_lambda(type,lambda[i]); //compute the average of Lagrangian multipliers over the required time window
+     430             :     }
+     431        5302 :     if(time>=tend && tend >=0) { //setting tend<0 will disable this feature
+     432          98 :       if(!done_average[i]) {
+     433          91 :         avglambda[i]=avglambda[i]/avg_counter;
+     434             :         done_average[i]=true;
+     435          91 :         lambda[i]=avglambda[i];
+     436             :       }
+     437             :       else
+     438           7 :         lambda[i]=avglambda[i]; //keep Lagrangian multipliers fixed to the previously computed average.
+     439             :     }
+     440        5302 :     work[i]+=(convert_lambda(type,lambda[i])-oldlambda[i])*getArgument(i); //compute the work performed in updating lambda
+     441        5302 :     totalWork_+=work[i];
+     442        5302 :     totalWork=totalWork_;
+     443        5302 :     oldlambda[i]=convert_lambda(type,lambda[i]);
+     444             :   };
+     445         550 :   if(time>=tstart && time <=tend)
+     446          84 :     avg_counter++;
+     447         550 : }
+     448             : 
+     449        5050 : void MaxEnt::calculate() {
+     450             :   double totf2=0.0;
+     451             :   double ene=0.0;
+     452        5050 :   double KbT=simtemp;
+     453       53732 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     454       97364 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_error")->set(expected_eps[i]);
+     455       48682 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_work")->set(work[i]);
+     456       48682 :     valueWork->set(totalWork);
+     457       48682 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_coupling")->set(lambda[i]);
+     458       48682 :     const double f=-KbT*convert_lambda(type,lambda[i])*apply_weights[myrep];
+     459       48682 :     totf2+=f*f;
+     460       48682 :     ene+=KbT*convert_lambda(type,lambda[i])*getArgument(i)*apply_weights[myrep];
+     461       48682 :     setOutputForce(i,f);
+     462             :   }
+     463        5050 :   setBias(ene);
+     464        5050 :   valueForce2->set(totf2);
+     465        5050 : }
+     466             : 
+     467        5050 : void MaxEnt::update() {
+     468             : 
+     469        5050 :   if(getStep()%stride_ == 0)
+     470         550 :     WriteLagrangians(lambda,lagmultOfile_);
+     471        5050 :   if(getStep()%pace_ == 0) {
+     472         550 :     update_lambda();
+     473         550 :     if(!no_broadcast) {
+     474         550 :       if(comm.Get_rank()==0) //Comunicate Lagrangian multipliers from reference replica to higher ones
+     475         462 :         multi_sim_comm.Bcast(lambda,learn_replica);
+     476             :     }
+     477         550 :     comm.Bcast(lambda,0);
+     478             :   }
+     479        5050 :   isFirstStep=false;
+     480        5050 : }
+     481             : 
+     482             : }
+     483             : 
+     484             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MetaD.cpp.func-sort-c.html b/coverage/bias/MetaD.cpp.func-sort-c.html new file mode 100644 index 000000000000..b67c5f7e9dac --- /dev/null +++ b/coverage/bias/MetaD.cpp.func-sort-c.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - bias/MetaD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - MetaD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:950107788.2 %
Date:2024-02-22 21:58:45Functions:262892.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias5MetaD24getGaussianNormalizationERKNS1_8GaussianE0
_ZN4PLMD4bias5MetaDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias5MetaD17logTemperingSpecsERKNS1_14TemperingSpecsE3
_ZN4PLMD4bias5MetaD11updateNlistEv4
_ZN4PLMD4bias5MetaD16noStretchWarningEv12
_ZN4PLMD4bias5MetaD12temperHeightERdRKNS1_14TemperingSpecsEd60
_ZN4PLMD4bias5MetaD24computeReweightingFactorEv102
_ZN4PLMD4bias5MetaD18readTemperingSpecsERNS1_14TemperingSpecsE151
_ZN4PLMD4bias5MetaD29updateFrequencyAdaptiveStrideEv154
_ZN4PLMD4bias5MetaD14TemperingSpecsC2EbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ddd156
_ZN4PLMD4bias5MetaDC1ERKNS_13ActionOptionsE157
_ZN4PLMD4bias5MetaD16registerKeywordsERNS_8KeywordsE159
_ZN4PLMD4bias5MetaD25registerTemperingKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RNS_8KeywordsE159
_ZN4PLMD4bias5MetaD16evaluateGaussianERKSt6vectorIdSaIdEERKNS1_8GaussianE192
_ZN4PLMD4bias5MetaD24getTransitionBarrierBiasEv273
_ZN4PLMD4bias5MetaD7getBiasERKSt6vectorIdSaIdEE285
_ZN4PLMD4bias5MetaD18getGaussianSupportERKNS1_8GaussianE640
_ZN4PLMD4bias5MetaD9getHeightERKSt6vectorIdSaIdEE2736
_ZN4PLMD4bias5MetaD13writeGaussianERKNS1_8GaussianERNS_5OFileE2922
_ZN4PLMD4bias5MetaD11addGaussianERKNS1_8GaussianE5546
_ZN4PLMD4bias5MetaD8GaussianC2EbdRKSt6vectorIdSaIdEES7_5546
_ZN4PLMD4bias5MetaD13readGaussiansEPNS_5IFileE6037
_ZN4PLMD4bias5MetaD6updateEv6239
_ZN4PLMD4bias5MetaD21getBiasAndDerivativesERKSt6vectorIdSaIdEERS4_8395
_ZN4PLMD4bias5MetaD9calculateEv8435
_ZNK4PLMD4bias5MetaD19checkNeedsGradientsEv8435
_ZN4PLMD4bias5MetaD11scanOneHillEPNS_5IFileERSt6vectorINS_5ValueESaIS5_EERS4_IdSaIdEESB_RdRb8499
_ZN4PLMD4bias5MetaD30evaluateGaussianAndDerivativesERKSt6vectorIdSaIdEERKNS1_8GaussianERS4_SA_2409207
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MetaD.cpp.func.html b/coverage/bias/MetaD.cpp.func.html new file mode 100644 index 000000000000..f250e0328d1b --- /dev/null +++ b/coverage/bias/MetaD.cpp.func.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - bias/MetaD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - MetaD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:950107788.2 %
Date:2024-02-22 21:58:45Functions:262892.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias5MetaD11addGaussianERKNS1_8GaussianE5546
_ZN4PLMD4bias5MetaD11scanOneHillEPNS_5IFileERSt6vectorINS_5ValueESaIS5_EERS4_IdSaIdEESB_RdRb8499
_ZN4PLMD4bias5MetaD11updateNlistEv4
_ZN4PLMD4bias5MetaD12temperHeightERdRKNS1_14TemperingSpecsEd60
_ZN4PLMD4bias5MetaD13readGaussiansEPNS_5IFileE6037
_ZN4PLMD4bias5MetaD13writeGaussianERKNS1_8GaussianERNS_5OFileE2922
_ZN4PLMD4bias5MetaD14TemperingSpecsC2EbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESA_ddd156
_ZN4PLMD4bias5MetaD16evaluateGaussianERKSt6vectorIdSaIdEERKNS1_8GaussianE192
_ZN4PLMD4bias5MetaD16noStretchWarningEv12
_ZN4PLMD4bias5MetaD16registerKeywordsERNS_8KeywordsE159
_ZN4PLMD4bias5MetaD17logTemperingSpecsERKNS1_14TemperingSpecsE3
_ZN4PLMD4bias5MetaD18getGaussianSupportERKNS1_8GaussianE640
_ZN4PLMD4bias5MetaD18readTemperingSpecsERNS1_14TemperingSpecsE151
_ZN4PLMD4bias5MetaD21getBiasAndDerivativesERKSt6vectorIdSaIdEERS4_8395
_ZN4PLMD4bias5MetaD24computeReweightingFactorEv102
_ZN4PLMD4bias5MetaD24getGaussianNormalizationERKNS1_8GaussianE0
_ZN4PLMD4bias5MetaD24getTransitionBarrierBiasEv273
_ZN4PLMD4bias5MetaD25registerTemperingKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RNS_8KeywordsE159
_ZN4PLMD4bias5MetaD29updateFrequencyAdaptiveStrideEv154
_ZN4PLMD4bias5MetaD30evaluateGaussianAndDerivativesERKSt6vectorIdSaIdEERKNS1_8GaussianERS4_SA_2409207
_ZN4PLMD4bias5MetaD6updateEv6239
_ZN4PLMD4bias5MetaD7getBiasERKSt6vectorIdSaIdEE285
_ZN4PLMD4bias5MetaD8GaussianC2EbdRKSt6vectorIdSaIdEES7_5546
_ZN4PLMD4bias5MetaD9calculateEv8435
_ZN4PLMD4bias5MetaD9getHeightERKSt6vectorIdSaIdEE2736
_ZN4PLMD4bias5MetaDC1ERKNS_13ActionOptionsE157
_ZN4PLMD4bias5MetaDC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4bias5MetaD19checkNeedsGradientsEv8435
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MetaD.cpp.gcov.html b/coverage/bias/MetaD.cpp.gcov.html new file mode 100644 index 000000000000..c8cde503b92a --- /dev/null +++ b/coverage/bias/MetaD.cpp.gcov.html @@ -0,0 +1,2381 @@ + + + + + + + + LCOV - plumed test coverage - bias/MetaD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - MetaD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:950107788.2 %
Date:2024-02-22 21:58:45Functions:262892.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/FlexibleBin.h"
+      27             : #include "tools/Exception.h"
+      28             : #include "tools/Grid.h"
+      29             : #include "tools/Matrix.h"
+      30             : #include "tools/OpenMP.h"
+      31             : #include "tools/Random.h"
+      32             : #include "tools/File.h"
+      33             : #include "tools/Communicator.h"
+      34             : #include <ctime>
+      35             : #include <numeric>
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace bias {
+      39             : 
+      40             : //+PLUMEDOC BIAS METAD
+      41             : /*
+      42             : Used to performed metadynamics on one or more collective variables.
+      43             : 
+      44             : In a metadynamics simulations a history dependent bias composed of
+      45             : intermittently added Gaussian functions is added to the potential \cite metad.
+      46             : 
+      47             : \f[
+      48             : V(\vec{s},t) = \sum_{ k \tau < t} W(k \tau)
+      49             : \exp\left(
+      50             : -\sum_{i=1}^{d} \frac{(s_i-s_i^{(0)}(k \tau))^2}{2\sigma_i^2}
+      51             : \right).
+      52             : \f]
+      53             : 
+      54             : This potential forces the system away from the kinetic traps in the potential energy surface
+      55             : and out into the unexplored parts of the energy landscape. Information on the Gaussian
+      56             : functions from which this potential is composed is output to a file called HILLS, which
+      57             : is used both the restart the calculation and to reconstruct the free energy as a function of the CVs.
+      58             : The free energy can be reconstructed from a metadynamics calculation because the final bias is given
+      59             : by:
+      60             : 
+      61             : \f[
+      62             : V(\vec{s}) = -F(\vec{s})
+      63             : \f]
+      64             : 
+      65             : During post processing the free energy can be calculated in this way using the \ref sum_hills
+      66             : utility.
+      67             : 
+      68             : In the simplest possible implementation of a metadynamics calculation the expense of a metadynamics
+      69             : calculation increases with the length of the simulation as one has to, at every step, evaluate
+      70             : the values of a larger and larger number of Gaussian kernels. To avoid this issue you can
+      71             : store the bias on a grid.  This approach is similar to that proposed in \cite babi08jcp but has the
+      72             : advantage that the grid spacing is independent on the Gaussian width.
+      73             : Notice that you should provide the grid boundaries (GRID_MIN and GRID_MAX) and either the number of bins
+      74             : for every collective variable (GRID_BIN) or the desired grid spacing (GRID_SPACING).
+      75             : In case you provide both PLUMED will use the most conservative choice (highest number of bins) for each dimension.
+      76             : In case you do not provide any information about bin size (neither GRID_BIN nor GRID_SPACING)
+      77             : PLUMED will use 1/5 of the Gaussian width (SIGMA) as grid spacing if the width is fixed or 1/5 of the minimum
+      78             : Gaussian width (SIGMA_MIN) if the width is variable. This default choice should be reasonable for most applications.
+      79             : 
+      80             : Alternatively to the use of grids, it is possible to use a neighbor list to decrease the cost of evaluating the bias,
+      81             : this can be enabled using NLIST. NLIST can be beneficial with more than 2 collective variables, where GRID becomes
+      82             : expensive and memory consuming. The neighbor list will be updated everytime the CVs go farther than a cut-off value
+      83             : from the position they were at last neighbor list update. Gaussians are added to the neigbhor list if their center
+      84             : is within 6.*DP2CUTOFF*sigma*sigma. While the list is updated if the CVs are farther from the center than 0.5 of the
+      85             : standard deviation of the Gaussian center distribution of the list. These parameters (6 and 0.5) can be modified using
+      86             : NLIST_PARAMETERS. Note that the use of neighbor list does not provide the exact bias.
+      87             : 
+      88             : Metadynamics can be restarted either from a HILLS file as well as from a GRID, in this second
+      89             : case one can first save a GRID using GRID_WFILE (and GRID_WSTRIDE) and at a later stage read
+      90             : it using GRID_RFILE.
+      91             : 
+      92             : The work performed by the METAD bias can be calculated using CALC_WORK, note that this is expensive when not using grids.
+      93             : 
+      94             : Another option that is available in plumed is well-tempered metadynamics \cite Barducci:2008. In this
+      95             : variant of metadynamics the heights of the Gaussian hills are scaled at each step so the bias is now
+      96             : given by:
+      97             : 
+      98             : \f[
+      99             : V({s},t)= \sum_{t'=0,\tau_G,2\tau_G,\dots}^{t'<t} W e^{-V({s}({q}(t'),t')/\Delta T} \exp\left(
+     100             : -\sum_{i=1}^{d} \frac{(s_i({q})-s_i({q}(t'))^2}{2\sigma_i^2}
+     101             : \right),
+     102             : \f]
+     103             : 
+     104             : This method ensures that the bias converges more smoothly. It should be noted that, in the case of well-tempered metadynamics, in
+     105             : the output printed the Gaussian height is re-scaled using the bias factor.
+     106             : Also notice that with well-tempered metadynamics the HILLS file does not contain the bias,
+     107             : but the negative of the free-energy estimate. This choice has the advantage that
+     108             : one can restart a simulation using a different value for the \f$\Delta T\f$. The applied bias will be scaled accordingly.
+     109             : 
+     110             : Note that you can use here also the flexible Gaussian approach  \cite Branduardi:2012dl
+     111             : in which you can adapt the Gaussian to the extent of Cartesian space covered by a variable or
+     112             : to the space in collective variable covered in a given time. In this case the width of the deposited
+     113             : Gaussian potential is denoted by one value only that is a Cartesian space (ADAPTIVE=GEOM) or a time
+     114             : (ADAPTIVE=DIFF). Note that a specific integration technique for the deposited Gaussian kernels
+     115             : should be used in this case. Check the documentation for utility sum_hills.
+     116             : 
+     117             : With the keyword INTERVAL one changes the metadynamics algorithm setting the bias force equal to zero
+     118             : outside boundary \cite baftizadeh2012protein. If, for example, metadynamics is performed on a CV s and one is interested only
+     119             : to the free energy for s > boundary, the history dependent potential is still updated according to the above
+     120             : equations but the metadynamics force is set to zero for s < boundary. Notice that Gaussian kernels are added also
+     121             : if s < boundary, as the tails of these Gaussian kernels influence VG in the relevant region s > boundary. In this way, the
+     122             : force on the system in the region s > boundary comes from both metadynamics and the force field, in the region
+     123             : s < boundary only from the latter. This approach allows obtaining a history-dependent bias potential VG that
+     124             : fluctuates around a stable estimator, equal to the negative of the free energy far enough from the
+     125             : boundaries. Note that:
+     126             : - It works only for one-dimensional biases;
+     127             : - It works both with and without GRID;
+     128             : - The interval limit boundary in a region where the free energy derivative is not large;
+     129             : - If in the region outside the limit boundary the system has a free energy minimum, the INTERVAL keyword should
+     130             :   be used together with a \ref UPPER_WALLS or \ref LOWER_WALLS at boundary.
+     131             : 
+     132             : As a final note, since version 2.0.2 when the system is outside of the selected interval the force
+     133             : is set to zero and the bias value to the value at the corresponding boundary. This allows acceptances
+     134             : for replica exchange methods to be computed correctly.
+     135             : 
+     136             : Multiple walkers  \cite multiplewalkers can also be used. See below the examples.
+     137             : 
+     138             : 
+     139             : The \f$c(t)\f$ reweighting factor can also be calculated on the fly using the equations
+     140             : presented in \cite Tiwary_jp504920s.
+     141             : The expression used to calculate \f$c(t)\f$ follows directly from Eq. 3 in \cite Tiwary_jp504920s,
+     142             : where \f$F(\vec{s})=-\gamma/(\gamma-1) V(\vec{s})\f$.
+     143             : This gives smoother results than equivalent Eqs. 13 and Eqs. 14 in that paper.
+     144             : The \f$c(t)\f$ is given by the rct component while the bias
+     145             : normalized by \f$c(t)\f$ is given by the rbias component (rbias=bias-rct) which can be used
+     146             : to obtain a reweighted histogram.
+     147             : The calculation of \f$c(t)\f$ is enabled by using the keyword CALC_RCT.
+     148             : By default \f$c(t)\f$ is updated every time the bias changes, but if this slows down the simulation
+     149             : the keyword RCT_USTRIDE can be set to a value higher than 1.
+     150             : This option requires that a grid is used.
+     151             : 
+     152             : Additional material and examples can be also found in the tutorials:
+     153             : 
+     154             : - \ref lugano-3
+     155             : 
+     156             : Concurrent metadynamics
+     157             : as done e.g. in Ref. \cite gil2015enhanced . This indeed can be obtained by using the METAD
+     158             : action multiple times in the same input file.
+     159             : 
+     160             : \par Examples
+     161             : 
+     162             : The following input is for a standard metadynamics calculation using as
+     163             : collective variables the distance between atoms 3 and 5
+     164             : and the distance between atoms 2 and 4. The value of the CVs and
+     165             : the metadynamics bias potential are written to the COLVAR file every 100 steps.
+     166             : \plumedfile
+     167             : DISTANCE ATOMS=3,5 LABEL=d1
+     168             : DISTANCE ATOMS=2,4 LABEL=d2
+     169             : METAD ARG=d1,d2 SIGMA=0.2,0.2 HEIGHT=0.3 PACE=500 LABEL=restraint
+     170             : PRINT ARG=d1,d2,restraint.bias STRIDE=100  FILE=COLVAR
+     171             : \endplumedfile
+     172             : (See also \ref DISTANCE \ref PRINT).
+     173             : 
+     174             : \par
+     175             : If you use adaptive Gaussian kernels, with diffusion scheme where you use
+     176             : a Gaussian that should cover the space of 20 time steps in collective variables.
+     177             : Note that in this case the histogram correction is needed when summing up hills.
+     178             : \plumedfile
+     179             : DISTANCE ATOMS=3,5 LABEL=d1
+     180             : DISTANCE ATOMS=2,4 LABEL=d2
+     181             : METAD ARG=d1,d2 SIGMA=20 HEIGHT=0.3 PACE=500 LABEL=restraint ADAPTIVE=DIFF
+     182             : PRINT ARG=d1,d2,restraint.bias STRIDE=100  FILE=COLVAR
+     183             : \endplumedfile
+     184             : 
+     185             : \par
+     186             : If you use adaptive Gaussian kernels, with geometrical scheme where you use
+     187             : a Gaussian that should cover the space of 0.05 nm in Cartesian space.
+     188             : Note that in this case the histogram correction is needed when summing up hills.
+     189             : \plumedfile
+     190             : DISTANCE ATOMS=3,5 LABEL=d1
+     191             : DISTANCE ATOMS=2,4 LABEL=d2
+     192             : METAD ARG=d1,d2 SIGMA=0.05 HEIGHT=0.3 PACE=500 LABEL=restraint ADAPTIVE=GEOM
+     193             : PRINT ARG=d1,d2,restraint.bias STRIDE=100  FILE=COLVAR
+     194             : \endplumedfile
+     195             : 
+     196             : \par
+     197             : When using adaptive Gaussian kernels you might want to limit how the hills width can change.
+     198             : You can use SIGMA_MIN and SIGMA_MAX keywords.
+     199             : The sigmas should specified in terms of CV so you should use the CV units.
+     200             : Note that if you use a negative number, this means that the limit is not set.
+     201             : Note also that in this case the histogram correction is needed when summing up hills.
+     202             : \plumedfile
+     203             : DISTANCE ATOMS=3,5 LABEL=d1
+     204             : DISTANCE ATOMS=2,4 LABEL=d2
+     205             : METAD ...
+     206             :   ARG=d1,d2 SIGMA=0.05 HEIGHT=0.3 PACE=500 LABEL=restraint ADAPTIVE=GEOM
+     207             :   SIGMA_MIN=0.2,0.1 SIGMA_MAX=0.5,1.0
+     208             : ... METAD
+     209             : PRINT ARG=d1,d2,restraint.bias STRIDE=100  FILE=COLVAR
+     210             : \endplumedfile
+     211             : 
+     212             : \par
+     213             : Multiple walkers can be also use as in  \cite multiplewalkers
+     214             : These are enabled by setting the number of walker used, the id of the
+     215             : current walker which interprets the input file, the directory where the
+     216             : hills containing files resides, and the frequency to read the other walkers.
+     217             : Here is an example
+     218             : \plumedfile
+     219             : DISTANCE ATOMS=3,5 LABEL=d1
+     220             : METAD ...
+     221             :    ARG=d1 SIGMA=0.05 HEIGHT=0.3 PACE=500 LABEL=restraint
+     222             :    WALKERS_N=10
+     223             :    WALKERS_ID=3
+     224             :    WALKERS_DIR=../
+     225             :    WALKERS_RSTRIDE=100
+     226             : ... METAD
+     227             : \endplumedfile
+     228             : where  WALKERS_N is the total number of walkers, WALKERS_ID is the
+     229             : id of the present walker (starting from 0 ) and the WALKERS_DIR is the directory
+     230             : where all the walkers are located. WALKERS_RSTRIDE is the number of step between
+     231             : one update and the other. Since version 2.2.5, hills files are automatically
+     232             : flushed every WALKERS_RSTRIDE steps.
+     233             : 
+     234             : \par
+     235             : The \f$c(t)\f$ reweighting factor can be calculated on the fly using the equations
+     236             : presented in \cite Tiwary_jp504920s as described above.
+     237             : This is enabled by using the keyword CALC_RCT,
+     238             : and can be done only if the bias is defined on a grid.
+     239             : \plumedfile
+     240             : phi: TORSION ATOMS=1,2,3,4
+     241             : psi: TORSION ATOMS=5,6,7,8
+     242             : 
+     243             : METAD ...
+     244             :  LABEL=metad
+     245             :  ARG=phi,psi SIGMA=0.20,0.20 HEIGHT=1.20 BIASFACTOR=5 TEMP=300.0 PACE=500
+     246             :  GRID_MIN=-pi,-pi GRID_MAX=pi,pi GRID_BIN=150,150
+     247             :  CALC_RCT
+     248             :  RCT_USTRIDE=10
+     249             : ... METAD
+     250             : \endplumedfile
+     251             : Here we have asked that the calculation is performed every 10 hills deposition by using
+     252             : RCT_USTRIDE keyword. If this keyword is not given, the calculation will
+     253             : by default be performed every time the bias changes. The \f$c(t)\f$ reweighting factor will be given
+     254             : in the rct component while the instantaneous value of the bias potential
+     255             : normalized using the \f$c(t)\f$ reweighting factor is given in the rbias component
+     256             : [rbias=bias-rct] which can be used to obtain a reweighted histogram or
+     257             : free energy surface using the \ref HISTOGRAM analysis.
+     258             : 
+     259             : \par
+     260             : The kinetics of the transitions between basins can also be analyzed on the fly as
+     261             : in \cite PRL230602. The flag ACCELERATION turn on accumulation of the acceleration
+     262             : factor that can then be used to determine the rate. This method can be used together
+     263             : with \ref COMMITTOR analysis to stop the simulation when the system get to the target basin.
+     264             : It must be used together with Well-Tempered Metadynamics. If restarting from a previous
+     265             : metadynamics you need to use the ACCELERATION_RFILE keyword to give the name of the
+     266             : data file from which the previous value of the acceleration factor should be read, otherwise the
+     267             : calculation of the acceleration factor will be wrong.
+     268             : 
+     269             : \par
+     270             : By using the flag FREQUENCY_ADAPTIVE the frequency adaptive scheme introduced in \cite Wang-JCP-2018
+     271             : is turned on. The frequency for hill addition then changes dynamically based on the acceleration factor
+     272             : according to the following equation
+     273             : \f[
+     274             : \tau_{\mathrm{dep}}(t) =
+     275             : \min\left[
+     276             : \tau_0 \cdot
+     277             : \max\left[\frac{\alpha(t)}{\theta},1\right]
+     278             : ,\tau_{c}
+     279             : \right]
+     280             : \f]
+     281             : where \f$\tau_0\f$ is the initial hill addition frequency given by the PACE keyword,
+     282             : \f$\tau_{c}\f$ is the maximum allowed frequency given by the FA_MAX_PACE keyword,
+     283             : \f$\alpha(t)\f$ is the instantaneous acceleration factor at time \f$t\f$,
+     284             : and \f$\theta\f$ is a threshold value that acceleration factor has to reach before
+     285             : triggering a change in the hill addition frequency given by the FA_MIN_ACCELERATION keyword.
+     286             : The frequency for updating the hill addition frequency according to this equation is
+     287             : given by the FA_UPDATE_FREQUENCY keyword, by default it is the same as the value given
+     288             : in PACE. The hill hill addition frequency increase monotonously such that if the
+     289             : instantaneous acceleration factor is lower than in the previous updating step the
+     290             : previous \f$\tau_{\mathrm{dep}}\f$ is kept rather than updating it to a lower value.
+     291             : The instantaneous hill addition frequency \f$\tau_{\mathrm{dep}}(t)\f$ is outputted
+     292             : to pace component. Note that if restarting from a previous metadynamics run you need to
+     293             : use the ACCELERATION_RFILE keyword to read in the acceleration factors from the
+     294             : previous run, otherwise the hill addition frequency will start from the initial
+     295             : frequency.
+     296             : 
+     297             : 
+     298             : \par
+     299             : You can also provide a target distribution using the keyword TARGET
+     300             : \cite white2015designing
+     301             : \cite marinelli2015ensemble
+     302             : \cite gil2016empirical
+     303             : The TARGET should be a grid containing a free-energy (i.e. the -\f$k_B\f$T*log of the desired target distribution).
+     304             : Gaussian kernels will then be scaled by a factor
+     305             : \f[
+     306             : e^{\beta(\tilde{F}(s)-\tilde{F}_{max})}
+     307             : \f]
+     308             : Here \f$\tilde{F}(s)\f$ is the free energy defined on the grid and \f$\tilde{F}_{max}\f$ its maximum value.
+     309             : Notice that we here used the maximum value as in ref \cite gil2016empirical
+     310             : This choice allows to avoid exceedingly large Gaussian kernels to be added. However,
+     311             : it could make the Gaussian too small. You should always choose carefully the HEIGHT parameter
+     312             : in this case.
+     313             : The grid file should be similar to other PLUMED grid files in that it should contain
+     314             : both the target free-energy and its derivatives.
+     315             : 
+     316             : Notice that if you wish your simulation to converge to the target free energy you should use
+     317             : the DAMPFACTOR command to provide a global tempering \cite dama2014well
+     318             : Alternatively, if you use a BIASFACTOR your simulation will converge to a free
+     319             : energy that is a linear combination of the target free energy and of the intrinsic free energy
+     320             : determined by the original force field.
+     321             : 
+     322             : \plumedfile
+     323             : DISTANCE ATOMS=3,5 LABEL=d1
+     324             : METAD ...
+     325             :  LABEL=t1
+     326             :  ARG=d1 SIGMA=0.05 TAU=200 DAMPFACTOR=100 PACE=250
+     327             :  GRID_MIN=1.14 GRID_MAX=1.32 GRID_BIN=6
+     328             :  TARGET=dist.grid
+     329             : ... METAD
+     330             : 
+     331             : PRINT ARG=d1,t1.bias STRIDE=100 FILE=COLVAR
+     332             : \endplumedfile
+     333             : 
+     334             : The file dist.dat for this calculation would read:
+     335             : 
+     336             : \auxfile{dist.grid}
+     337             : #! FIELDS d1 t1.target der_d1
+     338             : #! SET min_d1 1.14
+     339             : #! SET max_d1 1.32
+     340             : #! SET nbins_d1  6
+     341             : #! SET periodic_d1 false
+     342             :    1.1400   0.0031   0.1101
+     343             :    1.1700   0.0086   0.2842
+     344             :    1.2000   0.0222   0.6648
+     345             :    1.2300   0.0521   1.4068
+     346             :    1.2600   0.1120   2.6873
+     347             :    1.2900   0.2199   4.6183
+     348             :    1.3200   0.3948   7.1055
+     349             : \endauxfile
+     350             : 
+     351             : Notice that BIASFACTOR can also be chosen as equal to 1. In this case one will perform
+     352             : unbiased sampling. Instead of using HEIGHT, one should provide the TAU parameter.
+     353             : \plumedfile
+     354             : d: DISTANCE ATOMS=3,5
+     355             : METAD ARG=d SIGMA=0.1 TAU=4.0 TEMP=300 PACE=100 BIASFACTOR=1.0
+     356             : \endplumedfile
+     357             : The HILLS file obtained will still work with `plumed sum_hills` so as to plot a free-energy.
+     358             : The case where this makes sense is probably that of RECT simulations.
+     359             : 
+     360             : Regarding RECT simulations, you can also use the RECT keyword so as to avoid using multiple input files.
+     361             : For instance, a single input file will be
+     362             : \plumedfile
+     363             : d: DISTANCE ATOMS=3,5
+     364             : METAD ARG=d SIGMA=0.1 TAU=4.0 TEMP=300 PACE=100 RECT=1.0,1.5,2.0,3.0
+     365             : \endplumedfile
+     366             : The number of elements in the RECT array should be equal to the number of replicas.
+     367             : 
+     368             : */
+     369             : //+ENDPLUMEDOC
+     370             : 
+     371             : class MetaD : public Bias {
+     372             : 
+     373             : private:
+     374             :   struct Gaussian {
+     375             :     bool   multivariate; // this is required to discriminate the one dimensional case
+     376             :     double height;
+     377             :     std::vector<double> center;
+     378             :     std::vector<double> sigma;
+     379             :     std::vector<double> invsigma;
+     380        5546 :     Gaussian(const bool m, const double h, const std::vector<double>& c, const std::vector<double>& s):
+     381        5546 :       multivariate(m),height(h),center(c),sigma(s),invsigma(s) {
+     382             :       // to avoid troubles from zero element in flexible hills
+     383       16175 :       for(unsigned i=0; i<invsigma.size(); ++i) {
+     384       10629 :         if(std::abs(invsigma[i])>1.e-20) invsigma[i]=1.0/invsigma[i] ;
+     385           0 :         else invsigma[i]=0.0;
+     386             :       }
+     387        5546 :     }
+     388             :   };
+     389           8 :   struct TemperingSpecs {
+     390             :     bool is_active;
+     391             :     std::string name_stem;
+     392             :     std::string name;
+     393             :     double biasf;
+     394             :     double threshold;
+     395             :     double alpha;
+     396         156 :     inline TemperingSpecs(bool is_active, const std::string &name_stem, const std::string &name, double biasf, double threshold, double alpha) :
+     397         156 :       is_active(is_active), name_stem(name_stem), name(name), biasf(biasf), threshold(threshold), alpha(alpha)
+     398         156 :     {}
+     399             :   };
+     400             :   // general setup
+     401             :   double kbt_;
+     402             :   int stride_;
+     403             :   bool calc_work_;
+     404             :   // well-tempered MetaD
+     405             :   bool welltemp_;
+     406             :   double biasf_;
+     407             :   // output files format
+     408             :   std::string fmt_;
+     409             :   // first step?
+     410             :   bool isFirstStep_;
+     411             :   // Gaussian starting parameters
+     412             :   double height0_;
+     413             :   std::vector<double> sigma0_;
+     414             :   std::vector<double> sigma0min_;
+     415             :   std::vector<double> sigma0max_;
+     416             :   // Gaussians
+     417             :   std::vector<Gaussian> hills_;
+     418             :   std::unique_ptr<FlexibleBin> flexbin_;
+     419             :   int adaptive_;
+     420             :   OFile hillsOfile_;
+     421             :   std::vector<std::unique_ptr<IFile>> ifiles_;
+     422             :   std::vector<std::string> ifilesnames_;
+     423             :   // Grids
+     424             :   bool grid_;
+     425             :   std::unique_ptr<GridBase> BiasGrid_;
+     426             :   OFile gridfile_;
+     427             :   bool storeOldGrids_;
+     428             :   int wgridstride_;
+     429             :   // multiple walkers
+     430             :   int mw_n_;
+     431             :   std::string mw_dir_;
+     432             :   int mw_id_;
+     433             :   int mw_rstride_;
+     434             :   bool walkers_mpi_;
+     435             :   unsigned mpi_nw_;
+     436             :   // flying gaussians
+     437             :   bool flying_;
+     438             :   // kinetics from metadynamics
+     439             :   bool acceleration_;
+     440             :   double acc_;
+     441             :   double acc_restart_mean_;
+     442             :   // transition-tempering metadynamics
+     443             :   bool calc_max_bias_;
+     444             :   double max_bias_;
+     445             :   bool calc_transition_bias_;
+     446             :   double transition_bias_;
+     447             :   std::vector<std::vector<double> > transitionwells_;
+     448             :   static const size_t n_tempering_options_ = 1;
+     449             :   static const std::string tempering_names_[1][2];
+     450             :   double dampfactor_;
+     451             :   struct TemperingSpecs tt_specs_;
+     452             :   std::string targetfilename_;
+     453             :   std::unique_ptr<GridBase> TargetGrid_;
+     454             :   // frequency adaptive metadynamics
+     455             :   int current_stride_;
+     456             :   bool freq_adaptive_;
+     457             :   int fa_update_frequency_;
+     458             :   int fa_max_stride_;
+     459             :   double fa_min_acceleration_;
+     460             :   // intervals
+     461             :   double uppI_;
+     462             :   double lowI_;
+     463             :   bool doInt_;
+     464             :   // reweighting
+     465             :   bool calc_rct_;
+     466             :   double reweight_factor_;
+     467             :   unsigned rct_ustride_;
+     468             :   // work
+     469             :   double work_;
+     470             :   // neighbour list stuff
+     471             :   bool nlist_;
+     472             :   bool nlist_update_;
+     473             :   unsigned nlist_steps_;
+     474             :   std::array<double,2> nlist_param_;
+     475             :   std::vector<Gaussian> nlist_hills_;
+     476             :   std::vector<double> nlist_center_;
+     477             :   std::vector<double> nlist_dev2_;
+     478             : 
+     479             :   double stretchA=1.0;
+     480             :   double stretchB=0.0;
+     481             : 
+     482             :   bool noStretchWarningDone=false;
+     483             : 
+     484          12 :   void noStretchWarning() {
+     485          12 :     if(!noStretchWarningDone) {
+     486           3 :       log<<"\nWARNING: you are using a HILLS file with Gaussian kernels, PLUMED 2.8 uses stretched Gaussians by default\n";
+     487             :     }
+     488          12 :     noStretchWarningDone=true;
+     489          12 :   }
+     490             : 
+     491             :   static void registerTemperingKeywords(const std::string &name_stem, const std::string &name, Keywords &keys);
+     492             :   void   readTemperingSpecs(TemperingSpecs &t_specs);
+     493             :   void   logTemperingSpecs(const TemperingSpecs &t_specs);
+     494             :   void   readGaussians(IFile*);
+     495             :   void   writeGaussian(const Gaussian&,OFile&);
+     496             :   void   addGaussian(const Gaussian&);
+     497             :   double getHeight(const std::vector<double>&);
+     498             :   void   temperHeight(double &height, const TemperingSpecs &t_specs, const double tempering_bias);
+     499             :   double getBias(const std::vector<double>&);
+     500             :   double getBiasAndDerivatives(const std::vector<double>&, std::vector<double>&);
+     501             :   double evaluateGaussian(const std::vector<double>&, const Gaussian&);
+     502             :   double evaluateGaussianAndDerivatives(const std::vector<double>&, const Gaussian&,std::vector<double>&,std::vector<double>&);
+     503             :   double getGaussianNormalization(const Gaussian&);
+     504             :   std::vector<unsigned> getGaussianSupport(const Gaussian&);
+     505             :   bool   scanOneHill(IFile* ifile, std::vector<Value>& v, std::vector<double>& center, std::vector<double>& sigma, double& height, bool& multivariate);
+     506             :   void   computeReweightingFactor();
+     507             :   double getTransitionBarrierBias();
+     508             :   void   updateFrequencyAdaptiveStride();
+     509             :   void   updateNlist();
+     510             : 
+     511             : public:
+     512             :   explicit MetaD(const ActionOptions&);
+     513             :   void calculate() override;
+     514             :   void update() override;
+     515             :   static void registerKeywords(Keywords& keys);
+     516             :   bool checkNeedsGradients()const override;
+     517             : };
+     518             : 
+     519             : PLUMED_REGISTER_ACTION(MetaD,"METAD")
+     520             : 
+     521         159 : void MetaD::registerKeywords(Keywords& keys) {
+     522         159 :   Bias::registerKeywords(keys);
+     523         318 :   keys.addOutputComponent("rbias","CALC_RCT","the instantaneous value of the bias normalized using the c(t) reweighting factor [rbias=bias-rct]."
+     524             :                           "This component can be used to obtain a reweighted histogram.");
+     525         318 :   keys.addOutputComponent("rct","CALC_RCT","the reweighting factor \\f$c(t)\\f$.");
+     526         318 :   keys.addOutputComponent("work","CALC_WORK","accumulator for work");
+     527         318 :   keys.addOutputComponent("acc","ACCELERATION","the metadynamics acceleration factor");
+     528         318 :   keys.addOutputComponent("maxbias", "CALC_MAX_BIAS", "the maximum of the metadynamics V(s, t)");
+     529         318 :   keys.addOutputComponent("transbias", "CALC_TRANSITION_BIAS", "the metadynamics transition bias V*(t)");
+     530         318 :   keys.addOutputComponent("pace","FREQUENCY_ADAPTIVE","the hill addition frequency when employing frequency adaptive metadynamics");
+     531         318 :   keys.addOutputComponent("nlker","NLIST","number of hills in the neighbor list");
+     532         318 :   keys.addOutputComponent("nlsteps","NLIST","number of steps from last neighbor list update");
+     533         159 :   keys.use("ARG");
+     534         318 :   keys.add("compulsory","SIGMA","the widths of the Gaussian hills");
+     535         318 :   keys.add("compulsory","PACE","the frequency for hill addition");
+     536         318 :   keys.add("compulsory","FILE","HILLS","a file in which the list of added hills is stored");
+     537         318 :   keys.add("optional","HEIGHT","the heights of the Gaussian hills. Compulsory unless TAU and either BIASFACTOR or DAMPFACTOR are given");
+     538         318 :   keys.add("optional","FMT","specify format for HILLS files (useful for decrease the number of digits in regtests)");
+     539         318 :   keys.add("optional","BIASFACTOR","use well tempered metadynamics and use this bias factor.  Please note you must also specify temp");
+     540         318 :   keys.addFlag("CALC_WORK",false,"calculate the total accumulated work done by the bias since last restart");
+     541         318 :   keys.add("optional","RECT","list of bias factors for all the replicas");
+     542         318 :   keys.add("optional","DAMPFACTOR","damp hills with exp(-max(V)/(kT*DAMPFACTOR)");
+     543         318 :   for (size_t i = 0; i < n_tempering_options_; i++) {
+     544         159 :     registerTemperingKeywords(tempering_names_[i][0], tempering_names_[i][1], keys);
+     545             :   }
+     546         318 :   keys.add("optional","TARGET","target to a predefined distribution");
+     547         318 :   keys.add("optional","TEMP","the system temperature - this is only needed if you are doing well-tempered metadynamics");
+     548         318 :   keys.add("optional","TAU","in well tempered metadynamics, sets height to (k_B Delta T*pace*timestep)/tau");
+     549         318 :   keys.addFlag("CALC_RCT",false,"calculate the c(t) reweighting factor and use that to obtain the normalized bias [rbias=bias-rct]."
+     550             :                "This method is not compatible with metadynamics not on a grid.");
+     551         318 :   keys.add("optional","RCT_USTRIDE","the update stride for calculating the \\f$c(t)\\f$ reweighting factor."
+     552             :            "The default 1, so \\f$c(t)\\f$ is updated every time the bias is updated.");
+     553         318 :   keys.add("optional","GRID_MIN","the lower bounds for the grid");
+     554         318 :   keys.add("optional","GRID_MAX","the upper bounds for the grid");
+     555         318 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     556         318 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     557         318 :   keys.addFlag("GRID_SPARSE",false,"use a sparse grid to store hills");
+     558         318 :   keys.addFlag("GRID_NOSPLINE",false,"don't use spline interpolation with grids");
+     559         318 :   keys.add("optional","GRID_WSTRIDE","write the grid to a file every N steps");
+     560         318 :   keys.add("optional","GRID_WFILE","the file on which to write the grid");
+     561         318 :   keys.add("optional","GRID_RFILE","a grid file from which the bias should be read at the initial step of the simulation");
+     562         318 :   keys.addFlag("STORE_GRIDS",false,"store all the grid files the calculation generates. They will be deleted if this keyword is not present");
+     563         318 :   keys.addFlag("NLIST",false,"Use neighbor list for kernels summation, faster but experimental");
+     564         318 :   keys.add("optional", "NLIST_PARAMETERS","(default=6.,0.5) the two cutoff parameters for the Gaussians neighbor list");
+     565         318 :   keys.add("optional","ADAPTIVE","use a geometric (=GEOM) or diffusion (=DIFF) based hills width scheme. Sigma is one number that has distance units or time step dimensions");
+     566         318 :   keys.add("optional","SIGMA_MAX","the upper bounds for the sigmas (in CV units) when using adaptive hills. Negative number means no bounds ");
+     567         318 :   keys.add("optional","SIGMA_MIN","the lower bounds for the sigmas (in CV units) when using adaptive hills. Negative number means no bounds ");
+     568         318 :   keys.add("optional","WALKERS_ID", "walker id");
+     569         318 :   keys.add("optional","WALKERS_N", "number of walkers");
+     570         318 :   keys.add("optional","WALKERS_DIR", "shared directory with the hills files from all the walkers");
+     571         318 :   keys.add("optional","WALKERS_RSTRIDE","stride for reading hills files");
+     572         318 :   keys.addFlag("WALKERS_MPI",false,"Switch on MPI version of multiple walkers - not compatible with WALKERS_* options other than WALKERS_DIR");
+     573         318 :   keys.add("optional","INTERVAL","one dimensional lower and upper limits, outside the limits the system will not feel the biasing force.");
+     574         318 :   keys.addFlag("FLYING_GAUSSIAN",false,"Switch on flying Gaussian method, must be used with WALKERS_MPI");
+     575         318 :   keys.addFlag("ACCELERATION",false,"Set to TRUE if you want to compute the metadynamics acceleration factor.");
+     576         318 :   keys.add("optional","ACCELERATION_RFILE","a data file from which the acceleration should be read at the initial step of the simulation");
+     577         318 :   keys.addFlag("CALC_MAX_BIAS", false, "Set to TRUE if you want to compute the maximum of the metadynamics V(s, t)");
+     578         318 :   keys.addFlag("CALC_TRANSITION_BIAS", false, "Set to TRUE if you want to compute a metadynamics transition bias V*(t)");
+     579         318 :   keys.add("numbered", "TRANSITIONWELL", "This keyword appears multiple times as TRANSITIONWELL followed by an integer. Each specifies the coordinates for one well as in transition-tempered metadynamics. At least one must be provided.");
+     580         318 :   keys.addFlag("FREQUENCY_ADAPTIVE",false,"Set to TRUE if you want to enable frequency adaptive metadynamics such that the frequency for hill addition to change dynamically based on the acceleration factor.");
+     581         318 :   keys.add("optional","FA_UPDATE_FREQUENCY","the frequency for updating the hill addition pace in frequency adaptive metadynamics, by default this is equal to the value given in PACE");
+     582         318 :   keys.add("optional","FA_MAX_PACE","the maximum hill addition frequency allowed in frequency adaptive metadynamics. By default there is no maximum value.");
+     583         318 :   keys.add("optional","FA_MIN_ACCELERATION","only update the hill addition pace in frequency adaptive metadynamics after reaching the minimum acceleration factor given here. By default it is 1.0.");
+     584         159 :   keys.use("RESTART");
+     585         159 :   keys.use("UPDATE_FROM");
+     586         159 :   keys.use("UPDATE_UNTIL");
+     587         159 : }
+     588             : 
+     589             : const std::string MetaD::tempering_names_[1][2] = {{"TT", "transition tempered"}};
+     590             : 
+     591         159 : void MetaD::registerTemperingKeywords(const std::string &name_stem, const std::string &name, Keywords &keys) {
+     592         318 :   keys.add("optional", name_stem + "BIASFACTOR", "use " + name + " metadynamics with this bias factor.  Please note you must also specify temp");
+     593         318 :   keys.add("optional", name_stem + "BIASTHRESHOLD", "use " + name + " metadynamics with this bias threshold.  Please note you must also specify " + name_stem + "BIASFACTOR");
+     594         318 :   keys.add("optional", name_stem + "ALPHA", "use " + name + " metadynamics with this hill size decay exponent parameter.  Please note you must also specify " + name_stem + "BIASFACTOR");
+     595         159 : }
+     596             : 
+     597         157 : MetaD::MetaD(const ActionOptions& ao):
+     598             :   PLUMED_BIAS_INIT(ao),
+     599         156 :   kbt_(0.0),
+     600         156 :   stride_(0),
+     601         156 :   calc_work_(false),
+     602         156 :   welltemp_(false),
+     603         156 :   biasf_(-1.0),
+     604         156 :   isFirstStep_(true),
+     605         156 :   height0_(std::numeric_limits<double>::max()),
+     606         156 :   adaptive_(FlexibleBin::none),
+     607         156 :   grid_(false),
+     608         156 :   wgridstride_(0),
+     609         156 :   mw_n_(1), mw_dir_(""), mw_id_(0), mw_rstride_(1),
+     610         156 :   walkers_mpi_(false), mpi_nw_(0),
+     611         156 :   flying_(false),
+     612         156 :   acceleration_(false), acc_(0.0), acc_restart_mean_(0.0),
+     613         156 :   calc_max_bias_(false), max_bias_(0.0),
+     614         156 :   calc_transition_bias_(false), transition_bias_(0.0),
+     615         156 :   dampfactor_(0.0),
+     616         312 :   tt_specs_(false, "TT", "Transition Tempered", -1.0, 0.0, 1.0),
+     617         156 :   current_stride_(0),
+     618         156 :   freq_adaptive_(false),
+     619         156 :   fa_update_frequency_(0),
+     620         156 :   fa_max_stride_(0),
+     621         156 :   fa_min_acceleration_(1.0),
+     622         156 :   uppI_(-1), lowI_(-1), doInt_(false),
+     623         156 :   calc_rct_(false),
+     624         156 :   reweight_factor_(0.0),
+     625         156 :   rct_ustride_(1),
+     626         156 :   work_(0),
+     627         156 :   nlist_(false),
+     628         156 :   nlist_update_(false),
+     629         469 :   nlist_steps_(0)
+     630             : {
+     631         156 :   if(!dp2cutoffNoStretch()) {
+     632         156 :     stretchA=dp2cutoffA;
+     633         156 :     stretchB=dp2cutoffB;
+     634             :   }
+     635             :   // parse the flexible hills
+     636             :   std::string adaptiveoption;
+     637             :   adaptiveoption="NONE";
+     638         312 :   parse("ADAPTIVE",adaptiveoption);
+     639         156 :   if(adaptiveoption=="GEOM") {
+     640          22 :     log.printf("  Uses Geometry-based hills width: sigma must be in distance units and only one sigma is needed\n");
+     641          22 :     adaptive_=FlexibleBin::geometry;
+     642         134 :   } else if(adaptiveoption=="DIFF") {
+     643           3 :     log.printf("  Uses Diffusion-based hills width: sigma must be in time steps and only one sigma is needed\n");
+     644           3 :     adaptive_=FlexibleBin::diffusion;
+     645         131 :   } else if(adaptiveoption=="NONE") {
+     646         130 :     adaptive_=FlexibleBin::none;
+     647             :   } else {
+     648           1 :     error("I do not know this type of adaptive scheme");
+     649             :   }
+     650             : 
+     651         155 :   parse("FMT",fmt_);
+     652             : 
+     653             :   // parse the sigma
+     654         155 :   parseVector("SIGMA",sigma0_);
+     655         155 :   if(adaptive_==FlexibleBin::none) {
+     656             :     // if you use normal sigma you need one sigma per argument
+     657         130 :     if( sigma0_.size()!=getNumberOfArguments() ) error("number of arguments does not match number of SIGMA parameters");
+     658             :   } else {
+     659             :     // if you use flexible hills you need one sigma
+     660          25 :     if(sigma0_.size()!=1) {
+     661           1 :       error("If you choose ADAPTIVE you need only one sigma according to your choice of type (GEOM/DIFF)");
+     662             :     }
+     663             :     // if adaptive then the number must be an integer
+     664          24 :     if(adaptive_==FlexibleBin::diffusion) {
+     665           3 :       if(int(sigma0_[0])-sigma0_[0]>1.e-9 || int(sigma0_[0])-sigma0_[0] <-1.e-9 || int(sigma0_[0])<1 ) {
+     666           0 :         error("In case of adaptive hills with diffusion, the sigma must be an integer which is the number of time steps\n");
+     667             :       }
+     668             :     }
+     669             :     // here evtl parse the sigma min and max values
+     670          48 :     parseVector("SIGMA_MIN",sigma0min_);
+     671          24 :     if(sigma0min_.size()>0 && sigma0min_.size()!=getNumberOfArguments()) {
+     672           1 :       error("the number of SIGMA_MIN values be the same of the number of the arguments");
+     673          23 :     } else if(sigma0min_.size()==0) {
+     674          23 :       sigma0min_.resize(getNumberOfArguments());
+     675          67 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {sigma0min_[i]=-1.;}
+     676             :     }
+     677             : 
+     678          46 :     parseVector("SIGMA_MAX",sigma0max_);
+     679          23 :     if(sigma0max_.size()>0 && sigma0max_.size()!=getNumberOfArguments()) {
+     680           1 :       error("the number of SIGMA_MAX values be the same of the number of the arguments");
+     681          22 :     } else if(sigma0max_.size()==0) {
+     682          22 :       sigma0max_.resize(getNumberOfArguments());
+     683          64 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {sigma0max_[i]=-1.;}
+     684             :     }
+     685             : 
+     686          44 :     flexbin_=Tools::make_unique<FlexibleBin>(adaptive_,this,sigma0_[0],sigma0min_,sigma0max_);
+     687             :   }
+     688             : 
+     689             :   // note: HEIGHT is not compulsory, since one could use the TAU keyword, see below
+     690         152 :   parse("HEIGHT",height0_);
+     691         152 :   parse("PACE",stride_);
+     692         151 :   if(stride_<=0) error("frequency for hill addition is nonsensical");
+     693         151 :   current_stride_ = stride_;
+     694         159 :   std::string hillsfname="HILLS";
+     695         151 :   parse("FILE",hillsfname);
+     696             : 
+     697             :   // Manually set to calculate special bias quantities
+     698             :   // throughout the course of simulation. (These are chosen due to
+     699             :   // relevance for tempering and event-driven logic as well.)
+     700         151 :   parseFlag("CALC_MAX_BIAS", calc_max_bias_);
+     701         305 :   parseFlag("CALC_TRANSITION_BIAS", calc_transition_bias_);
+     702             : 
+     703             :   std::vector<double> rect_biasf_;
+     704         302 :   parseVector("RECT",rect_biasf_);
+     705         151 :   if(rect_biasf_.size()>0) {
+     706          18 :     int r=0;
+     707          18 :     if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+     708          18 :     comm.Bcast(r,0);
+     709          18 :     biasf_=rect_biasf_[r];
+     710          18 :     log<<"  You are using RECT\n";
+     711             :   } else {
+     712         266 :     parse("BIASFACTOR",biasf_);
+     713             :   }
+     714         151 :   if( biasf_<1.0  && biasf_!=-1.0) error("well tempered bias factor is nonsensical");
+     715         302 :   parse("DAMPFACTOR",dampfactor_); kbt_=getkBT();
+     716         151 :   if(biasf_>=1.0) {
+     717          38 :     if(kbt_==0.0) error("Unless the MD engine passes the temperature to plumed, with well-tempered metad you must specify it using TEMP");
+     718          38 :     welltemp_=true;
+     719             :   }
+     720         151 :   if(dampfactor_>0.0) {
+     721           2 :     if(kbt_==0.0) error("Unless the MD engine passes the temperature to plumed, with damped metad you must specify it using TEMP");
+     722             :   }
+     723             : 
+     724         151 :   parseFlag("CALC_WORK",calc_work_);
+     725             : 
+     726             :   // Set transition tempering parameters.
+     727             :   // Transition wells are read later via calc_transition_bias_.
+     728         151 :   readTemperingSpecs(tt_specs_);
+     729         151 :   if (tt_specs_.is_active) calc_transition_bias_ = true;
+     730             : 
+     731             :   // If any previous option specified to calculate a transition bias,
+     732             :   // now read the transition wells for that quantity.
+     733         151 :   if (calc_transition_bias_) {
+     734          13 :     std::vector<double> tempcoords(getNumberOfArguments());
+     735          26 :     for (unsigned i = 0; ; i++) {
+     736          78 :       if (!parseNumberedVector("TRANSITIONWELL", i, tempcoords) ) break;
+     737          26 :       if (tempcoords.size() != getNumberOfArguments()) {
+     738           0 :         error("incorrect number of coordinates for transition tempering well");
+     739             :       }
+     740          26 :       transitionwells_.push_back(tempcoords);
+     741             :     }
+     742             :   }
+     743             : 
+     744         302 :   parse("TARGET",targetfilename_);
+     745         151 :   if(targetfilename_.length()>0 && kbt_==0.0)  error("with TARGET temperature must be specified");
+     746         151 :   double tau=0.0;
+     747         151 :   parse("TAU",tau);
+     748         151 :   if(tau==0.0) {
+     749         129 :     if(height0_==std::numeric_limits<double>::max()) error("At least one between HEIGHT and TAU should be specified");
+     750             :     // if tau is not set, we compute it here from the other input parameters
+     751         129 :     if(welltemp_) tau=(kbt_*(biasf_-1.0))/height0_*getTimeStep()*stride_;
+     752         110 :     else if(dampfactor_>0.0) tau=(kbt_*dampfactor_)/height0_*getTimeStep()*stride_;
+     753             :   } else {
+     754          22 :     if(height0_!=std::numeric_limits<double>::max()) error("At most one between HEIGHT and TAU should be specified");
+     755          22 :     if(welltemp_) {
+     756          19 :       if(biasf_!=1.0) height0_=(kbt_*(biasf_-1.0))/tau*getTimeStep()*stride_;
+     757           4 :       else           height0_=kbt_/tau*getTimeStep()*stride_; // special case for gamma=1
+     758             :     }
+     759           3 :     else if(dampfactor_>0.0) height0_=(kbt_*dampfactor_)/tau*getTimeStep()*stride_;
+     760           1 :     else error("TAU only makes sense in well-tempered or damped metadynamics");
+     761             :   }
+     762             : 
+     763             :   // Grid Stuff
+     764         153 :   std::vector<std::string> gmin(getNumberOfArguments());
+     765         300 :   parseVector("GRID_MIN",gmin);
+     766         150 :   if(gmin.size()!=getNumberOfArguments() && gmin.size()!=0) error("not enough values for GRID_MIN");
+     767         150 :   std::vector<std::string> gmax(getNumberOfArguments());
+     768         300 :   parseVector("GRID_MAX",gmax);
+     769         150 :   if(gmax.size()!=getNumberOfArguments() && gmax.size()!=0) error("not enough values for GRID_MAX");
+     770         150 :   std::vector<unsigned> gbin(getNumberOfArguments());
+     771             :   std::vector<double>   gspacing;
+     772         300 :   parseVector("GRID_BIN",gbin);
+     773         150 :   if(gbin.size()!=getNumberOfArguments() && gbin.size()!=0) error("not enough values for GRID_BIN");
+     774         300 :   parseVector("GRID_SPACING",gspacing);
+     775         150 :   if(gspacing.size()!=getNumberOfArguments() && gspacing.size()!=0) error("not enough values for GRID_SPACING");
+     776         150 :   if(gmin.size()!=gmax.size()) error("GRID_MAX and GRID_MIN should be either present or absent");
+     777         150 :   if(gspacing.size()!=0 && gmin.size()==0) error("If GRID_SPACING is present also GRID_MIN and GRID_MAX should be present");
+     778         150 :   if(gbin.size()!=0     && gmin.size()==0) error("If GRID_BIN is present also GRID_MIN and GRID_MAX should be present");
+     779         150 :   if(gmin.size()!=0) {
+     780          61 :     if(gbin.size()==0 && gspacing.size()==0) {
+     781           6 :       if(adaptive_==FlexibleBin::none) {
+     782           6 :         log<<"  Binsize not specified, 1/5 of sigma will be be used\n";
+     783           6 :         plumed_assert(sigma0_.size()==getNumberOfArguments());
+     784           6 :         gspacing.resize(getNumberOfArguments());
+     785          13 :         for(unsigned i=0; i<gspacing.size(); i++) gspacing[i]=0.2*sigma0_[i];
+     786             :       } else {
+     787             :         // with adaptive hills and grid a sigma min must be specified
+     788           0 :         for(unsigned i=0; i<sigma0min_.size(); i++) if(sigma0min_[i]<=0) error("When using ADAPTIVE Gaussians on a grid SIGMA_MIN must be specified");
+     789           0 :         log<<"  Binsize not specified, 1/5 of sigma_min will be be used\n";
+     790           0 :         gspacing.resize(getNumberOfArguments());
+     791           0 :         for(unsigned i=0; i<gspacing.size(); i++) gspacing[i]=0.2*sigma0min_[i];
+     792             :       }
+     793          55 :     } else if(gspacing.size()!=0 && gbin.size()==0) {
+     794           2 :       log<<"  The number of bins will be estimated from GRID_SPACING\n";
+     795          53 :     } else if(gspacing.size()!=0 && gbin.size()!=0) {
+     796           1 :       log<<"  You specified both GRID_BIN and GRID_SPACING\n";
+     797           1 :       log<<"  The more conservative (highest) number of bins will be used for each variable\n";
+     798             :     }
+     799          61 :     if(gbin.size()==0) gbin.assign(getNumberOfArguments(),1);
+     800          73 :     if(gspacing.size()!=0) for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     801             :         double a,b;
+     802          13 :         Tools::convert(gmin[i],a);
+     803          12 :         Tools::convert(gmax[i],b);
+     804          12 :         unsigned n=std::ceil(((b-a)/gspacing[i]));
+     805          12 :         if(gbin[i]<n) gbin[i]=n;
+     806             :       }
+     807             :   }
+     808         149 :   if(gbin.size()>0) grid_=true;
+     809             : 
+     810         149 :   bool sparsegrid=false;
+     811         149 :   parseFlag("GRID_SPARSE",sparsegrid);
+     812         149 :   bool nospline=false;
+     813         149 :   parseFlag("GRID_NOSPLINE",nospline);
+     814         149 :   bool spline=!nospline;
+     815         300 :   parse("GRID_WSTRIDE",wgridstride_);
+     816             :   std::string gridfilename_;
+     817         149 :   parse("GRID_WFILE",gridfilename_);
+     818         149 :   parseFlag("STORE_GRIDS",storeOldGrids_);
+     819         149 :   if(grid_ && gridfilename_.length()>0) {
+     820          19 :     if(wgridstride_==0 ) error("frequency with which to output grid not specified use GRID_WSTRIDE");
+     821             :   }
+     822         149 :   if(grid_ && wgridstride_>0) {
+     823          20 :     if(gridfilename_.length()==0) error("grid filename not specified use GRID_WFILE");
+     824             :   }
+     825             : 
+     826             :   std::string gridreadfilename_;
+     827         149 :   parse("GRID_RFILE",gridreadfilename_);
+     828             : 
+     829         149 :   if(!grid_&&gridfilename_.length()> 0) error("To write a grid you need first to define it!");
+     830         149 :   if(!grid_&&gridreadfilename_.length()>0) error("To read a grid you need first to define it!");
+     831             : 
+     832             :   /*setup neighbor list stuff*/
+     833         298 :   parseFlag("NLIST", nlist_);
+     834         149 :   nlist_center_.resize(getNumberOfArguments());
+     835         149 :   nlist_dev2_.resize(getNumberOfArguments());
+     836         150 :   if(nlist_&&grid_) error("NLIST and GRID cannot be combined!");
+     837             :   std::vector<double> nlist_param;
+     838         298 :   parseVector("NLIST_PARAMETERS",nlist_param);
+     839         149 :   if(nlist_param.size()==0)
+     840             :   {
+     841         149 :     nlist_param_[0]=6.0;//*DP2CUTOFF -> max distance of neighbors
+     842         149 :     nlist_param_[1]=0.5;//*nlist_dev2_[i] -> condition for rebuilding
+     843             :   }
+     844             :   else
+     845             :   {
+     846           0 :     plumed_massert(nlist_param.size()==2,"two cutoff parameters are needed for the neighbor list");
+     847           0 :     plumed_massert(nlist_param[0]>1.0,"the first of NLIST_PARAMETERS must be greater than 1. The smaller the first, the smaller should be the second as well");
+     848           0 :     const double min_PARAM_1=(1.-1./std::sqrt(nlist_param[0]/2))+0.16;
+     849           0 :     plumed_massert(nlist_param[1]>0,"the second of NLIST_PARAMETERS must be greater than 0");
+     850           0 :     plumed_massert(nlist_param[1]<=min_PARAM_1,"the second of NLIST_PARAMETERS must be smaller to avoid systematic errors. Largest suggested value is: 1.16-1/sqrt(PARAM_0/2) = "+std::to_string(min_PARAM_1));
+     851           0 :     nlist_param_[0]=nlist_param[0];
+     852           0 :     nlist_param_[1]=nlist_param[1];
+     853             :   }
+     854             : 
+     855             :   // Reweighting factor rct
+     856         149 :   parseFlag("CALC_RCT",calc_rct_);
+     857         149 :   if (calc_rct_) plumed_massert(grid_,"CALC_RCT is supported only if bias is on a grid");
+     858         149 :   parse("RCT_USTRIDE",rct_ustride_);
+     859             : 
+     860         149 :   if(dampfactor_>0.0) {
+     861           2 :     if(!grid_) error("With DAMPFACTOR you should use grids");
+     862             :   }
+     863             : 
+     864             :   // Multiple walkers
+     865         149 :   parse("WALKERS_N",mw_n_);
+     866         149 :   parse("WALKERS_ID",mw_id_);
+     867         149 :   if(mw_n_<=mw_id_) error("walker ID should be a numerical value less than the total number of walkers");
+     868         149 :   parse("WALKERS_DIR",mw_dir_);
+     869         149 :   parse("WALKERS_RSTRIDE",mw_rstride_);
+     870             : 
+     871             :   // MPI version
+     872         149 :   parseFlag("WALKERS_MPI",walkers_mpi_);
+     873             : 
+     874             :   //If this Action is not compiled with MPI the user is informed and we exit gracefully
+     875         149 :   if(walkers_mpi_) {
+     876          39 :     plumed_assert(Communicator::plumedHasMPI()) << "Invalid walkers configuration: WALKERS_MPI flag requires MPI compilation";
+     877          40 :     plumed_assert(Communicator::initialized()) << "Invalid walkers configuration: WALKERS_MPI needs the communicator correctly initialized.";
+     878             :   }
+     879             : 
+     880             :   // Flying Gaussian
+     881         148 :   parseFlag("FLYING_GAUSSIAN", flying_);
+     882             : 
+     883             :   // Inteval keyword
+     884         149 :   std::vector<double> tmpI(2);
+     885         296 :   parseVector("INTERVAL",tmpI);
+     886         148 :   if(tmpI.size()!=2&&tmpI.size()!=0) error("both a lower and an upper limits must be provided with INTERVAL");
+     887         148 :   else if(tmpI.size()==2) {
+     888           2 :     lowI_=tmpI.at(0);
+     889           2 :     uppI_=tmpI.at(1);
+     890           2 :     if(getNumberOfArguments()!=1) error("INTERVAL limits correction works only for monodimensional metadynamics!");
+     891           2 :     if(uppI_<lowI_) error("The Upper limit must be greater than the Lower limit!");
+     892           2 :     if(getPntrToArgument(0)->isPeriodic()) error("INTERVAL cannot be used with periodic variables!");
+     893           2 :     doInt_=true;
+     894             :   }
+     895             : 
+     896         296 :   parseFlag("ACCELERATION",acceleration_);
+     897             :   // Check for a restart acceleration if acceleration is active.
+     898             :   std::string acc_rfilename;
+     899         148 :   if(acceleration_) {
+     900           8 :     parse("ACCELERATION_RFILE", acc_rfilename);
+     901             :   }
+     902             : 
+     903         148 :   freq_adaptive_=false;
+     904         148 :   parseFlag("FREQUENCY_ADAPTIVE",freq_adaptive_);
+     905             :   //
+     906         148 :   fa_update_frequency_=0;
+     907         148 :   parse("FA_UPDATE_FREQUENCY",fa_update_frequency_);
+     908         148 :   if(fa_update_frequency_!=0 && !freq_adaptive_) {
+     909           0 :     plumed_merror("It doesn't make sense to use the FA_MAX_PACE keyword if frequency adaptive METAD hasn't been activated by using the FREQUENCY_ADAPTIVE flag");
+     910             :   }
+     911         148 :   if(fa_update_frequency_==0 && freq_adaptive_) {
+     912           0 :     fa_update_frequency_=stride_;
+     913             :   }
+     914             :   //
+     915         148 :   fa_max_stride_=0;
+     916         148 :   parse("FA_MAX_PACE",fa_max_stride_);
+     917         148 :   if(fa_max_stride_!=0 && !freq_adaptive_) {
+     918           0 :     plumed_merror("It doesn't make sense to use the FA_MAX_PACE keyword if frequency adaptive METAD hasn't been activated by using the FREQUENCY_ADAPTIVE flag");
+     919             :   }
+     920             :   //
+     921         148 :   fa_min_acceleration_=1.0;
+     922         148 :   parse("FA_MIN_ACCELERATION",fa_min_acceleration_);
+     923         148 :   if(fa_min_acceleration_!=1.0 && !freq_adaptive_) {
+     924           0 :     plumed_merror("It doesn't make sense to use the FA_MIN_ACCELERATION keyword if frequency adaptive METAD hasn't been activated by using the FREQUENCY_ADAPTIVE flag");
+     925             :   }
+     926             : 
+     927         148 :   checkRead();
+     928             : 
+     929         148 :   log.printf("  Gaussian width ");
+     930         148 :   if (adaptive_==FlexibleBin::diffusion)log.printf(" (Note: The units of sigma are in timesteps) ");
+     931         148 :   if (adaptive_==FlexibleBin::geometry)log.printf(" (Note: The units of sigma are in dist units) ");
+     932         396 :   for(unsigned i=0; i<sigma0_.size(); ++i) log.printf(" %f",sigma0_[i]);
+     933         148 :   log.printf("  Gaussian height %f\n",height0_);
+     934         148 :   log.printf("  Gaussian deposition pace %d\n",stride_);
+     935         148 :   log.printf("  Gaussian file %s\n",hillsfname.c_str());
+     936         148 :   if(welltemp_) {
+     937          38 :     log.printf("  Well-Tempered Bias Factor %f\n",biasf_);
+     938          38 :     log.printf("  Hills relaxation time (tau) %f\n",tau);
+     939          38 :     log.printf("  KbT %f\n",kbt_);
+     940             :   }
+     941             : 
+     942             :   // Transition tempered metadynamics options
+     943         148 :   if (tt_specs_.is_active) {
+     944           3 :     logTemperingSpecs(tt_specs_);
+     945             :     // Check that the appropriate transition bias quantity is calculated.
+     946             :     // (Should never trip, given that the flag is automatically set.)
+     947           3 :     if (!calc_transition_bias_) {
+     948           0 :       error(" transition tempering requires calculation of a transition bias");
+     949             :     }
+     950             :   }
+     951             : 
+     952             :   // Overall tempering sanity check (this gets tricky when multiple are active).
+     953             :   // When multiple temperings are active, it's fine to have one tempering attempt
+     954             :   // to increase hill size with increasing bias, so long as the others can shrink
+     955             :   // the hills faster than it increases their size in the long-time limit.
+     956             :   // This set of checks ensures that the hill sizes eventually decay to zero as c(t)
+     957             :   // diverges to infinity.
+     958             :   // The alpha parameter allows hills to decay as 1/t^alpha instead of 1/t,
+     959             :   // a slower decay, so as t -> infinity, only the temperings with the largest
+     960             :   // alphas govern the final asymptotic decay. (Alpha helps prevent false convergence.)
+     961         148 :   if (welltemp_ || dampfactor_ > 0.0 || tt_specs_.is_active) {
+     962             :     // Determine the number of active temperings.
+     963             :     int n_active = 0;
+     964          43 :     if (welltemp_) n_active++;
+     965          43 :     if (dampfactor_ > 0.0) n_active++;
+     966          43 :     if (tt_specs_.is_active) n_active++;
+     967             :     // Find the greatest alpha.
+     968          43 :     double greatest_alpha = 0.0;
+     969          43 :     if (welltemp_) greatest_alpha = std::max(greatest_alpha, 1.0);
+     970          45 :     if (dampfactor_ > 0.0) greatest_alpha = std::max(greatest_alpha, 1.0);
+     971          46 :     if (tt_specs_.is_active) greatest_alpha = std::max(greatest_alpha, tt_specs_.alpha);
+     972             :     // Find the least alpha.
+     973          43 :     double least_alpha = 1.0;
+     974             :     if (welltemp_) least_alpha = std::min(least_alpha, 1.0);
+     975          43 :     if (dampfactor_ > 0.0) least_alpha = std::min(least_alpha, 1.0);
+     976          44 :     if (tt_specs_.is_active) least_alpha = std::min(least_alpha, tt_specs_.alpha);
+     977             :     // Find the inverse harmonic average of the delta T parameters for all
+     978             :     // of the temperings with the greatest alpha values.
+     979             :     double total_governing_deltaT_inv = 0.0;
+     980          43 :     if (welltemp_ && 1.0 == greatest_alpha && biasf_ != 1.0) total_governing_deltaT_inv += 1.0 / (biasf_ - 1.0);
+     981          43 :     if (dampfactor_ > 0.0 && 1.0 == greatest_alpha) total_governing_deltaT_inv += 1.0 / (dampfactor_);
+     982          43 :     if (tt_specs_.is_active && tt_specs_.alpha == greatest_alpha) total_governing_deltaT_inv += 1.0 / (tt_specs_.biasf - 1.0);
+     983             :     // Give a newbie-friendly error message for people using one tempering if
+     984             :     // only one is active.
+     985          43 :     if (n_active == 1 && total_governing_deltaT_inv < 0.0) {
+     986           0 :       error("for stable tempering, the bias factor must be greater than one");
+     987             :       // Give a slightly more complex error message to users stacking multiple
+     988             :       // tempering options at a time, but all with uniform alpha values.
+     989          43 :     } else if (total_governing_deltaT_inv < 0.0 && greatest_alpha == least_alpha) {
+     990           0 :       error("for stable tempering, the sum of the inverse Delta T parameters must be greater than zero!");
+     991             :       // Give the most technical error message to users stacking multiple tempering
+     992             :       // options with different alpha parameters.
+     993          43 :     } else if (total_governing_deltaT_inv < 0.0 && greatest_alpha != least_alpha) {
+     994           0 :       error("for stable tempering, the sum of the inverse Delta T parameters for the greatest asymptotic hill decay exponents must be greater than zero!");
+     995             :     }
+     996             :   }
+     997             : 
+     998         148 :   if(doInt_) log.printf("  Upper and Lower limits boundaries for the bias are activated at %f - %f\n", lowI_, uppI_);
+     999             : 
+    1000         148 :   if(grid_) {
+    1001          60 :     log.printf("  Grid min");
+    1002         161 :     for(unsigned i=0; i<gmin.size(); ++i) log.printf(" %s",gmin[i].c_str() );
+    1003          60 :     log.printf("\n");
+    1004          60 :     log.printf("  Grid max");
+    1005         161 :     for(unsigned i=0; i<gmax.size(); ++i) log.printf(" %s",gmax[i].c_str() );
+    1006          60 :     log.printf("\n");
+    1007          60 :     log.printf("  Grid bin");
+    1008         161 :     for(unsigned i=0; i<gbin.size(); ++i) log.printf(" %u",gbin[i]);
+    1009          60 :     log.printf("\n");
+    1010          60 :     if(spline) {log.printf("  Grid uses spline interpolation\n");}
+    1011          60 :     if(sparsegrid) {log.printf("  Grid uses sparse grid\n");}
+    1012          60 :     if(wgridstride_>0) {log.printf("  Grid is written on file %s with stride %d\n",gridfilename_.c_str(),wgridstride_);}
+    1013             :   }
+    1014             : 
+    1015         148 :   if(mw_n_>1) {
+    1016           6 :     if(walkers_mpi_) error("MPI version of multiple walkers is not compatible with filesystem version of multiple walkers");
+    1017           6 :     log.printf("  %d multiple walkers active\n",mw_n_);
+    1018           6 :     log.printf("  walker id %d\n",mw_id_);
+    1019           6 :     log.printf("  reading stride %d\n",mw_rstride_);
+    1020           6 :     if(mw_dir_!="")log.printf("  directory with hills files %s\n",mw_dir_.c_str());
+    1021             :   } else {
+    1022         142 :     if(walkers_mpi_) {
+    1023          38 :       log.printf("  Multiple walkers active using MPI communnication\n");
+    1024          38 :       if(mw_dir_!="")log.printf("  directory with hills files %s\n",mw_dir_.c_str());
+    1025          38 :       if(comm.Get_rank()==0) {
+    1026             :         // Only root of group can communicate with other walkers
+    1027          23 :         mpi_nw_=multi_sim_comm.Get_size();
+    1028             :       }
+    1029             :       // Communicate to the other members of the same group
+    1030             :       // info abount number of walkers and walker index
+    1031          38 :       comm.Bcast(mpi_nw_,0);
+    1032             :     }
+    1033             :   }
+    1034             : 
+    1035         148 :   if(flying_) {
+    1036           6 :     if(!walkers_mpi_) error("Flying Gaussian method must be used with MPI version of multiple walkers");
+    1037           6 :     log.printf("  Flying Gaussian method with %d walkers active\n",mpi_nw_);
+    1038             :   }
+    1039             : 
+    1040         148 :   if(nlist_) {
+    1041           2 :     addComponent("nlker");
+    1042           2 :     componentIsNotPeriodic("nlker");
+    1043           2 :     addComponent("nlsteps");
+    1044           2 :     componentIsNotPeriodic("nlsteps");
+    1045             :   }
+    1046             : 
+    1047         148 :   if(calc_rct_) {
+    1048          18 :     addComponent("rbias"); componentIsNotPeriodic("rbias");
+    1049          12 :     addComponent("rct"); componentIsNotPeriodic("rct");
+    1050           6 :     log.printf("  The c(t) reweighting factor will be calculated every %u hills\n",rct_ustride_);
+    1051          12 :     getPntrToComponent("rct")->set(reweight_factor_);
+    1052             :   }
+    1053             : 
+    1054         150 :   if(calc_work_) { addComponent("work"); componentIsNotPeriodic("work"); }
+    1055             : 
+    1056         148 :   if(acceleration_) {
+    1057           4 :     if (kbt_ == 0.0) {
+    1058           0 :       error("The calculation of the acceleration works only if simulation temperature has been defined");
+    1059             :     }
+    1060           4 :     log.printf("  calculation on the fly of the acceleration factor\n");
+    1061          12 :     addComponent("acc"); componentIsNotPeriodic("acc");
+    1062             :     // Set the initial value of the the acceleration.
+    1063             :     // If this is not a restart, set to 1.0.
+    1064           4 :     if (acc_rfilename.length() == 0) {
+    1065           4 :       getPntrToComponent("acc")->set(1.0);
+    1066           2 :       if(getRestart()) {
+    1067           1 :         log.printf("  WARNING: calculating the acceleration factor in a restarted run without reading in the previous value will most likely lead to incorrect results.\n");
+    1068           1 :         log.printf("           You should use the ACCELERATION_RFILE keyword.\n");
+    1069             :       }
+    1070             :       // Otherwise, read and set the restart value.
+    1071             :     } else {
+    1072             :       // Restart of acceleration does not make sense if the restart timestep is zero.
+    1073             :       //if (getStep() == 0) {
+    1074             :       //  error("Restarting calculation of acceleration factors works only if simulation timestep is restarted correctly");
+    1075             :       //}
+    1076             :       // Open the ACCELERATION_RFILE.
+    1077           2 :       IFile acc_rfile;
+    1078           2 :       acc_rfile.link(*this);
+    1079           2 :       if(acc_rfile.FileExist(acc_rfilename)) {
+    1080           2 :         acc_rfile.open(acc_rfilename);
+    1081             :       } else {
+    1082           0 :         error("The ACCELERATION_RFILE file you want to read: " + acc_rfilename + ", cannot be found!");
+    1083             :       }
+    1084             :       // Read the file to find the restart acceleration.
+    1085           2 :       double acc_rmean=0.0;
+    1086           2 :       double acc_rtime=0.0;
+    1087             :       bool found=false;
+    1088           2 :       std::string acclabel = getLabel() + ".acc";
+    1089           2 :       acc_rfile.allowIgnoredFields();
+    1090         248 :       while(acc_rfile.scanField("time", acc_rtime)) {
+    1091         122 :         acc_rfile.scanField(acclabel, acc_rmean);
+    1092         122 :         acc_rfile.scanField();
+    1093             :         found=true;
+    1094             :       }
+    1095           2 :       if(!found) error("The ACCELERATION_RFILE file you want to read: " + acc_rfilename + ", does not contain a time field!");
+    1096           2 :       acc_restart_mean_ = acc_rmean;
+    1097             :       // Set component based on the read values.
+    1098           2 :       getPntrToComponent("acc")->set(acc_rmean);
+    1099           2 :       log.printf("  initial acceleration factor read from file %s: value of %f at time %f\n",acc_rfilename.c_str(),acc_rmean,acc_rtime);
+    1100           2 :     }
+    1101             :   }
+    1102             : 
+    1103         148 :   if (calc_max_bias_) {
+    1104           0 :     if (!grid_) error("Calculating the maximum bias on the fly works only with a grid");
+    1105           0 :     log.printf("  calculation on the fly of the maximum bias max(V(s,t)) \n");
+    1106           0 :     addComponent("maxbias");
+    1107           0 :     componentIsNotPeriodic("maxbias");
+    1108             :   }
+    1109             : 
+    1110         148 :   if (calc_transition_bias_) {
+    1111          13 :     if (!grid_) error("Calculating the transition bias on the fly works only with a grid");
+    1112          13 :     log.printf("  calculation on the fly of the transition bias V*(t)\n");
+    1113          26 :     addComponent("transbias");
+    1114          13 :     componentIsNotPeriodic("transbias");
+    1115          13 :     log<<"  Number of transition wells "<<transitionwells_.size()<<"\n";
+    1116          13 :     if (transitionwells_.size() == 0) error("Calculating the transition bias on the fly requires definition of at least one transition well");
+    1117             :     // Check that a grid is in use.
+    1118          13 :     if (!grid_) error(" transition barrier finding requires a grid for the bias");
+    1119             :     // Log the wells and check that they are in the grid.
+    1120          39 :     for (unsigned i = 0; i < transitionwells_.size(); i++) {
+    1121             :       // Log the coordinate.
+    1122          26 :       log.printf("  Transition well %d at coordinate ", i);
+    1123          64 :       for (unsigned j = 0; j < getNumberOfArguments(); j++) log.printf("%f ", transitionwells_[i][j]);
+    1124          26 :       log.printf("\n");
+    1125             :       // Check that the coordinate is in the grid.
+    1126          64 :       for (unsigned j = 0; j < getNumberOfArguments(); j++) {
+    1127             :         double max, min;
+    1128          38 :         Tools::convert(gmin[j], min);
+    1129          38 :         Tools::convert(gmax[j], max);
+    1130          38 :         if (transitionwells_[i][j] < min || transitionwells_[i][j] > max) error(" transition well is not in grid");
+    1131             :       }
+    1132             :     }
+    1133             :   }
+    1134             : 
+    1135         148 :   if(freq_adaptive_) {
+    1136           2 :     if(!acceleration_) {
+    1137           0 :       plumed_merror("Frequency adaptive metadynamics only works if the calculation of the acceleration factor is enabled with the ACCELERATION keyword\n");
+    1138             :     }
+    1139           2 :     if(walkers_mpi_) {
+    1140           0 :       plumed_merror("Combining frequency adaptive metadynamics with MPI multiple walkers is not allowed");
+    1141             :     }
+    1142             : 
+    1143           2 :     log.printf("  Frequency adaptive metadynamics enabled\n");
+    1144           2 :     if(getRestart() && acc_rfilename.length() == 0) {
+    1145           0 :       log.printf("  WARNING: using the frequency adaptive scheme in a restarted run without reading in the previous value of the acceleration factor will most likely lead to incorrect results.\n");
+    1146           0 :       log.printf("           You should use the ACCELERATION_RFILE keyword.\n");
+    1147             :     }
+    1148           2 :     log.printf("  The frequency for hill addition will change dynamically based on the metadynamics acceleration factor\n");
+    1149           2 :     log.printf("  The hill addition frequency will be updated every %d steps\n",fa_update_frequency_);
+    1150           2 :     if(fa_min_acceleration_>1.0) {
+    1151           2 :       log.printf("  The hill addition frequency will only be updated once the metadynamics acceleration factor becomes larger than %.1f \n",fa_min_acceleration_);
+    1152             :     }
+    1153           2 :     if(fa_max_stride_!=0) {
+    1154           2 :       log.printf("  The hill addition frequency will not become larger than %d steps\n",fa_max_stride_);
+    1155             :     }
+    1156           4 :     addComponent("pace"); componentIsNotPeriodic("pace");
+    1157           2 :     updateFrequencyAdaptiveStride();
+    1158             :   }
+    1159             : 
+    1160             :   // initializing and checking grid
+    1161             :   bool restartedFromGrid=false;  // restart from grid file
+    1162         148 :   if(grid_) {
+    1163          60 :     if(!(gridreadfilename_.length()>0)) {
+    1164             :       // check for mesh and sigma size
+    1165         116 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+    1166             :         double a,b;
+    1167          74 :         Tools::convert(gmin[i],a);
+    1168          74 :         Tools::convert(gmax[i],b);
+    1169          74 :         double mesh=(b-a)/((double)gbin[i]);
+    1170          74 :         if(adaptive_==FlexibleBin::none) {
+    1171          74 :           if(mesh>0.5*sigma0_[i]) log<<"  WARNING: Using a METAD with a Grid Spacing larger than half of the Gaussians width (SIGMA) can produce artifacts\n";
+    1172             :         } else {
+    1173           0 :           if(sigma0min_[i]<0.) error("When using ADAPTIVE Gaussians on a grid SIGMA_MIN must be specified");
+    1174           0 :           if(mesh>0.5*sigma0min_[i]) log<<"  WARNING: to use a METAD with a GRID and ADAPTIVE you need to set a Grid Spacing lower than half of the Gaussians (SIGMA_MIN) \n";
+    1175             :         }
+    1176             :       }
+    1177          42 :       std::string funcl=getLabel() + ".bias";
+    1178          42 :       if(!sparsegrid) {BiasGrid_=Tools::make_unique<Grid>(funcl,getArguments(),gmin,gmax,gbin,spline,true);}
+    1179           6 :       else {BiasGrid_=Tools::make_unique<SparseGrid>(funcl,getArguments(),gmin,gmax,gbin,spline,true);}
+    1180          42 :       std::vector<std::string> actualmin=BiasGrid_->getMin();
+    1181          42 :       std::vector<std::string> actualmax=BiasGrid_->getMax();
+    1182         116 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+    1183             :         std::string is;
+    1184          74 :         Tools::convert(i,is);
+    1185          74 :         if(gmin[i]!=actualmin[i]) error("GRID_MIN["+is+"] must be adjusted to "+actualmin[i]+" to fit periodicity");
+    1186          74 :         if(gmax[i]!=actualmax[i]) error("GRID_MAX["+is+"] must be adjusted to "+actualmax[i]+" to fit periodicity");
+    1187             :       }
+    1188          42 :     } else {
+    1189             :       // read the grid in input, find the keys
+    1190          18 :       if(walkers_mpi_&&gridreadfilename_.at(0)!='/') {
+    1191             :         //if possible the root replica will share its current folder so that all walkers will read the same file
+    1192           0 :         const std::string ret = std::filesystem::current_path();
+    1193           0 :         gridreadfilename_ = "/" + gridreadfilename_;
+    1194           0 :         gridreadfilename_ = ret + gridreadfilename_;
+    1195           0 :         if(comm.Get_rank()==0) multi_sim_comm.Bcast(gridreadfilename_,0);
+    1196           0 :         comm.Bcast(gridreadfilename_,0);
+    1197             :       }
+    1198          18 :       IFile gridfile;
+    1199          18 :       gridfile.link(*this);
+    1200          18 :       if(gridfile.FileExist(gridreadfilename_)) {
+    1201          18 :         gridfile.open(gridreadfilename_);
+    1202             :       } else {
+    1203           0 :         error("The GRID file you want to read: " + gridreadfilename_ + ", cannot be found!");
+    1204             :       }
+    1205          18 :       std::string funcl=getLabel() + ".bias";
+    1206          36 :       BiasGrid_=GridBase::create(funcl, getArguments(), gridfile, gmin, gmax, gbin, sparsegrid, spline, true);
+    1207          18 :       if(BiasGrid_->getDimension()!=getNumberOfArguments()) error("mismatch between dimensionality of input grid and number of arguments");
+    1208          45 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1209          54 :         if( getPntrToArgument(i)->isPeriodic()!=BiasGrid_->getIsPeriodic()[i] ) error("periodicity mismatch between arguments and input bias");
+    1210             :         double a, b;
+    1211          27 :         Tools::convert(gmin[i],a);
+    1212          27 :         Tools::convert(gmax[i],b);
+    1213          27 :         double mesh=(b-a)/((double)gbin[i]);
+    1214          27 :         if(mesh>0.5*sigma0_[i]) log<<"  WARNING: Using a METAD with a Grid Spacing larger than half of the Gaussians width can produce artifacts\n";
+    1215             :       }
+    1216          18 :       log.printf("  Restarting from %s\n",gridreadfilename_.c_str());
+    1217          18 :       if(getRestart()) restartedFromGrid=true;
+    1218          18 :     }
+    1219             :   }
+    1220             : 
+    1221             :   // if we are restarting from GRID and using WALKERS_MPI we can check that all walkers have actually read the grid
+    1222         148 :   if(getRestart()&&walkers_mpi_) {
+    1223           9 :     std::vector<int> restarted(mpi_nw_,0);
+    1224           9 :     if(comm.Get_rank()==0) multi_sim_comm.Allgather(int(restartedFromGrid), restarted);
+    1225           9 :     comm.Bcast(restarted,0);
+    1226             :     int result = std::accumulate(restarted.begin(),restarted.end(),0);
+    1227           9 :     if(result!=0&&result!=mpi_nw_) error("in this WALKERS_MPI run some replica have restarted from GRID while other do not!");
+    1228             :   }
+    1229             : 
+    1230         186 :   if(walkers_mpi_&&mw_dir_==""&&hillsfname.at(0)!='/') {
+    1231             :     //if possible the root replica will share its current folder so that all walkers will read the same file
+    1232          76 :     const std::string ret = std::filesystem::current_path();
+    1233             :     mw_dir_ = ret;
+    1234          38 :     mw_dir_ = mw_dir_ + "/";
+    1235          38 :     if(comm.Get_rank()==0) multi_sim_comm.Bcast(mw_dir_,0);
+    1236          38 :     comm.Bcast(mw_dir_,0);
+    1237             :   }
+    1238             : 
+    1239             :   // creating std::vector of ifile* for hills reading
+    1240             :   // open all files at the beginning and read Gaussians if restarting
+    1241             :   bool restartedFromHills=false;  // restart from hills files
+    1242         308 :   for(int i=0; i<mw_n_; ++i) {
+    1243             :     std::string fname;
+    1244         160 :     if(mw_dir_!="") {
+    1245          47 :       if(mw_n_>1) {
+    1246           9 :         std::stringstream out; out << i;
+    1247          18 :         fname = mw_dir_+"/"+hillsfname+"."+out.str();
+    1248          47 :       } else if(walkers_mpi_) {
+    1249          76 :         fname = mw_dir_+"/"+hillsfname;
+    1250             :       } else {
+    1251             :         fname = hillsfname;
+    1252             :       }
+    1253             :     } else {
+    1254         113 :       if(mw_n_>1) {
+    1255           9 :         std::stringstream out; out << i;
+    1256          18 :         fname = hillsfname+"."+out.str();
+    1257           9 :       } else {
+    1258             :         fname = hillsfname;
+    1259             :       }
+    1260             :     }
+    1261         160 :     ifiles_.emplace_back(Tools::make_unique<IFile>());
+    1262             :     // this is just a shortcut pointer to the last element:
+    1263             :     IFile *ifile = ifiles_.back().get();
+    1264         160 :     ifilesnames_.push_back(fname);
+    1265         160 :     ifile->link(*this);
+    1266         160 :     if(ifile->FileExist(fname)) {
+    1267          36 :       ifile->open(fname);
+    1268          36 :       if(getRestart()&&!restartedFromGrid) {
+    1269          19 :         log.printf("  Restarting from %s:",ifilesnames_[i].c_str());
+    1270          19 :         readGaussians(ifiles_[i].get());
+    1271             :         restartedFromHills=true;
+    1272             :       }
+    1273          36 :       ifiles_[i]->reset(false);
+    1274             :       // close only the walker own hills file for later writing
+    1275          36 :       if(i==mw_id_) ifiles_[i]->close();
+    1276             :     } else {
+    1277             :       // in case a file does not exist and we are restarting, complain that the file was not found
+    1278         124 :       if(getRestart()&&!restartedFromGrid) error("restart file "+fname+" not found");
+    1279             :     }
+    1280             :   }
+    1281             : 
+    1282             :   // if we are restarting from FILE and using WALKERS_MPI we can check that all walkers have actually read the FILE
+    1283         148 :   if(getRestart()&&walkers_mpi_) {
+    1284           9 :     std::vector<int> restarted(mpi_nw_,0);
+    1285           9 :     if(comm.Get_rank()==0) multi_sim_comm.Allgather(int(restartedFromHills), restarted);
+    1286           9 :     comm.Bcast(restarted,0);
+    1287             :     int result = std::accumulate(restarted.begin(),restarted.end(),0);
+    1288           9 :     if(result!=0&&result!=mpi_nw_) error("in this WALKERS_MPI run some replica have restarted from FILE while other do not!");
+    1289             :   }
+    1290             : 
+    1291         148 :   comm.Barrier();
+    1292             :   // this barrier is needed when using walkers_mpi
+    1293             :   // to be sure that all files have been read before
+    1294             :   // backing them up
+    1295             :   // it should not be used when walkers_mpi is false otherwise
+    1296             :   // it would introduce troubles when using replicas without METAD
+    1297             :   // (e.g. in bias exchange with a neutral replica)
+    1298             :   // see issue #168 on github
+    1299         148 :   if(comm.Get_rank()==0 && walkers_mpi_) multi_sim_comm.Barrier();
+    1300             : 
+    1301         148 :   if(targetfilename_.length()>0) {
+    1302           2 :     IFile gridfile; gridfile.open(targetfilename_);
+    1303           2 :     std::string funcl=getLabel() + ".target";
+    1304           4 :     TargetGrid_=GridBase::create(funcl,getArguments(),gridfile,false,false,true);
+    1305           2 :     if(TargetGrid_->getDimension()!=getNumberOfArguments()) error("mismatch between dimensionality of input grid and number of arguments");
+    1306           4 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1307           4 :       if( getPntrToArgument(i)->isPeriodic()!=TargetGrid_->getIsPeriodic()[i] ) error("periodicity mismatch between arguments and input bias");
+    1308             :     }
+    1309           2 :   }
+    1310             : 
+    1311         148 :   if(getRestart()) {
+    1312             :     // if this is a restart the neighbor list should be immediately updated
+    1313          37 :     if(nlist_) nlist_update_=true;
+    1314             :     // Calculate the Tiwary-Parrinello reweighting factor if we are restarting from previous hills
+    1315          37 :     if(calc_rct_) computeReweightingFactor();
+    1316             :     // Calculate all special bias quantities desired if restarting with nonzero bias.
+    1317          37 :     if(calc_max_bias_) {
+    1318           0 :       max_bias_ = BiasGrid_->getMaxValue();
+    1319           0 :       getPntrToComponent("maxbias")->set(max_bias_);
+    1320             :     }
+    1321          37 :     if(calc_transition_bias_) {
+    1322          13 :       transition_bias_ = getTransitionBarrierBias();
+    1323          26 :       getPntrToComponent("transbias")->set(transition_bias_);
+    1324             :     }
+    1325             :   }
+    1326             : 
+    1327             :   // open grid file for writing
+    1328         148 :   if(wgridstride_>0) {
+    1329          19 :     gridfile_.link(*this);
+    1330          19 :     if(walkers_mpi_) {
+    1331           0 :       int r=0;
+    1332           0 :       if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+    1333           0 :       comm.Bcast(r,0);
+    1334           0 :       if(r>0) gridfilename_="/dev/null";
+    1335           0 :       gridfile_.enforceSuffix("");
+    1336             :     }
+    1337          19 :     if(mw_n_>1) gridfile_.enforceSuffix("");
+    1338          19 :     gridfile_.open(gridfilename_);
+    1339             :   }
+    1340             : 
+    1341             :   // open hills file for writing
+    1342         148 :   hillsOfile_.link(*this);
+    1343         148 :   if(walkers_mpi_) {
+    1344          38 :     int r=0;
+    1345          38 :     if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+    1346          38 :     comm.Bcast(r,0);
+    1347          38 :     if(r>0) ifilesnames_[mw_id_]="/dev/null";
+    1348          76 :     hillsOfile_.enforceSuffix("");
+    1349             :   }
+    1350         154 :   if(mw_n_>1) hillsOfile_.enforceSuffix("");
+    1351         148 :   hillsOfile_.open(ifilesnames_[mw_id_]);
+    1352         148 :   if(fmt_.length()>0) hillsOfile_.fmtField(fmt_);
+    1353         148 :   hillsOfile_.addConstantField("multivariate");
+    1354         148 :   hillsOfile_.addConstantField("kerneltype");
+    1355         148 :   if(doInt_) {
+    1356           4 :     hillsOfile_.addConstantField("lower_int").printField("lower_int",lowI_);
+    1357           4 :     hillsOfile_.addConstantField("upper_int").printField("upper_int",uppI_);
+    1358             :   }
+    1359             :   hillsOfile_.setHeavyFlush();
+    1360             :   // output periodicities of variables
+    1361         415 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) hillsOfile_.setupPrintValue( getPntrToArgument(i) );
+    1362             : 
+    1363             :   bool concurrent=false;
+    1364         148 :   const ActionSet&actionSet(plumed.getActionSet());
+    1365        1705 :   for(const auto & p : actionSet) if(dynamic_cast<MetaD*>(p.get())) { concurrent=true; break; }
+    1366         148 :   if(concurrent) log<<"  You are using concurrent metadynamics\n";
+    1367         148 :   if(rect_biasf_.size()>0) {
+    1368          18 :     if(walkers_mpi_) {
+    1369          12 :       log<<"  You are using RECT in its 'altruistic' implementation\n";
+    1370             :     }{
+    1371          18 :       log<<"  You are using RECT\n";
+    1372             :     }
+    1373             :   }
+    1374             : 
+    1375         296 :   log<<"  Bibliography "<<plumed.cite("Laio and Parrinello, PNAS 99, 12562 (2002)");
+    1376         186 :   if(welltemp_) log<<plumed.cite("Barducci, Bussi, and Parrinello, Phys. Rev. Lett. 100, 020603 (2008)");
+    1377         148 :   if(tt_specs_.is_active) {
+    1378           6 :     log << plumed.cite("Dama, Rotskoff, Parrinello, and Voth, J. Chem. Theory Comput. 10, 3626 (2014)");
+    1379           6 :     log << plumed.cite("Dama, Parrinello, and Voth, Phys. Rev. Lett. 112, 240602 (2014)");
+    1380             :   }
+    1381         192 :   if(mw_n_>1||walkers_mpi_) log<<plumed.cite("Raiteri, Laio, Gervasio, Micheletti, and Parrinello, J. Phys. Chem. B 110, 3533 (2006)");
+    1382         169 :   if(adaptive_!=FlexibleBin::none) log<<plumed.cite("Branduardi, Bussi, and Parrinello, J. Chem. Theory Comput. 8, 2247 (2012)");
+    1383         150 :   if(doInt_) log<<plumed.cite("Baftizadeh, Cossio, Pietrucci, and Laio, Curr. Phys. Chem. 2, 79 (2012)");
+    1384         152 :   if(acceleration_) log<<plumed.cite("Pratyush and Parrinello, Phys. Rev. Lett. 111, 230602 (2013)");
+    1385         154 :   if(calc_rct_) log<<plumed.cite("Pratyush and Parrinello, J. Phys. Chem. B, 119, 736 (2015)");
+    1386         228 :   if(concurrent || rect_biasf_.size()>0) log<<plumed.cite("Gil-Ley and Bussi, J. Chem. Theory Comput. 11, 1077 (2015)");
+    1387         160 :   if(rect_biasf_.size()>0 && walkers_mpi_) log<<plumed.cite("Hosek, Toulcova, Bortolato, and Spiwok, J. Phys. Chem. B 120, 2209 (2016)");
+    1388         148 :   if(targetfilename_.length()>0) {
+    1389           4 :     log<<plumed.cite("White, Dama, and Voth, J. Chem. Theory Comput. 11, 2451 (2015)");
+    1390           4 :     log<<plumed.cite("Marinelli and Faraldo-GoÌmez,  Biophys. J. 108, 2779 (2015)");
+    1391           4 :     log<<plumed.cite("Gil-Ley, Bottaro, and Bussi, J. Chem. Theory Comput. 12, 2790 (2016)");
+    1392             :   }
+    1393         150 :   if(freq_adaptive_) log<<plumed.cite("Wang, Valsson, Tiwary, Parrinello, and Lindorff-Larsen, J. Chem. Phys. 149, 072309 (2018)");
+    1394         148 :   log<<"\n";
+    1395         396 : }
+    1396             : 
+    1397         151 : void MetaD::readTemperingSpecs(TemperingSpecs &t_specs)
+    1398             : {
+    1399             :   // Set global tempering parameters.
+    1400         151 :   parse(t_specs.name_stem + "BIASFACTOR", t_specs.biasf);
+    1401         151 :   if (t_specs.biasf != -1.0) {
+    1402           3 :     if (kbt_ == 0.0) {
+    1403           0 :       error("Unless the MD engine passes the temperature to plumed, with tempered metad you must specify it using TEMP");
+    1404             :     }
+    1405           3 :     if (t_specs.biasf == 1.0) {
+    1406           0 :       error("A bias factor of 1 corresponds to zero delta T and zero hill size, so it is not allowed.");
+    1407             :     }
+    1408           3 :     t_specs.is_active = true;
+    1409           3 :     parse(t_specs.name_stem + "BIASTHRESHOLD", t_specs.threshold);
+    1410           3 :     if (t_specs.threshold < 0.0) {
+    1411           0 :       error(t_specs.name + " bias threshold is nonsensical");
+    1412             :     }
+    1413           3 :     parse(t_specs.name_stem + "ALPHA", t_specs.alpha);
+    1414           3 :     if (t_specs.alpha <= 0.0 || t_specs.alpha > 1.0) {
+    1415           0 :       error(t_specs.name + " decay shape parameter alpha is nonsensical");
+    1416             :     }
+    1417             :   }
+    1418         151 : }
+    1419             : 
+    1420           3 : void MetaD::logTemperingSpecs(const TemperingSpecs &t_specs)
+    1421             : {
+    1422           3 :   log.printf("  %s bias factor %f\n", t_specs.name.c_str(), t_specs.biasf);
+    1423           3 :   log.printf("  KbT %f\n", kbt_);
+    1424           3 :   if (t_specs.threshold != 0.0) log.printf("  %s bias threshold %f\n", t_specs.name.c_str(), t_specs.threshold);
+    1425           3 :   if (t_specs.alpha != 1.0) log.printf("  %s decay shape parameter alpha %f\n", t_specs.name.c_str(), t_specs.alpha);
+    1426           3 : }
+    1427             : 
+    1428        6037 : void MetaD::readGaussians(IFile *ifile)
+    1429             : {
+    1430        6037 :   unsigned ncv=getNumberOfArguments();
+    1431        6037 :   std::vector<double> center(ncv);
+    1432        6037 :   std::vector<double> sigma(ncv);
+    1433             :   double height;
+    1434             :   int nhills=0;
+    1435        6037 :   bool multivariate=false;
+    1436             : 
+    1437             :   std::vector<Value> tmpvalues;
+    1438       18124 :   for(unsigned j=0; j<getNumberOfArguments(); ++j) tmpvalues.push_back( Value( this, getPntrToArgument(j)->getName(), false ) );
+    1439             : 
+    1440        8499 :   while(scanOneHill(ifile,tmpvalues,center,sigma,height,multivariate))
+    1441             :   {
+    1442        2462 :     nhills++;
+    1443             :     // note that for gamma=1 we store directly -F
+    1444        2462 :     if(welltemp_ && biasf_>1.0) height*=(biasf_-1.0)/biasf_;
+    1445        2462 :     addGaussian(Gaussian(multivariate,height,center,sigma));
+    1446             :   }
+    1447        6037 :   log.printf("      %d Gaussians read\n",nhills);
+    1448       12074 : }
+    1449             : 
+    1450        2922 : void MetaD::writeGaussian(const Gaussian& hill, OFile&file)
+    1451             : {
+    1452        2922 :   unsigned ncv=getNumberOfArguments();
+    1453        2922 :   file.printField("time",getTimeStep()*getStep());
+    1454        8194 :   for(unsigned i=0; i<ncv; ++i) {
+    1455        5272 :     file.printField(getPntrToArgument(i),hill.center[i]);
+    1456             :   }
+    1457        5844 :   hillsOfile_.printField("kerneltype","stretched-gaussian");
+    1458        2922 :   if(hill.multivariate) {
+    1459         892 :     hillsOfile_.printField("multivariate","true");
+    1460             :     Matrix<double> mymatrix(ncv,ncv);
+    1461             :     unsigned k=0;
+    1462        1047 :     for(unsigned i=0; i<ncv; i++) {
+    1463        1357 :       for(unsigned j=i; j<ncv; j++) {
+    1464             :         // recompose the full inverse matrix
+    1465         756 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k];
+    1466         756 :         k++;
+    1467             :       }
+    1468             :     }
+    1469             :     // invert it
+    1470             :     Matrix<double> invmatrix(ncv,ncv);
+    1471         446 :     Invert(mymatrix,invmatrix);
+    1472             :     // enforce symmetry
+    1473        1047 :     for(unsigned i=0; i<ncv; i++) {
+    1474        1357 :       for(unsigned j=i; j<ncv; j++) {
+    1475         756 :         invmatrix(i,j)=invmatrix(j,i);
+    1476             :       }
+    1477             :     }
+    1478             : 
+    1479             :     // do cholesky so to have a "sigma like" number
+    1480             :     Matrix<double> lower(ncv,ncv);
+    1481         446 :     cholesky(invmatrix,lower);
+    1482             :     // loop in band form
+    1483        1047 :     for(unsigned i=0; i<ncv; i++) {
+    1484        1357 :       for(unsigned j=0; j<ncv-i; j++) {
+    1485        1512 :         file.printField("sigma_"+getPntrToArgument(j+i)->getName()+"_"+getPntrToArgument(j)->getName(),lower(j+i,j));
+    1486             :       }
+    1487             :     }
+    1488             :   } else {
+    1489        4952 :     hillsOfile_.printField("multivariate","false");
+    1490        7147 :     for(unsigned i=0; i<ncv; ++i)
+    1491        9342 :       file.printField("sigma_"+getPntrToArgument(i)->getName(),hill.sigma[i]);
+    1492             :   }
+    1493        2922 :   double height=hill.height;
+    1494             :   // note that for gamma=1 we store directly -F
+    1495        2922 :   if(welltemp_ && biasf_>1.0) height*=biasf_/(biasf_-1.0);
+    1496        5844 :   file.printField("height",height).printField("biasf",biasf_);
+    1497        4431 :   if(mw_n_>1) file.printField("clock",int(std::time(0)));
+    1498        2922 :   file.printField();
+    1499        2922 : }
+    1500             : 
+    1501        5546 : void MetaD::addGaussian(const Gaussian& hill)
+    1502             : {
+    1503        5546 :   if(grid_) {
+    1504         640 :     size_t ncv=getNumberOfArguments();
+    1505         640 :     std::vector<unsigned> nneighb=getGaussianSupport(hill);
+    1506         640 :     std::vector<Grid::index_t> neighbors=BiasGrid_->getNeighbors(hill.center,nneighb);
+    1507         640 :     std::vector<double> der(ncv);
+    1508         640 :     std::vector<double> xx(ncv);
+    1509         640 :     if(comm.Get_size()==1) {
+    1510             :       // for performance reasons and thread safety
+    1511         544 :       std::vector<double> dp(ncv);
+    1512       55324 :       for(size_t i=0; i<neighbors.size(); ++i) {
+    1513       54780 :         Grid::index_t ineigh=neighbors[i];
+    1514      158922 :         for(unsigned j=0; j<ncv; ++j) der[j]=0.0;
+    1515       54780 :         BiasGrid_->getPoint(ineigh,xx);
+    1516       54780 :         double bias=evaluateGaussianAndDerivatives(xx,hill,der,dp);
+    1517       54780 :         BiasGrid_->addValueAndDerivatives(ineigh,bias,der);
+    1518             :       }
+    1519             :     } else {
+    1520          96 :       unsigned stride=comm.Get_size();
+    1521          96 :       unsigned rank=comm.Get_rank();
+    1522          96 :       std::vector<double> allder(ncv*neighbors.size(),0.0);
+    1523          96 :       std::vector<double> n_der(ncv,0.0);
+    1524          96 :       std::vector<double> allbias(neighbors.size(),0.0);
+    1525             :       // for performance reasons and thread safety
+    1526          96 :       std::vector<double> dp(ncv);
+    1527       27148 :       for(unsigned i=rank; i<neighbors.size(); i+=stride) {
+    1528       27052 :         Grid::index_t ineigh=neighbors[i];
+    1529       81156 :         for(unsigned j=0; j<ncv; ++j) n_der[j]=0.0;
+    1530       27052 :         BiasGrid_->getPoint(ineigh,xx);
+    1531       27052 :         allbias[i]=evaluateGaussianAndDerivatives(xx,hill,n_der,dp);
+    1532       81156 :         for(unsigned j=0; j<ncv; j++) allder[ncv*i+j]=n_der[j];
+    1533             :       }
+    1534          96 :       comm.Sum(allbias);
+    1535          96 :       comm.Sum(allder);
+    1536      103200 :       for(unsigned i=0; i<neighbors.size(); ++i) {
+    1537      103104 :         Grid::index_t ineigh=neighbors[i];
+    1538      309312 :         for(unsigned j=0; j<ncv; ++j) der[j]=allder[ncv*i+j];
+    1539      103104 :         BiasGrid_->addValueAndDerivatives(ineigh,allbias[i],der);
+    1540             :       }
+    1541             :     }
+    1542        4906 :   } else hills_.push_back(hill);
+    1543        5546 : }
+    1544             : 
+    1545         640 : std::vector<unsigned> MetaD::getGaussianSupport(const Gaussian& hill)
+    1546             : {
+    1547             :   std::vector<unsigned> nneigh;
+    1548             :   std::vector<double> cutoff;
+    1549         640 :   unsigned ncv=getNumberOfArguments();
+    1550             : 
+    1551             :   // traditional or flexible hill?
+    1552         640 :   if(hill.multivariate) {
+    1553             :     unsigned k=0;
+    1554             :     Matrix<double> mymatrix(ncv,ncv);
+    1555           0 :     for(unsigned i=0; i<ncv; i++) {
+    1556           0 :       for(unsigned j=i; j<ncv; j++) {
+    1557             :         // recompose the full inverse matrix
+    1558           0 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k];
+    1559           0 :         k++;
+    1560             :       }
+    1561             :     }
+    1562             :     // Reinvert so to have the ellipses
+    1563             :     Matrix<double> myinv(ncv,ncv);
+    1564           0 :     Invert(mymatrix,myinv);
+    1565             :     Matrix<double> myautovec(ncv,ncv);
+    1566           0 :     std::vector<double> myautoval(ncv); //should I take this or their square root?
+    1567           0 :     diagMat(myinv,myautoval,myautovec);
+    1568             :     double maxautoval=0.;
+    1569             :     unsigned ind_maxautoval; ind_maxautoval=ncv;
+    1570           0 :     for(unsigned i=0; i<ncv; i++) {
+    1571           0 :       if(myautoval[i]>maxautoval) {maxautoval=myautoval[i]; ind_maxautoval=i;}
+    1572             :     }
+    1573           0 :     for(unsigned i=0; i<ncv; i++) {
+    1574           0 :       cutoff.push_back(std::sqrt(2.0*dp2cutoff)*std::abs(std::sqrt(maxautoval)*myautovec(i,ind_maxautoval)));
+    1575             :     }
+    1576             :   } else {
+    1577        1618 :     for(unsigned i=0; i<ncv; ++i) {
+    1578         978 :       cutoff.push_back(std::sqrt(2.0*dp2cutoff)*hill.sigma[i]);
+    1579             :     }
+    1580             :   }
+    1581             : 
+    1582         640 :   if(doInt_) {
+    1583           2 :     if(hill.center[0]+cutoff[0] > uppI_ || hill.center[0]-cutoff[0] < lowI_) {
+    1584             :       // in this case, we updated the entire grid to avoid problems
+    1585           2 :       return BiasGrid_->getNbin();
+    1586             :     } else {
+    1587           0 :       nneigh.push_back( static_cast<unsigned>(ceil(cutoff[0]/BiasGrid_->getDx()[0])) );
+    1588             :       return nneigh;
+    1589             :     }
+    1590             :   } else {
+    1591        1614 :     for(unsigned i=0; i<ncv; i++) {
+    1592         976 :       nneigh.push_back( static_cast<unsigned>(ceil(cutoff[i]/BiasGrid_->getDx()[i])) );
+    1593             :     }
+    1594             :   }
+    1595             : 
+    1596             :   return nneigh;
+    1597             : }
+    1598             : 
+    1599         285 : double MetaD::getBias(const std::vector<double>& cv)
+    1600             : {
+    1601         285 :   double bias=0.0;
+    1602         285 :   if(grid_) bias = BiasGrid_->getValue(cv);
+    1603             :   else {
+    1604          82 :     unsigned nt=OpenMP::getNumThreads();
+    1605          82 :     unsigned stride=comm.Get_size();
+    1606          82 :     unsigned rank=comm.Get_rank();
+    1607             : 
+    1608          82 :     if(!nlist_) {
+    1609          82 :       #pragma omp parallel num_threads(nt)
+    1610             :       {
+    1611             :         #pragma omp for reduction(+:bias) nowait
+    1612             :         for(unsigned i=rank; i<hills_.size(); i+=stride) bias+=evaluateGaussian(cv,hills_[i]);
+    1613             :       }
+    1614             :     } else {
+    1615           0 :       #pragma omp parallel num_threads(nt)
+    1616             :       {
+    1617             :         #pragma omp for reduction(+:bias) nowait
+    1618             :         for(unsigned i=rank; i<nlist_hills_.size(); i+=stride) bias+=evaluateGaussian(cv,nlist_hills_[i]);
+    1619             :       }
+    1620             :     }
+    1621          82 :     comm.Sum(bias);
+    1622             :   }
+    1623             : 
+    1624         285 :   return bias;
+    1625             : }
+    1626             : 
+    1627        8395 : double MetaD::getBiasAndDerivatives(const std::vector<double>& cv, std::vector<double>& der)
+    1628             : {
+    1629        8395 :   unsigned ncv=getNumberOfArguments();
+    1630        8395 :   double bias=0.0;
+    1631        8395 :   if(grid_) {
+    1632        1506 :     std::vector<double> vder(ncv);
+    1633        1506 :     bias=BiasGrid_->getValueAndDerivatives(cv,vder);
+    1634        3498 :     for(unsigned i=0; i<ncv; i++) der[i]=vder[i];
+    1635             :   } else {
+    1636        6889 :     unsigned nt=OpenMP::getNumThreads();
+    1637        6889 :     unsigned stride=comm.Get_size();
+    1638        6889 :     unsigned rank=comm.Get_rank();
+    1639             : 
+    1640        6889 :     if(!nlist_) {
+    1641        6884 :       if(hills_.size()<2*nt*stride||nt==1) {
+    1642             :         // for performance reasons and thread safety
+    1643        2586 :         std::vector<double> dp(ncv);
+    1644        6703 :         for(unsigned i=rank; i<hills_.size(); i+=stride) {
+    1645        4117 :           bias+=evaluateGaussianAndDerivatives(cv,hills_[i],der,dp);
+    1646             :         }
+    1647             :       } else {
+    1648        4298 :         #pragma omp parallel num_threads(nt)
+    1649             :         {
+    1650             :           std::vector<double> omp_deriv(ncv,0.);
+    1651             :           // for performance reasons and thread safety
+    1652             :           std::vector<double> dp(ncv);
+    1653             :           #pragma omp for reduction(+:bias) nowait
+    1654             :           for(unsigned i=rank; i<hills_.size(); i+=stride) {
+    1655             :             bias+=evaluateGaussianAndDerivatives(cv,hills_[i],omp_deriv,dp);
+    1656             :           }
+    1657             :           #pragma omp critical
+    1658             :           for(unsigned i=0; i<ncv; i++) der[i]+=omp_deriv[i];
+    1659             :         }
+    1660             :       }
+    1661             :     } else {
+    1662           5 :       if(hills_.size()<2*nt*stride||nt==1) {
+    1663             :         // for performance reasons and thread safety
+    1664           0 :         std::vector<double> dp(ncv);
+    1665           0 :         for(unsigned i=rank; i<nlist_hills_.size(); i+=stride) {
+    1666           0 :           bias+=evaluateGaussianAndDerivatives(cv,nlist_hills_[i],der,dp);
+    1667             :         }
+    1668             :       } else {
+    1669           5 :         #pragma omp parallel num_threads(nt)
+    1670             :         {
+    1671             :           std::vector<double> omp_deriv(ncv,0.);
+    1672             :           // for performance reasons and thread safety
+    1673             :           std::vector<double> dp(ncv);
+    1674             :           #pragma omp for reduction(+:bias) nowait
+    1675             :           for(unsigned i=rank; i<nlist_hills_.size(); i+=stride) {
+    1676             :             bias+=evaluateGaussianAndDerivatives(cv,nlist_hills_[i],omp_deriv,dp);
+    1677             :           }
+    1678             :           #pragma omp critical
+    1679             :           for(unsigned i=0; i<ncv; i++) der[i]+=omp_deriv[i];
+    1680             :         }
+    1681             :       }
+    1682             :     }
+    1683        6889 :     comm.Sum(bias);
+    1684        6889 :     comm.Sum(der);
+    1685             :   }
+    1686             : 
+    1687        8395 :   return bias;
+    1688             : }
+    1689             : 
+    1690           0 : double MetaD::getGaussianNormalization(const Gaussian& hill)
+    1691             : {
+    1692             :   double norm=1;
+    1693           0 :   unsigned ncv=hill.center.size();
+    1694             : 
+    1695           0 :   if(hill.multivariate) {
+    1696             :     // recompose the full sigma from the upper diag cholesky
+    1697             :     unsigned k=0;
+    1698             :     Matrix<double> mymatrix(ncv,ncv);
+    1699           0 :     for(unsigned i=0; i<ncv; i++) {
+    1700           0 :       for(unsigned j=i; j<ncv; j++) {
+    1701           0 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k]; // recompose the full inverse matrix
+    1702           0 :         k++;
+    1703             :       }
+    1704           0 :       double ldet; logdet( mymatrix, ldet );
+    1705           0 :       norm = std::exp( ldet );  // Not sure here if mymatrix is sigma or inverse
+    1706             :     }
+    1707             :   } else {
+    1708           0 :     for(unsigned i=0; i<hill.sigma.size(); i++) norm*=hill.sigma[i];
+    1709             :   }
+    1710             : 
+    1711           0 :   return norm*std::pow(2*pi,static_cast<double>(ncv)/2.0);
+    1712             : }
+    1713             : 
+    1714         192 : double MetaD::evaluateGaussian(const std::vector<double>& cv, const Gaussian& hill)
+    1715             : {
+    1716         192 :   unsigned ncv=cv.size();
+    1717             : 
+    1718             :   // I use a pointer here because cv is const (and should be const)
+    1719             :   // but when using doInt it is easier to locally replace cv[0] with
+    1720             :   // the upper/lower limit in case it is out of range
+    1721             :   double tmpcv[1];
+    1722             :   const double *pcv=NULL; // pointer to cv
+    1723         192 :   if(ncv>0) pcv=&cv[0];
+    1724         192 :   if(doInt_) {
+    1725           0 :     plumed_assert(ncv==1);
+    1726           0 :     tmpcv[0]=cv[0];
+    1727           0 :     if(cv[0]<lowI_) tmpcv[0]=lowI_;
+    1728           0 :     if(cv[0]>uppI_) tmpcv[0]=uppI_;
+    1729             :     pcv=&(tmpcv[0]);
+    1730             :   }
+    1731             : 
+    1732             :   double dp2=0.0;
+    1733         192 :   if(hill.multivariate) {
+    1734             :     unsigned k=0;
+    1735             :     // recompose the full sigma from the upper diag cholesky
+    1736             :     Matrix<double> mymatrix(ncv,ncv);
+    1737           0 :     for(unsigned i=0; i<ncv; i++) {
+    1738           0 :       for(unsigned j=i; j<ncv; j++) {
+    1739           0 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k]; // recompose the full inverse matrix
+    1740           0 :         k++;
+    1741             :       }
+    1742             :     }
+    1743           0 :     for(unsigned i=0; i<ncv; i++) {
+    1744           0 :       double dp_i=difference(i,hill.center[i],pcv[i]);
+    1745           0 :       for(unsigned j=i; j<ncv; j++) {
+    1746           0 :         if(i==j) {
+    1747           0 :           dp2+=dp_i*dp_i*mymatrix(i,j)*0.5;
+    1748             :         } else {
+    1749           0 :           double dp_j=difference(j,hill.center[j],pcv[j]);
+    1750           0 :           dp2+=dp_i*dp_j*mymatrix(i,j);
+    1751             :         }
+    1752             :       }
+    1753             :     }
+    1754             :   } else {
+    1755         576 :     for(unsigned i=0; i<ncv; i++) {
+    1756         384 :       double dp=difference(i,hill.center[i],pcv[i])*hill.invsigma[i];
+    1757         384 :       dp2+=dp*dp;
+    1758             :     }
+    1759         192 :     dp2*=0.5;
+    1760             :   }
+    1761             : 
+    1762             :   double bias=0.0;
+    1763         192 :   if(dp2<dp2cutoff) bias=hill.height*(stretchA*std::exp(-dp2)+stretchB);
+    1764             : 
+    1765         192 :   return bias;
+    1766             : }
+    1767             : 
+    1768     2409207 : double MetaD::evaluateGaussianAndDerivatives(const std::vector<double>& cv, const Gaussian& hill, std::vector<double>& der, std::vector<double>& dp_)
+    1769             : {
+    1770     2409207 :   unsigned ncv=cv.size();
+    1771             : 
+    1772             :   // I use a pointer here because cv is const (and should be const)
+    1773             :   // but when using doInt it is easier to locally replace cv[0] with
+    1774             :   // the upper/lower limit in case it is out of range
+    1775             :   const double *pcv=NULL; // pointer to cv
+    1776             :   double tmpcv[1]; // tmp array with cv (to be used with doInt_)
+    1777     2409207 :   if(ncv>0) pcv=&cv[0];
+    1778     2409207 :   if(doInt_) {
+    1779         602 :     plumed_assert(ncv==1);
+    1780         602 :     tmpcv[0]=cv[0];
+    1781         602 :     if(cv[0]<lowI_) tmpcv[0]=lowI_;
+    1782         602 :     if(cv[0]>uppI_) tmpcv[0]=uppI_;
+    1783             :     pcv=&(tmpcv[0]);
+    1784             :   }
+    1785             : 
+    1786             :   bool int_der=false;
+    1787     2409207 :   if(doInt_) {
+    1788         602 :     if(cv[0]<lowI_ || cv[0]>uppI_) int_der=true;
+    1789             :   }
+    1790             : 
+    1791             :   double dp2=0.0;
+    1792             :   double bias=0.0;
+    1793     2409207 :   if(hill.multivariate) {
+    1794             :     unsigned k=0;
+    1795             :     // recompose the full sigma from the upper diag cholesky
+    1796             :     Matrix<double> mymatrix(ncv,ncv);
+    1797      161635 :     for(unsigned i=0; i<ncv; i++) {
+    1798      162513 :       for(unsigned j=i; j<ncv; j++) {
+    1799       81476 :         mymatrix(i,j)=mymatrix(j,i)=hill.sigma[k]; // recompose the full inverse matrix
+    1800       81476 :         k++;
+    1801             :       }
+    1802             :     }
+    1803      161635 :     for(unsigned i=0; i<ncv; i++) {
+    1804       81037 :       dp_[i]=difference(i,hill.center[i],pcv[i]);
+    1805      162513 :       for(unsigned j=i; j<ncv; j++) {
+    1806       81476 :         if(i==j) {
+    1807       81037 :           dp2+=dp_[i]*dp_[i]*mymatrix(i,j)*0.5;
+    1808             :         } else {
+    1809         439 :           double dp_j=difference(j,hill.center[j],pcv[j]);
+    1810         439 :           dp2+=dp_[i]*dp_j*mymatrix(i,j);
+    1811             :         }
+    1812             :       }
+    1813             :     }
+    1814       80598 :     if(dp2<dp2cutoff) {
+    1815       77683 :       bias=hill.height*std::exp(-dp2);
+    1816       77683 :       if(!int_der) {
+    1817      155673 :         for(unsigned i=0; i<ncv; i++) {
+    1818             :           double tmp=0.0;
+    1819      156594 :           for(unsigned j=0; j<ncv; j++) tmp += dp_[j]*mymatrix(i,j)*bias;
+    1820       77990 :           der[i]-=tmp*stretchA;
+    1821             :         }
+    1822             :       } else {
+    1823           0 :         for(unsigned i=0; i<ncv; i++) der[i]=0.;
+    1824             :       }
+    1825       77683 :       bias=stretchA*bias+hill.height*stretchB;
+    1826             :     }
+    1827             :   } else {
+    1828     6976185 :     for(unsigned i=0; i<ncv; i++) {
+    1829     4647576 :       dp_[i]=difference(i,hill.center[i],pcv[i])*hill.invsigma[i];
+    1830     4647576 :       dp2+=dp_[i]*dp_[i];
+    1831             :     }
+    1832     2328609 :     dp2*=0.5;
+    1833     2328609 :     if(dp2<dp2cutoff) {
+    1834     1357291 :       bias=hill.height*std::exp(-dp2);
+    1835     1357291 :       if(!int_der) {
+    1836     4063094 :         for(unsigned i=0; i<ncv; i++) der[i]-=bias*dp_[i]*hill.invsigma[i]*stretchA;
+    1837             :       } else {
+    1838         478 :         for(unsigned i=0; i<ncv; i++) der[i]=0.;
+    1839             :       }
+    1840     1357291 :       bias=stretchA*bias+hill.height*stretchB;
+    1841             :     }
+    1842             :   }
+    1843             : 
+    1844     2409207 :   return bias;
+    1845             : }
+    1846             : 
+    1847        2736 : double MetaD::getHeight(const std::vector<double>& cv)
+    1848             : {
+    1849        2736 :   double height=height0_;
+    1850        2736 :   if(welltemp_) {
+    1851         275 :     double vbias = getBias(cv);
+    1852         275 :     if(biasf_>1.0) {
+    1853         259 :       height = height0_*std::exp(-vbias/(kbt_*(biasf_-1.0)));
+    1854             :     } else {
+    1855             :       // notice that if gamma=1 we store directly -F
+    1856          16 :       height = height0_*std::exp(-vbias/kbt_);
+    1857             :     }
+    1858             :   }
+    1859        2736 :   if(dampfactor_>0.0) {
+    1860          18 :     plumed_assert(BiasGrid_);
+    1861          18 :     double m=BiasGrid_->getMaxValue();
+    1862          18 :     height*=std::exp(-m/(kbt_*(dampfactor_)));
+    1863             :   }
+    1864        2736 :   if (tt_specs_.is_active) {
+    1865          60 :     double vbarrier = transition_bias_;
+    1866          60 :     temperHeight(height, tt_specs_, vbarrier);
+    1867             :   }
+    1868        2736 :   if(TargetGrid_) {
+    1869          18 :     double f=TargetGrid_->getValue(cv)-TargetGrid_->getMaxValue();
+    1870          18 :     height*=std::exp(f/kbt_);
+    1871             :   }
+    1872        2736 :   return height;
+    1873             : }
+    1874             : 
+    1875          60 : void MetaD::temperHeight(double& height, const TemperingSpecs& t_specs, const double tempering_bias)
+    1876             : {
+    1877          60 :   if (t_specs.alpha == 1.0) {
+    1878          80 :     height *= std::exp(-std::max(0.0, tempering_bias - t_specs.threshold) / (kbt_ * (t_specs.biasf - 1.0)));
+    1879             :   } else {
+    1880          40 :     height *= std::pow(1 + (1 - t_specs.alpha) / t_specs.alpha * std::max(0.0, tempering_bias - t_specs.threshold) / (kbt_ * (t_specs.biasf - 1.0)), - t_specs.alpha / (1 - t_specs.alpha));
+    1881             :   }
+    1882          60 : }
+    1883             : 
+    1884        8435 : void MetaD::calculate()
+    1885             : {
+    1886             :   // this is because presently there is no way to properly pass information
+    1887             :   // on adaptive hills (diff) after exchanges:
+    1888        8435 :   if(adaptive_==FlexibleBin::diffusion && getExchangeStep()) error("ADAPTIVE=DIFF is not compatible with replica exchange");
+    1889             : 
+    1890        8435 :   const unsigned ncv=getNumberOfArguments();
+    1891        8435 :   std::vector<double> cv(ncv);
+    1892       21082 :   for(unsigned i=0; i<ncv; ++i) cv[i]=getArgument(i);
+    1893             : 
+    1894        8435 :   if(nlist_) {
+    1895           5 :     nlist_steps_++;
+    1896           5 :     if(getExchangeStep()) nlist_update_=true;
+    1897             :     else {
+    1898          11 :       for(unsigned i=0; i<ncv; ++i) {
+    1899           8 :         double d = difference(i, cv[i], nlist_center_[i]);
+    1900           8 :         double nk_dist2 = d*d/nlist_dev2_[i];
+    1901           8 :         if(nk_dist2>nlist_param_[1]) {nlist_update_=true; break;}
+    1902             :       }
+    1903             :     }
+    1904           5 :     if(nlist_update_) updateNlist();
+    1905             :   }
+    1906             : 
+    1907             :   double ene = 0.;
+    1908        8435 :   std::vector<double> der(ncv,0.);
+    1909        8435 :   if(biasf_!=1.0) ene = getBiasAndDerivatives(cv,der);
+    1910        8435 :   setBias(ene);
+    1911       21082 :   for(unsigned i=0; i<ncv; i++) setOutputForce(i,-der[i]);
+    1912             : 
+    1913        8440 :   if(calc_work_) getPntrToComponent("work")->set(work_);
+    1914        8545 :   if(calc_rct_) getPntrToComponent("rbias")->set(ene - reweight_factor_);
+    1915             :   // calculate the acceleration factor
+    1916        8435 :   if(acceleration_&&!isFirstStep_) {
+    1917         329 :     acc_ += static_cast<double>(getStride()) * std::exp(ene/(kbt_));
+    1918         329 :     const double mean_acc = acc_/((double) getStep());
+    1919         329 :     getPntrToComponent("acc")->set(mean_acc);
+    1920        8435 :   } else if (acceleration_ && isFirstStep_ && acc_restart_mean_ > 0.0) {
+    1921           2 :     acc_ = acc_restart_mean_ * static_cast<double>(getStep());
+    1922           2 :     if(freq_adaptive_) {
+    1923             :       // has to be done here if restarting, as the acc is not defined before
+    1924           1 :       updateFrequencyAdaptiveStride();
+    1925             :     }
+    1926             :   }
+    1927        8435 : }
+    1928             : 
+    1929        6239 : void MetaD::update()
+    1930             : {
+    1931             :   // adding hills criteria (could be more complex though)
+    1932             :   bool nowAddAHill;
+    1933        6239 :   if(getStep()%current_stride_==0 && !isFirstStep_) nowAddAHill=true;
+    1934             :   else {
+    1935             :     nowAddAHill=false;
+    1936        3503 :     isFirstStep_=false;
+    1937             :   }
+    1938             : 
+    1939        6239 :   unsigned ncv=getNumberOfArguments();
+    1940        6239 :   std::vector<double> cv(ncv);
+    1941       16690 :   for(unsigned i=0; i<ncv; ++i) cv[i] = getArgument(i);
+    1942             : 
+    1943             :   double vbias=0.;
+    1944        6239 :   if(calc_work_) vbias=getBias(cv);
+    1945             : 
+    1946             :   // if you use adaptive, call the FlexibleBin
+    1947             :   bool multivariate=false;
+    1948        6239 :   if(adaptive_!=FlexibleBin::none) {
+    1949         778 :     flexbin_->update(nowAddAHill);
+    1950             :     multivariate=true;
+    1951             :   }
+    1952             : 
+    1953             :   std::vector<double> thissigma;
+    1954        6239 :   if(nowAddAHill) {
+    1955             :     // add a Gaussian
+    1956        2736 :     double height=getHeight(cv);
+    1957             :     // returns upper diagonal inverse
+    1958        3110 :     if(adaptive_!=FlexibleBin::none) thissigma=flexbin_->getInverseMatrix();
+    1959             :     // returns normal sigma
+    1960        2362 :     else thissigma=sigma0_;
+    1961             : 
+    1962             :     // In case we use walkers_mpi, it is now necessary to communicate with other replicas.
+    1963        2736 :     if(walkers_mpi_) {
+    1964             :       // Allocate arrays to store all walkers hills
+    1965         174 :       std::vector<double> all_cv(mpi_nw_*ncv,0.0);
+    1966         174 :       std::vector<double> all_sigma(mpi_nw_*thissigma.size(),0.0);
+    1967         174 :       std::vector<double> all_height(mpi_nw_,0.0);
+    1968         174 :       std::vector<int>    all_multivariate(mpi_nw_,0);
+    1969         174 :       if(comm.Get_rank()==0) {
+    1970             :         // Communicate (only root)
+    1971          99 :         multi_sim_comm.Allgather(cv,all_cv);
+    1972          99 :         multi_sim_comm.Allgather(thissigma,all_sigma);
+    1973             :         // notice that if gamma=1 we store directly -F so this scaling is not necessary:
+    1974          99 :         multi_sim_comm.Allgather(height*(biasf_>1.0?biasf_/(biasf_-1.0):1.0),all_height);
+    1975          99 :         multi_sim_comm.Allgather(int(multivariate),all_multivariate);
+    1976             :       }
+    1977             :       // Share info with group members
+    1978         174 :       comm.Bcast(all_cv,0);
+    1979         174 :       comm.Bcast(all_sigma,0);
+    1980         174 :       comm.Bcast(all_height,0);
+    1981         174 :       comm.Bcast(all_multivariate,0);
+    1982             : 
+    1983             :       // Flying Gaussian
+    1984         174 :       if (flying_) {
+    1985          54 :         hills_.clear();
+    1986          54 :         comm.Barrier();
+    1987             :       }
+    1988             : 
+    1989         696 :       for(unsigned i=0; i<mpi_nw_; i++) {
+    1990             :         // actually add hills one by one
+    1991         522 :         std::vector<double> cv_now(ncv);
+    1992         522 :         std::vector<double> sigma_now(thissigma.size());
+    1993        1566 :         for(unsigned j=0; j<ncv; j++) cv_now[j]=all_cv[i*ncv+j];
+    1994        1674 :         for(unsigned j=0; j<thissigma.size(); j++) sigma_now[j]=all_sigma[i*thissigma.size()+j];
+    1995             :         // notice that if gamma=1 we store directly -F so this scaling is not necessary:
+    1996         522 :         double fact=(biasf_>1.0?(biasf_-1.0)/biasf_:1.0);
+    1997         522 :         Gaussian newhill=Gaussian(all_multivariate[i],all_height[i]*fact,cv_now,sigma_now);
+    1998         522 :         addGaussian(newhill);
+    1999         522 :         if(!flying_) writeGaussian(newhill,hillsOfile_);
+    2000         522 :       }
+    2001             :     } else {
+    2002        2562 :       Gaussian newhill=Gaussian(multivariate,height,cv,thissigma);
+    2003        2562 :       addGaussian(newhill);
+    2004        2562 :       writeGaussian(newhill,hillsOfile_);
+    2005        2562 :     }
+    2006             : 
+    2007             :     // this is to update the hills neighbor list
+    2008        2736 :     if(nlist_) nlist_update_=true;
+    2009             :   }
+    2010             : 
+    2011             :   // this should be outside of the if block in case
+    2012             :   // mw_rstride_ is not a multiple of stride_
+    2013        6239 :   if(mw_n_>1 && getStep()%mw_rstride_==0) hillsOfile_.flush();
+    2014             : 
+    2015        6239 :   if(calc_work_) {
+    2016           5 :     if(nlist_) updateNlist();
+    2017           5 :     double vbias1=getBias(cv);
+    2018           5 :     work_+=vbias1-vbias;
+    2019             :   }
+    2020             : 
+    2021             :   // dump grid on file
+    2022        6239 :   if(wgridstride_>0&&(getStep()%wgridstride_==0||getCPT())) {
+    2023             :     // in case old grids are stored, a sequence of grids should appear
+    2024             :     // this call results in a repetition of the header:
+    2025          91 :     if(storeOldGrids_) gridfile_.clearFields();
+    2026             :     // in case only latest grid is stored, file should be rewound
+    2027             :     // this will overwrite previously written grids
+    2028             :     else {
+    2029          51 :       int r = 0;
+    2030          51 :       if(walkers_mpi_) {
+    2031           0 :         if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+    2032           0 :         comm.Bcast(r,0);
+    2033             :       }
+    2034          51 :       if(r==0) gridfile_.rewind();
+    2035             :     }
+    2036          91 :     BiasGrid_->writeToFile(gridfile_);
+    2037             :     // if a single grid is stored, it is necessary to flush it, otherwise
+    2038             :     // the file might stay empty forever (when a single grid is not large enough to
+    2039             :     // trigger flushing from the operating system).
+    2040             :     // on the other hand, if grids are stored one after the other this is
+    2041             :     // no necessary, and we leave the flushing control to the user as usual
+    2042             :     // (with FLUSH keyword)
+    2043          91 :     if(!storeOldGrids_) gridfile_.flush();
+    2044             :   }
+    2045             : 
+    2046             :   // if multiple walkers and time to read Gaussians
+    2047        6239 :   if(mw_n_>1 && getStep()%mw_rstride_==0) {
+    2048       12048 :     for(int i=0; i<mw_n_; ++i) {
+    2049             :       // don't read your own Gaussians
+    2050        9036 :       if(i==mw_id_) continue;
+    2051             :       // if the file is not open yet
+    2052        6024 :       if(!(ifiles_[i]->isOpen())) {
+    2053             :         // check if it exists now and open it!
+    2054           6 :         if(ifiles_[i]->FileExist(ifilesnames_[i])) {
+    2055           6 :           ifiles_[i]->open(ifilesnames_[i]);
+    2056           6 :           ifiles_[i]->reset(false);
+    2057             :         }
+    2058             :         // otherwise read the new Gaussians
+    2059             :       } else {
+    2060        6018 :         log.printf("  Reading hills from %s:",ifilesnames_[i].c_str());
+    2061        6018 :         readGaussians(ifiles_[i].get());
+    2062        6018 :         ifiles_[i]->reset(false);
+    2063             :       }
+    2064             :     }
+    2065             :     // this is to update the hills neighbor list
+    2066        3012 :     if(nlist_) nlist_update_=true;
+    2067             :   }
+    2068             : 
+    2069             :   // Recalculate special bias quantities whenever the bias has been changed by the update.
+    2070        6239 :   bool bias_has_changed = (nowAddAHill || (mw_n_ > 1 && getStep() % mw_rstride_ == 0));
+    2071        6239 :   if (calc_rct_ && bias_has_changed && getStep()%(stride_*rct_ustride_)==0) computeReweightingFactor();
+    2072        6239 :   if (calc_max_bias_ && bias_has_changed) {
+    2073           0 :     max_bias_ = BiasGrid_->getMaxValue();
+    2074           0 :     getPntrToComponent("maxbias")->set(max_bias_);
+    2075             :   }
+    2076        6239 :   if (calc_transition_bias_ && bias_has_changed) {
+    2077         260 :     transition_bias_ = getTransitionBarrierBias();
+    2078         520 :     getPntrToComponent("transbias")->set(transition_bias_);
+    2079             :   }
+    2080             : 
+    2081             :   // Frequency adaptive metadynamics - update hill addition frequency
+    2082        6239 :   if(freq_adaptive_ && getStep()%fa_update_frequency_==0) {
+    2083         151 :     updateFrequencyAdaptiveStride();
+    2084             :   }
+    2085        6239 : }
+    2086             : 
+    2087             : /// takes a pointer to the file and a template std::string with values v and gives back the next center, sigma and height
+    2088        8499 : bool MetaD::scanOneHill(IFile* ifile, std::vector<Value>& tmpvalues, std::vector<double>& center, std::vector<double>& sigma, double& height, bool& multivariate)
+    2089             : {
+    2090             :   double dummy;
+    2091        8499 :   multivariate=false;
+    2092       16998 :   if(ifile->scanField("time",dummy)) {
+    2093        2462 :     unsigned ncv=tmpvalues.size();
+    2094        7340 :     for(unsigned i=0; i<ncv; ++i) {
+    2095        4878 :       ifile->scanField( &tmpvalues[i] );
+    2096        4878 :       if( tmpvalues[i].isPeriodic() && ! getPntrToArgument(i)->isPeriodic() ) {
+    2097           0 :         error("in hills file periodicity for variable " + tmpvalues[i].getName() + " does not match periodicity in input");
+    2098        4878 :       } else if( tmpvalues[i].isPeriodic() ) {
+    2099           0 :         std::string imin, imax; tmpvalues[i].getDomain( imin, imax );
+    2100           0 :         std::string rmin, rmax; getPntrToArgument(i)->getDomain( rmin, rmax );
+    2101           0 :         if( imin!=rmin || imax!=rmax ) {
+    2102           0 :           error("in hills file periodicity for variable " + tmpvalues[i].getName() + " does not match periodicity in input");
+    2103             :         }
+    2104             :       }
+    2105        4878 :       center[i]=tmpvalues[i].get();
+    2106             :     }
+    2107             :     // scan for kerneltype
+    2108        2462 :     std::string ktype="stretched-gaussian";
+    2109        7377 :     if( ifile->FieldExist("kerneltype") ) ifile->scanField("kerneltype",ktype);
+    2110        2462 :     if( ktype=="gaussian" ) {
+    2111          12 :       noStretchWarning();
+    2112        2450 :     } else if( ktype!="stretched-gaussian") {
+    2113           0 :       error("non Gaussian kernels are not supported in MetaD");
+    2114             :     }
+    2115             :     // scan for multivariate label: record the actual file position so to eventually rewind
+    2116             :     std::string sss;
+    2117        4924 :     ifile->scanField("multivariate",sss);
+    2118        2462 :     if(sss=="true") multivariate=true;
+    2119        2462 :     else if(sss=="false") multivariate=false;
+    2120           0 :     else plumed_merror("cannot parse multivariate = "+ sss);
+    2121        2462 :     if(multivariate) {
+    2122           0 :       sigma.resize(ncv*(ncv+1)/2);
+    2123             :       Matrix<double> upper(ncv,ncv);
+    2124             :       Matrix<double> lower(ncv,ncv);
+    2125           0 :       for(unsigned i=0; i<ncv; i++) {
+    2126           0 :         for(unsigned j=0; j<ncv-i; j++) {
+    2127           0 :           ifile->scanField("sigma_"+getPntrToArgument(j+i)->getName()+"_"+getPntrToArgument(j)->getName(),lower(j+i,j));
+    2128           0 :           upper(j,j+i)=lower(j+i,j);
+    2129             :         }
+    2130             :       }
+    2131             :       Matrix<double> mymult(ncv,ncv);
+    2132             :       Matrix<double> invmatrix(ncv,ncv);
+    2133           0 :       mult(lower,upper,mymult);
+    2134             :       // now invert and get the sigmas
+    2135           0 :       Invert(mymult,invmatrix);
+    2136             :       // put the sigmas in the usual order: upper diagonal (this time in normal form and not in band form)
+    2137             :       unsigned k=0;
+    2138           0 :       for(unsigned i=0; i<ncv; i++) {
+    2139           0 :         for(unsigned j=i; j<ncv; j++) {
+    2140           0 :           sigma[k]=invmatrix(i,j);
+    2141           0 :           k++;
+    2142             :         }
+    2143             :       }
+    2144             :     } else {
+    2145        7340 :       for(unsigned i=0; i<ncv; ++i) {
+    2146        9756 :         ifile->scanField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+    2147             :       }
+    2148             :     }
+    2149             : 
+    2150        2462 :     ifile->scanField("height",height);
+    2151        2462 :     ifile->scanField("biasf",dummy);
+    2152        7203 :     if(ifile->FieldExist("clock")) ifile->scanField("clock",dummy);
+    2153        4924 :     if(ifile->FieldExist("lower_int")) ifile->scanField("lower_int",dummy);
+    2154        4924 :     if(ifile->FieldExist("upper_int")) ifile->scanField("upper_int",dummy);
+    2155        2462 :     ifile->scanField();
+    2156             :     return true;
+    2157             :   } else {
+    2158             :     return false;
+    2159             :   }
+    2160             : }
+    2161             : 
+    2162         102 : void MetaD::computeReweightingFactor()
+    2163             : {
+    2164         102 :   if(biasf_==1.0) { // in this case we have no bias, so reweight factor is 0.0
+    2165           0 :     getPntrToComponent("rct")->set(0.0);
+    2166           0 :     return;
+    2167             :   }
+    2168             : 
+    2169         102 :   double Z_0=0; //proportional to the integral of exp(-beta*F)
+    2170         102 :   double Z_V=0; //proportional to the integral of exp(-beta*(F+V))
+    2171         102 :   double minusBetaF=biasf_/(biasf_-1.)/kbt_;
+    2172         102 :   double minusBetaFplusV=1./(biasf_-1.)/kbt_;
+    2173         102 :   if (biasf_==-1.0) { //non well-tempered case
+    2174           0 :     minusBetaF=1./kbt_;
+    2175             :     minusBetaFplusV=0;
+    2176             :   }
+    2177         102 :   max_bias_=BiasGrid_->getMaxValue(); //to avoid exp overflow
+    2178             : 
+    2179         102 :   const unsigned rank=comm.Get_rank();
+    2180         102 :   const unsigned stride=comm.Get_size();
+    2181      920504 :   for (Grid::index_t t=rank; t<BiasGrid_->getSize(); t+=stride) {
+    2182      920402 :     const double val=BiasGrid_->getValue(t);
+    2183      920402 :     Z_0+=std::exp(minusBetaF*(val-max_bias_));
+    2184      920402 :     Z_V+=std::exp(minusBetaFplusV*(val-max_bias_));
+    2185             :   }
+    2186         102 :   comm.Sum(Z_0);
+    2187         102 :   comm.Sum(Z_V);
+    2188             : 
+    2189         102 :   reweight_factor_=kbt_*std::log(Z_0/Z_V)+max_bias_;
+    2190         204 :   getPntrToComponent("rct")->set(reweight_factor_);
+    2191             : }
+    2192             : 
+    2193         273 : double MetaD::getTransitionBarrierBias()
+    2194             : {
+    2195             :   // If there is only one well of interest, return the bias at that well point.
+    2196         273 :   if (transitionwells_.size() == 1) {
+    2197           0 :     double tb_bias = getBias(transitionwells_[0]);
+    2198           0 :     return tb_bias;
+    2199             : 
+    2200             :     // Otherwise, check for the least barrier bias between all pairs of wells.
+    2201             :     // Note that because the paths can be considered edges between the wells' nodes
+    2202             :     // to make a graph and the path barriers satisfy certain cycle inequalities, it
+    2203             :     // is sufficient to look at paths corresponding to a minimal spanning tree of the
+    2204             :     // overall graph rather than examining every edge in the graph.
+    2205             :     // For simplicity, I chose the star graph with center well 0 as the spanning tree.
+    2206             :     // It is most efficient to start the path searches from the wells that are
+    2207             :     // expected to be sampled last, so transitionwell_[0] should correspond to the
+    2208             :     // starting well. With this choice the searches will terminate in one step until
+    2209             :     // transitionwell_[1] is sampled.
+    2210             :   } else {
+    2211             :     double least_transition_bias;
+    2212         273 :     std::vector<double> sink = transitionwells_[0];
+    2213         273 :     std::vector<double> source = transitionwells_[1];
+    2214         273 :     least_transition_bias = BiasGrid_->findMaximalPathMinimum(source, sink);
+    2215         273 :     for (unsigned i = 2; i < transitionwells_.size(); i++) {
+    2216           0 :       if (least_transition_bias == 0.0) {
+    2217             :         break;
+    2218             :       }
+    2219           0 :       source = transitionwells_[i];
+    2220           0 :       double curr_transition_bias = BiasGrid_->findMaximalPathMinimum(source, sink);
+    2221           0 :       least_transition_bias = fmin(curr_transition_bias, least_transition_bias);
+    2222             :     }
+    2223             :     return least_transition_bias;
+    2224             :   }
+    2225             : }
+    2226             : 
+    2227         154 : void MetaD::updateFrequencyAdaptiveStride()
+    2228             : {
+    2229         154 :   plumed_massert(freq_adaptive_,"should only be used if frequency adaptive metadynamics is enabled");
+    2230         154 :   plumed_massert(acceleration_,"frequency adaptive metadynamics can only be used if the acceleration factor is calculated");
+    2231         154 :   const double mean_acc = acc_/((double) getStep());
+    2232         154 :   int tmp_stride= stride_*floor((mean_acc/fa_min_acceleration_)+0.5);
+    2233         154 :   if(mean_acc >= fa_min_acceleration_) {
+    2234         129 :     if(tmp_stride > current_stride_) {current_stride_ = tmp_stride;}
+    2235             :   }
+    2236         154 :   if(fa_max_stride_!=0 && current_stride_>fa_max_stride_) {
+    2237           0 :     current_stride_=fa_max_stride_;
+    2238             :   }
+    2239         154 :   getPntrToComponent("pace")->set(current_stride_);
+    2240         154 : }
+    2241             : 
+    2242        8435 : bool MetaD::checkNeedsGradients()const
+    2243             : {
+    2244        8435 :   if(adaptive_==FlexibleBin::geometry) {
+    2245         192 :     if(getStep()%stride_==0 && !isFirstStep_) return true;
+    2246         109 :     else return false;
+    2247             :   } else return false;
+    2248             : }
+    2249             : 
+    2250           4 : void MetaD::updateNlist()
+    2251             : {
+    2252             :   // no need to check for neighbors
+    2253           4 :   if(hills_.size()==0) return;
+    2254             : 
+    2255             :   // here we generate the neighbor list
+    2256           4 :   nlist_hills_.clear();
+    2257             :   std::vector<Gaussian> local_flat_nl;
+    2258           4 :   unsigned nt=OpenMP::getNumThreads();
+    2259           4 :   if(hills_.size()<2*nt) nt=1;
+    2260           4 :   #pragma omp parallel num_threads(nt)
+    2261             :   {
+    2262             :     std::vector<Gaussian> private_flat_nl;
+    2263             :     #pragma omp for nowait
+    2264             :     for(unsigned k=0; k<hills_.size(); k++)
+    2265             :     {
+    2266             :       double dist2=0;
+    2267             :       for(unsigned i=0; i<getNumberOfArguments(); i++)
+    2268             :       {
+    2269             :         const double d=difference(i,getArgument(i),hills_[k].center[i])/hills_[k].sigma[i];
+    2270             :         dist2+=d*d;
+    2271             :       }
+    2272             :       if(dist2<=nlist_param_[0]*dp2cutoff) private_flat_nl.push_back(hills_[k]);
+    2273             :     }
+    2274             :     #pragma omp critical
+    2275             :     local_flat_nl.insert(local_flat_nl.end(), private_flat_nl.begin(), private_flat_nl.end());
+    2276             :   }
+    2277           4 :   nlist_hills_ = local_flat_nl;
+    2278             : 
+    2279             :   // here we set some properties that are used to decide when to update it again
+    2280          12 :   for(unsigned i=0; i<getNumberOfArguments(); i++) nlist_center_[i]=getArgument(i);
+    2281             :   std::vector<double> dev2;
+    2282           4 :   dev2.resize(getNumberOfArguments(),0);
+    2283          46 :   for(unsigned k=0; k<nlist_hills_.size(); k++)
+    2284             :   {
+    2285         126 :     for(unsigned i=0; i<getNumberOfArguments(); i++)
+    2286             :     {
+    2287          84 :       const double d=difference(i,getArgument(i),nlist_hills_[k].center[i]);
+    2288          84 :       dev2[i]+=d*d;
+    2289             :     }
+    2290             :   }
+    2291          12 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+    2292           8 :     if(dev2[i]>0.) nlist_dev2_[i]=dev2[i]/static_cast<double>(nlist_hills_.size());
+    2293           0 :     else nlist_dev2_[i]=hills_.back().sigma[i]*hills_.back().sigma[i];
+    2294             :   }
+    2295             : 
+    2296             :   // we are done
+    2297           4 :   getPntrToComponent("nlker")->set(nlist_hills_.size());
+    2298           4 :   getPntrToComponent("nlsteps")->set(nlist_steps_);
+    2299           4 :   nlist_steps_=0;
+    2300           4 :   nlist_update_=false;
+    2301           4 : }
+    2302             : 
+    2303             : }
+    2304             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MovingRestraint.cpp.func-sort-c.html b/coverage/bias/MovingRestraint.cpp.func-sort-c.html new file mode 100644 index 000000000000..fe9e5928d682 --- /dev/null +++ b/coverage/bias/MovingRestraint.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/MovingRestraint.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - MovingRestraint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101101100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias15MovingRestraintC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias15MovingRestraintC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias15MovingRestraint16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4bias15MovingRestraint9calculateEv566
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MovingRestraint.cpp.func.html b/coverage/bias/MovingRestraint.cpp.func.html new file mode 100644 index 000000000000..411f760b1573 --- /dev/null +++ b/coverage/bias/MovingRestraint.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/MovingRestraint.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - MovingRestraint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101101100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias15MovingRestraint16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4bias15MovingRestraint9calculateEv566
_ZN4PLMD4bias15MovingRestraintC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias15MovingRestraintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/MovingRestraint.cpp.gcov.html b/coverage/bias/MovingRestraint.cpp.gcov.html new file mode 100644 index 000000000000..61b9cb836d02 --- /dev/null +++ b/coverage/bias/MovingRestraint.cpp.gcov.html @@ -0,0 +1,343 @@ + + + + + + + + LCOV - plumed test coverage - bias/MovingRestraint.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - MovingRestraint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101101100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace bias {
+      27             : 
+      28             : //+PLUMEDOC BIAS MOVINGRESTRAINT
+      29             : /*
+      30             : Add a time-dependent, harmonic restraint on one or more variables.
+      31             : 
+      32             : This form of bias can be used to performed steered MD \cite Grubmuller3
+      33             : and Jarzynski sampling \cite jarzynski.
+      34             : 
+      35             : The harmonic restraint on your system is given by:
+      36             : 
+      37             : \f[
+      38             : V(\vec{s},t) = \frac{1}{2} \kappa(t) ( \vec{s} - \vec{s}_0(t) )^2
+      39             : \f]
+      40             : 
+      41             : The time dependence of \f$\kappa\f$ and \f$\vec{s}_0\f$ are specified by a list of
+      42             : STEP, KAPPA and AT keywords.  These keywords tell plumed what values \f$\kappa\f$ and \f$\vec{s}_0\f$
+      43             : should have at the time specified by the corresponding STEP keyword.  In between these times
+      44             : the values of \f$\kappa\f$ and \f$\vec{s}_0\f$ are linearly interpolated.
+      45             : 
+      46             : Additional material and examples can be also found in the tutorial \ref belfast-5
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : The following input is dragging the distance between atoms 2 and 4
+      51             : from 1 to 2 in the first 1000 steps, then back in the next 1000 steps.
+      52             : In the following 500 steps the restraint is progressively switched off.
+      53             : \plumedfile
+      54             : DISTANCE ATOMS=2,4 LABEL=d
+      55             : MOVINGRESTRAINT ...
+      56             :   ARG=d
+      57             :   STEP0=0    AT0=1.0 KAPPA0=100.0
+      58             :   STEP1=1000 AT1=2.0
+      59             :   STEP2=2000 AT2=1.0
+      60             :   STEP3=2500         KAPPA3=0.0
+      61             : ... MOVINGRESTRAINT
+      62             : \endplumedfile
+      63             : The following input is progressively building restraints
+      64             : distances between atoms 1 and 5 and between atoms 2 and 4
+      65             : in the first 1000 steps. Afterwards, the restraint is kept
+      66             : static.
+      67             : \plumedfile
+      68             : DISTANCE ATOMS=1,5 LABEL=d1
+      69             : DISTANCE ATOMS=2,4 LABEL=d2
+      70             : MOVINGRESTRAINT ...
+      71             :   ARG=d1,d2
+      72             :   STEP0=0    AT0=1.0,1.5 KAPPA0=0.0,0.0
+      73             :   STEP1=1000 AT1=1.0,1.5 KAPPA1=1.0,1.0
+      74             : ... MOVINGRESTRAINT
+      75             : \endplumedfile
+      76             : The following input is progressively bringing atoms 1 and 2
+      77             : close to each other with an upper wall
+      78             : \plumedfile
+      79             : DISTANCE ATOMS=1,2 LABEL=d1
+      80             : MOVINGRESTRAINT ...
+      81             :   ARG=d1
+      82             :   VERSE=U
+      83             :   STEP0=0    AT0=1.0 KAPPA0=10.0
+      84             :   STEP1=1000 AT1=0.0
+      85             : ... MOVINGRESTRAINT
+      86             : \endplumedfile
+      87             : 
+      88             : By default the Action is issuing some values which are
+      89             : the work on each degree of freedom, the center of the harmonic potential,
+      90             : the total bias deposited
+      91             : 
+      92             : (See also \ref DISTANCE).
+      93             : 
+      94             : \attention Work is not computed properly when KAPPA is time dependent.
+      95             : 
+      96             : */
+      97             : //+ENDPLUMEDOC
+      98             : 
+      99             : 
+     100             : class MovingRestraint : public Bias {
+     101             :   std::vector<std::vector<double> > at;
+     102             :   std::vector<std::vector<double> > kappa;
+     103             :   std::vector<long long int> step;
+     104             :   std::vector<double> oldaa;
+     105             :   std::vector<double> oldk;
+     106             :   std::vector<double> olddpotdk;
+     107             :   std::vector<double> oldf;
+     108             :   std::vector<std::string> verse;
+     109             :   std::vector<double> work;
+     110             :   double tot_work;
+     111             : public:
+     112             :   explicit MovingRestraint(const ActionOptions&);
+     113             :   void calculate() override;
+     114             :   static void registerKeywords( Keywords& keys );
+     115             : };
+     116             : 
+     117             : PLUMED_REGISTER_ACTION(MovingRestraint,"MOVINGRESTRAINT")
+     118             : 
+     119           6 : void MovingRestraint::registerKeywords( Keywords& keys ) {
+     120           6 :   Bias::registerKeywords(keys);
+     121           6 :   keys.use("ARG");
+     122          12 :   keys.add("compulsory","VERSE","B","Tells plumed whether the restraint is only acting for CV larger (U) or smaller (L) than "
+     123             :            "the restraint or whether it is acting on both sides (B)");
+     124          12 :   keys.add("numbered","STEP","This keyword appears multiple times as STEP\\f$x\\f$ with x=0,1,2,...,n. Each value given represents "
+     125             :            "the MD step at which the restraint parameters take the values KAPPA\\f$x\\f$ and AT\\f$x\\f$.");
+     126          12 :   keys.reset_style("STEP","compulsory");
+     127          12 :   keys.add("numbered","AT","AT\\f$x\\f$ is equal to the position of the restraint at time STEP\\f$x\\f$. For intermediate times this parameter "
+     128             :            "is linearly interpolated. If no AT\\f$x\\f$ is specified for STEP\\f$x\\f$ then the values of AT are kept constant "
+     129             :            "during the interval of time between STEP\\f$x-1\\f$ and STEP\\f$x\\f$.");
+     130          12 :   keys.reset_style("AT","compulsory");
+     131          12 :   keys.add("numbered","KAPPA","KAPPA\\f$x\\f$ is equal to the value of the force constants at time STEP\\f$x\\f$. For intermediate times this "
+     132             :            "parameter is linearly interpolated.  If no KAPPA\\f$x\\f$ is specified for STEP\\f$x\\f$ then the values of KAPPA\\f$x\\f$ "
+     133             :            "are kept constant during the interval of time between STEP\\f$x-1\\f$ and STEP\\f$x\\f$.");
+     134          12 :   keys.reset_style("KAPPA","compulsory");
+     135          12 :   keys.addOutputComponent("work","default","the total work performed changing this restraint");
+     136          12 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+     137          12 :   keys.addOutputComponent("_cntr","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     138             :                           "these quantities will named with  the arguments of the bias followed by "
+     139             :                           "the character string _cntr. These quantities give the instantaneous position "
+     140             :                           "of the center of the harmonic potential.");
+     141          12 :   keys.addOutputComponent("_work","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     142             :                           "These quantities will named with the arguments of the bias followed by "
+     143             :                           "the character string _work. These quantities tell the user how much work has "
+     144             :                           "been done by the potential in dragging the system along the various colvar axis.");
+     145          12 :   keys.addOutputComponent("_kappa","default","one or multiple instances of this quantity can be referenced elsewhere in the input file. "
+     146             :                           "These quantities will named with the arguments of the bias followed by "
+     147             :                           "the character string _kappa. These quantities tell the user the time dependent value of kappa.");
+     148           6 : }
+     149             : 
+     150           4 : MovingRestraint::MovingRestraint(const ActionOptions&ao):
+     151             :   PLUMED_BIAS_INIT(ao),
+     152           4 :   verse(getNumberOfArguments())
+     153             : {
+     154           4 :   parseVector("VERSE",verse);
+     155           4 :   std::vector<long long int> ss(1); ss[0]=-1;
+     156           4 :   std::vector<double> kk( getNumberOfArguments() ), aa( getNumberOfArguments() );
+     157          10 :   for(int i=0;; i++) {
+     158             :     // Read in step
+     159          28 :     if( !parseNumberedVector("STEP",i,ss) ) break;
+     160          19 :     for(unsigned j=0; j<step.size(); j++) {
+     161           9 :       if(ss[0]<step[j]) error("in moving restraint step number must always increase");
+     162             :     }
+     163          10 :     step.push_back(ss[0]);
+     164             : 
+     165             :     // Try to read kappa
+     166          20 :     if( !parseNumberedVector("KAPPA",i,kk) ) kk=kappa[i-1];
+     167          10 :     kappa.push_back(kk);
+     168             : 
+     169             :     // Now read AT
+     170          20 :     if( !parseNumberedVector("AT",i,aa) ) aa=at[i-1];
+     171          10 :     at.push_back(aa);
+     172          10 :   }
+     173           4 :   checkRead();
+     174             : 
+     175          14 :   for(unsigned i=0; i<step.size(); i++) {
+     176          10 :     log.printf("  step%u %lld\n",i,step[i]);
+     177          10 :     log.printf("  at");
+     178          22 :     for(unsigned j=0; j<at[i].size(); j++) log.printf(" %f",at[i][j]);
+     179          10 :     log.printf("\n");
+     180          10 :     log.printf("  with force constant");
+     181          22 :     for(unsigned j=0; j<kappa[i].size(); j++) log.printf(" %f",kappa[i][j]);
+     182          10 :     log.printf("\n");
+     183             :   };
+     184             : 
+     185          12 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     186             : 
+     187             :   // add the centers of the restraint as additional components that can be retrieved (useful for debug)
+     188             : 
+     189             :   std::string comp;
+     190           9 :   for(unsigned i=0; i< getNumberOfArguments() ; i++) {
+     191          10 :     comp=getPntrToArgument(i)->getName()+"_cntr"; // each spring has its own center
+     192          10 :     addComponent(comp); componentIsNotPeriodic(comp);
+     193          10 :     comp=getPntrToArgument(i)->getName()+"_work"; // each spring has its own work
+     194          10 :     addComponent(comp); componentIsNotPeriodic(comp);
+     195          10 :     comp=getPntrToArgument(i)->getName()+"_kappa"; // each spring has its own kappa
+     196          10 :     addComponent(comp); componentIsNotPeriodic(comp);
+     197           5 :     work.push_back(0.); // initialize the work value
+     198             :   }
+     199           8 :   addComponent("work"); componentIsNotPeriodic("work");
+     200           4 :   tot_work=0.0;
+     201             : 
+     202           4 :   log<<"  Bibliography ";
+     203           8 :   log<<cite("Grubmuller, Heymann, and Tavan, Science 271, 997 (1996)")<<"\n";
+     204             : 
+     205           4 : }
+     206             : 
+     207             : 
+     208         566 : void MovingRestraint::calculate() {
+     209             :   double ene=0.0;
+     210             :   double totf2=0.0;
+     211         566 :   unsigned narg=getNumberOfArguments();
+     212         566 :   long long int now=getStep();
+     213         566 :   std::vector<double> kk(narg),aa(narg),f(narg),dpotdk(narg);
+     214         566 :   if(now<=step[0]) {
+     215           3 :     kk=kappa[0];
+     216           3 :     aa=at[0];
+     217           3 :     oldaa=at[0];
+     218           3 :     oldk=kappa[0];
+     219           3 :     olddpotdk.resize(narg);
+     220           3 :     oldf.resize(narg);
+     221         563 :   } else if(now>=step[step.size()-1]) {
+     222          47 :     kk=kappa[step.size()-1];
+     223          47 :     aa=at[step.size()-1];
+     224             :   } else {
+     225             :     unsigned i=0;
+     226         521 :     for(i=1; i<step.size()-1; i++) if(now<step[i]) break;
+     227         516 :     double c2=(now-step[i-1])/double(step[i]-step[i-1]);
+     228         516 :     double c1=1.0-c2;
+     229        1040 :     for(unsigned j=0; j<narg; j++) kk[j]=(c1*kappa[i-1][j]+c2*kappa[i][j]);
+     230        1040 :     for(unsigned j=0; j<narg; j++) {
+     231         524 :       const double a1=at[i-1][j];
+     232         524 :       const double a2=at[i][j];
+     233         524 :       aa[j]=(c1*a1+c2*(a1+difference(j,a1,a2)));
+     234             :     }
+     235             :   }
+     236         566 :   tot_work=0.0;
+     237        1142 :   for(unsigned i=0; i<narg; ++i) {
+     238         576 :     const double cv=difference(i,aa[i],getArgument(i)); // this gives: getArgument(i) - aa[i]
+     239        1152 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_cntr")->set(aa[i]);
+     240         576 :     const double k=kk[i];
+     241         576 :     f[i]=-k*cv;
+     242         576 :     if(verse[i]=="U" && cv<0) continue;
+     243         576 :     if(verse[i]=="L" && cv>0) continue;
+     244        1728 :     plumed_assert(verse[i]=="U" || verse[i]=="L" || verse[i]=="B");
+     245         576 :     dpotdk[i]=0.5*cv*cv;
+     246         576 :     if(oldaa.size()==aa.size() && oldf.size()==f.size()) work[i]+=0.5*(oldf[i]+f[i])*(aa[i]-oldaa[i]) + 0.5*( dpotdk[i]+olddpotdk[i] )*(kk[i]-oldk[i]);
+     247        1152 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_work")->set(work[i]);
+     248        1152 :     getPntrToComponent(getPntrToArgument(i)->getName()+"_kappa")->set(kk[i]);
+     249         576 :     tot_work+=work[i];
+     250         576 :     ene+=0.5*k*cv*cv;
+     251         576 :     setOutputForce(i,f[i]);
+     252         576 :     totf2+=f[i]*f[i];
+     253             :   };
+     254         566 :   getPntrToComponent("work")->set(tot_work);
+     255         566 :   oldf=f;
+     256         566 :   oldaa=aa;
+     257         566 :   oldk=kk;
+     258         566 :   olddpotdk=dpotdk;
+     259         566 :   setBias(ene);
+     260        1132 :   getPntrToComponent("force2")->set(totf2);
+     261         566 : }
+     262             : 
+     263             : }
+     264             : }
+     265             : 
+     266             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/PBMetaD.cpp.func-sort-c.html b/coverage/bias/PBMetaD.cpp.func-sort-c.html new file mode 100644 index 000000000000..cba503dbb058 --- /dev/null +++ b/coverage/bias/PBMetaD.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - bias/PBMetaD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - PBMetaD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:56664188.3 %
Date:2024-02-22 21:58:45Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias7PBMetaD16noStretchWarningEv0
_ZN4PLMD4bias7PBMetaDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias7PBMetaD13readGaussiansEjPNS_5IFileE2
_ZN4PLMD4bias7PBMetaD11scanOneHillEjPNS_5IFileERSt6vectorINS_5ValueESaIS5_EERS4_IdSaIdEESB_RdRb10
_ZN4PLMD4bias7PBMetaDC1ERKNS_13ActionOptionsE41
_ZN4PLMD4bias7PBMetaD16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD4bias7PBMetaD18getGaussianSupportEjRKNS1_8GaussianE196
_ZN4PLMD4bias7PBMetaD6updateEv335
_ZN4PLMD4bias7PBMetaD9calculateEv335
_ZNK4PLMD4bias7PBMetaD19checkNeedsGradientsEv335
_ZN4PLMD4bias7PBMetaD13writeGaussianEjRKNS1_8GaussianEPNS_5OFileE1100
_ZN4PLMD4bias7PBMetaD11addGaussianEjRKNS1_8GaussianE1108
_ZN4PLMD4bias7PBMetaD8GaussianC2ERKSt6vectorIdSaIdEES7_db1108
_ZN4PLMD4bias7PBMetaD21getBiasAndDerivativesEjRKSt6vectorIdSaIdEEPd1269
_ZN4PLMD4bias7PBMetaD16evaluateGaussianEjRKSt6vectorIdSaIdEERKNS1_8GaussianEPd8664
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/PBMetaD.cpp.func.html b/coverage/bias/PBMetaD.cpp.func.html new file mode 100644 index 000000000000..d8526f679389 --- /dev/null +++ b/coverage/bias/PBMetaD.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - bias/PBMetaD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - PBMetaD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:56664188.3 %
Date:2024-02-22 21:58:45Functions:131586.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias7PBMetaD11addGaussianEjRKNS1_8GaussianE1108
_ZN4PLMD4bias7PBMetaD11scanOneHillEjPNS_5IFileERSt6vectorINS_5ValueESaIS5_EERS4_IdSaIdEESB_RdRb10
_ZN4PLMD4bias7PBMetaD13readGaussiansEjPNS_5IFileE2
_ZN4PLMD4bias7PBMetaD13writeGaussianEjRKNS1_8GaussianEPNS_5OFileE1100
_ZN4PLMD4bias7PBMetaD16evaluateGaussianEjRKSt6vectorIdSaIdEERKNS1_8GaussianEPd8664
_ZN4PLMD4bias7PBMetaD16noStretchWarningEv0
_ZN4PLMD4bias7PBMetaD16registerKeywordsERNS_8KeywordsE43
_ZN4PLMD4bias7PBMetaD18getGaussianSupportEjRKNS1_8GaussianE196
_ZN4PLMD4bias7PBMetaD21getBiasAndDerivativesEjRKSt6vectorIdSaIdEEPd1269
_ZN4PLMD4bias7PBMetaD6updateEv335
_ZN4PLMD4bias7PBMetaD8GaussianC2ERKSt6vectorIdSaIdEES7_db1108
_ZN4PLMD4bias7PBMetaD9calculateEv335
_ZN4PLMD4bias7PBMetaDC1ERKNS_13ActionOptionsE41
_ZN4PLMD4bias7PBMetaDC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4bias7PBMetaD19checkNeedsGradientsEv335
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/PBMetaD.cpp.gcov.html b/coverage/bias/PBMetaD.cpp.gcov.html new file mode 100644 index 000000000000..33228fdf7d68 --- /dev/null +++ b/coverage/bias/PBMetaD.cpp.gcov.html @@ -0,0 +1,1391 @@ + + + + + + + + LCOV - plumed test coverage - bias/PBMetaD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - PBMetaD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:56664188.3 %
Date:2024-02-22 21:58:45Functions:131586.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/FlexibleBin.h"
+      27             : #include "tools/Exception.h"
+      28             : #include "tools/Grid.h"
+      29             : #include "tools/Matrix.h"
+      30             : #include "tools/OpenMP.h"
+      31             : #include "tools/Random.h"
+      32             : #include "tools/File.h"
+      33             : #include "tools/Communicator.h"
+      34             : #include <ctime>
+      35             : #include <numeric>
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace bias {
+      39             : 
+      40             : //+PLUMEDOC BIAS PBMETAD
+      41             : /*
+      42             : Used to performed Parallel Bias metadynamics.
+      43             : 
+      44             : This action activate Parallel Bias Metadynamics (PBMetaD) \cite pbmetad, a version of metadynamics \cite metad in which
+      45             : multiple low-dimensional bias potentials are applied in parallel.
+      46             : In the current implementation, these have the form of mono-dimensional metadynamics bias
+      47             : potentials:
+      48             : 
+      49             : \f[
+      50             : {V(s_1,t), ..., V(s_N,t)}
+      51             : \f]
+      52             : 
+      53             : where:
+      54             : 
+      55             : \f[
+      56             : V(s_i,t) = \sum_{ k \tau < t} W_i(k \tau)
+      57             : \exp\left(
+      58             : - \frac{(s_i-s_i^{(0)}(k \tau))^2}{2\sigma_i^2}
+      59             : \right).
+      60             : \f]
+      61             : 
+      62             : To ensure the convergence of each mono-dimensional bias potential to the corresponding free energy,
+      63             : at each deposition step the Gaussian heights are multiplied by the so-called conditional term:
+      64             : 
+      65             : \f[
+      66             : W_i(k \tau)=W_0 \frac{\exp\left(
+      67             : - \frac{V(s_i,k \tau)}{k_B T}
+      68             : \right)}{\sum_{i=1}^N
+      69             : \exp\left(
+      70             : - \frac{V(s_i,k \tau)}{k_B T}
+      71             : \right)}
+      72             : \f]
+      73             : 
+      74             : where \f$W_0\f$ is the initial Gaussian height.
+      75             : 
+      76             : The PBMetaD bias potential is defined by:
+      77             : 
+      78             : \f[
+      79             : V_{PB}(\vec{s},t) = -k_B T \log{\sum_{i=1}^N
+      80             : \exp\left(
+      81             : - \frac{V(s_i,t)}{k_B T}
+      82             : \right)}.
+      83             : \f]
+      84             : 
+      85             : 
+      86             : Information on the Gaussian functions that build each bias potential are printed to
+      87             : multiple HILLS files, which
+      88             : are used both to restart the calculation and to reconstruct the mono-dimensional
+      89             : free energies as a function of the corresponding CVs.
+      90             : These can be reconstructed using the \ref sum_hills utility because the final bias is given
+      91             : by:
+      92             : 
+      93             : \f[
+      94             : V(s_i) = -F(s_i)
+      95             : \f]
+      96             : 
+      97             : Currently, only a subset of the \ref METAD options are available in PBMetaD.
+      98             : 
+      99             : The bias potentials can be stored on a grid to increase performances of long PBMetaD simulations.
+     100             : You should
+     101             : provide either the number of bins for every collective variable (GRID_BIN) or
+     102             : the desired grid spacing (GRID_SPACING). In case you provide both PLUMED will use
+     103             : the most conservative choice (highest number of bins) for each dimension.
+     104             : In case you do not provide any information about bin size (neither GRID_BIN nor GRID_SPACING)
+     105             : and if Gaussian width is fixed PLUMED will use 1/5 of the Gaussian width as grid spacing.
+     106             : This default choice should be reasonable for most applications.
+     107             : 
+     108             : Another option that is available is well-tempered metadynamics \cite Barducci:2008. In this
+     109             : variant of PBMetaD the heights of the Gaussian hills are scaled at each step by the
+     110             : additional well-tempered metadynamics term.
+     111             : This  ensures that each bias converges more smoothly. It should be noted that, in the case of well-tempered metadynamics, in
+     112             : the output printed the Gaussian height is re-scaled using the bias factor.
+     113             : Also notice that with well-tempered metadynamics the HILLS files do not contain the bias,
+     114             : but the negative of the free-energy estimate. This choice has the advantage that
+     115             : one can restart a simulation using a different value for the \f$\Delta T\f$. The applied bias will be scaled accordingly.
+     116             : 
+     117             : Note that you can use here also the flexible Gaussian approach  \cite Branduardi:2012dl
+     118             : in which you can adapt the Gaussian to the extent of Cartesian space covered by a variable or
+     119             : to the space in collective variable covered in a given time. In this case the width of the deposited
+     120             : Gaussian potential is denoted by one value only that is a Cartesian space (ADAPTIVE=GEOM) or a time
+     121             : (ADAPTIVE=DIFF). Note that a specific integration technique for the deposited Gaussian kernels
+     122             : should be used in this case. Check the documentation for utility sum_hills.
+     123             : 
+     124             : With the keyword INTERVAL one changes the metadynamics algorithm setting the bias force equal to zero
+     125             : outside boundary \cite baftizadeh2012protein. If, for example, metadynamics is performed on a CV s and one is interested only
+     126             : to the free energy for s > boundary, the history dependent potential is still updated according to the above
+     127             : equations but the metadynamics force is set to zero for s < boundary. Notice that Gaussian kernels are added also
+     128             : if s < boundary, as the tails of these Gaussian kernels influence VG in the relevant region s > boundary. In this way, the
+     129             : force on the system in the region s > boundary comes from both metadynamics and the force field, in the region
+     130             : s < boundary only from the latter. This approach allows obtaining a history-dependent bias potential VG that
+     131             : fluctuates around a stable estimator, equal to the negative of the free energy far enough from the
+     132             : boundaries. Note that:
+     133             : - It works only for one-dimensional biases;
+     134             : - It works both with and without GRID;
+     135             : - The interval limit boundary in a region where the free energy derivative is not large;
+     136             : - If in the region outside the limit boundary the system has a free energy minimum, the INTERVAL keyword should
+     137             :   be used together with a \ref UPPER_WALLS or \ref LOWER_WALLS at boundary.
+     138             : 
+     139             : For systems with multiple CVs that share identical properties, PBMetaD with partitioned families can be used
+     140             : to group them under one bias potential that each contributes to \cite Prakash2018PF. This is done with a list
+     141             : of PF keywords, where each PF* argument contains the list of CVs from ARG to be placed in that family. Once
+     142             : invoked, each CV in ARG must be placed in exactly one PF, even if it results in families containing only one CV.
+     143             : Additionally, in cases where each of SIGMA or GRID entry would correspond to each ARG entry, they now correspond to
+     144             : each PF and must be adjusted accordingly.
+     145             : 
+     146             : Multiple walkers  \cite multiplewalkers can also be used. See below the examples.
+     147             : 
+     148             : \par Examples
+     149             : 
+     150             : The following input is for PBMetaD calculation using as
+     151             : collective variables the distance between atoms 3 and 5
+     152             : and the distance between atoms 2 and 4. The value of the CVs and
+     153             : the PBMetaD bias potential are written to the COLVAR file every 100 steps.
+     154             : \plumedfile
+     155             : DISTANCE ATOMS=3,5 LABEL=d1
+     156             : DISTANCE ATOMS=2,4 LABEL=d2
+     157             : PBMETAD ARG=d1,d2 SIGMA=0.2,0.2 HEIGHT=0.3 PACE=500 LABEL=pb FILE=HILLS_d1,HILLS_d2
+     158             : PRINT ARG=d1,d2,pb.bias STRIDE=100 FILE=COLVAR
+     159             : \endplumedfile
+     160             : (See also \ref DISTANCE and \ref PRINT).
+     161             : 
+     162             : \par
+     163             : If you use well-tempered metadynamics, you should specify a single bias factor and initial
+     164             : Gaussian height.
+     165             : \plumedfile
+     166             : DISTANCE ATOMS=3,5 LABEL=d1
+     167             : DISTANCE ATOMS=2,4 LABEL=d2
+     168             : PBMETAD ...
+     169             : ARG=d1,d2 SIGMA=0.2,0.2 HEIGHT=0.3
+     170             : PACE=500 BIASFACTOR=8 LABEL=pb
+     171             : FILE=HILLS_d1,HILLS_d2
+     172             : ... PBMETAD
+     173             : PRINT ARG=d1,d2,pb.bias STRIDE=100 FILE=COLVAR
+     174             : \endplumedfile
+     175             : 
+     176             : \par
+     177             : Using partitioned families, each CV in ARG must be in exactly one family. Here,
+     178             : the distance between atoms 1,2 is degenerate with 2,4, but not with the
+     179             : distance between 3,5. Note that two SIGMA are provided to match the two PF.
+     180             : \plumedfile
+     181             : DISTANCE ATOMS=3,5 LABEL=d1
+     182             : DISTANCE ATOMS=2,4 LABEL=d2
+     183             : DISTANCE ATOMS=1,2 LABEL=d3
+     184             : PBMETAD ...
+     185             : ARG=d1,d2,d3 SIGMA=0.2,0.2 HEIGHT=0.3
+     186             : PF0=d1 PF1=d2,d3
+     187             : PACE=500 BIASFACTOR=8 LABEL=pb
+     188             : FILE=HILLS_d1,HILLS_d2
+     189             : ... PBMETAD
+     190             : PRINT ARG=d1,d2,d3,pb.bias STRIDE=100 FILE=COLVAR
+     191             : \endplumedfile
+     192             : 
+     193             : \par
+     194             : The following input enables the MPI version of multiple-walkers.
+     195             : \plumedfile
+     196             : DISTANCE ATOMS=3,5 LABEL=d1
+     197             : DISTANCE ATOMS=2,4 LABEL=d2
+     198             : PBMETAD ...
+     199             : ARG=d1,d2 SIGMA=0.2,0.2 HEIGHT=0.3
+     200             : PACE=500 BIASFACTOR=8 LABEL=pb
+     201             : FILE=HILLS_d1,HILLS_d2
+     202             : WALKERS_MPI
+     203             : ... PBMETAD
+     204             : PRINT ARG=d1,d2,pb.bias STRIDE=100 FILE=COLVAR
+     205             : \endplumedfile
+     206             : 
+     207             : \par
+     208             : The disk version of multiple-walkers can be
+     209             : enabled by setting the number of walker used, the id of the
+     210             : current walker which interprets the input file, the directory where the
+     211             : hills containing files resides, and the frequency to read the other walkers.
+     212             : Here is an example
+     213             : \plumedfile
+     214             : DISTANCE ATOMS=3,5 LABEL=d1
+     215             : DISTANCE ATOMS=2,4 LABEL=d2
+     216             : PBMETAD ...
+     217             : ARG=d1,d2 SIGMA=0.2,0.2 HEIGHT=0.3
+     218             : PACE=500 BIASFACTOR=8 LABEL=pb
+     219             : FILE=HILLS_d1,HILLS_d2
+     220             : WALKERS_N=10
+     221             : WALKERS_ID=3
+     222             : WALKERS_DIR=../
+     223             : WALKERS_RSTRIDE=100
+     224             : ... PBMETAD
+     225             : PRINT ARG=d1,d2,pb.bias STRIDE=100 FILE=COLVAR
+     226             : \endplumedfile
+     227             : where  WALKERS_N is the total number of walkers, WALKERS_ID is the
+     228             : id of the present walker (starting from 0 ) and the WALKERS_DIR is the directory
+     229             : where all the walkers are located. WALKERS_RSTRIDE is the number of step between
+     230             : one update and the other.
+     231             : 
+     232             : */
+     233             : //+ENDPLUMEDOC
+     234             : 
+     235             : class PBMetaD : public Bias {
+     236             : 
+     237             : private:
+     238             :   struct Gaussian {
+     239             :     std::vector<double> center;
+     240             :     std::vector<double> sigma;
+     241             :     double height;
+     242             :     bool   multivariate; // this is required to discriminate the one dimensional case
+     243             :     std::vector<double> invsigma;
+     244        1108 :     Gaussian(const std::vector<double> & center,const std::vector<double> & sigma, double height, bool multivariate):
+     245        1108 :       center(center),sigma(sigma),height(height),multivariate(multivariate),invsigma(sigma) {
+     246             :       // to avoid troubles from zero element in flexible hills
+     247        2216 :         for(unsigned i=0; i<invsigma.size(); ++i) if(std::abs(invsigma[i])>1.e-20) invsigma[i]=1.0/invsigma[i] ; else invsigma[i]=0.0;
+     248        1108 :     }
+     249             :   };
+     250             :   // general setup
+     251             :   double kbt_;
+     252             :   int stride_;
+     253             :   // well-tempered MetaD
+     254             :   bool welltemp_;
+     255             :   double biasf_;
+     256             :   // output files format
+     257             :   std::string fmt_;
+     258             :   // first step?
+     259             :   bool isFirstStep_;
+     260             :   // Gaussian starting parameters
+     261             :   double height0_;
+     262             :   std::vector<double> sigma0_;
+     263             :   std::vector<double> sigma0min_;
+     264             :   std::vector<double> sigma0max_;
+     265             :   // Gaussians
+     266             :   std::vector<std::vector<Gaussian> > hills_;
+     267             :   std::vector<FlexibleBin> flexbin_;
+     268             :   int adaptive_;
+     269             :   std::vector<std::unique_ptr<OFile>> hillsOfiles_;
+     270             :   std::vector<std::unique_ptr<IFile>> ifiles_;
+     271             :   std::vector<std::string> ifilesnames_;
+     272             :   // Grids
+     273             :   bool grid_;
+     274             :   std::vector<std::unique_ptr<GridBase>> BiasGrids_;
+     275             :   std::vector<std::unique_ptr<OFile>> gridfiles_;
+     276             :   int wgridstride_;
+     277             :   // Partitioned Families
+     278             :   unsigned int pf_n_; // initialize number of partitioned families
+     279             :   std::vector<int> pfs_; //std::vector length of arguments that holds which pf# each cv belongs in
+     280             :   std::vector<Value*> pfhold_; // std::vector length of pf_n which stores a pointer to the first argument fed to each family
+     281             :   bool do_pf_; // if partitioned families are enabled
+     282             :   // multiple walkers
+     283             :   int mw_n_;
+     284             :   std::string mw_dir_;
+     285             :   int mw_id_;
+     286             :   int mw_rstride_;
+     287             :   bool walkers_mpi_;
+     288             :   size_t mpi_nw_;
+     289             :   unsigned mpi_id_;
+     290             :   std::vector<std::string> hillsfname_;
+     291             :   // intervals
+     292             :   std::vector<double> uppI_;
+     293             :   std::vector<double> lowI_;
+     294             :   std::vector<bool>  doInt_;
+     295             :   // variable for selector
+     296             :   std::string selector_;
+     297             :   bool  do_select_;
+     298             :   unsigned select_value_;
+     299             :   unsigned current_value_;
+     300             : 
+     301             :   double stretchA=1.0;
+     302             :   double stretchB=0.0;
+     303             : 
+     304             :   bool noStretchWarningDone=false;
+     305             : 
+     306           0 :   void noStretchWarning() {
+     307           0 :     if(!noStretchWarningDone) {
+     308           0 :       log<<"\nWARNING: you are using a HILLS file with Gaussian kernels, PLUMED 2.8 uses stretched Gaussians by default\n";
+     309             :     }
+     310           0 :     noStretchWarningDone=true;
+     311           0 :   }
+     312             : 
+     313             :   void   readGaussians(unsigned iarg, IFile*);
+     314             :   void   writeGaussian(unsigned iarg, const Gaussian&, OFile*);
+     315             :   void   addGaussian(unsigned iarg, const Gaussian&);
+     316             :   double getBiasAndDerivatives(unsigned iarg, const std::vector<double>&, double* der=NULL);
+     317             :   double evaluateGaussian(unsigned iarg, const std::vector<double>&, const Gaussian&,double* der=NULL);
+     318             :   std::vector<unsigned> getGaussianSupport(unsigned iarg, const Gaussian&);
+     319             :   bool   scanOneHill(unsigned iarg, IFile *ifile,  std::vector<Value> &v, std::vector<double> &center, std::vector<double>  &sigma, double &height, bool &multivariate);
+     320             : 
+     321             : public:
+     322             :   explicit PBMetaD(const ActionOptions&);
+     323             :   void calculate() override;
+     324             :   void update() override;
+     325             :   static void registerKeywords(Keywords& keys);
+     326             :   bool checkNeedsGradients()const override;
+     327             : };
+     328             : 
+     329             : PLUMED_REGISTER_ACTION(PBMetaD,"PBMETAD")
+     330             : 
+     331          43 : void PBMetaD::registerKeywords(Keywords& keys) {
+     332          43 :   Bias::registerKeywords(keys);
+     333          43 :   keys.use("ARG");
+     334          86 :   keys.add("compulsory","SIGMA","the widths of the Gaussian hills");
+     335          86 :   keys.add("compulsory","PACE","the frequency for hill addition, one for all biases");
+     336          86 :   keys.add("optional","FILE","files in which the lists of added hills are stored, default names are assigned using arguments if FILE is not found");
+     337          86 :   keys.add("optional","HEIGHT","the height of the Gaussian hills, one for all biases. Compulsory unless TAU, TEMP and BIASFACTOR are given");
+     338          86 :   keys.add("optional","FMT","specify format for HILLS files (useful for decrease the number of digits in regtests)");
+     339          86 :   keys.add("optional","BIASFACTOR","use well tempered metadynamics with this bias factor, one for all biases.  Please note you must also specify temp");
+     340          86 :   keys.add("optional","TEMP","the system temperature - this is only needed if you are doing well-tempered metadynamics");
+     341          86 :   keys.add("optional","TAU","in well tempered metadynamics, sets height to (k_B Delta T*pace*timestep)/tau");
+     342          86 :   keys.add("optional","GRID_MIN","the lower bounds for the grid");
+     343          86 :   keys.add("optional","GRID_MAX","the upper bounds for the grid");
+     344          86 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     345          86 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     346          86 :   keys.addFlag("GRID_SPARSE",false,"use a sparse grid to store hills");
+     347          86 :   keys.addFlag("GRID_NOSPLINE",false,"don't use spline interpolation with grids");
+     348          86 :   keys.add("optional","GRID_WSTRIDE", "frequency for dumping the grid");
+     349          86 :   keys.add("optional","GRID_WFILES", "dump grid for the bias, default names are used if GRID_WSTRIDE is used without GRID_WFILES.");
+     350          86 :   keys.add("optional","GRID_RFILES", "read grid for the bias");
+     351          86 :   keys.add("optional","ADAPTIVE","use a geometric (=GEOM) or diffusion (=DIFF) based hills width scheme. Sigma is one number that has distance units or timestep dimensions");
+     352          86 :   keys.add("optional","SIGMA_MAX","the upper bounds for the sigmas (in CV units) when using adaptive hills. Negative number means no bounds ");
+     353          86 :   keys.add("optional","SIGMA_MIN","the lower bounds for the sigmas (in CV units) when using adaptive hills. Negative number means no bounds ");
+     354          86 :   keys.add("numbered","PF", "specify which CVs belong in a partitioned family. Once a PF is specified, all CVs in ARG must be placed in a PF even if there is one CV per PFâ€");
+     355          86 :   keys.add("optional","SELECTOR", "add forces and do update based on the value of SELECTOR");
+     356          86 :   keys.add("optional","SELECTOR_ID", "value of SELECTOR");
+     357          86 :   keys.add("optional","WALKERS_ID", "walker id");
+     358          86 :   keys.add("optional","WALKERS_N", "number of walkers");
+     359          86 :   keys.add("optional","WALKERS_DIR", "shared directory with the hills files from all the walkers");
+     360          86 :   keys.add("optional","WALKERS_RSTRIDE","stride for reading hills files");
+     361          86 :   keys.addFlag("WALKERS_MPI",false,"Switch on MPI version of multiple walkers - not compatible with WALKERS_* options other than WALKERS_DIR");
+     362          86 :   keys.add("optional","INTERVAL_MIN","one dimensional lower limits, outside the limits the system will not feel the biasing force.");
+     363          86 :   keys.add("optional","INTERVAL_MAX","one dimensional upper limits, outside the limits the system will not feel the biasing force.");
+     364          43 :   keys.use("RESTART");
+     365          43 :   keys.use("UPDATE_FROM");
+     366          43 :   keys.use("UPDATE_UNTIL");
+     367          43 : }
+     368             : 
+     369          41 : PBMetaD::PBMetaD(const ActionOptions& ao):
+     370             :   PLUMED_BIAS_INIT(ao),
+     371          41 :   kbt_(0.0),
+     372          41 :   stride_(0),
+     373          41 :   welltemp_(false),
+     374          41 :   biasf_(1.0),
+     375          41 :   isFirstStep_(true),
+     376          41 :   height0_(std::numeric_limits<double>::max()),
+     377          41 :   adaptive_(FlexibleBin::none),
+     378          41 :   grid_(false),
+     379          41 :   wgridstride_(0),
+     380          41 :   pf_n_(0), do_pf_(false),
+     381          41 :   mw_n_(1), mw_dir_(""), mw_id_(0), mw_rstride_(1),
+     382          41 :   walkers_mpi_(false), mpi_nw_(0),
+     383          41 :   do_select_(false)
+     384             : {
+     385             : 
+     386             :   // parse the flexible hills
+     387             :   std::string adaptiveoption;
+     388             :   adaptiveoption="NONE";
+     389          82 :   parse("ADAPTIVE",adaptiveoption);
+     390          41 :   if(adaptiveoption=="GEOM") {
+     391           0 :     log.printf("  Uses Geometry-based hills width: sigma must be in distance units and only one sigma is needed\n");
+     392           0 :     adaptive_=FlexibleBin::geometry;
+     393          41 :   } else if(adaptiveoption=="DIFF") {
+     394           4 :     log.printf("  Uses Diffusion-based hills width: sigma must be in time steps and only one sigma is needed\n");
+     395           4 :     adaptive_=FlexibleBin::diffusion;
+     396          37 :   } else if(adaptiveoption=="NONE") {
+     397          37 :     adaptive_=FlexibleBin::none;
+     398             :   } else {
+     399           0 :     error("I do not know this type of adaptive scheme");
+     400             :   }
+     401             : 
+     402          41 :   parse("FMT",fmt_);
+     403             : 
+     404             :   // Partitioned Families - fill with -1 to mark as invalid
+     405          41 :   pfs_.assign(getNumberOfArguments(), -1);
+     406          41 :   pfhold_.resize(getNumberOfArguments());
+     407             :   std::vector<Value*> familyargs;
+     408          41 :   for(int i = 0;; i++) {
+     409          94 :     parseArgumentList("PF", i, familyargs);
+     410          47 :     if (familyargs.empty()) break;
+     411             : 
+     412           6 :     do_pf_ = true;
+     413           6 :     log << "  Identified Partitioned Family " << i << ":";
+     414          15 :     for (unsigned j = 0; j < familyargs.size(); j++) {
+     415           9 :       log << " " << familyargs[j]->getName();
+     416             :       // loop through the argument list to make sure it exists and assign it
+     417             :       bool foundArg = false;
+     418          36 :       for (unsigned argnum = 0; argnum < getNumberOfArguments(); argnum++) {
+     419          27 :         if (familyargs[j]->getName() == getPntrToArgument(argnum)->getName()) {
+     420             :           foundArg = true;
+     421           9 :           if (pfs_[argnum] != -1) {
+     422           0 :             error(familyargs[j]->getName() + " already present in PF" + std::to_string(pfs_[argnum]));
+     423             :           }
+     424           9 :           pfs_[argnum] = i;  // store the pf# for each cv
+     425           9 :           if (pfhold_[i] == nullptr) {
+     426             :             // if this is the first argument in the family, store a pointer for it (this is for HILLS & GRID files)
+     427           6 :             pfhold_[i] = getPntrToArgument(argnum);
+     428             :           }
+     429             :         }
+     430             :       }
+     431           9 :       if (!foundArg) {
+     432           0 :         error(familyargs[j]->getName() + " in PF" + std::to_string(i) + " not found in ARG");
+     433             :       }
+     434             :     }
+     435           6 :     log << "\n";
+     436           6 :     pf_n_++;
+     437           6 :   }
+     438             : 
+     439             :   // if PF were specified, every argument gets treated as its own PF
+     440          41 :   if (!do_pf_) {
+     441          38 :     pf_n_ = getNumberOfArguments();
+     442         114 :     for(unsigned i=0; i < pf_n_; i++) {
+     443          76 :       pfhold_[i] = getPntrToArgument(i);
+     444          76 :       pfs_[i] = i;
+     445             :     }
+     446             :   } else {
+     447             :     // If we are doing PF, make sure each argument got assigned to a family.
+     448          12 :     for (unsigned i = 0; i < getNumberOfArguments(); i++) {
+     449           9 :       if (pfs_[i] == -1) error(getPntrToArgument(i)->getName() + " was not assigned a PF");
+     450             :     }
+     451             :   }
+     452             : 
+     453             :   // parse the sigma
+     454          41 :   parseVector("SIGMA",sigma0_);
+     455          41 :   if(adaptive_==FlexibleBin::none) {
+     456             :     // if you use normal sigma you need one sigma per argument
+     457          37 :     if( sigma0_.size()!=pf_n_ ) {
+     458           0 :       std::string fields = do_pf_ ? "PFs" : "arguments";
+     459           0 :       error("number of " + fields + " does not match number of SIGMA parameters");
+     460             :     }
+     461             :   } else {
+     462             :     // if you use flexible hills you need one sigma
+     463           4 :     if(sigma0_.size()!=1) {
+     464           0 :       error("If you choose ADAPTIVE you need only one sigma according to your choice of type (GEOM/DIFF)");
+     465             :     }
+     466             :     // if adaptive then the number must be an integer
+     467           4 :     if(adaptive_==FlexibleBin::diffusion) {
+     468           4 :       if(int(sigma0_[0])-sigma0_[0]>1.e-9 || int(sigma0_[0])-sigma0_[0] <-1.e-9 || int(sigma0_[0])<1 ) {
+     469           0 :         error("In case of adaptive hills with diffusion, the sigma must be an integer which is the number of time steps\n");
+     470             :       }
+     471             :     }
+     472             :     // here evtl parse the sigma min and max values
+     473           8 :     parseVector("SIGMA_MIN",sigma0min_);
+     474           4 :     if(sigma0min_.size()>0 && sigma0min_.size()!=pf_n_) {
+     475           0 :       error("the number of SIGMA_MIN values be the same of the number of the arguments/PF");
+     476           4 :     } else if(sigma0min_.size()==0) {
+     477           0 :       sigma0min_.resize(pf_n_);
+     478           0 :       for(unsigned i=0; i<pf_n_; i++) {sigma0min_[i]=-1.;}
+     479             :     }
+     480             : 
+     481           8 :     parseVector("SIGMA_MAX",sigma0max_);
+     482           4 :     if(sigma0max_.size()>0 && sigma0max_.size()!=pf_n_) {
+     483           0 :       error("the number of SIGMA_MAX values be the same of the number of the arguments/PF");
+     484           4 :     } else if(sigma0max_.size()==0) {
+     485           4 :       sigma0max_.resize(pf_n_);
+     486          12 :       for(unsigned i=0; i<pf_n_; i++) {sigma0max_[i]=-1.;}
+     487             :     }
+     488             : 
+     489          12 :     for(unsigned i=0; i<pf_n_; i++) {
+     490             :       std::vector<double> tmp_smin, tmp_smax;
+     491           8 :       tmp_smin.resize(1,sigma0min_[i]);
+     492           8 :       tmp_smax.resize(1,sigma0max_[i]);
+     493          16 :       flexbin_.push_back(FlexibleBin(adaptive_,this,i,sigma0_[0],tmp_smin,tmp_smax));
+     494             :     }
+     495             :   }
+     496             : 
+     497             :   // note: HEIGHT is not compulsory, since one could use the TAU keyword, see below
+     498          41 :   parse("HEIGHT",height0_);
+     499          41 :   parse("PACE",stride_);
+     500          41 :   if(stride_<=0) error("frequency for hill addition is nonsensical");
+     501             : 
+     502             : 
+     503          82 :   parseVector("FILE",hillsfname_);
+     504          41 :   if(hillsfname_.size()==0) {
+     505          27 :     for(unsigned i=0; i< pf_n_; i++) {
+     506          18 :       std::string name = do_pf_ ? "HILLS.PF"+std::to_string(i) : "HILLS."+getPntrToArgument(i)->getName();
+     507          18 :       hillsfname_.push_back(name);
+     508             :     }
+     509             :   }
+     510          41 :   if( hillsfname_.size()!=pf_n_ ) {
+     511           0 :     error("number of FILE arguments does not match number of HILLS files");
+     512             :   }
+     513             : 
+     514          41 :   parse("BIASFACTOR",biasf_);
+     515          41 :   if( biasf_<1.0 ) error("well tempered bias factor is nonsensical");
+     516          41 :   kbt_=getkBT();
+     517          41 :   if(biasf_>1.0) {
+     518          40 :     if(kbt_==0.0) error("Unless the MD engine passes the temperature to plumed, with well-tempered metad you must specify it using TEMP");
+     519          40 :     welltemp_=true;
+     520             :   }
+     521          41 :   double tau=0.0;
+     522          41 :   parse("TAU",tau);
+     523          41 :   if(tau==0.0) {
+     524          41 :     if(height0_==std::numeric_limits<double>::max()) error("At least one between HEIGHT and TAU should be specified");
+     525             :     // if tau is not set, we compute it here from the other input parameters
+     526          41 :     if(welltemp_) tau=(kbt_*(biasf_-1.0))/height0_*getTimeStep()*stride_;
+     527             :   } else {
+     528           0 :     if(!welltemp_)error("TAU only makes sense in well-tempered metadynamics");
+     529           0 :     if(height0_!=std::numeric_limits<double>::max()) error("At most one between HEIGHT and TAU should be specified");
+     530           0 :     height0_=(kbt_*(biasf_-1.0))/tau*getTimeStep()*stride_;
+     531             :   }
+     532             : 
+     533             : 
+     534             :   // Multiple walkers
+     535          41 :   parse("WALKERS_N",mw_n_);
+     536          41 :   parse("WALKERS_ID",mw_id_);
+     537          41 :   if(mw_n_<=mw_id_) error("walker ID should be a numerical value less than the total number of walkers");
+     538          41 :   parse("WALKERS_DIR",mw_dir_);
+     539          41 :   parse("WALKERS_RSTRIDE",mw_rstride_);
+     540             : 
+     541             :   // MPI version
+     542          41 :   parseFlag("WALKERS_MPI",walkers_mpi_);
+     543             : 
+     544             :   // Grid file
+     545          82 :   parse("GRID_WSTRIDE",wgridstride_);
+     546             :   std::vector<std::string> gridfilenames_;
+     547          41 :   parseVector("GRID_WFILES",gridfilenames_);
+     548          41 :   if (wgridstride_ == 0 && gridfilenames_.size() > 0) {
+     549           0 :     error("frequency with which to output grid not specified use GRID_WSTRIDE");
+     550             :   }
+     551          41 :   if(gridfilenames_.size()==0 && wgridstride_ > 0) {
+     552          12 :     for(unsigned i=0; i<pf_n_; i++) {
+     553           8 :       std::string name = do_pf_ ? "GRID.PF"+std::to_string(i) : "GRID."+getPntrToArgument(i)->getName();
+     554           8 :       gridfilenames_.push_back(name);
+     555             :     }
+     556             :   }
+     557          41 :   if(gridfilenames_.size() > 0 && hillsfname_.size() > 0 && gridfilenames_.size() != hillsfname_.size())
+     558           0 :     error("number of GRID_WFILES arguments does not match number of HILLS files");
+     559             : 
+     560             :   // Read grid
+     561             :   std::vector<std::string> gridreadfilenames_;
+     562          41 :   parseVector("GRID_RFILES",gridreadfilenames_);
+     563             : 
+     564             :   // Grid Stuff
+     565          41 :   std::vector<std::string> gmin(pf_n_);
+     566          82 :   parseVector("GRID_MIN",gmin);
+     567          41 :   if(gmin.size()!=pf_n_ && gmin.size()!=0) error("not enough values for GRID_MIN");
+     568          41 :   std::vector<std::string> gmax(pf_n_);
+     569          82 :   parseVector("GRID_MAX",gmax);
+     570          41 :   if(gmax.size()!=pf_n_ && gmax.size()!=0) error("not enough values for GRID_MAX");
+     571          41 :   std::vector<unsigned> gbin(pf_n_);
+     572             :   std::vector<double>   gspacing;
+     573          82 :   parseVector("GRID_BIN",gbin);
+     574          41 :   if(gbin.size()!=pf_n_ && gbin.size()!=0) error("not enough values for GRID_BIN");
+     575          82 :   parseVector("GRID_SPACING",gspacing);
+     576          41 :   if(gspacing.size()!=pf_n_ && gspacing.size()!=0) error("not enough values for GRID_SPACING");
+     577          41 :   if(gmin.size()!=gmax.size()) error("GRID_MAX and GRID_MIN should be either present or absent");
+     578          41 :   if(gspacing.size()!=0 && gmin.size()==0) error("If GRID_SPACING is present also GRID_MIN and GRID_MAX should be present");
+     579          41 :   if(gbin.size()!=0     && gmin.size()==0) error("If GRID_BIN is present also GRID_MIN and GRID_MAX should be present");
+     580          41 :   if(gmin.size()!=0) {
+     581           9 :     if(gbin.size()==0 && gspacing.size()==0) {
+     582           9 :       if(adaptive_==FlexibleBin::none) {
+     583           5 :         log<<"  Binsize not specified, 1/5 of sigma will be be used\n";
+     584           5 :         plumed_assert(sigma0_.size()==pf_n_);
+     585           5 :         gspacing.resize(pf_n_);
+     586          15 :         for(unsigned i=0; i<gspacing.size(); i++) gspacing[i]=0.2*sigma0_[i];
+     587             :       } else {
+     588             :         // with adaptive hills and grid a sigma min must be specified
+     589          12 :         for(unsigned i=0; i<sigma0min_.size(); i++) if(sigma0min_[i]<=0) error("When using ADAPTIVE Gaussians on a grid SIGMA_MIN must be specified");
+     590           4 :         log<<"  Binsize not specified, 1/5 of sigma_min will be be used\n";
+     591           4 :         gspacing.resize(pf_n_);
+     592          12 :         for(unsigned i=0; i<gspacing.size(); i++) gspacing[i]=0.2*sigma0min_[i];
+     593             :       }
+     594           0 :     } else if(gspacing.size()!=0 && gbin.size()==0) {
+     595           0 :       log<<"  The number of bins will be estimated from GRID_SPACING\n";
+     596           0 :     } else if(gspacing.size()!=0 && gbin.size()!=0) {
+     597           0 :       log<<"  You specified both GRID_BIN and GRID_SPACING\n";
+     598           0 :       log<<"  The more conservative (highest) number of bins will be used for each variable\n";
+     599             :     }
+     600           9 :     if(gbin.size()==0) gbin.assign(pf_n_,1);
+     601          27 :     if(gspacing.size()!=0) for(unsigned i=0; i<pf_n_; i++) {
+     602             :         double a,b;
+     603          18 :         Tools::convert(gmin[i],a);
+     604          18 :         Tools::convert(gmax[i],b);
+     605          18 :         unsigned n=std::ceil(((b-a)/gspacing[i]));
+     606          18 :         if(gbin[i]<n) gbin[i]=n;
+     607             :       }
+     608             :   }
+     609          41 :   if(gbin.size()>0) grid_=true;
+     610             : 
+     611          41 :   bool sparsegrid=false;
+     612          41 :   parseFlag("GRID_SPARSE",sparsegrid);
+     613          41 :   bool nospline=false;
+     614          41 :   parseFlag("GRID_NOSPLINE",nospline);
+     615          41 :   bool spline=!nospline;
+     616          41 :   if(!grid_&&gridfilenames_.size() > 0) error("To write a grid you need first to define it!");
+     617          41 :   if(!grid_&&gridreadfilenames_.size() > 0) error("To read a grid you need first to define it!");
+     618             : 
+     619          41 :   doInt_.resize(pf_n_,false);
+     620             :   // Interval keyword
+     621          41 :   parseVector("INTERVAL_MIN",lowI_);
+     622          82 :   parseVector("INTERVAL_MAX",uppI_);
+     623             :   // various checks
+     624          41 :   if(lowI_.size()!=uppI_.size()) error("both a lower and an upper limits must be provided with INTERVAL");
+     625          41 :   if(lowI_.size()!=0 && lowI_.size()!=pf_n_) error("check number of argument of INTERVAL");
+     626          49 :   for(unsigned i=0; i<lowI_.size(); ++i) {
+     627           8 :     if(uppI_[i]<lowI_[i]) error("The Upper limit must be greater than the Lower limit!");
+     628           8 :     if(pfhold_[i]->isPeriodic()) warning("INTERVAL is not used for periodic variables");
+     629             :     else doInt_[i]=true;
+     630             :   }
+     631             : 
+     632             :   // parse selector stuff
+     633          82 :   parse("SELECTOR", selector_);
+     634          41 :   if(selector_.length()>0) {
+     635           0 :     do_select_ = true;
+     636           0 :     parse("SELECTOR_ID", select_value_);
+     637             :   }
+     638             : 
+     639          41 :   checkRead();
+     640             : 
+     641          41 :   log.printf("  Gaussian width ");
+     642          41 :   if (adaptive_==FlexibleBin::diffusion)log.printf(" (Note: The units of sigma are in timesteps) ");
+     643          41 :   if (adaptive_==FlexibleBin::geometry)log.printf(" (Note: The units of sigma are in dist units) ");
+     644         119 :   for(unsigned i=0; i<sigma0_.size(); ++i) log.printf(" %f",sigma0_[i]);
+     645          41 :   log.printf("  Gaussian height %f\n",height0_);
+     646          41 :   log.printf("  Gaussian deposition pace %d\n",stride_);
+     647          41 :   log.printf("  Gaussian files ");
+     648         123 :   for(unsigned i=0; i<hillsfname_.size(); ++i) log.printf("%s ",hillsfname_[i].c_str());
+     649          41 :   log.printf("\n");
+     650          41 :   if(welltemp_) {
+     651          40 :     log.printf("  Well-Tempered Bias Factor %f\n",biasf_);
+     652          40 :     log.printf("  Hills relaxation time (tau) %f\n",tau);
+     653          40 :     log.printf("  KbT %f\n",kbt_);
+     654             :   }
+     655             : 
+     656          41 :   if(do_select_) {
+     657           0 :     log.printf("  Add forces and update bias based on the value of SELECTOR %s\n",selector_.c_str());
+     658           0 :     log.printf("  Id of the SELECTOR for this action %u\n", select_value_);
+     659             :   }
+     660             : 
+     661          41 :   if(mw_n_>1) {
+     662           0 :     if(walkers_mpi_) error("MPI version of multiple walkers is not compatible with filesystem version of multiple walkers");
+     663           0 :     log.printf("  %d multiple walkers active\n",mw_n_);
+     664           0 :     log.printf("  walker id %d\n",mw_id_);
+     665           0 :     log.printf("  reading stride %d\n",mw_rstride_);
+     666           0 :     if(mw_dir_!="")log.printf("  directory with hills files %s\n",mw_dir_.c_str());
+     667             :   } else {
+     668          41 :     if(walkers_mpi_) {
+     669          34 :       log.printf("  Multiple walkers active using MPI communnication\n");
+     670          34 :       if(mw_dir_!="")log.printf("  directory with hills files %s\n",mw_dir_.c_str());
+     671          34 :       if(comm.Get_rank()==0) {
+     672             :         // Only root of group can communicate with other walkers
+     673          18 :         mpi_nw_ = multi_sim_comm.Get_size();
+     674          18 :         mpi_id_ = multi_sim_comm.Get_rank();
+     675             :       }
+     676             :       // Communicate to the other members of the same group
+     677             :       // info abount number of walkers and walker index
+     678          34 :       comm.Bcast(mpi_nw_,0);
+     679          34 :       comm.Bcast(mpi_id_,0);
+     680             :     }
+     681             :   }
+     682             : 
+     683         123 :   for(unsigned i=0; i<doInt_.size(); i++) {
+     684          82 :     if(doInt_[i]) log.printf("  Upper and Lower limits boundaries for the bias of CV %u are activated\n", i);
+     685             :   }
+     686          41 :   if(grid_) {
+     687           9 :     log.printf("  Grid min");
+     688          27 :     for(unsigned i=0; i<gmin.size(); ++i) log.printf(" %s",gmin[i].c_str() );
+     689           9 :     log.printf("\n");
+     690           9 :     log.printf("  Grid max");
+     691          27 :     for(unsigned i=0; i<gmax.size(); ++i) log.printf(" %s",gmax[i].c_str() );
+     692           9 :     log.printf("\n");
+     693           9 :     log.printf("  Grid bin");
+     694          27 :     for(unsigned i=0; i<gbin.size(); ++i) log.printf(" %u",gbin[i]);
+     695           9 :     log.printf("\n");
+     696           9 :     if(spline) {log.printf("  Grid uses spline interpolation\n");}
+     697           9 :     if(sparsegrid) {log.printf("  Grid uses sparse grid\n");}
+     698           9 :     if(wgridstride_>0) {
+     699          18 :       for(unsigned i=0; i<gridfilenames_.size(); ++i) {
+     700          12 :         log.printf("  Grid is written on file %s with stride %d\n",gridfilenames_[i].c_str(),wgridstride_);
+     701             :       }
+     702             :     }
+     703           9 :     if(gridreadfilenames_.size()>0) {
+     704           3 :       for(unsigned i=0; i<gridreadfilenames_.size(); ++i) {
+     705           2 :         log.printf("  Reading bias from grid in file %s \n",gridreadfilenames_[i].c_str());
+     706             :       }
+     707             :     }
+     708             :   }
+     709             : 
+     710             :   // initializing vector of hills
+     711          41 :   hills_.resize(pf_n_);
+     712             : 
+     713             :   // restart from external grid
+     714             :   bool restartedFromGrid=false;
+     715             : 
+     716             :   // initializing and checking grid
+     717          41 :   if(grid_) {
+     718             :     // check for mesh and sigma size
+     719          27 :     for(unsigned i=0; i<pf_n_; i++) {
+     720             :       double a,b;
+     721          18 :       int family = pfs_[i]; // point to families instead of arguments
+     722          18 :       Tools::convert(gmin[family],a);
+     723          18 :       Tools::convert(gmax[family],b);
+     724          18 :       double mesh=(b-a)/((double)gbin[family]);
+     725          18 :       if(adaptive_==FlexibleBin::none) {
+     726          10 :         if(mesh>0.5*sigma0_[i]) log<<"  WARNING: Using a PBMETAD with a Grid Spacing larger than half of the Gaussians width can produce artifacts\n";
+     727             :       } else {
+     728           8 :         if(mesh>0.5*sigma0min_[i]||sigma0min_[i]<0.) log<<"  WARNING: to use a PBMETAD with a GRID and ADAPTIVE you need to set a Grid Spacing larger than half of the Gaussians \n";
+     729             :       }
+     730             :     }
+     731           9 :     std::string funcl=getLabel() + ".bias";
+     732          27 :     for(unsigned i=0; i<pf_n_; ++i) {
+     733          18 :       std::vector<Value*> args(1);
+     734          18 :       args[0] = pfhold_[i];  //Use first argument in family for interactions.
+     735          18 :       std::vector<std::string> gmin_t(1);
+     736          18 :       std::vector<std::string> gmax_t(1);
+     737          18 :       std::vector<unsigned>    gbin_t(1);
+     738             :       gmin_t[0] = gmin[i];
+     739             :       gmax_t[0] = gmax[i];
+     740          18 :       gbin_t[0] = gbin[i];
+     741          18 :       std::unique_ptr<GridBase> BiasGrid_;
+     742             :       // Read grid from file
+     743          18 :       if(gridreadfilenames_.size()>0) {
+     744           2 :         IFile gridfile;
+     745           2 :         gridfile.link(*this);
+     746           2 :         if(gridfile.FileExist(gridreadfilenames_[i])) {
+     747           2 :           gridfile.open(gridreadfilenames_[i]);
+     748             :         } else {
+     749           0 :           error("The GRID file you want to read: " + gridreadfilenames_[i] + ", cannot be found!");
+     750             :         }
+     751           2 :         std::string funcl = getLabel() + ".bias";
+     752           4 :         BiasGrid_=GridBase::create(funcl, args, gridfile, gmin_t, gmax_t, gbin_t, sparsegrid, spline, true);
+     753           2 :         if(BiasGrid_->getDimension() != args.size()) {
+     754           0 :           error("mismatch between dimensionality of input grid and number of arguments");
+     755             :         }
+     756           4 :         if(pfhold_[i]->isPeriodic() != BiasGrid_->getIsPeriodic()[0]) {
+     757           0 :           error("periodicity mismatch between arguments and input bias");
+     758             :         }
+     759           2 :         log.printf("  Restarting from %s:\n",gridreadfilenames_[i].c_str());
+     760           2 :         if(getRestart()) restartedFromGrid=true;
+     761           2 :       } else {
+     762          16 :         if(!sparsegrid) {BiasGrid_=Tools::make_unique<Grid>(funcl,args,gmin_t,gmax_t,gbin_t,spline,true);}
+     763           0 :         else           {BiasGrid_=Tools::make_unique<SparseGrid>(funcl,args,gmin_t,gmax_t,gbin_t,spline,true);}
+     764          16 :         std::vector<std::string> actualmin=BiasGrid_->getMin();
+     765          16 :         std::vector<std::string> actualmax=BiasGrid_->getMax();
+     766             :         std::string is;
+     767          16 :         Tools::convert(i,is);
+     768          16 :         if(gmin_t[0]!=actualmin[0]) error("GRID_MIN["+is+"] must be adjusted to "+actualmin[0]+" to fit periodicity");
+     769          16 :         if(gmax_t[0]!=actualmax[0]) error("GRID_MAX["+is+"] must be adjusted to "+actualmax[0]+" to fit periodicity");
+     770          16 :       }
+     771          18 :       BiasGrids_.emplace_back(std::move(BiasGrid_));
+     772          36 :     }
+     773             :   }
+     774             : 
+     775             : 
+     776             : 
+     777             : // creating vector of ifile* for hills reading
+     778             : // open all files at the beginning and read Gaussians if restarting
+     779             : 
+     780          82 :   for(int j=0; j<mw_n_; ++j) {
+     781         123 :     for(unsigned i=0; i<hillsfname_.size(); ++i) {
+     782          82 :       unsigned k=j*hillsfname_.size()+i;
+     783             :       std::string fname;
+     784          82 :       if(mw_dir_!="") {
+     785           0 :         if(mw_n_>1) {
+     786           0 :           std::stringstream out; out << j;
+     787           0 :           fname = mw_dir_+"/"+hillsfname_[i]+"."+out.str();
+     788           0 :         } else if(walkers_mpi_) {
+     789           0 :           fname = mw_dir_+"/"+hillsfname_[i];
+     790             :         } else {
+     791             :           fname = hillsfname_[i];
+     792             :         }
+     793             :       } else {
+     794          82 :         if(mw_n_>1) {
+     795           0 :           std::stringstream out; out << j;
+     796           0 :           fname = hillsfname_[i]+"."+out.str();
+     797           0 :         } else {
+     798             :           fname = hillsfname_[i];
+     799             :         }
+     800             :       }
+     801          82 :       ifiles_.emplace_back(Tools::make_unique<IFile>());
+     802             :       // this is just a shortcut pointer to the last element:
+     803             :       IFile *ifile = ifiles_.back().get();
+     804          82 :       ifile->link(*this);
+     805          82 :       ifilesnames_.push_back(fname);
+     806          82 :       if(ifile->FileExist(fname)) {
+     807          18 :         ifile->open(fname);
+     808          18 :         if(getRestart()&&!restartedFromGrid) {
+     809           2 :           log.printf("  Restarting from %s:",ifilesnames_[k].c_str());
+     810           2 :           readGaussians(i,ifiles_[k].get());
+     811             :         }
+     812          18 :         ifiles_[k]->reset(false);
+     813             :         // close only the walker own hills file for later writing
+     814          18 :         if(j==mw_id_) ifiles_[k]->close();
+     815             :       } else {
+     816             :         // in case a file does not exist and we are restarting, complain that the file was not found
+     817          64 :         if(getRestart()) log<<"  WARNING: restart file "<<fname<<" not found\n";
+     818             :       }
+     819             :     }
+     820             :   }
+     821             : 
+     822          41 :   comm.Barrier();
+     823          41 :   if(comm.Get_rank()==0 && walkers_mpi_) multi_sim_comm.Barrier();
+     824             : 
+     825             :   // open hills files for writing
+     826         123 :   for(unsigned i=0; i<hillsfname_.size(); ++i) {
+     827             :     auto ofile=Tools::make_unique<OFile>();
+     828          82 :     ofile->link(*this);
+     829             :     // if MPI multiple walkers, only rank 0 will write to file
+     830          82 :     if(walkers_mpi_) {
+     831          68 :       int r=0;
+     832          68 :       if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+     833          68 :       comm.Bcast(r,0);
+     834          68 :       if(r>0) ifilesnames_[mw_id_*hillsfname_.size()+i]="/dev/null";
+     835         136 :       ofile->enforceSuffix("");
+     836             :     }
+     837          82 :     if(mw_n_>1) ofile->enforceSuffix("");
+     838          82 :     ofile->open(ifilesnames_[mw_id_*hillsfname_.size()+i]);
+     839          82 :     if(fmt_.length()>0) ofile->fmtField(fmt_);
+     840         164 :     ofile->addConstantField("multivariate");
+     841         164 :     ofile->addConstantField("kerneltype");
+     842          82 :     if(doInt_[i]) {
+     843          16 :       ofile->addConstantField("lower_int").printField("lower_int",lowI_[i]);
+     844          16 :       ofile->addConstantField("upper_int").printField("upper_int",uppI_[i]);
+     845             :     }
+     846          82 :     ofile->setHeavyFlush();
+     847             :     // output periodicities of variables
+     848          82 :     ofile->setupPrintValue( pfhold_[i] );  //assuming cvs in the same family have the same periodicity and boundaries.
+     849             :     // push back
+     850          82 :     hillsOfiles_.emplace_back(std::move(ofile));
+     851          82 :   }
+     852             : 
+     853             :   // Dump grid to files
+     854          41 :   if(wgridstride_ > 0) {
+     855          18 :     for(unsigned i = 0; i < gridfilenames_.size(); ++i) {
+     856             :       auto ofile=Tools::make_unique<OFile>();
+     857          12 :       ofile->link(*this);
+     858          12 :       std::string gridfname_tmp = gridfilenames_[i];
+     859          12 :       if(walkers_mpi_) {
+     860           8 :         int r = 0;
+     861           8 :         if(comm.Get_rank() == 0) {
+     862           4 :           r = multi_sim_comm.Get_rank();
+     863             :         }
+     864           8 :         comm.Bcast(r, 0);
+     865           8 :         if(r>0) {
+     866             :           gridfname_tmp = "/dev/null";
+     867             :         }
+     868          16 :         ofile->enforceSuffix("");
+     869             :       }
+     870          12 :       if(mw_n_>1) ofile->enforceSuffix("");
+     871          12 :       ofile->open(gridfname_tmp);
+     872          12 :       ofile->setHeavyFlush();
+     873          12 :       gridfiles_.emplace_back(std::move(ofile));
+     874          12 :     }
+     875             :   }
+     876             : 
+     877          82 :   log<<"  Bibliography "<<plumed.cite("Pfaendtner and Bonomi. J. Chem. Theory Comput. 11, 5062 (2015)");
+     878          49 :   if(doInt_[0]) log<<plumed.cite(
+     879           8 :                        "Baftizadeh, Cossio, Pietrucci, and Laio, Curr. Phys. Chem. 2, 79 (2012)");
+     880         109 :   if(mw_n_>1||walkers_mpi_) log<<plumed.cite(
+     881          68 :                                    "Raiteri, Laio, Gervasio, Micheletti, and Parrinello, J. Phys. Chem. B 110, 3533 (2006)");
+     882          49 :   if(adaptive_!=FlexibleBin::none) log<<plumed.cite(
+     883           8 :                                           "Branduardi, Bussi, and Parrinello, J. Chem. Theory Comput. 8, 2247 (2012)");
+     884          44 :   if (do_pf_) log<<plumed.cite("Prakash, Fu, Bonomi, and Pfaendtner, J. Chem. Theory Comput. 14, 4985 (2018)");
+     885          41 :   log<<"\n";
+     886             : 
+     887             : 
+     888          82 : }
+     889             : 
+     890           2 : void PBMetaD::readGaussians(unsigned iarg, IFile *ifile)
+     891             : {
+     892           2 :   std::vector<double> center(1);
+     893           2 :   std::vector<double> sigma(1);
+     894             :   double height;
+     895             :   int nhills=0;
+     896           2 :   bool multivariate=false;
+     897           2 :   int family=pfs_[iarg];
+     898             : 
+     899             :   std::vector<Value> tmpvalues;
+     900           4 :   tmpvalues.push_back( Value( this, pfhold_[family]->getName(), false ) );
+     901             : 
+     902          10 :   while(scanOneHill(iarg,ifile,tmpvalues,center,sigma,height,multivariate)) {
+     903             :     ;
+     904           8 :     nhills++;
+     905           8 :     if(welltemp_) {height*=(biasf_-1.0)/biasf_;}
+     906           8 :     addGaussian(family, Gaussian(center,sigma,height,multivariate));
+     907             :   }
+     908           2 :   log.printf("      %d Gaussians read\n",nhills);
+     909           4 : }
+     910             : 
+     911        1100 : void PBMetaD::writeGaussian(unsigned iarg, const Gaussian& hill, OFile *ofile)
+     912             : {
+     913        1100 :   int family=pfs_[iarg];
+     914        2200 :   ofile->printField("time",getTimeStep()*getStep());
+     915        1100 :   ofile->printField(pfhold_[family],hill.center[0]);
+     916             : 
+     917        2200 :   ofile->printField("kerneltype","stretched-gaussian");
+     918        1100 :   if(hill.multivariate) {
+     919         288 :     ofile->printField("multivariate","true");
+     920         144 :     double lower = std::sqrt(1./hill.sigma[0]);
+     921         288 :     ofile->printField("sigma_"+pfhold_[family]->getName()+"_"+
+     922         144 :                       pfhold_[family]->getName(),lower);
+     923             :   } else {
+     924        1912 :     ofile->printField("multivariate","false");
+     925        1912 :     ofile->printField("sigma_"+pfhold_[family]->getName(),hill.sigma[0]);
+     926             :   }
+     927        1100 :   double height=hill.height;
+     928        1100 :   if(welltemp_) height *= biasf_/(biasf_-1.0);
+     929        1100 :   ofile->printField("height",height);
+     930        1100 :   ofile->printField("biasf",biasf_);
+     931        1100 :   if(mw_n_>1) ofile->printField("clock",int(std::time(0)));
+     932        1100 :   ofile->printField();
+     933        1100 : }
+     934             : 
+     935        1108 : void PBMetaD::addGaussian(unsigned iarg, const Gaussian& hill)
+     936             : {
+     937        1108 :   if(!grid_) {hills_[iarg].push_back(hill);}
+     938             :   else {
+     939         196 :     std::vector<unsigned> nneighb=getGaussianSupport(iarg, hill);
+     940         196 :     std::vector<Grid::index_t> neighbors=BiasGrids_[iarg]->getNeighbors(hill.center,nneighb);
+     941         196 :     std::vector<double> der(1);
+     942         196 :     std::vector<double> xx(1);
+     943         196 :     if(comm.Get_size()==1) {
+     944        1064 :       for(unsigned i=0; i<neighbors.size(); ++i) {
+     945        1036 :         Grid::index_t ineigh=neighbors[i];
+     946        1036 :         der[0]=0.0;
+     947        1036 :         BiasGrids_[iarg]->getPoint(ineigh,xx);
+     948        1036 :         double bias=evaluateGaussian(iarg,xx,hill,&der[0]);
+     949        1036 :         BiasGrids_[iarg]->addValueAndDerivatives(ineigh,bias,der);
+     950             :       }
+     951             :     } else {
+     952         168 :       unsigned stride=comm.Get_size();
+     953         168 :       unsigned rank=comm.Get_rank();
+     954         168 :       std::vector<double> allder(neighbors.size(),0.0);
+     955         168 :       std::vector<double> allbias(neighbors.size(),0.0);
+     956        3276 :       for(unsigned i=rank; i<neighbors.size(); i+=stride) {
+     957        3108 :         Grid::index_t ineigh=neighbors[i];
+     958        3108 :         BiasGrids_[iarg]->getPoint(ineigh,xx);
+     959        3108 :         allbias[i]=evaluateGaussian(iarg,xx,hill,&allder[i]);
+     960             :       }
+     961         168 :       comm.Sum(allbias);
+     962         168 :       comm.Sum(allder);
+     963        6384 :       for(unsigned i=0; i<neighbors.size(); ++i) {
+     964        6216 :         Grid::index_t ineigh=neighbors[i];
+     965        6216 :         der[0]=allder[i];
+     966        6216 :         BiasGrids_[iarg]->addValueAndDerivatives(ineigh,allbias[i],der);
+     967             :       }
+     968             :     }
+     969             :   }
+     970        1108 : }
+     971             : 
+     972         196 : std::vector<unsigned> PBMetaD::getGaussianSupport(unsigned iarg, const Gaussian& hill)
+     973             : {
+     974             :   std::vector<unsigned> nneigh;
+     975             :   double cutoff;
+     976         196 :   if(hill.multivariate) {
+     977         144 :     double maxautoval=1./hill.sigma[0];
+     978         144 :     cutoff=std::sqrt(2.0*dp2cutoff*maxautoval);
+     979             :   } else {
+     980          52 :     cutoff=std::sqrt(2.0*dp2cutoff)*hill.sigma[0];
+     981             :   }
+     982             : 
+     983         196 :   if(doInt_[iarg]) {
+     984         144 :     if(hill.center[0]+cutoff > uppI_[iarg] || hill.center[0]-cutoff < lowI_[iarg]) {
+     985             :       // in this case, we updated the entire grid to avoid problems
+     986           0 :       return BiasGrids_[iarg]->getNbin();
+     987             :     } else {
+     988         144 :       nneigh.push_back( static_cast<unsigned>(ceil(cutoff/BiasGrids_[iarg]->getDx()[0])));
+     989             :       return nneigh;
+     990             :     }
+     991             :   }
+     992             : 
+     993          52 :   nneigh.push_back( static_cast<unsigned>(ceil(cutoff/BiasGrids_[iarg]->getDx()[0])) );
+     994             : 
+     995             :   return nneigh;
+     996             : }
+     997             : 
+     998        1269 : double PBMetaD::getBiasAndDerivatives(unsigned iarg, const std::vector<double>& cv, double* der)
+     999             : {
+    1000        1269 :   double bias=0.0;
+    1001        1269 :   int family = pfs_[iarg];
+    1002        1269 :   if(!grid_) {
+    1003        1000 :     unsigned stride=comm.Get_size();
+    1004        1000 :     unsigned rank=comm.Get_rank();
+    1005        5520 :     for(unsigned i=rank; i<hills_[family].size(); i+=stride) {
+    1006        4520 :       bias += evaluateGaussian(iarg,cv,hills_[family][i],der);
+    1007             :     }
+    1008        1000 :     comm.Sum(bias);
+    1009        1000 :     if(der) comm.Sum(der,1);
+    1010             :   } else {
+    1011         269 :     if(der) {
+    1012         145 :       std::vector<double> vder(1);
+    1013         145 :       bias = BiasGrids_[family]->getValueAndDerivatives(cv,vder);
+    1014         145 :       der[0] = vder[0];
+    1015             :     } else {
+    1016         124 :       bias = BiasGrids_[family]->getValue(cv);
+    1017             :     }
+    1018             :   }
+    1019             : 
+    1020        1269 :   return bias;
+    1021             : }
+    1022             : 
+    1023        8664 : double PBMetaD::evaluateGaussian(unsigned iarg, const std::vector<double>& cv, const Gaussian& hill, double* der)
+    1024             : {
+    1025             :   double bias=0.0;
+    1026             : // I use a pointer here because cv is const (and should be const)
+    1027             : // but when using doInt it is easier to locally replace cv[0] with
+    1028             : // the upper/lower limit in case it is out of range
+    1029             :   const double *pcv=NULL;
+    1030             :   double tmpcv[1]; // tmp array with cv (to be used with doInt_)
+    1031        8664 :   tmpcv[0]=cv[0];
+    1032             :   bool isOutOfInt = false;
+    1033        8664 :   if(doInt_[iarg]) {
+    1034        2664 :     if(cv[0]<lowI_[iarg]) { tmpcv[0]=lowI_[iarg]; isOutOfInt = true; }
+    1035        2664 :     else if(cv[0]>uppI_[iarg]) { tmpcv[0]=uppI_[iarg]; isOutOfInt = true; }
+    1036             :   }
+    1037             :   pcv=&(tmpcv[0]);
+    1038             : 
+    1039        8664 :   if(hill.multivariate) {
+    1040        2664 :     double dp  = difference(iarg, hill.center[0], pcv[0]);
+    1041        2664 :     double dp2 = 0.5 * dp * dp * hill.sigma[0];
+    1042        2664 :     if(dp2<dp2cutoff) {
+    1043        2534 :       bias = hill.height*std::exp(-dp2);
+    1044        2534 :       if(der && !isOutOfInt) {
+    1045        2534 :         der[0] += -bias * dp * hill.sigma[0] * stretchA;
+    1046             :       }
+    1047        2534 :       bias=stretchA*bias+hill.height*stretchB;
+    1048             :     }
+    1049             :   } else {
+    1050        6000 :     double dp  = difference(iarg, hill.center[0], pcv[0]) * hill.invsigma[0];
+    1051        6000 :     double dp2 = 0.5 * dp * dp;
+    1052        6000 :     if(dp2<dp2cutoff) {
+    1053        5938 :       bias = hill.height*std::exp(-dp2);
+    1054        5938 :       if(der && !isOutOfInt) {
+    1055        3682 :         der[0] += -bias * dp * hill.invsigma[0] * stretchA;
+    1056             :       }
+    1057        5938 :       bias=stretchA*bias+hill.height*stretchB;
+    1058             :     }
+    1059             :   }
+    1060             : 
+    1061        8664 :   return bias;
+    1062             : }
+    1063             : 
+    1064         335 : void PBMetaD::calculate()
+    1065             : {
+    1066             :   // this is because presently there is no way to properly pass information
+    1067             :   // on adaptive hills (diff) after exchanges:
+    1068         335 :   if(adaptive_==FlexibleBin::diffusion && getExchangeStep()) error("ADAPTIVE=DIFF is not compatible with replica exchange");
+    1069             : 
+    1070         335 :   std::vector<double> cv(1);
+    1071             :   double der[1];
+    1072         335 :   std::vector<double> bias(getNumberOfArguments());
+    1073         335 :   std::vector<double> deriv(getNumberOfArguments());
+    1074             : 
+    1075         335 :   double ncv = (double) getNumberOfArguments();
+    1076             :   double bmin = 1.0e+19;
+    1077        1020 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1078         685 :     cv[0]    = getArgument(i);
+    1079         685 :     der[0]   = 0.0;
+    1080         685 :     bias[i]  = getBiasAndDerivatives(i, cv, der);
+    1081         685 :     deriv[i] = der[0];
+    1082         685 :     if(bias[i] < bmin) bmin = bias[i];
+    1083             :   }
+    1084             :   double ene = 0.;
+    1085        1020 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1086         685 :     ene += std::exp((-bias[i]+bmin)/kbt_);
+    1087             :   }
+    1088             : 
+    1089             :   // set Forces - set them to zero if SELECTOR is active
+    1090         335 :   if(do_select_) current_value_ = static_cast<unsigned>(plumed.passMap[selector_]);
+    1091             : 
+    1092         335 :   if(!do_select_ || select_value_==current_value_) {
+    1093        1020 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1094         685 :       const double f = - std::exp((-bias[i]+bmin)/kbt_) / (ene) * deriv[i];
+    1095         685 :       setOutputForce(i, f);
+    1096             :     }
+    1097             :   }
+    1098             : 
+    1099         335 :   if(do_select_ && select_value_!=current_value_) {
+    1100           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) setOutputForce(i, 0.0);
+    1101             :   }
+    1102             : 
+    1103             :   // set bias
+    1104         335 :   ene = -kbt_ * (std::log(ene) - std::log(ncv)) + bmin;
+    1105         335 :   setBias(ene);
+    1106         335 : }
+    1107             : 
+    1108         335 : void PBMetaD::update()
+    1109             : {
+    1110             :   bool multivariate;
+    1111             :   // adding hills criteria
+    1112             :   bool nowAddAHill;
+    1113         335 :   if(getStep()%stride_==0 && !isFirstStep_) nowAddAHill=true;
+    1114             :   else {
+    1115             :     nowAddAHill=false;
+    1116          49 :     isFirstStep_=false;
+    1117             :   }
+    1118             : 
+    1119             :   // if you use adaptive, call the FlexibleBin
+    1120         335 :   if(adaptive_!=FlexibleBin::none) {
+    1121         120 :     for(unsigned i=0; i<getNumberOfArguments(); i++) flexbin_[i].update(nowAddAHill,i);
+    1122             :     multivariate=true;
+    1123             :   } else {
+    1124             :     multivariate=false;
+    1125             :   }
+    1126             : 
+    1127         335 :   if(nowAddAHill && (!do_select_ || select_value_==current_value_)) {
+    1128             :     // get all biases and heights
+    1129         286 :     std::vector<double> cv(getNumberOfArguments());
+    1130         286 :     std::vector<double> bias(getNumberOfArguments());
+    1131         286 :     std::vector<double> thissigma(getNumberOfArguments());
+    1132         286 :     std::vector<double> height(getNumberOfArguments());
+    1133         286 :     std::vector<double> cv_tmp(1);
+    1134         286 :     std::vector<double> sigma_tmp(1);
+    1135             :     double norm = 0.0;
+    1136             :     double bmin = 1.0e+19;
+    1137         870 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1138         584 :       int family=pfs_[i];
+    1139             :       // get flex/sigmas for each family and assign them to this args sigma
+    1140         584 :       if(adaptive_!=FlexibleBin::none) thissigma[i]=flexbin_[family].getInverseMatrix(i)[0];
+    1141         512 :       else thissigma[i]=sigma0_[family];
+    1142         584 :       cv[i]     = getArgument(i);
+    1143         584 :       cv_tmp[0] = getArgument(i);
+    1144         584 :       bias[i] = getBiasAndDerivatives(i, cv_tmp);
+    1145         584 :       if(bias[i] < bmin) bmin = bias[i];
+    1146             :     }
+    1147             :     // calculate heights and norm
+    1148         870 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1149         584 :       double h = std::exp((-bias[i]+bmin)/kbt_);
+    1150         584 :       norm += h;
+    1151         584 :       height[i] = h;
+    1152             :     }
+    1153             :     // normalize and apply welltemp correction
+    1154         870 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1155         584 :       height[i] *=  height0_ / norm;
+    1156         584 :       if(welltemp_) height[i] *= std::exp(-bias[i]/(kbt_*(biasf_-1.0)));
+    1157             :     }
+    1158             : 
+    1159             :     // MPI Multiple walkers: share hills and add them all
+    1160         286 :     if(walkers_mpi_) {
+    1161             :       // Allocate arrays to store all walkers hills
+    1162         258 :       std::vector<double> all_cv(mpi_nw_*cv.size(), 0.0);
+    1163         258 :       std::vector<double> all_sigma(mpi_nw_*getNumberOfArguments(), 0.0);
+    1164         258 :       std::vector<double> all_height(mpi_nw_*height.size(), 0.0);
+    1165         258 :       if(comm.Get_rank()==0) {
+    1166             :         // fill in value
+    1167         390 :         for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1168         260 :           unsigned j = mpi_id_ * getNumberOfArguments() + i;
+    1169         260 :           all_cv[j] = cv[i];
+    1170         260 :           all_sigma[j]  = thissigma[i];
+    1171         260 :           all_height[j] = height[i];
+    1172             :         }
+    1173             :         // Communicate (only root)
+    1174         130 :         multi_sim_comm.Sum(&all_cv[0], all_cv.size());
+    1175         130 :         multi_sim_comm.Sum(&all_sigma[0], all_sigma.size());
+    1176         130 :         multi_sim_comm.Sum(&all_height[0], all_height.size());
+    1177             :       }
+    1178             :       // Share info with group members
+    1179         258 :       comm.Sum(&all_cv[0], all_cv.size());
+    1180         258 :       comm.Sum(&all_sigma[0], all_sigma.size());
+    1181         258 :       comm.Sum(&all_height[0], all_height.size());
+    1182             :       // now add hills one by one
+    1183         774 :       for(unsigned j=0; j<mpi_nw_; ++j) {
+    1184        1548 :         for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1185             :           // Add CVs of same family together and write to same file
+    1186        1032 :           int family = pfs_[i];
+    1187        1032 :           cv_tmp[0]    = all_cv[j*cv.size()+i];
+    1188        1032 :           double height_tmp = all_height[j*cv.size()+i];
+    1189        1032 :           sigma_tmp[0] = all_sigma[j*cv.size()+i];
+    1190        1032 :           Gaussian newhill = Gaussian(cv_tmp, sigma_tmp, height_tmp, multivariate);
+    1191        1032 :           addGaussian(family, newhill);
+    1192        1032 :           writeGaussian(i, newhill, hillsOfiles_[family].get());
+    1193        1032 :         }
+    1194             :       }
+    1195             :       // just add your own hills
+    1196             :     } else {
+    1197          96 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1198             :         // Add CVs of same family together and write to same file
+    1199          68 :         int family = pfs_[i];
+    1200          68 :         cv_tmp[0] = cv[i];
+    1201          68 :         if(adaptive_!=FlexibleBin::none) sigma_tmp[0]=thissigma[i];
+    1202          68 :         else sigma_tmp[0] = sigma0_[family];
+    1203          68 :         Gaussian newhill = Gaussian(cv_tmp, sigma_tmp, height[i], multivariate);
+    1204          68 :         addGaussian(family, newhill);
+    1205          68 :         writeGaussian(i, newhill, hillsOfiles_[family].get());
+    1206          68 :       }
+    1207             :     }
+    1208             :   }
+    1209             : 
+    1210             :   // write grid files
+    1211         335 :   if(wgridstride_>0 && (getStep()%wgridstride_==0 || getCPT())) {
+    1212          14 :     int r = 0;
+    1213          14 :     if(walkers_mpi_) {
+    1214           4 :       if(comm.Get_rank()==0) r=multi_sim_comm.Get_rank();
+    1215           4 :       comm.Bcast(r,0);
+    1216             :     }
+    1217          14 :     if(r==0) {
+    1218          36 :       for(unsigned i=0; i<gridfiles_.size(); ++i) {
+    1219          24 :         gridfiles_[i]->rewind();
+    1220          24 :         BiasGrids_[i]->writeToFile(*gridfiles_[i]);
+    1221          24 :         gridfiles_[i]->flush();
+    1222             :       }
+    1223             :     }
+    1224             :   }
+    1225             : 
+    1226             :   // if multiple walkers and time to read Gaussians
+    1227         335 :   if(mw_n_>1 && getStep()%mw_rstride_==0) {
+    1228           0 :     for(int j=0; j<mw_n_; ++j) {
+    1229           0 :       for(unsigned i=0; i<hillsfname_.size(); ++i) {
+    1230           0 :         unsigned k=j*hillsfname_.size()+i;
+    1231             :         // don't read your own Gaussians
+    1232           0 :         if(j==mw_id_) continue;
+    1233             :         // if the file is not open yet
+    1234           0 :         if(!(ifiles_[k]->isOpen())) {
+    1235             :           // check if it exists now and open it!
+    1236           0 :           if(ifiles_[k]->FileExist(ifilesnames_[k])) {
+    1237           0 :             ifiles_[k]->open(ifilesnames_[k]);
+    1238           0 :             ifiles_[k]->reset(false);
+    1239             :           }
+    1240             :           // otherwise read the new Gaussians
+    1241             :         } else {
+    1242           0 :           log.printf("  Reading hills from %s:",ifilesnames_[k].c_str());
+    1243           0 :           readGaussians(i,ifiles_[k].get());
+    1244           0 :           ifiles_[k]->reset(false);
+    1245             :         }
+    1246             :       }
+    1247             :     }
+    1248             :   }
+    1249             : 
+    1250         335 : }
+    1251             : 
+    1252             : /// takes a pointer to the file and a template string with values v and gives back the next center, sigma and height
+    1253          10 : bool PBMetaD::scanOneHill(unsigned iarg, IFile *ifile, std::vector<Value> &tmpvalues, std::vector<double> &center, std::vector<double> &sigma, double &height, bool &multivariate)
+    1254             : {
+    1255             :   double dummy;
+    1256          10 :   multivariate=false;
+    1257          10 :   Value* argPtr = pfhold_[pfs_[iarg]];
+    1258          20 :   if(ifile->scanField("time",dummy)) {
+    1259           8 :     ifile->scanField( &tmpvalues[0] );
+    1260           8 :     if( tmpvalues[0].isPeriodic() && ! argPtr->isPeriodic() ) {
+    1261           0 :       error("in hills file periodicity for variable " + tmpvalues[0].getName() + " does not match periodicity in input");
+    1262           8 :     } else if( tmpvalues[0].isPeriodic() ) {
+    1263           0 :       std::string imin, imax; tmpvalues[0].getDomain( imin, imax );
+    1264           0 :       std::string rmin, rmax; argPtr->getDomain( rmin, rmax );
+    1265           0 :       if( imin!=rmin || imax!=rmax ) {
+    1266           0 :         error("in hills file periodicity for variable " + tmpvalues[0].getName() + " does not match periodicity in input");
+    1267             :       }
+    1268             :     }
+    1269           8 :     center[0]=tmpvalues[0].get();
+    1270           8 :     std::string ktype="stretched-gaussian";
+    1271          24 :     if( ifile->FieldExist("kerneltype") ) ifile->scanField("kerneltype",ktype);
+    1272             : 
+    1273           8 :     if( ktype=="gaussian" ) {
+    1274           0 :       noStretchWarning();
+    1275           8 :     } else if( ktype!="stretched-gaussian") {
+    1276           0 :       error("non Gaussian kernels are not supported in MetaD");
+    1277             :     }
+    1278             : 
+    1279             :     std::string sss;
+    1280          16 :     ifile->scanField("multivariate",sss);
+    1281           8 :     if(sss=="true") multivariate=true;
+    1282           8 :     else if(sss=="false") multivariate=false;
+    1283           0 :     else plumed_merror("cannot parse multivariate = "+ sss);
+    1284           8 :     if(multivariate) {
+    1285           0 :       ifile->scanField("sigma_"+argPtr->getName()+"_"+
+    1286             :                        argPtr->getName(),sigma[0]);
+    1287           0 :       sigma[0] = 1./(sigma[0]*sigma[0]);
+    1288             :     } else {
+    1289          16 :       ifile->scanField("sigma_"+argPtr->getName(),sigma[0]);
+    1290             :     }
+    1291           8 :     ifile->scanField("height",height);
+    1292           8 :     ifile->scanField("biasf",dummy);
+    1293          16 :     if(ifile->FieldExist("clock")) ifile->scanField("clock",dummy);
+    1294          16 :     if(ifile->FieldExist("lower_int")) ifile->scanField("lower_int",dummy);
+    1295          16 :     if(ifile->FieldExist("upper_int")) ifile->scanField("upper_int",dummy);
+    1296           8 :     ifile->scanField();
+    1297             :     return true;
+    1298             :   } else {
+    1299             :     return false;
+    1300             :   }
+    1301             : 
+    1302             : }
+    1303             : 
+    1304         335 : bool PBMetaD::checkNeedsGradients()const
+    1305             : {
+    1306         335 :   if(adaptive_==FlexibleBin::geometry) {
+    1307           0 :     if(getStep()%stride_==0 && !isFirstStep_) return true;
+    1308           0 :     else return false;
+    1309             :   } else return false;
+    1310             : }
+    1311             : 
+    1312             : }
+    1313             : }
+    1314             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Restraint.cpp.func-sort-c.html b/coverage/bias/Restraint.cpp.func-sort-c.html new file mode 100644 index 000000000000..ef8900f60c17 --- /dev/null +++ b/coverage/bias/Restraint.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/Restraint.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Restraint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4141100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9RestraintC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias9RestraintC1ERKNS_13ActionOptionsE178
_ZN4PLMD4bias9Restraint16registerKeywordsERNS_8KeywordsE180
_ZN4PLMD4bias9Restraint9calculateEv4670
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Restraint.cpp.func.html b/coverage/bias/Restraint.cpp.func.html new file mode 100644 index 000000000000..7b575c84e142 --- /dev/null +++ b/coverage/bias/Restraint.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/Restraint.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Restraint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4141100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias9Restraint16registerKeywordsERNS_8KeywordsE180
_ZN4PLMD4bias9Restraint9calculateEv4670
_ZN4PLMD4bias9RestraintC1ERKNS_13ActionOptionsE178
_ZN4PLMD4bias9RestraintC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/Restraint.cpp.gcov.html b/coverage/bias/Restraint.cpp.gcov.html new file mode 100644 index 000000000000..62436db70d22 --- /dev/null +++ b/coverage/bias/Restraint.cpp.gcov.html @@ -0,0 +1,204 @@ + + + + + + + + LCOV - plumed test coverage - bias/Restraint.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - Restraint.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4141100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace bias {
+      27             : 
+      28             : //+PLUMEDOC BIAS RESTRAINT
+      29             : /*
+      30             : Adds harmonic and/or linear restraints on one or more variables.
+      31             : 
+      32             : Either or both
+      33             : of SLOPE and KAPPA must be present to specify the linear and harmonic force constants
+      34             : respectively.  The resulting potential is given by:
+      35             : \f[
+      36             :   \sum_i \frac{k_i}{2} (x_i-a_i)^2 + m_i*(x_i-a_i)
+      37             : \f].
+      38             : 
+      39             : The number of components for any vector of force constants must be equal to the number
+      40             : of arguments to the action.
+      41             : 
+      42             : Additional material and examples can be also found in the tutorial \ref lugano-2
+      43             : 
+      44             : \par Examples
+      45             : 
+      46             : The following input tells plumed to restrain the distance between atoms 3 and 5
+      47             : and the distance between atoms 2 and 4, at different equilibrium
+      48             : values, and to print the energy of the restraint
+      49             : \plumedfile
+      50             : DISTANCE ATOMS=3,5 LABEL=d1
+      51             : DISTANCE ATOMS=2,4 LABEL=d2
+      52             : RESTRAINT ARG=d1,d2 AT=1.0,1.5 KAPPA=150.0,150.0 LABEL=restraint
+      53             : PRINT ARG=restraint.bias
+      54             : \endplumedfile
+      55             : 
+      56             : */
+      57             : //+ENDPLUMEDOC
+      58             : 
+      59             : class Restraint : public Bias {
+      60             :   std::vector<double> at;
+      61             :   std::vector<double> kappa;
+      62             :   std::vector<double> slope;
+      63             :   Value* valueForce2;
+      64             : public:
+      65             :   explicit Restraint(const ActionOptions&);
+      66             :   void calculate() override;
+      67             :   static void registerKeywords(Keywords& keys);
+      68             : };
+      69             : 
+      70             : PLUMED_REGISTER_ACTION(Restraint,"RESTRAINT")
+      71             : 
+      72         180 : void Restraint::registerKeywords(Keywords& keys) {
+      73         180 :   Bias::registerKeywords(keys);
+      74         180 :   keys.use("ARG");
+      75         360 :   keys.add("compulsory","SLOPE","0.0","specifies that the restraint is linear and what the values of the force constants on each of the variables are");
+      76         360 :   keys.add("compulsory","KAPPA","0.0","specifies that the restraint is harmonic and what the values of the force constants on each of the variables are");
+      77         360 :   keys.add("compulsory","AT","the position of the restraint");
+      78         360 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      79         180 : }
+      80             : 
+      81         178 : Restraint::Restraint(const ActionOptions&ao):
+      82             :   PLUMED_BIAS_INIT(ao),
+      83         350 :   at(getNumberOfArguments()),
+      84         175 :   kappa(getNumberOfArguments(),0.0),
+      85         353 :   slope(getNumberOfArguments(),0.0)
+      86             : {
+      87         175 :   parseVector("SLOPE",slope);
+      88         175 :   parseVector("KAPPA",kappa);
+      89         175 :   parseVector("AT",at);
+      90         175 :   checkRead();
+      91             : 
+      92         175 :   log.printf("  at");
+      93         385 :   for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
+      94         175 :   log.printf("\n");
+      95         175 :   log.printf("  with harmonic force constant");
+      96         385 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+      97         175 :   log.printf("\n");
+      98         175 :   log.printf("  and linear force constant");
+      99         385 :   for(unsigned i=0; i<slope.size(); i++) log.printf(" %f",slope[i]);
+     100         175 :   log.printf("\n");
+     101             : 
+     102         350 :   addComponent("force2");
+     103         175 :   componentIsNotPeriodic("force2");
+     104         175 :   valueForce2=getPntrToComponent("force2");
+     105         178 : }
+     106             : 
+     107             : 
+     108        4670 : void Restraint::calculate() {
+     109             :   double ene=0.0;
+     110             :   double totf2=0.0;
+     111        9607 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     112        9874 :     const double cv=difference(i,at[i],getArgument(i));
+     113        4937 :     const double k=kappa[i];
+     114        4937 :     const double m=slope[i];
+     115        4937 :     const double f=-(k*cv+m);
+     116        4937 :     ene+=0.5*k*cv*cv+m*cv;
+     117        4937 :     setOutputForce(i,f);
+     118        4937 :     totf2+=f*f;
+     119             :   }
+     120        4670 :   setBias(ene);
+     121        4670 :   valueForce2->set(totf2);
+     122        4670 : }
+     123             : 
+     124             : }
+     125             : 
+     126             : 
+     127             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.cpp.func-sort-c.html b/coverage/bias/ReweightBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..1d67a8976d54 --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightBaseC2ERKNS_13ActionOptionsE20
_ZN4PLMD4bias12ReweightBase16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD4bias12ReweightBase9calculateEv6232
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.cpp.func.html b/coverage/bias/ReweightBase.cpp.func.html new file mode 100644 index 000000000000..c38518d583a8 --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBase16registerKeywordsERNS_8KeywordsE28
_ZN4PLMD4bias12ReweightBase9calculateEv6232
_ZN4PLMD4bias12ReweightBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightBaseC2ERKNS_13ActionOptionsE20
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.cpp.gcov.html b/coverage/bias/ReweightBase.cpp.gcov.html new file mode 100644 index 000000000000..7c6107ff4795 --- /dev/null +++ b/coverage/bias/ReweightBase.cpp.gcov.html @@ -0,0 +1,130 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ReweightBase.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace bias {
+      26             : 
+      27          28 : void ReweightBase::registerKeywords(Keywords& keys) {
+      28          28 :   Action::registerKeywords( keys );
+      29          28 :   ActionWithValue::registerKeywords( keys );
+      30          28 :   ActionWithArguments::registerKeywords( keys );
+      31          28 :   keys.setComponentsIntroduction("This action calculates the logarithm of a weight for reweighting");
+      32          56 :   keys.add("optional","TEMP","the system temperature.  This is not required if your MD code passes this quantity to PLUMED");
+      33          28 :   keys.remove("NUMERICAL_DERIVATIVES");
+      34          28 : }
+      35             : 
+      36          20 : ReweightBase::ReweightBase(const ActionOptions&ao):
+      37             :   Action(ao),
+      38             :   ActionWithValue(ao),
+      39          20 :   ActionWithArguments(ao)
+      40             : {
+      41          20 :   simtemp=getkBT();
+      42          20 :   if(simtemp==0) error("The MD engine does not pass the temperature to plumed so you have to specify it using TEMP");
+      43             :   // Create something to hold the weight
+      44          40 :   addValue(); setNotPeriodic();
+      45          20 : }
+      46             : 
+      47        6232 : void ReweightBase::calculate() {
+      48        6232 :   double weight = getLogWeight();
+      49        6232 :   setValue( weight );
+      50        6232 : }
+      51             : 
+      52             : }
+      53             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.h.func-sort-c.html b/coverage/bias/ReweightBase.h.func-sort-c.html new file mode 100644 index 000000000000..174d68052bcd --- /dev/null +++ b/coverage/bias/ReweightBase.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2633.3 %
Date:2024-02-22 21:58:45Functions:2633.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBase16calculateWeightsERKj0
_ZN4PLMD4bias12ReweightBase22getNumberOfDerivativesEv0
_ZN4PLMD4bias12ReweightBase9clearDataEv0
_ZNK4PLMD4bias12ReweightBase9getWeightERKj0
_ZNK4PLMD4bias12ReweightBase17buildsWeightStoreEv7
_ZN4PLMD4bias12ReweightBase5applyEv6232
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.h.func.html b/coverage/bias/ReweightBase.h.func.html new file mode 100644 index 000000000000..7801803264b2 --- /dev/null +++ b/coverage/bias/ReweightBase.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2633.3 %
Date:2024-02-22 21:58:45Functions:2633.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBase16calculateWeightsERKj0
_ZN4PLMD4bias12ReweightBase22getNumberOfDerivativesEv0
_ZN4PLMD4bias12ReweightBase5applyEv6232
_ZN4PLMD4bias12ReweightBase9clearDataEv0
_ZNK4PLMD4bias12ReweightBase17buildsWeightStoreEv7
_ZNK4PLMD4bias12ReweightBase9getWeightERKj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBase.h.gcov.html b/coverage/bias/ReweightBase.h.gcov.html new file mode 100644 index 000000000000..2f0aacf7e4ad --- /dev/null +++ b/coverage/bias/ReweightBase.h.gcov.html @@ -0,0 +1,130 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2633.3 %
Date:2024-02-22 21:58:45Functions:2633.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_bias_ReweightBase_h
+      23             : #define __PLUMED_bias_ReweightBase_h
+      24             : 
+      25             : #include "core/ActionWithValue.h"
+      26             : #include "core/ActionWithArguments.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace bias {
+      30             : 
+      31             : class ReweightBase :
+      32             :   public ActionWithValue,
+      33             :   public ActionWithArguments
+      34             : {
+      35             : protected:
+      36             : /// The temperature at which you are running the simulation
+      37             :   double simtemp;
+      38             : public:
+      39             :   static void registerKeywords(Keywords&);
+      40             :   explicit ReweightBase(const ActionOptions&ao);
+      41           0 :   unsigned getNumberOfDerivatives() override { return 0; }
+      42           7 :   virtual bool buildsWeightStore() const { return false; }
+      43             :   void calculate() override;
+      44           0 :   virtual void calculateWeights( const unsigned& nframes ) {}
+      45             :   virtual double getLogWeight() = 0;
+      46           0 :   virtual double getWeight( const unsigned& iweight ) const { plumed_error(); }
+      47           0 :   virtual void clearData() {}
+      48        6232 :   void apply() override {}
+      49             : };
+      50             : 
+      51             : }
+      52             : }
+      53             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBias.cpp.func-sort-c.html b/coverage/bias/ReweightBias.cpp.func-sort-c.html new file mode 100644 index 000000000000..a21c384deaca --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightBiasC1ERKNS_13ActionOptionsE3
_ZN4PLMD4bias12ReweightBias16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4bias12ReweightBias12getLogWeightEv1007
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBias.cpp.func.html b/coverage/bias/ReweightBias.cpp.func.html new file mode 100644 index 000000000000..e6e928e9f377 --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightBias12getLogWeightEv1007
_ZN4PLMD4bias12ReweightBias16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4bias12ReweightBiasC1ERKNS_13ActionOptionsE3
_ZN4PLMD4bias12ReweightBiasC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightBias.cpp.gcov.html b/coverage/bias/ReweightBias.cpp.gcov.html new file mode 100644 index 000000000000..813a0981943e --- /dev/null +++ b/coverage/bias/ReweightBias.cpp.gcov.html @@ -0,0 +1,175 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightBias.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ReweightBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC REWEIGHTING REWEIGHT_BIAS
+      26             : /*
+      27             : Calculate weights for ensemble averages that negate the effect the bias has on the region of phase space explored
+      28             : 
+      29             : If a static or pseudo-static bias \f$V(x,t')\f$ is acting on
+      30             : the system we can remove the bias and get the unbiased probability distribution using:
+      31             : 
+      32             : \f[
+      33             : \langle P(s',t) \rangle = \frac{ \sum_{t'}^t \delta( s(x) - s' ) \exp\left( +\frac{V(x,t')}{k_B T} \right) }{ \sum_t'^t \exp\left( +\frac{V(x,t')}{k_B T} \right) }
+      34             : \f]
+      35             : 
+      36             : The weights calculated by this action are equal to \f$\exp\left( +\frac{V(x,t')}{k_B T} \right)\f$ these weights can then be used in any action
+      37             : that computes ensemble averages.  For example this action can be used in tandem with \ref HISTOGRAM or \ref AVERAGE.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : In the following example there is a fixed restraint on the distance between atoms 1 and 2.  Clearly, this
+      42             : restraint will have an effect on the region of phase space that will be sampled when an MD simulation is
+      43             : run using this variable.  Consequently, when the histogram as a function of the distance, \f$x\f$, is accumulated,
+      44             : we use reweighting into order to discount the effect of the bias from our final histogram.
+      45             : 
+      46             : \plumedfile
+      47             : x: DISTANCE ATOMS=1,2
+      48             : RESTRAINT ARG=x SLOPE=1.0 AT=0.0
+      49             : bias: REWEIGHT_BIAS TEMP=300
+      50             : 
+      51             : HISTOGRAM ...
+      52             :   ARG=x
+      53             :   GRID_MIN=0.0
+      54             :   GRID_MAX=3.0
+      55             :   GRID_BIN=100
+      56             :   BANDWIDTH=0.1
+      57             :   LOGWEIGHTS=bias
+      58             :   LABEL=hB
+      59             : ... HISTOGRAM
+      60             : 
+      61             : DUMPGRID GRID=hB FILE=histoB STRIDE=1 FMT=%8.4f
+      62             : \endplumedfile
+      63             : 
+      64             : 
+      65             : */
+      66             : //+ENDPLUMEDOC
+      67             : 
+      68             : namespace PLMD {
+      69             : namespace bias {
+      70             : 
+      71             : class ReweightBias : public ReweightBase {
+      72             : public:
+      73             :   static void registerKeywords(Keywords&);
+      74             :   explicit ReweightBias(const ActionOptions&ao);
+      75             :   double getLogWeight() override;
+      76             : };
+      77             : 
+      78             : PLUMED_REGISTER_ACTION(ReweightBias,"REWEIGHT_BIAS")
+      79             : 
+      80           5 : void ReweightBias::registerKeywords(Keywords& keys ) {
+      81           5 :   ReweightBase::registerKeywords( keys ); keys.remove("ARG");
+      82          10 :   keys.add("compulsory","ARG","*.bias","the biases that must be taken into account when reweighting");
+      83           5 : }
+      84             : 
+      85           3 : ReweightBias::ReweightBias(const ActionOptions&ao):
+      86             :   Action(ao),
+      87           3 :   ReweightBase(ao)
+      88             : {
+      89           3 : }
+      90             : 
+      91        1007 : double ReweightBias::getLogWeight() {
+      92             :   // Retrieve the bias
+      93        2014 :   double bias=0.0; for(unsigned i=0; i<getNumberOfArguments(); ++i) bias+=getArgument(i);
+      94        1007 :   return bias / simtemp;
+      95             : }
+      96             : 
+      97             : }
+      98             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightMetad.cpp.func-sort-c.html b/coverage/bias/ReweightMetad.cpp.func-sort-c.html new file mode 100644 index 000000000000..9fe50a248347 --- /dev/null +++ b/coverage/bias/ReweightMetad.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightMetad.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightMetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias13ReweightMetadC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias13ReweightMetadC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias13ReweightMetad12getLogWeightEv2
_ZN4PLMD4bias13ReweightMetad16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightMetad.cpp.func.html b/coverage/bias/ReweightMetad.cpp.func.html new file mode 100644 index 000000000000..93179ac4d0a6 --- /dev/null +++ b/coverage/bias/ReweightMetad.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightMetad.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightMetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias13ReweightMetad12getLogWeightEv2
_ZN4PLMD4bias13ReweightMetad16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4bias13ReweightMetadC1ERKNS_13ActionOptionsE1
_ZN4PLMD4bias13ReweightMetadC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightMetad.cpp.gcov.html b/coverage/bias/ReweightMetad.cpp.gcov.html new file mode 100644 index 000000000000..7f01b2afb2b4 --- /dev/null +++ b/coverage/bias/ReweightMetad.cpp.gcov.html @@ -0,0 +1,172 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightMetad.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightMetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "ReweightBase.h"
+      24             : 
+      25             : //+PLUMEDOC REWEIGHTING REWEIGHT_METAD
+      26             : /*
+      27             : Calculate the weights configurations should contribute to the histogram in a simulation in which a metadynamics bias acts upon the system.
+      28             : 
+      29             : This command allows you to use the reweighting algorithm discussed in \cite PratyushReweighting when constructing a histogram
+      30             : of the configurations visited during a metadynamics simulation.
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : In the following example there is a metadynamics bias acting on the distance between atoms 1 and 2.  Clearly, this
+      35             : bias will have an effect on the region of phase space that will be sampled when an MD simulation is
+      36             : run using this variable.  Consequently, when the histogram as a function of the angle, \f$a\f$, is accumulated,
+      37             : we use reweighting into order to discount the effect of the bias from our final histogram.  We do not use
+      38             : \ref REWEIGHT_BIAS here, however, as the bias changes with time.  We thus use the reweighting algorithm for
+      39             : metadynamics instead.  Notice also that we have to specify how often we would like to calculate the c(t) reweighting
+      40             : factor and the grid over which we calculate c(t) in the input to the METAD command.
+      41             : 
+      42             : \plumedfile
+      43             : a: ANGLE ATOMS=1,2,3
+      44             : x: DISTANCE ATOMS=1,2
+      45             : METAD ARG=x PACE=100 SIGMA=0.1 HEIGHT=1.5 BIASFACTOR=5 GRID_MIN=0 GRID_MAX=10 GRID_BIN=100 CALC_RCT RCT_USTRIDE=50
+      46             : 
+      47             : bias: REWEIGHT_METAD TEMP=300
+      48             : 
+      49             : HISTOGRAM ...
+      50             :   ARG=a
+      51             :   GRID_MIN=0.0
+      52             :   GRID_MAX=pi
+      53             :   GRID_BIN=100
+      54             :   BANDWIDTH=0.1
+      55             :   LOGWEIGHTS=bias
+      56             :   LABEL=hB
+      57             : ... HISTOGRAM
+      58             : 
+      59             : DUMPGRID GRID=hB FILE=histoB STRIDE=1 FMT=%8.4f
+      60             : \endplumedfile
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : namespace PLMD {
+      66             : namespace bias {
+      67             : 
+      68             : class ReweightMetad : public ReweightBase {
+      69             : public:
+      70             :   static void registerKeywords(Keywords&);
+      71             :   explicit ReweightMetad(const ActionOptions&ao);
+      72             :   double getLogWeight() override;
+      73             : };
+      74             : 
+      75             : PLUMED_REGISTER_ACTION(ReweightMetad,"REWEIGHT_METAD")
+      76             : 
+      77           3 : void ReweightMetad::registerKeywords(Keywords& keys ) {
+      78           3 :   ReweightBase::registerKeywords( keys ); keys.remove("ARG");
+      79           6 :   keys.add("compulsory","ARG","*.rbias","the biases that must be taken into account when reweighting");
+      80           3 : }
+      81             : 
+      82           1 : ReweightMetad::ReweightMetad(const ActionOptions&ao):
+      83             :   Action(ao),
+      84           1 :   ReweightBase(ao)
+      85             : {
+      86           1 : }
+      87             : 
+      88           2 : double ReweightMetad::getLogWeight() {
+      89             :   // Retrieve the bias
+      90           4 :   double bias=0.0; for(unsigned i=0; i<getNumberOfArguments(); ++i) bias+=getArgument(i);
+      91           2 :   return bias / simtemp;
+      92             : }
+      93             : 
+      94             : }
+      95             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightTemperaturePressure.cpp.func-sort-c.html b/coverage/bias/ReweightTemperaturePressure.cpp.func-sort-c.html new file mode 100644 index 000000000000..fa538cec035b --- /dev/null +++ b/coverage/bias/ReweightTemperaturePressure.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightTemperaturePressure.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightTemperaturePressure.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:454697.8 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias27ReweightTemperaturePressureC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias27ReweightTemperaturePressureC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias27ReweightTemperaturePressure16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4bias27ReweightTemperaturePressure12getLogWeightEv1001
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightTemperaturePressure.cpp.func.html b/coverage/bias/ReweightTemperaturePressure.cpp.func.html new file mode 100644 index 000000000000..be5f6890eb63 --- /dev/null +++ b/coverage/bias/ReweightTemperaturePressure.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightTemperaturePressure.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightTemperaturePressure.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:454697.8 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias27ReweightTemperaturePressure12getLogWeightEv1001
_ZN4PLMD4bias27ReweightTemperaturePressure16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4bias27ReweightTemperaturePressureC1ERKNS_13ActionOptionsE4
_ZN4PLMD4bias27ReweightTemperaturePressureC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightTemperaturePressure.cpp.gcov.html b/coverage/bias/ReweightTemperaturePressure.cpp.gcov.html new file mode 100644 index 000000000000..d8e540e925c8 --- /dev/null +++ b/coverage/bias/ReweightTemperaturePressure.cpp.gcov.html @@ -0,0 +1,341 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightTemperaturePressure.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightTemperaturePressure.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:454697.8 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2019-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "ReweightBase.h"
+      24             : 
+      25             : //+PLUMEDOC REWEIGHTING REWEIGHT_TEMP_PRESS
+      26             : /*
+      27             : Calculate weights for ensemble averages at temperatures and/or pressures different than those used in your original simulation.
+      28             : 
+      29             : We can use our knowledge of the probability distribution in the canonical (N\f$\mathcal{V}\f$T) or the isothermal-isobaric ensemble (NPT) to reweight the data
+      30             : contained in trajectories and obtain ensemble averages at different temperatures and/or pressures.
+      31             : 
+      32             : Consider the ensemble average of an observable \f$O(\mathbf{R},\mathcal{V})\f$ that depends on the atomic coordinates \f$\mathbf{R}\f$ and the volume \f$\mathcal{V}\f$.
+      33             : This observable is in practice any collective variable (CV) calculated by Plumed.
+      34             : The ensemble average of the observable in an ensemble \f$ \xi' \f$  can be calculated from a simulation performed in an ensemble \f$ \xi \f$ using:
+      35             : \f[
+      36             : \langle O(\mathbf{R},\mathcal{V}) \rangle_{\xi'} = \frac{\langle O(\mathbf{R},\mathcal{V}) w(\mathbf{R},\mathcal{V}) \rangle_{\xi}}
+      37             :                                                      {\langle w(\mathbf{R},\mathcal{V}) \rangle_{\xi}}
+      38             : \f]
+      39             : where \f$\langle \cdot \rangle_{\xi}\f$ and  \f$\langle \cdot \rangle_{\xi'}\f$ are mean values in the simulated and targeted ensemble, respectively, \f$ E(\mathbf{R}) \f$ is the potential energy of the system, and \f$ w (\mathbf{R},\mathcal{V}) \f$ are the appropriate weights to take from \f$ \xi \f$ to \f$ \xi' \f$.
+      40             : This action calculates the weights  \f$ w (\mathbf{R},\mathcal{V}) \f$ and handles 4 different cases:
+      41             :   1. Change of temperature from T to T' at constant volume. That is to say, from a simulation performed in the N\f$\mathcal{V}\f$T (canonical) ensemble, obtain an ensemble average in the N\f$\mathcal{V}\f$T' ensemble. The weights in this case are  \f$ w(\mathbf{R},\mathcal{V}) = e^{(\beta-\beta')E(\mathbf{R})} \f$ with \f$ \beta \f$ and \f$ \beta' \f$ the inverse temperatures.
+      42             :   2. Change of temperature from T to T' at constant pressure. That is to say, from a simulation performed in the NPT (isothermal-isobaric) ensemble, obtain an ensemble average in the NPT' ensemble. The weights in this case are \f$ w(\mathbf{R},\mathcal{V}) = e^{(\beta-\beta')(E(\mathbf{R}) + P\mathcal{V}) } \f$.
+      43             :   3. Change of pressure from P to P' at constant temperature. That is to say, from a simulation performed in the NPT (isothermal-isobaric) ensemble, obtain an ensemble average in the NP'T ensemble. The weights in this case are \f$ w(\mathbf{R},\mathcal{V}) = e^{\beta (P - P') \mathcal{V}} \f$.
+      44             :   4. Change of temperature and pressure from T,P to T',P'. That is to say, from a simulation performed in the NPT (isothermal-isobaric) ensemble, obtain an ensemble average in the NP'T' ensemble. The weights in this case are \f$ w(\mathbf{R},\mathcal{V}) = e^{(\beta-\beta')E(\mathbf{R}) + (\beta P - \beta' P') \mathcal{V}} \f$.
+      45             : 
+      46             : These weights can be used in any action that computes ensemble averages.
+      47             : For example this action can be used in tandem with \ref HISTOGRAM or \ref AVERAGE.
+      48             : 
+      49             : 
+      50             : The above equation is often impractical since the overlap between the distributions of energy and volume at different temperatures and pressures is only significant for neighboring temperatures and pressures.
+      51             : For this reason an unbiased simulation is of little use to reweight at different temperatures and/or pressures.
+      52             : A successful approach has been altering the probability of observing a configuration in order to increase this overlap \cite wanglandau.
+      53             : This is done through a bias potential \f$ V(\mathbf{s}) \f$ where \f$ \mathbf{s} \f$ is a set of CVs, that often is the energy (and possibly the volume).
+      54             : In order to calculate ensemble averages, also the effect of this bias must be taken into account.
+      55             : The ensemble average of the observable in the ensemble \f$ \xi' \f$ can be calculated from a biased simulation performed in the ensemble \f$\xi\f$ with bias \f$ V(\mathbf{s}) \f$ using:
+      56             : \f[
+      57             : \langle O(\mathbf{R},\mathcal{V}) \rangle_{\xi'} = \frac{\langle O(\mathbf{R},\mathcal{V})  w (\mathbf{R},\mathcal{V}) e^{\beta V(\mathbf{s})}  \rangle_{\xi,V}}
+      58             :                                                      {\langle w (\mathbf{R},\mathcal{V})  e^{\beta V(\mathbf{s})}  \rangle_{\xi,V}}
+      59             : \f]
+      60             : where \f$\langle \cdot \rangle_{\xi,V}\f$ is a mean value in the biased ensemble with static bias \f$ V(\mathbf{s}) \f$.
+      61             : Therefore in order to reweight the trajectory at different temperatures and/or pressures one must use the weights calculated by this action \f$ w (\mathbf{R},\mathcal{V}) \f$ together with the weights of \ref REWEIGHT_BIAS (see the examples below).
+      62             : 
+      63             : The bias potential \f$ V(\mathbf{s}) \f$ can be constructed with \ref METAD using \ref ENERGY as a CV \cite mich+04prl.
+      64             : More specialized tools are available, for instance using bespoke target distributions such as \ref TD_MULTICANONICAL and \ref TD_MULTITHERMAL_MULTIBARIC \cite Piaggi-PRL-2019 \cite Piaggi-JCP-2019 within \ref VES.
+      65             : In the latter algorithms the interval of temperatures and pressures in which the trajectory can be reweighted is chosen explicitly.
+      66             : 
+      67             : \par Examples
+      68             : 
+      69             : We consider the 4 cases described above.
+      70             : 
+      71             : The following input can be used to postprocess a molecular dynamics trajectory of a system of 1000 particles run at 500 K and constant volume using a static bias potential.
+      72             : 
+      73             : \plumedfile
+      74             : energy: READ FILE=COLVAR VALUES=energy  IGNORE_TIME
+      75             : distance: READ FILE=COLVAR VALUES=distance  IGNORE_TIME
+      76             : mybias: READ FILE=COLVAR VALUES=mybias.bias  IGNORE_TIME
+      77             : 
+      78             : # Shift energy (to avoid numerical issues)
+      79             : renergy: COMBINE ARG=energy PARAMETERS=-13250 PERIODIC=NO
+      80             : 
+      81             : # Weights
+      82             : bias_weights: REWEIGHT_BIAS TEMP=500 ARG=mybias.bias
+      83             : temp_press_weights: REWEIGHT_TEMP_PRESS TEMP=500 REWEIGHT_TEMP=300 ENERGY=renergy
+      84             : 
+      85             : # Ensemble average of the distance at 300 K
+      86             : avg_dist: AVERAGE ARG=distance LOGWEIGHTS=bias_weights,temp_press_weights
+      87             : 
+      88             : PRINT ARG=avg_dist FILE=COLVAR_REWEIGHT STRIDE=1
+      89             : \endplumedfile
+      90             : 
+      91             : Clearly, in performing the analysis above we would read from the potential energy, a distance, and the value of the bias potential from a COLVAR file like the one shown below.  We would then be able
+      92             : to calculate the ensemble average of the distance at 300 K.
+      93             : 
+      94             : \auxfile{COLVAR}
+      95             : #! FIELDS time energy volume mybias.bias distance
+      96             :  10000.000000 -13133.769283 7.488921 63.740530 0.10293
+      97             :  10001.000000 -13200.239722 7.116548 36.691988 0.16253
+      98             :  10002.000000 -13165.108850 7.202273 44.408815 0.17625
+      99             : \endauxfile
+     100             : 
+     101             : The next three inputs can be used to postprocess a molecular dynamics trajectory of a system of 1000 particles run at 500 K and 1 bar using a static bias potential.
+     102             : 
+     103             : We read from a file COLVAR the potential energy, the volume, and the value of the bias potential and calculate the ensemble average of the (particle) density at 300 K and 1 bar (the simulation temperature was 500 K).
+     104             : 
+     105             : \plumedfile
+     106             : energy: READ FILE=COLVAR VALUES=energy  IGNORE_TIME
+     107             : volume: READ FILE=COLVAR VALUES=volume  IGNORE_TIME
+     108             : mybias: READ FILE=COLVAR VALUES=mybias.bias  IGNORE_TIME
+     109             : 
+     110             : # Shift energy and volume (to avoid numerical issues)
+     111             : rvol: COMBINE ARG=volume PARAMETERS=7.8 PERIODIC=NO
+     112             : renergy: COMBINE ARG=energy PARAMETERS=-13250 PERIODIC=NO
+     113             : 
+     114             : # Weights
+     115             : bias_weights: REWEIGHT_BIAS TEMP=500 ARG=mybias.bias
+     116             : temp_press_weights: REWEIGHT_TEMP_PRESS TEMP=500 REWEIGHT_TEMP=300 PRESSURE=0.06022140857 ENERGY=renergy VOLUME=rvol
+     117             : 
+     118             : # Ensemble average of the volume at 300 K
+     119             : avg_vol: AVERAGE ARG=volume LOGWEIGHTS=bias_weights,temp_press_weights
+     120             : # Ensemble average of the density at 300 K
+     121             : avg_density: CUSTOM ARG=avg_vol FUNC=1000/x PERIODIC=NO
+     122             : 
+     123             : PRINT ARG=avg_density FILE=COLVAR_REWEIGHT STRIDE=1
+     124             : \endplumedfile
+     125             : 
+     126             : In the next example we calculate the ensemble average of the (particle) density at 500 K and 300 MPa (the simulation pressure was 1 bar).
+     127             : 
+     128             : \plumedfile
+     129             : volume: READ FILE=COLVAR VALUES=volume  IGNORE_TIME
+     130             : mybias: READ FILE=COLVAR VALUES=mybias.bias  IGNORE_TIME
+     131             : 
+     132             : # Shift volume (to avoid numerical issues)
+     133             : rvol: COMBINE ARG=volume PARAMETERS=7.8 PERIODIC=NO
+     134             : 
+     135             : # Weights
+     136             : bias_weights: REWEIGHT_BIAS TEMP=500 ARG=mybias.bias
+     137             : temp_press_weights: REWEIGHT_TEMP_PRESS TEMP=500 PRESSURE=0.06022140857 REWEIGHT_PRESSURE=180.66422571 VOLUME=volume
+     138             : 
+     139             : # Ensemble average of the volume at 300 K and 300 MPa
+     140             : avg_vol: AVERAGE ARG=volume LOGWEIGHTS=bias_weights,temp_press_weights
+     141             : # Ensemble average of the density at 300 K and 300 MPa
+     142             : avg_density: CUSTOM ARG=avg_vol FUNC=1000/x PERIODIC=NO
+     143             : 
+     144             : PRINT ARG=avg_density FILE=COLVAR_REWEIGHT STRIDE=1
+     145             : \endplumedfile
+     146             : 
+     147             : 
+     148             : In this final example we calculate the ensemble average of the (particle) density at 300 K and 300 MPa (the simulation temperature and pressure were 500 K and 1 bar).
+     149             : 
+     150             : \plumedfile
+     151             : energy: READ FILE=COLVAR VALUES=energy  IGNORE_TIME
+     152             : volume: READ FILE=COLVAR VALUES=volume  IGNORE_TIME
+     153             : mybias: READ FILE=COLVAR VALUES=mybias.bias  IGNORE_TIME
+     154             : 
+     155             : # Shift energy and volume (to avoid numerical issues)
+     156             : rvol: COMBINE ARG=volume PARAMETERS=7.8 PERIODIC=NO
+     157             : renergy: COMBINE ARG=energy PARAMETERS=-13250 PERIODIC=NO
+     158             : 
+     159             : # Weights
+     160             : bias_weights: REWEIGHT_BIAS TEMP=500 ARG=mybias.bias
+     161             : temp_press_weights: REWEIGHT_TEMP_PRESS TEMP=500 REWEIGHT_TEMP=300 PRESSURE=0.06022140857 REWEIGHT_PRESSURE=180.66422571 ENERGY=renergy VOLUME=rvol
+     162             : 
+     163             : # Ensemble average of the volume at 300 K and 300 MPa
+     164             : avg_vol: AVERAGE ARG=volume LOGWEIGHTS=bias_weights,temp_press_weights
+     165             : # Ensemble average of the density at 300 K and 300 MPa
+     166             : avg_density: CUSTOM ARG=avg_vol FUNC=1000/x PERIODIC=NO
+     167             : 
+     168             : PRINT ARG=avg_density FILE=COLVAR_REWEIGHT STRIDE=1
+     169             : \endplumedfile
+     170             : 
+     171             : */
+     172             : //+ENDPLUMEDOC
+     173             : 
+     174             : namespace PLMD {
+     175             : namespace bias {
+     176             : 
+     177             : class ReweightTemperaturePressure : public ReweightBase {
+     178             : private:
+     179             : ///
+     180             :   double rpress_, press_, rtemp_;
+     181             :   std::vector<Value*> myenergy, myvol;
+     182             : public:
+     183             :   static void registerKeywords(Keywords&);
+     184             :   explicit ReweightTemperaturePressure(const ActionOptions&ao);
+     185             :   double getLogWeight() override;
+     186             : };
+     187             : 
+     188             : PLUMED_REGISTER_ACTION(ReweightTemperaturePressure,"REWEIGHT_TEMP_PRESS")
+     189             : 
+     190           6 : void ReweightTemperaturePressure::registerKeywords(Keywords& keys ) {
+     191           6 :   ReweightBase::registerKeywords( keys );
+     192           6 :   keys.remove("ARG");
+     193          12 :   keys.add("optional","ENERGY","Energy");
+     194          12 :   keys.add("optional","VOLUME","Volume");
+     195          12 :   keys.add("optional","REWEIGHT_PRESSURE","Reweighting pressure");
+     196          12 :   keys.add("optional","PRESSURE","The system pressure");
+     197          12 :   keys.add("optional","REWEIGHT_TEMP","Reweighting temperature");
+     198           6 : }
+     199             : 
+     200           4 : ReweightTemperaturePressure::ReweightTemperaturePressure(const ActionOptions&ao):
+     201             :   Action(ao),
+     202           4 :   ReweightBase(ao)
+     203             : {
+     204             :   // Initialize to not defined (negative)
+     205           4 :   rpress_=-1;
+     206           4 :   press_=-1;
+     207           4 :   rtemp_=-1;
+     208           4 :   parse("REWEIGHT_PRESSURE",rpress_);
+     209           4 :   parse("PRESSURE",press_);
+     210           4 :   parse("REWEIGHT_TEMP",rtemp_);
+     211           4 :   rtemp_*=getKBoltzmann();
+     212             : 
+     213           8 :   parseArgumentList("ENERGY",myenergy);
+     214           4 :   if(!myenergy.empty()) {
+     215           3 :     log.printf("  with energies: ");
+     216           6 :     for(unsigned i=0; i<myenergy.size(); i++) log.printf(" %s",myenergy[i]->getName().c_str());
+     217           3 :     log.printf("\n");
+     218             :   }
+     219             :   //requestArguments(myenergy);
+     220             : 
+     221           8 :   parseArgumentList("VOLUME",myvol);
+     222           4 :   if(!myvol.empty()) {
+     223           3 :     log.printf("  with volumes: ");
+     224           6 :     for(unsigned i=0; i<myvol.size(); i++) log.printf(" %s",myvol[i]->getName().c_str());
+     225           3 :     log.printf("\n");
+     226             :   }
+     227             : 
+     228             :   std::vector<Value*> conc;
+     229           4 :   conc.insert(conc.begin(), myenergy.begin(), myenergy.end());
+     230           4 :   conc.insert(conc.end(), myvol.begin(), myvol.end());
+     231           4 :   requestArguments(conc);
+     232             : 
+     233             :   // 4 possible cases
+     234             :   // Case 1) Reweight from T to T' with V=const (canonical)
+     235           4 :   if (rtemp_>=0 && press_<0 && rpress_<0 && !myenergy.empty() && myvol.empty() ) {
+     236           1 :     log.printf("  reweighting simulation from temperature %f to temperature %f at constant volume \n",simtemp/getKBoltzmann(),rtemp_/getKBoltzmann() );
+     237           1 :     log.printf("  WARNING: If the simulation is performed at constant pressure add the keywords PRESSURE and VOLUME \n" );
+     238             :   }
+     239             :   // Case 2) Reweight from T to T' with P=const (isothermal-isobaric)
+     240           3 :   else if (rtemp_>=0 && press_>=0 && rpress_<0 && !myenergy.empty() && !myvol.empty() ) log.printf("  reweighting simulation from temperature %f to temperature %f at constant pressure %f \n",simtemp/getKBoltzmann(),rtemp_/getKBoltzmann(), press_ );
+     241             :   // Case 3) Reweight from P to P' with T=const (isothermal-isobaric)
+     242           2 :   else if (rtemp_<0 && press_>=0 && rpress_>=0 && myenergy.empty() && !myvol.empty() ) log.printf("  reweighting simulation from pressure %f to pressure %f at constant temperature %f\n",press_,rpress_,simtemp/getKBoltzmann() );
+     243             :   // Case 4) Reweight from T,P to T',P' (isothermal-isobaric)
+     244           1 :   else if (rtemp_>0 && press_>=0 && rpress_>=0 && !myenergy.empty() && !myvol.empty() ) log.printf("  reweighting simulation from temperature %f and pressure %f to temperature %f and pressure %f \n",simtemp/getKBoltzmann(), press_, rtemp_/getKBoltzmann(), rpress_);
+     245           0 :   else error("Combination of ENERGY, VOLUME, REWEIGHT_PRESSURE, PRESSURE and REWEIGHT_TEMP not supported. Please refer to the manual for supported combinations.");
+     246           4 : }
+     247             : 
+     248        1001 : double ReweightTemperaturePressure::getLogWeight() {
+     249        2002 :   double energy=0.0; for(unsigned i=0; i<myenergy.size(); ++i) energy+=getArgument(i);
+     250        2002 :   double volume=0.0; for(unsigned i=0; i<myvol.size(); ++i) volume+=getArgument(myenergy.size()+i);
+     251             :   // 4 possible cases
+     252             :   // Case 1) Reweight from T to T' with V=const (canonical)
+     253        1001 :   if (rtemp_>=0 && press_<0 && rpress_<0) return ((1.0/simtemp)- (1.0/rtemp_) )*energy;
+     254             :   // Case 2) Reweight from T to T' with P=const (isothermal-isobaric)
+     255        1001 :   else if (rtemp_>=0 && press_>=0 && rpress_<0)  return ((1.0/simtemp)- (1.0/rtemp_) )*energy + ((1.0/simtemp) - (1.0/rtemp_))*press_*volume;
+     256             :   // Case 3) Reweight from P to P' with T=const (isothermal-isobaric)
+     257        1001 :   else if (rtemp_<0 && press_>=0 && rpress_>=0)  return (1.0/simtemp)*(press_ - rpress_)*volume;
+     258             :   // Case 4) Reweight from T,P to T',P' (isothermal-isobaric)
+     259        1001 :   else if (rtemp_>0 && press_>=0 && rpress_>=0) return ((1.0/simtemp)- (1.0/rtemp_) )*energy + ((1.0/simtemp)*press_ - (1.0/rtemp_)*rpress_ )*volume;
+     260             :   else return 0;
+     261             : }
+     262             : 
+     263             : }
+     264             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightWham.cpp.func-sort-c.html b/coverage/bias/ReweightWham.cpp.func-sort-c.html new file mode 100644 index 000000000000..057a1175ce56 --- /dev/null +++ b/coverage/bias/ReweightWham.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightWham.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightWham.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444891.7 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightWham9clearDataEv0
_ZN4PLMD4bias12ReweightWhamC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias12ReweightWham16calculateWeightsERKj7
_ZN4PLMD4bias12ReweightWhamC1ERKNS_13ActionOptionsE12
_ZNK4PLMD4bias12ReweightWham17buildsWeightStoreEv12
_ZN4PLMD4bias12ReweightWham16registerKeywordsERNS_8KeywordsE14
_ZNK4PLMD4bias12ReweightWham9getWeightERKj2457
_ZN4PLMD4bias12ReweightWham12getLogWeightEv4224
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightWham.cpp.func.html b/coverage/bias/ReweightWham.cpp.func.html new file mode 100644 index 000000000000..ffb723ccf506 --- /dev/null +++ b/coverage/bias/ReweightWham.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightWham.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightWham.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444891.7 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias12ReweightWham12getLogWeightEv4224
_ZN4PLMD4bias12ReweightWham16calculateWeightsERKj7
_ZN4PLMD4bias12ReweightWham16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD4bias12ReweightWham9clearDataEv0
_ZN4PLMD4bias12ReweightWhamC1ERKNS_13ActionOptionsE12
_ZN4PLMD4bias12ReweightWhamC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4bias12ReweightWham17buildsWeightStoreEv12
_ZNK4PLMD4bias12ReweightWham9getWeightERKj2457
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/ReweightWham.cpp.gcov.html b/coverage/bias/ReweightWham.cpp.gcov.html new file mode 100644 index 000000000000..9b11ec55f1b7 --- /dev/null +++ b/coverage/bias/ReweightWham.cpp.gcov.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - bias/ReweightWham.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - ReweightWham.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444891.7 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ReweightBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Communicator.h"
+      25             : 
+      26             : //+PLUMEDOC REWEIGHTING REWEIGHT_WHAM
+      27             : /*
+      28             : Calculate the weights for configurations using the weighted histogram analysis method.
+      29             : 
+      30             : Suppose that you have run multiple \f$N\f$ trajectories each of which was computed by integrating a different biased Hamiltonian. We can calculate the probability of observing
+      31             : the set of configurations during the \f$N\f$ trajectories that we ran using the product of multinomial distributions shown below:
+      32             : \f[
+      33             : P( \vec{T} ) \propto \prod_{j=1}^M \prod_{k=1}^N (c_k w_{kj} p_j)^{t_{kj}}
+      34             : \label{eqn:wham1}
+      35             : \f]
+      36             : In this expression the second product runs over the biases that were used when calculating the \f$N\f$ trajectories.  The first product then runs over the
+      37             : \f$M\f$ bins in our histogram.  The \f$p_j\f$ variable that is inside this product is the quantity we wish to extract; namely, the unbiased probability of
+      38             : having a set of CV values that lie within the range for the \f$j\f$th bin.
+      39             : 
+      40             : The quantity that we can easily extract from our simulations, \f$t_{kj}\f$, however, measures the number of frames from trajectory \f$k\f$ that are inside the \f$j\f$th bin.
+      41             : To interpret this quantity we must consider the bias that acts on each of the replicas so the \f$w_{kj}\f$ term is introduced.  This quantity is calculated as:
+      42             : \f[
+      43             : w_{kj} =
+      44             : \f]
+      45             : and is essentially the factor that we have to multiply the unbiased probability of being in the bin by in order to get the probability that we would be inside this same bin in
+      46             : the \f$k\f$th of our biased simulations.  Obviously, these \f$w_{kj}\f$ values depend on the value that the CVs take and also on the particular trajectory that we are investigating
+      47             : all of which, remember, have different simulation biases.  Finally, \f$c_k\f$ is a free parameter that ensures that, for each \f$k\f$, the biased probability is normalized.
+      48             : 
+      49             : We can use the equation for the probability that was given above to find a set of values for \f$p_j\f$ that maximizes the likelihood of observing the trajectory.
+      50             : This constrained optimization must be performed using a set of Lagrange multipliers, \f$\lambda_k\f$, that ensure that each of the biased probability distributions
+      51             : are normalized, that is \f$\sum_j c_kw_{kj}p_j=1\f$.  Furthermore, as the problem is made easier if the quantity in the equation above is replaced by its logarithm
+      52             : we actually chose to minimize
+      53             : \f[
+      54             : \mathcal{L}= \sum_{j=1}^M \sum_{k=1}^N t_{kj} \ln c_k  w_{kj} p_j + \sum_k\lambda_k \left( \sum_{j=1}^N c_k w_{kj} p_j - 1 \right)
+      55             : \f]
+      56             : After some manipulations the following (WHAM) equations emerge:
+      57             : \f[
+      58             : \begin{aligned}
+      59             : p_j & \propto \frac{\sum_{k=1}^N t_{kj}}{\sum_k c_k w_{kj}} \\
+      60             : c_k & =\frac{1}{\sum_{j=1}^M w_{kj} p_j}
+      61             : \end{aligned}
+      62             : \f]
+      63             : which can be solved by computing the \f$p_j\f$ values using the first of the two equations above with an initial guess for the \f$c_k\f$ values and by then refining
+      64             : these \f$p_j\f$ values using the \f$c_k\f$ values that are obtained by inserting the \f$p_j\f$ values obtained into the second of the two equations above.
+      65             : 
+      66             : Notice that only \f$\sum_k t_{kj}\f$, which is the total number of configurations from all the replicas that enter the \f$j\f$th bin, enters the WHAM equations above.
+      67             : There is thus no need to record which replica generated each of the frames.  One can thus simply gather the trajectories from all the replicas together at the outset.
+      68             : This observation is important as it is the basis of the binless formulation of WHAM that is implemented within PLUMED.
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : 
+      75             : namespace PLMD {
+      76             : namespace bias {
+      77             : 
+      78             : class ReweightWham : public ReweightBase {
+      79             : private:
+      80             :   double thresh;
+      81             :   unsigned nreplicas;
+      82             :   unsigned maxiter;
+      83             :   bool weightsCalculated;
+      84             :   std::vector<double> stored_biases;
+      85             :   std::vector<double> final_weights;
+      86             : public:
+      87             :   static void registerKeywords(Keywords&);
+      88             :   explicit ReweightWham(const ActionOptions&ao);
+      89          12 :   bool buildsWeightStore() const override { return true; }
+      90             :   void calculateWeights( const unsigned& nframes ) override;
+      91             :   void clearData() override;
+      92             :   double getLogWeight() override;
+      93             :   double getWeight( const unsigned& iweight ) const override;
+      94             : };
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(ReweightWham,"REWEIGHT_WHAM")
+      97             : 
+      98          14 : void ReweightWham::registerKeywords(Keywords& keys ) {
+      99          14 :   ReweightBase::registerKeywords( keys ); keys.remove("ARG");
+     100          28 :   keys.add("compulsory","ARG","*.bias","the biases that must be taken into account when reweighting");
+     101          28 :   keys.add("compulsory","MAXITER","1000","maximum number of iterations for WHAM algorithm");
+     102          28 :   keys.add("compulsory","WHAMTOL","1e-10","threshold for convergence of WHAM algorithm");
+     103          14 : }
+     104             : 
+     105          12 : ReweightWham::ReweightWham(const ActionOptions&ao):
+     106             :   Action(ao),
+     107             :   ReweightBase(ao),
+     108          12 :   weightsCalculated(false)
+     109             : {
+     110          24 :   parse("MAXITER",maxiter); parse("WHAMTOL",thresh);
+     111          12 :   if(comm.Get_rank()==0) nreplicas=multi_sim_comm.Get_size();
+     112          12 :   comm.Bcast(nreplicas,0);
+     113          12 : }
+     114             : 
+     115        4224 : double ReweightWham::getLogWeight() {
+     116        4224 :   if( getStep()==0 ) return 1.0;  // This is here as first step is ignored in all analyses
+     117        4212 :   weightsCalculated=false;
+     118        8424 :   double bias=0.0; for(unsigned i=0; i<getNumberOfArguments(); ++i) bias+=getArgument(i);
+     119             : 
+     120        4212 :   std::vector<double> biases(nreplicas,0.0);
+     121        4212 :   if(comm.Get_rank()==0) multi_sim_comm.Allgather(bias,biases);
+     122        4212 :   comm.Bcast(biases,0);
+     123       29484 :   for(unsigned i=0; i<biases.size(); i++) stored_biases.push_back( biases[i] );
+     124             :   return 1.0;
+     125             : }
+     126             : 
+     127           0 : void ReweightWham::clearData() {
+     128           0 :   stored_biases.resize(0);
+     129           0 : }
+     130             : 
+     131        2457 : double ReweightWham::getWeight( const unsigned& iweight ) const {
+     132             :   plumed_dbg_assert( weightsCalculated && iweight<final_weights.size() );
+     133        2457 :   return final_weights[iweight];
+     134             : }
+     135             : 
+     136           7 : void ReweightWham::calculateWeights( const unsigned& nframes ) {
+     137           7 :   if( stored_biases.size()!=nreplicas*nframes ) error("wrong number of weights stored");
+     138             :   // Get the minimum value of the bias
+     139           7 :   double minv = *min_element(std::begin(stored_biases), std::end(stored_biases));
+     140             :   // Resize final weights array
+     141           7 :   plumed_assert( stored_biases.size()%nreplicas==0 );
+     142           7 :   final_weights.resize( stored_biases.size() / nreplicas, 1.0 );
+     143             :   // Offset and exponential of the bias
+     144           7 :   std::vector<double> expv( stored_biases.size() );
+     145       14749 :   for(unsigned i=0; i<expv.size(); ++i) expv[i] = std::exp( (-stored_biases[i]+minv) / simtemp );
+     146             :   // Initialize Z
+     147           7 :   std::vector<double> Z( nreplicas, 1.0 ), oldZ( nreplicas );
+     148             :   // Now the iterative loop to calculate the WHAM weights
+     149        2674 :   for(unsigned iter=0; iter<maxiter; ++iter) {
+     150             :     // Store Z
+     151       18718 :     for(unsigned j=0; j<Z.size(); ++j) oldZ[j]=Z[j];
+     152             :     // Recompute weights
+     153             :     double norm=0;
+     154      941248 :     for(unsigned j=0; j<final_weights.size(); ++j) {
+     155             :       double ew=0;
+     156     6570018 :       for(unsigned k=0; k<Z.size(); ++k) ew += expv[j*Z.size()+k]  / Z[k];
+     157      938574 :       final_weights[j] = 1.0 / ew; norm += final_weights[j];
+     158             :     }
+     159             :     // Normalize weights
+     160      941248 :     for(unsigned j=0; j<final_weights.size(); ++j) final_weights[j] /= norm;
+     161             :     // Recompute Z
+     162       18718 :     for(unsigned j=0; j<Z.size(); ++j) Z[j] = 0.0;
+     163      941248 :     for(unsigned j=0; j<final_weights.size(); ++j) {
+     164     6570018 :       for(unsigned k=0; k<Z.size(); ++k) Z[k] += final_weights[j]*expv[j*Z.size()+k];
+     165             :     }
+     166             :     // Normalize Z and compute change in Z
+     167       18718 :     double change=0; norm=0; for(unsigned k=0; k<Z.size(); ++k) norm+=Z[k];
+     168       18718 :     for(unsigned k=0; k<Z.size(); ++k) {
+     169       16044 :       Z[k] /= norm; double d = std::log( Z[k] / oldZ[k] ); change += d*d;
+     170             :     }
+     171        2681 :     if( change<thresh ) { weightsCalculated=true; return; }
+     172             :   }
+     173           0 :   error("Too many iterations in WHAM" );
+     174             : }
+     175             : 
+     176             : }
+     177             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/UWalls.cpp.func-sort-c.html b/coverage/bias/UWalls.cpp.func-sort-c.html new file mode 100644 index 000000000000..c96ec4d0f0c3 --- /dev/null +++ b/coverage/bias/UWalls.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/UWalls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - UWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6UWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD4bias6UWallsC1ERKNS_13ActionOptionsE17
_ZN4PLMD4bias6UWalls16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD4bias6UWalls9calculateEv28015
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/UWalls.cpp.func.html b/coverage/bias/UWalls.cpp.func.html new file mode 100644 index 000000000000..722659a05862 --- /dev/null +++ b/coverage/bias/UWalls.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - bias/UWalls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - UWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4bias6UWalls16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD4bias6UWalls9calculateEv28015
_ZN4PLMD4bias6UWallsC1ERKNS_13ActionOptionsE17
_ZN4PLMD4bias6UWallsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/UWalls.cpp.gcov.html b/coverage/bias/UWalls.cpp.gcov.html new file mode 100644 index 000000000000..109b93a35616 --- /dev/null +++ b/coverage/bias/UWalls.cpp.gcov.html @@ -0,0 +1,224 @@ + + + + + + + + LCOV - plumed test coverage - bias/UWalls.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - bias - UWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Bias.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace bias {
+      27             : 
+      28             : //+PLUMEDOC BIAS UPPER_WALLS
+      29             : /*
+      30             : Defines a wall for the value of one or more collective variables,
+      31             :  which limits the region of the phase space accessible during the simulation.
+      32             : 
+      33             : The restraining potential starts acting on the system when the value of the CV is greater
+      34             : (in the case of UPPER_WALLS) or lower (in the case of LOWER_WALLS) than a certain limit \f$a_i\f$ (AT)
+      35             : minus an offset \f$o_i\f$ (OFFSET).
+      36             : The expression for the bias due to the wall is given by:
+      37             : 
+      38             : \f$
+      39             :   \sum_i {k_i}((x_i-a_i+o_i)/s_i)^e_i
+      40             : \f$
+      41             : 
+      42             : \f$k_i\f$ (KAPPA) is an energy constant in internal unit of the code, \f$s_i\f$ (EPS) a rescaling factor and
+      43             : \f$e_i\f$ (EXP) the exponent determining the power law. By default: EXP = 2, EPS = 1.0, OFFSET = 0.
+      44             : 
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : The following input tells plumed to add both a lower and an upper walls on the distance
+      49             : between atoms 3 and 5 and the distance between atoms 2 and 4. The lower and upper limits
+      50             : are defined at different values. The strength of the walls is the same for the four cases.
+      51             : It also tells plumed to print the energy of the walls.
+      52             : \plumedfile
+      53             : DISTANCE ATOMS=3,5 LABEL=d1
+      54             : DISTANCE ATOMS=2,4 LABEL=d2
+      55             : UPPER_WALLS ARG=d1,d2 AT=1.0,1.5 KAPPA=150.0,150.0 EXP=2,2 EPS=1,1 OFFSET=0,0 LABEL=uwall
+      56             : LOWER_WALLS ARG=d1,d2 AT=0.0,1.0 KAPPA=150.0,150.0 EXP=2,2 EPS=1,1 OFFSET=0,0 LABEL=lwall
+      57             : PRINT ARG=uwall.bias,lwall.bias
+      58             : \endplumedfile
+      59             : 
+      60             : */
+      61             : //+ENDPLUMEDOC
+      62             : 
+      63             : class UWalls : public Bias {
+      64             :   std::vector<double> at;
+      65             :   std::vector<double> kappa;
+      66             :   std::vector<double> exp;
+      67             :   std::vector<double> eps;
+      68             :   std::vector<double> offset;
+      69             : public:
+      70             :   explicit UWalls(const ActionOptions&);
+      71             :   void calculate() override;
+      72             :   static void registerKeywords(Keywords& keys);
+      73             : };
+      74             : 
+      75             : PLUMED_REGISTER_ACTION(UWalls,"UPPER_WALLS")
+      76             : 
+      77          19 : void UWalls::registerKeywords(Keywords& keys) {
+      78          19 :   Bias::registerKeywords(keys);
+      79          19 :   keys.use("ARG");
+      80          38 :   keys.add("compulsory","AT","the positions of the wall. The a_i in the expression for a wall.");
+      81          38 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      82          38 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      83          38 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      84          38 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      85          38 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential");
+      86          19 : }
+      87             : 
+      88          17 : UWalls::UWalls(const ActionOptions&ao):
+      89             :   PLUMED_BIAS_INIT(ao),
+      90          34 :   at(getNumberOfArguments(),0),
+      91          17 :   kappa(getNumberOfArguments(),0.0),
+      92          17 :   exp(getNumberOfArguments(),2.0),
+      93          17 :   eps(getNumberOfArguments(),1.0),
+      94          34 :   offset(getNumberOfArguments(),0.0)
+      95             : {
+      96             :   // Note : the sizes of these vectors are checked automatically by parseVector
+      97          17 :   parseVector("OFFSET",offset);
+      98          17 :   parseVector("EPS",eps);
+      99          17 :   parseVector("EXP",exp);
+     100          17 :   parseVector("KAPPA",kappa);
+     101          17 :   parseVector("AT",at);
+     102          17 :   checkRead();
+     103             : 
+     104          17 :   log.printf("  at");
+     105          34 :   for(unsigned i=0; i<at.size(); i++) log.printf(" %f",at[i]);
+     106          17 :   log.printf("\n");
+     107          17 :   log.printf("  with an offset");
+     108          34 :   for(unsigned i=0; i<offset.size(); i++) log.printf(" %f",offset[i]);
+     109          17 :   log.printf("\n");
+     110          17 :   log.printf("  with force constant");
+     111          34 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     112          17 :   log.printf("\n");
+     113          17 :   log.printf("  and exponent");
+     114          34 :   for(unsigned i=0; i<exp.size(); i++) log.printf(" %f",exp[i]);
+     115          17 :   log.printf("\n");
+     116          17 :   log.printf("  rescaled");
+     117          34 :   for(unsigned i=0; i<eps.size(); i++) log.printf(" %f",eps[i]);
+     118          17 :   log.printf("\n");
+     119             : 
+     120          34 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     121          17 : }
+     122             : 
+     123       28015 : void UWalls::calculate() {
+     124             :   double ene=0.0;
+     125             :   double totf2=0.0;
+     126       56030 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     127             :     double f = 0.0;
+     128       28015 :     const double cv=difference(i,at[i],getArgument(i));
+     129       28015 :     const double off=offset[i];
+     130       28015 :     const double epsilon=eps[i];
+     131       28015 :     const double uscale = (cv+off)/epsilon;
+     132       28015 :     if( uscale > 0.) {
+     133           6 :       const double k=kappa[i];
+     134           6 :       const double exponent=exp[i];
+     135           6 :       double power = pow( uscale, exponent );
+     136           6 :       f = -( k / epsilon ) * exponent * power / uscale;
+     137           6 :       ene += k * power;
+     138           6 :       totf2 += f * f;
+     139             :     }
+     140       28015 :     setOutputForce(i,f);
+     141             :   }
+     142       28015 :   setBias(ene);
+     143       28015 :   getPntrToComponent("force2")->set(totf2);
+     144       28015 : }
+     145             : 
+     146             : }
+     147             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/index-sort-f.html b/coverage/bias/index-sort-f.html new file mode 100644 index 000000000000..94d9b6c89473 --- /dev/null +++ b/coverage/bias/index-sort-f.html @@ -0,0 +1,274 @@ + + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2381260191.5 %
Date:2024-02-22 21:58:45Functions:10012480.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ReweightBase.h +
33.3%33.3%
+
33.3 %2 / 633.3 %2 / 6
LWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
ReweightMetad.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
Restraint.cpp +
100.0%
+
100.0 %41 / 4175.0 %3 / 4
ReweightBase.cpp +
100.0%
+
100.0 %18 / 1875.0 %3 / 4
ABMD.cpp +
100.0%
+
100.0 %62 / 6275.0 %3 / 4
Bias.cpp +
100.0%
+
100.0 %37 / 3775.0 %3 / 4
ReweightTemperaturePressure.cpp +
97.8%97.8%
+
97.8 %45 / 4675.0 %3 / 4
External.cpp +
100.0%
+
100.0 %40 / 4075.0 %3 / 4
UWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
ReweightBias.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
BiasValue.cpp +
100.0%
+
100.0 %19 / 1975.0 %3 / 4
MovingRestraint.cpp +
100.0%
+
100.0 %101 / 10175.0 %3 / 4
ReweightWham.cpp +
91.7%91.7%
+
91.7 %44 / 4875.0 %6 / 8
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %90 / 9180.0 %4 / 5
PBMetaD.cpp +
88.3%88.3%
+
88.3 %566 / 64186.7 %13 / 15
MaxEnt.cpp +
96.6%96.6%
+
96.6 %225 / 23390.9 %10 / 11
MetaD.cpp +
88.2%88.2%
+
88.2 %950 / 107792.9 %26 / 28
Bias.h +
100.0%
+
100.0 %9 / 9100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/index-sort-l.html b/coverage/bias/index-sort-l.html new file mode 100644 index 000000000000..ebea8c2bbfde --- /dev/null +++ b/coverage/bias/index-sort-l.html @@ -0,0 +1,274 @@ + + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2381260191.5 %
Date:2024-02-22 21:58:45Functions:10012480.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ReweightBase.h +
33.3%33.3%
+
33.3 %2 / 633.3 %2 / 6
PBMetaD.cpp +
88.3%88.3%
+
88.3 %566 / 64186.7 %13 / 15
MetaD.cpp +
88.2%88.2%
+
88.2 %950 / 107792.9 %26 / 28
ReweightWham.cpp +
91.7%91.7%
+
91.7 %44 / 4875.0 %6 / 8
MaxEnt.cpp +
96.6%96.6%
+
96.6 %225 / 23390.9 %10 / 11
ReweightTemperaturePressure.cpp +
97.8%97.8%
+
97.8 %45 / 4675.0 %3 / 4
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %90 / 9180.0 %4 / 5
Bias.h +
100.0%
+
100.0 %9 / 9100.0 %3 / 3
ReweightMetad.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
ReweightBias.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
ReweightBase.cpp +
100.0%
+
100.0 %18 / 1875.0 %3 / 4
BiasValue.cpp +
100.0%
+
100.0 %19 / 1975.0 %3 / 4
Bias.cpp +
100.0%
+
100.0 %37 / 3775.0 %3 / 4
External.cpp +
100.0%
+
100.0 %40 / 4075.0 %3 / 4
Restraint.cpp +
100.0%
+
100.0 %41 / 4175.0 %3 / 4
LWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
UWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
ABMD.cpp +
100.0%
+
100.0 %62 / 6275.0 %3 / 4
MovingRestraint.cpp +
100.0%
+
100.0 %101 / 10175.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/bias/index.html b/coverage/bias/index.html new file mode 100644 index 000000000000..88d7ed191e71 --- /dev/null +++ b/coverage/bias/index.html @@ -0,0 +1,274 @@ + + + + + + + + LCOV - plumed test coverage - bias + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - biasHitTotalCoverage
Test:plumed test coverageLines:2381260191.5 %
Date:2024-02-22 21:58:45Functions:10012480.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ABMD.cpp +
100.0%
+
100.0 %62 / 6275.0 %3 / 4
Bias.cpp +
100.0%
+
100.0 %37 / 3775.0 %3 / 4
Bias.h +
100.0%
+
100.0 %9 / 9100.0 %3 / 3
BiasValue.cpp +
100.0%
+
100.0 %19 / 1975.0 %3 / 4
ExtendedLagrangian.cpp +
98.9%98.9%
+
98.9 %90 / 9180.0 %4 / 5
External.cpp +
100.0%
+
100.0 %40 / 4075.0 %3 / 4
LWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
MaxEnt.cpp +
96.6%96.6%
+
96.6 %225 / 23390.9 %10 / 11
MetaD.cpp +
88.2%88.2%
+
88.2 %950 / 107792.9 %26 / 28
MovingRestraint.cpp +
100.0%
+
100.0 %101 / 10175.0 %3 / 4
PBMetaD.cpp +
88.3%88.3%
+
88.3 %566 / 64186.7 %13 / 15
Restraint.cpp +
100.0%
+
100.0 %41 / 4175.0 %3 / 4
ReweightBase.cpp +
100.0%
+
100.0 %18 / 1875.0 %3 / 4
ReweightBase.h +
33.3%33.3%
+
33.3 %2 / 633.3 %2 / 6
ReweightBias.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
ReweightMetad.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
ReweightTemperaturePressure.cpp +
97.8%97.8%
+
97.8 %45 / 4675.0 %3 / 4
ReweightWham.cpp +
91.7%91.7%
+
91.7 %44 / 4875.0 %6 / 8
UWalls.cpp +
100.0%
+
100.0 %56 / 5675.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Benchmark.cpp.func-sort-c.html b/coverage/cltools/Benchmark.cpp.func-sort-c.html new file mode 100644 index 000000000000..fe1702580b6a --- /dev/null +++ b/coverage/cltools/Benchmark.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Benchmark.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Benchmark.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:157220.8 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_118SignalHandlerGuardC2EiPFviE0
_ZN4PLMD7cltools9Benchmark4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZZN4PLMD7cltools9Benchmark4mainEP8_IO_FILES3_RNS_12CommunicatorEENKUlvE_clEv0
signalHandler0
_ZN4PLMD7cltools12_GLOBAL__N_119BenchmarkRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools9BenchmarkC2ERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools9Benchmark11descriptionB5cxx11Ev4
_ZN4PLMD7cltools12_GLOBAL__N_119BenchmarkRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_119BenchmarkRegisterMeD2Ev4187
_ZN4PLMD7cltools9Benchmark16registerKeywordsERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Benchmark.cpp.func.html b/coverage/cltools/Benchmark.cpp.func.html new file mode 100644 index 000000000000..86946320bc4b --- /dev/null +++ b/coverage/cltools/Benchmark.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Benchmark.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Benchmark.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:157220.8 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_118SignalHandlerGuardC2EiPFviE0
_ZN4PLMD7cltools12_GLOBAL__N_119BenchmarkRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_119BenchmarkRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_119BenchmarkRegisterMeD2Ev4187
_ZN4PLMD7cltools9Benchmark16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools9Benchmark4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools9BenchmarkC2ERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools9Benchmark11descriptionB5cxx11Ev4
_ZZN4PLMD7cltools9Benchmark4mainEP8_IO_FILES3_RNS_12CommunicatorEENKUlvE_clEv0
signalHandler0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Benchmark.cpp.gcov.html b/coverage/cltools/Benchmark.cpp.gcov.html new file mode 100644 index 000000000000..c830e04f90e6 --- /dev/null +++ b/coverage/cltools/Benchmark.cpp.gcov.html @@ -0,0 +1,270 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Benchmark.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Benchmark.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:157220.8 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2019-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Communicator.h"
+      25             : #include "tools/Tools.h"
+      26             : #include "config/Config.h"
+      27             : #include "tools/PlumedHandle.h"
+      28             : #include <cstdio>
+      29             : #include <string>
+      30             : #include <vector>
+      31             : #include <iostream>
+      32             : #include <fstream>
+      33             : #include <atomic>
+      34             : #include <csignal>
+      35             : #include <cstdio>
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace cltools {
+      39             : 
+      40             : //+PLUMEDOC TOOLS benchmark
+      41             : /*
+      42             : benchmark is a lightweight reimplementation of driver focused on running benchmarks
+      43             : 
+      44             : The main difference wrt driver is that it generates a trajectory in memory rather than reading it
+      45             : from a file. This allows to better time the overhead of the plumed library, without including
+      46             : the time needed to read the trajectory.
+      47             : 
+      48             : As of now it does not test cases where atoms are scattered over processors (TODO).
+      49             : 
+      50             : It is also possible to load a separate version of the plumed kernel. This enables running
+      51             : benchmarks agaist previous plumed versions
+      52             : 
+      53             : \par Examples
+      54             : 
+      55             : \verbatim
+      56             : plumed benchmark --plumed plumed.dat
+      57             : \endverbatim
+      58             : 
+      59             : \verbatim
+      60             : plumed benchmark --plumed plumed.dat --kernel /path/to/libplumedKernel.so
+      61             : \endverbatim
+      62             : 
+      63             : */
+      64             : //+ENDPLUMEDOC
+      65             : 
+      66             : namespace {
+      67             : 
+      68             : std::atomic<bool> signalReceived(false);
+      69             : 
+      70             : class SignalHandlerGuard {
+      71             : public:
+      72           0 :   SignalHandlerGuard(int signal, void (*newHandler)(int)) : signal_(signal) {
+      73             :     // Store the current handler before setting the new one
+      74           0 :     prevHandler_ = std::signal(signal, newHandler);
+      75           0 :     if (prevHandler_ == SIG_ERR) {
+      76           0 :       throw std::runtime_error("Failed to set signal handler");
+      77             :     }
+      78           0 :   }
+      79             : 
+      80             :   ~SignalHandlerGuard() {
+      81             :     // Restore the previous handler upon destruction
+      82           0 :     std::signal(signal_, prevHandler_);
+      83           0 :   }
+      84             : 
+      85             :   // Delete copy constructor and assignment operator to prevent copying
+      86             :   SignalHandlerGuard(const SignalHandlerGuard&) = delete;
+      87             :   SignalHandlerGuard& operator=(const SignalHandlerGuard&) = delete;
+      88             : 
+      89             : private:
+      90             :   int signal_;
+      91             :   void (*prevHandler_)(int);
+      92             : };
+      93             : 
+      94           0 : extern "C" void signalHandler(int signal) {
+      95           0 :   if (signal == SIGINT) {
+      96             :     signalReceived.store(true);
+      97           0 :     fprintf(stderr, "Signal handler called\n");
+      98             :   }
+      99           0 : }
+     100             : 
+     101             : }
+     102             : 
+     103             : class Benchmark:
+     104             :   public CLTool
+     105             : {
+     106             : public:
+     107             :   static void registerKeywords( Keywords& keys );
+     108             :   explicit Benchmark(const CLToolOptions& co );
+     109             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+     110           4 :   std::string description()const override {
+     111           4 :     return "run a calculation with a fixed trajectory to find bottlenecks in PLUMED";
+     112             :   }
+     113             : };
+     114             : 
+     115       12565 : PLUMED_REGISTER_CLTOOL(Benchmark,"benchmark")
+     116             : 
+     117        4187 : void Benchmark::registerKeywords( Keywords& keys ) {
+     118        4187 :   CLTool::registerKeywords( keys );
+     119        8374 :   keys.add("compulsory","--plumed","plumed.dat","convert the input in this file to the html manual");
+     120        8374 :   keys.add("compulsory","--natoms","100000","the number of atoms to use for the simulation");
+     121        8374 :   keys.add("compulsory","--nsteps","2000","number of steps of MD to perform (-1 means forever)");
+     122        8374 :   keys.add("optional","--kernel","path to kernel (default=current kernel)");
+     123        8374 :   keys.addFlag("--shuffled",false,"reshuffle atoms");
+     124        4187 : }
+     125             : 
+     126           4 : Benchmark::Benchmark(const CLToolOptions& co ):
+     127           4 :   CLTool(co)
+     128             : {
+     129           4 :   inputdata=commandline;
+     130           4 : }
+     131             : 
+     132           0 : int Benchmark::main(FILE* in, FILE*out,Communicator& pc) {
+     133           0 :   PlumedHandle p([&]() {
+     134             :     std::string kernel;
+     135           0 :     parse("--kernel",kernel);
+     136           0 :     if(kernel.length()>0) return PlumedHandle::dlopen(kernel.c_str());
+     137           0 :     else return PlumedHandle();
+     138           0 :   }());
+     139             : 
+     140           0 :   if(Communicator::plumedHasMPI()) p.cmd("setMPIComm",&pc.Get_comm());
+     141           0 :   p.cmd("setRealPrecision",(int)sizeof(double));
+     142           0 :   p.cmd("setMDLengthUnits",1.0);
+     143           0 :   p.cmd("setMDChargeUnits",1.0);
+     144           0 :   p.cmd("setMDMassUnits",1.0);
+     145           0 :   p.cmd("setMDEngine","benchmarks");
+     146           0 :   p.cmd("setTimestep",1.0);
+     147           0 :   std::string plumedFile; parse("--plumed",plumedFile);
+     148           0 :   p.cmd("setPlumedDat",plumedFile.c_str());
+     149           0 :   p.cmd("setLog",out);
+     150             : 
+     151           0 :   int nf; parse("--nsteps",nf);
+     152           0 :   unsigned natoms; parse("--natoms",natoms);
+     153           0 :   p.cmd("setNatoms",natoms); p.cmd("init");
+     154           0 :   std::vector<double> cell( 9 ), virial( 9 );
+     155           0 :   std::vector<Vector> pos( natoms ), forces( natoms );
+     156           0 :   std::vector<double> masses( natoms, 1 ), charges( natoms, 0 );
+     157             : 
+     158           0 :   bool shuffled=false;
+     159           0 :   parseFlag("--shuffled",shuffled);
+     160             : 
+     161             : 
+     162           0 :   SignalHandlerGuard sigIntGuard(SIGINT, signalHandler);
+     163             : 
+     164             :   std::vector<int> shuffled_indexes;
+     165             : 
+     166           0 :   if(shuffled) {
+     167           0 :     shuffled_indexes.resize(natoms);
+     168           0 :     for(unsigned i=0; i<natoms; i++) shuffled_indexes[i]=natoms-i-1;
+     169             :   }
+     170             : 
+     171           0 :   int plumedStopCondition=0;
+     172           0 :   for(int step=0; nf<0 || step<nf; ++step) {
+     173           0 :     for(unsigned j=0; j<natoms; ++j) pos[j] = Vector(step*j, step*j+1, step*j+2);
+     174           0 :     p.cmd("setStep",step);
+     175           0 :     p.cmd("setStopFlag",&plumedStopCondition);
+     176           0 :     p.cmd("setForces",&forces[0][0],3*natoms);
+     177           0 :     p.cmd("setBox",&cell[0],9);
+     178           0 :     p.cmd("setVirial",&virial[0],9);
+     179           0 :     p.cmd("setPositions",&pos[0][0],3*natoms);
+     180           0 :     p.cmd("setMasses",&masses[0],natoms);
+     181           0 :     p.cmd("setCharges",&charges[0],natoms);
+     182           0 :     if(shuffled) {
+     183           0 :       p.cmd("setAtomsNlocal",natoms);
+     184           0 :       p.cmd("setAtomsGatindex",&shuffled_indexes[0],shuffled_indexes.size());
+     185             :     }
+     186           0 :     p.cmd("calc");
+     187           0 :     if(plumedStopCondition || signalReceived.load()) break;
+     188             :   }
+     189           0 :   return 0;
+     190           0 : }
+     191             : 
+     192             : } // End of namespace
+     193             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Completion.cpp.func-sort-c.html b/coverage/cltools/Completion.cpp.func-sort-c.html new file mode 100644 index 000000000000..3f2de13699a0 --- /dev/null +++ b/coverage/cltools/Completion.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Completion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Completion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:103627.8 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools10Completion4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools10CompletionC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMe6createERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools10Completion11descriptionB5cxx11Ev4
_ZN4PLMD7cltools10Completion16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Completion.cpp.func.html b/coverage/cltools/Completion.cpp.func.html new file mode 100644 index 000000000000..05fe1e9d9332 --- /dev/null +++ b/coverage/cltools/Completion.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Completion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Completion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:103627.8 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools10Completion16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools10Completion4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools10CompletionC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_120CompletionRegisterMeD2Ev4187
_ZNK4PLMD7cltools10Completion11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Completion.cpp.gcov.html b/coverage/cltools/Completion.cpp.gcov.html new file mode 100644 index 000000000000..9d8dac602167 --- /dev/null +++ b/coverage/cltools/Completion.cpp.gcov.html @@ -0,0 +1,212 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Completion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Completion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:103627.8 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "config/Config.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include <cstdio>
+      28             : #include <string>
+      29             : #include <vector>
+      30             : #include <iostream>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace cltools {
+      34             : 
+      35             : //+PLUMEDOC TOOLS completion
+      36             : /*
+      37             : Dumps the body of a bash function to be used for auto completion.
+      38             : 
+      39             : Users will typically not need this command.
+      40             : See more at \ref BashAutocompletion
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : \verbatim
+      45             : plumed completion
+      46             : \endverbatim
+      47             : 
+      48             : 
+      49             : */
+      50             : //+ENDPLUMEDOC
+      51             : 
+      52             : class Completion:
+      53             :   public CLTool
+      54             : {
+      55             : public:
+      56             :   static void registerKeywords( Keywords& keys );
+      57             :   explicit Completion(const CLToolOptions& co );
+      58             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+      59           4 :   std::string description()const override {
+      60           4 :     return "dump a function usable for programmable completion";
+      61             :   }
+      62             : };
+      63             : 
+      64       12565 : PLUMED_REGISTER_CLTOOL(Completion,"completion")
+      65             : 
+      66        4187 : void Completion::registerKeywords( Keywords& keys ) {
+      67        4187 :   CLTool::registerKeywords( keys );
+      68        4187 : }
+      69             : 
+      70           4 : Completion::Completion(const CLToolOptions& co ):
+      71           4 :   CLTool(co)
+      72             : {
+      73           4 :   inputdata=commandline;
+      74           4 : }
+      75             : 
+      76           0 : int Completion::main(FILE* in, FILE*out,Communicator& pc) {
+      77             :   static const char completion [] = {
+      78             : #include "completion.xxd"
+      79             : // cppcheck-suppress syntaxError
+      80             :     , 0x00
+      81             :   };
+      82             :   std::fprintf(out,"local cmds=\"help -h --help");
+      83             : // Build list of available C++ tools:
+      84           0 :   std::vector<std::string> availableCxx=cltoolRegister().list();
+      85             : // Build list of available shell tools:
+      86           0 :   std::vector<std::string> tmp=Tools::ls(std::string(config::getPlumedRoot()+"/scripts"));
+      87           0 :   for(unsigned j=0; j<tmp.size(); ++j) {
+      88           0 :     size_t ff=tmp[j].find(".sh");
+      89           0 :     if(ff==std::string::npos) tmp[j].erase();
+      90           0 :     else                 tmp[j].erase(ff);
+      91             :   }
+      92           0 :   for(unsigned j=0; j<availableCxx.size(); j++) std::fprintf(out," %s",availableCxx[j].c_str());
+      93           0 :   for(unsigned j=0; j<tmp.size(); ++j) if(tmp[j].length()>0) std::fprintf(out," %s",tmp[j].c_str());
+      94             :   std::fprintf(out,"\"\n");
+      95             : 
+      96           0 :   for(unsigned j=0; j<availableCxx.size(); j++) {
+      97           0 :     std::string s=availableCxx[j];
+      98             : // handle - sign (convert to underscore)
+      99             :     for(;;) {
+     100           0 :       size_t n=s.find("-");
+     101           0 :       if(n==std::string::npos) break;
+     102           0 :       s[n]='_';
+     103           0 :     }
+     104             :     std::fprintf(out,"local cmd_keys_%s=\"",s.c_str());
+     105           0 :     std::vector<std::string> keys=cltoolRegister().getKeys(availableCxx[j]);
+     106           0 :     for(unsigned k=0; k<keys.size(); k++) {
+     107             : // handle --help/-h
+     108           0 :       std::string s=keys[k];
+     109             :       for(;;) {
+     110           0 :         size_t n=s.find("/");
+     111           0 :         if(n==std::string::npos) break;
+     112           0 :         s[n]=' ';
+     113           0 :       }
+     114             :       std::fprintf(out," %s",s.c_str());
+     115             :     }
+     116             :     std::fprintf(out,"\"\n");
+     117           0 :   }
+     118             : 
+     119             :   std::fprintf(out,"%s\n",completion);
+     120           0 :   std::string name=config::getPlumedProgramName();
+     121             : 
+     122             :   std::fprintf(out,
+     123             :                "############################################\n"
+     124             :                "## ADD THESE COMMANDS TO YOUR .bashrc FILE:\n"
+     125             :                "############################################\n"
+     126             :                "# _%s() { eval \"$(%s --no-mpi completion 2>/dev/null)\";}\n"
+     127             :                "# complete -F _%s -o default %s\n"
+     128             :                "############################################\n",
+     129             :                name.c_str(),name.c_str(),name.c_str(),name.c_str());
+     130             : 
+     131           0 :   return 0;
+     132           0 : }
+     133             : 
+     134             : } // End of namespace
+     135             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Driver.cpp.func-sort-c.html b/coverage/cltools/Driver.cpp.func-sort-c.html new file mode 100644 index 000000000000..e584515ca465 --- /dev/null +++ b/coverage/cltools/Driver.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Driver.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Driver.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55261689.6 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools6DriverIfE28evaluateNumericalDerivativesERKxRNS_10PlumedMainERKSt6vectorIfSaIfEESB_SB_RS9_RKdSC_0
_ZN4PLMD7cltools6DriverIfE4mainEP8_IO_FILES4_RNS_12CommunicatorE0
_ZZN4PLMD7cltools6DriverIfE4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlPvE0_clES7_0
_ZN4PLMD7cltools6DriverIfEC2ERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools6DriverIdE11descriptionB5cxx11Ev4
_ZN4PLMD7cltools6DriverIdE28evaluateNumericalDerivativesERKxRNS_10PlumedMainERKSt6vectorIdSaIdEESB_SB_RS9_RKdSC_25
_ZZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlPvE0_clES7_251
_ZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorE808
_ZN4PLMD7cltools6DriverIdEC2ERKNS_13CLToolOptionsE812
_ZN4PLMD7cltools6DriverIdE16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools6DriverIfE16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltoolsL11register_cbEPvPNS_7molfile11vmdplugin_tE75366
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Driver.cpp.func.html b/coverage/cltools/Driver.cpp.func.html new file mode 100644 index 000000000000..246d14edb578 --- /dev/null +++ b/coverage/cltools/Driver.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Driver.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Driver.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55261689.6 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools6DriverIdE16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools6DriverIdE28evaluateNumericalDerivativesERKxRNS_10PlumedMainERKSt6vectorIdSaIdEESB_SB_RS9_RKdSC_25
_ZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorE808
_ZN4PLMD7cltools6DriverIdEC2ERKNS_13CLToolOptionsE812
_ZN4PLMD7cltools6DriverIfE16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools6DriverIfE28evaluateNumericalDerivativesERKxRNS_10PlumedMainERKSt6vectorIfSaIfEESB_SB_RS9_RKdSC_0
_ZN4PLMD7cltools6DriverIfE4mainEP8_IO_FILES4_RNS_12CommunicatorE0
_ZN4PLMD7cltools6DriverIfEC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltoolsL11register_cbEPvPNS_7molfile11vmdplugin_tE75366
_ZNK4PLMD7cltools6DriverIdE11descriptionB5cxx11Ev4
_ZZN4PLMD7cltools6DriverIdE4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlPvE0_clES7_251
_ZZN4PLMD7cltools6DriverIfE4mainEP8_IO_FILES4_RNS_12CommunicatorEENKUlPvE0_clES7_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Driver.cpp.gcov.html b/coverage/cltools/Driver.cpp.gcov.html new file mode 100644 index 000000000000..7da102a58460 --- /dev/null +++ b/coverage/cltools/Driver.cpp.gcov.html @@ -0,0 +1,1256 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Driver.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Driver.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55261689.6 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "core/ActionWithValue.h"
+      28             : #include "core/ActionShortcut.h"
+      29             : #include "tools/Communicator.h"
+      30             : #include "tools/Random.h"
+      31             : #include "tools/Pbc.h"
+      32             : #include <cstdio>
+      33             : #include <cstring>
+      34             : #include <vector>
+      35             : #include <map>
+      36             : #include <memory>
+      37             : #include "tools/Units.h"
+      38             : #include "tools/PDB.h"
+      39             : #include "tools/FileBase.h"
+      40             : #include "tools/IFile.h"
+      41             : #include "xdrfile/xdrfile_trr.h"
+      42             : #include "xdrfile/xdrfile_xtc.h"
+      43             : 
+      44             : 
+      45             : // when using molfile plugin
+      46             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+      47             : #ifndef __PLUMED_HAS_EXTERNAL_MOLFILE_PLUGINS
+      48             : /* Use the internal ones. Alternatively:
+      49             :  *    ifeq (,$(findstring __PLUMED_HAS_EXTERNAL_MOLFILE_PLUGINS,$(CPPFLAGS)))
+      50             :  *    CPPFLAGS+=-I../molfile
+      51             :  */
+      52             : #include "molfile/libmolfile_plugin.h"
+      53             : #include "molfile/molfile_plugin.h"
+      54             : using namespace PLMD::molfile;
+      55             : #else
+      56             : #include <libmolfile_plugin.h>
+      57             : #include <molfile_plugin.h>
+      58             : #endif
+      59             : #endif
+      60             : 
+      61             : namespace PLMD {
+      62             : namespace cltools {
+      63             : 
+      64             : //+PLUMEDOC TOOLS driver-float
+      65             : /*
+      66             : Equivalent to \ref driver, but using single precision reals.
+      67             : 
+      68             : The purpose of this tool is just to test what PLUMED does when linked from
+      69             : a single precision code.
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : \verbatim
+      74             : plumed driver-float --plumed plumed.dat --ixyz trajectory.xyz
+      75             : \endverbatim
+      76             : 
+      77             : See also examples in \ref driver
+      78             : 
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : //
+      82             : 
+      83             : 
+      84             : //+PLUMEDOC TOOLS driver
+      85             : /*
+      86             : driver is a tool that allows one to to use plumed to post-process an existing trajectory.
+      87             : 
+      88             : The input to driver is specified using the command line arguments described below.
+      89             : 
+      90             : In addition, you can use the special \subpage READ command inside your plumed input
+      91             : to read in colvar files that were generated during your MD simulation.  The values
+      92             : read in can then be treated like calculated colvars.
+      93             : 
+      94             : \warning
+      95             : Notice that by default the driver has no knowledge about the masses and charges
+      96             : of your atoms! Thus, if you want to compute quantities depending charges (e.g. \ref DHENERGY)
+      97             : or masses (e.g. \ref COM) you should pass the proper information to the driver.
+      98             : You can do it either with the --pdb option or with the --mc option. The latter
+      99             : will read a file produced by \ref DUMPMASSCHARGE .
+     100             : 
+     101             : 
+     102             : \par Examples
+     103             : 
+     104             : The following command tells plumed to post process the trajectory contained in `trajectory.xyz`
+     105             :  by performing the actions described in the input file `plumed.dat`.  If an action that takes the
+     106             : stride keyword is given a stride equal to \f$n\f$ then it will be performed only on every \f$n\f$th
+     107             : frames in the trajectory file.
+     108             : \verbatim
+     109             : plumed driver --plumed plumed.dat --ixyz trajectory.xyz
+     110             : \endverbatim
+     111             : 
+     112             : Notice that `xyz` files are expected to be in internal PLUMED units, that is by default nm.
+     113             : You can change this behavior by using the `--length-units` option:
+     114             : \verbatim
+     115             : plumed driver --plumed plumed.dat --ixyz trajectory.xyz --length-units A
+     116             : \endverbatim
+     117             : The strings accepted by the `--length-units` options are the same ones accepted by the \ref UNITS action.
+     118             : Other file formats typically have their default coordinates (e.g., `gro` files are always in nm)
+     119             : and it thus should not be necessary to use the `--length-units` option. Additionally,
+     120             : consider that the units used by the `driver` might be different by the units used in the PLUMED input
+     121             : file `plumed.dat`. For instance consider the command:
+     122             : \verbatim
+     123             : plumed driver --plumed plumed.dat --ixyz trajectory.xyz --length-units A
+     124             : \endverbatim
+     125             : where `plumed.dat` is
+     126             : \plumedfile
+     127             : # no explicit UNITS action here
+     128             : d: DISTANCE ATOMS=1,2
+     129             : PRINT ARG=d FILE=colvar
+     130             : \endplumedfile
+     131             : In this case, the driver reads the `xyz` file assuming it to contain coordinates in Angstrom units.
+     132             : However, the resulting `colvar` file contains a distance expressed in nm.
+     133             : 
+     134             : The following command tells plumed to post process the trajectory contained in trajectory.xyz.
+     135             :  by performing the actions described in the input file plumed.dat.
+     136             : \verbatim
+     137             : plumed driver --plumed plumed.dat --ixyz trajectory.xyz --trajectory-stride 100 --timestep 0.001
+     138             : \endverbatim
+     139             : Here though
+     140             : `--trajectory-stride` is set equal to the frequency with which frames were output during the trajectory
+     141             : and the `--timestep` is equal to the simulation timestep.  As such the `STRIDE` parameters in the `plumed.dat`
+     142             : files are referred to the original timestep and any files output resemble those that would have been generated
+     143             : had we run the calculation we are running with driver when the MD simulation was running.
+     144             : 
+     145             : PLUMED can read xyz files (in PLUMED units) and gro files (in nm). In addition,
+     146             : PLUMED includes by default support for a
+     147             : subset of the trajectory file formats supported by VMD, e.g. xtc and dcd:
+     148             : 
+     149             : \verbatim
+     150             : plumed driver --plumed plumed.dat --pdb diala.pdb --mf_xtc traj.xtc --trajectory-stride 100 --timestep 0.001
+     151             : \endverbatim
+     152             : 
+     153             : where `--mf_` prefixes the extension of one of the accepted molfile plugin format.
+     154             : If PLUMED has been \ref Installation "installed" with full molfile support, other formats will be available.
+     155             : Just type `plumed driver --help` to see which plugins are available.
+     156             : 
+     157             : Molfile plugin require periodic cell to be triangular (i.e. first vector oriented along x and
+     158             : second vector in xy plane). This is true for many MD codes. However, it could be false
+     159             : if you rotate the coordinates in your trajectory before reading them in the driver.
+     160             : Also notice that some formats (e.g. amber crd) do not specify atom number. In this case you can use
+     161             : the `--natoms` option:
+     162             : \verbatim
+     163             : plumed driver --plumed plumed.dat --imf_crd trajectory.crd --natoms 128
+     164             : \endverbatim
+     165             : 
+     166             : Check the available molfile plugins and limitations at [this link](http://www.ks.uiuc.edu/Research/vmd/plugins/molfile/).
+     167             : 
+     168             : Additionally, you can use the xdrfile implementation of xtc and trr. To this aim, just
+     169             : download and install properly the xdrfile library (see [this link](http://www.gromacs.org/Developer_Zone/Programming_Guide/XTC_Library)).
+     170             : If the xdrfile library is installed properly the PLUMED configure script should be able to
+     171             : detect it and enable it.
+     172             : Notice that the xdrfile implementation of xtc and trr
+     173             : is more robust than the molfile one, since it provides support for generic cell shapes.
+     174             : In addition, it allows \ref DUMPATOMS to write compressed xtc files.
+     175             : 
+     176             : 
+     177             : */
+     178             : //+ENDPLUMEDOC
+     179             : //
+     180             : 
+     181             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     182             : static std::vector<molfile_plugin_t *> plugins;
+     183             : static std::map <std::string, unsigned> pluginmap;
+     184       75366 : static int register_cb(void *v, vmdplugin_t *p) {
+     185             :   //const char *key = p->name;
+     186      150732 :   const auto ret = pluginmap.insert ( std::pair<std::string,unsigned>(std::string(p->name),plugins.size()) );
+     187       75366 :   if (ret.second==false) {
+     188             :     //cerr<<"MOLFILE: found duplicate plugin for "<<key<<" : not inserted "<<endl;
+     189             :   } else {
+     190             :     //cerr<<"MOLFILE: loading plugin "<<key<<" number "<<plugins.size()-1<<endl;
+     191       75366 :     plugins.push_back(reinterpret_cast<molfile_plugin_t *>(p));
+     192             :   }
+     193       75366 :   return VMDPLUGIN_SUCCESS;
+     194             : }
+     195             : #endif
+     196             : 
+     197             : template<typename real>
+     198             : class Driver : public CLTool {
+     199             : public:
+     200             :   static void registerKeywords( Keywords& keys );
+     201             :   explicit Driver(const CLToolOptions& co );
+     202             :   int main(FILE* in,FILE*out,Communicator& pc) override;
+     203             :   void evaluateNumericalDerivatives( const long long int& step, PlumedMain& p, const std::vector<real>& coordinates,
+     204             :                                      const std::vector<real>& masses, const std::vector<real>& charges,
+     205             :                                      std::vector<real>& cell, const double& base, std::vector<real>& numder );
+     206             :   std::string description()const override;
+     207             : };
+     208             : 
+     209             : template<typename real>
+     210        8374 : void Driver<real>::registerKeywords( Keywords& keys ) {
+     211        8374 :   CLTool::registerKeywords( keys ); keys.isDriver();
+     212       16748 :   keys.addFlag("--help-debug",false,"print special options that can be used to create regtests");
+     213       16748 :   keys.add("compulsory","--plumed","plumed.dat","specify the name of the plumed input file");
+     214       16748 :   keys.add("compulsory","--timestep","1.0","the timestep that was used in the calculation that produced this trajectory in picoseconds");
+     215       16748 :   keys.add("compulsory","--trajectory-stride","1","the frequency with which frames were output to this trajectory during the simulation"
+     216             :            " (0 means that the number of the step is read from the trajectory file,"
+     217             :            " currently working only for xtc/trr files read with --ixtc/--trr)"
+     218             :           );
+     219       16748 :   keys.add("compulsory","--multi","0","set number of replicas for multi environment (needs MPI)");
+     220       16748 :   keys.addFlag("--noatoms",false,"don't read in a trajectory.  Just use colvar files as specified in plumed.dat");
+     221       16748 :   keys.addFlag("--parse-only",false,"read the plumed input file and stop");
+     222       16748 :   keys.addFlag("--restart",false,"makes driver behave as if restarting");
+     223       16748 :   keys.add("atoms","--ixyz","the trajectory in xyz format");
+     224       16748 :   keys.add("atoms","--igro","the trajectory in gro format");
+     225       16748 :   keys.add("atoms","--idlp4","the trajectory in DL_POLY_4 format");
+     226       16748 :   keys.add("atoms","--ixtc","the trajectory in xtc format (xdrfile implementation)");
+     227       16748 :   keys.add("atoms","--itrr","the trajectory in trr format (xdrfile implementation)");
+     228       16748 :   keys.add("optional","--shortcut-ofile","the name of the file to output info on the way shortcuts have been expanded.  If there are no shortcuts in your input file nothing is output");
+     229       16748 :   keys.add("optional","--length-units","units for length, either as a string or a number");
+     230       16748 :   keys.add("optional","--mass-units","units for mass in pdb and mc file, either as a string or a number");
+     231       16748 :   keys.add("optional","--charge-units","units for charge in pdb and mc file, either as a string or a number");
+     232       16748 :   keys.add("optional","--kt","set \\f$k_B T\\f$, it will not be necessary to specify temperature in input file");
+     233       16748 :   keys.add("optional","--dump-forces","dump the forces on a file");
+     234       16748 :   keys.add("optional","--dump-forces-fmt","( default=%%f ) the format to use to dump the forces");
+     235       16748 :   keys.addFlag("--dump-full-virial",false,"with --dump-forces, it dumps the 9 components of the virial");
+     236       16748 :   keys.add("optional","--pdb","provides a pdb with masses and charges");
+     237       16748 :   keys.add("optional","--mc","provides a file with masses and charges as produced with DUMPMASSCHARGE");
+     238       16748 :   keys.add("optional","--box","comma-separated box dimensions (3 for orthorhombic, 9 for generic)");
+     239       16748 :   keys.add("optional","--natoms","provides number of atoms - only used if file format does not contain number of atoms");
+     240       16748 :   keys.add("optional","--initial-step","provides a number for the initial step, default is 0");
+     241       16748 :   keys.add("optional","--debug-forces","output a file containing the forces due to the bias evaluated using numerical derivatives "
+     242             :            "and using the analytical derivatives implemented in plumed");
+     243       16748 :   keys.add("hidden","--debug-float","[yes/no] turns on the single precision version (to check float interface)");
+     244       16748 :   keys.add("hidden","--debug-dd","[yes/no] use a fake domain decomposition");
+     245       16748 :   keys.add("hidden","--debug-pd","[yes/no] use a fake particle decomposition");
+     246       16748 :   keys.add("hidden","--debug-grex","use a fake gromacs-like replica exchange, specify exchange stride");
+     247       16748 :   keys.add("hidden","--debug-grex-log","log file for debug=grex");
+     248             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     249        8374 :   MOLFILE_INIT_ALL
+     250        8374 :   MOLFILE_REGISTER_ALL(NULL, register_cb)
+     251       83740 :   for(unsigned i=0; i<plugins.size(); i++) {
+     252      150732 :     std::string kk="--mf_"+std::string(plugins[i]->name);
+     253      150732 :     std::string mm=" molfile: the trajectory in "+std::string(plugins[i]->name)+" format " ;
+     254      150732 :     keys.add("atoms",kk,mm);
+     255             :   }
+     256             : #endif
+     257        8374 : }
+     258             : template<typename real>
+     259         816 : Driver<real>::Driver(const CLToolOptions& co ):
+     260         816 :   CLTool(co)
+     261             : {
+     262         816 :   inputdata=commandline;
+     263         816 : }
+     264             : template<typename real>
+     265           4 : std::string Driver<real>::description()const { return "analyze trajectories with plumed"; }
+     266             : 
+     267             : template<typename real>
+     268         808 : int Driver<real>::main(FILE* in,FILE*out,Communicator& pc) {
+     269             : 
+     270         808 :   Units units;
+     271         808 :   PDB pdb;
+     272             : 
+     273             : // Parse everything
+     274         808 :   bool printhelpdebug; parseFlag("--help-debug",printhelpdebug);
+     275         808 :   if( printhelpdebug ) {
+     276             :     std::fprintf(out,"%s",
+     277             :                  "Additional options for debug (only to be used in regtest):\n"
+     278             :                  "  [--debug-float yes]     : turns on the single precision version (to check float interface)\n"
+     279             :                  "  [--debug-dd yes]        : use a fake domain decomposition\n"
+     280             :                  "  [--debug-pd yes]        : use a fake particle decomposition\n"
+     281             :                 );
+     282             :     return 0;
+     283             :   }
+     284             :   // Are we reading trajectory data
+     285         808 :   bool noatoms; parseFlag("--noatoms",noatoms);
+     286        1616 :   bool parseOnly; parseFlag("--parse-only",parseOnly);
+     287         808 :   std::string full_outputfile; parse("--shortcut-ofile",full_outputfile);
+     288        1616 :   bool restart; parseFlag("--restart",restart);
+     289             : 
+     290             :   std::string fakein;
+     291             :   bool debug_float=false;
+     292             :   fakein="";
+     293        1616 :   if(parse("--debug-float",fakein)) {
+     294           0 :     if(fakein=="yes") debug_float=true;
+     295           0 :     else if(fakein=="no") debug_float=false;
+     296           0 :     else error("--debug-float should have argument yes or no");
+     297             :   }
+     298             : 
+     299             :   if(debug_float && sizeof(real)!=sizeof(float)) {
+     300           0 :     auto cl=cltoolRegister().create(CLToolOptions("driver-float"));
+     301             :     cl->setInputData(this->getInputData());
+     302           0 :     int ret=cl->main(in,out,pc);
+     303             :     return ret;
+     304           0 :   }
+     305             : 
+     306             :   bool debug_pd=false;
+     307             :   fakein="";
+     308        1616 :   if(parse("--debug-pd",fakein)) {
+     309          12 :     if(fakein=="yes") debug_pd=true;
+     310           0 :     else if(fakein=="no") debug_pd=false;
+     311           0 :     else error("--debug-pd should have argument yes or no");
+     312             :   }
+     313             :   if(debug_pd) std::fprintf(out,"DEBUGGING PARTICLE DECOMPOSITION\n");
+     314             : 
+     315             :   bool debug_dd=false;
+     316             :   fakein="";
+     317        1616 :   if(parse("--debug-dd",fakein)) {
+     318          58 :     if(fakein=="yes") debug_dd=true;
+     319           0 :     else if(fakein=="no") debug_dd=false;
+     320           0 :     else error("--debug-dd should have argument yes or no");
+     321             :   }
+     322             :   if(debug_dd) std::fprintf(out,"DEBUGGING DOMAIN DECOMPOSITION\n");
+     323             : 
+     324         808 :   if( debug_pd || debug_dd ) {
+     325          70 :     if(noatoms) error("cannot debug without atoms");
+     326             :   }
+     327             : 
+     328             : // set up for multi replica driver:
+     329         808 :   int multi=0;
+     330         808 :   parse("--multi",multi);
+     331         808 :   Communicator intracomm;
+     332         808 :   Communicator intercomm;
+     333         808 :   if(multi) {
+     334         170 :     int ntot=pc.Get_size();
+     335         170 :     int nintra=ntot/multi;
+     336         170 :     if(multi*nintra!=ntot) error("invalid number of processes for multi environment");
+     337         170 :     pc.Split(pc.Get_rank()/nintra,pc.Get_rank(),intracomm);
+     338         170 :     pc.Split(pc.Get_rank()%nintra,pc.Get_rank(),intercomm);
+     339             :   } else {
+     340         638 :     intracomm.Set_comm(pc.Get_comm());
+     341             :   }
+     342             : 
+     343             : // set up for debug replica exchange:
+     344         808 :   bool debug_grex=parse("--debug-grex",fakein);
+     345         808 :   int  grex_stride=0;
+     346             :   FILE*grex_log=NULL;
+     347             : // call fclose when fp goes out of scope
+     348         966 :   auto deleter=[](auto f) { if(f) std::fclose(f); };
+     349             :   std::unique_ptr<FILE,decltype(deleter)> grex_log_deleter(grex_log,deleter);
+     350             : 
+     351         808 :   if(debug_grex) {
+     352          30 :     if(noatoms) error("must have atoms to debug_grex");
+     353          30 :     if(multi<2)  error("--debug_grex needs --multi with at least two replicas");
+     354          30 :     Tools::convert(fakein,grex_stride);
+     355          30 :     std::string n; Tools::convert(intercomm.Get_rank(),n);
+     356             :     std::string file;
+     357          60 :     parse("--debug-grex-log",file);
+     358          30 :     if(file.length()>0) {
+     359          60 :       file+="."+n;
+     360          30 :       grex_log=std::fopen(file.c_str(),"w");
+     361             :       grex_log_deleter.reset(grex_log);
+     362             :     }
+     363             :   }
+     364             : 
+     365             : // Read the plumed input file name
+     366         808 :   std::string plumedFile; parse("--plumed",plumedFile);
+     367             : // the timestep
+     368         808 :   double t; parse("--timestep",t);
+     369         808 :   real timestep=real(t);
+     370             : // the stride
+     371         808 :   unsigned stride; parse("--trajectory-stride",stride);
+     372             : // are we writing forces
+     373         808 :   std::string dumpforces(""), debugforces(""), dumpforcesFmt("%f");;
+     374         808 :   bool dumpfullvirial=false;
+     375         808 :   if(!noatoms) {
+     376         754 :     parse("--dump-forces",dumpforces);
+     377        1508 :     parse("--debug-forces",debugforces);
+     378             :   }
+     379        1626 :   if(dumpforces!="" || debugforces!="" ) parse("--dump-forces-fmt",dumpforcesFmt);
+     380        1246 :   if(dumpforces!="") parseFlag("--dump-full-virial",dumpfullvirial);
+     381         808 :   if( debugforces!="" && (debug_dd || debug_pd) ) error("cannot debug forces and domain/particle decomposition at same time");
+     382           0 :   if( debugforces!="" && sizeof(real)!=sizeof(double) ) error("cannot debug forces in single precision mode");
+     383             : 
+     384         808 :   real kt=-1.0;
+     385        1616 :   parse("--kt",kt);
+     386             :   std::string trajectory_fmt;
+     387             : 
+     388             :   bool use_molfile=false;
+     389             :   molfile_plugin_t *api=NULL;
+     390             : 
+     391             : // Read in an xyz file
+     392         808 :   std::string trajectoryFile(""), pdbfile(""), mcfile("");
+     393         808 :   bool pbc_cli_given=false; std::vector<double> pbc_cli_box(9,0.0);
+     394         808 :   int command_line_natoms=-1;
+     395             : 
+     396         808 :   if(!noatoms) {
+     397        1508 :     std::string traj_xyz; parse("--ixyz",traj_xyz);
+     398        1508 :     std::string traj_gro; parse("--igro",traj_gro);
+     399        1508 :     std::string traj_dlp4; parse("--idlp4",traj_dlp4);
+     400             :     std::string traj_xtc;
+     401             :     std::string traj_trr;
+     402         754 :     parse("--ixtc",traj_xtc);
+     403         754 :     parse("--itrr",traj_trr);
+     404             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     405        7540 :     for(unsigned i=0; i<plugins.size(); i++) {
+     406       13572 :       std::string molfile_key="--mf_"+std::string(plugins[i]->name);
+     407             :       std::string traj_molfile;
+     408        6786 :       parse(molfile_key,traj_molfile);
+     409        6786 :       if(traj_molfile.length()>0) {
+     410         251 :         std::fprintf(out,"\nDRIVER: Found molfile format trajectory %s with name %s\n",plugins[i]->name,traj_molfile.c_str());
+     411             :         trajectoryFile=traj_molfile;
+     412         502 :         trajectory_fmt=std::string(plugins[i]->name);
+     413             :         use_molfile=true;
+     414         251 :         api = plugins[i];
+     415             :       }
+     416             :     }
+     417             : #endif
+     418             :     { // check that only one fmt is specified
+     419             :       int nn=0;
+     420         754 :       if(traj_xyz.length()>0) nn++;
+     421         754 :       if(traj_gro.length()>0) nn++;
+     422         754 :       if(traj_dlp4.length()>0) nn++;
+     423         754 :       if(traj_xtc.length()>0) nn++;
+     424         754 :       if(traj_trr.length()>0) nn++;
+     425         754 :       if(nn>1) {
+     426           0 :         std::fprintf(stderr,"ERROR: cannot provide more than one trajectory file\n");
+     427             :         return 1;
+     428             :       }
+     429             :     }
+     430         754 :     if(traj_xyz.length()>0 && trajectoryFile.length()==0) {
+     431             :       trajectoryFile=traj_xyz;
+     432             :       trajectory_fmt="xyz";
+     433             :     }
+     434         754 :     if(traj_gro.length()>0 && trajectoryFile.length()==0) {
+     435             :       trajectoryFile=traj_gro;
+     436             :       trajectory_fmt="gro";
+     437             :     }
+     438         754 :     if(traj_dlp4.length()>0 && trajectoryFile.length()==0) {
+     439             :       trajectoryFile=traj_dlp4;
+     440             :       trajectory_fmt="dlp4";
+     441             :     }
+     442         754 :     if(traj_xtc.length()>0 && trajectoryFile.length()==0) {
+     443             :       trajectoryFile=traj_xtc;
+     444             :       trajectory_fmt="xdr-xtc";
+     445             :     }
+     446         754 :     if(traj_trr.length()>0 && trajectoryFile.length()==0) {
+     447             :       trajectoryFile=traj_trr;
+     448             :       trajectory_fmt="xdr-trr";
+     449             :     }
+     450         754 :     if(trajectoryFile.length()==0&&!parseOnly) {
+     451           0 :       std::fprintf(stderr,"ERROR: missing trajectory data\n");
+     452             :       return 1;
+     453             :     }
+     454        1508 :     std::string lengthUnits(""); parse("--length-units",lengthUnits);
+     455         754 :     if(lengthUnits.length()>0) units.setLength(lengthUnits);
+     456        1508 :     std::string chargeUnits(""); parse("--charge-units",chargeUnits);
+     457         754 :     if(chargeUnits.length()>0) units.setCharge(chargeUnits);
+     458        1508 :     std::string massUnits(""); parse("--mass-units",massUnits);
+     459         754 :     if(massUnits.length()>0) units.setMass(massUnits);
+     460             : 
+     461        1508 :     parse("--pdb",pdbfile);
+     462         754 :     if(pdbfile.length()>0) {
+     463          75 :       bool check=pdb.read(pdbfile,false,1.0);
+     464          75 :       if(!check) error("error reading pdb file");
+     465             :     }
+     466             : 
+     467        1508 :     parse("--mc",mcfile);
+     468             : 
+     469        1508 :     std::string pbc_cli_list; parse("--box",pbc_cli_list);
+     470         754 :     if(pbc_cli_list.length()>0) {
+     471             :       pbc_cli_given=true;
+     472          33 :       std::vector<std::string> words=Tools::getWords(pbc_cli_list,",");
+     473          33 :       if(words.size()==3) {
+     474         132 :         for(int i=0; i<3; i++) std::sscanf(words[i].c_str(),"%100lf",&(pbc_cli_box[4*i]));
+     475           0 :       } else if(words.size()==9) {
+     476           0 :         for(int i=0; i<9; i++) std::sscanf(words[i].c_str(),"%100lf",&(pbc_cli_box[i]));
+     477             :       } else {
+     478           0 :         std::string msg="ERROR: cannot parse command-line box "+pbc_cli_list;
+     479           0 :         std::fprintf(stderr,"%s\n",msg.c_str());
+     480             :         return 1;
+     481             :       }
+     482             : 
+     483          33 :     }
+     484             : 
+     485        1508 :     parse("--natoms",command_line_natoms);
+     486             : 
+     487             :   }
+     488             : 
+     489             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     490         251 :   auto mf_deleter=[api](void* h_in) {
+     491         251 :     if(h_in) {
+     492         251 :       std::unique_ptr<std::lock_guard<std::mutex>> lck;
+     493         446 :       if(api->is_reentrant==VMDPLUGIN_THREADUNSAFE) lck=Tools::molfile_lock();
+     494         251 :       api->close_file_read(h_in);
+     495         251 :     }
+     496             :   };
+     497             :   void *h_in=NULL;
+     498             :   std::unique_ptr<void,decltype(mf_deleter)> h_in_deleter(h_in,mf_deleter);
+     499             : 
+     500             :   molfile_timestep_t ts_in; // this is the structure that has the timestep
+     501             : // a std::vector<float> with the same scope as ts_in
+     502             : // it is necessary in order to store the pointer to ts_in.coords
+     503             :   std::vector<float> ts_in_coords;
+     504         808 :   ts_in.coords=ts_in_coords.data();
+     505         808 :   ts_in.velocities=NULL;
+     506         808 :   ts_in.A=-1; // we use this to check whether cell is provided or not
+     507             : #endif
+     508             : 
+     509             : 
+     510             : 
+     511         808 :   if(debug_dd && debug_pd) error("cannot use debug-dd and debug-pd at the same time");
+     512         808 :   if(debug_pd || debug_dd) {
+     513          70 :     if( !Communicator::initialized() ) error("needs mpi for debug-pd");
+     514             :   }
+     515             : 
+     516         808 :   PlumedMain p;
+     517         808 :   p.cmd("setRealPrecision",(int)sizeof(real));
+     518             :   int checknatoms=-1;
+     519         808 :   long long int step=0;
+     520         808 :   parse("--initial-step",step);
+     521             : 
+     522         808 :   if(restart) p.cmd("setRestart",1);
+     523             : 
+     524         808 :   if(Communicator::initialized()) {
+     525         307 :     if(multi) {
+     526         292 :       if(intracomm.Get_rank()==0) p.cmd("GREX setMPIIntercomm",&intercomm.Get_comm());
+     527         340 :       p.cmd("GREX setMPIIntracomm",&intracomm.Get_comm());
+     528         170 :       p.cmd("GREX init");
+     529             :     }
+     530         614 :     p.cmd("setMPIComm",&intracomm.Get_comm());
+     531             :   }
+     532         808 :   p.cmd("setMDLengthUnits",units.getLength());
+     533         808 :   p.cmd("setMDChargeUnits",units.getCharge());
+     534         808 :   p.cmd("setMDMassUnits",units.getMass());
+     535         808 :   p.cmd("setMDEngine","driver");
+     536         808 :   p.cmd("setTimestep",timestep);
+     537        1616 :   if( !parseOnly || full_outputfile.length()==0 ) p.cmd("setPlumedDat",plumedFile.c_str());
+     538         808 :   p.cmd("setLog",out);
+     539             : 
+     540             :   int natoms;
+     541         808 :   int lvl=0;
+     542         808 :   int pb=1;
+     543             : 
+     544         808 :   if(parseOnly) {
+     545           0 :     if(command_line_natoms<0) error("--parseOnly requires setting the number of atoms with --natoms");
+     546           0 :     natoms=command_line_natoms;
+     547             :   }
+     548             : 
+     549             : 
+     550         808 :   FILE* fp=NULL; FILE* fp_forces=NULL; OFile fp_dforces;
+     551             : 
+     552             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     553             :   std::unique_ptr<FILE,decltype(deleter)> fp_forces_deleter(fp_forces,deleter);
+     554             : 
+     555           5 :   auto xdr_deleter=[](auto xd) { if(xd) xdrfile::xdrfile_close(xd); };
+     556             : 
+     557             :   xdrfile::XDRFILE* xd=NULL;
+     558             : 
+     559             :   std::unique_ptr<xdrfile::XDRFILE,decltype(xdr_deleter)> xd_deleter(xd,xdr_deleter);
+     560             : 
+     561         808 :   if(!noatoms&&!parseOnly) {
+     562         754 :     if (trajectoryFile=="-")
+     563             :       fp=in;
+     564             :     else {
+     565         754 :       if(multi) {
+     566             :         std::string n;
+     567         170 :         Tools::convert(intercomm.Get_rank(),n);
+     568         340 :         std::string testfile=FileBase::appendSuffix(trajectoryFile,"."+n);
+     569         170 :         FILE* tmp_fp=std::fopen(testfile.c_str(),"r");
+     570             :         // no exceptions here
+     571         170 :         if(tmp_fp) { std::fclose(tmp_fp); trajectoryFile=testfile;}
+     572             :       }
+     573         754 :       if(use_molfile==true) {
+     574             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     575         251 :         std::unique_ptr<std::lock_guard<std::mutex>> lck;
+     576         446 :         if(api->is_reentrant==VMDPLUGIN_THREADUNSAFE) lck=Tools::molfile_lock();
+     577         251 :         h_in = api->open_file_read(trajectoryFile.c_str(), trajectory_fmt.c_str(), &natoms);
+     578             :         h_in_deleter.reset(h_in);
+     579         251 :         if(natoms==MOLFILE_NUMATOMS_UNKNOWN) {
+     580           2 :           if(command_line_natoms>=0) natoms=command_line_natoms;
+     581           0 :           else error("this file format does not provide number of atoms; use --natoms on the command line");
+     582             :         }
+     583         251 :         ts_in_coords.resize(3*natoms);
+     584         251 :         ts_in.coords = ts_in_coords.data();
+     585             : #endif
+     586        1255 :       } else if(trajectory_fmt=="xdr-xtc" || trajectory_fmt=="xdr-trr") {
+     587           5 :         xd=xdrfile::xdrfile_open(trajectoryFile.c_str(),"r");
+     588             :         xd_deleter.reset(xd);
+     589           5 :         if(!xd) {
+     590           0 :           std::string msg="ERROR: Error opening trajectory file "+trajectoryFile;
+     591           0 :           std::fprintf(stderr,"%s\n",msg.c_str());
+     592             :           return 1;
+     593             :         }
+     594           5 :         if(trajectory_fmt=="xdr-xtc") xdrfile::read_xtc_natoms(&trajectoryFile[0],&natoms);
+     595           5 :         if(trajectory_fmt=="xdr-trr") xdrfile::read_trr_natoms(&trajectoryFile[0],&natoms);
+     596             :       } else {
+     597         498 :         fp=std::fopen(trajectoryFile.c_str(),"r");
+     598             :         fp_deleter.reset(fp);
+     599         498 :         if(!fp) {
+     600           0 :           std::string msg="ERROR: Error opening trajectory file "+trajectoryFile;
+     601           0 :           std::fprintf(stderr,"%s\n",msg.c_str());
+     602             :           return 1;
+     603             :         }
+     604             :       }
+     605             :     }
+     606         754 :     if(dumpforces.length()>0) {
+     607         438 :       if(Communicator::initialized() && pc.Get_size()>1) {
+     608             :         std::string n;
+     609         226 :         Tools::convert(pc.Get_rank(),n);
+     610         452 :         dumpforces+="."+n;
+     611             :       }
+     612         438 :       fp_forces=std::fopen(dumpforces.c_str(),"w");
+     613             :       fp_forces_deleter.reset(fp_forces);
+     614             :     }
+     615         754 :     if(debugforces.length()>0) {
+     616          11 :       if(Communicator::initialized() && pc.Get_size()>1) {
+     617             :         std::string n;
+     618           6 :         Tools::convert(pc.Get_rank(),n);
+     619          12 :         debugforces+="."+n;
+     620             :       }
+     621          11 :       fp_dforces.open(debugforces);
+     622             :     }
+     623             :   }
+     624             : 
+     625             :   std::string line;
+     626             :   std::vector<real> coordinates;
+     627             :   std::vector<real> forces;
+     628             :   std::vector<real> masses;
+     629             :   std::vector<real> charges;
+     630             :   std::vector<real> cell;
+     631             :   std::vector<real> virial;
+     632             :   std::vector<real> numder;
+     633             : 
+     634             : // variables to test particle decomposition
+     635             :   int pd_nlocal=0;
+     636             :   int pd_start=0;
+     637             : // variables to test random decomposition (=domain decomposition)
+     638             :   std::vector<int>  dd_gatindex;
+     639             :   std::vector<int>  dd_g2l;
+     640             :   std::vector<real> dd_masses;
+     641             :   std::vector<real> dd_charges;
+     642             :   std::vector<real> dd_forces;
+     643             :   std::vector<real> dd_coordinates;
+     644             :   int dd_nlocal=0;
+     645             : // random stream to choose decompositions
+     646         808 :   Random rnd;
+     647             : 
+     648         808 :   if(trajectory_fmt=="dlp4") {
+     649           2 :     if(!Tools::getline(fp,line)) error("error reading title");
+     650           2 :     if(!Tools::getline(fp,line)) error("error reading atoms");
+     651           2 :     std::sscanf(line.c_str(),"%d %d %d",&lvl,&pb,&natoms);
+     652             : 
+     653             :   }
+     654             :   bool lstep=true;
+     655      244020 :   while(true) {
+     656      244828 :     if(!noatoms&&!parseOnly) {
+     657       44488 :       if(use_molfile==true) {
+     658             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     659       18596 :         std::unique_ptr<std::lock_guard<std::mutex>> lck;
+     660       37048 :         if(api->is_reentrant==VMDPLUGIN_THREADUNSAFE) lck=Tools::molfile_lock();
+     661             :         int rc;
+     662       18596 :         rc = api->read_next_timestep(h_in, natoms, &ts_in);
+     663       18596 :         if(rc==MOLFILE_EOF) {
+     664             :           break;
+     665             :         }
+     666             : #endif
+     667       47119 :       } else if(trajectory_fmt=="xyz" || trajectory_fmt=="gro" || trajectory_fmt=="dlp4") {
+     668       25823 :         if(!Tools::getline(fp,line)) break;
+     669             :       }
+     670             :     }
+     671             :     bool first_step=false;
+     672      244083 :     if(!noatoms&&!parseOnly) {
+     673       71570 :       if(use_molfile==false && (trajectory_fmt=="xyz" || trajectory_fmt=="gro")) {
+     674       25309 :         if(trajectory_fmt=="gro") if(!Tools::getline(fp,line)) error("premature end of trajectory file");
+     675       25309 :         std::sscanf(line.c_str(),"%100d",&natoms);
+     676             :       }
+     677       69141 :       if(use_molfile==false && trajectory_fmt=="dlp4") {
+     678             :         char xa[9];
+     679             :         int xb,xc,xd;
+     680             :         double t;
+     681          20 :         std::sscanf(line.c_str(),"%8s %lld %d %d %d %lf",xa,&step,&xb,&xc,&xd,&t);
+     682          20 :         if (lstep) {
+     683           2 :           p.cmd("setTimestep",real(t));
+     684             :           lstep = false;
+     685             :         }
+     686             :       }
+     687             :     }
+     688      244083 :     if(checknatoms<0 && !noatoms) {
+     689         754 :       pd_nlocal=natoms;
+     690             :       pd_start=0;
+     691             :       first_step=true;
+     692         754 :       masses.assign(natoms,std::numeric_limits<real>::quiet_NaN());
+     693         754 :       charges.assign(natoms,std::numeric_limits<real>::quiet_NaN());
+     694             : //case pdb: structure
+     695         754 :       if(pdbfile.length()>0) {
+     696       28092 :         for(unsigned i=0; i<pdb.size(); ++i) {
+     697       28017 :           AtomNumber an=pdb.getAtomNumbers()[i];
+     698             :           unsigned index=an.index();
+     699       28017 :           if( index>=unsigned(natoms) ) error("atom index in pdb exceeds the number of atoms in trajectory");
+     700       28017 :           masses[index]=pdb.getOccupancy()[i];
+     701       28017 :           charges[index]=pdb.getBeta()[i];
+     702             :         }
+     703             :       }
+     704         754 :       if(mcfile.length()>0) {
+     705           5 :         IFile ifile;
+     706           5 :         ifile.open(mcfile);
+     707             :         int index; double mass; double charge;
+     708        1138 :         while(ifile.scanField("index",index).scanField("mass",mass).scanField("charge",charge).scanField()) {
+     709         564 :           masses[index]=mass;
+     710         564 :           charges[index]=charge;
+     711             :         }
+     712           5 :       }
+     713      243329 :     } else if( checknatoms<0 && noatoms ) {
+     714          54 :       natoms=0;
+     715             :     }
+     716      244083 :     if( checknatoms<0 ) {
+     717         808 :       if(kt>=0) {
+     718           3 :         p.cmd("setKbT",kt);
+     719             :       }
+     720         808 :       checknatoms=natoms;
+     721         808 :       p.cmd("setNatoms",natoms);
+     722         808 :       p.cmd("init");
+     723             :       // Check if we have been asked to output the long version of the input and if there are shortcuts
+     724         808 :       if( parseOnly && full_outputfile.length()>0 ) {
+     725             : 
+     726             :         // Read in the plumed input file and store what is in there
+     727             :         std::map<std::string,std::vector<std::string> > data;
+     728           0 :         IFile ifile; ifile.open(plumedFile); std::vector<std::string> words;
+     729           0 :         while( Tools::getParsedLine(ifile,words) && !p.getEndPlumed() ) {
+     730           0 :           p.readInputWords(words,false); Action* aa=p.getActionSet()[p.getActionSet().size()-1].get();
+     731           0 :           ActionWithValue* av=aa->castToActionWithValue();
+     732           0 :           if( av && aa->getDefaultString().length()>0 ) {
+     733           0 :             std::vector<std::string> def; def.push_back( "defaults " + aa->getDefaultString() );
+     734           0 :             data[ aa->getLabel() ] = def;
+     735           0 :           }
+     736           0 :           ActionShortcut* as=aa->castToActionShortcut();
+     737           0 :           if( as ) {
+     738           0 :             if( aa->getDefaultString().length()>0 ) {
+     739           0 :               std::vector<std::string> def; def.push_back( "defaults " + aa->getDefaultString() );
+     740           0 :               data[ as->getShortcutLabel() ] = def;
+     741           0 :             }
+     742           0 :             if( data.find( as->getShortcutLabel() )!=data.end() ) {
+     743           0 :               std::vector<std::string> shortcut_commands = as->getSavedInputLines();
+     744           0 :               for(unsigned i=0; i<shortcut_commands.size(); ++i) data[ as->getShortcutLabel() ].push_back( shortcut_commands[i] );
+     745           0 :             } else data[ as->getShortcutLabel() ] = as->getSavedInputLines();
+     746             :           }
+     747             :         }
+     748           0 :         ifile.close();
+     749             :         // Only output the full version of the input file if there are shortcuts
+     750           0 :         if( data.size()>0 ) {
+     751           0 :           OFile long_file; long_file.open( full_outputfile ); long_file.printf("{\n"); bool firstpass=true;
+     752           0 :           for(auto& x : data ) {
+     753           0 :             if( !firstpass ) long_file.printf("   },\n");
+     754           0 :             long_file.printf("   \"%s\" : {\n", x.first.c_str() );
+     755           0 :             plumed_assert( x.second.size()>0 ); unsigned sstart=0;
+     756           0 :             if( x.second[0].find("defaults")!=std::string::npos ) {
+     757           0 :               sstart=1; long_file.printf("      \"defaults\" : \"%s\"", x.second[0].substr( 9 ).c_str() );
+     758           0 :               if( x.second.size()>1 ) long_file.printf(",\n"); else long_file.printf("\n");
+     759             :             }
+     760           0 :             if( x.second.size()>sstart ) {
+     761           0 :               long_file.printf("      \"expansion\" : \"%s", x.second[sstart].c_str() );
+     762           0 :               for(unsigned j=sstart+1; j<x.second.size(); ++j) long_file.printf("\\n%s", x.second[j].c_str() );
+     763           0 :               long_file.printf("\"\n");
+     764             :             }
+     765             :             firstpass=false;
+     766             :           }
+     767           0 :           long_file.printf("   }\n}\n"); long_file.close();
+     768           0 :         }
+     769           0 :       }
+     770         808 :       if(parseOnly) break;
+     771             :     }
+     772      244083 :     if(checknatoms!=natoms) {
+     773           0 :       std::string stepstr; Tools::convert(step,stepstr);
+     774           0 :       error("number of atoms in frame " + stepstr + " does not match number of atoms in first frame");
+     775             :     }
+     776             : 
+     777      244083 :     coordinates.assign(3*natoms,real(0.0));
+     778      244083 :     forces.assign(3*natoms,real(0.0));
+     779      244083 :     cell.assign(9,real(0.0));
+     780      244083 :     virial.assign(9,real(0.0));
+     781             : 
+     782      244083 :     if( first_step || rnd.U01()>0.5) {
+     783      123674 :       if(debug_pd) {
+     784         152 :         int npe=intracomm.Get_size();
+     785         152 :         std::vector<int> loc(npe,0);
+     786         152 :         std::vector<int> start(npe,0);
+     787         608 :         for(int i=0; i<npe-1; i++) {
+     788         456 :           int cc=(natoms*2*rnd.U01())/npe;
+     789         456 :           if(start[i]+cc>natoms) cc=natoms-start[i];
+     790         456 :           loc[i]=cc;
+     791         456 :           start[i+1]=start[i]+loc[i];
+     792             :         }
+     793         152 :         loc[npe-1]=natoms-start[npe-1];
+     794         152 :         intracomm.Bcast(loc,0);
+     795         152 :         intracomm.Bcast(start,0);
+     796         152 :         pd_nlocal=loc[intracomm.Get_rank()];
+     797         152 :         pd_start=start[intracomm.Get_rank()];
+     798         152 :         if(intracomm.Get_rank()==0) {
+     799             :           std::fprintf(out,"\nDRIVER: Reassigning particle decomposition\n");
+     800         190 :           std::fprintf(out,"DRIVER: "); for(int i=0; i<npe; i++) std::fprintf(out,"%d ",loc[i]); printf("\n");
+     801         190 :           std::fprintf(out,"DRIVER: "); for(int i=0; i<npe; i++) std::fprintf(out,"%d ",start[i]); printf("\n");
+     802             :         }
+     803         152 :         p.cmd("setAtomsNlocal",pd_nlocal);
+     804         152 :         p.cmd("setAtomsContiguous",pd_start);
+     805      123522 :       } else if(debug_dd) {
+     806         946 :         int npe=intracomm.Get_size();
+     807         946 :         int rank=intracomm.Get_rank();
+     808         946 :         dd_charges.assign(natoms,0.0);
+     809         946 :         dd_masses.assign(natoms,0.0);
+     810         946 :         dd_gatindex.assign(natoms,-1);
+     811         946 :         dd_g2l.assign(natoms,-1);
+     812         946 :         dd_coordinates.assign(3*natoms,0.0);
+     813         946 :         dd_forces.assign(3*natoms,0.0);
+     814             :         dd_nlocal=0;
+     815       52456 :         for(int i=0; i<natoms; ++i) {
+     816       51510 :           double r=rnd.U01()*npe;
+     817      110396 :           int n; for(n=0; n<npe; n++) if(n+1>r)break;
+     818       51510 :           plumed_assert(n<npe);
+     819       51510 :           if(n==rank) {
+     820       19167 :             dd_gatindex[dd_nlocal]=i;
+     821       19167 :             dd_g2l[i]=dd_nlocal;
+     822       19167 :             dd_charges[dd_nlocal]=charges[i];
+     823       19167 :             dd_masses[dd_nlocal]=masses[i];
+     824       19167 :             dd_nlocal++;
+     825             :           }
+     826             :         }
+     827         946 :         if(intracomm.Get_rank()==0) {
+     828             :           std::fprintf(out,"\nDRIVER: Reassigning domain decomposition\n");
+     829             :         }
+     830         946 :         p.cmd("setAtomsNlocal",dd_nlocal);
+     831         946 :         p.cmd("setAtomsGatindex",&dd_gatindex[0],dd_nlocal);
+     832             :       }
+     833             :     }
+     834             : 
+     835      244083 :     int plumedStopCondition=0;
+     836      244083 :     if(!noatoms) {
+     837       43743 :       if(use_molfile) {
+     838             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     839       18345 :         if(pbc_cli_given==false) {
+     840       18324 :           if(ts_in.A>0.0) { // this is negative if molfile does not provide box
+     841             :             // info on the cell: convert using pbcset.tcl from pbctools in vmd distribution
+     842       18319 :             real cosBC=cos(real(ts_in.alpha)*pi/180.);
+     843             :             //double sinBC=std::sin(ts_in.alpha*pi/180.);
+     844       18319 :             real cosAC=std::cos(real(ts_in.beta)*pi/180.);
+     845       18319 :             real cosAB=std::cos(real(ts_in.gamma)*pi/180.);
+     846       18319 :             real sinAB=std::sin(real(ts_in.gamma)*pi/180.);
+     847       18319 :             real Ax=real(ts_in.A);
+     848       18319 :             real Bx=real(ts_in.B)*cosAB;
+     849       18319 :             real By=real(ts_in.B)*sinAB;
+     850       18319 :             real Cx=real(ts_in.C)*cosAC;
+     851       18319 :             real Cy=(real(ts_in.C)*real(ts_in.B)*cosBC-Cx*Bx)/By;
+     852       18319 :             real Cz=std::sqrt(real(ts_in.C)*real(ts_in.C)-Cx*Cx-Cy*Cy);
+     853       18319 :             cell[0]=Ax/10.; cell[1]=0.; cell[2]=0.;
+     854       18319 :             cell[3]=Bx/10.; cell[4]=By/10.; cell[5]=0.;
+     855       18319 :             cell[6]=Cx/10.; cell[7]=Cy/10.; cell[8]=Cz/10.;
+     856             :           } else {
+     857           5 :             cell[0]=0.0; cell[1]=0.0; cell[2]=0.0;
+     858           5 :             cell[3]=0.0; cell[4]=0.0; cell[5]=0.0;
+     859           5 :             cell[6]=0.0; cell[7]=0.0; cell[8]=0.0;
+     860             :           }
+     861             :         } else {
+     862         210 :           for(unsigned i=0; i<9; i++)cell[i]=pbc_cli_box[i];
+     863             :         }
+     864             :         // info on coords
+     865             :         // the order is xyzxyz...
+     866     7739619 :         for(int i=0; i<3*natoms; i++) {
+     867     7721274 :           coordinates[i]=real(ts_in.coords[i])/real(10.); //convert to nm
+     868             :           //cerr<<"COOR "<<coordinates[i]<<endl;
+     869             :         }
+     870             : #endif
+     871       50766 :       } else if(trajectory_fmt=="xdr-xtc" || trajectory_fmt=="xdr-trr") {
+     872             :         int localstep;
+     873             :         float time;
+     874             :         xdrfile::matrix box;
+     875             : // here we cannot use a std::vector<rvec> since it does not compile.
+     876             : // we thus use a std::unique_ptr<rvec[]>
+     877             :         auto pos=Tools::make_unique<xdrfile::rvec[]>(natoms);
+     878             :         float prec,lambda;
+     879             :         int ret=xdrfile::exdrOK;
+     880          69 :         if(trajectory_fmt=="xdr-xtc") ret=xdrfile::read_xtc(xd,natoms,&localstep,&time,box,pos.get(),&prec);
+     881          69 :         if(trajectory_fmt=="xdr-trr") ret=xdrfile::read_trr(xd,natoms,&localstep,&time,&lambda,box,pos.get(),NULL,NULL);
+     882          69 :         if(stride==0) step=localstep;
+     883          69 :         if(ret==xdrfile::exdrENDOFFILE) break;
+     884          67 :         if(ret!=xdrfile::exdrOK) break;
+     885         832 :         for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++) cell[3*i+j]=box[i][j];
+     886       10976 :         for(int i=0; i<natoms; i++) for(unsigned j=0; j<3; j++)
+     887        8184 :             coordinates[3*i+j]=real(pos[i][j]);
+     888             :       } else {
+     889       25329 :         if(trajectory_fmt=="xyz") {
+     890       22969 :           if(!Tools::getline(fp,line)) error("premature end of trajectory file");
+     891             : 
+     892       22969 :           std::vector<double> celld(9,0.0);
+     893       22969 :           if(pbc_cli_given==false) {
+     894             :             std::vector<std::string> words;
+     895       45492 :             words=Tools::getWords(line);
+     896       22746 :             if(words.size()==3) {
+     897       22169 :               Tools::convert(words[0],celld[0]);
+     898       22169 :               Tools::convert(words[1],celld[4]);
+     899       22169 :               Tools::convert(words[2],celld[8]);
+     900         577 :             } else if(words.size()==9) {
+     901         577 :               Tools::convert(words[0],celld[0]);
+     902         577 :               Tools::convert(words[1],celld[1]);
+     903         577 :               Tools::convert(words[2],celld[2]);
+     904         577 :               Tools::convert(words[3],celld[3]);
+     905         577 :               Tools::convert(words[4],celld[4]);
+     906         577 :               Tools::convert(words[5],celld[5]);
+     907         577 :               Tools::convert(words[6],celld[6]);
+     908         577 :               Tools::convert(words[7],celld[7]);
+     909         577 :               Tools::convert(words[8],celld[8]);
+     910           0 :             } else error("needed box in second line of xyz file");
+     911       22746 :           } else {                      // from command line
+     912         223 :             celld=pbc_cli_box;
+     913             :           }
+     914      229690 :           for(unsigned i=0; i<9; i++)cell[i]=real(celld[i]);
+     915             :         }
+     916       25329 :         if(trajectory_fmt=="dlp4") {
+     917          20 :           std::vector<double> celld(9,0.0);
+     918          20 :           if(pbc_cli_given==false) {
+     919          20 :             if(!Tools::getline(fp,line)) error("error reading vector a of cell");
+     920          20 :             std::sscanf(line.c_str(),"%lf %lf %lf",&celld[0],&celld[1],&celld[2]);
+     921          20 :             if(!Tools::getline(fp,line)) error("error reading vector b of cell");
+     922          20 :             std::sscanf(line.c_str(),"%lf %lf %lf",&celld[3],&celld[4],&celld[5]);
+     923          20 :             if(!Tools::getline(fp,line)) error("error reading vector c of cell");
+     924          20 :             std::sscanf(line.c_str(),"%lf %lf %lf",&celld[6],&celld[7],&celld[8]);
+     925             :           } else {
+     926           0 :             celld=pbc_cli_box;
+     927             :           }
+     928         200 :           for(auto i=0; i<9; i++)cell[i]=real(celld[i])*0.1;
+     929             :         }
+     930             :         int ddist=0;
+     931             :         // Read coordinates
+     932     2431235 :         for(int i=0; i<natoms; i++) {
+     933     2405906 :           bool ok=Tools::getline(fp,line);
+     934     2405906 :           if(!ok) error("premature end of trajectory file");
+     935             :           double cc[3];
+     936     2405906 :           if(trajectory_fmt=="xyz") {
+     937             :             char dummy[1000];
+     938     1692792 :             int ret=std::sscanf(line.c_str(),"%999s %100lf %100lf %100lf",dummy,&cc[0],&cc[1],&cc[2]);
+     939     1692792 :             if(ret!=4) error("cannot read line"+line);
+     940      713114 :           } else if(trajectory_fmt=="gro") {
+     941             :             // do the gromacs way
+     942      712474 :             if(!i) {
+     943             :               //
+     944             :               // calculate the distance between dots (as in gromacs gmxlib/confio.c, routine get_w_conf )
+     945             :               //
+     946             :               const char      *p1, *p2, *p3;
+     947             :               p1 = std::strchr(line.c_str(), '.');
+     948        2340 :               if (p1 == NULL) error("seems there are no coordinates in the gro file");
+     949        2340 :               p2 = std::strchr(&p1[1], '.');
+     950        2340 :               if (p2 == NULL) error("seems there is only one coordinates in the gro file");
+     951        2340 :               ddist = p2 - p1;
+     952        2340 :               p3 = std::strchr(&p2[1], '.');
+     953        2340 :               if (p3 == NULL)error("seems there are only two coordinates in the gro file");
+     954        2340 :               if (p3 - p2 != ddist)error("not uniform spacing in fields in the gro file");
+     955             :             }
+     956      712474 :             Tools::convert(line.substr(20,ddist),cc[0]);
+     957      712474 :             Tools::convert(line.substr(20+ddist,ddist),cc[1]);
+     958     1424948 :             Tools::convert(line.substr(20+ddist+ddist,ddist),cc[2]);
+     959         640 :           } else if(trajectory_fmt=="dlp4") {
+     960             :             char dummy[9];
+     961             :             int idummy;
+     962             :             double m,c;
+     963         640 :             std::sscanf(line.c_str(),"%8s %d %lf %lf",dummy,&idummy,&m,&c);
+     964         640 :             masses[i]=real(m);
+     965         640 :             charges[i]=real(c);
+     966         640 :             if(!Tools::getline(fp,line)) error("error reading coordinates");
+     967         640 :             std::sscanf(line.c_str(),"%lf %lf %lf",&cc[0],&cc[1],&cc[2]);
+     968         640 :             cc[0]*=0.1;
+     969         640 :             cc[1]*=0.1;
+     970         640 :             cc[2]*=0.1;
+     971         640 :             if(lvl>0) {
+     972         640 :               if(!Tools::getline(fp,line)) error("error skipping velocities");
+     973             :             }
+     974         640 :             if(lvl>1) {
+     975         640 :               if(!Tools::getline(fp,line)) error("error skipping forces");
+     976             :             }
+     977           0 :           } else plumed_error();
+     978     2405906 :           if(!debug_pd || ( i>=pd_start && i<pd_start+pd_nlocal) ) {
+     979     2386466 :             coordinates[3*i]=real(cc[0]);
+     980     2386466 :             coordinates[3*i+1]=real(cc[1]);
+     981     2386466 :             coordinates[3*i+2]=real(cc[2]);
+     982             :           }
+     983             :         }
+     984       25329 :         if(trajectory_fmt=="gro") {
+     985        2340 :           if(!Tools::getline(fp,line)) error("premature end of trajectory file");
+     986        2340 :           std::vector<std::string> words=Tools::getWords(line);
+     987        2340 :           if(words.size()<3) error("cannot understand box format");
+     988        2340 :           Tools::convert(words[0],cell[0]);
+     989        2340 :           Tools::convert(words[1],cell[4]);
+     990        2340 :           Tools::convert(words[2],cell[8]);
+     991        2340 :           if(words.size()>3) Tools::convert(words[3],cell[1]);
+     992        2340 :           if(words.size()>4) Tools::convert(words[4],cell[2]);
+     993        2340 :           if(words.size()>5) Tools::convert(words[5],cell[3]);
+     994        2340 :           if(words.size()>6) Tools::convert(words[6],cell[5]);
+     995        2340 :           if(words.size()>7) Tools::convert(words[7],cell[6]);
+     996        2340 :           if(words.size()>8) Tools::convert(words[8],cell[7]);
+     997        2340 :         }
+     998             : 
+     999             :       }
+    1000             : 
+    1001       43738 :       p.cmd("setStepLongLong",step);
+    1002       43738 :       p.cmd("setStopFlag",&plumedStopCondition);
+    1003             : 
+    1004       43738 :       if(debug_dd) {
+    1005       37336 :         for(int i=0; i<dd_nlocal; ++i) {
+    1006       35572 :           int kk=dd_gatindex[i];
+    1007       35572 :           dd_coordinates[3*i+0]=coordinates[3*kk+0];
+    1008       35572 :           dd_coordinates[3*i+1]=coordinates[3*kk+1];
+    1009       35572 :           dd_coordinates[3*i+2]=coordinates[3*kk+2];
+    1010             :         }
+    1011        1764 :         p.cmd("setForces",&dd_forces[0],3*dd_nlocal);
+    1012        1764 :         p.cmd("setPositions",&dd_coordinates[0],3*dd_nlocal);
+    1013        1764 :         p.cmd("setMasses",&dd_masses[0],dd_nlocal);
+    1014        1764 :         p.cmd("setCharges",&dd_charges[0],dd_nlocal);
+    1015             :       } else {
+    1016             : // this is required to avoid troubles when the last domain
+    1017             : // contains zero atoms
+    1018             : // Basically, for empty domains we pass null pointers
+    1019             : #define fix_pd(xx) (pd_nlocal!=0?&xx:NULL)
+    1020       83948 :         p.cmd("setForces",fix_pd(forces[3*pd_start]),3*pd_nlocal);
+    1021       83948 :         p.cmd("setPositions",fix_pd(coordinates[3*pd_start]),3*pd_nlocal);
+    1022       83948 :         p.cmd("setMasses",fix_pd(masses[pd_start]),pd_nlocal);
+    1023       83948 :         p.cmd("setCharges",fix_pd(charges[pd_start]),pd_nlocal);
+    1024             :       }
+    1025       43738 :       p.cmd("setBox",cell.data(),9);
+    1026       43738 :       p.cmd("setVirial",virial.data(),9);
+    1027             :     } else {
+    1028      200340 :       p.cmd("setStepLongLong",step);
+    1029      200340 :       p.cmd("setStopFlag",&plumedStopCondition);
+    1030             :     }
+    1031      244078 :     p.cmd("calc");
+    1032      244078 :     if(debugforces.length()>0) {
+    1033          25 :       virial.assign(9,real(0.0));
+    1034          25 :       forces.assign(3*natoms,real(0.0));
+    1035          25 :       p.cmd("prepareCalc");
+    1036          25 :       p.cmd("performCalcNoUpdate");
+    1037             :     }
+    1038             : 
+    1039             : // this is necessary as only processor zero is adding to the virial:
+    1040      244078 :     intracomm.Bcast(virial,0);
+    1041      244078 :     if(debug_pd) intracomm.Sum(forces);
+    1042      244078 :     if(debug_dd) {
+    1043       37336 :       for(int i=0; i<dd_nlocal; i++) {
+    1044       35572 :         forces[3*dd_gatindex[i]+0]=dd_forces[3*i+0];
+    1045       35572 :         forces[3*dd_gatindex[i]+1]=dd_forces[3*i+1];
+    1046       35572 :         forces[3*dd_gatindex[i]+2]=dd_forces[3*i+2];
+    1047             :       }
+    1048        1764 :       dd_forces.assign(3*natoms,0.0);
+    1049        1764 :       intracomm.Sum(forces);
+    1050             :     }
+    1051      244078 :     if(debug_grex &&step%grex_stride==0) {
+    1052         114 :       p.cmd("GREX savePositions");
+    1053         114 :       if(intracomm.Get_rank()>0) {
+    1054          57 :         p.cmd("GREX prepare");
+    1055             :       } else {
+    1056          57 :         int r=intercomm.Get_rank();
+    1057          57 :         int n=intercomm.Get_size();
+    1058          57 :         int partner=r+(2*((r+step/grex_stride)%2))-1;
+    1059             :         if(partner<0)partner=0;
+    1060          57 :         if(partner>=n) partner=n-1;
+    1061          57 :         p.cmd("GREX setPartner",partner);
+    1062          57 :         p.cmd("GREX calculate");
+    1063          57 :         p.cmd("GREX shareAllDeltaBias");
+    1064         228 :         for(int i=0; i<n; i++) {
+    1065         171 :           std::string s; Tools::convert(i,s);
+    1066         342 :           real a=std::numeric_limits<real>::quiet_NaN(); s="GREX getDeltaBias "+s; p.cmd(s,&a);
+    1067         171 :           if(grex_log) std::fprintf(grex_log," %f",a);
+    1068             :         }
+    1069          57 :         if(grex_log) std::fprintf(grex_log,"\n");
+    1070             :       }
+    1071             :     }
+    1072             : 
+    1073             : 
+    1074      244078 :     if(fp_forces) {
+    1075       22241 :       std::fprintf(fp_forces,"%d\n",natoms);
+    1076       44482 :       std::string fmtv=dumpforcesFmt+" "+dumpforcesFmt+" "+dumpforcesFmt+" "+dumpforcesFmt+" "+dumpforcesFmt+" "+dumpforcesFmt+" "+dumpforcesFmt+" "+dumpforcesFmt+" "+dumpforcesFmt+"\n";
+    1077       44482 :       std::string fmt=dumpforcesFmt+" "+dumpforcesFmt+" "+dumpforcesFmt+"\n";
+    1078       22241 :       if(dumpfullvirial) {
+    1079         350 :         std::fprintf(fp_forces,fmtv.c_str(),virial[0],virial[1],virial[2],virial[3],virial[4],virial[5],virial[6],virial[7],virial[8]);
+    1080             :       } else {
+    1081       21891 :         std::fprintf(fp_forces,fmt.c_str(),virial[0],virial[4],virial[8]);
+    1082             :       }
+    1083       22241 :       fmt="X "+fmt;
+    1084     2152406 :       for(int i=0; i<natoms; i++)
+    1085     2130165 :         std::fprintf(fp_forces,fmt.c_str(),forces[3*i],forces[3*i+1],forces[3*i+2]);
+    1086             :     }
+    1087      244078 :     if(debugforces.length()>0) {
+    1088             :       // Now call the routine to work out the derivatives numerically
+    1089          25 :       numder.assign(3*natoms+9,real(0.0)); real base=0;
+    1090          25 :       p.cmd("getBias",&base);
+    1091          25 :       if( std::abs(base)<epsilon ) printf("WARNING: bias for configuration appears to be zero so debugging forces is trivial");
+    1092          25 :       evaluateNumericalDerivatives( step, p, coordinates, masses, charges, cell, base, numder );
+    1093             : 
+    1094             :       // And output everything to a file
+    1095          25 :       fp_dforces.fmtField(" " + dumpforcesFmt);
+    1096        1795 :       for(int i=0; i<3*natoms; ++i) {
+    1097        1770 :         fp_dforces.printField("parameter",(int)i);
+    1098        3540 :         fp_dforces.printField("analytical",forces[i]);
+    1099        1770 :         fp_dforces.printField("numerical",-numder[i]);
+    1100        1770 :         fp_dforces.printField();
+    1101             :       }
+    1102             :       // And print the virial
+    1103         250 :       for(int i=0; i<9; ++i) {
+    1104         225 :         fp_dforces.printField("parameter",3*natoms+i );
+    1105         225 :         fp_dforces.printField("analytical",virial[i] );
+    1106         225 :         fp_dforces.printField("numerical",-numder[3*natoms+i]);
+    1107         225 :         fp_dforces.printField();
+    1108             :       }
+    1109             :     }
+    1110             : 
+    1111      244078 :     if(plumedStopCondition) break;
+    1112             : 
+    1113      244020 :     step+=stride;
+    1114             :   }
+    1115         808 :   if(!parseOnly) p.cmd("runFinalJobs");
+    1116             : 
+    1117             :   return 0;
+    1118        3232 : }
+    1119             : 
+    1120             : template<typename real>
+    1121          25 : void Driver<real>::evaluateNumericalDerivatives( const long long int& step, PlumedMain& p, const std::vector<real>& coordinates,
+    1122             :     const std::vector<real>& masses, const std::vector<real>& charges,
+    1123             :     std::vector<real>& cell, const double& base, std::vector<real>& numder ) {
+    1124             : 
+    1125          25 :   int natoms = coordinates.size() / 3; real delta = std::sqrt(epsilon);
+    1126          25 :   std::vector<Vector> pos(natoms); real bias=0;
+    1127          25 :   std::vector<real> fake_forces( 3*natoms ), fake_virial(9);
+    1128         615 :   for(int i=0; i<natoms; ++i) {
+    1129        2360 :     for(unsigned j=0; j<3; ++j) pos[i][j]=coordinates[3*i+j];
+    1130             :   }
+    1131             : 
+    1132         615 :   for(int i=0; i<natoms; ++i) {
+    1133        2360 :     for(unsigned j=0; j<3; ++j) {
+    1134        1770 :       pos[i][j]=pos[i][j]+delta;
+    1135        1770 :       p.cmd("setStepLongLong",step);
+    1136        1770 :       p.cmd("setPositions",&pos[0][0],3*natoms);
+    1137        1770 :       p.cmd("setForces",&fake_forces[0],3*natoms);
+    1138        1770 :       p.cmd("setMasses",&masses[0],natoms);
+    1139        1770 :       p.cmd("setCharges",&charges[0],natoms);
+    1140        1770 :       p.cmd("setBox",&cell[0],9);
+    1141        1770 :       p.cmd("setVirial",&fake_virial[0],9);
+    1142        1770 :       p.cmd("prepareCalc");
+    1143        1770 :       p.cmd("performCalcNoUpdate");
+    1144        1770 :       p.cmd("getBias",&bias);
+    1145        1770 :       pos[i][j]=coordinates[3*i+j];
+    1146        1770 :       numder[3*i+j] = (bias - base) / delta;
+    1147             :     }
+    1148             :   }
+    1149             : 
+    1150             :   // Create the cell
+    1151          25 :   Tensor box( cell[0], cell[1], cell[2], cell[3], cell[4], cell[5], cell[6], cell[7], cell[8] );
+    1152             :   // And the virial
+    1153          25 :   Pbc pbc; pbc.setBox( box ); Tensor nvirial;
+    1154         325 :   for(unsigned i=0; i<3; i++) for(unsigned k=0; k<3; k++) {
+    1155         225 :       double arg0=box(i,k);
+    1156        5535 :       for(int j=0; j<natoms; ++j) pos[j]=pbc.realToScaled( pos[j] );
+    1157         225 :       cell[3*i+k]=box(i,k)=box(i,k)+delta; pbc.setBox(box);
+    1158        5535 :       for(int j=0; j<natoms; j++) pos[j]=pbc.scaledToReal( pos[j] );
+    1159         225 :       p.cmd("setStepLongLong",step);
+    1160         225 :       p.cmd("setPositions",&pos[0][0],3*natoms);
+    1161         225 :       p.cmd("setForces",&fake_forces[0],3*natoms);
+    1162         225 :       p.cmd("setMasses",&masses[0],natoms);
+    1163         225 :       p.cmd("setCharges",&charges[0],natoms);
+    1164         225 :       p.cmd("setBox",&cell[0],9);
+    1165         225 :       p.cmd("setVirial",&fake_virial[0],9);
+    1166         225 :       p.cmd("prepareCalc");
+    1167         225 :       p.cmd("performCalcNoUpdate");
+    1168         225 :       p.cmd("getBias",&bias);
+    1169         225 :       cell[3*i+k]=box(i,k)=arg0; pbc.setBox(box);
+    1170       21465 :       for(int j=0; j<natoms; j++) for(unsigned n=0; n<3; ++n) pos[j][n]=coordinates[3*j+n];
+    1171         225 :       nvirial(i,k) = ( bias - base ) / delta;
+    1172             :     }
+    1173          25 :   nvirial=-matmul(box.transpose(),nvirial);
+    1174         325 :   for(unsigned i=0; i<3; i++) for(unsigned k=0; k<3; k++)  numder[3*natoms+3*i+k] = nvirial(i,k);
+    1175             : 
+    1176          25 : }
+    1177             : 
+    1178             : }
+    1179             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverDouble.cpp.func-sort-c.html b/coverage/cltools/DriverDouble.cpp.func-sort-c.html new file mode 100644 index 000000000000..55bd8afcd979 --- /dev/null +++ b/coverage/cltools/DriverDouble.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - cltools/DriverDouble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverDouble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMe6createERKNS_13CLToolOptionsE812
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverDouble.cpp.func.html b/coverage/cltools/DriverDouble.cpp.func.html new file mode 100644 index 000000000000..1828519ca62a --- /dev/null +++ b/coverage/cltools/DriverDouble.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - cltools/DriverDouble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverDouble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMe6createERKNS_13CLToolOptionsE812
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_122DriverDoubleRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverDouble.cpp.gcov.html b/coverage/cltools/DriverDouble.cpp.gcov.html new file mode 100644 index 000000000000..67aca33af64a --- /dev/null +++ b/coverage/cltools/DriverDouble.cpp.gcov.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - cltools/DriverDouble.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverDouble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Driver.cpp"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace cltools {
+      27             : 
+      28             : // We instantiate here the template version of Driver so as
+      29             : // to accelerate parallel compilation.
+      30             : 
+      31             : typedef Driver<double> DriverDouble;
+      32             : 
+      33       13373 : PLUMED_REGISTER_CLTOOL(DriverDouble,"driver")
+      34             : 
+      35             : }
+      36             : }
+      37             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverFloat.cpp.func-sort-c.html b/coverage/cltools/DriverFloat.cpp.func-sort-c.html new file mode 100644 index 000000000000..d396fc84d3aa --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - cltools/DriverFloat.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverFloat.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMe6createERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools6DriverIfE11descriptionB5cxx11Ev4
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverFloat.cpp.func.html b/coverage/cltools/DriverFloat.cpp.func.html new file mode 100644 index 000000000000..b444d4e1eecb --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - cltools/DriverFloat.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverFloat.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_121DriverFloatRegisterMeD2Ev4187
_ZNK4PLMD7cltools6DriverIfE11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/DriverFloat.cpp.gcov.html b/coverage/cltools/DriverFloat.cpp.gcov.html new file mode 100644 index 000000000000..d8c35bc8d774 --- /dev/null +++ b/coverage/cltools/DriverFloat.cpp.gcov.html @@ -0,0 +1,119 @@ + + + + + + + + LCOV - plumed test coverage - cltools/DriverFloat.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - DriverFloat.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Driver.cpp"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace cltools {
+      27             : 
+      28             : // We instantiate here the template version of Driver so as
+      29             : // to accelerate parallel compilation.
+      30             : 
+      31             : typedef Driver<float> DriverFloat;
+      32             : 
+      33             : /// Specialized version
+      34             : template<>
+      35           4 : std::string Driver<float>::description()const { return "analyze trajectories with plumed (single precision version)"; }
+      36             : 
+      37             : 
+      38       12565 : PLUMED_REGISTER_CLTOOL(DriverFloat,"driver-float")
+      39             : 
+      40             : }
+      41             : }
+      42             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenExample.cpp.func-sort-c.html b/coverage/cltools/GenExample.cpp.func-sort-c.html new file mode 100644 index 000000000000..f2b18294a8b6 --- /dev/null +++ b/coverage/cltools/GenExample.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenExample.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenExample.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:172207.7 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools10GenExample15createLongInputERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EE0
_ZN4PLMD7cltools10GenExample17printExampleInputERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EERKS8_SG_RSt14basic_ofstreamIcS6_E0
_ZN4PLMD7cltools10GenExample4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools10GenExampleC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMe6createERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools10GenExample11descriptionB5cxx11Ev4
_ZN4PLMD7cltools10GenExample16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenExample.cpp.func.html b/coverage/cltools/GenExample.cpp.func.html new file mode 100644 index 000000000000..57a0b7780f65 --- /dev/null +++ b/coverage/cltools/GenExample.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenExample.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenExample.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:172207.7 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools10GenExample15createLongInputERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EE0
_ZN4PLMD7cltools10GenExample16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools10GenExample17printExampleInputERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EERKS8_SG_RSt14basic_ofstreamIcS6_E0
_ZN4PLMD7cltools10GenExample4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools10GenExampleC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_120GenExampleRegisterMeD2Ev4187
_ZNK4PLMD7cltools10GenExample11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenExample.cpp.gcov.html b/coverage/cltools/GenExample.cpp.gcov.html new file mode 100644 index 000000000000..16b43e2daa78 --- /dev/null +++ b/coverage/cltools/GenExample.cpp.gcov.html @@ -0,0 +1,428 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenExample.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenExample.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:172207.7 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2019-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "config/Config.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/ActionWithValue.h"
+      28             : #include "core/ActionWithVirtualAtom.h"
+      29             : #include "core/ActionShortcut.h"
+      30             : #include "core/ActionSet.h"
+      31             : #include "core/PlumedMain.h"
+      32             : #include "tools/Communicator.h"
+      33             : #include "tools/IFile.h"
+      34             : #include <cstdio>
+      35             : #include <string>
+      36             : #include <vector>
+      37             : #include <iostream>
+      38             : #include <fstream>
+      39             : 
+      40             : namespace PLMD {
+      41             : namespace cltools {
+      42             : 
+      43             : //+PLUMEDOC TOOLS gen_example
+      44             : /*
+      45             : gen_example is a tool that you can use to construct an example for the manual that users can interact with to understand
+      46             : 
+      47             : The example constructed by this action is in html. In all probability you will never need to use this
+      48             : tool. However, it is used within the scripts that generate the html manual for PLUMED.  If you need to use this
+      49             : tool outside those scripts the input is specified using the following command line arguments.
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : The following generates an example based on the contents of the plumed file plumed.dat
+      54             : \verbatim
+      55             : plumed gen_example --plumed plumed.dat --status working
+      56             : \endverbatim
+      57             : 
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : class GenExample:
+      63             :   public CLTool
+      64             : {
+      65             : private:
+      66             :   int multi;
+      67             :   std::string status, version;
+      68             :   Communicator intracomm;
+      69             :   Communicator intercomm;
+      70             : public:
+      71             :   static void registerKeywords( Keywords& keys );
+      72             :   explicit GenExample(const CLToolOptions& co );
+      73             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+      74           4 :   std::string description()const override {
+      75           4 :     return "construct an example for the manual that users can interact with";
+      76             :   }
+      77             :   void printExampleInput( const std::vector<std::vector<std::string> >& input, const std::string& egname, const std::string& divname, std::ofstream& ofile );
+      78             :   std::vector<std::vector<std::string> > createLongInput( const std::vector<std::vector<std::string> >& input );
+      79             : };
+      80             : 
+      81       12565 : PLUMED_REGISTER_CLTOOL(GenExample,"gen_example")
+      82             : 
+      83        4187 : void GenExample::registerKeywords( Keywords& keys ) {
+      84        4187 :   CLTool::registerKeywords( keys );
+      85        8374 :   keys.add("compulsory","--plumed","plumed.dat","convert the input in this file to the html manual");
+      86        8374 :   keys.add("compulsory","--out","example.html","the file on which to output the example in html");
+      87        8374 :   keys.add("compulsory","--name","ppp","the name to use for this particular input");
+      88        8374 :   keys.add("compulsory","--status","nobadge","whether or not the input file works");
+      89        8374 :   keys.add("compulsory","--multi","0","set number of replicas for multi environment (needs MPI)");
+      90        4187 : }
+      91             : 
+      92           4 : GenExample::GenExample(const CLToolOptions& co ):
+      93             :   CLTool(co),
+      94           4 :   multi(0),
+      95           8 :   status("nobadge"),
+      96           4 :   version("master")
+      97             : {
+      98           4 :   inputdata=commandline;
+      99           4 : }
+     100             : 
+     101           0 : int GenExample::main(FILE* in, FILE*out,Communicator& pc) {
+     102             : 
+     103             : // set up for multi replica driver:
+     104           0 :   parse("--multi",multi);
+     105           0 :   if(multi) {
+     106           0 :     int ntot=pc.Get_size(); int nintra=ntot/multi;
+     107           0 :     if(multi*nintra!=ntot) error("invalid number of processes for multi environment");
+     108           0 :     pc.Split(pc.Get_rank()/nintra,pc.Get_rank(),intracomm);
+     109           0 :     pc.Split(pc.Get_rank()%nintra,pc.Get_rank(),intercomm);
+     110             :   } else {
+     111           0 :     intracomm.Set_comm(pc.Get_comm());
+     112             :   }
+     113             : 
+     114           0 :   if( config::getVersionLong().find("dev")==std::string::npos ) version="v"+config::getVersion();
+     115           0 :   std::string fname, egname, outfile; parse("--plumed",fname);
+     116           0 :   parse("--name",egname); parse("--out",outfile); parse("--status",status);
+     117             : 
+     118           0 :   int r=0;
+     119           0 :   if(intracomm.Get_rank()==0) r=intercomm.Get_rank();
+     120           0 :   intracomm.Bcast(r,0);
+     121           0 :   if(r>0) outfile="/dev/null";
+     122             : 
+     123           0 :   IFile ifile; ifile.open(fname); ifile.allowNoEOL(); std::ofstream ofile; ofile.open(outfile); std::vector<bool> shortcuts;
+     124             :   bool hasshortcuts=false, endplumed=false; std::vector<std::vector<std::string> > input; std::vector<std::string> words;
+     125           0 :   while( Tools::getParsedLine(ifile, words, false) ) {
+     126           0 :     input.push_back( words ); shortcuts.push_back( false );
+     127           0 :     if( words.empty() || words[0].find("#")!=std::string::npos || endplumed ) continue;
+     128           0 :     std::vector<std::string> interpreted( words ); Tools::interpretLabel(interpreted);
+     129           0 :     if( interpreted[0]=="ENDPLUMED" ) { endplumed=true; continue; }
+     130           0 :     Keywords keys; actionRegister().getKeywords( interpreted[0], keys );
+     131           0 :     if( status=="working" && keys.exists("IS_SHORTCUT") ) hasshortcuts=shortcuts[shortcuts.size()-1]=true;
+     132           0 :   }
+     133           0 :   ifile.close();
+     134           0 :   if( hasshortcuts ) {
+     135           0 :     ofile<<"<div style=\"width: 80%; float:left\" id=\"value_details_"<<egname<<"\"> Click on the labels of the actions for more information on what each action computes </div>\n";
+     136           0 :     ofile<<"<div style=\"width: 10%; float:left\"><button type=\"button\" id=\""<<egname<<"_button\" onclick=\'swapInput(\""<<egname<<"\")\'>contract shortcuts</button></div>";
+     137             :   } else {
+     138           0 :     ofile<<"<div style=\"width: 90%; float:left\" id=\"value_details_"<<egname<<"\"> Click on the labels of the actions for more information on what each action computes </div>\n";
+     139             :   }
+     140           0 :   ofile<<"<div style=\"width: 10%; float:left\">";
+     141           0 :   ofile<<"<img src=\"https://img.shields.io/badge/";
+     142           0 :   if(status=="working") ofile<<version<<"-passing-green";
+     143           0 :   else if(status=="broken") ofile<<version<<"-failed-red";
+     144           0 :   else if(status=="loads") ofile<<"with-LOAD-yellow";
+     145           0 :   else if(status=="incomplete") ofile<<version<<"-incomplete-yellow";
+     146           0 :   else error("unknown status");
+     147           0 :   ofile<<".svg\" alt=\"tested on "<<version<<"\" /></div>";
+     148           0 :   ofile.flush();
+     149           0 :   if( hasshortcuts ) {
+     150             :     // Write out the short version of the input
+     151           0 :     ofile<<"<div style=\"width: 100%; float:left\" id=\"input_"<<egname<<"\"></div>"<<std::endl;
+     152             :     // Write an extra pre to make sure the html after the example is put in the right place on the page
+     153           0 :     ofile<<"<pre style=\"width: 97%;\" class=\"fragment\"></pre>"<<std::endl;
+     154           0 :     ofile<<"<script type=\"text/javascript\">"<<std::endl;
+     155           0 :     ofile<<"if (window.addEventListener) { // Mozilla, Netscape, Firefox"<<std::endl;
+     156           0 :     ofile<<"    window.addEventListener('load', "<<egname<<"Load, false);"<<std::endl;
+     157           0 :     ofile<<"} else if (window.attachEvent) { // IE"<<std::endl;
+     158           0 :     ofile<<"    window.attachEvent('onload', "<<egname<<"Load);"<<std::endl;
+     159           0 :     ofile<<"}"<<std::endl;
+     160           0 :     ofile<<"function "<<egname<<"Load(event) {"<<std::endl;
+     161           0 :     ofile<<"       swapInput(\""<<egname<<"\");"<<std::endl;
+     162           0 :     ofile<<"}"<<std::endl;
+     163           0 :     ofile<<"</script>"<<std::endl;
+     164           0 :     ofile<<"<div style=\"display:none;\" id=\""<<egname<<"short\">"<<std::endl;
+     165           0 :     printExampleInput( input, egname + "short", egname, ofile );
+     166           0 :     ofile<<"</div>"<<std::endl;
+     167             :     // Write out long version of the input
+     168           0 :     ofile<<"<div style=\"display:none;\" id=\""<<egname<<"long\">";
+     169           0 :     std::vector<std::vector<std::string> > long_input = createLongInput( input );
+     170           0 :     printExampleInput( long_input, egname + "long", egname, ofile );
+     171           0 :     ofile<<"</div>"<<std::endl;
+     172           0 :   } else printExampleInput( input, egname, egname, ofile );
+     173           0 :   ofile.close(); return 0;
+     174           0 : }
+     175             : 
+     176           0 : std::vector<std::vector<std::string> > GenExample::createLongInput( const std::vector<std::vector<std::string> >& input ) {
+     177           0 :   std::vector<std::vector<std::string> > long_input; PlumedMain myplumed; int rr=sizeof(double), natoms=10000000; double kt=2.49;
+     178           0 :   myplumed.cmd("setRealPrecision",&rr);
+     179           0 :   if(Communicator::initialized()) {
+     180           0 :     if(multi) {
+     181           0 :       if(intracomm.Get_rank()==0) myplumed.cmd("GREX setMPIIntercomm",&intercomm.Get_comm());
+     182           0 :       myplumed.cmd("GREX setMPIIntracomm",&intracomm.Get_comm()); myplumed.cmd("GREX init");
+     183             :     }
+     184           0 :     myplumed.cmd("setMPIComm",&intracomm.Get_comm());
+     185             :   }
+     186           0 :   bool endplumed=false; myplumed.cmd("setNatoms",&natoms); myplumed.cmd("setKbT",&kt); myplumed.cmd("init");
+     187           0 :   for(unsigned ll=0; ll<input.size(); ++ll) {
+     188           0 :     if( input[ll].empty() || endplumed ) { long_input.push_back( input[ll] ); continue; }
+     189           0 :     if( input[ll][0].find("#")!=std::string::npos ) { long_input.push_back( input[ll] ); continue; }
+     190           0 :     std::vector<std::string> interpreted( input[ll] ); Tools::interpretLabel(interpreted);
+     191           0 :     if( interpreted[0]=="ENDPLUMED" ) { endplumed=true; long_input.push_back( input[ll] ); continue; }
+     192           0 :     Keywords keys; plumed_assert( actionRegister().check( interpreted[0] ) );
+     193           0 :     actionRegister().getKeywords( interpreted[0], keys ); std::string lab, myinputline;
+     194           0 :     if( Tools::parse(interpreted, "LABEL", lab ) ) myinputline = lab + ": ";
+     195           0 :     myinputline += interpreted[0] + " "; bool trailingcomment=false;
+     196           0 :     for(unsigned i=1; i<interpreted.size(); ++i) {
+     197           0 :       if( trailingcomment && interpreted[i]=="@newline") { trailingcomment=false; continue; }
+     198           0 :       if( interpreted[i].find("#")!=std::string::npos ) { trailingcomment=true; continue; }
+     199           0 :       if( interpreted[i]=="@newline" || interpreted[i]=="..." ) continue;
+     200           0 :       std::size_t pos = 0;  while ((pos = interpreted[i].find("@newline",pos)) != std::string::npos) { interpreted[i].replace(pos, 8, "\n"); pos++; }
+     201           0 :       myinputline += interpreted[i] + " ";
+     202             :     }
+     203           0 :     if( status=="working" && keys.exists("IS_SHORTCUT") ) {
+     204           0 :       myplumed.readInputLine( myinputline );
+     205           0 :       ActionShortcut* as=myplumed.getActionSet()[myplumed.getActionSet().size()-1].get()->castToActionShortcut();
+     206           0 :       plumed_assert( as ); std::vector<std::string> shortcut_commands = as->getSavedInputLines();
+     207           0 :       for(unsigned i=0; i<shortcut_commands.size(); ++i) {
+     208           0 :         std::vector<std::string> words = Tools::getWords( shortcut_commands[i] ); long_input.push_back( words );
+     209           0 :       }
+     210           0 :     } else { long_input.push_back( input[ll] ); myplumed.readInputLine( myinputline ); }
+     211           0 :   }
+     212           0 :   return long_input;
+     213           0 : }
+     214             : 
+     215           0 : void GenExample::printExampleInput( const std::vector<std::vector<std::string> >& input, const std::string& egname, const std::string& divname, std::ofstream& ofile ) {
+     216           0 :   PlumedMain myplumed; int rr=sizeof(double), natoms=10000000; double kt=2.49;
+     217           0 :   myplumed.cmd("setRealPrecision",&rr);
+     218           0 :   if(Communicator::initialized()) {
+     219           0 :     if(multi) {
+     220           0 :       if(intracomm.Get_rank()==0) myplumed.cmd("GREX setMPIIntercomm",&intercomm.Get_comm());
+     221           0 :       myplumed.cmd("GREX setMPIIntracomm",&intracomm.Get_comm()); myplumed.cmd("GREX init");
+     222             :     }
+     223           0 :     myplumed.cmd("setMPIComm",&intracomm.Get_comm());
+     224             :   }
+     225           0 :   myplumed.cmd("setNatoms",&natoms); myplumed.cmd("setKbT",&kt); myplumed.cmd("init");
+     226             :   std::vector<std::string> labellist; bool endplumed=false;
+     227           0 :   ofile<<"<pre style=\"width: 97%;\" class=\"fragment\">"<<std::endl;
+     228           0 :   for(unsigned ll=0; ll<input.size(); ++ll) {
+     229           0 :     if( input[ll].empty() ) { ofile<<std::endl; continue; }
+     230           0 :     if( input[ll][0].find("#")!=std::string::npos || endplumed ) {
+     231           0 :       ofile<<"<span style=\"color:blue\">"<<input[ll][0];
+     232           0 :       for(unsigned i=1; i<input[ll].size(); ++i) ofile<<" "<<input[ll][i];
+     233           0 :       ofile<<"</span>"<<std::endl;;
+     234             :     } else {
+     235             :       // Interpret the label if this needs to be done
+     236           0 :       std::vector<std::string> interpreted( input[ll] ); Tools::interpretLabel(interpreted); std::string lab, myinputline;
+     237             :       // Now read in the label
+     238           0 :       if( Tools::parse(interpreted,"LABEL",lab) ) {
+     239           0 :         ofile<<"<b name=\""<<egname<<lab<<"\" onclick=\'showPath(\""<<divname<<"\",\""<<egname<<lab<<"\")\'>"<<lab<<": </b>";
+     240           0 :         labellist.push_back(lab); myinputline = lab + ": ";
+     241             :       }
+     242             :       // Print the keyword in use in the action
+     243           0 :       std::string action = interpreted[0]; myinputline += interpreted[0] + " ";
+     244           0 :       if( action=="ENDPLUMED" ) endplumed=true;
+     245           0 :       Keywords keys; actionRegister().getKeywords( interpreted[0], keys );
+     246             :       // Handle conversion of action names to links
+     247           0 :       std::transform(action.begin(), action.end(), action.begin(), [](unsigned char c) { return std::tolower(c); });
+     248           0 :       ofile<<"<a href=\"https://www.plumed.org/doc-"<<version<<"/user-doc/html/";
+     249             :       for(unsigned n=0;; ++n) {
+     250           0 :         std::size_t und=action.find_first_of("_");
+     251           0 :         if( und==std::string::npos ) break;
+     252           0 :         std::string first=action.substr(0,und);
+     253           0 :         for(auto c : first ) { if( isdigit(c) ) ofile<<c; else ofile<<"_"<<c; }
+     254           0 :         ofile<<"_"; action=action.substr(und+1);
+     255           0 :       }
+     256           0 :       for(auto c : action ) { if( isdigit(c) ) ofile<<c; else ofile<<"_"<<c; }
+     257           0 :       ofile<<".html\" style=\"color:green\">"<<interpreted[0]<<"</a> ";
+     258             :       // And write out everything else in the input line
+     259             :       bool trailingcomment=false;
+     260           0 :       for(unsigned i=1; i<interpreted.size(); ++i) {
+     261           0 :         if( interpreted[i]=="@newline" && i==1 ) { ofile<<"..."<<std::endl<<"   "; continue; }
+     262           0 :         else if( interpreted[i]=="@newline" ) {
+     263           0 :           if( trailingcomment ) { ofile<<"</span>"; trailingcomment=false; }
+     264           0 :           if( interpreted[i+1]=="..." ) ofile<<std::endl;
+     265           0 :           else ofile<<std::endl<<"   ";
+     266           0 :           continue;
+     267           0 :         } else if( interpreted[i]=="__FILL__" ) {
+     268           0 :           if( status!="incomplete" ) error("found __FILL__ statement but status is " + status);
+     269           0 :           ofile<<"<span style=\"background-color:yellow\">__FILL__</span>";
+     270           0 :           continue;
+     271           0 :         } else if( interpreted[i]==action ) continue;
+     272           0 :         if( interpreted[i].find("#")!=std::string::npos ) { trailingcomment=true; ofile<<"<span style=\"color:blue\">"; }
+     273             : 
+     274           0 :         if( !trailingcomment ) {
+     275           0 :           std::size_t eq=interpreted[i].find_first_of("=");
+     276           0 :           if( eq!=std::string::npos ) {
+     277           0 :             std::string keyword=interpreted[i].substr(0,eq), rest=interpreted[i].substr(eq+1);
+     278           0 :             ofile<<"<div class=\"tooltip\">"<<keyword<<"<div class=\"right\">"<<keys.getTooltip(keyword)<<"<i></i></div></div>";
+     279           0 :             if( rest=="__FILL__" ) {
+     280           0 :               if( status!="incomplete" ) error("found __FILL__ statement but status is " + status);
+     281           0 :               ofile<<"=<span style=\"background-color:yellow\">__FILL__</span>";
+     282           0 :             } else if( rest.find_first_of("{")!=std::string::npos ) {
+     283           0 :               std::size_t pos = 0;  while ((pos = rest.find("@newline",pos)) != std::string::npos) { rest.replace(pos, 8, "\n"); pos++; }
+     284           0 :               ofile<<"="<<rest<<" "; myinputline += keyword + "=" + rest + " ";
+     285             :             } else {
+     286           0 :               std::vector<std::string> args=Tools::getWords(rest,"\t\n ,"); ofile<<"=";
+     287           0 :               for(unsigned i=0; i<args.size(); ++i) {
+     288             :                 bool islabel=false; std::string thislab;
+     289           0 :                 for(unsigned j=0; j<labellist.size(); ++j) {
+     290           0 :                   std::size_t dot=args[i].find_first_of("."); std::string lll=args[i].substr(0,dot);
+     291           0 :                   if( lll==labellist[j] ) { islabel=true; thislab=labellist[j]; break; }
+     292             :                 }
+     293           0 :                 if( islabel ) ofile<<"<b name=\""<<egname<<thislab<<"\">"<<args[i]<<"</b>";
+     294             :                 else ofile<<args[i];
+     295           0 :                 if( i!=args.size()-1 ) ofile<<",";
+     296             :               }
+     297           0 :               myinputline += interpreted[i] + " ";
+     298           0 :             }
+     299           0 :             ofile<<" ";
+     300           0 :           } else if( interpreted[i]!="@newline" && interpreted[i]!="..." ) {
+     301           0 :             myinputline += interpreted[i] + " ";
+     302           0 :             ofile<<"<div class=\"tooltip\">"<<interpreted[i]<<"<div class=\"right\">"<<keys.getTooltip(interpreted[i])<<"<i></i></div></div> ";
+     303           0 :           } else if( interpreted[i]=="..." ) ofile<<"...";
+     304           0 :         } else ofile<<interpreted[i]<<" ";
+     305             :       }
+     306           0 :       if( trailingcomment ) ofile<<"</span>";
+     307             :       // This builds the hidden content that tells the user about what is calculated
+     308           0 :       if( status=="working" ) {
+     309           0 :         ofile<<"<span style=\"display:none;\" id=\""<<egname<<lab<<"\">";
+     310           0 :         ofile<<"The "<<interpreted[0]<<" action with label <b>"<<lab<<"</b>";
+     311           0 :         myplumed.readInputLine( myinputline );
+     312           0 :         ActionWithValue* av=myplumed.getActionSet().selectWithLabel<Action*>(lab)->castToActionWithValue();
+     313           0 :         if( av ) {
+     314           0 :           if( av->getNumberOfComponents()==1 ) { ofile<<" calculates a single scalar value"; }
+     315           0 :           else if( av->getNumberOfComponents()>0 ) {
+     316           0 :             ofile<<" calculates the following quantities:"<<std::endl;
+     317           0 :             ofile<<"<table  align=\"center\" frame=\"void\" width=\"95%%\" cellpadding=\"5%%\">"<<std::endl;
+     318           0 :             ofile<<"<tr><td width=\"5%%\"><b> Quantity </b>  </td><td><b> Description </b> </td></tr>"<<std::endl;
+     319           0 :             unsigned ncomp = av->getNumberOfComponents();
+     320           0 :             for(unsigned k=0; k<ncomp; ++k ) {
+     321           0 :               std::string myname = av->copyOutput(k)->getName(); std::size_t dot=myname.find_first_of(".");
+     322           0 :               std::string tname=myname.substr(dot+1); std::size_t und=tname.find_last_of("_"); std::size_t hyph=tname.find_first_of("-");
+     323           0 :               if( und!=std::string::npos && hyph!=std::string::npos ) plumed_merror("cannot use underscore and hyphen in name");
+     324           0 :               ofile<<"<tr><td width=\"5%%\">"<<myname<<"</td><td>";
+     325           0 :               if( und!=std::string::npos ) {
+     326           0 :                 ofile<<keys.getOutputComponentDescription(tname.substr(und))<<" This particular component measures this quantity for the input CV named ";
+     327           0 :                 ofile<<tname.substr(0,und);
+     328           0 :               } else if( hyph!=std::string::npos ) {
+     329           0 :                 ofile<<keys.getOutputComponentDescription(tname.substr(0,hyph))<<"  This is the "<<tname.substr(hyph+1)<<"th of these quantities";
+     330           0 :               } else ofile<<keys.getOutputComponentDescription(tname);
+     331           0 :               ofile<<"</td></tr>"<<std::endl;
+     332             :             }
+     333           0 :             ofile<<"</table>"<<std::endl;
+     334             :           }
+     335             :         } else {
+     336           0 :           ActionWithVirtualAtom* avv=myplumed.getActionSet().selectWithLabel<Action*>(lab)->castToActionWithVirtualAtom();
+     337           0 :           if( avv ) ofile<<" calculates the position of a virtual atom";
+     338           0 :           else if( interpreted[0]=="GROUP" ) ofile<<" defines a group of atoms so that they can be referred to later in the input";
+     339             :         }
+     340           0 :         ofile<<"</span>"<<std::endl;
+     341             :       } else {
+     342           0 :         ofile<<"<span style=\"display:none;\" id=\""<<egname<<lab<<"\"> You cannot view the components that are calculated by each action for this input file. Sorry </span>"<<std::endl;
+     343             :       }
+     344           0 :     }
+     345           0 :     ofile.flush();
+     346             :   }
+     347           0 :   ofile<<"</pre>"<<std::endl;
+     348           0 : }
+     349             : 
+     350             : } // End of namespace
+     351             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenJson.cpp.func-sort-c.html b/coverage/cltools/GenJson.cpp.func-sort-c.html new file mode 100644 index 000000000000..b8ad01526529 --- /dev/null +++ b/coverage/cltools/GenJson.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenJson.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenJson.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9191100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools7GenJson4mainEP8_IO_FILES3_RNS_12CommunicatorE1
_ZNK4PLMD7cltools7GenJson11descriptionB5cxx11Ev4
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMe6createERKNS_13CLToolOptionsE5
_ZN4PLMD7cltools7GenJsonC2ERKNS_13CLToolOptionsE5
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeD2Ev4187
_ZN4PLMD7cltools7GenJson16registerKeywordsERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenJson.cpp.func.html b/coverage/cltools/GenJson.cpp.func.html new file mode 100644 index 000000000000..9fe8beb52f82 --- /dev/null +++ b/coverage/cltools/GenJson.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenJson.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenJson.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9191100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMe6createERKNS_13CLToolOptionsE5
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_117GenJsonRegisterMeD2Ev4187
_ZN4PLMD7cltools7GenJson16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools7GenJson4mainEP8_IO_FILES3_RNS_12CommunicatorE1
_ZN4PLMD7cltools7GenJsonC2ERKNS_13CLToolOptionsE5
_ZNK4PLMD7cltools7GenJson11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenJson.cpp.gcov.html b/coverage/cltools/GenJson.cpp.gcov.html new file mode 100644 index 000000000000..80f0c1453d49 --- /dev/null +++ b/coverage/cltools/GenJson.cpp.gcov.html @@ -0,0 +1,257 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenJson.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenJson.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9191100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2022,2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "config/Config.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/GenericMolInfo.h"
+      28             : #include <cstdio>
+      29             : #include <string>
+      30             : #include <iostream>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace cltools {
+      34             : 
+      35             : //+PLUMEDOC TOOLS gen_json
+      36             : /*
+      37             : gen_json constructs a json file that includes a dictionary of actions, the keywords for those actions and the components and outputs this to standard output
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : The following command generates the json file
+      42             : \verbatim
+      43             : plumed gen_json
+      44             : \endverbatim
+      45             : 
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : class GenJson : public CLTool {
+      51             : private:
+      52             :   std::string version;
+      53             : public:
+      54             :   static void registerKeywords( Keywords& keys );
+      55             :   explicit GenJson(const CLToolOptions& co );
+      56             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+      57           4 :   std::string description()const override {
+      58           4 :     return "print out a json file that contains the pluemd syntax";
+      59             :   }
+      60             : };
+      61             : 
+      62       12566 : PLUMED_REGISTER_CLTOOL(GenJson,"gen_json")
+      63             : 
+      64        4187 : void GenJson::registerKeywords( Keywords& keys ) {
+      65        4187 :   CLTool::registerKeywords( keys );
+      66        8374 :   keys.add("compulsory","--actions","a file containing one line descriptions of the various actions");
+      67        4187 : }
+      68             : 
+      69           5 : GenJson::GenJson(const CLToolOptions& co ):
+      70             :   CLTool(co),
+      71           5 :   version("master")
+      72             : {
+      73           5 :   inputdata=commandline;
+      74          10 :   if( config::getVersionLong().find("dev")==std::string::npos ) version="v"+config::getVersion();
+      75           5 : }
+      76             : 
+      77           1 : int GenJson::main(FILE* in, FILE*out,Communicator& pc) {
+      78           1 :   std::string line(""), actionfile; parse("--actions",actionfile);
+      79           1 :   IFile myfile; myfile.open(actionfile); bool stat;
+      80             :   std::map<std::string,std::string> action_map;
+      81         322 :   while((stat=myfile.getline(line))) {
+      82         321 :     std::size_t col = line.find_first_of(":");
+      83         642 :     action_map.insert(std::pair<std::string,std::string>( line.substr(0,col), line.substr(col+1) ) );
+      84             :   }
+      85           1 :   myfile.close();
+      86             : 
+      87             :   // Cycle over all the action names
+      88           1 :   std::cout<<"{"<<std::endl;
+      89             :   // Get the vimlink
+      90           2 :   std::cout<<"  \"vimlink\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/_vim_syntax.html\","<<std::endl;
+      91             :   // And the replicas link
+      92           2 :   std::cout<<"  \"replicalink\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/special-replica-syntax.html\","<<std::endl;
+      93             :   // Get the names of all the actions
+      94           1 :   std::vector<std::string> action_names( actionRegister().getActionNames() );
+      95         299 :   for(unsigned i=0; i<action_names.size(); ++i) {
+      96         894 :     std::cout<<"  \""<<action_names[i]<<'"'<<": {"<<std::endl; std::string action=action_names[i];
+      97             :     // Handle conversion of action names to links
+      98         596 :     std::cout<<"    \"hyperlink\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/";
+      99        3674 :     std::transform(action.begin(), action.end(), action.begin(), [](unsigned char c) { return std::tolower(c); });
+     100             :     while(true) {
+     101         486 :       std::size_t und=action.find_first_of("_");
+     102         486 :       if( und==std::string::npos ) break;
+     103         188 :       std::string first=action.substr(0,und);
+     104        2250 :       for(auto c : first ) { if( isdigit(c) ) std::cout<<c; else std::cout<<"_"<<c; }
+     105         376 :       std::cout<<"_"; action=action.substr(und+1);
+     106         188 :     }
+     107        4612 :     for(auto c : action ) { if( isdigit(c) ) std::cout<<c; else std::cout<<"_"<<c; }
+     108         298 :     std::cout<<".html\","<<std::endl;
+     109         596 :     std::cout<<"    \"description\" : \""<<action_map[action_names[i]]<<"\",\n";
+     110             :     // Now output keyword information
+     111         298 :     Keywords keys; actionRegister().getKeywords( action_names[i], keys );
+     112         298 :     std::cout<<"    \"syntax\" : {"<<std::endl;
+     113        4857 :     for(unsigned j=0; j<keys.size(); ++j) {
+     114        4559 :       std::string desc = keys.getKeywordDescription( keys.getKeyword(j) );
+     115        4559 :       if( desc.find("default=")!=std::string::npos ) {
+     116        3034 :         std::size_t brac=desc.find_first_of(")"); desc = desc.substr(brac+1);
+     117             :       }
+     118        4559 :       std::size_t dot=desc.find_first_of(".");
+     119       22795 :       std::cout<<"       \""<<keys.getKeyword(j)<<"\" : { \"type\": \""<<keys.getStyle(keys.getKeyword(j))<<"\", \"description\": \""<<desc.substr(0,dot)<<"\", \"multiple\": "<<keys.numbered( keys.getKeyword(j) )<<"}";
+     120        5081 :       if( j==keys.size()-1 && !keys.exists("HAS_VALUES") ) std::cout<<std::endl; else std::cout<<","<<std::endl;
+     121             :     }
+     122         596 :     if( keys.exists("HAS_VALUES") ) {
+     123         224 :       std::cout<<"       \"output\" : {"<<std::endl;
+     124         224 :       std::vector<std::string> components( keys.getOutputComponents() );
+     125             :       // Check if we have a value
+     126             :       bool hasvalue=true;
+     127        2281 :       for(unsigned k=0; k<components.size(); ++k) {
+     128        4252 :         if( keys.getOutputComponentFlag( components[k] )=="default" ) { hasvalue=false; break; }
+     129             :       }
+     130         224 :       if( hasvalue ) {
+     131         155 :         std::cout<<"         \"value\": {"<<std::endl;
+     132         155 :         std::cout<<"           \"flag\": \"value\","<<std::endl;
+     133         155 :         std::cout<<"           \"description\": \"a scalar quantity\""<<std::endl;
+     134         155 :         if( components.size()==0 ) std::cout<<"         }"<<std::endl; else std::cout<<"         },"<<std::endl;
+     135             :       }
+     136        2628 :       for(unsigned k=0; k<components.size(); ++k) {
+     137        4808 :         std::cout<<"         \""<<components[k]<<"\" : {"<<std::endl;
+     138        7212 :         std::cout<<"           \"flag\": \""<<keys.getOutputComponentFlag( components[k] )<<"\","<<std::endl;
+     139        2404 :         std::string desc=keys.getOutputComponentDescription( components[k] ); std::size_t dot=desc.find_first_of(".");
+     140        7212 :         std::cout<<"           \"description\": \""<<desc.substr(0,dot)<<"\""<<std::endl;
+     141        2404 :         if( k==components.size()-1 ) std::cout<<"         }"<<std::endl; else std::cout<<"         },"<<std::endl;
+     142             :       }
+     143         224 :       std::cout<<"       }"<<std::endl;
+     144             : 
+     145         224 :     }
+     146         298 :     std::cout<<"    },"<<std::endl;
+     147             :     // This ensures that \n is replaced by \\n
+     148         298 :     std::string unsafen="\n", safen="\\n", helpstr = keys.getHelpString();
+     149         298 :     for( std::size_t pos = helpstr.find("\n");
+     150       11462 :          pos != std::string::npos;
+     151       11164 :          pos = helpstr.find("\n", pos)
+     152       11164 :        ) { helpstr.replace(pos, unsafen.size(), safen); pos += safen.size(); }
+     153         596 :     std::cout<<"    \"help\" : \""<<helpstr<<"\"\n";
+     154         298 :     std::cout<<"  },"<<std::endl;
+     155         298 :   }
+     156             :   // Get all the special groups
+     157           1 :   std::cout<<"  \"groups\" : {"<<std::endl;
+     158           1 :   std::cout<<"    \"@allatoms\" : { \n"<<std::endl;
+     159           1 :   std::cout<<"        \"description\" : \"refers to all the MD codes atoms and PLUMEDs vatoms\","<<std::endl;
+     160           2 :   std::cout<<"        \"link\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/_group.html\""<<std::endl;
+     161           1 :   std::cout<<"    },"<<std::endl;
+     162           1 :   std::cout<<"    \"@mdatoms\" : { \n"<<std::endl;
+     163           1 :   std::cout<<"        \"description\" : \"refers to all the MD codes atoms but not PLUMEDs vatoms\","<<std::endl;
+     164           2 :   std::cout<<"        \"link\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/_group.html\""<<std::endl;
+     165             :   // Now print all the special keywords in molinfo
+     166           1 :   std::map<std::string,std::string> specials( GenericMolInfo::getSpecialKeywords() );
+     167          36 :   for(auto const& s : specials ) {
+     168          35 :     std::cout<<"    },"<<std::endl;
+     169          70 :     std::cout<<"    \""<<s.first<<"\" : { \n"<<std::endl;
+     170          70 :     std::cout<<"        \"description\" : \""<<s.second<<"\","<<std::endl;
+     171          70 :     std::cout<<"        \"link\" : \"https://www.plumed.org/doc-"<<version<<"/user-doc/html/_m_o_l_i_n_f_o.html\""<<std::endl;
+     172             :   }
+     173           1 :   std::cout<<"        }"<<std::endl;
+     174           1 :   std::cout<<"  }"<<std::endl;
+     175           1 :   std::cout<<"}"<<std::endl;
+     176           1 :   return 0;
+     177           2 : }
+     178             : 
+     179             : } // End of namespace
+     180             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenTemplate.cpp.func-sort-c.html b/coverage/cltools/GenTemplate.cpp.func-sort-c.html new file mode 100644 index 000000000000..560168f54bdb --- /dev/null +++ b/coverage/cltools/GenTemplate.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenTemplate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenTemplate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:132356.5 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11GenTemplate4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools11GenTemplateC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMe6createERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools11GenTemplate11descriptionB5cxx11Ev4
_ZN4PLMD7cltools11GenTemplate16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenTemplate.cpp.func.html b/coverage/cltools/GenTemplate.cpp.func.html new file mode 100644 index 000000000000..711e98b29f69 --- /dev/null +++ b/coverage/cltools/GenTemplate.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenTemplate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenTemplate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:132356.5 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11GenTemplate16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools11GenTemplate4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools11GenTemplateC2ERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_121GenTemplateRegisterMeD2Ev4187
_ZNK4PLMD7cltools11GenTemplate11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/GenTemplate.cpp.gcov.html b/coverage/cltools/GenTemplate.cpp.gcov.html new file mode 100644 index 000000000000..5025a0a1dfa8 --- /dev/null +++ b/coverage/cltools/GenTemplate.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + + LCOV - plumed test coverage - cltools/GenTemplate.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - GenTemplate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:132356.5 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include <cstdio>
+      27             : #include <string>
+      28             : #include <iostream>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace cltools {
+      32             : 
+      33             : //+PLUMEDOC TOOLS gentemplate
+      34             : /*
+      35             : gentemplate is a tool that you can use to construct template inputs for the various actions
+      36             : 
+      37             : The templates generated by this tool are primarily for use with Toni Giorgino's VMD GUI.  It may be
+      38             : useful however to use this tool as a quick aid memoir.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : The following generates template input for the action DISTANCE.
+      43             : \verbatim
+      44             : plumed gentemplate --action DISTANCE
+      45             : \endverbatim
+      46             : 
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : class GenTemplate:
+      52             :   public CLTool
+      53             : {
+      54             : public:
+      55             :   static void registerKeywords( Keywords& keys );
+      56             :   explicit GenTemplate(const CLToolOptions& co );
+      57             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+      58           4 :   std::string description()const override {
+      59           4 :     return "print out a template input for a particular action";
+      60             :   }
+      61             : };
+      62             : 
+      63       12565 : PLUMED_REGISTER_CLTOOL(GenTemplate,"gentemplate")
+      64             : 
+      65        4187 : void GenTemplate::registerKeywords( Keywords& keys ) {
+      66        4187 :   CLTool::registerKeywords( keys );
+      67        8374 :   keys.add("optional","--action","print the template for this particular action");
+      68        8374 :   keys.addFlag("--list",false,"print a list of the available actions");
+      69        8374 :   keys.addFlag("--include-optional",false,"also print optional modifiers");
+      70        4187 : }
+      71             : 
+      72           4 : GenTemplate::GenTemplate(const CLToolOptions& co ):
+      73           4 :   CLTool(co)
+      74             : {
+      75           4 :   inputdata=commandline;
+      76           4 : }
+      77             : 
+      78           0 : int GenTemplate::main(FILE* in, FILE*out,Communicator& pc) {
+      79             : 
+      80             :   std::string action;
+      81           0 :   bool list_templates=false;
+      82           0 :   parseFlag("--list",list_templates);
+      83             : 
+      84           0 :   if(list_templates) {
+      85           0 :     std::cerr<<actionRegister()<<"\n";
+      86             :     return 0;
+      87           0 :   } else if(parse("--action",action)) {
+      88             :     bool include_optional;
+      89           0 :     parseFlag("--include-optional",include_optional);
+      90           0 :     if( !actionRegister().printTemplate(action,include_optional) ) {
+      91           0 :       error("there is no registered action named " + action);
+      92             :       return 1;
+      93             :     }
+      94             :   } else return 1;
+      95             : 
+      96             : 
+      97             : 
+      98           0 :   return 0;
+      99             : }
+     100             : }
+     101             : 
+     102             : } // End of namespace
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Info.cpp.func-sort-c.html b/coverage/cltools/Info.cpp.func-sort-c.html new file mode 100644 index 000000000000..54c2ebaa2f74 --- /dev/null +++ b/coverage/cltools/Info.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Info.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Info.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394783.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools4Info11descriptionB5cxx11Ev4
_ZN4PLMD7cltools4Info4mainEP8_IO_FILES3_RNS_12CommunicatorE1861
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMe6createERKNS_13CLToolOptionsE1865
_ZN4PLMD7cltools4InfoC2ERKNS_13CLToolOptionsE1865
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeD2Ev4187
_ZN4PLMD7cltools4Info16registerKeywordsERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Info.cpp.func.html b/coverage/cltools/Info.cpp.func.html new file mode 100644 index 000000000000..3d757915afbe --- /dev/null +++ b/coverage/cltools/Info.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Info.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Info.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394783.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMe6createERKNS_13CLToolOptionsE1865
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_114InfoRegisterMeD2Ev4187
_ZN4PLMD7cltools4Info16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools4Info4mainEP8_IO_FILES3_RNS_12CommunicatorE1861
_ZN4PLMD7cltools4InfoC2ERKNS_13CLToolOptionsE1865
_ZNK4PLMD7cltools4Info11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Info.cpp.gcov.html b/coverage/cltools/Info.cpp.gcov.html new file mode 100644 index 000000000000..6071c1a0d459 --- /dev/null +++ b/coverage/cltools/Info.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Info.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Info.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394783.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "config/Config.h"
+      26             : #include <cstdio>
+      27             : #include <string>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace cltools {
+      31             : 
+      32             : //+PLUMEDOC TOOLS info
+      33             : /*
+      34             : This tool allows you to obtain information about your plumed version
+      35             : 
+      36             : You can specify the information you require using the following command line
+      37             : arguments
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : The following command returns the root directory for your plumed distribution.
+      42             : \verbatim
+      43             : plumed info --root
+      44             : \endverbatim
+      45             : 
+      46             : */
+      47             : //+ENDPLUMEDOC
+      48             : 
+      49             : class Info:
+      50             :   public CLTool
+      51             : {
+      52             : public:
+      53             :   static void registerKeywords( Keywords& keys );
+      54             :   explicit Info(const CLToolOptions& co );
+      55             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+      56           4 :   std::string description()const override {
+      57           4 :     return "provide informations about plumed";
+      58             :   }
+      59             : };
+      60             : 
+      61       14426 : PLUMED_REGISTER_CLTOOL(Info,"info")
+      62             : 
+      63        4187 : void Info::registerKeywords( Keywords& keys ) {
+      64        4187 :   CLTool::registerKeywords( keys );
+      65        8374 :   keys.addFlag("--configuration",false,"prints the configuration file");
+      66        8374 :   keys.addFlag("--root",false,"print the location of the root directory for the plumed source");
+      67        8374 :   keys.addFlag("--user-doc",false,"print the location of user manual (html)");
+      68        8374 :   keys.addFlag("--developer-doc",false,"print the location of user manual (html)");
+      69        8374 :   keys.addFlag("--version",false,"print the version number");
+      70        8374 :   keys.addFlag("--long-version",false,"print the version number (long version)");
+      71        8374 :   keys.addFlag("--git-version",false,"print the version number (git version, if available)");
+      72        8374 :   keys.addFlag("--include-dir",false,"print the location of the include dir");
+      73        8374 :   keys.addFlag("--soext",false,"print the extension of shared libraries (so or dylib)");
+      74        4187 : }
+      75             : 
+      76        1865 : Info::Info(const CLToolOptions& co ):
+      77        1865 :   CLTool(co)
+      78             : {
+      79        1865 :   inputdata=commandline;
+      80        1865 : }
+      81             : 
+      82        1861 : int Info::main(FILE* in, FILE*out,Communicator& pc) {
+      83             : 
+      84        1861 :   bool printconfiguration; parseFlag("--configuration",printconfiguration);
+      85        1861 :   bool printroot; parseFlag("--root",printroot);
+      86        1861 :   bool printuserdoc; parseFlag("--user-doc",printuserdoc);
+      87        1861 :   bool printdeveloperdoc; parseFlag("--developer-doc",printdeveloperdoc);
+      88        1861 :   bool printversion; parseFlag("--version",printversion);
+      89        1861 :   bool printlongversion; parseFlag("--long-version",printlongversion);
+      90        1861 :   bool printgitversion; parseFlag("--git-version",printgitversion);
+      91        1861 :   bool printincludedir; parseFlag("--include-dir",printincludedir);
+      92        1861 :   bool printsoext; parseFlag("--soext",printsoext);
+      93        2472 :   if(printroot) std::fprintf(out,"%s\n",config::getPlumedRoot().c_str());
+      94        1893 :   if(printconfiguration) std::fprintf(out,"%s",config::getMakefile().c_str());
+      95        1861 :   if(printincludedir) std::fprintf(out,"%s\n",config::getPlumedIncludedir().c_str());
+      96        1861 :   if(printuserdoc) {
+      97           0 :     std::string userdoc=config::getPlumedHtmldir()+"/user-doc/html/index.html";
+      98           0 :     FILE *ff=std::fopen(userdoc.c_str(),"r");
+      99             :     // no exception here
+     100           0 :     if(ff) std::fclose(ff);
+     101           0 :     else userdoc="http://www.plumed.org/doc-v" + config::getVersion() + "/user-doc/html/index.html";
+     102             :     std::fprintf(out,"%s\n",userdoc.c_str());
+     103             :   }
+     104        1861 :   if(printdeveloperdoc) {
+     105           0 :     std::string developerdoc=config::getPlumedHtmldir()+"/developer-doc/html/index.html";
+     106           0 :     FILE *ff=std::fopen(developerdoc.c_str(),"r");
+     107             :     // no exception here
+     108           0 :     if(ff) std::fclose(ff);
+     109           0 :     else developerdoc="http://www.plumed.org/doc-v" + config::getVersion() + "/developer-doc/html/index.html";
+     110             :     std::fprintf(out,"%s\n",developerdoc.c_str());
+     111             :   }
+     112        1861 :   if(printversion) std::fprintf(out,"%s\n",config::getVersion().c_str());
+     113        1861 :   if(printlongversion) std::fprintf(out,"%s\n",config::getVersionLong().c_str());
+     114        1861 :   if(printgitversion) std::fprintf(out,"%s\n",config::getVersionGit().c_str());
+     115        3079 :   if(printsoext) std::fprintf(out,"%s\n",config::getSoExt().c_str());
+     116             : 
+     117        1861 :   return 0;
+     118             : }
+     119             : 
+     120             : 
+     121             : 
+     122             : }
+     123             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Manual.cpp.func-sort-c.html b/coverage/cltools/Manual.cpp.func-sort-c.html new file mode 100644 index 000000000000..89687f71c50b --- /dev/null +++ b/coverage/cltools/Manual.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Manual.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Manual.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools6Manual11descriptionB5cxx11Ev4
_ZN4PLMD7cltools6Manual4mainEP8_IO_FILES3_RNS_12CommunicatorE299
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMe6createERKNS_13CLToolOptionsE303
_ZN4PLMD7cltools6ManualC2ERKNS_13CLToolOptionsE303
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeD2Ev4187
_ZN4PLMD7cltools6Manual16registerKeywordsERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Manual.cpp.func.html b/coverage/cltools/Manual.cpp.func.html new file mode 100644 index 000000000000..baab1cd2f012 --- /dev/null +++ b/coverage/cltools/Manual.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Manual.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Manual.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMe6createERKNS_13CLToolOptionsE303
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_116ManualRegisterMeD2Ev4187
_ZN4PLMD7cltools6Manual16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools6Manual4mainEP8_IO_FILES3_RNS_12CommunicatorE299
_ZN4PLMD7cltools6ManualC2ERKNS_13CLToolOptionsE303
_ZNK4PLMD7cltools6Manual11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/Manual.cpp.gcov.html b/coverage/cltools/Manual.cpp.gcov.html new file mode 100644 index 000000000000..a5eb1092f2d7 --- /dev/null +++ b/coverage/cltools/Manual.cpp.gcov.html @@ -0,0 +1,178 @@ + + + + + + + + LCOV - plumed test coverage - cltools/Manual.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - Manual.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "config/Config.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include <cstdio>
+      28             : #include <string>
+      29             : #include <iostream>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace cltools {
+      33             : 
+      34             : //+PLUMEDOC TOOLS manual
+      35             : /*
+      36             : manual is a tool that you can use to construct the manual page for
+      37             : a particular action
+      38             : 
+      39             : The manual constructed by this action is in html. In all probability you will never need to use this
+      40             : tool. However, it is used within the scripts that generate the html manual for PLUMED.  If you need to use this
+      41             : tool outside those scripts the input is specified using the following command line arguments.
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : The following generates the html manual for the action DISTANCE.
+      46             : \verbatim
+      47             : plumed manual --action DISTANCE
+      48             : \endverbatim
+      49             : 
+      50             : 
+      51             : */
+      52             : //+ENDPLUMEDOC
+      53             : 
+      54             : class Manual:
+      55             :   public CLTool
+      56             : {
+      57             : public:
+      58             :   static void registerKeywords( Keywords& keys );
+      59             :   explicit Manual(const CLToolOptions& co );
+      60             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+      61           4 :   std::string description()const override {
+      62           4 :     return "print out a description of the keywords for an action in html";
+      63             :   }
+      64             : };
+      65             : 
+      66       12864 : PLUMED_REGISTER_CLTOOL(Manual,"manual")
+      67             : 
+      68        4187 : void Manual::registerKeywords( Keywords& keys ) {
+      69        4187 :   CLTool::registerKeywords( keys );
+      70        8374 :   keys.add("compulsory","--action","print the manual for this particular action");
+      71        8374 :   keys.addFlag("--vim",false,"print the keywords in vim syntax");
+      72        8374 :   keys.addFlag("--spelling",false,"print a list of the keywords and component names for the spell checker");
+      73        4187 : }
+      74             : 
+      75         303 : Manual::Manual(const CLToolOptions& co ):
+      76         303 :   CLTool(co)
+      77             : {
+      78         303 :   inputdata=commandline;
+      79         303 : }
+      80             : 
+      81         299 : int Manual::main(FILE* in, FILE*out,Communicator& pc) {
+      82             : 
+      83             :   std::string action;
+      84         598 :   if( !parse("--action",action) ) return 1;
+      85         299 :   std::cerr<<"LIST OF DOCUMENTED ACTIONS:\n";
+      86         299 :   std::cerr<<actionRegister()<<"\n";
+      87         299 :   std::cerr<<"LIST OF DOCUMENTED COMMAND LINE TOOLS:\n";
+      88         299 :   std::cerr<<cltoolRegister()<<"\n\n";
+      89         299 :   bool vimout; parseFlag("--vim",vimout);
+      90         299 :   bool spellout; parseFlag("--spelling",spellout);
+      91         299 :   if( vimout && spellout ) error("can only use one of --vim and --spelling at a time");
+      92         299 :   if( !actionRegister().printManual(action,vimout,spellout) && !cltoolRegister().printManual(action,spellout) ) {
+      93           1 :     std::fprintf(stderr,"specified action is not registered\n");
+      94             :     return 1;
+      95             :   }
+      96             : 
+      97             :   return 0;
+      98             : }
+      99             : 
+     100             : } // End of namespace
+     101             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/PdbRenumber.cpp.func-sort-c.html b/coverage/cltools/PdbRenumber.cpp.func-sort-c.html new file mode 100644 index 000000000000..55f50b9f74c1 --- /dev/null +++ b/coverage/cltools/PdbRenumber.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/PdbRenumber.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - PdbRenumber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515396.2 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11PdbRenumber4mainEP8_IO_FILES3_RNS_12CommunicatorE3
_ZNK4PLMD7cltools11PdbRenumber11descriptionB5cxx11Ev4
_ZN4PLMD7cltools11PdbRenumberC2ERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools11PdbRenumber16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/PdbRenumber.cpp.func.html b/coverage/cltools/PdbRenumber.cpp.func.html new file mode 100644 index 000000000000..198f8c95b4fc --- /dev/null +++ b/coverage/cltools/PdbRenumber.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/PdbRenumber.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - PdbRenumber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515396.2 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools11PdbRenumber16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools11PdbRenumber4mainEP8_IO_FILES3_RNS_12CommunicatorE3
_ZN4PLMD7cltools11PdbRenumberC2ERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_121PdbRenumberRegisterMeD2Ev4187
_ZNK4PLMD7cltools11PdbRenumber11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/PdbRenumber.cpp.gcov.html b/coverage/cltools/PdbRenumber.cpp.gcov.html new file mode 100644 index 000000000000..e13d3c3b7304 --- /dev/null +++ b/coverage/cltools/PdbRenumber.cpp.gcov.html @@ -0,0 +1,275 @@ + + + + + + + + LCOV - plumed test coverage - cltools/PdbRenumber.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - PdbRenumber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515396.2 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/IFile.h"
+      27             : #include "tools/OFile.h"
+      28             : #include "tools/h36.h"
+      29             : #include <cstdio>
+      30             : #include <string>
+      31             : #include <vector>
+      32             : #include <array>
+      33             : #include <limits>
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace cltools {
+      37             : 
+      38             : //+PLUMEDOC TOOLS pdbrenumber
+      39             : /*
+      40             : Modify atom numbers in a PDB, possibly using hybrid-36 coding.
+      41             : 
+      42             : When reading a PDB files, PLUMED honors the serial number of each atom.
+      43             : This command can be used to process a PDB file changing the atom serial numbers.
+      44             : Notice that the resulting list might have gaps. It is however fundamental
+      45             : that atom numbers correspond to those used within the MD code.
+      46             : Importantly, if the serial number of an atom is greater than 99999, it is
+      47             : written in hybrid-36 notation (see \ref pdbreader).
+      48             : The main use of \ref pdbrenumber is thus that of producing files where atoms
+      49             : are numbered using hybrid-36 convention.
+      50             : 
+      51             : The output PDB file is identical to the input PDB file, except for the atom number
+      52             : field.
+      53             : The rest of the line is written unchanged
+      54             : to the output file, even if it is incorrectly formatted. Residue numbers are not touched,
+      55             : and atom numbers in the input file are ignored.
+      56             : 
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : By default, \ref pdbreader  just sets the numbers as progressive starting from 1.
+      61             : For instance the following command:
+      62             : \verbatim
+      63             : > plumed pdbrenumber --ipdb input.pdb --opdb output.pdb
+      64             : \endverbatim
+      65             : will copy file `input.pdb` to `output.pdb` replacing all the serial atoms with
+      66             : increasing numbers starting from one. Atoms that have an index that is greater than 99999 will be written
+      67             : in the output PDB file in hybrid-36 code.
+      68             : 
+      69             : It is possible to set a different serial number for the first atom, letting the
+      70             : following ones grow by one at each line. Here for instance the first atom
+      71             : will be assigned serial 1000, the second serial 1001, etc:
+      72             : \verbatim
+      73             : > plumed pdbrenumber --ipdb input.pdb --opdb output.pdb --firstatomnumber 1000
+      74             : \endverbatim
+      75             : If the first atom number is >99999, it should be given as a decimal number (not in hybrid-36 code).
+      76             : However, numbers >99999 in the output PDB file will be written in hybrid-36 code.
+      77             : 
+      78             : As an alternative, one can provide a list of atoms as one per line in an auxiliary file.
+      79             : \verbatim
+      80             : > plumed pdbrenumber --ipdb input.pdb --opdb output.pdb --atomnumbers list.txt
+      81             : \endverbatim
+      82             : The `list.txt` file might be something like this
+      83             : \verbatim
+      84             : 120000
+      85             : 120001
+      86             : 120002
+      87             : 1
+      88             : 2
+      89             : 3
+      90             : \endverbatim
+      91             : Numbers >99999 in the list should be provided as decimal numbers (not in hybrid-36 code).
+      92             : However, numbers >99999 in the output PDB file will be written in hybrid-36 code.
+      93             : Notice that there should be at least enough lines in `list.txt` as many atoms in the PDB file.
+      94             : Additional lines in `list.txt` will just be ignored.
+      95             : 
+      96             : 
+      97             : */
+      98             : //+ENDPLUMEDOC
+      99             : 
+     100             : class PdbRenumber:
+     101             :   public CLTool
+     102             : {
+     103             : public:
+     104             :   static void registerKeywords( Keywords& keys );
+     105             :   explicit PdbRenumber(const CLToolOptions& co );
+     106             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+     107           4 :   std::string description()const override {
+     108           4 :     return "Modify atom numbers in a PDB, possibly using hybrid-36 coding";
+     109             :   }
+     110             : };
+     111             : 
+     112       12568 : PLUMED_REGISTER_CLTOOL(PdbRenumber,"pdbrenumber")
+     113             : 
+     114        4187 : void PdbRenumber::registerKeywords( Keywords& keys ) {
+     115        4187 :   CLTool::registerKeywords( keys );
+     116        8374 :   keys.add("compulsory","--ipdb","specify the name of the input PDB file");
+     117        8374 :   keys.add("compulsory","--opdb","specify the name of the output PDB file");
+     118        8374 :   keys.add("optional","--firstatomnumber","specify the desired serial number of the first atom of the output file");
+     119        8374 :   keys.add("optional","--atomnumbers","specify the desired serial numbers of the atoms of the output file using a separate list");
+     120        4187 : }
+     121             : 
+     122           7 : PdbRenumber::PdbRenumber(const CLToolOptions& co ):
+     123           7 :   CLTool(co)
+     124             : {
+     125           7 :   inputdata=commandline;
+     126           7 : }
+     127             : 
+     128           3 : int PdbRenumber::main(FILE* in, FILE*out,Communicator& pc) {
+     129             : 
+     130             :   std::string ipdb;
+     131           6 :   parse("--ipdb",ipdb);
+     132             :   std::string opdb;
+     133           3 :   parse("--opdb",opdb);
+     134             : 
+     135           3 :   unsigned iat=0;
+     136             : 
+     137           6 :   parse("--firstatomnumber",iat);
+     138             : 
+     139             :   std::string atomnumbers;
+     140           6 :   parse("--atomnumbers",atomnumbers);
+     141             : 
+     142           3 :   plumed_assert(ipdb.length()>0) << "please specify the input PDB with --ipdb";
+     143           3 :   plumed_assert(opdb.length()>0) << "please specify the onput PDB with --opdb";
+     144             :   std::fprintf(out,"  with input PDB: %s\n",ipdb.c_str());
+     145             :   std::fprintf(out,"  with output PDB: %s\n",opdb.c_str());
+     146             : 
+     147             :   std::vector<unsigned> serials;
+     148             : 
+     149           3 :   if(atomnumbers.length()>0) {
+     150           1 :     plumed_assert(iat==0) << "it is not possible to use both --atomnumbers and --firstatomnumber";
+     151             :     std::fprintf(out,"  reading atom numbers from file %s\n",atomnumbers.c_str());
+     152           1 :     IFile ifile;
+     153           1 :     ifile.open(atomnumbers);
+     154             :     std::string line;
+     155           7 :     while(ifile.getline(line)) {
+     156             :       int i;
+     157           6 :       Tools::convert(line,i);
+     158           6 :       serials.push_back(i);
+     159             :     }
+     160           1 :   } else {
+     161           2 :     if(iat==0) iat=1;
+     162           2 :     std::fprintf(out,"  with atoms starting from %u\n",iat);
+     163             :   }
+     164             : 
+     165           3 :   IFile ifile;
+     166           3 :   ifile.open(ipdb);
+     167             : 
+     168           3 :   OFile ofile;
+     169           3 :   ofile.open(opdb);
+     170             : 
+     171             :   std::string line;
+     172      100112 :   while(ifile.getline(line)) {
+     173      100109 :     std::string record=line.substr(0,6);
+     174      100109 :     Tools::trim(record);
+     175             : 
+     176      100109 :     if(record=="ATOM" || record=="HETATM") {
+     177             :       std::array<char,6> at;
+     178      100109 :       unsigned ii=iat;
+     179      100109 :       if(serials.size()>0) {
+     180           6 :         plumed_assert(iat<serials.size()) << "there are more atoms in the PDB than serials in the file";
+     181           6 :         ii=serials[iat];
+     182             :       }
+     183      100109 :       const char* msg = h36::hy36encode(5,ii,&at[0]);
+     184      100109 :       plumed_assert(msg==nullptr) << msg;
+     185      100109 :       at[5]=0;
+     186      200218 :       ofile << line.substr(0,6) << &at[0] << line.substr(11) << "\n";
+     187      100109 :       iat++;
+     188             :     } else {
+     189           0 :       if(record=="END" || record=="ENDMDL") iat=0;
+     190           0 :       ofile << line << "\n";
+     191             :     }
+     192             :   }
+     193             : 
+     194           3 :   return 0;
+     195           3 : }
+     196             : }
+     197             : 
+     198             : } // End of namespace
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SimpleMD.cpp.func-sort-c.html b/coverage/cltools/SimpleMD.cpp.func-sort-c.html new file mode 100644 index 000000000000..01d5084589c5 --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.func-sort-c.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-02-22 21:58:45Functions:2020100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools8SimpleMD11descriptionB5cxx11Ev4
_ZN4PLMD7cltools8SimpleMD10read_inputERdS2_S2_S2_S2_RiS3_S3_RbRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_SB_S3_S3_S2_S2_9
_ZN4PLMD7cltools8SimpleMD11read_natomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi9
_ZN4PLMD7cltools8SimpleMD14read_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_13VectorGenericILj3EEESaISC_EEPd9
_ZN4PLMD7cltools8SimpleMD20randomize_velocitiesEiidRKSt6vectorIdSaIdEERS2_INS_13VectorGenericILj3EEESaIS8_EERNS_6RandomE9
_ZN4PLMD7cltools8SimpleMD21write_final_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRKSt6vectorINS_13VectorGenericILj3EEESaISC_EEPKdb9
_ZN4PLMD7cltools8SimpleMD4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools8SimpleMDC2ERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools8SimpleMD15write_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRKSt6vectorINS_13VectorGenericILj3EEESaISC_EEPKdb39
_ZN4PLMD7cltools8SimpleMD16write_statisticsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEidiiddd174
_ZN4PLMD7cltools8SimpleMD12compute_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRS2_IS2_IiSaIiEESaISC_EE458
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeD2Ev4187
_ZN4PLMD7cltools8SimpleMD16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools8SimpleMD10check_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EES8_ddRb5700
_ZN4PLMD7cltools8SimpleMD14compute_engkinEiRKSt6vectorIdSaIdEERKS2_INS_13VectorGenericILj3EEESaIS8_EERd5700
_ZN4PLMD7cltools8SimpleMD14compute_forcesEiddRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRKS2_IS2_IiSaIiEESaISC_EERS6_Rd5709
_ZN4PLMD7cltools8SimpleMD10thermostatEiiRKSt6vectorIdSaIdEEdddRS2_INS_13VectorGenericILj3EEESaIS8_EERdRNS_6RandomE11400
_ZN4PLMD7cltools8SimpleMD3pbcEPKdRKNS_13VectorGenericILj3EEERS5_9982883
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SimpleMD.cpp.func.html b/coverage/cltools/SimpleMD.cpp.func.html new file mode 100644 index 000000000000..1e7a17b61c41 --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.func.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-02-22 21:58:45Functions:2020100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_118SimpleMDRegisterMeD2Ev4187
_ZN4PLMD7cltools8SimpleMD10check_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EES8_ddRb5700
_ZN4PLMD7cltools8SimpleMD10read_inputERdS2_S2_S2_S2_RiS3_S3_RbRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_SB_SB_S3_S3_S2_S2_9
_ZN4PLMD7cltools8SimpleMD10thermostatEiiRKSt6vectorIdSaIdEEdddRS2_INS_13VectorGenericILj3EEESaIS8_EERdRNS_6RandomE11400
_ZN4PLMD7cltools8SimpleMD11read_natomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi9
_ZN4PLMD7cltools8SimpleMD12compute_listEiRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRS2_IS2_IiSaIiEESaISC_EE458
_ZN4PLMD7cltools8SimpleMD14compute_engkinEiRKSt6vectorIdSaIdEERKS2_INS_13VectorGenericILj3EEESaIS8_EERd5700
_ZN4PLMD7cltools8SimpleMD14compute_forcesEiddRKSt6vectorINS_13VectorGenericILj3EEESaIS4_EEPKddRKS2_IS2_IiSaIiEESaISC_EERS6_Rd5709
_ZN4PLMD7cltools8SimpleMD14read_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_13VectorGenericILj3EEESaISC_EEPd9
_ZN4PLMD7cltools8SimpleMD15write_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRKSt6vectorINS_13VectorGenericILj3EEESaISC_EEPKdb39
_ZN4PLMD7cltools8SimpleMD16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools8SimpleMD16write_statisticsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEidiiddd174
_ZN4PLMD7cltools8SimpleMD20randomize_velocitiesEiidRKSt6vectorIdSaIdEERS2_INS_13VectorGenericILj3EEESaIS8_EERNS_6RandomE9
_ZN4PLMD7cltools8SimpleMD21write_final_positionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRKSt6vectorINS_13VectorGenericILj3EEESaISC_EEPKdb9
_ZN4PLMD7cltools8SimpleMD3pbcEPKdRKNS_13VectorGenericILj3EEERS5_9982883
_ZN4PLMD7cltools8SimpleMD4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools8SimpleMDC2ERKNS_13CLToolOptionsE13
_ZNK4PLMD7cltools8SimpleMD11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SimpleMD.cpp.gcov.html b/coverage/cltools/SimpleMD.cpp.gcov.html new file mode 100644 index 000000000000..2bd3099f9b01 --- /dev/null +++ b/coverage/cltools/SimpleMD.cpp.gcov.html @@ -0,0 +1,685 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SimpleMD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SimpleMD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:231231100.0 %
Date:2024-02-22 21:58:45Functions:2020100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Vector.h"
+      26             : #include "tools/Random.h"
+      27             : #include "tools/OpenMP.h"
+      28             : #include <string>
+      29             : #include <cstdio>
+      30             : #include <cmath>
+      31             : #include <vector>
+      32             : #include <memory>
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace cltools {
+      36             : 
+      37             : //+PLUMEDOC TOOLS simplemd
+      38             : /*
+      39             : simplemd allows one to do molecular dynamics on systems of Lennard-Jones atoms.
+      40             : 
+      41             : The input to simplemd is specified in an input file. Configurations are input and
+      42             : output in xyz format. The input file should contain one directive per line.
+      43             : The directives available are as follows:
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : You run an MD simulation using simplemd with the following command:
+      48             : \verbatim
+      49             : plumed simplemd < in
+      50             : \endverbatim
+      51             : 
+      52             : The following is an example of an input file for a simplemd calculation. This file
+      53             : instructs simplemd to do 50 steps of MD at a temperature of 0.722
+      54             : \verbatim
+      55             : inputfile input.xyz
+      56             : outputfile output.xyz
+      57             : temperature 0.722
+      58             : tstep 0.005
+      59             : friction 1
+      60             : forcecutoff 2.5
+      61             : listcutoff  3.0
+      62             : nstep 50
+      63             : nconfig 10 trajectory.xyz
+      64             : nstat   10 energies.dat
+      65             : \endverbatim
+      66             : 
+      67             : If you run the following a description of all the directives that can be used in the
+      68             : input file will be output.
+      69             : \verbatim
+      70             : plumed simplemd --help
+      71             : \endverbatim
+      72             : 
+      73             : */
+      74             : //+ENDPLUMEDOC
+      75             : 
+      76             : // simple static function to close a file
+      77             : // defined once here since it's used in many places in this file
+      78             : // in addition, this seems the only way to use it in the write_statistics_fp_deleter member
+      79             : static void (*deleter)(FILE* f) = [](auto f) { if(f) std::fclose(f); };
+      80             : 
+      81             : class SimpleMD:
+      82             :   public PLMD::CLTool
+      83             : {
+      84           4 :   std::string description()const override {
+      85           4 :     return "run lj code";
+      86             :   }
+      87             : 
+      88             :   bool write_positions_first;
+      89             :   bool write_statistics_first;
+      90             :   int write_statistics_last_time_reopened;
+      91             :   FILE* write_statistics_fp;
+      92             :   std::unique_ptr<FILE,decltype(deleter)> write_statistics_fp_deleter{nullptr,deleter};
+      93             : 
+      94             : 
+      95             : public:
+      96        4187 :   static void registerKeywords( Keywords& keys ) {
+      97        8374 :     keys.add("compulsory","nstep","The number of steps of dynamics you want to run");
+      98        8374 :     keys.add("compulsory","temperature","NVE","the temperature at which you wish to run the simulation in LJ units");
+      99        8374 :     keys.add("compulsory","friction","off","The friction (in LJ units) for the Langevin thermostat that is used to keep the temperature constant");
+     100        8374 :     keys.add("compulsory","tstep","0.005","the integration timestep in LJ units");
+     101        8374 :     keys.add("compulsory","epsilon","1.0","LJ parameter");
+     102        8374 :     keys.add("compulsory","sigma","1.0","LJ parameter");
+     103        8374 :     keys.add("compulsory","inputfile","An xyz file containing the initial configuration of the system");
+     104        8374 :     keys.add("compulsory","forcecutoff","2.5","");
+     105        8374 :     keys.add("compulsory","listcutoff","3.0","");
+     106        8374 :     keys.add("compulsory","outputfile","An output xyz file containing the final configuration of the system");
+     107        8374 :     keys.add("compulsory","nconfig","10","The frequency with which to write configurations to the trajectory file followed by the name of the trajectory file");
+     108        8374 :     keys.add("compulsory","nstat","1","The frequency with which to write the statistics to the statistics file followed by the name of the statistics file");
+     109        8374 :     keys.add("compulsory","idum","0","The random number seed");
+     110        8374 :     keys.add("compulsory","ndim","3","The dimensionality of the system (some interesting LJ clusters are two dimensional)");
+     111        8374 :     keys.add("compulsory","wrapatoms","false","If true, atomic coordinates are written wrapped in minimal cell");
+     112        4187 :   }
+     113             : 
+     114          13 :   explicit SimpleMD( const CLToolOptions& co ) :
+     115             :     CLTool(co),
+     116          13 :     write_positions_first(true),
+     117          13 :     write_statistics_first(true),
+     118          13 :     write_statistics_last_time_reopened(0),
+     119          13 :     write_statistics_fp(NULL)
+     120             :   {
+     121          13 :     inputdata=ifile;
+     122          13 :   }
+     123             : 
+     124             : private:
+     125             : 
+     126             :   void
+     127           9 :   read_input(double& temperature,
+     128             :              double& tstep,
+     129             :              double& friction,
+     130             :              double& forcecutoff,
+     131             :              double& listcutoff,
+     132             :              int&    nstep,
+     133             :              int&    nconfig,
+     134             :              int&    nstat,
+     135             :              bool&   wrapatoms,
+     136             :              std::string& inputfile,
+     137             :              std::string& outputfile,
+     138             :              std::string& trajfile,
+     139             :              std::string& statfile,
+     140             :              int&    ndim,
+     141             :              int&    idum,
+     142             :              double& epsilon,
+     143             :              double& sigma)
+     144             :   {
+     145             : 
+     146             :     // Read everything from input file
+     147             :     char buffer1[256];
+     148          18 :     std::string tempstr; parse("temperature",tempstr);
+     149           9 :     if( tempstr!="NVE" ) Tools::convert(tempstr,temperature);
+     150          18 :     parse("tstep",tstep);
+     151          18 :     std::string frictionstr; parse("friction",frictionstr);
+     152           9 :     if( tempstr!="NVE" ) {
+     153           9 :       if(frictionstr=="off") error("Specify friction for thermostat");
+     154           9 :       Tools::convert(frictionstr,friction);
+     155             :     }
+     156           9 :     parse("forcecutoff",forcecutoff);
+     157           9 :     parse("listcutoff",listcutoff);
+     158           9 :     parse("nstep",nstep);
+     159           9 :     parse("idum",idum);
+     160           9 :     parse("epsilon",epsilon);
+     161           9 :     parse("sigma",sigma);
+     162             : 
+     163             :     // Read in stuff with sanity checks
+     164          18 :     parse("inputfile",inputfile);
+     165           9 :     if(inputfile.length()==0) error("Specify input file");
+     166          18 :     parse("outputfile",outputfile);
+     167           9 :     if(outputfile.length()==0) error("Specify output file");
+     168          18 :     std::string nconfstr; parse("nconfig",nconfstr);
+     169           9 :     std::sscanf(nconfstr.c_str(),"%100d %255s",&nconfig,buffer1);
+     170             :     trajfile=buffer1;
+     171           9 :     if(trajfile.length()==0) error("Specify traj file");
+     172          18 :     std::string nstatstr; parse("nstat",nstatstr);
+     173           9 :     std::sscanf(nstatstr.c_str(),"%100d %255s",&nstat,buffer1);
+     174             :     statfile=buffer1;
+     175           9 :     if(statfile.length()==0) error("Specify stat file");
+     176           9 :     parse("ndim",ndim);
+     177           9 :     if(ndim<1 || ndim>3) error("ndim should be 1,2 or 3");
+     178             :     std::string w;
+     179           9 :     parse("wrapatoms",w);
+     180           9 :     wrapatoms=false;
+     181           9 :     if(w.length()>0 && (w[0]=='T' || w[0]=='t')) wrapatoms=true;
+     182           9 :   }
+     183             : 
+     184           9 :   void read_natoms(const std::string & inputfile,int & natoms) {
+     185             : // read the number of atoms in file "input.xyz"
+     186           9 :     FILE* fp=std::fopen(inputfile.c_str(),"r");
+     187           9 :     if(!fp) error(std::string("file ") + inputfile + std::string(" not found"));
+     188             : 
+     189             : // call fclose when fp goes out of scope
+     190             :     std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     191             : 
+     192           9 :     int ret=std::fscanf(fp,"%1000d",&natoms);
+     193           9 :     if(ret==0) plumed_error() <<"Error reading number of atoms from file "<<inputfile;
+     194           9 :   }
+     195             : 
+     196           9 :   void read_positions(const std::string& inputfile,int natoms,std::vector<Vector>& positions,double cell[3]) {
+     197             : // read positions and cell from a file called inputfile
+     198             : // natoms (input variable) and number of atoms in the file should be consistent
+     199           9 :     FILE* fp=std::fopen(inputfile.c_str(),"r");
+     200           9 :     if(!fp) error(std::string("file ") + inputfile + std::string(" not found"));
+     201             : // call fclose when fp goes out of scope
+     202             :     std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     203             : 
+     204             :     char buffer[256];
+     205             :     char atomname[256];
+     206             :     char* cret=fgets(buffer,256,fp);
+     207           9 :     if(cret==nullptr) plumed_error() <<"Error reading buffer from file "<<inputfile;
+     208           9 :     int ret=std::fscanf(fp,"%1000lf %1000lf %1000lf",&cell[0],&cell[1],&cell[2]);
+     209           9 :     if(ret==0) plumed_error() <<"Error reading cell line from file "<<inputfile;
+     210         779 :     for(int i=0; i<natoms; i++) {
+     211         770 :       ret=std::fscanf(fp,"%255s %1000lf %1000lf %1000lf",atomname,&positions[i][0],&positions[i][1],&positions[i][2]);
+     212             : // note: atomname is read but not used
+     213         770 :       if(ret==0) plumed_error() <<"Error reading atom line from file "<<inputfile;
+     214             :     }
+     215           9 :   }
+     216             : 
+     217           9 :   void randomize_velocities(const int natoms,const int ndim,const double temperature,const std::vector<double>&masses,std::vector<Vector>& velocities,Random&random) {
+     218             : // randomize the velocities according to the temperature
+     219        3075 :     for(int iatom=0; iatom<natoms; iatom++) for(int i=0; i<ndim; i++)
+     220        2296 :         velocities[iatom][i]=std::sqrt(temperature/masses[iatom])*random.Gaussian();
+     221           9 :   }
+     222             : 
+     223     9982883 :   void pbc(const double cell[3],const Vector & vin,Vector & vout) {
+     224             : // apply periodic boundary condition to a vector
+     225    39931532 :     for(int i=0; i<3; i++) {
+     226    29948649 :       vout[i]=vin[i]-std::floor(vin[i]/cell[i]+0.5)*cell[i];
+     227             :     }
+     228     9982883 :   }
+     229             : 
+     230        5700 :   void check_list(const int natoms,const std::vector<Vector>& positions,const std::vector<Vector>&positions0,const double listcutoff,
+     231             :                   const double forcecutoff,bool & recompute)
+     232             :   {
+     233             : // check if the neighbour list have to be recomputed
+     234        5700 :     recompute=false;
+     235        5700 :     auto delta2=(0.5*(listcutoff-forcecutoff))*(0.5*(listcutoff-forcecutoff));
+     236             : // if ANY atom moved more than half of the skin thickness, recompute is set to .true.
+     237      217300 :     for(int iatom=0; iatom<natoms; iatom++) {
+     238      211600 :       if(modulo2(positions[iatom]-positions0[iatom])>delta2) recompute=true;
+     239             :     }
+     240        5700 :   }
+     241             : 
+     242             : 
+     243         458 :   void compute_list(const int natoms,const std::vector<Vector>& positions,const double cell[3],const double listcutoff,
+     244             :                     std::vector<std::vector<int> >& list) {
+     245         458 :     double listcutoff2=listcutoff*listcutoff; // squared list cutoff
+     246         458 :     list.assign(natoms,std::vector<int>());
+     247         458 :     #   pragma omp parallel for num_threads(OpenMP::getNumThreads()) schedule(static,1)
+     248             :     for(int iatom=0; iatom<natoms-1; iatom++) {
+     249             :       for(int jatom=iatom+1; jatom<natoms; jatom++) {
+     250             :         auto distance=positions[iatom]-positions[jatom];
+     251             :         Vector distance_pbc; // minimum-image distance of the two atoms
+     252             :         pbc(cell,distance,distance_pbc);
+     253             : // if the interparticle distance is larger than the cutoff, skip
+     254             :         if(modulo2(distance_pbc)>listcutoff2)continue;
+     255             :         list[iatom].push_back(jatom);
+     256             :       }
+     257             :     }
+     258         458 :   }
+     259             : 
+     260        5709 :   void compute_forces(const int natoms,double epsilon, double sigma,const std::vector<Vector>& positions,const double cell[3],
+     261             :                       double forcecutoff,const std::vector<std::vector<int> >& list,std::vector<Vector>& forces,double & engconf)
+     262             :   {
+     263        5709 :     double forcecutoff2=forcecutoff*forcecutoff; // squared force cutoff
+     264        5709 :     engconf=0.0;
+     265             :     double engconf_tmp=0.0; // separate variable for reduction (gcc 4.8 does not make reductions on references)
+     266      855189 :     for(int i=0; i<natoms; i++)for(int k=0; k<3; k++) forces[i][k]=0.0;
+     267        5709 :     double engcorrection=4.0*epsilon*(1.0/std::pow(forcecutoff2/(sigma*sigma),6.0)-1.0/std::pow(forcecutoff2/(sigma*sigma),3)); // energy necessary shift the potential avoiding discontinuities
+     268        5709 :     #   pragma omp parallel num_threads(OpenMP::getNumThreads())
+     269             :     {
+     270             :       std::vector<Vector> omp_forces(forces.size());
+     271             :       #pragma omp for reduction(+:engconf_tmp) schedule(static,1) nowait
+     272             :       for(int iatom=0; iatom<natoms-1; iatom++) {
+     273             :         for(int jlist=0; jlist<list[iatom].size(); jlist++) {
+     274             :           const int jatom=list[iatom][jlist];
+     275             :           auto distance=positions[iatom]-positions[jatom];
+     276             :           Vector distance_pbc;    // minimum-image distance of the two atoms
+     277             :           pbc(cell,distance,distance_pbc);
+     278             :           auto distance_pbc2=modulo2(distance_pbc);   // squared minimum-image distance
+     279             : // if the interparticle distance is larger than the cutoff, skip
+     280             :           if(distance_pbc2>forcecutoff2) continue;
+     281             :           auto distance_pbcm2=sigma*sigma/distance_pbc2;
+     282             :           auto distance_pbcm6=distance_pbcm2*distance_pbcm2*distance_pbcm2;
+     283             :           auto distance_pbcm8=distance_pbcm6*distance_pbcm2;
+     284             :           auto distance_pbcm12=distance_pbcm6*distance_pbcm6;
+     285             :           auto distance_pbcm14=distance_pbcm12*distance_pbcm2;
+     286             :           engconf_tmp+=4.0*epsilon*(distance_pbcm12 - distance_pbcm6) - engcorrection;
+     287             :           auto f=24.0*distance_pbc*(2.0*distance_pbcm14-distance_pbcm8)*epsilon/sigma;
+     288             :           omp_forces[iatom]+=f;
+     289             :           omp_forces[jatom]-=f;
+     290             :         }
+     291             :       }
+     292             :       #     pragma omp critical
+     293             :       for(unsigned i=0; i<omp_forces.size(); i++) forces[i]+=omp_forces[i];
+     294             :     }
+     295             : 
+     296        5709 :     engconf=engconf_tmp;
+     297             : 
+     298        5709 :   }
+     299             : 
+     300        5700 :   void compute_engkin(const int natoms,const std::vector<double>& masses,const std::vector<Vector>& velocities,double & engkin)
+     301             :   {
+     302             : // calculate the kinetic energy from the velocities
+     303        5700 :     engkin=0.0;
+     304      217300 :     for(int iatom=0; iatom<natoms; iatom++) {
+     305      211600 :       engkin+=0.5*masses[iatom]*modulo2(velocities[iatom]);
+     306             :     }
+     307        5700 :   }
+     308             : 
+     309             : 
+     310       11400 :   void thermostat(const int natoms,const int ndim,const std::vector<double>& masses,const double dt,const double friction,
+     311             :                   const double temperature,std::vector<Vector>& velocities,double & engint,Random & random) {
+     312             : // Langevin thermostat, implemented as described in Bussi and Parrinello, Phys. Rev. E (2007)
+     313             : // it is a linear combination of old velocities and new, randomly chosen, velocity,
+     314             : // with proper coefficients
+     315       11400 :     double c1=std::exp(-friction*dt);
+     316      434600 :     for(int iatom=0; iatom<natoms; iatom++) {
+     317      423200 :       double c2=std::sqrt((1.0-c1*c1)*temperature/masses[iatom]);
+     318     1636800 :       for(int i=0; i<ndim; i++) {
+     319     1213600 :         engint+=0.5*masses[iatom]*velocities[iatom][i]*velocities[iatom][i];
+     320     1213600 :         velocities[iatom][i]=c1*velocities[iatom][i]+c2*random.Gaussian();
+     321     1213600 :         engint-=0.5*masses[iatom]*velocities[iatom][i]*velocities[iatom][i];
+     322             :       }
+     323             :     }
+     324       11400 :   }
+     325             : 
+     326          39 :   void write_positions(const std::string& trajfile,int natoms,const std::vector<Vector>& positions,const double cell[3],const bool wrapatoms)
+     327             :   {
+     328             : // write positions on file trajfile
+     329             : // positions are appended at the end of the file
+     330          39 :     Vector pos;
+     331             :     FILE*fp;
+     332          39 :     if(write_positions_first) {
+     333           9 :       fp=std::fopen(trajfile.c_str(),"w");
+     334           9 :       write_positions_first=false;
+     335             :     } else {
+     336          30 :       fp=std::fopen(trajfile.c_str(),"a");
+     337             :     }
+     338          39 :     plumed_assert(fp);
+     339             : // call fclose when fp goes out of scope
+     340             :     std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     341             :     std::fprintf(fp,"%d\n",natoms);
+     342          39 :     std::fprintf(fp,"%f %f %f\n",cell[0],cell[1],cell[2]);
+     343        3847 :     for(int iatom=0; iatom<natoms; iatom++) {
+     344             : // usually, it is better not to apply pbc here, so that diffusion
+     345             : // is more easily calculated from a trajectory file:
+     346        3808 :       if(wrapatoms) pbc(cell,positions[iatom],pos);
+     347        2728 :       else pos=positions[iatom];
+     348        3808 :       std::fprintf(fp,"Ar %10.7f %10.7f %10.7f\n",pos[0],pos[1],pos[2]);
+     349             :     }
+     350          39 :   }
+     351             : 
+     352           9 :   void write_final_positions(const std::string& outputfile,int natoms,const std::vector<Vector>& positions,const double cell[3],const bool wrapatoms)
+     353             :   {
+     354             : // write positions on file outputfile
+     355           9 :     Vector pos;
+     356             :     FILE*fp;
+     357           9 :     fp=std::fopen(outputfile.c_str(),"w");
+     358           9 :     plumed_assert(fp);
+     359             : // call fclose when fp goes out of scope
+     360             :     std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     361             :     std::fprintf(fp,"%d\n",natoms);
+     362           9 :     std::fprintf(fp,"%f %f %f\n",cell[0],cell[1],cell[2]);
+     363         779 :     for(int iatom=0; iatom<natoms; iatom++) {
+     364             : // usually, it is better not to apply pbc here, so that diffusion
+     365             : // is more easily calculated from a trajectory file:
+     366         770 :       if(wrapatoms) pbc(cell,positions[iatom],pos);
+     367         554 :       else pos=positions[iatom];
+     368         770 :       std::fprintf(fp,"Ar %10.7f %10.7f %10.7f\n",pos[0],pos[1],pos[2]);
+     369             :     }
+     370           9 :   }
+     371             : 
+     372             : 
+     373         174 :   void write_statistics(const std::string & statfile,const int istep,const double tstep,
+     374             :                         const int natoms,const int ndim,const double engkin,const double engconf,const double engint) {
+     375             : // write statistics on file statfile
+     376         174 :     if(write_statistics_first) {
+     377             : // first time this routine is called, open the file
+     378           9 :       write_statistics_fp=std::fopen(statfile.c_str(),"w");
+     379             :       write_statistics_fp_deleter.reset(write_statistics_fp);
+     380           9 :       write_statistics_first=false;
+     381             :     }
+     382         174 :     if(istep-write_statistics_last_time_reopened>100) {
+     383             : // every 100 steps, reopen the file to flush the buffer
+     384             :       write_statistics_fp_deleter.reset(nullptr); // close file
+     385          16 :       write_statistics_fp=std::fopen(statfile.c_str(),"a");
+     386             :       write_statistics_fp_deleter.reset(write_statistics_fp);
+     387          16 :       write_statistics_last_time_reopened=istep;
+     388             :     }
+     389         174 :     std::fprintf(write_statistics_fp,"%d %f %f %f %f %f\n",istep,istep*tstep,2.0*engkin/double(ndim*natoms),engconf,engkin+engconf,engkin+engconf+engint);
+     390         174 :   }
+     391             : 
+     392             : 
+     393             : 
+     394           9 :   int main(FILE* in,FILE*out,PLMD::Communicator& pc) override {
+     395             :     int            natoms;       // number of atoms
+     396             :     std::vector<Vector> positions;    // atomic positions
+     397             :     std::vector<Vector> velocities;   // velocities
+     398             :     std::vector<double> masses;       // masses
+     399             :     std::vector<Vector> forces;       // forces
+     400             :     double         cell[3];      // cell size
+     401             :     double         cell9[3][3];  // cell size
+     402             : 
+     403             : // neighbour list variables
+     404             : // see Allen and Tildesey book for details
+     405             :     std::vector< std::vector<int> >  list; // neighbour list
+     406             :     std::vector<Vector> positions0;   // reference atomic positions, i.e. positions when the neighbour list
+     407             : 
+     408             : // input parameters
+     409             : // all of them have a reasonable default value, set in read_input()
+     410             :     double      tstep;             // simulation timestep
+     411             :     double      temperature;       // temperature
+     412             :     double      friction;          // friction for Langevin dynamics (for NVE, use 0)
+     413             :     double      listcutoff;        // cutoff for neighbour list
+     414             :     double      forcecutoff;       // cutoff for forces
+     415             :     int         nstep;             // number of steps
+     416             :     int         nconfig;           // stride for output of configurations
+     417             :     int         nstat;             // stride for output of statistics
+     418             :     int         ndim;              // dimensionality of the system (1, 2, or 3)
+     419             :     int         idum;              // seed
+     420             :     int         plumedWantsToStop; // stop flag
+     421             :     bool        wrapatoms;         // if true, atomic coordinates are written wrapped in minimal cell
+     422             :     std::string inputfile;         // name of file with starting configuration (xyz)
+     423             :     std::string outputfile;        // name of file with final configuration (xyz)
+     424             :     std::string trajfile;          // name of the trajectory file (xyz)
+     425             :     std::string statfile;          // name of the file with statistics
+     426             : 
+     427             :     double      epsilon, sigma;    // LJ parameters
+     428             : 
+     429             :     double engkin;                 // kinetic energy
+     430             :     double engconf;                // configurational energy
+     431             :     double engint;                 // integral for conserved energy in Langevin dynamics
+     432             : 
+     433             :     bool recompute_list;           // control if the neighbour list have to be recomputed
+     434             : 
+     435           9 :     Random random;                 // random numbers stream
+     436             : 
+     437           9 :     std::unique_ptr<PlumedMain> plumed;
+     438             : 
+     439             : // Commenting the next line it is possible to switch-off plumed
+     440           9 :     plumed=Tools::make_unique<PLMD::PlumedMain>();
+     441             : 
+     442           9 :     if(plumed) plumed->cmd("setRealPrecision",int(sizeof(double)));
+     443             : 
+     444           9 :     read_input(temperature,tstep,friction,forcecutoff,
+     445             :                listcutoff,nstep,nconfig,nstat,
+     446             :                wrapatoms,inputfile,outputfile,trajfile,statfile,
+     447             :                ndim,idum,epsilon,sigma);
+     448             : 
+     449             : // number of atoms is read from file inputfile
+     450           9 :     read_natoms(inputfile,natoms);
+     451             : 
+     452             : // write the parameters in output so they can be checked
+     453             :     std::fprintf(out,"%s %s\n","Starting configuration           :",inputfile.c_str());
+     454             :     std::fprintf(out,"%s %s\n","Final configuration              :",outputfile.c_str());
+     455           9 :     std::fprintf(out,"%s %d\n","Number of atoms                  :",natoms);
+     456           9 :     std::fprintf(out,"%s %f\n","Temperature                      :",temperature);
+     457           9 :     std::fprintf(out,"%s %f\n","Time step                        :",tstep);
+     458           9 :     std::fprintf(out,"%s %f\n","Friction                         :",friction);
+     459           9 :     std::fprintf(out,"%s %f\n","Cutoff for forces                :",forcecutoff);
+     460           9 :     std::fprintf(out,"%s %f\n","Cutoff for neighbour list        :",listcutoff);
+     461           9 :     std::fprintf(out,"%s %d\n","Number of steps                  :",nstep);
+     462           9 :     std::fprintf(out,"%s %d\n","Stride for trajectory            :",nconfig);
+     463             :     std::fprintf(out,"%s %s\n","Trajectory file                  :",trajfile.c_str());
+     464           9 :     std::fprintf(out,"%s %d\n","Stride for statistics            :",nstat);
+     465             :     std::fprintf(out,"%s %s\n","Statistics file                  :",statfile.c_str());
+     466           9 :     std::fprintf(out,"%s %d\n","Dimensionality                   :",ndim);
+     467           9 :     std::fprintf(out,"%s %d\n","Seed                             :",idum);
+     468           9 :     std::fprintf(out,"%s %s\n","Are atoms wrapped on output?     :",(wrapatoms?"T":"F"));
+     469           9 :     std::fprintf(out,"%s %f\n","Epsilon                          :",epsilon);
+     470           9 :     std::fprintf(out,"%s %f\n","Sigma                            :",sigma);
+     471             : 
+     472             : // Setting the seed
+     473           9 :     random.setSeed(idum);
+     474             : 
+     475             : // allocation of dynamical arrays
+     476           9 :     positions.resize(natoms);
+     477           9 :     positions0.resize(natoms);
+     478           9 :     velocities.resize(natoms);
+     479           9 :     forces.resize(natoms);
+     480           9 :     masses.resize(natoms);
+     481           9 :     list.resize(natoms);
+     482             : 
+     483             : // masses are hard-coded to 1
+     484         779 :     for(int i=0; i<natoms; ++i) masses[i]=1.0;
+     485             : 
+     486             : // energy integral initialized to 0
+     487           9 :     engint=0.0;
+     488             : 
+     489             : // positions are read from file inputfile
+     490           9 :     read_positions(inputfile,natoms,positions,cell);
+     491             : 
+     492             : // velocities are randomized according to temperature
+     493           9 :     randomize_velocities(natoms,ndim,temperature,masses,velocities,random);
+     494             : 
+     495           9 :     if(plumed) {
+     496           9 :       plumed->cmd("setNatoms",natoms);
+     497           9 :       plumed->cmd("setNoVirial");
+     498           9 :       plumed->cmd("setMDEngine","simpleMD");
+     499           9 :       plumed->cmd("setTimestep",tstep);
+     500           9 :       plumed->cmd("setPlumedDat","plumed.dat");
+     501           9 :       int pversion=0;
+     502           9 :       plumed->cmd("getApiVersion",&pversion);
+     503             : // setting kbT is only implemented with api>1
+     504             : // even if not necessary in principle in SimpleMD (which is part of plumed)
+     505             : // we leave the check here as a reference
+     506           9 :       if(pversion>1) plumed->cmd("setKbT",temperature);
+     507           9 :       plumed->cmd("init");
+     508             :     }
+     509             : 
+     510             : // neighbour list are computed, and reference positions are saved
+     511           9 :     compute_list(natoms,positions,cell,listcutoff,list);
+     512             : 
+     513             :     int list_size=0;
+     514         779 :     for(int i=0; i<list.size(); i++) list_size+=list[i].size();
+     515             :     std::fprintf(out,"List size: %d\n",list_size);
+     516         779 :     for(int iatom=0; iatom<natoms; ++iatom) positions0[iatom]=positions[iatom];
+     517             : 
+     518             : // forces are computed before starting md
+     519           9 :     compute_forces(natoms,epsilon,sigma,positions,cell,forcecutoff,list,forces,engconf);
+     520             : 
+     521             : // remove forces if ndim<3
+     522           9 :     if(ndim<3)
+     523          30 :       for(int iatom=0; iatom<natoms; ++iatom) for(int k=ndim; k<3; ++k) forces[iatom][k]=0.0;
+     524             : 
+     525             : // here is the main md loop
+     526             : // Langevin thermostat is applied before and after a velocity-Verlet integrator
+     527             : // the overall structure is:
+     528             : //   thermostat
+     529             : //   update velocities
+     530             : //   update positions
+     531             : //   (eventually recompute neighbour list)
+     532             : //   compute forces
+     533             : //   update velocities
+     534             : //   thermostat
+     535             : //   (eventually dump output informations)
+     536        5709 :     for(int istep=0; istep<nstep; istep++) {
+     537        5700 :       thermostat(natoms,ndim,masses,0.5*tstep,friction,temperature,velocities,engint,random);
+     538             : 
+     539      217300 :       for(int iatom=0; iatom<natoms; iatom++)
+     540      211600 :         velocities[iatom]+=forces[iatom]*0.5*tstep/masses[iatom];
+     541             : 
+     542      217300 :       for(int iatom=0; iatom<natoms; iatom++)
+     543      211600 :         positions[iatom]+=velocities[iatom]*tstep;
+     544             : 
+     545             : // a check is performed to decide whether to recalculate the neighbour list
+     546        5700 :       check_list(natoms,positions,positions0,listcutoff,forcecutoff,recompute_list);
+     547        5700 :       if(recompute_list) {
+     548         449 :         compute_list(natoms,positions,cell,listcutoff,list);
+     549       44295 :         for(int iatom=0; iatom<natoms; ++iatom) positions0[iatom]=positions[iatom];
+     550             :         int list_size=0;
+     551       44295 :         for(int i=0; i<list.size(); i++) list_size+=list[i].size();
+     552             :         std::fprintf(out,"List size: %d\n",list_size);
+     553             :       }
+     554             : 
+     555        5700 :       compute_forces(natoms,epsilon,sigma,positions,cell,forcecutoff,list,forces,engconf);
+     556             : 
+     557        5700 :       if(plumed) {
+     558        5700 :         plumedWantsToStop=0;
+     559       74100 :         for(int i=0; i<3; i++)for(int k=0; k<3; k++) cell9[i][k]=0.0;
+     560       22800 :         for(int i=0; i<3; i++) cell9[i][i]=cell[i];
+     561        5700 :         plumed->cmd("setStep",istep+1);
+     562        5700 :         plumed->cmd("setMasses",&masses[0]);
+     563        5700 :         plumed->cmd("setForces",&forces[0][0]);
+     564        5700 :         plumed->cmd("setEnergy",engconf);
+     565        5700 :         plumed->cmd("setPositions",&positions[0][0]);
+     566        5700 :         plumed->cmd("setBox",&cell9[0][0]);
+     567        5700 :         plumed->cmd("setStopFlag",&plumedWantsToStop);
+     568        5700 :         plumed->cmd("calc");
+     569        5700 :         if(plumedWantsToStop) nstep=istep;
+     570             :       }
+     571             : // remove forces if ndim<3
+     572        5700 :       if(ndim<3)
+     573       60000 :         for(int iatom=0; iatom<natoms; ++iatom) for(int k=ndim; k<3; ++k) forces[iatom][k]=0.0;
+     574             : 
+     575      217300 :       for(int iatom=0; iatom<natoms; iatom++)
+     576      211600 :         velocities[iatom]+=forces[iatom]*0.5*tstep/masses[iatom];
+     577             : 
+     578        5700 :       thermostat(natoms,ndim,masses,0.5*tstep,friction,temperature,velocities,engint,random);
+     579             : 
+     580             : // kinetic energy is calculated
+     581        5700 :       compute_engkin(natoms,masses,velocities,engkin);
+     582             : 
+     583             : // eventually, write positions and statistics
+     584        5700 :       if((istep+1)%nconfig==0) write_positions(trajfile,natoms,positions,cell,wrapatoms);
+     585        5700 :       if((istep+1)%nstat==0)   write_statistics(statfile,istep+1,tstep,natoms,ndim,engkin,engconf,engint);
+     586             : 
+     587             :     }
+     588             : 
+     589             : // call final plumed jobs
+     590           9 :     plumed->cmd("runFinalJobs");
+     591             : 
+     592             : // write final positions
+     593           9 :     write_final_positions(outputfile,natoms,positions,cell,wrapatoms);
+     594             : 
+     595           9 :     return 0;
+     596          18 :   }
+     597             : 
+     598             : 
+     599             : };
+     600             : 
+     601       12574 : PLUMED_REGISTER_CLTOOL(SimpleMD,"simplemd")
+     602             : 
+     603             : }
+     604             : }
+     605             : 
+     606             : 
+     607             : 
+     608             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SumHills.cpp.func-sort-c.html b/coverage/cltools/SumHills.cpp.func-sort-c.html new file mode 100644 index 000000000000..c6e703824772 --- /dev/null +++ b/coverage/cltools/SumHills.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SumHills.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19621690.7 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7cltools14CLToolSumHills11descriptionB5cxx11Ev4
_ZN4PLMD7cltools14CLToolSumHills18findCvsAndPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IS7_SaIS7_EESaISC_EERSC_SG_RbRS7_SI_9
_ZN4PLMD7cltools14CLToolSumHills4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools14CLToolSumHillsC2ERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeD2Ev4187
_ZN4PLMD7cltools14CLToolSumHills16registerKeywordsERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SumHills.cpp.func.html b/coverage/cltools/SumHills.cpp.func.html new file mode 100644 index 000000000000..26f0134cfd58 --- /dev/null +++ b/coverage/cltools/SumHills.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SumHills.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19621690.7 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMe6createERKNS_13CLToolOptionsE13
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_124CLToolSumHillsRegisterMeD2Ev4187
_ZN4PLMD7cltools14CLToolSumHills16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools14CLToolSumHills18findCvsAndPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IS7_SaIS7_EESaISC_EERSC_SG_RbRS7_SI_9
_ZN4PLMD7cltools14CLToolSumHills4mainEP8_IO_FILES3_RNS_12CommunicatorE9
_ZN4PLMD7cltools14CLToolSumHillsC2ERKNS_13CLToolOptionsE13
_ZNK4PLMD7cltools14CLToolSumHills11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/SumHills.cpp.gcov.html b/coverage/cltools/SumHills.cpp.gcov.html new file mode 100644 index 000000000000..a55f29b86330 --- /dev/null +++ b/coverage/cltools/SumHills.cpp.gcov.html @@ -0,0 +1,702 @@ + + + + + + + + LCOV - plumed test coverage - cltools/SumHills.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - SumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19621690.7 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "core/Action.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "tools/Communicator.h"
+      29             : #include "tools/Random.h"
+      30             : #include <cstdio>
+      31             : #include <string>
+      32             : #include <vector>
+      33             : #include <iostream>
+      34             : #include "tools/File.h"
+      35             : #include "core/Value.h"
+      36             : #include "tools/Matrix.h"
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace cltools {
+      40             : 
+      41             : //+PLUMEDOC TOOLS sum_hills
+      42             : /*
+      43             : sum_hills is a tool that allows one to to use plumed to post-process an existing hills/colvar file
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : a typical case is about the integration of a hills file:
+      48             : 
+      49             : \verbatim
+      50             : plumed sum_hills  --hills PATHTOMYHILLSFILE
+      51             : \endverbatim
+      52             : 
+      53             : The default name for the output file will be fes.dat
+      54             : Note that starting from this version plumed will automatically detect the
+      55             : number of the variables you have and their periodicity.
+      56             : Additionally, if you use flexible hills (multivariate Gaussian kernels), plumed will understand it from the HILLS file.
+      57             : 
+      58             : The sum_hills tool will also accept multiple files that will be integrated one after the other
+      59             : 
+      60             : \verbatim
+      61             : plumed sum_hills  --hills PATHTOMYHILLSFILE1,PATHTOMYHILLSFILE2,PATHTOMYHILLSFILE3
+      62             : \endverbatim
+      63             : 
+      64             : if you want to integrate out some variable you do
+      65             : 
+      66             : \verbatim
+      67             : plumed sum_hills  --hills PATHTOMYHILLSFILE   --idw t1 --kt 0.6
+      68             : \endverbatim
+      69             : 
+      70             : where with --idw you define the variables that you want
+      71             : all the others will be integrated out. --kt defines the temperature of the system in energy units.
+      72             : (be consistent with the units you have in your hills: plumed will not check this for you)
+      73             : If you need more variables then you may use a comma separated syntax
+      74             : 
+      75             : \verbatim
+      76             : plumed sum_hills  --hills PATHTOMYHILLSFILE   --idw t1,t2 --kt 0.6
+      77             : \endverbatim
+      78             : 
+      79             : You can define the output grid only with the number of bins you want
+      80             : while min/max will be detected for you
+      81             : 
+      82             : \verbatim
+      83             : plumed sum_hills --bin 99,99 --hills PATHTOMYHILLSFILE
+      84             : \endverbatim
+      85             : 
+      86             : or full grid specification
+      87             : 
+      88             : \verbatim
+      89             : plumed sum_hills --bin 99,99 --min -pi,-pi --max pi,pi --hills PATHTOMYHILLSFILE
+      90             : \endverbatim
+      91             : 
+      92             : You can of course use numbers instead of -pi/pi.
+      93             : 
+      94             : You can use a --stride keyword to have a dump each bunch of hills you read
+      95             : \verbatim
+      96             : plumed sum_hills --stride 300 --hills PATHTOMYHILLSFILE
+      97             : \endverbatim
+      98             : 
+      99             : You can also have, in case of well tempered metadynamics, only the negative
+     100             : bias instead of the free energy through the keyword --negbias
+     101             : 
+     102             : \verbatim
+     103             : plumed sum_hills --negbias --hills PATHTOMYHILLSFILE
+     104             : \endverbatim
+     105             : 
+     106             : Here the default name will be negativebias.dat
+     107             : 
+     108             : From time to time you might need to use HILLS or a COLVAR file
+     109             : as it was just a simple set  of points from which you want to build
+     110             : a free energy by using -(1/beta)log(P)
+     111             : then you use --histo
+     112             : 
+     113             : \verbatim
+     114             : plumed sum_hills --histo PATHTOMYCOLVARORHILLSFILE  --sigma 0.2,0.2 --kt 0.6
+     115             : \endverbatim
+     116             : 
+     117             : in this case you need a --kt to do the reweighting and then you
+     118             : need also some width (with the --sigma keyword) for the histogram calculation (actually will be done with
+     119             : Gaussian kernels, so it will be a continuous histogram)
+     120             : Here the default output will be histo.dat.
+     121             : Note that also here you can have multiple input files separated by a comma.
+     122             : 
+     123             : Additionally, if you want to do histogram and hills from the same file you can do as this
+     124             : \verbatim
+     125             : plumed sum_hills --hills --histo PATHTOMYCOLVARORHILLSFILE  --sigma 0.2,0.2 --kt 0.6
+     126             : \endverbatim
+     127             : The two files can be eventually the same
+     128             : 
+     129             : Another interesting thing one can do is monitor the difference in blocks as a metadynamics goes on.
+     130             : When the bias deposited is constant over the whole domain one can consider to be at convergence.
+     131             : This can be done with the --nohistory keyword
+     132             : 
+     133             : \verbatim
+     134             : plumed sum_hills --stride 300 --hills PATHTOMYHILLSFILE  --nohistory
+     135             : \endverbatim
+     136             : 
+     137             : and similarly one can do the same for an histogram file
+     138             : 
+     139             : \verbatim
+     140             : plumed sum_hills --histo PATHTOMYCOLVARORHILLSFILE  --sigma 0.2,0.2 --kt 0.6 --nohistory
+     141             : \endverbatim
+     142             : 
+     143             : just to check the hypothetical free energy calculated in single blocks of time during a simulation
+     144             : and not in a cumulative way
+     145             : 
+     146             : Output format can be controlled via the --fmt field
+     147             : 
+     148             : \verbatim
+     149             : plumed sum_hills --hills PATHTOMYHILLSFILE  --fmt %8.3f
+     150             : \endverbatim
+     151             : 
+     152             : where here we chose a float with length of 8 and 3 digits
+     153             : 
+     154             : The output can be named in a arbitrary way  :
+     155             : 
+     156             : \verbatim
+     157             : plumed sum_hills --hills PATHTOMYHILLSFILE  --outfile myfes.dat
+     158             : \endverbatim
+     159             : 
+     160             : will produce a file myfes.dat which contains the free energy.
+     161             : 
+     162             : If you use stride, this keyword is the suffix
+     163             : 
+     164             : \verbatim
+     165             : plumed sum_hills --hills PATHTOMYHILLSFILE  --outfile myfes_ --stride 100
+     166             : \endverbatim
+     167             : 
+     168             : will produce myfes_0.dat,  myfes_1.dat, myfes_2.dat etc.
+     169             : 
+     170             : The same is true for the output coming from histogram
+     171             : \verbatim
+     172             : plumed sum_hills --histo HILLS --kt 2.5 --sigma 0.01 --outhisto myhisto.dat
+     173             : \endverbatim
+     174             : 
+     175             : is producing a file myhisto.dat
+     176             : while, when using stride, this is the suffix
+     177             : 
+     178             : \verbatim
+     179             : plumed sum_hills --histo HILLS --kt 2.5 --sigma 0.01 --outhisto myhisto_ --stride 100
+     180             : \endverbatim
+     181             : 
+     182             : that gives  myhisto_0.dat,  myhisto_1.dat,  myhisto_3.dat etc..
+     183             : 
+     184             : */
+     185             : //+ENDPLUMEDOC
+     186             : 
+     187             : class CLToolSumHills : public CLTool {
+     188             : public:
+     189             :   static void registerKeywords( Keywords& keys );
+     190             :   explicit CLToolSumHills(const CLToolOptions& co );
+     191             :   int main(FILE* in,FILE*out,Communicator& pc) override;
+     192             :   std::string description()const override;
+     193             : /// find a list of variables present, if they are periodic and which is the period
+     194             : /// return false if the file does not exist
+     195             :   static bool findCvsAndPeriodic(const std::string & filename, std::vector< std::vector <std::string> > &cvs,std::vector<std::string> &pmin,std::vector<std::string> &pmax, bool &multivariate, std::string &lowI_, std::string &uppI_);
+     196             : };
+     197             : 
+     198        4187 : void CLToolSumHills::registerKeywords( Keywords& keys ) {
+     199        4187 :   CLTool::registerKeywords( keys );
+     200        8374 :   keys.addFlag("--help-debug",false,"print special options that can be used to create regtests");
+     201        8374 :   keys.add("optional","--hills","specify the name of the hills file");
+     202        8374 :   keys.add("optional","--histo","specify the name of the file for histogram a colvar/hills file is good");
+     203        8374 :   keys.add("optional","--stride","specify the stride for integrating hills file (default 0=never)");
+     204        8374 :   keys.add("optional","--min","the lower bounds for the grid");
+     205        8374 :   keys.add("optional","--max","the upper bounds for the grid");
+     206        8374 :   keys.add("optional","--bin","the number of bins for the grid");
+     207        8374 :   keys.add("optional","--spacing","grid spacing, alternative to the number of bins");
+     208        8374 :   keys.add("optional","--idw","specify the variables to be used for the free-energy/histogram (default is all). With --hills the other variables will be integrated out, with --histo the other variables won't be considered");
+     209        8374 :   keys.add("optional","--outfile","specify the output file for sumhills");
+     210        8374 :   keys.add("optional","--outhisto","specify the output file for the histogram");
+     211        8374 :   keys.add("optional","--kt","specify temperature in energy units for integrating out variables");
+     212        8374 :   keys.add("optional","--sigma"," a vector that specify the sigma for binning (only needed when doing histogram ");
+     213        8374 :   keys.addFlag("--negbias",false," print the negative bias instead of the free energy (only needed with well tempered runs and flexible hills) ");
+     214        8374 :   keys.addFlag("--nohistory",false," to be used with --stride:  it splits the bias/histogram in pieces without previous history ");
+     215        8374 :   keys.addFlag("--mintozero",false," it translate all the minimum value in bias/histogram to zero (useful to compare results) ");
+     216        8374 :   keys.add("optional","--fmt","specify the output format");
+     217        4187 : }
+     218             : 
+     219          13 : CLToolSumHills::CLToolSumHills(const CLToolOptions& co ):
+     220          13 :   CLTool(co)
+     221             : {
+     222          13 :   inputdata=commandline;
+     223          13 : }
+     224             : 
+     225           4 : std::string CLToolSumHills::description()const { return "sum the hills with  plumed"; }
+     226             : 
+     227           9 : int CLToolSumHills::main(FILE* in,FILE*out,Communicator& pc) {
+     228             : 
+     229             : // Read the hills input file name
+     230             :   std::vector<std::string> hillsFiles;
+     231             :   bool dohills;
+     232          18 :   dohills=parseVector("--hills",hillsFiles);
+     233             : // Read the histogram file
+     234             :   std::vector<std::string> histoFiles;
+     235             :   bool dohisto;
+     236           9 :   dohisto=parseVector("--histo",histoFiles);
+     237             : 
+     238           9 :   plumed_massert(dohisto || dohills,"you should use --histo or/and --hills command");
+     239             : 
+     240             :   std::vector< std::vector<std::string> > vcvs;
+     241             :   std::vector<std::string> vpmin;
+     242             :   std::vector<std::string> vpmax;
+     243             :   std::string lowI_, uppI_;
+     244           9 :   if(dohills) {
+     245             :     // parse it as it was a restart
+     246             :     bool vmultivariate;
+     247           8 :     findCvsAndPeriodic(hillsFiles[0], vcvs, vpmin, vpmax, vmultivariate, lowI_, uppI_);
+     248             :   }
+     249             : 
+     250             :   std::vector< std::vector<std::string> > hcvs;
+     251             :   std::vector<std::string> hpmin;
+     252             :   std::vector<std::string> hpmax;
+     253             : 
+     254             :   std::vector<std::string> sigma;
+     255           9 :   if(dohisto) {
+     256             :     bool hmultivariate;
+     257           1 :     findCvsAndPeriodic(histoFiles[0], hcvs, hpmin, hpmax, hmultivariate, lowI_, uppI_);
+     258             :     // here need also the vector of sigmas
+     259           2 :     parseVector("--sigma",sigma);
+     260           1 :     if(sigma.size()==0)plumed_merror("you should define --sigma vector when using histogram");
+     261             :     lowI_=uppI_="-1.";  // Interval is not use for histograms
+     262             :   }
+     263             : 
+     264           9 :   if(dohisto && dohills) {
+     265           0 :     plumed_massert(vcvs==hcvs,"variables for histogram and bias should have the same labels");
+     266           0 :     plumed_massert(hpmin==vpmin,"variables for histogram and bias should have the same min for periodicity");
+     267           0 :     plumed_massert(hpmax==vpmax,"variables for histogram and bias should have the same max for periodicity");
+     268             :   }
+     269             : 
+     270             :   // now put into a neutral vector
+     271             : 
+     272             :   std::vector< std::vector<std::string> > cvs;
+     273             :   std::vector<std::string> pmin;
+     274             :   std::vector<std::string> pmax;
+     275             : 
+     276           9 :   if(dohills) {
+     277           8 :     cvs=vcvs;
+     278           8 :     pmin=vpmin;
+     279           8 :     pmax=vpmax;
+     280             :   }
+     281           9 :   if(dohisto) {
+     282           1 :     cvs=hcvs;
+     283           1 :     pmin=hpmin;
+     284           1 :     pmax=hpmax;
+     285             :   }
+     286             : 
+     287             : 
+     288             :   // setup grids
+     289             :   unsigned grid_check=0;
+     290           9 :   std::vector<std::string> gmin(cvs.size());
+     291          18 :   if(parseVector("--min",gmin)) {
+     292           4 :     if(gmin.size()!=cvs.size() && gmin.size()!=0) plumed_merror("not enough values for --min");
+     293             :     grid_check++;
+     294             :   }
+     295           9 :   std::vector<std::string> gmax(cvs.size() );
+     296          18 :   if(parseVector("--max",gmax)) {
+     297           4 :     if(gmax.size()!=cvs.size() && gmax.size()!=0) plumed_merror("not enough values for --max");
+     298           4 :     grid_check++;
+     299             :   }
+     300           9 :   std::vector<std::string> gbin(cvs.size());
+     301             :   bool grid_has_bin; grid_has_bin=false;
+     302          18 :   if(parseVector("--bin",gbin)) {
+     303           5 :     if(gbin.size()!=cvs.size() && gbin.size()!=0) plumed_merror("not enough values for --bin");
+     304             :     grid_has_bin=true;
+     305             :   }
+     306           9 :   std::vector<std::string> gspacing(cvs.size());
+     307             :   bool grid_has_spacing; grid_has_spacing=false;
+     308          18 :   if(parseVector("--spacing",gspacing)) {
+     309           1 :     if(gspacing.size()!=cvs.size() && gspacing.size()!=0) plumed_merror("not enough values for --spacing");
+     310             :     grid_has_spacing=true;
+     311             :   }
+     312             :   // allowed: no grids only bin
+     313             :   // not allowed: partial grid definition
+     314           9 :   plumed_massert( gmin.size()==gmax.size() && (gmin.size()==0 ||  gmin.size()==cvs.size() ),"you should specify --min and --max together with same number of components");
+     315             : 
+     316             : 
+     317             : 
+     318           9 :   PlumedMain plumed;
+     319             :   std::string ss;
+     320           9 :   unsigned nn=1;
+     321             :   ss="setNatoms";
+     322           9 :   plumed.cmd(ss,&nn);
+     323           9 :   if(Communicator::initialized())  plumed.cmd("setMPIComm",&pc.Get_comm());
+     324           9 :   plumed.cmd("init",&nn);
+     325           9 :   std::vector <bool> isdone(cvs.size(),false);
+     326          26 :   for(unsigned i=0; i<cvs.size(); i++) {
+     327          17 :     if(!isdone[i]) {
+     328             :       isdone[i]=true;
+     329             :       std::vector<std::string> actioninput;
+     330             :       std::vector <unsigned> inds;
+     331          17 :       actioninput.push_back("FAKE");
+     332          34 :       actioninput.push_back("ATOMS=1");
+     333          34 :       actioninput.push_back("LABEL="+cvs[i][0]);
+     334             :       std::vector<std::string> comps, periods;
+     335          17 :       if(cvs[i].size()>1) {comps.push_back(cvs[i][1]); inds.push_back(i);}
+     336          17 :       periods.push_back(pmin[i]); periods.push_back(pmax[i]);
+     337          25 :       for(unsigned j=i+1; j<cvs.size(); j++) {
+     338           8 :         if(cvs[i][0]==cvs[j][0] && !isdone[j]) {
+     339           0 :           if(cvs[i].size()==1 || cvs[j].size()==1  )plumed_merror("you cannot have twice the same label and no components ");
+     340           0 :           if(cvs[j].size()>1) {
+     341           0 :             comps.push_back(cvs[j][1]);
+     342           0 :             periods.push_back(pmin[j]); periods.push_back(pmax[j]);
+     343           0 :             isdone[j]=true; inds.push_back(j);
+     344             :           }
+     345             :         }
+     346             : 
+     347             :       }
+     348             :       // drain all the components
+     349             :       std::string addme;
+     350          17 :       if(comps.size()>0) {
+     351             :         addme="COMPONENTS=";
+     352           1 :         for(unsigned i=0; i<comps.size()-1; i++)addme+=comps[i]+",";
+     353             :         addme+=comps.back();
+     354           1 :         actioninput.push_back(addme);
+     355             :       }
+     356             :       // periodicity (always explicit here)
+     357             :       addme="PERIODIC=";
+     358          34 :       for(unsigned j=0; j<periods.size()-1; j++) {
+     359          34 :         addme+=periods[j]+",";
+     360             :       }
+     361             :       addme+=periods.back();
+     362          17 :       actioninput.push_back(addme);
+     363          18 :       for(unsigned j=0; j<inds.size(); j++) {
+     364           1 :         unsigned jj; jj=inds[j];
+     365           1 :         if(grid_check==2) {
+     366             :           double gm;
+     367             :           double pm;
+     368           1 :           if(pmin[jj]!="none") {
+     369           1 :             Tools::convert(gmin[jj],gm);
+     370           1 :             Tools::convert(pmin[jj],pm);
+     371           1 :             if(  gm<pm  ) {
+     372           0 :               plumed_merror("Periodicity issue : GRID_MIN value ( "+gmin[jj]+" ) is less than periodicity in HILLS file in "+cvs[jj][0]+ " ( "+pmin[jj]+" ) ");
+     373             :             }
+     374             :           }
+     375           1 :           if(pmax[jj]!="none") {
+     376           1 :             Tools::convert(gmax[jj],gm);
+     377           1 :             Tools::convert(pmax[jj],pm);
+     378           1 :             if(  gm>pm ) {
+     379           0 :               plumed_merror("Periodicity issue : GRID_MAX value ( "+gmax[jj]+" ) is more than periodicity in HILLS file in "+cvs[jj][0]+ " ( "+pmax[jj]+" ) ");
+     380             :             }
+     381             :           }
+     382             :         }
+     383             :       }
+     384             : 
+     385             : //  for(unsigned i=0;i< actioninput.size();i++){
+     386             : //    cerr<<"AA "<<actioninput[i]<<endl;
+     387             : //  }
+     388          17 :       plumed.readInputWords(actioninput,false);
+     389          34 :     }
+     390             : 
+     391             :   }
+     392           9 :   unsigned ncv=cvs.size();
+     393             :   std::vector<std::string> actioninput;
+     394             :   std::vector<std::string> idw;
+     395             :   // check if the variables to be used are correct
+     396          18 :   if(parseVector("--idw",idw)) {
+     397           4 :     for(unsigned i=0; i<idw.size(); i++) {
+     398             :       bool found=false;
+     399           6 :       for(unsigned j=0; j<cvs.size(); j++) {
+     400           4 :         if(cvs[j].size()>1) {
+     401           0 :           if(idw[i]==cvs[j][0]+"."+cvs[j][1])found=true;
+     402             :         } else {
+     403           4 :           if(idw[i]==cvs[j][0])found=true;
+     404             :         }
+     405             :       }
+     406           2 :       if(!found)plumed_merror("variable "+idw[i]+" is not found in the bunch of cvs: revise your --idw option" );
+     407             :     }
+     408           2 :     plumed_massert( idw.size()<=cvs.size(),"the number of variables to be integrated should be at most equal to the total number of cvs  ");
+     409             :     // in this case you need a beta factor!
+     410             :   }
+     411             : 
+     412           9 :   std::string kt; kt=std::string("1.");// assign an arbitrary value just in case that idw.size()==cvs.size()
+     413           9 :   if ( dohisto || idw.size()!=0  ) {
+     414           6 :     plumed_massert(parse("--kt",kt),"if you make a dimensionality reduction (--idw) or a histogram (--histo) then you need to define --kt ");
+     415             :   }
+     416             : 
+     417             :   std::string addme;
+     418             : 
+     419           9 :   actioninput.push_back("FUNCSUMHILLS");
+     420          18 :   actioninput.push_back("ISCLTOOL");
+     421             : 
+     422             :   // set names
+     423             :   std::string outfile;
+     424          18 :   if(parse("--outfile",outfile)) {
+     425           0 :     actioninput.push_back("OUTHILLS="+outfile);
+     426             :   }
+     427             :   std::string outhisto;
+     428          18 :   if(parse("--outhisto",outhisto)) {
+     429           2 :     actioninput.push_back("OUTHISTO="+outhisto);
+     430             :   }
+     431             : 
+     432             : 
+     433             :   addme="ARG=";
+     434          17 :   for(unsigned i=0; i<(ncv-1); i++) {
+     435           8 :     if(cvs[i].size()==1) {
+     436          16 :       addme+=std::string(cvs[i][0])+",";
+     437             :     } else {
+     438           0 :       addme+=std::string(cvs[i][0])+"."+std::string(cvs[i][1])+",";
+     439             :     }
+     440             :   }
+     441           9 :   if(cvs[ncv-1].size()==1) {
+     442          16 :     addme+=std::string(cvs[ncv-1][0]);
+     443             :   } else {
+     444           2 :     addme+=std::string(cvs[ncv-1][0])+"."+std::string(cvs[ncv-1][1]);
+     445             :   }
+     446           9 :   actioninput.push_back(addme);
+     447             :   //for(unsigned i=0;i< actioninput.size();i++){
+     448             :   //  cerr<<"AA "<<actioninput[i]<<endl;
+     449             :   //}
+     450           9 :   if(dohills) {
+     451           9 :     addme="HILLSFILES="; for(unsigned i=0; i<hillsFiles.size()-1; i++)addme+=hillsFiles[i]+","; addme+=hillsFiles[hillsFiles.size()-1];
+     452           8 :     actioninput.push_back(addme);
+     453             :     // set the grid
+     454             :   }
+     455           9 :   if(grid_check==2) {
+     456           7 :     addme="GRID_MAX="; for(unsigned i=0; i<(ncv-1); i++)addme+=gmax[i]+","; addme+=gmax[ncv-1];
+     457           4 :     actioninput.push_back(addme);
+     458           7 :     addme="GRID_MIN="; for(unsigned i=0; i<(ncv-1); i++)addme+=gmin[i]+","; addme+=gmin[ncv-1];
+     459           4 :     actioninput.push_back(addme);
+     460             :   }
+     461           9 :   if(grid_has_bin) {
+     462          10 :     addme="GRID_BIN="; for(unsigned i=0; i<(ncv-1); i++)addme+=gbin[i]+","; addme+=gbin[ncv-1];
+     463           5 :     actioninput.push_back(addme);
+     464             :   }
+     465           9 :   if(grid_has_spacing) {
+     466           1 :     addme="GRID_SPACING="; for(unsigned i=0; i<(ncv-1); i++)addme+=gspacing[i]+","; addme+=gspacing[ncv-1];
+     467           1 :     actioninput.push_back(addme);
+     468             :   }
+     469             :   std::string  stride; stride="";
+     470          18 :   if(parse("--stride",stride)) {
+     471           1 :     actioninput.push_back("INITSTRIDE="+stride);
+     472             :     bool  nohistory;
+     473           1 :     parseFlag("--nohistory",nohistory);
+     474           1 :     if(nohistory) {
+     475           0 :       actioninput.push_back("NOHISTORY");
+     476             :     }
+     477             :   }
+     478             :   bool  mintozero;
+     479           9 :   parseFlag("--mintozero",mintozero);
+     480           9 :   if(mintozero) {
+     481           0 :     actioninput.push_back("MINTOZERO");
+     482             :   }
+     483           9 :   if(idw.size()!=0) {
+     484             :     addme="PROJ=";
+     485           2 :     for(unsigned i=0; i<idw.size()-1; i++) {addme+=idw[i]+",";}
+     486             :     addme+=idw.back();
+     487           2 :     actioninput.push_back(addme);
+     488             :   }
+     489             : 
+     490           9 :   if(dohisto) {
+     491           1 :     if(idw.size()==0) {
+     492           1 :       if(sigma.size()!=hcvs.size()) plumed_merror("you should define as many --sigma vector as the number of collective variable used for the histogram ");
+     493             :     } else {
+     494           0 :       if(idw.size()!=sigma.size()) plumed_merror("you should define as many --sigma vector as the number of collective variable used for the histogram ");
+     495             :     }
+     496             :   }
+     497             : 
+     498           9 :   if(idw.size()!=0 || dohisto) {
+     499           6 :     actioninput.push_back("KT="+kt);
+     500             :   }
+     501           9 :   if(dohisto) {
+     502           1 :     addme="HISTOFILES="; for(unsigned i=0; i<histoFiles.size()-1; i++) {addme+=histoFiles[i]+",";} addme+=histoFiles[histoFiles.size()-1];
+     503           1 :     actioninput.push_back(addme);
+     504             : 
+     505             :     addme="HISTOSIGMA=";
+     506           2 :     for(unsigned i=0; i<sigma.size()-1; i++) {addme+=sigma[i]+",";}
+     507             :     addme+=sigma.back();
+     508           1 :     actioninput.push_back(addme);
+     509             :   }
+     510             : 
+     511             :   bool negbias;
+     512           9 :   parseFlag("--negbias",negbias);
+     513           9 :   if(negbias) {
+     514           2 :     actioninput.push_back("NEGBIAS");
+     515             :   }
+     516             : 
+     517           9 :   if(lowI_!=uppI_) {
+     518           0 :     addme="INTERVAL="; addme+=lowI_+","; addme+=uppI_;
+     519           0 :     actioninput.push_back(addme);
+     520             :   }
+     521             : 
+     522             :   std::string fmt; fmt="";
+     523          18 :   parse("--fmt",fmt);
+     524          18 :   if(fmt!="")actioninput.push_back("FMT="+fmt);
+     525             : 
+     526             : 
+     527             : //  for(unsigned i=0;i< actioninput.size();i++){
+     528             : //   cerr<<"AA "<<actioninput[i]<<endl;
+     529             : //  }
+     530           9 :   plumed.readInputWords(actioninput,false);
+     531             :   // if not a grid, then set it up automatically
+     532           9 :   return 0;
+     533          27 : }
+     534             : 
+     535           9 : bool CLToolSumHills::findCvsAndPeriodic(const std::string & filename, std::vector< std::vector<std::string>  > &cvs, std::vector<std::string> &pmin,std::vector<std::string> &pmax, bool &multivariate, std::string &lowI_, std::string &uppI_) {
+     536           9 :   IFile ifile;
+     537           9 :   ifile.allowIgnoredFields();
+     538             :   std::vector<std::string> fields;
+     539           9 :   if(ifile.FileExist(filename)) {
+     540             :     cvs.clear(); pmin.clear(); pmax.clear();
+     541           9 :     ifile.open(filename);
+     542           9 :     ifile.scanFieldList(fields);
+     543             :     bool before_sigma=true;
+     544         121 :     for(unsigned i=0; i<fields.size(); i++) {
+     545             :       size_t pos = 0;
+     546             :       size_t founds,foundm,foundp;
+     547             :       //found=(fields[i].find("sigma_", pos) || fields[i].find("min_", pos) || fields[i].find("max_", pos) ) ;
+     548         112 :       founds=fields[i].find("sigma_", pos)  ;
+     549         112 :       foundm=fields[i].find("min_", pos)  ;
+     550         112 :       foundp=fields[i].find("max_", pos)  ;
+     551         112 :       if (founds!=std::string::npos || foundm!=std::string::npos ||  foundp!=std::string::npos )before_sigma=false;
+     552             :       // cvs are after time and before sigmas
+     553             :       size_t  found;
+     554         112 :       found=fields[i].find("time", pos);
+     555         112 :       if( found==std::string::npos && before_sigma) {
+     556             :         // separate the components
+     557             :         size_t dot=fields[i].find_first_of('.');
+     558             :         std::vector<std::string> ss;
+     559             :         // this loop does not take into account repetitions
+     560          17 :         if(dot!=std::string::npos) {
+     561           1 :           std::string a=fields[i].substr(0,dot);
+     562           1 :           std::string name=fields[i].substr(dot+1);
+     563           1 :           ss.push_back(a);
+     564           1 :           ss.push_back(name);
+     565           1 :           cvs.push_back(ss);
+     566             :         } else {
+     567             :           std::vector<std::string> ss;
+     568          16 :           ss.push_back(fields[i]);
+     569          16 :           cvs.push_back(ss);
+     570          16 :         }
+     571             :         //std::cerr<<"found variable number  "<<cvs.size()<<" :  "<<cvs.back()[0]<<std::endl;
+     572             :         //if((cvs.back()).size()!=1){
+     573             :         //      std::cerr<<"component    "<<(cvs.back()).back()<<std::endl;
+     574             :         //}
+     575             :         // get periodicity
+     576          17 :         pmin.push_back("none");
+     577          34 :         pmax.push_back("none");
+     578          18 :         std::string mm; if((cvs.back()).size()>1) {mm=cvs.back()[0]+"."+cvs.back()[1];} else {mm=cvs.back()[0];}
+     579          34 :         if(ifile.FieldExist("min_"+mm)) {
+     580             :           std::string val;
+     581          28 :           ifile.scanField("min_"+mm,val);
+     582             :           pmin[pmin.size()-1]=val;
+     583             :           // std::cerr<<"found min   :  "<<pmin.back()<<std::endl;
+     584             :         }
+     585             :         //std::cerr<<"found min   :  "<<pmin.back()<<std::endl;
+     586          34 :         if(ifile.FieldExist("max_"+mm)) {
+     587             :           std::string val;
+     588          28 :           ifile.scanField("max_"+mm,val);
+     589             :           pmax[pmax.size()-1]=val;
+     590             :           // std::cerr<<"found max   :  "<<pmax.back()<<std::endl;
+     591             :         }
+     592             :         //std::cerr<<"found max   :  "<<pmax.back()<<std::endl;
+     593          17 :       }
+     594             :     }
+     595             :     // is multivariate ???
+     596             :     std::string sss;
+     597           9 :     multivariate=false;
+     598          18 :     if(ifile.FieldExist("multivariate")) {
+     599             :       ;
+     600          18 :       ifile.scanField("multivariate",sss);
+     601           9 :       if(sss=="true") { multivariate=true;}
+     602           3 :       else if(sss=="false") { multivariate=false;}
+     603             :     }
+     604             :     // do interval?
+     605          18 :     if(ifile.FieldExist("lower_int")) {
+     606           0 :       ifile.scanField("lower_int",lowI_);
+     607           0 :       ifile.scanField("upper_int",uppI_);
+     608             :     } else {
+     609             :       lowI_="-1.";
+     610             :       uppI_="-1.";
+     611             :     }
+     612           9 :     ifile.scanField();
+     613             :     return true;
+     614             :   } else {
+     615             :     return false;
+     616             :   }
+     617           9 : }
+     618             : 
+     619             : 
+     620       12574 : PLUMED_REGISTER_CLTOOL(CLToolSumHills,"sum_hills")
+     621             : 
+     622             : 
+     623             : 
+     624             : }
+     625             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/index-sort-f.html b/coverage/cltools/index-sort-f.html new file mode 100644 index 000000000000..34601e05df93 --- /dev/null +++ b/coverage/cltools/index-sort-f.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1381177877.7 %
Date:2024-02-22 21:58:45Functions:10912289.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Benchmark.cpp +
20.8%20.8%
+
20.8 %15 / 7260.0 %6 / 10
GenExample.cpp +
7.7%7.7%
+
7.7 %17 / 22066.7 %6 / 9
Driver.cpp +
89.6%89.6%
+
89.6 %552 / 61675.0 %9 / 12
GenTemplate.cpp +
56.5%56.5%
+
56.5 %13 / 2385.7 %6 / 7
Completion.cpp +
27.8%27.8%
+
27.8 %10 / 3685.7 %6 / 7
kT.cpp +
63.2%63.2%
+
63.2 %12 / 1985.7 %6 / 7
DriverDouble.cpp +
100.0%
+
100.0 %1 / 1100.0 %3 / 3
DriverFloat.cpp +
100.0%
+
100.0 %2 / 2100.0 %4 / 4
Info.cpp +
83.0%83.0%
+
83.0 %39 / 47100.0 %7 / 7
GenJson.cpp +
100.0%
+
100.0 %91 / 91100.0 %7 / 7
Manual.cpp +
100.0%
+
100.0 %24 / 24100.0 %7 / 7
PdbRenumber.cpp +
96.2%96.2%
+
96.2 %51 / 53100.0 %7 / 7
pesmd.cpp +
100.0%
+
100.0 %127 / 127100.0 %7 / 7
SumHills.cpp +
90.7%90.7%
+
90.7 %196 / 216100.0 %8 / 8
SimpleMD.cpp +
100.0%
+
100.0 %231 / 231100.0 %20 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/index-sort-l.html b/coverage/cltools/index-sort-l.html new file mode 100644 index 000000000000..dc9d9b8b889e --- /dev/null +++ b/coverage/cltools/index-sort-l.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1381177877.7 %
Date:2024-02-22 21:58:45Functions:10912289.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
GenExample.cpp +
7.7%7.7%
+
7.7 %17 / 22066.7 %6 / 9
Benchmark.cpp +
20.8%20.8%
+
20.8 %15 / 7260.0 %6 / 10
Completion.cpp +
27.8%27.8%
+
27.8 %10 / 3685.7 %6 / 7
GenTemplate.cpp +
56.5%56.5%
+
56.5 %13 / 2385.7 %6 / 7
kT.cpp +
63.2%63.2%
+
63.2 %12 / 1985.7 %6 / 7
Info.cpp +
83.0%83.0%
+
83.0 %39 / 47100.0 %7 / 7
Driver.cpp +
89.6%89.6%
+
89.6 %552 / 61675.0 %9 / 12
SumHills.cpp +
90.7%90.7%
+
90.7 %196 / 216100.0 %8 / 8
PdbRenumber.cpp +
96.2%96.2%
+
96.2 %51 / 53100.0 %7 / 7
DriverDouble.cpp +
100.0%
+
100.0 %1 / 1100.0 %3 / 3
DriverFloat.cpp +
100.0%
+
100.0 %2 / 2100.0 %4 / 4
Manual.cpp +
100.0%
+
100.0 %24 / 24100.0 %7 / 7
GenJson.cpp +
100.0%
+
100.0 %91 / 91100.0 %7 / 7
pesmd.cpp +
100.0%
+
100.0 %127 / 127100.0 %7 / 7
SimpleMD.cpp +
100.0%
+
100.0 %231 / 231100.0 %20 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/index.html b/coverage/cltools/index.html new file mode 100644 index 000000000000..31559d4d153f --- /dev/null +++ b/coverage/cltools/index.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - cltools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltoolsHitTotalCoverage
Test:plumed test coverageLines:1381177877.7 %
Date:2024-02-22 21:58:45Functions:10912289.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Benchmark.cpp +
20.8%20.8%
+
20.8 %15 / 7260.0 %6 / 10
Completion.cpp +
27.8%27.8%
+
27.8 %10 / 3685.7 %6 / 7
Driver.cpp +
89.6%89.6%
+
89.6 %552 / 61675.0 %9 / 12
DriverDouble.cpp +
100.0%
+
100.0 %1 / 1100.0 %3 / 3
DriverFloat.cpp +
100.0%
+
100.0 %2 / 2100.0 %4 / 4
GenExample.cpp +
7.7%7.7%
+
7.7 %17 / 22066.7 %6 / 9
GenJson.cpp +
100.0%
+
100.0 %91 / 91100.0 %7 / 7
GenTemplate.cpp +
56.5%56.5%
+
56.5 %13 / 2385.7 %6 / 7
Info.cpp +
83.0%83.0%
+
83.0 %39 / 47100.0 %7 / 7
Manual.cpp +
100.0%
+
100.0 %24 / 24100.0 %7 / 7
PdbRenumber.cpp +
96.2%96.2%
+
96.2 %51 / 53100.0 %7 / 7
SimpleMD.cpp +
100.0%
+
100.0 %231 / 231100.0 %20 / 20
SumHills.cpp +
90.7%90.7%
+
90.7 %196 / 216100.0 %8 / 8
kT.cpp +
63.2%63.2%
+
63.2 %12 / 1985.7 %6 / 7
pesmd.cpp +
100.0%
+
100.0 %127 / 127100.0 %7 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/kT.cpp.func-sort-c.html b/coverage/cltools/kT.cpp.func-sort-c.html new file mode 100644 index 000000000000..4d4fa9b63fb6 --- /dev/null +++ b/coverage/cltools/kT.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/kT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - kT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121963.2 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools2kt4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools2ktC2ERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools2kt11descriptionB5cxx11Ev4
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeD2Ev4187
_ZN4PLMD7cltools2kt16registerKeywordsERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/kT.cpp.func.html b/coverage/cltools/kT.cpp.func.html new file mode 100644 index 000000000000..38e3683f5ab6 --- /dev/null +++ b/coverage/cltools/kT.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/kT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - kT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121963.2 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMe6createERKNS_13CLToolOptionsE4
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_112ktRegisterMeD2Ev4187
_ZN4PLMD7cltools2kt16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools2kt4mainEP8_IO_FILES3_RNS_12CommunicatorE0
_ZN4PLMD7cltools2ktC2ERKNS_13CLToolOptionsE4
_ZNK4PLMD7cltools2kt11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/kT.cpp.gcov.html b/coverage/cltools/kT.cpp.gcov.html new file mode 100644 index 000000000000..9d60797f2bd1 --- /dev/null +++ b/coverage/cltools/kT.cpp.gcov.html @@ -0,0 +1,164 @@ + + + + + + + + LCOV - plumed test coverage - cltools/kT.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - kT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121963.2 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "config/Config.h"
+      26             : #include "tools/Units.h"
+      27             : #include "core/ActionRegister.h"
+      28             : #include <cstdio>
+      29             : #include <string>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace cltools {
+      33             : 
+      34             : //+PLUMEDOC TOOLS kt
+      35             : /*
+      36             : Print out the value of \f$k_BT\f$ at a particular temperature
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : The following command will tell you the value of \f$k_BT\f$ when T is equal
+      41             : to 300 K in eV
+      42             : 
+      43             : \verbatim
+      44             : plumed kt --temp 300 --units eV
+      45             : \endverbatim
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : class kt:
+      51             :   public CLTool
+      52             : {
+      53             : public:
+      54             :   static void registerKeywords( Keywords& keys );
+      55             :   explicit kt(const CLToolOptions& co );
+      56             :   int main(FILE* in, FILE*out,Communicator& pc) override;
+      57           4 :   std::string description()const override {
+      58           4 :     return "print out the value of kT at a particular temperature";
+      59             :   }
+      60             : };
+      61             : 
+      62       12565 : PLUMED_REGISTER_CLTOOL(kt,"kt")
+      63             : 
+      64        4187 : void kt::registerKeywords( Keywords& keys ) {
+      65        4187 :   CLTool::registerKeywords( keys );
+      66        8374 :   keys.add("compulsory","--temp","print the manual for this particular action");
+      67        8374 :   keys.add("compulsory","--units","kj/mol","the units of energy can be kj/mol, kcal/mol, j/mol, eV or the conversion factor from kj/mol");
+      68        4187 : }
+      69             : 
+      70           4 : kt::kt(const CLToolOptions& co ):
+      71           4 :   CLTool(co)
+      72             : {
+      73           4 :   inputdata=commandline;
+      74           4 : }
+      75             : 
+      76           0 : int kt::main(FILE* in, FILE*out,Communicator& pc) {
+      77             : 
+      78           0 :   std::string unitname; parse("--units",unitname);
+      79           0 :   Units units; units.setEnergy( unitname );
+      80           0 :   double temp; parse("--temp",temp);
+      81           0 :   double kk=(kBoltzmann*temp)/units.getEnergy();
+      82             :   std::fprintf(out,"When the temperature is %f kelvin kT is equal to %f %s\n",temp,kk,unitname.c_str());
+      83           0 :   return 0;
+      84           0 : }
+      85             : 
+      86             : } // End of namespace
+      87             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/pesmd.cpp.func-sort-c.html b/coverage/cltools/pesmd.cpp.func-sort-c.html new file mode 100644 index 000000000000..dc7b5bb461a0 --- /dev/null +++ b/coverage/cltools/pesmd.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/pesmd.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - pesmd.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:127127100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools5PesMD10read_inputERdS2_S2_RiRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIdSaIdEES3_RbSE_S3_3
_ZN4PLMD7cltools5PesMD4mainEP8_IO_FILES3_RNS_12CommunicatorE3
_ZNK4PLMD7cltools5PesMD11descriptionB5cxx11Ev4
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeD2Ev4187
_ZN4PLMD7cltools5PesMD16registerKeywordsERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/pesmd.cpp.func.html b/coverage/cltools/pesmd.cpp.func.html new file mode 100644 index 000000000000..8b84bb49cb42 --- /dev/null +++ b/coverage/cltools/pesmd.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - cltools/pesmd.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - pesmd.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:127127100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMe6createERKNS_13CLToolOptionsE7
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeC2Ev4187
_ZN4PLMD7cltools12_GLOBAL__N_115PesMDRegisterMeD2Ev4187
_ZN4PLMD7cltools5PesMD10read_inputERdS2_S2_RiRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIdSaIdEES3_RbSE_S3_3
_ZN4PLMD7cltools5PesMD16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7cltools5PesMD4mainEP8_IO_FILES3_RNS_12CommunicatorE3
_ZNK4PLMD7cltools5PesMD11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/cltools/pesmd.cpp.gcov.html b/coverage/cltools/pesmd.cpp.gcov.html new file mode 100644 index 000000000000..9fc884284dd8 --- /dev/null +++ b/coverage/cltools/pesmd.cpp.gcov.html @@ -0,0 +1,389 @@ + + + + + + + + LCOV - plumed test coverage - cltools/pesmd.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - cltools - pesmd.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:127127100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Vector.h"
+      26             : #include "tools/Random.h"
+      27             : #include "tools/Communicator.h"
+      28             : #include <string>
+      29             : #include <cstdio>
+      30             : #include <vector>
+      31             : #include <memory>
+      32             : 
+      33             : //+PLUMEDOC TOOLS pesmd
+      34             : /*
+      35             : Pesmd allows one to do (biased) Langevin dynamics on a two-dimensional potential energy surface.
+      36             : 
+      37             : The energy landscape that you are moving about on is specified using a plumed input file.
+      38             : The directives that are available for this command line tool are as follows:
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : You run a Langevin simulation using pesmd with the following command:
+      43             : \verbatim
+      44             : plumed pesmd < input
+      45             : \endverbatim
+      46             : 
+      47             : The following is an example of an input file for a pesmd simulation. This file
+      48             : instructs pesmd to do 50 steps of Langevin dynamics on a 2D potential energy surface
+      49             : at a temperature of 0.722
+      50             : \verbatim
+      51             : temperature 0.722
+      52             : tstep 0.005
+      53             : friction 1
+      54             : dimension 2
+      55             : nstep 50
+      56             : ipos 0.0 0.0
+      57             : \endverbatim
+      58             : 
+      59             : If you run the following a description of all the directives that can be used in the
+      60             : input file will be output.
+      61             : \verbatim
+      62             : plumed pesmd --help
+      63             : \endverbatim
+      64             : 
+      65             : The energy landscape to explore is given within the plumed input file.  For example the following
+      66             : example input uses \ref MATHEVAL to define a two dimensional potential.
+      67             : 
+      68             : \verbatim
+      69             : d1: DISTANCE ATOMS=1,2 COMPONENTS
+      70             : ff: MATHEVAL ARG=d1.x,d1,y PERIODIC=NO FUNC=()
+      71             : bb: BIASVALUE ARG=ff
+      72             : \endverbatim
+      73             : 
+      74             : Atom 1 is placed at the origin.  The x and y components on our surface are the
+      75             : positions of the particle on our two dimensional energy landscape.  By calculating the
+      76             : vector connecting atom 1 (the origin) to atom 2 (the position of our particle) we are thus
+      77             : getting the position of the atom on the energy landscape.  This is then inserted into the function
+      78             : that is calculated on the second line.  The value of this function is then used as a bias.
+      79             : 
+      80             : We can also specify a potential on a grid and look at the dynamics on this function using pesmd.
+      81             : A plumed input for an example such as this one might look something like this:
+      82             : 
+      83             : \verbatim
+      84             : d1: DISTANCE ATOMS=1,2 COMPONENTS
+      85             : bb: EXTERNAL ARG=d1.x,d1,y FILE=fes.dat
+      86             : \endverbatim
+      87             : 
+      88             : In this way we can use pesmd to do a dynamics on a free energy surface calculated using metadynamics
+      89             : and sum_hills.  On a final note once we have defined our potential we can use all the biasing functions
+      90             : within plumed in addition in order to do a biased dynamics on the potential energy landscape of interest.
+      91             : 
+      92             : */
+      93             : //+ENDPLUMEDOC
+      94             : 
+      95             : namespace PLMD {
+      96             : namespace cltools {
+      97             : 
+      98             : class PesMD  : public PLMD::CLTool {
+      99           4 :   std::string description() const override {
+     100           4 :     return "Langevin dynamics on PLUMED energy landscape";
+     101             :   }
+     102             : public:
+     103        4187 :   static void registerKeywords( Keywords& keys ) {
+     104        8374 :     keys.add("compulsory","nstep","The number of steps of dynamics you want to run");
+     105        8374 :     keys.add("compulsory","temperature","NVE","the temperature at which you wish to run the simulation in LJ units");
+     106        8374 :     keys.add("compulsory","friction","off","The friction (in LJ units) for the Langevin thermostat that is used to keep the temperature constant");
+     107        8374 :     keys.add("compulsory","tstep","0.005","the integration timestep in LJ units");
+     108        8374 :     keys.add("compulsory","dimension","the dimension of your energy landscape");
+     109        8374 :     keys.add("compulsory","plumed","plumed.dat","the name of the plumed input file containing the potential");
+     110        8374 :     keys.add("compulsory","ipos","0.0","the initial position of the system");
+     111        8374 :     keys.add("compulsory","idum","0","The random number seed");
+     112        8374 :     keys.addFlag("periodic",false,"are your input coordinates periodic");
+     113        8374 :     keys.add("optional","min","minimum value the coordinates can take for a periodic domain");
+     114        8374 :     keys.add("optional","max","maximum value the coordinates can take for a periodic domain");
+     115        4187 :   }
+     116             : 
+     117           7 :   explicit PesMD( const CLToolOptions& co ) :
+     118           7 :     CLTool(co)
+     119             :   {
+     120           7 :     inputdata=ifile;
+     121             :   }
+     122             : 
+     123             : private:
+     124             : 
+     125           3 :   void read_input(double& temperature,
+     126             :                   double& tstep,
+     127             :                   double& friction,
+     128             :                   int& dim,
+     129             :                   std::string& plumedin,
+     130             :                   std::vector<double>& ipos,
+     131             :                   int&    nstep,
+     132             :                   bool&   lperiod,
+     133             :                   std::vector<double>& periods,
+     134             :                   int&    idum)
+     135             :   {
+     136             :     // Read everything from input file
+     137           6 :     std::string tempstr; parse("temperature",tempstr);
+     138           3 :     if( tempstr!="NVE" ) Tools::convert(tempstr,temperature);
+     139           6 :     parse("tstep",tstep);
+     140           6 :     std::string frictionstr; parse("friction",frictionstr);
+     141           3 :     if( tempstr!="NVE" ) {
+     142           3 :       if(frictionstr=="off") error("pecify friction for thermostat");
+     143           3 :       Tools::convert(frictionstr,friction);
+     144             :     }
+     145           6 :     parse("plumed",plumedin); parse("dimension",dim);
+     146           6 :     parse("nstep",nstep); parse("idum",idum);
+     147           3 :     ipos.resize( dim ); parseVector("ipos",ipos);
+     148             : 
+     149           3 :     parseFlag("periodic",lperiod);
+     150           3 :     if( lperiod ) {
+     151           2 :       if( dim>3 ) error("can only do three dimensional periodic functions");
+     152           2 :       std::vector<double> min( dim ); parseVector("min",min);
+     153           2 :       std::vector<double> max( dim ); parseVector("max",max);
+     154           2 :       periods.resize( dim );
+     155           7 :       for(int i=0; i<dim; ++i) {
+     156           5 :         if( max[i]<min[i] ) error("invalid periods specified max is less than min");
+     157           5 :         periods[i]=max[i]-min[i];
+     158             :       }
+     159             :     }
+     160           3 :   }
+     161             : 
+     162             : 
+     163             : public:
+     164             : 
+     165           3 :   int main( FILE* in, FILE* out, PLMD::Communicator& pc) override {
+     166             :     std::string plumedin; std::vector<double> ipos;
+     167             :     double temp, tstep, friction; bool lperiod;
+     168             :     int dim, nsteps, seed; std::vector<double> periods;
+     169             :     int plumedWantsToStop;
+     170           3 :     Random random;
+     171             : 
+     172           3 :     read_input( temp, tstep, friction, dim, plumedin, ipos, nsteps, lperiod, periods, seed );
+     173             :     // Setup random number generator
+     174           3 :     random.setSeed(seed);
+     175             : 
+     176             :     // Setup box if we have periodic domain
+     177           3 :     std::vector<double> box(9, 0.0);
+     178           3 :     if( lperiod && dim==1 ) { box[0]=box[4]=box[8]=periods[0]; }
+     179           3 :     else if( lperiod && dim==2 ) { box[0]=periods[0]; box[4]=box[8]=periods[1]; }
+     180           2 :     else if( lperiod && dim==3 ) { box[0]=periods[0]; box[4]=periods[1]; box[8]=periods[2]; }
+     181           1 :     else if( lperiod ) error("invalid dimension for periodic potential must be 1, 2 or 3");
+     182             : 
+     183             :     // Create plumed object and initialize
+     184             :     auto plumed=Tools::make_unique<PLMD::PlumedMain>();
+     185           3 :     int s=sizeof(double);
+     186           3 :     plumed->cmd("setRealPrecision",&s);
+     187           3 :     if(Communicator::initialized()) plumed->cmd("setMPIComm",&pc.Get_comm());
+     188           3 :     int natoms=( std::floor(dim/3) +  2 );
+     189           3 :     plumed->cmd("setNatoms",&natoms);
+     190           3 :     plumed->cmd("setNoVirial");
+     191           3 :     plumed->cmd("setMDEngine","pesmd");
+     192           3 :     plumed->cmd("setTimestep",&tstep);
+     193           3 :     plumed->cmd("setPlumedDat",plumedin.c_str());
+     194           3 :     plumed->cmd("init");
+     195             : 
+     196             :     // Now create some fake atoms
+     197           3 :     int nat = std::floor( dim/3 ) + 1;
+     198           3 :     std::vector<double> masses( 1+nat, 1 );
+     199           3 :     std::vector<Vector> velocities( nat ), positions( nat+1 ), forces( nat+1 );
+     200             :     // Will set these properly eventually
+     201           3 :     int k=0; positions[0].zero(); // Atom zero is fixed at origin
+     202          19 :     for(int i=0; i<nat; ++i) for(unsigned j=0; j<3; ++j) {
+     203          12 :         if( k<dim ) { positions[1+i][j]=ipos[k]; } else { positions[1+i][j]=0;}
+     204          12 :         k++;
+     205             :       }
+     206             :     // And initialize the velocities
+     207          19 :     for(int i=0; i<nat; ++i) for(int j=0; j<3; ++j) velocities[i][j]=random.Gaussian() * std::sqrt( temp );
+     208             :     // And calculate the kinetic energy
+     209             :     double tke=0;
+     210           7 :     for(int i=0; i<nat; ++i) {
+     211          10 :       for(int j=0; j<3; ++j) {
+     212           9 :         if( 3*i+j>dim-1 ) break;
+     213             :         tke += 0.5*velocities[i][j]*velocities[i][j];
+     214             :       }
+     215             :     }
+     216             : 
+     217             :     // Now call plumed to get initial forces
+     218           3 :     int istep=0; double zero=0;
+     219           3 :     plumed->cmd("setStep",&istep);
+     220           3 :     plumed->cmd("setMasses",&masses[0]);
+     221           3 :     Tools::set_to_zero(forces);
+     222           3 :     plumed->cmd("setForces",&forces[0][0]);
+     223           3 :     plumed->cmd("setEnergy",&zero);
+     224           3 :     if( lperiod ) plumed->cmd("setBox",&box[0]);
+     225           3 :     plumed->cmd("setPositions",&positions[0][0]);
+     226           3 :     plumed->cmd("calc");
+     227             : 
+     228             :     double therm_eng=0;
+     229           3 :     FILE* fp=fopen("stats.out","w+");
+     230             : 
+     231         153 :     for(int istep=0; istep<nsteps; ++istep) {
+     232             : 
+     233         150 :       if( istep%20==0 && pc.Get_rank()==0 ) std::printf("Doing step %i\n",istep);
+     234             : 
+     235             :       // Langevin thermostat
+     236         150 :       double lscale=std::exp(-0.5*tstep/friction);
+     237         150 :       double lrand=std::sqrt((1.-lscale*lscale)*temp);
+     238         350 :       for(int j=0; j<nat; ++j) {
+     239         500 :         for(int k=0; k<3; ++k) {
+     240         450 :           if( 3*j+k>dim-1 ) break;
+     241         300 :           therm_eng=therm_eng+0.5*velocities[j][k]*velocities[j][k];
+     242         300 :           velocities[j][k]=lscale*velocities[j][k]+lrand*random.Gaussian();
+     243         300 :           therm_eng=therm_eng-0.5*velocities[j][k]*velocities[0][k];
+     244             :         }
+     245             :       }
+     246             : 
+     247             :       // First step of velocity verlet
+     248         350 :       for(int j=0; j<nat; ++j) {
+     249         500 :         for(int k=0; k<3; ++k) {
+     250         450 :           if( 3*j+k>dim-1 ) break;
+     251         300 :           velocities[j][k] = velocities[j][k] + 0.5*tstep*forces[1+j][k];
+     252         300 :           positions[1+j][k] = positions[1+j][k] + tstep*velocities[j][k];
+     253             :         }
+     254             :       }
+     255             : 
+     256         150 :       int istepplusone=istep+1;
+     257         150 :       plumedWantsToStop=0;
+     258         150 :       plumed->cmd("setStep",&istepplusone);
+     259         150 :       plumed->cmd("setMasses",&masses[0]);
+     260         150 :       Tools::set_to_zero(forces);
+     261         150 :       plumed->cmd("setForces",&forces[0][0]);
+     262         150 :       double fenergy=0.0;
+     263         150 :       plumed->cmd("setEnergy",&fenergy);
+     264         150 :       plumed->cmd("setPositions",&positions[0][0]);
+     265         150 :       plumed->cmd("setStopFlag",&plumedWantsToStop);
+     266         150 :       plumed->cmd("calc");
+     267             :       // if(istep%2000==0) plumed->cmd("writeCheckPointFile");
+     268         150 :       if(plumedWantsToStop) nsteps=istep;
+     269             : 
+     270             :       // Second step of velocity verlet
+     271         350 :       for(int j=0; j<nat; ++j) {
+     272         500 :         for(int k=0; k<3; ++k) {
+     273         450 :           if( 3*j+k>dim-1 ) break;
+     274         300 :           velocities[j][k] = velocities[j][k] + 0.5*tstep*forces[1+j][k];
+     275             :         }
+     276             :       }
+     277             : 
+     278             :       // Langevin thermostat
+     279         150 :       lscale=std::exp(-0.5*tstep/friction);
+     280         150 :       lrand=std::sqrt((1.-lscale*lscale)*temp);
+     281         350 :       for(int j=0; j<nat; ++j) {
+     282         500 :         for(int k=0; k<3; ++k) {
+     283         450 :           if( 3*j+k>dim-1) break;
+     284         300 :           therm_eng=therm_eng+0.5*velocities[j][k]*velocities[j][k];
+     285         300 :           velocities[j][k]=lscale*velocities[j][k]+lrand*random.Gaussian();
+     286         300 :           therm_eng=therm_eng-0.5*velocities[j][k]*velocities[j][k];
+     287             :         }
+     288             :       }
+     289             :       // Calculate total kinetic energy
+     290             :       tke=0;
+     291         350 :       for(int i=0; i<nat; ++i) {
+     292         500 :         for(int j=0; j<3; ++j) {
+     293         450 :           if( 3*i+j>dim-1 ) break;
+     294         300 :           tke += 0.5*velocities[i][j]*velocities[i][j];
+     295             :         }
+     296             :       }
+     297             : 
+     298             :       // Print everything
+     299             :       // conserved = potential+1.5*ttt+therm_eng;
+     300         150 :       if( pc.Get_rank()==0 ) std::fprintf(fp,"%i %f %f %f \n", istep, istep*tstep, tke, therm_eng );
+     301             :     }
+     302             : 
+     303           3 :     fclose(fp);
+     304             : 
+     305           3 :     return 0;
+     306           3 :   }
+     307             : };
+     308             : 
+     309       12568 : PLUMED_REGISTER_CLTOOL(PesMD,"pesmd")
+     310             : 
+     311             : }
+     312             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Angle.cpp.func-sort-c.html b/coverage/colvar/Angle.cpp.func-sort-c.html new file mode 100644 index 000000000000..ce4fb9d34d74 --- /dev/null +++ b/coverage/colvar/Angle.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353697.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5AngleC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5AngleC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar5Angle16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD6colvar5Angle9calculateEv304
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Angle.cpp.func.html b/coverage/colvar/Angle.cpp.func.html new file mode 100644 index 000000000000..c7e7ede43a0a --- /dev/null +++ b/coverage/colvar/Angle.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353697.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5Angle16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD6colvar5Angle9calculateEv304
_ZN4PLMD6colvar5AngleC1ERKNS_13ActionOptionsE18
_ZN4PLMD6colvar5AngleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Angle.cpp.gcov.html b/coverage/colvar/Angle.cpp.gcov.html new file mode 100644 index 000000000000..a7efb6db9458 --- /dev/null +++ b/coverage/colvar/Angle.cpp.gcov.html @@ -0,0 +1,225 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Angle.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353697.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Angle.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace colvar {
+      28             : 
+      29             : //+PLUMEDOC COLVAR ANGLE
+      30             : /*
+      31             : Calculate an angle.
+      32             : 
+      33             : This command can be used to compute the angle between three atoms. Alternatively
+      34             : if four atoms appear in the atom
+      35             : specification it calculates the angle between
+      36             : two vectors identified by two pairs of atoms.
+      37             : 
+      38             : If _three_ atoms are given, the angle is defined as:
+      39             : \f[
+      40             : \theta=\arccos\left(\frac{ {\bf r}_{21}\cdot {\bf r}_{23}}{
+      41             : |{\bf r}_{21}| |{\bf r}_{23}|}\right)
+      42             : \f]
+      43             : Here \f$ {\bf r}_{ij}\f$ is the distance vector among the
+      44             : \f$i\f$th and the \f$j\f$th listed atom.
+      45             : 
+      46             : If _four_ atoms are given, the angle is defined as:
+      47             : \f[
+      48             : \theta=\arccos\left(\frac{ {\bf r}_{21}\cdot {\bf r}_{34}}{
+      49             : |{\bf r}_{21}| |{\bf r}_{34}|}\right)
+      50             : \f]
+      51             : 
+      52             : Notice that angles defined in this way are non-periodic variables and
+      53             : their value is limited by definition between 0 and \f$\pi\f$.
+      54             : 
+      55             : The vectors \f$ {\bf r}_{ij}\f$ are by default evaluated taking
+      56             : periodic boundary conditions into account.
+      57             : This behavior can be changed with the NOPBC flag.
+      58             : 
+      59             : \par Examples
+      60             : 
+      61             : This command tells plumed to calculate the angle between the vector connecting atom 1 to atom 2 and
+      62             : the vector connecting atom 2 to atom 3 and to print it on file COLVAR1. At the same time,
+      63             : the angle between vector connecting atom 1 to atom 2 and the vector connecting atom 3 to atom 4 is printed
+      64             : on file COLVAR2.
+      65             : \plumedfile
+      66             : 
+      67             : a: ANGLE ATOMS=1,2,3
+      68             : # equivalently one could state:
+      69             : # a: ANGLE ATOMS=1,2,2,3
+      70             : 
+      71             : b: ANGLE ATOMS=1,2,3,4
+      72             : 
+      73             : PRINT ARG=a FILE=COLVAR1
+      74             : PRINT ARG=b FILE=COLVAR2
+      75             : \endplumedfile
+      76             : 
+      77             : 
+      78             : */
+      79             : //+ENDPLUMEDOC
+      80             : 
+      81             : class Angle : public Colvar {
+      82             :   bool pbc;
+      83             : 
+      84             : public:
+      85             :   explicit Angle(const ActionOptions&);
+      86             : // active methods:
+      87             :   void calculate() override;
+      88             :   static void registerKeywords( Keywords& keys );
+      89             : };
+      90             : 
+      91             : PLUMED_REGISTER_ACTION(Angle,"ANGLE")
+      92             : 
+      93          20 : void Angle::registerKeywords( Keywords& keys ) {
+      94          20 :   Colvar::registerKeywords(keys);
+      95          40 :   keys.add("atoms","ATOMS","the list of atoms involved in this collective variable (either 3 or 4 atoms)");
+      96          20 : }
+      97             : 
+      98          18 : Angle::Angle(const ActionOptions&ao):
+      99             :   PLUMED_COLVAR_INIT(ao),
+     100          18 :   pbc(true)
+     101             : {
+     102             :   std::vector<AtomNumber> atoms;
+     103          18 :   parseAtomList("ATOMS",atoms);
+     104          18 :   bool nopbc=!pbc;
+     105          18 :   parseFlag("NOPBC",nopbc);
+     106          18 :   pbc=!nopbc;
+     107             : 
+     108          18 :   if(atoms.size()==3) {
+     109          12 :     log.printf("  between atoms %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial());
+     110          12 :     atoms.resize(4);
+     111          12 :     atoms[3]=atoms[2];
+     112          12 :     atoms[2]=atoms[1];
+     113           6 :   } else if(atoms.size()==4) {
+     114           5 :     log.printf("  between lines %d-%d and %d-%d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial());
+     115           1 :   } else error("Number of specified atoms should be either 3 or 4");
+     116             : 
+     117          17 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     118           0 :   else    log.printf("  without periodic boundary conditions\n");
+     119             : 
+     120          35 :   addValueWithDerivatives(); setNotPeriodic();
+     121          17 :   requestAtoms(atoms);
+     122          17 :   checkRead();
+     123          19 : }
+     124             : 
+     125             : // calculator
+     126         304 : void Angle::calculate() {
+     127             : 
+     128         304 :   if(pbc) makeWhole();
+     129             : 
+     130         304 :   Vector dij,dik;
+     131         304 :   dij=delta(getPosition(2),getPosition(3));
+     132         304 :   dik=delta(getPosition(1),getPosition(0));
+     133         304 :   Vector ddij,ddik;
+     134             :   PLMD::Angle a;
+     135         304 :   double angle=a.compute(dij,dik,ddij,ddik);
+     136         304 :   setAtomsDerivatives(0,ddik);
+     137         304 :   setAtomsDerivatives(1,-ddik);
+     138         608 :   setAtomsDerivatives(2,-ddij);
+     139             :   setAtomsDerivatives(3,ddij);
+     140         304 :   setValue           (angle);
+     141             :   setBoxDerivativesNoPbc();
+     142         304 : }
+     143             : 
+     144             : }
+     145             : }
+     146             : 
+     147             : 
+     148             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Cell.cpp.func-sort-c.html b/coverage/colvar/Cell.cpp.func-sort-c.html new file mode 100644 index 000000000000..b4948584c260 --- /dev/null +++ b/coverage/colvar/Cell.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Cell.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Cell.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4CellC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar4CellC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar4Cell16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD6colvar4Cell9calculateEv150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Cell.cpp.func.html b/coverage/colvar/Cell.cpp.func.html new file mode 100644 index 000000000000..48425ff9f964 --- /dev/null +++ b/coverage/colvar/Cell.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Cell.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Cell.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4Cell16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD6colvar4Cell9calculateEv150
_ZN4PLMD6colvar4CellC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar4CellC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Cell.cpp.gcov.html b/coverage/colvar/Cell.cpp.gcov.html new file mode 100644 index 000000000000..db8fbe075f5a --- /dev/null +++ b/coverage/colvar/Cell.cpp.gcov.html @@ -0,0 +1,186 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Cell.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Cell.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace colvar {
+      27             : 
+      28             : //+PLUMEDOC COLVAR CELL
+      29             : /*
+      30             : Calculate the components of the simulation cell
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : The following input tells plumed to print the squared modulo of each of the three lattice vectors
+      35             : \plumedfile
+      36             : cell: CELL
+      37             : aaa:    COMBINE ARG=cell.ax,cell.ay,cell.az POWERS=2,2,2 PERIODIC=NO
+      38             : bbb:    COMBINE ARG=cell.bx,cell.by,cell.bz POWERS=2,2,2 PERIODIC=NO
+      39             : ccc:    COMBINE ARG=cell.cx,cell.cy,cell.cz POWERS=2,2,2 PERIODIC=NO
+      40             : PRINT ARG=aaa,bbb,ccc
+      41             : \endplumedfile
+      42             : 
+      43             : */
+      44             : //+ENDPLUMEDOC
+      45             : 
+      46             : 
+      47             : class Cell : public Colvar {
+      48             :   Value* components[3][3];
+      49             : 
+      50             : public:
+      51             :   explicit Cell(const ActionOptions&);
+      52             : // active methods:
+      53             :   void calculate() override;
+      54             : /// Register all the keywords for this action
+      55             :   static void registerKeywords( Keywords& keys );
+      56             : };
+      57             : 
+      58             : PLUMED_REGISTER_ACTION(Cell,"CELL")
+      59             : 
+      60           9 : Cell::Cell(const ActionOptions&ao):
+      61           9 :   PLUMED_COLVAR_INIT(ao)
+      62             : {
+      63             :   std::vector<AtomNumber> atoms;
+      64           9 :   checkRead();
+      65             : 
+      66          27 :   addComponentWithDerivatives("ax"); componentIsNotPeriodic("ax"); components[0][0]=getPntrToComponent("ax");
+      67          27 :   addComponentWithDerivatives("ay"); componentIsNotPeriodic("ay"); components[0][1]=getPntrToComponent("ay");
+      68          27 :   addComponentWithDerivatives("az"); componentIsNotPeriodic("az"); components[0][2]=getPntrToComponent("az");
+      69          27 :   addComponentWithDerivatives("bx"); componentIsNotPeriodic("bx"); components[1][0]=getPntrToComponent("bx");
+      70          27 :   addComponentWithDerivatives("by"); componentIsNotPeriodic("by"); components[1][1]=getPntrToComponent("by");
+      71          27 :   addComponentWithDerivatives("bz"); componentIsNotPeriodic("bz"); components[1][2]=getPntrToComponent("bz");
+      72          27 :   addComponentWithDerivatives("cx"); componentIsNotPeriodic("cx"); components[2][0]=getPntrToComponent("cx");
+      73          27 :   addComponentWithDerivatives("cy"); componentIsNotPeriodic("cy"); components[2][1]=getPntrToComponent("cy");
+      74          27 :   addComponentWithDerivatives("cz"); componentIsNotPeriodic("cz"); components[2][2]=getPntrToComponent("cz");
+      75           9 :   requestAtoms(atoms);
+      76           9 : }
+      77             : 
+      78          11 : void Cell::registerKeywords( Keywords& keys ) {
+      79          11 :   Action::registerKeywords( keys );
+      80          11 :   ActionWithValue::registerKeywords( keys );
+      81          11 :   ActionAtomistic::registerKeywords( keys );
+      82          11 :   componentsAreNotOptional(keys);
+      83          22 :   keys.addOutputComponent("ax","default","the ax component of the cell matrix");
+      84          22 :   keys.addOutputComponent("ay","default","the ay component of the cell matrix");
+      85          22 :   keys.addOutputComponent("az","default","the az component of the cell matrix");
+      86          22 :   keys.addOutputComponent("bx","default","the bx component of the cell matrix");
+      87          22 :   keys.addOutputComponent("by","default","the by component of the cell matrix");
+      88          22 :   keys.addOutputComponent("bz","default","the bz component of the cell matrix");
+      89          22 :   keys.addOutputComponent("cx","default","the cx component of the cell matrix");
+      90          22 :   keys.addOutputComponent("cy","default","the cy component of the cell matrix");
+      91          22 :   keys.addOutputComponent("cz","default","the cz component of the cell matrix");
+      92          11 : }
+      93             : 
+      94             : 
+      95             : // calculator
+      96         150 : void Cell::calculate() {
+      97             : 
+      98        1950 :   for(int i=0; i<3; i++) for(int j=0; j<3; j++) components[i][j]->set(getBox()[i][j]);
+      99        1950 :   for(int l=0; l<3; l++) for(int m=0; m<3; m++) {
+     100        5400 :       Tensor der; for(int i=0; i<3; i++) der[i][m]=getBox()[l][i];
+     101        1350 :       setBoxDerivatives(components[l][m],-der);
+     102             :     }
+     103         150 : }
+     104             : 
+     105             : }
+     106             : }
+     107             : 
+     108             : 
+     109             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Constant.cpp.func-sort-c.html b/coverage/colvar/Constant.cpp.func-sort-c.html new file mode 100644 index 000000000000..d86719239ca8 --- /dev/null +++ b/coverage/colvar/Constant.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Constant.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Constant.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424495.5 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8ConstantC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8ConstantC1ERKNS_13ActionOptionsE39
_ZN4PLMD6colvar8Constant16registerKeywordsERNS_8KeywordsE41
_ZN4PLMD6colvar8Constant9calculateEv3401
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Constant.cpp.func.html b/coverage/colvar/Constant.cpp.func.html new file mode 100644 index 000000000000..f73eb1278c46 --- /dev/null +++ b/coverage/colvar/Constant.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Constant.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Constant.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424495.5 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8Constant16registerKeywordsERNS_8KeywordsE41
_ZN4PLMD6colvar8Constant9calculateEv3401
_ZN4PLMD6colvar8ConstantC1ERKNS_13ActionOptionsE39
_ZN4PLMD6colvar8ConstantC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Constant.cpp.gcov.html b/coverage/colvar/Constant.cpp.gcov.html new file mode 100644 index 000000000000..a2d005f6b6e3 --- /dev/null +++ b/coverage/colvar/Constant.cpp.gcov.html @@ -0,0 +1,209 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Constant.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Constant.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424495.5 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace colvar {
+      28             : 
+      29             : //+PLUMEDOC COLVAR CONSTANT
+      30             : /*
+      31             : Return one or more constant quantities with or without derivatives.
+      32             : 
+      33             : Useful in combination with functions that
+      34             : takes in input constants or parameters.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The following input instructs plumed to compute the distance
+      39             : between atoms 1 and 2. If this distance is between 1.0 and 2.0, it is
+      40             : printed. If it is lower than 1.0 (larger than 2.0), 1.0 (2.0) is printed
+      41             : 
+      42             : \plumedfile
+      43             : cn: CONSTANT VALUES=1.0,2.0
+      44             : dis: DISTANCE ATOMS=1,2
+      45             : sss: SORT ARG=cn.v-0,dis,cn.v-1
+      46             : PRINT ARG=sss.2
+      47             : \endplumedfile
+      48             : 
+      49             : In case you want to pass a single value you can use VALUE:
+      50             : \plumedfile
+      51             : cn: CONSTANT VALUE=1.0
+      52             : dis: DISTANCE ATOMS=1,2
+      53             : sss: SORT ARG=cn,dis
+      54             : PRINT ARG=sss.1
+      55             : \endplumedfile
+      56             : 
+      57             : */
+      58             : //+ENDPLUMEDOC
+      59             : 
+      60             : class Constant : public Colvar {
+      61             :   std::vector<double> values;
+      62             : public:
+      63             :   explicit Constant(const ActionOptions&);
+      64             :   void calculate() override;
+      65             :   static void registerKeywords( Keywords& keys );
+      66             : };
+      67             : 
+      68             : PLUMED_REGISTER_ACTION(Constant,"CONSTANT")
+      69             : 
+      70          39 : Constant::Constant(const ActionOptions&ao):
+      71          39 :   PLUMED_COLVAR_INIT(ao)
+      72             : {
+      73          39 :   bool noderiv=false;
+      74          39 :   parseFlag("NODERIV",noderiv);
+      75          78 :   parseVector("VALUES",values);
+      76             :   std::vector<double> value;
+      77          78 :   parseVector("VALUE",value);
+      78          39 :   if(values.size()==0&&value.size()==0) error("One should use either VALUE or VALUES");
+      79          39 :   if(values.size()!=0&&value.size()!=0) error("One should use either VALUE or VALUES");
+      80          39 :   if(value.size()>1) error("VALUE cannot take more than one number");
+      81          39 :   if(values.size()==0) {
+      82          11 :     values.resize(1);
+      83          11 :     values[0]=value[0];
+      84             :   }
+      85          39 :   checkRead();
+      86          39 :   if(values.size()==1) {
+      87          76 :     if(!noderiv) addValueWithDerivatives();
+      88           0 :     else addValue();
+      89          38 :     setNotPeriodic();
+      90          38 :     setValue(values[0]);
+      91           1 :   } else if(values.size()>1) {
+      92           3 :     for(unsigned i=0; i<values.size(); i++) {
+      93           2 :       std::string num; Tools::convert(i,num);
+      94           4 :       if(!noderiv) addComponentWithDerivatives("v-"+num);
+      95           0 :       else addComponent("v-"+num);
+      96           2 :       componentIsNotPeriodic("v-"+num);
+      97           2 :       Value* comp=getPntrToComponent("v-"+num);
+      98           2 :       comp->set(values[i]);
+      99             :     }
+     100             :   }
+     101             : // fake request to avoid errors:
+     102             :   std::vector<AtomNumber> atoms;
+     103          39 :   requestAtoms(atoms);
+     104          39 : }
+     105             : 
+     106          41 : void Constant::registerKeywords( Keywords& keys ) {
+     107          41 :   Colvar::registerKeywords( keys );
+     108          41 :   componentsAreNotOptional(keys);
+     109          41 :   keys.remove("NUMERICAL_DERIVATIVES");
+     110          82 :   keys.add("optional","VALUES","The values of the constants");
+     111          82 :   keys.add("optional","VALUE","The value of the constant");
+     112          82 :   keys.addFlag("NODERIV",false,"Set to TRUE if you want values without derivatives.");
+     113          82 :   keys.addOutputComponent("v","default","the # value");
+     114          41 : }
+     115             : 
+     116             : // calculator
+     117        3401 : void Constant::calculate() {
+     118        3401 :   if(values.size()==1) {
+     119        3396 :     setValue(values[0]);
+     120        3396 :     return;
+     121             :   }
+     122          15 :   for(unsigned i=0; i<values.size(); i++) {
+     123          10 :     Value* comp=getPntrToComponent(i);
+     124          10 :     comp->set(values[i]);
+     125             :   }
+     126             : }
+     127             : 
+     128             : }
+     129             : }
+     130             : 
+     131             : 
+     132             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ContactMap.cpp.func-sort-c.html b/coverage/colvar/ContactMap.cpp.func-sort-c.html new file mode 100644 index 000000000000..1c0db0338580 --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ContactMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ContactMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12013191.6 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10ContactMap18checkFieldsAllowedEv0
_ZN4PLMD6colvar10ContactMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar10ContactMapC1ERKNS_13ActionOptionsE8
_ZN4PLMD6colvar10ContactMap16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6colvar10ContactMap9calculateEv2215
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ContactMap.cpp.func.html b/coverage/colvar/ContactMap.cpp.func.html new file mode 100644 index 000000000000..3c578cd66fbc --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ContactMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ContactMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12013191.6 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10ContactMap16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6colvar10ContactMap18checkFieldsAllowedEv0
_ZN4PLMD6colvar10ContactMap9calculateEv2215
_ZN4PLMD6colvar10ContactMapC1ERKNS_13ActionOptionsE8
_ZN4PLMD6colvar10ContactMapC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ContactMap.cpp.gcov.html b/coverage/colvar/ContactMap.cpp.gcov.html new file mode 100644 index 000000000000..ea65a856b9ef --- /dev/null +++ b/coverage/colvar/ContactMap.cpp.gcov.html @@ -0,0 +1,404 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ContactMap.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ContactMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12013191.6 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "tools/Communicator.h"
+      24             : #include "tools/NeighborList.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/SwitchingFunction.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace colvar {
+      30             : 
+      31             : //+PLUMEDOC COLVAR CONTACTMAP
+      32             : /*
+      33             : Calculate the distances between a number of pairs of atoms and transform each distance by a switching function.
+      34             : 
+      35             : The transformed distance can be compared with a reference value in order to calculate the squared distance
+      36             : between two contact maps. Each distance can also be weighted for a given value. CONTACTMAP can be used together
+      37             : with \ref FUNCPATHMSD to define a path in the contactmap space.
+      38             : 
+      39             : The individual contact map distances related to each contact can be accessed as components
+      40             : named `cm.contact-1`, `cm.contact-2`, etc, assuming that the label of the CONTACTMAP is `cm`.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : The following example calculates switching functions based on the distances between atoms
+      45             : 1 and 2, 3 and 4 and 4 and 5. The values of these three switching functions are then output
+      46             : to a file named colvar.
+      47             : 
+      48             : \plumedfile
+      49             : CONTACTMAP ATOMS1=1,2 ATOMS2=3,4 ATOMS3=4,5 ATOMS4=5,6 SWITCH={RATIONAL R_0=1.5} LABEL=f1
+      50             : PRINT ARG=f1.* FILE=colvar
+      51             : \endplumedfile
+      52             : 
+      53             : The following example calculates the difference of the current contact map with respect
+      54             : to a reference provided. In this case REFERENCE is the fraction of contact that is formed
+      55             : (i.e. the distance between two atoms transformed with the SWITCH), while R_0 is the contact
+      56             : distance. WEIGHT gives the relative weight of each contact to the final distance measure.
+      57             : 
+      58             : \plumedfile
+      59             : CONTACTMAP ...
+      60             : ATOMS1=1,2 REFERENCE1=0.1 WEIGHT1=0.5
+      61             : ATOMS2=3,4 REFERENCE2=0.5 WEIGHT2=1.0
+      62             : ATOMS3=4,5 REFERENCE3=0.25 WEIGHT3=1.0
+      63             : ATOMS4=5,6 REFERENCE4=0.0 WEIGHT4=0.5
+      64             : SWITCH={RATIONAL R_0=1.5}
+      65             : LABEL=cmap
+      66             : CMDIST
+      67             : ... CONTACTMAP
+      68             : 
+      69             : PRINT ARG=cmap FILE=colvar
+      70             : \endplumedfile
+      71             : 
+      72             : The next example calculates calculates fraction of native contacts (Q)
+      73             : for Trp-cage mini-protein. R_0 is the distance at which the switch function is guaranteed to
+      74             : be 1.0 – it doesn't really matter for Q and  should be something very small, like 1 A.
+      75             : REF is the reference distance for the contact, e.g. the distance from a crystal structure.
+      76             : LAMBDA is the tolerance for the distance – if set to 1.0, the contact would have to have exactly
+      77             : the reference value to be formed; instead for lambda values of 1.5–1.8 are usually used to allow some slack.
+      78             : BETA is the softness of the switch function, default is 50nm.
+      79             : WEIGHT is the 1/(number of contacts) giving equal weight to each contact.
+      80             : 
+      81             : When using native contact Q switch function, please cite \cite best2013
+      82             : 
+      83             : \plumedfile
+      84             : # The full (much-longer) example available in regtest/basic/rt72/
+      85             : 
+      86             : CONTACTMAP ...
+      87             : ATOMS1=1,67 SWITCH1={Q R_0=0.01 BETA=50.0 LAMBDA=1.5 REF=0.4059} WEIGHT1=0.003597
+      88             : ATOMS2=1,68 SWITCH2={Q R_0=0.01 BETA=50.0 LAMBDA=1.5 REF=0.4039} WEIGHT2=0.003597
+      89             : ATOMS3=1,69 SWITCH3={Q R_0=0.01 BETA=50.0 LAMBDA=1.5 REF=0.3215} WEIGHT3=0.003597
+      90             : ATOMS4=5,61 SWITCH4={Q R_0=0.01 BETA=50.0 LAMBDA=1.5 REF=0.4277} WEIGHT4=0.003597
+      91             : ATOMS5=5,67 SWITCH5={Q R_0=0.01 BETA=50.0 LAMBDA=1.5 REF=0.3851} WEIGHT5=0.003597
+      92             : ATOMS6=5,68 SWITCH6={Q R_0=0.01 BETA=50.0 LAMBDA=1.5 REF=0.3811} WEIGHT6=0.003597
+      93             : ATOMS7=5,69 SWITCH7={Q R_0=0.01 BETA=50.0 LAMBDA=1.5 REF=0.3133} WEIGHT7=0.003597
+      94             : LABEL=cmap
+      95             : SUM
+      96             : ... CONTACTMAP
+      97             : 
+      98             : PRINT ARG=cmap FILE=colvar
+      99             : \endplumedfile
+     100             : (See also \ref switchingfunction)
+     101             : 
+     102             : */
+     103             : //+ENDPLUMEDOC
+     104             : 
+     105             : class ContactMap : public Colvar {
+     106             : private:
+     107             :   bool pbc, serial, docomp, dosum, docmdist;
+     108             :   std::unique_ptr<NeighborList> nl;
+     109             :   std::vector<SwitchingFunction> sfs;
+     110             :   std::vector<double> reference, weight;
+     111             : public:
+     112             :   static void registerKeywords( Keywords& keys );
+     113             :   explicit ContactMap(const ActionOptions&);
+     114             : // active methods:
+     115             :   void calculate() override;
+     116           0 :   void checkFieldsAllowed() override {}
+     117             : };
+     118             : 
+     119             : PLUMED_REGISTER_ACTION(ContactMap,"CONTACTMAP")
+     120             : 
+     121          10 : void ContactMap::registerKeywords( Keywords& keys ) {
+     122          10 :   Colvar::registerKeywords( keys );
+     123          20 :   keys.add("numbered","ATOMS","the atoms involved in each of the contacts you wish to calculate. "
+     124             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one contact will be "
+     125             :            "calculated for each ATOM keyword you specify.");
+     126          20 :   keys.reset_style("ATOMS","atoms");
+     127          20 :   keys.add("numbered","SWITCH","The switching functions to use for each of the contacts in your map. "
+     128             :            "You can either specify a global switching function using SWITCH or one "
+     129             :            "switching function for each contact. Details of the various switching "
+     130             :            "functions you can use are provided on \\ref switchingfunction.");
+     131          20 :   keys.add("numbered","REFERENCE","A reference value for a given contact, by default is 0.0 "
+     132             :            "You can either specify a global reference value using REFERENCE or one "
+     133             :            "reference value for each contact.");
+     134          20 :   keys.add("numbered","WEIGHT","A weight value for a given contact, by default is 1.0 "
+     135             :            "You can either specify a global weight value using WEIGHT or one "
+     136             :            "weight value for each contact.");
+     137          20 :   keys.reset_style("SWITCH","compulsory");
+     138          20 :   keys.addFlag("SUM",false,"calculate the sum of all the contacts in the input");
+     139          20 :   keys.addFlag("CMDIST",false,"calculate the distance with respect to the provided reference contact map");
+     140          20 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     141          20 :   keys.addOutputComponent("contact","default","By not using SUM or CMDIST each contact will be stored in a component");
+     142          10 : }
+     143             : 
+     144           8 : ContactMap::ContactMap(const ActionOptions&ao):
+     145             :   PLUMED_COLVAR_INIT(ao),
+     146           8 :   pbc(true),
+     147           8 :   serial(false),
+     148           8 :   docomp(true),
+     149           8 :   dosum(false),
+     150           8 :   docmdist(false)
+     151             : {
+     152           8 :   parseFlag("SERIAL",serial);
+     153           8 :   parseFlag("SUM",dosum);
+     154           8 :   parseFlag("CMDIST",docmdist);
+     155           8 :   if(docmdist==true&&dosum==true) error("You cannot use SUM and CMDIST together");
+     156           8 :   bool nopbc=!pbc;
+     157           8 :   parseFlag("NOPBC",nopbc);
+     158           8 :   pbc=!nopbc;
+     159             : 
+     160             :   // Read in the atoms
+     161             :   std::vector<AtomNumber> t, ga_lista, gb_lista;
+     162           8 :   for(int i=1;; ++i ) {
+     163        1186 :     parseAtomList("ATOMS", i, t );
+     164         593 :     if( t.empty() ) break;
+     165             : 
+     166         585 :     if( t.size()!=2 ) {
+     167           0 :       std::string ss; Tools::convert(i,ss);
+     168           0 :       error("ATOMS" + ss + " keyword has the wrong number of atoms");
+     169             :     }
+     170         585 :     ga_lista.push_back(t[0]); gb_lista.push_back(t[1]);
+     171         585 :     t.resize(0);
+     172             : 
+     173             :     // Add a value for this contact
+     174         585 :     std::string num; Tools::convert(i,num);
+     175         595 :     if(!dosum&&!docmdist) {addComponentWithDerivatives("contact-"+num); componentIsNotPeriodic("contact-"+num);}
+     176         585 :   }
+     177             :   // Create neighbour lists
+     178          16 :   nl=Tools::make_unique<NeighborList>(ga_lista,gb_lista,serial,true,pbc,getPbc(),comm);
+     179             : 
+     180             :   // Read in switching functions
+     181           8 :   std::string errors; sfs.resize( ga_lista.size() ); unsigned nswitch=0;
+     182         593 :   for(unsigned i=0; i<ga_lista.size(); ++i) {
+     183         585 :     std::string num, sw1; Tools::convert(i+1, num);
+     184        1170 :     if( !parseNumbered( "SWITCH", i+1, sw1 ) ) break;
+     185         585 :     nswitch++; sfs[i].set(sw1,errors);
+     186         585 :     if( errors.length()!=0 ) error("problem reading SWITCH" + num + " keyword : " + errors );
+     187             :   }
+     188           8 :   if( nswitch==0 ) {
+     189           0 :     std::string sw; parse("SWITCH",sw);
+     190           0 :     if(sw.length()==0) error("no switching function specified use SWITCH keyword");
+     191           0 :     for(unsigned i=0; i<ga_lista.size(); ++i) {
+     192           0 :       sfs[i].set(sw,errors);
+     193           0 :       if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     194             :     }
+     195           8 :   } else if( nswitch!=sfs.size()  ) {
+     196           0 :     std::string num; Tools::convert(nswitch+1, num);
+     197           0 :     error("missing SWITCH" + num + " keyword");
+     198             :   }
+     199             : 
+     200             :   // Read in reference values
+     201             :   nswitch=0;
+     202           8 :   reference.resize(ga_lista.size(), 0.);
+     203          18 :   for(unsigned i=0; i<ga_lista.size(); ++i) {
+     204          32 :     if( !parseNumbered( "REFERENCE", i+1, reference[i] ) ) break;
+     205          10 :     nswitch++;
+     206             :   }
+     207           8 :   if( nswitch==0 ) {
+     208           6 :     parse("REFERENCE",reference[0]);
+     209         575 :     for(unsigned i=1; i<ga_lista.size(); ++i) {
+     210         569 :       reference[i]=reference[0];
+     211         569 :       nswitch++;
+     212             :     }
+     213             :   }
+     214           8 :   if(nswitch == 0 && docmdist) error("with CMDIST one must use REFERENCE to setup the reference contact map");
+     215             : 
+     216             :   // Read in weight values
+     217             :   nswitch=0;
+     218           8 :   weight.resize(ga_lista.size(), 1.0);
+     219         588 :   for(unsigned i=0; i<ga_lista.size(); ++i) {
+     220        1162 :     if( !parseNumbered( "WEIGHT", i+1, weight[i] ) ) break;
+     221         580 :     nswitch++;
+     222             :   }
+     223           8 :   if( nswitch==0 ) {
+     224           1 :     parse("WEIGHT",weight[0]);
+     225           5 :     for(unsigned i=1; i<ga_lista.size(); ++i) {
+     226           4 :       weight[i]=weight[0];
+     227             :     }
+     228             :     nswitch = ga_lista.size();
+     229             :   }
+     230             : 
+     231             :   // Output details of all contacts
+     232         593 :   for(unsigned i=0; i<sfs.size(); ++i) {
+     233         585 :     log.printf("  The %uth contact is calculated from atoms : %d %d. Inflection point of switching function is at %s. Reference contact value is %f\n",
+     234        1170 :                i+1, ga_lista[i].serial(), gb_lista[i].serial(), ( sfs[i].description() ).c_str(), reference[i] );
+     235             :   }
+     236             : 
+     237           8 :   if(dosum) {
+     238          10 :     addValueWithDerivatives(); setNotPeriodic();
+     239           5 :     log.printf("  colvar is sum of all contacts in contact map\n");
+     240             :   }
+     241           8 :   if(docmdist) {
+     242           4 :     addValueWithDerivatives(); setNotPeriodic();
+     243           2 :     log.printf("  colvar is distance between the contact map matrix and the provided reference matrix\n");
+     244             :   }
+     245             : 
+     246           8 :   if(dosum || docmdist) {
+     247           7 :     docomp=false;
+     248             :   } else {
+     249           1 :     serial=true;
+     250           1 :     docomp=true;
+     251             :   }
+     252             : 
+     253             :   // Set up if it is just a list of contacts
+     254           8 :   requestAtoms(nl->getFullAtomList());
+     255           8 :   checkRead();
+     256           8 : }
+     257             : 
+     258        2215 : void ContactMap::calculate() {
+     259             : 
+     260        2215 :   double ncoord=0.;
+     261        2215 :   Tensor virial;
+     262        2215 :   std::vector<Vector> deriv(getNumberOfAtoms());
+     263             : 
+     264             :   unsigned stride;
+     265             :   unsigned rank;
+     266        2215 :   if(serial) {
+     267             :     // when using components the parallelisation do not work
+     268             :     stride=1;
+     269             :     rank=0;
+     270             :   } else {
+     271        2210 :     stride=comm.Get_size();
+     272        2210 :     rank=comm.Get_rank();
+     273             :   }
+     274             : 
+     275             : // sum over close pairs
+     276      149835 :   for(unsigned i=rank; i<nl->size(); i+=stride) {
+     277      147620 :     Vector distance;
+     278      147620 :     unsigned i0=nl->getClosePair(i).first;
+     279      147620 :     unsigned i1=nl->getClosePair(i).second;
+     280      147620 :     if(pbc) {
+     281      147620 :       distance=pbcDistance(getPosition(i0),getPosition(i1));
+     282             :     } else {
+     283           0 :       distance=delta(getPosition(i0),getPosition(i1));
+     284             :     }
+     285             : 
+     286      147620 :     double dfunc=0.;
+     287      147620 :     double coord = weight[i]*(sfs[i].calculate(distance.modulo(), dfunc) - reference[i]);
+     288      147620 :     Vector tmpder = weight[i]*dfunc*distance;
+     289      147620 :     Tensor tmpvir = weight[i]*dfunc*Tensor(distance,distance);
+     290      147620 :     if(!docmdist) {
+     291      146595 :       deriv[i0] -= tmpder;
+     292      146595 :       deriv[i1] += tmpder;
+     293      146595 :       virial    -= tmpvir;
+     294      146595 :       ncoord    += coord;
+     295             :     } else {
+     296        1025 :       tmpder *= 2.*coord;
+     297        1025 :       tmpvir *= 2.*coord;
+     298        1025 :       deriv[i0] -= tmpder;
+     299        1025 :       deriv[i1] += tmpder;
+     300        1025 :       virial    -= tmpvir;
+     301        1025 :       ncoord    += coord*coord;
+     302             :     }
+     303             : 
+     304      147620 :     if(docomp) {
+     305          25 :       Value* val=getPntrToComponent( i );
+     306          25 :       setAtomsDerivatives( val, i0, deriv[i0] );
+     307          25 :       setAtomsDerivatives( val, i1, deriv[i1] );
+     308          25 :       setBoxDerivatives( val, -tmpvir );
+     309             :       val->set(coord);
+     310             :     }
+     311             :   }
+     312             : 
+     313        2215 :   if(!serial) {
+     314        2210 :     comm.Sum(&ncoord,1);
+     315        2210 :     if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size());
+     316        2210 :     comm.Sum(&virial[0][0],9);
+     317             :   }
+     318             : 
+     319        2215 :   if( !docomp ) {
+     320      297400 :     for(unsigned i=0; i<deriv.size(); ++i) setAtomsDerivatives(i,deriv[i]);
+     321        2210 :     setValue           (ncoord);
+     322        2210 :     setBoxDerivatives  (virial);
+     323             :   }
+     324        2215 : }
+     325             : 
+     326             : }
+     327             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Coordination.cpp.func-sort-c.html b/coverage/colvar/Coordination.cpp.func-sort-c.html new file mode 100644 index 000000000000..80b048abdeb9 --- /dev/null +++ b/coverage/colvar/Coordination.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Coordination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Coordination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12CoordinationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar12CoordinationC1ERKNS_13ActionOptionsE182
_ZN4PLMD6colvar12Coordination16registerKeywordsERNS_8KeywordsE184
_ZNK4PLMD6colvar12Coordination7pairingEdRdjj15263736
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Coordination.cpp.func.html b/coverage/colvar/Coordination.cpp.func.html new file mode 100644 index 000000000000..d9d4a1a23aee --- /dev/null +++ b/coverage/colvar/Coordination.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Coordination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Coordination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar12Coordination16registerKeywordsERNS_8KeywordsE184
_ZN4PLMD6colvar12CoordinationC1ERKNS_13ActionOptionsE182
_ZN4PLMD6colvar12CoordinationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar12Coordination7pairingEdRdjj15263736
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Coordination.cpp.gcov.html b/coverage/colvar/Coordination.cpp.gcov.html new file mode 100644 index 000000000000..2ec1761af3c1 --- /dev/null +++ b/coverage/colvar/Coordination.cpp.gcov.html @@ -0,0 +1,231 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Coordination.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Coordination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CoordinationBase.h"
+      23             : #include "tools/SwitchingFunction.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace colvar {
+      28             : 
+      29             : //+PLUMEDOC COLVAR COORDINATION
+      30             : /*
+      31             : Calculate coordination numbers.
+      32             : 
+      33             : This keyword can be used to calculate the number of contacts between two groups of atoms
+      34             : and is defined as
+      35             : \f[
+      36             : \sum_{i\in A} \sum_{i\in B} s_{ij}
+      37             : \f]
+      38             : where \f$s_{ij}\f$ is 1 if the contact between atoms \f$i\f$ and \f$j\f$ is formed,
+      39             : zero otherwise.
+      40             : In actuality, \f$s_{ij}\f$ is replaced with a switching function so as to ensure that the calculated CV has continuous derivatives.
+      41             : The default switching function is:
+      42             : \f[
+      43             : s_{ij} = \frac{ 1 - \left(\frac{{\bf r}_{ij}-d_0}{r_0}\right)^n } { 1 - \left(\frac{{\bf r}_{ij}-d_0}{r_0}\right)^m }
+      44             : \f]
+      45             : but it can be changed using the optional SWITCH option.
+      46             : 
+      47             : To make your calculation faster you can use a neighbor list, which makes it that only a
+      48             : relevant subset of the pairwise distance are calculated at every step.
+      49             : 
+      50             : If GROUPB is empty, it will sum the \f$\frac{N(N-1)}{2}\f$ pairs in GROUPA. This avoids computing
+      51             : twice permuted indexes (e.g. pair (i,j) and (j,i)) thus running at twice the speed.
+      52             : 
+      53             : Notice that if there are common atoms between GROUPA and GROUPB the switching function should be
+      54             : equal to one. These "self contacts" are discarded by plumed (since version 2.1),
+      55             : so that they actually count as "zero".
+      56             : 
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : The following example instructs plumed to calculate the total coordination number of the atoms in group 1-10 with the atoms in group 20-100.  For atoms 1-10 coordination numbers are calculated that count the number of atoms from the second group that are within 0.3 nm of the central atom.  A neighbor list is used to make this calculation faster, this neighbor list is updated every 100 steps.
+      61             : \plumedfile
+      62             : COORDINATION GROUPA=1-10 GROUPB=20-100 R_0=0.3 NLIST NL_CUTOFF=0.5 NL_STRIDE=100
+      63             : \endplumedfile
+      64             : 
+      65             : The following is a dummy example which should compute the value 0 because the self interaction
+      66             : of atom 1 is skipped. Notice that in plumed 2.0 "self interactions" were not skipped, and the
+      67             : same calculation should return 1.
+      68             : \plumedfile
+      69             : c: COORDINATION GROUPA=1 GROUPB=1 R_0=0.3
+      70             : PRINT ARG=c STRIDE=10
+      71             : \endplumedfile
+      72             : 
+      73             : Here's an example that shows what happens when providing COORDINATION with
+      74             : a single group:
+      75             : \plumedfile
+      76             : # define some huge group:
+      77             : group: GROUP ATOMS=1-1000
+      78             : # Here's coordination of a group against itself:
+      79             : c1: COORDINATION GROUPA=group GROUPB=group R_0=0.3
+      80             : # Here's coordination within a single group:
+      81             : x: COORDINATION GROUPA=group R_0=0.3
+      82             : # This is just multiplying times 2 the variable x:
+      83             : c2: COMBINE ARG=x COEFFICIENTS=2 PERIODIC=NO
+      84             : 
+      85             : # the two variables c1 and c2 should be identical, but the calculation of c2 is twice faster
+      86             : # since it runs on half of the pairs.
+      87             : PRINT ARG=c1,c2 STRIDE=10
+      88             : \endplumedfile
+      89             : 
+      90             : 
+      91             : 
+      92             : */
+      93             : //+ENDPLUMEDOC
+      94             : 
+      95             : class Coordination : public CoordinationBase {
+      96             :   SwitchingFunction switchingFunction;
+      97             : 
+      98             : public:
+      99             :   explicit Coordination(const ActionOptions&);
+     100             : // active methods:
+     101             :   static void registerKeywords( Keywords& keys );
+     102             :   double pairing(double distance,double&dfunc,unsigned i,unsigned j)const override;
+     103             : };
+     104             : 
+     105             : PLUMED_REGISTER_ACTION(Coordination,"COORDINATION")
+     106             : 
+     107         184 : void Coordination::registerKeywords( Keywords& keys ) {
+     108         184 :   CoordinationBase::registerKeywords(keys);
+     109         368 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     110         368 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     111         368 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     112         368 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     113         368 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+     114             :            "The following provides information on the \\ref switchingfunction that are available. "
+     115             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     116         184 : }
+     117             : 
+     118         182 : Coordination::Coordination(const ActionOptions&ao):
+     119             :   Action(ao),
+     120         182 :   CoordinationBase(ao)
+     121             : {
+     122             : 
+     123             :   std::string sw,errors;
+     124         364 :   parse("SWITCH",sw);
+     125         182 :   if(sw.length()>0) {
+     126         133 :     switchingFunction.set(sw,errors);
+     127         131 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     128             :   } else {
+     129          49 :     int nn=6;
+     130          49 :     int mm=0;
+     131          49 :     double d0=0.0;
+     132          49 :     double r0=0.0;
+     133          49 :     parse("R_0",r0);
+     134          49 :     if(r0<=0.0) error("R_0 should be explicitly specified and positive");
+     135          49 :     parse("D_0",d0);
+     136          49 :     parse("NN",nn);
+     137          47 :     parse("MM",mm);
+     138          47 :     switchingFunction.set(nn,mm,r0,d0);
+     139             :   }
+     140             : 
+     141         177 :   checkRead();
+     142             : 
+     143         359 :   log<<"  contacts are counted with cutoff "<<switchingFunction.description()<<"\n";
+     144         192 : }
+     145             : 
+     146    15263736 : double Coordination::pairing(double distance,double&dfunc,unsigned i,unsigned j)const {
+     147             :   (void) i; // avoid warnings
+     148             :   (void) j; // avoid warnings
+     149    15263736 :   return switchingFunction.calculateSqr(distance,dfunc);
+     150             : }
+     151             : 
+     152             : }
+     153             : 
+     154             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/CoordinationBase.cpp.func-sort-c.html b/coverage/colvar/CoordinationBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..7e7040db8f5f --- /dev/null +++ b/coverage/colvar/CoordinationBase.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - colvar/CoordinationBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - CoordinationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:899098.9 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16CoordinationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16CoordinationBaseD0Ev0
_ZN4PLMD6colvar16CoordinationBaseD1Ev0
_ZN4PLMD6colvar16CoordinationBaseC2ERKNS_13ActionOptionsE191
_ZN4PLMD6colvar16CoordinationBaseD2Ev191
_ZN4PLMD6colvar16CoordinationBase16registerKeywordsERNS_8KeywordsE197
_ZN4PLMD6colvar16CoordinationBase9calculateEv3072
_ZN4PLMD6colvar16CoordinationBase7prepareEv3297
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/CoordinationBase.cpp.func.html b/coverage/colvar/CoordinationBase.cpp.func.html new file mode 100644 index 000000000000..0e845fb9d9f3 --- /dev/null +++ b/coverage/colvar/CoordinationBase.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - colvar/CoordinationBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - CoordinationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:899098.9 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16CoordinationBase16registerKeywordsERNS_8KeywordsE197
_ZN4PLMD6colvar16CoordinationBase7prepareEv3297
_ZN4PLMD6colvar16CoordinationBase9calculateEv3072
_ZN4PLMD6colvar16CoordinationBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16CoordinationBaseC2ERKNS_13ActionOptionsE191
_ZN4PLMD6colvar16CoordinationBaseD0Ev0
_ZN4PLMD6colvar16CoordinationBaseD1Ev0
_ZN4PLMD6colvar16CoordinationBaseD2Ev191
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/CoordinationBase.cpp.gcov.html b/coverage/colvar/CoordinationBase.cpp.gcov.html new file mode 100644 index 000000000000..64f774a0b4e5 --- /dev/null +++ b/coverage/colvar/CoordinationBase.cpp.gcov.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - colvar/CoordinationBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - CoordinationBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:899098.9 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CoordinationBase.h"
+      23             : #include "tools/NeighborList.h"
+      24             : #include "tools/Communicator.h"
+      25             : #include "tools/OpenMP.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace colvar {
+      29             : 
+      30         197 : void CoordinationBase::registerKeywords( Keywords& keys ) {
+      31         197 :   Colvar::registerKeywords(keys);
+      32         394 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+      33         394 :   keys.addFlag("PAIR",false,"Pair only 1st element of the 1st group with 1st element in the second, etc");
+      34         394 :   keys.addFlag("NLIST",false,"Use a neighbor list to speed up the calculation");
+      35         394 :   keys.add("optional","NL_CUTOFF","The cutoff for the neighbor list");
+      36         394 :   keys.add("optional","NL_STRIDE","The frequency with which we are updating the atoms in the neighbor list");
+      37         394 :   keys.add("atoms","GROUPA","First list of atoms");
+      38         394 :   keys.add("atoms","GROUPB","Second list of atoms (if empty, N*(N-1)/2 pairs in GROUPA are counted)");
+      39         197 : }
+      40             : 
+      41         191 : CoordinationBase::CoordinationBase(const ActionOptions&ao):
+      42             :   PLUMED_COLVAR_INIT(ao),
+      43         191 :   pbc(true),
+      44         191 :   serial(false),
+      45         191 :   invalidateList(true),
+      46         191 :   firsttime(true)
+      47             : {
+      48             : 
+      49         382 :   parseFlag("SERIAL",serial);
+      50             : 
+      51             :   std::vector<AtomNumber> ga_lista,gb_lista;
+      52         191 :   parseAtomList("GROUPA",ga_lista);
+      53         191 :   parseAtomList("GROUPB",gb_lista);
+      54             : 
+      55         191 :   bool nopbc=!pbc;
+      56         191 :   parseFlag("NOPBC",nopbc);
+      57         191 :   pbc=!nopbc;
+      58             : 
+      59             : // pair stuff
+      60         191 :   bool dopair=false;
+      61         191 :   parseFlag("PAIR",dopair);
+      62             : 
+      63             : // neighbor list stuff
+      64         191 :   bool doneigh=false;
+      65         191 :   double nl_cut=0.0;
+      66         191 :   int nl_st=0;
+      67         191 :   parseFlag("NLIST",doneigh);
+      68         191 :   if(doneigh) {
+      69          24 :     parse("NL_CUTOFF",nl_cut);
+      70          24 :     if(nl_cut<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+      71          24 :     parse("NL_STRIDE",nl_st);
+      72          24 :     if(nl_st<=0) error("NL_STRIDE should be explicitly specified and positive");
+      73             :   }
+      74             : 
+      75         382 :   addValueWithDerivatives(); setNotPeriodic();
+      76         191 :   if(gb_lista.size()>0) {
+      77         204 :     if(doneigh)  nl=Tools::make_unique<NeighborList>(ga_lista,gb_lista,serial,dopair,pbc,getPbc(),comm,nl_cut,nl_st);
+      78         312 :     else         nl=Tools::make_unique<NeighborList>(ga_lista,gb_lista,serial,dopair,pbc,getPbc(),comm);
+      79             :   } else {
+      80          11 :     if(doneigh)  nl=Tools::make_unique<NeighborList>(ga_lista,serial,pbc,getPbc(),comm,nl_cut,nl_st);
+      81          22 :     else         nl=Tools::make_unique<NeighborList>(ga_lista,serial,pbc,getPbc(),comm);
+      82             :   }
+      83             : 
+      84         191 :   requestAtoms(nl->getFullAtomList());
+      85             : 
+      86         191 :   log.printf("  between two groups of %u and %u atoms\n",static_cast<unsigned>(ga_lista.size()),static_cast<unsigned>(gb_lista.size()));
+      87         191 :   log.printf("  first group:\n");
+      88        5459 :   for(unsigned int i=0; i<ga_lista.size(); ++i) {
+      89        5268 :     if ( (i+1) % 25 == 0 ) log.printf("  \n");
+      90        5268 :     log.printf("  %d", ga_lista[i].serial());
+      91             :   }
+      92         191 :   log.printf("  \n  second group:\n");
+      93       10811 :   for(unsigned int i=0; i<gb_lista.size(); ++i) {
+      94       10620 :     if ( (i+1) % 25 == 0 ) log.printf("  \n");
+      95       10620 :     log.printf("  %d", gb_lista[i].serial());
+      96             :   }
+      97         191 :   log.printf("  \n");
+      98         191 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+      99           0 :   else    log.printf("  without periodic boundary conditions\n");
+     100         191 :   if(dopair) log.printf("  with PAIR option\n");
+     101         191 :   if(doneigh) {
+     102          24 :     log.printf("  using neighbor lists with\n");
+     103          24 :     log.printf("  update every %d steps and cutoff %f\n",nl_st,nl_cut);
+     104             :   }
+     105         191 : }
+     106             : 
+     107         191 : CoordinationBase::~CoordinationBase() {
+     108             : // destructor required to delete forward declared class
+     109         191 : }
+     110             : 
+     111        3297 : void CoordinationBase::prepare() {
+     112        3297 :   if(nl->getStride()>0) {
+     113         216 :     if(firsttime || (getStep()%nl->getStride()==0)) {
+     114         179 :       requestAtoms(nl->getFullAtomList());
+     115         179 :       invalidateList=true;
+     116         179 :       firsttime=false;
+     117             :     } else {
+     118          37 :       requestAtoms(nl->getReducedAtomList());
+     119          37 :       invalidateList=false;
+     120          37 :       if(getExchangeStep()) error("Neighbor lists should be updated on exchange steps - choose a NL_STRIDE which divides the exchange stride!");
+     121             :     }
+     122         216 :     if(getExchangeStep()) firsttime=true;
+     123             :   }
+     124        3297 : }
+     125             : 
+     126             : // calculator
+     127        3072 : void CoordinationBase::calculate()
+     128             : {
+     129             : 
+     130        3072 :   double ncoord=0.;
+     131        3072 :   Tensor virial;
+     132        3072 :   std::vector<Vector> deriv(getNumberOfAtoms());
+     133             : 
+     134        3072 :   if(nl->getStride()>0 && invalidateList) {
+     135         143 :     nl->update(getPositions());
+     136             :   }
+     137             : 
+     138             :   unsigned stride;
+     139             :   unsigned rank;
+     140        3072 :   if(serial) {
+     141             :     stride=1;
+     142             :     rank=0;
+     143             :   } else {
+     144        3072 :     stride=comm.Get_size();
+     145        3072 :     rank=comm.Get_rank();
+     146             :   }
+     147             : 
+     148        3072 :   unsigned nt=OpenMP::getNumThreads();
+     149        3072 :   const unsigned nn=nl->size();
+     150        3072 :   if(nt*stride*10>nn) nt=1;
+     151             : 
+     152        3072 :   #pragma omp parallel num_threads(nt)
+     153             :   {
+     154             :     std::vector<Vector> omp_deriv(getPositions().size());
+     155             :     Tensor omp_virial;
+     156             : 
+     157             :     #pragma omp for reduction(+:ncoord) nowait
+     158             :     for(unsigned int i=rank; i<nn; i+=stride) {
+     159             : 
+     160             :       Vector distance;
+     161             :       unsigned i0=nl->getClosePair(i).first;
+     162             :       unsigned i1=nl->getClosePair(i).second;
+     163             : 
+     164             :       if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) continue;
+     165             : 
+     166             :       if(pbc) {
+     167             :         distance=pbcDistance(getPosition(i0),getPosition(i1));
+     168             :       } else {
+     169             :         distance=delta(getPosition(i0),getPosition(i1));
+     170             :       }
+     171             : 
+     172             :       double dfunc=0.;
+     173             :       ncoord += pairing(distance.modulo2(), dfunc,i0,i1);
+     174             : 
+     175             :       Vector dd(dfunc*distance);
+     176             :       Tensor vv(dd,distance);
+     177             :       if(nt>1) {
+     178             :         omp_deriv[i0]-=dd;
+     179             :         omp_deriv[i1]+=dd;
+     180             :         omp_virial-=vv;
+     181             :       } else {
+     182             :         deriv[i0]-=dd;
+     183             :         deriv[i1]+=dd;
+     184             :         virial-=vv;
+     185             :       }
+     186             : 
+     187             :     }
+     188             :     #pragma omp critical
+     189             :     if(nt>1) {
+     190             :       for(unsigned i=0; i<getPositions().size(); i++) deriv[i]+=omp_deriv[i];
+     191             :       virial+=omp_virial;
+     192             :     }
+     193             :   }
+     194             : 
+     195        3072 :   if(!serial) {
+     196        3072 :     comm.Sum(ncoord);
+     197        3072 :     if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size());
+     198        3072 :     comm.Sum(virial);
+     199             :   }
+     200             : 
+     201      378000 :   for(unsigned i=0; i<deriv.size(); ++i) setAtomsDerivatives(i,deriv[i]);
+     202        3072 :   setValue           (ncoord);
+     203        3072 :   setBoxDerivatives  (virial);
+     204             : 
+     205        3072 : }
+     206             : }
+     207             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DHEnergy.cpp.func-sort-c.html b/coverage/colvar/DHEnergy.cpp.func-sort-c.html new file mode 100644 index 000000000000..358a727e4eb2 --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/DHEnergy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DHEnergy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313393.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8DHEnergyC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8DHEnergyC1ERKNS_13ActionOptionsE8
_ZN4PLMD6colvar8DHEnergy16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD6colvar8DHEnergy7pairingEdRdjj840
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DHEnergy.cpp.func.html b/coverage/colvar/DHEnergy.cpp.func.html new file mode 100644 index 000000000000..c5f69a9107a5 --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/DHEnergy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DHEnergy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313393.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8DHEnergy16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD6colvar8DHEnergyC1ERKNS_13ActionOptionsE8
_ZN4PLMD6colvar8DHEnergyC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar8DHEnergy7pairingEdRdjj840
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DHEnergy.cpp.gcov.html b/coverage/colvar/DHEnergy.cpp.gcov.html new file mode 100644 index 000000000000..380014426bea --- /dev/null +++ b/coverage/colvar/DHEnergy.cpp.gcov.html @@ -0,0 +1,220 @@ + + + + + + + + LCOV - plumed test coverage - colvar/DHEnergy.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DHEnergy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313393.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CoordinationBase.h"
+      23             : #include "tools/SwitchingFunction.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace colvar {
+      29             : 
+      30             : //+PLUMEDOC COLVAR DHENERGY
+      31             : /*
+      32             : Calculate Debye-Huckel interaction energy among GROUPA and GROUPB.
+      33             : 
+      34             : This variable calculates the electrostatic interaction among GROUPA and GROUPB
+      35             : using a Debye-Huckel approximation defined as
+      36             : \f[
+      37             : \frac{1}{4\pi\epsilon_r\epsilon_0}
+      38             : \sum_{i\in A} \sum_{j \in B} q_i q_j
+      39             : \frac{e^{-\kappa |{\bf r}_{ij}|}}{|{\bf r}_{ij}|}
+      40             : \f]
+      41             : 
+      42             : This collective variable can be used to analyze or induce electrostatically driven reactions \cite do13jctc.
+      43             : Notice that the value of the DHENERGY is returned in plumed units (see \ref UNITS).
+      44             : 
+      45             : If GROUPB is empty, it will sum the N*(N-1)/2 pairs in GROUPA. This avoids computing
+      46             : twice permuted indexes (e.g. pair (i,j) and (j,i)) thus running at twice the speed.
+      47             : 
+      48             : Notice that if there are common atoms between GROUPA and GROUPB their interaction is discarded.
+      49             : 
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : \plumedfile
+      54             : # this is printing the electrostatic interaction between two groups of atoms
+      55             : dh: DHENERGY GROUPA=1-10 GROUPB=11-20 EPSILON=80.0 I=0.1 TEMP=300.0
+      56             : PRINT ARG=dh
+      57             : \endplumedfile
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : class DHEnergy : public CoordinationBase {
+      63             :   double k; // Inverse Debye screening length
+      64             :   double constant;
+      65             :   double epsilon;
+      66             : 
+      67             : public:
+      68             :   explicit DHEnergy(const ActionOptions&);
+      69             : // active methods:
+      70             :   static void registerKeywords( Keywords& keys );
+      71             :   double pairing(double distance,double&dfunc,unsigned i,unsigned j)const override;
+      72             : };
+      73             : 
+      74             : PLUMED_REGISTER_ACTION(DHEnergy,"DHENERGY")
+      75             : 
+      76          10 : void DHEnergy::registerKeywords( Keywords& keys ) {
+      77          10 :   CoordinationBase::registerKeywords(keys);
+      78          20 :   keys.add("compulsory","I","1.0","Ionic strength (M)");
+      79          20 :   keys.add("compulsory","TEMP","300.0","Simulation temperature (K)");
+      80          20 :   keys.add("compulsory","EPSILON","80.0","Dielectric constant of solvent");
+      81          10 : }
+      82             : 
+      83             : /*
+      84             : Global constants in SI unit used in this calculation:
+      85             :       N_A = 6.0221412927 * 10^(23) mol^(-1) : Avogadro number
+      86             :       q = 1.60217656535 * 10^(-19) C : proton charge
+      87             :       e_0 = 8.854187817620 * 10^(-12) C^2/(N*m^2) : vacuum's dielectric constant
+      88             :       k_B = 1.380648813 * 10^(-23) N*m/K : Boltzmann constant
+      89             : In SI unit, Debye Huckel CV is defined as:
+      90             :       DHen = \sum_i\sum_j (q_i*q_j*q^2*N_A)/(4*pi*eps*e_0) * exp(-k*|f_ij|)/(|f_ij|)
+      91             :              + \sum_i\sum_j (q_i*q_j*q^2*N_A)/(4*pi*epp*e_0) * (1/|r_ij| - 1/|f_ij|)
+      92             :            = (q^2*N_A)/(4*pi*e_0) * \sum_i\sum_j q_i*q_j * (exp(-k*|f_ij|)/(eps*|f_ij|) + 1/epp*(1/|r_ij| - 1/|f_ij|))
+      93             : (in which |f_ij| = \sqrt(|r_ij|^2+\sigma_i*\sigma_j*exp(-|r_ij|^2/4*\sigma_i*\sigma_j)),
+      94             :  \sigma_i and \sigma_j are the effective Born radius.)
+      95             : For an efficient calculation, we group constants and variables into groups:
+      96             :       constant = (q^2*N_A)/(4*pi*e_0)
+      97             :       tmp = 1/eps*exp(-k*|f_ij|)/(|f_ij|) + 1/epp*(1/|r_ij| - 1/|f_ij|)
+      98             : 
+      99             : To speed up the loop calculation, constant can be modified as followed:
+     100             :       constant= (q^2*N_A)/(4*pi*e_0*10^(-9))*10^(-3) (kJ/mol)
+     101             :               = ((1.60217656535*10^(-19))^2*6.0221412927*10^(23)*10^(-3))/(4*3.14159265*8.854187817620*10^(-12)*10^(-9))
+     102             :               = 138.935458111 (kJ/mol)
+     103             : 
+     104             : */
+     105             : 
+     106           8 : DHEnergy::DHEnergy(const ActionOptions&ao):
+     107             :   Action(ao),
+     108             :   CoordinationBase(ao),
+     109           8 :   k(0.0),
+     110           8 :   constant(0.0)
+     111             : {
+     112             :   double I,T;
+     113           8 :   parse("I",I);
+     114           8 :   parse("TEMP",T);
+     115           8 :   parse("EPSILON",epsilon);
+     116           8 :   checkRead();
+     117           8 :   if( usingNaturalUnits() ) error("DHENERGY cannot be used for calculations performed with natural units");
+     118           8 :   constant=138.935458111/getUnits().getEnergy()/getUnits().getLength()*getUnits().getCharge()*getUnits().getCharge();
+     119           8 :   k=std::sqrt(I/(epsilon*T))*502.903741125*getUnits().getLength();
+     120           8 :   checkRead();
+     121           8 :   log<<"  with solvent dielectric constant "<<epsilon<<"\n";
+     122           8 :   log<<"  at temperature "<<T<<" K\n";
+     123           8 :   log<<"  at ionic strength "<<I<< "M\n";
+     124           8 :   log<<"  these parameters correspond to a screening length of "<<(1.0/k)<<"\n";
+     125          16 :   log<<"  Bibliography "<<plumed.cite("Do, Carloni, Varani and Bussi, J. Chem. Theory Comput. 9, 1720 (2013)")<<" \n";
+     126           8 : }
+     127             : 
+     128         840 : double DHEnergy::pairing(double distance2,double&dfunc,unsigned i,unsigned j)const {
+     129         840 :   double distance=std::sqrt(distance2);
+     130         840 :   if(getAbsoluteIndex(i)==getAbsoluteIndex(j)) {
+     131           0 :     dfunc=0.0;
+     132           0 :     return 0.0;
+     133             :   }
+     134         840 :   double invdistance=1.0/distance;
+     135         840 :   double tmp=std::exp(-k*distance)*invdistance*constant*getCharge(i)*getCharge(j)/epsilon;
+     136         840 :   double dtmp=-(k+invdistance)*tmp;
+     137         840 :   dfunc=dtmp*invdistance;
+     138         840 :   return tmp;
+     139             : }
+     140             : 
+     141             : }
+     142             : 
+     143             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DRMSD.cpp.func-sort-c.html b/coverage/colvar/DRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..eaf298ce3375 --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/DRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4343100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5DRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5DRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD6colvar5DRMSD16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6colvar5DRMSD9calculateEv595
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DRMSD.cpp.func.html b/coverage/colvar/DRMSD.cpp.func.html new file mode 100644 index 000000000000..31b895d404c2 --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/DRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4343100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5DRMSD16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6colvar5DRMSD9calculateEv595
_ZN4PLMD6colvar5DRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD6colvar5DRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/DRMSD.cpp.gcov.html b/coverage/colvar/DRMSD.cpp.gcov.html new file mode 100644 index 000000000000..6c0a23528c09 --- /dev/null +++ b/coverage/colvar/DRMSD.cpp.gcov.html @@ -0,0 +1,269 @@ + + + + + + + + LCOV - plumed test coverage - colvar/DRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - DRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4343100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/PDB.h"
+      26             : #include "reference/DRMSD.h"
+      27             : #include "reference/MetricRegister.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace colvar {
+      31             : 
+      32             : //+PLUMEDOC DCOLVAR DRMSD
+      33             : /*
+      34             : Calculate the distance RMSD with respect to a reference structure.
+      35             : 
+      36             : To calculate the root-mean-square deviation between the atoms in two configurations
+      37             : you must first superimpose the two structures in some ways.  Obviously, it is the internal vibrational
+      38             : motions of the structure - i.e. not the translations and rotations - that are interesting. However,
+      39             : aligning two structures by removing the translational and rotational motions is not easy.  Furthermore,
+      40             : in some cases there can be alignment issues caused by so-called frame-fitting problems. It is thus
+      41             : often cheaper and easier to calculate the distances between all the pairs of atoms.  The distance
+      42             : between the two structures, \f$\mathbf{X}^a\f$ and \f$\mathbf{X}^b\f$ can then be measured as:
+      43             : 
+      44             : \f[
+      45             : d(\mathbf{X}^A, \mathbf{X}^B) = \sqrt{\frac{1}{N(N-1)} \sum_{i \ne j} [ d(\mathbf{x}_i^a,\mathbf{x}_j^a) - d(\mathbf{x}_i^b,\mathbf{x}_j^b) ]^2}
+      46             : \f]
+      47             : 
+      48             : where \f$N\f$ is the number of atoms and \f$d(\mathbf{x}_i,\mathbf{x}_j)\f$ represents the distance between
+      49             : atoms \f$i\f$ and \f$j\f$.  Clearly, this representation of the configuration is invariant to translation and rotation.
+      50             : However, it can become expensive to calculate when the number of atoms is large.  This can be resolved
+      51             : within the DRMSD colvar by setting LOWER_CUTOFF and UPPER_CUTOFF.  These keywords ensure that only
+      52             : pairs of atoms that are within a certain range are incorporated into the above sum.
+      53             : 
+      54             : In PDB files the atomic coordinates and box lengths should be in Angstroms unless
+      55             : you are working with natural units.  If you are working with natural units then the coordinates
+      56             : should be in your natural length unit.  For more details on the PDB file format visit http://www.wwpdb.org/docs.html
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : The following tells plumed to calculate the distance RMSD between
+      61             : the positions of the atoms in the reference file and their instantaneous
+      62             : position. Only pairs of atoms whose distance in the reference structure is within
+      63             : 0.1 and 0.8 nm are considered.
+      64             : 
+      65             : \plumedfile
+      66             : DRMSD REFERENCE=file1.pdb LOWER_CUTOFF=0.1 UPPER_CUTOFF=0.8
+      67             : \endplumedfile
+      68             : 
+      69             : The reference file is a PDB file that looks like this
+      70             : 
+      71             : \auxfile{file1.pdb}
+      72             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      73             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      74             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      75             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      76             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      77             : END
+      78             : \endauxfile
+      79             : 
+      80             : The following tells plumed to calculate a DRMSD value for a pair of molecules.
+      81             : 
+      82             : \plumedfile
+      83             : DRMSD REFERENCE=file2.pdb LOWER_CUTOFF=0.1 UPPER_CUTOFF=0.8 TYPE=INTER-DRMSD
+      84             : \endplumedfile
+      85             : 
+      86             : In the input reference file (file.pdb) the atoms in each of the two molecules are separated by a TER
+      87             : command as shown below.
+      88             : 
+      89             : \auxfile{file2.pdb}
+      90             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      91             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      92             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      93             : TER
+      94             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      95             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      96             : END
+      97             : \endauxfile
+      98             : 
+      99             : In this example the INTER-DRMSD type ensures that the set of distances from which the final
+     100             : quantity is computed involve one atom from each of the two molecules.  If this is replaced
+     101             : by INTRA-DRMSD then only those distances involving pairs of atoms that are both in the same
+     102             : molecule are computed.
+     103             : 
+     104             : */
+     105             : //+ENDPLUMEDOC
+     106             : 
+     107             : 
+     108             : class DRMSD : public Colvar {
+     109             : 
+     110             :   bool pbc_;
+     111             :   MultiValue myvals;
+     112             :   ReferenceValuePack mypack;
+     113             :   std::unique_ptr<PLMD::DRMSD> drmsd_;
+     114             : 
+     115             : public:
+     116             :   explicit DRMSD(const ActionOptions&);
+     117             :   void calculate() override;
+     118             :   static void registerKeywords(Keywords& keys);
+     119             : };
+     120             : 
+     121             : PLUMED_REGISTER_ACTION(DRMSD,"DRMSD")
+     122             : 
+     123          14 : void DRMSD::registerKeywords(Keywords& keys) {
+     124          14 :   Colvar::registerKeywords(keys);
+     125          28 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     126          28 :   keys.add("compulsory","LOWER_CUTOFF","only pairs of atoms further than LOWER_CUTOFF are considered in the calculation.");
+     127          28 :   keys.add("compulsory","UPPER_CUTOFF","only pairs of atoms closer than UPPER_CUTOFF are considered in the calculation.");
+     128          28 :   keys.add("compulsory","TYPE","DRMSD","what kind of DRMSD would you like to calculate.  You can use either the normal DRMSD involving all the distances between "
+     129             :            "the atoms in your molecule.  Alternatively, if you have multiple molecules you can use the type INTER-DRMSD "
+     130             :            "to compute DRMSD values involving only those distances between the atoms at least two molecules or the type INTRA-DRMSD "
+     131             :            "to compute DRMSD values involving only those distances between atoms in the same molecule");
+     132          14 : }
+     133             : 
+     134          12 : DRMSD::DRMSD(const ActionOptions&ao):
+     135          12 :   PLUMED_COLVAR_INIT(ao), pbc_(true), myvals(1,0), mypack(0,0,myvals)
+     136             : {
+     137             :   std::string reference;
+     138          12 :   parse("REFERENCE",reference);
+     139             :   double lcutoff;
+     140          12 :   parse("LOWER_CUTOFF",lcutoff);
+     141             :   double ucutoff;
+     142          12 :   parse("UPPER_CUTOFF",ucutoff);
+     143          12 :   bool nopbc(false);
+     144          12 :   parseFlag("NOPBC",nopbc);
+     145          12 :   pbc_=!nopbc;
+     146             : 
+     147          25 :   addValueWithDerivatives(); setNotPeriodic();
+     148             : 
+     149             :   // read everything in ang and transform to nm if we are not in natural units
+     150          12 :   PDB pdb;
+     151          12 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     152           1 :     error("missing input file " + reference );
+     153             : 
+     154             :   // store target_ distance
+     155          11 :   std::string type; parse("TYPE",type);
+     156          22 :   drmsd_=metricRegister().create<PLMD::DRMSD>( type );
+     157          11 :   drmsd_->setBoundsOnDistances( !nopbc, lcutoff, ucutoff );
+     158          11 :   drmsd_->read( pdb );
+     159          11 :   checkRead();
+     160             : 
+     161             :   std::vector<AtomNumber> atoms;
+     162          11 :   drmsd_->getAtomRequests( atoms );
+     163             : //   drmsd_->setNumberOfAtoms( atoms.size() );
+     164          11 :   requestAtoms( atoms );
+     165             : 
+     166             :   // Setup the derivative pack
+     167          11 :   myvals.resize( 1, 3*atoms.size()+9 ); mypack.resize( 0, atoms.size() );
+     168         129 :   for(unsigned i=0; i<atoms.size(); ++i) mypack.setAtomIndex( i, i );
+     169             : 
+     170          11 :   log.printf("  reference from file %s\n",reference.c_str());
+     171          11 :   log.printf("  which contains %d atoms\n",getNumberOfAtoms());
+     172          11 :   log.printf("  with indices : ");
+     173         129 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     174         118 :     if(i%25==0) log<<"\n";
+     175         118 :     log.printf("%d ",atoms[i].serial());
+     176             :   }
+     177          11 :   log.printf("\n");
+     178          28 : }
+     179             : 
+     180             : // calculator
+     181         595 : void DRMSD::calculate() {
+     182             : 
+     183         595 :   double drmsd; Tensor virial; mypack.clear();
+     184         595 :   drmsd=drmsd_->calculate(getPositions(), getPbc(), mypack, false);
+     185             : 
+     186         595 :   setValue(drmsd);
+     187        9285 :   for(unsigned i=0; i<getNumberOfAtoms(); ++i) { if( myvals.isActive(3*i) ) setAtomsDerivatives( i, mypack.getAtomDerivative(i) ); }
+     188         595 :   setBoxDerivatives( mypack.getBoxDerivatives() );
+     189         595 : }
+     190             : 
+     191             : }
+     192             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dimer.cpp.func-sort-c.html b/coverage/colvar/Dimer.cpp.func-sort-c.html new file mode 100644 index 000000000000..752bbe00b264 --- /dev/null +++ b/coverage/colvar/Dimer.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Dimer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dimer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:828992.1 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5DimerC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5Dimer16consistencyCheckEv2
_ZN4PLMD6colvar5DimerC1ERKNS_13ActionOptionsE2
_ZN4PLMD6colvar5Dimer16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar5Dimer9calculateEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dimer.cpp.func.html b/coverage/colvar/Dimer.cpp.func.html new file mode 100644 index 000000000000..3a6624bcc5b8 --- /dev/null +++ b/coverage/colvar/Dimer.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Dimer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dimer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:828992.1 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5Dimer16consistencyCheckEv2
_ZN4PLMD6colvar5Dimer16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar5Dimer9calculateEv4
_ZN4PLMD6colvar5DimerC1ERKNS_13ActionOptionsE2
_ZN4PLMD6colvar5DimerC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dimer.cpp.gcov.html b/coverage/colvar/Dimer.cpp.gcov.html new file mode 100644 index 000000000000..bf4b155d4d9f --- /dev/null +++ b/coverage/colvar/Dimer.cpp.gcov.html @@ -0,0 +1,395 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Dimer.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dimer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:828992.1 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Communicator.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace colvar {
+      29             : 
+      30             : //+PLUMEDOC COLVAR DIMER
+      31             : /*
+      32             : This CV computes the dimer interaction energy for a collection of dimers.
+      33             : 
+      34             : Each dimer represents an atom, as described in the dimer paper \cite dimer-metad.
+      35             : A system of N atoms is thus represented with N dimers, each
+      36             : Dimer being composed of two beads and eventually a virtual site representing its center of mass.
+      37             : 
+      38             : A typical configuration for a dimerized system has the following ordering of atoms:
+      39             : 
+      40             : 1    TAG1 X Y Z          N atoms representing the first bead of each Dimer
+      41             : 
+      42             : 2    TAG2 X Y Z
+      43             : 
+      44             : ...
+      45             : 
+      46             : N    TAGN X Y Z          N atoms representing the second bead of each Dimer
+      47             : 
+      48             : N+1  TAG1 X Y Z
+      49             : 
+      50             : N+2  TAG2 X Y Z
+      51             : 
+      52             : ...
+      53             : 
+      54             : 2N   TAGN X Y Z          Optional: N atoms representing the center of mass of each Dimer
+      55             : 
+      56             : 2N+1 TAG1 X Y Z
+      57             : 
+      58             : 2N+2 TAG2 X Y Z
+      59             : 
+      60             : ...
+      61             : 
+      62             : 3N   TAGN X Y Z          The configuration might go on with un-dimerized atoms (like a solvent)
+      63             : 
+      64             : 3N+1
+      65             : 
+      66             : 3N+2
+      67             : 
+      68             : ...
+      69             : 
+      70             : 
+      71             : The Dimer interaction energy is defined between atoms x and N+x, for x=1,...,N and is
+      72             : characterized by two parameters Q and DSIGMA. These are passed as mandatory arguments along with
+      73             : the temperature of the system.
+      74             : 
+      75             : \par Examples
+      76             : 
+      77             : This line tells Plumed to compute the Dimer interaction energy for every dimer in the system.
+      78             : 
+      79             : \plumedfile
+      80             : dim: DIMER TEMP=300 Q=0.5 ALLATOMS DSIGMA=0.002
+      81             : \endplumedfile
+      82             : 
+      83             : If the simulation doesn't use virtual sites for the dimers centers of mass,
+      84             : Plumed has to know in order to determine correctly the total number of dimers from
+      85             : the total number of atoms:
+      86             : \plumedfile
+      87             : dim: DIMER TEMP=300 Q=0.5 ALLATOMS DSIGMA=0.002 NOVSITES
+      88             : \endplumedfile
+      89             : 
+      90             : The NOVSITES flag is not required if one provides the atom serials of each Dimer. These are
+      91             : defined through two lists of atoms provided __instead__ of the ALLATOMS keyword.
+      92             : For example, the Dimer interaction energy of dimers specified by beads (1;23),(5;27),(7;29) is:
+      93             : \plumedfile
+      94             : dim: DIMER TEMP=300 Q=0.5 ATOMS1=1,5,7 ATOMS2=23,27,29 DSIGMA=0.002
+      95             : \endplumedfile
+      96             : 
+      97             : Note that the ATOMS1,ATOMS2 keywords can support atom groups and
+      98             : interval notation as defined in \ref GROUP.
+      99             : 
+     100             : 
+     101             : In a Replica Exchange simulation the keyword DSIGMA can be used in two ways:
+     102             : if a plumed.n.dat file is provided for each replica, then DSIGMA is passed as a single value,
+     103             : like in the previous examples, and each replica will read its own DSIGMA value. If
+     104             : a unique plumed.dat is given, DSIGMA has to be a list containing a value for each replica.
+     105             : For 4 replicas:
+     106             : \plumedfile
+     107             : #SETTINGS NREPLICAS=4
+     108             : dim: DIMER TEMP=300 Q=0.5 ATOMS1=1,5,7 ATOMS2=23,27,29 DSIGMA=0.002,0.002,0.004,0.01
+     109             : \endplumedfile
+     110             : 
+     111             : 
+     112             : \par Usage of the CV
+     113             : 
+     114             : The dimer interaction is not coded in the driver program and has to be inserted
+     115             : in the Hamiltonian of the system as a linear RESTRAINT (see \ref RESTRAINT):
+     116             : \plumedfile
+     117             : dim: DIMER TEMP=300 Q=0.5 ALLATOMS DSIGMA=0.002
+     118             : RESTRAINT ARG=dim AT=0 KAPPA=0 SLOPE=1 LABEL=dimforces
+     119             : \endplumedfile
+     120             : 
+     121             : In a replica exchange, Metadynamics (see \ref METAD) can be used on the Dimer CV to reduce
+     122             : the number of replicas. Just keep in mind that METAD SIGMA values should be tuned
+     123             : in the standard way for each replica according to the value of DSIGMA.
+     124             : */
+     125             : //+ENDPLUMEDOC
+     126             : 
+     127             : class Dimer : public Colvar {
+     128             : public:
+     129             :   static void registerKeywords( Keywords& keys);
+     130             :   explicit Dimer(const ActionOptions&);
+     131             :   void calculate() override;
+     132             : protected:
+     133             :   bool trimer,useall;
+     134             :   int myrank, nranks;
+     135             :   double qexp,temperature,beta,dsigma;
+     136             :   std::vector<double> dsigmas;
+     137             : private:
+     138             :   void consistencyCheck();
+     139             :   std::vector<AtomNumber> usedatoms1;
+     140             :   std::vector<AtomNumber> usedatoms2;
+     141             : 
+     142             : };
+     143             : 
+     144             : PLUMED_REGISTER_ACTION(Dimer, "DIMER")
+     145             : 
+     146             : 
+     147             : 
+     148           4 : void Dimer::registerKeywords( Keywords& keys) {
+     149           4 :   Colvar::registerKeywords(keys);
+     150             : 
+     151           8 :   keys.add("compulsory","DSIGMA","The interaction strength of the dimer bond.");
+     152           8 :   keys.add("compulsory", "Q", "The exponent of the dimer potential.");
+     153           8 :   keys.add("compulsory", "TEMP", "The temperature (in Kelvin) of the simulation.");
+     154           8 :   keys.add("atoms", "ATOMS1", "The list of atoms representing the first bead of each Dimer being considered by this CV. Used if ALLATOMS flag is missing");
+     155           8 :   keys.add("atoms", "ATOMS2", "The list of atoms representing the second bead of each Dimer being considered by this CV. Used if ALLATOMS flag is missing");
+     156           8 :   keys.addFlag("ALLATOMS", false, "Use EVERY atom of the system. Overrides ATOMS keyword.");
+     157           8 :   keys.addFlag("NOVSITES", false, "If present the configuration is without virtual sites at the centroid positions.");
+     158             : 
+     159           4 : }
+     160             : 
+     161             : 
+     162             : 
+     163           2 : Dimer::Dimer(const ActionOptions& ao):
+     164           2 :   PLUMED_COLVAR_INIT(ao)
+     165             : {
+     166             : 
+     167           4 :   log<<" Bibliography "<<plumed.cite("M Nava, F. Palazzesi, C. Perego and M. Parrinello, J. Chem. Theory Comput. 13, 425(2017)")<<"\n";
+     168           2 :   parseVector("DSIGMA",dsigmas);
+     169           2 :   parse("Q",qexp);
+     170           4 :   parse("TEMP",temperature);
+     171             : 
+     172             : 
+     173             :   std::vector<AtomNumber> atoms;
+     174           2 :   parseFlag("ALLATOMS",useall);
+     175           2 :   trimer=true;
+     176             :   bool notrim;
+     177           2 :   parseFlag("NOVSITES",notrim);
+     178           2 :   trimer=!notrim;
+     179             : 
+     180           2 :   nranks=multi_sim_comm.Get_size();
+     181           2 :   myrank=multi_sim_comm.Get_rank();
+     182           2 :   if(dsigmas.size()==1)
+     183           2 :     dsigma=dsigmas[0];
+     184             :   else
+     185           0 :     dsigma=dsigmas[myrank];
+     186             : 
+     187             : 
+     188             : 
+     189             : 
+     190           2 :   if(useall)
+     191             :   {
+     192             :     // go with every atom in the system but not the virtuals...
+     193             :     int natoms;
+     194           1 :     if(trimer)
+     195           1 :       natoms= 2*getTotAtoms()/3;
+     196             :     else
+     197           0 :       natoms=getTotAtoms()/2;
+     198             : 
+     199          45 :     for(unsigned int i=0; i<((unsigned int)natoms); i++)
+     200             :     {
+     201             :       AtomNumber ati;
+     202             :       ati.setIndex(i);
+     203          44 :       atoms.push_back(ati);
+     204             :     }
+     205             :   }
+     206             :   else  // serials for the first beads of each dimer are given
+     207             :   {
+     208           1 :     parseAtomList("ATOMS1",usedatoms1);
+     209           2 :     parseAtomList("ATOMS2",usedatoms2);
+     210             : 
+     211             :     int isz1 = usedatoms1.size();
+     212             : 
+     213           5 :     for(unsigned int i=0; i<isz1; i++)
+     214             :     {
+     215             :       AtomNumber ati;
+     216           4 :       ati.setIndex(usedatoms1[i].index());
+     217           4 :       atoms.push_back(ati);
+     218             :     }
+     219             : 
+     220             :     int isz2 = usedatoms2.size();
+     221           5 :     for(unsigned int i=0; i<isz2; i++)
+     222             :     {
+     223             :       AtomNumber atip2;
+     224           4 :       atip2.setIndex(usedatoms2[i].index());
+     225           4 :       atoms.push_back(atip2);
+     226             :     }
+     227             : 
+     228             :   }
+     229           2 :   consistencyCheck();
+     230           2 :   checkRead();
+     231           2 :   beta = 1./(kBoltzmann*temperature);
+     232             : 
+     233           2 :   addValueWithDerivatives();  // allocate
+     234           2 :   requestAtoms(atoms);
+     235           2 :   setNotPeriodic();
+     236           2 : }
+     237             : 
+     238           4 : void Dimer::calculate()
+     239             : {
+     240           4 :   double cv_val=0;
+     241           4 :   Tensor virial;
+     242             :   std::vector<Vector> derivatives;
+     243           4 :   std::vector<Vector> my_pos=getPositions();
+     244           4 :   int atms = my_pos.size();
+     245             :   std::vector<Vector> der_b2;
+     246          38 :   for(int i=0; i<atms/2; i++)
+     247             :   {
+     248          34 :     Vector dist;
+     249          34 :     dist = pbcDistance(my_pos[i],my_pos[i+atms/2]);
+     250             :     double distquad=0;
+     251         136 :     for(int j=0; j<3; j++)
+     252         102 :       distquad += dist[j]*dist[j];
+     253             : 
+     254          34 :     double dsigquad = dsigma*dsigma;
+     255          34 :     double fac1 = 1.0 + distquad/(2*qexp*dsigquad);
+     256          34 :     double fac1qm1 = std::pow(fac1,qexp-1);
+     257             : 
+     258             : 
+     259          34 :     cv_val += (fac1*fac1qm1-1.0)/beta;
+     260          34 :     Vector der_val;
+     261          34 :     Vector mder_val;
+     262         136 :     for(int j=0; j<3; j++)
+     263             :     {
+     264         102 :       der_val[j] = -fac1qm1*dist[j]/(dsigquad*beta);
+     265         102 :       mder_val[j]=-der_val[j];
+     266             :     }
+     267          34 :     derivatives.push_back(der_val);
+     268          34 :     der_b2.push_back(mder_val);
+     269             : 
+     270             :     // virial part: each dimer contributes -x_{ij}*ds/dx_{ij}  (s is the CV)
+     271          34 :     double dfunc = fac1qm1/(beta*dsigquad);
+     272          34 :     Vector dd(dfunc*dist);
+     273          34 :     Tensor vv(dd,dist);
+     274          34 :     virial -= vv;
+     275             : 
+     276             :   }
+     277             : 
+     278           4 :   derivatives.insert(derivatives.end(), der_b2.begin(), der_b2.end());
+     279             : 
+     280          72 :   for(unsigned int i=0; i<derivatives.size(); i++)
+     281          68 :     setAtomsDerivatives(i,derivatives[i]);
+     282             : 
+     283           4 :   setValue(cv_val);
+     284           4 :   setBoxDerivatives(virial);
+     285             : 
+     286           4 : }
+     287             : 
+     288             : 
+     289             : 
+     290             : /*****************
+     291             : There are some conditions that a valid input should satisfy.
+     292             : These are checked here and PLUMED error handlers are (eventually) called.
+     293             : ******************/
+     294           2 : void Dimer::consistencyCheck()
+     295             : {
+     296           2 :   if(!useall && usedatoms1.size()!=usedatoms2.size())
+     297           0 :     error("The provided atom lists are of different sizes.");
+     298             : 
+     299           2 :   if(qexp<0.5 || qexp>1)
+     300           0 :     warning("Dimer CV is meant to be used with q-exponents between 0.5 and 1. We are not responsible for any black hole. :-)");
+     301             : 
+     302           2 :   if(dsigma<0)
+     303           0 :     error("Please use positive sigma values for the Dimer strength constant");
+     304             : 
+     305           2 :   if(temperature<0)
+     306           0 :     error("Please, use a positive value for the temperature...");
+     307             : 
+     308             :   // if dsigmas has only one element means that either
+     309             :   // you are using different plumed.x.dat files or a plumed.dat with a single replica
+     310           2 :   if(dsigmas.size()!=nranks && dsigmas.size()!=1)
+     311           0 :     error("Mismatch between provided sigmas and number of replicas");
+     312             : 
+     313           2 : }
+     314             : 
+     315             : 
+     316             : }
+     317             : }
+     318             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dipole.cpp.func-sort-c.html b/coverage/colvar/Dipole.cpp.func-sort-c.html new file mode 100644 index 000000000000..504c2e99473f --- /dev/null +++ b/coverage/colvar/Dipole.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Dipole.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dipole.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6DipoleC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar6DipoleC1ERKNS_13ActionOptionsE54
_ZN4PLMD6colvar6Dipole16registerKeywordsERNS_8KeywordsE56
_ZN4PLMD6colvar6Dipole9calculateEv923
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dipole.cpp.func.html b/coverage/colvar/Dipole.cpp.func.html new file mode 100644 index 000000000000..984149b7ac9a --- /dev/null +++ b/coverage/colvar/Dipole.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Dipole.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dipole.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6Dipole16registerKeywordsERNS_8KeywordsE56
_ZN4PLMD6colvar6Dipole9calculateEv923
_ZN4PLMD6colvar6DipoleC1ERKNS_13ActionOptionsE54
_ZN4PLMD6colvar6DipoleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Dipole.cpp.gcov.html b/coverage/colvar/Dipole.cpp.gcov.html new file mode 100644 index 000000000000..54e6969f7f01 --- /dev/null +++ b/coverage/colvar/Dipole.cpp.gcov.html @@ -0,0 +1,235 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Dipole.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Dipole.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace colvar {
+      27             : 
+      28             : //+PLUMEDOC COLVAR DIPOLE
+      29             : /*
+      30             : Calculate the dipole moment for a group of atoms.
+      31             : 
+      32             : When running with periodic boundary conditions, the atoms should be
+      33             : in the proper periodic image. This is done automatically since PLUMED 2.5,
+      34             : by considering the ordered list of atoms and rebuilding the molecule with a procedure
+      35             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+      36             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+      37             : which actually modifies the coordinates stored in PLUMED.
+      38             : 
+      39             : In case you want to recover the old behavior you should use the NOPBC flag.
+      40             : In that case you need to take care that atoms are in the correct
+      41             : periodic image.
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : The following tells plumed to calculate the dipole of the group of atoms containing
+      46             : the atoms from 1-10 and print it every 5 steps
+      47             : \plumedfile
+      48             : d: DIPOLE GROUP=1-10
+      49             : PRINT FILE=output STRIDE=5 ARG=d
+      50             : \endplumedfile
+      51             : 
+      52             : \attention
+      53             : If the total charge Q of the group in non zero, then a charge Q/N will be subtracted to every atom,
+      54             : where N is the number of atoms. This implies that the dipole (which for a charged system depends
+      55             : on the position) is computed on the geometric center of the group.
+      56             : 
+      57             : 
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : class Dipole : public Colvar {
+      62             :   std::vector<AtomNumber> ga_lista;
+      63             :   bool components;
+      64             :   bool nopbc;
+      65             : public:
+      66             :   explicit Dipole(const ActionOptions&);
+      67             :   void calculate() override;
+      68             :   static void registerKeywords(Keywords& keys);
+      69             : };
+      70             : 
+      71             : PLUMED_REGISTER_ACTION(Dipole,"DIPOLE")
+      72             : 
+      73          56 : void Dipole::registerKeywords(Keywords& keys) {
+      74          56 :   Colvar::registerKeywords(keys);
+      75         112 :   keys.add("atoms","GROUP","the group of atoms we are calculating the dipole moment for");
+      76         112 :   keys.addFlag("COMPONENTS",false,"calculate the x, y and z components of the dipole separately and store them as label.x, label.y and label.z");
+      77         112 :   keys.addOutputComponent("x","COMPONENTS","the x-component of the dipole");
+      78         112 :   keys.addOutputComponent("y","COMPONENTS","the y-component of the dipole");
+      79         112 :   keys.addOutputComponent("z","COMPONENTS","the z-component of the dipole");
+      80          56 : }
+      81             : 
+      82          54 : Dipole::Dipole(const ActionOptions&ao):
+      83             :   PLUMED_COLVAR_INIT(ao),
+      84          54 :   components(false)
+      85             : {
+      86          54 :   parseAtomList("GROUP",ga_lista);
+      87          54 :   parseFlag("COMPONENTS",components);
+      88          54 :   parseFlag("NOPBC",nopbc);
+      89          54 :   checkRead();
+      90          54 :   if(components) {
+      91           6 :     addComponentWithDerivatives("x"); componentIsNotPeriodic("x");
+      92           6 :     addComponentWithDerivatives("y"); componentIsNotPeriodic("y");
+      93           6 :     addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+      94             :   } else {
+      95         104 :     addValueWithDerivatives(); setNotPeriodic();
+      96             :   }
+      97             : 
+      98          54 :   log.printf("  of %u atoms\n",static_cast<unsigned>(ga_lista.size()));
+      99         379 :   for(unsigned int i=0; i<ga_lista.size(); ++i) {
+     100         325 :     log.printf("  %d", ga_lista[i].serial());
+     101             :   }
+     102          54 :   log.printf("  \n");
+     103          54 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     104          16 :   else      log.printf("  using periodic boundary conditions\n");
+     105             : 
+     106          54 :   requestAtoms(ga_lista);
+     107          54 : }
+     108             : 
+     109             : // calculator
+     110         923 : void Dipole::calculate()
+     111             : {
+     112         923 :   if(!nopbc) makeWhole();
+     113             :   double ctot=0.;
+     114             :   unsigned N=getNumberOfAtoms();
+     115         923 :   std::vector<double> charges(N);
+     116         923 :   Vector dipje;
+     117             : 
+     118        7258 :   for(unsigned i=0; i<N; ++i) {
+     119        6335 :     charges[i]=getCharge(i);
+     120        6335 :     ctot+=charges[i];
+     121             :   }
+     122         923 :   ctot/=(double)N;
+     123             : 
+     124        7258 :   for(unsigned i=0; i<N; ++i) {
+     125        6335 :     charges[i]-=ctot;
+     126        6335 :     dipje += charges[i]*getPosition(i);
+     127             :   }
+     128             : 
+     129         923 :   if(!components) {
+     130         778 :     double dipole = dipje.modulo();
+     131         778 :     double idip = 1./dipole;
+     132             : 
+     133        6243 :     for(unsigned i=0; i<N; i++) {
+     134        5465 :       double dfunc=charges[i]*idip;
+     135        5465 :       setAtomsDerivatives(i,dfunc*dipje);
+     136             :     }
+     137         778 :     setBoxDerivativesNoPbc();
+     138         778 :     setValue(dipole);
+     139             :   } else {
+     140         145 :     Value* valuex=getPntrToComponent("x");
+     141         145 :     Value* valuey=getPntrToComponent("y");
+     142         145 :     Value* valuez=getPntrToComponent("z");
+     143        1015 :     for(unsigned i=0; i<N; i++) {
+     144         870 :       setAtomsDerivatives(valuex,i,charges[i]*Vector(1.0,0.0,0.0));
+     145         870 :       setAtomsDerivatives(valuey,i,charges[i]*Vector(0.0,1.0,0.0));
+     146         870 :       setAtomsDerivatives(valuez,i,charges[i]*Vector(0.0,0.0,1.0));
+     147             :     }
+     148         145 :     setBoxDerivativesNoPbc(valuex);
+     149         145 :     setBoxDerivativesNoPbc(valuey);
+     150         145 :     setBoxDerivativesNoPbc(valuez);
+     151         145 :     valuex->set(dipje[0]);
+     152         145 :     valuey->set(dipje[1]);
+     153         145 :     valuez->set(dipje[2]);
+     154             :   }
+     155         923 : }
+     156             : 
+     157             : }
+     158             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Distance.cpp.func-sort-c.html b/coverage/colvar/Distance.cpp.func-sort-c.html new file mode 100644 index 000000000000..047a75720ee2 --- /dev/null +++ b/coverage/colvar/Distance.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Distance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Distance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8DistanceC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8DistanceC1ERKNS_13ActionOptionsE466
_ZN4PLMD6colvar8Distance16registerKeywordsERNS_8KeywordsE468
_ZN4PLMD6colvar8Distance9calculateEv42384
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Distance.cpp.func.html b/coverage/colvar/Distance.cpp.func.html new file mode 100644 index 000000000000..904c6c6482b1 --- /dev/null +++ b/coverage/colvar/Distance.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Distance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Distance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8Distance16registerKeywordsERNS_8KeywordsE468
_ZN4PLMD6colvar8Distance9calculateEv42384
_ZN4PLMD6colvar8DistanceC1ERKNS_13ActionOptionsE466
_ZN4PLMD6colvar8DistanceC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Distance.cpp.gcov.html b/coverage/colvar/Distance.cpp.gcov.html new file mode 100644 index 000000000000..78d742c367db --- /dev/null +++ b/coverage/colvar/Distance.cpp.gcov.html @@ -0,0 +1,306 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Distance.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Distance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Pbc.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace colvar {
+      28             : 
+      29             : //+PLUMEDOC COLVAR DISTANCE
+      30             : /*
+      31             : Calculate the distance between a pair of atoms.
+      32             : 
+      33             : By default the distance is computed taking into account periodic
+      34             : boundary conditions. This behavior can be changed with the NOPBC flag.
+      35             : Moreover, single components in Cartesian space (x,y, and z, with COMPONENTS)
+      36             : or single components projected to the three lattice vectors (a,b, and c, with SCALED_COMPONENTS)
+      37             : can be also computed.
+      38             : 
+      39             : Notice that Cartesian components will not have the proper periodicity!
+      40             : If you have to study e.g. the permeation of a molecule across a membrane,
+      41             : better to use SCALED_COMPONENTS.
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : The following input tells plumed to print the distance between atoms 3 and 5,
+      46             : the distance between atoms 2 and 4 and the x component of the distance between atoms 2 and 4.
+      47             : \plumedfile
+      48             : d1:  DISTANCE ATOMS=3,5
+      49             : d2:  DISTANCE ATOMS=2,4
+      50             : d2c: DISTANCE ATOMS=2,4 COMPONENTS
+      51             : PRINT ARG=d1,d2,d2c.x
+      52             : \endplumedfile
+      53             : 
+      54             : The following input computes the end-to-end distance for a polymer
+      55             : of 100 atoms and keeps it at a value around 5.
+      56             : \plumedfile
+      57             : WHOLEMOLECULES ENTITY0=1-100
+      58             : e2e: DISTANCE ATOMS=1,100 NOPBC
+      59             : RESTRAINT ARG=e2e KAPPA=1 AT=5
+      60             : \endplumedfile
+      61             : 
+      62             : Notice that NOPBC is used
+      63             : to be sure that if the end-to-end distance is larger than half the simulation
+      64             : box the distance is compute properly. Also notice that, since many MD
+      65             : codes break molecules across cell boundary, it might be necessary to
+      66             : use the \ref WHOLEMOLECULES keyword (also notice that it should be
+      67             : _before_ distance). The list of atoms provided to \ref WHOLEMOLECULES
+      68             : here contains all the atoms between 1 and 100. Strictly speaking, this
+      69             : is not necessary. If you know for sure that atoms with difference in
+      70             : the index say equal to 10 are _not_ going to be farther than half cell
+      71             : you can e.g. use
+      72             : \plumedfile
+      73             : WHOLEMOLECULES ENTITY0=1,10,20,30,40,50,60,70,80,90,100
+      74             : e2e: DISTANCE ATOMS=1,100 NOPBC
+      75             : RESTRAINT ARG=e2e KAPPA=1 AT=5
+      76             : \endplumedfile
+      77             : Just be sure that the ordered list provide to \ref WHOLEMOLECULES has the following
+      78             : properties:
+      79             : - Consecutive atoms should be closer than half-cell throughout the entire simulation.
+      80             : - Atoms required later for the distance (e.g. 1 and 100) should be included in the list
+      81             : 
+      82             : The following example shows how to take into account periodicity e.g.
+      83             : in z-component of a distance
+      84             : \plumedfile
+      85             : # this is a center of mass of a large group
+      86             : c: COM ATOMS=1-100
+      87             : # this is the distance between atom 101 and the group
+      88             : d: DISTANCE ATOMS=c,101 COMPONENTS
+      89             : # this makes a new variable, dd, equal to d and periodic, with domain -10,10
+      90             : # this is the right choise if e.g. the cell is orthorombic and its size in
+      91             : # z direction is 20.
+      92             : dz: COMBINE ARG=d.z PERIODIC=-10,10
+      93             : # metadynamics on dd
+      94             : METAD ARG=dz SIGMA=0.1 HEIGHT=0.1 PACE=200
+      95             : \endplumedfile
+      96             : 
+      97             : Using SCALED_COMPONENTS this problem should not arise because they are always periodic
+      98             : with domain (-0.5,+0.5).
+      99             : 
+     100             : 
+     101             : 
+     102             : 
+     103             : */
+     104             : //+ENDPLUMEDOC
+     105             : 
+     106             : class Distance : public Colvar {
+     107             :   bool components;
+     108             :   bool scaled_components;
+     109             :   bool pbc;
+     110             : 
+     111             : public:
+     112             :   static void registerKeywords( Keywords& keys );
+     113             :   explicit Distance(const ActionOptions&);
+     114             : // active methods:
+     115             :   void calculate() override;
+     116             : };
+     117             : 
+     118             : PLUMED_REGISTER_ACTION(Distance,"DISTANCE")
+     119             : 
+     120         468 : void Distance::registerKeywords( Keywords& keys ) {
+     121         468 :   Colvar::registerKeywords( keys );
+     122         936 :   keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between");
+     123         936 :   keys.addFlag("COMPONENTS",false,"calculate the x, y and z components of the distance separately and store them as label.x, label.y and label.z");
+     124         936 :   keys.addFlag("SCALED_COMPONENTS",false,"calculate the a, b and c scaled components of the distance separately and store them as label.a, label.b and label.c");
+     125         936 :   keys.addOutputComponent("x","COMPONENTS","the x-component of the vector connecting the two atoms");
+     126         936 :   keys.addOutputComponent("y","COMPONENTS","the y-component of the vector connecting the two atoms");
+     127         936 :   keys.addOutputComponent("z","COMPONENTS","the z-component of the vector connecting the two atoms");
+     128         936 :   keys.addOutputComponent("a","SCALED_COMPONENTS","the normalized projection on the first lattice vector of the vector connecting the two atoms");
+     129         936 :   keys.addOutputComponent("b","SCALED_COMPONENTS","the normalized projection on the second lattice vector of the vector connecting the two atoms");
+     130         936 :   keys.addOutputComponent("c","SCALED_COMPONENTS","the normalized projection on the third lattice vector of the vector connecting the two atoms");
+     131         468 : }
+     132             : 
+     133         466 : Distance::Distance(const ActionOptions&ao):
+     134             :   PLUMED_COLVAR_INIT(ao),
+     135         466 :   components(false),
+     136         466 :   scaled_components(false),
+     137         466 :   pbc(true)
+     138             : {
+     139             :   std::vector<AtomNumber> atoms;
+     140         932 :   parseAtomList("ATOMS",atoms);
+     141         466 :   if(atoms.size()!=2)
+     142           1 :     error("Number of specified atoms should be 2");
+     143         465 :   parseFlag("COMPONENTS",components);
+     144         465 :   parseFlag("SCALED_COMPONENTS",scaled_components);
+     145         465 :   bool nopbc=!pbc;
+     146         465 :   parseFlag("NOPBC",nopbc);
+     147         465 :   pbc=!nopbc;
+     148         465 :   checkRead();
+     149             : 
+     150         465 :   log.printf("  between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
+     151         465 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     152           4 :   else    log.printf("  without periodic boundary conditions\n");
+     153             : 
+     154         465 :   if(components && scaled_components) error("COMPONENTS and SCALED_COMPONENTS are not compatible");
+     155             : 
+     156         464 :   if(components) {
+     157          93 :     addComponentWithDerivatives("x"); componentIsNotPeriodic("x");
+     158          93 :     addComponentWithDerivatives("y"); componentIsNotPeriodic("y");
+     159          62 :     addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+     160          31 :     log<<"  WARNING: components will not have the proper periodicity - see manual\n";
+     161         433 :   } else if(scaled_components) {
+     162           6 :     addComponentWithDerivatives("a"); componentIsPeriodic("a","-0.5","+0.5");
+     163           6 :     addComponentWithDerivatives("b"); componentIsPeriodic("b","-0.5","+0.5");
+     164           6 :     addComponentWithDerivatives("c"); componentIsPeriodic("c","-0.5","+0.5");
+     165             :   } else {
+     166         864 :     addValueWithDerivatives(); setNotPeriodic();
+     167             :   }
+     168             : 
+     169             : 
+     170         464 :   requestAtoms(atoms);
+     171         468 : }
+     172             : 
+     173             : 
+     174             : // calculator
+     175       42384 : void Distance::calculate() {
+     176             : 
+     177       42384 :   if(pbc) makeWhole();
+     178             : 
+     179       42384 :   Vector distance=delta(getPosition(0),getPosition(1));
+     180       42384 :   const double value=distance.modulo();
+     181       42384 :   const double invvalue=1.0/value;
+     182             : 
+     183       42384 :   if(components) {
+     184         394 :     Value* valuex=getPntrToComponent("x");
+     185         394 :     Value* valuey=getPntrToComponent("y");
+     186         394 :     Value* valuez=getPntrToComponent("z");
+     187             : 
+     188         394 :     setAtomsDerivatives (valuex,0,Vector(-1,0,0));
+     189         394 :     setAtomsDerivatives (valuex,1,Vector(+1,0,0));
+     190         394 :     setBoxDerivativesNoPbc(valuex);
+     191         394 :     valuex->set(distance[0]);
+     192             : 
+     193         394 :     setAtomsDerivatives (valuey,0,Vector(0,-1,0));
+     194         394 :     setAtomsDerivatives (valuey,1,Vector(0,+1,0));
+     195         394 :     setBoxDerivativesNoPbc(valuey);
+     196         394 :     valuey->set(distance[1]);
+     197             : 
+     198         394 :     setAtomsDerivatives (valuez,0,Vector(0,0,-1));
+     199         394 :     setAtomsDerivatives (valuez,1,Vector(0,0,+1));
+     200         394 :     setBoxDerivativesNoPbc(valuez);
+     201         394 :     valuez->set(distance[2]);
+     202       41990 :   } else if(scaled_components) {
+     203          11 :     Value* valuea=getPntrToComponent("a");
+     204          11 :     Value* valueb=getPntrToComponent("b");
+     205          22 :     Value* valuec=getPntrToComponent("c");
+     206          11 :     Vector d=getPbc().realToScaled(distance);
+     207          11 :     setAtomsDerivatives (valuea,0,matmul(getPbc().getInvBox(),Vector(-1,0,0)));
+     208          11 :     setAtomsDerivatives (valuea,1,matmul(getPbc().getInvBox(),Vector(+1,0,0)));
+     209          11 :     valuea->set(Tools::pbc(d[0]));
+     210          11 :     setAtomsDerivatives (valueb,0,matmul(getPbc().getInvBox(),Vector(0,-1,0)));
+     211          11 :     setAtomsDerivatives (valueb,1,matmul(getPbc().getInvBox(),Vector(0,+1,0)));
+     212          11 :     valueb->set(Tools::pbc(d[1]));
+     213          11 :     setAtomsDerivatives (valuec,0,matmul(getPbc().getInvBox(),Vector(0,0,-1)));
+     214          11 :     setAtomsDerivatives (valuec,1,matmul(getPbc().getInvBox(),Vector(0,0,+1)));
+     215          11 :     valuec->set(Tools::pbc(d[2]));
+     216             :   } else {
+     217       41979 :     setAtomsDerivatives(0,-invvalue*distance);
+     218       83958 :     setAtomsDerivatives(1,invvalue*distance);
+     219             :     setBoxDerivativesNoPbc();
+     220       41979 :     setValue           (value);
+     221             :   }
+     222             : 
+     223       42384 : }
+     224             : 
+     225             : }
+     226             : }
+     227             : 
+     228             : 
+     229             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/EEFSolv.cpp.func-sort-c.html b/coverage/colvar/EEFSolv.cpp.func-sort-c.html new file mode 100644 index 000000000000..81b05b451990 --- /dev/null +++ b/coverage/colvar/EEFSolv.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - colvar/EEFSolv.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - EEFSolv.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22924394.2 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7EEFSolvC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar7EEFSolv12setupTypeMapB5cxx11Ev5
_ZN4PLMD6colvar7EEFSolv13setupValueMapB5cxx11Ev5
_ZN4PLMD6colvar7EEFSolv14setupConstantsERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IdSaIdEESaIS9_EEb5
_ZN4PLMD6colvar7EEFSolvC1ERKNS_13ActionOptionsE5
_ZN4PLMD6colvar7EEFSolv16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6colvar7EEFSolv13update_neighbEv30
_ZN4PLMD6colvar7EEFSolv9calculateEv30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/EEFSolv.cpp.func.html b/coverage/colvar/EEFSolv.cpp.func.html new file mode 100644 index 000000000000..88bbda168c47 --- /dev/null +++ b/coverage/colvar/EEFSolv.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - colvar/EEFSolv.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - EEFSolv.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22924394.2 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7EEFSolv12setupTypeMapB5cxx11Ev5
_ZN4PLMD6colvar7EEFSolv13setupValueMapB5cxx11Ev5
_ZN4PLMD6colvar7EEFSolv13update_neighbEv30
_ZN4PLMD6colvar7EEFSolv14setupConstantsERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IdSaIdEESaIS9_EEb5
_ZN4PLMD6colvar7EEFSolv16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6colvar7EEFSolv9calculateEv30
_ZN4PLMD6colvar7EEFSolvC1ERKNS_13ActionOptionsE5
_ZN4PLMD6colvar7EEFSolvC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/EEFSolv.cpp.gcov.html b/coverage/colvar/EEFSolv.cpp.gcov.html new file mode 100644 index 000000000000..4abd62ed46cf --- /dev/null +++ b/coverage/colvar/EEFSolv.cpp.gcov.html @@ -0,0 +1,1254 @@ + + + + + + + + LCOV - plumed test coverage - colvar/EEFSolv.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - EEFSolv.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22924394.2 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /* This class was originally written by Thomas Loehr */
+      24             : 
+      25             : #include "Colvar.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/PlumedMain.h"
+      29             : #include "core/GenericMolInfo.h"
+      30             : #include "tools/Communicator.h"
+      31             : #include "tools/OpenMP.h"
+      32             : #include <initializer_list>
+      33             : 
+      34             : #define INV_PI_SQRT_PI 0.179587122
+      35             : #define KCAL_TO_KJ 4.184
+      36             : #define ANG_TO_NM 0.1
+      37             : #define ANG3_TO_NM3 0.001
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace colvar {
+      41             : 
+      42             : //+PLUMEDOC COLVAR EEFSOLV
+      43             : /*
+      44             : Calculates EEF1 solvation free energy for a group of atoms.
+      45             : 
+      46             : EEF1 is a solvent-accessible surface area based model, where the free energy of solvation is computed using a pairwise interaction term for non-hydrogen atoms:
+      47             : \f[
+      48             :     \Delta G^\mathrm{solv}_i = \Delta G^\mathrm{ref}_i - \sum_{j \neq i} f_i(r_{ij}) V_j
+      49             : \f]
+      50             : where \f$\Delta G^\mathrm{solv}_i\f$ is the free energy of solvation, \f$\Delta G^\mathrm{ref}_i\f$ is the reference solvation free energy, \f$V_j\f$ is the volume of atom \f$j\f$ and
+      51             : \f[
+      52             :     f_i(r) 4\pi r^2 = \frac{2}{\sqrt{\pi}} \frac{\Delta G^\mathrm{free}_i}{\lambda_i} \exp\left\{ - \frac{(r-R_i)^2}{\lambda^2_i}\right\}
+      53             : \f]
+      54             : where \f$\Delta G^\mathrm{free}_i\f$ is the solvation free energy of the isolated group, \f$\lambda_i\f$ is the correlation length equal to the width of the first solvation shell and \f$R_i\f$ is the van der Waals radius of atom \f$i\f$.
+      55             : 
+      56             : The output from this collective variable, the free energy of solvation, can be used with the \ref BIASVALUE keyword to provide implicit solvation to a system. All parameters are designed to be used with a modified CHARMM36 force field. It takes only non-hydrogen atoms as input, these can be conveniently specified using the \ref GROUP action with the NDX_GROUP parameter. To speed up the calculation, EEFSOLV internally uses a neighbor list with a cutoff dependent on the type of atom (maximum of 1.95 nm). This cutoff can be extended further by using the NL_BUFFER keyword.
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : \plumedfile
+      61             : #SETTINGS MOLFILE=regtest/basic/rt77/peptide.pdb
+      62             : MOLINFO MOLTYPE=protein STRUCTURE=peptide.pdb
+      63             : WHOLEMOLECULES ENTITY0=1-111
+      64             : 
+      65             : # This allows us to select only non-hydrogen atoms
+      66             : #SETTINGS AUXFILE=regtest/basic/rt77/index.ndx
+      67             : protein-h: GROUP NDX_FILE=index.ndx NDX_GROUP=Protein-H
+      68             : 
+      69             : # We extend the cutoff by 0.1 nm and update the neighbor list every 40 steps
+      70             : solv: EEFSOLV ATOMS=protein-h
+      71             : 
+      72             : # Here we actually add our calculated energy back to the potential
+      73             : bias: BIASVALUE ARG=solv
+      74             : 
+      75             : PRINT ARG=solv FILE=SOLV
+      76             : \endplumedfile
+      77             : 
+      78             : */
+      79             : //+ENDPLUMEDOC
+      80             : 
+      81             : class EEFSolv : public Colvar {
+      82             : private:
+      83             :   bool pbc;
+      84             :   bool serial;
+      85             :   double delta_g_ref;
+      86             :   double nl_buffer;
+      87             :   unsigned nl_stride;
+      88             :   unsigned nl_update;
+      89             :   std::vector<std::vector<unsigned> > nl;
+      90             :   std::vector<std::vector<bool> > nlexpo;
+      91             :   std::vector<std::vector<double> > parameter;
+      92             :   void setupConstants(const std::vector<AtomNumber> &atoms, std::vector<std::vector<double> > &parameter, bool tcorr);
+      93             :   std::map<std::string, std::map<std::string, std::string> > setupTypeMap();
+      94             :   std::map<std::string, std::vector<double> > setupValueMap();
+      95             :   void update_neighb();
+      96             : 
+      97             : public:
+      98             :   static void registerKeywords(Keywords& keys);
+      99             :   explicit EEFSolv(const ActionOptions&);
+     100             :   void calculate() override;
+     101             : };
+     102             : 
+     103             : PLUMED_REGISTER_ACTION(EEFSolv,"EEFSOLV")
+     104             : 
+     105           7 : void EEFSolv::registerKeywords(Keywords& keys) {
+     106           7 :   Colvar::registerKeywords(keys);
+     107          14 :   keys.add("atoms", "ATOMS", "The atoms to be included in the calculation, e.g. the whole protein.");
+     108          14 :   keys.add("compulsory", "NL_BUFFER", "0.1", "The buffer to the intrinsic cutoff used when calculating pairwise interactions.");
+     109          14 :   keys.add("compulsory", "NL_STRIDE", "40", "The frequency with which the neighbor list is updated.");
+     110          14 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     111          14 :   keys.addFlag("TEMP_CORRECTION", false, "Correct free energy of solvation constants for temperatures different from 298.15 K");
+     112           7 : }
+     113             : 
+     114           5 : EEFSolv::EEFSolv(const ActionOptions&ao):
+     115             :   PLUMED_COLVAR_INIT(ao),
+     116           5 :   pbc(true),
+     117           5 :   serial(false),
+     118           5 :   delta_g_ref(0.),
+     119           5 :   nl_buffer(0.1),
+     120           5 :   nl_stride(40),
+     121           5 :   nl_update(0)
+     122             : {
+     123             :   std::vector<AtomNumber> atoms;
+     124          10 :   parseAtomList("ATOMS", atoms);
+     125             :   const unsigned size = atoms.size();
+     126           5 :   bool tcorr = false;
+     127           5 :   parseFlag("TEMP_CORRECTION", tcorr);
+     128           5 :   parse("NL_BUFFER", nl_buffer);
+     129           5 :   parse("NL_STRIDE", nl_stride);
+     130             : 
+     131           5 :   bool nopbc = !pbc;
+     132           5 :   parseFlag("NOPBC", nopbc);
+     133           5 :   pbc = !nopbc;
+     134             : 
+     135           5 :   parseFlag("SERIAL",serial);
+     136             : 
+     137           5 :   checkRead();
+     138             : 
+     139          10 :   log << "  Bibliography " << plumed.cite("Lazaridis T, Karplus M, Proteins Struct. Funct. Genet. 35, 133 (1999)"); log << "\n";
+     140             : 
+     141           5 :   nl.resize(size);
+     142           5 :   nlexpo.resize(size);
+     143           5 :   parameter.resize(size, std::vector<double>(4, 0));
+     144           5 :   setupConstants(atoms, parameter, tcorr);
+     145             : 
+     146           5 :   addValueWithDerivatives();
+     147           5 :   setNotPeriodic();
+     148           5 :   requestAtoms(atoms);
+     149           5 : }
+     150             : 
+     151          30 : void EEFSolv::update_neighb() {
+     152             :   const double lower_c2 = 0.24 * 0.24; // this is the cut-off for bonded atoms
+     153             :   const unsigned size = getNumberOfAtoms();
+     154             : 
+     155        1830 :   for (unsigned i=0; i<size; i++) {
+     156        1800 :     nl[i].clear();
+     157             :     nlexpo[i].clear();
+     158        1800 :     const Vector posi = getPosition(i);
+     159             :     // Loop through neighboring atoms, add the ones below cutoff
+     160       54900 :     for (unsigned j=i+1; j<size; j++) {
+     161       53100 :       if(parameter[i][1]==0&&parameter[j][1]==0) continue;
+     162       51750 :       const double d2 = delta(posi, getPosition(j)).modulo2();
+     163       51750 :       if (d2 < lower_c2 && j < i+14) {
+     164             :         // crude approximation for i-i+1/2 interactions,
+     165             :         // we want to exclude atoms separated by less than three bonds
+     166        2695 :         continue;
+     167             :       }
+     168             :       // We choose the maximum lambda value and use a more conservative cutoff
+     169       49055 :       double mlambda = 1./parameter[i][2];
+     170       49055 :       if (1./parameter[j][2] > mlambda) mlambda = 1./parameter[j][2];
+     171       49055 :       const double c2 = (2. * mlambda + nl_buffer) * (2. * mlambda + nl_buffer);
+     172       49055 :       if (d2 < c2 ) {
+     173       26069 :         nl[i].push_back(j);
+     174       26069 :         if(parameter[i][2] == parameter[j][2] && parameter[i][3] == parameter[j][3]) {
+     175        5175 :           nlexpo[i].push_back(true);
+     176       20894 :         } else nlexpo[i].push_back(false);
+     177             :       }
+     178             :     }
+     179             :   }
+     180          30 : }
+     181             : 
+     182          30 : void EEFSolv::calculate() {
+     183          30 :   if(pbc) makeWhole();
+     184          30 :   if(getExchangeStep()) nl_update = 0;
+     185          30 :   if(nl_update==0) update_neighb();
+     186             : 
+     187             :   const unsigned size=getNumberOfAtoms();
+     188          30 :   double bias = 0.0;
+     189          30 :   std::vector<Vector> deriv(size, Vector(0,0,0));
+     190             : 
+     191             :   unsigned stride;
+     192             :   unsigned rank;
+     193          30 :   if(serial) {
+     194             :     stride=1;
+     195             :     rank=0;
+     196             :   } else {
+     197          30 :     stride=comm.Get_size();
+     198          30 :     rank=comm.Get_rank();
+     199             :   }
+     200             : 
+     201          30 :   unsigned nt=OpenMP::getNumThreads();
+     202          30 :   if(nt*stride*10>size) nt=1;
+     203             : 
+     204          30 :   #pragma omp parallel num_threads(nt)
+     205             :   {
+     206             :     std::vector<Vector> deriv_omp(size, Vector(0,0,0));
+     207             :     #pragma omp for reduction(+:bias) nowait
+     208             :     for (unsigned i=rank; i<size; i+=stride) {
+     209             :       const Vector posi = getPosition(i);
+     210             :       double fedensity = 0.0;
+     211             :       Vector deriv_i;
+     212             :       const double vdw_volume_i   = parameter[i][0];
+     213             :       const double delta_g_free_i = parameter[i][1];
+     214             :       const double inv_lambda_i   = parameter[i][2];
+     215             :       const double vdw_radius_i   = parameter[i][3];
+     216             : 
+     217             :       // The pairwise interactions are unsymmetric, but we can get away with calculating the distance only once
+     218             :       for (unsigned i_nl=0; i_nl<nl[i].size(); i_nl++) {
+     219             :         const unsigned j = nl[i][i_nl];
+     220             :         const double vdw_volume_j   = parameter[j][0];
+     221             :         const double delta_g_free_j = parameter[j][1];
+     222             :         const double inv_lambda_j   = parameter[j][2];
+     223             :         const double vdw_radius_j   = parameter[j][3];
+     224             : 
+     225             :         const Vector dist     = delta(posi, getPosition(j));
+     226             :         const double rij      = dist.modulo();
+     227             :         const double inv_rij  = 1.0 / rij;
+     228             :         const double inv_rij2 = inv_rij * inv_rij;
+     229             :         const double fact_ij  = inv_rij2 * delta_g_free_i * vdw_volume_j * INV_PI_SQRT_PI * inv_lambda_i;
+     230             :         const double fact_ji  = inv_rij2 * delta_g_free_j * vdw_volume_i * INV_PI_SQRT_PI * inv_lambda_j;
+     231             : 
+     232             :         // in this case we can calculate a single exponential
+     233             :         if(!nlexpo[i][i_nl]) {
+     234             :           // i-j interaction
+     235             :           if(inv_rij > 0.5*inv_lambda_i && delta_g_free_i!=0.)
+     236             :           {
+     237             :             const double e_arg = (rij - vdw_radius_i)*inv_lambda_i;
+     238             :             const double expo  = std::exp(-e_arg*e_arg);
+     239             :             const double fact  = expo*fact_ij;
+     240             :             const double e_deriv = inv_rij*fact*(inv_rij + e_arg*inv_lambda_i);
+     241             :             const Vector dd    = e_deriv*dist;
+     242             :             fedensity    += fact;
+     243             :             deriv_i      += dd;
+     244             :             if(nt>1) deriv_omp[j] -= dd;
+     245             :             else deriv[j] -= dd;
+     246             :           }
+     247             : 
+     248             :           // j-i interaction
+     249             :           if(inv_rij > 0.5*inv_lambda_j && delta_g_free_j!=0.)
+     250             :           {
+     251             :             const double e_arg = (rij - vdw_radius_j)*inv_lambda_j;
+     252             :             const double expo  = std::exp(-e_arg*e_arg);
+     253             :             const double fact  = expo*fact_ji;
+     254             :             const double e_deriv = inv_rij*fact*(inv_rij + e_arg*inv_lambda_j);
+     255             :             const Vector dd    = e_deriv*dist;
+     256             :             fedensity    += fact;
+     257             :             deriv_i      += dd;
+     258             :             if(nt>1) deriv_omp[j] -= dd;
+     259             :             else deriv[j] -= dd;
+     260             :           }
+     261             :         } else {
+     262             :           // i-j interaction
+     263             :           if(inv_rij > 0.5*inv_lambda_i)
+     264             :           {
+     265             :             const double e_arg = (rij - vdw_radius_i)*inv_lambda_i;
+     266             :             const double expo  = std::exp(-e_arg*e_arg);
+     267             :             const double fact  = expo*(fact_ij + fact_ji);
+     268             :             const double e_deriv = inv_rij*fact*(inv_rij + e_arg*inv_lambda_i);
+     269             :             const Vector dd    = e_deriv*dist;
+     270             :             fedensity    += fact;
+     271             :             deriv_i      += dd;
+     272             :             if(nt>1) deriv_omp[j] -= dd;
+     273             :             else deriv[j] -= dd;
+     274             :           }
+     275             :         }
+     276             : 
+     277             :       }
+     278             :       if(nt>1) deriv_omp[i] += deriv_i;
+     279             :       else deriv[i] += deriv_i;
+     280             :       bias += 0.5*fedensity;
+     281             :     }
+     282             :     #pragma omp critical
+     283             :     if(nt>1) for(unsigned i=0; i<size; i++) deriv[i]+=deriv_omp[i];
+     284             :   }
+     285             : 
+     286          30 :   if(!serial) {
+     287          30 :     comm.Sum(bias);
+     288          30 :     if(!deriv.empty()) comm.Sum(&deriv[0][0],3*deriv.size());
+     289             :   }
+     290             : 
+     291          30 :   Tensor virial;
+     292        1830 :   for(unsigned i=0; i<size; i++) {
+     293        1800 :     setAtomsDerivatives(i, -deriv[i]);
+     294        1800 :     virial += Tensor(getPosition(i), -deriv[i]);
+     295             :   }
+     296          30 :   setBoxDerivatives(-virial);
+     297          30 :   setValue(delta_g_ref - bias);
+     298             : 
+     299             :   // Keep track of the neighbourlist updates
+     300          30 :   nl_update++;
+     301          30 :   if (nl_update == nl_stride) {
+     302          30 :     nl_update = 0;
+     303             :   }
+     304          30 : }
+     305             : 
+     306           5 : void EEFSolv::setupConstants(const std::vector<AtomNumber> &atoms, std::vector<std::vector<double> > &parameter, bool tcorr) {
+     307             :   std::vector<std::vector<double> > parameter_temp;
+     308          10 :   parameter_temp.resize(atoms.size(), std::vector<double>(7,0));
+     309             :   std::map<std::string, std::vector<double> > valuemap;
+     310             :   std::map<std::string, std::map<std::string, std::string> > typemap;
+     311           5 :   valuemap = setupValueMap();
+     312           5 :   typemap  = setupTypeMap();
+     313           5 :   auto * moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     314             :   bool cter=false;
+     315           5 :   if (moldat) {
+     316           5 :     log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+     317         305 :     for(unsigned i=0; i<atoms.size(); ++i) {
+     318             : 
+     319             :       // Get atom and residue names
+     320         300 :       std::string Aname = moldat->getAtomName(atoms[i]);
+     321         300 :       std::string Rname = moldat->getResidueName(atoms[i]);
+     322         300 :       std::string Atype = typemap[Rname][Aname];
+     323             : 
+     324             :       // Check for terminal COOH or COO- (different atomtypes & parameters!)
+     325         598 :       if (Aname == "OT1" || Aname == "OXT") {
+     326             :         // We create a temporary AtomNumber object to access future atoms
+     327             :         unsigned ai = atoms[i].index();
+     328             :         AtomNumber tmp_an;
+     329           2 :         tmp_an.setIndex(ai + 2);
+     330           2 :         if (moldat->checkForAtom(tmp_an) && moldat->getAtomName(tmp_an) == "HT2") {
+     331             :           // COOH
+     332             :           Atype = "OB";
+     333             :         } else {
+     334             :           // COO-
+     335             :           Atype = "OC";
+     336             :         }
+     337             :         cter = true;
+     338             :       }
+     339         302 :       if (Aname == "OT2" || (cter == true && Aname == "O")) {
+     340             :         unsigned ai = atoms[i].index();
+     341             :         AtomNumber tmp_an;
+     342           2 :         tmp_an.setIndex(ai + 1);
+     343           2 :         if (moldat->checkForAtom(tmp_an) && moldat->getAtomName(tmp_an) == "HT2") {
+     344             :           // COOH
+     345             :           Atype = "OH1";
+     346             :         } else {
+     347             :           // COO-
+     348             :           Atype = "OC";
+     349             :         }
+     350             :       }
+     351             : 
+     352             :       // Check for H-atoms
+     353             :       char type;
+     354         300 :       char first = Aname.at(0);
+     355             : 
+     356             :       // GOLDEN RULE: type is first letter, if not a number
+     357         300 :       if (!isdigit(first)) {
+     358             :         type = first;
+     359             :         // otherwise is the second
+     360             :       } else {
+     361           0 :         type = Aname.at(1);
+     362             :       }
+     363             : 
+     364         300 :       if (type == 'H') {
+     365           0 :         error("EEF1-SB does not allow the use of hydrogen atoms!\n");
+     366             :       }
+     367             : 
+     368             :       // Lookup atomtype in table or throw exception if its not there
+     369             :       try {
+     370         300 :         parameter_temp[i] = valuemap.at(Atype);
+     371           0 :       } catch (const std::exception &e) {
+     372           0 :         log << "Type: " << Atype << "  Name: " << Aname << "  Residue: " << Rname << "\n";
+     373           0 :         error("Invalid atom type!\n");
+     374           0 :       }
+     375             : 
+     376             :       // Temperature correction
+     377         300 :       if (tcorr && parameter[i][1] > 0.0) {
+     378             :         const double t0 = 298.15;
+     379           0 :         const double delta_g_ref_t0 = parameter_temp[i][1];
+     380           0 :         const double delta_h_ref_t0 = parameter_temp[i][3];
+     381           0 :         const double delta_cp = parameter_temp[i][4];
+     382           0 :         const double delta_s_ref_t0 = (delta_h_ref_t0 - delta_g_ref_t0) / t0;
+     383           0 :         const double t = getkBT() / getKBoltzmann();
+     384           0 :         parameter_temp[i][1] -= delta_s_ref_t0 * (t - t0) - delta_cp * t * std::log(t / t0) + delta_cp * (t - t0);
+     385           0 :         parameter_temp[i][2] *= parameter_temp[i][1] / delta_g_ref_t0;
+     386             :       }
+     387         300 :       parameter[i][0] = parameter_temp[i][0];
+     388         300 :       parameter[i][1] = parameter_temp[i][2];
+     389         300 :       parameter[i][2] = parameter_temp[i][5];
+     390         300 :       parameter[i][3] = parameter_temp[i][6];
+     391             :     }
+     392             :   } else {
+     393           0 :     error("MOLINFO DATA not found\n");
+     394             :   }
+     395         305 :   for(unsigned i=0; i<atoms.size(); ++i) delta_g_ref += parameter_temp[i][1];
+     396           5 : }
+     397             : 
+     398           5 : std::map<std::string, std::map<std::string, std::string> > EEFSolv::setupTypeMap()  {
+     399             :   std::map<std::string, std::map<std::string, std::string> > typemap;
+     400          10 :   typemap["ACE"] = {
+     401             :     {"CH3", "CT3"},
+     402             :     {"HH31","HA3"},
+     403             :     {"HH32","HA3"},
+     404             :     {"HH33","HA3"},
+     405             :     {"C",   "C"  },
+     406             :     {"O",   "O"  }
+     407          40 :   };
+     408          10 :   typemap["ALA"] = {
+     409             :     {"N",   "NH1"},
+     410             :     {"HN",  "H"  },
+     411             :     {"CA",  "CT1"},
+     412             :     {"HA",  "HB1"},
+     413             :     {"CB",  "CT3"},
+     414             :     {"HB1", "HA3"},
+     415             :     {"HB2", "HA3"},
+     416             :     {"HB3", "HA3"},
+     417             :     {"C",   "C"  },
+     418             :     {"O",   "O"  }
+     419          60 :   };
+     420          10 :   typemap["ARG"] = {
+     421             :     {"N",    "NH1"},
+     422             :     {"HN",   "H"  },
+     423             :     {"CA",   "CT1"},
+     424             :     {"HA",   "HB1"},
+     425             :     {"CB",   "CT2"},
+     426             :     {"HB1",  "HA2"},
+     427             :     {"HB2",  "HA2"},
+     428             :     {"CG",   "CT2"},
+     429             :     {"HG1",  "HA2"},
+     430             :     {"HG2",  "HA2"},
+     431             :     {"CD",   "CT2"},
+     432             :     {"HD1",  "HA2"},
+     433             :     {"HD2",  "HA2"},
+     434             :     {"NE",   "NC2"},
+     435             :     {"HE",   "HC" },
+     436             :     {"CZ",   "C"  },
+     437             :     {"NH1",  "NC2"},
+     438             :     {"HH11", "HC" },
+     439             :     {"HH12", "HC" },
+     440             :     {"NH2",  "NC2"},
+     441             :     {"HH21", "HC" },
+     442             :     {"HH22", "HC" },
+     443             :     {"C",    "C"  },
+     444             :     {"O",    "O"  }
+     445         130 :   };
+     446          10 :   typemap["ASN"] = {
+     447             :     {"N",    "NH1"},
+     448             :     {"HN",   "H"  },
+     449             :     {"CA",   "CT1"},
+     450             :     {"HA",   "HB1"},
+     451             :     {"CB",   "CT2"},
+     452             :     {"HB1",  "HA2"},
+     453             :     {"HB2",  "HA2"},
+     454             :     {"CG",   "CC" },
+     455             :     {"OD1",  "O"  },
+     456             :     {"ND2",  "NH2"},
+     457             :     {"HD21", "H"  },
+     458             :     {"HD22", "H"  },
+     459             :     {"C",    "C"  },
+     460             :     {"O",    "O"  }
+     461          80 :   };
+     462          10 :   typemap["ASPP"] = {
+     463             :     {"N",   "NH1"},
+     464             :     {"HN",  "H"  },
+     465             :     {"CA",  "CT1"},
+     466             :     {"HA",  "HB1"},
+     467             :     {"CB",  "CT2"},
+     468             :     {"HB1", "HA2"},
+     469             :     {"HB2", "HA2"},
+     470             :     {"CG",  "CD" },
+     471             :     {"OD1", "OB" },
+     472             :     {"OD2", "OH1"},
+     473             :     {"HD2", "H"  },
+     474             :     {"C",   "C"  },
+     475             :     {"O",   "O"  }
+     476          75 :   };
+     477          10 :   typemap["ASP"] = {
+     478             :     {"N",   "NH1"},
+     479             :     {"HN",  "H"  },
+     480             :     {"CA",  "CT1"},
+     481             :     {"HA",  "HB1"},
+     482             :     {"CB",  "CT2"},
+     483             :     {"HB1", "HA2"},
+     484             :     {"HB2", "HA2"},
+     485             :     {"CG",  "CC" },
+     486             :     {"OD1", "OC" },
+     487             :     {"OD2", "OC" },
+     488             :     {"C",   "C"  },
+     489             :     {"O",   "O"  }
+     490          70 :   };
+     491          10 :   typemap["CYS"] = {
+     492             :     {"N",   "NH1"},
+     493             :     {"HN",  "H"  },
+     494             :     {"CA",  "CT1"},
+     495             :     {"HA",  "HB1"},
+     496             :     {"CB",  "CT2"},
+     497             :     {"HB1", "HA2"},
+     498             :     {"HB2", "HA2"},
+     499             :     {"SG",  "S"  },
+     500             :     {"HG1", "HS" },
+     501             :     {"C",   "C"  },
+     502             :     {"O",   "O"  }
+     503          65 :   };
+     504          10 :   typemap["GLN"] = {
+     505             :     {"N",    "NH1" },
+     506             :     {"HN",   "H"   },
+     507             :     {"CA",   "CT1" },
+     508             :     {"HA",   "HB1" },
+     509             :     {"CB",   "CT2" },
+     510             :     {"HB1",  "HA2" },
+     511             :     {"HB2",  "HA2" },
+     512             :     {"CG",   "CT2" },
+     513             :     {"HG1",  "HA2" },
+     514             :     {"HG2",  "HA2" },
+     515             :     {"CD",   "CC"  },
+     516             :     {"OE1",  "O"   },
+     517             :     {"NE2",  "NH2" },
+     518             :     {"HE21", "H"   },
+     519             :     {"HE22", "H"   },
+     520             :     {"C",    "C"   },
+     521             :     {"O",    "O"   }
+     522          95 :   };
+     523          10 :   typemap["GLUP"] = {
+     524             :     {"N",   "NH1"},
+     525             :     {"HN",  "H"  },
+     526             :     {"CA",  "CT1"},
+     527             :     {"HA",  "HB1"},
+     528             :     {"CB",  "CT2"},
+     529             :     {"HB1", "HA2"},
+     530             :     {"HB2", "HA2"},
+     531             :     {"CG",  "CT2"},
+     532             :     {"HG1", "HA2"},
+     533             :     {"HG2", "HA2"},
+     534             :     {"CD",  "CD" },
+     535             :     {"OE1", "OB" },
+     536             :     {"OE2", "OH1"},
+     537             :     {"HE2", "H"  },
+     538             :     {"C",   "C"  },
+     539             :     {"O",   "O"  }
+     540          90 :   };
+     541          10 :   typemap["GLU"] = {
+     542             :     {"N",   "NH1"},
+     543             :     {"HN",  "H"  },
+     544             :     {"CA",  "CT1"},
+     545             :     {"HA",  "HB1"},
+     546             :     {"CB",  "CT2"},
+     547             :     {"HB1", "HA2"},
+     548             :     {"HB2", "HA2"},
+     549             :     {"CG",  "CT2"},
+     550             :     {"HG1", "HA2"},
+     551             :     {"HG2", "HA2"},
+     552             :     {"CD",  "CC" },
+     553             :     {"OE1", "OC" },
+     554             :     {"OE2", "OC" },
+     555             :     {"C",   "C"  },
+     556             :     {"O",   "O"  }
+     557          85 :   };
+     558          10 :   typemap["GLY"] = {
+     559             :     {"N",   "NH1"},
+     560             :     {"HN",  "H"  },
+     561             :     {"CA",  "CT2"},
+     562             :     {"HA1", "HB2"},
+     563             :     {"HA2", "HB2"},
+     564             :     {"C",   "C"  },
+     565             :     {"O",   "O"  }
+     566          45 :   };
+     567          10 :   typemap["HSD"] = {
+     568             :     {"N",   "NH1"},
+     569             :     {"HN",  "H"  },
+     570             :     {"CA",  "CT1"},
+     571             :     {"HA",  "HB1"},
+     572             :     {"CB",  "CT2"},
+     573             :     {"HB1", "HA2"},
+     574             :     {"HB2", "HA2"},
+     575             :     {"ND1", "NR1"},
+     576             :     {"HD1", "H"  },
+     577             :     {"CG",  "CPH1"},
+     578             :     {"CE1", "CPH2"},
+     579             :     {"HE1", "HR1"},
+     580             :     {"NE2", "NR2"},
+     581             :     {"CD2", "CPH1"},
+     582             :     {"HD2", "HR3"},
+     583             :     {"C",   "C"  },
+     584             :     {"O",   "O"  }
+     585          95 :   };
+     586          10 :   typemap["HIS"] = {
+     587             :     {"N",   "NH1"},
+     588             :     {"HN",  "H"  },
+     589             :     {"CA",  "CT1"},
+     590             :     {"HA",  "HB1"},
+     591             :     {"CB",  "CT2"},
+     592             :     {"HB1", "HA2"},
+     593             :     {"HB2", "HA2"},
+     594             :     {"ND1", "NR2"},
+     595             :     {"CG",  "CPH1"},
+     596             :     {"CE1", "CPH2"},
+     597             :     {"HE1", "HR1"},
+     598             :     {"NE2", "NR1"},
+     599             :     {"HE2", "H"  },
+     600             :     {"CD2", "CPH1"},
+     601             :     {"HD2", "HR3"},
+     602             :     {"C",   "C"  },
+     603             :     {"O",   "O"  }
+     604          95 :   };
+     605          10 :   typemap["HSE"] = {
+     606             :     {"N",   "NH1"},
+     607             :     {"HN",  "H"  },
+     608             :     {"CA",  "CT1"},
+     609             :     {"HA",  "HB1"},
+     610             :     {"CB",  "CT2"},
+     611             :     {"HB1", "HA2"},
+     612             :     {"HB2", "HA2"},
+     613             :     {"ND1", "NR2"},
+     614             :     {"CG",  "CPH1"},
+     615             :     {"CE1", "CPH2"},
+     616             :     {"HE1", "HR1"},
+     617             :     {"NE2", "NR1"},
+     618             :     {"HE2", "H"  },
+     619             :     {"CD2", "CPH1"},
+     620             :     {"HD2", "HR3"},
+     621             :     {"C",   "C"  },
+     622             :     {"O",   "O"  }
+     623          95 :   };
+     624          10 :   typemap["HSP"] = {
+     625             :     {"N",   "NH1"},
+     626             :     {"HN",  "H"  },
+     627             :     {"CA",  "CT1"},
+     628             :     {"HA",  "HB1"},
+     629             :     {"CB",  "CT2"},
+     630             :     {"HB1", "HA2"},
+     631             :     {"HB2", "HA2"},
+     632             :     {"CD2", "CPH1"},
+     633             :     {"HD2", "HR1"},
+     634             :     {"CG",  "CPH1"},
+     635             :     {"NE2", "NR3"},
+     636             :     {"HE2", "H"  },
+     637             :     {"ND1", "NR3"},
+     638             :     {"HD1", "H"  },
+     639             :     {"CE1", "CPH2"},
+     640             :     {"HE1", "HR2"},
+     641             :     {"C",   "C"  },
+     642             :     {"O",   "O"  }
+     643         100 :   };
+     644          10 :   typemap["ILE"] = {
+     645             :     {"N",    "NH1"},
+     646             :     {"HN",   "H"  },
+     647             :     {"CA",   "CT1"},
+     648             :     {"HA",   "HB1"},
+     649             :     {"CB",   "CT1"},
+     650             :     {"HB",   "HA1"},
+     651             :     {"CG2",  "CT3"},
+     652             :     {"HG21", "HA3"},
+     653             :     {"HG22", "HA3"},
+     654             :     {"HG23", "HA3"},
+     655             :     {"CG1",  "CT2"},
+     656             :     {"HG11", "HA2"},
+     657             :     {"HG12", "HA2"},
+     658             :     {"CD",   "CT3"},
+     659             :     {"HD1",  "HA3"},
+     660             :     {"HD2",  "HA3"},
+     661             :     {"HD3",  "HA3"},
+     662             :     {"C",    "C"  },
+     663             :     {"O",    "O"  }
+     664         105 :   };
+     665          10 :   typemap["LEU"] = {
+     666             :     {"N",    "NH1"},
+     667             :     {"HN",   "H"  },
+     668             :     {"CA",   "CT1"},
+     669             :     {"HA",   "HB1"},
+     670             :     {"CB",   "CT2"},
+     671             :     {"HB1",  "HA2"},
+     672             :     {"HB2",  "HA2"},
+     673             :     {"CG",   "CT1"},
+     674             :     {"HG",   "HA1"},
+     675             :     {"CD1",  "CT3"},
+     676             :     {"HD11", "HA3"},
+     677             :     {"HD12", "HA3"},
+     678             :     {"HD13", "HA3"},
+     679             :     {"CD2",  "CT3"},
+     680             :     {"HD21", "HA3"},
+     681             :     {"HD22", "HA3"},
+     682             :     {"HD23", "HA3"},
+     683             :     {"C",    "C"  },
+     684             :     {"O",    "O"  }
+     685         105 :   };
+     686          10 :   typemap["LYS"] = {
+     687             :     {"N",   "NH1"},
+     688             :     {"HN",  "H"  },
+     689             :     {"CA",  "CT1"},
+     690             :     {"HA",  "HB1"},
+     691             :     {"CB",  "CT2"},
+     692             :     {"HB1", "HA2"},
+     693             :     {"HB2", "HA2"},
+     694             :     {"CG",  "CT2"},
+     695             :     {"HG1", "HA2"},
+     696             :     {"HG2", "HA2"},
+     697             :     {"CD",  "CT2"},
+     698             :     {"HD1", "HA2"},
+     699             :     {"HD2", "HA2"},
+     700             :     {"CE",  "CT2"},
+     701             :     {"HE1", "HA2"},
+     702             :     {"HE2", "HA2"},
+     703             :     {"NZ",  "NH3"},
+     704             :     {"HZ1", "HC" },
+     705             :     {"HZ2", "HC" },
+     706             :     {"HZ3", "HC" },
+     707             :     {"C",   "C"  },
+     708             :     {"O",   "O"  }
+     709         120 :   };
+     710          10 :   typemap["MET"] = {
+     711             :     {"N",   "NH1"},
+     712             :     {"HN",  "H"  },
+     713             :     {"CA",  "CT1"},
+     714             :     {"HA",  "HB1"},
+     715             :     {"CB",  "CT2"},
+     716             :     {"HB1", "HA2"},
+     717             :     {"HB2", "HA2"},
+     718             :     {"CG",  "CT2"},
+     719             :     {"HG1", "HA2"},
+     720             :     {"HG2", "HA2"},
+     721             :     {"SD",  "S"  },
+     722             :     {"CE",  "CT3"},
+     723             :     {"HE1", "HA3"},
+     724             :     {"HE2", "HA3"},
+     725             :     {"HE3", "HA3"},
+     726             :     {"C",   "C"  },
+     727             :     {"O",   "O"  }
+     728          95 :   };
+     729          10 :   typemap["NMA"] = {
+     730             :     {"N",   "NH1"},
+     731             :     {"HN",  "H"  },
+     732             :     {"CH3", "CT3"},
+     733             :     {"HH31","HA3"},
+     734             :     {"HH32","HA3"},
+     735             :     {"HH33","HA3"},
+     736          40 :   };
+     737          10 :   typemap["PHE"] = {
+     738             :     {"N",   "NH1"},
+     739             :     {"HN",  "H"  },
+     740             :     {"CA",  "CT1"},
+     741             :     {"HA",  "HB1"},
+     742             :     {"CB",  "CT2"},
+     743             :     {"HB1", "HA2"},
+     744             :     {"HB2", "HA2"},
+     745             :     {"CG",  "CA" },
+     746             :     {"CD1", "CA" },
+     747             :     {"HD1", "HP" },
+     748             :     {"CE1", "CA" },
+     749             :     {"HE1", "HP" },
+     750             :     {"CZ",  "CA" },
+     751             :     {"HZ",  "HP" },
+     752             :     {"CD2", "CA" },
+     753             :     {"HD2", "HP" },
+     754             :     {"CE2", "CA" },
+     755             :     {"HE2", "HP" },
+     756             :     {"C",   "C"  },
+     757             :     {"O",   "O"  }
+     758         110 :   };
+     759          10 :   typemap["PRO"] = {
+     760             :     {"N",   "N"  },
+     761             :     {"CD",  "CP3"},
+     762             :     {"HD1", "HA2"},
+     763             :     {"HD2", "HA2"},
+     764             :     {"CA",  "CP1"},
+     765             :     {"HA",  "HB1"},
+     766             :     {"CB",  "CP2"},
+     767             :     {"HB1", "HA2"},
+     768             :     {"HB2", "HA2"},
+     769             :     {"CG",  "CP2"},
+     770             :     {"HG1", "HA2"},
+     771             :     {"HG2", "HA2"},
+     772             :     {"C",   "C"  },
+     773             :     {"O",   "O"  }
+     774          80 :   };
+     775          10 :   typemap["SER"] = {
+     776             :     {"N",   "NH1"},
+     777             :     {"HN",  "H"  },
+     778             :     {"CA",  "CT1"},
+     779             :     {"HA",  "HB1"},
+     780             :     {"CB",  "CT2"},
+     781             :     {"HB1", "HA2"},
+     782             :     {"HB2", "HA2"},
+     783             :     {"OG",  "OH1"},
+     784             :     {"HG1", "H"  },
+     785             :     {"C",   "C"  },
+     786             :     {"O",   "O"  }
+     787          65 :   };
+     788          10 :   typemap["THR"] = {
+     789             :     {"N",    "NH1"},
+     790             :     {"HN",   "H"  },
+     791             :     {"CA",   "CT1"},
+     792             :     {"HA",   "HB1"},
+     793             :     {"CB",   "CT1"},
+     794             :     {"HB",   "HA1"},
+     795             :     {"OG1",  "OH1"},
+     796             :     {"HG1",  "H"  },
+     797             :     {"CG2",  "CT3"},
+     798             :     {"HG21", "HA3"},
+     799             :     {"HG22", "HA3"},
+     800             :     {"HG23", "HA3"},
+     801             :     {"C",    "C"  },
+     802             :     {"O",    "O"  }
+     803          80 :   };
+     804          10 :   typemap["TRP"] = {
+     805             :     {"N",   "NH1"},
+     806             :     {"HN",  "H"  },
+     807             :     {"CA",  "CT1"},
+     808             :     {"HA",  "HB1"},
+     809             :     {"CB",  "CT2"},
+     810             :     {"HB1", "HA2"},
+     811             :     {"HB2", "HA2"},
+     812             :     {"CG",  "CY" },
+     813             :     {"CD1", "CA" },
+     814             :     {"HD1", "HP" },
+     815             :     {"NE1", "NY" },
+     816             :     {"HE1", "H"  },
+     817             :     {"CE2", "CPT"},
+     818             :     {"CD2", "CPT"},
+     819             :     {"CE3", "CAI"},
+     820             :     {"HE3", "HP" },
+     821             :     {"CZ3", "CA" },
+     822             :     {"HZ3", "HP" },
+     823             :     {"CZ2", "CAI"},
+     824             :     {"HZ2", "HP" },
+     825             :     {"CH2", "CA" },
+     826             :     {"HH2", "HP" },
+     827             :     {"C",   "C"  },
+     828             :     {"O",   "O"  }
+     829         130 :   };
+     830          10 :   typemap["TYR"] = {
+     831             :     {"N",   "NH1"},
+     832             :     {"HN",  "H"  },
+     833             :     {"CA",  "CT1"},
+     834             :     {"HA",  "HB1"},
+     835             :     {"CB",  "CT2"},
+     836             :     {"HB1", "HA2"},
+     837             :     {"HB2", "HA2"},
+     838             :     {"CG",  "CA" },
+     839             :     {"CD1", "CA" },
+     840             :     {"HD1", "HP" },
+     841             :     {"CE1", "CA" },
+     842             :     {"HE1", "HP" },
+     843             :     {"CZ",  "CA" },
+     844             :     {"OH",  "OH1"},
+     845             :     {"HH",  "H"  },
+     846             :     {"CD2", "CA" },
+     847             :     {"HD2", "HP" },
+     848             :     {"CE2", "CA" },
+     849             :     {"HE2", "HP" },
+     850             :     {"C",   "C"  },
+     851             :     {"O",   "O"  }
+     852         115 :   };
+     853          10 :   typemap["VAL"] = {
+     854             :     {"N",    "NH1"},
+     855             :     {"HN",   "H"  },
+     856             :     {"CA",   "CT1"},
+     857             :     {"HA",   "HB1"},
+     858             :     {"CB",   "CT1"},
+     859             :     {"HB",   "HA1"},
+     860             :     {"CG1",  "CT3"},
+     861             :     {"HG11", "HA3"},
+     862             :     {"HG12", "HA3"},
+     863             :     {"HG13", "HA3"},
+     864             :     {"CG2",  "CT3"},
+     865             :     {"HG21", "HA3"},
+     866             :     {"HG22", "HA3"},
+     867             :     {"HG23", "HA3"},
+     868             :     {"C",    "C"  },
+     869             :     {"O",    "O"  }
+     870          90 :   };
+     871           5 :   return typemap;
+     872             : }
+     873             : 
+     874           5 : std::map<std::string, std::vector<double> > EEFSolv::setupValueMap() {
+     875             :   // Volume ∆Gref ∆Gfree ∆H ∆Cp λ vdw_radius
+     876             :   std::map<std::string, std::vector<double> > valuemap;
+     877           5 :   valuemap["C"] = {
+     878             :     ANG3_TO_NM3 * 14.720,
+     879             :     KCAL_TO_KJ * 0.000,
+     880             :     KCAL_TO_KJ * 0.000,
+     881             :     KCAL_TO_KJ * 0.000,
+     882             :     KCAL_TO_KJ * 0.0,
+     883             :     1. / (ANG_TO_NM * 3.5),
+     884             :     0.20,
+     885          10 :   };
+     886           5 :   valuemap["CD"] = {
+     887             :     ANG3_TO_NM3 * 14.720,
+     888             :     KCAL_TO_KJ * 0.000,
+     889             :     KCAL_TO_KJ * 0.000,
+     890             :     KCAL_TO_KJ * 0.000,
+     891             :     KCAL_TO_KJ * 0.0,
+     892             :     1. / (ANG_TO_NM * 3.5),
+     893             :     0.20,
+     894          10 :   };
+     895           5 :   valuemap["CT1"] = {
+     896             :     ANG3_TO_NM3 * 11.507,
+     897             :     KCAL_TO_KJ * -0.187,
+     898             :     KCAL_TO_KJ * -0.187,
+     899             :     KCAL_TO_KJ * 0.876,
+     900             :     KCAL_TO_KJ * 0.0,
+     901             :     1. / (ANG_TO_NM * 3.5),
+     902             :     0.20,
+     903          10 :   };
+     904           5 :   valuemap["CT2"] = {
+     905             :     ANG3_TO_NM3 * 18.850,
+     906             :     KCAL_TO_KJ * 0.372,
+     907             :     KCAL_TO_KJ * 0.372,
+     908             :     KCAL_TO_KJ * -0.610,
+     909             :     KCAL_TO_KJ * 18.6,
+     910             :     1. / (ANG_TO_NM * 3.5),
+     911             :     0.20,
+     912          10 :   };
+     913           5 :   valuemap["CT2A"] = {
+     914             :     ANG3_TO_NM3 * 18.666,
+     915             :     KCAL_TO_KJ * 0.372,
+     916             :     KCAL_TO_KJ * 0.372,
+     917             :     KCAL_TO_KJ * -0.610,
+     918             :     KCAL_TO_KJ * 18.6,
+     919             :     1. / (ANG_TO_NM * 3.5),
+     920             :     0.20,
+     921          10 :   };
+     922           5 :   valuemap["CT3"] = {
+     923             :     ANG3_TO_NM3 * 27.941,
+     924             :     KCAL_TO_KJ * 1.089,
+     925             :     KCAL_TO_KJ * 1.089,
+     926             :     KCAL_TO_KJ * -1.779,
+     927             :     KCAL_TO_KJ * 35.6,
+     928             :     1. / (ANG_TO_NM * 3.5),
+     929             :     0.204,
+     930          10 :   };
+     931           5 :   valuemap["CPH1"] = {
+     932             :     ANG3_TO_NM3 * 5.275,
+     933             :     KCAL_TO_KJ * 0.057,
+     934             :     KCAL_TO_KJ * 0.080,
+     935             :     KCAL_TO_KJ * -0.973,
+     936             :     KCAL_TO_KJ * 6.9,
+     937             :     1. / (ANG_TO_NM * 3.5),
+     938             :     0.18,
+     939          10 :   };
+     940           5 :   valuemap["CPH2"] = {
+     941             :     ANG3_TO_NM3 * 11.796,
+     942             :     KCAL_TO_KJ * 0.057,
+     943             :     KCAL_TO_KJ * 0.080,
+     944             :     KCAL_TO_KJ * -0.973,
+     945             :     KCAL_TO_KJ * 6.9,
+     946             :     1. / (ANG_TO_NM * 3.5),
+     947             :     0.18,
+     948          10 :   };
+     949           5 :   valuemap["CPT"] = {
+     950             :     ANG3_TO_NM3 * 4.669,
+     951             :     KCAL_TO_KJ * -0.890,
+     952             :     KCAL_TO_KJ * -0.890,
+     953             :     KCAL_TO_KJ * 2.220,
+     954             :     KCAL_TO_KJ * 6.9,
+     955             :     1. / (ANG_TO_NM * 3.5),
+     956             :     0.186,
+     957          10 :   };
+     958           5 :   valuemap["CY"] = {
+     959             :     ANG3_TO_NM3 * 10.507,
+     960             :     KCAL_TO_KJ * -0.890,
+     961             :     KCAL_TO_KJ * -0.890,
+     962             :     KCAL_TO_KJ * 2.220,
+     963             :     KCAL_TO_KJ * 6.9,
+     964             :     1. / (ANG_TO_NM * 3.5),
+     965             :     0.199,
+     966          10 :   };
+     967           5 :   valuemap["CP1"] = {
+     968             :     ANG3_TO_NM3 * 25.458,
+     969             :     KCAL_TO_KJ * -0.187,
+     970             :     KCAL_TO_KJ * -0.187,
+     971             :     KCAL_TO_KJ * 0.876,
+     972             :     KCAL_TO_KJ * 0.0,
+     973             :     1. / (ANG_TO_NM * 3.5),
+     974             :     0.227,
+     975          10 :   };
+     976           5 :   valuemap["CP2"] = {
+     977             :     ANG3_TO_NM3 * 19.880,
+     978             :     KCAL_TO_KJ * 0.372,
+     979             :     KCAL_TO_KJ * 0.372,
+     980             :     KCAL_TO_KJ * -0.610,
+     981             :     KCAL_TO_KJ * 18.6,
+     982             :     1. / (ANG_TO_NM * 3.5),
+     983             :     0.217,
+     984          10 :   };
+     985           5 :   valuemap["CP3"] = {
+     986             :     ANG3_TO_NM3 * 26.731,
+     987             :     KCAL_TO_KJ * 0.372,
+     988             :     KCAL_TO_KJ * 0.372,
+     989             :     KCAL_TO_KJ * -0.610,
+     990             :     KCAL_TO_KJ * 18.6,
+     991             :     1. / (ANG_TO_NM * 3.5),
+     992             :     0.217,
+     993          10 :   };
+     994           5 :   valuemap["CC"] = {
+     995             :     ANG3_TO_NM3 * 16.539,
+     996             :     KCAL_TO_KJ * 0.000,
+     997             :     KCAL_TO_KJ * 0.000,
+     998             :     KCAL_TO_KJ * 0.000,
+     999             :     KCAL_TO_KJ * 0.0,
+    1000             :     1. / (ANG_TO_NM * 3.5),
+    1001             :     0.20,
+    1002          10 :   };
+    1003           5 :   valuemap["CAI"] = {
+    1004             :     ANG3_TO_NM3 * 18.249,
+    1005             :     KCAL_TO_KJ * 0.057,
+    1006             :     KCAL_TO_KJ * 0.057,
+    1007             :     KCAL_TO_KJ * -0.973,
+    1008             :     KCAL_TO_KJ * 6.9,
+    1009             :     1. / (ANG_TO_NM * 3.5),
+    1010             :     0.199,
+    1011          10 :   };
+    1012           5 :   valuemap["CA"] = {
+    1013             :     ANG3_TO_NM3 * 18.249,
+    1014             :     KCAL_TO_KJ * 0.057,
+    1015             :     KCAL_TO_KJ * 0.057,
+    1016             :     KCAL_TO_KJ * -0.973,
+    1017             :     KCAL_TO_KJ * 6.9,
+    1018             :     1. / (ANG_TO_NM * 3.5),
+    1019             :     0.199,
+    1020          10 :   };
+    1021           5 :   valuemap["N"] = {
+    1022             :     ANG3_TO_NM3 * 0.000,
+    1023             :     KCAL_TO_KJ * -1.000,
+    1024             :     KCAL_TO_KJ * -1.000,
+    1025             :     KCAL_TO_KJ * -1.250,
+    1026             :     KCAL_TO_KJ * 8.8,
+    1027             :     1. / (ANG_TO_NM * 3.5),
+    1028             :     0.185,
+    1029          10 :   };
+    1030           5 :   valuemap["NR1"] = {
+    1031             :     ANG3_TO_NM3 * 15.273,
+    1032             :     KCAL_TO_KJ * -5.950,
+    1033             :     KCAL_TO_KJ * -5.950,
+    1034             :     KCAL_TO_KJ * -9.059,
+    1035             :     KCAL_TO_KJ * -8.8,
+    1036             :     1. / (ANG_TO_NM * 3.5),
+    1037             :     0.185,
+    1038          10 :   };
+    1039           5 :   valuemap["NR2"] = {
+    1040             :     ANG3_TO_NM3 * 15.111,
+    1041             :     KCAL_TO_KJ * -3.820,
+    1042             :     KCAL_TO_KJ * -3.820,
+    1043             :     KCAL_TO_KJ * -4.654,
+    1044             :     KCAL_TO_KJ * -8.8,
+    1045             :     1. / (ANG_TO_NM * 3.5),
+    1046             :     0.185,
+    1047          10 :   };
+    1048           5 :   valuemap["NR3"] = {
+    1049             :     ANG3_TO_NM3 * 15.071,
+    1050             :     KCAL_TO_KJ * -5.950,
+    1051             :     KCAL_TO_KJ * -5.950,
+    1052             :     KCAL_TO_KJ * -9.059,
+    1053             :     KCAL_TO_KJ * -8.8,
+    1054             :     1. / (ANG_TO_NM * 3.5),
+    1055             :     0.185,
+    1056          10 :   };
+    1057           5 :   valuemap["NH1"] = {
+    1058             :     ANG3_TO_NM3 * 10.197,
+    1059             :     KCAL_TO_KJ * -5.950,
+    1060             :     KCAL_TO_KJ * -5.950,
+    1061             :     KCAL_TO_KJ * -9.059,
+    1062             :     KCAL_TO_KJ * -8.8,
+    1063             :     1. / (ANG_TO_NM * 3.5),
+    1064             :     0.185,
+    1065          10 :   };
+    1066           5 :   valuemap["NH2"] = {
+    1067             :     ANG3_TO_NM3 * 18.182,
+    1068             :     KCAL_TO_KJ * -5.950,
+    1069             :     KCAL_TO_KJ * -5.950,
+    1070             :     KCAL_TO_KJ * -9.059,
+    1071             :     KCAL_TO_KJ * -8.8,
+    1072             :     1. / (ANG_TO_NM * 3.5),
+    1073             :     0.185,
+    1074          10 :   };
+    1075           5 :   valuemap["NH3"] = {
+    1076             :     ANG3_TO_NM3 * 18.817,
+    1077             :     KCAL_TO_KJ * -20.000,
+    1078             :     KCAL_TO_KJ * -20.000,
+    1079             :     KCAL_TO_KJ * -25.000,
+    1080             :     KCAL_TO_KJ * -18.0,
+    1081             :     1. / (ANG_TO_NM * 6.0),
+    1082             :     0.185,
+    1083          10 :   };
+    1084           5 :   valuemap["NC2"] = {
+    1085             :     ANG3_TO_NM3 * 18.215,
+    1086             :     KCAL_TO_KJ * -10.000,
+    1087             :     KCAL_TO_KJ * -10.000,
+    1088             :     KCAL_TO_KJ * -12.000,
+    1089             :     KCAL_TO_KJ * -7.0,
+    1090             :     1. / (ANG_TO_NM * 6.0),
+    1091             :     0.185,
+    1092          10 :   };
+    1093           5 :   valuemap["NY"] = {
+    1094             :     ANG3_TO_NM3 * 12.001,
+    1095             :     KCAL_TO_KJ * -5.950,
+    1096             :     KCAL_TO_KJ * -5.950,
+    1097             :     KCAL_TO_KJ * -9.059,
+    1098             :     KCAL_TO_KJ * -8.8,
+    1099             :     1. / (ANG_TO_NM * 3.5),
+    1100             :     0.185,
+    1101          10 :   };
+    1102           5 :   valuemap["NP"] = {
+    1103             :     ANG3_TO_NM3 * 4.993,
+    1104             :     KCAL_TO_KJ * -20.000,
+    1105             :     KCAL_TO_KJ * -20.000,
+    1106             :     KCAL_TO_KJ * -25.000,
+    1107             :     KCAL_TO_KJ * -18.0,
+    1108             :     1. / (ANG_TO_NM * 6.0),
+    1109             :     0.185,
+    1110          10 :   };
+    1111           5 :   valuemap["O"] = {
+    1112             :     ANG3_TO_NM3 * 11.772,
+    1113             :     KCAL_TO_KJ * -5.330,
+    1114             :     KCAL_TO_KJ * -5.330,
+    1115             :     KCAL_TO_KJ * -5.787,
+    1116             :     KCAL_TO_KJ * -8.8,
+    1117             :     1. / (ANG_TO_NM * 3.5),
+    1118             :     0.170,
+    1119          10 :   };
+    1120           5 :   valuemap["OB"] = {
+    1121             :     ANG3_TO_NM3 * 11.694,
+    1122             :     KCAL_TO_KJ * -5.330,
+    1123             :     KCAL_TO_KJ * -5.330,
+    1124             :     KCAL_TO_KJ * -5.787,
+    1125             :     KCAL_TO_KJ * -8.8,
+    1126             :     1. / (ANG_TO_NM * 3.5),
+    1127             :     0.170,
+    1128          10 :   };
+    1129           5 :   valuemap["OC"] = {
+    1130             :     ANG3_TO_NM3 * 12.003,
+    1131             :     KCAL_TO_KJ * -10.000,
+    1132             :     KCAL_TO_KJ * -10.000,
+    1133             :     KCAL_TO_KJ * -12.000,
+    1134             :     KCAL_TO_KJ * -9.4,
+    1135             :     1. / (ANG_TO_NM * 6.0),
+    1136             :     0.170,
+    1137          10 :   };
+    1138           5 :   valuemap["OH1"] = {
+    1139             :     ANG3_TO_NM3 * 15.528,
+    1140             :     KCAL_TO_KJ * -5.920,
+    1141             :     KCAL_TO_KJ * -5.920,
+    1142             :     KCAL_TO_KJ * -9.264,
+    1143             :     KCAL_TO_KJ * -11.2,
+    1144             :     1. / (ANG_TO_NM * 3.5),
+    1145             :     0.177,
+    1146          10 :   };
+    1147           5 :   valuemap["OS"] = {
+    1148             :     ANG3_TO_NM3 * 6.774,
+    1149             :     KCAL_TO_KJ * -2.900,
+    1150             :     KCAL_TO_KJ * -2.900,
+    1151             :     KCAL_TO_KJ * -3.150,
+    1152             :     KCAL_TO_KJ * -4.8,
+    1153             :     1. / (ANG_TO_NM * 3.5),
+    1154             :     0.177,
+    1155          10 :   };
+    1156           5 :   valuemap["S"] = {
+    1157             :     ANG3_TO_NM3 * 20.703,
+    1158             :     KCAL_TO_KJ * -3.240,
+    1159             :     KCAL_TO_KJ * -3.240,
+    1160             :     KCAL_TO_KJ * -4.475,
+    1161             :     KCAL_TO_KJ * -39.9,
+    1162             :     1. / (ANG_TO_NM * 3.5),
+    1163             :     0.20,
+    1164          10 :   };
+    1165           5 :   valuemap["SM"] = {
+    1166             :     ANG3_TO_NM3 * 21.306,
+    1167             :     KCAL_TO_KJ * -3.240,
+    1168             :     KCAL_TO_KJ * -3.240,
+    1169             :     KCAL_TO_KJ * -4.475,
+    1170             :     KCAL_TO_KJ * -39.9,
+    1171             :     1. / (ANG_TO_NM * 3.5),
+    1172             :     0.197,
+    1173          10 :   };
+    1174           5 :   return valuemap;
+    1175             : }
+    1176             : }
+    1177             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ERMSD.cpp.func-sort-c.html b/coverage/colvar/ERMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..b06c0b4a6bc0 --- /dev/null +++ b/coverage/colvar/ERMSD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ERMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505198.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5ERMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar5ERMSDC1ERKNS_13ActionOptionsE4
_ZN4PLMD6colvar5ERMSD16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6colvar5ERMSD9calculateEv222
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ERMSD.cpp.func.html b/coverage/colvar/ERMSD.cpp.func.html new file mode 100644 index 000000000000..6192b35a8dca --- /dev/null +++ b/coverage/colvar/ERMSD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ERMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505198.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar5ERMSD16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6colvar5ERMSD9calculateEv222
_ZN4PLMD6colvar5ERMSDC1ERKNS_13ActionOptionsE4
_ZN4PLMD6colvar5ERMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ERMSD.cpp.gcov.html b/coverage/colvar/ERMSD.cpp.gcov.html new file mode 100644 index 000000000000..a676547b1810 --- /dev/null +++ b/coverage/colvar/ERMSD.cpp.gcov.html @@ -0,0 +1,291 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ERMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505198.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /*
+      24             :  This vast majority of the source code in this file was writting by
+      25             :  Sandro Bottaro with some help from Giovanni Bussi
+      26             : */
+      27             : 
+      28             : #include "Colvar.h"
+      29             : #include "core/PlumedMain.h"
+      30             : #include "core/ActionRegister.h"
+      31             : #include "tools/PDB.h"
+      32             : #include "tools/ERMSD.h"
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace colvar {
+      36             : 
+      37             : 
+      38             : //+PLUMEDOC COLVAR ERMSD
+      39             : /*
+      40             : Calculate eRMSD with respect to a reference structure.
+      41             : 
+      42             : eRMSD is a metric developed for measuring distances between three-dimensional RNA structures.
+      43             : The standard RMSD measure is highly inaccurate when measuring distances among three-dimensional
+      44             : structures of nucleic acids.
+      45             : It is not unusual, for example, that two RNA structures with low RMSD (i.e. less than 0.4nm) display a completely different network of base-base interactions.
+      46             : 
+      47             : eRMSD measures the distance between structures by considering only the relative positions and orientations of nucleobases. The eRMSD can be considered as a vectorial version of contact maps and it is calculated as follows:
+      48             : 
+      49             : 1. Set up a local reference system in the center of the six-membered ring of each nucleobase in a molecule.
+      50             :    The xy plane lies on the plane of the nucleobase, and it is oriented such that the Watson-Crick interaction is always at \f$\theta\approx 60^{\circ}\f$.
+      51             : 
+      52             : 2. Calculate all pairwise distance vectors \f$\vec{r}_{i,j}\f$ among base centers.
+      53             : 
+      54             : 3. Rescale distance vectors as \f$\tilde{\vec{r}}_{i,j}=(r_x/a,r_y/a,r_z/b)\f$, where  a=b=5 \f$\r{A}\f$, c=3 \f$\r{A}\f$. This rescaling has the effect of weighting more deviations on the z-axis with respect to the x/y directions.
+      55             : 
+      56             : 4. Calculate the G vectors
+      57             : 
+      58             : \f[
+      59             : \vec{G}(\tilde{\vec{r}}) = (\sin(\gamma \tilde{r}) \tilde{r}_x/\tilde{r},\sin(\gamma \tilde{r}) \tilde{r}_y/\tilde{r},\sin(\gamma \tilde{r}) \tilde{r}_z/\tilde{r}, 1+\cos(\gamma \tilde{r})) \times
+      60             : \frac{\Theta(\tilde{r}_{cutoff}-\tilde{r})}{\gamma}
+      61             : \f]
+      62             : 
+      63             : Here, \f$ \gamma = \pi/\tilde{r}_{cutoff}\f$ and \f$ \Theta \f$ is the Heaviside step function. The default cutoff is set to 2.4.
+      64             : 
+      65             : 5. The eRMSD between two structures \f$ \alpha \f$ and \f$ \beta \f$ reads
+      66             : 
+      67             : \f[
+      68             : eRMSD = \sqrt{\frac{1}{N} \sum_{j,k} \vert \vec{G}(\tilde{\vec{r}}_{jk}^{\alpha}) - \vec{G}(\tilde{\vec{r}}_{jk}^{\beta}) \vert^2 }
+      69             : \f]
+      70             : 
+      71             : Using the default cutoff, two structures with eRMSD of 0.7 or lower can be considered as significantly similar. A full description of the eRMSD can be found in \cite bott14
+      72             : 
+      73             : ERMSD is computed using the position of three atoms on the 6-membered ring of each involved nucleobase. The atoms should be:
+      74             : - C2,C4,C6 for pyrimdines
+      75             : - C2,C6,C4 for purines
+      76             : 
+      77             : The different order for purines and pyrimidines is fundamental and allows you to compute ERMSD between structures with different
+      78             : sequences as well! Notice that the simplest way to avoid mistakes in choosing these atoms is to use the `@lcs-#` strings
+      79             : as shown in the examples (see also \ref MOLINFO).
+      80             : 
+      81             : \warning Notice that the ERMSD implemented here is not integrated with the other metrics in plumed. As a consequence, it is not (yet) possible
+      82             : to e.g. build path collective variables using ERMSD
+      83             : 
+      84             : \warning Notice that ERMSD expect a single molecule and makes coordinate whole before anything else. As such, results might be unexpected
+      85             : for a multi molecular system.
+      86             : 
+      87             : \par Examples
+      88             : 
+      89             : Calculate the eRMSD from reference structure reference.pdb using the default cutoff (2.4). The list of residues involved in the calculation has to be specified. In this example, the eRMSD is calculated
+      90             : considering residues 1,2,3,4,5,6.
+      91             : 
+      92             : \plumedfile
+      93             : #SETTINGS MOLFILE=regtest/basic/rt-ermsd/ref.pdb
+      94             : MOLINFO STRUCTURE=reference.pdb
+      95             : eRMSD1: ERMSD REFERENCE=reference.pdb ATOMS=@lcs-1,@lcs-2,@lcs-3,@lcs-4,@lcs-5,@lcs-6
+      96             : \endplumedfile
+      97             : 
+      98             : */
+      99             : //+ENDPLUMEDOC
+     100             : 
+     101             : 
+     102             : class ERMSD : public Colvar {
+     103             : 
+     104             : 
+     105             :   std::vector<Vector> derivs;
+     106             :   PLMD::ERMSD ermsd;
+     107             :   bool pbc;
+     108             : 
+     109             : public:
+     110             :   explicit ERMSD(const ActionOptions&);
+     111             :   void calculate() override;
+     112             :   static void registerKeywords(Keywords& keys);
+     113             : };
+     114             : 
+     115             : PLUMED_REGISTER_ACTION(ERMSD,"ERMSD")
+     116             : 
+     117           6 : void ERMSD::registerKeywords(Keywords& keys) {
+     118           6 :   Colvar::registerKeywords(keys);
+     119             : 
+     120          12 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     121          12 :   keys.add("compulsory","CUTOFF","2.4","only pairs of atoms closer than CUTOFF are considered in the calculation.");
+     122          12 :   keys.add("atoms","ATOMS","the list of atoms (use lcs)");
+     123          12 :   keys.add("optional","PAIRS","List of pairs considered. All pairs are considered if this value is not specified.");
+     124             : 
+     125           6 : }
+     126             : 
+     127           4 : ERMSD::ERMSD(const ActionOptions&ao):
+     128           4 :   PLUMED_COLVAR_INIT(ao), pbc(true)
+     129             : {
+     130             :   std::string reference;
+     131           4 :   parse("REFERENCE",reference);
+     132           4 :   double cutoff=2.4;
+     133           4 :   parse("CUTOFF",cutoff);
+     134             : 
+     135             : 
+     136           4 :   bool nopbc(false);
+     137           4 :   parseFlag("NOPBC",nopbc);
+     138           4 :   pbc=!nopbc;
+     139             : 
+     140             :   std::vector<AtomNumber> atoms_;
+     141           8 :   parseAtomList("ATOMS",atoms_);
+     142             : 
+     143             :   std::vector<unsigned> pairs_;
+     144           4 :   parseVector("PAIRS",pairs_);
+     145           4 :   checkRead();
+     146             : 
+     147           8 :   addValueWithDerivatives(); setNotPeriodic();
+     148             : 
+     149           4 :   if(atoms_.size()<6) error("at least six atoms should be specified");
+     150           4 :   if(atoms_.size()%3!=0) error("Atoms are not multiple of 3");
+     151           4 :   if(pairs_.size()%2!=0) error("pairs are not multiple of 2");
+     152             : 
+     153             : 
+     154             :   //checkRead();
+     155             :   //log.printf("  of atoms");
+     156             :   //for(unsigned i=0;i<atoms.size();++i) log.printf(" %d",atoms[i].serial());
+     157             :   //requestAtoms(atoms);
+     158             : 
+     159             :   // read everything in ang and transform to nm if we are not in natural units
+     160           4 :   PDB pdb;
+     161           4 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     162           0 :     error("missing input file " + reference );
+     163             :   // store target_ distance
+     164             :   std::vector <Vector> reference_positions;
+     165           4 :   unsigned natoms = atoms_.size();
+     166           4 :   log.printf("Read %u atoms\n",natoms);
+     167             : 
+     168           4 :   reference_positions.resize(natoms);
+     169         856 :   for(unsigned i=0; i<natoms; i++) {
+     170         852 :     reference_positions[i] = pdb.getPosition(atoms_[i]);
+     171             :     //log.printf("%f %f %f \n",reference_positions[i][0],reference_positions[i][1],reference_positions[i][2]);
+     172             :   }
+     173             : 
+     174             : // shift to count from zero
+     175          28 :   for(unsigned i=0; i<pairs_.size(); ++i) pairs_[i]--;
+     176             : 
+     177           4 :   ermsd.setReference(reference_positions,pairs_,cutoff/getUnits().getLength());
+     178             : 
+     179           4 :   requestAtoms(atoms_);
+     180           4 :   derivs.resize(natoms);
+     181             : 
+     182           4 :   log.printf("  reference from file %s\n",reference.c_str());
+     183           4 :   log.printf("  which contains %u atoms\n",natoms);
+     184             : 
+     185           4 :   log<<"  Bibliography "
+     186           8 :      <<plumed.cite("Bottaro, Di Palma, and Bussi, Nucleic Acids Res. 42, 13306 (2014)")
+     187          12 :      <<plumed.cite("Bottaro, Banas, Sponer, and Bussi, J. Phys. Chem. Lett. 7, 4032 (2016)")<<"\n";
+     188             : 
+     189           8 : }
+     190             : 
+     191             : // calculator
+     192         222 : void ERMSD::calculate() {
+     193             : // set derivatives to zero
+     194         222 :   Tools::set_to_zero(derivs);
+     195             :   double ermsdist;
+     196         222 :   Tensor virial;
+     197             : // This is a trick to avoid explicit virial calculation
+     198             : // 1. we make the molecule whole
+     199         222 :   makeWhole();
+     200             : // 2. we ignore pbcs
+     201         222 :   Pbc fake_pbc;
+     202             : // Notice that this might have problems when having 2 RNA molecules (hybridization).
+     203             : 
+     204         222 :   ermsdist=ermsd.calculate(getPositions(),fake_pbc,derivs,virial);
+     205         222 :   const double scale=getUnits().getLength();
+     206         222 :   setValue(ermsdist*scale);
+     207             : 
+     208       47508 :   for(unsigned i=0; i<derivs.size(); ++i) {setAtomsDerivatives(i,derivs[i]*scale);}
+     209             : 
+     210         222 :   setBoxDerivativesNoPbc();
+     211         222 : }
+     212             : 
+     213             : }
+     214             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Energy.cpp.func-sort-c.html b/coverage/colvar/Energy.cpp.func-sort-c.html new file mode 100644 index 000000000000..23c3b02f62dc --- /dev/null +++ b/coverage/colvar/Energy.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Energy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Energy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6EnergyC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar6EnergyC1ERKNS_13ActionOptionsE40
_ZN4PLMD6colvar6Energy16registerKeywordsERNS_8KeywordsE42
_ZN4PLMD6colvar6Energy4waitEv3989
_ZN4PLMD6colvar6Energy5applyEv3989
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Energy.cpp.func.html b/coverage/colvar/Energy.cpp.func.html new file mode 100644 index 000000000000..8cb45edfdada --- /dev/null +++ b/coverage/colvar/Energy.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Energy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Energy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6Energy16registerKeywordsERNS_8KeywordsE42
_ZN4PLMD6colvar6Energy4waitEv3989
_ZN4PLMD6colvar6Energy5applyEv3989
_ZN4PLMD6colvar6EnergyC1ERKNS_13ActionOptionsE40
_ZN4PLMD6colvar6EnergyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Energy.cpp.gcov.html b/coverage/colvar/Energy.cpp.gcov.html new file mode 100644 index 000000000000..e3ee85442faf --- /dev/null +++ b/coverage/colvar/Energy.cpp.gcov.html @@ -0,0 +1,202 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Energy.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Energy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionToPutData.h"
+      23             : #include "core/DomainDecomposition.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace colvar {
+      30             : 
+      31             : //+PLUMEDOC COLVAR ENERGY
+      32             : /*
+      33             : Calculate the total potential energy of the simulation box.
+      34             : 
+      35             : The potential energy can be biased e.g. with umbrella sampling \cite bart-karp98jpcb or with well-tempered metadynamics \cite Bonomi:2009p17935.
+      36             : 
+      37             : Notice that this CV could be unavailable with some MD code. When
+      38             : it is available, and when also replica exchange is available,
+      39             : metadynamics applied to ENERGY can be used to decrease the
+      40             : number of required replicas.
+      41             : 
+      42             : \bug This \ref ENERGY does not include long tail corrections.
+      43             : Thus when using e.g. LAMMPS `"pair_modify tail yes"` or GROMACS `"DispCorr Ener"` (or `"DispCorr EnerPres"`),
+      44             : the potential energy from \ref ENERGY will be slightly different form the one of the MD code.
+      45             : You should still be able to use \ref ENERGY and then reweight your simulation with the correct MD energy value.
+      46             : 
+      47             : \bug Acceptance for replica exchange when \ref ENERGY is biased
+      48             : is computed correctly only if all the replicas have the same
+      49             : potential energy function. This is for instance not true when
+      50             : using GROMACS with lambda replica exchange or with plumed-hrex branch.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The following input instructs plumed to print the energy of the system
+      55             : \plumedfile
+      56             : ene: ENERGY
+      57             : PRINT ARG=ene
+      58             : \endplumedfile
+      59             : 
+      60             : */
+      61             : //+ENDPLUMEDOC
+      62             : 
+      63             : 
+      64             : class Energy : public ActionToPutData {
+      65             : private:
+      66             : /// This is used to sum the data
+      67             :   DomainDecomposition* interface;
+      68             : /// This is the list of forces that must be scaled
+      69             :   std::vector<ActionToPutData*> forces_to_scale;
+      70             : public:
+      71             :   explicit Energy(const ActionOptions&);
+      72             : // active methods:
+      73             :   static void registerKeywords( Keywords& keys );
+      74             :   void wait() override;
+      75             :   void apply() override;
+      76             : };
+      77             : 
+      78             : 
+      79             : PLUMED_REGISTER_ACTION(Energy,"ENERGY")
+      80             : 
+      81          40 : Energy::Energy(const ActionOptions&ao):
+      82             :   Action(ao),
+      83             :   ActionToPutData(ao),
+      84          40 :   interface(NULL)
+      85             : {
+      86          40 :   plumed.setEnergyValue( getLabel() ); std::vector<unsigned> shape;
+      87          80 :   addValue( shape ); setNotPeriodic(); setUnit( "energy", "default" );
+      88          40 :   ActionToPutData* px=plumed.getActionSet().selectWithLabel< ActionToPutData*>("posx");
+      89          40 :   plumed_assert(px); forces_to_scale.push_back(px); addDependency( px );
+      90          40 :   ActionToPutData* py=plumed.getActionSet().selectWithLabel< ActionToPutData*>("posy");
+      91          40 :   plumed_assert(py); forces_to_scale.push_back(py); addDependency( py );
+      92          40 :   ActionToPutData* pz=plumed.getActionSet().selectWithLabel< ActionToPutData*>("posz");
+      93          40 :   plumed_assert(pz); forces_to_scale.push_back(pz); addDependency( pz );
+      94          40 :   ActionToPutData* bx=plumed.getActionSet().selectWithLabel< ActionToPutData*>("Box");
+      95          40 :   plumed_assert(bx); forces_to_scale.push_back(bx); addDependency( bx );
+      96          40 :   log<<"  Bibliography ";
+      97          80 :   log<<plumed.cite("Bartels and Karplus, J. Phys. Chem. B 102, 865 (1998)");
+      98          80 :   log<<plumed.cite("Bonomi and Parrinello, J. Comp. Chem. 30, 1615 (2009)");
+      99          40 :   log<<"\n";
+     100          40 : }
+     101             : 
+     102          42 : void Energy::registerKeywords( Keywords& keys ) {
+     103          42 :   Action::registerKeywords( keys );
+     104          42 : }
+     105             : 
+     106        3989 : void Energy::wait() {
+     107        3989 :   if( !interface ) {
+     108          40 :     std::vector<DomainDecomposition*> allput=plumed.getActionSet().select<DomainDecomposition*>();
+     109          40 :     if( allput.size()>1 ) warning("found more than one interface so don't know how to sum energy");
+     110          40 :     interface = allput[0];
+     111             :   }
+     112        3989 :   ActionToPutData::wait(); if( interface ) interface->sumOverDomains( copyOutput(0) );
+     113        3989 : }
+     114             : 
+     115        3989 : void Energy::apply() {
+     116        3989 :   if( getPntrToValue()->forcesWereAdded() ) {
+     117         250 :     for(unsigned i=0; i<forces_to_scale.size(); ++i) forces_to_scale[i]->rescaleForces( 1.- getPntrToValue()->getForce(0));
+     118             :   }
+     119        3989 : }
+     120             : 
+     121             : }
+     122             : }
+     123             : 
+     124             : 
+     125             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ExtraCV.cpp.func-sort-c.html b/coverage/colvar/ExtraCV.cpp.func-sort-c.html new file mode 100644 index 000000000000..1fadf84bb7ff --- /dev/null +++ b/coverage/colvar/ExtraCV.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ExtraCV.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ExtraCV.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7ExtraCVC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar7ExtraCVC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar7ExtraCV16registerKeywordsERNS_8KeywordsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ExtraCV.cpp.func.html b/coverage/colvar/ExtraCV.cpp.func.html new file mode 100644 index 000000000000..4bb23469b4e8 --- /dev/null +++ b/coverage/colvar/ExtraCV.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ExtraCV.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ExtraCV.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7ExtraCV16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar7ExtraCVC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar7ExtraCVC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ExtraCV.cpp.gcov.html b/coverage/colvar/ExtraCV.cpp.gcov.html new file mode 100644 index 000000000000..37156a353aad --- /dev/null +++ b/coverage/colvar/ExtraCV.cpp.gcov.html @@ -0,0 +1,155 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ExtraCV.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ExtraCV.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace colvar {
+      28             : 
+      29             : //+PLUMEDOC COLVAR EXTRACV
+      30             : /*
+      31             : Allow PLUMED to use collective variables computed in the MD engine.
+      32             : 
+      33             : This feature requires the MD engine to use special instructions to pass to PLUMED the value of
+      34             : some pre-computed collective variable. Check the documentation of the MD code to find out which
+      35             : collective variables can be computed and passed to PLUMED. These variables can then be accessed by
+      36             : name using the EXTRACV action.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : This example takes the lambda variable pre-computed in GROMACS and apply to it a restraint to keep
+      41             : it close to the value 3.
+      42             : \plumedfile
+      43             : l: EXTRACV NAME=lambda
+      44             : RESTRAINT ARG=l KAPPA=10 AT=3
+      45             : \endplumedfile
+      46             : 
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : 
+      52             : class ExtraCV : public ActionShortcut {
+      53             : public:
+      54             :   explicit ExtraCV(const ActionOptions&);
+      55             :   static void registerKeywords( Keywords& keys );
+      56             : };
+      57             : 
+      58             : PLUMED_REGISTER_ACTION(ExtraCV,"EXTRACV")
+      59             : 
+      60           3 : ExtraCV::ExtraCV(const ActionOptions&ao):
+      61             :   Action(ao),
+      62           3 :   ActionShortcut(ao)
+      63             : {
+      64           6 :   std::vector<std::string> argn(1); parse("NAME",argn[0]);
+      65           6 :   readInputLine( argn[0] + ": PUT UNIT=number SHAPE=0 MUTABLE PERIODIC=NO");
+      66           6 :   if( getShortcutLabel()!=argn[0] ) readInputLine( getShortcutLabel() + ": COMBINE ARG=" + argn[0] + " PERIODIC=NO");
+      67           3 : }
+      68             : 
+      69           5 : void ExtraCV::registerKeywords( Keywords& keys ) {
+      70           5 :   ActionShortcut::registerKeywords( keys );
+      71          10 :   keys.add("compulsory","NAME","name of the CV as computed by the MD engine");
+      72           5 : }
+      73             : 
+      74             : }
+      75             : }
+      76             : 
+      77             : 
+      78             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Fake.cpp.func-sort-c.html b/coverage/colvar/Fake.cpp.func-sort-c.html new file mode 100644 index 000000000000..86fab47e1881 --- /dev/null +++ b/coverage/colvar/Fake.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Fake.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Fake.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303781.1 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10ColvarFake9calculateEv0
_ZN4PLMD6colvar10ColvarFakeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar10ColvarFakeC1ERKNS_13ActionOptionsE17
_ZN4PLMD6colvar10ColvarFake16registerKeywordsERNS_8KeywordsE19
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Fake.cpp.func.html b/coverage/colvar/Fake.cpp.func.html new file mode 100644 index 000000000000..197531af64f6 --- /dev/null +++ b/coverage/colvar/Fake.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Fake.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Fake.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303781.1 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar10ColvarFake16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD6colvar10ColvarFake9calculateEv0
_ZN4PLMD6colvar10ColvarFakeC1ERKNS_13ActionOptionsE17
_ZN4PLMD6colvar10ColvarFakeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Fake.cpp.gcov.html b/coverage/colvar/Fake.cpp.gcov.html new file mode 100644 index 000000000000..578a00160bcc --- /dev/null +++ b/coverage/colvar/Fake.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Fake.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Fake.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303781.1 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace colvar {
+      27             : 
+      28             : //+PLUMEDOC COLVAR FAKE
+      29             : /*
+      30             : This is a fake colvar container used by cltools or various other actions that supports input and period definitions
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : \plumedfile
+      35             : FAKE ATOMS=1 PERIODIC=-3.14,3.14   LABEL=d2
+      36             : \endplumedfile
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : class ColvarFake : public Colvar {
+      42             : 
+      43             : public:
+      44             :   static void registerKeywords( Keywords& keys );
+      45             :   explicit ColvarFake(const ActionOptions&);
+      46             : // active methods:
+      47             :   void calculate() override;
+      48             : };
+      49             : 
+      50             : PLUMED_REGISTER_ACTION(ColvarFake,"FAKE")
+      51             : 
+      52          19 : void ColvarFake::registerKeywords( Keywords& keys ) {
+      53          19 :   Colvar::registerKeywords( keys );
+      54          38 :   keys.add("atoms","ATOMS","the fake atom index, a number is enough");
+      55          38 :   keys.reserve("compulsory","PERIODIC","if the output of your function is periodic then you should specify the periodicity of the function.  If the output is not periodic you must state this using PERIODIC=NO,NO (one for the lower and the other for the upper boundary). For multicomponents then it is PERIODIC=mincomp1,maxcomp1,mincomp2,maxcomp2  etc ");
+      56          19 :   keys.use("PERIODIC");
+      57          38 :   keys.add("optional","COMPONENTS","additional components that this variable is supposed to have. Periodicity is ruled by PERIODIC keyword ");
+      58          19 :   useCustomisableComponents(keys);
+      59          19 : }
+      60             : 
+      61          17 : ColvarFake::ColvarFake(const ActionOptions&ao):
+      62          17 :   PLUMED_COLVAR_INIT(ao)
+      63             : {
+      64             :   std::vector<AtomNumber> atoms;
+      65          34 :   parseAtomList("ATOMS",atoms);
+      66             : 
+      67             :   std::vector<std::string> comps;
+      68             :   // multiple components for this variable
+      69          34 :   parseVector("COMPONENTS",comps);
+      70          17 :   if(comps.size()!=0) {
+      71           2 :     for(unsigned i=0; i<comps.size(); i++) {
+      72           2 :       addComponentWithDerivatives(comps[i]);
+      73             :     }
+      74             :     // periodicity
+      75             :   } else {
+      76             :     // only one component for this variable
+      77          32 :     addValueWithDerivatives();
+      78             :   }
+      79             :   std::vector<std::string> period;
+      80          34 :   parseVector("PERIODIC",period);
+      81          17 :   if(period.size()!=0) {
+      82          17 :     plumed_massert(static_cast<unsigned>(getNumberOfComponents()*2)==period.size(),"the periodicty should coincide with the number of components");
+      83          17 :     if(comps.size()!=0) {
+      84           2 :       for(int i=0; i<getNumberOfComponents(); i++) {
+      85           1 :         std::string pp=comps[i];
+      86           1 :         if(period[i*2]!="none" && period[i*2+1]!="none" ) {
+      87           1 :           componentIsPeriodic(pp,period[i*2],period[i*2+1]);
+      88             :         } else {
+      89           0 :           componentIsNotPeriodic(pp);
+      90             :         }
+      91             :       }
+      92             :     } else {
+      93          29 :       if(period[0]!="none" && period[1]!="none" ) {
+      94          13 :         setPeriodic(period[0],period[1]);
+      95             :       } else {
+      96           3 :         setNotPeriodic();
+      97             :       }
+      98             :     }
+      99             :   } else {
+     100           0 :     if(comps.size()!=0) {
+     101           0 :       for(int i=0; i<getNumberOfComponents(); i++) {
+     102           0 :         componentIsNotPeriodic(getPntrToComponent(i)->getName());
+     103             :       }
+     104             :     } else {
+     105           0 :       setNotPeriodic();
+     106             :     }
+     107             :   }
+     108          17 :   checkRead();
+     109          17 :   requestAtoms(atoms);
+     110             : 
+     111          34 : }
+     112             : 
+     113             : 
+     114             : // calculator
+     115           0 : void ColvarFake::calculate() {
+     116           0 :   plumed_merror("you should never have got here");
+     117             : }
+     118             : 
+     119             : }
+     120             : }
+     121             : 
+     122             : 
+     123             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/GHBFIX.cpp.func-sort-c.html b/coverage/colvar/GHBFIX.cpp.func-sort-c.html new file mode 100644 index 000000000000..9e8a690586cc --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/GHBFIX.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - GHBFIX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7676100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6GHBFIXC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar6GHBFIXC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar6GHBFIX16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD6colvar6GHBFIX7pairingEdRdjj150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/GHBFIX.cpp.func.html b/coverage/colvar/GHBFIX.cpp.func.html new file mode 100644 index 000000000000..55606f70ecc2 --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/GHBFIX.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - GHBFIX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7676100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6GHBFIX16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar6GHBFIXC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar6GHBFIXC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6colvar6GHBFIX7pairingEdRdjj150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/GHBFIX.cpp.gcov.html b/coverage/colvar/GHBFIX.cpp.gcov.html new file mode 100644 index 000000000000..d5a479347711 --- /dev/null +++ b/coverage/colvar/GHBFIX.cpp.gcov.html @@ -0,0 +1,294 @@ + + + + + + + + LCOV - plumed test coverage - colvar/GHBFIX.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - GHBFIX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7676100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2021-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CoordinationBase.h"
+      23             : #include "tools/SwitchingFunction.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "tools/IFile.h"
+      27             : 
+      28             : #include <iostream>
+      29             : 
+      30             : #include <string>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace colvar {
+      34             : 
+      35             : //+PLUMEDOC COLVAR GHBFIX
+      36             : /*
+      37             : Calculate the GHBFIX interaction energy among GROUPA and GROUPB
+      38             : using a potential defined in KührovaÌ et al., Improving the performance of the AMBER RNA force field by
+      39             : tuning the hydrogen-bonding interactions, JCTC, 2019. Essentially it is a switching function being -1 for small distances and 0 for large distances with a smooth interpolation in the middle. This can be scaled as desired by specifying interaction scaling parameters and energy units.
+      40             : 
+      41             : This collective variable can be used to analyze hydrogen bond interactions, or to generate bias potentials.
+      42             : Notice that the value of the GHBFIX is returned in plumed units (see \ref UNITS), if not specified differently via ENERGY_UNITS.
+      43             : 
+      44             : \par Examples
+      45             : This example prints the GHBFIX interaction in kcal/mol between two groups of atoms using D_0, D_MAX and C
+      46             : It is applied in the functional form introduced in the pioneering paper.
+      47             : The types of atoms 1-6 should be defined in typesTable_examples.dat while their interaction parameters should be defined in scalingParameters_examples.dat in kBT units.
+      48             : 
+      49             : \plumedfile
+      50             : #SETTINGS AUXFOLDER=regtest/basic/rt-ghbfix
+      51             : gh: GHBFIX PAIR GROUPA=1,2,3 GROUP=4,5,6 D_0=0.2 D_MAX=0.3 C=0.8 TYPES=typesTable_examples.dat PARAMS=scalingParameters_examples.dat ENERGY_UNITS=kcal/mol
+      52             : PRINT FILE=output ARG=gh
+      53             : \endplumedfile
+      54             : 
+      55             : */
+      56             : //+ENDPLUMEDOC
+      57             : 
+      58             : class GHBFIX : public CoordinationBase {
+      59             : 
+      60             :   double dmax;
+      61             :   double dmax_squared;
+      62             :   double d0;
+      63             :   double c;
+      64             : 
+      65             :   std::vector<unsigned> typesTable;
+      66             : 
+      67             :   std::vector<double> etas;
+      68             : 
+      69             :   unsigned n;
+      70             : 
+      71             :   double dmax2;
+      72             :   double A;
+      73             :   double B;
+      74             :   double C;
+      75             :   double D;
+      76             : 
+      77             : public:
+      78             :   explicit GHBFIX(const ActionOptions&);
+      79             : // active methods:
+      80             :   static void registerKeywords( Keywords& keys );
+      81             :   double pairing(double distance,double&dfunc,unsigned i,unsigned j)const override;
+      82             : };
+      83             : 
+      84             : PLUMED_REGISTER_ACTION(GHBFIX,"GHBFIX")
+      85             : 
+      86           3 : void GHBFIX::registerKeywords( Keywords& keys ) {
+      87           3 :   CoordinationBase::registerKeywords(keys);
+      88             : 
+      89           6 :   keys.add("optional","ENERGY_UNITS","the value of ENERGY_UNITS in the switching function");
+      90           6 :   keys.add("compulsory","TYPES","the value of TYPES in the switching function");
+      91           6 :   keys.add("compulsory","PARAMS","the value of PARAMS in the switching function");
+      92           6 :   keys.add("compulsory","D_MAX","the value of D_MAX in the switching function");
+      93           6 :   keys.add("compulsory","D_0","the value of D_0 in the switching function");
+      94           6 :   keys.add("compulsory","C","the value of C in the switching function");
+      95           3 : }
+      96             : 
+      97           1 : GHBFIX::GHBFIX(const ActionOptions&ao):
+      98             :   Action(ao),
+      99           1 :   CoordinationBase(ao)
+     100             : {
+     101             :   std::string types;
+     102             :   std::string params;
+     103           1 :   std::string energy_units ="plumed" ;
+     104             : 
+     105           1 :   parse("D_MAX",dmax);
+     106           1 :   dmax_squared = dmax*dmax;
+     107           1 :   parse("D_0",d0);
+     108           1 :   parse("C",c);
+     109           1 :   parse("TYPES",types);
+     110           1 :   parse("PARAMS",params);
+     111           1 :   parse("ENERGY_UNITS",energy_units);
+     112             : 
+     113           1 :   dmax2 = dmax-d0;
+     114             : 
+     115           1 :   A = (-c*dmax2*dmax2)/((1-c)*dmax2*dmax2);
+     116           1 :   B = (2*dmax2)/((1-c)*dmax2*dmax2);
+     117           1 :   C = -1/((1-c)*dmax2*dmax2);
+     118           1 :   D = 1/(c*dmax2*dmax2);
+     119             : 
+     120             :   std::map<std::string,unsigned> MapTypesTable;
+     121             : 
+     122             :   //typesTable
+     123           1 :   IFile typesfile;
+     124           1 :   typesfile.link(*this);
+     125           1 :   typesfile.open(types);
+     126             :   std::string itype;
+     127           6 :   while(typesfile.scanField("itype",itype).scanField()) {
+     128           2 :     plumed_assert(itype.empty()==false)<<"itype is empty";
+     129             : 
+     130           2 :     if (MapTypesTable.empty()) {
+     131           1 :       MapTypesTable.insert({itype, 0});
+     132             :     }
+     133             :     else if (MapTypesTable.count(itype) == 0) {
+     134             :       unsigned currentMax = 0;
+     135           2 :       for(auto it = MapTypesTable.cbegin(); it != MapTypesTable.cend(); ++it ) {
+     136           1 :         if (it ->second > currentMax) {
+     137             :           currentMax = it->second;
+     138             :         }
+     139             :       }
+     140           2 :       MapTypesTable.insert({itype, currentMax+1});
+     141             :     }
+     142             : 
+     143           2 :     typesTable.push_back(MapTypesTable[itype]);
+     144             :   }
+     145             : 
+     146           1 :   n = (int)*std::max_element(std::begin(typesTable), std::end(typesTable));
+     147           1 :   n+=1;
+     148             : 
+     149             :   //scalingParameters
+     150           1 :   etas.resize(n*n,0.0);
+     151           1 :   IFile etafile;
+     152           1 :   etafile.open(params);
+     153             :   std::string it,jt;
+     154             :   double eta;
+     155          14 :   while(etafile.scanField("itype",it).scanField("jtype",jt).scanField("eta",eta).scanField()) {
+     156           6 :     plumed_assert(it.empty()==false)<<"itype is empty";
+     157           6 :     plumed_assert(jt.empty()==false)<<"jtype is empty";
+     158           6 :     etas[n*MapTypesTable[it]+MapTypesTable[jt]]=eta;
+     159             :   }
+     160             : 
+     161           1 :   if(energy_units!="plumed") {
+     162           1 :     Units units;
+     163           1 :     units.setEnergy(energy_units);
+     164           5 :     for(auto i=0; i<etas.size(); i++) etas[i]*=units.getEnergy()/getUnits().getEnergy();
+     165           1 :   }
+     166             : 
+     167           3 : }
+     168             : 
+     169             : 
+     170         150 : double GHBFIX::pairing(double distance2,double&dfunc,unsigned i,unsigned j)const {
+     171             : 
+     172         150 :   const auto i1=getAbsoluteIndex(i).index();
+     173         150 :   plumed_assert(i1<typesTable.size())<<"your types table only covers "<<typesTable.size()<<" atoms, but you are trying to access atom number "<<(i1+1);
+     174         150 :   const auto t1=typesTable[i1];
+     175             : 
+     176         150 :   const auto i2=getAbsoluteIndex(j).index();
+     177         150 :   plumed_assert(i2<typesTable.size())<<"your types table only covers "<<typesTable.size()<<" atoms, but you are trying to access atom number "<<(i2+1);
+     178         150 :   const auto t2=typesTable[i2];
+     179             : 
+     180         150 :   const double scale=etas[n*t1+t2];
+     181             : 
+     182             :   double result;
+     183         150 :   if(distance2>dmax_squared) {
+     184             :     result=0.;
+     185           1 :     dfunc=0.0;
+     186           1 :     return result;
+     187             :   }
+     188         149 :   double distance=std::sqrt(distance2);
+     189         149 :   const double rdist = (distance-d0);
+     190             : 
+     191         149 :   if(rdist<=0.) {
+     192             :     result=-1.;
+     193         100 :     dfunc=0.0;
+     194             :   } else {
+     195             :     result=-1.;
+     196          49 :     dfunc=0.0;
+     197             : 
+     198          49 :     if (rdist > c*dmax2) {
+     199           9 :       result+=(A + B*rdist + C*rdist*rdist);
+     200           9 :       dfunc+=B+2*C*rdist;
+     201          40 :     } else if (rdist > 0.0) {
+     202          40 :       result+=D*(rdist*rdist);
+     203          40 :       dfunc+=2*D*rdist;
+     204             :     }
+     205             : 
+     206          49 :     dfunc/=distance;
+     207             :   }
+     208             : 
+     209         149 :   result*=scale;
+     210         149 :   dfunc*=scale;
+     211             : 
+     212         149 :   return result;
+     213             : }
+     214             : 
+     215             : }
+     216             : 
+     217             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Gyration.cpp.func-sort-c.html b/coverage/colvar/Gyration.cpp.func-sort-c.html new file mode 100644 index 000000000000..90e7a06ab684 --- /dev/null +++ b/coverage/colvar/Gyration.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Gyration.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Gyration.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14218377.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8GyrationC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8GyrationC1ERKNS_13ActionOptionsE33
_ZN4PLMD6colvar8Gyration16registerKeywordsERNS_8KeywordsE35
_ZN4PLMD6colvar8Gyration9calculateEv1195
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Gyration.cpp.func.html b/coverage/colvar/Gyration.cpp.func.html new file mode 100644 index 000000000000..b9ed1741b989 --- /dev/null +++ b/coverage/colvar/Gyration.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Gyration.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Gyration.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14218377.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8Gyration16registerKeywordsERNS_8KeywordsE35
_ZN4PLMD6colvar8Gyration9calculateEv1195
_ZN4PLMD6colvar8GyrationC1ERKNS_13ActionOptionsE33
_ZN4PLMD6colvar8GyrationC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Gyration.cpp.gcov.html b/coverage/colvar/Gyration.cpp.gcov.html new file mode 100644 index 000000000000..da818850777c --- /dev/null +++ b/coverage/colvar/Gyration.cpp.gcov.html @@ -0,0 +1,447 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Gyration.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Gyration.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14218377.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace colvar {
+      28             : 
+      29             : //+PLUMEDOC COLVAR GYRATION
+      30             : /*
+      31             : Calculate the radius of gyration, or other properties related to it.
+      32             : 
+      33             : The different properties can be calculated and selected by the TYPE keyword:
+      34             : the Radius of Gyration (RADIUS); the Trace of the Gyration Tensor (TRACE);
+      35             : the Largest Principal Moment of the Gyration Tensor (GTPC_1); the middle Principal Moment of the Gyration Tensor (GTPC_2);
+      36             : the Smallest Principal Moment of the Gyration Tensor (GTPC_3); the Asphericiry (ASPHERICITY); the Acylindricity (ACYLINDRICITY);
+      37             : the Relative Shape Anisotropy (KAPPA2); the Smallest Principal Radius Of Gyration (GYRATION_3);
+      38             : the Middle Principal Radius of Gyration (GYRATION_2); the Largest Principal Radius of Gyration (GYRATION_1).
+      39             : A derivation of all these different variants can be found in \cite Vymetal:2011gv
+      40             : 
+      41             : The radius of gyration is calculated using:
+      42             : 
+      43             : \f[
+      44             : s_{\rm Gyr}=\Big ( \frac{\sum_i^{n}
+      45             :  m_i \vert {r}_i -{r}_{\rm COM} \vert ^2 }{\sum_i^{n} m_i} \Big)^{1/2}
+      46             : \f]
+      47             : 
+      48             : with the position of the center of mass \f${r}_{\rm COM}\f$ given by:
+      49             : 
+      50             : \f[
+      51             : {r}_{\rm COM}=\frac{\sum_i^{n} {r}_i\ m_i }{\sum_i^{n} m_i}
+      52             : \f]
+      53             : 
+      54             : The radius of gyration usually makes sense when atoms used for the calculation
+      55             : are all part of the same molecule.
+      56             : When running with periodic boundary conditions, the atoms should be
+      57             : in the proper periodic image. This is done automatically since PLUMED 2.2,
+      58             : by considering the ordered list of atoms and rebuilding the broken entities using a procedure
+      59             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+      60             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+      61             : which actually modifies the coordinates stored in PLUMED.
+      62             : 
+      63             : In case you want to recover the old behavior you should use the NOPBC flag.
+      64             : In that case you need to take care that atoms are in the correct
+      65             : periodic image.
+      66             : 
+      67             : 
+      68             : \par Examples
+      69             : 
+      70             : The following input tells plumed to print the radius of gyration of the
+      71             : chain containing atoms 10 to 20.
+      72             : \plumedfile
+      73             : GYRATION TYPE=RADIUS ATOMS=10-20 LABEL=rg
+      74             : PRINT ARG=rg STRIDE=1 FILE=colvar
+      75             : \endplumedfile
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : class Gyration : public Colvar {
+      81             : private:
+      82             :   enum CV_TYPE {RADIUS, TRACE, GTPC_1, GTPC_2, GTPC_3, ASPHERICITY, ACYLINDRICITY, KAPPA2, GYRATION_3, GYRATION_2, GYRATION_1, TOT};
+      83             :   int rg_type;
+      84             :   bool use_masses;
+      85             :   bool nopbc;
+      86             :   std::vector<Vector> derivatives;
+      87             : public:
+      88             :   static void registerKeywords(Keywords& keys);
+      89             :   explicit Gyration(const ActionOptions&);
+      90             :   void calculate() override;
+      91             : };
+      92             : 
+      93             : PLUMED_REGISTER_ACTION(Gyration,"GYRATION")
+      94             : 
+      95          35 : void Gyration::registerKeywords(Keywords& keys) {
+      96          35 :   Colvar::registerKeywords(keys);
+      97          70 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the Gyration Tensor for");
+      98          70 :   keys.add("compulsory","TYPE","RADIUS","The type of calculation relative to the Gyration Tensor you want to perform");
+      99          70 :   keys.addFlag("MASS_WEIGHTED",false,"set the masses of all the atoms equal to one");
+     100          35 : }
+     101             : 
+     102          33 : Gyration::Gyration(const ActionOptions&ao):
+     103             :   PLUMED_COLVAR_INIT(ao),
+     104          33 :   use_masses(false),
+     105          33 :   nopbc(false)
+     106             : {
+     107             :   std::vector<AtomNumber> atoms;
+     108          65 :   parseAtomList("ATOMS",atoms);
+     109          32 :   if(atoms.size()==0) error("no atoms specified");
+     110          66 :   parseFlag("MASS_WEIGHTED",use_masses);
+     111             :   std::string Type;
+     112          32 :   parse("TYPE",Type);
+     113          32 :   parseFlag("NOPBC",nopbc);
+     114          32 :   checkRead();
+     115             : 
+     116          32 :   if(Type=="RADIUS") rg_type=RADIUS;
+     117          21 :   else if(Type=="TRACE") rg_type=TRACE;
+     118          19 :   else if(Type=="GTPC_1") rg_type=GTPC_1;
+     119          17 :   else if(Type=="GTPC_2") rg_type=GTPC_2;
+     120          15 :   else if(Type=="GTPC_3") rg_type=GTPC_3;
+     121          13 :   else if(Type=="ASPHERICITY") rg_type=ASPHERICITY;
+     122          11 :   else if(Type=="ACYLINDRICITY") rg_type=ACYLINDRICITY;
+     123           9 :   else if(Type=="KAPPA2") rg_type=KAPPA2;
+     124           7 :   else if(Type=="RGYR_3") rg_type=GYRATION_3;
+     125           5 :   else if(Type=="RGYR_2") rg_type=GYRATION_2;
+     126           3 :   else if(Type=="RGYR_1") rg_type=GYRATION_1;
+     127           1 :   else error("Unknown GYRATION type");
+     128             : 
+     129          31 :   switch(rg_type)
+     130             :   {
+     131          11 :   case RADIUS:   log.printf("  GYRATION RADIUS (Rg);"); break;
+     132           2 :   case TRACE:  log.printf("  TRACE OF THE GYRATION TENSOR;"); break;
+     133           2 :   case GTPC_1: log.printf("  THE LARGEST PRINCIPAL MOMENT OF THE GYRATION TENSOR (S'_1);"); break;
+     134           2 :   case GTPC_2: log.printf("  THE MIDDLE PRINCIPAL MOMENT OF THE GYRATION TENSOR (S'_2);");  break;
+     135           2 :   case GTPC_3: log.printf("  THE SMALLEST PRINCIPAL MOMENT OF THE GYRATION TENSOR (S'_3);"); break;
+     136           2 :   case ASPHERICITY: log.printf("  THE ASPHERICITY (b');"); break;
+     137           2 :   case ACYLINDRICITY: log.printf("  THE ACYLINDRICITY (c');"); break;
+     138           2 :   case KAPPA2: log.printf("  THE RELATIVE SHAPE ANISOTROPY (kappa^2);"); break;
+     139           2 :   case GYRATION_3: log.printf("  THE SMALLEST PRINCIPAL RADIUS OF GYRATION (r_g3);"); break;
+     140           2 :   case GYRATION_2: log.printf("  THE MIDDLE PRINCIPAL RADIUS OF GYRATION (r_g2);"); break;
+     141           2 :   case GYRATION_1: log.printf("  THE LARGEST PRINCIPAL RADIUS OF GYRATION (r_g1);"); break;
+     142             :   }
+     143          49 :   if(rg_type>TRACE) log<<"  Bibliography "<<plumed.cite("JiriÌ Vymetal and JiriÌ Vondrasek, J. Phys. Chem. A 115, 11455 (2011)");
+     144          31 :   log<<"\n";
+     145             : 
+     146          31 :   log.printf("  atoms involved : ");
+     147         233 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial());
+     148          31 :   log.printf("\n");
+     149             : 
+     150          31 :   if(nopbc) {
+     151           4 :     log<<"  PBC will be ignored\n";
+     152             :   } else {
+     153          27 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     154             :   }
+     155             : 
+     156          63 :   addValueWithDerivatives(); setNotPeriodic();
+     157          31 :   requestAtoms(atoms);
+     158          35 : }
+     159             : 
+     160        1195 : void Gyration::calculate() {
+     161             : 
+     162        1195 :   if(!nopbc) makeWhole();
+     163             : 
+     164        1195 :   Vector com;
+     165             :   double totmass = 0.;
+     166        1195 :   if( use_masses ) {
+     167           0 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     168           0 :       totmass+=getMass(i);
+     169           0 :       com+=getMass(i)*getPosition(i);
+     170             :     }
+     171             :   } else {
+     172        1195 :     totmass = static_cast<double>(getNumberOfAtoms());
+     173       10373 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     174        9178 :       com+=getPosition(i);
+     175             :     }
+     176             :   }
+     177        1195 :   com /= totmass;
+     178             : 
+     179        1195 :   double rgyr=0.;
+     180        1195 :   derivatives.resize(getNumberOfAtoms());
+     181             : 
+     182        1195 :   if(rg_type==RADIUS||rg_type==TRACE) {
+     183         795 :     if( use_masses ) {
+     184           0 :       for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     185           0 :         const Vector diff = delta( com, getPosition(i) );
+     186           0 :         rgyr          += getMass(i)*diff.modulo2();
+     187           0 :         derivatives[i] = diff*getMass(i);
+     188             :       }
+     189             :     } else {
+     190        7973 :       for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     191        7178 :         const Vector diff = delta( com, getPosition(i) );
+     192        7178 :         rgyr          += diff.modulo2();
+     193        7178 :         derivatives[i] = diff;
+     194             :       }
+     195             :     }
+     196             :     double fact;
+     197         795 :     if(rg_type==RADIUS) {
+     198         665 :       rgyr = std::sqrt(rgyr/totmass);
+     199         665 :       fact = 1./(rgyr*totmass);
+     200             :     } else {
+     201         130 :       rgyr = 2.*rgyr;
+     202             :       fact = 4;
+     203             :     }
+     204         795 :     setValue(rgyr);
+     205        7973 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) setAtomsDerivatives(i,fact*derivatives[i]);
+     206         795 :     setBoxDerivativesNoPbc();
+     207         795 :     return;
+     208             :   }
+     209             : 
+     210             : 
+     211         400 :   Tensor3d gyr_tens;
+     212             :   //calculate gyration tensor
+     213         400 :   if( use_masses ) {
+     214           0 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     215           0 :       const Vector diff=delta( com, getPosition(i) );
+     216           0 :       gyr_tens[0][0]+=getMass(i)*diff[0]*diff[0];
+     217           0 :       gyr_tens[1][1]+=getMass(i)*diff[1]*diff[1];
+     218           0 :       gyr_tens[2][2]+=getMass(i)*diff[2]*diff[2];
+     219           0 :       gyr_tens[0][1]+=getMass(i)*diff[0]*diff[1];
+     220           0 :       gyr_tens[0][2]+=getMass(i)*diff[0]*diff[2];
+     221           0 :       gyr_tens[1][2]+=getMass(i)*diff[1]*diff[2];
+     222             :     }
+     223             :   } else {
+     224        2400 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     225        2000 :       const Vector diff=delta( com, getPosition(i) );
+     226        2000 :       gyr_tens[0][0]+=diff[0]*diff[0];
+     227        2000 :       gyr_tens[1][1]+=diff[1]*diff[1];
+     228        2000 :       gyr_tens[2][2]+=diff[2]*diff[2];
+     229        2000 :       gyr_tens[0][1]+=diff[0]*diff[1];
+     230        2000 :       gyr_tens[0][2]+=diff[0]*diff[2];
+     231        2000 :       gyr_tens[1][2]+=diff[1]*diff[2];
+     232             :     }
+     233             :   }
+     234             : 
+     235             :   // first make the matrix symmetric
+     236         400 :   gyr_tens[1][0] = gyr_tens[0][1];
+     237         400 :   gyr_tens[2][0] = gyr_tens[0][2];
+     238         400 :   gyr_tens[2][1] = gyr_tens[1][2];
+     239         400 :   Tensor3d ttransf,transf;
+     240         400 :   Vector princ_comp,prefactor;
+     241             :   //diagonalize gyration tensor
+     242         400 :   diagMatSym(gyr_tens, princ_comp, ttransf);
+     243         400 :   transf=transpose(ttransf);
+     244             :   //sort eigenvalues and eigenvectors
+     245         400 :   if (princ_comp[0]<princ_comp[1]) {
+     246         400 :     double tmp=princ_comp[0]; princ_comp[0]=princ_comp[1]; princ_comp[1]=tmp;
+     247        1600 :     for (unsigned i=0; i<3; i++) {tmp=transf[i][0]; transf[i][0]=transf[i][1]; transf[i][1]=tmp;}
+     248             :   }
+     249         400 :   if (princ_comp[1]<princ_comp[2]) {
+     250         400 :     double tmp=princ_comp[1]; princ_comp[1]=princ_comp[2]; princ_comp[2]=tmp;
+     251        1600 :     for (unsigned i=0; i<3; i++) {tmp=transf[i][1]; transf[i][1]=transf[i][2]; transf[i][2]=tmp;}
+     252             :   }
+     253         400 :   if (princ_comp[0]<princ_comp[1]) {
+     254         400 :     double tmp=princ_comp[0]; princ_comp[0]=princ_comp[1]; princ_comp[1]=tmp;
+     255        1600 :     for (unsigned i=0; i<3; i++) {tmp=transf[i][0]; transf[i][0]=transf[i][1]; transf[i][1]=tmp;}
+     256             :   }
+     257             :   //calculate determinant of transformation matrix
+     258             :   double det = determinant(transf);
+     259             :   // transformation matrix for rotation must have positive determinant, otherwise multiply one column by (-1)
+     260         400 :   if(det<0) {
+     261        1600 :     for(unsigned j=0; j<3; j++) transf[j][2]=-transf[j][2];
+     262         400 :     det = -det;
+     263             :   }
+     264         400 :   if(std::abs(det-1.)>0.0001) error("Plumed Error: Cannot diagonalize gyration tensor\n");
+     265         400 :   switch(rg_type) {
+     266         135 :   case GTPC_1:
+     267             :   case GTPC_2:
+     268             :   case GTPC_3:
+     269             :   {
+     270         135 :     int pc_index = rg_type-2; //index of principal component
+     271         135 :     rgyr=std::sqrt(princ_comp[pc_index]/totmass);
+     272         135 :     double rm = rgyr*totmass;
+     273         135 :     if(rm>1e-6) prefactor[pc_index]=1.0/rm; //some parts of derivate
+     274             :     break;
+     275             :   }
+     276           0 :   case GYRATION_3:        //the smallest principal radius of gyration
+     277             :   {
+     278           0 :     rgyr=std::sqrt((princ_comp[1]+princ_comp[2])/totmass);
+     279           0 :     double rm = rgyr*totmass;
+     280           0 :     if (rm>1e-6) {
+     281           0 :       prefactor[1]=1.0/rm;
+     282           0 :       prefactor[2]=1.0/rm;
+     283             :     }
+     284             :     break;
+     285             :   }
+     286         130 :   case GYRATION_2:       //the midle principal radius of gyration
+     287             :   {
+     288         130 :     rgyr=std::sqrt((princ_comp[0]+princ_comp[2])/totmass);
+     289         130 :     double rm = rgyr*totmass;
+     290         130 :     if (rm>1e-6) {
+     291         130 :       prefactor[0]=1.0/rm;
+     292         130 :       prefactor[2]=1.0/rm;
+     293             :     }
+     294             :     break;
+     295             :   }
+     296           0 :   case GYRATION_1:      //the largest principal radius of gyration
+     297             :   {
+     298           0 :     rgyr=std::sqrt((princ_comp[0]+princ_comp[1])/totmass);
+     299           0 :     double rm = rgyr*totmass;
+     300           0 :     if (rm>1e-6) {
+     301           0 :       prefactor[0]=1.0/rm;
+     302           0 :       prefactor[1]=1.0/rm;
+     303             :     }
+     304             :     break;
+     305             :   }
+     306           5 :   case ASPHERICITY:
+     307             :   {
+     308           5 :     rgyr=std::sqrt((princ_comp[0]-0.5*(princ_comp[1]+princ_comp[2]))/totmass);
+     309           5 :     double rm = rgyr*totmass;
+     310           5 :     if (rm>1e-6) {
+     311           5 :       prefactor[0]= 1.0/rm;
+     312           5 :       prefactor[1]=-0.5/rm;
+     313           5 :       prefactor[2]=-0.5/rm;
+     314             :     }
+     315             :     break;
+     316             :   }
+     317           0 :   case ACYLINDRICITY:
+     318             :   {
+     319           0 :     rgyr=std::sqrt((princ_comp[1]-princ_comp[2])/totmass);
+     320           0 :     double rm = rgyr*totmass;
+     321           0 :     if (rm>1e-6) {  //avoid division by zero
+     322           0 :       prefactor[1]= 1.0/rm;
+     323           0 :       prefactor[2]=-1.0/rm;
+     324             :     }
+     325             :     break;
+     326             :   }
+     327         130 :   case KAPPA2: // relative shape anisotropy
+     328             :   {
+     329         130 :     double trace = princ_comp[0]+princ_comp[1]+princ_comp[2];
+     330         130 :     double tmp=princ_comp[0]*princ_comp[1]+ princ_comp[1]*princ_comp[2]+ princ_comp[0]*princ_comp[2];
+     331         130 :     rgyr=1.0-3*(tmp/(trace*trace));
+     332         130 :     if (rgyr>1e-6) {
+     333         130 :       prefactor[0]= -3*((princ_comp[1]+princ_comp[2])-2*tmp/trace)/(trace*trace) *2;
+     334         130 :       prefactor[1]= -3*((princ_comp[0]+princ_comp[2])-2*tmp/trace)/(trace*trace) *2;
+     335         130 :       prefactor[2]= -3*((princ_comp[0]+princ_comp[1])-2*tmp/trace)/(trace*trace) *2;
+     336             :     }
+     337             :     break;
+     338             :   }
+     339             :   }
+     340             : 
+     341         400 :   if(use_masses) {
+     342           0 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     343           0 :       Vector tX;
+     344           0 :       const Vector diff=delta( com,getPosition(i) );
+     345             :       //project atomic postional vectors to diagonalized frame
+     346           0 :       for(unsigned j=0; j<3; j++) tX[j]=transf[0][j]*diff[0]+transf[1][j]*diff[1]+transf[2][j]*diff[2];
+     347           0 :       for(unsigned j=0; j<3; j++) derivatives[i][j]=getMass(i)*(prefactor[0]*transf[j][0]*tX[0]+
+     348           0 :             prefactor[1]*transf[j][1]*tX[1]+
+     349           0 :             prefactor[2]*transf[j][2]*tX[2]);
+     350           0 :       setAtomsDerivatives(i,derivatives[i]);
+     351             :     }
+     352             :   } else {
+     353        2400 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     354        2000 :       Vector tX;
+     355        2000 :       const Vector diff=delta( com,getPosition(i) );
+     356             :       //project atomic postional vectors to diagonalized frame
+     357        8000 :       for(unsigned j=0; j<3; j++) tX[j]=transf[0][j]*diff[0]+transf[1][j]*diff[1]+transf[2][j]*diff[2];
+     358        8000 :       for(unsigned j=0; j<3; j++) derivatives[i][j]=prefactor[0]*transf[j][0]*tX[0]+
+     359        6000 :             prefactor[1]*transf[j][1]*tX[1]+
+     360        6000 :             prefactor[2]*transf[j][2]*tX[2];
+     361        2000 :       setAtomsDerivatives(i,derivatives[i]);
+     362             :     }
+     363             :   }
+     364             : 
+     365         400 :   setValue(rgyr);
+     366         400 :   setBoxDerivativesNoPbc();
+     367             : }
+     368             : 
+     369             : }
+     370             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/MultiRMSD.cpp.func-sort-c.html b/coverage/colvar/MultiRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..d6ce3f4d460a --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/MultiRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - MultiRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:414297.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar9MultiRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar9MultiRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar9MultiRMSD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar9MultiRMSD9calculateEv15
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/MultiRMSD.cpp.func.html b/coverage/colvar/MultiRMSD.cpp.func.html new file mode 100644 index 000000000000..479d796f8607 --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/MultiRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - MultiRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:414297.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar9MultiRMSD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6colvar9MultiRMSD9calculateEv15
_ZN4PLMD6colvar9MultiRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6colvar9MultiRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/MultiRMSD.cpp.gcov.html b/coverage/colvar/MultiRMSD.cpp.gcov.html new file mode 100644 index 000000000000..a5f74743aa89 --- /dev/null +++ b/coverage/colvar/MultiRMSD.cpp.gcov.html @@ -0,0 +1,286 @@ + + + + + + + + LCOV - plumed test coverage - colvar/MultiRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - MultiRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:414297.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/PDB.h"
+      26             : #include "reference/MultiDomainRMSD.h"
+      27             : #include "reference/MetricRegister.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace colvar {
+      31             : 
+      32             : class MultiRMSD : public Colvar {
+      33             : 
+      34             :   std::unique_ptr<PLMD::MultiDomainRMSD> rmsd;
+      35             :   bool squared;
+      36             :   MultiValue myvals;
+      37             :   ReferenceValuePack mypack;
+      38             :   bool nopbc;
+      39             : 
+      40             : public:
+      41             :   explicit MultiRMSD(const ActionOptions&);
+      42             :   void calculate() override;
+      43             :   static void registerKeywords(Keywords& keys);
+      44             : };
+      45             : 
+      46             : //+PLUMEDOC DCOLVAR MULTI_RMSD
+      47             : /*
+      48             : Calculate the RMSD distance moved by a number of separated domains from their positions in a reference structure.
+      49             : 
+      50             : 
+      51             : When you have large proteins the calculation of the root mean squared deviation between all the atoms in a reference
+      52             : structure and the instantaneous configuration becomes prohibitively expensive.  You may thus instead want to calculate
+      53             : the RMSD between the atoms in a set of domains of your protein and your reference structure.  That is to say:
+      54             : 
+      55             : \f[
+      56             : d(X,X_r) = \sqrt{ \sum_{i} w_i\vert X_i - X_i' \vert^2 }
+      57             : \f]
+      58             : 
+      59             : where here the sum is over the domains of the protein, \f$X_i\f$ represents the positions of the atoms in domain \f$i\f$
+      60             : in the instantaneous configuration and \f$X_i'\f$ is the positions of the atoms in domain \f$i\f$ in the reference
+      61             : configuration.  \f$w_i\f$ is an optional weight.
+      62             : 
+      63             : The distances for each of the domains in the above sum can be calculated using the \ref DRMSD or \ref RMSD measures or
+      64             : using a combination of these distance.  The reference configuration is specified in a pdb file like the one below:
+      65             : 
+      66             : \auxfile{file1.pdb}
+      67             : ATOM      2  O   ALA     2      -0.926  -2.447  -0.497  1.00  1.00      DIA  O
+      68             : ATOM      4  HNT ALA     2       0.533  -0.396   1.184  1.00  1.00      DIA  H
+      69             : ATOM      6  HT1 ALA     2      -0.216  -2.590   1.371  1.00  1.00      DIA  H
+      70             : ATOM      7  HT2 ALA     2      -0.309  -1.255   2.315  1.00  1.00      DIA  H
+      71             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      72             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      73             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      74             : TER
+      75             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      76             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      77             : ATOM     16  HN  ALA     2       1.713   1.021  -0.873  1.00  1.00      DIA  H
+      78             : ATOM     18  HA  ALA     2       0.099  -0.774  -2.218  1.00  1.00      DIA  H
+      79             : ATOM     19  CB  ALA     2       2.063  -1.223  -1.276  1.00  1.00      DIA  C
+      80             : ATOM     20  HB1 ALA     2       2.670  -0.716  -2.057  1.00  1.00      DIA  H
+      81             : ATOM     21  HB2 ALA     2       2.556  -1.051  -0.295  1.00  1.00      DIA  H
+      82             : ATOM     22  HB3 ALA     2       2.070  -2.314  -1.490  1.00  1.00      DIA  H
+      83             : END
+      84             : \endauxfile
+      85             : 
+      86             : with the TER keyword being used to separate the various domains in you protein.
+      87             : 
+      88             : 
+      89             : \par Examples
+      90             : 
+      91             : The following tells plumed to calculate the RMSD distance between
+      92             : the positions of the atoms in the reference file and their instantaneous
+      93             : position.  The Kearsley algorithm for each of the domains.
+      94             : 
+      95             : \plumedfile
+      96             : MULTI_RMSD REFERENCE=file1.pdb TYPE=MULTI-OPTIMAL
+      97             : \endplumedfile
+      98             : 
+      99             : The following tells plumed to calculate the RMSD distance between the positions of
+     100             : the atoms in the domains of reference the reference structure and their instantaneous
+     101             : positions.  Here distances are calculated using the \ref DRMSD measure.
+     102             : 
+     103             : \plumedfile
+     104             : MULTI_RMSD REFERENCE=file1.pdb TYPE=MULTI-DRMSD
+     105             : \endplumedfile
+     106             : 
+     107             : in this case it is possible to use the following DRMSD options in the pdb file using the REMARK syntax:
+     108             : \verbatim
+     109             : NOPBC to calculate distances without PBC
+     110             : LOWER_CUTOFF=# only pairs of atoms further than LOWER_CUTOFF are considered in the calculation
+     111             : UPPER_CUTOFF=# only pairs of atoms further than UPPER_CUTOFF are considered in the calculation
+     112             : \endverbatim
+     113             : as shown in the following example
+     114             : 
+     115             : \auxfile{file2.pdb}
+     116             : REMARK NOPBC
+     117             : REMARK LOWER_CUTOFF=0.1
+     118             : REMARK UPPER_CUTOFF=0.8
+     119             : ATOM      2  O   ALA     2      -0.926  -2.447  -0.497  1.00  1.00      DIA  O
+     120             : ATOM      4  HNT ALA     2       0.533  -0.396   1.184  1.00  1.00      DIA  H
+     121             : ATOM      6  HT1 ALA     2      -0.216  -2.590   1.371  1.00  1.00      DIA  H
+     122             : ATOM      7  HT2 ALA     2      -0.309  -1.255   2.315  1.00  1.00      DIA  H
+     123             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+     124             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+     125             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+     126             : TER
+     127             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+     128             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+     129             : ATOM     16  HN  ALA     2       1.713   1.021  -0.873  1.00  1.00      DIA  H
+     130             : ATOM     18  HA  ALA     2       0.099  -0.774  -2.218  1.00  1.00      DIA  H
+     131             : ATOM     19  CB  ALA     2       2.063  -1.223  -1.276  1.00  1.00      DIA  C
+     132             : ATOM     20  HB1 ALA     2       2.670  -0.716  -2.057  1.00  1.00      DIA  H
+     133             : ATOM     21  HB2 ALA     2       2.556  -1.051  -0.295  1.00  1.00      DIA  H
+     134             : ATOM     22  HB3 ALA     2       2.070  -2.314  -1.490  1.00  1.00      DIA  H
+     135             : END
+     136             : \endauxfile
+     137             : 
+     138             : 
+     139             : */
+     140             : //+ENDPLUMEDOC
+     141             : 
+     142             : PLUMED_REGISTER_ACTION(MultiRMSD,"MULTI_RMSD")
+     143             : 
+     144           5 : void MultiRMSD::registerKeywords(Keywords& keys) {
+     145           5 :   Colvar::registerKeywords(keys);
+     146          10 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     147          10 :   keys.add("compulsory","TYPE","MULTI-SIMPLE","the manner in which RMSD alignment is performed.  Should be MULTI-OPTIMAL, MULTI-OPTIMAL-FAST,  MULTI-SIMPLE or MULTI-DRMSD.");
+     148          10 :   keys.addFlag("SQUARED",false," This should be set if you want the mean squared displacement instead of the root mean squared displacement");
+     149           5 : }
+     150             : 
+     151           3 : MultiRMSD::MultiRMSD(const ActionOptions&ao):
+     152           3 :   PLUMED_COLVAR_INIT(ao),squared(false),myvals(1,0), mypack(0,0,myvals),nopbc(false)
+     153             : {
+     154             :   std::string reference;
+     155           6 :   parse("REFERENCE",reference);
+     156             :   std::string type;
+     157           3 :   type.assign("SIMPLE");
+     158           3 :   parse("TYPE",type);
+     159           3 :   parseFlag("SQUARED",squared);
+     160           3 :   parseFlag("NOPBC",nopbc);
+     161           3 :   checkRead();
+     162             : 
+     163           6 :   addValueWithDerivatives(); setNotPeriodic();
+     164           3 :   PDB pdb;
+     165             : 
+     166             :   // read everything in ang and transform to nm if we are not in natural units
+     167           3 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     168           0 :     error("missing input file " + reference );
+     169             : 
+     170           6 :   rmsd=metricRegister().create<MultiDomainRMSD>(type,pdb);
+     171             :   // Do not align molecule if we are doing DRMSD for domains and NOPBC has been specified in input
+     172           6 :   if( pdb.hasFlag("NOPBC") ) nopbc=true;
+     173             : 
+     174             :   std::vector<AtomNumber> atoms;
+     175           3 :   rmsd->getAtomRequests( atoms );
+     176           3 :   requestAtoms( atoms );
+     177             : 
+     178           3 :   myvals.resize( 1, 3*atoms.size()+9 ); mypack.resize( 0, atoms.size() );
+     179          48 :   for(unsigned i=0; i<atoms.size(); ++i) mypack.setAtomIndex( i, i );
+     180             : 
+     181           3 :   log.printf("  reference from file %s\n",reference.c_str());
+     182           3 :   log.printf("  which contains %d atoms\n",getNumberOfAtoms());
+     183           3 :   log.printf("  with indices : ");
+     184          48 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     185          45 :     if(i%25==0) log<<"\n";
+     186          45 :     log.printf("%d ",atoms[i].serial());
+     187             :   }
+     188           3 :   log.printf("\n");
+     189           3 :   log.printf("  method for alignment : %s \n",type.c_str() );
+     190           3 :   if(squared)log.printf("  chosen to use SQUARED option for MSD instead of RMSD\n");
+     191           6 : }
+     192             : 
+     193             : // calculator
+     194          15 : void MultiRMSD::calculate() {
+     195          15 :   if(!nopbc) makeWhole();
+     196          15 :   double r=rmsd->calculate( getPositions(), getPbc(), mypack, squared );
+     197             : 
+     198          15 :   setValue(r);
+     199         240 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) setAtomsDerivatives( i, mypack.getAtomDerivative(i) );
+     200             : 
+     201          15 :   if( !mypack.virialWasSet() ) setBoxDerivativesNoPbc();
+     202          10 :   else setBoxDerivatives( mypack.getBoxDerivatives() );
+     203          15 : }
+     204             : 
+     205             : }
+     206             : }
+     207             : 
+     208             : 
+     209             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PCARMSD.cpp.func-sort-c.html b/coverage/colvar/PCARMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..f87c07849eb1 --- /dev/null +++ b/coverage/colvar/PCARMSD.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PCARMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PCARMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:939498.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7PCARMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar7PCARMSDC1ERKNS_13ActionOptionsE2
_ZZN4PLMD6colvar7PCARMSDC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_2
_ZN4PLMD6colvar7PCARMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar7PCARMSD9calculateEv1092
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PCARMSD.cpp.func.html b/coverage/colvar/PCARMSD.cpp.func.html new file mode 100644 index 000000000000..899575e6cfa2 --- /dev/null +++ b/coverage/colvar/PCARMSD.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PCARMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PCARMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:939498.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7PCARMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6colvar7PCARMSD9calculateEv1092
_ZN4PLMD6colvar7PCARMSDC1ERKNS_13ActionOptionsE2
_ZN4PLMD6colvar7PCARMSDC2ERKNS_13ActionOptionsE0
_ZZN4PLMD6colvar7PCARMSDC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PCARMSD.cpp.gcov.html b/coverage/colvar/PCARMSD.cpp.gcov.html new file mode 100644 index 000000000000..d760b0b1d078 --- /dev/null +++ b/coverage/colvar/PCARMSD.cpp.gcov.html @@ -0,0 +1,343 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PCARMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PCARMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:939498.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/PDB.h"
+      26             : #include "tools/RMSD.h"
+      27             : #include "tools/Tools.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace colvar {
+      31             : 
+      32             : class PCARMSD : public Colvar {
+      33             : 
+      34             :   std::unique_ptr<PLMD::RMSD> rmsd;
+      35             :   bool squared;
+      36             :   bool nopbc;
+      37             :   std::vector< std::vector<Vector> > eigenvectors;
+      38             :   std::vector<PDB> pdbv;
+      39             :   std::vector<std::string> pca_names;
+      40             : public:
+      41             :   explicit PCARMSD(const ActionOptions&);
+      42             :   void calculate() override;
+      43             :   static void registerKeywords(Keywords& keys);
+      44             : };
+      45             : 
+      46             : //+PLUMEDOC DCOLVAR PCARMSD
+      47             : /*
+      48             : Calculate the PCA components for a number of provided eigenvectors and an average structure.
+      49             : 
+      50             : For information on this method ( see \cite Sutto:2010 and \cite spiwok ). Performs optimal alignment at every step and reports the rmsd so you know if you are far or close from the average structure.
+      51             : It takes the average structure and eigenvectors in form of a pdb.
+      52             : Note that beta and occupancy values in the pdb are neglected and all the weights are placed to 1 (differently from the RMSD colvar for example)
+      53             : 
+      54             : \par Examples
+      55             : 
+      56             : \plumedfile
+      57             : PCARMSD AVERAGE=file.pdb EIGENVECTORS=eigenvectors.pdb
+      58             : \endplumedfile
+      59             : 
+      60             : The input is taken so to be compatible with the output you get from g_covar utility of gromacs (suitably adapted to have a pdb input format).
+      61             : The reference configuration (file.pdb) will thus be in a file that looks something like this:
+      62             : 
+      63             : \auxfile{file.pdb}
+      64             : TITLE     Average structure
+      65             : MODEL        1
+      66             : ATOM      1  CL  ALA     1       1.042  -3.070   0.946  1.00  0.00
+      67             : ATOM      5  CLP ALA     1       0.416  -2.033   0.132  1.00  0.00
+      68             : ATOM      6  OL  ALA     1       0.415  -2.082  -0.976  1.00  0.00
+      69             : ATOM      7  NL  ALA     1      -0.134  -1.045   0.677  1.00  0.00
+      70             : ATOM      9  CA  ALA     1      -0.774   0.053   0.003  1.00  0.00
+      71             : TER
+      72             : ENDMDL
+      73             : \endauxfile
+      74             : 
+      75             : while the eigenvectors will be in a pdb file (eigenvectors.pdb) that looks something like this:
+      76             : 
+      77             : \auxfile{eigenvectors.pdb}
+      78             : TITLE     frame t= -1.000
+      79             : MODEL        1
+      80             : ATOM      1  CL  ALA     1       1.194  -2.988   0.724  1.00  0.00
+      81             : ATOM      5  CLP ALA     1      -0.996   0.042   0.144  1.00  0.00
+      82             : ATOM      6  OL  ALA     1      -1.246  -0.178  -0.886  1.00  0.00
+      83             : ATOM      7  NL  ALA     1      -2.296   0.272   0.934  1.00  0.00
+      84             : ATOM      9  CA  ALA     1      -0.436   2.292   0.814  1.00  0.00
+      85             : TER
+      86             : ENDMDL
+      87             : TITLE     frame t= 0.000
+      88             : MODEL        1
+      89             : ATOM      1  CL  ALA     1       1.042  -3.070   0.946  1.00  0.00
+      90             : ATOM      5  CLP ALA     1      -0.774   0.053   0.003  1.00  0.00
+      91             : ATOM      6  OL  ALA     1      -0.849  -0.166  -1.034  1.00  0.00
+      92             : ATOM      7  NL  ALA     1      -2.176   0.260   0.563  1.00  0.00
+      93             : ATOM      9  CA  ALA     1       0.314   1.825   0.962  1.00  0.00
+      94             : TER
+      95             : ENDMDL
+      96             : 
+      97             : \endauxfile
+      98             : 
+      99             : */
+     100             : //+ENDPLUMEDOC
+     101             : 
+     102             : PLUMED_REGISTER_ACTION(PCARMSD,"PCARMSD")
+     103             : 
+     104           4 : void PCARMSD::registerKeywords(Keywords& keys) {
+     105           4 :   Colvar::registerKeywords(keys);
+     106           8 :   keys.add("compulsory","AVERAGE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     107           8 :   keys.add("compulsory","EIGENVECTORS","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     108           8 :   keys.addOutputComponent("eig","default","the projections on each eigenvalue are stored on values labeled eig-1, eig-2, ...");
+     109           8 :   keys.addOutputComponent("residual","default","the distance of the present configuration from the configuration supplied as AVERAGE in terms of mean squared displacement after optimal alignment ");
+     110           8 :   keys.addFlag("SQUARED_ROOT",false," This should be set if you want RMSD instead of mean squared displacement ");
+     111           4 : }
+     112             : 
+     113           2 : PCARMSD::PCARMSD(const ActionOptions&ao):
+     114             :   PLUMED_COLVAR_INIT(ao),
+     115           2 :   squared(true),
+     116           2 :   nopbc(false)
+     117             : {
+     118             :   std::string f_average;
+     119           4 :   parse("AVERAGE",f_average);
+     120             :   std::string type;
+     121           2 :   type.assign("OPTIMAL");
+     122             :   std::string f_eigenvectors;
+     123           2 :   parse("EIGENVECTORS",f_eigenvectors);
+     124           2 :   bool sq;  parseFlag("SQUARED_ROOT",sq);
+     125           2 :   if (sq) { squared=false; }
+     126           2 :   parseFlag("NOPBC",nopbc);
+     127           2 :   checkRead();
+     128             : 
+     129           2 :   PDB pdb;
+     130             : 
+     131             :   // read everything in ang and transform to nm if we are not in natural units
+     132           2 :   if( !pdb.read(f_average,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     133           0 :     error("missing input file " + f_average );
+     134             : 
+     135           2 :   rmsd=Tools::make_unique<RMSD>();
+     136             :   bool remove_com=true;
+     137             :   bool normalize_weights=true;
+     138             :   // here align and displace are a simple vector of ones
+     139          24 :   std::vector<double> align; align=pdb.getOccupancy(); for(unsigned i=0; i<align.size(); i++) {align[i]=1.;} ;
+     140          24 :   std::vector<double> displace;  displace=pdb.getBeta(); for(unsigned i=0; i<displace.size(); i++) {displace[i]=1.;} ;
+     141             :   // reset again to reimpose unifrom weights (safe to disable this)
+     142           2 :   rmsd->set(align,displace,pdb.getPositions(),type,remove_com,normalize_weights);
+     143           2 :   requestAtoms( pdb.getAtomNumbers() );
+     144             : 
+     145           4 :   addComponentWithDerivatives("residual"); componentIsNotPeriodic("residual");
+     146             : 
+     147           2 :   log.printf("  average from file %s\n",f_average.c_str());
+     148           2 :   log.printf("  which contains %d atoms\n",getNumberOfAtoms());
+     149           2 :   log.printf("  with indices : ");
+     150          24 :   for(unsigned i=0; i<pdb.getAtomNumbers().size(); ++i) {
+     151          22 :     if(i%25==0) log<<"\n";
+     152          22 :     log.printf("%d ",pdb.getAtomNumbers()[i].serial());
+     153             :   }
+     154           2 :   log.printf("\n");
+     155           2 :   log.printf("  method for alignment : %s \n",type.c_str() );
+     156           2 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     157           1 :   else      log.printf("  using periodic boundary conditions\n");
+     158             : 
+     159           4 :   log<<"  Bibliography "<<plumed.cite("Spiwok, Lipovova and Kralova, JPCB, 111, 3073 (2007)  ");
+     160           4 :   log<<" "<<plumed.cite( "Sutto, D'Abramo, Gervasio, JCTC, 6, 3640 (2010)");
+     161             : 
+     162             :   unsigned neigenvects;
+     163           2 :   neigenvects=0;
+     164             :   // now get the eigenvectors
+     165             :   // open the file
+     166           2 :   if (FILE* fp=this->fopen(f_eigenvectors.c_str(),"r"))
+     167             :   {
+     168             : // call fclose when exiting this block
+     169           2 :     auto deleter=[this](FILE* f) { this->fclose(f); };
+     170             :     std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     171             : 
+     172             :     std::vector<AtomNumber> aaa;
+     173           2 :     log<<"  Opening the eigenvectors file "<<f_eigenvectors.c_str()<<"\n";
+     174             :     bool do_read=true;
+     175             :     unsigned nat=0;
+     176          72 :     while (do_read) {
+     177          72 :       PDB mypdb;
+     178             :       // check the units for reading this file: how can they make sense?
+     179          72 :       do_read=mypdb.readFromFilepointer(fp,usingNaturalUnits(),0.1/getUnits().getLength());
+     180          72 :       if(do_read) {
+     181          70 :         neigenvects++;
+     182          70 :         if(mypdb.getAtomNumbers().size()==0) error("number of atoms in a frame should be more than zero");
+     183          70 :         if(nat==0) nat=mypdb.getAtomNumbers().size();
+     184          70 :         if(nat!=mypdb.getAtomNumbers().size()) error("frames should have the same number of atoms");
+     185          70 :         if(aaa.empty()) aaa=mypdb.getAtomNumbers();
+     186         140 :         if(aaa!=mypdb.getAtomNumbers()) error("frames should contain same atoms in same order");
+     187          70 :         log<<"  Found eigenvector: "<<neigenvects<<" containing  "<<mypdb.getAtomNumbers().size()<<" atoms\n";
+     188          70 :         pdbv.push_back(mypdb);
+     189          70 :         eigenvectors.push_back(mypdb.getPositions());
+     190             :       } else {break ;}
+     191          72 :     }
+     192           2 :     log<<"  Found total "<<neigenvects<< " eigenvectors in the file "<<f_eigenvectors.c_str()<<" \n";
+     193           2 :     if(neigenvects==0) error("at least one eigenvector is expected");
+     194           2 :   }
+     195             :   // the components
+     196          72 :   for(unsigned i=0; i<neigenvects; i++) {
+     197          70 :     std::string num; Tools::convert( i, num );
+     198         140 :     std::string name; name=std::string("eig-")+num;
+     199          70 :     pca_names.push_back(name);
+     200         140 :     addComponentWithDerivatives(name); componentIsNotPeriodic(name);
+     201             :   }
+     202           2 :   turnOnDerivatives();
+     203             : 
+     204           4 : }
+     205             : 
+     206             : // calculator
+     207        1092 : void PCARMSD::calculate() {
+     208        1092 :   if(!nopbc) makeWhole();
+     209        1092 :   Tensor rotation,invrotation;
+     210             :   Matrix<std::vector<Vector> > drotdpos(3,3);
+     211             :   std::vector<Vector> alignedpos;
+     212             :   std::vector<Vector> centeredpos;
+     213             :   std::vector<Vector> centeredref;
+     214             :   std::vector<Vector> ddistdpos;
+     215        2184 :   double r=rmsd->calc_PCAelements( getPositions(), ddistdpos, rotation,  drotdpos, alignedpos,centeredpos, centeredref,squared);
+     216        1092 :   invrotation=rotation.transpose();
+     217             : 
+     218        2184 :   Value* verr=getPntrToComponent("residual");
+     219             :   verr->set(r);
+     220       13104 :   for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) {
+     221       12012 :     setAtomsDerivatives (verr,iat,ddistdpos[iat]);
+     222             :   }
+     223             : 
+     224             :   std::vector< Vector > der;
+     225        1092 :   der.resize(getNumberOfAtoms());
+     226             : 
+     227             : 
+     228       39312 :   for(unsigned i=0; i<eigenvectors.size(); i++) {
+     229       38220 :     Value* value=getPntrToComponent(pca_names[i].c_str());
+     230             :     double val; val=0.;
+     231      458640 :     for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) {
+     232      420420 :       val+=dotProduct(alignedpos[iat]-centeredref[iat],eigenvectors[i][iat]);   der[iat].zero();
+     233             :     }
+     234             :     value->set(val);
+     235             :     // here the loop is reversed to better suit the structure of the derivative of the rotation matrix
+     236             :     double tmp1;
+     237      152880 :     for(unsigned a=0; a<3; a++) {
+     238      458640 :       for(unsigned b=0; b<3; b++) {
+     239             :         tmp1=0.;
+     240     4127760 :         for(unsigned n=0; n<getNumberOfAtoms(); n++) {
+     241     3783780 :           tmp1+=centeredpos[n][b]*eigenvectors[i][n][a];
+     242             :         }
+     243     4127760 :         for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) {
+     244     3783780 :           der[iat]+=drotdpos[a][b][iat]*tmp1;
+     245             :         }
+     246             :       }
+     247             :     }
+     248       38220 :     Vector v1;
+     249      458640 :     for(unsigned n=0; n<getNumberOfAtoms(); n++) {
+     250      420420 :       v1+=(1./getNumberOfAtoms())*matmul(invrotation,eigenvectors[i][n]);
+     251             :     }
+     252      458640 :     for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) {
+     253      420420 :       der[iat]+=matmul(invrotation,eigenvectors[i][iat])-v1;
+     254      420420 :       setAtomsDerivatives (value,iat,der[iat]);
+     255             :     }
+     256             :   }
+     257             : 
+     258       40404 :   for(int i=0; i<getNumberOfComponents(); ++i) setBoxDerivativesNoPbc( getPntrToComponent(i) );
+     259             : 
+     260        1092 : }
+     261             : 
+     262             : }
+     263             : }
+     264             : 
+     265             : 
+     266             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSD.cpp.func-sort-c.html b/coverage/colvar/PathMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..0b570cabd1c8 --- /dev/null +++ b/coverage/colvar/PathMSD.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PathMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7PathMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar7PathMSDC1ERKNS_13ActionOptionsE14
_ZN4PLMD6colvar7PathMSD16registerKeywordsERNS_8KeywordsE16
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSD.cpp.func.html b/coverage/colvar/PathMSD.cpp.func.html new file mode 100644 index 000000000000..391c5641f7fd --- /dev/null +++ b/coverage/colvar/PathMSD.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PathMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7PathMSD16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD6colvar7PathMSDC1ERKNS_13ActionOptionsE14
_ZN4PLMD6colvar7PathMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSD.cpp.gcov.html b/coverage/colvar/PathMSD.cpp.gcov.html new file mode 100644 index 000000000000..4e8e85743fbf --- /dev/null +++ b/coverage/colvar/PathMSD.cpp.gcov.html @@ -0,0 +1,206 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PathMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PathMSDBase.h"
+      23             : #include "core/PlumedMain.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace colvar {
+      27             : 
+      28             : //+PLUMEDOC COLVAR PATHMSD
+      29             : /*
+      30             : This Colvar calculates path collective variables.
+      31             : 
+      32             : This is the Path Collective Variables implementation
+      33             : ( see \cite brand07 ).
+      34             : This variable computes the progress along a given set of frames that is provided
+      35             : in input ("sss" component) and the distance from them ("zzz" component).
+      36             : (see below).
+      37             : 
+      38             : When running with periodic boundary conditions, the atoms should be
+      39             : in the proper periodic image. This is done automatically since PLUMED 2.5,
+      40             : by considering the ordered list of atoms and rebuilding molecules with a procedure
+      41             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+      42             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+      43             : which actually modifies the coordinates stored in PLUMED.
+      44             : 
+      45             : In case you want to recover the old behavior you should use the NOPBC flag.
+      46             : In that case you need to take care that atoms are in the correct
+      47             : periodic image.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : Here below is a case where you have defined three frames and you want to
+      52             : calculate the progress along the path and the distance from it in p1
+      53             : 
+      54             : \plumedfile
+      55             : p1: PATHMSD REFERENCE=file.pdb  LAMBDA=500.0 NEIGH_STRIDE=4 NEIGH_SIZE=8
+      56             : PRINT ARG=p1.sss,p1.zzz STRIDE=1 FILE=colvar FMT=%8.4f
+      57             : \endplumedfile
+      58             : 
+      59             : note that NEIGH_STRIDE=4 NEIGH_SIZE=8 control the neighbor list parameter (optional but
+      60             : recommended for performance) and states that the neighbor list will be calculated every 4
+      61             : steps and consider only the closest 8 member to the actual md snapshots.
+      62             : 
+      63             : This input must be accompanied by a REFERENCE PDB file in which the positions of each of the frames are specified
+      64             : separated using either END or ENDMDL as shown below:
+      65             : 
+      66             : \auxfile{file.pdb}
+      67             : ATOM      1  CL  ALA     1      -3.171   0.295   2.045  1.00  1.00
+      68             : ATOM      5  CLP ALA     1      -1.819  -0.143   1.679  1.00  1.00
+      69             : ATOM      6  OL  ALA     1      -1.177  -0.889   2.401  1.00  1.00
+      70             : ATOM      7  NL  ALA     1      -1.313   0.341   0.529  1.00  1.00
+      71             : END
+      72             : ATOM      1  CL  ALA     1      -3.175   0.365   2.024  1.00  1.00
+      73             : ATOM      5  CLP ALA     1      -1.814  -0.106   1.685  1.00  1.00
+      74             : ATOM      6  OL  ALA     1      -1.201  -0.849   2.425  1.00  1.00
+      75             : ATOM      7  NL  ALA     1      -1.296   0.337   0.534  1.00  1.00
+      76             : END
+      77             : ATOM      1  CL  ALA     1      -2.990   0.383   2.277  1.00  1.00
+      78             : ATOM      5  CLP ALA     1      -1.664  -0.085   1.831  1.00  1.00
+      79             : ATOM      6  OL  ALA     1      -0.987  -0.835   2.533  1.00  1.00
+      80             : ATOM      7  NL  ALA     1      -1.227   0.364   0.646  1.00  1.00
+      81             : END
+      82             : \endauxfile
+      83             : 
+      84             : \note
+      85             : The implementation of this collective variable and of \ref PROPERTYMAP
+      86             : is shared, as well as most input options.
+      87             : 
+      88             : 
+      89             : */
+      90             : //+ENDPLUMEDOC
+      91             : 
+      92             : class PathMSD : public PathMSDBase {
+      93             : public:
+      94             :   explicit PathMSD(const ActionOptions&);
+      95             :   static void registerKeywords(Keywords& keys);
+      96             : };
+      97             : 
+      98             : PLUMED_REGISTER_ACTION(PathMSD,"PATHMSD")
+      99             : 
+     100          16 : void PathMSD::registerKeywords(Keywords& keys) {
+     101          16 :   PathMSDBase::registerKeywords(keys);
+     102          16 :   componentsAreNotOptional(keys);
+     103          32 :   keys.addOutputComponent("sss","default","the position on the path");
+     104          32 :   keys.addOutputComponent("zzz","default","the distance from the path");
+     105          16 : }
+     106             : 
+     107          14 : PathMSD::PathMSD(const ActionOptions&ao):
+     108          14 :   Action(ao),PathMSDBase(ao)
+     109             : {
+     110          14 :   checkRead();
+     111             : 
+     112          14 :   log<<"  Bibliography "
+     113          28 :      <<plumed.cite("Branduardi, Gervasio, Parrinello J. Chem. Phys. 126, 054103 (2007)")
+     114          28 :      <<"\n";
+     115             :   // no need to read anything
+     116          42 :   addComponentWithDerivatives("sss"); componentIsNotPeriodic("sss");
+     117          28 :   addComponentWithDerivatives("zzz"); componentIsNotPeriodic("zzz");
+     118          14 :   requestAtoms(pdbv[0].getAtomNumbers());
+     119             : 
+     120          14 :   double i=1.;
+     121         634 :   for(unsigned it=0 ; it<nframes ; ++it) {
+     122         620 :     std::vector<double> v; v.push_back(i);
+     123         620 :     indexvec.push_back(v); i+=1.;
+     124             :   }
+     125          14 : }
+     126             : 
+     127             : }
+     128             : 
+     129             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSDBase.cpp.func-sort-c.html b/coverage/colvar/PathMSDBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..ccb6e895f34d --- /dev/null +++ b/coverage/colvar/PathMSDBase.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18018497.8 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PathMSDBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar11PathMSDBaseD0Ev0
_ZN4PLMD6colvar11PathMSDBaseD1Ev0
_ZN4PLMD6colvar11PathMSDBaseC2ERKNS_13ActionOptionsE25
_ZN4PLMD6colvar11PathMSDBaseD2Ev25
_ZZN4PLMD6colvar11PathMSDBaseC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_25
_ZN4PLMD6colvar11PathMSDBase16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD6colvar11PathMSDBase9calculateEv11179
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSDBase.cpp.func.html b/coverage/colvar/PathMSDBase.cpp.func.html new file mode 100644 index 000000000000..076b92b5cf0d --- /dev/null +++ b/coverage/colvar/PathMSDBase.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18018497.8 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PathMSDBase16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD6colvar11PathMSDBase9calculateEv11179
_ZN4PLMD6colvar11PathMSDBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar11PathMSDBaseC2ERKNS_13ActionOptionsE25
_ZN4PLMD6colvar11PathMSDBaseD0Ev0
_ZN4PLMD6colvar11PathMSDBaseD1Ev0
_ZN4PLMD6colvar11PathMSDBaseD2Ev25
_ZZN4PLMD6colvar11PathMSDBaseC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_25
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSDBase.cpp.gcov.html b/coverage/colvar/PathMSDBase.cpp.gcov.html new file mode 100644 index 000000000000..851da87b4491 --- /dev/null +++ b/coverage/colvar/PathMSDBase.cpp.gcov.html @@ -0,0 +1,414 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18018497.8 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PathMSDBase.h"
+      23             : #include "Colvar.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "tools/Communicator.h"
+      27             : #include "tools/PDB.h"
+      28             : #include "tools/RMSD.h"
+      29             : #include "tools/Tools.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace colvar {
+      33             : 
+      34          29 : void PathMSDBase::registerKeywords(Keywords& keys) {
+      35          29 :   Colvar::registerKeywords(keys);
+      36          58 :   keys.add("compulsory","LAMBDA","the lambda parameter is needed for smoothing, is in the units of plumed");
+      37          58 :   keys.add("compulsory","REFERENCE","the pdb is needed to provide the various milestones");
+      38          58 :   keys.add("optional","NEIGH_SIZE","size of the neighbor list");
+      39          58 :   keys.add("optional","NEIGH_STRIDE","how often the neighbor list needs to be calculated in time units");
+      40          58 :   keys.add("optional", "EPSILON", "(default=-1) the maximum distance between the close and the current structure, the positive value turn on the close structure method");
+      41          58 :   keys.add("optional", "LOG_CLOSE", "(default=0) value 1 enables logging regarding the close structure");
+      42          58 :   keys.add("optional", "DEBUG_CLOSE", "(default=0) value 1 enables extensive debugging info regarding the close structure, the simulation will run much slower");
+      43          29 : }
+      44             : 
+      45          25 : PathMSDBase::PathMSDBase(const ActionOptions&ao):
+      46             :   PLUMED_COLVAR_INIT(ao),
+      47          25 :   nopbc(false),
+      48          25 :   neigh_size(-1),
+      49          25 :   neigh_stride(-1),
+      50          25 :   epsilonClose(-1),
+      51          25 :   debugClose(0),
+      52          25 :   logClose(0),
+      53          25 :   computeRefClose(false),
+      54          25 :   nframes(0)
+      55             : {
+      56          25 :   parse("LAMBDA",lambda);
+      57          25 :   parse("NEIGH_SIZE",neigh_size);
+      58          25 :   parse("NEIGH_STRIDE",neigh_stride);
+      59          25 :   parse("REFERENCE",reference);
+      60          25 :   parse("EPSILON", epsilonClose);
+      61          25 :   parse("LOG_CLOSE", logClose);
+      62          25 :   parse("DEBUG_CLOSE", debugClose);
+      63          25 :   parseFlag("NOPBC",nopbc);
+      64             : 
+      65             :   // open the file
+      66          25 :   if (FILE* fp=this->fopen(reference.c_str(),"r"))
+      67             :   {
+      68             : // call fclose when exiting this block
+      69          25 :     auto deleter=[this](FILE* f) { this->fclose(f); };
+      70             :     std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+      71             : 
+      72             :     std::vector<AtomNumber> aaa;
+      73          25 :     log<<"Opening reference file "<<reference.c_str()<<"\n";
+      74             :     bool do_read=true;
+      75             :     unsigned nat=0;
+      76        1107 :     while (do_read) {
+      77        1107 :       PDB mypdb;
+      78        1107 :       RMSD mymsd;
+      79        1107 :       do_read=mypdb.readFromFilepointer(fp,usingNaturalUnits(),0.1/getUnits().getLength());
+      80        1107 :       if(do_read) {
+      81        1082 :         nframes++;
+      82        1082 :         if(mypdb.getAtomNumbers().size()==0) error("number of atoms in a frame should be more than zero");
+      83        1082 :         if(nat==0) nat=mypdb.getAtomNumbers().size();
+      84        1082 :         if(nat!=mypdb.getAtomNumbers().size()) error("frames should have the same number of atoms");
+      85        1082 :         if(aaa.empty()) {
+      86          25 :           aaa=mypdb.getAtomNumbers();
+      87          25 :           log.printf("  found %zu atoms in input \n",aaa.size());
+      88          25 :           log.printf("  with indices : ");
+      89         346 :           for(unsigned i=0; i<aaa.size(); ++i) {
+      90         321 :             if(i%25==0) log<<"\n";
+      91         321 :             log.printf("%d ",aaa[i].serial());
+      92             :           }
+      93          25 :           log.printf("\n");
+      94             :         }
+      95        2164 :         if(aaa!=mypdb.getAtomNumbers()) error("frames should contain same atoms in same order");
+      96        1082 :         log<<"Found PDB: "<<nframes<<" containing  "<<mypdb.getAtomNumbers().size()<<" atoms\n";
+      97        1082 :         pdbv.push_back(mypdb);
+      98        1082 :         derivs_s.resize(mypdb.getAtomNumbers().size());
+      99        1082 :         derivs_z.resize(mypdb.getAtomNumbers().size());
+     100        1082 :         mymsd.set(mypdb,"OPTIMAL");
+     101        1082 :         msdv.push_back(mymsd); // the vector that stores the frames
+     102             :       } else {break ;}
+     103        1107 :     }
+     104          25 :     log<<"Found TOTAL "<<nframes<< " PDB in the file "<<reference.c_str()<<" \n";
+     105          25 :     if(nframes==0) error("at least one frame expected");
+     106             :     //set up rmsdRefClose, initialize it to the first structure loaded from reference file
+     107          25 :     rmsdPosClose.set(pdbv[0], "OPTIMAL");
+     108          25 :     firstPosClose = true;
+     109          25 :   }
+     110          25 :   if(neigh_stride>0 || neigh_size>0) {
+     111          14 :     if(neigh_size>int(nframes)) {
+     112           0 :       log.printf(" List size required ( %d ) is too large: resizing to the maximum number of frames required: %u  \n",neigh_size,nframes);
+     113           0 :       neigh_size=nframes;
+     114             :     }
+     115          14 :     log.printf("  Neighbor list enabled: \n");
+     116          14 :     log.printf("                size   :  %d elements\n",neigh_size);
+     117          14 :     log.printf("                stride :  %d timesteps \n",neigh_stride);
+     118             :   } else {
+     119          11 :     log.printf("  Neighbor list NOT enabled \n");
+     120             :   }
+     121          25 :   if (epsilonClose > 0) {
+     122           2 :     log.printf(" Computing with the close structure, epsilon = %lf\n", epsilonClose);
+     123           4 :     log << "  Bibliography " << plumed.cite("Pazurikova J, Krenek A, Spiwok V, Simkova M J. Chem. Phys. 146, 115101 (2017)") << "\n";
+     124             :   }
+     125             :   else {
+     126          23 :     debugClose = 0;
+     127          23 :     logClose = 0;
+     128             :   }
+     129          25 :   if (debugClose)
+     130           2 :     log.printf(" Extensive debug info regarding close structure turned on\n");
+     131             : 
+     132          25 :   rotationRefClose.resize(nframes);
+     133          25 :   savedIndices = std::vector<unsigned>(nframes);
+     134             : 
+     135          25 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     136          24 :   else      log.printf("  using periodic boundary conditions\n");
+     137             : 
+     138          25 : }
+     139             : 
+     140          25 : PathMSDBase::~PathMSDBase() {
+     141          75 : }
+     142             : 
+     143       11179 : void PathMSDBase::calculate() {
+     144             : 
+     145       11179 :   if(neigh_size>0 && getExchangeStep()) error("Neighbor lists for this collective variable are not compatible with replica exchange, sorry for that!");
+     146             : 
+     147             :   //log.printf("NOW CALCULATE! \n");
+     148             : 
+     149       11179 :   if(!nopbc) makeWhole();
+     150             : 
+     151             : 
+     152             :   // resize the list to full
+     153       11179 :   if(imgVec.empty()) { // this is the signal that means: recalculate all
+     154        7164 :     imgVec.resize(nframes);
+     155             :     #pragma omp simd
+     156        7164 :     for(unsigned i=0; i<nframes; i++) {
+     157      300920 :       imgVec[i].property=indexvec[i];
+     158      300920 :       imgVec[i].index=i;
+     159             :     }
+     160             :   }
+     161             : 
+     162             : // THIS IS THE HEAVY PART (RMSD STUFF)
+     163       11179 :   unsigned stride=comm.Get_size();
+     164       11179 :   unsigned rank=comm.Get_rank();
+     165       11179 :   size_t nat=pdbv[0].size();
+     166       11179 :   plumed_assert(nat>0);
+     167       11179 :   plumed_assert(nframes>0);
+     168       11179 :   plumed_assert(imgVec.size()>0);
+     169             : 
+     170       11179 :   std::vector<Tensor> tmp_rotationRefClose(nframes);
+     171             : 
+     172       11179 :   if (epsilonClose > 0) {
+     173             :     //compute rmsd between positions and close structure, save rotation matrix, drotation_drr01
+     174        1092 :     double posclose = rmsdPosClose.calc_Rot_DRotDRr01(getPositions(), rotationPosClose, drotationPosCloseDrr01, true);
+     175             :     //if we compute for the first time or the existing close structure is too far from current structure
+     176        1092 :     if (firstPosClose || (posclose > epsilonClose)) {
+     177             :       //set the current structure as close one for a few next steps
+     178          16 :       if (logClose)
+     179          16 :         log << "PLUMED_CLOSE: new close structure, rmsd pos close " << posclose << "\n";
+     180          16 :       rmsdPosClose.clear();
+     181          16 :       rmsdPosClose.setReference(getPositions());
+     182             :       //as this is a new close structure, we need to save the rotation matrices fitted to the reference structures
+     183             :       // and we need to accurately recalculate for all reference structures
+     184          16 :       computeRefClose = true;
+     185          16 :       imgVec.resize(nframes);
+     186         688 :       for(unsigned i=0; i<nframes; i++) {
+     187         672 :         imgVec[i].property=indexvec[i];
+     188         672 :         imgVec[i].index=i;
+     189             :       }
+     190          16 :       firstPosClose = false;
+     191          16 :     }
+     192             :     else {
+     193             :       //the current structure is pretty close to the close structure, so we use saved rotation matrices to decrease the complexity of rmsd comuptation
+     194        1076 :       if (debugClose)
+     195        1076 :         log << "PLUMED-CLOSE: old close structure, rmsd pos close " << posclose << "\n";
+     196        1076 :       computeRefClose = false;
+     197             :     }
+     198             :   }
+     199             : 
+     200       11179 :   std::vector<double> tmp_distances(imgVec.size(),0.0);
+     201             :   std::vector<Vector> tmp_derivs;
+     202             : // this array is a merge of all tmp_derivs, so as to allow a single comm.Sum below
+     203       11179 :   std::vector<Vector> tmp_derivs2(imgVec.size()*nat);
+     204             : 
+     205             : // if imgVec.size() is less than nframes, it means that only some msd will be calculated
+     206       11179 :   if (epsilonClose > 0) {
+     207        1092 :     if (computeRefClose) {
+     208             :       //recompute rotation matrices accurately
+     209         688 :       for(unsigned i=rank; i<imgVec.size(); i+=stride) {
+     210         672 :         tmp_distances[i] = msdv[imgVec[i].index].calc_Rot(getPositions(), tmp_derivs, tmp_rotationRefClose[imgVec[i].index], true);
+     211         672 :         plumed_assert(tmp_derivs.size()==nat);
+     212             :         #pragma omp simd
+     213        8736 :         for(unsigned j=0; j<nat; j++) tmp_derivs2[i*nat+j]=tmp_derivs[j];
+     214             :       }
+     215             :     }
+     216             :     else {
+     217             :       //approximate distance with saved rotation matrices
+     218       46268 :       for(unsigned i=rank; i<imgVec.size(); i+=stride) {
+     219       45192 :         tmp_distances[i] = msdv[imgVec[i].index].calculateWithCloseStructure(getPositions(), tmp_derivs, rotationPosClose, rotationRefClose[imgVec[i].index], drotationPosCloseDrr01, true);
+     220       45192 :         plumed_assert(tmp_derivs.size()==nat);
+     221             :         #pragma omp simd
+     222      587496 :         for(unsigned j=0; j<nat; j++) tmp_derivs2[i*nat+j]=tmp_derivs[j];
+     223       45192 :         if (debugClose) {
+     224       45192 :           double withclose = tmp_distances[i];
+     225       45192 :           RMSD opt;
+     226       45192 :           opt.setType("OPTIMAL");
+     227       90384 :           opt.setReference(msdv[imgVec[i].index].getReference());
+     228             :           std::vector<Vector> ders;
+     229       45192 :           double withoutclose = opt.calculate(getPositions(), ders, true);
+     230       45192 :           float difference = std::abs(withoutclose-withclose);
+     231       45192 :           log<<"PLUMED-CLOSE: difference original "<<withoutclose;
+     232       45192 :           log<<" - with close "<<withclose<<" = "<<difference<<", step "<<getStep()<<", i "<<i<<" imgVec[i].index "<<imgVec[i].index<<"\n";
+     233       45192 :         }
+     234             :       }
+     235             :     }
+     236             :   }
+     237             :   else {
+     238             :     // store temporary local results
+     239      297781 :     for(unsigned i=rank; i<imgVec.size(); i+=stride) {
+     240      287694 :       tmp_distances[i]=msdv[imgVec[i].index].calculate(getPositions(),tmp_derivs,true);
+     241      287694 :       plumed_assert(tmp_derivs.size()==nat);
+     242             :       #pragma omp simd
+     243     3729822 :       for(unsigned j=0; j<nat; j++) tmp_derivs2[i*nat+j]=tmp_derivs[j];
+     244             :     }
+     245             :   }
+     246             : 
+     247             : // reduce over all processors
+     248       11179 :   comm.Sum(tmp_distances);
+     249       11179 :   comm.Sum(tmp_derivs2);
+     250       11179 :   if (epsilonClose > 0 && computeRefClose) {
+     251          16 :     comm.Sum(tmp_rotationRefClose);
+     252         688 :     for (unsigned i=0; i<nframes; i++) {
+     253         672 :       rotationRefClose[i] = tmp_rotationRefClose[i];
+     254             :     }
+     255             :   }
+     256             : // assign imgVec[i].distance and imgVec[i].distder
+     257      482329 :   for(size_t i=0; i<imgVec.size(); i++) {
+     258      471150 :     imgVec[i].distance=tmp_distances[i];
+     259      471150 :     imgVec[i].distder.assign(&tmp_derivs2[i*nat],nat+&tmp_derivs2[i*nat]);
+     260             :   }
+     261             : 
+     262             : // END OF THE HEAVY PART
+     263             : 
+     264             :   std::vector<Value*> val_s_path;
+     265       11179 :   if(labels.size()>0) {
+     266       18018 :     for(unsigned i=0; i<labels.size(); i++) { val_s_path.push_back(getPntrToComponent(labels[i].c_str()));}
+     267             :   } else {
+     268        5173 :     val_s_path.push_back(getPntrToComponent("sss"));
+     269             :   }
+     270       22358 :   Value* val_z_path=getPntrToComponent("zzz");
+     271             : 
+     272       28364 :   std::vector<double> s_path(val_s_path.size()); for(unsigned i=0; i<s_path.size(); i++)s_path[i]=0.;
+     273             :   double min_distance=1e10;
+     274      482329 :   for(auto & it : imgVec) {
+     275      471150 :     if(it.distance < min_distance) min_distance=it.distance;
+     276             :   }
+     277             : 
+     278             :   double partition=0.;
+     279      482329 :   for(auto & it : imgVec) {
+     280      471150 :     it.similarity=std::exp(-lambda*(it.distance - min_distance));
+     281     1194552 :     for(unsigned i=0; i<s_path.size(); i++) {
+     282      723402 :       s_path[i]+=(it.property[i])*it.similarity;
+     283             :     }
+     284      471150 :     partition+=it.similarity;
+     285             :   }
+     286       28364 :   for(unsigned i=0; i<s_path.size(); i++) { s_path[i]/=partition;  val_s_path[i]->set(s_path[i]) ;}
+     287       11179 :   val_z_path->set(-(1./lambda)*std::log(partition) + min_distance);
+     288             : 
+     289             :   // clean vector
+     290       11179 :   Tools::set_to_zero(derivs_z);
+     291             :   double tmp;
+     292       28364 :   for(unsigned j=0; j<s_path.size(); j++) {
+     293             :     // clean up
+     294       17185 :     Tools::set_to_zero(derivs_s);
+     295             :     // do the derivative
+     296      740587 :     for(const auto & it : imgVec) {
+     297      723402 :       double expval=it.similarity;
+     298      723402 :       tmp=lambda*expval*(s_path[j]-it.property[j])/partition;
+     299             :       #pragma omp simd
+     300    10117428 :       for(unsigned i=0; i< derivs_s.size(); i++) { derivs_s[i]+=tmp*it.distder[i] ;}
+     301      723402 :       if(j==0) {
+     302             :         #pragma omp simd
+     303     6585900 :         for(unsigned i=0; i< derivs_z.size(); i++) { derivs_z[i]+=it.distder[i]*expval/partition;}
+     304             :       }
+     305             :     }
+     306      240386 :     for(unsigned i=0; i< derivs_s.size(); i++) {
+     307      223201 :       setAtomsDerivatives (val_s_path[j],i,derivs_s[i]);
+     308      223201 :       if(j==0) {setAtomsDerivatives (val_z_path,i,derivs_z[i]);}
+     309             :     }
+     310             :   }
+     311       28364 :   for(unsigned i=0; i<val_s_path.size(); ++i) setBoxDerivativesNoPbc(val_s_path[i]);
+     312       11179 :   setBoxDerivativesNoPbc(val_z_path);
+     313             :   //
+     314             :   //  here set next round neighbors
+     315             :   //
+     316       11179 :   if (neigh_size>0) {
+     317             :     //if( int(getStep())%int(neigh_stride/getTimeStep())==0 ){
+     318             :     // enforce consistency: the stride is in time steps
+     319        7153 :     if( int(getStep())%int(neigh_stride)==0 ) {
+     320             : 
+     321             :       // next round do it all:empty the vector
+     322        7153 :       imgVec.clear();
+     323             :     }
+     324             :     // time to analyze the results:
+     325        7153 :     if(imgVec.size()==nframes) {
+     326             :       //sort by msd
+     327           0 :       sort(imgVec.begin(), imgVec.end(), imgOrderByDist());
+     328             :       //resize
+     329           0 :       imgVec.resize(neigh_size);
+     330             :     }
+     331             :   }
+     332             :   //log.printf("CALCULATION DONE! \n");
+     333       11179 : }
+     334             : 
+     335             : }
+     336             : 
+     337             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSDBase.h.func-sort-c.html b/coverage/colvar/PathMSDBase.h.func-sort-c.html new file mode 100644 index 000000000000..1795a9ac1790 --- /dev/null +++ b/coverage/colvar/PathMSDBase.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSDBase.h.func.html b/coverage/colvar/PathMSDBase.h.func.html new file mode 100644 index 000000000000..98f9ca62e212 --- /dev/null +++ b/coverage/colvar/PathMSDBase.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PathMSDBase.h.gcov.html b/coverage/colvar/PathMSDBase.h.gcov.html new file mode 100644 index 000000000000..6404405ac966 --- /dev/null +++ b/coverage/colvar/PathMSDBase.h.gcov.html @@ -0,0 +1,178 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PathMSDBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PathMSDBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_colvar_PathMSDBase_h
+      23             : #define __PLUMED_colvar_PathMSDBase_h
+      24             : 
+      25             : #include "Colvar.h"
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : #include "tools/PDB.h"
+      29             : #include "tools/RMSD.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace colvar {
+      33             : 
+      34             : class PathMSDBase : public Colvar {
+      35             : /// this class is a general container for path stuff
+      36      300920 :   class ImagePath {
+      37             :   public:
+      38             :     // cardinal indexing: needed to map over msd
+      39             :     unsigned index;
+      40             :     // spiwok indexing
+      41             :     std::vector<double> property;
+      42             :     // distance
+      43             :     double distance;
+      44             :     // similarity (exp - lambda distance) or other
+      45             :     double similarity;
+      46             :     // derivatives of the distance
+      47             :     std::vector<Vector> distder;
+      48             :     // here one can add a pointer to a value (hypothetically providing a distance from a point)
+      49             :   };
+      50             :   struct imgOrderByDist {
+      51             :     bool operator ()(ImagePath const& a, ImagePath const& b) {
+      52           0 :       return (a).distance < (b).distance;
+      53             :     }
+      54             :   };
+      55             :   struct imgOrderBySimilarity {
+      56             :     bool operator ()(ImagePath const& a, ImagePath const& b) {
+      57             :       return (a).similarity > (b).similarity;
+      58             :     }
+      59             :   };
+      60             : 
+      61             :   bool nopbc;
+      62             : 
+      63             :   double lambda;
+      64             :   int neigh_size;
+      65             :   int neigh_stride;
+      66             :   std::vector<RMSD> msdv;
+      67             :   std::string reference;
+      68             :   std::vector<Vector> derivs_s;
+      69             :   std::vector<Vector> derivs_z;
+      70             :   std::vector <ImagePath> imgVec; // this can be used for doing neighlist
+      71             : 
+      72             :   //variables used for the close structure method, i is the number of reference structures
+      73             :   double epsilonClose; //the maximal distance between the close and the current structure before reassignment
+      74             :   int debugClose; //turns on debug mode
+      75             :   int logClose; //turns on logging
+      76             :   RMSD rmsdPosClose; //rmsd between the current and the close structure
+      77             :   bool firstPosClose; //flag indicating the first time we need to calculate the distance between the close and the current structure
+      78             :   bool computeRefClose; //flag indicating necessity to recompute accurately all distances and rotation matrices between the close structure and reference str
+      79             :   std::vector<Tensor> rotationRefClose; //Tensor[i] saved rotation matrices between the close structure and reference structures
+      80             :   Tensor rotationPosClose; //rotation matrix between the close and the current structure
+      81             :   std::array<std::array<Tensor,3>,3> drotationPosCloseDrr01; //Tensor[3][3]; //derivation of the rotation matrix w.r.t rr01, necessary for calculation of derivations
+      82             :   std::vector<unsigned> savedIndices; //saved indices of imgVec from previous steps, used for recalculating after neighbourlist update
+      83             : protected:
+      84             :   std::vector<PDB> pdbv;
+      85             :   std::vector<std::string> labels;
+      86             :   std::vector< std::vector<double> > indexvec; // use double to allow isomaps
+      87             :   unsigned nframes;
+      88             : public:
+      89             :   explicit PathMSDBase(const ActionOptions&);
+      90             :   ~PathMSDBase();
+      91             : // active methods:
+      92             :   void calculate() override;
+      93             : //  virtual void prepare();
+      94             :   static void registerKeywords(Keywords& keys);
+      95             : };
+      96             : 
+      97             : }
+      98             : }
+      99             : 
+     100             : #endif
+     101             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Position.cpp.func-sort-c.html b/coverage/colvar/Position.cpp.func-sort-c.html new file mode 100644 index 000000000000..f282e833ccdf --- /dev/null +++ b/coverage/colvar/Position.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Position.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Position.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6565100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8PositionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8PositionC1ERKNS_13ActionOptionsE87
_ZN4PLMD6colvar8Position16registerKeywordsERNS_8KeywordsE89
_ZN4PLMD6colvar8Position9calculateEv8037
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Position.cpp.func.html b/coverage/colvar/Position.cpp.func.html new file mode 100644 index 000000000000..9c8a2a18625a --- /dev/null +++ b/coverage/colvar/Position.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Position.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Position.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6565100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8Position16registerKeywordsERNS_8KeywordsE89
_ZN4PLMD6colvar8Position9calculateEv8037
_ZN4PLMD6colvar8PositionC1ERKNS_13ActionOptionsE87
_ZN4PLMD6colvar8PositionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Position.cpp.gcov.html b/coverage/colvar/Position.cpp.gcov.html new file mode 100644 index 000000000000..4867d0fc6397 --- /dev/null +++ b/coverage/colvar/Position.cpp.gcov.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Position.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Position.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6565100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Pbc.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace colvar {
+      28             : 
+      29             : //+PLUMEDOC COLVAR POSITION
+      30             : /*
+      31             : Calculate the components of the position of an atom.
+      32             : 
+      33             : Notice that single components will not have the proper periodicity!
+      34             : If you need the values to be consistent through PBC you should use SCALED_COMPONENTS,
+      35             : which defines values that by construction are in the -0.5,0.5 domain. This is
+      36             : similar to the equivalent flag for \ref DISTANCE.
+      37             : Also notice that by default the minimal image distance from the
+      38             : origin is considered (can be changed with NOPBC).
+      39             : 
+      40             : \attention
+      41             : This variable should be used with extreme care since it allows to easily go into troubles. See comments below.
+      42             : 
+      43             : This variable can be safely used only if
+      44             : Hamiltonian is not invariant for translation (i.e. there are other absolute positions which are biased, e.g. by position restraints)
+      45             : and cell size and shapes are fixed through the simulation.
+      46             : 
+      47             : If you are not in this situation and still want to use the absolute position of an atom you should first fix the reference frame.
+      48             : This can be done e.g. using \ref FIT_TO_TEMPLATE.
+      49             : 
+      50             : \par Examples
+      51             : 
+      52             : \plumedfile
+      53             : # align to a template
+      54             : FIT_TO_TEMPLATE REFERENCE=ref.pdb
+      55             : p: POSITION ATOM=3
+      56             : PRINT ARG=p.x,p.y,p.z
+      57             : \endplumedfile
+      58             : 
+      59             : The reference position is specified in a pdb file like the one shown below
+      60             : 
+      61             : \auxfile{ref.pdb}
+      62             : ATOM      3  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      63             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      64             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      65             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      66             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      67             : END
+      68             : \endauxfile
+      69             : 
+      70             : */
+      71             : //+ENDPLUMEDOC
+      72             : 
+      73             : class Position : public Colvar {
+      74             :   bool scaled_components;
+      75             :   bool pbc;
+      76             : 
+      77             : public:
+      78             :   static void registerKeywords( Keywords& keys );
+      79             :   explicit Position(const ActionOptions&);
+      80             : // active methods:
+      81             :   void calculate() override;
+      82             : };
+      83             : 
+      84             : PLUMED_REGISTER_ACTION(Position,"POSITION")
+      85             : 
+      86          89 : void Position::registerKeywords( Keywords& keys ) {
+      87          89 :   Colvar::registerKeywords( keys );
+      88          89 :   componentsAreNotOptional(keys);
+      89         178 :   keys.add("atoms","ATOM","the atom number");
+      90         178 :   keys.addFlag("SCALED_COMPONENTS",false,"calculate the a, b and c scaled components of the position separately and store them as label.a, label.b and label.c");
+      91         178 :   keys.addOutputComponent("x","default","the x-component of the atom position");
+      92         178 :   keys.addOutputComponent("y","default","the y-component of the atom position");
+      93         178 :   keys.addOutputComponent("z","default","the z-component of the atom position");
+      94         178 :   keys.addOutputComponent("a","SCALED_COMPONENTS","the normalized projection on the first lattice vector of the atom position");
+      95         178 :   keys.addOutputComponent("b","SCALED_COMPONENTS","the normalized projection on the second lattice vector of the atom position");
+      96         178 :   keys.addOutputComponent("c","SCALED_COMPONENTS","the normalized projection on the third lattice vector of the atom position");
+      97          89 : }
+      98             : 
+      99          87 : Position::Position(const ActionOptions&ao):
+     100             :   PLUMED_COLVAR_INIT(ao),
+     101          87 :   scaled_components(false),
+     102          87 :   pbc(true)
+     103             : {
+     104             :   std::vector<AtomNumber> atoms;
+     105         174 :   parseAtomList("ATOM",atoms);
+     106          87 :   if(atoms.size()!=1)
+     107           1 :     error("Number of specified atoms should be 1");
+     108          86 :   parseFlag("SCALED_COMPONENTS",scaled_components);
+     109          86 :   bool nopbc=!pbc;
+     110          86 :   parseFlag("NOPBC",nopbc);
+     111          86 :   pbc=!nopbc;
+     112          86 :   checkRead();
+     113             : 
+     114          86 :   log.printf("  for atom %d\n",atoms[0].serial());
+     115          86 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     116           4 :   else    log.printf("  without periodic boundary conditions\n");
+     117             : 
+     118          86 :   if(scaled_components) {
+     119          12 :     addComponentWithDerivatives("a"); componentIsPeriodic("a","-0.5","+0.5");
+     120          12 :     addComponentWithDerivatives("b"); componentIsPeriodic("b","-0.5","+0.5");
+     121          12 :     addComponentWithDerivatives("c"); componentIsPeriodic("c","-0.5","+0.5");
+     122             :   } else {
+     123         246 :     addComponentWithDerivatives("x"); componentIsNotPeriodic("x");
+     124         246 :     addComponentWithDerivatives("y"); componentIsNotPeriodic("y");
+     125         165 :     addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+     126          82 :     log<<"  WARNING: components will not have the proper periodicity - see manual\n";
+     127             :   }
+     128             : 
+     129          86 :   requestAtoms(atoms);
+     130          88 : }
+     131             : 
+     132             : 
+     133             : // calculator
+     134        8037 : void Position::calculate() {
+     135             : 
+     136        8037 :   Vector distance;
+     137        8037 :   if(pbc) {
+     138       15984 :     distance=pbcDistance(Vector(0.0,0.0,0.0),getPosition(0));
+     139             :   } else {
+     140          45 :     distance=delta(Vector(0.0,0.0,0.0),getPosition(0));
+     141             :   }
+     142             : 
+     143        8037 :   if(scaled_components) {
+     144          41 :     Value* valuea=getPntrToComponent("a");
+     145          41 :     Value* valueb=getPntrToComponent("b");
+     146          82 :     Value* valuec=getPntrToComponent("c");
+     147          41 :     Vector d=getPbc().realToScaled(distance);
+     148          41 :     setAtomsDerivatives (valuea,0,matmul(getPbc().getInvBox(),Vector(+1,0,0)));
+     149          41 :     valuea->set(Tools::pbc(d[0]));
+     150          41 :     setAtomsDerivatives (valueb,0,matmul(getPbc().getInvBox(),Vector(0,+1,0)));
+     151          41 :     valueb->set(Tools::pbc(d[1]));
+     152          41 :     setAtomsDerivatives (valuec,0,matmul(getPbc().getInvBox(),Vector(0,0,+1)));
+     153          41 :     valuec->set(Tools::pbc(d[2]));
+     154             :   } else {
+     155        7996 :     Value* valuex=getPntrToComponent("x");
+     156        7996 :     Value* valuey=getPntrToComponent("y");
+     157        7996 :     Value* valuez=getPntrToComponent("z");
+     158             : 
+     159        7996 :     setAtomsDerivatives (valuex,0,Vector(+1,0,0));
+     160        7996 :     setBoxDerivatives   (valuex,Tensor(distance,Vector(-1,0,0)));
+     161        7996 :     valuex->set(distance[0]);
+     162             : 
+     163        7996 :     setAtomsDerivatives (valuey,0,Vector(0,+1,0));
+     164        7996 :     setBoxDerivatives   (valuey,Tensor(distance,Vector(0,-1,0)));
+     165        7996 :     valuey->set(distance[1]);
+     166             : 
+     167        7996 :     setAtomsDerivatives (valuez,0,Vector(0,0,+1));
+     168        7996 :     setBoxDerivatives   (valuez,Tensor(distance,Vector(0,0,-1)));
+     169        7996 :     valuez->set(distance[2]);
+     170             :   }
+     171        8037 : }
+     172             : 
+     173             : }
+     174             : }
+     175             : 
+     176             : 
+     177             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html b/coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html new file mode 100644 index 000000000000..a1f8410671e3 --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ProjectionOnAxis.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ProjectionOnAxis.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596295.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16ProjectionOnAxisC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar16ProjectionOnAxisC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar16ProjectionOnAxis16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar16ProjectionOnAxis9calculateEv25
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ProjectionOnAxis.cpp.func.html b/coverage/colvar/ProjectionOnAxis.cpp.func.html new file mode 100644 index 000000000000..079976b1f51b --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ProjectionOnAxis.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ProjectionOnAxis.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596295.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar16ProjectionOnAxis16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6colvar16ProjectionOnAxis9calculateEv25
_ZN4PLMD6colvar16ProjectionOnAxisC1ERKNS_13ActionOptionsE1
_ZN4PLMD6colvar16ProjectionOnAxisC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/ProjectionOnAxis.cpp.gcov.html b/coverage/colvar/ProjectionOnAxis.cpp.gcov.html new file mode 100644 index 000000000000..f95a31304505 --- /dev/null +++ b/coverage/colvar/ProjectionOnAxis.cpp.gcov.html @@ -0,0 +1,246 @@ + + + + + + + + LCOV - plumed test coverage - colvar/ProjectionOnAxis.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - ProjectionOnAxis.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596295.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Angle.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace colvar {
+      28             : 
+      29             : //+PLUMEDOC COLVAR PROJECTION_ON_AXIS
+      30             : /*
+      31             : Calculate a position based on the projection along and extension from a defined axis.
+      32             : 
+      33             : This variable takes 3 input atoms or pseudoatoms, using the two AXIS_ATOMS to define a linear vector.
+      34             : The position of the ATOM is then calculated relative to this vector, with two output components.
+      35             : The projection on the axis (proj) is the distance along the axis from the ATOM to the origin.
+      36             : The extension (ext) is the orthogonal distance between the ATOM and the axis.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : This command tells plumed to define an axis, by calculating a vector that passes through atom 1 and atom 2.
+      41             : The position of atom 3 as a projection along this vector is calculated and printed to COLVAR1.
+      42             : At the same time, the perpendicular distance of atom 3 from the axis, the extension, is printed to COLVAR2.
+      43             : 
+      44             : \plumedfile
+      45             : poa: PROJECTION_ON_AXIS AXIS_ATOMS=1,2 ATOM=3
+      46             : PRINT ARG=poa.proj FILE=COLVAR1
+      47             : PRINT ARG=poa.ext FILE=COLVAR2
+      48             : \endplumedfile
+      49             : 
+      50             : A particular application of this variable could be to study the motion of a ligand relative to its binding pocket on a protein.
+      51             : In this set of commands, the anchor points a1 and a2 are defined using example atom numbers within the protein.
+      52             : As a2 is attempting to be as close as possible to the center of the binding pocket, a COM is used when there are no suitable protein atoms.
+      53             : Similarly, a COM is used to define the position of the ligand in lig1.
+      54             : The calculated projection of lig1 along the axis defined between a1 and a2 is printed to COLVAR1.
+      55             : The calculated perpendicular extension of lig1 from the axis defined between a1 and a2 is printed to COLVAR2.
+      56             : 
+      57             : \plumedfile
+      58             : a1: GROUP ATOMS=3754            # Anchor point 1
+      59             : a2: COM ATOMS=3019,4329,4744    # Anchor point 2
+      60             : lig1: COM ATOMS=5147-5190       # Ligand
+      61             : pp: PROJECTION_ON_AXIS AXIS_ATOMS=a1,a2 ATOM=lig1
+      62             : PRINT ARG=pp.proj FILE=COLVAR1
+      63             : PRINT ARG=pp.ext FILE=COLVAR2
+      64             : \endplumedfile
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : class ProjectionOnAxis : public Colvar {
+      70             :   bool pbc;
+      71             : 
+      72             : public:
+      73             :   explicit ProjectionOnAxis(const ActionOptions&);
+      74             : // Active methods:
+      75             :   virtual void calculate();
+      76             :   static void registerKeywords( Keywords& keys );
+      77             : };
+      78             : 
+      79             : PLUMED_REGISTER_ACTION(ProjectionOnAxis,"PROJECTION_ON_AXIS")
+      80             : 
+      81           3 : void ProjectionOnAxis::registerKeywords( Keywords& keys ) {
+      82           3 :   Colvar::registerKeywords(keys);
+      83           6 :   keys.add("atoms","AXIS_ATOMS","The atoms that define the direction of the axis of interest");
+      84           6 :   keys.add("atoms","ATOM","The atom whose position we want to project on the axis of interest");
+      85           6 :   keys.addOutputComponent("proj","COMPONENTS","The value of the projection along the axis");
+      86           6 :   keys.addOutputComponent("ext","COMPONENTS","The value of the extension from the axis");
+      87           3 : }
+      88             : 
+      89           1 : ProjectionOnAxis::ProjectionOnAxis(const ActionOptions&ao):
+      90             :   PLUMED_COLVAR_INIT(ao),
+      91           1 :   pbc(true)
+      92             : {
+      93             :   std::vector<AtomNumber> axis_atoms;
+      94           2 :   parseAtomList("AXIS_ATOMS",axis_atoms);
+      95           1 :   if( axis_atoms.size()!=2 ) error("There should only be two atoms specified to AXIS_ATOMS keyword");
+      96             :   std::vector<AtomNumber> atom;
+      97           2 :   parseAtomList("ATOM",atom);
+      98           1 :   if( atom.size()!=1 ) error("There should only be one atom specified to ATOM keyword");
+      99           1 :   log.printf("  calculating projection of vector connecting atom %d and atom %d on vector connecting atom %d and atom %d \n",
+     100             :              axis_atoms[0].serial(), atom[0].serial(), axis_atoms[0].serial(), axis_atoms[1].serial() );
+     101           1 :   bool nopbc=!pbc;
+     102           1 :   parseFlag("NOPBC",nopbc);
+     103           1 :   pbc=!nopbc;
+     104             : 
+     105           1 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     106           0 :   else    log.printf("  not using periodic boundary conditions\n");
+     107             : 
+     108             :   // Add values to store data
+     109           3 :   addComponentWithDerivatives("proj"); componentIsNotPeriodic("proj");
+     110           3 :   addComponentWithDerivatives("ext"); componentIsNotPeriodic("ext");
+     111             :   // Get all the atom positions
+     112           1 :   axis_atoms.push_back( atom[0] );
+     113           1 :   requestAtoms(axis_atoms);
+     114           1 :   checkRead();
+     115           1 : }
+     116             : 
+     117             : // Calculator
+     118          25 : void ProjectionOnAxis::calculate() {
+     119             : 
+     120          25 :   Vector rik, rjk;
+     121          25 :   if( pbc ) {
+     122          25 :     rik = pbcDistance( getPosition(2), getPosition(0) );
+     123          25 :     rjk = pbcDistance( getPosition(2), getPosition(1) );
+     124             :   } else {
+     125           0 :     rik = delta( getPosition(2), getPosition(0) );
+     126           0 :     rjk = delta( getPosition(2), getPosition(1) );
+     127             :   }
+     128          25 :   Vector rij = delta( rik, rjk ); double dij = rij.modulo();
+     129          25 :   Vector nij = (1.0/dij)*rij; Tensor dij_a1;
+     130             :   // Derivative of director connecting atom1 - atom2 wrt the position of atom 1
+     131          25 :   dij_a1(0,0) = ( -(nij[1]*nij[1]+nij[2]*nij[2])/dij );   // dx/dx
+     132          25 :   dij_a1(0,1) = (  nij[0]*nij[1]/dij );                   // dx/dy
+     133          25 :   dij_a1(0,2) = (  nij[0]*nij[2]/dij );                   // dx/dz
+     134          25 :   dij_a1(1,0) = (  nij[1]*nij[0]/dij );                   // dy/dx
+     135          25 :   dij_a1(1,1) = ( -(nij[0]*nij[0]+nij[2]*nij[2])/dij );   // dy/dy
+     136          25 :   dij_a1(1,2) = (  nij[1]*nij[2]/dij );
+     137          25 :   dij_a1(2,0) = (  nij[2]*nij[0]/dij );
+     138          25 :   dij_a1(2,1) = (  nij[2]*nij[1]/dij );
+     139          25 :   dij_a1(2,2) = ( -(nij[1]*nij[1]+nij[0]*nij[0])/dij );
+     140             : 
+     141             :   // Calculate dot product and derivatives
+     142          25 :   double d = dotProduct( -rik, nij );
+     143          25 :   Vector dd1 = matmul(-rik, dij_a1) - nij;
+     144          25 :   Vector dd2 = matmul(rik, dij_a1);
+     145          25 :   Vector dd3 = nij;
+     146          50 :   Value* pval=getPntrToComponent("proj"); pval->set( d );
+     147          25 :   setAtomsDerivatives( pval, 0, dd1 );
+     148          25 :   setAtomsDerivatives( pval, 1, dd2 );
+     149          25 :   setAtomsDerivatives( pval, 2, dd3 );
+     150          25 :   setBoxDerivatives( pval, -Tensor( rik, dd1 ) - Tensor( rjk, dd2 ) );
+     151             :   // Calculate derivatives of perpendicular distance from axis
+     152          25 :   double c = std::sqrt( rik.modulo2() - d*d ); double invc = (1.0/c);
+     153             :   // Calculate derivatives of the other thing
+     154          25 :   Vector der1 = invc*(rik - d*dd1);
+     155          25 :   Vector der2 = invc*(-d*dd2);
+     156          25 :   Vector der3 = invc*(-rik - d*dd3);
+     157             : 
+     158          50 :   Value* cval=getPntrToComponent("ext"); cval->set( c );
+     159          25 :   setAtomsDerivatives( cval, 0, der1 );
+     160          25 :   setAtomsDerivatives( cval, 1, der2 );
+     161          25 :   setAtomsDerivatives( cval, 2, der3 );
+     162          25 :   setBoxDerivatives( cval, -Tensor( rik, der1 ) - Tensor( rjk, der2 ) );
+     163          25 : }
+     164             : 
+     165             : }
+     166             : }
+     167             : 
+     168             : 
+     169             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PropertyMap.cpp.func-sort-c.html b/coverage/colvar/PropertyMap.cpp.func-sort-c.html new file mode 100644 index 000000000000..ee3468a60545 --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PropertyMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PropertyMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242692.3 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PropertyMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar11PropertyMapC1ERKNS_13ActionOptionsE11
_ZN4PLMD6colvar11PropertyMap16registerKeywordsERNS_8KeywordsE13
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PropertyMap.cpp.func.html b/coverage/colvar/PropertyMap.cpp.func.html new file mode 100644 index 000000000000..f643f86ede4f --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PropertyMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PropertyMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242692.3 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar11PropertyMap16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD6colvar11PropertyMapC1ERKNS_13ActionOptionsE11
_ZN4PLMD6colvar11PropertyMapC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/PropertyMap.cpp.gcov.html b/coverage/colvar/PropertyMap.cpp.gcov.html new file mode 100644 index 000000000000..a9dd54776e5a --- /dev/null +++ b/coverage/colvar/PropertyMap.cpp.gcov.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - colvar/PropertyMap.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - PropertyMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242692.3 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PathMSDBase.h"
+      23             : #include "core/PlumedMain.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace colvar {
+      27             : 
+      28             : //+PLUMEDOC COLVAR PROPERTYMAP
+      29             : /*
+      30             : Calculate generic property maps.
+      31             : 
+      32             : This Colvar calculates the property maps according to the work of Spiwok \cite Spiwok:2011ce.
+      33             : 
+      34             : 
+      35             : Basically it calculates
+      36             : \f{eqnarray*}{
+      37             : X=\frac{\sum_i X_i*\exp(-\lambda D_i(x))}{\sum_i  \exp(-\lambda D_i(x))} \\
+      38             : Y=\frac{\sum_i Y_i*\exp(-\lambda D_i(x))}{\sum_i  \exp(-\lambda D_i(x))} \\
+      39             : \cdots\\
+      40             : zzz=-\frac{1}{\lambda}\log(\sum_i  \exp(-\lambda D_i(x)))
+      41             : \f}
+      42             : 
+      43             : where the parameters \f$X_i\f$  and  \f$Y_i\f$ are provided in the input pdb (allv.pdb in this case) and
+      44             :  \f$D_i(x)\f$  is the mean squared displacement after optimal alignment calculated on the pdb frames you input (see Kearsley).
+      45             : 
+      46             : 
+      47             : When running with periodic boundary conditions, the atoms should be
+      48             : in the proper periodic image. This is done automatically since PLUMED 2.5,
+      49             : by considering the ordered list of atoms and rebuilding molecules using a procedure
+      50             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+      51             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+      52             : which actually modifies the coordinates stored in PLUMED.
+      53             : 
+      54             : In case you want to recover the old behavior you should use the NOPBC flag.
+      55             : In that case you need to take care that atoms are in the correct
+      56             : periodic image.
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : \plumedfile
+      61             : p3: PROPERTYMAP REFERENCE=allv.pdb PROPERTY=X,Y LAMBDA=69087 NEIGH_SIZE=8 NEIGH_STRIDE=4
+      62             : PRINT ARG=p3.X,p3.Y,p3.zzz STRIDE=1 FILE=colvar FMT=%8.4f
+      63             : \endplumedfile
+      64             : 
+      65             : note that NEIGH_STRIDE=4 NEIGH_SIZE=8 control the neighbor list parameter (optional but
+      66             : recommended for performance) and states that the neighbor list will be calculated every 4
+      67             : steps and consider only the closest 8 member to the actual md snapshots.
+      68             : 
+      69             : In this case the input line instructs plumed to look for two properties X and Y with attached values in the REMARK
+      70             : line of the reference pdb (Note: No spaces from X and = and 1 !!!!).
+      71             : e.g.
+      72             : 
+      73             : \auxfile{allv.pdb}
+      74             : REMARK X=1 Y=2
+      75             : ATOM      1  CL  ALA     1      -3.171   0.295   2.045  1.00  1.00
+      76             : ATOM      5  CLP ALA     1      -1.819  -0.143   1.679  1.00  1.00
+      77             : END
+      78             : REMARK X=2 Y=3
+      79             : ATOM      1  CL  ALA     1      -3.175   0.365   2.024  1.00  1.00
+      80             : ATOM      5  CLP ALA     1      -1.814  -0.106   1.685  1.00  1.00
+      81             : END
+      82             : \endauxfile
+      83             : 
+      84             : \note
+      85             : The implementation of this collective variable and of \ref PATHMSD
+      86             : is shared, as well as most input options.
+      87             : 
+      88             : */
+      89             : //+ENDPLUMEDOC
+      90             : 
+      91             : class PropertyMap : public PathMSDBase {
+      92             : public:
+      93             :   explicit PropertyMap(const ActionOptions&);
+      94             :   static void registerKeywords(Keywords& keys);
+      95             : };
+      96             : 
+      97             : PLUMED_REGISTER_ACTION(PropertyMap,"PROPERTYMAP")
+      98             : 
+      99          13 : void PropertyMap::registerKeywords(Keywords& keys) {
+     100          13 :   PathMSDBase::registerKeywords(keys);
+     101          26 :   keys.add("compulsory","PROPERTY","the property to be used in the indexing: this goes in the REMARK field of the reference");
+     102          13 :   ActionWithValue::useCustomisableComponents(keys);
+     103          26 :   keys.addOutputComponent("zzz","default","the minimum distance from the reference points");
+     104          13 : }
+     105             : 
+     106          11 : PropertyMap::PropertyMap(const ActionOptions&ao):
+     107             :   Action(ao),
+     108          11 :   PathMSDBase(ao)
+     109             : {
+     110             :   // this is the only additional keyword needed
+     111          11 :   parseVector("PROPERTY",labels);
+     112          11 :   checkRead();
+     113          11 :   log<<"  Bibliography "
+     114          22 :      <<plumed.cite("Spiwok V, Kralova B  J. Chem. Phys. 135,  224504 (2011)")
+     115          22 :      <<"\n";
+     116          11 :   if(labels.size()==0) {
+     117             :     const std::size_t buflen=500;
+     118             :     char buf[buflen];
+     119             :     std::snprintf(buf,buflen,"Need to specify PROPERTY with this action\n");
+     120           0 :     plumed_merror(buf);
+     121             :   } else {
+     122          33 :     for(unsigned i=0; i<labels.size(); i++) {
+     123          22 :       log<<" found custom propety to be found in the REMARK line: "<<labels[i].c_str()<<"\n";
+     124          44 :       addComponentWithDerivatives(labels[i]); componentIsNotPeriodic(labels[i]);
+     125             :     }
+     126             :     // add distance anyhow
+     127          22 :     addComponentWithDerivatives("zzz"); componentIsNotPeriodic("zzz");
+     128             :     //reparse the REMARK field and pick the index
+     129         473 :     for(unsigned i=0; i<pdbv.size(); i++) {
+     130             :       // now look for X=1.34555 Y=5.6677
+     131             :       std::vector<double> labelvals;
+     132        1386 :       for(unsigned j=0; j<labels.size(); j++) {
+     133             :         double val;
+     134         924 :         if( pdbv[i].getArgumentValue(labels[j],val) ) {labelvals.push_back(val);}
+     135             :         else {
+     136             :           const std::size_t buflen=500;
+     137             :           char buf[buflen];
+     138             :           std::snprintf(buf,buflen,"PROPERTY LABEL \" %s \" NOT FOUND IN REMARK FOR FRAME %u \n",labels[j].c_str(),i);
+     139           0 :           plumed_merror(buf);
+     140             :         };
+     141             :       }
+     142         462 :       indexvec.push_back(labelvals);
+     143             :     }
+     144             :   }
+     145          11 :   requestAtoms(pdbv[0].getAtomNumbers());
+     146             : 
+     147          11 : }
+     148             : 
+     149             : }
+     150             : }
+     151             : 
+     152             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Puckering.cpp.func-sort-c.html b/coverage/colvar/Puckering.cpp.func-sort-c.html new file mode 100644 index 000000000000..7fdf7cd60d58 --- /dev/null +++ b/coverage/colvar/Puckering.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Puckering.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Puckering.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22822999.6 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar9PuckeringC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar9PuckeringC1ERKNS_13ActionOptionsE54
_ZN4PLMD6colvar9Puckering16registerKeywordsERNS_8KeywordsE56
_ZN4PLMD6colvar9Puckering11calculate6mEv103
_ZN4PLMD6colvar9Puckering11calculate5mEv294
_ZN4PLMD6colvar9Puckering9calculateEv397
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Puckering.cpp.func.html b/coverage/colvar/Puckering.cpp.func.html new file mode 100644 index 000000000000..8770639def12 --- /dev/null +++ b/coverage/colvar/Puckering.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Puckering.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Puckering.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22822999.6 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar9Puckering11calculate5mEv294
_ZN4PLMD6colvar9Puckering11calculate6mEv103
_ZN4PLMD6colvar9Puckering16registerKeywordsERNS_8KeywordsE56
_ZN4PLMD6colvar9Puckering9calculateEv397
_ZN4PLMD6colvar9PuckeringC1ERKNS_13ActionOptionsE54
_ZN4PLMD6colvar9PuckeringC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Puckering.cpp.gcov.html b/coverage/colvar/Puckering.cpp.gcov.html new file mode 100644 index 000000000000..3accec61b4ae --- /dev/null +++ b/coverage/colvar/Puckering.cpp.gcov.html @@ -0,0 +1,497 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Puckering.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Puckering.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22822999.6 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Torsion.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace colvar {
+      29             : 
+      30             : //+PLUMEDOC COLVAR PUCKERING
+      31             : /*
+      32             :  Calculate sugar pseudorotation coordinates.
+      33             : 
+      34             :  This command can be used to calculate ring's pseudorotations in sugars (puckers). It works for both
+      35             :  5-membered and 6-membered rings. Notice that there are two different implementations depending if
+      36             :  one passes 5 or 6 atoms in the ATOMS keyword.
+      37             : 
+      38             :  For 5-membered rings the implementation is the one discussed in \cite huang2014improvement .
+      39             :  This implementation is simple and can be used in RNA to distinguish C2'-endo and C3'-endo conformations.
+      40             :  Both the polar coordinates (phs and amp) and the Cartesian coordinates (Zx and Zy) are provided.
+      41             :  C2'-endo conformations have negative Zx, whereas C3'-endo conformations have positive Zy.
+      42             :  Notation is consistent with \cite huang2014improvement .
+      43             :  The five atoms should be provided as C4',O4',C1',C2',C3'.
+      44             :  Notice that this is the same order that can be obtained using the \ref MOLINFO syntax (see example below).
+      45             : 
+      46             :  For 6-membered rings the implementation is the general Cremer-Pople one \cite cremer1975general
+      47             :  as also discussed in \cite biarnes2007conformational .
+      48             :  This implementation provides both a triplet with Cartesian components (qx, qy, and qz)
+      49             :  and a triplet of polar components (amplitude, phi, and theta).
+      50             :  Applications of this particular implementation are to be published (paper in preparation).
+      51             : 
+      52             :  \note The 6-membered ring implementation distributed with previous versions of PLUMED lead to
+      53             :  qx and qy values that had an opposite sign with respect to those originally defined in \cite cremer1975general.
+      54             :  The bug is fixed in version 2.5.
+      55             : 
+      56             :  Components of this action are:
+      57             : 
+      58             :  \par Examples
+      59             : 
+      60             :  This input tells plumed to print the puckering phase angle of the second nucleotide of a RNA molecule on file COLVAR.
+      61             :  \plumedfile
+      62             :  #SETTINGS MOLFILE=regtest/basic/rt65/AA.pdb
+      63             :  MOLINFO STRUCTURE=rna.pdb MOLTYPE=rna
+      64             :  PUCKERING ATOMS=@sugar-2 LABEL=puck
+      65             :  PRINT ARG=puck.phs FILE=COLVAR
+      66             :  \endplumedfile
+      67             : 
+      68             : */
+      69             : //+ENDPLUMEDOC
+      70             : 
+      71             : class Puckering : public Colvar {
+      72             : 
+      73             : public:
+      74             :   explicit Puckering(const ActionOptions&);
+      75             :   void calculate() override;
+      76             :   static void registerKeywords(Keywords& keys);
+      77             :   void calculate5m();
+      78             :   void calculate6m();
+      79             : };
+      80             : 
+      81             : PLUMED_REGISTER_ACTION(Puckering,"PUCKERING")
+      82             : 
+      83          56 : void Puckering::registerKeywords(Keywords& keys) {
+      84          56 :   Colvar::registerKeywords( keys );
+      85          56 :   keys.remove("NOPBC");
+      86         112 :   keys.add("atoms","ATOMS","the five or six atoms of the sugar ring in the proper order");
+      87         112 :   keys.addOutputComponent("phs","default","Pseudorotation phase (5 membered rings)");
+      88         112 :   keys.addOutputComponent("amp","default","Pseudorotation amplitude (5 membered rings)");
+      89         112 :   keys.addOutputComponent("Zx","default","Pseudorotation x Cartesian component (5 membered rings)");
+      90         112 :   keys.addOutputComponent("Zy","default","Pseudorotation y Cartesian component (5 membered rings)");
+      91         112 :   keys.addOutputComponent("phi","default","Pseudorotation phase (6 membered rings)");
+      92         112 :   keys.addOutputComponent("theta","default","Theta angle (6 membered rings)");
+      93         112 :   keys.addOutputComponent("amplitude","default","Pseudorotation amplitude (6 membered rings)");
+      94         112 :   keys.addOutputComponent("qx","default","Cartesian component x (6 membered rings)");
+      95         112 :   keys.addOutputComponent("qy","default","Cartesian component y (6 membered rings)");
+      96         112 :   keys.addOutputComponent("qz","default","Cartesian component z (6 membered rings)");
+      97          56 : }
+      98             : 
+      99          54 : Puckering::Puckering(const ActionOptions&ao):
+     100          54 :   PLUMED_COLVAR_INIT(ao)
+     101             : {
+     102             :   std::vector<AtomNumber> atoms;
+     103         108 :   parseAtomList("ATOMS",atoms);
+     104          54 :   if(atoms.size()!=5 && atoms.size()!=6) error("only for 5 or 6-membered rings");
+     105          53 :   checkRead();
+     106             : 
+     107          53 :   if(atoms.size()==5) {
+     108          52 :     log.printf("  between atoms %d %d %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial(),atoms[4].serial());
+     109           1 :   } else if(atoms.size()==6) {
+     110           1 :     log.printf("  between atoms %d %d %d %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial(),atoms[4].serial(),atoms[5].serial());
+     111           0 :   } else error("ATOMS should specify 5 atoms");
+     112             : 
+     113          53 :   if(atoms.size()==5) {
+     114         156 :     addComponentWithDerivatives("phs"); componentIsPeriodic("phs","-pi","pi");
+     115         156 :     addComponentWithDerivatives("amp"); componentIsNotPeriodic("amp");
+     116         156 :     addComponentWithDerivatives("Zx"); componentIsNotPeriodic("Zx");
+     117         156 :     addComponentWithDerivatives("Zy"); componentIsNotPeriodic("Zy");
+     118           1 :   } else if(atoms.size()==6) {
+     119           3 :     addComponentWithDerivatives("qx"); componentIsNotPeriodic("qx");
+     120           3 :     addComponentWithDerivatives("qy"); componentIsNotPeriodic("qy");
+     121           3 :     addComponentWithDerivatives("qz"); componentIsNotPeriodic("qz");
+     122           3 :     addComponentWithDerivatives("phi"); componentIsPeriodic("phi","0","2pi");
+     123           3 :     addComponentWithDerivatives("theta"); componentIsNotPeriodic("theta");
+     124           3 :     addComponentWithDerivatives("amplitude"); componentIsNotPeriodic("amplitude");
+     125             :   }
+     126             : 
+     127          53 :   log<<"  Bibliography ";
+     128         105 :   if(atoms.size()==5) log<<plumed.cite("Huang, Giese, Lee, York, J. Chem. Theory Comput. 10, 1538 (2014)");
+     129          55 :   if(atoms.size()==6) log<<plumed.cite("Cremer and Pople, J. Am. Chem. Soc. 97, 1354 (1975)");
+     130          53 :   log<<"\n";
+     131             : 
+     132          53 :   requestAtoms(atoms);
+     133          55 : }
+     134             : 
+     135             : // calculator
+     136         397 : void Puckering::calculate() {
+     137         397 :   makeWhole();
+     138         397 :   if(getNumberOfAtoms()==5) calculate5m();
+     139         103 :   else calculate6m();
+     140         397 : }
+     141             : 
+     142         294 : void Puckering::calculate5m() {
+     143             : 
+     144         294 :   Vector d0,d1,d2,d3,d4,d5;
+     145             : 
+     146         294 :   d0=delta(getPosition(2),getPosition(1));
+     147         294 :   d1=delta(getPosition(3),getPosition(2));
+     148         294 :   d2=delta(getPosition(4),getPosition(3));
+     149         294 :   d3=delta(getPosition(4),getPosition(3));
+     150         294 :   d4=delta(getPosition(0),getPosition(4));
+     151         294 :   d5=delta(getPosition(1),getPosition(0));
+     152             : 
+     153         294 :   Vector dd0,dd1,dd2,dd3,dd4,dd5;
+     154             : 
+     155             :   PLMD::Torsion t;
+     156             : 
+     157         294 :   double v1=t.compute(d0,d1,d2,dd0,dd1,dd2);
+     158         294 :   double v3=t.compute(d3,d4,d5,dd3,dd4,dd5);
+     159             : 
+     160         294 :   double Zx=(v1+v3)/(2.0*std::cos(4.0*pi/5.0));
+     161         294 :   double Zy=(v1-v3)/(2.0*std::sin(4.0*pi/5.0));
+     162         294 :   double phase=std::atan2(Zy,Zx);
+     163         294 :   double amplitude=std::sqrt(Zx*Zx+Zy*Zy);
+     164             : 
+     165        1764 :   Vector dZx_dR[5];
+     166        1764 :   Vector dZy_dR[5];
+     167             : 
+     168         294 :   dZx_dR[0]=(dd5-dd4);
+     169         294 :   dZx_dR[1]=(dd0-dd5);
+     170         294 :   dZx_dR[2]=(dd1-dd0);
+     171         294 :   dZx_dR[3]=(dd2+dd3-dd1);
+     172         294 :   dZx_dR[4]=(dd4-dd3-dd2);
+     173             : 
+     174         294 :   dZy_dR[0]=(dd4-dd5);
+     175         294 :   dZy_dR[1]=(dd0+dd5);
+     176         294 :   dZy_dR[2]=(dd1-dd0);
+     177         294 :   dZy_dR[3]=(dd2-dd3-dd1);
+     178         294 :   dZy_dR[4]=(dd3-dd4-dd2);
+     179             : 
+     180        1764 :   for(unsigned j=0; j<5; j++) dZx_dR[j]*=(1.0/(2.0*std::cos(4.0*pi/5.0)));
+     181        1764 :   for(unsigned j=0; j<5; j++) dZy_dR[j]*=(1.0/(2.0*std::sin(4.0*pi/5.0)));
+     182             : 
+     183        1764 :   Vector dphase_dR[5];
+     184        1764 :   for(unsigned j=0; j<5; j++) dphase_dR[j]=(1.0/(Zx*Zx+Zy*Zy))*(-Zy*dZx_dR[j] + Zx*dZy_dR[j]);
+     185             : 
+     186        1764 :   Vector damplitude_dR[5];
+     187        1764 :   for(unsigned j=0; j<5; j++) damplitude_dR[j]=(1.0/amplitude)*(Zx*dZx_dR[j] + Zy*dZy_dR[j]);
+     188             : 
+     189         588 :   Value* vzx=getPntrToComponent("Zx");
+     190             :   vzx->set(Zx);
+     191         294 :   setAtomsDerivatives (vzx,0, dZx_dR[0]);
+     192         294 :   setAtomsDerivatives (vzx,1, dZx_dR[1]);
+     193         294 :   setAtomsDerivatives (vzx,2, dZx_dR[2]);
+     194         294 :   setAtomsDerivatives (vzx,3, dZx_dR[3]);
+     195         294 :   setAtomsDerivatives (vzx,4, dZx_dR[4]);
+     196         294 :   setBoxDerivativesNoPbc(vzx);
+     197             : 
+     198         588 :   Value* vzy=getPntrToComponent("Zy");
+     199             :   vzy->set(Zy);
+     200         294 :   setAtomsDerivatives (vzy,0, dZy_dR[0]);
+     201         294 :   setAtomsDerivatives (vzy,1, dZy_dR[1]);
+     202         294 :   setAtomsDerivatives (vzy,2, dZy_dR[2]);
+     203         294 :   setAtomsDerivatives (vzy,3, dZy_dR[3]);
+     204         294 :   setAtomsDerivatives (vzy,4, dZy_dR[4]);
+     205         294 :   setBoxDerivativesNoPbc(vzy);
+     206             : 
+     207             : 
+     208         588 :   Value* vph=getPntrToComponent("phs");
+     209             :   vph->set(phase);
+     210         294 :   setAtomsDerivatives (vph,0, dphase_dR[0]);
+     211         294 :   setAtomsDerivatives (vph,1, dphase_dR[1]);
+     212         294 :   setAtomsDerivatives (vph,2, dphase_dR[2]);
+     213         294 :   setAtomsDerivatives (vph,3, dphase_dR[3]);
+     214         294 :   setAtomsDerivatives (vph,4, dphase_dR[4]);
+     215         294 :   setBoxDerivativesNoPbc(vph);
+     216             : 
+     217         588 :   Value* vam=getPntrToComponent("amp");
+     218             :   vam->set(amplitude);
+     219         294 :   setAtomsDerivatives (vam,0, damplitude_dR[0]);
+     220         294 :   setAtomsDerivatives (vam,1, damplitude_dR[1]);
+     221         294 :   setAtomsDerivatives (vam,2, damplitude_dR[2]);
+     222         294 :   setAtomsDerivatives (vam,3, damplitude_dR[3]);
+     223         294 :   setAtomsDerivatives (vam,4, damplitude_dR[4]);
+     224         294 :   setBoxDerivativesNoPbc(vam);
+     225             : 
+     226             : 
+     227         294 : }
+     228             : 
+     229         103 : void Puckering::calculate6m() {
+     230             : 
+     231         103 :   std::vector<Vector> r(6);
+     232         721 :   for(unsigned i=0; i<6; i++) r[i]=getPosition(i);
+     233             : 
+     234         103 :   std::vector<Vector> R(6);
+     235         103 :   Vector center;
+     236         721 :   for(unsigned j=0; j<6; j++) center+=r[j]/6.0;
+     237         721 :   for(unsigned j=0; j<6; j++) R[j]=(r[j]-center);
+     238             : 
+     239         103 :   Vector Rp,Rpp;
+     240         721 :   for(unsigned j=0; j<6; j++) Rp +=R[j]*std::sin(2.0/6.0*pi*j);
+     241         721 :   for(unsigned j=0; j<6; j++) Rpp+=R[j]*std::cos(2.0/6.0*pi*j);
+     242             : 
+     243         103 :   Vector n=crossProduct(Rp,Rpp);
+     244         103 :   Vector nhat=n/modulo(n);
+     245             : 
+     246         103 :   Tensor dn_dRp=dcrossDv1(Rp,Rpp);
+     247         103 :   Tensor dn_dRpp=dcrossDv2(Rp,Rpp);
+     248             : 
+     249         103 :   Tensor dnhat_dn= 1.0/modulo(n)*( Tensor::identity() - extProduct(nhat,nhat));
+     250         103 :   Tensor dnhat_dRp=matmul(dnhat_dn,dn_dRp);
+     251         103 :   Tensor dnhat_dRpp=matmul(dnhat_dn,dn_dRpp);
+     252             : 
+     253         103 :   std::vector<double> z(6);
+     254         721 :   for(unsigned j=0; j<6; j++) z[j]=dotProduct(R[j],nhat);
+     255             : 
+     256         103 :   std::vector<std::vector<Vector> > dz_dR(6);
+     257         721 :   for(unsigned j=0; j<6; j++) dz_dR[j].resize(6);
+     258             : 
+     259        4429 :   for(unsigned i=0; i<6; i++) for(unsigned j=0; j<6; j++) {
+     260        3708 :       if(i==j) dz_dR[i][j]+=nhat;
+     261        3708 :       dz_dR[i][j]+=matmul(R[i],dnhat_dRp)*std::sin(2.0/6.0*pi*j);
+     262        3708 :       dz_dR[i][j]+=matmul(R[i],dnhat_dRpp)*std::cos(2.0/6.0*pi*j);
+     263             :     }
+     264             : 
+     265             :   double B=0.0;
+     266         721 :   for(unsigned j=0; j<6; j++) B+=z[j]*std::cos(4.0/6.0*pi*j);
+     267             : 
+     268         103 :   std::vector<Vector> dB_dR(6);
+     269        4429 :   for(unsigned i=0; i<6; i++) for(unsigned j=0; j<6; j++) {
+     270        3708 :       dB_dR[i]+=dz_dR[j][i]*std::cos(4.0/6.0*pi*j);
+     271             :     }
+     272         103 :   Vector Bsum;
+     273         721 :   for(unsigned j=0; j<6; j++) Bsum+=dB_dR[j];
+     274         721 :   for(unsigned j=0; j<6; j++) dB_dR[j]-=Bsum/6.0;;
+     275             : 
+     276             :   double A=0.0;
+     277         721 :   for(unsigned j=0; j<6; j++) A+=z[j]*std::sin(4.0/6.0*pi*j);
+     278             : 
+     279         103 :   std::vector<Vector> dA_dR(6);
+     280        4429 :   for(unsigned i=0; i<6; i++) for(unsigned j=0; j<6; j++) {
+     281        3708 :       dA_dR[i]+=dz_dR[j][i]*std::sin(4.0/6.0*pi*j);
+     282             :     }
+     283         103 :   Vector Asum;
+     284         721 :   for(unsigned j=0; j<6; j++) Asum+=dA_dR[j];
+     285         721 :   for(unsigned j=0; j<6; j++) dA_dR[j]-=Asum/6.0;;
+     286             : 
+     287             :   double C=0.0;
+     288         721 :   for(unsigned j=0; j<6; j++) C+=z[j]*Tools::fastpow(-1.0,(j));
+     289             : 
+     290         103 :   std::vector<Vector> dC_dR(6);
+     291        4429 :   for(unsigned i=0; i<6; i++) for(unsigned j=0; j<6; j++) {
+     292        3708 :       dC_dR[i]+=dz_dR[j][i]*Tools::fastpow(-1.0,(j));
+     293             :     }
+     294             : 
+     295         103 :   Vector Csum;
+     296         721 :   for(unsigned j=0; j<6; j++) Csum+=dC_dR[j];
+     297         721 :   for(unsigned j=0; j<6; j++) dC_dR[j]-=Csum/6.0;;
+     298             : 
+     299             : 
+     300             : // qx
+     301         103 :   double qx = -A/std::sqrt(3);
+     302             : 
+     303             : // qx derivaties
+     304         103 :   std::vector<Vector> dqx_dR(6);
+     305         721 :   for(unsigned j=0; j<6; j++) {
+     306         618 :     dqx_dR[j]=-1/std::sqrt(3) * dA_dR[j];
+     307             :   }
+     308             : 
+     309         206 :   Value* vqx=getPntrToComponent("qx");
+     310             :   vqx->set(qx);
+     311         103 :   setAtomsDerivatives (vqx,0, dqx_dR[0] );
+     312         103 :   setAtomsDerivatives (vqx,1, dqx_dR[1] );
+     313         103 :   setAtomsDerivatives (vqx,2, dqx_dR[2] );
+     314         103 :   setAtomsDerivatives (vqx,3, dqx_dR[3] );
+     315         103 :   setAtomsDerivatives (vqx,4, dqx_dR[4] );
+     316         103 :   setAtomsDerivatives (vqx,5, dqx_dR[5] );
+     317         103 :   setBoxDerivativesNoPbc(vqx);
+     318             : 
+     319             : // qy
+     320         103 :   double qy = B/std::sqrt(3);
+     321             : 
+     322             : // qy derivatives
+     323         103 :   std::vector<Vector> dqy_dR(6);
+     324         721 :   for(unsigned j=0; j<6; j++) {
+     325         618 :     dqy_dR[j]=1/std::sqrt(3) * dB_dR[j];
+     326             :   }
+     327             : 
+     328         206 :   Value* vqy=getPntrToComponent("qy");
+     329             :   vqy->set(qy);
+     330         103 :   setAtomsDerivatives (vqy,0, dqy_dR[0] );
+     331         103 :   setAtomsDerivatives (vqy,1, dqy_dR[1] );
+     332         103 :   setAtomsDerivatives (vqy,2, dqy_dR[2] );
+     333         103 :   setAtomsDerivatives (vqy,3, dqy_dR[3] );
+     334         103 :   setAtomsDerivatives (vqy,4, dqy_dR[4] );
+     335         103 :   setAtomsDerivatives (vqy,5, dqy_dR[5] );
+     336         103 :   setBoxDerivativesNoPbc(vqy);
+     337             : 
+     338             : // qz
+     339         103 :   double qz = C/std::sqrt(6);
+     340             : 
+     341             : // qz derivatives
+     342         103 :   std::vector<Vector> dqz_dR(6);
+     343         721 :   for(unsigned j=0; j<6; j++) {
+     344         618 :     dqz_dR[j]=1/std::sqrt(6) * dC_dR[j];
+     345             :   }
+     346             : 
+     347         206 :   Value* vqz=getPntrToComponent("qz");
+     348             :   vqz->set(qz);
+     349         103 :   setAtomsDerivatives (vqz,0, dqz_dR[0] );
+     350         103 :   setAtomsDerivatives (vqz,1, dqz_dR[1] );
+     351         103 :   setAtomsDerivatives (vqz,2, dqz_dR[2] );
+     352         103 :   setAtomsDerivatives (vqz,3, dqz_dR[3] );
+     353         103 :   setAtomsDerivatives (vqz,4, dqz_dR[4] );
+     354         103 :   setAtomsDerivatives (vqz,5, dqz_dR[5] );
+     355         103 :   setBoxDerivativesNoPbc(vqz);
+     356             : 
+     357             : 
+     358             : // PHASE
+     359         103 :   double phi=std::atan2(-A,B);
+     360             : 
+     361             : // PHASE DERIVATIVES
+     362         103 :   std::vector<Vector> dphi_dR(6);
+     363         721 :   for(unsigned j=0; j<6; j++) {
+     364         618 :     dphi_dR[j]=1.0/(A*A+B*B) * (-B*dA_dR[j] + A*dB_dR[j]);
+     365             :   }
+     366             : 
+     367         206 :   Value* vphi=getPntrToComponent("phi");
+     368             :   vphi->set(phi);
+     369         103 :   setAtomsDerivatives (vphi,0, dphi_dR[0] );
+     370         103 :   setAtomsDerivatives (vphi,1, dphi_dR[1] );
+     371         103 :   setAtomsDerivatives (vphi,2, dphi_dR[2] );
+     372         103 :   setAtomsDerivatives (vphi,3, dphi_dR[3] );
+     373         103 :   setAtomsDerivatives (vphi,4, dphi_dR[4] );
+     374         103 :   setAtomsDerivatives (vphi,5, dphi_dR[5] );
+     375         103 :   setBoxDerivativesNoPbc(vphi);
+     376             : 
+     377             : //  AMPLITUDE
+     378         103 :   double amplitude=std::sqrt((2*(A*A+B*B)+C*C)/6);
+     379             : 
+     380             : //  AMPLITUDE DERIVATIES
+     381         103 :   std::vector<Vector> damplitude_dR(6);
+     382         721 :   for (unsigned j=0; j<6; j++) {
+     383         618 :     damplitude_dR[j]=0.5*std::sqrt(2.0/6.0)/(std::sqrt(A*A+B*B+0.5*C*C)) * (2*A*dA_dR[j] + 2*B*dB_dR[j] + C*dC_dR[j]);
+     384             :   }
+     385             : 
+     386         206 :   Value* vamplitude=getPntrToComponent("amplitude");
+     387             :   vamplitude->set(amplitude);
+     388         103 :   setAtomsDerivatives (vamplitude,0, damplitude_dR[0] );
+     389         103 :   setAtomsDerivatives (vamplitude,1, damplitude_dR[1] );
+     390         103 :   setAtomsDerivatives (vamplitude,2, damplitude_dR[2] );
+     391         103 :   setAtomsDerivatives (vamplitude,3, damplitude_dR[3] );
+     392         103 :   setAtomsDerivatives (vamplitude,4, damplitude_dR[4] );
+     393         103 :   setAtomsDerivatives (vamplitude,5, damplitude_dR[5] );
+     394         103 :   setBoxDerivativesNoPbc(vamplitude);
+     395             : 
+     396             : //  THETA
+     397         103 :   double theta=std::acos( C / std::sqrt(2.*(A*A+B*B) +C*C ) );
+     398             : 
+     399             : //  THETA DERIVATIVES
+     400         103 :   std::vector<Vector> dtheta_dR(6);
+     401         721 :   for(unsigned j=0; j<6; j++) {
+     402         618 :     dtheta_dR[j]=1.0/(3.0*std::sqrt(2)*amplitude*amplitude) * (C/(std::sqrt(A*A+B*B)) * (A*dA_dR[j] + B*dB_dR[j]) - std::sqrt(A*A+B*B)*dC_dR[j]);
+     403             :   }
+     404         206 :   Value* vtheta=getPntrToComponent("theta");
+     405             :   vtheta->set(theta);
+     406         103 :   setAtomsDerivatives (vtheta,0, dtheta_dR[0] );
+     407         103 :   setAtomsDerivatives (vtheta,1, dtheta_dR[1] );
+     408         103 :   setAtomsDerivatives (vtheta,2, dtheta_dR[2] );
+     409         103 :   setAtomsDerivatives (vtheta,3, dtheta_dR[3] );
+     410         103 :   setAtomsDerivatives (vtheta,4, dtheta_dR[4] );
+     411         103 :   setAtomsDerivatives (vtheta,5, dtheta_dR[5] );
+     412         103 :   setBoxDerivativesNoPbc(vtheta);
+     413         206 : }
+     414             : 
+     415             : 
+     416             : }
+     417             : }
+     418             : 
+     419             : 
+     420             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSD.cpp.func-sort-c.html b/coverage/colvar/RMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..aeca056be112 --- /dev/null +++ b/coverage/colvar/RMSD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/RMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4RMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar4RMSDC1ERKNS_13ActionOptionsE78
_ZN4PLMD6colvar4RMSD16registerKeywordsERNS_8KeywordsE80
_ZN4PLMD6colvar4RMSD9calculateEv40496
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSD.cpp.func.html b/coverage/colvar/RMSD.cpp.func.html new file mode 100644 index 000000000000..f92b4bfd9639 --- /dev/null +++ b/coverage/colvar/RMSD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/RMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar4RMSD16registerKeywordsERNS_8KeywordsE80
_ZN4PLMD6colvar4RMSD9calculateEv40496
_ZN4PLMD6colvar4RMSDC1ERKNS_13ActionOptionsE78
_ZN4PLMD6colvar4RMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/RMSD.cpp.gcov.html b/coverage/colvar/RMSD.cpp.gcov.html new file mode 100644 index 000000000000..611e5b155c9e --- /dev/null +++ b/coverage/colvar/RMSD.cpp.gcov.html @@ -0,0 +1,314 @@ + + + + + + + + LCOV - plumed test coverage - colvar/RMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/PDB.h"
+      26             : #include "reference/RMSDBase.h"
+      27             : #include "reference/MetricRegister.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace colvar {
+      31             : 
+      32             : class RMSD : public Colvar {
+      33             : 
+      34             :   MultiValue myvals;
+      35             :   ReferenceValuePack mypack;
+      36             :   std::unique_ptr<PLMD::RMSDBase> rmsd;
+      37             :   bool squared;
+      38             :   bool nopbc;
+      39             : 
+      40             : public:
+      41             :   explicit RMSD(const ActionOptions&);
+      42             :   void calculate() override;
+      43             :   static void registerKeywords(Keywords& keys);
+      44             : };
+      45             : 
+      46             : //+PLUMEDOC DCOLVAR RMSD
+      47             : /*
+      48             : Calculate the RMSD with respect to a reference structure.
+      49             : 
+      50             : The aim with this colvar it to calculate something like:
+      51             : 
+      52             : \f[
+      53             : d(X,X') = \vert X-X' \vert
+      54             : \f]
+      55             : 
+      56             : where \f$ X \f$ is the instantaneous position of all the atoms in the system and
+      57             : \f$ X' \f$ is the positions of the atoms in some reference structure provided as input.
+      58             : \f$ d(X,X') \f$ thus measures the distance all the atoms have moved away from this reference configuration.
+      59             : Oftentimes, it is only the internal motions of the structure - i.e. not the translations of the center of
+      60             : mass or the rotations of the reference frame - that are interesting.  Hence, when calculating the
+      61             : the root-mean-square deviation between the atoms in two configurations
+      62             : you must first superimpose the two structures in some way. At present PLUMED provides two distinct ways
+      63             : of performing this superposition.  The first method is applied when you use TYPE=SIMPLE in the input
+      64             : line.  This instruction tells PLUMED that the root mean square deviation is to be calculated after the
+      65             : positions of the geometric centers in the reference and instantaneous configurations are aligned.  In
+      66             : other words \f$d(X,x')\f$ is to be calculated using:
+      67             : 
+      68             : \f[
+      69             :  d(X,X') = \sqrt{ \sum_i \sum_\alpha^{x,y,z}  \frac{w_i}{\sum_j w_j}( X_{i,\alpha}-com_\alpha(X)-{X'}_{i,\alpha}+com_\alpha(X') )^2 }
+      70             : \f]
+      71             : with
+      72             : \f[
+      73             : com_\alpha(X)= \sum_i  \frac{w'_{i}}{\sum_j w'_j}X_{i,\alpha}
+      74             : \f]
+      75             : and
+      76             : \f[
+      77             : com_\alpha(X')= \sum_i  \frac{w'_{i}}{\sum_j w'_j}X'_{i,\alpha}
+      78             : \f]
+      79             : Obviously, \f$ com_\alpha(X) \f$ and  \f$ com_\alpha(X') \f$  represent the positions of the center of mass in the reference
+      80             : and instantaneous configurations if the weights $w'$ are set equal to the atomic masses.  If the weights are all set equal to
+      81             : one, however, \f$com_\alpha(X) \f$ and  \f$ com_\alpha(X') \f$ are the positions of the geometric centers.
+      82             : Notice that there are sets of weights:  \f$ w' \f$ and  \f$ w \f$. The first is used to calculate the position of the center of mass
+      83             : (so it determines how the atoms are \e aligned).  Meanwhile, the second is used when calculating how far the atoms have actually been
+      84             : \e displaced.  These weights are assigned in the reference configuration that you provide as input (i.e. the appear in the input file
+      85             : to this action that you set using REFERENCE=whatever.pdb).  This input reference configuration consists of a simple pdb file
+      86             : containing the set of atoms for which you want to calculate the RMSD displacement and their positions in the reference configuration.
+      87             : It is important to note that the indices in this pdb need to be set correctly.  The indices in this file determine the indices of the
+      88             : instantaneous atomic positions that are used by PLUMED when calculating this colvar.  As such if you want to calculate the RMSD distance
+      89             : moved by the first, fourth, sixth and twenty eighth atoms in the MD codes input file then the indices of the corresponding reference positions in this pdb
+      90             : file should be set equal to 1, 4, 6 and 28.
+      91             : 
+      92             : The pdb input file should also contain the values of \f$w\f$ and \f$w'\f$. In particular, the OCCUPANCY column (the first column after the coordinates)
+      93             : is used provides the values of \f$ w'\f$ that are used to calculate the position of the center of mass.  The BETA column (the second column
+      94             : after the Cartesian coordinates) is used to provide the \f$ w \f$ values which are used in the the calculation of the displacement.
+      95             : Please note that it is possible to use fractional values for beta and for the occupancy. However, we recommend you only do this when
+      96             : you really know what you are doing however as the results can be rather strange.
+      97             : 
+      98             : In PDB files the atomic coordinates and box lengths should be in Angstroms unless
+      99             : you are working with natural units.  If you are working with natural units then the coordinates
+     100             : should be in your natural length unit.  For more details on the PDB file format visit http://www.wwpdb.org/docs.html.
+     101             : Make sure your PDB file is correctly formatted as explained \ref pdbreader "in this page".
+     102             : 
+     103             : A different method is used to calculate the RMSD distance when you use TYPE=OPTIMAL on the input line.  In this case  the root mean square
+     104             : deviation is calculated after the positions of geometric centers in the reference and instantaneous configurations are aligned AND after
+     105             : an optimal alignment of the two frames is performed so that motion due to rotation of the reference frame between the two structures is
+     106             : removed.  The equation for \f$d(X,X')\f$ in this case reads:
+     107             : 
+     108             : \f[
+     109             : d(X,X') = \sqrt{ \sum_i \sum_\alpha^{x,y,z}  \frac{w_i}{\sum_j w_j}[ X_{i,\alpha}-com_\alpha(X)- \sum_\beta M(X,X',w')_{\alpha,\beta}({X'}_{i,\beta}-com_\beta(X')) ]^2 }
+     110             : \f]
+     111             : 
+     112             : where \f$ M(X,X',w') \f$ is the optimal alignment matrix which is calculated using the Kearsley \cite kearsley algorithm.  Again different sets of
+     113             : weights are used for the alignment (\f$w'\f$) and for the displacement calculations (\f$w\f$).
+     114             : This gives a great deal of flexibility as it allows you to use a different sets of atoms (which may or may not overlap) for the alignment and displacement
+     115             : parts of the calculation. This may be very useful when you want to calculate how a ligand moves about in a protein cavity as you can use the protein as a reference
+     116             : system and do no alignment of the ligand.
+     117             : 
+     118             : (Note: when this form of RMSD is used to calculate the secondary structure variables (\ref ALPHARMSD, \ref ANTIBETARMSD and \ref PARABETARMSD
+     119             : all the atoms in the segment are assumed to be part of both the alignment and displacement sets and all weights are set equal to one)
+     120             : 
+     121             : Please note that there are a number of other methods for calculating the distance between the instantaneous configuration and a reference configuration
+     122             : that are available in plumed.  More information on these various methods can be found in the section of the manual on \ref dists.
+     123             : 
+     124             : When running with periodic boundary conditions, the atoms should be
+     125             : in the proper periodic image. This is done automatically since PLUMED 2.5,
+     126             : by considering the ordered list of atoms and rebuilding molecules using a procedure
+     127             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+     128             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+     129             : which actually modifies the coordinates stored in PLUMED.
+     130             : 
+     131             : In case you want to recover the old behavior you should use the NOPBC flag.
+     132             : In that case you need to take care that atoms are in the correct
+     133             : periodic image.
+     134             : 
+     135             : \par Examples
+     136             : 
+     137             : The following tells plumed to calculate the RMSD distance between
+     138             : the positions of the atoms in the reference file and their instantaneous
+     139             : position.  The Kearsley algorithm is used so this is done optimally.
+     140             : 
+     141             : \plumedfile
+     142             : RMSD REFERENCE=file.pdb TYPE=OPTIMAL
+     143             : \endplumedfile
+     144             : 
+     145             : The reference configuration is specified in a pdb file that will have a format similar to the one shown below:
+     146             : 
+     147             : \auxfile{file.pdb}
+     148             : ATOM      1  CL  ALA     1      -3.171   0.295   2.045  1.00  1.00
+     149             : ATOM      5  CLP ALA     1      -1.819  -0.143   1.679  1.00  1.00
+     150             : ATOM      6  OL  ALA     1      -1.177  -0.889   2.401  1.00  1.00
+     151             : ATOM      7  NL  ALA     1      -1.313   0.341   0.529  1.00  1.00
+     152             : ATOM      8  HL  ALA     1      -1.845   0.961  -0.011  1.00  1.00
+     153             : END
+     154             : \endauxfile
+     155             : 
+     156             : ...
+     157             : 
+     158             : */
+     159             : //+ENDPLUMEDOC
+     160             : 
+     161             : PLUMED_REGISTER_ACTION(RMSD,"RMSD")
+     162             : 
+     163          80 : void RMSD::registerKeywords(Keywords& keys) {
+     164          80 :   Colvar::registerKeywords(keys);
+     165         160 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     166         160 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be OPTIMAL or SIMPLE.");
+     167         160 :   keys.addFlag("SQUARED",false," This should be set if you want mean squared displacement instead of RMSD ");
+     168          80 : }
+     169             : 
+     170          78 : RMSD::RMSD(const ActionOptions&ao):
+     171             :   PLUMED_COLVAR_INIT(ao),
+     172         158 :   myvals(1,0),
+     173          78 :   mypack(0,0,myvals),
+     174          78 :   squared(false),
+     175         156 :   nopbc(false)
+     176             : {
+     177             :   std::string reference;
+     178         158 :   parse("REFERENCE",reference);
+     179             :   std::string type;
+     180          78 :   type.assign("SIMPLE");
+     181          78 :   parse("TYPE",type);
+     182          78 :   parseFlag("SQUARED",squared);
+     183          78 :   parseFlag("NOPBC",nopbc);
+     184             : 
+     185          78 :   checkRead();
+     186             : 
+     187             : 
+     188         158 :   addValueWithDerivatives(); setNotPeriodic();
+     189          78 :   PDB pdb;
+     190             : 
+     191             :   // read everything in ang and transform to nm if we are not in natural units
+     192          78 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     193           1 :     error("missing input file " + reference );
+     194             : 
+     195         154 :   rmsd=metricRegister().create<RMSDBase>(type,pdb);
+     196             : 
+     197             :   std::vector<AtomNumber> atoms;
+     198          77 :   rmsd->getAtomRequests( atoms );
+     199             : //  rmsd->setNumberOfAtoms( atoms.size() );
+     200          77 :   requestAtoms( atoms );
+     201             : 
+     202             :   // Setup the derivative pack
+     203          77 :   myvals.resize( 1, 3*atoms.size()+9 ); mypack.resize( 0, atoms.size() );
+     204        3833 :   for(unsigned i=0; i<atoms.size(); ++i) mypack.setAtomIndex( i, i );
+     205             : 
+     206          76 :   log.printf("  reference from file %s\n",reference.c_str());
+     207          76 :   log.printf("  which contains %d atoms\n",getNumberOfAtoms());
+     208          76 :   log.printf("  with indices : ");
+     209        3833 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     210        3757 :     if(i%25==0) log<<"\n";
+     211        3757 :     log.printf("%d ",atoms[i].serial());
+     212             :   }
+     213          76 :   log.printf("\n");
+     214          76 :   log.printf("  method for alignment : %s \n",type.c_str() );
+     215          76 :   if(squared)log.printf("  chosen to use SQUARED option for MSD instead of RMSD\n");
+     216          76 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     217          19 :   else      log.printf("  using periodic boundary conditions\n");
+     218         164 : }
+     219             : 
+     220             : 
+     221             : // calculator
+     222       40496 : void RMSD::calculate() {
+     223       40496 :   if(!nopbc) makeWhole();
+     224       40496 :   double r=rmsd->calculate( getPositions(), mypack, squared );
+     225             : 
+     226       40496 :   setValue(r);
+     227    14617727 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) setAtomsDerivatives( i, mypack.getAtomDerivative(i) );
+     228             : 
+     229       40496 :   Tensor virial; plumed_dbg_assert( !mypack.virialWasSet() );
+     230       40496 :   setBoxDerivativesNoPbc();
+     231       40496 : }
+     232             : 
+     233             : }
+     234             : }
+     235             : 
+     236             : 
+     237             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Template.cpp.func-sort-c.html b/coverage/colvar/Template.cpp.func-sort-c.html new file mode 100644 index 000000000000..b6eccbf27390 --- /dev/null +++ b/coverage/colvar/Template.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Template.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Template.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:73420.6 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8Template9calculateEv0
_ZN4PLMD6colvar8TemplateC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8TemplateC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8Template16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Template.cpp.func.html b/coverage/colvar/Template.cpp.func.html new file mode 100644 index 000000000000..e920403af4c6 --- /dev/null +++ b/coverage/colvar/Template.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Template.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Template.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:73420.6 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar8Template16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6colvar8Template9calculateEv0
_ZN4PLMD6colvar8TemplateC1ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar8TemplateC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Template.cpp.gcov.html b/coverage/colvar/Template.cpp.gcov.html new file mode 100644 index 000000000000..3406e36b1e35 --- /dev/null +++ b/coverage/colvar/Template.cpp.gcov.html @@ -0,0 +1,191 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Template.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Template.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:73420.6 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace colvar {
+      27             : 
+      28             : //+PLUMEDOC COLVAR TEMPLATE
+      29             : /*
+      30             : This file provides a template for if you want to introduce a new CV.
+      31             : 
+      32             : <!-----You should add a description of your CV here---->
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : <!---You should put an example of how to use your CV here--->
+      37             : 
+      38             : \plumedfile
+      39             : # This should be a sample input.
+      40             : t: TEMPLATE ATOMS=1,2
+      41             : PRINT ARG=t STRIDE=100 FILE=COLVAR
+      42             : \endplumedfile
+      43             : <!---You should reference here the other actions used in this example--->
+      44             : (see also \ref PRINT)
+      45             : 
+      46             : */
+      47             : //+ENDPLUMEDOC
+      48             : 
+      49             : class Template : public Colvar {
+      50             :   bool pbc;
+      51             : 
+      52             : public:
+      53             :   explicit Template(const ActionOptions&);
+      54             : // active methods:
+      55             :   void calculate() override;
+      56             :   static void registerKeywords(Keywords& keys);
+      57             : };
+      58             : 
+      59             : PLUMED_REGISTER_ACTION(Template,"TEMPLATE")
+      60             : 
+      61           2 : void Template::registerKeywords(Keywords& keys) {
+      62           2 :   Colvar::registerKeywords(keys);
+      63           4 :   keys.addFlag("TEMPLATE_DEFAULT_OFF_FLAG",false,"flags that are by default not performed should be specified like this");
+      64           4 :   keys.add("compulsory","TEMPLATE_COMPULSORY","all compulsory keywords should be added like this with a description here");
+      65           4 :   keys.add("optional","TEMPLATE_OPTIONAL","all optional keywords that have input should be added like a description here");
+      66           4 :   keys.add("atoms","ATOMS","the keyword with which you specify what atoms to use should be added like this");
+      67           2 : }
+      68             : 
+      69           0 : Template::Template(const ActionOptions&ao):
+      70             :   PLUMED_COLVAR_INIT(ao),
+      71           0 :   pbc(true)
+      72             : {
+      73             :   std::vector<AtomNumber> atoms;
+      74           0 :   parseAtomList("ATOMS",atoms);
+      75           0 :   if(atoms.size()!=2)
+      76           0 :     error("Number of specified atoms should be 2");
+      77           0 :   bool nopbc=!pbc;
+      78           0 :   parseFlag("NOPBC",nopbc);
+      79           0 :   pbc=!nopbc;
+      80           0 :   checkRead();
+      81             : 
+      82           0 :   log.printf("  between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
+      83           0 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+      84           0 :   else    log.printf("  without periodic boundary conditions\n");
+      85             : 
+      86           0 :   addValueWithDerivatives(); setNotPeriodic();
+      87             : 
+      88           0 :   requestAtoms(atoms);
+      89           0 : }
+      90             : 
+      91             : 
+      92             : // calculator
+      93           0 : void Template::calculate() {
+      94             : 
+      95           0 :   Vector distance;
+      96           0 :   if(pbc) {
+      97           0 :     distance=pbcDistance(getPosition(0),getPosition(1));
+      98             :   } else {
+      99           0 :     distance=delta(getPosition(0),getPosition(1));
+     100             :   }
+     101           0 :   const double value=distance.modulo();
+     102           0 :   const double invvalue=1.0/value;
+     103             : 
+     104           0 :   setAtomsDerivatives(0,-invvalue*distance);
+     105           0 :   setAtomsDerivatives(1,invvalue*distance);
+     106           0 :   setBoxDerivatives  (-invvalue*Tensor(distance,distance));
+     107           0 :   setValue           (value);
+     108           0 : }
+     109             : 
+     110             : }
+     111             : }
+     112             : 
+     113             : 
+     114             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Torsion.cpp.func-sort-c.html b/coverage/colvar/Torsion.cpp.func-sort-c.html new file mode 100644 index 000000000000..2ce709162448 --- /dev/null +++ b/coverage/colvar/Torsion.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Torsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626891.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7TorsionC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar7TorsionC1ERKNS_13ActionOptionsE653
_ZN4PLMD6colvar7Torsion16registerKeywordsERNS_8KeywordsE655
_ZN4PLMD6colvar7Torsion9calculateEv34543
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Torsion.cpp.func.html b/coverage/colvar/Torsion.cpp.func.html new file mode 100644 index 000000000000..7dbdfc8e9559 --- /dev/null +++ b/coverage/colvar/Torsion.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Torsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626891.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar7Torsion16registerKeywordsERNS_8KeywordsE655
_ZN4PLMD6colvar7Torsion9calculateEv34543
_ZN4PLMD6colvar7TorsionC1ERKNS_13ActionOptionsE653
_ZN4PLMD6colvar7TorsionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Torsion.cpp.gcov.html b/coverage/colvar/Torsion.cpp.gcov.html new file mode 100644 index 000000000000..e14ca0ef808c --- /dev/null +++ b/coverage/colvar/Torsion.cpp.gcov.html @@ -0,0 +1,272 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Torsion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626891.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Torsion.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace colvar {
+      28             : 
+      29             : //+PLUMEDOC COLVAR TORSION
+      30             : /*
+      31             : Calculate a torsional angle.
+      32             : 
+      33             : This command can be used to compute the torsion between four atoms or alternatively
+      34             : to calculate the angle between two vectors projected on the plane
+      35             : orthogonal to an axis.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : This input tells plumed to print the torsional angle between atoms 1, 2, 3 and 4
+      40             : on file COLVAR.
+      41             : \plumedfile
+      42             : t: TORSION ATOMS=1,2,3,4
+      43             : # this is an alternative, equivalent, definition:
+      44             : # t: TORSION VECTOR1=2,1 AXIS=2,3 VECTOR2=3,4
+      45             : PRINT ARG=t FILE=COLVAR
+      46             : \endplumedfile
+      47             : 
+      48             : If you are working with a protein you can specify the special named torsion angles \f$\phi\f$, \f$\psi\f$, \f$\omega\f$ and \f$\chi_1\f$
+      49             : by using TORSION in combination with the \ref MOLINFO command.  This can be done by using the following
+      50             : syntax.
+      51             : 
+      52             : \plumedfile
+      53             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      54             : MOLINFO MOLTYPE=protein STRUCTURE=myprotein.pdb
+      55             : t1: TORSION ATOMS=@phi-3
+      56             : t2: TORSION ATOMS=@psi-4
+      57             : PRINT ARG=t1,t2 FILE=colvar STRIDE=10
+      58             : \endplumedfile
+      59             : 
+      60             : Here, \@phi-3 tells plumed that you would like to calculate the \f$\phi\f$ angle in the third residue of the protein.
+      61             : Similarly \@psi-4 tells plumed that you want to calculate the \f$\psi\f$ angle of the fourth residue of the protein.
+      62             : 
+      63             : Both of the previous examples specify that the torsion angle should be calculated based on the position of four atoms.
+      64             : For the first example in particular the assumption when the torsion is specified in this way is that there are chemical
+      65             : bonds between atoms 1 and 2, atoms 2 and 3 and atoms 3 and 4. In general, however, a torsional angle measures the angle
+      66             : between two planes, which have at least one vector in common.  As shown below, there is thus an alternate, more general, way
+      67             : through which we can define a torsional angle:
+      68             : 
+      69             : \plumedfile
+      70             : t1: TORSION VECTOR1=1,2 AXIS=3,4 VECTOR2=5,6
+      71             : PRINT ARG=t1 FILE=colvar STRIDE=20
+      72             : \endplumedfile
+      73             : 
+      74             : This input instructs PLUMED to calculate the angle between the plane containing the vector connecting atoms 1 and 2 and the vector
+      75             : connecting atoms 3 and 4 and the plane containing this second vector and the vector connecting atoms 5 and 6.  We can even use
+      76             : PLUMED to calculate the torsional angle between two bond vectors around the z-axis as shown below:
+      77             : 
+      78             : \plumedfile
+      79             : a0: FIXEDATOM AT=0,0,0
+      80             : az: FIXEDATOM AT=0,0,1
+      81             : t1: TORSION VECTOR1=1,2 AXIS=a0,az VECTOR2=5,6
+      82             : PRINT ARG=t1 FILE=colvar STRIDE=20
+      83             : \endplumedfile
+      84             : 
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : class Torsion : public Colvar {
+      90             :   bool pbc;
+      91             :   bool do_cosine;
+      92             : 
+      93             : public:
+      94             :   explicit Torsion(const ActionOptions&);
+      95             : // active methods:
+      96             :   void calculate() override;
+      97             :   static void registerKeywords(Keywords& keys);
+      98             : };
+      99             : 
+     100             : PLUMED_REGISTER_ACTION(Torsion,"TORSION")
+     101             : 
+     102         655 : void Torsion::registerKeywords(Keywords& keys) {
+     103         655 :   Colvar::registerKeywords( keys );
+     104        1310 :   keys.add("atoms-1","ATOMS","the four atoms involved in the torsional angle");
+     105        1310 :   keys.add("atoms-2","AXIS","two atoms that define an axis.  You can use this to find the angle in the plane perpendicular to the axis between the vectors specified using the VECTOR1 and VECTOR2 keywords.");
+     106        1310 :   keys.add("atoms-2","VECTOR1","two atoms that define a vector.  You can use this in combination with VECTOR2 and AXIS");
+     107        1310 :   keys.add("atoms-2","VECTOR2","two atoms that define a vector.  You can use this in combination with VECTOR1 and AXIS");
+     108        1310 :   keys.addFlag("COSINE",false,"calculate cosine instead of dihedral");
+     109         655 : }
+     110             : 
+     111         653 : Torsion::Torsion(const ActionOptions&ao):
+     112             :   PLUMED_COLVAR_INIT(ao),
+     113         653 :   pbc(true),
+     114         653 :   do_cosine(false)
+     115             : {
+     116             :   std::vector<AtomNumber> atoms,v1,v2,axis;
+     117         653 :   parseAtomList("ATOMS",atoms);
+     118         653 :   parseAtomList("VECTOR1",v1);
+     119         653 :   parseAtomList("VECTOR2",v2);
+     120         653 :   parseAtomList("AXIS",axis);
+     121             : 
+     122         653 :   parseFlag("COSINE",do_cosine);
+     123             : 
+     124         653 :   bool nopbc=!pbc;
+     125         653 :   parseFlag("NOPBC",nopbc);
+     126         653 :   pbc=!nopbc;
+     127         653 :   checkRead();
+     128             : 
+     129         653 :   if(atoms.size()==4) {
+     130         648 :     if(!(v1.empty() && v2.empty() && axis.empty()))
+     131           1 :       error("ATOMS keyword is not compatible with VECTOR1, VECTOR2 and AXIS keywords");
+     132         647 :     log.printf("  between atoms %d %d %d %d\n",atoms[0].serial(),atoms[1].serial(),atoms[2].serial(),atoms[3].serial());
+     133         647 :     atoms.resize(6);
+     134         647 :     atoms[5]=atoms[3];
+     135         647 :     atoms[4]=atoms[2];
+     136         647 :     atoms[3]=atoms[2];
+     137         647 :     atoms[2]=atoms[1];
+     138           5 :   } else if(atoms.empty()) {
+     139           4 :     if(!(v1.size()==2 && v2.size()==2 && axis.size()==2))
+     140           0 :       error("VECTOR1, VECTOR2 and AXIS should specify 2 atoms each");
+     141           4 :     log.printf("  between lines %d-%d and %d-%d, projected on the plane orthogonal to line %d-%d\n",
+     142             :                v1[0].serial(),v1[1].serial(),v2[0].serial(),v2[1].serial(),axis[0].serial(),axis[1].serial());
+     143           4 :     atoms.resize(6);
+     144           4 :     atoms[0]=v1[1];
+     145           4 :     atoms[1]=v1[0];
+     146           4 :     atoms[2]=axis[0];
+     147           4 :     atoms[3]=axis[1];
+     148           4 :     atoms[4]=v2[0];
+     149           4 :     atoms[5]=v2[1];
+     150           1 :   } else error("ATOMS should specify 4 atoms");
+     151             : 
+     152         651 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     153         112 :   else    log.printf("  without periodic boundary conditions\n");
+     154             : 
+     155         651 :   if(do_cosine) log.printf("  calculating cosine instead of torsion\n");
+     156             : 
+     157         651 :   addValueWithDerivatives();
+     158        1304 :   if(!do_cosine) setPeriodic("-pi","pi");
+     159           0 :   else setNotPeriodic();
+     160         651 :   requestAtoms(atoms);
+     161         655 : }
+     162             : 
+     163             : // calculator
+     164       34543 : void Torsion::calculate() {
+     165             : 
+     166       34543 :   Vector d0,d1,d2;
+     167       34543 :   if(pbc) makeWhole();
+     168       34543 :   d0=delta(getPosition(1),getPosition(0));
+     169       34543 :   d1=delta(getPosition(3),getPosition(2));
+     170       34543 :   d2=delta(getPosition(5),getPosition(4));
+     171       34543 :   Vector dd0,dd1,dd2;
+     172             :   PLMD::Torsion t;
+     173       34543 :   double torsion=t.compute(d0,d1,d2,dd0,dd1,dd2);
+     174       34543 :   if(do_cosine) {
+     175           0 :     dd0 *= -std::sin(torsion);
+     176           0 :     dd1 *= -std::sin(torsion);
+     177           0 :     dd2 *= -std::sin(torsion);
+     178           0 :     torsion = std::cos(torsion);
+     179             :   }
+     180       34543 :   setAtomsDerivatives(0,dd0);
+     181       69086 :   setAtomsDerivatives(1,-dd0);
+     182             :   setAtomsDerivatives(2,dd1);
+     183       69086 :   setAtomsDerivatives(3,-dd1);
+     184             :   setAtomsDerivatives(4,dd2);
+     185       34543 :   setAtomsDerivatives(5,-dd2);
+     186             : 
+     187       34543 :   setValue           (torsion);
+     188             :   setBoxDerivativesNoPbc();
+     189       34543 : }
+     190             : 
+     191             : }
+     192             : }
+     193             : 
+     194             : 
+     195             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Volume.cpp.func-sort-c.html b/coverage/colvar/Volume.cpp.func-sort-c.html new file mode 100644 index 000000000000..2b7ab6038c9b --- /dev/null +++ b/coverage/colvar/Volume.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Volume.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Volume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6VolumeC2ERKNS_13ActionOptionsE0
_ZN4PLMD6colvar6VolumeC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar6Volume16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD6colvar6Volume9calculateEv148
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Volume.cpp.func.html b/coverage/colvar/Volume.cpp.func.html new file mode 100644 index 000000000000..3660f09a924d --- /dev/null +++ b/coverage/colvar/Volume.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Volume.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Volume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6colvar6Volume16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD6colvar6Volume9calculateEv148
_ZN4PLMD6colvar6VolumeC1ERKNS_13ActionOptionsE9
_ZN4PLMD6colvar6VolumeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/Volume.cpp.gcov.html b/coverage/colvar/Volume.cpp.gcov.html new file mode 100644 index 000000000000..ce6cb32902df --- /dev/null +++ b/coverage/colvar/Volume.cpp.gcov.html @@ -0,0 +1,162 @@ + + + + + + + + LCOV - plumed test coverage - colvar/Volume.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvar - Volume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace colvar {
+      27             : 
+      28             : //+PLUMEDOC COLVAR VOLUME
+      29             : /*
+      30             : Calculate the volume of the simulation box.
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : The following input tells plumed to print the volume of the system
+      35             : \plumedfile
+      36             : vol: VOLUME
+      37             : PRINT ARG=vol
+      38             : \endplumedfile
+      39             : 
+      40             : */
+      41             : //+ENDPLUMEDOC
+      42             : 
+      43             : 
+      44             : class Volume : public Colvar {
+      45             : 
+      46             : public:
+      47             :   explicit Volume(const ActionOptions&);
+      48             : // active methods:
+      49             :   void calculate() override;
+      50             : /// Register all the keywords for this action
+      51             :   static void registerKeywords( Keywords& keys );
+      52             : };
+      53             : 
+      54             : PLUMED_REGISTER_ACTION(Volume,"VOLUME")
+      55             : 
+      56           9 : Volume::Volume(const ActionOptions&ao):
+      57           9 :   PLUMED_COLVAR_INIT(ao)
+      58             : {
+      59             :   std::vector<AtomNumber> atoms;
+      60           9 :   checkRead();
+      61             : 
+      62          18 :   addValueWithDerivatives(); setNotPeriodic();
+      63           9 :   requestAtoms(atoms);
+      64           9 : }
+      65             : 
+      66          11 : void Volume::registerKeywords( Keywords& keys ) {
+      67          11 :   Action::registerKeywords( keys );
+      68          11 :   ActionWithValue::registerKeywords( keys );
+      69          11 :   ActionAtomistic::registerKeywords( keys );
+      70          11 : }
+      71             : 
+      72             : 
+      73             : // calculator
+      74         148 : void Volume::calculate() {
+      75             : 
+      76         148 :   double v=getBox().determinant();
+      77         148 :   setBoxDerivatives(-v*Tensor::identity());
+      78         148 :   setValue         (v);
+      79         148 : }
+      80             : 
+      81             : }
+      82             : }
+      83             : 
+      84             : 
+      85             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/index-sort-f.html b/coverage/colvar/index-sort-f.html new file mode 100644 index 000000000000..be52eb6c9348 --- /dev/null +++ b/coverage/colvar/index-sort-f.html @@ -0,0 +1,394 @@ + + + + + + + + LCOV - plumed test coverage - colvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvarHitTotalCoverage
Test:plumed test coverageLines:2056218993.9 %
Date:2024-02-22 21:58:45Functions:9713571.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Template.cpp +
20.6%20.6%
+
20.6 %7 / 3425.0 %1 / 4
Fake.cpp +
81.1%81.1%
+
81.1 %30 / 3750.0 %2 / 4
ContactMap.cpp +
91.6%91.6%
+
91.6 %120 / 13160.0 %3 / 5
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %180 / 18462.5 %5 / 8
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %89 / 9062.5 %5 / 8
PathMSD.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
ExtraCV.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
PropertyMap.cpp +
92.3%92.3%
+
92.3 %24 / 2666.7 %2 / 3
Constant.cpp +
95.5%95.5%
+
95.5 %42 / 4475.0 %3 / 4
Volume.cpp +
100.0%
+
100.0 %16 / 1675.0 %3 / 4
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
MultiRMSD.cpp +
97.6%97.6%
+
97.6 %41 / 4275.0 %3 / 4
Torsion.cpp +
91.2%91.2%
+
91.2 %62 / 6875.0 %3 / 4
DHEnergy.cpp +
93.9%93.9%
+
93.9 %31 / 3375.0 %3 / 4
DRMSD.cpp +
100.0%
+
100.0 %43 / 4375.0 %3 / 4
RMSD.cpp +
100.0%
+
100.0 %46 / 4675.0 %3 / 4
Coordination.cpp +
100.0%
+
100.0 %29 / 2975.0 %3 / 4
Position.cpp +
100.0%
+
100.0 %65 / 6575.0 %3 / 4
Cell.cpp +
100.0%
+
100.0 %35 / 3575.0 %3 / 4
Distance.cpp +
100.0%
+
100.0 %80 / 8075.0 %3 / 4
GHBFIX.cpp +
100.0%
+
100.0 %76 / 7675.0 %3 / 4
ERMSD.cpp +
98.0%98.0%
+
98.0 %50 / 5175.0 %3 / 4
Dipole.cpp +
100.0%
+
100.0 %60 / 6075.0 %3 / 4
Gyration.cpp +
77.6%77.6%
+
77.6 %142 / 18375.0 %3 / 4
Angle.cpp +
97.2%97.2%
+
97.2 %35 / 3675.0 %3 / 4
Energy.cpp +
100.0%
+
100.0 %31 / 3180.0 %4 / 5
Dimer.cpp +
92.1%92.1%
+
92.1 %82 / 8980.0 %4 / 5
PCARMSD.cpp +
98.9%98.9%
+
98.9 %93 / 9480.0 %4 / 5
Puckering.cpp +
99.6%99.6%
+
99.6 %228 / 22983.3 %5 / 6
EEFSolv.cpp +
94.2%94.2%
+
94.2 %229 / 24387.5 %7 / 8
PathMSDBase.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/index-sort-l.html b/coverage/colvar/index-sort-l.html new file mode 100644 index 000000000000..4ff2feb6774d --- /dev/null +++ b/coverage/colvar/index-sort-l.html @@ -0,0 +1,394 @@ + + + + + + + + LCOV - plumed test coverage - colvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvarHitTotalCoverage
Test:plumed test coverageLines:2056218993.9 %
Date:2024-02-22 21:58:45Functions:9713571.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Template.cpp +
20.6%20.6%
+
20.6 %7 / 3425.0 %1 / 4
PathMSDBase.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
Gyration.cpp +
77.6%77.6%
+
77.6 %142 / 18375.0 %3 / 4
Fake.cpp +
81.1%81.1%
+
81.1 %30 / 3750.0 %2 / 4
Torsion.cpp +
91.2%91.2%
+
91.2 %62 / 6875.0 %3 / 4
ContactMap.cpp +
91.6%91.6%
+
91.6 %120 / 13160.0 %3 / 5
Dimer.cpp +
92.1%92.1%
+
92.1 %82 / 8980.0 %4 / 5
PropertyMap.cpp +
92.3%92.3%
+
92.3 %24 / 2666.7 %2 / 3
DHEnergy.cpp +
93.9%93.9%
+
93.9 %31 / 3375.0 %3 / 4
EEFSolv.cpp +
94.2%94.2%
+
94.2 %229 / 24387.5 %7 / 8
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
Constant.cpp +
95.5%95.5%
+
95.5 %42 / 4475.0 %3 / 4
Angle.cpp +
97.2%97.2%
+
97.2 %35 / 3675.0 %3 / 4
MultiRMSD.cpp +
97.6%97.6%
+
97.6 %41 / 4275.0 %3 / 4
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %180 / 18462.5 %5 / 8
ERMSD.cpp +
98.0%98.0%
+
98.0 %50 / 5175.0 %3 / 4
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %89 / 9062.5 %5 / 8
PCARMSD.cpp +
98.9%98.9%
+
98.9 %93 / 9480.0 %4 / 5
Puckering.cpp +
99.6%99.6%
+
99.6 %228 / 22983.3 %5 / 6
ExtraCV.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
Volume.cpp +
100.0%
+
100.0 %16 / 1675.0 %3 / 4
PathMSD.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
Coordination.cpp +
100.0%
+
100.0 %29 / 2975.0 %3 / 4
Energy.cpp +
100.0%
+
100.0 %31 / 3180.0 %4 / 5
Cell.cpp +
100.0%
+
100.0 %35 / 3575.0 %3 / 4
DRMSD.cpp +
100.0%
+
100.0 %43 / 4375.0 %3 / 4
RMSD.cpp +
100.0%
+
100.0 %46 / 4675.0 %3 / 4
Dipole.cpp +
100.0%
+
100.0 %60 / 6075.0 %3 / 4
Position.cpp +
100.0%
+
100.0 %65 / 6575.0 %3 / 4
GHBFIX.cpp +
100.0%
+
100.0 %76 / 7675.0 %3 / 4
Distance.cpp +
100.0%
+
100.0 %80 / 8075.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/colvar/index.html b/coverage/colvar/index.html new file mode 100644 index 000000000000..63e9ad4b869d --- /dev/null +++ b/coverage/colvar/index.html @@ -0,0 +1,394 @@ + + + + + + + + LCOV - plumed test coverage - colvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - colvarHitTotalCoverage
Test:plumed test coverageLines:2056218993.9 %
Date:2024-02-22 21:58:45Functions:9713571.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Angle.cpp +
97.2%97.2%
+
97.2 %35 / 3675.0 %3 / 4
Cell.cpp +
100.0%
+
100.0 %35 / 3575.0 %3 / 4
Constant.cpp +
95.5%95.5%
+
95.5 %42 / 4475.0 %3 / 4
ContactMap.cpp +
91.6%91.6%
+
91.6 %120 / 13160.0 %3 / 5
Coordination.cpp +
100.0%
+
100.0 %29 / 2975.0 %3 / 4
CoordinationBase.cpp +
98.9%98.9%
+
98.9 %89 / 9062.5 %5 / 8
DHEnergy.cpp +
93.9%93.9%
+
93.9 %31 / 3375.0 %3 / 4
DRMSD.cpp +
100.0%
+
100.0 %43 / 4375.0 %3 / 4
Dimer.cpp +
92.1%92.1%
+
92.1 %82 / 8980.0 %4 / 5
Dipole.cpp +
100.0%
+
100.0 %60 / 6075.0 %3 / 4
Distance.cpp +
100.0%
+
100.0 %80 / 8075.0 %3 / 4
EEFSolv.cpp +
94.2%94.2%
+
94.2 %229 / 24387.5 %7 / 8
ERMSD.cpp +
98.0%98.0%
+
98.0 %50 / 5175.0 %3 / 4
Energy.cpp +
100.0%
+
100.0 %31 / 3180.0 %4 / 5
ExtraCV.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
Fake.cpp +
81.1%81.1%
+
81.1 %30 / 3750.0 %2 / 4
GHBFIX.cpp +
100.0%
+
100.0 %76 / 7675.0 %3 / 4
Gyration.cpp +
77.6%77.6%
+
77.6 %142 / 18375.0 %3 / 4
MultiRMSD.cpp +
97.6%97.6%
+
97.6 %41 / 4275.0 %3 / 4
PCARMSD.cpp +
98.9%98.9%
+
98.9 %93 / 9480.0 %4 / 5
PathMSD.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
PathMSDBase.cpp +
97.8%97.8%
+
97.8 %180 / 18462.5 %5 / 8
PathMSDBase.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
Position.cpp +
100.0%
+
100.0 %65 / 6575.0 %3 / 4
ProjectionOnAxis.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
PropertyMap.cpp +
92.3%92.3%
+
92.3 %24 / 2666.7 %2 / 3
Puckering.cpp +
99.6%99.6%
+
99.6 %228 / 22983.3 %5 / 6
RMSD.cpp +
100.0%
+
100.0 %46 / 4675.0 %3 / 4
Template.cpp +
20.6%20.6%
+
20.6 %7 / 3425.0 %1 / 4
Torsion.cpp +
91.2%91.2%
+
91.2 %62 / 6875.0 %3 / 4
Volume.cpp +
100.0%
+
100.0 %16 / 1675.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/Config.inc.func-sort-c.html b/coverage/config/Config.inc.func-sort-c.html new file mode 100644 index 000000000000..036659e2dcb4 --- /dev/null +++ b/coverage/config/Config.inc.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - config/Config.inc - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - config - Config.inc (source / functions)HitTotalCoverage
Test:plumed test coverageLines:86811.8 %
Date:2024-02-22 21:58:45Functions:32512.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev0
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv0
_ZN4PLMD6config12plumed_soextEv0
_ZN4PLMD6config13getEnvCommandB5cxx11Ev0
_ZN4PLMD6config13getVersionGitB5cxx11Ev0
_ZN4PLMD6config14getLibraryPathB5cxx11Ev0
_ZN4PLMD6config14plumed_htmldirEv0
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev0
_ZN4PLMD6config17plumed_includedirEv0
_ZN4PLMD6config18getCompilationDateB5cxx11Ev0
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev0
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev0
_ZN4PLMD6config19plumed_program_nameEv0
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev0
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
_ZN4PLMD6config14getVersionLongB5cxx11Ev1
_ZN4PLMD6config11plumed_rootEv300
_ZN4PLMD6config13getPlumedRootB5cxx11Ev300
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/Config.inc.func.html b/coverage/config/Config.inc.func.html new file mode 100644 index 000000000000..eacabf0fe7d8 --- /dev/null +++ b/coverage/config/Config.inc.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - config/Config.inc - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - config - Config.inc (source / functions)HitTotalCoverage
Test:plumed test coverageLines:86811.8 %
Date:2024-02-22 21:58:45Functions:32512.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev0
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv0
_ZN4PLMD6config11plumed_rootEv300
_ZN4PLMD6config12plumed_soextEv0
_ZN4PLMD6config13getEnvCommandB5cxx11Ev0
_ZN4PLMD6config13getPlumedRootB5cxx11Ev300
_ZN4PLMD6config13getVersionGitB5cxx11Ev0
_ZN4PLMD6config14getLibraryPathB5cxx11Ev0
_ZN4PLMD6config14getVersionLongB5cxx11Ev1
_ZN4PLMD6config14plumed_htmldirEv0
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev0
_ZN4PLMD6config17plumed_includedirEv0
_ZN4PLMD6config18getCompilationDateB5cxx11Ev0
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev0
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev0
_ZN4PLMD6config19plumed_program_nameEv0
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev0
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/Config.inc.gcov.html b/coverage/config/Config.inc.gcov.html new file mode 100644 index 000000000000..e66a6d7ac78e --- /dev/null +++ b/coverage/config/Config.inc.gcov.html @@ -0,0 +1,273 @@ + + + + + + + + LCOV - plumed test coverage - config/Config.inc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - config - Config.inc (source / functions)HitTotalCoverage
Test:plumed test coverageLines:86811.8 %
Date:2024-02-22 21:58:45Functions:32512.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Config.h"
+      24             : #include "version.h"
+      25             : #include <cstdlib>
+      26             : #include <cstring>
+      27             : #include <dlfcn.h>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace config {
+      31             : 
+      32             : // This is a fix to allow conda to correctly replace paths in binary files.
+      33             : // These functions should not be static or they will be optimized away!
+      34         300 : const char* plumed_root() {return "/home/runner/work/plumed2/plumed2/";}
+      35           0 : const char* plumed_soext() {return "so";}
+      36           0 : const char* plumed_htmldir() {return "xxxxNAxxxx";}
+      37           0 : const char* plumed_includedir() {return "xxxxNAxxxx";}
+      38           0 : const char* plumed_program_name() {return "xxxxNAxxxx";}
+      39             : 
+      40           0 : std::string getSoExt() {
+      41           0 :   return plumed_soext();
+      42             : }
+      43             : 
+      44           0 : bool isInstalled() {
+      45           0 :   return false;
+      46             : }
+      47             : 
+      48         300 : std::string getPlumedRoot() {
+      49         300 :   char *env = std::getenv("PLUMED_ROOT");
+      50             :   std::string ss;
+      51         300 :   if( env == NULL) {
+      52         300 :     ss=plumed_root();
+      53             :   } else {
+      54           0 :     ss=std::string( env );
+      55             :   }
+      56         300 :   return ss;
+      57             : }
+      58             : 
+      59           0 : std::string getPlumedHtmldir() {
+      60           0 :   if(!isInstalled()) return getPlumedRoot();
+      61           0 :   char *env = std::getenv("PLUMED_HTMLDIR");
+      62             :   std::string ss;
+      63           0 :   if( env == NULL) {
+      64           0 :     ss=plumed_htmldir();
+      65             :   } else {
+      66           0 :     ss=std::string( env );
+      67             :   }
+      68             :   return ss;
+      69             : }
+      70             : 
+      71           0 : std::string getPlumedIncludedir() {
+      72           0 :   if(!isInstalled()) return getPlumedRoot()+"/src/include";
+      73           0 :   char *env = std::getenv("PLUMED_INCLUDEDIR");
+      74             :   std::string ss;
+      75           0 :   if( env == NULL) {
+      76           0 :     ss=plumed_includedir();
+      77             :   } else {
+      78           0 :     ss=std::string( env );
+      79             :   }
+      80             :   return ss;
+      81             : }
+      82             : 
+      83           0 : std::string getPlumedProgramName() {
+      84           0 :   if(!isInstalled()) return "plumed";
+      85           0 :   char *env = std::getenv("PLUMED_PROGRAM_NAME");
+      86             :   std::string ss;
+      87           0 :   if( env == NULL) {
+      88           0 :     ss=plumed_program_name();
+      89             :   } else {
+      90           0 :     ss=std::string( env );
+      91             :   }
+      92             :   return ss;
+      93             : }
+      94             : 
+      95           0 : std::string getEnvCommand() {
+      96           0 :   return "env PLUMED_ROOT=\""+getPlumedRoot()+"\""+
+      97           0 :          " env PLUMED_VERSION=\""+getVersionLong()+"\""+
+      98           0 :          " env PLUMED_HTMLDIR=\""+getPlumedHtmldir()+"\""+
+      99           0 :          " env PLUMED_INCLUDEDIR=\""+getPlumedIncludedir()+"\""+
+     100           0 :          " env PLUMED_PROGRAM_NAME=\""+getPlumedProgramName()+"\""+
+     101           0 :          " env PLUMED_IS_INSTALLED=\""+(false?"yes":"no")+"\"";
+     102             : }
+     103             : 
+     104           0 : std::string getVersion() {
+     105           0 :   return PLUMED_VERSION_SHORT;
+     106             : }
+     107             : 
+     108           1 : std::string getVersionLong() {
+     109           1 :   return PLUMED_VERSION_LONG;
+     110             : }
+     111             : 
+     112           0 : std::string getVersionGit() {
+     113           0 :   return PLUMED_VERSION_GIT;
+     114             : }
+     115             : 
+     116           0 : std::string getMakefile() {
+     117             :   static const unsigned char confu [] = {
+     118             : #include "Makefile.conf.xxd"
+     119             :     , 0x00
+     120             :   };
+     121             :   auto conf=(char*)confu;
+     122           0 :   return std::string(conf,conf+std::strlen(conf));
+     123             : }
+     124             : 
+     125           0 : bool hasMatheval() {
+     126             : #ifdef __PLUMED_HAS_MATHEVAL
+     127             :   return true;
+     128             : #else
+     129           0 :   return false;
+     130             : #endif
+     131             : }
+     132             : 
+     133           0 : bool hasDlopen() {
+     134             : #ifdef __PLUMED_HAS_DLOPEN
+     135           0 :   return true;
+     136             : #else
+     137             :   return false;
+     138             : #endif
+     139             : }
+     140             : 
+     141           0 : bool hasCregex() {
+     142             : #ifdef __PLUMED_HAS_CREGEX
+     143             :   return true;
+     144             : #else
+     145           0 :   return false;
+     146             : #endif
+     147             : }
+     148             : 
+     149           0 : bool hasMolfile() {
+     150             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     151           0 :   return true;
+     152             : #else
+     153             :   return false;
+     154             : #endif
+     155             : }
+     156             : 
+     157           0 : bool hasExternalMolfile() {
+     158             : #ifdef __PLUMED_HAS_EXTERNAL_MOLFILE_PLUGINS
+     159             :   return true;
+     160             : #else
+     161           0 :   return false;
+     162             : #endif
+     163             : }
+     164             : 
+     165           0 : bool hasZlib() {
+     166             : #ifdef __PLUMED_HAS_ZLIB
+     167           0 :   return true;
+     168             : #else
+     169             :   return false;
+     170             : #endif
+     171             : }
+     172             : 
+     173           0 : std::string getCompilationDate() {
+     174           0 :   return __DATE__;
+     175             : }
+     176             : 
+     177           0 : std::string getCompilationTime() {
+     178           0 :   return __TIME__;
+     179             : }
+     180             : 
+     181           0 : std::string getLibraryPath() {
+     182             : #ifdef __PLUMED_HAS_DLADDR
+     183             :   Dl_info info;
+     184           0 :   if(dladdr((void*)getLibraryPath,&info)) {
+     185           0 :     return info.dli_fname;
+     186             :   } else {
+     187           0 :     return "";
+     188             :   }
+     189             : #endif
+     190             : 
+     191             : }
+     192             : 
+     193             : 
+     194             : }
+     195             : }
+     196             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/ConfigInstall.inc.func-sort-c.html b/coverage/config/ConfigInstall.inc.func-sort-c.html new file mode 100644 index 000000000000..7f88f6e5f1c1 --- /dev/null +++ b/coverage/config/ConfigInstall.inc.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - config/ConfigInstall.inc - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - config - ConfigInstall.inc (source / functions)HitTotalCoverage
Test:plumed test coverageLines:496872.1 %
Date:2024-02-22 21:58:45Functions:182572.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev0
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev32
_ZN4PLMD6config13getEnvCommandB5cxx11Ev659
_ZN4PLMD6config14plumed_htmldirEv659
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev659
_ZN4PLMD6config17plumed_includedirEv659
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev659
_ZN4PLMD6config19plumed_program_nameEv659
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev659
_ZN4PLMD6config13getVersionGitB5cxx11Ev1011
_ZN4PLMD6config14getLibraryPathB5cxx11Ev1011
_ZN4PLMD6config18getCompilationDateB5cxx11Ev1011
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev1011
_ZN4PLMD6config12plumed_soextEv1221
_ZN4PLMD6config8getSoExtB5cxx11Ev1221
_ZN4PLMD6config14getVersionLongB5cxx11Ev1674
_ZN4PLMD6config11isInstalledEv2618
_ZN4PLMD6config11plumed_rootEv7224
_ZN4PLMD6config13getPlumedRootB5cxx11Ev7224
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/ConfigInstall.inc.func.html b/coverage/config/ConfigInstall.inc.func.html new file mode 100644 index 000000000000..b5f4cabb3543 --- /dev/null +++ b/coverage/config/ConfigInstall.inc.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - config/ConfigInstall.inc - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - config - ConfigInstall.inc (source / functions)HitTotalCoverage
Test:plumed test coverageLines:496872.1 %
Date:2024-02-22 21:58:45Functions:182572.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6config10getVersionB5cxx11Ev0
_ZN4PLMD6config10hasMolfileEv0
_ZN4PLMD6config11getMakefileB5cxx11Ev32
_ZN4PLMD6config11hasMathevalEv0
_ZN4PLMD6config11isInstalledEv2618
_ZN4PLMD6config11plumed_rootEv7224
_ZN4PLMD6config12plumed_soextEv1221
_ZN4PLMD6config13getEnvCommandB5cxx11Ev659
_ZN4PLMD6config13getPlumedRootB5cxx11Ev7224
_ZN4PLMD6config13getVersionGitB5cxx11Ev1011
_ZN4PLMD6config14getLibraryPathB5cxx11Ev1011
_ZN4PLMD6config14getVersionLongB5cxx11Ev1674
_ZN4PLMD6config14plumed_htmldirEv659
_ZN4PLMD6config16getPlumedHtmldirB5cxx11Ev659
_ZN4PLMD6config17plumed_includedirEv659
_ZN4PLMD6config18getCompilationDateB5cxx11Ev1011
_ZN4PLMD6config18getCompilationTimeB5cxx11Ev1011
_ZN4PLMD6config18hasExternalMolfileEv0
_ZN4PLMD6config19getPlumedIncludedirB5cxx11Ev659
_ZN4PLMD6config19plumed_program_nameEv659
_ZN4PLMD6config20getPlumedProgramNameB5cxx11Ev659
_ZN4PLMD6config7hasZlibEv0
_ZN4PLMD6config8getSoExtB5cxx11Ev1221
_ZN4PLMD6config9hasCregexEv0
_ZN4PLMD6config9hasDlopenEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/ConfigInstall.inc.gcov.html b/coverage/config/ConfigInstall.inc.gcov.html new file mode 100644 index 000000000000..696d6d80e93f --- /dev/null +++ b/coverage/config/ConfigInstall.inc.gcov.html @@ -0,0 +1,273 @@ + + + + + + + + LCOV - plumed test coverage - config/ConfigInstall.inc + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - config - ConfigInstall.inc (source / functions)HitTotalCoverage
Test:plumed test coverageLines:496872.1 %
Date:2024-02-22 21:58:45Functions:182572.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Config.h"
+      24             : #include "version.h"
+      25             : #include <cstdlib>
+      26             : #include <cstring>
+      27             : #include <dlfcn.h>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace config {
+      31             : 
+      32             : // This is a fix to allow conda to correctly replace paths in binary files.
+      33             : // These functions should not be static or they will be optimized away!
+      34        7224 : const char* plumed_root() {return "/home/runner/opt/lib/plumed";}
+      35        1221 : const char* plumed_soext() {return "so";}
+      36         659 : const char* plumed_htmldir() {return "/home/runner/opt/share/doc/plumed";}
+      37         659 : const char* plumed_includedir() {return "/home/runner/opt/include";}
+      38         659 : const char* plumed_program_name() {return "plumed";}
+      39             : 
+      40        1221 : std::string getSoExt() {
+      41        1221 :   return plumed_soext();
+      42             : }
+      43             : 
+      44        2618 : bool isInstalled() {
+      45        2618 :   return true;
+      46             : }
+      47             : 
+      48        7224 : std::string getPlumedRoot() {
+      49        7224 :   char *env = std::getenv("PLUMED_ROOT");
+      50             :   std::string ss;
+      51        7224 :   if( env == NULL) {
+      52        7224 :     ss=plumed_root();
+      53             :   } else {
+      54           0 :     ss=std::string( env );
+      55             :   }
+      56        7224 :   return ss;
+      57             : }
+      58             : 
+      59         659 : std::string getPlumedHtmldir() {
+      60         659 :   if(!isInstalled()) return getPlumedRoot();
+      61         659 :   char *env = std::getenv("PLUMED_HTMLDIR");
+      62             :   std::string ss;
+      63         659 :   if( env == NULL) {
+      64         659 :     ss=plumed_htmldir();
+      65             :   } else {
+      66           0 :     ss=std::string( env );
+      67             :   }
+      68             :   return ss;
+      69             : }
+      70             : 
+      71         659 : std::string getPlumedIncludedir() {
+      72         659 :   if(!isInstalled()) return getPlumedRoot()+"/src/include";
+      73         659 :   char *env = std::getenv("PLUMED_INCLUDEDIR");
+      74             :   std::string ss;
+      75         659 :   if( env == NULL) {
+      76         659 :     ss=plumed_includedir();
+      77             :   } else {
+      78           0 :     ss=std::string( env );
+      79             :   }
+      80             :   return ss;
+      81             : }
+      82             : 
+      83         659 : std::string getPlumedProgramName() {
+      84         659 :   if(!isInstalled()) return "plumed";
+      85         659 :   char *env = std::getenv("PLUMED_PROGRAM_NAME");
+      86             :   std::string ss;
+      87         659 :   if( env == NULL) {
+      88         659 :     ss=plumed_program_name();
+      89             :   } else {
+      90           0 :     ss=std::string( env );
+      91             :   }
+      92             :   return ss;
+      93             : }
+      94             : 
+      95         659 : std::string getEnvCommand() {
+      96        1318 :   return "env PLUMED_ROOT=\""+getPlumedRoot()+"\""+
+      97        2636 :          " env PLUMED_VERSION=\""+getVersionLong()+"\""+
+      98        2636 :          " env PLUMED_HTMLDIR=\""+getPlumedHtmldir()+"\""+
+      99        2636 :          " env PLUMED_INCLUDEDIR=\""+getPlumedIncludedir()+"\""+
+     100        1977 :          " env PLUMED_PROGRAM_NAME=\""+getPlumedProgramName()+"\""+
+     101        1977 :          " env PLUMED_IS_INSTALLED=\""+(true?"yes":"no")+"\"";
+     102             : }
+     103             : 
+     104           0 : std::string getVersion() {
+     105           0 :   return PLUMED_VERSION_SHORT;
+     106             : }
+     107             : 
+     108        1674 : std::string getVersionLong() {
+     109        1674 :   return PLUMED_VERSION_LONG;
+     110             : }
+     111             : 
+     112        1011 : std::string getVersionGit() {
+     113        1011 :   return PLUMED_VERSION_GIT;
+     114             : }
+     115             : 
+     116          32 : std::string getMakefile() {
+     117             :   static const unsigned char confu [] = {
+     118             : #include "Makefile.conf.xxd"
+     119             :     , 0x00
+     120             :   };
+     121             :   auto conf=(char*)confu;
+     122          32 :   return std::string(conf,conf+std::strlen(conf));
+     123             : }
+     124             : 
+     125           0 : bool hasMatheval() {
+     126             : #ifdef __PLUMED_HAS_MATHEVAL
+     127             :   return true;
+     128             : #else
+     129           0 :   return false;
+     130             : #endif
+     131             : }
+     132             : 
+     133           0 : bool hasDlopen() {
+     134             : #ifdef __PLUMED_HAS_DLOPEN
+     135           0 :   return true;
+     136             : #else
+     137             :   return false;
+     138             : #endif
+     139             : }
+     140             : 
+     141           0 : bool hasCregex() {
+     142             : #ifdef __PLUMED_HAS_CREGEX
+     143             :   return true;
+     144             : #else
+     145           0 :   return false;
+     146             : #endif
+     147             : }
+     148             : 
+     149           0 : bool hasMolfile() {
+     150             : #ifdef __PLUMED_HAS_MOLFILE_PLUGINS
+     151           0 :   return true;
+     152             : #else
+     153             :   return false;
+     154             : #endif
+     155             : }
+     156             : 
+     157           0 : bool hasExternalMolfile() {
+     158             : #ifdef __PLUMED_HAS_EXTERNAL_MOLFILE_PLUGINS
+     159             :   return true;
+     160             : #else
+     161           0 :   return false;
+     162             : #endif
+     163             : }
+     164             : 
+     165           0 : bool hasZlib() {
+     166             : #ifdef __PLUMED_HAS_ZLIB
+     167           0 :   return true;
+     168             : #else
+     169             :   return false;
+     170             : #endif
+     171             : }
+     172             : 
+     173        1011 : std::string getCompilationDate() {
+     174        1011 :   return __DATE__;
+     175             : }
+     176             : 
+     177        1011 : std::string getCompilationTime() {
+     178        1011 :   return __TIME__;
+     179             : }
+     180             : 
+     181        1011 : std::string getLibraryPath() {
+     182             : #ifdef __PLUMED_HAS_DLADDR
+     183             :   Dl_info info;
+     184        1011 :   if(dladdr((void*)getLibraryPath,&info)) {
+     185        1011 :     return info.dli_fname;
+     186             :   } else {
+     187           0 :     return "";
+     188             :   }
+     189             : #endif
+     190             : 
+     191             : }
+     192             : 
+     193             : 
+     194             : }
+     195             : }
+     196             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/index-sort-f.html b/coverage/config/index-sort-f.html new file mode 100644 index 000000000000..bcc1904c3bdc --- /dev/null +++ b/coverage/config/index-sort-f.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - config + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - configHitTotalCoverage
Test:plumed test coverageLines:5713641.9 %
Date:2024-02-22 21:58:45Functions:215042.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
11.8%11.8%
+
11.8 %8 / 6812.0 %3 / 25
ConfigInstall.inc +
72.1%72.1%
+
72.1 %49 / 6872.0 %18 / 25
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/index-sort-l.html b/coverage/config/index-sort-l.html new file mode 100644 index 000000000000..38d214a0f58e --- /dev/null +++ b/coverage/config/index-sort-l.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - config + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - configHitTotalCoverage
Test:plumed test coverageLines:5713641.9 %
Date:2024-02-22 21:58:45Functions:215042.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
11.8%11.8%
+
11.8 %8 / 6812.0 %3 / 25
ConfigInstall.inc +
72.1%72.1%
+
72.1 %49 / 6872.0 %18 / 25
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/config/index.html b/coverage/config/index.html new file mode 100644 index 000000000000..6f9e22a9618e --- /dev/null +++ b/coverage/config/index.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - config + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - configHitTotalCoverage
Test:plumed test coverageLines:5713641.9 %
Date:2024-02-22 21:58:45Functions:215042.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Config.inc +
11.8%11.8%
+
11.8 %8 / 6812.0 %3 / 25
ConfigInstall.inc +
72.1%72.1%
+
72.1 %49 / 6872.0 %18 / 25
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.cpp.func-sort-c.html b/coverage/core/Action.cpp.func-sort-c.html new file mode 100644 index 000000000000..c10a7c430069 --- /dev/null +++ b/coverage/core/Action.cpp.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - core/Action.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Action.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15619281.2 %
Date:2024-02-22 21:58:45Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action12clearOptionsEv0
_ZN4PLMD6Action16calculateFromPDBERKNS_3PDBE0
_ZN4PLMD6Action29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD6Action4exitEi0
_ZN4PLMD6ActionD0Ev0
_ZNK4PLMD6Action16getDocumentationB5cxx11Ev0
_ZN4PLMD6Action4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE24
_ZNK4PLMD6Action5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30
_ZN4PLMD6Action10getKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33
_ZN4PLMD6Action5fopenEPKcS2_73
_ZN4PLMD6Action6fcloseEP8_IO_FILE91
_ZN4PLMD6Action6getkBTEv619
_ZNK4PLMD6Action13getKBoltzmannEv660
_ZNK4PLMD6Action6getCPTEv1095
_ZNK4PLMD6Action17usingNaturalUnitsEv3124
_ZN4PLMD6Action9setOptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3980
_ZN4PLMD6Action7warningERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4171
_ZN4PLMD6ActionD2Ev21852
_ZN4PLMD13ActionOptionsC2ERKS0_RKNS_8KeywordsE21853
_ZN4PLMD6ActionC2ERKNS_13ActionOptionsE21853
_ZN4PLMD13ActionOptionsC2ERNS_10PlumedMainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE21855
_ZN4PLMD6Action16registerKeywordsERNS_8KeywordsE22444
_ZNK4PLMD6Action15getExchangeStepEv28109
_ZN4PLMD6Action6fflushEv29998
_ZN4PLMD6Action9checkReadEv35414
_ZN4PLMD6Action19setupConstantValuesERKb54099
_ZN4PLMD6Action9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb64356
_ZN4PLMD6Action17clearDependenciesEv189224
_ZNK4PLMD6Action11getTimeStepEv218305
_ZN4PLMD6Action7prepareEv697858
_ZN4PLMD6Action13addDependencyEPS0_1178684
_ZNK4PLMD6Action11checkUpdateEv1995342
_ZNK4PLMD6Action7getTimeEv3346236
_ZN4PLMD6Action8activateEv4512068
_ZNK4PLMD6Action7getStepEv4913563
_ZNK4PLMD6Action8getUnitsEv14346306
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.cpp.func.html b/coverage/core/Action.cpp.func.html new file mode 100644 index 000000000000..d7e45d4e6293 --- /dev/null +++ b/coverage/core/Action.cpp.func.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - core/Action.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Action.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15619281.2 %
Date:2024-02-22 21:58:45Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13ActionOptionsC2ERKS0_RKNS_8KeywordsE21853
_ZN4PLMD13ActionOptionsC2ERNS_10PlumedMainERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE21855
_ZN4PLMD6Action10getKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE33
_ZN4PLMD6Action12clearOptionsEv0
_ZN4PLMD6Action13addDependencyEPS0_1178684
_ZN4PLMD6Action16calculateFromPDBERKNS_3PDBE0
_ZN4PLMD6Action16registerKeywordsERNS_8KeywordsE22444
_ZN4PLMD6Action17clearDependenciesEv189224
_ZN4PLMD6Action19setupConstantValuesERKb54099
_ZN4PLMD6Action29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD6Action4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE24
_ZN4PLMD6Action4exitEi0
_ZN4PLMD6Action5fopenEPKcS2_73
_ZN4PLMD6Action6fcloseEP8_IO_FILE91
_ZN4PLMD6Action6fflushEv29998
_ZN4PLMD6Action6getkBTEv619
_ZN4PLMD6Action7prepareEv697858
_ZN4PLMD6Action7warningERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4171
_ZN4PLMD6Action8activateEv4512068
_ZN4PLMD6Action9checkReadEv35414
_ZN4PLMD6Action9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb64356
_ZN4PLMD6Action9setOptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3980
_ZN4PLMD6ActionC2ERKNS_13ActionOptionsE21853
_ZN4PLMD6ActionD0Ev0
_ZN4PLMD6ActionD2Ev21852
_ZNK4PLMD6Action11checkUpdateEv1995342
_ZNK4PLMD6Action11getTimeStepEv218305
_ZNK4PLMD6Action13getKBoltzmannEv660
_ZNK4PLMD6Action15getExchangeStepEv28109
_ZNK4PLMD6Action16getDocumentationB5cxx11Ev0
_ZNK4PLMD6Action17usingNaturalUnitsEv3124
_ZNK4PLMD6Action5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30
_ZNK4PLMD6Action6getCPTEv1095
_ZNK4PLMD6Action7getStepEv4913563
_ZNK4PLMD6Action7getTimeEv3346236
_ZNK4PLMD6Action8getUnitsEv14346306
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.cpp.gcov.html b/coverage/core/Action.cpp.gcov.html new file mode 100644 index 000000000000..a0e07dafb536 --- /dev/null +++ b/coverage/core/Action.cpp.gcov.html @@ -0,0 +1,422 @@ + + + + + + + + LCOV - plumed test coverage - core/Action.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Action.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15619281.2 %
Date:2024-02-22 21:58:45Functions:303683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Action.h"
+      23             : #include "ActionAtomistic.h"
+      24             : #include "ActionWithValue.h"
+      25             : #include "ActionWithArguments.h"
+      26             : #include "ActionWithVirtualAtom.h"
+      27             : #include "ActionForInterface.h"
+      28             : #include "DomainDecomposition.h"
+      29             : #include "PbcAction.h"
+      30             : #include "ActionToPutData.h"
+      31             : #include "ActionToGetData.h"
+      32             : #include "PlumedMain.h"
+      33             : #include "tools/Log.h"
+      34             : #include "tools/Exception.h"
+      35             : #include "tools/Communicator.h"
+      36             : #include "ActionSet.h"
+      37             : #include <iostream>
+      38             : 
+      39             : namespace PLMD {
+      40             : 
+      41             : Keywords ActionOptions::emptyKeys;
+      42             : 
+      43       21855 : ActionOptions::ActionOptions(PlumedMain&p,const std::vector<std::string>&l):
+      44       21855 :   plumed(p),
+      45       21855 :   line(l),
+      46       21855 :   keys(emptyKeys)
+      47             : {
+      48       21855 : }
+      49             : 
+      50       21853 : ActionOptions::ActionOptions(const ActionOptions&ao,const Keywords&keys):
+      51       21853 :   plumed(ao.plumed),
+      52       21853 :   line(ao.line),
+      53       21853 :   keys(keys)
+      54             : {
+      55       21853 : }
+      56             : 
+      57       22444 : void Action::registerKeywords( Keywords& keys ) {
+      58       22444 :   plumed_assert( keys.size()==0 );
+      59       44888 :   keys.add( "hidden", "LABEL", "a label for the action so that its output can be referenced in the input to other actions.  Actions with scalar output are referenced using their label only.  Actions with vector output must have a separate label for every component.  Individual components are then referred to using label.component" );
+      60       44888 :   keys.reserve("optional","UPDATE_FROM","Only update this action from this time");
+      61       44888 :   keys.reserve("optional","UPDATE_UNTIL","Only update this action until this time");
+      62       44888 :   keys.reserve("optional","RESTART","allows per-action setting of restart (YES/NO/AUTO)");
+      63       22444 : }
+      64             : 
+      65       21853 : Action::Action(const ActionOptions&ao):
+      66       21853 :   name(ao.line[0]),
+      67       21853 :   line(ao.line),
+      68       21853 :   update_from(std::numeric_limits<double>::max()),
+      69       21853 :   update_until(std::numeric_limits<double>::max()),
+      70       21853 :   timestep(0),
+      71       21853 :   active(false),
+      72       21853 :   restart(ao.plumed.getRestart()),
+      73       21853 :   doCheckPoint(ao.plumed.getCPT()),
+      74       21853 :   never_activate(false),
+      75       21853 :   plumed(ao.plumed),
+      76       21853 :   log(plumed.getLog()),
+      77       21853 :   comm(plumed.comm),
+      78       21853 :   multi_sim_comm(plumed.multi_sim_comm),
+      79       21853 :   keywords(ao.keys)
+      80             : {
+      81             :   // Retrieve the timestep and save it
+      82       21853 :   ActionWithValue* ts = plumed.getActionSet().selectWithLabel<ActionWithValue*>("timestep");
+      83       21853 :   if( ts ) timestep = (ts->copyOutput(0))->get();
+      84             : 
+      85             :   line.erase(line.begin());
+      86       43706 :   if( !keywords.exists("NO_ACTION_LOG") ) log.printf("Action %s\n",name.c_str());
+      87             : 
+      88       21853 :   if(comm.Get_rank()==0) {
+      89       14340 :     replica_index=multi_sim_comm.Get_rank();
+      90             :   }
+      91       21853 :   comm.Bcast(replica_index,0);
+      92             : 
+      93       65366 :   if ( keywords.exists("LABEL") ) { parse("LABEL",label); }
+      94       21853 :   if(label.length()==0) {
+      95        2421 :     std::string s; Tools::convert(plumed.getActionSet().size()-plumed.getActionSet().select<ActionForInterface*>().size(),s);
+      96        4842 :     label="@"+s;
+      97             :   }
+      98       21853 :   if( plumed.getActionSet().selectWithLabel<Action*>(label) ) error("label " + label + " has been already used");
+      99       43706 :   if( !keywords.exists("NO_ACTION_LOG") ) log.printf("  with label %s\n",label.c_str());
+     100       45461 :   if ( keywords.exists("UPDATE_FROM") ) parse("UPDATE_FROM",update_from);
+     101       43706 :   if( !keywords.exists("NO_ACTION_LOG") && update_from!=std::numeric_limits<double>::max()) log.printf("  only update from time %f\n",update_from);
+     102       45461 :   if ( keywords.exists("UPDATE_UNTIL") ) parse("UPDATE_UNTIL",update_until);
+     103       43706 :   if( !keywords.exists("NO_ACTION_LOG") && update_until!=std::numeric_limits<double>::max()) log.printf("  only update until time %f\n",update_until);
+     104       43706 :   if ( keywords.exists("RESTART") ) {
+     105        1819 :     std::string srestart="AUTO";
+     106        3636 :     parse("RESTART",srestart);
+     107        1818 :     if(srestart=="YES") restart=true;
+     108        1736 :     else if(srestart=="NO")  restart=false;
+     109        1714 :     else if(srestart=="AUTO") {
+     110             :       // do nothing, this is the default
+     111           2 :     } else error("RESTART should be either YES, NO, or AUTO");
+     112             :   }
+     113       21853 : }
+     114             : 
+     115       43704 : Action::~Action() {
+     116       21852 :   if(files.size()!=0) {
+     117           0 :     std::cerr<<"WARNING: some files open in action "+getLabel()+" where not properly closed. This could lead to data loss!!\n";
+     118             :   }
+     119       43704 : }
+     120             : 
+     121          73 : FILE* Action::fopen(const char *path, const char *mode) {
+     122             :   bool write(false);
+     123         146 :   for(const char*p=mode; *p; p++) if(*p=='w' || *p=='a' || *p=='+') write=true;
+     124             :   FILE* fp;
+     125          73 :   if(write && comm.Get_rank()!=0) fp=plumed.fopen("/dev/null",mode);
+     126          73 :   else      fp=plumed.fopen(path,mode);
+     127          73 :   files.insert(fp);
+     128          73 :   return fp;
+     129             : }
+     130             : 
+     131          91 : int Action::fclose(FILE*fp) {
+     132             :   files.erase(fp);
+     133          91 :   return plumed.fclose(fp);
+     134             : }
+     135             : 
+     136       29998 : void Action::fflush() {
+     137       29998 :   for(const auto & p : files) {
+     138           0 :     std::fflush(p);
+     139             :   }
+     140       29998 : }
+     141             : 
+     142          33 : std::string Action::getKeyword(const std::string& key) {
+     143             :   // Check keyword has been registered
+     144          33 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     145             : 
+     146             :   std::string outkey;
+     147          33 :   if( Tools::getKey(line,key,outkey ) ) return key + outkey;
+     148             : 
+     149           0 :   if( keywords.style(key,"compulsory") ) {
+     150           0 :     if( keywords.getDefaultValue(key,outkey) ) {
+     151           0 :       if( outkey.length()==0 ) error("keyword " + key + " has weird default value");
+     152           0 :       return key + "=" +  outkey;
+     153             :     } else {
+     154           0 :       error("keyword " + key + " is compulsory for this action");
+     155             :     }
+     156             :   }
+     157           0 :   return "";
+     158             : }
+     159             : 
+     160       64356 : void Action::parseFlag(const std::string&key,bool & t) {
+     161             :   // Check keyword has been registered
+     162       64356 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     163             :   // Check keyword is a flag
+     164      128712 :   if(!keywords.style(key,"nohtml")) {
+     165      126156 :     plumed_massert( keywords.style(key,"vessel") || keywords.style(key,"flag") || keywords.style(key,"hidden"), "keyword " + key + " is not a flag");
+     166             :   }
+     167             : 
+     168             :   // Read in the flag otherwise get the default value from the keywords object
+     169       64356 :   if(!Tools::parseFlag(line,key,t)) {
+     170      113492 :     if( keywords.style(key,"nohtml") || keywords.style(key,"vessel") ) {
+     171        2654 :       t=false;
+     172       52765 :     } else if ( !keywords.getLogicalDefault(key,t) ) {
+     173           0 :       log.printf("ERROR in action %s with label %s : flag %s has no default",name.c_str(),label.c_str(),key.c_str() );
+     174           0 :       plumed_error();
+     175             :     }
+     176             :   }
+     177       64356 : }
+     178             : 
+     179     1178684 : void Action::addDependency(Action*action) {
+     180     1178684 :   after.push_back(action);
+     181     1178684 : }
+     182             : 
+     183     4512068 : void Action::activate() {
+     184             : // This is set to true if actions are only need to be computed in setup (during checkRead)
+     185     4512068 :   if( never_activate ) return;
+     186             : // preparation step is called only the first time an Action is activated.
+     187             : // since it could change its dependences (e.g. in an ActionAtomistic which is
+     188             : // accessing to a virtual atom), this is done just before dependencies are
+     189             : // activated
+     190     4512068 :   if(!active) {
+     191     2019527 :     this->unlockRequests();
+     192     2019527 :     prepare();
+     193     2019527 :     this->lockRequests();
+     194             :   } else return;
+     195     5253430 :   for(const auto & p : after) p->activate();
+     196     2019527 :   active=true;
+     197             : }
+     198             : 
+     199        3980 : void Action::setOption(const std::string &s) {
+     200             : // This overloads the action and activate some options
+     201        3980 :   options.insert(s);
+     202        7874 :   for(const auto & p : after) p->setOption(s);
+     203        3980 : }
+     204             : 
+     205           0 : void Action::clearOptions() {
+     206             : // This overloads the action and activate some options
+     207             :   options.clear();
+     208           0 : }
+     209             : 
+     210             : 
+     211      189224 : void Action::clearDependencies() {
+     212             :   after.clear();
+     213      189224 : }
+     214             : 
+     215           0 : std::string Action::getDocumentation()const {
+     216           0 :   return std::string("UNDOCUMENTED ACTION");
+     217             : }
+     218             : 
+     219       35414 : void Action::checkRead() {
+     220       35414 :   if(!line.empty()) {
+     221           0 :     std::string msg="cannot understand the following words from the input line : ";
+     222           0 :     for(unsigned i=0; i<line.size(); i++) {
+     223           0 :       if(i>0) msg = msg + ", ";
+     224           0 :       msg = msg + line[i];
+     225             :     }
+     226           0 :     error(msg);
+     227             :   }
+     228       35414 :   setupConstantValues(false);
+     229       35414 : }
+     230             : 
+     231       54099 : void Action::setupConstantValues( const bool& have_atoms ) {
+     232       54099 :   if( have_atoms ) {
+     233             :     // This ensures that we switch off actions that only depend on constant when passed from the
+     234             :     // MD code on the first step
+     235       18685 :     ActionAtomistic* at = castToActionAtomistic();
+     236       18685 :     ActionWithValue* av = castToActionWithValue();
+     237       18685 :     if( at && av ) {
+     238        9423 :       never_activate=av->getNumberOfComponents()>0;
+     239        9423 :       for(unsigned i=0; i<av->getNumberOfComponents(); ++i) {
+     240        9260 :         if( !av->copyOutput(i)->isConstant() ) { never_activate=false; break; }
+     241             :       }
+     242             :     }
+     243             :   }
+     244       54099 :   ActionWithArguments* aa = castToActionWithArguments();
+     245       54099 :   if(aa) never_activate = aa->calculateConstantValues( have_atoms );
+     246       54099 : }
+     247             : 
+     248     4913563 : long long int Action::getStep()const {
+     249     4913563 :   return plumed.getStep();
+     250             : }
+     251             : 
+     252     3346236 : double Action::getTime()const {
+     253     3346236 :   return timestep*getStep();
+     254             : }
+     255             : 
+     256      218305 : double Action::getTimeStep()const {
+     257      218305 :   return timestep;
+     258             : }
+     259             : 
+     260         619 : double Action::getkBT() {
+     261         619 :   double temp=-1.0;
+     262        1843 :   if( keywords.exists("TEMP") ) parse("TEMP",temp);
+     263        1555 :   if(temp>=0.0 && keywords.style("TEMP","optional") ) return getKBoltzmann()*temp;
+     264         238 :   ActionForInterface* kb=plumed.getActionSet().selectWithLabel<ActionForInterface*>("kBT");
+     265         238 :   double kbt=0; if(kb) kbt=(kb->copyOutput(0))->get();
+     266         354 :   if( temp>=0 && keywords.style("TEMP","compulsory") ) {
+     267          58 :     double kB=getKBoltzmann();
+     268          58 :     if( kbt>0 && std::abs(kbt-kB*temp)>1e-4) {
+     269           0 :       std::string strt1, strt2; Tools::convert( temp, strt1 ); Tools::convert( kbt/kB, strt2 );
+     270           0 :       warning("using TEMP=" + strt1 + " while MD engine uses " + strt2 + "\n");
+     271             :     }
+     272          58 :     kbt = kB*temp;
+     273          58 :     plumed_massert(kbt>0,"your MD engine does not pass the temperature to plumed, you must specify it using TEMP");
+     274             :     return kbt;
+     275             :   }
+     276             :   return kbt;
+     277             : }
+     278             : 
+     279           0 : void Action::exit(int c) {
+     280           0 :   plumed.exit(c);
+     281           0 : }
+     282             : 
+     283           0 : void Action::calculateNumericalDerivatives( ActionWithValue* a ) {
+     284           0 :   plumed_merror("if you get here it means that you are trying to use numerical derivatives for a class that does not implement them");
+     285             : }
+     286             : 
+     287      697858 : void Action::prepare() {
+     288      697858 :   return;
+     289             : }
+     290             : 
+     291          30 : [[noreturn]] void Action::error( const std::string & msg ) const {
+     292          60 :   if( !keywords.exists("NO_ACTION_LOG") ) log.printf("ERROR in input to action %s with label %s : %s \n \n", name.c_str(), label.c_str(), msg.c_str() );
+     293          90 :   plumed_merror("ERROR in input to action " + name + " with label " + label + " : " + msg );
+     294             : }
+     295             : 
+     296        4171 : void Action::warning( const std::string & msg ) {
+     297        4171 :   log.printf("WARNING for action %s with label %s : %s \n", name.c_str(), label.c_str(), msg.c_str() );
+     298        4171 : }
+     299             : 
+     300           0 : void Action::calculateFromPDB( const PDB& pdb ) {
+     301           0 :   activate();
+     302           0 :   for(const auto & p : after) {
+     303           0 :     ActionWithValue*av=castToActionWithValue();
+     304           0 :     if(av) { av->clearInputForces(); av->clearDerivatives(); }
+     305           0 :     p->readAtomsFromPDB( pdb );
+     306           0 :     p->calculate();
+     307             :   }
+     308           0 :   readAtomsFromPDB( pdb );
+     309           0 :   calculate();
+     310           0 : }
+     311             : 
+     312       28109 : bool Action::getExchangeStep()const {
+     313       28109 :   return plumed.getExchangeStep();
+     314             : }
+     315             : 
+     316          24 : std::string Action::cite(const std::string&s) {
+     317          24 :   return plumed.cite(s);
+     318             : }
+     319             : 
+     320             : /// Check if action should be updated.
+     321     1995342 : bool Action::checkUpdate()const {
+     322     1995342 :   double t=getTime();
+     323     1995342 :   if(t<update_until && (update_from==std::numeric_limits<double>::max() || t>=update_from)) return true;
+     324         510 :   else return false;
+     325             : }
+     326             : 
+     327        1095 : bool Action::getCPT() const {
+     328        1095 :   return plumed.getCPT();
+     329             : }
+     330             : 
+     331    14346306 : const Units& Action::getUnits() const {
+     332    14346306 :   return plumed.getUnits();
+     333             : }
+     334             : 
+     335        3124 : bool Action::usingNaturalUnits() const {
+     336        3124 :   return plumed.usingNaturalUnits();
+     337             : }
+     338             : 
+     339         660 : double Action::getKBoltzmann() const {
+     340         660 :   if( usingNaturalUnits() ) return 1.0;
+     341         660 :   else return kBoltzmann/getUnits().getEnergy();
+     342             : }
+     343             : 
+     344             : }
+     345             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.h.func-sort-c.html b/coverage/core/Action.h.func-sort-c.html new file mode 100644 index 000000000000..1e2e0e836920 --- /dev/null +++ b/coverage/core/Action.h.func-sort-c.html @@ -0,0 +1,221 @@ + + + + + + + + LCOV - plumed test coverage - core/Action.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Action.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-02-22 21:58:45Functions:323786.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action13parseNumberedIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_0
_ZN4PLMD6Action15castToPbcActionEv0
_ZN4PLMD6Action16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD6Action20castToActionShortcutEv0
_ZN4PLMD6Action21castToActionToGetDataEv0
_ZN4PLMD6Action19parseNumberedVectorIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE14
_ZN4PLMD6Action5parseImEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_16
_ZN4PLMD6Action11parseVectorIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE31
_ZN4PLMD6Action19parseNumberedVectorIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE32
_ZN4PLMD6Action5parseIxEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_109
_ZN4PLMD6Action24castToActionForInterfaceEv603
_ZN4PLMD6Action19parseNumberedVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE1313
_ZN4PLMD6Action13parseNumberedIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_1376
_ZN4PLMD6Action19parseNumberedVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRSt6vectorIT_SaISB_EE2145
_ZN4PLMD6Action5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3708
_ZN4PLMD6Action11parseVectorIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE6130
_ZN4PLMD6Action5parseIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_6303
_ZN4PLMD6Action25castToDomainDecompositionEv7390
_ZN4PLMD6Action11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE11208
_ZN4PLMD6Action12runFinalJobsEv19677
_ZN4PLMD6Action5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_22522
_ZN4PLMD6Action11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RSt6vectorIT_SaISB_EE24274
_ZN4PLMD6Action13parseNumberedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRT_27972
_ZN4PLMD6Action25castToActionWithArgumentsEv45661
_ZN4PLMD6Action5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RT_54148
_ZNK4PLMD6Action25checkNumericalDerivativesEv246036
_ZN4PLMD6Action21castToActionWithValueEv251215
_ZN4PLMD6Action6updateEv764928
_ZN4PLMD6Action12lockRequestsEv1317678
_ZN4PLMD6Action14unlockRequestsEv1317678
_ZNK4PLMD6Action10isOptionOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1414809
_ZN4PLMD6Action21castToActionAtomisticEv1865961
_ZNK4PLMD6Action19checkNeedsGradientsEv2010748
_ZN4PLMD6Action27castToActionWithVirtualAtomEv2097282
_ZN4PLMD6Action12beforeUpdateEv2442296
_ZN4PLMD6Action10deactivateEv2491929
_ZN4PLMD6Action21castToActionToPutDataEv6109302
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.h.func.html b/coverage/core/Action.h.func.html new file mode 100644 index 000000000000..afce6aff84f5 --- /dev/null +++ b/coverage/core/Action.h.func.html @@ -0,0 +1,221 @@ + + + + + + + + LCOV - plumed test coverage - core/Action.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Action.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-02-22 21:58:45Functions:323786.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Action10deactivateEv2491929
_ZN4PLMD6Action11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RSt6vectorIT_SaISB_EE24274
_ZN4PLMD6Action11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE11208
_ZN4PLMD6Action11parseVectorIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE31
_ZN4PLMD6Action11parseVectorIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE6130
_ZN4PLMD6Action12beforeUpdateEv2442296
_ZN4PLMD6Action12lockRequestsEv1317678
_ZN4PLMD6Action12runFinalJobsEv19677
_ZN4PLMD6Action13parseNumberedINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRT_27972
_ZN4PLMD6Action13parseNumberedIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_1376
_ZN4PLMD6Action13parseNumberedIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRT_0
_ZN4PLMD6Action14unlockRequestsEv1317678
_ZN4PLMD6Action15castToPbcActionEv0
_ZN4PLMD6Action16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD6Action19parseNumberedVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_iRSt6vectorIT_SaISB_EE2145
_ZN4PLMD6Action19parseNumberedVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE1313
_ZN4PLMD6Action19parseNumberedVectorIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE32
_ZN4PLMD6Action19parseNumberedVectorIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIT_SaISB_EE14
_ZN4PLMD6Action20castToActionShortcutEv0
_ZN4PLMD6Action21castToActionAtomisticEv1865961
_ZN4PLMD6Action21castToActionToGetDataEv0
_ZN4PLMD6Action21castToActionToPutDataEv6109302
_ZN4PLMD6Action21castToActionWithValueEv251215
_ZN4PLMD6Action24castToActionForInterfaceEv603
_ZN4PLMD6Action25castToActionWithArgumentsEv45661
_ZN4PLMD6Action25castToDomainDecompositionEv7390
_ZN4PLMD6Action27castToActionWithVirtualAtomEv2097282
_ZN4PLMD6Action5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS7_RT_54148
_ZN4PLMD6Action5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_22522
_ZN4PLMD6Action5parseIiEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_6303
_ZN4PLMD6Action5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3708
_ZN4PLMD6Action5parseImEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_16
_ZN4PLMD6Action5parseIxEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_109
_ZN4PLMD6Action6updateEv764928
_ZNK4PLMD6Action10isOptionOnERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1414809
_ZNK4PLMD6Action19checkNeedsGradientsEv2010748
_ZNK4PLMD6Action25checkNumericalDerivativesEv246036
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Action.h.gcov.html b/coverage/core/Action.h.gcov.html new file mode 100644 index 000000000000..9c6474f24e2d --- /dev/null +++ b/coverage/core/Action.h.gcov.html @@ -0,0 +1,563 @@ + + + + + + + + LCOV - plumed test coverage - core/Action.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Action.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-02-22 21:58:45Functions:323786.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_Action_h
+      23             : #define __PLUMED_core_Action_h
+      24             : #include <vector>
+      25             : #include <string>
+      26             : #include <set>
+      27             : #include "tools/Keywords.h"
+      28             : #include "tools/Tools.h"
+      29             : #include "tools/Units.h"
+      30             : #include "tools/Log.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : class PDB;
+      35             : class PlumedMain;
+      36             : class Communicator;
+      37             : class ActionWithValue;
+      38             : class ActionWithArguments;
+      39             : class ActionAtomistic;
+      40             : class ActionWithVirtualAtom;
+      41             : class PbcAction;
+      42             : class ActionToGetData;
+      43             : class ActionToPutData;
+      44             : class DomainDecomposition;
+      45             : class ActionForInterface;
+      46             : class ActionShortcut;
+      47             : 
+      48             : /// This class is used to bring the relevant information to the Action constructor.
+      49             : /// Only Action and ActionRegister class can access to its content, which is
+      50             : /// kept private to other classes, and may change in the future.
+      51       43708 : class ActionOptions {
+      52             :   friend class Action;
+      53             :   friend class ActionRegister;
+      54             : /// Reference to main PlumedMain object
+      55             :   PlumedMain& plumed;
+      56             : /// Input line which sets up the action
+      57             :   std::vector<std::string> line;
+      58             : /// The documentation for this action
+      59             :   const Keywords& keys;
+      60             :   static Keywords emptyKeys;
+      61             : public:
+      62             : /// Constructor
+      63             :   ActionOptions(PlumedMain&p,const std::vector<std::string>&);
+      64             :   ActionOptions(const ActionOptions&,const Keywords& keys);
+      65             : };
+      66             : 
+      67             : /// Base class for all the input Actions.
+      68             : /// The input Actions are more or less corresponding to the directives
+      69             : /// in the plumed.dat file and are applied in order at each time-step.
+      70             : class Action {
+      71             :   friend class ActionShortcut;
+      72             : 
+      73             : /// Name of the directive in the plumed.dat file.
+      74             :   const std::string name;
+      75             : 
+      76             : /// Label of the Action, as set with LABEL= in the plumed.dat file.
+      77             :   std::string label;
+      78             : 
+      79             : /// Directive line.
+      80             : /// This line is progressively erased during Action construction
+      81             : /// so as to check if all the present keywords are correct.
+      82             :   std::vector<std::string> line;
+      83             : 
+      84             : /// Update only after this time.
+      85             :   double update_from;
+      86             : 
+      87             : /// Update only until this time.
+      88             :   double update_until;
+      89             : 
+      90             : /// Save the timestep here
+      91             :   double timestep;
+      92             : 
+      93             : protected:
+      94             : /// Get the units that we are operating in
+      95             :   const Units& getUnits() const;
+      96             : /// Are we using natural units
+      97             :   bool usingNaturalUnits()const;
+      98             : /// Get the value of Boltzmann's constant
+      99             :   double getKBoltzmann()const;
+     100             : public:
+     101             : 
+     102             : /// Check if action should be updated.
+     103             :   bool checkUpdate()const;
+     104             : 
+     105             : public:
+     106             :   typedef std::vector<Action*> Dependencies;
+     107             : 
+     108             : private:
+     109             : /// Actions on which this Action depends.
+     110             :   Dependencies after;
+     111             : 
+     112             : /// Switch to activate Action on this step.
+     113             :   bool active;
+     114             : 
+     115             : /// Option that you might have enabled
+     116             :   std::set<std::string> options;
+     117             : 
+     118             :   bool restart;
+     119             : 
+     120             :   bool doCheckPoint;
+     121             : 
+     122             :   bool never_activate;
+     123             : 
+     124             : /// The set of default arguments that we are using
+     125             :   std::string defaults;
+     126             : public:
+     127             : 
+     128             : /// Reference to main plumed object
+     129             :   PlumedMain& plumed;
+     130             : 
+     131             : /// Reference to the log stream
+     132             :   Log& log;
+     133             : 
+     134             : /// Specify that this Action depends on another one
+     135             :   void addDependency(Action*);
+     136             : 
+     137             : /// Clear the dependence list for this Action
+     138             :   void clearDependencies();
+     139             : 
+     140             : /// Get the value of kBT by either reading the TEMP keyword
+     141             : /// and multiplying the temperature by Boltzmann's constant
+     142             : /// or get it fro the MD code
+     143             :   double getkBT();
+     144             : 
+     145             : /// Return the present timestep
+     146             :   long long int getStep()const;
+     147             : 
+     148             : /// Return the present time
+     149             :   double getTime()const;
+     150             : 
+     151             : /// Return the timestep
+     152             :   double getTimeStep()const;
+     153             : 
+     154             : /// Return true if we are doing a restart
+     155             :   bool getRestart()const;
+     156             : 
+     157             : /// Return true if we are doing at a checkpoint step
+     158             :   bool getCPT()const;
+     159             : 
+     160             : /// Just read one of the keywords and return the whole thing as a string
+     161             :   std::string getKeyword(const std::string& key);
+     162             : 
+     163             : /// Parse one keyword as generic type
+     164             :   template<class T>
+     165             :   void parse(const std::string&key,T&t);
+     166             : 
+     167             : /// Parse one numbered keyword as generic type
+     168             :   template<class T>
+     169             :   bool parseNumbered(const std::string&key, const int no, T&t);
+     170             : 
+     171             : /// Parse one keyword as std::vector
+     172             :   template<class T>
+     173             :   void parseVector(const std::string&key,std::vector<T>&t);
+     174             : 
+     175             : /// Parse a vector with a number
+     176             :   template<class T>
+     177             :   bool parseNumberedVector(const std::string& key, const int no, std::vector<T>&t);
+     178             : 
+     179             : /// Parse one keyword as boolean flag
+     180             :   void parseFlag(const std::string&key,bool&t);
+     181             : 
+     182             : /// Crash calculation and print documentation
+     183             :   [[noreturn]] void error( const std::string & msg ) const;
+     184             : 
+     185             : /// Issue a warning
+     186             :   void warning( const std::string & msg );
+     187             : 
+     188             : /// Exit with error code c
+     189             :   void exit(int c=0);
+     190             : 
+     191             : ///
+     192             :   std::set<FILE*> files;
+     193             : 
+     194             : public:
+     195             : /// Standard constructor from ActionOptions
+     196             :   explicit Action(const ActionOptions&);
+     197             : /// Destructor
+     198             :   virtual ~Action();
+     199             : private:
+     200             : /// Copy constructor is deleted
+     201             :   Action(const Action&a) = delete;
+     202             : /// Assignment operator is deleted
+     203             :   Action& operator=(const Action&a) = delete;
+     204             :   int replica_index;
+     205             : public:
+     206             : /// Check if Action was properly read.
+     207             : /// This checks if Action::line is empty. It must be called after
+     208             : /// a final Action has been initialized
+     209             :   void checkRead();
+     210             : 
+     211             : /// This calculates any values that are constant and ensures
+     212             : /// that we don't calculate these actions on every timestep
+     213             :   void setupConstantValues( const bool& have_atoms );
+     214             : 
+     215             :   Communicator& comm;
+     216             :   Communicator& multi_sim_comm;
+     217             : 
+     218             :   const Keywords& keywords;
+     219             : /// Prepare an Action for calculation
+     220             : /// This can be used by Action if they need some special preparation
+     221             : /// before calculation. Typical case is for collective variables
+     222             : /// which would like to change their list of requested atoms.
+     223             : /// By default (if not overridden) does nothing.
+     224             :   virtual void prepare();
+     225             : 
+     226             : /// Register all the relevant keywords for the action
+     227             :   static void registerKeywords( Keywords& keys );
+     228             : 
+     229     1317678 :   virtual void lockRequests() {}
+     230     1317678 :   virtual void unlockRequests() {}
+     231             : 
+     232             : /// Calculate an Action.
+     233             : /// This method is called one or more times per step.
+     234             : /// The set of all Actions is calculated in forward order.
+     235             :   virtual void calculate()=0;
+     236             : 
+     237             : /// Apply an Action.
+     238             : /// This method is called one time per step.
+     239             : /// The set of all Actions is applied in backward order.
+     240             :   virtual void apply()=0;
+     241             : 
+     242             : /// Before Update.
+     243             : /// This is a special method that is called just
+     244             : /// before the update() method. It can be used by
+     245             : /// actions that want to do something irrespectively
+     246             : /// of the fact that update() is active or not.
+     247             : /// In other words, this is *always* called, even when action
+     248             : /// is not active.
+     249     2442296 :   virtual void beforeUpdate() {}
+     250             : 
+     251             : /// Update.
+     252             : /// This method is called one time per step.
+     253             : /// The set of all Actions is updated in forward order.
+     254      764928 :   virtual void update() {}
+     255             : 
+     256             : /// RunFinalJobs
+     257             : /// This method is called once at the very end of the calculation.
+     258             : /// The set of all Actions in run for the final time in forward order.
+     259       19677 :   virtual void runFinalJobs() {}
+     260             : 
+     261             : /// Tell to the Action to flush open files
+     262             :   void fflush();
+     263             : 
+     264             :   virtual std::string getDocumentation()const;
+     265             : 
+     266             : /// Returns the label
+     267             :   const std::string & getLabel()const;
+     268             : 
+     269             : /// Returns the name
+     270             :   const std::string & getName()const;
+     271             : 
+     272             : /// Set action to active
+     273             :   virtual void activate();
+     274             : 
+     275             : ///
+     276             :   virtual void setOption(const std::string &s);
+     277             : 
+     278             :   virtual void clearOptions();
+     279             : 
+     280             : /// Set action to inactive
+     281             :   virtual void deactivate();
+     282             : 
+     283             : /// Check if action is active
+     284             :   bool isActive()const;
+     285             : 
+     286             : /// Check if an option is on
+     287             :   bool isOptionOn(const std::string &s)const;
+     288             : 
+     289             : /// Return dependencies
+     290             :   const Dependencies & getDependencies()const {return after;}
+     291             : 
+     292             : /// Check if numerical derivatives should be performed
+     293      246036 :   virtual bool checkNumericalDerivatives()const {return false;}
+     294             : 
+     295             : /// Check if the action needs gradient
+     296     2010748 :   virtual bool checkNeedsGradients()const {return false;}
+     297             : 
+     298             : /// Perform calculation using numerical derivatives
+     299             : /// N.B. only pass an ActionWithValue to this routine if you know exactly what you
+     300             : /// are doing.
+     301             :   virtual void calculateNumericalDerivatives( ActionWithValue* a=NULL );
+     302             : 
+     303             : /// Opens a file.
+     304             : /// This is similar to plain fopen, but with some extra functionality.
+     305             : /// * When opened for writing, processors other than the one with rank 0 just open /dev/null
+     306             : /// * PlumedMain::fopen is used, so that other tricks may appear (see \ref PlumedMain::fopen)
+     307             :   FILE *fopen(const char *path, const char *mode);
+     308             : /// Closes a file opened with Action::fclose().
+     309             :   int   fclose(FILE*fp);
+     310             : 
+     311             : /// Calculate the action given a pdb file as input.  This is used to initialize
+     312             : /// things like distance from a point in CV map space given a pdb as an input file
+     313             :   void calculateFromPDB( const PDB&  );
+     314             : /// This is overwritten in ActionAtomistic so that we can read
+     315             : /// the atoms from the pdb input file rather than taking them from the
+     316             : /// MD code
+     317           0 :   virtual void readAtomsFromPDB( const PDB&  ) {}
+     318             : /// Check if we are on an exchange step
+     319             :   bool getExchangeStep()const;
+     320             : 
+     321             : /// Cite a paper see PlumedMain::cite
+     322             :   std::string cite(const std::string&s);
+     323             : 
+     324             : /// Get the defaults
+     325             :   std::string getDefaultString() const ;
+     326             : 
+     327             : /// Specialized casts, to make PlumedMain run faster
+     328      251215 :   virtual ActionWithValue* castToActionWithValue() noexcept { return nullptr; }
+     329       45661 :   virtual ActionWithArguments* castToActionWithArguments() noexcept { return nullptr; }
+     330     1865961 :   virtual ActionAtomistic* castToActionAtomistic() noexcept { return nullptr; }
+     331     2097282 :   virtual ActionWithVirtualAtom* castToActionWithVirtualAtom() noexcept { return nullptr; }
+     332           0 :   virtual PbcAction* castToPbcAction() noexcept { return nullptr; }
+     333     6109302 :   virtual ActionToPutData* castToActionToPutData() noexcept { return nullptr; }
+     334           0 :   virtual ActionToGetData* castToActionToGetData() noexcept { return nullptr; }
+     335        7390 :   virtual DomainDecomposition* castToDomainDecomposition() noexcept { return nullptr; }
+     336         603 :   virtual ActionForInterface* castToActionForInterface() noexcept { return nullptr; }
+     337           0 :   virtual ActionShortcut* castToActionShortcut() noexcept { return nullptr; }
+     338             : };
+     339             : 
+     340             : /////////////////////
+     341             : // FAST INLINE METHODS
+     342             : 
+     343             : inline
+     344             : const std::string & Action::getLabel()const {
+     345   100853251 :   return label;
+     346             : }
+     347             : 
+     348             : inline
+     349             : const std::string & Action::getName()const {
+     350      453737 :   return name;
+     351             : }
+     352             : 
+     353             : template<class T>
+     354       86806 : void Action::parse(const std::string&key,T&t) {
+     355             : //  if(!Tools::parse(line,key,t)){
+     356             : //    log.printf("ERROR parsing keyword %s\n",key.c_str());
+     357             : //    log.printf("%s\n",getDocumentation().c_str());
+     358             : //    this->exit(1);
+     359             : //  }
+     360             :   // Check keyword has been registered
+     361       86806 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     362             : 
+     363             :   // Now try to read the keyword
+     364             :   std::string def;
+     365       86806 :   bool present=Tools::findKeyword(line,key);
+     366       86806 :   bool found=Tools::parse(line,key,t,replica_index);
+     367       86809 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     368             : 
+     369             :   // If it isn't read and it is compulsory see if a default value was specified
+     370      173577 :   if ( !found && (keywords.style(key,"compulsory") || keywords.style(key,"hidden")) ) {
+     371       13920 :     if( keywords.getDefaultValue(key,def) ) {
+     372        8632 :       if( def.length()==0 || !Tools::convertNoexcept(def,t) ) {
+     373           0 :         plumed_error() <<"ERROR in action "<<name<<" with label "<<label<<" : keyword "<<key<<" has weird default value";
+     374             :       }
+     375       17264 :       defaults += " " + key + "=" + def;
+     376       10576 :     } else if( keywords.style(key,"compulsory") ) {
+     377           3 :       error("keyword " + key + " is compulsory for this action");
+     378             :     }
+     379             :   }
+     380       86803 : }
+     381             : 
+     382             : template<class T>
+     383       29348 : bool Action::parseNumbered(const std::string&key, const int no, T&t) {
+     384             :   // Check keyword has been registered
+     385       29348 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     386       29348 :   if( !keywords.numbered(key) ) error("numbered keywords are not allowed for " + key );
+     387             : 
+     388             :   // Now try to read the keyword
+     389       29348 :   std::string num; Tools::convert(no,num);
+     390       58696 :   return Tools::parse(line,key+num,t,replica_index);
+     391             : }
+     392             : 
+     393             : template<class T>
+     394       41643 : void Action::parseVector(const std::string&key,std::vector<T>&t) {
+     395             : //  if(!Tools::parseVector(line,key,t)){
+     396             : //    log.printf("ERROR parsing keyword %s\n",key.c_str());
+     397             : //    log.printf("%s\n",getDocumentation().c_str());
+     398             : //    this->exit(1);
+     399             : //  }
+     400             : 
+     401             :   // Check keyword has been registered
+     402       41643 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     403       41643 :   unsigned size=t.size(); bool skipcheck=false;
+     404       41643 :   if(size==0) skipcheck=true;
+     405             : 
+     406             :   // Now try to read the keyword
+     407             :   std::string def; T val;
+     408       41643 :   bool present=Tools::findKeyword(line,key);
+     409       41643 :   bool found=Tools::parseVector(line,key,t,replica_index);
+     410       41644 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     411             : 
+     412             :   // Check vectors size is correct (not if this is atoms or ARG)
+     413       83284 :   if( !keywords.style(key,"atoms") && found ) {
+     414             : //     bool skipcheck=false;
+     415             : //     if( keywords.style(key,"compulsory") ){ keywords.getDefaultValue(key,def); skipcheck=(def=="nosize"); }
+     416       23939 :     if( !skipcheck && t.size()!=size ) error("vector read in for keyword " + key + " has the wrong size");
+     417             :   }
+     418             : 
+     419             :   // If it isn't read and it is compulsory see if a default value was specified
+     420       55885 :   if ( !found && (keywords.style(key,"compulsory") || keywords.style(key,"hidden")) ) {
+     421        1928 :     if( keywords.getDefaultValue(key,def) ) {
+     422        1826 :       if( def.length()==0 || !Tools::convertNoexcept(def,val) ) {
+     423           0 :         plumed_error() <<"ERROR in action "<<name<<" with label "<<label<<" : keyword "<<key<<" has weird default value";
+     424             :       } else {
+     425        1826 :         if(t.size()>0) {
+     426        1604 :           for(unsigned i=0; i<t.size(); ++i) t[i]=val;
+     427        1604 :           defaults += " " + key + "=" + def; for(unsigned i=1; i<t.size(); ++i) defaults += "," + def;
+     428        2434 :         } else { t.push_back(val); defaults += " " + key + "=" + def; }
+     429             :       }
+     430         204 :     } else if( keywords.style(key,"compulsory") ) {
+     431           4 :       error("keyword " + key + " is compulsory for this action");
+     432             :     }
+     433       39711 :   } else if ( !found ) {
+     434        6057 :     t.resize(0);
+     435             :   }
+     436       41639 : }
+     437             : 
+     438             : template<class T>
+     439        3504 : bool Action::parseNumberedVector(const std::string&key, const int no, std::vector<T>&t) {
+     440        3504 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     441        3504 :   if( !keywords.numbered(key) ) error("numbered keywords are not allowed for " + key );
+     442             : 
+     443        3504 :   unsigned size=t.size(); bool skipcheck=false;
+     444        3504 :   if(size==0) skipcheck=true;
+     445        3504 :   std::string num; Tools::convert(no,num);
+     446        3504 :   bool present=Tools::findKeyword(line,key);
+     447        3504 :   bool found=Tools::parseVector(line,key+num,t,replica_index);
+     448        3504 :   if(present && !found) error("keyword " + key +" could not be read correctly");
+     449             : 
+     450        7008 :   if(  keywords.style(key,"compulsory") ) {
+     451          90 :     if (!skipcheck && found && t.size()!=size ) error("vector read in for keyword " + key + num + " has the wrong size");
+     452        3414 :   } else if ( !found ) {
+     453        1039 :     t.resize(0);
+     454             :   }
+     455        3504 :   return found;
+     456             : }
+     457             : 
+     458             : inline
+     459     2491929 : void Action::deactivate() {
+     460             :   options.clear();
+     461     2491929 :   active=false;
+     462     2491929 : }
+     463             : 
+     464             : inline
+     465             : bool Action::isActive()const {
+     466    11204449 :   return active;
+     467             : }
+     468             : 
+     469             : inline
+     470     1414809 : bool Action::isOptionOn(const std::string &s)const {
+     471     1414809 :   return options.count(s);
+     472             : }
+     473             : 
+     474             : inline
+     475             : bool Action::getRestart()const {
+     476        3653 :   return restart;
+     477             : }
+     478             : 
+     479             : inline
+     480             : std::string Action::getDefaultString() const {
+     481           0 :   return defaults;
+     482             : }
+     483             : 
+     484             : }
+     485             : #endif
+     486             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.cpp.func-sort-c.html b/coverage/core/ActionAnyorder.cpp.func-sort-c.html new file mode 100644 index 000000000000..5a60651732d8 --- /dev/null +++ b/coverage/core/ActionAnyorder.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3650.0 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD14ActionAnyorderC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionAnyorderC2ERKNS_13ActionOptionsE105
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.cpp.func.html b/coverage/core/ActionAnyorder.cpp.func.html new file mode 100644 index 000000000000..b44ebeb9beba --- /dev/null +++ b/coverage/core/ActionAnyorder.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3650.0 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD14ActionAnyorderC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionAnyorderC2ERKNS_13ActionOptionsE105
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.cpp.gcov.html b/coverage/core/ActionAnyorder.cpp.gcov.html new file mode 100644 index 000000000000..995838411855 --- /dev/null +++ b/coverage/core/ActionAnyorder.cpp.gcov.html @@ -0,0 +1,115 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3650.0 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionAnyorder.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "ActionSet.h"
+      25             : #include "tools/Exception.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29         105 : ActionAnyorder::ActionAnyorder(const ActionOptions&ao):
+      30         105 :   Action(ao)
+      31             : {
+      32         105 : }
+      33             : 
+      34           0 : void ActionAnyorder::registerKeywords( Keywords& keys ) {
+      35           0 :   Action::registerKeywords(keys);
+      36           0 : }
+      37             : 
+      38             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.h.func-sort-c.html b/coverage/core/ActionAnyorder.h.func-sort-c.html new file mode 100644 index 000000000000..413125506fe4 --- /dev/null +++ b/coverage/core/ActionAnyorder.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1333.3 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder5applyEv0
_ZN4PLMD14ActionAnyorder9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.h.func.html b/coverage/core/ActionAnyorder.h.func.html new file mode 100644 index 000000000000..786a88e371bb --- /dev/null +++ b/coverage/core/ActionAnyorder.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1333.3 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionAnyorder5applyEv0
_ZN4PLMD14ActionAnyorder9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAnyorder.h.gcov.html b/coverage/core/ActionAnyorder.h.gcov.html new file mode 100644 index 000000000000..6d31478c93d1 --- /dev/null +++ b/coverage/core/ActionAnyorder.h.gcov.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAnyorder.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAnyorder.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1333.3 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionAnyorder_h
+      23             : #define __PLUMED_core_ActionAnyorder_h
+      24             : 
+      25             : #include "Action.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : /**
+      30             : \ingroup MULTIINHERIT
+      31             : Action used to create a PLMD::Action that can go both before and after ActionSetup actions.
+      32             : */
+      33          87 : class ActionAnyorder :
+      34             :   public virtual Action {
+      35             : public:
+      36             : /// Constructor
+      37             :   explicit ActionAnyorder(const ActionOptions&ao);
+      38             : /// Creator of keywords
+      39             :   static void registerKeywords( Keywords& keys );
+      40             : /// Do nothing.
+      41           0 :   void calculate() override {}
+      42             : /// Do nothing.
+      43           0 :   void apply() override {}
+      44             : };
+      45             : 
+      46             : }
+      47             : 
+      48             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.cpp.func-sort-c.html b/coverage/core/ActionAtomistic.cpp.func-sort-c.html new file mode 100644 index 000000000000..060c177137aa --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAtomistic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAtomistic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:21323092.6 %
Date:2024-02-22 21:58:45Functions:202580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD15ActionAtomistic9changeBoxERKNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD15ActionAtomisticC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionAtomisticD0Ev0
_ZN4PLMD15ActionAtomisticD1Ev0
_ZNK4PLMD15ActionAtomistic9getVirialEv6
_ZN4PLMD15ActionAtomistic29calculateNumericalDerivativesEPNS_15ActionWithValueE195
_ZN4PLMD15ActionAtomistic35calculateAtomicNumericalDerivativesEPNS_15ActionWithValueERKj492
_ZNK4PLMD15ActionAtomistic11getGradientERKjRNS_13VectorGenericILj3EEERSt3mapINS_10AtomNumberES4_St4lessIS7_ESaISt4pairIKS7_S4_EEE8208
_ZN4PLMD15ActionAtomisticC2ERKNS_13ActionOptionsE10198
_ZN4PLMD15ActionAtomisticD2Ev10198
_ZN4PLMD15ActionAtomistic12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EEb10260
_ZN4PLMD15ActionAtomistic16registerKeywordsERNS_8KeywordsE10467
_ZNK4PLMD15ActionAtomistic11getTotAtomsEv10523
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE11745
_ZN4PLMD15ActionAtomistic17interpretAtomListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_INS_10AtomNumberESaISB_EE11807
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_10AtomNumberESaISA_EE13731
_ZN4PLMD15ActionAtomistic17updateUniqueLocalERKbRKSt6vectorIiSaIiEE73541
_ZN4PLMD15ActionAtomistic16setForcesOnAtomsERKSt6vectorIdSaIdEERj75040
_ZN4PLMD15ActionAtomistic15setForcesOnCellERKSt6vectorIdSaIdEERj77551
_ZN4PLMD15ActionAtomistic15setForcesOnCellEPKdmRj81970
_ZN4PLMD15ActionAtomistic9makeWholeEv106272
_ZN4PLMD15ActionAtomistic13retrieveAtomsEv162248
_ZNK4PLMD15ActionAtomistic8pbcApplyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj222049
_ZNK4PLMD15ActionAtomistic15getValueIndicesERKNS_10AtomNumberE1608819
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.cpp.func.html b/coverage/core/ActionAtomistic.cpp.func.html new file mode 100644 index 000000000000..1595b1fd018d --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAtomistic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAtomistic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:21323092.6 %
Date:2024-02-22 21:58:45Functions:202580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EEb10260
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE11745
_ZN4PLMD15ActionAtomistic13parseAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorINS_10AtomNumberESaISA_EE13731
_ZN4PLMD15ActionAtomistic13retrieveAtomsEv162248
_ZN4PLMD15ActionAtomistic15setForcesOnCellEPKdmRj81970
_ZN4PLMD15ActionAtomistic15setForcesOnCellERKSt6vectorIdSaIdEERj77551
_ZN4PLMD15ActionAtomistic16readAtomsFromPDBERKNS_3PDBE0
_ZN4PLMD15ActionAtomistic16registerKeywordsERNS_8KeywordsE10467
_ZN4PLMD15ActionAtomistic16setForcesOnAtomsERKSt6vectorIdSaIdEERj75040
_ZN4PLMD15ActionAtomistic17interpretAtomListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_INS_10AtomNumberESaISB_EE11807
_ZN4PLMD15ActionAtomistic17updateUniqueLocalERKbRKSt6vectorIiSaIiEE73541
_ZN4PLMD15ActionAtomistic29calculateNumericalDerivativesEPNS_15ActionWithValueE195
_ZN4PLMD15ActionAtomistic35calculateAtomicNumericalDerivativesEPNS_15ActionWithValueERKj492
_ZN4PLMD15ActionAtomistic9changeBoxERKNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD15ActionAtomistic9makeWholeEv106272
_ZN4PLMD15ActionAtomisticC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionAtomisticC2ERKNS_13ActionOptionsE10198
_ZN4PLMD15ActionAtomisticD0Ev0
_ZN4PLMD15ActionAtomisticD1Ev0
_ZN4PLMD15ActionAtomisticD2Ev10198
_ZNK4PLMD15ActionAtomistic11getGradientERKjRNS_13VectorGenericILj3EEERSt3mapINS_10AtomNumberES4_St4lessIS7_ESaISt4pairIKS7_S4_EEE8208
_ZNK4PLMD15ActionAtomistic11getTotAtomsEv10523
_ZNK4PLMD15ActionAtomistic15getValueIndicesERKNS_10AtomNumberE1608819
_ZNK4PLMD15ActionAtomistic8pbcApplyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj222049
_ZNK4PLMD15ActionAtomistic9getVirialEv6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.cpp.gcov.html b/coverage/core/ActionAtomistic.cpp.gcov.html new file mode 100644 index 000000000000..4b37f92b3efa --- /dev/null +++ b/coverage/core/ActionAtomistic.cpp.gcov.html @@ -0,0 +1,437 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAtomistic.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAtomistic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:21323092.6 %
Date:2024-02-22 21:58:45Functions:202580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionAtomistic.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "ActionSet.h"
+      25             : #include "GenericMolInfo.h"
+      26             : #include "PbcAction.h"
+      27             : #include <vector>
+      28             : #include <string>
+      29             : #include "ActionWithValue.h"
+      30             : #include "Group.h"
+      31             : #include "ActionWithVirtualAtom.h"
+      32             : #include "tools/Exception.h"
+      33             : #include "tools/Pbc.h"
+      34             : #include "tools/PDB.h"
+      35             : 
+      36             : namespace PLMD {
+      37             : 
+      38       10198 : ActionAtomistic::~ActionAtomistic() {
+      39             : // empty destructor to delete unique_ptr
+      40       10198 : }
+      41             : 
+      42       10198 : ActionAtomistic::ActionAtomistic(const ActionOptions&ao):
+      43             :   Action(ao),
+      44       10198 :   unique_local_needs_update(true),
+      45       10198 :   boxValue(NULL),
+      46       10198 :   lockRequestAtoms(false),
+      47       10198 :   donotretrieve(false),
+      48       10198 :   donotforce(false),
+      49       10198 :   chargesWereSet(false)
+      50             : {
+      51       10198 :   ActionWithValue* bv = plumed.getActionSet().selectWithLabel<ActionWithValue*>("Box");
+      52       10198 :   if( bv ) boxValue=bv->copyOutput(0);
+      53             :   // We now get all the information about atoms that are lying about
+      54       10198 :   std::vector<ActionWithValue*> vatoms = plumed.getActionSet().select<ActionWithValue*>();
+      55     6190653 :   for(const auto & vv : vatoms ) {
+      56     6180455 :     ActionToPutData* ap = vv->castToActionToPutData();
+      57     6180455 :     if( ap ) {
+      58      142306 :       if( ap->getRole()=="x" ) xpos.push_back( ap->copyOutput(0) );
+      59      142306 :       if( ap->getRole()=="y" ) ypos.push_back( ap->copyOutput(0) );
+      60      142306 :       if( ap->getRole()=="z" ) zpos.push_back( ap->copyOutput(0) );
+      61      142306 :       if( ap->getRole()=="m" ) masv.push_back( ap->copyOutput(0) );
+      62      142306 :       if( ap->getRole()=="q" ) chargev.push_back( ap->copyOutput(0) );
+      63             :     }
+      64     6180455 :     ActionWithVirtualAtom* av = vv->castToActionWithVirtualAtom();
+      65     6180455 :     if( av || vv->getName()=="ARGS2VATOM" ) {
+      66     6087911 :       xpos.push_back( vv->copyOutput( vv->getLabel() + ".x") );
+      67     6087911 :       ypos.push_back( vv->copyOutput( vv->getLabel() + ".y") );
+      68     6087911 :       zpos.push_back( vv->copyOutput( vv->getLabel() + ".z") );
+      69     6087911 :       masv.push_back( vv->copyOutput( vv->getLabel() + ".mass") );
+      70     6087911 :       chargev.push_back( vv->copyOutput( vv->getLabel() + ".charge") );
+      71             :     }
+      72             :   }
+      73       10198 :   if( xpos.size()!=ypos.size() || xpos.size()!=zpos.size() || xpos.size()!=masv.size() || xpos.size()!=chargev.size() )
+      74           0 :     error("mismatch between value arrays");
+      75       10198 : }
+      76             : 
+      77       10467 : void ActionAtomistic::registerKeywords( Keywords& keys ) {
+      78             :   (void) keys; // avoid warning
+      79       10467 : }
+      80             : 
+      81             : 
+      82       10260 : void ActionAtomistic::requestAtoms(const std::vector<AtomNumber> & a, const bool clearDep) {
+      83       10260 :   plumed_massert(!lockRequestAtoms,"requested atom list can only be changed in the prepare() method");
+      84       10260 :   int nat=a.size();
+      85       10260 :   indexes=a;
+      86       10260 :   positions.resize(nat);
+      87       10260 :   forces.resize(nat);
+      88       10260 :   masses.resize(nat);
+      89       10260 :   charges.resize(nat);
+      90       10260 :   atom_value_ind.resize( a.size() );
+      91       10260 :   int n=getTotAtoms();
+      92       10260 :   if(clearDep) clearDependencies();
+      93       10749 :   unique.clear(); std::vector<bool> requirements( xpos.size(), false );
+      94       10260 :   if( boxValue ) addDependency( boxValue->getPntrToAction() );
+      95     1386426 :   for(unsigned i=0; i<indexes.size(); i++) {
+      96     1376169 :     if(indexes[i].index()>=n) { std::string num; Tools::convert( indexes[i].serial(),num ); error("atom " + num + " out of range"); }
+      97     1376166 :     atom_value_ind[i] = getValueIndices( indexes[i] ); requirements[atom_value_ind[i].first] = true;
+      98     1376166 :     if( atom_value_ind[i].first==0 ) unique.push_back(indexes[i]);
+      99        7225 :     else if( atom_value_ind[i].second>0 ) error("action atomistic is not set up to deal with multiple vectors in position input");
+     100             :   }
+     101             :   // Add the dependencies to the actions that we require
+     102       10259 :   Tools::removeDuplicates(unique); value_depends.resize(0);
+     103     6101802 :   for(unsigned i=0; i<requirements.size(); ++i ) {
+     104     6091543 :     if( !requirements[i] ) continue;
+     105       17308 :     value_depends.push_back( i );
+     106       17307 :     addDependency( xpos[i]->getPntrToAction() );
+     107       17307 :     addDependency( ypos[i]->getPntrToAction() );
+     108       17307 :     addDependency( zpos[i]->getPntrToAction() );
+     109       17307 :     addDependency( masv[i]->getPntrToAction() );
+     110       17307 :     addDependency( chargev[i]->getPntrToAction() );
+     111             :   }
+     112       10259 :   unique_local_needs_update=true;
+     113       10259 : }
+     114             : 
+     115      222049 : void ActionAtomistic::pbcApply(std::vector<Vector>& dlist, unsigned max_index)const {
+     116      222049 :   pbc.apply(dlist, max_index);
+     117      222049 : }
+     118             : 
+     119         195 : void ActionAtomistic::calculateNumericalDerivatives( ActionWithValue* a ) {
+     120         195 :   calculateAtomicNumericalDerivatives( a, 0 );
+     121         195 : }
+     122             : 
+     123           0 : void ActionAtomistic::changeBox( const Tensor& newbox ) {
+     124           0 :   pbc.setBox( newbox );
+     125           0 : }
+     126             : 
+     127         492 : void ActionAtomistic::calculateAtomicNumericalDerivatives( ActionWithValue* a, const unsigned& startnum ) {
+     128         492 :   if(!a) {
+     129         279 :     a=castToActionWithValue();
+     130         279 :     plumed_massert(a,"only Actions with a value can be differentiated");
+     131             :   }
+     132             : 
+     133         492 :   const size_t nval=a->getNumberOfComponents();
+     134         492 :   const size_t natoms=getNumberOfAtoms();
+     135         492 :   std::vector<Vector> value(nval*natoms);
+     136         492 :   std::vector<Tensor> valuebox(nval);
+     137         492 :   std::vector<Vector> savedPositions(natoms);
+     138             :   const double delta=std::sqrt(epsilon);
+     139             : 
+     140       91856 :   for(int i=0; i<natoms; i++) for(int k=0; k<3; k++) {
+     141       68523 :       savedPositions[i][k]=positions[i][k];
+     142       68523 :       positions[i][k]=positions[i][k]+delta;
+     143       68523 :       a->calculate();
+     144       68523 :       positions[i][k]=savedPositions[i][k];
+     145      202917 :       for(int j=0; j<nval; j++) {
+     146      134394 :         value[j*natoms+i][k]=a->getOutputQuantity(j);
+     147             :       }
+     148             :     }
+     149         492 :   Tensor box(pbc.getBox());
+     150        6396 :   for(int i=0; i<3; i++) for(int k=0; k<3; k++) {
+     151        4428 :       double arg0=box(i,k);
+     152      209997 :       for(int j=0; j<natoms; j++) positions[j]=pbc.realToScaled(positions[j]);
+     153        4428 :       box(i,k)=box(i,k)+delta;
+     154        4428 :       pbc.setBox(box);
+     155      209997 :       for(int j=0; j<natoms; j++) positions[j]=pbc.scaledToReal(positions[j]);
+     156        4428 :       a->calculate();
+     157        4428 :       box(i,k)=arg0;
+     158        4428 :       pbc.setBox(box);
+     159      209997 :       for(int j=0; j<natoms; j++) positions[j]=savedPositions[j];
+     160       19512 :       for(int j=0; j<nval; j++) valuebox[j](i,k)=a->getOutputQuantity(j);
+     161             :     }
+     162             : 
+     163         492 :   a->calculate();
+     164         492 :   a->clearDerivatives();
+     165        2168 :   for(int j=0; j<nval; j++) {
+     166        1676 :     Value* v=a->copyOutput(j);
+     167             :     double ref=v->get();
+     168        1676 :     if(v->hasDerivatives()) {
+     169      100117 :       for(int i=0; i<natoms; i++) for(int k=0; k<3; k++) {
+     170       74532 :           double d=(value[j*natoms+i][k]-ref)/delta;
+     171       74532 :           v->addDerivative(startnum+3*i+k,d);
+     172             :         }
+     173         741 :       Tensor virial;
+     174        9633 :       for(int i=0; i<3; i++) for(int k=0; k<3; k++)virial(i,k)= (valuebox[j](i,k)-ref)/delta;
+     175             : // BE CAREFUL WITH NON ORTHOROMBIC CELL
+     176         741 :       virial=-matmul(box.transpose(),virial);
+     177        9633 :       for(int i=0; i<3; i++) for(int k=0; k<3; k++) v->addDerivative(startnum+3*natoms+3*k+i,virial(k,i));
+     178             :     }
+     179             :   }
+     180         492 : }
+     181             : 
+     182       11745 : void ActionAtomistic::parseAtomList(const std::string&key, std::vector<AtomNumber> &t) {
+     183       11745 :   parseAtomList(key,-1,t);
+     184       11744 : }
+     185             : 
+     186       13731 : void ActionAtomistic::parseAtomList(const std::string&key,const int num, std::vector<AtomNumber> &t) {
+     187       13731 :   plumed_massert( keywords.style(key,"atoms") || keywords.style(key,"hidden"), "keyword " + key + " should be registered as atoms");
+     188             :   std::vector<std::string> strings;
+     189       13731 :   if( num<0 ) {
+     190       11745 :     parseVector(key,strings);
+     191       11744 :     if(strings.empty()) return;
+     192             :   } else {
+     193        1986 :     if ( !parseNumberedVector(key,num,strings) ) return;
+     194             :   }
+     195       11204 :   t.resize(0); interpretAtomList( strings, t );
+     196       13731 : }
+     197             : 
+     198       11807 : void ActionAtomistic::interpretAtomList(std::vector<std::string>& strings, std::vector<AtomNumber> &t) {
+     199       11807 :   Tools::interpretRanges(strings);
+     200      652155 :   for(unsigned i=0; i<strings.size(); ++i) {
+     201             :     AtomNumber atom;
+     202      640348 :     bool ok=Tools::convertNoexcept(strings[i],atom); // this is converting strings to AtomNumbers
+     203      640348 :     if(ok) t.push_back(atom);
+     204             : // here we check if this is a special symbol for MOLINFO
+     205      640348 :     if( !ok && strings[i].compare(0,1,"@")==0 ) {
+     206         619 :       std::string symbol=strings[i].substr(1);
+     207         619 :       if(symbol=="allatoms") {
+     208          24 :         auto n=0; for(unsigned i=0; i<xpos.size(); ++i) n += xpos[i]->getNumberOfValues();
+     209         365 :         t.reserve(n); for(unsigned i=0; i<n; i++) t.push_back(AtomNumber::index(i));
+     210             :         ok=true;
+     211         609 :       } else if(symbol=="mdatoms") {
+     212          12 :         const auto n=xpos[0]->getNumberOfValues();
+     213          12 :         t.reserve(t.size()+n);
+     214         948 :         for(unsigned i=0; i<n; i++) t.push_back(AtomNumber::index(i));
+     215             :         ok=true;
+     216             :       } else {
+     217         597 :         auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     218         597 :         if( moldat ) {
+     219         597 :           std::vector<AtomNumber> atom_list; moldat->interpretSymbol( symbol, atom_list );
+     220         597 :           if( atom_list.size()>0 ) { ok=true; t.insert(t.end(),atom_list.begin(),atom_list.end()); }
+     221           0 :           else { error(strings[i] + " is not a label plumed knows"); }
+     222             :         } else {
+     223           0 :           error("atoms specified using @ symbol but no MOLINFO was available");
+     224             :         }
+     225             :       }
+     226             :     }
+     227             : // here we check if the atom name is the name of a group
+     228      639729 :     if(!ok) {
+     229       14587 :       Group* mygrp=plumed.getActionSet().selectWithLabel<Group*>(strings[i]);
+     230       14587 :       if(mygrp) {
+     231         394 :         std::vector<std::string> grp_str( mygrp->getGroupAtoms() );
+     232         394 :         interpretAtomList( grp_str, t ); ok=true;
+     233         394 :       } else {
+     234       14193 :         Group* mygrp2=plumed.getActionSet().selectWithLabel<Group*>(strings[i]+"_grp");
+     235       14193 :         if(mygrp2) {
+     236           0 :           std::vector<std::string> grp_str( mygrp2->getGroupAtoms() );
+     237           0 :           interpretAtomList( grp_str, t ); ok=true;
+     238           0 :         }
+     239             :       }
+     240             :     }
+     241             : // here we check if the atom name is the name of an added virtual atom
+     242      639954 :     if(!ok) {
+     243             :       unsigned ind = 0;
+     244    12173878 :       for(unsigned j=0; j<xpos.size(); ++j) {
+     245    12173878 :         if( xpos[j]->getPntrToAction()->getLabel()==strings[i] ) {
+     246       14193 :           t.push_back( AtomNumber::index(ind) ); ok=true; break;
+     247             :         }
+     248    12159685 :         ind = ind + xpos[j]->getNumberOfValues();
+     249             :       }
+     250             :     }
+     251      626155 :     if(!ok) error("it was not possible to interpret atom name " + strings[i]);
+     252             :     // plumed_massert(ok,"it was not possible to interpret atom name " + strings[i]);
+     253             :   }
+     254       11807 : }
+     255             : 
+     256     1608819 : std::pair<std::size_t, std::size_t> ActionAtomistic::getValueIndices( const AtomNumber& i ) const {
+     257     1608819 :   std::size_t valno=0, k = i.index();
+     258    13768611 :   for(unsigned j=0; j<xpos.size(); ++j) {
+     259    13768611 :     if( k<xpos[j]->getNumberOfValues() ) { valno=j; break; }
+     260    12159792 :     k = k - xpos[j]->getNumberOfValues();
+     261             :   }
+     262     1608819 :   return std::pair<std::size_t, std::size_t>( valno, k );
+     263             : }
+     264             : 
+     265      162248 : void ActionAtomistic::retrieveAtoms() {
+     266      162248 :   if( boxValue ) {
+     267      159914 :     PbcAction* pbca = boxValue->getPntrToAction()->castToPbcAction();
+     268      159914 :     plumed_assert( pbca ); pbc=pbca->pbc;
+     269             :   }
+     270      162248 :   if( donotretrieve || indexes.size()==0 ) return;
+     271      140104 :   ActionToPutData* cv = chargev[0]->getPntrToAction()->castToActionToPutData();
+     272      140104 :   if(cv) chargesWereSet=cv->hasBeenSet();
+     273             :   unsigned j = 0;
+     274     4314695 :   for(const auto & a : atom_value_ind) {
+     275     4174591 :     std::size_t nn = a.first, kk = a.second;
+     276     4174591 :     positions[j][0] = xpos[nn]->data[kk];
+     277     4174591 :     positions[j][1] = ypos[nn]->data[kk];
+     278     4174591 :     positions[j][2] = zpos[nn]->data[kk];
+     279     4174591 :     charges[j] = chargev[nn]->data[kk];
+     280     4174591 :     masses[j] = masv[nn]->data[kk];
+     281     4174591 :     j++;
+     282             :   }
+     283             : }
+     284             : 
+     285       75040 : void ActionAtomistic::setForcesOnAtoms(const std::vector<double>& forcesToApply, unsigned& ind) {
+     286       75040 :   if( donotforce || (indexes.size()==0 && getName()!="FIXEDATOM") ) return;
+     287      178423 :   for(unsigned i=0; i<value_depends.size(); ++i) {
+     288      103383 :     xpos[value_depends[i]]->hasForce = true;
+     289      103383 :     ypos[value_depends[i]]->hasForce = true;
+     290      103383 :     zpos[value_depends[i]]->hasForce = true;
+     291             :   }
+     292     1507934 :   for(const auto & a : atom_value_ind) {
+     293             :     plumed_dbg_massert( ind<forcesToApply.size(), "problem setting forces in " + getLabel() );
+     294     1432894 :     std::size_t nn = a.first, kk = a.second;
+     295     1432894 :     xpos[nn]->inputForce[kk] += forcesToApply[ind]; ind++;
+     296     1432894 :     ypos[nn]->inputForce[kk] += forcesToApply[ind]; ind++;
+     297     1432894 :     zpos[nn]->inputForce[kk] += forcesToApply[ind]; ind++;
+     298             :   }
+     299       75040 :   setForcesOnCell( forcesToApply, ind );
+     300             : }
+     301             : 
+     302       77551 : void ActionAtomistic::setForcesOnCell(const std::vector<double>& forcesToApply, unsigned& ind) {
+     303       77551 :   setForcesOnCell(forcesToApply.data(),forcesToApply.size(),ind);
+     304       77551 : }
+     305             : 
+     306       81970 : void ActionAtomistic::setForcesOnCell(const double* forcesToApply, std::size_t size, unsigned& ind) {
+     307      819700 :   for(unsigned i=0; i<9; ++i) {
+     308             :     plumed_dbg_massert( ind<size, "problem setting forces in " + getLabel() );
+     309      737730 :     boxValue->addForce( i, forcesToApply[ind] ); ind++;
+     310             :   }
+     311       81970 : }
+     312             : 
+     313           6 : Tensor ActionAtomistic::getVirial() const {
+     314          78 :   Tensor vir; for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) vir[i][j] = boxValue->getForce(3*i+j);
+     315           6 :   return vir;
+     316             : }
+     317             : 
+     318           0 : void ActionAtomistic::readAtomsFromPDB(const PDB& pdb) {
+     319             : 
+     320           0 :   for(unsigned j=0; j<indexes.size(); j++) {
+     321           0 :     if( indexes[j].index()>pdb.size() ) error("there are not enough atoms in the input pdb file");
+     322           0 :     if( pdb.getAtomNumbers()[j].index()!=indexes[j].index() ) error("there are atoms missing in the pdb file");
+     323           0 :     positions[j]=pdb.getPositions()[indexes[j].index()];
+     324             :   }
+     325           0 :   for(unsigned j=0; j<indexes.size(); j++) charges[j]=pdb.getBeta()[indexes[j].index()];
+     326           0 :   for(unsigned j=0; j<indexes.size(); j++) masses[j]=pdb.getOccupancy()[indexes[j].index()];
+     327           0 : }
+     328             : 
+     329       10523 : unsigned ActionAtomistic::getTotAtoms()const {
+     330             :   unsigned natoms = 0;
+     331     6102402 :   for(unsigned i=0; i<xpos.size(); ++i ) natoms += xpos[i]->getNumberOfValues();
+     332       10523 :   return natoms;
+     333             : }
+     334             : 
+     335      106272 : void ActionAtomistic::makeWhole() {
+     336     1152856 :   for(unsigned j=0; j<positions.size()-1; ++j) {
+     337             :     const Vector & first (positions[j]);
+     338     1046584 :     Vector & second (positions[j+1]);
+     339     1046584 :     second=first+pbcDistance(first,second);
+     340             :   }
+     341      106272 : }
+     342             : 
+     343        8208 : void ActionAtomistic::getGradient( const unsigned& ind, Vector& deriv, std::map<AtomNumber,Vector>& gradients ) const {
+     344        8208 :   std::size_t nn = atom_value_ind[ind].first;
+     345        8208 :   if( nn==0 ) { gradients[indexes[ind]] += deriv; return; }
+     346          39 :   xpos[nn]->passGradients( deriv[0], gradients );
+     347          39 :   ypos[nn]->passGradients( deriv[1], gradients );
+     348          39 :   zpos[nn]->passGradients( deriv[2], gradients );
+     349             : }
+     350             : 
+     351       73541 : void ActionAtomistic::updateUniqueLocal( const bool& useunique, const std::vector<int>& g2l ) {
+     352       73541 :   if( useunique ) { unique_local=unique; return; }
+     353             :   // Update unique local if it needs an update
+     354        9064 :   unique_local_needs_update=false; unique_local.clear();
+     355       71922 :   for(auto pp=unique.begin(); pp!=unique.end(); ++pp) {
+     356       62858 :     if(g2l[pp->index()]>=0) unique_local.push_back(*pp); // already sorted
+     357             :   }
+     358             : }
+     359             : 
+     360             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.h.func-sort-c.html b/coverage/core/ActionAtomistic.h.func-sort-c.html new file mode 100644 index 000000000000..37c16e2c4130 --- /dev/null +++ b/coverage/core/ActionAtomistic.h.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAtomistic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAtomistic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15ActionAtomistic18getAbsoluteIndexesEv160
_ZN4PLMD15ActionAtomistic8addForceERKSt4pairImmERKNS_13VectorGenericILj3EEE9967
_ZNK4PLMD15ActionAtomistic8getForceERKSt4pairImmE15886
_ZNK4PLMD15ActionAtomistic9getChargeEi48946
_ZN4PLMD15ActionAtomistic12lockRequestsEv148236
_ZN4PLMD15ActionAtomistic14unlockRequestsEv148236
_ZN4PLMD15ActionAtomistic21castToActionAtomisticEv175027
_ZN4PLMD15ActionAtomistic17setGlobalPositionERKSt4pairImmERKNS_13VectorGenericILj3EEE322110
_ZNK4PLMD15ActionAtomistic17getGlobalPositionERKSt4pairImmE326248
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.h.func.html b/coverage/core/ActionAtomistic.h.func.html new file mode 100644 index 000000000000..798b23779afe --- /dev/null +++ b/coverage/core/ActionAtomistic.h.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAtomistic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAtomistic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionAtomistic12lockRequestsEv148236
_ZN4PLMD15ActionAtomistic14unlockRequestsEv148236
_ZN4PLMD15ActionAtomistic17setGlobalPositionERKSt4pairImmERKNS_13VectorGenericILj3EEE322110
_ZN4PLMD15ActionAtomistic21castToActionAtomisticEv175027
_ZN4PLMD15ActionAtomistic8addForceERKSt4pairImmERKNS_13VectorGenericILj3EEE9967
_ZNK4PLMD15ActionAtomistic17getGlobalPositionERKSt4pairImmE326248
_ZNK4PLMD15ActionAtomistic18getAbsoluteIndexesEv160
_ZNK4PLMD15ActionAtomistic8getForceERKSt4pairImmE15886
_ZNK4PLMD15ActionAtomistic9getChargeEi48946
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionAtomistic.h.gcov.html b/coverage/core/ActionAtomistic.h.gcov.html new file mode 100644 index 000000000000..f77f5fafa42f --- /dev/null +++ b/coverage/core/ActionAtomistic.h.gcov.html @@ -0,0 +1,373 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionAtomistic.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionAtomistic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionAtomistic_h
+      23             : #define __PLUMED_core_ActionAtomistic_h
+      24             : 
+      25             : #include "Action.h"
+      26             : #include "tools/Tensor.h"
+      27             : #include "tools/Pbc.h"
+      28             : #include "tools/ForwardDecl.h"
+      29             : #include "Value.h"
+      30             : #include <vector>
+      31             : #include <map>
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : class Pbc;
+      36             : class PDB;
+      37             : 
+      38             : /// \ingroup MULTIINHERIT
+      39             : /// Action used to create objects that access the positions of the atoms from the MD code
+      40             : class ActionAtomistic :
+      41             :   virtual public Action
+      42             : {
+      43             :   friend class Group;
+      44             :   friend class DomainDecomposition;
+      45             :   friend class ActionWithVirtualAtom;
+      46             : 
+      47             :   std::vector<AtomNumber> indexes;         // the set of needed atoms
+      48             :   std::vector<std::size_t>   value_depends;   // The list of values that are being used
+      49             :   std::vector<std::pair<std::size_t, std::size_t > > atom_value_ind;  // The list of values and indices for the atoms that are being used
+      50             : /// unique should be an ordered set since we later create a vector containing the corresponding indexes
+      51             :   std::vector<AtomNumber>  unique;
+      52             : /// unique_local should be an ordered set since we later create a vector containing the corresponding indexes
+      53             :   bool unique_local_needs_update;
+      54             :   std::vector<AtomNumber>  unique_local;
+      55             :   std::vector<Vector>   positions;       // positions of the needed atoms
+      56             :   double                energy;
+      57             :   Value*                boxValue;
+      58             :   ForwardDecl<Pbc>      pbc_fwd;
+      59             :   Pbc&                  pbc=*pbc_fwd;
+      60             :   std::vector<double>   masses;
+      61             :   std::vector<double>   charges;
+      62             : 
+      63             :   std::vector<Vector>   forces;          // forces on the needed atoms
+      64             :   double                forceOnEnergy;
+      65             : 
+      66             :   double                forceOnExtraCV;
+      67             : 
+      68             :   bool                  lockRequestAtoms; // forbid changes to request atoms
+      69             : 
+      70             :   bool                  donotretrieve;
+      71             :   bool                  donotforce;
+      72             : 
+      73             : /// Values that hold information about atom positions and charges
+      74             :   std::vector<Value*>   xpos, ypos, zpos, masv, chargev;
+      75             :   void updateUniqueLocal( const bool& useunique, const std::vector<int>& g2l );
+      76             : protected:
+      77             :   bool                  chargesWereSet;
+      78             :   void setExtraCV(const std::string &name);
+      79             : /// Used to interpret whether this index is a virtual atom or a real atom
+      80             :   std::pair<std::size_t, std::size_t> getValueIndices( const AtomNumber& i ) const ;
+      81             : public:
+      82             : /// Request an array of atoms.
+      83             : /// This method is used to ask for a list of atoms. Atoms
+      84             : /// should be asked for by number. If this routine is called
+      85             : /// during the simulation, atoms will be available at the next step
+      86             : /// MAYBE WE HAVE TO FIND SOMETHING MORE CLEAR FOR DYNAMIC
+      87             : /// LISTS OF ATOMS
+      88             :   void requestAtoms(const std::vector<AtomNumber> & a, const bool clearDep=true);
+      89             : /// Get position of i-th atom (access by relative index)
+      90             :   const Vector & getPosition(int)const;
+      91             : /// Get position of i-th atom (access by absolute AtomNumber).
+      92             : /// With direct access to the global atom array.
+      93             : /// \warning Should be only used by actions that need to read the shared position array.
+      94             : ///          This array is insensitive to local changes such as makeWhole(), numerical derivatives, etc.
+      95             :   Vector getGlobalPosition(const std::pair<std::size_t,std::size_t>& ) const ;
+      96             : /// Modify position of i-th atom (access by absolute AtomNumber).
+      97             : /// \warning Should be only used by actions that need to modify the shared position array.
+      98             : ///          This array is insensitive to local changes such as makeWhole(), numerical derivatives, etc.
+      99             :   void setGlobalPosition(const std::pair<std::size_t,std::size_t>&, const Vector& pos);
+     100             : /// Get total number of atoms, including virtual ones.
+     101             : /// Can be used to make a loop on modifyGlobalPosition or getGlobalPosition.
+     102             :   unsigned getTotAtoms()const;
+     103             : /// Get box shape
+     104             :   const Tensor & getBox()const;
+     105             : /// Get the array of all positions
+     106             :   const std::vector<Vector> & getPositions()const;
+     107             : /// Get the virial that is acting
+     108             :   Tensor getVirial() const ;
+     109             : /// Get energy
+     110             :   const double & getEnergy()const;
+     111             : /// Get mass of i-th atom
+     112             :   double getMass(int i)const;
+     113             : /// Get charge of i-th atom
+     114             :   double getCharge(int i)const;
+     115             : /// Get the force acting on a particular atom
+     116             :   Vector getForce( const std::pair<std::size_t, std::size_t>& a ) const ;
+     117             : /// Add force to an atom
+     118             :   void addForce( const std::pair<std::size_t, std::size_t>& a, const Vector& f );
+     119             : /// Get a reference to force on energy
+     120             :   double & modifyForceOnEnergy();
+     121             : /// Get number of available atoms
+     122  4197236614 :   unsigned getNumberOfAtoms()const {return indexes.size();}
+     123             : /// Compute the pbc distance between two positions
+     124             :   Vector pbcDistance(const Vector&,const Vector&)const;
+     125             : /// Applies  PBCs to a seriens of positions or distances
+     126             :   void pbcApply(std::vector<Vector>& dlist, unsigned max_index=0) const;
+     127             : /// Get the vector of absolute indexes
+     128             :   virtual const std::vector<AtomNumber> & getAbsoluteIndexes()const;
+     129             : /// Get the absolute index of an atom
+     130             :   AtomNumber getAbsoluteIndex(int i)const;
+     131             : /// Parse a list of atoms without a numbered keyword
+     132             :   void parseAtomList(const std::string&key,std::vector<AtomNumber> &t);
+     133             : /// Parse an list of atom with a numbred keyword
+     134             :   void parseAtomList(const std::string&key,const int num, std::vector<AtomNumber> &t);
+     135             : /// Convert a set of read in strings into an atom list (this is used in parseAtomList)
+     136             :   void interpretAtomList( std::vector<std::string>& strings, std::vector<AtomNumber> &t);
+     137             : /// Change the box shape
+     138             :   void changeBox( const Tensor& newbox );
+     139             : /// Get reference to Pbc
+     140             :   const Pbc & getPbc() const;
+     141             : /// Add the forces to the atoms
+     142             :   void setForcesOnAtoms( const std::vector<double>& forcesToApply, unsigned& ind );
+     143             : /// Add the virial forces
+     144             :   void setForcesOnCell(const std::vector<double>& forcesToApply, unsigned& ind);
+     145             : /// Add the virial forces (span-like syntax)
+     146             :   void setForcesOnCell(const double* forcesToApply, std::size_t size, unsigned& ind);
+     147             : /// Skip atom retrieval - use with care.
+     148             : /// If this function is called during initialization, then atoms are
+     149             : /// not going to be retrieved. Can be used for optimization. Notice that
+     150             : /// calling getPosition(int) in an Action where DoNotRetrieve() was called might
+     151             : /// lead to undefined behavior.
+     152          40 :   void doNotRetrieve() {donotretrieve=true;}
+     153             : /// Skip atom forces - use with care.
+     154             : /// If this function is called during initialization, then forces are
+     155             : /// not going to be propagated. Can be used for optimization.
+     156          40 :   void doNotForce() {donotforce=true;}
+     157             : /// Make atoms whole, assuming they are in the proper order
+     158             :   void makeWhole();
+     159             : public:
+     160             : 
+     161             : // virtual functions:
+     162             : 
+     163             :   explicit ActionAtomistic(const ActionOptions&ao);
+     164             :   ~ActionAtomistic();
+     165             :   static void registerKeywords( Keywords& keys );
+     166             : 
+     167             : /// N.B. only pass an ActionWithValue to this routine if you know exactly what you
+     168             : /// are doing.  The default will be correct for the vast majority of cases
+     169             :   void   calculateNumericalDerivatives( ActionWithValue* a=NULL ) override;
+     170             : /// Numerical derivative routine to use when using Actions that inherit from BOTH
+     171             : /// ActionWithArguments and ActionAtomistic
+     172             :   void calculateAtomicNumericalDerivatives( ActionWithValue* a, const unsigned& startnum );
+     173             : 
+     174             :   virtual void retrieveAtoms();
+     175             :   void lockRequests() override;
+     176             :   void unlockRequests() override;
+     177             :   const std::vector<AtomNumber> & getUnique()const;
+     178             :   const std::vector<AtomNumber> & getUniqueLocal()const;
+     179             : /// Read in an input file containing atom positions and calculate the action for the atomic
+     180             : /// configuration therin
+     181             :   void readAtomsFromPDB( const PDB& pdb ) override;
+     182             : /// Transfer the gradients
+     183             :   void getGradient( const unsigned& ind, Vector& deriv, std::map<AtomNumber,Vector>& gradients ) const ;
+     184      175027 :   ActionAtomistic* castToActionAtomistic() noexcept final { return this; }
+     185             : };
+     186             : 
+     187             : inline
+     188             : const Vector & ActionAtomistic::getPosition(int i)const {
+     189   530771439 :   return positions[i];
+     190             : }
+     191             : 
+     192             : inline
+     193             : double ActionAtomistic::getMass(int i)const {
+     194      519469 :   return masses[i];
+     195             : }
+     196             : 
+     197             : inline
+     198       48946 : double ActionAtomistic::getCharge(int i) const {
+     199       48946 :   if( !chargesWereSet ) error("charges were not passed to plumed");
+     200       48946 :   return charges[i];
+     201             : }
+     202             : 
+     203             : inline
+     204         160 : const std::vector<AtomNumber> & ActionAtomistic::getAbsoluteIndexes()const {
+     205         161 :   return indexes;
+     206             : }
+     207             : 
+     208             : inline
+     209             : AtomNumber ActionAtomistic::getAbsoluteIndex(int i)const {
+     210   126263034 :   return indexes[i];
+     211             : }
+     212             : 
+     213             : inline
+     214             : const std::vector<Vector> & ActionAtomistic::getPositions()const {
+     215      561704 :   return positions;
+     216             : }
+     217             : 
+     218             : inline
+     219             : const double & ActionAtomistic::getEnergy()const {
+     220             :   return energy;
+     221             : }
+     222             : 
+     223             : inline
+     224             : const Tensor & ActionAtomistic::getBox()const {
+     225       25194 :   return pbc.getBox();
+     226             : }
+     227             : 
+     228             : inline
+     229             : double & ActionAtomistic::modifyForceOnEnergy() {
+     230             :   return forceOnEnergy;
+     231             : }
+     232             : 
+     233             : inline
+     234             : const Pbc & ActionAtomistic::getPbc() const {
+     235      580866 :   return pbc;
+     236             : }
+     237             : 
+     238             : inline
+     239      148236 : void ActionAtomistic::lockRequests() {
+     240      162827 :   lockRequestAtoms=true;
+     241      148236 : }
+     242             : 
+     243             : inline
+     244      148236 : void ActionAtomistic::unlockRequests() {
+     245      162827 :   lockRequestAtoms=false;
+     246      148236 : }
+     247             : 
+     248             : inline
+     249             : const std::vector<AtomNumber> & ActionAtomistic::getUnique()const {
+     250       11264 :   return unique;
+     251             : }
+     252             : 
+     253             : inline
+     254             : const std::vector<AtomNumber> & ActionAtomistic::getUniqueLocal() const {
+     255       47010 :   return unique_local;
+     256             : }
+     257             : 
+     258             : inline
+     259      326248 : Vector ActionAtomistic::getGlobalPosition(const std::pair<std::size_t,std::size_t>& a) const {
+     260      326248 :   Vector pos;
+     261      326248 :   pos[0]=xpos[a.first]->data[a.second];
+     262      326248 :   pos[1]=ypos[a.first]->data[a.second];
+     263      326248 :   pos[2]=zpos[a.first]->data[a.second];
+     264      326248 :   return pos;
+     265             : }
+     266             : 
+     267             : inline
+     268      322110 : void ActionAtomistic::setGlobalPosition(const std::pair<std::size_t, std::size_t>& a, const Vector& pos ) {
+     269      322110 :   xpos[a.first]->data[a.second]=pos[0];
+     270      322110 :   ypos[a.first]->data[a.second]=pos[1];
+     271      322110 :   zpos[a.first]->data[a.second]=pos[2];
+     272      322110 : }
+     273             : 
+     274             : inline
+     275       15886 : Vector ActionAtomistic::getForce( const std::pair<std::size_t, std::size_t>& a ) const {
+     276       15886 :   Vector f;
+     277       15886 :   f[0]=xpos[a.first]->getForce(a.second);
+     278       15886 :   f[1]=ypos[a.first]->getForce(a.second);
+     279       15886 :   f[2]=zpos[a.first]->getForce(a.second);
+     280       15886 :   return f;
+     281             : }
+     282             : 
+     283             : inline
+     284        9967 : void ActionAtomistic::addForce( const std::pair<std::size_t, std::size_t>& a, const Vector& f ) {
+     285        9967 :   xpos[a.first]->addForce( a.second, f[0] );
+     286        9967 :   ypos[a.first]->addForce( a.second, f[1] );
+     287        9967 :   zpos[a.first]->addForce( a.second, f[2] );
+     288        9967 : }
+     289             : 
+     290             : inline
+     291             : Vector ActionAtomistic::pbcDistance(const Vector &v1,const Vector &v2)const {
+     292   149453749 :   return pbc.distance(v1,v2);
+     293             : }
+     294             : 
+     295             : }
+     296             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionForInterface.cpp.func-sort-c.html b/coverage/core/ActionForInterface.cpp.func-sort-c.html new file mode 100644 index 000000000000..1b24ef190c93 --- /dev/null +++ b/coverage/core/ActionForInterface.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionForInterface.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionForInterface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionForInterfaceC1ERKNS_13ActionOptionsE0
_ZN4PLMD18ActionForInterface16registerKeywordsERNS_8KeywordsE6550
_ZN4PLMD18ActionForInterfaceC2ERKNS_13ActionOptionsE7522
_ZNK4PLMD18ActionForInterface7getRoleB5cxx11Ev355957
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionForInterface.cpp.func.html b/coverage/core/ActionForInterface.cpp.func.html new file mode 100644 index 000000000000..21db9047a0e8 --- /dev/null +++ b/coverage/core/ActionForInterface.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionForInterface.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionForInterface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionForInterface16registerKeywordsERNS_8KeywordsE6550
_ZN4PLMD18ActionForInterfaceC1ERKNS_13ActionOptionsE0
_ZN4PLMD18ActionForInterfaceC2ERKNS_13ActionOptionsE7522
_ZNK4PLMD18ActionForInterface7getRoleB5cxx11Ev355957
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionForInterface.cpp.gcov.html b/coverage/core/ActionForInterface.cpp.gcov.html new file mode 100644 index 000000000000..ffe339ce9a1a --- /dev/null +++ b/coverage/core/ActionForInterface.cpp.gcov.html @@ -0,0 +1,126 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionForInterface.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionForInterface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionForInterface.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "PlumedMain.h"
+      25             : #include "ActionSet.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29        6550 : void ActionForInterface::registerKeywords(Keywords& keys) {
+      30        6550 :   Action::registerKeywords(keys); ActionWithValue::registerKeywords( keys );
+      31       13100 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      32       13100 :   keys.add("optional","ROLE","Get the role this value plays in the code can be x/y/z/m/q to signify that this is x, y, z positions of atoms or masses or charges of atoms");
+      33        6550 : }
+      34             : 
+      35        7522 : ActionForInterface::ActionForInterface(const ActionOptions&ao):
+      36             :   Action(ao),
+      37             :   ActionWithValue(ao),
+      38        7522 :   firststep(true),
+      39        7522 :   wasscaled(false),
+      40        7522 :   wasset(false)
+      41             : {
+      42       20654 :   if( keywords.exists("ROLE") && getName()!="DOMAIN_DECOMPOSITION") parse("ROLE",role);
+      43        7522 : }
+      44             : 
+      45      355957 : std::string ActionForInterface::getRole() const {
+      46      355957 :   return role;
+      47             : }
+      48             : 
+      49             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionForInterface.h.func-sort-c.html b/coverage/core/ActionForInterface.h.func-sort-c.html new file mode 100644 index 000000000000..1eb7a98a7b51 --- /dev/null +++ b/coverage/core/ActionForInterface.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionForInterface.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionForInterface.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7887.5 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD18ActionForInterface26getNumberOfForcesToRescaleEv0
_ZN4PLMD18ActionForInterface24castToActionForInterfaceEv819
_ZN4PLMD18ActionForInterface5resetEv52435
_ZN4PLMD18ActionForInterface16clearDerivativesEv371337
_ZN4PLMD18ActionForInterface20setGradientsIfNeededEv371337
_ZN4PLMD18ActionForInterface9calculateEv371337
_ZN4PLMD18ActionForInterface22getNumberOfDerivativesEv24047029
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionForInterface.h.func.html b/coverage/core/ActionForInterface.h.func.html new file mode 100644 index 000000000000..c206722adcf0 --- /dev/null +++ b/coverage/core/ActionForInterface.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionForInterface.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionForInterface.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7887.5 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionForInterface16clearDerivativesEv371337
_ZN4PLMD18ActionForInterface20setGradientsIfNeededEv371337
_ZN4PLMD18ActionForInterface22getNumberOfDerivativesEv24047029
_ZN4PLMD18ActionForInterface24castToActionForInterfaceEv819
_ZN4PLMD18ActionForInterface5resetEv52435
_ZN4PLMD18ActionForInterface9calculateEv371337
_ZNK4PLMD18ActionForInterface26getNumberOfForcesToRescaleEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionForInterface.h.gcov.html b/coverage/core/ActionForInterface.h.gcov.html new file mode 100644 index 000000000000..f8d4c9c0e99f --- /dev/null +++ b/coverage/core/ActionForInterface.h.gcov.html @@ -0,0 +1,167 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionForInterface.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionForInterface.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7887.5 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionForInterface_h
+      23             : #define __PLUMED_core_ActionForInterface_h
+      24             : 
+      25             : #include "tools/TypesafePtr.h"
+      26             : #include "ActionWithValue.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : class ActionForInterface : public ActionWithValue {
+      31             :   friend class Atoms;
+      32             :   friend class PlumedMain;
+      33             : protected:
+      34             : // Is this the first step
+      35             :   bool firststep;
+      36             : /// Have the forces in this action been scaled by another action
+      37             :   bool wasscaled;
+      38             : /// Action has been set
+      39             :   bool wasset;
+      40             : /// The role this plays
+      41             :   std::string role;
+      42             : public:
+      43             :   static void registerKeywords(Keywords& keys);
+      44             :   explicit ActionForInterface(const ActionOptions&ao);
+      45             : /// Override clear the input data
+      46      371337 :   void clearDerivatives() override {}
+      47             : /// Override the need to deal with gradients
+      48      371337 :   void setGradientsIfNeeded() override {}
+      49             : /// Check if the value has been set
+      50             :   bool hasBeenSet() const ;
+      51             : /// The number of derivatives
+      52    24047029 :   unsigned getNumberOfDerivatives() override { return 0; }
+      53             : ///
+      54             :   virtual void resetForStepStart() = 0;
+      55             : /// Set the start point for the memory if needed
+      56             :   virtual void setStart( const std::string& name, const unsigned& sss) = 0;
+      57             : /// Set the stride for the memory if needed
+      58             :   virtual void setStride( const std::string& name, const unsigned& sss) = 0;
+      59             : /// Set the pointer to the value that contains this data
+      60             :   virtual bool setValuePointer( const std::string& name, const TypesafePtr & ) = 0;
+      61             : /// Set the force to the value that contains this data
+      62             :   virtual bool setForcePointer( const std::string& name, const TypesafePtr & ) = 0;
+      63             : /// This get the number of forces that need to be rescaled in rescale forces
+      64           0 :   virtual unsigned getNumberOfForcesToRescale() const { plumed_merror("no method for rescaling forces for this type of input"); }
+      65             : /// Overriding this method from ActionWithValue ensures that taskLists that are set during share are not updated during calculate loop
+      66             : //  void setupForCalculation( const bool& force=false ) override {}
+      67             : /// Get the data
+      68             :   virtual void share() = 0;
+      69             :   virtual void shareAll() = 0;
+      70             : /// Get the data to share
+      71             :   virtual void wait() = 0;
+      72             : /// Actually set the values for the output
+      73      371337 :   void calculate() override { wasscaled=false; }
+      74       52435 :   virtual void reset() {}
+      75             :   virtual void Set_comm(Communicator& comm) = 0;
+      76             : /// For replica exchange
+      77             :   virtual void writeBinary(std::ostream&o) = 0;
+      78             :   virtual void readBinary(std::istream&i) = 0;
+      79             :   virtual bool onStep() const = 0;
+      80             :   std::string getRole() const ;
+      81         819 :   ActionForInterface* castToActionForInterface() noexcept final { return this; }
+      82             : };
+      83             : 
+      84             : inline
+      85             : bool ActionForInterface::hasBeenSet() const {
+      86      357986 :   return wasset;
+      87             : }
+      88             : 
+      89             : }
+      90             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.cpp.func-sort-c.html b/coverage/core/ActionPilot.cpp.func-sort-c.html new file mode 100644 index 000000000000..0375dcedc7c7 --- /dev/null +++ b/coverage/core/ActionPilot.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionPilot.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionPilotC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionPilot9setStrideERKi17
_ZN4PLMD11ActionPilotC2ERKNS_13ActionOptionsE2696
_ZN4PLMD11ActionPilot16registerKeywordsERNS_8KeywordsE2765
_ZNK4PLMD11ActionPilot9getStrideEv81235
_ZNK4PLMD11ActionPilot6onStepEv1448824
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.cpp.func.html b/coverage/core/ActionPilot.cpp.func.html new file mode 100644 index 000000000000..530d93ea41e0 --- /dev/null +++ b/coverage/core/ActionPilot.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionPilot.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionPilot16registerKeywordsERNS_8KeywordsE2765
_ZN4PLMD11ActionPilot9setStrideERKi17
_ZN4PLMD11ActionPilotC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionPilotC2ERKNS_13ActionOptionsE2696
_ZNK4PLMD11ActionPilot6onStepEv1448824
_ZNK4PLMD11ActionPilot9getStrideEv81235
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.cpp.gcov.html b/coverage/core/ActionPilot.cpp.gcov.html new file mode 100644 index 000000000000..6be79e650e2d --- /dev/null +++ b/coverage/core/ActionPilot.cpp.gcov.html @@ -0,0 +1,132 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionPilot.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionPilot.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : 
+      26        2765 : void ActionPilot::registerKeywords(Keywords& keys) {}
+      27             : 
+      28        2696 : ActionPilot::ActionPilot(const ActionOptions&ao):
+      29             :   Action(ao),
+      30        2696 :   stride(1)
+      31             : {
+      32        5392 :   if( keywords.exists("STRIDE") ) {
+      33        2638 :     parse("STRIDE",stride);
+      34        5276 :     if( !keywords.style("STRIDE","hidden") ) log.printf("  with stride %d\n",stride);
+      35             :   } else {
+      36          58 :     stride=0;
+      37             :   }
+      38        2696 : }
+      39             : 
+      40     1448824 : bool ActionPilot::onStep()const {
+      41     1448824 :   if( stride>0 ) return getStep()%stride==0;
+      42             :   return false;
+      43             : }
+      44             : 
+      45       81235 : int ActionPilot::getStride()const {
+      46       81235 :   return stride;
+      47             : }
+      48             : 
+      49          17 : void ActionPilot::setStride(const int& n) {
+      50          17 :   stride=n;
+      51          17 : }
+      52             : 
+      53             : }
+      54             : 
+      55             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.h.func-sort-c.html b/coverage/core/ActionPilot.h.func-sort-c.html new file mode 100644 index 000000000000..01a0d6c340c9 --- /dev/null +++ b/coverage/core/ActionPilot.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionPilot.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.h.func.html b/coverage/core/ActionPilot.h.func.html new file mode 100644 index 000000000000..7b6f1c2e2b81 --- /dev/null +++ b/coverage/core/ActionPilot.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionPilot.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionPilot.h.gcov.html b/coverage/core/ActionPilot.h.gcov.html new file mode 100644 index 000000000000..48f449f5c3c4 --- /dev/null +++ b/coverage/core/ActionPilot.h.gcov.html @@ -0,0 +1,135 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionPilot.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionPilot.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionPilot_h
+      23             : #define __PLUMED_core_ActionPilot_h
+      24             : 
+      25             : #include "Action.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : /**
+      30             : \ingroup MULTIINHERIT
+      31             : This is used to create PLMD::Action objects that are run with some set frequency.
+      32             : Any PLMD::Action
+      33             : that does not inherit from PLMD::Action is only run when some other Action requires the output from
+      34             : it in order to run.  This class is used in PLMD::Bias
+      35             :  Action which drives the execution of other Action's.
+      36             :  Action's of this kind are executed with a fixed stride
+      37             :  which is specified on the directive line with a STRIDE= keyword
+      38             : */
+      39        1517 : class ActionPilot:
+      40             :   public virtual Action
+      41             : {
+      42             :   int stride; // multiple time step
+      43             : public:
+      44             :   explicit ActionPilot(const ActionOptions&);
+      45             : /// Create the keywords for actionPilot
+      46             :   static void registerKeywords(Keywords& keys);
+      47             : /// Check if the action is active on this step
+      48             :   virtual bool onStep()const;
+      49             : /// Set the value of the stride
+      50             :   void setStride( const int& n );
+      51             : /// Get the stride
+      52             :   int getStride()const;
+      53             : };
+      54             : 
+      55             : }
+      56             : 
+      57             : #endif
+      58             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.cpp.func-sort-c.html b/coverage/core/ActionRegister.cpp.func-sort-c.html new file mode 100644 index 000000000000..a620c0b83129 --- /dev/null +++ b/coverage/core/ActionRegister.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionRegister.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:456569.2 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionRegister13printTemplateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD14ActionRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbSA_299
_ZN4PLMDlsERSoRKNS_14ActionRegisterE302
_ZNK4PLMD14ActionRegister14getActionNamesB5cxx11Ev303
_ZN4PLMD14ActionRegister11getKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE596
_ZN4PLMD14ActionRegisterD2Ev4187
_ZN4PLMD14ActionRegister6createERKNS_13ActionOptionsE21855
_ZN4PLMD14ActionRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE22752
_ZN4PLMD14ActionRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6ActionESt14default_deleteIS8_EERKNS_13ActionOptionsEEPFvRNS_8KeywordsEE1247729
_ZN4PLMD14ActionRegister6removeEPFSt10unique_ptrINS_6ActionESt14default_deleteIS2_EERKNS_13ActionOptionsEE1247729
_ZN4PLMD14actionRegisterEv2518215
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.cpp.func.html b/coverage/core/ActionRegister.cpp.func.html new file mode 100644 index 000000000000..82cbdb1a6256 --- /dev/null +++ b/coverage/core/ActionRegister.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionRegister.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:456569.2 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionRegister11getKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_8KeywordsE596
_ZN4PLMD14ActionRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKbSA_299
_ZN4PLMD14ActionRegister13printTemplateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZN4PLMD14ActionRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6ActionESt14default_deleteIS8_EERKNS_13ActionOptionsEEPFvRNS_8KeywordsEE1247729
_ZN4PLMD14ActionRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE22752
_ZN4PLMD14ActionRegister6createERKNS_13ActionOptionsE21855
_ZN4PLMD14ActionRegister6removeEPFSt10unique_ptrINS_6ActionESt14default_deleteIS2_EERKNS_13ActionOptionsEE1247729
_ZN4PLMD14ActionRegisterD2Ev4187
_ZN4PLMD14actionRegisterEv2518215
_ZN4PLMDlsERSoRKNS_14ActionRegisterE302
_ZNK4PLMD14ActionRegister14getActionNamesB5cxx11Ev303
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.cpp.gcov.html b/coverage/core/ActionRegister.cpp.gcov.html new file mode 100644 index 000000000000..12f5838f1cad --- /dev/null +++ b/coverage/core/ActionRegister.cpp.gcov.html @@ -0,0 +1,219 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionRegister.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:456569.2 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionRegister.h"
+      23             : #include "tools/Tools.h"
+      24             : #include "Action.h"
+      25             : #include <algorithm>
+      26             : #include <iostream>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30        4187 : ActionRegister::~ActionRegister() {
+      31        4187 :   if(m.size()>0) {
+      32           0 :     std::string names="";
+      33           0 :     for(const auto & p : m) names+=p.first+" ";
+      34           0 :     std::cerr<<"WARNING: Directive "+ names +" has not been properly unregistered. This might lead to memory leak!!\n";
+      35             :   }
+      36        4187 : }
+      37             : 
+      38     2518215 : ActionRegister& actionRegister() {
+      39     2518215 :   static ActionRegister ans;
+      40     2518215 :   return ans;
+      41             : }
+      42             : 
+      43     1247729 : void ActionRegister::remove(creator_pointer f) {
+      44   108238311 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      45   108238311 :     if((*p).second==f) {
+      46     1247729 :       m.erase(p); break;
+      47             :     }
+      48             :   }
+      49     1247729 : }
+      50             : 
+      51     1247729 : void ActionRegister::add(std::string key,creator_pointer f,keywords_pointer k) {
+      52             :   // this force each action to be registered as an uppercase string
+      53     6301447 :   if ( std::any_of( std::begin( key ), std::end( key ), []( char c ) { return ( std::islower( c ) ); } ) ) plumed_error() << "Action: " + key + " cannot be registered, use only UPPERCASE characters";
+      54             :   if(m.count(key)) {
+      55             :     m.erase(key);
+      56           0 :     disabled.insert(key);
+      57             :   } else {
+      58     1247729 :     m.insert(std::pair<std::string,creator_pointer>(key,f));
+      59             :     // Store a pointer to the function that creates keywords
+      60             :     // A pointer is stored and not the keywords because all
+      61             :     // Vessels must be dynamically loaded before the actions.
+      62     1247729 :     mk.insert(std::pair<std::string,keywords_pointer>(key,k));
+      63             :   };
+      64     1247729 : }
+      65             : 
+      66       22752 : bool ActionRegister::check(const std::string & key) {
+      67       22748 :   if(m.count(key)>0 && mk.count(key)>0) return true;
+      68             :   return false;
+      69             : }
+      70             : 
+      71       21855 : std::unique_ptr<Action> ActionRegister::create(const ActionOptions&ao) {
+      72       21855 :   if(ao.line.size()<1)return NULL;
+      73             :   // Create a copy of the manual locally. The manual is
+      74             :   // then added to the ActionOptions. This allows us to
+      75             :   // ensure during construction that all the keywords for
+      76             :   // the action have been documented. In addition, we can
+      77             :   // generate the documentation when the user makes an error
+      78             :   // in the input.
+      79       21855 :   std::unique_ptr<Action> action;
+      80       21855 :   if( check(ao.line[0]) ) {
+      81       21853 :     Keywords keys; mk[ao.line[0]](keys);
+      82       21853 :     ActionOptions nao( ao,keys );
+      83       43668 :     action=m[ao.line[0]](nao);
+      84       21853 :   }
+      85             :   return action;
+      86       21855 : }
+      87             : 
+      88         596 : bool ActionRegister::getKeywords(const std::string& action, Keywords& keys) {
+      89         596 :   if ( check(action) ) {  mk[action](keys); return true; }
+      90             :   return false;
+      91             : }
+      92             : 
+      93         299 : bool ActionRegister::printManual(const std::string& action, const bool& vimout, const bool& spellout) {
+      94         299 :   if ( check(action) ) {
+      95         298 :     Keywords keys; getKeywords( action, keys );
+      96         298 :     if( vimout ) {
+      97         298 :       printf("%s",action.c_str()); keys.print_vim(); printf("\n");
+      98           0 :     } else if( spellout ) {
+      99           0 :       keys.print_spelling();
+     100             :     } else {
+     101           0 :       keys.print_html();
+     102             :     }
+     103             :     return true;
+     104         298 :   } else {
+     105             :     return false;
+     106             :   }
+     107             : }
+     108             : 
+     109           0 : bool ActionRegister::printTemplate(const std::string& action, bool include_optional) {
+     110           0 :   if( check(action) ) {
+     111           0 :     Keywords keys; mk[action](keys);
+     112           0 :     keys.print_template(action, include_optional);
+     113             :     return true;
+     114           0 :   } else {
+     115             :     return false;
+     116             :   }
+     117             : }
+     118             : 
+     119         303 : std::vector<std::string> ActionRegister::getActionNames() const {
+     120             :   std::vector<std::string> s;
+     121       90600 :   for(const auto & it : m) s.push_back(it.first);
+     122         303 :   std::sort(s.begin(),s.end());
+     123         303 :   return s;
+     124           0 : }
+     125             : 
+     126         302 : std::ostream & operator<<(std::ostream &log,const ActionRegister&ar) {
+     127         302 :   std::vector<std::string> s(ar.getActionNames());
+     128       90301 :   for(unsigned i=0; i<s.size(); i++) log<<"  "<<s[i]<<"\n";
+     129         302 :   if(!ar.disabled.empty()) {
+     130           0 :     s.assign(ar.disabled.size(),"");
+     131           0 :     std::copy(ar.disabled.begin(),ar.disabled.end(),s.begin());
+     132           0 :     std::sort(s.begin(),s.end());
+     133           0 :     log<<"+++++++ WARNING +++++++\n";
+     134           0 :     log<<"The following keywords have been registered more than once and will be disabled:\n";
+     135           0 :     for(unsigned i=0; i<s.size(); i++) log<<"  - "<<s[i]<<"\n";
+     136           0 :     log<<"+++++++ END WARNING +++++++\n";
+     137             :   };
+     138         302 :   return log;
+     139         302 : }
+     140             : 
+     141             : 
+     142             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.h.func-sort-c.html b/coverage/core/ActionRegister.h.func-sort-c.html new file mode 100644 index 000000000000..f97e0f765033 --- /dev/null +++ b/coverage/core/ActionRegister.h.func-sort-c.html @@ -0,0 +1,3433 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionRegister.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:81984097.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionRegistrationINS_11multicolvar11XYDistancesEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar15VolumeTetraporeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInEnvelopeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6LWallsEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q3EEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q4EEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_15crystallization22InterMolecularTorsionsEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q3EE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6adjmat20ContactAlignedMatrixEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6dimred9SmacofMDSEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8analysis14LandmarkStagedEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8analysis18SelectRandomFramesEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8function6TargetEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XDistancesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInCylinderEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarCombineEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarProductEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DistanceFromContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_15crystallization11SimpleCubicEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_15crystallization11TetrahedralEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_15crystallization13PolymerAnglesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat10SMACMatrixEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat19ClusterDistributionEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6dimred13SketchMapReadEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6dimred15SketchMapSmacofEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6dimred18SketchMapPointwiseEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8analysis17ReselectLandmarksEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools11FindContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools16FourierTransformEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools18FindContourSurfaceEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools20FindSphericalContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeCavityEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DihedralCorrelationEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6UWallsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_15crystallization13MoleculePlaneEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_15crystallization15BondOrientationEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_15crystallization8GradientEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4pamm15HBPammHydrogensEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6adjmat11HBondMatrixEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6adjmat15ClusterDiameterEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6adjmat18ClusterWithSurfaceEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred19OutputPCAProjectionEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred24ProjectNonLandmarkPointsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8analysis23ReadDissimilarityMatrixEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_9gridtools9GridToXYZEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar13FilterBetweenEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_11multicolvar14VolumeInSphereEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CenterOfMultiColvarEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_11multicolvar7XAnglesEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_11multicolvar9XYTorsionEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q4EE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6dimred17SketchMapConjGradEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_7mapping11PropertyMapEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_8function9PiecewiseEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterLessEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_11multicolvar12LocalAverageEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_11multicolvar13NumberOfLinksEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_15crystallization19MoleculeOrientationEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_15crystallization7FccubicEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6adjmat13MatrixRowSumsEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6adjmat9DumpGraphEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_9gridtools13IntegrateGridEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q6EEEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_15crystallization4SMACEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6adjmat16MatrixColumnSumsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8analysis13OutputPDBFileEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpCubeEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterMoreEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_11multicolvar6BridgeEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_4maze4LossEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6adjmat13OutputClusterEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_8analysis16SelectWithStrideEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_8analysis24PrintDissimilarityMatrixEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_15crystallization21EnvironmentSimilarityEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarDensityEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_11multicolvar7DensityEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightWhamEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_8function4SortEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_8analysis28EuclideanDissimilarityMatrixEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q6EE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_6adjmat13DFSClusteringEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEE6createERKNS_13ActionOptionsE16
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEE6createERKNS_13ActionOptionsE16
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEE6createERKNS_13ActionOptionsE19
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_8analysis16OutputColvarFileEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeAroundEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEE6createERKNS_13ActionOptionsE24
_ZN4PLMD18ActionRegistrationINS_6adjmat11ClusterSizeEE6createERKNS_13ActionOptionsE24
_ZN4PLMD18ActionRegistrationINS_6adjmat17ClusterPropertiesEE6createERKNS_13ActionOptionsE27
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEE6createERKNS_13ActionOptionsE27
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEE6createERKNS_13ActionOptionsE28
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEE6createERKNS_13ActionOptionsE30
_ZN4PLMD18ActionRegistrationINS_8analysis18ReadAnalysisFramesEE6createERKNS_13ActionOptionsE30
_ZN4PLMD18ActionRegistrationINS_8function5StatsEE6createERKNS_13ActionOptionsE31
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEE6createERKNS_13ActionOptionsE32
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEE6createERKNS_13ActionOptionsE33
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEE6createERKNS_13ActionOptionsE33
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEE6createERKNS_13ActionOptionsE34
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEE6createERKNS_13ActionOptionsE35
_ZN4PLMD18ActionRegistrationINS_6colvar8ConstantEE6createERKNS_13ActionOptionsE39
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEE6createERKNS_13ActionOptionsE40
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEE6createERKNS_13ActionOptionsE47
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEE6createERKNS_13ActionOptionsE49
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEE6createERKNS_13ActionOptionsE50
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEE6createERKNS_13ActionOptionsE51
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CoordinationNumbersEE6createERKNS_13ActionOptionsE52
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEE6createERKNS_13ActionOptionsE54
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEE6createERKNS_13ActionOptionsE54
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEE6createERKNS_13ActionOptionsE56
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEE6createERKNS_13ActionOptionsE61
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEE6createERKNS_13ActionOptionsE65
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEE6createERKNS_13ActionOptionsE71
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEE6createERKNS_13ActionOptionsE73
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEE6createERKNS_13ActionOptionsE75
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEE6createERKNS_13ActionOptionsE78
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEE6createERKNS_13ActionOptionsE86
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEE6createERKNS_13ActionOptionsE87
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEE6createERKNS_13ActionOptionsE87
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEE6createERKNS_13ActionOptionsE90
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEE6createERKNS_13ActionOptionsE95
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEE6createERKNS_13ActionOptionsE120
_ZN4PLMD18ActionRegistrationINS_5GroupEE6createERKNS_13ActionOptionsE132
_ZN4PLMD18ActionRegistrationINS_8function7CombineEE6createERKNS_13ActionOptionsE140
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEE6createERKNS_13ActionOptionsE157
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEE6createERKNS_13ActionOptionsE160
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEE6createERKNS_13ActionOptionsE178
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEE6createERKNS_13ActionOptionsE182
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEE6createERKNS_13ActionOptionsE191
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEE6createERKNS_13ActionOptionsE268
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEE6createERKNS_13ActionOptionsE285
_ZN4PLMD18ActionRegistrationINS_8function6CustomEE6createERKNS_13ActionOptionsE434
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEE6createERKNS_13ActionOptionsE466
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEE6createERKNS_13ActionOptionsE653
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEE6createERKNS_13ActionOptionsE824
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEE6createERKNS_13ActionOptionsE936
_ZN4PLMD18ActionRegistrationINS_9PbcActionEE6createERKNS_13ActionOptionsE936
_ZN4PLMD18ActionRegistrationINS_11multicolvar12LocalAverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar12LocalAverageEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeAroundEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeCavityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeCavityEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar13NumberOfLinksEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar13NumberOfLinksEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar14VolumeInSphereEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar14VolumeInSphereEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar15VolumeTetraporeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar15VolumeTetraporeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInCylinderEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInCylinderEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInEnvelopeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInEnvelopeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarCombineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarCombineEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarDensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarDensityEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarProductEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarProductEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CenterOfMultiColvarEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CenterOfMultiColvarEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CoordinationNumbersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CoordinationNumbersEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DihedralCorrelationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DihedralCorrelationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DistanceFromContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DistanceFromContourEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar6BridgeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar6BridgeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar7DensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar7DensityEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6LWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6LWallsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6UWallsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization11SimpleCubicEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization11SimpleCubicEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization11TetrahedralEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization11TetrahedralEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization13MoleculePlaneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization13MoleculePlaneEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization13PolymerAnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization13PolymerAnglesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15BondOrientationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15BondOrientationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q3EEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q3EEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q4EEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q4EEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q6EEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q6EEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization19MoleculeOrientationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization19MoleculeOrientationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization21EnvironmentSimilarityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization21EnvironmentSimilarityEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization22InterMolecularTorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization22InterMolecularTorsionsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q3EEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q3EED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q4EEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q4EED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q6EEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q6EED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization4SMACEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization4SMACEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization7FccubicEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization7FccubicEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization8GradientEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization8GradientEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightWhamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightWhamEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze4LossEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze4LossEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4pamm15HBPammHydrogensEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4pamm15HBPammHydrogensEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5GroupEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5GroupEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat10SMACMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat10SMACMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat11ClusterSizeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat11ClusterSizeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat11HBondMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat11HBondMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13DFSClusteringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13DFSClusteringEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13MatrixRowSumsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13MatrixRowSumsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13OutputClusterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13OutputClusterEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat15ClusterDiameterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat15ClusterDiameterEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat16MatrixColumnSumsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat16MatrixColumnSumsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat17ClusterPropertiesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat17ClusterPropertiesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat18ClusterWithSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat18ClusterWithSurfaceEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat19ClusterDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat19ClusterDistributionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat20ContactAlignedMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat20ContactAlignedMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat9DumpGraphEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat9DumpGraphEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8ConstantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8ConstantEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred13SketchMapReadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred13SketchMapReadEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred15SketchMapSmacofEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred15SketchMapSmacofEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred17SketchMapConjGradEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred17SketchMapConjGradEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred18SketchMapPointwiseEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred18SketchMapPointwiseEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred19OutputPCAProjectionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred19OutputPCAProjectionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred24ProjectNonLandmarkPointsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred24ProjectNonLandmarkPointsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred9SmacofMDSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred9SmacofMDSEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7mapping11PropertyMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7mapping11PropertyMapEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis13OutputPDBFileEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis13OutputPDBFileEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis14LandmarkStagedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis14LandmarkStagedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis16OutputColvarFileEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis16OutputColvarFileEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis16SelectWithStrideEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis16SelectWithStrideEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis17ReselectLandmarksEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis17ReselectLandmarksEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis18ReadAnalysisFramesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis18ReadAnalysisFramesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis18SelectRandomFramesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis18SelectRandomFramesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis23ReadDissimilarityMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis23ReadDissimilarityMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis24PrintDissimilarityMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis24PrintDissimilarityMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis28EuclideanDissimilarityMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis28EuclideanDissimilarityMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function4SortEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function4SortEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function5StatsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function5StatsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function6TargetEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function6TargetEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function7CombineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function7CombineEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function9PiecewiseEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function9PiecewiseEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9PbcActionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9PbcActionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools11FindContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools11FindContourEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools13IntegrateGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools13IntegrateGridEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools16FourierTransformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools16FourierTransformEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools18FindContourSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools18FindContourSurfaceEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools20FindSphericalContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools20FindSphericalContourEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpCubeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpCubeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools9GridToXYZEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools9GridToXYZEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEE6createERKNS_13ActionOptionsE5610
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEE6createERKNS_13ActionOptionsE7163
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterLessEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterLessEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterMoreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterMoreEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar13FilterBetweenEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar13FilterBetweenEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_8function6CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_8function6CustomEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XDistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XDistancesEED2Ev12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar11XYDistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar11XYDistancesEED2Ev12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar7XAnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar7XAnglesEED2Ev12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar9XYTorsionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE25122
_ZN4PLMD18ActionRegistrationINS_11multicolvar9XYTorsionEED2Ev25122
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.h.func.html b/coverage/core/ActionRegister.h.func.html new file mode 100644 index 000000000000..710ab9faa651 --- /dev/null +++ b/coverage/core/ActionRegister.h.func.html @@ -0,0 +1,3433 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionRegister.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:81984097.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterLessEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterLessEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterLessEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterMoreEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterMoreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar10FilterMoreEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XDistancesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XDistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar10XDistancesEED2Ev12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar11XYDistancesEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar11XYDistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar11XYDistancesEED2Ev12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar12LocalAverageEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_11multicolvar12LocalAverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar12LocalAverageEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeAroundEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeAroundEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeCavityEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeCavityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar12VolumeCavityEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar13FilterBetweenEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_11multicolvar13FilterBetweenEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar13FilterBetweenEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_11multicolvar13NumberOfLinksEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_11multicolvar13NumberOfLinksEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar13NumberOfLinksEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar14VolumeInSphereEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_11multicolvar14VolumeInSphereEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar14VolumeInSphereEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEE6createERKNS_13ActionOptionsE22
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar15DumpMultiColvarEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar15VolumeTetraporeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar15VolumeTetraporeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar15VolumeTetraporeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16InPlaneDistancesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInCylinderEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInCylinderEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInCylinderEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInEnvelopeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInEnvelopeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar16VolumeInEnvelopeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarCombineEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarCombineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarCombineEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarDensityEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarDensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarDensityEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarProductEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarProductEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar18MultiColvarProductEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CenterOfMultiColvarEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CenterOfMultiColvarEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CenterOfMultiColvarEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CoordinationNumbersEE6createERKNS_13ActionOptionsE52
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CoordinationNumbersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19CoordinationNumbersEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DihedralCorrelationEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DihedralCorrelationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DihedralCorrelationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DistanceFromContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DistanceFromContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar19DistanceFromContourEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar6AnglesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar6BridgeEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_11multicolvar6BridgeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar6BridgeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar7DensityEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_11multicolvar7DensityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar7DensityEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar7XAnglesEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_11multicolvar7XAnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar7XAnglesEED2Ev12561
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar8TorsionsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar9AlphaBetaEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEE6createERKNS_13ActionOptionsE51
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar9DistancesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_11multicolvar9XYTorsionEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_11multicolvar9XYTorsionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE25122
_ZN4PLMD18ActionRegistrationINS_11multicolvar9XYTorsionEED2Ev25122
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEE6createERKNS_13ActionOptionsE87
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14GenericMolInfoEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6LWallsEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6LWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6LWallsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6UWallsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14manyrestraints6UWallsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion10memFusionPEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion20fusionPoreExpansionPEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_14membranefusion21fusionPoreNucleationPEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEE6createERKNS_13ActionOptionsE65
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15ActionToGetDataEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEE6createERKNS_13ActionOptionsE5610
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15ActionToPutDataEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization11SimpleCubicEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_15crystallization11SimpleCubicEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization11SimpleCubicEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization11TetrahedralEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_15crystallization11TetrahedralEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization11TetrahedralEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization13MoleculePlaneEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_15crystallization13MoleculePlaneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization13MoleculePlaneEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization13PolymerAnglesEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_15crystallization13PolymerAnglesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization13PolymerAnglesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15BondOrientationEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_15crystallization15BondOrientationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15BondOrientationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q3EEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q3EEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q3EEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q4EEEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q4EEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q4EEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q6EEEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q6EEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization15LocalSteinhardtINS1_2Q6EEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization19MoleculeOrientationEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_15crystallization19MoleculeOrientationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization19MoleculeOrientationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization21EnvironmentSimilarityEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_15crystallization21EnvironmentSimilarityEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization21EnvironmentSimilarityEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization22InterMolecularTorsionsEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_15crystallization22InterMolecularTorsionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization22InterMolecularTorsionsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q3EE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q3EEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q3EED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q4EE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q4EEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q4EED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q6EE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q6EEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization2Q6EED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization4SMACEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_15crystallization4SMACEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization4SMACEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization7FccubicEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_15crystallization7FccubicEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization7FccubicEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_15crystallization8GradientEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_15crystallization8GradientEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_15crystallization8GradientEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12AntibetaRMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure12ParabetaRMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_18secondarystructure9AlphaRMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEE6createERKNS_13ActionOptionsE936
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_19DomainDecompositionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3drr27DynamicReferenceRestrainingEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3eds3EDSEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3piv3PIVEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEE6createERKNS_13ActionOptionsE95
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves10BF_FourierEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEE6createERKNS_13ActionOptionsE73
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves10TD_UniformEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_CombinedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEE6createERKNS_13ActionOptionsE61
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_LegendreEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEE6createERKNS_13ActionOptionsE47
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves11BF_WaveletsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEE6createERKNS_13ActionOptionsE191
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves11TD_GaussianEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves11TD_VonMisesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves12BF_ChebyshevEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves12BF_GaussiansEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves13OutputFesBiasEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves13TD_ChiSquaredEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves14TD_ExponentialEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves15TD_WellTemperedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves16BF_CubicBsplinesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves17TD_MulticanonicalEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEE6createERKNS_13ActionOptionsE90
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves18VesLinearExpansionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEE6createERKNS_13ActionOptionsE75
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_BachAveragedSGDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves19Opt_RobbinsMonroSGDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEE6createERKNS_13ActionOptionsE71
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves20OutputBasisFunctionsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves20TD_GeneralizedNormalEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves20TD_LinearCombinationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves21TD_ProductCombinationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves22TD_ProductDistributionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEE6createERKNS_13ActionOptionsE120
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves24OutputTargetDistributionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves25TD_MultithermalMultibaricEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves26TD_GeneralizedExtremeValueEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves32TD_ExponentiallyModifiedGaussianEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves6TD_ChiEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves7BF_SineEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves7TD_GridEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves8Opt_AdamEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CosineEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEE6createERKNS_13ActionOptionsE10
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_CustomEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEE6createERKNS_13ActionOptionsE16
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9BF_PowersEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9Opt_DummyEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEE6createERKNS_13ActionOptionsE16
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9TD_CustomEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_3ves9VesDeltaFEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightBiasEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightWhamEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightWhamEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias12ReweightWhamEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias13ReweightMetadEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias15MovingRestraintEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias18ExtendedLagrangianEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias27ReweightTemperaturePressureEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias4ABMDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEE6createERKNS_13ActionOptionsE157
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias5MetaDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias6LWallsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEE6createERKNS_13ActionOptionsE50
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias6MaxEntEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias6UWallsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEE6createERKNS_13ActionOptionsE41
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias7PBMetaDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias8ExternalEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEE6createERKNS_13ActionOptionsE33
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias9BiasValueEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEE6createERKNS_13ActionOptionsE178
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4bias9RestraintEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb11CS2BackboneEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEE6createERKNS_13ActionOptionsE19
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb13MetainferenceEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb14FretEfficiencyEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb3NOEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb3PREEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEE6createERKNS_13ActionOptionsE29
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_4isdb3RDCEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb4EMMIEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEE6createERKNS_13ActionOptionsE32
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_4isdb4SAXSEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb6SelectEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb6ShadowEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb7CaliberEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb7EMMIVOXEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb7RescaleEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb8SelectorEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4isdb9JCouplingEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze10Steered_MDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze11Random_WalkEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze13OptimizerBiasEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze19Simulated_AnnealingEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze22Random_Acceleration_MDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze4LossEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_4maze4LossEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze4LossEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4maze7MemeticEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEE6createERKNS_13ActionOptionsE30
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes12OPESexpandedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes15ECVmultiThermalEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasFileEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes16ECVumbrellasLineEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes20ECVmultiThermalBaricEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes9ECVcustomEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes9ECVlinearEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11convergenceEEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4opes9OPESmetadINS1_11explorationEEEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4pamm12HBPammMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4pamm15HBPammHydrogensEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4pamm15HBPammHydrogensEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4pamm15HBPammHydrogensEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4pamm4PAMMEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEE6createERKNS_13ActionOptionsE24
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4s2cm14S2ContactModelEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4sasa10SASA_HASELEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_4sasa9SASA_LCPOEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5GroupEE6createERKNS_13ActionOptionsE132
_ZN4PLMD18ActionRegistrationINS_5GroupEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5GroupEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5fisst5FISSTEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5setup4LoadEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5setup5UnitsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEE6createERKNS_13ActionOptionsE56
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5setup7RestartEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5vatom5GhostEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEE6createERKNS_13ActionOptionsE7163
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_5vatom6CenterEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_5vatom9FixedAtomEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat10SMACMatrixEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat10SMACMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat10SMACMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat11ClusterSizeEE6createERKNS_13ActionOptionsE24
_ZN4PLMD18ActionRegistrationINS_6adjmat11ClusterSizeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat11ClusterSizeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat11HBondMatrixEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6adjmat11HBondMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat11HBondMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13ContactMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13DFSClusteringEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_6adjmat13DFSClusteringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13DFSClusteringEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13MatrixRowSumsEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6adjmat13MatrixRowSumsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13MatrixRowSumsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13OutputClusterEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6adjmat13OutputClusterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat13OutputClusterEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat14TopologyMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat15ClusterDiameterEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6adjmat15ClusterDiameterEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat15ClusterDiameterEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat16MatrixColumnSumsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6adjmat16MatrixColumnSumsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat16MatrixColumnSumsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat17ClusterPropertiesEE6createERKNS_13ActionOptionsE27
_ZN4PLMD18ActionRegistrationINS_6adjmat17ClusterPropertiesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat17ClusterPropertiesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat18ClusterWithSurfaceEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6adjmat18ClusterWithSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat18ClusterWithSurfaceEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat19ClusterDistributionEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat19ClusterDistributionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat19ClusterDistributionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat20ContactAlignedMatrixEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6adjmat20ContactAlignedMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat20ContactAlignedMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat6SprintEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6adjmat9DumpGraphEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6adjmat9DumpGraphEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6adjmat9DumpGraphEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar10ColvarFakeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar10ContactMapEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEE6createERKNS_13ActionOptionsE11
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar11PropertyMapEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEE6createERKNS_13ActionOptionsE182
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar12CoordinationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar16ProjectionOnAxisEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar4CellEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEE6createERKNS_13ActionOptionsE78
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar4RMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar5AngleEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar5DRMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar5DimerEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar5ERMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEE6createERKNS_13ActionOptionsE54
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar6DipoleEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEE6createERKNS_13ActionOptionsE40
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar6EnergyEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar6GHBFIXEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar6VolumeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar7EEFSolvEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar7ExtraCVEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar7PCARMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEE6createERKNS_13ActionOptionsE14
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar7PathMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEE6createERKNS_13ActionOptionsE653
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar7TorsionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8ConstantEE6createERKNS_13ActionOptionsE39
_ZN4PLMD18ActionRegistrationINS_6colvar8ConstantEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8ConstantEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8DHEnergyEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEE6createERKNS_13ActionOptionsE466
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8DistanceEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEE6createERKNS_13ActionOptionsE33
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8GyrationEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEE6createERKNS_13ActionOptionsE87
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8PositionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar8TemplateEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar9MultiRMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEE6createERKNS_13ActionOptionsE54
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6colvar9PuckeringEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred13SketchMapReadEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6dimred13SketchMapReadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred13SketchMapReadEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred15SketchMapSmacofEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6dimred15SketchMapSmacofEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred15SketchMapSmacofEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred17SketchMapConjGradEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6dimred17SketchMapConjGradEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred17SketchMapConjGradEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred18SketchMapPointwiseEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_6dimred18SketchMapPointwiseEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred18SketchMapPointwiseEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred19OutputPCAProjectionEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred19OutputPCAProjectionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred19OutputPCAProjectionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred24ProjectNonLandmarkPointsEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_6dimred24ProjectNonLandmarkPointsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred24ProjectNonLandmarkPointsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred32ClassicalMultiDimensionalScalingEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred3PCAEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred9SketchMapEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6dimred9SmacofMDSEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_6dimred9SmacofMDSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6dimred9SmacofMDSEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6funnel6FunnelEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6funnel9FUNNEL_PSEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_6logmfd6LogMFDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEE6createERKNS_13ActionOptionsE28
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic10DumpForcesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic10WrapAroundEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic13FitToTemplateEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic14DumpMassChargeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEE6createERKNS_13ActionOptionsE35
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic14WholeMoleculesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEE6createERKNS_13ActionOptionsE285
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic15DumpDerivativesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic15DumpProjectionsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic15RandomExchangesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic20EffectiveEnergyDriftEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEE6createERKNS_13ActionOptionsE86
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic4ReadEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic4TimeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic5DebugEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEE6createERKNS_13ActionOptionsE17
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic5FlushEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEE6createERKNS_13ActionOptionsE824
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic5PrintEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic6PlumedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEE6createERKNS_13ActionOptionsE18
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic7IncludeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEE6createERKNS_13ActionOptionsE7
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic8UpdateIfEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEE6createERKNS_13ActionOptionsE160
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic9DumpAtomsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEE6createERKNS_13ActionOptionsE268
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic9EndPlumedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7generic9ResetCellEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7mapping11PropertyMapEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_7mapping11PropertyMapEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7mapping11PropertyMapEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7mapping12AdaptivePathEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7mapping4PathEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_7mapping7PCAVarsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis11WhamWeightsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis13OutputPDBFileEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8analysis13OutputPDBFileEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis13OutputPDBFileEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis13WhamHistogramEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis14LandmarkStagedEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8analysis14LandmarkStagedEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis14LandmarkStagedEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis16OutputColvarFileEE6createERKNS_13ActionOptionsE20
_ZN4PLMD18ActionRegistrationINS_8analysis16OutputColvarFileEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis16OutputColvarFileEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis16SelectWithStrideEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_8analysis16SelectWithStrideEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis16SelectWithStrideEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis17ReselectLandmarksEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8analysis17ReselectLandmarksEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis17ReselectLandmarksEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis18ReadAnalysisFramesEE6createERKNS_13ActionOptionsE30
_ZN4PLMD18ActionRegistrationINS_8analysis18ReadAnalysisFramesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis18ReadAnalysisFramesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis18SelectRandomFramesEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8analysis18SelectRandomFramesEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis18SelectRandomFramesEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis21FarthestPointSamplingEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis23ReadDissimilarityMatrixEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8analysis23ReadDissimilarityMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis23ReadDissimilarityMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis24PrintDissimilarityMatrixEE6createERKNS_13ActionOptionsE8
_ZN4PLMD18ActionRegistrationINS_8analysis24PrintDissimilarityMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis24PrintDissimilarityMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis28EuclideanDissimilarityMatrixEE6createERKNS_13ActionOptionsE13
_ZN4PLMD18ActionRegistrationINS_8analysis28EuclideanDissimilarityMatrixEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis28EuclideanDissimilarityMatrixEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis7AverageEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis9CommittorEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEE6createERKNS_13ActionOptionsE34
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8analysis9HistogramEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function11FuncPathMSDEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEE6createERKNS_13ActionOptionsE9
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function12FuncSumHillsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function13LocalEnsembleEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function15FuncPathGeneralEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function4SortEE6createERKNS_13ActionOptionsE12
_ZN4PLMD18ActionRegistrationINS_8function4SortEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function4SortEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function5StatsEE6createERKNS_13ActionOptionsE31
_ZN4PLMD18ActionRegistrationINS_8function5StatsEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function5StatsEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function6CustomEE6createERKNS_13ActionOptionsE434
_ZN4PLMD18ActionRegistrationINS_8function6CustomEEC2ESt17basic_string_viewIcSt11char_traitsIcEE8374
_ZN4PLMD18ActionRegistrationINS_8function6CustomEED2Ev8374
_ZN4PLMD18ActionRegistrationINS_8function6TargetEE6createERKNS_13ActionOptionsE0
_ZN4PLMD18ActionRegistrationINS_8function6TargetEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function6TargetEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function7CombineEE6createERKNS_13ActionOptionsE140
_ZN4PLMD18ActionRegistrationINS_8function7CombineEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function7CombineEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEE6createERKNS_13ActionOptionsE5
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function7annfunc3ANNEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function7pytorch12PytorchModelEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEE6createERKNS_13ActionOptionsE27
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function8EnsembleEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_8function9PiecewiseEE6createERKNS_13ActionOptionsE3
_ZN4PLMD18ActionRegistrationINS_8function9PiecewiseEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_8function9PiecewiseEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9PbcActionEE6createERKNS_13ActionOptionsE936
_ZN4PLMD18ActionRegistrationINS_9PbcActionEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9PbcActionEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools11FindContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools11FindContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools11FindContourEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEE6createERKNS_13ActionOptionsE15
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools12ConvertToFESEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools13IntegrateGridEE6createERKNS_13ActionOptionsE4
_ZN4PLMD18ActionRegistrationINS_9gridtools13IntegrateGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools13IntegrateGridEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools15InterpolateGridEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools16FourierTransformEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools16FourierTransformEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools16FourierTransformEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools18FindContourSurfaceEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools18FindContourSurfaceEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools18FindContourSurfaceEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools20FindSphericalContourEE6createERKNS_13ActionOptionsE1
_ZN4PLMD18ActionRegistrationINS_9gridtools20FindSphericalContourEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools20FindSphericalContourEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpCubeEE6createERKNS_13ActionOptionsE6
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpCubeEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpCubeEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEE6createERKNS_13ActionOptionsE49
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools8DumpGridEED2Ev4187
_ZN4PLMD18ActionRegistrationINS_9gridtools9GridToXYZEE6createERKNS_13ActionOptionsE2
_ZN4PLMD18ActionRegistrationINS_9gridtools9GridToXYZEEC2ESt17basic_string_viewIcSt11char_traitsIcEE4187
_ZN4PLMD18ActionRegistrationINS_9gridtools9GridToXYZEED2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionRegister.h.gcov.html b/coverage/core/ActionRegister.h.gcov.html new file mode 100644 index 000000000000..6d07ce0df1aa --- /dev/null +++ b/coverage/core/ActionRegister.h.gcov.html @@ -0,0 +1,209 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionRegister.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:81984097.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionRegister_h
+      23             : #define __PLUMED_core_ActionRegister_h
+      24             : 
+      25             : #include <string>
+      26             : #include <map>
+      27             : #include <set>
+      28             : #include <iosfwd>
+      29             : #include "tools/Keywords.h"
+      30             : #include <memory>
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : class Action;
+      35             : class ActionOptions;
+      36             : 
+      37             : /// Register holding all the allowed keywords.
+      38             : /// This is a register which holds a map between strings (directives) and function pointers.
+      39             : /// The function pointers are pointing to functions which create an object of
+      40             : /// the corresponding class given the corresponding options (ActionOptions).
+      41             : /// There should be only one of there objects allocated.
+      42             : /// Actions should be registered here at the beginning of execution
+      43             : /// If the same directive is used for different classes, it is automatically disabled
+      44             : /// to avoid random results.
+      45             : ///
+      46             : class ActionRegister {
+      47             : /// Write on a stream the list of registered directives
+      48             :   friend std::ostream &operator<<(std::ostream &,const ActionRegister&);
+      49             : /// Pointer to a function which, given the options, create an Action
+      50             :   typedef std::unique_ptr<Action>(*creator_pointer)(const ActionOptions&);
+      51             : /// Pointer to a function which, returns the keywords allowed
+      52             :   typedef void(*keywords_pointer)(Keywords&);
+      53             : /// Map action to a function which creates the related object
+      54             :   std::map<std::string,creator_pointer> m;
+      55             : /// Map action to a function which documents the related object
+      56             :   std::map<std::string,keywords_pointer> mk;
+      57             : /// Set of disabled actions (which were registered more than once)
+      58             :   std::set<std::string> disabled;
+      59             : public:
+      60             : /// Register a new class.
+      61             : /// \param key The name of the directive to be used in the input file
+      62             : /// \param cp A pointer to a function which creates an object of that class
+      63             : /// \param kp A pointer to a function which returns the allowed keywords
+      64             :   void add(std::string key,creator_pointer cp,keywords_pointer kp);
+      65             : /// Verify if a directive is present in the register
+      66             :   bool check(const std::string & action);
+      67             : /// Create an Action of the type indicated in the options
+      68             : /// \param ao object containing information for initialization, such as the full input line, a pointer to PlumedMain, etc
+      69             :   std::unique_ptr<Action> create(const ActionOptions&ao);
+      70             : /// Print out the keywords for an action in html/vim ready for input into the manual
+      71             :   bool printManual(const std::string& action, const bool& vimout, const bool& spellout);
+      72             : /// Retrieve a keywords object for a particular action
+      73             :   bool getKeywords( const std::string& action, Keywords& keys );
+      74             : /// Print out a template command for an action
+      75             :   bool printTemplate(const std::string& action, bool include_optional);
+      76             :   void remove(creator_pointer);
+      77             : /// Get a list of action names
+      78             :   std::vector<std::string> getActionNames() const ;
+      79             :   ~ActionRegister();
+      80             : };
+      81             : 
+      82             : /// Function returning a reference to the ActionRegister.
+      83             : /// \relates ActionRegister
+      84             : /// To avoid problems with order of initialization, this function contains
+      85             : /// a static ActionRegister which is built the first time the function is called.
+      86             : /// In this manner, it is always initialized before it's used
+      87             : ActionRegister& actionRegister();
+      88             : 
+      89             : std::ostream & operator<<(std::ostream &log,const ActionRegister&ar);
+      90             : 
+      91             : template<typename T>
+      92             : inline constexpr bool isActionType = std::is_base_of<Action, T>::value;
+      93             : //in C++20 you we'll make this a concept
+      94             : //template<typename T>
+      95             : //concept ActionType = std::is_base_of<::PLMD::Action, T>::value;
+      96             : //so the template will be template<ActionType ActionType>class ActionRegistration{...}
+      97             : //without the explicit need of the static assert
+      98             : 
+      99             : ///Each instance of this specialized class represents an action that can be called
+     100             : ///with  the specified directive.
+     101             : ///As soon it goes out of scope it will deregister the directive from the singleton ActionRegister
+     102             : template<typename ActionClass>
+     103             : class ActionRegistration {
+     104       21850 :   static std::unique_ptr<Action> create(const ActionOptions&ao) {
+     105       42542 :     return std::make_unique<ActionClass>(ao);
+     106             :   }
+     107             : public:
+     108             :   ///On construction register the ActionClass with the wanted directive
+     109     1247726 :   ActionRegistration(std::string_view directive) {
+     110             :     static_assert(isActionType<ActionClass>,
+     111             :                   "ActionRegistration accepts only class that inherit from Action");
+     112     1247726 :     actionRegister().add(directive.data(),create,ActionClass::registerKeywords);
+     113     1247726 :   }
+     114             :   ///On destruction deregister the ActionClass (useful when you unload a shared object)
+     115     1247726 :   ~ActionRegistration() {actionRegister().remove(create);}
+     116             : };
+     117             : } //PLMD
+     118             : 
+     119             : #define PLUMED_CONCATENATE_DIRECT(s1, s2) s1##s2
+     120             : #define PLUMED_CONCATENATE(s1, s2) PLUMED_CONCATENATE_DIRECT(s1, s2)
+     121             : 
+     122             : /// Shortcut for Action registration
+     123             : /// \relates PLMD::ActionRegister
+     124             : /// For easier registration, this file also provides a macro PLUMED_REGISTER_ACTION.
+     125             : /// \param classname the name of the class to be registered
+     126             : /// \param directive a string containing the corresponding directive
+     127             : /// This macro should be used in the .cpp file of the corresponding class
+     128             : #define PLUMED_REGISTER_ACTION(classname,directive) \
+     129             :   namespace {::PLMD::ActionRegistration<classname> \
+     130             :              PLUMED_CONCATENATE(classname##Registerer,__LINE__)(directive);}
+     131             : #endif
+     132             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.cpp.func-sort-c.html b/coverage/core/ActionSet.cpp.func-sort-c.html new file mode 100644 index 000000000000..aaf8ec5d11f7 --- /dev/null +++ b/coverage/core/ActionSet.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSet.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSet.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ActionSet11clearDeleteEv1
_ZN4PLMD9ActionSetC2ERNS_10PlumedMainE805283
_ZN4PLMD9ActionSetD2Ev805283
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.cpp.func.html b/coverage/core/ActionSet.cpp.func.html new file mode 100644 index 000000000000..c9d2642f9f54 --- /dev/null +++ b/coverage/core/ActionSet.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSet.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSet.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ActionSet11clearDeleteEv1
_ZN4PLMD9ActionSetC2ERNS_10PlumedMainE805283
_ZN4PLMD9ActionSetD2Ev805283
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.cpp.gcov.html b/coverage/core/ActionSet.cpp.gcov.html new file mode 100644 index 000000000000..81cdfa46abb4 --- /dev/null +++ b/coverage/core/ActionSet.cpp.gcov.html @@ -0,0 +1,119 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSet.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSet.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionSet.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : 
+      26      805283 : ActionSet::ActionSet(PlumedMain&p):
+      27      805283 :   plumed(p) {
+      28             :   (void) plumed; // to suppress warning about "unused plumed"
+      29      805283 : }
+      30             : 
+      31      805283 : ActionSet::~ActionSet()
+      32             : {
+      33             : // required in order to deallocate in reverse order:
+      34      827089 :   for(int i=size()-1; i>=0; i--) (*this)[i].reset();
+      35      805283 : }
+      36             : 
+      37           1 : void ActionSet::clearDelete() {
+      38          10 :   for(int i=size()-1; i>=0; i--) (*this)[i].reset();
+      39           1 :   clear();
+      40           1 : }
+      41             : 
+      42             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.h.func-sort-c.html b/coverage/core/ActionSet.h.func-sort-c.html new file mode 100644 index 000000000000..ab59e1332b0b --- /dev/null +++ b/coverage/core/ActionSet.h.func-sort-c.html @@ -0,0 +1,209 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSet.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSet.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:313491.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9ActionSet6selectIPNS_3ves14BasisFunctionsEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves18TargetDistributionEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves7VesBiasEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet12getLabelListIPNS_15ActionWithValueEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEv1
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_4maze9OptimizerEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_8analysis21LandmarkSelectionBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6dimred27DimensionalityReductionBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD9ActionSet6selectIPNS_11ActionSetupEEESt6vectorIT_SaIS5_EEv2
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6adjmat19AdjacencyMatrixBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_4maze4LossEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6adjmat14ClusteringBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD9ActionSet12selectLatestIPNS_3piv3PIVEEET_PKNS_6ActionE12
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_9PbcActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZNK4PLMD9ActionSet6selectIPNS_4opes12ExpansionCVsEEESt6vectorIT_SaIS6_EEv30
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_8analysis12AnalysisBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE77
_ZNK4PLMD9ActionSet6selectIPNS_7generic4ReadEEESt6vectorIT_SaIS6_EEv86
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves7VesBiasEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE88
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_10vesselbase16ActionWithVesselEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE118
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToGetDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE131
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves14BasisFunctionsEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE241
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_11multicolvar15MultiColvarBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE386
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves18TargetDistributionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE407
_ZNK4PLMD9ActionSet6selectIPNS_19DomainDecompositionEEESt6vectorIT_SaIS5_EEv830
_ZNK4PLMD9ActionSet6selectIPNS_15ActionAtomisticEEESt6vectorIT_SaIS5_EEv880
_ZNK4PLMD9ActionSet12selectLatestIPNS_14GenericMolInfoEEET_PKNS_6ActionE959
_ZNK4PLMD9ActionSet6selectIPNS_15ActionToPutDataEEESt6vectorIT_SaIS5_EEv1041
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_18ActionForInterfaceEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1228
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToPutDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8845
_ZNK4PLMD9ActionSet6selectIPNS_15ActionWithValueEEESt6vectorIT_SaIS5_EEv10532
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6ActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE21853
_ZNK4PLMD9ActionSet6selectIPNS_11ActionPilotEEESt6vectorIT_SaIS5_EEv22706
_ZNK4PLMD9ActionSet6selectIPNS_18ActionForInterfaceEEESt6vectorIT_SaIS5_EEv25129
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_5GroupEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28780
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionWithValueEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1113896
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.h.func.html b/coverage/core/ActionSet.h.func.html new file mode 100644 index 000000000000..74ea4a9596fc --- /dev/null +++ b/coverage/core/ActionSet.h.func.html @@ -0,0 +1,209 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSet.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSet.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:313491.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9ActionSet12getLabelListIPNS_15ActionWithValueEEENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEv1
_ZNK4PLMD9ActionSet12selectLatestIPNS_14GenericMolInfoEEET_PKNS_6ActionE959
_ZNK4PLMD9ActionSet12selectLatestIPNS_3piv3PIVEEET_PKNS_6ActionE12
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_10vesselbase16ActionWithVesselEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE118
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_11multicolvar15MultiColvarBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE386
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToGetDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE131
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionToPutDataEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8845
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_15ActionWithValueEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1113896
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_18ActionForInterfaceEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1228
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves14BasisFunctionsEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE241
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves18TargetDistributionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE407
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_3ves7VesBiasEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE88
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_4maze4LossEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_4maze9OptimizerEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_5GroupEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE28780
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6ActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE21853
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6adjmat14ClusteringBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6adjmat19AdjacencyMatrixBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_6dimred27DimensionalityReductionBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_8analysis12AnalysisBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE77
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_8analysis21LandmarkSelectionBaseEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZNK4PLMD9ActionSet15selectWithLabelIPNS_9PbcActionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZNK4PLMD9ActionSet6selectIPNS_11ActionPilotEEESt6vectorIT_SaIS5_EEv22706
_ZNK4PLMD9ActionSet6selectIPNS_11ActionSetupEEESt6vectorIT_SaIS5_EEv2
_ZNK4PLMD9ActionSet6selectIPNS_15ActionAtomisticEEESt6vectorIT_SaIS5_EEv880
_ZNK4PLMD9ActionSet6selectIPNS_15ActionToPutDataEEESt6vectorIT_SaIS5_EEv1041
_ZNK4PLMD9ActionSet6selectIPNS_15ActionWithValueEEESt6vectorIT_SaIS5_EEv10532
_ZNK4PLMD9ActionSet6selectIPNS_18ActionForInterfaceEEESt6vectorIT_SaIS5_EEv25129
_ZNK4PLMD9ActionSet6selectIPNS_19DomainDecompositionEEESt6vectorIT_SaIS5_EEv830
_ZNK4PLMD9ActionSet6selectIPNS_3ves14BasisFunctionsEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves18TargetDistributionEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_3ves7VesBiasEEESt6vectorIT_SaIS6_EEv0
_ZNK4PLMD9ActionSet6selectIPNS_4opes12ExpansionCVsEEESt6vectorIT_SaIS6_EEv30
_ZNK4PLMD9ActionSet6selectIPNS_7generic4ReadEEESt6vectorIT_SaIS6_EEv86
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSet.h.gcov.html b/coverage/core/ActionSet.h.gcov.html new file mode 100644 index 000000000000..ed5c73c83226 --- /dev/null +++ b/coverage/core/ActionSet.h.gcov.html @@ -0,0 +1,224 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSet.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSet.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:313491.2 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionSet_h
+      23             : #define __PLUMED_core_ActionSet_h
+      24             : 
+      25             : #include "Action.h"
+      26             : #include <memory>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : class PlumedMain;
+      31             : 
+      32             : /// std::vector containing the sequence of Action to be done.
+      33             : /// It is a vector of Action*, and as such it has the entire
+      34             : /// std::vector interface. Moreover, it implements methods to extract
+      35             : /// Acion* of a given type (select<T>()), NOT of a given type (selectNot<T>())
+      36             : /// or to find an Action with a given label (selectWithLabel())
+      37             : /// Finally, since it holds pointers, there is a clearDelete() function
+      38             : /// which deletes the pointers before deleting the vector
+      39             : class ActionSet:
+      40             :   public std::vector<std::unique_ptr<Action>>
+      41             : {
+      42             :   PlumedMain& plumed;
+      43             : public:
+      44             :   explicit ActionSet(PlumedMain&p);
+      45             :   ~ActionSet();
+      46             : /// Clear and deletes all the included pointers.
+      47             :   void clearDelete();
+      48             : 
+      49             : /// Extract pointers to all Action's of type T
+      50             : /// To extract all Colvar , use select<Colvar*>();
+      51             :   template <class T>
+      52             :   std::vector<T> select()const;
+      53             : /// Extract pointers to all Action's which are not of type T
+      54             : /// E.g., to extract all noncolvars, use
+      55             : ///    selectNot<Colvar*>();
+      56             :   template <class T>
+      57             :   std::vector<Action*> selectNot()const;
+      58             : /// Extract pointer to an action labeled s, only if it is of
+      59             : /// type T. E.g., to extract an action labeled "pippo", use selectWithLabel<Action*>("pippo")
+      60             : /// If you want it to be a Colvar, use selectWithLabel<Colvar*>(pippo). If it is
+      61             : /// not found, it returns NULL
+      62             :   template <class T>
+      63             :   T selectWithLabel(const std::string&s)const;
+      64             : /// get the labels in the list of actions in form of a string (useful to debug)
+      65             : /// Only classes that can be dynamic casted to T are reported
+      66             :   template <class T>
+      67             :   std::string getLabelList() const;
+      68             : /// get the labels in the form of a vector of strings
+      69             : /// Only classes that can be dynamic casted to T are reported
+      70             :   template <class T>
+      71             :   std::vector<std::string> getLabelVector() const;
+      72             : /// Extract pointer to last action of type T located before
+      73             : /// action. If action is not in ActionSet or if there is no action of type T
+      74             : /// returns NULL.
+      75             : /// Typically to be used as selectLatest<Type>(this);
+      76             :   template <class T>
+      77             :   T selectLatest(const Action*action)const;
+      78             : };
+      79             : 
+      80             : /////
+      81             : // INLINE IMPLEMENTATIONS:
+      82             : 
+      83             : template <class T>
+      84       61236 : std::vector<T> ActionSet::select()const {
+      85             :   std::vector<T> ret;
+      86    19130395 :   for(const auto & p : (*this)) {
+      87    19069159 :     T t=dynamic_cast<T>(p.get());
+      88    19069159 :     if(t) ret.push_back(t);
+      89             :   };
+      90       61236 :   return ret;
+      91             : }
+      92             : 
+      93             : template <class T>
+      94     1176093 : T ActionSet::selectWithLabel(const std::string&s)const {
+      95    60016045 :   for(const auto & p : (*this)) {
+      96    53655928 :     T t=dynamic_cast<T>(p.get());
+      97    59959932 :     if(t && t->getLabel()==s) return t;
+      98             :   };
+      99             :   return NULL;
+     100             : }
+     101             : 
+     102             : template <class T>
+     103             : std::vector<Action*> ActionSet::selectNot()const {
+     104             :   std::vector<Action*> ret;
+     105             :   for(const auto & p : (*this)) {
+     106             :     T t=dynamic_cast<T>(p);
+     107             :     if(!t) ret.push_back(p.get());
+     108             :   };
+     109             :   return ret;
+     110             : }
+     111             : 
+     112             : template <class T>
+     113           1 : std::string ActionSet::getLabelList() const {
+     114             :   std::string outlist;
+     115          12 :   for(const auto & p : (*this)) {
+     116          22 :     if(dynamic_cast<T>(p.get())) outlist+=p->getLabel()+" ";
+     117             :   };
+     118           1 :   return  outlist;
+     119             : }
+     120             : 
+     121             : 
+     122             : template <class T>
+     123             : std::vector<std::string> ActionSet::getLabelVector() const {
+     124             :   std::vector<std::string> outlist;
+     125             :   for(const auto & p : (*this)) {
+     126             :     if(dynamic_cast<T>(p.get())) outlist.push_back(p->getLabel());
+     127             :   };
+     128             :   return  outlist;
+     129             : }
+     130             : 
+     131             : template <class T>
+     132         971 : T ActionSet::selectLatest(const Action*action) const {
+     133             :   T t=nullptr;
+     134       21583 :   for(const auto & p : (*this)) {
+     135       20652 :     if(p.get()==action) return t;
+     136       20612 :     T r=dynamic_cast<T>(p.get());
+     137       20612 :     if(r) t=r;
+     138             :   }
+     139             :   return t;
+     140             : }
+     141             : 
+     142             : 
+     143             : 
+     144             : }
+     145             : 
+     146             : #endif
+     147             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.cpp.func-sort-c.html b/coverage/core/ActionSetup.cpp.func-sort-c.html new file mode 100644 index 000000000000..14e1a5227902 --- /dev/null +++ b/coverage/core/ActionSetup.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSetup.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101190.9 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetupC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionSetupC2ERKNS_13ActionOptionsE80
_ZN4PLMD11ActionSetup16registerKeywordsERNS_8KeywordsE175
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.cpp.func.html b/coverage/core/ActionSetup.cpp.func.html new file mode 100644 index 000000000000..fd1fcc3defcc --- /dev/null +++ b/coverage/core/ActionSetup.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSetup.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101190.9 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup16registerKeywordsERNS_8KeywordsE175
_ZN4PLMD11ActionSetupC1ERKNS_13ActionOptionsE0
_ZN4PLMD11ActionSetupC2ERKNS_13ActionOptionsE80
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.cpp.gcov.html b/coverage/core/ActionSetup.cpp.gcov.html new file mode 100644 index 000000000000..f48ef1d22fb2 --- /dev/null +++ b/coverage/core/ActionSetup.cpp.gcov.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSetup.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101190.9 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionSetup.h"
+      23             : #include "ActionForInterface.h"
+      24             : #include "PlumedMain.h"
+      25             : #include "ActionSet.h"
+      26             : #include "tools/Exception.h"
+      27             : #include "ActionAnyorder.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31          80 : ActionSetup::ActionSetup(const ActionOptions&ao):
+      32          80 :   Action(ao)
+      33             : {
+      34          80 :   const ActionSet& actionset(plumed.getActionSet());
+      35         718 :   for(const auto & p : actionset) {
+      36             : // check that all the preceding actions are ActionSetup
+      37         638 :     if( !dynamic_cast<ActionSetup*>(p.get()) && !dynamic_cast<ActionForInterface*>(p.get()) && !dynamic_cast<ActionAnyorder*>(p.get()) ) {
+      38           0 :       error("Action " + getLabel() + " is a setup action, and should be only preceded by other setup actions or by actions that can be used in any order.");
+      39             :     }
+      40             :   }
+      41          80 : }
+      42             : 
+      43         175 : void ActionSetup::registerKeywords( Keywords& keys ) {
+      44         175 :   Action::registerKeywords(keys);
+      45         175 :   keys.remove("LABEL");
+      46         175 : }
+      47             : 
+      48             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.h.func-sort-c.html b/coverage/core/ActionSetup.h.func-sort-c.html new file mode 100644 index 000000000000..57a0e23bb78e --- /dev/null +++ b/coverage/core/ActionSetup.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSetup.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1333.3 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup5applyEv0
_ZN4PLMD11ActionSetup9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.h.func.html b/coverage/core/ActionSetup.h.func.html new file mode 100644 index 000000000000..ccbc7c37ded8 --- /dev/null +++ b/coverage/core/ActionSetup.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSetup.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1333.3 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ActionSetup5applyEv0
_ZN4PLMD11ActionSetup9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionSetup.h.gcov.html b/coverage/core/ActionSetup.h.gcov.html new file mode 100644 index 000000000000..612bd1afd6bd --- /dev/null +++ b/coverage/core/ActionSetup.h.gcov.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionSetup.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionSetup.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1333.3 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionSetup_h
+      23             : #define __PLUMED_core_ActionSetup_h
+      24             : 
+      25             : #include "Action.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : /**
+      30             : \ingroup MULTIINHERIT
+      31             : Action used to create a PLMD::Action that do something during setup only e.g. PLMD::SetupUnits
+      32             : */
+      33           1 : class ActionSetup :
+      34             :   public virtual Action {
+      35             : public:
+      36             : /// Constructor
+      37             :   explicit ActionSetup(const ActionOptions&ao);
+      38             : /// Creator of keywords
+      39             :   static void registerKeywords( Keywords& keys );
+      40             : /// Do nothing.
+      41           0 :   void calculate() override {}
+      42             : /// Do nothing.
+      43           0 :   void apply() override {}
+      44             : };
+      45             : 
+      46             : }
+      47             : 
+      48             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.cpp.func-sort-c.html b/coverage/core/ActionShortcut.cpp.func-sort-c.html new file mode 100644 index 000000000000..aaa127a4d72c --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:192770.4 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcutC1ERKNS_13ActionOptionsE0
_ZNK4PLMD14ActionShortcut18getSavedInputLinesB5cxx11Ev0
_ZN4PLMD14ActionShortcutC2ERKNS_13ActionOptionsE15
_ZN4PLMD14ActionShortcut16registerKeywordsERNS_8KeywordsE23
_ZN4PLMD14ActionShortcut13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE42
_ZNK4PLMD14ActionShortcut16getShortcutLabelB5cxx11Ev60
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.cpp.func.html b/coverage/core/ActionShortcut.cpp.func.html new file mode 100644 index 000000000000..dd7107bc6a00 --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionShortcut.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:192770.4 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE42
_ZN4PLMD14ActionShortcut16registerKeywordsERNS_8KeywordsE23
_ZN4PLMD14ActionShortcutC1ERKNS_13ActionOptionsE0
_ZN4PLMD14ActionShortcutC2ERKNS_13ActionOptionsE15
_ZNK4PLMD14ActionShortcut16getShortcutLabelB5cxx11Ev60
_ZNK4PLMD14ActionShortcut18getSavedInputLinesB5cxx11Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.cpp.gcov.html b/coverage/core/ActionShortcut.cpp.gcov.html new file mode 100644 index 000000000000..2be0d2692187 --- /dev/null +++ b/coverage/core/ActionShortcut.cpp.gcov.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionShortcut.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionShortcut.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:192770.4 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionShortcut.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "ActionSet.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28          23 : void ActionShortcut::registerKeywords( Keywords& keys ) {
+      29          23 :   Action::registerKeywords( keys );
+      30          46 :   keys.add("hidden","IS_SHORTCUT","hidden keyword to tell if actions are shortcuts so that example generator can provide expansions of shortcuts");
+      31          23 : }
+      32             : 
+      33          15 : ActionShortcut::ActionShortcut(const ActionOptions&ao):
+      34             :   Action(ao),
+      35          15 :   shortcutlabel(label)
+      36             : {
+      37          15 :   std::string s; Tools::convert(plumed.getActionSet().size(),s);
+      38          15 :   if( shortcutlabel==("@" + s) ) {
+      39           0 :     std::string t; Tools::convert(plumed.getActionSet().size(),t);
+      40           0 :     shortcutlabel="@" + t;
+      41          30 :   } else label = ("@s" + s);
+      42          15 : }
+      43             : 
+      44          42 : void ActionShortcut::readInputLine( const std::string& input ) {
+      45          42 :   std::string f_input = input; savedInputLines.push_back( input );
+      46          42 :   if( update_from!=std::numeric_limits<double>::max() ) {
+      47           0 :     std::string ufrom; Tools::convert( update_from, ufrom ); f_input += " UPDATE_FROM=" + ufrom;
+      48             :   }
+      49          42 :   if( update_until!=std::numeric_limits<double>::max() ) {
+      50           0 :     std::string util; Tools::convert( update_until, util ); f_input += " UPDATE_UNTIL=" + util;
+      51             :   }
+      52          84 :   if( keywords.exists("RESTART") ) {
+      53           0 :     if( restart ) f_input += " RESTART=YES";
+      54           0 :     if( !restart ) f_input += " RESTART=NO";
+      55             :   }
+      56          42 :   plumed.readInputLine( f_input );
+      57          42 : }
+      58             : 
+      59          60 : const std::string & ActionShortcut::getShortcutLabel() const {
+      60          60 :   return shortcutlabel;
+      61             : }
+      62             : 
+      63           0 : std::vector<std::string> ActionShortcut::getSavedInputLines() const {
+      64           0 :   return savedInputLines;
+      65             : }
+      66             : 
+      67             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.h.func-sort-c.html b/coverage/core/ActionShortcut.h.func-sort-c.html new file mode 100644 index 000000000000..abfedf8f5fdb --- /dev/null +++ b/coverage/core/ActionShortcut.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionShortcut.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:030.0 %
Date:2024-02-22 21:58:45Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut20castToActionShortcutEv0
_ZN4PLMD14ActionShortcut5applyEv0
_ZN4PLMD14ActionShortcut9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.h.func.html b/coverage/core/ActionShortcut.h.func.html new file mode 100644 index 000000000000..88dc372258e0 --- /dev/null +++ b/coverage/core/ActionShortcut.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionShortcut.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:030.0 %
Date:2024-02-22 21:58:45Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ActionShortcut20castToActionShortcutEv0
_ZN4PLMD14ActionShortcut5applyEv0
_ZN4PLMD14ActionShortcut9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionShortcut.h.gcov.html b/coverage/core/ActionShortcut.h.gcov.html new file mode 100644 index 000000000000..0d43fca7e477 --- /dev/null +++ b/coverage/core/ActionShortcut.h.gcov.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionShortcut.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionShortcut.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:030.0 %
Date:2024-02-22 21:58:45Functions:030.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionShortcut_h
+      23             : #define __PLUMED_core_ActionShortcut_h
+      24             : 
+      25             : #include "Action.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : /**
+      30             : \ingroup MULTIINHERIT
+      31             : Action used to create a command that expands to multiple PLMD::Action commands when read in during input
+      32             : */
+      33             : class ActionShortcut :
+      34             :   public virtual Action {
+      35             : private:
+      36             :   std::string shortcutlabel;
+      37             :   std::vector<std::string> savedInputLines;
+      38             : public:
+      39             :   const std::string & getShortcutLabel() const ;
+      40             :   static void registerKeywords( Keywords& keys );
+      41             : /// Constructor
+      42             :   explicit ActionShortcut(const ActionOptions&ao);
+      43             : /// Read a line of input and create appropriate actions
+      44             :   void readInputLine( const std::string& input );
+      45             : /// Do nothing.
+      46           0 :   void calculate() override {}
+      47             : /// Do nothing.
+      48           0 :   void apply() override {}
+      49             : /// Get the lines of the shortcut that were read in
+      50             :   std::vector<std::string> getSavedInputLines() const ;
+      51           0 :   ActionShortcut* castToActionShortcut() noexcept final { return this; }
+      52             : };
+      53             : 
+      54             : }
+      55             : 
+      56             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToGetData.cpp.func-sort-c.html b/coverage/core/ActionToGetData.cpp.func-sort-c.html new file mode 100644 index 000000000000..dce5fe579f90 --- /dev/null +++ b/coverage/core/ActionToGetData.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToGetData.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToGetData.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243080.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToGetDataC2ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionToGetData9get_shapeERKNS_11TypesafePtrE1
_ZN4PLMD15ActionToGetData10set_memoryERKNS_11TypesafePtrE65
_ZN4PLMD15ActionToGetData8get_rankERKNS_11TypesafePtrE65
_ZN4PLMD15ActionToGetDataC1ERKNS_13ActionOptionsE65
_ZN4PLMD15ActionToGetData16registerKeywordsERNS_8KeywordsE67
_ZN4PLMD15ActionToGetData9calculateEv670
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToGetData.cpp.func.html b/coverage/core/ActionToGetData.cpp.func.html new file mode 100644 index 000000000000..f7ed0b03ba5b --- /dev/null +++ b/coverage/core/ActionToGetData.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToGetData.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToGetData.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243080.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToGetData10set_memoryERKNS_11TypesafePtrE65
_ZN4PLMD15ActionToGetData16registerKeywordsERNS_8KeywordsE67
_ZN4PLMD15ActionToGetData8get_rankERKNS_11TypesafePtrE65
_ZN4PLMD15ActionToGetData9calculateEv670
_ZN4PLMD15ActionToGetData9get_shapeERKNS_11TypesafePtrE1
_ZN4PLMD15ActionToGetDataC1ERKNS_13ActionOptionsE65
_ZN4PLMD15ActionToGetDataC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToGetData.cpp.gcov.html b/coverage/core/ActionToGetData.cpp.gcov.html new file mode 100644 index 000000000000..d8824375a717 --- /dev/null +++ b/coverage/core/ActionToGetData.cpp.gcov.html @@ -0,0 +1,160 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToGetData.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToGetData.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243080.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionToGetData.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "PlumedMain.h"
+      25             : 
+      26             : //+PLUMEDOC ANALYSIS GET
+      27             : /*
+      28             : Get data from PLUMED for another code
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : 
+      37             : PLUMED_REGISTER_ACTION(ActionToGetData,"GET")
+      38             : 
+      39          67 : void ActionToGetData::registerKeywords(Keywords& keys) {
+      40          67 :   Action::registerKeywords(keys); ActionPilot::registerKeywords(keys); ActionWithArguments::registerKeywords(keys);
+      41         134 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be stored");
+      42         134 :   keys.add("compulsory","TYPE","value","what do you want to collect for the value can be derivative/force");
+      43          67 :   keys.use("ARG");
+      44          67 : }
+      45             : 
+      46          65 : ActionToGetData::ActionToGetData(const ActionOptions&ao):
+      47             :   Action(ao),
+      48             :   ActionPilot(ao),
+      49             :   ActionWithArguments(ao),
+      50          65 :   mydata(DataPassingObject::create(plumed.getRealPrecision()))
+      51             : {
+      52         130 :   std::string type; parse("TYPE",type);
+      53          65 :   if( type=="value" ) gtype=val;
+      54           0 :   else if( type=="derivatives" ) gtype=deriv;
+      55           0 :   else if( type=="forces" ) gtype=force;
+      56           0 :   else plumed_merror("cannot get " + type + " for value TYPE should be value/derivative/force");
+      57             : 
+      58          65 :   if( gtype!=val ) error("not implemented functionality to pass derviatives or forces to python.  Email gareth.tribello@gmail.com if you want this.");
+      59             : 
+      60          65 :   if( getNumberOfArguments()!=1 ) error("python interface works best when you ask for one argument at a time");
+      61          65 :   getPntrToArgument(0)->buildDataStore(); data.resize( getPntrToArgument(0)->getNumberOfValues() );
+      62          65 : }
+      63             : 
+      64          65 : void ActionToGetData::get_rank( const TypesafePtr & dims ) {
+      65          65 :   if( getPntrToArgument(0)->getRank()==0 ) { dims.set(long(1)); return; }
+      66           0 :   dims.set(long(getPntrToArgument(0)->getRank()));
+      67             : }
+      68             : 
+      69           1 : void ActionToGetData::get_shape( const TypesafePtr & dims ) {
+      70           1 :   if( getPntrToArgument(0)->getRank()==0 ) { dims.set(long(1)); return; }
+      71           0 :   auto dims_=dims.get<long*>( getPntrToArgument(0)->getRank() );
+      72           0 :   for(unsigned j=0; j<getPntrToArgument(0)->getRank(); ++j) dims_[j] = getPntrToArgument(0)->getShape()[j];
+      73             : }
+      74             : 
+      75          65 : void ActionToGetData::set_memory( const TypesafePtr & val ) {
+      76          65 :   mydata->setValuePointer(val,getPntrToArgument(0)->getShape(),false);
+      77          65 : }
+      78             : 
+      79         670 : void ActionToGetData::calculate() {
+      80         670 :   plumed_assert( gtype==val ); mydata->setData( getPntrToArgument(0) );
+      81         670 : }
+      82             : 
+      83             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToGetData.h.func-sort-c.html b/coverage/core/ActionToGetData.h.func-sort-c.html new file mode 100644 index 000000000000..2cbfb23f5005 --- /dev/null +++ b/coverage/core/ActionToGetData.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToGetData.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToGetData.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToGetData21castToActionToGetDataEv0
_ZN4PLMD15ActionToGetData5applyEv660
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToGetData.h.func.html b/coverage/core/ActionToGetData.h.func.html new file mode 100644 index 000000000000..c3282be36939 --- /dev/null +++ b/coverage/core/ActionToGetData.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToGetData.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToGetData.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToGetData21castToActionToGetDataEv0
_ZN4PLMD15ActionToGetData5applyEv660
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToGetData.h.gcov.html b/coverage/core/ActionToGetData.h.gcov.html new file mode 100644 index 000000000000..f1862f22cd61 --- /dev/null +++ b/coverage/core/ActionToGetData.h.gcov.html @@ -0,0 +1,135 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToGetData.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToGetData.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionToGetData_h
+      23             : #define __PLUMED_core_ActionToGetData_h
+      24             : 
+      25             : #include "ActionWithArguments.h"
+      26             : #include "ActionPilot.h"
+      27             : #include "DataPassingObject.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : class ActionToGetData :
+      32             :   public ActionPilot,
+      33             :   public ActionWithArguments
+      34             : {
+      35             : private:
+      36             : /// What do you want to collect to pass back to python
+      37             :   enum {val,deriv,force} gtype;
+      38             : /// This holds the pointer that we are setting
+      39             :   std::unique_ptr<DataPassingObject> mydata;
+      40             : /// This temporarily holds the data so it can be passed out
+      41             :   std::vector<double> data;
+      42             : public:
+      43             :   static void registerKeywords(Keywords& keys);
+      44             :   explicit ActionToGetData(const ActionOptions&ao);
+      45             : /// Get the rank of the output
+      46             :   void get_rank( const TypesafePtr & rank );
+      47             : /// Get the shape of the output
+      48             :   void get_shape( const TypesafePtr & dims );
+      49             : /// Set the memory that holds the output
+      50             :   void set_memory( const TypesafePtr & val );
+      51             : /// Actually set the values for the output
+      52             :   void calculate();
+      53         660 :   void apply() {}
+      54           0 :   ActionToGetData* castToActionToGetData() noexcept final { return this; }
+      55             : };
+      56             : 
+      57             : }
+      58             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToPutData.cpp.func-sort-c.html b/coverage/core/ActionToPutData.cpp.func-sort-c.html new file mode 100644 index 000000000000..767b066f3c61 --- /dev/null +++ b/coverage/core/ActionToPutData.cpp.func-sort-c.html @@ -0,0 +1,141 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToPutData.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToPutData.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9510293.1 %
Date:2024-02-22 21:58:45Functions:1717100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15ActionToPutData26getNumberOfForcesToRescaleEv150
_ZN4PLMD15ActionToPutData13rescaleForcesERKd200
_ZN4PLMD15ActionToPutData10readBinaryERSi798
_ZN4PLMD15ActionToPutData11writeBinaryERSo798
_ZN4PLMD15ActionToPutDataC2ERKNS_13ActionOptionsE976
_ZNK4PLMD15ActionToPutData14getLocalValuesERSt6vectorIdSaIdEE1350
_ZN4PLMD15ActionToPutDataC1ERKNS_13ActionOptionsE5610
_ZN4PLMD15ActionToPutData16registerKeywordsERNS_8KeywordsE5612
_ZN4PLMD15ActionToPutData7setUnitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_6586
_ZN4PLMD15ActionToPutData11updateUnitsEPNS_16DataPassingToolsE6726
_ZNK4PLMD15ActionToPutData11getUnitNameB5cxx11Ev6726
_ZN4PLMD15ActionToPutData4waitEv52583
_ZN4PLMD15ActionToPutData5applyEv314128
_ZN4PLMD15ActionToPutData8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj324435
_ZN4PLMD15ActionToPutData9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj324435
_ZN4PLMD15ActionToPutData15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE731392
_ZN4PLMD15ActionToPutData15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1419399
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToPutData.cpp.func.html b/coverage/core/ActionToPutData.cpp.func.html new file mode 100644 index 000000000000..983c34bf55fc --- /dev/null +++ b/coverage/core/ActionToPutData.cpp.func.html @@ -0,0 +1,141 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToPutData.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToPutData.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9510293.1 %
Date:2024-02-22 21:58:45Functions:1717100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToPutData10readBinaryERSi798
_ZN4PLMD15ActionToPutData11updateUnitsEPNS_16DataPassingToolsE6726
_ZN4PLMD15ActionToPutData11writeBinaryERSo798
_ZN4PLMD15ActionToPutData13rescaleForcesERKd200
_ZN4PLMD15ActionToPutData15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE731392
_ZN4PLMD15ActionToPutData15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE1419399
_ZN4PLMD15ActionToPutData16registerKeywordsERNS_8KeywordsE5612
_ZN4PLMD15ActionToPutData4waitEv52583
_ZN4PLMD15ActionToPutData5applyEv314128
_ZN4PLMD15ActionToPutData7setUnitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_6586
_ZN4PLMD15ActionToPutData8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj324435
_ZN4PLMD15ActionToPutData9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj324435
_ZN4PLMD15ActionToPutDataC1ERKNS_13ActionOptionsE5610
_ZN4PLMD15ActionToPutDataC2ERKNS_13ActionOptionsE976
_ZNK4PLMD15ActionToPutData11getUnitNameB5cxx11Ev6726
_ZNK4PLMD15ActionToPutData14getLocalValuesERSt6vectorIdSaIdEE1350
_ZNK4PLMD15ActionToPutData26getNumberOfForcesToRescaleEv150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToPutData.cpp.gcov.html b/coverage/core/ActionToPutData.cpp.gcov.html new file mode 100644 index 000000000000..0afae1e2a94e --- /dev/null +++ b/coverage/core/ActionToPutData.cpp.gcov.html @@ -0,0 +1,258 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToPutData.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToPutData.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9510293.1 %
Date:2024-02-22 21:58:45Functions:1717100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionToPutData.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "PlumedMain.h"
+      25             : #include "ActionSet.h"
+      26             : 
+      27             : //+PLUMEDOC ANALYSIS PUT
+      28             : /*
+      29             : Pass data into PLUMED
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : namespace PLMD {
+      37             : 
+      38             : PLUMED_REGISTER_ACTION(ActionToPutData,"PUT")
+      39             : 
+      40        5612 : void ActionToPutData::registerKeywords(Keywords& keys) {
+      41        5612 :   ActionForInterface::registerKeywords( keys );
+      42       11224 :   keys.add("compulsory","SHAPE","0","the shape of the value that is being passed to PLUMED");
+      43       11224 :   keys.add("compulsory","UNIT","the unit of the quantity that is being passed to PLUMED through this value.  Can be either number, energy, time, length, mass or charge");
+      44       11224 :   keys.add("compulsory","FORCE_UNIT","default","the units to use for the force");
+      45       11224 :   keys.add("compulsory","PERIODIC","if the value being passed to plumed is periodic then you should specify the periodicity of the function.  If the value "
+      46             :            "is not periodic you must state this using PERIODIC=NO.  Positions are passed with PERIODIC=NO even though special methods are used "
+      47             :            "to deal with pbc");
+      48       11224 :   keys.addFlag("CONSTANT",false,"does this quantity not depend on time");
+      49       11224 :   keys.addFlag("FROM_DOMAINS",false,"is this quantity passed through the domain decomposition object");
+      50       11224 :   keys.addFlag("MUTABLE",false,"can plumed change the value of the pointer that is passed from the MD code");
+      51        5612 : }
+      52             : 
+      53        6586 : ActionToPutData::ActionToPutData(const ActionOptions&ao):
+      54             :   Action(ao),
+      55             :   ActionForInterface(ao),
+      56        6586 :   noforce(false),
+      57        6586 :   fixed(false),
+      58        6586 :   from_domains(false),
+      59        6586 :   resetable(false),
+      60        6586 :   dataCanBeSet(true),
+      61        6586 :   unit(n),
+      62        6586 :   mydata(DataPassingObject::create(plumed.getRealPrecision()))
+      63             : {
+      64       12196 :   if( getName()!="ENERGY" && getName()!="PBC" ) {
+      65       11220 :     std::vector<unsigned> shape; parseVector("SHAPE",shape);
+      66        5610 :     if( shape.size()==1 && shape[0]==0 ) { shape.resize(0); addValue( shape ); }
+      67        4680 :     else { addValue( shape ); }
+      68             : 
+      69        5610 :     std::string unitstr, funitstr; parse("UNIT",unitstr);
+      70       11220 :     parse("FORCE_UNIT",funitstr); setUnit( unitstr, funitstr );
+      71             : 
+      72             :     // Now sort out period
+      73       11220 :     std::vector<std::string> period; parseVector("PERIODIC",period);
+      74        5610 :     if( period.size()==1 ) {
+      75        5610 :       if( period[0]!="NO") error("input to PERIODIC keyword does not make sense");
+      76        5610 :       setNotPeriodic();
+      77           0 :     } else if( period.size()==2 ) setPeriodic( period[0], period[1] );
+      78           0 :     else  error("input to PERIODIC keyword does not make sense");
+      79             : 
+      80       11220 :     parseFlag("CONSTANT",fixed); if( fixed ) { noforce=true; copyOutput(0)->setConstant(); }
+      81       11220 :     parseFlag("FROM_DOMAINS",from_domains); parseFlag("MUTABLE",resetable);
+      82        5610 :   }
+      83        6586 : }
+      84             : 
+      85        6586 : void ActionToPutData::setUnit( const std::string& unitstr, const std::string& funitstr ) {
+      86        6586 :   if( unitstr=="number" ) unit=n;
+      87        6583 :   else if( unitstr=="energy" ) unit=e;
+      88        6484 :   else if( unitstr=="length" ) unit=l;
+      89        2740 :   else if( unitstr=="mass" ) unit=m;
+      90        1804 :   else if( unitstr=="charge" ) unit=q;
+      91         868 :   else if( unitstr=="time" ) unit=t;
+      92           0 :   else error( unitstr + " is not a valid input unit");
+      93             :   // Set the force units
+      94        6586 :   if( funitstr=="default" ) funit=d;
+      95         936 :   else if( funitstr=="energy" ) funit=eng;
+      96           0 :   else error( funitstr + " is not a valid input force unit");
+      97        6586 : }
+      98             : 
+      99        6726 : std::string ActionToPutData::getUnitName() const {
+     100        6726 :   if( unit==e ) return "energy";
+     101        6623 :   if( unit==l ) return "length";
+     102        2799 :   if( unit==m ) return "mass";
+     103        1843 :   if( unit==q ) return "charge";
+     104         887 :   if( unit==t ) return "time";
+     105           0 :   plumed_error();
+     106             : }
+     107             : 
+     108      324435 : void ActionToPutData::setStart( const std::string& name, const unsigned& sss) {
+     109      324435 :   plumed_assert( name==getLabel() ); mydata->setStart(sss);
+     110      324435 : }
+     111             : 
+     112      324435 : void ActionToPutData::setStride( const std::string& name, const unsigned& sss ) {
+     113      324435 :   plumed_assert( name==getLabel() ); mydata->setStride(sss);
+     114      324435 : }
+     115             : 
+     116        6726 : void ActionToPutData::updateUnits( DataPassingTools* passtools ) {
+     117             :   // Don't need to do anythign if this is just a number
+     118        6726 :   if( unit==n ) return ;
+     119             : 
+     120       13452 :   double vunits=passtools->getUnitConversion( getUnitName() );
+     121        6726 :   mydata->setUnit(vunits); if( fixed && wasset ) mydata->share_data( 0, getPntrToValue()->getNumberOfValues(), getPntrToValue() );
+     122        6726 :   if( funit==eng ) mydata->setForceUnit( 1/passtools->getUnitConversion("energy"));
+     123        5770 :   else if( funit==d ) mydata->setForceUnit(1/passtools->getUnitConversion("energy")*vunits);
+     124             : }
+     125             : 
+     126     1419399 : bool ActionToPutData::setValuePointer( const std::string& name, const TypesafePtr & val ) {
+     127     1419399 :   if( name!=getLabel() ) return false;
+     128      325373 :   wasset=true; plumed_massert( dataCanBeSet, "set " + getLabel() + " cannot be set at this time");
+     129      325364 :   if( !from_domains ) {
+     130       56550 :     if( !resetable && getPntrToComponent(0)->getRank()==0 ) {
+     131        4918 :       mydata->saveValueAsDouble( val );
+     132        4918 :       if( fixed ) mydata->share_data( 0, getPntrToValue()->getNumberOfValues(), getPntrToValue() );
+     133       51632 :     } else mydata->setValuePointer(val,getPntrToComponent(0)->getShape(), !resetable);
+     134      537628 :   } else mydata->setValuePointer(val,std::vector<unsigned>(), !resetable);
+     135             :   return true;
+     136             : }
+     137             : 
+     138      731392 : bool ActionToPutData::setForcePointer( const std::string& name, const TypesafePtr & val ) {
+     139      731392 :   if( name!=getLabel() ) return false;
+     140      213206 :   plumed_massert( dataCanBeSet, "force on " + getLabel() + " cannot be set at this time");
+     141      213206 :   if( !from_domains ) mydata->setForcePointer(val,getPntrToComponent(0)->getShape());
+     142      334464 :   else mydata->setForcePointer(val,std::vector<unsigned>());
+     143             :   return true;
+     144             : }
+     145             : 
+     146        1350 : void ActionToPutData::getLocalValues( std::vector<double>& vals ) const {
+     147        1350 :   mydata->share_data( vals );
+     148        1350 : }
+     149             : 
+     150       52583 : void ActionToPutData::wait() {
+     151       52583 :   dataCanBeSet=false; if( fixed || !wasset ) { return; } plumed_assert( wasset );
+     152       52583 :   mydata->share_data( 0, getPntrToValue()->getNumberOfValues(), getPntrToValue() );
+     153             : }
+     154             : 
+     155      314128 : void ActionToPutData::apply() {
+     156      314128 :   if( getPntrToValue()->forcesWereAdded() && !noforce ) {
+     157       98352 :     if( getName()=="ENERGY" || getDependencies().size()==0 ) mydata->add_force( getPntrToValue() );
+     158             :   }
+     159      314128 : }
+     160             : 
+     161         150 : unsigned ActionToPutData::getNumberOfForcesToRescale() const {
+     162         150 :   if( getName()!="ENERGY" || getDependencies().size()>0 ) return copyOutput(0)->getNumberOfValues();
+     163           0 :   plumed_assert( getDependencies().size()==1 ); ActionForInterface* ai = getDependencies()[0]->castToActionForInterface();
+     164           0 :   return ai->getNumberOfForcesToRescale();
+     165             : }
+     166             : 
+     167         200 : void ActionToPutData::rescaleForces( const double& alpha ) {
+     168         200 :   if( noforce ) return; wasscaled=true;
+     169         150 :   mydata->rescale_force( getNumberOfForcesToRescale(), alpha, getPntrToValue() );
+     170             : 
+     171             : }
+     172             : 
+     173         798 : void ActionToPutData::writeBinary(std::ostream&o) {
+     174         798 :   if(!fixed) getPntrToValue()->writeBinary(o);
+     175         798 : }
+     176             : 
+     177         798 : void ActionToPutData::readBinary(std::istream&i) {
+     178         798 :   if(!fixed) getPntrToValue()->readBinary(i);
+     179         798 : }
+     180             : 
+     181             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToPutData.h.func-sort-c.html b/coverage/core/ActionToPutData.h.func-sort-c.html new file mode 100644 index 000000000000..653db5fbf33e --- /dev/null +++ b/coverage/core/ActionToPutData.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToPutData.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToPutData.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToPutData8Set_commERNS_12CommunicatorE1
_ZN4PLMD15ActionToPutData8shareAllEv228
_ZNK4PLMD15ActionToPutData6onStepEv3356
_ZN4PLMD15ActionToPutData21castToActionToPutDataEv211257
_ZN4PLMD15ActionToPutData5shareEv593089
_ZN4PLMD15ActionToPutData17resetForStepStartEv604336
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToPutData.h.func.html b/coverage/core/ActionToPutData.h.func.html new file mode 100644 index 000000000000..5ef4e3834042 --- /dev/null +++ b/coverage/core/ActionToPutData.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToPutData.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToPutData.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionToPutData17resetForStepStartEv604336
_ZN4PLMD15ActionToPutData21castToActionToPutDataEv211257
_ZN4PLMD15ActionToPutData5shareEv593089
_ZN4PLMD15ActionToPutData8Set_commERNS_12CommunicatorE1
_ZN4PLMD15ActionToPutData8shareAllEv228
_ZNK4PLMD15ActionToPutData6onStepEv3356
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionToPutData.h.gcov.html b/coverage/core/ActionToPutData.h.gcov.html new file mode 100644 index 000000000000..66a53a528192 --- /dev/null +++ b/coverage/core/ActionToPutData.h.gcov.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionToPutData.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionToPutData.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionToPutData_h
+      23             : #define __PLUMED_core_ActionToPutData_h
+      24             : 
+      25             : #include "ActionForInterface.h"
+      26             : #include "DataPassingObject.h"
+      27             : #include "tools/Units.h"
+      28             : #include "DataPassingTools.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : class ActionToPutData :
+      33             :   public ActionForInterface
+      34             : {
+      35             :   friend class PlumedMain;
+      36             :   friend class TimeStep;
+      37             :   friend class DomainDecomposition;
+      38             : private:
+      39             : /// Are we not applying forces on this values
+      40             :   bool noforce;
+      41             : /// Is this quantity fixed
+      42             :   bool fixed;
+      43             : /// Is this quantity passed from the domains
+      44             :   bool from_domains;
+      45             : /// Is PLUMED allowed to change the value of this pointer
+      46             :   bool resetable;
+      47             : /// Are we allowed to set data at this time
+      48             :   bool dataCanBeSet;
+      49             : /// The unit of the value that has been passed to plumed
+      50             :   enum {n,e,l,m,q,t} unit;
+      51             : /// The unit to to use for the force
+      52             :   enum {d,eng} funit;
+      53             : /// This holds the pointer that we getting data from
+      54             :   std::unique_ptr<DataPassingObject> mydata;
+      55             : /// Convert the enum contaning the unit into the name of the unit
+      56             :   std::string getUnitName() const ;
+      57             : protected:
+      58             : /// Setup the units of the input value
+      59             :   void setUnit( const std::string& unitstr, const std::string& funitstr );
+      60             : public:
+      61             :   static void registerKeywords(Keywords& keys);
+      62             :   explicit ActionToPutData(const ActionOptions&ao);
+      63             : /// Set the start point for the memory if needed
+      64             :   void setStart( const std::string& name, const unsigned& sss) override;
+      65             : /// This resets the stride in the collection object
+      66             :   void setStride( const std::string& name, const unsigned& sss ) override;
+      67             : /// Update the units on the input data
+      68             :   void updateUnits( DataPassingTools* passtools );
+      69             : /// This is called at the start of the step
+      70      604336 :   void resetForStepStart() override { dataCanBeSet = true; }
+      71             : /// These are the actions that set the pointers to the approrpiate values
+      72             :   virtual bool setValuePointer( const std::string& name, const TypesafePtr & val ) override ;
+      73             :   bool setForcePointer( const std::string& name, const TypesafePtr & val ) override ;
+      74             : ///
+      75           1 :   void Set_comm(Communicator& comm) override {}
+      76             : /// And this gets the number of forces that need to be rescaled
+      77             :   unsigned getNumberOfForcesToRescale() const override ;
+      78             : /// Share the data
+      79      593089 :   void share() override {}
+      80         228 :   void shareAll() override {}
+      81             : ///
+      82             :   void getLocalValues( std::vector<double>& vals ) const ;
+      83             : /// Get the data to share
+      84             :   virtual void wait() override ;
+      85             : /// Actually set the values for the output
+      86             :   virtual void apply() override ;
+      87             :   void rescaleForces( const double& alpha );
+      88             : /// For replica exchange
+      89             :   void writeBinary(std::ostream&o) override;
+      90             :   virtual void readBinary(std::istream&i) override;
+      91        3356 :   bool onStep() const override { return false; }
+      92      211257 :   ActionToPutData* castToActionToPutData() noexcept final { return this; }
+      93             : };
+      94             : 
+      95             : }
+      96             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.cpp.func-sort-c.html b/coverage/core/ActionWithArguments.cpp.func-sort-c.html new file mode 100644 index 000000000000..6302a9f8b87c --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithArguments.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithArguments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15117884.8 %
Date:2024-02-22 21:58:45Functions:131492.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArgumentsC1ERKNS_13ActionOptionsE0
_ZN4PLMD19ActionWithArguments24requestExtraDependenciesERKSt6vectorIPNS_5ValueESaIS3_EE4
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIPNS_5ValueESaISB_EE53
_ZN4PLMD19ActionWithArguments29calculateNumericalDerivativesEPNS_15ActionWithValueE58
_ZNK4PLMD19ActionWithArguments12setGradientsEPNS_5ValueERj83
_ZNK4PLMD19ActionWithArguments13getProjectionEjj261
_ZN4PLMD19ActionWithArguments21expandArgKeywordInPDBERKNS_3PDBE416
_ZN4PLMD19ActionWithArgumentsC2ERKNS_13ActionOptionsE2948
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISB_EE2988
_ZN4PLMD19ActionWithArguments21interpretArgumentListERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_IPNS_5ValueESaISD_EE3096
_ZN4PLMD19ActionWithArguments16registerKeywordsERNS_8KeywordsE3149
_ZN4PLMD19ActionWithArguments23calculateConstantValuesERKb8429
_ZN4PLMD19ActionWithArguments20addForcesOnArgumentsERKjRKSt6vectorIdSaIdEERj27002
_ZN4PLMD19ActionWithArguments16requestArgumentsERKSt6vectorIPNS_5ValueESaIS3_EE179064
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.cpp.func.html b/coverage/core/ActionWithArguments.cpp.func.html new file mode 100644 index 000000000000..cdf4c0a99e64 --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithArguments.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithArguments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15117884.8 %
Date:2024-02-22 21:58:45Functions:131492.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArguments16registerKeywordsERNS_8KeywordsE3149
_ZN4PLMD19ActionWithArguments16requestArgumentsERKSt6vectorIPNS_5ValueESaIS3_EE179064
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISB_EE2988
_ZN4PLMD19ActionWithArguments17parseArgumentListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiRSt6vectorIPNS_5ValueESaISB_EE53
_ZN4PLMD19ActionWithArguments20addForcesOnArgumentsERKjRKSt6vectorIdSaIdEERj27002
_ZN4PLMD19ActionWithArguments21expandArgKeywordInPDBERKNS_3PDBE416
_ZN4PLMD19ActionWithArguments21interpretArgumentListERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERS1_IPNS_5ValueESaISD_EE3096
_ZN4PLMD19ActionWithArguments23calculateConstantValuesERKb8429
_ZN4PLMD19ActionWithArguments24requestExtraDependenciesERKSt6vectorIPNS_5ValueESaIS3_EE4
_ZN4PLMD19ActionWithArguments29calculateNumericalDerivativesEPNS_15ActionWithValueE58
_ZN4PLMD19ActionWithArgumentsC1ERKNS_13ActionOptionsE0
_ZN4PLMD19ActionWithArgumentsC2ERKNS_13ActionOptionsE2948
_ZNK4PLMD19ActionWithArguments12setGradientsEPNS_5ValueERj83
_ZNK4PLMD19ActionWithArguments13getProjectionEjj261
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.cpp.gcov.html b/coverage/core/ActionWithArguments.cpp.gcov.html new file mode 100644 index 000000000000..0d8668dc77d4 --- /dev/null +++ b/coverage/core/ActionWithArguments.cpp.gcov.html @@ -0,0 +1,400 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithArguments.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithArguments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15117884.8 %
Date:2024-02-22 21:58:45Functions:131492.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithArguments.h"
+      23             : #include "ActionWithValue.h"
+      24             : #include "ActionAtomistic.h"
+      25             : #include "ActionForInterface.h"
+      26             : #include "ActionWithVirtualAtom.h"
+      27             : #include "tools/PDB.h"
+      28             : #include "PlumedMain.h"
+      29             : #include "ActionSet.h"
+      30             : #include <iostream>
+      31             : #include <regex>
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35        3149 : void ActionWithArguments::registerKeywords(Keywords& keys) {
+      36        6298 :   keys.reserve("numbered","ARG","the input for this action is the scalar output from one or more other actions. The particular scalars that you will use "
+      37             :                "are referenced using the label of the action. If the label appears on its own then it is assumed that the Action calculates "
+      38             :                "a single scalar value.  The value of this scalar is thus used as the input to this new action.  If * or *.* appears the "
+      39             :                "scalars calculated by all the proceeding actions in the input file are taken.  Some actions have multi-component outputs and "
+      40             :                "each component of the output has a specific label.  For example a \\ref DISTANCE action labelled dist may have three components "
+      41             :                "x, y and z.  To take just the x component you should use dist.x, if you wish to take all three components then use dist.*."
+      42             :                "More information on the referencing of Actions can be found in the section of the manual on the PLUMED \\ref Syntax.  "
+      43             :                "Scalar values can also be "
+      44             :                "referenced using POSIX regular expressions as detailed in the section on \\ref Regex. To use this feature you you must compile "
+      45             :                "PLUMED with the appropriate flag.");
+      46        3149 : }
+      47             : 
+      48        2988 : void ActionWithArguments::parseArgumentList(const std::string&key,std::vector<Value*>&arg) {
+      49        2988 :   std::string def; std::vector<std::string> c; arg.clear(); parseVector(key,c);
+      50        3482 :   if( c.size()==0 && (keywords.style(key,"compulsory") || keywords.style(key,"hidden")) ) {
+      51           0 :     if( keywords.getDefaultValue(key,def) ) c.push_back( def );
+      52             :     else return;
+      53             :   }
+      54        2988 :   interpretArgumentList(c,arg);
+      55        2988 : }
+      56             : 
+      57          53 : bool ActionWithArguments::parseArgumentList(const std::string&key,int i,std::vector<Value*>&arg) {
+      58             :   std::vector<std::string> c;
+      59             :   arg.clear();
+      60          53 :   if(parseNumberedVector(key,i,c)) {
+      61          12 :     interpretArgumentList(c,arg);
+      62             :     return true;
+      63             :   } else return false;
+      64          53 : }
+      65             : 
+      66        3096 : void ActionWithArguments::interpretArgumentList(const std::vector<std::string>& c, std::vector<Value*>&arg) {
+      67        8658 :   for(unsigned i=0; i<c.size(); i++) {
+      68             :     // is a regex? then just interpret it. The signal is ()
+      69        5565 :     if(!c[i].compare(0,1,"(")) {
+      70         213 :       unsigned l=c[i].length();
+      71         213 :       if(!c[i].compare(l-1,1,")")) {
+      72             :         // start regex parsing
+      73             :         bool found_something=false;
+      74             :         // take the string enclosed in quotes and put in round brackets
+      75         212 :         std::string myregex=c[i];
+      76         212 :         std::vector<ActionWithValue*> all=plumed.getActionSet().select<ActionWithValue*>();
+      77         213 :         if( all.empty() ) error("your input file is not telling plumed to calculate anything");
+      78             : 
+      79             :         try {
+      80         212 :           std::regex txt_regex(myregex,std::regex::extended);
+      81         211 :           plumed_massert(txt_regex.mark_count()==1,"I can parse with only one subexpression");
+      82       24154 :           for(unsigned j=0; j<all.size(); j++) {
+      83       23943 :             std::vector<std::string> ss=all[j]->getComponentsVector();
+      84      349443 :             for(unsigned  k=0; k<ss.size(); ++k) {
+      85      325500 :               if(std::regex_match(ss[k],txt_regex)) {
+      86       21549 :                 arg.push_back(all[j]->copyOutput(ss[k]));
+      87             :                 found_something=true;
+      88             :               }
+      89             :             }
+      90       23943 :           }
+      91         212 :         } catch(std::regex_error & e) {
+      92           3 :           plumed_error()<<"Error parsing regular expression: "<<e.what();
+      93           1 :         }
+      94         211 :         if(!found_something) plumed_error()<<"There isn't any action matching your regex " << myregex;
+      95             :       } else {
+      96           2 :         plumed_merror("did you want to use regexp to input arguments? enclose it between two round braces (...) with no spaces!");
+      97             :       }
+      98             :     } else {
+      99             :       std::size_t dot=c[i].find_first_of('.');
+     100        5352 :       std::string a=c[i].substr(0,dot);
+     101        5352 :       std::string name=c[i].substr(dot+1);
+     102        5352 :       if(c[i].find(".")!=std::string::npos) {   // if it contains a dot:
+     103        1882 :         if(a=="*" && name=="*") {
+     104             :           // Take all values from all actions
+     105           1 :           std::vector<ActionWithValue*> all=plumed.getActionSet().select<ActionWithValue*>();
+     106           1 :           if( all.empty() ) error("your input file is not telling plumed to calculate anything");
+     107          17 :           for(unsigned j=0; j<all.size(); j++) {
+     108          16 :             ActionForInterface* ap=all[j]->castToActionForInterface(); if( ap ) continue;
+     109          18 :             for(int k=0; k<all[j]->getNumberOfComponents(); ++k) arg.push_back(all[j]->copyOutput(k));
+     110             :           }
+     111        1872 :         } else if ( name=="*") {
+     112             :           // Take all the values from an action with a specific name
+     113         532 :           ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(a);
+     114         532 :           if(!action) {
+     115           0 :             std::string str=" (hint! the actions with value in this ActionSet are: ";
+     116           0 :             str+=plumed.getActionSet().getLabelList<ActionWithValue*>()+")";
+     117           0 :             error("cannot find action named " + a + str);
+     118             :           }
+     119         532 :           if( action->getNumberOfComponents()==0 ) error("found " + a +".* indicating use all components calculated by action with label " + a + " but this action has no components");
+     120        5592 :           for(int k=0; k<action->getNumberOfComponents(); ++k) arg.push_back(action->copyOutput(k));
+     121        1340 :         } else if ( a=="*" ) {
+     122             :           // Take components from all actions with a specific name
+     123           8 :           std::vector<ActionWithValue*> all=plumed.getActionSet().select<ActionWithValue*>();
+     124           8 :           if( all.empty() ) error("your input file is not telling plumed to calculate anything");
+     125             :           unsigned nval=0;
+     126          97 :           for(unsigned j=0; j<all.size(); j++) {
+     127         178 :             std::string flab; flab=all[j]->getLabel() + "." + name;
+     128          89 :             if( all[j]->exists(flab) ) { arg.push_back(all[j]->copyOutput(flab)); nval++; }
+     129             :           }
+     130           8 :           if(nval==0) error("found no actions with a component called " + name );
+     131             :         } else {
+     132             :           // Take values with a specific name
+     133        1332 :           ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(a);
+     134        1332 :           if(!action) {
+     135           0 :             std::string str=" (hint! the actions with value in this ActionSet are: ";
+     136           0 :             str+=plumed.getActionSet().getLabelList<ActionWithValue*>()+")";
+     137           0 :             error("cannot find action named " + a +str);
+     138             :           }
+     139        1332 :           if( !(action->exists(c[i])) ) {
+     140           0 :             std::string str=" (hint! the components in this actions are: ";
+     141           0 :             str+=action->getComponentsList()+")";
+     142           0 :             error("action " + a + " has no component named " + name + str);
+     143             :           } ;
+     144        1332 :           arg.push_back(action->copyOutput(c[i]));
+     145             :         }
+     146             :       } else {    // if it doesn't contain a dot
+     147        3479 :         if(c[i]=="*") {
+     148             :           // Take all values from all actions
+     149         104 :           std::vector<ActionWithValue*> all=plumed.getActionSet().select<ActionWithValue*>();
+     150         104 :           if( all.empty() ) error("your input file is not telling plumed to calculate anything");
+     151        1567 :           for(unsigned j=0; j<all.size(); j++) {
+     152        1463 :             ActionWithVirtualAtom* av=all[j]->castToActionWithVirtualAtom(); if( av ) continue;
+     153        1406 :             ActionForInterface* ap=all[j]->castToActionForInterface(); if( ap && all[j]->getName()!="ENERGY" ) continue;
+     154        1281 :             for(int k=0; k<all[j]->getNumberOfComponents(); ++k) arg.push_back(all[j]->copyOutput(k));
+     155             :           }
+     156             :         } else {
+     157        3375 :           ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(c[i]);
+     158        3375 :           if(!action) {
+     159           1 :             std::string str=" (hint! the actions with value in this ActionSet are: ";
+     160           2 :             str+=plumed.getActionSet().getLabelList<ActionWithValue*>()+")";
+     161           3 :             error("cannot find action named " + c[i] + str );
+     162             :           }
+     163        3374 :           if( !(action->exists(c[i])) ) {
+     164           0 :             std::string str=" (hint! the components in this actions are: ";
+     165           0 :             str+=action->getComponentsList()+")";
+     166           0 :             error("action " + c[i] + " has no component named " + c[i] +str);
+     167             :           };
+     168        3375 :           arg.push_back(action->copyOutput(c[i]));
+     169             :         }
+     170             :       }
+     171             :     }
+     172             :   }
+     173        3093 : }
+     174             : 
+     175         416 : void ActionWithArguments::expandArgKeywordInPDB( const PDB& pdb ) {
+     176         416 :   std::vector<std::string> arg_names = pdb.getArgumentNames();
+     177         416 :   if( arg_names.size()>0 ) {
+     178             :     std::vector<Value*> arg_vals;
+     179          80 :     interpretArgumentList( arg_names, arg_vals );
+     180             :   }
+     181         416 : }
+     182             : 
+     183      179064 : void ActionWithArguments::requestArguments(const std::vector<Value*> &arg) {
+     184      179064 :   plumed_massert(!lockRequestArguments,"requested argument list can only be changed in the prepare() method");
+     185      179064 :   arguments=arg;
+     186      179064 :   clearDependencies();
+     187             :   std::string fullname;
+     188             :   std::string name;
+     189     1255645 :   for(unsigned i=0; i<arguments.size(); i++) {
+     190     1076581 :     fullname=arguments[i]->getName();
+     191     1076581 :     if(fullname.find(".")!=std::string::npos) {
+     192             :       std::size_t dot=fullname.find_first_of('.');
+     193      739076 :       name=fullname.substr(0,dot);
+     194             :     } else {
+     195             :       name=fullname;
+     196             :     }
+     197     1076581 :     ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(name);
+     198     1076581 :     plumed_massert(action,"cannot find action named (in requestArguments - this is weird)" + name);
+     199     1076581 :     addDependency(action);
+     200             :   }
+     201      179064 : }
+     202             : 
+     203           4 : void ActionWithArguments::requestExtraDependencies(const std::vector<Value*> &extra) {
+     204           4 :   plumed_massert(!lockRequestArguments,"requested argument list can only be changed in the prepare() method");
+     205             :   std::string fullname;
+     206             :   std::string name;
+     207           9 :   for(unsigned i=0; i<extra.size(); i++) {
+     208           5 :     fullname=extra[i]->getName();
+     209           5 :     if(fullname.find(".")!=std::string::npos) {
+     210             :       std::size_t dot=fullname.find_first_of('.');
+     211           0 :       name=fullname.substr(0,dot);
+     212             :     } else {
+     213             :       name=fullname;
+     214             :     }
+     215           5 :     ActionWithValue* action=plumed.getActionSet().selectWithLabel<ActionWithValue*>(name);
+     216           5 :     plumed_massert(action,"cannot find action named (in requestArguments - this is weird)" + name);
+     217           5 :     addDependency(action);
+     218             :   }
+     219           4 : }
+     220             : 
+     221        2948 : ActionWithArguments::ActionWithArguments(const ActionOptions&ao):
+     222             :   Action(ao),
+     223        2948 :   lockRequestArguments(false)
+     224             : {
+     225        5899 :   if( keywords.exists("ARG") ) {
+     226             :     std::vector<Value*> arg;
+     227        5710 :     parseArgumentList("ARG",arg);
+     228             : 
+     229        2852 :     if(!arg.empty()) {
+     230        2705 :       log.printf("  with arguments");
+     231       26266 :       for(unsigned i=0; i<arg.size(); i++) log.printf(" %s",arg[i]->getName().c_str());
+     232        2705 :       log.printf("\n");
+     233             :     }
+     234        2852 :     requestArguments(arg);
+     235             :   }
+     236        2945 : }
+     237             : 
+     238          58 : void ActionWithArguments::calculateNumericalDerivatives( ActionWithValue* a ) {
+     239          58 :   if(!a) {
+     240          58 :     a=castToActionWithValue();
+     241          58 :     plumed_massert(a,"cannot compute numerical derivatives for an action without values");
+     242             :   }
+     243             : 
+     244          58 :   const size_t nval=a->getNumberOfComponents();
+     245             :   const size_t npar=arguments.size();
+     246          58 :   std::vector<double> value (nval*npar);
+     247         161 :   for(int i=0; i<npar; i++) {
+     248         103 :     double arg0=arguments[i]->get();
+     249             :     arguments[i]->set(arg0+std::sqrt(epsilon));
+     250         103 :     a->calculate();
+     251         103 :     arguments[i]->set(arg0);
+     252        1367 :     for(int j=0; j<nval; j++) {
+     253        1264 :       value[i*nval+j]=a->getOutputQuantity(j);
+     254             :     }
+     255             :   }
+     256          58 :   a->calculate();
+     257          58 :   a->clearDerivatives();
+     258        1192 :   for(int j=0; j<nval; j++) {
+     259        1134 :     Value* v=a->copyOutput(j);
+     260        1804 :     if( v->hasDerivatives() ) for(int i=0; i<npar; i++) v->addDerivative(i,(value[i*nval+j]-a->getOutputQuantity(j))/std::sqrt(epsilon));
+     261             :   }
+     262          58 : }
+     263             : 
+     264         261 : double ActionWithArguments::getProjection(unsigned i,unsigned j)const {
+     265         261 :   plumed_massert(i<arguments.size()," making projections with an index which  is too large");
+     266         261 :   plumed_massert(j<arguments.size()," making projections with an index which  is too large");
+     267         261 :   const Value* v1=arguments[i];
+     268         261 :   const Value* v2=arguments[j];
+     269         261 :   return Value::projection(*v1,*v2);
+     270             : }
+     271             : 
+     272       27002 : void ActionWithArguments::addForcesOnArguments( const unsigned& argstart, const std::vector<double>& forces, unsigned& ind  ) {
+     273       66416 :   for(unsigned i=0; i<arguments.size(); ++i) { arguments[i]->addForce( forces[i] ); ind++; }
+     274       27002 : }
+     275             : 
+     276          83 : void ActionWithArguments::setGradients( Value* myval, unsigned& start ) const {
+     277          83 :   if( !myval->hasDeriv ) return; plumed_assert( myval->getRank()==0 );
+     278             : 
+     279             :   bool scalar=true;
+     280         249 :   for(unsigned i=0; i<arguments.size(); ++i ) {
+     281         166 :     if( arguments[i]->getRank()!=0 ) { scalar=false; break; }
+     282             :   }
+     283          83 :   if( !scalar ) {
+     284             :     bool constant=true;
+     285           0 :     for(unsigned i=0; i<arguments.size(); ++i ) {
+     286           0 :       if( !arguments[i]->isConstant() ) { constant=false; break; }
+     287           0 :       else start += arguments[i]->getNumberOfValues();
+     288             :     }
+     289           0 :     if( !constant ) error("cannot set gradient as unable to handle non-constant actions that take vectors/matrices/grids in input");
+     290             :   }
+     291             :   // Now pass the gradients
+     292         249 :   for(unsigned i=0; i<arguments.size(); ++i ) arguments[i]->passGradients( myval->getDerivative(i), myval->gradients );
+     293             : }
+     294             : 
+     295        8429 : bool ActionWithArguments::calculateConstantValues( const bool& haveatoms ) {
+     296        8429 :   ActionWithValue* av = castToActionWithValue();
+     297        8429 :   if( !av || arguments.size()==0 ) return false;
+     298             :   bool constant = true, atoms=false;
+     299        4351 :   for(unsigned i=0; i<arguments.size(); ++i) {
+     300        4351 :     ActionAtomistic* aa=arguments[i]->getPntrToAction()->castToActionAtomistic();
+     301        4351 :     if( aa ) { atoms=true; }
+     302        4351 :     if( !arguments[i]->isConstant() ) { constant=false; break; }
+     303             :   }
+     304        4351 :   if( constant ) {
+     305             :     // Set everything constant first as we need to set the shape
+     306           0 :     for(unsigned i=0; i<av->getNumberOfComponents(); ++i) (av->copyOutput(i))->setConstant();
+     307           0 :     if( !haveatoms ) log.printf("  values stored by this action are computed during startup and stay fixed during the simulation\n");
+     308           0 :     if( atoms ) return haveatoms;
+     309             :   }
+     310             :   // Now do the calculation and store the values if we don't need anything from the atoms
+     311        4351 :   if( constant && !haveatoms ) {
+     312           0 :     plumed_assert( !atoms ); activate(); calculate(); deactivate();
+     313           0 :     for(unsigned i=0; i<av->getNumberOfComponents(); ++i) {
+     314           0 :       unsigned nv = av->copyOutput(i)->getNumberOfValues();
+     315           0 :       log.printf("  %d values stored in component labelled %s are : ", nv, (av->copyOutput(i))->getName().c_str() );
+     316           0 :       for(unsigned j=0; j<nv; ++j) log.printf(" %f", (av->copyOutput(i))->get(j) );
+     317           0 :       log.printf("\n");
+     318             :     }
+     319             :   }
+     320             :   return constant;
+     321             : }
+     322             : 
+     323             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.h.func-sort-c.html b/coverage/core/ActionWithArguments.h.func-sort-c.html new file mode 100644 index 000000000000..e7e0270332a4 --- /dev/null +++ b/coverage/core/ActionWithArguments.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithArguments.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithArguments.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArgumentsD2Ev2945
_ZN4PLMD19ActionWithArguments25castToActionWithArgumentsEv8512
_ZNK4PLMD19ActionWithArguments12getArgumentsEv458116
_ZN4PLMD19ActionWithArguments12lockRequestsEv539016
_ZN4PLMD19ActionWithArguments14unlockRequestsEv539016
_ZNK4PLMD19ActionWithArguments20getNumberOfArgumentsEv4121366806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.h.func.html b/coverage/core/ActionWithArguments.h.func.html new file mode 100644 index 000000000000..e9181fec7489 --- /dev/null +++ b/coverage/core/ActionWithArguments.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithArguments.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithArguments.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19ActionWithArguments12lockRequestsEv539016
_ZN4PLMD19ActionWithArguments14unlockRequestsEv539016
_ZN4PLMD19ActionWithArguments25castToActionWithArgumentsEv8512
_ZN4PLMD19ActionWithArgumentsD2Ev2945
_ZNK4PLMD19ActionWithArguments12getArgumentsEv458116
_ZNK4PLMD19ActionWithArguments20getNumberOfArgumentsEv4121366806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithArguments.h.gcov.html b/coverage/core/ActionWithArguments.h.gcov.html new file mode 100644 index 000000000000..cfc6900f4b1d --- /dev/null +++ b/coverage/core/ActionWithArguments.h.gcov.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithArguments.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithArguments.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionWithArguments_h
+      23             : #define __PLUMED_core_ActionWithArguments_h
+      24             : 
+      25             : #include "Action.h"
+      26             : #include "Value.h"
+      27             : #include <vector>
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : /**
+      32             : \ingroup MULTIINHERIT
+      33             : This is used to create PLMD::Action objects that take the output from some other Action as input.
+      34             : This is used in PLMD::Function and PLMD::Bias
+      35             :  PLMD::Action objects that inherit from PLMD::ActionWithArguments take
+      36             :  values and components calculated in other PLMD::Action objects and
+      37             :  use this information to calculate some new function.  If you have
+      38             :  only one list of arguments you should use the reserved keyword <b> ARG </b>
+      39             :  when you use parseArgumentList.
+      40             : */
+      41             : 
+      42             : class ActionWithArguments:
+      43             :   public virtual Action
+      44             : {
+      45             :   std::vector<Value*> arguments;
+      46             :   bool lockRequestArguments;
+      47             : protected:
+      48             : /// This changes the arg keyword in the pdb file
+      49             :   void expandArgKeywordInPDB( const PDB& pdb );
+      50             : public:
+      51             : /// Get the scalar product between the gradients of two variables
+      52             :   double getProjection(unsigned i,unsigned j)const;
+      53             : /// Registers the list of keywords
+      54             :   static void registerKeywords( Keywords& keys );
+      55             : /// Returns the value of an argument
+      56             :   double getArgument( const unsigned n ) const;
+      57             : /// Return a pointer to specific argument
+      58             :   Value* getPntrToArgument( const unsigned n );
+      59             : /// Returns the number of arguments
+      60             :   virtual unsigned getNumberOfArguments() const ;
+      61             : /// Takes the difference taking into account pbc for arg i
+      62             :   double difference(int, double, double) const;
+      63             : /// Takes one value and brings it back into the pbc of argument i
+      64             :   double bringBackInPbc(int i,double d1)const;
+      65             : /// Parse a list of arguments
+      66             :   void parseArgumentList(const std::string&key,std::vector<Value*>&args);
+      67             : /// Parse a numbered list of arguments
+      68             :   bool parseArgumentList(const std::string&key,int i,std::vector<Value*>&args);
+      69             : /// Setup the dependencies
+      70             :   void requestArguments(const std::vector<Value*> &arg);
+      71             :   void requestExtraDependencies(const std::vector<Value*> &extra);
+      72             : /// Add forces to arguments (used in apply)
+      73             :   void addForcesOnArguments( const unsigned& argstart, const std::vector<double>& forces, unsigned& ind );
+      74             : public:
+      75             :   explicit ActionWithArguments(const ActionOptions&);
+      76        2945 :   virtual ~ActionWithArguments() {}
+      77             : /// Calculate the numerical derivatives
+      78             : /// N.B. only pass an ActionWithValue to this routine if you know exactly what you
+      79             : /// are doing.  The default will be correct for the vast majority of cases
+      80             :   void calculateNumericalDerivatives( ActionWithValue* a=NULL ) override;
+      81             :   void lockRequests() override;
+      82             :   void unlockRequests() override;
+      83             : /// Returns an array of pointers to the arguments
+      84             :   virtual const std::vector<Value*>    & getArguments() const ;
+      85             : /// Convert a list of argument names into a list of pointers to the values
+      86             :   void interpretArgumentList(const std::vector<std::string>& c, std::vector<Value*>&arg);
+      87             : /// Used to calculate constant values in startup
+      88             :   bool calculateConstantValues( const bool& have_atoms );
+      89             : /// Get the gradient for this action
+      90             :   void setGradients( Value* myval, unsigned& start ) const ;
+      91        8512 :   ActionWithArguments* castToActionWithArguments() noexcept final { return this; }
+      92             : };
+      93             : 
+      94             : 
+      95             : inline
+      96             : Value* ActionWithArguments::getPntrToArgument( const unsigned n ) {
+      97     4570938 :   return arguments[n];
+      98             : }
+      99             : 
+     100             : inline
+     101             : double ActionWithArguments::getArgument(const unsigned n) const {
+     102      824278 :   return arguments[n]->get();
+     103             : }
+     104             : 
+     105             : inline
+     106  4121366806 : unsigned ActionWithArguments::getNumberOfArguments()const {
+     107  4121385319 :   return arguments.size();
+     108             : }
+     109             : 
+     110             : inline
+     111             : double ActionWithArguments::difference(int i,double d1,double d2)const {
+     112     4855279 :   return arguments[i]->difference(d1,d2);
+     113             : }
+     114             : 
+     115             : inline
+     116             : double ActionWithArguments::bringBackInPbc(int i,double d1)const {
+     117        1427 :   return arguments[i]->bringBackInPbc(d1);
+     118             : }
+     119             : 
+     120             : inline
+     121      539016 : void ActionWithArguments::lockRequests() {
+     122      553607 :   lockRequestArguments=true;
+     123      539016 : }
+     124             : 
+     125             : inline
+     126      539016 : void ActionWithArguments::unlockRequests() {
+     127      553607 :   lockRequestArguments=false;
+     128      539016 : }
+     129             : 
+     130             : inline
+     131      458116 : const std::vector<Value*> & ActionWithArguments::getArguments() const {
+     132      461930 :   return arguments;
+     133             : }
+     134             : 
+     135             : }
+     136             : 
+     137             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.cpp.func-sort-c.html b/coverage/core/ActionWithValue.cpp.func-sort-c.html new file mode 100644 index 000000000000..824be531bd2c --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.func-sort-c.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithValue.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13214591.0 %
Date:2024-02-22 21:58:45Functions:253083.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue23noAnalyticalDerivativesERNS_8KeywordsE0
_ZN4PLMD15ActionWithValueC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionWithValueD0Ev0
_ZN4PLMD15ActionWithValueD1Ev0
_ZNK4PLMD15ActionWithValue17getComponentsListB5cxx11Ev0
_ZN4PLMD15ActionWithValue19componentIsPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_92
_ZN4PLMD15ActionWithValue25useCustomisableComponentsERNS_8KeywordsE256
_ZN4PLMD15ActionWithValue11setPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_677
_ZN4PLMD15ActionWithValue24componentsAreNotOptionalERNS_8KeywordsE1304
_ZN4PLMD15ActionWithValue23addValueWithDerivativesERKSt6vectorIjSaIjEE2300
_ZN4PLMD15ActionWithValue8addValueERKSt6vectorIjSaIjEE6642
_ZN4PLMD15ActionWithValue14setNotPeriodicEv8265
_ZN4PLMD15ActionWithValue16registerKeywordsERNS_8KeywordsE11118
_ZN4PLMD15ActionWithValueC2ERKNS_13ActionOptionsE18844
_ZN4PLMD15ActionWithValueD2Ev18844
_ZNK4PLMD15ActionWithValue19getComponentsVectorB5cxx11Ev23996
_ZN4PLMD15ActionWithValue27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE32447
_ZN4PLMD15ActionWithValue12addComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE37050
_ZN4PLMD15ActionWithValue22componentIsNotPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE66306
_ZN4PLMD15ActionWithValue14checkForForcesEv336620
_ZNK4PLMD15ActionWithValue10copyOutputERKj574657
_ZN4PLMD15ActionWithValue16clearDerivativesEv1403167
_ZN4PLMD15ActionWithValue20setGradientsIfNeededEv1414809
_ZN4PLMD15ActionWithValue16clearInputForcesEv1771724
_ZN4PLMD15ActionWithValue18getPntrToComponentEi1915855
_ZN4PLMD15ActionWithValue18getPntrToComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10612984
_ZNK4PLMD15ActionWithValue12getComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10679382
_ZNK4PLMD15ActionWithValue6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10684571
_ZNK4PLMD15ActionWithValue10copyOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30465860
_ZN4PLMD15ActionWithValue17turnOnDerivativesEv48102873
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.cpp.func.html b/coverage/core/ActionWithValue.cpp.func.html new file mode 100644 index 000000000000..9af791a9e6ac --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.func.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithValue.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13214591.0 %
Date:2024-02-22 21:58:45Functions:253083.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue11setPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_677
_ZN4PLMD15ActionWithValue12addComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE37050
_ZN4PLMD15ActionWithValue14checkForForcesEv336620
_ZN4PLMD15ActionWithValue14setNotPeriodicEv8265
_ZN4PLMD15ActionWithValue16clearDerivativesEv1403167
_ZN4PLMD15ActionWithValue16clearInputForcesEv1771724
_ZN4PLMD15ActionWithValue16registerKeywordsERNS_8KeywordsE11118
_ZN4PLMD15ActionWithValue17turnOnDerivativesEv48102873
_ZN4PLMD15ActionWithValue18getPntrToComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10612984
_ZN4PLMD15ActionWithValue18getPntrToComponentEi1915855
_ZN4PLMD15ActionWithValue19componentIsPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_92
_ZN4PLMD15ActionWithValue20setGradientsIfNeededEv1414809
_ZN4PLMD15ActionWithValue22componentIsNotPeriodicERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE66306
_ZN4PLMD15ActionWithValue23addValueWithDerivativesERKSt6vectorIjSaIjEE2300
_ZN4PLMD15ActionWithValue23noAnalyticalDerivativesERNS_8KeywordsE0
_ZN4PLMD15ActionWithValue24componentsAreNotOptionalERNS_8KeywordsE1304
_ZN4PLMD15ActionWithValue25useCustomisableComponentsERNS_8KeywordsE256
_ZN4PLMD15ActionWithValue27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIjSaIjEE32447
_ZN4PLMD15ActionWithValue8addValueERKSt6vectorIjSaIjEE6642
_ZN4PLMD15ActionWithValueC1ERKNS_13ActionOptionsE0
_ZN4PLMD15ActionWithValueC2ERKNS_13ActionOptionsE18844
_ZN4PLMD15ActionWithValueD0Ev0
_ZN4PLMD15ActionWithValueD1Ev0
_ZN4PLMD15ActionWithValueD2Ev18844
_ZNK4PLMD15ActionWithValue10copyOutputERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30465860
_ZNK4PLMD15ActionWithValue10copyOutputERKj574657
_ZNK4PLMD15ActionWithValue12getComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10679382
_ZNK4PLMD15ActionWithValue17getComponentsListB5cxx11Ev0
_ZNK4PLMD15ActionWithValue19getComponentsVectorB5cxx11Ev23996
_ZNK4PLMD15ActionWithValue6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10684571
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.cpp.gcov.html b/coverage/core/ActionWithValue.cpp.gcov.html new file mode 100644 index 000000000000..29628d8b715f --- /dev/null +++ b/coverage/core/ActionWithValue.cpp.gcov.html @@ -0,0 +1,363 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithValue.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13214591.0 %
Date:2024-02-22 21:58:45Functions:253083.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithValue.h"
+      23             : #include "ActionWithArguments.h"
+      24             : #include "ActionAtomistic.h"
+      25             : #include "tools/Exception.h"
+      26             : #include "tools/OpenMP.h"
+      27             : #include "tools/Communicator.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31       11118 : void ActionWithValue::registerKeywords(Keywords& keys) {
+      32       11118 :   keys.setComponentsIntroduction("By default the value of the calculated quantity can be referenced elsewhere in the "
+      33             :                                  "input file by using the label of the action.  Alternatively this Action can be used "
+      34             :                                  "to calculate the following quantities by employing the keywords listed "
+      35             :                                  "below.  These quantities can be referenced elsewhere in the input by using this Action's "
+      36             :                                  "label followed by a dot and the name of the quantity required from the list below.");
+      37       22236 :   keys.addFlag("NUMERICAL_DERIVATIVES", false, "calculate the derivatives for these quantities numerically");
+      38       22236 :   keys.add("hidden","HAS_VALUES","this is used in json output to determine those actions that have values");
+      39       11118 : }
+      40             : 
+      41           0 : void ActionWithValue::noAnalyticalDerivatives(Keywords& keys) {
+      42           0 :   keys.remove("NUMERICAL_DERIVATIVES");
+      43           0 :   keys.addFlag("NUMERICAL_DERIVATIVES",false,"analytical derivatives are not implemented for this keyword so numerical derivatives are always used");
+      44           0 : }
+      45             : 
+      46        1304 : void ActionWithValue::componentsAreNotOptional(Keywords& keys) {
+      47        1304 :   keys.setComponentsIntroduction("By default this Action calculates the following quantities. These quantities can "
+      48             :                                  "be referenced elsewhere in the input by using this Action's label followed by a "
+      49             :                                  "dot and the name of the quantity required from the list below.");
+      50        1304 : }
+      51             : 
+      52         256 : void ActionWithValue::useCustomisableComponents(Keywords& keys) {
+      53         256 :   keys.setComponentsIntroduction("The names of the components in this action can be customized by the user in the "
+      54             :                                  "actions input file.  However, in addition to the components that can be customized the "
+      55             :                                  "following quantities will always be output");
+      56         256 : }
+      57             : 
+      58       18844 : ActionWithValue::ActionWithValue(const ActionOptions&ao):
+      59             :   Action(ao),
+      60       18844 :   noderiv(true),
+      61       18844 :   numericalDerivatives(false)
+      62             : {
+      63       47951 :   if( keywords.exists("NUMERICAL_DERIVATIVES") ) parseFlag("NUMERICAL_DERIVATIVES",numericalDerivatives);
+      64       37688 :   if(!keywords.exists("NO_ACTION_LOG") && numericalDerivatives) log.printf("  using numerical derivatives\n");
+      65       18844 : }
+      66             : 
+      67       18844 : ActionWithValue::~ActionWithValue() {
+      68             : // empty destructor to delete unique_ptr
+      69       18844 : }
+      70             : 
+      71     1771724 : void ActionWithValue::clearInputForces() {
+      72     4240159 :   for(unsigned i=0; i<values.size(); i++) values[i]->clearInputForce();
+      73     1771724 : }
+      74             : 
+      75     1403167 : void ActionWithValue::clearDerivatives() {
+      76     1403167 :   unsigned nt = OpenMP::getNumThreads();
+      77     1403167 :   #pragma omp parallel num_threads(nt)
+      78             :   {
+      79             :     #pragma omp for
+      80             :     for(unsigned i=0; i<values.size(); i++) values[i]->clearDerivatives();
+      81             :   }
+      82     1403167 : }
+      83             : 
+      84             : // -- These are the routine for copying the value pointers to other classes -- //
+      85             : 
+      86    10684571 : bool ActionWithValue::exists( const std::string& name ) const {
+      87   101653053 :   for(unsigned i=0; i<values.size(); ++i) {
+      88    90973207 :     if (values[i]->name==name) return true;
+      89             :   }
+      90             :   return false;
+      91             : }
+      92             : 
+      93    30465860 : Value* ActionWithValue::copyOutput( const std::string& name ) const {
+      94   102628940 :   for(unsigned i=0; i<values.size(); ++i) {
+      95   102628940 :     if (values[i]->name==name) return values[i].get();
+      96             :   }
+      97           0 :   plumed_merror("there is no pointer with name " + name);
+      98             : }
+      99             : 
+     100      574657 : Value* ActionWithValue::copyOutput( const unsigned& n ) const {
+     101      574657 :   plumed_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+     102      574657 :   return values[n].get();
+     103             : }
+     104             : 
+     105             : // -- HERE WE HAVE THE STUFF FOR THE DEFAULT VALUE -- //
+     106             : 
+     107        6642 : void ActionWithValue::addValue( const std::vector<unsigned>& shape ) {
+     108        6642 :   plumed_massert(values.empty(),"You have already added the default value for this action");
+     109        6642 :   values.emplace_back(Tools::make_unique<Value>(this,getLabel(), false, shape ) );
+     110        6642 : }
+     111             : 
+     112        2300 : void ActionWithValue::addValueWithDerivatives( const std::vector<unsigned>& shape ) {
+     113        2300 :   plumed_massert(values.empty(),"You have already added the default value for this action");
+     114        2300 :   values.emplace_back(Tools::make_unique<Value>(this,getLabel(), true, shape ) );
+     115        2300 : }
+     116             : 
+     117        8265 : void ActionWithValue::setNotPeriodic() {
+     118        8265 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
+     119        8265 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     120        8265 :   values[0]->min=0; values[0]->max=0;
+     121        8265 :   values[0]->setupPeriodicity();
+     122        8265 : }
+     123             : 
+     124         677 : void ActionWithValue::setPeriodic( const std::string& min, const std::string& max ) {
+     125         677 :   plumed_massert(values.size()==1,"The number of components is not equal to one");
+     126         677 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     127         677 :   values[0]->setDomain( min, max );
+     128         677 : }
+     129             : 
+     130             : // -- HERE WE HAVE THE STUFF FOR NAMED VALUES / COMPONENTS -- //
+     131             : 
+     132       37050 : void ActionWithValue::addComponent( const std::string& name, const std::vector<unsigned>& shape ) {
+     133       37050 :   if( !keywords.outputComponentExists(name,true) ) {
+     134           0 :     plumed_merror("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
+     135             :                   "registerKeywords as described in the developer docs.");
+     136             :   }
+     137       74100 :   std::string thename; thename=getLabel() + "." + name;
+     138    18749652 :   for(unsigned i=0; i<values.size(); ++i) {
+     139    18712602 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
+     140    18712602 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name: "+thename);
+     141    18712602 :     plumed_massert(values[i]->name!=thename&&name!="bias","Since PLUMED 2.3 the component 'bias' is automatically added to all biases by the general constructor!\n"
+     142             :                    "Remove the line addComponent(\"bias\") from your bias.");
+     143             :   }
+     144       37050 :   values.emplace_back(Tools::make_unique<Value>(this,thename, false ) );
+     145       37050 :   std::string msg="  added component to this action:  "+thename+" \n";
+     146       37050 :   log.printf(msg.c_str());
+     147       37050 : }
+     148             : 
+     149       32447 : void ActionWithValue::addComponentWithDerivatives( const std::string& name, const std::vector<unsigned>& shape ) {
+     150       32447 :   if( !keywords.outputComponentExists(name,true) ) {
+     151           0 :     plumed_merror("a description of component " + name + " has not been added to the manual. Components should be registered like keywords in "
+     152             :                   "registerKeywords as described in the developer doc.");
+     153             :   }
+     154       64894 :   std::string thename; thename=getLabel() + "." + name;
+     155     2485610 :   for(unsigned i=0; i<values.size(); ++i) {
+     156     2453163 :     plumed_massert(values[i]->name!=getLabel(),"Cannot mix single values with components");
+     157     2453163 :     plumed_massert(values[i]->name!=thename,"there is already a value with this name: "+thename);
+     158     2453163 :     plumed_massert(values[i]->name!=thename&&name!="bias","Since PLUMED 2.3 the component 'bias' is automatically added to all biases by the general constructor!\n"
+     159             :                    "Remove the line addComponentWithDerivatives(\"bias\") from your bias.");
+     160             :   }
+     161       32447 :   values.emplace_back(Tools::make_unique<Value>(this,thename, true ) );
+     162       32447 :   std::string msg="  added component to this action:  "+thename+" \n";
+     163       32447 :   log.printf(msg.c_str());
+     164       32447 : }
+     165             : 
+     166    10679382 : int ActionWithValue::getComponent( const std::string& name ) const {
+     167    10679382 :   plumed_massert( !exists( getLabel() ), "You should not be calling this routine if you are using a value");
+     168    21358764 :   std::string thename; thename=getLabel() + "." + name;
+     169    64289878 :   for(unsigned i=0; i<values.size(); ++i) {
+     170    64289878 :     if (values[i]->name==thename) return i;
+     171             :   }
+     172           0 :   plumed_merror("there is no component with name " + name);
+     173             : }
+     174             : 
+     175           0 : std::string ActionWithValue::getComponentsList( ) const {
+     176             :   std::string complist;
+     177           0 :   for(unsigned i=0; i<values.size(); ++i) {
+     178           0 :     complist+=values[i]->name+" ";
+     179             :   }
+     180           0 :   return complist;
+     181             : }
+     182             : 
+     183       23996 : std::vector<std::string> ActionWithValue::getComponentsVector( ) const {
+     184             :   std::vector<std::string> complist;
+     185      349581 :   for(unsigned i=0; i<values.size(); ++i) {
+     186      325585 :     complist.push_back(values[i]->name);
+     187             :   }
+     188       23996 :   return complist;
+     189           0 : }
+     190             : 
+     191       66306 : void ActionWithValue::componentIsNotPeriodic( const std::string& name ) {
+     192       66306 :   int kk=getComponent(name);
+     193       66306 :   values[kk]->min=0; values[kk]->max=0;
+     194       66306 :   values[kk]->setupPeriodicity();
+     195       66306 : }
+     196             : 
+     197          92 : void ActionWithValue::componentIsPeriodic( const std::string& name, const std::string& min, const std::string& max ) {
+     198          92 :   int kk=getComponent(name);
+     199          92 :   values[kk]->setDomain(min,max);
+     200          92 : }
+     201             : 
+     202     1414809 : void ActionWithValue::setGradientsIfNeeded() {
+     203     2829618 :   if(isOptionOn("GRADIENTS")) {
+     204         201 :     ActionAtomistic* aa=castToActionAtomistic();
+     205         201 :     if(aa) {
+     206         308 :       for(unsigned i=0; i<values.size(); i++) { unsigned start=0; values[i]->gradients.clear(); values[i]->setGradients( aa, start ); }
+     207             :     } else {
+     208          83 :       ActionWithArguments* aarg = castToActionWithArguments();
+     209          83 :       if( !aarg ) plumed_merror( "failing in " + getLabel() );
+     210         166 :       for(unsigned i=0; i<values.size(); i++) { unsigned start=0; values[i]->gradients.clear(); aarg->setGradients( values[i].get(), start ); }
+     211             :     }
+     212             :   }
+     213     1414809 : }
+     214             : 
+     215    48102873 : void ActionWithValue::turnOnDerivatives() {
+     216             :   // Turn on the derivatives
+     217    48102873 :   noderiv=false;
+     218             :   // Resize the derivatives
+     219  4177489630 :   for(unsigned i=0; i<values.size(); ++i) values[i]->resizeDerivatives( getNumberOfDerivatives() );
+     220             :   // And turn on the derivatives in all actions on which we are dependent
+     221    96200313 :   for(unsigned i=0; i<getDependencies().size(); ++i) {
+     222    48097440 :     ActionWithValue* vv=getDependencies()[i]->castToActionWithValue();
+     223    48097440 :     if(vv) vv->turnOnDerivatives();
+     224             :   }
+     225    48102873 : }
+     226             : 
+     227    10612984 : Value* ActionWithValue::getPntrToComponent( const std::string& name ) {
+     228    10612984 :   int kk=getComponent(name);
+     229    10612984 :   return values[kk].get();
+     230             : }
+     231             : 
+     232     1915855 : Value* ActionWithValue::getPntrToComponent( int n ) {
+     233             :   plumed_dbg_massert(n<values.size(),"you have requested a pointer that is out of bounds");
+     234     1915855 :   return values[n].get();
+     235             : }
+     236             : 
+     237      336620 : bool ActionWithValue::checkForForces() {
+     238      336620 :   const unsigned    ncp=getNumberOfComponents();
+     239      336620 :   unsigned    nder=getNumberOfDerivatives();
+     240      336620 :   if( ncp==0 || nder==0 ) return false;
+     241             : 
+     242             :   unsigned nvalsWithForce=0;
+     243      336620 :   valsToForce.resize(ncp);
+     244      929213 :   for(unsigned i=0; i<ncp; ++i) {
+     245      592593 :     if( values[i]->hasForce && !values[i]->constant ) {
+     246      107051 :       valsToForce[nvalsWithForce]=i; nvalsWithForce++;
+     247             :     }
+     248             :   }
+     249      336620 :   if( nvalsWithForce==0 ) return false;
+     250             : 
+     251             :   // Make sure forces to apply is empty of forces
+     252      103474 :   if( forcesForApply.size()!=nder ) forcesForApply.resize( nder );
+     253             :   std::fill(forcesForApply.begin(),forcesForApply.end(),0);
+     254             : 
+     255             :   unsigned stride=1;
+     256             :   unsigned rank=0;
+     257      103474 :   if(ncp>4*comm.Get_size()) {
+     258          52 :     stride=comm.Get_size();
+     259          52 :     rank=comm.Get_rank();
+     260             :   }
+     261             : 
+     262      103474 :   unsigned nt=OpenMP::getNumThreads();
+     263      103474 :   if(nt>ncp/(4*stride)) nt=1;
+     264             : 
+     265      103474 :   #pragma omp parallel num_threads(nt)
+     266             :   {
+     267             :     std::vector<double> omp_f;
+     268             :     if( nt>1 ) omp_f.resize(nder,0);
+     269             :     #pragma omp for
+     270             :     for(unsigned i=rank; i<nvalsWithForce; i+=stride) {
+     271             :       double ff=values[valsToForce[i]]->inputForce[0];
+     272             :       std::vector<double> & thisderiv( values[valsToForce[i]]->data );
+     273             :       if( nt>1 ) for(unsigned j=0; j<nder; ++j) omp_f[j] += ff*thisderiv[1+j];
+     274             :       else for(unsigned j=0; j<nder; ++j) forcesForApply[j] += ff*thisderiv[1+j];
+     275             :     }
+     276             :     #pragma omp critical
+     277             :     {
+     278             :       if( nt>1 ) for(unsigned j=0; j<forcesForApply.size(); ++j) forcesForApply[j]+=omp_f[j];
+     279             :     }
+     280             :   }
+     281             : 
+     282      103474 :   if(ncp>4*comm.Get_size()) comm.Sum(&forcesForApply[0],nder);
+     283             :   return true;
+     284             : }
+     285             : 
+     286             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.h.func-sort-c.html b/coverage/core/ActionWithValue.h.func-sort-c.html new file mode 100644 index 000000000000..c84205322834 --- /dev/null +++ b/coverage/core/ActionWithValue.h.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue18checkFieldsAllowedEv0
_ZN4PLMD15ActionWithValue23useNumericalDerivativesEv2
_ZNK4PLMD15ActionWithValue25doNotCalculateDerivativesEv5924
_ZNK4PLMD15ActionWithValue17getOutputQuantityEj153914
_ZN4PLMD15ActionWithValue8setValueERKd190121
_ZNK4PLMD15ActionWithValue25checkNumericalDerivativesEv2015827
_ZNK4PLMD15ActionWithValue17getOutputQuantityERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3543898
_ZN4PLMD15ActionWithValue21castToActionWithValueEv49891427
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.h.func.html b/coverage/core/ActionWithValue.h.func.html new file mode 100644 index 000000000000..69e1942be5b8 --- /dev/null +++ b/coverage/core/ActionWithValue.h.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15ActionWithValue18checkFieldsAllowedEv0
_ZN4PLMD15ActionWithValue21castToActionWithValueEv49891427
_ZN4PLMD15ActionWithValue23useNumericalDerivativesEv2
_ZN4PLMD15ActionWithValue8setValueERKd190121
_ZNK4PLMD15ActionWithValue17getOutputQuantityERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3543898
_ZNK4PLMD15ActionWithValue17getOutputQuantityEj153914
_ZNK4PLMD15ActionWithValue25checkNumericalDerivativesEv2015827
_ZNK4PLMD15ActionWithValue25doNotCalculateDerivativesEv5924
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithValue.h.gcov.html b/coverage/core/ActionWithValue.h.gcov.html new file mode 100644 index 000000000000..3138b4f932c3 --- /dev/null +++ b/coverage/core/ActionWithValue.h.gcov.html @@ -0,0 +1,320 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithValue.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionWithValue_h
+      23             : #define __PLUMED_core_ActionWithValue_h
+      24             : 
+      25             : #include "Action.h"
+      26             : #include "Value.h"
+      27             : #include "tools/Exception.h"
+      28             : #include <vector>
+      29             : #include <memory>
+      30             : #include <cstring>
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : /**
+      35             : \ingroup MULTIINHERIT
+      36             : Used to create a PLMD::Action that has some scalar or vectorial output that may or may not have some derivatives.
+      37             : This is used for PLMD::Bias, PLMD::Colvar and PLMD::Function
+      38             : 
+      39             : The vast majority of the PLMD::Action objects that are implemented in
+      40             : plumed calculate some quantity or a set of quantities.  This could be
+      41             : the value of a CV, the value of a function or the potential due to a bias.
+      42             : PLMD::ActionWithValue provides the functionality for storing these quantities
+      43             : and (in tandem with PLMD::ActionWithArguments) the functionality for passing
+      44             : quantities between PLMD::Actions.  When you are deciding what quantities
+      45             : your new PLMD::Action will need to store using PLMD::ActionWithValue you must
+      46             : ask yourself the following two questions:
+      47             : 
+      48             : - Do I need to differentiate my output quantities
+      49             : - Is my PLMD::Action calculating a single thing or does the output have multiple components
+      50             : 
+      51             : If the answer to the first of these questions is yes then you must setup your values
+      52             : you using either PLMD::ActionWithValue::addValueWithDerivatives() or
+      53             : PLMD::ActionWithValue::addComponentWithDerivatives.  If the answer is no you
+      54             : can set up values using PLMD::ActionWithValue::addValue() or PLMD::ActionWithValue::addComponent().
+      55             : The precise routine you use to setup your values will depend on your answer to the
+      56             : second question.  As you are probably aware if the output of your PLMD::Action is a
+      57             : single quantity you can reference that quantity in the input file using the label of the
+      58             : PLMD::Action it was calculated in.  If your action <b> outputs only one quantity </b>
+      59             : we call that quantity the <b> value </b> of the Action.  To set the <b> value </b> and get pointers to it
+      60             : you should <b> use the set of routines that have the word value in the name </b>.  If, by contrast,
+      61             : your PLMD::Action calculates multiple quantities then these quantities are referenced in input using the
+      62             : label.component syntax.  We refer to these <b> multiple quantities </b> the <b> components </b>
+      63             : of the PLMD::Action.  Perhaps unsurprisingly, when you manipulate the <b> components </b> of an
+      64             : PLMD::Action you should use <b> the routines with the word component in the name. </b>
+      65             : */
+      66             : 
+      67             : class ActionWithValue :
+      68             :   public virtual Action
+      69             : {
+      70             : private:
+      71             : /// An array containing the values for this action
+      72             :   std::vector<std::unique_ptr<Value>> values;
+      73             : /// A vector that is used to hold the forces that we will apply on the input quantities
+      74             :   std::vector<double> forcesForApply;
+      75             :   std::vector<unsigned> valsToForce;
+      76             : /// Are we skipping the calculation of the derivatives
+      77             :   bool noderiv;
+      78             : /// Are we using numerical derivatives to differentiate
+      79             :   bool numericalDerivatives;
+      80             : /// Return the index for the component named name
+      81             :   int getComponent( const std::string& name ) const;
+      82             : public:
+      83             : 
+      84             : // -------- The action has one value only  ---------------- //
+      85             : 
+      86             : /// Add a value with the name label
+      87             :   void addValue( const std::vector<unsigned>& shape=std::vector<unsigned>() );
+      88             : /// Add a value with the name label that has derivatives
+      89             :   void addValueWithDerivatives( const std::vector<unsigned>& shape=std::vector<unsigned>() );
+      90             : /// Set your default value to have no periodicity
+      91             :   void setNotPeriodic();
+      92             : /// Set the value to be periodic with a particular domain
+      93             :   void setPeriodic( const std::string& min, const std::string& max );
+      94             : protected:
+      95             : /// Get a pointer to the default value
+      96             :   Value* getPntrToValue();
+      97             : /// Set the default value (the one without name)
+      98             :   void setValue(const double& d);
+      99             : 
+     100             : // -------- The action has multiple components ---------- //
+     101             : 
+     102             : public:
+     103             : /// Add a value with a name like label.name
+     104             :   void addComponent( const std::string& name, const std::vector<unsigned>& shape=std::vector<unsigned>() );
+     105             : /// Add a value with a name like label.name that has derivatives
+     106             :   void addComponentWithDerivatives( const std::string& name, const std::vector<unsigned>& shape=std::vector<unsigned>() );
+     107             : /// Set your value component to have no periodicity
+     108             :   void componentIsNotPeriodic( const std::string& name );
+     109             : /// Set the value to be periodic with a particular domain
+     110             :   void componentIsPeriodic( const std::string& name, const std::string& min, const std::string& max );
+     111             : protected:
+     112             : /// Return a pointer to the component by index
+     113             :   Value* getPntrToComponent(int i);
+     114             : /// Return a pointer to the value by name
+     115             :   Value* getPntrToComponent(const std::string& name);
+     116             : /// Accumulate the forces from the Values
+     117             :   bool checkForForces();
+     118             : /// Get the forces to apply
+     119             :   const std::vector<double>& getForcesToApply() const;
+     120             : public:
+     121             :   explicit ActionWithValue(const ActionOptions&ao);
+     122             :   ~ActionWithValue();
+     123             : 
+     124             : /// Register all the relevant keywords for the action
+     125             :   static void registerKeywords( Keywords& keys );
+     126             : /// Insist that numerical derivatives should always be used for an action and make this fact appear in the manual
+     127             :   static void noAnalyticalDerivatives(Keywords& keys);
+     128             : /// Puts a message into the manual that the components always output
+     129             :   static void componentsAreNotOptional(Keywords& keys);
+     130             : /// The components in the action will depend on the user
+     131             :   static void useCustomisableComponents(Keywords& keys);
+     132             : /// Are we not calculating derivatives
+     133             :   virtual bool doNotCalculateDerivatives() const ;
+     134             : /// Get the value of one of the components of the PLMD::Action
+     135             :   double getOutputQuantity( const unsigned j ) const ;
+     136             : /// Get the value with a specific name (N.B. if there is no such value this returns zero)
+     137             :   double getOutputQuantity( const std::string& name ) const ;
+     138             : 
+     139             : //  --- Routines for passing stuff to ActionWithArguments -- //
+     140             : 
+     141             : /// Check if a value with a particular name is present.  This is only used in PLMD::ActionWithArguments.
+     142             : /// You should not use it when manipulating components.
+     143             :   bool exists( const std::string& name ) const;
+     144             : /// Return a pointer to the value with name (this is used to retrieve values in other PLMD::Actions)
+     145             : /// You should NEVER use this routine to refer to the components of your PLMD::Action.  Use
+     146             : /// getPntrToComponent instead.
+     147             :   Value* copyOutput( const std::string&name ) const;
+     148             : /// Return a pointer to the value with this number (this is used to retrieve values in other PLMD::Actions)
+     149             : /// You should NEVER use this routine to refer to the components of your PLMD::Action.  Use
+     150             : /// getPntrToComponent instead.
+     151             :   Value* copyOutput( const unsigned& n ) const;
+     152             : /// get a string that contains all the available components
+     153             :   std::string getComponentsList( ) const ;
+     154             : /// get a vector that contains the label for all the components
+     155             :   std::vector<std::string> getComponentsVector( ) const ;
+     156             : 
+     157             : 
+     158             : // -- Routines for everything else -- //
+     159             : 
+     160             : /// Returns the number of values defined
+     161             :   int getNumberOfComponents() const ;
+     162             : /// Clear the forces on the values
+     163             :   void clearInputForces();
+     164             : /// Clear the derivatives of values wrt parameters
+     165             :   virtual void clearDerivatives();
+     166             : /// Calculate the gradients and store them for all the values (need for projections)
+     167             :   virtual void setGradientsIfNeeded();
+     168             : /// Set the value
+     169             :   void setValue(Value*,double);
+     170             : /// Check if numerical derivatives should be used
+     171             :   bool checkNumericalDerivatives() const override;
+     172             : /// This forces the class to use numerical derivatives
+     173             :   void useNumericalDerivatives();
+     174             : // These are things for using vectors of values as fields
+     175           0 :   virtual void checkFieldsAllowed() { error("cannot use this action as a field"); }
+     176             :   virtual unsigned getNumberOfDerivatives()=0;
+     177             : /// Activate the calculation of derivatives
+     178             :   virtual void turnOnDerivatives();
+     179    49891427 :   ActionWithValue* castToActionWithValue() noexcept final { return this; }
+     180             : };
+     181             : 
+     182             : inline
+     183      153914 : double ActionWithValue::getOutputQuantity(const unsigned j) const {
+     184      153914 :   plumed_massert(j<values.size(),"index requested is out of bounds");
+     185      153914 :   return values[j]->get();
+     186             : }
+     187             : 
+     188             : inline
+     189     3543898 : double ActionWithValue::getOutputQuantity( const std::string& name ) const {
+     190     3543898 :   int offset=getLabel().size();
+     191     8006542 :   for(unsigned i=0; i<values.size(); ++i) {
+     192             :     const std::string & valname=values[i]->name;
+     193     4550030 :     if(valname.size()>offset+1 && valname[offset]=='.' ) {
+     194             :       plumed_dbg_assert(Tools::startWith(valname,getLabel()));
+     195             :       if(!std::strcmp(valname.c_str()+offset+1,name.c_str())) return values[i]->get();
+     196             :     }
+     197             :   }
+     198             :   return 0.0;
+     199             : }
+     200             : 
+     201             : inline
+     202      190121 : void ActionWithValue::setValue(const double& d) {
+     203      190121 :   plumed_massert(values.size()==1, "cannot use setValue in multi-component actions");
+     204      190121 :   plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
+     205      190121 :   values[0]->set(d);
+     206      190121 : }
+     207             : 
+     208             : inline
+     209             : int ActionWithValue::getNumberOfComponents() const {
+     210      152397 :   return values.size();
+     211             : }
+     212             : 
+     213             : inline
+     214           2 : void ActionWithValue::useNumericalDerivatives() {
+     215           4 :   plumed_massert( keywords.exists("NUMERICAL_DERIVATIVES"), "numerical derivatives are not permitted for this action" );
+     216           2 :   numericalDerivatives=true;
+     217           2 : }
+     218             : 
+     219             : inline
+     220     2015827 : bool ActionWithValue::checkNumericalDerivatives() const {
+     221     2015871 :   return numericalDerivatives;
+     222             : }
+     223             : 
+     224             : inline
+     225        5924 : bool ActionWithValue::doNotCalculateDerivatives() const {
+     226    69225548 :   return noderiv;
+     227             : }
+     228             : 
+     229             : inline
+     230             : const std::vector<double>& ActionWithValue::getForcesToApply() const {
+     231      103474 :   return forcesForApply;
+     232             : }
+     233             : 
+     234             : inline
+     235             : Value* ActionWithValue::getPntrToValue() {
+     236             :   plumed_dbg_massert(values.size()==1,"The number of components is not equal to one");
+     237             :   plumed_dbg_massert(values[0]->name==getLabel(), "The value you are trying to retrieve is not the default");
+     238             :   return values[0].get();
+     239             : }
+     240             : 
+     241             : }
+     242             : 
+     243             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html b/coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html new file mode 100644 index 000000000000..80523413799e --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVirtualAtom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVirtualAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5858100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtomC1ERKNS_13ActionOptionsE0
_ZN4PLMD21ActionWithVirtualAtom17setBoxDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE605
_ZN4PLMD21ActionWithVirtualAtom22setBoxDerivativesNoPbcEv605
_ZN4PLMD21ActionWithVirtualAtom12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE7167
_ZN4PLMD21ActionWithVirtualAtomC2ERKNS_13ActionOptionsE7178
_ZN4PLMD21ActionWithVirtualAtom16registerKeywordsERNS_8KeywordsE7188
_ZN4PLMD21ActionWithVirtualAtom5applyEv14338
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.cpp.func.html b/coverage/core/ActionWithVirtualAtom.cpp.func.html new file mode 100644 index 000000000000..a2eca89522f1 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVirtualAtom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVirtualAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5858100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtom12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE7167
_ZN4PLMD21ActionWithVirtualAtom16registerKeywordsERNS_8KeywordsE7188
_ZN4PLMD21ActionWithVirtualAtom17setBoxDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE605
_ZN4PLMD21ActionWithVirtualAtom22setBoxDerivativesNoPbcEv605
_ZN4PLMD21ActionWithVirtualAtom5applyEv14338
_ZN4PLMD21ActionWithVirtualAtomC1ERKNS_13ActionOptionsE0
_ZN4PLMD21ActionWithVirtualAtomC2ERKNS_13ActionOptionsE7178
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.cpp.gcov.html b/coverage/core/ActionWithVirtualAtom.cpp.gcov.html new file mode 100644 index 000000000000..daee82d9a1c8 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVirtualAtom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVirtualAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5858100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithVirtualAtom.h"
+      23             : #include <array>
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27        7188 : void ActionWithVirtualAtom::registerKeywords(Keywords& keys) {
+      28        7188 :   Action::registerKeywords(keys);
+      29        7188 :   ActionAtomistic::registerKeywords(keys);
+      30       14376 :   keys.add("atoms","ATOMS","the list of atoms which are involved the virtual atom's definition");
+      31       14376 :   keys.addOutputComponent("x","default","the x coordinate of the virtual atom");
+      32       14376 :   keys.addOutputComponent("y","default","the y coordinate of the virtual atom");
+      33       14376 :   keys.addOutputComponent("z","default","the z coordinate of the virtual atom");
+      34       14376 :   keys.addOutputComponent("mass","default","the mass of the virtual atom");
+      35       14376 :   keys.addOutputComponent("charge","default","the charge of the virtual atom");
+      36        7188 : }
+      37             : 
+      38        7178 : ActionWithVirtualAtom::ActionWithVirtualAtom(const ActionOptions&ao):
+      39             :   Action(ao),
+      40             :   ActionAtomistic(ao),
+      41        7178 :   ActionWithValue(ao)
+      42             : {
+      43       21534 :   addComponentWithDerivatives("x"); componentIsNotPeriodic("x");
+      44       21534 :   addComponentWithDerivatives("y"); componentIsNotPeriodic("y");
+      45       14356 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+      46             :   // Store the derivatives with respect to the virial only even if there are no atoms
+      47       28712 :   for(unsigned i=0; i<3; ++i) getPntrToComponent(i)->resizeDerivatives(9);
+      48       28712 :   addComponent("mass"); componentIsNotPeriodic("mass"); getPntrToComponent("mass")->isConstant();
+      49       21534 :   addComponent("charge"); componentIsNotPeriodic("charge"); getPntrToComponent("charge")->isConstant();
+      50        7178 : }
+      51             : 
+      52        7167 : void ActionWithVirtualAtom::requestAtoms(const std::vector<AtomNumber> & a) {
+      53       28668 :   ActionAtomistic::requestAtoms(a); for(unsigned i=0; i<3; ++i) getPntrToComponent(i)->resizeDerivatives(3*a.size()+9);
+      54        7167 : }
+      55             : 
+      56       14338 : void ActionWithVirtualAtom::apply() {
+      57       14338 :   Value* xval=getPntrToComponent(0);
+      58       14338 :   Value* yval=getPntrToComponent(1);
+      59       14338 :   Value* zval=getPntrToComponent(2);
+      60       14338 :   if( !xval->forcesWereAdded() && !yval->forcesWereAdded() && !zval->forcesWereAdded() ) return ;
+      61        4419 :   if( xval->isConstant() && yval->isConstant() && zval->isConstant() ) return;
+      62             : 
+      63        8795 :   for(unsigned i=0; i<value_depends.size(); ++i) {
+      64        4376 :     xpos[value_depends[i]]->hasForce = true;
+      65        4376 :     ypos[value_depends[i]]->hasForce = true;
+      66        4376 :     zpos[value_depends[i]]->hasForce = true;
+      67             :   }
+      68             :   unsigned k=0;
+      69        4419 :   double xf = xval->inputForce[0];
+      70        4419 :   double yf = yval->inputForce[0];
+      71        4419 :   double zf = zval->inputForce[0];
+      72       35874 :   for(const auto & a : atom_value_ind) {
+      73       31455 :     std::size_t nn = a.first, kk = a.second;
+      74       31455 :     xpos[nn]->inputForce[kk] += xf*xval->data[1+k] + yf*yval->data[1+k] + zf*zval->data[1+k]; k++;
+      75       31455 :     ypos[nn]->inputForce[kk] += xf*xval->data[1+k] + yf*yval->data[1+k] + zf*zval->data[1+k]; k++;
+      76       31455 :     zpos[nn]->inputForce[kk] += xf*xval->data[1+k] + yf*yval->data[1+k] + zf*zval->data[1+k]; k++;
+      77             :   }
+      78             :   std::array<double,9> virial;
+      79       44190 :   for(unsigned i=0; i<9; ++i) { virial[i] = xf*xval->data[1+k] + yf*yval->data[1+k] + zf*zval->data[1+k]; k++; }
+      80        4419 :   unsigned ind = 0; setForcesOnCell( virial.data(), virial.size(), ind );
+      81             :   // The above can be achieved using the two functions below.  The code above that is specialised for the ActionWithVirtualAtom
+      82             :   // class runs faster than the general code below.
+      83             :   // if( !checkForForces() ) return ;
+      84             :   // unsigned mm=0; setForcesOnAtoms( getForcesToApply(), mm );
+      85             : }
+      86             : 
+      87         605 : void ActionWithVirtualAtom::setBoxDerivatives(const std::vector<Tensor> &d) {
+      88         605 :   plumed_assert(d.size()==3); unsigned nbase = 3*getNumberOfAtoms();
+      89        2420 :   for(unsigned i=0; i<3; ++i) {
+      90        1815 :     Value* myval = getPntrToComponent(i);
+      91        7260 :     for(unsigned j=0; j<3; ++j) {
+      92       21780 :       for(unsigned k=0; k<3; ++k) myval->setDerivative( nbase + 3*j + k, d[i][j][k] );
+      93             :     }
+      94             :   }
+      95             : // Subtract the trivial part coming from a distorsion applied to the ghost atom first.
+      96             : // Notice that this part alone should exactly cancel the already accumulated virial
+      97             : // due to forces on this atom.
+      98        2420 :   Vector pos; for(unsigned i=0; i<3; ++i) pos[i] = getPntrToComponent(i)->get();
+      99        7865 :   for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++) getPntrToComponent(j)->addDerivative( nbase + 3*i + j, pos[i] );
+     100         605 : }
+     101             : 
+     102         605 : void ActionWithVirtualAtom::setBoxDerivativesNoPbc() {
+     103         605 :   std::vector<Tensor> bd(3);
+     104       24200 :   for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++) for(unsigned k=0; k<3; k++) {
+     105             : // Notice that this expression is very similar to the one used in Colvar::setBoxDerivativesNoPbc().
+     106             : // Indeed, we have the negative of a sum over dependent atoms (l) of the external product between positions
+     107             : // and derivatives. Notice that this only works only when Pbc have not been used to compute
+     108             : // derivatives.
+     109       16902 :         for(unsigned l=0; l<getNumberOfAtoms(); l++) {
+     110         567 :           bd[k][i][j]-=getPosition(l)[i]*getPntrToComponent(k)->getDerivative(3*l+j);
+     111             :         }
+     112             :       }
+     113         605 :   setBoxDerivatives(bd);
+     114         605 : }
+     115             : 
+     116             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.h.func-sort-c.html b/coverage/core/ActionWithVirtualAtom.h.func-sort-c.html new file mode 100644 index 000000000000..6f6989f034af --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVirtualAtom.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVirtualAtom.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtom11setPositionERKNS_13VectorGenericILj3EEE14422
_ZN4PLMD21ActionWithVirtualAtom19setAtomsDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE14422
_ZN4PLMD21ActionWithVirtualAtom9setChargeEd19571
_ZN4PLMD21ActionWithVirtualAtom7setMassEd19575
_ZN4PLMD21ActionWithVirtualAtom22getNumberOfDerivativesEv2618525
_ZN4PLMD21ActionWithVirtualAtom27castToActionWithVirtualAtomEv6102390
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.h.func.html b/coverage/core/ActionWithVirtualAtom.h.func.html new file mode 100644 index 000000000000..3db9eefdeced --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVirtualAtom.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVirtualAtom.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD21ActionWithVirtualAtom11setPositionERKNS_13VectorGenericILj3EEE14422
_ZN4PLMD21ActionWithVirtualAtom19setAtomsDerivativesERKSt6vectorINS_13TensorGenericILj3ELj3EEESaIS3_EE14422
_ZN4PLMD21ActionWithVirtualAtom22getNumberOfDerivativesEv2618525
_ZN4PLMD21ActionWithVirtualAtom27castToActionWithVirtualAtomEv6102390
_ZN4PLMD21ActionWithVirtualAtom7setMassEd19575
_ZN4PLMD21ActionWithVirtualAtom9setChargeEd19571
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ActionWithVirtualAtom.h.gcov.html b/coverage/core/ActionWithVirtualAtom.h.gcov.html new file mode 100644 index 000000000000..fa2bf68de426 --- /dev/null +++ b/coverage/core/ActionWithVirtualAtom.h.gcov.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage - core/ActionWithVirtualAtom.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ActionWithVirtualAtom.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_ActionWithVirtualAtom_h
+      23             : #define __PLUMED_core_ActionWithVirtualAtom_h
+      24             : 
+      25             : #include "ActionAtomistic.h"
+      26             : #include "ActionWithValue.h"
+      27             : #include "tools/AtomNumber.h"
+      28             : #include "tools/Vector.h"
+      29             : #include "tools/Tensor.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /**
+      34             : \ingroup INHERIT
+      35             : Inherit from here if you are calculating the position of a virtual atom (eg a center of mass)
+      36             : */
+      37             : 
+      38             : /// Class to add a single virtual atom to the system.
+      39             : /// (it might be extended to add multiple virtual atoms).
+      40             : class ActionWithVirtualAtom:
+      41             :   public ActionAtomistic,
+      42             :   public ActionWithValue
+      43             : {
+      44             : protected:
+      45             : /// Set position of the virtual atom
+      46             :   void setPosition(const Vector &);
+      47             : /// Set its mass
+      48             :   void setMass(double);
+      49             : /// Set its charge
+      50             :   void setCharge(double);
+      51             : /// Request the atoms on which the calculation demands
+      52             :   void requestAtoms(const std::vector<AtomNumber> & a);
+      53             : /// Set the derivatives of virtual atom coordinate wrt atoms on which it dependes
+      54             :   void setAtomsDerivatives(const std::vector<Tensor> &d);
+      55             : /// Set the box derivatives.
+      56             : /// This should be a vector of size 3. First index corresponds
+      57             : /// to the components of the virtual atom.
+      58             : /// Notice that this routine subtract the trivial term coming from cell deformation
+      59             : /// since this term is already implicitly included. Indeed, if the vatom
+      60             : /// position is a linear function of atomic coordinates it is not necessary
+      61             : /// to call this function (implicit term is fine) (e.g. vatom::COM and vatom::Center).
+      62             : /// On the other hand if the vatom position is a non-linear function of atomic coordinates this
+      63             : /// should be called (see vatom::Ghost).
+      64             :   void setBoxDerivatives(const std::vector<Tensor> &d);
+      65             : /// Set box derivatives automatically.
+      66             : /// It should be called after the settomsDerivatives has been used for all
+      67             : /// single atoms.
+      68             : /// \warning It only works for virtual atoms NOT using PBCs!
+      69             : ///          This implies that all atoms used + the new virtual atom should be
+      70             : ///          in the same periodic image.
+      71             :   void setBoxDerivativesNoPbc();
+      72             : public:
+      73             : /// Return the atom id of the corresponding virtual atom
+      74             :   AtomNumber getIndex()const;
+      75             :   explicit ActionWithVirtualAtom(const ActionOptions&ao);
+      76             :   static void registerKeywords(Keywords& keys);
+      77             :   virtual unsigned getNumberOfDerivatives();
+      78             :   virtual void apply();
+      79     6102390 :   ActionWithVirtualAtom* castToActionWithVirtualAtom() noexcept final { return this; }
+      80             : };
+      81             : 
+      82             : inline
+      83     2618525 : unsigned ActionWithVirtualAtom::getNumberOfDerivatives() {
+      84     2618525 :   return 3*getNumberOfAtoms()+9;
+      85             : }
+      86             : 
+      87             : inline
+      88       14422 : void ActionWithVirtualAtom::setPosition(const Vector & pos) {
+      89       57688 :   for(unsigned i=0; i<3; ++i) getPntrToComponent(i)->set(pos[i]);
+      90       14422 : }
+      91             : 
+      92             : inline
+      93       19575 : void ActionWithVirtualAtom::setMass(double m) {
+      94       19575 :   getPntrToComponent(3)->set(m);
+      95       19575 : }
+      96             : 
+      97             : inline
+      98       19571 : void ActionWithVirtualAtom::setCharge(double c) {
+      99       19571 :   getPntrToComponent(4)->set(c);
+     100       19571 : }
+     101             : 
+     102             : inline
+     103       14422 : void ActionWithVirtualAtom::setAtomsDerivatives(const std::vector<Tensor> &d) {
+     104             :   unsigned jj=0;
+     105       14422 :   Value* xval=getPntrToComponent(0);
+     106       14422 :   Value* yval=getPntrToComponent(1);
+     107       14422 :   Value* zval=getPntrToComponent(2);
+     108       95984 :   for(unsigned j=0; j<getNumberOfAtoms(); ++j) {
+     109      326248 :     for(unsigned k=0; k<3; ++k) {
+     110      244686 :       xval->setDerivative( jj, d[j][k][0] );
+     111      244686 :       yval->setDerivative( jj, d[j][k][1] );
+     112      244686 :       zval->setDerivative( jj, d[j][k][2] );
+     113             :       jj++;
+     114             :     }
+     115             :   }
+     116       14422 : }
+     117             : 
+     118             : }
+     119             : 
+     120             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.cpp.func-sort-c.html b/coverage/core/CLTool.cpp.func-sort-c.html new file mode 100644 index 000000000000..e3c87f759ff4 --- /dev/null +++ b/coverage/core/CLTool.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - core/CLTool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:859985.9 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6CLTool5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6CLTool13readInputFileEiPPcP8_IO_FILES4_52
_ZN4PLMD6CLTool19readCommandLineArgsEiPPcP8_IO_FILE2990
_ZN4PLMD6CLTool21setRemainingToDefaultEP8_IO_FILE3042
_ZN4PLMD6CLTool9readInputEiPPcP8_IO_FILES4_3042
_ZN4PLMD13CLToolOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3110
_ZN4PLMD13CLToolOptionsC2ERKS0_RKNS_8KeywordsE3110
_ZN4PLMD6CLToolC2ERKNS_13CLToolOptionsE3110
_ZN4PLMD6CLTool9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb21044
_ZN4PLMD6CLTool16registerKeywordsERNS_8KeywordsE62805
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.cpp.func.html b/coverage/core/CLTool.cpp.func.html new file mode 100644 index 000000000000..ec8b66c8610d --- /dev/null +++ b/coverage/core/CLTool.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - core/CLTool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:859985.9 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13CLToolOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3110
_ZN4PLMD13CLToolOptionsC2ERKS0_RKNS_8KeywordsE3110
_ZN4PLMD6CLTool13readInputFileEiPPcP8_IO_FILES4_52
_ZN4PLMD6CLTool16registerKeywordsERNS_8KeywordsE62805
_ZN4PLMD6CLTool19readCommandLineArgsEiPPcP8_IO_FILE2990
_ZN4PLMD6CLTool21setRemainingToDefaultEP8_IO_FILE3042
_ZN4PLMD6CLTool5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD6CLTool9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb21044
_ZN4PLMD6CLTool9readInputEiPPcP8_IO_FILES4_3042
_ZN4PLMD6CLToolC2ERKNS_13CLToolOptionsE3110
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.cpp.gcov.html b/coverage/core/CLTool.cpp.gcov.html new file mode 100644 index 000000000000..48d6ebe6b8df --- /dev/null +++ b/coverage/core/CLTool.cpp.gcov.html @@ -0,0 +1,293 @@ + + + + + + + + LCOV - plumed test coverage - core/CLTool.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:859985.9 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLTool.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : 
+      26             : Keywords CLToolOptions::emptyKeys;
+      27             : 
+      28        3110 : CLToolOptions::CLToolOptions(const std::string &name):
+      29        3110 :   line(1,name),
+      30        3110 :   keys(emptyKeys)
+      31             : {
+      32        3110 : }
+      33             : 
+      34        3110 : CLToolOptions::CLToolOptions(const CLToolOptions& co, const Keywords& k):
+      35        3110 :   line(co.line),
+      36        3110 :   keys(k)
+      37             : {
+      38        3110 : }
+      39             : 
+      40       62805 : void CLTool::registerKeywords( Keywords& keys ) {
+      41      125610 :   keys.addFlag("--help/-h",false,"print this help");
+      42       62805 : }
+      43             : 
+      44        3110 : CLTool::CLTool(const CLToolOptions& co ):
+      45        3110 :   name(co.line[0]),
+      46        3110 :   keywords(co.keys),
+      47        3110 :   inputdata(unset)
+      48             : {
+      49        3110 : }
+      50             : 
+      51       21044 : void CLTool::parseFlag( const std::string&key, bool&t ) {
+      52       21044 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+      53       42088 :   plumed_massert(keywords.style(key,"flag"),"keyword " + key + " has not been registered as a flag");
+      54           0 :   plumed_assert(inputData.count(key)>0);
+      55       42088 :   if( inputData[key]=="true") t=true;
+      56       37616 :   else if( inputData[key]=="false") t=false;
+      57           0 :   else plumed_error();
+      58       21044 : }
+      59             : 
+      60        3042 : bool CLTool::readInput( int argc, char**argv, FILE* in, FILE*out ) {
+      61        3042 :   plumed_massert( inputdata!=unset,"You have not specified where your tool reads its input. "
+      62             :                   "If it is from the command line (like driver) add inputdata=commandline to the "
+      63             :                   "tools constructor. If it reads everything from an input file (like simplemd) "
+      64             :                   "add inputdata=ifile to the tools constructor");
+      65        3042 :   if(inputdata==commandline) return readCommandLineArgs( argc, argv, out );
+      66          52 :   if(inputdata==ifile) return readInputFile( argc, argv, in, out );
+      67             :   return true;
+      68             : }
+      69             : 
+      70        2990 : bool CLTool::readCommandLineArgs( int argc, char**argv, FILE*out ) {
+      71        2990 :   plumed_assert(inputdata==commandline);
+      72        2990 :   std::string prefix(""), a(""), thiskey;
+      73             : 
+      74             :   // Set all flags to default false
+      75       56999 :   for(unsigned k=0; k<keywords.size(); ++k) {
+      76       54009 :     thiskey=keywords.get(k);
+      77      132436 :     if( keywords.style(thiskey,"flag") ) inputData.insert(std::pair<std::string,std::string>(thiskey,"false"));
+      78             :   }
+      79             : 
+      80             :   // Read command line arguments
+      81             :   bool printhelp=false;
+      82       12378 :   for(int i=1; i<argc; i++) {
+      83       18776 :     a=prefix+argv[i];
+      84        9388 :     if(a.length()==0) continue;
+      85       18776 :     if(a=="-h" || a=="--help") {
+      86             :       printhelp=true;
+      87             :     } else {
+      88             :       bool found=false;
+      89      305796 :       for(unsigned k=0; k<keywords.size(); ++k) {
+      90      296408 :         thiskey=keywords.get(k);
+      91      592816 :         if( keywords.style(thiskey,"flag") ) {
+      92       60656 :           if( a==thiskey ) { found=true; inputData[thiskey]="true"; }
+      93             :         } else {
+      94      235752 :           if( a==thiskey ) {
+      95        3318 :             prefix=thiskey+"="; found=true;
+      96        6636 :             inputData.insert(std::pair<std::string,std::string>(thiskey,""));
+      97      464868 :           } else if(Tools::startWith(a,thiskey+"=")) {
+      98        3836 :             a.erase(0,a.find("=")+1); prefix=""; found=true;
+      99             :             if(inputData.count(thiskey)==0) {
+     100        1038 :               inputData.insert(std::pair<std::string,std::string>(thiskey,a));
+     101             :             } else {
+     102        3317 :               inputData[thiskey]=a;
+     103             :             }
+     104             :           }
+     105             :         }
+     106             :       }
+     107        9388 :       if(!found) {
+     108           0 :         std::fprintf(stderr,"ERROR in input for command line tool %s : %s option is unknown \n\n", name.c_str(), a.c_str() );
+     109             :         std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     110             :         std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     111           0 :         keywords.print( out );
+     112             :         printhelp=true;
+     113             :       }
+     114             :     }
+     115        9388 :     if(printhelp) break;
+     116             :   }
+     117             : 
+     118        2990 :   if(!printhelp) setRemainingToDefault(out);
+     119             : 
+     120        2990 :   if(printhelp) {
+     121             :     std::fprintf(out,"Usage: %s [options] \n\n", name.c_str() );
+     122           0 :     keywords.print( out );
+     123             :   }
+     124             : 
+     125        2990 :   return !printhelp;
+     126             : }
+     127             : 
+     128        3042 : void CLTool::setRemainingToDefault(FILE* out) {
+     129             :   std::string def, thiskey;
+     130       58059 :   for(unsigned k=0; k<keywords.size(); ++k) {
+     131       55017 :     thiskey=keywords.get(k);
+     132      110034 :     if( keywords.style(thiskey,"compulsory") ) {
+     133             :       if( inputData.count(thiskey)==0 ) {
+     134        1652 :         if( keywords.getDefaultValue(thiskey,def) ) {
+     135        1652 :           plumed_assert( def.length()>0 );
+     136        3304 :           inputData.insert(std::pair<std::string,std::string>(thiskey,def));
+     137             :         } else {
+     138             :           std::fprintf(out,"ERROR : argument %s is compulsory. Use --help option for help\n",thiskey.c_str() );
+     139           0 :           plumed_error();
+     140             :         }
+     141             :       }
+     142             :     }
+     143             :   }
+     144        3042 : }
+     145             : 
+     146          52 : bool CLTool::readInputFile( int argc, char**argv, FILE* in, FILE*out ) {
+     147          52 :   plumed_assert(inputdata==ifile);
+     148             : 
+     149             :   // Check if use is just asking for help
+     150             :   std::string a;
+     151          95 :   for(int i=1; i<argc; i++) {
+     152          43 :     a=argv[i];
+     153          43 :     if(a.length()==0) continue;
+     154          86 :     if(a=="-h" || a=="--help") {
+     155             :       std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     156             :       std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     157           0 :       keywords.print( out );
+     158             :       return false;
+     159             :     }
+     160             :   }
+     161             : 
+     162             :   FILE* mystdin=in;
+     163             : // call fclose when fp_deleter goes out of scope
+     164          43 :   auto deleter=[](auto f) { std::fclose(f); };
+     165             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(nullptr,deleter);
+     166             : 
+     167          52 :   if(argc==2) {
+     168          43 :     mystdin=std::fopen(argv[1],"r");
+     169          43 :     if(!mystdin) {
+     170           0 :       std::fprintf(stderr,"ERROR: cannot open file %s\n\n",argv[1]);
+     171             :       std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     172             :       std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     173           0 :       keywords.print( out );
+     174             :       return false;
+     175             :     }
+     176             :     fp_deleter.reset(mystdin);
+     177             :   }
+     178             : 
+     179          52 :   plumed_assert(mystdin);
+     180             : 
+     181             :   char buffer[256]; std::string line; line.resize(256);
+     182         864 :   while(fgets(buffer,256,mystdin)) {
+     183             :     line=buffer;
+     184       24516 :     for(unsigned i=0; i<line.length(); ++i) if(line[i]=='#' || line[i]=='\n') line.erase(i);
+     185         812 :     Tools::stripLeadingAndTrailingBlanks( line );
+     186         812 :     if(line.length()==0) continue;
+     187         775 :     std::sscanf(line.c_str(),"%255s",buffer);
+     188         775 :     std::string keyword=buffer; bool found=false;
+     189       16236 :     for(unsigned i=0; i<keywords.size(); ++i) {
+     190       15461 :       std::string thiskey=keywords.get(i);
+     191       15461 :       if(thiskey==keyword) {
+     192             :         found=true;
+     193         775 :         std::size_t keypos=line.find_first_of(keyword)+keyword.length();
+     194        1550 :         inputData.insert(std::pair<std::string,std::string>(thiskey,line.substr(keypos)));
+     195         775 :         Tools::stripLeadingAndTrailingBlanks( inputData[thiskey] );
+     196             :       }
+     197             :     }
+     198         775 :     if(!found) {
+     199           0 :       std::fprintf(stderr,"ERROR in input for command line tool %s : unknown keyword %s found in input file\n\n",name.c_str(),keyword.c_str());
+     200             :       std::fprintf(out,"Usage: %s < inputFile \n", name.c_str() );
+     201             :       std::fprintf(out,"inputFile should contain one directive per line.  The directives should come from amongst the following\n\n");
+     202           0 :       keywords.print( out );
+     203             :       return false;
+     204             :     }
+     205             :   }
+     206             : 
+     207          52 :   setRemainingToDefault(out);
+     208             :   return true;
+     209             : }
+     210             : 
+     211           0 : [[noreturn]] void CLTool::error( const std::string& msg ) {
+     212           0 :   std::fprintf(stderr,"ERROR : in input for command line tool %s : %s\n",name.c_str(),msg.c_str());
+     213           0 :   plumed_error();
+     214             : }
+     215             : 
+     216             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.h.func-sort-c.html b/coverage/core/CLTool.h.func-sort-c.html new file mode 100644 index 000000000000..e6a849469e73 --- /dev/null +++ b/coverage/core/CLTool.h.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - core/CLTool.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243470.6 %
Date:2024-02-22 21:58:45Functions:121580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6CLTool5parseIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD6CLToolD0Ev0
_ZNK4PLMD6CLTool11descriptionB5cxx11Ev0
_ZN4PLMD6CLTool11parseVectorIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE2
_ZN4PLMD6CLTool11parseVectorIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE40
_ZN4PLMD6CLTool5parseIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_40
_ZN4PLMD6CLTool5parseImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_80
_ZN4PLMD6CLTool11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RSt6vectorIT_SaISB_EE158
_ZN4PLMD6CLTool11parseVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE166
_ZN4PLMD6CLTool5parseIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_808
_ZN4PLMD6CLTool5parseIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_856
_ZN4PLMD6CLTool5parseIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1598
_ZN4PLMD6CLTool5parseIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1706
_ZN4PLMD6CLToolD2Ev3110
_ZN4PLMD6CLTool5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RT_22610
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.h.func.html b/coverage/core/CLTool.h.func.html new file mode 100644 index 000000000000..a60179a09ad4 --- /dev/null +++ b/coverage/core/CLTool.h.func.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - core/CLTool.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243470.6 %
Date:2024-02-22 21:58:45Functions:121580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6CLTool11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RSt6vectorIT_SaISB_EE158
_ZN4PLMD6CLTool11parseVectorIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE166
_ZN4PLMD6CLTool11parseVectorIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE40
_ZN4PLMD6CLTool11parseVectorIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISB_EE2
_ZN4PLMD6CLTool5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS7_RT_22610
_ZN4PLMD6CLTool5parseIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1706
_ZN4PLMD6CLTool5parseIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD6CLTool5parseIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1598
_ZN4PLMD6CLTool5parseIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_856
_ZN4PLMD6CLTool5parseImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_80
_ZN4PLMD6CLTool5parseIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_808
_ZN4PLMD6CLTool5parseIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_40
_ZN4PLMD6CLToolD0Ev0
_ZN4PLMD6CLToolD2Ev3110
_ZNK4PLMD6CLTool11descriptionB5cxx11Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLTool.h.gcov.html b/coverage/core/CLTool.h.gcov.html new file mode 100644 index 000000000000..7daed007ac46 --- /dev/null +++ b/coverage/core/CLTool.h.gcov.html @@ -0,0 +1,242 @@ + + + + + + + + LCOV - plumed test coverage - core/CLTool.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLTool.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:243470.6 %
Date:2024-02-22 21:58:45Functions:121580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_CLTool_h
+      23             : #define __PLUMED_core_CLTool_h
+      24             : #include <cstdio>
+      25             : #include <vector>
+      26             : #include <string>
+      27             : #include <cstdio>
+      28             : #include "tools/Tools.h"
+      29             : #include "tools/Keywords.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : class Communicator;
+      34             : 
+      35        6220 : class CLToolOptions {
+      36             :   friend class CLTool;
+      37             :   friend class CLToolRegister;
+      38             : private:
+      39             :   std::vector<std::string> line;
+      40             : /// The documentation for this command line tool
+      41             :   const Keywords& keys;
+      42             :   static Keywords emptyKeys;
+      43             : public:
+      44             :   explicit CLToolOptions(const std::string &name);
+      45             :   CLToolOptions(const CLToolOptions& co, const Keywords& k);
+      46             : };
+      47             : 
+      48             : /**
+      49             : \ingroup INHERIT
+      50             : This is the abstract base class to use for implementing new command line tool, within it there
+      51             : is \ref AddingACLTool "information" as to how to go about implemneting a new tool.
+      52             : */
+      53             : 
+      54             : class CLTool {
+      55             : private:
+      56             : /// The name of this command line tool
+      57             :   const std::string name;
+      58             : /// The list of keywords for this CLTool
+      59             :   const Keywords& keywords;
+      60             : /// The data read in from the command line stored in a map with the keywords
+      61             :   std::map<std::string,std::string> inputData;
+      62             : /// Read the arguments from the command line
+      63             :   bool readCommandLineArgs( int argc, char**argv, FILE*out );
+      64             : /// Read the arguments from an input file specified on the command line
+      65             :   bool readInputFile( int argc, char**argv, FILE* in, FILE*out );
+      66             : /// Set arguments from the default options provided to Keywords
+      67             :   void setRemainingToDefault(FILE* out);
+      68             : public:
+      69             : /// Set the input data:
+      70             :   void setInputData(const std::map<std::string,std::string>&inputData) {
+      71             :     this->inputData=inputData;
+      72           0 :   }
+      73             :   const std::map<std::string,std::string>&getInputData() {
+      74             :     return this->inputData;
+      75             :   }
+      76             : protected:
+      77             : /// Get the value of one of the command line arguments
+      78             :   template<class T>
+      79             :   bool parse(const std::string&key,T&t);
+      80             : /// Find out whether one of the command line flags is present or not
+      81             :   void parseFlag(const std::string&key,bool&t);
+      82             : /// Crash the command line tool with an error
+      83             :   [[noreturn]] void error(const std::string& msg);
+      84             :   template<class T>
+      85             :   bool parseVector(const std::string&key,std::vector<T>&t);
+      86             : public:
+      87             : /// How is the input specified on the command line or in an input file
+      88             :   enum {unset,commandline,ifile} inputdata;
+      89             : /// Create the help keywords
+      90             :   static void registerKeywords( Keywords& keys );
+      91             :   explicit CLTool(const CLToolOptions& co );
+      92             : /// Read the arguments from the command line
+      93             :   bool readInput( int argc, char**argv, FILE* in, FILE*out );
+      94             : /// virtual function mapping to the specific main for each tool
+      95             :   virtual int main( FILE* in, FILE*out, Communicator&pc )=0;
+      96             : /// virtual function returning a one-line descriptor for the tool
+      97           0 :   virtual std::string description()const {return "(no description available)";}
+      98             : /// virtual destructor to allow inheritance
+      99        3110 :   virtual ~CLTool() {}
+     100             : };
+     101             : 
+     102             : template<class T>
+     103       27698 : bool CLTool::parse(const std::string&key,T&t) {
+     104       27698 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     105       55396 :   if(keywords.style(key,"compulsory") ) {
+     106           0 :     if(inputData.count(key)==0) error("missing data for keyword " + key);
+     107        4114 :     bool check=Tools::convertNoexcept(inputData[key],t);
+     108        4114 :     if(!check) error("data input for keyword " + key + " has wrong type");
+     109             :     return true;
+     110             :   }
+     111       21739 :   if( inputData.count(key)==0 ) return false;
+     112        1845 :   Tools::convert(inputData[key],t);
+     113        1845 :   return true;
+     114             : }
+     115             : // very limited support and check: take more from core/Action.h parseVector
+     116             : template<class T>
+     117         366 : bool CLTool::parseVector(const std::string&key,std::vector<T>&t) {
+     118             : 
+     119             :   // Check keyword has been registered
+     120         366 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     121             :   // initial size
+     122         366 :   unsigned size=t.size();
+     123             :   bool skipcheck=false;
+     124         366 :   if(size==0) skipcheck=true; // if the vector in input has size zero, skip the check if size of input vector is the same of argument read
+     125             : 
+     126             :   // check if there is some value
+     127             : 
+     128         732 :   plumed_massert(inputData[key]!="false","compulsory keyword "+std::string(key)+"has no data");
+     129         366 :   std::vector<std::string> words=Tools::getWords(inputData[key],"\t\n ,");
+     130         366 :   t.resize(0);
+     131         366 :   if(words.size()==0)return false;
+     132             : 
+     133         773 :   for(unsigned i=0; i<words.size(); ++i) {
+     134             :     T v;
+     135         487 :     Tools::convert(words[i],v);
+     136         487 :     t.push_back(v);
+     137             :   }
+     138             :   // check the size
+     139         286 :   if( !skipcheck && t.size()!=size ) {
+     140           0 :     plumed_merror("vector read in for keyword  "+key+" has wrong size" );
+     141             :   }
+     142             :   std::string def;
+     143             :   T val;
+     144         572 :   if ( keywords.style(key,"compulsory") && t.size()==0 ) {
+     145           0 :     if( keywords.getDefaultValue(key,def) ) {
+     146           0 :       if( def.length()==0 || !Tools::convertNoexcept(def,val) ) {
+     147           0 :         plumed_merror("ERROR in keyword "+key+ " has weird default value" );
+     148             :       } else {
+     149             :         // GB: before it was like this, but clearly if t.size()==0 this was not doing anything
+     150             :         // for(unsigned i=0; i<t.size(); ++i) t[i]=val;
+     151           0 :         t.resize(1);
+     152           0 :         t[0]=val;
+     153             :       }
+     154             :     } else {
+     155           0 :       plumed_merror("keyword " + key + " is compulsory for this action");
+     156             :     }
+     157             :   }
+     158             :   return true;
+     159         366 : }
+     160             : 
+     161             : 
+     162             : 
+     163             : }
+     164             : 
+     165             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolMain.cpp.func-sort-c.html b/coverage/core/CLToolMain.cpp.func-sort-c.html new file mode 100644 index 000000000000..e83e0033774a --- /dev/null +++ b/coverage/core/CLToolMain.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - core/CLToolMain.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolMain.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10913580.7 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10CLToolMain3runEiPPcP8_IO_FILES4_RNS_12CommunicatorE4228
_ZN4PLMD10CLToolMainC2Ev4228
_ZN4PLMD10CLToolMainD0Ev4228
_ZN4PLMD10CLToolMainD2Ev4228
_ZN4PLMD10CLToolMain3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE12941
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolMain.cpp.func.html b/coverage/core/CLToolMain.cpp.func.html new file mode 100644 index 000000000000..953d6cd962a4 --- /dev/null +++ b/coverage/core/CLToolMain.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - core/CLToolMain.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolMain.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10913580.7 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10CLToolMain3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE12941
_ZN4PLMD10CLToolMain3runEiPPcP8_IO_FILES4_RNS_12CommunicatorE4228
_ZN4PLMD10CLToolMainC2Ev4228
_ZN4PLMD10CLToolMainD0Ev4228
_ZN4PLMD10CLToolMainD2Ev4228
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolMain.cpp.gcov.html b/coverage/core/CLToolMain.cpp.gcov.html new file mode 100644 index 000000000000..5e6c649232d3 --- /dev/null +++ b/coverage/core/CLToolMain.cpp.gcov.html @@ -0,0 +1,368 @@ + + + + + + + + LCOV - plumed test coverage - core/CLToolMain.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolMain.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10913580.7 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLToolMain.h"
+      23             : #include "config/Config.h"
+      24             : #include "tools/Exception.h"
+      25             : #include "tools/Communicator.h"
+      26             : #include "CLTool.h"
+      27             : #include "CLToolRegister.h"
+      28             : #include "tools/Tools.h"
+      29             : #include "tools/DLLoader.h"
+      30             : #include <string>
+      31             : #include <cstdlib>
+      32             : #include <cstdio>
+      33             : #include <iostream>
+      34             : #include <algorithm>
+      35             : #include <memory>
+      36             : 
+      37             : namespace PLMD {
+      38             : 
+      39        4228 : CLToolMain::CLToolMain():
+      40        4228 :   argc(0),
+      41        4228 :   in(stdin),
+      42        4228 :   out(stdout)
+      43             : {
+      44        4228 : }
+      45             : 
+      46        8456 : CLToolMain::~CLToolMain() {
+      47             : // empty destructor to delete unique_ptr
+      48        8456 : }
+      49             : 
+      50             : #define CHECK_NULL(val,word) plumed_assert(val) << "NULL pointer received in cmd(\"CLTool " << word <<  "\"";
+      51             : 
+      52       12941 : void CLToolMain::cmd(std::string_view word,const TypesafePtr & val) {
+      53             : 
+      54             : // Enumerate all possible commands:
+      55             :   enum {
+      56             : #include "CLToolMainEnum.inc"
+      57             :   };
+      58             : 
+      59             : // Static object (initialized once) containing the map of commands:
+      60             :   const static Tools::FastStringUnorderedMap<int> word_map = {
+      61             : #include "CLToolMainMap.inc"
+      62       12941 :   };
+      63             : 
+      64             :   gch::small_vector<std::string_view> words;
+      65       12941 :   Tools::getWordsSimple(words,word);
+      66       12941 :   unsigned nw=words.size();
+      67       12941 :   if(nw==0) {
+      68             :     // do nothing
+      69             :   } else {
+      70             :     int iword=-1;
+      71             :     const char*const*v;
+      72             :     const char*vv;
+      73             :     const auto it=word_map.find(words[0]);
+      74       12941 :     if(it!=word_map.end()) iword=it->second;
+      75       12941 :     switch(iword) {
+      76             :     case cmd_setArgc:
+      77        4144 :       CHECK_NULL(val,word);
+      78        4144 :       argc=val.get<int>();
+      79        4144 :       break;
+      80             :     case cmd_setArgv:
+      81        4144 :       CHECK_NULL(val,word);
+      82        4144 :       v=val.get<const char*const*>(argc);
+      83       26856 :       for(int i=0; i<argc; ++i) argv.push_back(std::string(v[i]));
+      84             :       break;
+      85             :     case cmd_setArgvLine:
+      86          84 :       CHECK_NULL(val,word);
+      87             :       vv=val.get<const char*>();
+      88          84 :       argv=Tools::getWords(vv);
+      89          84 :       break;
+      90             :     case cmd_setIn:
+      91           0 :       CHECK_NULL(val,word);
+      92           0 :       in=val.get<FILE*>();
+      93           0 :       break;
+      94             :     case cmd_setOut:
+      95           1 :       CHECK_NULL(val,word);
+      96           1 :       out=val.get<FILE*>();
+      97           1 :       break;
+      98         340 :     case cmd_setMPIComm:
+      99         340 :       comm.Set_comm(val);
+     100             :       break;
+     101           0 :     case cmd_setMPIFComm:
+     102           0 :       comm.Set_fcomm(val);
+     103             :       break;
+     104             :     case cmd_run:
+     105        4228 :       CHECK_NULL(val,word);
+     106        4228 :       argc=argv.size();
+     107             :       {
+     108       27428 :         int n=0; for(int i=0; i<argc; ++i) n+=argv[i].length()+1;
+     109        4228 :         std::vector<char> args(n);
+     110        4228 :         std::vector<char*> vvv(argc);
+     111             :         char* ptr=&args[0];
+     112       27428 :         for(int i=0; i<argc; ++i) {
+     113       23200 :           vvv[i]=ptr;
+     114      200180 :           for(unsigned c=0; c<argv[i].length(); ++c) {
+     115      176980 :             *ptr=argv[i][c]; ptr++;
+     116             :           }
+     117       23200 :           *ptr=0; ptr++;
+     118             :         }
+     119        4228 :         val.set(int(run(argc,&vvv[0],in,out,comm)));
+     120             :       }
+     121        4228 :       break;
+     122           0 :     default:
+     123           0 :       plumed_error() << "cannot interpret cmd(\"CLTool " << word << "\"). check plumed developers manual to see the available commands.";
+     124             :       break;
+     125             :     }
+     126             :   }
+     127       12941 : }
+     128             : 
+     129             : /**
+     130             : This is the entry point to the command line tools
+     131             : included in the plumed library.
+     132             : */
+     133             : 
+     134        4228 : int CLToolMain::run(int argc, char **argv,FILE*in,FILE*out,Communicator& pc) {
+     135             :   int i;
+     136             :   bool printhelp=false;
+     137             : 
+     138        4228 :   DLLoader dlloader;
+     139             : 
+     140        4228 :   std::string root=config::getPlumedRoot();
+     141             : 
+     142             :   bool standalone_executable=false;
+     143             : 
+     144             : // Start parsing options
+     145        4228 :   std::string prefix("");
+     146        4228 :   std::string a("");
+     147        8032 :   for(i=1; i<argc; i++) {
+     148       16064 :     a=prefix+argv[i];
+     149        8032 :     if(a.length()==0) continue;
+     150       24096 :     if(a=="help" || a=="-h" || a=="--help") {
+     151             :       printhelp=true;
+     152             :       break;
+     153        8028 :     } else if(a=="--has-mpi") {
+     154           0 :       if(Communicator::initialized()) return 0;
+     155           0 :       else return 1;
+     156        8028 :     } else if(a=="--has-cregex") {
+     157           0 :       return (config::hasCregex()?0:1);
+     158        8028 :     } else if(a=="--has-dlopen") {
+     159           0 :       return (config::hasDlopen()?0:1);
+     160        8028 :     } else if(a=="--has-molfile") {
+     161           0 :       return (config::hasMolfile()?0:1);
+     162        8028 :     } else if(a=="--has-external-molfile") {
+     163           0 :       return (config::hasExternalMolfile()?0:1);
+     164        8028 :     } else if(a=="--has-zlib") {
+     165           0 :       return (config::hasZlib()?0:1);
+     166        8028 :     } else if(a=="--has-xdrfile") {
+     167             :       return 0; // always ok
+     168        8028 :     } else if(a=="--is-installed") {
+     169         641 :       return (config::isInstalled()?0:1);
+     170        7387 :     } else if(a=="--no-mpi") {
+     171             : // this is ignored, as it is parsed in main
+     172        3804 :       continue;
+     173        3583 :     } else if(a=="--mpi") {
+     174             : // this is ignored, as it is parsed in main
+     175           0 :       continue;
+     176        3583 :     } else if(a=="--standalone-executable") {
+     177             :       standalone_executable=true;
+     178        7166 :     } else if(Tools::startWith(a,"--load=")) {
+     179           0 :       a.erase(0,a.find("=")+1);
+     180             :       prefix="";
+     181           0 :       void *p=dlloader.load(a);
+     182           0 :       if(!p) {
+     183           0 :         std::fprintf(stderr,"ERROR: cannot load library %s\n",a.c_str());
+     184           0 :         std::fprintf(stderr,"ERROR: %s\n",dlloader.error().c_str());
+     185             :         return 1;
+     186             :       }
+     187        3583 :     } else if(a=="--load") {
+     188             :       prefix="--load=";
+     189        3583 :     } else if(a[0]=='-') {
+     190           0 :       std::string msg="ERROR: Unknown option " +a;
+     191           0 :       std::fprintf(stderr,"%s\n",msg.c_str());
+     192             :       return 1;
+     193             :     } else break;
+     194             :   }
+     195             : 
+     196             : // Check if plumedRoot/patches/ directory exists (as a further check)
+     197        3587 :   if(!standalone_executable) {
+     198        3587 :     std::vector<std::string> files=Tools::ls(root);
+     199        3587 :     if(find(files.begin(),files.end(),"patches")==files.end()) {
+     200             :       std::string msg=
+     201           0 :         "WARNING: I cannot find "+root+"/patches/ directory. Set PLUMED_ROOT or reinstall PLUMED\n\n";
+     202           0 :       std::fprintf(stderr,"%s",msg.c_str());
+     203             :     }
+     204        3587 :   }
+     205             : 
+     206             : // Build list of available C++ tools:
+     207        3587 :   std::vector<std::string> availableCxx=cltoolRegister().list();
+     208             : // Build list of available shell tools:
+     209             :   std::vector<std::string> availableShell;
+     210        3587 :   if(!standalone_executable) {
+     211             :     std::vector<std::string> tmp;
+     212        7174 :     tmp=Tools::ls(std::string(root+"/scripts"));
+     213       28696 :     for(unsigned j=0; j<tmp.size(); ++j) {
+     214       25109 :       size_t ff=tmp[j].find(".sh");
+     215       25109 :       if(ff==std::string::npos) tmp[j].erase();
+     216       25109 :       else                 tmp[j].erase(ff);
+     217             :     }
+     218       28696 :     for(unsigned j=0; j<tmp.size(); ++j) if(tmp[j].length()>0) availableShell.push_back(tmp[j]);
+     219        3587 :   }
+     220             : 
+     221        3587 :   if(printhelp) {
+     222             :     std::string msg=
+     223             :       "Usage: plumed [options] [command] [command options]\n"
+     224             :       "  plumed [command] -h|--help: to print help for a specific command\n"
+     225             :       "Options:\n"
+     226             :       "  [help|-h|--help]          : to print this help\n"
+     227             :       "  [--is-installed]          : fails if plumed is not installed\n"
+     228             :       "  [--has-mpi]               : fails if plumed is running without MPI\n"
+     229             :       "  [--has-dlopen]            : fails if plumed is compiled without dlopen\n"
+     230             :       "  [--load LIB]              : loads a shared object (typically a plugin library)\n"
+     231             :       "  [--standalone-executable] : tells plumed not to look for commands implemented as scripts\n"
+     232           4 :       "Commands:\n";
+     233             :     std::fprintf(out,"%s",msg.c_str());
+     234          72 :     for(unsigned j=0; j<availableCxx.size(); ++j) {
+     235         136 :       auto cl=cltoolRegister().create(CLToolOptions(availableCxx[j]));
+     236          68 :       plumed_assert(cl);
+     237         136 :       std::string manual=availableCxx[j]+" : "+cl->description();
+     238             :       std::fprintf(out,"  plumed %s\n", manual.c_str());
+     239          68 :     }
+     240          32 :     for(unsigned j=0; j<availableShell.size(); ++j) {
+     241             :       std::string manual;
+     242             : #ifdef __PLUMED_HAS_POPEN
+     243          56 :       std::string cmd=config::getEnvCommand()+" \""+root+"/scripts/"+availableShell[j]+".sh\" --description";
+     244          28 :       FILE *fp=popen(cmd.c_str(),"r");
+     245             :       std::string line;
+     246          64 :       while(Tools::getline(fp,line))manual+=line;
+     247          28 :       pclose(fp);
+     248             : #else
+     249             :       manual="(doc not avail)";
+     250             : #endif
+     251          56 :       manual= availableShell[j]+" : "+manual;
+     252             :       std::fprintf(out,"  plumed %s\n", manual.c_str());
+     253             :     }
+     254             :     return 0;
+     255             :   }
+     256        3583 :   if(i==argc) {
+     257             :     std::fprintf(out,"%s","Nothing to do. Use 'plumed help' for help\n");
+     258             :     return 0;
+     259             :   }
+     260             : 
+     261             : // this is the command to be executed:
+     262        3583 :   std::string command(argv[i]);
+     263             : 
+     264        3583 :   if(find(availableCxx.begin(),availableCxx.end(),command)!=availableCxx.end()) {
+     265        6084 :     auto cl=cltoolRegister().create(CLToolOptions(command));
+     266        3042 :     plumed_assert(cl);
+     267             :     // Read the command line options (returns false if we are just printing help)
+     268        3042 :     if( !cl->readInput( argc-i,&argv[i],in,out ) ) { return 0; }
+     269        3042 :     int ret=cl->main(in,out,pc);
+     270             :     return ret;
+     271        3042 :   }
+     272             : 
+     273         541 :   if(find(availableShell.begin(),availableShell.end(),command)!=availableShell.end()) {
+     274         541 :     plumed_massert(in==stdin,"shell tools can only work on stdin");
+     275         541 :     plumed_massert(out==stdout,"shell tools can only work on stdin");
+     276        1082 :     std::string cmd=config::getEnvCommand()+" \""+root+"/scripts/"+command+".sh\"";
+     277        2050 :     for(int j=i+1; j<argc; j++) cmd+=std::string(" ")+argv[j];
+     278         541 :     int r=std::system(cmd.c_str());
+     279             : // this is necessary since system seems to return numbers which are multiple
+     280             : // of 256. this would make the interpretation by the shell wrong
+     281             : // I just return 1 in case of failure and 0 in case of success
+     282         541 :     if(r!=0) return 1;
+     283         429 :     else return 0;
+     284             :   }
+     285             : 
+     286           0 :   std::string msg="ERROR: unknown command " + command + ". Use 'plumed help' for help";
+     287           0 :   std::fprintf(stderr,"%s\n",msg.c_str());
+     288             :   return 1;
+     289             : 
+     290        7815 : }
+     291             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.cpp.func-sort-c.html b/coverage/core/CLToolRegister.cpp.func-sort-c.html new file mode 100644 index 000000000000..3626a7971479 --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - core/CLToolRegister.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:395867.2 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD14CLToolRegister7getKeysERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD14CLToolRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb1
_ZN4PLMDlsERSoRKNS_14CLToolRegisterE299
_ZN4PLMD14CLToolRegister6createERKNS_13CLToolOptionsE3110
_ZNK4PLMD14CLToolRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3111
_ZNK4PLMD14CLToolRegister4listB5cxx11Ev3886
_ZN4PLMD14CLToolRegisterD2Ev4187
_ZN4PLMD14CLToolRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS8_EERKNS_13CLToolOptionsEEPFvRNS_8KeywordsEE71179
_ZN4PLMD14CLToolRegister6removeEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS2_EERKNS_13CLToolOptionsEE71179
_ZN4PLMD14cltoolRegisterEv149355
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.cpp.func.html b/coverage/core/CLToolRegister.cpp.func.html new file mode 100644 index 000000000000..8a9129b3d584 --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - core/CLToolRegister.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:395867.2 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14CLToolRegister11printManualERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb1
_ZN4PLMD14CLToolRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS8_EERKNS_13CLToolOptionsEEPFvRNS_8KeywordsEE71179
_ZN4PLMD14CLToolRegister6createERKNS_13CLToolOptionsE3110
_ZN4PLMD14CLToolRegister6removeEPFSt10unique_ptrINS_6CLToolESt14default_deleteIS2_EERKNS_13CLToolOptionsEE71179
_ZN4PLMD14CLToolRegisterD2Ev4187
_ZN4PLMD14cltoolRegisterEv149355
_ZN4PLMDlsERSoRKNS_14CLToolRegisterE299
_ZNK4PLMD14CLToolRegister4listB5cxx11Ev3886
_ZNK4PLMD14CLToolRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3111
_ZNK4PLMD14CLToolRegister7getKeysERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/CLToolRegister.cpp.gcov.html b/coverage/core/CLToolRegister.cpp.gcov.html new file mode 100644 index 000000000000..cd6d4a40525b --- /dev/null +++ b/coverage/core/CLToolRegister.cpp.gcov.html @@ -0,0 +1,202 @@ + + + + + + + + LCOV - plumed test coverage - core/CLToolRegister.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - CLToolRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:395867.2 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CLToolRegister.h"
+      23             : #include "tools/Tools.h"
+      24             : #include "CLTool.h"
+      25             : #include <algorithm>
+      26             : #include <iostream>
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31        4187 : CLToolRegister::~CLToolRegister() {
+      32        4187 :   if(m.size()>0) {
+      33           0 :     std::string names="";
+      34           0 :     for(const auto & p : m) names+=p.first+" ";
+      35           0 :     std::cerr<<"WARNING: CLTools "+ names +" has not been properly unregistered. This might lead to memory leak!!\n";
+      36             :   }
+      37        4187 : }
+      38             : 
+      39      149355 : CLToolRegister& cltoolRegister() {
+      40      149355 :   static CLToolRegister ans;
+      41      149355 :   return ans;
+      42             : }
+      43             : 
+      44       71179 : void CLToolRegister::remove(creator_pointer f) {
+      45      556871 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      46      556871 :     if((*p).second==f) {
+      47       71179 :       m.erase(p); break;
+      48             :     }
+      49             :   }
+      50       71179 : }
+      51             : 
+      52       71179 : void CLToolRegister::add(std::string key,creator_pointer f,keywords_pointer kf) {
+      53             :   if(m.count(key)) {
+      54             :     m.erase(key);
+      55           0 :     disabled.insert(key);
+      56             :   } else {
+      57       71179 :     m.insert(std::pair<std::string,creator_pointer>(key,f));
+      58       71179 :     Keywords keys; kf(keys);
+      59       71179 :     mk.insert(std::pair<std::string,Keywords>(key,keys));
+      60       71179 :   };
+      61       71179 : }
+      62             : 
+      63        3111 : bool CLToolRegister::check(const std::string & key)const {
+      64        3110 :   if(m.count(key)>0) return true;
+      65             :   return false;
+      66             : }
+      67             : 
+      68        3110 : std::unique_ptr<CLTool> CLToolRegister::create(const CLToolOptions&ao) {
+      69        3110 :   if(ao.line.size()<1)return NULL;
+      70        3110 :   std::unique_ptr<CLTool> cltool;
+      71        3110 :   if(check(ao.line[0])) {
+      72        3110 :     CLToolOptions nao( ao,mk[ao.line[0]] );
+      73        6220 :     cltool=m[ao.line[0]](nao);
+      74             :   }
+      75             :   return cltool;
+      76        3110 : }
+      77             : 
+      78             : 
+      79         299 : std::ostream & operator<<(std::ostream &log,const CLToolRegister&ar) {
+      80         299 :   std::vector<std::string> s(ar.list());
+      81        5382 :   for(unsigned i=0; i<s.size(); i++) log<<"  "<<s[i]<<"\n";
+      82         299 :   if(!ar.disabled.empty()) {
+      83           0 :     s.assign(ar.disabled.size(),"");
+      84           0 :     std::copy(ar.disabled.begin(),ar.disabled.end(),s.begin());
+      85           0 :     std::sort(s.begin(),s.end());
+      86           0 :     log<<"+++++++ WARNING +++++++\n";
+      87           0 :     log<<"The following keywords have been registered more than once and will be disabled:\n";
+      88           0 :     for(unsigned i=0; i<s.size(); i++) log<<"  - "<<s[i]<<"\n";
+      89           0 :     log<<"+++++++ END WARNING +++++++\n";
+      90             :   };
+      91         299 :   return log;
+      92         299 : }
+      93             : 
+      94           1 : bool CLToolRegister::printManual( const std::string& cltool, const bool& spelling ) {
+      95           1 :   if( spelling && check(cltool) ) {
+      96           0 :     mk[cltool].print_spelling();
+      97           0 :     return true;
+      98           1 :   } else if ( check(cltool) ) {
+      99           0 :     mk[cltool].print_html();
+     100           0 :     return true;
+     101             :   } else {
+     102             :     return false;
+     103             :   }
+     104             : }
+     105             : 
+     106           0 : std::vector<std::string> CLToolRegister::getKeys(const std::string& cltool)const {
+     107           0 :   if ( check(cltool) ) {
+     108             :     return mk.find(cltool)->second.getKeys();
+     109             :   } else {
+     110             :     std::vector<std::string> empty;
+     111             :     return empty;
+     112           0 :   }
+     113             : }
+     114             : 
+     115             : 
+     116        3886 : std::vector<std::string> CLToolRegister::list()const {
+     117             :   std::vector<std::string> s;
+     118       69948 :   for(const auto & it : m) s.push_back(it.first);
+     119        3886 :   std::sort(s.begin(),s.end());
+     120        3886 :   return s;
+     121           0 : }
+     122             : 
+     123             : 
+     124             : 
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.cpp.func-sort-c.html b/coverage/core/Colvar.cpp.func-sort-c.html new file mode 100644 index 000000000000..4c5f3b99651c --- /dev/null +++ b/coverage/core/Colvar.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/Colvar.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Colvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6ColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD6ColvarC2ERKNS_13ActionOptionsE1850
_ZN4PLMD6Colvar16registerKeywordsERNS_8KeywordsE1914
_ZN4PLMD6Colvar12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE2281
_ZN4PLMD6Colvar5applyEv111495
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEPNS_5ValueE191152
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.cpp.func.html b/coverage/core/Colvar.cpp.func.html new file mode 100644 index 000000000000..0fef9ca52cc7 --- /dev/null +++ b/coverage/core/Colvar.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/Colvar.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Colvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Colvar12requestAtomsERKSt6vectorINS_10AtomNumberESaIS2_EE2281
_ZN4PLMD6Colvar16registerKeywordsERNS_8KeywordsE1914
_ZN4PLMD6Colvar22setBoxDerivativesNoPbcEPNS_5ValueE191152
_ZN4PLMD6Colvar5applyEv111495
_ZN4PLMD6ColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD6ColvarC2ERKNS_13ActionOptionsE1850
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.cpp.gcov.html b/coverage/core/Colvar.cpp.gcov.html new file mode 100644 index 000000000000..860ec0780e17 --- /dev/null +++ b/coverage/core/Colvar.cpp.gcov.html @@ -0,0 +1,143 @@ + + + + + + + + LCOV - plumed test coverage - core/Colvar.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Colvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Colvar.h"
+      23             : #include "tools/OpenMP.h"
+      24             : #include <vector>
+      25             : #include <string>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29        1850 : Colvar::Colvar(const ActionOptions&ao):
+      30             :   Action(ao),
+      31             :   ActionAtomistic(ao),
+      32        1850 :   ActionWithValue(ao)
+      33             : {
+      34        1850 : }
+      35             : 
+      36        1914 : void Colvar::registerKeywords( Keywords& keys ) {
+      37        1914 :   Action::registerKeywords( keys );
+      38        1914 :   ActionWithValue::registerKeywords( keys );
+      39        1914 :   ActionAtomistic::registerKeywords( keys );
+      40        3828 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      41        1914 : }
+      42             : 
+      43        2281 : void Colvar::requestAtoms(const std::vector<AtomNumber> & a) {
+      44             : // Tell actionAtomistic what atoms we are getting
+      45        2281 :   ActionAtomistic::requestAtoms(a);
+      46             : // Resize the derivatives of all atoms
+      47        6003 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(3*a.size()+9);
+      48        2280 : }
+      49             : 
+      50      111495 : void Colvar::apply() {
+      51      111495 :   if( !checkForForces() ) return ;
+      52       76822 :   unsigned ind=0;
+      53       76822 :   if( getNumberOfAtoms()>0 ) setForcesOnAtoms( getForcesToApply(), ind );
+      54        2511 :   else setForcesOnCell( getForcesToApply(), ind );
+      55             : }
+      56             : 
+      57      191152 : void Colvar::setBoxDerivativesNoPbc(Value* v) {
+      58      191152 :   Tensor virial;
+      59             :   unsigned nat=getNumberOfAtoms();
+      60    33630224 :   for(unsigned i=0; i<nat; i++) virial-=Tensor(getPosition(i),
+      61    16719536 :                                           Vector(v->getDerivative(3*i+0),
+      62             :                                               v->getDerivative(3*i+1),
+      63    33439072 :                                               v->getDerivative(3*i+2)));
+      64      191152 :   setBoxDerivatives(v,virial);
+      65      191152 : }
+      66             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.h.func-sort-c.html b/coverage/core/Colvar.h.func-sort-c.html new file mode 100644 index 000000000000..9663d1667ceb --- /dev/null +++ b/coverage/core/Colvar.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - core/Colvar.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Colvar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6ColvarD2Ev1847
_ZN4PLMD6Colvar22getNumberOfDerivativesEv116400
_ZN4PLMD6Colvar17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE228967
_ZN4PLMD6Colvar19setAtomsDerivativesEPNS_5ValueEiRKNS_13VectorGenericILj3EEE18212005
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.h.func.html b/coverage/core/Colvar.h.func.html new file mode 100644 index 000000000000..08794655c0fd --- /dev/null +++ b/coverage/core/Colvar.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - core/Colvar.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Colvar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Colvar17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE228967
_ZN4PLMD6Colvar19setAtomsDerivativesEPNS_5ValueEiRKNS_13VectorGenericILj3EEE18212005
_ZN4PLMD6Colvar22getNumberOfDerivativesEv116400
_ZN4PLMD6ColvarD2Ev1847
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Colvar.h.gcov.html b/coverage/core/Colvar.h.gcov.html new file mode 100644 index 000000000000..2f6ae41e033a --- /dev/null +++ b/coverage/core/Colvar.h.gcov.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - core/Colvar.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Colvar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_Colvar_h
+      23             : #define __PLUMED_core_Colvar_h
+      24             : 
+      25             : #include "ActionAtomistic.h"
+      26             : #include "ActionWithValue.h"
+      27             : #include <vector>
+      28             : 
+      29             : #define PLUMED_COLVAR_INIT(ao) Action(ao),Colvar(ao)
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /**
+      34             : \ingroup INHERIT
+      35             : This is the abstract base class to use for implementing new collective variables, within it there is
+      36             : \ref AddingAColvar "information" as to how to go about implementing a new CV.
+      37             : */
+      38             : 
+      39             : class Colvar :
+      40             :   public ActionAtomistic,
+      41             :   public ActionWithValue
+      42             : {
+      43             : private:
+      44             : protected:
+      45             :   void requestAtoms(const std::vector<AtomNumber> & a);
+      46             : // Set the derivatives for a particular atom equal to the input Vector
+      47             : // This routine is called setAtomsDerivatives because not because you
+      48             : // are setting the derivative of many atoms but because you are setting
+      49             : // the derivatives of a particular atom.  The s is an apostrophe s
+      50             : // but you can't put apostrophes in function names
+      51             :   void           setAtomsDerivatives(int,const Vector&);
+      52             :   void           setAtomsDerivatives(Value*,int,const Vector&);
+      53             :   void           setBoxDerivatives(const Tensor&);
+      54             :   void           setBoxDerivatives(Value*,const Tensor&);
+      55             :   const Tensor & getBoxDerivatives()const;
+      56             :   const double & getForce()const;
+      57             :   void apply() override;
+      58             : /// Set box derivatives automatically.
+      59             : /// It should be called after the setAtomsDerivatives has been used for all
+      60             : /// single atoms.
+      61             : /// \warning It only works for collective variable NOT using PBCs!
+      62             :   void           setBoxDerivativesNoPbc();
+      63             :   void           setBoxDerivativesNoPbc(Value*);
+      64             : public:
+      65             :   explicit Colvar(const ActionOptions&);
+      66        1847 :   ~Colvar() {}
+      67             :   static void registerKeywords( Keywords& keys );
+      68             :   unsigned getNumberOfDerivatives() override;
+      69             : };
+      70             : 
+      71             : inline
+      72    18212005 : void Colvar::setAtomsDerivatives(Value*v,int i,const Vector&d) {
+      73    18212005 :   v->addDerivative(3*i+0,d[0]);
+      74    18212005 :   v->addDerivative(3*i+1,d[1]);
+      75    18212005 :   v->addDerivative(3*i+2,d[2]);
+      76    18212005 : }
+      77             : 
+      78             : 
+      79             : inline
+      80      228967 : void Colvar::setBoxDerivatives(Value* v,const Tensor&d) {
+      81             :   unsigned nat=getNumberOfAtoms();
+      82      228967 :   v->addDerivative(3*nat+0,d(0,0));
+      83      228967 :   v->addDerivative(3*nat+1,d(0,1));
+      84      228967 :   v->addDerivative(3*nat+2,d(0,2));
+      85      228967 :   v->addDerivative(3*nat+3,d(1,0));
+      86      228967 :   v->addDerivative(3*nat+4,d(1,1));
+      87      228967 :   v->addDerivative(3*nat+5,d(1,2));
+      88      228967 :   v->addDerivative(3*nat+6,d(2,0));
+      89      228967 :   v->addDerivative(3*nat+7,d(2,1));
+      90      228967 :   v->addDerivative(3*nat+8,d(2,2));
+      91      228967 : }
+      92             : 
+      93             : inline
+      94             : void Colvar::setAtomsDerivatives(int i,const Vector&d) {
+      95    16331220 :   setAtomsDerivatives(getPntrToValue(),i,d);
+      96             : }
+      97             : 
+      98             : inline
+      99             : void Colvar::setBoxDerivatives(const Tensor&d) {
+     100       12402 :   setBoxDerivatives(getPntrToValue(),d);
+     101        2210 : }
+     102             : 
+     103             : inline
+     104             : void Colvar::setBoxDerivativesNoPbc() {
+     105      119765 :   setBoxDerivativesNoPbc(getPntrToValue());
+     106        1010 : }
+     107             : 
+     108             : inline
+     109      116400 : unsigned Colvar::getNumberOfDerivatives() {
+     110      116400 :   return 3*getNumberOfAtoms() + 9;
+     111             : }
+     112             : 
+     113             : 
+     114             : }
+     115             : 
+     116             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingObject.cpp.func-sort-c.html b/coverage/core/DataPassingObject.cpp.func-sort-c.html new file mode 100644 index 000000000000..05677b00fccb --- /dev/null +++ b/coverage/core/DataPassingObject.cpp.func-sort-c.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:657685.5 %
Date:2024-02-22 21:58:45Functions:142948.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD22DataPassingObjectTypedIfE10share_dataERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE10share_dataERKjS3_PNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE13rescale_forceERKjRKdPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE15setForcePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEE0
_ZN4PLMD22DataPassingObjectTypedIfE15setValuePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEERKb0
_ZN4PLMD22DataPassingObjectTypedIfE17saveValueAsDoubleERKNS_11TypesafePtrE0
_ZN4PLMD22DataPassingObjectTypedIfE7setDataEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceERKSt6vectorIiSaIiEEPNS_5ValueE0
_ZN4PLMDL10getPointerIKfEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSB_RPT_0
_ZN4PLMDL10getPointerIfEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSA_RPT_0
_ZNK4PLMD22DataPassingObjectTypedIdE9MD2doubleERKNS_11TypesafePtrE0
_ZNK4PLMD22DataPassingObjectTypedIfE10share_dataERSt6vectorIdSaIdEE0
_ZNK4PLMD22DataPassingObjectTypedIfE9MD2doubleERKNS_11TypesafePtrE0
_ZN4PLMD22DataPassingObjectTypedIdE13rescale_forceERKjRKdPNS_5ValueE150
_ZN4PLMD22DataPassingObjectTypedIdE7setDataEPNS_5ValueE670
_ZNK4PLMD22DataPassingObjectTypedIdE10share_dataERSt6vectorIdSaIdEE1350
_ZN4PLMD22DataPassingObjectTypedIdE17saveValueAsDoubleERKNS_11TypesafePtrE4918
_ZN4PLMD17DataPassingObject6createEj6651
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceEPNS_5ValueE18339
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorIiSaIiEEPNS_5ValueE34425
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE45588
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE53945
_ZN4PLMDL10getPointerIdEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSA_RPT_98462
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKjS3_PNS_5ValueE161223
_ZN4PLMDL10getPointerIKdEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSB_RPT_210578
_ZN4PLMD22DataPassingObjectTypedIdE15setForcePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEE213206
_ZN4PLMD22DataPassingObjectTypedIdE15setValuePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEERKb320511
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingObject.cpp.func.html b/coverage/core/DataPassingObject.cpp.func.html new file mode 100644 index 000000000000..7d0eff47407d --- /dev/null +++ b/coverage/core/DataPassingObject.cpp.func.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:657685.5 %
Date:2024-02-22 21:58:45Functions:142948.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17DataPassingObject6createEj6651
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE53945
_ZN4PLMD22DataPassingObjectTypedIdE10share_dataERKjS3_PNS_5ValueE161223
_ZN4PLMD22DataPassingObjectTypedIdE13rescale_forceERKjRKdPNS_5ValueE150
_ZN4PLMD22DataPassingObjectTypedIdE15setForcePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEE213206
_ZN4PLMD22DataPassingObjectTypedIdE15setValuePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEERKb320511
_ZN4PLMD22DataPassingObjectTypedIdE17saveValueAsDoubleERKNS_11TypesafePtrE4918
_ZN4PLMD22DataPassingObjectTypedIdE7setDataEPNS_5ValueE670
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceEPNS_5ValueE18339
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE45588
_ZN4PLMD22DataPassingObjectTypedIdE9add_forceERKSt6vectorIiSaIiEEPNS_5ValueE34425
_ZN4PLMD22DataPassingObjectTypedIfE10share_dataERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE10share_dataERKjS3_PNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE13rescale_forceERKjRKdPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE15setForcePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEE0
_ZN4PLMD22DataPassingObjectTypedIfE15setValuePointerERKNS_11TypesafePtrERKSt6vectorIjSaIjEERKb0
_ZN4PLMD22DataPassingObjectTypedIfE17saveValueAsDoubleERKNS_11TypesafePtrE0
_ZN4PLMD22DataPassingObjectTypedIfE7setDataEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceERKSt6vectorINS_10AtomNumberESaIS3_EERKS2_IjSaIjEEPNS_5ValueE0
_ZN4PLMD22DataPassingObjectTypedIfE9add_forceERKSt6vectorIiSaIiEEPNS_5ValueE0
_ZN4PLMDL10getPointerIKdEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSB_RPT_210578
_ZN4PLMDL10getPointerIKfEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSB_RPT_0
_ZN4PLMDL10getPointerIdEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSA_RPT_98462
_ZN4PLMDL10getPointerIfEEvRKNS_11TypesafePtrERKSt6vectorIjSaIjEERKjSA_RPT_0
_ZNK4PLMD22DataPassingObjectTypedIdE10share_dataERSt6vectorIdSaIdEE1350
_ZNK4PLMD22DataPassingObjectTypedIdE9MD2doubleERKNS_11TypesafePtrE0
_ZNK4PLMD22DataPassingObjectTypedIfE10share_dataERSt6vectorIdSaIdEE0
_ZNK4PLMD22DataPassingObjectTypedIfE9MD2doubleERKNS_11TypesafePtrE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingObject.cpp.gcov.html b/coverage/core/DataPassingObject.cpp.gcov.html new file mode 100644 index 000000000000..960616ff0656 --- /dev/null +++ b/coverage/core/DataPassingObject.cpp.gcov.html @@ -0,0 +1,271 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingObject.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:657685.5 %
Date:2024-02-22 21:58:45Functions:142948.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DataPassingObject.h"
+      23             : #include "tools/OpenMP.h"
+      24             : #include "tools/Tools.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28             : template<typename T>
+      29      309040 : static void getPointer(const TypesafePtr & p, const std::vector<unsigned>& shape, const unsigned& start, const unsigned& stride, T*&pp ) {
+      30      309040 :   if( shape.size()==1 && stride==1 ) { pp=p.get<T*>( shape[0] );  }
+      31      307391 :   else if( shape.size()==1 ) { auto p_=p.get<T*>( {shape[0],stride} ); pp = p_+start; }
+      32       66821 :   else if( shape.size()==2 ) { pp=p.get<T*>( {shape[0],shape[1]} ); }
+      33      309040 : }
+      34             : 
+      35             : template <class T>
+      36             : class DataPassingObjectTyped : public DataPassingObject {
+      37             : private:
+      38             : /// A pointer to the value
+      39             :   TypesafePtr v;
+      40             : /// A pointer to the force
+      41             :   TypesafePtr f;
+      42             : public:
+      43             : /// This convers a number from the MD code into a double
+      44             :   double MD2double(const TypesafePtr &) const override ;
+      45             : /// This is used when you want to save the passed object to a double variable in PLUMED rather than the pointer
+      46             : /// this can be used even when you don't pass a pointer from the MD code
+      47             :   void saveValueAsDouble( const TypesafePtr & val ) override;
+      48             : /// Set the pointer to the value
+      49             :   void setValuePointer( const TypesafePtr & p, const std::vector<unsigned>& shape, const bool& isconst ) override;
+      50             : /// Set the pointer to the force
+      51             :   void setForcePointer( const TypesafePtr & p, const std::vector<unsigned>& shape ) override;
+      52             : /// This gets the data in the pointer and passes it to the output value
+      53             :   void share_data( std::vector<double>& values ) const override ;
+      54             : /// Share the data and put it in the value from sequential data
+      55             :   void share_data( const unsigned& j, const unsigned& k, Value* value ) override;
+      56             : /// Share the data and put it in the value from a scattered data
+      57             :   void share_data( const std::vector<AtomNumber>&index, const std::vector<unsigned>& i, Value* value ) override;
+      58             : /// Pass the force from the value to the output value
+      59             :   void add_force( Value* vv ) override;
+      60             :   void add_force( const std::vector<int>& index, Value* value ) override;
+      61             :   void add_force( const std::vector<AtomNumber>& index, const std::vector<unsigned>& i, Value* value ) override;
+      62             : /// Rescale the force on the output value
+      63             :   void rescale_force( const unsigned& n, const double& factor, Value* value ) override;
+      64             : /// This transfers everything to the output
+      65             :   void setData( Value* value ) override;
+      66             : };
+      67             : 
+      68        6651 : std::unique_ptr<DataPassingObject> DataPassingObject::create(unsigned n) {
+      69        6651 :   if(n==sizeof(double)) {
+      70        6651 :     return std::unique_ptr<DataPassingObject>(new DataPassingObjectTyped<double>());
+      71           0 :   } else  if(n==sizeof(float)) {
+      72           0 :     return std::unique_ptr<DataPassingObject>(new DataPassingObjectTyped<float>());
+      73             :   }
+      74           0 :   std::string pp; Tools::convert(n,pp);
+      75           0 :   plumed_merror("cannot create an MD interface with sizeof(real)=="+ pp);
+      76             :   return NULL;
+      77             : }
+      78             : 
+      79             : template <class T>
+      80           0 : double DataPassingObjectTyped<T>::MD2double(const TypesafePtr & m) const {
+      81           0 :   double d=double(m.template get<T>()); return d;
+      82             : }
+      83             : 
+      84             : template <class T>
+      85        4918 : void DataPassingObjectTyped<T>::saveValueAsDouble( const TypesafePtr & val ) {
+      86        4918 :   hasbackup=true; bvalue=double(val.template get<T>());
+      87             :   // The following is to avoid extra digits in case the MD code uses floats
+      88             :   // e.g.: float f=0.002 when converted to double becomes 0.002000000094995
+      89             :   // To avoid this, we keep only up to 6 significant digits after first one
+      90             :   if( sizeof(T)<=4) {
+      91           0 :     double magnitude=std::pow(10,std::floor(std::log10(bvalue)));
+      92           0 :     bvalue=std::round(bvalue/magnitude*1e6)/1e6*magnitude;
+      93             :   }
+      94        4918 : }
+      95             : 
+      96             : template <class T>
+      97      320511 : void DataPassingObjectTyped<T>::setValuePointer( const TypesafePtr & val, const std::vector<unsigned>& shape, const bool& isconst ) {
+      98      320511 :   if( shape.size()==0 ) {
+      99      268909 :     if( isconst ) val.get<const T*>(); else val.get<T*>();  // just check type and discard pointer
+     100       51602 :   } else if( shape.size()==1 ) {
+     101           0 :     if( isconst ) val.get<const T*>(shape[0]); else val.get<T*>(shape[0]);  // just check type and discard pointer
+     102       51602 :   } else if( shape.size()==2 ) {
+     103       51602 :     if( isconst ) val.get<const T*>({shape[0],shape[1]}); else val.get<T*>({shape[0],shape[1]});  // just check type and discard pointer
+     104             :   }
+     105      320511 :   v=val.copy();
+     106      320511 : }
+     107             : 
+     108             : template <class T>
+     109      213206 : void DataPassingObjectTyped<T>::setForcePointer( const TypesafePtr & val, const std::vector<unsigned>& shape ) {
+     110      213206 :   if( shape.size()==0 ) val.get<T*>();  // just check type and discard pointer
+     111       45944 :   else if( shape.size()==1 ) val.get<T*>(shape[0]);   // just check type and discard pointer
+     112       45944 :   else if( shape.size()==2 ) val.get<T*>({shape[0],shape[1]});   // just check type and discard pointer
+     113      213204 :   f=val.copy();
+     114      213204 : }
+     115             : 
+     116             : template <class T>
+     117         670 : void DataPassingObjectTyped<T>::setData( Value* value ) {
+     118         670 :   if( value->getRank()==0 ) { *v.template get<T*>() = static_cast<T>(value->get()) / unit; return; }
+     119           0 :   T* pp; getPointer( v, value->getShape(), start, stride, pp ); unsigned nvals=value->getNumberOfValues();
+     120           0 :   for(unsigned i=0; i<nvals; ++i) pp[i] = T( value->get(i) );
+     121             : }
+     122             : 
+     123             : template <class T>
+     124      161223 : void DataPassingObjectTyped<T>::share_data( const unsigned& j, const unsigned& k, Value* value ) {
+     125      161223 :   if( value->getRank()==0 ) {
+     126        5940 :     if( hasbackup ) value->set( unit*bvalue );
+     127          72 :     else value->set( unit*double(v.template get<T>()) );
+     128        5940 :     return;
+     129             :   }
+     130      155283 :   std::vector<unsigned> s(value->getShape()); if( s.size()==1 ) s[0]=k-j;
+     131      155283 :   const T* pp; getPointer( v, s, start, stride, pp );
+     132      155283 :   std::vector<double> & d=value->data;
+     133      155283 :   #pragma omp parallel for num_threads(value->getGoodNumThreads(j,k))
+     134             :   for(unsigned i=j; i<k; ++i) d[i]=unit*pp[i*stride];
+     135             : }
+     136             : 
+     137             : template <class T>
+     138        1350 : void DataPassingObjectTyped<T>::share_data( std::vector<double>& values ) const {
+     139        1350 :   std::vector<unsigned> maxel(1,values.size()); const T* pp; getPointer( v, maxel, start, stride, pp );
+     140        1350 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(values))
+     141             :   for(unsigned i=0; i<values.size(); ++i) values[i]=unit*pp[i*stride];
+     142        1350 : }
+     143             : 
+     144             : template <class T>
+     145       53945 : void DataPassingObjectTyped<T>::share_data( const std::vector<AtomNumber>&index, const std::vector<unsigned>& i, Value* value ) {
+     146       53945 :   plumed_dbg_assert( value->getRank()==1 ); std::vector<unsigned> maxel(1,index.size());
+     147             : #ifndef NDEBUG
+     148             : // bounds are only checked in debug mode since they require this extra step that is potentially expensive
+     149             :   maxel[0]=(i.size()>0?*std::max_element(i.begin(),i.end())+1:0);
+     150             : #else
+     151       53945 :   maxel[0]=0;
+     152             : #endif
+     153       53945 :   const T* pp; getPointer( v, maxel, start, stride, pp );
+     154             :   // cannot be parallelized with omp because access to data is not ordered
+     155     1163394 :   unsigned k=0; for(const auto & p : index) { value->data[p.index()]=unit*pp[i[k]*stride]; k++; }
+     156       53945 : }
+     157             : 
+     158             : template <class T>
+     159       18339 : void DataPassingObjectTyped<T>::add_force( Value* value ) {
+     160       18339 :   if( value->getRank()==0 ) { *f.template get<T*>() += funit*static_cast<T>(value->getForce(0)); return; }
+     161       18299 :   T* pp; getPointer( f, value->getShape(), start, stride, pp ); unsigned nvals=value->getNumberOfValues();
+     162       18299 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(pp,nvals))
+     163             :   for(unsigned i=0; i<nvals; ++i) pp[i*stride] += funit*T(value->getForce(i));
+     164             : }
+     165             : 
+     166             : template <class T>
+     167       34425 : void DataPassingObjectTyped<T>::add_force( const std::vector<int>& index, Value* value ) {
+     168       34425 :   plumed_assert( value->getRank()==1 ); std::vector<unsigned> s(1,index.size()); T* pp; getPointer( f, s, start, stride, pp );
+     169       34425 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(pp,index.size()))
+     170             :   for(unsigned i=0; i<index.size(); ++i) pp[i*stride] += funit*T(value->getForce(index[i]));
+     171       34425 : }
+     172             : 
+     173             : template <class T>
+     174       45588 : void DataPassingObjectTyped<T>::add_force( const std::vector<AtomNumber>& index, const std::vector<unsigned>& i, Value* value ) {
+     175       45588 :   plumed_dbg_assert( value->getRank()==1 ); std::vector<unsigned> maxel(1,index.size());
+     176             : #ifndef NDEBUG
+     177             : // bounds are only checked in debug mode since they require this extra step that is potentially expensive
+     178             :   maxel[0]=(i.size()>0?*std::max_element(i.begin(),i.end())+1:0);
+     179             : #else
+     180       45588 :   maxel[0]=0;
+     181             : #endif
+     182       45588 :   T* pp; getPointer( f, maxel, start, stride, pp );
+     183      648741 :   unsigned k=0; for(const auto & p : index) { pp[stride*i[k]] += funit*T(value->getForce(p.index())); k++; }
+     184       45588 : }
+     185             : 
+     186             : template <class T>
+     187         150 : void DataPassingObjectTyped<T>::rescale_force( const unsigned& n, const double& factor, Value* value ) {
+     188         150 :   plumed_assert( value->getRank()>0 ); std::vector<unsigned> s( value->getShape() ); if( s.size()==1 ) s[0] = n;
+     189         150 :   T* pp; getPointer( f, s, start, stride, pp );
+     190         150 :   #pragma omp parallel for num_threads(OpenMP::getGoodNumThreads(pp,n))
+     191             :   for(unsigned i=0; i<n; ++i) pp[i*stride] *= T(factor);
+     192         150 : }
+     193             : 
+     194             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingObject.h.func-sort-c.html b/coverage/core/DataPassingObject.h.func-sort-c.html new file mode 100644 index 000000000000..2861fad0c063 --- /dev/null +++ b/coverage/core/DataPassingObject.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingObject.h.func.html b/coverage/core/DataPassingObject.h.func.html new file mode 100644 index 000000000000..63395c9d9a6e --- /dev/null +++ b/coverage/core/DataPassingObject.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingObject.h.gcov.html b/coverage/core/DataPassingObject.h.gcov.html new file mode 100644 index 000000000000..405af2304f3a --- /dev/null +++ b/coverage/core/DataPassingObject.h.gcov.html @@ -0,0 +1,163 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingObject.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_DataPassingObject_h
+      23             : #define __PLUMED_core_DataPassingObject_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <memory>
+      27             : #include <set>
+      28             : #include "tools/AtomNumber.h"
+      29             : #include "tools/TypesafePtr.h"
+      30             : #include "Value.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : class DataPassingObject {
+      35             : protected:
+      36             : /// The start of the data in the input pointer
+      37             :   unsigned start;
+      38             : /// The spacing between values in the input arrays
+      39             :   unsigned stride;
+      40             : /// The units of the quantity
+      41             :   double unit;
+      42             : /// The units of the force on this quantity
+      43             :   double funit;
+      44             : /// The backup value of the quantity (used if the value is passed directly)
+      45             :   bool hasbackup;
+      46             :   double bvalue;
+      47             : public:
+      48             :   static std::unique_ptr<DataPassingObject> create(unsigned n);
+      49             :   explicit DataPassingObject() : start(0), stride(1), unit(1), funit(1), hasbackup(false), bvalue(0) {}
+      50             :   /// Virtual destructor, just to allow inheritance.
+      51             :   virtual ~DataPassingObject() {}
+      52             : /// Convert what comes from the MD code to a double
+      53             :   virtual double MD2double(const TypesafePtr & m) const=0;
+      54             : ///
+      55      324435 :   void setStart( const unsigned& s ) { start=s; }
+      56             : /// Set the stride to use when getting data from the input array
+      57      324435 :   void setStride( const unsigned& s ) { stride=s; }
+      58             : /// Set the unit for the value
+      59        6726 :   void setUnit( const double& u ) { unit=u; }
+      60             : /// Set the unit for the force
+      61        6726 :   void setForceUnit( const double& u ) { funit=u; }
+      62             : /// This is used when you want to save the passed object to a double variable in PLUMED rather than the pointer
+      63             : /// this can be used even when you don't pass a pointer from the MD code
+      64             :   virtual void saveValueAsDouble( const TypesafePtr & val )=0;
+      65             : /// Set the pointer to the value
+      66             :   virtual void setValuePointer( const TypesafePtr & val, const std::vector<unsigned>& shape, const bool& isconst )=0;
+      67             : /// Set the pointer to the force
+      68             :   virtual void setForcePointer( const TypesafePtr & val, const std::vector<unsigned>& shape )=0;
+      69             : /// This gets the data in the pointer and passes it to the output value
+      70             :   virtual void share_data( std::vector<double>& values ) const = 0;
+      71             : /// Share the data and put it in the value from sequential data
+      72             :   virtual void share_data( const unsigned& j, const unsigned& k, Value* value )=0;
+      73             : /// Share the data and put it in the value from a scattered data
+      74             :   virtual void share_data( const std::vector<AtomNumber>&index, const std::vector<unsigned>& i, Value* value )=0;
+      75             : /// Pass the force from the value to the output value
+      76             :   virtual void add_force( Value* vv )=0;
+      77             :   virtual void add_force( const std::vector<int>& index, Value* value )=0;
+      78             :   virtual void add_force( const std::vector<AtomNumber>& index, const std::vector<unsigned>& i, Value* value )=0;
+      79             : /// Rescale the forces that were passed
+      80             :   virtual void rescale_force( const unsigned& n, const double& factor, Value* value )=0;
+      81             : /// This transfers everything to the output
+      82             :   virtual void setData( Value* value )=0;
+      83             : };
+      84             : 
+      85             : }
+      86             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingTools.cpp.func-sort-c.html b/coverage/core/DataPassingTools.cpp.func-sort-c.html new file mode 100644 index 000000000000..8fb4efede183 --- /dev/null +++ b/coverage/core/DataPassingTools.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:192382.6 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD21DataPassingToolsTypedIfE16getRealPrecisionEv0
_ZNK4PLMD21DataPassingToolsTypedIfE9MD2doubleERKNS_11TypesafePtrE0
_ZNK4PLMD21DataPassingToolsTypedIfE9double2MDERKdRKNS_11TypesafePtrE1
_ZNK4PLMD21DataPassingToolsTypedIdE9double2MDERKdRKNS_11TypesafePtrE2389
_ZNK4PLMD21DataPassingToolsTypedIdE9MD2doubleERKNS_11TypesafePtrE2493
_ZNK4PLMD21DataPassingToolsTypedIdE16getRealPrecisionEv7662
_ZNK4PLMD16DataPassingTools17getUnitConversionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15795
_ZN4PLMD16DataPassingTools6createEj806164
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingTools.cpp.func.html b/coverage/core/DataPassingTools.cpp.func.html new file mode 100644 index 000000000000..9e69d724330d --- /dev/null +++ b/coverage/core/DataPassingTools.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:192382.6 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16DataPassingTools6createEj806164
_ZNK4PLMD16DataPassingTools17getUnitConversionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15795
_ZNK4PLMD21DataPassingToolsTypedIdE16getRealPrecisionEv7662
_ZNK4PLMD21DataPassingToolsTypedIdE9MD2doubleERKNS_11TypesafePtrE2493
_ZNK4PLMD21DataPassingToolsTypedIdE9double2MDERKdRKNS_11TypesafePtrE2389
_ZNK4PLMD21DataPassingToolsTypedIfE16getRealPrecisionEv0
_ZNK4PLMD21DataPassingToolsTypedIfE9MD2doubleERKNS_11TypesafePtrE0
_ZNK4PLMD21DataPassingToolsTypedIfE9double2MDERKdRKNS_11TypesafePtrE1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingTools.cpp.gcov.html b/coverage/core/DataPassingTools.cpp.gcov.html new file mode 100644 index 000000000000..2d7eaf53e2d1 --- /dev/null +++ b/coverage/core/DataPassingTools.cpp.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingTools.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:192382.6 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DataPassingTools.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "tools/Tools.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28       15795 : double DataPassingTools::getUnitConversion( const std::string& unit ) const {
+      29       15795 :   if( unit=="energy" ) return MDUnits.getEnergy()/units.getEnergy();
+      30        6623 :   if( unit=="length" ) return MDUnits.getLength()/units.getLength();
+      31        2799 :   if( unit=="mass" ) return  MDUnits.getMass()/units.getMass();
+      32        1843 :   if( unit=="charge" ) return MDUnits.getCharge()/units.getCharge();
+      33         887 :   if( unit=="time" ) return MDUnits.getTime()/units.getTime();
+      34           0 :   if( unit=="number" ) return 1;
+      35           0 :   plumed_error();
+      36             : }
+      37             : 
+      38             : template <class T>
+      39      806164 : class DataPassingToolsTyped : public DataPassingTools {
+      40             : public:
+      41             :   int getRealPrecision() const override;
+      42             :   double MD2double(const TypesafePtr & m)const override;
+      43             :   void double2MD(const double&d,const TypesafePtr & m) const override;
+      44             : };
+      45             : 
+      46      806164 : std::unique_ptr<DataPassingTools> DataPassingTools::create(unsigned n) {
+      47      806164 :   if(n==sizeof(double)) {
+      48      806163 :     return std::unique_ptr<DataPassingTools>(new DataPassingToolsTyped<double>());
+      49           1 :   } else  if(n==sizeof(float)) {
+      50           1 :     return std::unique_ptr<DataPassingTools>(new DataPassingToolsTyped<float>());
+      51             :   }
+      52           0 :   std::string pp; Tools::convert(n,pp);
+      53           0 :   plumed_merror("cannot create an MD interface with sizeof(real)=="+ pp);
+      54             :   return NULL;
+      55             : }
+      56             : 
+      57             : template <class T>
+      58        7662 : int DataPassingToolsTyped<T>::getRealPrecision() const {
+      59        7662 :   return sizeof(T);
+      60             : }
+      61             : 
+      62             : template <class T>
+      63        2493 : double DataPassingToolsTyped<T>::MD2double(const TypesafePtr & m) const {
+      64        2493 :   return double(m.template get<T>());
+      65             : }
+      66             : 
+      67             : template <class T>
+      68        2390 : void DataPassingToolsTyped<T>::double2MD(const double&d,const TypesafePtr & m) const {
+      69        2390 :   m.set(T(d));
+      70        2390 : }
+      71             : 
+      72             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingTools.h.func-sort-c.html b/coverage/core/DataPassingTools.h.func-sort-c.html new file mode 100644 index 000000000000..322795e20c82 --- /dev/null +++ b/coverage/core/DataPassingTools.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingTools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16DataPassingToolsD0Ev0
_ZN4PLMD16DataPassingToolsD2Ev806164
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingTools.h.func.html b/coverage/core/DataPassingTools.h.func.html new file mode 100644 index 000000000000..b7b98522ab48 --- /dev/null +++ b/coverage/core/DataPassingTools.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingTools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16DataPassingToolsD0Ev0
_ZN4PLMD16DataPassingToolsD2Ev806164
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DataPassingTools.h.gcov.html b/coverage/core/DataPassingTools.h.gcov.html new file mode 100644 index 000000000000..5966d736fb88 --- /dev/null +++ b/coverage/core/DataPassingTools.h.gcov.html @@ -0,0 +1,131 @@ + + + + + + + + LCOV - plumed test coverage - core/DataPassingTools.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DataPassingTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_DataPassingTools_h
+      23             : #define __PLUMED_core_DataPassingTools_h
+      24             : 
+      25             : #include <string>
+      26             : #include <memory>
+      27             : #include <map>
+      28             : #include "tools/TypesafePtr.h"
+      29             : #include "tools/Units.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : class PlumedMain;
+      34             : 
+      35             : class DataPassingTools {
+      36             :   friend class PlumedMain;
+      37             : private:
+      38             : /// The units used in the MD code and PLUMED
+      39             :   Units units;
+      40             :   Units MDUnits;
+      41             : /// Is the code using natural units
+      42             :   bool usingNaturalUnits;
+      43             : public:
+      44             : /// Virtual destructor, just to allow inheritance.
+      45      806164 :   virtual ~DataPassingTools() {}
+      46             :   static std::unique_ptr<DataPassingTools> create(unsigned n);
+      47             :   virtual int getRealPrecision() const = 0;
+      48             :   double getUnitConversion( const std::string& unit ) const ;
+      49             :   virtual double MD2double(const TypesafePtr & m) const=0;
+      50             :   virtual void double2MD(const double&,const TypesafePtr & m) const=0;
+      51             : };
+      52             : 
+      53             : }
+      54             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DomainDecomposition.cpp.func-sort-c.html b/coverage/core/DomainDecomposition.cpp.func-sort-c.html new file mode 100644 index 000000000000..28f1ebe6583a --- /dev/null +++ b/coverage/core/DomainDecomposition.cpp.func-sort-c.html @@ -0,0 +1,205 @@ + + + + + + + + LCOV - plumed test coverage - core/DomainDecomposition.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DomainDecomposition.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25426695.5 %
Date:2024-02-22 21:58:45Functions:313393.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19DomainDecompositionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD19DomainDecomposition26getNumberOfForcesToRescaleEv0
_ZN4PLMD19DomainDecomposition10readBinaryERSi114
_ZN4PLMD19DomainDecomposition11writeBinaryERSo114
_ZN4PLMD19DomainDecomposition11getFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition13clearFullListEv116
_ZN4PLMD19DomainDecomposition14createFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition11DomainComms6enableERNS_12CommunicatorE381
_ZN4PLMD19DomainDecomposition8Set_commERNS_12CommunicatorE381
_ZNK4PLMD19DomainDecomposition11getGatindexEv459
_ZN4PLMD19DomainDecomposition18setAtomsContiguousEi533
_ZNK4PLMD19DomainDecomposition9getDdStepEv900
_ZN4PLMD19DomainDecompositionC1ERKNS_13ActionOptionsE936
_ZN4PLMD19DomainDecomposition16registerKeywordsERNS_8KeywordsE938
_ZN4PLMD19DomainDecomposition16setAtomsGatindexERKNS_11TypesafePtrEb978
_ZN4PLMD19DomainDecomposition8shareAllEv994
_ZN4PLMD19DomainDecomposition14setAtomsNlocalEi1511
_ZN4PLMD19DomainDecomposition17getAllActiveAtomsERSt6vectorINS_10AtomNumberESaIS2_EE2159
_ZN4PLMD19DomainDecomposition14sumOverDomainsEPNS_5ValueE3989
_ZN4PLMDL31getenvMergeVectorsPriorityQueueEv21153
_ZN4PLMD19DomainDecomposition18broadcastToDomainsEPNS_5ValueE48636
_ZN4PLMD19DomainDecomposition5applyEv52328
_ZN4PLMD19DomainDecomposition5resetEv52328
_ZN4PLMD19DomainDecomposition4waitEv52452
_ZN4PLMD19DomainDecomposition5shareERKSt6vectorINS_10AtomNumberESaIS2_EE53021
_ZN4PLMDL17getenvForceUniqueEv53270
_ZN4PLMD19DomainDecomposition5shareEv54150
_ZN4PLMD19DomainDecomposition17resetForStepStartEv55759
_ZN4PLMD19DomainDecomposition15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE167262
_ZN4PLMD19DomainDecomposition8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj268814
_ZN4PLMD19DomainDecomposition9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj268814
_ZN4PLMD19DomainDecomposition15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE272836
_ZNK4PLMD19DomainDecomposition16getNumberOfAtomsEv326726
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DomainDecomposition.cpp.func.html b/coverage/core/DomainDecomposition.cpp.func.html new file mode 100644 index 000000000000..567d971ae35d --- /dev/null +++ b/coverage/core/DomainDecomposition.cpp.func.html @@ -0,0 +1,205 @@ + + + + + + + + LCOV - plumed test coverage - core/DomainDecomposition.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DomainDecomposition.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25426695.5 %
Date:2024-02-22 21:58:45Functions:313393.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19DomainDecomposition10readBinaryERSi114
_ZN4PLMD19DomainDecomposition11DomainComms6enableERNS_12CommunicatorE381
_ZN4PLMD19DomainDecomposition11getFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition11writeBinaryERSo114
_ZN4PLMD19DomainDecomposition13clearFullListEv116
_ZN4PLMD19DomainDecomposition14createFullListERKNS_11TypesafePtrE116
_ZN4PLMD19DomainDecomposition14setAtomsNlocalEi1511
_ZN4PLMD19DomainDecomposition14sumOverDomainsEPNS_5ValueE3989
_ZN4PLMD19DomainDecomposition15setForcePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE167262
_ZN4PLMD19DomainDecomposition15setValuePointerERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE272836
_ZN4PLMD19DomainDecomposition16registerKeywordsERNS_8KeywordsE938
_ZN4PLMD19DomainDecomposition16setAtomsGatindexERKNS_11TypesafePtrEb978
_ZN4PLMD19DomainDecomposition17getAllActiveAtomsERSt6vectorINS_10AtomNumberESaIS2_EE2159
_ZN4PLMD19DomainDecomposition17resetForStepStartEv55759
_ZN4PLMD19DomainDecomposition18broadcastToDomainsEPNS_5ValueE48636
_ZN4PLMD19DomainDecomposition18setAtomsContiguousEi533
_ZN4PLMD19DomainDecomposition4waitEv52452
_ZN4PLMD19DomainDecomposition5applyEv52328
_ZN4PLMD19DomainDecomposition5resetEv52328
_ZN4PLMD19DomainDecomposition5shareERKSt6vectorINS_10AtomNumberESaIS2_EE53021
_ZN4PLMD19DomainDecomposition5shareEv54150
_ZN4PLMD19DomainDecomposition8Set_commERNS_12CommunicatorE381
_ZN4PLMD19DomainDecomposition8setStartERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj268814
_ZN4PLMD19DomainDecomposition8shareAllEv994
_ZN4PLMD19DomainDecomposition9setStrideERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj268814
_ZN4PLMD19DomainDecompositionC1ERKNS_13ActionOptionsE936
_ZN4PLMD19DomainDecompositionC2ERKNS_13ActionOptionsE0
_ZN4PLMDL17getenvForceUniqueEv53270
_ZN4PLMDL31getenvMergeVectorsPriorityQueueEv21153
_ZNK4PLMD19DomainDecomposition11getGatindexEv459
_ZNK4PLMD19DomainDecomposition16getNumberOfAtomsEv326726
_ZNK4PLMD19DomainDecomposition26getNumberOfForcesToRescaleEv0
_ZNK4PLMD19DomainDecomposition9getDdStepEv900
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DomainDecomposition.cpp.gcov.html b/coverage/core/DomainDecomposition.cpp.gcov.html new file mode 100644 index 000000000000..7add442773eb --- /dev/null +++ b/coverage/core/DomainDecomposition.cpp.gcov.html @@ -0,0 +1,553 @@ + + + + + + + + LCOV - plumed test coverage - core/DomainDecomposition.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DomainDecomposition.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25426695.5 %
Date:2024-02-22 21:58:45Functions:313393.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DomainDecomposition.h"
+      23             : #include "ActionToPutData.h"
+      24             : #include "ActionAtomistic.h"
+      25             : #include "ActionRegister.h"
+      26             : #include "PlumedMain.h"
+      27             : #include "ActionSet.h"
+      28             : 
+      29             : //+PLUMEDOC ANALYSIS DOMAIN_DECOMPOSITION
+      30             : /*
+      31             : Pass domain decomposed properties of atoms to PLUMED
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : 
+      40             : /// Use a priority_queue to merge unique vectors.
+      41             : /// export PLUMED_MERGE_VECTORS_PRIORITY_QUEUE=yes to use a priority_queue.
+      42             : /// Might be faster with some settings, but appears to not be in practice.
+      43             : /// This option is for testing and might be removed.
+      44       21153 : static bool getenvMergeVectorsPriorityQueue() noexcept {
+      45       21153 :   static const auto* res=std::getenv("PLUMED_MERGE_VECTORS_PRIORITY_QUEUE");
+      46       21153 :   return res;
+      47             : }
+      48             : 
+      49             : /// Use unique list of atoms to manipulate forces and positions.
+      50             : /// A unique list of atoms is used to manipulate forces and positions in MPI parallel runs.
+      51             : /// In serial runs, this is done if convenient. The code currently contain
+      52             : /// some heuristic to decide if the unique list should be used or not.
+      53             : /// An env var can be used to override this decision.
+      54             : /// export PLUMED_FORCE_UNIQUE=yes  # enforce using the unique list in serial runs
+      55             : /// export PLUMED_FORCE_UNIQUE=no   # enforce not using the unique list in serial runs
+      56             : /// export PLUMED_FORCE_UNIQUE=auto # choose heuristically
+      57             : /// default: auto
+      58       53270 : static const char* getenvForceUnique() noexcept {
+      59       53270 :   static const auto* res=std::getenv("PLUMED_FORCE_UNIQUE");
+      60       53270 :   return res;
+      61             : }
+      62             : 
+      63             : PLUMED_REGISTER_ACTION(DomainDecomposition,"DOMAIN_DECOMPOSITION")
+      64             : 
+      65         381 : void DomainDecomposition::DomainComms::enable(Communicator& c) {
+      66         381 :   on=true;
+      67         381 :   Set_comm(c.Get_comm());
+      68         381 :   async=Get_size()<10;
+      69         381 :   if(std::getenv("PLUMED_ASYNC_SHARE")) {
+      70           4 :     std::string s(std::getenv("PLUMED_ASYNC_SHARE"));
+      71           4 :     if(s=="yes") async=true;
+      72           4 :     else if(s=="no") async=false;
+      73           0 :     else plumed_merror("PLUMED_ASYNC_SHARE variable is set to " + s + "; should be yes or no");
+      74             :   }
+      75         381 : }
+      76             : 
+      77         938 : void DomainDecomposition::registerKeywords(Keywords& keys) {
+      78         938 :   ActionForInterface::registerKeywords( keys ); keys.remove("ROLE");
+      79        1876 :   keys.add("compulsory","NATOMS","the number of atoms across all the domains");
+      80        1876 :   keys.add("numbered","VALUE","value to create for the domain decomposition");
+      81        1876 :   keys.add("numbered","UNIT","unit of the ith value that is being passed through the domain decomposition");
+      82        1876 :   keys.add("numbered","CONSTANT","is the ith value that is being passed through the domain decomposition constant");
+      83        1876 :   keys.add("numbered","PERIODIC","if the value being passed to plumed is periodic then you should specify the periodicity of the function.  If the value "
+      84             :            "is not periodic you must state this using PERIODIC=NO.  Positions are passed with PERIODIC=NO even though special methods are used "
+      85             :            "to deal with pbc");
+      86        1876 :   keys.add("numbered","ROLE","Get the role this value plays in the code can be x/y/z/m/q to signify that this is x, y, z positions of atoms or masses or charges of atoms");
+      87         938 : }
+      88             : 
+      89         936 : DomainDecomposition::DomainDecomposition(const ActionOptions&ao):
+      90             :   Action(ao),
+      91             :   ActionForInterface(ao),
+      92         936 :   ddStep(0),
+      93         936 :   shuffledAtoms(0),
+      94         936 :   asyncSent(false),
+      95         936 :   unique_serial(false)
+      96             : {
+      97             :   // Read in the number of atoms
+      98        1872 :   int natoms; parse("NATOMS",natoms);
+      99         936 :   std::string str_natoms; Tools::convert( natoms, str_natoms );
+     100             :   // Setup the gat index
+     101      660385 :   gatindex.resize(natoms); for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=i;
+     102             :   // Now read in the values we are creating here
+     103        4680 :   for(unsigned i=1;; ++i) {
+     104             :     std::string valname;
+     105       11232 :     if( !parseNumbered("VALUE",i,valname) ) break;
+     106        9360 :     std::string unit; parseNumbered("UNIT",i,unit);
+     107        9360 :     std::string constant; parseNumbered("CONSTANT",i,constant);
+     108        9360 :     std::string period; parseNumbered("PERIODIC",i,period);
+     109        9360 :     std::string role; parseNumbered("ROLE",i,role);
+     110        6552 :     if( constant=="True") plumed.readInputLine( valname + ": PUT FROM_DOMAINS CONSTANT SHAPE=" + str_natoms + " UNIT=" + unit + " PERIODIC=" + period + " ROLE=" + role, true );
+     111        5616 :     else if( constant=="False") plumed.readInputLine( valname + ": PUT FROM_DOMAINS SHAPE=" + str_natoms + " UNIT=" + unit + " PERIODIC=" + period + " ROLE=" + role, true );
+     112           0 :     else plumed_merror("missing information on whether value is constant");
+     113             :     // And save the list of values that are set from here
+     114        4680 :     ActionToPutData* ap=plumed.getActionSet().selectWithLabel<ActionToPutData*>(valname); ap->addDependency( this ); inputs.push_back( ap );
+     115        4680 :   }
+     116         936 :   plumed.readInputLine("Box: PBC",true);
+     117             :   // Turn on the domain decomposition
+     118         936 :   if( Communicator::initialized() ) Set_comm(comm);
+     119         936 : }
+     120             : 
+     121         381 : void DomainDecomposition::Set_comm(Communicator& comm) {
+     122         381 :   dd.enable(comm); setAtomsNlocal(getNumberOfAtoms()); setAtomsContiguous(0);
+     123         381 :   if( dd.Get_rank()!=0 ) {
+     124         268 :     ActionToPutData* ap=plumed.getActionSet().selectWithLabel<ActionToPutData*>("Box"); ap->noforce=true;
+     125             :   }
+     126         381 : }
+     127             : 
+     128      326726 : unsigned DomainDecomposition::getNumberOfAtoms() const {
+     129      326726 :   if( inputs.size()==0 ) return 0;
+     130      326726 :   return (inputs[0]->getPntrToValue())->getShape()[0];
+     131             : }
+     132             : 
+     133       55759 : void DomainDecomposition::resetForStepStart() {
+     134      334554 :   for(const auto & pp : inputs) pp->resetForStepStart();
+     135       55759 : }
+     136             : 
+     137      268814 : void DomainDecomposition::setStart( const std::string& name, const unsigned& sss) {
+     138      786630 :   for(const auto & pp : inputs) {
+     139      786630 :     if( pp->getLabel()==name ) { pp->setStart(name, sss); return; }
+     140             :   }
+     141           0 :   plumed_error();
+     142             : }
+     143             : 
+     144      268814 : void DomainDecomposition::setStride( const std::string& name, const unsigned& sss) {
+     145      786630 :   for(const auto & pp : inputs) {
+     146      786630 :     if( pp->getLabel()==name ) { pp->setStride(name, sss); return; }
+     147             :   }
+     148           0 :   plumed_error();
+     149             : }
+     150             : 
+     151      272836 : bool DomainDecomposition::setValuePointer( const std::string& name, const TypesafePtr & val ) {
+     152      272836 :   wasset=true;  // Once the domain decomposition stuff is transferred moved the setting of this to where the g2l vector is setup
+     153      810756 :   for(const auto & pp : inputs) {
+     154      806737 :     if( pp->setValuePointer( name, val ) ) return true;
+     155             :   }
+     156             :   return false;
+     157             : }
+     158             : 
+     159      167262 : bool DomainDecomposition::setForcePointer( const std::string& name, const TypesafePtr & val ) {
+     160      334644 :   for(const auto & pp : inputs) {
+     161      334614 :     if( pp->setForcePointer( name, val ) ) return true;
+     162             :   }
+     163             :   return false;
+     164             : }
+     165             : 
+     166        1511 : void DomainDecomposition::setAtomsNlocal(int n) {
+     167        1511 :   gatindex.resize(n);
+     168        1511 :   g2l.resize(getNumberOfAtoms(),-1);
+     169        1511 :   if(dd) {
+     170             : // Since these vectors are sent with MPI by using e.g.
+     171             : // &dd.positionsToBeSent[0]
+     172             : // we make sure they are non-zero-sized so as to
+     173             : // avoid errors when doing boundary check
+     174        1487 :     if(n==0) n++;
+     175        1487 :     std::size_t nvals = inputs.size(), natoms = getNumberOfAtoms();
+     176        1487 :     dd.positionsToBeSent.resize(n*nvals,0.0);
+     177        1487 :     dd.positionsToBeReceived.resize(natoms*nvals,0.0);
+     178        1487 :     dd.indexToBeSent.resize(n,0);
+     179        1487 :     dd.indexToBeReceived.resize(natoms,0);
+     180             :   }
+     181        1511 : }
+     182             : 
+     183         978 : void DomainDecomposition::setAtomsGatindex(const TypesafePtr & g,bool fortran) {
+     184         978 :   plumed_massert( g || gatindex.size()==0, "NULL gatindex pointer with non-zero local atoms");
+     185             :   auto gg=g.get<const int*>(gatindex.size());
+     186         978 :   ddStep=getStep();
+     187         978 :   if(fortran) {
+     188           0 :     for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=gg[i]-1;
+     189             :   } else {
+     190       21470 :     for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=gg[i];
+     191             :   }
+     192       56200 :   for(unsigned i=0; i<g2l.size(); i++) g2l[i]=-1;
+     193         978 :   if( gatindex.size()==getNumberOfAtoms() ) {
+     194           9 :     shuffledAtoms=0;
+     195        1005 :     for(unsigned i=0; i<gatindex.size(); i++) {
+     196         996 :       if( gatindex[i]!=i ) { shuffledAtoms=1; break; }
+     197             :     }
+     198             :   } else {
+     199         969 :     shuffledAtoms=1;
+     200             :   }
+     201         978 :   if(dd) dd.Sum(shuffledAtoms);
+     202       21470 :   for(unsigned i=0; i<gatindex.size(); i++) g2l[gatindex[i]]=i;
+     203             :   // keep in unique only those atoms that are local
+     204        9824 :   for(unsigned i=0; i<actions.size(); i++) actions[i]->unique_local_needs_update=true;
+     205             :   unique.clear();
+     206         978 : }
+     207             : 
+     208         533 : void DomainDecomposition::setAtomsContiguous(int start) {
+     209         533 :   ddStep=plumed.getStep();
+     210      186927 :   for(unsigned i=0; i<gatindex.size(); i++) gatindex[i]=start+i;
+     211      199239 :   for(unsigned i=0; i<g2l.size(); i++) g2l[i]=-1;
+     212      186927 :   for(unsigned i=0; i<gatindex.size(); i++) g2l[gatindex[i]]=i;
+     213         533 :   if(gatindex.size()<getNumberOfAtoms()) shuffledAtoms=1;
+     214             :   // keep in unique only those atoms that are local
+     215         745 :   for(unsigned i=0; i<actions.size(); i++) actions[i]->unique_local_needs_update=true;
+     216             :   unique.clear();
+     217         533 : }
+     218             : 
+     219         994 : void DomainDecomposition::shareAll() {
+     220        1108 :   unique.clear(); int natoms = getNumberOfAtoms();
+     221         994 :   if( dd && shuffledAtoms>0 ) {
+     222       17350 :     for(int i=0; i<natoms; ++i) if( g2l[i]>=0 ) unique.push_back( AtomNumber::index(i) );
+     223             :   } else {
+     224         810 :     unique.resize(natoms);
+     225      652947 :     for(int i=0; i<natoms; i++) unique[i]=AtomNumber::index(i);
+     226             :   }
+     227         994 :   share(unique);
+     228         994 : }
+     229             : 
+     230       54150 : void DomainDecomposition::share() {
+     231             :   // We can no longer set the pointers after the share
+     232      324900 :   bool atomsNeeded=false; for(const auto & pp : inputs) pp->share();
+     233             :   // At first step I scatter all the atoms so as to store their mass and charge
+     234             :   // Notice that this works with the assumption that charges and masses are
+     235             :   // not changing during the simulation!
+     236       54150 :   if( firststep ) {
+     237         880 :     actions = plumed.getActionSet().select<ActionAtomistic*>();
+     238         880 :     shareAll(); return;
+     239             :   }
+     240             : 
+     241       53270 :   if(!getenvForceUnique() || !std::strcmp(getenvForceUnique(),"auto")) {
+     242             :     unsigned largest=0;
+     243      252329 :     for(unsigned i=0; i<actions.size(); i++) {
+     244      199059 :       if(actions[i]->isActive()) {
+     245             :         auto l=actions[i]->getUnique().size();
+     246      149738 :         if(l>largest) largest=l;
+     247             :       }
+     248             :     }
+     249       53270 :     if(largest*2<getNumberOfAtoms()) unique_serial=true;
+     250       34642 :     else unique_serial=false;
+     251           0 :   } else if(!std::strcmp(getenvForceUnique(),"yes")) {
+     252           0 :     unique_serial=true;
+     253           0 :   } else if(!std::strcmp(getenvForceUnique(),"no")) {
+     254           0 :     unique_serial=false;
+     255             :   } else {
+     256           0 :     plumed_error()<<"PLUMED_FORCE_UNIQUE set to unknown value "<<getenvForceUnique();
+     257             :   }
+     258             : 
+     259       53270 :   if(unique_serial || !(int(gatindex.size())==getNumberOfAtoms() && shuffledAtoms==0)) {
+     260      100851 :     for(unsigned i=0; i<actions.size(); i++) {
+     261       90921 :       if( actions[i]->unique_local_needs_update ) actions[i]->updateUniqueLocal( !(dd && shuffledAtoms>0), g2l );
+     262             :     }
+     263             :     // Now reset unique for the new step
+     264             :     std::vector<const std::vector<AtomNumber>*> vectors;
+     265       18994 :     vectors.reserve(actions.size());
+     266      100851 :     for(unsigned i=0; i<actions.size(); i++) {
+     267       81857 :       if(actions[i]->isActive()) {
+     268       57717 :         if(!actions[i]->getUnique().empty()) {
+     269             :           // unique are the local atoms
+     270       47010 :           vectors.push_back(&actions[i]->getUniqueLocal());
+     271             :         }
+     272             :       }
+     273             :     }
+     274       18994 :     if(!vectors.empty()) atomsNeeded=true;
+     275       18994 :     unique.clear();
+     276       18994 :     Tools::mergeSortedVectors(vectors,unique,getenvMergeVectorsPriorityQueue());
+     277             :   } else {
+     278      151478 :     for(unsigned i=0; i<actions.size(); i++) {
+     279      117202 :       if(actions[i]->isActive()) {
+     280       92021 :         if(!actions[i]->getUnique().empty()) { atomsNeeded=true; }
+     281             :       }
+     282             :     }
+     283             :   }
+     284             : 
+     285             :   // Now we retrieve the atom numbers we need
+     286       53270 :   if( atomsNeeded ) share( unique );
+     287             : }
+     288             : 
+     289       53021 : void DomainDecomposition::share(const std::vector<AtomNumber>& unique) {
+     290             :   // This retrieves what values we need to get
+     291             :   int ndata=0; std::vector<Value*> values_to_get;
+     292       53021 :   if(!(int(gatindex.size())==getNumberOfAtoms() && shuffledAtoms==0)) {
+     293        2188 :     uniq_index.resize(unique.size());
+     294       31141 :     for(unsigned i=0; i<unique.size(); i++) uniq_index[i]=g2l[unique[i].index()];
+     295       13128 :     for(const auto & ip : inputs) {
+     296       10940 :       if( (!ip->fixed || firststep) && ip->wasset ) { (ip->mydata)->share_data( unique, uniq_index, ip->copyOutput(0) ); values_to_get.push_back(ip->copyOutput(0)); ndata++; }
+     297             :     }
+     298       50833 :   } else if( unique_serial) {
+     299       15747 :     uniq_index.resize(unique.size());
+     300      355047 :     for(unsigned i=0; i<unique.size(); i++) uniq_index[i]=unique[i].index();
+     301       94482 :     for(const auto & ip : inputs) {
+     302       78735 :       if( (!ip->fixed || firststep) && ip->wasset ) { (ip->mydata)->share_data( unique, uniq_index, ip->copyOutput(0) ); values_to_get.push_back(ip->copyOutput(0)); ndata++; }
+     303             :     }
+     304             :   } else {
+     305             : // faster version, which retrieves all atoms
+     306      210516 :     for(const auto & ip : inputs) {
+     307      175430 :       if( (!ip->fixed || firststep) && ip->wasset ) { (ip->mydata)->share_data( 0, getNumberOfAtoms(), ip->copyOutput(0) ); values_to_get.push_back(ip->copyOutput(0)); ndata++; }
+     308             :     }
+     309             :   }
+     310             : 
+     311       53021 :   if(dd && shuffledAtoms>0) {
+     312        2164 :     if(dd.async) {
+     313        9530 :       for(unsigned i=0; i<dd.mpi_request_positions.size(); i++) dd.mpi_request_positions[i].wait();
+     314        9530 :       for(unsigned i=0; i<dd.mpi_request_index.size(); i++)     dd.mpi_request_index[i].wait();
+     315             :     }
+     316             : 
+     317        2164 :     int count=0;
+     318       31059 :     for(const auto & p : unique) {
+     319       28895 :       dd.indexToBeSent[count]=p.index(); int dpoint=0;
+     320      120270 :       for(unsigned i=0; i<values_to_get.size(); ++i) {
+     321       91375 :         dd.positionsToBeSent[ndata*count+dpoint]=values_to_get[i]->get(p.index());
+     322       91375 :         dpoint++;
+     323             :       }
+     324       28895 :       count++;
+     325             :     }
+     326             : 
+     327        2164 :     if(dd.async) {
+     328        2144 :       asyncSent=true;
+     329        2144 :       dd.mpi_request_positions.resize(dd.Get_size());
+     330        2144 :       dd.mpi_request_index.resize(dd.Get_size());
+     331        9730 :       for(int i=0; i<dd.Get_size(); i++) {
+     332        7586 :         dd.mpi_request_index[i]=dd.Isend(&dd.indexToBeSent[0],count,i,666);
+     333        7586 :         dd.mpi_request_positions[i]=dd.Isend(&dd.positionsToBeSent[0],ndata*count,i,667);
+     334             :       }
+     335             :     } else {
+     336          20 :       const int n=(dd.Get_size());
+     337          20 :       std::vector<int> counts(n);
+     338          20 :       std::vector<int> displ(n);
+     339          20 :       std::vector<int> counts5(n);
+     340          20 :       std::vector<int> displ5(n);
+     341          20 :       dd.Allgather(count,counts);
+     342          20 :       displ[0]=0;
+     343          80 :       for(int i=1; i<n; ++i) displ[i]=displ[i-1]+counts[i-1];
+     344         100 :       for(int i=0; i<n; ++i) counts5[i]=counts[i]*ndata;
+     345         100 :       for(int i=0; i<n; ++i) displ5[i]=displ[i]*ndata;
+     346          20 :       dd.Allgatherv(&dd.indexToBeSent[0],count,&dd.indexToBeReceived[0],&counts[0],&displ[0]);
+     347          20 :       dd.Allgatherv(&dd.positionsToBeSent[0],ndata*count,&dd.positionsToBeReceived[0],&counts5[0],&displ5[0]);
+     348          20 :       int tot=displ[n-1]+counts[n-1];
+     349        1620 :       for(int i=0; i<tot; i++) {
+     350             :         int dpoint=0;
+     351        7264 :         for(unsigned j=0; j<values_to_get.size(); ++j) {
+     352        5664 :           values_to_get[j]->data[dd.indexToBeReceived[i]] = dd.positionsToBeReceived[ndata*i+dpoint]; dpoint++;
+     353             :         }
+     354             :       }
+     355             :     }
+     356             :   }
+     357       53021 : }
+     358             : 
+     359       52452 : void DomainDecomposition::wait() {
+     360      314712 :   for(const auto & ip : inputs) ip->dataCanBeSet=false;
+     361             : 
+     362       52452 :   if(dd && shuffledAtoms>0) {
+     363             :     int ndata=0; std::vector<Value*> values_to_set;
+     364       12984 :     for(const auto & ip : inputs) {
+     365       10820 :       if( (!ip->fixed || firststep) && ip->wasset ) { values_to_set.push_back(ip->copyOutput(0)); ndata++; }
+     366             :     }
+     367             : 
+     368             : // receive toBeReceived
+     369        2164 :     if(asyncSent) {
+     370             :       Communicator::Status status;
+     371             :       std::size_t count=0;
+     372        9730 :       for(int i=0; i<dd.Get_size(); i++) {
+     373        7586 :         dd.Recv(&dd.indexToBeReceived[count],dd.indexToBeReceived.size()-count,i,666,status);
+     374        7586 :         int c=status.Get_count<int>();
+     375        7586 :         dd.Recv(&dd.positionsToBeReceived[ndata*count],dd.positionsToBeReceived.size()-ndata*count,i,667);
+     376        7586 :         count+=c;
+     377             :       }
+     378       65116 :       for(int i=0; i<count; i++) {
+     379             :         int dpoint=0;
+     380      263252 :         for(unsigned j=0; j<values_to_set.size(); ++j) {
+     381      200280 :           values_to_set[j]->set(dd.indexToBeReceived[i], dd.positionsToBeReceived[ndata*i+dpoint] );
+     382      200280 :           dpoint++;
+     383             :         }
+     384             :       }
+     385        2144 :       asyncSent=false;
+     386             :     }
+     387             :   }
+     388       52452 : }
+     389             : 
+     390           0 : unsigned DomainDecomposition::getNumberOfForcesToRescale() const {
+     391           0 :   return gatindex.size();
+     392             : }
+     393             : 
+     394       52328 : void DomainDecomposition::apply() {
+     395      313968 :   for(const auto & ip : inputs) {
+     396      261640 :     if( !(ip->getPntrToValue())->forcesWereAdded() || ip->noforce ) {
+     397      181627 :       continue;
+     398       80013 :     } else if( ip->wasscaled || (!unique_serial && int(gatindex.size())==getNumberOfAtoms() && shuffledAtoms==0) ) {
+     399       34425 :       (ip->mydata)->add_force( gatindex, ip->getPntrToValue() );
+     400       45588 :     } else { (ip->mydata)->add_force( unique, uniq_index, ip->getPntrToValue() ); }
+     401             :   }
+     402       52328 : }
+     403             : 
+     404       52328 : void DomainDecomposition::reset() {
+     405       52328 :   if( !unique_serial && int(gatindex.size())==getNumberOfAtoms() && shuffledAtoms==0 ) return;
+     406             :   // This is an optimisation to ensure that we don't call std::fill over the whole forces
+     407             :   // array if there are a small number of atoms passed between the MD code and PLUMED
+     408       17796 :   if( dd && shuffledAtoms>0 ) getAllActiveAtoms( unique );
+     409      106776 :   for(const auto & ip : inputs) (ip->copyOutput(0))->clearInputForce( unique );
+     410             : }
+     411             : 
+     412         114 : void DomainDecomposition::writeBinary(std::ostream&o) {
+     413         684 :   for(const auto & ip : inputs) ip->writeBinary(o);
+     414         114 : }
+     415             : 
+     416         114 : void DomainDecomposition::readBinary(std::istream&i) {
+     417         684 :   for(const auto & ip : inputs) ip->readBinary(i);
+     418         114 : }
+     419             : 
+     420       48636 : void DomainDecomposition::broadcastToDomains( Value* val ) {
+     421       48636 :   if( dd ) dd.Bcast( val->data, 0 );
+     422       48636 : }
+     423             : 
+     424        3989 : void DomainDecomposition::sumOverDomains( Value* val ) {
+     425        3989 :   if( dd && shuffledAtoms>0 ) dd.Sum( val->data );
+     426        3989 : }
+     427             : 
+     428         900 : const long int& DomainDecomposition::getDdStep() const {
+     429         900 :   return ddStep;
+     430             : }
+     431             : 
+     432         459 : const std::vector<int>& DomainDecomposition::getGatindex() const {
+     433         459 :   return gatindex;
+     434             : }
+     435             : 
+     436        2159 : void DomainDecomposition::getAllActiveAtoms( std::vector<AtomNumber>& u ) {
+     437             :   std::vector<const std::vector<AtomNumber>*> vectors;
+     438       20776 :   for(unsigned i=0; i<actions.size(); i++) {
+     439       18617 :     if(actions[i]->isActive()) {
+     440       12817 :       if(!actions[i]->getUnique().empty()) {
+     441             :         // unique are the local atoms
+     442       11264 :         vectors.push_back(&actions[i]->getUnique());
+     443             :       }
+     444             :     }
+     445             :   }
+     446             :   u.clear();
+     447        2159 :   Tools::mergeSortedVectors(vectors,u,getenvMergeVectorsPriorityQueue());
+     448        2159 : }
+     449             : 
+     450         116 : void DomainDecomposition::createFullList(const TypesafePtr & n) {
+     451         116 :   if( firststep ) {
+     452           7 :     int natoms = getNumberOfAtoms();
+     453           7 :     n.set(int(natoms)); fullList.resize(natoms);
+     454         803 :     for(unsigned i=0; i<natoms; i++) fullList[i]=i;
+     455             :   } else {
+     456             : // We update here the unique list defined at Atoms::unique.
+     457             : // This is not very clear, and probably should be coded differently.
+     458             : // Hopefully this fix the longstanding issue with NAMD.
+     459         109 :     getAllActiveAtoms( unique );
+     460         109 :     fullList.clear(); fullList.reserve(unique.size());
+     461        5012 :     for(const auto & p : unique) fullList.push_back(p.index());
+     462         109 :     n.set(int(fullList.size()));
+     463             :   }
+     464         116 : }
+     465             : 
+     466         116 : void DomainDecomposition::getFullList(const TypesafePtr & x) {
+     467             :   auto xx=x.template get<const int**>();
+     468         116 :   if(!fullList.empty()) *xx=&fullList[0];
+     469           6 :   else *xx=NULL;
+     470         116 : }
+     471             : 
+     472         116 : void DomainDecomposition::clearFullList() {
+     473         116 :   fullList.resize(0);
+     474         116 : }
+     475             : 
+     476             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DomainDecomposition.h.func-sort-c.html b/coverage/core/DomainDecomposition.h.func-sort-c.html new file mode 100644 index 000000000000..2a05d37e41e3 --- /dev/null +++ b/coverage/core/DomainDecomposition.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/DomainDecomposition.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DomainDecomposition.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19DomainDecomposition11DomainCommsC2Ev936
_ZNK4PLMD19DomainDecomposition6onStepEv1654
_ZN4PLMD19DomainDecomposition25castToDomainDecompositionEv3544
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DomainDecomposition.h.func.html b/coverage/core/DomainDecomposition.h.func.html new file mode 100644 index 000000000000..fbfe0599da1e --- /dev/null +++ b/coverage/core/DomainDecomposition.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/DomainDecomposition.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DomainDecomposition.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19DomainDecomposition11DomainCommsC2Ev936
_ZN4PLMD19DomainDecomposition25castToDomainDecompositionEv3544
_ZNK4PLMD19DomainDecomposition6onStepEv1654
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/DomainDecomposition.h.gcov.html b/coverage/core/DomainDecomposition.h.gcov.html new file mode 100644 index 000000000000..277f4952a1d8 --- /dev/null +++ b/coverage/core/DomainDecomposition.h.gcov.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage - core/DomainDecomposition.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - DomainDecomposition.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_DomainDecomposition_h
+      23             : #define __PLUMED_core_DomainDecomposition_h
+      24             : 
+      25             : #include "ActionForInterface.h"
+      26             : #include "tools/Communicator.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : class ActionToPutData;
+      31             : class ActionAtomistic;
+      32             : 
+      33             : class DomainDecomposition : public ActionForInterface {
+      34             : private:
+      35             :   class DomainComms : public Communicator {
+      36             :   public:
+      37             :     bool on;
+      38             :     bool async;
+      39             : 
+      40             :     std::vector<Communicator::Request> mpi_request_positions;
+      41             :     std::vector<Communicator::Request> mpi_request_index;
+      42             : 
+      43             :     std::vector<double> positionsToBeSent;
+      44             :     std::vector<double> positionsToBeReceived;
+      45             :     std::vector<int>    indexToBeSent;
+      46             :     std::vector<int>    indexToBeReceived;
+      47      252918 :     operator bool() const {return on;}
+      48         936 :     DomainComms(): on(false), async(false) {}
+      49             :     void enable(Communicator& c);
+      50             :   };
+      51             :   DomainComms dd;
+      52             :   long int ddStep;
+      53             : 
+      54             :   std::vector<int>    gatindex;
+      55             : /// Map global indexes to local indexes
+      56             : /// E.g. g2l[i] is the position of atom i in the array passed from the MD engine.
+      57             : /// Called "global to local" since originally it was used to map global indexes to local
+      58             : /// ones used in domain decomposition. However, it is now also used for the NAMD-like
+      59             : /// interface, where only a small number of atoms is passed to plumed.
+      60             :   std::vector<int> g2l;
+      61             : 
+      62             :   unsigned shuffledAtoms;
+      63             : 
+      64             :   bool asyncSent;
+      65             :   bool unique_serial; // use unique in serial mode
+      66             : /// This holds the list of unique atoms
+      67             :   std::vector<AtomNumber> unique;
+      68             :   std::vector<unsigned> uniq_index;
+      69             : /// This holds the list of actions that are set from this action
+      70             :   std::vector<ActionToPutData*> inputs;
+      71             : /// This holds all the actions that read atoms
+      72             :   std::vector<ActionAtomistic*> actions;
+      73             : /// The list that holds all the atom indexes we need
+      74             :   std::vector<int> fullList;
+      75             : /// This actually does the sharing of the data across the domains
+      76             :   void share(const std::vector<AtomNumber>& unique);
+      77             : /// Get all the atoms in the input that are active at this time
+      78             :   void getAllActiveAtoms( std::vector<AtomNumber>& u );
+      79             : public:
+      80             :   static void registerKeywords(Keywords& keys);
+      81             :   explicit DomainDecomposition(const ActionOptions&ao);
+      82             :   void setStart( const std::string& name, const unsigned& sss) override ;
+      83             :   void setStride( const std::string& name, const unsigned& sss) override ;
+      84             :   void resetForStepStart() override ;
+      85             :   bool setValuePointer( const std::string& name, const TypesafePtr & ) override ;
+      86             :   bool setForcePointer( const std::string& name, const TypesafePtr & ) override ;
+      87             :   unsigned getNumberOfForcesToRescale() const override ;
+      88             :   void share() override ;
+      89             :   void shareAll() override ;
+      90             :   void wait() override ;
+      91             :   void reset() override ;
+      92             :   void writeBinary(std::ostream&o) override ;
+      93             :   void readBinary(std::istream&i) override ;
+      94             :   void apply() override ;
+      95             :   void setAtomsNlocal(int n);
+      96             :   void setAtomsGatindex(const TypesafePtr & g,bool fortran);
+      97             :   void setAtomsContiguous(int start);
+      98             :   void Set_comm(Communicator& comm) override ;
+      99             :   void broadcastToDomains( Value* val );
+     100             :   void sumOverDomains( Value* val );
+     101             :   const long int& getDdStep() const ;
+     102             :   const std::vector<int>& getGatindex() const ;
+     103             :   void createFullList(const TypesafePtr & x);
+     104             :   void getFullList(const TypesafePtr & x);
+     105             :   void clearFullList();
+     106        1654 :   bool onStep() const override { return getNumberOfAtoms()>0; }
+     107             :   unsigned getNumberOfAtoms() const;
+     108        3544 :   DomainDecomposition* castToDomainDecomposition() noexcept final { return this; }
+     109             : };
+     110             : 
+     111             : }
+     112             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ExchangePatterns.cpp.func-sort-c.html b/coverage/core/ExchangePatterns.cpp.func-sort-c.html new file mode 100644 index 000000000000..3989bd76e65e --- /dev/null +++ b/coverage/core/ExchangePatterns.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ExchangePatterns.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ExchangePatterns.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:52619.2 %
Date:2024-02-22 21:58:45Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ExchangePatterns7getFlagERi0
_ZN4PLMD16ExchangePatterns7getListERKNS_11TypesafePtrE0
_ZN4PLMD16ExchangePatterns7setFlagEi0
_ZN4PLMD16ExchangePatterns7setNofREi0
_ZN4PLMD16ExchangePatterns7setSeedEi0
_ZN4PLMD16ExchangePatternsC2Ev805283
_ZN4PLMD16ExchangePatternsD2Ev805283
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ExchangePatterns.cpp.func.html b/coverage/core/ExchangePatterns.cpp.func.html new file mode 100644 index 000000000000..7e8f837b4659 --- /dev/null +++ b/coverage/core/ExchangePatterns.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/ExchangePatterns.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ExchangePatterns.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:52619.2 %
Date:2024-02-22 21:58:45Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16ExchangePatterns7getFlagERi0
_ZN4PLMD16ExchangePatterns7getListERKNS_11TypesafePtrE0
_ZN4PLMD16ExchangePatterns7setFlagEi0
_ZN4PLMD16ExchangePatterns7setNofREi0
_ZN4PLMD16ExchangePatterns7setSeedEi0
_ZN4PLMD16ExchangePatternsC2Ev805283
_ZN4PLMD16ExchangePatternsD2Ev805283
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/ExchangePatterns.cpp.gcov.html b/coverage/core/ExchangePatterns.cpp.gcov.html new file mode 100644 index 000000000000..2faf63e5245d --- /dev/null +++ b/coverage/core/ExchangePatterns.cpp.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - core/ExchangePatterns.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - ExchangePatterns.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:52619.2 %
Date:2024-02-22 21:58:45Functions:2728.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ExchangePatterns.h"
+      23             : #include "tools/Random.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27      805283 : ExchangePatterns::ExchangePatterns():
+      28      805283 :   PatternFlag(NONE),
+      29      805283 :   NumberOfReplicas(1)
+      30      805283 : {}
+      31             : 
+      32      805283 : ExchangePatterns::~ExchangePatterns() {}
+      33             : 
+      34           0 : void ExchangePatterns::setNofR(const int nrepl) {
+      35           0 :   NumberOfReplicas=nrepl;
+      36           0 : }
+      37             : 
+      38           0 : void ExchangePatterns::setFlag(const int flag) {
+      39           0 :   PatternFlag=flag;
+      40           0 : }
+      41             : 
+      42           0 : void ExchangePatterns::getFlag(int &flag) {
+      43           0 :   flag=PatternFlag;
+      44           0 : }
+      45             : 
+      46           0 : void ExchangePatterns::setSeed(const int seed)
+      47             : {
+      48           0 :   random.setSeed(seed);
+      49           0 : }
+      50             : 
+      51           0 : void ExchangePatterns::getList(const TypesafePtr & ind)
+      52             : {
+      53           0 :   auto iind=ind.get<int*>(NumberOfReplicas);
+      54           0 :   switch(PatternFlag)
+      55             :   {
+      56             :   case RANDOM:
+      57           0 :     for(int i=0; i<NumberOfReplicas; i++) {
+      58             :       int stat=1;
+      59           0 :       while(stat) {
+      60             :         stat=0;
+      61           0 :         iind[i] = (int) (random.U01()*NumberOfReplicas);
+      62           0 :         for(int j=0; j<i; j++) if(iind[i]==iind[j]) stat=1;
+      63             :       }
+      64             :     }
+      65             :     break;
+      66             :   case NEIGHBOR:
+      67           0 :     for(int i=0; i<NumberOfReplicas; i++) iind[i]=i;
+      68             :     break;
+      69             :   }
+      70           0 : }
+      71             : 
+      72             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/FlexibleBin.cpp.func-sort-c.html b/coverage/core/FlexibleBin.cpp.func-sort-c.html new file mode 100644 index 000000000000..a2568b542c09 --- /dev/null +++ b/coverage/core/FlexibleBin.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/FlexibleBin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - FlexibleBin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11514678.8 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11FlexibleBin9getMatrixEv0
_ZN4PLMD11FlexibleBinC2EiPNS_19ActionWithArgumentsEjRKdRSt6vectorIdSaIdEERKS7_8
_ZN4PLMD11FlexibleBinC2EiPNS_19ActionWithArgumentsERKdRSt6vectorIdSaIdEERKS7_22
_ZNK4PLMD11FlexibleBin16getInverseMatrixEj72
_ZN4PLMD11FlexibleBin6updateEbj80
_ZNK4PLMD11FlexibleBin16getInverseMatrixEv374
_ZN4PLMD11FlexibleBin6updateEb778
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/FlexibleBin.cpp.func.html b/coverage/core/FlexibleBin.cpp.func.html new file mode 100644 index 000000000000..410a2b264c74 --- /dev/null +++ b/coverage/core/FlexibleBin.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - core/FlexibleBin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - FlexibleBin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11514678.8 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11FlexibleBin6updateEb778
_ZN4PLMD11FlexibleBin6updateEbj80
_ZN4PLMD11FlexibleBinC2EiPNS_19ActionWithArgumentsERKdRSt6vectorIdSaIdEERKS7_22
_ZN4PLMD11FlexibleBinC2EiPNS_19ActionWithArgumentsEjRKdRSt6vectorIdSaIdEERKS7_8
_ZNK4PLMD11FlexibleBin16getInverseMatrixEj72
_ZNK4PLMD11FlexibleBin16getInverseMatrixEv374
_ZNK4PLMD11FlexibleBin9getMatrixEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/FlexibleBin.cpp.gcov.html b/coverage/core/FlexibleBin.cpp.gcov.html new file mode 100644 index 000000000000..b00f4fb3eb1e --- /dev/null +++ b/coverage/core/FlexibleBin.cpp.gcov.html @@ -0,0 +1,413 @@ + + + + + + + + LCOV - plumed test coverage - core/FlexibleBin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - FlexibleBin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11514678.8 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "FlexibleBin.h"
+      23             : #include "ActionWithArguments.h"
+      24             : #include <cmath>
+      25             : #include <iostream>
+      26             : #include <vector>
+      27             : #include "tools/Matrix.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : 
+      32          22 : FlexibleBin::FlexibleBin(int type, ActionWithArguments *paction, double const &d, std::vector<double> &smin, const std::vector<double> &smax):
+      33          22 :   type(type),
+      34          22 :   paction(paction),
+      35          22 :   sigma(d),
+      36          22 :   sigmamin(smin),
+      37          22 :   sigmamax(smax)
+      38             : {
+      39             :   // initialize the averages and the variance matrices
+      40          22 :   if(type==diffusion) {
+      41           3 :     unsigned ncv=paction->getNumberOfArguments();
+      42           3 :     std::vector<double> average(ncv*(ncv+1)/2);
+      43           3 :     std::vector<double> variance(ncv*(ncv+1)/2);
+      44             :   }
+      45          22 :   paction->log<<"  Limits for sigmas using adaptive hills:  \n";
+      46          64 :   for(unsigned i=0; i<paction->getNumberOfArguments(); ++i) {
+      47          42 :     paction->log<<"   CV  "<<paction->getPntrToArgument(i)->getName()<<":\n";
+      48          42 :     if(sigmamin[i]>0.) {
+      49           0 :       limitmin.push_back(true);
+      50           0 :       paction->log<<"       Min "<<sigmamin[i];
+      51           0 :       sigmamin[i]*=sigmamin[i]; // this is because the matrix which is calculated is the sigmasquared
+      52             :     } else {
+      53          42 :       limitmin.push_back(false);
+      54          42 :       paction->log<<"       Min No ";
+      55             :     }
+      56          42 :     if(sigmamax[i]>0.) {
+      57           0 :       limitmax.push_back(true);
+      58           0 :       paction->log<<"       Max "<<sigmamax[i];
+      59           0 :       sigmamax[i]*=sigmamax[i];
+      60             :     } else {
+      61          42 :       limitmax.push_back(false);
+      62          42 :       paction->log<<"       Max No ";
+      63             :     }
+      64          42 :     paction->log<<" \n";
+      65             :   }
+      66             : 
+      67          22 : }
+      68             : 
+      69             : /// Constructure for 1D FB for PBMETAD
+      70           8 : FlexibleBin::FlexibleBin(int type, ActionWithArguments *paction, unsigned iarg,
+      71           8 :                          double const &d, std::vector<double> &smin, const std::vector<double> &smax):
+      72           8 :   type(type),paction(paction),sigma(d),sigmamin(smin),sigmamax(smax)
+      73             : {
+      74             :   // initialize the averages and the variance matrices
+      75           8 :   if(type==diffusion) {
+      76           8 :     std::vector<double> average(1);
+      77           8 :     std::vector<double> variance(1);
+      78             :   }
+      79           8 :   paction->log<<"  Limits for sigmas using adaptive hills:  \n";
+      80           8 :   paction->log<<"   CV  "<<paction->getPntrToArgument(iarg)->getName()<<":\n";
+      81           8 :   if(sigmamin[0]>0.) {
+      82           8 :     limitmin.push_back(true);
+      83           8 :     paction->log<<"       Min "<<sigmamin[0];
+      84           8 :     sigmamin[0]*=sigmamin[0];
+      85             :   } else {
+      86           0 :     limitmin.push_back(false);
+      87           0 :     paction->log<<"       Min No ";
+      88             :   }
+      89           8 :   if(sigmamax[0]>0.) {
+      90           0 :     limitmax.push_back(true);
+      91           0 :     paction->log<<"       Max "<<sigmamax[0];
+      92           0 :     sigmamax[0]*=sigmamax[0];
+      93             :   } else {
+      94           8 :     limitmax.push_back(false);
+      95           8 :     paction->log<<"       Max No ";
+      96             :   }
+      97           8 :   paction->log<<" \n";
+      98           8 : }
+      99             : 
+     100             : /// Update the flexible bin
+     101             : /// in case of diffusion based: update at every step
+     102             : /// in case of gradient based: update only when you add the hill
+     103         778 : void FlexibleBin::update(bool nowAddAHill) {
+     104         778 :   unsigned ncv=paction->getNumberOfArguments();
+     105         778 :   unsigned dimension=ncv*(ncv+1)/2;
+     106             :   std::vector<double> delta;
+     107             :   std::vector<double> cv;
+     108         778 :   double decay=1./sigma;
+     109             :   // this is done all the times from scratch. It is not an accumulator
+     110             :   // here update the flexible bin according to the needs
+     111         778 :   switch (type) {
+     112             :   // This should be called every time
+     113         586 :   case diffusion:
+     114             :     // if you use this below then the decay is in time units
+     115             :     //double decay=paction->getTimeStep()/sigma;
+     116             :     // to be consistent with the rest of the program: everything is better to be in timesteps
+     117             :     // THE AVERAGE VALUE
+     118             :     // beware: the pbc
+     119         586 :     delta.resize(ncv);
+     120        1172 :     for(unsigned i=0; i<ncv; i++) cv.push_back(paction->getArgument(i));
+     121         586 :     if(average.size()==0) { // initial time: just set the initial vector
+     122           2 :       average.resize(ncv);
+     123           4 :       for(unsigned i=0; i<ncv; i++) average[i]=cv[i];
+     124             :     } else { // accumulate
+     125        1168 :       for(unsigned i=0; i<ncv; i++) {
+     126         584 :         delta[i]=paction->difference(i,average[i],cv[i]);
+     127         584 :         average[i]+=decay*delta[i];
+     128         584 :         average[i]=paction->bringBackInPbc(i,average[i]); // equation 8 of "Metadynamics with adaptive Gaussians"
+     129             :       }
+     130             :     }
+     131             :     // THE VARIANCE
+     132         586 :     if(variance.size()==0) {
+     133           2 :       variance.resize(dimension,0.); // nonredundant members dimension=ncv*(ncv+1)/2;
+     134             :     } else {
+     135             :       unsigned k=0;
+     136        1168 :       for(unsigned i=0; i<ncv; i++) {
+     137        1168 :         for(unsigned j=i; j<ncv; j++) { // upper diagonal loop
+     138         584 :           variance[k]+=decay*(delta[i]*delta[j]-variance[k]);
+     139         584 :           k++;
+     140             :         }
+     141             :       }
+     142             :     }
+     143             :     break;
+     144         192 :   case geometry:
+     145             :     //this calculates in variance the \nabla CV_i \dot \nabla CV_j
+     146         192 :     variance.resize(dimension);
+     147             :     // now the signal for retrieving the gradients should be already given by checkNeedsGradients.
+     148             :     // here just do the projections
+     149             :     // note that the call  checkNeedsGradients() in BiasMetaD takes care of switching on the call to gradients
+     150         192 :     if (nowAddAHill) { // geometry is sync with hill deposition
+     151             :       unsigned k=0;
+     152         249 :       for(unsigned i=0; i<ncv; i++) {
+     153         415 :         for(unsigned j=i; j<ncv; j++) {
+     154             :           // eq 12 of "Metadynamics with adaptive Gaussians"
+     155         249 :           variance[k]=sigma*sigma*(paction->getProjection(i,j));
+     156         249 :           k++;
+     157             :         }
+     158             :       }
+     159             :     }
+     160             :     break;
+     161           0 :   default:
+     162           0 :     plumed_merror("This flexible bin method is not recognized");
+     163             :   }
+     164         778 : }
+     165             : 
+     166           0 : std::vector<double> FlexibleBin::getMatrix() const {
+     167           0 :   return variance;
+     168             : }
+     169             : 
+     170             : /// Update the flexible bin for PBMetaD like FlexBin
+     171             : /// in case of diffusion based: update at every step
+     172             : /// in case of gradient based: update only when you add the hill
+     173          80 : void FlexibleBin::update(bool nowAddAHill, unsigned iarg) {
+     174             :   // this is done all the times from scratch. It is not an accumulator
+     175             :   // here update the flexible bin according to the needs
+     176             :   std::vector<double> cv;
+     177             :   std::vector<double> delta;
+     178             :   // if you use this below then the decay is in time units
+     179             :   // to be consistent with the rest of the program: everything is better to be in timesteps
+     180          80 :   double decay=1./sigma;
+     181          80 :   switch (type) {
+     182             :   // This should be called every time
+     183          80 :   case diffusion:
+     184             :     // THE AVERAGE VALUE
+     185          80 :     delta.resize(1);
+     186          80 :     cv.push_back(paction->getArgument(iarg));
+     187          80 :     if(average.size()==0) { // initial time: just set the initial vector
+     188           8 :       average.resize(1);
+     189           8 :       average[0]=cv[0];
+     190             :     } else { // accumulate
+     191          72 :       delta[0]=paction->difference(iarg,average[0],cv[0]);
+     192          72 :       average[0]+=decay*delta[0];
+     193          72 :       average[0]=paction->bringBackInPbc(iarg,average[0]); // equation 8 of "Metadynamics with adaptive Gaussians"
+     194             :     }
+     195             :     // THE VARIANCE
+     196          80 :     if(variance.size()==0) {
+     197           8 :       variance.resize(1,0.); // nonredundant members dimension=ncv*(ncv+1)/2;
+     198             :     } else {
+     199          72 :       variance[0]+=decay*(delta[0]*delta[0]-variance[0]);
+     200             :     }
+     201             :     break;
+     202           0 :   case geometry:
+     203             :     //this calculates in variance the \nabla CV_i \dot \nabla CV_j
+     204           0 :     variance.resize(1);
+     205             :     // now the signal for retrieving the gradients should be already given by checkNeedsGradients.
+     206             :     // here just do the projections
+     207             :     // note that the call  checkNeedsGradients() in BiasMetaD takes care of switching on the call to gradients
+     208           0 :     if (nowAddAHill) { // geometry is sync with hill deposition
+     209             :       // eq 12 of "Metadynamics with adaptive Gaussians"
+     210           0 :       variance[0]=sigma*sigma*(paction->getProjection(iarg,iarg));
+     211             :     }
+     212             :     break;
+     213           0 :   default:
+     214           0 :     plumed_merror("This flexible bin is not recognized");
+     215             :   }
+     216          80 : }
+     217             : 
+     218             : ///
+     219             : /// Calculate the matrix of  (dcv_i/dx)*(dcv_j/dx)^-1
+     220             : /// that is needed for the metrics in metadynamics
+     221             : ///
+     222             : ///
+     223         374 : std::vector<double> FlexibleBin::getInverseMatrix() const {
+     224         374 :   unsigned ncv=paction->getNumberOfArguments();
+     225             :   Matrix<double> matrix(ncv,ncv);
+     226             :   unsigned i,j,k;
+     227             :   k=0;
+     228             :   // place the matrix in a complete matrix for compatibility
+     229         831 :   for (i=0; i<ncv; i++) {
+     230         997 :     for (j=i; j<ncv; j++) {
+     231         540 :       matrix(j,i)=matrix(i,j)=variance[k];
+     232         540 :       k++;
+     233             :     }
+     234             :   }
+     235             : #define NEWFLEX
+     236             : #ifdef NEWFLEX
+     237             :   // diagonalize to impose boundaries (only if boundaries are set)
+     238             :   Matrix<double>      eigenvecs(ncv,ncv);
+     239         374 :   std::vector<double> eigenvals(ncv);
+     240             : 
+     241             :   //eigenvecs: first is eigenvec number, second is eigenvec component
+     242         374 :   if(diagMat( matrix, eigenvals, eigenvecs )!=0) {plumed_merror("diagonalization in FlexibleBin failed! This matrix is weird\n");};
+     243             : 
+     244         831 :   for (i=0; i<ncv; i++) { //loop on the dimension
+     245         457 :     if( limitmax[i] ) {
+     246             :       //limit every  component that is larger
+     247           0 :       for (j=0; j<ncv; j++) { //loop on components
+     248           0 :         if(std::pow(eigenvals[j]*eigenvecs[j][i],2)>std::pow(sigmamax[i],2) ) {
+     249           0 :           eigenvals[j]=std::sqrt(std::pow(sigmamax[i]/(eigenvecs[j][i]),2))*copysign(1.,eigenvals[j]);
+     250             :         }
+     251             :       }
+     252             :     }
+     253             :   }
+     254         831 :   for (i=0; i<ncv; i++) { //loop on the dimension
+     255             :     // find the largest one:  if it is smaller than min  then rescale
+     256         457 :     if( limitmin[i] ) {
+     257             :       unsigned imax=0;
+     258             :       double fmax=-1.e10;
+     259           0 :       for (j=0; j<ncv; j++) { //loop on components
+     260           0 :         double fact=std::pow(eigenvals[j]*eigenvecs[j][i],2);
+     261           0 :         if(fact>fmax) {
+     262             :           fmax=fact; imax=j;
+     263             :         }
+     264             :       }
+     265           0 :       if(fmax<std::pow(sigmamin[i],2) ) {
+     266           0 :         eigenvals[imax]=std::sqrt(std::pow(sigmamin[i]/(eigenvecs[imax][i]),2))*copysign(1.,eigenvals[imax]);
+     267             :       }
+     268             :     }
+     269             :   }
+     270             : 
+     271             :   // normalize eigenvecs
+     272             :   Matrix<double> newinvmatrix(ncv,ncv);
+     273         831 :   for (i=0; i<ncv; i++) {
+     274        1080 :     for (j=0; j<ncv; j++) {
+     275         623 :       newinvmatrix[j][i]=eigenvecs[j][i]/eigenvals[j];
+     276             :     }
+     277             :   }
+     278             : 
+     279         374 :   std::vector<double> uppervec(ncv*(ncv+1)/2);
+     280             :   k=0;
+     281         831 :   for (i=0; i<ncv; i++) {
+     282         997 :     for (j=i; j<ncv; j++) {
+     283             :       double scal=0;
+     284        1329 :       for(unsigned l=0; l<ncv; ++l) {
+     285         789 :         scal+=eigenvecs[l][i]*newinvmatrix[l][j];
+     286             :       }
+     287         540 :       uppervec[k]=scal; k++;
+     288             :     }
+     289             :   }
+     290             : #else
+     291             :   // get the inverted matrix
+     292             :   Matrix<double> invmatrix(ncv,ncv);
+     293             :   Invert(matrix,invmatrix);
+     294             :   std::vector<double> uppervec(ncv*(ncv+1)/2);
+     295             :   // upper diagonal of the inverted matrix (that is symmetric)
+     296             :   k=0;
+     297             :   for (i=0; i<ncv; i++) {
+     298             :     for (j=i; j<ncv; j++) {
+     299             :       uppervec[k]=invmatrix(i,j);
+     300             :       k++;
+     301             :     }
+     302             :   }
+     303             : #endif
+     304         374 :   return uppervec;
+     305             : }
+     306             : 
+     307             : ///
+     308             : /// Calculate the matrix of  (dcv_i/dx)*(dcv_j/dx)^-1
+     309             : /// that is needed for the metrics in metadynamics
+     310             : /// for PBMetaD like FlexBin
+     311             : ///
+     312          72 : std::vector<double> FlexibleBin::getInverseMatrix(unsigned iarg) const {
+     313             :   // diagonalize to impose boundaries (only if boundaries are set)
+     314          72 :   std::vector<double> eigenvals(1, variance[0]);
+     315          72 :   if( limitmax[0] ) {
+     316           0 :     if(eigenvals[0]>sigmamax[0]) {
+     317           0 :       eigenvals[0]=sigmamax[0];
+     318             :     }
+     319             :   }
+     320             :   // find the largest one:  if it is smaller than min  then rescale
+     321          72 :   if( limitmin[0] ) {
+     322             :     double fmax=-1.e10;
+     323          72 :     double fact=eigenvals[0];
+     324          72 :     if(fact>fmax) {
+     325             :       fmax=fact;
+     326             :     }
+     327          72 :     if(fmax<sigmamin[0]) {
+     328          72 :       eigenvals[0]=sigmamin[0];
+     329             :     }
+     330             :   }
+     331          72 :   std::vector<double> uppervec(1,1./eigenvals[0]);
+     332             : 
+     333          72 :   return uppervec;
+     334             : }
+     335             : 
+     336             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GREX.cpp.func-sort-c.html b/coverage/core/GREX.cpp.func-sort-c.html new file mode 100644 index 000000000000..48527fb6227c --- /dev/null +++ b/coverage/core/GREX.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/GREX.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GREX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10013375.2 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4GREX13savePositionsEv114
_ZN4PLMD4GREX9calculateEv114
_ZN4PLMD4GREXC2ERNS_10PlumedMainE204
_ZN4PLMD4GREXD0Ev204
_ZN4PLMD4GREXD2Ev204
_ZN4PLMD4GREX3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE1077
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GREX.cpp.func.html b/coverage/core/GREX.cpp.func.html new file mode 100644 index 000000000000..29ea51dff91a --- /dev/null +++ b/coverage/core/GREX.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/GREX.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GREX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10013375.2 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4GREX13savePositionsEv114
_ZN4PLMD4GREX3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE1077
_ZN4PLMD4GREX9calculateEv114
_ZN4PLMD4GREXC2ERNS_10PlumedMainE204
_ZN4PLMD4GREXD0Ev204
_ZN4PLMD4GREXD2Ev204
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GREX.cpp.gcov.html b/coverage/core/GREX.cpp.gcov.html new file mode 100644 index 000000000000..73fb0881ebf0 --- /dev/null +++ b/coverage/core/GREX.cpp.gcov.html @@ -0,0 +1,292 @@ + + + + + + + + LCOV - plumed test coverage - core/GREX.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GREX.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10013375.2 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "GREX.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "tools/Communicator.h"
+      26             : #include <sstream>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30         204 : GREX::GREX(PlumedMain&p):
+      31         204 :   initialized(false),
+      32         204 :   plumedMain(p),
+      33         204 :   partner(-1), // = unset
+      34         204 :   localDeltaBias(0),
+      35         204 :   foreignDeltaBias(0),
+      36         204 :   localUNow(0),
+      37         204 :   localUSwap(0),
+      38         204 :   myreplica(-1) // = unset
+      39             : {
+      40         204 :   p.setSuffix(".NA");
+      41         204 : }
+      42             : 
+      43         408 : GREX::~GREX() {
+      44             : // empty destructor to delete unique_ptr
+      45         408 : }
+      46             : 
+      47             : #define CHECK_INIT(ini,word) plumed_assert(ini) << "cmd(\"" << word <<"\") should be only used after GREX initialization"
+      48             : #define CHECK_NOTINIT(ini,word) plumed_assert(!(ini)) << "cmd(\"" << word <<"\") should be only used before GREX initialization"
+      49             : #define CHECK_NOTNULL(val,word) plumed_assert(val) << "NULL pointer received in cmd(\"GREX " << word << "\")"
+      50             : 
+      51        1077 : void GREX::cmd(std::string_view key,const TypesafePtr & val) {
+      52             : // Enumerate all possible commands:
+      53             :   enum {
+      54             : #include "GREXEnum.inc"
+      55             :   };
+      56             : 
+      57             : // Static object (initialized once) containing the map of commands:
+      58             :   const static Tools::FastStringUnorderedMap<int> word_map = {
+      59             : #include "GREXMap.inc"
+      60        1077 :   };
+      61             : 
+      62             :   gch::small_vector<std::string_view> words;
+      63        1077 :   Tools::getWordsSimple(words,key);
+      64        1077 :   unsigned nw=words.size();
+      65        1077 :   if(nw==0) {
+      66             :     // do nothing
+      67             :   } else {
+      68             :     int iword=-1;
+      69             :     const auto it=word_map.find(words[0]);
+      70        1077 :     if(it!=word_map.end()) iword=it->second;
+      71        1077 :     switch(iword) {
+      72             :     case cmd_initialized:
+      73           0 :       CHECK_NOTNULL(val,key);
+      74           0 :       val.set(int(initialized));
+      75             :       break;
+      76         204 :     case cmd_setMPIIntracomm:
+      77         204 :       CHECK_NOTINIT(initialized,key);
+      78         408 :       intracomm.Set_comm(val.get<const void*>());
+      79         204 :       break;
+      80         156 :     case cmd_setMPIIntercomm:
+      81         156 :       CHECK_NOTINIT(initialized,key);
+      82         312 :       intercomm.Set_comm(val.get<const void*>());
+      83         312 :       plumedMain.multi_sim_comm.Set_comm(val.get<const void*>());
+      84         156 :       break;
+      85           0 :     case cmd_setMPIFIntracomm:
+      86           0 :       CHECK_NOTINIT(initialized,key);
+      87           0 :       intracomm.Set_fcomm(val.get<const void*>());
+      88           0 :       break;
+      89           0 :     case cmd_setMPIFIntercomm:
+      90           0 :       CHECK_NOTINIT(initialized,key);
+      91           0 :       intercomm.Set_fcomm(val.get<const void*>());
+      92           0 :       plumedMain.multi_sim_comm.Set_fcomm(val.get<const void*>());
+      93           0 :       break;
+      94         204 :     case cmd_init:
+      95         204 :       CHECK_NOTINIT(initialized,key);
+      96         204 :       initialized=true;
+      97             : // note that for PEs!=root this is automatically 0 (comm defaults to MPI_COMM_SELF)
+      98         204 :       myreplica=intercomm.Get_rank();
+      99         204 :       intracomm.Sum(myreplica);
+     100             :       {
+     101             :         std::string s;
+     102         204 :         Tools::convert(myreplica,s);
+     103         408 :         plumedMain.setSuffix("."+s);
+     104             :       }
+     105         204 :       break;
+     106          57 :     case cmd_prepare:
+     107          57 :       CHECK_INIT(initialized,key);
+     108          57 :       if(intracomm.Get_rank()==0) return;
+     109          57 :       intracomm.Bcast(partner,0);
+     110          57 :       calculate();
+     111             :       break;
+     112          57 :     case cmd_setPartner:
+     113          57 :       CHECK_INIT(initialized,key);
+     114          57 :       partner=val.get<int>();
+     115          57 :       break;
+     116         114 :     case cmd_savePositions:
+     117         114 :       CHECK_INIT(initialized,key);
+     118         114 :       savePositions();
+     119             :       break;
+     120          57 :     case cmd_calculate:
+     121          57 :       CHECK_INIT(initialized,key);
+     122          57 :       if(intracomm.Get_rank()!=0) return;
+     123          57 :       intracomm.Bcast(partner,0);
+     124          57 :       calculate();
+     125             :       break;
+     126           0 :     case cmd_getLocalDeltaBias:
+     127           0 :       CHECK_INIT(initialized,key);
+     128           0 :       CHECK_NOTNULL(val,key);
+     129           0 :       plumedMain.plumedQuantityToMD("energy",localDeltaBias,val);
+     130           0 :       break;
+     131           0 :     case cmd_cacheLocalUNow:
+     132           0 :       CHECK_INIT(initialized,key);
+     133           0 :       CHECK_NOTNULL(val,key);
+     134             :       {
+     135           0 :         localUNow=plumedMain.MDQuantityToPLUMED("energy",val);
+     136           0 :         intracomm.Sum(localUNow);
+     137             :       }
+     138             :       break;
+     139           0 :     case cmd_cacheLocalUSwap:
+     140           0 :       CHECK_INIT(initialized,key);
+     141           0 :       CHECK_NOTNULL(val,key);
+     142             :       {
+     143           0 :         localUSwap=plumedMain.MDQuantityToPLUMED("energy",val);
+     144           0 :         intracomm.Sum(localUSwap);
+     145             :       }
+     146             :       break;
+     147           0 :     case cmd_getForeignDeltaBias:
+     148           0 :       CHECK_INIT(initialized,key);
+     149           0 :       CHECK_NOTNULL(val,key);
+     150           0 :       plumedMain.plumedQuantityToMD("energy",foreignDeltaBias,val);
+     151           0 :       break;
+     152          57 :     case cmd_shareAllDeltaBias:
+     153          57 :       CHECK_INIT(initialized,key);
+     154          57 :       if(intracomm.Get_rank()!=0) return;
+     155          57 :       allDeltaBias.assign(intercomm.Get_size(),0.0);
+     156          57 :       allDeltaBias[intercomm.Get_rank()]=localDeltaBias;
+     157          57 :       intercomm.Sum(allDeltaBias);
+     158             :       break;
+     159         171 :     case cmd_getDeltaBias:
+     160         171 :       CHECK_INIT(initialized,key);
+     161         171 :       CHECK_NOTNULL(val,key);
+     162         171 :       plumed_assert(nw==2);
+     163         171 :       plumed_massert(allDeltaBias.size()==static_cast<unsigned>(intercomm.Get_size()),
+     164             :                      "to retrieve bias with cmd(\"GREX getDeltaBias\"), first share it with cmd(\"GREX shareAllDeltaBias\")");
+     165             :       {
+     166             :         unsigned rep;
+     167         171 :         Tools::convert(std::string(words[1]),rep);
+     168         171 :         plumed_massert(rep<allDeltaBias.size(),"replica index passed to cmd(\"GREX getDeltaBias\") is out of range");
+     169         171 :         plumedMain.plumedQuantityToMD("energy",allDeltaBias[rep],val);
+     170             :       }
+     171         171 :       break;
+     172           0 :     default:
+     173           0 :       plumed_error() << "cannot interpret cmd(\" GREX" << key << "\"). check plumed developers manual to see the available commands.";
+     174             :       break;
+     175             :     }
+     176             :   }
+     177             : }
+     178             : 
+     179         114 : void GREX::savePositions() {
+     180         114 :   plumedMain.prepareDependencies();
+     181         114 :   plumedMain.resetActive(true);
+     182         114 :   plumedMain.shareAll();
+     183         114 :   plumedMain.waitData();
+     184         114 :   std::ostringstream o;
+     185         114 :   plumedMain.writeBinary(o);
+     186         114 :   buffer=o.str();
+     187         114 : }
+     188             : 
+     189         114 : void GREX::calculate() {
+     190             :   unsigned nn=buffer.size();
+     191         114 :   std::vector<char> rbuf(nn);
+     192         114 :   localDeltaBias=-plumedMain.getBias();
+     193         114 :   if(intracomm.Get_rank()==0) {
+     194          57 :     Communicator::Request req=intercomm.Isend(buffer,partner,1066);
+     195          57 :     intercomm.Recv(rbuf,partner,1066);
+     196          57 :     req.wait();
+     197             :   }
+     198         114 :   intracomm.Bcast(rbuf,0);
+     199         114 :   std::istringstream i(std::string(&rbuf[0],rbuf.size()));
+     200         114 :   plumedMain.readBinary(i);
+     201         114 :   plumedMain.setExchangeStep(true);
+     202         114 :   plumedMain.prepareDependencies();
+     203         114 :   plumedMain.justCalculate();
+     204         114 :   plumedMain.setExchangeStep(false);
+     205         114 :   localDeltaBias+=plumedMain.getBias();
+     206         114 :   localDeltaBias+=localUSwap-localUNow;
+     207         114 :   if(intracomm.Get_rank()==0) {
+     208          57 :     Communicator::Request req=intercomm.Isend(localDeltaBias,partner,1067);
+     209          57 :     intercomm.Recv(foreignDeltaBias,partner,1067);
+     210          57 :     req.wait();
+     211             :   }
+     212         114 :   intracomm.Bcast(foreignDeltaBias,0);
+     213         228 : }
+     214             : 
+     215             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.cpp.func-sort-c.html b/coverage/core/GenericMolInfo.cpp.func-sort-c.html new file mode 100644 index 000000000000..e70ecdb4bfd5 --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.func-sort-c.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18121982.6 %
Date:2024-02-22 21:58:45Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfoC2ERKNS_13ActionOptionsE0
_ZN4PLMD14GenericMolInfoD2Ev0
_ZNK4PLMD14GenericMolInfo10getChainIDB5cxx11ENS_10AtomNumberE0
_ZN4PLMD14GenericMolInfo18getSpecialKeywordsB5cxx11Ev1
_ZNK4PLMD14GenericMolInfo7isWholeEv1
_ZN4PLMD14GenericMolInfo11getBackboneERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS1_IS1_INS_10AtomNumberESaISD_EESaISF_EE25
_ZN4PLMD14GenericMolInfoC1ERKNS_13ActionOptionsE87
_ZN4PLMD14GenericMolInfoD0Ev87
_ZN4PLMD14GenericMolInfoD1Ev87
_ZN4PLMD14GenericMolInfo16registerKeywordsERNS_8KeywordsE89
_ZNK4PLMD14GenericMolInfo12checkForAtomENS_10AtomNumberE127
_ZN4PLMD14GenericMolInfo15interpretSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE597
_ZN4PLMD14GenericMolInfo7prepareEv5103
_ZNK4PLMD14GenericMolInfo14getResidueNameB5cxx11ENS_10AtomNumberE14176
_ZNK4PLMD14GenericMolInfo10getPDBsizeEv14820
_ZNK4PLMD14GenericMolInfo11getPositionENS_10AtomNumberE30260
_ZNK4PLMD14GenericMolInfo11getAtomNameB5cxx11ENS_10AtomNumberE46204
_ZNK4PLMD14GenericMolInfo16getResidueNumberENS_10AtomNumberE60228
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.cpp.func.html b/coverage/core/GenericMolInfo.cpp.func.html new file mode 100644 index 000000000000..4cffc3f20eff --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.func.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18121982.6 %
Date:2024-02-22 21:58:45Functions:151883.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo11getBackboneERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS1_IS1_INS_10AtomNumberESaISD_EESaISF_EE25
_ZN4PLMD14GenericMolInfo15interpretSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorINS_10AtomNumberESaISA_EE597
_ZN4PLMD14GenericMolInfo16registerKeywordsERNS_8KeywordsE89
_ZN4PLMD14GenericMolInfo18getSpecialKeywordsB5cxx11Ev1
_ZN4PLMD14GenericMolInfo7prepareEv5103
_ZN4PLMD14GenericMolInfoC1ERKNS_13ActionOptionsE87
_ZN4PLMD14GenericMolInfoC2ERKNS_13ActionOptionsE0
_ZN4PLMD14GenericMolInfoD0Ev87
_ZN4PLMD14GenericMolInfoD1Ev87
_ZN4PLMD14GenericMolInfoD2Ev0
_ZNK4PLMD14GenericMolInfo10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD14GenericMolInfo10getPDBsizeEv14820
_ZNK4PLMD14GenericMolInfo11getAtomNameB5cxx11ENS_10AtomNumberE46204
_ZNK4PLMD14GenericMolInfo11getPositionENS_10AtomNumberE30260
_ZNK4PLMD14GenericMolInfo12checkForAtomENS_10AtomNumberE127
_ZNK4PLMD14GenericMolInfo14getResidueNameB5cxx11ENS_10AtomNumberE14176
_ZNK4PLMD14GenericMolInfo16getResidueNumberENS_10AtomNumberE60228
_ZNK4PLMD14GenericMolInfo7isWholeEv1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.cpp.gcov.html b/coverage/core/GenericMolInfo.cpp.gcov.html new file mode 100644 index 000000000000..56e234c2ec07 --- /dev/null +++ b/coverage/core/GenericMolInfo.cpp.gcov.html @@ -0,0 +1,445 @@ + + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18121982.6 %
Date:2024-02-22 21:58:45Functions:151883.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "GenericMolInfo.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "ActionSet.h"
+      25             : #include "PlumedMain.h"
+      26             : #include "tools/MolDataClass.h"
+      27             : #include "tools/PDB.h"
+      28             : #include "tools/Communicator.h"
+      29             : #include "config/Config.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : 
+      34             : /*
+      35             : This action is defined in core/ as it is used by other actions.
+      36             : Anyway, it is registered in setup/, so that excluding that module from
+      37             : compilation will exclude it from plumed.
+      38             : */
+      39             : 
+      40             : 
+      41          89 : void GenericMolInfo::registerKeywords( Keywords& keys ) {
+      42          89 :   ActionSetup::registerKeywords(keys);
+      43         178 :   keys.add("compulsory","STRUCTURE","a file in pdb format containing a reference structure. "
+      44             :            "This is used to defines the atoms in the various residues, chains, etc . "
+      45             :            "For more details on the PDB file format visit http://www.wwpdb.org/docs.html");
+      46         178 :   keys.add("compulsory","MOLTYPE","protein","what kind of molecule is contained in the pdb file - usually not needed since protein/RNA/DNA are compatible");
+      47         178 :   keys.add("compulsory","PYTHON_BIN","default","python interpreter");
+      48         178 :   keys.add("atoms","CHAIN","(for masochists ( mostly Davide Branduardi ) ) The atoms involved in each of the chains of interest in the structure.");
+      49         178 :   keys.add("hidden","STRIDE","frequency for resetting the python interpreter. Should be 1.");
+      50         178 :   keys.addFlag("WHOLE", false, "The reference structure is whole, i.e. not broken by PBC");
+      51          89 : }
+      52             : 
+      53         174 : GenericMolInfo::~GenericMolInfo() {
+      54             : // empty destructor to delete unique_ptr
+      55         261 : }
+      56             : 
+      57          87 : GenericMolInfo::GenericMolInfo( const ActionOptions&ao ):
+      58             :   Action(ao),
+      59             :   ActionAnyorder(ao),
+      60             :   ActionPilot(ao),
+      61             :   ActionAtomistic(ao),
+      62          87 :   iswhole_(false)
+      63             : {
+      64          87 :   plumed_assert(getStride()==1);
+      65             :   // Read what is contained in the pdb file
+      66          87 :   parse("MOLTYPE",mytype);
+      67             : 
+      68             :   // check if whole
+      69          87 :   parseFlag("WHOLE", iswhole_);
+      70             : 
+      71          87 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      72          87 :   if( moldat ) log<<"  overriding last MOLINFO with label " << moldat->getLabel()<<"\n";
+      73             : 
+      74             :   std::vector<AtomNumber> backbone;
+      75         174 :   parseAtomList("CHAIN",backbone);
+      76          87 :   if( read_backbone.size()==0 ) {
+      77           0 :     for(unsigned i=1;; ++i) {
+      78         174 :       parseAtomList("CHAIN",i,backbone);
+      79          87 :       if( backbone.size()==0 ) break;
+      80           0 :       read_backbone.push_back(backbone);
+      81           0 :       backbone.resize(0);
+      82             :     }
+      83             :   } else {
+      84           0 :     read_backbone.push_back(backbone);
+      85             :   }
+      86          87 :   if( read_backbone.size()==0 ) {
+      87          87 :     parse("STRUCTURE",reference);
+      88             : 
+      89          87 :     if( ! pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()))plumed_merror("missing input file " + reference );
+      90             : 
+      91          87 :     std::vector<std::string> chains; pdb.getChainNames( chains );
+      92          87 :     log.printf("  pdb file named %s contains %u chains \n",reference.c_str(), static_cast<unsigned>(chains.size()));
+      93         248 :     for(unsigned i=0; i<chains.size(); ++i) {
+      94             :       unsigned start,end; std::string errmsg;
+      95         161 :       pdb.getResidueRange( chains[i], start, end, errmsg );
+      96         161 :       if( errmsg.length()!=0 ) error( errmsg );
+      97             :       AtomNumber astart,aend;
+      98         161 :       pdb.getAtomRange( chains[i], astart, aend, errmsg );
+      99         161 :       if( errmsg.length()!=0 ) error( errmsg );
+     100         161 :       log.printf("  chain named %s contains residues %u to %u and atoms %u to %u \n",chains[i].c_str(),start,end,astart.serial(),aend.serial());
+     101             :     }
+     102             : 
+     103             :     std::string python_bin;
+     104         174 :     parse("PYTHON_BIN",python_bin);
+     105          87 :     if(python_bin=="no") {
+     106           0 :       log<<"  python interpreter disabled\n";
+     107             :     } else {
+     108         174 :       pythonCmd=config::getEnvCommand();
+     109          87 :       if(python_bin!="default") {
+     110           0 :         log<<"  forcing python interpreter: "<<python_bin<<"\n";
+     111           0 :         pythonCmd+=" env PLUMED_PYTHON_BIN="+python_bin;
+     112             :       }
+     113             :       bool sorted=true;
+     114          87 :       const auto & at=pdb.getAtomNumbers();
+     115       91362 :       for(unsigned i=0; i<at.size(); i++) {
+     116       91275 :         if(at[i].index()!=i) sorted=false;
+     117             :       }
+     118          87 :       if(!sorted) {
+     119           1 :         log<<"  PDB is not sorted, python interpreter will be disabled\n";
+     120          86 :       } else if(!Subprocess::available()) {
+     121           0 :         log<<"  subprocess is not available, python interpreter will be disabled\n";
+     122             :       } else {
+     123          86 :         enablePythonInterpreter=true;
+     124             :       }
+     125             :     }
+     126          87 :   }
+     127          87 : }
+     128             : 
+     129           1 : std::map<std::string,std::string> GenericMolInfo::getSpecialKeywords() {
+     130             :   std::map<std::string,std::string> mapkeys;
+     131           1 :   mapkeys.insert( std::pair<std::string,std::string>("@mda:","atom selection built using syntax for <a href=\\\"https://docs.mdanalysis.org/stable/documentation_pages/selections.html\\\">MDAnalysis</a>") );
+     132           1 :   mapkeys.insert( std::pair<std::string,std::string>("@mdt:","atom selection built using syntax for <a href=\\\"https://www.mdtraj.org/1.9.8.dev0/index.html\\\">mdtraj</a>") );
+     133           1 :   mapkeys.insert( std::pair<std::string,std::string>("@vmdexec:","atom selection built using syntax for <a href=\\\"https://www.ks.uiuc.edu/Research/vmd/\\\">VMD</a>") );
+     134           1 :   mapkeys.insert( std::pair<std::string,std::string>("@vmd:","atom selection built using syntax for <a href=\\\"https://www.ks.uiuc.edu/Research/vmd/\\\">VMD</a> python module") );
+     135           1 :   mapkeys.insert( std::pair<std::string,std::string>("@nucleic","all atoms that are part of a DNA or RNA molecule") );
+     136           1 :   mapkeys.insert( std::pair<std::string,std::string>("@protein","all atoms that are part of a protein") );
+     137           1 :   mapkeys.insert( std::pair<std::string,std::string>("@water","all water molecules") );
+     138           1 :   mapkeys.insert( std::pair<std::string,std::string>("@ions","all the ions") );
+     139           1 :   mapkeys.insert( std::pair<std::string,std::string>("@hydrogens","all hydrogen atoms") );
+     140           1 :   mapkeys.insert( std::pair<std::string,std::string>("@nonhydrogens","all non hydrogen atoms") );
+     141           1 :   mapkeys.insert( std::pair<std::string,std::string>("@phi-","the four atoms that are required to calculate the phi dihedral for") );
+     142           1 :   mapkeys.insert( std::pair<std::string,std::string>("@psi-","the four atoms that are required to calculate the psi dihedral for") );
+     143           1 :   mapkeys.insert( std::pair<std::string,std::string>("@omega-","the four atoms that are required to calculate the omega dihedral for") );
+     144           1 :   mapkeys.insert( std::pair<std::string,std::string>("@chi1-","the four atoms that are required to calculate the chi1 dihedral for") );
+     145           1 :   mapkeys.insert( std::pair<std::string,std::string>("@chi2-","the four atoms that are required to calculate the chi2 dihedral for") );
+     146           1 :   mapkeys.insert( std::pair<std::string,std::string>("@chi3-","the four atoms that are required to calculate the chi3 dihedral for") );
+     147           1 :   mapkeys.insert( std::pair<std::string,std::string>("@chi4-","the four atoms that are required to calculate the chi4 dihedral for") );
+     148           1 :   mapkeys.insert( std::pair<std::string,std::string>("@chi5-","the four atoms that are required to calculate the chi5 dihedral for") );
+     149           1 :   mapkeys.insert( std::pair<std::string,std::string>("@sidechain-","the protein sidechain atoms in") );
+     150           1 :   mapkeys.insert( std::pair<std::string,std::string>("@back-","the protein/dna/rna backbone atoms in") );
+     151           1 :   mapkeys.insert( std::pair<std::string,std::string>("@alpha-","the four atoms that are required to calculate the alpha backbone dihedral for") );
+     152           1 :   mapkeys.insert( std::pair<std::string,std::string>("@beta-","the four atoms that are required to calculate the beta backbone dihedral for") );
+     153           1 :   mapkeys.insert( std::pair<std::string,std::string>("@gamma-","the four atoms that are required to calculate the gamma backbone dihedral for") );
+     154           1 :   mapkeys.insert( std::pair<std::string,std::string>("@delta-","the four atoms that are required to calculate the delta backbone dihedral for") );
+     155           1 :   mapkeys.insert( std::pair<std::string,std::string>("@epsilon-","the four atoms that are required to calculate the backbone epsilon dihedral for") );
+     156           1 :   mapkeys.insert( std::pair<std::string,std::string>("@zeta-","the four atoms that are required to calculate the zeta backbone dihedral for") );
+     157           1 :   mapkeys.insert( std::pair<std::string,std::string>("@v0-","the four atoms that are required to calculate the v0 sugar dihedral for") );
+     158           1 :   mapkeys.insert( std::pair<std::string,std::string>("@v1-","the four atoms that are required to calculate the v1 sugar dihedral for") );
+     159           1 :   mapkeys.insert( std::pair<std::string,std::string>("@v2-","the four atoms that are required to calculate the v2 sugar dihedral for") );
+     160           1 :   mapkeys.insert( std::pair<std::string,std::string>("@v3-","the four atoms that are required to calculate the v3 sugar dihedral for") );
+     161           1 :   mapkeys.insert( std::pair<std::string,std::string>("@v4-","the four atoms that are required to calculate the v4 sugar dihedral for") );
+     162           1 :   mapkeys.insert( std::pair<std::string,std::string>("@chi-","the four atoms that are required to alcullate the chi dihedral for") );
+     163           1 :   mapkeys.insert( std::pair<std::string,std::string>("@sugar-","the heavy atoms of the sugar in") );
+     164           1 :   mapkeys.insert( std::pair<std::string,std::string>("@base-","the heavy atoms of the base in") );
+     165           1 :   mapkeys.insert( std::pair<std::string,std::string>("@lcs-","an ordered triplet of atoms on the 6-membered ring of the nucleobase in") );
+     166           1 :   return mapkeys;
+     167             : }
+     168             : 
+     169          25 : void GenericMolInfo::getBackbone( std::vector<std::string>& restrings, const std::string& fortype, std::vector< std::vector<AtomNumber> >& backbone ) {
+     170          25 :   if( fortype!=mytype ) error("cannot calculate a variable designed for " + fortype + " molecules for molecule type " + mytype );
+     171          25 :   if( MolDataClass::numberOfAtomsPerResidueInBackbone( mytype )==0 ) error("backbone is not defined for molecule type " + mytype );
+     172             : 
+     173          25 :   if( read_backbone.size()!=0 ) {
+     174           0 :     if( restrings.size()!=1 ) error("cannot interpret anything other than all for residues when using CHAIN keywords");
+     175           0 :     if( restrings[0]!="all" ) error("cannot interpret anything other than all for residues when using CHAIN keywords");
+     176           0 :     backbone.resize( read_backbone.size() );
+     177           0 :     for(unsigned i=0; i<read_backbone.size(); ++i) {
+     178           0 :       backbone[i].resize( read_backbone[i].size() );
+     179           0 :       for(unsigned j=0; j<read_backbone[i].size(); ++j) backbone[i][j]=read_backbone[i][j];
+     180             :     }
+     181             :   } else {
+     182             :     bool useter=false; // This is used to deal with terminal groups in WHOLEMOLECULES
+     183          25 :     if( restrings.size()==1 ) {
+     184          23 :       useter=( restrings[0].find("ter")!=std::string::npos );
+     185          23 :       if( restrings[0].find("all")!=std::string::npos ) {
+     186          21 :         std::vector<std::string> chains; pdb.getChainNames( chains );
+     187         348 :         for(unsigned i=0; i<chains.size(); ++i) {
+     188             :           unsigned r_start, r_end; std::string errmsg, mm, nn;
+     189         327 :           pdb.getResidueRange( chains[i], r_start, r_end, errmsg );
+     190         327 :           if( !useter ) {
+     191         327 :             std::string resname = pdb.getResidueName( r_start );
+     192         327 :             if( MolDataClass::isTerminalGroup( mytype, resname ) ) r_start++;
+     193         327 :             resname = pdb.getResidueName( r_end );
+     194         327 :             if( MolDataClass::isTerminalGroup( mytype, resname ) ) r_end--;
+     195             :           }
+     196         327 :           Tools::convert(r_start,mm); Tools::convert(r_end,nn);
+     197         348 :           if(i==0) restrings[0] = mm + "-" + nn;
+     198         612 :           else restrings.push_back(  mm + "-" + nn );
+     199             :         }
+     200          21 :       }
+     201             :     }
+     202          25 :     Tools::interpretRanges(restrings);
+     203             : 
+     204             :     // Convert the list of involved residues into a list of segments of chains
+     205             :     int nk, nj; std::vector< std::vector<unsigned> > segments;
+     206             :     std::vector<unsigned> thissegment;
+     207          25 :     Tools::convert(restrings[0],nk); thissegment.push_back(nk);
+     208        2652 :     for(unsigned i=1; i<restrings.size(); ++i) {
+     209        2627 :       Tools::convert(restrings[i-1],nk);
+     210        2627 :       Tools::convert(restrings[i],nj);
+     211        7265 :       if( (nk+1)!=nj || pdb.getChainID(nk)!=pdb.getChainID(nj) ) {
+     212         308 :         segments.push_back(thissegment);
+     213         308 :         thissegment.resize(0);
+     214             :       }
+     215        2627 :       thissegment.push_back(nj);
+     216             :     }
+     217          25 :     segments.push_back( thissegment );
+     218             : 
+     219             :     // And now get the backbone atoms from each segment
+     220          25 :     backbone.resize( segments.size() );
+     221             :     std::vector<AtomNumber> atomnumbers;
+     222         358 :     for(unsigned i=0; i<segments.size(); ++i) {
+     223        2985 :       for(unsigned j=0; j<segments[i].size(); ++j) {
+     224        2652 :         std::string resname=pdb.getResidueName( segments[i][j] );
+     225        2652 :         if( !MolDataClass::allowedResidue(mytype, resname) ) {
+     226           0 :           std::string num; Tools::convert( segments[i][j], num );
+     227           0 :           error("residue " + num + " is not recognized for moltype " + mytype );
+     228             :         }
+     229        2652 :         if( !useter && MolDataClass::isTerminalGroup( mytype, resname ) ) {
+     230           0 :           std::string num; Tools::convert( segments[i][j], num );
+     231           0 :           error("residue " + num + " appears to be a terminal group");
+     232             :         }
+     233        2652 :         if( resname=="GLY" ) warning("GLY residues are achiral - assuming HA1 atom is in CB position");
+     234        2652 :         MolDataClass::getBackboneForResidue( mytype, segments[i][j], pdb, atomnumbers );
+     235        2652 :         if( atomnumbers.size()==0 ) {
+     236           0 :           std::string num; Tools::convert( segments[i][j], num );
+     237           0 :           error("Could not find required backbone atom in residue number " + num );
+     238             :         } else {
+     239       15912 :           for(unsigned k=0; k<atomnumbers.size(); ++k) backbone[i].push_back( atomnumbers[k] );
+     240             :         }
+     241        2652 :         atomnumbers.resize(0);
+     242             :       }
+     243             :     }
+     244          25 :   }
+     245          25 : }
+     246             : 
+     247         597 : void GenericMolInfo::interpretSymbol( const std::string& symbol, std::vector<AtomNumber>& atoms ) {
+     248        2370 :   if(Tools::startWith(symbol,"mdt:") || Tools::startWith(symbol,"mda:") || Tools::startWith(symbol,"vmd:") || Tools::startWith(symbol,"vmdexec:")) {
+     249             : 
+     250           8 :     plumed_assert(enablePythonInterpreter);
+     251             : 
+     252          16 :     log<<"  symbol " + symbol + " will be sent to python interpreter\n";
+     253           8 :     if(!selector) {
+     254           1 :       log<<"  MOLINFO "<<getLabel()<<": starting python interpreter\n";
+     255           1 :       if(comm.Get_rank()==0) {
+     256           2 :         selector=Tools::make_unique<Subprocess>(pythonCmd+" \""+config::getPlumedRoot()+"\"/scripts/selector.sh --pdb " + reference);
+     257           1 :         selector->stop();
+     258             :       }
+     259             :     }
+     260             : 
+     261           8 :     if(comm.Get_rank()==0) {
+     262           8 :       int ok=0;
+     263             :       std::string error_msg;
+     264             :       // this is a complicated way to have the exception propagated with MPI.
+     265             :       // It is necessary since only one process calls the selector.
+     266             :       // Probably I should recycle the exception propagation at library boundaries
+     267             :       // to allow transferring the exception to other processes.
+     268             :       try {
+     269           8 :         plumed_assert(selector) << "Python interpreter is disabled, selection " + symbol + " cannot be interpreted";
+     270             :         auto h=selector->contStop(); // stops again when it goes out of scope
+     271           8 :         (*selector) << symbol << "\n";
+     272           8 :         selector->flush();
+     273             :         std::string res;
+     274             :         std::vector<std::string> words;
+     275             :         while(true) {
+     276           8 :           selector->getline(res);
+     277          16 :           words=Tools::getWords(res);
+     278          16 :           if(!words.empty() && words[0]=="Error") plumed_error()<<res;
+     279          16 :           if(!words.empty() && words[0]=="Selection:") break;
+     280             :         }
+     281             :         words.erase(words.begin());
+     282           8 :         atoms.resize(0);
+     283         356 :         for(const auto & w : words) {
+     284             :           int n;
+     285         348 :           if(w.empty()) continue;
+     286         348 :           Tools::convert(w,n);
+     287         696 :           atoms.push_back(AtomNumber::serial(n));
+     288             :         }
+     289           8 :         ok=1;
+     290          16 :       } catch (const Exception & e) {
+     291           0 :         error_msg=e.what();
+     292           0 :       }
+     293           8 :       comm.Bcast(ok,0);
+     294           8 :       if(!ok) {
+     295           0 :         size_t s=error_msg.length();
+     296           0 :         comm.Bcast(s,0);
+     297           0 :         comm.Bcast(error_msg,0);
+     298           0 :         throw Exception()<<error_msg;
+     299             :       }
+     300           8 :       size_t nat=atoms.size();
+     301           8 :       comm.Bcast(nat,0);
+     302           8 :       comm.Bcast(atoms,0);
+     303             :     } else {
+     304           0 :       int ok=0;
+     305             :       std::string error_msg;
+     306           0 :       comm.Bcast(ok,0);
+     307           0 :       if(!ok) {
+     308             :         size_t s;
+     309           0 :         comm.Bcast(s,0);
+     310           0 :         error_msg.resize(s);
+     311           0 :         comm.Bcast(error_msg,0);
+     312           0 :         throw Exception()<<error_msg;
+     313             :       }
+     314           0 :       size_t nat=0;
+     315           0 :       comm.Bcast(nat,0);
+     316           0 :       comm.Bcast(atoms,0);
+     317             :     }
+     318           8 :     log<<"  selection interpreted using ";
+     319          18 :     if(Tools::startWith(symbol,"mdt:")) log<<"mdtraj "<<cite("McGibbon et al, Biophys. J., 109, 1528 (2015)")<<"\n";
+     320          22 :     if(Tools::startWith(symbol,"mda:")) log<<"MDAnalysis "<<cite("Gowers et al, Proceedings of the 15th Python in Science Conference, doi:10.25080/majora-629e541a-00e (2016)")<<"\n";
+     321          16 :     if(Tools::startWith(symbol,"vmdexec:")) log<<"VMD "<<cite("Humphrey, Dalke, and Schulten, K., J. Molec. Graphics, 14, 33 (1996)")<<"\n";
+     322          16 :     if(Tools::startWith(symbol,"vmd:")) log<<"VMD (github.com/Eigenstate/vmd-python) "<<cite("Humphrey, Dalke, and Schulten, K., J. Molec. Graphics, 14, 33 (1996)")<<"\n";
+     323           8 :     return;
+     324             :   }
+     325         589 :   MolDataClass::specialSymbol( mytype, symbol, pdb, atoms );
+     326         589 :   if(atoms.empty()) error(symbol + " not found in your MOLINFO structure");
+     327             : }
+     328             : 
+     329       46204 : std::string GenericMolInfo::getAtomName(AtomNumber a)const {
+     330       46204 :   return pdb.getAtomName(a);
+     331             : }
+     332             : 
+     333         127 : bool GenericMolInfo::checkForAtom(AtomNumber a)const {
+     334         127 :   return pdb.checkForAtom(a);
+     335             : }
+     336             : 
+     337       60228 : unsigned GenericMolInfo::getResidueNumber(AtomNumber a)const {
+     338       60228 :   return pdb.getResidueNumber(a);
+     339             : }
+     340             : 
+     341       14820 : unsigned GenericMolInfo::getPDBsize()const {
+     342       14820 :   return pdb.size();
+     343             : }
+     344             : 
+     345       14176 : std::string GenericMolInfo::getResidueName(AtomNumber a)const {
+     346       14176 :   return pdb.getResidueName(a);
+     347             : }
+     348             : 
+     349           0 : std::string GenericMolInfo::getChainID(AtomNumber a)const {
+     350           0 :   return pdb.getChainID(a);
+     351             : }
+     352             : 
+     353       30260 : Vector GenericMolInfo::getPosition(AtomNumber a)const {
+     354       30260 :   return pdb.getPosition(a);
+     355             : }
+     356             : 
+     357           1 : bool GenericMolInfo::isWhole() const {
+     358           1 :   return iswhole_;
+     359             : }
+     360             : 
+     361        5103 : void GenericMolInfo::prepare() {
+     362        5103 :   if(selector) {
+     363           1 :     log<<"  MOLINFO "<<getLabel()<<": killing python interpreter\n";
+     364             :     selector.reset();
+     365             :   }
+     366        5103 : }
+     367             : 
+     368             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.h.func-sort-c.html b/coverage/core/GenericMolInfo.h.func-sort-c.html new file mode 100644 index 000000000000..9769928ec98c --- /dev/null +++ b/coverage/core/GenericMolInfo.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo5applyEv5103
_ZN4PLMD14GenericMolInfo9calculateEv5103
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.h.func.html b/coverage/core/GenericMolInfo.h.func.html new file mode 100644 index 000000000000..2ae28c78227e --- /dev/null +++ b/coverage/core/GenericMolInfo.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14GenericMolInfo5applyEv5103
_ZN4PLMD14GenericMolInfo9calculateEv5103
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/GenericMolInfo.h.gcov.html b/coverage/core/GenericMolInfo.h.gcov.html new file mode 100644 index 000000000000..635a5ce0d413 --- /dev/null +++ b/coverage/core/GenericMolInfo.h.gcov.html @@ -0,0 +1,163 @@ + + + + + + + + LCOV - plumed test coverage - core/GenericMolInfo.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - GenericMolInfo.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_GenericMolInfo_h
+      23             : #define __PLUMED_core_GenericMolInfo_h
+      24             : 
+      25             : #include "ActionSetup.h"
+      26             : #include "ActionPilot.h"
+      27             : #include "ActionAtomistic.h"
+      28             : #include "ActionAnyorder.h"
+      29             : #include "tools/Exception.h"
+      30             : #include "tools/ForwardDecl.h"
+      31             : #include "tools/Subprocess.h"
+      32             : #include <memory>
+      33             : #include <map>
+      34             : 
+      35             : namespace PLMD {
+      36             : 
+      37             : class PDB;
+      38             : 
+      39             : class GenericMolInfo :
+      40             :   public ActionAnyorder,
+      41             :   public ActionPilot,
+      42             :   public ActionAtomistic {
+      43             : private:
+      44             :   ForwardDecl<PDB> pdb_fwd;
+      45             : /// A pdb file containing the topology
+      46             :   PDB& pdb=*pdb_fwd;
+      47             : /// The type of molecule in the pdb
+      48             :   std::string mytype;
+      49             : /// The name of the reference pdb file
+      50             :   std::string reference;
+      51             : /// The backbone that was read in from the pdb file
+      52             :   std::vector< std::vector<AtomNumber> > read_backbone;
+      53             : /// Python interpreter is enabled
+      54             :   bool enablePythonInterpreter=false;
+      55             : /// Python command
+      56             :   std::string pythonCmd;
+      57             : /// Selector subprocess
+      58             :   std::unique_ptr<Subprocess> selector;
+      59             : /// Structure in pdb file is whole
+      60             :   bool iswhole_;
+      61             : public:
+      62             :   ~GenericMolInfo();
+      63        5103 :   void calculate() override {}
+      64        5103 :   void apply() override {}
+      65             :   static void registerKeywords( Keywords& keys );
+      66             :   static std::map<std::string,std::string> getSpecialKeywords();
+      67             :   explicit GenericMolInfo(const ActionOptions&ao);
+      68             :   void getBackbone( std::vector<std::string>& resstrings, const std::string& fortype, std::vector< std::vector<AtomNumber> >& backbone );
+      69             :   std::string getAtomName(AtomNumber a)const;
+      70             :   bool checkForAtom(AtomNumber a)const;
+      71             :   unsigned getResidueNumber(AtomNumber a)const;
+      72             :   std::string getChainID(AtomNumber a)const;
+      73             :   Vector getPosition(AtomNumber a)const;
+      74             :   bool isWhole() const;
+      75             :   unsigned getPDBsize()const ;
+      76             :   std::string getResidueName(AtomNumber a)const;
+      77             :   void interpretSymbol( const std::string& symbol, std::vector<AtomNumber>& atoms );
+      78             : /// Calculate is used to kill the python interpreter.
+      79             : /// We do this in order to avoid possible interference or slowing down of the simulation
+      80             : /// due to the extra subprocess.
+      81             :   void prepare() override;
+      82             : };
+      83             : 
+      84             : }
+      85             : 
+      86             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Group.cpp.func-sort-c.html b/coverage/core/Group.cpp.func-sort-c.html new file mode 100644 index 000000000000..86076f73a7db --- /dev/null +++ b/coverage/core/Group.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - core/Group.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Group.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:737498.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5GroupC2ERKNS_13ActionOptionsE0
_ZN4PLMD5GroupC1ERKNS_13ActionOptionsE132
_ZN4PLMD5Group16registerKeywordsERNS_8KeywordsE134
_ZNK4PLMD5Group13getGroupAtomsB5cxx11Ev394
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Group.cpp.func.html b/coverage/core/Group.cpp.func.html new file mode 100644 index 000000000000..b5ccf26ef231 --- /dev/null +++ b/coverage/core/Group.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - core/Group.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Group.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:737498.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Group16registerKeywordsERNS_8KeywordsE134
_ZN4PLMD5GroupC1ERKNS_13ActionOptionsE132
_ZN4PLMD5GroupC2ERKNS_13ActionOptionsE0
_ZNK4PLMD5Group13getGroupAtomsB5cxx11Ev394
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Group.cpp.gcov.html b/coverage/core/Group.cpp.gcov.html new file mode 100644 index 000000000000..a900ac1f7db5 --- /dev/null +++ b/coverage/core/Group.cpp.gcov.html @@ -0,0 +1,315 @@ + + + + + + + + LCOV - plumed test coverage - core/Group.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Group.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:737498.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Group.h"
+      23             : #include "ActionRegister.h"
+      24             : #include "PlumedMain.h"
+      25             : #include "Value.h"
+      26             : #include "ActionWithValue.h"
+      27             : #include "ActionWithVirtualAtom.h"
+      28             : #include "tools/IFile.h"
+      29             : #include "tools/Tools.h"
+      30             : #include <string>
+      31             : #include <vector>
+      32             : #include <algorithm>
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : //+PLUMEDOC GENERIC GROUP
+      37             : /*
+      38             : Define a group of atoms so that a particular list of atoms can be referenced with a single label in definitions of CVs or virtual atoms.
+      39             : 
+      40             : Atoms can be listed as comma separated numbers (i.e. `1,2,3,10,45,7,9`) , simple positive ranges
+      41             : (i.e. `20-40`), ranges with a stride either positive or negative (i.e. `20-40:2` or `80-50:-2`) or as
+      42             : comma separated combinations of all the former methods (`1,2,4,5,10-20,21-40:2,80-50:-2`).
+      43             : 
+      44             : Moreover, lists can be imported from ndx files (GROMACS format). Use `NDX_FILE` to set the name of
+      45             : the index file and `NDX_GROUP` to set the name of the group to be imported (default is first one).
+      46             : 
+      47             : It is also possible to remove atoms from a list and or sort them using keywords `REMOVE`, `SORT`, and `UNIQUE`.
+      48             : The flow is the following:
+      49             : - If `ATOMS` is present, then take the ordered list of atoms from the `ATOMS` keyword as a starting list.
+      50             : - If `NDX_FILE` is present, then append to it the list obtained from the gromacs group.
+      51             : - If `REMOVE` is present, then remove the first occurrence of each of these atoms from the list.
+      52             :   If one tries to remove an atom that was not listed plumed adds a notice in the output.
+      53             :   An atom that is present twice in the original list might be removed twice.
+      54             : - If `SORT` is present, then the resulting list is sorted by increasing serial number.
+      55             : - If `UNIQUE` is present, then the resulting list is sorted by increasing serial number _and_ duplicate elements are removed.
+      56             : 
+      57             : Notice that this command just creates a shortcut, and does not imply any real calculation.
+      58             : So, having a huge group defined does not slow down your calculation in any way.
+      59             : It is just convenient to better organize input files. Might be used in combination with
+      60             : the \ref INCLUDE command so as to store long group definitions in a separate file.
+      61             : 
+      62             : 
+      63             : \par Examples
+      64             : 
+      65             : This command create a group of atoms containing atoms 1, 4, 7, 11 and 14 (labeled 'o'), and another containing
+      66             : atoms 2, 3, 5, 6, 8, 9, 12, and 13 (labeled 'h'):
+      67             : \plumedfile
+      68             : o: GROUP ATOMS=1,4,7,11,14
+      69             : h: GROUP ATOMS=2,3,5,6,8,9,12,13
+      70             : # compute the coordination among the two groups
+      71             : c: COORDINATION GROUPA=o GROUPB=h R_0=0.3
+      72             : # same could have been obtained without GROUP, just writing:
+      73             : # c: COORDINATION GROUPA=1,4,7,11,14 GROUPB=2,3,5,6,8,9,12,13
+      74             : 
+      75             : # print the coordination on file 'colvar'
+      76             : PRINT ARG=c FILE=colvar
+      77             : \endplumedfile
+      78             : 
+      79             : Groups can be conveniently stored in a separate file.
+      80             : E.g. one could create a file named `groups.dat` which reads
+      81             : \plumedfile
+      82             : #SETTINGS FILENAME=groups.dat
+      83             : # this is groups.dat
+      84             : o: GROUP ATOMS=1,4,7,11,14
+      85             : h: GROUP ATOMS=2,3,5,6,8,9,12,13
+      86             : \endplumedfile
+      87             : and then include it in the main 'plumed.dat' file
+      88             : \plumedfile
+      89             : INCLUDE FILE=groups.dat
+      90             : # compute the coordination among the two groups
+      91             : c: COORDINATION GROUPA=o GROUPB=h R_0=0.3
+      92             : # print the coordination on file 'colvar'
+      93             : PRINT ARG=c FILE=colvar
+      94             : \endplumedfile
+      95             : The `groups.dat` file could be very long and include lists of thousand atoms without cluttering the main plumed.dat file.
+      96             : 
+      97             : A GROMACS index file such as the one shown below:
+      98             : 
+      99             : \auxfile{index.ndx}
+     100             : [ Protein ]
+     101             : 1 3 5 7 9
+     102             : 2 4 6 8 10
+     103             : [ Group2 ]
+     104             : 30 31 32 33 34 35 36 37 38 39 40
+     105             : 5
+     106             : \endauxfile
+     107             : 
+     108             : can also be imported by using the GROUP keyword as shown below
+     109             : \plumedfile
+     110             : # import group named 'Protein' from file index.ndx
+     111             : pro: GROUP NDX_FILE=index.ndx NDX_GROUP=Protein
+     112             : # dump all the atoms of the protein on a trajectory file
+     113             : DUMPATOMS ATOMS=pro FILE=traj.gro
+     114             : \endplumedfile
+     115             : 
+     116             : A list can be edited with `REMOVE`. For instance, if you
+     117             : are using a water model with three atoms per molecule, you can
+     118             : easily construct the list of hydrogen atoms in this manner
+     119             : \plumedfile
+     120             : # take one atom every three, that is oxygens
+     121             : ox: GROUP ATOMS=1-90:3
+     122             : # take the remaining atoms, that is hydrogens
+     123             : hy: GROUP ATOMS=1-90 REMOVE=ox
+     124             : DUMPATOMS ATOMS=ox FILE=ox.gro
+     125             : DUMPATOMS ATOMS=hy FILE=hy.gro
+     126             : \endplumedfile
+     127             : 
+     128             : 
+     129             : */
+     130             : //+ENDPLUMEDOC
+     131             : 
+     132             : PLUMED_REGISTER_ACTION(Group,"GROUP")
+     133             : 
+     134         132 : Group::Group(const ActionOptions&ao):
+     135             :   Action(ao),
+     136         132 :   ActionAtomistic(ao)
+     137             : {
+     138         264 :   parseAtomList("ATOMS",atoms);
+     139             :   std::string ndxfile,ndxgroup;
+     140         132 :   parse("NDX_FILE",ndxfile);
+     141         264 :   parse("NDX_GROUP",ndxgroup);
+     142         132 :   if(ndxfile.length()>0 && atoms.size()>0) error("either use explicit atom list or import from index file");
+     143         132 :   if(ndxfile.length()==0 && ndxgroup.size()>0) error("NDX_GROUP can be only used is NDX_FILE is also used");
+     144             : 
+     145         132 :   if(ndxfile.length()>0) {
+     146          35 :     if(ndxgroup.size()>0) log<<"  importing group '"+ndxgroup+"'";
+     147           1 :     else                  log<<"  importing first group";
+     148          18 :     log<<" from index file "<<ndxfile<<"\n";
+     149             : 
+     150          18 :     IFile ifile;
+     151          18 :     ifile.open(ndxfile);
+     152             :     std::string line;
+     153             :     std::string groupname;
+     154             :     bool firstgroup=true;
+     155             :     bool groupfound=false;
+     156        3835 :     while(ifile.getline(line)) {
+     157        3817 :       std::vector<std::string> words=Tools::getWords(line);
+     158        7739 :       if(words.size()>=3 && words[0]=="[" && words[2]=="]") {
+     159         164 :         if(groupname.length()>0) firstgroup=false;
+     160             :         groupname=words[1];
+     161         164 :         if(groupname==ndxgroup || ndxgroup.length()==0) groupfound=true;
+     162        3653 :       } else if(groupname==ndxgroup || (firstgroup && ndxgroup.length()==0)) {
+     163        6160 :         for(unsigned i=0; i<words.size(); i++) {
+     164        5760 :           AtomNumber at; Tools::convert(words[i],at);
+     165        5760 :           atoms.push_back(at);
+     166             :         }
+     167             :       }
+     168        3817 :     }
+     169          18 :     if(!groupfound) error("group has not been found in index file");
+     170          18 :   }
+     171             : 
+     172             :   std::vector<AtomNumber> remove;
+     173         264 :   parseAtomList("REMOVE",remove);
+     174         132 :   if(remove.size()>0) {
+     175             :     std::vector<AtomNumber> notfound;
+     176             :     unsigned k=0;
+     177           2 :     log<<"  removing these atoms from the list:";
+     178         114 :     for(unsigned i=0; i<remove.size(); i++) {
+     179         112 :       const auto it = find(atoms.begin(),atoms.end(),remove[i]);
+     180         112 :       if(it!=atoms.end()) {
+     181         111 :         if(k%25==0) log<<"\n";
+     182         111 :         log<<" "<<(*it).serial();
+     183         111 :         k++;
+     184             :         atoms.erase(it);
+     185           1 :       } else notfound.push_back(remove[i]);
+     186             :     }
+     187           2 :     log<<"\n";
+     188           2 :     if(notfound.size()>0) {
+     189           1 :       log<<"  the following atoms were not found:";
+     190           2 :       for(unsigned i=0; i<notfound.size(); i++) log<<" "<<notfound[i].serial();
+     191           1 :       log<<"\n";
+     192             :     }
+     193             :   }
+     194             : 
+     195         132 :   bool sortme=false;
+     196         132 :   parseFlag("SORT",sortme);
+     197         132 :   if(sortme) {
+     198           1 :     log<<"  atoms are sorted\n";
+     199           1 :     sort(atoms.begin(),atoms.end());
+     200             :   }
+     201         132 :   bool unique=false;
+     202         132 :   parseFlag("UNIQUE",unique);
+     203         132 :   if(unique) {
+     204           1 :     log<<"  sorting atoms and removing duplicates\n";
+     205           1 :     Tools::removeDuplicates(atoms);
+     206             :   }
+     207             : 
+     208         132 :   log.printf("  list of atoms:");
+     209      183007 :   for(unsigned i=0; i<atoms.size(); i++) {
+     210      182875 :     if(i%25==0) log<<"\n";
+     211      182875 :     log<<" "<<atoms[i].serial();
+     212             :   }
+     213         132 :   log.printf("\n");
+     214         132 : }
+     215             : 
+     216         134 : void Group::registerKeywords( Keywords& keys ) {
+     217         134 :   Action::registerKeywords( keys );
+     218         134 :   ActionAtomistic::registerKeywords( keys );
+     219         268 :   keys.add("atoms", "ATOMS", "the numerical indexes for the set of atoms in the group");
+     220         268 :   keys.add("atoms", "REMOVE","remove these atoms from the list");
+     221         268 :   keys.addFlag("SORT",false,"sort the resulting list");
+     222         268 :   keys.addFlag("UNIQUE",false,"sort atoms and remove duplicated ones");
+     223         268 :   keys.add("optional", "NDX_FILE", "the name of index file (gromacs syntax)");
+     224         268 :   keys.add("optional", "NDX_GROUP", "the name of the group to be imported (gromacs syntax) - first group found is used by default");
+     225         134 : }
+     226             : 
+     227         394 : std::vector<std::string> Group::getGroupAtoms() const {
+     228         394 :   std::vector<std::string> atoms_str(atoms.size());
+     229      195289 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     230      194895 :     std::pair<std::size_t,std::size_t> a = getValueIndices( atoms[i] );
+     231      194895 :     if( xpos[a.first]->getNumberOfValues()==1 ) atoms_str[i] = (xpos[a.first]->getPntrToAction())->getLabel();
+     232      187921 :     else { Tools::convert( atoms[i].serial(), atoms_str[i] ); }
+     233             :   }
+     234         394 :   return atoms_str;
+     235           0 : }
+     236             : 
+     237             : }
+     238             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Group.h.func-sort-c.html b/coverage/core/Group.h.func-sort-c.html new file mode 100644 index 000000000000..12731cb6f074 --- /dev/null +++ b/coverage/core/Group.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/Group.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Group.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:020.0 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Group5applyEv0
_ZN4PLMD5Group9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Group.h.func.html b/coverage/core/Group.h.func.html new file mode 100644 index 000000000000..7e57974fe817 --- /dev/null +++ b/coverage/core/Group.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - core/Group.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Group.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:020.0 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Group5applyEv0
_ZN4PLMD5Group9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Group.h.gcov.html b/coverage/core/Group.h.gcov.html new file mode 100644 index 000000000000..b73865233a11 --- /dev/null +++ b/coverage/core/Group.h.gcov.html @@ -0,0 +1,118 @@ + + + + + + + + LCOV - plumed test coverage - core/Group.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Group.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:020.0 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_Group_h
+      23             : #define __PLUMED_core_Group_h
+      24             : #include "ActionAtomistic.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28             : class Group : public ActionAtomistic {
+      29             : private:
+      30             :   std::vector<AtomNumber> atoms;
+      31             : public:
+      32             :   explicit Group(const ActionOptions&ao);
+      33             :   static void registerKeywords( Keywords& keys );
+      34             :   std::vector<std::string> getGroupAtoms() const ;
+      35           0 :   void calculate() override {}
+      36           0 :   void apply() override {}
+      37             : };
+      38             : 
+      39             : }
+      40             : 
+      41             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PbcAction.cpp.func-sort-c.html b/coverage/core/PbcAction.cpp.func-sort-c.html new file mode 100644 index 000000000000..4329b0f75c92 --- /dev/null +++ b/coverage/core/PbcAction.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/PbcAction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PbcAction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9PbcActionC2ERKNS_13ActionOptionsE0
_ZN4PLMD9PbcAction10readBinaryERSi114
_ZN4PLMD9PbcActionC1ERKNS_13ActionOptionsE936
_ZN4PLMD9PbcAction16registerKeywordsERNS_8KeywordsE938
_ZN4PLMD9PbcAction4waitEv48522
_ZN4PLMD9PbcAction6setPbcEv48636
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PbcAction.cpp.func.html b/coverage/core/PbcAction.cpp.func.html new file mode 100644 index 000000000000..77c3bc06d397 --- /dev/null +++ b/coverage/core/PbcAction.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/PbcAction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PbcAction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9PbcAction10readBinaryERSi114
_ZN4PLMD9PbcAction16registerKeywordsERNS_8KeywordsE938
_ZN4PLMD9PbcAction4waitEv48522
_ZN4PLMD9PbcAction6setPbcEv48636
_ZN4PLMD9PbcActionC1ERKNS_13ActionOptionsE936
_ZN4PLMD9PbcActionC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PbcAction.cpp.gcov.html b/coverage/core/PbcAction.cpp.gcov.html new file mode 100644 index 000000000000..ad1edfcd851a --- /dev/null +++ b/coverage/core/PbcAction.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - core/PbcAction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PbcAction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PbcAction.h"
+      23             : #include "DomainDecomposition.h"
+      24             : #include "tools/Pbc.h"
+      25             : #include "PlumedMain.h"
+      26             : #include "ActionSet.h"
+      27             : #include "ActionRegister.h"
+      28             : 
+      29             : //+PLUMEDOC ANALYSIS PBC
+      30             : /*
+      31             : Pass the cell vectors into PLUMED.
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : 
+      40             : PLUMED_REGISTER_ACTION(PbcAction,"PBC")
+      41             : 
+      42         938 : void PbcAction::registerKeywords( Keywords& keys ) {
+      43         938 :   Action::registerKeywords( keys );
+      44        1876 :   keys.add("hidden","NO_ACTION_LOG","suppresses printing from action on the log");
+      45         938 : }
+      46             : 
+      47         936 : PbcAction::PbcAction(const ActionOptions&ao):
+      48             :   Action(ao),
+      49             :   ActionToPutData(ao),
+      50         936 :   interface(NULL)
+      51             : {
+      52         936 :   std::vector<unsigned> shape(2); shape[0]=shape[1]=3;
+      53        1872 :   addValue( shape ); setNotPeriodic(); setUnit( "length", "energy" );
+      54         936 :   getPntrToValue()->buildDataStore();
+      55         936 : }
+      56             : 
+      57             : 
+      58       48636 : void PbcAction::setPbc() {
+      59       48636 :   if( !interface ) {
+      60         781 :     std::vector<DomainDecomposition*> allput=plumed.getActionSet().select<DomainDecomposition*>();
+      61         781 :     if( allput.size()>1 ) warning("found more than one interface so don't know how to broadcast cell");
+      62         781 :     interface = allput[0];
+      63             :   }
+      64       48636 :   Tensor box; if( interface ) interface->broadcastToDomains( getPntrToValue() );
+      65      632268 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) box(i,j) = getPntrToValue()->get(3*i+j);
+      66       48636 :   pbc.setBox(box);
+      67       48636 : }
+      68             : 
+      69       48522 : void PbcAction::wait() {
+      70       48522 :   ActionToPutData::wait(); setPbc();
+      71       48522 : }
+      72             : 
+      73         114 : void PbcAction::readBinary(std::istream&i) {
+      74         114 :   ActionToPutData::readBinary(i); setPbc();
+      75         114 : }
+      76             : 
+      77             : }
+      78             : 
+      79             : 
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PbcAction.h.func-sort-c.html b/coverage/core/PbcAction.h.func-sort-c.html new file mode 100644 index 000000000000..23d9a820bd79 --- /dev/null +++ b/coverage/core/PbcAction.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - core/PbcAction.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PbcAction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9PbcAction15castToPbcActionEv159914
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PbcAction.h.func.html b/coverage/core/PbcAction.h.func.html new file mode 100644 index 000000000000..e80473928e55 --- /dev/null +++ b/coverage/core/PbcAction.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - core/PbcAction.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PbcAction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9PbcAction15castToPbcActionEv159914
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PbcAction.h.gcov.html b/coverage/core/PbcAction.h.gcov.html new file mode 100644 index 000000000000..ca648584602b --- /dev/null +++ b/coverage/core/PbcAction.h.gcov.html @@ -0,0 +1,136 @@ + + + + + + + + LCOV - plumed test coverage - core/PbcAction.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PbcAction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_PbcAction_h
+      23             : #define __PLUMED_core_PbcAction_h
+      24             : 
+      25             : #include "ActionToPutData.h"
+      26             : #include "tools/ForwardDecl.h"
+      27             : 
+      28             : #include <vector>
+      29             : #include <string>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : class Pbc;
+      34             : class DomainDecomposition;
+      35             : 
+      36             : class PbcAction : public ActionToPutData {
+      37             :   friend class ActionAtomistic;
+      38             : private:
+      39             :   DomainDecomposition* interface;
+      40             :   ForwardDecl<Pbc> pbc_fwd;
+      41             :   Pbc&   pbc=*pbc_fwd;
+      42             :   void setPbc();
+      43             : public:
+      44             :   explicit PbcAction(const ActionOptions&);
+      45             : // active methods:
+      46             :   static void registerKeywords( Keywords& keys );
+      47             :   Pbc& getPbc();
+      48             :   void wait() override;
+      49             :   void readBinary(std::istream&i) override;
+      50      159914 :   PbcAction* castToPbcAction() noexcept final { return this; }
+      51             : };
+      52             : 
+      53             : inline
+      54             : Pbc& PbcAction::getPbc() {
+      55         527 :   return pbc;
+      56             : }
+      57             : 
+      58             : }
+      59             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.cpp.func-sort-c.html b/coverage/core/PlumedMain.cpp.func-sort-c.html new file mode 100644 index 000000000000..35e52cbac8f4 --- /dev/null +++ b/coverage/core/PlumedMain.cpp.func-sort-c.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage - core/PlumedMain.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMain.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:79888690.1 %
Date:2024-02-22 21:58:45Functions:545794.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10PlumedMain4exitEi0
_ZN4PLMD10PlumedMain9justApplyEv0
_ZNK4PLMD10PlumedMain18MDQuantityToPLUMEDERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZN4PLMD10PlumedMain14readInputLinesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD10PlumedMain4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZN4PLMD10PlumedMain19performCalcNoForcesEv10
_ZN4PLMD10PlumedMain14setEnergyValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE40
_ZNK4PLMD10PlumedMain24useCountReferenceCounterEv42
_ZNK4PLMD10PlumedMain11valueExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE60
_ZN4PLMDL9testThrowEPKc61
_ZN4PLMD10PlumedMain4stopEv65
_ZN4PLMD10PlumedMain5fopenEPKcS2_73
_ZN4PLMD10PlumedMain6fcloseEP8_IO_FILE91
_ZN4PLMD10PlumedMain10readBinaryERSi114
_ZN4PLMD10PlumedMain8shareAllEv114
_ZNK4PLMD10PlumedMain11writeBinaryERSo114
_ZNK4PLMD10PlumedMain7getWorkEv450
_ZN4PLMD10PlumedMain25runJobsAtEndOfCalculationEv817
_ZN4PLMD10PlumedMain13readInputFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE887
_ZN4PLMD10PlumedMain13readInputFileERNS_5IFileE888
_ZN4PLMD10PlumedMain4initEv1011
_ZN4PLMD10PlumedMain8setUnitsERKbRKNS_5UnitsE1032
_ZN4PLMD10PlumedMain6fflushEv1543
_ZNK4PLMD10PlumedMain15inputsAreActiveEv1707
_ZN4PLMD10PlumedMain19performCalcNoUpdateEv2134
_ZNK4PLMD10PlumedMain18plumedQuantityToMDERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKdRKNS_11TypesafePtrE2343
_ZNK4PLMD10PlumedMain7getBiasEv2805
_ZNK4PLMD10PlumedMain17usingNaturalUnitsEv3124
_ZN4PLMD10PlumedMain4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3802
_ZN4PLMD12_GLOBAL__N_114CountInstancesD2Ev4187
_ZN4PLMD10PlumedMain10insertFileERNS_8FileBaseE4534
_ZN4PLMD10PlumedMain9eraseFileERNS_8FileBaseE4831
_ZNK4PLMD10PlumedMain16getRealPrecisionEv6651
_ZN4PLMD10PlumedMain13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb7908
_ZN4PLMD10PlumedMain6getLogEv21853
_ZN4PLMD10PlumedMain14readInputWordsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKb22014
_ZN4PLMD10PlumedMain21setupInterfaceActionsEv22706
_ZN4PLMD10PlumedMain13setInputForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE213206
_ZN4PLMD10PlumedMain4calcEv253984
_ZN4PLMD10PlumedMain11performCalcEv253994
_ZN4PLMD10PlumedMain6updateEv254073
_ZN4PLMD10PlumedMain11prepareCalcEv256054
_ZN4PLMD10PlumedMain9startStepEv256099
_ZN4PLMD10PlumedMain11resetInputsEv256128
_ZN4PLMD10PlumedMain17backwardPropagateEv256128
_ZN4PLMD10PlumedMain9shareDataEv256138
_ZN4PLMD10PlumedMain13justCalculateEv256252
_ZN4PLMD10PlumedMain8waitDataEv256252
_ZN4PLMD10PlumedMain19prepareDependenciesEv256381
_ZN4PLMD10PlumedMain13setInputValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSA_RKNS_11TypesafePtrE324438
_ZN4PLMD10PlumedMainD0Ev804466
_ZN4PLMD10PlumedMainC2Ev805283
_ZN4PLMD10PlumedMainD2Ev805283
_ZN4PLMD10PlumedMain3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE1118633
_ZN4PLMD10PlumedMain24decreaseReferenceCounterEv8804439
_ZN4PLMD10PlumedMain24increaseReferenceCounterEv8805358
_ZN4PLMD10PlumedMain8getUnitsEv14346306
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.cpp.func.html b/coverage/core/PlumedMain.cpp.func.html new file mode 100644 index 000000000000..2909d315d639 --- /dev/null +++ b/coverage/core/PlumedMain.cpp.func.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage - core/PlumedMain.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMain.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:79888690.1 %
Date:2024-02-22 21:58:45Functions:545794.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10PlumedMain10insertFileERNS_8FileBaseE4534
_ZN4PLMD10PlumedMain10readBinaryERSi114
_ZN4PLMD10PlumedMain11performCalcEv253994
_ZN4PLMD10PlumedMain11prepareCalcEv256054
_ZN4PLMD10PlumedMain11resetInputsEv256128
_ZN4PLMD10PlumedMain13justCalculateEv256252
_ZN4PLMD10PlumedMain13readInputFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE887
_ZN4PLMD10PlumedMain13readInputFileERNS_5IFileE888
_ZN4PLMD10PlumedMain13readInputLineERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb7908
_ZN4PLMD10PlumedMain13setInputForceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE213206
_ZN4PLMD10PlumedMain13setInputValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjSA_RKNS_11TypesafePtrE324438
_ZN4PLMD10PlumedMain14readInputLinesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD10PlumedMain14readInputWordsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKb22014
_ZN4PLMD10PlumedMain14setEnergyValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE40
_ZN4PLMD10PlumedMain17backwardPropagateEv256128
_ZN4PLMD10PlumedMain19performCalcNoForcesEv10
_ZN4PLMD10PlumedMain19performCalcNoUpdateEv2134
_ZN4PLMD10PlumedMain19prepareDependenciesEv256381
_ZN4PLMD10PlumedMain21setupInterfaceActionsEv22706
_ZN4PLMD10PlumedMain24decreaseReferenceCounterEv8804439
_ZN4PLMD10PlumedMain24increaseReferenceCounterEv8805358
_ZN4PLMD10PlumedMain25runJobsAtEndOfCalculationEv817
_ZN4PLMD10PlumedMain3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE1118633
_ZN4PLMD10PlumedMain4calcEv253984
_ZN4PLMD10PlumedMain4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3802
_ZN4PLMD10PlumedMain4exitEi0
_ZN4PLMD10PlumedMain4initEv1011
_ZN4PLMD10PlumedMain4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZN4PLMD10PlumedMain4stopEv65
_ZN4PLMD10PlumedMain5fopenEPKcS2_73
_ZN4PLMD10PlumedMain6fcloseEP8_IO_FILE91
_ZN4PLMD10PlumedMain6fflushEv1543
_ZN4PLMD10PlumedMain6getLogEv21853
_ZN4PLMD10PlumedMain6updateEv254073
_ZN4PLMD10PlumedMain8getUnitsEv14346306
_ZN4PLMD10PlumedMain8setUnitsERKbRKNS_5UnitsE1032
_ZN4PLMD10PlumedMain8shareAllEv114
_ZN4PLMD10PlumedMain8waitDataEv256252
_ZN4PLMD10PlumedMain9eraseFileERNS_8FileBaseE4831
_ZN4PLMD10PlumedMain9justApplyEv0
_ZN4PLMD10PlumedMain9shareDataEv256138
_ZN4PLMD10PlumedMain9startStepEv256099
_ZN4PLMD10PlumedMainC2Ev805283
_ZN4PLMD10PlumedMainD0Ev804466
_ZN4PLMD10PlumedMainD2Ev805283
_ZN4PLMD12_GLOBAL__N_114CountInstancesD2Ev4187
_ZN4PLMDL9testThrowEPKc61
_ZNK4PLMD10PlumedMain11valueExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE60
_ZNK4PLMD10PlumedMain11writeBinaryERSo114
_ZNK4PLMD10PlumedMain15inputsAreActiveEv1707
_ZNK4PLMD10PlumedMain16getRealPrecisionEv6651
_ZNK4PLMD10PlumedMain17usingNaturalUnitsEv3124
_ZNK4PLMD10PlumedMain18MDQuantityToPLUMEDERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE0
_ZNK4PLMD10PlumedMain18plumedQuantityToMDERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKdRKNS_11TypesafePtrE2343
_ZNK4PLMD10PlumedMain24useCountReferenceCounterEv42
_ZNK4PLMD10PlumedMain7getBiasEv2805
_ZNK4PLMD10PlumedMain7getWorkEv450
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.cpp.gcov.html b/coverage/core/PlumedMain.cpp.gcov.html new file mode 100644 index 000000000000..cbdb0c5a6401 --- /dev/null +++ b/coverage/core/PlumedMain.cpp.gcov.html @@ -0,0 +1,1492 @@ + + + + + + + + LCOV - plumed test coverage - core/PlumedMain.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMain.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:79888690.1 %
Date:2024-02-22 21:58:45Functions:545794.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PlumedMain.h"
+      23             : #include "ActionAtomistic.h"
+      24             : #include "ActionPilot.h"
+      25             : #include "ActionForInterface.h"
+      26             : #include "ActionRegister.h"
+      27             : #include "ActionSet.h"
+      28             : #include "ActionWithValue.h"
+      29             : #include "ActionWithVirtualAtom.h"
+      30             : #include "ActionToGetData.h"
+      31             : #include "ActionToPutData.h"
+      32             : #include "CLToolMain.h"
+      33             : #include "ExchangePatterns.h"
+      34             : #include "GREX.h"
+      35             : #include "DomainDecomposition.h"
+      36             : #include "config/Config.h"
+      37             : #include "tools/Citations.h"
+      38             : #include "tools/Communicator.h"
+      39             : #include "tools/DLLoader.h"
+      40             : #include "tools/Exception.h"
+      41             : #include "tools/IFile.h"
+      42             : #include "tools/Log.h"
+      43             : #include "tools/OpenMP.h"
+      44             : #include "tools/Tools.h"
+      45             : #include "tools/Stopwatch.h"
+      46             : #include "tools/TypesafePtr.h"
+      47             : #include "lepton/Exception.h"
+      48             : #include "DataPassingTools.h"
+      49             : #include "small_vector/small_vector.h"
+      50             : #include <cstdlib>
+      51             : #include <cstdio>
+      52             : #include <cstring>
+      53             : #include <set>
+      54             : #include <exception>
+      55             : #include <stdexcept>
+      56             : #include <ios>
+      57             : #include <new>
+      58             : #include <typeinfo>
+      59             : #include <iostream>
+      60             : #include <algorithm>
+      61             : #include <system_error>
+      62             : #include <future>
+      63             : #include <memory>
+      64             : #include <functional>
+      65             : #include <regex>
+      66             : #include <any>
+      67             : #include <optional>
+      68             : #include <variant>
+      69             : #include <filesystem>
+      70             : 
+      71             : namespace PLMD {
+      72             : 
+      73             : /// Small utility just used in this file to throw arbitrary exceptions
+      74          61 : [[noreturn]] static void testThrow(const char* what) {
+      75          61 :   auto words=Tools::getWords(what);
+      76          61 :   plumed_assert(words.size()>0);
+      77             : #define __PLUMED_THROW_NOMSG(type) if(words[0]==#type) throw type()
+      78             : #define __PLUMED_THROW_MSG(type) if(words[0]==#type) throw type(what)
+      79          62 :   __PLUMED_THROW_MSG(PLMD::ExceptionError);
+      80          61 :   __PLUMED_THROW_MSG(PLMD::ExceptionDebug);
+      81          60 :   __PLUMED_THROW_MSG(PLMD::Exception);
+      82          59 :   __PLUMED_THROW_MSG(PLMD::lepton::Exception);
+      83          57 :   __PLUMED_THROW_NOMSG(std::bad_exception);
+      84          56 :   __PLUMED_THROW_NOMSG(std::bad_array_new_length);
+      85          55 :   __PLUMED_THROW_NOMSG(std::bad_alloc);
+      86          54 :   __PLUMED_THROW_NOMSG(std::bad_function_call);
+      87          53 :   __PLUMED_THROW_NOMSG(std::bad_weak_ptr);
+      88          52 :   __PLUMED_THROW_NOMSG(std::bad_cast);
+      89          51 :   __PLUMED_THROW_NOMSG(std::bad_typeid);
+      90          50 :   __PLUMED_THROW_NOMSG(std::bad_variant_access);
+      91          49 :   __PLUMED_THROW_NOMSG(std::bad_optional_access);
+      92          48 :   __PLUMED_THROW_NOMSG(std::bad_any_cast);
+      93          47 :   __PLUMED_THROW_MSG(std::underflow_error);
+      94          46 :   __PLUMED_THROW_MSG(std::overflow_error);
+      95          45 :   __PLUMED_THROW_MSG(std::range_error);
+      96          44 :   __PLUMED_THROW_MSG(std::runtime_error);
+      97          43 :   __PLUMED_THROW_MSG(std::out_of_range);
+      98          42 :   __PLUMED_THROW_MSG(std::length_error);
+      99          41 :   __PLUMED_THROW_MSG(std::domain_error);
+     100          40 :   __PLUMED_THROW_MSG(std::invalid_argument);
+     101          39 :   __PLUMED_THROW_MSG(std::logic_error);
+     102             : 
+     103             : 
+     104             : 
+     105          38 :   if(words[0]=="std::system_error") {
+     106           4 :     plumed_assert(words.size()>2);
+     107             :     int error_code;
+     108           4 :     Tools::convert(words[2],error_code);
+     109           4 :     if(words[1]=="std::generic_category") throw std::system_error(error_code,std::generic_category(),what);
+     110           3 :     if(words[1]=="std::system_category") throw std::system_error(error_code,std::system_category(),what);
+     111           2 :     if(words[1]=="std::iostream_category") throw std::system_error(error_code,std::iostream_category(),what);
+     112           1 :     if(words[1]=="std::future_category") throw std::system_error(error_code,std::future_category(),what);
+     113             :   }
+     114             : 
+     115          34 :   if(words[0]=="std::filesystem::filesystem_error") {
+     116             :     int error_code;
+     117           3 :     plumed_assert(words.size()>2);
+     118           3 :     Tools::convert(words[2],error_code);
+     119             :     std::error_code x_error_code;
+     120           3 :     if(words[1]=="std::generic_category") x_error_code=::std::error_code(error_code,::std::generic_category());
+     121           3 :     if(words[1]=="std::system_category") x_error_code=::std::error_code(error_code,::std::system_category());
+     122           3 :     if(words[1]=="std::iostream_category") x_error_code=::std::error_code(error_code,::std::iostream_category());
+     123           3 :     if(words[1]=="std::future_category") x_error_code=::std::error_code(error_code,::std::future_category());
+     124             : 
+     125           4 :     if(words.size()<4) throw std::filesystem::filesystem_error(what,x_error_code);
+     126           4 :     if(words.size()<5) throw std::filesystem::filesystem_error(what,std::filesystem::path(words[3]),x_error_code);
+     127           4 :     throw std::filesystem::filesystem_error(what,std::filesystem::path(words[3]),std::filesystem::path(words[4]),x_error_code);
+     128             :   }
+     129             : 
+     130             : #define __PLUMED_THROW_REGEX(name) if(words[1]=="std::regex_constants::error_" #name) throw std::regex_error(std::regex_constants::error_ ##name)
+     131          31 :   if(words[0]=="std::regex_error") {
+     132          13 :     plumed_assert(words.size()>1);
+     133          13 :     __PLUMED_THROW_REGEX(collate);
+     134          12 :     __PLUMED_THROW_REGEX(ctype);
+     135          11 :     __PLUMED_THROW_REGEX(escape);
+     136          10 :     __PLUMED_THROW_REGEX(backref);
+     137           9 :     __PLUMED_THROW_REGEX(brack);
+     138           8 :     __PLUMED_THROW_REGEX(paren);
+     139           7 :     __PLUMED_THROW_REGEX(brace);
+     140           6 :     __PLUMED_THROW_REGEX(badbrace);
+     141           5 :     __PLUMED_THROW_REGEX(range);
+     142           4 :     __PLUMED_THROW_REGEX(space);
+     143           3 :     __PLUMED_THROW_REGEX(badrepeat);
+     144           2 :     __PLUMED_THROW_REGEX(complexity);
+     145           1 :     __PLUMED_THROW_REGEX(stack);
+     146             :   }
+     147             : 
+     148             : #define __PLUMED_THROW_FUTURE(name) if(words[1]=="std::future_errc::" #name) throw std::future_error(::std::future_errc::name)
+     149          18 :   if(words[0]=="std::future_error") {
+     150           4 :     plumed_assert(words.size()>1);
+     151           4 :     __PLUMED_THROW_FUTURE(broken_promise);
+     152           3 :     __PLUMED_THROW_FUTURE(future_already_retrieved);
+     153           2 :     __PLUMED_THROW_FUTURE(promise_already_satisfied);
+     154           1 :     __PLUMED_THROW_FUTURE(no_state);
+     155             :   }
+     156             : 
+     157          14 :   if(words[0]=="std::ios_base::failure") {
+     158           1 :     int error_code=0;
+     159           1 :     if(words.size()>2) Tools::convert(words[2],error_code);
+     160           1 :     if(words.size()>1 && words[1]=="std::generic_category") throw std::ios_base::failure(what,std::error_code(error_code,std::generic_category()));
+     161           1 :     if(words.size()>1 && words[1]=="std::system_category") throw std::ios_base::failure(what,std::error_code(error_code,std::system_category()));
+     162           1 :     if(words.size()>1 && words[1]=="std::iostream_category") throw std::ios_base::failure(what,std::error_code(error_code,std::iostream_category()));
+     163           1 :     if(words.size()>1 && words[1]=="std::future_category") throw std::ios_base::failure(what,std::error_code(error_code,std::future_category()));
+     164           2 :     throw std::ios_base::failure(what);
+     165             :   }
+     166             : 
+     167          13 :   if(words[0]=="int") {
+     168           1 :     int value=0;
+     169           1 :     if(words.size()>1) Tools::convert(words[1],value);
+     170           1 :     throw value;
+     171             :   }
+     172             : 
+     173          12 :   if(words[0]=="test_nested1") {
+     174             :     try {
+     175          12 :       throw Exception(std::string("inner ")+what);
+     176           6 :     } catch(...) {
+     177             :       try {
+     178          18 :         std::throw_with_nested(Exception(std::string("middle ")+what));
+     179           6 :       } catch(...) {
+     180          18 :         std::throw_with_nested(Exception(std::string("outer ")+what));
+     181           6 :       }
+     182           6 :     }
+     183             :   }
+     184             : 
+     185           6 :   if(words[0]=="test_nested2") {
+     186             :     try {
+     187           3 :       throw std::bad_alloc();
+     188           3 :     } catch(...) {
+     189             :       try {
+     190           9 :         std::throw_with_nested(Exception(std::string("middle ")+what));
+     191           3 :       } catch(...) {
+     192           9 :         std::throw_with_nested(Exception(std::string("outer ")+what));
+     193           3 :       }
+     194           3 :     }
+     195             :   }
+     196             : 
+     197           3 :   if(words[0]=="test_nested3") {
+     198             :     try {
+     199           2 :       throw "inner";
+     200           2 :     } catch(...) {
+     201             :       try {
+     202           6 :         std::throw_with_nested(Exception(std::string("middle ")+what));
+     203           2 :       } catch(...) {
+     204           6 :         std::throw_with_nested(Exception(std::string("outer ")+what));
+     205           2 :       }
+     206           2 :     }
+     207             :   }
+     208             : 
+     209           2 :   plumed_error() << "unknown exception " << what;
+     210          61 : }
+     211             : 
+     212             : namespace {
+     213             : // This is an internal tool used to count how many PlumedMain objects have been created
+     214             : // and if they were correctly destroyed.
+     215             : // When using debug options, it leads to a crash
+     216             : // Otherwise, it just prints a message
+     217             : class CountInstances {
+     218             :   std::atomic<int> counter{};
+     219             : public:
+     220             :   void increase() noexcept {
+     221             :     ++counter;
+     222             :   }
+     223             :   void decrease() noexcept {
+     224             :     --counter;
+     225             :   }
+     226        4187 :   ~CountInstances() {
+     227        4187 :     if(counter!=0) {
+     228           0 :       std::cerr<<"WARNING: internal inconsistency in allocated PlumedMain instances (" <<counter<< ")\n";
+     229             : #ifndef NDEBUG
+     230             :       std::abort();
+     231             : #endif
+     232             :     }
+     233        4187 :   }
+     234             : };
+     235             : static CountInstances countInstances;
+     236             : }
+     237             : 
+     238             : 
+     239      805283 : PlumedMain::PlumedMain():
+     240      805283 :   initialized(false),
+     241      805283 :   MDEngine("mdcode"),
+     242             : // automatically write on log in destructor
+     243      805283 :   stopwatch_fwd(log),
+     244      805283 :   step(0),
+     245      805283 :   active(false),
+     246      805283 :   endPlumed(false),
+     247      805283 :   passtools(DataPassingTools::create(sizeof(double))),
+     248      805283 :   actionSet_fwd(*this),
+     249      805283 :   bias(0.0),
+     250      805283 :   work(0.0),
+     251      805283 :   exchangeStep(false),
+     252      805283 :   restart(false),
+     253      805283 :   doCheckPoint(false),
+     254      805283 :   stopNow(false),
+     255           0 :   name_of_energy(""),
+     256      805283 :   novirial(false),
+     257      805283 :   detailedTimers(false),
+     258      805283 :   gpuDeviceId(-1)
+     259             : {
+     260      805283 :   passtools->usingNaturalUnits=false;
+     261      805283 :   increaseReferenceCounter();
+     262      805283 :   log.link(comm);
+     263     1610566 :   log.setLinePrefix("PLUMED: ");
+     264             :   // this is at last so as to avoid inconsistencies if an exception is thrown
+     265             :   countInstances.increase(); // noexcept
+     266      805283 : }
+     267             : 
+     268             : // destructor needed to delete forward declarated objects
+     269     1609749 : PlumedMain::~PlumedMain() {
+     270             :   countInstances.decrease();
+     271     4830881 : }
+     272             : 
+     273             : /////////////////////////////////////////////////////////////
+     274             : //  MAIN INTERPRETER
+     275             : 
+     276             : #define CHECK_INIT(ini,word) plumed_assert(ini)<<"cmd(\"" << word << "\") should be only used after plumed initialization"
+     277             : #define CHECK_NOTINIT(ini,word) plumed_assert(!(ini))<<"cmd(\"" << word << "\") should be only used before plumed initialization"
+     278             : #define CHECK_NOTNULL(val,word) plumed_assert(val)<<"NULL pointer received in cmd(\"" << word << "\")"
+     279             : 
+     280             : 
+     281     1118633 : void PlumedMain::cmd(std::string_view word,const TypesafePtr & val) {
+     282             : 
+     283             : // Enumerate all possible commands:
+     284             :   enum {
+     285             : #include "PlumedMainEnum.inc"
+     286             :   };
+     287             : 
+     288             : // Static object (initialized once) containing the map of commands:
+     289             :   const static Tools::FastStringUnorderedMap<int> word_map = {
+     290             : #include "PlumedMainMap.inc"
+     291     1118633 :   };
+     292             : 
+     293             :   try {
+     294             : 
+     295     1118633 :     auto ss=stopwatch.startPause();
+     296             : 
+     297             :     gch::small_vector<std::string_view> words;
+     298     1118633 :     Tools::getWordsSimple(words,word);
+     299             : 
+     300     1118633 :     unsigned nw=words.size();
+     301     1118633 :     if(nw==0) {
+     302             :       // do nothing
+     303             :     } else {
+     304             :       int iword=-1;
+     305             :       const auto it=word_map.find(words[0]);
+     306     1118633 :       if(it!=word_map.end()) iword=it->second;
+     307             : 
+     308     1118626 :       switch(iword) {
+     309       51602 :       case cmd_setBox:
+     310       51602 :         CHECK_INIT(initialized,word);
+     311       51602 :         CHECK_NOTNULL(val,word);
+     312       51602 :         setInputValue( "Box", 0, 1, val );
+     313       51602 :         break;
+     314       55743 :       case cmd_setPositions:
+     315       55743 :         CHECK_INIT(initialized,word);
+     316       55743 :         setInputValue("posx", 0, 3, val );
+     317       55743 :         setInputValue("posy", 1, 3, val );
+     318       55743 :         setInputValue("posz", 2, 3, val );
+     319       55743 :         break;
+     320       55747 :       case cmd_setMasses:
+     321       55747 :         CHECK_INIT(initialized,word);
+     322       55747 :         setInputValue("Masses", 0, 1, val );
+     323       55744 :         break;
+     324       45838 :       case cmd_setCharges:
+     325       45838 :         CHECK_INIT(initialized,word);
+     326       45838 :         setInputValue("Charges", 0, 1, val);
+     327       45838 :         break;
+     328           1 :       case cmd_setPositionsX:
+     329           1 :         CHECK_INIT(initialized,word);
+     330           1 :         setInputValue("posx", 0, 1, val);
+     331           1 :         break;
+     332           1 :       case cmd_setPositionsY:
+     333           1 :         CHECK_INIT(initialized,word);
+     334           1 :         setInputValue("posy", 0, 1, val);
+     335           1 :         break;
+     336           1 :       case cmd_setPositionsZ:
+     337           1 :         CHECK_INIT(initialized,word);
+     338           1 :         setInputValue("posz", 0, 1, val);
+     339           1 :         break;
+     340       45944 :       case cmd_setVirial:
+     341       45944 :         CHECK_INIT(initialized,word);
+     342       45944 :         CHECK_NOTNULL(val,word);
+     343       45944 :         setInputForce("Box",val);
+     344       45942 :         break;
+     345        9792 :       case cmd_setEnergy:
+     346        9792 :         CHECK_INIT(initialized,word);
+     347        9792 :         CHECK_NOTNULL(val,word);
+     348        9792 :         if( name_of_energy!="" ) setInputValue( name_of_energy, 0, 1,  val );
+     349             :         break;
+     350       55743 :       case cmd_setForces:
+     351       55743 :         CHECK_INIT(initialized,word);
+     352       55743 :         setInputForce("posx",val);
+     353       55743 :         setInputForce("posy",val);
+     354       55743 :         setInputForce("posz",val);
+     355       55743 :         break;
+     356           1 :       case cmd_setForcesX:
+     357           1 :         CHECK_INIT(initialized,word);
+     358           1 :         setInputForce("posx",val);
+     359           1 :         break;
+     360           1 :       case cmd_setForcesY:
+     361           1 :         CHECK_INIT(initialized,word);
+     362           1 :         setInputForce("posy",val);
+     363           1 :         break;
+     364           1 :       case cmd_setForcesZ:
+     365           1 :         CHECK_INIT(initialized,word);
+     366           1 :         setInputForce("posz",val);
+     367           1 :         break;
+     368      253984 :       case cmd_calc:
+     369      253984 :         CHECK_INIT(initialized,word);
+     370      253984 :         calc();
+     371             :         break;
+     372          99 :       case cmd_prepareDependencies:
+     373          99 :         CHECK_INIT(initialized,word);
+     374          99 :         prepareDependencies();
+     375             :         break;
+     376          84 :       case cmd_shareData:
+     377          84 :         CHECK_INIT(initialized,word);
+     378          84 :         shareData();
+     379             :         break;
+     380        2070 :       case cmd_prepareCalc:
+     381        2070 :         CHECK_INIT(initialized,word);
+     382        2070 :         prepareCalc();
+     383             :         break;
+     384          10 :       case cmd_performCalc:
+     385          10 :         CHECK_INIT(initialized,word);
+     386          10 :         performCalc();
+     387             :         break;
+     388        2134 :       case cmd_performCalcNoUpdate:
+     389        2134 :         CHECK_INIT(initialized,word);
+     390        2134 :         performCalcNoUpdate();
+     391             :         break;
+     392          10 :       case cmd_performCalcNoForces:
+     393          10 :         CHECK_INIT(initialized,word);
+     394          10 :         performCalcNoForces();
+     395             :         break;
+     396          79 :       case cmd_update:
+     397          79 :         CHECK_INIT(initialized,word);
+     398          79 :         update();
+     399             :         break;
+     400        6090 :       case cmd_setStep:
+     401        6090 :         CHECK_INIT(initialized,word);
+     402        6093 :         CHECK_NOTNULL(val,word);
+     403        6087 :         step=val.get<int>();
+     404        6087 :         startStep();
+     405             :         break;
+     406           0 :       case cmd_setStepLong:
+     407           0 :         CHECK_INIT(initialized,word);
+     408           0 :         CHECK_NOTNULL(val,word);
+     409           0 :         step=val.get<long int>();
+     410           0 :         startStep();
+     411             :         break;
+     412      250012 :       case cmd_setStepLongLong:
+     413      250012 :         CHECK_INIT(initialized,word);
+     414      250012 :         CHECK_NOTNULL(val,word);
+     415      250012 :         step=val.get<long long int>();
+     416      250012 :         startStep();
+     417             :         break;
+     418           0 :       case cmd_setValue:
+     419             :       {
+     420           0 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2); setInputValue( std::string(words[1]), 0, 1, val );
+     421             :       }
+     422           0 :       break;
+     423             :       /* ADDED WITH API=7 */
+     424           0 :       case cmd_setValueForces:
+     425             :       {
+     426           0 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2); setInputForce( std::string(words[1]), val );
+     427             :       }
+     428           0 :       break;
+     429             :       // words used less frequently:
+     430        1130 :       case cmd_setAtomsNlocal:
+     431        1130 :         CHECK_INIT(initialized,word);
+     432        1130 :         CHECK_NOTNULL(val,word);
+     433        4542 :         for(const auto & pp : inputs ) {
+     434        3412 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     435        3412 :           if( dd ) dd->setAtomsNlocal(val.get<int>());
+     436             :         }
+     437             :         break;
+     438         978 :       case cmd_setAtomsGatindex:
+     439         978 :         CHECK_INIT(initialized,word);
+     440        3934 :         for(const auto & pp : inputs ) {
+     441        2956 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     442        2956 :           if( dd ) dd->setAtomsGatindex(val,false);
+     443             :         }
+     444             :         break;
+     445           0 :       case cmd_setAtomsFGatindex:
+     446           0 :         CHECK_INIT(initialized,word);
+     447           0 :         for(const auto & pp : inputs ) {
+     448           0 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     449           0 :           if( dd ) dd->setAtomsGatindex(val,false);
+     450             :         }
+     451             :         break;
+     452         152 :       case cmd_setAtomsContiguous:
+     453         152 :         CHECK_INIT(initialized,word);
+     454         152 :         CHECK_NOTNULL(val,word);
+     455         608 :         for(const auto & pp : inputs ) {
+     456         456 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     457         456 :           if( dd ) dd->setAtomsContiguous(val.get<int>());
+     458             :         }
+     459             :         break;
+     460         116 :       case cmd_createFullList:
+     461         116 :         CHECK_INIT(initialized,word);
+     462         116 :         CHECK_NOTNULL(val,word);
+     463         553 :         for(const auto & pp : inputs ) {
+     464         437 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     465         437 :           if( dd ) dd->createFullList(val);
+     466             :         }
+     467             :         break;
+     468         116 :       case cmd_getFullList:
+     469             :       {
+     470         116 :         CHECK_INIT(initialized,word);
+     471         116 :         CHECK_NOTNULL(val,word);
+     472             :         unsigned nlists=0;
+     473         553 :         for(const auto & pp : inputs ) {
+     474         437 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     475         437 :           if( dd ) { dd->getFullList(val); nlists++; }
+     476             :         }
+     477         116 :         plumed_assert( nlists==1 );
+     478             :       }
+     479             :       break;
+     480         116 :       case cmd_clearFullList:
+     481         116 :         CHECK_INIT(initialized,word);
+     482         553 :         for(const auto & pp : inputs ) {
+     483         437 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     484         437 :           if( dd ) dd->clearFullList();
+     485             :         }
+     486             :         break;
+     487             :       /* ADDED WITH API==6 */
+     488          65 :       case cmd_getDataRank:
+     489             :       {
+     490          65 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2 || nw==3);
+     491          65 :         std::string vtype=""; if( nw==3 ) vtype=" TYPE="+std::string(words[2]);
+     492         195 :         readInputLine( "grab_" + std::string(words[1]) + ": GET ARG=" + std::string(words[1]) + vtype );
+     493         130 :         ActionToGetData* as=actionSet.selectWithLabel<ActionToGetData*>("grab_"+std::string(words[1]));
+     494          65 :         plumed_assert( as ); as->get_rank( val );
+     495             :       }
+     496          65 :       break;
+     497             :       /* ADDED WITH API==6 */
+     498           1 :       case cmd_getDataShape:
+     499             :       {
+     500           1 :         CHECK_INIT(initialized,std::string(words[0]));
+     501           2 :         ActionToGetData* as1=actionSet.selectWithLabel<ActionToGetData*>("grab_"+std::string(words[1]));
+     502           1 :         plumed_assert( as1 ); as1->get_shape( val );
+     503             :       }
+     504             :       break;
+     505             :       /* ADDED WITH API==6 */
+     506          65 :       case cmd_setMemoryForData:
+     507             :       {
+     508          65 :         CHECK_INIT(initialized,words[0]); plumed_assert(nw==2 || nw==3);
+     509         130 :         ActionToGetData* as2=actionSet.selectWithLabel<ActionToGetData*>("grab_"+std::string(words[1]));
+     510          65 :         plumed_assert( as2 ); as2->set_memory( val );
+     511             :       }
+     512             :       break;
+     513             :       /* ADDED WITH API==6 */
+     514             :       case cmd_setErrorHandler:
+     515             :       {
+     516           0 :         if(val) error_handler=*static_cast<const plumed_error_handler*>(val.get<const void*>());
+     517           0 :         else error_handler.handler=NULL;
+     518             :       }
+     519             :       break;
+     520           0 :       case cmd_read:
+     521           0 :         CHECK_INIT(initialized,word);
+     522           0 :         if(val)readInputFile(val.get<const char*>());
+     523           0 :         else   readInputFile("plumed.dat");
+     524             :         break;
+     525         274 :       case cmd_readInputLine:
+     526         274 :         CHECK_INIT(initialized,word);
+     527         274 :         CHECK_NOTNULL(val,word);
+     528         274 :         readInputLine(val.get<const char*>());
+     529         234 :         break;
+     530           1 :       case cmd_readInputLines:
+     531           1 :         CHECK_INIT(initialized,word);
+     532           1 :         CHECK_NOTNULL(val,word);
+     533           1 :         readInputLines(val.get<const char*>());
+     534           1 :         break;
+     535           1 :       case cmd_clear:
+     536             :       {
+     537           1 :         CHECK_INIT(initialized,word);
+     538             :         std::vector<int> natoms;
+     539           3 :         for(const auto & pp : inputs ) {
+     540           2 :           DomainDecomposition* dd=pp->castToDomainDecomposition();
+     541           2 :           if ( dd ) natoms.push_back( dd->getNumberOfAtoms() );
+     542             :         }
+     543           1 :         actionSet.clearDelete(); inputs.clear();
+     544           2 :         for(unsigned i=0; i<natoms.size(); ++i) {
+     545           1 :           std::string str_natoms; Tools::convert( natoms[i], str_natoms );
+     546           3 :           readInputLine( MDEngine + ": DOMAIN_DECOMPOSITION NATOMS=" + str_natoms +
+     547           2 :                          " VALUE1=posx UNIT1=length PERIODIC1=NO CONSTANT1=False ROLE1=x" +
+     548           2 :                          " VALUE2=posy UNIT2=length PERIODIC2=NO CONSTANT2=False ROLE2=y" +
+     549           2 :                          " VALUE3=posz UNIT3=length PERIODIC3=NO CONSTANT3=False ROLE3=z" +
+     550           2 :                          " VALUE4=Masses UNIT4=mass PERIODIC4=NO CONSTANT4=True ROLE4=m" +
+     551             :                          " VALUE5=Charges UNIT5=charge PERIODIC5=NO CONSTANT5=True ROLE5=q");
+     552             : 
+     553             :         }
+     554           1 :         setUnits( passtools->usingNaturalUnits, passtools->units );
+     555             :       }
+     556           1 :       break;
+     557             :       case cmd_getApiVersion:
+     558          42 :         CHECK_NOTNULL(val,word);
+     559          42 :         val.set(int(10));
+     560             :         break;
+     561             :       // commands which can be used only before initialization:
+     562        1011 :       case cmd_init:
+     563        1011 :         CHECK_NOTINIT(initialized,word);
+     564        1011 :         init();
+     565             :         break;
+     566         882 :       case cmd_setRealPrecision:
+     567         882 :         CHECK_NOTINIT(initialized,word);
+     568         882 :         CHECK_NOTNULL(val,word);
+     569        1763 :         passtools=DataPassingTools::create(val.get<int>());
+     570         881 :         passtools->usingNaturalUnits=false;
+     571         881 :         break;
+     572         814 :       case cmd_setMDLengthUnits:
+     573         814 :         CHECK_NOTINIT(initialized,word);
+     574         814 :         CHECK_NOTNULL(val,word);
+     575         814 :         passtools->MDUnits.setLength(passtools->MD2double(val));
+     576             :         break;
+     577         814 :       case cmd_setMDChargeUnits:
+     578         814 :         CHECK_NOTINIT(initialized,word);
+     579         814 :         CHECK_NOTNULL(val,word);
+     580         814 :         passtools->MDUnits.setCharge(passtools->MD2double(val));
+     581             :         break;
+     582         814 :       case cmd_setMDMassUnits:
+     583         814 :         CHECK_NOTINIT(initialized,word);
+     584         814 :         CHECK_NOTNULL(val,word);
+     585         814 :         passtools->MDUnits.setMass(passtools->MD2double(val));
+     586             :         break;
+     587          45 :       case cmd_setMDEnergyUnits:
+     588          45 :         CHECK_NOTINIT(initialized,word);
+     589          45 :         CHECK_NOTNULL(val,word);
+     590          45 :         passtools->MDUnits.setEnergy(passtools->MD2double(val));
+     591             :         break;
+     592           6 :       case cmd_setMDTimeUnits:
+     593           6 :         CHECK_NOTINIT(initialized,word);
+     594           6 :         CHECK_NOTNULL(val,word);
+     595           6 :         passtools->MDUnits.setTime(passtools->MD2double(val));
+     596             :         break;
+     597           0 :       case cmd_setNaturalUnits:
+     598             :         // set the boltzman constant for MD in natural units (kb=1)
+     599             :         // only needed in LJ codes if the MD is passing temperatures to plumed (so, not yet...)
+     600             :         // use as cmd("setNaturalUnits")
+     601           0 :         CHECK_NOTINIT(initialized,word);
+     602           0 :         passtools->usingNaturalUnits=true;
+     603           0 :         break;
+     604          52 :       case cmd_setNoVirial:
+     605             :       {
+     606          52 :         CHECK_NOTINIT(initialized,word);
+     607          52 :         ActionToPutData* ap=actionSet.selectWithLabel<ActionToPutData*>("Box");
+     608          52 :         if( ap ) ap->noforce=true;
+     609             :         else {
+     610           0 :           ActionForInterface* af = actionSet.selectWithLabel<ActionForInterface*>(MDEngine);
+     611           0 :           if( af ) plumed_merror("setNoVirial should be called after number of atoms have been set");
+     612             :         }
+     613             :       }
+     614             :       break;
+     615         869 :       case cmd_setPlumedDat:
+     616         869 :         CHECK_NOTINIT(initialized,word);
+     617         869 :         CHECK_NOTNULL(val,word);
+     618         869 :         plumedDat=val.get<const char*>();
+     619             :         break;
+     620         341 :       case cmd_setMPIComm:
+     621         341 :         CHECK_NOTINIT(initialized,word);
+     622         341 :         comm.Set_comm(val);
+     623         343 :         for(const auto & pp : inputs ) pp->Set_comm(comm);
+     624             :         break;
+     625           0 :       case cmd_setMPIFComm:
+     626           0 :         CHECK_NOTINIT(initialized,word);
+     627           0 :         comm.Set_fcomm(val);
+     628           0 :         for(const auto & pp : inputs ) pp->Set_comm(comm);
+     629             :         break;
+     630           0 :       case cmd_setMPImultiSimComm:
+     631           0 :         CHECK_NOTINIT(initialized,word);
+     632           0 :         multi_sim_comm.Set_comm(val);
+     633             :         break;
+     634         994 :       case cmd_setNatoms:
+     635             :       {
+     636         994 :         CHECK_NOTINIT(initialized,word);
+     637         994 :         CHECK_NOTNULL(val,word);
+     638         994 :         int natoms = val.get<int>(); std::string str_natoms; Tools::convert( natoms, str_natoms );
+     639         990 :         ActionForInterface* dd=actionSet.selectWithLabel<ActionForInterface*>(MDEngine);
+     640        3795 :         if( !dd && natoms>0 ) readInputLine( MDEngine + ": DOMAIN_DECOMPOSITION NATOMS=" + str_natoms +  +
+     641        1870 :                                                " VALUE1=posx UNIT1=length PERIODIC1=NO CONSTANT1=False ROLE1=x" +
+     642        1870 :                                                " VALUE2=posy UNIT2=length PERIODIC2=NO CONSTANT2=False ROLE2=y" +
+     643        1870 :                                                " VALUE3=posz UNIT3=length PERIODIC3=NO CONSTANT3=False ROLE3=z" +
+     644        1870 :                                                " VALUE4=Masses UNIT4=mass PERIODIC4=NO CONSTANT4=True ROLE4=m" +
+     645        1870 :                                                " VALUE5=Charges UNIT5=charge PERIODIC5=NO CONSTANT5=True ROLE5=q", true );
+     646             :       }
+     647         990 :       break;
+     648         870 :       case cmd_setTimestep:
+     649             :       {
+     650         870 :         CHECK_NOTINIT(initialized,word);
+     651         870 :         CHECK_NOTNULL(val,word);
+     652         870 :         ActionToPutData* ts = actionSet.selectWithLabel<ActionToPutData*>("timestep");
+     653         870 :         if( !ts ) {
+     654         868 :           readInputLine("timestep: PUT UNIT=time PERIODIC=NO CONSTANT", true);
+     655        1736 :           ts = actionSet.selectWithLabel<ActionToPutData*>("timestep");
+     656             :         }
+     657        1740 :         if( !ts->setValuePointer("timestep", val ) ) plumed_error();
+     658             :       }
+     659             :       break;
+     660             :       /* ADDED WITH API==2 */
+     661          59 :       case cmd_setKbT:
+     662             :       {
+     663          59 :         CHECK_NOTINIT(initialized,word);
+     664          59 :         CHECK_NOTNULL(val,word);
+     665          59 :         readInputLine("kBT: PUT CONSTANT PERIODIC=NO UNIT=energy", true);
+     666          59 :         ActionToPutData* kb = actionSet.selectWithLabel<ActionToPutData*>("kBT");
+     667         118 :         if( !kb->setValuePointer("kBT", val ) ) plumed_error();
+     668             :       }
+     669             :       break;
+     670             :       /* ADDED WITH API==3 */
+     671           8 :       case cmd_setRestart:
+     672           8 :         CHECK_NOTINIT(initialized,word);
+     673           8 :         CHECK_NOTNULL(val,word);
+     674           8 :         if(val.get<int>()!=0) restart=true;
+     675             :         break;
+     676             :       /* ADDED WITH API==4 */
+     677           0 :       case cmd_doCheckPoint:
+     678           0 :         CHECK_INIT(initialized,word);
+     679           0 :         CHECK_NOTNULL(val,word);
+     680           0 :         doCheckPoint = false;
+     681           0 :         if(val.get<int>()!=0) doCheckPoint = true;
+     682             :         break;
+     683             :       /* ADDED WITH API==6 */
+     684             :       case cmd_setNumOMPthreads:
+     685           0 :         CHECK_NOTNULL(val,word);
+     686             :         {
+     687           0 :           auto nt=val.get<unsigned>();
+     688             :           if(nt==0) nt=1;
+     689           0 :           OpenMP::setNumThreads(nt);
+     690             :         }
+     691             :         break;
+     692             :       /* ADDED WITH API==10 */
+     693             :       case cmd_setGpuDeviceId:
+     694           0 :         CHECK_NOTNULL(val,word);
+     695             :         {
+     696           0 :           auto id=val.get<int>();
+     697           0 :           if(id>=0) gpuDeviceId=id;
+     698             :         }
+     699             :         break;
+     700             :       /* ADDED WITH API==6 */
+     701             :       /* only used for testing */
+     702             :       case cmd_throw:
+     703          61 :         CHECK_NOTNULL(val,word);
+     704          61 :         testThrow(val.get<const char*>());
+     705             :       /* ADDED WITH API==10 */
+     706             :       case cmd_setNestedExceptions:
+     707          25 :         CHECK_NOTNULL(val,word);
+     708          25 :         if(val.get<int>()!=0) nestedExceptions=true;
+     709           1 :         else nestedExceptions=false;
+     710             :         break;
+     711             :       /* STOP API */
+     712         867 :       case cmd_setMDEngine:
+     713         867 :         CHECK_NOTINIT(initialized,word);
+     714         867 :         CHECK_NOTNULL(val,word);
+     715         867 :         MDEngine=val.get<const char*>();
+     716             :         break;
+     717         854 :       case cmd_setLog:
+     718         854 :         CHECK_NOTINIT(initialized,word);
+     719         854 :         log.link(val.get<FILE*>());
+     720             :         break;
+     721          53 :       case cmd_setLogFile:
+     722          53 :         CHECK_NOTINIT(initialized,word);
+     723          53 :         CHECK_NOTNULL(val,word);
+     724         175 :         log.open(val.get<const char*>());
+     725          53 :         break;
+     726             :       // other commands that should be used after initialization:
+     727      253911 :       case cmd_setStopFlag:
+     728      253911 :         CHECK_INIT(initialized,word);
+     729      253911 :         CHECK_NOTNULL(val,word);
+     730      253911 :         val.get<int*>(); // just check type and discard pointer
+     731      253910 :         stopFlag=val.copy();
+     732      253910 :         break;
+     733           0 :       case cmd_getExchangesFlag:
+     734           0 :         CHECK_INIT(initialized,word);
+     735           0 :         CHECK_NOTNULL(val,word);
+     736           0 :         exchangePatterns.getFlag(*val.get<int*>()); // note: getFlag changes the value of the reference!
+     737             :         break;
+     738           0 :       case cmd_setExchangesSeed:
+     739           0 :         CHECK_INIT(initialized,word);
+     740           0 :         CHECK_NOTNULL(val,word);
+     741           0 :         exchangePatterns.setSeed(val.get<int>());
+     742             :         break;
+     743           0 :       case cmd_setNumberOfReplicas:
+     744           0 :         CHECK_INIT(initialized,word);
+     745           0 :         CHECK_NOTNULL(val,word);
+     746           0 :         exchangePatterns.setNofR(val.get<int>());
+     747             :         break;
+     748           0 :       case cmd_getExchangesList:
+     749           0 :         CHECK_INIT(initialized,word);
+     750           0 :         CHECK_NOTNULL(val,word);
+     751           0 :         exchangePatterns.getList(val.get<int*>());
+     752           0 :         break;
+     753         817 :       case cmd_runFinalJobs:
+     754         817 :         CHECK_INIT(initialized,word);
+     755         817 :         runJobsAtEndOfCalculation();
+     756             :         break;
+     757          96 :       case cmd_isEnergyNeeded:
+     758             :       {
+     759          96 :         CHECK_INIT(initialized,word);
+     760          96 :         CHECK_NOTNULL(val,word);
+     761          96 :         if( name_of_energy =="" ) {
+     762          96 :           val.set(int(0));
+     763             :         } else {
+     764           0 :           ActionToPutData* ap=actionSet.selectWithLabel<ActionToPutData*>(name_of_energy);
+     765           0 :           if(ap->isActive()) val.set(int(1));
+     766           0 :           else               val.set(int(0));
+     767             :         }
+     768             :       }
+     769             :       break;
+     770        2172 :       case cmd_getBias:
+     771        2172 :         CHECK_INIT(initialized,word);
+     772        2172 :         CHECK_NOTNULL(val,word);
+     773        2172 :         plumedQuantityToMD( "energy", getBias(), val );
+     774        2172 :         break;
+     775             :       case cmd_checkAction:
+     776           2 :         CHECK_NOTNULL(val,word);
+     777           2 :         plumed_assert(nw==2);
+     778           5 :         val.set(int(actionRegister().check(std::string(words[1])) ? 1:0));
+     779           2 :         break;
+     780             :       case cmd_setExtraCV:
+     781             :       {
+     782          30 :         CHECK_NOTNULL(val,word);
+     783          30 :         plumed_assert(nw==2);
+     784          90 :         if( valueExists(std::string(words[1])) ) setInputValue( std::string(words[1]), 0, 1, val );
+     785             :       }
+     786             :       break;
+     787             :       case cmd_setExtraCVForce:
+     788             :       {
+     789          30 :         CHECK_NOTNULL(val,word); plumed_assert(nw==2);
+     790         120 :         if( valueExists(std::string(words[1])) ) setInputForce( std::string(words[1]), val );
+     791             :       }
+     792             :       break;
+     793             :       /* ADDED WITH API==10 */
+     794             :       case cmd_isExtraCVNeeded:
+     795          10 :         CHECK_NOTNULL(val,word);
+     796          10 :         plumed_assert(nw==2); val.set(int(0));
+     797          56 :         for(const auto & p : inputs) {
+     798          50 :           if( p->getLabel()==words[1] && p->isActive() ) { val.set(int(1)); break; }
+     799             :         }
+     800             :         break;
+     801        1077 :       case cmd_GREX:
+     802        1281 :         if(!grex) grex=Tools::make_unique<GREX>(*this);
+     803        1077 :         plumed_massert(grex,"error allocating grex");
+     804             :         {
+     805        1077 :           std::string kk=std::string(words[1]);
+     806        1419 :           for(unsigned i=2; i<words.size(); i++) kk+=" "+std::string(words[i]);
+     807        1077 :           grex->cmd(kk.c_str(),val);
+     808             :         }
+     809        1077 :         break;
+     810       12941 :       case cmd_CLTool:
+     811       12941 :         CHECK_NOTINIT(initialized,word);
+     812       17169 :         if(!cltool) cltool=Tools::make_unique<CLToolMain>();
+     813             :         {
+     814       12941 :           std::string kk(words[1]);
+     815       12941 :           for(unsigned i=2; i<words.size(); i++) kk+=" "+std::string(words[i]);
+     816       12941 :           cltool->cmd(kk.c_str(),val);
+     817             :         }
+     818       12941 :         break;
+     819             :         break;
+     820             :       /* ADDED WITH API==7 */
+     821             :       case cmd_convert:
+     822             :       {
+     823             :         double v;
+     824          57 :         plumed_assert(words.size()==2);
+     825         236 :         if(Tools::convertNoexcept(std::string(words[1]),v)) passtools->double2MD(v,val);
+     826             :       }
+     827          57 :       break;
+     828           7 :       default:
+     829          14 :         plumed_error() << "cannot interpret cmd(\"" << word << "\"). check plumed developers manual to see the available commands.";
+     830             :         break;
+     831             :       }
+     832             :     }
+     833             : 
+     834     1118755 :   } catch (...) {
+     835         122 :     if(log.isOpen()) {
+     836             :       try {
+     837          54 :         log<<"\n################################################################################\n";
+     838          54 :         log<<Tools::concatenateExceptionMessages();
+     839          54 :         log<<"\n################################################################################\n";
+     840          54 :         log.flush();
+     841           0 :       } catch(...) {
+     842             :         // ignore errors here.
+     843             :         // in any case, we are rethrowing this below
+     844           0 :       }
+     845             :     }
+     846         122 :     throw;
+     847         122 :   }
+     848     1118511 : }
+     849             : 
+     850             : ////////////////////////////////////////////////////////////////////////
+     851             : 
+     852        1011 : void PlumedMain::init() {
+     853             : // check that initialization just happens once
+     854        1011 :   initialized=true;
+     855        1011 :   if(!log.isOpen()) log.link(stdout);
+     856        1011 :   log<<"PLUMED is starting\n";
+     857        3033 :   log<<"Version: "<<config::getVersionLong()<<" (git: "<<config::getVersionGit()<<") "
+     858        4044 :      <<"compiled on " <<config::getCompilationDate() << " at " << config::getCompilationTime() << "\n";
+     859        1011 :   log<<"Please cite these papers when using PLUMED ";
+     860        2022 :   log<<cite("The PLUMED consortium, Nat. Methods 16, 670 (2019)");
+     861        2022 :   log<<cite("Tribello, Bonomi, Branduardi, Camilloni, and Bussi, Comput. Phys. Commun. 185, 604 (2014)");
+     862        1011 :   log<<"\n";
+     863        1011 :   log<<"For further information see the PLUMED web page at http://www.plumed.org\n";
+     864        1011 :   log<<"Root: "<<config::getPlumedRoot()<<"\n";
+     865        1011 :   log<<"LibraryPath: "<<config::getLibraryPath()<<"\n";
+     866        2022 :   log<<"For installed feature, see "<<config::getPlumedRoot() + "/src/config/config.txt\n";
+     867        1011 :   log.printf("Molecular dynamics engine: %s\n",MDEngine.c_str());
+     868        1011 :   log.printf("Precision of reals: %d\n",passtools->getRealPrecision());
+     869        1794 :   log.printf("Running over %d %s\n",comm.Get_size(),(comm.Get_size()>1?"nodes":"node"));
+     870        1011 :   log<<"Number of threads: "<<OpenMP::getNumThreads()<<"\n";
+     871        1011 :   log<<"Cache line size: "<<OpenMP::getCachelineSize()<<"\n";
+     872        3808 :   for(const auto & pp : inputs ) {
+     873        2797 :     DomainDecomposition* dd=pp->castToDomainDecomposition();
+     874        2797 :     if ( dd ) log.printf("Number of atoms: %d\n",dd->getNumberOfAtoms());
+     875             :   }
+     876        1011 :   if(grex) log.printf("GROMACS-like replica exchange is on\n");
+     877        1011 :   log.printf("File suffix: %s\n",getSuffix().c_str());
+     878        1011 :   if(plumedDat.length()>0) {
+     879         869 :     readInputFile(plumedDat);
+     880             :     plumedDat="";
+     881             :   }
+     882        1011 :   setUnits( passtools->usingNaturalUnits, passtools->units );
+     883        1011 :   ActionToPutData* ts = actionSet.selectWithLabel<ActionToPutData*>("timestep");
+     884        1011 :   if(ts) log.printf("Timestep: %f\n",(ts->copyOutput(0))->get());
+     885        1011 :   ActionToPutData* kb = actionSet.selectWithLabel<ActionToPutData*>("kBT");
+     886        1011 :   if(kb)
+     887          59 :     log.printf("KbT: %f\n",(kb->copyOutput(0))->get());
+     888             :   else {
+     889         952 :     log.printf("KbT has not been set by the MD engine\n");
+     890         952 :     log.printf("It should be set by hand where needed\n");
+     891             :   }
+     892        1011 :   log<<"Relevant bibliography:\n";
+     893        1011 :   log<<citations;
+     894        1011 :   log<<"Please read and cite where appropriate!\n";
+     895        1011 :   log<<"Finished setup\n";
+     896        1011 : }
+     897             : 
+     898       22706 : void PlumedMain::setupInterfaceActions() {
+     899       44422 :   inputs.clear(); std::vector<ActionForInterface*> ap=actionSet.select<ActionForInterface*>();
+     900      172152 :   for(unsigned i=0; i<ap.size(); ++i) {
+     901      149446 :     if( ap[i]->getName()=="ENERGY" || ap[i]->getDependencies().size()==0 ) inputs.push_back( ap[i] );
+     902             :   }
+     903       22706 : }
+     904             : 
+     905         887 : void PlumedMain::readInputFile(const std::string & str) {
+     906         887 :   plumed_assert(initialized);
+     907         887 :   log<<"FILE: "<<str<<"\n";
+     908         887 :   IFile ifile;
+     909         887 :   ifile.link(*this);
+     910         887 :   ifile.open(str);
+     911         887 :   ifile.allowNoEOL();
+     912         887 :   readInputFile(ifile);
+     913         887 :   log<<"END FILE: "<<str<<"\n";
+     914         887 :   log.flush();
+     915             : 
+     916         887 : }
+     917             : 
+     918         888 : void PlumedMain::readInputFile(IFile & ifile) {
+     919             :   std::vector<std::string> words;
+     920       14968 :   while(Tools::getParsedLine(ifile,words) && !endPlumed) readInputWords(words,false);
+     921         888 :   endPlumed=false;
+     922         888 :   pilots=actionSet.select<ActionPilot*>();
+     923         888 :   setupInterfaceActions();
+     924         888 : }
+     925             : 
+     926        7908 : void PlumedMain::readInputLine(const std::string & str, const bool& before_init) {
+     927        7908 :   if( !before_init ) plumed_assert(initialized);
+     928        7908 :   if(str.empty()) return;
+     929        7908 :   std::vector<std::string> words=Tools::getWords(str);
+     930        7908 :   citations.clear();
+     931        7908 :   readInputWords(words,before_init);
+     932        7868 :   if(!citations.empty()) {
+     933           2 :     log<<"Relevant bibliography:\n";
+     934           2 :     log<<citations;
+     935           2 :     log<<"Please read and cite where appropriate!\n";
+     936             :   }
+     937        7908 : }
+     938             : 
+     939           1 : void PlumedMain::readInputLines(const std::string & str) {
+     940           1 :   plumed_assert(initialized);
+     941           1 :   if(str.empty()) return;
+     942             : 
+     943           1 :   log<<"FILE: (temporary)\n";
+     944             : 
+     945             :   // Open a temporary file
+     946           1 :   auto fp=std::tmpfile();
+     947           1 :   plumed_assert(fp);
+     948             : 
+     949             :   // make sure file is closed (and thus deleted) also if an exception occurs
+     950           1 :   auto deleter=[](auto fp) { std::fclose(fp); };
+     951             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     952             : 
+     953           1 :   auto ret=std::fputs(str.c_str(),fp);
+     954           1 :   plumed_assert(ret!=EOF);
+     955             : 
+     956           1 :   std::rewind(fp);
+     957             : 
+     958           1 :   IFile ifile;
+     959           1 :   ifile.link(*this);
+     960           1 :   ifile.link(fp);
+     961           1 :   ifile.allowNoEOL();
+     962             : 
+     963           1 :   readInputFile(ifile);
+     964           1 :   log<<"END FILE: (temporary)\n";
+     965           1 : }
+     966             : 
+     967       22014 : void PlumedMain::readInputWords(const std::vector<std::string> & words, const bool& before_init) {
+     968       22014 :   if( !before_init ) plumed_assert(initialized);
+     969       22014 :   if(words.empty())return;
+     970       21858 :   else if(words[0]=="_SET_SUFFIX") {
+     971           3 :     plumed_assert(words.size()==2);
+     972             :     setSuffix(words[1]);
+     973             :   } else {
+     974       21855 :     std::vector<std::string> interpreted(words);
+     975       21855 :     Tools::interpretLabel(interpreted);
+     976       43672 :     auto action=actionRegister().create(ActionOptions(*this,interpreted));
+     977       21817 :     if(!action) {
+     978             :       std::string msg;
+     979             :       msg ="ERROR\nI cannot understand line:";
+     980          10 :       for(unsigned i=0; i<interpreted.size(); ++i) msg+=" "+interpreted[i];
+     981             :       msg+="\nMaybe a missing space or a typo?";
+     982           2 :       log << msg;
+     983           2 :       log.flush();
+     984           4 :       plumed_merror(msg);
+     985             :     }
+     986       21815 :     action->checkRead();
+     987       21815 :     actionSet.emplace_back(std::move(action));
+     988       21857 :   };
+     989             : 
+     990       21818 :   pilots=actionSet.select<ActionPilot*>();
+     991       21818 :   setupInterfaceActions();
+     992             : }
+     993             : 
+     994             : ////////////////////////////////////////////////////////////////////////
+     995             : 
+     996           0 : void PlumedMain::exit(int c) {
+     997           0 :   comm.Abort(c);
+     998           0 : }
+     999             : 
+    1000       21853 : Log& PlumedMain::getLog() {
+    1001       21853 :   return log;
+    1002             : }
+    1003             : 
+    1004      253984 : void PlumedMain::calc() {
+    1005      253984 :   prepareCalc();
+    1006      253984 :   performCalc();
+    1007      253984 : }
+    1008             : 
+    1009      256054 : void PlumedMain::prepareCalc() {
+    1010      256054 :   prepareDependencies();
+    1011      256054 :   shareData();
+    1012      256054 : }
+    1013             : 
+    1014             : //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+    1015             : // here we have the main steps in "calc()"
+    1016             : // they can be called individually, but the standard thing is to
+    1017             : // traverse them in this order:
+    1018      256381 : void PlumedMain::prepareDependencies() {
+    1019             : 
+    1020             : // Stopwatch is stopped when sw goes out of scope
+    1021      256381 :   auto sw=stopwatch.startStop("1 Prepare dependencies");
+    1022             : 
+    1023             : // activate all the actions which are on step
+    1024             : // activation is recursive and enables also the dependencies
+    1025             : // before doing that, the prepare() method is called to see if there is some
+    1026             : // new/changed dependency (up to now, only useful for dependences on virtual atoms,
+    1027             : // which can be dynamically changed).
+    1028             : 
+    1029             : // First switch off all actions
+    1030     2748316 :   for(const auto & p : actionSet) {
+    1031     2491935 :     p->deactivate();
+    1032             :   }
+    1033             : 
+    1034             : // for optimization, an "active" flag remains false if no action at all is active
+    1035      256381 :   active=false;
+    1036     1604461 :   for(unsigned i=0; i<pilots.size(); ++i) {
+    1037     1348080 :     if(pilots[i]->onStep()) {
+    1038     1278165 :       pilots[i]->activate();
+    1039     1278165 :       active=true;
+    1040             :     }
+    1041             :   };
+    1042             : 
+    1043             : // This stops the driver calculation if there is not a read action
+    1044      256381 :   if( !active && !inputsAreActive() ) stopFlag.set(int(1));
+    1045             : 
+    1046             : // also, if one of them is the total energy, tell to atoms that energy should be collected
+    1047     2748316 :   for(const auto & p : actionSet) {
+    1048     2491935 :     if(p->isActive()) {
+    1049     2019613 :       if(p->checkNeedsGradients()) p->setOption("GRADIENTS");
+    1050             :     }
+    1051             :   }
+    1052             : 
+    1053      256381 : }
+    1054             : 
+    1055        1707 : bool PlumedMain::inputsAreActive() const {
+    1056        5063 :   for(const auto & ip : inputs) {
+    1057        5010 :     if( ip->onStep() ) return true;
+    1058             :   }
+    1059             :   return false;
+    1060             : }
+    1061             : 
+    1062         114 : void PlumedMain::shareAll() {
+    1063         456 :   for(const auto & ip : inputs) ip->shareAll();
+    1064         114 : }
+    1065             : 
+    1066      256138 : void PlumedMain::shareData() {
+    1067             : // atom positions are shared (but only if there is something to do)
+    1068      256138 :   if(!active)return;
+    1069             : // Stopwatch is stopped when sw goes out of scope
+    1070      254490 :   auto sw=stopwatch.startStop("2 Sharing data");
+    1071      630979 :   for(const auto & ip : inputs) ip->share();
+    1072      254490 : }
+    1073             : 
+    1074        2134 : void PlumedMain::performCalcNoUpdate() {
+    1075        2134 :   waitData();
+    1076        2134 :   justCalculate();
+    1077        2134 :   backwardPropagate();
+    1078        2134 :   resetInputs();
+    1079        2134 : }
+    1080             : 
+    1081          10 : void PlumedMain::performCalcNoForces() {
+    1082          10 :   waitData();
+    1083          10 :   justCalculate();
+    1084          10 : }
+    1085             : 
+    1086      253994 : void PlumedMain::performCalc() {
+    1087      253994 :   waitData();
+    1088      253994 :   justCalculate();
+    1089      253994 :   backwardPropagate();
+    1090      253994 :   update();
+    1091      253994 :   resetInputs();
+    1092      253994 : }
+    1093             : 
+    1094      256252 : void PlumedMain::waitData() {
+    1095      256252 :   if(!active)return;
+    1096             : // Stopwatch is stopped when sw goes out of scope
+    1097      254604 :   auto sw=stopwatch.startStop("3 Waiting for data");
+    1098      631435 :   for(const auto & ip : inputs) {
+    1099      376831 :     if( ip->isActive() && ip->hasBeenSet() ) ip->wait();
+    1100      275838 :     else if( ip->isActive() ) ip->warning("input requested but this quantity has not been set");
+    1101             :   }
+    1102      254604 : }
+    1103             : 
+    1104      256252 : void PlumedMain::justCalculate() {
+    1105      256252 :   if(!active)return;
+    1106             : // Stopwatch is stopped when sw goes out of scope
+    1107      254604 :   auto sw=stopwatch.startStop("4 Calculating (forward loop)");
+    1108      254604 :   bias=0.0;
+    1109      254604 :   work=0.0;
+    1110             : 
+    1111             :   // Check the input actions to determine if we need to calculate constants that
+    1112             :   // depend on masses and charges
+    1113             :   bool firststep=false;
+    1114      631435 :   for(const auto & ip : inputs) {
+    1115      376831 :     if( ip->firststep ) firststep=true;
+    1116             :   }
+    1117      257333 :   if( firststep ) { for(const auto & ip : inputs) ip->firststep=false; }
+    1118             : 
+    1119             :   int iaction=0;
+    1120             : // calculate the active actions in order (assuming *backward* dependence)
+    1121     2721932 :   for(const auto & pp : actionSet) {
+    1122             :     Action* p(pp.get());
+    1123             :     try {
+    1124     2467328 :       if(p->isActive()) {
+    1125             : // Stopwatch is stopped when sw goes out of scope.
+    1126             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+    1127     2017760 :         Stopwatch::Handler sw;
+    1128     2017760 :         if(detailedTimers) {
+    1129        2481 :           auto actionNumberLabel=std::to_string(iaction);
+    1130        2481 :           const unsigned m=actionSet.size();
+    1131        7443 :           unsigned k=0; unsigned n=1; while(n<m) { n*=10; k++; }
+    1132        2481 :           auto spaces=std::string(k-actionNumberLabel.length(),' ');
+    1133        2481 :           sw=stopwatch.startStop("4A " + spaces + actionNumberLabel+" "+p->getLabel());
+    1134             :         }
+    1135     2017760 :         ActionWithValue*av=p->castToActionWithValue();
+    1136     2017760 :         ActionAtomistic*aa=p->castToActionAtomistic();
+    1137             :         {
+    1138     2017760 :           if(av) av->clearInputForces();
+    1139     2017760 :           if(av) av->clearDerivatives();
+    1140             :         }
+    1141             :         {
+    1142     2017760 :           if(aa) if(aa->isActive()) aa->retrieveAtoms();
+    1143             :         }
+    1144     2017760 :         if(p->checkNumericalDerivatives()) p->calculateNumericalDerivatives();
+    1145     2017193 :         else p->calculate();
+    1146             :         // This retrieves components called bias
+    1147     2017760 :         if(av) {
+    1148     1771724 :           bias+=av->getOutputQuantity("bias");
+    1149     1771724 :           work+=av->getOutputQuantity("work");
+    1150     1771724 :           av->setGradientsIfNeeded();
+    1151             :         }
+    1152             :         // This makes all values that depend on the (fixed) masses and charges constant
+    1153     2017760 :         if( firststep ) p->setupConstantValues( true );
+    1154     2017760 :         ActionWithVirtualAtom*avv=p->castToActionWithVirtualAtom();
+    1155     2017760 :         if(avv)avv->setGradientsIfNeeded();
+    1156     2017760 :       }
+    1157           0 :     } catch(...) {
+    1158           0 :       plumed_error_nested() << "An error happened while calculating " << p->getLabel();
+    1159           0 :     }
+    1160     2467328 :     iaction++;
+    1161             :   }
+    1162      254604 : }
+    1163             : 
+    1164           0 : void PlumedMain::justApply() {
+    1165           0 :   backwardPropagate();
+    1166           0 :   update();
+    1167           0 :   resetInputs();
+    1168           0 : }
+    1169             : 
+    1170      256128 : void PlumedMain::backwardPropagate() {
+    1171      256128 :   if(!active)return;
+    1172             :   int iaction=0;
+    1173             : // Stopwatch is stopped when sw goes out of scope
+    1174      254480 :   auto sw=stopwatch.startStop("5 Applying (backward loop)");
+    1175             : // apply them in reverse order
+    1176     2719802 :   for(auto pp=actionSet.rbegin(); pp!=actionSet.rend(); ++pp) {
+    1177             :     const auto & p(pp->get());
+    1178     2465322 :     if(p->isActive()) {
+    1179             : 
+    1180             : // Stopwatch is stopped when sw goes out of scope.
+    1181             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+    1182     2016096 :       Stopwatch::Handler sw;
+    1183     2016096 :       if(detailedTimers) {
+    1184        2481 :         auto actionNumberLabel=std::to_string(iaction);
+    1185        2481 :         const unsigned m=actionSet.size();
+    1186        7443 :         unsigned k=0; unsigned n=1; while(n<m) { n*=10; k++; }
+    1187        2481 :         auto spaces=std::string(k-actionNumberLabel.length(),' ');
+    1188        2481 :         sw=stopwatch.startStop("5A " + spaces + actionNumberLabel+" "+p->getLabel());
+    1189             :       }
+    1190             : 
+    1191     2016096 :       p->apply();
+    1192     2016096 :     }
+    1193     2465322 :     iaction++;
+    1194             :   }
+    1195             : 
+    1196             : // Stopwatch is stopped when sw goes out of scope.
+    1197             : // We explicitly declare a Stopwatch::Handler here to allow for conditional initialization.
+    1198      254480 :   Stopwatch::Handler sw1;
+    1199      254480 :   if(detailedTimers) sw1=stopwatch.startStop("5B Update forces");
+    1200      254480 : }
+    1201             : 
+    1202      254073 : void PlumedMain::update() {
+    1203      254073 :   if(!active)return;
+    1204             : 
+    1205             : // Stopwatch is stopped when sw goes out of scope
+    1206      252425 :   auto sw=stopwatch.startStop("6 Update");
+    1207             : 
+    1208             : // update step (for statistics, etc)
+    1209      252425 :   updateFlags.push(true);
+    1210     2694755 :   for(const auto & p : actionSet) {
+    1211     2442330 :     p->beforeUpdate();
+    1212     4437162 :     if(p->isActive() && p->checkUpdate() && updateFlagsTop()) p->update();
+    1213             :   }
+    1214      504854 :   while(!updateFlags.empty()) updateFlags.pop();
+    1215             :   if(!updateFlags.empty()) plumed_merror("non matching changes in the update flags");
+    1216             : // Check that no action has told the calculation to stop
+    1217      252425 :   if(stopNow) {
+    1218          65 :     if(stopFlag) stopFlag.set(int(1));
+    1219           0 :     else plumed_merror("your md code cannot handle plumed stop events - add a call to plumed.comm(stopFlag,stopCondition)");
+    1220             :   }
+    1221             : 
+    1222             : // flush by default every 10000 steps
+    1223             : // hopefully will not affect performance
+    1224             : // also if receive checkpointing signal
+    1225      252425 :   if(step%10000==0||doCheckPoint) {
+    1226         982 :     fflush();
+    1227         982 :     log.flush();
+    1228       23111 :     for(const auto & p : actionSet) p->fflush();
+    1229             :   }
+    1230      252425 : }
+    1231             : 
+    1232           4 : void PlumedMain::load(const std::string& fileName) {
+    1233           4 :   if(DLLoader::installed()) {
+    1234           4 :     std::string libName=fileName;
+    1235           4 :     size_t n=libName.find_last_of(".");
+    1236           5 :     std::string extension="";
+    1237           4 :     std::string base=libName;
+    1238           4 :     if(n!=std::string::npos && n<libName.length()-1)
+    1239           8 :       extension=libName.substr(n+1);
+    1240           4 :     if(n!=std::string::npos && n<libName.length())
+    1241           8 :       base=libName.substr(0,n);
+    1242           4 :     if(extension=="cpp") {
+    1243             : // full path command, including environment setup
+    1244             : // this will work even if plumed is not in the execution path or if it has been
+    1245             : // installed with a name different from "plumed"
+    1246           6 :       std::string cmd=config::getEnvCommand()+" \""+config::getPlumedRoot()+"\"/scripts/mklib.sh "+libName;
+    1247           3 :       log<<"Executing: "<<cmd;
+    1248           3 :       if(comm.Get_size()>0) log<<" (only on master node)";
+    1249           3 :       log<<"\n";
+    1250           3 :       if(comm.Get_rank()==0) {
+    1251           3 :         int ret=std::system(cmd.c_str());
+    1252           3 :         if(ret!=0)
+    1253           2 :           plumed_error() <<"An error happened while executing command "<<cmd<<"\n";
+    1254             :       }
+    1255           2 :       comm.Barrier();
+    1256           4 :       base="./"+base;
+    1257             :     }
+    1258           6 :     libName=base+"."+config::getSoExt();
+    1259           3 :     void *p=dlloader.load(libName);
+    1260           3 :     if(!p) {
+    1261           0 :       plumed_error()<<"I cannot load library " << fileName << " " << dlloader.error();
+    1262             :     }
+    1263           4 :     log<<"Loading shared library "<<libName.c_str()<<"\n";
+    1264           3 :     log<<"Here is the new list of available actions\n";
+    1265           3 :     log<<actionRegister();
+    1266             :   } else
+    1267           0 :     plumed_error()<<"While loading library "<< fileName << " loading was not enabled, please check if dlopen was found at configure time";
+    1268           3 : }
+    1269             : 
+    1270      256128 : void PlumedMain::resetInputs() {
+    1271      637511 :   for(const auto & ip : inputs) {
+    1272      381383 :     if( ip->isActive() && ip->hasBeenSet() ) ip->reset();
+    1273             :   }
+    1274      256128 : }
+    1275             : 
+    1276        2805 : double PlumedMain::getBias() const {
+    1277        2805 :   return bias;
+    1278             : }
+    1279             : 
+    1280         450 : double PlumedMain::getWork() const {
+    1281         450 :   return work;
+    1282             : }
+    1283             : 
+    1284          73 : FILE* PlumedMain::fopen(const char *path, const char *mode) {
+    1285          73 :   std::string mmode(mode);
+    1286          73 :   std::string ppath(path);
+    1287          73 :   std::string suffix(getSuffix());
+    1288          73 :   std::string ppathsuf=ppath+suffix;
+    1289          73 :   FILE*fp=std::fopen(const_cast<char*>(ppathsuf.c_str()),const_cast<char*>(mmode.c_str()));
+    1290          73 :   if(!fp) fp=std::fopen(const_cast<char*>(ppath.c_str()),const_cast<char*>(mmode.c_str()));
+    1291          73 :   plumed_massert(fp,"file " + ppath + " cannot be found");
+    1292          73 :   return fp;
+    1293             : }
+    1294             : 
+    1295          91 : int PlumedMain::fclose(FILE*fp) {
+    1296          91 :   return std::fclose(fp);
+    1297             : }
+    1298             : 
+    1299        3802 : std::string PlumedMain::cite(const std::string&item) {
+    1300        3802 :   return citations.cite(item);
+    1301             : }
+    1302             : 
+    1303        1543 : void PlumedMain::fflush() {
+    1304        4797 :   for(const auto  & p : files) {
+    1305        3254 :     p->flush();
+    1306             :   }
+    1307        1543 : }
+    1308             : 
+    1309        4534 : void PlumedMain::insertFile(FileBase&f) {
+    1310        4534 :   files.insert(&f);
+    1311        4534 : }
+    1312             : 
+    1313        4831 : void PlumedMain::eraseFile(FileBase&f) {
+    1314        4831 :   files.erase(&f);
+    1315        4831 : }
+    1316             : 
+    1317          65 : void PlumedMain::stop() {
+    1318          65 :   stopNow=true;
+    1319          65 : }
+    1320             : 
+    1321         817 : void PlumedMain::runJobsAtEndOfCalculation() {
+    1322       20736 :   for(const auto & p : actionSet) {
+    1323       19919 :     p->runFinalJobs();
+    1324             :   }
+    1325         817 : }
+    1326             : 
+    1327     8805358 : unsigned PlumedMain::increaseReferenceCounter() noexcept {
+    1328     8805358 :   return ++referenceCounter;
+    1329             : }
+    1330             : 
+    1331     8804439 : unsigned PlumedMain::decreaseReferenceCounter() noexcept {
+    1332     8804439 :   return --referenceCounter;
+    1333             : }
+    1334             : 
+    1335          42 : unsigned PlumedMain::useCountReferenceCounter() const noexcept {
+    1336          42 :   return referenceCounter;
+    1337             : }
+    1338             : 
+    1339          60 : bool PlumedMain::valueExists( const std::string& name ) const {
+    1340         240 :   for(const auto & p : inputs) {
+    1341         240 :     if( p->getLabel()==name ) return true;
+    1342             :   }
+    1343             :   return false;
+    1344             : }
+    1345             : 
+    1346      324438 : void PlumedMain::setInputValue( const std::string& name, const unsigned& start, const unsigned& stride, const TypesafePtr & val ) {
+    1347             :   bool found=false;
+    1348      884569 :   for(const auto & pp : inputs) {
+    1349      884569 :     if( pp->setValuePointer( name, val ) ) { pp->setStart(name, start); pp->setStride(name, stride); found=true; break; }
+    1350             :   }
+    1351           0 :   plumed_massert( found, "found no action to set named " + name );
+    1352      324435 : }
+    1353             : 
+    1354      213206 : void PlumedMain::setInputForce( const std::string& name, const TypesafePtr & val ) {
+    1355             :   bool found=false;
+    1356      564040 :   for(const auto & pp : inputs) {
+    1357      564040 :     if( pp->setForcePointer( name, val ) ) { found=true; break; }
+    1358             :   }
+    1359      213204 :   plumed_massert( found, "found no action to set named " + name );
+    1360      213204 : }
+    1361             : 
+    1362        1032 : void PlumedMain::setUnits( const bool& natural, const Units& u ) {
+    1363        1032 :   passtools->usingNaturalUnits = natural; passtools->units=u;
+    1364        1032 :   std::vector<ActionToPutData*> idata = actionSet.select<ActionToPutData*>();
+    1365        7758 :   for(const auto & ip : idata) ip->updateUnits( passtools.get() );
+    1366        1032 : }
+    1367             : 
+    1368      256099 : void PlumedMain::startStep() {
+    1369      637399 :   for(const auto & ip : inputs) ip->resetForStepStart();
+    1370      256099 : }
+    1371             : 
+    1372         114 : void PlumedMain::writeBinary(std::ostream&o)const {
+    1373         456 :   for(const auto & ip : inputs) ip->writeBinary(o);
+    1374         114 : }
+    1375             : 
+    1376         114 : void PlumedMain::readBinary(std::istream&i) {
+    1377         456 :   for(const auto & ip : inputs) ip->readBinary(i);
+    1378         114 : }
+    1379             : 
+    1380          40 : void PlumedMain::setEnergyValue( const std::string& name ) {
+    1381          40 :   name_of_energy = name;
+    1382          40 : }
+    1383             : 
+    1384        6651 : int PlumedMain::getRealPrecision() const {
+    1385        6651 :   return passtools->getRealPrecision();
+    1386             : }
+    1387             : 
+    1388        3124 : bool PlumedMain::usingNaturalUnits() const {
+    1389        3124 :   return passtools->usingNaturalUnits;
+    1390             : }
+    1391             : 
+    1392    14346306 : const Units& PlumedMain::getUnits() {
+    1393    14346306 :   return passtools->units;
+    1394             : }
+    1395             : 
+    1396        2343 : void PlumedMain::plumedQuantityToMD( const std::string& unit, const double& eng, const TypesafePtr & m) const {
+    1397        2343 :   passtools->double2MD( eng/passtools->getUnitConversion(unit),m );
+    1398        2343 : }
+    1399             : 
+    1400           0 : double PlumedMain::MDQuantityToPLUMED( const std::string& unit, const TypesafePtr & m) const {
+    1401           0 :   double x=passtools->MD2double(m);
+    1402           0 :   return x*passtools->getUnitConversion(unit);
+    1403             : }
+    1404             : 
+    1405             : #ifdef __PLUMED_HAS_PYTHON
+    1406             : // This is here to stop cppcheck throwing an error
+    1407             : #endif
+    1408             : 
+    1409             : #ifdef __PLUMED_HAS_DLADDR
+    1410             : // This is here to stop cppcheck throwing an error
+    1411             : #endif
+    1412             : 
+    1413             : }
+    1414             : 
+    1415             : //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.h.func-sort-c.html b/coverage/core/PlumedMain.h.func-sort-c.html new file mode 100644 index 000000000000..16c1facbf982 --- /dev/null +++ b/coverage/core/PlumedMain.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - core/PlumedMain.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMain.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:151788.2 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.h.func.html b/coverage/core/PlumedMain.h.func.html new file mode 100644 index 000000000000..f631987aae39 --- /dev/null +++ b/coverage/core/PlumedMain.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - core/PlumedMain.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMain.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:151788.2 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMain.h.gcov.html b/coverage/core/PlumedMain.h.gcov.html new file mode 100644 index 000000000000..91d70df6414f --- /dev/null +++ b/coverage/core/PlumedMain.h.gcov.html @@ -0,0 +1,654 @@ + + + + + + + + LCOV - plumed test coverage - core/PlumedMain.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMain.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:151788.2 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_PlumedMain_h
+      23             : #define __PLUMED_core_PlumedMain_h
+      24             : 
+      25             : #include "WithCmd.h"
+      26             : #include "tools/ForwardDecl.h"
+      27             : #include <cstdio>
+      28             : #include <string>
+      29             : #include <vector>
+      30             : #include <set>
+      31             : #include <stack>
+      32             : #include <memory>
+      33             : #include <map>
+      34             : #include <atomic>
+      35             : 
+      36             : // !!!!!!!!!!!!!!!!!!!!!!    DANGER   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!11
+      37             : // THE FOLLOWING ARE DEFINITIONS WHICH ARE NECESSARY FOR DYNAMIC LOADING OF THE PLUMED KERNEL:
+      38             : // This section should be consistent with the Plumed.h file.
+      39             : // Since the Plumed.h file may be included in host MD codes, **NEVER** MODIFY THE CODE DOWN HERE
+      40             : 
+      41             : /* Generic function pointer */
+      42             : typedef void (*plumed_function_pointer)(void);
+      43             : 
+      44             : /* Holder for function pointer */
+      45             : typedef struct {
+      46             :   plumed_function_pointer p;
+      47             : } plumed_function_holder;
+      48             : 
+      49             : // END OF DANGER
+      50             : ////////////////////////////////////////////////////////////
+      51             : 
+      52             : namespace PLMD {
+      53             : 
+      54             : 
+      55             : 
+      56             : class ActionAtomistic;
+      57             : class ActionPilot;
+      58             : class ActionForInterface;
+      59             : class Log;
+      60             : class Atoms;
+      61             : class ActionSet;
+      62             : class DLLoader;
+      63             : class Communicator;
+      64             : class Stopwatch;
+      65             : class Citations;
+      66             : class ExchangePatterns;
+      67             : class FileBase;
+      68             : class TypesafePtr;
+      69             : class IFile;
+      70             : class Units;
+      71             : class DataPassingTools;
+      72             : 
+      73             : /**
+      74             : Main plumed object.
+      75             : In MD engines this object is not manipulated directly but it is wrapped in
+      76             : plumed or PLMD::Plumed objects. Its main method is cmd(),
+      77             : which defines completely the external plumed interface.
+      78             : It does not contain any static data.
+      79             : */
+      80             : class PlumedMain:
+      81             :   public WithCmd
+      82             : {
+      83             : /// Pointers to files opened in actions associated to this object.
+      84             : /// Notice that with the current implementation this should be at the top of this
+      85             : /// structure. Indeed, this should be destroyed *after* all the actions allocated
+      86             : /// in this PlumedMain object have been destroyed.
+      87             :   std::set<FileBase*> files;
+      88             : /// Forward declaration.
+      89             :   ForwardDecl<Communicator> comm_fwd;
+      90             : public:
+      91             : /// Communicator for plumed.
+      92             : /// Includes all the processors used by plumed.
+      93             :   Communicator&comm=*comm_fwd;
+      94             : 
+      95             : private:
+      96             : /// Forward declaration.
+      97             :   ForwardDecl<Communicator> multi_sim_comm_fwd;
+      98             : public:
+      99             :   Communicator&multi_sim_comm=*multi_sim_comm_fwd;
+     100             : 
+     101             : private:
+     102             : /// Error handler.
+     103             : /// Pointer to a function that is called an exception thrown within
+     104             : /// the library is about to leave the library.
+     105             : /// Can be used to remap exceptions in case the plumed wrapper was compiled
+     106             : /// with a different version of the C++ standard library.
+     107             : /// Should only be called from \ref plumed_plumedmain_cmd().
+     108             :   typedef struct {
+     109             :     void* ptr;
+     110             :     void(*handler)(void* ptr,int code,const char*);
+     111             :   } plumed_error_handler;
+     112             : 
+     113             :   plumed_error_handler error_handler= {NULL,NULL};
+     114             : 
+     115             :   bool nestedExceptions=false;
+     116             : 
+     117             : /// Forward declaration.
+     118             :   ForwardDecl<DLLoader> dlloader_fwd;
+     119             :   DLLoader& dlloader=*dlloader_fwd;
+     120             : 
+     121             :   std::unique_ptr<WithCmd> cltool;
+     122             : 
+     123             :   std::unique_ptr<WithCmd> grex;
+     124             : /// Flag to avoid double initialization
+     125             :   bool  initialized;
+     126             : /// Name of MD engine
+     127             :   std::string MDEngine;
+     128             : 
+     129             : /// Forward declaration.
+     130             :   ForwardDecl<Log> log_fwd;
+     131             : /// Log stream
+     132             :   Log& log=*log_fwd;
+     133             : 
+     134             : /// Forward declaration.
+     135             : /// Should be placed after log since its constructor takes a log reference as an argument.
+     136             :   ForwardDecl<Stopwatch> stopwatch_fwd;
+     137             :   Stopwatch& stopwatch=*stopwatch_fwd;
+     138             : 
+     139             : /// Forward declaration.
+     140             :   ForwardDecl<Citations> citations_fwd;
+     141             : /// tools/Citations.holder
+     142             :   Citations& citations=*citations_fwd;
+     143             : 
+     144             : /// Present step number.
+     145             :   long long int step;
+     146             : 
+     147             : /// Condition for plumed to be active.
+     148             : /// At every step, PlumedMain is checking if there are Action's requiring some work.
+     149             : /// If at least one Action requires some work, this variable is set to true.
+     150             :   bool active;
+     151             : 
+     152             : /// Name of the input file
+     153             :   std::string plumedDat;
+     154             : 
+     155             : /// End of input file.
+     156             : /// Set to true to terminate reading
+     157             :   bool endPlumed;
+     158             : 
+     159             : /// Forward declaration.
+     160             :   ForwardDecl<ActionSet> actionSet_fwd;
+     161             : /// Set of actions found in plumed.dat file
+     162             :   ActionSet& actionSet=*actionSet_fwd;
+     163             : 
+     164             : /// These are tools to pass data to PLUMED
+     165             :   std::unique_ptr<DataPassingTools> passtools;
+     166             : 
+     167             : /// Vector of actions that are passed data from the MD code
+     168             :   std::vector<ActionForInterface*> inputs;
+     169             : 
+     170             : /// Set of Pilot actions.
+     171             : /// These are the action the, if they are Pilot::onStep(), can trigger execution
+     172             :   std::vector<ActionPilot*> pilots;
+     173             : 
+     174             : /// Suffix string for file opening, useful for multiple simulations in the same directory
+     175             :   std::string suffix;
+     176             : 
+     177             : /// The total bias (=total energy of the restraints)
+     178             :   double bias;
+     179             : 
+     180             : /// The total work.
+     181             : /// This computed by accumulating the change in external potentials.
+     182             :   double work;
+     183             : 
+     184             : /// Forward declaration.
+     185             :   ForwardDecl<ExchangePatterns> exchangePatterns_fwd;
+     186             : /// Class of possible exchange patterns, used for BIASEXCHANGE but also for future parallel tempering
+     187             :   ExchangePatterns& exchangePatterns=*exchangePatterns_fwd;
+     188             : 
+     189             : /// Set to true if on an exchange step
+     190             :   bool exchangeStep;
+     191             : 
+     192             : /// Flag for restart
+     193             :   bool restart;
+     194             : 
+     195             : /// Flag for checkpointig
+     196             :   bool doCheckPoint;
+     197             : 
+     198             : /// A string that holds the name of the action that gets the energy from the MD
+     199             : /// code.  Set empty if energy is not used.
+     200             :   std::string name_of_energy;
+     201             : 
+     202             : /// This sets up the values that are set from the MD code
+     203             :   void startStep();
+     204             : 
+     205             : /// This sets up the vector that contains the interface to the MD code
+     206             :   void setupInterfaceActions();
+     207             : private:
+     208             : /// Forward declaration.
+     209             :   ForwardDecl<TypesafePtr> stopFlag_fwd;
+     210             : public:
+     211             : /// Stuff to make plumed stop the MD code cleanly
+     212             :   TypesafePtr& stopFlag=*stopFlag_fwd;
+     213             :   bool stopNow;
+     214             : 
+     215             : /// Stack for update flags.
+     216             : /// Store information used in class \ref generic::UpdateIf
+     217             :   std::stack<bool> updateFlags;
+     218             : 
+     219             : public:
+     220             : /// This determines if the user has created a value to hold the quantity that is being passed
+     221             :   bool valueExists( const std::string& name ) const ;
+     222             : 
+     223             : /// This sets the the value with a particular name to the pointer to the data in the MD code
+     224             :   void setInputValue( const std::string& name, const unsigned& start, const unsigned& stride, const TypesafePtr & val );
+     225             : 
+     226             : /// This sets the the forces with a particular name to the pointer to the data in the MD code
+     227             :   void setInputForce( const std::string& name, const TypesafePtr & val );
+     228             : 
+     229             : /// This updates the units of the input quantities
+     230             :   void setUnits( const bool& natural, const Units& u );
+     231             : 
+     232             : /// Flag to switch off virial calculation (for debug and MD codes with no barostat)
+     233             :   bool novirial;
+     234             : 
+     235             : /// Flag to switch on detailed timers
+     236             :   bool detailedTimers;
+     237             : 
+     238             : /// GpuDevice Identifier
+     239             :   int gpuDeviceId;
+     240             : 
+     241             : /// Generic map string -> double
+     242             : /// intended to pass information across Actions
+     243             :   std::map<std::string,double> passMap;
+     244             : 
+     245             : /// Add a citation, returning a string containing the reference number, something like "[10]"
+     246             :   std::string cite(const std::string&);
+     247             : 
+     248             : /// Get number of threads that can be used by openmp
+     249             :   unsigned getNumThreads()const;
+     250             : 
+     251             : /// Get a reasonable number of threads so as to access to an array of size s located at x
+     252             :   template<typename T>
+     253             :   unsigned getGoodNumThreads(const T*x,unsigned s)const;
+     254             : 
+     255             : /// Get a reasonable number of threads so as to access to vector v;
+     256             :   template<typename T>
+     257             :   unsigned getGoodNumThreads(const std::vector<T> & v)const;
+     258             : 
+     259             : public:
+     260             :   PlumedMain();
+     261             : // this is to access to WithCmd versions of cmd (allowing overloading of a virtual method)
+     262             :   using WithCmd::cmd;
+     263             :   /**
+     264             :    cmd method, accessible with standard Plumed.h interface.
+     265             :    \param key The name of the command to be executed.
+     266             :    \param val The argument of the command to be executed.
+     267             :    It is called as plumed_cmd() or as PLMD::Plumed::cmd()
+     268             :    It is the interpreter for plumed commands. It basically contains the definition of the plumed interface.
+     269             :    If you want to add a new functionality to the interface between plumed
+     270             :    and an MD engine, this is the right place
+     271             :    Notice that this interface should always keep retro-compatibility
+     272             :   */
+     273             :   void cmd(std::string_view key,const TypesafePtr & val=nullptr) override;
+     274             :   ~PlumedMain();
+     275             :   /**
+     276             :     Read an input file.
+     277             :     \param str name of the file
+     278             :   */
+     279             :   void readInputFile(const std::string & str);
+     280             :   /**
+     281             :     Read an input file.
+     282             :     \param ifile
+     283             :   */
+     284             :   void readInputFile(IFile & ifile);
+     285             :   /**
+     286             :     Read an input string.
+     287             :     \param str name of the string
+     288             :   */
+     289             :   void readInputWords(const std::vector<std::string> &  str, const bool& before_init);
+     290             : 
+     291             :   /**
+     292             :     Read an input string.
+     293             :     \param str name of the string
+     294             :     At variance with readInputWords(), this is splitting the string into words
+     295             :   */
+     296             :   void readInputLine(const std::string & str, const bool& before_init=false);
+     297             : 
+     298             :   /**
+     299             :     Read an input buffer.
+     300             :     \param str name of the string
+     301             :     Same as readInputFile, but first write str on a temporary file and then read
+     302             :     that files. At variance with readInputLine, it can take care of comments and
+     303             :     continuation lines.
+     304             :   */
+     305             :   void readInputLines(const std::string & str);
+     306             : 
+     307             :   /**
+     308             :     Initialize the object.
+     309             :     Should be called once.
+     310             :   */
+     311             :   void init();
+     312             :   /**
+     313             :     Prepare the calculation.
+     314             :     Here it is checked which are the active Actions and communication of the relevant atoms is initiated.
+     315             :     Shortcut for prepareDependencies() + shareData()
+     316             :   */
+     317             :   void prepareCalc();
+     318             :   /**
+     319             :     Prepare the list of active Actions and needed atoms.
+     320             :     Scan the Actions to see which are active and which are not, so as to prepare a list of
+     321             :     the atoms needed at this step.
+     322             :   */
+     323             :   void prepareDependencies();
+     324             :   /**
+     325             :     Ensure that all the atoms are shared.
+     326             :     This is used in GREX to ensure that we transfer all the positions from the MD code to PLUMED.
+     327             :   */
+     328             :   void shareAll();
+     329             :   /**
+     330             :     Share the needed atoms.
+     331             :     In asynchronous implementations, this method sends the required atoms to all the plumed processes,
+     332             :     without waiting for the communication to complete.
+     333             :   */
+     334             :   void shareData();
+     335             :   /**
+     336             :     Perform the calculation.
+     337             :     Shortcut for waitData() + justCalculate() + justApply().
+     338             :     Equivalently: waitData() + justCalculate() + backwardPropagate() + update().
+     339             :   */
+     340             :   void performCalc();
+     341             :   /**
+     342             :     Perform the calculation without update()
+     343             :     Shortcut for: waitData() + justCalculate() + backwardPropagate()
+     344             :   */
+     345             :   void performCalcNoUpdate();
+     346             :   /**
+     347             :     Perform the calculation without backpropagation nor update()
+     348             :     Shortcut for: waitData() + justCalculate()
+     349             :   */
+     350             :   void performCalcNoForces();
+     351             :   /**
+     352             :     Complete PLUMED calculation.
+     353             :     Shortcut for prepareCalc() + performCalc()
+     354             :   */
+     355             :   void calc();
+     356             :   /**
+     357             :     Scatters the needed atoms.
+     358             :     In asynchronous implementations, this method waits for the communications started in shareData()
+     359             :     to be completed. Otherwise, just send around needed atoms.
+     360             :   */
+     361             :   void waitData();
+     362             :   /**
+     363             :     Perform the forward loop on active actions.
+     364             :   */
+     365             :   void justCalculate();
+     366             :   /**
+     367             :     Backward propagate and update.
+     368             :     Shortcut for backwardPropagate() + update()
+     369             :     I leave it here for backward compatibility
+     370             :   */
+     371             :   void justApply();
+     372             :   /**
+     373             :     Perform the backward loop on active actions.
+     374             :     Needed to apply the forces back.
+     375             :   */
+     376             :   void backwardPropagate();
+     377             :   /**
+     378             :     Call the update() method.
+     379             :   */
+     380             :   void update();
+     381             :   /**
+     382             :     If there are calculations that need to be done at the very end of the calculations this
+     383             :     makes sures they are done
+     384             :   */
+     385             :   /**
+     386             :     This function does clearInputForces for the list of atoms that have a force on them. This
+     387             :     is an optimisation to prevent calling std::fill over a large array
+     388             :   */
+     389             :   void resetInputs();
+     390             :   void runJobsAtEndOfCalculation();
+     391             : /// Reference to the list of Action's
+     392             :   const ActionSet & getActionSet()const;
+     393             : /// Referenge to the log stream
+     394             :   Log & getLog();
+     395             : /// Return the number of the step
+     396     4914546 :   long long int getStep()const {return step;}
+     397             : /// Stop the run
+     398             :   void exit(int c=0);
+     399             : /// Load a shared library
+     400             :   void load(const std::string&);
+     401             : /// Get the suffix string
+     402             :   const std::string & getSuffix()const;
+     403             : /// Set the suffix string
+     404             :   void setSuffix(const std::string&);
+     405             : /// get the value of the bias
+     406             :   double getBias()const;
+     407             : /// get the value of the work
+     408             :   double getWork()const;
+     409             : /// Opens a file.
+     410             : /// Similar to plain fopen, but, if it finds an error in opening the file, it also tries with
+     411             : /// path+suffix.  This trick is useful for multiple replica simulations.
+     412             :   FILE* fopen(const char *path, const char *mode);
+     413             : /// Closes a file opened with PlumedMain::fopen()
+     414             :   int fclose(FILE*fp);
+     415             : /// Insert a file
+     416             :   void insertFile(FileBase&);
+     417             : /// Erase a file
+     418             :   void eraseFile(FileBase&);
+     419             : /// Flush all files
+     420             :   void fflush();
+     421             : /// Check if restarting
+     422             :   bool getRestart()const;
+     423             : /// Set restart flag
+     424          56 :   void setRestart(bool f) {restart=f;}
+     425             : /// Check if checkpointing
+     426             :   bool getCPT()const;
+     427             : /// Set exchangeStep flag
+     428             :   void setExchangeStep(bool f);
+     429             : /// Get exchangeStep flag
+     430             :   bool getExchangeStep()const;
+     431             : /// Stop the calculation cleanly (both the MD code and plumed)
+     432             :   void stop();
+     433             : /// Enforce active flag.
+     434             : /// This is a (bit dirty) hack to solve a bug. When there is no active ActionPilot,
+     435             : /// several shortcuts are used. However, these shortcuts can block GREX module.
+     436             : /// This function allows to enforce active plumed when doing exchanges,
+     437             : /// thus fixing the bug.
+     438             :   void resetActive(bool active);
+     439             : 
+     440             : /// Access to exchange patterns
+     441           0 :   ExchangePatterns& getExchangePatterns() {return exchangePatterns;}
+     442             : 
+     443             : /// Push a state to update flags
+     444             :   void updateFlagsPush(bool);
+     445             : /// Pop a state from update flags
+     446             :   void updateFlagsPop();
+     447             : /// Get top of update flags
+     448             :   bool updateFlagsTop();
+     449             : /// Set end of input file
+     450             :   void setEndPlumed();
+     451             : /// Get the value of the end plumed flag
+     452             :   bool getEndPlumed() const ;
+     453             : /// Get the value of the gpuDeviceId
+     454             :   int getGpuDeviceId() const ;
+     455             : /// Call error handler.
+     456             : /// Should only be called from \ref plumed_plumedmain_cmd().
+     457             : /// If the error handler was not set, returns false.
+     458             :   bool callErrorHandler(int code,const char* msg)const;
+     459             : private:
+     460             :   std::atomic<unsigned> referenceCounter{};
+     461             : public:
+     462             : /// Atomically increase reference counter and return the new value
+     463             :   unsigned increaseReferenceCounter() noexcept;
+     464             : /// Atomically decrease reference counter and return the new value
+     465             :   unsigned decreaseReferenceCounter() noexcept;
+     466             : /// Report the reference counter
+     467             :   unsigned useCountReferenceCounter() const noexcept;
+     468             :   void enableNestedExceptions();
+     469             :   bool getNestedExceptions()const {
+     470         122 :     return nestedExceptions;
+     471             :   }
+     472             : /// Check if there is active input in the action set
+     473             :   bool inputsAreActive() const ;
+     474             : /// Transfer information from input MD code
+     475             :   void writeBinary(std::ostream&)const;
+     476             :   void readBinary(std::istream&);
+     477             : /// Used to set the name of the action that holds the energy
+     478             :   void setEnergyValue( const std::string& name );
+     479             : /// Get the real preicision
+     480             :   int getRealPrecision() const;
+     481             : /// Are we using natural units
+     482             :   bool usingNaturalUnits() const ;
+     483             : /// Get the units that are being used
+     484             :   const Units& getUnits();
+     485             : /// Take an energy that is calculated by PLUMED and pass it to a typesafe pointer
+     486             : /// that the MD code can access.
+     487             :   void plumedQuantityToMD( const std::string& unit, const double& eng, const TypesafePtr & m) const ;
+     488             : /// Take a typesafe pointer from the MD code and convert it to a double
+     489             :   double MDQuantityToPLUMED( const std::string& unit, const TypesafePtr & m) const ;
+     490             : };
+     491             : 
+     492             : /////
+     493             : // FAST INLINE METHODS:
+     494             : 
+     495             : inline
+     496             : const ActionSet & PlumedMain::getActionSet()const {
+     497     1173490 :   return actionSet;
+     498             : }
+     499             : 
+     500             : inline
+     501             : const std::string & PlumedMain::getSuffix()const {
+     502        4855 :   return suffix;
+     503             : }
+     504             : 
+     505             : inline
+     506             : void PlumedMain::setSuffix(const std::string&s) {
+     507         411 :   suffix=s;
+     508         411 : }
+     509             : 
+     510             : inline
+     511             : bool PlumedMain::getRestart()const {
+     512       21909 :   return restart;
+     513             : }
+     514             : 
+     515             : inline
+     516             : bool PlumedMain::getCPT()const {
+     517       21853 :   return doCheckPoint;
+     518             : }
+     519             : 
+     520             : inline
+     521             : void PlumedMain::setExchangeStep(bool s) {
+     522         228 :   exchangeStep=s;
+     523             : }
+     524             : 
+     525             : inline
+     526             : bool PlumedMain::getExchangeStep()const {
+     527       28109 :   return exchangeStep;
+     528             : }
+     529             : 
+     530             : inline
+     531             : void PlumedMain::resetActive(bool active) {
+     532         114 :   this->active=active;
+     533             : }
+     534             : 
+     535             : inline
+     536             : void PlumedMain::updateFlagsPush(bool on) {
+     537             :   updateFlags.push(on);
+     538             : }
+     539             : 
+     540             : inline
+     541             : void PlumedMain::updateFlagsPop() {
+     542             :   updateFlags.pop();
+     543          12 : }
+     544             : 
+     545             : inline
+     546             : bool PlumedMain::updateFlagsTop() {
+     547     1994839 :   return updateFlags.top();
+     548             : }
+     549             : 
+     550             : inline
+     551             : void PlumedMain::setEndPlumed() {
+     552         268 :   endPlumed=true;
+     553             : }
+     554             : 
+     555             : inline
+     556             : bool PlumedMain::getEndPlumed() const {
+     557           0 :   return endPlumed;
+     558             : }
+     559             : 
+     560             : inline
+     561             : int PlumedMain::getGpuDeviceId() const {
+     562             :   return gpuDeviceId;
+     563             : }
+     564             : 
+     565             : inline
+     566             : bool PlumedMain::callErrorHandler(int code,const char* msg)const {
+     567             :   if(error_handler.handler) {
+     568             :     error_handler.handler(error_handler.ptr,code,msg);
+     569             :     return true;
+     570             :   } else return false;
+     571             : }
+     572             : 
+     573             : 
+     574             : }
+     575             : 
+     576             : #endif
+     577             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMainInitializer.cpp.func-sort-c.html b/coverage/core/PlumedMainInitializer.cpp.func-sort-c.html new file mode 100644 index 000000000000..4233773a1335 --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - core/PlumedMainInitializer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMainInitializer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22326982.9 %
Date:2024-02-22 21:58:45Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZL13typesafeDebugPKc16plumed_safeptr_x0
plumed_plumedmain_cmd_nothrow0
plumed_plumedmain_use_count42
_ZL16translate_nested24plumed_nothrow_handler_x68
plumed_plumedmain_cmd_safe95
_ZL17translate_current24plumed_nothrow_handler_xPPvPKc134
plumed_plumedmain_cmd357
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerC2Ev4187
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerD2Ev4187
plumed_plumedmain_cmd_safe_nothrow14847
_ZL19getenvTypesafeDebugv14942
plumed_plumedmain_create804364
plumed_plumedmain_finalize804364
plumed_symbol_table_init808522
plumed_plumedmain_create_reference8000075
plumed_plumedmain_delete_reference8804439
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMainInitializer.cpp.func.html b/coverage/core/PlumedMainInitializer.cpp.func.html new file mode 100644 index 000000000000..c55300aa5f6f --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - core/PlumedMainInitializer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMainInitializer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22326982.9 %
Date:2024-02-22 21:58:45Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZL13typesafeDebugPKc16plumed_safeptr_x0
_ZL16translate_nested24plumed_nothrow_handler_x68
_ZL17translate_current24plumed_nothrow_handler_xPPvPKc134
_ZL19getenvTypesafeDebugv14942
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerC2Ev4187
_ZN4PLMD12_GLOBAL__N_121PlumedMainInitializerD2Ev4187
plumed_plumedmain_cmd357
plumed_plumedmain_cmd_nothrow0
plumed_plumedmain_cmd_safe95
plumed_plumedmain_cmd_safe_nothrow14847
plumed_plumedmain_create804364
plumed_plumedmain_create_reference8000075
plumed_plumedmain_delete_reference8804439
plumed_plumedmain_finalize804364
plumed_plumedmain_use_count42
plumed_symbol_table_init808522
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/PlumedMainInitializer.cpp.gcov.html b/coverage/core/PlumedMainInitializer.cpp.gcov.html new file mode 100644 index 000000000000..258e071ecdc9 --- /dev/null +++ b/coverage/core/PlumedMainInitializer.cpp.gcov.html @@ -0,0 +1,567 @@ + + + + + + + + LCOV - plumed test coverage - core/PlumedMainInitializer.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - PlumedMainInitializer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22326982.9 %
Date:2024-02-22 21:58:45Functions:141687.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PlumedMainInitializer.h"
+      23             : #include "PlumedMain.h"
+      24             : #include "tools/Exception.h"
+      25             : #include "lepton/Exception.h"
+      26             : #include <cstdlib>
+      27             : #include <cstring>
+      28             : #include <iostream>
+      29             : #if defined __PLUMED_HAS_DLOPEN
+      30             : #include <dlfcn.h>
+      31             : #endif
+      32             : #include <exception>
+      33             : #include <stdexcept>
+      34             : #include <ios>
+      35             : #include <new>
+      36             : #include <typeinfo>
+      37             : #include <system_error>
+      38             : #include <future>
+      39             : #include <memory>
+      40             : #include <functional>
+      41             : #include <regex>
+      42             : #include <any>
+      43             : #include <variant>
+      44             : #include <optional>
+      45             : #include <filesystem>
+      46             : #include "tools/TypesafePtr.h"
+      47             : #include "tools/Log.h"
+      48             : #include "tools/Tools.h"
+      49             : 
+      50             : 
+      51       14942 : static bool getenvTypesafeDebug() noexcept {
+      52       14942 :   static const auto* res=std::getenv("PLUMED_TYPESAFE_DEBUG");
+      53       14942 :   return res;
+      54             : }
+      55             : 
+      56             : // cppcheck-suppress passedByValue
+      57           0 : static void typesafeDebug(const char*key,plumed_safeptr_x safe) noexcept {
+      58           0 :   std::fprintf(stderr,"+++ PLUMED_TYPESAFE_DEBUG %s %p %zu",key,safe.ptr,safe.nelem);
+      59           0 :   const size_t* shape=safe.shape;
+      60           0 :   if(shape) {
+      61           0 :     std::fprintf(stderr," (");
+      62           0 :     while(*shape!=0) {
+      63           0 :       std::fprintf(stderr," %zu",*shape);
+      64           0 :       shape++;
+      65             :     }
+      66           0 :     std::fprintf(stderr," )");
+      67             :   }
+      68           0 :   std::fprintf(stderr," %zx %p\n",safe.flags,safe.opt);
+      69           0 : }
+      70             : 
+      71             : // create should never throw
+      72             : // in case of a problem, it logs the error and return a null pointer
+      73             : // when loaded by an interface >=2.5, this will result in a non valid plumed object.
+      74             : // earlier interfaces will just give a segfault or a failed assertion.
+      75      804364 : extern "C" void*plumed_plumedmain_create() {
+      76             :   try {
+      77      804364 :     return new PLMD::PlumedMain;
+      78           0 :   } catch(const std::exception & e) {
+      79           0 :     std::cerr<<"+++ an error happened while creating a plumed object\n";
+      80           0 :     std::cerr<<e.what()<<std::endl;
+      81             :     return nullptr;
+      82           0 :   } catch(...) {
+      83           0 :     std::cerr<<"+++ an unknown error happened while creating a plumed object"<<std::endl;
+      84             :     return nullptr;
+      85           0 :   }
+      86             : }
+      87             : 
+      88     8000075 : extern "C" unsigned plumed_plumedmain_create_reference(void*plumed) {
+      89     8000075 :   plumed_massert(plumed,"trying to create a reference to a plumed object which is not initialized");
+      90             :   auto p=static_cast<PLMD::PlumedMain*>(plumed);
+      91     8000075 :   return p->increaseReferenceCounter();
+      92             : }
+      93             : 
+      94     8804439 : extern "C" unsigned plumed_plumedmain_delete_reference(void*plumed) {
+      95     8804439 :   plumed_massert(plumed,"trying to delete a reference to a plumed object which is not initialized");
+      96             :   auto p=static_cast<PLMD::PlumedMain*>(plumed);
+      97     8804439 :   return p->decreaseReferenceCounter();
+      98             : }
+      99             : 
+     100          42 : extern "C" unsigned plumed_plumedmain_use_count(void*plumed) {
+     101          42 :   plumed_massert(plumed,"trying to delete a reference to a plumed object which is not initialized");
+     102             :   auto p=static_cast<PLMD::PlumedMain*>(plumed);
+     103          42 :   return p->useCountReferenceCounter();
+     104             : }
+     105             : 
+     106         357 : extern "C" void plumed_plumedmain_cmd(void*plumed,const char*key,const void*val) {
+     107         357 :   plumed_massert(plumed,"trying to use a plumed object which is not initialized");
+     108             :   auto p=static_cast<PLMD::PlumedMain*>(plumed);
+     109         357 :   p->cmd(key,PLMD::TypesafePtr::unchecked(val));
+     110         357 : }
+     111             : 
+     112             : extern "C" {
+     113          95 :   static void plumed_plumedmain_cmd_safe(void*plumed,const char*key,plumed_safeptr_x safe) {
+     114          95 :     plumed_massert(plumed,"trying to use a plumed object which is not initialized");
+     115             :     auto p=static_cast<PLMD::PlumedMain*>(plumed);
+     116          95 :     if(getenvTypesafeDebug()) typesafeDebug(key,safe);
+     117          95 :     p->cmd(key,PLMD::TypesafePtr::fromSafePtr(&safe));
+     118          95 :   }
+     119             : }
+     120             : 
+     121             : /// Internal tool
+     122             : /// Throws the currently managed exception and call the nothrow handler.
+     123             : /// If nested is not null, it is passed and then gets populated with a pointer that should
+     124             : /// be called on the nested exception
+     125             : /// If msg is not null, it overrides the message. Can be used to build a concatenated message.
+     126         134 : static void translate_current(plumed_nothrow_handler_x nothrow,void**nested=nullptr,const char*msg=nullptr) {
+     127         134 :   const void* opt[11]= {"n",nested,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr};
+     128             :   try {
+     129             :     // this function needs to be called while catching an exception
+     130             :     // cppcheck-suppress rethrowNoCurrentException
+     131         134 :     throw;
+     132         134 :   } catch(const PLMD::ExceptionTypeError & e) {
+     133           8 :     if(!msg) msg=e.what();
+     134           8 :     nothrow.handler(nothrow.ptr,20300,msg,opt);
+     135          63 :   } catch(const PLMD::ExceptionError & e) {
+     136          55 :     if(!msg) msg=e.what();
+     137          55 :     nothrow.handler(nothrow.ptr,20200,msg,opt);
+     138          56 :   } catch(const PLMD::ExceptionDebug & e) {
+     139           1 :     if(!msg) msg=e.what();
+     140           1 :     nothrow.handler(nothrow.ptr,20100,msg,opt);
+     141          22 :   } catch(const PLMD::Exception & e) {
+     142          21 :     if(!msg) msg=e.what();
+     143          21 :     nothrow.handler(nothrow.ptr,20000,msg,opt);
+     144          22 :   } catch(const PLMD::lepton::Exception & e) {
+     145           1 :     if(!msg) msg=e.what();
+     146           1 :     nothrow.handler(nothrow.ptr,19900,msg,opt);
+     147             :     // 11000 to 12000 are "bad exceptions". message will be copied without new allocations
+     148           2 :   } catch(const std::bad_variant_access & e) {
+     149           1 :     if(!msg) msg=e.what();
+     150           1 :     nothrow.handler(nothrow.ptr,11700,msg,opt);
+     151           2 :   } catch(const std::bad_optional_access & e) {
+     152           1 :     if(!msg) msg=e.what();
+     153           1 :     nothrow.handler(nothrow.ptr,11600,msg,opt);
+     154           2 :   } catch(const std::bad_exception & e) {
+     155           1 :     if(!msg) msg=e.what();
+     156           1 :     nothrow.handler(nothrow.ptr,11500,msg,opt);
+     157           2 :   } catch(const std::bad_array_new_length & e) {
+     158           1 :     if(!msg) msg=e.what();
+     159           1 :     nothrow.handler(nothrow.ptr,11410,msg,opt);
+     160           4 :   } catch(const std::bad_alloc & e) {
+     161           3 :     if(!msg) msg=e.what();
+     162           3 :     nothrow.handler(nothrow.ptr,11400,msg,opt);
+     163           4 :   } catch(const std::bad_function_call & e) {
+     164           1 :     if(!msg) msg=e.what();
+     165           1 :     nothrow.handler(nothrow.ptr,11300,msg,opt);
+     166           2 :   } catch(const std::bad_weak_ptr & e) {
+     167           1 :     if(!msg) msg=e.what();
+     168           1 :     nothrow.handler(nothrow.ptr,11200,msg,opt);
+     169           2 :   } catch(const std::bad_any_cast & e) {
+     170           1 :     if(!msg) msg=e.what();
+     171           1 :     nothrow.handler(nothrow.ptr,11150,msg,opt);
+     172           2 :   } catch(const std::bad_cast & e) {
+     173           1 :     if(!msg) msg=e.what();
+     174           1 :     nothrow.handler(nothrow.ptr,11100,msg,opt);
+     175           2 :   } catch(const std::bad_typeid & e) {
+     176           1 :     if(!msg) msg=e.what();
+     177           1 :     nothrow.handler(nothrow.ptr,11000,msg,opt);
+     178          14 :   } catch(const std::regex_error & e) {
+     179          13 :     if(!msg) msg=e.what();
+     180          13 :     if(e.code()==std::regex_constants::error_collate) nothrow.handler(nothrow.ptr,10240,msg,opt);
+     181           1 :     else if(e.code()==std::regex_constants::error_ctype) nothrow.handler(nothrow.ptr,10241,msg,opt);
+     182           1 :     else if(e.code()==std::regex_constants::error_escape) nothrow.handler(nothrow.ptr,10242,msg,opt);
+     183           1 :     else if(e.code()==std::regex_constants::error_backref) nothrow.handler(nothrow.ptr,10243,msg,opt);
+     184           1 :     else if(e.code()==std::regex_constants::error_brack) nothrow.handler(nothrow.ptr,10244,msg,opt);
+     185           1 :     else if(e.code()==std::regex_constants::error_paren) nothrow.handler(nothrow.ptr,10245,msg,opt);
+     186           1 :     else if(e.code()==std::regex_constants::error_brace) nothrow.handler(nothrow.ptr,10246,msg,opt);
+     187           1 :     else if(e.code()==std::regex_constants::error_badbrace) nothrow.handler(nothrow.ptr,10247,msg,opt);
+     188           1 :     else if(e.code()==std::regex_constants::error_range) nothrow.handler(nothrow.ptr,10248,msg,opt);
+     189           1 :     else if(e.code()==std::regex_constants::error_space) nothrow.handler(nothrow.ptr,10249,msg,opt);
+     190           1 :     else if(e.code()==std::regex_constants::error_badrepeat) nothrow.handler(nothrow.ptr,10250,msg,opt);
+     191           1 :     else if(e.code()==std::regex_constants::error_complexity) nothrow.handler(nothrow.ptr,10251,msg,opt);
+     192           1 :     else if(e.code()==std::regex_constants::error_stack) nothrow.handler(nothrow.ptr,10252,msg,opt);
+     193             :     // fallback to generic runtime_error
+     194           0 :     else nothrow.handler(nothrow.ptr,10200,msg,opt);
+     195          16 :   } catch(const std::filesystem::filesystem_error & e) {
+     196           3 :     if(!msg) msg=e.what();
+     197           3 :     int value=e.code().value();
+     198             : 
+     199           3 :     opt[2]="c"; // "c" passes the error code.
+     200           3 :     opt[3]=&value;
+     201             : 
+     202           3 :     opt[4]="C"; // "C" passes the error category
+     203           3 :     int generic_category=1;
+     204           3 :     int system_category=2;
+     205           3 :     int iostream_category=3;
+     206           3 :     int future_category=4;
+     207           3 :     if(e.code().category()==std::generic_category()) opt[5]=&generic_category;
+     208           0 :     else if(e.code().category()==std::system_category()) opt[5]=&system_category;
+     209           0 :     else if(e.code().category()==std::iostream_category()) opt[5]=&iostream_category;
+     210           0 :     else if(e.code().category()==std::future_category()) opt[5]=&future_category;
+     211           0 :     else opt[5]=nullptr;
+     212             : 
+     213             :     // local class, just needed to propely pass path information
+     214             :     // path is stored as a span of bytes.
+     215             :     // in theory, could be wchar type (on Windows, not tested),
+     216             :     // so we explicitly store the number of bytes
+     217             :     struct Path {
+     218             :       std::size_t numbytes=0;
+     219             :       const void* ptr=nullptr;
+     220             :       Path(const std::filesystem::path & path):
+     221             :         numbytes(sizeof(std::filesystem::path::value_type)*path.native().length()),
+     222             :         ptr(path.c_str())
+     223             :       {}
+     224             :       Path() = default;
+     225             :     };
+     226             : 
+     227           3 :     opt[6]="p"; // path1
+     228           3 :     Path path1; // declared here since it should survive till the end of this function
+     229           3 :     if(!e.path1().empty()) {
+     230           2 :       path1=Path(e.path1());
+     231           2 :       opt[7]=&path1;
+     232             :     }
+     233             : 
+     234           3 :     opt[8]="q"; // path2
+     235           3 :     Path path2; // declared here since it should survive till the end of this function
+     236           3 :     if(!e.path2().empty()) {
+     237           1 :       path2=Path(e.path2());
+     238           1 :       opt[9]=&path2;
+     239             :     }
+     240             : 
+     241           3 :     nothrow.handler(nothrow.ptr,10229,msg,opt);
+     242           4 :   } catch(const std::ios_base::failure & e) {
+     243           1 :     if(!msg) msg=e.what();
+     244           1 :     int value=e.code().value();
+     245           1 :     opt[2]="c"; // "c" passes the error code.
+     246           1 :     opt[3]=&value;
+     247           1 :     if(e.code().category()==std::generic_category()) nothrow.handler(nothrow.ptr,10230,msg,opt);
+     248           1 :     else if(e.code().category()==std::system_category()) nothrow.handler(nothrow.ptr,10231,msg,opt);
+     249           1 :     else if(e.code().category()==std::iostream_category()) nothrow.handler(nothrow.ptr,10232,msg,opt);
+     250           0 :     else if(e.code().category()==std::future_category()) nothrow.handler(nothrow.ptr,10233,msg,opt);
+     251             :     else
+     252             :       // 10239 represents std::ios_base::failure with default constructur
+     253           0 :       nothrow.handler(nothrow.ptr,10239,msg,opt);
+     254           5 :   } catch(const std::system_error & e) {
+     255           4 :     if(!msg) msg=e.what();
+     256           4 :     int value=e.code().value();
+     257           4 :     opt[2]="c"; // "c" passes the error code.
+     258           4 :     opt[3]=&value;
+     259           4 :     if(e.code().category()==std::generic_category()) nothrow.handler(nothrow.ptr,10220,msg,opt);
+     260           3 :     else if(e.code().category()==std::system_category()) nothrow.handler(nothrow.ptr,10221,msg,opt);
+     261           2 :     else if(e.code().category()==std::iostream_category()) nothrow.handler(nothrow.ptr,10222,msg,opt);
+     262           1 :     else if(e.code().category()==std::future_category()) nothrow.handler(nothrow.ptr,10223,msg,opt);
+     263             :     // fallback to generic runtime_error
+     264           0 :     else nothrow.handler(nothrow.ptr,10200,msg,opt);
+     265           5 :   } catch(const std::underflow_error &e) {
+     266           1 :     if(!msg) msg=e.what();
+     267           1 :     nothrow.handler(nothrow.ptr,10215,msg,opt);
+     268           2 :   } catch(const std::overflow_error &e) {
+     269           1 :     if(!msg) msg=e.what();
+     270           1 :     nothrow.handler(nothrow.ptr,10210,msg,opt);
+     271           2 :   } catch(const std::range_error &e) {
+     272           1 :     if(!msg) msg=e.what();
+     273           1 :     nothrow.handler(nothrow.ptr,10205,msg,opt);
+     274           2 :   } catch(const std::runtime_error & e) {
+     275           1 :     if(!msg) msg=e.what();
+     276           1 :     nothrow.handler(nothrow.ptr,10200,msg,opt);
+     277           5 :   } catch(const std::future_error & e) {
+     278           4 :     if(!msg) msg=e.what();
+     279           1 :     if(e.code()==std::make_error_code(std::future_errc::broken_promise)) nothrow.handler(nothrow.ptr,10125,msg,opt);
+     280           1 :     else if(e.code()==std::make_error_code(std::future_errc::future_already_retrieved)) nothrow.handler(nothrow.ptr,10126,msg,opt);
+     281           1 :     else if(e.code()==std::make_error_code(std::future_errc::promise_already_satisfied)) nothrow.handler(nothrow.ptr,10127,msg,opt);
+     282           1 :     else if(e.code()==std::make_error_code(std::future_errc::no_state)) nothrow.handler(nothrow.ptr,10128,msg,opt);
+     283             :     // fallback to generic logic_error
+     284           0 :     else nothrow.handler(nothrow.ptr,10100,msg,opt);
+     285           5 :   } catch(const std::out_of_range & e) {
+     286           1 :     if(!msg) msg=e.what();
+     287           1 :     nothrow.handler(nothrow.ptr,10120,msg,opt);
+     288           2 :   } catch(const std::length_error & e) {
+     289           1 :     if(!msg) msg=e.what();
+     290           1 :     nothrow.handler(nothrow.ptr,10115,msg,opt);
+     291           2 :   } catch(const std::domain_error & e) {
+     292           1 :     if(!msg) msg=e.what();
+     293           1 :     nothrow.handler(nothrow.ptr,10110,msg,opt);
+     294           2 :   } catch(const std::invalid_argument & e) {
+     295           1 :     if(!msg) msg=e.what();
+     296           1 :     nothrow.handler(nothrow.ptr,10105,msg,opt);
+     297           2 :   } catch(const std::logic_error & e) {
+     298           1 :     if(!msg) msg=e.what();
+     299           1 :     nothrow.handler(nothrow.ptr,10100,msg,opt);
+     300             :     // generic exception. message will be copied without new allocations
+     301             :     // reports all non caught exceptions that are derived from std::exception
+     302             :     // for instance, boost exceptions would end up here
+     303           1 :   } catch(const std::exception & e) {
+     304           0 :     if(!msg) msg=e.what();
+     305           0 :     nothrow.handler(nothrow.ptr,10000,msg,opt);
+     306           1 :   } catch(const char* m) {
+     307           1 :     if(!msg) msg=m;
+     308           1 :     nothrow.handler(nothrow.ptr,10000,msg,opt);
+     309           1 :   } catch(const std::string & s) {
+     310           0 :     if(!msg) msg=s.c_str();
+     311           0 :     nothrow.handler(nothrow.ptr,10000,msg,opt);
+     312           1 :   } catch (...) {
+     313             :     // if exception cannot be translated, we add a bad_exception to the stack
+     314           1 :     nothrow.handler(nothrow.ptr,11500,"plumed could not translate exception",opt);
+     315           1 :   }
+     316         134 : }
+     317             : 
+     318          68 : static void translate_nested(plumed_nothrow_handler_x nothrow) {
+     319             :   try {
+     320          68 :     throw;
+     321          68 :   } catch (const std::nested_exception & e) {
+     322             : // If this exception has a nested one:
+     323          12 :     auto nothrow_nested=nothrow;
+     324          12 :     nothrow_nested.ptr=nullptr;
+     325             : // translate the current exception asking the wrapper to allocate a new exception
+     326          12 :     translate_current(nothrow,&nothrow_nested.ptr);
+     327             : // if the wrapper cannot allocate the exception, this will be a nullptr
+     328          12 :     if(nothrow_nested.ptr) {
+     329             :       try {
+     330             : // transfer control to the nested exception
+     331          12 :         e.rethrow_nested();
+     332          12 :       } catch (...) {
+     333             : // recursively translate it
+     334          12 :         translate_nested(nothrow_nested);
+     335          12 :       }
+     336             :     }
+     337          68 :   } catch (...) {
+     338             : // otherwise, just translate the current exception
+     339          56 :     translate_current(nothrow);
+     340          56 :   }
+     341          68 : }
+     342             : 
+     343             : extern "C" {
+     344       14847 :   static void plumed_plumedmain_cmd_safe_nothrow(void*plumed,const char*key,plumed_safeptr_x safe,plumed_nothrow_handler_x nothrow) {
+     345             : // This is a workaround for a suboptimal choice in PLUMED <2.8
+     346             : // In particular, the only way to bypass the exception handling process was to call the plumed_plumedmain_cmd_safe
+     347             : // function directly.
+     348             : // With this modification, it is possible to just call the plumed_plumedmain_cmd_safe_nothrow function
+     349             : // passing a null error handler.
+     350       14847 :     if(!nothrow.handler) {
+     351           0 :       plumed_plumedmain_cmd_safe(plumed,key,safe);
+     352           0 :       return;
+     353             :     }
+     354             :     auto p=static_cast<PLMD::PlumedMain*>(plumed);
+     355             : // At library boundaries we translate exceptions to error codes.
+     356             : // This allows an exception to be catched also if the MD code
+     357             : // was linked against a different C++ library
+     358             :     try {
+     359       14847 :       plumed_massert(plumed,"trying to use a plumed object which is not initialized");
+     360       14847 :       if(getenvTypesafeDebug()) typesafeDebug(key,safe);
+     361       14847 :       p->cmd(key,PLMD::TypesafePtr::fromSafePtr(&safe));
+     362         122 :     } catch(...) {
+     363         122 :       if(p->getNestedExceptions()) {
+     364          56 :         translate_nested(nothrow);
+     365             :       } else {
+     366             : // In this case, we just consider the latest thrown exception and
+     367             : // supplement it with a concatenated message so as not to
+     368             : // loose information.
+     369          66 :         auto msg=PLMD::Tools::concatenateExceptionMessages();
+     370          66 :         translate_current(nothrow,nullptr,msg.c_str());
+     371             :       }
+     372         122 :     }
+     373             :   }
+     374             : }
+     375             : 
+     376             : extern "C" {
+     377           0 :   static void plumed_plumedmain_cmd_nothrow(void*plumed,const char*key,const void*val,plumed_nothrow_handler_x nothrow) {
+     378             :     plumed_safeptr_x safe;
+     379           0 :     plumed_assert(nothrow.handler) << "Accepting a null pointer here would make the calling code non compatible with plumed 2.5 to 2.7";
+     380           0 :     safe.ptr=val;
+     381           0 :     safe.nelem=0;
+     382           0 :     safe.shape=NULL;
+     383           0 :     safe.flags=0;
+     384           0 :     safe.opt=NULL;
+     385           0 :     plumed_plumedmain_cmd_safe_nothrow(plumed,key,safe,nothrow);
+     386           0 :   }
+     387             : }
+     388             : 
+     389      804364 : extern "C" void plumed_plumedmain_finalize(void*plumed) {
+     390      804364 :   plumed_massert(plumed,"trying to deallocate a plumed object which is not initialized");
+     391             : // I think it is not possible to replace this delete with a smart pointer
+     392             : // since the ownership of this pointer is in a C structure. GB
+     393      804364 :   delete static_cast<PLMD::PlumedMain*>(plumed);
+     394      804364 : }
+     395             : 
+     396             : // values here should be consistent with those in plumed_symbol_table_init !!!!
+     397             : plumed_symbol_table_type_x plumed_symbol_table= {
+     398             :   4,
+     399             :   {plumed_plumedmain_create,plumed_plumedmain_cmd,plumed_plumedmain_finalize},
+     400             :   plumed_plumedmain_cmd_nothrow,
+     401             :   plumed_plumedmain_cmd_safe,
+     402             :   plumed_plumedmain_cmd_safe_nothrow,
+     403             :   plumed_plumedmain_create_reference,
+     404             :   plumed_plumedmain_delete_reference,
+     405             :   plumed_plumedmain_use_count
+     406             : };
+     407             : 
+     408             : // values here should be consistent with those above !!!!
+     409      808522 : extern "C" void plumed_symbol_table_init() {
+     410      808522 :   plumed_symbol_table.version=4;
+     411      808522 :   plumed_symbol_table.functions.create=plumed_plumedmain_create;
+     412      808522 :   plumed_symbol_table.functions.cmd=plumed_plumedmain_cmd;
+     413      808522 :   plumed_symbol_table.functions.finalize=plumed_plumedmain_finalize;
+     414      808522 :   plumed_symbol_table.cmd_nothrow=plumed_plumedmain_cmd_nothrow;
+     415      808522 :   plumed_symbol_table.cmd_safe=plumed_plumedmain_cmd_safe;
+     416      808522 :   plumed_symbol_table.cmd_safe_nothrow=plumed_plumedmain_cmd_safe_nothrow;
+     417      808522 :   plumed_symbol_table.create_reference=plumed_plumedmain_create_reference;
+     418      808522 :   plumed_symbol_table.delete_reference=plumed_plumedmain_delete_reference;
+     419      808522 :   plumed_symbol_table.use_count=plumed_plumedmain_use_count;
+     420      808522 : }
+     421             : 
+     422             : namespace PLMD {
+     423             : 
+     424             : #define plumed_convert_fptr(ptr,fptr) { ptr=NULL; std::memcpy(&ptr,&fptr,(sizeof(fptr)>sizeof(ptr)?sizeof(ptr):sizeof(fptr))); }
+     425             : 
+     426             : /// Static object which registers Plumed.
+     427             : /// This is a static object which, during its construction at startup,
+     428             : /// registers the pointers to plumed_plumedmain_create, plumed_plumedmain_cmd and plumed_plumedmain_finalize
+     429             : /// to the plumed_kernel_register function.
+     430             : /// Registration is only required with plumed loader <=2.4, but we do it anyway in order to maintain
+     431             : /// backward compatibility. Notice that as of plumed 2.5 the plumed_kernel_register is found
+     432             : /// using dlsym, in order to allow the libplumedKernel library to be loadable also when
+     433             : /// the plumed_kernel_register symbol is not available.
+     434             : namespace {
+     435             : class PlumedMainInitializer {
+     436             :   const bool debug;
+     437             : public:
+     438        4187 :   PlumedMainInitializer():
+     439        4187 :     debug(std::getenv("PLUMED_LOAD_DEBUG"))
+     440             :   {
+     441             : // make sure static plumed_function_pointers is initialized here
+     442        4187 :     plumed_symbol_table_init();
+     443        4187 :     if(debug) std::fprintf(stderr,"+++ Initializing PLUMED with plumed_symbol_table version %i at %p\n",plumed_symbol_table.version,(void*)&plumed_symbol_table);
+     444             : #if defined(__PLUMED_HAS_DLOPEN)
+     445        4187 :     if(std::getenv("PLUMED_LOAD_SKIP_REGISTRATION")) {
+     446           0 :       if(debug) std::fprintf(stderr,"+++ Skipping registration +++\n");
+     447           0 :       return;
+     448             :     }
+     449             :     typedef plumed_plumedmain_function_holder_x* (*plumed_kernel_register_type_x)(const plumed_plumedmain_function_holder_x*);
+     450             :     plumed_kernel_register_type_x plumed_kernel_register=nullptr;
+     451             :     void* handle=nullptr;
+     452             : #if defined(__PLUMED_HAS_RTLD_DEFAULT)
+     453        4187 :     if(debug) std::fprintf(stderr,"+++ Registering functions. Looking in RTLD_DEFAULT +++\n");
+     454        4187 :     void* dls=dlsym(RTLD_DEFAULT,"plumed_kernel_register");
+     455             : #else
+     456             :     handle=dlopen(NULL,RTLD_LOCAL);
+     457             :     if(debug) std::fprintf(stderr,"+++ Registering functions. dlopen handle at %p +++\n",handle);
+     458             :     void* dls=dlsym(handle,"plumed_kernel_register");
+     459             : #endif
+     460        4187 :     *(void **)(&plumed_kernel_register)=dls;
+     461        4187 :     if(debug) {
+     462           0 :       if(plumed_kernel_register) {
+     463           0 :         std::fprintf(stderr,"+++ plumed_kernel_register found at %p +++\n",dls);
+     464             :       }
+     465           0 :       else std::fprintf(stderr,"+++ plumed_kernel_register not found +++\n");
+     466             :     }
+     467             :     void*createp;
+     468             :     void*cmdp;
+     469             :     void*finalizep;
+     470             :     plumed_convert_fptr(createp,plumed_symbol_table.functions.create);
+     471             :     plumed_convert_fptr(cmdp,plumed_symbol_table.functions.cmd);
+     472             :     plumed_convert_fptr(finalizep,plumed_symbol_table.functions.finalize);
+     473        4187 :     if(plumed_kernel_register && debug) std::fprintf(stderr,"+++ Registering functions at %p (%p,%p,%p) +++\n",
+     474             :           (void*)&plumed_symbol_table.functions,createp,cmdp,finalizep);
+     475        4187 :     if(plumed_kernel_register) (*plumed_kernel_register)(&plumed_symbol_table.functions);
+     476             : // Notice that handle could be null in the following cases:
+     477             : // - if we use RTLD_DEFAULT
+     478             : // - on Linux if we don't use RTLD_DEFAULT, since dlopen(NULL,RTLD_LOCAL) returns a null pointer.
+     479             :     if(handle) dlclose(handle);
+     480             : #endif
+     481             :   }
+     482        4187 :   ~PlumedMainInitializer() {
+     483        4187 :     if(debug) std::fprintf(stderr,"+++ Finalizing PLUMED with plumed_symbol_table at %p\n",(void*)&plumed_symbol_table);
+     484        4187 :   }
+     485             : } PlumedMainInitializerRegisterMe;
+     486             : }
+     487             : 
+     488             : }
+     489             : 
+     490             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/TargetDist.cpp.func-sort-c.html b/coverage/core/TargetDist.cpp.func-sort-c.html new file mode 100644 index 000000000000..9dc1d2b3d93d --- /dev/null +++ b/coverage/core/TargetDist.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/TargetDist.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - TargetDist.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:0270.0 %
Date:2024-02-22 21:58:45Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10TargetDist4readERKNS_3PDBERKSt6vectorIPNS_5ValueESaIS6_EE0
_ZN4PLMD10TargetDist4readERKSt6vectorIdSaIdEERKS1_IPNS_5ValueESaIS7_EE0
_ZN4PLMD10TargetDist9calculateERSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/TargetDist.cpp.func.html b/coverage/core/TargetDist.cpp.func.html new file mode 100644 index 000000000000..0954aba86e97 --- /dev/null +++ b/coverage/core/TargetDist.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - core/TargetDist.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - TargetDist.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:0270.0 %
Date:2024-02-22 21:58:45Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10TargetDist4readERKNS_3PDBERKSt6vectorIPNS_5ValueESaIS6_EE0
_ZN4PLMD10TargetDist4readERKSt6vectorIdSaIdEERKS1_IPNS_5ValueESaIS7_EE0
_ZN4PLMD10TargetDist9calculateERSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/TargetDist.cpp.gcov.html b/coverage/core/TargetDist.cpp.gcov.html new file mode 100644 index 000000000000..88707a2f1069 --- /dev/null +++ b/coverage/core/TargetDist.cpp.gcov.html @@ -0,0 +1,148 @@ + + + + + + + + LCOV - plumed test coverage - core/TargetDist.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - TargetDist.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:0270.0 %
Date:2024-02-22 21:58:45Functions:030.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "TargetDist.h"
+      23             : #include "tools/PDB.h"
+      24             : #include "ActionWithValue.h"
+      25             : #include "Value.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30           0 : void TargetDist::read( const PDB& pdb, const std::vector<Value*> & ar ) {
+      31             :   // Clear values in target actions
+      32           0 :   for(unsigned i=0; i<ar.size(); ++i) {
+      33           0 :     (ar[i]->getPntrToAction())->clearInputForces();
+      34           0 :     (ar[i]->getPntrToAction())->clearDerivatives();
+      35             :   }
+      36             : 
+      37             :   // Calculate target actions from input in PDB file
+      38           0 :   std::vector<double> targ( ar.size() );
+      39           0 :   for(unsigned i=0; i<ar.size(); ++i) {
+      40           0 :     if( ar[i]->valueHasBeenSet() ) {
+      41           0 :       targ[i]=ar[i]->get();
+      42             :     } else {
+      43           0 :       (ar[i]->getPntrToAction())->calculateFromPDB( pdb );
+      44           0 :       targ[i]=ar[i]->get();
+      45             :     }
+      46             :   }
+      47           0 :   read( targ, ar );
+      48           0 : }
+      49             : 
+      50           0 : void TargetDist::read( const std::vector<double>& targ, const std::vector<Value*> & ar ) {
+      51           0 :   plumed_assert( targ.size()==ar.size() );
+      52             : 
+      53           0 :   target.resize( ar.size() ); args.resize( ar.size() );
+      54           0 :   log.printf("  distance from this point in cv space : ");
+      55           0 :   for(unsigned i=0; i<target.size(); ++i) { log.printf("%f ", targ[i]); target[i]=targ[i]; args[i]=ar[i]; }
+      56           0 :   log.printf("\n");
+      57           0 : }
+      58             : 
+      59           0 : double TargetDist::calculate( std::vector<double>& derivs ) {
+      60           0 :   plumed_assert( derivs.size()==args.size() );
+      61             :   double dist=0;
+      62           0 :   for(unsigned i=0; i<args.size(); ++i) {
+      63           0 :     double tmp=args[i]->difference( target[i], args[i]->get() );
+      64           0 :     derivs[i]=tmp; dist+=tmp*tmp;
+      65             :   }
+      66           0 :   dist=std::sqrt(dist);
+      67           0 :   for(unsigned i=0; i<args.size(); ++i) derivs[i]/=dist;
+      68           0 :   return dist;
+      69             : }
+      70             : 
+      71             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.cpp.func-sort-c.html b/coverage/core/Value.cpp.func-sort-c.html new file mode 100644 index 000000000000..d64ee5a58acf --- /dev/null +++ b/coverage/core/Value.cpp.func-sort-c.html @@ -0,0 +1,169 @@ + + + + + + + + LCOV - plumed test coverage - core/Value.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Value.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12814886.5 %
Date:2024-02-22 21:58:45Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3addERKNS_5ValueEPS0_0
_ZN4PLMD4copyERKNS_5ValueEPS0_0
_ZN4PLMD4copyERKNS_5ValueERS0_0
_ZN4PLMD5ValueC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE18
_ZNK4PLMD5Value9getDomainERdS1_34
_ZN4PLMD5Value12setGradientsEPNS_15ActionAtomisticERj190
_ZN4PLMD5Value10projectionERKS0_S2_261
_ZNK4PLMD5Value13passGradientsERKdRSt3mapINS_10AtomNumberENS_13VectorGenericILj3EEESt4lessIS4_ESaISt4pairIKS4_S6_EEE283
_ZN4PLMD5Value10readBinaryERSi456
_ZNK4PLMD5Value11writeBinaryERSo456
_ZN4PLMD5Value14buildDataStoreEv1001
_ZN4PLMD5Value11setConstantEv2799
_ZNK4PLMD5Value9getDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_27940
_ZN4PLMD5ValueC2EPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbRKSt6vectorIjSaIjEE91073
_ZN4PLMD5Value8setShapeERKSt6vectorIjSaIjEE94808
_ZNK4PLMD5Value17getGoodNumThreadsERKjS2_155283
_ZN4PLMD5Value3setERKmRKd200280
_ZNK4PLMD5Value10applyForceERSt6vectorIdSaIdEE369850
_ZN4PLMD5Value9setDomainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1151480
_ZN4PLMD5Value16setupPeriodicityEv1226051
_ZNK4PLMD5Value10isPeriodicEv1666682
_ZN4PLMD5Value14setNotPeriodicEv3528930
_ZN4PLMD5ValueC2Ev3561022
_ZN4PLMD5Value15getPntrToActionEv12586847
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.cpp.func.html b/coverage/core/Value.cpp.func.html new file mode 100644 index 000000000000..2a9eda4ce9f7 --- /dev/null +++ b/coverage/core/Value.cpp.func.html @@ -0,0 +1,169 @@ + + + + + + + + LCOV - plumed test coverage - core/Value.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Value.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12814886.5 %
Date:2024-02-22 21:58:45Functions:212487.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3addERKNS_5ValueEPS0_0
_ZN4PLMD4copyERKNS_5ValueEPS0_0
_ZN4PLMD4copyERKNS_5ValueERS0_0
_ZN4PLMD5Value10projectionERKS0_S2_261
_ZN4PLMD5Value10readBinaryERSi456
_ZN4PLMD5Value11setConstantEv2799
_ZN4PLMD5Value12setGradientsEPNS_15ActionAtomisticERj190
_ZN4PLMD5Value14buildDataStoreEv1001
_ZN4PLMD5Value14setNotPeriodicEv3528930
_ZN4PLMD5Value15getPntrToActionEv12586847
_ZN4PLMD5Value16setupPeriodicityEv1226051
_ZN4PLMD5Value3setERKmRKd200280
_ZN4PLMD5Value8setShapeERKSt6vectorIjSaIjEE94808
_ZN4PLMD5Value9setDomainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1151480
_ZN4PLMD5ValueC2EPNS_15ActionWithValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbRKSt6vectorIjSaIjEE91073
_ZN4PLMD5ValueC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE18
_ZN4PLMD5ValueC2Ev3561022
_ZNK4PLMD5Value10applyForceERSt6vectorIdSaIdEE369850
_ZNK4PLMD5Value10isPeriodicEv1666682
_ZNK4PLMD5Value11writeBinaryERSo456
_ZNK4PLMD5Value13passGradientsERKdRSt3mapINS_10AtomNumberENS_13VectorGenericILj3EEESt4lessIS4_ESaISt4pairIKS4_S6_EEE283
_ZNK4PLMD5Value17getGoodNumThreadsERKjS2_155283
_ZNK4PLMD5Value9getDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_27940
_ZNK4PLMD5Value9getDomainERdS1_34
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.cpp.gcov.html b/coverage/core/Value.cpp.gcov.html new file mode 100644 index 000000000000..cbe21b731bfa --- /dev/null +++ b/coverage/core/Value.cpp.gcov.html @@ -0,0 +1,313 @@ + + + + + + + + LCOV - plumed test coverage - core/Value.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Value.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12814886.5 %
Date:2024-02-22 21:58:45Functions:212487.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Value.h"
+      23             : #include "ActionWithValue.h"
+      24             : #include "ActionAtomistic.h"
+      25             : #include "ActionWithArguments.h"
+      26             : #include "ActionWithVirtualAtom.h"
+      27             : #include "tools/Exception.h"
+      28             : #include "tools/OpenMP.h"
+      29             : #include "PlumedMain.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33     3561022 : Value::Value():
+      34     3561022 :   action(NULL),
+      35     3561022 :   value_set(false),
+      36     3561022 :   hasForce(false),
+      37     3561022 :   constant(false),
+      38     3561022 :   storedata(false),
+      39             :   shape(std::vector<unsigned>()),
+      40     3561022 :   hasDeriv(true),
+      41     3561022 :   periodicity(unset),
+      42     3561022 :   min(0.0),
+      43     3561022 :   max(0.0),
+      44     3561022 :   max_minus_min(0.0),
+      45     3561022 :   inv_max_minus_min(0.0)
+      46             : {
+      47     3561022 :   data.resize(1); inputForce.resize(1);
+      48     3561022 : }
+      49             : 
+      50          18 : Value::Value(const std::string& name):
+      51          18 :   action(NULL),
+      52          18 :   value_set(false),
+      53          18 :   hasForce(false),
+      54          18 :   constant(false),
+      55          18 :   name(name),
+      56          18 :   storedata(false),
+      57             :   shape(std::vector<unsigned>()),
+      58          18 :   hasDeriv(true),
+      59          18 :   periodicity(unset),
+      60          18 :   min(0.0),
+      61          18 :   max(0.0),
+      62          18 :   max_minus_min(0.0),
+      63          18 :   inv_max_minus_min(0.0)
+      64             : {
+      65          18 :   data.resize(1); inputForce.resize(1);
+      66          18 :   data[0]=inputForce[0]=0;
+      67          18 : }
+      68             : 
+      69       91073 : Value::Value(ActionWithValue* av, const std::string& name, const bool withderiv, const std::vector<unsigned>&ss):
+      70       91073 :   action(av),
+      71       91073 :   value_set(false),
+      72       91073 :   hasForce(false),
+      73       91073 :   constant(false),
+      74       91073 :   name(name),
+      75       91073 :   storedata(false),
+      76       91073 :   hasDeriv(withderiv),
+      77       91073 :   periodicity(unset),
+      78       91073 :   min(0.0),
+      79       91073 :   max(0.0),
+      80       91073 :   max_minus_min(0.0),
+      81       91073 :   inv_max_minus_min(0.0)
+      82             : {
+      83       91073 :   if( action ) storedata=action->getName()=="PUT";
+      84       91073 :   setShape( ss );
+      85       91073 : }
+      86             : 
+      87       94808 : void Value::setShape( const std::vector<unsigned>&ss ) {
+      88       94808 :   std::size_t tot=1; shape.resize( ss.size() );
+      89      105104 :   for(unsigned i=0; i<shape.size(); ++i) { tot = tot*ss[i]; shape[i]=ss[i]; }
+      90             : 
+      91       94808 :   if( shape.size()>0 && hasDeriv ) {
+      92             :     // This is for grids
+      93           0 :     std::size_t ndata = tot*action->getNumberOfDerivatives();
+      94           0 :     data.resize( ndata );
+      95       94808 :   } else if( shape.size()==0 ) {
+      96             :     // This is for scalars
+      97       86384 :     data.resize(1); inputForce.resize(1);
+      98        8424 :   } else if( storedata ) {
+      99             :     // This is for vectors and matrices
+     100        7488 :     data.resize( tot ); inputForce.resize( tot );
+     101             :   }
+     102       94808 : }
+     103             : 
+     104     1226051 : void Value::setupPeriodicity() {
+     105     1226051 :   if( min==0 && max==0 ) {
+     106       74571 :     periodicity=notperiodic;
+     107             :   } else {
+     108     1151480 :     periodicity=periodic;
+     109     1151480 :     max_minus_min=max-min;
+     110     1151480 :     plumed_massert(max_minus_min>0, "your function has a very strange domain?");
+     111     1151480 :     inv_max_minus_min=1.0/max_minus_min;
+     112             :   }
+     113     1226051 : }
+     114             : 
+     115     1666682 : bool Value::isPeriodic()const {
+     116     1666682 :   plumed_massert(periodicity!=unset,"periodicity should be set");
+     117     1666682 :   return periodicity==periodic;
+     118             : }
+     119             : 
+     120      369850 : bool Value::applyForce(std::vector<double>& forces ) const {
+     121      369850 :   if( !hasForce || constant ) return false;
+     122             :   plumed_dbg_massert( data.size()-1==forces.size()," forces array has wrong size" );
+     123        9379 :   const unsigned N=data.size()-1;
+     124    42194907 :   for(unsigned i=0; i<N; ++i) forces[i]=inputForce[0]*data[1+i];
+     125             :   return true;
+     126             : }
+     127             : 
+     128     3528930 : void Value::setNotPeriodic() {
+     129     3528930 :   min=0; max=0; periodicity=notperiodic;
+     130     3528930 : }
+     131             : 
+     132     1151480 : void Value::setDomain(const std::string& pmin,const std::string& pmax) {
+     133     1151480 :   str_min=pmin;
+     134     1151480 :   if( !Tools::convertNoexcept(str_min,min) ) action->error("could not convert period string " + str_min + " to real");
+     135     1151480 :   str_max=pmax;
+     136     1151480 :   if( !Tools::convertNoexcept(str_max,max) ) action->error("could not convert period string " + str_max + " to read");
+     137     1151480 :   setupPeriodicity();
+     138     1151480 : }
+     139             : 
+     140       27940 : void Value::getDomain(std::string&minout,std::string&maxout) const {
+     141       27940 :   plumed_massert(periodicity==periodic,"function should be periodic");
+     142       27940 :   minout=str_min;
+     143       27940 :   maxout=str_max;
+     144       27940 : }
+     145             : 
+     146          34 : void Value::getDomain(double&minout,double&maxout) const {
+     147          34 :   plumed_massert(periodicity==periodic,"function should be periodic");
+     148          34 :   minout=min;
+     149          34 :   maxout=max;
+     150          34 : }
+     151             : 
+     152         190 : void Value::setGradients( ActionAtomistic* aa, unsigned& start ) {
+     153             :   // Can't do gradients if we don't have derivatives
+     154         190 :   if( !hasDeriv ) return;
+     155         154 :   plumed_assert( shape.size()==0 );
+     156        8362 :   for(unsigned j=0; j<aa->getNumberOfAtoms(); ++j) {
+     157        8208 :     Vector der(data[1+start+3*j],data[1+start+3*j+1],data[1+start+3*j+2]);
+     158        8208 :     aa->getGradient( j, der, gradients );
+     159             :   }
+     160         154 :   start += aa->getNumberOfAtoms();
+     161             : }
+     162             : 
+     163         283 : void Value::passGradients( const double& der, std::map<AtomNumber,Vector>& g ) const {
+     164        8921 :   for(const auto & p : gradients) { AtomNumber iatom=p.first; g[iatom] += p.second*der; }
+     165         283 : }
+     166             : 
+     167         261 : double Value::projection(const Value& v1,const Value&v2) {
+     168             :   double proj=0.0;
+     169             :   const std::map<AtomNumber,Vector> & grad1(v1.gradients);
+     170             :   const std::map<AtomNumber,Vector> & grad2(v2.gradients);
+     171       16167 :   for(const auto & p1 : grad1) {
+     172       15906 :     AtomNumber a=p1.first;
+     173             :     const auto p2=grad2.find(a);
+     174       15906 :     if(p2!=grad2.end()) {
+     175        8224 :       proj+=dotProduct(p1.second,(*p2).second);
+     176             :     }
+     177             :   }
+     178         261 :   return proj;
+     179             : }
+     180             : 
+     181    12586847 : ActionWithValue* Value::getPntrToAction() {
+     182    12586847 :   plumed_assert( action!=NULL );
+     183    12586847 :   return action;
+     184             : }
+     185             : 
+     186      200280 : void Value::set(const std::size_t& n, const double& v ) {
+     187      200280 :   value_set=true;
+     188      200280 :   if( getRank()==0 ) { plumed_assert( n==0 ); data[n]=v; applyPeriodicity(n); }
+     189      200280 :   else if( !hasDeriv ) { plumed_dbg_massert( n<data.size(), "failing in " + getName() ); data[n]=v; applyPeriodicity(n); }
+     190           0 :   else { data[n*(1+action->getNumberOfDerivatives())] = v; }
+     191      200280 : }
+     192             : 
+     193        1001 : void Value::buildDataStore() {
+     194        1001 :   if( getRank()==0 ) return;
+     195         936 :   storedata=true; setShape( shape );
+     196             : }
+     197             : 
+     198        2799 : void Value::setConstant() {
+     199        2799 :   constant=true; storedata=true; setShape( shape );
+     200        2799 : }
+     201             : 
+     202         456 : void Value::writeBinary(std::ostream&o) const {
+     203         456 :   o.write(reinterpret_cast<const char*>(&data[0]),data.size()*sizeof(double));
+     204         456 : }
+     205             : 
+     206         456 : void Value::readBinary(std::istream&i) {
+     207         456 :   i.read(reinterpret_cast<char*>(&data[0]),data.size()*sizeof(double));
+     208         456 : }
+     209             : 
+     210      155283 : unsigned Value::getGoodNumThreads( const unsigned& j, const unsigned& k ) const {
+     211      155283 :   return OpenMP::getGoodNumThreads( &data[j], (k-j) );
+     212             : }
+     213             : 
+     214           0 : void copy( const Value& val1, Value& val2 ) {
+     215           0 :   unsigned nder=val1.getNumberOfDerivatives();
+     216           0 :   if( nder!=val2.getNumberOfDerivatives() ) { val2.resizeDerivatives( nder ); }
+     217           0 :   val2.clearDerivatives();
+     218           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2.addDerivative( i, val1.getDerivative(i) );
+     219             :   val2.set( val1.get() );
+     220           0 : }
+     221             : 
+     222           0 : void copy( const Value& val1, Value* val2 ) {
+     223           0 :   unsigned nder=val1.getNumberOfDerivatives();
+     224           0 :   if( nder!=val2->getNumberOfDerivatives() ) { val2->resizeDerivatives( nder ); }
+     225           0 :   val2->clearDerivatives();
+     226           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2->addDerivative( i, val1.getDerivative(i) );
+     227             :   val2->set( val1.get() );
+     228           0 : }
+     229             : 
+     230           0 : void add( const Value& val1, Value* val2 ) {
+     231           0 :   plumed_assert( val1.getNumberOfDerivatives()==val2->getNumberOfDerivatives() );
+     232           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2->addDerivative( i, val1.getDerivative(i) );
+     233           0 :   val2->set( val1.get() + val2->get() );
+     234           0 : }
+     235             : 
+     236             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.h.func-sort-c.html b/coverage/core/Value.h.func-sort-c.html new file mode 100644 index 000000000000..2cc06a8437af --- /dev/null +++ b/coverage/core/Value.h.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - core/Value.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Value.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Value9chainRuleEd434
_ZNK4PLMD5Value14bringBackInPbcEd3173
_ZN4PLMD5Value15clearInputForceERKSt6vectorINS_10AtomNumberESaIS2_EE88980
_ZNK4PLMD5Value22getNumberOfDerivativesEv348282
_ZN4PLMD5Value16clearDerivativesEv2157113
_ZNK4PLMD5Value17getNumberOfValuesEv32288072
_ZN4PLMD5Value16applyPeriodicityERKj44648169
_ZNK4PLMD5Value10differenceEdd155958940
_ZN4PLMD5Value17resizeDerivativesEi4129461481
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.h.func.html b/coverage/core/Value.h.func.html new file mode 100644 index 000000000000..47be03277afc --- /dev/null +++ b/coverage/core/Value.h.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - core/Value.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Value.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Value15clearInputForceERKSt6vectorINS_10AtomNumberESaIS2_EE88980
_ZN4PLMD5Value16applyPeriodicityERKj44648169
_ZN4PLMD5Value16clearDerivativesEv2157113
_ZN4PLMD5Value17resizeDerivativesEi4129461481
_ZN4PLMD5Value9chainRuleEd434
_ZNK4PLMD5Value10differenceEdd155958940
_ZNK4PLMD5Value14bringBackInPbcEd3173
_ZNK4PLMD5Value17getNumberOfValuesEv32288072
_ZNK4PLMD5Value22getNumberOfDerivativesEv348282
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/Value.h.gcov.html b/coverage/core/Value.h.gcov.html new file mode 100644 index 000000000000..6e19df720c0a --- /dev/null +++ b/coverage/core/Value.h.gcov.html @@ -0,0 +1,476 @@ + + + + + + + + LCOV - plumed test coverage - core/Value.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - Value.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_Value_h
+      23             : #define __PLUMED_core_Value_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <string>
+      27             : #include <map>
+      28             : #include "tools/Exception.h"
+      29             : #include "tools/Tools.h"
+      30             : #include "tools/AtomNumber.h"
+      31             : #include "tools/Vector.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : class ActionWithValue;
+      36             : class ActionAtomistic;
+      37             : 
+      38             : /// \ingroup TOOLBOX
+      39             : /// A class for holding the value of a function together with its derivatives.
+      40             : /// Typically, an  object of type PLMD::ActionWithValue will contain one
+      41             : /// object of type PLUMD::Value that will be named after the label.  If the
+      42             : /// PLMD::ActionWithValue is part of a class that calculates multiple components
+      43             : /// then the class will contain multiple that will be called label.component-name
+      44             : /// This class is used to pass information between different PLMD::Action
+      45             : /// objects.  However, if you find a use for a tempory PLMD::Value in some method
+      46             : /// you are implementing please feel free to use it.
+      47             : class Value {
+      48             :   friend class ActionWithValue;
+      49             :   friend class ActionAtomistic;
+      50             :   friend class ActionWithArguments;
+      51             :   friend class ActionWithVirtualAtom;
+      52             :   friend class DomainDecomposition;
+      53             :   template<typename T>
+      54             :   friend class DataPassingObjectTyped;
+      55             : /// This copies the contents of a value into a second value (just the derivatives and value)
+      56             :   friend void copy( const Value& val1, Value& val2 );
+      57             : /// This copies the contents of a value into a second value (but second value is a pointer)
+      58             :   friend void copy( const Value& val, Value* val2 );
+      59             : /// This adds some derivatives onto the value
+      60             :   friend void add( const Value& val1, Value* valout );
+      61             : /// This calculates val1*val2 and sorts out the derivatives
+      62             :   friend void product( const Value& val1, const Value& val2, Value& valout );
+      63             : /// This calculates va1/val2 and sorts out the derivatives
+      64             :   friend void quotient( const Value& val1, const Value& val2, Value* valout );
+      65             : private:
+      66             : /// The action in which this quantity is calculated
+      67             :   ActionWithValue* action;
+      68             : /// Had the value been set
+      69             :   bool value_set;
+      70             : /// The value of the quantity
+      71             :   std::vector<double> data;
+      72             : /// The force acting on this quantity
+      73             :   std::vector<double> inputForce;
+      74             : /// A flag telling us we have a force acting on this quantity
+      75             :   bool hasForce;
+      76             : /// This flag is used if the value is a constant
+      77             :   bool constant;
+      78             : /// The derivatives of the quantity stored in value
+      79             :   std::map<AtomNumber,Vector> gradients;
+      80             : /// The name of this quantiy
+      81             :   std::string name;
+      82             : /// Are we storing the data for this value if it is vector or matrix
+      83             :   bool storedata;
+      84             : /// What is the shape of the value (0 dimensional=scalar, n dimensional with derivatives=grid, 1 dimensional no derivatives=vector, 2 dimensional no derivatives=matrix)
+      85             :   std::vector<unsigned> shape;
+      86             : /// Does this quanity have derivatives
+      87             :   bool hasDeriv;
+      88             : /// Is this quantity periodic
+      89             :   enum {unset,periodic,notperiodic} periodicity;
+      90             : /// Various quantities that describe the domain of this value
+      91             :   std::string str_min, str_max;
+      92             :   double min,max;
+      93             :   double max_minus_min;
+      94             :   double inv_max_minus_min;
+      95             : /// Complete the setup of the periodicity
+      96             :   void setupPeriodicity();
+      97             : // bring value within PBCs
+      98             :   void applyPeriodicity( const unsigned& ival );
+      99             : public:
+     100             : /// A constructor that can be used to make Vectors of values
+     101             :   Value();
+     102             : /// A constructor that can be used to make Vectors of named values
+     103             :   explicit Value(const std::string& name);
+     104             : /// A constructor that is used throughout the code to setup the value poiters
+     105             :   Value(ActionWithValue* av, const std::string& name, const bool withderiv,const std::vector<unsigned>&ss=std::vector<unsigned>());
+     106             : /// Set the shape of the Value
+     107             :   void setShape( const std::vector<unsigned>&ss );
+     108             : /// Set the value of the function
+     109             :   void set(double);
+     110             : /// Set the value of the stored data
+     111             :   void set(const std::size_t& n, const double& v );
+     112             : /// Add something to the value of the function
+     113             :   void add(double);
+     114             : /// Get the value of the function
+     115             :   double get( const std::size_t& ival=0 ) const;
+     116             : /// Find out if the value has been set
+     117             :   bool valueHasBeenSet() const;
+     118             : /// Check if the value is periodic
+     119             :   bool isPeriodic() const;
+     120             : /// Set the function not periodic
+     121             :   void setNotPeriodic();
+     122             : /// Set the domain of the function
+     123             :   void setDomain(const std::string&, const std::string&);
+     124             : /// Get the domain of the quantity
+     125             :   void getDomain(std::string&,std::string&) const;
+     126             : /// Get the domain of the quantity
+     127             :   void getDomain(double&,double&) const;
+     128             : /// Get the name of the quantity
+     129             :   const std::string& getName() const;
+     130             : /// Check whether or not this particular quantity has derivatives
+     131             :   bool hasDerivatives()const;
+     132             : /// Get the number of derivatives that this particular value has
+     133             :   unsigned getNumberOfDerivatives() const;
+     134             : /// Set the number of derivatives
+     135             :   void resizeDerivatives(int n);
+     136             : /// Set all the derivatives to zero
+     137             :   void clearDerivatives();
+     138             : /// Add some derivative to the ith component of the derivatives array
+     139             :   void addDerivative(unsigned i,double d);
+     140             : /// Set the value of the ith component of the derivatives array
+     141             :   void setDerivative(unsigned i, double d);
+     142             : /// Apply the chain rule to the derivatives
+     143             :   void chainRule(double df);
+     144             : /// Get the derivative with respect to component n
+     145             :   double getDerivative(const unsigned n) const;
+     146             : /// Clear the input force on the variable
+     147             :   void clearInputForce();
+     148             : /// Special method for clearing forces on variables used by DataPassingObject
+     149             :   void clearInputForce( const std::vector<AtomNumber>& index );
+     150             : /// Add some force on this value
+     151             :   void addForce(double f);
+     152             : /// Add some force on the ival th component of this value
+     153             :   void addForce( const std::size_t& ival, double f );
+     154             : /// Get the value of the force on this colvar
+     155             :   double getForce( const std::size_t& ival=0 ) const ;
+     156             : /// Apply the forces to the derivatives using the chain rule (if there are no forces this routine returns false)
+     157             :   bool applyForce( std::vector<double>& forces ) const ;
+     158             : /// Calculate the difference between the instantaneous value of the function and some other point: other_point-inst_val
+     159             :   double difference(double)const;
+     160             : /// Calculate the difference between two values of this function: d2 -d1
+     161             :   double difference(double d1,double d2)const;
+     162             : /// This returns the pointer to the action where this value is calculated
+     163             :   ActionWithValue* getPntrToAction();
+     164             : /// Bring back one value into the correct pbc if needed, else give back the value
+     165             :   double bringBackInPbc(double d1)const;
+     166             : /// Get the difference between max and minimum of domain
+     167             :   double getMaxMinusMin()const;
+     168             : /// This sets up the gradients
+     169             :   void setGradients( ActionAtomistic* aa, unsigned& start );
+     170             : /// This passes gradients from one action to another
+     171             :   void passGradients( const double& der, std::map<AtomNumber,Vector>& g ) const ;
+     172             :   static double projection(const Value&,const Value&);
+     173             : /// Get the rank of the object that is contained in this value
+     174             :   unsigned getRank() const ;
+     175             : /// Get the shape of the object that is contained in this value
+     176             :   const std::vector<unsigned>& getShape() const ;
+     177             : /// This turns on storing of vectors/matrices
+     178             :   void buildDataStore();
+     179             : /// Get the total number of scalars that are stored here
+     180             :   unsigned getNumberOfValues() const ;
+     181             : /// Get the number of threads to use when assigning this value
+     182             :   unsigned getGoodNumThreads( const unsigned& j, const unsigned& k ) const ;
+     183             : /// These are used for passing around the data in this value when we are doing replica exchange
+     184             :   void writeBinary(std::ostream&o) const ;
+     185             :   void readBinary(std::istream&i);
+     186             : /// These are used for making constant values
+     187             :   bool isConstant() const ;
+     188             :   void setConstant();
+     189             : /// Check if forces have been added on this value
+     190             :   bool forcesWereAdded() const ;
+     191             : };
+     192             : 
+     193             : void copy( const Value& val1, Value& val2 );
+     194             : void copy( const Value& val1, Value* val2 );
+     195             : void add( const Value& val1, Value* valout );
+     196             : 
+     197             : inline
+     198    44648169 : void Value::applyPeriodicity(const unsigned& ival) {
+     199    44648169 :   if(periodicity==periodic) {
+     200    30706146 :     data[ival]=min+difference(min,data[ival]);
+     201    30706146 :     if(data[ival]<min)data[ival]+=max_minus_min;
+     202             :   }
+     203    44648169 : }
+     204             : 
+     205             : inline
+     206             : void product( const Value& val1, const Value& val2, Value& valout ) {
+     207             :   plumed_assert( val1.getNumberOfDerivatives()==val2.getNumberOfDerivatives() );
+     208             :   if( valout.getNumberOfDerivatives()!=val1.getNumberOfDerivatives() ) valout.resizeDerivatives( val1.getNumberOfDerivatives() );
+     209             :   valout.value_set=false;
+     210             :   valout.clearDerivatives();
+     211             :   double u=val1.get();
+     212             :   double v=val2.get();
+     213             :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) {
+     214             :     valout.addDerivative(i, u*val2.getDerivative(i) + v*val1.getDerivative(i) );
+     215             :   }
+     216             :   valout.set( u*v );
+     217             : }
+     218             : 
+     219             : inline
+     220             : void quotient( const Value& val1, const Value& val2, Value* valout ) {
+     221             :   plumed_assert( val1.getNumberOfDerivatives()==val2.getNumberOfDerivatives());
+     222             :   if( valout->getNumberOfDerivatives()!=val1.getNumberOfDerivatives() ) valout->resizeDerivatives( val1.getNumberOfDerivatives() );
+     223             :   valout->value_set=false;
+     224             :   valout->clearDerivatives();
+     225             :   double u=val1.get();
+     226             :   double v=val2.get();
+     227             :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) {
+     228             :     valout->addDerivative(i, v*val1.getDerivative(i) - u*val2.getDerivative(i) );
+     229             :   }
+     230             :   valout->chainRule( 1/(v*v) ); valout->set( u / v );
+     231             : }
+     232             : 
+     233             : inline
+     234             : void Value::set(double v) {
+     235    44020001 :   value_set=true;
+     236    44249443 :   data[0]=v;
+     237    44204533 :   applyPeriodicity(0);
+     238       19138 : }
+     239             : 
+     240             : inline
+     241             : void Value::add(double v) {
+     242             :   value_set=true;
+     243             :   data[0]+=v;
+     244             :   applyPeriodicity(0);
+     245             : }
+     246             : 
+     247             : inline
+     248             : double Value::get( const std::size_t& ival )const {
+     249     3865527 :   return data[ival];
+     250             : }
+     251             : 
+     252             : inline
+     253             : bool Value::valueHasBeenSet() const {
+     254           0 :   return value_set;
+     255             : }
+     256             : 
+     257             : inline
+     258             : const std::string& Value::getName()const {
+     259     8698179 :   return name;
+     260             : }
+     261             : 
+     262             : inline
+     263      348282 : unsigned Value::getNumberOfDerivatives() const {
+     264      348282 :   plumed_massert(hasDeriv,"the derivatives array for this value has zero size");
+     265      348282 :   if( shape.size()>0 ) return shape.size();
+     266      348282 :   return data.size() - 1;
+     267             : }
+     268             : 
+     269             : inline
+     270             : double Value::getDerivative(const unsigned n) const {
+     271             :   plumed_dbg_massert(n<getNumberOfDerivatives(),"you are asking for a derivative that is out of bounds");
+     272    20411431 :   return data[1+n];
+     273             : }
+     274             : 
+     275             : inline
+     276             : bool Value::hasDerivatives() const {
+     277       13272 :   return hasDeriv;
+     278             : }
+     279             : 
+     280             : inline
+     281  4129461481 : void Value::resizeDerivatives(int n) {
+     282  4129461481 :   if( shape.size()>0 ) return;
+     283  4105414458 :   if(hasDeriv) data.resize(1+n);
+     284             : }
+     285             : 
+     286             : inline
+     287             : void Value::addDerivative(unsigned i,double d) {
+     288             :   plumed_dbg_massert(i<getNumberOfDerivatives(),"derivative is out of bounds");
+     289    22659919 :   data[1+i]+=d;
+     290          10 : }
+     291             : 
+     292             : inline
+     293             : void Value::setDerivative(unsigned i, double d) {
+     294             :   plumed_dbg_massert(i<getNumberOfDerivatives(),"derivative is out of bounds");
+     295      324137 :   data[1+i]=d;
+     296             : }
+     297             : 
+     298             : inline
+     299         434 : void Value::chainRule(double df) {
+     300       18368 :   for(unsigned i=0; i<getNumberOfDerivatives(); ++i) data[1+i]*=df;
+     301         434 : }
+     302             : 
+     303             : inline
+     304             : void Value::clearInputForce() {
+     305     2468512 :   if( !hasForce ) return;
+     306      215507 :   hasForce=false; std::fill(inputForce.begin(),inputForce.end(),0);
+     307             : }
+     308             : 
+     309             : inline
+     310       88980 : void Value::clearInputForce( const std::vector<AtomNumber>& index ) {
+     311       88980 :   if( !hasForce ) return;
+     312      733185 :   hasForce=false; for(const auto & p : index) inputForce[p.index()]=0;
+     313             : }
+     314             : 
+     315             : inline
+     316     2157113 : void Value::clearDerivatives() {
+     317     2157113 :   if( constant ) return;
+     318     2157113 :   value_set=false;
+     319     2157113 :   if( data.size()>1 ) std::fill(data.begin()+1, data.end(), 0);
+     320             : }
+     321             : 
+     322             : inline
+     323             : void Value::addForce(double f) {
+     324      188546 :   hasForce=true;
+     325      188546 :   inputForce[0]+=f;
+     326        2623 : }
+     327             : 
+     328             : inline
+     329             : void Value::addForce(const std::size_t& ival, double f) {
+     330             :   plumed_dbg_massert(ival<inputForce.size(),"too few components in value to add force");
+     331      738876 :   hasForce=true;
+     332      738876 :   inputForce[ival]+=f;
+     333             : }
+     334             : 
+     335             : inline
+     336             : bool Value::forcesWereAdded() const {
+     337      594095 :   return hasForce;
+     338             : }
+     339             : 
+     340             : inline
+     341             : double Value::getForce( const std::size_t& ival ) const {
+     342             :   plumed_dbg_assert( ival<inputForce.size() );
+     343      629213 :   return inputForce[ival];
+     344             : }
+     345             : 
+     346             : /// d2-d1
+     347             : inline
+     348   155958940 : double Value::difference(double d1,double d2)const {
+     349   155958940 :   if(periodicity==notperiodic) {
+     350    90590166 :     return d2-d1;
+     351    65368774 :   } else if(periodicity==periodic) {
+     352    65368774 :     double s=(d2-d1)*inv_max_minus_min;
+     353             :     // remember: pbc brings the difference in a range of -0.5:0.5
+     354    65368774 :     s=Tools::pbc(s);
+     355    65368774 :     return s*max_minus_min;
+     356           0 :   } else plumed_merror("periodicity should be set to compute differences");
+     357             : }
+     358             : 
+     359             : inline
+     360        3173 : double Value::bringBackInPbc(double d1)const {
+     361        3173 :   return min+max_minus_min/2.+difference(min+max_minus_min/2., d1);
+     362             : }
+     363             : 
+     364             : inline
+     365             : double Value::difference(double d)const {
+     366   119526971 :   return difference(get(),d);
+     367             : }
+     368             : 
+     369             : inline
+     370             : double Value::getMaxMinusMin()const {
+     371             :   plumed_dbg_assert( periodicity==periodic );
+     372         266 :   return max_minus_min;
+     373             : }
+     374             : 
+     375             : inline
+     376             : unsigned Value::getRank() const {
+     377      472923 :   return shape.size();
+     378             : }
+     379             : 
+     380             : inline
+     381             : const std::vector<unsigned>& Value::getShape() const {
+     382      271403 :   return shape;
+     383             : }
+     384             : 
+     385             : inline
+     386    32288072 : unsigned Value::getNumberOfValues() const {
+     387    34243341 :   unsigned size=1; for(unsigned i=0; i<shape.size(); ++i) size *= shape[i];
+     388    32288072 :   return size;
+     389             : }
+     390             : 
+     391             : inline
+     392             : bool Value::isConstant() const {
+     393       18030 :   return constant;
+     394             : }
+     395             : 
+     396             : }
+     397             : 
+     398             : #endif
+     399             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/WithCmd.h.func-sort-c.html b/coverage/core/WithCmd.h.func-sort-c.html new file mode 100644 index 000000000000..373654a33d91 --- /dev/null +++ b/coverage/core/WithCmd.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/WithCmd.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - WithCmd.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91464.3 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE0
_ZN4PLMD7WithCmdD0Ev0
_ZN4PLMD7WithCmdD2Ev0
_ZN4PLMD7WithCmd3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE180
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrEmPKm275810
_ZN4PLMD7WithCmd3cmdEPKcRKNS_11TypesafePtrE856883
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/WithCmd.h.func.html b/coverage/core/WithCmd.h.func.html new file mode 100644 index 000000000000..c711c9a5fc7e --- /dev/null +++ b/coverage/core/WithCmd.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - core/WithCmd.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - WithCmd.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91464.3 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7WithCmd3cmdEPKcRKNS_11TypesafePtrE856883
_ZN4PLMD7WithCmd3cmdERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_11TypesafePtrE180
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE0
_ZN4PLMD7WithCmd3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrEmPKm275810
_ZN4PLMD7WithCmdD0Ev0
_ZN4PLMD7WithCmdD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/WithCmd.h.gcov.html b/coverage/core/WithCmd.h.gcov.html new file mode 100644 index 000000000000..260a63656662 --- /dev/null +++ b/coverage/core/WithCmd.h.gcov.html @@ -0,0 +1,144 @@ + + + + + + + + LCOV - plumed test coverage - core/WithCmd.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - core - WithCmd.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91464.3 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_core_WithCmd_h
+      23             : #define __PLUMED_core_WithCmd_h
+      24             : 
+      25             : #include "tools/TypesafePtr.h"
+      26             : #include <string>
+      27             : #include <string_view>
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : /// Base for classes with cmd() method.
+      32             : /// This is an abstract base class for classes with
+      33             : /// cmd() method.
+      34             : class WithCmd {
+      35             : public:
+      36             :   /// This is the preferred method as it avoid allocations of temporaries.
+      37             :   /// If this is not overridded, it will call the legacy method.
+      38           0 :   virtual void cmd(std::string_view key,const TypesafePtr & val=nullptr) {
+      39           0 :     cmd(std::string(key),val);
+      40           0 :   }
+      41             :   /// This is the legacy method we used in older plumed versions, so it is still possible.
+      42             :   /// If this is not overridden, it will call the preferred method
+      43         180 :   virtual void cmd(const std::string& key,const TypesafePtr & val=nullptr) {
+      44         180 :     cmd(std::string_view(key),val);
+      45         180 :   }
+      46             :   void cmd(std::string_view key,const TypesafePtr & val,const std::size_t* shape) {
+      47             :     cmd(key,TypesafePtr::setNelemAndShape(val,0,shape));
+      48             :   }
+      49      275810 :   void cmd(std::string_view key,const TypesafePtr & val,std::size_t nelem, const std::size_t* shape=nullptr) {
+      50      275810 :     cmd(key,TypesafePtr::setNelemAndShape(val,nelem,shape));
+      51      275810 :   }
+      52             :   /// This is needed to avoid ambiguities
+      53      856883 :   void cmd(const char* key,const TypesafePtr & val=nullptr) {
+      54      856883 :     cmd(std::string_view(key),val);
+      55      856761 :   }
+      56             :   virtual ~WithCmd();
+      57             : };
+      58             : 
+      59             : inline
+      60           0 : WithCmd::~WithCmd() {
+      61             : // do nothing
+      62             : // here just to allow inheriting from this class properly
+      63           0 : }
+      64             : 
+      65             : }
+      66             : 
+      67             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/index-sort-f.html b/coverage/core/index-sort-f.html new file mode 100644 index 000000000000..022d89fe8b96 --- /dev/null +++ b/coverage/core/index-sort-f.html @@ -0,0 +1,644 @@ + + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:3556412386.2 %
Date:2024-02-22 21:58:45Functions:1308142791.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionSetup.h +
33.3%33.3%
+
33.3 %1 / 30.0 %0 / 2
ActionAnyorder.h +
33.3%33.3%
+
33.3 %1 / 30.0 %0 / 2
Group.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
TargetDist.cpp +
0.0%
+
0.0 %0 / 270.0 %0 / 3
ActionShortcut.h +
0.0%
+
0.0 %0 / 30.0 %0 / 3
ExchangePatterns.cpp +
19.2%19.2%
+
19.2 %5 / 2628.6 %2 / 7
ActionAnyorder.cpp +
50.0%50.0%
+
50.0 %3 / 633.3 %1 / 3
DataPassingObject.cpp +
85.5%85.5%
+
85.5 %65 / 7648.3 %14 / 29
ActionToGetData.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
DataPassingTools.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
WithCmd.h +
64.3%64.3%
+
64.3 %9 / 1450.0 %3 / 6
ActionSetup.cpp +
90.9%90.9%
+
90.9 %10 / 1166.7 %2 / 3
ActionShortcut.cpp +
70.4%70.4%
+
70.4 %19 / 2766.7 %4 / 6
ActionForInterface.cpp +
100.0%
+
100.0 %13 / 1375.0 %3 / 4
Group.cpp +
98.6%98.6%
+
98.6 %73 / 7475.0 %3 / 4
DataPassingTools.cpp +
82.6%82.6%
+
82.6 %19 / 2375.0 %6 / 8
CLTool.h +
70.6%70.6%
+
70.6 %24 / 3480.0 %12 / 15
ActionAtomistic.cpp +
92.6%92.6%
+
92.6 %213 / 23080.0 %20 / 25
ActionPilot.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
Colvar.cpp +
100.0%
+
100.0 %25 / 2583.3 %5 / 6
PbcAction.cpp +
100.0%
+
100.0 %25 / 2583.3 %5 / 6
GenericMolInfo.cpp +
82.6%82.6%
+
82.6 %181 / 21983.3 %15 / 18
ActionWithValue.cpp +
91.0%91.0%
+
91.0 %132 / 14583.3 %25 / 30
Action.cpp +
81.2%81.2%
+
81.2 %156 / 19283.3 %30 / 36
ActionWithVirtualAtom.cpp +
100.0%
+
100.0 %58 / 5885.7 %6 / 7
ActionToGetData.cpp +
80.0%80.0%
+
80.0 %24 / 3085.7 %6 / 7
ActionForInterface.h +
87.5%87.5%
+
87.5 %7 / 885.7 %6 / 7
FlexibleBin.cpp +
78.8%78.8%
+
78.8 %115 / 14685.7 %6 / 7
Action.h +
91.6%91.6%
+
91.6 %76 / 8386.5 %32 / 37
ActionWithValue.h +
95.8%95.8%
+
95.8 %23 / 2487.5 %7 / 8
PlumedMainInitializer.cpp +
82.9%82.9%
+
82.9 %223 / 26987.5 %14 / 16
Value.cpp +
86.5%86.5%
+
86.5 %128 / 14887.5 %21 / 24
CLTool.cpp +
85.9%85.9%
+
85.9 %85 / 9990.0 %9 / 10
CLToolRegister.cpp +
67.2%67.2%
+
67.2 %39 / 5890.0 %9 / 10
ActionRegister.cpp +
69.2%69.2%
+
69.2 %45 / 6590.9 %10 / 11
ActionSet.h +
100.0%
+
100.0 %18 / 1891.2 %31 / 34
ActionWithArguments.cpp +
84.8%84.8%
+
84.8 %151 / 17892.9 %13 / 14
DomainDecomposition.cpp +
95.5%95.5%
+
95.5 %254 / 26693.9 %31 / 33
PlumedMain.cpp +
90.1%90.1%
+
90.1 %798 / 88694.7 %54 / 57
ActionRegister.h +
100.0%
+
100.0 %6 / 697.5 %819 / 840
DataPassingObject.h +
100.0%
+
100.0 %4 / 4-0 / 0
PlumedMain.h +
88.2%88.2%
+
88.2 %15 / 17-0 / 0
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
PbcAction.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
DomainDecomposition.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
ActionSet.cpp +
100.0%
+
100.0 %10 / 10100.0 %3 / 3
Colvar.h +
100.0%
+
100.0 %24 / 24100.0 %4 / 4
CLToolMain.cpp +
80.7%80.7%
+
80.7 %109 / 135100.0 %5 / 5
ActionWithVirtualAtom.h +
100.0%
+
100.0 %22 / 22100.0 %6 / 6
ActionToPutData.h +
100.0%
+
100.0 %6 / 6100.0 %6 / 6
GREX.cpp +
75.2%75.2%
+
75.2 %100 / 133100.0 %6 / 6
ActionWithArguments.h +
100.0%
+
100.0 %16 / 16100.0 %6 / 6
Value.h +
96.7%96.7%
+
96.7 %59 / 61100.0 %9 / 9
ActionAtomistic.h +
100.0%
+
100.0 %46 / 46100.0 %9 / 9
ActionToPutData.cpp +
93.1%93.1%
+
93.1 %95 / 102100.0 %17 / 17
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/index-sort-l.html b/coverage/core/index-sort-l.html new file mode 100644 index 000000000000..f459252ed9a5 --- /dev/null +++ b/coverage/core/index-sort-l.html @@ -0,0 +1,644 @@ + + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:3556412386.2 %
Date:2024-02-22 21:58:45Functions:1308142791.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Group.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
ActionShortcut.h +
0.0%
+
0.0 %0 / 30.0 %0 / 3
TargetDist.cpp +
0.0%
+
0.0 %0 / 270.0 %0 / 3
ExchangePatterns.cpp +
19.2%19.2%
+
19.2 %5 / 2628.6 %2 / 7
ActionSetup.h +
33.3%33.3%
+
33.3 %1 / 30.0 %0 / 2
ActionAnyorder.h +
33.3%33.3%
+
33.3 %1 / 30.0 %0 / 2
ActionToGetData.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
ActionAnyorder.cpp +
50.0%50.0%
+
50.0 %3 / 633.3 %1 / 3
WithCmd.h +
64.3%64.3%
+
64.3 %9 / 1450.0 %3 / 6
CLToolRegister.cpp +
67.2%67.2%
+
67.2 %39 / 5890.0 %9 / 10
ActionRegister.cpp +
69.2%69.2%
+
69.2 %45 / 6590.9 %10 / 11
ActionShortcut.cpp +
70.4%70.4%
+
70.4 %19 / 2766.7 %4 / 6
CLTool.h +
70.6%70.6%
+
70.6 %24 / 3480.0 %12 / 15
GREX.cpp +
75.2%75.2%
+
75.2 %100 / 133100.0 %6 / 6
FlexibleBin.cpp +
78.8%78.8%
+
78.8 %115 / 14685.7 %6 / 7
ActionToGetData.cpp +
80.0%80.0%
+
80.0 %24 / 3085.7 %6 / 7
CLToolMain.cpp +
80.7%80.7%
+
80.7 %109 / 135100.0 %5 / 5
Action.cpp +
81.2%81.2%
+
81.2 %156 / 19283.3 %30 / 36
DataPassingTools.cpp +
82.6%82.6%
+
82.6 %19 / 2375.0 %6 / 8
GenericMolInfo.cpp +
82.6%82.6%
+
82.6 %181 / 21983.3 %15 / 18
PlumedMainInitializer.cpp +
82.9%82.9%
+
82.9 %223 / 26987.5 %14 / 16
ActionWithArguments.cpp +
84.8%84.8%
+
84.8 %151 / 17892.9 %13 / 14
DataPassingObject.cpp +
85.5%85.5%
+
85.5 %65 / 7648.3 %14 / 29
CLTool.cpp +
85.9%85.9%
+
85.9 %85 / 9990.0 %9 / 10
Value.cpp +
86.5%86.5%
+
86.5 %128 / 14887.5 %21 / 24
ActionForInterface.h +
87.5%87.5%
+
87.5 %7 / 885.7 %6 / 7
PlumedMain.h +
88.2%88.2%
+
88.2 %15 / 17-0 / 0
PlumedMain.cpp +
90.1%90.1%
+
90.1 %798 / 88694.7 %54 / 57
ActionSetup.cpp +
90.9%90.9%
+
90.9 %10 / 1166.7 %2 / 3
ActionWithValue.cpp +
91.0%91.0%
+
91.0 %132 / 14583.3 %25 / 30
Action.h +
91.6%91.6%
+
91.6 %76 / 8386.5 %32 / 37
ActionAtomistic.cpp +
92.6%92.6%
+
92.6 %213 / 23080.0 %20 / 25
ActionToPutData.cpp +
93.1%93.1%
+
93.1 %95 / 102100.0 %17 / 17
DomainDecomposition.cpp +
95.5%95.5%
+
95.5 %254 / 26693.9 %31 / 33
ActionWithValue.h +
95.8%95.8%
+
95.8 %23 / 2487.5 %7 / 8
Value.h +
96.7%96.7%
+
96.7 %59 / 61100.0 %9 / 9
Group.cpp +
98.6%98.6%
+
98.6 %73 / 7475.0 %3 / 4
DataPassingTools.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
PbcAction.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
DomainDecomposition.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
DataPassingObject.h +
100.0%
+
100.0 %4 / 4-0 / 0
ActionToPutData.h +
100.0%
+
100.0 %6 / 6100.0 %6 / 6
ActionRegister.h +
100.0%
+
100.0 %6 / 697.5 %819 / 840
ActionSet.cpp +
100.0%
+
100.0 %10 / 10100.0 %3 / 3
ActionForInterface.cpp +
100.0%
+
100.0 %13 / 1375.0 %3 / 4
ActionPilot.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
ActionWithArguments.h +
100.0%
+
100.0 %16 / 16100.0 %6 / 6
ActionSet.h +
100.0%
+
100.0 %18 / 1891.2 %31 / 34
ActionWithVirtualAtom.h +
100.0%
+
100.0 %22 / 22100.0 %6 / 6
Colvar.h +
100.0%
+
100.0 %24 / 24100.0 %4 / 4
Colvar.cpp +
100.0%
+
100.0 %25 / 2583.3 %5 / 6
PbcAction.cpp +
100.0%
+
100.0 %25 / 2583.3 %5 / 6
ActionAtomistic.h +
100.0%
+
100.0 %46 / 46100.0 %9 / 9
ActionWithVirtualAtom.cpp +
100.0%
+
100.0 %58 / 5885.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/core/index.html b/coverage/core/index.html new file mode 100644 index 000000000000..916c32a0511e --- /dev/null +++ b/coverage/core/index.html @@ -0,0 +1,644 @@ + + + + + + + + LCOV - plumed test coverage - core + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - coreHitTotalCoverage
Test:plumed test coverageLines:3556412386.2 %
Date:2024-02-22 21:58:45Functions:1308142791.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Action.cpp +
81.2%81.2%
+
81.2 %156 / 19283.3 %30 / 36
Action.h +
91.6%91.6%
+
91.6 %76 / 8386.5 %32 / 37
ActionAnyorder.cpp +
50.0%50.0%
+
50.0 %3 / 633.3 %1 / 3
ActionAnyorder.h +
33.3%33.3%
+
33.3 %1 / 30.0 %0 / 2
ActionAtomistic.cpp +
92.6%92.6%
+
92.6 %213 / 23080.0 %20 / 25
ActionAtomistic.h +
100.0%
+
100.0 %46 / 46100.0 %9 / 9
ActionForInterface.cpp +
100.0%
+
100.0 %13 / 1375.0 %3 / 4
ActionForInterface.h +
87.5%87.5%
+
87.5 %7 / 885.7 %6 / 7
ActionPilot.cpp +
100.0%
+
100.0 %15 / 1583.3 %5 / 6
ActionPilot.h +
100.0%
+
100.0 %1 / 1-0 / 0
ActionRegister.cpp +
69.2%69.2%
+
69.2 %45 / 6590.9 %10 / 11
ActionRegister.h +
100.0%
+
100.0 %6 / 697.5 %819 / 840
ActionSet.cpp +
100.0%
+
100.0 %10 / 10100.0 %3 / 3
ActionSet.h +
100.0%
+
100.0 %18 / 1891.2 %31 / 34
ActionSetup.cpp +
90.9%90.9%
+
90.9 %10 / 1166.7 %2 / 3
ActionSetup.h +
33.3%33.3%
+
33.3 %1 / 30.0 %0 / 2
ActionShortcut.cpp +
70.4%70.4%
+
70.4 %19 / 2766.7 %4 / 6
ActionShortcut.h +
0.0%
+
0.0 %0 / 30.0 %0 / 3
ActionToGetData.cpp +
80.0%80.0%
+
80.0 %24 / 3085.7 %6 / 7
ActionToGetData.h +
50.0%50.0%
+
50.0 %1 / 250.0 %1 / 2
ActionToPutData.cpp +
93.1%93.1%
+
93.1 %95 / 102100.0 %17 / 17
ActionToPutData.h +
100.0%
+
100.0 %6 / 6100.0 %6 / 6
ActionWithArguments.cpp +
84.8%84.8%
+
84.8 %151 / 17892.9 %13 / 14
ActionWithArguments.h +
100.0%
+
100.0 %16 / 16100.0 %6 / 6
ActionWithValue.cpp +
91.0%91.0%
+
91.0 %132 / 14583.3 %25 / 30
ActionWithValue.h +
95.8%95.8%
+
95.8 %23 / 2487.5 %7 / 8
ActionWithVirtualAtom.cpp +
100.0%
+
100.0 %58 / 5885.7 %6 / 7
ActionWithVirtualAtom.h +
100.0%
+
100.0 %22 / 22100.0 %6 / 6
CLTool.cpp +
85.9%85.9%
+
85.9 %85 / 9990.0 %9 / 10
CLTool.h +
70.6%70.6%
+
70.6 %24 / 3480.0 %12 / 15
CLToolMain.cpp +
80.7%80.7%
+
80.7 %109 / 135100.0 %5 / 5
CLToolRegister.cpp +
67.2%67.2%
+
67.2 %39 / 5890.0 %9 / 10
Colvar.cpp +
100.0%
+
100.0 %25 / 2583.3 %5 / 6
Colvar.h +
100.0%
+
100.0 %24 / 24100.0 %4 / 4
DataPassingObject.cpp +
85.5%85.5%
+
85.5 %65 / 7648.3 %14 / 29
DataPassingObject.h +
100.0%
+
100.0 %4 / 4-0 / 0
DataPassingTools.cpp +
82.6%82.6%
+
82.6 %19 / 2375.0 %6 / 8
DataPassingTools.h +
100.0%
+
100.0 %1 / 150.0 %1 / 2
DomainDecomposition.cpp +
95.5%95.5%
+
95.5 %254 / 26693.9 %31 / 33
DomainDecomposition.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
ExchangePatterns.cpp +
19.2%19.2%
+
19.2 %5 / 2628.6 %2 / 7
FlexibleBin.cpp +
78.8%78.8%
+
78.8 %115 / 14685.7 %6 / 7
GREX.cpp +
75.2%75.2%
+
75.2 %100 / 133100.0 %6 / 6
GenericMolInfo.cpp +
82.6%82.6%
+
82.6 %181 / 21983.3 %15 / 18
GenericMolInfo.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
Group.cpp +
98.6%98.6%
+
98.6 %73 / 7475.0 %3 / 4
Group.h +
0.0%
+
0.0 %0 / 20.0 %0 / 2
PbcAction.cpp +
100.0%
+
100.0 %25 / 2583.3 %5 / 6
PbcAction.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
PlumedMain.cpp +
90.1%90.1%
+
90.1 %798 / 88694.7 %54 / 57
PlumedMain.h +
88.2%88.2%
+
88.2 %15 / 17-0 / 0
PlumedMainInitializer.cpp +
82.9%82.9%
+
82.9 %223 / 26987.5 %14 / 16
TargetDist.cpp +
0.0%
+
0.0 %0 / 270.0 %0 / 3
Value.cpp +
86.5%86.5%
+
86.5 %128 / 14887.5 %21 / 24
Value.h +
96.7%96.7%
+
96.7 %59 / 61100.0 %9 / 9
WithCmd.h +
64.3%64.3%
+
64.3 %9 / 1450.0 %3 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/BondOrientation.cpp.func-sort-c.html b/coverage/crystallization/BondOrientation.cpp.func-sort-c.html new file mode 100644 index 000000000000..04b9be61aab1 --- /dev/null +++ b/coverage/crystallization/BondOrientation.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/BondOrientation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - BondOrientation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515691.1 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization15BondOrientationC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization15BondOrientationC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization15BondOrientation16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD15crystallization15BondOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE60
_ZNK4PLMD15crystallization15BondOrientation15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/BondOrientation.cpp.func.html b/coverage/crystallization/BondOrientation.cpp.func.html new file mode 100644 index 000000000000..c3cb22a5a942 --- /dev/null +++ b/coverage/crystallization/BondOrientation.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/BondOrientation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - BondOrientation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515691.1 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization15BondOrientation16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD15crystallization15BondOrientationC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization15BondOrientationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization15BondOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE60
_ZNK4PLMD15crystallization15BondOrientation15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/BondOrientation.cpp.gcov.html b/coverage/crystallization/BondOrientation.cpp.gcov.html new file mode 100644 index 000000000000..2c5d704e7a39 --- /dev/null +++ b/coverage/crystallization/BondOrientation.cpp.gcov.html @@ -0,0 +1,212 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/BondOrientation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - BondOrientation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515691.1 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "tools/SwitchingFunction.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "multicolvar/AtomValuePack.h"
+      25             : #include "VectorMultiColvar.h"
+      26             : 
+      27             : //+PLUMEDOC MCOLVAR BOND_DIRECTIONS
+      28             : /*
+      29             : Calculate the vectors connecting atoms that are within cutoff defined using a switching function.
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace crystallization {
+      38             : 
+      39             : class BondOrientation : public VectorMultiColvar {
+      40             : private:
+      41             :   double rcut2;
+      42             :   SwitchingFunction switchingFunction;
+      43             : public:
+      44             :   static void registerKeywords( Keywords& keys );
+      45             :   explicit BondOrientation( const ActionOptions& ao );
+      46             :   double calculateWeight( const unsigned& current, const double& weight, multicolvar::AtomValuePack& myatoms ) const override;
+      47             :   void calculateVector( multicolvar::AtomValuePack& myatoms ) const override;
+      48             : };
+      49             : 
+      50             : PLUMED_REGISTER_ACTION(BondOrientation,"BOND_DIRECTIONS")
+      51             : 
+      52           4 : void BondOrientation::registerKeywords( Keywords& keys ) {
+      53           4 :   VectorMultiColvar::registerKeywords( keys );
+      54           8 :   keys.add("numbered","ATOMS","the atoms involved in each of the vectors you wish to calculate. "
+      55             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one vector will be "
+      56             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+      57             :            "specify the indices of two atoms).  The eventual number of quantities calculated by this "
+      58             :            "action will depend on what functions of the distribution you choose to calculate.");
+      59           8 :   keys.reset_style("ATOMS","atoms");
+      60           8 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+      61           8 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+      62             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+      63           8 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+      64             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+      65           8 :   keys.add("compulsory","NN","12","The n parameter of the switching function ");
+      66           8 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      67           8 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      68           8 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      69           8 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      70             :            "The following provides information on the \\ref switchingfunction that are available. "
+      71             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      72           8 :   keys.use("VMEAN"); keys.use("VSUM");
+      73           4 : }
+      74             : 
+      75           2 : BondOrientation::BondOrientation( const ActionOptions& ao ):
+      76             :   Action(ao),
+      77           2 :   VectorMultiColvar(ao)
+      78             : {
+      79             :   // Read atoms
+      80           2 :   weightHasDerivatives=true;
+      81             :   std::vector<AtomNumber> all_atoms;
+      82           4 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+      83           2 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+      84           2 :   setupMultiColvarBase( all_atoms );
+      85             :   // Read in the switching function
+      86           4 :   std::string sw, errors; parse("SWITCH",sw);
+      87           2 :   if(sw.length()>0) {
+      88           2 :     switchingFunction.set(sw,errors);
+      89             :   } else {
+      90           0 :     double r_0=-1.0, d_0; int nn, mm;
+      91           0 :     parse("NN",nn); parse("MM",mm);
+      92           0 :     parse("R_0",r_0); parse("D_0",d_0);
+      93           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+      94           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+      95             :   }
+      96           2 :   log.printf("  orientation of those bonds with lengths are less than %s\n",( switchingFunction.description() ).c_str() );
+      97             :   // Set the link cell cutoff
+      98           2 :   setLinkCellCutoff( switchingFunction.get_dmax() );
+      99           2 :   double rcut = switchingFunction.get_dmax(); rcut2 = rcut*rcut;
+     100             :   // Set the dimensionality of the vectors
+     101           2 :   setVectorDimensionality(3);
+     102           2 : }
+     103             : 
+     104         150 : double BondOrientation::calculateWeight( const unsigned& current, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+     105         150 :   Vector distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) ); double distm=distance.modulo2();
+     106         150 :   if( distm>rcut2 ) return 0.0;
+     107          60 :   double df, ww=switchingFunction.calculateSqr( distm, df );
+     108             :   // Derivatives of weights
+     109          60 :   addAtomDerivatives( 0, 0, -df*weight*distance, myatoms );
+     110          60 :   addAtomDerivatives( 0, 1, df*weight*distance, myatoms );
+     111          60 :   myatoms.addBoxDerivatives( 0, (-df)*weight*Tensor(distance,distance) );
+     112          60 :   return ww;
+     113             : }
+     114             : 
+     115          60 : void BondOrientation::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
+     116          60 :   Vector distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     117             : 
+     118          60 :   addAtomDerivatives( 2, 0, Vector(-1.0,0,0), myatoms );
+     119          60 :   addAtomDerivatives( 2, 1, Vector(+1.0,0,0), myatoms );
+     120          60 :   myatoms.addBoxDerivatives( 2, Tensor(distance,Vector(-1.0,0,0)) );
+     121          60 :   myatoms.addValue( 2, distance[0] );
+     122             : 
+     123          60 :   addAtomDerivatives( 3, 0, Vector(0,-1.0,0), myatoms );
+     124          60 :   addAtomDerivatives( 3, 1, Vector(0,+1.0,0), myatoms );
+     125          60 :   myatoms.addBoxDerivatives( 3, Tensor(distance,Vector(0,-1.0,0)) );
+     126          60 :   myatoms.addValue( 3, distance[1] );
+     127             : 
+     128          60 :   addAtomDerivatives( 4, 0, Vector(0,0,-1.0), myatoms );
+     129          60 :   addAtomDerivatives( 4, 1, Vector(0,0,+1.0), myatoms );
+     130          60 :   myatoms.addBoxDerivatives( 4, Tensor(distance,Vector(0,0,-1.0)) );
+     131          60 :   myatoms.addValue( 4, distance[2] );
+     132          60 : }
+     133             : 
+     134             : }
+     135             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.cpp.func-sort-c.html b/coverage/crystallization/CubicHarmonicBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..1f08cd8c4578 --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/CubicHarmonicBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - CubicHarmonicBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:747993.7 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17CubicHarmonicBaseC2ERKNS_13ActionOptionsE6
_ZN4PLMD15crystallization17CubicHarmonicBase16registerKeywordsERNS_8KeywordsE12
_ZNK4PLMD15crystallization17CubicHarmonicBase7computeERKjRNS_11multicolvar13AtomValuePackE26142
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.cpp.func.html b/coverage/crystallization/CubicHarmonicBase.cpp.func.html new file mode 100644 index 000000000000..65abf135f3f8 --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/CubicHarmonicBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - CubicHarmonicBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:747993.7 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBase16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD15crystallization17CubicHarmonicBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17CubicHarmonicBaseC2ERKNS_13ActionOptionsE6
_ZNK4PLMD15crystallization17CubicHarmonicBase7computeERKjRNS_11multicolvar13AtomValuePackE26142
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.cpp.gcov.html b/coverage/crystallization/CubicHarmonicBase.cpp.gcov.html new file mode 100644 index 000000000000..153c0b9e92e4 --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/CubicHarmonicBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - CubicHarmonicBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:747993.7 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CubicHarmonicBase.h"
+      23             : #include "tools/SwitchingFunction.h"
+      24             : 
+      25             : #include <string>
+      26             : #include <cmath>
+      27             : 
+      28             : using namespace std;
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace crystallization {
+      32             : 
+      33          12 : void CubicHarmonicBase::registerKeywords( Keywords& keys ) {
+      34          12 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      35          36 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+      36          24 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      37          24 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      38          24 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      39          24 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      40          24 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      41             :            "The following provides information on the \\ref switchingfunction that are available. "
+      42             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      43          24 :   keys.add("compulsory","PHI","0.0","The Euler rotational angle phi");
+      44          24 :   keys.add("compulsory","THETA","0.0","The Euler rotational angle theta");
+      45          24 :   keys.add("compulsory","PSI","0.0","The Euler rotational angle psi");
+      46          24 :   keys.addFlag("UNORMALIZED",false,"calculate the sum of the components of the vector rather than the mean");
+      47             :   // Use actionWithDistributionKeywords
+      48          48 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+      49          48 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      50          36 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      51          12 : }
+      52             : 
+      53           6 : CubicHarmonicBase::CubicHarmonicBase(const ActionOptions&ao):
+      54             :   Action(ao),
+      55           6 :   MultiColvarBase(ao)
+      56             : {
+      57             :   // Read in the switching function
+      58          12 :   std::string sw, errors; parse("SWITCH",sw);
+      59           6 :   if(sw.length()>0) {
+      60           6 :     switchingFunction.set(sw,errors);
+      61           6 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+      62             :   } else {
+      63           0 :     double r_0=-1.0, d_0; int nn, mm;
+      64           0 :     parse("NN",nn); parse("MM",mm);
+      65           0 :     parse("R_0",r_0); parse("D_0",d_0);
+      66           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+      67           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+      68             :   }
+      69             : 
+      70          18 :   double phi, theta, psi; parse("PHI",phi); parse("THETA",theta); parse("PSI",psi);
+      71           6 :   log.printf("  creating rotation matrix with Euler angles phi=%f, theta=%f and psi=%f\n",phi,theta,psi);
+      72             :   // Calculate the rotation matrix http://mathworld.wolfram.com/EulerAngles.html
+      73           6 :   rotationmatrix[0][0]=std::cos(psi)*std::cos(phi)-std::cos(theta)*std::sin(phi)*std::sin(psi);
+      74           6 :   rotationmatrix[0][1]=std::cos(psi)*std::sin(phi)+std::cos(theta)*std::cos(phi)*std::sin(psi);
+      75           6 :   rotationmatrix[0][2]=std::sin(psi)*std::sin(theta);
+      76             : 
+      77           6 :   rotationmatrix[1][0]=-std::sin(psi)*std::cos(phi)-std::cos(theta)*std::sin(phi)*std::cos(psi);
+      78           6 :   rotationmatrix[1][1]=-std::sin(psi)*std::sin(phi)+std::cos(theta)*std::cos(phi)*std::cos(psi);
+      79           6 :   rotationmatrix[1][2]=std::cos(psi)*std::sin(theta);
+      80             : 
+      81           6 :   rotationmatrix[2][0]=std::sin(theta)*std::sin(phi);
+      82           6 :   rotationmatrix[2][1]=-std::sin(theta)*std::cos(phi);
+      83           6 :   rotationmatrix[2][2]=std::cos(theta);
+      84             : 
+      85             : 
+      86           6 :   log.printf("  measure crystallinity around central atom.  Includes those atoms within %s\n",( switchingFunction.description() ).c_str() );
+      87           6 :   parseFlag("UNORMALIZED",unormalized);
+      88           6 :   if( unormalized ) log.printf("  output sum of vector functions \n");
+      89           6 :   else log.printf("  output mean of vector functions \n");
+      90             :   // Set the link cell cutoff
+      91           6 :   rcut2 = switchingFunction.get_dmax()*switchingFunction.get_dmax();
+      92           6 :   setLinkCellCutoff( switchingFunction.get_dmax() );
+      93             :   // And setup the ActionWithVessel
+      94           6 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms );
+      95           6 : }
+      96             : 
+      97       26142 : double CubicHarmonicBase::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+      98       26142 :   double dfunc; Vector rotatedis;
+      99             : 
+     100             :   // Calculate the coordination number
+     101       26142 :   Vector myder, rotateder, fder; unsigned nat=myatoms.getNumberOfAtoms();
+     102             : 
+     103     2517483 :   for(unsigned i=1; i<nat; ++i) {
+     104             :     Vector& distance=myatoms.getPosition(i);
+     105             : 
+     106             :     double d2;
+     107     3953726 :     if ( (d2=distance[0]*distance[0])<rcut2 &&
+     108     1462385 :          (d2+=distance[1]*distance[1])<rcut2 &&
+     109     3193615 :          (d2+=distance[2]*distance[2])<rcut2 &&
+     110             :          d2>epsilon ) {
+     111             : 
+     112      328678 :       double sw = switchingFunction.calculateSqr( d2, dfunc );
+     113             : 
+     114      328678 :       rotatedis[0]=rotationmatrix[0][0]*distance[0]
+     115      328678 :                    +rotationmatrix[0][1]*distance[1]
+     116      328678 :                    +rotationmatrix[0][2]*distance[2];
+     117      328678 :       rotatedis[1]=rotationmatrix[1][0]*distance[0]
+     118      328678 :                    +rotationmatrix[1][1]*distance[1]
+     119      328678 :                    +rotationmatrix[1][2]*distance[2];
+     120      328678 :       rotatedis[2]=rotationmatrix[2][0]*distance[0]
+     121      328678 :                    +rotationmatrix[2][1]*distance[1]
+     122      328678 :                    +rotationmatrix[2][2]*distance[2];
+     123             : 
+     124      328678 :       double tmp = calculateCubicHarmonic( rotatedis, d2, rotateder );
+     125             : 
+     126      328678 :       myder[0]=rotationmatrix[0][0]*rotateder[0]
+     127      328678 :                +rotationmatrix[1][0]*rotateder[1]
+     128      328678 :                +rotationmatrix[2][0]*rotateder[2];
+     129      328678 :       myder[1]=rotationmatrix[0][1]*rotateder[0]
+     130      328678 :                +rotationmatrix[1][1]*rotateder[1]
+     131      328678 :                +rotationmatrix[2][1]*rotateder[2];
+     132      328678 :       myder[2]=rotationmatrix[0][2]*rotateder[0]
+     133      328678 :                +rotationmatrix[1][2]*rotateder[1]
+     134      328678 :                +rotationmatrix[2][2]*rotateder[2];
+     135             : 
+     136      328678 :       fder = (+dfunc)*tmp*distance + sw*myder;
+     137             : 
+     138      328678 :       accumulateSymmetryFunction( 1, i, sw*tmp, fder, Tensor(distance,-fder), myatoms );
+     139      328678 :       accumulateSymmetryFunction( -1, i, sw, (+dfunc)*distance, (-dfunc)*Tensor(distance,distance), myatoms );
+     140             :     }
+     141             :   }
+     142             :   // values -> der of... value [0], weight[1], x coord [2], y, z... [more magic]
+     143       26142 :   updateActiveAtoms( myatoms );
+     144       26142 :   if( !unormalized ) myatoms.getUnderlyingMultiValue().quotientRule( 1, 1 );
+     145       26142 :   return myatoms.getValue(1); // this is equivalent to getting an "atomic" CV
+     146             : }
+     147             : 
+     148             : }
+     149             : }
+     150             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.h.func-sort-c.html b/coverage/crystallization/CubicHarmonicBase.h.func-sort-c.html new file mode 100644 index 000000000000..8b2b85c9b0b8 --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/CubicHarmonicBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - CubicHarmonicBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBase10isPeriodicEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.h.func.html b/coverage/crystallization/CubicHarmonicBase.h.func.html new file mode 100644 index 000000000000..bcac0dfdd444 --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/CubicHarmonicBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - CubicHarmonicBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17CubicHarmonicBase10isPeriodicEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/CubicHarmonicBase.h.gcov.html b/coverage/crystallization/CubicHarmonicBase.h.gcov.html new file mode 100644 index 000000000000..0fb2e6500333 --- /dev/null +++ b/coverage/crystallization/CubicHarmonicBase.h.gcov.html @@ -0,0 +1,128 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/CubicHarmonicBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - CubicHarmonicBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_crystallization_CubicHarmonicBase_h
+      23             : #define __PLUMED_crystallization_CubicHarmonicBase_h
+      24             : 
+      25             : #include "multicolvar/MultiColvarBase.h"
+      26             : #include "multicolvar/AtomValuePack.h"
+      27             : #include "tools/SwitchingFunction.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace crystallization {
+      31             : 
+      32             : class CubicHarmonicBase : public multicolvar::MultiColvarBase {
+      33             : private:
+      34             : //  double nl_cut;
+      35             :   double rcut2;
+      36             :   double rotationmatrix[3][3];
+      37             :   bool unormalized;
+      38             :   SwitchingFunction switchingFunction;
+      39             : public:
+      40             :   static void registerKeywords( Keywords& keys );
+      41             :   explicit CubicHarmonicBase(const ActionOptions&);
+      42             : // active methods:
+      43             :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const ;
+      44             :   virtual double calculateCubicHarmonic( const Vector& distance, const double& d2, Vector& myder ) const = 0;
+      45             : /// Returns the number of coordinates of the field
+      46           7 :   bool isPeriodic() { return false; }
+      47             : };
+      48             : 
+      49             : }
+      50             : }
+      51             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/EnvironmentSimilarity.cpp.func-sort-c.html b/coverage/crystallization/EnvironmentSimilarity.cpp.func-sort-c.html new file mode 100644 index 000000000000..e189ed3edf1e --- /dev/null +++ b/coverage/crystallization/EnvironmentSimilarity.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/EnvironmentSimilarity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - EnvironmentSimilarity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22523994.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization21EnvironmentSimilarityC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization21EnvironmentSimilarity26parseReferenceEnvironmentsERSt6vectorIS2_INS_13VectorGenericILj3EEESaIS4_EESaIS6_EERS2_IS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESaISH_EERd10
_ZN4PLMD15crystallization21EnvironmentSimilarityC1ERKNS_13ActionOptionsE10
_ZN4PLMD15crystallization21EnvironmentSimilarity16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD15crystallization21EnvironmentSimilarity10isPeriodicEv17
_ZN4PLMD15crystallization21EnvironmentSimilarity11maxDistanceERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EE17
_ZNK4PLMD15crystallization21EnvironmentSimilarity7computeERKjRNS_11multicolvar13AtomValuePackE30144
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/EnvironmentSimilarity.cpp.func.html b/coverage/crystallization/EnvironmentSimilarity.cpp.func.html new file mode 100644 index 000000000000..d49f51ffdd97 --- /dev/null +++ b/coverage/crystallization/EnvironmentSimilarity.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/EnvironmentSimilarity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - EnvironmentSimilarity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22523994.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization21EnvironmentSimilarity10isPeriodicEv17
_ZN4PLMD15crystallization21EnvironmentSimilarity11maxDistanceERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EE17
_ZN4PLMD15crystallization21EnvironmentSimilarity16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD15crystallization21EnvironmentSimilarity26parseReferenceEnvironmentsERSt6vectorIS2_INS_13VectorGenericILj3EEESaIS4_EESaIS6_EERS2_IS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESaISH_EERd10
_ZN4PLMD15crystallization21EnvironmentSimilarityC1ERKNS_13ActionOptionsE10
_ZN4PLMD15crystallization21EnvironmentSimilarityC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization21EnvironmentSimilarity7computeERKjRNS_11multicolvar13AtomValuePackE30144
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/EnvironmentSimilarity.cpp.gcov.html b/coverage/crystallization/EnvironmentSimilarity.cpp.gcov.html new file mode 100644 index 000000000000..ef558b2c5614 --- /dev/null +++ b/coverage/crystallization/EnvironmentSimilarity.cpp.gcov.html @@ -0,0 +1,645 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/EnvironmentSimilarity.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - EnvironmentSimilarity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22523994.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /* ----------------------------------------------------------------------
+      24             :    Contributing author: Pablo Piaggi (Princeton University)
+      25             : ------------------------------------------------------------------------- */
+      26             : 
+      27             : #include "multicolvar/MultiColvarBase.h"
+      28             : #include "multicolvar/AtomValuePack.h"
+      29             : #include "core/ActionRegister.h"
+      30             : #include "core/PlumedMain.h"
+      31             : #include "tools/PDB.h"
+      32             : #include <limits>
+      33             : 
+      34             : using namespace std;
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace crystallization {
+      38             : 
+      39             : 
+      40             : //+PLUMEDOC MCOLVAR ENVIRONMENTSIMILARITY
+      41             : /*
+      42             : Measure how similar the environment around atoms is to that found in some reference crystal structure.
+      43             : 
+      44             : This CV was introduced in this article \cite Piaggi-JCP-2019.
+      45             : The starting point for the definition of the CV is the local atomic density around an atom.
+      46             : We consider an environment \f$\chi\f$ around this atom and we define the density by
+      47             : \f[
+      48             :  \rho_{\chi}(\mathbf{r})=\sum\limits_{i\in\chi} \exp\left(- \frac{|\mathbf{r}_i-\mathbf{r}|^2} {2\sigma^2} \right),
+      49             : \f]
+      50             : where \f$i\f$ runs over the neighbors in the environment \f$\chi\f$, \f$\sigma\f$ is a broadening parameter, and \f$\mathbf{r}_i\f$ are the
+      51             : coordinates of the neighbors relative to the central atom.
+      52             : We now define a reference environment or template \f$\chi_0\f$ that contains \f$n\f$ reference positions \f$\{\mathbf{r}^0_1,...,\mathbf{r}^0_n\}\f$
+      53             : that describe, for instance, the nearest neighbors in a given lattice.
+      54             : \f$\sigma\f$ is set using the SIGMA keyword and \f$\chi_0\f$ is chosen with the CRYSTAL_STRUCTURE keyword.
+      55             : If only the SPECIES keyword is given then the atoms defined there will be the central and neighboring atoms.
+      56             : If instead the SPECIESA and SPECIESB keywords are given then SPECIESA determines the central atoms and SPECIESB the neighbors.
+      57             : 
+      58             : The environments \f$\chi\f$ and \f$\chi_0\f$ are compared using the kernel,
+      59             : \f[
+      60             :  k_{\chi_0}(\chi)= \int d\mathbf{r} \rho_{\chi}(\mathbf{r}) \rho_{\chi_0}(\mathbf{r}) .
+      61             : \f]
+      62             : Combining the two equations above and performing the integration analytically we obtain,
+      63             : \f[
+      64             :  k_{\chi_0}(\chi)= \sum\limits_{i\in\chi} \sum\limits_{j\in\chi_0} \pi^{3/2} \sigma^3  \exp\left(- \frac{|\mathbf{r}_i-\mathbf{r}^0_j|^2} {4\sigma^2} \right).
+      65             : \f]
+      66             : The kernel is finally normalized,
+      67             : \f[
+      68             :  \tilde{k}_{\chi_0}(\chi)  = \frac{1}{n} \sum\limits_{i\in\chi} \sum\limits_{j\in\chi_0} \exp\left( - \frac{|\mathbf{r}_i-\mathbf{r}^0_j|^2} {4\sigma^2} \right),
+      69             : \f]
+      70             : such that \f$\tilde{k}_{\chi_0}(\chi_0) = 1\f$.
+      71             : The above kernel is computed for each atom in the SPECIES or SPECIESA keywords.
+      72             : This quantity is a multicolvar so you can compute it for multiple atoms using a single PLUMED action and then compute
+      73             : the average value for the atoms in your system, the number of atoms that have an \f$\tilde{k}_{\chi_0}\f$ value that is more that some target and
+      74             : so on.
+      75             : 
+      76             : The kernel can be generalized to crystal structures described as a lattice with a basis of more than one atom.
+      77             : In this case there is more than one type of environment.
+      78             : We consider the case of \f$M\f$ environments \f$X = \chi_1,\chi_2,...,\chi_M\f$ and we define the kernel through a best match strategy:
+      79             : \f[
+      80             :  \tilde{k}_X(\chi)= \frac{1}{\lambda} \log \left ( \sum\limits_{l=1}^{M}\exp \left (\lambda \: \tilde{k}_{\chi_l}(\chi) \right ) \right ).
+      81             : \f]
+      82             : For a large enough \f$\lambda\f$ this expression will select the largest \f$\tilde{k}_{\chi_l}(\chi)\f$ with \f$\chi_l \in X\f$.
+      83             : This approach can be used, for instance, to target the hexagonal closed packed (HCP keyword) or the diamond structure (DIAMOND keyword).
+      84             : 
+      85             : The CRYSTAL_STRUCTURE keyword can take the values SC (simple cubic), BCC (body centered cubic), FCC (face centered cubic),
+      86             : HCP (hexagonal closed pack), DIAMOND (cubic diamond), and CUSTOM (user defined).
+      87             : All options follow the same conventions as in the [lattice command](https://lammps.sandia.gov/doc/lattice.html) of [LAMMPS](https://lammps.sandia.gov/).
+      88             : If a CRYSTAL_STRUCTURE other than CUSTOM is used, then the lattice constants have to be specified using the keyword LATTICE_CONSTANTS.
+      89             : One value has to be specified for SC, BCC, FCC, and DIAMOND and two values have to be set for HCP (a and c lattice constants in that order).
+      90             : 
+      91             : If the CUSTOM option is used then the reference environments have to be specified by the user.
+      92             : The reference environments are specified in pdb files containing the distance vectors from the central atom to the neighbors.
+      93             : Make sure your PDB file is correctly formatted as explained \ref pdbreader "in this page"
+      94             : If only one reference environment is specified then the filename should be given as argument of the keyword REFERENCE.
+      95             : If instead several reference environments are given, then they have to be provided in separate pdb files and given as arguments of the
+      96             : keywords REFERENCE_1, REFERENCE_2, etc.
+      97             : If you have a reference crystal structure configuration you can use the [Environment Finder](https://github.com/PabloPiaggi/EnvironmentFinder) app to determine the reference environments that you should use.
+      98             : 
+      99             : If multiple chemical species are involved in the calculation, it is possible to provide the atom types (names) both for atoms in the reference environments and in the simulation box.
+     100             : This information is provided in pdb files using the atom name field.
+     101             : The comparison between environments is performed taking into account whether the atom names match.
+     102             : 
+     103             : \par Examples
+     104             : 
+     105             : The following input calculates the ENVIRONMENTSIMILARITY kernel for 250 atoms in the system
+     106             : using the BCC atomic environment as target, and then calculates and prints the average value
+     107             :  for this quantity.
+     108             : 
+     109             : \plumedfile
+     110             : ENVIRONMENTSIMILARITY SPECIES=1-250 SIGMA=0.05 LATTICE_CONSTANTS=0.423 CRYSTAL_STRUCTURE=BCC MEAN LABEL=es
+     111             : 
+     112             : PRINT ARG=es.mean FILE=COLVAR
+     113             : \endplumedfile
+     114             : 
+     115             : The next example compares the environments of the 96 selected atoms with a user specified reference
+     116             : environment. The reference environment is contained in the env1.pdb file. Once the kernel is computed
+     117             :  the average and the number of atoms with a kernel larger than 0.5 are computed.
+     118             : 
+     119             : \plumedfile
+     120             : ENVIRONMENTSIMILARITY ...
+     121             :  SPECIES=1-288:3
+     122             :  SIGMA=0.05
+     123             :  CRYSTAL_STRUCTURE=CUSTOM
+     124             :  REFERENCE=env1.pdb
+     125             :  LABEL=es
+     126             :  MEAN
+     127             :  MORE_THAN={RATIONAL R_0=0.5 NN=12 MM=24}
+     128             : ... ENVIRONMENTSIMILARITY
+     129             : 
+     130             : PRINT ARG=es.mean,es.morethan FILE=COLVAR
+     131             : \endplumedfile
+     132             : 
+     133             : The next example is similar to the one above but in this case 4 reference environments are specified.
+     134             :  Each reference environment is given in a separate pdb file.
+     135             : 
+     136             : \plumedfile
+     137             : ENVIRONMENTSIMILARITY ...
+     138             :  SPECIES=1-288:3
+     139             :  SIGMA=0.05
+     140             :  CRYSTAL_STRUCTURE=CUSTOM
+     141             :  REFERENCE_1=env1.pdb
+     142             :  REFERENCE_2=env2.pdb
+     143             :  REFERENCE_3=env3.pdb
+     144             :  REFERENCE_4=env4.pdb
+     145             :  LABEL=es
+     146             :  MEAN
+     147             :  MORE_THAN={RATIONAL R_0=0.5 NN=12 MM=24}
+     148             : ... ENVIRONMENTSIMILARITY
+     149             : 
+     150             : PRINT ARG=es.mean,es.morethan FILE=COLVAR
+     151             : \endplumedfile
+     152             : 
+     153             : The following examples illustrates the use of pdb files to provide information about different chemical species:
+     154             : \plumedfile
+     155             : ENVIRONMENTSIMILARITY ...
+     156             :  SPECIES=1-6
+     157             :  SIGMA=0.05
+     158             :  CRYSTAL_STRUCTURE=CUSTOM
+     159             :  REFERENCE=env.pdb
+     160             :  LABEL=es
+     161             :  MEAN
+     162             :  MORE_THAN={RATIONAL R_0=0.5 NN=12 MM=24}
+     163             :  ATOM_NAMES_FILE=atom-names.pdb
+     164             : ... ENVIRONMENTSIMILARITY
+     165             : \endplumedfile
+     166             : Here the file env.pdb is:
+     167             : \verbatim
+     168             : ATOM      1    O MOL     1      -2.239  -1.296  -0.917  1.00  0.00           O
+     169             : ATOM      2    O MOL     1       0.000   0.000   2.751  1.00  0.00           O
+     170             : \endverbatim
+     171             : where atoms are of type O, and the atom-names.pdb file is:
+     172             : \verbatim
+     173             : ATOM      1  O       X   1       0.000   2.593   4.126  0.00  0.00           O
+     174             : ATOM      2  H       X   1       0.000   3.509   3.847  0.00  0.00           H
+     175             : ATOM      3  H       X   1       0.000   2.635   5.083  0.00  0.00           H
+     176             : ATOM      4  O       X   1       0.000   2.593  11.462  0.00  0.00           O
+     177             : ATOM      5  H       X   1       0.000   3.509  11.183  0.00  0.00           H
+     178             : ATOM      6  H       X   1       0.000   2.635  12.419  0.00  0.00           H
+     179             : \endverbatim
+     180             : where atoms are of type O and H.
+     181             : In this case, all atoms are used as centers, but only neighbors of type O are taken into account.
+     182             : 
+     183             : */
+     184             : //+ENDPLUMEDOC
+     185             : 
+     186             : 
+     187             : class EnvironmentSimilarity : public multicolvar::MultiColvarBase {
+     188             : private:
+     189             :   // All global variables end with underscore
+     190             :   // square of cutoff, square of broadening parameter
+     191             :   double rcut2_, sigmaSqr_;
+     192             :   // lambda parameter for softmax function
+     193             :   double lambda_;
+     194             :   // Array of Vectors to store the reference environments, i.e. the templates
+     195             :   std::vector<std::vector<Vector>> environments_;
+     196             :   // Array of strings to store the atom names of reference environments
+     197             :   std::vector<std::vector<std::string>> environmentsAtomNames_;
+     198             :   // Use of atom names reference file
+     199             :   std::vector<std::string> atomNames_;
+     200             : public:
+     201             :   static void registerKeywords( Keywords& keys );
+     202             :   explicit EnvironmentSimilarity(const ActionOptions&);
+     203             : // active methods:
+     204             :   virtual double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const ;
+     205             : // Returns the number of coordinates of the field
+     206          17 :   bool isPeriodic() { return false; }
+     207             : // Calculates maximum distance in an environment
+     208             :   double maxDistance(const std::vector<Vector> & environment);
+     209             :   // Parse everything connected to the definition of the reference environments
+     210             :   // First argument is the array of Vectors that stores the reference environments
+     211             :   // Second argument is the array of strings that stores the atom names of reference environments
+     212             :   // Third argument is the maximum distance in the ref environments and sets the
+     213             :   // cutoff for the cell lists
+     214             :   void parseReferenceEnvironments( std::vector<std::vector<Vector>>& environments,  std::vector<std::vector<std::string>>& environmentsAtomNames, double& max_dist);
+     215             : };
+     216             : 
+     217             : PLUMED_REGISTER_ACTION(EnvironmentSimilarity,"ENVIRONMENTSIMILARITY")
+     218             : 
+     219          12 : void EnvironmentSimilarity::registerKeywords( Keywords& keys ) {
+     220          12 :   MultiColvarBase::registerKeywords( keys );
+     221          36 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+     222          24 :   keys.add("compulsory","SIGMA","0.1","Broadening parameter");
+     223          24 :   keys.add("compulsory","CRYSTAL_STRUCTURE","FCC","Targeted crystal structure. Options are: "
+     224             :            "SC: simple cubic, "
+     225             :            "BCC: body center cubic, "
+     226             :            "FCC: face centered cubic, "
+     227             :            "HCP: hexagonal closed pack, "
+     228             :            "DIAMOND: cubic diamond, "
+     229             :            "CUSTOM: user defined "
+     230             :            " ");
+     231          24 :   keys.add("optional","LATTICE_CONSTANTS","Lattice constants. Two comma separated values for HCP, "
+     232             :            "one value for all other CRYSTAL_STRUCTURES.");
+     233          24 :   keys.add("compulsory","LAMBDA","100","Lambda parameter");
+     234          24 :   keys.add("optional","REFERENCE","PDB file with relative distances from central atom."
+     235             :            " Use this keyword if you are targeting a single reference environment.");
+     236          24 :   keys.add("numbered","REFERENCE_","PDB files with relative distances from central atom."
+     237             :            " Each file corresponds to one template."
+     238             :            " Use these keywords if you are targeting more than one reference environment.");
+     239          24 :   keys.add("optional","ATOM_NAMES_FILE","PDB file with atom names for all atoms in SPECIES."
+     240             :            " Atoms in reference environments will be compared only if atom names match.");
+     241             :   // Use actionWithDistributionKeywords
+     242          48 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+     243          48 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     244          36 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     245          12 : }
+     246             : 
+     247          10 : EnvironmentSimilarity::EnvironmentSimilarity(const ActionOptions&ao):
+     248             :   Action(ao),
+     249          10 :   MultiColvarBase(ao)
+     250             : {
+     251          10 :   log.printf("  Please read and cite ");
+     252          20 :   log << plumed.cite("Piaggi and Parrinello, J. Chem. Phys. 150 (24), 244119 (2019)");
+     253          10 :   log.printf("\n");
+     254             : 
+     255             :   // Parse everything connected to the definition of the reference environments
+     256             :   double max_dist_ref_vector;
+     257          10 :   parseReferenceEnvironments(environments_, environmentsAtomNames_, max_dist_ref_vector);
+     258             : 
+     259             :   double sigma;
+     260          10 :   parse("SIGMA", sigma);
+     261          10 :   log.printf("  representing local density as a sum of Gaussians with standard deviation %f\n",sigma);
+     262          10 :   sigmaSqr_=sigma*sigma;
+     263             : 
+     264          10 :   lambda_=100;
+     265          20 :   parse("LAMBDA", lambda_);
+     266          10 :   if (environments_.size()>1) log.printf("  using a soft max function with lambda %f\n",lambda_);
+     267             : 
+     268             :   // Set the link cell cutoff
+     269          10 :   double rcut = max_dist_ref_vector + 3*sigma;
+     270          10 :   setLinkCellCutoff( rcut );
+     271          10 :   rcut2_ = rcut * rcut;
+     272             : 
+     273             :   // And setup the ActionWithVessel
+     274          10 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms ); checkRead();
+     275             : 
+     276          10 :   plumed_massert(atomNames_.empty() || atomNames_.size()==getNumberOfAtoms(),"mismatch between atoms in SPECIES and ATOM_NAMES_FILE");
+     277          10 : }
+     278             : 
+     279       30144 : double EnvironmentSimilarity::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     280       30144 :   if (environments_.size()==1 && atomNames_.empty() ) {
+     281             :     // One reference environment case - no atom names
+     282      155464 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     283             :       const Vector& distance=myatoms.getPosition(i);
+     284             :       double d2;
+     285      232452 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     286       77840 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     287      194068 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     288             :            d2>epsilon ) {
+     289             :         // Iterate over atoms in the reference environment
+     290      236856 :         for(unsigned k=0; k<environments_[0].size(); ++k) {
+     291      220400 :           Vector distanceFromRef=distance-environments_[0][k];
+     292      220400 :           double value = std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[0].size() ;
+     293      220400 :           accumulateSymmetryFunction( 1, i, value, -(value/(2*sigmaSqr_))*distanceFromRef, (value/(2*sigmaSqr_))*Tensor(distance,distanceFromRef), myatoms );
+     294             :         }
+     295             :       }
+     296             :     }
+     297             :     return myatoms.getValue(1);
+     298       29292 :   } else if (atomNames_.empty()) {
+     299             :     // More than one reference environment case - no atom names
+     300       29196 :     std::vector<double> values(environments_.size()); //value for each template
+     301             :     // First time calculate sums
+     302     2808756 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     303             :       const Vector& distance=myatoms.getPosition(i);
+     304             :       double d2;
+     305     4534472 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     306     1754912 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     307     3469608 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     308             :            d2>epsilon ) {
+     309             :         // Iterate over templates
+     310     1216388 :         for(unsigned j=0; j<environments_.size(); ++j) {
+     311             :           // Iterate over atoms in the template
+     312     4893780 :           for(unsigned k=0; k<environments_[j].size(); ++k) {
+     313     3921936 :             Vector distanceFromRef=distance-environments_[j][k];
+     314     3921936 :             values[j] += std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[j].size() ;
+     315             :           }
+     316             :         }
+     317             :       }
+     318             :     }
+     319             :     double sum=0;
+     320      145188 :     for(unsigned j=0; j<environments_.size(); ++j) {
+     321      115992 :       values[j] = std::exp(lambda_*values[j]);
+     322      115992 :       sum += values[j];
+     323             :     }
+     324             :     // Second time find derivatives
+     325     2808756 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     326             :       const Vector& distance=myatoms.getPosition(i);
+     327             :       double d2;
+     328     4534472 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     329     1754912 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     330     3469608 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     331             :            d2>epsilon ) {
+     332             :         // Iterate over reference environment
+     333     1216388 :         for(unsigned j=0; j<environments_.size(); ++j) {
+     334             :           // Iterate over atoms in the reference environment
+     335     4893780 :           for(unsigned k=0; k<environments_[j].size(); ++k) {
+     336     3921936 :             Vector distanceFromRef=distance-environments_[j][k];
+     337     3921936 :             double value = std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[j].size() ;
+     338     3921936 :             accumulateSymmetryFunction( 1, i, value, -(values[j]/sum)*(value/(2*sigmaSqr_))*distanceFromRef, (values[j]/sum)*(value/(2*sigmaSqr_))*Tensor(distance,distanceFromRef), myatoms );
+     339             :           }
+     340             :         }
+     341             :       }
+     342             :     }
+     343       29196 :     return std::log(sum)/lambda_;
+     344             :   } else {
+     345             :     // Reference environments with atom names
+     346          96 :     std::vector<double> values(environments_.size()); //value for each template
+     347             :     // First time calculate sums
+     348       27648 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     349             :       const Vector& distance=myatoms.getPosition(i);
+     350             :       double d2;
+     351       42816 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     352       15264 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     353       33216 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     354             :            d2>epsilon ) {
+     355             :         // Iterate over templates
+     356        9600 :         for(unsigned j=0; j<environments_.size(); ++j) {
+     357             :           // Iterate over atoms in the template
+     358       38400 :           for(unsigned k=0; k<environments_[j].size(); ++k) {
+     359       30720 :             if (atomNames_[myatoms.getIndex(i)]==environmentsAtomNames_[j][k]) {
+     360        6144 :               Vector distanceFromRef=distance-environments_[j][k];
+     361        6144 :               values[j] += std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[j].size() ;
+     362             :             }
+     363             :           }
+     364             :         }
+     365             :       }
+     366             :     }
+     367             :     double sum=0;
+     368         480 :     for(unsigned j=0; j<environments_.size(); ++j) {
+     369         384 :       values[j] = std::exp(lambda_*values[j]);
+     370         384 :       sum += values[j];
+     371             :     }
+     372             :     // Second time find derivatives
+     373       27648 :     for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     374             :       const Vector& distance=myatoms.getPosition(i);
+     375             :       double d2;
+     376       42816 :       if ( (d2=distance[0]*distance[0])<rcut2_ &&
+     377       15264 :            (d2+=distance[1]*distance[1])<rcut2_ &&
+     378       33216 :            (d2+=distance[2]*distance[2])<rcut2_ &&
+     379             :            d2>epsilon ) {
+     380             :         // Iterate over reference environment
+     381        9600 :         for(unsigned j=0; j<environments_.size(); ++j) {
+     382             :           // Iterate over atoms in the reference environment
+     383       38400 :           for(unsigned k=0; k<environments_[j].size(); ++k) {
+     384       30720 :             if (atomNames_[myatoms.getIndex(i)]==environmentsAtomNames_[j][k]) {
+     385        6144 :               Vector distanceFromRef=distance-environments_[j][k];
+     386        6144 :               double value = std::exp(-distanceFromRef.modulo2()/(4*sigmaSqr_) )/environments_[j].size() ;
+     387        6144 :               accumulateSymmetryFunction( 1, i, value, -(values[j]/sum)*(value/(2*sigmaSqr_))*distanceFromRef, (values[j]/sum)*(value/(2*sigmaSqr_))*Tensor(distance,distanceFromRef), myatoms );
+     388             :             }
+     389             :           }
+     390             :         }
+     391             :       }
+     392             :     }
+     393          96 :     return std::log(sum)/lambda_;
+     394             :   }
+     395             : }
+     396             : 
+     397          17 : double EnvironmentSimilarity::maxDistance( const std::vector<Vector> & environment ) {
+     398             :   double max_dist = 0.0;
+     399          85 :   for(unsigned i=0; i<environment.size(); ++i) {
+     400          68 :     double norm=environment[i].modulo();
+     401          68 :     if (norm>max_dist) max_dist=norm;
+     402             :   }
+     403          17 :   return max_dist;
+     404             : }
+     405             : 
+     406          10 : void EnvironmentSimilarity::parseReferenceEnvironments( std::vector<std::vector<Vector>>& environments, std::vector<std::vector<std::string>>& environmentsAtomNames, double& max_dist) {
+     407             :   std::vector<double> lattice_constants;
+     408          20 :   parseVector("LATTICE_CONSTANTS", lattice_constants);
+     409             :   std::string crystal_structure;
+     410          20 :   parse("CRYSTAL_STRUCTURE", crystal_structure);
+     411             :   // find crystal structure
+     412          10 :   if (crystal_structure == "FCC") {
+     413           1 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for FCC");
+     414           1 :     environments.resize(1);
+     415           1 :     environments[0].resize(12);
+     416           1 :     environments[0][0]  = Vector(+0.5,+0.5,+0.0)*lattice_constants[0];
+     417           1 :     environments[0][1]  = Vector(-0.5,-0.5,+0.0)*lattice_constants[0];
+     418           1 :     environments[0][2]  = Vector(+0.5,-0.5,+0.0)*lattice_constants[0];
+     419           1 :     environments[0][3]  = Vector(-0.5,+0.5,+0.0)*lattice_constants[0];
+     420           1 :     environments[0][4]  = Vector(+0.5,+0.0,+0.5)*lattice_constants[0];
+     421           1 :     environments[0][5]  = Vector(-0.5,+0.0,-0.5)*lattice_constants[0];
+     422           1 :     environments[0][6]  = Vector(-0.5,+0.0,+0.5)*lattice_constants[0];
+     423           1 :     environments[0][7]  = Vector(+0.5,+0.0,-0.5)*lattice_constants[0];
+     424           1 :     environments[0][8]  = Vector(+0.0,+0.5,+0.5)*lattice_constants[0];
+     425           1 :     environments[0][9]  = Vector(+0.0,-0.5,-0.5)*lattice_constants[0];
+     426           1 :     environments[0][10] = Vector(+0.0,-0.5,+0.5)*lattice_constants[0];
+     427           1 :     environments[0][11] = Vector(+0.0,+0.5,-0.5)*lattice_constants[0];
+     428           1 :     max_dist = std::sqrt(2)*lattice_constants[0]/2.;
+     429           9 :   } else if (crystal_structure == "SC") {
+     430           0 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for SC");
+     431           0 :     environments.resize(1);
+     432           0 :     environments[0].resize(6);
+     433           0 :     environments[0][0]  = Vector(+1.0,+0.0,+0.0)*lattice_constants[0];
+     434           0 :     environments[0][1]  = Vector(-1.0,+0.0,+0.0)*lattice_constants[0];
+     435           0 :     environments[0][2]  = Vector(+0.0,+1.0,+0.0)*lattice_constants[0];
+     436           0 :     environments[0][3]  = Vector(+0.0,-1.0,+0.0)*lattice_constants[0];
+     437           0 :     environments[0][4]  = Vector(+0.0,+0.0,+1.0)*lattice_constants[0];
+     438           0 :     environments[0][5]  = Vector(+0.0,+0.0,-1.0)*lattice_constants[0];
+     439           0 :     max_dist = lattice_constants[0];
+     440           9 :   } else if (crystal_structure == "BCC") {
+     441           2 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for BCC");
+     442           2 :     environments.resize(1);
+     443           2 :     environments[0].resize(14);
+     444           2 :     environments[0][0]  = Vector(+0.5,+0.5,+0.5)*lattice_constants[0];
+     445           2 :     environments[0][1]  = Vector(-0.5,-0.5,-0.5)*lattice_constants[0];
+     446           2 :     environments[0][2]  = Vector(-0.5,+0.5,+0.5)*lattice_constants[0];
+     447           2 :     environments[0][3]  = Vector(+0.5,-0.5,+0.5)*lattice_constants[0];
+     448           2 :     environments[0][4]  = Vector(+0.5,+0.5,-0.5)*lattice_constants[0];
+     449           2 :     environments[0][5]  = Vector(-0.5,-0.5,+0.5)*lattice_constants[0];
+     450           2 :     environments[0][6]  = Vector(+0.5,-0.5,-0.5)*lattice_constants[0];
+     451           2 :     environments[0][7]  = Vector(-0.5,+0.5,-0.5)*lattice_constants[0];
+     452           2 :     environments[0][8]  = Vector(+1.0,+0.0,+0.0)*lattice_constants[0];
+     453           2 :     environments[0][9]  = Vector(+0.0,+1.0,+0.0)*lattice_constants[0];
+     454           2 :     environments[0][10] = Vector(+0.0,+0.0,+1.0)*lattice_constants[0];
+     455           2 :     environments[0][11] = Vector(-1.0,+0.0,+0.0)*lattice_constants[0];
+     456           2 :     environments[0][12] = Vector(+0.0,-1.0,+0.0)*lattice_constants[0];
+     457           2 :     environments[0][13] = Vector(+0.0,+0.0,-1.0)*lattice_constants[0];
+     458           2 :     max_dist = lattice_constants[0];
+     459           7 :   } else if (crystal_structure == "HCP") {
+     460           1 :     if (lattice_constants.size() != 2) error("Number of LATTICE_CONSTANTS arguments must be two for HCP");
+     461           1 :     environments.resize(2);
+     462           1 :     environments[0].resize(12);
+     463           1 :     environments[1].resize(12);
+     464             :     double sqrt3=std::sqrt(3);
+     465           1 :     environments[0][0]  = Vector(+0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     466           1 :     environments[0][1]  = Vector(-0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     467           1 :     environments[0][2]  = Vector(+0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     468           1 :     environments[0][3]  = Vector(-0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     469           1 :     environments[0][4]  = Vector(+1.0,+0.0,+0.0)      *lattice_constants[0];
+     470           1 :     environments[0][5]  = Vector(-1.0,+0.0,+0.0)      *lattice_constants[0];
+     471           1 :     environments[0][6]  = Vector(+0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     472           1 :     environments[0][7]  = Vector(-0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     473           1 :     environments[0][8]  = Vector(+0.0,-sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     474           1 :     environments[0][9]  = Vector(+0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     475           1 :     environments[0][10] = Vector(-0.5,+sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     476           1 :     environments[0][11] = Vector(+0.0,-sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     477           1 :     environments[1][0]  = Vector(+0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     478           1 :     environments[1][1]  = Vector(-0.5,+sqrt3/2.0,+0.0)*lattice_constants[0];
+     479           1 :     environments[1][2]  = Vector(+0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     480           1 :     environments[1][3]  = Vector(-0.5,-sqrt3/2.0,+0.0)*lattice_constants[0];
+     481           1 :     environments[1][4]  = Vector(+1.0,+0.0,+0.0)      *lattice_constants[0];
+     482           1 :     environments[1][5]  = Vector(-1.0,+0.0,+0.0)      *lattice_constants[0];
+     483           1 :     environments[1][6]  = Vector(+0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     484           1 :     environments[1][7]  = Vector(-0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     485           1 :     environments[1][8]  = Vector(+0.0,+sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,+0.5)*lattice_constants[1];
+     486           1 :     environments[1][9]  = Vector(+0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     487           1 :     environments[1][10] = Vector(-0.5,-sqrt3/6.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     488           1 :     environments[1][11] = Vector(+0.0,+sqrt3/3.0,+0.0)*lattice_constants[0] + Vector(+0.0,+0.0,-0.5)*lattice_constants[1];
+     489           1 :     max_dist = lattice_constants[0];
+     490           6 :   } else if (crystal_structure == "DIAMOND") {
+     491           1 :     if (lattice_constants.size() != 1) error("Number of LATTICE_CONSTANTS arguments must be one for DIAMOND");
+     492           1 :     environments.resize(2);
+     493           1 :     environments[0].resize(4); environments[1].resize(4);
+     494           1 :     environments[0][0]  = Vector(+1.0,+1.0,+1.0)*lattice_constants[0]/4.0;
+     495           1 :     environments[0][1]  = Vector(-1.0,-1.0,+1.0)*lattice_constants[0]/4.0;
+     496           1 :     environments[0][2]  = Vector(+1.0,-1.0,-1.0)*lattice_constants[0]/4.0;
+     497           1 :     environments[0][3]  = Vector(-1.0,+1.0,-1.0)*lattice_constants[0]/4.0;
+     498           1 :     environments[1][0]  = Vector(+1.0,-1.0,+1.0)*lattice_constants[0]/4.0;
+     499           1 :     environments[1][1]  = Vector(-1.0,+1.0,+1.0)*lattice_constants[0]/4.0;
+     500           1 :     environments[1][2]  = Vector(+1.0,+1.0,-1.0)*lattice_constants[0]/4.0;
+     501           1 :     environments[1][3]  = Vector(-1.0,-1.0,-1.0)*lattice_constants[0]/4.0;
+     502           1 :     max_dist = std::sqrt(3)*lattice_constants[0]/4.0;
+     503           5 :   } else if (crystal_structure == "CUSTOM") {
+     504             :     std::string reffile;
+     505          10 :     parse("REFERENCE",reffile);
+     506           5 :     if (!reffile.empty()) {
+     507             :       // Case with one reference environment
+     508           1 :       environments.resize(1); environmentsAtomNames.resize(1);
+     509           1 :       PDB pdb;
+     510           1 :       if( !pdb.read(reffile,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     511           0 :         error("missing input file " + reffile );
+     512           1 :       unsigned natoms=pdb.getPositions().size();
+     513           1 :       environments[0].resize( natoms ); environmentsAtomNames[0].resize( natoms );
+     514           5 :       for(unsigned i=0; i<natoms; ++i) environments[0][i]=pdb.getPositions()[i];
+     515           5 :       for(unsigned i=0; i<natoms; ++i) environmentsAtomNames[0][i]=pdb.getAtomName(pdb.getAtomNumbers()[i]);
+     516           1 :       max_dist=maxDistance(environments[0]);
+     517           1 :       log.printf("  reading %d reference vectors from %s \n", natoms, reffile.c_str() );
+     518           1 :     } else {
+     519             :       // Case with several reference environments
+     520           4 :       max_dist=0;
+     521          16 :       for(unsigned int i=1;; i++) {
+     522          40 :         if(!parseNumbered("REFERENCE_",i,reffile) ) {break;}
+     523          16 :         PDB pdb;
+     524          16 :         if( !pdb.read(reffile,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     525           0 :           error("missing input file " + reffile );
+     526          16 :         unsigned natoms=pdb.getPositions().size();
+     527             :         std::vector<Vector> environment; std::vector<std::string> environmentAtomNames;
+     528          16 :         environment.resize( natoms ); environmentAtomNames.resize( natoms);
+     529          80 :         for(unsigned i=0; i<natoms; ++i) environment[i]=pdb.getPositions()[i];
+     530          80 :         for(unsigned i=0; i<natoms; ++i) environmentAtomNames[i]=pdb.getAtomName(pdb.getAtomNumbers()[i]);
+     531          16 :         environments.push_back(environment);
+     532          16 :         environmentsAtomNames.push_back(environmentAtomNames);
+     533          16 :         double norm = maxDistance(environment);
+     534          16 :         if (norm>max_dist) max_dist=norm;
+     535          16 :         log.printf("  Reference environment %d : reading %d reference vectors from %s \n", i, natoms, reffile.c_str() );
+     536          32 :       }
+     537             :     }
+     538           5 :     if (environments.size()==0) error("No environments have been found! Please specify a PDB file in the REFERENCE "
+     539             :                                         "or in the REFERENCE_1, REFERENCE_2, etc keywords");
+     540           5 :     log.printf("  Number of reference environments is %lu\n",environments.size() );
+     541           5 :     log.printf("  Number of vectors per reference environment is %lu\n",environments[0].size() );
+     542             :     std::string atomNamesFile;
+     543          10 :     parse("ATOM_NAMES_FILE",atomNamesFile);
+     544           5 :     if (!atomNamesFile.empty()) {
+     545           1 :       PDB pdb;
+     546           1 :       if( !pdb.read(atomNamesFile,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     547           0 :         error("missing input file " + atomNamesFile);
+     548           1 :       unsigned natoms=pdb.getPositions().size();
+     549           1 :       atomNames_.resize( natoms );
+     550         385 :       for(unsigned i=0; i<natoms; ++i) atomNames_[i]=pdb.getAtomName(pdb.getAtomNumbers()[i]);
+     551           1 :       log.printf("  Read %d atoms from atom names file %s \n", natoms, atomNamesFile.c_str() );
+     552           1 :       log.printf("  Atoms in environments will be considered only if atom names match.\n");
+     553           1 :     } else {
+     554           4 :       log.printf("  No atom names file has been given. Atoms in reference environments will be matched disregarding atom type.\n");
+     555             :     }
+     556             :   } else {
+     557           0 :     error("CRYSTAL_STRUCTURE=" + crystal_structure + " does not match any structures in the database");
+     558             :   }
+     559             : 
+     560          10 :   log.printf("  targeting the %s crystal structure",crystal_structure.c_str());
+     561          10 :   if (lattice_constants.size()>0) log.printf(" with lattice constants %f\n",lattice_constants[0]);
+     562           5 :   else log.printf("\n");
+     563             : 
+     564          10 :   log.printf("  maximum distance in the reference environment is %f\n",max_dist);
+     565          10 : }
+     566             : 
+     567             : }
+     568             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Fccubic.cpp.func-sort-c.html b/coverage/crystallization/Fccubic.cpp.func-sort-c.html new file mode 100644 index 000000000000..c31506a06c6a --- /dev/null +++ b/coverage/crystallization/Fccubic.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Fccubic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Fccubic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2828100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization7FccubicC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization7FccubicC1ERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization7Fccubic16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD15crystallization7Fccubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_320614
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Fccubic.cpp.func.html b/coverage/crystallization/Fccubic.cpp.func.html new file mode 100644 index 000000000000..269ed2683970 --- /dev/null +++ b/coverage/crystallization/Fccubic.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Fccubic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Fccubic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2828100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization7Fccubic16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD15crystallization7FccubicC1ERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization7FccubicC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization7Fccubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_320614
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Fccubic.cpp.gcov.html b/coverage/crystallization/Fccubic.cpp.gcov.html new file mode 100644 index 000000000000..c45b0d2397d3 --- /dev/null +++ b/coverage/crystallization/Fccubic.cpp.gcov.html @@ -0,0 +1,210 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Fccubic.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Fccubic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2828100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CubicHarmonicBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/SwitchingFunction.h"
+      25             : 
+      26             : #include <string>
+      27             : #include <cmath>
+      28             : 
+      29             : using namespace std;
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace crystallization {
+      33             : 
+      34             : //+PLUMEDOC MCOLVAR FCCUBIC
+      35             : /*
+      36             : Measure how similar the environment around atoms is to that found in a FCC structure.
+      37             : 
+      38             : This CV was introduced in this article \cite fcc-michele-1 and again in this article \cite fcc-michele-2
+      39             : This CV essentially determines whether the environment around any given atom is similar to that found in
+      40             : the FCC structure or not.  The function that is used to make this determination is as follows:
+      41             : 
+      42             : \f[
+      43             : s_i = \frac{ \sum_{i \ne j} \sigma(r_{ij}) \left\{ a\left[ \frac{(x_{ij}y_{ij})^4 + (x_{ij}z_{ij})^4 + (y_{ij}z_{ij})^4}{r_{ij}^8} - \frac{\alpha (x_{ij}y_{ij}z_{ij})^4}{r_{ij}^{12}} \right] + b \right\} }{ \sum_{i \ne j} \sigma(r_{ij}) }
+      44             : \f]
+      45             : 
+      46             : In this expression \f$x_{ij}\f$, \f$y_{ij}\f$ and \f$z_{ij}\f$ are the \f$x\f$, \f$y\f$ and \f$z\f$ components of the vector connecting atom \f$i\f$ to
+      47             : atom \f$j\f$ and \f$r_{ij}\f$ is the magnitude of this vector.  \f$\sigma(r_{ij})\f$ is a \ref switchingfunction that acts on the distance between
+      48             : atom \f$i\f$ and atom \f$j\f$ and its inclusion in the numerator and the denominator of the above expression as well as the fact that we are summing
+      49             : over all of the other atoms in the system ensures that we are calculating an average
+      50             : of the function of \f$x_{ij}\f$, \f$y_{ij}\f$ and \f$z_{ij}\f$ for the atoms in the first coordination sphere around atom \f$i\f$.  Lastly, \f$\alpha\f$
+      51             : is a parameter that can be set by the user, which by default is equal to three.  The values of \f$a\f$ and \f$b\f$ are calculated from \f$\alpha\f$ using:
+      52             : 
+      53             : \f[
+      54             : a = \frac{ 80080}{ 2717 + 16 \alpha} \qquad \textrm{and} \qquad b = \frac{ 16(\alpha - 143) }{2717 + 16\alpha}
+      55             : \f]
+      56             : 
+      57             : This quantity is once again a multicolvar so you can compute it for multiple atoms using a single PLUMED action and then compute
+      58             : the average value for the atoms in your system, the number of atoms that have an \f$s_i\f$ value that is more that some target and
+      59             : so on.  Notice also that you can rotate the reference frame if you are using a non-standard unit cell.
+      60             : 
+      61             : \par Examples
+      62             : 
+      63             : The following input calculates the FCCUBIC parameter for the 64 atoms in the system
+      64             : and then calculates and prints the average value for this quantity.
+      65             : 
+      66             : \plumedfile
+      67             : FCCUBIC SPECIES=1-64 SWITCH={RATIONAL D_0=3.0 R_0=1.5} MEAN LABEL=d
+      68             : PRINT ARG=d.* FILE=colv
+      69             : \endplumedfile
+      70             : 
+      71             : */
+      72             : //+ENDPLUMEDOC
+      73             : 
+      74             : 
+      75             : class Fccubic : public CubicHarmonicBase {
+      76             : private:
+      77             :   double alpha, a1, b1;
+      78             : public:
+      79             :   static void registerKeywords( Keywords& keys );
+      80             :   explicit Fccubic(const ActionOptions&);
+      81             :   double calculateCubicHarmonic( const Vector& distance, const double& d2, Vector& myder ) const override;
+      82             : };
+      83             : 
+      84             : PLUMED_REGISTER_ACTION(Fccubic,"FCCUBIC")
+      85             : 
+      86           6 : void Fccubic::registerKeywords( Keywords& keys ) {
+      87           6 :   CubicHarmonicBase::registerKeywords( keys );
+      88          12 :   keys.add("compulsory","ALPHA","3.0","The alpha parameter of the angular function");
+      89           6 : }
+      90             : 
+      91           4 : Fccubic::Fccubic(const ActionOptions&ao):
+      92             :   Action(ao),
+      93           4 :   CubicHarmonicBase(ao)
+      94             : {
+      95             :   // Scaling factors such that '1' corresponds to fcc lattice
+      96             :   // and '0' corresponds to isotropic (liquid)
+      97           4 :   parse("ALPHA",alpha);
+      98           4 :   a1 = 80080. / (2717. + 16*alpha); b1 = 16.*(alpha-143)/(2717+16*alpha);
+      99           4 :   log.printf("  setting alpha parameter equal to %f \n",alpha);
+     100             :   // And setup the ActionWithVessel
+     101           4 :   checkRead();
+     102           4 : }
+     103             : 
+     104      320614 : double Fccubic::calculateCubicHarmonic( const Vector& distance, const double& d2, Vector& myder ) const {
+     105      320614 :   double x2 = distance[0]*distance[0];
+     106      320614 :   double x4 = x2*x2;
+     107             : 
+     108      320614 :   double y2 = distance[1]*distance[1];
+     109      320614 :   double y4 = y2*y2;
+     110             : 
+     111      320614 :   double z2 = distance[2]*distance[2];
+     112      320614 :   double z4 = z2*z2;
+     113             : 
+     114      320614 :   double r8 = pow( d2, 4 );
+     115             :   double r12 = pow( d2, 6 );
+     116             : 
+     117      320614 :   double tmp = ((x4*y4)+(x4*z4)+(y4*z4))/r8-alpha*x4*y4*z4/r12;
+     118             : 
+     119      320614 :   double t0 = (x2*y4+x2*z4)/r8-alpha*x2*y4*z4/r12;
+     120      320614 :   double t1 = (y2*x4+y2*z4)/r8-alpha*y2*x4*z4/r12;
+     121      320614 :   double t2 = (z2*x4+z2*y4)/r8-alpha*z2*x4*y4/r12;
+     122      320614 :   double t3 = (2*tmp-alpha*x4*y4*z4/r12)/d2;
+     123             : 
+     124      320614 :   myder[0]=4*a1*distance[0]*(t0-t3);
+     125      320614 :   myder[1]=4*a1*distance[1]*(t1-t3);
+     126      320614 :   myder[2]=4*a1*distance[2]*(t2-t3);
+     127             : 
+     128      320614 :   return a1*tmp+b1;
+     129             : }
+     130             : 
+     131             : }
+     132             : }
+     133             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.cpp.func-sort-c.html b/coverage/crystallization/Gradient.cpp.func-sort-c.html new file mode 100644 index 000000000000..2a5cded005b0 --- /dev/null +++ b/coverage/crystallization/Gradient.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Gradient.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Gradient.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:507071.4 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization8GradientC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization8GradientC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization8Gradient16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD15crystallization8Gradient12setupRegionsEv232
_ZNK4PLMD15crystallization8Gradient19calculateAllVolumesERKjRNS_10MultiValueE11600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.cpp.func.html b/coverage/crystallization/Gradient.cpp.func.html new file mode 100644 index 000000000000..201207bccfcb --- /dev/null +++ b/coverage/crystallization/Gradient.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Gradient.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Gradient.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:507071.4 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization8Gradient12setupRegionsEv232
_ZN4PLMD15crystallization8Gradient16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD15crystallization8GradientC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization8GradientC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization8Gradient19calculateAllVolumesERKjRNS_10MultiValueE11600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.cpp.gcov.html b/coverage/crystallization/Gradient.cpp.gcov.html new file mode 100644 index 000000000000..0686d8cb0541 --- /dev/null +++ b/coverage/crystallization/Gradient.cpp.gcov.html @@ -0,0 +1,244 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Gradient.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Gradient.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:507071.4 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Gradient.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/HistogramBead.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace crystallization {
+      29             : 
+      30             : //+PLUMEDOC MCOLVARF GRADIENT
+      31             : /*
+      32             : Calculate the gradient of the average value of a multicolvar value
+      33             : 
+      34             : This command allows you to calculate the collective variable discussed in \cite fede-grad.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The input below calculates the gradient of the density of atoms in the manner
+      39             : described in \cite fede-grad in order to detect whether or not atoms are distributed
+      40             : uniformly along the x-axis of the simulation cell.
+      41             : 
+      42             : \plumedfile
+      43             : d1: DENSITY SPECIES=1-50
+      44             : s1: GRADIENT ORIGIN=1 DATA=d1 DIR=x NBINS=4 SIGMA=1.0
+      45             : PRINT ARG=s1 FILE=colvar
+      46             : \endplumedfile
+      47             : 
+      48             : The input below calculates the coordination numbers of the 50 atoms in the simulation cell.
+      49             : The gradient of this quantity is then evaluated in the manner described using the equation above
+      50             : to detect whether the average values of the coordination number are uniformly distributed along the
+      51             : x-axis of the simulation cell.
+      52             : 
+      53             : \plumedfile
+      54             : d2: COORDINATIONNUMBER SPECIES=1-50 SWITCH={RATIONAL R_0=2.0} MORE_THAN={EXP R_0=4.0}
+      55             : s2: GRADIENT ORIGIN=1 DATA=d2 DIR=x NBINS=4 SIGMA=1.0
+      56             : PRINT ARG=s2 FILE=colvar
+      57             : \endplumedfile
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : PLUMED_REGISTER_ACTION(Gradient,"GRADIENT")
+      63             : 
+      64           4 : void Gradient::registerKeywords( Keywords& keys ) {
+      65           4 :   VolumeGradientBase::registerKeywords( keys );
+      66           8 :   keys.add("atoms","ORIGIN","we will use the position of this atom as the origin in our calculation");
+      67           8 :   keys.add("compulsory","DIR","xyz","the directions in which we are calculating the gradient.  Should be x, y, z, xy, xz, yz or xyz");
+      68           8 :   keys.add("compulsory","NBINS","number of bins to use in each direction for the calculation of the gradient");
+      69           8 :   keys.add("compulsory","SIGMA","1.0","the width of the function to be used for kernel density estimation");
+      70           8 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      71           4 : }
+      72             : 
+      73           2 : Gradient::Gradient(const ActionOptions&ao):
+      74             :   Action(ao),
+      75             :   VolumeGradientBase(ao),
+      76           2 :   nbins(3)
+      77             : {
+      78             :   std::vector<AtomNumber> atom;
+      79           4 :   parseAtomList("ORIGIN",atom);
+      80           2 :   if( atom.size()!=1 ) error("should only be one atom specified");
+      81           2 :   log.printf("  origin is at position of atom : %d\n",atom[0].serial() );
+      82             : 
+      83           4 :   std::string direction; parse("DIR",direction);
+      84           2 :   std::vector<unsigned> tbins; parseVector("NBINS",tbins);
+      85           4 :   for(unsigned i=0; i<tbins.size(); ++i) {
+      86           2 :     if( tbins[i]<2 ) error("Number of grid points should be greater than 1");
+      87             :   }
+      88             : 
+      89           2 :   if( direction=="x" ) {
+      90           2 :     if( tbins.size()!=1 ) error("mismatch between number of bins and direction");
+      91           2 :     nbins[0]=tbins[0]; nbins[1]=0; nbins[2]=0;
+      92           0 :   } else if( direction=="y" ) {
+      93           0 :     if( tbins.size()!=1 ) error("mismatch between number of bins and direction");
+      94           0 :     nbins[0]=0; nbins[1]=tbins[0]; nbins[2]=0;
+      95           0 :   } else if( direction=="z" ) {
+      96           0 :     if( tbins.size()!=1 ) error("mismatch between number of bins and direction");
+      97           0 :     nbins[0]=0; nbins[1]=0; nbins[2]=tbins[0];
+      98           0 :   } else if( direction=="xy" ) {
+      99           0 :     if( tbins.size()!=2 ) error("mismatch between number of bins and direction");
+     100           0 :     nbins[0]=tbins[0]; nbins[1]=tbins[1]; nbins[2]=0;
+     101           0 :   } else if( direction=="xz" ) {
+     102           0 :     if( tbins.size()!=2 ) error("mismatch between number of bins and direction");
+     103           0 :     nbins[0]=tbins[0]; nbins[1]=0; nbins[2]=tbins[1];
+     104           0 :   } else if( direction=="yz" ) {
+     105           0 :     if( tbins.size()!=2 ) error("mismatch between number of bins and direction");
+     106           0 :     nbins[0]=0; nbins[1]=tbins[0]; nbins[2]=tbins[1];
+     107           0 :   } else if( direction=="xyz" ) {
+     108           0 :     if( tbins.size()!=3 ) error("mismatch between number of bins and direction");
+     109           0 :     nbins[0]=tbins[0]; nbins[1]=tbins[1]; nbins[2]=tbins[2];
+     110             :   } else {
+     111           0 :     error( direction + " is not valid gradient direction");
+     112             :   }
+     113             : 
+     114             :   // Find number of quantities
+     115           2 :   if( getPntrToMultiColvar()->isDensity() ) vend=2;
+     116           1 :   else if( getPntrToMultiColvar()->getNumberOfQuantities()==2 ) vend=2;
+     117           0 :   else vend = getPntrToMultiColvar()->getNumberOfQuantities();
+     118           2 :   nquantities = vend + nbins[0] + nbins[1] + nbins[2];
+     119             : 
+     120             :   // Output some nice information
+     121           2 :   std::string functype=getPntrToMultiColvar()->getName();
+     122          27 :   std::transform( functype.begin(), functype.end(), functype.begin(), [](unsigned char c) { return std::tolower(c); } );
+     123           2 :   log.printf("  calculating gradient of %s in %s direction \n",functype.c_str(), direction.c_str() );
+     124           4 :   log<<"  Bibliography:"<<plumed.cite("Giberti, Tribello and Parrinello, J. Chem. Theory Comput., 9, 2526 (2013)")<<"\n";
+     125             : 
+     126           4 :   parse("SIGMA",sigma); parse("KERNEL",kerneltype);
+     127           2 :   checkRead(); requestAtoms(atom);
+     128             : 
+     129             :   // And setup the vessel
+     130           2 :   std::string input; addVessel( "GRADIENT", input, -1 );
+     131             :   // And resize everything
+     132           2 :   readVesselKeywords();
+     133           2 : }
+     134             : 
+     135         232 : void Gradient::setupRegions() {
+     136             : //  if( !getPbc().isOrthorombic() ) error("cell must be orthorhombic when using gradient");
+     137         232 : }
+     138             : 
+     139       11600 : void Gradient::calculateAllVolumes( const unsigned& curr, MultiValue& outvals ) const {
+     140             :   // Setup the bead
+     141       11600 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( kerneltype );
+     142             : 
+     143       11600 :   Vector cpos = pbcDistance( getPosition(0), getPntrToMultiColvar()->getCentralAtomPos( curr ) );
+     144             :   // Note we use the pbc from base multicolvar so that we get numerical derivatives correct
+     145       11600 :   Vector oderiv, fpos = (getPntrToMultiColvar()->getPbc()).realToScaled( cpos );
+     146             : 
+     147       11600 :   Vector deriv; unsigned nbase=vend; std::vector<Vector> refder(1); Tensor vir; vir.zero();
+     148       46400 :   for(unsigned idir=0; idir<3; ++idir) {
+     149       34800 :     deriv[0]=deriv[1]=deriv[2]=0.0;
+     150       34800 :     double delx = 1.0 / static_cast<double>( nbins[idir] );
+     151       81200 :     for(unsigned jbead=0; jbead<nbins[idir]; ++jbead) {
+     152             :       // Calculate what box we are in
+     153       46400 :       bead.set( -0.5+jbead*delx, -0.5+(jbead+1)*delx, sigma );
+     154       46400 :       double weight=bead.calculate( fpos[0], deriv[idir] );
+     155       46400 :       oderiv = (getPntrToMultiColvar()->getPbc()).realToScaled( deriv );
+     156             :       // Set and derivatives
+     157       46400 :       refder[0]=-oderiv; // vir = -Tensor(cpos,oderiv);
+     158       46400 :       setNumberInVolume( nbase+jbead, curr, weight, oderiv, vir, refder, outvals );
+     159             : //          addReferenceAtomDerivatives( nbase+jbead, 0, -oderiv );
+     160             : //          addBoxDerivatives( nbase+jbead, -Tensor(cpos,oderiv) );
+     161             :     }
+     162       34800 :     nbase += nbins[idir];
+     163             :   }
+     164       11600 : }
+     165             : 
+     166             : }
+     167             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.h.func-sort-c.html b/coverage/crystallization/Gradient.h.func-sort-c.html new file mode 100644 index 000000000000..ea0f586e4e55 --- /dev/null +++ b/coverage/crystallization/Gradient.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Gradient.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Gradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15crystallization8Gradient21getNumberOfQuantitiesEv12064
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.h.func.html b/coverage/crystallization/Gradient.h.func.html new file mode 100644 index 000000000000..7d1e660ad079 --- /dev/null +++ b/coverage/crystallization/Gradient.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Gradient.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Gradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15crystallization8Gradient21getNumberOfQuantitiesEv12064
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Gradient.h.gcov.html b/coverage/crystallization/Gradient.h.gcov.html new file mode 100644 index 000000000000..731fdc1d3141 --- /dev/null +++ b/coverage/crystallization/Gradient.h.gcov.html @@ -0,0 +1,136 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Gradient.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Gradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_crystallization_Gradient_h
+      23             : #define __PLUMED_crystallization_Gradient_h
+      24             : 
+      25             : #include "multicolvar/VolumeGradientBase.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace crystallization {
+      29             : 
+      30             : class Gradient : public multicolvar::VolumeGradientBase {
+      31             :   friend class GradientVessel;
+      32             : private:
+      33             : /// The value of sigma
+      34             :   double sigma;
+      35             : /// Number of quantities in use in this colvar
+      36             :   unsigned vend, nquantities;
+      37             : /// Number of bins in each direction
+      38             :   std::vector<unsigned> nbins;
+      39             : /// The type of kernel for the histogram
+      40             :   std::string kerneltype;
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             :   explicit Gradient(const ActionOptions&);
+      44             : /// Get the number of quantities that are calculated each time
+      45             :   virtual unsigned getNumberOfQuantities() const ;
+      46             : /// Check on pbc - is it orthorhombic
+      47             :   void setupRegions();
+      48             : /// Calculate whats in the volume
+      49             :   void calculateAllVolumes( const unsigned& curr, MultiValue& outvals ) const ;
+      50             : };
+      51             : 
+      52             : inline
+      53       12064 : unsigned Gradient::getNumberOfQuantities() const {
+      54       12064 :   return nquantities;
+      55             : }
+      56             : 
+      57             : }
+      58             : }
+      59             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/GradientVessel.cpp.func-sort-c.html b/coverage/crystallization/GradientVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..f6cd2a7347c2 --- /dev/null +++ b/coverage/crystallization/GradientVessel.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/GradientVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - GradientVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:829784.5 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE2
_ZN4PLMD15crystallization14GradientVessel16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization14GradientVessel16value_descriptorB5cxx11Ev2
_ZN4PLMD15crystallization14GradientVesselC2ERKNS_10vesselbase13VesselOptionsE2
_ZN4PLMD15crystallization14GradientVessel6resizeEv4
_ZN4PLMD15crystallization14GradientVessel6finishERKSt6vectorIdSaIdEE232
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMeC2Ev4187
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMeD2Ev4187
_ZN4PLMD15crystallization14GradientVessel14reserveKeywordERNS_8KeywordsE4187
_ZNK4PLMD15crystallization14GradientVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE11600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/GradientVessel.cpp.func.html b/coverage/crystallization/GradientVessel.cpp.func.html new file mode 100644 index 000000000000..5aae8a68c199 --- /dev/null +++ b/coverage/crystallization/GradientVessel.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/GradientVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - GradientVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:829784.5 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE2
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMeC2Ev4187
_ZN4PLMD15crystallization12_GLOBAL__N_124GradientVesselRegisterMeD2Ev4187
_ZN4PLMD15crystallization14GradientVessel14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD15crystallization14GradientVessel16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization14GradientVessel16value_descriptorB5cxx11Ev2
_ZN4PLMD15crystallization14GradientVessel6finishERKSt6vectorIdSaIdEE232
_ZN4PLMD15crystallization14GradientVessel6resizeEv4
_ZN4PLMD15crystallization14GradientVesselC2ERKNS_10vesselbase13VesselOptionsE2
_ZNK4PLMD15crystallization14GradientVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE11600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/GradientVessel.cpp.gcov.html b/coverage/crystallization/GradientVessel.cpp.gcov.html new file mode 100644 index 000000000000..be6dad0c4316 --- /dev/null +++ b/coverage/crystallization/GradientVessel.cpp.gcov.html @@ -0,0 +1,269 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/GradientVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - GradientVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:829784.5 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "vesselbase/VesselRegister.h"
+      23             : #include "vesselbase/FunctionVessel.h"
+      24             : #include "vesselbase/ActionWithVessel.h"
+      25             : #include "multicolvar/ActionVolume.h"
+      26             : #include "VectorMultiColvar.h"
+      27             : #include "Gradient.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace crystallization {
+      31             : 
+      32             : class GradientVessel : public vesselbase::FunctionVessel {
+      33             : private:
+      34             :   bool isdens;
+      35             :   size_t nweights, ncomponents;
+      36             :   std::vector<unsigned> starts;
+      37             : public:
+      38             :   static void registerKeywords( Keywords& keys );
+      39             :   static void reserveKeyword( Keywords& keys );
+      40             :   explicit GradientVessel( const vesselbase::VesselOptions& da );
+      41             :   std::string value_descriptor();
+      42             :   void resize();
+      43             :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const ;
+      44             :   void finish( const std::vector<double>& buffer );
+      45             : };
+      46             : 
+      47       12563 : PLUMED_REGISTER_VESSEL(GradientVessel,"GRADIENT")
+      48             : 
+      49           2 : void GradientVessel::registerKeywords( Keywords& keys ) {
+      50           2 :   vesselbase::FunctionVessel::registerKeywords(keys);
+      51           2 : }
+      52             : 
+      53        4187 : void GradientVessel::reserveKeyword( Keywords& keys ) {
+      54        8374 :   keys.reserve("vessel","GRADIENT","calculate the gradient");
+      55        8374 :   keys.addOutputComponent("gradient","GRADIENT","the gradient");
+      56        4187 : }
+      57             : 
+      58           2 : GradientVessel::GradientVessel( const vesselbase::VesselOptions& da ) :
+      59           2 :   FunctionVessel(da)
+      60             : {
+      61           2 :   Gradient* vg=dynamic_cast<Gradient*>( getAction() );
+      62           2 :   plumed_assert( vg ); isdens=(vg->getPntrToMultiColvar())->isDensity();
+      63           2 :   nweights = vg->nbins[0] + vg->nbins[1] + vg->nbins[2];
+      64           2 :   if( (vg->getPntrToMultiColvar())->getNumberOfQuantities()>2 ) {
+      65           0 :     ncomponents = (vg->getPntrToMultiColvar())->getNumberOfQuantities() - 2;
+      66             :   } else {
+      67           2 :     ncomponents = 1;
+      68             :   }
+      69             : 
+      70           2 :   starts.push_back(0);
+      71           2 :   if( vg->nbins[0]>0 ) {
+      72           2 :     starts.push_back( vg->nbins[0] );
+      73           2 :     if( vg->nbins[1]>0 ) {
+      74           0 :       starts.push_back( vg->nbins[0] + vg->nbins[1] );
+      75           0 :       if( vg->nbins[2]>0 ) starts.push_back( nweights );
+      76           2 :     } else if( vg->nbins[2]>0 ) {
+      77           0 :       starts.push_back( nweights );
+      78             :     }
+      79           0 :   } else if( vg->nbins[1]>0 ) {
+      80           0 :     starts.push_back( vg->nbins[1] );
+      81           0 :     if( vg->nbins[2]>0 ) starts.push_back( nweights );
+      82           0 :   } else if( vg->nbins[2]>0 ) {
+      83           0 :     starts.push_back( nweights );
+      84             :   }
+      85           2 : }
+      86             : 
+      87           2 : std::string GradientVessel::value_descriptor() {
+      88           2 :   return "the gradient";
+      89             : }
+      90             : 
+      91           4 : void GradientVessel::resize() {
+      92           4 :   if( getAction()->derivativesAreRequired() ) {
+      93           2 :     unsigned nder=getAction()->getNumberOfDerivatives();
+      94           2 :     resizeBuffer( (1+nder)*(ncomponents+1)*nweights );
+      95           2 :     getFinalValue()->resizeDerivatives( nder );
+      96             :   } else {
+      97           2 :     resizeBuffer( (ncomponents+1)*nweights );
+      98             :   }
+      99           4 : }
+     100             : 
+     101       11600 : void GradientVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+     102             :   unsigned nder;
+     103       11600 :   if( getAction()->derivativesAreRequired() ) nder=getAction()->getNumberOfDerivatives();
+     104             :   else nder=0;
+     105       11600 :   unsigned wstart, cstart; if( ncomponents==1 ) { cstart=1; wstart=2; } else { cstart=2; wstart=2+ncomponents; }
+     106             : 
+     107       58000 :   for(unsigned iw=0; iw<nweights; ++iw) {
+     108       46400 :     unsigned xx = (ncomponents+1)*iw;
+     109       46400 :     double weight=myvals.get(wstart+iw);
+     110       46400 :     buffer[bufstart+xx*(nder+1)] += weight;
+     111       46400 :     myvals.chainRule( wstart + iw, xx, 1, 0, 1.0, bufstart, buffer );
+     112       92800 :     for(unsigned jc=0; jc<ncomponents; ++jc) {
+     113       46400 :       double colvar=myvals.get( cstart + jc );
+     114       46400 :       buffer[bufstart+(xx+1+jc)*(nder+1) ] += weight*colvar;
+     115       46400 :       myvals.chainRule( cstart + jc, xx + 1 + jc, 1, 0, weight, bufstart, buffer );
+     116       46400 :       myvals.chainRule( wstart + iw, xx + 1 + jc, 1, 0, colvar, bufstart, buffer );
+     117             :     }
+     118             :   }
+     119       11600 : }
+     120             : 
+     121         232 : void GradientVessel::finish( const std::vector<double>& buffer ) {
+     122         232 :   std::vector<double> val_interm( ncomponents*nweights );
+     123             :   unsigned nder;
+     124         232 :   if( getAction()->derivativesAreRequired() ) nder=getAction()->getNumberOfDerivatives();
+     125             :   else nder=0;
+     126         232 :   Matrix<double> der_interm( ncomponents*nweights, nder ); der_interm=0;
+     127             : 
+     128         232 :   if( isdens ) {
+     129         580 :     for(unsigned iw=0; iw<nweights; ++iw) {
+     130         464 :       val_interm[iw] = buffer[bufstart + 2*iw*(1+nder)];
+     131         464 :       if( getAction()->derivativesAreRequired() ) {
+     132         464 :         unsigned wstart = bufstart + 2*iw*(nder+1) + 1;
+     133       75632 :         for(unsigned jder=0; jder<nder; ++jder) der_interm( iw, jder ) += buffer[ wstart + jder ];
+     134             :       }
+     135             :     }
+     136             :   } else {
+     137         580 :     for(unsigned iw=0; iw<nweights; ++iw) {
+     138         464 :       unsigned xx = (ncomponents+1)*iw;
+     139         464 :       double ww=buffer[bufstart + xx*(1+nder)];
+     140         928 :       for(unsigned jc=0; jc<ncomponents; ++jc) val_interm[ iw*ncomponents + jc ] = buffer[bufstart + (xx+1+jc)*(1+nder)] / ww;
+     141         464 :       if( getAction()->derivativesAreRequired() ) {
+     142         464 :         unsigned wstart = bufstart + xx*(nder+1) + 1;
+     143         928 :         for(unsigned jc=0; jc<ncomponents; ++jc) {
+     144         464 :           unsigned bstart = bufstart + ( xx + 1 + jc )*(nder+1) + 1;
+     145         464 :           double val = buffer[bufstart + (nder+1)*(xx+1+jc)];
+     146       75632 :           for(unsigned jder=0; jder<nder; ++jder)
+     147       75168 :             der_interm( iw*ncomponents + jc, jder ) = (1.0/ww)*buffer[bstart + jder] - (val/(ww*ww))*buffer[wstart + jder];
+     148             :         }
+     149             :       }
+     150             :     }
+     151             :   }
+     152             : 
+     153         232 :   double tmp, diff2=0.0;
+     154             : 
+     155         232 :   if( getAction()->derivativesAreRequired() ) {
+     156             :     Value* fval=getFinalValue();
+     157         464 :     for(unsigned j=0; j<starts.size()-1; ++j) {
+     158        1160 :       for(unsigned bin=starts[j]; bin<starts[j+1]; ++bin) {
+     159        1856 :         for(unsigned jc=0; jc<ncomponents; ++jc) {
+     160         928 :           if( bin==starts[j] ) {
+     161         232 :             tmp=val_interm[(starts[j+1]-1)*ncomponents + jc] - val_interm[bin*ncomponents + jc];
+     162       37816 :             for(unsigned jder=0; jder<nder; ++jder) {
+     163       37584 :               fval->addDerivative( jder, +2.0*tmp*der_interm( (starts[j+1]-1)*ncomponents + jc, jder) );
+     164       37584 :               fval->addDerivative( jder, -2.0*tmp*der_interm( bin*ncomponents + jc, jder ) );
+     165             :             }
+     166             :           } else {
+     167         696 :             tmp=val_interm[(bin-1)*ncomponents + jc] - val_interm[bin*ncomponents + jc];
+     168      113448 :             for(unsigned jder=0; jder<nder; ++jder) {
+     169      112752 :               fval->addDerivative( jder, +2.0*tmp*der_interm( (bin-1)*ncomponents + jc, jder) );
+     170      112752 :               fval->addDerivative( jder, -2.0*tmp*der_interm( bin*ncomponents + jc, jder ) );
+     171             :             }
+     172             :           }
+     173         928 :           diff2+=tmp*tmp;
+     174             :         }
+     175             :       }
+     176             :     }
+     177             :   } else {
+     178           0 :     for(unsigned j=0; j<starts.size()-1; ++j) {
+     179           0 :       for(unsigned bin=starts[j]; bin<starts[j+1]; ++bin) {
+     180           0 :         for(unsigned jc=0; jc<ncomponents; ++jc) {
+     181           0 :           if( bin==starts[j] ) tmp=val_interm[(starts[j+1]-1)*ncomponents + jc] - val_interm[bin*ncomponents + jc];
+     182           0 :           else tmp=val_interm[(bin-1)*ncomponents + jc] - val_interm[bin*ncomponents + jc];
+     183           0 :           diff2+=tmp*tmp;
+     184             :         }
+     185             :       }
+     186             :     }
+     187             :   }
+     188         232 :   setOutputValue( diff2 );
+     189         232 : }
+     190             : 
+     191             : }
+     192             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/InterMolecularTorsions.cpp.func-sort-c.html b/coverage/crystallization/InterMolecularTorsions.cpp.func-sort-c.html new file mode 100644 index 000000000000..a094e9b1090f --- /dev/null +++ b/coverage/crystallization/InterMolecularTorsions.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/InterMolecularTorsions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - InterMolecularTorsions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:136221.0 %
Date:2024-02-22 21:58:45Functions:1714.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization22InterMolecularTorsions10isPeriodicEv0
_ZN4PLMD15crystallization22InterMolecularTorsions14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_0
_ZN4PLMD15crystallization22InterMolecularTorsionsC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization22InterMolecularTorsionsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization22InterMolecularTorsions15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE0
_ZNK4PLMD15crystallization22InterMolecularTorsions7computeERKjRNS_11multicolvar13AtomValuePackE0
_ZN4PLMD15crystallization22InterMolecularTorsions16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/InterMolecularTorsions.cpp.func.html b/coverage/crystallization/InterMolecularTorsions.cpp.func.html new file mode 100644 index 000000000000..b867c72a0379 --- /dev/null +++ b/coverage/crystallization/InterMolecularTorsions.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/InterMolecularTorsions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - InterMolecularTorsions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:136221.0 %
Date:2024-02-22 21:58:45Functions:1714.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization22InterMolecularTorsions10isPeriodicEv0
_ZN4PLMD15crystallization22InterMolecularTorsions14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_0
_ZN4PLMD15crystallization22InterMolecularTorsions16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization22InterMolecularTorsionsC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization22InterMolecularTorsionsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization22InterMolecularTorsions15calculateWeightERKjRKdRNS_11multicolvar13AtomValuePackE0
_ZNK4PLMD15crystallization22InterMolecularTorsions7computeERKjRNS_11multicolvar13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/InterMolecularTorsions.cpp.gcov.html b/coverage/crystallization/InterMolecularTorsions.cpp.gcov.html new file mode 100644 index 000000000000..59bbde66adb1 --- /dev/null +++ b/coverage/crystallization/InterMolecularTorsions.cpp.gcov.html @@ -0,0 +1,270 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/InterMolecularTorsions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - InterMolecularTorsions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:136221.0 %
Date:2024-02-22 21:58:45Functions:1714.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "multicolvar/MultiColvarBase.h"
+      23             : #include "multicolvar/AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/SwitchingFunction.h"
+      26             : #include "tools/Torsion.h"
+      27             : 
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : //+PLUMEDOC MCOLVARF INTERMOLECULARTORSIONS
+      32             : /*
+      33             : Calculate torsion angles between vectors on adjacent molecules
+      34             : 
+      35             : This variable can be used to calculate the average torsional angles between vectors.  In other words,
+      36             : it can be used to compute quantities like this:
+      37             : 
+      38             : \f[
+      39             : s = \frac{ \sum_{i \ne j} \sigma(r_{ij}) \theta_{ij} }{ \sum_{i \ne j} \sigma(r_{ij}) }
+      40             : \f]
+      41             : 
+      42             : Here the sums run over all pairs of molecules. \f$\sigma(r_{ij})\f$ is a \ref switchingfunction that
+      43             : action on the distance between the centers of molecules \f$i\f$ and \f$j\f$.  \f$\theta_{ij}\f$ is then
+      44             : the torsional angle between an orientation vector for molecule \f$i\f$ and molecule \f$j\f$.
+      45             : 
+      46             : This command can be used to calculate the intermolecular torsional angles between the orientations of nearby molecules.  The orientation of a
+      47             : molecule can be calculated by using either the \ref MOLECULES or the \ref PLANES commands.  These two commands calculate the orientation of a
+      48             : bond in the molecule or the orientation of a plane containing three of the molecule's atoms.  Furthermore, when we use these commands we think of
+      49             : molecules as objects that lie at a point in space and that have an orientation.   This command calculates the torsional angles between the orientations
+      50             : of these objects.  We can then calculates functions of a large number of these torsional angles that measures things such as the number of torsional
+      51             : angles that are within a particular range.  Because it is often useful to only consider the torsional angles between objects that are within a certain
+      52             : distance of each other we can, when calculating these sums, perform a weighted sum and use a \ref switchingfunction to ensure that we focus on molecules
+      53             : that are close together.
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : The example input below is necessarily but gives you an idea of what can be achieved using this action.
+      58             : The orientations and positions of four molecules are defined using the \ref MOLECULES action as the position of the
+      59             : centers of mass of the two atoms specified and the direction of the vector connecting the two atoms that were specified.
+      60             : The torsional angles between the molecules are then calculated by the \ref INTERMOLECULARTORSIONS command labelled torsion_p.
+      61             : We then compute a \ref HISTOGRAM that shows the distribution that these torsional angles take in the structure.  The weight
+      62             : a given torsional angle contributes to this \ref HISTOGRAM is determined using a \ref switchingfunction that acts on the distance
+      63             : between the two molecules.  As such the torsional angles between molecules that are close together contribute a high weight to the
+      64             : histogram while the torsional angles between molecules that are far apart does not contribute to the histogram.  The histogram is
+      65             : averaged over the whole trajectory and output once all the trajectory frames have been read.
+      66             : 
+      67             : \plumedfile
+      68             : m1: MOLECULES MOL1=1,2 MOL2=3,4 MOL3=5,6 MOL4=7,8
+      69             : torsion_p: INTERMOLECULARTORSIONS MOLS=m1 SWITCH={RATIONAL R_0=0.25 D_0=2.0 D_MAX=3.0}
+      70             : htt_p: HISTOGRAM DATA=torsion_p GRID_MIN=-pi GRID_MAX=pi BANDWIDTH=0.1 GRID_BIN=200 STRIDE=1
+      71             : DUMPGRID GRID=htt_p FILE=myhist.out
+      72             : \endplumedfile
+      73             : 
+      74             : */
+      75             : //+ENDPLUMEDOC
+      76             : 
+      77             : namespace PLMD {
+      78             : namespace crystallization {
+      79             : 
+      80             : class InterMolecularTorsions : public multicolvar::MultiColvarBase {
+      81             : private:
+      82             : /// The switching function that tells us if atoms are close enough together
+      83             :   SwitchingFunction switchingFunction;
+      84             : public:
+      85             :   static void registerKeywords( Keywords& keys );
+      86             :   explicit InterMolecularTorsions(const ActionOptions&);
+      87             : /// Do the stuff with the switching functions
+      88             :   double calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const ;
+      89             : /// Actually do the calculation
+      90             :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const ;
+      91             : /// Is the variable periodic
+      92           0 :   bool isPeriodic() { return true; }
+      93           0 :   void retrieveDomain( std::string& min, std::string& max ) { min="-pi"; max="+pi"; }
+      94             : };
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(InterMolecularTorsions,"INTERMOLECULARTORSIONS")
+      97             : 
+      98           2 : void InterMolecularTorsions::registerKeywords( Keywords& keys ) {
+      99           2 :   MultiColvarBase::registerKeywords( keys );
+     100           4 :   keys.add("atoms","MOLS","The molecules you would like to calculate the torsional angles between. This should be the label/s of \\ref MOLECULES or \\ref PLANES actions");
+     101           4 :   keys.add("atoms-1","MOLSA","In this version of the input the torsional angles between all pairs of atoms including one atom from MOLSA one atom from MOLSB will be computed. "
+     102             :            "This should be the label/s of \\ref MOLECULES or \\ref PLANES actions");
+     103           4 :   keys.add("atoms-1","MOLSB","In this version of the input the torsional angles between all pairs of atoms including one atom from MOLSA one atom from MOLSB will be computed. "
+     104             :            "This should be the label/s of \\ref MOLECULES or \\ref PLANES actions");
+     105           4 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     106           4 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     107           4 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     108           4 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     109           4 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+     110             :            "The following provides information on the \\ref switchingfunction that are available. "
+     111             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     112             :   // Use actionWithDistributionKeywords
+     113           2 :   keys.remove("LOWMEM");
+     114           4 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+     115           2 : }
+     116             : 
+     117           0 : InterMolecularTorsions::InterMolecularTorsions(const ActionOptions& ao):
+     118             :   Action(ao),
+     119           0 :   MultiColvarBase(ao)
+     120             : {
+     121           0 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+     122           0 :     if( getBaseMultiColvar(i)->getNumberOfQuantities()!=5 ) error("input multicolvar does not calculate molecular orientations");
+     123             :   }
+     124             :   // The weight of this does have derivatives
+     125           0 :   weightHasDerivatives=true;
+     126             : 
+     127             :   // Read in the switching function
+     128           0 :   std::string sw, errors; parse("SWITCH",sw);
+     129           0 :   if(sw.length()>0) {
+     130           0 :     switchingFunction.set(sw,errors);
+     131             :   } else {
+     132           0 :     double r_0=-1.0, d_0; int nn, mm;
+     133           0 :     parse("NN",nn); parse("MM",mm);
+     134           0 :     parse("R_0",r_0); parse("D_0",d_0);
+     135           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     136           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+     137             :   }
+     138           0 :   log.printf("  calculating number of links with atoms separation of %s\n",( switchingFunction.description() ).c_str() );
+     139           0 :   std::vector<AtomNumber> all_atoms; readTwoGroups( "MOLS", "MOLSA", "MOLSB", all_atoms );
+     140           0 :   setupMultiColvarBase( all_atoms ); setLinkCellCutoff( switchingFunction.get_dmax() );
+     141             : 
+     142           0 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+     143           0 :     if( !getBaseMultiColvar(i)->hasDifferentiableOrientation() ) error("cannot use multicolvar of type " + getBaseMultiColvar(i)->getName() );
+     144             :   }
+     145             : 
+     146             :   // Create holders for the collective variable
+     147           0 :   readVesselKeywords();
+     148           0 :   plumed_assert( getNumberOfVessels()==0 );
+     149           0 :   std::string input; addVessel( "SUM", input, -1 );
+     150           0 :   readVesselKeywords();
+     151           0 : }
+     152             : 
+     153           0 : double InterMolecularTorsions::calculateWeight( const unsigned& taskCode, const double& weight, multicolvar::AtomValuePack& myatoms ) const {
+     154           0 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     155           0 :   double dfunc, sw = switchingFunction.calculateSqr( distance.modulo2(), dfunc );
+     156             : 
+     157           0 :   if( !doNotCalculateDerivatives() ) {
+     158           0 :     addAtomDerivatives( 0, 0, (-dfunc)*weight*distance, myatoms );
+     159           0 :     addAtomDerivatives( 0, 1, (dfunc)*weight*distance, myatoms );
+     160           0 :     myatoms.addBoxDerivatives( 0, (-dfunc)*weight*Tensor(distance,distance) );
+     161             :   }
+     162           0 :   return sw;
+     163             : }
+     164             : 
+     165           0 : double InterMolecularTorsions::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     166           0 :   Vector v1, v2, dv1, dv2, dconn, conn = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     167             : 
+     168             :   // Retrieve vectors
+     169           0 :   std::vector<double> orient0( 5 ), orient1( 5 );
+     170           0 :   getInputData( 0, true, myatoms, orient0 );
+     171           0 :   getInputData( 1, true, myatoms, orient1 );
+     172           0 :   for(unsigned i=0; i<3; ++i) { v1[i]=orient0[2+i]; v2[i]=orient1[2+i]; }
+     173           0 :   if( getBaseMultiColvar(0)->getNumberOfQuantities()<3 ) return 1.0;
+     174             : 
+     175             :   // Evaluate angle
+     176           0 :   Torsion t; double angle = t.compute( v1, conn, v2, dv1, dconn, dv2 );
+     177           0 :   for(unsigned i=0; i<3; ++i) { orient0[i+2]=dv1[i]; orient1[i+2]=dv2[i]; }
+     178             : 
+     179             :   // And accumulate derivatives
+     180           0 :   if( !doNotCalculateDerivatives() ) {
+     181           0 :     MultiValue& myder0=getInputDerivatives( 0, true, myatoms );
+     182           0 :     mergeInputDerivatives( 1, 2, orient1.size(), 0, orient0, myder0, myatoms );
+     183           0 :     MultiValue& myder1=getInputDerivatives( 1, true, myatoms );
+     184           0 :     mergeInputDerivatives( 1, 2, orient0.size(), 1, orient1, myder1, myatoms );
+     185           0 :     addAtomDerivatives( 1, 0, -dconn, myatoms ); addAtomDerivatives( 1, 1, dconn, myatoms );
+     186           0 :     myatoms.addBoxDerivatives( 1, -extProduct( conn, dconn ) );
+     187             :   }
+     188             : 
+     189             :   return angle;
+     190             : }
+     191             : 
+     192             : }
+     193             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/LocalSteinhardt.h.func-sort-c.html b/coverage/crystallization/LocalSteinhardt.h.func-sort-c.html new file mode 100644 index 000000000000..7fc047cbab16 --- /dev/null +++ b/coverage/crystallization/LocalSteinhardt.h.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/LocalSteinhardt.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - LocalSteinhardt.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131872.2 %
Date:2024-02-22 21:58:45Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q3EEC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q4EEC1ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization15LocalSteinhardtINS0_2Q3EE21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_0
_ZNK4PLMD15crystallization15LocalSteinhardtINS0_2Q4EE21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_0
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q3EE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q4EE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q6EEC1ERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q6EE16registerKeywordsERNS_8KeywordsE7
_ZNK4PLMD15crystallization15LocalSteinhardtINS0_2Q6EE21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_43186
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/LocalSteinhardt.h.func.html b/coverage/crystallization/LocalSteinhardt.h.func.html new file mode 100644 index 000000000000..c0b88cec44ba --- /dev/null +++ b/coverage/crystallization/LocalSteinhardt.h.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/LocalSteinhardt.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - LocalSteinhardt.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131872.2 %
Date:2024-02-22 21:58:45Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q3EE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q3EEC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q4EE16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q4EEC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q6EE16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD15crystallization15LocalSteinhardtINS0_2Q6EEC1ERKNS_13ActionOptionsE5
_ZNK4PLMD15crystallization15LocalSteinhardtINS0_2Q3EE21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_0
_ZNK4PLMD15crystallization15LocalSteinhardtINS0_2Q4EE21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_0
_ZNK4PLMD15crystallization15LocalSteinhardtINS0_2Q6EE21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESC_RS5_RSA_SE_43186
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/LocalSteinhardt.h.gcov.html b/coverage/crystallization/LocalSteinhardt.h.gcov.html new file mode 100644 index 000000000000..941ed526e1ca --- /dev/null +++ b/coverage/crystallization/LocalSteinhardt.h.gcov.html @@ -0,0 +1,139 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/LocalSteinhardt.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - LocalSteinhardt.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131872.2 %
Date:2024-02-22 21:58:45Functions:5955.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_crystallization_LocalSteinhardt_h
+      23             : #define __PLUMED_crystallization_LocalSteinhardt_h
+      24             : #include "OrientationSphere.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace crystallization {
+      28             : 
+      29             : template<class T>
+      30             : class LocalSteinhardt : public OrientationSphere {
+      31             : public:
+      32          11 :   static void registerKeywords( Keywords& keys ) {
+      33          11 :     OrientationSphere::registerKeywords(keys);
+      34          11 :   }
+      35           5 :   explicit LocalSteinhardt(const ActionOptions& ao): Action(ao), OrientationSphere(ao)
+      36             :   {
+      37          12 :     for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+      38           7 :       T* mc=dynamic_cast<T*>( getBaseMultiColvar(i) );
+      39           7 :       if(!mc) {
+      40           0 :         if( getBaseMultiColvar(i)->getNumberOfBaseMultiColvars()==0 ) {
+      41           0 :           error("input action is not calculating the correct vectors");
+      42             :         }
+      43           0 :         for(unsigned j=0; j<getBaseMultiColvar(i)->getNumberOfBaseMultiColvars(); ++j) {
+      44           0 :           T* mmc=dynamic_cast<T*>( getBaseMultiColvar(i)->getBaseMultiColvar(j) );
+      45           0 :           if( !mmc ) error("input action is not calculating the correct vectors");
+      46             :         }
+      47             :       }
+      48             :     }
+      49           5 :   }
+      50       43186 :   double computeVectorFunction( const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+      51             :                                 Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const override {
+      52       43186 :     double dot=0; dconn.zero();
+      53     1166022 :     for(unsigned k=2; k<vec1.size(); ++k) {
+      54     1122836 :       dot+=vec1[k]*vec2[k]; dvec1[k]=vec2[k]; dvec2[k]=vec1[k];
+      55             :     }
+      56       43186 :     return dot;
+      57             :   }
+      58             : };
+      59             : 
+      60             : }
+      61             : }
+      62             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculeOrientation.cpp.func-sort-c.html b/coverage/crystallization/MoleculeOrientation.cpp.func-sort-c.html new file mode 100644 index 000000000000..c8f1a76d3f52 --- /dev/null +++ b/coverage/crystallization/MoleculeOrientation.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/MoleculeOrientation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - MoleculeOrientation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525594.5 %
Date:2024-02-22 21:58:45Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization19MoleculeOrientationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization19MoleculeOrientation29getAbsoluteIndexOfCentralAtomERKj0
_ZN4PLMD15crystallization19MoleculeOrientationC1ERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization19MoleculeOrientation16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD15crystallization19MoleculeOrientation26normalizeVectorDerivativesERNS_10MultiValueE4992
_ZNK4PLMD15crystallization19MoleculeOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE16584
_ZNK4PLMD15crystallization19MoleculeOrientation15normalizeVectorERSt6vectorIdSaIdEE1041228
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculeOrientation.cpp.func.html b/coverage/crystallization/MoleculeOrientation.cpp.func.html new file mode 100644 index 000000000000..c5adfd7632f1 --- /dev/null +++ b/coverage/crystallization/MoleculeOrientation.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/MoleculeOrientation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - MoleculeOrientation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525594.5 %
Date:2024-02-22 21:58:45Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization19MoleculeOrientation16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD15crystallization19MoleculeOrientationC1ERKNS_13ActionOptionsE4
_ZN4PLMD15crystallization19MoleculeOrientationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization19MoleculeOrientation15calculateVectorERNS_11multicolvar13AtomValuePackE16584
_ZNK4PLMD15crystallization19MoleculeOrientation15normalizeVectorERSt6vectorIdSaIdEE1041228
_ZNK4PLMD15crystallization19MoleculeOrientation26normalizeVectorDerivativesERNS_10MultiValueE4992
_ZNK4PLMD15crystallization19MoleculeOrientation29getAbsoluteIndexOfCentralAtomERKj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculeOrientation.cpp.gcov.html b/coverage/crystallization/MoleculeOrientation.cpp.gcov.html new file mode 100644 index 000000000000..184a5d69b414 --- /dev/null +++ b/coverage/crystallization/MoleculeOrientation.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/MoleculeOrientation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - MoleculeOrientation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525594.5 %
Date:2024-02-22 21:58:45Functions:5771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "VectorMultiColvar.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace crystallization {
+      27             : 
+      28             : //+PLUMEDOC MCOLVAR MOLECULES
+      29             : /*
+      30             : Calculate the vectors connecting a pair of atoms in order to represent the orientation of a molecule.
+      31             : 
+      32             : At its simplest this command can be used to calculate the average length of an internal vector in a
+      33             : collection of different molecules.  When used in conjunction with MutiColvarFunctions in can be used
+      34             : to do a variety of more complex tasks.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The following input tells plumed to calculate the distances between two of the atoms in a molecule.
+      39             : This is done for the same set of atoms four different molecules and the average separation is then
+      40             : calculated.
+      41             : 
+      42             : \plumedfile
+      43             : MOLECULES MOL1=1,2 MOL2=3,4 MOL3=5,6 MOL4=7,8 MEAN LABEL=mm
+      44             : PRINT ARG=mm.mean FILE=colvar
+      45             : \endplumedfile
+      46             : 
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51             : 
+      52             : class MoleculeOrientation : public VectorMultiColvar {
+      53             : private:
+      54             :   unsigned nvectors;
+      55             : public:
+      56             :   static void registerKeywords( Keywords& keys );
+      57             :   explicit MoleculeOrientation( const ActionOptions& ao );
+      58             :   AtomNumber getAbsoluteIndexOfCentralAtom( const unsigned& iatom ) const override;
+      59             :   void calculateVector( multicolvar::AtomValuePack& myatoms ) const override;
+      60             :   void normalizeVector( std::vector<double>& vals ) const override;
+      61             :   void normalizeVectorDerivatives( MultiValue& myvals ) const override;
+      62             : };
+      63             : 
+      64             : PLUMED_REGISTER_ACTION(MoleculeOrientation,"MOLECULES")
+      65             : 
+      66           6 : void MoleculeOrientation::registerKeywords( Keywords& keys ) {
+      67          12 :   VectorMultiColvar::registerKeywords( keys ); keys.use("MEAN"); keys.use("VMEAN");
+      68          12 :   keys.add("numbered","MOL","The numerical indices of the atoms in the molecule. The orientation of the molecule is equal to "
+      69             :            "the vector connecting the first two atoms specified.  If a third atom is specified its position "
+      70             :            "is used to specify where the molecule is.  If a third atom is not present the molecule is assumed "
+      71             :            "to be at the center of the vector connecting the first two atoms.");
+      72          12 :   keys.reset_style("MOL","atoms");
+      73           6 : }
+      74             : 
+      75           4 : MoleculeOrientation::MoleculeOrientation( const ActionOptions& ao ):
+      76             :   Action(ao),
+      77           4 :   VectorMultiColvar(ao)
+      78             : {
+      79             :   std::vector<AtomNumber> all_atoms;
+      80           8 :   readAtomsLikeKeyword("MOL",-1,all_atoms);
+      81           4 :   nvectors = std::floor( ablocks.size() / 2 );
+      82           4 :   if( ablocks.size()%2!=0 && 2*nvectors+1!=ablocks.size() ) error("number of atoms in molecule specification is wrong.  Should be two or three.");
+      83             : 
+      84           4 :   if( all_atoms.size()==0 ) error("No atoms were specified");
+      85           4 :   setVectorDimensionality( 3*nvectors ); setupMultiColvarBase( all_atoms );
+      86             : 
+      87           4 :   if( ablocks.size()==2*nvectors+1  ) {
+      88           4 :     std::vector<bool> catom_ind(ablocks.size(), false); catom_ind[ablocks.size()-1]=true;
+      89           4 :     setAtomsForCentralAtom( catom_ind );
+      90             :   }
+      91           4 : }
+      92             : 
+      93           0 : AtomNumber MoleculeOrientation::getAbsoluteIndexOfCentralAtom( const unsigned& iatom ) const {
+      94             :   plumed_dbg_assert( iatom<atom_lab.size() );
+      95           0 :   plumed_assert( atom_lab[iatom].first==0 );
+      96           0 :   return ActionAtomistic::getAbsoluteIndex( ablocks[0][atom_lab[iatom].second] );
+      97             : }
+      98             : 
+      99       16584 : void MoleculeOrientation::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
+     100       33168 :   for(unsigned i=0; i<nvectors; ++i) {
+     101       16584 :     Vector distance; distance=getSeparation( myatoms.getPosition(2*i+0), myatoms.getPosition(2*i+1) );
+     102             : 
+     103       16584 :     addAtomDerivatives( 2+3*i+0, 2*i+0, Vector(-1.0,0,0), myatoms );
+     104       16584 :     addAtomDerivatives( 2+3*i+0, 2*i+1, Vector(+1.0,0,0), myatoms );
+     105       16584 :     myatoms.addBoxDerivatives( 2+3*i+0, Tensor(distance,Vector(-1.0,0,0)) );
+     106       16584 :     myatoms.addValue( 2+3*i+0, distance[0] );
+     107             : 
+     108       16584 :     addAtomDerivatives( 2+3*i+1, 2*i+0, Vector(0,-1.0,0), myatoms );
+     109       16584 :     addAtomDerivatives( 2+3*i+1, 2*i+1, Vector(0,+1.0,0), myatoms );
+     110       16584 :     myatoms.addBoxDerivatives( 2+3*i+1, Tensor(distance,Vector(0,-1.0,0)) );
+     111       16584 :     myatoms.addValue( 2+3*i+1, distance[1] );
+     112             : 
+     113       16584 :     addAtomDerivatives( 2+3*i+2, 2*i+0, Vector(0,0,-1.0), myatoms );
+     114       16584 :     addAtomDerivatives( 2+3*i+2, 2*i+1, Vector(0,0,+1.0), myatoms );
+     115       16584 :     myatoms.addBoxDerivatives( 2+3*i+2, Tensor(distance,Vector(0,0,-1.0)) );
+     116       16584 :     myatoms.addValue( 2+3*i+2, distance[2] );
+     117             :   }
+     118       16584 : }
+     119             : 
+     120     1041228 : void MoleculeOrientation::normalizeVector( std::vector<double>& vals ) const {
+     121     2082456 :   for(unsigned i=0; i<nvectors; ++i) {
+     122             :     double norm=0;
+     123     4164912 :     for(unsigned j=0; j<3; ++j) norm += vals[2+3*i+j]*vals[2+3*i+j];
+     124     1041228 :     norm = sqrt(norm);
+     125             : 
+     126     1041228 :     double inorm = 1.0; if( norm>epsilon ) inorm = 1.0 / norm;
+     127     4164912 :     for(unsigned j=0; j<3; ++j) vals[2+3*i+j] = inorm*vals[2+3*i+j];
+     128             :   }
+     129     1041228 : }
+     130             : 
+     131        4992 : void MoleculeOrientation::normalizeVectorDerivatives( MultiValue& myvals ) const {
+     132        4992 :   std::vector<double> weight( nvectors ), wdf( nvectors );
+     133        9984 :   for(unsigned ivec=0; ivec<nvectors; ++ivec) {
+     134       19968 :     double v=0; for(unsigned jcomp=0; jcomp<3; ++jcomp) v += myvals.get( 2+3*ivec+jcomp )*myvals.get( 2+3*ivec+jcomp );
+     135        4992 :     v=sqrt(v); weight[ivec]=1.0; wdf[ivec]=1.0;
+     136        4992 :     if( v>epsilon ) { weight[ivec] = 1.0 / v; wdf[ivec] = 1.0 / ( v*v*v ); }
+     137             :   }
+     138             : 
+     139       54672 :   for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
+     140       49680 :     unsigned jder=myvals.getActiveIndex(j);
+     141       99360 :     for(unsigned ivec=0; ivec<nvectors; ++ivec) {
+     142      198720 :       double comp2=0.0; for(unsigned jcomp=0; jcomp<3; ++jcomp) comp2 += myvals.get(2+3*ivec+jcomp)*myvals.getDerivative( 2+3*ivec+jcomp, jder );
+     143      198720 :       for(unsigned jcomp=0; jcomp<3; ++jcomp) {
+     144      149040 :         myvals.setDerivative( 2+3*ivec+jcomp, jder, weight[ivec]*myvals.getDerivative( 2+3*ivec+jcomp, jder ) - wdf[ivec]*comp2*myvals.get(2+3*ivec+jcomp) );
+     145             :       }
+     146             :     }
+     147             :   }
+     148        4992 : }
+     149             : 
+     150             : }
+     151             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculePlane.cpp.func-sort-c.html b/coverage/crystallization/MoleculePlane.cpp.func-sort-c.html new file mode 100644 index 000000000000..d1a656c9b3c9 --- /dev/null +++ b/coverage/crystallization/MoleculePlane.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/MoleculePlane.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - MoleculePlane.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:375172.5 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization13MoleculePlaneC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization13MoleculePlane29getAbsoluteIndexOfCentralAtomERKj0
_ZN4PLMD15crystallization13MoleculePlaneC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization13MoleculePlane16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD15crystallization13MoleculePlane15calculateVectorERNS_11multicolvar13AtomValuePackE8888
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculePlane.cpp.func.html b/coverage/crystallization/MoleculePlane.cpp.func.html new file mode 100644 index 000000000000..3653d4d9e43b --- /dev/null +++ b/coverage/crystallization/MoleculePlane.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/MoleculePlane.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - MoleculePlane.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:375172.5 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization13MoleculePlane16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD15crystallization13MoleculePlaneC1ERKNS_13ActionOptionsE2
_ZN4PLMD15crystallization13MoleculePlaneC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization13MoleculePlane15calculateVectorERNS_11multicolvar13AtomValuePackE8888
_ZNK4PLMD15crystallization13MoleculePlane29getAbsoluteIndexOfCentralAtomERKj0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/MoleculePlane.cpp.gcov.html b/coverage/crystallization/MoleculePlane.cpp.gcov.html new file mode 100644 index 000000000000..8c942e345332 --- /dev/null +++ b/coverage/crystallization/MoleculePlane.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/MoleculePlane.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - MoleculePlane.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:375172.5 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "VectorMultiColvar.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace crystallization {
+      27             : 
+      28             : //+PLUMEDOC MCOLVAR PLANES
+      29             : /*
+      30             : Calculate the plane perpendicular to two vectors in order to represent the orientation of a planar molecule.
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : 
+      39             : class MoleculePlane : public VectorMultiColvar {
+      40             : private:
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             :   explicit MoleculePlane( const ActionOptions& ao );
+      44             :   AtomNumber getAbsoluteIndexOfCentralAtom( const unsigned& iatom ) const override;
+      45             :   void calculateVector( multicolvar::AtomValuePack& myatoms ) const override;
+      46             : };
+      47             : 
+      48             : PLUMED_REGISTER_ACTION(MoleculePlane,"PLANES")
+      49             : 
+      50           4 : void MoleculePlane::registerKeywords( Keywords& keys ) {
+      51           4 :   VectorMultiColvar::registerKeywords( keys ); keys.use("VMEAN");
+      52           8 :   keys.add("numbered","MOL","The numerical indices of the atoms in the molecule. If three atoms are specified the orientation "
+      53             :            "of the molecule is taken as the normal to the plane containing the vector connecting the first and "
+      54             :            "second atoms and the vector connecting the second and third atoms.  If four atoms are specified the "
+      55             :            "orientation of the molecule is taken as the normal to the plane containing the vector connecting the "
+      56             :            "first and second atoms and the vector connecting the third and fourth atoms. The molecule is always "
+      57             :            "assumed to lie at the geometric center for the three/four atoms.");
+      58           8 :   keys.reset_style("MOL","atoms");
+      59           4 : }
+      60             : 
+      61           2 : MoleculePlane::MoleculePlane( const ActionOptions& ao ):
+      62             :   Action(ao),
+      63           2 :   VectorMultiColvar(ao)
+      64             : {
+      65             :   std::vector<AtomNumber> all_atoms;
+      66           4 :   readAtomsLikeKeyword("MOL",-1,all_atoms);
+      67           2 :   if( ablocks.size()!=3 && ablocks.size()!=4 ) error("number of atoms in molecule specification is wrong.  Should be three or four.");
+      68             : 
+      69           2 :   if( all_atoms.size()==0 ) error("No atoms were specified");
+      70           2 :   setVectorDimensionality( 3 ); setupMultiColvarBase( all_atoms );
+      71           2 : }
+      72             : 
+      73           0 : AtomNumber MoleculePlane::getAbsoluteIndexOfCentralAtom( const unsigned& iatom ) const {
+      74             :   plumed_dbg_assert( iatom<atom_lab.size() );
+      75           0 :   plumed_assert( atom_lab[iatom].first==0 );
+      76           0 :   return ActionAtomistic::getAbsoluteIndex( ablocks[0][atom_lab[iatom].second] );
+      77             : }
+      78             : 
+      79        8888 : void MoleculePlane::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
+      80        8888 :   Vector d1, d2, cp;
+      81        8888 :   if( myatoms.getNumberOfAtoms()==3 ) {
+      82        8888 :     d1=getSeparation( myatoms.getPosition(1), myatoms.getPosition(0) );
+      83        8888 :     d2=getSeparation( myatoms.getPosition(1), myatoms.getPosition(2) );
+      84             :   } else {
+      85           0 :     d1=getSeparation( myatoms.getPosition(1), myatoms.getPosition(0) );
+      86           0 :     d2=getSeparation( myatoms.getPosition(2), myatoms.getPosition(3) );
+      87             :   }
+      88        8888 :   cp = crossProduct( d1, d2 );
+      89             : 
+      90        8888 :   addAtomDerivatives( 2, 0, crossProduct( Vector(-1.0,0,0), d2 ), myatoms );
+      91        8888 :   if( myatoms.getNumberOfAtoms()==3 ) {
+      92        8888 :     addAtomDerivatives( 2, 1, crossProduct( Vector(+1.0,0,0), d2 ) + crossProduct( Vector(-1.0,0,0), d1 ), myatoms );
+      93        8888 :     addAtomDerivatives( 2, 2, crossProduct( Vector(+1.0,0,0), d1 ), myatoms );
+      94             :   } else {
+      95           0 :     addAtomDerivatives( 2, 1, crossProduct( Vector(+1.0,0,0), d2 ), myatoms );
+      96           0 :     addAtomDerivatives( 2, 2, crossProduct( Vector(-1.0,0,0), d1 ), myatoms );
+      97           0 :     addAtomDerivatives( 2, 3, crossProduct( Vector(+1.0,0,0), d1 ), myatoms );
+      98             :   }
+      99        8888 :   myatoms.addBoxDerivatives( 2, Tensor(d1,crossProduct(Vector(+1.0,0,0), d2)) + Tensor( d2, crossProduct(Vector(-1.0,0,0), d1)) );
+     100        8888 :   myatoms.addValue( 2, cp[0] );
+     101             : 
+     102        8888 :   addAtomDerivatives( 3, 0, crossProduct( Vector(0,-1.0,0), d2 ), myatoms );
+     103        8888 :   if( myatoms.getNumberOfAtoms()==3 ) {
+     104        8888 :     addAtomDerivatives( 3, 1, crossProduct( Vector(0,+1.0,0), d2 ) + crossProduct( Vector(0,-1.0,0), d1 ), myatoms );
+     105        8888 :     addAtomDerivatives( 3, 2, crossProduct( Vector(0,+1.0,0), d1 ), myatoms );
+     106             :   } else {
+     107           0 :     addAtomDerivatives( 3, 1, crossProduct( Vector(0,+1.0,0), d2 ), myatoms );
+     108           0 :     addAtomDerivatives( 3, 2, crossProduct( Vector(0,-1.0,0), d1 ), myatoms );
+     109           0 :     addAtomDerivatives( 3, 3, crossProduct( Vector(0,+1.0,0), d1 ), myatoms );
+     110             :   }
+     111        8888 :   myatoms.addBoxDerivatives( 3, Tensor(d1,crossProduct(Vector(0,+1.0,0), d2)) + Tensor( d2, crossProduct(Vector(0,-1.0,0), d1)) );
+     112        8888 :   myatoms.addValue( 3, cp[1] );
+     113             : 
+     114        8888 :   addAtomDerivatives( 4, 0, crossProduct( Vector(0,0,-1.0), d2 ), myatoms );
+     115        8888 :   if( myatoms.getNumberOfAtoms()==3 ) {
+     116        8888 :     addAtomDerivatives( 4, 1, crossProduct( Vector(0,0,+1.0), d2 ) + crossProduct( Vector(0,0,-1.0), d1 ), myatoms );
+     117        8888 :     addAtomDerivatives( 4, 2, crossProduct( Vector(0,0,+1.0), d1 ), myatoms);
+     118             :   } else {
+     119           0 :     addAtomDerivatives( 4, 1, crossProduct( Vector(0,0,-1.0), d2 ), myatoms);
+     120           0 :     addAtomDerivatives( 4, 2, crossProduct( Vector(0,0,-1.0), d1 ), myatoms);
+     121           0 :     addAtomDerivatives( 4, 3, crossProduct( Vector(0,0,+1.0), d1 ), myatoms);
+     122             :   }
+     123        8888 :   myatoms.addBoxDerivatives( 4, Tensor(d1,crossProduct(Vector(0,0,+1.0), d2)) + Tensor( d2, crossProduct(Vector(0,0,-1.0), d1)) );
+     124        8888 :   myatoms.addValue( 4, cp[2] );
+     125        8888 : }
+     126             : 
+     127             : // Vector MoleculePlane::getCentralAtom(){
+     128             : //   Vector com; com.zero();
+     129             : //   if( getNAtoms()==3 ){
+     130             : //       com+=(1.0/3.0)*getPosition(0);
+     131             : //       com+=(1.0/3.0)*getPosition(1);
+     132             : //       com+=(1.0/3.0)*getPosition(2);
+     133             : //       addCentralAtomDerivatives( 0, (1.0/3.0)*Tensor::identity() );
+     134             : //       addCentralAtomDerivatives( 1, (1.0/3.0)*Tensor::identity() );
+     135             : //       addCentralAtomDerivatives( 2, (1.0/3.0)*Tensor::identity() );
+     136             : //       return com;
+     137             : //   }
+     138             : //   com+=0.25*getPosition(0);
+     139             : //   com+=0.25*getPosition(1);
+     140             : //   com+=0.25*getPosition(2);
+     141             : //   com+=0.25*getPosition(3);
+     142             : //   addCentralAtomDerivatives( 0, 0.25*Tensor::identity() );
+     143             : //   addCentralAtomDerivatives( 1, 0.25*Tensor::identity() );
+     144             : //   addCentralAtomDerivatives( 2, 0.25*Tensor::identity() );
+     145             : //   addCentralAtomDerivatives( 3, 0.25*Tensor::identity() );
+     146             : //   return com;
+     147             : // }
+     148             : 
+     149             : }
+     150             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.cpp.func-sort-c.html b/coverage/crystallization/OrientationSphere.cpp.func-sort-c.html new file mode 100644 index 000000000000..4eaf572557bd --- /dev/null +++ b/coverage/crystallization/OrientationSphere.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/OrientationSphere.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - OrientationSphere.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606690.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphereC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17OrientationSphereC2ERKNS_13ActionOptionsE11
_ZN4PLMD15crystallization17OrientationSphere16registerKeywordsERNS_8KeywordsE21
_ZNK4PLMD15crystallization17OrientationSphere7computeERKjRNS_11multicolvar13AtomValuePackE7782
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.cpp.func.html b/coverage/crystallization/OrientationSphere.cpp.func.html new file mode 100644 index 000000000000..17c048a6cf55 --- /dev/null +++ b/coverage/crystallization/OrientationSphere.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/OrientationSphere.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - OrientationSphere.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606690.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphere16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD15crystallization17OrientationSphereC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17OrientationSphereC2ERKNS_13ActionOptionsE11
_ZNK4PLMD15crystallization17OrientationSphere7computeERKjRNS_11multicolvar13AtomValuePackE7782
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.cpp.gcov.html b/coverage/crystallization/OrientationSphere.cpp.gcov.html new file mode 100644 index 000000000000..2a3b738a9bb5 --- /dev/null +++ b/coverage/crystallization/OrientationSphere.cpp.gcov.html @@ -0,0 +1,208 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/OrientationSphere.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - OrientationSphere.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606690.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "OrientationSphere.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "VectorMultiColvar.h"
+      25             : 
+      26             : using namespace std;
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace crystallization {
+      30             : 
+      31          21 : void OrientationSphere::registerKeywords( Keywords& keys ) {
+      32          21 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      33          42 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      34          42 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      35          42 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      36          42 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      37          42 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      38             :            "The following provides information on the \\ref switchingfunction that are available. "
+      39             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      40             :   // Use actionWithDistributionKeywords
+      41          63 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+      42          63 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN");
+      43          84 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      44          42 :   keys.use("LOWEST"); keys.use("HIGHEST");
+      45          21 : }
+      46             : 
+      47          11 : OrientationSphere::OrientationSphere(const ActionOptions&ao):
+      48             :   Action(ao),
+      49          11 :   MultiColvarBase(ao)
+      50             : {
+      51          11 :   if( getNumberOfBaseMultiColvars()>1 ) warning("not sure if orientation sphere works with more than one base multicolvar - check numerical derivatives");
+      52             :   // Read in the switching function
+      53          22 :   std::string sw, errors; parse("SWITCH",sw);
+      54          11 :   if(sw.length()>0) {
+      55          11 :     switchingFunction.set(sw,errors);
+      56             :   } else {
+      57           0 :     double r_0=-1.0, d_0; int nn, mm;
+      58           0 :     parse("NN",nn); parse("MM",mm);
+      59           0 :     parse("R_0",r_0); parse("D_0",d_0);
+      60           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+      61           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+      62             :   }
+      63          11 :   log.printf("  degree of overlap in orientation between central molecule and those within %s\n",( switchingFunction.description() ).c_str() );
+      64          22 :   log<<"  Bibliography "<<plumed.cite("Tribello, Giberti, Sosso, Salvalaglio and Parrinello, J. Chem. Theory Comput. 13, 1317 (2017)")<<"\n";
+      65             :   // Set the link cell cutoff
+      66          11 :   rcut2 = switchingFunction.get_dmax()*switchingFunction.get_dmax();
+      67          11 :   setLinkCellCutoff( switchingFunction.get_dmax() );
+      68          11 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms );
+      69          11 : }
+      70             : 
+      71        7782 : double OrientationSphere::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+      72        7782 :   double sw, value=0, denom=0, dfunc; Vector ddistance;
+      73        7782 :   unsigned ncomponents=getBaseMultiColvar(0)->getNumberOfQuantities();
+      74        7782 :   std::vector<double> catom_orient( ncomponents ), this_orient( ncomponents );
+      75        7782 :   std::vector<double> this_der( ncomponents ), catom_der( ncomponents );
+      76             : 
+      77        7782 :   getInputData( 0, true, myatoms, catom_orient );
+      78        7782 :   MultiValue& myder0=getInputDerivatives( 0, true, myatoms );
+      79             : 
+      80     1379893 :   for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+      81             :     Vector& distance=myatoms.getPosition(i);
+      82             :     double d2;
+      83     2611747 :     if ( (d2=distance[0]*distance[0])<rcut2 &&
+      84     1239636 :          (d2+=distance[1]*distance[1])<rcut2 &&
+      85     2501268 :          (d2+=distance[2]*distance[2])<rcut2 &&
+      86             :          d2>epsilon ) {
+      87             : 
+      88     1069658 :       sw = switchingFunction.calculateSqr( d2, dfunc );
+      89             : 
+      90     1069658 :       getInputData( i, true, myatoms, this_orient );
+      91             :       // Calculate the dot product wrt to this position
+      92     1069658 :       double f_dot = computeVectorFunction( distance, catom_orient, this_orient, ddistance, catom_der, this_der );
+      93             : 
+      94     1069658 :       if( !doNotCalculateDerivatives() ) {
+      95      233625 :         for(unsigned k=2; k<catom_orient.size(); ++k) { this_der[k]*=sw; catom_der[k]*=sw; }
+      96       10227 :         MultiValue& myder1=getInputDerivatives( i, true, myatoms );
+      97       10227 :         mergeInputDerivatives( 1, 2, this_orient.size(), 0, catom_der, myder0, myatoms );
+      98       10227 :         mergeInputDerivatives( 1, 2, catom_der.size(), i, this_der, myder1, myatoms );
+      99       10227 :         addAtomDerivatives( 1, 0, f_dot*(-dfunc)*distance - sw*ddistance, myatoms );
+     100       10227 :         addAtomDerivatives( 1, i, f_dot*(dfunc)*distance + sw*ddistance, myatoms );
+     101       10227 :         myatoms.addBoxDerivatives( 1, (-dfunc)*f_dot*Tensor(distance,distance) - sw*extProduct(distance,ddistance) );
+     102       10227 :         myder1.clearAll();
+     103             : 
+     104       10227 :         addAtomDerivatives( -1, 0, (-dfunc)*distance, myatoms );
+     105       10227 :         addAtomDerivatives( -1, i, (dfunc)*distance, myatoms );
+     106       10227 :         myatoms.addTemporyBoxDerivatives( (-dfunc)*Tensor(distance,distance) );
+     107             : 
+     108             :       }
+     109     1069658 :       value += sw*f_dot;
+     110     1069658 :       denom += sw;
+     111             :     }
+     112             :   }
+     113        7782 :   double rdenom, df2, pref=calculateCoordinationPrefactor( denom, df2 );
+     114        7782 :   if( std::fabs(denom)>epsilon ) { rdenom = 1.0 / denom; }
+     115           0 :   else { plumed_assert(std::fabs(value)<epsilon); rdenom=1.0; }
+     116             : 
+     117             :   // Now divide everything
+     118        7782 :   double rdenom2=rdenom*rdenom;
+     119        7782 :   updateActiveAtoms( myatoms ); MultiValue& myvals=myatoms.getUnderlyingMultiValue();
+     120       57486 :   for(unsigned i=0; i<myvals.getNumberActive(); ++i) {
+     121       49704 :     unsigned ider=myvals.getActiveIndex(i);
+     122             :     double  dgd=myvals.getTemporyDerivative(ider);
+     123       49704 :     myvals.setDerivative( 1, ider, rdenom*(pref*myvals.getDerivative(1,ider)+value*df2*dgd) - (value*pref*dgd)*rdenom2 );
+     124             :   }
+     125             : 
+     126       15564 :   return pref*rdenom*value;
+     127             : }
+     128             : 
+     129             : }
+     130             : }
+     131             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.h.func-sort-c.html b/coverage/crystallization/OrientationSphere.h.func-sort-c.html new file mode 100644 index 000000000000..8e889004dc6c --- /dev/null +++ b/coverage/crystallization/OrientationSphere.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/OrientationSphere.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - OrientationSphere.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphere10isPeriodicEv12
_ZNK4PLMD15crystallization17OrientationSphere30calculateCoordinationPrefactorERKdRd3318
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.h.func.html b/coverage/crystallization/OrientationSphere.h.func.html new file mode 100644 index 000000000000..0027c0f6de7f --- /dev/null +++ b/coverage/crystallization/OrientationSphere.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/OrientationSphere.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - OrientationSphere.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17OrientationSphere10isPeriodicEv12
_ZNK4PLMD15crystallization17OrientationSphere30calculateCoordinationPrefactorERKdRd3318
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/OrientationSphere.h.gcov.html b/coverage/crystallization/OrientationSphere.h.gcov.html new file mode 100644 index 000000000000..3d25f9606f7e --- /dev/null +++ b/coverage/crystallization/OrientationSphere.h.gcov.html @@ -0,0 +1,130 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/OrientationSphere.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - OrientationSphere.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_crystallization_OrientationSphere_h
+      23             : #define __PLUMED_crystallization_OrientationSphere_h
+      24             : 
+      25             : #include "multicolvar/MultiColvarBase.h"
+      26             : #include "multicolvar/AtomValuePack.h"
+      27             : #include "tools/SwitchingFunction.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace crystallization {
+      31             : 
+      32             : class OrientationSphere : public multicolvar::MultiColvarBase {
+      33             : private:
+      34             :   double rcut2;
+      35             :   SwitchingFunction switchingFunction;
+      36             : public:
+      37             :   static void registerKeywords( Keywords& keys );
+      38             :   explicit OrientationSphere(const ActionOptions&);
+      39             :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const ;
+      40             :   virtual double computeVectorFunction( const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+      41             :                                         Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const = 0;
+      42             :   virtual double calculateCoordinationPrefactor( const double& coord, double& df ) const ;
+      43          12 :   bool isPeriodic() { return false; }
+      44             : };
+      45             : 
+      46             : inline
+      47        3318 : double OrientationSphere::calculateCoordinationPrefactor( const double& coord, double& df ) const {
+      48        3318 :   df=0.0; return 1.0;
+      49             : }
+      50             : 
+      51             : }
+      52             : }
+      53             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/PolymerAngles.cpp.func-sort-c.html b/coverage/crystallization/PolymerAngles.cpp.func-sort-c.html new file mode 100644 index 000000000000..8f1fb446e53b --- /dev/null +++ b/coverage/crystallization/PolymerAngles.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/PolymerAngles.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - PolymerAngles.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization13PolymerAnglesC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization13PolymerAnglesC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization13PolymerAngles16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD15crystallization13PolymerAngles21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESA_RS3_RS8_SC_616
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/PolymerAngles.cpp.func.html b/coverage/crystallization/PolymerAngles.cpp.func.html new file mode 100644 index 000000000000..fae2c65fb38c --- /dev/null +++ b/coverage/crystallization/PolymerAngles.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/PolymerAngles.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - PolymerAngles.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization13PolymerAngles16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD15crystallization13PolymerAnglesC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization13PolymerAnglesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization13PolymerAngles21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESA_RS3_RS8_SC_616
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/PolymerAngles.cpp.gcov.html b/coverage/crystallization/PolymerAngles.cpp.gcov.html new file mode 100644 index 000000000000..2602d003ec07 --- /dev/null +++ b/coverage/crystallization/PolymerAngles.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/PolymerAngles.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - PolymerAngles.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "OrientationSphere.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC MCOLVARF POLYMER_ANGLES
+      26             : /*
+      27             : Calculate a function to investigate the relative orientations of polymer angles
+      28             : 
+      29             : This CV takes the vectors calculated by a \ref PLANES action as input and computes the following function
+      30             : of the relative angles, \f$\theta\f$, between the vectors that are normal to the pairs of input vectors:
+      31             : 
+      32             : \f[
+      33             : s = \frac{ 3 \cos^2 \theta - 1 }{ 2 }
+      34             : \f]
+      35             : 
+      36             : This average of this quantity over all the vectors in the first coordination sphere around each of the PLANES specified
+      37             : is then calculated.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : The example below calculates a set of vectors using the \ref PLANES action.  The average number for the function \f$s\f$
+      42             : defined above is then computed over the first coordination sphere of each of the centers of mass of the molecules that were
+      43             : used to define the planes.  Finally the average of these quantities is computed an printed to a file.
+      44             : 
+      45             : \plumedfile
+      46             : PLANES ...
+      47             : MOL1=9,10,11
+      48             : MOL2=89,90,91
+      49             : MOL3=473,474,475
+      50             : MOL4=1161,1162,1163
+      51             : MOL5=1521,1522,1523
+      52             : MOL6=1593,1594,1595
+      53             : MOL7=1601,1602,1603
+      54             : MOL8=2201,2202,2203
+      55             : LABEL=m3
+      56             : ... PLANES
+      57             : 
+      58             : s3: POLYMER_ANGLES SPECIES=m3 LOWMEM SWITCH={RATIONAL R_0=0.6} MEAN
+      59             : PRINT ARG=s3.mean FILE=colvar
+      60             : \endplumedfile
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : namespace PLMD {
+      66             : namespace crystallization {
+      67             : 
+      68             : class PolymerAngles : public OrientationSphere {
+      69             : public:
+      70             :   static void registerKeywords( Keywords& keys );
+      71             :   explicit PolymerAngles(const ActionOptions& ao);
+      72             :   double computeVectorFunction( const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+      73             :                                 Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const override;
+      74             : };
+      75             : 
+      76             : PLUMED_REGISTER_ACTION(PolymerAngles,"POLYMER_ANGLES")
+      77             : 
+      78           3 : void PolymerAngles::registerKeywords( Keywords& keys ) {
+      79           3 :   OrientationSphere::registerKeywords(keys);
+      80           3 : }
+      81             : 
+      82           1 : PolymerAngles::PolymerAngles(const ActionOptions& ao):
+      83             :   Action(ao),
+      84           1 :   OrientationSphere(ao)
+      85             : {
+      86           1 :   if( mybasemulticolvars.size()==0 ) error("SMAC must take multicolvar as input");
+      87           2 :   for(unsigned i=0; i<mybasemulticolvars.size(); ++i) {
+      88           1 :     if( (mybasemulticolvars[i]->getNumberOfQuantities()-2)%3!=0 ) error("POLYMER_ANGLES is only possible with three dimensional vectors");
+      89             :   }
+      90           1 : }
+      91             : 
+      92         616 : double PolymerAngles::computeVectorFunction( const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+      93             :     Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const {
+      94             : 
+      95         616 :   plumed_assert( (vec1.size()-2)==3 );
+      96        2464 :   double dot = 0; for(unsigned k=0; k<3; ++k) dot += vec1[2+k]*vec2[2+k];
+      97        2464 :   double ans = 1.5*dot*dot - 0.5; for(unsigned k=0; k<3; ++k) { dvec1[2+k]=3*dot*vec2[2+k]; dvec2[2+k]=3*dot*vec1[2+k]; }
+      98         616 :   return ans;
+      99             : }
+     100             : 
+     101             : }
+     102             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q3.cpp.func-sort-c.html b/coverage/crystallization/Q3.cpp.func-sort-c.html new file mode 100644 index 000000000000..05f9b71b142c --- /dev/null +++ b/coverage/crystallization/Q3.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Q3.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Q3.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31717.6 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization2Q3C1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q3C2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q316registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q3.cpp.func.html b/coverage/crystallization/Q3.cpp.func.html new file mode 100644 index 000000000000..a57e1cc775cd --- /dev/null +++ b/coverage/crystallization/Q3.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Q3.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Q3.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31717.6 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization2Q316registerKeywordsERNS_8KeywordsE2
_ZN4PLMD15crystallization2Q3C1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q3C2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q3.cpp.gcov.html b/coverage/crystallization/Q3.cpp.gcov.html new file mode 100644 index 000000000000..a08b8267f6eb --- /dev/null +++ b/coverage/crystallization/Q3.cpp.gcov.html @@ -0,0 +1,300 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Q3.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Q3.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31717.6 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Steinhardt.h"
+      23             : #include "LocalSteinhardt.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : //+PLUMEDOC MCOLVAR Q3
+      27             : /*
+      28             : Calculate 3rd order Steinhardt parameters.
+      29             : 
+      30             : The 3rd order Steinhardt parameters allow us to measure the degree to which the first coordination shell
+      31             : around an atom is ordered.  The Steinhardt parameter for atom, \f$i\f$ is complex vector whose components are
+      32             : calculated using the following formula:
+      33             : 
+      34             : \f[
+      35             : q_{3m}(i) = \frac{\sum_j \sigma( r_{ij} ) Y_{3m}(\mathbf{r}_{ij}) }{\sum_j \sigma( r_{ij} ) }
+      36             : \f]
+      37             : 
+      38             : where \f$Y_{3m}\f$ is one of the 3rd order spherical harmonics so \f$m\f$ is a number that runs from \f$-3\f$ to
+      39             : \f$+3\f$.  The function \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between
+      40             : atoms \f$i\f$ and \f$j\f$.  The parameters of this function should be set so that it the function is equal to one
+      41             : when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.
+      42             : 
+      43             : The Steinhardt parameters can be used to measure the degree of order in the system in a variety of different ways.  The
+      44             : simplest way of measuring whether or not the coordination sphere is ordered is to simply take the norm of the above vector i.e.
+      45             : 
+      46             : \f[
+      47             : Q_3(i) = \sqrt{ \sum_{m=-3}^3 q_{3m}(i)^{*} q_{3m}(i) }
+      48             : \f]
+      49             : 
+      50             : This norm is small when the coordination shell is disordered and larger when the coordination shell is ordered. Furthermore, when
+      51             : the keywords LESS_THAN, MIN, MAX, HISTOGRAM, MEAN and so on are used with this colvar it is the distribution of these normed quantities
+      52             : that is investigated.
+      53             : 
+      54             : Other measures of order can be taken by averaging the components of the individual \f$q_3\f$ vectors individually or by taking dot products of
+      55             : the \f$q_{3}\f$ vectors on adjacent atoms.  More information on these variables can be found in the documentation for \ref LOCAL_Q3,
+      56             : \ref LOCAL_AVERAGE and \ref NLINKS.
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : The following command calculates the average Q3 parameter for the 64 atoms in a box of Lennard Jones and prints this
+      61             : quantity to a file called colvar:
+      62             : 
+      63             : \plumedfile
+      64             : Q3 SPECIES=1-64 D_0=1.3 R_0=0.2 MEAN LABEL=q3
+      65             : PRINT ARG=q3.mean FILE=colvar
+      66             : \endplumedfile
+      67             : 
+      68             : The following command calculates the histogram of Q3 parameters for the 64 atoms in a box of Lennard Jones and prints these
+      69             : quantities to a file called colvar:
+      70             : 
+      71             : \plumedfile
+      72             : Q3 SPECIES=1-64 D_0=1.3 R_0=0.2 HISTOGRAM={GAUSSIAN LOWER=0.0 UPPER=1.0 NBINS=20 SMEAR=0.1} LABEL=q3
+      73             : PRINT ARG=q3.* FILE=colvar
+      74             : \endplumedfile
+      75             : 
+      76             : The following command could be used to measure the Q3 parameters that describe the arrangement of chlorine ions around the
+      77             : sodium atoms in sodium chloride.  The imagined system here is composed of 64 NaCl formula units and the atoms are arranged in the input
+      78             : with the 64 Na\f$^+\f$ ions followed by the 64 Cl\f$-\f$ ions.  Once again the average Q3 parameter is calculated and output to a
+      79             : file called colvar
+      80             : 
+      81             : \plumedfile
+      82             : Q3 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN LABEL=q3
+      83             : PRINT ARG=q3.mean FILE=colvar
+      84             : \endplumedfile
+      85             : 
+      86             : If you simply want to examine the values of the Q3 parameters for each of the atoms in your system you can do so by exploiting the
+      87             : command \ref DUMPMULTICOLVAR as shown in the example below.  The following output file will output a file in an extended xyz format
+      88             : called q3.xyz for each frame of the analyzed MD trajectory.  The first column in this file will contain a dummy name for each of the
+      89             : atoms, columns 2-4 will then contain the x, y and z positions of the atoms, column 5 will contain the value of the Q3 parameter, columns
+      90             : 6-12 will contain the real parts of the director of the \f$q_{3m}\f$ vector while columns 12-19 will contain the imaginary parts of this director.
+      91             : 
+      92             : \plumedfile
+      93             : q3: Q3 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN
+      94             : DUMPMULTICOLVAR DATA=q3 FILE=q3.xyz
+      95             : \endplumedfile
+      96             : 
+      97             : */
+      98             : //+ENDPLUMEDOC
+      99             : 
+     100             : //+PLUMEDOC MCOLVARF LOCAL_Q3
+     101             : /*
+     102             : Calculate the local degree of order around an atoms by taking the average dot product between the \f$q_3\f$ vector on the central atom and the \f$q_3\f$ vector on the atoms in the first coordination sphere.
+     103             : 
+     104             : The \ref Q3 command allows one to calculate one complex vectors for each of the atoms in your system that describe the degree of order in the coordination sphere
+     105             : around a particular atom. The difficulty with these vectors comes when combining the order parameters from all of the individual atoms/molecules so as to get a
+     106             : measure of the global degree of order for the system. The simplest way of doing this - calculating the average Steinhardt parameter - can be problematic. If one is
+     107             : examining nucleation say only the order parameters for those atoms in the nucleus will change significantly when the nucleus forms. The order parameters for the
+     108             : atoms in the surrounding liquid will remain pretty much the same. As such if one models a small nucleus embedded in a very large amount of solution/melt any
+     109             : change in the average order parameter will be negligible. Substantial changes in the value of this average can be observed in simulations of nucleation but only
+     110             : because the number of atoms is relatively small.
+     111             : 
+     112             : When the average \ref Q3 parameter is used to bias the dynamics a problems
+     113             : can occur. These averaged coordinates cannot distinguish between the correct,
+     114             : single-nucleus pathway and a concerted pathway in which all the atoms rearrange
+     115             : themselves into their solid-like configuration simultaneously. This second type
+     116             : of pathway would be impossible in reality because there is a large entropic
+     117             : barrier that prevents concerted processes like this from happening.  However,
+     118             : in the finite sized systems that are commonly simulated this barrier is reduced
+     119             : substantially. As a result in simulations where average Steinhardt parameters
+     120             : are biased there are often quite dramatic system size effects
+     121             : 
+     122             : If one wants to simulate nucleation using some form on
+     123             : biased dynamics what is really required is an order parameter that measures:
+     124             : 
+     125             : - Whether or not the coordination spheres around atoms are ordered
+     126             : - Whether or not the atoms that are ordered are clustered together in a crystalline nucleus
+     127             : 
+     128             : \ref LOCAL_AVERAGE and \ref NLINKS are variables that can be combined with the Steinhardt parameters allow to calculate variables that satisfy these requirements.
+     129             : LOCAL_Q3 is another variable that can be used in these sorts of calculations. The LOCAL_Q3 parameter for a particular atom is a number that measures the extent to
+     130             : which the orientation of the atoms in the first coordination sphere of an atom match the orientation of the central atom.  It does this by calculating the following
+     131             : quantity for each of the atoms in the system:
+     132             : 
+     133             : \f[
+     134             :  s_i = \frac{ \sum_j \sigma( r_{ij} ) \sum_{m=-3}^3 q_{3m}^{*}(i)q_{3m}(j) }{ \sum_j \sigma( r_{ij} ) }
+     135             : \f]
+     136             : 
+     137             : where \f$q_{3m}(i)\f$ and \f$q_{3m}(j)\f$ are the 3rd order Steinhardt vectors calculated for atom \f$i\f$ and atom \f$j\f$ respectively and the asterisk denotes complex
+     138             : conjugation.  The function
+     139             : \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between atoms \f$i\f$ and \f$j\f$.  The parameters of this function should be set
+     140             : so that it the function is equal to one when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.  The sum in the numerator
+     141             : of this expression is the dot product of the Steinhardt parameters for atoms \f$i\f$ and \f$j\f$ and thus measures the degree to which the orientations of these
+     142             : adjacent atoms is correlated.
+     143             : 
+     144             : \par Examples
+     145             : 
+     146             : The following command calculates the average value of the LOCAL_Q3 parameter for the 64 Lennard Jones atoms in the system under study and prints this
+     147             : quantity to a file called colvar.
+     148             : 
+     149             : \plumedfile
+     150             : Q3 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q3
+     151             : LOCAL_Q3 SPECIES=q3 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LABEL=lq3
+     152             : PRINT ARG=lq3.mean FILE=colvar
+     153             : \endplumedfile
+     154             : 
+     155             : The following input calculates the distribution of LOCAL_Q3 parameters at any given time and outputs this information to a file.
+     156             : 
+     157             : \plumedfile
+     158             : Q3 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q3
+     159             : LOCAL_Q3 SPECIES=q3 SWITCH={RATIONAL D_0=1.3 R_0=0.2} HISTOGRAM={GAUSSIAN LOWER=0.0 UPPER=1.0 NBINS=20 SMEAR=0.1} LABEL=lq3
+     160             : PRINT ARG=lq3.* FILE=colvar
+     161             : \endplumedfile
+     162             : 
+     163             : The following calculates the LOCAL_Q3 parameters for atoms 1-5 only. For each of these atoms comparisons of the geometry of the coordination sphere
+     164             : are done with those of all the other atoms in the system.  The final quantity is the average and is outputted to a file
+     165             : 
+     166             : \plumedfile
+     167             : Q3 SPECIESA=1-5 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q3a
+     168             : Q3 SPECIESA=6-64 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q3b
+     169             : 
+     170             : LOCAL_Q3 SPECIES=q3a,q3b SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LOWMEM LABEL=w3
+     171             : PRINT ARG=w3.* FILE=colvar
+     172             : \endplumedfile
+     173             : 
+     174             : */
+     175             : //+ENDPLUMEDOC
+     176             : 
+     177             : 
+     178             : namespace PLMD {
+     179             : namespace crystallization {
+     180             : 
+     181             : class Q3 : public Steinhardt {
+     182             : public:
+     183             :   static void registerKeywords( Keywords& keys );
+     184             :   explicit Q3( const ActionOptions& ao );
+     185             : };
+     186             : 
+     187             : PLUMED_REGISTER_ACTION(Q3,"Q3")
+     188             : typedef LocalSteinhardt<Q3> LOCAL_Q3;
+     189             : PLUMED_REGISTER_ACTION(LOCAL_Q3,"LOCAL_Q3")
+     190             : 
+     191           2 : void Q3::registerKeywords( Keywords& keys ) {
+     192           2 :   Steinhardt::registerKeywords( keys );
+     193           2 : }
+     194             : 
+     195           0 : Q3::Q3(const ActionOptions& ao ):
+     196             :   Action(ao),
+     197           0 :   Steinhardt(ao)
+     198             : {
+     199           0 :   setAngularMomentum(3);
+     200             : 
+     201             : // Spherical harmonics normalization:
+     202             : // even =  sqrt ( ((2l+1)*(l-m)!) / (4*pi*(l+m)!) )
+     203             : // odd  = -sqrt ( ((2l+1)*(l-m)!) / (4*pi*(l+m)!) )
+     204             : 
+     205           0 :   normaliz.resize( 4 );
+     206           0 :   normaliz[0] = sqrt( ( 7.0*6.0 ) / (4.0*pi*6.0) );
+     207           0 :   normaliz[1] = -sqrt( ( 7.0*2.0 ) / (4.0*pi*24.0) );
+     208           0 :   normaliz[2] = sqrt( ( 7.0*1.0) / (4.0*pi*120.0) );
+     209           0 :   normaliz[3] = -sqrt( ( 7.0*1.0) / (4.0*pi*720.0) );
+     210             : 
+     211             : // Legendre polynomial coefficients of order three
+     212             : 
+     213           0 :   coeff_poly.resize( 4 );
+     214           0 :   coeff_poly[0]=0.0;
+     215           0 :   coeff_poly[1]=-1.5;
+     216           0 :   coeff_poly[2]=0.0;
+     217           0 :   coeff_poly[3]=2.5;
+     218             : 
+     219           0 : }
+     220             : 
+     221             : }
+     222             : }
+     223             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q4.cpp.func-sort-c.html b/coverage/crystallization/Q4.cpp.func-sort-c.html new file mode 100644 index 000000000000..2e70ba61caef --- /dev/null +++ b/coverage/crystallization/Q4.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Q4.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Q4.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization2Q4C2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q4C1ERKNS_13ActionOptionsE3
_ZN4PLMD15crystallization2Q416registerKeywordsERNS_8KeywordsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q4.cpp.func.html b/coverage/crystallization/Q4.cpp.func.html new file mode 100644 index 000000000000..d4ca1db9c0ad --- /dev/null +++ b/coverage/crystallization/Q4.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Q4.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Q4.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization2Q416registerKeywordsERNS_8KeywordsE5
_ZN4PLMD15crystallization2Q4C1ERKNS_13ActionOptionsE3
_ZN4PLMD15crystallization2Q4C2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q4.cpp.gcov.html b/coverage/crystallization/Q4.cpp.gcov.html new file mode 100644 index 000000000000..5d3b591ea5fb --- /dev/null +++ b/coverage/crystallization/Q4.cpp.gcov.html @@ -0,0 +1,292 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Q4.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Q4.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Steinhardt.h"
+      23             : #include "LocalSteinhardt.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : //+PLUMEDOC MCOLVAR Q4
+      27             : /*
+      28             : Calculate fourth order Steinhardt parameters.
+      29             : 
+      30             : The fourth order Steinhardt parameters allow us to measure the degree to which the first coordination shell
+      31             : around an atom is ordered.  The Steinhardt parameter for atom, \f$i\f$ is complex vector whose components are
+      32             : calculated using the following formula:
+      33             : 
+      34             : \f[
+      35             : q_{4m}(i) = \frac{\sum_j \sigma( r_{ij} ) Y_{4m}(\mathbf{r}_{ij}) }{\sum_j \sigma( r_{ij} ) }
+      36             : \f]
+      37             : 
+      38             : where \f$Y_{4m}\f$ is one of the fourth order spherical harmonics so \f$m\f$ is a number that runs from \f$-4\f$ to
+      39             : \f$+4\f$.  The function \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between
+      40             : atoms \f$i\f$ and \f$j\f$.  The parameters of this function should be set so that it the function is equal to one
+      41             : when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.
+      42             : 
+      43             : The Steinhardt parameters can be used to measure the degree of order in the system in a variety of different ways.  The
+      44             : simplest way of measuring whether or not the coordination sphere is ordered is to simply take the norm of the above vector i.e.
+      45             : 
+      46             : \f[
+      47             : Q_4(i) = \sqrt{ \sum_{m=-4}^4 q_{4m}(i)^{*} q_{4m}(i) }
+      48             : \f]
+      49             : 
+      50             : This norm is small when the coordination shell is disordered and larger when the coordination shell is ordered. Furthermore, when
+      51             : the keywords LESS_THAN, MIN, MAX, HISTOGRAM, MEAN and so on are used with this colvar it is the distribution of these normed quantities
+      52             : that is investigated.
+      53             : 
+      54             : Other measures of order can be taken by averaging the components of the individual \f$q_4\f$ vectors individually or by taking dot products of
+      55             : the \f$q_{4}\f$ vectors on adjacent atoms.  More information on these variables can be found in the documentation for \ref LOCAL_Q4,
+      56             : \ref LOCAL_AVERAGE and \ref NLINKS.
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : The following command calculates the average Q4 parameter for the 64 atoms in a box of Lennard Jones and prints this
+      61             : quantity to a file called colvar:
+      62             : 
+      63             : \plumedfile
+      64             : Q4 SPECIES=1-64 D_0=1.3 R_0=0.2 MEAN LABEL=q4
+      65             : PRINT ARG=q4.mean FILE=colvar
+      66             : \endplumedfile
+      67             : 
+      68             : The following command calculates the histogram of Q4 parameters for the 64 atoms in a box of Lennard Jones and prints these
+      69             : quantities to a file called colvar:
+      70             : 
+      71             : \plumedfile
+      72             : Q4 SPECIES=1-64 D_0=1.3 R_0=0.2 HISTOGRAM={GAUSSIAN LOWER=0.0 UPPER=1.0 NBINS=20 SMEAR=0.1} LABEL=q4
+      73             : PRINT ARG=q4.* FILE=colvar
+      74             : \endplumedfile
+      75             : 
+      76             : The following command could be used to measure the Q4 parameters that describe the arrangement of chlorine ions around the
+      77             : sodium atoms in sodium chloride.  The imagined system here is composed of 64 NaCl formula units and the atoms are arranged in the input
+      78             : with the 64 Na\f$^+\f$ ions followed by the 64 Cl\f$-\f$ ions.  Once again the average Q4 parameter is calculated and output to a
+      79             : file called colvar
+      80             : 
+      81             : \plumedfile
+      82             : Q4 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN LABEL=q4
+      83             : PRINT ARG=q4.mean FILE=colvar
+      84             : \endplumedfile
+      85             : 
+      86             : If you simply want to examine the values of the Q4 parameters for each of the atoms in your system you can do so by exploiting the
+      87             : command \ref DUMPMULTICOLVAR as shown in the example below.  The following output file will output a file in an extended xyz format
+      88             : called q$.xyz for each frame of the analyzed MD trajectory.  The first column in this file will contain a dummy name for each of the
+      89             : atoms, columns 2-4 will then contain the x, y and z positions of the atoms, column 5 will contain the value of the Q4 parameter, columns
+      90             : 6-15 will contain the real parts of the director of the \f$q_{6m}\f$ vector while columns 15-24 will contain the imaginary parts of this director.
+      91             : 
+      92             : \plumedfile
+      93             : q4: Q4 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN
+      94             : DUMPMULTICOLVAR DATA=q4 FILE=q4.xyz
+      95             : \endplumedfile
+      96             : 
+      97             : */
+      98             : //+ENDPLUMEDOC
+      99             : 
+     100             : //+PLUMEDOC MCOLVARF LOCAL_Q4
+     101             : /*
+     102             : Calculate the local degree of order around an atoms by taking the average dot product between the \f$q_4\f$ vector on the central atom and the \f$q_4\f$ vector on the atoms in the first coordination sphere.
+     103             : 
+     104             : The \ref Q4 command allows one to calculate one complex vectors for each of the atoms in your system that describe the degree of order in the coordination sphere
+     105             : around a particular atom. The difficulty with these vectors comes when combining the order parameters from all of the individual atoms/molecules so as to get a
+     106             : measure of the global degree of order for the system. The simplest way of doing this - calculating the average Steinhardt parameter - can be problematic. If one is
+     107             : examining nucleation say only the order parameters for those atoms in the nucleus will change significantly when the nucleus forms. The order parameters for the
+     108             : atoms in the surrounding liquid will remain pretty much the same. As such if one models a small nucleus embedded in a very large amount of solution/melt any
+     109             : change in the average order parameter will be negligible. Substantial changes in the value of this average can be observed in simulations of nucleation but only
+     110             : because the number of atoms is relatively small.
+     111             : 
+     112             : When the average \ref Q4 parameter is used to bias the dynamics a problems
+     113             : can occur. These averaged coordinates cannot distinguish between the correct,
+     114             : single-nucleus pathway and a concerted pathway in which all the atoms rearrange
+     115             : themselves into their solid-like configuration simultaneously. This second type
+     116             : of pathway would be impossible in reality because there is a large entropic
+     117             : barrier that prevents concerted processes like this from happening.  However,
+     118             : in the finite sized systems that are commonly simulated this barrier is reduced
+     119             : substantially. As a result in simulations where average Steinhardt parameters
+     120             : are biased there are often quite dramatic system size effects
+     121             : 
+     122             : If one wants to simulate nucleation using some form on
+     123             : biased dynamics what is really required is an order parameter that measures:
+     124             : 
+     125             : - Whether or not the coordination spheres around atoms are ordered
+     126             : - Whether or not the atoms that are ordered are clustered together in a crystalline nucleus
+     127             : 
+     128             : \ref LOCAL_AVERAGE and \ref NLINKS are variables that can be combined with the Steinhardt parameters allow to calculate variables that satisfy these requirements.
+     129             : LOCAL_Q4 is another variable that can be used in these sorts of calculations. The LOCAL_Q4 parameter for a particular atom is a number that measures the extent to
+     130             : which the orientation of the atoms in the first coordination sphere of an atom match the orientation of the central atom.  It does this by calculating the following
+     131             : quantity for each of the atoms in the system:
+     132             : 
+     133             : \f[
+     134             :  s_i = \frac{ \sum_j \sigma( r_{ij} ) \sum_{m=-4}^4 q_{4m}^{*}(i)q_{4m}(j) }{ \sum_j \sigma( r_{ij} ) }
+     135             : \f]
+     136             : 
+     137             : where \f$q_{4m}(i)\f$ and \f$q_{4m}(j)\f$ are the fourth order Steinhardt vectors calculated for atom \f$i\f$ and atom \f$j\f$ respectively and the asterisk denotes
+     138             : complex conjugation.  The function
+     139             : \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between atoms \f$i\f$ and \f$j\f$.  The parameters of this function should be set
+     140             : so that it the function is equal to one when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.  The sum in the numerator
+     141             : of this expression is the dot product of the Steinhardt parameters for atoms \f$i\f$ and \f$j\f$ and thus measures the degree to which the orientations of these
+     142             : adjacent atoms is correlated.
+     143             : 
+     144             : \par Examples
+     145             : 
+     146             : The following command calculates the average value of the LOCAL_Q4 parameter for the 64 Lennard Jones atoms in the system under study and prints this
+     147             : quantity to a file called colvar.
+     148             : 
+     149             : \plumedfile
+     150             : Q4 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q4
+     151             : LOCAL_Q4 SPECIES=q4 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LABEL=lq4
+     152             : PRINT ARG=lq4.mean FILE=colvar
+     153             : \endplumedfile
+     154             : 
+     155             : The following input calculates the distribution of LOCAL_Q4 parameters at any given time and outputs this information to a file.
+     156             : 
+     157             : \plumedfile
+     158             : Q4 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q4
+     159             : LOCAL_Q4 SPECIES=q4 SWITCH={RATIONAL D_0=1.3 R_0=0.2} HISTOGRAM={GAUSSIAN LOWER=0.0 UPPER=1.0 NBINS=20 SMEAR=0.1} LABEL=lq4
+     160             : PRINT ARG=lq4.* FILE=colvar
+     161             : \endplumedfile
+     162             : 
+     163             : The following calculates the LOCAL_Q4 parameters for atoms 1-5 only. For each of these atoms comparisons of the geometry of the coordination sphere
+     164             : are done with those of all the other atoms in the system.  The final quantity is the average and is outputted to a file
+     165             : 
+     166             : \plumedfile
+     167             : Q4 SPECIESA=1-5 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q4a
+     168             : Q4 SPECIESA=6-64 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q4b
+     169             : 
+     170             : LOCAL_Q4 SPECIES=q4a,q4b SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LOWMEM LABEL=w4
+     171             : PRINT ARG=w4.* FILE=colvar
+     172             : \endplumedfile
+     173             : 
+     174             : */
+     175             : //+ENDPLUMEDOC
+     176             : 
+     177             : namespace PLMD {
+     178             : namespace crystallization {
+     179             : 
+     180             : class Q4 : public Steinhardt {
+     181             : public:
+     182             :   static void registerKeywords( Keywords& keys );
+     183             :   explicit Q4( const ActionOptions& ao );
+     184             : };
+     185             : 
+     186             : PLUMED_REGISTER_ACTION(Q4,"Q4")
+     187             : typedef LocalSteinhardt<Q4> LOCAL_Q4;
+     188             : PLUMED_REGISTER_ACTION(LOCAL_Q4,"LOCAL_Q4")
+     189             : 
+     190           5 : void Q4::registerKeywords( Keywords& keys ) {
+     191           5 :   Steinhardt::registerKeywords( keys );
+     192           5 : }
+     193             : 
+     194           3 : Q4::Q4(const ActionOptions& ao ):
+     195             :   Action(ao),
+     196           3 :   Steinhardt(ao)
+     197             : {
+     198           3 :   setAngularMomentum(4);
+     199             : 
+     200           3 :   normaliz.resize( 5 );
+     201           3 :   normaliz[0] = sqrt( ( 9.0*24.0 ) / (4.0*pi*24.0) );
+     202           3 :   normaliz[1] = -sqrt( ( 9.0*6.0 ) / (4.0*pi*120.0) );
+     203           3 :   normaliz[2] = sqrt( ( 9.0*2.0) / (4.0*pi*720.0) );
+     204           3 :   normaliz[3] = -sqrt( ( 9.0*1) / (4.0*pi*5040.0) );
+     205           3 :   normaliz[4] = sqrt( (9.0*1) / (4.0*pi*40320.0) );
+     206             : 
+     207           3 :   coeff_poly.resize( 5 );
+     208           3 :   coeff_poly[0]=0.375; coeff_poly[1]=0.0;
+     209           3 :   coeff_poly[2]=-3.75; coeff_poly[3]=0.0;
+     210           3 :   coeff_poly[4]=4.375;
+     211           3 : }
+     212             : 
+     213             : }
+     214             : }
+     215             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q6.cpp.func-sort-c.html b/coverage/crystallization/Q6.cpp.func-sort-c.html new file mode 100644 index 000000000000..49116172e853 --- /dev/null +++ b/coverage/crystallization/Q6.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Q6.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Q6.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization2Q6C2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization2Q6C1ERKNS_13ActionOptionsE15
_ZN4PLMD15crystallization2Q616registerKeywordsERNS_8KeywordsE17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q6.cpp.func.html b/coverage/crystallization/Q6.cpp.func.html new file mode 100644 index 000000000000..41f954d73daf --- /dev/null +++ b/coverage/crystallization/Q6.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Q6.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Q6.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization2Q616registerKeywordsERNS_8KeywordsE17
_ZN4PLMD15crystallization2Q6C1ERKNS_13ActionOptionsE15
_ZN4PLMD15crystallization2Q6C2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Q6.cpp.gcov.html b/coverage/crystallization/Q6.cpp.gcov.html new file mode 100644 index 000000000000..3b4fecb53fcf --- /dev/null +++ b/coverage/crystallization/Q6.cpp.gcov.html @@ -0,0 +1,295 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Q6.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Q6.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Steinhardt.h"
+      23             : #include "LocalSteinhardt.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : //+PLUMEDOC MCOLVAR Q6
+      27             : /*
+      28             : Calculate sixth order Steinhardt parameters.
+      29             : 
+      30             : The sixth order Steinhardt parameters allow us to measure the degree to which the first coordination shell
+      31             : around an atom is ordered.  The Steinhardt parameter for atom, \f$i\f$ is complex vector whose components are
+      32             : calculated using the following formula:
+      33             : 
+      34             : \f[
+      35             : q_{6m}(i) = \frac{\sum_j \sigma( r_{ij} ) Y_{6m}(\mathbf{r}_{ij}) }{\sum_j \sigma( r_{ij} ) }
+      36             : \f]
+      37             : 
+      38             : where \f$Y_{6m}\f$ is one of the sixth order spherical harmonics so \f$m\f$ is a number that runs from \f$-6\f$ to
+      39             : \f$+6\f$.  The function \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between
+      40             : atoms \f$i\f$ and \f$j\f$.  The parameters of this function should be set so that it the function is equal to one
+      41             : when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.
+      42             : 
+      43             : The Steinhardt parameters can be used to measure the degree of order in the system in a variety of different ways.  The
+      44             : simplest way of measuring whether or not the coordination sphere is ordered is to simply take the norm of the above vector i.e.
+      45             : 
+      46             : \f[
+      47             : Q_6(i) = \sqrt{ \sum_{m=-6}^6 q_{6m}(i)^{*} q_{6m}(i) }
+      48             : \f]
+      49             : 
+      50             : This norm is small when the coordination shell is disordered and larger when the coordination shell is ordered. Furthermore, when
+      51             : the keywords LESS_THAN, MIN, MAX, HISTOGRAM, MEAN and so on are used with this colvar it is the distribution of these normed quantities
+      52             : that is investigated.
+      53             : 
+      54             : Other measures of order can be taken by averaging the components of the individual \f$q_6\f$ vectors individually or by taking dot products of
+      55             : the \f$q_{6}\f$ vectors on adjacent atoms.  More information on these variables can be found in the documentation for \ref LOCAL_Q6,
+      56             : \ref LOCAL_AVERAGE and \ref NLINKS.
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : The following command calculates the average Q6 parameter for the 64 atoms in a box of Lennard Jones and prints this
+      61             : quantity to a file called colvar:
+      62             : 
+      63             : \plumedfile
+      64             : Q6 SPECIES=1-64 D_0=1.3 R_0=0.2 MEAN LABEL=q6
+      65             : PRINT ARG=q6.mean FILE=colvar
+      66             : \endplumedfile
+      67             : 
+      68             : The following command calculates the histogram of Q6 parameters for the 64 atoms in a box of Lennard Jones and prints these
+      69             : quantities to a file called colvar:
+      70             : 
+      71             : \plumedfile
+      72             : Q6 SPECIES=1-64 D_0=1.3 R_0=0.2 HISTOGRAM={GAUSSIAN LOWER=0.0 UPPER=1.0 NBINS=20 SMEAR=0.1} LABEL=q6
+      73             : PRINT ARG=q6.* FILE=colvar
+      74             : \endplumedfile
+      75             : 
+      76             : The following command could be used to measure the Q6 parameters that describe the arrangement of chlorine ions around the
+      77             : sodium atoms in sodium chloride.  The imagined system here is composed of 64 NaCl formula units and the atoms are arranged in the input
+      78             : with the 64 Na\f$^+\f$ ions followed by the 64 Cl\f$-\f$ ions.  Once again the average Q6 parameter is calculated and output to a
+      79             : file called colvar
+      80             : 
+      81             : \plumedfile
+      82             : Q6 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN LABEL=q6
+      83             : PRINT ARG=q6.mean FILE=colvar
+      84             : \endplumedfile
+      85             : 
+      86             : If you simply want to examine the values of the Q6 parameters for each of the atoms in your system you can do so by exploiting the
+      87             : command \ref DUMPMULTICOLVAR as shown in the example below.  The following output file will output a file in an extended xyz format
+      88             : called q6.xyz for each frame of the analyzed MD trajectory.  The first column in this file will contain a dummy name for each of the
+      89             : atoms, columns 2-4 will then contain the x, y and z positions of the atoms, column 5 will contain the value of the Q6 parameter, columns
+      90             : 6-19 will contain the real parts of the director of the \f$q_{6m}\f$ vector while columns 20-33 will contain the imaginary parts of this director.
+      91             : 
+      92             : \plumedfile
+      93             : q6: Q6 SPECIESA=1-64 SPECIESB=65-128 D_0=1.3 R_0=0.2 MEAN
+      94             : DUMPMULTICOLVAR DATA=q6 FILE=q6.xyz
+      95             : \endplumedfile
+      96             : 
+      97             : */
+      98             : //+ENDPLUMEDOC
+      99             : 
+     100             : //+PLUMEDOC MCOLVARF LOCAL_Q6
+     101             : /*
+     102             : Calculate the local degree of order around an atoms by taking the average dot product between the \f$q_6\f$ vector on the central atom and the \f$q_6\f$ vector on the atoms in the first coordination sphere.
+     103             : 
+     104             : The \ref Q6 command allows one to calculate one complex vectors for each of the atoms in your system that describe the degree of order in the coordination sphere
+     105             : around a particular atom. The difficulty with these vectors comes when combining the order parameters from all of the individual atoms/molecules so as to get a
+     106             : measure of the global degree of order for the system. The simplest way of doing this - calculating the average Steinhardt parameter - can be problematic. If one is
+     107             : examining nucleation say only the order parameters for those atoms in the nucleus will change significantly when the nucleus forms. The order parameters for the
+     108             : atoms in the surrounding liquid will remain pretty much the same. As such if one models a small nucleus embedded in a very large amount of solution/melt any
+     109             : change in the average order parameter will be negligible. Substantial changes in the value of this average can be observed in simulations of nucleation but only
+     110             : because the number of atoms is relatively small.
+     111             : 
+     112             : When the average \ref Q6 parameter is used to bias the dynamics a problems
+     113             : can occur. These averaged coordinates cannot distinguish between the correct,
+     114             : single-nucleus pathway and a concerted pathway in which all the atoms rearrange
+     115             : themselves into their solid-like configuration simultaneously. This second type
+     116             : of pathway would be impossible in reality because there is a large entropic
+     117             : barrier that prevents concerted processes like this from happening.  However,
+     118             : in the finite sized systems that are commonly simulated this barrier is reduced
+     119             : substantially. As a result in simulations where average Steinhardt parameters
+     120             : are biased there are often quite dramatic system size effects
+     121             : 
+     122             : If one wants to simulate nucleation using some form on
+     123             : biased dynamics what is really required is an order parameter that measures:
+     124             : 
+     125             : - Whether or not the coordination spheres around atoms are ordered
+     126             : - Whether or not the atoms that are ordered are clustered together in a crystalline nucleus
+     127             : 
+     128             : \ref LOCAL_AVERAGE and \ref NLINKS are variables that can be combined with the Steinhardt parameters allow to calculate variables that satisfy these requirements.
+     129             : LOCAL_Q6 is another variable that can be used in these sorts of calculations. The LOCAL_Q6 parameter for a particular atom is a number that measures the extent to
+     130             : which the orientation of the atoms in the first coordination sphere of an atom match the orientation of the central atom.  It does this by calculating the following
+     131             : quantity for each of the atoms in the system:
+     132             : 
+     133             : \f[
+     134             :  s_i = \frac{ \sum_j \sigma( r_{ij} ) \sum_{m=-6}^6 q_{6m}^{*}(i)q_{6m}(j) }{ \sum_j \sigma( r_{ij} ) }
+     135             : \f]
+     136             : 
+     137             : where \f$q_{6m}(i)\f$ and \f$q_{6m}(j)\f$ are the sixth order Steinhardt vectors calculated for atom \f$i\f$ and atom \f$j\f$ respectively and the asterisk denotes
+     138             : complex conjugation.  The function
+     139             : \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between atoms \f$i\f$ and \f$j\f$.  The parameters of this function should be set
+     140             : so that it the function is equal to one when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.  The sum in the numerator
+     141             : of this expression is the dot product of the Steinhardt parameters for atoms \f$i\f$ and \f$j\f$ and thus measures the degree to which the orientations of these
+     142             : adjacent atoms is correlated.
+     143             : 
+     144             : \par Examples
+     145             : 
+     146             : The following command calculates the average value of the LOCAL_Q6 parameter for the 64 Lennard Jones atoms in the system under study and prints this
+     147             : quantity to a file called colvar.
+     148             : 
+     149             : \plumedfile
+     150             : Q6 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q6
+     151             : LOCAL_Q6 SPECIES=q6 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LABEL=lq6
+     152             : PRINT ARG=lq6.mean FILE=colvar
+     153             : \endplumedfile
+     154             : 
+     155             : The following input calculates the distribution of LOCAL_Q6 parameters at any given time and outputs this information to a file.
+     156             : 
+     157             : \plumedfile
+     158             : Q6 SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=q6
+     159             : LOCAL_Q6 SPECIES=q6 SWITCH={RATIONAL D_0=1.3 R_0=0.2} HISTOGRAM={GAUSSIAN LOWER=0.0 UPPER=1.0 NBINS=20 SMEAR=0.1} LABEL=lq6
+     160             : PRINT ARG=lq6.* FILE=colvar
+     161             : \endplumedfile
+     162             : 
+     163             : The following calculates the LOCAL_Q6 parameters for atoms 1-5 only. For each of these atoms comparisons of the geometry of the coordination sphere
+     164             : are done with those of all the other atoms in the system.  The final quantity is the average and is outputted to a file
+     165             : 
+     166             : \plumedfile
+     167             : Q6 SPECIESA=1-5 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q6a
+     168             : Q6 SPECIESA=6-64 SPECIESB=1-64 D_0=1.3 R_0=0.2 LABEL=q6b
+     169             : 
+     170             : LOCAL_Q6 SPECIES=q6a,q6b SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LOWMEM LABEL=w6
+     171             : PRINT ARG=w6.* FILE=colvar
+     172             : \endplumedfile
+     173             : 
+     174             : */
+     175             : //+ENDPLUMEDOC
+     176             : 
+     177             : namespace PLMD {
+     178             : namespace crystallization {
+     179             : 
+     180             : class Q6 : public Steinhardt {
+     181             : public:
+     182             :   static void registerKeywords( Keywords& keys );
+     183             :   explicit Q6( const ActionOptions& ao );
+     184             : };
+     185             : 
+     186             : PLUMED_REGISTER_ACTION(Q6,"Q6")
+     187             : typedef LocalSteinhardt<Q6> LOCAL_Q6;
+     188             : PLUMED_REGISTER_ACTION(LOCAL_Q6,"LOCAL_Q6")
+     189             : 
+     190          17 : void Q6::registerKeywords( Keywords& keys ) {
+     191          17 :   Steinhardt::registerKeywords( keys );
+     192          17 : }
+     193             : 
+     194          15 : Q6::Q6(const ActionOptions& ao ):
+     195             :   Action(ao),
+     196          15 :   Steinhardt(ao)
+     197             : {
+     198          15 :   setAngularMomentum(6);
+     199             : 
+     200          15 :   normaliz.resize( 7 );
+     201          15 :   normaliz[0] = sqrt( ( 13.0*720.0 ) / (4.0*pi*720.0) );
+     202          15 :   normaliz[1] = -sqrt( ( 13.0*120.0 ) / (4.0*pi*5040) );
+     203          15 :   normaliz[2] = sqrt( ( 13.0*24) / (4.0*pi*40320) );
+     204          15 :   normaliz[3] = -sqrt( ( 13.0*6) / (4.0*pi*362880) );
+     205          15 :   normaliz[4] = sqrt( (13.0*2) / (4.0*pi*3628800) );
+     206          15 :   normaliz[5] = -sqrt( (13.0*1) / (4.0*pi*39916800) );
+     207          15 :   normaliz[6] = sqrt( (13.0*1) / (4.0*pi*479001600) );
+     208             : 
+     209          15 :   coeff_poly.resize( 7 );
+     210          15 :   coeff_poly[0]=-0.3125; coeff_poly[1]=0.0;
+     211          15 :   coeff_poly[2]=6.5625; coeff_poly[3]=0.0;
+     212          15 :   coeff_poly[4]=-19.6875; coeff_poly[5]=0.0;
+     213          15 :   coeff_poly[6]=14.4375;
+     214          15 : }
+     215             : 
+     216             : }
+     217             : }
+     218             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/SMAC.cpp.func-sort-c.html b/coverage/crystallization/SMAC.cpp.func-sort-c.html new file mode 100644 index 000000000000..af13df81c2ba --- /dev/null +++ b/coverage/crystallization/SMAC.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/SMAC.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - SMAC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization4SMACC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization4SMACC1ERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization4SMAC16registerKeywordsERNS_8KeywordsE7
_ZNK4PLMD15crystallization4SMAC30calculateCoordinationPrefactorERKdRd4464
_ZNK4PLMD15crystallization4SMAC21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESA_RS3_RS8_SC_1025856
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/SMAC.cpp.func.html b/coverage/crystallization/SMAC.cpp.func.html new file mode 100644 index 000000000000..1d6f7697d72e --- /dev/null +++ b/coverage/crystallization/SMAC.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/SMAC.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - SMAC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization4SMAC16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD15crystallization4SMACC1ERKNS_13ActionOptionsE5
_ZN4PLMD15crystallization4SMACC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization4SMAC21computeVectorFunctionERKNS_13VectorGenericILj3EEERKSt6vectorIdSaIdEESA_RS3_RS8_SC_1025856
_ZNK4PLMD15crystallization4SMAC30calculateCoordinationPrefactorERKdRd4464
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/SMAC.cpp.gcov.html b/coverage/crystallization/SMAC.cpp.gcov.html new file mode 100644 index 000000000000..f43ad3e02a5f --- /dev/null +++ b/coverage/crystallization/SMAC.cpp.gcov.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/SMAC.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - SMAC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "OrientationSphere.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Torsion.h"
+      25             : #include "tools/KernelFunctions.h"
+      26             : 
+      27             : //+PLUMEDOC MCOLVARF SMAC
+      28             : /*
+      29             : Calculate a variant on the SMAC collective variable
+      30             : 
+      31             : This variable is discussed in \cite smac-paper
+      32             : 
+      33             : The SMAC collective variable can be used to study the formation of molecular solids
+      34             : from either the melt or from solution.  The idea behind this variable is that what
+      35             : differentiates a molecular solid from a molecular liquid is an alignment of
+      36             : internal vectors in neighboring molecules.  In other words, the relative orientation
+      37             : of neighboring molecules is no longer random as it is in a liquid.  In a solid particular
+      38             : torsional angles between molecules are preferred.  As such this CV calculates the following
+      39             : average:
+      40             : 
+      41             : \f[
+      42             : s_i = \frac{ \left\{ 1 - \psi\left[ \sum_{j \ne i} \sigma(r_{ij}) \right] \right\} \sum_{j \ne i} \sigma(r_{ij}) \sum_n K_n(\theta_{ij}) }{ \sum_{j \ne i} \sigma(r_{ij}) }
+      43             : \f]
+      44             : 
+      45             : In this expression \f$r_{ij}\f$ is the distance between molecule \f$i\f$ and molecule \f$j\f$ and \f$\sigma(r_{ij})\f$ is a
+      46             : \ref switchingfunction that acts on this distance.  By including this switching function in the second summation in the
+      47             : numerator and in the denominator we are thus ensuring that we calculate an average over the molecules in the first coordination
+      48             : sphere of molecule \f$i\f$.  All molecules in higher coordination sphere will essentially contribute zero to the sums in the
+      49             : above expression because their \f$\sigma(r_{ij})\f$ will be very small.  \f$\psi\f$ is also a switching function.  The term
+      50             : including \f$\psi\f$ in the numerator is there to ensure that only those molecules that are attached to a reasonably large
+      51             : number of molecules.  It is important to include this "more than" switching function when you are simulating nucleation
+      52             : from solution with this CV.  Lastly, the $K_n functions are \ref kernelfunctions that take the torsion angle, \f$\theta_{ij}\f$, between the
+      53             : internal orientation vectors for molecules \f$i\f$ and \f$j\f$ as input.  These kernel functions should be set so that they are
+      54             : equal to one when the relative orientation of the molecules are as they are in the solid and equal to zero otherwise.
+      55             : The final \f$s_i\f$ quantity thus measures whether (on average) the molecules in the first coordination sphere around molecule \f$i\f$
+      56             : are oriented as they would be in the solid.  Furthermore, this Action is a multicolvar so you can calculate the \f$s_i\f$ values
+      57             : for all the molecules in your system simultaneously and then determine the average, the number less than and so on.
+      58             : 
+      59             : \par Examples
+      60             : 
+      61             : In the example below the orientation of the molecules in the system is determined by calculating the
+      62             : vector that connects a pair of atoms.  SMAC is then used to determine whether the molecules are sitting
+      63             : in a solid or liquid like environment.  We can determine whether the environment is solid or liquid like because in the solid the torsional angle between
+      64             : the bond vectors on adjacent molecules is close to 0 or \f$\pi\f$.  The final quantity that is output to the colvar
+      65             : file measures the number of molecules that have a SMAC parameter that is greater than 0.7.  N.B. By using
+      66             : the indices of three atoms for each of the MOL keywords below we are telling PLUMED to use the first two
+      67             : numbers to determine the orientation of the molecule that will ultimately be used when calculating the \f$\theta_{ij}\f$
+      68             : terms in the formula above.  The atom with the third index meanwhile is used when we calculate \f$r_{ij}\f$.
+      69             : 
+      70             : \plumedfile
+      71             : MOLECULES ...
+      72             : MOL1=9,10,9
+      73             : MOL2=89,90,89
+      74             : MOL3=473,474,473
+      75             : MOL4=1161,1162,1161
+      76             : MOL5=1521,1522,1521
+      77             : MOL6=1593,1594,1593
+      78             : MOL7=1601,1602,1601
+      79             : MOL8=2201,2202,2201
+      80             : LABEL=m3
+      81             : ... MOLECULES
+      82             : 
+      83             : SMAC ...
+      84             :    SPECIES=m3 LOWMEM
+      85             :    KERNEL1={GAUSSIAN CENTER=0 SIGMA=0.480} KERNEL2={GAUSSIAN CENTER=pi SIGMA=0.480}
+      86             :    SWITCH={RATIONAL R_0=0.6} MORE_THAN={RATIONAL R_0=0.7} SWITCH_COORD={EXP R_0=4}
+      87             :    LABEL=s2
+      88             : ... SMAC
+      89             : 
+      90             : PRINT ARG=s2.* FILE=colvar
+      91             : \endplumedfile
+      92             : 
+      93             : This second example works in a way that is very similar to the previous command.  Now, however,
+      94             : the orientation of the molecules is determined by finding the plane that contains the positions
+      95             : of three atoms.
+      96             : 
+      97             : \plumedfile
+      98             : PLANES ...
+      99             : MOL1=9,10,11
+     100             : MOL2=89,90,91
+     101             : MOL3=473,474,475
+     102             : MOL4=1161,1162,1163
+     103             : MOL5=1521,1522,1523
+     104             : MOL6=1593,1594,1595
+     105             : MOL7=1601,1602,1603
+     106             : MOL8=2201,2202,2203
+     107             : VMEAN
+     108             : LABEL=m3
+     109             : ... PLANES
+     110             : 
+     111             : SMAC ...
+     112             :    SPECIES=m3 LOWMEM
+     113             :    KERNEL1={GAUSSIAN CENTER=0 SIGMA=0.480} KERNEL2={GAUSSIAN CENTER=pi SIGMA=0.480}
+     114             :    SWITCH={RATIONAL R_0=0.6} MORE_THAN={RATIONAL R_0=0.7} SWITCH_COORD={EXP R_0=3.0}
+     115             :    LABEL=s2
+     116             : ... SMAC
+     117             : 
+     118             : PRINT ARG=s2.* FILE=colvar
+     119             : \endplumedfile
+     120             : 
+     121             : */
+     122             : //+ENDPLUMEDOC
+     123             : 
+     124             : namespace PLMD {
+     125             : namespace crystallization {
+     126             : 
+     127             : class SMAC : public OrientationSphere {
+     128             : private:
+     129             :   std::vector<KernelFunctions> kernels;
+     130             :   SwitchingFunction coord_switch;
+     131             : public:
+     132             :   static void registerKeywords( Keywords& keys );
+     133             :   explicit SMAC(const ActionOptions& ao);
+     134             :   double computeVectorFunction( const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+     135             :                                 Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const override;
+     136             :   double calculateCoordinationPrefactor( const double& coord, double& df ) const override;
+     137             : };
+     138             : 
+     139             : PLUMED_REGISTER_ACTION(SMAC,"SMAC")
+     140             : 
+     141           7 : void SMAC::registerKeywords( Keywords& keys ) {
+     142           7 :   OrientationSphere::registerKeywords(keys);
+     143          14 :   keys.add("numbered","KERNEL","The kernels used in the function of the angle");
+     144          14 :   keys.add("compulsory","SWITCH_COORD","This keyword is used to define the coordination switching function.");
+     145          14 :   keys.reset_style("KERNEL","compulsory");
+     146           7 : }
+     147             : 
+     148           5 : SMAC::SMAC(const ActionOptions& ao):
+     149             :   Action(ao),
+     150           5 :   OrientationSphere(ao)
+     151             : {
+     152           5 :   if( mybasemulticolvars.size()==0 ) error("SMAC must take multicolvar as input");
+     153          11 :   for(unsigned i=0; i<mybasemulticolvars.size(); ++i) {
+     154           6 :     if( (mybasemulticolvars[i]->getNumberOfQuantities()-2)%3!=0 ) error("SMAC is only possible with three dimensional vectors");
+     155             :   }
+     156             : 
+     157             :   std::string kernelinpt;
+     158          10 :   for(int i=1;; i++) {
+     159          30 :     if( !parseNumbered("KERNEL",i,kernelinpt) ) break;
+     160          10 :     KernelFunctions mykernel( kernelinpt );
+     161          10 :     kernels.push_back( mykernel );
+     162          10 :   }
+     163           5 :   if( kernels.size()==0 ) error("no kernels defined");
+     164             : 
+     165          10 :   std::string sw, errors; parse("SWITCH_COORD",sw);
+     166           5 :   if(sw.length()==0) error("SWITCH_COORD keyword is missing");
+     167           5 :   coord_switch.set(sw,errors);
+     168           5 :   if(errors.length()>0) error("the following errors were found in input to SWITCH_COORD : " + errors );
+     169             : 
+     170           5 : }
+     171             : 
+     172     1025856 : double SMAC::computeVectorFunction( const Vector& conn, const std::vector<double>& vec1, const std::vector<double>& vec2,
+     173             :                                     Vector& dconn, std::vector<double>& dvec1, std::vector<double>& dvec2 ) const {
+     174             : 
+     175     1025856 :   unsigned nvectors = ( vec1.size() - 2 ) / 3; plumed_assert( (vec1.size()-2)%3==0 );
+     176     1025856 :   std::vector<Vector> dv1(nvectors), dv2(nvectors), tdconn(nvectors); Torsion t; std::vector<Vector> v1(nvectors), v2(nvectors);
+     177             :   std::vector<std::unique_ptr<Value>> pos;
+     178     3077568 :   for(unsigned i=0; i<nvectors; ++i) { pos.emplace_back( Tools::make_unique<Value>() ); pos[i]->setDomain( "-pi", "pi" ); }
+     179             : 
+     180     2051712 :   for(unsigned j=0; j<nvectors; ++j) {
+     181     4103424 :     for(unsigned k=0; k<3; ++k) {
+     182     3077568 :       v1[j][k]=vec1[2+3*j+k]; v2[j][k]=vec2[2+3*j+k];
+     183             :     }
+     184     1025856 :     double angle = t.compute( v1[j], conn, v2[j], dv1[j], tdconn[j], dv2[j] );
+     185             :     pos[j]->set( angle );
+     186             :   }
+     187             : 
+     188     1025856 :   auto pos_ptr=Tools::unique2raw(pos);
+     189             : 
+     190     1025856 :   double ans=0; std::vector<double> deriv( nvectors ), df( nvectors, 0 );
+     191     3077568 :   for(unsigned i=0; i<kernels.size(); ++i) {
+     192     2051712 :     ans += kernels[i].evaluate( pos_ptr, deriv );
+     193     4103424 :     for(unsigned j=0; j<nvectors; ++j) df[j] += deriv[j];
+     194             :   }
+     195     2051712 :   dconn.zero(); for(unsigned j=0; j<nvectors; ++j) dconn += df[j]*tdconn[j];
+     196     2051712 :   for(unsigned j=0; j<nvectors; ++j) {
+     197     4103424 :     for(unsigned k=0; k<3; ++k) { dvec1[2+3*j+k]=df[j]*dv1[j][k]; dvec2[2+3*j+k]=df[j]*dv2[j][k]; }
+     198             :   }
+     199     1025856 :   return ans;
+     200     1025856 : }
+     201             : 
+     202        4464 : double SMAC::calculateCoordinationPrefactor( const double& coord, double& df ) const {
+     203        4464 :   double f=1-coord_switch.calculate( coord, df ); df*=-coord; return f;
+     204             : }
+     205             : 
+     206             : }
+     207             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/SimpleCubic.cpp.func-sort-c.html b/coverage/crystallization/SimpleCubic.cpp.func-sort-c.html new file mode 100644 index 000000000000..801f44807cc5 --- /dev/null +++ b/coverage/crystallization/SimpleCubic.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/SimpleCubic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - SimpleCubic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11SimpleCubicC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization11SimpleCubicC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11SimpleCubic16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD15crystallization11SimpleCubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/SimpleCubic.cpp.func.html b/coverage/crystallization/SimpleCubic.cpp.func.html new file mode 100644 index 000000000000..12dac0f6a7e5 --- /dev/null +++ b/coverage/crystallization/SimpleCubic.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/SimpleCubic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - SimpleCubic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11SimpleCubic16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD15crystallization11SimpleCubicC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11SimpleCubicC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization11SimpleCubic22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/SimpleCubic.cpp.gcov.html b/coverage/crystallization/SimpleCubic.cpp.gcov.html new file mode 100644 index 000000000000..9594cf0f2ce2 --- /dev/null +++ b/coverage/crystallization/SimpleCubic.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/SimpleCubic.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - SimpleCubic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CubicHarmonicBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : #include <string>
+      26             : #include <cmath>
+      27             : 
+      28             : using namespace std;
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace crystallization {
+      32             : 
+      33             : //+PLUMEDOC MCOLVAR SIMPLECUBIC
+      34             : /*
+      35             : Calculate whether or not the coordination spheres of atoms are arranged as they would be in a simple cubic structure.
+      36             : 
+      37             : We can measure how similar the environment around atom \f$i\f$ is to a simple cubic structure is by evaluating
+      38             : the following quantity:
+      39             : 
+      40             : \f[
+      41             : s_i = \frac{ \sum_{i \ne j} \sigma(r_{ij}) \left[ \frac{ x_{ij}^4 + y_{ij}^4 + z_{ij}^4 }{r_{ij}^4} \right] }{ \sum_{i \ne j} \sigma(r_{ij}) }
+      42             : \f]
+      43             : 
+      44             : In this expression \f$x_{ij}\f$, \f$y_{ij}\f$ and \f$z_{ij}\f$ are the \f$x\f$, \f$y\f$ and \f$z\f$ components of the vector connecting atom \f$i\f$ to
+      45             : atom \f$j\f$ and \f$r_{ij}\f$ is the magnitude of this vector.  \f$\sigma(r_{ij})\f$ is a \ref switchingfunction that acts on the distance between atom \f$i\f$ and atom \f$j\f$ and its inclusion in the numerator and the denominator of the above expression as well as the fact that we are summing
+      46             : over all of the other atoms in the system ensures that we are calculating an average
+      47             : of the function of \f$x_{ij}\f$, \f$y_{ij}\f$ and \f$z_{ij}\f$ for the atoms in the first coordination sphere around atom \f$i\f$.
+      48             : This quantity is once again a multicolvar so you can compute it for multiple atoms using a single PLUMED action and then compute
+      49             : the average value for the atoms in your system, the number of atoms that have an \f$s_i\f$ value that is more that some target and
+      50             : so on.  Notice also that you can rotate the reference frame if you are using a non-standard unit cell.
+      51             : 
+      52             : 
+      53             : \par Examples
+      54             : 
+      55             : The following input tells plumed to calculate the simple cubic parameter for the atoms 1-100 with themselves.
+      56             : The mean value is then calculated.
+      57             : \plumedfile
+      58             : SIMPLECUBIC SPECIES=1-100 R_0=1.0 MEAN
+      59             : \endplumedfile
+      60             : 
+      61             : The following input tells plumed to look at the ways atoms 1-100 are within 3.0 are arranged about atoms
+      62             : from 101-110.  The number of simple cubic parameters that are greater than 0.8 is then output
+      63             : \plumedfile
+      64             : SIMPLECUBIC SPECIESA=101-110 SPECIESB=1-100 R_0=3.0 MORE_THAN={RATIONAL R_0=0.8 NN=6 MM=12 D_0=0}
+      65             : \endplumedfile
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : 
+      71             : class SimpleCubic : public CubicHarmonicBase {
+      72             : public:
+      73             :   static void registerKeywords( Keywords& keys );
+      74             :   explicit SimpleCubic(const ActionOptions&);
+      75             :   double calculateCubicHarmonic( const Vector& distance, const double& d2, Vector& myder ) const override;
+      76             : };
+      77             : 
+      78             : PLUMED_REGISTER_ACTION(SimpleCubic,"SIMPLECUBIC")
+      79             : 
+      80           3 : void SimpleCubic::registerKeywords( Keywords& keys ) {
+      81           3 :   CubicHarmonicBase::registerKeywords( keys );
+      82           3 : }
+      83             : 
+      84           1 : SimpleCubic::SimpleCubic(const ActionOptions&ao):
+      85             :   Action(ao),
+      86           1 :   CubicHarmonicBase(ao)
+      87             : {
+      88           1 :   checkRead();
+      89           1 : }
+      90             : 
+      91        4032 : double SimpleCubic::calculateCubicHarmonic( const Vector& distance, const double& d2, Vector& myder ) const {
+      92        4032 :   double x2 = distance[0]*distance[0];
+      93        4032 :   double x3 = distance[0]*x2;
+      94        4032 :   double x4 = distance[0]*x3;
+      95             : 
+      96        4032 :   double y2 = distance[1]*distance[1];
+      97        4032 :   double y3 = distance[1]*y2;
+      98        4032 :   double y4 = distance[1]*y3;
+      99             : 
+     100        4032 :   double z2 = distance[2]*distance[2];
+     101        4032 :   double z3 = distance[2]*z2;
+     102        4032 :   double z4 = distance[2]*z3;
+     103             : 
+     104        4032 :   double r4 = pow( d2, 2 );
+     105        4032 :   double tmp = ( x4 + y4 + z4 ) / r4;
+     106             : 
+     107        4032 :   double t1=(x2+y2+z2), t2=t1*t1, t3=(x4+y4+z4)/(t1*t2);
+     108        4032 :   myder[0] = 4*x3/t2-4*distance[0]*t3;
+     109        4032 :   myder[1] = 4*y3/t2-4*distance[1]*t3;
+     110        4032 :   myder[2] = 4*z3/t2-4*distance[2]*t3;
+     111        4032 :   return tmp;
+     112             : }
+     113             : 
+     114             : }
+     115             : }
+     116             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Steinhardt.cpp.func-sort-c.html b/coverage/crystallization/Steinhardt.cpp.func-sort-c.html new file mode 100644 index 000000000000..4c514f95f41a --- /dev/null +++ b/coverage/crystallization/Steinhardt.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Steinhardt.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Steinhardt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7878100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization10SteinhardtC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization10Steinhardt18setAngularMomentumERKj18
_ZN4PLMD15crystallization10SteinhardtC2ERKNS_13ActionOptionsE18
_ZN4PLMD15crystallization10Steinhardt16registerKeywordsERNS_8KeywordsE24
_ZNK4PLMD15crystallization10Steinhardt15calculateVectorERNS_11multicolvar13AtomValuePackE76317
_ZNK4PLMD15crystallization10Steinhardt10deriv_polyERKjRKdRd15643770
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Steinhardt.cpp.func.html b/coverage/crystallization/Steinhardt.cpp.func.html new file mode 100644 index 000000000000..37a5b0701628 --- /dev/null +++ b/coverage/crystallization/Steinhardt.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Steinhardt.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Steinhardt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7878100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization10Steinhardt16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD15crystallization10Steinhardt18setAngularMomentumERKj18
_ZN4PLMD15crystallization10SteinhardtC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization10SteinhardtC2ERKNS_13ActionOptionsE18
_ZNK4PLMD15crystallization10Steinhardt10deriv_polyERKjRKdRd15643770
_ZNK4PLMD15crystallization10Steinhardt15calculateVectorERNS_11multicolvar13AtomValuePackE76317
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Steinhardt.cpp.gcov.html b/coverage/crystallization/Steinhardt.cpp.gcov.html new file mode 100644 index 000000000000..83f20ab0fdcf --- /dev/null +++ b/coverage/crystallization/Steinhardt.cpp.gcov.html @@ -0,0 +1,252 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Steinhardt.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Steinhardt.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7878100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Steinhardt.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include <complex>
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace crystallization {
+      28             : 
+      29          24 : void Steinhardt::registerKeywords( Keywords& keys ) {
+      30          24 :   VectorMultiColvar::registerKeywords( keys );
+      31          48 :   keys.add("compulsory","NN","12","The n parameter of the switching function ");
+      32          48 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      33          48 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      34          48 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      35          48 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      36             :            "The following provides information on the \\ref switchingfunction that are available. "
+      37             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+      38          72 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+      39          96 :   keys.use("MEAN"); keys.use("LESS_THAN"); keys.use("MORE_THAN"); keys.use("VMEAN");
+      40         120 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS"); keys.use("MIN"); keys.use("ALT_MIN");
+      41          48 :   keys.use("LOWEST"); keys.use("HIGHEST");
+      42          24 : }
+      43             : 
+      44          18 : Steinhardt::Steinhardt( const ActionOptions& ao ):
+      45             :   Action(ao),
+      46             :   VectorMultiColvar(ao),
+      47          18 :   tmom(0)
+      48             : {
+      49             :   // Read in the switching function
+      50          36 :   std::string sw, errors; parse("SWITCH",sw);
+      51          18 :   if(sw.length()>0) {
+      52           6 :     switchingFunction.set(sw,errors);
+      53             :   } else {
+      54          12 :     double r_0=-1.0, d_0; int nn, mm;
+      55          24 :     parse("NN",nn); parse("MM",mm);
+      56          24 :     parse("R_0",r_0); parse("D_0",d_0);
+      57          12 :     if( r_0<0.0 ) error("you must set a value for R_0");
+      58          12 :     switchingFunction.set(nn,mm,r_0,d_0);
+      59             :   }
+      60          18 :   log.printf("  Steinhardt parameter of central atom and those within %s\n",( switchingFunction.description() ).c_str() );
+      61          36 :   log<<"  Bibliography "<<plumed.cite("Tribello, Giberti, Sosso, Salvalaglio and Parrinello, J. Chem. Theory Comput. 13, 1317 (2017)")<<"\n";
+      62             :   // Set the link cell cutoff
+      63          18 :   setLinkCellCutoff( switchingFunction.get_dmax() );
+      64          18 :   rcut = switchingFunction.get_dmax(); rcut2 = rcut*rcut;
+      65          18 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms );
+      66          18 : }
+      67             : 
+      68          18 : void Steinhardt::setAngularMomentum( const unsigned& ang ) {
+      69          18 :   tmom=ang; setVectorDimensionality( 2*(2*ang + 1) );
+      70          18 : }
+      71             : 
+      72       76317 : void Steinhardt::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
+      73             :   double dfunc, dpoly_ass, md, tq6, itq6, real_z, imag_z;
+      74       76317 :   Vector dz, myrealvec, myimagvec, real_dz, imag_dz;
+      75             :   // The square root of -1
+      76             :   std::complex<double> ii( 0.0, 1.0 ), dp_x, dp_y, dp_z;
+      77             : 
+      78       76317 :   unsigned ncomp=2*tmom+1;
+      79             :   double sw, poly_ass, dlen; std::complex<double> powered;
+      80     5297031 :   for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+      81             :     Vector& distance=myatoms.getPosition(i);  // getSeparation( myatoms.getPosition(0), myatoms.getPosition(i) );
+      82             :     double d2;
+      83     9591512 :     if ( (d2=distance[0]*distance[0])<rcut2 &&
+      84     4370798 :          (d2+=distance[1]*distance[1])<rcut2 &&
+      85     8662510 :          (d2+=distance[2]*distance[2])<rcut2 &&
+      86             :          d2>epsilon ) {
+      87             : 
+      88     2437950 :       dlen = sqrt(d2);
+      89     2437950 :       sw = switchingFunction.calculate( dlen, dfunc );
+      90     2437950 :       accumulateSymmetryFunction( -1, i, sw, (+dfunc)*distance, (-dfunc)*Tensor( distance,distance ), myatoms );
+      91     2437950 :       double dlen3 = d2*dlen;
+      92             :       // Do stuff for m=0
+      93     2437950 :       poly_ass=deriv_poly( 0, distance[2]/dlen, dpoly_ass );
+      94             :       // Derivatives of z/r wrt x, y, z
+      95     2437950 :       dz = -( distance[2] / dlen3 )*distance; dz[2] += (1.0 / dlen);
+      96             :       // Derivative wrt to the vector connecting the two atoms
+      97     2437950 :       myrealvec = (+sw)*dpoly_ass*dz + poly_ass*(+dfunc)*distance;
+      98             :       // Accumulate the derivatives
+      99     2437950 :       accumulateSymmetryFunction( 2 + tmom, i, sw*poly_ass, myrealvec, Tensor( -myrealvec,distance ), myatoms );
+     100             : 
+     101             :       // The complex number of which we have to take powers
+     102     2437950 :       std::complex<double> com1( distance[0]/dlen,distance[1]/dlen );
+     103             :       powered = std::complex<double>(1.0,0.0);
+     104             : 
+     105             :       // Do stuff for all other m values
+     106    15643770 :       for(unsigned m=1; m<=tmom; ++m) {
+     107             :         // Calculate Legendre Polynomial
+     108    13205820 :         poly_ass=deriv_poly( m, distance[2]/dlen, dpoly_ass );
+     109             :         // Calculate power of complex number
+     110             :         // if(std::abs(com1)>epsilon) powered=pow(com1,m-1);
+     111             :         // else if(m==1) powered=std::complex<double>(1.,0);
+     112             :         // else powered = std::complex<double>(0.,0.);
+     113             :         // Real and imaginary parts of z
+     114             :         real_z = real(com1*powered); imag_z = imag(com1*powered );
+     115             : 
+     116             :         // Calculate steinhardt parameter
+     117    13205820 :         tq6=poly_ass*real_z;   // Real part of steinhardt parameter
+     118    13205820 :         itq6=poly_ass*imag_z;  // Imaginary part of steinhardt parameter
+     119             : 
+     120             :         // Derivatives wrt ( x/r + iy )^m
+     121    13205820 :         md=static_cast<double>(m);
+     122    13205820 :         dp_x = md*powered*( (1.0/dlen)-(distance[0]*distance[0])/dlen3-ii*(distance[0]*distance[1])/dlen3 );
+     123    13205820 :         dp_y = md*powered*( ii*(1.0/dlen)-(distance[0]*distance[1])/dlen3-ii*(distance[1]*distance[1])/dlen3 );
+     124    13205820 :         dp_z = md*powered*( -(distance[0]*distance[2])/dlen3-ii*(distance[1]*distance[2])/dlen3 );
+     125             : 
+     126             :         // Derivatives of real and imaginary parts of above
+     127    13205820 :         real_dz[0] = real( dp_x ); real_dz[1] = real( dp_y ); real_dz[2] = real( dp_z );
+     128    13205820 :         imag_dz[0] = imag( dp_x ); imag_dz[1] = imag( dp_y ); imag_dz[2] = imag( dp_z );
+     129             : 
+     130             :         // Complete derivative of steinhardt parameter
+     131    13205820 :         myrealvec = (+sw)*dpoly_ass*real_z*dz + (+dfunc)*distance*tq6 + (+sw)*poly_ass*real_dz;
+     132    13205820 :         myimagvec = (+sw)*dpoly_ass*imag_z*dz + (+dfunc)*distance*itq6 + (+sw)*poly_ass*imag_dz;
+     133             : 
+     134             :         // Real part
+     135    13205820 :         accumulateSymmetryFunction( 2 + tmom + m, i, sw*tq6, myrealvec, Tensor( -myrealvec,distance ), myatoms );
+     136             :         // Imaginary part
+     137    13205820 :         accumulateSymmetryFunction( 2+ncomp+tmom+m, i, sw*itq6, myimagvec, Tensor( -myimagvec,distance ), myatoms );
+     138             :         // Store -m part of vector
+     139    13205820 :         double pref=pow(-1.0,m);
+     140             :         // -m part of vector is just +m part multiplied by (-1.0)**m and multiplied by complex
+     141             :         // conjugate of Legendre polynomial
+     142             :         // Real part
+     143    13205820 :         accumulateSymmetryFunction( 2+tmom-m, i, pref*sw*tq6, pref*myrealvec, pref*Tensor( -myrealvec,distance ), myatoms );
+     144             :         // Imaginary part
+     145    13205820 :         accumulateSymmetryFunction( 2+ncomp+tmom-m, i, -pref*sw*itq6, -pref*myimagvec, pref*Tensor( myimagvec,distance ), myatoms );
+     146             :         // Calculate next power of complex number
+     147             :         powered *= com1;
+     148             :       }
+     149             :     }
+     150             :   }
+     151             : 
+     152             :   // Normalize
+     153       76317 :   updateActiveAtoms( myatoms );
+     154     1929999 :   for(unsigned i=0; i<getNumberOfComponentsInVector(); ++i) myatoms.getUnderlyingMultiValue().quotientRule( 2+i, 2+i );
+     155       76317 : }
+     156             : 
+     157    15643770 : double Steinhardt::deriv_poly( const unsigned& m, const double& val, double& df ) const {
+     158             :   double fact=1.0;
+     159    59020380 :   for(unsigned j=1; j<=m; ++j) fact=fact*j;
+     160    15643770 :   double res=coeff_poly[m]*fact;
+     161             : 
+     162    15643770 :   double pow=1.0, xi=val, dxi=1.0; df=0.0;
+     163    59020380 :   for(int i=m+1; i<=tmom; ++i) {
+     164             :     double fact=1.0;
+     165   110931360 :     for(unsigned j=i-m+1; j<=i; ++j) fact=fact*j;
+     166    43376610 :     res=res+coeff_poly[i]*fact*xi;
+     167    43376610 :     df = df + pow*coeff_poly[i]*fact*dxi;
+     168    43376610 :     xi=xi*val; dxi=dxi*val; pow+=1.0;
+     169             :   }
+     170    15643770 :   df = df*normaliz[m];
+     171    15643770 :   return normaliz[m]*res;
+     172             : }
+     173             : 
+     174             : }
+     175             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Tetrahedral.cpp.func-sort-c.html b/coverage/crystallization/Tetrahedral.cpp.func-sort-c.html new file mode 100644 index 000000000000..023bd6817444 --- /dev/null +++ b/coverage/crystallization/Tetrahedral.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Tetrahedral.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Tetrahedral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11TetrahedralC2ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization11TetrahedralC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11Tetrahedral16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD15crystallization11Tetrahedral22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Tetrahedral.cpp.func.html b/coverage/crystallization/Tetrahedral.cpp.func.html new file mode 100644 index 000000000000..55b26bd3b120 --- /dev/null +++ b/coverage/crystallization/Tetrahedral.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Tetrahedral.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Tetrahedral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization11Tetrahedral16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD15crystallization11TetrahedralC1ERKNS_13ActionOptionsE1
_ZN4PLMD15crystallization11TetrahedralC2ERKNS_13ActionOptionsE0
_ZNK4PLMD15crystallization11Tetrahedral22calculateCubicHarmonicERKNS_13VectorGenericILj3EEERKdRS3_4032
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/Tetrahedral.cpp.gcov.html b/coverage/crystallization/Tetrahedral.cpp.gcov.html new file mode 100644 index 000000000000..2bc2c273f3f4 --- /dev/null +++ b/coverage/crystallization/Tetrahedral.cpp.gcov.html @@ -0,0 +1,204 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/Tetrahedral.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - Tetrahedral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CubicHarmonicBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : #include <string>
+      26             : #include <cmath>
+      27             : 
+      28             : using namespace std;
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace crystallization {
+      32             : 
+      33             : //+PLUMEDOC MCOLVAR TETRAHEDRAL
+      34             : /*
+      35             : Calculate the degree to which the environment about ions has a tetrahedral order.
+      36             : 
+      37             : We can measure the degree to which the atoms in the first coordination shell around any atom, \f$i\f$ is
+      38             : is arranged like a tetrahedron using the following function.
+      39             : 
+      40             : \f[
+      41             :  s(i) = \frac{1}{\sum_j \sigma( r_{ij} )} \sum_j \sigma( r_{ij} )\left[ \frac{(x_{ij} + y_{ij} + z_{ij})^3}{r_{ij}^3} +
+      42             :                                                                         \frac{(x_{ij} - y_{ij} - z_{ij})^3}{r_{ij}^3} +
+      43             :                                                                         \frac{(-x_{ij} + y_{ij} - z_{ij})^3}{r_{ij}^3} +
+      44             :                                                                         \frac{(-x_{ij} - y_{ij} + z_{ij})^3}{r_{ij}^3} \right]
+      45             : \f]
+      46             : 
+      47             : Here \f$r_{ij}\f$ is the magnitude of the vector connecting atom \f$i\f$ to atom \f$j\f$ and \f$x_{ij}\f$, \f$y_{ij}\f$ and \f$z_{ij}\f$
+      48             : are its three components.  The function  \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between
+      49             : atoms \f$i\f$ and \f$j\f$.  The parameters of this function should be set so that the function is equal to one
+      50             : when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The following command calculates the average value of the TETRAHEDRAL parameter for a set of 64 atoms all of the same type
+      55             : and outputs this quantity to a file called colvar.
+      56             : 
+      57             : \plumedfile
+      58             : tt: TETRAHEDRAL SPECIES=1-64 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN
+      59             : PRINT ARG=tt.mean FILE=colvar
+      60             : \endplumedfile
+      61             : 
+      62             : The following command calculates the number of TETRAHEDRAL parameters that are greater than 0.8 in a set of 10 atoms.
+      63             : In this calculation it is assumed that there are two atom types A and B and that the first coordination sphere of the
+      64             : 10 atoms of type A contains atoms of type B.  The formula above is thus calculated for ten different A atoms and within
+      65             : it the sum over \f$j\f$ runs over 40 atoms of type B that could be in the first coordination sphere.
+      66             : 
+      67             : \plumedfile
+      68             : tt: TETRAHEDRAL SPECIESA=1-10 SPECIESB=11-40 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MORE_THAN={RATIONAL R_0=0.8}
+      69             : PRINT ARG=tt.* FILE=colvar
+      70             : \endplumedfile
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : 
+      75             : 
+      76             : class Tetrahedral : public CubicHarmonicBase {
+      77             : public:
+      78             :   static void registerKeywords( Keywords& keys );
+      79             :   explicit Tetrahedral(const ActionOptions&);
+      80             :   double calculateCubicHarmonic( const Vector& distance, const double& d2, Vector& myder ) const override;
+      81             : };
+      82             : 
+      83             : PLUMED_REGISTER_ACTION(Tetrahedral,"TETRAHEDRAL")
+      84             : 
+      85           3 : void Tetrahedral::registerKeywords( Keywords& keys ) {
+      86           3 :   CubicHarmonicBase::registerKeywords( keys );
+      87           3 : }
+      88             : 
+      89           1 : Tetrahedral::Tetrahedral(const ActionOptions&ao):
+      90             :   Action(ao),
+      91           1 :   CubicHarmonicBase(ao)
+      92             : {
+      93           1 :   checkRead();
+      94           1 : }
+      95             : 
+      96        4032 : double Tetrahedral::calculateCubicHarmonic( const Vector& distance, const double& d2, Vector& myder ) const {
+      97        4032 :   double sp1 = +distance[0]+distance[1]+distance[2];
+      98        4032 :   double sp2 = +distance[0]-distance[1]-distance[2];
+      99        4032 :   double sp3 = -distance[0]+distance[1]-distance[2];
+     100        4032 :   double sp4 = -distance[0]-distance[1]+distance[2];
+     101             : 
+     102             :   double sp1c = pow( sp1, 3 );
+     103             :   double sp2c = pow( sp2, 3 );
+     104             :   double sp3c = pow( sp3, 3 );
+     105             :   double sp4c = pow( sp4, 3 );
+     106             : 
+     107        4032 :   double d1 = distance.modulo();
+     108             :   double r3 = pow( d1, 3 );
+     109             :   double r5 = pow( d1, 5 );
+     110             : 
+     111        4032 :   double tmp = sp1c/r3 + sp2c/r3 + sp3c/r3 + sp4c/r3;
+     112             : 
+     113        4032 :   double t1=(3*sp1c)/r5; double tt1=((3*sp1*sp1)/r3);
+     114        4032 :   double t2=(3*sp2c)/r5; double tt2=((3*sp2*sp2)/r3);
+     115        4032 :   double t3=(3*sp3c)/r5; double tt3=((3*sp3*sp3)/r3);
+     116        4032 :   double t4=(3*sp4c)/r5; double tt4=((3*sp4*sp4)/r3);
+     117             : 
+     118        4032 :   myder[0] = (tt1-(distance[0]*t1))  + (tt2-(distance[0]*t2))  + (-tt3-(distance[0]*t3))  + (-tt4-(distance[0]*t4));
+     119        4032 :   myder[1] = (tt1-(distance[1]*t1))  + (-tt2-(distance[1]*t2))  + (tt3-(distance[1]*t3))  + (-tt4-(distance[1]*t4));
+     120        4032 :   myder[2] = (tt1-(distance[2]*t1))  + (-tt2-(distance[2]*t2))  + (-tt3-(distance[2]*t3))  + (tt4-(distance[2]*t4));
+     121             : 
+     122        4032 :   return tmp;
+     123             : }
+     124             : 
+     125             : }
+     126             : }
+     127             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMean.cpp.func-sort-c.html b/coverage/crystallization/VectorMean.cpp.func-sort-c.html new file mode 100644 index 000000000000..1052f853dca3 --- /dev/null +++ b/coverage/crystallization/VectorMean.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorMean.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorMean.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4444100.0 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization10VectorMean16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD15crystallization10VectorMean16value_descriptorB5cxx11Ev6
_ZN4PLMD15crystallization10VectorMeanC2ERKNS_10vesselbase13VesselOptionsE6
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMe6createERKNS_10vesselbase13VesselOptionsE6
_ZN4PLMD15crystallization10VectorMean6resizeEv23
_ZN4PLMD15crystallization10VectorMean6finishERKSt6vectorIdSaIdEE1828
_ZN4PLMD15crystallization10VectorMean14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeC2Ev4187
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeD2Ev4187
_ZNK4PLMD15crystallization10VectorMean9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE14712
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMean.cpp.func.html b/coverage/crystallization/VectorMean.cpp.func.html new file mode 100644 index 000000000000..4e094bdffee1 --- /dev/null +++ b/coverage/crystallization/VectorMean.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorMean.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorMean.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4444100.0 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization10VectorMean14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD15crystallization10VectorMean16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD15crystallization10VectorMean16value_descriptorB5cxx11Ev6
_ZN4PLMD15crystallization10VectorMean6finishERKSt6vectorIdSaIdEE1828
_ZN4PLMD15crystallization10VectorMean6resizeEv23
_ZN4PLMD15crystallization10VectorMeanC2ERKNS_10vesselbase13VesselOptionsE6
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMe6createERKNS_10vesselbase13VesselOptionsE6
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeC2Ev4187
_ZN4PLMD15crystallization12_GLOBAL__N_120VectorMeanRegisterMeD2Ev4187
_ZNK4PLMD15crystallization10VectorMean9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE14712
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMean.cpp.gcov.html b/coverage/crystallization/VectorMean.cpp.gcov.html new file mode 100644 index 000000000000..5b7b95b0d42b --- /dev/null +++ b/coverage/crystallization/VectorMean.cpp.gcov.html @@ -0,0 +1,190 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorMean.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorMean.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4444100.0 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "vesselbase/VesselRegister.h"
+      23             : #include "vesselbase/FunctionVessel.h"
+      24             : #include "vesselbase/ActionWithVessel.h"
+      25             : #include "multicolvar/ActionVolume.h"
+      26             : #include "VectorMultiColvar.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace crystallization {
+      30             : 
+      31             : class VectorMean : public vesselbase::FunctionVessel {
+      32             : private:
+      33             :   unsigned nder;
+      34             : public:
+      35             :   static void registerKeywords( Keywords& keys );
+      36             :   static void reserveKeyword( Keywords& keys );
+      37             :   explicit VectorMean( const vesselbase::VesselOptions& da );
+      38             :   std::string value_descriptor();
+      39             :   void resize();
+      40             :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const ;
+      41             :   void finish( const std::vector<double>& buffer );
+      42             : };
+      43             : 
+      44       12567 : PLUMED_REGISTER_VESSEL(VectorMean,"VMEAN")
+      45             : 
+      46           6 : void VectorMean::registerKeywords( Keywords& keys ) {
+      47           6 :   vesselbase::FunctionVessel::registerKeywords(keys);
+      48           6 : }
+      49             : 
+      50        4187 : void VectorMean::reserveKeyword( Keywords& keys ) {
+      51        8374 :   keys.reserve("vessel","VMEAN","calculate the norm of the mean vector.");
+      52        8374 :   keys.addOutputComponent("vmean","VMEAN","the norm of the mean vector. The output component can be referred to elsewhere in the input "
+      53             :                           "file by using the label.vmean");
+      54        4187 : }
+      55             : 
+      56           6 : VectorMean::VectorMean( const vesselbase::VesselOptions& da ) :
+      57             :   FunctionVessel(da),
+      58           6 :   nder(0)
+      59             : {
+      60           6 : }
+      61             : 
+      62           6 : std::string VectorMean::value_descriptor() {
+      63           6 :   return "the norm of the mean vector";
+      64             : }
+      65             : 
+      66          23 : void VectorMean::resize() {
+      67          23 :   unsigned ncomp=getAction()->getNumberOfQuantities() - 2;
+      68             : 
+      69          23 :   if( getAction()->derivativesAreRequired() ) {
+      70          16 :     nder=getAction()->getNumberOfDerivatives();
+      71          16 :     resizeBuffer( (1+nder)*(ncomp+1) ); getFinalValue()->resizeDerivatives( nder );
+      72             :   } else {
+      73           7 :     nder=0; resizeBuffer(ncomp+1);
+      74             :   }
+      75          23 : }
+      76             : 
+      77       14712 : void VectorMean::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+      78       14712 :   unsigned ncomp=getAction()->getNumberOfQuantities()-2;
+      79             : 
+      80       14712 :   double weight=myvals.get(0); plumed_dbg_assert( weight>=getTolerance() );
+      81       14712 :   buffer[bufstart] += weight;
+      82       61240 :   for(unsigned i=0; i<ncomp; ++i) buffer[bufstart + (1+i)*(1+nder)] += weight*myvals.get(2+i);
+      83       14712 :   if( !getAction()->derivativesAreRequired() ) return;
+      84             : 
+      85       14712 :   if( diffweight ) myvals.chainRule( 0, 0, 1, 0, 1.0, bufstart, buffer );
+      86       61240 :   for(unsigned i=0; i<ncomp; ++i) {
+      87       46528 :     double colvar=myvals.get(2+i);
+      88       46528 :     myvals.chainRule( 2+i, 1+i, 1, 0, weight, bufstart, buffer );
+      89       46528 :     if( diffweight ) myvals.chainRule( 0, 1+i, 1, 0, colvar, bufstart, buffer );
+      90             :   }
+      91             :   return;
+      92             : }
+      93             : 
+      94        1828 : void VectorMean::finish( const std::vector<double>& buffer ) {
+      95        1828 :   unsigned ncomp=getAction()->getNumberOfQuantities()-2;
+      96        1828 :   double sum=0, ww=buffer[bufstart];
+      97        7358 :   for(unsigned i=0; i<ncomp; ++i) {
+      98        5530 :     double tmp = buffer[bufstart+(nder+1)*(i+1)] / ww;
+      99        5530 :     sum+=tmp*tmp;
+     100             :   }
+     101        1828 :   setOutputValue( sqrt(sum) );
+     102        1828 :   if( !getAction()->derivativesAreRequired() ) return;
+     103             : 
+     104        1828 :   Value* fval=getFinalValue(); double tw = 1.0 / sqrt(sum);
+     105        7358 :   for(unsigned icomp=0; icomp<ncomp; ++icomp) {
+     106        5530 :     double tmp = buffer[bufstart + (icomp+1)*(1+nder)] / ww;
+     107        5530 :     unsigned bstart = bufstart + (1+icomp)*(nder+1) + 1;
+     108      460636 :     for(unsigned jder=0; jder<nder; ++jder) fval->addDerivative( jder, (tw*tmp/ww)*( buffer[bstart + jder] - tmp*buffer[bufstart + 1 + jder] ) );
+     109             :   }
+     110             : }
+     111             : 
+     112             : }
+     113             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.cpp.func-sort-c.html b/coverage/crystallization/VectorMultiColvar.cpp.func-sort-c.html new file mode 100644 index 000000000000..c35bad1872df --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorMultiColvar.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorMultiColvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344379.1 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17VectorMultiColvar16addForcesOnAtomsERKSt6vectorIdSaIdEE0
_ZN4PLMD15crystallization17VectorMultiColvar22doNotCalculateDirectorEv0
_ZN4PLMD15crystallization17VectorMultiColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17VectorMultiColvar23setVectorDimensionalityERKj26
_ZN4PLMD15crystallization17VectorMultiColvarC2ERKNS_13ActionOptionsE26
_ZN4PLMD15crystallization17VectorMultiColvar16registerKeywordsERNS_8KeywordsE38
_ZNK4PLMD15crystallization17VectorMultiColvar26normalizeVectorDerivativesERNS_10MultiValueE29195
_ZNK4PLMD15crystallization17VectorMultiColvar15normalizeVectorERSt6vectorIdSaIdEE64156
_ZNK4PLMD15crystallization17VectorMultiColvar7computeERKjRNS_11multicolvar13AtomValuePackE101849
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.cpp.func.html b/coverage/crystallization/VectorMultiColvar.cpp.func.html new file mode 100644 index 000000000000..231e14ea8176 --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorMultiColvar.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorMultiColvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344379.1 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17VectorMultiColvar16addForcesOnAtomsERKSt6vectorIdSaIdEE0
_ZN4PLMD15crystallization17VectorMultiColvar16registerKeywordsERNS_8KeywordsE38
_ZN4PLMD15crystallization17VectorMultiColvar22doNotCalculateDirectorEv0
_ZN4PLMD15crystallization17VectorMultiColvar23setVectorDimensionalityERKj26
_ZN4PLMD15crystallization17VectorMultiColvarC1ERKNS_13ActionOptionsE0
_ZN4PLMD15crystallization17VectorMultiColvarC2ERKNS_13ActionOptionsE26
_ZNK4PLMD15crystallization17VectorMultiColvar15normalizeVectorERSt6vectorIdSaIdEE64156
_ZNK4PLMD15crystallization17VectorMultiColvar26normalizeVectorDerivativesERNS_10MultiValueE29195
_ZNK4PLMD15crystallization17VectorMultiColvar7computeERKjRNS_11multicolvar13AtomValuePackE101849
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.cpp.gcov.html b/coverage/crystallization/VectorMultiColvar.cpp.gcov.html new file mode 100644 index 000000000000..407b62785fb0 --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorMultiColvar.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorMultiColvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344379.1 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "VectorMultiColvar.h"
+      23             : #include "multicolvar/BridgedMultiColvarFunction.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace crystallization {
+      27             : 
+      28          38 : void VectorMultiColvar::registerKeywords( Keywords& keys ) {
+      29          38 :   MultiColvarBase::registerKeywords( keys );
+      30          38 :   keys.setComponentsIntroduction("When the label of this action is used as the input for a second you are not referring to a scalar quantity as you are in "
+      31             :                                  "regular collective variables.  The label is used to reference the full set of vectors calculated by "
+      32             :                                  "the action.  This is usual when using \\ref multicolvarfunction. Generally when doing this the previously calculated "
+      33             :                                  "multicolvar will be referenced using the DATA keyword rather than ARG.\n\n"
+      34             :                                  "This Action can be used to calculate the following scalar quantities directly.  These quantities are calculated by "
+      35             :                                  "employing the keywords listed below. "
+      36             :                                  "These quantities can then be referenced elsewhere in the input file by using this Action's label "
+      37             :                                  "followed by a dot and the name of the quantity. All of them can be calculated multiple times "
+      38             :                                  "with different parameters.  In this case the quantities calculated can be referenced elsewhere in the "
+      39             :                                  "input by using the name of the quantity followed by a numerical identifier "
+      40             :                                  "e.g. <em>label</em>.lessthan-1, <em>label</em>.lessthan-2 etc.  When doing this and, for clarity we have "
+      41             :                                  "made it so that the user can set the label for the components. As such by using the LABEL keyword in the description of the keyword "
+      42             :                                  "input you can customize the component name.  In addition, you can calculate all of these scalar functions for "
+      43             :                                  "one particular component of the calculated vector by making use of the COMPONENT keyword.  The first component is used to "
+      44             :                                  "refer to the norm of the vector.  The individual components can then be referenced using the numbers 2, 3, and so on.  So "
+      45             :                                  "as an example MEAN1={COMPONENT=1} calculates the average vector norm.  MEAN2={COMPONENT=2} by contrast calculates the mean "
+      46             :                                  "for all of the first components of the vectors.");
+      47          38 : }
+      48             : 
+      49          26 : VectorMultiColvar::VectorMultiColvar(const ActionOptions& ao):
+      50             :   Action(ao),
+      51             :   MultiColvarBase(ao),
+      52          26 :   store_director(true)
+      53             : {
+      54             :   setLowMemOption(true);
+      55          26 : }
+      56             : 
+      57          26 : void VectorMultiColvar::setVectorDimensionality( const unsigned& ncomp ) {
+      58          26 :   ncomponents = ncomp; resizeFunctions(); // This resize needs to be here to ensure buffers are set to correct size in base
+      59          26 : }
+      60             : 
+      61           0 : void VectorMultiColvar::doNotCalculateDirector() {
+      62           0 :   store_director=false;    // Need a sanity check in here so that you don't use the same instance of Q4 to calculate vectors and directors
+      63           0 : }
+      64             : 
+      65      101849 : double VectorMultiColvar::compute( const unsigned& taskIndex, multicolvar::AtomValuePack& myatoms ) const {
+      66             :   // Now calculate the vector
+      67      101849 :   calculateVector( myatoms );
+      68             :   // Sort out the active derivatives
+      69      101849 :   updateActiveAtoms( myatoms );
+      70             : 
+      71             :   // Now calculate the norm of the vector (this is what we return here)
+      72             :   double norm=0;
+      73     2032127 :   for(unsigned i=0; i<ncomponents; ++i) norm += myatoms.getValue(2+i)*myatoms.getValue(2+i);
+      74      101849 :   norm=sqrt(norm);
+      75             : 
+      76      101849 :   if( !doNotCalculateDerivatives() ) {
+      77       76287 :     double inorm = 1.0 / norm; std::vector<double> dervec( ncomponents );
+      78     1535613 :     for(unsigned i=0; i<ncomponents; ++i) dervec[i] = inorm*myatoms.getValue(2+i);
+      79             : 
+      80             :     MultiValue& myvals=myatoms.getUnderlyingMultiValue();
+      81     7895952 :     for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
+      82     7819665 :       unsigned jder=myvals.getActiveIndex(j);
+      83   185984763 :       for(unsigned i=0; i<ncomponents; ++i) myvals.addDerivative( 1, jder, dervec[i]*myvals.getDerivative( 2+i, jder ) );
+      84             :     }
+      85             :   }
+      86             : 
+      87      101849 :   return norm;
+      88             : }
+      89             : 
+      90       64156 : void VectorMultiColvar::normalizeVector( std::vector<double>& vals ) const {
+      91             :   double inorm = 1.0;
+      92       64156 :   if( vals[1]>epsilon ) inorm = 1.0 / vals[1];
+      93     1632096 :   for(unsigned i=2; i<vals.size(); ++i) vals[i] = inorm*vals[i];
+      94       64156 : }
+      95             : 
+      96       29195 : void VectorMultiColvar::normalizeVectorDerivatives( MultiValue& myvals ) const {
+      97       29195 :   double v = myvals.get(1), weight = 1.0 / v,  wdf = 1.0 / ( v*v*v );
+      98     3570659 :   for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
+      99     3541464 :     double comp2=0.0; unsigned jder=myvals.getActiveIndex(j);
+     100    85824660 :     for(unsigned jcomp=2; jcomp<myvals.getNumberOfValues(); ++jcomp) comp2 += myvals.get(jcomp)*myvals.getDerivative( jcomp, jder );
+     101    85824660 :     for(unsigned jcomp=2; jcomp<myvals.getNumberOfValues(); ++jcomp) {
+     102    82283196 :       myvals.setDerivative( jcomp, jder, weight*myvals.getDerivative( jcomp, jder ) - wdf*comp2*myvals.get(jcomp) );
+     103             :     }
+     104             :   }
+     105       29195 : }
+     106             : 
+     107           0 : void VectorMultiColvar::addForcesOnAtoms( const std::vector<double>& inforces ) {
+     108             :   plumed_dbg_assert( inforces.size()==getNumberOfDerivatives() );
+     109           0 :   std::vector<double> oldforces( getNumberOfDerivatives() );
+     110           0 :   getForcesFromVessels( oldforces );
+     111           0 :   for(unsigned i=0; i<getNumberOfDerivatives(); ++i) oldforces[i]+=inforces[i];
+     112           0 :   unsigned ind=0; setForcesOnAtoms( oldforces, ind );
+     113           0 : }
+     114             : 
+     115             : }
+     116             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.h.func-sort-c.html b/coverage/crystallization/VectorMultiColvar.h.func-sort-c.html new file mode 100644 index 000000000000..dfb03ca4b3a2 --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorMultiColvar.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorMultiColvar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15crystallization17VectorMultiColvar28hasDifferentiableOrientationEv4
_ZN4PLMD15crystallization17VectorMultiColvarD2Ev26
_ZN4PLMD15crystallization17VectorMultiColvar10isPeriodicEv35
_ZNK4PLMD15crystallization17VectorMultiColvar21getNumberOfQuantitiesEv1255376
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.h.func.html b/coverage/crystallization/VectorMultiColvar.h.func.html new file mode 100644 index 000000000000..0d21dd3d9d8c --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorMultiColvar.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorMultiColvar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization17VectorMultiColvar10isPeriodicEv35
_ZN4PLMD15crystallization17VectorMultiColvarD2Ev26
_ZNK4PLMD15crystallization17VectorMultiColvar21getNumberOfQuantitiesEv1255376
_ZNK4PLMD15crystallization17VectorMultiColvar28hasDifferentiableOrientationEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorMultiColvar.h.gcov.html b/coverage/crystallization/VectorMultiColvar.h.gcov.html new file mode 100644 index 000000000000..5a44f3c1d262 --- /dev/null +++ b/coverage/crystallization/VectorMultiColvar.h.gcov.html @@ -0,0 +1,162 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorMultiColvar.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorMultiColvar.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_crystallization_VectorMultiColvar_h
+      23             : #define __PLUMED_crystallization_VectorMultiColvar_h
+      24             : 
+      25             : #include "tools/Matrix.h"
+      26             : #include "multicolvar/MultiColvarBase.h"
+      27             : #include "multicolvar/AtomValuePack.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace crystallization {
+      31             : 
+      32             : class VectorMultiColvar : public multicolvar::MultiColvarBase {
+      33             :   friend class OrientationSphere;
+      34             :   friend class VolumeGradientBase;
+      35             : private:
+      36             : /// Are we storing the director of the vector of the vector
+      37             :   bool store_director;
+      38             : /// How many components does the vector have
+      39             :   unsigned ncomponents;
+      40             : /// These are tempory vectors that are used to store values and directors
+      41             :   std::vector<double> vv1, vv2;
+      42             : protected:
+      43             : /// Set the dimensionality of the vector
+      44             :   void setVectorDimensionality( const unsigned& );
+      45             : /// Used in vector average to add forces from vector the the forces from here
+      46             :   void addForcesOnAtoms( const std::vector<double>& inforces );
+      47             : public:
+      48             :   static void registerKeywords( Keywords& keys );
+      49             :   explicit VectorMultiColvar(const ActionOptions&);
+      50          52 :   ~VectorMultiColvar() {}
+      51             : /// The norm of a vector is not periodic
+      52          35 :   virtual bool isPeriodic() { return false; }
+      53             : /// Calculate the multicolvar
+      54             : //  double doCalculation( const unsigned& taskIndex, multicolvar::AtomValuePack& myatoms ) const ;
+      55             : /// This shouldn't do anything
+      56             :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const ;
+      57             : /// Calculate the vector
+      58             :   virtual void calculateVector( multicolvar::AtomValuePack& myatoms ) const=0;
+      59             : /// Get the number of components in the vector
+      60             :   unsigned getNumberOfComponentsInVector() const ;
+      61             : /// Get the number of quantities we are calculating per step
+      62             :   unsigned getNumberOfQuantities() const ;
+      63             : /// Can we differentiate the orientation - yes we can the multicolvar is a vector
+      64           4 :   bool hasDifferentiableOrientation() const { return true; }
+      65             : ///  This makes sure we are not calculating the director when we do LocalAverage
+      66             :   virtual void doNotCalculateDirector();
+      67             : /// This does normalizeing of vectors for storeDataVessel
+      68             :   virtual void normalizeVector( std::vector<double>& vals ) const ;
+      69             :   virtual void normalizeVectorDerivatives( MultiValue& myvals ) const ;
+      70             : };
+      71             : 
+      72             : inline
+      73             : unsigned VectorMultiColvar::getNumberOfComponentsInVector() const {
+      74     1929999 :   return ncomponents;
+      75             : }
+      76             : 
+      77             : inline
+      78     1255376 : unsigned VectorMultiColvar::getNumberOfQuantities() const {
+      79     1255376 :   return 2 + ncomponents;
+      80             : }
+      81             : 
+      82             : }
+      83             : }
+      84             : #endif
+      85             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorSum.cpp.func-sort-c.html b/coverage/crystallization/VectorSum.cpp.func-sort-c.html new file mode 100644 index 000000000000..73e36353a242 --- /dev/null +++ b/coverage/crystallization/VectorSum.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorSum.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorSum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:54211.9 %
Date:2024-02-22 21:58:45Functions:31030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMe6createERKNS_10vesselbase13VesselOptionsE0
_ZN4PLMD15crystallization9VectorSum16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD15crystallization9VectorSum16value_descriptorB5cxx11Ev0
_ZN4PLMD15crystallization9VectorSum6finishERKSt6vectorIdSaIdEE0
_ZN4PLMD15crystallization9VectorSum6resizeEv0
_ZN4PLMD15crystallization9VectorSumC2ERKNS_10vesselbase13VesselOptionsE0
_ZNK4PLMD15crystallization9VectorSum9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE0
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMeC2Ev4187
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMeD2Ev4187
_ZN4PLMD15crystallization9VectorSum14reserveKeywordERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorSum.cpp.func.html b/coverage/crystallization/VectorSum.cpp.func.html new file mode 100644 index 000000000000..0ec1155ba206 --- /dev/null +++ b/coverage/crystallization/VectorSum.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorSum.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorSum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:54211.9 %
Date:2024-02-22 21:58:45Functions:31030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMe6createERKNS_10vesselbase13VesselOptionsE0
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMeC2Ev4187
_ZN4PLMD15crystallization12_GLOBAL__N_119VectorSumRegisterMeD2Ev4187
_ZN4PLMD15crystallization9VectorSum14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD15crystallization9VectorSum16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD15crystallization9VectorSum16value_descriptorB5cxx11Ev0
_ZN4PLMD15crystallization9VectorSum6finishERKSt6vectorIdSaIdEE0
_ZN4PLMD15crystallization9VectorSum6resizeEv0
_ZN4PLMD15crystallization9VectorSumC2ERKNS_10vesselbase13VesselOptionsE0
_ZNK4PLMD15crystallization9VectorSum9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/VectorSum.cpp.gcov.html b/coverage/crystallization/VectorSum.cpp.gcov.html new file mode 100644 index 000000000000..db194a4fe706 --- /dev/null +++ b/coverage/crystallization/VectorSum.cpp.gcov.html @@ -0,0 +1,191 @@ + + + + + + + + LCOV - plumed test coverage - crystallization/VectorSum.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallization - VectorSum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:54211.9 %
Date:2024-02-22 21:58:45Functions:31030.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "vesselbase/VesselRegister.h"
+      23             : #include "vesselbase/FunctionVessel.h"
+      24             : #include "vesselbase/ActionWithVessel.h"
+      25             : #include "multicolvar/ActionVolume.h"
+      26             : #include "VectorMultiColvar.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace crystallization {
+      30             : 
+      31             : class VectorSum : public vesselbase::FunctionVessel {
+      32             : private:
+      33             :   unsigned nder;
+      34             : public:
+      35             :   static void registerKeywords( Keywords& keys );
+      36             :   static void reserveKeyword( Keywords& keys );
+      37             :   explicit VectorSum( const vesselbase::VesselOptions& da );
+      38             :   std::string value_descriptor();
+      39             :   void resize();
+      40             :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const ;
+      41             :   void finish( const std::vector<double>& buffer );
+      42             : };
+      43             : 
+      44       12561 : PLUMED_REGISTER_VESSEL(VectorSum,"VSUM")
+      45             : 
+      46           0 : void VectorSum::registerKeywords( Keywords& keys ) {
+      47           0 :   vesselbase::FunctionVessel::registerKeywords(keys);
+      48           0 : }
+      49             : 
+      50        4187 : void VectorSum::reserveKeyword( Keywords& keys ) {
+      51        8374 :   keys.reserve("vessel","VSUM","calculate the norm of the sum of vectors.");
+      52        8374 :   keys.addOutputComponent("vsum","VSUM","the norm of sum of vectors. The output component can be referred to elsewhere in the input "
+      53             :                           "file by using the label.vsum");
+      54        4187 : }
+      55             : 
+      56           0 : VectorSum::VectorSum( const vesselbase::VesselOptions& da ) :
+      57             :   FunctionVessel(da),
+      58           0 :   nder(0)
+      59             : {
+      60           0 : }
+      61             : 
+      62           0 : std::string VectorSum::value_descriptor() {
+      63           0 :   return "the norm of the mean vector";
+      64             : }
+      65             : 
+      66           0 : void VectorSum::resize() {
+      67           0 :   unsigned ncomp=getAction()->getNumberOfQuantities() - 2;
+      68             : 
+      69           0 :   if( getAction()->derivativesAreRequired() ) {
+      70           0 :     nder=getAction()->getNumberOfDerivatives();
+      71           0 :     resizeBuffer( (1+nder)*ncomp ); getFinalValue()->resizeDerivatives( nder );
+      72             :   } else {
+      73           0 :     nder=0; resizeBuffer(ncomp);
+      74             :   }
+      75           0 : }
+      76             : 
+      77           0 : void VectorSum::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+      78           0 :   unsigned ncomp=getAction()->getNumberOfQuantities()-2;
+      79             : 
+      80           0 :   double weight=myvals.get(0);
+      81             :   plumed_dbg_assert( weight>=getTolerance() );
+      82           0 :   for(unsigned i=0; i<ncomp; ++i) buffer[bufstart + i*(1+nder)] += weight*myvals.get(2+i);
+      83           0 :   if( !getAction()->derivativesAreRequired() ) return;
+      84             : 
+      85           0 :   for(unsigned i=0; i<ncomp; ++i) {
+      86           0 :     double colvar=myvals.get(2+i);
+      87           0 :     myvals.chainRule( 2+i, i, 1, 0, weight, bufstart, buffer );
+      88           0 :     if( diffweight ) myvals.chainRule( 0, i, 1, 0, colvar, bufstart, buffer );
+      89             :   }
+      90           0 :   return;
+      91             : }
+      92             : 
+      93           0 : void VectorSum::finish( const std::vector<double>& buffer ) {
+      94           0 :   unsigned ncomp=getAction()->getNumberOfQuantities()-2;
+      95             : 
+      96             :   double sum=0;
+      97           0 :   for(unsigned i=0; i<ncomp; ++i) {
+      98           0 :     double tmp = buffer[bufstart+(nder+1)*i];
+      99           0 :     sum+=tmp*tmp;
+     100             :   }
+     101           0 :   double tw = 1.0 / sqrt(sum);
+     102           0 :   setOutputValue( sqrt(sum) );
+     103           0 :   if( !getAction()->derivativesAreRequired() ) return;
+     104             : 
+     105             :   Value* fval=getFinalValue();
+     106           0 :   for(unsigned icomp=0; icomp<ncomp; ++icomp) {
+     107           0 :     double tmp = buffer[bufstart + icomp*(1+nder)];
+     108           0 :     unsigned bstart = bufstart + icomp*(nder+1) + 1;
+     109           0 :     for(unsigned jder=0; jder<nder; ++jder) fval->addDerivative( jder, tw*tmp*buffer[bstart + jder] );
+     110             :   }
+     111             : }
+     112             : 
+     113             : }
+     114             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/index-sort-f.html b/coverage/crystallization/index-sort-f.html new file mode 100644 index 000000000000..b1a6d5d6071e --- /dev/null +++ b/coverage/crystallization/index-sort-f.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - crystallization + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallizationHitTotalCoverage
Test:plumed test coverageLines:1000119683.6 %
Date:2024-02-22 21:58:45Functions:9713671.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
InterMolecularTorsions.cpp +
21.0%21.0%
+
21.0 %13 / 6214.3 %1 / 7
VectorSum.cpp +
11.9%11.9%
+
11.9 %5 / 4230.0 %3 / 10
Q3.cpp +
17.6%17.6%
+
17.6 %3 / 1733.3 %1 / 3
LocalSteinhardt.h +
72.2%72.2%
+
72.2 %13 / 1855.6 %5 / 9
MoleculePlane.cpp +
72.5%72.5%
+
72.5 %37 / 5160.0 %3 / 5
Q6.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
Q4.cpp +
100.0%
+
100.0 %17 / 1766.7 %2 / 3
VectorMultiColvar.cpp +
79.1%79.1%
+
79.1 %34 / 4366.7 %6 / 9
MoleculeOrientation.cpp +
94.5%94.5%
+
94.5 %52 / 5571.4 %5 / 7
Fccubic.cpp +
100.0%
+
100.0 %28 / 2875.0 %3 / 4
PolymerAngles.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
CubicHarmonicBase.cpp +
93.7%93.7%
+
93.7 %74 / 7975.0 %3 / 4
SimpleCubic.cpp +
100.0%
+
100.0 %24 / 2475.0 %3 / 4
OrientationSphere.cpp +
90.9%90.9%
+
90.9 %60 / 6675.0 %3 / 4
Tetrahedral.cpp +
100.0%
+
100.0 %22 / 2275.0 %3 / 4
SMAC.cpp +
100.0%
+
100.0 %42 / 4280.0 %4 / 5
BondOrientation.cpp +
91.1%91.1%
+
91.1 %51 / 5680.0 %4 / 5
Gradient.cpp +
71.4%71.4%
+
71.4 %50 / 7080.0 %4 / 5
Steinhardt.cpp +
100.0%
+
100.0 %78 / 7883.3 %5 / 6
EnvironmentSimilarity.cpp +
94.1%94.1%
+
94.1 %225 / 23985.7 %6 / 7
CubicHarmonicBase.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
Gradient.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
OrientationSphere.h +
100.0%
+
100.0 %3 / 3100.0 %2 / 2
VectorMultiColvar.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
GradientVessel.cpp +
84.5%84.5%
+
84.5 %82 / 97100.0 %10 / 10
VectorMean.cpp +
100.0%
+
100.0 %44 / 44100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/index-sort-l.html b/coverage/crystallization/index-sort-l.html new file mode 100644 index 000000000000..d8e9ea180247 --- /dev/null +++ b/coverage/crystallization/index-sort-l.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - crystallization + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallizationHitTotalCoverage
Test:plumed test coverageLines:1000119683.6 %
Date:2024-02-22 21:58:45Functions:9713671.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
VectorSum.cpp +
11.9%11.9%
+
11.9 %5 / 4230.0 %3 / 10
Q3.cpp +
17.6%17.6%
+
17.6 %3 / 1733.3 %1 / 3
InterMolecularTorsions.cpp +
21.0%21.0%
+
21.0 %13 / 6214.3 %1 / 7
Gradient.cpp +
71.4%71.4%
+
71.4 %50 / 7080.0 %4 / 5
LocalSteinhardt.h +
72.2%72.2%
+
72.2 %13 / 1855.6 %5 / 9
MoleculePlane.cpp +
72.5%72.5%
+
72.5 %37 / 5160.0 %3 / 5
VectorMultiColvar.cpp +
79.1%79.1%
+
79.1 %34 / 4366.7 %6 / 9
GradientVessel.cpp +
84.5%84.5%
+
84.5 %82 / 97100.0 %10 / 10
OrientationSphere.cpp +
90.9%90.9%
+
90.9 %60 / 6675.0 %3 / 4
BondOrientation.cpp +
91.1%91.1%
+
91.1 %51 / 5680.0 %4 / 5
CubicHarmonicBase.cpp +
93.7%93.7%
+
93.7 %74 / 7975.0 %3 / 4
EnvironmentSimilarity.cpp +
94.1%94.1%
+
94.1 %225 / 23985.7 %6 / 7
MoleculeOrientation.cpp +
94.5%94.5%
+
94.5 %52 / 5571.4 %5 / 7
CubicHarmonicBase.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
Gradient.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
OrientationSphere.h +
100.0%
+
100.0 %3 / 3100.0 %2 / 2
VectorMultiColvar.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
PolymerAngles.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
Q4.cpp +
100.0%
+
100.0 %17 / 1766.7 %2 / 3
Q6.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
Tetrahedral.cpp +
100.0%
+
100.0 %22 / 2275.0 %3 / 4
SimpleCubic.cpp +
100.0%
+
100.0 %24 / 2475.0 %3 / 4
Fccubic.cpp +
100.0%
+
100.0 %28 / 2875.0 %3 / 4
SMAC.cpp +
100.0%
+
100.0 %42 / 4280.0 %4 / 5
VectorMean.cpp +
100.0%
+
100.0 %44 / 44100.0 %10 / 10
Steinhardt.cpp +
100.0%
+
100.0 %78 / 7883.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/crystallization/index.html b/coverage/crystallization/index.html new file mode 100644 index 000000000000..a048e12a3f83 --- /dev/null +++ b/coverage/crystallization/index.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - crystallization + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - crystallizationHitTotalCoverage
Test:plumed test coverageLines:1000119683.6 %
Date:2024-02-22 21:58:45Functions:9713671.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
BondOrientation.cpp +
91.1%91.1%
+
91.1 %51 / 5680.0 %4 / 5
CubicHarmonicBase.cpp +
93.7%93.7%
+
93.7 %74 / 7975.0 %3 / 4
CubicHarmonicBase.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
EnvironmentSimilarity.cpp +
94.1%94.1%
+
94.1 %225 / 23985.7 %6 / 7
Fccubic.cpp +
100.0%
+
100.0 %28 / 2875.0 %3 / 4
Gradient.cpp +
71.4%71.4%
+
71.4 %50 / 7080.0 %4 / 5
Gradient.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
GradientVessel.cpp +
84.5%84.5%
+
84.5 %82 / 97100.0 %10 / 10
InterMolecularTorsions.cpp +
21.0%21.0%
+
21.0 %13 / 6214.3 %1 / 7
LocalSteinhardt.h +
72.2%72.2%
+
72.2 %13 / 1855.6 %5 / 9
MoleculeOrientation.cpp +
94.5%94.5%
+
94.5 %52 / 5571.4 %5 / 7
MoleculePlane.cpp +
72.5%72.5%
+
72.5 %37 / 5160.0 %3 / 5
OrientationSphere.cpp +
90.9%90.9%
+
90.9 %60 / 6675.0 %3 / 4
OrientationSphere.h +
100.0%
+
100.0 %3 / 3100.0 %2 / 2
PolymerAngles.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
Q3.cpp +
17.6%17.6%
+
17.6 %3 / 1733.3 %1 / 3
Q4.cpp +
100.0%
+
100.0 %17 / 1766.7 %2 / 3
Q6.cpp +
100.0%
+
100.0 %20 / 2066.7 %2 / 3
SMAC.cpp +
100.0%
+
100.0 %42 / 4280.0 %4 / 5
SimpleCubic.cpp +
100.0%
+
100.0 %24 / 2475.0 %3 / 4
Steinhardt.cpp +
100.0%
+
100.0 %78 / 7883.3 %5 / 6
Tetrahedral.cpp +
100.0%
+
100.0 %22 / 2275.0 %3 / 4
VectorMean.cpp +
100.0%
+
100.0 %44 / 44100.0 %10 / 10
VectorMultiColvar.cpp +
79.1%79.1%
+
79.1 %34 / 4366.7 %6 / 9
VectorMultiColvar.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
VectorSum.cpp +
11.9%11.9%
+
11.9 %5 / 4230.0 %3 / 10
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func-sort-c.html b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func-sort-c.html new file mode 100644 index 000000000000..e9e43e7d5a46 --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ClassicalMultiDimensionalScaling.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ClassicalMultiDimensionalScaling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC1ERKNS_13ActionOptionsE7
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling20calculateProjectionsERKNS_6MatrixIdEERS3_12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html new file mode 100644 index 000000000000..ed51d4a7f1ea --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ClassicalMultiDimensionalScaling.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ClassicalMultiDimensionalScaling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD6dimred32ClassicalMultiDimensionalScaling20calculateProjectionsERKNS_6MatrixIdEERS3_12
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC1ERKNS_13ActionOptionsE7
_ZN4PLMD6dimred32ClassicalMultiDimensionalScalingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html new file mode 100644 index 000000000000..23f6dd19bd08 --- /dev/null +++ b/coverage/dimred/ClassicalMultiDimensionalScaling.cpp.gcov.html @@ -0,0 +1,287 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ClassicalMultiDimensionalScaling.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ClassicalMultiDimensionalScaling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DimensionalityReductionBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC DIMRED CLASSICAL_MDS
+      26             : /*
+      27             : Create a low-dimensional projection of a trajectory using the classical multidimensional
+      28             :  scaling algorithm.
+      29             : 
+      30             : Multidimensional scaling (MDS) is similar to what is done when you make a map. You start with distances
+      31             : between London, Belfast, Paris and Dublin and then you try to arrange points on a piece of paper so that the (suitably scaled)
+      32             : distances between the points in your map representing each of those cities are related to the true distances between the cities.
+      33             : Stating this more mathematically MDS endeavors to find an <a href="http://en.wikipedia.org/wiki/Isometry">isometry</a>
+      34             : between points distributed in a high-dimensional space and a set of points distributed in a low-dimensional plane.
+      35             : In other words, if we have \f$M\f$ \f$D\f$-dimensional points, \f$\mathbf{X}\f$,
+      36             : and we can calculate dissimilarities between pairs them, \f$D_{ij}\f$, we can, with an MDS calculation, try to create \f$M\f$ projections,
+      37             : \f$\mathbf{x}\f$, of the high dimensionality points in a \f$d\f$-dimensional linear space by trying to arrange the projections so that the
+      38             : Euclidean distances between pairs of them, \f$d_{ij}\f$, resemble the dissimilarities between the high dimensional points.  In short we minimize:
+      39             : 
+      40             : \f[
+      41             : \chi^2 = \sum_{i \ne j} \left( D_{ij} - d_{ij} \right)^2
+      42             : \f]
+      43             : 
+      44             : where \f$D_{ij}\f$ is the distance between point \f$X^{i}\f$ and point \f$X^{j}\f$ and \f$d_{ij}\f$ is the distance between the projection
+      45             : of \f$X^{i}\f$, \f$x^i\f$, and the projection of \f$X^{j}\f$, \f$x^j\f$.  A tutorial on this approach can be used to analyze simulations
+      46             : can be found in the tutorial \ref lugano-5 and in the following <a href="https://www.youtube.com/watch?v=ofC2qz0_9_A&feature=youtu.be" > short video.</a>
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : The following command instructs plumed to construct a classical multidimensional scaling projection of a trajectory.
+      51             : The RMSD distance between atoms 1-256 have moved is used to measure the distances in the high-dimensional space.
+      52             : 
+      53             : \plumedfile
+      54             : data: COLLECT_FRAMES ATOMS=1-256
+      55             : mat: EUCLIDEAN_DISSIMILARITIES USE_OUTPUT_DATA_FROM=data
+      56             : mds: CLASSICAL_MDS USE_OUTPUT_DATA_FROM=mat NLOW_DIM=2
+      57             : OUTPUT_ANALYSIS_DATA_TO_COLVAR USE_OUTPUT_DATA_FROM=mds FILE=rmsd-embed
+      58             : \endplumedfile
+      59             : 
+      60             : The following section is for people who are interested in how this method works in detail. A solid understanding of this material is
+      61             : not necessary to use MDS.
+      62             : 
+      63             : \section dim-sec Method of optimization
+      64             : 
+      65             : The stress function can be minimized using a standard optimization algorithm such as conjugate gradients or steepest descent.
+      66             : However, it is more common to do this minimization using a technique known as classical scaling.  Classical scaling works by
+      67             : recognizing that each of the distances $D_{ij}$ in the above sum can be written as:
+      68             : 
+      69             : \f[
+      70             : D_{ij}^2 = \sum_{\alpha} (X^i_\alpha - X^j_\alpha)^2 = \sum_\alpha (X^i_\alpha)^2 + (X^j_\alpha)^2 - 2X^i_\alpha X^j_\alpha
+      71             : \f]
+      72             : 
+      73             : We can use this expression and matrix algebra to calculate multiple distances at once.  For instance if we have three points,
+      74             : \f$\mathbf{X}\f$, we can write distances between them as:
+      75             : 
+      76             : \f{eqnarray*}{
+      77             : D^2(\mathbf{X}) &=& \left[ \begin{array}{ccc}
+      78             : 0 & d_{12}^2 & d_{13}^2 \\
+      79             : d_{12}^2 & 0 & d_{23}^2 \\
+      80             : d_{13}^2 & d_{23}^2 & 0
+      81             : \end{array}\right] \\
+      82             : &=&
+      83             : \sum_\alpha \left[ \begin{array}{ccc}
+      84             : (X^1_\alpha)^2 & (X^1_\alpha)^2 & (X^1_\alpha)^2 \\
+      85             : (X^2_\alpha)^2 & (X^2_\alpha)^2 & (X^2_\alpha)^2 \\
+      86             : (X^3_\alpha)^2 & (X^3_\alpha)^2 & (X^3_\alpha)^2 \\
+      87             : \end{array}\right]
+      88             :  + \sum_\alpha \left[ \begin{array}{ccc}
+      89             : (X^1_\alpha)^2 & (X^2_\alpha)^2 & (X^3_\alpha)^2 \\
+      90             : (X^1_\alpha)^2 & (X^2_\alpha)^2 & (X^3_\alpha)^2 \\
+      91             : (X^1_\alpha)^2 & (X^2_\alpha)^2 & (X^3_\alpha)^2 \\
+      92             : \end{array}\right]
+      93             : - 2 \sum_\alpha \left[ \begin{array}{ccc}
+      94             : X^1_\alpha X^1_\alpha & X^1_\alpha X^2_\alpha & X^1_\alpha X^3_\alpha \\
+      95             : X^2_\alpha X^1_\alpha & X^2_\alpha X^2_\alpha & X^2_\alpha X^3_\alpha \\
+      96             : X^1_\alpha X^3_\alpha & X^3_\alpha X^2_\alpha & X^3_\alpha X^3_\alpha
+      97             : \end{array}\right] \nonumber \\
+      98             : &=& \mathbf{c 1^T} + \mathbf{1 c^T} - 2 \sum_\alpha \mathbf{x}_a \mathbf{x}^T_a =  \mathbf{c 1^T} + \mathbf{1 c^T} - 2\mathbf{X X^T}
+      99             : \f}
+     100             : 
+     101             : This last equation can be extended to situations when we have more than three points.  In it \f$\mathbf{X}\f$ is a matrix that has
+     102             : one high-dimensional point on each of its rows and \f$\mathbf{X^T}\f$ is its transpose.  \f$\mathbf{1}\f$ is an \f$M \times 1\f$ vector
+     103             : of ones and \f$\mathbf{c}\f$ is a vector with components given by:
+     104             : 
+     105             : \f[
+     106             : c_i = \sum_\alpha (x_\alpha^i)^2
+     107             : \f]
+     108             : 
+     109             : These quantities are the diagonal elements of \f$\mathbf{X X^T}\f$, which is a dot product or Gram Matrix that contains the
+     110             : dot product of the vector \f$X_i\f$ with the vector \f$X_j\f$ in element \f$i,j\f$.
+     111             : 
+     112             : In classical scaling we introduce a centering matrix \f$\mathbf{J}\f$ that is given by:
+     113             : 
+     114             : \f[
+     115             : \mathbf{J} = \mathbf{I} - \frac{1}{M} \mathbf{11^T}
+     116             : \f]
+     117             : 
+     118             : where \f$\mathbf{I}\f$ is the identity.  Multiplying the equations above from the front and back by this matrix and a factor of a \f$-\frac{1}{2}\f$ gives:
+     119             : 
+     120             : \f{eqnarray*}{
+     121             :  -\frac{1}{2} \mathbf{J} \mathbf{D}^2(\mathbf{X}) \mathbf{J} &=& -\frac{1}{2}\mathbf{J}( \mathbf{c 1^T} + \mathbf{1 c^T} - 2\mathbf{X X^T})\mathbf{J} \\
+     122             :  &=& -\frac{1}{2}\mathbf{J c 1^T J} - \frac{1}{2} \mathbf{J 1 c^T J} + \frac{1}{2} \mathbf{J}(2\mathbf{X X^T})\mathbf{J} \\
+     123             :  &=& \mathbf{ J X X^T J } = \mathbf{X X^T } \label{eqn:scaling}
+     124             : \f}
+     125             : 
+     126             : The fist two terms in this expression disappear because \f$\mathbf{1^T J}=\mathbf{J 1} =\mathbf{0}\f$, where \f$\mathbf{0}\f$
+     127             : is a matrix containing all zeros.  In the final step meanwhile we use the fact that the matrix of squared distances will not
+     128             : change when we translate all the points.  We can thus assume that the mean value, \f$\mu\f$, for each of the components, \f$\alpha\f$:
+     129             : \f[
+     130             : \mu_\alpha = \frac{1}{M} \sum_{i=1}^N \mathbf{X}^i_\alpha
+     131             : \f]
+     132             : is equal to 0 so the columns of \f$\mathbf{X}\f$ add up to 0.  This in turn means that each of the columns of
+     133             : \f$\mathbf{X X^T}\f$ adds up to zero, which is what allows us to write \f$\mathbf{ J X X^T J } = \mathbf{X X^T }\f$.
+     134             : 
+     135             : The matrix of squared distances is symmetric and positive-definite we can thus use the spectral decomposition to decompose it as:
+     136             : 
+     137             : \f[
+     138             : \Phi= \mathbf{V} \Lambda \mathbf{V}^T
+     139             : \f]
+     140             : 
+     141             : Furthermore, because the matrix we are diagonalizing, \f$\mathbf{X X^T}\f$, is the product of a matrix and its transpose
+     142             : we can use this decomposition to write:
+     143             : 
+     144             : \f[
+     145             : \mathbf{X} =\mathbf{V} \Lambda^\frac{1}{2}
+     146             : \f]
+     147             : 
+     148             : Much as in PCA there are generally a small number of large eigenvalues in \f$\Lambda\f$ and many small eigenvalues.
+     149             : We can safely use only the large eigenvalues and their corresponding eigenvectors to express the relationship between
+     150             : the coordinates \f$\mathbf{X}\f$.  This gives us our set of low-dimensional projections.
+     151             : 
+     152             : This derivation makes a number of assumptions about the how the low dimensional points should best be arranged to minimize
+     153             : the stress. If you use an interactive optimization algorithm such as SMACOF you may thus be able to find a better
+     154             : (lower-stress) projection of the points.  For more details on the assumptions made
+     155             : see <a href="http://quest4rigor.com/tag/multidimensional-scaling/"> this website.</a>
+     156             : */
+     157             : //+ENDPLUMEDOC
+     158             : 
+     159             : namespace PLMD {
+     160             : namespace dimred {
+     161             : 
+     162             : class ClassicalMultiDimensionalScaling : public DimensionalityReductionBase {
+     163             : public:
+     164             :   static void registerKeywords( Keywords& keys );
+     165             :   explicit ClassicalMultiDimensionalScaling( const ActionOptions& ao );
+     166             :   void calculateProjections( const Matrix<double>&, Matrix<double>& ) override;
+     167             : };
+     168             : 
+     169             : PLUMED_REGISTER_ACTION(ClassicalMultiDimensionalScaling,"CLASSICAL_MDS")
+     170             : 
+     171           9 : void ClassicalMultiDimensionalScaling::registerKeywords( Keywords& keys ) {
+     172           9 :   DimensionalityReductionBase::registerKeywords( keys );
+     173           9 : }
+     174             : 
+     175           7 : ClassicalMultiDimensionalScaling::ClassicalMultiDimensionalScaling( const ActionOptions& ao):
+     176             :   Action(ao),
+     177           7 :   DimensionalityReductionBase(ao)
+     178             : {
+     179           7 :   if( dimredbase ) error("input to CLASSICAL_MDS should not be output from dimensionality reduction object");
+     180           7 : }
+     181             : 
+     182          12 : void ClassicalMultiDimensionalScaling::calculateProjections( const Matrix<double>& targets, Matrix<double>& projections ) {
+     183             :   // Retrieve the distances from the dimensionality reduction object
+     184          12 :   double half=(-0.5); Matrix<double> distances( half*targets );
+     185             : 
+     186             :   // Apply centering transtion
+     187             :   unsigned n=distances.nrows(); double sum;
+     188             :   // First HM
+     189        1564 :   for(unsigned i=0; i<n; ++i) {
+     190      389056 :     sum=0; for(unsigned j=0; j<n; ++j) sum+=distances(i,j);
+     191      389056 :     for(unsigned j=0; j<n; ++j) distances(i,j) -= sum/n;
+     192             :   }
+     193             :   // Now (HM)H
+     194        1564 :   for(unsigned i=0; i<n; ++i) {
+     195      389056 :     sum=0; for(unsigned j=0; j<n; ++j) sum+=distances(j,i);
+     196      389056 :     for(unsigned j=0; j<n; ++j) distances(j,i) -= sum/n;
+     197             :   }
+     198             : 
+     199             :   // Diagonalize matrix
+     200          12 :   std::vector<double> eigval(n); Matrix<double> eigvec(n,n);
+     201          12 :   diagMat( distances, eigval, eigvec );
+     202             : 
+     203             :   // Pass final projections to map object
+     204        1564 :   for(unsigned i=0; i<n; ++i) {
+     205        4654 :     for(unsigned j=0; j<projections.ncols(); ++j) projections(i,j)=std::sqrt(eigval[n-1-j])*eigvec(n-1-j,i);
+     206             :   }
+     207          12 : }
+     208             : 
+     209             : }
+     210             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.cpp.func-sort-c.html b/coverage/dimred/DimensionalityReductionBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..3cdafde33de5 --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - dimred/DimensionalityReductionBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - DimensionalityReductionBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:475979.7 %
Date:2024-02-22 21:58:45Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase15calculateStressERKSt6vectorIdSaIdEERS4_0
_ZN4PLMD6dimred27DimensionalityReductionBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred27DimensionalityReductionBase15getArgumentListEv2
_ZN4PLMD6dimred27DimensionalityReductionBaseC2ERKNS_13ActionOptionsE16
_ZN4PLMD6dimred27DimensionalityReductionBase15performAnalysisEv19
_ZN4PLMD6dimred27DimensionalityReductionBase16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD6dimred27DimensionalityReductionBase13getProjectionERKjRSt6vectorIdSaIdEERd1050
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.cpp.func.html b/coverage/dimred/DimensionalityReductionBase.cpp.func.html new file mode 100644 index 000000000000..a394719bf55d --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - dimred/DimensionalityReductionBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - DimensionalityReductionBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:475979.7 %
Date:2024-02-22 21:58:45Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase13getProjectionERKjRSt6vectorIdSaIdEERd1050
_ZN4PLMD6dimred27DimensionalityReductionBase15calculateStressERKSt6vectorIdSaIdEERS4_0
_ZN4PLMD6dimred27DimensionalityReductionBase15getArgumentListEv2
_ZN4PLMD6dimred27DimensionalityReductionBase15performAnalysisEv19
_ZN4PLMD6dimred27DimensionalityReductionBase16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD6dimred27DimensionalityReductionBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred27DimensionalityReductionBaseC2ERKNS_13ActionOptionsE16
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.cpp.gcov.html b/coverage/dimred/DimensionalityReductionBase.cpp.gcov.html new file mode 100644 index 000000000000..bad5d0f42142 --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.cpp.gcov.html @@ -0,0 +1,212 @@ + + + + + + + + LCOV - plumed test coverage - dimred/DimensionalityReductionBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - DimensionalityReductionBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:475979.7 %
Date:2024-02-22 21:58:45Functions:5771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DimensionalityReductionBase.h"
+      23             : #include "reference/ReferenceConfiguration.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace dimred {
+      28             : 
+      29          30 : void DimensionalityReductionBase::registerKeywords( Keywords& keys ) {
+      30          30 :   analysis::AnalysisBase::registerKeywords( keys );
+      31          60 :   keys.add("compulsory","NLOW_DIM","number of low-dimensional coordinates required");
+      32          60 :   keys.addOutputComponent("coord","default","the low-dimensional projections of the various input configurations");
+      33          30 : }
+      34             : 
+      35          16 : DimensionalityReductionBase::DimensionalityReductionBase( const ActionOptions& ao ):
+      36             :   Action(ao),
+      37             :   analysis::AnalysisBase(ao),
+      38          16 :   dimredbase(NULL)
+      39             : {
+      40             :   // Check that some dissimilarity information is available
+      41          16 :   if( my_input_data ) {
+      42          27 :     if( getName()!="PCA" && !dissimilaritiesWereSet() ) error("dissimilarities have not been calcualted in input actions");
+      43             :     // Now we check if the input was a dimensionality reduction object
+      44          15 :     dimredbase = dynamic_cast<DimensionalityReductionBase*>( my_input_data );
+      45             :   }
+      46             : 
+      47             :   // Retrieve the dimension in the low dimensionality space
+      48          16 :   nlow=0;
+      49          16 :   if( dimredbase ) {
+      50           5 :     nlow=dimredbase->nlow;
+      51           5 :     log.printf("  projecting in %u dimensional space \n",nlow);
+      52          22 :   } else if( keywords.exists("NLOW_DIM") ) {
+      53          10 :     parse("NLOW_DIM",nlow);
+      54          10 :     if( nlow<1 ) error("dimensionality of low dimensional space must be at least one");
+      55          10 :     log.printf("  projecting in %u dimensional space \n",nlow);
+      56             :   }
+      57             :   // Now add fake components to the underlying ActionWithValue for the arguments
+      58             :   std::string num;
+      59          45 :   for(unsigned i=0; i<nlow; ++i) {
+      60          87 :     Tools::convert(i+1,num); addComponent( "coord-" + num ); componentIsNotPeriodic( "coord-" + num );
+      61             :   }
+      62          16 : }
+      63             : 
+      64           2 : std::vector<Value*> DimensionalityReductionBase::getArgumentList() {
+      65             :   std::vector<Value*> arglist( analysis::AnalysisBase::getArgumentList() );
+      66           6 :   for(unsigned i=0; i<nlow; ++i) arglist.push_back( getPntrToComponent(i) );
+      67           2 :   return arglist;
+      68             : }
+      69             : 
+      70        1050 : void DimensionalityReductionBase::getProjection( const unsigned& idata, std::vector<double>& point, double& weight ) {
+      71        1050 :   if( point.size()!=nlow ) point.resize( nlow );
+      72        3150 :   weight = getWeight(idata); for(unsigned i=0; i<nlow; ++i) point[i]=projections(idata,i);
+      73        1050 : }
+      74             : 
+      75          19 : void DimensionalityReductionBase::performAnalysis() {
+      76          19 :   log.printf("Generating projections required by action %s \n",getLabel().c_str() );
+      77             :   // Resize the tempory array (this is used for out of sample)
+      78          19 :   dtargets.resize( getNumberOfDataPoints() );
+      79             :   // Resize the projections array
+      80          19 :   projections.resize( getNumberOfDataPoints(), nlow );
+      81             :   // Retrieve the projections from the previous calculation
+      82          19 :   if( dimredbase ) {
+      83           6 :     std::vector<double> newp( nlow ); double w;
+      84        1056 :     for(unsigned i=0; i<getNumberOfDataPoints(); ++i) {
+      85        1050 :       dimredbase->getProjection( i, newp, w ); plumed_dbg_assert( newp.size()==nlow );
+      86        3150 :       for(unsigned j=0; j<nlow; ++j) projections(i,j)=newp[j];
+      87             :     }
+      88             :   }
+      89             :   // Calculate matrix of dissimilarities
+      90          19 :   Matrix<double> targets( getNumberOfDataPoints(), getNumberOfDataPoints() ); targets=0;
+      91        2686 :   for(unsigned i=1; i<getNumberOfDataPoints(); ++i) {
+      92      367354 :     for(unsigned j=0; j<i; ++j) targets(i,j)=targets(j,i)=getDissimilarity( i, j );
+      93             :   }
+      94             :   // This calculates the projections of the points
+      95          19 :   calculateProjections( targets, projections );
+      96             :   // Now set the projection values in the underlying object
+      97          19 :   if( my_input_data ) {
+      98        2620 :     for(unsigned idat=0; idat<getNumberOfDataPoints(); ++idat) {
+      99        2602 :       analysis::DataCollectionObject& myref=AnalysisBase::getStoredData(idat,false); std::string num;
+     100        7804 :       for(unsigned i=0; i<nlow; ++i) { Tools::convert(i+1,num); myref.setArgument( getLabel() + ".coord-" + num, projections(idat,i) ); }
+     101             :     }
+     102             :   }
+     103          19 :   log.printf("Generated projections required by action %s \n",getLabel().c_str() );
+     104          19 : }
+     105             : 
+     106           0 : double DimensionalityReductionBase::calculateStress( const std::vector<double>& p, std::vector<double>& d ) {
+     107             : 
+     108             :   // Zero derivative and stress accumulators
+     109           0 :   for(unsigned i=0; i<p.size(); ++i) d[i]=0.0;
+     110           0 :   double stress=0; std::vector<double> dtmp( p.size() );
+     111             : 
+     112             :   // Now accumulate total stress on system
+     113           0 :   for(unsigned i=0; i<dtargets.size(); ++i) {
+     114           0 :     if( dtargets[i]<epsilon ) continue ;
+     115             : 
+     116             :     // Calculate distance in low dimensional space
+     117             :     double dd=0;
+     118           0 :     for(unsigned j=0; j<p.size(); ++j) { dtmp[j]=p[j]-projections(i,j); dd+=dtmp[j]*dtmp[j]; }
+     119           0 :     dd = std::sqrt(dd);
+     120             : 
+     121             :     // Now do transformations and calculate differences
+     122           0 :     double ddiff = dd - dtargets[i];
+     123             : 
+     124             :     // Calculate derivatives
+     125           0 :     double pref = 2.*getWeight(i) / dd;
+     126           0 :     for(unsigned j=0; j<p.size(); ++j) d[j] += pref*ddiff*dtmp[j];
+     127             : 
+     128             :     // Accumulate the total stress
+     129           0 :     stress += getWeight(i)*ddiff*ddiff;
+     130             :   }
+     131           0 :   return stress;
+     132             : }
+     133             : 
+     134             : }
+     135             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.h.func-sort-c.html b/coverage/dimred/DimensionalityReductionBase.h.func-sort-c.html new file mode 100644 index 000000000000..91c81dcd3769 --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - dimred/DimensionalityReductionBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - DimensionalityReductionBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:040.0 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase17setTargetDistanceERKjRKd0
_ZNK4PLMD6dimred27DimensionalityReductionBase11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.h.func.html b/coverage/dimred/DimensionalityReductionBase.h.func.html new file mode 100644 index 000000000000..bf73d1e64ef6 --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - dimred/DimensionalityReductionBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - DimensionalityReductionBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:040.0 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred27DimensionalityReductionBase17setTargetDistanceERKjRKd0
_ZNK4PLMD6dimred27DimensionalityReductionBase11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/DimensionalityReductionBase.h.gcov.html b/coverage/dimred/DimensionalityReductionBase.h.gcov.html new file mode 100644 index 000000000000..8b5334bded86 --- /dev/null +++ b/coverage/dimred/DimensionalityReductionBase.h.gcov.html @@ -0,0 +1,151 @@ + + + + + + + + LCOV - plumed test coverage - dimred/DimensionalityReductionBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - DimensionalityReductionBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:040.0 %
Date:2024-02-22 21:58:45Functions:020.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_dimred_DimensionalityReductionBase_h
+      23             : #define __PLUMED_dimred_DimensionalityReductionBase_h
+      24             : 
+      25             : #include "analysis/AnalysisBase.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace dimred {
+      29             : 
+      30             : class DimensionalityReductionBase : public analysis::AnalysisBase {
+      31             :   friend class ProjectNonLandmarkPoints;
+      32             :   friend class SketchMapBase;
+      33             : private:
+      34             : /// This are the target distances for a single point.
+      35             : /// This is used when we do out of sample or pointwise global optimization
+      36             :   std::vector<double> dtargets;
+      37             : /// The projections that were generated by the dimensionality reduction algorithm
+      38             :   Matrix<double> projections;
+      39             : protected:
+      40             : /// Dimensionality of low dimensional space
+      41             :   unsigned nlow;
+      42             : /// A pointer to any dimensionality reduction base that we have got projections from
+      43             :   DimensionalityReductionBase* dimredbase;
+      44             : public:
+      45             :   static void registerKeywords( Keywords& keys );
+      46             :   explicit DimensionalityReductionBase( const ActionOptions& );
+      47             : /// Get the ith data point (this returns the projection)
+      48             :   virtual void getProjection( const unsigned& idata, std::vector<double>& point, double& weight );
+      49             : /// Actually perform the analysis
+      50             :   virtual void performAnalysis();
+      51             : /// Overwrite getArguments so we get arguments from underlying class
+      52             :   std::vector<Value*> getArgumentList();
+      53             : /// Calculate the projections of points
+      54             :   virtual void calculateProjections( const Matrix<double>&, Matrix<double>& )=0;
+      55             : /// Set one of the elements in the target vector.  This target vector is used
+      56             : /// when we use calculateStress when finding the projections of individual points.
+      57             : /// For example this function is used in PLMD::dimred::ProjectOutOfSample
+      58             :   virtual void setTargetDistance( const unsigned&, const double& );
+      59             : /// Calculate the pointwise stress on one point when it is located at pp.
+      60             : /// This function makes use of the distance data in dtargets
+      61             : /// It is used in PLMD::dimred::ProjectOutOfSample and in pointwise optimisation
+      62             :   virtual double calculateStress( const std::vector<double>& pp, std::vector<double>& der );
+      63             : /// Overwrite virtual function in ActionWithVessel
+      64           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const { plumed_error(); }
+      65             : };
+      66             : 
+      67             : inline
+      68           0 : void DimensionalityReductionBase::setTargetDistance( const unsigned& idata, const double& dist ) {
+      69           0 :   dtargets[idata]=dist;
+      70           0 : }
+      71             : 
+      72             : }
+      73             : }
+      74             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/OutputPCAProjections.cpp.func-sort-c.html b/coverage/dimred/OutputPCAProjections.cpp.func-sort-c.html new file mode 100644 index 000000000000..2cff724868cd --- /dev/null +++ b/coverage/dimred/OutputPCAProjections.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - dimred/OutputPCAProjections.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - OutputPCAProjections.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343597.1 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred19OutputPCAProjectionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred19OutputPCAProjection11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD6dimred19OutputPCAProjection15performAnalysisEv2
_ZN4PLMD6dimred19OutputPCAProjectionC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred19OutputPCAProjection16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/OutputPCAProjections.cpp.func.html b/coverage/dimred/OutputPCAProjections.cpp.func.html new file mode 100644 index 000000000000..4409d10016ca --- /dev/null +++ b/coverage/dimred/OutputPCAProjections.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - dimred/OutputPCAProjections.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - OutputPCAProjections.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343597.1 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred19OutputPCAProjection15performAnalysisEv2
_ZN4PLMD6dimred19OutputPCAProjection16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred19OutputPCAProjectionC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred19OutputPCAProjectionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred19OutputPCAProjection11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/OutputPCAProjections.cpp.gcov.html b/coverage/dimred/OutputPCAProjections.cpp.gcov.html new file mode 100644 index 000000000000..445deac6ee1e --- /dev/null +++ b/coverage/dimred/OutputPCAProjections.cpp.gcov.html @@ -0,0 +1,188 @@ + + + + + + + + LCOV - plumed test coverage - dimred/OutputPCAProjections.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - OutputPCAProjections.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343597.1 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "analysis/AnalysisBase.h"
+      23             : #include "reference/ReferenceAtoms.h"
+      24             : #include "reference/ReferenceArguments.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/GenericMolInfo.h"
+      29             : #include "tools/PDB.h"
+      30             : #include "PCA.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace dimred {
+      34             : 
+      35             : //+PLUMEDOC DIMRED OUTPUT_PCA_PROJECTION
+      36             : /*
+      37             : This is used to output the projection calculated by principle component analysis
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : class OutputPCAProjection : public analysis::AnalysisBase {
+      45             : private:
+      46             :   PDB mypdb;
+      47             :   PCA* mypca;
+      48             :   std::string fmt;
+      49             :   std::string filename;
+      50             : public:
+      51             :   static void registerKeywords( Keywords& keys );
+      52             :   explicit OutputPCAProjection( const ActionOptions& );
+      53           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const { plumed_error(); }
+      54             :   void performAnalysis();
+      55             : };
+      56             : 
+      57             : PLUMED_REGISTER_ACTION(OutputPCAProjection,"OUTPUT_PCA_PROJECTION")
+      58             : 
+      59           4 : void OutputPCAProjection::registerKeywords( Keywords& keys ) {
+      60           4 :   analysis::AnalysisBase::registerKeywords( keys );
+      61           8 :   keys.add("compulsory","FILE","the name of the file to output to");
+      62           8 :   keys.add("optional","FMT","the format to use in the output file");
+      63           8 :   keys.add("compulsory","STRIDE","0","the frequency with which to perform the required analysis and to output the data.  The default value of 0 tells plumed to use all the data");
+      64           4 : }
+      65             : 
+      66           2 : OutputPCAProjection::OutputPCAProjection( const ActionOptions& ao ):
+      67             :   Action(ao),
+      68             :   analysis::AnalysisBase(ao),
+      69           2 :   fmt("%f")
+      70             : {
+      71             :   // Setup the PCA object
+      72           2 :   mypca = dynamic_cast<PCA*>( my_input_data );
+      73           2 :   if( !mypca ) error("input must be a PCA object");
+      74             : 
+      75             :   // Get setup the pdb
+      76           2 :   mypdb.setAtomNumbers( my_input_data->getAtomIndexes() );
+      77           2 :   mypdb.setArgumentNames( (mypca->my_input_data)->getArgumentNames() );
+      78             : 
+      79             :   // Find a moldata object
+      80           2 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      81           3 :   if( moldat ) warning("PDB output files do not have atom types unless you use MOLDATA");
+      82             : 
+      83           6 :   parse("FILE",filename); parse("FMT",fmt);
+      84           4 :   if( !getRestart() ) { OFile ofile; ofile.link(*this); ofile.setBackupString("analysis"); ofile.backupAllFiles(filename); }
+      85           2 :   log.printf("  printing data to file named %s \n",filename.c_str() );
+      86           2 : }
+      87             : 
+      88           2 : void OutputPCAProjection::performAnalysis() {
+      89             :   // Find a moldata object
+      90           2 :   auto* mymoldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+      91             :   // Output the embedding in plumed pdb format
+      92           2 :   OFile afile; afile.link(*this); afile.setBackupString("analysis");
+      93           2 :   mypdb.setAtomPositions( (mypca->myref)->getReferencePositions() );
+      94           4 :   for(unsigned j=0; j<mypca->getArguments().size(); ++j) mypdb.setArgumentValue( (mypca->getArguments()[j])->getName(), (mypca->myref)->getReferenceArgument(j) );
+      95             :   // And output the first frame
+      96           2 :   afile.open( filename ); afile.printf("REMARK TYPE=%s \n", mypca->mtype.c_str() );
+      97           2 :   if( usingNaturalUnits() ) mypdb.print( 1.0, mymoldat, afile, fmt );
+      98           2 :   else mypdb.print( getUnits().getLength()/0.1, mymoldat, afile, fmt );
+      99             :   // And now output the eigenvectors
+     100           6 :   for(unsigned dim=0; dim<mypca->nlow; ++dim) {
+     101           4 :     afile.printf("REMARK TYPE=DIRECTION \n");
+     102           4 :     mypdb.setAtomPositions( mypca->directions[dim].getReferencePositions() );
+     103           8 :     for(unsigned j=0; j<mypca->getArguments().size(); ++j) mypdb.setArgumentValue( (mypca->getArguments()[j])->getName(), mypca->directions[dim].getReferenceArgument(j) );
+     104           4 :     if( usingNaturalUnits() ) mypdb.print( 1.0, mymoldat, afile, fmt );
+     105           4 :     else mypdb.print( getUnits().getLength()/0.1, mymoldat, afile, fmt );
+     106             :   }
+     107           2 :   afile.close();
+     108           2 : }
+     109             : 
+     110             : }
+     111             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.cpp.func-sort-c.html b/coverage/dimred/PCA.cpp.func-sort-c.html new file mode 100644 index 000000000000..16944e8b89ae --- /dev/null +++ b/coverage/dimred/PCA.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - dimred/PCA.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - PCA.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9611980.7 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred3PCA13getProjectionERKjRSt6vectorIdSaIdEERd0
_ZN4PLMD6dimred3PCAC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred3PCA15performAnalysisEv3
_ZN4PLMD6dimred3PCAC1ERKNS_13ActionOptionsE3
_ZN4PLMD6dimred3PCA16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6dimred3PCA13getProjectionERNS_8analysis20DataCollectionObjectERSt6vectorIdSaIdEE546
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.cpp.func.html b/coverage/dimred/PCA.cpp.func.html new file mode 100644 index 000000000000..fec3b1e4cb18 --- /dev/null +++ b/coverage/dimred/PCA.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - dimred/PCA.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - PCA.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9611980.7 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred3PCA13getProjectionERKjRSt6vectorIdSaIdEERd0
_ZN4PLMD6dimred3PCA13getProjectionERNS_8analysis20DataCollectionObjectERSt6vectorIdSaIdEE546
_ZN4PLMD6dimred3PCA15performAnalysisEv3
_ZN4PLMD6dimred3PCA16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6dimred3PCAC1ERKNS_13ActionOptionsE3
_ZN4PLMD6dimred3PCAC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.cpp.gcov.html b/coverage/dimred/PCA.cpp.gcov.html new file mode 100644 index 000000000000..a054baed9db3 --- /dev/null +++ b/coverage/dimred/PCA.cpp.gcov.html @@ -0,0 +1,355 @@ + + + + + + + + LCOV - plumed test coverage - dimred/PCA.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - PCA.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9611980.7 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PCA.h"
+      23             : #include "tools/Matrix.h"
+      24             : #include "reference/MetricRegister.h"
+      25             : #include "reference/ReferenceValuePack.h"
+      26             : #include "analysis/ReadAnalysisFrames.h"
+      27             : #include "core/ActionRegister.h"
+      28             : 
+      29             : //+PLUMEDOC DIMRED PCA
+      30             : /*
+      31             : Perform principal component analysis (PCA) using either the positions of the atoms a large number of collective variables as input.
+      32             : 
+      33             : Principal component analysis is a statistical technique that uses an orthogonal transformation to convert a set of observations of
+      34             : poorly correlated variables into a set of linearly uncorrelated variables.  You can read more about the specifics of this technique
+      35             : here: https://en.wikipedia.org/wiki/Principal_component_analysis
+      36             : 
+      37             : When used with molecular dynamics simulations a set of frames taken from the trajectory, \f$\{X_i\}\f$, or the values of
+      38             : a number of collective variables which are calculated from the trajectory frames are used as input.  In this second instance your
+      39             : input to the PCA analysis algorithm is thus a set of high-dimensional vectors of collective variables.  However, if
+      40             : collective variables are calculated from the positions of the atoms or if the positions are used directly the assumption is that
+      41             : this input trajectory is a set of poorly correlated (high-dimensional) vectors.  After principal component analysis has been
+      42             : performed the output is a set of orthogonal vectors that describe the directions in which the largest motions have been seen.
+      43             : In other words, principal component analysis provides a method for lowering the dimensionality of the data contained in a trajectory.
+      44             : These output directions are some linear combination of the \f$x\f$, \f$y\f$ and \f$z\f$ positions if the positions were used as input
+      45             : or some linear combination of the input collective variables if a high-dimensional vector of collective variables was used as input.
+      46             : 
+      47             : As explained on the Wikipedia page you must calculate the average and covariance for each of the input coordinates.  In other words, you must
+      48             : calculate the average structure and the amount the system fluctuates around this average structure.  The problem in doing so when the
+      49             : \f$x\f$, \f$y\f$ and \f$z\f$ coordinates of a molecule are used as input is that the majority of the changes in the positions of the
+      50             : atoms comes from the translational and rotational degrees of freedom of the molecule.  The first six principal components will thus, most likely,
+      51             : be uninteresting.  Consequently, to remedy this problem PLUMED provides the functionality to perform an RMSD alignment of the all the structures
+      52             : to be analyzed to the first frame in the trajectory.  This can be used to effectively remove translational and/or rotational motions from
+      53             : consideration.  The resulting principal components thus describe vibrational motions of the molecule.
+      54             : 
+      55             : If you wish to calculate the projection of a trajectory on a set of principal components calculated from this PCA action then the output can be
+      56             : used as input for the \ref PCAVARS action.
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : The following input instructs PLUMED to perform a principal component analysis in which the covariance matrix is calculated from changes in the positions
+      61             : of the first 22 atoms.  The TYPE=OPTIMAL instruction ensures that translational and rotational degrees of freedom are removed from consideration.
+      62             : The first two principal components will be output to a file called PCA-comp.pdb.  Trajectory frames will be collected on every step and the PCA calculation
+      63             : will be performed at the end of the simulation.
+      64             : 
+      65             : \plumedfile
+      66             : ff: COLLECT_FRAMES ATOMS=1-22 STRIDE=1
+      67             : pca: PCA USE_OUTPUT_DATA_FROM=ff METRIC=OPTIMAL NLOW_DIM=2
+      68             : OUTPUT_PCA_PROJECTION USE_OUTPUT_DATA_FROM=pca FILE=PCA-comp.pdb
+      69             : \endplumedfile
+      70             : 
+      71             : The following input instructs PLUMED to perform a principal component analysis in which the covariance matrix is calculated from changes in the six distances
+      72             : seen in the previous lines.  Notice that here the TYPE=EUCLIDEAN keyword is used to indicate that no alignment has to be done when calculating the various
+      73             : elements of the covariance matrix from the input vectors.  In this calculation the first two principal components will be output to a file called PCA-comp.pdb.
+      74             : Trajectory frames will be collected every five steps and the PCA calculation is performed every 1000 steps.  Consequently, if you run a 2000 step simulation the
+      75             : PCA analysis will be performed twice.  The REWEIGHT_BIAS action in this input tells PLUMED that rather that ascribing a weight of one to each of the frames
+      76             : when calculating averages and covariance matrices a reweighting should be performed based and each frames' weight in these calculations should be determined based on
+      77             : the current value of the instantaneous bias (see \ref REWEIGHT_BIAS).
+      78             : 
+      79             : \plumedfile
+      80             : d1: DISTANCE ATOMS=1,2
+      81             : d2: DISTANCE ATOMS=1,3
+      82             : d3: DISTANCE ATOMS=1,4
+      83             : d4: DISTANCE ATOMS=2,3
+      84             : d5: DISTANCE ATOMS=2,4
+      85             : d6: DISTANCE ATOMS=3,4
+      86             : rr: RESTRAINT ARG=d1 AT=0.1 KAPPA=10
+      87             : rbias: REWEIGHT_BIAS TEMP=300
+      88             : 
+      89             : ff: COLLECT_FRAMES ARG=d1,d2,d3,d4,d5,d6 LOGWEIGHTS=rbias STRIDE=5
+      90             : pca: PCA USE_OUTPUT_DATA_FROM=ff METRIC=EUCLIDEAN NLOW_DIM=2
+      91             : OUTPUT_PCA_PROJECTION USE_OUTPUT_DATA_FROM=pca STRIDE=100 FILE=PCA-comp.pdb
+      92             : \endplumedfile
+      93             : 
+      94             : */
+      95             : //+ENDPLUMEDOC
+      96             : 
+      97             : namespace PLMD {
+      98             : namespace dimred {
+      99             : 
+     100             : PLUMED_REGISTER_ACTION(PCA,"PCA")
+     101             : 
+     102           5 : void PCA::registerKeywords( Keywords& keys ) {
+     103          15 :   DimensionalityReductionBase::registerKeywords( keys ); keys.use("ARG"); keys.reset_style("ARG","optional");
+     104          10 :   keys.add("compulsory","METRIC","EUCLIDEAN","the method that you are going to use to measure the distances between points");
+     105          10 :   keys.add("atoms","ATOMS","the list of atoms that you are going to use in the measure of distance that you are using");
+     106           5 : }
+     107             : 
+     108           3 : PCA::PCA(const ActionOptions&ao):
+     109             :   Action(ao),
+     110           3 :   DimensionalityReductionBase(ao)
+     111             : {
+     112             :   // Get the input PDB file from the underlying ReadAnalysisFrames object
+     113           3 :   analysis::ReadAnalysisFrames* myframes = dynamic_cast<analysis::ReadAnalysisFrames*>( my_input_data );
+     114           3 :   if( !myframes ) error("input to PCA should be ReadAnalysisFrames object");
+     115           6 :   parse("METRIC",mtype); std::vector<AtomNumber> atoms;
+     116           3 :   log.printf("  performing PCA analysis using %s metric \n", mtype.c_str() );
+     117           3 :   if( my_input_data->getNumberOfAtoms()>0 ) {
+     118           2 :     parseAtomList("ATOMS",atoms);
+     119           1 :     if( atoms.size()!=0 ) {
+     120           0 :       mypdb.setAtomNumbers( atoms );
+     121           0 :       for(unsigned i=0; i<atoms.size(); ++i) {
+     122             :         bool found=false;
+     123           0 :         for(unsigned j=0; j<my_input_data->getAtomIndexes().size(); ++j) {
+     124           0 :           if( my_input_data->getAtomIndexes()[j]==atoms[i] ) { found=true; break; }
+     125             :         }
+     126           0 :         if( !found ) {
+     127           0 :           std::string num; Tools::convert( atoms[i].serial(), num );
+     128           0 :           error("atom number " + num + " is not stored in any action that has been input");
+     129             :         }
+     130             :       }
+     131           0 :       mypdb.addBlockEnd( atoms.size() );
+     132           1 :     } else if( getNumberOfArguments()==0 ) {
+     133           1 :       mypdb.setAtomNumbers( my_input_data->getAtomIndexes() );
+     134           1 :       mypdb.addBlockEnd( my_input_data->getAtomIndexes().size() );
+     135           1 :       if( mtype=="EUCLIDEAN" ) mtype="OPTIMAL";
+     136             :     }
+     137             :   }
+     138           3 :   if( my_input_data->getArgumentNames().size()>0 ) {
+     139           2 :     if( getNumberOfArguments()==0 && atoms.size()==0 ) {
+     140           2 :       std::vector<std::string> argnames( my_input_data->getArgumentNames() );
+     141           2 :       mypdb.setArgumentNames( argnames ); requestArguments( my_input_data->getArgumentList() );
+     142           2 :     } else {
+     143           0 :       std::vector<Value*> myargs( getArguments() );
+     144           0 :       std::vector<std::string> inargnames( my_input_data->getArgumentNames() );
+     145           0 :       std::vector<std::string> argnames( myargs.size() );
+     146           0 :       for(unsigned i=0; i<myargs.size(); ++i) {
+     147           0 :         argnames[i]=myargs[i]->getName();
+     148             :         bool found=false;
+     149           0 :         for(unsigned j=0; j<inargnames.size(); ++j) {
+     150           0 :           if( argnames[i]==inargnames[j] ) { found=true; break; }
+     151             :         }
+     152           0 :         if( !found ) error("input named " + my_input_data->getLabel() + " does not store/calculate quantity named " + argnames[i] );
+     153             :       }
+     154           0 :       mypdb.setArgumentNames( argnames ); requestArguments( myargs );
+     155           0 :     }
+     156             :   }
+     157           3 :   if( nlow==0 ) error("dimensionality of output not set");
+     158           3 :   checkRead();
+     159           3 : }
+     160             : 
+     161           3 : void PCA::performAnalysis() {
+     162             :   // Align everything to the first frame
+     163           3 :   my_input_data->getStoredData( 0, false ).transferDataToPDB( mypdb );
+     164           3 :   auto myconf0=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     165           3 :   MultiValue myval( 1, myconf0->getNumberOfReferenceArguments() + 3*myconf0->getNumberOfReferencePositions() + 9 );
+     166           3 :   ReferenceValuePack mypack( myconf0->getNumberOfReferenceArguments(), myconf0->getNumberOfReferencePositions(), myval );
+     167          25 :   for(unsigned i=0; i<myconf0->getNumberOfReferencePositions(); ++i) mypack.setAtomIndex( i, i );
+     168             :   // Setup some PCA storage
+     169           3 :   myconf0->setupPCAStorage ( mypack );
+     170           3 :   std::vector<double> displace( myconf0->getNumberOfReferencePositions() );
+     171           3 :   if( myconf0->getNumberOfReferencePositions()>0 ) {
+     172           1 :     ReferenceAtoms* at = dynamic_cast<ReferenceAtoms*>( myconf0.get() );
+     173           1 :     displace = at->getDisplace();
+     174             :   }
+     175             : 
+     176             :   // Create some arrays to store the average position
+     177           3 :   std::vector<double> sarg( myconf0->getNumberOfReferenceArguments(), 0 );
+     178           3 :   std::vector<Vector> spos( myconf0->getNumberOfReferencePositions() );
+     179          25 :   for(unsigned i=0; i<myconf0->getNumberOfReferencePositions(); ++i) spos[i].zero();
+     180             : 
+     181             :   // Calculate the average displacement from the first frame
+     182           3 :   double norm=getWeight(0); std::vector<double> args( getNumberOfArguments() );
+     183        1638 :   for(unsigned i=1; i<getNumberOfDataPoints(); ++i) {
+     184        1635 :     my_input_data->getStoredData( i, false ).transferDataToPDB( mypdb );
+     185        3815 :     for(unsigned j=0; j<getArguments().size(); ++j) mypdb.getArgumentValue( getArguments()[j]->getName(), args[j] );
+     186        1635 :     myconf0->calc( mypdb.getPositions(), getPbc(), getArguments(), args, mypack, true );
+     187             :     // Accumulate average displacement of arguments (Here PBC could do fucked up things - really needs Berry Phase ) GAT
+     188        3815 :     for(unsigned j=0; j<myconf0->getNumberOfReferenceArguments(); ++j) sarg[j] += 0.5*getWeight(i)*mypack.getArgumentDerivative(j);
+     189             :     // Accumulate average displacement of position
+     190       13625 :     for(unsigned j=0; j<myconf0->getNumberOfReferencePositions(); ++j) spos[j] += getWeight(i)*mypack.getAtomsDisplacementVector()[j] / displace[j];
+     191        1635 :     norm += getWeight(i);
+     192             :   }
+     193             :   // Now normalise the displacements to get the average and add these to the first frame
+     194           3 :   double inorm = 1.0 / norm ;
+     195           7 :   for(unsigned j=0; j<myconf0->getNumberOfReferenceArguments(); ++j) sarg[j] = inorm*sarg[j] + myconf0->getReferenceArguments()[j];
+     196          25 :   for(unsigned j=0; j<myconf0->getNumberOfReferencePositions(); ++j) spos[j] = inorm*spos[j] + myconf0->getReferencePositions()[j];
+     197             :   // Now accumulate the covariance
+     198           3 :   unsigned narg=myconf0->getNumberOfReferenceArguments(), natoms=myconf0->getNumberOfReferencePositions();
+     199           3 :   Matrix<double> covar( narg+3*natoms, narg+3*natoms ); covar=0;
+     200        1641 :   for(unsigned i=0; i<getNumberOfDataPoints(); ++i) {
+     201        1638 :     my_input_data->getStoredData( i, false ).transferDataToPDB( mypdb );
+     202        3822 :     for(unsigned j=0; j<getArguments().size(); ++j) mypdb.getArgumentValue( getArguments()[j]->getName(), args[j] );
+     203        1638 :     myconf0->calc( mypdb.getPositions(), getPbc(), getArguments(), args, mypack, true );
+     204        3822 :     for(unsigned jarg=0; jarg<narg; ++jarg) {
+     205             :       // Need sorting for PBC with GAT
+     206        2184 :       double jarg_d = 0.5*mypack.getArgumentDerivative(jarg) + myconf0->getReferenceArguments()[jarg] - sarg[jarg];
+     207        6552 :       for(unsigned karg=0; karg<narg; ++karg) {
+     208             :         // Need sorting for PBC with GAT
+     209        4368 :         double karg_d = 0.5*mypack.getArgumentDerivative(karg) + myconf0->getReferenceArguments()[karg] - sarg[karg];
+     210        4368 :         covar( jarg, karg ) += 0.25*getWeight(i)*jarg_d*karg_d; // mypack.getArgumentDerivative(jarg)*mypack.getArgumentDerivative(karg);
+     211             :       }
+     212             :     }
+     213       13650 :     for(unsigned jat=0; jat<natoms; ++jat) {
+     214       48048 :       for(unsigned jc=0; jc<3; ++jc) {
+     215       36036 :         double jdisplace = mypack.getAtomsDisplacementVector()[jat][jc] / displace[jat] + myconf0->getReferencePositions()[jat][jc] - spos[jat][jc];
+     216      828828 :         for(unsigned kat=0; kat<natoms; ++kat) {
+     217     3171168 :           for(unsigned kc=0; kc<3; ++kc) {
+     218     2378376 :             double kdisplace = mypack.getAtomsDisplacementVector()[kat][kc] /displace[kat] + myconf0->getReferencePositions()[kat][kc] - spos[kat][kc];
+     219     2378376 :             covar( narg+3*jat + jc, narg+3*kat + kc ) += getWeight(i)*jdisplace*kdisplace;
+     220             :           }
+     221             :         }
+     222             :       }
+     223             :     }
+     224             :   }
+     225             :   // Normalise
+     226          73 :   for(unsigned i=0; i<covar.nrows(); ++i) {
+     227        4434 :     for(unsigned j=0; j<covar.ncols(); ++j) covar(i,j) *= inorm;
+     228             :   }
+     229             : 
+     230             :   // Diagonalise the covariance
+     231           3 :   std::vector<double> eigval( narg+3*natoms );
+     232             :   Matrix<double> eigvec( narg+3*natoms, narg+3*natoms );
+     233           3 :   diagMat( covar, eigval, eigvec );
+     234             : 
+     235             :   // Output the reference configuration
+     236           3 :   mypdb.setAtomPositions( spos );
+     237           7 :   for(unsigned j=0; j<sarg.size(); ++j) mypdb.setArgumentValue( getArguments()[j]->getName(), sarg[j] );
+     238             :   // Reset the reference configuration
+     239           6 :   myref = metricRegister().create<ReferenceConfiguration>( mtype, mypdb );
+     240             : 
+     241             :   // Store and print the eigenvectors
+     242           3 :   std::vector<Vector> tmp_atoms( natoms );
+     243           9 :   for(unsigned dim=0; dim<nlow; ++dim) {
+     244           6 :     unsigned idim = covar.ncols() - 1 - dim;
+     245          14 :     for(unsigned i=0; i<narg; ++i) mypdb.setArgumentValue( getArguments()[i]->getName(), eigvec(idim,i) );
+     246          50 :     for(unsigned i=0; i<natoms; ++i) {
+     247         176 :       for(unsigned k=0; k<3; ++k) tmp_atoms[i][k]=eigvec(idim,narg+3*i+k);
+     248             :     }
+     249           6 :     mypdb.setAtomPositions( tmp_atoms );
+     250             :     // Create a direction object so that we can calculate other PCA components
+     251          12 :     directions.push_back( Direction(ReferenceConfigurationOptions("DIRECTION")));
+     252           6 :     directions[dim].read( mypdb );
+     253             :   }
+     254           3 : }
+     255             : 
+     256           0 : void PCA::getProjection( const unsigned& idata, std::vector<double>& point, double& weight ) {
+     257           0 :   if( point.size()!=nlow ) point.resize( nlow );
+     258             :   // Retrieve the weight
+     259           0 :   weight = getWeight(idata);
+     260             :   // Retrieve the data point
+     261           0 :   getProjection( my_input_data->getStoredData( idata, false ), point );
+     262           0 : }
+     263             : 
+     264         546 : void PCA::getProjection( analysis::DataCollectionObject& myidata, std::vector<double>& point ) {
+     265         546 :   myidata.transferDataToPDB( mypdb ); std::vector<double> args( getArguments().size() );
+     266        1638 :   for(unsigned j=0; j<getArguments().size(); ++j) mypdb.getArgumentValue( getArguments()[j]->getName(), args[j] );
+     267             :   // Create some storage space
+     268         546 :   MultiValue myval( 1, 3*mypdb.getPositions().size() + args.size() + 9);
+     269         546 :   ReferenceValuePack mypack( args.size(), mypdb.getPositions().size(), myval );
+     270         546 :   for(unsigned i=0; i<mypdb.getPositions().size(); ++i) mypack.setAtomIndex( i, i );
+     271         546 :   myref->setupPCAStorage( mypack );
+     272             :   // And calculate
+     273         546 :   myref->calculate( mypdb.getPositions(), getPbc(), getArguments(), mypack, true );
+     274        1638 :   for(unsigned i=0; i<nlow; ++i) point[i]=myref->projectDisplacementOnVector( directions[i], getArguments(), args, mypack );
+     275        1092 : }
+     276             : 
+     277             : }
+     278             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.h.func-sort-c.html b/coverage/dimred/PCA.h.func-sort-c.html new file mode 100644 index 000000000000..809709890fbe --- /dev/null +++ b/coverage/dimred/PCA.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - dimred/PCA.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - PCA.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:030.0 %
Date:2024-02-22 21:58:45Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred3PCA15calculateStressERKSt6vectorIdSaIdEERS4_0
_ZN4PLMD6dimred3PCA17setTargetDistanceERKjRKd0
_ZN4PLMD6dimred3PCA20calculateProjectionsERKNS_6MatrixIdEERS3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.h.func.html b/coverage/dimred/PCA.h.func.html new file mode 100644 index 000000000000..d8c3296c30d1 --- /dev/null +++ b/coverage/dimred/PCA.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - dimred/PCA.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - PCA.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:030.0 %
Date:2024-02-22 21:58:45Functions:030.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred3PCA15calculateStressERKSt6vectorIdSaIdEERS4_0
_ZN4PLMD6dimred3PCA17setTargetDistanceERKjRKd0
_ZN4PLMD6dimred3PCA20calculateProjectionsERKNS_6MatrixIdEERS3_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/PCA.h.gcov.html b/coverage/dimred/PCA.h.gcov.html new file mode 100644 index 000000000000..993d6b1dbb36 --- /dev/null +++ b/coverage/dimred/PCA.h.gcov.html @@ -0,0 +1,135 @@ + + + + + + + + LCOV - plumed test coverage - dimred/PCA.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - PCA.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:030.0 %
Date:2024-02-22 21:58:45Functions:030.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_dimred_PCA_h
+      23             : #define __PLUMED_dimred_PCA_h
+      24             : 
+      25             : #include "DimensionalityReductionBase.h"
+      26             : #include "reference/ReferenceConfiguration.h"
+      27             : #include "reference/Direction.h"
+      28             : #include "tools/PDB.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace dimred {
+      32             : 
+      33             : class PCA : public DimensionalityReductionBase {
+      34             :   friend class OutputPCAProjection;
+      35             : private:
+      36             : /// The way we are measuring distances
+      37             :   std::string mtype;
+      38             : /// The position of the reference configuration (the one we align to)
+      39             :   PDB mypdb;
+      40             : /// The eigenvectors for the displacements in argument space
+      41             :   std::string ofilename, fmt;
+      42             : /// The eigenvectors that we are using
+      43             :   std::unique_ptr<ReferenceConfiguration> myref;
+      44             :   std::vector<Direction> directions;
+      45             : public:
+      46             :   static void registerKeywords( Keywords& keys );
+      47             :   explicit PCA(const ActionOptions&ao);
+      48             :   void performAnalysis() override;
+      49             :   void getProjection( const unsigned& idata, std::vector<double>& point, double& weight ) override;
+      50             :   void getProjection( analysis::DataCollectionObject& myidata, std::vector<double>& point );
+      51           0 :   void calculateProjections( const Matrix<double>&, Matrix<double>& ) override { plumed_error(); }
+      52           0 :   void setTargetDistance( const unsigned&, const double& ) override { plumed_error(); }
+      53           0 :   double calculateStress( const std::vector<double>& pp, std::vector<double>& der ) override { plumed_error(); }
+      54             : };
+      55             : 
+      56             : }
+      57             : }
+      58             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ProjectNonLandmarkPoints.cpp.func-sort-c.html b/coverage/dimred/ProjectNonLandmarkPoints.cpp.func-sort-c.html new file mode 100644 index 000000000000..3a6dbf31f29d --- /dev/null +++ b/coverage/dimred/ProjectNonLandmarkPoints.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ProjectNonLandmarkPoints.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ProjectNonLandmarkPoints.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384290.5 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15getArgumentListEv0
_ZN4PLMD6dimred24ProjectNonLandmarkPointsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred24ProjectNonLandmarkPoints11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15performAnalysisEv2
_ZN4PLMD6dimred24ProjectNonLandmarkPointsC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred24ProjectNonLandmarkPoints16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred24ProjectNonLandmarkPoints13getStoredDataERKjRKb1046
_ZN4PLMD6dimred24ProjectNonLandmarkPoints18generateProjectionERKjRSt6vectorIdSaIdEE1046
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15calculateStressERKSt6vectorIdSaIdEERS4_16744
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ProjectNonLandmarkPoints.cpp.func.html b/coverage/dimred/ProjectNonLandmarkPoints.cpp.func.html new file mode 100644 index 000000000000..5d9c05cc6760 --- /dev/null +++ b/coverage/dimred/ProjectNonLandmarkPoints.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ProjectNonLandmarkPoints.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ProjectNonLandmarkPoints.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384290.5 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred24ProjectNonLandmarkPoints13getStoredDataERKjRKb1046
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15calculateStressERKSt6vectorIdSaIdEERS4_16744
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15getArgumentListEv0
_ZN4PLMD6dimred24ProjectNonLandmarkPoints15performAnalysisEv2
_ZN4PLMD6dimred24ProjectNonLandmarkPoints16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD6dimred24ProjectNonLandmarkPoints18generateProjectionERKjRSt6vectorIdSaIdEE1046
_ZN4PLMD6dimred24ProjectNonLandmarkPointsC1ERKNS_13ActionOptionsE2
_ZN4PLMD6dimred24ProjectNonLandmarkPointsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred24ProjectNonLandmarkPoints11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/ProjectNonLandmarkPoints.cpp.gcov.html b/coverage/dimred/ProjectNonLandmarkPoints.cpp.gcov.html new file mode 100644 index 000000000000..e945c80bc097 --- /dev/null +++ b/coverage/dimred/ProjectNonLandmarkPoints.cpp.gcov.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage - dimred/ProjectNonLandmarkPoints.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - ProjectNonLandmarkPoints.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384290.5 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "tools/Random.h"
+      26             : #include "tools/ConjugateGradient.h"
+      27             : #include "analysis/AnalysisBase.h"
+      28             : #include "reference/ReferenceConfiguration.h"
+      29             : #include "DimensionalityReductionBase.h"
+      30             : #include "PCA.h"
+      31             : 
+      32             : //+PLUMEDOC DIMRED PROJECT_ALL_ANALYSIS_DATA
+      33             : /*
+      34             : Find projections of all non-landmark points using the embedding calculated by a dimensionality reduction optimization calculation.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : */
+      39             : //+ENDPLUMEDOC
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace dimred {
+      43             : 
+      44             : class ProjectNonLandmarkPoints : public analysis::AnalysisBase {
+      45             : private:
+      46             : /// Tolerance for conjugate gradient algorithm
+      47             :   double cgtol;
+      48             : /// Number of diemsions in low dimensional space
+      49             :   unsigned nlow;
+      50             : /// The class that calculates the projection of the data that is required
+      51             :   DimensionalityReductionBase* mybase;
+      52             : /// Generate a projection of the ith data point - this is called in two routine
+      53             :   void generateProjection( const unsigned& idat, std::vector<double>& point );
+      54             : public:
+      55             :   static void registerKeywords( Keywords& keys );
+      56             :   explicit ProjectNonLandmarkPoints( const ActionOptions& ao );
+      57             : /// Get a reference configuration (this returns the projection)
+      58             :   analysis::DataCollectionObject& getStoredData( const unsigned& idat, const bool& calcdist );
+      59             : /// Overwrite getArguments so we get arguments from underlying class
+      60             :   std::vector<Value*> getArgumentList();
+      61             : /// This does nothing -- projections are calculated when getDataPoint and getReferenceConfiguration are called
+      62           2 :   void performAnalysis() {}
+      63             : /// This just calls calculate stress in the underlying projection object
+      64             :   double calculateStress( const std::vector<double>& pp, std::vector<double>& der );
+      65             : /// Overwrite virtual function in ActionWithVessel
+      66           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const { plumed_error(); }
+      67             : };
+      68             : 
+      69             : PLUMED_REGISTER_ACTION(ProjectNonLandmarkPoints,"PROJECT_ALL_ANALYSIS_DATA")
+      70             : 
+      71           4 : void ProjectNonLandmarkPoints::registerKeywords( Keywords& keys ) {
+      72           4 :   analysis::AnalysisBase::registerKeywords( keys );
+      73           8 :   keys.add("compulsory","PROJECTION","the projection that you wish to generate out-of-sample projections with");
+      74           8 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient optimization");
+      75           8 :   keys.addOutputComponent("coord","default","the low-dimensional projections of the various input configurations");
+      76           4 : }
+      77             : 
+      78           2 : ProjectNonLandmarkPoints::ProjectNonLandmarkPoints( const ActionOptions& ao ):
+      79             :   Action(ao),
+      80             :   analysis::AnalysisBase(ao),
+      81           2 :   mybase(NULL)
+      82             : {
+      83           2 :   std::string myproj; parse("PROJECTION",myproj);
+      84           2 :   mybase = plumed.getActionSet().selectWithLabel<DimensionalityReductionBase*>( myproj );
+      85           2 :   if( !mybase ) error("could not find projection of data named " + myproj );
+      86             :   // Add the dependency and set the dimensionality
+      87           2 :   addDependency( mybase ); nlow = mybase->nlow;
+      88             :   // Add fake components to the underlying ActionWithValue for the arguments
+      89             :   std::string num;
+      90           6 :   for(unsigned i=0; i<nlow; ++i) {
+      91          12 :     Tools::convert(i+1,num); addComponent( "coord-" + num ); componentIsNotPeriodic( "coord-" + num );
+      92             :   }
+      93             : 
+      94           2 :   log.printf("  generating out-of-sample projections using projection with label %s \n",myproj.c_str() );
+      95           4 :   parse("CGTOL",cgtol);
+      96           2 : }
+      97             : 
+      98           0 : std::vector<Value*> ProjectNonLandmarkPoints::getArgumentList() {
+      99             :   std::vector<Value*> arglist( analysis::AnalysisBase::getArgumentList() );
+     100           0 :   for(unsigned i=0; i<nlow; ++i) arglist.push_back( getPntrToComponent(i) );
+     101           0 :   return arglist;
+     102             : }
+     103             : 
+     104        1046 : void ProjectNonLandmarkPoints::generateProjection( const unsigned& idat, std::vector<double>& point ) {
+     105        1046 :   PCA* ispca = dynamic_cast<PCA*>( mybase );
+     106        1046 :   if( ispca ) {
+     107         546 :     ispca->getProjection( my_input_data->getStoredData(idat,false), point );
+     108             :   } else {
+     109             :     ConjugateGradient<ProjectNonLandmarkPoints> myminimiser( this );
+     110         500 :     unsigned closest=0; double mindist = std::sqrt( getDissimilarity( mybase->getDataPointIndexInBase(0), idat ) );
+     111         500 :     mybase->setTargetDistance( 0, mindist );
+     112      125000 :     for(unsigned i=1; i<mybase->getNumberOfDataPoints(); ++i) {
+     113      124500 :       double dist = std::sqrt( getDissimilarity( mybase->getDataPointIndexInBase(i), idat ) );
+     114      124500 :       mybase->setTargetDistance( i, dist );
+     115      124500 :       if( dist<mindist ) { mindist=dist; closest=i; }
+     116             :     }
+     117             :     // Put the initial guess near to the closest landmark  -- may wish to use grid here again Sandip??
+     118         500 :     Random random; random.setSeed(-1234);
+     119        1500 :     for(unsigned j=0; j<nlow; ++j) point[j]=mybase->projections(closest,j) + (random.RandU01() - 0.5)*0.01;
+     120         500 :     myminimiser.minimise( cgtol, point, &ProjectNonLandmarkPoints::calculateStress );
+     121             :   }
+     122        1046 : }
+     123             : 
+     124        1046 : analysis::DataCollectionObject& ProjectNonLandmarkPoints::getStoredData( const unsigned& idat, const bool& calcdist ) {
+     125        1046 :   std::vector<double> pp(nlow); generateProjection( idat, pp ); std::string num;
+     126             :   analysis::DataCollectionObject& myref=AnalysisBase::getStoredData(idat,calcdist);
+     127        3138 :   for(unsigned i=0; i<nlow; ++i) { Tools::convert(i+1,num); myref.setArgument( getLabel() + ".coord-" + num, pp[i] ); }
+     128        1046 :   return myref;
+     129             : }
+     130             : 
+     131       16744 : double ProjectNonLandmarkPoints::calculateStress( const std::vector<double>& pp, std::vector<double>& der ) {
+     132       16744 :   return mybase->calculateStress( pp, der );
+     133             : }
+     134             : 
+     135             : }
+     136             : }
+     137             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SMACOF.cpp.func-sort-c.html b/coverage/dimred/SMACOF.cpp.func-sort-c.html new file mode 100644 index 000000000000..4ba909b52313 --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SMACOF.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SMACOF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:323397.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred6SMACOF3runERKNS_6MatrixIdEES5_RKdRKjRS3_1
_ZN4PLMD6dimred6SMACOF14calculateSigmaERKNS_6MatrixIdEES5_S5_RS3_15
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SMACOF.cpp.func.html b/coverage/dimred/SMACOF.cpp.func.html new file mode 100644 index 000000000000..bf0ae302b8d9 --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SMACOF.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SMACOF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:323397.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred6SMACOF14calculateSigmaERKNS_6MatrixIdEES5_S5_RS3_15
_ZN4PLMD6dimred6SMACOF3runERKNS_6MatrixIdEES5_RKdRKjRS3_1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SMACOF.cpp.gcov.html b/coverage/dimred/SMACOF.cpp.gcov.html new file mode 100644 index 000000000000..83f39328371f --- /dev/null +++ b/coverage/dimred/SMACOF.cpp.gcov.html @@ -0,0 +1,170 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SMACOF.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SMACOF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:323397.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "SMACOF.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace dimred {
+      26             : 
+      27           1 : void SMACOF::run( const Matrix<double>& Weights, const Matrix<double>& Distances, const double& tol, const unsigned& maxloops, Matrix<double>& InitialZ ) {
+      28             :   unsigned M = Distances.nrows();
+      29             : 
+      30             :   // Calculate V
+      31             :   Matrix<double> V(M,M); double totalWeight=0.;
+      32         501 :   for(unsigned i=0; i<M; ++i) {
+      33      250500 :     for(unsigned j=0; j<M; ++j) {
+      34      250000 :       if(i==j) continue;
+      35      249500 :       V(i,j)=-Weights(i,j);
+      36      249500 :       if( j<i ) totalWeight+=Weights(i,j);
+      37             :     }
+      38      250500 :     for(unsigned j=0; j<M; ++j) {
+      39      250000 :       if(i==j)continue;
+      40      249500 :       V(i,i)-=V(i,j);
+      41             :     }
+      42             :   }
+      43             : 
+      44             :   // And pseudo invert V
+      45           1 :   Matrix<double> mypseudo(M, M); pseudoInvert(V, mypseudo);
+      46           1 :   Matrix<double> dists( M, M ); double myfirstsig = calculateSigma( Weights, Distances, InitialZ, dists ) / totalWeight;
+      47             : 
+      48             :   // initial sigma is made up of the original distances minus the distances between the projections all squared.
+      49             :   Matrix<double> temp( M, M ), BZ( M, M ), newZ( M, InitialZ.ncols() );
+      50          14 :   for(unsigned n=0; n<maxloops; ++n) {
+      51          14 :     if(n==maxloops-1) plumed_merror("ran out of steps in SMACOF algorithm");
+      52             : 
+      53             :     // Recompute BZ matrix
+      54        7014 :     for(unsigned i=0; i<M; ++i) {
+      55     3507000 :       for(unsigned j=0; j<M; ++j) {
+      56     3500000 :         if(i==j) continue;  //skips over the diagonal elements
+      57             : 
+      58     3493000 :         if( dists(i,j)>0 ) BZ(i,j) = -Weights(i,j)*Distances(i,j) / dists(i,j);
+      59           0 :         else BZ(i,j)=0.;
+      60             :       }
+      61             :       //the diagonal elements are -off diagonal elements BZ(i,i)-=BZ(i,j)   (Equation 8.25)
+      62        7000 :       BZ(i,i)=0; //create the space memory for the diagonal elements which are scalars
+      63     3507000 :       for(unsigned j=0; j<M; ++j) {
+      64     3500000 :         if(i==j) continue;
+      65     3493000 :         BZ(i,i)-=BZ(i,j);
+      66             :       }
+      67             :     }
+      68             : 
+      69          14 :     mult( mypseudo, BZ, temp); mult(temp, InitialZ, newZ);
+      70             :     //Compute new sigma
+      71          14 :     double newsig = calculateSigma( Weights, Distances, newZ, dists ) / totalWeight;
+      72             :     //Computing whether the algorithm has converged (has the mass of the potato changed
+      73             :     //when we put it back in the oven!)
+      74          14 :     if( std::fabs( newsig - myfirstsig )<tol ) break;
+      75             :     myfirstsig=newsig;
+      76             :     InitialZ = newZ;
+      77             :   }
+      78           1 : }
+      79             : 
+      80          15 : double SMACOF::calculateSigma( const Matrix<double>& Weights, const Matrix<double>& Distances, const Matrix<double>& InitialZ, Matrix<double>& dists ) {
+      81             :   unsigned M = Distances.nrows(); double sigma=0;
+      82        7500 :   for(unsigned i=1; i<M; ++i) {
+      83     1878735 :     for(unsigned j=0; j<i; ++j) {
+      84     5613750 :       double dlow=0; for(unsigned k=0; k<InitialZ.ncols(); ++k) { double tmp=InitialZ(i,k) - InitialZ(j,k); dlow+=tmp*tmp; }
+      85     1871250 :       dists(i,j)=dists(j,i)=std::sqrt(dlow); double tmp3 = Distances(i,j) - dists(i,j);
+      86     1871250 :       sigma += Weights(i,j)*tmp3*tmp3;
+      87             :     }
+      88             :   }
+      89          15 :   return sigma;
+      90             : }
+      91             : 
+      92             : }
+      93             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMap.cpp.func-sort-c.html b/coverage/dimred/SketchMap.cpp.func-sort-c.html new file mode 100644 index 000000000000..0e710e6513e8 --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:144729.8 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred9SketchMapC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMap16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMap.cpp.func.html b/coverage/dimred/SketchMap.cpp.func.html new file mode 100644 index 000000000000..e85b9b5d3905 --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:144729.8 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred9SketchMap16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6dimred9SketchMapC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SketchMapC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMap.cpp.gcov.html b/coverage/dimred/SketchMap.cpp.gcov.html new file mode 100644 index 000000000000..538f48fe5639 --- /dev/null +++ b/coverage/dimred/SketchMap.cpp.gcov.html @@ -0,0 +1,182 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMap.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:144729.8 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionShortcut.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace dimred {
+      27             : 
+      28             : //+PLUMEDOC DIMRED SKETCH_MAP
+      29             : /*
+      30             : This can be used to output the data that has been stored in an Analysis object.
+      31             : 
+      32             : \par Examples
+      33             : 
+      34             : */
+      35             : //+ENDPLUMEDOC
+      36             : 
+      37             : class SketchMap : public ActionShortcut {
+      38             : public:
+      39             :   static void registerKeywords( Keywords& keys );
+      40             :   explicit SketchMap( const ActionOptions& );
+      41             : };
+      42             : 
+      43             : PLUMED_REGISTER_ACTION(SketchMap,"SKETCH_MAP")
+      44             : 
+      45           2 : void SketchMap::registerKeywords( Keywords& keys ) {
+      46           2 :   ActionShortcut::registerKeywords( keys );
+      47           4 :   keys.add("compulsory","NLOW_DIM","the dimension of the low dimensional space in which the projections will be constructed");
+      48           4 :   keys.add("compulsory","MATRIX","the matrix of distances between points that you want to reproduce in your sketch-map projection");
+      49           4 :   keys.add("compulsory","HIGH_DIM_FUNCTION","the parameters of the switching function in the high dimensional space");
+      50           4 :   keys.add("compulsory","LOW_DIM_FUNCTION","the parameters of the switching function in the low dimensional space");
+      51           4 :   keys.add("compulsory","ANNEAL_RATE","0.5","the rate at which to do the annealing");
+      52           4 :   keys.add("compulsory","ANNEAL_STEPS","10","the number of steps of annealing to do");
+      53           4 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      54             : // Smap pointwise input
+      55           4 :   keys.add("compulsory","NCYCLES","5","the number of cycles of global optimization to attempt");
+      56           4 :   keys.add("compulsory","BUFFER","1.1","grid extent for search is (max projection - minimum projection) multiplied by this value");
+      57           4 :   keys.add("compulsory","CGRID_SIZE","10","number of points to use in each grid direction");
+      58           4 :   keys.add("compulsory","FGRID_SIZE","0","interpolate the grid onto this number of points -- only works in 2D");
+      59           2 : }
+      60             : 
+      61           0 : SketchMap::SketchMap( const ActionOptions& ao ) :
+      62             :   Action(ao),
+      63           0 :   ActionShortcut(ao)
+      64             : {
+      65             :   // Input for MDS
+      66           0 :   std::string mds_line = getShortcutLabel() + "_mds: CLASSICAL_MDS";
+      67           0 :   std::string nlow; parse("NLOW_DIM",nlow); mds_line += " NLOW_DIM=" + nlow;
+      68           0 :   std::string mat; parse("MATRIX",mat); mds_line += " USE_OUTPUT_DATA_FROM=" + mat;
+      69           0 :   readInputLine( mds_line );
+      70             :   // Create generic input for all conjgrad cycles
+      71           0 :   std::string cgtol; parse("CGTOL",cgtol); std::string ncyc; parse("NCYCLES",ncyc); std::string buf; parse("BUFFER",buf);
+      72           0 :   std::string cg_grid; parse("CGRID_SIZE",cg_grid); std::string fg_grid; parse("FGRID_SIZE",fg_grid);
+      73           0 :   std::string cg_step_input = " CGTOL=" + cgtol; unsigned nlow_dim; Tools::convert( nlow, nlow_dim );
+      74           0 :   std::string pw_step_input = cg_step_input + " NCYCLES=" + ncyc + " BUFFER=" + buf;
+      75           0 :   pw_step_input += " CGRID_SIZE=" + cg_grid; for(unsigned i=1; i<nlow_dim; ++i) pw_step_input += "," + cg_grid;
+      76           0 :   pw_step_input += " FGRID_SIZE=" + fg_grid; for(unsigned i=1; i<nlow_dim; ++i) pw_step_input += "," + fg_grid;
+      77             :   // Input for iterative distance matching
+      78           0 :   std::string imds_line_cg = getShortcutLabel() + "_smap1_cg: SKETCHMAP_CONJGRAD USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_mds";
+      79           0 :   std::string hd_func; parse("HIGH_DIM_FUNCTION",hd_func); imds_line_cg += " HIGH_DIM_FUNCTION={" + hd_func + "}";
+      80           0 :   std::string ld_func; parse("LOW_DIM_FUNCTION",ld_func); imds_line_cg += " LOW_DIM_FUNCTION={" + ld_func + "}";
+      81           0 :   imds_line_cg += cg_step_input + " MIXPARAM=1.0"; readInputLine( imds_line_cg );
+      82           0 :   std::string imds_line_pw = getShortcutLabel() + "_smap1_pw: SKETCHMAP_POINTWISE USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_smap1_cg";
+      83           0 :   imds_line_pw += pw_step_input + " MIXPARAM=1.0"; readInputLine( imds_line_pw );
+      84             :   // Now sketch-map
+      85           0 :   unsigned asteps; parse("ANNEAL_STEPS",asteps); std::string psmap = getShortcutLabel() + "_smap1_pw";
+      86           0 :   if( asteps>1 ) {
+      87           0 :     double smear; parse("ANNEAL_RATE", smear); double old_mix = 1.0; double new_mix = old_mix*smear;
+      88           0 :     for(unsigned i=0; i<asteps; ++i) {
+      89           0 :       std::string omix; Tools::convert( old_mix, omix ); std::string nmix; Tools::convert( new_mix, nmix );
+      90           0 :       imds_line_cg = getShortcutLabel() + "_smap" + nmix + "_cg: SKETCHMAP_CONJGRAD USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_smap" + omix + "_pw";
+      91           0 :       imds_line_cg += cg_step_input + " MIXPARAM=" + nmix; readInputLine( imds_line_cg );
+      92           0 :       imds_line_pw = getShortcutLabel() + "_smap" + nmix + "_pw: SKETCHMAP_POINTWISE USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_smap" + omix + "_cg";
+      93           0 :       imds_line_pw += pw_step_input + " MIXPARAM=" + nmix; readInputLine( imds_line_pw );
+      94           0 :       old_mix = new_mix; new_mix = old_mix*smear; psmap = getShortcutLabel() + "_smap" + nmix + "_pw";
+      95             :     }
+      96             :   }
+      97             :   // Final sketch-map with no mixing of distance matching
+      98           0 :   imds_line_cg = getShortcutLabel() + "_smap_cg: SKETCHMAP_CONJGRAD USE_OUTPUT_DATA_FROM=" + psmap + cg_step_input;
+      99           0 :   readInputLine( imds_line_cg );
+     100           0 :   imds_line_pw = getShortcutLabel() + ": SKETCHMAP_POINTWISE USE_OUTPUT_DATA_FROM=" + getShortcutLabel() + "_smap_cg" + pw_step_input;
+     101           0 :   readInputLine( imds_line_pw );
+     102           0 : }
+     103             : 
+     104             : }
+     105             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.cpp.func-sort-c.html b/coverage/dimred/SketchMapBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..b7f416594a78 --- /dev/null +++ b/coverage/dimred/SketchMapBase.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7979100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred13SketchMapBaseC2ERKNS_13ActionOptionsE6
_ZN4PLMD6dimred13SketchMapBase20calculateProjectionsERKNS_6MatrixIdEERS3_7
_ZN4PLMD6dimred13SketchMapBase16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6dimred13SketchMapBase19calculateFullStressERKSt6vectorIdSaIdEERS4_1913
_ZN4PLMD6dimred13SketchMapBase15calculateStressERKSt6vectorIdSaIdEERS4_41344
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.cpp.func.html b/coverage/dimred/SketchMapBase.cpp.func.html new file mode 100644 index 000000000000..01a96abf7bb8 --- /dev/null +++ b/coverage/dimred/SketchMapBase.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7979100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBase15calculateStressERKSt6vectorIdSaIdEERS4_41344
_ZN4PLMD6dimred13SketchMapBase16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD6dimred13SketchMapBase19calculateFullStressERKSt6vectorIdSaIdEERS4_1913
_ZN4PLMD6dimred13SketchMapBase20calculateProjectionsERKNS_6MatrixIdEERS3_7
_ZN4PLMD6dimred13SketchMapBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred13SketchMapBaseC2ERKNS_13ActionOptionsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.cpp.gcov.html b/coverage/dimred/SketchMapBase.cpp.gcov.html new file mode 100644 index 000000000000..24cd8fc0a626 --- /dev/null +++ b/coverage/dimred/SketchMapBase.cpp.gcov.html @@ -0,0 +1,243 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7979100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "SketchMapBase.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace dimred {
+      26             : 
+      27          14 : void SketchMapBase::registerKeywords( Keywords& keys ) {
+      28          14 :   DimensionalityReductionBase::registerKeywords( keys );
+      29          14 :   keys.remove("NLOW_DIM");
+      30          28 :   keys.add("compulsory","HIGH_DIM_FUNCTION","as in input action","the parameters of the switching function in the high dimensional space");
+      31          28 :   keys.add("compulsory","LOW_DIM_FUNCTION","as in input action","the parameters of the switching function in the low dimensional space");
+      32          28 :   keys.add("compulsory","MIXPARAM","0.0","the amount of the pure distances to mix into the stress function");
+      33          14 : }
+      34             : 
+      35           6 : SketchMapBase::SketchMapBase( const ActionOptions& ao ):
+      36             :   Action(ao),
+      37             :   DimensionalityReductionBase(ao),
+      38           6 :   smapbase(NULL),
+      39           6 :   normw(0.0)
+      40             : {
+      41             :   // Check if we have data from a input sketch-map object - we can reuse switching functions wahoo!!
+      42           6 :   if( dimredbase ) smapbase = dynamic_cast<SketchMapBase*>( dimredbase );
+      43             : 
+      44             :   // Read in the switching functions
+      45             :   std::string linput,hinput, errors;
+      46          12 :   parse("HIGH_DIM_FUNCTION",hinput);
+      47           6 :   if( hinput=="as in input action" ) {
+      48           1 :     if( !smapbase ) error("high dimensional switching function has not been set - use HIGH_DIM_FUNCTION");
+      49           1 :     reuse_hd=true;
+      50           1 :     log.printf("  reusing high dimensional filter function defined in previous sketch-map action\n");
+      51             :   } else {
+      52           5 :     reuse_hd=false;
+      53           5 :     highdf.set(hinput,errors);
+      54           5 :     if(errors.length()>0) error(errors);
+      55          10 :     log.printf("  filter function for dissimilarities in high dimensional space has cutoff %s \n",highdf.description().c_str() );
+      56             :   }
+      57             : 
+      58          12 :   parse("LOW_DIM_FUNCTION",linput);
+      59           6 :   if( linput=="as in input action" ) {
+      60           1 :     if( !smapbase ) error("low dimensional switching function has not been set - use LOW_DIM_FUNCTION");
+      61           1 :     reuse_ld=true;
+      62           1 :     log.printf("  reusing low dimensional filter function defined in previous sketch-map action\n");
+      63             :   } else {
+      64           5 :     reuse_ld=false;
+      65           5 :     lowdf.set(linput,errors);
+      66           5 :     if(errors.length()>0) error(errors);
+      67          10 :     log.printf("  filter function for distances in low dimensionality space has cutoff %s \n",lowdf.description().c_str() );
+      68             :   }
+      69             : 
+      70             :   // Read the mixing parameter
+      71           6 :   parse("MIXPARAM",mixparam);
+      72           6 :   if( mixparam<0 || mixparam>1 ) error("mixing parameter must be between 0 and 1");
+      73           6 :   log.printf("  mixing %f of pure distances with %f of filtered distances \n",mixparam,1.-mixparam);
+      74           6 : }
+      75             : 
+      76           7 : void SketchMapBase::calculateProjections( const Matrix<double>& targets, Matrix<double>& projections ) {
+      77           7 :   if( dtargets.size()!=targets.nrows() ) {
+      78             :     // These hold data so that we can do stress calculations
+      79           6 :     dtargets.resize( targets.nrows() ); ftargets.resize( targets.nrows() ); pweights.resize( targets.nrows() );
+      80             :     // Matrices for storing input data
+      81             :     transformed.resize( targets.nrows(), targets.ncols() );
+      82             :     distances.resize( targets.nrows(), targets.ncols() );
+      83             :   }
+      84             : 
+      85             :   // Stores the weights in an array for faster access, as well as the normalization
+      86           7 :   normw=0;
+      87        1141 :   for(unsigned i=0; i<targets.nrows() ; ++i) { pweights[i] = getWeight(i); normw+=pweights[i]; }
+      88           7 :   normw*=normw;
+      89             : 
+      90             :   // Transform the high dimensional distances
+      91             :   double df; distances=0.; transformed=0.;
+      92        1134 :   for(unsigned i=1; i<distances.ncols(); ++i) {
+      93      172838 :     for(unsigned j=0; j<i; ++j) {
+      94      171711 :       distances(i,j)=distances(j,i)=std::sqrt( targets(i,j) );
+      95      171711 :       transformed(i,j)=transformed(j,i)=transformHighDimensionalDistance( distances(i,j), df );
+      96             :     }
+      97             :   }
+      98             :   // And minimse
+      99           7 :   minimise( projections );
+     100           7 : }
+     101             : 
+     102       41344 : double SketchMapBase::calculateStress( const std::vector<double>& p, std::vector<double>& d ) {
+     103             :   // Zero derivative and stress accumulators
+     104      124032 :   for(unsigned i=0; i<p.size(); ++i) d[i]=0.0;
+     105       41344 :   double stress=0; std::vector<double> dtmp( p.size() );
+     106             :   // Now accumulate total stress on system
+     107     6687344 :   for(unsigned i=0; i<ftargets.size(); ++i) {
+     108     6646000 :     if( dtargets[i]<epsilon ) continue ;
+     109             : 
+     110             :     // Calculate distance in low dimensional space
+     111     6615785 :     double dd=0;
+     112    19847355 :     for(unsigned j=0; j<p.size(); ++j) { dtmp[j]=p[j]-projections(i,j); dd+=dtmp[j]*dtmp[j]; }
+     113     6615785 :     dd = std::sqrt(dd);
+     114             : 
+     115             :     // Now do transformations and calculate differences
+     116     6615785 :     double df, fd = transformLowDimensionalDistance( dd, df );
+     117     6615785 :     double ddiff = dd - dtargets[i];
+     118     6615785 :     double fdiff = fd - ftargets[i];
+     119             : 
+     120             :     // Calculate derivatives
+     121     6615785 :     double pref = 2.*getWeight(i) / dd ;
+     122    19847355 :     for(unsigned j=0; j<p.size(); ++j) d[j] += pref*( (1-mixparam)*fdiff*df + mixparam*ddiff )*dtmp[j];
+     123             : 
+     124             :     // Accumulate the total stress
+     125     6615785 :     stress += getWeight(i)*( (1-mixparam)*fdiff*fdiff + mixparam*ddiff*ddiff );
+     126             :   }
+     127       41344 :   return stress;
+     128             : }
+     129             : 
+     130        1913 : double SketchMapBase::calculateFullStress( const std::vector<double>& p, std::vector<double>& d ) {
+     131             :   // Zero derivative and stress accumulators
+     132      393213 :   for(unsigned i=0; i<p.size(); ++i) d[i]=0.0;
+     133        1913 :   double stress=0; std::vector<double> dtmp( nlow );
+     134             : 
+     135      195650 :   for(unsigned i=1; i<distances.nrows(); ++i) {
+     136      193737 :     double iweight = pweights[i];
+     137    14802162 :     for(unsigned j=0; j<i; ++j) {
+     138    14608425 :       double jweight =  pweights[j];
+     139             :       // Calculate distance in low dimensional space
+     140    14608425 :       double dd=0;
+     141    43825275 :       for(unsigned k=0; k<nlow; ++k) { dtmp[k]=p[nlow*i+k] - p[nlow*j+k]; dd+=dtmp[k]*dtmp[k]; }
+     142    14608425 :       dd = std::sqrt(dd);
+     143             : 
+     144             :       // Now do transformations and calculate differences
+     145    14608425 :       double df, fd = transformLowDimensionalDistance( dd, df );
+     146    14608425 :       double ddiff = dd - distances(i,j);
+     147    14608425 :       double fdiff = fd - transformed(i,j);;
+     148             : 
+     149             :       // Calculate derivatives
+     150    14608425 :       double pref = 2.*iweight*jweight*( (1-mixparam)*fdiff*df + mixparam*ddiff ) / dd;
+     151    43825275 :       for(unsigned k=0; k<nlow; ++k) {
+     152    29216850 :         double dterm=pref*dtmp[k]; d[nlow*i+k]+=dterm; d[nlow*j+k]-=dterm;
+     153             :       }
+     154             : 
+     155             :       // Accumulate the total stress
+     156    14608425 :       stress += iweight*jweight*( (1-mixparam)*fdiff*fdiff + mixparam*ddiff*ddiff );
+     157             :     }
+     158             :   }
+     159      393213 :   stress /= normw; for (unsigned k=0; k < d.size(); ++k) d[k] /= normw;
+     160        1913 :   return stress;
+     161             : }
+     162             : 
+     163             : }
+     164             : }
+     165             : 
+     166             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.h.func-sort-c.html b/coverage/dimred/SketchMapBase.h.func-sort-c.html new file mode 100644 index 000000000000..5f6d8bef5d35 --- /dev/null +++ b/coverage/dimred/SketchMapBase.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBase17setTargetDistanceERKjRKd145000
_ZNK4PLMD6dimred13SketchMapBase32transformHighDimensionalDistanceERKdRd341661
_ZNK4PLMD6dimred13SketchMapBase31transformLowDimensionalDistanceERKdRd26384110
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.h.func.html b/coverage/dimred/SketchMapBase.h.func.html new file mode 100644 index 000000000000..7c0ffe8974f6 --- /dev/null +++ b/coverage/dimred/SketchMapBase.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapBase17setTargetDistanceERKjRKd145000
_ZNK4PLMD6dimred13SketchMapBase31transformLowDimensionalDistanceERKdRd26384110
_ZNK4PLMD6dimred13SketchMapBase32transformHighDimensionalDistanceERKdRd341661
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapBase.h.gcov.html b/coverage/dimred/SketchMapBase.h.gcov.html new file mode 100644 index 000000000000..c1a4de3b2b62 --- /dev/null +++ b/coverage/dimred/SketchMapBase.h.gcov.html @@ -0,0 +1,170 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_dimred_SketchMapBase_h
+      23             : #define __PLUMED_dimred_SketchMapBase_h
+      24             : 
+      25             : #include "tools/SwitchingFunction.h"
+      26             : #include "DimensionalityReductionBase.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace dimred {
+      30             : 
+      31             : class SketchMapBase : public DimensionalityReductionBase {
+      32             : private:
+      33             : /// To save us retyping switching functions many times the code will reuse the
+      34             : /// ones from previous sketch-map objects
+      35             :   bool reuse_hd, reuse_ld;
+      36             : /// Was previous action in chain a sketch-map action
+      37             :   SketchMapBase* smapbase;
+      38             : /// Switching functions for low and high dimensional space
+      39             :   SwitchingFunction lowdf, highdf;
+      40             : /// This is used within calculate stress to hold the target distances and the
+      41             : /// target values for the high dimensional switching function
+      42             :   std::vector<double> dtargets, ftargets, pweights;
+      43             : /// Stress normalization (sum_ij w_i w_j)
+      44             :   double normw;
+      45             : protected:
+      46             : /// This holds the target distances and target transformed distances
+      47             :   Matrix<double> distances, transformed;
+      48             : /// The fraction of pure distances to mix in when optimising
+      49             :   double mixparam;
+      50             : public:
+      51             :   static void registerKeywords( Keywords& keys );
+      52             :   explicit SketchMapBase( const ActionOptions& );
+      53             : /// This starts the process of calculating the projections
+      54             :   void calculateProjections( const Matrix<double>&, Matrix<double>& ) override;
+      55             : /// This finishes the process of calculating the prjections
+      56             :   virtual void minimise( Matrix<double>& )=0;
+      57             : /// Apply the low dimensional switching function to the value val
+      58             :   double transformLowDimensionalDistance( const double& val, double& df ) const ;
+      59             : /// Apply the high dimensional switching function to the value val
+      60             :   double transformHighDimensionalDistance( const double& val, double& df ) const ;
+      61             : /// Set the target distance and from it calculate the target value for the switching function
+      62             : /// This target vector is used when we use calculateStress when finding the projections of individual points.
+      63             : /// For example this function is used in PLMD::dimred::ProjectOutOfSample
+      64             :   void setTargetDistance( const unsigned& idata, const double& dist ) override;
+      65             : /// Calculate the pointwise stress on one point when it is located at p.
+      66             : /// This function makes use of the distance data in dtargets and ftargets
+      67             : /// It is used in PLMD::dimred::ProjectOutOfSample and in pointwise optimisation
+      68             :   double calculateStress( const std::vector<double>& p, std::vector<double>& d ) override;
+      69             : /// Calculate the total stress when the projections are placed at point p.  Notice
+      70             : /// this is a vectorized version of the matrix of projections
+      71             :   double calculateFullStress( const std::vector<double>& p, std::vector<double>& d );
+      72             : };
+      73             : 
+      74             : inline
+      75    26384110 : double SketchMapBase::transformLowDimensionalDistance( const double& val, double& df ) const {
+      76    26384110 :   if( reuse_ld ) return smapbase->transformLowDimensionalDistance( val, df );
+      77    21473710 :   double ans=1.0 - lowdf.calculate( val, df ); df*=-val; return ans;
+      78             : }
+      79             : 
+      80             : inline
+      81      341661 : double SketchMapBase::transformHighDimensionalDistance( const double& val, double& df ) const {
+      82      341661 :   if( reuse_hd ) return smapbase->transformHighDimensionalDistance( val, df );
+      83      316711 :   double ans=1.0 - highdf.calculate( val, df ); df*=-val; return ans;
+      84             : }
+      85             : 
+      86             : inline
+      87      145000 : void SketchMapBase::setTargetDistance( const unsigned& idata, const double& dist ) {
+      88      145000 :   double df; dtargets[idata]=dist; ftargets[idata]=transformHighDimensionalDistance( dist, df );
+      89      145000 : }
+      90             : 
+      91             : }
+      92             : }
+      93             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapConjGrad.cpp.func-sort-c.html b/coverage/dimred/SketchMapConjGrad.cpp.func-sort-c.html new file mode 100644 index 000000000000..236fe3ba8ebc --- /dev/null +++ b/coverage/dimred/SketchMapConjGrad.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapConjGrad.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapConjGrad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred17SketchMapConjGradC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred17SketchMapConjGradC1ERKNS_13ActionOptionsE3
_ZN4PLMD6dimred17SketchMapConjGrad8minimiseERNS_6MatrixIdEE4
_ZN4PLMD6dimred17SketchMapConjGrad16registerKeywordsERNS_8KeywordsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapConjGrad.cpp.func.html b/coverage/dimred/SketchMapConjGrad.cpp.func.html new file mode 100644 index 000000000000..d21aa304ba5d --- /dev/null +++ b/coverage/dimred/SketchMapConjGrad.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapConjGrad.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapConjGrad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred17SketchMapConjGrad16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6dimred17SketchMapConjGrad8minimiseERNS_6MatrixIdEE4
_ZN4PLMD6dimred17SketchMapConjGradC1ERKNS_13ActionOptionsE3
_ZN4PLMD6dimred17SketchMapConjGradC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapConjGrad.cpp.gcov.html b/coverage/dimred/SketchMapConjGrad.cpp.gcov.html new file mode 100644 index 000000000000..eee04056e379 --- /dev/null +++ b/coverage/dimred/SketchMapConjGrad.cpp.gcov.html @@ -0,0 +1,147 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapConjGrad.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapConjGrad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "SketchMapBase.h"
+      24             : #include "tools/ConjugateGradient.h"
+      25             : 
+      26             : //+PLUMEDOC DIMRED SKETCHMAP_CONJGRAD
+      27             : /*
+      28             : Optimize the sketch-map stress function using conjugate gradients.
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace dimred {
+      37             : 
+      38             : class SketchMapConjGrad : public SketchMapBase {
+      39             : private:
+      40             :   double cgtol;
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             :   explicit SketchMapConjGrad( const ActionOptions& ao );
+      44             :   void minimise( Matrix<double>& ) override;
+      45             : };
+      46             : 
+      47             : PLUMED_REGISTER_ACTION(SketchMapConjGrad,"SKETCHMAP_CONJGRAD")
+      48             : 
+      49           5 : void SketchMapConjGrad::registerKeywords( Keywords& keys ) {
+      50           5 :   SketchMapBase::registerKeywords( keys );
+      51          10 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      52           5 : }
+      53             : 
+      54           3 : SketchMapConjGrad::SketchMapConjGrad( const ActionOptions& ao ):
+      55             :   Action(ao),
+      56           3 :   SketchMapBase(ao)
+      57             : {
+      58           3 :   parse("CGTOL",cgtol);
+      59           3 :   log.printf("  tolerance for conjugate gradient algorithm equals %f \n",cgtol);
+      60           3 : }
+      61             : 
+      62           4 : void SketchMapConjGrad::minimise( Matrix<double>& projections ) {
+      63             :   ConjugateGradient<SketchMapConjGrad> mycgminimise( this );
+      64           4 :   std::vector<double> myproj( projections.getVector() );
+      65           4 :   mycgminimise.minimise( cgtol, myproj, &SketchMapConjGrad::calculateFullStress );
+      66           4 :   projections.setFromVector( myproj );
+      67           4 : }
+      68             : 
+      69             : }
+      70             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapPointwise.cpp.func-sort-c.html b/coverage/dimred/SketchMapPointwise.cpp.func-sort-c.html new file mode 100644 index 000000000000..dd736e353577 --- /dev/null +++ b/coverage/dimred/SketchMapPointwise.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapPointwise.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapPointwise.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred18SketchMapPointwiseC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred18SketchMapPointwise8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred18SketchMapPointwiseC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred18SketchMapPointwise16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapPointwise.cpp.func.html b/coverage/dimred/SketchMapPointwise.cpp.func.html new file mode 100644 index 000000000000..3bc08c5762b6 --- /dev/null +++ b/coverage/dimred/SketchMapPointwise.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapPointwise.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapPointwise.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred18SketchMapPointwise16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred18SketchMapPointwise8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred18SketchMapPointwiseC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred18SketchMapPointwiseC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapPointwise.cpp.gcov.html b/coverage/dimred/SketchMapPointwise.cpp.gcov.html new file mode 100644 index 000000000000..632022c4a9bd --- /dev/null +++ b/coverage/dimred/SketchMapPointwise.cpp.gcov.html @@ -0,0 +1,203 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapPointwise.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapPointwise.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "SketchMapBase.h"
+      24             : #include "tools/ConjugateGradient.h"
+      25             : #include "gridtools/GridSearch.h"
+      26             : 
+      27             : //+PLUMEDOC DIMRED SKETCHMAP_POINTWISE
+      28             : /*
+      29             : Optimize the sketch-map stress function using a pointwise global optimization algorithm.
+      30             : 
+      31             : \par Examples
+      32             : 
+      33             : */
+      34             : //+ENDPLUMEDOC
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace dimred {
+      38             : 
+      39             : class SketchMapPointwise : public SketchMapBase {
+      40             : private:
+      41             :   unsigned ncycles;
+      42             :   double cgtol, gbuf;
+      43             :   std::vector<unsigned> npoints, nfgrid;
+      44             : public:
+      45             :   static void registerKeywords( Keywords& keys );
+      46             :   explicit SketchMapPointwise( const ActionOptions& ao );
+      47             :   void minimise( Matrix<double>& ) override;
+      48             : };
+      49             : 
+      50             : PLUMED_REGISTER_ACTION(SketchMapPointwise,"SKETCHMAP_POINTWISE")
+      51             : 
+      52           3 : void SketchMapPointwise::registerKeywords( Keywords& keys ) {
+      53           3 :   SketchMapBase::registerKeywords( keys );
+      54           6 :   keys.add("compulsory","NCYCLES","5","the number of cycles of global optimization to attempt");
+      55           6 :   keys.add("compulsory","CGTOL","1E-6","the tolerance for the conjugate gradient minimization");
+      56           6 :   keys.add("compulsory","BUFFER","1.1","grid extent for search is (max projection - minimum projection) multiplied by this value");
+      57           6 :   keys.add("compulsory","CGRID_SIZE","10","number of points to use in each grid direction");
+      58           6 :   keys.add("compulsory","FGRID_SIZE","0","interpolate the grid onto this number of points -- only works in 2D");
+      59           3 : }
+      60             : 
+      61           1 : SketchMapPointwise::SketchMapPointwise( const ActionOptions& ao ):
+      62             :   Action(ao),
+      63             :   SketchMapBase(ao),
+      64           2 :   npoints(nlow),
+      65           1 :   nfgrid(nlow)
+      66             : {
+      67           3 :   parseVector("CGRID_SIZE",npoints); parse("BUFFER",gbuf);
+      68           1 :   if( npoints.size()!=nlow ) error("vector giving number of grid point in each direction has wrong size");
+      69           2 :   parse("NCYCLES",ncycles); parse("CGTOL",cgtol);
+      70             : 
+      71           2 :   parseVector("FGRID_SIZE",nfgrid);
+      72           1 :   if( nfgrid[0]!=0 && nlow!=2 ) error("interpolation only works in two dimensions");
+      73             : 
+      74           1 :   log.printf("  doing %u cycles of global optimization sweeps\n",ncycles);
+      75           1 :   log.printf("  using coarse grid of points that is %u",npoints[0]);
+      76           1 :   log.printf(" and that is %f larger than the difference between the position of the minimum and maximum projection \n",gbuf);
+      77           2 :   for(unsigned j=1; j<npoints.size(); ++j) log.printf(" by %u",npoints[j]);
+      78           1 :   if( nfgrid[0]>0 ) {
+      79           1 :     log.printf("  interpolating stress onto grid of points that is %u",nfgrid[0]);
+      80           2 :     for(unsigned j=1; j<nfgrid.size(); ++j) log.printf(" by %u",nfgrid[j]);
+      81           1 :     log.printf("\n");
+      82             :   }
+      83           1 :   log.printf("  tolerance for conjugate gradient algorithm equals %f \n",cgtol);
+      84           1 : }
+      85             : 
+      86           1 : void SketchMapPointwise::minimise( Matrix<double>& projections ) {
+      87           1 :   std::vector<double> gmin( nlow ), gmax( nlow ), mypoint( nlow );
+      88             : 
+      89             :   // Find the extent of the grid
+      90           3 :   for(unsigned j=0; j<nlow; ++j) gmin[j]=gmax[j]=projections(0,j);
+      91         100 :   for(unsigned i=1; i<getNumberOfDataPoints(); ++i) {
+      92         297 :     for(unsigned j=0; j<nlow; ++j) {
+      93         198 :       if( projections(i,j) < gmin[j] ) gmin[j] = projections(i,j);
+      94         198 :       if( projections(i,j) > gmax[j] ) gmax[j] = projections(i,j);
+      95             :     }
+      96             :   }
+      97           3 :   for(unsigned j=0; j<nlow; ++j) {
+      98           2 :     double gbuffer = 0.5*gbuf*( gmax[j]-gmin[j] ) - 0.5*( gmax[j]- gmin[j] );
+      99           2 :     gmin[j]-=gbuffer; gmax[j]+=gbuffer;
+     100             :   }
+     101             : 
+     102             :   // And do the search
+     103             :   ConjugateGradient<SketchMapPointwise> mycgminimise( this );
+     104           1 :   gridtools::GridSearch<SketchMapPointwise> mygridsearch( gmin, gmax, npoints, nfgrid, this );
+     105             :   // Run multiple loops over all projections
+     106           3 :   for(unsigned i=0; i<ncycles; ++i) {
+     107         202 :     for(unsigned j=0; j<getNumberOfDataPoints(); ++j) {
+     108             :       // Setup target distances and target functions for calculate stress
+     109       20200 :       for(unsigned k=0; k<getNumberOfDataPoints(); ++k) setTargetDistance( k, distances(j,k)  );
+     110             : 
+     111             :       // Find current projection of jth point
+     112         600 :       for(unsigned k=0; k<mypoint.size(); ++k) mypoint[k]=projections(j,k);
+     113             :       // Minimise using grid search
+     114         200 :       bool moved=mygridsearch.minimise( mypoint, &SketchMapPointwise::calculateStress );
+     115         200 :       if( moved ) {
+     116             :         // Reassign the new projection
+     117          66 :         for(unsigned k=0; k<mypoint.size(); ++k) projections(j,k)=mypoint[k];
+     118             :         // Minimise output using conjugate gradient
+     119          22 :         mycgminimise.minimise( cgtol, projections.getVector(), &SketchMapPointwise::calculateFullStress );
+     120             :       }
+     121             :     }
+     122             :   }
+     123           1 : }
+     124             : 
+     125             : }
+     126             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapRead.cpp.func-sort-c.html b/coverage/dimred/SketchMapRead.cpp.func-sort-c.html new file mode 100644 index 000000000000..cd8f0a92b7c7 --- /dev/null +++ b/coverage/dimred/SketchMapRead.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapRead.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapRead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:758192.6 %
Date:2024-02-22 21:58:45Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapRead15getArgumentListEv0
_ZN4PLMD6dimred13SketchMapReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred13SketchMapRead23getDataPointIndexInBaseERKj0
_ZN4PLMD6dimred13SketchMapRead8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred13SketchMapReadC1ERKNS_13ActionOptionsE1
_ZZN4PLMD6dimred13SketchMapReadC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_1
_ZN4PLMD6dimred13SketchMapRead16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred13SketchMapRead9getWeightERKj168
_ZNK4PLMD6dimred13SketchMapRead21getNumberOfDataPointsEv173
_ZN4PLMD6dimred13SketchMapRead16getDissimilarityERKjS3_3486
_ZN4PLMD6dimred13SketchMapRead13getStoredDataERKjRKb7056
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapRead.cpp.func.html b/coverage/dimred/SketchMapRead.cpp.func.html new file mode 100644 index 000000000000..d72f21eb53b1 --- /dev/null +++ b/coverage/dimred/SketchMapRead.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapRead.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapRead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:758192.6 %
Date:2024-02-22 21:58:45Functions:81172.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred13SketchMapRead13getStoredDataERKjRKb7056
_ZN4PLMD6dimred13SketchMapRead15getArgumentListEv0
_ZN4PLMD6dimred13SketchMapRead16getDissimilarityERKjS3_3486
_ZN4PLMD6dimred13SketchMapRead16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred13SketchMapRead8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred13SketchMapRead9getWeightERKj168
_ZN4PLMD6dimred13SketchMapReadC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred13SketchMapReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD6dimred13SketchMapRead21getNumberOfDataPointsEv173
_ZNK4PLMD6dimred13SketchMapRead23getDataPointIndexInBaseERKj0
_ZZN4PLMD6dimred13SketchMapReadC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapRead.cpp.gcov.html b/coverage/dimred/SketchMapRead.cpp.gcov.html new file mode 100644 index 000000000000..e9610e5677e5 --- /dev/null +++ b/coverage/dimred/SketchMapRead.cpp.gcov.html @@ -0,0 +1,273 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapRead.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapRead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:758192.6 %
Date:2024-02-22 21:58:45Functions:81172.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "SketchMapBase.h"
+      24             : #include "reference/ReferenceConfiguration.h"
+      25             : #include "reference/MetricRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "tools/PDB.h"
+      28             : 
+      29             : //+PLUMEDOC DIMRED SKETCHMAP_READ
+      30             : /*
+      31             : Read in a sketch-map projection from an input file
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace dimred {
+      40             : 
+      41             : class SketchMapRead : public SketchMapBase {
+      42             : private:
+      43             :   std::string mtype;
+      44             :   PDB mypdb;
+      45             :   std::vector<Value*> all_values;
+      46             :   std::vector<double> weights;
+      47             : /// The list of properties in the property map
+      48             :   std::map<std::string,std::vector<double> > property;
+      49             : /// The data collection objects we have
+      50             :   std::vector<analysis::DataCollectionObject> data;
+      51             : /// The frames that we are using to calculate distances
+      52             :   std::vector<std::unique_ptr<ReferenceConfiguration> > myframes;
+      53             : public:
+      54             :   static void registerKeywords( Keywords& keys );
+      55             :   explicit SketchMapRead( const ActionOptions& ao );
+      56             :   void minimise( Matrix<double>& ) override;
+      57             :   analysis::DataCollectionObject& getStoredData( const unsigned& idata, const bool& calcdist ) override;
+      58             :   unsigned getNumberOfDataPoints() const override;
+      59             :   std::vector<Value*> getArgumentList() override;
+      60             :   unsigned getDataPointIndexInBase( const unsigned& idata ) const override;
+      61             :   double getDissimilarity( const unsigned& i, const unsigned& j ) override;
+      62             :   double getWeight( const unsigned& idata ) override;
+      63             : };
+      64             : 
+      65             : PLUMED_REGISTER_ACTION(SketchMapRead,"SKETCHMAP_READ")
+      66             : 
+      67           3 : void SketchMapRead::registerKeywords( Keywords& keys ) {
+      68           3 :   SketchMapBase::registerKeywords( keys ); keys.remove("USE_OUTPUT_DATA_FROM");
+      69           6 :   keys.add("compulsory","TYPE","OPTIMAL-FAST","the manner in which distances are calculated. More information on the different "
+      70             :            "metrics that are available in PLUMED can be found in the section of the manual on "
+      71             :            "\\ref dists");
+      72           6 :   keys.add("compulsory","REFERENCE","the file containing the sketch-map projection");
+      73           6 :   keys.add("compulsory","PROPERTY","the property to be used in the index. This should be in the REMARK of the reference");
+      74           6 :   keys.addFlag("DISABLE_CHECKS",false,"disable checks on reference input structures.");
+      75           3 :   useCustomisableComponents(keys);
+      76           3 : }
+      77             : 
+      78           1 : SketchMapRead::SketchMapRead( const ActionOptions& ao ):
+      79             :   Action(ao),
+      80           1 :   SketchMapBase(ao)
+      81             : {
+      82           2 :   std::vector<std::string> propnames; parseVector("PROPERTY",propnames);
+      83           1 :   if(propnames.size()==0) error("no properties were specified");
+      84           1 :   nlow=propnames.size();
+      85           3 :   for(unsigned i=0; i<nlow; ++i) {
+      86           4 :     std::size_t dot=propnames[i].find_first_of( getLabel() + "." ); std::string substr=propnames[i].c_str();
+      87           2 :     if( dot!=std::string::npos ) { substr.erase(dot,getLabel().length()+1); }
+      88           4 :     log.printf(",%s", propnames[i].c_str() ); addComponent( substr ); componentIsNotPeriodic( substr );
+      89           4 :     property.insert( std::pair<std::string,std::vector<double> >( propnames[i], std::vector<double>() ) );
+      90             :   }
+      91           1 :   log.printf("  mapped properties are %s ",propnames[0].c_str() );
+      92           2 :   for(unsigned i=1; i<nlow; ++i) log.printf(",%s", propnames[i].c_str() );
+      93           1 :   log.printf("\n");
+      94             : 
+      95           3 :   parse("TYPE",mtype); bool skipchecks; parseFlag("DISABLE_CHECKS",skipchecks);
+      96           2 :   std::string ifilename; parse("REFERENCE",ifilename);
+      97           1 :   FILE* fp=this->fopen(ifilename.c_str(),"r");
+      98           1 :   if(!fp) error("could not open reference file " + ifilename );
+      99             : // call fclose when fp goes out of scope
+     100           1 :   auto deleter=[this](FILE* f) { this->fclose(f); };
+     101             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     102             : 
+     103             : 
+     104             :   // Read in the embedding
+     105             :   bool do_read=true; double val, ww, wnorm=0, prop; unsigned nfram=0;
+     106          85 :   while (do_read) {
+     107          85 :     PDB inpdb;
+     108             :     // Read the pdb file
+     109          85 :     do_read=inpdb.readFromFilepointer(fp,usingNaturalUnits(),0.1/getUnits().getLength());
+     110             :     // Break if we are done
+     111          85 :     if( !do_read ) break ;
+     112             :     // Check for required properties
+     113         252 :     for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+     114         168 :       if( !inpdb.getArgumentValue( it->first, prop ) ) error("pdb input does not have contain property named " + it->first );
+     115         168 :       it->second.push_back(prop);
+     116             :     }
+     117             :     // And read the frame ( create a measure )
+     118          84 :     myframes.emplace_back( metricRegister().create<ReferenceConfiguration>( mtype, inpdb ) );
+     119         168 :     if( !inpdb.getArgumentValue( "WEIGHT", ww ) ) error("could not find weights in input pdb");
+     120          84 :     weights.push_back( ww ); wnorm += ww; nfram++;
+     121             :     // And create a data collection object
+     122          84 :     analysis::DataCollectionObject new_data; new_data.setAtomNumbersAndArgumentNames( getLabel(), inpdb.getAtomNumbers(), inpdb.getArgumentNames() );
+     123          84 :     new_data.setAtomPositions( inpdb.getPositions() );
+     124         504 :     for(unsigned i=0; i<inpdb.getArgumentNames().size(); ++i) {
+     125         420 :       std::string aname = inpdb.getArgumentNames()[i];
+     126         420 :       if( !inpdb.getArgumentValue( aname, val ) ) error("failed to find argument named " + aname);
+     127         420 :       new_data.setArgument( aname, val );
+     128             :     }
+     129          84 :     data.push_back( new_data );
+     130          85 :   }
+     131             :   // Finish the setup of the object by getting the arguments and atoms that are required
+     132             :   std::vector<AtomNumber> atoms; std::vector<std::string> args;
+     133          85 :   for(unsigned i=0; i<myframes.size(); ++i) { weights[i] /= wnorm; myframes[i]->getAtomRequests( atoms, skipchecks ); myframes[i]->getArgumentRequests( args, skipchecks ); }
+     134           1 :   requestAtoms( atoms ); std::vector<Value*> req_args; std::vector<std::string> fargs;
+     135           6 :   for(unsigned i=0; i<args.size(); ++i) {
+     136             :     bool found=false;
+     137          12 :     for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+     138           9 :       if( args[i]==it->first ) { found=true; break; }
+     139             :     }
+     140           5 :     if( !found ) { fargs.push_back( args[i] ); }
+     141             :   }
+     142           1 :   interpretArgumentList( fargs, req_args ); mypdb.setArgumentNames( fargs ); requestArguments( req_args );
+     143             : 
+     144           1 :   if(nfram==0 ) error("no reference configurations were specified");
+     145           1 :   log.printf(" found %u configurations in file %s\n",nfram,ifilename.c_str() );
+     146           4 : }
+     147             : 
+     148           1 : void SketchMapRead::minimise( Matrix<double>& projections ) {
+     149             :   unsigned j=0;
+     150           3 :   for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+     151         170 :     for(unsigned i=0; i<myframes.size(); ++i) projections(i,j) = it->second[i];
+     152           2 :     j++;
+     153             :   }
+     154           1 : }
+     155             : 
+     156        7056 : analysis::DataCollectionObject & SketchMapRead::getStoredData( const unsigned& idata, const bool& calcdist ) {
+     157        7056 :   return data[idata];
+     158             : }
+     159             : 
+     160         173 : unsigned SketchMapRead::getNumberOfDataPoints() const {
+     161         173 :   return myframes.size();
+     162             : }
+     163             : 
+     164           0 : unsigned SketchMapRead::getDataPointIndexInBase( const unsigned& idata ) const {
+     165           0 :   error("cannot use read in sketch-map to out of sample project data");
+     166             :   return idata;
+     167             : }
+     168             : 
+     169           0 : std::vector<Value*> SketchMapRead::getArgumentList() {
+     170           0 :   std::vector<Value*> arglist( ActionWithArguments::getArguments() );
+     171           0 :   for(unsigned i=0; i<nlow; ++i) arglist.push_back( getPntrToComponent(i) );
+     172           0 :   return arglist;
+     173             : }
+     174             : 
+     175             : // Highly unsatisfactory solution to problem GAT
+     176        3486 : double SketchMapRead::getDissimilarity( const unsigned& i, const unsigned& j ) {
+     177        3486 :   plumed_assert( i<myframes.size() && j<myframes.size() );
+     178        3486 :   if( i!=j ) {
+     179             :     double dd;
+     180        3486 :     getStoredData( i, true ).transferDataToPDB( mypdb );
+     181        3486 :     auto myref1=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     182        3486 :     getStoredData( j, true ).transferDataToPDB( mypdb );
+     183        3486 :     auto myref2=metricRegister().create<ReferenceConfiguration>(mtype, mypdb);
+     184        3486 :     dd=distance( getPbc(), ActionWithArguments::getArguments(), myref1.get(), myref2.get(), true );
+     185             :     return dd;
+     186        3486 :   }
+     187             :   return 0.0;
+     188             : }
+     189             : 
+     190         168 : double SketchMapRead::getWeight( const unsigned& idata ) {
+     191         168 :   plumed_assert( idata<weights.size() );
+     192         168 :   return weights[idata];
+     193             : }
+     194             : 
+     195             : }
+     196             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapSmacof.cpp.func-sort-c.html b/coverage/dimred/SketchMapSmacof.cpp.func-sort-c.html new file mode 100644 index 000000000000..234116519717 --- /dev/null +++ b/coverage/dimred/SketchMapSmacof.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapSmacof.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapSmacof.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred15SketchMapSmacofC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred15SketchMapSmacof8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred15SketchMapSmacofC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred15SketchMapSmacof18recalculateWeightsERKNS_6MatrixIdEERS3_2
_ZN4PLMD6dimred15SketchMapSmacof16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapSmacof.cpp.func.html b/coverage/dimred/SketchMapSmacof.cpp.func.html new file mode 100644 index 000000000000..94821f48ad83 --- /dev/null +++ b/coverage/dimred/SketchMapSmacof.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapSmacof.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapSmacof.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred15SketchMapSmacof16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD6dimred15SketchMapSmacof18recalculateWeightsERKNS_6MatrixIdEERS3_2
_ZN4PLMD6dimred15SketchMapSmacof8minimiseERNS_6MatrixIdEE1
_ZN4PLMD6dimred15SketchMapSmacofC1ERKNS_13ActionOptionsE1
_ZN4PLMD6dimred15SketchMapSmacofC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SketchMapSmacof.cpp.gcov.html b/coverage/dimred/SketchMapSmacof.cpp.gcov.html new file mode 100644 index 000000000000..25b0c01152bd --- /dev/null +++ b/coverage/dimred/SketchMapSmacof.cpp.gcov.html @@ -0,0 +1,187 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SketchMapSmacof.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SketchMapSmacof.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "SketchMapBase.h"
+      24             : #include "SMACOF.h"
+      25             : 
+      26             : //+PLUMEDOC DIMRED SKETCHMAP_SMACOF
+      27             : /*
+      28             : Optimize the sketch-map stress function using the SMACOF algorithm.
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace dimred {
+      37             : 
+      38             : class SketchMapSmacof : public SketchMapBase {
+      39             : private:
+      40             :   unsigned max_smap, maxiter;
+      41             :   double smap_tol, iter_tol, regulariser;
+      42             :   double recalculateWeights( const Matrix<double>& projections, Matrix<double>& weights );
+      43             : public:
+      44             :   static void registerKeywords( Keywords& keys );
+      45             :   explicit SketchMapSmacof( const ActionOptions& ao );
+      46             :   void minimise( Matrix<double>& ) override;
+      47             : };
+      48             : 
+      49             : PLUMED_REGISTER_ACTION(SketchMapSmacof,"SKETCHMAP_SMACOF")
+      50             : 
+      51           3 : void SketchMapSmacof::registerKeywords( Keywords& keys ) {
+      52           3 :   SketchMapBase::registerKeywords( keys );
+      53           6 :   keys.add("compulsory","SMACOF_TOL","1E-4","the tolerance for each SMACOF cycle");
+      54           6 :   keys.add("compulsory","SMACOF_MAXCYC","1000","maximum number of optimization cycles for SMACOF algorithm");
+      55           6 :   keys.add("compulsory","SMAP_TOL","1E-4","the tolerance for sketch-map");
+      56           6 :   keys.add("compulsory","SMAP_MAXCYC","100","maximum number of optimization cycles for iterative sketch-map algorithm");
+      57           6 :   keys.add("compulsory","REGULARISE_PARAM","0.001","this is used to ensure that we don't divide by zero when updating weights");
+      58           3 : }
+      59             : 
+      60           1 : SketchMapSmacof::SketchMapSmacof( const ActionOptions& ao ):
+      61             :   Action(ao),
+      62           1 :   SketchMapBase(ao)
+      63             : {
+      64           1 :   parse("REGULARISE_PARAM",regulariser);
+      65           2 :   parse("SMACOF_MAXCYC",max_smap); parse("SMAP_MAXCYC",maxiter);
+      66           2 :   parse("SMACOF_TOL",smap_tol); parse("SMAP_TOL",iter_tol);
+      67           1 : }
+      68             : 
+      69           1 : void SketchMapSmacof::minimise( Matrix<double>& projections ) {
+      70             :   Matrix<double> weights( distances.nrows(), distances.ncols() ); weights=0.;
+      71           1 :   double filt = recalculateWeights( projections, weights );
+      72             : 
+      73           1 :   for(unsigned i=0; i<maxiter; ++i) {
+      74           1 :     SMACOF::run( weights, distances, smap_tol, max_smap, projections );
+      75             :     // Recalculate weights matrix and sigma
+      76           1 :     double newsig = recalculateWeights( projections, weights );
+      77             :     // Test whether or not the algorithm has converged
+      78           1 :     if( std::fabs( newsig - filt )<iter_tol ) break;
+      79             :     // Make initial sigma into new sigma so that the value of new sigma is used every time so that the error can be reduced
+      80             :     filt=newsig;
+      81             :   }
+      82           1 : }
+      83             : 
+      84           2 : double SketchMapSmacof::recalculateWeights( const Matrix<double>& projections, Matrix<double>& weights ) {
+      85             :   double filt=0, totalWeight=0.;; double dr;
+      86        1000 :   for(unsigned i=1; i<weights.nrows(); ++i) {
+      87      250498 :     for(unsigned j=0; j<i; ++j) {
+      88      249500 :       double ninj=getWeight(i)*getWeight(j); totalWeight += ninj;
+      89             : 
+      90             :       double tempd=0;
+      91      748500 :       for(unsigned k=0; k<projections.ncols(); ++k) {
+      92      499000 :         double tmp = projections(i,k) - projections(j,k);
+      93      499000 :         tempd += tmp*tmp;
+      94             :       }
+      95      249500 :       double dij=std::sqrt(tempd);
+      96             : 
+      97      249500 :       double fij = transformLowDimensionalDistance( dij, dr );
+      98      249500 :       double filter=transformed(i,j)-fij;
+      99      249500 :       double diff=distances(i,j) - dij;
+     100             : 
+     101      249500 :       if( std::fabs(diff)<regulariser ) weights(i,j)=weights(j,i)=0.0;
+     102      249403 :       else weights(i,j)=weights(j,i) = ninj*( (1-mixparam)*( filter*dr )/diff + mixparam );
+     103      249500 :       filt += ninj*( (1-mixparam)*filter*filter + mixparam*diff*diff );
+     104             :     }
+     105             :   }
+     106           2 :   return filt / totalWeight;
+     107             : }
+     108             : 
+     109             : }
+     110             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SmacoffMDS.cpp.func-sort-c.html b/coverage/dimred/SmacoffMDS.cpp.func-sort-c.html new file mode 100644 index 000000000000..e436b6254655 --- /dev/null +++ b/coverage/dimred/SmacoffMDS.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SmacoffMDS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SmacoffMDS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:61931.6 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred9SmacofMDS20calculateProjectionsERKNS_6MatrixIdEERS3_0
_ZN4PLMD6dimred9SmacofMDSC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SmacofMDSC2ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SmacofMDS16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SmacoffMDS.cpp.func.html b/coverage/dimred/SmacoffMDS.cpp.func.html new file mode 100644 index 000000000000..8c09712ed491 --- /dev/null +++ b/coverage/dimred/SmacoffMDS.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SmacoffMDS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SmacoffMDS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:61931.6 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6dimred9SmacofMDS16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD6dimred9SmacofMDS20calculateProjectionsERKNS_6MatrixIdEERS3_0
_ZN4PLMD6dimred9SmacofMDSC1ERKNS_13ActionOptionsE0
_ZN4PLMD6dimred9SmacofMDSC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/SmacoffMDS.cpp.gcov.html b/coverage/dimred/SmacoffMDS.cpp.gcov.html new file mode 100644 index 000000000000..55c763d58eb9 --- /dev/null +++ b/coverage/dimred/SmacoffMDS.cpp.gcov.html @@ -0,0 +1,159 @@ + + + + + + + + LCOV - plumed test coverage - dimred/SmacoffMDS.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimred - SmacoffMDS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:61931.6 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DimensionalityReductionBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "SMACOF.h"
+      25             : 
+      26             : //+PLUMEDOC DIMRED SMACOF_MDS
+      27             : /*
+      28             : Optimize the multidimensional scaling stress function using the SMACOF algorithm.
+      29             : 
+      30             : \par Examples
+      31             : 
+      32             : */
+      33             : //+ENDPLUMEDOC
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace dimred {
+      37             : 
+      38             : class SmacofMDS : public DimensionalityReductionBase {
+      39             : private:
+      40             :   unsigned maxloops;
+      41             :   double tol;
+      42             : public:
+      43             :   static void registerKeywords( Keywords& keys );
+      44             :   explicit SmacofMDS( const ActionOptions& );
+      45             :   void calculateProjections( const Matrix<double>&, Matrix<double>& ) override;
+      46             : };
+      47             : 
+      48             : PLUMED_REGISTER_ACTION(SmacofMDS,"SMACOF_MDS")
+      49             : 
+      50           2 : void SmacofMDS::registerKeywords( Keywords& keys ) {
+      51           2 :   DimensionalityReductionBase::registerKeywords( keys );
+      52           2 :   keys.remove("NLOW_DIM");
+      53           4 :   keys.add("compulsory","SMACOF_TOL","1E-4","tolerance for the SMACOF optimization algorithm");
+      54           4 :   keys.add("compulsory","SMACOF_MAXCYC","1000","maximum number of optimization cycles for SMACOF algorithm");
+      55           2 : }
+      56             : 
+      57           0 : SmacofMDS::SmacofMDS( const ActionOptions& ao):
+      58             :   Action(ao),
+      59           0 :   DimensionalityReductionBase(ao)
+      60             : {
+      61           0 :   if( !dimredbase ) error("SMACOF must be initialized using output from dimensionality reduction object");
+      62             : 
+      63           0 :   parse("SMACOF_TOL",tol); parse("SMACOF_MAXCYC",maxloops);
+      64           0 :   log.printf("  running smacof to convergence at %f or for a maximum of %u steps \n",tol,maxloops);
+      65           0 : }
+      66             : 
+      67           0 : void SmacofMDS::calculateProjections( const Matrix<double>& targets, Matrix<double>& projections ) {
+      68             :   // Take the square root of all the distances and the weights
+      69             :   Matrix<double> weights( targets.nrows(), targets.ncols() );
+      70             :   Matrix<double> distances( targets.nrows(), targets.ncols() );
+      71           0 :   for(unsigned i=1; i<distances.ncols(); ++i) {
+      72           0 :     for(unsigned j=0; j<i; ++j) {
+      73           0 :       distances(i,j)=distances(j,i)=std::sqrt( targets(i,j) );
+      74           0 :       weights(i,j)=weights(j,i)=getWeight(i)*getWeight(j);
+      75             :     }
+      76             :   }
+      77             :   // And run SMACOF
+      78           0 :   SMACOF::run( weights, targets, tol, maxloops, projections );
+      79           0 : }
+      80             : 
+      81             : }
+      82             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/index-sort-f.html b/coverage/dimred/index-sort-f.html new file mode 100644 index 000000000000..f830b8c68f04 --- /dev/null +++ b/coverage/dimred/index-sort-f.html @@ -0,0 +1,244 @@ + + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:54664684.5 %
Date:2024-02-22 21:58:45Functions:517865.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
DimensionalityReductionBase.h +
0.0%
+
0.0 %0 / 40.0 %0 / 2
PCA.h +
0.0%
+
0.0 %0 / 30.0 %0 / 3
SmacoffMDS.cpp +
31.6%31.6%
+
31.6 %6 / 1925.0 %1 / 4
SketchMap.cpp +
29.8%29.8%
+
29.8 %14 / 4733.3 %1 / 3
OutputPCAProjections.cpp +
97.1%97.1%
+
97.1 %34 / 3560.0 %3 / 5
PCA.cpp +
80.7%80.7%
+
80.7 %96 / 11966.7 %4 / 6
ProjectNonLandmarkPoints.cpp +
90.5%90.5%
+
90.5 %38 / 4266.7 %6 / 9
DimensionalityReductionBase.cpp +
79.7%79.7%
+
79.7 %47 / 5971.4 %5 / 7
SketchMapRead.cpp +
92.6%92.6%
+
92.6 %75 / 8172.7 %8 / 11
SketchMapPointwise.cpp +
100.0%
+
100.0 %46 / 4675.0 %3 / 4
ClassicalMultiDimensionalScaling.cpp +
100.0%
+
100.0 %20 / 2075.0 %3 / 4
SketchMapConjGrad.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
SketchMapSmacof.cpp +
100.0%
+
100.0 %36 / 3680.0 %4 / 5
SketchMapBase.cpp +
100.0%
+
100.0 %79 / 7983.3 %5 / 6
SMACOF.cpp +
97.0%97.0%
+
97.0 %32 / 33100.0 %2 / 2
SketchMapBase.h +
100.0%
+
100.0 %9 / 9100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/index-sort-l.html b/coverage/dimred/index-sort-l.html new file mode 100644 index 000000000000..dfb2e393b3e2 --- /dev/null +++ b/coverage/dimred/index-sort-l.html @@ -0,0 +1,244 @@ + + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:54664684.5 %
Date:2024-02-22 21:58:45Functions:517865.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PCA.h +
0.0%
+
0.0 %0 / 30.0 %0 / 3
DimensionalityReductionBase.h +
0.0%
+
0.0 %0 / 40.0 %0 / 2
SketchMap.cpp +
29.8%29.8%
+
29.8 %14 / 4733.3 %1 / 3
SmacoffMDS.cpp +
31.6%31.6%
+
31.6 %6 / 1925.0 %1 / 4
DimensionalityReductionBase.cpp +
79.7%79.7%
+
79.7 %47 / 5971.4 %5 / 7
PCA.cpp +
80.7%80.7%
+
80.7 %96 / 11966.7 %4 / 6
ProjectNonLandmarkPoints.cpp +
90.5%90.5%
+
90.5 %38 / 4266.7 %6 / 9
SketchMapRead.cpp +
92.6%92.6%
+
92.6 %75 / 8172.7 %8 / 11
SMACOF.cpp +
97.0%97.0%
+
97.0 %32 / 33100.0 %2 / 2
OutputPCAProjections.cpp +
97.1%97.1%
+
97.1 %34 / 3560.0 %3 / 5
SketchMapBase.h +
100.0%
+
100.0 %9 / 9100.0 %3 / 3
SketchMapConjGrad.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
ClassicalMultiDimensionalScaling.cpp +
100.0%
+
100.0 %20 / 2075.0 %3 / 4
SketchMapSmacof.cpp +
100.0%
+
100.0 %36 / 3680.0 %4 / 5
SketchMapPointwise.cpp +
100.0%
+
100.0 %46 / 4675.0 %3 / 4
SketchMapBase.cpp +
100.0%
+
100.0 %79 / 7983.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/dimred/index.html b/coverage/dimred/index.html new file mode 100644 index 000000000000..7e56bcc43d79 --- /dev/null +++ b/coverage/dimred/index.html @@ -0,0 +1,244 @@ + + + + + + + + LCOV - plumed test coverage - dimred + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - dimredHitTotalCoverage
Test:plumed test coverageLines:54664684.5 %
Date:2024-02-22 21:58:45Functions:517865.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ClassicalMultiDimensionalScaling.cpp +
100.0%
+
100.0 %20 / 2075.0 %3 / 4
DimensionalityReductionBase.cpp +
79.7%79.7%
+
79.7 %47 / 5971.4 %5 / 7
DimensionalityReductionBase.h +
0.0%
+
0.0 %0 / 40.0 %0 / 2
OutputPCAProjections.cpp +
97.1%97.1%
+
97.1 %34 / 3560.0 %3 / 5
PCA.cpp +
80.7%80.7%
+
80.7 %96 / 11966.7 %4 / 6
PCA.h +
0.0%
+
0.0 %0 / 30.0 %0 / 3
ProjectNonLandmarkPoints.cpp +
90.5%90.5%
+
90.5 %38 / 4266.7 %6 / 9
SMACOF.cpp +
97.0%97.0%
+
97.0 %32 / 33100.0 %2 / 2
SketchMap.cpp +
29.8%29.8%
+
29.8 %14 / 4733.3 %1 / 3
SketchMapBase.cpp +
100.0%
+
100.0 %79 / 7983.3 %5 / 6
SketchMapBase.h +
100.0%
+
100.0 %9 / 9100.0 %3 / 3
SketchMapConjGrad.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
SketchMapPointwise.cpp +
100.0%
+
100.0 %46 / 4675.0 %3 / 4
SketchMapRead.cpp +
92.6%92.6%
+
92.6 %75 / 8172.7 %8 / 11
SketchMapSmacof.cpp +
100.0%
+
100.0 %36 / 3680.0 %4 / 5
SmacoffMDS.cpp +
31.6%31.6%
+
31.6 %6 / 1925.0 %1 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.cpp.func-sort-c.html b/coverage/drr/DRR.cpp.func-sort-c.html new file mode 100644 index 000000000000..d29fec4ad5c8 --- /dev/null +++ b/coverage/drr/DRR.cpp.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33135593.2 %
Date:2024-02-22 21:58:45Functions:242596.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3drr7DRRAxis12isInBoundaryEd0
_ZN4PLMD3drr3ABF11mergewindowERKS1_S3_2
_ZN4PLMD3drr4CZAR11mergewindowERKS1_S3_2
_ZNK4PLMD3drr12DRRForceGrid15writeDivergenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_2
_ZN4PLMD3drr12DRRForceGrid5mergeERKSt6vectorINS0_7DRRAxisESaIS3_EES7_4
_ZN4PLMD3drr7DRRAxis5mergeERKS1_S3_4
_ZNK4PLMD3drr4CZAR16writeZCountZGradERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb18
_ZN4PLMD3drr12DRRForceGridC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb26
_ZNK4PLMD3drr12DRRForceGrid10write1DPMFENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS7_26
_ZN4PLMD3drr12DRRForceGrid9fillTableERKSt6vectorIS2_IdSaIdEESaIS4_EE34
_ZNK4PLMD3drr12DRRForceGrid8writeAllERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_b36
_ZN4PLMD3drr12DRRForceGridC2Ev38
_ZN4PLMD3drr7DRRAxis15getMiddlePointsEv60
_ZN4PLMD3drr3ABF13store_getbiasERKSt6vectorIdSaIdEES6_RS4_123
_ZNK4PLMD3drr12DRRForceGrid20getAccumulatedForcesERKSt6vectorIdSaIdEE1600
_ZN4PLMD3drr12DRRForceGrid5storeERKSt6vectorIdSaIdEES6_m1723
_ZNK4PLMD3drr7DRRAxis14isRealPeriodicEv5860
_ZNK4PLMD3drr12DRRForceGrid13getDivergenceERKSt6vectorIdSaIdEE64800
_ZNK4PLMD3drr12DRRForceGrid8getCountERKSt6vectorIdSaIdEEb67612
_ZNK4PLMD3drr12DRRForceGrid11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr12DRRForceGrid22getCountsLogDerivativeERKSt6vectorIdSaIdEE195576
_ZNK4PLMD3drr4CZAR11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr12DRRForceGrid12isInBoundaryERKSt6vectorIdSaIdEE393846
_ZNK4PLMD3drr12DRRForceGrid13sampleAddressERKSt6vectorIdSaIdEE1012383
_ZN4PLMD3drr12DRRForceGrid7index1DERKNS0_7DRRAxisEd2407170
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.cpp.func.html b/coverage/drr/DRR.cpp.func.html new file mode 100644 index 000000000000..fa8d7505a408 --- /dev/null +++ b/coverage/drr/DRR.cpp.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33135593.2 %
Date:2024-02-22 21:58:45Functions:242596.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12DRRForceGrid5mergeERKSt6vectorINS0_7DRRAxisESaIS3_EES7_4
_ZN4PLMD3drr12DRRForceGrid5storeERKSt6vectorIdSaIdEES6_m1723
_ZN4PLMD3drr12DRRForceGrid7index1DERKNS0_7DRRAxisEd2407170
_ZN4PLMD3drr12DRRForceGrid9fillTableERKSt6vectorIS2_IdSaIdEESaIS4_EE34
_ZN4PLMD3drr12DRRForceGridC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb26
_ZN4PLMD3drr12DRRForceGridC2Ev38
_ZN4PLMD3drr3ABF11mergewindowERKS1_S3_2
_ZN4PLMD3drr3ABF13store_getbiasERKSt6vectorIdSaIdEES6_RS4_123
_ZN4PLMD3drr4CZAR11mergewindowERKS1_S3_2
_ZN4PLMD3drr7DRRAxis15getMiddlePointsEv60
_ZN4PLMD3drr7DRRAxis5mergeERKS1_S3_4
_ZNK4PLMD3drr12DRRForceGrid10write1DPMFENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKS7_26
_ZNK4PLMD3drr12DRRForceGrid11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr12DRRForceGrid12isInBoundaryERKSt6vectorIdSaIdEE393846
_ZNK4PLMD3drr12DRRForceGrid13getDivergenceERKSt6vectorIdSaIdEE64800
_ZNK4PLMD3drr12DRRForceGrid13sampleAddressERKSt6vectorIdSaIdEE1012383
_ZNK4PLMD3drr12DRRForceGrid15writeDivergenceERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_2
_ZNK4PLMD3drr12DRRForceGrid20getAccumulatedForcesERKSt6vectorIdSaIdEE1600
_ZNK4PLMD3drr12DRRForceGrid22getCountsLogDerivativeERKSt6vectorIdSaIdEE195576
_ZNK4PLMD3drr12DRRForceGrid8getCountERKSt6vectorIdSaIdEEb67612
_ZNK4PLMD3drr12DRRForceGrid8writeAllERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_b36
_ZNK4PLMD3drr4CZAR11getGradientERKSt6vectorIdSaIdEEb195576
_ZNK4PLMD3drr4CZAR16writeZCountZGradERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb18
_ZNK4PLMD3drr7DRRAxis12isInBoundaryEd0
_ZNK4PLMD3drr7DRRAxis14isRealPeriodicEv5860
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.cpp.gcov.html b/coverage/drr/DRR.cpp.gcov.html new file mode 100644 index 000000000000..751f51df61b9 --- /dev/null +++ b/coverage/drr/DRR.cpp.gcov.html @@ -0,0 +1,635 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33135593.2 %
Date:2024-02-22 21:58:45Functions:242596.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :     Copyright (c) 2017 of Haochuan Chen (excluding colvar_UIestimator.h)
+       3             :     Copyright (c) 2017 of Haohao Fu (colvar_UIestimator.h)
+       4             : 
+       5             :     This program is free software: you can redistribute it and/or modify
+       6             :     it under the terms of the GNU Lesser General Public License as published
+       7             :     by the Free Software Foundation, either version 3 of the License, or
+       8             :     (at your option) any later version.
+       9             : 
+      10             :     This program is distributed in the hope that it will be useful,
+      11             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
+      12             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      13             :     GNU Lesser General Public License for more details.
+      14             : 
+      15             :     You should have received a copy of the GNU Lesser General Public License
+      16             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+      17             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      18             : #ifdef __PLUMED_HAS_BOOST_SERIALIZATION
+      19             : #include "DRR.h"
+      20             : 
+      21             : namespace PLMD {
+      22             : namespace drr {
+      23             : 
+      24             : using std::vector;
+      25             : using std::string;
+      26             : using std::begin;
+      27             : using std::end;
+      28             : 
+      29           0 : bool DRRAxis::isInBoundary(double x) const {
+      30           0 :   if (x < min || x > max)
+      31             :     return false;
+      32             :   else
+      33           0 :     return true;
+      34             : }
+      35             : 
+      36        5860 : bool DRRAxis::isRealPeriodic() const {
+      37        5860 :   if (periodic == true) {
+      38        5808 :     if (std::abs(domainMax - max) < binWidth &&
+      39        5796 :         std::abs(domainMin - min) < binWidth) {
+      40             :       return true;
+      41             :     } else {
+      42          12 :       return false;
+      43             :     }
+      44             :   } else {
+      45             :     return false;
+      46             :   }
+      47             : }
+      48             : 
+      49           4 : DRRAxis DRRAxis::merge(const DRRAxis &d1, const DRRAxis &d2) {
+      50           4 :   const double newmin = std::min(d1.min, d2.min);
+      51           4 :   const double newmax = std::max(d1.max, d2.max);
+      52           4 :   const double newWidth = d1.binWidth;
+      53           4 :   const size_t newbins = size_t(std::nearbyint((newmax - newmin) / newWidth));
+      54           4 :   const bool newpbc = d1.periodic;
+      55           4 :   const double newdmin = std::min(d1.domainMin, d2.domainMin);
+      56           4 :   const double newdmax = std::max(d1.domainMax, d2.domainMax);
+      57             :   DRRAxis result(newmin, newmax, newbins, newpbc, newdmin, newdmax);
+      58           4 :   return result;
+      59             : }
+      60             : 
+      61          60 : vector<double> DRRAxis::getMiddlePoints() {
+      62          60 :   vector<double> result(nbins, 0);
+      63          60 :   const double width = binWidth;
+      64          60 :   double temp = min - width / 2;
+      65          60 :   std::generate(begin(result), end(result), [&temp, &width]() {
+      66        3382 :     temp += width;
+      67             :     return temp;
+      68             :   });
+      69          60 :   return result;
+      70             : }
+      71             : 
+      72     2407170 : size_t DRRForceGrid::index1D(const DRRAxis &c, double x) {
+      73     2407170 :   size_t idx = size_t(std::floor((x - c.min) / c.binWidth));
+      74     2407170 :   idx = (idx == c.nbins) ? (c.nbins - 1) : idx;
+      75     2407170 :   return idx;
+      76             : }
+      77             : 
+      78          34 : void DRRForceGrid::fillTable(const vector<vector<double>> &in) {
+      79          34 :   table.resize(ndims, vector<double>(sampleSize, 0));
+      80          82 :   for (size_t i = 0; i < ndims; ++i) {
+      81             :     size_t repeatAll = 1, repeatOne = 1;
+      82          62 :     for (size_t j = i + 1; j < ndims; ++j)
+      83          14 :       repeatOne *= in[j].size();
+      84          62 :     for (size_t j = 0; j < i; ++j)
+      85          14 :       repeatAll *= in[j].size();
+      86             :     size_t in_i_sz = in[i].size();
+      87        3390 :     for (size_t l = 0; l < in_i_sz; ++l)
+      88        3342 :       std::fill_n(begin(table[i]) + l * repeatOne, repeatOne, in[i][l]);
+      89         784 :     for (size_t k = 0; k < repeatAll - 1; ++k)
+      90         736 :       std::copy_n(begin(table[i]), repeatOne * in_i_sz,
+      91         736 :                   begin(table[i]) + repeatOne * in_i_sz * (k + 1));
+      92             :   }
+      93          34 : }
+      94             : 
+      95          38 : DRRForceGrid::DRRForceGrid()
+      96          38 :   : suffix(""), ndims(0), dimensions(0), sampleSize(0),
+      97          38 :     headers(""), table(0), forces(0), samples(0), endpoints(0), shifts(0),
+      98          76 :     outputunit(1.0) {}
+      99             : 
+     100          26 : DRRForceGrid::DRRForceGrid(const vector<DRRAxis> &p_dimensions,
+     101          26 :                            const string &p_suffix, bool initializeTable)
+     102          26 :   : suffix(p_suffix), ndims(p_dimensions.size()), dimensions(p_dimensions) {
+     103          26 :   sampleSize = 1;
+     104          26 :   vector<vector<double>> mp(ndims);
+     105          26 :   std::stringstream ss;
+     106          26 :   ss << "# " << ndims << '\n';
+     107          26 :   shifts.resize(ndims, 0);
+     108          26 :   shifts[0] = 1;
+     109          64 :   for (size_t i = 0; i < ndims; ++i) {
+     110          38 :     sampleSize = dimensions[i].nbins * sampleSize;
+     111          38 :     mp[i] = dimensions[i].getMiddlePoints();
+     112          38 :     if (i > 0) {
+     113          12 :       shifts[i] = shifts[i - 1] * dimensions[i - 1].nbins;
+     114             :     }
+     115             :     ss.precision(std::numeric_limits<double>::max_digits10);
+     116          76 :     ss << std::fixed << "# " << dimensions[i].min << ' '
+     117          76 :        << dimensions[i].binWidth << ' ' << dimensions[i].nbins;
+     118          38 :     if (dimensions[i].isPeriodic())
+     119          56 :       ss << " 1" << '\n';
+     120             :     else
+     121          20 :       ss << " 0" << '\n';
+     122             :   }
+     123          26 :   headers = ss.str();
+     124          26 :   if (initializeTable)
+     125          18 :     fillTable(mp);
+     126          26 :   forces.resize(sampleSize * ndims, 0.0);
+     127          26 :   samples.resize(sampleSize, 0);
+     128          26 :   outputunit = 1.0;
+     129             :   // For 1D pmf
+     130          26 :   if (ndims == 1) {
+     131          14 :     endpoints.resize(dimensions[0].nbins + 1, 0);
+     132          14 :     double ep = dimensions[0].min;
+     133          14 :     double stride = dimensions[0].binWidth;
+     134         882 :     for (auto &i : endpoints) {
+     135         868 :       i = ep;
+     136         868 :       ep += stride;
+     137             :     }
+     138             :   }
+     139          26 : }
+     140             : 
+     141      393846 : bool DRRForceGrid::isInBoundary(const vector<double> &pos) const {
+     142             :   bool result = true;
+     143     1175042 :   for (size_t i = 0; i < ndims; ++i) {
+     144      782805 :     if (pos[i] < dimensions[i].min || pos[i] > dimensions[i].max)
+     145             :       return false;
+     146             :   }
+     147             :   return result;
+     148             : }
+     149             : 
+     150     1012383 : size_t DRRForceGrid::sampleAddress(const vector<double> &pos) const {
+     151             :   size_t saddr = 0;
+     152     3029541 :   for (size_t i = 0; i < ndims; ++i) {
+     153     2017158 :     saddr += shifts[i] * index1D(dimensions[i], pos[i]);
+     154             :   }
+     155     1012383 :   return saddr;
+     156             : }
+     157             : 
+     158        1723 : bool DRRForceGrid::store(const vector<double> &pos, const vector<double> &f,
+     159             :                          unsigned long int nsamples) {
+     160        1723 :   if (isInBoundary(pos)) {
+     161        1714 :     if (nsamples == 0)
+     162             :       return true;
+     163         914 :     const size_t baseaddr = sampleAddress(pos);
+     164         914 :     samples[baseaddr] += nsamples;
+     165         914 :     auto it_fa = begin(forces) + baseaddr * ndims;
+     166         914 :     std::transform(begin(f), end(f), it_fa, it_fa, std::plus<double>());
+     167         914 :     return true;
+     168             :   } else {
+     169             :     return false;
+     170             :   }
+     171             : }
+     172             : 
+     173           4 : vector<DRRAxis> DRRForceGrid::merge(const vector<DRRAxis> &dA,
+     174             :                                     const vector<DRRAxis> &dB) {
+     175           4 :   vector<DRRAxis> dR(dA.size());
+     176           4 :   std::transform(begin(dA), end(dA), begin(dB), begin(dR), DRRAxis::merge);
+     177           4 :   return dR;
+     178             : }
+     179             : 
+     180             : vector<double>
+     181        1600 : DRRForceGrid::getAccumulatedForces(const vector<double> &pos) const {
+     182        1600 :   vector<double> result(ndims, 0);
+     183        1600 :   if (!isInBoundary(pos))
+     184             :     return result;
+     185         800 :   const size_t force_addr = sampleAddress(pos) * ndims;
+     186         800 :   std::copy(begin(forces) + force_addr, begin(forces) + force_addr + ndims,
+     187             :             begin(result));
+     188         800 :   return result;
+     189             : }
+     190             : 
+     191       67612 : unsigned long int DRRForceGrid::getCount(const vector<double> &pos,
+     192             :     bool SkipCheck) const {
+     193       67612 :   if (!SkipCheck) {
+     194        1600 :     if (!isInBoundary(pos)) {
+     195             :       return 0;
+     196             :     }
+     197             :   }
+     198       66812 :   return samples[sampleAddress(pos)];
+     199             : }
+     200             : 
+     201      195576 : vector<double> DRRForceGrid::getGradient(const vector<double> &pos,
+     202             :     bool SkipCheck) const {
+     203      195576 :   vector<double> result(ndims, 0);
+     204      195576 :   if (!SkipCheck) {
+     205      162000 :     if (!isInBoundary(pos)) {
+     206             :       return result;
+     207             :     }
+     208             :   }
+     209      195576 :   const size_t baseaddr = sampleAddress(pos);
+     210             :   const unsigned long int &count = samples[baseaddr];
+     211      195576 :   if (count == 0)
+     212             :     return result;
+     213      195411 :   auto it_fa = begin(forces) + baseaddr * ndims;
+     214      195411 :   std::transform(it_fa, it_fa + ndims, begin(result),
+     215      389802 :   [&count](double fa) { return (-1.0) * fa / count; });
+     216      195411 :   return result;
+     217             : }
+     218             : 
+     219       64800 : double DRRForceGrid::getDivergence(const vector<double> &pos) const {
+     220             :   double div = 0.0;
+     221       64800 :   vector<double> grad_deriv(ndims, 0.0);
+     222       64800 :   if (!isInBoundary(pos)) {
+     223             :     return div;
+     224             :   }
+     225       64800 :   const size_t force_addr = sampleAddress(pos) * ndims;
+     226       64800 :   vector<double> grad = getGradient(pos);
+     227      194400 :   for (size_t i = 0; i < ndims; ++i) {
+     228      129600 :     const double binWidth = dimensions[i].binWidth;
+     229      129600 :     vector<double> first = pos;
+     230      129600 :     first[i] = dimensions[i].min + binWidth * 0.5;
+     231      129600 :     vector<double> last = pos;
+     232      129600 :     last[i] = dimensions[i].max - binWidth * 0.5;
+     233      129600 :     const size_t force_addr_first = sampleAddress(first) * ndims;
+     234      129600 :     const size_t force_addr_last = sampleAddress(last) * ndims;
+     235      129600 :     if (force_addr == force_addr_first) {
+     236         720 :       if (dimensions[i].isRealPeriodic() == true) {
+     237         720 :         vector<double> next = pos;
+     238         720 :         next[i] += binWidth;
+     239         720 :         const vector<double> grad_next = getGradient(next);
+     240         720 :         const vector<double> grad_prev = getGradient(last);
+     241         720 :         grad_deriv[i] = (grad_next[i] - grad_prev[i]) / (2.0 * binWidth);
+     242             :       } else {
+     243           0 :         vector<double> next = pos;
+     244           0 :         next[i] += binWidth;
+     245           0 :         vector<double> next_2 = next;
+     246           0 :         next_2[i] += binWidth;
+     247           0 :         const vector<double> grad_next = getGradient(next);
+     248           0 :         const vector<double> grad_next_2 = getGradient(next_2);
+     249           0 :         grad_deriv[i] =
+     250           0 :           (grad_next_2[i] * -1.0 + grad_next[i] * 4.0 - grad[i] * 3.0) /
+     251           0 :           (2.0 * binWidth);
+     252             :       }
+     253      128880 :     } else if (force_addr == force_addr_last) {
+     254         720 :       if (dimensions[i].isRealPeriodic() == true) {
+     255         720 :         vector<double> prev = pos;
+     256         720 :         prev[i] -= binWidth;
+     257         720 :         const vector<double> grad_next = getGradient(first);
+     258         720 :         const vector<double> grad_prev = getGradient(prev);
+     259         720 :         grad_deriv[i] = (grad_next[i] - grad_prev[i]) / (2.0 * binWidth);
+     260             :       } else {
+     261           0 :         vector<double> prev = pos;
+     262           0 :         prev[i] -= binWidth;
+     263           0 :         vector<double> prev_2 = prev;
+     264           0 :         prev_2[i] -= binWidth;
+     265           0 :         const vector<double> grad_prev = getGradient(prev);
+     266           0 :         const vector<double> grad_prev_2 = getGradient(prev_2);
+     267           0 :         grad_deriv[i] =
+     268           0 :           (grad[i] * 3.0 - grad_prev[i] * 4.0 + grad_prev_2[i] * 1.0) /
+     269           0 :           (2.0 * binWidth);
+     270             :       }
+     271             :     } else {
+     272      128160 :       vector<double> prev = pos;
+     273      128160 :       prev[i] -= binWidth;
+     274      128160 :       vector<double> next = pos;
+     275      128160 :       next[i] += binWidth;
+     276      128160 :       const vector<double> grad_next = getGradient(next);
+     277      128160 :       const vector<double> grad_prev = getGradient(prev);
+     278      128160 :       grad_deriv[i] = (grad_next[i] - grad_prev[i]) / (2.0 * binWidth);
+     279             :     }
+     280             :   }
+     281             :   div = std::accumulate(begin(grad_deriv), end(grad_deriv), 0.0);
+     282             :   return div;
+     283             : }
+     284             : 
+     285             : vector<double>
+     286      195576 : DRRForceGrid::getCountsLogDerivative(const vector<double> &pos) const {
+     287      195576 :   const size_t addr = sampleAddress(pos);
+     288      195576 :   const unsigned long int count_this = samples[addr];
+     289      195576 :   vector<double> result(ndims, 0);
+     290      585588 :   for (size_t i = 0; i < ndims; ++i) {
+     291      390012 :     const double binWidth = dimensions[i].binWidth;
+     292             :     const size_t addr_first =
+     293      390012 :       addr - shifts[i] * index1D(dimensions[i], pos[i]) + 0;
+     294      390012 :     const size_t addr_last = addr_first + shifts[i] * (dimensions[i].nbins - 1);
+     295      390012 :     if (addr == addr_first) {
+     296        2210 :       if (dimensions[i].isRealPeriodic() == true) {
+     297        2178 :         const unsigned long int &count_next = samples[addr + shifts[i]];
+     298             :         const unsigned long int &count_prev = samples[addr_last];
+     299        2178 :         if (count_next != 0 && count_prev != 0)
+     300        2160 :           result[i] =
+     301        2160 :             (std::log(count_next) - std::log(count_prev)) / (2 * binWidth);
+     302             :       } else {
+     303          32 :         const unsigned long int &count_next = samples[addr + shifts[i]];
+     304          32 :         const unsigned long int &count_next2 = samples[addr + shifts[i] * 2];
+     305          32 :         if (count_next != 0 && count_this != 0 && count_next2 != 0)
+     306           6 :           result[i] =
+     307           6 :             (std::log(count_next2) * (-1.0) + std::log(count_next) * 4.0 -
+     308           6 :              std::log(count_this) * 3.0) /
+     309           6 :             (2.0 * binWidth);
+     310             :       }
+     311      387802 :     } else if (addr == addr_last) {
+     312        2210 :       if (dimensions[i].isRealPeriodic() == true) {
+     313        2178 :         const unsigned long int &count_prev = samples[addr - shifts[i]];
+     314             :         const unsigned long int &count_next = samples[addr_first];
+     315        2178 :         if (count_next != 0 && count_prev != 0)
+     316        2160 :           result[i] =
+     317        2160 :             (std::log(count_next) - std::log(count_prev)) / (2 * binWidth);
+     318             :       } else {
+     319          32 :         const unsigned long int &count_prev = samples[addr - shifts[i]];
+     320          32 :         const unsigned long int &count_prev2 = samples[addr - shifts[i] * 2];
+     321          32 :         if (count_prev != 0 && count_this != 0 && count_prev2 != 0)
+     322           6 :           result[i] = (std::log(count_this) * 3.0 - std::log(count_prev) * 4.0 +
+     323           6 :                        std::log(count_prev2)) /
+     324           6 :                       (2.0 * binWidth);
+     325             :       }
+     326             :     } else {
+     327      385592 :       const unsigned long int &count_prev = samples[addr - shifts[i]];
+     328      385592 :       const unsigned long int &count_next = samples[addr + shifts[i]];
+     329      385592 :       if (count_next != 0 && count_prev != 0)
+     330      385432 :         result[i] =
+     331      385432 :           (std::log(count_next) - std::log(count_prev)) / (2 * binWidth);
+     332             :     }
+     333             :   }
+     334      195576 :   return result;
+     335             : }
+     336             : 
+     337          26 : void DRRForceGrid::write1DPMF(string filename, const string &fmt) const {
+     338          26 :   filename += suffix + ".pmf";
+     339          52 :   std::string fmtv=fmt+" "+fmt+"\n";
+     340             :   FILE *ppmf;
+     341          26 :   ppmf = fopen(filename.c_str(), "w");
+     342          26 :   const double w = dimensions[0].binWidth;
+     343             :   double pmf = 0;
+     344          26 :   fprintf(ppmf, fmtv.c_str(), endpoints[0], pmf);
+     345        1166 :   for (size_t i = 0; i < dimensions[0].nbins; ++i) {
+     346        1140 :     vector<double> pos(1, 0);
+     347        1140 :     pos[0] = table[0][i];
+     348        1140 :     const vector<double> f = getGradient(pos, true);
+     349        1140 :     pmf += f[0] * w / outputunit;
+     350        1140 :     fprintf(ppmf, fmtv.c_str(), endpoints[i + 1], pmf);
+     351             :   }
+     352          26 :   fclose(ppmf);
+     353          26 : }
+     354             : 
+     355          36 : void DRRForceGrid::writeAll(const string &filename, const string &fmt, bool addition) const {
+     356          36 :   const std::string countname = filename + suffix + ".count";
+     357          36 :   const std::string gradname = filename + suffix + ".grad";
+     358          36 :   std::string fmtv=" "+fmt;
+     359          36 :   vector<double> pos(ndims, 0);
+     360             :   FILE *pGrad, *pCount;
+     361          36 :   if (addition) {
+     362           8 :     pGrad = fopen(gradname.c_str(), "a");
+     363           8 :     pCount = fopen(countname.c_str(), "a");
+     364             :   } else {
+     365          28 :     pGrad = fopen(gradname.c_str(), "w");
+     366          28 :     pCount = fopen(countname.c_str(), "w");
+     367             :   }
+     368             : 
+     369             :   char *buffer1, *buffer2;
+     370          36 :   buffer1 = (char *)malloc((sizeof(double)) * sampleSize * ndims);
+     371          36 :   buffer2 = (char *)malloc((sizeof(double)) * sampleSize * ndims);
+     372          36 :   setvbuf(pGrad, buffer1, _IOFBF, (sizeof(double)) * sampleSize * ndims);
+     373          36 :   setvbuf(pCount, buffer2, _IOFBF, (sizeof(double)) * sampleSize * ndims);
+     374          36 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pGrad);
+     375          36 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pCount);
+     376       66048 :   for (size_t i = 0; i < sampleSize; ++i) {
+     377      196896 :     for (size_t j = 0; j < ndims; ++j) {
+     378      130884 :       pos[j] = table[j][i];
+     379      130884 :       fprintf(pGrad, fmtv.c_str(), table[j][i]);
+     380      130884 :       fprintf(pCount, fmtv.c_str(), table[j][i]);
+     381             :     }
+     382       66012 :     fprintf(pCount, " %lu\n", getCount(pos, true));
+     383       66012 :     vector<double> f = getGradient(pos, true);
+     384      196896 :     for (size_t j = 0; j < ndims; ++j) {
+     385      130884 :       fprintf(pGrad, fmtv.c_str(), (f[j] / outputunit));
+     386             :     }
+     387             :     fprintf(pGrad, "\n");
+     388             :   }
+     389          36 :   fclose(pGrad);
+     390          36 :   fclose(pCount);
+     391          36 :   free(buffer1);
+     392          36 :   free(buffer2);
+     393          36 :   if (ndims == 1) {
+     394          52 :     write1DPMF(filename, fmt);
+     395             :   }
+     396          36 : }
+     397             : 
+     398           2 : void DRRForceGrid::writeDivergence(const string &filename, const string &fmt) const {
+     399           2 :   const string divname = filename + suffix + ".div";
+     400           2 :   std::string fmtv=" "+fmt;
+     401           2 :   vector<double> pos(ndims, 0);
+     402             :   FILE *pDiv;
+     403           2 :   pDiv = fopen(divname.c_str(), "w");
+     404           2 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pDiv);
+     405       64802 :   for (size_t i = 0; i < sampleSize; ++i) {
+     406      194400 :     for (size_t j = 0; j < ndims; ++j) {
+     407      129600 :       pos[j] = table[j][i];
+     408      129600 :       fprintf(pDiv, fmtv.c_str(), table[j][i]);
+     409             :     }
+     410       64800 :     const double divergence = getDivergence(pos);
+     411       64800 :     fprintf(pDiv, fmtv.c_str(), (divergence / outputunit));
+     412             :     fprintf(pDiv, "\n");
+     413             :   }
+     414           2 :   fclose(pDiv);
+     415           2 : }
+     416             : 
+     417         123 : bool ABF::store_getbias(const vector<double> &pos, const vector<double> &f,
+     418             :                         vector<double> &fbias) {
+     419         123 :   if (!isInBoundary(pos)) {
+     420             :     std::fill(begin(fbias), end(fbias), 0.0);
+     421             :     return false;
+     422             :   }
+     423         123 :   const size_t baseaddr = sampleAddress(pos);
+     424             :   unsigned long int &count = samples[baseaddr];
+     425         123 :   ++count;
+     426         123 :   double factor = 2 * (static_cast<double>(count)) / mFullSamples - 1;
+     427         123 :   auto it_fa = begin(forces) + baseaddr * ndims;
+     428             :   auto it_fb = begin(fbias);
+     429             :   auto it_f = begin(f);
+     430             :   auto it_maxFactor = begin(mMaxFactors);
+     431             :   do {
+     432             :     // Clamp to [0,maxFactors]
+     433         207 :     factor = factor < 0 ? 0 : factor > (*it_maxFactor) ? (*it_maxFactor) : factor;
+     434         207 :     (*it_fa) += (*it_f); // Accumulate instantaneous force
+     435         207 :     (*it_fb) = factor * (*it_fa) * (-1.0) /
+     436         207 :                static_cast<double>(count); // Calculate bias force
+     437             :     ++it_fa;
+     438             :     ++it_fb;
+     439             :     ++it_f;
+     440             :     ++it_maxFactor;
+     441         207 :   } while (it_f != end(f));
+     442             : 
+     443             :   return true;
+     444             : }
+     445             : 
+     446           2 : ABF ABF::mergewindow(const ABF &aWA, const ABF &aWB) {
+     447           2 :   const vector<DRRAxis> dR = merge(aWA.dimensions, aWB.dimensions);
+     448           2 :   const string suffix = ".abf";
+     449           2 :   ABF result(dR, suffix);
+     450           2 :   const size_t nrows = result.sampleSize;
+     451           2 :   const size_t ncols = result.ndims;
+     452           2 :   vector<double> pos(ncols, 0);
+     453         402 :   for (size_t i = 0; i < nrows; ++i) {
+     454         800 :     for (size_t j = 0; j < ncols; ++j) {
+     455         400 :       pos[j] = result.table[j][i];
+     456             :     }
+     457         400 :     const unsigned long int countA = aWA.getCount(pos);
+     458         400 :     const unsigned long int countB = aWB.getCount(pos);
+     459         400 :     const vector<double> aForceA = aWA.getAccumulatedForces(pos);
+     460         400 :     const vector<double> aForceB = aWB.getAccumulatedForces(pos);
+     461         400 :     result.store(pos, aForceA, countA);
+     462         400 :     result.store(pos, aForceB, countB);
+     463             :   }
+     464           2 :   return result;
+     465           0 : }
+     466             : 
+     467      195576 : vector<double> CZAR::getGradient(const vector<double> &pos,
+     468             :                                  bool SkipCheck) const {
+     469      195576 :   vector<double> result(ndims, 0);
+     470      195576 :   if (!SkipCheck) {
+     471      162000 :     if (!isInBoundary(pos)) {
+     472             :       return result;
+     473             :     }
+     474             :   }
+     475      195576 :   if (kbt <= std::numeric_limits<double>::epsilon()) {
+     476             :     std::cerr << "ERROR! The kbt shouldn't be zero when use CZAR estimator. "
+     477           0 :               << '\n';
+     478           0 :     std::abort();
+     479             :   }
+     480      195576 :   const size_t baseaddr = sampleAddress(pos);
+     481      195576 :   const vector<double> log_deriv(getCountsLogDerivative(pos));
+     482             :   const unsigned long int &count = samples[baseaddr];
+     483      195576 :   if (count == 0)
+     484             :     return result;
+     485      195421 :   auto it_fa = begin(forces) + baseaddr * ndims;
+     486      195421 :   std::transform(it_fa, it_fa + ndims, begin(log_deriv), begin(result),
+     487      389822 :   [&count, this](double fa, double ld) {
+     488      389822 :     return fa * (-1.0) / count - kbt * ld;
+     489             :   });
+     490      195421 :   return result;
+     491             : }
+     492             : 
+     493           2 : CZAR CZAR::mergewindow(const CZAR &cWA, const CZAR &cWB) {
+     494           2 :   const vector<DRRAxis> dR = merge(cWA.dimensions, cWB.dimensions);
+     495           2 :   const double newkbt = cWA.kbt;
+     496           2 :   const string suffix = ".czar";
+     497             :   CZAR result(dR, suffix, newkbt);
+     498           2 :   const size_t nrows = result.sampleSize;
+     499           2 :   const size_t ncols = result.ndims;
+     500           2 :   vector<double> pos(ncols, 0);
+     501         402 :   for (size_t i = 0; i < nrows; ++i) {
+     502         800 :     for (size_t j = 0; j < ncols; ++j) {
+     503         400 :       pos[j] = result.table[j][i];
+     504             :     }
+     505         400 :     const unsigned long int countA = cWA.getCount(pos);
+     506         400 :     const unsigned long int countB = cWB.getCount(pos);
+     507         400 :     const vector<double> aForceA = cWA.getAccumulatedForces(pos);
+     508         400 :     const vector<double> aForceB = cWB.getAccumulatedForces(pos);
+     509         400 :     result.store(pos, aForceA, countA);
+     510         400 :     result.store(pos, aForceB, countB);
+     511             :   }
+     512           2 :   return result;
+     513             : }
+     514             : 
+     515          18 : void CZAR:: writeZCountZGrad(const string &filename, bool addition) const {
+     516          18 :   const string countname = filename + ".zcount";
+     517          18 :   const string gradname = filename + ".zgrad";
+     518          18 :   vector<double> pos(ndims, 0);
+     519             :   FILE *pCount;
+     520             :   FILE *pGrad;
+     521          18 :   if (addition) {
+     522           4 :     pCount = fopen(countname.c_str(), "a");
+     523           4 :     pGrad = fopen(gradname.c_str(), "a");
+     524             :   } else {
+     525          14 :     pCount = fopen(countname.c_str(), "w");
+     526          14 :     pGrad = fopen(gradname.c_str(), "w");
+     527             :   }
+     528          18 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pCount);
+     529          18 :   fwrite(headers.c_str(), sizeof(char), strlen(headers.c_str()), pGrad);
+     530       33024 :   for (size_t i = 0; i < sampleSize; ++i) {
+     531       98448 :     for (size_t j = 0; j < ndims; ++j) {
+     532       65442 :       pos[j] = table[j][i];
+     533       65442 :       fprintf(pCount, " %.9f", table[j][i]);
+     534       65442 :       fprintf(pGrad, " %.9f", table[j][i]);
+     535             :     }
+     536       33006 :     const size_t baseaddr = sampleAddress(pos);
+     537             :     const auto& current_sample = samples[baseaddr];
+     538       33006 :     fprintf(pCount, " %lu\n", current_sample);
+     539       33006 :     if (current_sample == 0) {
+     540         195 :       for (size_t j = 0; j < ndims; ++j) {
+     541             :         fprintf(pGrad, " %.9f", 0.0);
+     542             :       }
+     543             :     } else {
+     544       98253 :       for (size_t j = 0; j < ndims; ++j) {
+     545       65332 :         const double grad = -1.0 * forces[baseaddr * ndims + j] / current_sample;
+     546       65332 :         fprintf(pGrad, " %.9f", grad / outputunit);
+     547             :       }
+     548             :     }
+     549             :     fprintf(pGrad, "\n");
+     550             :   }
+     551          18 :   fclose(pCount);
+     552          18 :   fclose(pGrad);
+     553          18 : }
+     554             : 
+     555             : }
+     556             : }
+     557             : 
+     558             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.h.func-sort-c.html b/coverage/drr/DRR.h.func-sort-c.html new file mode 100644 index 000000000000..5194c7e08b71 --- /dev/null +++ b/coverage/drr/DRR.h.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9999100.0 %
Date:2024-02-22 21:58:45Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12DRRForceGridD0Ev0
_ZN4PLMD3drr3ABFD0Ev0
_ZN4PLMD3drr4CZARD0Ev0
_ZN4PLMD3drr3ABFC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEddb2
_ZN4PLMD3drr4CZARD2Ev6
_ZN4PLMD3drr4CZAR9serializeIN5boost7archive15binary_iarchiveEEEvRT_j8
_ZN4PLMD3drr3ABFC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdRKS2_IdSaIdEEb11
_ZN4PLMD3drr12DRRForceGrid4loadIN5boost7archive15binary_iarchiveEEEvRT_j16
_ZN4PLMD3drr4CZAR9serializeIN5boost7archive15binary_oarchiveEEEvRT_j19
_ZN4PLMD3drr7DRRAxis4loadIN5boost7archive15binary_iarchiveEEEvRT_j22
_ZN4PLMD3drr3ABFD2Ev38
_ZNK4PLMD3drr12DRRForceGrid4saveIN5boost7archive15binary_oarchiveEEEvRT_j38
_ZNK4PLMD3drr7DRRAxis4saveIN5boost7archive15binary_oarchiveEEEvRT_j52
_ZN4PLMD3drr12DRRForceGridD2Ev76
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.h.func.html b/coverage/drr/DRR.h.func.html new file mode 100644 index 000000000000..094df9898020 --- /dev/null +++ b/coverage/drr/DRR.h.func.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9999100.0 %
Date:2024-02-22 21:58:45Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12DRRForceGrid4loadIN5boost7archive15binary_iarchiveEEEvRT_j16
_ZN4PLMD3drr12DRRForceGridD0Ev0
_ZN4PLMD3drr12DRRForceGridD2Ev76
_ZN4PLMD3drr3ABFC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdRKS2_IdSaIdEEb11
_ZN4PLMD3drr3ABFC2ERKSt6vectorINS0_7DRRAxisESaIS3_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEddb2
_ZN4PLMD3drr3ABFD0Ev0
_ZN4PLMD3drr3ABFD2Ev38
_ZN4PLMD3drr4CZAR9serializeIN5boost7archive15binary_iarchiveEEEvRT_j8
_ZN4PLMD3drr4CZAR9serializeIN5boost7archive15binary_oarchiveEEEvRT_j19
_ZN4PLMD3drr4CZARD0Ev0
_ZN4PLMD3drr4CZARD2Ev6
_ZN4PLMD3drr7DRRAxis4loadIN5boost7archive15binary_iarchiveEEEvRT_j22
_ZNK4PLMD3drr12DRRForceGrid4saveIN5boost7archive15binary_oarchiveEEEvRT_j38
_ZNK4PLMD3drr7DRRAxis4saveIN5boost7archive15binary_oarchiveEEEvRT_j52
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DRR.h.gcov.html b/coverage/drr/DRR.h.gcov.html new file mode 100644 index 000000000000..561b9211de41 --- /dev/null +++ b/coverage/drr/DRR.h.gcov.html @@ -0,0 +1,435 @@ + + + + + + + + LCOV - plumed test coverage - drr/DRR.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DRR.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9999100.0 %
Date:2024-02-22 21:58:45Functions:111478.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :     Copyright (c) 2017 of Haochuan Chen (excluding colvar_UIestimator.h)
+       3             :     Copyright (c) 2017 of Haohao Fu (colvar_UIestimator.h)
+       4             : 
+       5             :     This program is free software: you can redistribute it and/or modify
+       6             :     it under the terms of the GNU Lesser General Public License as published
+       7             :     by the Free Software Foundation, either version 3 of the License, or
+       8             :     (at your option) any later version.
+       9             : 
+      10             :     This program is distributed in the hope that it will be useful,
+      11             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
+      12             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      13             :     GNU Lesser General Public License for more details.
+      14             : 
+      15             :     You should have received a copy of the GNU Lesser General Public License
+      16             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+      17             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      18             : #ifndef __PLUMED_drr_DRR_h
+      19             : #define __PLUMED_drr_DRR_h
+      20             : // Build requirement: boost, c++11 compatible compiler.
+      21             : #ifdef __PLUMED_HAS_BOOST_SERIALIZATION
+      22             : 
+      23             : #include <algorithm>
+      24             : #include <cmath>
+      25             : #include <cstddef>
+      26             : #include <cstdlib>
+      27             : #include <fstream>
+      28             : #include <iomanip>
+      29             : #include <iostream>
+      30             : #include <iterator>
+      31             : #include <limits>
+      32             : #include <numeric>
+      33             : #include <sstream>
+      34             : 
+      35             : // boost headers for serialization
+      36             : #include <boost/archive/binary_iarchive.hpp>
+      37             : #include <boost/archive/binary_oarchive.hpp>
+      38             : #include <boost/serialization/string.hpp>
+      39             : #include <boost/serialization/vector.hpp>
+      40             : 
+      41             : namespace PLMD {
+      42             : namespace drr {
+      43             : 
+      44             : using std::vector;
+      45             : using std::string;
+      46             : using std::begin;
+      47             : using std::end;
+      48             : 
+      49             : /// This class can store the minimum, maximum and bins of a dimension(axis).
+      50             : class DRRAxis {
+      51             : public:
+      52             :   /// Default empty constructor
+      53          64 :   DRRAxis() {
+      54          64 :     min = max = 0.0;
+      55          64 :     nbins = 0;
+      56          64 :     periodic = false;
+      57          64 :     domainMax = domainMin = 0.0;
+      58          64 :     binWidth = 0.0;
+      59             :   }
+      60             :   /// Constructor using maximum value, minimum value and the number of bins(No
+      61             :   /// pbc)
+      62             :   DRRAxis(double l, double h, size_t n)
+      63             :     : min(l), max(h), nbins(n), periodic(false), domainMax(0), domainMin(0),
+      64             :       binWidth((max - min) / double(nbins)) {}
+      65             :   /// PBC-aware constructor
+      66             :   DRRAxis(double l, double h, size_t n, bool pbc, double dMax, double dMin)
+      67           4 :     : min(l), max(h), nbins(n), periodic(pbc), domainMax(dMax),
+      68           4 :       domainMin(dMin), binWidth((max - min) / double(nbins)) {}
+      69             :   /// Set values
+      70             :   void set(double l, double h, size_t n, bool pbc = false, double dmin = 0,
+      71             :            double dmax = 0) {
+      72          38 :     min = l;
+      73          38 :     max = h;
+      74          38 :     nbins = n;
+      75          38 :     periodic = pbc;
+      76          38 :     domainMax = dmax;
+      77          38 :     domainMin = dmin;
+      78          38 :     binWidth = (max - min) / nbins;
+      79             :   }
+      80             :   /// Set PBC data
+      81             :   void setPeriodicity(double dmin, double dmax) {
+      82          16 :     domainMax = dmax;
+      83          16 :     domainMin = dmin;
+      84          16 :     periodic = true;
+      85             :   }
+      86             :   /// Getters
+      87          41 :   double getMin() const { return this->min; }
+      88          40 :   double getMax() const { return this->max; }
+      89          31 :   double getWidth() const { return binWidth; }
+      90             :   double getDomainMax() const { return this->domainMax; }
+      91             :   double getDomainMin() const { return this->domainMin; }
+      92             :   size_t getBins() const { return this->nbins; }
+      93             : 
+      94             :   /// Check periodicity
+      95          60 :   bool isPeriodic() const { return this->periodic; }
+      96             :   /// Check real periodicity, i.e. the maximum == the domain maximum
+      97             :   bool isRealPeriodic() const;
+      98             : 
+      99             :   /// Check whether x is in this axis
+     100             :   bool isInBoundary(double x) const;
+     101             :   /// Get an array of middle points of each bins
+     102             :   vector<double> getMiddlePoints();
+     103             : 
+     104             :   /// Combine two axes if they share the same bin width.
+     105             :   static DRRAxis merge(const DRRAxis &d1, const DRRAxis &d2);
+     106             : 
+     107             :   friend class DRRForceGrid;
+     108             : 
+     109             : protected:
+     110             :   double min;       // Minimum value of the axis
+     111             :   double max;       // Maximum value of the axis
+     112             :   size_t nbins;     // Number of bins
+     113             :   bool periodic;    // Periodicity
+     114             :   double domainMax; // Maximum value of the CV domain
+     115             :   double domainMin; // Minimum value of the CV domain
+     116             :   friend class boost::serialization::access;
+     117             :   /// Use boost serialization
+     118             :   template <typename Archive>
+     119          52 :   void save(Archive &ar, const unsigned int version) const {
+     120          52 :     ar &min;
+     121          52 :     ar &max;
+     122          52 :     ar &nbins;
+     123          52 :     ar &periodic;
+     124          52 :     ar &domainMax;
+     125          52 :     ar &domainMin;
+     126          52 :   }
+     127             :   /// Split save and load. The bin width is calculated after initialization.
+     128             :   template <typename Archive>
+     129          22 :   void load(Archive &ar, const unsigned int version) {
+     130          22 :     ar &min;
+     131          22 :     ar &max;
+     132          22 :     ar &nbins;
+     133          22 :     ar &periodic;
+     134          22 :     ar &domainMax;
+     135          22 :     ar &domainMin;
+     136          22 :     binWidth = (max - min) / double(nbins);
+     137          22 :   }
+     138             :   template <typename Archive>
+     139             :   void serialize(Archive &ar, const unsigned int version) {
+     140             :     boost::serialization::split_member(ar, *this, version);
+     141             :   }
+     142             : 
+     143             : private:
+     144             :   double binWidth; // bin width
+     145             : };
+     146             : 
+     147             : /// A class for collecting instantaneous forces, calculating average forces and
+     148             : /// build CV histogram.
+     149             : class DRRForceGrid {
+     150             : public:
+     151             :   /// Empty constructor
+     152             :   DRRForceGrid();
+     153             :   /// "Real" constructor
+     154             :   /// The 2D table vector is mainly used for print grid points in grad and count
+     155             :   /// file.
+     156             :   /// So when use binary output we can set initializeTable to false to save
+     157             :   /// memory.
+     158             :   explicit DRRForceGrid(const vector<DRRAxis> &p_dimensions,
+     159             :                         const string &p_suffix,
+     160             :                         bool initializeTable = true);
+     161             :   /// Check whether a point is in this grid
+     162             :   bool isInBoundary(const vector<double> &pos) const;
+     163             :   //  /// Get internal indices of a point
+     164             :   //  vector<size_t> index(const vector<double> &pos) const;
+     165             :   /// Get internal counts address of a point
+     166             :   size_t sampleAddress(const vector<double> &pos) const;
+     167             :   /// Store instantaneous forces of a point
+     168             :   /// nsamples > 1 is useful for merging windows
+     169             :   bool store(const vector<double> &pos, const vector<double> &f,
+     170             :              unsigned long int nsamples = 1);
+     171             :   /// Get accumulated forces of a point
+     172             :   vector<double>
+     173             :   getAccumulatedForces(const vector<double> &pos) const;
+     174             :   /// Get counts of a point
+     175             :   unsigned long int getCount(const vector<double> &pos,
+     176             :                              bool SkipCheck = false) const;
+     177             :   /// Virtual function! get gradients of a point
+     178             :   /// CZAR and naive(ABF) have different gradient formulae
+     179             :   virtual vector<double> getGradient(const vector<double> &pos,
+     180             :                                      bool SkipCheck = false) const;
+     181             :   /// Calculate divergence of the mean force field (experimental)
+     182             :   double getDivergence(const vector<double> &pos) const;
+     183             :   /// Calculate dln(Ï)/dz, useful for CZAR
+     184             :   /// This function may be moved to CZAR class in the future
+     185             :   vector<double>
+     186             :   getCountsLogDerivative(const vector<double> &pos) const;
+     187             :   /// Write grad file
+     188             : //   void writeGrad(string filename) const;
+     189             :   /// Write 1D pmf file on one dimensional occasion
+     190             :   void write1DPMF(string filename, const string &fmt="%.9f") const;
+     191             :   /// Write count file
+     192             : //   void writeCount(string filename) const;
+     193             :   /// Write necessary output file in one function (.grad and .count)
+     194             :   void writeAll(const string &filename, const string &fmt="%.9f", bool addition = false) const;
+     195             :   /// Output divergence (.div) (experimental)
+     196             :   void writeDivergence(const string &filename, const string &fmt="%.9f") const;
+     197             :   /// merge windows
+     198             :   static vector<DRRAxis> merge(const vector<DRRAxis> &dA,
+     199             :                                const vector<DRRAxis> &dB);
+     200             :   /// Get suffix
+     201             :   string getSuffix() const { return suffix; }
+     202             :   /// Set unit for .grad output
+     203           4 :   void setOutputUnit(double unit) { outputunit = unit; }
+     204             :   /// Destructor
+     205         228 :   virtual ~DRRForceGrid() {}
+     206             : 
+     207             : protected:
+     208             :   /// The output suffix appended before .grad(.czar.grad) and
+     209             :   /// .count(.czar.count)
+     210             :   string suffix;
+     211             :   /// Number of dimensions
+     212             :   size_t ndims;
+     213             :   /// Store each axes
+     214             :   vector<DRRAxis> dimensions;
+     215             :   /// Size of samples
+     216             :   size_t sampleSize;
+     217             :   /// The header lines of .grad and .count files
+     218             :   string headers;
+     219             :   /// A table stores the middle points of all dimensions.
+     220             :   /// For output in .grad and .count files
+     221             :   vector<vector<double>> table;
+     222             :   /// Store the average force of each bins
+     223             :   vector<double> forces;
+     224             :   /// Store counts of each bins
+     225             :   vector<unsigned long int> samples;
+     226             :   /// Only for 1D pmf output
+     227             :   vector<double> endpoints;
+     228             :   /// For faster indexing
+     229             :   /// shifts[0] = 1, shifts[n+1] = shifts[n] * dimensions[n].nbins
+     230             :   vector<size_t> shifts;
+     231             :   /// For set different output units
+     232             :   double outputunit;
+     233             : 
+     234             :   /// Miscellaneous helper functions
+     235             :   static size_t index1D(const DRRAxis &c, double x);
+     236             :   void fillTable(const vector<vector<double>> &in);
+     237             : 
+     238             :   /// Boost serialization functions
+     239             :   friend class boost::serialization::access;
+     240             :   template <class Archive>
+     241          38 :   void save(Archive &ar, const unsigned int version) const {
+     242             :     // Don't save all members.
+     243          38 :     ar << suffix;
+     244          38 :     ar << dimensions;
+     245          38 :     ar << forces;
+     246          38 :     ar << samples;
+     247          38 :   }
+     248          16 :   template <class Archive> void load(Archive &ar, const unsigned int version) {
+     249          16 :     ar >> suffix;
+     250          16 :     ar >> dimensions;
+     251          16 :     ar >> forces;
+     252          16 :     ar >> samples;
+     253             :     // Restore other members.
+     254          16 :     ndims = dimensions.size();
+     255          16 :     sampleSize = samples.size();
+     256          16 :     std::stringstream ss;
+     257          16 :     ss << "# " << ndims << '\n';
+     258          16 :     vector<vector<double>> mp(ndims);
+     259          16 :     shifts.resize(ndims, 0);
+     260          16 :     shifts[0] = 1;
+     261          38 :     for (size_t i = 0; i < ndims; ++i) {
+     262          22 :       mp[i] = dimensions[i].getMiddlePoints();
+     263          22 :       if (i > 0) {
+     264           6 :         shifts[i] = shifts[i - 1] * dimensions[i - 1].nbins;
+     265             :       }
+     266             :       ss.precision(std::numeric_limits<double>::max_digits10);
+     267          44 :       ss << std::fixed << "# " << dimensions[i].min << ' '
+     268          44 :          << dimensions[i].binWidth << ' ' << dimensions[i].nbins;
+     269          22 :       if (dimensions[i].isPeriodic())
+     270          24 :         ss << " 1" << '\n';
+     271             :       else
+     272          20 :         ss << " 0" << '\n';
+     273             :     }
+     274          16 :     fillTable(mp);
+     275          16 :     headers = ss.str();
+     276          16 :     outputunit = 1.0;
+     277             :     // For 1D pmf
+     278          16 :     if (ndims == 1) {
+     279          10 :       endpoints.resize(dimensions[0].nbins + 1, 0);
+     280          10 :       double ep = dimensions[0].min;
+     281          10 :       double stride = dimensions[0].binWidth;
+     282        1020 :       for (auto it = begin(endpoints); it != end(endpoints); ++it) {
+     283        1010 :         (*it) = ep;
+     284        1010 :         ep += stride;
+     285             :       }
+     286             :     }
+     287          16 :   }
+     288             :   template <typename Archive>
+     289             :   void serialize(Archive &ar, const unsigned int version) {
+     290             :     boost::serialization::split_member(ar, *this, version);
+     291             :   }
+     292             : };
+     293             : 
+     294             : class ABF : public DRRForceGrid {
+     295             : public:
+     296          16 :   ABF() {}
+     297           2 :   ABF(const vector<DRRAxis> &p_dimensions, const string &p_suffix,
+     298             :       double fullSamples = 500.0, double maxFactor = 1.0,
+     299             :       bool initializeTable = true)
+     300           2 :     : DRRForceGrid(p_dimensions, p_suffix, initializeTable),
+     301           2 :       mFullSamples(fullSamples), mMaxFactors(p_dimensions.size(), maxFactor) {}
+     302          11 :   ABF(const vector<DRRAxis> &p_dimensions, const string &p_suffix,
+     303             :       double fullSamples, const vector<double>& maxFactors,
+     304             :       bool initializeTable = true)
+     305          11 :     : DRRForceGrid(p_dimensions, p_suffix, initializeTable),
+     306          11 :       mFullSamples(fullSamples), mMaxFactors(maxFactors) {}
+     307             :   // Provide a setter for ABF parametres (fullsamples, maxfactor)
+     308             :   void setParameters(double fullSamples, const vector<double>& maxFactors) {
+     309           1 :     mFullSamples = fullSamples;
+     310           1 :     mMaxFactors = maxFactors;
+     311           1 :   }
+     312             :   // Store the "instantaneous" spring force of a point and get ABF bias forces.
+     313             :   bool store_getbias(const vector<double> &pos,
+     314             :                      const vector<double> &f,
+     315             :                      vector<double> &fbias);
+     316             :   static ABF mergewindow(const ABF &aWA, const ABF &aWB);
+     317          38 :   ~ABF() {}
+     318             : 
+     319             : private:
+     320             :   // Parametres for calculate bias force
+     321             :   double mFullSamples;
+     322             :   vector<double> mMaxFactors;
+     323             :   // Boost serialization
+     324             :   friend class boost::serialization::access;
+     325             :   template <typename Archive>
+     326             :   void serialize(Archive &ar, const unsigned int version) {
+     327          27 :     ar &boost::serialization::base_object<DRRForceGrid>(*this);
+     328             :   }
+     329             : };
+     330             : 
+     331          28 : class CZAR : public DRRForceGrid {
+     332             : public:
+     333          16 :   CZAR() : kbt(0) {}
+     334             :   CZAR(const vector<DRRAxis> &p_dimensions, const string &p_suffix,
+     335             :        double p_kbt, bool initializeTable = true)
+     336          13 :     : DRRForceGrid(p_dimensions, p_suffix, initializeTable), kbt(p_kbt) {}
+     337             :   vector<double> getGradient(const vector<double> &pos,
+     338             :                              bool SkipCheck = false) const;
+     339             :   double getkbt() const { return kbt; }
+     340             :   void setkbt(double p_kbt) { kbt = p_kbt; }
+     341             :   static CZAR mergewindow(const CZAR &cWA, const CZAR &cWB);
+     342             :   void writeZCountZGrad(const string &filename, bool addition = false) const;
+     343          23 :   ~CZAR() {}
+     344             : 
+     345             : private:
+     346             :   double kbt;
+     347             :   friend class boost::serialization::access;
+     348             :   template <typename Archive>
+     349          27 :   void serialize(Archive &ar, const unsigned int version) {
+     350          27 :     ar &boost::serialization::base_object<DRRForceGrid>(*this);
+     351          27 :     ar &kbt;
+     352          27 :   }
+     353             : };
+     354             : }
+     355             : }
+     356             : 
+     357             : #endif
+     358             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html b/coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html new file mode 100644 index 000000000000..fbc979a2465e --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - drr/DynamicReferenceRestraining.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DynamicReferenceRestraining.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40444391.2 %
Date:2024-02-22 21:58:45Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr27DynamicReferenceRestrainingC2ERKNS_13ActionOptionsE0
_ZN4PLMD3drr27DynamicReferenceRestraining10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr27DynamicReferenceRestraining13is_file_existEPKc1
_ZN4PLMD3drr27DynamicReferenceRestraining4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr27DynamicReferenceRestrainingC1ERKNS_13ActionOptionsE12
_ZN4PLMD3drr27DynamicReferenceRestraining16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3drr27DynamicReferenceRestraining4saveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx19
_ZN4PLMD3drr27DynamicReferenceRestraining6updateEv123
_ZN4PLMD3drr27DynamicReferenceRestraining9calculateEv123
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DynamicReferenceRestraining.cpp.func.html b/coverage/drr/DynamicReferenceRestraining.cpp.func.html new file mode 100644 index 000000000000..7e5cd2c8a5c6 --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - drr/DynamicReferenceRestraining.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DynamicReferenceRestraining.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40444391.2 %
Date:2024-02-22 21:58:45Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr27DynamicReferenceRestraining10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr27DynamicReferenceRestraining13is_file_existEPKc1
_ZN4PLMD3drr27DynamicReferenceRestraining16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3drr27DynamicReferenceRestraining4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD3drr27DynamicReferenceRestraining4saveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx19
_ZN4PLMD3drr27DynamicReferenceRestraining6updateEv123
_ZN4PLMD3drr27DynamicReferenceRestraining9calculateEv123
_ZN4PLMD3drr27DynamicReferenceRestrainingC1ERKNS_13ActionOptionsE12
_ZN4PLMD3drr27DynamicReferenceRestrainingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/DynamicReferenceRestraining.cpp.gcov.html b/coverage/drr/DynamicReferenceRestraining.cpp.gcov.html new file mode 100644 index 000000000000..2d1985bad02b --- /dev/null +++ b/coverage/drr/DynamicReferenceRestraining.cpp.gcov.html @@ -0,0 +1,969 @@ + + + + + + + + LCOV - plumed test coverage - drr/DynamicReferenceRestraining.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - DynamicReferenceRestraining.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40444391.2 %
Date:2024-02-22 21:58:45Functions:8988.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :     Copyright (c) 2017 of Haochuan Chen (excluding colvar_UIestimator.h)
+       3             :     Copyright (c) 2017 of Haohao Fu (colvar_UIestimator.h)
+       4             : 
+       5             :     This program is free software: you can redistribute it and/or modify
+       6             :     it under the terms of the GNU Lesser General Public License as published
+       7             :     by the Free Software Foundation, either version 3 of the License, or
+       8             :     (at your option) any later version.
+       9             : 
+      10             :     This program is distributed in the hope that it will be useful,
+      11             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
+      12             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      13             :     GNU Lesser General Public License for more details.
+      14             : 
+      15             :     You should have received a copy of the GNU Lesser General Public License
+      16             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+      17             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      18             : #ifdef __PLUMED_HAS_BOOST_SERIALIZATION
+      19             : #include "core/ActionRegister.h"
+      20             : #include "bias/Bias.h"
+      21             : #include "core/PlumedMain.h"
+      22             : #include "DRR.h"
+      23             : #include "tools/Random.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "colvar_UIestimator.h"
+      26             : 
+      27             : #include <boost/archive/binary_iarchive.hpp>
+      28             : #include <boost/archive/binary_oarchive.hpp>
+      29             : #include <boost/serialization/vector.hpp>
+      30             : #include <cmath>
+      31             : #include <fstream>
+      32             : #include <iomanip>
+      33             : #include <iostream>
+      34             : #include <limits>
+      35             : #include <random>
+      36             : #include <string>
+      37             : 
+      38             : using namespace PLMD;
+      39             : using namespace bias;
+      40             : using namespace std;
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace drr {
+      44             : 
+      45             : //+PLUMEDOC EABFMOD_BIAS DRR
+      46             : /*
+      47             : Used to performed extended-system adaptive biasing force(eABF)
+      48             : 
+      49             : This method was introduced in \cite Lelievre2007.  It is used
+      50             :  on one or more collective variables. This method is also
+      51             :  called dynamic reference restraining(DRR) \cite Zheng2012 . A detailed description
+      52             :  of this module can be found at \cite Chen2018 .
+      53             : 
+      54             : For each collective variable \f$\xi_i\f$, a fictitious variable \f$\lambda_i\f$
+      55             : is attached through a spring. The fictitious variable \f$\lambda_i\f$ undergoes
+      56             : overdamped Langevin dynamics just like \ref EXTENDED_LAGRANGIAN. The ABF
+      57             : algorithm applies bias force on \f$\lambda_i\f$. The bias force acts on
+      58             : \f$\lambda_i\f$ is the negative average spring force on \f$\lambda_i\f$, which
+      59             : enhances the sampling of \f$\lambda_i\f$.
+      60             : 
+      61             : \f[
+      62             : F_{bias}(\lambda_i)=k(\lambda_i-\langle\xi_i\rangle_{\lambda_i})
+      63             : \f]
+      64             : 
+      65             : If spring force constant k is large enough, then \f$\xi_i\f$ synchronizes with
+      66             : \f$\lambda_i\f$. The naive(ABF) estimator is just the negative
+      67             : average spring force of \f$\lambda_i\f$.
+      68             : 
+      69             : The naive(ABF) estimator is biased. There are unbiased estimators such as
+      70             : CZAR(Corrected z-averaged restraint) \cite Lesage2016 and UI(Umbrella
+      71             : Integration).
+      72             : The CZAR estimates the gradients as:
+      73             : 
+      74             : \f[
+      75             : \frac{\partial{A}}{\partial{\xi_i}}\left({\xi}\right)=-\frac{1}{\beta}\frac{\partial\ln\tilde{\rho}\left(\xi\right)}{\partial{\xi_i}}+k\left(\langle\lambda_i\rangle_\xi-\xi_i\right)
+      76             : \f]
+      77             : 
+      78             : The UI estimates the gradients as:
+      79             : \f[
+      80             : A'(\xi^*)=\frac{{\sum_\lambda}N\left(\xi^*,\lambda\right)\left[\frac{\xi^*-\langle\xi\rangle_\lambda}{\beta\sigma_\lambda^2}-k(\xi^*-\lambda)\right]}{{\sum_\lambda}N\left(\xi^*,\lambda\right)}
+      81             : \f]
+      82             : 
+      83             : The code performing UI(colvar_UIestimator.h) is contributed by Haohao Fu \cite Fu2016 .
+      84             : It may be slow. I only change the Boltzmann constant and output
+      85             : precision in it. For new version and issues, please see:
+      86             : https://github.com/fhh2626/colvars
+      87             : 
+      88             : After running eABF/DRR, the \ref drr_tool utility can be used to extract the gradients and counts files from .drrstate. Naive(ABF) estimator's result is in .abf.grad and .abf.count files and CZAR estimator's result is in .czar.grad and .czar.count files. The additional .zcount and .zgrad files contain the number of samples of \f$\boldsymbol{\xi}\f$, and the negative of \f$\boldsymbol{\xi}\f$-averaged spring forces, respectively, which are mainly for inspecting and debugging purpose. To get PMF, the abf_integrate(https://github.com/Colvars/colvars/tree/master/colvartools) is useful for numerically integrating the .czar.grad file.
+      89             : 
+      90             : \par Examples
+      91             : 
+      92             : The following input tells plumed to perform a eABF/DRR simulation on two
+      93             : torsional angles.
+      94             : \plumedfile
+      95             : phi: TORSION ATOMS=5,7,9,15
+      96             : psi: TORSION ATOMS=7,9,15,17
+      97             : 
+      98             : DRR ...
+      99             : LABEL=eabf
+     100             : ARG=phi,psi
+     101             : FULLSAMPLES=500
+     102             : GRID_MIN=-pi,-pi
+     103             : GRID_MAX=pi,pi
+     104             : GRID_BIN=180,180
+     105             : FRICTION=8.0,8.0
+     106             : TAU=0.5,0.5
+     107             : OUTPUTFREQ=50000
+     108             : HISTORYFREQ=500000
+     109             : ... DRR
+     110             : 
+     111             : # monitor the two variables, their fictitious variables and applied forces.
+     112             : PRINT STRIDE=10 ARG=phi,psi,eabf.phi_fict,eabf.psi_fict,eabf.phi_biasforce,eabf.psi_biasforce FILE=COLVAR
+     113             : \endplumedfile
+     114             : 
+     115             : The following input tells plumed to perform a eABF/DRR simulation on the
+     116             : distance of atom 10 and 92. The distance is restraint by \ref LOWER_WALLS and
+     117             : \ref UPPER_WALLS.
+     118             : \plumedfile
+     119             : dist1: DISTANCE ATOMS=10,92
+     120             : eabf_winall: DRR ARG=dist1 FULLSAMPLES=2000 GRID_MIN=1.20 GRID_MAX=3.20 GRID_BIN=200 FRICTION=8.0 TAU=0.5 OUTPUTFREQ=5000 HISTORYFREQ=500000
+     121             : uwall: UPPER_WALLS ARG=eabf_winall.dist1_fict AT=3.2 KAPPA=418.4
+     122             : lwall: LOWER_WALLS ARG=eabf_winall.dist1_fict AT=1.2 KAPPA=418.4
+     123             : PRINT STRIDE=10 ARG=dist1,eabf_winall.dist1_fict,eabf_winall.dist1_biasforce FILE=COLVAR
+     124             : \endplumedfile
+     125             : 
+     126             : It's also possible to run extended generalized adaptive biasing force (egABF) described in \cite Zhao2017 .
+     127             : An egABF example:
+     128             : \plumedfile
+     129             : phi: TORSION ATOMS=5,7,9,15
+     130             : psi: TORSION ATOMS=7,9,15,17
+     131             : 
+     132             : DRR ...
+     133             : LABEL=gabf_phi
+     134             : ARG=phi
+     135             : FULLSAMPLES=500
+     136             : GRID_MIN=-pi
+     137             : GRID_MAX=pi
+     138             : GRID_BIN=180
+     139             : FRICTION=8.0
+     140             : TAU=0.5
+     141             : OUTPUTFREQ=50000
+     142             : HISTORYFREQ=500000
+     143             : ... DRR
+     144             : 
+     145             : DRR ...
+     146             : LABEL=gabf_psi
+     147             : ARG=psi
+     148             : FULLSAMPLES=500
+     149             : GRID_MIN=-pi
+     150             : GRID_MAX=pi
+     151             : GRID_BIN=180
+     152             : FRICTION=8.0
+     153             : TAU=0.5
+     154             : OUTPUTFREQ=50000
+     155             : HISTORYFREQ=500000
+     156             : ... DRR
+     157             : 
+     158             : DRR ...
+     159             : LABEL=gabf_2d
+     160             : ARG=phi,psi
+     161             : EXTERNAL_FORCE=gabf_phi.phi_springforce,gabf_psi.psi_springforce
+     162             : EXTERNAL_FICT=gabf_phi.phi_fictNoPBC,gabf_psi.psi_fictNoPBC
+     163             : GRID_MIN=-pi,-pi
+     164             : GRID_MAX=pi,pi
+     165             : GRID_BIN=180,180
+     166             : NOBIAS
+     167             : OUTPUTFREQ=50000
+     168             : HISTORYFREQ=500000
+     169             : ... DRR
+     170             : 
+     171             : PRINT STRIDE=10 ARG=phi,psi FILE=COLVAR
+     172             : \endplumedfile
+     173             : 
+     174             :  */
+     175             : //+ENDPLUMEDOC
+     176             : 
+     177             : using std::vector;
+     178             : using std::string;
+     179             : 
+     180             : class DynamicReferenceRestraining : public Bias {
+     181             : private:
+     182             :   bool firsttime;
+     183             :   bool nobias;
+     184             :   vector<double> fictNoPBC;
+     185             :   vector<double> real;
+     186             :   vector<double> springlength; // spring lengths
+     187             :   vector<double> fict;         // coordinates of extended variables
+     188             :   vector<double> vfict;        // velocities of extended variables
+     189             :   vector<double> vfict_laststep;
+     190             :   vector<double> ffict; // forces exerted on extended variables
+     191             :   vector<double> fbias; // bias forces from eABF
+     192             :   vector<double> kappa;
+     193             :   vector<double> tau;
+     194             :   vector<double> friction;
+     195             :   vector<double> etemp;
+     196             :   vector<double> ffict_measured;
+     197             :   vector<double> force_external;
+     198             :   vector<double> fict_external;
+     199             :   vector<Value *> biasforceValue;
+     200             :   vector<Value *> springforceValue;
+     201             :   vector<Value *> fictValue;
+     202             :   vector<Value *> vfictValue;
+     203             :   vector<Value *> fictNoPBCValue;
+     204             :   vector<Value *> externalForceValue;
+     205             :   vector<Value *> externalFictValue;
+     206             :   vector<double> c1;
+     207             :   vector<double> c2;
+     208             :   vector<double> mass;
+     209             :   vector<DRRAxis> delim;
+     210             :   string outputname;
+     211             :   string cptname;
+     212             :   string outputprefix;
+     213             :   string fmt_;
+     214             :   const size_t ndims;
+     215             :   double dt;
+     216             :   double kbt;
+     217             :   double outputfreq;
+     218             :   double historyfreq;
+     219             :   bool isRestart;
+     220             :   bool useCZARestimator;
+     221             :   bool useUIestimator;
+     222             :   bool mergeHistoryFiles;
+     223             :   bool textoutput;
+     224             :   bool withExternalForce;
+     225             :   bool withExternalFict;
+     226             :   vector<unsigned> reflectingWall;
+     227             :   ABF ABFGrid;
+     228             :   CZAR CZARestimator;
+     229             :   double fullsamples;
+     230             :   vector<double> maxFactors;
+     231             :   UIestimator::UIestimator eabf_UI;
+     232             :   Random rand;
+     233             : 
+     234             : public:
+     235             :   explicit DynamicReferenceRestraining(const ActionOptions &);
+     236             :   void calculate();
+     237             :   void update();
+     238             :   void save(const string &filename, long long int step);
+     239             :   void load(const string &filename);
+     240             :   void backupFile(const string &filename);
+     241             :   static void registerKeywords(Keywords &keys);
+     242             :   bool is_file_exist(const char *fileName);
+     243             : };
+     244             : 
+     245             : PLUMED_REGISTER_ACTION(DynamicReferenceRestraining, "DRR")
+     246             : 
+     247          14 : void DynamicReferenceRestraining::registerKeywords(Keywords &keys) {
+     248          14 :   Bias::registerKeywords(keys);
+     249          14 :   keys.use("ARG");
+     250          28 :   keys.add("optional", "KAPPA", "specifies that the restraint is harmonic and "
+     251             :            "what the values of the force constants on "
+     252             :            "each of the variables are (default to "
+     253             :            "\\f$k_BT\\f$/(GRID_SPACING)^2)");
+     254          28 :   keys.add("compulsory", "TAU", "0.5", "specifies relaxation time on each of "
+     255             :            "variables are, similar to "
+     256             :            "extended Time Constant in Colvars");
+     257          28 :   keys.add("compulsory", "FRICTION", "8.0",
+     258             :            "add a friction to the variable, similar to extended Langevin Damping "
+     259             :            "in Colvars");
+     260          28 :   keys.add("compulsory", "GRID_MIN", "the lower bounds for the grid (GRID_BIN "
+     261             :            "or GRID_SPACING should be specified)");
+     262          28 :   keys.add("compulsory", "GRID_MAX", "the upper bounds for the grid (GRID_BIN "
+     263             :            "or GRID_SPACING should be specified)");
+     264          28 :   keys.add("compulsory", "REFLECTINGWALL", "0", "whether add reflecting walls "
+     265             :            "for each CV at GRID_MIN and GRID_MAX. Setting non-zero values will "
+     266             :            "enable this feature");
+     267          28 :   keys.add("optional", "GRID_BIN", "the number of bins for the grid");
+     268          28 :   keys.add("optional", "GRID_SPACING", "the approximate grid spacing (to be "
+     269             :            "used as an alternative or together "
+     270             :            "with GRID_BIN)");
+     271          28 :   keys.add("optional", "ZGRID_MIN", "the lower bounds for the grid (ZGRID_BIN"
+     272             :            " or ZGRID_SPACING should be specified)");
+     273          28 :   keys.add("optional", "ZGRID_MAX", "the upper bounds for the grid (ZGRID_BIN"
+     274             :            " or ZGRID_SPACING should be specified)");
+     275          28 :   keys.add("optional", "ZGRID_BIN", "the number of bins for the grid");
+     276          28 :   keys.add("optional", "ZGRID_SPACING", "the approximate grid spacing (to be "
+     277             :            "used as an alternative or together "
+     278             :            "with ZGRID_BIN)");
+     279          28 :   keys.add("optional", "EXTERNAL_FORCE", "use forces from other action instead"
+     280             :            " of internal spring force, this disable the extended system!");
+     281          28 :   keys.add("optional", "EXTERNAL_FICT", "position of external fictitious "
+     282             :            "particles, useful for UIESTIMATOR");
+     283          28 :   keys.add("compulsory", "FULLSAMPLES", "500",
+     284             :            "number of samples in a bin prior to application of the ABF");
+     285          28 :   keys.add("compulsory", "MAXFACTOR", "1.0",
+     286             :            "maximum scaling factor of biasing force");
+     287          28 :   keys.add("compulsory", "OUTPUTFREQ", "write results to a file every N steps");
+     288          28 :   keys.add("optional", "HISTORYFREQ", "save history to a file every N steps");
+     289          28 :   keys.addFlag("NOCZAR", false, "disable the CZAR estimator");
+     290          28 :   keys.addFlag("UI", false,
+     291             :                "enable the umbrella integration estimator");
+     292          28 :   keys.add("optional", "UIRESTARTPREFIX",
+     293             :            "specify the restart files for umbrella integration");
+     294          28 :   keys.add("optional", "OUTPUTPREFIX",
+     295             :            "specify the output prefix (default to the label name)");
+     296          28 :   keys.add("optional", "TEMP", "the system temperature - needed when FRICTION "
+     297             :            "is present. If not provided will be taken from "
+     298             :            "MD code (if available)");
+     299          28 :   keys.add(
+     300             :     "optional", "EXTTEMP",
+     301             :     "the temperature of extended variables (default to system temperature)");
+     302          28 :   keys.add("optional", "DRR_RFILE",
+     303             :            "specifies the restart file (.drrstate file)");
+     304          28 :   keys.addFlag("NOBIAS", false, "DO NOT apply bias forces.");
+     305          28 :   keys.addFlag("TEXTOUTPUT", false, "use text output for grad and count files "
+     306             :                "instead of boost::serialization binary "
+     307             :                "output");
+     308          28 :   keys.addFlag("MERGEHISTORYFILES", false, "output all historic results "
+     309             :                "to a single file rather than multiple .drrstate files. "
+     310             :                "This option is effective only when textOutput is on.");
+     311          28 :   keys.add("optional","FMT","specify format for outfiles files (useful for decrease the number of digits in regtests)");
+     312          14 :   componentsAreNotOptional(keys);
+     313          28 :   keys.addOutputComponent(
+     314             :     "_fict", "default",
+     315             :     "one or multiple instances of this quantity can be referenced "
+     316             :     "elsewhere in the input file. "
+     317             :     "These quantities will named with the arguments of the bias followed by "
+     318             :     "the character string _tilde. It is possible to add forces on these "
+     319             :     "variable.");
+     320          28 :   keys.addOutputComponent(
+     321             :     "_vfict", "default",
+     322             :     "one or multiple instances of this quantity can be referenced "
+     323             :     "elsewhere in the input file. "
+     324             :     "These quantities will named with the arguments of the bias followed by "
+     325             :     "the character string _tilde. It is NOT possible to add forces on these "
+     326             :     "variable.");
+     327          28 :   keys.addOutputComponent(
+     328             :     "_biasforce", "default",
+     329             :     "The bias force from eABF/DRR of the fictitious particle.");
+     330          28 :   keys.addOutputComponent("_springforce", "default", "Spring force between real CVs and extended CVs");
+     331          28 :   keys.addOutputComponent("_fictNoPBC", "default",
+     332             :                           "the positions of fictitious particles (without PBC).");
+     333          14 : }
+     334             : 
+     335          12 : DynamicReferenceRestraining::DynamicReferenceRestraining(
+     336          12 :   const ActionOptions &ao)
+     337          12 :   : PLUMED_BIAS_INIT(ao), firsttime(true), nobias(false),
+     338          12 :     fictNoPBC(getNumberOfArguments(), 0.0), real(getNumberOfArguments(), 0.0),
+     339          12 :     springlength(getNumberOfArguments(), 0.0),
+     340          12 :     fict(getNumberOfArguments(), 0.0), vfict(getNumberOfArguments(), 0.0),
+     341          12 :     vfict_laststep(getNumberOfArguments(), 0.0),
+     342          12 :     ffict(getNumberOfArguments(), 0.0), fbias(getNumberOfArguments(), 0.0),
+     343          12 :     kappa(getNumberOfArguments(), 0.0), tau(getNumberOfArguments(), 0.0),
+     344          12 :     friction(getNumberOfArguments(), 0.0), etemp(getNumberOfArguments(), 0.0),
+     345          12 :     ffict_measured(getNumberOfArguments(), 0.0),
+     346          12 :     biasforceValue(getNumberOfArguments(), NULL),
+     347          12 :     springforceValue(getNumberOfArguments(), NULL),
+     348          12 :     fictValue(getNumberOfArguments(), NULL),
+     349          12 :     vfictValue(getNumberOfArguments(), NULL),
+     350          12 :     fictNoPBCValue(getNumberOfArguments(), NULL),
+     351          12 :     externalForceValue(getNumberOfArguments(), NULL),
+     352          12 :     externalFictValue(getNumberOfArguments(), NULL),
+     353          12 :     c1(getNumberOfArguments(), 0.0),
+     354          12 :     c2(getNumberOfArguments(), 0.0), mass(getNumberOfArguments(), 0.0),
+     355          12 :     delim(getNumberOfArguments()), outputname(""), cptname(""),
+     356          12 :     outputprefix(""), fmt_("%.9f"), ndims(getNumberOfArguments()), dt(0.0), kbt(0.0),
+     357          12 :     outputfreq(0.0), historyfreq(-1.0), isRestart(false),
+     358          12 :     useCZARestimator(true), useUIestimator(false), mergeHistoryFiles(false),
+     359          12 :     textoutput(false), withExternalForce(false), withExternalFict(false),
+     360          12 :     reflectingWall(getNumberOfArguments(), 0),
+     361          36 :     maxFactors(getNumberOfArguments(), 1.0)
+     362             : {
+     363          12 :   log << "eABF/DRR: You now are using the extended adaptive biasing "
+     364             :       "force(eABF) method."
+     365          12 :       << '\n';
+     366          12 :   log << "eABF/DRR: Some people also refer to it as dynamic reference "
+     367             :       "restraining(DRR) method."
+     368          12 :       << '\n';
+     369          12 :   log << "eABF/DRR: Currently the CZAR and naive(ABF on extended variables) "
+     370             :       "estimator is enabled by default."
+     371          12 :       << '\n';
+     372          12 :   log << "eABF/DRR: For reasons of performance, the umbrella integration "
+     373             :       "estimator is not enabled by default."
+     374          12 :       << '\n';
+     375          12 :   log << "eABF/DRR: This method is originally implemented in "
+     376             :       "colvars(https://github.com/colvars/colvars)."
+     377          12 :       << '\n';
+     378          12 :   log << "eABF/DRR: The code in plumed is heavily modified from "
+     379             :       "ExtendedLagrangian.cpp and doesn't implemented all variants of "
+     380             :       "eABF/DRR."
+     381          12 :       << '\n';
+     382          12 :   log << "eABF/DRR: The thermostat used here may be different from Colvars."
+     383          12 :       << '\n';
+     384          12 :   log << "eABF/DRR: To integrate the gradients file, you can use abf_integrate "
+     385             :       "from https://github.com/colvars/colvars/tree/master/colvartools."
+     386          12 :       << '\n';
+     387          12 :   log << "eABF/DRR: Please read relevant articles and use this biasing "
+     388             :       "method carefully!"
+     389          12 :       << '\n';
+     390          12 :   parseFlag("NOBIAS", nobias);
+     391          12 :   parseFlag("UI", useUIestimator);
+     392          12 :   bool noCZAR = false;
+     393          12 :   parseFlag("NOCZAR", noCZAR);
+     394             : //   noCZAR == false ? useCZARestimator = true : useCZARestimator = false;
+     395          12 :   parseFlag("TEXTOUTPUT", textoutput);
+     396          12 :   parseFlag("MERGEHISTORYFILES", mergeHistoryFiles);
+     397          12 :   parseVector("TAU", tau);
+     398          12 :   parseVector("FRICTION", friction);
+     399          12 :   parseVector("EXTTEMP", etemp);
+     400          12 :   parseVector("KAPPA", kappa);
+     401          12 :   parseVector("REFLECTINGWALL", reflectingWall);
+     402          12 :   parse("FULLSAMPLES", fullsamples);
+     403          12 :   parseVector("MAXFACTOR", maxFactors);
+     404          12 :   parse("OUTPUTFREQ", outputfreq);
+     405          12 :   parse("HISTORYFREQ", historyfreq);
+     406          24 :   parse("OUTPUTPREFIX", outputprefix);
+     407             :   string restart_prefix;
+     408          24 :   parse("DRR_RFILE", restart_prefix);
+     409             :   string uirprefix;
+     410          12 :   parse("UIRESTARTPREFIX", uirprefix);
+     411          12 :   parseArgumentList("EXTERNAL_FORCE", externalForceValue);
+     412          12 :   parseArgumentList("EXTERNAL_FICT", externalFictValue);
+     413          24 :   parse("FMT",fmt_);
+     414          12 :   if (externalForceValue.empty()) {
+     415          11 :     withExternalForce = false;
+     416           1 :   } else if (externalForceValue.size() != ndims) {
+     417           0 :     error("eABF/DRR: Number of forces doesn't match ARGS!");
+     418             :   } else {
+     419           1 :     withExternalForce = true;
+     420             :   }
+     421          12 :   if (withExternalForce && useUIestimator) {
+     422           1 :     if (externalFictValue.empty()) {
+     423           0 :       error("eABF/DRR: No external fictitious particles specified. UI estimator needs it.");
+     424           1 :     } else if(externalFictValue.size() != ndims) {
+     425           0 :       error("eABF/DRR: Number of fictitious particles doesn't match ARGS!");
+     426             :     } else {
+     427           1 :       withExternalFict = true;
+     428             :     }
+     429             :   }
+     430          12 :   kbt = getkBT();
+     431          12 :   if (kbt <= std::numeric_limits<double>::epsilon()) {
+     432           0 :     error("eABF/DRR: It seems the MD engine does not setup the temperature correctly for PLUMED."
+     433             :           "Please set it by the TEMP keyword manually.");
+     434             :   }
+     435          12 :   if (fullsamples < 0.5) {
+     436           0 :     fullsamples = 500.0;
+     437           0 :     log << "eABF/DRR: The fullsamples parametre is not set. Set it to "
+     438             :         "500(default)."
+     439           0 :         << '\n';
+     440             :   }
+     441          12 :   if (getRestart()) {
+     442           1 :     if (restart_prefix.length() != 0) {
+     443           1 :       isRestart = true;
+     444           1 :       firsttime = false;
+     445           1 :       load(restart_prefix);
+     446             :     } else {
+     447           0 :       log << "eABF/DRR: You don't specify the file for restarting." << '\n';
+     448           0 :       log << "eABF/DRR: So I assume you are splitting windows." << '\n';
+     449           0 :       isRestart = false;
+     450           0 :       firsttime = true;
+     451             :     }
+     452             :   }
+     453             : 
+     454          12 :   vector<string> gmin(ndims);
+     455          12 :   vector<string> zgmin(ndims);
+     456          12 :   parseVector("GRID_MIN", gmin);
+     457          24 :   parseVector("ZGRID_MIN", zgmin);
+     458          12 :   if (gmin.size() != ndims)
+     459           0 :     error("eABF/DRR: not enough values for GRID_MIN");
+     460          12 :   if (zgmin.size() != ndims) {
+     461          33 :     log << "eABF/DRR: You didn't specify ZGRID_MIN. " << '\n'
+     462          11 :         << "eABF/DRR: The GRID_MIN will be used instead.";
+     463          11 :     zgmin = gmin;
+     464             :   }
+     465          12 :   vector<string> gmax(ndims);
+     466          12 :   vector<string> zgmax(ndims);
+     467          12 :   parseVector("GRID_MAX", gmax);
+     468          24 :   parseVector("ZGRID_MAX", zgmax);
+     469          12 :   if (gmax.size() != ndims)
+     470           0 :     error("eABF/DRR: not enough values for GRID_MAX");
+     471          12 :   if (zgmax.size() != ndims) {
+     472          33 :     log << "eABF/DRR: You didn't specify ZGRID_MAX. " << '\n'
+     473          11 :         << "eABF/DRR: The GRID_MAX will be used instead.";
+     474          11 :     zgmax = gmax;
+     475             :   }
+     476          12 :   vector<unsigned> gbin(ndims);
+     477          12 :   vector<unsigned> zgbin(ndims);
+     478          12 :   vector<double> gspacing(ndims);
+     479          12 :   vector<double> zgspacing(ndims);
+     480          12 :   parseVector("GRID_BIN", gbin);
+     481          12 :   parseVector("ZGRID_BIN", zgbin);
+     482          12 :   parseVector("GRID_SPACING", gspacing);
+     483          24 :   parseVector("ZGRID_SPACING", zgspacing);
+     484          12 :   if (gbin.size() != ndims) {
+     485           3 :     log << "eABF/DRR: You didn't specify GRID_BIN. Trying to use GRID_SPACING "
+     486             :         "instead."
+     487           3 :         << '\n';
+     488           3 :     if (gspacing.size() != ndims) {
+     489           0 :       error("eABF/DRR: not enough values for GRID_BIN");
+     490             :     } else {
+     491           3 :       gbin.resize(ndims);
+     492           6 :       for (size_t i = 0; i < ndims; ++i) {
+     493             :         double l, h;
+     494           3 :         PLMD::Tools::convert(gmin[i], l);
+     495           3 :         PLMD::Tools::convert(gmax[i], h);
+     496           3 :         gbin[i] = std::nearbyint((h - l) / gspacing[i]);
+     497           3 :         gspacing[i] = (h - l) / gbin[i];
+     498           3 :         log << "GRID_BIN[" << i << "] is " << gbin[i] << '\n';
+     499             :       }
+     500             :     }
+     501             :   }
+     502          12 :   if (zgbin.size() != ndims) {
+     503          11 :     log << "eABF/DRR: You didn't specify ZGRID_BIN. Trying to use ZGRID_SPACING instead." << '\n';
+     504          11 :     if (zgspacing.size() != ndims) {
+     505          11 :       log << "eABF/DRR: You didn't specify ZGRID_SPACING. Trying to use GRID_SPACING or GRID_BIN instead." << '\n';
+     506          11 :       zgbin = gbin;
+     507          11 :       zgspacing = gspacing;
+     508             :     } else {
+     509           0 :       zgbin.resize(ndims);
+     510           0 :       for (size_t i = 0; i < ndims; ++i) {
+     511             :         double l, h;
+     512           0 :         PLMD::Tools::convert(zgmin[i], l);
+     513           0 :         PLMD::Tools::convert(zgmax[i], h);
+     514           0 :         zgbin[i] = std::nearbyint((h - l) / zgspacing[i]);
+     515           0 :         zgspacing[i] = (h - l) / zgbin[i];
+     516           0 :         log << "ZGRID_BIN[" << i << "] is " << zgbin[i] << '\n';
+     517             :       }
+     518             :     }
+     519             :   }
+     520          12 :   checkRead();
+     521             : 
+     522             :   // Set up kbt for extended system
+     523          12 :   log << "eABF/DRR: The fullsamples is " << fullsamples << '\n';
+     524          12 :   log << "eABF/DRR: The kbt(real system) is " << kbt << '\n';
+     525          12 :   dt = getTimeStep() * getStride();
+     526          12 :   log << "eABF/DRR: timestep = " << getTimeStep() << " ps with stride = " << getStride() << " steps\n";
+     527          12 :   vector<double> ekbt(ndims, 0.0);
+     528          12 :   if (etemp.size() != ndims) {
+     529          12 :     etemp.assign(ndims, kbt / getKBoltzmann());
+     530             :   }
+     531          12 :   if (tau.size() != ndims) {
+     532           0 :     tau.assign(ndims, 0.5);
+     533             :   }
+     534          12 :   if (friction.size() != ndims) {
+     535           0 :     friction.assign(ndims, 8.0);
+     536             :   }
+     537          12 :   if (maxFactors.size() != ndims) {
+     538           0 :     maxFactors.assign(ndims, 1.0);
+     539             :   }
+     540          31 :   for (size_t i = 0; i < ndims; ++i) {
+     541          19 :     log << "eABF/DRR: The maximum scaling factor [" << i << "] is " << maxFactors[i] << '\n';
+     542          19 :     if (maxFactors[i] > 1.0) {
+     543           0 :       log << "eABF/DRR: Warning! The maximum scaling factor larger than 1.0 is not recommended!" << '\n';
+     544             :     }
+     545             :   }
+     546          31 :   for (size_t i = 0; i < ndims; ++i) {
+     547          19 :     ekbt[i] = etemp[i] * getKBoltzmann();
+     548          19 :     log << "eABF/DRR: The kbt(extended system) of [" << i << "] is " << ekbt[i]
+     549          19 :         << '\n';
+     550          19 :     log << "eABF/DRR: relaxation time tau [" << i << "] is " << tau[i] << '\n';
+     551          19 :     log << "eABF/DRR: Extended variable [" << i << "] has friction: " << friction[i] << '\n';
+     552             :   }
+     553             : 
+     554             :   // Set up the force grid
+     555          12 :   vector<DRRAxis> zdelim(ndims);
+     556          31 :   for (size_t i = 0; i < ndims; ++i) {
+     557          19 :     log << "eABF/DRR: The " << i << " dimensional grid minimum is " << gmin[i]
+     558          19 :         << '\n';
+     559          19 :     log << "eABF/DRR: The " << i << " dimensional grid maximum is " << gmax[i]
+     560          19 :         << '\n';
+     561          19 :     log << "eABF/DRR: The " << i << " dimensional grid has " << gbin[i]
+     562          19 :         << " bins" << '\n';
+     563          19 :     log << "eABF/DRR: The " << i << " dimensional zgrid minimum is " << zgmin[i]
+     564          19 :         << '\n';
+     565          19 :     log << "eABF/DRR: The " << i << " dimensional zgrid maximum is " << zgmax[i]
+     566          19 :         << '\n';
+     567          19 :     log << "eABF/DRR: The " << i << " dimensional zgrid has " << zgbin[i]
+     568          19 :         << " bins" << '\n';
+     569             :     double l, h;
+     570          19 :     PLMD::Tools::convert(gmin[i], l);
+     571          19 :     PLMD::Tools::convert(gmax[i], h);
+     572          19 :     delim[i].set(l, h, gbin[i]);
+     573             :     double zl,zh;
+     574          19 :     PLMD::Tools::convert(zgmin[i], zl);
+     575          19 :     PLMD::Tools::convert(zgmax[i], zh);
+     576          19 :     zdelim[i].set(zl, zh, zgbin[i]);
+     577             :   }
+     578          12 :   if (kappa.size() != ndims) {
+     579           9 :     kappa.resize(ndims, 0.0);
+     580          25 :     for (size_t i = 0; i < ndims; ++i) {
+     581          16 :       if (kappa[i] <= 0) {
+     582          16 :         log << "eABF/DRR: The spring force constant kappa[" << i
+     583          16 :             << "] is not set." << '\n';
+     584          16 :         kappa[i] = ekbt[i] / (delim[i].getWidth() * delim[i].getWidth());
+     585          16 :         log << "eABF/DRR: set kappa[" << i
+     586          16 :             << "] according to bin width(ekbt/(binWidth^2))." << '\n';
+     587             :       }
+     588          16 :       log << "eABF/DRR: The spring force constant kappa[" << i << "] is "
+     589          16 :           << std::fixed << std::setprecision(10) << kappa[i] << '\n';
+     590             :     }
+     591             :   } else {
+     592           3 :     log << "eABF/DRR: The kappa have been set manually." << '\n';
+     593           6 :     for (size_t i = 0; i < ndims; ++i) {
+     594           3 :       log << "eABF/DRR: The spring force constant kappa[" << i << "] is "
+     595           3 :           << std::fixed << std::setprecision(10) << kappa[i] << '\n';
+     596             :     }
+     597             :   }
+     598             : 
+     599          31 :   for (size_t i = 0; i < ndims; ++i) {
+     600          19 :     mass[i] = kappa[i] * tau[i] * tau[i] / (4 * pi * pi);
+     601          19 :     log << "eABF/DRR: Fictitious mass[" << i << "] is " << mass[i] << '\n';
+     602          19 :     c1[i] = exp(-0.5 * friction[i] * dt);
+     603          19 :     c2[i] = sqrt(ekbt[i] * (1.0 - c1[i] * c1[i]) / mass[i]);
+     604             :   }
+     605             : 
+     606          31 :   for (size_t i = 0; i < ndims; ++i) {
+     607             :     // Position output
+     608          19 :     string comp = getPntrToArgument(i)->getName() + "_fict";
+     609          38 :     addComponentWithDerivatives(comp);
+     610          19 :     if (getPntrToArgument(i)->isPeriodic()) {
+     611             :       string a, b;
+     612             :       double c, d;
+     613          16 :       getPntrToArgument(i)->getDomain(a, b);
+     614          16 :       getPntrToArgument(i)->getDomain(c, d);
+     615          16 :       componentIsPeriodic(comp, a, b);
+     616          16 :       delim[i].setPeriodicity(c, d);
+     617             :       zdelim[i].setPeriodicity(c, d);
+     618             :     } else
+     619           3 :       componentIsNotPeriodic(comp);
+     620          19 :     fictValue[i] = getPntrToComponent(comp);
+     621             :     // Velocity output
+     622          38 :     comp = getPntrToArgument(i)->getName() + "_vfict";
+     623          19 :     addComponent(comp);
+     624          19 :     componentIsNotPeriodic(comp);
+     625          19 :     vfictValue[i] = getPntrToComponent(comp);
+     626             :     // Bias force from eABF/DRR output
+     627          38 :     comp = getPntrToArgument(i)->getName() + "_biasforce";
+     628          19 :     addComponent(comp);
+     629          19 :     componentIsNotPeriodic(comp);
+     630          19 :     biasforceValue[i] = getPntrToComponent(comp);
+     631             :     // Spring force output, useful for perform egABF and other analysis
+     632          38 :     comp = getPntrToArgument(i)->getName() + "_springforce";
+     633          19 :     addComponent(comp);
+     634          19 :     componentIsNotPeriodic(comp);
+     635          19 :     springforceValue[i] = getPntrToComponent(comp);
+     636             :     // Position output, no pbc-aware
+     637          38 :     comp = getPntrToArgument(i)->getName() + "_fictNoPBC";
+     638          19 :     addComponent(comp);
+     639          19 :     componentIsNotPeriodic(comp);
+     640          19 :     fictNoPBCValue[i] = getPntrToComponent(comp);
+     641             :   }
+     642             : 
+     643          12 :   if (outputprefix.length() == 0) {
+     644           0 :     outputprefix = getLabel();
+     645             :   }
+     646             :   // Support multiple replica
+     647          12 :   string replica_suffix = plumed.getSuffix();
+     648          12 :   if (replica_suffix.empty() == false) {
+     649           4 :     outputprefix = outputprefix + replica_suffix;
+     650             :   }
+     651          12 :   outputname = outputprefix + ".drrstate";
+     652          12 :   cptname = outputprefix + ".cpt.drrstate";
+     653             : 
+     654          12 :   if (!isRestart) {
+     655             :     // If you want to use on-the-fly text output for CZAR and naive estimator,
+     656             :     // you should turn it to true first!
+     657          11 :     ABFGrid = ABF(delim, ".abf", fullsamples, maxFactors, textoutput);
+     658             :     // Just initialize it even useCZARestimator is off.
+     659          22 :     CZARestimator = CZAR(zdelim, ".czar", kbt, textoutput);
+     660          11 :     log << "eABF/DRR: The init function of the grid is finished." << '\n';
+     661             :   } else {
+     662             :     // ABF Parametres are not saved in binary files
+     663             :     // So manully set them up
+     664           1 :     ABFGrid.setParameters(fullsamples, maxFactors);
+     665             :   }
+     666          12 :   if (useCZARestimator) {
+     667          12 :     log << "eABF/DRR: Using corrected z-average restraint estimator of gradients" << '\n';
+     668          24 :     log << "  Bibliography " << plumed.cite("Lesage, Lelièvre, Stoltz and Hénin, "
+     669          24 :                                             "J. Phys. Chem. B 3676, 121 (2017)");
+     670          12 :     log << plumed.cite("Darve and Pohorille, J. Chem. Phys. 9169, 115 (2001)") << '\n';
+     671             :   }
+     672          12 :   if (useUIestimator) {
+     673           9 :     log << "eABF/DRR: Using umbrella integration(Zheng and Yang's) estimator "
+     674             :         "of gradients."
+     675           9 :         << '\n';
+     676           9 :     log << "eABF/DRR: The UI estimator code is contributed by Haohao Fu."
+     677           9 :         << '\n';
+     678          18 :     log << "  Bibliography " << plumed.cite(
+     679          18 :           "Fu, Shao, Chipot and Cai, J. Chem. Theory Comput. 3506, 12 (2016)");
+     680          18 :     log << plumed.cite("Zheng and Yang, J. Chem. Theory Comput. 810, 8 (2012)");
+     681           9 :     log << plumed.cite("Darve and Pohorille, J. Chem. Phys. 9169, 115 (2001)") << '\n';
+     682           9 :     vector<double> lowerboundary(zdelim.size(), 0);
+     683           9 :     vector<double> upperboundary(zdelim.size(), 0);
+     684           9 :     vector<double> width(zdelim.size(), 0);
+     685          24 :     for (size_t i = 0; i < zdelim.size(); ++i) {
+     686          15 :       lowerboundary[i] = zdelim[i].getMin();
+     687          15 :       upperboundary[i] = zdelim[i].getMax();
+     688          15 :       width[i] = zdelim[i].getWidth();
+     689             :     }
+     690             :     vector<string> input_filename;
+     691             :     bool uirestart = false;
+     692           9 :     if (isRestart && (uirprefix.length() != 0)) {
+     693           1 :       input_filename.push_back(uirprefix);
+     694             :       uirestart = true;
+     695             :     }
+     696           9 :     if (isRestart && (uirprefix.length() == 0)) {
+     697           0 :       input_filename.push_back(outputprefix);
+     698             :     }
+     699           9 :     eabf_UI = UIestimator::UIestimator(
+     700           9 :                 lowerboundary, upperboundary, width, kappa, outputprefix, int(outputfreq),
+     701          18 :                 uirestart, input_filename, kbt / getKBoltzmann());
+     702           9 :   }
+     703          24 : }
+     704             : 
+     705         123 : void DynamicReferenceRestraining::calculate() {
+     706         123 :   long long int step_now = getStep();
+     707         123 :   if (firsttime) {
+     708          28 :     for (size_t i = 0; i < ndims; ++i) {
+     709          17 :       fict[i] = getArgument(i);
+     710          17 :       if(reflectingWall[i] && (fict[i]>=delim[i].getMax() || fict[i]<=delim[i].getMin())) {
+     711           0 :         error("eABF/DRR: initial position not in the range of [gmin, gmax]!");
+     712             :       }
+     713             :     }
+     714          11 :     firsttime = false;
+     715             :   }
+     716         123 :   if (step_now != 0) {
+     717         111 :     if ((step_now % int(outputfreq)) == 0) {
+     718          15 :       save(outputname, step_now);
+     719          15 :       if (textoutput) {
+     720          10 :         ABFGrid.writeAll(outputprefix, fmt_);
+     721          10 :         if (useCZARestimator) {
+     722          10 :           CZARestimator.writeAll(outputprefix, fmt_);
+     723          10 :           CZARestimator.writeZCountZGrad(outputprefix);
+     724             :         }
+     725             :       }
+     726             :     }
+     727         111 :     if (historyfreq > 0 && (step_now % int(historyfreq)) == 0) {
+     728           4 :       if (textoutput) {
+     729             :         const string filename =
+     730           4 :           outputprefix + ".another.drrstate";
+     731           4 :         save(filename, step_now);
+     732             :         const string textfilename =
+     733           4 :           mergeHistoryFiles ? (outputprefix + ".hist") : (outputprefix + "." + std::to_string(step_now));
+     734           4 :         ABFGrid.writeAll(textfilename, fmt_, mergeHistoryFiles);
+     735           4 :         if (useCZARestimator) {
+     736           4 :           CZARestimator.writeAll(textfilename, fmt_, mergeHistoryFiles);
+     737           4 :           CZARestimator.writeZCountZGrad(textfilename, mergeHistoryFiles);
+     738             :         }
+     739             :       } else {
+     740             :         const string filename =
+     741           0 :           outputprefix + "." + std::to_string(step_now) + ".drrstate";
+     742           0 :         save(filename, step_now);
+     743             :       }
+     744             :     }
+     745         111 :     if (getCPT()) {
+     746           0 :       log << "eABF/DRR: The MD engine is writing checkpoint so we also write a "
+     747             :           "DRR state file at step: "
+     748           0 :           << step_now << ".\n";
+     749           0 :       save(cptname, step_now);
+     750             :     }
+     751             :   }
+     752         123 :   if (withExternalForce == false) {
+     753             :     double ene = 0.0;
+     754         294 :     for (size_t i = 0; i < ndims; ++i) {
+     755         183 :       real[i] = getArgument(i);
+     756         183 :       springlength[i] = difference(i, fict[i], real[i]);
+     757         183 :       fictNoPBC[i] = real[i] - springlength[i];
+     758         183 :       double f = -kappa[i] * springlength[i];
+     759         183 :       ffict_measured[i] = -f;
+     760         183 :       ene += 0.5 * kappa[i] * springlength[i] * springlength[i];
+     761         183 :       setOutputForce(i, f);
+     762         183 :       ffict[i] = -f;
+     763         183 :       fict[i] = fictValue[i]->bringBackInPbc(fict[i]);
+     764         183 :       fictValue[i]->set(fict[i]);
+     765         183 :       vfictValue[i]->set(vfict_laststep[i]);
+     766         183 :       springforceValue[i]->set(ffict_measured[i]);
+     767         183 :       fictNoPBCValue[i]->set(fictNoPBC[i]);
+     768             :     }
+     769         111 :     setBias(ene);
+     770         111 :     ABFGrid.store_getbias(fict, ffict_measured, fbias);
+     771             :   } else {
+     772          36 :     for (size_t i = 0; i < ndims; ++i) {
+     773          24 :       real[i] = getArgument(i);
+     774          24 :       ffict_measured[i] = externalForceValue[i]->get();
+     775          24 :       if (withExternalFict) {
+     776          24 :         fictNoPBC[i] = externalFictValue[i]->get();
+     777             :       }
+     778          24 :       springforceValue[i]->set(ffict_measured[i]);
+     779          24 :       fictNoPBCValue[i]->set(fictNoPBC[i]);
+     780             :     }
+     781          12 :     ABFGrid.store_getbias(real, ffict_measured, fbias);
+     782          12 :     if (!nobias) {
+     783           0 :       for (size_t i = 0; i < ndims; ++i) {
+     784           0 :         setOutputForce(i, fbias[i]);
+     785             :       }
+     786             :     }
+     787             :   }
+     788         123 :   if (useCZARestimator) {
+     789         123 :     CZARestimator.store(real, ffict_measured);
+     790             :   }
+     791         123 :   if (useUIestimator) {
+     792          87 :     eabf_UI.update_output_filename(outputprefix);
+     793         174 :     eabf_UI.update(int(step_now), real, fictNoPBC);
+     794             :   }
+     795         123 : }
+     796             : 
+     797         123 : void DynamicReferenceRestraining::update() {
+     798         123 :   if (withExternalForce == false) {
+     799         294 :     for (size_t i = 0; i < ndims; ++i) {
+     800             :       // consider additional forces on the fictitious particle
+     801             :       // (e.g. MetaD stuff)
+     802         183 :       ffict[i] += fictValue[i]->getForce();
+     803         183 :       if (!nobias) {
+     804         183 :         ffict[i] += fbias[i];
+     805             :       }
+     806         183 :       biasforceValue[i]->set(fbias[i]);
+     807             :       // update velocity (half step)
+     808         183 :       vfict[i] += ffict[i] * 0.5 * dt / mass[i];
+     809             :       // thermostat (half step)
+     810         183 :       vfict[i] = c1[i] * vfict[i] + c2[i] * rand.Gaussian();
+     811             :       // save full step velocity to be dumped at next step
+     812         183 :       vfict_laststep[i] = vfict[i];
+     813             :       // thermostat (half step)
+     814         183 :       vfict[i] = c1[i] * vfict[i] + c2[i] * rand.Gaussian();
+     815             :       // update velocity (half step)
+     816         183 :       vfict[i] += ffict[i] * 0.5 * dt / mass[i];
+     817             :       // update position (full step)
+     818         183 :       fict[i] += vfict[i] * dt;
+     819             :       // reflecting boundary
+     820         183 :       if (reflectingWall[i]) {
+     821          24 :         if (fict[i]<delim[i].getMin()) {
+     822           1 :           fict[i]=delim[i].getMin()+(delim[i].getMin()-fict[i]);
+     823           1 :           vfict[i]*=-1.0;
+     824          23 :         } else if (fict[i]>delim[i].getMax()) {
+     825           0 :           fict[i]=delim[i].getMax()-(fict[i]-delim[i].getMax());
+     826           0 :           vfict[i]*=-1.0;
+     827             :         }
+     828             :       }
+     829             :     }
+     830             :   }
+     831         123 : }
+     832             : 
+     833          19 : void DynamicReferenceRestraining::save(const string &filename,
+     834             :                                        long long int step) {
+     835          19 :   std::ofstream out;
+     836          19 :   out.open(filename.c_str(), std::ios::binary);
+     837          19 :   boost::archive::binary_oarchive oa(out);
+     838          19 :   oa << step << fict << vfict << vfict_laststep << ffict << ABFGrid
+     839          19 :      << CZARestimator;
+     840          19 :   out.close();
+     841          19 : }
+     842             : 
+     843           1 : void DynamicReferenceRestraining::load(const string &rfile_prefix) {
+     844           1 :   string replica_suffix = plumed.getSuffix();
+     845             :   string filename;
+     846           1 :   if (replica_suffix.empty() == true) {
+     847           2 :     filename = rfile_prefix + ".drrstate";
+     848             :   } else {
+     849           0 :     filename = rfile_prefix + "." + replica_suffix + ".drrstate";
+     850             :   }
+     851           1 :   std::ifstream in;
+     852             :   long long int step;
+     853           1 :   in.open(filename.c_str(), std::ios::binary);
+     854           1 :   log << "eABF/DRR: Read restart file: " << filename << '\n';
+     855           1 :   boost::archive::binary_iarchive ia(in);
+     856           1 :   ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> ABFGrid >>
+     857           1 :      CZARestimator;
+     858           1 :   in.close();
+     859           1 :   log << "eABF/DRR: Restart at step: " << step << '\n';
+     860           1 :   backupFile(filename);
+     861           2 : }
+     862             : 
+     863           1 : void DynamicReferenceRestraining::backupFile(const string &filename) {
+     864             :   bool isSuccess = false;
+     865             :   long int i = 0;
+     866           2 :   while (!isSuccess) {
+     867             :     // If libstdc++ support C++17 we can simplify following code.
+     868           2 :     const string bckname = "bck." + filename + "." + std::to_string(i);
+     869           1 :     if (is_file_exist(bckname.c_str())) {
+     870           0 :       ++i;
+     871             :     } else {
+     872           1 :       log << "eABF/DRR: Backup original restart file to " << bckname << '\n';
+     873           1 :       std::ifstream src(filename.c_str(), std::ios::binary);
+     874           1 :       std::ofstream dst(bckname.c_str(), std::ios::binary);
+     875           1 :       dst << src.rdbuf();
+     876           1 :       src.close();
+     877           1 :       dst.close();
+     878             :       isSuccess = true;
+     879           1 :     }
+     880             :   }
+     881           1 : }
+     882             : 
+     883             : // Copy from
+     884             : // stackoverflow(https://stackoverflow.com/questions/12774207/fastest-way-to-check-if-a-file-exist-using-standard-c-c11-c)
+     885           1 : bool DynamicReferenceRestraining::is_file_exist(const char *fileName) {
+     886           1 :   std::ifstream infile(fileName);
+     887           1 :   return infile.good();
+     888           1 : }
+     889             : }
+     890             : }
+     891             : 
+     892             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/colvar_UIestimator.h.func-sort-c.html b/coverage/drr/colvar_UIestimator.h.func-sort-c.html new file mode 100644 index 000000000000..e7c364098eb1 --- /dev/null +++ b/coverage/drr/colvar_UIestimator.h.func-sort-c.html @@ -0,0 +1,209 @@ + + + + + + + + LCOV - plumed test coverage - drr/colvar_UIestimator.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - colvar_UIestimator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29930299.0 %
Date:2024-02-22 21:58:45Functions:3434100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr11UIestimator11UIestimator15read_inputfilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE1
_ZN4PLMD3drr11UIestimator11UIestimator11calc_1D_pmfEv9
_ZN4PLMD3drr11UIestimator11UIestimator12write_1D_pmfEv9
_ZN4PLMD3drr11UIestimator11UIestimatorC2ERKSt6vectorIdSaIdEES7_S7_S7_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEibRKS3_ISD_SaISD_EEd9
_ZN4PLMD3drr11UIestimator8n_matrixC2ERKSt6vectorIdSaIdEES7_S7_i9
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEEC2ERKS5_S8_S8_iS8_10
_ZN4PLMD3drr11UIestimator11UIestimatorC2Ev12
_ZN4PLMD3drr11UIestimator8n_vectorIiEC2ERKSt6vectorIdSaIdEES8_S8_iRKi19
_ZN4PLMD3drr11UIestimator11UIestimator11write_filesEv21
_ZN4PLMD3drr11UIestimator11UIestimator8calc_pmfEv21
_ZN4PLMD3drr11UIestimator11UIestimatorD2Ev21
_ZN4PLMD3drr11UIestimator8n_matrixC2Ev21
_ZN4PLMD3drr11UIestimator8n_vectorIdEC2Ev21
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEEC2Ev42
_ZN4PLMD3drr11UIestimator8n_vectorIdEC2ERKSt6vectorIdSaIdEES8_S8_iRKd63
_ZN4PLMD3drr11UIestimator8n_vectorIiEC2Ev63
_ZNK4PLMD3drr11UIestimator11UIestimator9writeheadERSt14basic_ofstreamIcSt11char_traitsIcEE63
_ZN4PLMD3drr11UIestimator11UIestimator6updateEiRKSt6vectorIdSaIdEES5_87
_ZN4PLMD3drr11UIestimator8n_matrix14increase_valueERKSt6vectorIdSaIdEES7_i87
_ZN4PLMD3drr11UIestimator8n_vectorIiE14increase_valueERKSt6vectorIdSaIdEERKi91
_ZN4PLMD3drr11UIestimator8n_vectorIiE9set_valueERKSt6vectorIdSaIdEERKi212
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9set_valueERKS5_S8_225
_ZN4PLMD3drr11UIestimator8n_vectorIdE14increase_valueERKSt6vectorIdSaIdEERKd318
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9get_valueERKS5_737
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9convert_xERKS5_962
_ZN4PLMD3drr11UIestimator8n_vectorIiE9get_valueERKSt6vectorIdSaIdEE7196
_ZN4PLMD3drr11UIestimator8n_vectorIiE9convert_xERKSt6vectorIdSaIdEE7499
_ZN4PLMD3drr11UIestimator8n_vectorIdE9set_valueERKSt6vectorIdSaIdEERKd26790
_ZN4PLMD3drr11UIestimator8n_matrix9get_valueERKSt6vectorIdSaIdEES7_171000
_ZN4PLMD3drr11UIestimator8n_matrix9convert_xERKSt6vectorIdSaIdEE171087
_ZN4PLMD3drr11UIestimator8n_matrix9convert_yERKSt6vectorIdSaIdEES7_171087
_ZN4PLMD3drr11UIestimator8n_vectorIdE9get_valueERKSt6vectorIdSaIdEE280499
_ZN4PLMD3drr11UIestimator8n_vectorIdE9convert_xERKSt6vectorIdSaIdEE307607
_ZN4PLMD3drr11UIestimator8n_matrix5roundEd1018791
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/colvar_UIestimator.h.func.html b/coverage/drr/colvar_UIestimator.h.func.html new file mode 100644 index 000000000000..8e93640fe9b2 --- /dev/null +++ b/coverage/drr/colvar_UIestimator.h.func.html @@ -0,0 +1,209 @@ + + + + + + + + LCOV - plumed test coverage - drr/colvar_UIestimator.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - colvar_UIestimator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29930299.0 %
Date:2024-02-22 21:58:45Functions:3434100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr11UIestimator11UIestimator11calc_1D_pmfEv9
_ZN4PLMD3drr11UIestimator11UIestimator11write_filesEv21
_ZN4PLMD3drr11UIestimator11UIestimator12write_1D_pmfEv9
_ZN4PLMD3drr11UIestimator11UIestimator15read_inputfilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EE1
_ZN4PLMD3drr11UIestimator11UIestimator6updateEiRKSt6vectorIdSaIdEES5_87
_ZN4PLMD3drr11UIestimator11UIestimator8calc_pmfEv21
_ZN4PLMD3drr11UIestimator11UIestimatorC2ERKSt6vectorIdSaIdEES7_S7_S7_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEibRKS3_ISD_SaISD_EEd9
_ZN4PLMD3drr11UIestimator11UIestimatorC2Ev12
_ZN4PLMD3drr11UIestimator11UIestimatorD2Ev21
_ZN4PLMD3drr11UIestimator8n_matrix14increase_valueERKSt6vectorIdSaIdEES7_i87
_ZN4PLMD3drr11UIestimator8n_matrix5roundEd1018791
_ZN4PLMD3drr11UIestimator8n_matrix9convert_xERKSt6vectorIdSaIdEE171087
_ZN4PLMD3drr11UIestimator8n_matrix9convert_yERKSt6vectorIdSaIdEES7_171087
_ZN4PLMD3drr11UIestimator8n_matrix9get_valueERKSt6vectorIdSaIdEES7_171000
_ZN4PLMD3drr11UIestimator8n_matrixC2ERKSt6vectorIdSaIdEES7_S7_i9
_ZN4PLMD3drr11UIestimator8n_matrixC2Ev21
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9convert_xERKS5_962
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9get_valueERKS5_737
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEE9set_valueERKS5_S8_225
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEEC2ERKS5_S8_S8_iS8_10
_ZN4PLMD3drr11UIestimator8n_vectorISt6vectorIdSaIdEEEC2Ev42
_ZN4PLMD3drr11UIestimator8n_vectorIdE14increase_valueERKSt6vectorIdSaIdEERKd318
_ZN4PLMD3drr11UIestimator8n_vectorIdE9convert_xERKSt6vectorIdSaIdEE307607
_ZN4PLMD3drr11UIestimator8n_vectorIdE9get_valueERKSt6vectorIdSaIdEE280499
_ZN4PLMD3drr11UIestimator8n_vectorIdE9set_valueERKSt6vectorIdSaIdEERKd26790
_ZN4PLMD3drr11UIestimator8n_vectorIdEC2ERKSt6vectorIdSaIdEES8_S8_iRKd63
_ZN4PLMD3drr11UIestimator8n_vectorIdEC2Ev21
_ZN4PLMD3drr11UIestimator8n_vectorIiE14increase_valueERKSt6vectorIdSaIdEERKi91
_ZN4PLMD3drr11UIestimator8n_vectorIiE9convert_xERKSt6vectorIdSaIdEE7499
_ZN4PLMD3drr11UIestimator8n_vectorIiE9get_valueERKSt6vectorIdSaIdEE7196
_ZN4PLMD3drr11UIestimator8n_vectorIiE9set_valueERKSt6vectorIdSaIdEERKi212
_ZN4PLMD3drr11UIestimator8n_vectorIiEC2ERKSt6vectorIdSaIdEES8_S8_iRKi19
_ZN4PLMD3drr11UIestimator8n_vectorIiEC2Ev63
_ZNK4PLMD3drr11UIestimator11UIestimator9writeheadERSt14basic_ofstreamIcSt11char_traitsIcEE63
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/colvar_UIestimator.h.gcov.html b/coverage/drr/colvar_UIestimator.h.gcov.html new file mode 100644 index 000000000000..2d55394a012c --- /dev/null +++ b/coverage/drr/colvar_UIestimator.h.gcov.html @@ -0,0 +1,932 @@ + + + + + + + + LCOV - plumed test coverage - drr/colvar_UIestimator.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - colvar_UIestimator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29930299.0 %
Date:2024-02-22 21:58:45Functions:3434100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :     Copyright (c) 2017 of Haochuan Chen (excluding colvar_UIestimator.h)
+       3             :     Copyright (c) 2017 of Haohao Fu (colvar_UIestimator.h)
+       4             : 
+       5             :     This program is free software: you can redistribute it and/or modify
+       6             :     it under the terms of the GNU Lesser General Public License as published
+       7             :     by the Free Software Foundation, either version 3 of the License, or
+       8             :     (at your option) any later version.
+       9             : 
+      10             :     This program is distributed in the hope that it will be useful,
+      11             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
+      12             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      13             :     GNU Lesser General Public License for more details.
+      14             : 
+      15             :     You should have received a copy of the GNU Lesser General Public License
+      16             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+      17             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      18             : #ifndef __PLUMED_drr_colvar_UIestimator_h
+      19             : #define __PLUMED_drr_colvar_UIestimator_h
+      20             : // The original code(https://github.com/fhh2626/colvars/blob/master/src/colvar_UIestimator.h) has been modified by Haochuan Chen.
+      21             : // Modifications:
+      22             : // 1. Disable colvars related code.
+      23             : // 2. Change boltzmann constant.
+      24             : // 3. Change output precision.
+      25             : // I(Haochuan Chen) don't know how to maintain this code and how it runs. If you are interested in it, please contact Haohao Fu.
+      26             : 
+      27             : #include <cmath>
+      28             : #include <vector>
+      29             : #include <fstream>
+      30             : #include <string>
+      31             : #include <iomanip>
+      32             : #include <limits>
+      33             : 
+      34             : #include <typeinfo>
+      35             : 
+      36             : // only for colvar module!
+      37             : // when integrated into other code, just remove this line and "...cvm::backup_file(...)"
+      38             : // #include "colvarmodule.h"
+      39             : 
+      40             : namespace PLMD {
+      41             : namespace drr {
+      42             : 
+      43             : namespace UIestimator
+      44             : {
+      45             : const int Y_SIZE = 21;
+      46             : const int HALF_Y_SIZE = 10;
+      47             : const double BOLTZMANN = 0.0083144621;
+      48             : const int EXTENDED_X_SIZE = HALF_Y_SIZE;
+      49             : 
+      50             : class n_matrix    // spare matrix, stores the distribution matrix of n(x,y)
+      51             : {
+      52             : public:
+      53          21 :   n_matrix() {}
+      54           9 :   n_matrix(const std::vector<double> & lowerboundary_p,   // lowerboundary of x
+      55             :            const std::vector<double> & upperboundary_p,   // upperboundary of
+      56             :            const std::vector<double> & width_p,           // width of x
+      57             :            const int y_size)           // size of y, for example, ysize=7, then when x=1, the distribution of y in [-2,4] is considered
+      58           9 :     : lowerboundary(lowerboundary_p), upperboundary(upperboundary_p), width(width_p)
+      59             :   {
+      60           9 :     this->dimension = lowerboundary.size();
+      61           9 :     this->y_size = y_size;     // keep in mind the internal (spare) matrix is stored in diagonal form
+      62           9 :     this->y_total_size = int(pow(y_size, dimension) + 0.000001);
+      63             : 
+      64             :     // the range of the matrix is [lowerboundary, upperboundary]
+      65           9 :     x_total_size = 1;
+      66          24 :     for (int i = 0; i < dimension; i++)
+      67             :     {
+      68          15 :       x_size.push_back(int((upperboundary[i] - lowerboundary[i]) / width[i] + 0.000001));
+      69          15 :       x_total_size *= x_size[i];
+      70             :     }
+      71             : 
+      72             :     // initialize the internal matrix
+      73           9 :     matrix.reserve(x_total_size);
+      74         100 :     for (int i = 0; i < x_total_size; i++)
+      75             :     {
+      76         182 :       matrix.push_back(std::vector<int>(y_total_size, 0));
+      77             :     }
+      78             : 
+      79           9 :     temp.resize(dimension);
+      80           9 :   }
+      81             : 
+      82      171000 :   int inline get_value(const std::vector<double> & x, const std::vector<double> & y)
+      83             :   {
+      84             :     //if (matrix[convert_x(x)][convert_y(x, y)]!=0)
+      85             :     //{
+      86             :     //std::cout<<convert_x(x)<<" "<<convert_y(x, y)<<" "<<x[0]<<" "<<x[1]<<" "<<y[0]<<" "<<y[1]<<" ";
+      87             :     //std::cout<<matrix[convert_x(x)][convert_y(x, y)]<<"sadasfdasaaaaaaaa"<<std::endl;
+      88             :     //}
+      89      171000 :     return matrix[convert_x(x)][convert_y(x, y)];
+      90             :   }
+      91             : 
+      92             :   void inline set_value(const std::vector<double> & x, const std::vector<double> & y, const int value)
+      93             :   {
+      94             :     matrix[convert_x(x)][convert_y(x,y)] = value;
+      95             :   }
+      96             : 
+      97          87 :   void inline increase_value(const std::vector<double> & x, const std::vector<double> & y, const int value)
+      98             :   {
+      99          87 :     matrix[convert_x(x)][convert_y(x,y)] += value;
+     100          87 :   }
+     101             : 
+     102             : private:
+     103             :   std::vector<double> lowerboundary;
+     104             :   std::vector<double> upperboundary;
+     105             :   std::vector<double> width;
+     106             :   int dimension;
+     107             :   std::vector<int> x_size;       // the size of x in each dimension
+     108             :   int x_total_size;              // the size of x of the internal matrix
+     109             :   int y_size;                    // the size of y in each dimension
+     110             :   int y_total_size;              // the size of y of the internal matrix
+     111             : 
+     112             :   std::vector<std::vector<int> > matrix;  // the internal matrix
+     113             : 
+     114             :   std::vector<int> temp;         // this vector is used in convert_x and convert_y to save computational resource
+     115             : 
+     116      171087 :   int convert_x(const std::vector<double> & x)        // convert real x value to its interal index
+     117             :   {
+     118      510684 :     for (int i = 0; i < dimension; i++)
+     119             :     {
+     120      339597 :       temp[i] = int((x[i] - lowerboundary[i]) / width[i] + 0.000001);
+     121             :     }
+     122             : 
+     123             :     int index = 0;
+     124      510684 :     for (int i = 0; i < dimension; i++)
+     125             :     {
+     126      339597 :       if (i + 1 < dimension)
+     127             :       {
+     128             :         int x_temp = 1;
+     129      337020 :         for (int j = i + 1; j < dimension; j++)
+     130      168510 :           x_temp *= x_size[j];
+     131      168510 :         index += temp[i] * x_temp;
+     132             :       }
+     133             :       else
+     134      171087 :         index += temp[i];
+     135             :     }
+     136      171087 :     return index;
+     137             :   }
+     138             : 
+     139      171087 :   int convert_y(const std::vector<double> & x, const std::vector<double> & y)        // convert real y value to its interal index
+     140             :   {
+     141      510684 :     for (int i = 0; i < dimension; i++)
+     142             :     {
+     143      339597 :       temp[i] = round((round(y[i] / width[i] + 0.000001) - round(x[i] / width[i] + 0.000001)) + (y_size - 1) / 2 + 0.000001);
+     144             :     }
+     145             : 
+     146             :     int index = 0;
+     147      510684 :     for (int i = 0; i < dimension; i++)
+     148             :     {
+     149      339597 :       if (i + 1 < dimension)
+     150      168510 :         index += temp[i] * int(pow(y_size, dimension - i - 1) + 0.000001);
+     151             :       else
+     152      171087 :         index += temp[i];
+     153             :     }
+     154      171087 :     return index;
+     155             :   }
+     156             : 
+     157     1018791 :   double round(double r)
+     158             :   {
+     159     1018791 :     return (r > 0.0) ? floor(r + 0.5) : ceil(r - 0.5);
+     160             :   }
+     161             : };
+     162             : 
+     163             : // vector, store the sum_x, sum_x_square, count_y
+     164             : template <typename T>
+     165             : class n_vector
+     166             : {
+     167             : public:
+     168         126 :   n_vector() {}
+     169          92 :   n_vector(const std::vector<double> & lowerboundary,   // lowerboundary of x
+     170             :            const std::vector<double> & upperboundary,   // upperboundary of
+     171             :            const std::vector<double> & width_p,                // width of x
+     172             :            const int y_size,           // size of y, for example, ysize=7, then when x=1, the distribution of y in [-2,4] is considered
+     173             :            const T & default_value)          //   the default value of T
+     174          92 :     :width(width_p)
+     175             :   {
+     176          92 :     this->dimension = lowerboundary.size();
+     177             : 
+     178          92 :     x_total_size = 1;
+     179         252 :     for (int i = 0; i < dimension; i++)
+     180             :     {
+     181         160 :       this->lowerboundary.push_back(lowerboundary[i] - (y_size - 1) / 2 * width[i] - 0.000001);
+     182         160 :       this->upperboundary.push_back(upperboundary[i] + (y_size - 1) / 2 * width[i] + 0.000001);
+     183             : 
+     184         160 :       x_size.push_back(int((this->upperboundary[i] - this->lowerboundary[i]) / this->width[i] + 0.000001));
+     185         160 :       x_total_size *= x_size[i];
+     186             :     }
+     187             : 
+     188             :     // initialize the internal vector
+     189          92 :     vector.resize(x_total_size, default_value);
+     190             : 
+     191          92 :     temp.resize(dimension);
+     192          92 :   }
+     193             : 
+     194      288432 :   T inline get_value(const std::vector<double> & x)
+     195             :   {
+     196      288432 :     return vector[convert_x(x)];
+     197             :   }
+     198             : 
+     199       27227 :   void inline set_value(const std::vector<double> & x, const T & value)
+     200             :   {
+     201       27227 :     vector[convert_x(x)] = value;
+     202       27227 :   }
+     203             : 
+     204         409 :   void inline increase_value(const std::vector<double> & x, const T & value)
+     205             :   {
+     206         409 :     vector[convert_x(x)] += value;
+     207         409 :   }
+     208             : private:
+     209             :   std::vector<double> lowerboundary;
+     210             :   std::vector<double> upperboundary;
+     211             :   std::vector<double> width;
+     212             :   int dimension;
+     213             :   std::vector<int> x_size;       // the size of x in each dimension
+     214             :   int x_total_size;              // the size of x of the internal matrix
+     215             : 
+     216             :   std::vector<T> vector;  // the internal vector
+     217             : 
+     218             :   std::vector<int> temp;         // this vector is used in convert_x and convert_y to save computational resource
+     219             : 
+     220      316068 :   int convert_x(const std::vector<double> & x)        // convert real x value to its interal index
+     221             :   {
+     222      943161 :     for (int i = 0; i < dimension; i++)
+     223             :     {
+     224      627093 :       temp[i] = int((x[i] - lowerboundary[i]) / width[i] + 0.000001);
+     225             :     }
+     226             : 
+     227             :     int index = 0;
+     228      943161 :     for (int i = 0; i < dimension; i++)
+     229             :     {
+     230      627093 :       if (i + 1 < dimension)
+     231             :       {
+     232             :         int x_temp = 1;
+     233      622050 :         for (int j = i + 1; j < dimension; j++)
+     234      311025 :           x_temp *= x_size[j];
+     235      311025 :         index += temp[i] * x_temp;
+     236             :       }
+     237             :       else
+     238      316068 :         index += temp[i];
+     239             :     }
+     240      316068 :     return index;
+     241             :   }
+     242             : };
+     243             : 
+     244             : class UIestimator      // the implemension of UI estimator
+     245             : {
+     246             : public:
+     247          12 :   UIestimator() {}
+     248             : 
+     249             :   //called when (re)start an eabf simulation
+     250           9 :   UIestimator(const std::vector<double>& lowerboundary_p,
+     251             :               const std::vector<double>& upperboundary_p,
+     252             :               const std::vector<double>& width_p,
+     253             :               const std::vector<double>& krestr_p,                // force constant in eABF
+     254             :               const std::string& output_filename_p,              // the prefix of output files
+     255             :               const int output_freq_p,
+     256             :               const bool restart_p,                              // whether restart from a .count and a .grad file
+     257             :               const std::vector<std::string>& input_filename_p,   // the prefixes of input files
+     258             :               const double temperature_p)
+     259           9 :     : lowerboundary(lowerboundary_p), upperboundary(upperboundary_p),
+     260           9 :       width(width_p), krestr(krestr_p),
+     261           9 :       output_filename(output_filename_p), output_freq(output_freq_p),
+     262           9 :       restart(restart_p), input_filename(input_filename_p),
+     263          18 :       temperature(temperature_p)
+     264             :   {
+     265             : 
+     266           9 :     dimension = lowerboundary.size();
+     267             : 
+     268          24 :     for (int i = 0; i < dimension; i++)
+     269             :     {
+     270          30 :       sum_x.push_back(n_vector<double>(lowerboundary, upperboundary, width, Y_SIZE, 0.0));
+     271          30 :       sum_x_square.push_back(n_vector<double>(lowerboundary, upperboundary, width, Y_SIZE, 0.0));
+     272             : 
+     273          30 :       x_av.push_back(n_vector<double>(lowerboundary, upperboundary, width, Y_SIZE, 0.0));
+     274          30 :       sigma_square.push_back(n_vector<double>(lowerboundary, upperboundary, width, Y_SIZE, 0.0));
+     275             :     }
+     276             : 
+     277           9 :     count_y = n_vector<int>(lowerboundary, upperboundary, width, Y_SIZE, 0);
+     278           9 :     distribution_x_y = n_matrix(lowerboundary, upperboundary, width, Y_SIZE);
+     279             : 
+     280           9 :     grad = n_vector<std::vector<double> >(lowerboundary, upperboundary, width, 1, std::vector<double>(dimension, 0.0));
+     281           9 :     count = n_vector<int>(lowerboundary, upperboundary, width, 1, 0);
+     282             : 
+     283           9 :     written = false;
+     284           9 :     written_1D = false;
+     285             : 
+     286           9 :     if (dimension == 1)
+     287             :     {
+     288           3 :       std::vector<double> upperboundary_temp = upperboundary;
+     289           3 :       upperboundary_temp[0] = upperboundary[0] + width[0];
+     290           3 :       oneD_pmf = n_vector<double>(lowerboundary, upperboundary_temp, width, 1, 0.0);
+     291             :     }
+     292             : 
+     293           9 :     if (restart == true)
+     294             :     {
+     295           1 :       input_grad = n_vector<std::vector<double> >(lowerboundary, upperboundary, width, 1, std::vector<double>(dimension, 0.0));
+     296           1 :       input_count = n_vector<int>(lowerboundary, upperboundary, width, 1, 0);
+     297             : 
+     298             :       // initialize input_Grad and input_count
+     299           1 :       std::vector<double> loop_flag(dimension, 0);
+     300           3 :       for (int i = 0; i < dimension; i++)
+     301             :       {
+     302           2 :         loop_flag[i] = lowerboundary[i];
+     303             :       }
+     304             :       while (true)
+     305             :       {
+     306          27 :         for (int i = 0; i < dimension; i++)
+     307             :         {
+     308          36 :           input_grad.set_value(loop_flag, std::vector<double>(dimension,0));
+     309             :         }
+     310           9 :         input_count.set_value(loop_flag, 0);
+     311             : 
+     312             :         // iterate over any dimensions
+     313           9 :         int i = dimension - 1;
+     314             :         while (true)
+     315             :         {
+     316          12 :           loop_flag[i] += width[i];
+     317          12 :           if (loop_flag[i] > upperboundary[i] - width[i] + 0.00001)
+     318             :           {
+     319           4 :             loop_flag[i] = lowerboundary[i];
+     320           4 :             i--;
+     321           4 :             if (i < 0)
+     322           1 :               goto INITIAL_LOOPEND;
+     323             :           }
+     324             :           else
+     325             :             break;
+     326             :         }
+     327             :       }
+     328             : INITIAL_LOOPEND:
+     329           1 :       read_inputfiles(input_filename);
+     330             :     }
+     331           9 :   }
+     332             : 
+     333          42 :   ~UIestimator() {}
+     334             : 
+     335             :   // called from MD engine every step
+     336          87 :   bool update(const int step, const std::vector<double> & x, std::vector<double> y)
+     337             :   {
+     338             : 
+     339             :     //std::cout<<"weeeee: :"<<std::endl;
+     340             :     //for (int i = 0; i < dimension; i++)
+     341             :     //{
+     342             :     //  std::cout<<x[i]<<" "<<y[i]<<" ";
+     343             :     //}
+     344             :     //std::cout<<std::endl;
+     345             : 
+     346          87 :     if (step % output_freq == 0)
+     347             :     {
+     348          21 :       calc_pmf();
+     349          21 :       write_files();
+     350             :       //write_interal_data();
+     351             :     }
+     352             : 
+     353         246 :     for (int i = 0; i < dimension; i++)
+     354             :     {
+     355             :       // for dihedral RC, it is possible that x = 179 and y = -179, should correct it
+     356             :       // may have problem, need to fix
+     357         159 :       if (x[i] > 150 && y[i] < -150)
+     358             :       {
+     359             :         //std::vector<double> x_temp(x);
+     360             :         //x_temp[i] -= 360;
+     361             :         //update(7, x_temp, y);
+     362           0 :         y[i] += 360;
+     363             :       }
+     364         159 :       if (x[i] < -150 && y[i] > 150)
+     365             :       {
+     366             :         //std::vector<double> x_temp(x);
+     367             :         //x_temp[i] += 360;
+     368             :         //update(7, x_temp, y);
+     369           0 :         y[i] -= 360;
+     370             :       }
+     371             : 
+     372         159 :       if (x[i] < lowerboundary[i] - EXTENDED_X_SIZE * width[i] + 0.00001 || x[i] > upperboundary[i] + EXTENDED_X_SIZE * width[i] - 0.00001 \
+     373         159 :           || y[i] - x[i] < -HALF_Y_SIZE * width[i] + 0.00001 || y[i] - x[i] > HALF_Y_SIZE * width[i] - 0.00001 \
+     374         318 :           || y[i] - lowerboundary[i] < -HALF_Y_SIZE * width[i] + 0.00001 || y[i] - upperboundary[i] > HALF_Y_SIZE * width[i] - 0.00001)
+     375             :         return false;
+     376             :     }
+     377             : 
+     378             :     //for (int i = 0; i < dimension; i++)
+     379             :     //{
+     380             :     //  std::cout<<x[i]<<" "<<y[i]<<" ";
+     381             :     //}
+     382             :     //std::cout<<std::endl;
+     383             : 
+     384         246 :     for (int i = 0; i < dimension; i++)
+     385             :     {
+     386         159 :       sum_x[i].increase_value(y, x[i]);
+     387         159 :       sum_x_square[i].increase_value(y, x[i] * x[i]);
+     388             :     }
+     389          87 :     count_y.increase_value(y, 1);
+     390             : 
+     391         246 :     for (int i = 0; i < dimension; i++)
+     392             :     {
+     393             :       //if (x[i] < lowerboundary[i] + 0.000001 || x[i] > upperboundary[i] - 0.000001)
+     394             :       // adapt colvars precision
+     395         159 :       if (x[i] < lowerboundary[i] + 0.00001 || x[i] > upperboundary[i] - 0.00001)
+     396             :         return false;
+     397             :     }
+     398          87 :     distribution_x_y.increase_value(x, y, 1);
+     399             : 
+     400          87 :     return true;
+     401             :   }
+     402             : 
+     403             :   // update the output_filename
+     404             :   void update_output_filename(const std::string& filename)
+     405             :   {
+     406          87 :     output_filename = filename;
+     407             :   }
+     408             : 
+     409             : private:
+     410             :   std::vector<n_vector<double> > sum_x;                        // the sum of x in each y bin
+     411             :   std::vector<n_vector<double> > sum_x_square;                 // the sum of x in each y bin
+     412             :   n_vector<int> count_y;                              // the distribution of y
+     413             :   n_matrix distribution_x_y;   // the distribution of <x, y> pair
+     414             : 
+     415             :   int dimension;
+     416             : 
+     417             :   std::vector<double> lowerboundary;
+     418             :   std::vector<double> upperboundary;
+     419             :   std::vector<double> width;
+     420             :   std::vector<double> krestr;
+     421             :   std::string output_filename;
+     422             :   int output_freq;
+     423             :   bool restart;
+     424             :   std::vector<std::string> input_filename;
+     425             :   double temperature;
+     426             : 
+     427             :   n_vector<std::vector<double> > grad;
+     428             :   n_vector<int> count;
+     429             : 
+     430             :   n_vector<double> oneD_pmf;
+     431             : 
+     432             :   n_vector<std::vector<double> > input_grad;
+     433             :   n_vector<int> input_count;
+     434             : 
+     435             :   // used in double integration
+     436             :   std::vector<n_vector<double> > x_av;
+     437             :   std::vector<n_vector<double> > sigma_square;
+     438             : 
+     439             :   bool written;
+     440             :   bool written_1D;
+     441             : 
+     442             :   // calculate gradients from the internal variables
+     443          21 :   void calc_pmf()
+     444             :   {
+     445             :     int norm;
+     446             : 
+     447          21 :     std::vector<double> loop_flag(dimension, 0);
+     448          54 :     for (int i = 0; i < dimension; i++)
+     449             :     {
+     450          33 :       loop_flag[i] = lowerboundary[i] - HALF_Y_SIZE * width[i];
+     451             :     }
+     452             : 
+     453             :     while (true)
+     454             :     {
+     455        6783 :       norm = count_y.get_value(loop_flag) > 0 ? count_y.get_value(loop_flag) : 1;
+     456       20106 :       for (int i = 0; i < dimension; i++)
+     457             :       {
+     458       13323 :         x_av[i].set_value(loop_flag, sum_x[i].get_value(loop_flag) / norm);
+     459       13323 :         sigma_square[i].set_value(loop_flag, sum_x_square[i].get_value(loop_flag) / norm - x_av[i].get_value(loop_flag) * x_av[i].get_value(loop_flag));
+     460             :       }
+     461             : 
+     462             :       // iterate over any dimensions
+     463        6783 :       int i = dimension - 1;
+     464             :       while (true)
+     465             :       {
+     466        7063 :         loop_flag[i] += width[i];
+     467        7063 :         if (loop_flag[i] > upperboundary[i] + HALF_Y_SIZE * width[i] - width[i] + 0.00001)
+     468             :         {
+     469         301 :           loop_flag[i] = lowerboundary[i] - HALF_Y_SIZE * width[i];
+     470         301 :           i--;
+     471         301 :           if (i < 0)
+     472          21 :             goto LOOPEND;
+     473             :         }
+     474             :         else
+     475             :           break;
+     476             :       }
+     477             :     }
+     478             : LOOPEND:
+     479             : 
+     480             :     // double integration
+     481          21 :     std::vector<double> av(dimension, 0);
+     482          21 :     std::vector<double> diff_av(dimension, 0);
+     483             : 
+     484          21 :     std::vector<double> loop_flag_x(dimension, 0);
+     485          21 :     std::vector<double> loop_flag_y(dimension, 0);
+     486          54 :     for (int i = 0; i < dimension; i++)
+     487             :     {
+     488          33 :       loop_flag_x[i] = lowerboundary[i];
+     489          33 :       loop_flag_y[i] = loop_flag_x[i] - HALF_Y_SIZE * width[i];
+     490             :     }
+     491             : 
+     492             :     while (true)
+     493             :     {
+     494         203 :       norm = 0;
+     495         546 :       for (int i = 0; i < dimension; i++)
+     496             :       {
+     497         343 :         av[i] = 0;
+     498         343 :         diff_av[i] = 0;
+     499         343 :         loop_flag_y[i] = loop_flag_x[i] - HALF_Y_SIZE * width[i];
+     500             :       }
+     501             : 
+     502             :       while (true)
+     503             :       {
+     504             :         //std::cout<<"pppppppppppppppppppppp "<<loop_flag_x[0]<<" "<<loop_flag_x[1]<<" "<<loop_flag_y[0]<<" "<<loop_flag_y[1]<<std::endl;
+     505       57260 :         norm += distribution_x_y.get_value(loop_flag_x, loop_flag_y);
+     506      170520 :         for (int i = 0; i < dimension; i++)
+     507             :         {
+     508      113260 :           if (sigma_square[i].get_value(loop_flag_y) > 0.00001 || sigma_square[i].get_value(loop_flag_y) < -0.00001)
+     509         480 :             av[i] += distribution_x_y.get_value(loop_flag_x, loop_flag_y) * ( (loop_flag_x[i] + 0.5 * width[i]) - x_av[i].get_value(loop_flag_y)) / sigma_square[i].get_value(loop_flag_y);
+     510             : 
+     511      113260 :           diff_av[i] += distribution_x_y.get_value(loop_flag_x, loop_flag_y) * (loop_flag_x[i] - loop_flag_y[i]);
+     512             :         }
+     513             : 
+     514             :         // iterate over any dimensions
+     515       57260 :         int i = dimension - 1;
+     516             :         while (true)
+     517             :         {
+     518       60060 :           loop_flag_y[i] += width[i];
+     519       60060 :           if (loop_flag_y[i] > loop_flag_x[i] + HALF_Y_SIZE * width[i] - width[i] + 0.00001)
+     520             :           {
+     521        3003 :             loop_flag_y[i] = loop_flag_x[i] - HALF_Y_SIZE * width[i];
+     522        3003 :             i--;
+     523        3003 :             if (i < 0)
+     524         203 :               goto LOOPEND2;
+     525             :           }
+     526             :           else
+     527             :             break;
+     528             :         }
+     529             :       }
+     530             : LOOPEND2:
+     531             : 
+     532         203 :       std::vector<double> grad_temp(dimension, 0);
+     533         546 :       for (int i = 0; i < dimension; i++)
+     534             :       {
+     535         343 :         diff_av[i] /= (norm > 0 ? norm : 1);
+     536         343 :         av[i] = BOLTZMANN * temperature * av[i] / (norm > 0 ? norm : 1);
+     537         343 :         grad_temp[i] = av[i] - krestr[i] * diff_av[i];
+     538             :       }
+     539         203 :       grad.set_value(loop_flag_x, grad_temp);
+     540         203 :       count.set_value(loop_flag_x, norm);
+     541             : 
+     542             :       // iterate over any dimensions
+     543         203 :       int i = dimension - 1;
+     544             :       while (true)
+     545             :       {
+     546         243 :         loop_flag_x[i] += width[i];
+     547         243 :         if (loop_flag_x[i] > upperboundary[i] - width[i] + 0.00001)
+     548             :         {
+     549          61 :           loop_flag_x[i] = lowerboundary[i];
+     550          61 :           i--;
+     551          61 :           if (i < 0)
+     552          21 :             goto LOOPEND3;
+     553             :         }
+     554             :         else
+     555             :           break;
+     556             :       }
+     557             :     }
+     558             : LOOPEND3:;
+     559          21 :   }
+     560             : 
+     561             : 
+     562             :   // calculate 1D pmf
+     563           9 :   void calc_1D_pmf()
+     564             :   {
+     565           9 :     std::vector<double> last_position(1, 0);
+     566           9 :     std::vector<double> position(1, 0);
+     567             : 
+     568             :     double min = 0;
+     569           9 :     double dG = 0;
+     570             : 
+     571           9 :     oneD_pmf.set_value(lowerboundary, 0);
+     572           9 :     last_position = lowerboundary;
+     573          72 :     for (double i = lowerboundary[0] + width[0]; i < upperboundary[0] + 0.000001; i += width[0])
+     574             :     {
+     575          63 :       position[0] = i + 0.000001;
+     576          63 :       if (restart == false || input_count.get_value(last_position) == 0)
+     577             :       {
+     578          63 :         dG = oneD_pmf.get_value(last_position) + grad.get_value(last_position)[0] * width[0];
+     579             :       }
+     580             :       else
+     581             :       {
+     582           0 :         dG = oneD_pmf.get_value(last_position) + ((grad.get_value(last_position)[0] * count.get_value(last_position) + input_grad.get_value(last_position)[0] * input_count.get_value(last_position)) / (count.get_value(last_position) + input_count.get_value(last_position))) * width[0];
+     583             :       }
+     584          63 :       if (dG < min)
+     585             :         min = dG;
+     586          63 :       oneD_pmf.set_value(position, dG);
+     587          63 :       last_position[0] = i + 0.000001;
+     588             :     }
+     589             : 
+     590          81 :     for (double i = lowerboundary[0]; i < upperboundary[0] + 0.000001; i += width[0])
+     591             :     {
+     592          72 :       position[0] = i + 0.000001;
+     593          72 :       oneD_pmf.set_value(position, oneD_pmf.get_value(position) - min);
+     594             :     }
+     595           9 :   }
+     596             : 
+     597             :   // write 1D pmf
+     598           9 :   void write_1D_pmf()
+     599             :   {
+     600           9 :     std::string pmf_filename = output_filename + ".UI.pmf";
+     601             : 
+     602             :     // only for colvars module!
+     603             : //                      if (written_1D) cvm::backup_file(pmf_filename.c_str());
+     604             : 
+     605           9 :     std::ofstream ofile_pmf(pmf_filename.c_str());
+     606             : 
+     607           9 :     std::vector<double> position(1, 0);
+     608          81 :     for (double i = lowerboundary[0]; i < upperboundary[0] + 0.000001; i += width[0])
+     609             :     {
+     610          72 :       ofile_pmf << i << " ";
+     611          72 :       position[0] = i + 0.000001;
+     612          72 :       ofile_pmf << oneD_pmf.get_value(position) << std::endl;
+     613             :     }
+     614           9 :     ofile_pmf.close();
+     615             : 
+     616           9 :     written_1D = true;
+     617          18 :   }
+     618             : 
+     619             :   // write heads of the output files
+     620          63 :   void writehead(std::ofstream& os) const
+     621             :   {
+     622          63 :     os << "# " << dimension << std::endl;
+     623         162 :     for (int i = 0; i < dimension; i++)
+     624             :     {
+     625          99 :       os.precision(std::numeric_limits<double>::max_digits10);
+     626         198 :       os << "# " << std::fixed << lowerboundary[i] << " " << width[i] << " " << int((upperboundary[i] - lowerboundary[i]) / width[i] + 0.000001) << " " << 0 << std::endl;
+     627             :     }
+     628             :     os << std::endl;
+     629          63 :   }
+     630             : 
+     631             :   // write interal data, used for testing
+     632             : //   void write_interal_data()
+     633             : //   {
+     634             : //     std::string internal_filaname = output_filename + ".UI.internal";
+     635             : //
+     636             : //     std::ofstream ofile_internal(internal_filaname.c_str());
+     637             : //
+     638             : //     std::vector<double> loop_flag(dimension, 0);
+     639             : //     for (int i = 0; i < dimension; i++)
+     640             : //     {
+     641             : //       loop_flag[i] = lowerboundary[i];
+     642             : //     }
+     643             : //     while (true)
+     644             : //     {
+     645             : //       for (int i = 0; i < dimension; i++)
+     646             : //       {
+     647             : //         ofile_internal << loop_flag[i] + 0.5 * width[i] << " ";
+     648             : //       }
+     649             : //
+     650             : //       for (int i = 0; i < dimension; i++)
+     651             : //       {
+     652             : //         ofile_internal << grad.get_value(loop_flag)[i] << " ";
+     653             : //       }
+     654             : //
+     655             : //       std::vector<double> ii(dimension,0);
+     656             : //       for (double i = loop_flag[0] - 10; i < loop_flag[0] + 10 + 0.00001; i+= width[0])
+     657             : //       {
+     658             : //         for (double j = loop_flag[1] - 10; j< loop_flag[1] + 10 +0.00001; j+=width[1])
+     659             : //         {
+     660             : //           ii[0] = i;
+     661             : //           ii[1] = j;
+     662             : //           ofile_internal << i <<" "<<j<<" "<< distribution_x_y.get_value(loop_flag,ii)<< " ";
+     663             : //         }
+     664             : //       }
+     665             : //       ofile_internal << std::endl;
+     666             : //
+     667             : //       // iterate over any dimensions
+     668             : //       int i = dimension - 1;
+     669             : //       while (true)
+     670             : //       {
+     671             : //         loop_flag[i] += width[i];
+     672             : //         if (loop_flag[i] > upperboundary[i] - width[i] + 0.00001)
+     673             : //         {
+     674             : //           loop_flag[i] = lowerboundary[i];
+     675             : //           i--;
+     676             : //           if (i < 0)
+     677             : //             goto LOOPEND5;
+     678             : //         }
+     679             : //         else
+     680             : //           break;
+     681             : //       }
+     682             : //     }
+     683             : // LOOPEND5:
+     684             : //     ofile_internal.close();
+     685             : //   }
+     686             : 
+     687             :   // write output files
+     688          21 :   void write_files()
+     689             :   {
+     690          21 :     std::string grad_filename = output_filename + ".UI.grad";
+     691          21 :     std::string hist_filename = output_filename + ".UI.hist.grad";
+     692          21 :     std::string count_filename = output_filename + ".UI.count";
+     693             : 
+     694             :     // only for colvars module!
+     695             : //                      if (written) cvm::backup_file(grad_filename.c_str());
+     696             :     //if (written) cvm::backup_file(hist_filename.c_str());
+     697             : //                      if (written) cvm::backup_file(count_filename.c_str());
+     698             : 
+     699          21 :     std::ofstream ofile(grad_filename.c_str());
+     700          21 :     std::ofstream ofile_hist(hist_filename.c_str(), std::ios::app);
+     701          21 :     std::ofstream ofile_count(count_filename.c_str());
+     702             : 
+     703          21 :     writehead(ofile);
+     704          21 :     writehead(ofile_hist);
+     705          21 :     writehead(ofile_count);
+     706             : 
+     707          21 :     if (dimension == 1)
+     708             :     {
+     709           9 :       calc_1D_pmf();
+     710           9 :       write_1D_pmf();
+     711             :     }
+     712             : 
+     713          21 :     std::vector<double> loop_flag(dimension, 0);
+     714          54 :     for (int i = 0; i < dimension; i++)
+     715             :     {
+     716          33 :       loop_flag[i] = lowerboundary[i];
+     717             :     }
+     718             :     while (true)
+     719             :     {
+     720         546 :       for (int i = 0; i < dimension; i++)
+     721             :       {
+     722         343 :         ofile << std::fixed << std::setprecision(6) << loop_flag[i] + 0.5 * width[i] << " ";
+     723         343 :         ofile_hist << std::fixed << std::setprecision(6) << loop_flag[i] + 0.5 * width[i] << " ";
+     724         343 :         ofile_count << std::fixed << std::setprecision(6) << loop_flag[i] + 0.5 * width[i] << " ";
+     725             :       }
+     726             : 
+     727         203 :       if (restart == false)
+     728             :       {
+     729         492 :         for (int i = 0; i < dimension; i++)
+     730             :         {
+     731         614 :           ofile << std::fixed << std::setprecision(6) << grad.get_value(loop_flag)[i] << " ";
+     732         614 :           ofile_hist << std::fixed << std::setprecision(6) << grad.get_value(loop_flag)[i] << " ";
+     733             :         }
+     734             :         ofile << std::endl;
+     735             :         ofile_hist << std::endl;
+     736         185 :         ofile_count << count.get_value(loop_flag) << " " <<std::endl;
+     737             :       }
+     738             :       else
+     739             :       {
+     740             :         double final_grad = 0;
+     741          54 :         for (int i = 0; i < dimension; i++)
+     742             :         {
+     743          36 :           int total_count_temp = (count.get_value(loop_flag) + input_count.get_value(loop_flag));
+     744          36 :           if (input_count.get_value(loop_flag) == 0)
+     745          20 :             final_grad = grad.get_value(loop_flag)[i];
+     746             :           else
+     747          16 :             final_grad = ((grad.get_value(loop_flag)[i] * count.get_value(loop_flag) + input_grad.get_value(loop_flag)[i] * input_count.get_value(loop_flag)) / total_count_temp);
+     748          36 :           ofile << std::fixed << std::setprecision(6) << final_grad << " ";
+     749          36 :           ofile_hist << std::fixed << std::setprecision(6) << final_grad << " ";
+     750             :         }
+     751             :         ofile << std::endl;
+     752             :         ofile_hist << std::endl;
+     753          18 :         ofile_count << (count.get_value(loop_flag) + input_count.get_value(loop_flag)) << " " <<std::endl;
+     754             :       }
+     755             : 
+     756             :       // iterate over any dimensions
+     757         203 :       int i = dimension - 1;
+     758             :       while (true)
+     759             :       {
+     760         243 :         loop_flag[i] += width[i];
+     761         243 :         if (loop_flag[i] > upperboundary[i] - width[i] + 0.00001)
+     762             :         {
+     763          61 :           loop_flag[i] = lowerboundary[i];
+     764          61 :           i--;
+     765             :           ofile << std::endl;
+     766             :           ofile_hist << std::endl;
+     767             :           ofile_count << std::endl;
+     768          61 :           if (i < 0)
+     769          21 :             goto LOOPEND4;
+     770             :         }
+     771             :         else
+     772             :           break;
+     773             :       }
+     774             :     }
+     775             : LOOPEND4:
+     776          21 :     ofile.close();
+     777          21 :     ofile_count.close();
+     778          21 :     ofile_hist.close();
+     779             : 
+     780          21 :     written = true;
+     781          42 :   }
+     782             : 
+     783             :   // read input files
+     784           1 :   void read_inputfiles(const std::vector<std::string>& input_filename)
+     785             :   {
+     786             :     char sharp;
+     787             :     double nothing;
+     788             :     int dimension_temp;
+     789             : 
+     790           1 :     std::vector<double> loop_bin_size(dimension, 0);
+     791           1 :     std::vector<double> position_temp(dimension, 0);
+     792           1 :     std::vector<double> grad_temp(dimension, 0);
+     793           1 :     int count_temp = 0;
+     794           2 :     for (unsigned int i = 0; i < input_filename.size(); i++)
+     795             :     {
+     796           1 :       int size = 1, size_temp = 0;
+     797             : 
+     798           1 :       std::string count_filename = input_filename[i] + ".UI.count";
+     799           1 :       std::string grad_filename = input_filename[i] + ".UI.grad";
+     800             : 
+     801           1 :       std::ifstream count_file(count_filename.c_str(), std::ios::in);
+     802           1 :       std::ifstream grad_file(grad_filename.c_str(), std::ios::in);
+     803             : 
+     804           1 :       count_file >> sharp >> dimension_temp;
+     805           1 :       grad_file >> sharp >> dimension_temp;
+     806             : 
+     807           3 :       for (int j = 0; j < dimension; j++)
+     808             :       {
+     809           4 :         count_file >> sharp >> nothing >> nothing >> size_temp >> nothing;
+     810           2 :         grad_file >> sharp >> nothing >> nothing >> nothing >> nothing;
+     811           2 :         size *= size_temp;
+     812             :       }
+     813             : 
+     814          10 :       for (int j = 0; j < size; j++)
+     815             :       {
+     816             :         do
+     817             :         {
+     818          27 :           for (int k = 0; k < dimension; k++)
+     819             :           {
+     820          18 :             count_file >> position_temp[k];
+     821             :             grad_file >> nothing;
+     822             :           }
+     823             : 
+     824          27 :           for (int l = 0; l < dimension; l++)
+     825             :           {
+     826          18 :             grad_file >> grad_temp[l];
+     827             :           }
+     828           9 :           count_file >> count_temp;
+     829             :         }
+     830           9 :         while (position_temp[i] < lowerboundary[i] - 0.000001 || position_temp[i] > upperboundary[i] + 0.000001);
+     831             : 
+     832           9 :         if (count_temp == 0)
+     833             :         {
+     834           5 :           continue;
+     835             :         }
+     836             : 
+     837          12 :         for (int m = 0; m < dimension; m++)
+     838             :         {
+     839           8 :           grad_temp[m] = (grad_temp[m] * count_temp + input_grad.get_value(position_temp)[m] * input_count.get_value(position_temp)) / (count_temp + input_count.get_value(position_temp));
+     840             :         }
+     841           4 :         input_grad.set_value(position_temp, grad_temp);
+     842           4 :         input_count.increase_value(position_temp, count_temp);
+     843             :       }
+     844             : 
+     845           1 :       count_file.close();
+     846           1 :       grad_file.close();
+     847           1 :     }
+     848           1 :   }
+     849             : };
+     850             : }
+     851             : 
+     852             : }
+     853             : }
+     854             : 
+     855             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/drrtool.cpp.func-sort-c.html b/coverage/drr/drrtool.cpp.func-sort-c.html new file mode 100644 index 000000000000..97d69797c827 --- /dev/null +++ b/coverage/drr/drrtool.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - drr/drrtool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - drrtool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687294.4 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr7drrtool14calcDivergenceERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_1
_ZN4PLMD3drr7drrtool10extractdrrERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE2
_ZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_2
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlRKS8_E_clESE_2
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlRKS8_SE_E0_clESE_SE_2
_ZNK4PLMD3drr7drrtool11descriptionB5cxx11Ev4
_ZN4PLMD3drr7drrtool4mainEP8_IO_FILES3_RNS_12CommunicatorE5
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMe6createERKNS_13CLToolOptionsE9
_ZN4PLMD3drr7drrtoolC2ERKNS_13CLToolOptionsE9
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeC2Ev4187
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeD2Ev4187
_ZN4PLMD3drr7drrtool16registerKeywordsERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/drrtool.cpp.func.html b/coverage/drr/drrtool.cpp.func.html new file mode 100644 index 000000000000..a25180c46dc1 --- /dev/null +++ b/coverage/drr/drrtool.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - drr/drrtool.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - drrtool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687294.4 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMe6createERKNS_13CLToolOptionsE9
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeC2Ev4187
_ZN4PLMD3drr12_GLOBAL__N_117drrtoolRegisterMeD2Ev4187
_ZN4PLMD3drr7drrtool10extractdrrERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE2
_ZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_2
_ZN4PLMD3drr7drrtool14calcDivergenceERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_1
_ZN4PLMD3drr7drrtool16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD3drr7drrtool4mainEP8_IO_FILES3_RNS_12CommunicatorE5
_ZN4PLMD3drr7drrtoolC2ERKNS_13CLToolOptionsE9
_ZNK4PLMD3drr7drrtool11descriptionB5cxx11Ev4
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlRKS8_E_clESE_2
_ZZN4PLMD3drr7drrtool12mergewindowsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EES8_ENKUlRKS8_SE_E0_clESE_SE_2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/drrtool.cpp.gcov.html b/coverage/drr/drrtool.cpp.gcov.html new file mode 100644 index 000000000000..09b6bd09b878 --- /dev/null +++ b/coverage/drr/drrtool.cpp.gcov.html @@ -0,0 +1,345 @@ + + + + + + + + LCOV - plumed test coverage - drr/drrtool.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drr - drrtool.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:687294.4 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :     Copyright (c) 2017 of Haochuan Chen (excluding colvar_UIestimator.h)
+       3             :     Copyright (c) 2017 of Haohao Fu (colvar_UIestimator.h)
+       4             : 
+       5             :     This program is free software: you can redistribute it and/or modify
+       6             :     it under the terms of the GNU Lesser General Public License as published
+       7             :     by the Free Software Foundation, either version 3 of the License, or
+       8             :     (at your option) any later version.
+       9             : 
+      10             :     This program is distributed in the hope that it will be useful,
+      11             :     but WITHOUT ANY WARRANTY; without even the implied warranty of
+      12             :     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      13             :     GNU Lesser General Public License for more details.
+      14             : 
+      15             :     You should have received a copy of the GNU Lesser General Public License
+      16             :     along with this program.  If not, see <http://www.gnu.org/licenses/>.
+      17             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      18             : #ifdef __PLUMED_HAS_BOOST_SERIALIZATION
+      19             : #include "cltools/CLTool.h"
+      20             : #include "core/CLToolRegister.h"
+      21             : #include "config/Config.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include "DRR.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "tools/Units.h"
+      26             : #include <boost/archive/binary_iarchive.hpp>
+      27             : #include <boost/archive/binary_oarchive.hpp>
+      28             : #include <boost/serialization/vector.hpp>
+      29             : #include <cstdlib>
+      30             : #include <fstream>
+      31             : #include <iostream>
+      32             : #include <string>
+      33             : 
+      34             : using namespace PLMD;
+      35             : using namespace cltools;
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace drr {
+      39             : 
+      40             : //+PLUMEDOC EABFMOD_TOOLS drr_tool
+      41             : /*
+      42             :  - Extract .grad and .count files from the binary output .drrstate
+      43             :  - Merge windows
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : The following command will extract .grad and .count files.
+      48             : \verbatim
+      49             : plumed drr_tool --extract eabf.drrstate
+      50             : \endverbatim
+      51             : 
+      52             : The following command will merge windows of two .drrstate file, and output the
+      53             : .grad and .count files.
+      54             : \verbatim
+      55             : plumed drr_tool --merge win1.drrstate,win2.drrstate
+      56             : \endverbatim
+      57             : 
+      58             : After getting the .grad and .count file, you can do numerical integration by
+      59             : using abf_integrate tool from
+      60             : https://github.com/Colvars/colvars/tree/master/colvartools
+      61             : \verbatim
+      62             : abf_integrate eabf.czar.grad
+      63             : \endverbatim
+      64             : \note
+      65             : The abf_integrate in colvartools is in kcal/mol, so it may be better to use --units kcal/mol when running drr_tool
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : using std::vector;
+      71             : using std::string;
+      72             : 
+      73             : class drrtool : public CLTool {
+      74             : public:
+      75             :   static void registerKeywords(Keywords &keys);
+      76             :   explicit drrtool(const CLToolOptions &co);
+      77             :   int main(FILE *in, FILE *out, Communicator &pc);
+      78             :   void extractdrr(const vector<string> &filename);
+      79             :   void mergewindows(const vector<string> &filename, string outputname);
+      80             :   void calcDivergence(const vector<string> &filename, const string &fmt);
+      81           4 :   string description() const { return "Extract or merge the drrstate files."; }
+      82             : 
+      83             : private:
+      84             :   bool verbosity;
+      85             :   Units units;
+      86             :   const string suffix{".drrstate"};
+      87             : };
+      88             : 
+      89       12570 : PLUMED_REGISTER_CLTOOL(drrtool, "drr_tool")
+      90             : 
+      91        4187 : void drrtool::registerKeywords(Keywords &keys) {
+      92        4187 :   CLTool::registerKeywords(keys);
+      93        8374 :   keys.add("optional", "--extract", "Extract drrstate file(s)");
+      94        8374 :   keys.add("optional", "--merge", "Merge eABF windows");
+      95        8374 :   keys.add("optional", "--merge_output", "The output filename of the merged result");
+      96        8374 :   keys.add("optional", "--divergence", "Calculate divergence of gradient field (experimental)");
+      97        8374 :   keys.add("optional","--dump-fmt","( default=%%f ) the format to use to dump the output");
+      98        8374 :   keys.add("compulsory","--units","kj/mol","the units of energy can be kj/mol, kcal/mol, j/mol, eV or the conversion factor from kj/mol");
+      99        8374 :   keys.addFlag("-v", false, "Verbose output");
+     100        4187 : }
+     101             : 
+     102           9 : drrtool::drrtool(const CLToolOptions &co) : CLTool(co) {
+     103           9 :   inputdata = commandline;
+     104           9 :   verbosity = false;
+     105           9 : }
+     106             : 
+     107           5 : int drrtool::main(FILE *in, FILE *out, Communicator &pc) {
+     108          10 :   parseFlag("-v", verbosity);
+     109             :   vector<string> stateFilesToExtract;
+     110             :   string unitname;
+     111           5 :   parse("--units",unitname);
+     112           5 :   units.setEnergy( unitname );
+     113           5 :   std::string dumpFmt("%.9f");;
+     114           5 :   parse("--dump-fmt", dumpFmt);
+     115           5 :   bool doextract = parseVector("--extract", stateFilesToExtract);
+     116           5 :   if (doextract) {
+     117           2 :     extractdrr(stateFilesToExtract);
+     118             :   }
+     119             :   vector<string> stateFilesToMerge;
+     120           5 :   bool domerge = parseVector("--merge", stateFilesToMerge);
+     121           5 :   if (domerge) {
+     122             :     string merge_outputname;
+     123           2 :     parse("--merge_output", merge_outputname);
+     124           4 :     mergewindows(stateFilesToMerge, merge_outputname);
+     125             :   }
+     126             :   vector<string> stateFilesToDivergence;
+     127           5 :   bool dodivergence = parseVector("--divergence", stateFilesToDivergence);
+     128           5 :   if (dodivergence) {
+     129           1 :     calcDivergence(stateFilesToDivergence, dumpFmt);
+     130             :   }
+     131           5 :   return 0;
+     132          10 : }
+     133             : 
+     134           2 : void drrtool::extractdrr(const vector<string> &filename) {
+     135           2 :   #pragma omp parallel for
+     136             :   for (size_t j = 0; j < filename.size(); ++j) {
+     137             :     std::ifstream in;
+     138             :     in.open(filename[j]);
+     139             :     boost::archive::binary_iarchive ia(in);
+     140             :     long long int step;
+     141             :     vector<double> fict;
+     142             :     vector<double> vfict;
+     143             :     vector<double> vfict_laststep;
+     144             :     vector<double> ffict;
+     145             :     ABF abfgrid;
+     146             :     CZAR czarestimator;
+     147             :     ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> abfgrid >>
+     148             :        czarestimator;
+     149             :     in.close();
+     150             :     abfgrid.setOutputUnit(units.getEnergy());
+     151             :     czarestimator.setOutputUnit(units.getEnergy());
+     152             :     if (verbosity) {
+     153             :       std::cout << "Output units factor: " << units.getEnergy() << '\n';
+     154             :       std::cout << "Dumping information of extended variables..." << '\n';
+     155             :       std::cout << "Step: " << step << '\n';
+     156             :       for (size_t i = 0; i < fict.size(); ++i) {
+     157             :         std::cout << "Dimension[" << i + 1 << "]:\n"
+     158             :                   << "  Coordinate: " << fict[i] << '\n'
+     159             :                   << "  Velocity: " << vfict[i] << '\n'
+     160             :                   << "  Velocity(laststep): " << vfict_laststep[i] << '\n'
+     161             :                   << "  Force: " << ffict[i] << '\n';
+     162             :       }
+     163             :       std::cout << "Dumping counts and gradients from grids..." << '\n';
+     164             :     }
+     165             :     string outputname(filename[j]);
+     166             :     outputname.resize(outputname.length() - suffix.length());
+     167             :     if (verbosity)
+     168             :       std::cout << "Writing ABF(naive) estimator files..." << '\n';
+     169             :     abfgrid.writeAll(outputname);
+     170             :     if (verbosity)
+     171             :       std::cout << "Writing CZAR estimator files..." << '\n';
+     172             :     czarestimator.writeAll(outputname);
+     173             :     czarestimator.writeZCountZGrad(outputname);
+     174             :   }
+     175           2 : }
+     176             : 
+     177           2 : void drrtool::mergewindows(const vector<string> &filename, string outputname) {
+     178           2 :   if (filename.size() < 2) {
+     179           0 :     std::cerr << "ERROR! You need at least two .drrstate file to merge windows!" << std::endl;
+     180           0 :     std::abort();
+     181             :   }
+     182             :   // Read grid into abfs and czars;
+     183             :   vector<ABF> abfs;
+     184             :   vector<CZAR> czars;
+     185           6 :   for (auto it_fn = filename.begin(); it_fn != filename.end(); ++it_fn) {
+     186           4 :     std::ifstream in;
+     187           4 :     in.open((*it_fn));
+     188           4 :     boost::archive::binary_iarchive ia(in);
+     189             :     long long int step;
+     190             :     vector<double> fict;
+     191             :     vector<double> vfict;
+     192             :     vector<double> vfict_laststep;
+     193             :     vector<double> ffict;
+     194             :     ABF abfgrid;
+     195             :     CZAR czarestimator;
+     196             :     ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> abfgrid >>
+     197             :        czarestimator;
+     198           4 :     abfgrid.setOutputUnit(units.getEnergy());
+     199             :     czarestimator.setOutputUnit(units.getEnergy());
+     200           4 :     abfs.push_back(abfgrid);
+     201           4 :     czars.push_back(czarestimator);
+     202           4 :     in.close();
+     203           8 :   }
+     204           2 :   CZAR cmerged = CZAR::mergewindow(czars[0], czars[1]);
+     205           2 :   ABF amerged = ABF::mergewindow(abfs[0], abfs[1]);
+     206           2 :   for (size_t i = 2; i < czars.size(); ++i) {
+     207           0 :     cmerged = CZAR::mergewindow(cmerged, czars[i]);
+     208           0 :     amerged = ABF::mergewindow(amerged, abfs[i]);
+     209             :   }
+     210           2 :   if (outputname.empty()) {
+     211             :     // Generate new file name for merged grad and count
+     212           1 :     vector<string> tmp_name = filename;
+     213           1 :     std::transform(std::begin(tmp_name), std::end(tmp_name), std::begin(tmp_name),
+     214           2 :     [&](const string & s) {return s.substr(0, s.find(suffix));});
+     215           2 :     outputname = std::accumulate(std::begin(tmp_name), std::end(tmp_name), string(""),
+     216           5 :     [](const string & a, const string & b) {return a + b + "+";});
+     217           1 :     outputname.resize(outputname.size() - 1);
+     218             :     std::cerr << "You have not specified an output filename for the merged"
+     219           1 :               << " result, so the default name \"" + outputname
+     220           2 :               << "\" is used here, which may yield unexpected behavior.\n";
+     221           1 :   }
+     222           2 :   cmerged.writeAll(outputname);
+     223           2 :   cmerged.writeZCountZGrad(outputname);
+     224           2 :   amerged.writeAll(outputname);
+     225           4 : }
+     226             : 
+     227           1 : void drrtool::calcDivergence(const vector<string> &filename, const string &dumpFmt) {
+     228           1 :   #pragma omp parallel for
+     229             :   for (size_t j = 0; j < filename.size(); ++j) {
+     230             :     std::ifstream in;
+     231             :     in.open(filename[j]);
+     232             :     boost::archive::binary_iarchive ia(in);
+     233             :     long long int step;
+     234             :     vector<double> fict;
+     235             :     vector<double> vfict;
+     236             :     vector<double> vfict_laststep;
+     237             :     vector<double> ffict;
+     238             :     ABF abfgrid;
+     239             :     CZAR czarestimator;
+     240             :     ia >> step >> fict >> vfict >> vfict_laststep >> ffict >> abfgrid >>
+     241             :        czarestimator;
+     242             :     in.close();
+     243             :     abfgrid.setOutputUnit(units.getEnergy());
+     244             :     czarestimator.setOutputUnit(units.getEnergy());
+     245             :     if (verbosity) {
+     246             :       std::cout << "Output units factor: " << units.getEnergy() << '\n';
+     247             :       std::cout << "Dumping information of extended variables..." << '\n';
+     248             :       std::cout << "Step: " << step << '\n';
+     249             :       for (size_t i = 0; i < fict.size(); ++i) {
+     250             :         std::cout << "Dimension[" << i + 1 << "]:\n"
+     251             :                   << "  Coordinate: " << fict[i] << '\n'
+     252             :                   << "  Velocity: " << vfict[i] << '\n'
+     253             :                   << "  Velocity(laststep): " << vfict_laststep[i] << '\n'
+     254             :                   << "  Force: " << ffict[i] << '\n';
+     255             :       }
+     256             :       std::cout << "Dumping counts and gradients from grids..." << '\n';
+     257             :     }
+     258             :     string outputname(filename[j]);
+     259             :     outputname.resize(outputname.length() - suffix.length());
+     260             :     abfgrid.writeDivergence(outputname, dumpFmt);
+     261             :     czarestimator.writeDivergence(outputname, dumpFmt);
+     262             :   }
+     263           1 : }
+     264             : 
+     265             : } // End of namespace
+     266             : }
+     267             : 
+     268             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/index-sort-f.html b/coverage/drr/index-sort-f.html new file mode 100644 index 000000000000..dd4808542b42 --- /dev/null +++ b/coverage/drr/index-sort-f.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1201127194.5 %
Date:2024-02-22 21:58:45Functions:899494.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
DRR.h +
100.0%
+
100.0 %99 / 9978.6 %11 / 14
DynamicReferenceRestraining.cpp +
91.2%91.2%
+
91.2 %404 / 44388.9 %8 / 9
DRR.cpp +
93.2%93.2%
+
93.2 %331 / 35596.0 %24 / 25
drrtool.cpp +
94.4%94.4%
+
94.4 %68 / 72100.0 %12 / 12
colvar_UIestimator.h +
99.0%99.0%
+
99.0 %299 / 302100.0 %34 / 34
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/index-sort-l.html b/coverage/drr/index-sort-l.html new file mode 100644 index 000000000000..3de7beb2591c --- /dev/null +++ b/coverage/drr/index-sort-l.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1201127194.5 %
Date:2024-02-22 21:58:45Functions:899494.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
DynamicReferenceRestraining.cpp +
91.2%91.2%
+
91.2 %404 / 44388.9 %8 / 9
DRR.cpp +
93.2%93.2%
+
93.2 %331 / 35596.0 %24 / 25
drrtool.cpp +
94.4%94.4%
+
94.4 %68 / 72100.0 %12 / 12
colvar_UIestimator.h +
99.0%99.0%
+
99.0 %299 / 302100.0 %34 / 34
DRR.h +
100.0%
+
100.0 %99 / 9978.6 %11 / 14
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/drr/index.html b/coverage/drr/index.html new file mode 100644 index 000000000000..026971728c83 --- /dev/null +++ b/coverage/drr/index.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - drr + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - drrHitTotalCoverage
Test:plumed test coverageLines:1201127194.5 %
Date:2024-02-22 21:58:45Functions:899494.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
DRR.cpp +
93.2%93.2%
+
93.2 %331 / 35596.0 %24 / 25
DRR.h +
100.0%
+
100.0 %99 / 9978.6 %11 / 14
DynamicReferenceRestraining.cpp +
91.2%91.2%
+
91.2 %404 / 44388.9 %8 / 9
colvar_UIestimator.h +
99.0%99.0%
+
99.0 %299 / 302100.0 %34 / 34
drrtool.cpp +
94.4%94.4%
+
94.4 %68 / 72100.0 %12 / 12
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/EDS.cpp.func-sort-c.html b/coverage/eds/EDS.cpp.func-sort-c.html new file mode 100644 index 000000000000..21ff6eb29722 --- /dev/null +++ b/coverage/eds/EDS.cpp.func-sort-c.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - eds/EDS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - eds - EDS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-02-22 21:58:45Functions:172085.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3eds3EDS17turnOnDerivativesEv0
_ZN4PLMD3eds3EDSC2ERKNS_13ActionOptionsE0
_ZN4PLMD3eds3EDSD2Ev0
_ZN4PLMD3eds3EDS17calc_lm_step_sizeEv1
_ZN4PLMD3eds3EDS20calc_covar_step_sizeEv1
_ZN4PLMD3eds3EDS13readInRestartEb2
_ZN4PLMD3eds3EDS20update_pseudo_virialEv2
_ZN4PLMD3eds3EDS18calc_ssd_step_sizeEv6
_ZN4PLMD3eds3EDS11update_biasEv8
_ZN4PLMD3eds3EDS15setupOutRestartEv8
_ZN4PLMD3eds3EDS16reset_statisticsEv8
_ZN4PLMD3eds3EDSC1ERKNS_13ActionOptionsE8
_ZN4PLMD3eds3EDSD0Ev8
_ZN4PLMD3eds3EDSD1Ev8
_ZN4PLMD3eds3EDS16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3eds3EDS17update_statisticsEv12
_ZN4PLMD3eds3EDS15writeOutRestartEv27
_ZN4PLMD3eds3EDS10apply_biasEv40
_ZN4PLMD3eds3EDS6updateEv40
_ZN4PLMD3eds3EDS9calculateEv40
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/EDS.cpp.func.html b/coverage/eds/EDS.cpp.func.html new file mode 100644 index 000000000000..620ee4232aed --- /dev/null +++ b/coverage/eds/EDS.cpp.func.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - eds/EDS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - eds - EDS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-02-22 21:58:45Functions:172085.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3eds3EDS10apply_biasEv40
_ZN4PLMD3eds3EDS11update_biasEv8
_ZN4PLMD3eds3EDS13readInRestartEb2
_ZN4PLMD3eds3EDS15setupOutRestartEv8
_ZN4PLMD3eds3EDS15writeOutRestartEv27
_ZN4PLMD3eds3EDS16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3eds3EDS16reset_statisticsEv8
_ZN4PLMD3eds3EDS17calc_lm_step_sizeEv1
_ZN4PLMD3eds3EDS17turnOnDerivativesEv0
_ZN4PLMD3eds3EDS17update_statisticsEv12
_ZN4PLMD3eds3EDS18calc_ssd_step_sizeEv6
_ZN4PLMD3eds3EDS20calc_covar_step_sizeEv1
_ZN4PLMD3eds3EDS20update_pseudo_virialEv2
_ZN4PLMD3eds3EDS6updateEv40
_ZN4PLMD3eds3EDS9calculateEv40
_ZN4PLMD3eds3EDSC1ERKNS_13ActionOptionsE8
_ZN4PLMD3eds3EDSC2ERKNS_13ActionOptionsE0
_ZN4PLMD3eds3EDSD0Ev8
_ZN4PLMD3eds3EDSD1Ev8
_ZN4PLMD3eds3EDSD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/EDS.cpp.gcov.html b/coverage/eds/EDS.cpp.gcov.html new file mode 100644 index 000000000000..d3361017137e --- /dev/null +++ b/coverage/eds/EDS.cpp.gcov.html @@ -0,0 +1,1251 @@ + + + + + + + + LCOV - plumed test coverage - eds/EDS.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - eds - EDS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-02-22 21:58:45Functions:172085.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2017 of Glen Hocky and Andrew White
+       3             : 
+       4             : The eds module is free software: you can redistribute it and/or modify
+       5             : it under the terms of the GNU Lesser General Public License as published by
+       6             : the Free Software Foundation, either version 3 of the License, or
+       7             : (at your option) any later version.
+       8             : 
+       9             : The eds module is distributed in the hope that it will be useful,
+      10             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      11             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      12             : GNU Lesser General Public License for more details.
+      13             : 
+      14             : You should have received a copy of the GNU Lesser General Public License
+      15             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      16             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      17             : #include "bias/Bias.h"
+      18             : #include "bias/ReweightBase.h"
+      19             : #include "core/ActionAtomistic.h"
+      20             : #include "core/ActionRegister.h"
+      21             : #include "core/PlumedMain.h"
+      22             : #include "tools/File.h"
+      23             : #include "tools/Matrix.h"
+      24             : #include "tools/Random.h"
+      25             : 
+      26             : #include <iostream>
+      27             : 
+      28             : using namespace PLMD;
+      29             : using namespace bias;
+      30             : 
+      31             : // namespace is lowercase to match
+      32             : // module names being all lowercase
+      33             : 
+      34             : namespace PLMD
+      35             : {
+      36             : namespace eds
+      37             : {
+      38             : 
+      39             : //+PLUMEDOC EDSMOD_BIAS EDS
+      40             : /*
+      41             : Add a linear bias on a set of observables.
+      42             : 
+      43             : This force is the same as the linear part of the bias in \ref
+      44             : RESTRAINT, but this bias has the ability to compute the prefactors
+      45             : adaptively using the scheme of White and Voth \cite white2014efficient
+      46             : in order to match target observable values for a set of CVs.
+      47             : Further updates to the algorithm are described in \cite hocky2017cgds
+      48             : and you can read a review on the method and its applications here: \cite Amirkulova2019Recent.
+      49             : 
+      50             : You can
+      51             : see a tutorial on EDS specifically for biasing coordination number at
+      52             : <a
+      53             : href="http://thewhitelab.org/blog/tutorial/2017/05/10/lammps-coordination-number-tutorial/">
+      54             : Andrew White's webpage</a>.
+      55             : 
+      56             : The addition to the potential is of the form
+      57             : \f[
+      58             :   \sum_i \frac{\alpha_i}{s_i} x_i
+      59             : \f]
+      60             : 
+      61             : where for CV \f$x_i\f$, a coupling constant \f${\alpha}_i\f$ is determined
+      62             : adaptively or set by the user to match a target value for
+      63             : \f$x_i\f$. \f$s_i\f$ is a scale parameter, which by default is set to
+      64             : the target value. It may also be set separately.
+      65             : 
+      66             : \warning
+      67             : It is not possible to set the target value of the observable
+      68             : to zero with the default value of \f$s_i\f$ as this will cause a
+      69             : divide-by-zero error. Instead, set \f$s_i=1\f$ or modify the CV so the
+      70             : desired target value is no longer zero.
+      71             : 
+      72             : Notice that a similar method is available as \ref MAXENT, although with different features and using a different optimization algorithm.
+      73             : 
+      74             : \par Virial
+      75             : 
+      76             : The bias forces modify the virial and this can change your simulation density if the bias is used in an NPT simulation.
+      77             : One way to avoid changing the virial contribution from the bias is to add the keyword VIRIAL=1.0, which changes how the bias
+      78             : is computed to minimize its contribution to the virial. This can also lead to smaller magnitude biases that are more robust if
+      79             : transferred to other systems.  VIRIAL=1.0 can be a reasonable starting point and increasing the value changes the balance between matching
+      80             : the set-points and minimizing the virial. See \cite Amirkulova2019Recent for details on the equations. Since the coupling constants
+      81             : are unique with a single CV, VIRIAL is not applicable with a single CV. When used with multiple CVs, the CVs should be correlated
+      82             : which is almost always the case.
+      83             : 
+      84             : \par Weighting
+      85             : 
+      86             : EDS computes means and variances as part of its algorithm. If you are
+      87             : also using a biasing method like metadynamics, you may wish to remove
+      88             : the effect of this bias in your EDS computations so that EDS works on
+      89             : the canonical values (reweighted to be unbiased).  For example, you may be using
+      90             : metadynamics to bias a dihedral angle to enhance sampling and be using
+      91             : EDS to set the average distance between two particular atoms. Specifically:
+      92             : 
+      93             : \plumedfile
+      94             : # set-up metadynamics
+      95             : t: TORSION ATOMS=1,2,3,4
+      96             : md: METAD ARG=d SIGMA=0.2 HEIGHT=0.3 PACE=500 TEMP=300
+      97             : # compute bias weights
+      98             : bias: REWEIGHT_METAD TEMP=300
+      99             : # now do EDS on distance while removing effect of metadynamics
+     100             : d: DISTANCE ATOMS=4,7
+     101             : eds: EDS ARG=d CENTER=3.0 PERIOD=100 TEMP=300 LOGWEIGHTS=bias
+     102             : \endplumedfile
+     103             : 
+     104             : This is an approximation though because EDS uses a finite samples while running to get means/variances.
+     105             : At the end of a run,
+     106             : you should ensure this approach worked and indeed your reweighted CV matches the target value.
+     107             : 
+     108             : \par Examples
+     109             : 
+     110             : The following input for a harmonic oscillator of two beads will
+     111             : adaptively find a linear bias to change the mean and variance to the
+     112             : target values. The PRINT line shows how to access the value of the
+     113             : coupling constants.
+     114             : 
+     115             : \plumedfile
+     116             : dist: DISTANCE ATOMS=1,2
+     117             : # this is the squared of the distance
+     118             : dist2: COMBINE ARG=dist POWERS=2 PERIODIC=NO
+     119             : 
+     120             : # bias mean and variance
+     121             : eds: EDS ARG=dist,dist2 CENTER=2.0,1.0 PERIOD=100 TEMP=1.0
+     122             : PRINT ARG=dist,dist2,eds.dist_coupling,eds.dist2_coupling,eds.bias,eds.force2 FILE=colvars.dat STRIDE=100
+     123             : \endplumedfile
+     124             : 
+     125             : <hr>
+     126             : 
+     127             : Rather than trying to find the coupling constants adaptively, one can ramp up to a constant value.
+     128             : \plumedfile
+     129             : dist: DISTANCE ATOMS=1,2
+     130             : dist2: COMBINE ARG=dist POWERS=2 PERIODIC=NO
+     131             : 
+     132             : # ramp couplings from 0,0 to -1,1 over 50000 steps
+     133             : eds: EDS ARG=dist,dist2 CENTER=2.0,1.0 FIXED=-1,1 RAMP PERIOD=50000 TEMP=1.0
+     134             : 
+     135             : # same as above, except starting at -0.5,0.5 rather than default of 0,0
+     136             : eds2: EDS ARG=dist,dist2 CENTER=2.0,1.0 FIXED=-1,1 INIT=-0.5,0.5 RAMP PERIOD=50000 TEMP=1.0
+     137             : \endplumedfile
+     138             : 
+     139             : <hr>
+     140             : A restart file can be added to dump information needed to restart/continue simulation using these parameters every PERIOD.
+     141             : \plumedfile
+     142             : dist: DISTANCE ATOMS=1,2
+     143             : dist2: COMBINE ARG=dist POWERS=2 PERIODIC=NO
+     144             : 
+     145             : # add the option to write to a restart file
+     146             : eds: EDS ARG=dist,dist2 CENTER=2.0,1.0 PERIOD=100 TEMP=1.0 OUT_RESTART=checkpoint.eds
+     147             : \endplumedfile
+     148             : 
+     149             : The first few lines of the restart file that is output if we run a calculation with one CV will look something like this:
+     150             : 
+     151             : \auxfile{restart.eds}
+     152             : #! FIELDS time d1_center d1_set d1_target d1_coupling d1_maxrange d1_maxgrad d1_accum d1_mean d1_std
+     153             : #! SET adaptive  1
+     154             : #! SET update_period  1
+     155             : #! SET seed  0
+     156             : #! SET kbt    2.4943
+     157             :    0.0000   1.0000   0.0000   0.0000   0.0000   7.4830   0.1497   0.0000   0.0000   0.0000
+     158             :    1.0000   1.0000   0.0000   0.0000   0.0000   7.4830   0.1497   0.0000   0.0000   0.0000
+     159             :    2.0000   1.0000  -7.4830   0.0000   0.0000   7.4830   0.1497   0.0224   0.0000   0.0000
+     160             :    3.0000   1.0000  -7.4830   0.0000  -7.4830   7.4830   0.1497   0.0224   0.0000   0.0000
+     161             :    4.0000   1.0000  -7.4830   0.0000  -7.4830   7.4830   0.1497   0.0224   0.0000   0.0000
+     162             : \endauxfile
+     163             : 
+     164             : <hr>
+     165             : 
+     166             : Read in a previous restart file. Adding RESTART flag makes output append
+     167             : \plumedfile
+     168             : d1: DISTANCE ATOMS=1,2
+     169             : 
+     170             : eds: EDS ARG=d1 CENTER=2.0 PERIOD=100 TEMP=1.0 IN_RESTART=restart.eds RESTART=YES
+     171             : \endplumedfile
+     172             : 
+     173             : <hr>
+     174             : 
+     175             : Read in a previous restart file and freeze the bias at the final level from the previous simulation
+     176             : \plumedfile
+     177             : d1: DISTANCE ATOMS=1,2
+     178             : 
+     179             : eds: EDS ARG=d1 CENTER=2.0 TEMP=1.0 IN_RESTART=restart.eds FREEZE
+     180             : \endplumedfile
+     181             : 
+     182             : <hr>
+     183             : 
+     184             : Read in a previous restart file and freeze the bias at the mean from the previous simulation
+     185             : \plumedfile
+     186             : d1: DISTANCE ATOMS=1,2
+     187             : 
+     188             : eds: EDS ARG=d1 CENTER=2.0 TEMP=1.0 IN_RESTART=restart.eds FREEZE MEAN
+     189             : \endplumedfile
+     190             : 
+     191             : 
+     192             : */
+     193             : //+ENDPLUMEDOC
+     194             : 
+     195             : class EDS : public Bias
+     196             : {
+     197             : 
+     198             : private:
+     199             :   /*We will get this and store it once, since on-the-fly changing number of CVs will be fatal*/
+     200             :   const unsigned int ncvs_;
+     201             :   std::vector<double> center_;
+     202             :   std::vector<Value *> center_values_;
+     203             :   ReweightBase *logweights_; // weights to use if reweighting averages
+     204             :   std::vector<double> scale_;
+     205             :   std::vector<double> current_coupling_;   // actually current coupling
+     206             :   std::vector<double> set_coupling_;       // what our coupling is ramping up to. Equal to current_coupling when gathering stats
+     207             :   std::vector<double> target_coupling_;    // used when loaded to reach a value
+     208             :   std::vector<double> max_coupling_range_; // used for adaptive range
+     209             :   std::vector<double> max_coupling_grad_;  // maximum allowed gradient
+     210             :   std::vector<double> coupling_rate_;
+     211             :   std::vector<double> coupling_accum_;
+     212             :   std::vector<double> means_;
+     213             :   std::vector<double> differences_;
+     214             :   std::vector<double> alpha_vector_;
+     215             :   std::vector<double> alpha_vector_2_;
+     216             :   std::vector<double> ssds_;
+     217             :   std::vector<double> step_size_;
+     218             :   std::vector<double> pseudo_virial_;
+     219             :   std::vector<Value *> out_coupling_;
+     220             :   Matrix<double> covar_;
+     221             :   Matrix<double> covar2_;
+     222             :   Matrix<double> lm_inv_;
+     223             :   std::string in_restart_name_;
+     224             :   std::string out_restart_name_;
+     225             :   std::string fmt_;
+     226             :   OFile out_restart_;
+     227             :   IFile in_restart_;
+     228             :   bool b_c_values_;
+     229             :   bool b_adaptive_;
+     230             :   bool b_freeze_;
+     231             :   bool b_equil_;
+     232             :   bool b_ramp_;
+     233             :   bool b_covar_;
+     234             :   bool b_restart_;
+     235             :   bool b_write_restart_;
+     236             :   bool b_lm_;
+     237             :   bool b_virial_;
+     238             :   bool b_update_virial_;
+     239             :   bool b_weights_;
+     240             :   int seed_;
+     241             :   int update_period_;
+     242             :   int avg_coupling_count_;
+     243             :   int update_calls_;
+     244             :   double kbt_;
+     245             :   double multi_prop_;
+     246             :   double lm_mixing_par_;
+     247             :   double virial_scaling_;
+     248             :   double pseudo_virial_sum_; // net virial for all cvs in current period
+     249             :   double max_logweight_;     // maximum observed max logweight for period
+     250             :   double wsum_;              // sum of weights thus far
+     251             :   Random rand_;
+     252             :   Value *value_force2_;
+     253             :   Value *value_pressure_;
+     254             : 
+     255             :   /*read input restart. b_mean sets if we use mean or final value for freeze*/
+     256             :   void readInRestart(const bool b_mean);
+     257             :   /*setup output restart*/
+     258             :   void setupOutRestart();
+     259             :   /*write output restart*/
+     260             :   void writeOutRestart();
+     261             :   void update_statistics();
+     262             :   void update_pseudo_virial();
+     263             :   void calc_lm_step_size();
+     264             :   void calc_covar_step_size();
+     265             :   void calc_ssd_step_size();
+     266             :   void reset_statistics();
+     267             :   void update_bias();
+     268             :   void apply_bias();
+     269             : 
+     270             : public:
+     271             :   explicit EDS(const ActionOptions &);
+     272             :   void calculate();
+     273             :   void update();
+     274             :   void turnOnDerivatives();
+     275             :   static void registerKeywords(Keywords &keys);
+     276             :   ~EDS();
+     277             : };
+     278             : 
+     279             : PLUMED_REGISTER_ACTION(EDS, "EDS")
+     280             : 
+     281          10 : void EDS::registerKeywords(Keywords &keys)
+     282             : {
+     283          10 :   Bias::registerKeywords(keys);
+     284          10 :   keys.use("ARG");
+     285          20 :   keys.add("optional", "CENTER", "The desired centers (equilibrium values) which will be sought during the adaptive linear biasing. This is for fixed centers");
+     286          20 :   keys.add("optional", "CENTER_ARG", "The desired centers (equilibrium values) which will be sought during the adaptive linear biasing. "
+     287             :            "CENTER_ARG is for calculated centers, e.g. from a CV or analysis. ");
+     288             : 
+     289          20 :   keys.add("optional", "PERIOD", "Steps over which to adjust bias for adaptive or ramping");
+     290          20 :   keys.add("compulsory", "RANGE", "25.0", "The (starting) maximum increase in coupling constant per PERIOD (in \\f$k_B T\\f$/[BIAS_SCALE unit]) for each CV biased");
+     291          20 :   keys.add("compulsory", "SEED", "0", "Seed for random order of changing bias");
+     292          20 :   keys.add("compulsory", "INIT", "0", "Starting value for coupling constant");
+     293          20 :   keys.add("compulsory", "FIXED", "0", "Fixed target values for coupling constant. Non-adaptive.");
+     294          20 :   keys.add("optional", "BIAS_SCALE", "A divisor to set the units of the bias. "
+     295             :            "If not set, this will be the CENTER value by default (as is done in White and Voth 2014).");
+     296          20 :   keys.add("optional", "TEMP", "The system temperature. If not provided will be taken from MD code (if available)");
+     297          20 :   keys.add("optional", "MULTI_PROP", "What proportion of dimensions to update at each step. "
+     298             :            "Must be in interval [1,0), where 1 indicates all and any other indicates a stochastic update. "
+     299             :            "If not set, default is 1 / N, where N is the number of CVs. ");
+     300          20 :   keys.add("optional", "VIRIAL", "Add an update penalty for having non-zero virial contributions. Only makes sense with multiple correlated CVs.");
+     301          20 :   keys.add("optional", "LOGWEIGHTS", "Add weights to use for computing statistics. For example, if biasing with metadynamics.");
+     302          20 :   keys.addFlag("LM", false, "Use Levenberg-Marquadt algorithm along with simultaneous keyword. Otherwise use gradient descent.");
+     303          20 :   keys.add("compulsory", "LM_MIXING", "1", "Initial mixing parameter when using Levenberg-Marquadt minimization.");
+     304          20 :   keys.add("optional", "RESTART_FMT", "the format that should be used to output real numbers in EDS restarts");
+     305          20 :   keys.add("optional", "OUT_RESTART", "Output file for all information needed to continue EDS simulation. "
+     306             :            "If you have the RESTART directive set (global or for EDS), this file will be appended to. "
+     307             :            "Note that the header will be printed again if appending.");
+     308          20 :   keys.add("optional", "IN_RESTART", "Read this file to continue an EDS simulation. "
+     309             :            "If same as OUT_RESTART and you have not set the RESTART directive, the file will be backed-up and overwritten with new output. "
+     310             :            "If you do have the RESTART flag set and it is the same name as OUT_RESTART, this file will be appended.");
+     311             : 
+     312          20 :   keys.addFlag("RAMP", false, "Slowly increase bias constant to a fixed value");
+     313          20 :   keys.addFlag("COVAR", false, "Utilize the covariance matrix when updating the bias. Default Off, but may be enabled due to other options");
+     314          20 :   keys.addFlag("FREEZE", false, "Fix bias at current level (only used for restarting).");
+     315          20 :   keys.addFlag("MEAN", false, "Instead of using final bias level from restart, use average. Can only be used in conjunction with FREEZE");
+     316             : 
+     317          10 :   keys.use("RESTART");
+     318             : 
+     319          20 :   keys.addOutputComponent("force2", "default", "squared value of force from the bias");
+     320          20 :   keys.addOutputComponent("pressure", "default", "If using virial keyword, this is the current sum of virial terms. It is in units of pressure (energy / vol^3)");
+     321          20 :   keys.addOutputComponent("_coupling", "default", "For each named CV biased, there will be a corresponding output CV_coupling storing the current linear bias prefactor.");
+     322          10 : }
+     323             : 
+     324           8 : EDS::EDS(const ActionOptions &ao) : PLUMED_BIAS_INIT(ao),
+     325           8 :   ncvs_(getNumberOfArguments()),
+     326           8 :   scale_(ncvs_, 0.0),
+     327           8 :   current_coupling_(ncvs_, 0.0),
+     328           8 :   set_coupling_(ncvs_, 0.0),
+     329           8 :   target_coupling_(ncvs_, 0.0),
+     330           8 :   max_coupling_range_(ncvs_, 25.0),
+     331           8 :   max_coupling_grad_(ncvs_, 0.0),
+     332           8 :   coupling_rate_(ncvs_, 1.0),
+     333           8 :   coupling_accum_(ncvs_, 0.0),
+     334           8 :   means_(ncvs_, 0.0),
+     335           8 :   step_size_(ncvs_, 0.0),
+     336           8 :   pseudo_virial_(ncvs_),
+     337           8 :   out_coupling_(ncvs_, NULL),
+     338           8 :   in_restart_name_(""),
+     339           8 :   out_restart_name_(""),
+     340           8 :   fmt_("%f"),
+     341           8 :   b_adaptive_(true),
+     342           8 :   b_freeze_(false),
+     343           8 :   b_equil_(true),
+     344           8 :   b_ramp_(false),
+     345           8 :   b_covar_(false),
+     346           8 :   b_restart_(false),
+     347           8 :   b_write_restart_(false),
+     348           8 :   b_lm_(false),
+     349           8 :   b_virial_(false),
+     350           8 :   b_weights_(false),
+     351           8 :   seed_(0),
+     352           8 :   update_period_(0),
+     353           8 :   avg_coupling_count_(1),
+     354           8 :   update_calls_(0),
+     355           8 :   kbt_(0.0),
+     356           8 :   multi_prop_(-1.0),
+     357           8 :   lm_mixing_par_(0.1),
+     358           8 :   virial_scaling_(0.),
+     359           8 :   pseudo_virial_sum_(0.0),
+     360           8 :   max_logweight_(0.0),
+     361           8 :   wsum_(0.0),
+     362          32 :   value_force2_(NULL)
+     363             : {
+     364             :   double temp = -1.0;
+     365           8 :   bool b_mean = false;
+     366             :   std::vector<Value *> wvalues;
+     367             : 
+     368          16 :   addComponent("force2");
+     369           8 :   componentIsNotPeriodic("force2");
+     370           8 :   value_force2_ = getPntrToComponent("force2");
+     371             : 
+     372          20 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     373             :   {
+     374          12 :     std::string comp = getPntrToArgument(i)->getName() + "_coupling";
+     375          12 :     addComponent(comp);
+     376          12 :     componentIsNotPeriodic(comp);
+     377          12 :     out_coupling_[i] = getPntrToComponent(comp);
+     378             :   }
+     379             : 
+     380           8 :   parseVector("CENTER", center_);
+     381           8 :   parseArgumentList("CENTER_ARG", center_values_);
+     382           8 :   parseArgumentList("LOGWEIGHTS", wvalues);
+     383           8 :   parseVector("BIAS_SCALE", scale_);
+     384           8 :   parseVector("RANGE", max_coupling_range_);
+     385           8 :   parseVector("FIXED", target_coupling_);
+     386           8 :   parseVector("INIT", set_coupling_);
+     387           8 :   parse("PERIOD", update_period_);
+     388           8 :   kbt_ = getkBT();
+     389           8 :   parse("SEED", seed_);
+     390           8 :   parse("MULTI_PROP", multi_prop_);
+     391           8 :   parse("LM_MIXING", lm_mixing_par_);
+     392           8 :   parse("RESTART_FMT", fmt_);
+     393           8 :   parse("VIRIAL", virial_scaling_);
+     394           8 :   fmt_ = " " + fmt_; // add space since parse strips them
+     395           8 :   parse("OUT_RESTART", out_restart_name_);
+     396           8 :   parseFlag("LM", b_lm_);
+     397           8 :   parseFlag("RAMP", b_ramp_);
+     398           8 :   parseFlag("FREEZE", b_freeze_);
+     399           8 :   parseFlag("MEAN", b_mean);
+     400           8 :   parseFlag("COVAR", b_covar_);
+     401           8 :   parse("IN_RESTART", in_restart_name_);
+     402           8 :   checkRead();
+     403             : 
+     404             :   /*
+     405             :    * Things that are different when using changing centers:
+     406             :    * 1. Scale
+     407             :    * 2. The log file
+     408             :    * 3. Reading Restarts
+     409             :    */
+     410             : 
+     411           8 :   if (center_.size() == 0)
+     412             :   {
+     413           1 :     if (center_values_.size() == 0)
+     414           0 :       error("Must set either CENTER or CENTER_ARG");
+     415           1 :     else if (center_values_.size() != ncvs_)
+     416           0 :       error("CENTER_ARG must contain the same number of variables as ARG");
+     417           1 :     b_c_values_ = true;
+     418           1 :     center_.resize(ncvs_);
+     419           1 :     log.printf("  EDS will use possibly varying centers\n");
+     420             :   }
+     421             :   else
+     422             :   {
+     423           7 :     if (center_.size() != ncvs_)
+     424           0 :       error("Must have same number of CENTER arguments as ARG arguments");
+     425           7 :     else if (center_values_.size() != 0)
+     426           0 :       error("You can only set CENTER or CENTER_ARG. Not both");
+     427           7 :     b_c_values_ = false;
+     428           7 :     log.printf("  EDS will use fixed centers\n");
+     429             :   }
+     430             : 
+     431             :   // check for weights
+     432           8 :   if (wvalues.size() > 1)
+     433             :   {
+     434           0 :     error("LOGWEIGHTS can only support one weight set. Please only pass one action");
+     435             :   }
+     436           8 :   else if (wvalues.size() == 1)
+     437             :   {
+     438           1 :     logweights_ = dynamic_cast<ReweightBase *>(wvalues[0]->getPntrToAction());
+     439           1 :     b_weights_ = true;
+     440             :   }
+     441             : 
+     442           8 :   log.printf("  setting scaling:");
+     443           8 :   if (scale_.size() > 0 && scale_.size() < ncvs_)
+     444             :   {
+     445           0 :     error("the number of BIAS_SCALE values be the same as number of CVs");
+     446             :   }
+     447           8 :   else if (scale_.size() == 0 && b_c_values_)
+     448             :   {
+     449           0 :     log.printf(" Setting SCALE to be 1 for all CVs\n");
+     450           0 :     scale_.resize(ncvs_);
+     451           0 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     452           0 :       scale_[i] = 1;
+     453             :   }
+     454           8 :   else if (scale_.size() == 0 && !b_c_values_)
+     455             :   {
+     456           2 :     log.printf(" (default) ");
+     457             : 
+     458           2 :     scale_.resize(ncvs_);
+     459           6 :     for (unsigned int i = 0; i < scale_.size(); ++i)
+     460             :     {
+     461           4 :       if (center_[i] == 0)
+     462           0 :         error("BIAS_SCALE parameter has been set to CENTER value of 0 (as is default). This will divide by 0, so giving up. See doc for EDS bias");
+     463           4 :       scale_[i] = center_[i];
+     464             :     }
+     465             :   }
+     466             :   else
+     467             :   {
+     468          14 :     for (unsigned int i = 0; i < scale_.size(); ++i)
+     469           8 :       log.printf(" %f", scale_[i]);
+     470             :   }
+     471           8 :   log.printf("\n");
+     472             : 
+     473           8 :   if (b_lm_)
+     474             :   {
+     475           1 :     log.printf("  EDS will perform Levenberg-Marquardt minimization with mixing parameter = %f\n", lm_mixing_par_);
+     476           1 :     differences_.resize(ncvs_);
+     477           1 :     alpha_vector_.resize(ncvs_);
+     478           1 :     alpha_vector_2_.resize(ncvs_);
+     479           1 :     covar_.resize(ncvs_, ncvs_);
+     480           1 :     covar2_.resize(ncvs_, ncvs_);
+     481           1 :     lm_inv_.resize(ncvs_, ncvs_);
+     482           1 :     covar2_ *= 0;
+     483           1 :     lm_inv_ *= 0;
+     484           1 :     if (multi_prop_ != 1)
+     485           0 :       log.printf("     WARNING - doing LM minimization but MULTI_PROP!=1\n");
+     486             :   }
+     487           7 :   else if (b_covar_)
+     488             :   {
+     489           1 :     log.printf("  EDS will utilize covariance matrix for update steps\n");
+     490           1 :     covar_.resize(ncvs_, ncvs_);
+     491             :   }
+     492             :   else
+     493             :   {
+     494           6 :     log.printf("  EDS will utilize variance for update steps\n");
+     495           6 :     ssds_.resize(ncvs_);
+     496             :   }
+     497             : 
+     498           8 :   b_virial_ = virial_scaling_;
+     499             : 
+     500           8 :   if (b_virial_)
+     501             :   {
+     502           1 :     if (ncvs_ == 1)
+     503           0 :       error("Minimizing the virial is only valid with multiply correlated collective variables.");
+     504             :     // check that the CVs can be used to compute pseudo-virial
+     505           1 :     log.printf("  EDS will compute virials of CVs and penalize with scale of %f. Checking CVs are valid...", virial_scaling_);
+     506           4 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     507             :     {
+     508           3 :       auto a = dynamic_cast<ActionAtomistic *>(getPntrToArgument(i)->getPntrToAction());
+     509           3 :       if (!a)
+     510           0 :         error("If using VIRIAL keyword, you must have normal CVs as arguments to EDS. Offending action: " + getPntrToArgument(i)->getPntrToAction()->getName());
+     511             :       // cppcheck-suppress nullPointerRedundantCheck
+     512           3 :       if (!(a->getPbc().isOrthorombic()))
+     513           3 :         log.printf("  WARNING: EDS Virial should have a orthorombic cell\n");
+     514             :     }
+     515           1 :     log.printf("done.\n");
+     516           2 :     addComponent("pressure");
+     517           1 :     componentIsNotPeriodic("pressure");
+     518           1 :     value_pressure_ = getPntrToComponent("pressure");
+     519             :   }
+     520             : 
+     521           8 :   if (b_mean && !b_freeze_)
+     522             :   {
+     523           0 :     error("EDS keyword MEAN can only be used along with keyword FREEZE");
+     524             :   }
+     525             : 
+     526           8 :   if (in_restart_name_ != "")
+     527             :   {
+     528           2 :     b_restart_ = true;
+     529           2 :     log.printf("  reading simulation information from file: %s\n", in_restart_name_.c_str());
+     530           2 :     readInRestart(b_mean);
+     531             :   }
+     532             :   else
+     533             :   {
+     534             : 
+     535             :     // in driver, this results in kbt of 0
+     536           6 :     if (kbt_ == 0)
+     537             :     {
+     538           0 :       error("  Unable to determine valid kBT. "
+     539             :             "Could be because you are runnning from driver or MD didn't give temperature.\n"
+     540             :             "Consider setting temperature manually with the TEMP keyword.");
+     541             :       kbt_ = 1;
+     542             :     }
+     543             : 
+     544           6 :     log.printf("  kBT = %f\n", kbt_);
+     545           6 :     log.printf("  Updating every %i steps\n", update_period_);
+     546             : 
+     547           6 :     if (!b_c_values_)
+     548             :     {
+     549           5 :       log.printf("  with centers:");
+     550          14 :       for (unsigned int i = 0; i < ncvs_; ++i)
+     551             :       {
+     552           9 :         log.printf(" %f ", center_[i]);
+     553             :       }
+     554             :     }
+     555             :     else
+     556             :     {
+     557           1 :       log.printf("  with actions centers:");
+     558           2 :       for (unsigned int i = 0; i < ncvs_; ++i)
+     559             :       {
+     560           1 :         log.printf(" %s ", center_values_[i]->getName().c_str());
+     561             :         // add dependency on these actions
+     562           1 :         addDependency(center_values_[i]->getPntrToAction());
+     563             :       }
+     564             :     }
+     565             : 
+     566           6 :     log.printf("\n  with initial ranges / rates:\n");
+     567          16 :     for (unsigned int i = 0; i < max_coupling_range_.size(); ++i)
+     568             :     {
+     569             :       // this is just an empirical guess. Bigger range, bigger grads. Less frequent updates, bigger changes
+     570             :       //
+     571             :       // using the current maxing out scheme, max_coupling_range is the biggest step that can be taken in any given interval
+     572          10 :       max_coupling_range_[i] *= kbt_;
+     573          10 :       max_coupling_grad_[i] = max_coupling_range_[i];
+     574          10 :       log.printf("    %f / %f\n", max_coupling_range_[i], max_coupling_grad_[i]);
+     575             :     }
+     576             : 
+     577           6 :     if (seed_ > 0)
+     578             :     {
+     579           2 :       log.printf("  setting random seed = %i", seed_);
+     580           2 :       rand_.setSeed(seed_);
+     581             :     }
+     582             : 
+     583          16 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     584          10 :       if (target_coupling_[i] != 0.0)
+     585           1 :         b_adaptive_ = false;
+     586             : 
+     587           6 :     if (!b_adaptive_)
+     588             :     {
+     589           1 :       if (b_ramp_)
+     590             :       {
+     591           1 :         log.printf("  ramping up coupling constants over %i steps\n", update_period_);
+     592             :       }
+     593             : 
+     594           1 :       log.printf("  with starting coupling constants");
+     595           2 :       for (unsigned int i = 0; i < set_coupling_.size(); ++i)
+     596           1 :         log.printf(" %f", set_coupling_[i]);
+     597           1 :       log.printf("\n");
+     598           1 :       log.printf("  and final coupling constants");
+     599           2 :       for (unsigned int i = 0; i < target_coupling_.size(); ++i)
+     600           1 :         log.printf(" %f", target_coupling_[i]);
+     601           1 :       log.printf("\n");
+     602             :     }
+     603             : 
+     604             :     // now do setup
+     605           6 :     if (b_ramp_)
+     606             :     {
+     607           1 :       update_period_ *= -1;
+     608             :     }
+     609             : 
+     610          16 :     for (unsigned int i = 0; i < set_coupling_.size(); ++i)
+     611          10 :       current_coupling_[i] = set_coupling_[i];
+     612             : 
+     613             :     // if b_adaptive_, then first half will be used for equilibrating and second half for statistics
+     614           6 :     if (update_period_ > 0)
+     615             :     {
+     616           5 :       update_period_ /= 2;
+     617             :     }
+     618             :   }
+     619             : 
+     620           8 :   if (b_freeze_)
+     621             :   {
+     622           1 :     b_adaptive_ = false;
+     623           1 :     update_period_ = 0;
+     624           1 :     if (b_mean)
+     625             :     {
+     626           1 :       log.printf("  freezing bias at the average level from the restart file\n");
+     627             :     }
+     628             :     else
+     629             :     {
+     630           0 :       log.printf("  freezing bias at current level\n");
+     631             :     }
+     632             :   }
+     633             : 
+     634           8 :   if (multi_prop_ == -1.0)
+     635             :   {
+     636           5 :     log.printf("  Will update each dimension stochastically with probability 1 / number of CVs\n");
+     637           5 :     multi_prop_ = 1.0 / ncvs_;
+     638             :   }
+     639           3 :   else if (multi_prop_ > 0 && multi_prop_ <= 1.0)
+     640             :   {
+     641           3 :     log.printf("  Will update each dimension stochastically with probability %f\n", multi_prop_);
+     642             :   }
+     643             :   else
+     644             :   {
+     645           0 :     error("  MULTI_PROP must be between 0 and 1\n");
+     646             :   }
+     647             : 
+     648           8 :   if (out_restart_name_.length() > 0)
+     649             :   {
+     650           8 :     log.printf("  writing restart information every %i steps to file %s with format %s\n", abs(update_period_), out_restart_name_.c_str(), fmt_.c_str());
+     651           8 :     b_write_restart_ = true;
+     652           8 :     setupOutRestart();
+     653             :   }
+     654             : 
+     655          16 :   log << "  Bibliography " << plumed.cite("White and Voth, J. Chem. Theory Comput. 10 (8), 3023-3030 (2014)") << "\n";
+     656          16 :   log << "  Bibliography " << plumed.cite("G. M. Hocky, T. Dannenhoffer-Lafage, G. A. Voth, J. Chem. Theory Comput. 13 (9), 4593-4603 (2017)") << "\n";
+     657           8 : }
+     658             : 
+     659           2 : void EDS::readInRestart(const bool b_mean)
+     660             : {
+     661           2 :   int adaptive_i = 0;
+     662             : 
+     663           2 :   in_restart_.open(in_restart_name_);
+     664             : 
+     665           4 :   if (in_restart_.FieldExist("kbt"))
+     666             :   {
+     667           2 :     in_restart_.scanField("kbt", kbt_);
+     668             :   }
+     669             :   else
+     670             :   {
+     671           0 :     error("No field 'kbt' in restart file");
+     672             :   }
+     673           2 :   log.printf("  with kBT = %f\n", kbt_);
+     674             : 
+     675           4 :   if (in_restart_.FieldExist("update_period"))
+     676             :   {
+     677           2 :     in_restart_.scanField("update_period", update_period_);
+     678             :   }
+     679             :   else
+     680             :   {
+     681           0 :     error("No field 'update_period' in restart file");
+     682             :   }
+     683           2 :   log.printf("  Updating every %i steps\n", update_period_);
+     684             : 
+     685           4 :   if (in_restart_.FieldExist("adaptive"))
+     686             :   {
+     687             :     // note, no version of scanField for boolean
+     688           2 :     in_restart_.scanField("adaptive", adaptive_i);
+     689             :   }
+     690             :   else
+     691             :   {
+     692           0 :     error("No field 'adaptive' in restart file");
+     693             :   }
+     694           2 :   b_adaptive_ = bool(adaptive_i);
+     695             : 
+     696           4 :   if (in_restart_.FieldExist("seed"))
+     697             :   {
+     698           2 :     in_restart_.scanField("seed", seed_);
+     699             :   }
+     700             :   else
+     701             :   {
+     702           0 :     error("No field 'seed' in restart file");
+     703             :   }
+     704           2 :   if (seed_ > 0)
+     705             :   {
+     706           0 :     log.printf("  setting random seed = %i", seed_);
+     707           0 :     rand_.setSeed(seed_);
+     708             :   }
+     709             : 
+     710             :   double time, tmp;
+     711           2 :   std::vector<double> avg_bias = std::vector<double>(center_.size());
+     712             :   unsigned int N = 0;
+     713             :   std::string cv_name;
+     714             : 
+     715          24 :   while (in_restart_.scanField("time", time))
+     716             :   {
+     717             : 
+     718          20 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     719             :     {
+     720             :       cv_name = getPntrToArgument(i)->getName();
+     721          20 :       in_restart_.scanField(cv_name + "_center", set_coupling_[i]);
+     722          20 :       in_restart_.scanField(cv_name + "_set", set_coupling_[i]);
+     723          20 :       in_restart_.scanField(cv_name + "_target", target_coupling_[i]);
+     724          20 :       in_restart_.scanField(cv_name + "_coupling", current_coupling_[i]);
+     725          20 :       in_restart_.scanField(cv_name + "_maxrange", max_coupling_range_[i]);
+     726          20 :       in_restart_.scanField(cv_name + "_maxgrad", max_coupling_grad_[i]);
+     727          20 :       in_restart_.scanField(cv_name + "_accum", coupling_accum_[i]);
+     728          10 :       in_restart_.scanField(cv_name + "_mean", means_[i]);
+     729          20 :       if (in_restart_.FieldExist(cv_name + "_pseudovirial"))
+     730             :       {
+     731           0 :         if (b_virial_)
+     732           0 :           in_restart_.scanField(cv_name + "_pseudovirial", pseudo_virial_[i]);
+     733             :         else // discard the field
+     734           0 :           in_restart_.scanField(cv_name + "_pseudovirial", tmp);
+     735             :       }
+     736             :       // unused due to difference between covar/nocovar
+     737          20 :       in_restart_.scanField(cv_name + "_std", tmp);
+     738             : 
+     739          10 :       avg_bias[i] += current_coupling_[i];
+     740             :     }
+     741          10 :     N++;
+     742             : 
+     743          10 :     in_restart_.scanField();
+     744             :   }
+     745             : 
+     746           2 :   log.printf("  with centers:");
+     747           4 :   for (unsigned int i = 0; i < center_.size(); ++i)
+     748             :   {
+     749           2 :     log.printf(" %f", center_[i]);
+     750             :   }
+     751           2 :   log.printf("\n  and scaling:");
+     752           4 :   for (unsigned int i = 0; i < scale_.size(); ++i)
+     753             :   {
+     754           2 :     log.printf(" %f", scale_[i]);
+     755             :   }
+     756             : 
+     757           2 :   log.printf("\n  with initial ranges / rates:\n");
+     758           4 :   for (unsigned int i = 0; i < max_coupling_range_.size(); ++i)
+     759             :   {
+     760           2 :     log.printf("    %f / %f\n", max_coupling_range_[i], max_coupling_grad_[i]);
+     761             :   }
+     762             : 
+     763           2 :   if (!b_adaptive_ && update_period_ < 0)
+     764             :   {
+     765           0 :     log.printf("  ramping up coupling constants over %i steps\n", -update_period_);
+     766             :   }
+     767             : 
+     768           2 :   if (b_mean)
+     769             :   {
+     770           1 :     log.printf("Loaded in averages for coupling constants...\n");
+     771           2 :     for (unsigned int i = 0; i < current_coupling_.size(); ++i)
+     772           1 :       current_coupling_[i] = avg_bias[i] / N;
+     773           2 :     for (unsigned int i = 0; i < current_coupling_.size(); ++i)
+     774           1 :       set_coupling_[i] = avg_bias[i] / N;
+     775             :   }
+     776             : 
+     777           2 :   log.printf("  with current coupling constants:\n    ");
+     778           4 :   for (unsigned int i = 0; i < current_coupling_.size(); ++i)
+     779           2 :     log.printf(" %f", current_coupling_[i]);
+     780           2 :   log.printf("\n");
+     781           2 :   log.printf("  with initial coupling constants:\n    ");
+     782           4 :   for (unsigned int i = 0; i < set_coupling_.size(); ++i)
+     783           2 :     log.printf(" %f", set_coupling_[i]);
+     784           2 :   log.printf("\n");
+     785           2 :   log.printf("  and final coupling constants:\n    ");
+     786           4 :   for (unsigned int i = 0; i < target_coupling_.size(); ++i)
+     787           2 :     log.printf(" %f", target_coupling_[i]);
+     788           2 :   log.printf("\n");
+     789             : 
+     790           2 :   in_restart_.close();
+     791           2 : }
+     792             : 
+     793           8 : void EDS::setupOutRestart()
+     794             : {
+     795           8 :   out_restart_.link(*this);
+     796           8 :   out_restart_.fmtField(fmt_);
+     797           8 :   out_restart_.open(out_restart_name_);
+     798             :   out_restart_.setHeavyFlush();
+     799             : 
+     800          16 :   out_restart_.addConstantField("adaptive").printField("adaptive", b_adaptive_);
+     801          16 :   out_restart_.addConstantField("update_period").printField("update_period", update_period_);
+     802          16 :   out_restart_.addConstantField("seed").printField("seed", seed_);
+     803          16 :   out_restart_.addConstantField("kbt").printField("kbt", kbt_);
+     804           8 : }
+     805             : 
+     806          27 : void EDS::writeOutRestart()
+     807             : {
+     808             :   std::string cv_name;
+     809          27 :   out_restart_.printField("time", getTimeStep() * getStep());
+     810             : 
+     811          66 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     812             :   {
+     813             :     cv_name = getPntrToArgument(i)->getName();
+     814          78 :     out_restart_.printField(cv_name + "_center", center_[i]);
+     815          78 :     out_restart_.printField(cv_name + "_set", set_coupling_[i]);
+     816          78 :     out_restart_.printField(cv_name + "_target", target_coupling_[i]);
+     817          78 :     out_restart_.printField(cv_name + "_coupling", current_coupling_[i]);
+     818          78 :     out_restart_.printField(cv_name + "_maxrange", max_coupling_range_[i]);
+     819          78 :     out_restart_.printField(cv_name + "_maxgrad", max_coupling_grad_[i]);
+     820          78 :     out_restart_.printField(cv_name + "_accum", coupling_accum_[i]);
+     821          39 :     out_restart_.printField(cv_name + "_mean", means_[i]);
+     822          39 :     if (b_virial_)
+     823          18 :       out_restart_.printField(cv_name + "_pseudovirial", pseudo_virial_[i]);
+     824          39 :     if (!b_covar_ && !b_lm_)
+     825          42 :       out_restart_.printField(cv_name + "_std", ssds_[i] / (fmax(1, update_calls_ - 1)));
+     826             :     else
+     827          36 :       out_restart_.printField(cv_name + "_std", covar_(i, i) / (fmax(1, update_calls_ - 1)));
+     828             :   }
+     829          27 :   out_restart_.printField();
+     830          27 : }
+     831             : 
+     832          40 : void EDS::calculate()
+     833             : {
+     834             : 
+     835             :   // get center values from action if necessary
+     836          40 :   if (b_c_values_)
+     837          10 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     838           5 :       center_[i] = center_values_[i]->get();
+     839             : 
+     840          40 :   apply_bias();
+     841          40 : }
+     842             : 
+     843          40 : void EDS::apply_bias()
+     844             : {
+     845             :   // Compute linear force as in "restraint"
+     846             :   double ene = 0, totf2 = 0, cv, m, f;
+     847             : 
+     848         100 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     849             :   {
+     850          60 :     cv = difference(i, center_[i], getArgument(i));
+     851          60 :     m = current_coupling_[i];
+     852          60 :     f = -m;
+     853          60 :     ene += m * cv;
+     854          60 :     setOutputForce(i, f);
+     855          60 :     totf2 += f * f;
+     856             :   }
+     857             : 
+     858          40 :   setBias(ene);
+     859          40 :   value_force2_->set(totf2);
+     860          40 : }
+     861             : 
+     862          12 : void EDS::update_statistics()
+     863             : {
+     864             :   double s, N, w = 1.0;
+     865          12 :   std::vector<double> deltas(ncvs_);
+     866             : 
+     867             :   // update weight max, if necessary
+     868          12 :   if (b_weights_)
+     869             :   {
+     870           2 :     w = logweights_->getLogWeight();
+     871           2 :     if (max_logweight_ < w)
+     872             :     {
+     873             :       // we have new max. Need to shift existing values
+     874           0 :       wsum_ *= exp(max_logweight_ - w);
+     875           0 :       max_logweight_ = w;
+     876             :     }
+     877             :     // convert to weight
+     878           2 :     w = exp(w - max_logweight_);
+     879           2 :     wsum_ += w;
+     880             :     N = wsum_;
+     881             :   }
+     882             :   else
+     883             :   {
+     884          10 :     N = fmax(1, update_calls_);
+     885             :   }
+     886             : 
+     887             :   // Welford, West, and Hanso online variance method
+     888             :   // with weights (default =  1.0)
+     889          32 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     890             :   {
+     891          20 :     deltas[i] = difference(i, means_[i], getArgument(i)) * w;
+     892          20 :     means_[i] += deltas[i] / N;
+     893          20 :     if (!b_covar_ && !b_lm_)
+     894           8 :       ssds_[i] += deltas[i] * difference(i, means_[i], getArgument(i));
+     895             :   }
+     896          12 :   if (b_covar_ || b_lm_)
+     897             :   {
+     898          16 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     899             :     {
+     900          36 :       for (unsigned int j = i; j < ncvs_; ++j)
+     901             :       {
+     902          24 :         s = (N - 1) * deltas[i] * deltas[j] / N / N - covar_(i, j) / N;
+     903          24 :         covar_(i, j) += s;
+     904             :         // do this so we don't double count
+     905          24 :         covar_(j, i) = covar_(i, j);
+     906             :       }
+     907             :     }
+     908             :   }
+     909          12 :   if (b_virial_)
+     910           2 :     update_pseudo_virial();
+     911          12 : }
+     912             : 
+     913           8 : void EDS::reset_statistics()
+     914             : {
+     915          20 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     916             :   {
+     917          12 :     means_[i] = 0;
+     918          12 :     if (!b_covar_ && !b_lm_)
+     919           6 :       ssds_[i] = 0;
+     920             :   }
+     921           8 :   if (b_covar_ || b_lm_)
+     922           8 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     923          24 :       for (unsigned int j = 0; j < ncvs_; ++j)
+     924          18 :         covar_(i, j) = 0;
+     925           8 :   if (b_virial_)
+     926             :   {
+     927           4 :     for (unsigned int i = 0; i < ncvs_; ++i)
+     928           3 :       pseudo_virial_[i] = 0;
+     929           1 :     pseudo_virial_sum_ = 0;
+     930             :   }
+     931           8 :   if (b_weights_)
+     932             :   {
+     933           2 :     wsum_ = 0;
+     934           2 :     max_logweight_ = 0;
+     935             :   }
+     936           8 : }
+     937             : 
+     938           1 : void EDS::calc_lm_step_size()
+     939             : {
+     940             :   // calulcate step size
+     941             :   // uses scale here, which by default is center
+     942             : 
+     943           1 :   mult(covar_, covar_, covar2_);
+     944           4 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     945             :   {
+     946           3 :     differences_[i] = difference(i, center_[i], means_[i]);
+     947           3 :     covar2_[i][i] += lm_mixing_par_ * covar2_[i][i];
+     948             :   }
+     949             : 
+     950             :   // "step_size_vec" = 2*inv(covar*covar+ lambda diag(covar*covar))*covar*(mean-center)
+     951           1 :   mult(covar_, differences_, alpha_vector_);
+     952           1 :   Invert(covar2_, lm_inv_);
+     953           1 :   mult(lm_inv_, alpha_vector_, alpha_vector_2_);
+     954             : 
+     955           4 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     956             :   {
+     957           3 :     step_size_[i] = 2 * alpha_vector_2_[i] / kbt_ / scale_[i];
+     958             :   }
+     959           1 : }
+     960             : 
+     961           1 : void EDS::calc_covar_step_size()
+     962             : {
+     963             :   // calulcate step size
+     964             :   // uses scale here, which by default is center
+     965             :   double tmp;
+     966           4 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     967             :   {
+     968             :     tmp = 0;
+     969          12 :     for (unsigned int j = 0; j < ncvs_; ++j)
+     970           9 :       tmp += difference(i, center_[i], means_[i]) * covar_(i, j);
+     971           3 :     step_size_[i] = 2 * tmp / kbt_ / scale_[i] * update_calls_ / fmax(1, update_calls_ - 1);
+     972             :   }
+     973           1 : }
+     974             : 
+     975           6 : void EDS::calc_ssd_step_size()
+     976             : {
+     977             :   double tmp;
+     978          12 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     979             :   {
+     980           6 :     tmp = 2. * difference(i, center_[i], means_[i]) * ssds_[i] / fmax(1, update_calls_ - 1);
+     981           6 :     step_size_[i] = tmp / kbt_ / scale_[i];
+     982             :   }
+     983           6 : }
+     984             : 
+     985           2 : void EDS::update_pseudo_virial()
+     986             : {
+     987             :   // We want to compute the bias force on each atom times the position
+     988             :   //  of the atoms.
+     989             :   double p, netp = 0, netpv = 0;
+     990             :   double volume = 0;
+     991           8 :   for (unsigned int i = 0; i < ncvs_; ++i)
+     992             :   {
+     993             :     // checked in setup to ensure this cast is valid.
+     994           6 :     ActionAtomistic *cv = dynamic_cast<ActionAtomistic *>(getPntrToArgument(i)->getPntrToAction());
+     995           6 :     Tensor v(cv->getVirial());
+     996           6 :     Tensor box(cv->getBox());
+     997             :     const unsigned int natoms = cv->getNumberOfAtoms();
+     998           6 :     if (!volume)
+     999           2 :       volume = box.determinant();
+    1000             : 
+    1001             :     // pressure contribution is -dBias / dV
+    1002             :     // dBias / dV = alpha / w * dCV / dV
+    1003             :     // to get partial of CV wrt to volume
+    1004             :     // dCV/dV = sum dCV/dvij * vij / V
+    1005             :     // where vij is box element
+    1006             :     // add diagonal of virial tensor to get net pressure
+    1007             :     // TODO: replace this with adjugate (Jacobi's Formula)   for non-orthorombic case(?)
+    1008           6 :     p = v(0, 0) * box(0, 0) + v(1, 1) * box(1, 1) + v(2, 2) * box(2, 2);
+    1009           6 :     p /= volume;
+    1010             : 
+    1011           6 :     netp += p;
+    1012             : 
+    1013             :     // now scale for correct units in EDS algorithm
+    1014           6 :     p *= (volume) / (kbt_ * natoms);
+    1015             : 
+    1016             :     // compute running mean of scaled
+    1017           6 :     if (set_coupling_[i] != 0)
+    1018           0 :       pseudo_virial_[i] = (p - pseudo_virial_[i]) / (fmax(1, update_calls_));
+    1019             :     else
+    1020           6 :       pseudo_virial_[i] = 0;
+    1021             :     // update net pressure
+    1022           6 :     netpv += pseudo_virial_[i];
+    1023             :   }
+    1024             :   // update pressure
+    1025           2 :   value_pressure_->set(netp);
+    1026           2 :   pseudo_virial_sum_ = netpv;
+    1027           2 : }
+    1028             : 
+    1029           8 : void EDS::update_bias()
+    1030             : {
+    1031           8 :   log.flush();
+    1032           8 :   if (b_lm_)
+    1033           1 :     calc_lm_step_size();
+    1034           7 :   else if (b_covar_)
+    1035           1 :     calc_covar_step_size();
+    1036             :   else
+    1037           6 :     calc_ssd_step_size();
+    1038             : 
+    1039          20 :   for (unsigned int i = 0; i < ncvs_; ++i)
+    1040             :   {
+    1041             : 
+    1042             :     // multidimesional stochastic step
+    1043          12 :     if (ncvs_ == 1 || (rand_.RandU01() < (multi_prop_)))
+    1044             :     {
+    1045             : 
+    1046          12 :       if (b_virial_)
+    1047             :       {
+    1048             :         // apply virial regularization
+    1049             :         //  P * dP/dcoupling
+    1050             :         //  coupling is already included in virial term due to plumed propogating from bias to forces
+    1051             :         //  thus we need to divide by it to get the derivative (since force is linear in coupling)
+    1052           3 :         if (fabs(set_coupling_[i]) > 0.000000001) // my heuristic for if EDS has started to prevent / 0
+    1053             :           // scale^2 here is to align units
+    1054           0 :           step_size_[i] -= 2 * scale_[i] * scale_[i] * virial_scaling_ * pseudo_virial_sum_ * pseudo_virial_sum_ / set_coupling_[i];
+    1055             :       }
+    1056          12 :       if (step_size_[i] == 0)
+    1057           4 :         continue;
+    1058             : 
+    1059             :       // clip gradient
+    1060           8 :       step_size_[i] = copysign(fmin(fabs(step_size_[i]), max_coupling_grad_[i]), step_size_[i]);
+    1061           8 :       coupling_accum_[i] += step_size_[i] * step_size_[i];
+    1062             : 
+    1063             :       // equation 5 in White and Voth, JCTC 2014
+    1064             :       // no negative sign because it's in step_size
+    1065           8 :       set_coupling_[i] += step_size_[i] * max_coupling_range_[i] / sqrt(coupling_accum_[i]);
+    1066           8 :       coupling_rate_[i] = (set_coupling_[i] - current_coupling_[i]) / update_period_;
+    1067             :     }
+    1068             :     else
+    1069             :     {
+    1070             :       // do not change the bias
+    1071           0 :       coupling_rate_[i] = 0;
+    1072             :     }
+    1073             :   }
+    1074             : 
+    1075             :   // reset means/vars
+    1076           8 :   reset_statistics();
+    1077           8 : }
+    1078             : 
+    1079          40 : void EDS::update()
+    1080             : {
+    1081             :   // adjust parameters according to EDS recipe
+    1082          40 :   update_calls_++;
+    1083             : 
+    1084             :   // if we aren't wating for the bias to equilibrate, set flag to collect data
+    1085             :   // want statistics before writing restart
+    1086          40 :   if (!b_equil_ && update_period_ > 0)
+    1087          12 :     update_statistics();
+    1088             : 
+    1089             :   // write restart with correct statistics before bias update
+    1090             :   // check if we're ramping or doing normal updates and then restart if needed. The ramping check
+    1091             :   // is complicated because we could be frozen, finished ramping or not ramping.
+    1092             :   // The + 2 is so we have an extra line showing that the bias isn't changing (for my sanity and yours)
+    1093          40 :   if (b_write_restart_)
+    1094             :   {
+    1095          40 :     if (getStep() == 0 ||
+    1096          32 :         ((update_period_ < 0 && !b_freeze_ && update_calls_ <= fabs(update_period_) + 2) ||
+    1097          24 :          (update_period_ > 0 && update_calls_ % update_period_ == 0)))
+    1098          27 :       writeOutRestart();
+    1099             :   }
+    1100             : 
+    1101             :   int b_finished_equil_flag = 1;
+    1102             : 
+    1103             :   // assume forces already applied and saved
+    1104             :   // are we ramping to a constant value and not done equilibrating?
+    1105          40 :   if (update_period_ < 0)
+    1106             :   {
+    1107           5 :     if (update_calls_ <= fabs(update_period_) && !b_freeze_)
+    1108             :     {
+    1109           4 :       for (unsigned int i = 0; i < ncvs_; ++i)
+    1110           2 :         current_coupling_[i] += (target_coupling_[i] - set_coupling_[i]) / fabs(update_period_);
+    1111             :     }
+    1112             :     // make sure we don't reset update calls
+    1113             :     b_finished_equil_flag = 0;
+    1114             :   }
+    1115          35 :   else if (update_period_ == 0)
+    1116             :   { // do we have a no-update case?
+    1117             :     // not updating
+    1118             :     // pass
+    1119             :   }
+    1120          30 :   else if (b_equil_)
+    1121             :   {
+    1122             :     // equilibrating
+    1123             :     // check if we've reached the setpoint
+    1124          48 :     for (unsigned int i = 0; i < ncvs_; ++i)
+    1125             :     {
+    1126          30 :       if (coupling_rate_[i] == 0 || pow(current_coupling_[i] - set_coupling_[i], 2) < pow(coupling_rate_[i], 2))
+    1127             :       {
+    1128          14 :         b_finished_equil_flag &= 1;
+    1129             :       }
+    1130             :       else
+    1131             :       {
+    1132          16 :         current_coupling_[i] += coupling_rate_[i];
+    1133             :         b_finished_equil_flag = 0;
+    1134             :       }
+    1135             :     }
+    1136             :   }
+    1137             : 
+    1138             :   // reduce all the flags
+    1139          40 :   if (b_equil_ && b_finished_equil_flag)
+    1140             :   {
+    1141          11 :     b_equil_ = false;
+    1142          11 :     update_calls_ = 0;
+    1143             :   }
+    1144             : 
+    1145             :   // Now we update coupling constant, if necessary
+    1146          40 :   if (!b_equil_ && update_period_ > 0 && update_calls_ == update_period_ && !b_freeze_)
+    1147             :   {
+    1148           8 :     update_bias();
+    1149           8 :     update_calls_ = 0;
+    1150           8 :     avg_coupling_count_++;
+    1151           8 :     b_equil_ = true; // back to equilibration now
+    1152             :   }                  // close update if
+    1153             : 
+    1154             :   // pass couplings out so they are accessible
+    1155         100 :   for (unsigned int i = 0; i < ncvs_; ++i)
+    1156             :   {
+    1157          60 :     out_coupling_[i]->set(current_coupling_[i]);
+    1158             :   }
+    1159          40 : }
+    1160             : 
+    1161          16 : EDS::~EDS()
+    1162             : {
+    1163           8 :   out_restart_.close();
+    1164          24 : }
+    1165             : 
+    1166           0 : void EDS::turnOnDerivatives()
+    1167             : {
+    1168             :   // do nothing
+    1169             :   // this is to avoid errors triggered when a bias is used as a CV
+    1170             :   // (This is done in ExtendedLagrangian.cpp)
+    1171           0 : }
+    1172             : 
+    1173             : }
+    1174             : } // close the 2 namespaces
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/index-sort-f.html b/coverage/eds/index-sort-f.html new file mode 100644 index 000000000000..dbcc0c353273 --- /dev/null +++ b/coverage/eds/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - eds + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - edsHitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-02-22 21:58:45Functions:172085.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EDS.cpp +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/index-sort-l.html b/coverage/eds/index-sort-l.html new file mode 100644 index 000000000000..23973bf9b131 --- /dev/null +++ b/coverage/eds/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - eds + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - edsHitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-02-22 21:58:45Functions:172085.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EDS.cpp +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/eds/index.html b/coverage/eds/index.html new file mode 100644 index 000000000000..ff4590c7cb8e --- /dev/null +++ b/coverage/eds/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - eds + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - edsHitTotalCoverage
Test:plumed test coverageLines:45148692.8 %
Date:2024-02-22 21:58:45Functions:172085.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EDS.cpp +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/emerald.png b/coverage/emerald.png new file mode 100644 index 0000000000000000000000000000000000000000..38ad4f4068b935643d2486f323005fb294a9bd7e GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^Jb!lvI6;R0X`wF(yt=9xVZRt1vCRixIA4P dLn>}1Cji+@42)0J?}79&c)I$ztaD0e0sy@GAL0N2 literal 0 HcmV?d00001 diff --git a/coverage/fisst/FISST.cpp.func-sort-c.html b/coverage/fisst/FISST.cpp.func-sort-c.html new file mode 100644 index 000000000000..3fdb71518a39 --- /dev/null +++ b/coverage/fisst/FISST.cpp.func-sort-c.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - fisst/FISST.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - FISST.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24730880.2 %
Date:2024-02-22 21:58:45Functions:151978.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5fisst5FISST13readInRestartEv0
_ZN4PLMD5fisst5FISST17turnOnDerivativesEv0
_ZN4PLMD5fisst5FISSTC2ERKNS_13ActionOptionsE0
_ZN4PLMD5fisst5FISSTD2Ev0
_ZN4PLMD5fisst5FISST15setupOutRestartEv2
_ZN4PLMD5fisst5FISST18setupOutObservableEv2
_ZN4PLMD5fisst5FISSTC1ERKNS_13ActionOptionsE2
_ZN4PLMD5fisst5FISSTD0Ev2
_ZN4PLMD5fisst5FISSTD1Ev2
_ZN4PLMD5fisst5FISST16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD5fisst5FISST25compute_observable_weightEv8
_ZN4PLMD5fisst5FISST10apply_biasEv10
_ZN4PLMD5fisst5FISST11update_biasEv10
_ZN4PLMD5fisst5FISST15writeOutRestartEv10
_ZN4PLMD5fisst5FISST17update_statisticsEv10
_ZN4PLMD5fisst5FISST18writeOutObservableEv10
_ZN4PLMD5fisst5FISST6updateEv10
_ZN4PLMD5fisst5FISST9calculateEv10
_ZN4PLMD5fisst5FISST21NormalizeForceWeightsEv12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/FISST.cpp.func.html b/coverage/fisst/FISST.cpp.func.html new file mode 100644 index 000000000000..66cc3b227a68 --- /dev/null +++ b/coverage/fisst/FISST.cpp.func.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - fisst/FISST.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - FISST.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24730880.2 %
Date:2024-02-22 21:58:45Functions:151978.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5fisst5FISST10apply_biasEv10
_ZN4PLMD5fisst5FISST11update_biasEv10
_ZN4PLMD5fisst5FISST13readInRestartEv0
_ZN4PLMD5fisst5FISST15setupOutRestartEv2
_ZN4PLMD5fisst5FISST15writeOutRestartEv10
_ZN4PLMD5fisst5FISST16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD5fisst5FISST17turnOnDerivativesEv0
_ZN4PLMD5fisst5FISST17update_statisticsEv10
_ZN4PLMD5fisst5FISST18setupOutObservableEv2
_ZN4PLMD5fisst5FISST18writeOutObservableEv10
_ZN4PLMD5fisst5FISST21NormalizeForceWeightsEv12
_ZN4PLMD5fisst5FISST25compute_observable_weightEv8
_ZN4PLMD5fisst5FISST6updateEv10
_ZN4PLMD5fisst5FISST9calculateEv10
_ZN4PLMD5fisst5FISSTC1ERKNS_13ActionOptionsE2
_ZN4PLMD5fisst5FISSTC2ERKNS_13ActionOptionsE0
_ZN4PLMD5fisst5FISSTD0Ev2
_ZN4PLMD5fisst5FISSTD1Ev2
_ZN4PLMD5fisst5FISSTD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/FISST.cpp.gcov.html b/coverage/fisst/FISST.cpp.gcov.html new file mode 100644 index 000000000000..5eb9dc35ed43 --- /dev/null +++ b/coverage/fisst/FISST.cpp.gcov.html @@ -0,0 +1,736 @@ + + + + + + + + LCOV - plumed test coverage - fisst/FISST.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - FISST.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24730880.2 %
Date:2024-02-22 21:58:45Functions:151978.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2020 of Glen Hocky
+       3             : 
+       4             : The FISST module is free software: you can redistribute it and/or modify
+       5             : it under the terms of the GNU Lesser General Public License as published by
+       6             : the Free Software Foundation, either version 3 of the License, or
+       7             : (at your option) any later version.
+       8             : 
+       9             : The FISST module is distributed in the hope that it will be useful,
+      10             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      11             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      12             : GNU Lesser General Public License for more details.
+      13             : 
+      14             : You should have received a copy of the GNU Lesser General Public License
+      15             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      16             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      17             : #include "bias/Bias.h"
+      18             : #include "core/ActionRegister.h"
+      19             : #include "tools/File.h"
+      20             : #include "tools/Matrix.h"
+      21             : #include "tools/Random.h"
+      22             : #include "legendre_rule_fast.h"
+      23             : 
+      24             : #include <iostream>
+      25             : 
+      26             : 
+      27             : using namespace PLMD;
+      28             : using namespace bias;
+      29             : 
+      30             : //namespace is lowercase to match
+      31             : //module names being all lowercase
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace fisst {
+      35             : 
+      36             : //+PLUMEDOC FISSTMOD_BIAS FISST
+      37             : /*
+      38             : Compute and apply the optimal linear force on an observable to enhance sampling of conformational distributions over a range of applied forces.
+      39             : 
+      40             : This method is described in \cite Hartmann-FISST-2019
+      41             : 
+      42             : If the system's Hamiltonian is given by:
+      43             : \f[
+      44             :     H(\vec{p},\vec{q}) = \sum_{j} \frac{p_j^2}{2m_j} + U(\vec{q}),
+      45             : \f]
+      46             : 
+      47             : This bias modifies the Hamiltonian to be:
+      48             : \f[
+      49             :   H'(\vec{p},\vec{q}) = H(\vec{p},\vec{q}) - \bar{F} Q
+      50             : \f]
+      51             : 
+      52             : where for CV \f$Q\f$, a coupling constant \f${\bar{F}}\f$ is determined
+      53             : adaptively according to the FISST algorithm.
+      54             : 
+      55             : Specifically,
+      56             : \f[
+      57             : \bar{F}(Q)=\frac{ \int_{F_{min}}^{F_{max}} e^{\beta F Q(\vec{q})} \omega(F) F dF}{\int_{F_{min}}^{F_{max}} e^{\beta F Q(\vec{q})} \omega(F) dF},
+      58             : \f]
+      59             : 
+      60             : where \f$\vec{q}\f$ are the molecular coordinates of the system, and \f$w(F)\f$ is a weighting function that is learned on the fly for each force by the FISST algorithm (starting from an initial weight distribution, uniform by default).
+      61             : 
+      62             : The target for \f$w(F)=1/Z_q(F)\f$, where
+      63             : \f[
+      64             :     Z_q(F) \equiv \int d\vec{q} e^{-\beta U(\vec{q}) + \beta F Q(\vec{q})}.
+      65             : \f]
+      66             : 
+      67             : FISST also computes and writes Observable Weights \f$W_F(\vec{q}_t)\f$ for a molecular configuration at time \f$t\f$, so that averages of other quantities \f$A(\vec{q})\f$ can be reconstructed later at different force values (over a trajectory with \f$T\f$ samples):
+      68             : \f[
+      69             :     \langle A \rangle_F = \frac{1}{T} \sum_t W_F(\vec{q}_t) A(\vec{q}_t).
+      70             : \f]
+      71             : 
+      72             : 
+      73             : \par Examples
+      74             : 
+      75             : In the following example, an adaptive restraint is learned to bias the distance between two atoms in a system, for a force range of 0-100 pN.
+      76             : 
+      77             : \plumedfile
+      78             : UNITS LENGTH=A TIME=fs ENERGY=kcal/mol
+      79             : 
+      80             : b1: GROUP ATOMS=1
+      81             : b2: GROUP ATOMS=12
+      82             : 
+      83             : dend: DISTANCE ATOMS=b1,b2
+      84             : 
+      85             : #The conversion factor is 69.4786 pN = 1 kcal/mol/Angstrom
+      86             : 
+      87             : #0 pN to 100 pN
+      88             : f: FISST MIN_FORCE=0 MAX_FORCE=1.44 PERIOD=100 NINTERPOLATE=31 ARG=dend OUT_RESTART=pull.restart.txt OUT_OBSERVABLE=pull.observable.txt OBSERVABLE_FREQ=1000
+      89             : 
+      90             : PRINT ARG=dend,f.dend_fbar,f.bias,f.force2 FILE=pull.colvar.txt STRIDE=1000
+      91             : \endplumedfile
+      92             : 
+      93             : 
+      94             : */
+      95             : //+ENDPLUMEDOC
+      96             : 
+      97             : 
+      98             : class FISST : public Bias {
+      99             : 
+     100             : 
+     101             : private:
+     102             :   /*We will get this and store it once, since on-the-fly changing number of CVs will be fatal*/
+     103             :   const unsigned int ncvs_;
+     104             :   std::vector<double> center_;
+     105             :   std::vector<double> current_avg_force_;
+     106             : 
+     107             :   std::vector<double> forces_;
+     108             :   std::vector<double> force_weight_;
+     109             :   std::vector<double> gauss_weight_;
+     110             :   std::vector<double> partition_estimate_;
+     111             :   std::vector<double> observable_weight_;
+     112             : 
+     113             :   std::string in_restart_name_;
+     114             :   std::string out_restart_name_;
+     115             :   std::string out_observable_name_;
+     116             :   std::string fmt_;
+     117             :   std::string initial_weight_dist_;
+     118             :   OFile out_restart_;
+     119             :   OFile out_observable_;
+     120             :   IFile in_restart_;
+     121             :   bool b_freeze_;
+     122             :   bool b_adaptive_;
+     123             :   bool b_restart_;
+     124             :   bool b_write_restart_;
+     125             :   bool b_write_observable_;
+     126             :   bool b_first_restart_sample_;
+     127             :   int period_;
+     128             :   int reset_period_;
+     129             :   int observable_freq_;
+     130             :   int n_interpolation_;
+     131             :   int n_samples_;
+     132             :   double kbt_;
+     133             :   double beta_;
+     134             :   //change min_force and max_force to vectors if going to do more than one cv
+     135             :   double max_force_;
+     136             :   double min_force_;
+     137             :   double initial_weight_rate_;
+     138             :   double threshold_;
+     139             :   Random rand_;
+     140             : 
+     141             : 
+     142             :   Value* value_force2_;
+     143             :   void readInRestart();
+     144             :   void NormalizeForceWeights();
+     145             :   /*setup output restart*/
+     146             :   void setupOutRestart();
+     147             :   void setupOutObservable();
+     148             :   /*write output restart*/
+     149             :   void writeOutRestart();
+     150             :   void writeOutObservable();
+     151             :   void update_statistics();
+     152             :   void update_bias();
+     153             :   void apply_bias();
+     154             :   void compute_observable_weight();
+     155             : 
+     156             : public:
+     157             :   explicit FISST(const ActionOptions&);
+     158             :   void calculate();
+     159             :   void update();
+     160             :   void turnOnDerivatives();
+     161             :   static void registerKeywords(Keywords& keys);
+     162             :   ~FISST();
+     163             : };
+     164             : 
+     165             : PLUMED_REGISTER_ACTION(FISST,"FISST")
+     166             : 
+     167           4 : void FISST::registerKeywords(Keywords& keys) {
+     168           4 :   Bias::registerKeywords(keys);
+     169           4 :   keys.use("ARG");
+     170           8 :   keys.add("compulsory","PERIOD","Steps corresponding to the learning rate");
+     171           8 :   keys.add("optional","RESET_PERIOD","Reset the learning statistics every time this number of steps comes around.");
+     172           8 :   keys.add("compulsory","NINTERPOLATE","Number of grid points on which to do interpolation.");
+     173           8 :   keys.add("compulsory","MIN_FORCE","Minimum force (per CV) to use for sampling. Units: [Energy]/[CV]  (can be negative).");
+     174           8 :   keys.add("compulsory","MAX_FORCE","Maximum force (per CV) to use for sampling.");
+     175           8 :   keys.add("compulsory","CENTER","0","The CV value at which the applied bias energy will be zero");
+     176           8 :   keys.add("optional","KBT","The system temperature in units of KB*T. If not provided will be taken from MD code (if available)");
+     177             : 
+     178           8 :   keys.add("optional","INITIAL_WEIGHT_DIST","Starting distribution for the force weights (options: UNIFORM, EXP, GAUSS).");
+     179           8 :   keys.add("optional","INITIAL_WEIGHT_RATE","Rate of decay for exponential and gaussian distributions. W(F)~exp(-r |F|^d).");
+     180             : 
+     181           8 :   keys.add("optional","RESTART_FMT","the format that should be used to output real numbers in FISST restarts.");
+     182           8 :   keys.add("optional","OUT_RESTART","Output file for all information needed to continue FISST simulation."
+     183             :            "If you have the RESTART directive set (global or for FISST), this file will be appended to."
+     184             :            "Note that the header will be printed again if appending.");
+     185           8 :   keys.add("optional","IN_RESTART","Read this file to continue an FISST simulation. "
+     186             :            "If same as OUT_RESTART and you have not set the RESTART directive, the file will be backed-up and overwritten with new output."
+     187             :            "If you do have the RESTART flag set and it is the same name as OUT_RESTART, this file will be appended.");
+     188           8 :   keys.add("optional","OUT_OBSERVABLE","Output file putting weights needed to compute observables at different force values."
+     189             :            "If you have the RESTART directive set (global or for FISST), this file will be appended to. "
+     190             :            "Note that the header will be printed again if appending.");
+     191           8 :   keys.add("optional","OBSERVABLE_FREQ","How often to write out observable weights (default=period).");
+     192           8 :   keys.addFlag("FREEZE",false,"Fix bias weights at current level (only used for restarting).");
+     193           4 :   keys.use("RESTART");
+     194           8 :   keys.addOutputComponent("force2","default","squared value of force from the bias.");
+     195           8 :   keys.addOutputComponent("_fbar","default", "For each named CV biased, there will be a corresponding output CV_fbar storing the current linear bias prefactor.");
+     196           4 : }
+     197             : 
+     198           2 : FISST::FISST(const ActionOptions&ao):
+     199             :   PLUMED_BIAS_INIT(ao),
+     200           2 :   ncvs_(getNumberOfArguments()),
+     201           0 :   current_avg_force_(ncvs_,0.0),
+     202           2 :   center_(ncvs_,0.0),
+     203             :   //change min_force and max_force to vectors if going to do more than one cv
+     204           2 :   min_force_(0.0),
+     205           2 :   max_force_(0.0),
+     206           2 :   in_restart_name_(""),
+     207           2 :   out_restart_name_(""),
+     208           2 :   out_observable_name_(""),
+     209           2 :   fmt_("%e"),
+     210           2 :   b_freeze_(false),
+     211           2 :   b_restart_(false),
+     212           2 :   b_write_restart_(false),
+     213           2 :   b_write_observable_(false),
+     214           2 :   b_first_restart_sample_(true),
+     215           2 :   n_interpolation_(0),
+     216           2 :   n_samples_(0),
+     217           2 :   initial_weight_rate_(0),
+     218           2 :   initial_weight_dist_("UNIFORM"),
+     219           2 :   period_(0),
+     220           2 :   reset_period_(0),
+     221           2 :   observable_freq_(0),
+     222           2 :   kbt_(0.0),
+     223           6 :   value_force2_(NULL)
+     224             : {
+     225           2 :   if(ncvs_==0)
+     226           0 :     error("Must specify at least one CV with ARG");
+     227             : 
+     228             :   //temporary
+     229           2 :   if(ncvs_>1)
+     230           0 :     error("FISST only supports using one CV right now");
+     231             : 
+     232           4 :   addComponent("force2");
+     233           2 :   componentIsNotPeriodic("force2");
+     234           2 :   value_force2_ = getPntrToComponent("force2");
+     235             : 
+     236           4 :   for(unsigned int i = 0; i<ncvs_; i++) {
+     237           2 :     std::string comp = getPntrToArgument(i)->getName() + "_fbar";
+     238           2 :     addComponent(comp);
+     239           2 :     componentIsNotPeriodic(comp);
+     240             :   }
+     241             : 
+     242           2 :   parseVector("CENTER",center_);
+     243             :   //change min_force and max_force to vectors if going to do more than one cv
+     244           2 :   parse("MIN_FORCE",min_force_);
+     245           2 :   parse("MAX_FORCE",max_force_);
+     246           2 :   parse("PERIOD",period_);
+     247           2 :   parse("RESET_PERIOD",reset_period_);
+     248           2 :   parse("INITIAL_WEIGHT_DIST",initial_weight_dist_);
+     249           2 :   parse("INITIAL_WEIGHT_RATE",initial_weight_rate_);
+     250           2 :   parse("OBSERVABLE_FREQ",observable_freq_);
+     251           2 :   parse("NINTERPOLATE",n_interpolation_);
+     252           2 :   parseFlag("FREEZE",b_freeze_);
+     253           2 :   parse("KBT",kbt_);
+     254           2 :   parse("RESTART_FMT", fmt_);
+     255           2 :   fmt_ = " " + fmt_;//add space since parse strips them
+     256           2 :   parse("OUT_RESTART",out_restart_name_);
+     257           2 :   parse("OUT_OBSERVABLE",out_observable_name_);
+     258           2 :   parse("IN_RESTART",in_restart_name_);
+     259           2 :   checkRead();
+     260             : 
+     261           2 :   if(center_.size() != ncvs_)
+     262           0 :     error("Must have same number of CENTER arguments as ARG arguments");
+     263             : 
+     264           2 :   if(in_restart_name_ != "") {
+     265           0 :     b_restart_ = true;
+     266           0 :     log.printf("  reading simulation information from file: %s\n",in_restart_name_.c_str());
+     267           0 :     readInRestart();
+     268             :   } else {
+     269             : 
+     270           2 :     if(! kbt_ > 0.0) kbt_=getkBT();
+     271             : 
+     272             :     //in driver, this results in kbt of 0
+     273           2 :     if(kbt_ == 0) {
+     274           0 :       error("  Unable to determine valid kBT. "
+     275             :             "Could be because you are runnning from driver or MD didn't give temperature.\n"
+     276             :             "Consider setting temperature manually with the KBT keyword.");
+     277             :     }
+     278             : 
+     279           2 :     log.printf("  kBT = %f\n",kbt_);
+     280           2 :     log.printf("  Updating with a time scale of %i steps\n",period_);
+     281             : 
+     282           2 :     log.printf("  Using centers for CVs of:");
+     283           4 :     for(unsigned int i = 0; i< ncvs_; i++) {
+     284           2 :       log.printf(" %f ",center_[i]);
+     285             :     }
+     286           2 :     log.printf("\n");
+     287           2 :     observable_weight_.resize(n_interpolation_);
+     288          64 :     for(unsigned int i = 0; i<n_interpolation_; i++) observable_weight_[i] = 1.0;
+     289             : 
+     290           2 :     forces_.resize(n_interpolation_);
+     291           2 :     force_weight_.resize(n_interpolation_);
+     292             :     //using code from the MIST project
+     293           2 :     gauss_weight_.resize(n_interpolation_);
+     294           2 :     legendre_compute_glr(n_interpolation_, &forces_[0], &gauss_weight_[0]);
+     295           2 :     rescale(min_force_, max_force_, n_interpolation_, &forces_[0], &gauss_weight_[0]);
+     296             : 
+     297           2 :     log.printf("Using weight distribution %s with rate %f\n",initial_weight_dist_.c_str(),initial_weight_rate_);
+     298           2 :     if(initial_weight_dist_ == "UNIFORM" ) {
+     299          32 :       for(unsigned int i = 0; i<n_interpolation_; i++) force_weight_[i] = 1.0;
+     300             :     }
+     301           1 :     else if (initial_weight_dist_ == "EXP" ) {
+     302          32 :       for(unsigned int i = 0; i<n_interpolation_; i++) force_weight_[i] = exp(-fabs(forces_[i])*initial_weight_rate_);
+     303             :     }
+     304           0 :     else if (initial_weight_dist_ == "GAUSS" ) {
+     305           0 :       for(unsigned int i = 0; i<n_interpolation_; i++) force_weight_[i] = exp(-pow(forces_[i],2)*initial_weight_rate_);
+     306             :     }
+     307             :     else {
+     308           0 :       error("  Specified weight distribution is not from the allowed list.");
+     309             : 
+     310             :     }
+     311             : 
+     312           2 :     partition_estimate_.resize(n_interpolation_);
+     313           2 :     NormalizeForceWeights();
+     314             :     double sum = 0.0;
+     315          64 :     for(unsigned int i = 0; i<n_interpolation_; i++) {
+     316             :       //setting partition estimate as 1/w_i
+     317          62 :       partition_estimate_[i] = 1/force_weight_[i];
+     318          62 :       log.printf("force/gauss weight/force_weight: %i %f %f %f\n",i,forces_[i],gauss_weight_[i],force_weight_[i]);
+     319          62 :       sum+=gauss_weight_[i]*force_weight_[i];
+     320             :     }
+     321           2 :     log.printf("--Sum_i w_i g_i: %f\n",sum);
+     322             : 
+     323             :   }
+     324             : 
+     325             :   //set inverse temperature
+     326           2 :   beta_ = 1/kbt_;
+     327             : 
+     328           2 :   if(b_freeze_ && b_restart_) {
+     329           0 :     log.printf("  freezing weights read in from the restart file\n");
+     330             :   }
+     331             : 
+     332           2 :   if(out_restart_name_.length()>0) {
+     333           2 :     log.printf("  writing restart information every %i steps to file %s with format %s\n",abs(period_),out_restart_name_.c_str(), fmt_.c_str());
+     334           2 :     b_write_restart_ = true;
+     335           2 :     setupOutRestart();
+     336             :   }
+     337           2 :   if(out_observable_name_.length()>0) {
+     338           2 :     if(observable_freq_==0) observable_freq_ = period_;
+     339           2 :     log.printf("  writing observable information every %i steps to file %s with format %s\n",observable_freq_,out_observable_name_.c_str(), fmt_.c_str());
+     340           2 :     b_write_observable_ = true;
+     341           2 :     setupOutObservable();
+     342             :   }
+     343             : 
+     344             :   //add citation later:
+     345             :   //log<<"  Bibliography "<<plumed.cite("")<<"\n";
+     346           2 : }
+     347             : 
+     348          12 : void FISST::NormalizeForceWeights() {
+     349             :   double denom = 0.0;
+     350             : 
+     351         384 :   for(unsigned i=0; i<n_interpolation_; i++)
+     352         372 :     denom += gauss_weight_[i] * force_weight_[i];
+     353             : 
+     354         384 :   for(unsigned i=0; i<n_interpolation_; i++)
+     355         372 :     force_weight_[i] /= denom;
+     356          12 : }
+     357             : 
+     358           0 : void FISST::readInRestart() {
+     359           0 :   in_restart_.open(in_restart_name_);
+     360             : 
+     361           0 :   if(in_restart_.FieldExist("kbt")) {
+     362           0 :     in_restart_.scanField("kbt",kbt_);
+     363           0 :   } else { error("No field 'kbt' in restart file"); }
+     364           0 :   log.printf("  with kBT = %f\n",kbt_);
+     365             : 
+     366           0 :   if(in_restart_.FieldExist("period")) {
+     367           0 :     in_restart_.scanField("period",period_);
+     368           0 :   } else { error("No field 'period' in restart file"); }
+     369           0 :   log.printf("  Updating every %i steps\n",period_);
+     370             : 
+     371             : //this one can be optional
+     372           0 :   if(in_restart_.FieldExist("reset_period")) {
+     373           0 :     in_restart_.scanField("reset_period",reset_period_);
+     374             :   }
+     375           0 :   log.printf("  Resetting statistics every %i steps\n",reset_period_);
+     376             : 
+     377           0 :   if(in_restart_.FieldExist("n_interpolation")) {
+     378           0 :     in_restart_.scanField("n_interpolation",n_interpolation_);
+     379           0 :   } else { error("No field 'n_interpolation' in restart file"); }
+     380             : 
+     381           0 :   if(in_restart_.FieldExist("min_force")) {
+     382           0 :     in_restart_.scanField("min_force",min_force_);
+     383           0 :   } else { error("No field 'min_force' in restart file"); }
+     384           0 :   if(in_restart_.FieldExist("max_force")) {
+     385           0 :     in_restart_.scanField("max_force",max_force_);
+     386           0 :   } else { error("No field 'max_force' in restart file"); }
+     387           0 :   log.printf("  with forces from min_force=%e to max_force=%e over %i bins\n",min_force_,max_force_,n_interpolation_);
+     388             : 
+     389             :   unsigned int N = 0;
+     390             :   std::string cv_name;
+     391             :   double tmp, time;
+     392             : 
+     393           0 :   while(in_restart_.scanField("time",time)) {
+     394           0 :     in_restart_.scanField("nsamples",n_samples_);
+     395             : 
+     396           0 :     observable_weight_.resize(n_interpolation_);
+     397           0 :     partition_estimate_.resize(n_interpolation_);
+     398           0 :     force_weight_.resize(n_interpolation_);
+     399           0 :     gauss_weight_.resize(n_interpolation_);
+     400           0 :     forces_.resize(n_interpolation_);
+     401             : 
+     402           0 :     for(unsigned int i = 0; i<ncvs_; ++i) {
+     403             :       cv_name = getPntrToArgument(i)->getName();
+     404           0 :       in_restart_.scanField(cv_name,tmp);
+     405           0 :       for(unsigned int j =0; j<n_interpolation_; ++j) {
+     406           0 :         in_restart_.scanField(cv_name + "_f"+std::to_string(j),forces_[j]);
+     407           0 :         in_restart_.scanField(cv_name + "_g"+std::to_string(j),gauss_weight_[j]);
+     408           0 :         in_restart_.scanField(cv_name + "_w"+std::to_string(j),force_weight_[j]);
+     409           0 :         in_restart_.scanField(cv_name + "_z"+std::to_string(j),partition_estimate_[j]);
+     410             :       }
+     411             :     }
+     412             :     N++;
+     413             : 
+     414           0 :     in_restart_.scanField();
+     415             :   }
+     416             : 
+     417             :   double sum = 0.0;
+     418           0 :   for(unsigned int j =0; j<n_interpolation_; ++j) {
+     419             :     //clear observable weight, which will be set later
+     420           0 :     observable_weight_[j] = 1.0;
+     421             : 
+     422             :     //setting partition estimate as 1/w_i
+     423           0 :     log.printf("force/gauss weight/force_weight: %i %e %e %e\n",j,forces_[j],gauss_weight_[j],force_weight_[j]);
+     424           0 :     sum+=gauss_weight_[j]*force_weight_[j];
+     425             :   }
+     426           0 :   log.printf("--Sum_i w_i g_i: %f\n",sum);
+     427             : 
+     428           0 :   in_restart_.close();
+     429           0 : }
+     430             : 
+     431           2 : void FISST::setupOutObservable() {
+     432           2 :   out_observable_.link(*this);
+     433           2 :   out_observable_.fmtField(fmt_);
+     434           2 :   out_observable_.open(out_observable_name_);
+     435             :   out_observable_.setHeavyFlush();
+     436             : 
+     437           4 :   out_observable_.addConstantField("kbt").printField("kbt",kbt_);
+     438           4 :   out_observable_.addConstantField("n_interpolation").printField("n_interpolation",n_interpolation_);
+     439           4 :   out_observable_.addConstantField("period").printField("period",period_);
+     440           4 :   out_observable_.addConstantField("min_force").printField("min_force",min_force_);
+     441           4 :   out_observable_.addConstantField("max_force").printField("max_force",max_force_);
+     442           2 : }
+     443             : 
+     444           2 : void FISST::setupOutRestart() {
+     445           2 :   out_restart_.link(*this);
+     446           2 :   out_restart_.fmtField(fmt_);
+     447           2 :   out_restart_.open(out_restart_name_);
+     448             :   out_restart_.setHeavyFlush();
+     449             : 
+     450           4 :   out_restart_.addConstantField("kbt").printField("kbt",kbt_);
+     451           4 :   out_restart_.addConstantField("n_interpolation").printField("n_interpolation",n_interpolation_);
+     452           4 :   out_restart_.addConstantField("period").printField("period",period_);
+     453           2 :   if(reset_period_>0) out_restart_.addConstantField("reset_period").printField("reset_period",reset_period_);
+     454           4 :   out_restart_.addConstantField("min_force").printField("min_force",min_force_);
+     455           4 :   out_restart_.addConstantField("max_force").printField("max_force",max_force_);
+     456           2 : }
+     457             : 
+     458          10 : void FISST::writeOutRestart() {
+     459             :   std::string cv_name;
+     460          10 :   out_restart_.printField("time",getTimeStep()*getStep());
+     461          10 :   out_restart_.printField("nsamples",n_samples_);
+     462             : 
+     463          20 :   for(unsigned int i = 0; i<ncvs_; ++i) {
+     464             :     cv_name = getPntrToArgument(i)->getName();
+     465          10 :     double Q_i = difference(i, center_[i], getArgument(i));
+     466          10 :     out_restart_.printField(cv_name,Q_i);
+     467         320 :     for(int j = 0; j < n_interpolation_; j++ ) {
+     468             : //have to update this for multiple cvs
+     469         620 :       out_restart_.printField(cv_name + "_f"+std::to_string(j),forces_[j]);
+     470         620 :       out_restart_.printField(cv_name + "_g"+std::to_string(j),gauss_weight_[j]);
+     471         620 :       out_restart_.printField(cv_name + "_w"+std::to_string(j),force_weight_[j]);
+     472         620 :       out_restart_.printField(cv_name + "_z"+std::to_string(j),partition_estimate_[j]);
+     473             :     }
+     474             :   }
+     475          10 :   out_restart_.printField();
+     476          10 : }
+     477             : 
+     478          10 : void FISST::writeOutObservable() {
+     479             :   std::string cv_name;
+     480          10 :   out_observable_.printField("time",getTimeStep()*getStep());
+     481          10 :   out_observable_.printField("nsamples",n_samples_);
+     482             : 
+     483          20 :   for(unsigned int i = 0; i<ncvs_; ++i) {
+     484             :     cv_name = getPntrToArgument(i)->getName();
+     485          10 :     double Q_i = difference(i, center_[i], getArgument(i));
+     486          10 :     out_observable_.printField(cv_name,Q_i);
+     487          10 :     out_observable_.printField(cv_name + "_fbar",current_avg_force_[i]);
+     488         320 :     for(int j = 0; j < n_interpolation_; j++ ) {
+     489             : //have to update this for multiple cvs
+     490         620 :       out_observable_.printField(cv_name + "_f"+std::to_string(j),forces_[j]);
+     491         620 :       out_observable_.printField(cv_name + "_ow"+std::to_string(j),observable_weight_[j]);
+     492             :     }
+     493             :   }
+     494          10 :   out_observable_.printField();
+     495          10 : }
+     496             : 
+     497             : 
+     498          10 : void FISST::calculate() {
+     499          10 :   if(getStep() == 0 ) {
+     500           2 :     if(b_write_restart_) writeOutRestart();
+     501           2 :     if(b_write_observable_) writeOutObservable();
+     502             :   }
+     503             : 
+     504          10 :   if(! b_freeze_) {
+     505          10 :     if(b_restart_ && b_first_restart_sample_) {
+     506             :       //dont' update statistics if restarting and first sample
+     507           0 :       b_first_restart_sample_ = false;
+     508             :     }
+     509             :     else {
+     510          10 :       update_statistics();
+     511             :     }
+     512             :   }
+     513          10 :   update_bias();
+     514          10 :   apply_bias();
+     515             : 
+     516             :   //check about writing restart file
+     517          10 :   if(getStep()>0 && getStep()%period_==0) {
+     518           8 :     if(b_write_restart_) writeOutRestart();
+     519             :   }
+     520          10 :   if(getStep()>0 && getStep()%observable_freq_==0) {
+     521           8 :     if(b_write_observable_) {
+     522           8 :       compute_observable_weight();
+     523           8 :       writeOutObservable();
+     524             :     }
+     525             :   }
+     526          10 : }
+     527             : 
+     528             : 
+     529          10 : void FISST::apply_bias() {
+     530             :   //Compute linear force as in "restraint"
+     531             :   double ene = 0, totf2 = 0, cv, m, f;
+     532             : 
+     533          20 :   for(unsigned int i = 0; i < ncvs_; ++i) {
+     534          10 :     cv = difference(i, center_[i], getArgument(i));
+     535          10 :     double fbar = current_avg_force_[i];
+     536          10 :     ene -= fbar*cv;
+     537          10 :     setOutputForce(i,fbar);
+     538          10 :     totf2 += fbar*fbar;
+     539             : 
+     540          10 :     std::string fbar_name_ = getPntrToArgument(i)->getName() + "_fbar";
+     541          10 :     Value* fbar_ = getPntrToComponent(fbar_name_);
+     542             :     fbar_->set(fbar);
+     543             :   };
+     544             : 
+     545          10 :   setBias(ene);
+     546          10 :   value_force2_->set(totf2);
+     547             :   //log.flush();
+     548          10 : }
+     549             : 
+     550          10 : void FISST::update_statistics()  {
+     551             : //get stride is for multiple time stepping
+     552          10 :   double dt=getTimeStep()*getStride();
+     553          10 :   double h = dt/(period_*getTimeStep());
+     554             :   double fbar_denum_integral = 0.0;
+     555             : 
+     556          10 :   int step = getStep();
+     557          10 :   if(reset_period_>0 && step>0 && step%reset_period_==0) {
+     558           0 :     n_samples_=1;
+     559             :   }
+     560             :   else {
+     561          10 :     n_samples_++;
+     562             :   }
+     563          10 :   double d_n_samples = (double)n_samples_;
+     564             : 
+     565          20 :   for(unsigned int i = 0; i < ncvs_; ++i) {
+     566          10 :     double Q_i = difference(i, center_[i], getArgument(i));
+     567         320 :     for(unsigned int j=0; j<n_interpolation_; j++)
+     568             :     {
+     569             :       //if multiple cvs, these need to be updated to have 2 columns
+     570         310 :       double f_j = forces_[j];
+     571         310 :       double w_j = force_weight_[j];
+     572         310 :       double g_j = gauss_weight_[j];
+     573             : 
+     574         310 :       fbar_denum_integral += g_j * w_j * exp(beta_*f_j * Q_i);
+     575             :     }
+     576             : 
+     577         320 :     for(unsigned int j=0; j<n_interpolation_; j++)
+     578             :     {
+     579         310 :       double f_j = forces_[j];
+     580         310 :       double sample_weight = exp(beta_*f_j * Q_i) / fbar_denum_integral;
+     581             : 
+     582         310 :       partition_estimate_[j] = sample_weight/d_n_samples + partition_estimate_[j]*(d_n_samples-1)/(d_n_samples);
+     583             : 
+     584         310 :       double w_jn = force_weight_[j];
+     585         310 :       double z_jn = partition_estimate_[j];
+     586             : 
+     587         310 :       double w_jp1 = (1.0 - h) * w_jn + h / z_jn;
+     588         310 :       force_weight_[j] = w_jp1;
+     589             :     }
+     590             :   }
+     591             : 
+     592             :   // make sure that the weights are normalised
+     593          10 :   NormalizeForceWeights();
+     594          10 : }
+     595             : 
+     596             : 
+     597          10 : void FISST::update_bias()
+     598             : {
+     599          20 :   for(unsigned int i = 0; i < ncvs_; ++i) {
+     600          10 :     double Q_i = difference(i, center_[i], getArgument(i));
+     601             :     double fbar_num_integral = 0.0;
+     602             :     double fbar_denum_integral = 0.0;
+     603             : 
+     604         320 :     for(unsigned int j=0; j<n_interpolation_; j++ ) {
+     605         310 :       double f_j = forces_[j];
+     606         310 :       double w_j = force_weight_[j];
+     607         310 :       double g_j = gauss_weight_[j];
+     608             : 
+     609         310 :       fbar_num_integral += g_j * f_j * w_j * exp(beta_*f_j*Q_i);
+     610         310 :       fbar_denum_integral += g_j * w_j * exp(beta_*f_j*Q_i);
+     611             :     }
+     612             : 
+     613          10 :     current_avg_force_[i] = fbar_num_integral/fbar_denum_integral;
+     614             :   }
+     615          10 : }
+     616             : 
+     617           8 : void FISST::compute_observable_weight() {
+     618           8 :   double obs_num = (max_force_ - min_force_);
+     619             : 
+     620          16 :   for(unsigned int i = 0; i < ncvs_; ++i) {
+     621           8 :     double Q_i = difference(i, center_[i], getArgument(i));
+     622             : 
+     623         256 :     for(unsigned int j=0; j<n_interpolation_; j++ ) {
+     624         248 :       double z_j = partition_estimate_[j];
+     625         248 :       double f_j = forces_[j];
+     626             :       double denum_integral = 0.0;
+     627             : 
+     628        7936 :       for( unsigned int k=0; k<n_interpolation_; k++ ) {
+     629        7688 :         double f_k = forces_[k];
+     630        7688 :         double w_k = force_weight_[k];
+     631        7688 :         double g_k = gauss_weight_[k];
+     632             : 
+     633        7688 :         denum_integral += g_k * w_k * exp(beta_*(f_k-f_j)*Q_i);
+     634             :       }
+     635         248 :       observable_weight_[j] = obs_num/(denum_integral*z_j);
+     636             :     }
+     637             :   }
+     638           8 : }
+     639             : 
+     640             : 
+     641             : 
+     642          10 : void FISST::update() {
+     643             :   //pass
+     644          10 : }
+     645             : 
+     646           4 : FISST::~FISST() {
+     647           2 :   out_restart_.close();
+     648           2 :   out_observable_.close();
+     649           6 : }
+     650             : 
+     651           0 : void FISST::turnOnDerivatives() {
+     652             :   // do nothing
+     653             :   // this is to avoid errors triggered when a bias is used as a CV
+     654             :   // (This is done in ExtendedLagrangian.cpp)
+     655           0 : }
+     656             : 
+     657             : 
+     658             : }
+     659             : }//close the 2 namespaces
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/index-sort-f.html b/coverage/fisst/index-sort-f.html new file mode 100644 index 000000000000..662694b103bc --- /dev/null +++ b/coverage/fisst/index-sort-f.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - fisst + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisstHitTotalCoverage
Test:plumed test coverageLines:31940179.6 %
Date:2024-02-22 21:58:45Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FISST.cpp +
80.2%80.2%
+
80.2 %247 / 30878.9 %15 / 19
legendre_rule_fast.cpp +
77.4%77.4%
+
77.4 %72 / 9385.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/index-sort-l.html b/coverage/fisst/index-sort-l.html new file mode 100644 index 000000000000..36ce5853f068 --- /dev/null +++ b/coverage/fisst/index-sort-l.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - fisst + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisstHitTotalCoverage
Test:plumed test coverageLines:31940179.6 %
Date:2024-02-22 21:58:45Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
legendre_rule_fast.cpp +
77.4%77.4%
+
77.4 %72 / 9385.7 %6 / 7
FISST.cpp +
80.2%80.2%
+
80.2 %247 / 30878.9 %15 / 19
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/index.html b/coverage/fisst/index.html new file mode 100644 index 000000000000..d634545faebf --- /dev/null +++ b/coverage/fisst/index.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - fisst + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisstHitTotalCoverage
Test:plumed test coverageLines:31940179.6 %
Date:2024-02-22 21:58:45Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FISST.cpp +
80.2%80.2%
+
80.2 %247 / 30878.9 %15 / 19
legendre_rule_fast.cpp +
77.4%77.4%
+
77.4 %72 / 9385.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/legendre_rule_fast.cpp.func-sort-c.html b/coverage/fisst/legendre_rule_fast.cpp.func-sort-c.html new file mode 100644 index 000000000000..c7c40baf623e --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - fisst/legendre_rule_fast.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - legendre_rule_fast.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:729377.4 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5fisst21legendre_compute_glr2EdiPdS1_0
_ZN4PLMD5fisst20legendre_compute_glrEiPdS1_2
_ZN4PLMD5fisst21legendre_compute_glr0EiPdS1_2
_ZN4PLMD5fisst21legendre_compute_glr1EiPdS1_2
_ZN4PLMD5fisst7rescaleEddiPdS1_2
_ZN4PLMD5fisst7rk2_legEdddi30
_ZN4PLMD5fisst7ts_multEPddi330
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/legendre_rule_fast.cpp.func.html b/coverage/fisst/legendre_rule_fast.cpp.func.html new file mode 100644 index 000000000000..c7c0e2a5520d --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - fisst/legendre_rule_fast.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - legendre_rule_fast.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:729377.4 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5fisst20legendre_compute_glrEiPdS1_2
_ZN4PLMD5fisst21legendre_compute_glr0EiPdS1_2
_ZN4PLMD5fisst21legendre_compute_glr1EiPdS1_2
_ZN4PLMD5fisst21legendre_compute_glr2EdiPdS1_0
_ZN4PLMD5fisst7rescaleEddiPdS1_2
_ZN4PLMD5fisst7rk2_legEdddi30
_ZN4PLMD5fisst7ts_multEPddi330
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/fisst/legendre_rule_fast.cpp.gcov.html b/coverage/fisst/legendre_rule_fast.cpp.gcov.html new file mode 100644 index 000000000000..4d8b357e8756 --- /dev/null +++ b/coverage/fisst/legendre_rule_fast.cpp.gcov.html @@ -0,0 +1,642 @@ + + + + + + + + LCOV - plumed test coverage - fisst/legendre_rule_fast.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - fisst - legendre_rule_fast.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:729377.4 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2020 of Glen Hocky
+       3             : 
+       4             : The FISST module is free software: you can redistribute it and/or modify
+       5             : it under the terms of the GNU Lesser General Public License as published by
+       6             : the Free Software Foundation, either version 3 of the License, or
+       7             : (at your option) any later version.
+       8             : 
+       9             : The FISST module is distributed in the hope that it will be useful,
+      10             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      11             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      12             : GNU Lesser General Public License for more details.
+      13             : 
+      14             : You should have received a copy of the GNU Lesser General Public License
+      15             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      16             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      17             : //#ifndef __PLUMED_fisst_legendre_rule_fast_h
+      18             : //#define __PLUMED_fisst_legendre_rule_fast_h
+      19             : // adapted from:
+      20             : // https://people.sc.fsu.edu/~jburkardt/cpp_src/legendre_rule_fast/legendre_rule_fast.html
+      21             : //
+      22             : #include "legendre_rule_fast.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace fisst {
+      26             : //****************************************************************************80
+      27             : 
+      28           2 : void legendre_compute_glr ( int n, double x[], double w[] )
+      29             : 
+      30             : //****************************************************************************80
+      31             : //
+      32             : //  Purpose:
+      33             : //
+      34             : //    LEGENDRE_COMPUTE_GLR: Legendre quadrature by the Glaser-Liu-Rokhlin method.
+      35             : //
+      36             : //  Licensing:
+      37             : //
+      38             : //    This code is distributed under the GNU LGPL license.
+      39             : //
+      40             : //  Modified:
+      41             : //
+      42             : //    20 October 2009
+      43             : //
+      44             : //  Author:
+      45             : //
+      46             : //    Original C++ version by Nick Hale.
+      47             : //    This C++ version by John Burkardt.
+      48             : //
+      49             : //  Reference:
+      50             : //
+      51             : //    Andreas Glaser, Xiangtao Liu, Vladimir Rokhlin,
+      52             : //    A fast algorithm for the calculation of the roots of special functions,
+      53             : //    SIAM Journal on Scientific Computing,
+      54             : //    Volume 29, Number 4, pages 1420-1438, 2007.
+      55             : //
+      56             : //  Parameters:
+      57             : //
+      58             : //    Input, int N, the order.
+      59             : //
+      60             : //    Output, double X[N], the abscissas.
+      61             : //
+      62             : //    Output, double W[N], the weights.
+      63             : //
+      64             : {
+      65             :   int i;
+      66             :   double p;
+      67             :   double pp;
+      68             :   double w_sum;
+      69             : //
+      70             : //  Get the value and derivative of the N-th Legendre polynomial at 0.
+      71             : //
+      72           2 :   legendre_compute_glr0 ( n, &p, &pp );
+      73             : //
+      74             : //  If N is odd, then zero is a root.
+      75             : //
+      76           2 :   if ( n % 2 == 1 )
+      77             :   {
+      78           2 :     x[(n-1)/2] = p;
+      79           2 :     w[(n-1)/2] = pp;
+      80             :   }
+      81             : //
+      82             : //  If N is even, we have to call a function to find the first root.
+      83             : //
+      84             :   else
+      85             :   {
+      86           0 :     legendre_compute_glr2 ( p, n, &x[n/2], &w[n/2] );
+      87             :   }
+      88             : //
+      89             : //  Get the complete set of roots and derivatives.
+      90             : //
+      91           2 :   legendre_compute_glr1 ( n, x, w );
+      92             : //
+      93             : //  Compute the W.
+      94             : //
+      95          64 :   for ( i = 0; i < n; i++ )
+      96             :   {
+      97          62 :     w[i] = 2.0 / ( 1.0 - x[i] ) / ( 1.0 + x[i] ) / w[i] / w[i];
+      98             :   }
+      99             :   w_sum = 0.0;
+     100          64 :   for ( i = 0; i < n; i++ )
+     101             :   {
+     102          62 :     w_sum = w_sum + w[i];
+     103             :   }
+     104          64 :   for ( i = 0; i < n; i++ )
+     105             :   {
+     106          62 :     w[i] = 2.0 * w[i] / w_sum;
+     107             :   }
+     108           2 :   return;
+     109             : }
+     110             : //****************************************************************************80
+     111             : 
+     112           2 : void legendre_compute_glr0 ( int n, double *p, double *pp )
+     113             : 
+     114             : //****************************************************************************80
+     115             : //
+     116             : //  Purpose:
+     117             : //
+     118             : //    LEGENDRE_COMPUTE_GLR0 gets a starting value for the fast algorithm.
+     119             : //
+     120             : //  Licensing:
+     121             : //
+     122             : //    This code is distributed under the GNU LGPL license.
+     123             : //
+     124             : //  Modified:
+     125             : //
+     126             : //    19 October 2009
+     127             : //
+     128             : //  Author:
+     129             : //
+     130             : //    Original C++ version by Nick Hale.
+     131             : //    This C++ version by John Burkardt.
+     132             : //
+     133             : //  Reference:
+     134             : //
+     135             : //    Andreas Glaser, Xiangtao Liu, Vladimir Rokhlin,
+     136             : //    A fast algorithm for the calculation of the roots of special functions,
+     137             : //    SIAM Journal on Scientific Computing,
+     138             : //    Volume 29, Number 4, pages 1420-1438, 2007.
+     139             : //
+     140             : //  Parameters:
+     141             : //
+     142             : //    Input, int N, the order of the Legendre polynomial.
+     143             : //
+     144             : //    Output, double *P, *PP, the value of the N-th Legendre polynomial
+     145             : //    and its derivative at 0.
+     146             : //
+     147             : {
+     148             :   double dk;
+     149             :   int k;
+     150             :   double pm1;
+     151             :   double pm2;
+     152             :   double ppm1;
+     153             :   double ppm2;
+     154             : 
+     155             :   pm2 = 0.0;
+     156             :   pm1 = 1.0;
+     157             :   ppm2 = 0.0;
+     158             :   ppm1 = 0.0;
+     159             : 
+     160          64 :   for ( k = 0; k < n; k++)
+     161             :   {
+     162          62 :     dk = ( double ) k;
+     163          62 :     *p = - dk * pm2 / ( dk + 1.0 );
+     164          62 :     *pp = ( ( 2.0 * dk + 1.0 ) * pm1 - dk * ppm2 ) / ( dk + 1.0 );
+     165             :     pm2 = pm1;
+     166          62 :     pm1 = *p;
+     167             :     ppm2 = ppm1;
+     168             :     ppm1 = *pp;
+     169             :   }
+     170           2 :   return;
+     171             : }
+     172             : //****************************************************************************80
+     173             : 
+     174           2 : void legendre_compute_glr1 ( int n, double *x, double *w )
+     175             : 
+     176             : //****************************************************************************80
+     177             : //
+     178             : //  Purpose:
+     179             : //
+     180             : //    LEGENDRE_COMPUTE_GLR1 gets the complete set of Legendre points and weights.
+     181             : //
+     182             : //  Discussion:
+     183             : //
+     184             : //    This routine requires that a starting estimate be provided for one
+     185             : //    root and its derivative.  This information will be stored in entry
+     186             : //    (N+1)/2 if N is odd, or N/2 if N is even, of X and W.
+     187             : //
+     188             : //  Licensing:
+     189             : //
+     190             : //    This code is distributed under the GNU LGPL license.
+     191             : //
+     192             : //  Modified:
+     193             : //
+     194             : //    19 October 2009
+     195             : //
+     196             : //  Author:
+     197             : //
+     198             : //    Original C++ version by Nick Hale.
+     199             : //    This C++ version by John Burkardt.
+     200             : //
+     201             : //  Reference:
+     202             : //
+     203             : //    Andreas Glaser, Xiangtao Liu, Vladimir Rokhlin,
+     204             : //    A fast algorithm for the calculation of the roots of special functions,
+     205             : //    SIAM Journal on Scientific Computing,
+     206             : //    Volume 29, Number 4, pages 1420-1438, 2007.
+     207             : //
+     208             : //  Parameters:
+     209             : //
+     210             : //    Input, int N, the order of the Legendre polynomial.
+     211             : //
+     212             : //    Input/output, double X[N].  On input, a starting value
+     213             : //    has been set in one entry.  On output, the roots of the Legendre
+     214             : //    polynomial.
+     215             : //
+     216             : //    Input/output, double W[N].  On input, a starting value
+     217             : //    has been set in one entry.  On output, the derivatives of the Legendre
+     218             : //    polynomial at the zeros.
+     219             : //
+     220             : //  Local Parameters:
+     221             : //
+     222             : //    Local, int M, the number of terms in the Taylor expansion.
+     223             : //
+     224             : {
+     225             :   double dk;
+     226             :   double dn;
+     227             :   double h;
+     228             :   int j;
+     229             :   int k;
+     230             :   int l;
+     231             :   int m = 30;
+     232             :   int n2;
+     233             :   static double pi = 3.141592653589793;
+     234             :   int s;
+     235             :   double *u;
+     236             :   double *up;
+     237             :   double xp;
+     238             : 
+     239           2 :   if ( n % 2 == 1 )
+     240             :   {
+     241           2 :     n2 = ( n - 1 ) / 2 - 1;
+     242             :     s = 1;
+     243             :   }
+     244             :   else
+     245             :   {
+     246           0 :     n2 = n / 2 - 1;
+     247             :     s = 0;
+     248             :   }
+     249             : 
+     250           2 :   u = new double[m+2];
+     251           2 :   up = new double[m+1];
+     252             : 
+     253           2 :   dn = ( double ) n;
+     254             : 
+     255          32 :   for ( j = n2 + 1; j < n - 1; j++ )
+     256             :   {
+     257          30 :     xp = x[j];
+     258             : 
+     259          30 :     h = rk2_leg ( pi/2.0, -pi/2.0, xp, n ) - xp;
+     260             : 
+     261          30 :     u[0] = 0.0;
+     262          30 :     u[1] = 0.0;
+     263          30 :     u[2] = w[j];
+     264             : 
+     265          30 :     up[0] = 0.0;
+     266          30 :     up[1] = u[2];
+     267             : 
+     268         900 :     for ( k = 0; k <= m - 2; k++ )
+     269             :     {
+     270         870 :       dk = ( double ) k;
+     271             : 
+     272         870 :       u[k+3] =
+     273             :         (
+     274         870 :           2.0 * xp * ( dk + 1.0 ) * u[k+2]
+     275         870 :           + ( dk * ( dk + 1.0 ) - dn * ( dn + 1.0 ) ) * u[k+1] / ( dk + 1.0 )
+     276         870 :         ) / ( 1.0 - xp ) / ( 1.0 + xp ) / ( dk + 2.0 );
+     277             : 
+     278         870 :       up[k+2] = ( dk + 2.0 ) * u[k+3];
+     279             :     }
+     280             : 
+     281         180 :     for ( l = 0; l < 5; l++ )
+     282             :     {
+     283         150 :       h = h - ts_mult ( u, h, m ) / ts_mult ( up, h, m-1 );
+     284             :     }
+     285             : 
+     286          30 :     x[j+1] = xp + h;
+     287          30 :     w[j+1] = ts_mult ( up, h, m - 1 );
+     288             :   }
+     289             : 
+     290          34 :   for ( k = 0; k <= n2 + s; k++ )
+     291             :   {
+     292          32 :     x[k] = - x[n-1-k];
+     293          32 :     w[k] = w[n-1-k];
+     294             :   }
+     295           2 :   return;
+     296             : }
+     297             : //****************************************************************************80
+     298             : 
+     299           0 : void legendre_compute_glr2 ( double pn0, int n, double *x1, double *d1 )
+     300             : 
+     301             : //****************************************************************************80
+     302             : //
+     303             : //  Purpose:
+     304             : //
+     305             : //    LEGENDRE_COMPUTE_GLR2 finds the first real root.
+     306             : //
+     307             : //  Discussion:
+     308             : //
+     309             : //    This function is only called if N is even.
+     310             : //
+     311             : //  Licensing:
+     312             : //
+     313             : //    This code is distributed under the GNU LGPL license.
+     314             : //
+     315             : //  Modified:
+     316             : //
+     317             : //    19 October 2009
+     318             : //
+     319             : //  Author:
+     320             : //
+     321             : //    Original C++ version by Nick Hale.
+     322             : //    This C++ version by John Burkardt.
+     323             : //
+     324             : //  Reference:
+     325             : //
+     326             : //    Andreas Glaser, Xiangtao Liu, Vladimir Rokhlin,
+     327             : //    A fast algorithm for the calculation of the roots of special functions,
+     328             : //    SIAM Journal on Scientific Computing,
+     329             : //    Volume 29, Number 4, pages 1420-1438, 2007.
+     330             : //
+     331             : //  Parameters:
+     332             : //
+     333             : //    Input, double PN0, the value of the N-th Legendre polynomial
+     334             : //    at 0.
+     335             : //
+     336             : //    Input, int N, the order of the Legendre polynomial.
+     337             : //
+     338             : //    Output, double *X1, the first real root.
+     339             : //
+     340             : //    Output, double *D1, the derivative at X1.
+     341             : //
+     342             : //  Local Parameters:
+     343             : //
+     344             : //    Local, int M, the number of terms in the Taylor expansion.
+     345             : //
+     346             : {
+     347             :   double dk;
+     348             :   double dn;
+     349             :   int k;
+     350             :   int l;
+     351             :   int m = 30;
+     352             :   static double pi = 3.141592653589793;
+     353             :   double t;
+     354             :   double *u;
+     355             :   double *up;
+     356             : 
+     357             :   t = 0.0;
+     358           0 :   *x1 = rk2_leg ( t, -pi/2.0, 0.0, n );
+     359             : 
+     360           0 :   u = new double[m+2];
+     361           0 :   up = new double[m+1];
+     362             : 
+     363           0 :   dn = ( double ) n;
+     364             : //
+     365             : //  U[0] and UP[0] are never used.
+     366             : //  U[M+1] is set, but not used, and UP[M] is set and not used.
+     367             : //  What gives?
+     368             : //
+     369           0 :   u[0] = 0.0;
+     370           0 :   u[1] = pn0;
+     371             : 
+     372           0 :   up[0] = 0.0;
+     373             : 
+     374           0 :   for ( k = 0; k <= m - 2; k = k + 2 )
+     375             :   {
+     376           0 :     dk = ( double ) k;
+     377             : 
+     378           0 :     u[k+2] = 0.0;
+     379           0 :     u[k+3] = ( dk * ( dk + 1.0 ) - dn * ( dn + 1.0 ) ) * u[k+1]
+     380           0 :              / (dk + 1.0) / (dk + 2.0 );
+     381             : 
+     382           0 :     up[k+1] = 0.0;
+     383           0 :     up[k+2] = ( dk + 2.0 ) * u[k+3];
+     384             :   }
+     385             : 
+     386           0 :   for ( l = 0; l < 5; l++ )
+     387             :   {
+     388           0 :     *x1 = *x1 - ts_mult ( u, *x1, m ) / ts_mult ( up, *x1, m-1 );
+     389             :   }
+     390           0 :   *d1 = ts_mult ( up, *x1, m-1 );
+     391             : 
+     392           0 :   return;
+     393             : }
+     394             : 
+     395             : //****************************************************************************80
+     396             : 
+     397           2 : void rescale ( double a, double b, int n, double x[], double w[] )
+     398             : 
+     399             : //****************************************************************************80
+     400             : //
+     401             : //  Purpose:
+     402             : //
+     403             : //    RESCALE rescales a Legendre quadrature rule from [-1,+1] to [A,B].
+     404             : //
+     405             : //  Licensing:
+     406             : //
+     407             : //    This code is distributed under the GNU LGPL license.
+     408             : //
+     409             : //  Modified:
+     410             : //
+     411             : //    18 October 2009
+     412             : //
+     413             : //  Author:
+     414             : //
+     415             : //    Original MATLAB version by Nick Hale.
+     416             : //    C++ version by John Burkardt.
+     417             : //
+     418             : //  Reference:
+     419             : //
+     420             : //    Andreas Glaser, Xiangtao Liu, Vladimir Rokhlin,
+     421             : //    A fast algorithm for the calculation of the roots of special functions,
+     422             : //    SIAM Journal on Scientific Computing,
+     423             : //    Volume 29, Number 4, pages 1420-1438, 2007.
+     424             : //
+     425             : //  Parameters:
+     426             : //
+     427             : //    Input, double A, B, the endpoints of the new interval.
+     428             : //
+     429             : //    Input, int N, the order.
+     430             : //
+     431             : //    Input/output, double X[N], on input, the abscissas for [-1,+1].
+     432             : //    On output, the abscissas for [A,B].
+     433             : //
+     434             : //    Input/output, double W[N], on input, the weights for [-1,+1].
+     435             : //    On output, the weights for [A,B].
+     436             : //
+     437             : {
+     438             :   int i;
+     439             : 
+     440          64 :   for ( i = 0; i < n; i++ )
+     441             :   {
+     442          62 :     x[i] = ( ( a + b ) + ( b - a ) * x[i] ) / 2.0;
+     443             :   }
+     444          64 :   for ( i = 0; i < n; i++ )
+     445             :   {
+     446          62 :     w[i] = ( b - a ) * w[i] / 2.0;
+     447             :   }
+     448           2 :   return;
+     449             : }
+     450             : //****************************************************************************80
+     451             : 
+     452          30 : double rk2_leg ( double t1, double t2, double x, int n )
+     453             : 
+     454             : //****************************************************************************80
+     455             : //
+     456             : //  Purpose:
+     457             : //
+     458             : //    RK2_LEG advances the value of X(T) using a Runge-Kutta method.
+     459             : //
+     460             : //  Licensing:
+     461             : //
+     462             : //    This code is distributed under the GNU LGPL license.
+     463             : //
+     464             : //  Modified:
+     465             : //
+     466             : //    22 October 2009
+     467             : //
+     468             : //  Author:
+     469             : //
+     470             : //    Original C++ version by Nick Hale.
+     471             : //    This C++ version by John Burkardt.
+     472             : //
+     473             : //  Parameters:
+     474             : //
+     475             : //    Input, double T1, T2, the range of the integration interval.
+     476             : //
+     477             : //    Input, double X, the value of X at T1.
+     478             : //
+     479             : //    Input, int N, the number of steps to take.
+     480             : //
+     481             : //    Output, double RK2_LEG, the value of X at T2.
+     482             : //
+     483             : {
+     484             :   double f;
+     485             :   double h;
+     486             :   int j;
+     487             :   double k1;
+     488             :   double k2;
+     489             :   int m = 10;
+     490             :   double snn1;
+     491             :   double t;
+     492             : 
+     493          30 :   h = ( t2 - t1 ) / ( double ) m;
+     494          30 :   snn1 = sqrt ( ( double ) ( n * ( n + 1 ) ) );
+     495             :   t = t1;
+     496             : 
+     497         330 :   for ( j = 0; j < m; j++ )
+     498             :   {
+     499         300 :     f = ( 1.0 - x ) * ( 1.0 + x );
+     500         300 :     k1 = - h * f / ( snn1 * sqrt ( f ) - 0.5 * x * sin ( 2.0 * t ) );
+     501         300 :     x = x + k1;
+     502             : 
+     503         300 :     t = t + h;
+     504             : 
+     505         300 :     f = ( 1.0 - x ) * ( 1.0 + x );
+     506         300 :     k2 = - h * f / ( snn1 * sqrt ( f ) - 0.5 * x * sin ( 2.0 * t ) );
+     507         300 :     x = x + 0.5 * ( k2 - k1 );
+     508             :   }
+     509          30 :   return x;
+     510             : }
+     511             : //****************************************************************************80
+     512             : 
+     513         330 : double ts_mult ( double *u, double h, int n )
+     514             : 
+     515             : //****************************************************************************80
+     516             : //
+     517             : //  Purpose:
+     518             : //
+     519             : //    TS_MULT evaluates a polynomial.
+     520             : //
+     521             : //  Licensing:
+     522             : //
+     523             : //    This code is distributed under the GNU LGPL license.
+     524             : //
+     525             : //  Modified:
+     526             : //
+     527             : //    17 May 2013
+     528             : //
+     529             : //  Author:
+     530             : //
+     531             : //    Original C++ version by Nick Hale.
+     532             : //    This C++ version by John Burkardt.
+     533             : //
+     534             : //  Parameters:
+     535             : //
+     536             : //    Input, double U[N+1], the polynomial coefficients.
+     537             : //    U[0] is ignored.
+     538             : //
+     539             : //    Input, double H, the polynomial argument.
+     540             : //
+     541             : //    Input, int N, the number of terms to compute.
+     542             : //
+     543             : //    Output, double TS_MULT, the value of the polynomial.
+     544             : //
+     545             : {
+     546             :   double hk;
+     547             :   int k;
+     548             :   double ts;
+     549             : 
+     550             :   ts = 0.0;
+     551             :   hk = 1.0;
+     552       10050 :   for ( k = 1; k<= n; k++ )
+     553             :   {
+     554        9720 :     ts = ts + u[k] * hk;
+     555        9720 :     hk = hk * h;
+     556             :   }
+     557         330 :   return ts;
+     558             : }
+     559             : 
+     560             : //close the namespaces
+     561             : }
+     562             : }
+     563             : 
+     564             : //#endif
+     565             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Combine.cpp.func-sort-c.html b/coverage/function/Combine.cpp.func-sort-c.html new file mode 100644 index 000000000000..66f52af519ed --- /dev/null +++ b/coverage/function/Combine.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Combine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Combine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434693.5 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7CombineC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function7CombineC1ERKNS_13ActionOptionsE140
_ZN4PLMD8function7Combine16registerKeywordsERNS_8KeywordsE142
_ZN4PLMD8function7Combine9calculateEv7959
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Combine.cpp.func.html b/coverage/function/Combine.cpp.func.html new file mode 100644 index 000000000000..442f245dd236 --- /dev/null +++ b/coverage/function/Combine.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Combine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Combine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434693.5 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7Combine16registerKeywordsERNS_8KeywordsE142
_ZN4PLMD8function7Combine9calculateEv7959
_ZN4PLMD8function7CombineC1ERKNS_13ActionOptionsE140
_ZN4PLMD8function7CombineC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Combine.cpp.gcov.html b/coverage/function/Combine.cpp.gcov.html new file mode 100644 index 000000000000..3f77914e7217 --- /dev/null +++ b/coverage/function/Combine.cpp.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - function/Combine.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Combine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434693.5 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Function.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace function {
+      27             : 
+      28             : //+PLUMEDOC FUNCTION COMBINE
+      29             : /*
+      30             : Calculate a polynomial combination of a set of other variables.
+      31             : 
+      32             : The functional form of this function is
+      33             : \f[
+      34             : C=\sum_{i=1}^{N_{arg}} c_i (x_i-a_i)^{p_i}
+      35             : \f]
+      36             : 
+      37             : The coefficients c, the parameters a and the powers p are provided as vectors.
+      38             : 
+      39             : Notice that COMBINE is not able to predict which will be periodic domain
+      40             : of the computed value automatically. The user is thus forced to specify it
+      41             : explicitly. Use PERIODIC=NO if the resulting variable is not periodic,
+      42             : and PERIODIC=A,B where A and B are the two boundaries if the resulting variable
+      43             : is periodic.
+      44             : 
+      45             : 
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : The following input tells plumed to print the distance between atoms 3 and 5
+      50             : its square (as computed from the x,y,z components) and the distance
+      51             : again as computed from the square root of the square.
+      52             : \plumedfile
+      53             : DISTANCE LABEL=dist      ATOMS=3,5 COMPONENTS
+      54             : COMBINE  LABEL=distance2 ARG=dist.x,dist.y,dist.z POWERS=2,2,2 PERIODIC=NO
+      55             : COMBINE  LABEL=distance  ARG=distance2 POWERS=0.5 PERIODIC=NO
+      56             : PRINT ARG=distance,distance2
+      57             : \endplumedfile
+      58             : (See also \ref PRINT and \ref DISTANCE).
+      59             : 
+      60             : The following input tells plumed to add a restraint on the
+      61             : cube of a dihedral angle. Notice that since the angle has a
+      62             : periodic domain
+      63             : -pi,pi its cube has a domain -pi**3,pi**3.
+      64             : \plumedfile
+      65             : t: TORSION ATOMS=1,3,5,7
+      66             : c: COMBINE ARG=t POWERS=3 PERIODIC=-31.0062766802998,31.0062766802998
+      67             : RESTRAINT ARG=c KAPPA=10 AT=0
+      68             : \endplumedfile
+      69             : 
+      70             : 
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : 
+      75             : 
+      76             : class Combine :
+      77             :   public Function
+      78             : {
+      79             :   bool normalize;
+      80             :   std::vector<double> coefficients;
+      81             :   std::vector<double> parameters;
+      82             :   std::vector<double> powers;
+      83             : public:
+      84             :   explicit Combine(const ActionOptions&);
+      85             :   void calculate() override;
+      86             :   static void registerKeywords(Keywords& keys);
+      87             : };
+      88             : 
+      89             : 
+      90             : PLUMED_REGISTER_ACTION(Combine,"COMBINE")
+      91             : 
+      92         142 : void Combine::registerKeywords(Keywords& keys) {
+      93         142 :   Function::registerKeywords(keys);
+      94         284 :   keys.use("ARG"); keys.use("PERIODIC");
+      95         284 :   keys.add("compulsory","COEFFICIENTS","1.0","the coefficients of the arguments in your function");
+      96         284 :   keys.add("compulsory","PARAMETERS","0.0","the parameters of the arguments in your function");
+      97         284 :   keys.add("compulsory","POWERS","1.0","the powers to which you are raising each of the arguments in your function");
+      98         284 :   keys.addFlag("NORMALIZE",false,"normalize all the coefficients so that in total they are equal to one");
+      99         142 : }
+     100             : 
+     101         140 : Combine::Combine(const ActionOptions&ao):
+     102             :   Action(ao),
+     103             :   Function(ao),
+     104         140 :   normalize(false),
+     105         283 :   coefficients(getNumberOfArguments(),1.0),
+     106         143 :   parameters(getNumberOfArguments(),0.0),
+     107         283 :   powers(getNumberOfArguments(),1.0)
+     108             : {
+     109         279 :   parseVector("COEFFICIENTS",coefficients);
+     110         139 :   if(coefficients.size()!=static_cast<unsigned>(getNumberOfArguments()))
+     111           0 :     error("Size of COEFFICIENTS array should be the same as number for arguments");
+     112             : 
+     113         277 :   parseVector("PARAMETERS",parameters);
+     114         138 :   if(parameters.size()!=static_cast<unsigned>(getNumberOfArguments()))
+     115           0 :     error("Size of PARAMETERS array should be the same as number for arguments");
+     116             : 
+     117         275 :   parseVector("POWERS",powers);
+     118         137 :   if(powers.size()!=static_cast<unsigned>(getNumberOfArguments()))
+     119           0 :     error("Size of POWERS array should be the same as number for arguments");
+     120             : 
+     121         140 :   parseFlag("NORMALIZE",normalize);
+     122             : 
+     123         137 :   if(normalize) {
+     124             :     double n=0.0;
+     125          16 :     for(unsigned i=0; i<coefficients.size(); i++) n+=coefficients[i];
+     126          16 :     for(unsigned i=0; i<coefficients.size(); i++) coefficients[i]*=(1.0/n);
+     127             :   }
+     128             : 
+     129         137 :   addValueWithDerivatives();
+     130         137 :   checkRead();
+     131             : 
+     132         137 :   log.printf("  with coefficients:");
+     133         410 :   for(unsigned i=0; i<coefficients.size(); i++) log.printf(" %f",coefficients[i]);
+     134         137 :   log.printf("\n");
+     135         137 :   log.printf("  with parameters:");
+     136         410 :   for(unsigned i=0; i<parameters.size(); i++) log.printf(" %f",parameters[i]);
+     137         137 :   log.printf("\n");
+     138         137 :   log.printf("  and powers:");
+     139         410 :   for(unsigned i=0; i<powers.size(); i++) log.printf(" %f",powers[i]);
+     140         137 :   log.printf("\n");
+     141         143 : }
+     142             : 
+     143        7959 : void Combine::calculate() {
+     144        7959 :   double combine=0.0;
+     145       20386 :   for(unsigned i=0; i<coefficients.size(); ++i) {
+     146       12427 :     double cv = (getArgument(i)-parameters[i]);
+     147       12427 :     combine+=coefficients[i]*std::pow(cv,powers[i]);
+     148       12427 :     setDerivative(i,coefficients[i]*powers[i]*std::pow(cv,powers[i]-1.0));
+     149             :   };
+     150        7959 :   setValue(combine);
+     151        7959 : }
+     152             : 
+     153             : }
+     154             : }
+     155             : 
+     156             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Custom.cpp.func-sort-c.html b/coverage/function/Custom.cpp.func-sort-c.html new file mode 100644 index 000000000000..28951683971b --- /dev/null +++ b/coverage/function/Custom.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Custom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:565994.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6CustomC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function6CustomC1ERKNS_13ActionOptionsE434
_ZN4PLMD8function6Custom16registerKeywordsERNS_8KeywordsE438
_ZN4PLMD8function6Custom9calculateEv39154
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Custom.cpp.func.html b/coverage/function/Custom.cpp.func.html new file mode 100644 index 000000000000..7bab1edcb00d --- /dev/null +++ b/coverage/function/Custom.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Custom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:565994.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6Custom16registerKeywordsERNS_8KeywordsE438
_ZN4PLMD8function6Custom9calculateEv39154
_ZN4PLMD8function6CustomC1ERKNS_13ActionOptionsE434
_ZN4PLMD8function6CustomC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Custom.cpp.gcov.html b/coverage/function/Custom.cpp.gcov.html new file mode 100644 index 000000000000..bd4b47bab054 --- /dev/null +++ b/coverage/function/Custom.cpp.gcov.html @@ -0,0 +1,375 @@ + + + + + + + + LCOV - plumed test coverage - function/Custom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:565994.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "Function.h"
+      24             : #include "lepton/Lepton.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace function {
+      28             : 
+      29             : //+PLUMEDOC FUNCTION CUSTOM
+      30             : /*
+      31             : Calculate a combination of variables using a custom expression.
+      32             : 
+      33             : This action computes an  arbitrary function of one or more
+      34             : collective variables. Arguments are chosen with the ARG keyword,
+      35             : and the function is provided with the FUNC string. Notice that this
+      36             : string should contain no space. Within FUNC, one can refer to the
+      37             : arguments as x,y,z, and t (up to four variables provided as ARG).
+      38             : This names can be customized using the VAR keyword (see examples below).
+      39             : 
+      40             : This function is implemented using the Lepton library, that allows to evaluate
+      41             : algebraic expressions and to automatically differentiate them.
+      42             : 
+      43             : If you want a function that depends not only on collective variables
+      44             : but also on time you can use the \subpage TIME action.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : The following input tells plumed to perform a metadynamics
+      49             : using as a CV the difference between two distances.
+      50             : \plumedfile
+      51             : dAB: DISTANCE ATOMS=10,12
+      52             : dAC: DISTANCE ATOMS=10,15
+      53             : diff: CUSTOM ARG=dAB,dAC FUNC=y-x PERIODIC=NO
+      54             : # notice: the previous line could be replaced with the following
+      55             : # diff: COMBINE ARG=dAB,dAC COEFFICIENTS=-1,1
+      56             : METAD ARG=diff SIGMA=0.1 HEIGHT=0.5 BIASFACTOR=10 PACE=100
+      57             : \endplumedfile
+      58             : (see also \ref DISTANCE, \ref COMBINE, and \ref METAD).
+      59             : Notice that forces applied to diff will be correctly propagated
+      60             : to atoms 10, 12, and 15.
+      61             : Also notice that since CUSTOM is used without the VAR option
+      62             : the two arguments should be referred to as x and y in the expression FUNC.
+      63             : For simple functions
+      64             : such as this one it is possible to use \ref COMBINE.
+      65             : 
+      66             : The following input tells plumed to print the angle between vectors
+      67             : identified by atoms 1,2 and atoms 2,3
+      68             : its square (as computed from the x,y,z components) and the distance
+      69             : again as computed from the square root of the square.
+      70             : \plumedfile
+      71             : DISTANCE LABEL=d1 ATOMS=1,2 COMPONENTS
+      72             : DISTANCE LABEL=d2 ATOMS=2,3 COMPONENTS
+      73             : CUSTOM ...
+      74             :   LABEL=theta
+      75             :   ARG=d1.x,d1.y,d1.z,d2.x,d2.y,d2.z
+      76             :   VAR=ax,ay,az,bx,by,bz
+      77             :   FUNC=acos((ax*bx+ay*by+az*bz)/sqrt((ax*ax+ay*ay+az*az)*(bx*bx+by*by+bz*bz)))
+      78             :   PERIODIC=NO
+      79             : ... CUSTOM
+      80             : PRINT ARG=theta
+      81             : \endplumedfile
+      82             : (See also \ref PRINT and \ref DISTANCE).
+      83             : 
+      84             : Notice that this action implements a large number of functions (trigonometric, exp, log, etc).
+      85             : Among the useful functions, have a look at the step function (that is the Heaviside function).
+      86             : `step(x)` is defined as 1 when `x` is positive and `0` when x is negative. This allows for
+      87             : a straightforward implementation of if clauses.
+      88             : 
+      89             : For example, imagine that you want to implement a restraint that only acts when a
+      90             : distance is larger than 0.5. You can do it with
+      91             : \plumedfile
+      92             : d: DISTANCE ATOMS=10,15
+      93             : m: CUSTOM ARG=d FUNC=0.5*step(0.5-x)+x*step(x-0.5) PERIODIC=NO
+      94             : # check the function you are applying:
+      95             : PRINT ARG=d,m FILE=checkme
+      96             : RESTRAINT ARG=d AT=0.5 KAPPA=10.0
+      97             : \endplumedfile
+      98             : (see also \ref DISTANCE, \ref PRINT, and \ref RESTRAINT)
+      99             : 
+     100             : The meaning of the function `0.5*step(0.5-x)+x*step(x-0.5)` is:
+     101             : - If x<0.5 (step(0.5-x)!=0) use 0.5
+     102             : - If x>0.5 (step(x-0.5)!=0) use x
+     103             : Notice that the same could have been obtained using an \ref UPPER_WALLS
+     104             : However, with CUSTOM you can create way more complex definitions.
+     105             : 
+     106             : \warning If you apply forces on the variable (as in the previous example) you should
+     107             : make sure that the variable is continuous!
+     108             : Conversely, if you are just analyzing a trajectory you can safely use
+     109             : discontinuous variables.
+     110             : 
+     111             : A possible continuity check with gnuplot is
+     112             : \verbatim
+     113             : # this allow to step function to be used in gnuplot:
+     114             : gnuplot> step(x)=0.5*(erf(x*10000000)+1)
+     115             : # here you can test your function
+     116             : gnuplot> p 0.5*step(0.5-x)+x*step(x-0.5)
+     117             : \endverbatim
+     118             : 
+     119             : Also notice that you can easily make logical operations on the conditions that you
+     120             : create. The equivalent of the AND operator is the product: `step(1.0-x)*step(x-0.5)` is
+     121             : only equal to 1 when x is between 0.5 and 1.0. By combining negation and AND you can obtain an OR. That is,
+     122             : `1-step(1.0-x)*step(x-0.5)` is only equal to 1 when x is outside the 0.5-1.0 interval.
+     123             : 
+     124             : CUSTOM can be used in combination with \ref DISTANCE to implement variants of the
+     125             : DISTANCE keyword that were present in PLUMED 1.3 and that allowed to compute
+     126             : the distance of a point from a line defined by two other points, or the progression
+     127             : along that line.
+     128             : \plumedfile
+     129             : # take center of atoms 1 to 10 as reference point 1
+     130             : p1: CENTER ATOMS=1-10
+     131             : # take center of atoms 11 to 20 as reference point 2
+     132             : p2: CENTER ATOMS=11-20
+     133             : # take center of atoms 21 to 30 as reference point 3
+     134             : p3: CENTER ATOMS=21-30
+     135             : 
+     136             : # compute distances
+     137             : d12: DISTANCE ATOMS=p1,p2
+     138             : d13: DISTANCE ATOMS=p1,p3
+     139             : d23: DISTANCE ATOMS=p2,p3
+     140             : 
+     141             : # compute progress variable of the projection of point p3
+     142             : # along the vector joining p1 and p2
+     143             : # notice that progress is measured from the middle point
+     144             : onaxis: CUSTOM ARG=d13,d23,d12 FUNC=(0.5*(y^2-x^2)/z) PERIODIC=NO
+     145             : 
+     146             : # compute between point p3 and the vector joining p1 and p2
+     147             : fromaxis: CUSTOM ARG=d13,d23,d12,onaxis VAR=x,y,z,o FUNC=(0.5*(y^2+x^2)-o^2-0.25*z^2) PERIODIC=NO
+     148             : 
+     149             : PRINT ARG=onaxis,fromaxis
+     150             : 
+     151             : \endplumedfile
+     152             : 
+     153             : Notice that these equations have been used to combine \ref RMSD
+     154             : from different snapshots of a protein so as to define
+     155             : progression (S) and distance (Z) variables \cite perez2015atp.
+     156             : 
+     157             : 
+     158             : */
+     159             : //+ENDPLUMEDOC
+     160             : 
+     161             : 
+     162             : class Custom :
+     163             :   public Function
+     164             : {
+     165             :   lepton::CompiledExpression expression;
+     166             :   std::vector<lepton::CompiledExpression> expression_deriv;
+     167             :   std::vector<std::string> var;
+     168             :   std::string func;
+     169             :   std::vector<double> values;
+     170             :   std::vector<char*> names;
+     171             :   std::vector<double*> lepton_ref;
+     172             :   std::vector<double*> lepton_ref_deriv;
+     173             : public:
+     174             :   explicit Custom(const ActionOptions&);
+     175             :   void calculate() override;
+     176             :   static void registerKeywords(Keywords& keys);
+     177             : };
+     178             : 
+     179             : PLUMED_REGISTER_ACTION(Custom,"CUSTOM")
+     180             : 
+     181             : //+PLUMEDOC FUNCTION MATHEVAL
+     182             : /*
+     183             : An alias to the \ref CUSTOM function.
+     184             : 
+     185             : This alias is kept in order to maintain compatibility with previous PLUMED versions.
+     186             : However, notice that as of PLUMED 2.5 the libmatheval library is not linked anymore,
+     187             : and the \ref MATHEVAL function is implemented using the Lepton library.
+     188             : 
+     189             : \par Examples
+     190             : 
+     191             : Just replace \ref CUSTOM with \ref MATHEVAL.
+     192             : 
+     193             : \plumedfile
+     194             : d: DISTANCE ATOMS=10,15
+     195             : m: MATHEVAL ARG=d FUNC=0.5*step(0.5-x)+x*step(x-0.5) PERIODIC=NO
+     196             : # check the function you are applying:
+     197             : PRINT ARG=d,m FILE=checkme
+     198             : RESTRAINT ARG=d AT=0.5 KAPPA=10.0
+     199             : \endplumedfile
+     200             : (see also \ref DISTANCE, \ref PRINT, and \ref RESTRAINT)
+     201             : 
+     202             : */
+     203             : //+ENDPLUMEDOC
+     204             : 
+     205             : class Matheval :
+     206             :   public Custom {
+     207             : };
+     208             : 
+     209             : PLUMED_REGISTER_ACTION(Custom,"MATHEVAL")
+     210             : 
+     211         438 : void Custom::registerKeywords(Keywords& keys) {
+     212         438 :   Function::registerKeywords(keys);
+     213         876 :   keys.use("ARG"); keys.use("PERIODIC");
+     214         876 :   keys.add("compulsory","FUNC","the function you wish to evaluate");
+     215         876 :   keys.add("optional","VAR","the names to give each of the arguments in the function.  If you have up to three arguments in your function you can use x, y and z to refer to them.  Otherwise you must use this flag to give your variables names.");
+     216         438 : }
+     217             : 
+     218         434 : Custom::Custom(const ActionOptions&ao):
+     219             :   Action(ao),
+     220             :   Function(ao),
+     221         434 :   expression_deriv(getNumberOfArguments()),
+     222         434 :   values(getNumberOfArguments()),
+     223         434 :   names(getNumberOfArguments()),
+     224         434 :   lepton_ref(getNumberOfArguments(),nullptr),
+     225        1302 :   lepton_ref_deriv(getNumberOfArguments()*getNumberOfArguments(),nullptr)
+     226             : {
+     227         868 :   parseVector("VAR",var);
+     228         434 :   if(var.size()==0) {
+     229         421 :     var.resize(getNumberOfArguments());
+     230         421 :     if(getNumberOfArguments()>3)
+     231           0 :       error("Using more than 3 arguments you should explicitly write their names with VAR");
+     232         421 :     if(var.size()>0) var[0]="x";
+     233         421 :     if(var.size()>1) var[1]="y";
+     234         421 :     if(var.size()>2) var[2]="z";
+     235             :   }
+     236         434 :   if(var.size()!=getNumberOfArguments())
+     237           0 :     error("Size of VAR array should be the same as number of arguments");
+     238         434 :   parse("FUNC",func);
+     239         434 :   addValueWithDerivatives();
+     240         434 :   checkRead();
+     241             : 
+     242         434 :   log.printf("  with function : %s\n",func.c_str());
+     243         434 :   log.printf("  with variables :");
+     244         968 :   for(unsigned i=0; i<var.size(); i++) log.printf(" %s",var[i].c_str());
+     245         434 :   log.printf("\n");
+     246             : 
+     247         434 :   lepton::ParsedExpression pe=lepton::Parser::parse(func).optimize(lepton::Constants());
+     248         434 :   log<<"  function as parsed by lepton: "<<pe<<"\n";
+     249         434 :   expression=pe.createCompiledExpression();
+     250         942 :   for(auto &p: expression.getVariables()) {
+     251         508 :     if(std::find(var.begin(),var.end(),p)==var.end()) {
+     252           0 :       error("variable " + p + " is not defined");
+     253             :     }
+     254             :   }
+     255         434 :   log<<"  derivatives as computed by lepton:\n";
+     256         968 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     257        1068 :     lepton::ParsedExpression pe=lepton::Parser::parse(func).differentiate(var[i]).optimize(lepton::Constants());
+     258         534 :     log<<"    "<<pe<<"\n";
+     259         534 :     expression_deriv[i]=pe.createCompiledExpression();
+     260             :   }
+     261             : 
+     262         968 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     263             :     try {
+     264         534 :       lepton_ref[i]=&expression.getVariableReference(var[i]);
+     265          26 :     } catch(const PLMD::lepton::Exception& exc) {
+     266             : // this is necessary since in some cases lepton things a variable is not present even though it is present
+     267             : // e.g. func=0*x
+     268          26 :     }
+     269             :   }
+     270         968 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     271        1526 :     for(unsigned j=0; j<getNumberOfArguments(); j++) {
+     272             :       try {
+     273         992 :         lepton_ref_deriv[i*getNumberOfArguments()+j]=&expression_deriv[i].getVariableReference(var[j]);
+     274         513 :       } catch(const PLMD::lepton::Exception& exc) {
+     275             : // this is necessary since in some cases lepton things a variable is not present even though it is present
+     276             : // e.g. func=0*x
+     277         513 :       }
+     278             :     }
+     279             :   }
+     280         434 : }
+     281             : 
+     282       39154 : void Custom::calculate() {
+     283       78949 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     284       39795 :     if(lepton_ref[i]) *lepton_ref[i]=getArgument(i);
+     285             :   }
+     286       39154 :   setValue(expression.evaluate());
+     287       78949 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     288       82348 :     for(unsigned j=0; j<getNumberOfArguments(); j++) {
+     289       42553 :       if(lepton_ref_deriv[i*getNumberOfArguments()+j]) *lepton_ref_deriv[i*getNumberOfArguments()+j]=getArgument(j);
+     290             :     }
+     291       39795 :     setDerivative(i,expression_deriv[i].evaluate());
+     292             :   }
+     293       39154 : }
+     294             : 
+     295             : }
+     296             : }
+     297             : 
+     298             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Ensemble.cpp.func-sort-c.html b/coverage/function/Ensemble.cpp.func-sort-c.html new file mode 100644 index 000000000000..e9e875f13ee4 --- /dev/null +++ b/coverage/function/Ensemble.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Ensemble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Ensemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8012763.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8EnsembleC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function8EnsembleC1ERKNS_13ActionOptionsE27
_ZN4PLMD8function8Ensemble16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD8function8Ensemble9calculateEv125
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Ensemble.cpp.func.html b/coverage/function/Ensemble.cpp.func.html new file mode 100644 index 000000000000..55d8209ebd45 --- /dev/null +++ b/coverage/function/Ensemble.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Ensemble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Ensemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8012763.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Ensemble16registerKeywordsERNS_8KeywordsE29
_ZN4PLMD8function8Ensemble9calculateEv125
_ZN4PLMD8function8EnsembleC1ERKNS_13ActionOptionsE27
_ZN4PLMD8function8EnsembleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Ensemble.cpp.gcov.html b/coverage/function/Ensemble.cpp.gcov.html new file mode 100644 index 000000000000..fd5035a5a42a --- /dev/null +++ b/coverage/function/Ensemble.cpp.gcov.html @@ -0,0 +1,340 @@ + + + + + + + + LCOV - plumed test coverage - function/Ensemble.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Ensemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8012763.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Function.h"
+      23             : #include "tools/Communicator.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace function {
+      29             : 
+      30             : //+PLUMEDOC FUNCTION ENSEMBLE
+      31             : /*
+      32             : Calculates the replica averaging of a collective variable over multiple replicas.
+      33             : 
+      34             : Each collective variable is averaged separately and stored in a component labelled <em>label</em>.cvlabel.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The following input tells plumed to calculate the distance between atoms 3 and 5
+      39             : and the average it over the available replicas.
+      40             : \plumedfile
+      41             : dist: DISTANCE ATOMS=3,5
+      42             : ens: ENSEMBLE ARG=dist
+      43             : PRINT ARG=dist,ens.dist
+      44             : \endplumedfile
+      45             : 
+      46             : */
+      47             : //+ENDPLUMEDOC
+      48             : 
+      49             : 
+      50             : class Ensemble :
+      51             :   public Function
+      52             : {
+      53             :   unsigned ens_dim;
+      54             :   unsigned my_repl;
+      55             :   unsigned narg;
+      56             :   bool     master;
+      57             :   bool     do_reweight;
+      58             :   bool     do_moments;
+      59             :   bool     do_central;
+      60             :   bool     do_powers;
+      61             :   double   kbt;
+      62             :   double   moment;
+      63             :   double   power;
+      64             : public:
+      65             :   explicit Ensemble(const ActionOptions&);
+      66             :   void     calculate() override;
+      67             :   static void registerKeywords(Keywords& keys);
+      68             : };
+      69             : 
+      70             : 
+      71             : PLUMED_REGISTER_ACTION(Ensemble,"ENSEMBLE")
+      72             : 
+      73          29 : void Ensemble::registerKeywords(Keywords& keys) {
+      74          29 :   Function::registerKeywords(keys);
+      75          29 :   keys.use("ARG");
+      76          58 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the latest ARG as energy");
+      77          58 :   keys.addFlag("CENTRAL",false,"calculate a central moment instead of a standard moment");
+      78          58 :   keys.add("optional","TEMP","the system temperature - this is only needed if you are reweighting");
+      79          58 :   keys.add("optional","MOMENT","the moment you want to calculate in alternative to the mean or the variance");
+      80          58 :   keys.add("optional","POWER","the power of the mean (and moment)");
+      81          29 :   ActionWithValue::useCustomisableComponents(keys);
+      82          29 : }
+      83             : 
+      84          27 : Ensemble::Ensemble(const ActionOptions&ao):
+      85             :   Action(ao),
+      86             :   Function(ao),
+      87          27 :   do_reweight(false),
+      88          27 :   do_moments(false),
+      89          27 :   do_central(false),
+      90          27 :   do_powers(false),
+      91          27 :   kbt(-1.0),
+      92          27 :   moment(0),
+      93          27 :   power(0)
+      94             : {
+      95          27 :   parseFlag("REWEIGHT", do_reweight);
+      96          27 :   if(do_reweight) {
+      97          12 :     kbt=getkBT();
+      98          12 :     if(kbt==0.0) error("Unless the MD engine passes the temperature to plumed, with REWEIGHT you must specify TEMP");
+      99          30 :   } else { double temp=0.0; parse("TEMP",temp); }
+     100             : 
+     101          27 :   parse("MOMENT",moment);
+     102          27 :   if(moment==1) error("MOMENT can be any number but for 0 and 1");
+     103          27 :   if(moment!=0) do_moments=true;
+     104          27 :   parseFlag("CENTRAL", do_central);
+     105          27 :   if(!do_moments&&do_central) error("To calculate a CENTRAL moment you need to define for which MOMENT");
+     106             : 
+     107          27 :   parse("POWER",power);
+     108          27 :   if(power==1) error("POWER can be any number but for 0 and 1");
+     109          27 :   if(power!=0) do_powers=true;
+     110             : 
+     111          27 :   checkRead();
+     112             : 
+     113          27 :   master = (comm.Get_rank()==0);
+     114          27 :   ens_dim=0;
+     115          27 :   my_repl=0;
+     116          27 :   if(master) {
+     117          17 :     ens_dim=multi_sim_comm.Get_size();
+     118          17 :     my_repl=multi_sim_comm.Get_rank();
+     119             :   }
+     120          27 :   comm.Bcast(ens_dim,0);
+     121          27 :   comm.Bcast(my_repl,0);
+     122          27 :   if(ens_dim<2) log.printf("WARNING: ENSEMBLE with one replica is not doing any averaging!\n");
+     123             : 
+     124             :   // prepare output components, the number depending on reweighing or not
+     125          27 :   narg = getNumberOfArguments();
+     126          27 :   if(do_reweight) narg--;
+     127             : 
+     128             :   // these are the averages
+     129        3044 :   for(unsigned i=0; i<narg; i++) {
+     130        3017 :     std::string s=getPntrToArgument(i)->getName();
+     131        3017 :     addComponentWithDerivatives(s);
+     132        3017 :     getPntrToComponent(i)->setNotPeriodic();
+     133             :   }
+     134             :   // these are the moments
+     135          27 :   if(do_moments) {
+     136           0 :     for(unsigned i=0; i<narg; i++) {
+     137           0 :       std::string s=getPntrToArgument(i)->getName()+"_m";
+     138           0 :       addComponentWithDerivatives(s);
+     139           0 :       getPntrToComponent(i+narg)->setNotPeriodic();
+     140             :     }
+     141             :   }
+     142             : 
+     143          27 :   log.printf("  averaging over %u replicas.\n", ens_dim);
+     144          27 :   if(do_reweight) log.printf("  doing simple REWEIGHT using the latest ARGUMENT as energy.\n");
+     145          27 :   if(do_moments&&!do_central)  log.printf("  calculating also the %lf standard moment\n", moment);
+     146          27 :   if(do_moments&&do_central)   log.printf("  calculating also the %lf central moment\n", moment);
+     147          27 :   if(do_powers)                log.printf("  calculating the %lf power of the mean (and moment)\n", power);
+     148          27 : }
+     149             : 
+     150         125 : void Ensemble::calculate() {
+     151             :   double norm = 0.0;
+     152         125 :   double fact = 0.0;
+     153             : 
+     154             :   // calculate the weights either from BIAS
+     155         125 :   if(do_reweight) {
+     156             :     std::vector<double> bias;
+     157           0 :     bias.resize(ens_dim);
+     158           0 :     if(master) {
+     159           0 :       bias[my_repl] = getArgument(narg);
+     160           0 :       if(ens_dim>1) multi_sim_comm.Sum(&bias[0], ens_dim);
+     161             :     }
+     162           0 :     comm.Sum(&bias[0], ens_dim);
+     163           0 :     const double maxbias = *(std::max_element(bias.begin(), bias.end()));
+     164           0 :     for(unsigned i=0; i<ens_dim; ++i) {
+     165           0 :       bias[i] = exp((bias[i]-maxbias)/kbt);
+     166           0 :       norm += bias[i];
+     167             :     }
+     168           0 :     fact = bias[my_repl]/norm;
+     169             :     // or arithmetic ones
+     170             :   } else {
+     171         125 :     norm = static_cast<double>(ens_dim);
+     172         125 :     fact = 1.0/norm;
+     173             :   }
+     174             : 
+     175         125 :   const double fact_kbt = fact/kbt;
+     176             : 
+     177         125 :   std::vector<double> mean(narg);
+     178         125 :   std::vector<double> dmean(narg,fact);
+     179             :   // calculate the mean
+     180         125 :   if(master) {
+     181        2106 :     for(unsigned i=0; i<narg; ++i) mean[i] = fact*getArgument(i);
+     182          99 :     if(ens_dim>1) multi_sim_comm.Sum(&mean[0], narg);
+     183             :   }
+     184         125 :   comm.Sum(&mean[0], narg);
+     185             : 
+     186             :   std::vector<double> v_moment, dv_moment;
+     187             :   // calculate other moments
+     188         125 :   if(do_moments) {
+     189           0 :     v_moment.resize(narg);
+     190           0 :     dv_moment.resize(narg);
+     191             :     // standard moment
+     192           0 :     if(!do_central) {
+     193           0 :       if(master) {
+     194           0 :         for(unsigned i=0; i<narg; ++i) {
+     195           0 :           const double tmp = fact*std::pow(getArgument(i),moment-1);
+     196           0 :           v_moment[i]      = tmp*getArgument(i);
+     197           0 :           dv_moment[i]     = moment*tmp;
+     198             :         }
+     199           0 :         if(ens_dim>1) multi_sim_comm.Sum(&v_moment[0], narg);
+     200             :       } else {
+     201           0 :         for(unsigned i=0; i<narg; ++i) {
+     202           0 :           const double tmp = fact*std::pow(getArgument(i),moment-1);
+     203           0 :           dv_moment[i]     = moment*tmp;
+     204             :         }
+     205             :       }
+     206             :       // central moment
+     207             :     } else {
+     208           0 :       if(master) {
+     209           0 :         for(unsigned i=0; i<narg; ++i) {
+     210           0 :           const double tmp = std::pow(getArgument(i)-mean[i],moment-1);
+     211           0 :           v_moment[i]      = fact*tmp*(getArgument(i)-mean[i]);
+     212           0 :           dv_moment[i]     = moment*tmp*(fact-fact/norm);
+     213             :         }
+     214           0 :         if(ens_dim>1) multi_sim_comm.Sum(&v_moment[0], narg);
+     215             :       } else {
+     216           0 :         for(unsigned i=0; i<narg; ++i) {
+     217           0 :           const double tmp = std::pow(getArgument(i)-mean[i],moment-1);
+     218           0 :           dv_moment[i]     = moment*tmp*(fact-fact/norm);
+     219             :         }
+     220             :       }
+     221             :     }
+     222           0 :     comm.Sum(&v_moment[0], narg);
+     223             :   }
+     224             : 
+     225             :   // calculate powers of moments
+     226         125 :   if(do_powers) {
+     227          72 :     for(unsigned i=0; i<narg; ++i) {
+     228          48 :       const double tmp1 = std::pow(mean[i],power-1);
+     229          48 :       mean[i]          *= tmp1;
+     230          48 :       dmean[i]         *= power*tmp1;
+     231          48 :       if(do_moments) {
+     232           0 :         const double tmp2 = std::pow(v_moment[i],power-1);
+     233           0 :         v_moment[i]      *= tmp2;
+     234           0 :         dv_moment[i]     *= power*tmp2;
+     235             :       }
+     236             :     }
+     237             :   }
+     238             : 
+     239             :   // set components
+     240        3358 :   for(unsigned i=0; i<narg; ++i) {
+     241             :     // set mean
+     242        3233 :     Value* v=getPntrToComponent(i);
+     243        3233 :     v->set(mean[i]);
+     244        3233 :     setDerivative(v, i, dmean[i]);
+     245        3233 :     if(do_reweight) {
+     246           0 :       const double w_tmp = fact_kbt*(getArgument(i) - mean[i]);
+     247           0 :       setDerivative(v, narg, w_tmp);
+     248             :     }
+     249        3233 :     if(do_moments) {
+     250             :       // set moments
+     251           0 :       Value* u=getPntrToComponent(i+narg);
+     252           0 :       u->set(v_moment[i]);
+     253           0 :       setDerivative(u, i, dv_moment[i]);
+     254           0 :       if(do_reweight) {
+     255           0 :         const double w_tmp = fact_kbt*(pow(getArgument(i),moment) - v_moment[i]);
+     256           0 :         setDerivative(u, narg, w_tmp);
+     257             :       }
+     258             :     }
+     259             :   }
+     260         125 : }
+     261             : 
+     262             : }
+     263             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathGeneral.cpp.func-sort-c.html b/coverage/function/FuncPathGeneral.cpp.func-sort-c.html new file mode 100644 index 000000000000..b11ec2a4b96c --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncPathGeneral.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathGeneral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10012977.5 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function15FuncPathGeneralC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function15FuncPathGeneral13loadReferenceEv1
_ZN4PLMD8function15FuncPathGeneralC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function15FuncPathGeneral16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function15FuncPathGeneral7prepareEv175001
_ZN4PLMD8function15FuncPathGeneral9calculateEv175001
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathGeneral.cpp.func.html b/coverage/function/FuncPathGeneral.cpp.func.html new file mode 100644 index 000000000000..e46da50e62f4 --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncPathGeneral.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathGeneral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10012977.5 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function15FuncPathGeneral13loadReferenceEv1
_ZN4PLMD8function15FuncPathGeneral16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD8function15FuncPathGeneral7prepareEv175001
_ZN4PLMD8function15FuncPathGeneral9calculateEv175001
_ZN4PLMD8function15FuncPathGeneralC1ERKNS_13ActionOptionsE1
_ZN4PLMD8function15FuncPathGeneralC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathGeneral.cpp.gcov.html b/coverage/function/FuncPathGeneral.cpp.gcov.html new file mode 100644 index 000000000000..d2008ac533d7 --- /dev/null +++ b/coverage/function/FuncPathGeneral.cpp.gcov.html @@ -0,0 +1,418 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncPathGeneral.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathGeneral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10012977.5 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Function.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/IFile.h"
+      26             : #include <limits>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace function {
+      30             : 
+      31             : //+PLUMEDOC FUNCTION FUNCPATHGENERAL
+      32             : /*
+      33             : This function calculates path collective variables (PCVs) using an arbitrary combination of collective variables.
+      34             : 
+      35             : The method used to calculate the PCVs that is used in this method is described in \cite Hovan2019.
+      36             : 
+      37             : This variable computes the progress along a given set of frames that is provided in an input file ("s" component) and the distance from them ("z" component).
+      38             : The input file could be a colvar file generated with plumed driver on a trajectory containing the frames.
+      39             : 
+      40             : The metric for the path collective variables takes the following form:
+      41             : 
+      42             : \f[
+      43             : R[X - X_i] = \sum_{j=1}^M c_j^2 (x_j - x_{i,j})^2\,.
+      44             : \f]
+      45             : 
+      46             : Here, the coefficients \f$c_j\f$ determine the relative weights of the collective variables \f$c_j\f$ in the metric.
+      47             : A value for the lambda coefficient also needs to be provided, typically chosen in such a way that it ensures a smooth variation of the "s" component.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : This command calculates the PCVs using the values from the file COLVAR_TRAJ and the provided values for the lambda and the coefficients.
+      52             : Since the columns in the file were not specified, the first one will be ignored (assumed to correspond to the time) and the rest used.
+      53             : 
+      54             : \plumedfile
+      55             : FUNCPATHGENERAL ...
+      56             : LABEL=path
+      57             : LAMBDA=12.2
+      58             : REFERENCE=COLVAR_TRAJ
+      59             : COEFFICIENTS=0.3536,0.3536,0.3536,0.3536,0.7071
+      60             : ARG=d1,d2,d,t,drmsd
+      61             : ... FUNCPATHGENERAL
+      62             : \endplumedfile
+      63             : 
+      64             : The command below is a variation of the previous one, specifying a subset of the collective variables and using a neighbor list.
+      65             : The columns are zero-indexed.
+      66             : The neighbor list will include the 10 closest frames and will be recalculated every 20 steps.
+      67             : 
+      68             : \plumedfile
+      69             : FUNCPATHGENERAL ...
+      70             : LABEL=path
+      71             : LAMBDA=5.0
+      72             : REFERENCE=COLVAR_TRAJ
+      73             : COLUMNS=2,3,4
+      74             : COEFFICIENTS=0.3536,0.3536,0.3536
+      75             : ARG=d2,d,t
+      76             : NEIGH_SIZE=10
+      77             : NEIGH_STRIDE=20
+      78             : ... FUNCPATHGENERAL
+      79             : \endplumedfile
+      80             : 
+      81             : */
+      82             : //+ENDPLUMEDOC
+      83             : 
+      84             : class FuncPathGeneral : public Function {
+      85             :   double lambda;
+      86             :   int neigh_size;
+      87             :   double neigh_stride;
+      88             : 
+      89             :   std::vector<double> coefficients;
+      90             :   std::vector< std::vector<double> > path_cv_values;
+      91             : 
+      92             :   // For faster calculation
+      93             :   std::vector<double> expdists;
+      94             : 
+      95             :   // For calculating derivatives
+      96             :   std::vector< std::vector<double> > numerators;
+      97             :   std::vector<double> s_path_ders;
+      98             :   std::vector<double> z_path_ders;
+      99             : 
+     100             :   // For handling periodicity
+     101             :   std::vector<double> domains;
+     102             : 
+     103             :   std::string reference;
+     104             :   std::vector<int> columns;
+     105             : 
+     106             :   std::vector< std::pair<int,double> > neighpair;
+     107             :   std::vector <Value*> allArguments;
+     108             : 
+     109             :   // Methods
+     110             :   void loadReference();
+     111             : 
+     112             :   struct pairordering {
+     113             :     bool operator ()(std::pair<int, double> const& a, std::pair<int, double> const& b) {
+     114           0 :       return (a).second < (b).second;
+     115             :     }
+     116             :   };
+     117             : 
+     118             : public:
+     119             :   explicit FuncPathGeneral(const ActionOptions&);
+     120             : // Active methods:
+     121             :   virtual void calculate();
+     122             :   virtual void prepare();
+     123             :   static void registerKeywords(Keywords& keys);
+     124             : };
+     125             : 
+     126             : PLUMED_REGISTER_ACTION(FuncPathGeneral, "FUNCPATHGENERAL")
+     127             : 
+     128           1 : void FuncPathGeneral::loadReference() {
+     129           1 :   IFile input;
+     130           1 :   input.open(reference);
+     131           1 :   if (!input)
+     132           0 :     plumed_merror("Could not open the reference file!");
+     133          18 :   while (input)
+     134             :   {
+     135             :     std::vector<std::string> strings;
+     136          17 :     Tools::getParsedLine(input, strings);
+     137          17 :     if (strings.empty())
+     138             :       continue;
+     139             :     std::vector<double> colvarLine;
+     140             :     double value;
+     141          16 :     int max = columns.empty() ? strings.size() : columns.size();
+     142         128 :     for (int i = 0; i < max; ++i)
+     143             :     {
+     144         112 :       int col = columns.empty() ? i : columns[i];
+     145             :       // If no columns have been entered, ignore the first (time) and take the rest
+     146         112 :       if (columns.empty() && i == 0)
+     147          16 :         continue;
+     148             : 
+     149          96 :       Tools::convert(strings[col], value);
+     150          96 :       colvarLine.push_back(value);
+     151             :     }
+     152          16 :     path_cv_values.push_back(colvarLine);
+     153          17 :   }
+     154           1 : }
+     155             : 
+     156           3 : void FuncPathGeneral::registerKeywords(Keywords& keys) {
+     157           3 :   Function::registerKeywords(keys);
+     158           3 :   keys.use("ARG");
+     159           6 :   keys.add("compulsory", "LAMBDA", "Lambda parameter required for smoothing");
+     160           6 :   keys.add("compulsory", "COEFFICIENTS", "Coefficients to be assigned to the CVs");
+     161           6 :   keys.add("compulsory", "REFERENCE", "Colvar file needed to provide the CV milestones");
+     162           6 :   keys.add("optional", "COLUMNS", "List of columns in the reference colvar file specifying the CVs");
+     163           6 :   keys.add("optional", "NEIGH_SIZE", "Size of the neighbor list");
+     164           6 :   keys.add("optional", "NEIGH_STRIDE", "How often the neighbor list needs to be calculated in time units");
+     165           3 :   componentsAreNotOptional(keys);
+     166           6 :   keys.addOutputComponent("s", "default", "Position on the path");
+     167           6 :   keys.addOutputComponent("z", "default", "Distance from the path");
+     168           3 : }
+     169             : 
+     170           1 : FuncPathGeneral::FuncPathGeneral(const ActionOptions&ao):
+     171             :   Action(ao),
+     172             :   Function(ao),
+     173           1 :   neigh_size(-1),
+     174           1 :   neigh_stride(-1.)
+     175             : {
+     176           1 :   parse("LAMBDA", lambda);
+     177           1 :   parse("NEIGH_SIZE", neigh_size);
+     178           1 :   parse("NEIGH_STRIDE", neigh_stride);
+     179           1 :   parse("REFERENCE", reference);
+     180           1 :   parseVector("COEFFICIENTS", coefficients);
+     181           1 :   parseVector("COLUMNS", columns);
+     182           1 :   checkRead();
+     183           1 :   log.printf("  lambda is %f\n", lambda);
+     184           1 :   if (getNumberOfArguments() != coefficients.size())
+     185           0 :     plumed_merror("The numbers of coefficients and CVs are different!");
+     186           1 :   if (!columns.empty()) {
+     187           0 :     if (columns.size() != coefficients.size())
+     188           0 :       plumed_merror("The numbers of coefficients and columns are different!");
+     189             :   }
+     190           1 :   log.printf("  Consistency check completed! Your path cvs look good!\n");
+     191             : 
+     192             :   // Load the reference colvar file
+     193           1 :   loadReference();
+     194             : 
+     195             :   // Do some neighbour printout
+     196           1 :   if (neigh_stride > 0. || neigh_size > 0) {
+     197           0 :     if (static_cast<unsigned>(neigh_size) > path_cv_values.size()) {
+     198           0 :       log.printf(" List size required ( %d ) is too large: resizing to the maximum number of arg required: %d  \n", neigh_size, getNumberOfArguments());
+     199           0 :       neigh_size = path_cv_values.size();
+     200             :     }
+     201           0 :     log.printf("  Neighbour list enabled: \n");
+     202           0 :     log.printf("                 size   :  %d elements\n", neigh_size);
+     203           0 :     log.printf("                 stride :  %f time \n", neigh_stride);
+     204             :   } else {
+     205           1 :     log.printf("  Neighbour list NOT enabled \n");
+     206             :   }
+     207             : 
+     208           2 :   addComponentWithDerivatives("s"); componentIsNotPeriodic("s");
+     209           3 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+     210             : 
+     211             :   // Initialise vectors
+     212           1 :   std::vector<double> temp (coefficients.size());
+     213          17 :   for (unsigned i = 0; i < path_cv_values.size(); ++i) {
+     214          16 :     numerators.push_back(temp);
+     215          16 :     expdists.push_back(0.);
+     216          16 :     s_path_ders.push_back(0.);
+     217          16 :     z_path_ders.push_back(0.);
+     218             :   }
+     219             : 
+     220             :   // Store the arguments
+     221           7 :   for (unsigned i=0; i<getNumberOfArguments(); i++)
+     222           6 :     allArguments.push_back(getPntrToArgument(i));
+     223             : 
+     224             :   // Get periodic domains, negative for not periodic, stores half the domain length (maximum difference)
+     225           7 :   for (unsigned i = 0; i < allArguments.size(); ++i) {
+     226           6 :     if (allArguments[i]->isPeriodic()) {
+     227             :       double min_lim, max_lim;
+     228           0 :       allArguments[i]->getDomain(min_lim, max_lim);
+     229           0 :       domains.push_back((max_lim - min_lim) / 2);
+     230             :     }
+     231             :     else
+     232           6 :       domains.push_back(-1.);
+     233             :   }
+     234           1 : }
+     235             : 
+     236             : // Calculator
+     237      175001 : void FuncPathGeneral::calculate() {
+     238             :   double s_path = 0.;
+     239             :   double partition = 0.;
+     240             :   double tmp, value, diff, expdist, s_der, z_der;
+     241             :   int ii;
+     242             : 
+     243             :   typedef std::vector< std::pair< int,double> >::iterator pairiter;
+     244             : 
+     245     2975001 :   for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     246     2800000 :     (*it).second = 0.;
+     247             :   }
+     248             : 
+     249      175001 :   if (neighpair.empty()) {
+     250             :     // Resize at the first step
+     251           1 :     neighpair.resize(path_cv_values.size());
+     252          17 :     for (unsigned i = 0; i < path_cv_values.size(); ++i)
+     253          16 :       neighpair[i].first = i;
+     254             :   }
+     255             : 
+     256      175001 :   Value* val_s_path=getPntrToComponent("s");
+     257      175001 :   Value* val_z_path=getPntrToComponent("z");
+     258             : 
+     259     1225007 :   for(unsigned j = 0; j < allArguments.size(); ++j) {
+     260     1050006 :     value = allArguments[j]->get();
+     261    17850102 :     for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     262    16800096 :       diff = (value - path_cv_values[(*it).first][j]);
+     263    16800096 :       if (domains[j] > 0) {
+     264           0 :         if (diff > domains[j])
+     265           0 :           diff -= 2 * domains[j];
+     266           0 :         if (diff < -domains[j])
+     267           0 :           diff += 2 * domains[j];
+     268             :       }
+     269    33600192 :       (*it).second += Tools::fastpow(coefficients[j] * diff, 2);
+     270    33600192 :       numerators[(*it).first][j] = 2 * Tools::fastpow(coefficients[j], 2) * diff;
+     271             :     }
+     272             :   }
+     273             : 
+     274     2975017 :   for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     275     2800016 :     expdist = std::exp(-lambda * (*it).second);
+     276     2800016 :     expdists[(*it).first] = expdist;
+     277     2800016 :     s_path += ((*it).first + 1) * expdist;
+     278     2800016 :     partition += expdist;
+     279             :   }
+     280             : 
+     281      175001 :   if(partition==0.0) partition=std::numeric_limits<double>::min();
+     282             : 
+     283      175001 :   s_path /= partition;
+     284             :   val_s_path->set(s_path);
+     285      175001 :   val_z_path->set(-(1. / lambda) * std::log(partition));
+     286             : 
+     287             :   // Derivatives
+     288     2975017 :   for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     289     2800016 :     ii = (*it).first;
+     290     2800016 :     tmp = lambda * expdists[ii] * (s_path - (ii + 1)) / partition;
+     291     2800016 :     s_path_ders[ii] = tmp;
+     292     2800016 :     z_path_ders[ii] = expdists[ii] / partition;
+     293             :   }
+     294     1225007 :   for (unsigned i = 0; i < coefficients.size(); ++i) {
+     295             :     s_der = 0.;
+     296             :     z_der = 0.;
+     297    17850102 :     for (pairiter it = neighpair.begin(); it != neighpair.end(); ++it) {
+     298    16800096 :       ii = (*it).first;
+     299    16800096 :       s_der += s_path_ders[ii] * numerators[ii][i];
+     300    16800096 :       z_der += z_path_ders[ii] * numerators[ii][i];
+     301             :     }
+     302             :     setDerivative(val_s_path, i, s_der);
+     303             :     setDerivative(val_z_path, i, z_der);
+     304             :   }
+     305      175001 : }
+     306             : 
+     307             : // Prepare the required arguments
+     308      175001 : void FuncPathGeneral::prepare() {
+     309             :   // Neighbour list: rank and activate the chain for the next step
+     310             : 
+     311             :   // Neighbour list: if neigh_size < 0 never sort and keep the full vector
+     312             :   // Neighbour list: if neigh_size > 0
+     313             :   //                 if the size is full -> sort the vector and decide the dependencies for next step
+     314             :   //                 if the size is not full -> check if next step will need the full dependency otherwise keep these dependencies
+     315             : 
+     316      175001 :   if (neigh_size > 0) {
+     317           0 :     if (neighpair.size() == path_cv_values.size()) {
+     318             :       // The complete round has been done: need to sort, shorten and give it a go
+     319             :       // Sort the values
+     320           0 :       std::sort(neighpair.begin(), neighpair.end(), pairordering());
+     321             :       // Resize the effective list
+     322           0 :       neighpair.resize(neigh_size);
+     323           0 :       log.printf("  NEIGHBOUR LIST NOW INCLUDES INDICES: ");
+     324           0 :       for (int i = 0; i < neigh_size; ++i)
+     325           0 :         log.printf(" %i ",neighpair[i].first);
+     326           0 :       log.printf(" \n");
+     327             :     } else {
+     328           0 :       if (int(getStep()) % int(neigh_stride / getTimeStep()) == 0) {
+     329           0 :         log.printf(" Time %f : recalculating full neighbour list \n", getStep() * getTimeStep());
+     330           0 :         neighpair.resize(path_cv_values.size());
+     331           0 :         for (unsigned i = 0; i < path_cv_values.size(); ++i)
+     332           0 :           neighpair[i].first = i;
+     333             :       }
+     334             :     }
+     335             :   }
+     336             : 
+     337      175001 :   requestArguments(allArguments);
+     338      175001 : }
+     339             : 
+     340             : }
+     341             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathMSD.cpp.func-sort-c.html b/coverage/function/FuncPathMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..9bc37c5e4966 --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncPathMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:748092.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function11FuncPathMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function11FuncPathMSDC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function11FuncPathMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function11FuncPathMSD7prepareEv1092
_ZN4PLMD8function11FuncPathMSD9calculateEv1092
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathMSD.cpp.func.html b/coverage/function/FuncPathMSD.cpp.func.html new file mode 100644 index 000000000000..8d7b873bd1ea --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncPathMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:748092.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function11FuncPathMSD16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function11FuncPathMSD7prepareEv1092
_ZN4PLMD8function11FuncPathMSD9calculateEv1092
_ZN4PLMD8function11FuncPathMSDC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function11FuncPathMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncPathMSD.cpp.gcov.html b/coverage/function/FuncPathMSD.cpp.gcov.html new file mode 100644 index 000000000000..ea68b85c0400 --- /dev/null +++ b/coverage/function/FuncPathMSD.cpp.gcov.html @@ -0,0 +1,445 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncPathMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncPathMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:748092.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Function.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace function {
+      28             : 
+      29             : //+PLUMEDOC FUNCTION FUNCPATHMSD
+      30             : /*
+      31             : This function calculates path collective variables.
+      32             : 
+      33             : This is the Path Collective Variables implementation
+      34             : ( see \cite brand07 ).
+      35             : This variable computes the progress along a given set of frames that is provided
+      36             : in input ("s" component) and the distance from them ("z" component).
+      37             : It is a function of mean squared displacement that are obtained by the joint use of mean squared displacement variables with the SQUARED flag
+      38             : (see below).
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : Here below is a case where you have defined three frames and you want to
+      43             : calculate the progress along the path and the distance from it in p1
+      44             : 
+      45             : \plumedfile
+      46             : t1: RMSD REFERENCE=frame_1.pdb TYPE=OPTIMAL SQUARED
+      47             : t2: RMSD REFERENCE=frame_21.pdb TYPE=OPTIMAL SQUARED
+      48             : t3: RMSD REFERENCE=frame_42.pdb TYPE=OPTIMAL SQUARED
+      49             : p1: FUNCPATHMSD ARG=t1,t2,t3 LAMBDA=500.0
+      50             : PRINT ARG=t1,t2,t3,p1.s,p1.z STRIDE=1 FILE=colvar FMT=%8.4f
+      51             : \endplumedfile
+      52             : 
+      53             : For this input you would then define the position of the reference coordinates in three separate pdb files.  The contents of the
+      54             : file frame_1.pdb are shown below:
+      55             : 
+      56             : \auxfile{frame_1.pdb}
+      57             : ATOM      1  CL  ALA     1      -3.171   0.295   2.045  1.00  1.00
+      58             : ATOM      5  CLP ALA     1      -1.819  -0.143   1.679  1.00  1.00
+      59             : ATOM      6  OL  ALA     1      -1.177  -0.889   2.401  1.00  1.00
+      60             : ATOM      7  NL  ALA     1      -1.313   0.341   0.529  1.00  1.00
+      61             : ATOM      8  HL  ALA     1      -1.845   0.961  -0.011  1.00  1.00
+      62             : END
+      63             : \endauxfile
+      64             : 
+      65             : This is then frame.21.pdb:
+      66             : 
+      67             : \auxfile{frame_21.pdb}
+      68             : ATOM      1  CL  ALA     1      -3.089   1.850   1.546  1.00  1.00
+      69             : ATOM      5  CLP ALA     1      -1.667   1.457   1.629  1.00  1.00
+      70             : ATOM      6  OL  ALA     1      -0.974   1.868   2.533  1.00  1.00
+      71             : ATOM      7  NL  ALA     1      -1.204   0.683   0.642  1.00  1.00
+      72             : ATOM      8  HL  ALA     1      -1.844   0.360  -0.021  1.00  1.00
+      73             : END
+      74             : \endauxfile
+      75             : 
+      76             : and finally this is frame_42.pdb:
+      77             : 
+      78             : \auxfile{frame_42.pdb}
+      79             : ATOM      1  CL  ALA     1      -3.257   1.605   1.105  1.00  1.00
+      80             : ATOM      5  CLP ALA     1      -1.941   1.459   0.447  1.00  1.00
+      81             : ATOM      6  OL  ALA     1      -1.481   2.369  -0.223  1.00  1.00
+      82             : ATOM      7  NL  ALA     1      -1.303   0.291   0.647  1.00  1.00
+      83             : ATOM      8  HL  ALA     1      -1.743  -0.379   1.229  1.00  1.00
+      84             : END
+      85             : \endauxfile
+      86             : 
+      87             : This second example shows how to define a PATH in \ref CONTACTMAP space:
+      88             : 
+      89             : \plumedfile
+      90             : CONTACTMAP ...
+      91             : ATOMS1=1,2 REFERENCE1=0.1
+      92             : ATOMS2=3,4 REFERENCE2=0.5
+      93             : ATOMS3=4,5 REFERENCE3=0.25
+      94             : ATOMS4=5,6 REFERENCE4=0.0
+      95             : SWITCH={RATIONAL R_0=1.5}
+      96             : LABEL=c1
+      97             : CMDIST
+      98             : ... CONTACTMAP
+      99             : 
+     100             : CONTACTMAP ...
+     101             : ATOMS1=1,2 REFERENCE1=0.3
+     102             : ATOMS2=3,4 REFERENCE2=0.9
+     103             : ATOMS3=4,5 REFERENCE3=0.45
+     104             : ATOMS4=5,6 REFERENCE4=0.1
+     105             : SWITCH={RATIONAL R_0=1.5}
+     106             : LABEL=c2
+     107             : CMDIST
+     108             : ... CONTACTMAP
+     109             : 
+     110             : CONTACTMAP ...
+     111             : ATOMS1=1,2 REFERENCE1=1.0
+     112             : ATOMS2=3,4 REFERENCE2=1.0
+     113             : ATOMS3=4,5 REFERENCE3=1.0
+     114             : ATOMS4=5,6 REFERENCE4=1.0
+     115             : SWITCH={RATIONAL R_0=1.5}
+     116             : LABEL=c3
+     117             : CMDIST
+     118             : ... CONTACTMAP
+     119             : 
+     120             : p1: FUNCPATHMSD ARG=c1,c2,c3 LAMBDA=500.0
+     121             : PRINT ARG=c1,c2,c3,p1.s,p1.z STRIDE=1 FILE=colvar FMT=%8.4f
+     122             : \endplumedfile
+     123             : 
+     124             : This third example shows how to define a PATH in \ref PIV space:
+     125             : 
+     126             : \plumedfile
+     127             : PIV ...
+     128             : LABEL=c1
+     129             : PRECISION=1000
+     130             : NLIST
+     131             : REF_FILE=Ref1.pdb
+     132             : PIVATOMS=2
+     133             : ATOMTYPES=A,B
+     134             : ONLYDIRECT
+     135             : SFACTOR=1.0,0.2
+     136             : SORT=1,1
+     137             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     138             : SWITCH2={RATIONAL R_0=0.5 MM=10 NN=5}
+     139             : NL_CUTOFF=1.2,1.2
+     140             : NL_STRIDE=10,10
+     141             : NL_SKIN=0.1,0.1
+     142             : ... PIV
+     143             : PIV ...
+     144             : LABEL=c2
+     145             : PRECISION=1000
+     146             : NLIST
+     147             : REF_FILE=Ref2.pdb
+     148             : PIVATOMS=2
+     149             : ATOMTYPES=A,B
+     150             : ONLYDIRECT
+     151             : SFACTOR=1.0,0.2
+     152             : SORT=1,1
+     153             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     154             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+     155             : NL_CUTOFF=1.2,1.2
+     156             : NL_STRIDE=10,10
+     157             : NL_SKIN=0.1,0.1
+     158             : ... PIV
+     159             : 
+     160             : p1: FUNCPATHMSD ARG=c1,c2 LAMBDA=0.180338
+     161             : METAD ARG=p1.s,p1.z SIGMA=0.01,0.2 HEIGHT=0.8 PACE=500   LABEL=res
+     162             : PRINT ARG=c1,c2,p1.s,p1.z,res.bias STRIDE=500  FILE=colvar FMT=%15.6f
+     163             : \endplumedfile
+     164             : 
+     165             : */
+     166             : //+ENDPLUMEDOC
+     167             : 
+     168             : class FuncPathMSD : public Function {
+     169             :   double lambda;
+     170             :   int neigh_size;
+     171             :   double neigh_stride;
+     172             :   std::vector< std::pair<Value *,double> > neighpair;
+     173             :   std::map<Value *,double > indexmap; // use double to allow isomaps
+     174             :   std::vector <Value*> allArguments;
+     175             : // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+     176             : // this below is useful when one wants to sort a vector of double and have back the order
+     177             : // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+     178             : // create a custom sorter
+     179             :   typedef std::vector<double>::const_iterator myiter;
+     180             :   struct ordering {
+     181             :     bool operator ()(std::pair<unsigned, myiter> const& a, std::pair<unsigned, myiter> const& b) {
+     182             :       return *(a.second) < *(b.second);
+     183             :     }
+     184             :   };
+     185             : // sorting utility
+     186             :   std::vector<int> increasingOrder( std::vector<double> &v) {
+     187             :     // make a pair
+     188             :     std::vector< std::pair<unsigned, myiter> > order(v.size());
+     189             :     unsigned n = 0;
+     190             :     for (myiter it = v.begin(); it != v.end(); ++it, ++n) {
+     191             :       order[n] = make_pair(n, it); // note: heere i do not put the values but the addresses that point to the value
+     192             :     }
+     193             :     // now sort according the second value
+     194             :     std::sort(order.begin(), order.end(), ordering());
+     195             :     std::vector<int> vv(v.size()); n=0;
+     196             :     for (const auto & it : order) {
+     197             :       vv[n]=it.first; n++;
+     198             :     }
+     199             :     return vv;
+     200             :   }
+     201             : // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+     202             : // XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
+     203             : 
+     204             :   struct pairordering {
+     205             :     bool operator ()(std::pair<Value *, double> const& a, std::pair<Value*, double> const& b) {
+     206         437 :       return (a).second > (b).second;
+     207             :     }
+     208             :   };
+     209             : 
+     210             : public:
+     211             :   explicit FuncPathMSD(const ActionOptions&);
+     212             : // active methods:
+     213             :   void calculate() override;
+     214             :   void prepare() override;
+     215             :   static void registerKeywords(Keywords& keys);
+     216             : };
+     217             : 
+     218             : PLUMED_REGISTER_ACTION(FuncPathMSD,"FUNCPATHMSD")
+     219             : 
+     220           4 : void FuncPathMSD::registerKeywords(Keywords& keys) {
+     221           4 :   Function::registerKeywords(keys);
+     222           4 :   keys.use("ARG");
+     223           8 :   keys.add("compulsory","LAMBDA","the lambda parameter is needed for smoothing, is in the units of plumed");
+     224           8 :   keys.add("optional","NEIGH_SIZE","size of the neighbor list");
+     225           8 :   keys.add("optional","NEIGH_STRIDE","how often the neighbor list needs to be calculated in time units");
+     226           4 :   componentsAreNotOptional(keys);
+     227           8 :   keys.addOutputComponent("s","default","the position on the path");
+     228           8 :   keys.addOutputComponent("z","default","the distance from the path");
+     229           4 : }
+     230           2 : FuncPathMSD::FuncPathMSD(const ActionOptions&ao):
+     231             :   Action(ao),
+     232             :   Function(ao),
+     233           2 :   neigh_size(-1),
+     234           2 :   neigh_stride(-1.)
+     235             : {
+     236             : 
+     237           2 :   parse("LAMBDA",lambda);
+     238           2 :   parse("NEIGH_SIZE",neigh_size);
+     239           2 :   parse("NEIGH_STRIDE",neigh_stride);
+     240           2 :   checkRead();
+     241           2 :   log.printf("  lambda is %f\n",lambda);
+     242             :   // list the action involved and check the type
+     243           2 :   std::string myname=getPntrToArgument(0)->getPntrToAction()->getName();
+     244           2 :   if(myname!="RMSD"&&myname!="CONTACTMAP"&&myname!="DISTANCE"&&myname!="PIV") error("One or more of your arguments is not of RMSD/CONTACTMAP/DISTANCE/PIV type!!!");
+     245           6 :   for(unsigned i=1; i<getNumberOfArguments(); i++) {
+     246             :     // for each value get the name and the label of the corresponding action
+     247           4 :     if( getPntrToArgument(i)->getPntrToAction()->getName()!=myname ) error("mismatch between the types of arguments");
+     248             :   }
+     249           2 :   log.printf("  Consistency check completed! Your path cvs look good!\n");
+     250             :   // do some neighbor printout
+     251           2 :   if(neigh_stride>0. || neigh_size>0) {
+     252           1 :     if(neigh_size>static_cast<int>(getNumberOfArguments())) {
+     253           0 :       log.printf(" List size required ( %d ) is too large: resizing to the maximum number of arg required: %d  \n",neigh_size,getNumberOfArguments());
+     254           0 :       neigh_size=getNumberOfArguments();
+     255             :     }
+     256           1 :     log.printf("  Neighbor list enabled: \n");
+     257           1 :     log.printf("                size   :  %d elements\n",neigh_size);
+     258           1 :     log.printf("                stride :  %f time \n",neigh_stride);
+     259             :   } else {
+     260           1 :     log.printf("  Neighbor list NOT enabled \n");
+     261             :   }
+     262             : 
+     263           4 :   addComponentWithDerivatives("s"); componentIsNotPeriodic("s");
+     264           4 :   addComponentWithDerivatives("z"); componentIsNotPeriodic("z");
+     265             : 
+     266             :   // now backup the arguments
+     267           8 :   for(unsigned i=0; i<getNumberOfArguments(); i++)allArguments.push_back(getPntrToArgument(i));
+     268             :   double i=1.;
+     269           8 :   for(const auto & it : allArguments) {
+     270           6 :     indexmap[it]=i; i+=1.;
+     271             :   }
+     272             : 
+     273           2 : }
+     274             : // calculator
+     275        1092 : void FuncPathMSD::calculate() {
+     276             : // log.printf("NOW CALCULATE! \n");
+     277             :   double s_path=0.;
+     278             :   double partition=0.;
+     279        1092 :   if(neighpair.empty()) { // at first step, resize it
+     280           0 :     neighpair.resize(allArguments.size());
+     281           0 :     for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     282             :   }
+     283             : 
+     284        1092 :   Value* val_s_path=getPntrToComponent("s");
+     285        2184 :   Value* val_z_path=getPntrToComponent("z");
+     286             : 
+     287        3959 :   for(auto & it : neighpair) {
+     288        2867 :     it.second=std::exp(-lambda*(it.first->get()));
+     289        2867 :     s_path+=(indexmap[it.first])*it.second;
+     290        2867 :     partition+=it.second;
+     291             :   }
+     292        1092 :   s_path/=partition;
+     293             :   val_s_path->set(s_path);
+     294        1092 :   val_z_path->set(-(1./lambda)*std::log(partition));
+     295             :   int n=0;
+     296        3959 :   for(const auto & it : neighpair) {
+     297        2867 :     double expval=it.second;
+     298        2867 :     double tmp=lambda*expval*(s_path-(indexmap[it.first]))/partition;
+     299             :     setDerivative(val_s_path,n,tmp);
+     300        2867 :     setDerivative(val_z_path,n,expval/partition);
+     301        2867 :     n++;
+     302             :   }
+     303             : 
+     304             : //  log.printf("CALCULATION DONE! \n");
+     305        1092 : }
+     306             : ///
+     307             : /// this function updates the needed argument list
+     308             : ///
+     309        1092 : void FuncPathMSD::prepare() {
+     310             : 
+     311             :   // neighbor list: rank and activate the chain for the next step
+     312             : 
+     313             :   // neighbor list: if neigh_size<0 never sort and keep the full vector
+     314             :   // neighbor list: if neigh_size>0
+     315             :   //                if the size is full -> sort the vector and decide the dependencies for next step
+     316             :   //                if the size is not full -> check if next step will need the full dependency otherwise keep this dependencies
+     317             : 
+     318             :   // here just resize the neighpair. The real resizing of reinit will be done by the prepare stage that will modify the  list of arguments
+     319        1092 :   if (neigh_size>0) {
+     320         546 :     if(neighpair.size()==allArguments.size()) { // I just did the complete round: need to sort, shorten and give it a go
+     321             :       // sort the values
+     322         137 :       std::sort(neighpair.begin(),neighpair.end(),pairordering());
+     323             :       // resize the effective list
+     324         137 :       neighpair.resize(neigh_size);
+     325         137 :       log.printf("  NEIGH LIST NOW INCLUDE INDEXES: ");
+     326         411 :       for(int i=0; i<neigh_size; ++i) {log.printf(" %f ",indexmap[neighpair[i].first]);} log.printf(" \n");
+     327             :     } else {
+     328         409 :       if( int(getStep())%int(neigh_stride/getTimeStep())==0 ) {
+     329         137 :         log.printf(" Time %f : recalculating full neighlist \n",getStep()*getTimeStep());
+     330         137 :         neighpair.resize(allArguments.size());
+     331         548 :         for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     332             :       }
+     333             :     }
+     334             :   } else {
+     335         546 :     if( int(getStep())==0) {
+     336           1 :       neighpair.resize(allArguments.size());
+     337           4 :       for(unsigned i=0; i<allArguments.size(); i++)neighpair[i].first=allArguments[i];
+     338             :     }
+     339             :   }
+     340             :   std::vector<Value*> argstocall;
+     341             : //log.printf("PREPARING \n");
+     342             :   argstocall.clear();
+     343        1092 :   if(!neighpair.empty()) {
+     344        3959 :     for(const auto & it : neighpair) {
+     345        2867 :       argstocall.push_back( it.first );
+     346             :       //     log.printf("CALLING %p %f ",(*it).first ,indexmap[(*it).first] );
+     347             :     }
+     348             :   } else {
+     349           0 :     for(unsigned i=0; i<allArguments.size(); i++) {
+     350           0 :       argstocall.push_back(allArguments[i]);
+     351             :     }
+     352             :   }
+     353             : // now the list of argument changes
+     354        1092 :   requestArguments(argstocall);
+     355             : //now resize the derivatives as well
+     356             : //for each value in this action
+     357        3276 :   for(int i=0; i< getNumberOfComponents(); i++) {
+     358             :     //resize the derivative to the number   the
+     359        2184 :     getPntrToComponent(i)->clearDerivatives();
+     360        2184 :     getPntrToComponent(i)->resizeDerivatives(getNumberOfArguments());
+     361             :   }
+     362             : //log.printf("PREPARING DONE! \n");
+     363        1092 : }
+     364             : 
+     365             : }
+     366             : }
+     367             : 
+     368             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncSumHills.cpp.func-sort-c.html b/coverage/function/FuncSumHills.cpp.func-sort-c.html new file mode 100644 index 000000000000..66458a12efeb --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncSumHills.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncSumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29232589.8 %
Date:2024-02-22 21:58:45Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12FuncSumHills9calculateEv0
_ZN4PLMD8function12FuncSumHillsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function12FilesHandler12getMinMaxBinERKSt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESD_RS2_IjSaIjEERKSC_1
_ZN4PLMD8function12FilesHandler12getMinMaxBinERKSt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESD_RS2_IjSaIjEE4
_ZN4PLMD8function12FuncSumHills21checkFilesAreExistingERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE9
_ZN4PLMD8function12FuncSumHillsC1ERKNS_13ActionOptionsE9
_ZN4PLMD8function12FuncSumHills16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD8function12FilesHandlerC2ERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKbRNS_6ActionERNS_3LogE14
_ZN4PLMD8function12FilesHandler9readBunchEPNS_18BiasRepresentationEi15
_ZN4PLMD8function5mylogEd900
_ZN4PLMD8function8mylogderEd1800
_ZN4PLMD8function12FilesHandler11scanOneHillEPNS_18BiasRepresentationEPNS_5IFileE5578
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncSumHills.cpp.func.html b/coverage/function/FuncSumHills.cpp.func.html new file mode 100644 index 000000000000..5844c7758df8 --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncSumHills.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncSumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29232589.8 %
Date:2024-02-22 21:58:45Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function12FilesHandler11scanOneHillEPNS_18BiasRepresentationEPNS_5IFileE5578
_ZN4PLMD8function12FilesHandler12getMinMaxBinERKSt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESD_RS2_IjSaIjEE4
_ZN4PLMD8function12FilesHandler12getMinMaxBinERKSt6vectorIPNS_5ValueESaIS4_EERNS_12CommunicatorERS2_IdSaIdEESD_RS2_IjSaIjEERKSC_1
_ZN4PLMD8function12FilesHandler9readBunchEPNS_18BiasRepresentationEi15
_ZN4PLMD8function12FilesHandlerC2ERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKbRNS_6ActionERNS_3LogE14
_ZN4PLMD8function12FuncSumHills16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD8function12FuncSumHills21checkFilesAreExistingERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE9
_ZN4PLMD8function12FuncSumHills9calculateEv0
_ZN4PLMD8function12FuncSumHillsC1ERKNS_13ActionOptionsE9
_ZN4PLMD8function12FuncSumHillsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function5mylogEd900
_ZN4PLMD8function8mylogderEd1800
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/FuncSumHills.cpp.gcov.html b/coverage/function/FuncSumHills.cpp.gcov.html new file mode 100644 index 000000000000..0cbbe35e4257 --- /dev/null +++ b/coverage/function/FuncSumHills.cpp.gcov.html @@ -0,0 +1,715 @@ + + + + + + + + LCOV - plumed test coverage - function/FuncSumHills.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - FuncSumHills.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:29232589.8 %
Date:2024-02-22 21:58:45Functions:101283.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "Function.h"
+      24             : #include "tools/Exception.h"
+      25             : #include "tools/Communicator.h"
+      26             : #include "tools/BiasRepresentation.h"
+      27             : #include "tools/KernelFunctions.h"
+      28             : #include "tools/File.h"
+      29             : #include "tools/Tools.h"
+      30             : #include "tools/Stopwatch.h"
+      31             : #include "tools/Grid.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace function {
+      35             : 
+      36             : 
+      37             : //+PLUMEDOC FUNCTION FUNCSUMHILLS
+      38             : /*
+      39             : This function is intended to be called by the command line tool sum_hills.  It is meant to integrate a HILLS file or an HILLS file interpreted as a histogram in a variety of ways. It is, therefore, not expected that you use this during your dynamics (it will crash!)
+      40             : 
+      41             : In the future one could implement periodic integration during the metadynamics
+      42             : or straightforward MD as a tool to check convergence
+      43             : 
+      44             : \par Examples
+      45             : 
+      46             : There are currently no examples for this keyword.
+      47             : 
+      48             : */
+      49             : //+ENDPLUMEDOC
+      50             : 
+      51          14 : class FilesHandler {
+      52             :   std::vector <std::string> filenames;
+      53             :   std::vector <std::unique_ptr<IFile>>  ifiles;
+      54             :   Action *action;
+      55             :   Log *log;
+      56             :   bool parallelread;
+      57             :   unsigned beingread;
+      58             :   bool isopen;
+      59             : public:
+      60             :   FilesHandler(const std::vector<std::string> &filenames, const bool &parallelread,  Action &myaction, Log &mylog);
+      61             :   bool readBunch(BiasRepresentation *br, int stride);
+      62             :   bool scanOneHill(BiasRepresentation *br, IFile *ifile );
+      63             :   void getMinMaxBin(const std::vector<Value*> & vals, Communicator &cc, std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin);
+      64             :   void getMinMaxBin(const std::vector<Value*> & vals, Communicator &cc, std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin, const std::vector<double> &histosigma);
+      65             : };
+      66          14 : FilesHandler::FilesHandler(const std::vector<std::string> &filenames, const bool &parallelread, Action &action, Log &mylog ):filenames(filenames),log(&mylog),parallelread(parallelread),beingread(0),isopen(false) {
+      67          14 :   this->action=&action;
+      68          29 :   for(unsigned i=0; i<filenames.size(); i++) {
+      69             :     auto ifile=Tools::make_unique<IFile>();
+      70          15 :     ifile->link(action);
+      71          15 :     plumed_massert((ifile->FileExist(filenames[i])), "the file "+filenames[i]+" does not exist " );
+      72          15 :     ifiles.emplace_back(std::move(ifile));
+      73          15 :   }
+      74             : 
+      75          14 : }
+      76             : 
+      77             : // note that the FileHandler is completely transparent respect to the biasrepresentation
+      78             : // no check are made at this level
+      79          15 : bool FilesHandler::readBunch(BiasRepresentation *br, int stride = -1) {
+      80             :   bool morefiles; morefiles=true;
+      81          15 :   if(parallelread) {
+      82           0 :     (*log)<<"  doing parallelread \n";
+      83           0 :     plumed_merror("parallelread is not yet implemented !!!");
+      84             :   } else {
+      85          15 :     (*log)<<"  doing serialread \n";
+      86             :     // read one by one hills
+      87             :     // is the type defined? if not, assume it is a gaussian
+      88             :     IFile *ff;
+      89          15 :     ff=ifiles[beingread].get();
+      90          15 :     if(!isopen) {
+      91          14 :       (*log)<<"  opening file "<<filenames[beingread]<<"\n";
+      92          14 :       ff->open(filenames[beingread]); isopen=true;
+      93             :     }
+      94          15 :     int n=0;
+      95             :     while(true) {
+      96             :       bool fileisover=true;
+      97        5578 :       while(scanOneHill(br,ff)) {
+      98             :         // here do the dump if needed
+      99        5563 :         n=br->getNumberOfKernels();
+     100        5563 :         if(stride>0 && n%stride==0 && n!=0  ) {
+     101           1 :           (*log)<<"  done with this chunk: now with "<<n<<" kernels  \n";
+     102             :           fileisover=false;
+     103             :           break;
+     104             :         }
+     105             :       }
+     106             :       if(fileisover) {
+     107          15 :         (*log)<<"  closing file "<<filenames[beingread]<<"\n";
+     108          15 :         ff->close();
+     109          15 :         isopen=false;
+     110          15 :         (*log)<<"  now total "<<br->getNumberOfKernels()<<" kernels \n";
+     111          15 :         beingread++;
+     112          15 :         if(beingread<ifiles.size()) {
+     113           1 :           ff=ifiles[beingread].get(); ff->open(filenames[beingread]);
+     114           1 :           (*log)<<"  opening file "<<filenames[beingread]<<"\n";
+     115           1 :           isopen=true;
+     116             :         } else {
+     117             :           morefiles=false;
+     118          14 :           (*log)<<"  final chunk: now with "<<n<<" kernels  \n";
+     119             :           break;
+     120             :         }
+     121             :       }
+     122             :       // if there are no more files to read and this file is over then quit
+     123             :       if(fileisover && !morefiles) {break;}
+     124             :       // if you are in the middle of a file and you are here
+     125             :       // then means that you read what you need to read
+     126           2 :       if(!fileisover ) {break;}
+     127             :     }
+     128             :   }
+     129          15 :   return morefiles;
+     130             : }
+     131           4 : void FilesHandler::getMinMaxBin(const std::vector<Value*> & vals, Communicator &cc, std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin) {
+     132             :   // create the representation (no grid)
+     133           4 :   BiasRepresentation br(vals,cc);
+     134             :   // read all the kernels
+     135           4 :   readBunch(&br);
+     136             :   // loop over the kernels and get the support
+     137           4 :   br.getMinMaxBin(vmin,vmax,vbin);
+     138           4 : }
+     139           1 : void FilesHandler::getMinMaxBin(const std::vector<Value*> & vals, Communicator &cc, std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin, const std::vector<double> &histosigma) {
+     140           1 :   BiasRepresentation br(vals,cc,histosigma);
+     141             :   // read all the kernels
+     142           1 :   readBunch(&br);
+     143             :   // loop over the kernels and get the support
+     144           1 :   br.getMinMaxBin(vmin,vmax,vbin);
+     145             :   //for(unsigned i=0;i<vals.size();i++){cerr<<"XXX "<<vmin[i]<<" "<<vmax[i]<<" "<<vbin[i]<<"\n";}
+     146           1 : }
+     147        5578 : bool FilesHandler::scanOneHill(BiasRepresentation *br, IFile *ifile ) {
+     148             :   double dummy;
+     149       11156 :   if(ifile->scanField("time",dummy)) {
+     150             :     //(*log)<<"   scanning one hill: "<<dummy<<" \n";
+     151       16689 :     if(ifile->FieldExist("biasf")) ifile->scanField("biasf",dummy);
+     152       11126 :     if(ifile->FieldExist("clock")) ifile->scanField("clock",dummy);
+     153             :     // keep this intermediate function in case you need to parse more data in the future
+     154        5563 :     br->pushKernel(ifile);
+     155             :     //(*log)<<"  read hill\n";
+     156        5563 :     if(br->hasSigmaInInput())ifile->allowIgnoredFields();
+     157        5563 :     ifile->scanField();
+     158        5563 :     return true;
+     159             :   } else {
+     160             :     return false;
+     161             :   }
+     162             : }
+     163             : 
+     164             : 
+     165         900 : double  mylog( double v1 ) {
+     166         900 :   return std::log(v1);
+     167             : }
+     168             : 
+     169        1800 : double  mylogder( double v1 ) {
+     170        1800 :   return 1./v1;
+     171             : }
+     172             : 
+     173             : 
+     174             : 
+     175             : class FuncSumHills :
+     176             :   public Function
+     177             : {
+     178             :   std::vector<std::string> hillsFiles,histoFiles;
+     179             :   std::vector<std::string> proj;
+     180             :   int initstride;
+     181             :   bool iscltool,integratehills,integratehisto,parallelread;
+     182             :   bool negativebias;
+     183             :   bool nohistory;
+     184             :   bool minTOzero;
+     185             :   bool doInt;
+     186             :   double lowI_;
+     187             :   double uppI_;
+     188             :   double beta;
+     189             :   std::string outhills,outhisto,fmt;
+     190             :   std::unique_ptr<BiasRepresentation> biasrep;
+     191             :   std::unique_ptr<BiasRepresentation> historep;
+     192             : public:
+     193             :   explicit FuncSumHills(const ActionOptions&);
+     194             :   void calculate() override; // this probably is not needed
+     195             :   bool checkFilesAreExisting(const std::vector<std::string> & hills );
+     196             :   static void registerKeywords(Keywords& keys);
+     197             : };
+     198             : 
+     199             : PLUMED_REGISTER_ACTION(FuncSumHills,"FUNCSUMHILLS")
+     200             : 
+     201          11 : void FuncSumHills::registerKeywords(Keywords& keys) {
+     202          11 :   Function::registerKeywords(keys);
+     203          11 :   keys.use("ARG");
+     204          22 :   keys.add("optional","HILLSFILES"," source file for hills creation(may be the same as HILLS)"); // this can be a vector!
+     205          22 :   keys.add("optional","HISTOFILES"," source file for histogram creation(may be the same as HILLS)"); // also this can be a vector!
+     206          22 :   keys.add("optional","HISTOSIGMA"," sigmas for binning when the histogram correction is needed    ");
+     207          22 :   keys.add("optional","PROJ"," only with sumhills: the projection on the CVs");
+     208          22 :   keys.add("optional","KT"," only with sumhills: the kt factor when projection on CVs");
+     209          22 :   keys.add("optional","GRID_MIN","the lower bounds for the grid");
+     210          22 :   keys.add("optional","GRID_MAX","the upper bounds for the grid");
+     211          22 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+     212          22 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+     213          22 :   keys.add("optional","INTERVAL","set one dimensional INTERVAL");
+     214          22 :   keys.add("optional","OUTHILLS"," output file for hills ");
+     215          22 :   keys.add("optional","OUTHISTO"," output file for histogram ");
+     216          22 :   keys.add("optional","INITSTRIDE"," stride if you want an initial dump ");
+     217          22 :   keys.add("optional","STRIDE"," stride when you do it on the fly ");
+     218          22 :   keys.addFlag("ISCLTOOL",false,"use via plumed command line: calculate at read phase and then go");
+     219          22 :   keys.addFlag("PARALLELREAD",false,"read parallel HILLS file");
+     220          22 :   keys.addFlag("NEGBIAS",false,"dump  negative bias ( -bias )   instead of the free energy: needed in well tempered with flexible hills ");
+     221          22 :   keys.addFlag("NOHISTORY",false,"to be used with INITSTRIDE:  it splits the bias/histogram in pieces without previous history  ");
+     222          22 :   keys.addFlag("MINTOZERO",false,"translate the resulting bias/histogram to have the minimum to zero  ");
+     223          22 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     224          11 : }
+     225             : 
+     226           9 : FuncSumHills::FuncSumHills(const ActionOptions&ao):
+     227             :   Action(ao),
+     228             :   Function(ao),
+     229           9 :   initstride(-1),
+     230           9 :   iscltool(false),
+     231           9 :   integratehills(false),
+     232           9 :   integratehisto(false),
+     233           9 :   parallelread(false),
+     234           9 :   negativebias(false),
+     235           9 :   nohistory(false),
+     236           9 :   minTOzero(false),
+     237           9 :   doInt(false),
+     238           9 :   lowI_(-1.),
+     239           9 :   uppI_(-1.),
+     240           9 :   beta(-1.),
+     241           9 :   fmt("%14.9f")
+     242             : {
+     243             : 
+     244             :   // format
+     245           9 :   parse("FMT",fmt);
+     246           9 :   log<<"  Output format is "<<fmt<<"\n";
+     247             :   // here read
+     248             :   // Grid Stuff
+     249             :   std::vector<std::string> gmin;
+     250          18 :   parseVector("GRID_MIN",gmin);
+     251           9 :   if(gmin.size()!=getNumberOfArguments() && gmin.size()!=0) error("not enough values for GRID_MIN");
+     252           9 :   plumed_massert(gmin.size()==getNumberOfArguments() || gmin.size()==0,"need GRID_MIN argument for this") ;
+     253             :   std::vector<std::string> gmax;
+     254          18 :   parseVector("GRID_MAX",gmax);
+     255           9 :   if(gmax.size()!=getNumberOfArguments() && gmax.size()!=0) error("not enough values for GRID_MAX");
+     256           9 :   plumed_massert(gmax.size()==getNumberOfArguments() || gmax.size()==0,"need GRID_MAX argument for this") ;
+     257             :   std::vector<unsigned> gbin;
+     258             :   std::vector<double>   gspacing;
+     259          18 :   parseVector("GRID_BIN",gbin);
+     260           9 :   plumed_massert(gbin.size()==getNumberOfArguments() || gbin.size()==0,"need GRID_BIN argument for this") ;
+     261           9 :   if(gbin.size()!=getNumberOfArguments() && gbin.size()!=0) error("not enough values for GRID_BIN");
+     262          18 :   parseVector("GRID_SPACING",gspacing);
+     263           9 :   plumed_massert(gspacing.size()==getNumberOfArguments() || gspacing.size()==0,"need GRID_SPACING argument for this") ;
+     264           9 :   if(gspacing.size()!=getNumberOfArguments() && gspacing.size()!=0) error("not enough values for GRID_SPACING");
+     265           9 :   if(gspacing.size()!=0 && gbin.size()==0) {
+     266           1 :     log<<"  The number of bins will be estimated from GRID_SPACING\n";
+     267           8 :   } else if(gspacing.size()!=0 && gbin.size()!=0) {
+     268           0 :     log<<"  You specified both GRID_BIN and GRID_SPACING\n";
+     269           0 :     log<<"  The more conservative (highest) number of bins will be used for each variable\n";
+     270             :   }
+     271          10 :   if(gspacing.size()!=0) for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     272           1 :       if(gbin.size()==0) gbin.assign(getNumberOfArguments(),1);
+     273             :       double a,b;
+     274           1 :       Tools::convert(gmin[i],a);
+     275           1 :       Tools::convert(gmax[i],b);
+     276           1 :       unsigned n=std::ceil((b-a)/gspacing[i]);
+     277           1 :       if(gbin[i]<n) gbin[i]=n;
+     278             :     }
+     279             : 
+     280             :   // Inteval keyword
+     281           9 :   std::vector<double> tmpI(2);
+     282          18 :   parseVector("INTERVAL",tmpI);
+     283           9 :   if(tmpI.size()!=2&&tmpI.size()!=0) error("both a lower and an upper limits must be provided with INTERVAL");
+     284           9 :   else if(tmpI.size()==2) {
+     285           0 :     lowI_=tmpI.at(0);
+     286           0 :     uppI_=tmpI.at(1);
+     287           0 :     if(getNumberOfArguments()!=1) error("INTERVAL limits correction works only for monodimensional metadynamics!");
+     288           0 :     if(uppI_<lowI_) error("The Upper limit must be greater than the Lower limit!");
+     289           0 :     doInt=true;
+     290             :   }
+     291           9 :   if(doInt) {
+     292           0 :     log << "  Upper and Lower limits boundaries for the bias are activated at " << lowI_ << " - " << uppI_<<"\n";
+     293           0 :     log << "  Using the same values as boundaries for the grid if not other value was defined (default: 200 bins)\n";
+     294           0 :     std::ostringstream strsmin, strsmax;
+     295           0 :     strsmin << lowI_;
+     296           0 :     strsmax << uppI_;
+     297           0 :     if(gmin.size()==0) gmin.push_back(strsmin.str());
+     298           0 :     if(gmax.size()==0) gmax.push_back(strsmax.str());
+     299           0 :     if(gbin.size()==0) gbin.push_back(200);
+     300           0 :   }
+     301             : 
+     302             : 
+     303             :   // hills file:
+     304          18 :   parseVector("HILLSFILES",hillsFiles);
+     305           9 :   if(hillsFiles.size()==0) {
+     306           1 :     integratehills=false; // default behaviour
+     307             :   } else {
+     308           8 :     integratehills=true;
+     309          17 :     for(unsigned i=0; i<hillsFiles.size(); i++) log<<"  hillsfile  : "<<hillsFiles[i]<<"\n";
+     310             :   }
+     311             :   // histo file:
+     312          18 :   parseVector("HISTOFILES",histoFiles);
+     313           9 :   if(histoFiles.size()==0) {
+     314           8 :     integratehisto=false;
+     315             :   } else {
+     316           1 :     integratehisto=true;
+     317           2 :     for(unsigned i=0; i<histoFiles.size(); i++) log<<"  histofile  : "<<histoFiles[i]<<"\n";
+     318             :   }
+     319             :   std::vector<double> histoSigma;
+     320           9 :   if(integratehisto) {
+     321           1 :     parseVector("HISTOSIGMA",histoSigma);
+     322           3 :     for(unsigned i=0; i<histoSigma.size(); i++) log<<"  histosigma  : "<<histoSigma[i]<<"\n";
+     323             :   }
+     324             : 
+     325             :   // needs a projection?
+     326             :   proj.clear();
+     327           9 :   parseVector("PROJ",proj);
+     328           9 :   if(integratehills) {
+     329           8 :     plumed_massert(proj.size()<getNumberOfArguments()," The number of projection must be less than the full list of arguments ");
+     330             :   }
+     331           9 :   if(integratehisto) {
+     332           1 :     plumed_massert(proj.size()<=getNumberOfArguments()," The number of projection must be less or equal to the full list of arguments ");
+     333             :   }
+     334           9 :   if(integratehisto&&proj.size()==0) {
+     335           3 :     for(unsigned i=0; i<getNumberOfArguments(); i++) proj.push_back(getPntrToArgument(i)->getName());
+     336             :   }
+     337             : 
+     338             :   // add some automatic hills width: not in case stride is defined
+     339             :   // since when you start from zero the automatic size will be zero!
+     340           9 :   if(gmin.size()==0 || gmax.size()==0) {
+     341           5 :     log<<"   \n";
+     342           5 :     log<<"  No boundaries defined: need to do a prescreening of hills \n";
+     343             :     std::vector<Value*> tmphillsvalues, tmphistovalues;
+     344           5 :     if(integratehills) {
+     345          12 :       for(unsigned i=0; i<getNumberOfArguments(); i++)tmphillsvalues.push_back( getPntrToArgument(i) );
+     346             :     }
+     347           5 :     if(integratehisto) {
+     348           3 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     349           2 :         std::string ss = getPntrToArgument(i)->getName();
+     350           6 :         for(unsigned j=0; j<proj.size(); j++) {
+     351           4 :           if(proj[j]==ss) tmphistovalues.push_back( getPntrToArgument(i) );
+     352             :         }
+     353             :       }
+     354             :     }
+     355             : 
+     356           5 :     if(integratehills) {
+     357           4 :       FilesHandler hillsHandler(hillsFiles,parallelread,*this, log);
+     358             :       std::vector<double> vmin,vmax;
+     359             :       std::vector<unsigned> vbin;
+     360           4 :       hillsHandler.getMinMaxBin(tmphillsvalues,comm,vmin,vmax,vbin);
+     361           4 :       log<<"  found boundaries from hillsfile: \n";
+     362           4 :       gmin.resize(vmin.size());
+     363           4 :       gmax.resize(vmax.size());
+     364           4 :       if(gbin.size()==0) {
+     365           3 :         gbin=vbin;
+     366             :       } else {
+     367           1 :         log<<"  found nbins in input, this overrides the automatic choice \n";
+     368             :       }
+     369          12 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     370           8 :         Tools::convert(vmin[i],gmin[i]);
+     371           8 :         Tools::convert(vmax[i],gmax[i]);
+     372           8 :         log<<"  variable "<< getPntrToArgument(i)->getName()<<" min: "<<gmin[i]<<" max: "<<gmax[i]<<" nbin: "<<gbin[i]<<"\n";
+     373             :       }
+     374             :     }
+     375             :     // if at this stage bins are not there then do it with histo
+     376           5 :     if(gmin.size()==0) {
+     377           1 :       FilesHandler histoHandler(histoFiles,parallelread,*this, log);
+     378             :       std::vector<double> vmin,vmax;
+     379             :       std::vector<unsigned> vbin;
+     380           1 :       histoHandler.getMinMaxBin(tmphistovalues,comm,vmin,vmax,vbin,histoSigma);
+     381           1 :       log<<"  found boundaries from histofile: \n";
+     382           1 :       gmin.resize(vmin.size());
+     383           1 :       gmax.resize(vmax.size());
+     384           1 :       if(gbin.size()==0) {
+     385           0 :         gbin=vbin;
+     386             :       } else {
+     387           1 :         log<<"  found nbins in input, this overrides the automatic choice \n";
+     388             :       }
+     389           3 :       for(unsigned i=0; i<proj.size(); i++) {
+     390           2 :         Tools::convert(vmin[i],gmin[i]);
+     391           2 :         Tools::convert(vmax[i],gmax[i]);
+     392           2 :         log<<"  variable "<< proj[i] <<" min: "<<gmin[i]<<" max: "<<gmax[i]<<" nbin: "<<gbin[i]<<"\n";
+     393             :       }
+     394             :     }
+     395           5 :     log<<"  done!\n";
+     396           5 :     log<<"   \n";
+     397             :   }
+     398             : 
+     399             : 
+     400           9 :   if( proj.size() != 0 || integratehisto==true  ) {
+     401           3 :     parse("KT",beta);
+     402           7 :     for(unsigned i=0; i<proj.size(); i++) log<<"  projection "<<i<<" : "<<proj[i]<<"\n";
+     403             :     // this should be only for projection or free energy from histograms
+     404           3 :     plumed_massert(beta>0.,"if you make a projection or a histogram correction then you need KT flag!");
+     405           3 :     beta=1./beta;
+     406           3 :     log<<"  beta is "<<beta<<"\n";
+     407             :   }
+     408             :   // is a cltool: then you start and then die
+     409           9 :   parseFlag("ISCLTOOL",iscltool);
+     410             :   //
+     411           9 :   parseFlag("NEGBIAS",negativebias);
+     412             :   //
+     413           9 :   parseFlag("PARALLELREAD",parallelread);
+     414             :   // stride
+     415           9 :   parse("INITSTRIDE",initstride);
+     416             :   // output suffix or names
+     417           9 :   if(initstride<0) {
+     418           8 :     log<<"  Doing only one integration: no stride \n";
+     419             :     outhills="fes.dat"; outhisto="histo.dat";
+     420             :   }
+     421             :   else {
+     422             :     outhills="fes_"; outhisto="histo_";
+     423           1 :     log<<"  Doing integration slices every "<<initstride<<" kernels\n";
+     424           1 :     parseFlag("NOHISTORY",nohistory);
+     425           1 :     if(nohistory)log<<"  nohistory: each stride block has no memory of the previous block\n";
+     426             :   }
+     427           9 :   parseFlag("MINTOZERO",minTOzero);
+     428           9 :   if(minTOzero)log<<"  mintozero: bias/histogram will be translated to have the minimum value equal to zero\n";
+     429             :   //what might it be this?
+     430             :   // here start
+     431             :   // want something right now?? do it and return
+     432             :   // your argument is a set of cvs
+     433             :   // then you need: a hills / a colvar-like file (to do a histogram)
+     434             :   // create a bias representation for this
+     435           9 :   if(iscltool) {
+     436             : 
+     437             :     std::vector<Value*> tmphillsvalues, tmphistovalues;
+     438           9 :     if(integratehills) {
+     439          23 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     440             :         // allocate a new value from the old one: no deriv here
+     441             :         // if we are summing hills then all the arguments are needed
+     442          15 :         tmphillsvalues.push_back( getPntrToArgument(i) );
+     443             :       }
+     444             :     }
+     445           9 :     if(integratehisto) {
+     446           3 :       for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     447           2 :         std::string ss = getPntrToArgument(i)->getName();
+     448           6 :         for(unsigned j=0; j<proj.size(); j++) {
+     449           4 :           if(proj[j]==ss) tmphistovalues.push_back( getPntrToArgument(i) );
+     450             :         }
+     451             :       }
+     452             :     }
+     453             : 
+     454             :     // check if the files exists
+     455           9 :     if(integratehills) {
+     456           8 :       checkFilesAreExisting(hillsFiles);
+     457          16 :       biasrep=Tools::make_unique<BiasRepresentation>(tmphillsvalues,comm, gmin, gmax, gbin, doInt, lowI_, uppI_);
+     458           8 :       if(negativebias) {
+     459           1 :         biasrep->setRescaledToBias(true);
+     460           1 :         log<<"  required the -bias instead of the free energy \n";
+     461           1 :         if(initstride<0) {outhills="negativebias.dat";}
+     462             :         else {outhills="negativebias_";}
+     463             :       }
+     464             :     }
+     465             : 
+     466           9 :     parse("OUTHILLS",outhills);
+     467           9 :     parse("OUTHISTO",outhisto);
+     468           9 :     if(integratehills)log<<"  output file for fes/bias  is :  "<<outhills<<"\n";
+     469           9 :     if(integratehisto)log<<"  output file for histogram is :  "<<outhisto<<"\n";
+     470           9 :     checkRead();
+     471             : 
+     472           9 :     log<<"\n";
+     473           9 :     log<<"  Now calculating...\n";
+     474           9 :     log<<"\n";
+     475             : 
+     476             :     // here it defines the column to be histogrammed, tmpvalues should be only
+     477             :     // the list of the collective variable one want to consider
+     478           9 :     if(integratehisto) {
+     479           1 :       checkFilesAreExisting(histoFiles);
+     480           2 :       historep=Tools::make_unique<BiasRepresentation>(tmphistovalues,comm,gmin,gmax,gbin,histoSigma);
+     481             :     }
+     482             : 
+     483             :     // decide how to source hills ( serial/parallel )
+     484             :     // here below the input control
+     485             :     // say how many hills and it will read them from the
+     486             :     // bunch of files provided, will update the representation
+     487             :     // of hills (i.e. a list of hills and the associated grid)
+     488             : 
+     489             :     // decide how to source colvars ( serial parallel )
+     490           9 :     std::unique_ptr<FilesHandler> hillsHandler;
+     491           9 :     std::unique_ptr<FilesHandler> histoHandler;
+     492             : 
+     493          17 :     if(integratehills)  hillsHandler=Tools::make_unique<FilesHandler>(hillsFiles,parallelread,*this, log);
+     494          10 :     if(integratehisto)  histoHandler=Tools::make_unique<FilesHandler>(histoFiles,parallelread,*this, log);
+     495             : 
+     496             : // Stopwatch is logged when it goes out of scope
+     497           9 :     Stopwatch sw(log);
+     498             : 
+     499             : // Stopwatch is stopped when swh goes out of scope
+     500           9 :     auto swh=sw.startStop("0 Summing hills");
+     501             : 
+     502             :     // read a number of hills and put in the bias representation
+     503             :     int nfiles=0;
+     504           9 :     bool ibias=integratehills; bool ihisto=integratehisto;
+     505             :     while(true) {
+     506          10 :       if(  integratehills  && ibias  ) {
+     507           9 :         if(nohistory) {biasrep->clear(); log<<"  clearing history before reading a new block\n";};
+     508           9 :         log<<"  reading hills: \n";
+     509           9 :         ibias=hillsHandler->readBunch(biasrep.get(),initstride) ; log<<"\n";
+     510             :       }
+     511             : 
+     512          10 :       if(  integratehisto  && ihisto ) {
+     513           1 :         if(nohistory) {historep->clear(); log<<"  clearing history before reading a new block\n";};
+     514           1 :         log<<"  reading histogram: \n";
+     515           1 :         ihisto=histoHandler->readBunch(historep.get(),initstride) ;  log<<"\n";
+     516             :       }
+     517             : 
+     518             :       // dump: need to project?
+     519          10 :       if(proj.size()!=0) {
+     520             : 
+     521           4 :         if(integratehills) {
+     522             : 
+     523           3 :           log<<"  Bias: Projecting on subgrid... \n";
+     524           3 :           BiasWeight Bw(beta);
+     525           3 :           Grid biasGrid=*(biasrep->getGridPtr());
+     526           3 :           Grid smallGrid=biasGrid.project(proj,&Bw);
+     527           3 :           OFile gridfile; gridfile.link(*this);
+     528           3 :           std::ostringstream ostr; ostr<<nfiles;
+     529             :           std::string myout;
+     530           7 :           if(initstride>0) { myout=outhills+ostr.str()+".dat" ;} else {myout=outhills;}
+     531           3 :           log<<"  Bias: Writing subgrid on file "<<myout<<" \n";
+     532           3 :           gridfile.open(myout);
+     533           3 :           if(minTOzero) smallGrid.setMinToZero();
+     534             :           smallGrid.setOutputFmt(fmt);
+     535           3 :           smallGrid.writeToFile(gridfile);
+     536           3 :           gridfile.close();
+     537           3 :           if(!ibias)integratehills=false;// once you get to the final bunch just give up
+     538           3 :         }
+     539             :         // this should be removed
+     540           4 :         if(integratehisto) {
+     541             : 
+     542           1 :           log<<"  Histo: Projecting on subgrid... \n";
+     543           1 :           Grid histoGrid=*(historep->getGridPtr());
+     544             : 
+     545           1 :           OFile gridfile; gridfile.link(*this);
+     546           1 :           std::ostringstream ostr; ostr<<nfiles;
+     547             :           std::string myout;
+     548           1 :           if(initstride>0) { myout=outhisto+ostr.str()+".dat" ;} else {myout=outhisto;}
+     549           1 :           log<<"  Histo: Writing subgrid on file "<<myout<<" \n";
+     550           1 :           gridfile.open(myout);
+     551             : 
+     552           1 :           histoGrid.applyFunctionAllValuesAndDerivatives(&mylog,&mylogder);
+     553           1 :           histoGrid.scaleAllValuesAndDerivatives(-1./beta);
+     554           1 :           if(minTOzero) histoGrid.setMinToZero();
+     555             :           histoGrid.setOutputFmt(fmt);
+     556           1 :           histoGrid.writeToFile(gridfile);
+     557             : 
+     558           1 :           if(!ihisto)integratehisto=false;// once you get to the final bunch just give up
+     559           1 :         }
+     560             : 
+     561             :       } else {
+     562             : 
+     563           6 :         if(integratehills) {
+     564             : 
+     565           6 :           Grid biasGrid=*(biasrep->getGridPtr());
+     566           6 :           biasGrid.scaleAllValuesAndDerivatives(-1.);
+     567             : 
+     568           6 :           OFile gridfile; gridfile.link(*this);
+     569           6 :           std::ostringstream ostr; ostr<<nfiles;
+     570             :           std::string myout;
+     571           6 :           if(initstride>0) { myout=outhills+ostr.str()+".dat" ;} else {myout=outhills;}
+     572           6 :           log<<"  Writing full grid on file "<<myout<<" \n";
+     573           6 :           gridfile.open(myout);
+     574             : 
+     575           6 :           if(minTOzero) biasGrid.setMinToZero();
+     576             :           biasGrid.setOutputFmt(fmt);
+     577           6 :           biasGrid.writeToFile(gridfile);
+     578             :           // rescale back prior to accumulate
+     579           6 :           if(!ibias)integratehills=false;// once you get to the final bunch just give up
+     580           6 :         }
+     581           6 :         if(integratehisto) {
+     582             : 
+     583           0 :           Grid histoGrid=*(historep->getGridPtr());
+     584             :           // do this if you want a free energy from a grid, otherwise do not
+     585           0 :           histoGrid.applyFunctionAllValuesAndDerivatives(&mylog,&mylogder);
+     586           0 :           histoGrid.scaleAllValuesAndDerivatives(-1./beta);
+     587             : 
+     588           0 :           OFile gridfile; gridfile.link(*this);
+     589           0 :           std::ostringstream ostr; ostr<<nfiles;
+     590             :           std::string myout;
+     591           0 :           if(initstride>0) { myout=outhisto+ostr.str()+".dat" ;} else {myout=outhisto;}
+     592           0 :           log<<"  Writing full grid on file "<<myout<<" \n";
+     593           0 :           gridfile.open(myout);
+     594             : 
+     595             :           // also this is useful only for free energy
+     596           0 :           if(minTOzero) histoGrid.setMinToZero();
+     597             :           histoGrid.setOutputFmt(fmt);
+     598           0 :           histoGrid.writeToFile(gridfile);
+     599             : 
+     600           0 :           if(!ihisto)integratehisto=false; // once you get to the final bunch just give up
+     601           0 :         }
+     602             :       }
+     603          10 :       if ( !ibias && !ihisto) break; //when both are over then just quit
+     604             : 
+     605           1 :       nfiles++;
+     606           1 :     }
+     607             : 
+     608             :     return;
+     609           9 :   }
+     610             :   // just an initialization but you need to do something on the fly?: need to connect with a metad run and its grid representation
+     611             :   // your argument is a metad run
+     612             :   // if the grid does not exist crash and say that you need some data
+     613             :   // otherwise just link with it
+     614             : 
+     615           9 : }
+     616             : 
+     617           0 : void FuncSumHills::calculate() {
+     618             :   // this should be connected only with a grid representation to metadynamics
+     619             :   // at regular time just dump it
+     620           0 :   plumed_merror("You should have never got here: this stuff is not yet implemented!");
+     621             : }
+     622             : 
+     623           9 : bool FuncSumHills::checkFilesAreExisting(const std::vector<std::string> & hills ) {
+     624           9 :   plumed_massert(hills.size()!=0,"the number of  files provided should be at least one" );
+     625             :   auto ifile=Tools::make_unique<IFile>();
+     626           9 :   ifile->link(*this);
+     627          19 :   for(unsigned i=0; i< hills.size(); i++) {
+     628          10 :     plumed_massert(ifile->FileExist(hills[i]),"missing file "+hills[i]);
+     629             :   }
+     630           9 :   return true;
+     631             : 
+     632           9 : }
+     633             : 
+     634             : }
+     635             : 
+     636             : }
+     637             : 
+     638             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.cpp.func-sort-c.html b/coverage/function/Function.cpp.func-sort-c.html new file mode 100644 index 000000000000..c09b2262b0c3 --- /dev/null +++ b/coverage/function/Function.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - function/Function.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293096.7 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8FunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function8Function23addValueWithDerivativesEv574
_ZN4PLMD8function8FunctionC2ERKNS_13ActionOptionsE672
_ZN4PLMD8function8Function16registerKeywordsERNS_8KeywordsE702
_ZN4PLMD8function8Function27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3173
_ZN4PLMD8function8Function5applyEv225125
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.cpp.func.html b/coverage/function/Function.cpp.func.html new file mode 100644 index 000000000000..a8b16683a452 --- /dev/null +++ b/coverage/function/Function.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - function/Function.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293096.7 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Function16registerKeywordsERNS_8KeywordsE702
_ZN4PLMD8function8Function23addValueWithDerivativesEv574
_ZN4PLMD8function8Function27addComponentWithDerivativesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3173
_ZN4PLMD8function8Function5applyEv225125
_ZN4PLMD8function8FunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function8FunctionC2ERKNS_13ActionOptionsE672
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.cpp.gcov.html b/coverage/function/Function.cpp.gcov.html new file mode 100644 index 000000000000..a7217ec1371e --- /dev/null +++ b/coverage/function/Function.cpp.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - function/Function.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293096.7 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Function.h"
+      23             : #include "tools/OpenMP.h"
+      24             : #include "tools/Communicator.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace function {
+      28             : 
+      29         702 : void Function::registerKeywords(Keywords& keys) {
+      30         702 :   Action::registerKeywords(keys);
+      31         702 :   ActionWithValue::registerKeywords(keys);
+      32         702 :   ActionWithArguments::registerKeywords(keys);
+      33        1404 :   keys.reserve("compulsory","PERIODIC","if the output of your function is periodic then you should specify the periodicity of the function.  If the output is not periodic you must state this using PERIODIC=NO");
+      34         702 : }
+      35             : 
+      36         672 : Function::Function(const ActionOptions&ao):
+      37             :   Action(ao),
+      38             :   ActionWithValue(ao),
+      39         672 :   ActionWithArguments(ao)
+      40             : {
+      41         672 : }
+      42             : 
+      43         574 : void Function::addValueWithDerivatives() {
+      44         574 :   plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values");
+      45        1148 :   ActionWithValue::addValueWithDerivatives();
+      46         574 :   getPntrToValue()->resizeDerivatives(getNumberOfArguments());
+      47             : 
+      48        1148 :   if( keywords.exists("PERIODIC") ) {
+      49             :     std::vector<std::string> period;
+      50        1142 :     parseVector("PERIODIC",period);
+      51        1139 :     if(period.size()==1 && period[0]=="NO") {
+      52         568 :       setNotPeriodic();
+      53           3 :     } else if(period.size()==2) {
+      54           3 :       setPeriodic(period[0],period[1]);
+      55           0 :     } else error("missing PERIODIC keyword");
+      56         571 :   }
+      57         574 : }
+      58             : 
+      59        3173 : void Function::addComponentWithDerivatives( const std::string& name ) {
+      60        3173 :   plumed_massert( getNumberOfArguments()!=0, "for functions you must requestArguments before adding values");
+      61        3173 :   ActionWithValue::addComponentWithDerivatives(name);
+      62        3173 :   getPntrToComponent(name)->resizeDerivatives(getNumberOfArguments());
+      63        3173 : }
+      64             : 
+      65      225125 : void Function::apply()
+      66             : {
+      67      225125 :   if( !checkForForces() ) return;
+      68       26652 :   unsigned ind=0; addForcesOnArguments( 0, getForcesToApply(), ind );
+      69             : }
+      70             : 
+      71             : }
+      72             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.h.func-sort-c.html b/coverage/function/Function.h.func-sort-c.html new file mode 100644 index 000000000000..0b52f3708467 --- /dev/null +++ b/coverage/function/Function.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - function/Function.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8FunctionD2Ev672
_ZN4PLMD8function8Function22getNumberOfDerivativesEv3696424
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.h.func.html b/coverage/function/Function.h.func.html new file mode 100644 index 000000000000..dcf89a07b5a8 --- /dev/null +++ b/coverage/function/Function.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - function/Function.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function8Function22getNumberOfDerivativesEv3696424
_ZN4PLMD8function8FunctionD2Ev672
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Function.h.gcov.html b/coverage/function/Function.h.gcov.html new file mode 100644 index 000000000000..c154e93754e4 --- /dev/null +++ b/coverage/function/Function.h.gcov.html @@ -0,0 +1,150 @@ + + + + + + + + LCOV - plumed test coverage - function/Function.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Function.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_function_Function_h
+      23             : #define __PLUMED_function_Function_h
+      24             : 
+      25             : #include "core/ActionWithValue.h"
+      26             : #include "core/ActionWithArguments.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace function {
+      30             : 
+      31             : /**
+      32             : \ingroup INHERIT
+      33             : This is the abstract base class to use for implementing new CV function, within it there is
+      34             : \ref AddingAFunction "information" as to how to go about implementing a new function.
+      35             : */
+      36             : 
+      37             : class Function:
+      38             :   public ActionWithValue,
+      39             :   public ActionWithArguments
+      40             : {
+      41             : protected:
+      42             :   void setDerivative(int,double);
+      43             :   void setDerivative(Value*,int,double);
+      44             :   void addValueWithDerivatives();
+      45             :   void addComponentWithDerivatives( const std::string& name );
+      46             : public:
+      47             :   explicit Function(const ActionOptions&);
+      48         672 :   virtual ~Function() {}
+      49             :   void apply() override;
+      50             :   static void registerKeywords(Keywords&);
+      51             :   unsigned getNumberOfDerivatives() override;
+      52             : };
+      53             : 
+      54             : inline
+      55             : void Function::setDerivative(Value*v,int i,double d) {
+      56        2910 :   v->addDerivative(i,d);
+      57           0 : }
+      58             : 
+      59             : inline
+      60             : void Function::setDerivative(int i,double d) {
+      61             :   setDerivative(getPntrToValue(),i,d);
+      62           5 : }
+      63             : 
+      64             : inline
+      65     3696424 : unsigned Function::getNumberOfDerivatives() {
+      66     3696424 :   return getNumberOfArguments();
+      67             : }
+      68             : 
+      69             : }
+      70             : }
+      71             : 
+      72             : #endif
+      73             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LocalEnsemble.cpp.func-sort-c.html b/coverage/function/LocalEnsemble.cpp.func-sort-c.html new file mode 100644 index 000000000000..4f296abd8af2 --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/LocalEnsemble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LocalEnsemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function13LocalEnsembleC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function13LocalEnsembleC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function13LocalEnsemble16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function13LocalEnsemble9calculateEv40
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LocalEnsemble.cpp.func.html b/coverage/function/LocalEnsemble.cpp.func.html new file mode 100644 index 000000000000..377f3ced960f --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/LocalEnsemble.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LocalEnsemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function13LocalEnsemble16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD8function13LocalEnsemble9calculateEv40
_ZN4PLMD8function13LocalEnsembleC1ERKNS_13ActionOptionsE2
_ZN4PLMD8function13LocalEnsembleC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/LocalEnsemble.cpp.gcov.html b/coverage/function/LocalEnsemble.cpp.gcov.html new file mode 100644 index 000000000000..509941e86e90 --- /dev/null +++ b/coverage/function/LocalEnsemble.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + + LCOV - plumed test coverage - function/LocalEnsemble.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - LocalEnsemble.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Function.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/OpenMP.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace function {
+      28             : 
+      29             : //+PLUMEDOC FUNCTION LOCALENSEMBLE
+      30             : /*
+      31             : Calculates the average over multiple arguments.
+      32             : 
+      33             : If more than one collective variable is given for each argument then they
+      34             : are averaged separately. The average is stored in a component labelled <em>label</em>.cvlabel.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : The following input tells plumed to calculate the chemical shifts for four
+      39             : different proteins in the same simulation box then average them, calculated
+      40             : the sum of the squared deviation with respect to the experimental values and
+      41             : applies a linear restraint.
+      42             : \plumedfile
+      43             : MOLINFO STRUCTURE=data/template.pdb
+      44             : 
+      45             : chaina: GROUP ATOMS=1-1640
+      46             : chainb: GROUP ATOMS=1641-3280
+      47             : chainc: GROUP ATOMS=3281-4920
+      48             : chaind: GROUP ATOMS=4921-6560
+      49             : 
+      50             : WHOLEMOLECULES ENTITY0=chaina ENTITY1=chainb ENTITY2=chainc ENTITY3=chaind
+      51             : 
+      52             : csa: CS2BACKBONE ATOMS=chaina NRES=100 DATA=data/ TEMPLATE=chaina.pdb NOPBC
+      53             : csb: CS2BACKBONE ATOMS=chainb NRES=100 DATA=data/ TEMPLATE=chainb.pdb NOPBC
+      54             : csc: CS2BACKBONE ATOMS=chainc NRES=100 DATA=data/ TEMPLATE=chainc.pdb NOPBC
+      55             : csd: CS2BACKBONE ATOMS=chaind NRES=100 DATA=data/ TEMPLATE=chaind.pdb NOPBC
+      56             : 
+      57             : ensca: LOCALENSEMBLE NUM=4 ARG1=(csa\.ca_.*) ARG2=(csb\.ca_.*) ARG3=(csc\.ca_.*) ARG4=(csd\.ca_.*)
+      58             : enscb: LOCALENSEMBLE NUM=4 ARG1=(csa\.cb_.*) ARG2=(csb\.cb_.*) ARG3=(csc\.cb_.*) ARG4=(csd\.cb_.*)
+      59             : ensco: LOCALENSEMBLE NUM=4 ARG1=(csa\.co_.*) ARG2=(csb\.co_.*) ARG3=(csc\.co_.*) ARG4=(csd\.co_.*)
+      60             : enshn: LOCALENSEMBLE NUM=4 ARG1=(csa\.hn_.*) ARG2=(csb\.hn_.*) ARG3=(csc\.hn_.*) ARG4=(csd\.hn_.*)
+      61             : ensnh: LOCALENSEMBLE NUM=4 ARG1=(csa\.nh_.*) ARG2=(csb\.nh_.*) ARG3=(csc\.nh_.*) ARG4=(csd\.nh_.*)
+      62             : 
+      63             : stca: STATS ARG=(ensca\.csa\.ca_.*) PARARG=(csa\.expca_.*) SQDEVSUM
+      64             : stcb: STATS ARG=(enscb\.csa\.cb_.*) PARARG=(csa\.expcb_.*) SQDEVSUM
+      65             : stco: STATS ARG=(ensco\.csa\.co_.*) PARARG=(csa\.expco_.*) SQDEVSUM
+      66             : sthn: STATS ARG=(enshn\.csa\.hn_.*) PARARG=(csa\.exphn_.*) SQDEVSUM
+      67             : stnh: STATS ARG=(ensnh\.csa\.nh_.*) PARARG=(csa\.expnh_.*) SQDEVSUM
+      68             : 
+      69             : res: RESTRAINT ARG=stca.*,stcb.*,stco.*,sthn.*,stnh.* AT=0.,0.,0.,0.,0. KAPPA=0.,0.,0.,0.,0 SLOPE=16.,16.,12.,24.,0.5
+      70             : \endplumedfile
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : 
+      75             : 
+      76             : class LocalEnsemble :
+      77             :   public Function
+      78             : {
+      79             :   unsigned ens_dim;
+      80             :   unsigned narg;
+      81             : public:
+      82             :   explicit LocalEnsemble(const ActionOptions&);
+      83             :   void     calculate() override;
+      84             :   static void registerKeywords(Keywords& keys);
+      85             : };
+      86             : 
+      87             : 
+      88             : PLUMED_REGISTER_ACTION(LocalEnsemble,"LOCALENSEMBLE")
+      89             : 
+      90           4 : void LocalEnsemble::registerKeywords(Keywords& keys) {
+      91           4 :   Function::registerKeywords(keys);
+      92           4 :   keys.use("ARG");
+      93           8 :   keys.add("compulsory","NUM","the number of local replicas");
+      94           4 :   useCustomisableComponents(keys);
+      95           4 : }
+      96             : 
+      97           2 : LocalEnsemble::LocalEnsemble(const ActionOptions&ao):
+      98             :   Action(ao),
+      99             :   Function(ao),
+     100           2 :   ens_dim(0)
+     101             : {
+     102           2 :   parse("NUM",ens_dim);
+     103           2 :   if(ens_dim==0) error("NUM should be greater or equal to 1");
+     104             : 
+     105             :   std::vector<Value*> arg;
+     106             :   int oldsize=-1;
+     107           8 :   for(unsigned i=1; i<=ens_dim; ++i ) {
+     108             :     std::vector<Value*> larg;
+     109          12 :     if(!parseArgumentList("ARG",i,larg)) break;
+     110          18 :     for(unsigned j=0; j<larg.size(); j++) arg.push_back(larg[j]);
+     111           6 :     if(oldsize!=-1&&oldsize!=static_cast<int>(larg.size())) error("In LOCALENSEMBLE you should have the same number of arguments for each ARG keyword");
+     112           6 :     oldsize = larg.size();
+     113           6 :     if(!larg.empty()) {
+     114           6 :       log.printf("  with arguments %u: ", i);
+     115          18 :       for(unsigned j=0; j<larg.size(); j++) log.printf(" %s",larg[j]->getName().c_str());
+     116           6 :       log.printf("\n");
+     117             :     }
+     118             :   }
+     119           2 :   requestArguments(arg);
+     120           2 :   narg = arg.size()/ens_dim;
+     121             : 
+     122             :   // these are the averages
+     123           6 :   for(unsigned i=0; i<narg; i++) {
+     124           4 :     std::string s=getPntrToArgument(i)->getName();
+     125           4 :     addComponentWithDerivatives(s);
+     126           4 :     getPntrToComponent(i)->setNotPeriodic();
+     127             :   }
+     128             : 
+     129           2 :   log.printf("  averaging over %u replicas.\n", ens_dim);
+     130           2 : }
+     131             : 
+     132          40 : void LocalEnsemble::calculate()
+     133             : {
+     134          40 :   const double fact = 1.0/static_cast<double>(ens_dim);
+     135          40 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     136             :   for(unsigned i=0; i<narg; ++i) {
+     137             :     double mean = 0.;
+     138             :     Value* v=getPntrToComponent(i);
+     139             :     for(unsigned j=0; j<ens_dim; ++j) {
+     140             :       const unsigned index = j*narg+i;
+     141             :       setDerivative(v, index, fact);
+     142             :       mean += fact*getArgument(index);
+     143             :     }
+     144             :     v->set(mean);
+     145             :   }
+     146          40 : }
+     147             : 
+     148             : }
+     149             : }
+     150             : 
+     151             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Piecewise.cpp.func-sort-c.html b/coverage/function/Piecewise.cpp.func-sort-c.html new file mode 100644 index 000000000000..547fdd1e4cb1 --- /dev/null +++ b/coverage/function/Piecewise.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Piecewise.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Piecewise.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4545100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function9PiecewiseC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function9PiecewiseC1ERKNS_13ActionOptionsE3
_ZN4PLMD8function9Piecewise16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD8function9Piecewise9calculateEv10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Piecewise.cpp.func.html b/coverage/function/Piecewise.cpp.func.html new file mode 100644 index 000000000000..12439548c96b --- /dev/null +++ b/coverage/function/Piecewise.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Piecewise.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Piecewise.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4545100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function9Piecewise16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD8function9Piecewise9calculateEv10
_ZN4PLMD8function9PiecewiseC1ERKNS_13ActionOptionsE3
_ZN4PLMD8function9PiecewiseC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Piecewise.cpp.gcov.html b/coverage/function/Piecewise.cpp.gcov.html new file mode 100644 index 000000000000..ebfd21823d6b --- /dev/null +++ b/coverage/function/Piecewise.cpp.gcov.html @@ -0,0 +1,235 @@ + + + + + + + + LCOV - plumed test coverage - function/Piecewise.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Piecewise.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4545100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "Function.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace function {
+      27             : 
+      28             : //+PLUMEDOC FUNCTION PIECEWISE
+      29             : /*
+      30             : Compute a piece wise straight line through its arguments that passes through a set of ordered control points.
+      31             : 
+      32             : For variables less than the first
+      33             : (greater than the last) point, the value of the first (last) point is used.
+      34             : 
+      35             : \f[
+      36             : \frac{y_{i+1}-y_i}{x_{i+1}-x_i}(s-x_i)+y_i ;  if x_i<s<x_{i+1}
+      37             : \f]
+      38             : \f[
+      39             : y_N ; if x>x_{N-1}
+      40             : \f]
+      41             : \f[
+      42             : y_1 ; if x<x_0
+      43             : \f]
+      44             : 
+      45             : Control points are passed using the POINT0=... POINT1=... syntax as in the example below
+      46             : 
+      47             : If one argument is supplied, it results in a scalar quantity.
+      48             : If multiple arguments are supplied, it results
+      49             : in a vector of values. Each value will be named as the name of the original
+      50             : argument with suffix _pfunc.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : \plumedfile
+      55             : dist1: DISTANCE ATOMS=1,10
+      56             : dist2: DISTANCE ATOMS=2,11
+      57             : 
+      58             : pw: PIECEWISE POINT0=1,10 POINT1=2,PI POINT2=3,10 ARG=dist1
+      59             : ppww: PIECEWISE POINT0=1,10 POINT1=2,PI POINT2=3,10 ARG=dist1,dist2
+      60             : PRINT ARG=pw,ppww.dist1_pfunc,ppww.dist2_pfunc
+      61             : \endplumedfile
+      62             : 
+      63             : 
+      64             : */
+      65             : //+ENDPLUMEDOC
+      66             : 
+      67             : 
+      68             : class Piecewise :
+      69             :   public Function
+      70             : {
+      71             :   std::vector<std::pair<double,double> > points;
+      72             : public:
+      73             :   explicit Piecewise(const ActionOptions&);
+      74             :   void calculate() override;
+      75             :   static void registerKeywords(Keywords& keys);
+      76             : };
+      77             : 
+      78             : 
+      79             : PLUMED_REGISTER_ACTION(Piecewise,"PIECEWISE")
+      80             : 
+      81           5 : void Piecewise::registerKeywords(Keywords& keys) {
+      82           5 :   Function::registerKeywords(keys);
+      83           5 :   keys.use("ARG");
+      84          10 :   keys.add("numbered","POINT","This keyword is used to specify the various points in the function above.");
+      85          10 :   keys.reset_style("POINT","compulsory");
+      86           5 :   componentsAreNotOptional(keys);
+      87          10 :   keys.addOutputComponent("_pfunc","default","one or multiple instances of this quantity can be referenced elsewhere "
+      88             :                           "in the input file.  These quantities will be named with the arguments of the "
+      89             :                           "function followed by the character string _pfunc.  These quantities tell the "
+      90             :                           "user the values of the piece wise functions of each of the arguments.");
+      91           5 : }
+      92             : 
+      93           3 : Piecewise::Piecewise(const ActionOptions&ao):
+      94             :   Action(ao),
+      95           3 :   Function(ao)
+      96             : {
+      97           9 :   for(int i=0;; i++) {
+      98             :     std::vector<double> pp;
+      99          24 :     if(!parseNumberedVector("POINT",i,pp) ) break;
+     100           9 :     if(pp.size()!=2) error("points should be in x,y format");
+     101           9 :     points.push_back(std::pair<double,double>(pp[0],pp[1]));
+     102           9 :     if(i>0 && points[i].first<=points[i-1].first) error("points abscissas should be monotonously increasing");
+     103           9 :   }
+     104             : 
+     105           6 :   for(unsigned i=0; i<getNumberOfArguments(); i++)
+     106           4 :     if(getPntrToArgument(i)->isPeriodic())
+     107           1 :       error("Cannot use PIECEWISE on periodic arguments");
+     108             : 
+     109           2 :   if(getNumberOfArguments()==1) {
+     110           1 :     addValueWithDerivatives();
+     111           1 :     setNotPeriodic();
+     112             :   } else {
+     113           3 :     for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     114           3 :       addComponentWithDerivatives( getPntrToArgument(i)->getName()+"_pfunc" );
+     115           2 :       getPntrToComponent(i)->setNotPeriodic();
+     116             :     }
+     117             :   }
+     118           2 :   checkRead();
+     119             : 
+     120           2 :   log.printf("  on points:");
+     121           8 :   for(unsigned i=0; i<points.size(); i++) log.printf("   (%f,%f)",points[i].first,points[i].second);
+     122           2 :   log.printf("\n");
+     123           4 : }
+     124             : 
+     125          10 : void Piecewise::calculate() {
+     126          25 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     127             :     double val=getArgument(i);
+     128             :     unsigned p=0;
+     129          37 :     for(; p<points.size(); p++) {
+     130          33 :       if(val<points[p].first) break;
+     131             :     }
+     132             :     double f,d;
+     133          15 :     if(p==0) {
+     134           5 :       f=points[0].second;
+     135             :       d=0.0;
+     136          10 :     } else if(p==points.size()) {
+     137           4 :       f=points[points.size()-1].second;
+     138             :       d=0.0;
+     139             :     } else {
+     140           6 :       double m=(points[p].second-points[p-1].second) / (points[p].first-points[p-1].first);
+     141           6 :       f=m*(val-points[p-1].first)+points[p-1].second;
+     142             :       d=m;
+     143             :     }
+     144          15 :     if(getNumberOfArguments()==1) {
+     145           5 :       setValue(f);
+     146             :       setDerivative(i,d);
+     147             :     } else {
+     148          10 :       Value* v=getPntrToComponent(i);
+     149          10 :       v->set(f);
+     150             :       v->addDerivative(i,d);
+     151             :     }
+     152             :   }
+     153          10 : }
+     154             : 
+     155             : }
+     156             : }
+     157             : 
+     158             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sort.cpp.func-sort-c.html b/coverage/function/Sort.cpp.func-sort-c.html new file mode 100644 index 000000000000..f7396cb35ff4 --- /dev/null +++ b/coverage/function/Sort.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Sort.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sort.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function4SortC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function4Sort9calculateEv11
_ZN4PLMD8function4SortC1ERKNS_13ActionOptionsE12
_ZN4PLMD8function4Sort16registerKeywordsERNS_8KeywordsE14
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sort.cpp.func.html b/coverage/function/Sort.cpp.func.html new file mode 100644 index 000000000000..e2a678d23f70 --- /dev/null +++ b/coverage/function/Sort.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Sort.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sort.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function4Sort16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD8function4Sort9calculateEv11
_ZN4PLMD8function4SortC1ERKNS_13ActionOptionsE12
_ZN4PLMD8function4SortC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Sort.cpp.gcov.html b/coverage/function/Sort.cpp.gcov.html new file mode 100644 index 000000000000..73c06b5b391f --- /dev/null +++ b/coverage/function/Sort.cpp.gcov.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - function/Sort.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Sort.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "Function.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace function {
+      27             : 
+      28             : //+PLUMEDOC FUNCTION SORT
+      29             : /*
+      30             : This function can be used to sort colvars according to their magnitudes.
+      31             : 
+      32             : \par Description of components
+      33             : 
+      34             : This function sorts its arguments according to their magnitudes. The lowest argument will be
+      35             : labelled <em>label</em>.1, the second lowest will be labelled <em>label</em>.2 and so on.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : The following input tells plumed to print the distance of the closest and of
+      40             : the farthest atoms to atom 1, chosen among atoms from 2 to 5
+      41             : \plumedfile
+      42             : d12:  DISTANCE ATOMS=1,2
+      43             : d13:  DISTANCE ATOMS=1,3
+      44             : d14:  DISTANCE ATOMS=1,4
+      45             : d15:  DISTANCE ATOMS=1,5
+      46             : sort: SORT ARG=d12,d13,d14,d15
+      47             : PRINT ARG=sort.1,sort.4
+      48             : \endplumedfile
+      49             : 
+      50             : */
+      51             : //+ENDPLUMEDOC
+      52             : 
+      53             : 
+      54             : class Sort :
+      55             :   public Function
+      56             : {
+      57             : public:
+      58             :   explicit Sort(const ActionOptions&);
+      59             :   void calculate() override;
+      60             :   static void registerKeywords(Keywords& keys);
+      61             : };
+      62             : 
+      63             : 
+      64             : PLUMED_REGISTER_ACTION(Sort,"SORT")
+      65             : 
+      66          14 : void Sort::registerKeywords(Keywords& keys) {
+      67          14 :   Function::registerKeywords(keys);
+      68          14 :   keys.use("ARG");
+      69          14 :   useCustomisableComponents(keys);
+      70          14 : }
+      71             : 
+      72          12 : Sort::Sort(const ActionOptions&ao):
+      73             :   Action(ao),
+      74          12 :   Function(ao)
+      75             : {
+      76          35 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      77             :     std::string s;
+      78          24 :     Tools::convert(i+1,s);
+      79          24 :     if(getPntrToArgument(i)->isPeriodic())
+      80           3 :       error("Cannot sort periodic values (check argument "+s+")");
+      81          23 :     addComponentWithDerivatives(s);
+      82          23 :     getPntrToComponent(i)->setNotPeriodic();
+      83             :   }
+      84          11 :   checkRead();
+      85             : 
+      86          13 : }
+      87             : 
+      88          11 : void Sort::calculate() {
+      89          11 :   std::vector<std::pair<double,int> > vals(getNumberOfArguments());
+      90          54 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      91          43 :     vals[i].first=getArgument(i);
+      92             : // In this manner I remember from which argument the component depends:
+      93          43 :     vals[i].second=i;
+      94             :   }
+      95             : // STL sort sorts based on first element (value) then second (index)
+      96          11 :   std::sort(vals.begin(),vals.end());
+      97          54 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+      98          43 :     Value* v=getPntrToComponent(i);
+      99          43 :     v->set(vals[i].first);
+     100          43 :     setDerivative(v,vals[i].second,1.0);
+     101             :   }
+     102          11 : }
+     103             : 
+     104             : }
+     105             : }
+     106             : 
+     107             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Stats.cpp.func-sort-c.html b/coverage/function/Stats.cpp.func-sort-c.html new file mode 100644 index 000000000000..33ab7039d0af --- /dev/null +++ b/coverage/function/Stats.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Stats.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Stats.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959996.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function5StatsC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function5StatsC1ERKNS_13ActionOptionsE31
_ZN4PLMD8function5Stats16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD8function5Stats9calculateEv122
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Stats.cpp.func.html b/coverage/function/Stats.cpp.func.html new file mode 100644 index 000000000000..8b9987d1c80d --- /dev/null +++ b/coverage/function/Stats.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Stats.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Stats.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959996.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function5Stats16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD8function5Stats9calculateEv122
_ZN4PLMD8function5StatsC1ERKNS_13ActionOptionsE31
_ZN4PLMD8function5StatsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Stats.cpp.gcov.html b/coverage/function/Stats.cpp.gcov.html new file mode 100644 index 000000000000..5c183c452d7e --- /dev/null +++ b/coverage/function/Stats.cpp.gcov.html @@ -0,0 +1,316 @@ + + + + + + + + LCOV - plumed test coverage - function/Stats.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Stats.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959996.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Function.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace function {
+      27             : 
+      28             : //+PLUMEDOC FUNCTION STATS
+      29             : /*
+      30             : Calculates statistical properties of a set of collective variables with respect to a set of reference values.
+      31             : 
+      32             : In particular it calculates and stores as components the sum of the squared deviations, the correlation, the
+      33             : slope and the intercept of a linear fit.
+      34             : 
+      35             : The reference values can be either provided as values using PARAMETERS or using value without derivatives
+      36             : from other actions using PARARG (for example using experimental values from collective variables such as
+      37             : \ref CS2BACKBONE, \ref RDC, \ref NOE, \ref PRE).
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : The following input tells plumed to print the distance between three couple of atoms
+      42             : and compare them with three reference distances.
+      43             : 
+      44             : \plumedfile
+      45             : d1: DISTANCE ATOMS=10,50
+      46             : d2: DISTANCE ATOMS=1,100
+      47             : d3: DISTANCE ATOMS=45,75
+      48             : st: STATS ARG=d1,d2,d3 PARAMETERS=1.5,4.0,2.0
+      49             : PRINT ARG=d1,d2,d3,st.*
+      50             : \endplumedfile
+      51             : 
+      52             : */
+      53             : //+ENDPLUMEDOC
+      54             : 
+      55             : 
+      56             : class Stats :
+      57             :   public Function
+      58             : {
+      59             :   std::vector<double> parameters;
+      60             :   bool sqdonly;
+      61             :   bool components;
+      62             :   bool upperd;
+      63             : public:
+      64             :   explicit Stats(const ActionOptions&);
+      65             :   void calculate() override;
+      66             :   static void registerKeywords(Keywords& keys);
+      67             : };
+      68             : 
+      69             : 
+      70             : PLUMED_REGISTER_ACTION(Stats,"STATS")
+      71             : 
+      72          33 : void Stats::registerKeywords(Keywords& keys) {
+      73          33 :   Function::registerKeywords(keys);
+      74          33 :   keys.use("ARG");
+      75          66 :   keys.add("optional","PARARG","the input for this action is the scalar output from one or more other actions without derivatives.");
+      76          66 :   keys.add("optional","PARAMETERS","the parameters of the arguments in your function");
+      77          66 :   keys.addFlag("SQDEVSUM",false,"calculates only SQDEVSUM");
+      78          66 :   keys.addFlag("SQDEV",false,"calculates and store the SQDEV as components");
+      79          66 :   keys.addFlag("UPPERDISTS",false,"calculates and store the SQDEV as components");
+      80          66 :   keys.addOutputComponent("sqdevsum","default","the sum of the squared deviations between arguments and parameters");
+      81          66 :   keys.addOutputComponent("corr","default","the correlation between arguments and parameters");
+      82          66 :   keys.addOutputComponent("slope","default","the slope of a linear fit between arguments and parameters");
+      83          66 :   keys.addOutputComponent("intercept","default","the intercept of a linear fit between arguments and parameters");
+      84          66 :   keys.addOutputComponent("sqd","SQDEV","the squared deviations between arguments and parameters");
+      85          33 : }
+      86             : 
+      87          31 : Stats::Stats(const ActionOptions&ao):
+      88             :   Action(ao),
+      89             :   Function(ao),
+      90          31 :   sqdonly(false),
+      91          31 :   components(false),
+      92          31 :   upperd(false)
+      93             : {
+      94          62 :   parseVector("PARAMETERS",parameters);
+      95          31 :   if(parameters.size()!=static_cast<unsigned>(getNumberOfArguments())&&!parameters.empty())
+      96           0 :     error("Size of PARAMETERS array should be either 0 or the same as of the number of arguments in ARG1");
+      97             : 
+      98             :   std::vector<Value*> arg2;
+      99          62 :   parseArgumentList("PARARG",arg2);
+     100             : 
+     101          31 :   if(!arg2.empty()) {
+     102          14 :     if(parameters.size()>0) error("It is not possible to use PARARG and PARAMETERS together");
+     103          14 :     if(arg2.size()!=getNumberOfArguments()) error("Size of PARARG array should be the same as number for arguments in ARG");
+     104        5912 :     for(unsigned i=0; i<arg2.size(); i++) {
+     105        5898 :       parameters.push_back(arg2[i]->get());
+     106        5898 :       if(arg2[i]->hasDerivatives()==true) error("PARARG can only accept arguments without derivatives");
+     107             :     }
+     108             :   }
+     109             : 
+     110          31 :   if(parameters.size()!=getNumberOfArguments())
+     111           0 :     error("PARARG or PARAMETERS arrays should include the same number of elements as the arguments in ARG");
+     112             : 
+     113          31 :   if(getNumberOfArguments()<2) error("STATS need at least two arguments to be used");
+     114             : 
+     115          31 :   parseFlag("SQDEVSUM",sqdonly);
+     116          31 :   parseFlag("SQDEV",components);
+     117          31 :   parseFlag("UPPERDISTS",upperd);
+     118             : 
+     119          31 :   if(sqdonly&&components) error("You cannot used SQDEVSUM and SQDEV at the sametime");
+     120             : 
+     121          31 :   if(components) sqdonly = true;
+     122             : 
+     123          31 :   if(!arg2.empty()) log.printf("  using %zu parameters from inactive actions:", arg2.size());
+     124          17 :   else              log.printf("  using %zu parameters:", arg2.size());
+     125        6000 :   for(unsigned i=0; i<parameters.size(); i++) log.printf(" %f",parameters[i]);
+     126          31 :   log.printf("\n");
+     127             : 
+     128          31 :   if(sqdonly) {
+     129          17 :     if(components) {
+     130          60 :       for(unsigned i=0; i<parameters.size(); i++) {
+     131          48 :         std::string num; Tools::convert(i,num);
+     132          48 :         addComponentWithDerivatives("sqd-"+num);
+     133          96 :         componentIsNotPeriodic("sqd-"+num);
+     134             :       }
+     135             :     } else {
+     136           5 :       addComponentWithDerivatives("sqdevsum");
+     137          10 :       componentIsNotPeriodic("sqdevsum");
+     138             :     }
+     139             :   } else {
+     140          14 :     addComponentWithDerivatives("sqdevsum");
+     141          14 :     componentIsNotPeriodic("sqdevsum");
+     142          14 :     addComponentWithDerivatives("corr");
+     143          14 :     componentIsNotPeriodic("corr");
+     144          14 :     addComponentWithDerivatives("slope");
+     145          14 :     componentIsNotPeriodic("slope");
+     146          14 :     addComponentWithDerivatives("intercept");
+     147          28 :     componentIsNotPeriodic("intercept");
+     148             :   }
+     149             : 
+     150          31 :   checkRead();
+     151          31 : }
+     152             : 
+     153         122 : void Stats::calculate()
+     154             : {
+     155         122 :   if(sqdonly) {
+     156             : 
+     157             :     double nsqd = 0.;
+     158             :     Value* val;
+     159         106 :     if(!components) val=getPntrToComponent("sqdevsum");
+     160         174 :     for(unsigned i=0; i<parameters.size(); ++i) {
+     161         121 :       double dev = getArgument(i)-parameters[i];
+     162         121 :       if(upperd&&dev<0) dev=0.;
+     163         121 :       if(components) {
+     164           0 :         val=getPntrToComponent(i);
+     165           0 :         val->set(dev*dev);
+     166             :       } else {
+     167         121 :         nsqd += dev*dev;
+     168             :       }
+     169         121 :       setDerivative(val,i,2.*dev);
+     170             :     }
+     171          53 :     if(!components) val->set(nsqd);
+     172             : 
+     173             :   } else {
+     174             : 
+     175             :     double scx=0., scx2=0., scy=0., scy2=0., scxy=0.;
+     176             : 
+     177        6230 :     for(unsigned i=0; i<parameters.size(); ++i) {
+     178             :       const double tmpx=getArgument(i);
+     179        6161 :       const double tmpy=parameters[i];
+     180        6161 :       scx  += tmpx;
+     181        6161 :       scx2 += tmpx*tmpx;
+     182        6161 :       scy  += tmpy;
+     183        6161 :       scy2 += tmpy*tmpy;
+     184        6161 :       scxy += tmpx*tmpy;
+     185             :     }
+     186             : 
+     187          69 :     const double ns = parameters.size();
+     188             : 
+     189          69 :     const double num = ns*scxy - scx*scy;
+     190          69 :     const double idev2x = 1./(ns*scx2-scx*scx);
+     191          69 :     const double idevx = std::sqrt(idev2x);
+     192          69 :     const double idevy = 1./std::sqrt(ns*scy2-scy*scy);
+     193             : 
+     194             :     /* sd */
+     195          69 :     const double nsqd = scx2 + scy2 - 2.*scxy;
+     196             :     /* correlation */
+     197          69 :     const double correlation = num * idevx * idevy;
+     198             :     /* slope and intercept */
+     199          69 :     const double slope = num * idev2x;
+     200          69 :     const double inter = (scy - slope * scx)/ns;
+     201             : 
+     202          69 :     Value* valuea=getPntrToComponent("sqdevsum");
+     203          69 :     Value* valueb=getPntrToComponent("corr");
+     204          69 :     Value* valuec=getPntrToComponent("slope");
+     205         138 :     Value* valued=getPntrToComponent("intercept");
+     206             : 
+     207             :     valuea->set(nsqd);
+     208             :     valueb->set(correlation);
+     209             :     valuec->set(slope);
+     210             :     valued->set(inter);
+     211             : 
+     212             :     /* derivatives */
+     213        6230 :     for(unsigned i=0; i<parameters.size(); ++i) {
+     214        6161 :       const double common_d1 = (ns*parameters[i]-scy)*idevx;
+     215        6161 :       const double common_d2 = num*(ns*getArgument(i)-scx)*idev2x*idevx;
+     216        6161 :       const double common_d3 = common_d1 - common_d2;
+     217             : 
+     218             :       /* sqdevsum */
+     219        6161 :       const double sq_der = 2.*(getArgument(i)-parameters[i]);
+     220             :       /* correlation */
+     221        6161 :       const double co_der = common_d3*idevy;
+     222             :       /* slope */
+     223        6161 :       const double sl_der = (common_d1-2.*common_d2)*idevx;
+     224             :       /* intercept */
+     225        6161 :       const double int_der = -(slope+ scx*sl_der)/ns;
+     226             : 
+     227             :       setDerivative(valuea,i,sq_der);
+     228             :       setDerivative(valueb,i,co_der);
+     229             :       setDerivative(valuec,i,sl_der);
+     230             :       setDerivative(valued,i,int_der);
+     231             :     }
+     232             : 
+     233             :   }
+     234         122 : }
+     235             : 
+     236             : }
+     237             : }
+     238             : 
+     239             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Target.cpp.func-sort-c.html b/coverage/function/Target.cpp.func-sort-c.html new file mode 100644 index 000000000000..4231abe32785 --- /dev/null +++ b/coverage/function/Target.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Target.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Target.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:52619.2 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6Target9calculateEv0
_ZN4PLMD8function6TargetC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function6TargetC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function6Target16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Target.cpp.func.html b/coverage/function/Target.cpp.func.html new file mode 100644 index 000000000000..4754adf85c0e --- /dev/null +++ b/coverage/function/Target.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - function/Target.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Target.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:52619.2 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function6Target16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD8function6Target9calculateEv0
_ZN4PLMD8function6TargetC1ERKNS_13ActionOptionsE0
_ZN4PLMD8function6TargetC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/Target.cpp.gcov.html b/coverage/function/Target.cpp.gcov.html new file mode 100644 index 000000000000..3206cf716315 --- /dev/null +++ b/coverage/function/Target.cpp.gcov.html @@ -0,0 +1,236 @@ + + + + + + + + LCOV - plumed test coverage - function/Target.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - function - Target.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:52619.2 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Function.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/PDB.h"
+      25             : #include "reference/MetricRegister.h"
+      26             : #include "reference/ArgumentOnlyDistance.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace function {
+      30             : 
+      31             : //+PLUMEDOC DCOLVAR TARGET
+      32             : /*
+      33             : This function measures the Pythagorean distance from a particular structure measured in the space defined by some set of collective variables.
+      34             : 
+      35             : This collective variable can be used to calculate something akin to:
+      36             : 
+      37             : \f[
+      38             : d(X,X') = \vert X - X' \vert
+      39             : \f]
+      40             : 
+      41             : where \f$ X \f$ is the instantaneous values for a set of collective variables for the system and
+      42             : \f$ X' \f$ is the values that these self-same set of collective variables take in some reference structure provided as input.
+      43             : If we call our set of collective variables \f$\{s_i\}\f$ then this CV computes:
+      44             : 
+      45             : \f[
+      46             : d = \sqrt{ \sum_{i=1}^N (s_i - s_i^{(ref)})^2 }
+      47             : \f]
+      48             : 
+      49             : where \f$s_i^{(ref)}\f$ are the values of the CVs in the reference structure and \f$N\f$ is the number of input CVs.
+      50             : 
+      51             : We can also calculate normalized euclidean differences using this action and the METRIC=NORM-EUCLIDEAN flag.  In other words,
+      52             : we can compute:
+      53             : 
+      54             : \f[
+      55             : d = \sqrt{ \sum_{i=1}^N \sigma_i (s_i - s_i^{(ref)})^2 }
+      56             : \f]
+      57             : 
+      58             : where \f$\sigma_i\f$ is a vector of weights.  Lastly, by using the METRIC=MAHALONOBIS we can compute Mahalonobis distances using:
+      59             : 
+      60             : \f[
+      61             : d = \left( \mathbf{s} - \mathbf{s}^{(ref)} \right)^T \mathbf{\Sigma} \left( \mathbf{s} - \mathbf{s}^{(ref)} \right)
+      62             : \f]
+      63             : 
+      64             : where \f$\mathbf{s}\f$ is a column vector containing the values of all the CVs and \f$\mathbf{s}^{(ref)}\f$ is a column vector
+      65             : containing the values of the CVs in the reference configuration.  \f$\mathbf{\Sigma}\f$ is then an \f$N \times N\f$ matrix that is
+      66             : specified in the input.
+      67             : 
+      68             : \par Examples
+      69             : 
+      70             : The following input calculates the distance between a reference configuration and the instantaneous position of the system in the trajectory.
+      71             : The position of the reference configuration is specified by providing the values of the distance between atoms 1 and 2 and atoms 3 and 4.
+      72             : 
+      73             : \plumedfile
+      74             : d1: DISTANCE ATOMS=1,2
+      75             : d2: DISTANCE ATOMS=3,4
+      76             : t1: TARGET REFERENCE=reference.pdb TYPE=EUCLIDEAN
+      77             : PRINT ARG=t1 FILE=colvar
+      78             : \endplumedfile
+      79             : 
+      80             : The contents of the file containing the reference structure (reference.pdb) is shown below.  As you can see you must provide information on the
+      81             : labels of the CVs that are being used to define the position of the reference configuration in this file together with the values that these
+      82             : quantities take in the reference configuration.
+      83             : 
+      84             : \auxfile{reference.pdb}
+      85             : DESCRIPTION: a reference point.
+      86             : REMARK WEIGHT=1.0
+      87             : REMARK ARG=d1,d2
+      88             : REMARK d1=1.0 d2=1.0
+      89             : END
+      90             : \endauxfile
+      91             : 
+      92             : */
+      93             : //+ENDPLUMEDOC
+      94             : 
+      95             : class Target : public Function {
+      96             : private:
+      97             :   MultiValue myvals;
+      98             :   ReferenceValuePack mypack;
+      99             :   std::unique_ptr<PLMD::ArgumentOnlyDistance> target;
+     100             : public:
+     101             :   explicit Target(const ActionOptions&);
+     102             :   void calculate() override;
+     103             :   static void registerKeywords(Keywords& keys );
+     104             : };
+     105             : 
+     106             : PLUMED_REGISTER_ACTION(Target,"TARGET")
+     107             : 
+     108           2 : void Target::registerKeywords(Keywords& keys) {
+     109           2 :   Function::registerKeywords(keys);
+     110           4 :   keys.add("compulsory","TYPE","EUCLIDEAN","the manner in which the distance should be calculated");
+     111           4 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure. In the PDB file the atomic "
+     112             :            "coordinates and box lengths should be in Angstroms unless you are working with natural units. "
+     113             :            "If you are working with natural units then the coordinates should be in your natural length unit. "
+     114             :            "The charges and masses of the atoms (if required) should be inserted in the beta and occupancy "
+     115             :            "columns respectively. For more details on the PDB file format visit http://www.wwpdb.org/docs.html");
+     116           2 : }
+     117             : 
+     118           0 : Target::Target(const ActionOptions&ao):
+     119             :   Action(ao),
+     120             :   Function(ao),
+     121           0 :   myvals(1,0),
+     122           0 :   mypack(0,0,myvals)
+     123             : {
+     124           0 :   std::string type; parse("TYPE",type);
+     125           0 :   std::string reference; parse("REFERENCE",reference);
+     126           0 :   checkRead(); PDB pdb;
+     127           0 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     128           0 :     error("missing input file " + reference);
+     129             : 
+     130             :   // Use the base ActionWithArguments to expand things like a1.*
+     131           0 :   expandArgKeywordInPDB( pdb );
+     132             : 
+     133             :   // Generate the reference structure
+     134           0 :   target=metricRegister().create<ArgumentOnlyDistance>( type, pdb );
+     135             : 
+     136             :   // Get the argument names
+     137             :   std::vector<std::string> args_to_retrieve;
+     138           0 :   target->getArgumentRequests( args_to_retrieve, false );
+     139             : 
+     140             :   // Get the arguments
+     141             :   std::vector<Value*> myargs;
+     142           0 :   interpretArgumentList( args_to_retrieve, myargs );
+     143           0 :   requestArguments( myargs );
+     144             : 
+     145             :   // Now create packs
+     146           0 :   myvals.resize( 1, myargs.size() );
+     147           0 :   mypack.resize( myargs.size(), 0 );
+     148             : 
+     149             :   // Create the value
+     150           0 :   addValueWithDerivatives(); setNotPeriodic();
+     151           0 : }
+     152             : 
+     153           0 : void Target::calculate() {
+     154           0 :   mypack.clear(); double r=target->calculate( getArguments(), mypack, false ); setValue(r);
+     155           0 :   for(unsigned i=0; i<getNumberOfArguments(); i++) setDerivative( i, mypack.getArgumentDerivative(i) );
+     156           0 : }
+     157             : 
+     158             : }
+     159             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/index-sort-f.html b/coverage/function/index-sort-f.html new file mode 100644 index 000000000000..03ae96a92594 --- /dev/null +++ b/coverage/function/index-sort-f.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:881102985.6 %
Date:2024-02-22 21:58:45Functions:486376.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Target.cpp +
19.2%19.2%
+
19.2 %5 / 2625.0 %1 / 4
Sort.cpp +
100.0%
+
100.0 %26 / 2675.0 %3 / 4
Ensemble.cpp +
63.0%63.0%
+
63.0 %80 / 12775.0 %3 / 4
Stats.cpp +
96.0%96.0%
+
96.0 %95 / 9975.0 %3 / 4
Custom.cpp +
94.9%94.9%
+
94.9 %56 / 5975.0 %3 / 4
Combine.cpp +
93.5%93.5%
+
93.5 %43 / 4675.0 %3 / 4
Piecewise.cpp +
100.0%
+
100.0 %45 / 4575.0 %3 / 4
LocalEnsemble.cpp +
100.0%
+
100.0 %31 / 3175.0 %3 / 4
FuncPathMSD.cpp +
92.5%92.5%
+
92.5 %74 / 8080.0 %4 / 5
FuncPathGeneral.cpp +
77.5%77.5%
+
77.5 %100 / 12983.3 %5 / 6
Function.cpp +
96.7%96.7%
+
96.7 %29 / 3083.3 %5 / 6
FuncSumHills.cpp +
89.8%89.8%
+
89.8 %292 / 32583.3 %10 / 12
Function.h +
83.3%83.3%
+
83.3 %5 / 6100.0 %2 / 2
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/index-sort-l.html b/coverage/function/index-sort-l.html new file mode 100644 index 000000000000..5711ec825e09 --- /dev/null +++ b/coverage/function/index-sort-l.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:881102985.6 %
Date:2024-02-22 21:58:45Functions:486376.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Target.cpp +
19.2%19.2%
+
19.2 %5 / 2625.0 %1 / 4
Ensemble.cpp +
63.0%63.0%
+
63.0 %80 / 12775.0 %3 / 4
FuncPathGeneral.cpp +
77.5%77.5%
+
77.5 %100 / 12983.3 %5 / 6
Function.h +
83.3%83.3%
+
83.3 %5 / 6100.0 %2 / 2
FuncSumHills.cpp +
89.8%89.8%
+
89.8 %292 / 32583.3 %10 / 12
FuncPathMSD.cpp +
92.5%92.5%
+
92.5 %74 / 8080.0 %4 / 5
Combine.cpp +
93.5%93.5%
+
93.5 %43 / 4675.0 %3 / 4
Custom.cpp +
94.9%94.9%
+
94.9 %56 / 5975.0 %3 / 4
Stats.cpp +
96.0%96.0%
+
96.0 %95 / 9975.0 %3 / 4
Function.cpp +
96.7%96.7%
+
96.7 %29 / 3083.3 %5 / 6
Sort.cpp +
100.0%
+
100.0 %26 / 2675.0 %3 / 4
LocalEnsemble.cpp +
100.0%
+
100.0 %31 / 3175.0 %3 / 4
Piecewise.cpp +
100.0%
+
100.0 %45 / 4575.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/function/index.html b/coverage/function/index.html new file mode 100644 index 000000000000..0594faf01c8f --- /dev/null +++ b/coverage/function/index.html @@ -0,0 +1,214 @@ + + + + + + + + LCOV - plumed test coverage - function + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - functionHitTotalCoverage
Test:plumed test coverageLines:881102985.6 %
Date:2024-02-22 21:58:45Functions:486376.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Combine.cpp +
93.5%93.5%
+
93.5 %43 / 4675.0 %3 / 4
Custom.cpp +
94.9%94.9%
+
94.9 %56 / 5975.0 %3 / 4
Ensemble.cpp +
63.0%63.0%
+
63.0 %80 / 12775.0 %3 / 4
FuncPathGeneral.cpp +
77.5%77.5%
+
77.5 %100 / 12983.3 %5 / 6
FuncPathMSD.cpp +
92.5%92.5%
+
92.5 %74 / 8080.0 %4 / 5
FuncSumHills.cpp +
89.8%89.8%
+
89.8 %292 / 32583.3 %10 / 12
Function.cpp +
96.7%96.7%
+
96.7 %29 / 3083.3 %5 / 6
Function.h +
83.3%83.3%
+
83.3 %5 / 6100.0 %2 / 2
LocalEnsemble.cpp +
100.0%
+
100.0 %31 / 3175.0 %3 / 4
Piecewise.cpp +
100.0%
+
100.0 %45 / 4575.0 %3 / 4
Sort.cpp +
100.0%
+
100.0 %26 / 2675.0 %3 / 4
Stats.cpp +
96.0%96.0%
+
96.0 %95 / 9975.0 %3 / 4
Target.cpp +
19.2%19.2%
+
19.2 %5 / 2625.0 %1 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/FPS.cpp.func-sort-c.html b/coverage/funnel/FPS.cpp.func-sort-c.html new file mode 100644 index 000000000000..8349f06b08ef --- /dev/null +++ b/coverage/funnel/FPS.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - funnel/FPS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - FPS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959996.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel9FUNNEL_PSC2ERKNS_13ActionOptionsE0
_ZN4PLMD6funnel9FUNNEL_PSC1ERKNS_13ActionOptionsE5
_ZN4PLMD6funnel9FUNNEL_PS16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6funnel9FUNNEL_PS9calculateEv150
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/FPS.cpp.func.html b/coverage/funnel/FPS.cpp.func.html new file mode 100644 index 000000000000..68c3de478c82 --- /dev/null +++ b/coverage/funnel/FPS.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - funnel/FPS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - FPS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959996.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel9FUNNEL_PS16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD6funnel9FUNNEL_PS9calculateEv150
_ZN4PLMD6funnel9FUNNEL_PSC1ERKNS_13ActionOptionsE5
_ZN4PLMD6funnel9FUNNEL_PSC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/FPS.cpp.gcov.html b/coverage/funnel/FPS.cpp.gcov.html new file mode 100644 index 000000000000..a2140fb8117a --- /dev/null +++ b/coverage/funnel/FPS.cpp.gcov.html @@ -0,0 +1,396 @@ + + + + + + + + LCOV - plumed test coverage - funnel/FPS.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - FPS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959996.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2019-2020
+       3             : 
+       4             :    This file is part of funnel code module.
+       5             : 
+       6             :    The FM code respects the CC BY-NC license.
+       7             :    Users are free to download, adapt and use the code as long as it is not for commercial purposes.
+       8             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+       9             : #include "colvar/Colvar.h"
+      10             : #include "core/ActionRegister.h"
+      11             : #include <string>
+      12             : #include <cmath>
+      13             : #include <cassert>
+      14             : #include <vector>
+      15             : #include "tools/Tools.h"
+      16             : #include "tools/PDB.h"
+      17             : #include <iostream>
+      18             : #include "tools/RMSD.h"
+      19             : 
+      20             : using namespace std;
+      21             : 
+      22             : namespace PLMD {
+      23             : namespace funnel {
+      24             : 
+      25             : //+PLUMEDOC FUNNELMOD_COLVAR FUNNEL_PS
+      26             : /*
+      27             : FUNNEL_PS implements the Funnel-Metadynamics (FM) technique in PLUMED 2.
+      28             : 
+      29             : Please read the FM \cite limongelli2013funnel \cite raniolo2020ligand papers to better understand the notions hereby reported.
+      30             : 
+      31             : This colvar evaluates the position of a ligand of interest with respect to a given line, built from the two points
+      32             : A and B, and should be used together with the \ref FUNNEL bias.
+      33             : The constructed line represents the axis of the funnel-shape restraint potential, which should be placed so
+      34             : as to include the portion of a macromolecule (i.e., protein, DNA, etc.) that should be explored.
+      35             : Since it is important that the position of the line is updated based on the motion of the macromolecule during
+      36             : the simulation, this colvar incorporates an alignment method. The latter uses the TYPE=OPTIMAL option to remove
+      37             : motions due to rotation and translation of the macromolecule with respect to a reference structure, which is
+      38             : provided by the user. In order to accomplish the task, an optimal alignment matrix is calculated using the
+      39             : Kearsley \cite kearsley algorithm.
+      40             : The reference structure should be given as a pdb file, containing only the atoms of the macromolecule or a
+      41             : selection of them (e.g., the protein CA atoms of secondary structures). In contrast to the methods reported in
+      42             : the \ref dists, the values reported in the occupancy and beta-factor columns of the pdb file are not important
+      43             : since they will be overwritten and replaced by the value 1.00 during the procedure. It is important to understand
+      44             : that all atoms in the file will be used for the alignment, even if they display 0.00 in the occupancy column.
+      45             : 
+      46             : The ligand can be represented by one single atom or the center of mass (COM) of a group of atoms that should be
+      47             : provided by the user.
+      48             : 
+      49             : By default FUNNEL_PS is computed taking into account periodic boundary conditions. Since PLUMED 2.5, molecules are
+      50             : rebuilt using a procedure that is equivalent to that done in \ref WHOLEMOLECULES. We note that this action is local
+      51             : to this colvar, thus it does not modify the coordinates stored in PLUMED. Moreover, FUNNEL_PS requires an ANCHOR atom
+      52             : to be specified in order to facilitate the reconstruction of periodic boundary conditions. This atom should be the
+      53             : closest macromolecule's atom to the ligand and it should reduce the risk of ligand "warping" in the simulation box.
+      54             : Nevertheless, we highly recommend to add to the PLUMED input file a custom line of \ref WHOLEMOLECULES, in order to
+      55             : be sure of reconstructing the ligand together with the macromolecule (please look the examples). In this case, the user
+      56             : can use the NOPBC flag to turn off the internal periodic boundary condition reconstruction.
+      57             : 
+      58             : FUNNEL_PS is divided in two components (fps.lp and fps.ld) which evaluate the projection of the ligand along the funnel line
+      59             : and the distance from it, respectively. The values attributed to these two components are then used together with the
+      60             : potential file created by the \ref FUNNEL bias to define if the ligand is within or not in the funnel-shape restraint
+      61             : potential. In the latter case, the potential will force the ligand to enter within the funnel boundaries.
+      62             : 
+      63             : \par Examples
+      64             : 
+      65             : The following input tells plumed to print the FUNNEL_PS components for the COM of a ligand. The inputs are a reference structure,
+      66             : which is the structure used for the alignment, the COM of the molecule we want to track, and 2 points in the Cartesian space
+      67             : (i.e., x, y, and z) to draw the line representing the funnel axis.
+      68             : \plumedfile
+      69             : lig: COM ATOMS=2446,2447,2448,2449,2451
+      70             : fps: FUNNEL_PS REFERENCE=protein.pdb LIGAND=lig POINTS=5.3478,-0.7278,2.4746,7.3785,6.7364,-9.3624
+      71             : PRINT ARG=fps.lp,fps.ld
+      72             : \endplumedfile
+      73             : 
+      74             : It is recommended to add a line to force the reconstruction of the periodic boundary conditions. In the following example,
+      75             : \ref WHOLEMOLECULES was added to make sure that the ligand was reconstructed together with the protein. The list contains
+      76             : all the atoms reported in the start.pdb file followed by the ANCHOR atom and the ligand. All atoms should be contained in the
+      77             : same entity and the correct order.
+      78             : \plumedfile
+      79             : WHOLEMOLECULES ENTITY0=54,75,212,228,239,258,311,328,348,372,383,402,421,463,487,503,519,657,674,690,714,897,914,934,953,964,
+      80             : 974,985,1007,1018,1037,1247,1264,1283,1302,1324,1689,1708,1727,1738,1962,1984,1994,2312,2329,2349,2467,2490,2500,2517,2524,2536,
+      81             : 2547,2554,2569,2575,2591,2607,2635,2657,2676,2693,2700,2719,2735,2746,2770,2777,2788,2795,2805,2815,2832,2854,2868,2898,2904,
+      82             : 2911,2927,2948,2962,2472,3221,3224,3225,3228,3229,3231,3233,3235,3237
+      83             : lig: COM ATOMS=3221,3224,3225,3228,3229,3231,3233,3235,3237
+      84             : fps: FUNNEL_PS LIGAND=lig REFERENCE=start.pdb ANCHOR=2472 POINTS=4.724,5.369,4.069,4.597,5.721,4.343
+      85             : PRINT ARG=fps.lp,fps.ld
+      86             : \endplumedfile
+      87             : 
+      88             : */
+      89             : //+ENDPLUMEDOC
+      90             : 
+      91             : 
+      92             : class FUNNEL_PS : public Colvar {
+      93             : 
+      94             :   // Those are arrays that I created for the colvar
+      95             :   std::vector<AtomNumber> ligand_com;
+      96             :   std::vector<AtomNumber> anchor;
+      97             :   std::vector<AtomNumber> numbers;
+      98             :   bool pbc;
+      99             :   PLMD::RMSD alignment;
+     100             :   PLMD::PDB pdb;
+     101             :   bool squared;
+     102             : private:
+     103             :   vector<double> points;
+     104             : public:
+     105             :   explicit FUNNEL_PS(const ActionOptions&);
+     106             : // active methods:
+     107             :   virtual void calculate();
+     108             :   static void registerKeywords(Keywords& keys);
+     109             : // I need a method in RMSDCoreCalc and these were requested
+     110             :   std::vector<double> align;
+     111             :   std::vector<double> displace;
+     112             : };
+     113             : 
+     114             : using namespace std;
+     115             : 
+     116             : PLUMED_REGISTER_ACTION(FUNNEL_PS,"FUNNEL_PS")
+     117             : 
+     118           7 : void FUNNEL_PS::registerKeywords(Keywords& keys) {
+     119           7 :   Colvar::registerKeywords( keys );
+     120          14 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the structure you would like to align.");
+     121          14 :   keys.add("atoms","LIGAND","This MUST be a single atom, normally the COM of the ligand");
+     122          14 :   keys.add("atoms","ANCHOR","Closest protein atom to the ligand, picked to avoid pbc problems during the simulation");
+     123          14 :   keys.add("compulsory","POINTS","6 values defining x, y, and z of the 2 points used to construct the line. The order should be A_x,A_y,A_z,B_x,B_y,B_z.");
+     124          14 :   keys.addFlag("SQUARED-ROOT",false,"Used to initialize the creation of the alignment variable");
+     125          14 :   keys.addOutputComponent("lp","default","the position along the funnel line");
+     126          14 :   keys.addOutputComponent("ld","default","the distance from the funnel line");
+     127           7 : }
+     128             : 
+     129           5 : FUNNEL_PS::FUNNEL_PS(const ActionOptions&ao):
+     130             :   PLUMED_COLVAR_INIT(ao),
+     131           5 :   pbc(true),squared(true)
+     132             : {
+     133             :   string reference;
+     134          10 :   parse("REFERENCE",reference);
+     135             :   string type;
+     136           5 :   type.assign("OPTIMAL");
+     137          10 :   parseAtomList("LIGAND",ligand_com);
+     138           5 :   if(ligand_com.size()!=1)
+     139           0 :     error("Number of specified atoms should be one, normally the COM of the ligand");
+     140           5 :   parseVector("POINTS",points);
+     141           5 :   bool nopbc=!pbc;
+     142           5 :   parseFlag("NOPBC",nopbc);
+     143           5 :   pbc=!nopbc;
+     144             :   bool sq;
+     145           5 :   parseFlag("SQUARED-ROOT",sq);
+     146           5 :   if (sq) {
+     147           0 :     squared=false;
+     148             :   }
+     149           5 :   parseAtomList("ANCHOR",anchor);
+     150           5 :   checkRead();
+     151             : 
+     152             :   // read everything in ang and transform to nm if we are not in natural units
+     153           5 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     154           0 :     error("missing input file " + reference );
+     155             : 
+     156             :   bool remove_com=true;
+     157             :   bool normalize_weights=true;
+     158             :   // here displace is a simple vector of ones
+     159           5 :   align=pdb.getOccupancy();
+     160       16195 :   for(unsigned i=0; i<align.size(); i++) {
+     161       16190 :     align[i]=1.;
+     162             :   } ;
+     163           5 :   displace=pdb.getBeta();
+     164       16195 :   for(unsigned i=0; i<displace.size(); i++) {
+     165       16190 :     displace[i]=1.;
+     166             :   } ;
+     167             :   // reset again to reimpose uniform weights (safe to disable this)
+     168           5 :   alignment.set(align,displace,pdb.getPositions(),type,remove_com,normalize_weights);
+     169             : 
+     170             : 
+     171             : 
+     172             :   // Array with inside both the structure to align and the atom to be aligned
+     173           5 :   numbers=pdb.getAtomNumbers();
+     174           5 :   numbers.push_back(anchor[0]);
+     175           5 :   numbers.push_back(ligand_com[0]);
+     176             : 
+     177           5 :   log.printf("  average from file %s\n",reference.c_str());
+     178           5 :   log.printf("  method for alignment : %s \n",type.c_str() );
+     179             : 
+     180           5 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     181           0 :   else    log.printf("  without periodic boundary conditions\n");
+     182             : 
+     183          10 :   addComponentWithDerivatives("lp");
+     184          10 :   componentIsNotPeriodic("lp");
+     185          10 :   addComponentWithDerivatives("ld");
+     186           5 :   componentIsNotPeriodic("ld");
+     187             : 
+     188           5 :   requestAtoms( numbers );
+     189             : 
+     190           5 : }
+     191             : 
+     192             : // calculator
+     193         150 : void FUNNEL_PS::calculate() {
+     194             : 
+     195         150 :   if(pbc) makeWhole();
+     196             : 
+     197         150 :   Tensor Rotation;
+     198             :   Matrix<std::vector<Vector> > drotdpos(3,3);
+     199             :   std::vector<Vector> alignedpos;
+     200             :   std::vector<Vector> centeredpos;
+     201             :   std::vector<Vector> centeredref;
+     202             :   std::vector<Vector> ddistdpos;
+     203             : 
+     204             :   std::vector<Vector> buffer;
+     205             : 
+     206         150 :   Vector centerreference;
+     207         150 :   Vector centerpositions;
+     208             : 
+     209             :   // Created only to give the correct object to calc_FitElements
+     210             :   std::vector<Vector> sourceAllPositions;
+     211             :   std::vector<Vector> sourcePositions;
+     212             : 
+     213             :   // SourcePositions contains only the coordinates of the COM of the ligand, we need only this point
+     214         150 :   sourceAllPositions=getPositions();
+     215         150 :   sourcePositions=sourceAllPositions;
+     216         150 :   sourcePositions.resize(sourcePositions.size()-2);// just the protein
+     217             : 
+     218             :   // The two points that define the axis : this can be moved in the initialization
+     219         150 :   Vector p1 = VectorGeneric<3>(points[0],points[1],points[2]);
+     220         150 :   Vector p2 = VectorGeneric<3>(points[3],points[4],points[5]);
+     221         150 :   Vector s = p2 - p1;
+     222             : 
+     223             :   // I call the method calc_FitElements that initializes all feature that I need
+     224             :   // except for centerreference that I need to calculate from scratch
+     225             :   // Buffer has no meaning but I had to fulfill the requirements of calc_FitElements
+     226         150 :   double rmsd = alignment.calc_FitElements( sourcePositions, Rotation, drotdpos, buffer, centerpositions, squared);
+     227             : 
+     228             :   // To Plumed developers: it would be interesting to make the functions to calculate centers of mass public or protected
+     229         150 :   centerreference.zero();
+     230      485850 :   for(unsigned i=0; i<pdb.size(); i++) {
+     231      485700 :     centerreference+=pdb.getPositions()[i]*align[i]/align.size();
+     232             :   }
+     233             : 
+     234             :   /*
+     235             :   // I cancelled the additional lines in the library of RMSD.h, thus I am missing the center of the reference
+     236             :   // Creating variable kito to extract only the center of the reference, since no method is calling
+     237             :   // function getReferenceCenter()
+     238             :   PLMD::RMSDCoreData* kito; kito = new RMSDCoreData(align,displace,sourcePositions,pdb->getPositions());
+     239             :   centerreference = kito->getReferenceCenter();
+     240             :   delete kito;
+     241             :   */
+     242             : 
+     243             :   // DEBUG
+     244             :   /*    log.printf(" RMSD: %13.6lf\n",rmsd );
+     245             :       log.printf(" cpos: %13.6lf %13.6lf %13.6lf\n",centerpositions[0],centerpositions[1],centerpositions[2] );
+     246             :       log.printf(" Rotation: %13.6lf %13.6lf %13.6lf\n",Rotation[0][0],Rotation[0][1],Rotation[0][2] );
+     247             :       log.printf("           %13.6lf %13.6lf %13.6lf\n",Rotation[1][0],Rotation[1][1],Rotation[1][2] );
+     248             :       log.printf("           %13.6lf %13.6lf %13.6lf\n",Rotation[2][0],Rotation[2][1],Rotation[2][2] );
+     249             :   */
+     250             : 
+     251             :   // the position is   Rot(ligand-com_prot_md)+ com_prot_ref
+     252         150 :   Vector ligand_centered =getPositions().back()-centerpositions;
+     253         150 :   Vector ligand_aligned =matmul(Rotation,ligand_centered);
+     254         150 :   Vector v = ligand_aligned +centerreference -p1;
+     255             : 
+     256             :   // DEBUG
+     257             : //    log.printf(" ligando: %13.6lf %13.6lf %13.6lf\n",getPositions().back()[0],getPositions().back()[1],getPositions().back()[2] );
+     258             : 
+     259             :   //Projection vector v onto s
+     260             : 
+     261         150 :   Vector prj = (dotProduct(s,v)/dotProduct(s,s))*s;
+     262         150 :   const double prj_length = prj.modulo() ;
+     263             :   const double inv_prj_length = 1.0/prj_length;
+     264             : 
+     265         150 :   Vector height = v - prj;
+     266         150 :   const double prj_height = height.modulo() ;
+     267         150 :   const double inv_prj_height = 1.0/prj_height;
+     268             : 
+     269             :   // derivative of the prj: only on the com of the ligand
+     270         150 :   Vector der_prj;
+     271         150 :   der_prj=s/s.modulo();
+     272             : 
+     273             :   // derivative of the height: only on the com of the ligand
+     274         150 :   Vector der_height(inv_prj_height*(height[0]-(s[0]/s.modulo2())*dotProduct(height,s)),
+     275         150 :                     inv_prj_height*(height[1]-(s[1]/s.modulo2())*dotProduct(height,s)),
+     276         150 :                     inv_prj_height*(height[2]-(s[2]/s.modulo2())*dotProduct(height,s)));
+     277             : 
+     278         150 :   Value* valuelp=getPntrToComponent("lp");
+     279         150 :   Value* valueld=getPntrToComponent("ld");
+     280         150 :   valuelp->set(dotProduct(s,v)/s.modulo()); // this includes the sign
+     281             :   valueld->set(prj_height);
+     282             : 
+     283             :   // DEBUG
+     284             : //    log.printf(" Dopo: %13.6lf  %13.6lf\n",dotProduct(s,v)/s.modulo(),prj_height );
+     285             : 
+     286         150 :   setAtomsDerivatives(valuelp,getNumberOfAtoms()-1,matmul(transpose(Rotation),der_prj));
+     287         150 :   setAtomsDerivatives(valueld,getNumberOfAtoms()-1,matmul(transpose(Rotation),der_height));
+     288             : 
+     289         150 :   Vector der_h;
+     290         150 :   Vector der_l;
+     291         150 :   double weight=1./float(getNumberOfAtoms()-2.);
+     292             : 
+     293      485850 :   for(unsigned iat=0; iat<getNumberOfAtoms()-2; iat++) {
+     294      485700 :     der_h.zero();
+     295      485700 :     der_l.zero();
+     296     1942800 :     for(unsigned a=0; a<3; a++) {
+     297     5828400 :       for(unsigned b=0; b<3; b++) {
+     298    17485200 :         for(unsigned g=0; g<3; g++) {
+     299    13113900 :           der_h[a]+=der_height[b]*drotdpos[b][g][iat][a]*ligand_centered[g];
+     300    13113900 :           der_l[a]+=der_prj[b]*drotdpos[b][g][iat][a]*ligand_centered[g];
+     301             :         }
+     302     4371300 :         der_h[a]-=der_height[b]*Rotation[b][a]*weight;
+     303     4371300 :         der_l[a]-=der_prj[b]*Rotation[b][a]*weight;
+     304             :       }
+     305             :     }
+     306      485700 :     setAtomsDerivatives(valuelp,iat,der_l);
+     307      485700 :     setAtomsDerivatives(valueld,iat,der_h);
+     308             :   }
+     309             : 
+     310         150 :   setBoxDerivativesNoPbc(valuelp);
+     311         150 :   setBoxDerivativesNoPbc(valueld);
+     312             : 
+     313         150 : }
+     314             : 
+     315             : }
+     316             : }
+     317             : 
+     318             : 
+     319             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/Funnel.cpp.func-sort-c.html b/coverage/funnel/Funnel.cpp.func-sort-c.html new file mode 100644 index 000000000000..9332c98a84f5 --- /dev/null +++ b/coverage/funnel/Funnel.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - funnel/Funnel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - Funnel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15215399.3 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel6FunnelC2ERKNS_13ActionOptionsE0
_ZN4PLMD6funnel6Funnel10createBIASERKdS3_S3_S3_S3_S3_S3_S3_S3_RKbS3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_3
_ZN4PLMD6funnel6FunnelC1ERKNS_13ActionOptionsE4
_ZN4PLMD6funnel6Funnel16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6funnel6Funnel9calculateEv120
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/Funnel.cpp.func.html b/coverage/funnel/Funnel.cpp.func.html new file mode 100644 index 000000000000..8202b8058ecd --- /dev/null +++ b/coverage/funnel/Funnel.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - funnel/Funnel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - Funnel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15215399.3 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6funnel6Funnel10createBIASERKdS3_S3_S3_S3_S3_S3_S3_S3_RKbS3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_3
_ZN4PLMD6funnel6Funnel16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD6funnel6Funnel9calculateEv120
_ZN4PLMD6funnel6FunnelC1ERKNS_13ActionOptionsE4
_ZN4PLMD6funnel6FunnelC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/Funnel.cpp.gcov.html b/coverage/funnel/Funnel.cpp.gcov.html new file mode 100644 index 000000000000..da90c5a4dba9 --- /dev/null +++ b/coverage/funnel/Funnel.cpp.gcov.html @@ -0,0 +1,529 @@ + + + + + + + + LCOV - plumed test coverage - funnel/Funnel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnel - Funnel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15215399.3 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2019-2020
+       3             : 
+       4             :    This file is part of funnel code module.
+       5             : 
+       6             :    The FM code respects the CC BY-NC license.
+       7             :    Users are free to download, adapt and use the code as long as it is not for commercial purposes.
+       8             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+       9             : #include "bias/Bias.h"
+      10             : #include "core/ActionRegister.h"
+      11             : #include "tools/Grid.h"
+      12             : #include "tools/Exception.h"
+      13             : #include "tools/File.h"
+      14             : #include <cstring>
+      15             : #include "tools/Communicator.h"
+      16             : #include "core/ActionSet.h"
+      17             : #include "tools/FileBase.h"
+      18             : #include <memory>
+      19             : #include "core/PlumedMain.h"
+      20             : 
+      21             : using namespace std;
+      22             : using namespace PLMD::bias;
+      23             : 
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace funnel {
+      27             : 
+      28             : //+PLUMEDOC FUNNELMOD_BIAS FUNNEL
+      29             : /*
+      30             : Calculate a funnel-shape restraint potential that is defined on a grid that is read during the setup.
+      31             : 
+      32             : If the input file is not already present, it will create one with the name specified in the FILE flag.
+      33             : The potential has a two-dimensional resolution since it has been devised to be used with the two
+      34             : components of \ref FUNNEL_PS (i.e., fps.lp and fps.ld) and it is divided in two sections, a cone shape
+      35             : attached to a cylindrical one. The user can customize the shape of both the sections by modifying a
+      36             : number of flags. In particular the cone section of the funnel is calculated with the following formula:
+      37             : 
+      38             : \f[
+      39             : MAX_Z=R_{cyl} + tg_{alpha} * (z_{cc} - MIN_S)
+      40             : \f]
+      41             : 
+      42             : where  \f$ MAX_Z \f$ is the radius of the cone base,  \f$ R_{cyl} \f$ is the radius of the cylinder part,
+      43             : \f$ tg_{alpha} \f$ is the angle regulating how steep the cone is, \f$ z_{cc} \f$ is the switching point
+      44             : between cone and cylinder, and \f$ MIN_S \f$ is the lowest possible value assumed by fps.lp of \ref FUNNEL_PS.
+      45             : As for the cylinder, it starts from the value of \f$ z_{cc} \f$ and stops at the value of \f$ MAX_S \f$
+      46             : with a section of \f$ pi*r_{cyl}^2 \f$.
+      47             : 
+      48             : There is the option of transforming the cone region into a sphere with the use of the SPHERE flag. In this
+      49             : case, the new shape will have a radius of \f$ z_{cc} \f$. It might be necessary tuning the SAFETY option
+      50             : to select how much the potential extends from the sphere.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The following is an input for a calculation with a funnel potential that is defined in the file BIAS
+      55             : and that acts on the collective variables defined by FUNNEL_PS.
+      56             : \plumedfile
+      57             : lig: COM ATOMS=3221,3224,3225,3228,3229,3231,3233,3235,3237
+      58             : fps: FUNNEL_PS LIGAND=lig REFERENCE=start.pdb ANCHOR=2472 POINTS=4.724,5.369,4.069,4.597,5.721,4.343
+      59             : 
+      60             : FUNNEL ARG=fps.lp,fps.ld ZCC=1.8 ALPHA=0.55 RCYL=0.1 MINS=-0.5 MAXS=3.7 KAPPA=35100 NBINS=500 NBINZ=500 FILE=BIAS LABEL=funnel
+      61             : \endplumedfile
+      62             : 
+      63             : The BIAS will then look something like this:
+      64             : \auxfile{BIAS}
+      65             : #! FIELDS fps.lp fps.ld funnel.bias der_fps.lp der_fps.ld
+      66             : #! SET min_fps.lp -0.500000
+      67             : #! SET max_fps.lp 3.700000
+      68             : #! SET nbins_fps.lp 500.000000
+      69             : #! SET periodic_fps.lp false
+      70             : #! SET min_fps.ld 0.000000
+      71             : #! SET max_fps.ld 1.510142
+      72             : #! SET nbins_fps.ld 500.000000
+      73             : #! SET periodic_fps.ld false
+      74             :     -0.500000      0.000000      0.000000      0.000000      0.000000
+      75             :     -0.500000      0.003020      0.000000      0.000000      0.000000
+      76             :     -0.500000      0.006041      0.000000      0.000000      0.000000
+      77             :     -0.500000      0.009061      0.000000      0.000000      0.000000
+      78             :     -0.500000      0.012081      0.000000      0.000000      0.000000
+      79             :     -0.500000      0.015101      0.000000      0.000000      0.000000
+      80             : \endauxfile
+      81             : 
+      82             : The Funnel potential should always be used in combination with the collective variable  \ref FUNNEL_PS, since it
+      83             : is constructed to take as inputs fps.lp and fps.ld (the former linepos and linedist of Funnel-Metadynamics
+      84             : \cite FM).  In the first block of data the value of fps.lp (the value in the first column) is kept fixed
+      85             : and the value of the function is given at 500 equally spaced values for fps.ld between 0 and 1.51. In
+      86             : the second block of data fps.lp is fixed at \f$-0.5 + \frac{4.2}{500}\f$ and the value of the function
+      87             : is given at 500 equally spaced values for fps.ld between 0 and 1.51. In the third block of data the same
+      88             : is done but fps.lp is fixed at \f$-0.5 + \frac{8.4}{100}\f$ and so on until you get to the five hundredth
+      89             : block of data where fps.lp is fixed at \f$3.7\f$.
+      90             : 
+      91             : It is possible to switch the shape of the cone region, transforming it in a sphere, with the flag SPHERE.
+      92             : \plumedfile
+      93             : lig: COM ATOMS=545,546,547,548,549,550,551,552,553
+      94             : fps: FUNNEL_PS LIGAND=lig REFERENCE=ref.pdb ANCHOR=52 POINTS=2.793,3.696,3.942,3.607,4.298,3.452
+      95             : 
+      96             : FUNNEL ARG=fps.lp,fps.ld ZCC=4.0 RCYL=0.1 MINS=0.2 MAXS=4.9 KAPPA=100000 NBINS=500 NBINZ=500 SPHERE SAFETY=1.0 FILE=BIAS LABEL=funnel
+      97             : \endplumedfile
+      98             : 
+      99             : */
+     100             : //+ENDPLUMEDOC
+     101             : class Funnel : public Bias {
+     102             : 
+     103             : private:
+     104             :   std::unique_ptr<GridBase> BiasGrid_;
+     105             : 
+     106             :   /////////////////////
+     107             :   // old 2.3
+     108             :   //Grid* BiasGrid_;
+     109             :   /////////////////////
+     110             :   //Optional parameters
+     111             :   double NBINS;
+     112             :   double NBINZ;
+     113             :   double MINS;
+     114             :   double KAPPA;
+     115             :   double RCYL;
+     116             :   double safety;
+     117             :   double slope;
+     118             :   double ALPHA;
+     119             :   //Compulsory parameters
+     120             :   double MAXS;
+     121             :   double ZCC;
+     122             :   double scale_;
+     123             : 
+     124             : 
+     125             : public:
+     126             :   explicit Funnel(const ActionOptions&);
+     127             : 
+     128             :   // old Funnel-2.3
+     129             :   // ~Funnel();
+     130             : 
+     131             :   void calculate();
+     132             :   static void registerKeywords(Keywords& keys);
+     133             :   void createBIAS(const double& R_cyl, const double& z_cc, const double& alpha, const double& KAPPA,
+     134             :                   const double& MIN_S, const double& MAX_S, const double& NBIN_S, const double& NBIN_Z,
+     135             :                   const double& safety, const bool& sphere, const double& slope, const string& funcl,
+     136             :                   const string& file);
+     137             : //  void createBIAS3D(const double& R_cyl, const double& z_cc, const double& alpha,
+     138             : //                      const double& KAPPA, const double& MIN_S, const double& MAX_S, const double& NBIN_S,
+     139             : //                      const double& NBIN_Z, const double& safety, const bool& sphere, const double& slope,
+     140             : //                      const string& funcl);
+     141             : };
+     142             : 
+     143             : PLUMED_REGISTER_ACTION(Funnel,"FUNNEL")
+     144             : 
+     145           6 : void Funnel::registerKeywords(Keywords& keys) {
+     146           6 :   Bias::registerKeywords(keys);
+     147           6 :   keys.use("ARG");
+     148          12 :   keys.addFlag("NOSPLINE",false,"specifies that no spline interpolation is to be used when calculating the energy and forces due to the external potential");
+     149          12 :   keys.addFlag("SPARSE",false,"specifies that the external potential uses a sparse grid");
+     150          12 :   keys.addFlag("SPHERE",false, "The Funnel potential including the binding site can be spherical instead of a cone");
+     151          12 :   keys.add("compulsory","SCALE","1.0","a factor that multiplies the external potential, useful to invert free energies");
+     152             : // old stuff?
+     153             :   //  componentsAreNotOptional(keys);
+     154             :   //  keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+     155             : 
+     156             :   //Defining optional arguments
+     157          12 :   keys.add("optional","NBINS","number of bins along fps.lp");
+     158          12 :   keys.add("optional","NBINZ","number of bins along fps.ld");
+     159          12 :   keys.add("optional","MINS","minimum value assumed by fps.lp, if the ligand is able to go beyond this value the simulation will crash");
+     160          12 :   keys.add("optional","KAPPA","constant to be used for the funnel-shape restraint potential");
+     161          12 :   keys.add("optional","RCYL","radius of the cylindrical section");
+     162          12 :   keys.add("optional","SAFETY","To be used in case the SPHERE flag is chosen, it regulates how much the potential extends (in nm)");
+     163          12 :   keys.add("optional","SLOPE","Adjust the behavior of the potential outside the funnel, greater values than 1.0 will tend to push the ligand more towards the cylinder and vice versa");
+     164          12 :   keys.add("optional","ALPHA","angle to change the width of the cone section");
+     165             :   //Defining compulsory arguments
+     166          12 :   keys.add("compulsory","MAXS","MAXS","maximum value assumed by fps.lp");
+     167          12 :   keys.add("compulsory","ZCC","ZCC","switching point between cylinder and cone");
+     168          12 :   keys.add("compulsory","FILE","name of the Funnel potential file");
+     169          12 :   keys.addFlag("WALKERS_MPI",false,"To be used when gromacs + multiple walkers are used");
+     170           6 : }
+     171             : 
+     172             : // Old version 2.3
+     173             : //Funnel::~Funnel(){
+     174             : //  delete BiasGrid_;
+     175             : //}
+     176             : 
+     177           4 : Funnel::Funnel(const ActionOptions& ao):
+     178             :   PLUMED_BIAS_INIT(ao),
+     179             : // Old version 2.3
+     180             : // BiasGrid_(NULL),
+     181           4 :   NBINS(500.0),
+     182           4 :   NBINZ(500.0),
+     183           4 :   MINS(0.0),
+     184           4 :   KAPPA(84.0),
+     185           4 :   RCYL(0.1),
+     186           4 :   safety(1.0),
+     187           4 :   slope(1.0),
+     188           4 :   ALPHA(1.413)
+     189             : 
+     190             : {
+     191           4 :   bool sparsegrid=false;
+     192           4 :   parseFlag("SPARSE",sparsegrid);
+     193           4 :   bool nospline=false;
+     194           4 :   parseFlag("NOSPLINE",nospline);
+     195           4 :   bool spline=!nospline;
+     196           4 :   bool walkers_mpi=false;
+     197           4 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     198             : //  bool components=false;
+     199             : //  parseFlag("POINTS",components);
+     200           4 :   bool sphere=false;
+     201           4 :   parseFlag("SPHERE",sphere);
+     202           8 :   parse("SAFETY",safety);
+     203             :   string file;
+     204           8 :   parse("FILE",file);
+     205           4 :   if( file.length()==0 ) error("No funnel file name was specified");
+     206           4 :   parse("SCALE",scale_);
+     207             : 
+     208             :   //Reading optional arguments
+     209           4 :   parse("KAPPA",KAPPA);
+     210           4 :   parse("NBINS",NBINS);
+     211           4 :   parse("NBINZ",NBINZ);
+     212           4 :   parse("MINS",MINS);
+     213           4 :   parse("RCYL",RCYL);
+     214           4 :   parse("SLOPE",slope);
+     215           4 :   parse("ALPHA",ALPHA);
+     216             :   //Reading compulsory arguments
+     217           4 :   parse("MAXS",MAXS);
+     218           4 :   parse("ZCC",ZCC);
+     219             : 
+     220             : 
+     221           4 :   checkRead();
+     222             : 
+     223           4 :   log.printf("  External potential from file %s\n",file.c_str());
+     224           4 :   log.printf("  Multiplied by %lf\n",scale_);
+     225           4 :   if(spline) {
+     226           4 :     log.printf("  External potential uses spline interpolation\n");
+     227             :   }
+     228           4 :   if(sparsegrid) {
+     229           0 :     log.printf("  External potential uses sparse grid\n");
+     230             :   }
+     231             : 
+     232             :   // Non più necessario dalla 2.3
+     233             : //  addComponent("bias"); componentIsNotPeriodic("bias");
+     234             : 
+     235           4 :   std::string funcl=getLabel() + ".bias";
+     236             : 
+     237             : //  int size = plumed.comm.Get_size();
+     238             : //  int rank = plumed.comm.Get_rank();
+     239           4 :   IFile I_hate_this;
+     240           4 :   bool do_exist=I_hate_this.FileExist(file);
+     241             : 
+     242           4 :   if(walkers_mpi) {
+     243           2 :     if(comm.Get_rank()==0 && multi_sim_comm.Get_rank()==0) {
+     244           1 :       if(!do_exist) {
+     245           1 :         createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     246             :       }
+     247             :     }
+     248           2 :     multi_sim_comm.Barrier();
+     249             :   } else {
+     250           2 :     if(comm.Get_rank()==0) {
+     251           2 :       if(!do_exist) {
+     252           2 :         createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     253             :       }
+     254             :     }
+     255             :   }
+     256             : 
+     257             :   /*
+     258             :   if(comm.Get_rank()==0){
+     259             :     if(multi_sim_comm.Get_rank()==0 && walkers_mpi){
+     260             :           if(!do_exist){
+     261             :                   createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     262             :           }
+     263             :     } else {
+     264             :           if(!do_exist){
+     265             :                   createBIAS(RCYL, ZCC, ALPHA, KAPPA, MINS, MAXS, NBINS, NBINZ, safety, sphere, slope, funcl, file);
+     266             :           }
+     267             :     }
+     268             :     if(walkers_mpi) multi_sim_comm.Barrier();
+     269             :   }
+     270             :   */
+     271           4 :   comm.Barrier();
+     272             : 
+     273             : // read grid
+     274           4 :   IFile gridfile;
+     275           4 :   gridfile.open(file);
+     276           8 :   BiasGrid_=Grid::create(funcl,getArguments(),gridfile,sparsegrid,spline,true);
+     277             : //not necessary anymore?  gridfile.close();
+     278           4 :   if(BiasGrid_->getDimension()!=getNumberOfArguments()) error("mismatch between dimensionality of input grid and number of arguments");
+     279          12 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     280          16 :     if( getPntrToArgument(i)->isPeriodic()!=BiasGrid_->getIsPeriodic()[i] ) error("periodicity mismatch between arguments and input bias");
+     281             :   }
+     282           4 :   comm.Barrier();
+     283           4 :   if(comm.Get_rank()==0 && walkers_mpi) multi_sim_comm.Barrier();
+     284           8 :   log<<"  Bibliography "<<plumed.cite("Limongelli, Bonomi, and Parrinello, PNAS 110, 6358 (2013)")<<"\n";
+     285           8 : }
+     286             : 
+     287             : 
+     288           3 : void Funnel::createBIAS(const double& R_cyl, const double& z_cc, const double& alpha,
+     289             :                         const double& KAPPA, const double& MIN_S, const double& MAX_S, const double& NBIN_S,
+     290             :                         const double& NBIN_Z, const double& safety, const bool& sphere, const double& slope,
+     291             :                         const string& funcl, const string& file) {
+     292             :   //R_cyl and z_cc forms the parameters of the cylinder.
+     293             :   //alpha defines the angle in degrees.
+     294             : 
+     295             :   //PARAMETERS OF THE CONE
+     296           3 :   double tg_alpha= tan(alpha);
+     297             : 
+     298             :   //parameters for PROGRESSION
+     299             :   //parameters for DISTANCE
+     300             :   double MIN_Z=0;
+     301             :   double MAX_Z;
+     302           3 :   if (sphere==false) {
+     303           2 :     MAX_Z=R_cyl + tg_alpha * (z_cc - MIN_S);
+     304             :   }
+     305             :   else {
+     306           1 :     MAX_Z=z_cc+safety;
+     307             :   }
+     308             : 
+     309             :   //bin size
+     310           3 :   double DX_Z = (MAX_Z - MIN_Z) / NBIN_Z;
+     311             :   double DX_S;
+     312           3 :   if (sphere==false) {
+     313           2 :     DX_S=(MAX_S - MIN_S) / NBIN_S;
+     314             :   }
+     315             :   else {
+     316           1 :     DX_S=(MAX_S + z_cc + safety)/NBIN_S;
+     317             :   }
+     318             : 
+     319             :   double SS, Zmax, ZZ, D, d;
+     320             :   double POT, FZ, FS;
+     321             : 
+     322           3 :   PLMD::OFile pof;
+     323           3 :   pof.open(file);
+     324             : 
+     325             :   //Write the header
+     326           3 :   pof.printf("#! FIELDS %s %s %s der_%s der_%s \n", getPntrToArgument(0)->getName().c_str(), getPntrToArgument(1)->getName().c_str(), funcl.c_str(), getPntrToArgument(0)->getName().c_str(), getPntrToArgument(1)->getName().c_str());
+     327           3 :   if (sphere==false) pof.printf("#! SET min_%s %f\n", getPntrToArgument(0)->getName().c_str(), MIN_S);
+     328           1 :   else pof.printf("#! SET min_%s %f\n", getPntrToArgument(0)->getName().c_str(), -z_cc-safety);
+     329           3 :   pof.printf("#! SET max_%s %f\n", getPntrToArgument(0)->getName().c_str(), MAX_S);
+     330           3 :   pof.printf("#! SET nbins_%s %f\n", getPntrToArgument(0)->getName().c_str(), NBIN_S);
+     331           3 :   pof.printf("#! SET periodic_%s false\n", getPntrToArgument(0)->getName().c_str());
+     332           3 :   pof.printf("#! SET min_%s %f\n", getPntrToArgument(1)->getName().c_str(), MIN_Z);
+     333           3 :   pof.printf("#! SET max_%s %f\n", getPntrToArgument(1)->getName().c_str(), MAX_Z);
+     334           3 :   pof.printf("#! SET nbins_%s %f\n", getPntrToArgument(1)->getName().c_str(), NBIN_Z);
+     335           3 :   pof.printf("#! SET periodic_%s false\n", getPntrToArgument(1)->getName().c_str());
+     336             : 
+     337             :   //Calculate and write the GRID
+     338             :   //Cone or cylinder?
+     339             : 
+     340        1506 :   for(int is=0; is <= NBIN_S; is++) {
+     341        1503 :     if (sphere==false) {
+     342        1002 :       SS = MIN_S + is * DX_S;
+     343             :     }
+     344             :     else {
+     345         501 :       SS = - z_cc - safety + is * DX_S;
+     346             :     }
+     347             :     bool cone = false;
+     348        1503 :     if (sphere==false) {
+     349        1002 :       if(SS <= z_cc) cone = true;
+     350             :     }
+     351             :     else {
+     352         501 :       if (SS <= sqrt(pow(z_cc,2)-pow(R_cyl,2))) cone = true;
+     353             :     }
+     354             :     //Set wall boundaries properly
+     355             :     if(cone == true) {
+     356         902 :       if(sphere==false) {
+     357         548 :         Zmax = R_cyl + (z_cc - SS) * tg_alpha;
+     358             :       }
+     359             :       else {
+     360         354 :         if (SS > -z_cc) {
+     361         277 :           Zmax = sqrt(pow(z_cc,2) - pow(SS,2));
+     362             :         }
+     363             :         else {
+     364             :           Zmax = 0;
+     365             :         }
+     366             :       }
+     367             :     }
+     368         601 :     else Zmax = R_cyl;
+     369             : 
+     370      754506 :     for(int iz=0; iz <= NBIN_Z; iz++) {
+     371      753003 :       ZZ = MIN_Z + iz * DX_Z;
+     372             : 
+     373             :       //Inside or outside?
+     374             :       bool inside;
+     375      753003 :       if(ZZ < Zmax) inside = true;
+     376             :       else inside = false;
+     377             : 
+     378             :       if(inside == true) {
+     379             :         POT = 0;
+     380             :         FS = 0;
+     381             :         FZ = 0;
+     382             :       }
+     383             :       else {
+     384      518149 :         if(cone == true) {
+     385      235130 :           if(sphere==false) {
+     386      127824 :             POT = 0.5 * KAPPA * (ZZ - Zmax) * (ZZ - Zmax);
+     387      127824 :             FZ = - KAPPA * (ZZ - Zmax);
+     388      127824 :             FS = - KAPPA * (ZZ - Zmax) * tg_alpha;
+     389             :           }
+     390             :           else {
+     391      107306 :             D = sqrt(pow(ZZ,2)+pow(SS,2));
+     392      107306 :             d = D - z_cc;
+     393      107306 :             POT = 0.5 * KAPPA * pow(d,2);
+     394      107306 :             FZ = - KAPPA * d * ZZ / D;
+     395      107306 :             FS = - KAPPA * d * SS / D;
+     396             :           }
+     397             :         }
+     398             :         else {
+     399      283019 :           if(sphere==false) {
+     400      212018 :             POT = 0.5 * KAPPA * (ZZ - Zmax) * (ZZ - Zmax);
+     401      212018 :             FZ = - KAPPA * (ZZ - Zmax);
+     402             :             FS = 0;
+     403             :           }
+     404             :           else {
+     405       71001 :             D = sqrt(pow(ZZ,2)+pow(SS,2));
+     406       71001 :             d = D - z_cc;
+     407       71001 :             if(ZZ>=R_cyl+slope*(SS-z_cc)) {
+     408       45984 :               POT = 0.5 * KAPPA * pow(d,2);
+     409       45984 :               FZ = - KAPPA * d * ZZ / D;
+     410       45984 :               FS = - KAPPA * d * SS / D;
+     411             :             }
+     412             :             else {
+     413       25017 :               POT = 0.5 * KAPPA * pow(sqrt(pow((ZZ+slope*z_cc-R_cyl)/slope,2)+pow(ZZ,2))-
+     414             :                                       z_cc,2);
+     415       25017 :               FZ = - KAPPA*(sqrt(pow((ZZ+slope*z_cc-R_cyl)/slope,2)+pow(ZZ,2))-z_cc)*
+     416       25017 :                    ZZ/sqrt(pow((ZZ+slope*z_cc-R_cyl)/slope,2)+pow(ZZ,2));
+     417             :               FS = 0;
+     418             :             }
+     419             :           }
+     420             :         }
+     421             :       }
+     422      753003 :       pof.printf("%13.6lf %13.6lf %13.6lf %13.6lf %13.6lf\n", SS, ZZ, POT, FS, FZ);
+     423             :     }
+     424        1503 :     pof.printf("\n");
+     425             :   }
+     426           3 :   pof.close();
+     427           3 : }
+     428             : 
+     429         120 : void Funnel::calculate()
+     430             : {
+     431         120 :   unsigned ncv=getNumberOfArguments();
+     432         120 :   vector<double> cv(ncv), der(ncv);
+     433             : 
+     434         360 :   for(unsigned i=0; i<ncv; ++i) {
+     435         240 :     cv[i]=getArgument(i);
+     436             :   }
+     437             : 
+     438             : //  log.printf("  In Funnel: %13.6lf  %13.6lf\n", cv[0], cv[1]);
+     439             : 
+     440         120 :   double ene=scale_*BiasGrid_->getValueAndDerivatives(cv,der);
+     441             : 
+     442         120 :   setBias(ene);
+     443             : 
+     444             : // set Forces
+     445         360 :   for(unsigned i=0; i<ncv; ++i) {
+     446         240 :     const double f=-scale_*der[i];
+     447         240 :     setOutputForce(i,f);
+     448             :   }
+     449         120 : }
+     450             : 
+     451             : }
+     452             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/index-sort-f.html b/coverage/funnel/index-sort-f.html new file mode 100644 index 000000000000..da773e93982c --- /dev/null +++ b/coverage/funnel/index-sort-f.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24725298.0 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FPS.cpp +
96.0%96.0%
+
96.0 %95 / 9975.0 %3 / 4
Funnel.cpp +
99.3%99.3%
+
99.3 %152 / 15380.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/index-sort-l.html b/coverage/funnel/index-sort-l.html new file mode 100644 index 000000000000..61e6913cb1d8 --- /dev/null +++ b/coverage/funnel/index-sort-l.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24725298.0 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FPS.cpp +
96.0%96.0%
+
96.0 %95 / 9975.0 %3 / 4
Funnel.cpp +
99.3%99.3%
+
99.3 %152 / 15380.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/funnel/index.html b/coverage/funnel/index.html new file mode 100644 index 000000000000..2e23ebd9df5f --- /dev/null +++ b/coverage/funnel/index.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - funnel + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - funnelHitTotalCoverage
Test:plumed test coverageLines:24725298.0 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FPS.cpp +
96.0%96.0%
+
96.0 %95 / 9975.0 %3 / 4
Funnel.cpp +
99.3%99.3%
+
99.3 %152 / 15380.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gcov.css b/coverage/gcov.css new file mode 100644 index 000000000000..0fcdff13cea9 --- /dev/null +++ b/coverage/gcov.css @@ -0,0 +1,519 @@ +/* All views: initial background and text color */ +body +{ + color: #000000; + background-color: #ffffff; +} + +/* All views: standard link format*/ +a:link +{ + color: #284fa8; + text-decoration: underline; +} + +/* All views: standard link - visited format */ +a:visited +{ + color: #00cb40; + text-decoration: underline; +} + +/* All views: standard link - activated format */ +a:active +{ + color: #ff0040; + text-decoration: underline; +} + +/* All views: main title format */ +td.title +{ + text-align: center; + padding-bottom: 10px; + font-family: sans-serif; + font-size: 20pt; + font-style: italic; + font-weight: bold; +} + +/* All views: header item format */ +td.headerItem +{ + text-align: right; + padding-right: 6px; + font-family: sans-serif; + font-weight: bold; + vertical-align: top; + white-space: nowrap; +} + +/* All views: header item value format */ +td.headerValue +{ + text-align: left; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; +} + +/* All views: header item coverage table heading */ +td.headerCovTableHead +{ + text-align: center; + padding-right: 6px; + padding-left: 6px; + padding-bottom: 0px; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; +} + +/* All views: header item coverage table entry */ +td.headerCovTableEntry +{ + text-align: right; + color: #284fa8; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #dae7fe; +} + +/* All views: header item coverage table entry for high coverage rate */ +td.headerCovTableEntryHi +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #a7fc9d; +} + +/* All views: header item coverage table entry for medium coverage rate */ +td.headerCovTableEntryMed +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ffea20; +} + +/* All views: header item coverage table entry for ow coverage rate */ +td.headerCovTableEntryLo +{ + text-align: right; + color: #000000; + font-family: sans-serif; + font-weight: bold; + white-space: nowrap; + padding-left: 12px; + padding-right: 4px; + background-color: #ff0000; +} + +/* All views: header legend value for legend entry */ +td.headerValueLeg +{ + text-align: left; + color: #000000; + font-family: sans-serif; + font-size: 80%; + white-space: nowrap; + padding-top: 4px; +} + +/* All views: color of horizontal ruler */ +td.ruler +{ + background-color: #6688d4; +} + +/* All views: version string format */ +td.versionInfo +{ + text-align: center; + padding-top: 2px; + font-family: sans-serif; + font-style: italic; +} + +/* Directory view/File view (all)/Test case descriptions: + table headline format */ +td.tableHead +{ + text-align: center; + color: #ffffff; + background-color: #6688d4; + font-family: sans-serif; + font-size: 120%; + font-weight: bold; + white-space: nowrap; + padding-left: 4px; + padding-right: 4px; +} + +span.tableHeadSort +{ + padding-right: 4px; +} + +/* Directory view/File view (all): filename entry format */ +td.coverFile +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Directory view/File view (all): bar-graph entry format*/ +td.coverBar +{ + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; +} + +/* Directory view/File view (all): bar-graph outline color */ +td.coverBarOutline +{ + background-color: #000000; +} + +/* Directory view/File view (all): percentage entry for files with + high coverage rate */ +td.coverPerHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + high coverage rate */ +td.coverNumHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #a7fc9d; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + medium coverage rate */ +td.coverPerMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + medium coverage rate */ +td.coverNumMed +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ffea20; + white-space: nowrap; + font-family: sans-serif; +} + +/* Directory view/File view (all): percentage entry for files with + low coverage rate */ +td.coverPerLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Directory view/File view (all): line count entry for files with + low coverage rate */ +td.coverNumLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + white-space: nowrap; + font-family: sans-serif; +} + +/* File view (all): "show/hide details" link format */ +a.detail:link +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - visited format */ +a.detail:visited +{ + color: #B8D0FF; + font-size:80%; +} + +/* File view (all): "show/hide details" link - activated format */ +a.detail:active +{ + color: #ffffff; + font-size:80%; +} + +/* File view (detail): test name entry */ +td.testName +{ + text-align: right; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test percentage entry */ +td.testPer +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* File view (detail): test lines count entry */ +td.testNum +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-family: sans-serif; +} + +/* Test case descriptions: test name format*/ +dt +{ + font-family: sans-serif; + font-weight: bold; +} + +/* Test case descriptions: description table body */ +td.testDescription +{ + padding-top: 10px; + padding-left: 30px; + padding-bottom: 10px; + padding-right: 30px; + background-color: #dae7fe; +} + +/* Source code view: function entry */ +td.coverFn +{ + text-align: left; + padding-left: 10px; + padding-right: 20px; + color: #284fa8; + background-color: #dae7fe; + font-family: monospace; +} + +/* Source code view: function entry zero count*/ +td.coverFnLo +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #ff0000; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: function entry nonzero count*/ +td.coverFnHi +{ + text-align: right; + padding-left: 10px; + padding-right: 10px; + background-color: #dae7fe; + font-weight: bold; + font-family: sans-serif; +} + +/* Source code view: source code format */ +pre.source +{ + font-family: monospace; + white-space: pre; + margin-top: 2px; +} + +/* Source code view: line number format */ +span.lineNum +{ + background-color: #efe383; +} + +/* Source code view: format for lines which were executed */ +td.lineCov, +span.lineCov +{ + background-color: #cad7fe; +} + +/* Source code view: format for Cov legend */ +span.coverLegendCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #cad7fe; +} + +/* Source code view: format for lines which were not executed */ +td.lineNoCov, +span.lineNoCov +{ + background-color: #ff6230; +} + +/* Source code view: format for NoCov legend */ +span.coverLegendNoCov +{ + padding-left: 10px; + padding-right: 10px; + padding-bottom: 2px; + background-color: #ff6230; +} + +/* Source code view (function table): standard link - visited format */ +td.lineNoCov > a:visited, +td.lineCov > a:visited +{ + color: #000000; + text-decoration: underline; +} + +/* Source code view: format for lines which were executed only in a + previous version */ +span.lineDiffCov +{ + background-color: #b5f7af; +} + +/* Source code view: format for branches which were executed + * and taken */ +span.branchCov +{ + background-color: #cad7fe; +} + +/* Source code view: format for branches which were executed + * but not taken */ +span.branchNoCov +{ + background-color: #ff6230; +} + +/* Source code view: format for branches which were not executed */ +span.branchNoExec +{ + background-color: #ff6230; +} + +/* Source code view: format for the source code heading line */ +pre.sourceHeading +{ + white-space: pre; + font-family: monospace; + font-weight: bold; + margin: 0px; +} + +/* All views: header legend value for low rate */ +td.headerValueLegL +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 4px; + padding-right: 2px; + background-color: #ff0000; + font-size: 80%; +} + +/* All views: header legend value for med rate */ +td.headerValueLegM +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 2px; + background-color: #ffea20; + font-size: 80%; +} + +/* All views: header legend value for hi rate */ +td.headerValueLegH +{ + font-family: sans-serif; + text-align: center; + white-space: nowrap; + padding-left: 2px; + padding-right: 4px; + background-color: #a7fc9d; + font-size: 80%; +} + +/* All views except source code view: legend format for low coverage */ +span.coverLegendCovLo +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ff0000; +} + +/* All views except source code view: legend format for med coverage */ +span.coverLegendCovMed +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #ffea20; +} + +/* All views except source code view: legend format for hi coverage */ +span.coverLegendCovHi +{ + padding-left: 10px; + padding-right: 10px; + padding-top: 2px; + background-color: #a7fc9d; +} diff --git a/coverage/generic/Debug.cpp.func-sort-c.html b/coverage/generic/Debug.cpp.func-sort-c.html new file mode 100644 index 000000000000..9869138a80ec --- /dev/null +++ b/coverage/generic/Debug.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Debug.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Debug.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5DebugC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5DebugC1ERKNS_13ActionOptionsE6
_ZN4PLMD7generic5Debug16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7generic5Debug5applyEv140
_ZN4PLMD7generic5Debug9calculateEv140
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Debug.cpp.func.html b/coverage/generic/Debug.cpp.func.html new file mode 100644 index 000000000000..e1beb7e9f011 --- /dev/null +++ b/coverage/generic/Debug.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Debug.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Debug.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5Debug16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7generic5Debug5applyEv140
_ZN4PLMD7generic5Debug9calculateEv140
_ZN4PLMD7generic5DebugC1ERKNS_13ActionOptionsE6
_ZN4PLMD7generic5DebugC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Debug.cpp.gcov.html b/coverage/generic/Debug.cpp.gcov.html new file mode 100644 index 000000000000..943788bcfcd2 --- /dev/null +++ b/coverage/generic/Debug.cpp.gcov.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - generic/Debug.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Debug.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5656100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "core/PlumedMain.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace generic {
+      29             : 
+      30             : //+PLUMEDOC GENERIC DEBUG
+      31             : /*
+      32             : Set some debug options.
+      33             : 
+      34             : Can be used while debugging or optimizing plumed.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : \plumedfile
+      39             : # print detailed (action-by-action) timers at the end of simulation
+      40             : DEBUG DETAILED_TIMERS
+      41             : # dump every two steps which are the atoms required from the MD code
+      42             : DEBUG logRequestedAtoms STRIDE=2
+      43             : \endplumedfile
+      44             : 
+      45             : */
+      46             : //+ENDPLUMEDOC
+      47             : class Debug:
+      48             :   public ActionPilot
+      49             : {
+      50             :   OFile ofile;
+      51             :   bool logActivity;
+      52             :   bool logRequestedAtoms;
+      53             :   bool novirial;
+      54             :   bool detailedTimers;
+      55             : public:
+      56             :   explicit Debug(const ActionOptions&ao);
+      57             : /// Register all the relevant keywords for the action
+      58             :   static void registerKeywords( Keywords& keys );
+      59         140 :   void calculate() override {}
+      60             :   void apply() override;
+      61             : };
+      62             : 
+      63             : PLUMED_REGISTER_ACTION(Debug,"DEBUG")
+      64             : 
+      65           8 : void Debug::registerKeywords( Keywords& keys ) {
+      66           8 :   Action::registerKeywords( keys );
+      67           8 :   ActionPilot::registerKeywords(keys);
+      68          16 :   keys.add("compulsory","STRIDE","1","the frequency with which this action is to be performed");
+      69          16 :   keys.addFlag("logActivity",false,"write in the log which actions are inactive and which are inactive");
+      70          16 :   keys.addFlag("logRequestedAtoms",false,"write in the log which atoms have been requested at a given time");
+      71          16 :   keys.addFlag("NOVIRIAL",false,"switch off the virial contribution for the entirety of the simulation");
+      72          16 :   keys.addFlag("DETAILED_TIMERS",false,"switch on detailed timers");
+      73          16 :   keys.add("optional","FILE","the name of the file on which to output these quantities");
+      74           8 : }
+      75             : 
+      76           6 : Debug::Debug(const ActionOptions&ao):
+      77             :   Action(ao),
+      78             :   ActionPilot(ao),
+      79           6 :   logActivity(false),
+      80           6 :   logRequestedAtoms(false),
+      81           6 :   novirial(false) {
+      82           6 :   parseFlag("logActivity",logActivity);
+      83           6 :   if(logActivity) log.printf("  logging activity\n");
+      84           6 :   parseFlag("logRequestedAtoms",logRequestedAtoms);
+      85           6 :   if(logRequestedAtoms) log.printf("  logging requested atoms\n");
+      86           6 :   parseFlag("NOVIRIAL",novirial);
+      87           6 :   if(novirial) log.printf("  Switching off virial contribution\n");
+      88           6 :   if(novirial) plumed.novirial=true;
+      89           6 :   parseFlag("DETAILED_TIMERS",detailedTimers);
+      90           6 :   if(detailedTimers) {
+      91           2 :     log.printf("  Detailed timing on\n");
+      92           2 :     plumed.detailedTimers=true;
+      93             :   }
+      94           6 :   ofile.link(*this);
+      95             :   std::string file;
+      96          12 :   parse("FILE",file);
+      97           6 :   if(file.length()>0) {
+      98           2 :     ofile.open(file);
+      99           2 :     log.printf("  on file %s\n",file.c_str());
+     100             :   } else {
+     101           4 :     log.printf("  on plumed log file\n");
+     102           4 :     ofile.link(log);
+     103             :   }
+     104           6 :   checkRead();
+     105           6 : }
+     106             : 
+     107         140 : void Debug::apply() {
+     108         140 :   if(logActivity) {
+     109          10 :     const ActionSet&actionSet(plumed.getActionSet());
+     110             :     int a=0;
+     111         195 :     for(const auto & p : actionSet) {
+     112         185 :       if(dynamic_cast<Debug*>(p.get()))continue;
+     113         170 :       if(p->isActive()) a++;
+     114             :     };
+     115          10 :     if(a>0) {
+     116           9 :       ofile<<"activity at step "<<getStep()<<": ";
+     117         179 :       for(const auto & p : actionSet) {
+     118         170 :         if(dynamic_cast<Debug*>(p.get()))continue;
+     119         157 :         if(p->isActive()) ofile.printf("+");
+     120          36 :         else                 ofile.printf("-");
+     121             :       };
+     122           9 :       ofile.printf("\n");
+     123             :     };
+     124             :   };
+     125         140 :   if(logRequestedAtoms) {
+     126          17 :     ofile<<"requested atoms at step "<<getStep()<<": ";
+     127             :     const int* l;
+     128             :     int n;
+     129          17 :     plumed.cmd("createFullList",&n);
+     130          17 :     plumed.cmd("getFullList",&l);
+     131         213 :     for(int i=0; i<n; i++) ofile.printf(" %d",l[i]);
+     132          17 :     ofile.printf("\n");
+     133          17 :     plumed.cmd("clearFullList");
+     134             :   }
+     135             : 
+     136         140 : }
+     137             : 
+     138             : }
+     139             : }
+     140             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpAtoms.cpp.func-sort-c.html b/coverage/generic/DumpAtoms.cpp.func-sort-c.html new file mode 100644 index 000000000000..e78a8339fb41 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpAtoms.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpAtoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11711998.3 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9DumpAtomsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9DumpAtomsD2Ev0
_ZN4PLMD7generic9DumpAtomsC1ERKNS_13ActionOptionsE160
_ZN4PLMD7generic9DumpAtomsD0Ev160
_ZN4PLMD7generic9DumpAtomsD1Ev160
_ZN4PLMD7generic9DumpAtoms16registerKeywordsERNS_8KeywordsE162
_ZN4PLMD7generic9DumpAtoms6updateEv8730
_ZN4PLMD7generic9DumpAtoms5applyEv8825
_ZN4PLMD7generic9DumpAtoms9calculateEv8825
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpAtoms.cpp.func.html b/coverage/generic/DumpAtoms.cpp.func.html new file mode 100644 index 000000000000..41f144a900ea --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpAtoms.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpAtoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11711998.3 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9DumpAtoms16registerKeywordsERNS_8KeywordsE162
_ZN4PLMD7generic9DumpAtoms5applyEv8825
_ZN4PLMD7generic9DumpAtoms6updateEv8730
_ZN4PLMD7generic9DumpAtoms9calculateEv8825
_ZN4PLMD7generic9DumpAtomsC1ERKNS_13ActionOptionsE160
_ZN4PLMD7generic9DumpAtomsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9DumpAtomsD0Ev160
_ZN4PLMD7generic9DumpAtomsD1Ev160
_ZN4PLMD7generic9DumpAtomsD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpAtoms.cpp.gcov.html b/coverage/generic/DumpAtoms.cpp.gcov.html new file mode 100644 index 000000000000..3379bdac6591 --- /dev/null +++ b/coverage/generic/DumpAtoms.cpp.gcov.html @@ -0,0 +1,390 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpAtoms.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpAtoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11711998.3 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Pbc.h"
+      26             : #include "tools/File.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "tools/Units.h"
+      29             : #include <cstdio>
+      30             : #include <memory>
+      31             : #include "core/GenericMolInfo.h"
+      32             : #include "core/ActionSet.h"
+      33             : #include "xdrfile/xdrfile_xtc.h"
+      34             : #include "xdrfile/xdrfile_trr.h"
+      35             : 
+      36             : 
+      37             : namespace PLMD
+      38             : {
+      39             : namespace generic {
+      40             : 
+      41             : //+PLUMEDOC PRINTANALYSIS DUMPATOMS
+      42             : /*
+      43             : Dump selected atoms on a file.
+      44             : 
+      45             : This command can be used to output the positions of a particular set of atoms.
+      46             : The atoms required are output in a xyz or gro formatted file.
+      47             : If PLUMED has been compiled with xdrfile support, then also xtc and trr files can be written.
+      48             : To this aim one should install xdrfile library (http://www.gromacs.org/Developer_Zone/Programming_Guide/XTC_Library).
+      49             : If the xdrfile library is installed properly the PLUMED configure script should be able to
+      50             : detect it and enable it.
+      51             : The type of file is automatically detected from the file extension, but can be also
+      52             : enforced with TYPE.
+      53             : Importantly, if your
+      54             : input file contains actions that edit the atoms position (e.g. \ref WHOLEMOLECULES)
+      55             : and the DUMPATOMS command appears after this instruction, then the edited
+      56             : atom positions are output.
+      57             : You can control the buffering of output using the \ref FLUSH keyword on a separate line.
+      58             : 
+      59             : Units of the printed file can be controlled with the UNITS keyword. By default PLUMED units as
+      60             : controlled in the \ref UNITS command are used, but one can override it e.g. with UNITS=A.
+      61             : Notice that gro/xtc/trr files can only contain coordinates in nm.
+      62             : 
+      63             : \par Examples
+      64             : 
+      65             : The following input instructs plumed to print out the positions of atoms
+      66             : 1-10 together with the position of the center of mass of atoms 11-20 every
+      67             : 10 steps to a file called file.xyz.
+      68             : \plumedfile
+      69             : COM ATOMS=11-20 LABEL=c1
+      70             : DUMPATOMS STRIDE=10 FILE=file.xyz ATOMS=1-10,c1
+      71             : \endplumedfile
+      72             : Notice that the coordinates in the xyz file will be expressed in nm, since these
+      73             : are the defaults units in PLUMED. If you want the xyz file to be expressed in A, you should use the
+      74             : following input
+      75             : \plumedfile
+      76             : COM ATOMS=11-20 LABEL=c1
+      77             : DUMPATOMS STRIDE=10 FILE=file.xyz ATOMS=1-10,c1 UNITS=A
+      78             : \endplumedfile
+      79             : As an alternative, you might want to set all the length used by PLUMED to Angstrom using the \ref UNITS
+      80             : action. However, this latter choice will affect all your input and output.
+      81             : 
+      82             : The following input is very similar but dumps a .gro (gromacs) file,
+      83             : which also contains atom and residue names.
+      84             : \plumedfile
+      85             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      86             : # this is required to have proper atom names:
+      87             : MOLINFO STRUCTURE=reference.pdb
+      88             : # if omitted, atoms will have "X" name...
+      89             : 
+      90             : COM ATOMS=11-20 LABEL=c1
+      91             : DUMPATOMS STRIDE=10 FILE=file.gro ATOMS=1-10,c1
+      92             : # notice that last atom is a virtual one and will not have
+      93             : # a correct name in the resulting gro file
+      94             : \endplumedfile
+      95             : 
+      96             : The `file.gro` will contain coordinates expressed in nm, since this is the convention for gro files.
+      97             : 
+      98             : In case you have compiled PLUMED with `xdrfile` library, you might even write xtc or trr files as follows
+      99             : \plumedfile
+     100             : COM ATOMS=11-20 LABEL=c1
+     101             : DUMPATOMS STRIDE=10 FILE=file.xtc ATOMS=1-10,c1
+     102             : \endplumedfile
+     103             : Notice that xtc files are significantly smaller than gro and xyz files.
+     104             : 
+     105             : Finally, consider that gro and xtc file store coordinates with limited precision set by the
+     106             : `PRECISION` keyword. Default value is 3, which means "3 digits after dot" in nm (1/1000 of a nm).
+     107             : The following will write a larger xtc file with high resolution coordinates:
+     108             : \plumedfile
+     109             : COM ATOMS=11-20 LABEL=c1
+     110             : DUMPATOMS STRIDE=10 FILE=file.xtc ATOMS=1-10,c1 PRECISION=7
+     111             : \endplumedfile
+     112             : 
+     113             : 
+     114             : 
+     115             : */
+     116             : //+ENDPLUMEDOC
+     117             : 
+     118             : class DumpAtoms:
+     119             :   public ActionAtomistic,
+     120             :   public ActionPilot
+     121             : {
+     122             :   OFile of;
+     123             :   double lenunit;
+     124             :   int iprecision;
+     125             :   std::vector<std::string> names;
+     126             :   std::vector<unsigned>    residueNumbers;
+     127             :   std::vector<std::string> residueNames;
+     128             :   std::string type;
+     129             :   std::string fmt_gro_pos;
+     130             :   std::string fmt_gro_box;
+     131             :   std::string fmt_xyz;
+     132             :   xdrfile::XDRFILE* xd;
+     133             : public:
+     134             :   explicit DumpAtoms(const ActionOptions&);
+     135             :   ~DumpAtoms();
+     136             :   static void registerKeywords( Keywords& keys );
+     137        8825 :   void calculate() override {}
+     138        8825 :   void apply() override {}
+     139             :   void update() override ;
+     140             : };
+     141             : 
+     142             : PLUMED_REGISTER_ACTION(DumpAtoms,"DUMPATOMS")
+     143             : 
+     144         162 : void DumpAtoms::registerKeywords( Keywords& keys ) {
+     145         162 :   Action::registerKeywords( keys );
+     146         162 :   ActionPilot::registerKeywords( keys );
+     147         162 :   ActionAtomistic::registerKeywords( keys );
+     148         324 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+     149         324 :   keys.add("atoms", "ATOMS", "the atom indices whose positions you would like to print out");
+     150         324 :   keys.add("compulsory", "FILE", "file on which to output coordinates; extension is automatically detected");
+     151         324 :   keys.add("compulsory", "UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+     152         324 :   keys.add("optional", "PRECISION","The number of digits in trajectory file");
+     153         324 :   keys.add("optional", "TYPE","file type, either xyz, gro, xtc, or trr, can override an automatically detected file extension");
+     154         162 :   keys.use("RESTART");
+     155         162 :   keys.use("UPDATE_FROM");
+     156         162 :   keys.use("UPDATE_UNTIL");
+     157         162 : }
+     158             : 
+     159         160 : DumpAtoms::DumpAtoms(const ActionOptions&ao):
+     160             :   Action(ao),
+     161             :   ActionAtomistic(ao),
+     162             :   ActionPilot(ao),
+     163         160 :   iprecision(3)
+     164             : {
+     165             :   std::vector<AtomNumber> atoms;
+     166             :   std::string file;
+     167         320 :   parse("FILE",file);
+     168         160 :   if(file.length()==0) error("name out output file was not specified");
+     169         160 :   type=Tools::extension(file);
+     170         160 :   log<<"  file name "<<file<<"\n";
+     171         331 :   if(type=="gro" || type=="xyz" || type=="xtc" || type=="trr") {
+     172         144 :     log<<"  file extension indicates a "<<type<<" file\n";
+     173             :   } else {
+     174          16 :     log<<"  file extension not detected, assuming xyz\n";
+     175             :     type="xyz";
+     176             :   }
+     177             :   std::string ntype;
+     178         320 :   parse("TYPE",ntype);
+     179         160 :   if(ntype.length()>0) {
+     180           5 :     if(ntype!="xyz" && ntype!="gro" && ntype!="xtc" && ntype!="trr"
+     181           0 :       ) error("TYPE cannot be understood");
+     182           2 :     log<<"  file type enforced to be "<<ntype<<"\n";
+     183             :     type=ntype;
+     184             :   }
+     185             : 
+     186             :   fmt_gro_pos="%8.3f";
+     187             :   fmt_gro_box="%12.7f";
+     188             :   fmt_xyz="%f";
+     189             : 
+     190             :   std::string precision;
+     191         320 :   parse("PRECISION",precision);
+     192         160 :   if(precision.length()>0) {
+     193          91 :     Tools::convert(precision,iprecision);
+     194          91 :     log<<"  with precision "<<iprecision<<"\n";
+     195             :     std::string a,b;
+     196          91 :     Tools::convert(iprecision+5,a);
+     197          91 :     Tools::convert(iprecision,b);
+     198         182 :     fmt_gro_pos="%"+a+"."+b+"f";
+     199             :     fmt_gro_box=fmt_gro_pos;
+     200             :     fmt_xyz=fmt_gro_box;
+     201             :   }
+     202             : 
+     203         320 :   parseAtomList("ATOMS",atoms);
+     204             : 
+     205         320 :   std::string unitname; parse("UNITS",unitname);
+     206         160 :   if(unitname!="PLUMED") {
+     207           4 :     Units myunit; myunit.setLength(unitname);
+     208           6 :     if(myunit.getLength()!=1.0 && type=="gro") error("gro files should be in nm");
+     209           6 :     if(myunit.getLength()!=1.0 && type=="xtc") error("xtc files should be in nm");
+     210           6 :     if(myunit.getLength()!=1.0 && type=="trr") error("trr files should be in nm");
+     211           4 :     lenunit=getUnits().getLength()/myunit.getLength();
+     212         398 :   } else if(type=="gro" || type=="xtc" || type=="trr") lenunit=getUnits().getLength();
+     213         112 :   else lenunit=1.0;
+     214             : 
+     215         160 :   checkRead();
+     216         160 :   of.link(*this);
+     217         160 :   of.open(file);
+     218             :   std::string path=of.getPath();
+     219         160 :   log<<"  Writing on file "<<path<<"\n";
+     220             :   std::string mode=of.getMode();
+     221         160 :   if(type=="xtc") {
+     222           6 :     of.close();
+     223           6 :     xd=xdrfile::xdrfile_open(path.c_str(),mode.c_str());
+     224         154 :   } else if(type=="trr") {
+     225           4 :     of.close();
+     226           4 :     xd=xdrfile::xdrfile_open(path.c_str(),mode.c_str());
+     227             :   }
+     228         160 :   log.printf("  printing the following atoms in %s :", unitname.c_str() );
+     229       17962 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial() );
+     230         160 :   log.printf("\n");
+     231         160 :   requestAtoms(atoms);
+     232         160 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     233         160 :   if( moldat ) {
+     234          43 :     log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+     235          43 :     names.resize(atoms.size());
+     236        4983 :     for(unsigned i=0; i<atoms.size(); i++) if(atoms[i].index()<moldat->getPDBsize()) names[i]=moldat->getAtomName(atoms[i]);
+     237          43 :     residueNumbers.resize(atoms.size());
+     238        4983 :     for(unsigned i=0; i<residueNumbers.size(); ++i) if(atoms[i].index()<moldat->getPDBsize()) residueNumbers[i]=moldat->getResidueNumber(atoms[i]);
+     239          43 :     residueNames.resize(atoms.size());
+     240        4983 :     for(unsigned i=0; i<residueNames.size(); ++i) if(atoms[i].index()<moldat->getPDBsize()) residueNames[i]=moldat->getResidueName(atoms[i]);
+     241             :   }
+     242         160 : }
+     243             : 
+     244        8730 : void DumpAtoms::update() {
+     245        8730 :   if(type=="xyz") {
+     246        8288 :     of.printf("%d\n",getNumberOfAtoms());
+     247        8288 :     const Tensor & t(getPbc().getBox());
+     248        8288 :     if(getPbc().isOrthorombic()) {
+     249         364 :       of.printf((" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
+     250             :     } else {
+     251       16212 :       of.printf((" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),
+     252        8106 :                 lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     253        8106 :                 lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     254        8106 :                 lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     255             :                );
+     256             :     }
+     257       51816 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     258             :       const char* defname="X";
+     259             :       const char* name=defname;
+     260       43528 :       if(names.size()>0) if(names[i].length()>0) name=names[i].c_str();
+     261       87056 :       of.printf(("%s "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),name,lenunit*getPosition(i)(0),lenunit*getPosition(i)(1),lenunit*getPosition(i)(2));
+     262             :     }
+     263         442 :   } else if(type=="gro") {
+     264         322 :     const Tensor & t(getPbc().getBox());
+     265         322 :     of.printf("Made with PLUMED t=%f\n",getTime()/getUnits().getTime());
+     266         322 :     of.printf("%d\n",getNumberOfAtoms());
+     267       29668 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     268             :       const char* defname="X";
+     269             :       const char* name=defname;
+     270             :       unsigned residueNumber=0;
+     271       29346 :       if(names.size()>0) if(names[i].length()>0) name=names[i].c_str();
+     272       29346 :       if(residueNumbers.size()>0) residueNumber=residueNumbers[i];
+     273       29346 :       std::string resname="";
+     274       29346 :       if(residueNames.size()>0) resname=residueNames[i];
+     275       58692 :       of.printf(("%5u%-5s%5s%5d"+fmt_gro_pos+fmt_gro_pos+fmt_gro_pos+"\n").c_str(),
+     276             :                 residueNumber%100000,resname.c_str(),name,getAbsoluteIndex(i).serial()%100000,
+     277       29346 :                 lenunit*getPosition(i)(0),lenunit*getPosition(i)(1),lenunit*getPosition(i)(2));
+     278             :     }
+     279         644 :     of.printf((fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+" "+fmt_gro_box+"\n").c_str(),
+     280         322 :               lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2),
+     281         322 :               lenunit*t(0,1),lenunit*t(0,2),lenunit*t(1,0),
+     282         322 :               lenunit*t(1,2),lenunit*t(2,0),lenunit*t(2,1));
+     283         168 :   } else if(type=="xtc" || type=="trr") {
+     284             :     xdrfile::matrix box;
+     285         120 :     const Tensor & t(getPbc().getBox());
+     286         120 :     int natoms=getNumberOfAtoms();
+     287         120 :     int step=getStep();
+     288         120 :     float time=getTime()/getUnits().getTime();
+     289         120 :     float precision=Tools::fastpow(10.0,iprecision);
+     290        1560 :     for(int i=0; i<3; i++) for(int j=0; j<3; j++) box[i][j]=lenunit*t(i,j);
+     291             : // here we cannot use a std::vector<rvec> since it does not compile.
+     292             : // we thus use a std::unique_ptr<rvec[]>
+     293             :     auto pos = Tools::make_unique<xdrfile::rvec[]>(natoms);
+     294       25464 :     for(int i=0; i<natoms; i++) for(int j=0; j<3; j++) pos[i][j]=lenunit*getPosition(i)(j);
+     295         120 :     if(type=="xtc") {
+     296          72 :       write_xtc(xd,natoms,step,time,box,&pos[0],precision);
+     297          48 :     } else if(type=="trr") {
+     298          48 :       write_trr(xd,natoms,step,time,0.0,box,&pos[0],NULL,NULL);
+     299             :     }
+     300           0 :   } else plumed_merror("unknown file type "+type);
+     301        8730 : }
+     302             : 
+     303         320 : DumpAtoms::~DumpAtoms() {
+     304         160 :   if(type=="xtc") {
+     305           6 :     xdrfile_close(xd);
+     306         154 :   } else if(type=="trr") {
+     307           4 :     xdrfile_close(xd);
+     308             :   }
+     309         640 : }
+     310             : 
+     311             : 
+     312             : }
+     313             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpDerivatives.cpp.func-sort-c.html b/coverage/generic/DumpDerivatives.cpp.func-sort-c.html new file mode 100644 index 000000000000..d188947220b2 --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpDerivatives.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpDerivatives.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpDerivativesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpDerivativesD2Ev0
_ZN4PLMD7generic15DumpDerivativesC1ERKNS_13ActionOptionsE285
_ZN4PLMD7generic15DumpDerivativesD0Ev285
_ZN4PLMD7generic15DumpDerivativesD1Ev285
_ZN4PLMD7generic15DumpDerivatives16registerKeywordsERNS_8KeywordsE287
_ZN4PLMD7generic15DumpDerivatives6updateEv13420
_ZN4PLMD7generic15DumpDerivatives5applyEv13435
_ZN4PLMD7generic15DumpDerivatives9calculateEv13477
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpDerivatives.cpp.func.html b/coverage/generic/DumpDerivatives.cpp.func.html new file mode 100644 index 000000000000..42d44c9ab7e1 --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpDerivatives.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpDerivatives.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpDerivatives16registerKeywordsERNS_8KeywordsE287
_ZN4PLMD7generic15DumpDerivatives5applyEv13435
_ZN4PLMD7generic15DumpDerivatives6updateEv13420
_ZN4PLMD7generic15DumpDerivatives9calculateEv13477
_ZN4PLMD7generic15DumpDerivativesC1ERKNS_13ActionOptionsE285
_ZN4PLMD7generic15DumpDerivativesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpDerivativesD0Ev285
_ZN4PLMD7generic15DumpDerivativesD1Ev285
_ZN4PLMD7generic15DumpDerivativesD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpDerivatives.cpp.gcov.html b/coverage/generic/DumpDerivatives.cpp.gcov.html new file mode 100644 index 000000000000..6b81b2aec5cc --- /dev/null +++ b/coverage/generic/DumpDerivatives.cpp.gcov.html @@ -0,0 +1,210 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpDerivatives.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpDerivatives.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4646100.0 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/File.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace generic {
+      30             : 
+      31             : //+PLUMEDOC PRINTANALYSIS DUMPDERIVATIVES
+      32             : /*
+      33             : Dump the derivatives with respect to the input parameters for one or more objects (generally CVs, functions or biases).
+      34             : 
+      35             : For a CV this line in input instructs plumed to print the derivative of the CV with respect to the atom positions
+      36             : and the cell vectors (virial-like form).  In contrast, for a function or bias the derivative with respect to the input "CVs"
+      37             : will be output.  This command is most often used to test whether or not analytic derivatives have been implemented correctly.  This
+      38             : can be done by outputting the derivatives calculated analytically and numerically.  You can control the buffering of output using the \ref FLUSH keyword.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : The following input instructs plumed to write a file called deriv that contains both the
+      43             : analytical and numerical derivatives of the distance between atoms 1 and 2.
+      44             : \plumedfile
+      45             : DISTANCE ATOMS=1,2 LABEL=distance
+      46             : DISTANCE ATOMS=1,2 LABEL=distanceN NUMERICAL_DERIVATIVES
+      47             : DUMPDERIVATIVES ARG=distance,distanceN STRIDE=1 FILE=deriv
+      48             : \endplumedfile
+      49             : 
+      50             : (See also \ref DISTANCE)
+      51             : 
+      52             : */
+      53             : //+ENDPLUMEDOC
+      54             : 
+      55             : class DumpDerivatives :
+      56             :   public ActionPilot,
+      57             :   public ActionWithArguments
+      58             : {
+      59             :   std::string file;
+      60             :   std::string fmt;
+      61             :   OFile of;
+      62             : public:
+      63       13477 :   void calculate() override {}
+      64             :   explicit DumpDerivatives(const ActionOptions&);
+      65             :   static void registerKeywords(Keywords& keys);
+      66       13435 :   void apply() override {}
+      67             :   void update() override;
+      68             :   ~DumpDerivatives();
+      69             : };
+      70             : 
+      71             : PLUMED_REGISTER_ACTION(DumpDerivatives,"DUMPDERIVATIVES")
+      72             : 
+      73         287 : void DumpDerivatives::registerKeywords(Keywords& keys) {
+      74         287 :   Action::registerKeywords(keys);
+      75         287 :   ActionPilot::registerKeywords(keys);
+      76         287 :   ActionWithArguments::registerKeywords(keys);
+      77         287 :   keys.use("ARG");
+      78         574 :   keys.add("compulsory","STRIDE","1","the frequency with which the derivatives should be output");
+      79         574 :   keys.add("compulsory","FILE","the name of the file on which to output the derivatives");
+      80         574 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      81         287 :   keys.use("RESTART");
+      82         287 :   keys.use("UPDATE_FROM");
+      83         287 :   keys.use("UPDATE_UNTIL");
+      84         287 : }
+      85             : 
+      86         285 : DumpDerivatives::DumpDerivatives(const ActionOptions&ao):
+      87             :   Action(ao),
+      88             :   ActionPilot(ao),
+      89             :   ActionWithArguments(ao),
+      90         285 :   fmt("%15.10f")
+      91             : {
+      92         570 :   parse("FILE",file);
+      93         285 :   if( file.length()==0 ) error("name of output file was not specified");
+      94         285 :   parse("FMT",fmt);
+      95         285 :   fmt=" "+fmt;
+      96         285 :   of.link(*this);
+      97         285 :   of.open(file);
+      98         285 :   log.printf("  on file %s\n",file.c_str());
+      99         285 :   log.printf("  with format %s\n",fmt.c_str());
+     100             :   unsigned nargs=getNumberOfArguments();
+     101         285 :   if( nargs==0 ) error("no arguments specified");
+     102         285 :   (getPntrToArgument(0)->getPntrToAction())->turnOnDerivatives();
+     103         285 :   unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
+     104         285 :   if( npar==0 ) error("one or more arguments has no derivatives");
+     105         954 :   for(unsigned i=1; i<nargs; i++) {
+     106         669 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+     107         669 :     if( npar!=getPntrToArgument(i)->getNumberOfDerivatives() ) error("the number of derivatives must be the same in all values being dumped");
+     108             :   }
+     109         285 :   checkRead();
+     110         285 : }
+     111             : 
+     112             : 
+     113       13420 : void DumpDerivatives::update() {
+     114       13420 :   unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
+     115      918167 :   for(unsigned ipar=0; ipar<npar; ipar++) {
+     116      904747 :     of.fmtField(" %f");
+     117      904747 :     of.printField("time",getTime());
+     118      904747 :     of.printField("parameter",(int)ipar);
+     119     4567955 :     for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     120     3663208 :       of.fmtField(fmt);
+     121     3663208 :       of.printField(getPntrToArgument(i)->getName(),getPntrToArgument(i)->getDerivative(ipar) );
+     122             :     }
+     123      904747 :     of.printField();
+     124             :   }
+     125       13420 : }
+     126             : 
+     127         570 : DumpDerivatives::~DumpDerivatives() {
+     128         570 : }
+     129             : 
+     130             : }
+     131             : 
+     132             : 
+     133             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpForces.cpp.func-sort-c.html b/coverage/generic/DumpForces.cpp.func-sort-c.html new file mode 100644 index 000000000000..be43f33f85b1 --- /dev/null +++ b/coverage/generic/DumpForces.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpForces.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpForces.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpForcesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpForcesD2Ev0
_ZN4PLMD7generic10DumpForcesC1ERKNS_13ActionOptionsE28
_ZN4PLMD7generic10DumpForcesD0Ev28
_ZN4PLMD7generic10DumpForcesD1Ev28
_ZN4PLMD7generic10DumpForces16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD7generic10DumpForces5applyEv400
_ZN4PLMD7generic10DumpForces6updateEv400
_ZN4PLMD7generic10DumpForces9calculateEv400
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpForces.cpp.func.html b/coverage/generic/DumpForces.cpp.func.html new file mode 100644 index 000000000000..b8632169d95d --- /dev/null +++ b/coverage/generic/DumpForces.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpForces.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpForces.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10DumpForces16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD7generic10DumpForces5applyEv400
_ZN4PLMD7generic10DumpForces6updateEv400
_ZN4PLMD7generic10DumpForces9calculateEv400
_ZN4PLMD7generic10DumpForcesC1ERKNS_13ActionOptionsE28
_ZN4PLMD7generic10DumpForcesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10DumpForcesD0Ev28
_ZN4PLMD7generic10DumpForcesD1Ev28
_ZN4PLMD7generic10DumpForcesD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpForces.cpp.gcov.html b/coverage/generic/DumpForces.cpp.gcov.html new file mode 100644 index 000000000000..9f0b60df0d6a --- /dev/null +++ b/coverage/generic/DumpForces.cpp.gcov.html @@ -0,0 +1,196 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpForces.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpForces.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/File.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace generic {
+      29             : 
+      30             : //+PLUMEDOC PRINTANALYSIS DUMPFORCES
+      31             : /*
+      32             : Dump the force acting on one of a values in a file.
+      33             : 
+      34             : For a CV this command will dump
+      35             : the force on the CV itself. Be aware that in order to have the forces on the atoms
+      36             : you should multiply the output from this argument by the output from DUMPDERIVATIVES.
+      37             : Furthermore, also note that you can output the forces on multiple quantities simultaneously
+      38             : by specifying more than one argument. You can control the buffering of output using the \ref FLUSH keyword.
+      39             : 
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : The following input instructs plumed to write a file called forces that contains
+      44             : the force acting on the distance between atoms 1 and 2.
+      45             : \plumedfile
+      46             : DISTANCE ATOMS=1,2 LABEL=distance
+      47             : DUMPFORCES ARG=distance STRIDE=1 FILE=forces
+      48             : \endplumedfile
+      49             : 
+      50             : */
+      51             : //+ENDPLUMEDOC
+      52             : 
+      53             : class DumpForces :
+      54             :   public ActionPilot,
+      55             :   public ActionWithArguments
+      56             : {
+      57             :   std::string file;
+      58             :   std::string fmt;
+      59             :   OFile of;
+      60             : public:
+      61         400 :   void calculate() override {}
+      62             :   explicit DumpForces(const ActionOptions&);
+      63             :   static void registerKeywords(Keywords& keys);
+      64         400 :   void apply() override {}
+      65             :   void update() override;
+      66             :   ~DumpForces();
+      67             : };
+      68             : 
+      69             : PLUMED_REGISTER_ACTION(DumpForces,"DUMPFORCES")
+      70             : 
+      71          30 : void DumpForces::registerKeywords(Keywords& keys) {
+      72          30 :   Action::registerKeywords(keys);
+      73          30 :   ActionPilot::registerKeywords(keys);
+      74          30 :   ActionWithArguments::registerKeywords(keys);
+      75          30 :   keys.use("ARG");
+      76          60 :   keys.add("compulsory","STRIDE","1","the frequency with which the forces should be output");
+      77          60 :   keys.add("compulsory","FILE","the name of the file on which to output the forces");
+      78          60 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      79          30 :   keys.use("RESTART");
+      80          30 :   keys.use("UPDATE_FROM");
+      81          30 :   keys.use("UPDATE_UNTIL");
+      82          30 : }
+      83             : 
+      84          28 : DumpForces::DumpForces(const ActionOptions&ao):
+      85             :   Action(ao),
+      86             :   ActionPilot(ao),
+      87             :   ActionWithArguments(ao),
+      88          28 :   fmt("%15.10f")
+      89             : {
+      90          56 :   parse("FILE",file);
+      91          28 :   if( file.length()==0 ) error("name of file was not specified");
+      92          28 :   parse("FMT",fmt);
+      93          28 :   fmt=" "+fmt;
+      94          28 :   of.link(*this);
+      95          28 :   of.open(file);
+      96          28 :   log.printf("  on file %s\n",file.c_str());
+      97          28 :   log.printf("  with format %s\n",fmt.c_str());
+      98          28 :   if( getNumberOfArguments()==0 ) error("no arguments have been specified");
+      99          28 :   checkRead();
+     100          28 : }
+     101             : 
+     102             : 
+     103         400 : void DumpForces::update() {
+     104         400 :   of.fmtField(" %f");
+     105         400 :   of.printField("time",getTime());
+     106        4992 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     107        4592 :     of.fmtField(fmt);
+     108        4592 :     of.printField(getPntrToArgument(i)->getName(),getPntrToArgument(i)->getForce());
+     109             :   }
+     110         400 :   of.printField();
+     111         400 : }
+     112             : 
+     113          56 : DumpForces::~DumpForces() {
+     114          56 : }
+     115             : 
+     116             : }
+     117             : 
+     118             : 
+     119             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpMassCharge.cpp.func-sort-c.html b/coverage/generic/DumpMassCharge.cpp.func-sort-c.html new file mode 100644 index 000000000000..66680d9e44c3 --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpMassCharge.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpMassCharge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626398.4 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14DumpMassChargeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14DumpMassChargeD2Ev0
_ZN4PLMD7generic14DumpMassChargeC1ERKNS_13ActionOptionsE12
_ZN4PLMD7generic14DumpMassChargeD0Ev12
_ZN4PLMD7generic14DumpMassChargeD1Ev12
_ZN4PLMD7generic14DumpMassCharge16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7generic14DumpMassCharge5applyEv84
_ZN4PLMD7generic14DumpMassCharge6updateEv84
_ZN4PLMD7generic14DumpMassCharge7prepareEv84
_ZN4PLMD7generic14DumpMassCharge9calculateEv84
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpMassCharge.cpp.func.html b/coverage/generic/DumpMassCharge.cpp.func.html new file mode 100644 index 000000000000..569ad00a0ca8 --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpMassCharge.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpMassCharge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626398.4 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14DumpMassCharge16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7generic14DumpMassCharge5applyEv84
_ZN4PLMD7generic14DumpMassCharge6updateEv84
_ZN4PLMD7generic14DumpMassCharge7prepareEv84
_ZN4PLMD7generic14DumpMassCharge9calculateEv84
_ZN4PLMD7generic14DumpMassChargeC1ERKNS_13ActionOptionsE12
_ZN4PLMD7generic14DumpMassChargeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14DumpMassChargeD0Ev12
_ZN4PLMD7generic14DumpMassChargeD1Ev12
_ZN4PLMD7generic14DumpMassChargeD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpMassCharge.cpp.gcov.html b/coverage/generic/DumpMassCharge.cpp.gcov.html new file mode 100644 index 000000000000..f65562566de5 --- /dev/null +++ b/coverage/generic/DumpMassCharge.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpMassCharge.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpMassCharge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626398.4 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/File.h"
+      26             : #include "core/PlumedMain.h"
+      27             : 
+      28             : namespace PLMD
+      29             : {
+      30             : namespace generic {
+      31             : 
+      32             : //+PLUMEDOC PRINTANALYSIS DUMPMASSCHARGE
+      33             : /*
+      34             : Dump masses and charges on a selected file.
+      35             : 
+      36             : This command dumps a file containing charges and masses.
+      37             : It does so only once in the simulation (at first step).
+      38             : File can be recycled in the \ref driver tool.
+      39             : 
+      40             : Notice that masses and charges are only written once at the beginning
+      41             : of the simulation. In case no atom list is provided, charges and
+      42             : masses for all atoms are written.
+      43             : 
+      44             : \par Examples
+      45             : 
+      46             : You can add the DUMPMASSCHARGE action at the end of the plumed.dat
+      47             : file that you use during an MD simulations:
+      48             : 
+      49             : \plumedfile
+      50             : c1: COM ATOMS=1-10
+      51             : c2: COM ATOMS=11-20
+      52             : DUMPATOMS ATOMS=c1,c2 FILE=coms.xyz STRIDE=100
+      53             : 
+      54             : DUMPMASSCHARGE FILE=mcfile
+      55             : \endplumedfile
+      56             : 
+      57             : In this way, you will be able to use the same masses while processing
+      58             : a trajectory from the \ref driver . To do so, you need to
+      59             : add the --mc flag on the driver command line, e.g.
+      60             : \verbatim
+      61             : plumed driver --mc mcfile --plumed plumed.dat --ixyz traj.xyz
+      62             : \endverbatim
+      63             : 
+      64             : With the following input you can dump only the charges for a specific
+      65             : group:
+      66             : 
+      67             : \plumedfile
+      68             : solute_ions: GROUP ATOMS=1-121,200-2012
+      69             : DUMPATOMS FILE=traj.gro ATOMS=solute_ions STRIDE=100
+      70             : DUMPMASSCHARGE FILE=mcfile ATOMS=solute_ions
+      71             : \endplumedfile
+      72             : 
+      73             : */
+      74             : //+ENDPLUMEDOC
+      75             : 
+      76             : class DumpMassCharge:
+      77             :   public ActionAtomistic,
+      78             :   public ActionPilot
+      79             : {
+      80             :   std::string file;
+      81             :   bool first;
+      82             :   bool second;
+      83             :   bool print_masses;
+      84             :   bool print_charges;
+      85             : public:
+      86             :   explicit DumpMassCharge(const ActionOptions&);
+      87             :   ~DumpMassCharge();
+      88             :   static void registerKeywords( Keywords& keys );
+      89             :   void prepare() override;
+      90          84 :   void calculate() override {}
+      91          84 :   void apply() override {}
+      92             :   void update() override;
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(DumpMassCharge,"DUMPMASSCHARGE")
+      96             : 
+      97          14 : void DumpMassCharge::registerKeywords( Keywords& keys ) {
+      98          14 :   Action::registerKeywords( keys );
+      99          14 :   ActionPilot::registerKeywords( keys );
+     100          14 :   ActionAtomistic::registerKeywords( keys );
+     101          28 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+     102          28 :   keys.add("atoms", "ATOMS", "the atom indices whose charges and masses you would like to print out");
+     103          28 :   keys.add("compulsory", "FILE", "file on which to output charges and masses.");
+     104          28 :   keys.addFlag("ONLY_MASSES",false,"Only output masses to file");
+     105          28 :   keys.addFlag("ONLY_CHARGES",false,"Only output charges to file");
+     106          14 : }
+     107             : 
+     108          12 : DumpMassCharge::DumpMassCharge(const ActionOptions&ao):
+     109             :   Action(ao),
+     110             :   ActionAtomistic(ao),
+     111             :   ActionPilot(ao),
+     112          12 :   first(true),
+     113          12 :   second(true),
+     114          12 :   print_masses(true),
+     115          12 :   print_charges(true)
+     116             : {
+     117             :   std::vector<AtomNumber> atoms;
+     118          24 :   parse("FILE",file);
+     119          12 :   if(file.length()==0) error("name of output file was not specified");
+     120          12 :   log.printf("  output written to file %s\n",file.c_str());
+     121             : 
+     122          24 :   parseAtomList("ATOMS",atoms);
+     123             : 
+     124          12 :   if(atoms.size()==0) {
+     125           8 :     std::vector<std::string> strvec(1);
+     126           8 :     strvec[0]="@mdatoms"; interpretAtomList( strvec, atoms );
+     127           8 :   }
+     128             : 
+     129          12 :   bool only_masses = false;
+     130          12 :   parseFlag("ONLY_MASSES",only_masses);
+     131          12 :   if(only_masses) {
+     132           1 :     print_charges = false;
+     133           1 :     log.printf("  only masses will be written to file\n");
+     134             :   }
+     135             : 
+     136          12 :   bool only_charges = false;
+     137          12 :   parseFlag("ONLY_CHARGES",only_charges);
+     138          12 :   if(only_charges) {
+     139           1 :     print_masses = false;
+     140           1 :     log.printf("  only charges will be written to file\n");
+     141             :   }
+     142             : 
+     143             : 
+     144          12 :   checkRead();
+     145             : 
+     146          12 :   log.printf("  printing the following atoms:" );
+     147        1006 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial() );
+     148          12 :   log.printf("\n");
+     149          12 :   requestAtoms(atoms);
+     150             : 
+     151          12 :   if(only_masses && only_charges) {
+     152           0 :     plumed_merror("using both ONLY_MASSES and ONLY_CHARGES doesn't make sense");
+     153             :   }
+     154             : 
+     155          12 : }
+     156             : 
+     157          84 : void DumpMassCharge::prepare() {
+     158          84 :   if(!first && second) {
+     159          12 :     requestAtoms(std::vector<AtomNumber>());
+     160          12 :     second=false;
+     161             :   }
+     162          84 : }
+     163             : 
+     164          84 : void DumpMassCharge::update() {
+     165          84 :   if(!first) return;
+     166          12 :   first=false;
+     167             : 
+     168          12 :   OFile of;
+     169          12 :   of.link(*this);
+     170          12 :   of.open(file);
+     171             : 
+     172        1006 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     173         994 :     int ii=getAbsoluteIndex(i).index();
+     174         994 :     of.printField("index",ii);
+     175        1880 :     if(print_masses) {of.printField("mass",getMass(i));}
+     176        1880 :     if(print_charges) {of.printField("charge",getCharge(i));}
+     177         994 :     of.printField();
+     178             :   }
+     179          12 : }
+     180             : 
+     181          24 : DumpMassCharge::~DumpMassCharge() {
+     182          24 : }
+     183             : 
+     184             : 
+     185             : }
+     186             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpProjections.cpp.func-sort-c.html b/coverage/generic/DumpProjections.cpp.func-sort-c.html new file mode 100644 index 000000000000..6b259ba93ec6 --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpProjections.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpProjections.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpProjectionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpProjectionsD2Ev0
_ZN4PLMD7generic15DumpProjectionsC1ERKNS_13ActionOptionsE1
_ZN4PLMD7generic15DumpProjectionsD0Ev1
_ZN4PLMD7generic15DumpProjectionsD1Ev1
_ZN4PLMD7generic15DumpProjections16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7generic15DumpProjections5applyEv3
_ZN4PLMD7generic15DumpProjections6updateEv3
_ZN4PLMD7generic15DumpProjections9calculateEv3
_ZNK4PLMD7generic15DumpProjections19checkNeedsGradientsEv3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpProjections.cpp.func.html b/coverage/generic/DumpProjections.cpp.func.html new file mode 100644 index 000000000000..6abfbc00d4c1 --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpProjections.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpProjections.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15DumpProjections16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7generic15DumpProjections5applyEv3
_ZN4PLMD7generic15DumpProjections6updateEv3
_ZN4PLMD7generic15DumpProjections9calculateEv3
_ZN4PLMD7generic15DumpProjectionsC1ERKNS_13ActionOptionsE1
_ZN4PLMD7generic15DumpProjectionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15DumpProjectionsD0Ev1
_ZN4PLMD7generic15DumpProjectionsD1Ev1
_ZN4PLMD7generic15DumpProjectionsD2Ev0
_ZNK4PLMD7generic15DumpProjections19checkNeedsGradientsEv3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/DumpProjections.cpp.gcov.html b/coverage/generic/DumpProjections.cpp.gcov.html new file mode 100644 index 000000000000..45e555ffe269 --- /dev/null +++ b/coverage/generic/DumpProjections.cpp.gcov.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage - generic/DumpProjections.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - DumpProjections.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/File.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace generic {
+      30             : 
+      31             : //+PLUMEDOC PRINTANALYSIS DUMPPROJECTIONS
+      32             : /*
+      33             : Dump the derivatives with respect to the input parameters for one or more objects (generally CVs, functions or biases).
+      34             : 
+      35             : \par Examples
+      36             : 
+      37             : Compute the distance between two groups and write on a file the
+      38             : derivatives of this distance with respect to all the atoms of the two groups
+      39             : 
+      40             : \plumedfile
+      41             : x1: CENTER ATOMS=1-10
+      42             : x2: CENTER ATOMS=11-20
+      43             : d: DISTANCE ATOMS=x1,x2
+      44             : DUMPPROJECTIONS ARG=d FILE=proj STRIDE=20
+      45             : \endplumedfile
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : class DumpProjections :
+      51             :   public ActionPilot,
+      52             :   public ActionWithArguments
+      53             : {
+      54             :   std::string file;
+      55             :   std::string fmt;
+      56             :   OFile of;
+      57             : public:
+      58           3 :   void calculate() override {}
+      59             :   explicit DumpProjections(const ActionOptions&);
+      60             :   static void registerKeywords(Keywords& keys);
+      61           3 :   void apply() override {}
+      62             :   void update() override;
+      63           3 :   bool checkNeedsGradients()const override {return true;}
+      64             :   ~DumpProjections();
+      65             : };
+      66             : 
+      67             : PLUMED_REGISTER_ACTION(DumpProjections,"DUMPPROJECTIONS")
+      68             : 
+      69           3 : void DumpProjections::registerKeywords(Keywords& keys) {
+      70           3 :   Action::registerKeywords(keys);
+      71           3 :   ActionPilot::registerKeywords(keys);
+      72           3 :   ActionWithArguments::registerKeywords(keys);
+      73           3 :   keys.use("ARG");
+      74           6 :   keys.add("compulsory","STRIDE","1","the frequency with which the derivatives should be output");
+      75           6 :   keys.add("compulsory","FILE","the name of the file on which to output the derivatives");
+      76           6 :   keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
+      77           3 :   keys.use("RESTART");
+      78           3 :   keys.use("UPDATE_FROM");
+      79           3 :   keys.use("UPDATE_UNTIL");
+      80           3 : }
+      81             : 
+      82           1 : DumpProjections::DumpProjections(const ActionOptions&ao):
+      83             :   Action(ao),
+      84             :   ActionPilot(ao),
+      85             :   ActionWithArguments(ao),
+      86           1 :   fmt("%15.10f")
+      87             : {
+      88           2 :   parse("FILE",file);
+      89           1 :   if( file.length()==0 ) error("filename not specified");
+      90           1 :   parse("FMT",fmt);
+      91           1 :   fmt=" "+fmt;
+      92           1 :   of.open(file);
+      93           1 :   log.printf("  on file %s\n",file.c_str());
+      94           1 :   log.printf("  with format %s\n",fmt.c_str());
+      95           1 :   checkRead();
+      96             : 
+      97           3 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+      98           2 :     (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
+      99             :   }
+     100           1 : }
+     101             : 
+     102             : 
+     103           3 : void DumpProjections::update() {
+     104           6 :   of.fmtField(" %f").printField("time",getTime());
+     105           9 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     106          18 :     for(unsigned j=0; j<getNumberOfArguments(); j++) {
+     107          12 :       of.fmtField(fmt);
+     108          24 :       of.printField(getPntrToArgument(i)->getName()+"-"+getPntrToArgument(j)->getName(),getProjection(i,j));
+     109             :     }
+     110             :   }
+     111           3 :   of.printField();
+     112           3 : }
+     113             : 
+     114           2 : DumpProjections::~DumpProjections() {
+     115           2 : }
+     116             : 
+     117             : }
+     118             : 
+     119             : 
+     120             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html b/coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html new file mode 100644 index 000000000000..2f62f8ff36fd --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/EffectiveEnergyDrift.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EffectiveEnergyDrift.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic20EffectiveEnergyDriftC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic20EffectiveEnergyDriftD2Ev0
_ZN4PLMD7generic20EffectiveEnergyDriftC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic20EffectiveEnergyDriftD0Ev9
_ZN4PLMD7generic20EffectiveEnergyDriftD1Ev9
_ZN4PLMD7generic20EffectiveEnergyDrift16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic20EffectiveEnergyDrift5applyEv450
_ZN4PLMD7generic20EffectiveEnergyDrift6updateEv450
_ZN4PLMD7generic20EffectiveEnergyDrift9calculateEv450
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EffectiveEnergyDrift.cpp.func.html b/coverage/generic/EffectiveEnergyDrift.cpp.func.html new file mode 100644 index 000000000000..de7622566f54 --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - generic/EffectiveEnergyDrift.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EffectiveEnergyDrift.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic20EffectiveEnergyDrift16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic20EffectiveEnergyDrift5applyEv450
_ZN4PLMD7generic20EffectiveEnergyDrift6updateEv450
_ZN4PLMD7generic20EffectiveEnergyDrift9calculateEv450
_ZN4PLMD7generic20EffectiveEnergyDriftC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic20EffectiveEnergyDriftC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic20EffectiveEnergyDriftD0Ev9
_ZN4PLMD7generic20EffectiveEnergyDriftD1Ev9
_ZN4PLMD7generic20EffectiveEnergyDriftD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EffectiveEnergyDrift.cpp.gcov.html b/coverage/generic/EffectiveEnergyDrift.cpp.gcov.html new file mode 100644 index 000000000000..605207f7dfb1 --- /dev/null +++ b/coverage/generic/EffectiveEnergyDrift.cpp.gcov.html @@ -0,0 +1,448 @@ + + + + + + + + LCOV - plumed test coverage - generic/EffectiveEnergyDrift.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EffectiveEnergyDrift.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /*
+      24             :  This class was originally written by Marco Jacopo Ferrarotti
+      25             :  (marco.ferrarotti@gmail.com) and Giovanni Bussi
+      26             : */
+      27             : 
+      28             : #include "core/Action.h"
+      29             : #include "core/ActionPilot.h"
+      30             : #include "core/ActionWithValue.h"
+      31             : #include "core/ActionSet.h"
+      32             : #include "core/ActionRegister.h"
+      33             : #include "core/DomainDecomposition.h"
+      34             : #include "core/ActionToPutData.h"
+      35             : #include "core/PbcAction.h"
+      36             : #include "core/PlumedMain.h"
+      37             : 
+      38             : #include "tools/File.h"
+      39             : #include "tools/Pbc.h"
+      40             : 
+      41             : #include <algorithm>
+      42             : 
+      43             : namespace PLMD {
+      44             : namespace generic {
+      45             : 
+      46             : //+PLUMEDOC GENERIC EFFECTIVE_ENERGY_DRIFT
+      47             : /*
+      48             : Print the effective energy drift
+      49             : 
+      50             : The method used to calculate the effective energy drift is described in Ref \cite Ferrarotti2015
+      51             : 
+      52             : 
+      53             : \par Examples
+      54             : 
+      55             : 
+      56             : This is to monitor the effective energy drift for a metadynamics
+      57             : simulation on the Debye-Huckel energy. Since this variable is very expensive,
+      58             : it could be conveniently computed every second step.
+      59             : \plumedfile
+      60             : dh: DHENERGY GROUPA=1-10 GROUPB=11-20 EPSILON=80.0 I=0.1 TEMP=300.0
+      61             : METAD ARG=dh HEIGHT=0.5 SIGMA=0.1 PACE=500 STRIDE=2
+      62             : EFFECTIVE_ENERGY_DRIFT PRINT_STRIDE=100 FILE=eff
+      63             : \endplumedfile
+      64             : 
+      65             : This is to monitor if a restraint is too stiff
+      66             : \plumedfile
+      67             : d: DISTANCE ATOMS=10,20
+      68             : RESTRAINT ARG=d KAPPA=100000 AT=0.6
+      69             : EFFECTIVE_ENERGY_DRIFT PRINT_STRIDE=100 FILE=eff
+      70             : \endplumedfile
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : 
+      75             : 
+      76             : class EffectiveEnergyDrift:
+      77             :   public ActionPilot {
+      78             :   OFile output;
+      79             :   long long int printStride;
+      80             :   std::string fmt;
+      81             : 
+      82             :   double eed;
+      83             : 
+      84             :   std::vector<ActionWithValue*> biases;
+      85             : 
+      86             :   long long int pDdStep;
+      87             :   int nLocalAtoms;
+      88             :   int pNLocalAtoms;
+      89             :   std::vector<int> pGatindex;
+      90             :   std::vector<double> xpositions;
+      91             :   std::vector<double> ypositions;
+      92             :   std::vector<double> zpositions;
+      93             :   std::vector<Vector> positions;
+      94             :   std::vector<Vector> pPositions;
+      95             :   std::vector<Vector> forces;
+      96             :   std::vector<Vector> pForces;
+      97             :   Tensor box,pbox;
+      98             :   Tensor fbox,pfbox;
+      99             : 
+     100             :   const int nProc;
+     101             :   std::vector<int> indexCnt;
+     102             :   std::vector<int> indexDsp;
+     103             :   std::vector<int> dataCnt;
+     104             :   std::vector<int> dataDsp;
+     105             :   std::vector<int> indexS;
+     106             :   std::vector<int> indexR;
+     107             :   std::vector<double> dataS;
+     108             :   std::vector<double> dataR;
+     109             :   std::vector<int> backmap;
+     110             : 
+     111             :   double initialBias;
+     112             :   bool isFirstStep;
+     113             : 
+     114             :   bool ensemble;
+     115             :   PbcAction* pbc_action;
+     116             :   DomainDecomposition* domains;
+     117             :   ActionToPutData* posx;
+     118             :   ActionToPutData* posy;
+     119             :   ActionToPutData* posz;
+     120             : public:
+     121             :   explicit EffectiveEnergyDrift(const ActionOptions&);
+     122             :   ~EffectiveEnergyDrift();
+     123             : 
+     124             :   static void registerKeywords( Keywords& keys );
+     125             : 
+     126         450 :   void calculate() override {};
+     127         450 :   void apply() override {};
+     128             :   void update() override;
+     129             : };
+     130             : 
+     131             : PLUMED_REGISTER_ACTION(EffectiveEnergyDrift,"EFFECTIVE_ENERGY_DRIFT")
+     132             : 
+     133          11 : void EffectiveEnergyDrift::registerKeywords( Keywords& keys ) {
+     134          11 :   Action::registerKeywords( keys );
+     135          11 :   ActionPilot::registerKeywords( keys );
+     136             : 
+     137          22 :   keys.add("compulsory","STRIDE","1","should be set to 1. Effective energy drift computation has to be active at each step.");
+     138          22 :   keys.add("compulsory", "FILE", "file on which to output the effective energy drift.");
+     139          22 :   keys.add("compulsory", "PRINT_STRIDE", "frequency to which output the effective energy drift on FILE");
+     140          22 :   keys.addFlag("ENSEMBLE",false,"Set to TRUE if you want to average over multiple replicas.");
+     141          22 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     142          11 :   keys.use("RESTART");
+     143          11 :   keys.use("UPDATE_FROM");
+     144          11 :   keys.use("UPDATE_UNTIL");
+     145          11 : }
+     146             : 
+     147           9 : EffectiveEnergyDrift::EffectiveEnergyDrift(const ActionOptions&ao):
+     148             :   Action(ao),
+     149             :   ActionPilot(ao),
+     150           9 :   fmt("%f"),
+     151           9 :   eed(0.0),
+     152           9 :   nProc(plumed.comm.Get_size()),
+     153           9 :   initialBias(0.0),
+     154           9 :   isFirstStep(true),
+     155           9 :   ensemble(false),
+     156           9 :   pbc_action(NULL),
+     157           9 :   domains(NULL),
+     158           9 :   posx(NULL),
+     159           9 :   posy(NULL),
+     160          27 :   posz(NULL)
+     161             : {
+     162             :   //stride must be == 1
+     163           9 :   if(getStride()!=1) error("EFFECTIVE_ENERGY_DRIFT must have STRIDE=1 to work properly");
+     164             : 
+     165             :   //parse and open FILE
+     166             :   std::string fileName;
+     167          18 :   parse("FILE",fileName);
+     168           9 :   if(fileName.length()==0) error("name out output file was not specified\n");
+     169           9 :   output.link(*this);
+     170           9 :   output.open(fileName);
+     171             : 
+     172             :   //parse PRINT_STRIDE
+     173           9 :   parse("PRINT_STRIDE",printStride);
+     174             : 
+     175             : 
+     176             :   //parse FMT
+     177           9 :   parse("FMT",fmt);
+     178           9 :   fmt=" "+fmt;
+     179           9 :   log.printf("  with format %s\n",fmt.c_str());
+     180             : 
+     181             :   //parse ENSEMBLE
+     182           9 :   ensemble=false;
+     183           9 :   parseFlag("ENSEMBLE",ensemble);
+     184           9 :   if(ensemble&&comm.Get_rank()==0) {
+     185           0 :     if(multi_sim_comm.Get_size()<2) error("You CANNOT run Replica-Averaged simulations without running multiple replicas!\n");
+     186             :   }
+     187             : 
+     188          18 :   log<<"Bibliography "<<cite("Ferrarotti, Bottaro, Perez-Villa, and Bussi, J. Chem. Theory Comput. 11, 139 (2015)")<<"\n";
+     189             : 
+     190             :   //construct biases from ActionWithValue with a component named bias
+     191           9 :   std::vector<ActionWithValue*> tmpActions=plumed.getActionSet().select<ActionWithValue*>();
+     192         100 :   for(unsigned i=0; i<tmpActions.size(); i++) if(tmpActions[i]->exists(tmpActions[i]->getLabel()+".bias")) biases.push_back(tmpActions[i]);
+     193             : 
+     194             :   //resize counters and displacements useful to communicate with MPI_Allgatherv
+     195           9 :   indexCnt.resize(nProc);
+     196           9 :   indexDsp.resize(nProc);
+     197           9 :   dataCnt.resize(nProc);
+     198           9 :   dataDsp.resize(nProc);
+     199             :   // Retrieve the box
+     200           9 :   pbc_action=plumed.getActionSet().selectWithLabel<PbcAction*>("Box");
+     201             :   // Get the domain decomposition object
+     202           9 :   std::vector<DomainDecomposition*> ddact=plumed.getActionSet().select<DomainDecomposition*>();
+     203           9 :   if( ddact.size()>1 ) warning("found more than one interface so don't know get gatindex");
+     204           9 :   domains = ddact[0];
+     205           9 :   std::vector<ActionToPutData*> inputs=plumed.getActionSet().select<ActionToPutData*>();
+     206          73 :   for(const auto & pp : inputs ) {
+     207         128 :     if( pp->getRole()=="x" ) posx = pp;
+     208         128 :     if( pp->getRole()=="y" ) posy = pp;
+     209         128 :     if( pp->getRole()=="z" ) posz = pp;
+     210             :   }
+     211           9 :   plumed_assert( posx && posy && posz );
+     212             :   //resize the received buffers
+     213           9 :   indexR.resize((posx->copyOutput(0))->getShape()[0]);
+     214           9 :   dataR.resize((posx->copyOutput(0))->getShape()[0]*6);
+     215           9 :   backmap.resize((posx->copyOutput(0))->getShape()[0]);
+     216           9 : }
+     217             : 
+     218          18 : EffectiveEnergyDrift::~EffectiveEnergyDrift() {
+     219             : 
+     220          18 : }
+     221             : 
+     222         450 : void EffectiveEnergyDrift::update() {
+     223         450 :   Pbc & tpbc(pbc_action->getPbc()); bool pbc=tpbc.isSet();
+     224             : 
+     225             :   //retrieve data of local atoms
+     226         450 :   const std::vector<int>& gatindex = domains->getGatindex();
+     227         450 :   nLocalAtoms = gatindex.size();
+     228         450 :   xpositions.resize( gatindex.size() ); posx->getLocalValues( xpositions );
+     229         450 :   ypositions.resize( gatindex.size() ); posy->getLocalValues( ypositions );
+     230         450 :   zpositions.resize( gatindex.size() ); posz->getLocalValues( zpositions );
+     231         450 :   positions.resize( gatindex.size() ); forces.resize( gatindex.size() );
+     232       16650 :   for(unsigned i=0; i<gatindex.size(); ++i ) {
+     233       16200 :     positions[i][0] = xpositions[i];
+     234       16200 :     positions[i][1] = ypositions[i];
+     235       16200 :     positions[i][2] = zpositions[i];
+     236       16200 :     forces[i][0] = (posx->copyOutput(0))->getForce( gatindex[i] );
+     237       16200 :     forces[i][1] = (posy->copyOutput(0))->getForce( gatindex[i] );
+     238       16200 :     forces[i][2] = (posz->copyOutput(0))->getForce( gatindex[i] );
+     239             :   }
+     240         450 :   if(pbc) {
+     241         450 :     Tensor B=tpbc.getBox();
+     242         450 :     Tensor IB=tpbc.getInvBox();
+     243         450 :     #pragma omp parallel for
+     244             :     for(unsigned i=0; i<positions.size(); ++i) {
+     245             :       positions[i]=matmul(positions[i],IB);
+     246             :       forces[i]=matmul(B,forces[i]);
+     247             :     }
+     248         450 :     box=B; Tensor virial; Value* boxValue = pbc_action->copyOutput(0);
+     249        5850 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) virial[i][j]=boxValue->getForce(3*i+j);
+     250         450 :     fbox=matmul(transpose(inverse(box)),virial);
+     251             :   }
+     252             : 
+     253             :   //init stored data at the first step
+     254         450 :   if(isFirstStep) {
+     255           9 :     pDdStep=0;
+     256           9 :     pGatindex = domains->getGatindex();
+     257           9 :     pNLocalAtoms = pGatindex.size();
+     258           9 :     pPositions=positions;
+     259           9 :     pForces=forces;
+     260           9 :     pbox=box;
+     261           9 :     pfbox=fbox;
+     262           9 :     initialBias=plumed.getBias();
+     263             : 
+     264           9 :     isFirstStep=false;
+     265             :   }
+     266             : 
+     267             :   //if the dd has changed we have to reshare the stored data
+     268         450 :   if(pDdStep<domains->getDdStep() && nLocalAtoms<(posx->copyOutput(0))->getShape()[0]) {
+     269             :     //prepare the data to be sent
+     270         204 :     indexS.resize(pNLocalAtoms);
+     271         204 :     dataS.resize(pNLocalAtoms*6);
+     272             : 
+     273        5712 :     for(int i=0; i<pNLocalAtoms; i++) {
+     274        5508 :       indexS[i] = pGatindex[i];
+     275        5508 :       dataS[i*6] = pPositions[i][0];
+     276        5508 :       dataS[i*6+1] = pPositions[i][1];
+     277        5508 :       dataS[i*6+2] = pPositions[i][2];
+     278        5508 :       dataS[i*6+3] = pForces[i][0];
+     279        5508 :       dataS[i*6+4] = pForces[i][1];
+     280        5508 :       dataS[i*6+5] = pForces[i][2];
+     281             :     }
+     282             : 
+     283             :     //setup the counters and displacements for the communication
+     284         204 :     plumed.comm.Allgather(&pNLocalAtoms,1,&indexCnt[0],1);
+     285         204 :     indexDsp[0] = 0;
+     286        1020 :     for(int i=0; i<nProc; i++) {
+     287         816 :       dataCnt[i] = indexCnt[i]*6;
+     288             : 
+     289         816 :       if(i+1<nProc) indexDsp[i+1] = indexDsp[i]+indexCnt[i];
+     290         816 :       dataDsp[i] = indexDsp[i]*6;
+     291             :     }
+     292             : 
+     293             :     //share stored data
+     294         402 :     plumed.comm.Allgatherv((!indexS.empty()?&indexS[0]:NULL), pNLocalAtoms, &indexR[0], &indexCnt[0], &indexDsp[0]);
+     295         402 :     plumed.comm.Allgatherv((!dataS.empty()?&dataS[0]:NULL), pNLocalAtoms*6, &dataR[0], &dataCnt[0], &dataDsp[0]);
+     296             : 
+     297             :     //resize vectors to store the proper amount of data
+     298         204 :     pGatindex.resize(nLocalAtoms);
+     299         204 :     pPositions.resize(nLocalAtoms);
+     300         204 :     pForces.resize(nLocalAtoms);
+     301             : 
+     302             :     //compute backmap
+     303       22236 :     for(unsigned j=0; j<indexR.size(); j++) backmap[indexR[j]]=j;
+     304             : 
+     305             :     //fill the vectors pGatindex, pPositions and pForces
+     306        5712 :     for(int i=0; i<nLocalAtoms; i++) {
+     307        5508 :       int glb=backmap[gatindex[i]];
+     308        5508 :       pGatindex[i] = indexR[glb];
+     309        5508 :       pPositions[i][0] = dataR[glb*6];
+     310        5508 :       pPositions[i][1] = dataR[glb*6+1];
+     311        5508 :       pPositions[i][2] = dataR[glb*6+2];
+     312        5508 :       pForces[i][0] = dataR[glb*6+3];
+     313        5508 :       pForces[i][1] = dataR[glb*6+4];
+     314        5508 :       pForces[i][2] = dataR[glb*6+5];
+     315             :     }
+     316             :   }
+     317             : 
+     318             :   //compute the effective energy drift on local atoms
+     319             : 
+     320         450 :   double eed_tmp=eed;
+     321         450 :   #pragma omp parallel for reduction(+:eed_tmp)
+     322             :   for(int i=0; i<nLocalAtoms; i++) {
+     323             :     Vector dst=delta(pPositions[i],positions[i]);
+     324             :     if(pbc) for(unsigned k=0; k<3; k++) dst[k]=Tools::pbc(dst[k]);
+     325             :     eed_tmp += dotProduct(dst, forces[i]+pForces[i])*0.5;
+     326             :   }
+     327             : 
+     328         450 :   eed=eed_tmp;
+     329             : 
+     330         450 :   if(plumed.comm.Get_rank()==0) {
+     331        1950 :     for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++)
+     332        1350 :         eed-=0.5*(pfbox(i,j)+fbox(i,j))*(box(i,j)-pbox(i,j));
+     333             :   }
+     334             : 
+     335             : 
+     336             :   //print the effective energy drift on FILE with frequency PRINT_STRIDE
+     337         450 :   if(plumed.getStep()%printStride==0) {
+     338         450 :     double eedSum = eed;
+     339             :     double bias = 0.0;
+     340             : 
+     341             :     //we cannot just use plumed.getBias() because it will be ==0.0 if PRINT_STRIDE
+     342             :     //is not a multiple of the bias actions stride
+     343         900 :     for(unsigned i=0; i<biases.size(); i++) bias+=biases[i]->getOutputQuantity("bias");
+     344             : 
+     345         450 :     plumed.comm.Sum(&eedSum,1);
+     346             : 
+     347         450 :     double effective = eedSum+bias-initialBias-plumed.getWork();
+     348             :     // this is to take into account ensemble averaging
+     349         450 :     if(ensemble) {
+     350           0 :       if(plumed.comm.Get_rank()==0) plumed.multi_sim_comm.Sum(&effective,1);
+     351           0 :       else effective=0.;
+     352           0 :       plumed.comm.Sum(&effective,1);
+     353             :     }
+     354         450 :     output.fmtField(" %f");
+     355         450 :     output.printField("time",getTime());
+     356         450 :     output.fmtField(fmt);
+     357         450 :     output.printField("effective-energy",effective);
+     358         450 :     output.printField();
+     359             :   }
+     360             : 
+     361             :   //store the data of the current step
+     362         450 :   pDdStep = domains->getDdStep();
+     363         450 :   pNLocalAtoms = nLocalAtoms;
+     364             :   pPositions.swap(positions);
+     365             :   pForces.swap(forces);
+     366         450 :   pbox=box;
+     367         450 :   pfbox=fbox;
+     368         450 : }
+     369             : 
+     370             : }
+     371             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EndPlumed.cpp.func-sort-c.html b/coverage/generic/EndPlumed.cpp.func-sort-c.html new file mode 100644 index 000000000000..83e6123dd381 --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - generic/EndPlumed.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EndPlumed.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:81080.0 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9EndPlumed5applyEv0
_ZN4PLMD7generic9EndPlumed9calculateEv0
_ZN4PLMD7generic9EndPlumedC2ERKNS_13ActionOptionsE268
_ZN4PLMD7generic9EndPlumed16registerKeywordsERNS_8KeywordsE270
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EndPlumed.cpp.func.html b/coverage/generic/EndPlumed.cpp.func.html new file mode 100644 index 000000000000..34c30fbe5ebb --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - generic/EndPlumed.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EndPlumed.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:81080.0 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9EndPlumed16registerKeywordsERNS_8KeywordsE270
_ZN4PLMD7generic9EndPlumed5applyEv0
_ZN4PLMD7generic9EndPlumed9calculateEv0
_ZN4PLMD7generic9EndPlumedC2ERKNS_13ActionOptionsE268
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/EndPlumed.cpp.gcov.html b/coverage/generic/EndPlumed.cpp.gcov.html new file mode 100644 index 000000000000..0d55fed17453 --- /dev/null +++ b/coverage/generic/EndPlumed.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - generic/EndPlumed.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - EndPlumed.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:81080.0 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/ActionSet.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace generic {
+      28             : 
+      29             : //+PLUMEDOC GENERIC ENDPLUMED
+      30             : /*
+      31             : Terminate plumed input.
+      32             : 
+      33             : Can be used to effectively comment out the rest of the input file.
+      34             : It can be useful to quickly ignore part of a long input file. However,
+      35             : one should keep in mind that when opening the file it might be difficult to
+      36             : find where the commented out part begins. Regular comments (with `#`) are
+      37             : usually easier to read. Notice that \ref VimSyntax "VIM syntax" should be able
+      38             : to detect this command and properly mark the rest of the file as a comment,
+      39             : although since vim doesn't parse the whole file it might fail in doing so for long
+      40             : input files.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : \plumedfile
+      45             : d: DISTANCE ATOMS=1,10
+      46             : PRINT ARG=d FILE=COLVAR STRIDE=10
+      47             : ENDPLUMED
+      48             : commands here are ignored
+      49             : PRINT ARG=d FILE=COLVAR STRIDE=1
+      50             : \endplumedfile
+      51             : 
+      52             : */
+      53             : //+ENDPLUMEDOC
+      54             : class EndPlumed:
+      55             :   public Action
+      56             : {
+      57             : public:
+      58             :   explicit EndPlumed(const ActionOptions&ao);
+      59             : /// Register all the relevant keywords for the action
+      60             :   static void registerKeywords( Keywords& keys );
+      61           0 :   void calculate() override {}
+      62           0 :   void apply() override {}
+      63             : };
+      64             : 
+      65             : PLUMED_REGISTER_ACTION(EndPlumed,"ENDPLUMED")
+      66             : 
+      67         270 : void EndPlumed::registerKeywords( Keywords& keys ) {
+      68         270 :   Action::registerKeywords( keys );
+      69         270 : }
+      70             : 
+      71         268 : EndPlumed::EndPlumed(const ActionOptions&ao):
+      72         268 :   Action(ao)
+      73             : {
+      74         268 :   checkRead();
+      75         268 :   plumed.setEndPlumed();
+      76         268 : }
+      77             : 
+      78             : }
+      79             : }
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/FitToTemplate.cpp.func-sort-c.html b/coverage/generic/FitToTemplate.cpp.func-sort-c.html new file mode 100644 index 000000000000..0884431e2882 --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - generic/FitToTemplate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - FitToTemplate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10310697.2 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic13FitToTemplate22getNumberOfDerivativesEv0
_ZN4PLMD7generic13FitToTemplateC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic13FitToTemplateC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic13FitToTemplate16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic13FitToTemplate5applyEv108
_ZN4PLMD7generic13FitToTemplate9calculateEv108
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/FitToTemplate.cpp.func.html b/coverage/generic/FitToTemplate.cpp.func.html new file mode 100644 index 000000000000..76d4a33f684b --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - generic/FitToTemplate.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - FitToTemplate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10310697.2 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic13FitToTemplate16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD7generic13FitToTemplate22getNumberOfDerivativesEv0
_ZN4PLMD7generic13FitToTemplate5applyEv108
_ZN4PLMD7generic13FitToTemplate9calculateEv108
_ZN4PLMD7generic13FitToTemplateC1ERKNS_13ActionOptionsE9
_ZN4PLMD7generic13FitToTemplateC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/FitToTemplate.cpp.gcov.html b/coverage/generic/FitToTemplate.cpp.gcov.html new file mode 100644 index 000000000000..ae9da633b70f --- /dev/null +++ b/coverage/generic/FitToTemplate.cpp.gcov.html @@ -0,0 +1,460 @@ + + + + + + + + LCOV - plumed test coverage - generic/FitToTemplate.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - FitToTemplate.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10310697.2 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/ActionWithValue.h"
+      26             : #include "tools/Vector.h"
+      27             : #include "tools/Matrix.h"
+      28             : #include "tools/AtomNumber.h"
+      29             : #include "tools/Tools.h"
+      30             : #include "tools/RMSD.h"
+      31             : #include "core/PlumedMain.h"
+      32             : #include "core/ActionSet.h"
+      33             : #include "core/GenericMolInfo.h"
+      34             : #include "core/PbcAction.h"
+      35             : #include "tools/PDB.h"
+      36             : #include "tools/Pbc.h"
+      37             : 
+      38             : #include <vector>
+      39             : #include <string>
+      40             : #include <memory>
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace generic {
+      44             : 
+      45             : //+PLUMEDOC GENERIC FIT_TO_TEMPLATE
+      46             : /*
+      47             : This action is used to align a molecule to a template.
+      48             : 
+      49             : This can be used to move the coordinates stored in plumed
+      50             : so as to be aligned with a provided template in PDB format. Pdb should contain
+      51             : also weights for alignment (see the format of PDB files used e.g. for \ref RMSD).
+      52             : Make sure your PDB file is correctly formatted as explained \ref pdbreader "in this page".
+      53             : Weights for displacement are ignored, since no displacement is computed here.
+      54             : Notice that all atoms (not only those in the template) are aligned.
+      55             : To see what effect try
+      56             : the \ref DUMPATOMS directive to output the atomic positions.
+      57             : 
+      58             : Also notice that PLUMED propagate forces correctly so that you can add a bias on a CV computed
+      59             : after alignment. For many CVs this has no effect, but in some case the alignment can
+      60             : change the result. Examples are:
+      61             : - \ref POSITION CV since it is affected by a rigid shift of the system.
+      62             : - \ref DISTANCE CV with COMPONENTS. Since the alignment could involve a rotation (with TYPE=OPTIMAL) the actual components could be different
+      63             :   from the original ones.
+      64             : - \ref CELL components for a similar reason.
+      65             : - \ref DISTANCE from a \ref FIXEDATOM, provided the fixed atom is introduced _after_ the \ref FIT_TO_TEMPLATE action.
+      66             : 
+      67             : \attention
+      68             : The implementation of TYPE=OPTIMAL is available but should be considered in testing phase. Please report any
+      69             : strange behavior.
+      70             : 
+      71             : \attention
+      72             : This directive modifies the stored position at the precise moment
+      73             : it is executed. This means that only collective variables
+      74             : which are below it in the input script will see the corrected positions.
+      75             : As a general rule, put it at the top of the input file. Also, unless you
+      76             : know exactly what you are doing, leave the default stride (1), so that
+      77             : this action is performed at every MD step.
+      78             : 
+      79             : When running with periodic boundary conditions, the atoms should be
+      80             : in the proper periodic image. This is done automatically since PLUMED 2.5,
+      81             : by considering the ordered list of atoms and rebuilding the molecules using a procedure
+      82             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+      83             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+      84             : which actually modifies the coordinates stored in PLUMED.
+      85             : 
+      86             : In case you want to recover the old behavior you should use the NOPBC flag.
+      87             : In that case you need to take care that atoms are in the correct
+      88             : periodic image.
+      89             : 
+      90             : \par Examples
+      91             : 
+      92             : Align the atomic position to a template then print them.
+      93             : The following example is only translating the system so as
+      94             : to align the center of mass of a molecule to the one in the reference
+      95             : structure `ref.pdb`:
+      96             : \plumedfile
+      97             : # dump coordinates before fitting, to see the difference:
+      98             : DUMPATOMS FILE=dump-before.xyz ATOMS=1-20
+      99             : 
+     100             : # fit coordinates to ref.pdb template
+     101             : # this is a "TYPE=SIMPLE" fit, so that only translations are used.
+     102             : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=SIMPLE
+     103             : 
+     104             : # dump coordinates after fitting, to see the difference:
+     105             : DUMPATOMS FILE=dump-after.xyz ATOMS=1-20
+     106             : \endplumedfile
+     107             : 
+     108             : The following example instead performs a rototranslational fit.
+     109             : \plumedfile
+     110             : # dump coordinates before fitting, to see the difference:
+     111             : DUMPATOMS FILE=dump-before.xyz ATOMS=1-20
+     112             : 
+     113             : # fit coordinates to ref.pdb template
+     114             : # this is a "TYPE=OPTIMAL" fit, so that rototranslations are used.
+     115             : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=OPTIMAL
+     116             : 
+     117             : # dump coordinates after fitting, to see the difference:
+     118             : DUMPATOMS FILE=dump-after.xyz ATOMS=1-20
+     119             : \endplumedfile
+     120             : 
+     121             : In both these cases the reference structure should be provided in a reference pdb file such as the one below:
+     122             : 
+     123             : \auxfile{ref.pdb}
+     124             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+     125             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+     126             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+     127             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+     128             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+     129             : END
+     130             : \endauxfile
+     131             : 
+     132             : In the following example you see two completely equivalent way
+     133             : to restrain an atom close to a position that is defined in the reference
+     134             : frame of an aligned molecule. You could for instance use this command to calculate the
+     135             : position of the center of mass of a ligand after having aligned the atoms to the reference
+     136             : frame of the protein that is determined by aligning the atoms in the protein to the coordinates
+     137             : provided in the file ref.pdb
+     138             : \plumedfile
+     139             : # center of the ligand:
+     140             : center: CENTER ATOMS=100-110
+     141             : 
+     142             : FIT_TO_TEMPLATE REFERENCE=ref.pdb TYPE=OPTIMAL
+     143             : 
+     144             : # place a fixed atom in the protein reference coordinates:
+     145             : fix: FIXEDATOM AT=1.0,1.1,1.0
+     146             : 
+     147             : # take the distance between the fixed atom and the center of the ligand
+     148             : d: DISTANCE ATOMS=center,fix
+     149             : 
+     150             : # apply a restraint
+     151             : RESTRAINT ARG=d AT=0.0 KAPPA=100.0
+     152             : \endplumedfile
+     153             : 
+     154             : Notice that you could have obtained an (almost) identical result by adding a fictitious
+     155             : atom to `ref.pdb` with the serial number corresponding to the atom labelled `center` (there is no automatic way
+     156             : to get it, but in this example it should be the number of atoms of the system plus one),
+     157             : and properly setting the weights for alignment and displacement in \ref RMSD.
+     158             : There are two differences to be expected:
+     159             : (ab) \ref FIT_TO_TEMPLATE might be slower since it has to rototranslate all the available atoms and
+     160             : (b) variables employing periodic boundary conditions (such as \ref DISTANCE without `NOPBC`, as in the example above)
+     161             :   are allowed after \ref FIT_TO_TEMPLATE, whereas \ref RMSD expects the issues related to the periodic boundary conditions to be already solved.
+     162             : The latter means that before the \ref RMSD statement one should use \ref WRAPAROUND or \ref WHOLEMOLECULES to properly place
+     163             : the ligand.
+     164             : 
+     165             : 
+     166             : */
+     167             : //+ENDPLUMEDOC
+     168             : 
+     169             : 
+     170             : class FitToTemplate:
+     171             :   public ActionPilot,
+     172             :   public ActionAtomistic,
+     173             :   public ActionWithValue
+     174             : {
+     175             :   std::string type;
+     176             :   bool nopbc;
+     177             :   std::vector<double> weights;
+     178             :   std::vector<std::pair<std::size_t,std::size_t> > p_aligned;
+     179             :   Vector center;
+     180             :   Vector shift;
+     181             :   // optimal alignment related stuff
+     182             :   std::unique_ptr<PLMD::RMSD> rmsd;
+     183             :   Tensor rotation;
+     184             :   Matrix< std::vector<Vector> > drotdpos;
+     185             :   // not used anymore (see notes below at doNotRetrieve())
+     186             :   // std::vector<Vector> positions;
+     187             :   std::vector<Vector> DDistDRef;
+     188             :   std::vector<Vector> ddistdpos;
+     189             :   std::vector<Vector> centeredpositions;
+     190             :   Vector center_positions;
+     191             :   // Copy of the box value
+     192             :   Value* boxValue;
+     193             :   PbcAction* pbc_action;
+     194             : public:
+     195             :   explicit FitToTemplate(const ActionOptions&ao);
+     196             :   static void registerKeywords( Keywords& keys );
+     197             :   void calculate() override;
+     198             :   void apply() override;
+     199           0 :   unsigned getNumberOfDerivatives() override {plumed_merror("You should not call this function");};
+     200             : };
+     201             : 
+     202             : PLUMED_REGISTER_ACTION(FitToTemplate,"FIT_TO_TEMPLATE")
+     203             : 
+     204          11 : void FitToTemplate::registerKeywords( Keywords& keys ) {
+     205          11 :   Action::registerKeywords( keys );
+     206          11 :   ActionAtomistic::registerKeywords( keys );
+     207          22 :   keys.add("compulsory","STRIDE","1","the frequency with which molecules are reassembled.  Unless you are completely certain about what you are doing leave this set equal to 1!");
+     208          22 :   keys.add("compulsory","REFERENCE","a file in pdb format containing the reference structure and the atoms involved in the CV.");
+     209          22 :   keys.add("compulsory","TYPE","SIMPLE","the manner in which RMSD alignment is performed.  Should be OPTIMAL or SIMPLE.");
+     210          22 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     211          11 : }
+     212             : 
+     213           9 : FitToTemplate::FitToTemplate(const ActionOptions&ao):
+     214             :   Action(ao),
+     215             :   ActionPilot(ao),
+     216             :   ActionAtomistic(ao),
+     217             :   ActionWithValue(ao),
+     218          18 :   nopbc(false)
+     219             : {
+     220             :   std::string reference;
+     221           9 :   parse("REFERENCE",reference);
+     222           9 :   type.assign("SIMPLE");
+     223           9 :   parse("TYPE",type);
+     224             : 
+     225           9 :   parseFlag("NOPBC",nopbc);
+     226             : // if(type!="SIMPLE") error("Only TYPE=SIMPLE is implemented in FIT_TO_TEMPLATE");
+     227             : 
+     228           9 :   checkRead();
+     229             : 
+     230           9 :   PDB pdb;
+     231             : 
+     232             :   // read everything in ang and transform to nm if we are not in natural units
+     233           9 :   if( !pdb.read(reference,usingNaturalUnits(),0.1/getUnits().getLength()) )
+     234           0 :     error("missing input file " + reference );
+     235             : 
+     236           9 :   requestAtoms(pdb.getAtomNumbers());
+     237           9 :   log.printf("  found %zu atoms in input \n",pdb.getAtomNumbers().size());
+     238           9 :   log.printf("  with indices : ");
+     239          42 :   for(unsigned i=0; i<pdb.getAtomNumbers().size(); ++i) {
+     240          33 :     if(i%25==0) log<<"\n";
+     241          33 :     log.printf("%d ",pdb.getAtomNumbers()[i].serial());
+     242             :   }
+     243           9 :   log.printf("\n");
+     244             : 
+     245           9 :   std::vector<Vector> positions=pdb.getPositions();
+     246           9 :   weights=pdb.getOccupancy();
+     247           9 :   std::vector<AtomNumber> aligned=pdb.getAtomNumbers(); p_aligned.resize( aligned.size() );
+     248          42 :   for(unsigned i=0; i<aligned.size(); ++i) p_aligned[i] = getValueIndices( aligned[i] );
+     249             : 
+     250             : 
+     251             :   // normalize weights
+     252          42 :   double n=0.0; for(unsigned i=0; i<weights.size(); ++i) n+=weights[i];
+     253           9 :   if(n==0.0) {
+     254           0 :     error("PDB file " + reference + " has zero weights. Please check the occupancy column.");
+     255             :   }
+     256           9 :   n=1.0/n;
+     257          42 :   for(unsigned i=0; i<weights.size(); ++i) weights[i]*=n;
+     258             : 
+     259             :   // normalize weights for rmsd calculation
+     260           9 :   std::vector<double> weights_measure=pdb.getBeta();
+     261          42 :   n=0.0; for(unsigned i=0; i<weights_measure.size(); ++i) n+=weights_measure[i]; n=1.0/n;
+     262          42 :   for(unsigned i=0; i<weights_measure.size(); ++i) weights_measure[i]*=n;
+     263             : 
+     264             :   // subtract the center
+     265          42 :   for(unsigned i=0; i<weights.size(); ++i) center+=positions[i]*weights[i];
+     266          42 :   for(unsigned i=0; i<weights.size(); ++i) positions[i]-=center;
+     267             : 
+     268          13 :   if(type=="OPTIMAL" or type=="OPTIMAL-FAST" ) {
+     269           5 :     rmsd=Tools::make_unique<RMSD>();
+     270           5 :     rmsd->set(weights,weights_measure,positions,type,false,false);// note: the reference is shifted now with center in the origin
+     271          10 :     log<<"  Method chosen for fitting: "<<rmsd->getMethod()<<" \n";
+     272             :   }
+     273           9 :   if(nopbc) {
+     274           1 :     log<<"  Ignoring PBCs when doing alignment, make sure your molecule is whole!<n";
+     275             :   }
+     276             :   // register the value of rmsd (might be useful sometimes)
+     277          18 :   addValue(); setNotPeriodic();
+     278             : 
+     279             :   // I remove this optimization now in order to use makeWhole()
+     280             :   // Notice that for FIT_TO_TEMPLATE TYPE=OPTIMAL a copy was made anyway
+     281             :   // (due to the need to store position to propagate forces on rotational matrix later)
+     282             :   // For FIT_TO_TEMPLATE TYPE=SIMPLE in principle we could use it and write an ad hoc
+     283             :   // version of makeWhole that only computes the center. Too lazy to do it now.
+     284             :   // In case we do it later, remember that uncommenting this line means that
+     285             :   // getPositions will not work anymore! GB
+     286             :   // doNotRetrieve();
+     287             : 
+     288             :   // this is required so as to allow modifyGlobalForce() to return correct
+     289             :   // also for forces that are not owned (and thus not zeored) by all processors.
+     290           9 :   pbc_action=plumed.getActionSet().selectWithLabel<PbcAction*>("Box");
+     291           9 :   if( !pbc_action ) error("cannot align box has not been set");
+     292           9 :   boxValue=pbc_action->copyOutput(0);
+     293          18 : }
+     294             : 
+     295             : 
+     296         108 : void FitToTemplate::calculate() {
+     297             : 
+     298         108 :   if(!nopbc) makeWhole();
+     299             : 
+     300         108 :   if (type=="SIMPLE") {
+     301          48 :     Vector cc;
+     302             : 
+     303         144 :     for(unsigned i=0; i<p_aligned.size(); ++i) {
+     304          96 :       cc+=weights[i]*getPosition(i);
+     305             :     }
+     306             : 
+     307          48 :     shift=center-cc;
+     308          48 :     setValue(shift.modulo());
+     309          48 :     unsigned nat = getTotAtoms();
+     310        6384 :     for(unsigned i=0; i<nat; i++) {
+     311        6336 :       std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     312        6336 :       Vector ato=getGlobalPosition(a);
+     313        6336 :       setGlobalPosition(a,ato+shift);
+     314             :     }
+     315             :   }
+     316          60 :   else if( type=="OPTIMAL" or type=="OPTIMAL-FAST") {
+     317             :     // specific stuff that provides all that is needed
+     318          60 :     double r=rmsd->calc_FitElements( getPositions(), rotation,  drotdpos, centeredpositions, center_positions);
+     319          60 :     setValue(r); unsigned nat = getTotAtoms();
+     320        8004 :     for(unsigned i=0; i<nat; i++) {
+     321        7944 :       std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     322        7944 :       Vector ato=getGlobalPosition(a);
+     323        7944 :       setGlobalPosition(a,matmul(rotation,ato-center_positions)+center);
+     324             :     }
+     325             : // rotate box
+     326          60 :     Pbc& pbc(pbc_action->getPbc());
+     327          60 :     pbc.setBox(matmul(pbc_action->getPbc().getBox(),transpose(rotation)));
+     328             :   }
+     329         108 : }
+     330             : 
+     331         108 : void FitToTemplate::apply() {
+     332         108 :   auto nat=getTotAtoms();
+     333         108 :   if (type=="SIMPLE") {
+     334          48 :     Vector totForce;
+     335        6384 :     for(unsigned i=0; i<nat; i++) {
+     336        6336 :       std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     337        6336 :       totForce+=getForce(a);
+     338             :     }
+     339          48 :     Tensor vv=Tensor(center,totForce);
+     340         624 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) boxValue->addForce( 3*i+j, vv(i,j) );
+     341         144 :     for(unsigned i=0; i<p_aligned.size(); ++i) { addForce( p_aligned[i], -totForce*weights[i]); }
+     342          60 :   } else if ( type=="OPTIMAL" or type=="OPTIMAL-FAST") {
+     343          60 :     Vector totForce;
+     344        8004 :     for(unsigned i=0; i<nat; i++) {
+     345        7944 :       std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     346        7944 :       Vector f=getForce(a);
+     347             : // rotate back forces
+     348        7944 :       Vector nf=matmul(transpose(rotation),f);
+     349        7944 :       addForce(a, nf-f);
+     350             : // accumulate rotated c.o.m. forces - this is already in the non rotated reference frame
+     351        7944 :       totForce+=nf;
+     352             :     }
+     353          60 :     Tensor virial;
+     354         780 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) virial[i][j] = boxValue->getForce( 3*i+j );
+     355             : // notice that an extra Tensor(center,matmul(rotation,totForce)) is required to
+     356             : // compute the derivatives of the rotation with respect to center
+     357          60 :     Tensor ww=matmul(transpose(rotation),virial+Tensor(center,matmul(rotation,totForce)));
+     358             : // rotate back virial
+     359          60 :     virial=matmul(transpose(rotation),matmul(virial,rotation));
+     360             : 
+     361             : // now we compute the force due to alignment
+     362         360 :     for(unsigned i=0; i<p_aligned.size(); i++) {
+     363         300 :       Vector g;
+     364        1200 :       for(unsigned k=0; k<3; k++) {
+     365             : // this could be made faster computing only the diagonal of d
+     366         900 :         Tensor d=matmul(ww,RMSD::getMatrixFromDRot(drotdpos,i,k));
+     367         900 :         g[k]=(d(0,0)+d(1,1)+d(2,2));
+     368             :       }
+     369             : // here is the extra contribution
+     370         300 :       addForce( p_aligned[i], -g-weights[i]*totForce );
+     371             : // here it the contribution to the virial
+     372             : // notice that here we can use absolute positions since, for the alignment to be defined,
+     373             : // positions should be in one well defined periodic image
+     374         300 :       virial+=extProduct(getPosition(i),g);
+     375             :     }
+     376             : // finally, correction to the virial
+     377         120 :     boxValue->clearInputForce(); virial+=extProduct(matmul(transpose(rotation),center),totForce);
+     378         780 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) boxValue->addForce( 3*i+j, virial(i,j) );
+     379             :   }
+     380         108 : }
+     381             : 
+     382             : }
+     383             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Flush.cpp.func-sort-c.html b/coverage/generic/Flush.cpp.func-sort-c.html new file mode 100644 index 000000000000..af5af0463e07 --- /dev/null +++ b/coverage/generic/Flush.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Flush.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Flush.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5FlushC1ERKNS_13ActionOptionsE17
_ZN4PLMD7generic5Flush16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD7generic5Flush5applyEv561
_ZN4PLMD7generic5Flush6updateEv561
_ZN4PLMD7generic5Flush9calculateEv561
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Flush.cpp.func.html b/coverage/generic/Flush.cpp.func.html new file mode 100644 index 000000000000..ac8578704a89 --- /dev/null +++ b/coverage/generic/Flush.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Flush.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Flush.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5Flush16registerKeywordsERNS_8KeywordsE19
_ZN4PLMD7generic5Flush5applyEv561
_ZN4PLMD7generic5Flush6updateEv561
_ZN4PLMD7generic5Flush9calculateEv561
_ZN4PLMD7generic5FlushC1ERKNS_13ActionOptionsE17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Flush.cpp.gcov.html b/coverage/generic/Flush.cpp.gcov.html new file mode 100644 index 000000000000..b17dd683bed5 --- /dev/null +++ b/coverage/generic/Flush.cpp.gcov.html @@ -0,0 +1,168 @@ + + + + + + + + LCOV - plumed test coverage - generic/Flush.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Flush.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace generic {
+      29             : 
+      30             : //+PLUMEDOC GENERIC FLUSH
+      31             : /*
+      32             : This command instructs plumed to flush all the open files with a user specified frequency.
+      33             : Notice that all files are flushed anyway every 10000 steps.
+      34             : 
+      35             : This
+      36             : is useful for preventing data loss that would otherwise arise as a consequence of the code
+      37             : storing data for printing in the buffers. Notice that wherever it is written in the
+      38             : plumed input file, it will flush all the open files.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : A command like this in the input will instruct plumed to flush all the output files every 100 steps
+      43             : \plumedfile
+      44             : d1: DISTANCE ATOMS=1,10
+      45             : PRINT ARG=d1 STRIDE=5 FILE=colvar1
+      46             : 
+      47             : FLUSH STRIDE=100
+      48             : 
+      49             : d2: DISTANCE ATOMS=2,11
+      50             : # also this print is flushed every 100 steps:
+      51             : PRINT ARG=d2 STRIDE=10 FILE=colvar2
+      52             : \endplumedfile
+      53             : (see also \ref DISTANCE and \ref PRINT).
+      54             : */
+      55             : //+ENDPLUMEDOC
+      56             : 
+      57             : class Flush:
+      58             :   public ActionPilot
+      59             : {
+      60             : public:
+      61          17 :   explicit Flush(const ActionOptions&ao):
+      62             :     Action(ao),
+      63          17 :     ActionPilot(ao)
+      64             :   {
+      65          17 :     checkRead();
+      66          17 :   }
+      67             :   static void registerKeywords( Keywords& keys );
+      68         561 :   void calculate() override {}
+      69         561 :   void apply() override {}
+      70         561 :   void update() override {
+      71         561 :     plumed.fflush();
+      72         561 :     log.flush();
+      73         561 :     const ActionSet & actionSet(plumed.getActionSet());
+      74        8430 :     for(const auto & p : actionSet)
+      75        7869 :       p->fflush();
+      76         561 :   }
+      77             : };
+      78             : 
+      79             : PLUMED_REGISTER_ACTION(Flush,"FLUSH")
+      80             : 
+      81          19 : void Flush::registerKeywords( Keywords& keys ) {
+      82          19 :   Action::registerKeywords( keys );
+      83          19 :   ActionPilot::registerKeywords( keys );
+      84          38 :   keys.add("compulsory","STRIDE","the frequency with which all the open files should be flushed");
+      85          19 :   keys.remove("LABEL");
+      86          19 : }
+      87             : 
+      88             : }
+      89             : }
+      90             : 
+      91             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Include.cpp.func-sort-c.html b/coverage/generic/Include.cpp.func-sort-c.html new file mode 100644 index 000000000000..65d3a8c72ac6 --- /dev/null +++ b/coverage/generic/Include.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Include.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Include.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101283.3 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7Include5applyEv0
_ZN4PLMD7generic7Include9calculateEv0
_ZN4PLMD7generic7IncludeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic7IncludeC1ERKNS_13ActionOptionsE18
_ZN4PLMD7generic7Include16registerKeywordsERNS_8KeywordsE20
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Include.cpp.func.html b/coverage/generic/Include.cpp.func.html new file mode 100644 index 000000000000..6781dca626de --- /dev/null +++ b/coverage/generic/Include.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/Include.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Include.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101283.3 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic7Include16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD7generic7Include5applyEv0
_ZN4PLMD7generic7Include9calculateEv0
_ZN4PLMD7generic7IncludeC1ERKNS_13ActionOptionsE18
_ZN4PLMD7generic7IncludeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Include.cpp.gcov.html b/coverage/generic/Include.cpp.gcov.html new file mode 100644 index 000000000000..54156321c93d --- /dev/null +++ b/coverage/generic/Include.cpp.gcov.html @@ -0,0 +1,256 @@ + + + + + + + + LCOV - plumed test coverage - generic/Include.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Include.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101283.3 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/Action.h"
+      23             : #include "core/ActionAnyorder.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "tools/Exception.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace generic {
+      30             : 
+      31             : //+PLUMEDOC GENERIC INCLUDE
+      32             : /*
+      33             : Includes an external input file, similar to #include in C preprocessor.
+      34             : 
+      35             : Useful to split very large plumed.dat files. Notice that in PLUMED 2.4 this action
+      36             : cannot be used before the initial setup part of the file (e.g. in the part with \ref UNITS, \ref MOLINFO, etc).
+      37             : As of PLUMED 2.5, \ref INCLUDE can be used in any position of the file.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : This input:
+      42             : \plumedfile
+      43             : c1: COM ATOMS=1-100
+      44             : c2: COM ATOMS=101-202
+      45             : d: DISTANCE ATOMS=c1,c2
+      46             : PRINT ARG=d
+      47             : \endplumedfile
+      48             : can be replaced with this input:
+      49             : \plumedfile
+      50             : INCLUDE FILE=pippo.dat
+      51             : d: DISTANCE ATOMS=c1,c2
+      52             : PRINT ARG=d
+      53             : \endplumedfile
+      54             : where the content of file pippo.dat is
+      55             : \plumedfile
+      56             : #SETTINGS FILENAME=pippo.dat
+      57             : # this is pippo.dat
+      58             : c1: COM ATOMS=1-100
+      59             : c2: COM ATOMS=101-202
+      60             : \endplumedfile
+      61             : 
+      62             : The files in this example are rather short, but imagine a case like this one:
+      63             : \plumedfile
+      64             : INCLUDE FILE=groups.dat
+      65             : c: COORDINATION GROUPA=groupa GROUPB=groupb R_0=0.5
+      66             : METAD ARG=c HEIGHT=0.2 PACE=100 SIGMA=0.2 BIASFACTOR=5
+      67             : \endplumedfile
+      68             : Here `groups.dat` could be a huge file containing group definitions.  This groups.dat file might look something
+      69             : like the following example but with more atom indices in the groups.
+      70             : \plumedfile
+      71             : #SETTINGS FILENAME=groups.dat
+      72             : # this is groups.dat
+      73             : groupa: GROUP ...
+      74             :   ATOMS={
+      75             :     10
+      76             :     50
+      77             :     60
+      78             :     70
+      79             :     80
+      80             :     120
+      81             :   }
+      82             : ...
+      83             : groupb: GROUP ...
+      84             :   ATOMS={
+      85             :     11
+      86             :     51
+      87             :     61
+      88             :     71
+      89             :     81
+      90             :     121
+      91             :   }
+      92             : ...
+      93             : \endplumedfile
+      94             : So, included files are the best place where one can store long definitions.
+      95             : 
+      96             : Another case where INCLUDE is very useful is when running multi-replica simulations.
+      97             : Here different replicas might have different input files, but perhaps a large part of the
+      98             : input is shared. This part can be put in a common included file. For instance you could have
+      99             : `common.dat`:
+     100             : \plumedfile
+     101             : #SETTINGS FILENAME=common.dat
+     102             : # this is common.dat
+     103             : t: TORSION ATOMS=1,2,3,4
+     104             : \endplumedfile
+     105             : Then `plumed.0.dat`:
+     106             : \plumedfile
+     107             : # this is plumed.0.dat
+     108             : INCLUDE FILE=common.dat
+     109             : RESTRAINT ARG=t AT=1.0 KAPPA=10
+     110             : \endplumedfile
+     111             : And `plumed.1.dat`:
+     112             : \plumedfile
+     113             : # this is plumed.1.dat
+     114             : INCLUDE FILE=common.dat
+     115             : RESTRAINT ARG=t AT=1.2 KAPPA=10
+     116             : \endplumedfile
+     117             : 
+     118             : \warning
+     119             : Remember that when using multi replica simulations whenever plumed tried to open
+     120             : a file for reading it looks for a file with the replica suffix first.
+     121             : This is true also for files opened by INCLUDE!
+     122             : 
+     123             : As an example, the same result of the inputs above could have been obtained using
+     124             : the following `plumed.dat` file:
+     125             : \plumedfile
+     126             : #SETTINGS NREPLICAS=2
+     127             : t: TORSION ATOMS=1,2,3,4
+     128             : INCLUDE FILE=other.inc
+     129             : \endplumedfile
+     130             : Then `other.0.inc`:
+     131             : \plumedfile
+     132             : #SETTINGS FILENAME=other.0.inc
+     133             : # this is other.0.inc
+     134             : RESTRAINT ARG=t AT=1.0 KAPPA=10
+     135             : \endplumedfile
+     136             : And `other.1.inc`:
+     137             : \plumedfile
+     138             : #SETTINGS FILENAME=other.1.inc
+     139             : # this is other.1.inc
+     140             : RESTRAINT ARG=t AT=1.2 KAPPA=10
+     141             : \endplumedfile
+     142             : 
+     143             : 
+     144             : 
+     145             : 
+     146             : 
+     147             : */
+     148             : //+ENDPLUMEDOC
+     149             : 
+     150             : class Include :
+     151             :   public ActionAnyorder
+     152             : {
+     153             : public:
+     154             :   static void registerKeywords( Keywords& keys );
+     155             :   explicit Include(const ActionOptions&ao);
+     156           0 :   void calculate() override {}
+     157           0 :   void apply() override {}
+     158             : };
+     159             : 
+     160             : PLUMED_REGISTER_ACTION(Include,"INCLUDE")
+     161             : 
+     162          20 : void Include::registerKeywords( Keywords& keys ) {
+     163          20 :   Action::registerKeywords(keys);
+     164          40 :   keys.add("compulsory","FILE","file to be included");
+     165          20 : }
+     166             : 
+     167          18 : Include::Include(const ActionOptions&ao):
+     168             :   Action(ao),
+     169          18 :   ActionAnyorder(ao)
+     170             : {
+     171             :   std::string f;
+     172          18 :   parse("FILE",f);
+     173          18 :   checkRead();
+     174          18 :   plumed.readInputFile(f);
+     175          18 : }
+     176             : 
+     177             : }
+     178             : }
+     179             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Plumed.cpp.func-sort-c.html b/coverage/generic/Plumed.cpp.func-sort-c.html new file mode 100644 index 000000000000..899d1a0316d6 --- /dev/null +++ b/coverage/generic/Plumed.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - generic/Plumed.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Plumed.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16517793.2 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic6Plumed22getNumberOfDerivativesEv0
_ZN4PLMD7generic6PlumedC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic6PlumedC1ERKNS_13ActionOptionsE12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE0_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE1_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE_clEv12
_ZN4PLMD7generic6Plumed16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7generic6Plumed5applyEv104
_ZN4PLMD7generic6Plumed6updateEv104
_ZN4PLMD7generic6Plumed9calculateEv134
_ZN4PLMD7generic6Plumed7prepareEv164
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Plumed.cpp.func.html b/coverage/generic/Plumed.cpp.func.html new file mode 100644 index 000000000000..084a37f903f5 --- /dev/null +++ b/coverage/generic/Plumed.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - generic/Plumed.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Plumed.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16517793.2 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic6Plumed16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD7generic6Plumed22getNumberOfDerivativesEv0
_ZN4PLMD7generic6Plumed5applyEv104
_ZN4PLMD7generic6Plumed6updateEv104
_ZN4PLMD7generic6Plumed7prepareEv164
_ZN4PLMD7generic6Plumed9calculateEv134
_ZN4PLMD7generic6PlumedC1ERKNS_13ActionOptionsE12
_ZN4PLMD7generic6PlumedC2ERKNS_13ActionOptionsE0
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE0_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE1_clEv12
_ZZN4PLMD7generic6PlumedC4ERKNS_13ActionOptionsEENKUlvE_clEv12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Plumed.cpp.gcov.html b/coverage/generic/Plumed.cpp.gcov.html new file mode 100644 index 000000000000..f1d0d9caf25e --- /dev/null +++ b/coverage/generic/Plumed.cpp.gcov.html @@ -0,0 +1,493 @@ + + + + + + + + LCOV - plumed test coverage - generic/Plumed.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Plumed.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16517793.2 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAtomistic.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionPilot.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Tools.h"
+      27             : #include "tools/PlumedHandle.h"
+      28             : #include "tools/Communicator.h"
+      29             : #include "core/PlumedMain.h"
+      30             : #include <cstring>
+      31             : #ifdef __PLUMED_HAS_DLOPEN
+      32             : #include <dlfcn.h>
+      33             : #endif
+      34             : 
+      35             : #include <iostream>
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace generic {
+      39             : 
+      40             : //+PLUMEDOC GENERIC PLUMED
+      41             : /*
+      42             : Embed a separate PLUMED instance.
+      43             : 
+      44             : This command can be used to embed a separate PLUMED instance.
+      45             : Only required atoms will be passed to that instance, using an interface
+      46             : that is similar to the one used when calling PLUMED from the NAMD engine.
+      47             : 
+      48             : Notice that the two instances are running in the same UNIX process, so that they cannot be perfectly isolated.
+      49             : However, most of the features are expected to work correctly.
+      50             : 
+      51             : Notes:
+      52             : - The \ref LOAD action will not work correctly since registers will be shared among the two instances.
+      53             :   In particular, the loaded actions will be visible to both guest and host irrespective of where they are loaded from.
+      54             :   This can be fixed and will probably be fixed in a later version.
+      55             : - `CHDIR` is not thread safe.
+      56             :    However, in most implementations there will be a single process running PLUMED, with perhaps multiple OpenMP threads
+      57             :    spawn in order to parallelize the calculation of individual variables. So, this is likely not a problem.
+      58             : - MPI is working correctly. However, notice that the guest PLUMED will always run with a single process.
+      59             :   Multiple replicas should be handled correctly.
+      60             : 
+      61             : As an advanced feature, one can use the option `KERNEL` to select the version of the guest PLUMED instance.
+      62             : In particular, an empty `KERNEL` (default) implies that the guest PLUMED instance is the same as the host one
+      63             : (no library is loaded).
+      64             : On the other hand, `KERNEL=/path/to/libplumedKernel.so` will allow specifying a library to be loaded for the
+      65             : guest instance.
+      66             : In addition to those mentioned above, this feature has limitations mostly related to
+      67             : clashes in the symbols defined in the different instances of the PLUMED library.
+      68             : Clashes might be due by synonymous symbols from the PLUMED library or synonymous symbols
+      69             : from libraries linked to PLUMED, and would differ depending on the operating system you
+      70             : are using:
+      71             : - On OSX:
+      72             :   - Symbols from the PLUMED library would clash. The only way to avoid is to load PLUMED dynamically:
+      73             :     - If you are are using PLUMED with an MD code, it should be patched with `--runtime`.
+      74             :     - If you are using PLUMED driver, you should launch the `plumed-runtime` executable (contained in the
+      75             :       `prefix/lib/plumed/` directory) and export `PLUMED_KERNEL` equal to the path of the host kernel library
+      76             :      (as usual in runtime loading). Notice that as of PLUMED 2.10 we load kernels with RTLD_LOCAL by default.
+      77             :     - Symbols from dependent libraries should not clash since, as of version 2.5, we are using
+      78             :       two-level namespace. Problems when loading previous versions should anyway be solved using runtime
+      79             :       mode as explained above.
+      80             : - On Linux, any `KERNEL` should in principle work correctly. To achieve namespace separation we are loading
+      81             :   the guest kernel with `RTLD_DEEPBIND`. However, this might create difficult to track problems in other linked libraries.
+      82             : - On Unix systems where `RTLD_DEEPBIND` is not available kernels will not load correctly.
+      83             : - In general, there might be unexpected crashes. Particularly difficult are situations where different
+      84             :   kernels were compiled with different libraries.
+      85             : 
+      86             : \todo
+      87             : - Add support for multiple time stepping (`STRIDE` different from 1).
+      88             : - Add the possibility to import CVs calculated in the host PLUMED instance into the guest PLUMED instance.
+      89             :   Will be possible after \issue{83} will be closed.
+      90             : - Add the possibility to export CVs calculated in the guest PLUMED instance into the host PLUMED instance.
+      91             :   Could be implemented using the `DataFetchingObject` class.
+      92             : 
+      93             : \par Examples
+      94             : 
+      95             : Here an example plumed file:
+      96             : \plumedfile
+      97             : # plumed.dat
+      98             : p: PLUMED FILE=plumed2.dat
+      99             : PRINT ARG=p.bias FILE=COLVAR
+     100             : \endplumedfile
+     101             : `plumed2.dat` can be an arbitrary plumed input file, for instance
+     102             : \plumedfile
+     103             : #SETTINGS FILENAME=plumed2.dat
+     104             : # plumed2.dat
+     105             : d: DISTANCE ATOMS=1,10
+     106             : RESTRAINT ARG=d KAPPA=10 AT=2
+     107             : \endplumedfile
+     108             : 
+     109             : Now a more useful example.
+     110             : Imagine that you ran simulations using two different PLUMED input files.
+     111             : The files are long and complex and there are some clashes in the name of the variables (that is: same names
+     112             : are used in both files, same files are written, etc). In addition, files might have been written using different units (see \ref UNITS`).
+     113             : If you want to run a single simulation with a bias potential
+     114             : that is the sum of the two bias potentials, you can:
+     115             : - Place the two input files, as well as all the files required by plumed, in separate directories `directory1` and `directory2`.
+     116             : - Run with the following input file in the parent directory:
+     117             : \plumedfile
+     118             : # plumed.dat
+     119             : PLUMED FILE=plumed.dat CHDIR=directory1
+     120             : PLUMED FILE=plumed.dat CHDIR=directory2
+     121             : \endplumedfile
+     122             : 
+     123             : */
+     124             : //+ENDPLUMEDOC
+     125             : 
+     126             : class Plumed:
+     127             :   public ActionAtomistic,
+     128             :   public ActionWithValue,
+     129             :   public ActionPilot
+     130             : {
+     131             : /// True on root processor
+     132             :   const bool root;
+     133             : /// Separate directory.
+     134             :   const std::string directory;
+     135             : /// Interface to underlying plumed object.
+     136             :   PlumedHandle p;
+     137             : /// API number.
+     138             :   const int API;
+     139             : /// Self communicator
+     140             :   Communicator comm_self;
+     141             : /// Intercommunicator
+     142             :   Communicator intercomm;
+     143             : /// Detect first usage.
+     144             :   bool first=true;
+     145             : /// Stop flag, used to stop e.g. in committor analysis
+     146             :   int stop=0;
+     147             : /// Index of requested atoms.
+     148             :   std::vector<int> index;
+     149             : /// Masses of requested atoms.
+     150             :   std::vector<double> masses;
+     151             : /// Charges of requested atoms.
+     152             :   std::vector<double> charges;
+     153             : /// Forces on requested atoms.
+     154             :   std::vector<double> forces;
+     155             : /// Requested positions.
+     156             :   std::vector<double> positions;
+     157             : /// Applied virial.
+     158             :   Tensor virial;
+     159             : public:
+     160             : /// Constructor.
+     161             :   explicit Plumed(const ActionOptions&);
+     162             : /// Documentation.
+     163             :   static void registerKeywords( Keywords& keys );
+     164             :   void prepare() override;
+     165             :   void calculate() override;
+     166             :   void apply() override;
+     167             :   void update() override;
+     168           0 :   unsigned getNumberOfDerivatives() override {
+     169           0 :     return 0;
+     170             :   }
+     171             : };
+     172             : 
+     173             : PLUMED_REGISTER_ACTION(Plumed,"PLUMED")
+     174             : 
+     175          14 : void Plumed::registerKeywords( Keywords& keys ) {
+     176          14 :   Action::registerKeywords( keys );
+     177          14 :   ActionPilot::registerKeywords( keys );
+     178          14 :   ActionAtomistic::registerKeywords( keys );
+     179          28 :   keys.add("compulsory","STRIDE","1","stride different from 1 are not supported yet");
+     180          28 :   keys.add("optional","FILE","input file for the guest PLUMED instance");
+     181          28 :   keys.add("optional","KERNEL","kernel to be used for the guest PLUMED instance (USE WITH CAUTION!)");
+     182          28 :   keys.add("optional","LOG","log file for the guest PLUMED instance. By default the host log is used");
+     183          28 :   keys.add("optional","CHDIR","run guest in a separate directory");
+     184          28 :   keys.addFlag("NOREPLICAS",false,"run multiple replicas as isolated ones, without letting them know that the host has multiple replicas");
+     185          28 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potential");
+     186          14 : }
+     187             : 
+     188          12 : Plumed::Plumed(const ActionOptions&ao):
+     189             :   Action(ao),
+     190             :   ActionAtomistic(ao),
+     191             :   ActionWithValue(ao),
+     192             :   ActionPilot(ao),
+     193          24 :   root(comm.Get_rank()==0),
+     194          24 :   directory([&]() {
+     195             :   std::string directory;
+     196          24 :   parse("CHDIR",directory);
+     197          12 :   if(directory.length()>0) {
+     198           0 :     log<<"  running on separate directory "<<directory<<"\n";
+     199             :   }
+     200          12 :   return directory;
+     201             : }()),
+     202          24 : p([&]() {
+     203             :   std::string kernel;
+     204          24 :   parse("KERNEL",kernel);
+     205          12 :   if(kernel.length()==0) {
+     206          11 :     log<<"  using the current kernel\n";
+     207          11 :     return PlumedHandle();
+     208             :   } else {
+     209           1 :     log<<"  using the kernel "<<kernel<<"\n";
+     210           1 :     return PlumedHandle::dlopen(kernel.c_str());
+     211             :   }
+     212             : }()),
+     213          24 : API([&]() {
+     214          12 :   int api=0;
+     215          12 :   p.cmd("getApiVersion",&api);
+     216          12 :   log<<"  reported API version is "<<api<<"\n";
+     217             :   // note: this is required in order to have cmd performCalcNoUpdate and cmd update
+     218             :   // as a matter of fact, any version <2.5 will not even load due to namespace pollution
+     219          12 :   plumed_assert(api>3) << "API>3 is required for the PLUMED action to work correctly\n";
+     220          12 :   return api;
+     221          24 : }())
+     222             : {
+     223          12 :   Tools::DirectoryChanger directoryChanger(directory.c_str());
+     224             : 
+     225             :   bool noreplicas;
+     226          12 :   parseFlag("NOREPLICAS",noreplicas);
+     227             :   int nreps;
+     228          12 :   if(root) nreps=multi_sim_comm.Get_size();
+     229          12 :   comm.Bcast(nreps,0);
+     230          12 :   if(nreps>1) {
+     231           6 :     if(noreplicas) {
+     232           0 :       log<<"  running replicas as independent (no suffix used)\n";
+     233             :     } else {
+     234           6 :       log<<"  running replicas as standard multi replic (with suffix)\n";
+     235           6 :       if(root) {
+     236           6 :         intercomm.Set_comm(&multi_sim_comm.Get_comm());
+     237           6 :         p.cmd("GREX setMPIIntercomm",&intercomm.Get_comm());
+     238           6 :         p.cmd("GREX setMPIIntracomm",&comm_self.Get_comm());
+     239           3 :         p.cmd("GREX init");
+     240             :       }
+     241             :     }
+     242             :   } else {
+     243           6 :     if(noreplicas) {
+     244           0 :       log<<"  WARNING: flag NOREPLICAS ignored since we are running without replicas\n";
+     245             :     }
+     246             :   }
+     247             : 
+     248          12 :   int natoms=getTotAtoms();
+     249             : 
+     250          12 :   plumed_assert(getStride()==1) << "currently only supports STRIDE=1";
+     251             : 
+     252          12 :   double dt=getTimeStep();
+     253             : 
+     254             :   std::string file;
+     255          24 :   parse("FILE",file);
+     256          12 :   if(file.length()>0) {
+     257          12 :     log<<"  with input file "<<file<<"\n";
+     258           0 :   } else plumed_error() << "you must provide an input file\n";
+     259             : 
+     260             :   bool inherited_logfile=false;
+     261             :   std::string logfile;
+     262          24 :   parse("LOG",logfile);
+     263          12 :   if(logfile.length()>0) {
+     264           0 :     log<<"  with log file "<<logfile<<"\n";
+     265           0 :     if(root) p.cmd("setLogFile",logfile.c_str());
+     266          12 :   } else if(log.getFILE()) {
+     267          12 :     log<<"  with inherited log file\n";
+     268          12 :     if(root) p.cmd("setLog",log.getFILE());
+     269             :     inherited_logfile=true;
+     270             :   } else {
+     271           0 :     log<<"  with log on stdout\n";
+     272           0 :     if(root) p.cmd("setLog",stdout);
+     273             :   }
+     274             : 
+     275          12 :   checkRead();
+     276             : 
+     277          12 :   if(root) p.cmd("setMDEngine","plumed");
+     278             : 
+     279          12 :   double engunits=getUnits().getEnergy();
+     280          12 :   if(root) p.cmd("setMDEnergyUnits",&engunits);
+     281             : 
+     282          12 :   double lenunits=getUnits().getLength();
+     283          12 :   if(root) p.cmd("setMDLengthUnits",&lenunits);
+     284             : 
+     285          12 :   double timunits=getUnits().getTime();
+     286          12 :   if(root) p.cmd("setMDTimeUnits",&timunits);
+     287             : 
+     288          12 :   double chaunits=getUnits().getCharge();
+     289          12 :   if(root) p.cmd("setMDChargeUnits",&chaunits);
+     290          12 :   double masunits=getUnits().getMass();
+     291          12 :   if(root) p.cmd("setMDMassUnits",&masunits);
+     292             : 
+     293          12 :   double kbt=getkBT();
+     294          12 :   if(root) p.cmd("setKbT",&kbt);
+     295             : 
+     296          12 :   int res=0;
+     297          12 :   if(getRestart()) res=1;
+     298          12 :   if(root) p.cmd("setRestart",&res);
+     299             : 
+     300          12 :   if(root) p.cmd("setNatoms",&natoms);
+     301          12 :   if(root) p.cmd("setTimestep",&dt);
+     302          12 :   if(root) p.cmd("setPlumedDat",file.c_str());
+     303             : 
+     304          24 :   addComponentWithDerivatives("bias");
+     305          12 :   componentIsNotPeriodic("bias");
+     306             : 
+     307          12 :   if(inherited_logfile) log<<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
+     308          12 :   if(root) p.cmd("init");
+     309          12 :   if(inherited_logfile) log<<"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n";
+     310          12 : }
+     311             : 
+     312         164 : void Plumed::prepare() {
+     313         164 :   Tools::DirectoryChanger directoryChanger(directory.c_str());
+     314         164 :   int step=getStep();
+     315         164 :   if(root) p.cmd("setStep",&step);
+     316         164 :   if(root) p.cmd("prepareDependencies");
+     317         164 :   int ene=0;
+     318         164 :   if(root) p.cmd("isEnergyNeeded",&ene);
+     319         164 :   if(ene) plumed_error()<<"It is not currently possible to use ENERGY in a guest PLUMED";
+     320         164 :   int n=0;
+     321         164 :   if(root) p.cmd("createFullList",&n);
+     322         164 :   const int *pointer=nullptr;
+     323         164 :   if(root) p.cmd("getFullList",&pointer);
+     324         164 :   bool redo=(index.size()!=n);
+     325         164 :   if(first) redo=true;
+     326         164 :   first=false;
+     327        4409 :   if(root && !redo) for(int i=0; i<n; i++) if(index[i]!=pointer[i]) { redo=true; break;};
+     328         164 :   if(root && redo) {
+     329          22 :     index.resize(n);
+     330          22 :     masses.resize(n);
+     331          22 :     forces.resize(3*n);
+     332          22 :     positions.resize(3*n);
+     333          22 :     charges.resize(n);
+     334        1043 :     for(int i=0; i<n; i++) {
+     335        1021 :       index[i]=pointer[i];
+     336             :     };
+     337          22 :     p.cmd("setAtomsNlocal",&n);
+     338          22 :     p.cmd("setAtomsGatindex",index.data(),index.size());
+     339             :   }
+     340         164 :   if(root) p.cmd("clearFullList");
+     341         164 :   int tmp=0;
+     342         164 :   if(root && redo) {
+     343          22 :     tmp=1;
+     344             :   }
+     345         164 :   comm.Bcast(tmp,0);
+     346         164 :   if(tmp) {
+     347          34 :     int s=index.size();
+     348          34 :     comm.Bcast(s,0);
+     349          34 :     if(!root) index.resize(s);
+     350          34 :     comm.Bcast(index,0);
+     351             :     std::vector<AtomNumber> numbers;
+     352          34 :     numbers.reserve(index.size());
+     353        2138 :     for(auto i : index) numbers.emplace_back(AtomNumber::index(i));
+     354          34 :     requestAtoms(numbers);
+     355             :   }
+     356         164 : }
+     357             : 
+     358         134 : void Plumed::calculate() {
+     359         134 :   Tools::DirectoryChanger directoryChanger(directory.c_str());
+     360         134 :   if(root) p.cmd("setStopFlag",&stop);
+     361         134 :   Tensor box=getPbc().getBox();
+     362         134 :   if(root) p.cmd("setBox",&box[0][0],9);
+     363             : 
+     364         134 :   virial.zero();
+     365       24875 :   for(int i=0; i<forces.size(); i++) forces[i]=0.0;
+     366        4238 :   for(int i=0; i<masses.size(); i++) masses[i]=getMass(i);
+     367        4238 :   for(int i=0; i<charges.size(); i++) charges[i]=getCharge(i);
+     368             : 
+     369         134 :   if(root) p.cmd("setMasses",masses.data(),masses.size());
+     370         134 :   if(root) p.cmd("setCharges",charges.data(),charges.size());
+     371         134 :   if(root) p.cmd("setPositions",positions.data(),positions.size());
+     372         134 :   if(root) p.cmd("setForces",forces.data(),forces.size());
+     373         134 :   if(root) p.cmd("setVirial",&virial[0][0],9);
+     374             : 
+     375             : 
+     376        4238 :   if(root) for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     377        4104 :       positions[3*i+0]=getPosition(i)[0];
+     378        4104 :       positions[3*i+1]=getPosition(i)[1];
+     379        4104 :       positions[3*i+2]=getPosition(i)[2];
+     380             :     }
+     381             : 
+     382         134 :   if(root) p.cmd("shareData");
+     383         134 :   if(root) p.cmd("performCalcNoUpdate");
+     384             : 
+     385         134 :   int s=forces.size();
+     386         134 :   comm.Bcast(s,0);
+     387         134 :   if(!root) forces.resize(s);
+     388         134 :   comm.Bcast(forces,0);
+     389         134 :   comm.Bcast(virial,0);
+     390             : 
+     391         134 :   double bias=0.0;
+     392         134 :   if(root) p.cmd("getBias",&bias);
+     393         134 :   comm.Bcast(bias,0);
+     394         134 :   getPntrToComponent("bias")->set(bias);
+     395         134 : }
+     396             : 
+     397         104 : void Plumed::apply() {
+     398         104 :   Tools::DirectoryChanger directoryChanger(directory.c_str());
+     399         104 :   std::vector<double> fforces( forces.size() + 9, 0 );
+     400       19580 :   for(unsigned i=0; i<forces.size(); i++) fforces[i] += forces[i];
+     401        1352 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) fforces[forces.size()+3*i+j] = virial[i][j];
+     402         104 :   unsigned ind=0; setForcesOnAtoms( fforces, ind );
+     403         104 : }
+     404             : 
+     405         104 : void Plumed::update() {
+     406         104 :   Tools::DirectoryChanger directoryChanger(directory.c_str());
+     407         104 :   if(root) p.cmd("update");
+     408         104 :   comm.Bcast(stop,0);
+     409         104 :   if(stop) {
+     410           0 :     log<<"  Action " << getLabel()<<" asked to stop\n";
+     411           0 :     plumed.stop();
+     412             :   }
+     413         104 : }
+     414             : 
+     415             : }
+     416             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Print.cpp.func-sort-c.html b/coverage/generic/Print.cpp.func-sort-c.html new file mode 100644 index 000000000000..16f4b2289293 --- /dev/null +++ b/coverage/generic/Print.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/Print.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Print.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:555796.5 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5PrintC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5PrintD2Ev0
_ZN4PLMD7generic5PrintC1ERKNS_13ActionOptionsE824
_ZN4PLMD7generic5PrintD0Ev824
_ZN4PLMD7generic5PrintD1Ev824
_ZN4PLMD7generic5Print16registerKeywordsERNS_8KeywordsE826
_ZN4PLMD7generic5Print6updateEv211453
_ZN4PLMD7generic5Print5applyEv212076
_ZN4PLMD7generic5Print9calculateEv212198
_ZN4PLMD7generic5Print7prepareEv212321
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Print.cpp.func.html b/coverage/generic/Print.cpp.func.html new file mode 100644 index 000000000000..52063ac09937 --- /dev/null +++ b/coverage/generic/Print.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/Print.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Print.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:555796.5 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic5Print16registerKeywordsERNS_8KeywordsE826
_ZN4PLMD7generic5Print5applyEv212076
_ZN4PLMD7generic5Print6updateEv211453
_ZN4PLMD7generic5Print7prepareEv212321
_ZN4PLMD7generic5Print9calculateEv212198
_ZN4PLMD7generic5PrintC1ERKNS_13ActionOptionsE824
_ZN4PLMD7generic5PrintC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic5PrintD0Ev824
_ZN4PLMD7generic5PrintD1Ev824
_ZN4PLMD7generic5PrintD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Print.cpp.gcov.html b/coverage/generic/Print.cpp.gcov.html new file mode 100644 index 000000000000..d2096ca21270 --- /dev/null +++ b/coverage/generic/Print.cpp.gcov.html @@ -0,0 +1,257 @@ + + + + + + + + LCOV - plumed test coverage - generic/Print.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Print.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:555796.5 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace generic {
+      28             : 
+      29             : //+PLUMEDOC PRINTANALYSIS PRINT
+      30             : /*
+      31             : Print quantities to a file.
+      32             : 
+      33             : This directive can be used multiple times
+      34             : in the input so you can print files with different strides or print different quantities
+      35             : to different files.  You can control the buffering of output using the \subpage FLUSH keyword.
+      36             : Output file is either appended or backed up depending on the presence of the \ref RESTART action.
+      37             : A per-action `RESTART` keyword can be used as well.
+      38             : 
+      39             : Notice that printing happens in the so-called "update" phase. This implies that printing
+      40             : is affected by the presence of \ref UPDATE_IF actions. In addition, one might decide to start
+      41             : and stop printing at preassigned values of time using the `UPDATE_FROM` and `UPDATE_UNTIL` keywords.
+      42             : Keep into account that even on steps when the action is not updated (and thus the file is not printed)
+      43             : the argument will be activated. In other words, if you use `UPDATE_FROM` to start printing at a given time,
+      44             : the collective variables this PRINT statement depends on will be computed also before that time.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : The following input instructs plumed to print the distance between atoms 3 and 5 on a file
+      49             : called COLVAR every 10 steps, and the distance and total energy on a file called COLVAR_ALL
+      50             : every 1000 steps.
+      51             : \plumedfile
+      52             : # compute distance:
+      53             : distance: DISTANCE ATOMS=2,5
+      54             : # compute total energy (potential)
+      55             : energy: ENERGY
+      56             : # print distance on a file
+      57             : PRINT ARG=distance          STRIDE=10   FILE=COLVAR
+      58             : # print both variables on another file
+      59             : PRINT ARG=distance,energy   STRIDE=1000 FILE=COLVAR_ALL
+      60             : \endplumedfile
+      61             : 
+      62             : Notice that \ref DISTANCE and \ref ENERGY are computed respectively every 10 and 1000 steps, that is
+      63             : only when required.
+      64             : 
+      65             : */
+      66             : //+ENDPLUMEDOC
+      67             : 
+      68             : class Print :
+      69             :   public ActionPilot,
+      70             :   public ActionWithArguments
+      71             : {
+      72             :   std::string file;
+      73             :   OFile ofile;
+      74             :   std::string fmt;
+      75             : // small internal utility
+      76             : /////////////////////////////////////////
+      77             : // these are crazy things just for debug:
+      78             : // they allow to change regularly the
+      79             : // printed argument
+      80             :   int rotate;
+      81             :   int rotateCountdown;
+      82             :   int rotateLast;
+      83             :   std::vector<Value*> rotateArguments;
+      84             : /////////////////////////////////////////
+      85             : public:
+      86      212198 :   void calculate() override {}
+      87             :   void prepare() override;
+      88             :   explicit Print(const ActionOptions&);
+      89             :   static void registerKeywords(Keywords& keys);
+      90      212076 :   void apply() override {}
+      91             :   void update() override;
+      92             :   ~Print();
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(Print,"PRINT")
+      96             : 
+      97         826 : void Print::registerKeywords(Keywords& keys) {
+      98         826 :   Action::registerKeywords(keys);
+      99         826 :   ActionPilot::registerKeywords(keys);
+     100         826 :   ActionWithArguments::registerKeywords(keys);
+     101         826 :   keys.use("ARG");
+     102        1652 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
+     103        1652 :   keys.add("optional","FILE","the name of the file on which to output these quantities");
+     104        1652 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+     105        1652 :   keys.add("hidden","_ROTATE","some funky thing implemented by GBussi");
+     106         826 :   keys.use("RESTART");
+     107         826 :   keys.use("UPDATE_FROM");
+     108         826 :   keys.use("UPDATE_UNTIL");
+     109         826 : }
+     110             : 
+     111         824 : Print::Print(const ActionOptions&ao):
+     112             :   Action(ao),
+     113             :   ActionPilot(ao),
+     114             :   ActionWithArguments(ao),
+     115         824 :   fmt("%f"),
+     116        1648 :   rotate(0)
+     117             : {
+     118         824 :   ofile.link(*this);
+     119        1648 :   parse("FILE",file);
+     120         824 :   if(file.length()>0) {
+     121         824 :     ofile.open(file);
+     122         824 :     log.printf("  on file %s\n",file.c_str());
+     123             :   } else {
+     124           0 :     log.printf("  on plumed log file\n");
+     125           0 :     ofile.link(log);
+     126             :   }
+     127         824 :   parse("FMT",fmt);
+     128         824 :   fmt=" "+fmt;
+     129         824 :   log.printf("  with format %s\n",fmt.c_str());
+     130        6413 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) ofile.setupPrintValue( getPntrToArgument(i) );
+     131             : /////////////////////////////////////////
+     132             : // these are crazy things just for debug:
+     133             : // they allow to change regularly the
+     134             : // printed argument
+     135         824 :   parse("_ROTATE",rotate);
+     136         824 :   if(rotate>0) {
+     137           1 :     rotateCountdown=rotate;
+     138           4 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) rotateArguments.push_back( getPntrToArgument(i) );
+     139           1 :     std::vector<Value*> a(1,rotateArguments[0]);
+     140           1 :     requestArguments(std::vector<Value*>(1,rotateArguments[0]));
+     141           1 :     rotateLast=0;
+     142             :   }
+     143             : /////////////////////////////////////////
+     144         824 :   checkRead();
+     145         824 : }
+     146             : 
+     147      212321 : void Print::prepare() {
+     148             : /////////////////////////////////////////
+     149             : // these are crazy things just for debug:
+     150             : // they allow to change regularly the
+     151             : // printed argument
+     152      212321 :   if(rotate>0) {
+     153           5 :     rotateCountdown--;
+     154           5 :     if(rotateCountdown==0) {
+     155           2 :       rotateCountdown=rotate;
+     156           2 :       rotateLast++;
+     157           2 :       rotateLast%=rotateArguments.size();
+     158           4 :       requestArguments(std::vector<Value*>(1,rotateArguments[rotateLast]));
+     159             :     }
+     160             :   }
+     161             : /////////////////////////////////////////
+     162      212321 : }
+     163             : 
+     164      211453 : void Print::update() {
+     165      211453 :   ofile.fmtField(" %f");
+     166      211453 :   ofile.printField("time",getTime());
+     167      742547 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     168      531094 :     ofile.fmtField(fmt);
+     169      531094 :     ofile.printField( getPntrToArgument(i), getArgument(i) );
+     170             :   }
+     171      211453 :   ofile.printField();
+     172      211453 : }
+     173             : 
+     174        1648 : Print::~Print() {
+     175        1648 : }
+     176             : 
+     177             : }
+     178             : 
+     179             : 
+     180             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/RandomExchanges.cpp.func-sort-c.html b/coverage/generic/RandomExchanges.cpp.func-sort-c.html new file mode 100644 index 000000000000..891fd3292dcf --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - generic/RandomExchanges.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - RandomExchanges.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41330.8 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15RandomExchanges5applyEv0
_ZN4PLMD7generic15RandomExchanges9calculateEv0
_ZN4PLMD7generic15RandomExchangesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic15RandomExchanges16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/RandomExchanges.cpp.func.html b/coverage/generic/RandomExchanges.cpp.func.html new file mode 100644 index 000000000000..b9643a668bc7 --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - generic/RandomExchanges.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - RandomExchanges.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41330.8 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic15RandomExchanges16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7generic15RandomExchanges5applyEv0
_ZN4PLMD7generic15RandomExchanges9calculateEv0
_ZN4PLMD7generic15RandomExchangesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/RandomExchanges.cpp.gcov.html b/coverage/generic/RandomExchanges.cpp.gcov.html new file mode 100644 index 000000000000..8efcd86b286d --- /dev/null +++ b/coverage/generic/RandomExchanges.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + + LCOV - plumed test coverage - generic/RandomExchanges.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - RandomExchanges.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41330.8 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/Action.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Exception.h"
+      26             : #include "core/ExchangePatterns.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace generic {
+      30             : 
+      31             : //+PLUMEDOC GENERIC RANDOM_EXCHANGES
+      32             : /*
+      33             : Set random pattern for exchanges.
+      34             : 
+      35             : In this way, exchanges will not be done between replicas with consecutive index, but
+      36             : will be done using a random pattern.  Typically used in bias exchange \cite piana.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : Using the following three input files one can run a bias exchange
+      41             : metadynamics simulation using a different angle in each replica.
+      42             : Exchanges will be randomly tried between replicas 0-1, 0-2 and 1-2
+      43             : 
+      44             : Here is plumed.0.dat
+      45             : \plumedfile
+      46             : RANDOM_EXCHANGES
+      47             : t: TORSION ATOMS=1,2,3,4
+      48             : METAD ARG=t HEIGHT=0.1 PACE=100 SIGMA=0.3
+      49             : \endplumedfile
+      50             : 
+      51             : Here is plumed.1.dat
+      52             : \plumedfile
+      53             : RANDOM_EXCHANGES
+      54             : t: TORSION ATOMS=2,3,4,5
+      55             : METAD ARG=t HEIGHT=0.1 PACE=100 SIGMA=0.3
+      56             : \endplumedfile
+      57             : 
+      58             : Here is plumed.2.dat
+      59             : \plumedfile
+      60             : RANDOM_EXCHANGES
+      61             : t: TORSION ATOMS=3,4,5,6
+      62             : METAD ARG=t HEIGHT=0.1 PACE=100 SIGMA=0.3
+      63             : \endplumedfile
+      64             : 
+      65             : \warning Multi replica simulations are presently only working with gromacs.
+      66             : 
+      67             : \warning The directive should appear in input files for every replicas. In case SEED is specified, it
+      68             : should be the same in all input files.
+      69             : 
+      70             : */
+      71             : //+ENDPLUMEDOC
+      72             : 
+      73             : class RandomExchanges:
+      74             :   public Action
+      75             : {
+      76             : public:
+      77             :   static void registerKeywords( Keywords& keys );
+      78             :   explicit RandomExchanges(const ActionOptions&ao);
+      79           0 :   void calculate() override {}
+      80           0 :   void apply() override {}
+      81             : };
+      82             : 
+      83             : PLUMED_REGISTER_ACTION(RandomExchanges,"RANDOM_EXCHANGES")
+      84             : 
+      85           2 : void RandomExchanges::registerKeywords( Keywords& keys ) {
+      86           2 :   Action::registerKeywords(keys);
+      87           4 :   keys.add("optional","SEED","seed for random exchanges");
+      88           2 : }
+      89             : 
+      90           0 : RandomExchanges::RandomExchanges(const ActionOptions&ao):
+      91           0 :   Action(ao)
+      92             : {
+      93           0 :   plumed.getExchangePatterns().setFlag(ExchangePatterns::RANDOM);
+      94             : // I convert the seed to -seed because I think it is more general to use a positive seed in input
+      95           0 :   int seed=-1;
+      96           0 :   parse("SEED",seed);
+      97           0 :   if(seed>=0) plumed.getExchangePatterns().setSeed(-seed);
+      98           0 : }
+      99             : 
+     100             : }
+     101             : }
+     102             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Read.cpp.func-sort-c.html b/coverage/generic/Read.cpp.func-sort-c.html new file mode 100644 index 000000000000..235c9943927d --- /dev/null +++ b/coverage/generic/Read.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - generic/Read.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Read.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:949994.9 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Read22getNumberOfDerivativesEv0
_ZN4PLMD7generic4ReadC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4Read17turnOnDerivativesEv28
_ZN4PLMD7generic4Read7getFileEv37
_ZNK4PLMD7generic4Read11getFilenameB5cxx11Ev40
_ZN4PLMD7generic4ReadC1ERKNS_13ActionOptionsE86
_ZN4PLMD7generic4Read16registerKeywordsERNS_8KeywordsE88
_ZN4PLMD7generic4Read5applyEv921318
_ZN4PLMD7generic4Read6updateEv921318
_ZN4PLMD7generic4Read7prepareEv921318
_ZN4PLMD7generic4Read9calculateEv921318
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Read.cpp.func.html b/coverage/generic/Read.cpp.func.html new file mode 100644 index 000000000000..8f0a844e7011 --- /dev/null +++ b/coverage/generic/Read.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - generic/Read.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Read.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:949994.9 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Read16registerKeywordsERNS_8KeywordsE88
_ZN4PLMD7generic4Read17turnOnDerivativesEv28
_ZN4PLMD7generic4Read22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Read5applyEv921318
_ZN4PLMD7generic4Read6updateEv921318
_ZN4PLMD7generic4Read7getFileEv37
_ZN4PLMD7generic4Read7prepareEv921318
_ZN4PLMD7generic4Read9calculateEv921318
_ZN4PLMD7generic4ReadC1ERKNS_13ActionOptionsE86
_ZN4PLMD7generic4ReadC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7generic4Read11getFilenameB5cxx11Ev40
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Read.cpp.gcov.html b/coverage/generic/Read.cpp.gcov.html new file mode 100644 index 000000000000..6e792bf32c87 --- /dev/null +++ b/coverage/generic/Read.cpp.gcov.html @@ -0,0 +1,332 @@ + + + + + + + + LCOV - plumed test coverage - generic/Read.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Read.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:949994.9 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "tools/IFile.h"
+      28             : #include <memory>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace generic {
+      32             : 
+      33             : //+PLUMEDOC GENERIC READ
+      34             : /*
+      35             : Read quantities from a colvar file.
+      36             : 
+      37             : This Action can be used with driver to read in a colvar file that was generated during
+      38             : an MD simulation
+      39             : 
+      40             : \par Description of components
+      41             : 
+      42             : The READ command will read those fields that are labelled with the text string given to the
+      43             : VALUE keyword.  It will also read in any fields that are labeled with the text string
+      44             : given to the VALUE keyword followed by a dot and a further string. If a single Value is read in
+      45             : this value can be referenced using the label of the Action.  Alternatively, if multiple quantities
+      46             : are read in, they can be referenced elsewhere in the input by using the label for the Action
+      47             : followed by a dot and the character string that appeared after the dot in the title of the field.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : This input reads in data from a file called input_colvar.data that was generated
+      52             : in a calculation that involved PLUMED.  The first command reads in the data from the
+      53             : column headed phi1 while the second reads in the data from the column headed phi2.
+      54             : 
+      55             : \plumedfile
+      56             : rphi1:       READ FILE=input_colvar.data  VALUES=phi1
+      57             : rphi2:       READ FILE=input_colvar.data  VALUES=phi2
+      58             : PRINT ARG=rphi1,rphi2 STRIDE=500  FILE=output_colvar.data
+      59             : \endplumedfile
+      60             : 
+      61             : The file input_colvar.data is just a normal colvar file as shown below
+      62             : 
+      63             : \auxfile{input_colvar.data}
+      64             : #! FIELDS time phi psi metad.bias metad.rbias metad.rct
+      65             : #! SET min_phi -pi
+      66             : #! SET max_phi pi
+      67             : #! SET min_psi -pi
+      68             : #! SET max_psi pi
+      69             :  0.000000  -1.2379   0.8942   0.0000   0.0000   0.0000
+      70             :  1.000000  -1.4839   1.0482   0.0000   0.0000   0.0089
+      71             :  2.000000  -1.3243   0.6055   0.0753   0.0664   0.0184
+      72             : \endauxfile
+      73             : 
+      74             : */
+      75             : //+ENDPLUMEDOC
+      76             : 
+      77             : class Read :
+      78             :   public ActionPilot,
+      79             :   public ActionWithValue
+      80             : {
+      81             : private:
+      82             :   bool ignore_time;
+      83             :   bool ignore_forces;
+      84             :   bool cloned_file;
+      85             :   unsigned nlinesPerStep;
+      86             :   std::string filename;
+      87             : /// Unique pointer with the same scope as ifile.
+      88             :   std::unique_ptr<IFile> ifile_ptr;
+      89             : /// Pointer to input file.
+      90             : /// It is either pointing to the content of ifile_ptr
+      91             : /// or to the file it is cloned from.
+      92             :   IFile* ifile;
+      93             :   std::vector<std::unique_ptr<Value>> readvals;
+      94             : public:
+      95             :   static void registerKeywords( Keywords& keys );
+      96             :   explicit Read(const ActionOptions&);
+      97             :   void prepare() override;
+      98      921318 :   void apply() override {}
+      99             :   void calculate() override;
+     100             :   void update() override;
+     101             :   std::string getFilename() const;
+     102             :   IFile* getFile();
+     103             :   unsigned getNumberOfDerivatives() override;
+     104             :   void turnOnDerivatives() override;
+     105             : };
+     106             : 
+     107             : PLUMED_REGISTER_ACTION(Read,"READ")
+     108             : 
+     109          88 : void Read::registerKeywords(Keywords& keys) {
+     110          88 :   Action::registerKeywords(keys);
+     111          88 :   ActionPilot::registerKeywords(keys);
+     112          88 :   ActionWithValue::registerKeywords(keys);
+     113         176 :   keys.add("compulsory","STRIDE","1","the frequency with which the file should be read.");
+     114         176 :   keys.add("compulsory","EVERY","1","only read every \\f$n\\f$th line of the colvar file. This should be used if the colvar was written more frequently than the trajectory.");
+     115         176 :   keys.add("compulsory","VALUES","the values to read from the file");
+     116         176 :   keys.add("compulsory","FILE","the name of the file from which to read these quantities");
+     117         176 :   keys.addFlag("IGNORE_TIME",false,"ignore the time in the colvar file. When this flag is not present read will be quite strict "
+     118             :                "about the start time of the simulation and the stride between frames");
+     119         176 :   keys.addFlag("IGNORE_FORCES",false,"use this flag if the forces added by any bias can be safely ignored.  As an example forces can be "
+     120             :                "safely ignored if you are doing post processing that does not involve outputting forces");
+     121          88 :   keys.remove("NUMERICAL_DERIVATIVES");
+     122          88 :   keys.use("UPDATE_FROM");
+     123          88 :   keys.use("UPDATE_UNTIL");
+     124          88 :   ActionWithValue::useCustomisableComponents(keys);
+     125          88 : }
+     126             : 
+     127          86 : Read::Read(const ActionOptions&ao):
+     128             :   Action(ao),
+     129             :   ActionPilot(ao),
+     130             :   ActionWithValue(ao),
+     131          86 :   ignore_time(false),
+     132          86 :   ignore_forces(false),
+     133          86 :   nlinesPerStep(1)
+     134             : {
+     135             :   // Read the file name from the input line
+     136          86 :   parse("FILE",filename);
+     137             :   // Check if time is to be ignored
+     138          86 :   parseFlag("IGNORE_TIME",ignore_time);
+     139             :   // Check if forces are to be ignored
+     140          86 :   parseFlag("IGNORE_FORCES",ignore_forces);
+     141             :   // Open the file if it is not already opened
+     142          86 :   cloned_file=false;
+     143          86 :   std::vector<Read*> other_reads=plumed.getActionSet().select<Read*>();
+     144         126 :   for(unsigned i=0; i<other_reads.size(); ++i) {
+     145          40 :     if( other_reads[i]->getFilename()==filename ) {
+     146          37 :       ifile=other_reads[i]->getFile();
+     147          37 :       cloned_file=true;
+     148             :     }
+     149             :   }
+     150          86 :   if( !cloned_file ) {
+     151          62 :     ifile_ptr=Tools::make_unique<IFile>();
+     152          62 :     ifile=ifile_ptr.get();
+     153          62 :     if( !ifile->FileExist(filename) ) error("could not find file named " + filename);
+     154          62 :     ifile->link(*this);
+     155          62 :     ifile->open(filename);
+     156          62 :     ifile->allowIgnoredFields();
+     157             :   }
+     158          86 :   parse("EVERY",nlinesPerStep);
+     159          86 :   if(nlinesPerStep>1) log.printf("  only reading every %uth line of file %s\n",nlinesPerStep,filename.c_str() );
+     160          84 :   else log.printf("  reading data from file %s\n",filename.c_str() );
+     161             :   // Find out what we are reading
+     162          86 :   std::vector<std::string> valread; parseVector("VALUES",valread);
+     163             : 
+     164          86 :   if(nlinesPerStep>1 && cloned_file) error("Opening a file multiple times and using EVERY is not allowed");
+     165             : 
+     166             :   std::size_t dot=valread[0].find_first_of('.');
+     167          86 :   if( valread[0].find(".")!=std::string::npos ) {
+     168           8 :     std::string label=valread[0].substr(0,dot);
+     169           8 :     std::string name=valread[0].substr(dot+1);
+     170           8 :     if( name=="*" ) {
+     171           1 :       if( valread.size()>1 ) error("all values must be from the same Action when using READ");
+     172             :       std::vector<std::string> fieldnames;
+     173           1 :       ifile->scanFieldList( fieldnames );
+     174           8 :       for(unsigned i=0; i<fieldnames.size(); ++i) {
+     175           7 :         if( fieldnames[i].substr(0,dot)==label ) {
+     176           6 :           readvals.emplace_back(Tools::make_unique<Value>(this, fieldnames[i], false) ); addComponentWithDerivatives( fieldnames[i].substr(dot+1) );
+     177           6 :           if( ifile->FieldExist("min_" + fieldnames[i]) ) componentIsPeriodic( fieldnames[i].substr(dot+1), "-pi","pi" );
+     178           6 :           else componentIsNotPeriodic( fieldnames[i].substr(dot+1) );
+     179             :         }
+     180             :       }
+     181           1 :     } else {
+     182           7 :       readvals.emplace_back(Tools::make_unique<Value>(this, valread[0], false) ); addComponentWithDerivatives( name );
+     183          14 :       if( ifile->FieldExist("min_" + valread[0]) ) componentIsPeriodic( valread[0].substr(dot+1), "-pi", "pi" );
+     184          14 :       else componentIsNotPeriodic( valread[0].substr(dot+1) );
+     185           9 :       for(unsigned i=1; i<valread.size(); ++i) {
+     186           4 :         if( valread[i].substr(0,dot)!=label ) error("all values must be from the same Action when using READ");;
+     187           4 :         readvals.emplace_back(Tools::make_unique<Value>(this, valread[i], false) ); addComponentWithDerivatives( valread[i].substr(dot+1) );
+     188           4 :         if( ifile->FieldExist("min_" + valread[i]) ) componentIsPeriodic( valread[i].substr(dot+1), "-pi", "pi" );
+     189           4 :         else componentIsNotPeriodic( valread[i].substr(dot+1) );
+     190             :       }
+     191             :     }
+     192             :   } else {
+     193          78 :     if( valread.size()!=1 ) error("all values must be from the same Action when using READ");
+     194          78 :     readvals.emplace_back(Tools::make_unique<Value>(this, valread[0], false) ); addValueWithDerivatives();
+     195         165 :     if( ifile->FieldExist("min_" + valread[0]) ) setPeriodic( "-pi", "pi" );
+     196          69 :     else setNotPeriodic();
+     197          78 :     log.printf("  reading value %s and storing as %s\n",valread[0].c_str(),getLabel().c_str() );
+     198             :   }
+     199          86 :   checkRead();
+     200         172 : }
+     201             : 
+     202          40 : std::string Read::getFilename() const {
+     203          40 :   return filename;
+     204             : }
+     205             : 
+     206          37 : IFile* Read::getFile() {
+     207          37 :   return ifile;
+     208             : }
+     209             : 
+     210           0 : unsigned Read::getNumberOfDerivatives() {
+     211           0 :   return 0;
+     212             : }
+     213             : 
+     214          28 : void Read::turnOnDerivatives() {
+     215          28 :   if( !ignore_forces ) error("cannot calculate derivatives for colvars that are read in from a file.  If you are postprocessing and "
+     216             :                                "these forces do not matter add the flag IGNORE_FORCES to all READ actions");
+     217          28 : }
+     218             : 
+     219      921318 : void Read::prepare() {
+     220      921318 :   if( !cloned_file ) {
+     221             :     double du_time;
+     222      404026 :     if( !ifile->scanField("time",du_time) ) {
+     223           0 :       error("Reached end of file " + filename + " before end of trajectory");
+     224      202013 :     } else if( std::abs( du_time-getTime() )>getTimeStep() && !ignore_time ) {
+     225           0 :       std::string str_dutime,str_ptime; Tools::convert(du_time,str_dutime); Tools::convert(getTime(),str_ptime);
+     226           0 :       error("mismatched times in colvar files : colvar time=" + str_dutime + " plumed time=" + str_ptime + ". Add IGNORE_TIME to ignore error.");
+     227             :     }
+     228             :   }
+     229      921318 : }
+     230             : 
+     231      921318 : void Read::calculate() {
+     232             :   std::string smin, smax;
+     233     2018830 :   for(unsigned i=0; i<readvals.size(); ++i) {
+     234             : // .get  returns the raw pointer
+     235             : // ->get calls the Value::get() method
+     236     1097512 :     ifile->scanField( readvals[i].get() );
+     237     1097512 :     getPntrToComponent(i)->set( readvals[i]->get() );
+     238     1097512 :     if( readvals[i]->isPeriodic() ) {
+     239        3309 :       readvals[i]->getDomain( smin, smax );
+     240        3309 :       getPntrToComponent(i)->setDomain( smin, smax );
+     241             :     }
+     242             :   }
+     243      921318 : }
+     244             : 
+     245      921318 : void Read::update() {
+     246      921318 :   if( !cloned_file ) {
+     247      404577 :     for(unsigned i=0; i<nlinesPerStep; ++i) {
+     248      202564 :       ifile->scanField(); double du_time;
+     249      405128 :       if( !ifile->scanField("time",du_time) && !plumed.inputsAreActive() ) plumed.stop();
+     250             :     }
+     251             :   }
+     252      921318 : }
+     253             : 
+     254             : }
+     255             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/ResetCell.cpp.func-sort-c.html b/coverage/generic/ResetCell.cpp.func-sort-c.html new file mode 100644 index 000000000000..c1e40cbfa2a0 --- /dev/null +++ b/coverage/generic/ResetCell.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/ResetCell.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - ResetCell.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5555100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9ResetCellC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic9ResetCellC1ERKNS_13ActionOptionsE2
_ZN4PLMD7generic9ResetCell16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7generic9ResetCell5applyEv17
_ZN4PLMD7generic9ResetCell9calculateEv17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/ResetCell.cpp.func.html b/coverage/generic/ResetCell.cpp.func.html new file mode 100644 index 000000000000..ea2577729ffe --- /dev/null +++ b/coverage/generic/ResetCell.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/ResetCell.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - ResetCell.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5555100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic9ResetCell16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD7generic9ResetCell5applyEv17
_ZN4PLMD7generic9ResetCell9calculateEv17
_ZN4PLMD7generic9ResetCellC1ERKNS_13ActionOptionsE2
_ZN4PLMD7generic9ResetCellC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/ResetCell.cpp.gcov.html b/coverage/generic/ResetCell.cpp.gcov.html new file mode 100644 index 000000000000..10dde9aadf2d --- /dev/null +++ b/coverage/generic/ResetCell.cpp.gcov.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - generic/ResetCell.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - ResetCell.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5555100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "tools/Vector.h"
+      28             : #include "tools/Matrix.h"
+      29             : #include "tools/AtomNumber.h"
+      30             : #include "tools/Tools.h"
+      31             : #include "core/PbcAction.h"
+      32             : #include "tools/Pbc.h"
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace generic {
+      36             : 
+      37             : //+PLUMEDOC GENERIC RESET_CELL
+      38             : /*
+      39             : This action is used to rotate the full cell
+      40             : 
+      41             : This can be used to modify the periodic box. Notice that
+      42             : this is done at fixed scaled coordinates,
+      43             : so that also atomic coordinates for the entire system are affected.
+      44             : To see what effect try
+      45             : the \ref DUMPATOMS directive to output the atomic positions.
+      46             : 
+      47             : Also notice that PLUMED propagate forces correctly so that you can add a bias on a CV computed
+      48             : after rotation. See also \ref FIT_TO_TEMPLATE
+      49             : 
+      50             : Currently, only TYPE=TRIANGULAR is implemented, which allows one to reset
+      51             : the cell to a lower triangular one. Namely, a proper rotation is found that allows
+      52             : rotating the box so that the first lattice vector is in the form (ax,0,0),
+      53             : the second lattice vector is in the form (bx,by,0), and the third lattice vector is
+      54             : arbitrary.
+      55             : 
+      56             : \attention
+      57             : The implementation of this action is available but should be considered in testing phase. Please report any
+      58             : strange behavior.
+      59             : 
+      60             : \attention
+      61             : This directive modifies the stored position at the precise moment
+      62             : it is executed. This means that only collective variables
+      63             : which are below it in the input script will see the corrected positions.
+      64             : Unless you
+      65             : know exactly what you are doing, leave the default stride (1), so that
+      66             : this action is performed at every MD step.
+      67             : 
+      68             : \par Examples
+      69             : 
+      70             : Reset cell to be triangular after a rototranslational fit
+      71             : \plumedfile
+      72             : DUMPATOMS FILE=dump-original.xyz ATOMS=1-20
+      73             : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=OPTIMAL
+      74             : DUMPATOMS FILE=dump-fit.xyz ATOMS=1-20
+      75             : RESET_CELL TYPE=TRIANGULAR
+      76             : DUMPATOMS FILE=dump-reset.xyz ATOMS=1-20
+      77             : \endplumedfile
+      78             : 
+      79             : The reference file for the FIT_TO_TEMPLATE is just a normal pdb file with the format shown below:
+      80             : 
+      81             : \auxfile{ref.pdb}
+      82             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      83             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      84             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      85             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      86             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      87             : END
+      88             : \endauxfile
+      89             : 
+      90             : */
+      91             : //+ENDPLUMEDOC
+      92             : 
+      93             : 
+      94             : class ResetCell:
+      95             :   public ActionPilot,
+      96             :   public ActionAtomistic
+      97             : {
+      98             :   std::string type;
+      99             :   Tensor rotation,newbox;
+     100             :   Value* boxValue;
+     101             :   PbcAction* pbc_action;
+     102             : public:
+     103             :   explicit ResetCell(const ActionOptions&ao);
+     104             :   static void registerKeywords( Keywords& keys );
+     105             :   void calculate() override;
+     106             :   void apply() override;
+     107             : };
+     108             : 
+     109             : PLUMED_REGISTER_ACTION(ResetCell,"RESET_CELL")
+     110             : 
+     111           4 : void ResetCell::registerKeywords( Keywords& keys ) {
+     112           4 :   Action::registerKeywords( keys );
+     113           4 :   ActionAtomistic::registerKeywords( keys );
+     114           8 :   keys.add("compulsory","STRIDE","1","the frequency with which molecules are reassembled.  Unless you are completely certain about what you are doing leave this set equal to 1!");
+     115           8 :   keys.add("compulsory","TYPE","TRIANGULAR","the manner in which the cell is reset");
+     116           4 : }
+     117             : 
+     118           2 : ResetCell::ResetCell(const ActionOptions&ao):
+     119             :   Action(ao),
+     120             :   ActionPilot(ao),
+     121           2 :   ActionAtomistic(ao)
+     122             : {
+     123           2 :   type.assign("TRIANGULAR");
+     124           2 :   parse("TYPE",type);
+     125             : 
+     126           2 :   log<<"  type: "<<type<<"\n";
+     127           2 :   if(type!="TRIANGULAR") error("undefined type "+type);
+     128             : 
+     129           2 :   pbc_action=plumed.getActionSet().selectWithLabel<PbcAction*>("Box");
+     130           2 :   if( !pbc_action ) error("cannot reset cell if box has not been set");
+     131           2 :   boxValue=pbc_action->copyOutput(0);
+     132           2 : }
+     133             : 
+     134             : 
+     135          17 : void ResetCell::calculate() {
+     136          17 :   Pbc & pbc(pbc_action->getPbc());
+     137          17 :   Tensor box=pbc.getBox();
+     138             : 
+     139             : // moduli of lattice vectors
+     140          17 :   double a=modulo(box.getRow(0));
+     141          17 :   double b=modulo(box.getRow(1));
+     142          17 :   double c=modulo(box.getRow(2));
+     143             : // cos-angle between lattice vectors
+     144          17 :   double ab=dotProduct(box.getRow(0),box.getRow(1))/(a*b);
+     145          17 :   double ac=dotProduct(box.getRow(0),box.getRow(2))/(a*c);
+     146          17 :   double bc=dotProduct(box.getRow(1),box.getRow(2))/(b*c);
+     147             : 
+     148             : // generate a new set of lattice vectors as a lower triangular matrix
+     149          17 :   newbox[0][0]=a;
+     150          17 :   newbox[1][0]=b*ab;
+     151          17 :   newbox[1][1]=std::sqrt(b*b-newbox[1][0]*newbox[1][0]);
+     152          17 :   newbox[2][0]=c*ac;
+     153          17 :   newbox[2][1]=c*(bc-ac*ab)/std::sqrt(1-ab*ab);
+     154          17 :   newbox[2][2]=std::sqrt(c*c-newbox[2][0]*newbox[2][0]-newbox[2][1]*newbox[2][1]);
+     155             : 
+     156          17 :   if(determinant(newbox)*determinant(box)<0) newbox[2][2]=-newbox[2][2];
+     157             : 
+     158             : // rotation matrix from old to new coordinates
+     159          17 :   rotation=transpose(matmul(inverse(box),newbox));
+     160             : 
+     161             : // rotate all coordinates
+     162          17 :   unsigned nat = getTotAtoms();
+     163        1623 :   for(unsigned i=0; i<nat; i++) {
+     164        1606 :     std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     165        1606 :     Vector ato=matmul(rotation,getGlobalPosition(a));
+     166        1606 :     setGlobalPosition(a,ato);
+     167             :   }
+     168             : // rotate box
+     169          17 :   pbc.setBox(newbox);
+     170          17 : }
+     171             : 
+     172          17 : void ResetCell::apply() {
+     173             : // rotate back forces
+     174          17 :   unsigned nat = getTotAtoms();
+     175        1623 :   for(unsigned i=0; i<nat; i++) {
+     176        1606 :     std::pair<std::size_t,std::size_t> a = getValueIndices( AtomNumber::index(i));
+     177        1606 :     Vector f=getForce(a);
+     178        1606 :     Vector nf=matmul(transpose(rotation),f);
+     179        1606 :     addForce(a, nf-f );
+     180             :   }
+     181             : 
+     182             : // I have no mathematical derivation for this.
+     183             : // The reasoning is the following.
+     184             : // virial= h^T * dU/dh, where h is the box matrix and dU/dh its derivatives.
+     185             : // The final virial should be rotationally invariant, that is symmetric.
+     186             : // in the rotated frame, dU/dh elements [0][1], [0][2], and [1][2] should
+     187             : // be changed so as to enforce rotational invariance. Thus we here have to
+     188             : // make the virial matrix symmetric.
+     189             : // Since h^T is upper triangular, it can be shown that any change in these elements
+     190             : // will only affect the corresponding elements of the virial matrix.
+     191             : // Thus, the only possibility is to set the corresponding elements
+     192             : // of the virial matrix equal to their symmetric ones.
+     193             : // GB
+     194          17 :   Tensor virial;
+     195         221 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) virial[i][j]=boxValue->getForce( 3*i+j );
+     196          17 :   virial[0][1]=virial[1][0];
+     197          17 :   virial[0][2]=virial[2][0];
+     198          17 :   virial[1][2]=virial[2][1];
+     199             : // rotate back virial
+     200          17 :   virial=matmul(transpose(rotation),matmul(virial,rotation)); boxValue->clearInputForce();
+     201         221 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) boxValue->addForce( 3*i+j, virial(i,j) );
+     202             : 
+     203             : 
+     204          17 : }
+     205             : 
+     206             : }
+     207             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Time.cpp.func-sort-c.html b/coverage/generic/Time.cpp.func-sort-c.html new file mode 100644 index 000000000000..df935629d81c --- /dev/null +++ b/coverage/generic/Time.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - generic/Time.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Time.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41428.6 %
Date:2024-02-22 21:58:45Functions:1616.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Time22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Time5applyEv0
_ZN4PLMD7generic4Time9calculateEv0
_ZN4PLMD7generic4TimeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4TimeC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4Time16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Time.cpp.func.html b/coverage/generic/Time.cpp.func.html new file mode 100644 index 000000000000..5439752df206 --- /dev/null +++ b/coverage/generic/Time.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - generic/Time.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Time.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41428.6 %
Date:2024-02-22 21:58:45Functions:1616.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic4Time16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD7generic4Time22getNumberOfDerivativesEv0
_ZN4PLMD7generic4Time5applyEv0
_ZN4PLMD7generic4Time9calculateEv0
_ZN4PLMD7generic4TimeC1ERKNS_13ActionOptionsE0
_ZN4PLMD7generic4TimeC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/Time.cpp.gcov.html b/coverage/generic/Time.cpp.gcov.html new file mode 100644 index 000000000000..cb47010a074c --- /dev/null +++ b/coverage/generic/Time.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + + LCOV - plumed test coverage - generic/Time.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - Time.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:41428.6 %
Date:2024-02-22 21:58:45Functions:1616.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionWithValue.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include <string>
+      25             : #include <cmath>
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace generic {
+      29             : 
+      30             : //+PLUMEDOC GENERIC TIME
+      31             : /*
+      32             : retrieve the time of the simulation to be used elsewhere
+      33             : 
+      34             : \par Examples
+      35             : 
+      36             : \plumedfile
+      37             : TIME            LABEL=t1
+      38             : PRINT ARG=t1
+      39             : \endplumedfile
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : class Time : public ActionWithValue {
+      45             : public:
+      46             :   static void registerKeywords( Keywords& keys );
+      47             :   explicit Time(const ActionOptions&);
+      48             : // active methods:
+      49             :   void calculate() override;
+      50           0 :   void apply() override {}
+      51           0 :   unsigned getNumberOfDerivatives() override { return 0; }
+      52             : };
+      53             : 
+      54             : PLUMED_REGISTER_ACTION(Time,"TIME")
+      55             : 
+      56           2 : void Time::registerKeywords( Keywords& keys ) {
+      57           2 :   Action::registerKeywords( keys );
+      58           2 :   ActionWithValue::registerKeywords( keys );
+      59           2 : }
+      60             : 
+      61           0 : Time::Time(const ActionOptions&ao):
+      62           0 :   Action(ao),ActionWithValue(ao)
+      63             : {
+      64           0 :   addValueWithDerivatives(); setNotPeriodic();
+      65             :   // resize derivative by hand to a nonzero value
+      66           0 :   getPntrToValue()->resizeDerivatives(1);
+      67           0 : }
+      68             : 
+      69           0 : void Time::calculate() {
+      70           0 :   setValue           (getTime());
+      71           0 : }
+      72             : 
+      73             : }
+      74             : 
+      75             : 
+      76             : 
+      77             : 
+      78             : 
+      79             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/UpdateIf.cpp.func-sort-c.html b/coverage/generic/UpdateIf.cpp.func-sort-c.html new file mode 100644 index 000000000000..9b8c0626b175 --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/UpdateIf.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - UpdateIf.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8UpdateIfC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic8UpdateIfD2Ev0
_ZN4PLMD7generic8UpdateIfC1ERKNS_13ActionOptionsE7
_ZN4PLMD7generic8UpdateIfD0Ev7
_ZN4PLMD7generic8UpdateIfD1Ev7
_ZN4PLMD7generic8UpdateIf16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD7generic8UpdateIf12beforeUpdateEv28
_ZN4PLMD7generic8UpdateIf5applyEv28
_ZN4PLMD7generic8UpdateIf7prepareEv28
_ZN4PLMD7generic8UpdateIf9calculateEv28
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/UpdateIf.cpp.func.html b/coverage/generic/UpdateIf.cpp.func.html new file mode 100644 index 000000000000..a166862e6179 --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - generic/UpdateIf.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - UpdateIf.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic8UpdateIf12beforeUpdateEv28
_ZN4PLMD7generic8UpdateIf16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD7generic8UpdateIf5applyEv28
_ZN4PLMD7generic8UpdateIf7prepareEv28
_ZN4PLMD7generic8UpdateIf9calculateEv28
_ZN4PLMD7generic8UpdateIfC1ERKNS_13ActionOptionsE7
_ZN4PLMD7generic8UpdateIfC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic8UpdateIfD0Ev7
_ZN4PLMD7generic8UpdateIfD1Ev7
_ZN4PLMD7generic8UpdateIfD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/UpdateIf.cpp.gcov.html b/coverage/generic/UpdateIf.cpp.gcov.html new file mode 100644 index 000000000000..4234bce42884 --- /dev/null +++ b/coverage/generic/UpdateIf.cpp.gcov.html @@ -0,0 +1,235 @@ + + + + + + + + LCOV - plumed test coverage - generic/UpdateIf.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - UpdateIf.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionPilot.h"
+      23             : #include "core/ActionWithArguments.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace generic {
+      29             : 
+      30             : //+PLUMEDOC PRINTANALYSIS UPDATE_IF
+      31             : /*
+      32             : Conditional update of other actions.
+      33             : 
+      34             : 
+      35             : This action can be used to enable and disable the update step for the following actions
+      36             : depending on the value of its arguments. This allows for example to extract snapshots
+      37             : with value of some CVs in a given range.
+      38             : 
+      39             : When called with MORE_THAN and/or LESS_THAN keywords, this action starts an if block.
+      40             : The block is executed if all the arguments are less than all the respective values
+      41             : in the LESS_THAN keyword (if present) and all the arguments are more than all the
+      42             : respective values
+      43             : in the MORE_THAN keyword (if present).
+      44             : 
+      45             : When called with the END flag, this action ends the corresponding IF block.
+      46             : Notice that in this case one should also provide the ARG keyword. It is recommended to
+      47             : use the same ARG keyword that was used to begin the block, so as to make the input more readable.
+      48             : 
+      49             : Of course, blocks can be nested at will.
+      50             : 
+      51             : There are many potential usages for this keyword. One might e.g. decide to analyze some variable
+      52             : only when another variable is within a given range.
+      53             : 
+      54             : \warning
+      55             : Notice that not all the possible usage make
+      56             : particular sense. For example, conditionally updating a \ref METAD keyword
+      57             : (that is: adding hills only if a variable is within a given range)
+      58             : can lead to unexpected results.
+      59             : 
+      60             : \par Examples
+      61             : 
+      62             : The following input instructs plumed dump all the snapshots where an atom is in touch with
+      63             : the solute.
+      64             : \plumedfile
+      65             : solute: GROUP ATOMS=1-124
+      66             : coord: COORDINATION GROUPA=solute GROUPB=500 R_0=0.5
+      67             : 
+      68             : # A coordination number higher than 0.5 indicate that there is at least one
+      69             : # atom of group `solute` at less than 5 A from atom number 500
+      70             : 
+      71             : UPDATE_IF ARG=coord MORE_THAN=0.5
+      72             : DUMPATOMS ATOMS=solute,500 FILE=output.xyz
+      73             : UPDATE_IF ARG=coord END
+      74             : \endplumedfile
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : class UpdateIf:
+      80             :   public ActionPilot,
+      81             :   public ActionWithArguments
+      82             : {
+      83             :   std::vector<double> lower;
+      84             :   std::vector<double> upper;
+      85             :   bool on;
+      86             :   bool end;
+      87             : public:
+      88             :   void prepare() override;
+      89             :   void calculate() override;
+      90             :   void beforeUpdate() override;
+      91             :   explicit UpdateIf(const ActionOptions&);
+      92             :   static void registerKeywords(Keywords& keys);
+      93          28 :   void apply() override {}
+      94             :   ~UpdateIf();
+      95             : };
+      96             : 
+      97             : PLUMED_REGISTER_ACTION(UpdateIf,"UPDATE_IF")
+      98             : 
+      99           9 : void UpdateIf::registerKeywords(Keywords& keys) {
+     100           9 :   Action::registerKeywords(keys);
+     101           9 :   ActionPilot::registerKeywords(keys);
+     102           9 :   ActionWithArguments::registerKeywords(keys);
+     103           9 :   keys.use("ARG");
+     104          18 :   keys.add("compulsory","STRIDE","1","the frequency with which the quantities of interest should be output");
+     105          18 :   keys.addFlag("END",false,"end");
+     106          18 :   keys.add("optional","LESS_THAN","upper bound");
+     107          18 :   keys.add("optional","MORE_THAN","lower bound");
+     108           9 : }
+     109             : 
+     110           7 : UpdateIf::UpdateIf(const ActionOptions&ao):
+     111             :   Action(ao),
+     112             :   ActionPilot(ao),
+     113             :   ActionWithArguments(ao),
+     114           7 :   on(false),
+     115           7 :   end(false)
+     116             : {
+     117           7 :   parseFlag("END",end);
+     118           7 :   parseVector("LESS_THAN",upper);
+     119           7 :   parseVector("MORE_THAN",lower);
+     120           7 :   if(end && upper.size()!=0) error("END and LESS_THAN are not compatible");
+     121           7 :   if(end && lower.size()!=0) error("END and MORE_THAN are not compatible");
+     122           7 :   if(upper.size()==0) upper.assign(getNumberOfArguments(),+std::numeric_limits<double>::max());
+     123           7 :   if(lower.size()==0) lower.assign(getNumberOfArguments(),-std::numeric_limits<double>::max());
+     124           7 :   if(upper.size()!=getNumberOfArguments()) error("LESS_THAN should have the same size as ARG");
+     125           7 :   if(lower.size()!=getNumberOfArguments()) error("MORE_THAN should have the same size as ARG");
+     126          15 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     127           8 :     log<<"  boundaries for argument "<<i<<"    "<<lower[i]<<" "<<upper[i]<<"\n";
+     128             :   }
+     129           7 :   checkRead();
+     130           7 : }
+     131             : 
+     132          28 : void UpdateIf::prepare() {
+     133          28 :   on=false;
+     134          28 : }
+     135             : 
+     136          28 : void UpdateIf::calculate() {
+     137          28 :   on=true;
+     138          60 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     139          32 :     if(getArgument(i)>=upper[i] || getArgument(i)<=lower[i]) on=false;
+     140             :   }
+     141          28 : }
+     142             : 
+     143          28 : void UpdateIf::beforeUpdate() {
+     144          28 :   if(end) plumed.updateFlagsPop();
+     145             :   else {
+     146          23 :     if(on) plumed.updateFlagsPush(plumed.updateFlagsTop());
+     147           9 :     else   plumed.updateFlagsPush(false);
+     148             :   }
+     149          28 : }
+     150             : 
+     151             : 
+     152          14 : UpdateIf::~UpdateIf() {
+     153          14 : }
+     154             : 
+     155             : }
+     156             : 
+     157             : 
+     158             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WholeMolecules.cpp.func-sort-c.html b/coverage/generic/WholeMolecules.cpp.func-sort-c.html new file mode 100644 index 000000000000..19d4a9e174b3 --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/WholeMolecules.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - WholeMolecules.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768688.4 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14WholeMoleculesC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic14WholeMoleculesC1ERKNS_13ActionOptionsE35
_ZN4PLMD7generic14WholeMolecules16registerKeywordsERNS_8KeywordsE37
_ZN4PLMD7generic14WholeMolecules5applyEv3317
_ZN4PLMD7generic14WholeMolecules9calculateEv3317
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WholeMolecules.cpp.func.html b/coverage/generic/WholeMolecules.cpp.func.html new file mode 100644 index 000000000000..71b8a43002f5 --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/WholeMolecules.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - WholeMolecules.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768688.4 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic14WholeMolecules16registerKeywordsERNS_8KeywordsE37
_ZN4PLMD7generic14WholeMolecules5applyEv3317
_ZN4PLMD7generic14WholeMolecules9calculateEv3317
_ZN4PLMD7generic14WholeMoleculesC1ERKNS_13ActionOptionsE35
_ZN4PLMD7generic14WholeMoleculesC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WholeMolecules.cpp.gcov.html b/coverage/generic/WholeMolecules.cpp.gcov.html new file mode 100644 index 000000000000..f1e728fa9f03 --- /dev/null +++ b/coverage/generic/WholeMolecules.cpp.gcov.html @@ -0,0 +1,345 @@ + + + + + + + + LCOV - plumed test coverage - generic/WholeMolecules.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - WholeMolecules.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768688.4 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Vector.h"
+      26             : #include "tools/AtomNumber.h"
+      27             : #include "tools/Tools.h"
+      28             : #include "core/PlumedMain.h"
+      29             : #include "core/ActionSet.h"
+      30             : #include "core/GenericMolInfo.h"
+      31             : #include "tools/OpenMP.h"
+      32             : #include "tools/Tree.h"
+      33             : 
+      34             : #include <vector>
+      35             : #include <string>
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace generic {
+      39             : 
+      40             : //+PLUMEDOC GENERIC WHOLEMOLECULES
+      41             : /*
+      42             : This action is used to rebuild molecules that can become split by the periodic boundary conditions.
+      43             : 
+      44             : It is similar to the ALIGN_ATOMS keyword of plumed1, and is needed since some
+      45             : MD dynamics code (e.g. GROMACS) can break molecules during the calculation.
+      46             : 
+      47             : Running some CVs without this command can cause there to be discontinuities changes
+      48             : in the CV value and artifacts in the calculations.  This command can be applied
+      49             : more than once.  To see what effect is has use a variable without pbc or use
+      50             : the \ref DUMPATOMS directive to output the atomic positions.
+      51             : 
+      52             : \attention
+      53             : This directive modifies the stored position at the precise moment
+      54             : it is executed. This means that only collective variables
+      55             : which are below it in the input script will see the corrected positions.
+      56             : As a general rule, put it at the top of the input file. Also, unless you
+      57             : know exactly what you are doing, leave the default stride (1), so that
+      58             : this action is performed at every MD step.
+      59             : 
+      60             : The way WHOLEMOLECULES modifies each of the listed entities is this:
+      61             : - First atom of the list is left in place
+      62             : - Each atom of the list is shifted by a lattice vectors so that it becomes as close as possible
+      63             :   to the previous one, iteratively.
+      64             : 
+      65             : In this way, if an entity consists of a list of atoms such that consecutive atoms in the
+      66             : list are always closer than half a box side the entity will become whole.
+      67             : This can be usually achieved selecting consecutive atoms (1-100), but it is also possible
+      68             : to skip some atoms, provided consecutive chosen atoms are close enough.
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : This command instructs plumed to reconstruct the molecule containing atoms 1-20
+      73             : at every step of the calculation and dump them on a file.
+      74             : 
+      75             : \plumedfile
+      76             : # to see the effect, one could dump the atoms as they were before molecule reconstruction:
+      77             : # DUMPATOMS FILE=dump-broken.xyz ATOMS=1-20
+      78             : WHOLEMOLECULES ENTITY0=1-20
+      79             : DUMPATOMS FILE=dump.xyz ATOMS=1-20
+      80             : \endplumedfile
+      81             : 
+      82             : This command instructs plumed to reconstruct two molecules containing atoms 1-20 and 30-40
+      83             : 
+      84             : \plumedfile
+      85             : WHOLEMOLECULES ENTITY0=1-20 ENTITY1=30-40
+      86             : DUMPATOMS FILE=dump.xyz ATOMS=1-20,30-40
+      87             : \endplumedfile
+      88             : 
+      89             : This command instructs plumed to reconstruct the chain of backbone atoms in a
+      90             : protein
+      91             : 
+      92             : \plumedfile
+      93             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      94             : MOLINFO STRUCTURE=helix.pdb
+      95             : WHOLEMOLECULES RESIDUES=all MOLTYPE=protein
+      96             : \endplumedfile
+      97             : 
+      98             : */
+      99             : //+ENDPLUMEDOC
+     100             : 
+     101             : 
+     102             : class WholeMolecules:
+     103             :   public ActionPilot,
+     104             :   public ActionAtomistic
+     105             : {
+     106             :   std::vector<std::vector<std::pair<std::size_t,std::size_t> > > p_groups;
+     107             :   std::vector<std::vector<std::pair<std::size_t,std::size_t> > > p_roots;
+     108             :   std::vector<Vector> refs;
+     109             :   bool doemst, addref;
+     110             : public:
+     111             :   explicit WholeMolecules(const ActionOptions&ao);
+     112             :   static void registerKeywords( Keywords& keys );
+     113             :   void calculate() override;
+     114        3317 :   void apply() override {}
+     115             : };
+     116             : 
+     117             : PLUMED_REGISTER_ACTION(WholeMolecules,"WHOLEMOLECULES")
+     118             : 
+     119          37 : void WholeMolecules::registerKeywords( Keywords& keys ) {
+     120          37 :   Action::registerKeywords( keys );
+     121          37 :   ActionPilot::registerKeywords( keys );
+     122          37 :   ActionAtomistic::registerKeywords( keys );
+     123          74 :   keys.add("compulsory","STRIDE","1","the frequency with which molecules are reassembled.  Unless you are completely certain about what you are doing leave this set equal to 1!");
+     124          74 :   keys.add("numbered","ENTITY","the atoms that make up a molecule that you wish to align. To specify multiple molecules use a list of ENTITY keywords: ENTITY0, ENTITY1,...");
+     125          74 :   keys.reset_style("ENTITY","atoms");
+     126          74 :   keys.add("residues","RESIDUES","this command specifies that the backbone atoms in a set of residues all must be aligned. It must be used in tandem with the \\ref MOLINFO "
+     127             :            "action and the MOLTYPE keyword. If you wish to use all the residues from all the chains in your system you can do so by "
+     128             :            "specifying all. Alternatively, if you wish to use a subset of the residues you can specify the particular residues "
+     129             :            "you are interested in as a list of numbers");
+     130          74 :   keys.add("optional","MOLTYPE","the type of molecule that is under study.  This is used to define the backbone atoms");
+     131          74 :   keys.addFlag("EMST", false, "Define atoms sequence in entities using an Euclidean minimum spanning tree");
+     132          74 :   keys.addFlag("ADDREFERENCE", false, "Define the reference position of the first atom of each entity using a PDB file");
+     133          37 : }
+     134             : 
+     135          35 : WholeMolecules::WholeMolecules(const ActionOptions&ao):
+     136             :   Action(ao),
+     137             :   ActionPilot(ao),
+     138             :   ActionAtomistic(ao),
+     139          35 :   doemst(false), addref(false)
+     140             : {
+     141             :   std::vector<std::vector<AtomNumber> > groups;
+     142             :   std::vector<std::vector<AtomNumber> > roots;
+     143             :   // parse optional flags
+     144          35 :   parseFlag("EMST", doemst);
+     145          70 :   parseFlag("ADDREFERENCE", addref);
+     146             : 
+     147             :   // create groups from ENTITY
+     148          36 :   for(int i=0;; i++) {
+     149             :     std::vector<AtomNumber> group;
+     150         142 :     parseAtomList("ENTITY",i,group);
+     151          71 :     if( group.empty() ) break;
+     152          36 :     groups.push_back(group);
+     153          36 :   }
+     154             : 
+     155             :   // Read residues to align from MOLINFO
+     156          70 :   std::vector<std::string> resstrings; parseVector("RESIDUES",resstrings);
+     157          35 :   if( resstrings.size()>0 ) {
+     158           0 :     if( resstrings.size()==1 ) {
+     159           0 :       if( resstrings[0]=="all" ) resstrings[0]="all-ter";   // Include terminal groups in alignment
+     160             :     }
+     161           0 :     std::string moltype; parse("MOLTYPE",moltype);
+     162           0 :     if(moltype.length()==0) error("Found RESIDUES keyword without specification of the molecule - use MOLTYPE");
+     163           0 :     auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     164           0 :     if( !moldat ) error("MOLINFO is required to use RESIDUES");
+     165             :     std::vector< std::vector<AtomNumber> > backatoms;
+     166           0 :     moldat->getBackbone( resstrings, moltype, backatoms );
+     167           0 :     for(unsigned i=0; i<backatoms.size(); ++i) {
+     168           0 :       groups.push_back( backatoms[i] );
+     169             :     }
+     170           0 :   }
+     171             : 
+     172             :   // check number of groups
+     173          35 :   if(groups.size()==0) error("no atoms found for WHOLEMOLECULES!");
+     174             : 
+     175             :   // if using PDBs reorder atoms in groups based on proximity in PDB file
+     176          35 :   if(doemst) {
+     177           1 :     auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     178           1 :     if( !moldat ) error("MOLINFO is required to use EMST");
+     179             :     // initialize tree
+     180           1 :     Tree tree = Tree(moldat);
+     181             :     // cycle on groups and reorder atoms
+     182           2 :     for(unsigned i=0; i<groups.size(); ++i) {
+     183           2 :       groups[i] = tree.getTree(groups[i]);
+     184             :       // store root atoms
+     185           2 :       roots.push_back(tree.getRoot());
+     186             :     }
+     187             :   } else {
+     188             :     // fill root vector with previous atom in groups
+     189          69 :     for(unsigned i=0; i<groups.size(); ++i) {
+     190             :       std::vector<AtomNumber> root;
+     191        2661 :       for(unsigned j=0; j<groups[i].size()-1; ++j) root.push_back(groups[i][j]);
+     192             :       // store root atoms
+     193          35 :       roots.push_back(root);
+     194             :     }
+     195             :   }
+     196             : 
+     197             :   // adding reference if needed
+     198          35 :   if(addref) {
+     199           2 :     auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     200           2 :     if( !moldat ) error("MOLINFO is required to use ADDREFERENCE");
+     201           4 :     for(unsigned i=0; i<groups.size(); ++i) {
+     202             :       // add reference position of first atom in entity
+     203           4 :       refs.push_back(moldat->getPosition(groups[i][0]));
+     204             :     }
+     205             :   }
+     206             : 
+     207             :   // print out info
+     208          71 :   for(unsigned i=0; i<groups.size(); ++i) {
+     209          36 :     log.printf("  atoms in entity %d : ",i);
+     210        2820 :     for(unsigned j=0; j<groups[i].size(); ++j) log.printf("%d ",groups[i][j].serial() );
+     211          36 :     log.printf("\n");
+     212          36 :     if(addref) log.printf("     with reference position : %lf %lf %lf\n",refs[i][0],refs[i][1],refs[i][2]);
+     213             :   }
+     214             : 
+     215             :   // collect all atoms
+     216             :   std::vector<AtomNumber> merge;
+     217          71 :   for(unsigned i=0; i<groups.size(); ++i) {
+     218          36 :     merge.insert(merge.end(),groups[i].begin(),groups[i].end());
+     219             :   }
+     220             : 
+     221             :   // Convert groups to p_groups
+     222          35 :   p_groups.resize( groups.size() );
+     223          71 :   for(unsigned i=0; i<groups.size(); ++i) {
+     224          36 :     p_groups[i].resize( groups[i].size() );
+     225        2820 :     for(unsigned j=0; j<groups[i].size(); ++j) p_groups[i][j] = getValueIndices( groups[i][j] );
+     226             :   }
+     227             :   // Convert roots to p_roots
+     228          35 :   p_roots.resize( roots.size() );
+     229          71 :   for(unsigned i=0; i<roots.size(); ++i) {
+     230          36 :     p_roots[i].resize( roots[i].size() );
+     231        2784 :     for(unsigned j=0; j<roots[i].size(); ++j) p_roots[i][j] = getValueIndices( roots[i][j] );
+     232             :   }
+     233             : 
+     234             : 
+     235          35 :   checkRead();
+     236          35 :   Tools::removeDuplicates(merge);
+     237          35 :   requestAtoms(merge);
+     238             :   doNotRetrieve();
+     239             :   doNotForce();
+     240          35 : }
+     241             : 
+     242        3317 : void WholeMolecules::calculate() {
+     243        6639 :   for(unsigned i=0; i<p_groups.size(); ++i) {
+     244        3322 :     Vector first = getGlobalPosition(p_groups[i][0]);
+     245        3322 :     if(addref) {
+     246          12 :       first = refs[i]+pbcDistance(refs[i],first);
+     247          12 :       setGlobalPosition( p_groups[i][0], first );
+     248             :     }
+     249        3322 :     if(!doemst) {
+     250      294360 :       for(unsigned j=1; j<p_groups[i].size(); ++j) {
+     251      291040 :         Vector second=getGlobalPosition(p_groups[i][j]);
+     252      291040 :         first = first+pbcDistance(first,second);
+     253      291040 :         setGlobalPosition(p_groups[i][j], first );
+     254             :       }
+     255             :     } else {
+     256         246 :       for(unsigned j=1; j<p_groups[i].size(); ++j) {
+     257         244 :         Vector first=getGlobalPosition(p_roots[i][j-1]);
+     258         244 :         Vector second=getGlobalPosition(p_groups[i][j]);
+     259         244 :         second=first+pbcDistance(first,second);
+     260         244 :         setGlobalPosition(p_groups[i][j], second );
+     261             :       }
+     262             :     }
+     263             :   }
+     264        3317 : }
+     265             : 
+     266             : 
+     267             : }
+     268             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WrapAround.cpp.func-sort-c.html b/coverage/generic/WrapAround.cpp.func-sort-c.html new file mode 100644 index 000000000000..164a5e519a31 --- /dev/null +++ b/coverage/generic/WrapAround.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/WrapAround.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - WrapAround.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:575898.3 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10WrapAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD7generic10WrapAroundC1ERKNS_13ActionOptionsE5
_ZN4PLMD7generic10WrapAround16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7generic10WrapAround5applyEv579
_ZN4PLMD7generic10WrapAround9calculateEv579
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WrapAround.cpp.func.html b/coverage/generic/WrapAround.cpp.func.html new file mode 100644 index 000000000000..3367460f4890 --- /dev/null +++ b/coverage/generic/WrapAround.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - generic/WrapAround.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - WrapAround.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:575898.3 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7generic10WrapAround16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7generic10WrapAround5applyEv579
_ZN4PLMD7generic10WrapAround9calculateEv579
_ZN4PLMD7generic10WrapAroundC1ERKNS_13ActionOptionsE5
_ZN4PLMD7generic10WrapAroundC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/WrapAround.cpp.gcov.html b/coverage/generic/WrapAround.cpp.gcov.html new file mode 100644 index 000000000000..300cc5e02512 --- /dev/null +++ b/coverage/generic/WrapAround.cpp.gcov.html @@ -0,0 +1,333 @@ + + + + + + + + LCOV - plumed test coverage - generic/WrapAround.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - generic - WrapAround.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:575898.3 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Vector.h"
+      26             : #include "tools/AtomNumber.h"
+      27             : #include "tools/Tools.h"
+      28             : #include "core/PlumedMain.h"
+      29             : #include "core/ActionSet.h"
+      30             : #include "core/GenericMolInfo.h"
+      31             : 
+      32             : #include <vector>
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace generic {
+      36             : 
+      37             : //+PLUMEDOC GENERIC WRAPAROUND
+      38             : /*
+      39             : Rebuild periodic boundary conditions around chosen atoms.
+      40             : 
+      41             : 
+      42             : Modify position of atoms indicated by ATOMS by shifting them by lattice vectors so that they are
+      43             : as close as possible to the atoms indicated by AROUND. More precisely, for every atom i
+      44             : in the ATOMS list the following procedure is performed:
+      45             : - The atom j among those in the AROUND list is searched that is closest to atom i.
+      46             : - The atom i is replaced with its periodic image that is closest to atom j.
+      47             : 
+      48             : This action works similarly to \ref WHOLEMOLECULES in that it replaces atoms coordinate. Notice that only
+      49             : atoms specified with ATOMS are replaced, and that, at variance with \ref WHOLEMOLECULES,
+      50             : the order in which atoms are specified is irrelevant.
+      51             : 
+      52             : This is often convenient at a post processing stage (using the \ref driver), but sometime
+      53             : it is required during the simulation if collective variables need atoms to be in a specific periodic image.
+      54             : 
+      55             : \attention This directive modifies the stored position at the precise moment it is executed. This means that only collective variables which are below it in the input script will see the corrected positions. As a general rule, put it at the top of the input file. Also, unless you know exactly what you are doing, leave the default stride (1), so that this action is performed at every MD step.
+      56             : 
+      57             : Consider that the computational cost grows with the product
+      58             : of the size of the two lists (ATOMS and AROUND), so that this action can become very expensive.
+      59             : If you are using it to analyze a trajectory this is usually not a big problem. If you use it to
+      60             : analyze a simulation on the fly, e.g. with \ref DUMPATOMS to store a properly wrapped trajectory,
+      61             : consider the possibility of using the STRIDE keyword here (with great care).
+      62             : \par Examples
+      63             : 
+      64             : This command instructs plumed to move all the ions to their periodic image that is as close as possible to
+      65             : the rna group.
+      66             : 
+      67             : \plumedfile
+      68             : rna: GROUP ATOMS=1-100
+      69             : ions: GROUP ATOMS=101-110
+      70             : # first make the rna molecule whole
+      71             : WHOLEMOLECULES ENTITY0=rna
+      72             : WRAPAROUND ATOMS=ions AROUND=rna
+      73             : DUMPATOMS FILE=dump.xyz ATOMS=rna,ions
+      74             : \endplumedfile
+      75             : 
+      76             : In case you want to do it during a simulation and you only care about wrapping the ions in
+      77             : the `dump.xyz` file, you can use the following:
+      78             : 
+      79             : \plumedfile
+      80             : # add some restraint that do not require molecules to be whole:
+      81             : a: TORSION ATOMS=1,2,10,11
+      82             : RESTRAINT ARG=a AT=0.0 KAPPA=5
+      83             : 
+      84             : 
+      85             : # then do the things that are required for dumping the trajectory
+      86             : # notice that they are all done every 100 steps, so as not to
+      87             : # unnecessarily overload the calculation
+      88             : 
+      89             : rna: GROUP ATOMS=1-100
+      90             : ions: GROUP ATOMS=101-110
+      91             : # first make the rna molecule whole
+      92             : WHOLEMOLECULES ENTITY0=rna STRIDE=100
+      93             : WRAPAROUND ATOMS=ions AROUND=rna STRIDE=100
+      94             : DUMPATOMS FILE=dump.xyz ATOMS=rna,ions STRIDE=100
+      95             : \endplumedfile
+      96             : 
+      97             : Notice that if the biased variable requires a molecule to be whole, you might have to put
+      98             : just the \ref WHOLEMOLECULES command before computing that variable and leave the default STRIDE=1.
+      99             : 
+     100             : This command instructs plumed to center all atoms around the center of mass of a solute molecule.
+     101             : 
+     102             : \plumedfile
+     103             : solute: GROUP ATOMS=1-100
+     104             : all: GROUP ATOMS=1-1000
+     105             : # center of the solute:
+     106             : # notice that since plumed 2.2 this also works if the
+     107             : # solute molecule is broken
+     108             : com: COM ATOMS=solute
+     109             : # notice that we wrap around a single atom. this should be fast
+     110             : WRAPAROUND ATOMS=all AROUND=com
+     111             : DUMPATOMS FILE=dump.xyz ATOMS=all
+     112             : \endplumedfile
+     113             : 
+     114             : Notice that whereas \ref WHOLEMOLECULES is designed to make molecules whole,
+     115             : \ref WRAPAROUND can easily break molecules. In the last example,
+     116             : if solvent (atoms 101-1000) is made e.g. of water, then water
+     117             : molecules could be broken by \ref WRAPAROUND (hydrogen could end up
+     118             : in an image and oxygen in another one).
+     119             : One solution is to use \ref WHOLEMOLECULES on _all_ the water molecules
+     120             : after \ref WRAPAROUND. This is tedious. A better solution is to use the
+     121             : GROUPBY option which is going
+     122             : to consider the atoms listed in ATOMS as a list of groups
+     123             : each of size GROUPBY. The first atom of the group will be brought
+     124             : close to the AROUND atoms. The following atoms of the group
+     125             : will be just brought close to the first atom of the group.
+     126             : Assuming that oxygen is the first atom of each water molecules,
+     127             : in the following examples all the water oxygen atoms will be brought
+     128             : close to the solute, and all the hydrogen atoms will be kept close
+     129             : to their related oxygen.
+     130             : 
+     131             : \plumedfile
+     132             : solute: GROUP ATOMS=1-100
+     133             : water: GROUP ATOMS=101-1000
+     134             : com: COM ATOMS=solute
+     135             : # notice that we wrap around a single atom. this should be fast
+     136             : WRAPAROUND ATOMS=solute AROUND=com
+     137             : # notice that we wrap around a single atom. this should be fast
+     138             : WRAPAROUND ATOMS=water AROUND=com GROUPBY=3
+     139             : DUMPATOMS FILE=dump.xyz ATOMS=solute,water
+     140             : \endplumedfile
+     141             : 
+     142             : */
+     143             : //+ENDPLUMEDOC
+     144             : 
+     145             : 
+     146             : class WrapAround:
+     147             :   public ActionPilot,
+     148             :   public ActionAtomistic
+     149             : {
+     150             :   // cppcheck-suppress duplInheritedMember
+     151             :   std::vector<Vector> refatoms;
+     152             :   std::vector<std::pair<std::size_t,std::size_t> > p_atoms;
+     153             :   std::vector<std::pair<std::size_t,std::size_t> > p_reference;
+     154             :   unsigned groupby;
+     155             :   bool pair_;
+     156             : public:
+     157             :   explicit WrapAround(const ActionOptions&ao);
+     158             :   static void registerKeywords( Keywords& keys );
+     159             :   void calculate() override;
+     160         579 :   void apply() override {}
+     161             : };
+     162             : 
+     163             : PLUMED_REGISTER_ACTION(WrapAround,"WRAPAROUND")
+     164             : 
+     165           7 : void WrapAround::registerKeywords( Keywords& keys ) {
+     166           7 :   Action::registerKeywords( keys );
+     167           7 :   ActionAtomistic::registerKeywords( keys );
+     168           7 :   ActionPilot::registerKeywords( keys );
+     169          14 :   keys.add("compulsory","STRIDE","1","the frequency with which molecules are reassembled.  Unless you are completely certain about what you are doing leave this set equal to 1!");
+     170          14 :   keys.add("atoms","AROUND","reference atoms");
+     171          14 :   keys.add("atoms","ATOMS","wrapped atoms");
+     172          14 :   keys.add("compulsory","GROUPBY","1","group atoms so as not to break molecules");
+     173          14 :   keys.addFlag("PAIR", false, "Pair atoms in AROUND and ATOMS groups");
+     174           7 : }
+     175             : 
+     176           5 : WrapAround::WrapAround(const ActionOptions&ao):
+     177             :   Action(ao),
+     178             :   ActionPilot(ao),
+     179             :   ActionAtomistic(ao),
+     180           5 :   groupby(1),
+     181           5 :   pair_(false)
+     182             : {
+     183          10 :   std::vector<AtomNumber> atoms; parseAtomList("ATOMS",atoms);
+     184           5 :   std::vector<AtomNumber> reference; parseAtomList("AROUND",reference);
+     185           5 :   parse("GROUPBY",groupby);
+     186           5 :   parseFlag("PAIR", pair_);
+     187             : 
+     188           5 :   log.printf("  atoms in reference :");
+     189          11 :   for(unsigned j=0; j<reference.size(); ++j) log.printf(" %d",reference[j].serial() );
+     190           5 :   log.printf("\n");
+     191           5 :   log.printf("  atoms to be wrapped :");
+     192         399 :   for(unsigned j=0; j<atoms.size(); ++j) log.printf(" %d",atoms[j].serial() );
+     193           5 :   log.printf("\n");
+     194           5 :   if(groupby>1) log<<"  atoms will be grouped by "<<groupby<<"\n";
+     195           5 :   if(pair_) log.printf("  pairing atoms and references\n");
+     196             : 
+     197           5 :   if(atoms.size()%groupby!=0) error("number of atoms should be a multiple of groupby option");
+     198             :   // additional checks with PAIR
+     199           5 :   if(pair_ && atoms.size()!=reference.size()*groupby) error("with PAIR you must have: #ATOMS = #AROUND * #GROUPBY");
+     200             : 
+     201           5 :   checkRead();
+     202             : 
+     203             :   // do not remove duplicates with pair
+     204           5 :   if(!pair_) {
+     205           5 :     if(groupby<=1) Tools::removeDuplicates(atoms);
+     206           5 :     Tools::removeDuplicates(reference);
+     207             :   }
+     208             : 
+     209           5 :   std::vector<AtomNumber> merged(atoms.size()+reference.size());
+     210           5 :   merge(atoms.begin(),atoms.end(),reference.begin(),reference.end(),merged.begin());
+     211         404 :   p_atoms.resize( atoms.size() ); for(unsigned i=0; i<atoms.size(); ++i) p_atoms[i] = getValueIndices( atoms[i] );
+     212           5 :   refatoms.resize( reference.size() ); p_reference.resize( reference.size() );
+     213          11 :   for(unsigned i=0; i<reference.size(); ++i) p_reference[i] = getValueIndices( reference[i] );
+     214           5 :   Tools::removeDuplicates(merged);
+     215           5 :   requestAtoms(merged);
+     216             :   doNotRetrieve();
+     217             :   doNotForce();
+     218           5 : }
+     219             : 
+     220         579 : void WrapAround::calculate() {
+     221        1163 :   for(unsigned j=0; j<p_reference.size(); ++j) refatoms[j] = getGlobalPosition(p_reference[j]);
+     222             : 
+     223       15012 :   for(unsigned i=0; i<p_atoms.size(); i+=groupby) {
+     224       14433 :     Vector second, first=getGlobalPosition(p_atoms[i]);
+     225             :     double mindist2=std::numeric_limits<double>::max();
+     226             :     int closest=-1;
+     227       14433 :     if(pair_) {
+     228           0 :       closest = i/groupby;
+     229             :     } else {
+     230       29416 :       for(unsigned j=0; j<p_reference.size(); ++j) {
+     231       14983 :         second=refatoms[j];
+     232             :         const Vector distance=pbcDistance(first,second);
+     233       14983 :         const double distance2=modulo2(distance);
+     234       14983 :         if(distance2<mindist2) {
+     235             :           mindist2=distance2;
+     236       14713 :           closest=j;
+     237             :         }
+     238             :       }
+     239       14433 :       plumed_massert(closest>=0,"closest not found");
+     240             :     }
+     241       14433 :     second=refatoms[closest];
+     242             : // place first atom of the group
+     243       14433 :     first=second+pbcDistance(second,first); setGlobalPosition(p_atoms[i],first);
+     244             : // then place other atoms close to the first of the group
+     245       14928 :     for(unsigned j=1; j<groupby; j++) {
+     246         495 :       second=getGlobalPosition(p_atoms[i+j]);
+     247         495 :       setGlobalPosition( p_atoms[i+j], first+pbcDistance(first,second) );
+     248             :     }
+     249             :   }
+     250         579 : }
+     251             : 
+     252             : 
+     253             : 
+     254             : }
+     255             : 
+     256             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/index-sort-f.html b/coverage/generic/index-sort-f.html new file mode 100644 index 000000000000..74850c363a93 --- /dev/null +++ b/coverage/generic/index-sort-f.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1195125895.0 %
Date:2024-02-22 21:58:45Functions:10914873.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Time.cpp +
28.6%28.6%
+
28.6 %4 / 1416.7 %1 / 6
RandomExchanges.cpp +
30.8%30.8%
+
30.8 %4 / 1325.0 %1 / 4
Include.cpp +
83.3%83.3%
+
83.3 %10 / 1240.0 %2 / 5
EndPlumed.cpp +
80.0%80.0%
+
80.0 %8 / 1050.0 %2 / 4
FitToTemplate.cpp +
97.2%97.2%
+
97.2 %103 / 10666.7 %4 / 6
DumpAtoms.cpp +
98.3%98.3%
+
98.3 %117 / 11977.8 %7 / 9
DumpDerivatives.cpp +
100.0%
+
100.0 %46 / 4677.8 %7 / 9
DumpForces.cpp +
100.0%
+
100.0 %37 / 3777.8 %7 / 9
EffectiveEnergyDrift.cpp +
97.4%97.4%
+
97.4 %147 / 15177.8 %7 / 9
Debug.cpp +
100.0%
+
100.0 %56 / 5680.0 %4 / 5
WholeMolecules.cpp +
88.4%88.4%
+
88.4 %76 / 8680.0 %4 / 5
WrapAround.cpp +
98.3%98.3%
+
98.3 %57 / 5880.0 %4 / 5
ResetCell.cpp +
100.0%
+
100.0 %55 / 5580.0 %4 / 5
DumpMassCharge.cpp +
98.4%98.4%
+
98.4 %62 / 6380.0 %8 / 10
Print.cpp +
96.5%96.5%
+
96.5 %55 / 5780.0 %8 / 10
DumpProjections.cpp +
100.0%
+
100.0 %38 / 3880.0 %8 / 10
UpdateIf.cpp +
100.0%
+
100.0 %42 / 4280.0 %8 / 10
Read.cpp +
94.9%94.9%
+
94.9 %94 / 9981.8 %9 / 11
Plumed.cpp +
93.2%93.2%
+
93.2 %165 / 17781.8 %9 / 11
Flush.cpp +
100.0%
+
100.0 %19 / 19100.0 %5 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/index-sort-l.html b/coverage/generic/index-sort-l.html new file mode 100644 index 000000000000..4e319cce1b48 --- /dev/null +++ b/coverage/generic/index-sort-l.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1195125895.0 %
Date:2024-02-22 21:58:45Functions:10914873.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Time.cpp +
28.6%28.6%
+
28.6 %4 / 1416.7 %1 / 6
RandomExchanges.cpp +
30.8%30.8%
+
30.8 %4 / 1325.0 %1 / 4
EndPlumed.cpp +
80.0%80.0%
+
80.0 %8 / 1050.0 %2 / 4
Include.cpp +
83.3%83.3%
+
83.3 %10 / 1240.0 %2 / 5
WholeMolecules.cpp +
88.4%88.4%
+
88.4 %76 / 8680.0 %4 / 5
Plumed.cpp +
93.2%93.2%
+
93.2 %165 / 17781.8 %9 / 11
Read.cpp +
94.9%94.9%
+
94.9 %94 / 9981.8 %9 / 11
Print.cpp +
96.5%96.5%
+
96.5 %55 / 5780.0 %8 / 10
FitToTemplate.cpp +
97.2%97.2%
+
97.2 %103 / 10666.7 %4 / 6
EffectiveEnergyDrift.cpp +
97.4%97.4%
+
97.4 %147 / 15177.8 %7 / 9
WrapAround.cpp +
98.3%98.3%
+
98.3 %57 / 5880.0 %4 / 5
DumpAtoms.cpp +
98.3%98.3%
+
98.3 %117 / 11977.8 %7 / 9
DumpMassCharge.cpp +
98.4%98.4%
+
98.4 %62 / 6380.0 %8 / 10
Flush.cpp +
100.0%
+
100.0 %19 / 19100.0 %5 / 5
DumpForces.cpp +
100.0%
+
100.0 %37 / 3777.8 %7 / 9
DumpProjections.cpp +
100.0%
+
100.0 %38 / 3880.0 %8 / 10
UpdateIf.cpp +
100.0%
+
100.0 %42 / 4280.0 %8 / 10
DumpDerivatives.cpp +
100.0%
+
100.0 %46 / 4677.8 %7 / 9
ResetCell.cpp +
100.0%
+
100.0 %55 / 5580.0 %4 / 5
Debug.cpp +
100.0%
+
100.0 %56 / 5680.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/generic/index.html b/coverage/generic/index.html new file mode 100644 index 000000000000..0ff6ac295b6b --- /dev/null +++ b/coverage/generic/index.html @@ -0,0 +1,284 @@ + + + + + + + + LCOV - plumed test coverage - generic + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - genericHitTotalCoverage
Test:plumed test coverageLines:1195125895.0 %
Date:2024-02-22 21:58:45Functions:10914873.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Debug.cpp +
100.0%
+
100.0 %56 / 5680.0 %4 / 5
DumpAtoms.cpp +
98.3%98.3%
+
98.3 %117 / 11977.8 %7 / 9
DumpDerivatives.cpp +
100.0%
+
100.0 %46 / 4677.8 %7 / 9
DumpForces.cpp +
100.0%
+
100.0 %37 / 3777.8 %7 / 9
DumpMassCharge.cpp +
98.4%98.4%
+
98.4 %62 / 6380.0 %8 / 10
DumpProjections.cpp +
100.0%
+
100.0 %38 / 3880.0 %8 / 10
EffectiveEnergyDrift.cpp +
97.4%97.4%
+
97.4 %147 / 15177.8 %7 / 9
EndPlumed.cpp +
80.0%80.0%
+
80.0 %8 / 1050.0 %2 / 4
FitToTemplate.cpp +
97.2%97.2%
+
97.2 %103 / 10666.7 %4 / 6
Flush.cpp +
100.0%
+
100.0 %19 / 19100.0 %5 / 5
Include.cpp +
83.3%83.3%
+
83.3 %10 / 1240.0 %2 / 5
Plumed.cpp +
93.2%93.2%
+
93.2 %165 / 17781.8 %9 / 11
Print.cpp +
96.5%96.5%
+
96.5 %55 / 5780.0 %8 / 10
RandomExchanges.cpp +
30.8%30.8%
+
30.8 %4 / 1325.0 %1 / 4
Read.cpp +
94.9%94.9%
+
94.9 %94 / 9981.8 %9 / 11
ResetCell.cpp +
100.0%
+
100.0 %55 / 5580.0 %4 / 5
Time.cpp +
28.6%28.6%
+
28.6 %4 / 1416.7 %1 / 6
UpdateIf.cpp +
100.0%
+
100.0 %42 / 4280.0 %8 / 10
WholeMolecules.cpp +
88.4%88.4%
+
88.4 %76 / 8680.0 %4 / 5
WrapAround.cpp +
98.3%98.3%
+
98.3 %57 / 5880.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/glass.png b/coverage/glass.png new file mode 100644 index 0000000000000000000000000000000000000000..e1abc00680a3093c49fdb775ae6bdb6764c95af2 GIT binary patch literal 167 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)gaEa{HEjtmSN`?>!lvI6;R0X`wF z|Ns97GD8ntt^-nxB|(0{3=Yq3q=7g|-tI089jvk*Kn`btM`SSr1Gf+eGhVt|_XjA* zUgGKN%6^Gmn4d%Ph(nkFP>9RZ#WAE}PI3Z}&BVayv3^M*kj3EX>gTe~DWM4f=_Dpv literal 0 HcmV?d00001 diff --git a/coverage/gridtools/ActionWithGrid.cpp.func-sort-c.html b/coverage/gridtools/ActionWithGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..5320f2d05583 --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515298.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools14ActionWithGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools14ActionWithGrid17turnOnDerivativesEv16
_ZN4PLMD9gridtools14ActionWithGrid10createGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_65
_ZN4PLMD9gridtools14ActionWithGridC2ERKNS_13ActionOptionsE70
_ZN4PLMD9gridtools14ActionWithGrid16registerKeywordsERNS_8KeywordsE88
_ZN4PLMD9gridtools14ActionWithGrid9calculateEv215
_ZNK4PLMD9gridtools14ActionWithGrid7runTaskERKjRNS_10MultiValueE57902
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithGrid.cpp.func.html b/coverage/gridtools/ActionWithGrid.cpp.func.html new file mode 100644 index 000000000000..3aa937e664a0 --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515298.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools14ActionWithGrid10createGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_65
_ZN4PLMD9gridtools14ActionWithGrid16registerKeywordsERNS_8KeywordsE88
_ZN4PLMD9gridtools14ActionWithGrid17turnOnDerivativesEv16
_ZN4PLMD9gridtools14ActionWithGrid9calculateEv215
_ZN4PLMD9gridtools14ActionWithGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools14ActionWithGridC2ERKNS_13ActionOptionsE70
_ZNK4PLMD9gridtools14ActionWithGrid7runTaskERKjRNS_10MultiValueE57902
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithGrid.cpp.gcov.html b/coverage/gridtools/ActionWithGrid.cpp.gcov.html new file mode 100644 index 000000000000..6740704e9086 --- /dev/null +++ b/coverage/gridtools/ActionWithGrid.cpp.gcov.html @@ -0,0 +1,187 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:515298.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithGrid.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace gridtools {
+      28             : 
+      29          88 : void ActionWithGrid::registerKeywords( Keywords& keys ) {
+      30          88 :   vesselbase::ActionWithAveraging::registerKeywords( keys );
+      31         176 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density estimation");
+      32         176 :   keys.add("compulsory","KERNEL","gaussian","the kernel function you are using.  More details on  the kernels available "
+      33             :            "in plumed plumed can be found in \\ref kernelfunctions.");
+      34         176 :   keys.add("optional","CONCENTRATION","the concentration parameter for Von Mises-Fisher distributions");
+      35          88 : }
+      36             : 
+      37          70 : ActionWithGrid::ActionWithGrid( const ActionOptions& ao):
+      38             :   Action(ao),
+      39             :   ActionWithAveraging(ao),
+      40          70 :   mygrid(NULL)
+      41             : {
+      42          70 : }
+      43             : 
+      44          65 : std::unique_ptr<GridVessel> ActionWithGrid::createGrid( const std::string& type, const std::string& inputstr ) {
+      45             :   // Start creating the input for the grid
+      46          65 :   std::string vstring = inputstr;
+      47         130 :   if( keywords.exists("KERNEL") ) {
+      48          90 :     std::string vconc; parse("CONCENTRATION",vconc);
+      49          45 :     if( vconc.length()>0 ) {
+      50           4 :       vstring += " TYPE=fibonacci CONCENTRATION=" + vconc;
+      51             :     } else {
+      52          86 :       std::string kstring; parse("KERNEL",kstring);
+      53          53 :       if( kstring=="DISCRETE" ) vstring += " KERNEL=" + kstring;
+      54          66 :       else vstring += " KERNEL=" + kstring + " " + getKeyword("BANDWIDTH");
+      55             :     }
+      56             :   }
+      57         130 :   vesselbase::VesselOptions da("mygrid","",-1,vstring,this);
+      58          65 :   Keywords keys; gridtools::AverageOnGrid::registerKeywords( keys );
+      59          65 :   vesselbase::VesselOptions dar( da, keys );
+      60          65 :   std::unique_ptr<GridVessel> grid;
+      61          65 :   if( type=="histogram" ) {
+      62          37 :     grid=Tools::make_unique<HistogramOnGrid>(dar);
+      63          28 :   } else if( type=="average" ) {
+      64           8 :     grid=Tools::make_unique<AverageOnGrid>(dar);
+      65          20 :   } else if( type=="grid" ) {
+      66          20 :     grid=Tools::make_unique<GridVessel>(dar);
+      67             :   } else {
+      68           0 :     plumed_merror("no way to create grid of type " + type );
+      69             :   }
+      70             :   // cppcheck-suppress danglingLifetime
+      71          65 :   mygrid=grid.get();
+      72          65 :   return grid;
+      73          65 : }
+      74             : 
+      75          16 : void ActionWithGrid::turnOnDerivatives() {
+      76          16 :   needsDerivatives(); ActionWithValue::turnOnDerivatives();
+      77          16 :   if( getStride()==1 ) setStride(0);
+      78           8 :   else if( getStride()!=0 ) error("conflicting instructions for grid - stride was set but must be evaluated on every step for derivatives - remove STRIDE keyword");
+      79          16 :   if( clearstride>1 ) error("conflicting instructions for grid - CLEAR was set but grid must be reset on every step for derivatives - remove CLEAR keyword" );
+      80          16 :   if( weights.size()>0 ) error("conflicting instructions for grid - LOGWEIGHTS was set but weights are not considered when derivatives of grid are evaluated - remove LOGWEIGHTS keyword");
+      81          16 : }
+      82             : 
+      83         215 : void ActionWithGrid::calculate() {
+      84             :   // Do nothing if derivatives are not required
+      85         215 :   if( doNotCalculateDerivatives() ) return;
+      86             :   // Clear on every step
+      87          40 :   if( mygrid ) clearAverage();
+      88             :   // Should not be any reweighting so just set these accordingly
+      89          40 :   lweight=0; cweight=1.0;
+      90             :   // Prepare to do the averaging
+      91          40 :   prepareForAveraging();
+      92             :   // Run all the tasks (if required
+      93          40 :   if( useRunAllTasks ) runAllTasks();
+      94             :   // This the averaging if it is not done using task list
+      95          20 :   else performOperations( true );
+      96             :   // Update the norm
+      97          40 :   if( mygrid ) mygrid->setNorm( cweight );
+      98             :   // Finish the averaging
+      99          40 :   finishAveraging();
+     100             :   // And reset for next step
+     101          40 :   if( mygrid ) mygrid->reset();
+     102             : }
+     103             : 
+     104       57902 : void ActionWithGrid::runTask( const unsigned& current, MultiValue& myvals ) const {
+     105             :   // Set the weight of this point
+     106       57902 :   myvals.setValue( 0, cweight ); compute( current, myvals );
+     107       57902 : }
+     108             : 
+     109             : }
+     110             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.cpp.func-sort-c.html b/coverage/gridtools/ActionWithInputGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..f99d2e616ed9 --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithInputGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithInputGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313491.2 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools19ActionWithInputGrid17performOperationsERKb21
_ZN4PLMD9gridtools19ActionWithInputGridC2ERKNS_13ActionOptionsE25
_ZN4PLMD9gridtools19ActionWithInputGrid12clearAverageEv26
_ZN4PLMD9gridtools19ActionWithInputGrid16registerKeywordsERNS_8KeywordsE39
_ZN4PLMD9gridtools19ActionWithInputGrid19prepareForAveragingEv70
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.cpp.func.html b/coverage/gridtools/ActionWithInputGrid.cpp.func.html new file mode 100644 index 000000000000..8244c79653c5 --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithInputGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithInputGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313491.2 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGrid12clearAverageEv26
_ZN4PLMD9gridtools19ActionWithInputGrid16registerKeywordsERNS_8KeywordsE39
_ZN4PLMD9gridtools19ActionWithInputGrid17performOperationsERKb21
_ZN4PLMD9gridtools19ActionWithInputGrid19prepareForAveragingEv70
_ZN4PLMD9gridtools19ActionWithInputGridC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools19ActionWithInputGridC2ERKNS_13ActionOptionsE25
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.cpp.gcov.html b/coverage/gridtools/ActionWithInputGrid.cpp.gcov.html new file mode 100644 index 000000000000..707f6fb44dd4 --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithInputGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithInputGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313491.2 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithInputGrid.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace gridtools {
+      28             : 
+      29          39 : void ActionWithInputGrid::registerKeywords( Keywords& keys ) {
+      30          39 :   ActionWithGrid::registerKeywords( keys );
+      31          78 :   keys.add("compulsory","GRID","the action that creates the input grid you would like to use");
+      32          78 :   keys.add("optional","COMPONENT","if your input is a vector field use this to specify the component of the input vector field for which you wish to use");
+      33          39 : }
+      34             : 
+      35          25 : ActionWithInputGrid::ActionWithInputGrid(const ActionOptions&ao):
+      36             :   Action(ao),
+      37             :   ActionWithGrid(ao),
+      38          25 :   ingrid(NULL)
+      39             : {
+      40          25 :   std::string mlab; parse("GRID",mlab);
+      41          25 :   vesselbase::ActionWithVessel* mves= plumed.getActionSet().selectWithLabel<vesselbase::ActionWithVessel*>(mlab);
+      42          25 :   if(!mves) error("action labelled " +  mlab + " does not exist or does not have vessels");
+      43          25 :   addDependency(mves);
+      44             : 
+      45          25 :   for(unsigned i=0; i<mves->getNumberOfVessels(); ++i) {
+      46          25 :     ingrid=dynamic_cast<GridVessel*>( mves->getPntrToVessel(i) );
+      47          25 :     if( ingrid ) break;
+      48             :   }
+      49          25 :   if( !ingrid ) error("input action does not calculate a grid");
+      50             : 
+      51          25 :   if( ingrid->getNumberOfComponents()==1 ) {
+      52          25 :     mycomp=0;
+      53             :   } else {
+      54           0 :     int tcomp=-1; parse("COMPONENT",tcomp);
+      55           0 :     if( tcomp<0 ) error("component of vector field was not specified - use COMPONENT keyword");
+      56           0 :     mycomp=tcomp;
+      57             :   }
+      58          25 :   log.printf("  using %uth component of grid calculated by action %s \n",mycomp,mves->getLabel().c_str() );
+      59          25 : }
+      60             : 
+      61          26 : void ActionWithInputGrid::clearAverage() {
+      62          52 :   if( mygrid->getType()=="flat" ) mygrid->setBounds( ingrid->getMin(), ingrid->getMax(), mygrid->getNbin(), mygrid->getGridSpacing() );
+      63          26 :   ActionWithAveraging::clearAverage();
+      64          26 : }
+      65             : 
+      66          70 : void ActionWithInputGrid::prepareForAveraging() {
+      67          70 :   if( checkAllActive() ) {
+      68       93583 :     for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) {
+      69       93513 :       if( ingrid->inactive(i) ) error("if FIND_CONTOUR is used with BUFFER option then other actions cannot be performed with grid");
+      70             :     }
+      71             :   }
+      72          70 : }
+      73             : 
+      74          21 : void ActionWithInputGrid::performOperations( const bool& from_update ) {
+      75          21 :   prepareForAveraging(); runAllTasks();
+      76          21 : }
+      77             : 
+      78             : }
+      79             : }
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.h.func-sort-c.html b/coverage/gridtools/ActionWithInputGrid.h.func-sort-c.html new file mode 100644 index 000000000000..8490cf979c59 --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithInputGrid.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithInputGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGrid5applyEv28
_ZNK4PLMD9gridtools19ActionWithInputGrid14checkAllActiveEv70
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKSt6vectorIjSaIjEE32928
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKj117146
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.h.func.html b/coverage/gridtools/ActionWithInputGrid.h.func.html new file mode 100644 index 000000000000..e9d5d6bfdd07 --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithInputGrid.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithInputGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools19ActionWithInputGrid5applyEv28
_ZNK4PLMD9gridtools19ActionWithInputGrid14checkAllActiveEv70
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKSt6vectorIjSaIjEE32928
_ZNK4PLMD9gridtools19ActionWithInputGrid16getFunctionValueERKj117146
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithInputGrid.h.gcov.html b/coverage/gridtools/ActionWithInputGrid.h.gcov.html new file mode 100644 index 000000000000..81c12fe28b5f --- /dev/null +++ b/coverage/gridtools/ActionWithInputGrid.h.gcov.html @@ -0,0 +1,146 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithInputGrid.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithInputGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_gridtools_ActionWithInputGrid_h
+      23             : #define __PLUMED_gridtools_ActionWithInputGrid_h
+      24             : 
+      25             : #include "core/ActionPilot.h"
+      26             : #include "ActionWithGrid.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace gridtools {
+      30             : 
+      31             : class ActionWithInputGrid : public ActionWithGrid {
+      32             :   friend class DumpGrid;
+      33             : private:
+      34             :   unsigned mycomp;
+      35             : protected:
+      36             :   GridVessel* ingrid;
+      37             :   double getFunctionValue( const unsigned& ipoint ) const ;
+      38             :   double getFunctionValue( const std::vector<unsigned>& ip ) const ;
+      39             :   double getFunctionValueAndDerivatives( const std::vector<double>& x, std::vector<double>& der ) const ;
+      40             : public:
+      41             :   static void registerKeywords( Keywords& keys );
+      42             :   explicit ActionWithInputGrid(const ActionOptions&ao);
+      43             :   void clearAverage() override;
+      44             :   void prepareForAveraging() override;
+      45          70 :   virtual bool checkAllActive() const { return true; }
+      46             :   void performOperations( const bool& from_update ) override;
+      47          28 :   void apply() override {};
+      48             : };
+      49             : 
+      50             : inline
+      51      117146 : double ActionWithInputGrid::getFunctionValue( const unsigned& ipoint ) const {
+      52      117146 :   unsigned dim=ingrid->getDimension(); if( ingrid->noderiv ) dim=0;
+      53      117146 :   return ingrid->getGridElement( ipoint, mycomp*(1+dim) );
+      54             : }
+      55             : 
+      56             : inline
+      57       32928 : double ActionWithInputGrid::getFunctionValue( const std::vector<unsigned>& ip ) const {
+      58       32928 :   return getFunctionValue( ingrid->getIndex(ip) );
+      59             : }
+      60             : 
+      61             : inline
+      62             : double ActionWithInputGrid::getFunctionValueAndDerivatives( const std::vector<double>& x, std::vector<double>& der ) const {
+      63        8546 :   return ingrid->getValueAndDerivatives( x, mycomp, der );
+      64             : }
+      65             : 
+      66             : }
+      67             : }
+      68             : #endif
+      69             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.cpp.func-sort-c.html b/coverage/gridtools/ActionWithIntegral.cpp.func-sort-c.html new file mode 100644 index 000000000000..b025d9d0fc85 --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithIntegral.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithIntegral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegralC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ActionWithIntegralC2ERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools18ActionWithIntegral16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD9gridtools18ActionWithIntegral17turnOnDerivativesEv8
_ZN4PLMD9gridtools18ActionWithIntegral5applyEv20
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.cpp.func.html b/coverage/gridtools/ActionWithIntegral.cpp.func.html new file mode 100644 index 000000000000..0eee91a33f9c --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithIntegral.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithIntegral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegral16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD9gridtools18ActionWithIntegral17turnOnDerivativesEv8
_ZN4PLMD9gridtools18ActionWithIntegral5applyEv20
_ZN4PLMD9gridtools18ActionWithIntegralC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ActionWithIntegralC2ERKNS_13ActionOptionsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.cpp.gcov.html b/coverage/gridtools/ActionWithIntegral.cpp.gcov.html new file mode 100644 index 000000000000..85149ddead05 --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithIntegral.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithIntegral.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithIntegral.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace gridtools {
+      26             : 
+      27           6 : void ActionWithIntegral::registerKeywords( Keywords& keys ) {
+      28           6 :   ActionWithInputGrid::registerKeywords( keys );
+      29          12 :   keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      30          18 :   keys.remove("CLEAR"); keys.add("compulsory","CLEAR","1","the frequency with which to clear all the accumulated data.");
+      31           6 : }
+      32             : 
+      33           4 : ActionWithIntegral::ActionWithIntegral(const ActionOptions&ao):
+      34             :   Action(ao),
+      35           4 :   ActionWithInputGrid(ao)
+      36             : {
+      37           4 :   plumed_assert( ingrid->getNumberOfComponents()==1 );
+      38             :   // Retrieve the volume of the grid (for integration)
+      39           4 :   volume = ingrid->getCellVolume();
+      40             :   // Create something that is going to calculate the sum of all the values
+      41             :   // at the various grid points - this is going to be the integral
+      42           8 :   std::string fake_input; addVessel( "SUM", fake_input, -1 ); readVesselKeywords();
+      43             :   // Now create task list - number of tasks is equal to the number of grid points
+      44             :   // as we have to evaluate the function at each grid points
+      45        1145 :   for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) addTaskToList(i);
+      46             :   // And activate all tasks
+      47           4 :   deactivateAllTasks();
+      48        1145 :   for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) taskFlags[i]=1;
+      49           4 :   lockContributors();
+      50           4 : }
+      51             : 
+      52           8 : void ActionWithIntegral::turnOnDerivatives() {
+      53           8 :   ActionWithGrid::turnOnDerivatives();
+      54           8 :   forcesToApply.resize( ingrid->getNumberOfPoints() );
+      55           8 : }
+      56             : 
+      57          20 : void ActionWithIntegral::apply() {
+      58          20 :   if( getForcesFromVessels( forcesToApply ) ) ingrid->setForce( forcesToApply );
+      59          20 : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.h.func-sort-c.html b/coverage/gridtools/ActionWithIntegral.h.func-sort-c.html new file mode 100644 index 000000000000..e45b3c95860e --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithIntegral.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithIntegral.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3475.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegral10isPeriodicEv0
_ZN4PLMD9gridtools18ActionWithIntegral22getNumberOfDerivativesEv102
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.h.func.html b/coverage/gridtools/ActionWithIntegral.h.func.html new file mode 100644 index 000000000000..697fddeef9b4 --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithIntegral.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithIntegral.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3475.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ActionWithIntegral10isPeriodicEv0
_ZN4PLMD9gridtools18ActionWithIntegral22getNumberOfDerivativesEv102
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ActionWithIntegral.h.gcov.html b/coverage/gridtools/ActionWithIntegral.h.gcov.html new file mode 100644 index 000000000000..7225d74049a6 --- /dev/null +++ b/coverage/gridtools/ActionWithIntegral.h.gcov.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ActionWithIntegral.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ActionWithIntegral.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3475.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_gridtools_ActionWithIntegral_h
+      23             : #define __PLUMED_gridtools_ActionWithIntegral_h
+      24             : 
+      25             : #include "ActionWithInputGrid.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace gridtools {
+      29             : 
+      30             : class ActionWithIntegral : public ActionWithInputGrid {
+      31             : private:
+      32             :   double volume;
+      33             :   std::vector<double> forcesToApply;
+      34             : protected:
+      35             : /// Get the volume of a grid box
+      36             :   double getVolume() const ;
+      37             : public:
+      38             :   static void registerKeywords( Keywords& keys );
+      39             :   explicit ActionWithIntegral(const ActionOptions&ao);
+      40             :   unsigned getNumberOfDerivatives() override;
+      41             :   void turnOnDerivatives() override;
+      42             : /// Unless I am mistaken an integral should never be a periodic function
+      43           0 :   bool isPeriodic() override { return false; }
+      44             :   void apply() override;
+      45             : };
+      46             : 
+      47             : inline
+      48             : double ActionWithIntegral::getVolume() const {
+      49       11410 :   return volume;
+      50             : }
+      51             : 
+      52             : inline
+      53         102 : unsigned ActionWithIntegral::getNumberOfDerivatives() {
+      54         102 :   return ingrid->getNumberOfPoints();
+      55             : }
+      56             : 
+      57             : }
+      58             : }
+      59             : #endif
+      60             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.cpp.func-sort-c.html b/coverage/gridtools/AverageOnGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..d7b3d7079b32 --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/AverageOnGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - AverageOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:252696.2 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13AverageOnGridC2ERKNS_10vesselbase13VesselOptionsE8
_ZN4PLMD9gridtools13AverageOnGrid16registerKeywordsERNS_8KeywordsE65
_ZNK4PLMD9gridtools13AverageOnGrid14getGridElementERKjS3_361798
_ZNK4PLMD9gridtools13AverageOnGrid10accumulateERKjRKdS5_RKSt6vectorIdSaIdEERS8_11825111
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.cpp.func.html b/coverage/gridtools/AverageOnGrid.cpp.func.html new file mode 100644 index 000000000000..417b7d908910 --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/AverageOnGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - AverageOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:252696.2 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13AverageOnGrid16registerKeywordsERNS_8KeywordsE65
_ZN4PLMD9gridtools13AverageOnGridC2ERKNS_10vesselbase13VesselOptionsE8
_ZNK4PLMD9gridtools13AverageOnGrid10accumulateERKjRKdS5_RKSt6vectorIdSaIdEERS8_11825111
_ZNK4PLMD9gridtools13AverageOnGrid14getGridElementERKjS3_361798
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.cpp.gcov.html b/coverage/gridtools/AverageOnGrid.cpp.gcov.html new file mode 100644 index 000000000000..70ceeea66d6d --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.cpp.gcov.html @@ -0,0 +1,146 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/AverageOnGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - AverageOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:252696.2 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AverageOnGrid.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace gridtools {
+      26             : 
+      27          65 : void AverageOnGrid::registerKeywords( Keywords& keys ) {
+      28          65 :   HistogramOnGrid::registerKeywords( keys );
+      29          65 : }
+      30             : 
+      31           8 : AverageOnGrid::AverageOnGrid( const vesselbase::VesselOptions& da ):
+      32           8 :   HistogramOnGrid(da)
+      33             : {
+      34           8 :   arg_names.push_back( "density" );
+      35           8 :   if( !discrete ) {
+      36          22 :     for(unsigned i=0; i<dimension; ++i) arg_names.push_back( "ddensity_" + arg_names[i] );
+      37           8 :     nper += (dimension+1);
+      38             :   } else {
+      39           0 :     nper += 1;
+      40             :   }
+      41           8 : }
+      42             : 
+      43    11825111 : void AverageOnGrid::accumulate( const unsigned& ipoint, const double& weight, const double& dens, const std::vector<double>& der, std::vector<double>& buffer ) const {
+      44    11825111 :   buffer[bufstart+nper*ipoint] += weight*dens; buffer[ bufstart+nper*(ipoint+1) - (dimension+1) ] += dens;
+      45    11825111 :   if( der.size()>0 ) {
+      46    47300036 :     for(unsigned j=0; j<dimension; ++j) buffer[ bufstart+nper*ipoint + 1 + j ] += weight*der[j];
+      47    47300036 :     for(unsigned j=0; j<dimension; ++j) buffer[ bufstart+nper*(ipoint+1) - dimension + j ] += der[j];
+      48             :   }
+      49    11825111 : }
+      50             : 
+      51      361798 : double AverageOnGrid::getGridElement( const unsigned& ipoint, const unsigned& jelement ) const {
+      52      361798 :   if( noAverage() ) return getDataElement( nper*ipoint + jelement);
+      53             : 
+      54      360598 :   if( jelement>=(nper-(dimension+1)) ) return getDataElement( nper*ipoint + jelement );
+      55             : 
+      56      360098 :   if( noderiv ) return getDataElement( nper*ipoint+jelement ) / getDataElement( nper*(1+ipoint) - 1);
+      57             : 
+      58             :   double rdenom = 1.0;
+      59      360098 :   if( std::fabs(getDataElement( nper*(ipoint+1) -(dimension+1) ))>epsilon ) rdenom = 1. / getDataElement( nper*(ipoint+1) - (dimension+1) );
+      60             : 
+      61      360098 :   unsigned jderiv = jelement%(1+dimension);
+      62      360098 :   if( jderiv==0 ) return rdenom*getDataElement( nper*ipoint+jelement );
+      63             : 
+      64      203154 :   unsigned jfloor = std::floor( jelement / (1+dimension) );
+      65      203154 :   return rdenom*getDataElement( nper*ipoint+jelement ) - rdenom*rdenom*getDataElement(nper*ipoint+jfloor)*getDataElement(nper*(ipoint+1) - (dimension+1) + jderiv);
+      66             : }
+      67             : 
+      68             : }
+      69             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.h.func-sort-c.html b/coverage/gridtools/AverageOnGrid.h.func-sort-c.html new file mode 100644 index 000000000000..d41092b254a3 --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/AverageOnGrid.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - AverageOnGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3560.0 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13AverageOnGrid14getFinalForcesERKSt6vectorIdSaIdEERS4_0
_ZNK4PLMD9gridtools13AverageOnGrid15accumulateForceERKjRKdRKSt6vectorIdSaIdEERS8_0
_ZNK4PLMD9gridtools13AverageOnGrid21getNumberOfComponentsEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.h.func.html b/coverage/gridtools/AverageOnGrid.h.func.html new file mode 100644 index 000000000000..7910bb0cb7b3 --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/AverageOnGrid.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - AverageOnGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3560.0 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13AverageOnGrid14getFinalForcesERKSt6vectorIdSaIdEERS4_0
_ZNK4PLMD9gridtools13AverageOnGrid15accumulateForceERKjRKdRKSt6vectorIdSaIdEERS8_0
_ZNK4PLMD9gridtools13AverageOnGrid21getNumberOfComponentsEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/AverageOnGrid.h.gcov.html b/coverage/gridtools/AverageOnGrid.h.gcov.html new file mode 100644 index 000000000000..37e1717662f4 --- /dev/null +++ b/coverage/gridtools/AverageOnGrid.h.gcov.html @@ -0,0 +1,126 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/AverageOnGrid.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - AverageOnGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3560.0 %
Date:2024-02-22 21:58:45Functions:1333.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_gridtools_AverageOnGrid_h
+      23             : #define __PLUMED_gridtools_AverageOnGrid_h
+      24             : 
+      25             : #include "HistogramOnGrid.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace gridtools {
+      29             : 
+      30             : class AverageOnGrid : public HistogramOnGrid {
+      31             : public:
+      32             :   static void registerKeywords( Keywords& keys );
+      33             :   explicit AverageOnGrid( const vesselbase::VesselOptions& da );
+      34             :   void accumulate( const unsigned& ipoint, const double& weight, const double& dens, const std::vector<double>& der, std::vector<double>& buffer ) const override;
+      35           0 :   void accumulateForce( const unsigned& ipoint, const double& weight, const std::vector<double>& der, std::vector<double>& intforce ) const override { plumed_error(); }
+      36             :   double getGridElement( const unsigned& ipoint, const unsigned& jelement ) const override;
+      37             :   unsigned getNumberOfComponents() const override;
+      38           0 :   void getFinalForces( const std::vector<double>& buffer, std::vector<double>& finalForces ) override { plumed_error(); }
+      39             : };
+      40             : 
+      41             : inline
+      42           7 : unsigned AverageOnGrid::getNumberOfComponents() const {
+      43           7 :   if( noderiv ) return nper - 1;
+      44           7 :   return nper / ( dimension + 1 ) - 1;
+      45             : }
+      46             : 
+      47             : }
+      48             : }
+      49             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.cpp.func-sort-c.html b/coverage/gridtools/ContourFindingBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..ebaf2d242007 --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ContourFindingBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ContourFindingBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ContourFindingBaseC2ERKNS_13ActionOptionsE3
_ZN4PLMD9gridtools18ContourFindingBase16registerKeywordsERNS_8KeywordsE9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.cpp.func.html b/coverage/gridtools/ContourFindingBase.cpp.func.html new file mode 100644 index 000000000000..40a10479017b --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ContourFindingBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ContourFindingBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBase16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD9gridtools18ContourFindingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools18ContourFindingBaseC2ERKNS_13ActionOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.cpp.gcov.html b/coverage/gridtools/ContourFindingBase.cpp.gcov.html new file mode 100644 index 000000000000..aa7ce460d21e --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.cpp.gcov.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ContourFindingBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ContourFindingBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1111100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ContourFindingBase.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace gridtools {
+      26             : 
+      27           9 : void ContourFindingBase::registerKeywords( Keywords& keys ) {
+      28           9 :   ActionWithInputGrid::registerKeywords( keys );
+      29          18 :   keys.add("compulsory","CONTOUR","the value we would like to draw the contour at in the space");
+      30          18 :   keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      31           9 : }
+      32             : 
+      33           3 : ContourFindingBase::ContourFindingBase(const ActionOptions&ao):
+      34             :   Action(ao),
+      35             :   ActionWithInputGrid(ao),
+      36           3 :   mymin(this)
+      37             : {
+      38           3 :   if( ingrid->noDerivatives() ) error("cannot find contours if input grid has no derivatives");
+      39           3 :   parse("CONTOUR",contour);
+      40           3 :   log.printf("  calculating dividing surface along which function equals %f \n", contour);
+      41           3 : }
+      42             : 
+      43             : }
+      44             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.h.func-sort-c.html b/coverage/gridtools/ContourFindingBase.h.func-sort-c.html new file mode 100644 index 000000000000..5cb4ef8f528d --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ContourFindingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ContourFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBase10isPeriodicEv0
_ZN4PLMD9gridtools18ContourFindingBase22getNumberOfDerivativesEv32
_ZNK4PLMD9gridtools18ContourFindingBase24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_8246
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.h.func.html b/coverage/gridtools/ContourFindingBase.h.func.html new file mode 100644 index 000000000000..e33b427a95f1 --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ContourFindingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ContourFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18ContourFindingBase10isPeriodicEv0
_ZN4PLMD9gridtools18ContourFindingBase22getNumberOfDerivativesEv32
_ZNK4PLMD9gridtools18ContourFindingBase24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_8246
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ContourFindingBase.h.gcov.html b/coverage/gridtools/ContourFindingBase.h.gcov.html new file mode 100644 index 000000000000..4ad5e3f5cf76 --- /dev/null +++ b/coverage/gridtools/ContourFindingBase.h.gcov.html @@ -0,0 +1,140 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ContourFindingBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ContourFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_gridtools_ContourFindingBase_h
+      23             : #define __PLUMED_gridtools_ContourFindingBase_h
+      24             : 
+      25             : #include "ActionWithInputGrid.h"
+      26             : #include "tools/RootFindingBase.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace gridtools {
+      30             : 
+      31             : class ContourFindingBase : public ActionWithInputGrid {
+      32             : private:
+      33             : /// This is the object that does the root finding
+      34             :   RootFindingBase<ContourFindingBase> mymin;
+      35             : protected:
+      36             : /// Where you would like to find the contour
+      37             :   double contour;
+      38             : /// Find a contour along line specified by direction
+      39             :   void findContour( const std::vector<double>& direction, std::vector<double>& point ) const ;
+      40             : public:
+      41             :   static void registerKeywords( Keywords& keys );
+      42             :   explicit ContourFindingBase(const ActionOptions&ao);
+      43             : /// Get the contour value
+      44             :   double getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) const ;
+      45             : /// Overwrite not needed stuff
+      46          32 :   unsigned getNumberOfDerivatives() override { return 0; }
+      47             : /// This is not periodic
+      48           0 :   bool isPeriodic() override { return false; }
+      49             : };
+      50             : 
+      51             : inline
+      52             : void ContourFindingBase::findContour( const std::vector<double>& direction, std::vector<double>& point ) const {
+      53        1242 :   mymin.linesearch( direction, point, &ContourFindingBase::getDifferenceFromContour );
+      54        1242 : }
+      55             : 
+      56             : inline
+      57        8246 : double ContourFindingBase::getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) const {
+      58        8346 :   return getFunctionValueAndDerivatives( x, der ) - contour;
+      59             : }
+      60             : 
+      61             : }
+      62             : }
+      63             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ConvertToFES.cpp.func-sort-c.html b/coverage/gridtools/ConvertToFES.cpp.func-sort-c.html new file mode 100644 index 000000000000..f0b43161970f --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ConvertToFES.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ConvertToFES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444597.8 %
Date:2024-02-22 21:58:45Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12ConvertToFES10isPeriodicEv0
_ZN4PLMD9gridtools12ConvertToFESC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools12ConvertToFES7prepareEv12
_ZN4PLMD9gridtools12ConvertToFES12runFinalJobsEv15
_ZN4PLMD9gridtools12ConvertToFESC1ERKNS_13ActionOptionsE15
_ZNK4PLMD9gridtools12ConvertToFES19ignoreNormalizationEv15
_ZN4PLMD9gridtools12ConvertToFES16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD9gridtools12ConvertToFES18finishComputationsERKSt6vectorIdSaIdEE23
_ZN4PLMD9gridtools12ConvertToFES19prepareForAveragingEv23
_ZNK4PLMD9gridtools12ConvertToFES21getNumberOfQuantitiesEv92
_ZNK4PLMD9gridtools12ConvertToFES6onStepEv2234
_ZNK4PLMD9gridtools12ConvertToFES7computeERKjRNS_10MultiValueE14199
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ConvertToFES.cpp.func.html b/coverage/gridtools/ConvertToFES.cpp.func.html new file mode 100644 index 000000000000..3600d56ba363 --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ConvertToFES.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ConvertToFES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444597.8 %
Date:2024-02-22 21:58:45Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools12ConvertToFES10isPeriodicEv0
_ZN4PLMD9gridtools12ConvertToFES12runFinalJobsEv15
_ZN4PLMD9gridtools12ConvertToFES16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD9gridtools12ConvertToFES18finishComputationsERKSt6vectorIdSaIdEE23
_ZN4PLMD9gridtools12ConvertToFES19prepareForAveragingEv23
_ZN4PLMD9gridtools12ConvertToFES7prepareEv12
_ZN4PLMD9gridtools12ConvertToFESC1ERKNS_13ActionOptionsE15
_ZN4PLMD9gridtools12ConvertToFESC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools12ConvertToFES19ignoreNormalizationEv15
_ZNK4PLMD9gridtools12ConvertToFES21getNumberOfQuantitiesEv92
_ZNK4PLMD9gridtools12ConvertToFES6onStepEv2234
_ZNK4PLMD9gridtools12ConvertToFES7computeERKjRNS_10MultiValueE14199
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/ConvertToFES.cpp.gcov.html b/coverage/gridtools/ConvertToFES.cpp.gcov.html new file mode 100644 index 000000000000..3a267b92e891 --- /dev/null +++ b/coverage/gridtools/ConvertToFES.cpp.gcov.html @@ -0,0 +1,220 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/ConvertToFES.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - ConvertToFES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444597.8 %
Date:2024-02-22 21:58:45Functions:101283.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "ActionWithInputGrid.h"
+      24             : 
+      25             : //+PLUMEDOC GRIDANALYSIS CONVERT_TO_FES
+      26             : /*
+      27             : Convert a histogram, H(x), to a free energy surface using F(x) = -k_B T ln H(x).
+      28             : 
+      29             : This action allows you to take a free energy surface that was calculated using the \ref HISTOGRAM
+      30             : action and to convert it to a free energy surface.  This transformation performed by doing:
+      31             : 
+      32             : \f[
+      33             : F(x) = -k_B T \ln H(x)
+      34             : \f]
+      35             : 
+      36             : The free energy calculated on a grid is output by this action and can be printed using \ref DUMPGRID
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : This is a typical example showing how CONVERT_TO_FES might be used when post processing a trajectory.
+      41             : The input below calculates the free energy as a function of the distance between atom 1 and atom 2.
+      42             : This is done by accumulating a histogram as a function of this distance using kernel density estimation
+      43             : and the HISTOGRAM action.  All the data within this trajectory is used in the construction of this
+      44             : HISTOGRAM.  Finally, once all the data has been read in, the histogram is converted to a free energy
+      45             : using the formula above and the free energy is output to a file called fes.dat
+      46             : 
+      47             : \plumedfile
+      48             : x: DISTANCE ATOMS=1,2
+      49             : hA1: HISTOGRAM ARG=x GRID_MIN=0.0 GRID_MAX=3.0 GRID_BIN=100 BANDWIDTH=0.1
+      50             : ff: CONVERT_TO_FES GRID=hA1 TEMP=300
+      51             : DUMPGRID GRID=ff FILE=fes.dat
+      52             : \endplumedfile
+      53             : 
+      54             : */
+      55             : //+ENDPLUMEDOC
+      56             : 
+      57             : namespace PLMD {
+      58             : namespace gridtools {
+      59             : 
+      60             : class ConvertToFES : public ActionWithInputGrid {
+      61             : private:
+      62             :   double simtemp;
+      63             :   bool activated;
+      64             :   bool mintozero;
+      65             : public:
+      66             :   static void registerKeywords( Keywords& keys );
+      67             :   explicit ConvertToFES(const ActionOptions&ao);
+      68             :   unsigned getNumberOfQuantities() const override;
+      69          15 :   bool ignoreNormalization() const override { return true; }
+      70          12 :   void prepare() override { activated=true; }
+      71          23 :   void prepareForAveraging() override { ActionWithInputGrid::prepareForAveraging(); activated=false; }
+      72             :   void compute( const unsigned& current, MultiValue& myvals ) const override;
+      73             :   void finishComputations( const std::vector<double>& buffer ) override;
+      74           0 :   bool isPeriodic() override { return false; }
+      75        2234 :   bool onStep() const override { return activated; }
+      76             :   void runFinalJobs() override;
+      77             : };
+      78             : 
+      79             : PLUMED_REGISTER_ACTION(ConvertToFES,"CONVERT_TO_FES")
+      80             : 
+      81          17 : void ConvertToFES::registerKeywords( Keywords& keys ) {
+      82          17 :   ActionWithInputGrid::registerKeywords( keys );
+      83          34 :   keys.add("optional","TEMP","the temperature at which you are operating");
+      84          34 :   keys.addFlag("MINTOZERO",false,"set the minimum in the free energy to be equal to zero");
+      85          51 :   keys.remove("STRIDE"); keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      86          51 :   keys.remove("LOGWEIGHTS"); keys.remove("CLEAR"); keys.remove("NORMALIZATION");
+      87          17 : }
+      88             : 
+      89          15 : ConvertToFES::ConvertToFES(const ActionOptions&ao):
+      90             :   Action(ao),
+      91             :   ActionWithInputGrid(ao),
+      92          15 :   activated(false)
+      93             : {
+      94          15 :   plumed_assert( ingrid->getNumberOfComponents()==1 );
+      95             : 
+      96             :   // Create a grid
+      97          30 :   auto grid=createGrid( "grid", "COMPONENTS=" + getLabel() + " " + ingrid->getInputString() );
+      98          15 :   if( ingrid->noDerivatives() ) grid->setNoDerivatives();
+      99             :   std::vector<double> fspacing;
+     100          15 :   grid->setBounds( ingrid->getMin(), ingrid->getMax(), ingrid->getNbin(), fspacing);
+     101          15 :   setAveragingAction( std::move(grid), true );
+     102             : 
+     103          15 :   simtemp=getkBT(); parseFlag("MINTOZERO",mintozero);
+     104          15 :   if( simtemp==0 ) error("TEMP not set - use keyword TEMP");
+     105             : 
+     106             :   // Now create task list
+     107        8486 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) addTaskToList(i);
+     108             :   // And activate all tasks
+     109          15 :   deactivateAllTasks();
+     110        8486 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) taskFlags[i]=1;
+     111          15 :   lockContributors();
+     112          15 : }
+     113             : 
+     114          92 : unsigned ConvertToFES::getNumberOfQuantities() const {
+     115          92 :   if( mygrid->noDerivatives() ) return 2;
+     116          64 :   return 2 + mygrid->getDimension();
+     117             : }
+     118             : 
+     119       14199 : void ConvertToFES::compute( const unsigned& current, MultiValue& myvals ) const {
+     120       14199 :   double val=getFunctionValue( current ); myvals.setValue(1, -simtemp*std::log(val) );
+     121       14199 :   if( !mygrid->noDerivatives() && val>0 ) {
+     122       36998 :     for(unsigned i=0; i<mygrid->getDimension(); ++i) myvals.setValue( 2+i, -(simtemp/val)*ingrid->getGridElement(current,i+1) );
+     123             :   }
+     124       14199 : }
+     125             : 
+     126          23 : void ConvertToFES::finishComputations( const std::vector<double>& buffer ) {
+     127          23 :   ActionWithVessel::finishComputations( buffer );
+     128          23 :   if(!mintozero) return;
+     129             : 
+     130           2 :   double optval = mygrid->getGridElement( 0, 0 );
+     131        2602 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) {
+     132        2600 :     double tval = mygrid->getGridElement( i, 0 );
+     133        2600 :     if( tval<optval || std::isnan(optval) ) { optval=tval; }
+     134             :   }
+     135        2602 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) mygrid->addToGridElement( i, 0, -optval );
+     136             : }
+     137             : 
+     138          15 : void ConvertToFES::runFinalJobs() {
+     139          15 :   activated=true; update();
+     140          15 : }
+     141             : 
+     142             : }
+     143             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpCube.cpp.func-sort-c.html b/coverage/gridtools/DumpCube.cpp.func-sort-c.html new file mode 100644 index 000000000000..de6c6b81c9f7 --- /dev/null +++ b/coverage/gridtools/DumpCube.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/DumpCube.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - DumpCube.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313588.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8DumpCubeC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools8DumpCubeC1ERKNS_13ActionOptionsE6
_ZN4PLMD9gridtools8DumpCube16registerKeywordsERNS_8KeywordsE8
_ZNK4PLMD9gridtools8DumpCube9printGridERNS_5OFileE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpCube.cpp.func.html b/coverage/gridtools/DumpCube.cpp.func.html new file mode 100644 index 000000000000..672796190ef6 --- /dev/null +++ b/coverage/gridtools/DumpCube.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/DumpCube.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - DumpCube.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313588.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8DumpCube16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD9gridtools8DumpCubeC1ERKNS_13ActionOptionsE6
_ZN4PLMD9gridtools8DumpCubeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools8DumpCube9printGridERNS_5OFileE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpCube.cpp.gcov.html b/coverage/gridtools/DumpCube.cpp.gcov.html new file mode 100644 index 000000000000..59d40d476af0 --- /dev/null +++ b/coverage/gridtools/DumpCube.cpp.gcov.html @@ -0,0 +1,202 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/DumpCube.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - DumpCube.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313588.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "GridPrintingBase.h"
+      24             : #include "tools/OFile.h"
+      25             : 
+      26             : //+PLUMEDOC GRIDANALYSIS DUMPCUBE
+      27             : /*
+      28             : Output a three dimensional grid using the Gaussian cube file format.
+      29             : 
+      30             : Suppose you have calculated the value of a function on a three dimensional grid.
+      31             : This function might be a \ref HISTOGRAM or it might be a free energy energy surface
+      32             : that was calculated from this histogram by using \ref CONVERT_TO_FES.  Alternatively,
+      33             : your function might be a phase-field that was calculated using \ref MULTICOLVARDENS.
+      34             : Whatever the function is, however, you obviously cannot show it using a typical contour
+      35             : plotting program such as gnuplot as you have three input variables.
+      36             : 
+      37             : Tools like VMD have nice features for plotting these types of three dimensional functions
+      38             : but typically you are required to use a Gaussian cube file format to input the data.  This
+      39             : action thus allows you to output a function evaluated on a grid to a Gaussian cube file format.
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : The input below can be used to post process a trajectory.  A histogram as a function of the distance
+      44             : between atoms 1 and 2, the distance between atom 1 and 3 and the angle between the vector connecting atoms 1 and
+      45             : 2 and 1 and 3 is computed using kernel density estimation.  Once all the data contained in the trajectory has been read in and
+      46             : all the kernels have been added the resulting histogram is output to a file called histoA1.cube.  This file has the
+      47             : Gaussian cube file format.  The histogram can thus be visualized using tools such as VMD.
+      48             : 
+      49             : \plumedfile
+      50             : x1: DISTANCE ATOMS=1,2
+      51             : x2: DISTANCE ATOMS=1,3
+      52             : x3: ANGLE ATOMS=1,2,3
+      53             : 
+      54             : hA1: HISTOGRAM ARG=x1,x2,x3 GRID_MIN=0.0,0.0,0.0 GRID_MAX=3.0,3.0,3.0 GRID_BIN=10,10,10 BANDWIDTH=1.0,1.0,1.0
+      55             : DUMPCUBE GRID=hA1 FILE=histoA1.cube
+      56             : \endplumedfile
+      57             : 
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : namespace PLMD {
+      62             : namespace gridtools {
+      63             : 
+      64             : class DumpCube : public GridPrintingBase {
+      65             : private:
+      66             :   unsigned mycomp;
+      67             : public:
+      68             :   static void registerKeywords( Keywords& keys );
+      69             :   explicit DumpCube(const ActionOptions&ao);
+      70             :   void printGrid( OFile& ofile ) const override;
+      71             : };
+      72             : 
+      73             : PLUMED_REGISTER_ACTION(DumpCube,"DUMPCUBE")
+      74             : 
+      75           8 : void DumpCube::registerKeywords( Keywords& keys ) {
+      76           8 :   GridPrintingBase::registerKeywords( keys );
+      77          16 :   keys.add("optional","COMPONENT","if your input is a vector field use this to specify the component of the input vector field for which you wish to output");
+      78           8 : }
+      79             : 
+      80           6 : DumpCube::DumpCube(const ActionOptions&ao):
+      81             :   Action(ao),
+      82           6 :   GridPrintingBase(ao)
+      83             : {
+      84           6 :   fmt = fmt + " ";
+      85          12 :   if( ingrid->getType()!="flat" ) error("cannot dump grid of type " + ingrid->getType() + " using DUMPCUBE");
+      86           6 :   if( ingrid->getDimension()!=3 ) error("cannot print cube file if grid does not contain three dimensional data");
+      87             : 
+      88           6 :   if( ingrid->getNumberOfComponents()==1 ) {
+      89           6 :     mycomp=0;
+      90             :   } else {
+      91           0 :     int tcomp=-1; parse("COMPONENT",tcomp);
+      92           0 :     if( tcomp<0 ) error("component of vector field was not specified - use COMPONENT keyword");
+      93           0 :     mycomp=tcomp*(1+ingrid->getDimension()); if( ingrid->noDerivatives() ) mycomp=tcomp;
+      94           0 :     log.printf("  using %dth component of grid \n",tcomp );
+      95             :   }
+      96             : 
+      97           6 :   checkRead();
+      98           6 : }
+      99             : 
+     100           8 : void DumpCube::printGrid( OFile& ofile ) const {
+     101           8 :   double lunit = ingrid->getCubeUnits();
+     102             : 
+     103           8 :   ofile.printf("PLUMED CUBE FILE\n");
+     104           8 :   ofile.printf("OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n");
+     105             :   // Number of atoms followed by position of origin (origin set so that center of grid is in center of cell)
+     106          16 :   std::string ostr = "%d " + fmt + fmt + fmt + "\n";
+     107           8 :   ofile.printf(ostr.c_str(),1,-0.5*lunit*ingrid->getGridExtent(0),-0.5*lunit*ingrid->getGridExtent(1),-0.5*lunit*ingrid->getGridExtent(2));
+     108           8 :   ofile.printf(ostr.c_str(),ingrid->getNbin()[0],lunit*ingrid->getGridSpacing()[0],0.0,0.0);  // Number of bins in each direction followed by
+     109           8 :   ofile.printf(ostr.c_str(),ingrid->getNbin()[1],0.0,lunit*ingrid->getGridSpacing()[1],0.0);  // shape of voxel
+     110          16 :   ofile.printf(ostr.c_str(),ingrid->getNbin()[2],0.0,0.0,lunit*ingrid->getGridSpacing()[2]);
+     111           8 :   ofile.printf(ostr.c_str(),1,0.0,0.0,0.0); // Fake atom otherwise VMD doesn't work
+     112           8 :   std::vector<unsigned> pp(3); std::vector<unsigned> nbin( ingrid->getNbin() );
+     113         112 :   for(pp[0]=0; pp[0]<nbin[0]; ++pp[0]) {
+     114        1800 :     for(pp[1]=0; pp[1]<nbin[1]; ++pp[1]) {
+     115       40184 :       for(pp[2]=0; pp[2]<nbin[2]; ++pp[2]) {
+     116       38488 :         ofile.printf(fmt.c_str(), ingrid->getGridElement( ingrid->getIndex(pp), mycomp ) );
+     117       38488 :         if(pp[2]%6==5) ofile.printf("\n");
+     118             :       }
+     119        1696 :       ofile.printf("\n");
+     120             :     }
+     121             :   }
+     122           8 : }
+     123             : 
+     124             : }
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpGrid.cpp.func-sort-c.html b/coverage/gridtools/DumpGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..085d34caad89 --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/DumpGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - DumpGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8DumpGridC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools8DumpGridC1ERKNS_13ActionOptionsE49
_ZN4PLMD9gridtools8DumpGrid16registerKeywordsERNS_8KeywordsE51
_ZNK4PLMD9gridtools8DumpGrid9printGridERNS_5OFileE60
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpGrid.cpp.func.html b/coverage/gridtools/DumpGrid.cpp.func.html new file mode 100644 index 000000000000..e8ef995f799d --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/DumpGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - DumpGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools8DumpGrid16registerKeywordsERNS_8KeywordsE51
_ZN4PLMD9gridtools8DumpGridC1ERKNS_13ActionOptionsE49
_ZN4PLMD9gridtools8DumpGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools8DumpGrid9printGridERNS_5OFileE60
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/DumpGrid.cpp.gcov.html b/coverage/gridtools/DumpGrid.cpp.gcov.html new file mode 100644 index 000000000000..3cd2f4cf1033 --- /dev/null +++ b/coverage/gridtools/DumpGrid.cpp.gcov.html @@ -0,0 +1,273 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/DumpGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - DumpGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "GridPrintingBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/OFile.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace gridtools {
+      28             : 
+      29             : //+PLUMEDOC GRIDANALYSIS DUMPGRID
+      30             : /*
+      31             : Output the function on the grid to a file with the PLUMED grid format.
+      32             : 
+      33             : PLUMED provides a number of actions that calculate the values of functions on grids.
+      34             : For instance, whenever you calculate a free energy as a function of a collective variable using
+      35             : \ref HISTOGRAM and \ref CONVERT_TO_FES you will generally want to output the value of the free energy at a number of points on a
+      36             : discrete grid that covers the CV space uniformly.  Alternatively you may want to calculate
+      37             : what value some symmetry function takes at different points inside your simulation cell using \ref MULTICOLVARDENS.
+      38             : 
+      39             : This action allows you to output these functions calculated on a grid using a format that can be read in using gnuplot
+      40             : and other such plotting programs.  The file output using this action will have a header that contains some essential
+      41             : information about the function plotted and that looks something like this:
+      42             : 
+      43             : \verbatim
+      44             : #! FIELDS x y hA1 dhA1_x dhA1_x
+      45             : #! SET normalisation    2.0000
+      46             : #! SET min_x 0.0
+      47             : #! SET max_x 3.0
+      48             : #! SET nbins_x  100
+      49             : #! SET periodic_x false
+      50             : #! SET min_y 0.0
+      51             : #! SET max_y 3.0
+      52             : #! SET nbins_y  100
+      53             : #! SET periodic_y false
+      54             : \endverbatim
+      55             : 
+      56             : The header shown here tells us that we have grid showing the values that a function with two arguments x and y
+      57             : takes at various points in our cell.  The lines beneath the first line then tell us a little bit about these two
+      58             : input arguments.
+      59             : 
+      60             : The remaining lines of the file give us information on the positions of our grid points and the value the function and
+      61             : its partial derivatives with respect to x and y.  If the header is as above a list of values of the function that have
+      62             : x=0 and 100 values of y between 0.0 and 3.0 will be provided.  This block of data will be followed with a blank line.
+      63             : There will then be a second block of values which will all have been evaluated the same value of x and all possible values
+      64             : for y.  This block is then followed by a blank line again and this pattern continues until all points of the grid have been covered.
+      65             : 
+      66             : \par Examples
+      67             : 
+      68             : The following input monitors two torsional angles during a simulation
+      69             : and outputs a continuous histogram as a function of them at the end of the simulation.
+      70             : \plumedfile
+      71             : TORSION ATOMS=1,2,3,4 LABEL=r1
+      72             : TORSION ATOMS=2,3,4,5 LABEL=r2
+      73             : HISTOGRAM ...
+      74             :   ARG=r1,r2
+      75             :   GRID_MIN=-3.14,-3.14
+      76             :   GRID_MAX=3.14,3.14
+      77             :   GRID_BIN=200,200
+      78             :   BANDWIDTH=0.05,0.05
+      79             :   LABEL=hh
+      80             : ... HISTOGRAM
+      81             : 
+      82             : DUMPGRID GRID=hh FILE=histo
+      83             : \endplumedfile
+      84             : 
+      85             : The following input monitors two torsional angles during a simulation
+      86             : and outputs a discrete histogram as a function of them at the end of the simulation.
+      87             : \plumedfile
+      88             : TORSION ATOMS=1,2,3,4 LABEL=r1
+      89             : TORSION ATOMS=2,3,4,5 LABEL=r2
+      90             : HISTOGRAM ...
+      91             :   ARG=r1,r2
+      92             :   KERNEL=DISCRETE
+      93             :   GRID_MIN=-3.14,-3.14
+      94             :   GRID_MAX=3.14,3.14
+      95             :   GRID_BIN=200,200
+      96             :   LABEL=hh
+      97             : ... HISTOGRAM
+      98             : 
+      99             : DUMPGRID GRID=hh FILE=histo
+     100             : \endplumedfile
+     101             : 
+     102             : The following input monitors two torsional angles during a simulation
+     103             : and outputs the histogram accumulated thus far every 100000 steps.
+     104             : \plumedfile
+     105             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     106             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     107             : HISTOGRAM ...
+     108             :   ARG=r1,r2
+     109             :   GRID_MIN=-3.14,-3.14
+     110             :   GRID_MAX=3.14,3.14
+     111             :   GRID_BIN=200,200
+     112             :   BANDWIDTH=0.05,0.05
+     113             :   LABEL=hh
+     114             : ... HISTOGRAM
+     115             : 
+     116             : DUMPGRID GRID=hh FILE=histo STRIDE=100000
+     117             : \endplumedfile
+     118             : 
+     119             : The following input monitors two torsional angles during a simulation
+     120             : and outputs a separate histogram for each 100000 steps worth of trajectory.
+     121             : Notice how the CLEAR keyword is used here and how it is not used in the
+     122             : previous example.
+     123             : 
+     124             : \plumedfile
+     125             : TORSION ATOMS=1,2,3,4 LABEL=r1
+     126             : TORSION ATOMS=2,3,4,5 LABEL=r2
+     127             : HISTOGRAM ...
+     128             :   ARG=r1,r2 CLEAR=100000
+     129             :   GRID_MIN=-3.14,-3.14
+     130             :   GRID_MAX=3.14,3.14
+     131             :   GRID_BIN=200,200
+     132             :   BANDWIDTH=0.05,0.05
+     133             :   LABEL=hh
+     134             : ... HISTOGRAM
+     135             : 
+     136             : DUMPGRID GRID=hh FILE=histo STRIDE=100000
+     137             : \endplumedfile
+     138             : 
+     139             : */
+     140             : //+ENDPLUMEDOC
+     141             : 
+     142             : class DumpGrid : public GridPrintingBase {
+     143             : public:
+     144             :   static void registerKeywords( Keywords& keys );
+     145             :   explicit DumpGrid(const ActionOptions&ao);
+     146             :   void printGrid( OFile& ofile ) const override;
+     147             : };
+     148             : 
+     149             : PLUMED_REGISTER_ACTION(DumpGrid,"DUMPGRID")
+     150             : 
+     151          51 : void DumpGrid::registerKeywords( Keywords& keys ) {
+     152          51 :   GridPrintingBase::registerKeywords( keys );
+     153          51 : }
+     154             : 
+     155          49 : DumpGrid::DumpGrid(const ActionOptions&ao):
+     156             :   Action(ao),
+     157          49 :   GridPrintingBase(ao)
+     158             : {
+     159          98 :   if( ingrid->getType()!="flat" ) error("cannot dump grid of type " + ingrid->getType() + " using DUMPGRID");
+     160          98 :   fmt = " " + fmt; checkRead();
+     161          49 : }
+     162             : 
+     163          60 : void DumpGrid::printGrid( OFile& ofile ) const {
+     164          60 :   ofile.addConstantField("normalisation");
+     165         128 :   for(unsigned i=0; i<ingrid->getDimension(); ++i) {
+     166         136 :     ofile.addConstantField("min_" + ingrid->getComponentName(i) );
+     167         136 :     ofile.addConstantField("max_" + ingrid->getComponentName(i) );
+     168         136 :     ofile.addConstantField("nbins_" + ingrid->getComponentName(i) );
+     169         136 :     ofile.addConstantField("periodic_" + ingrid->getComponentName(i) );
+     170             :   }
+     171             : 
+     172          60 :   std::vector<double> xx( ingrid->getDimension() );
+     173          60 :   std::vector<unsigned> ind( ingrid->getDimension() );
+     174      103636 :   for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) {
+     175      103576 :     ingrid->getIndices( i, ind );
+     176      103576 :     if(i>0 && ingrid->getDimension()==2 && ind[ingrid->getDimension()-2]==0) ofile.printf("\n");
+     177      103576 :     ofile.fmtField(fmt); ofile.printField("normalisation", ingrid->getNorm() );
+     178      306047 :     for(unsigned j=0; j<ingrid->getDimension(); ++j) {
+     179      404942 :       ofile.printField("min_" + ingrid->getComponentName(j), ingrid->getMin()[j] );
+     180      404942 :       ofile.printField("max_" + ingrid->getComponentName(j), ingrid->getMax()[j] );
+     181      404942 :       ofile.printField("nbins_" + ingrid->getComponentName(j), static_cast<int>(ingrid->getNbin()[j]) );
+     182      219655 :       if( ingrid->isPeriodic(j) ) ofile.printField("periodic_" + ingrid->getComponentName(j), "true" );
+     183      370574 :       else          ofile.printField("periodic_" + ingrid->getComponentName(j), "false" );
+     184             :     }
+     185             :     // Retrieve and print the grid coordinates
+     186      103576 :     ingrid->getGridPointCoordinates(i, xx );
+     187      306047 :     for(unsigned j=0; j<ingrid->getDimension(); ++j) { ofile.fmtField(fmt); ofile.printField(ingrid->getComponentName(j),xx[j]); }
+     188      440087 :     for(unsigned j=0; j<ingrid->getNumberOfQuantities(); ++j) {
+     189      336511 :       ofile.fmtField(fmt); ofile.printField(ingrid->arg_names[ingrid->dimension+j], ingrid->getGridElement( i, j ) );
+     190             :     }
+     191      103576 :     ofile.printField();
+     192             :   }
+     193          60 : }
+     194             : 
+     195             : }
+     196             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindContour.cpp.func-sort-c.html b/coverage/gridtools/FindContour.cpp.func-sort-c.html new file mode 100644 index 000000000000..21a90089d917 --- /dev/null +++ b/coverage/gridtools/FindContour.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:748884.1 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools11FindContour10isPeriodicEv0
_ZN4PLMD9gridtools11FindContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools11FindContour14checkAllActiveEv0
_ZN4PLMD9gridtools11FindContour15finishAveragingEv1
_ZN4PLMD9gridtools11FindContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools11FindContour19prepareForAveragingEv2
_ZN4PLMD9gridtools11FindContour16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD9gridtools11FindContour21getNumberOfQuantitiesEv7
_ZNK4PLMD9gridtools11FindContour7computeERKjRNS_10MultiValueE554
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindContour.cpp.func.html b/coverage/gridtools/FindContour.cpp.func.html new file mode 100644 index 000000000000..003d28b1fe73 --- /dev/null +++ b/coverage/gridtools/FindContour.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:748884.1 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools11FindContour10isPeriodicEv0
_ZN4PLMD9gridtools11FindContour15finishAveragingEv1
_ZN4PLMD9gridtools11FindContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools11FindContour19prepareForAveragingEv2
_ZN4PLMD9gridtools11FindContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools11FindContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools11FindContour14checkAllActiveEv0
_ZNK4PLMD9gridtools11FindContour21getNumberOfQuantitiesEv7
_ZNK4PLMD9gridtools11FindContour7computeERKjRNS_10MultiValueE554
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindContour.cpp.gcov.html b/coverage/gridtools/FindContour.cpp.gcov.html new file mode 100644 index 000000000000..492300c59eb9 --- /dev/null +++ b/coverage/gridtools/FindContour.cpp.gcov.html @@ -0,0 +1,322 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindContour.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:748884.1 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "vesselbase/StoreDataVessel.h"
+      24             : #include "ContourFindingBase.h"
+      25             : 
+      26             : //+PLUMEDOC GRIDANALYSIS FIND_CONTOUR
+      27             : /*
+      28             : Find an isocontour in a smooth function.
+      29             : 
+      30             : As discussed in the part of the manual on \ref Analysis PLUMED contains a number of tools that allow you to calculate
+      31             : a function on a grid.  The function on this grid might be a \ref HISTOGRAM as a function of a few collective variables
+      32             : or it might be a phase field that has been calculated using \ref MULTICOLVARDENS.  If this function has one or two input
+      33             : arguments it is relatively straightforward to plot the function.  If by contrast the data has a three or more dimensions
+      34             : it can be difficult to visualize.
+      35             : 
+      36             : This action provides one tool for visualizing these functions.  It can be used to search for a set of points on a contour
+      37             : where the function takes a particular values.  In other words, for the function \f$f(x,y)\f$ this action would find a set
+      38             : of points \f$\{x_c,y_c\}\f$ that have:
+      39             : 
+      40             : \f[
+      41             : f(x_c,y_c) - c = 0
+      42             : \f]
+      43             : 
+      44             : where \f$c\f$ is some constant value that is specified by the user.  The points on this contour are detected using a variant
+      45             : on the marching squares or marching cubes algorithm, which you can find information on here:
+      46             : 
+      47             : https://en.wikipedia.org/wiki/Marching_squares
+      48             : https://en.wikipedia.org/wiki/Marching_cubes
+      49             : 
+      50             : As such, and unlike \ref FIND_CONTOUR_SURFACE or \ref FIND_SPHERICAL_CONTOUR, the function input to this action can have any dimension.
+      51             : Furthermore, the topology of the contour will be determined by the algorithm and does not need to be specified by the user.
+      52             : 
+      53             : \par Examples
+      54             : 
+      55             : The input below allows you to calculate something akin to a Willard-Chandler dividing surface \cite wcsurface.
+      56             : The simulation cell in this case contains a solid phase and a liquid phase.  The Willard-Chandler surface is the
+      57             : surface that separates the parts of the box containing the solid from the parts containing the liquid.  To compute the position
+      58             : of this surface  the \ref FCCUBIC symmetry function is calculated for each of the atoms in the system from on the geometry of the
+      59             : atoms in the first coordination sphere of each of the atoms.  These quantities are then transformed using a switching function.
+      60             : This procedure generates a single number for each atom in the system and this quantity has a value of one for atoms that are in
+      61             : parts of the box that resemble the solid structure and zero for atoms that are in parts of the box that resemble the liquid.
+      62             : The position of a virtual atom is then computed using \ref CENTER_OF_MULTICOLVAR and a phase field model is constructed using
+      63             : \ref MULTICOLVARDENS.  These procedure ensures that we have a continuous function that gives a measure of the average degree of
+      64             : solidness at each point in the simulation cell.  The Willard-Chandler dividing surface is calculated by finding a a set of points
+      65             : at which the value of this phase field is equal to 0.5.  This set of points is output to file called mycontour.dat.  A new contour
+      66             : is found on every single step for each frame that is read in.
+      67             : 
+      68             : \plumedfile
+      69             : UNITS NATURAL
+      70             : FCCUBIC ...
+      71             :   SPECIES=1-96000 SWITCH={CUBIC D_0=1.2 D_MAX=1.5}
+      72             :   ALPHA=27 PHI=0.0 THETA=-1.5708 PSI=-2.35619 LABEL=fcc
+      73             : ... FCCUBIC
+      74             : 
+      75             : tfcc: MTRANSFORM_MORE DATA=fcc LOWMEM SWITCH={SMAP R_0=0.5 A=8 B=8}
+      76             : center: CENTER_OF_MULTICOLVAR DATA=tfcc
+      77             : 
+      78             : dens: MULTICOLVARDENS ...
+      79             :   DATA=tfcc ORIGIN=center DIR=xyz
+      80             :   NBINS=80,80,80 BANDWIDTH=1.0,1.0,1.0 STRIDE=1 CLEAR=1
+      81             : ...
+      82             : 
+      83             : FIND_CONTOUR GRID=dens CONTOUR=0.5 FILE=mycontour.xyz
+      84             : \endplumedfile
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : namespace PLMD {
+      90             : namespace gridtools {
+      91             : 
+      92             : class FindContour : public ContourFindingBase {
+      93             : private:
+      94             :   bool firsttime;
+      95             :   unsigned gbuffer;
+      96             : /// Stuff for output
+      97             :   OFile of;
+      98             :   double lenunit;
+      99             :   std::string fmt_xyz;
+     100             : public:
+     101             :   static void registerKeywords( Keywords& keys );
+     102             :   explicit FindContour(const ActionOptions&ao);
+     103           0 :   bool checkAllActive() const override { return gbuffer==0; }
+     104             :   void prepareForAveraging() override;
+     105           0 :   bool isPeriodic() override { return false; }
+     106           7 :   unsigned getNumberOfQuantities() const override { return 1 + ingrid->getDimension(); }
+     107             :   void compute( const unsigned& current, MultiValue& myvals ) const override;
+     108             :   void finishAveraging() override;
+     109             : };
+     110             : 
+     111             : PLUMED_REGISTER_ACTION(FindContour,"FIND_CONTOUR")
+     112             : 
+     113           3 : void FindContour::registerKeywords( Keywords& keys ) {
+     114           3 :   ContourFindingBase::registerKeywords( keys );
+     115             : // We want a better way of doing this bit
+     116           6 :   keys.add("compulsory","BUFFER","0","number of buffer grid points around location where grid was found on last step.  If this is zero the full grid is calculated on each step");
+     117           6 :   keys.add("compulsory","FILE","file on which to output coordinates");
+     118           6 :   keys.add("compulsory","UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+     119           6 :   keys.add("optional", "PRECISION","The number of digits in trajectory file");
+     120           3 : }
+     121             : 
+     122           1 : FindContour::FindContour(const ActionOptions&ao):
+     123             :   Action(ao),
+     124             :   ContourFindingBase(ao),
+     125           1 :   firsttime(true)
+     126             : {
+     127             : 
+     128           1 :   parse("BUFFER",gbuffer);
+     129           1 :   if( gbuffer>0 ) log.printf("  after first step a subset of only %u grid points around where the countour was found will be checked\n",gbuffer);
+     130             : 
+     131           2 :   std::string file; parse("FILE",file);
+     132           1 :   if( file.length()==0 ) error("name out output file was not specified");
+     133           1 :   std::string type=Tools::extension(file);
+     134           1 :   log<<"  file name "<<file<<"\n";
+     135           1 :   if(type!="xyz") error("can only print xyz file type with contour finding");
+     136             : 
+     137             :   fmt_xyz="%f";
+     138           2 :   std::string precision; parse("PRECISION",precision);
+     139           1 :   if(precision.length()>0) {
+     140           1 :     int p; Tools::convert(precision,p);
+     141           1 :     log<<"  with precision "<<p<<"\n";
+     142             :     std::string a,b;
+     143           1 :     Tools::convert(p+5,a);
+     144           1 :     Tools::convert(p,b);
+     145           2 :     fmt_xyz="%"+a+"."+b+"f";
+     146             :   }
+     147           2 :   std::string unitname; parse("UNITS",unitname);
+     148           1 :   if(unitname!="PLUMED") {
+     149           0 :     Units myunit; myunit.setLength(unitname);
+     150           0 :     lenunit=getUnits().getLength()/myunit.getLength();
+     151           0 :   }
+     152           1 :   else lenunit=1.0;
+     153           1 :   of.link(*this); of.open(file);
+     154           1 :   checkRead(); mydata=buildDataStashes( NULL );
+     155           1 : }
+     156             : 
+     157           2 : void FindContour::prepareForAveraging() {
+     158             :   // Create a task list if first time
+     159           2 :   if( firsttime ) {
+     160       16465 :     for(unsigned i=0; i<ingrid->getDimension()*ingrid->getNumberOfPoints(); ++i) addTaskToList( i );
+     161             :   }
+     162           2 :   firsttime=false; deactivateAllTasks();
+     163             : 
+     164             :   // We now need to identify the grid points that we need to search through
+     165           2 :   std::vector<unsigned> nbin( ingrid->getNbin() );
+     166           2 :   std::vector<unsigned> ind( ingrid->getDimension() );
+     167           2 :   std::vector<unsigned> ones( ingrid->getDimension(), 1 );
+     168             :   unsigned num_neighbours; std::vector<unsigned> neighbours;
+     169       10978 :   for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) {
+     170             :     // Ensure inactive grid points are ignored
+     171       10976 :     if( ingrid->inactive(i) ) continue;
+     172             : 
+     173             :     // Get the index of the current grid point
+     174       10976 :     ingrid->getIndices( i, ind );
+     175       10976 :     ingrid->getNeighbors( ind, ones, num_neighbours, neighbours );
+     176             :     bool cycle=false;
+     177      307328 :     for(unsigned j=0; j<num_neighbours; ++j) {
+     178      296352 :       if( ingrid->inactive( neighbours[j]) ) { cycle=true; break; }
+     179             :     }
+     180       10976 :     if( cycle ) continue;
+     181             : 
+     182             :     // Get the value of a point on the grid
+     183       10976 :     double val1=getFunctionValue( i ) - contour;
+     184             :     bool edge=false;
+     185       43904 :     for(unsigned j=0; j<ingrid->getDimension(); ++j) {
+     186             :       // Make sure we don't search at the edge of the grid
+     187       32928 :       if( !ingrid->isPeriodic(j) && (ind[j]+1)==nbin[j] ) continue;
+     188       32928 :       else if( (ind[j]+1)==nbin[j] ) { edge=true; ind[j]=0; }
+     189       30968 :       else ind[j]+=1;
+     190       32928 :       double val2=getFunctionValue( ind ) - contour;
+     191       32928 :       if( val1*val2<0 ) taskFlags[ ingrid->getDimension()*i + j ] = 1;
+     192       32928 :       if( ingrid->isPeriodic(j) && edge ) { edge=false; ind[j]=nbin[j]-1; }
+     193       30968 :       else ind[j]-=1;
+     194             :     }
+     195             :   }
+     196           2 :   lockContributors();
+     197           2 : }
+     198             : 
+     199         554 : void FindContour::compute( const unsigned& current, MultiValue& myvals ) const {
+     200             :   // Retrieve the initial grid point coordinates
+     201         554 :   unsigned gpoint = std::floor( current / ingrid->getDimension() );
+     202         554 :   std::vector<double> point( ingrid->getDimension() );
+     203         554 :   ingrid->getGridPointCoordinates( gpoint, point );
+     204             : 
+     205             :   // Retrieve the direction we are searching for the contour
+     206         554 :   unsigned gdir = current%(ingrid->getDimension() );
+     207         554 :   std::vector<double> direction( ingrid->getDimension(), 0 );
+     208         554 :   direction[gdir] = 0.999999999*ingrid->getGridSpacing()[gdir];
+     209             : 
+     210             :   // Now find the contour
+     211             :   findContour( direction, point );
+     212             :   // And transfer to the store data vessel
+     213        2216 :   for(unsigned i=0; i<ingrid->getDimension(); ++i) myvals.setValue( 1+i, point[i] );
+     214         554 : }
+     215             : 
+     216           1 : void FindContour::finishAveraging() {
+     217             :   // And update the list of active grid points
+     218           1 :   if( gbuffer>0 ) {
+     219             :     std::vector<unsigned> neighbours; unsigned num_neighbours;
+     220           0 :     std::vector<unsigned> ugrid_indices( ingrid->getDimension() );
+     221           0 :     std::vector<bool> active( ingrid->getNumberOfPoints(), false );
+     222           0 :     std::vector<unsigned> gbuffer_vec( ingrid->getDimension(), gbuffer );
+     223           0 :     for(unsigned i=0; i<getCurrentNumberOfActiveTasks(); ++i) {
+     224             :       // Get the point we are operating on
+     225           0 :       unsigned ipoint = std::floor( getActiveTask(i) / ingrid->getDimension() );
+     226             :       // Get the indices of this point
+     227           0 :       ingrid->getIndices( ipoint, ugrid_indices );
+     228             :       // Now activate buffer region
+     229           0 :       ingrid->getNeighbors( ugrid_indices, gbuffer_vec, num_neighbours, neighbours );
+     230           0 :       for(unsigned n=0; n<num_neighbours; ++n) active[ neighbours[n] ]=true;
+     231             :     }
+     232           0 :     ingrid->activateThesePoints( active );
+     233             :   }
+     234           1 :   std::vector<double> point( 1 + ingrid->getDimension() );
+     235           1 :   of.printf("%u\n",mydata->getNumberOfStoredValues());
+     236           1 :   of.printf("Points found on isocontour\n");
+     237         555 :   for(unsigned i=0; i<mydata->getNumberOfStoredValues(); ++i) {
+     238         554 :     mydata->retrieveSequentialValue( i, false, point ); of.printf("X");
+     239        2216 :     for(unsigned j=0; j<ingrid->getDimension(); ++j) of.printf( (" " + fmt_xyz).c_str(), lenunit*point[1+j] );
+     240         554 :     of.printf("\n");
+     241             :   }
+     242           1 : }
+     243             : 
+     244             : }
+     245             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindContourSurface.cpp.func-sort-c.html b/coverage/gridtools/FindContourSurface.cpp.func-sort-c.html new file mode 100644 index 000000000000..4b55232f786f --- /dev/null +++ b/coverage/gridtools/FindContourSurface.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindContourSurface.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindContourSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:899395.7 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18FindContourSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools18FindContourSurface14checkAllActiveEv0
_ZN4PLMD9gridtools18FindContourSurfaceC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools18FindContourSurface12clearAverageEv3
_ZN4PLMD9gridtools18FindContourSurface15finishAveragingEv3
_ZN4PLMD9gridtools18FindContourSurface16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools18FindContourSurface19prepareForAveragingEv3
_ZNK4PLMD9gridtools18FindContourSurface21getNumberOfQuantitiesEv12
_ZNK4PLMD9gridtools18FindContourSurface7computeERKjRNS_10MultiValueE588
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindContourSurface.cpp.func.html b/coverage/gridtools/FindContourSurface.cpp.func.html new file mode 100644 index 000000000000..62c93b420e0a --- /dev/null +++ b/coverage/gridtools/FindContourSurface.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindContourSurface.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindContourSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:899395.7 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools18FindContourSurface12clearAverageEv3
_ZN4PLMD9gridtools18FindContourSurface15finishAveragingEv3
_ZN4PLMD9gridtools18FindContourSurface16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools18FindContourSurface19prepareForAveragingEv3
_ZN4PLMD9gridtools18FindContourSurfaceC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools18FindContourSurfaceC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools18FindContourSurface14checkAllActiveEv0
_ZNK4PLMD9gridtools18FindContourSurface21getNumberOfQuantitiesEv12
_ZNK4PLMD9gridtools18FindContourSurface7computeERKjRNS_10MultiValueE588
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindContourSurface.cpp.gcov.html b/coverage/gridtools/FindContourSurface.cpp.gcov.html new file mode 100644 index 000000000000..f0a237a3bf15 --- /dev/null +++ b/coverage/gridtools/FindContourSurface.cpp.gcov.html @@ -0,0 +1,340 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindContourSurface.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindContourSurface.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:899395.7 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "ContourFindingBase.h"
+      24             : 
+      25             : //+PLUMEDOC GRIDANALYSIS FIND_CONTOUR_SURFACE
+      26             : /*
+      27             : Find an isocontour by searching along either the x, y or z direction.
+      28             : 
+      29             : As discussed in the part of the manual on \ref Analysis PLUMED contains a number of tools that allow you to calculate
+      30             : a function on a grid.  The function on this grid might be a \ref HISTOGRAM as a function of a few collective variables
+      31             : or it might be a phase field that has been calculated using \ref MULTICOLVARDENS.  If this function has one or two input
+      32             : arguments it is relatively straightforward to plot the function.  If by contrast the data has a three dimensions it can be
+      33             : difficult to visualize.
+      34             : 
+      35             : This action provides one tool for visualizing these functions.  It can be used to search for a set of points on a contour
+      36             : where the function takes a particular value.  In other words, for the function \f$f(x,y,z)\f$ this action would find a set
+      37             : of points \f$\{x_c,y_c,z_c\}\f$ that have:
+      38             : 
+      39             : \f[
+      40             : f(x_c,y_c,z_c) - c = 0
+      41             : \f]
+      42             : 
+      43             : where \f$c\f$ is some constant value that is specified by the user.  The points on this contour are find by searching along lines
+      44             : that run parallel to the \f$x\f$, \f$y\f$ or \f$z\f$ axis of the simulation cell.  The result is, therefore, a two dimensional
+      45             : function evaluated on a grid that gives us the height of the interface as a function of two coordinates.
+      46             : 
+      47             : It is important to note that this action can only be used to detect contours in three dimensional functions.  In addition, this action will fail to
+      48             : find the full set of contour  points if the contour does not have the same topology as an infinite plane.  If you are uncertain that the isocontours in your
+      49             : function have the appropriate topology you should use \ref FIND_CONTOUR in place of \ref FIND_CONTOUR_SURFACE.
+      50             : 
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The input shown below was used to analyze the results from a simulation of an interface between solid and molten Lennard Jones.  The interface between
+      55             : the solid and the liquid was set up in the plane perpendicular to the \f$z\f$ direction of the simulation cell.   The input below calculates something
+      56             : akin to a Willard-Chandler dividing surface \cite wcsurface between the solid phase and the liquid phase.  There are two of these interfaces within the
+      57             : simulation box because of the periodic boundary conditions but we were able to determine that one of these two surfaces lies in a particular part of the
+      58             : simulation box.  The input below detects the height profile of one of these two interfaces.  It does so by computing a phase field average of the
+      59             : \ref FCCUBIC symmetry function using the \ref MULTICOLVARDENS action.  Notice that we use the fact that we know roughly where the interface is when specifying
+      60             : how this phase field is to be calculated and specify the region over the \f$z\f$-axis in which we are going to search for the phase field in the line defining
+      61             : the \ref MULTICOLVARDENS.  Once we have calculated the phase field we search for contour points on the lines that run parallel to the \f$z\f$-direction of the cell
+      62             : box using the FIND_CONTOUR_SURFACE command.  The final result is a \f$14 \times 14\f$ grid of values for the height of the interface as a function of the \f$(x,y)\f$
+      63             : position.  This grid is then output to a file called contour2.dat.
+      64             : 
+      65             : Notice that the commands below calculate the instantaneous position of the surface separating the solid and liquid and that as such the accumulated average is cleared
+      66             : on every step.
+      67             : 
+      68             : \plumedfile
+      69             : UNITS NATURAL
+      70             : FCCUBIC ...
+      71             :   SPECIES=1-96000 SWITCH={CUBIC D_0=1.2 D_MAX=1.5}
+      72             :   ALPHA=27 PHI=0.0 THETA=-1.5708 PSI=-2.35619 LABEL=fcc
+      73             : ... FCCUBIC
+      74             : 
+      75             : dens2: MULTICOLVARDENS DATA=fcc ORIGIN=1 DIR=xyz NBINS=14,14,50 ZREDUCED ZLOWER=6.0 ZUPPER=11.0 BANDWIDTH=1.0,1.0,1.0 CLEAR=1
+      76             : 
+      77             : ss2: FIND_CONTOUR_SURFACE GRID=dens2 CONTOUR=0.42 SEARCHDIR=z STRIDE=1 CLEAR=1
+      78             : DUMPGRID GRID=ss2 FILE=contour2.dat FMT=%8.4f STRIDE=1
+      79             : \endplumedfile
+      80             : 
+      81             : */
+      82             : //+ENDPLUMEDOC
+      83             : 
+      84             : namespace PLMD {
+      85             : namespace gridtools {
+      86             : 
+      87             : class FindContourSurface : public ContourFindingBase {
+      88             : private:
+      89             :   bool firsttime;
+      90             :   unsigned dir_n;
+      91             :   unsigned gbuffer;
+      92             :   std::vector<unsigned> ones;
+      93             :   std::vector<unsigned> gdirs;
+      94             :   std::vector<double> direction;
+      95             : public:
+      96             :   static void registerKeywords( Keywords& keys );
+      97             :   explicit FindContourSurface(const ActionOptions&ao);
+      98          12 :   unsigned getNumberOfQuantities() const override { return 2; }
+      99           0 :   bool checkAllActive() const override { return gbuffer==0; }
+     100             :   void clearAverage() override;
+     101             :   void prepareForAveraging() override;
+     102             :   void compute( const unsigned& current, MultiValue& myvals ) const override;
+     103             :   void finishAveraging() override;
+     104             : };
+     105             : 
+     106             : PLUMED_REGISTER_ACTION(FindContourSurface,"FIND_CONTOUR_SURFACE")
+     107             : 
+     108           3 : void FindContourSurface::registerKeywords( Keywords& keys ) {
+     109           3 :   ContourFindingBase::registerKeywords( keys );
+     110           6 :   keys.add("compulsory","SEARCHDIR","In which directions do you wish to search for the contour.");
+     111           6 :   keys.add("compulsory","BUFFER","0","number of buffer grid points around location where grid was found on last step.  If this is zero the full grid is calculated on each step");
+     112           3 : }
+     113             : 
+     114           1 : FindContourSurface::FindContourSurface(const ActionOptions&ao):
+     115             :   Action(ao),
+     116             :   ContourFindingBase(ao),
+     117           1 :   firsttime(true),
+     118           1 :   ones(ingrid->getDimension(),1)
+     119             : {
+     120           1 :   if( ingrid->getDimension()<2 ) error("cannot find dividing surface if input grid is one dimensional");
+     121             : 
+     122           2 :   std::string dir; parse("SEARCHDIR",dir); parse("BUFFER",gbuffer);
+     123           1 :   log.printf("  calculating location of contour on %d dimensional grid \n", ingrid->getDimension()-1 );
+     124           1 :   if( gbuffer>0 ) log.printf("  after first step a subset of only %u grid points around where the countour was found will be checked\n",gbuffer);
+     125           1 :   checkRead();
+     126             : 
+     127           1 :   unsigned n=0; gdirs.resize( ingrid->getDimension()-1 );
+     128           4 :   for(unsigned i=0; i<ingrid->getDimension(); ++i) {
+     129           3 :     if( ingrid->getComponentName(i)==dir ) {
+     130           1 :       dir_n=i;
+     131             :     } else {
+     132           2 :       if( n==gdirs.size() ) error("could not find " + dir + " direction in input grid");
+     133           2 :       gdirs[n]=i; n++;
+     134             :     }
+     135             :   }
+     136           1 :   if( n!=(ingrid->getDimension()-1) ) error("output of grid is not understood");
+     137             : 
+     138             :   // Create the input from the old string
+     139           2 :   std::string vstring = "COMPONENTS=" + getLabel() + " COORDINATES=" + ingrid->getComponentName( gdirs[0] );
+     140           2 :   for(unsigned i=1; i<gdirs.size(); ++i) vstring += "," + ingrid->getComponentName( gdirs[i] );
+     141             :   vstring += " PBC=";
+     142           1 :   if( ingrid->isPeriodic(gdirs[0]) ) vstring+="T";
+     143             :   else vstring+="F";
+     144           2 :   for(unsigned i=1; i<gdirs.size(); ++i) {
+     145           1 :     if( ingrid->isPeriodic(gdirs[i]) ) vstring+=",T"; else vstring+=",F";
+     146             :   }
+     147           2 :   auto grid=createGrid( "grid", vstring ); grid->setNoDerivatives();
+     148           1 :   setAveragingAction( std::move(grid), true );
+     149           2 : }
+     150             : 
+     151           3 : void FindContourSurface::clearAverage() {
+     152             :   // Set the boundaries of the output grid
+     153           3 :   std::vector<double> fspacing; std::vector<unsigned> snbins( ingrid->getDimension()-1 );
+     154           3 :   std::vector<std::string> smin( ingrid->getDimension()-1 ), smax( ingrid->getDimension()-1 );
+     155           9 :   for(unsigned i=0; i<gdirs.size(); ++i) {
+     156          18 :     smin[i]=ingrid->getMin()[gdirs[i]]; smax[i]=ingrid->getMax()[gdirs[i]];
+     157           6 :     snbins[i]=ingrid->getNbin()[gdirs[i]];
+     158             :   }
+     159           3 :   mygrid->setBounds( smin, smax, snbins, fspacing); resizeFunctions();
+     160           3 :   ActionWithAveraging::clearAverage();
+     161           6 : }
+     162             : 
+     163           3 : void FindContourSurface::prepareForAveraging() {
+     164             :   // Create a task list if first time
+     165           3 :   if( firsttime ) {
+     166           1 :     std::vector<unsigned> find( ingrid->getDimension() );
+     167           1 :     std::vector<unsigned> ind( mygrid->getDimension() );
+     168         197 :     for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) {
+     169         196 :       find.assign( find.size(), 0 ); mygrid->getIndices( i, ind );
+     170         588 :       for(unsigned j=0; j<gdirs.size(); ++j) find[gdirs[j]]=ind[j];
+     171             :       // Current will be set equal to the start point for this grid index
+     172         196 :       addTaskToList( ingrid->getIndex(find) );
+     173             :     }
+     174             :     // And prepare the task list
+     175           1 :     deactivateAllTasks();
+     176         197 :     for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+     177           1 :     lockContributors();
+     178             :     // Set the direction in which to look for the contour
+     179           1 :     direction.resize( ingrid->getDimension(), 0 );
+     180           1 :     direction[dir_n] = 0.999999999*ingrid->getGridSpacing()[dir_n];
+     181             :   }
+     182           3 : }
+     183             : 
+     184           3 : void FindContourSurface::finishAveraging() {
+     185             :   ContourFindingBase::finishAveraging();
+     186             :   // And update the list of active grid points
+     187           3 :   if( gbuffer>0 ) {
+     188           3 :     std::vector<double> dx( ingrid->getGridSpacing() );
+     189           3 :     std::vector<double> point( ingrid->getDimension() );
+     190           3 :     std::vector<double> lpoint( mygrid->getDimension() );
+     191             :     std::vector<unsigned> neighbours; unsigned num_neighbours;
+     192           3 :     std::vector<unsigned> ugrid_indices( ingrid->getDimension() );
+     193           3 :     std::vector<bool> active( ingrid->getNumberOfPoints(), false );
+     194           3 :     std::vector<unsigned> gbuffer_vec( ingrid->getDimension(), gbuffer );
+     195         591 :     for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) {
+     196             :       // Retrieve the coordinates of this grid point
+     197         588 :       mygrid->getGridPointCoordinates( i, lpoint );
+     198         588 :       point[dir_n] = mygrid->getGridElement( i, 0 );
+     199             :       // 0.5*dx added here to prevent problems with flooring of grid points
+     200        1764 :       for(unsigned j=0; j<gdirs.size(); ++j) point[gdirs[j]]=lpoint[j] + 0.5*dx[gdirs[j]];
+     201         588 :       ingrid->getIndices( point, ugrid_indices );
+     202             :       // Now activate buffer region
+     203         588 :       ingrid->getNeighbors( ugrid_indices, gbuffer_vec, num_neighbours, neighbours );
+     204       16464 :       for(unsigned n=0; n<num_neighbours; ++n) active[ neighbours[n] ]=true;
+     205             :     }
+     206           3 :     ingrid->activateThesePoints( active );
+     207             :   }
+     208           3 :   firsttime=false;
+     209           3 : }
+     210             : 
+     211         588 : void FindContourSurface::compute( const unsigned& current, MultiValue& myvals ) const {
+     212             :   std::vector<unsigned> neighbours; unsigned num_neighbours; unsigned nfound=0; double minp=0;
+     213         588 :   std::vector<unsigned> bins_n( ingrid->getNbin() ); unsigned shiftn=current;
+     214         588 :   std::vector<unsigned> ind( ingrid->getDimension() ); std::vector<double> point( ingrid->getDimension() );
+     215             : #ifndef NDEBUG
+     216             :   std::vector<unsigned> oind( mygrid->getDimension() ); mygrid->getIndices( current, oind );
+     217             : #endif
+     218       16749 :   for(unsigned i=0; i<bins_n[dir_n]; ++i) {
+     219             : #ifndef NDEBUG
+     220             :     std::vector<unsigned> base_ind( ingrid->getDimension() ); ingrid->getIndices( shiftn, base_ind );
+     221             :     for(unsigned j=0; j<gdirs.size(); ++j) plumed_dbg_assert( base_ind[gdirs[j]]==oind[j] );
+     222             : #endif
+     223             :     // Ensure inactive grid points are ignored
+     224       16749 :     if( ingrid->inactive( shiftn ) ) { shiftn += ingrid->getStride()[dir_n]; continue; }
+     225             :     // Get the index of the current grid point
+     226        7857 :     ingrid->getIndices( shiftn, ind );
+     227             :     // Exit if we are at the edge of the grid
+     228        7857 :     if( !ingrid->isPeriodic(dir_n) && (ind[dir_n]+1)==bins_n[dir_n] ) {
+     229           0 :       shiftn += ingrid->getStride()[dir_n]; continue;
+     230             :     }
+     231             : 
+     232             :     // Ensure points with inactive neighbours are ignored
+     233        7857 :     ingrid->getNeighbors( ind, ones, num_neighbours, neighbours );
+     234             :     bool cycle=false;
+     235      179020 :     for(unsigned j=0; j<num_neighbours; ++j) {
+     236      172753 :       if( ingrid->inactive( neighbours[j]) ) { cycle=true; break; }
+     237             :     }
+     238        7857 :     if( cycle ) { shiftn += ingrid->getStride()[dir_n]; continue; }
+     239             : 
+     240             :     // Now get the function value at two points
+     241        6267 :     double val1=getFunctionValue( shiftn ) - contour; double val2;
+     242        6267 :     if( (ind[dir_n]+1)==bins_n[dir_n] ) val2 = getFunctionValue( current ) - contour;
+     243        6267 :     else val2=getFunctionValue( shiftn + ingrid->getStride()[dir_n] ) - contour;
+     244             : 
+     245             :     // Check if the minimum is bracketed
+     246        6267 :     if( val1*val2<0 ) {
+     247         588 :       ingrid->getGridPointCoordinates( shiftn, point ); findContour( direction, point );
+     248         588 :       minp=point[dir_n]; nfound++; break;
+     249             :     }
+     250             : 
+     251             : 
+     252             :     // This moves us on to the next point
+     253        5679 :     shiftn += ingrid->getStride()[dir_n];
+     254             :   }
+     255             :   if( nfound==0 ) {
+     256           0 :     std::string num; Tools::convert( getStep(), num );
+     257           0 :     error("On step " + num + " failed to find required grid point");
+     258             :   }
+     259             :   myvals.setValue( 1, minp );
+     260         588 : }
+     261             : 
+     262             : }
+     263             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindSphericalContour.cpp.func-sort-c.html b/coverage/gridtools/FindSphericalContour.cpp.func-sort-c.html new file mode 100644 index 000000000000..2fe81d46e190 --- /dev/null +++ b/coverage/gridtools/FindSphericalContour.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindSphericalContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindSphericalContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools20FindSphericalContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools20FindSphericalContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools20FindSphericalContour16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD9gridtools20FindSphericalContour21getNumberOfQuantitiesEv4
_ZNK4PLMD9gridtools20FindSphericalContour7computeERKjRNS_10MultiValueE100
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindSphericalContour.cpp.func.html b/coverage/gridtools/FindSphericalContour.cpp.func.html new file mode 100644 index 000000000000..6954bbaef267 --- /dev/null +++ b/coverage/gridtools/FindSphericalContour.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindSphericalContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindSphericalContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools20FindSphericalContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools20FindSphericalContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools20FindSphericalContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools20FindSphericalContour21getNumberOfQuantitiesEv4
_ZNK4PLMD9gridtools20FindSphericalContour7computeERKjRNS_10MultiValueE100
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FindSphericalContour.cpp.gcov.html b/coverage/gridtools/FindSphericalContour.cpp.gcov.html new file mode 100644 index 000000000000..d0315e03bdab --- /dev/null +++ b/coverage/gridtools/FindSphericalContour.cpp.gcov.html @@ -0,0 +1,261 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FindSphericalContour.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FindSphericalContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "ContourFindingBase.h"
+      24             : #include "tools/Random.h"
+      25             : 
+      26             : //+PLUMEDOC GRIDANALYSIS FIND_SPHERICAL_CONTOUR
+      27             : /*
+      28             : Find an isocontour in a three dimensional grid by searching over a Fibonacci sphere.
+      29             : 
+      30             : As discussed in the part of the manual on \ref Analysis PLUMED contains a number of tools that allow you to calculate
+      31             : a function on a grid.  The function on this grid might be a \ref HISTOGRAM as a function of a few collective variables
+      32             : or it might be a phase field that has been calculated using \ref MULTICOLVARDENS.  If this function has one or two input
+      33             : arguments it is relatively straightforward to plot the function.  If by contrast the data has a three dimensions it can be
+      34             : difficult to visualize.
+      35             : 
+      36             : This action provides one tool for visualizing these functions.  It can be used to search for a set of points on a contour
+      37             : where the function takes a particular value.  In other words, for the function \f$f(x,y,z)\f$ this action would find a set
+      38             : of points \f$\{x_c,y_c,z_c\}\f$ that have:
+      39             : 
+      40             : \f[
+      41             : f(x_c,y_c,z_c) - c = 0
+      42             : \f]
+      43             : 
+      44             : where \f$c\f$ is some constant value that is specified by the user.  The points on this contour are find by searching along a
+      45             : set of equally spaced radii of a sphere that centered at on particular, user-specified atom or virtual atom.  To ensure that
+      46             : these search radii are equally spaced on the surface of the sphere the search directions are generated by using a Fibonacci
+      47             : spiral projected on a sphere.  In other words, the search directions are given by:
+      48             : 
+      49             : \f[
+      50             : \mathbf{r}_i = \left(
+      51             : \begin{matrix}
+      52             : \sqrt{1 - y^2} \cos(\phi) \\
+      53             : \frac{2i}{n} - 1 + \frac{1}{n}  \\
+      54             : \sqrt{1 - y^2} \sin(\phi)
+      55             : \end{matrix}
+      56             : \right)
+      57             : \f]
+      58             : 
+      59             : where \f$y\f$ is the quantity second component of the vector defined above, \f$n\f$ is the number of directions to look in and \f$\phi\f$ is
+      60             : 
+      61             : \f[
+      62             : \phi = \mod(i + R, n) \pi ( 3 - \sqrt{5} )
+      63             : \f]
+      64             : 
+      65             : where \f$R\f$ is a random variable between 0 and \f$n-1\f$ that is generated during the read in of the input file and that is fixed during
+      66             : the whole calculation.
+      67             : 
+      68             : It is important to note that this action can only be used to detect contours in three dimensional functions.  In addition, this action will fail to
+      69             : find the full set of contour  points if the contour does not have the same topology as a sphere.  If you are uncertain that the isocontours in your
+      70             : function have a spherical topology you should use \ref FIND_CONTOUR in place of \ref FIND_SPHERICAL_CONTOUR.
+      71             : 
+      72             : \par Examples
+      73             : 
+      74             : The following input demonstrates how this action can be used.  The input here is used to study the shape of a droplet that has been formed during the
+      75             : condensation of Lennard Jones from the vapor.  The input below achieves this by calculating the coordination numbers of all the atoms within the gas.
+      76             : Obviously, those atoms within the droplet will have a large value for the coordination number while the isolated atoms in the gas will have a low value.
+      77             : As such we can detect the sizes of the droplets by constructing a \ref CONTACT_MATRIX whose \f$ij\f$ element tells us whether atom \f$i\f$ and atom \f$j\f$
+      78             : have coordination number that is greater that two.  The atoms within the various droplets within the system can then be found by performing a
+      79             : \ref DFSCLUSTERING on this matrix to detect the connected components.  We can take the largest of these connected components and find the center of the droplet
+      80             : by exploiting the functionality within \ref CENTER_OF_MULTICOLVAR.  We can then construct a phase field based on the positions of the atoms in the largest
+      81             : cluster and the values of the coordination numbers of these atoms.  The final line in the input then finds the a set of points on the dividing surface that separates
+      82             : the droplet from the surrounding gas.  The value of the phase field on this isocontour is equal to 0.75.
+      83             : 
+      84             : \plumedfile
+      85             : # Calculate coordination numbers
+      86             : c1: COORDINATIONNUMBER SPECIES=1-512 SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0}
+      87             : # Select coordination numbers that are more than 2.0
+      88             : cf: MFILTER_MORE DATA=c1 SWITCH={RATIONAL D_0=2.0 R_0=0.1} LOWMEM
+      89             : # Build a contact matrix
+      90             : mat: CONTACT_MATRIX ATOMS=cf SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0}
+      91             : # Find largest cluster
+      92             : dfs: DFSCLUSTERING MATRIX=mat LOWMEM
+      93             : clust1: CLUSTER_PROPERTIES CLUSTERS=dfs CLUSTER=1
+      94             : # Find center of largest cluster
+      95             : trans1: MTRANSFORM_MORE DATA=clust1 SWITCH={RATIONAL D_0=2.0 R_0=0.1} LOWMEM
+      96             : cent: CENTER_OF_MULTICOLVAR DATA=trans1
+      97             : # Calculate the phase field of the coordination
+      98             : dens: MULTICOLVARDENS DATA=trans1 ORIGIN=cent DIR=xyz NBINS=30,30,30 BANDWIDTH=2.0,2.0,2.0
+      99             : # Find the isocontour around the nucleus
+     100             : sc: FIND_SPHERICAL_CONTOUR GRID=dens CONTOUR=0.85 INNER_RADIUS=10.0 OUTER_RADIUS=40.0 NPOINTS=100
+     101             : # And print the grid to a file
+     102             : GRID_TO_XYZ GRID=sc FILE=mysurface.xyz UNITS=A
+     103             : \endplumedfile
+     104             : 
+     105             : */
+     106             : //+ENDPLUMEDOC
+     107             : 
+     108             : namespace PLMD {
+     109             : namespace gridtools {
+     110             : 
+     111             : class FindSphericalContour : public ContourFindingBase {
+     112             : private:
+     113             :   unsigned nbins;
+     114             :   double min, max;
+     115             : public:
+     116             :   static void registerKeywords( Keywords& keys );
+     117             :   explicit FindSphericalContour(const ActionOptions&ao);
+     118           4 :   unsigned getNumberOfQuantities() const override { return 2; }
+     119             :   void compute( const unsigned& current, MultiValue& myvals ) const override;
+     120             : };
+     121             : 
+     122             : PLUMED_REGISTER_ACTION(FindSphericalContour,"FIND_SPHERICAL_CONTOUR")
+     123             : 
+     124           3 : void FindSphericalContour::registerKeywords( Keywords& keys ) {
+     125           3 :   ContourFindingBase::registerKeywords( keys );
+     126           6 :   keys.add("compulsory","NPOINTS","the number of points for which we are looking for the contour");
+     127           6 :   keys.add("compulsory","INNER_RADIUS","the minimum radius on which to look for the contour");
+     128           6 :   keys.add("compulsory","OUTER_RADIUS","the outer radius on which to look for the contour");
+     129           6 :   keys.add("compulsory","NBINS","1","the number of discrete sections in which to divide the distance between the inner and outer radius when searching for a contour");
+     130           3 : }
+     131             : 
+     132           1 : FindSphericalContour::FindSphericalContour(const ActionOptions&ao):
+     133             :   Action(ao),
+     134           1 :   ContourFindingBase(ao)
+     135             : {
+     136           1 :   if( ingrid->getDimension()!=3 ) error("input grid must be three dimensional");
+     137             : 
+     138           1 :   unsigned npoints; parse("NPOINTS",npoints);
+     139           1 :   log.printf("  searching for %u points on dividing surface \n",npoints);
+     140           3 :   parse("INNER_RADIUS",min); parse("OUTER_RADIUS",max); parse("NBINS",nbins);
+     141           1 :   log.printf("  expecting to find dividing surface at radii between %f and %f \n",min,max);
+     142           1 :   log.printf("  looking for contour in windows of length %f \n", (max-min)/nbins);
+     143             :   // Set this here so the same set of grid points are used on every turn
+     144           1 :   std::string vstring = "TYPE=fibonacci COMPONENTS=" + getLabel() + " COORDINATES=x,y,z PBC=F,F,F";
+     145           2 :   auto grid=createGrid( "grid", vstring ); grid->setNoDerivatives();
+     146           1 :   setAveragingAction( std::move(grid), true );
+     147             :   // use mygrid, since at this point grid has been moved
+     148           1 :   mygrid->setupFibonacciGrid( npoints );
+     149             : 
+     150           1 :   checkRead();
+     151             :   // Create a task list
+     152         101 :   for(unsigned i=0; i<npoints; ++i) addTaskToList( i );
+     153           1 :   deactivateAllTasks();
+     154         101 :   for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+     155           1 :   lockContributors();
+     156           2 : }
+     157             : 
+     158         100 : void FindSphericalContour::compute( const unsigned& current, MultiValue& myvals ) const {
+     159             :   // Generate contour point on inner sphere
+     160         100 :   std::vector<double> contour_point(3), direction(3), der(3), tmp(3);
+     161             :   // Retrieve this contour point from grid
+     162         100 :   mygrid->getGridPointCoordinates( current, direction );
+     163             :   // Now setup contour point on inner sphere
+     164         400 :   for(unsigned j=0; j<3; ++j) {
+     165         300 :     contour_point[j] = min*direction[j];
+     166         300 :     direction[j] = (max-min)*direction[j] / static_cast<double>(nbins);
+     167             :   }
+     168             :   bool found=false;
+     169         100 :   for(unsigned k=0; k<nbins; ++k) {
+     170         400 :     for(unsigned j=0; j<3; ++j) tmp[j] = contour_point[j] + direction[j];
+     171             :     double val1 = getDifferenceFromContour( contour_point, der );
+     172             :     double val2 = getDifferenceFromContour( tmp, der );
+     173         100 :     if( val1*val2<0 ) {
+     174             :       findContour( direction, contour_point );
+     175         400 :       double norm=0; for(unsigned j=0; j<3; ++j) norm += contour_point[j]*contour_point[j];
+     176         100 :       myvals.setValue( 1, std::sqrt(norm) ); found=true; break;
+     177             :     }
+     178           0 :     for(unsigned j=0; j<3; ++j) contour_point[j] = tmp[j];
+     179             :   }
+     180           0 :   if( !found ) error("range does not bracket the dividing surface");
+     181         100 : }
+     182             : 
+     183             : }
+     184             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FourierTransform.cpp.func-sort-c.html b/coverage/gridtools/FourierTransform.cpp.func-sort-c.html new file mode 100644 index 000000000000..bda499391a43 --- /dev/null +++ b/coverage/gridtools/FourierTransform.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FourierTransform.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FourierTransform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:718583.5 %
Date:2024-02-22 21:58:45Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16FourierTransform10isPeriodicEv0
_ZN4PLMD9gridtools16FourierTransformC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools16FourierTransform7computeERKjRNS_10MultiValueE0
_ZN4PLMD9gridtools16FourierTransform12clearAverageEv1
_ZN4PLMD9gridtools16FourierTransformC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools16FourierTransform16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools16FourierTransform17performOperationsERKb4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FourierTransform.cpp.func.html b/coverage/gridtools/FourierTransform.cpp.func.html new file mode 100644 index 000000000000..fc7b27e3206e --- /dev/null +++ b/coverage/gridtools/FourierTransform.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FourierTransform.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FourierTransform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:718583.5 %
Date:2024-02-22 21:58:45Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16FourierTransform10isPeriodicEv0
_ZN4PLMD9gridtools16FourierTransform12clearAverageEv1
_ZN4PLMD9gridtools16FourierTransform16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD9gridtools16FourierTransform17performOperationsERKb4
_ZN4PLMD9gridtools16FourierTransformC1ERKNS_13ActionOptionsE1
_ZN4PLMD9gridtools16FourierTransformC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools16FourierTransform7computeERKjRNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/FourierTransform.cpp.gcov.html b/coverage/gridtools/FourierTransform.cpp.gcov.html new file mode 100644 index 000000000000..0f6e16e711da --- /dev/null +++ b/coverage/gridtools/FourierTransform.cpp.gcov.html @@ -0,0 +1,329 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/FourierTransform.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - FourierTransform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:718583.5 %
Date:2024-02-22 21:58:45Functions:4757.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include <iostream>
+      23             : #include <complex>
+      24             : #include "ActionWithInputGrid.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #ifdef __PLUMED_HAS_FFTW
+      27             : #include <fftw3.h> // FFTW interface
+      28             : #endif
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace gridtools {
+      32             : 
+      33             : //+PLUMEDOC GRIDANALYSIS FOURIER_TRANSFORM
+      34             : /*
+      35             : Compute the Discrete Fourier Transform (DFT) by means of FFTW of data stored on a 2D grid.
+      36             : 
+      37             : This action can operate on any other action that outputs scalar data on a two-dimensional grid.
+      38             : 
+      39             : Up to now, even if the input data are purely real the action uses a complex DFT.
+      40             : 
+      41             : Just as a quick reference, given a 1D array \f$\mathbf{X}\f$ of size \f$n\f$, this action computes the vector \f$\mathbf{Y}\f$ given by
+      42             : 
+      43             : \f[
+      44             : Y_k = \sum_{j=0}^{n-1} X_j e^{2\pi\, j k \sqrt{-1}/n}.
+      45             : \f]
+      46             : 
+      47             : This can be easily extended to more than one dimension. All the other details can be found at http://www.fftw.org/doc/What-FFTW-Really-Computes.html#What-FFTW-Really-Computes.
+      48             : 
+      49             : The keyword "FOURIER_PARAMETERS" deserves just a note on the usage. This keyword specifies how the Fourier transform will be normalized. The keyword takes two numerical parameters (\f$a,\,b\f$) that define the normalization according to the following expression
+      50             : 
+      51             : \f[
+      52             : \frac{1}{n^{(1-a)/2}} \sum_{j=0}^{n-1} X_j e^{2\pi b\, j k \sqrt{-1}/n}
+      53             : \f]
+      54             : 
+      55             : The default values of these parameters are: \f$a=1\f$ and \f$b=1\f$.
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : The following example tells Plumed to compute the complex 2D 'backward' Discrete Fourier Transform by taking the data saved on a grid called 'density', and normalizing the output by \f$ \frac{1}{\sqrt{N_x\, N_y}}\f$, where \f$N_x\f$ and \f$N_y\f$ are the number of data on the grid (it can be the case that \f$N_x\neq N_y\f$):
+      60             : 
+      61             : \plumedfile
+      62             : FOURIER_TRANSFORM STRIDE=1 GRID=density FT_TYPE=complex FOURIER_PARAMETERS=0,-1
+      63             : \endplumedfile
+      64             : 
+      65             : */
+      66             : //+ENDPLUMEDOC
+      67             : 
+      68             : 
+      69             : class FourierTransform : public ActionWithInputGrid {
+      70             : private:
+      71             :   std::string output_type;
+      72             :   bool real_output, store_norm;
+      73             :   std::vector<int> fourier_params;
+      74             : public:
+      75             :   static void registerKeywords( Keywords& keys );
+      76             :   explicit FourierTransform(const ActionOptions&ao);
+      77             :   void clearAverage() override;
+      78             : #ifndef __PLUMED_HAS_FFTW
+      79             :   void performOperations( const bool& from_update ) override {}
+      80             : #else
+      81             :   void performOperations( const bool& from_update ) override;
+      82             : #endif
+      83           0 :   void compute( const unsigned&, MultiValue& ) const override {}
+      84           0 :   bool isPeriodic() override { return false; }
+      85             : };
+      86             : 
+      87             : PLUMED_REGISTER_ACTION(FourierTransform,"FOURIER_TRANSFORM")
+      88             : 
+      89           3 : void FourierTransform::registerKeywords( Keywords& keys ) {
+      90           6 :   ActionWithInputGrid::registerKeywords( keys ); keys.remove("BANDWIDTH"); keys.remove("KERNEL");
+      91           6 :   keys.add("optional","FT_TYPE","choose what kind of data you want as output on the grid. Possible values are: ABS = compute the complex modulus of Fourier coefficients (DEFAULT); NORM = compute the norm (i.e. ABS^2) of Fourier coefficients; COMPLEX = store the FFTW complex output on the grid (as a vector).");
+      92           6 :   keys.add("compulsory","FOURIER_PARAMETERS","default","what kind of normalization is applied to the output and if the Fourier transform in FORWARD or BACKWARD. This keyword takes the form FOURIER_PARAMETERS=A,B, where A and B can be 0, 1 or -1. The default values are A=1 (no normalization at all) and B=1 (forward FFT). Other possible choices for A are: "
+      93             :            "A=-1: normalize by the number of data, "
+      94             :            "A=0: normalize by the square root of the number of data (one forward and followed by backward FFT recover the original data). ");
+      95           3 : }
+      96             : 
+      97           1 : FourierTransform::FourierTransform(const ActionOptions&ao):
+      98             :   Action(ao),
+      99             :   ActionWithInputGrid(ao),
+     100           1 :   real_output(true),
+     101           1 :   store_norm(false),
+     102           1 :   fourier_params(2)
+     103             : {
+     104             : #ifndef __PLUMED_HAS_FFTW
+     105             :   error("this feature is only available if you compile PLUMED with FFTW");
+     106             : #else
+     107           1 :   if( ingrid->getDimension()!=2 ) error("fourier transform currently only works with two dimensional grids");
+     108             : 
+     109             :   // Get the type of FT
+     110           2 :   parse("FT_TYPE",output_type);
+     111           1 :   if (output_type.length()==0) {
+     112           0 :     log<<"  keyword FT_TYPE unset. By default output grid will contain REAL Fourier coefficients\n";
+     113           2 :   } else if ( output_type=="ABS" || output_type=="abs") {
+     114           0 :     log << "  keyword FT_TYPE is '"<< output_type << "' : will compute the MODULUS of Fourier coefficients\n";
+     115           2 :   } else if ( output_type=="NORM" || output_type=="norm") {
+     116           0 :     log << "  keyword FT_TYPE is '"<< output_type << "' : will compute the NORM of Fourier coefficients\n";
+     117           0 :     store_norm=true;
+     118           2 :   } else if ( output_type=="COMPLEX" || output_type=="complex" ) {
+     119           1 :     log<<"  keyword FT_TYPE is '"<< output_type <<"' : output grid will contain the COMPLEX Fourier coefficients\n";
+     120           1 :     real_output=false;
+     121           0 :   } else error("keyword FT_TYPE unrecognized!");
+     122             : 
+     123             :   // Normalize output?
+     124           2 :   std::string params_str; parse("FOURIER_PARAMETERS",params_str);
+     125           1 :   if (params_str=="default") {
+     126           0 :     fourier_params.assign( fourier_params.size(), 1 );
+     127           0 :     log.printf("  default values of Fourier parameters A=%i, B=%i : the output will NOT be normalized and BACKWARD Fourier transform is computed \n", fourier_params[0],fourier_params[1]);
+     128             :   } else {
+     129           1 :     std::vector<std::string> fourier_str = Tools::getWords(params_str, "\t\n ,");
+     130           1 :     if (fourier_str.size()>2) error("FOURIER_PARAMETERS can take just two values");
+     131           3 :     for (unsigned i=0; i<fourier_str.size(); ++i) {
+     132           2 :       Tools::convert(fourier_str[i],fourier_params[i]);
+     133           2 :       if (fourier_params[i]>1 || fourier_params[i]<-1) error("values accepted for FOURIER_PARAMETERS are only -1, 1 or 0");
+     134             :     }
+     135           1 :     log.printf("  Fourier parameters are A=%i, B=%i \n", fourier_params[0],fourier_params[1]);
+     136           1 :   }
+     137             : 
+     138             : 
+     139             :   // Create the input from the old string
+     140             :   std::string vstring;
+     141           1 :   if (real_output) {
+     142           0 :     if (!store_norm) vstring="COMPONENTS=" + getLabel() + "_abs";
+     143           0 :     else vstring="COMPONENTS=" + getLabel() + "_norm";
+     144           2 :   } else vstring="COMPONENTS=" + getLabel() + "_real," + getLabel() + "_imag";
+     145             : 
+     146             :   // Set COORDINATES keyword
+     147           2 :   vstring += " COORDINATES=" + ingrid->getComponentName( 0 );
+     148           3 :   for(unsigned i=1; i<ingrid->getDimension(); ++i) vstring += "," + ingrid->getComponentName( i );
+     149             : 
+     150             :   // Set PBC keyword
+     151             :   vstring += " PBC=";
+     152           1 :   if( ingrid->isPeriodic(0) ) vstring+="T"; else vstring+="F";
+     153           2 :   for(unsigned i=1; i<ingrid->getDimension(); ++i) {
+     154           1 :     if( ingrid->isPeriodic(i) ) vstring+=",T"; else vstring+=",F";
+     155             :   }
+     156             : 
+     157             : 
+     158             :   // Create a grid on which to store the fourier transform of the input grid
+     159           1 :   auto grid=createGrid( "grid", vstring );
+     160           1 :   if( ingrid->noDerivatives() ) grid->setNoDerivatives();
+     161           1 :   setAveragingAction( std::move(grid), false );
+     162             : 
+     163           1 :   checkRead();
+     164             : #endif
+     165           2 : }
+     166             : 
+     167           1 : void FourierTransform::clearAverage() {
+     168             :   std::vector<double> fspacing;
+     169           1 :   std::vector<std::string> ft_min( ingrid->getMin() ), ft_max( ingrid->getMax() );
+     170           3 :   for(unsigned i=0; i<ingrid->getDimension(); ++i) {
+     171           2 :     Tools::convert( 0.0, ft_min[i] ); Tools::convert( 2.0*pi*ingrid->getNbin()[i]/ ingrid->getGridExtent(i), ft_max[i] );
+     172             :   }
+     173           2 :   mygrid->setBounds( ft_min, ft_max, ingrid->getNbin(), fspacing); resizeFunctions();
+     174           1 :   ActionWithAveraging::clearAverage();
+     175           2 : }
+     176             : 
+     177             : #ifdef __PLUMED_HAS_FFTW
+     178           4 : void FourierTransform::performOperations( const bool& from_update ) {
+     179             : 
+     180             :   // Spacing of the real grid
+     181           4 :   std::vector<double> g_spacing ( ingrid->getGridSpacing() );
+     182             : 
+     183             :   // *** CHECK CORRECT k-GRID BOUNDARIES ***
+     184             :   //log<<"Real grid boundaries: \n"
+     185             :   //    <<"  min_x: "<<mygrid->getMin()[0]<<"  min_y: "<<mygrid->getMin()[1]<<"\n"
+     186             :   //    <<"  max_x: "<<mygrid->getMax()[0]<<"  max_y: "<<mygrid->getMax()[1]<<"\n"
+     187             :   //    <<"K-grid boundaries:"<<"\n"
+     188             :   //    <<"  min_x: "<<ft_min[0]<<"  min_y: "<<ft_min[1]<<"\n"
+     189             :   //    <<"  max_x: "<<ft_max[0]<<"  max_y: "<<ft_max[1]<<"\n";
+     190             : 
+     191             :   // Get the size of the input data arrays (to allocate FFT data)
+     192           4 :   size_t fft_dimension=static_cast<size_t>( ingrid->getNumberOfPoints() );
+     193           4 :   std::vector<unsigned> N_input_data( ingrid->getNbin() );
+     194          12 :   for(unsigned i=0; i<N_input_data.size(); ++i) if( !ingrid->isPeriodic(i) ) N_input_data[i]++;
+     195             :   // size_t fft_dimension=1; for(unsigned i=0; i<N_input_data.size(); ++i) fft_dimension*=static_cast<size_t>( N_input_data[i] );
+     196             : 
+     197             :   // FFT arrays
+     198           4 :   std::vector<std::complex<double> > input_data(fft_dimension), fft_data(fft_dimension);
+     199             : 
+     200             : 
+     201             :   // Fill real input with the data on the grid
+     202           4 :   std::vector<unsigned> ind( ingrid->getDimension() );
+     203       40808 :   for (unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) {
+     204             :     // Get point indices
+     205       40804 :     ingrid->getIndices(i, ind);
+     206             :     // Fill input data in row-major order
+     207       40804 :     input_data[ind[0]*N_input_data[0]+ind[1]].real( getFunctionValue( i ) );
+     208       40804 :     input_data[ind[0]*N_input_data[0]+ind[1]].imag( 0.0 );
+     209             :   }
+     210             : 
+     211             :   // *** HERE is the only clear limitation: I'm computing explicitly a 2D FT. It should not happen to deal with other than two-dimensional grid ...
+     212           4 :   fftw_plan plan_complex = fftw_plan_dft_2d(N_input_data[0], N_input_data[1], reinterpret_cast<fftw_complex*>(&input_data[0]), reinterpret_cast<fftw_complex*>(&fft_data[0]), fourier_params[1], FFTW_ESTIMATE);
+     213             : 
+     214             :   // Compute FT
+     215           4 :   fftw_execute( plan_complex );
+     216             : 
+     217             :   // Compute the normalization constant
+     218             :   double norm=1.0;
+     219          12 :   for (unsigned i=0; i<N_input_data.size(); ++i) {
+     220           8 :     norm *= pow( N_input_data[i], (1-fourier_params[0])/2 );
+     221             :   }
+     222             : 
+     223             :   // Save FT data to output grid
+     224           4 :   std::vector<unsigned> N_out_data ( mygrid->getNbin() );
+     225           8 :   std::vector<unsigned> out_ind ( mygrid->getDimension() );
+     226       40808 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) {
+     227       40804 :     mygrid->getIndices( i, out_ind );
+     228       40804 :     if (real_output) {
+     229             :       double ft_value;
+     230             :       // Compute abs/norm and fix normalization
+     231           0 :       if (!store_norm) ft_value=std::abs( fft_data[out_ind[0]*N_out_data[0]+out_ind[1]] / norm );
+     232           0 :       else ft_value=std::norm( fft_data[out_ind[0]*N_out_data[0]+out_ind[1]] / norm );
+     233             :       // Set the value
+     234           0 :       mygrid->setGridElement( i, 0, ft_value );
+     235             :     } else {
+     236             :       double ft_value_real, ft_value_imag;
+     237       40804 :       ft_value_real=fft_data[out_ind[0]*N_out_data[0]+out_ind[1]].real() / norm;
+     238       40804 :       ft_value_imag=fft_data[out_ind[0]*N_out_data[0]+out_ind[1]].imag() / norm;
+     239             :       // Set values
+     240       40804 :       mygrid->setGridElement( i, 0, ft_value_real);
+     241       40804 :       mygrid->setGridElement( i, 1, ft_value_imag);
+     242             :     }
+     243             :   }
+     244             : 
+     245             :   // Free FFTW stuff
+     246           4 :   fftw_destroy_plan(plan_complex);
+     247             : 
+     248           4 : }
+     249             : #endif
+     250             : 
+     251             : } // end namespace 'gridtools'
+     252             : } // end namespace 'PLMD'
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.cpp.func-sort-c.html b/coverage/gridtools/GridPrintingBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..1bdde223748b --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridPrintingBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridPrintingBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5353100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools16GridPrintingBase12runFinalJobsEv57
_ZN4PLMD9gridtools16GridPrintingBaseC2ERKNS_13ActionOptionsE57
_ZN4PLMD9gridtools16GridPrintingBase16registerKeywordsERNS_8KeywordsE63
_ZN4PLMD9gridtools16GridPrintingBase6updateEv68
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.cpp.func.html b/coverage/gridtools/GridPrintingBase.cpp.func.html new file mode 100644 index 000000000000..ef59574199dd --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridPrintingBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridPrintingBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5353100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBase12runFinalJobsEv57
_ZN4PLMD9gridtools16GridPrintingBase16registerKeywordsERNS_8KeywordsE63
_ZN4PLMD9gridtools16GridPrintingBase6updateEv68
_ZN4PLMD9gridtools16GridPrintingBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools16GridPrintingBaseC2ERKNS_13ActionOptionsE57
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.cpp.gcov.html b/coverage/gridtools/GridPrintingBase.cpp.gcov.html new file mode 100644 index 000000000000..cc1c4e3a31be --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.cpp.gcov.html @@ -0,0 +1,182 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridPrintingBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridPrintingBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5353100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "GridPrintingBase.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "vesselbase/ActionWithVessel.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace gridtools {
+      29             : 
+      30          63 : void GridPrintingBase::registerKeywords( Keywords& keys ) {
+      31          63 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys );
+      32         126 :   keys.add("compulsory","GRID","the action that creates the grid you would like to output");
+      33         126 :   keys.add("compulsory","STRIDE","0","the frequency with which the grid should be output to the file.  The default "
+      34             :            "value of 0 ensures that the grid is only output at the end of the trajectory");
+      35         126 :   keys.add("compulsory","FILE","density","the file on which to write the grid.");
+      36         126 :   keys.add("compulsory","REPLICA","0","the replica for which you would like to output this information");
+      37         126 :   keys.add("optional","FMT","the format that should be used to output real numbers");
+      38          63 : }
+      39             : 
+      40          57 : GridPrintingBase::GridPrintingBase(const ActionOptions&ao):
+      41             :   Action(ao),
+      42             :   ActionPilot(ao),
+      43         114 :   fmt("%f"),
+      44          57 :   output_for_all_replicas(false)
+      45             : {
+      46          57 :   std::string mlab; parse("GRID",mlab);
+      47          57 :   vesselbase::ActionWithVessel* mves= plumed.getActionSet().selectWithLabel<vesselbase::ActionWithVessel*>(mlab);
+      48          57 :   if(!mves) error("action labelled " +  mlab + " does not exist or does not have vessels");
+      49          57 :   addDependency(mves);
+      50             : 
+      51          57 :   for(unsigned i=0; i<mves->getNumberOfVessels(); ++i) {
+      52          57 :     ingrid=dynamic_cast<GridVessel*>( mves->getPntrToVessel(i) );
+      53          57 :     if( ingrid ) break;
+      54             :   }
+      55          57 :   if( !ingrid ) error("input action does not calculate a grid");
+      56             : 
+      57         114 :   parse("FILE",filename);
+      58          57 :   if(filename.length()==0) error("name out output file was not specified");
+      59          57 :   log.printf("  outputting grid calculated by action %s to file named %s",mves->getLabel().c_str(), filename.c_str() );
+      60         114 :   if( keywords.exists("FMT") ) {
+      61         110 :     parse("FMT",fmt); log.printf(" with format %s \n", fmt.c_str() );
+      62             :   } else {
+      63           2 :     log.printf("\n");
+      64             :   }
+      65         114 :   std::string rep_data; parse("REPLICA",rep_data);
+      66          57 :   if( rep_data=="all" ) output_for_all_replicas=true;
+      67          57 :   else { preps.resize(1); Tools::convert( rep_data, preps[0] ); }
+      68          57 :   if( output_for_all_replicas ) log.printf("  outputting files for all replicas \n");
+      69             :   else {
+      70          57 :     log.printf("  outputting data for replicas ");
+      71         114 :     for(unsigned i=0; i<preps.size(); ++i) log.printf("%d ", preps[i] );
+      72             :   }
+      73          57 : }
+      74             : 
+      75          68 : void GridPrintingBase::update() {
+      76          68 :   if( !output_for_all_replicas ) {
+      77          68 :     bool found=false; unsigned myrep=plumed.multi_sim_comm.Get_rank();
+      78          68 :     for(unsigned i=0; i<preps.size(); ++i) {
+      79          68 :       if( myrep==preps[i] ) { found=true; break; }
+      80             :     }
+      81          93 :     if( !found ) return;
+      82             :   }
+      83          68 :   if( getStep()==0 || getStride()==0 ) return ;
+      84             : 
+      85          43 :   OFile ofile; ofile.link(*this);
+      86          43 :   ofile.setBackupString("analysis");
+      87          43 :   ofile.open( filename ); printGrid( ofile );
+      88          43 : }
+      89             : 
+      90          57 : void GridPrintingBase::runFinalJobs() {
+      91          57 :   if( !output_for_all_replicas ) {
+      92          57 :     bool found=false; unsigned myrep=plumed.multi_sim_comm.Get_rank();
+      93          62 :     for(unsigned i=0; i<preps.size(); ++i) {
+      94          57 :       if( myrep==preps[i] ) { found=true; break; }
+      95             :     }
+      96          82 :     if( !found ) return;
+      97             :   }
+      98          52 :   if( getStride()>0 ) return;
+      99             : 
+     100          27 :   OFile ofile; ofile.link(*this);
+     101          27 :   ofile.open( filename ); printGrid( ofile );
+     102          27 : }
+     103             : 
+     104             : }
+     105             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.h.func-sort-c.html b/coverage/gridtools/GridPrintingBase.h.func-sort-c.html new file mode 100644 index 000000000000..22f93a469732 --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridPrintingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridPrintingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBase5applyEv68
_ZN4PLMD9gridtools16GridPrintingBase9calculateEv68
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.h.func.html b/coverage/gridtools/GridPrintingBase.h.func.html new file mode 100644 index 000000000000..afd41133c119 --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridPrintingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridPrintingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools16GridPrintingBase5applyEv68
_ZN4PLMD9gridtools16GridPrintingBase9calculateEv68
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridPrintingBase.h.gcov.html b/coverage/gridtools/GridPrintingBase.h.gcov.html new file mode 100644 index 000000000000..e3aa589ed527 --- /dev/null +++ b/coverage/gridtools/GridPrintingBase.h.gcov.html @@ -0,0 +1,127 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridPrintingBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridPrintingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_gridtools_GridPrintingBase_h
+      23             : #define __PLUMED_gridtools_GridPrintingBase_h
+      24             : 
+      25             : #include "core/ActionPilot.h"
+      26             : #include "GridVessel.h"
+      27             : #include "tools/OFile.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace gridtools {
+      31             : 
+      32             : class GridPrintingBase : public ActionPilot {
+      33             : protected:
+      34             :   GridVessel* ingrid;
+      35             :   std::string fmt, filename;
+      36             :   bool output_for_all_replicas;
+      37             :   std::vector<unsigned> preps;
+      38             : public:
+      39             :   static void registerKeywords( Keywords& keys );
+      40             :   explicit GridPrintingBase(const ActionOptions&ao);
+      41          68 :   void calculate() override {}
+      42          68 :   void apply() override {}
+      43             :   void update() override;
+      44             :   void runFinalJobs() override;
+      45             :   virtual void printGrid( OFile& ofile ) const=0;
+      46             : };
+      47             : 
+      48             : }
+      49             : }
+      50             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridSearch.h.func-sort-c.html b/coverage/gridtools/GridSearch.h.func-sort-c.html new file mode 100644 index 000000000000..e19926b57bdd --- /dev/null +++ b/coverage/gridtools/GridSearch.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridSearch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools10GridSearchINS_6dimred18SketchMapPointwiseEEC2ERKSt6vectorIdSaIdEES9_RKS5_IjSaIjEESD_PS3_1
_ZN4PLMD9gridtools10GridSearchINS_6dimred18SketchMapPointwiseEE8minimiseERSt6vectorIdSaIdEEMS3_FdRKS7_S8_E200
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridSearch.h.func.html b/coverage/gridtools/GridSearch.h.func.html new file mode 100644 index 000000000000..62c25f6011cf --- /dev/null +++ b/coverage/gridtools/GridSearch.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridSearch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools10GridSearchINS_6dimred18SketchMapPointwiseEE8minimiseERSt6vectorIdSaIdEEMS3_FdRKS7_S8_E200
_ZN4PLMD9gridtools10GridSearchINS_6dimred18SketchMapPointwiseEEC2ERKSt6vectorIdSaIdEES9_RKS5_IjSaIjEESD_PS3_1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridSearch.h.gcov.html b/coverage/gridtools/GridSearch.h.gcov.html new file mode 100644 index 000000000000..27b5ba86d02e --- /dev/null +++ b/coverage/gridtools/GridSearch.h.gcov.html @@ -0,0 +1,187 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridSearch.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384095.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_gridtools_GridSearch_h
+      23             : #define __PLUMED_gridtools_GridSearch_h
+      24             : 
+      25             : #include "tools/MinimiseBase.h"
+      26             : #include "GridVessel.h"
+      27             : #include <iostream>
+      28             : #include <memory>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace gridtools {
+      32             : 
+      33             : template <class FCLASS>
+      34           1 : class GridSearch {
+      35             : private:
+      36             : /// This is the pointer to the member function in the energy
+      37             : /// calculating class that calculates the energy
+      38             :   typedef double(FCLASS::*engf_pointer)( const std::vector<double>& p, std::vector<double>& der );
+      39             :   FCLASS* myclass_func;
+      40             :   std::unique_ptr<GridVessel> mygrid;
+      41             :   std::unique_ptr<GridVessel> myfgrid;
+      42             : public:
+      43           1 :   GridSearch( const std::vector<double>& mmin, const std::vector<double>& mmax, const std::vector<unsigned>& ng, const std::vector<unsigned>& nfg, FCLASS* funcc ) :
+      44           1 :     myclass_func( funcc )
+      45             :   {
+      46             :     // Create the grid objects
+      47           1 :     std::string nstr, vstring="COMPONENTS=func COORDINATES=x1";
+      48           2 :     for(unsigned i=1; i<mmin.size(); ++i) { Tools::convert(i+1,nstr); vstring += ",x" + nstr; }
+      49           2 :     vstring += " PBC=F"; for(unsigned i=1; i<mmin.size(); ++i) vstring += ",F";
+      50           2 :     vesselbase::VesselOptions da("mygrid","",-1,vstring,NULL);
+      51           1 :     Keywords keys; gridtools::GridVessel::registerKeywords( keys );
+      52           1 :     vesselbase::VesselOptions dar( da, keys );
+      53           1 :     mygrid=Tools::make_unique<GridVessel>(dar);
+      54           2 :     if( nfg[0]>0 ) myfgrid=Tools::make_unique<GridVessel>(dar);
+      55             : 
+      56             :     // Now setup the min and max values for the grid
+      57           1 :     std::vector<std::string> gmin( nfg.size() ), gmax( nfg.size() ); std::vector<double> dummy_spacing;
+      58           3 :     for(unsigned i=0; i<nfg.size(); ++i) { Tools::convert(mmin[i],gmin[i]); Tools::convert(mmax[i],gmax[i]); }
+      59           1 :     mygrid->setBounds( gmin, gmax, ng, dummy_spacing ); mygrid->resize();
+      60           1 :     if( myfgrid ) myfgrid->setBounds( gmin, gmax, nfg, dummy_spacing );
+      61           2 :   }
+      62             :   bool minimise( std::vector<double>& p, engf_pointer myfunc );
+      63             : };
+      64             : 
+      65             : template <class FCLASS>
+      66         200 : bool GridSearch<FCLASS>::minimise( std::vector<double>& p, engf_pointer myfunc ) {
+      67         200 :   std::vector<double> der( p.size() ); std::vector<double> coords( p.size() );
+      68         200 :   double initial_eng = (myclass_func->*myfunc)( p, der );
+      69         200 :   mygrid->getGridPointCoordinates( 0, coords );
+      70         200 :   double emin=(myclass_func->*myfunc)( coords, der );
+      71         200 :   mygrid->setValueAndDerivatives( 0, 0, emin, der ); unsigned pmin=0;
+      72       24200 :   for(unsigned i=1; i<mygrid->getNumberOfPoints(); ++i) {
+      73       24000 :     mygrid->getGridPointCoordinates( i, coords );
+      74       24000 :     double eng = (myclass_func->*myfunc)( coords, der );
+      75       24000 :     mygrid->setValueAndDerivatives( i, 0, eng, der );
+      76       24000 :     if( eng<emin ) { emin=eng; pmin=i; }
+      77             :   }
+      78             :   // This prevents division by zero
+      79             :   mygrid->setNorm( 1.0 );
+      80             : 
+      81         200 :   if( myfgrid ) {
+      82         200 :     myfgrid->getGridPointCoordinates( 0, coords ); pmin=0;
+      83         200 :     double emin=mygrid->getValueAndDerivatives( coords, 0, der );
+      84      520200 :     for(unsigned i=1; i<myfgrid->getNumberOfPoints(); ++i) {
+      85      520000 :       myfgrid->getGridPointCoordinates( i, coords );
+      86      520000 :       double eng = mygrid->getValueAndDerivatives( coords, 0, der );
+      87      520000 :       if( eng<emin ) { emin=eng; pmin=i; }
+      88             :     }
+      89         200 :     myfgrid->getGridPointCoordinates( pmin, coords );
+      90         200 :     double checkEng = (myclass_func->*myfunc)( coords, der );
+      91         200 :     if( checkEng<initial_eng ) {
+      92          22 :       myfgrid->getGridPointCoordinates( pmin, p );
+      93             :       return true;
+      94             :     } else {
+      95             :       return false;
+      96             :     }
+      97             :   }
+      98             : 
+      99           0 :   if( emin<initial_eng ) {
+     100           0 :     mygrid->getGridPointCoordinates( pmin, p );
+     101             :     return true;
+     102             :   } else {
+     103             :     return false;
+     104             :   }
+     105             : }
+     106             : 
+     107             : }
+     108             : }
+     109             : #endif
+     110             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridToXYZ.cpp.func-sort-c.html b/coverage/gridtools/GridToXYZ.cpp.func-sort-c.html new file mode 100644 index 000000000000..4cc1f88e8fa4 --- /dev/null +++ b/coverage/gridtools/GridToXYZ.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridToXYZ.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridToXYZ.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394488.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools9GridToXYZC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools9GridToXYZC1ERKNS_13ActionOptionsE2
_ZNK4PLMD9gridtools9GridToXYZ9printGridERNS_5OFileE2
_ZN4PLMD9gridtools9GridToXYZ16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridToXYZ.cpp.func.html b/coverage/gridtools/GridToXYZ.cpp.func.html new file mode 100644 index 000000000000..07dfdb00caf1 --- /dev/null +++ b/coverage/gridtools/GridToXYZ.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridToXYZ.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridToXYZ.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394488.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools9GridToXYZ16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD9gridtools9GridToXYZC1ERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools9GridToXYZC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools9GridToXYZ9printGridERNS_5OFileE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridToXYZ.cpp.gcov.html b/coverage/gridtools/GridToXYZ.cpp.gcov.html new file mode 100644 index 000000000000..36a9b202763f --- /dev/null +++ b/coverage/gridtools/GridToXYZ.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridToXYZ.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridToXYZ.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394488.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "GridPrintingBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/OFile.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace gridtools {
+      28             : 
+      29             : //+PLUMEDOC GRIDANALYSIS GRID_TO_XYZ
+      30             : /*
+      31             : Output the function on the grid to an xyz file
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : class GridToXYZ : public GridPrintingBase {
+      39             : private:
+      40             :   double lenunit;
+      41             :   unsigned mycomp;
+      42             : public:
+      43             :   static void registerKeywords( Keywords& keys );
+      44             :   explicit GridToXYZ(const ActionOptions&ao);
+      45             :   void printGrid( OFile& ofile ) const override;
+      46             : };
+      47             : 
+      48             : PLUMED_REGISTER_ACTION(GridToXYZ,"GRID_TO_XYZ")
+      49             : 
+      50           4 : void GridToXYZ::registerKeywords( Keywords& keys ) {
+      51           4 :   GridPrintingBase::registerKeywords( keys );
+      52           8 :   keys.add("optional","COMPONENT","if your input is a vector field use this to specify the component of the input vector field for which you wish to output");
+      53           8 :   keys.add("compulsory","UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+      54           8 :   keys.add("optional", "PRECISION","The number of digits in trajectory file");
+      55           4 :   keys.remove("FMT");
+      56           4 : }
+      57             : 
+      58           2 : GridToXYZ::GridToXYZ(const ActionOptions&ao):
+      59             :   Action(ao),
+      60           2 :   GridPrintingBase(ao)
+      61             : {
+      62           2 :   if( ingrid->getDimension()!=3 ) error("cannot print grid xyz file if grid does not contain three dimensional data");
+      63           2 :   fmt = " " + fmt;
+      64             : 
+      65           2 :   if( ingrid->getNumberOfComponents()==1 ) {
+      66           2 :     mycomp=0;
+      67             :   } else {
+      68           0 :     int tcomp=-1; parse("COMPONENT",tcomp);
+      69           0 :     if( tcomp<0 ) error("component of vector field was not specified - use COMPONENT keyword");
+      70           0 :     mycomp=tcomp*(1+ingrid->getDimension()); if( ingrid->noDerivatives() ) mycomp=tcomp;
+      71           0 :     log.printf("  using %dth component of grid \n",tcomp );
+      72             :   }
+      73             :   fmt="%f";
+      74           4 :   std::string precision; parse("PRECISION",precision);
+      75           2 :   if(precision.length()>0) {
+      76           2 :     int p; Tools::convert(precision,p);
+      77           2 :     log<<"  with precision "<<p<<"\n";
+      78             :     std::string a,b;
+      79           2 :     Tools::convert(p+5,a);
+      80           2 :     Tools::convert(p,b);
+      81           4 :     fmt="%"+a+"."+b+"f";
+      82             :   }
+      83           4 :   std::string unitname; parse("UNITS",unitname);
+      84           2 :   if(unitname!="PLUMED") {
+      85           2 :     Units myunit; myunit.setLength(unitname);
+      86           2 :     lenunit=getUnits().getLength()/myunit.getLength();
+      87           2 :   }
+      88           0 :   else lenunit=1.0;
+      89           2 :   checkRead();
+      90           2 : }
+      91             : 
+      92           2 : void GridToXYZ::printGrid( OFile& ofile ) const {
+      93           2 :   std::vector<double> point( 3 );
+      94           2 :   ofile.printf("%u\n",ingrid->getNumberOfPoints());
+      95           2 :   ofile.printf("Grid converted to xyz file \n");
+      96         246 :   for(unsigned i=0; i<ingrid->getNumberOfPoints(); ++i) {
+      97         244 :     ingrid->getGridPointCoordinates( i, point );
+      98         244 :     ofile.printf("X");
+      99             :     double val;
+     100         488 :     if( ingrid->getType()=="flat" ) val=1.0;
+     101         244 :     else val=ingrid->getGridElement( i, 0 );
+     102         976 :     for(unsigned j=0; j<3; ++j) { ofile.printf( (" " + fmt).c_str(), val*lenunit*point[j] ); }
+     103         244 :     ofile.printf("\n");
+     104             :   }
+     105           2 : }
+     106             : 
+     107             : }
+     108             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.cpp.func-sort-c.html b/coverage/gridtools/GridVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..506adfc930c3 --- /dev/null +++ b/coverage/gridtools/GridVessel.cpp.func-sort-c.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31633494.6 %
Date:2024-02-22 21:58:45Functions:373994.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools10GridVessel14setGridElementERKSt6vectorIjSaIjEERKjRKd0
_ZNK4PLMD9gridtools10GridVessel14getGridElementERKSt6vectorIjSaIjEERKj0
_ZN4PLMD9gridtools10GridVessel18setupFibonacciGridERKj3
_ZN4PLMD9gridtools10GridVessel19activateThesePointsERKSt6vectorIbSaIbEE3
_ZNK4PLMD9gridtools10GridVessel12getCubeUnitsEv8
_ZN4PLMD9gridtools10GridVessel12setCubeUnitsERKd11
_ZNK4PLMD9gridtools10GridVessel14getInputStringB5cxx11Ev17
_ZN4PLMD9gridtools10GridVessel16setNoDerivativesEv19
_ZN4PLMD9gridtools10GridVessel10applyForceERSt6vectorIdSaIdEE20
_ZN4PLMD9gridtools10GridVessel8setForceERKSt6vectorIdSaIdEE20
_ZNK4PLMD9gridtools10GridVessel17getFibonacciIndexERKSt6vectorIdSaIdEE57
_ZN4PLMD9gridtools10GridVessel11descriptionB5cxx11Ev65
_ZN4PLMD9gridtools10GridVessel16registerKeywordsERNS_8KeywordsE66
_ZN4PLMD9gridtools10GridVesselC2ERKNS_10vesselbase13VesselOptionsE67
_ZN4PLMD9gridtools10GridVessel9setBoundsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESC_RKS2_IjSaIjEERKS2_IdSaIdEE98
_ZN4PLMD9gridtools10GridVessel6finishERKSt6vectorIdSaIdEE118
_ZN4PLMD9gridtools10GridVessel6resizeEv213
_ZN4PLMD9gridtools10GridVessel16addToGridElementERKjS3_RKd2605
_ZNK4PLMD9gridtools10GridVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE15087
_ZNK4PLMD9gridtools10GridVessel12getNeighborsERKSt6vectorIdSaIdEERKS2_IjSaIjEERjRS8_21514
_ZN4PLMD9gridtools10GridVessel22setValueAndDerivativesERKjS3_RKdRKSt6vectorIdSaIdEE24200
_ZNK4PLMD9gridtools10GridVessel12getNeighborsERKSt6vectorIjSaIjEES6_RjRS4_40878
_ZNK4PLMD9gridtools10GridVessel23getFibonacciCoordinatesERKjRSt6vectorIdSaIdEE86817
_ZN4PLMD9gridtools10GridVessel14setGridElementERKjS3_RKd154208
_ZNK4PLMD9gridtools10GridVessel6getMinB5cxx11Ev202520
_ZNK4PLMD9gridtools10GridVessel6getMaxB5cxx11Ev202553
_ZNK4PLMD9gridtools10GridVessel7getNbinEv203150
_ZNK4PLMD9gridtools10GridVessel18getSplineNeighborsERKjRjRSt6vectorIjSaIjEE528846
_ZNK4PLMD9gridtools10GridVessel22getValueAndDerivativesERKSt6vectorIdSaIdEERKjRS4_528846
_ZNK4PLMD9gridtools10GridVessel8getIndexERKSt6vectorIdSaIdEE530957
_ZNK4PLMD9gridtools10GridVessel23getGridPointCoordinatesERKjRSt6vectorIdSaIdEE665380
_ZNK4PLMD9gridtools10GridVessel10getIndicesERKSt6vectorIdSaIdEERS2_IjSaIjEE1060391
_ZNK4PLMD9gridtools10GridVessel14getGridElementERKjS3_6552681
_ZNK4PLMD9gridtools10GridVessel9wasForcedEv11870273
_ZNK4PLMD9gridtools10GridVessel23getGridPointCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE12514073
_ZNK4PLMD9gridtools10GridVessel22getFlatGridCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE13037802
_ZNK4PLMD9gridtools10GridVessel10getIndicesERKjRSt6vectorIjSaIjEE15879029
_ZNK4PLMD9gridtools10GridVessel8getIndexERKSt6vectorIjSaIjEE24333386
_ZNK4PLMD9gridtools10GridVessel21convertIndexToIndicesERKjRKSt6vectorIjSaIjEERS6_112427827
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.cpp.func.html b/coverage/gridtools/GridVessel.cpp.func.html new file mode 100644 index 000000000000..d94573b16ca3 --- /dev/null +++ b/coverage/gridtools/GridVessel.cpp.func.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31633494.6 %
Date:2024-02-22 21:58:45Functions:373994.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools10GridVessel10applyForceERSt6vectorIdSaIdEE20
_ZN4PLMD9gridtools10GridVessel11descriptionB5cxx11Ev65
_ZN4PLMD9gridtools10GridVessel12setCubeUnitsERKd11
_ZN4PLMD9gridtools10GridVessel14setGridElementERKSt6vectorIjSaIjEERKjRKd0
_ZN4PLMD9gridtools10GridVessel14setGridElementERKjS3_RKd154208
_ZN4PLMD9gridtools10GridVessel16addToGridElementERKjS3_RKd2605
_ZN4PLMD9gridtools10GridVessel16registerKeywordsERNS_8KeywordsE66
_ZN4PLMD9gridtools10GridVessel16setNoDerivativesEv19
_ZN4PLMD9gridtools10GridVessel18setupFibonacciGridERKj3
_ZN4PLMD9gridtools10GridVessel19activateThesePointsERKSt6vectorIbSaIbEE3
_ZN4PLMD9gridtools10GridVessel22setValueAndDerivativesERKjS3_RKdRKSt6vectorIdSaIdEE24200
_ZN4PLMD9gridtools10GridVessel6finishERKSt6vectorIdSaIdEE118
_ZN4PLMD9gridtools10GridVessel6resizeEv213
_ZN4PLMD9gridtools10GridVessel8setForceERKSt6vectorIdSaIdEE20
_ZN4PLMD9gridtools10GridVessel9setBoundsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESC_RKS2_IjSaIjEERKS2_IdSaIdEE98
_ZN4PLMD9gridtools10GridVesselC2ERKNS_10vesselbase13VesselOptionsE67
_ZNK4PLMD9gridtools10GridVessel10getIndicesERKSt6vectorIdSaIdEERS2_IjSaIjEE1060391
_ZNK4PLMD9gridtools10GridVessel10getIndicesERKjRSt6vectorIjSaIjEE15879029
_ZNK4PLMD9gridtools10GridVessel12getCubeUnitsEv8
_ZNK4PLMD9gridtools10GridVessel12getNeighborsERKSt6vectorIdSaIdEERKS2_IjSaIjEERjRS8_21514
_ZNK4PLMD9gridtools10GridVessel12getNeighborsERKSt6vectorIjSaIjEES6_RjRS4_40878
_ZNK4PLMD9gridtools10GridVessel14getGridElementERKSt6vectorIjSaIjEERKj0
_ZNK4PLMD9gridtools10GridVessel14getGridElementERKjS3_6552681
_ZNK4PLMD9gridtools10GridVessel14getInputStringB5cxx11Ev17
_ZNK4PLMD9gridtools10GridVessel17getFibonacciIndexERKSt6vectorIdSaIdEE57
_ZNK4PLMD9gridtools10GridVessel18getSplineNeighborsERKjRjRSt6vectorIjSaIjEE528846
_ZNK4PLMD9gridtools10GridVessel21convertIndexToIndicesERKjRKSt6vectorIjSaIjEERS6_112427827
_ZNK4PLMD9gridtools10GridVessel22getFlatGridCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE13037802
_ZNK4PLMD9gridtools10GridVessel22getValueAndDerivativesERKSt6vectorIdSaIdEERKjRS4_528846
_ZNK4PLMD9gridtools10GridVessel23getFibonacciCoordinatesERKjRSt6vectorIdSaIdEE86817
_ZNK4PLMD9gridtools10GridVessel23getGridPointCoordinatesERKjRSt6vectorIdSaIdEE665380
_ZNK4PLMD9gridtools10GridVessel23getGridPointCoordinatesERKjRSt6vectorIjSaIjEERS4_IdSaIdEE12514073
_ZNK4PLMD9gridtools10GridVessel6getMaxB5cxx11Ev202553
_ZNK4PLMD9gridtools10GridVessel6getMinB5cxx11Ev202520
_ZNK4PLMD9gridtools10GridVessel7getNbinEv203150
_ZNK4PLMD9gridtools10GridVessel8getIndexERKSt6vectorIdSaIdEE530957
_ZNK4PLMD9gridtools10GridVessel8getIndexERKSt6vectorIjSaIjEE24333386
_ZNK4PLMD9gridtools10GridVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE15087
_ZNK4PLMD9gridtools10GridVessel9wasForcedEv11870273
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.cpp.gcov.html b/coverage/gridtools/GridVessel.cpp.gcov.html new file mode 100644 index 000000000000..0369f7b26af2 --- /dev/null +++ b/coverage/gridtools/GridVessel.cpp.gcov.html @@ -0,0 +1,603 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31633494.6 %
Date:2024-02-22 21:58:45Functions:373994.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "GridVessel.h"
+      23             : #include "vesselbase/ActionWithVessel.h"
+      24             : #include "tools/Random.h"
+      25             : #include "tools/Tools.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace gridtools {
+      29             : 
+      30          66 : void GridVessel::registerKeywords( Keywords& keys ) {
+      31          66 :   AveragingVessel::registerKeywords( keys );
+      32         132 :   keys.add("compulsory","TYPE","flat","how the grid points are being generated");
+      33         132 :   keys.add("compulsory","COMPONENTS","the names of the components in the vector");
+      34         132 :   keys.add("compulsory","COORDINATES","the names of the coordinates of the grid");
+      35         132 :   keys.add("compulsory","PBC","is the grid periodic in each direction or not");
+      36          66 : }
+      37             : 
+      38          67 : GridVessel::GridVessel( const vesselbase::VesselOptions& da ):
+      39             :   AveragingVessel(da),
+      40          67 :   bounds_set(false),
+      41          67 :   npoints(0),
+      42          67 :   cube_units(1.0),
+      43          67 :   wasforced(false),
+      44          67 :   noderiv(false)
+      45             : {
+      46         134 :   std::string geom; parse("TYPE",geom);
+      47          67 :   if( geom=="flat" ) gtype=flat;
+      48           3 :   else if( geom=="fibonacci" ) gtype=fibonacci;
+      49           0 :   else plumed_merror( geom + " is invalid geometry type");
+      50         134 :   std::vector<std::string> compnames; parseVector("COMPONENTS",compnames);
+      51          67 :   std::vector<std::string> coordnames; parseVector("COORDINATES",coordnames);
+      52          67 :   if( gtype==flat ) {
+      53          64 :     dimension=coordnames.size();
+      54          64 :     str_min.resize( dimension);  str_max.resize( dimension ); stride.resize( dimension );
+      55          64 :     max.resize( dimension ); dx.resize( dimension ); nbin.resize( dimension ); min.resize( dimension );
+      56           3 :   } else if( gtype==fibonacci ) {
+      57           3 :     if( coordnames.size()!=3 ) error("cannot generate fibonacci grid points on surface of sphere if not 3 input coordinates");
+      58           3 :     dimension=3;
+      59             :   }
+      60             : 
+      61          67 :   unsigned n=0; nper=compnames.size()*( 1 + coordnames.size() );
+      62          67 :   arg_names.resize( coordnames.size() + compnames.size()*( 1 + coordnames.size() ) );
+      63         169 :   for(unsigned i=0; i<coordnames.size(); ++i) { arg_names[n] = coordnames[i]; n++; }
+      64         135 :   for(unsigned i=0; i<compnames.size(); ++i) {
+      65          68 :     arg_names[n]=compnames[i]; n++;
+      66         172 :     for(unsigned j=0; j<coordnames.size(); ++j) { arg_names[n] = "d" + compnames[i] + "_" + coordnames[j]; n++; }
+      67             :   }
+      68          67 :   pbc.resize( dimension );
+      69          67 :   std::vector<std::string> spbc( dimension ); parseVector("PBC",spbc);
+      70         169 :   for(unsigned i=0; i<dimension; ++i) {
+      71         102 :     if( spbc[i]=="F" ) pbc[i]=false;
+      72          31 :     else if( spbc[i]=="T" ) pbc[i]=true;
+      73           0 :     else plumed_error();
+      74             :   }
+      75         134 : }
+      76             : 
+      77          19 : void GridVessel::setNoDerivatives() {
+      78          19 :   nper = ( nper/(1+dimension) ); noderiv=true;
+      79          19 :   std::vector<std::string> tnames( dimension ), cnames(nper);
+      80          41 :   for(unsigned i=0; i<dimension; ++i) tnames[i]=arg_names[i];
+      81          38 :   unsigned k=dimension; for(unsigned i=0; i<nper; ++i) { cnames[i]=arg_names[k]; k+=(1+dimension); }
+      82          19 :   arg_names.resize( dimension + nper );
+      83          41 :   for(unsigned i=0; i<dimension; ++i) arg_names[i]=tnames[i];
+      84          38 :   for(unsigned i=0; i<nper; ++i) arg_names[dimension+i]=cnames[i];
+      85          19 : }
+      86             : 
+      87          98 : void GridVessel::setBounds( const std::vector<std::string>& smin, const std::vector<std::string>& smax,
+      88             :                             const std::vector<unsigned>& binsin, const std::vector<double>& spacing ) {
+      89             :   plumed_dbg_assert( smin.size()==dimension && smax.size()==dimension );
+      90          98 :   plumed_assert( gtype==flat && (spacing.size()==dimension || binsin.size()==dimension) );
+      91             : 
+      92          98 :   npoints=1; bounds_set=true;
+      93         245 :   for(unsigned i=0; i<dimension; ++i) {
+      94         147 :     str_min[i]=smin[i]; str_max[i]=smax[i];
+      95             :     // GB: I ignore the result here not to break test multicolvar/rt-dens-average
+      96             :     // where these functions were called with str_min[i] and str_max[i] as empty string
+      97             :     // To be checked.
+      98         147 :     Tools::convertNoexcept( str_min[i], min[i] );
+      99         147 :     Tools::convertNoexcept( str_max[i], max[i] );
+     100             : 
+     101         147 :     if( spacing.size()==dimension && binsin.size()==dimension ) {
+     102          39 :       if( spacing[i]==0 ) nbin[i] = binsin[i];
+     103             :       else {
+     104          37 :         double range = max[i] - min[i]; nbin[i] = std::round( range / spacing[i]);
+     105             :         // This check ensures that nbins is set correctly if spacing is set the same as the number of bins
+     106          37 :         if( nbin[i]!=binsin[i] ) plumed_merror("mismatch between input spacing and input number of bins");
+     107             :       }
+     108         108 :     } else if( binsin.size()==dimension ) nbin[i]=binsin[i];
+     109           0 :     else if( spacing.size()==dimension ) nbin[i] = std::floor(( max[i] - min[i] ) / spacing[i]) + 1;
+     110           0 :     else plumed_error();
+     111         147 :     dx[i] = ( max[i] - min[i] ) / static_cast<double>( nbin[i] );
+     112         147 :     if( !pbc[i] ) { max[i] +=dx[i]; nbin[i]+=1; }
+     113         147 :     stride[i]=npoints;
+     114         147 :     npoints*=nbin[i];
+     115             :   }
+     116          98 :   resize();  // Always resize after setting new bounds as grid size may have have changed
+     117          98 : }
+     118             : 
+     119           3 : void GridVessel::setupFibonacciGrid( const unsigned& np ) {
+     120           3 :   bounds_set=true; root5 = std::sqrt(5);
+     121           3 :   npoints = np; golden = ( 1 + std::sqrt(5) ) / 2.0; igolden = golden - 1;
+     122           3 :   fib_increment = 2*pi*igolden; log_golden2 = std::log( golden*golden );
+     123           3 :   fib_offset = 2 / static_cast<double>( npoints );
+     124           3 :   fib_shift = fib_offset/2 - 1;
+     125           3 :   resize();
+     126             : 
+     127           3 :   std::vector<double> icoord( dimension ), jcoord( dimension );
+     128             :   // Find minimum distance between each pair of points
+     129           3 :   std::vector<double> mindists( npoints );
+     130         347 :   for(unsigned i=0; i<npoints; ++i) {
+     131         344 :     getFibonacciCoordinates( i, icoord ); mindists[i] = 0;
+     132       41080 :     for(unsigned j=0; j<npoints; ++j) {
+     133       40736 :       if( i==j ) continue ; // Points are not neighbors to themselves
+     134       40392 :       getFibonacciCoordinates( j, jcoord );
+     135             :       // Calculate the dot product
+     136      161568 :       double dot=0; for(unsigned k=0; k<dimension; ++k) dot += icoord[k]*jcoord[k];
+     137       40392 :       if( dot>mindists[i] ) mindists[i]=dot;
+     138             :     }
+     139             :   }
+     140             :   // And now take minimum of dot products
+     141           3 :   double min=mindists[0];
+     142         344 :   for(unsigned i=1; i<npoints; ++i) {
+     143         341 :     if( mindists[i]<min ) min=mindists[i];
+     144             :   }
+     145             :   double final_cutoff;
+     146           3 :   if( getFibonacciCutoff()<-1 ) final_cutoff=-1;
+     147           2 :   else final_cutoff = std::cos( std::acos( getFibonacciCutoff() ) + std::acos( min ) );
+     148             : 
+     149             :   // And now construct the neighbor list
+     150           3 :   fib_nlist.resize( npoints );
+     151         347 :   for(unsigned i=0; i<npoints; ++i) {
+     152         344 :     getFibonacciCoordinates( i, icoord );
+     153       41080 :     for(unsigned j=0; j<npoints; ++j) {
+     154       40736 :       if( i==j ) continue ; // Points are not neighbors to themselves
+     155       40392 :       getFibonacciCoordinates( j, jcoord );
+     156             :       // Calculate the dot product
+     157      161568 :       double dot=0; for(unsigned k=0; k<dimension; ++k) dot += icoord[k]*jcoord[k];
+     158       40392 :       if( dot>final_cutoff ) { fib_nlist[i].push_back(j); }
+     159             :     }
+     160             :   }
+     161           3 : }
+     162             : 
+     163          65 : std::string GridVessel::description() {
+     164          65 :   if( !bounds_set ) return "";
+     165             : 
+     166             :   std::string des;
+     167          51 :   if( gtype==flat ) {
+     168             :     des="grid of "; std::string num;
+     169          68 :     for(unsigned i=0; i<dimension-1; ++i) {
+     170          19 :       Tools::convert( nbin[i], num );
+     171          38 :       des += num + " X ";
+     172             :     }
+     173          49 :     Tools::convert( nbin[dimension-1], num );
+     174          49 :     des += num + " equally spaced points between (";
+     175          68 :     for(unsigned i=0; i<dimension-1; ++i) des += str_min[i] + ",";
+     176          49 :     Tools::convert( nbin[dimension-1], num );
+     177          49 :     des += str_min[dimension-1] + ") and (";
+     178          68 :     for(unsigned i=0; i<dimension-1; ++i) des += str_max[i] + ",";
+     179          98 :     des += str_max[dimension-1] + ")";
+     180           2 :   } else if( gtype==fibonacci ) {
+     181           2 :     std::string num; Tools::convert( npoints, num );
+     182           4 :     des += "fibonacci grid of " + num + " points on spherical surface";
+     183             :   }
+     184             :   return des;
+     185             : }
+     186             : 
+     187         213 : void GridVessel::resize() {
+     188         213 :   plumed_massert( nper>0, "Number of datapoints at each grid point has not been set");
+     189         213 :   if( getAction() ) resizeBuffer( getNumberOfBufferPoints()*nper + 1 + 2*getAction()->getNumberOfDerivatives() );
+     190         213 :   setDataSize( npoints*nper ); forces.resize( npoints );
+     191         213 :   if( active.size()!=npoints) active.resize( npoints, true );
+     192         213 : }
+     193             : 
+     194    24333386 : unsigned GridVessel::getIndex( const std::vector<unsigned>& indices ) const {
+     195             :   plumed_dbg_assert( gtype==flat && bounds_set && indices.size()==dimension );
+     196             :   // indices are flattended using a column-major order
+     197    24333386 :   unsigned index=indices[dimension-1];
+     198    69887444 :   for(unsigned i=dimension-1; i>0; --i) {
+     199    45554058 :     index=index*nbin[i-1]+indices[i-1];
+     200             :   }
+     201    24333386 :   return index;
+     202             : }
+     203             : 
+     204     1060391 : void GridVessel::getIndices( const std::vector<double>& point, std::vector<unsigned>& indices ) const {
+     205             :   plumed_dbg_assert( gtype==flat && bounds_set && point.size()==dimension && indices.size()==dimension );
+     206     3196142 :   for(unsigned i=0; i<dimension; ++i) {
+     207     2135751 :     indices[i]=std::floor( (point[i] - min[i])/dx[i] );
+     208     2135751 :     if( pbc[i] ) indices[i]=indices[i]%nbin[i];
+     209     2090227 :     else if( indices[i]>nbin[i] ) {
+     210           0 :       std::string pp, num; Tools::convert( point[0], pp );
+     211           0 :       for(unsigned j=1; j<point.size(); ++j) { Tools::convert( point[j], num ); pp += ", " + num; }
+     212           0 :       plumed_merror("point (" + pp + ")  is outside grid range");
+     213             :     }
+     214             :   }
+     215     1060391 : }
+     216             : 
+     217      530957 : unsigned GridVessel::getIndex( const std::vector<double>& point ) const {
+     218             :   plumed_dbg_assert( gtype==flat && bounds_set && point.size()==dimension );
+     219      530957 :   if( gtype==flat ) {
+     220      530957 :     std::vector<unsigned> indices(dimension); getIndices( point, indices );
+     221      530957 :     return getIndex( indices );
+     222           0 :   } else if( gtype==fibonacci ) {
+     223           0 :     return getFibonacciIndex( point );
+     224             :   } else {
+     225           0 :     plumed_error();
+     226             :   }
+     227             : }
+     228             : 
+     229          57 : unsigned GridVessel::getFibonacciIndex( const std::vector<double>& p ) const {
+     230             :   plumed_dbg_assert( gtype==fibonacci );
+     231             :   // Convert input point to coordinates on cylinder
+     232          57 :   int k=2; double phi = std::atan2( p[2], p[0] ), sinthet2 = 1 - p[1]*p[1];
+     233             :   // Calculate power to raise golden ratio
+     234          57 :   if( sinthet2<epsilon ) { k = 2; }
+     235             :   else {
+     236          57 :     k = std::floor( std::log( npoints*pi*root5*sinthet2 ) / log_golden2 );
+     237             :     if( k<2 ) k = 2;
+     238             :   }
+     239          57 :   double Fk = pow( golden, k ) / root5, F0 = std::round(Fk), F1 = std::round(Fk*golden);
+     240          57 :   Matrix<double> B(2,2), invB(2,2); std::vector<double> thisp(3);
+     241          57 :   B(0,0) = 2*pi*((F0+1)*igolden - std::floor((F0+1)*igolden)) - fib_increment;
+     242          57 :   B(0,1) = 2*pi*((F1+1)*igolden - std::floor((F1+1)*igolden)) - fib_increment;
+     243          57 :   B(1,0) = -2*F0/npoints; B(1,1) = -2*F1/npoints; Invert( B, invB );
+     244          57 :   std::vector<double> vv(2), rc(2); vv[0]=-phi; vv[1] = p[1] - fib_shift;
+     245          57 :   mult( invB, vv, rc ); std::vector<int> c(2); c[0]=std::floor(rc[0]); c[1]=std::floor(rc[1]);
+     246             :   unsigned outind=0; double mindist = 10000000.;
+     247         285 :   for(int s=0; s<4; ++s) {
+     248         228 :     double ttt, costheta = B(1,0)*( c[0] + s%2 ) + B(1,1)*( c[1] + s/2 ) + fib_shift;
+     249         228 :     if( costheta>1 ) ttt=1; else if( costheta<-1 ) ttt=-1; else ttt=costheta;
+     250         228 :     costheta = 2*ttt - costheta;
+     251         228 :     unsigned i = std::floor( 0.5*npoints*(1+costheta) ); getFibonacciCoordinates( i, thisp );
+     252         912 :     double dist=0; for(unsigned j=0; j<3; ++j) { double tmp=thisp[j]-p[j]; dist += tmp*tmp; }
+     253         228 :     if( dist<mindist ) { outind = i; mindist = dist; }
+     254             :   }
+     255          57 :   return outind;
+     256             : }
+     257             : 
+     258   112427827 : void GridVessel::convertIndexToIndices( const unsigned& index, const std::vector<unsigned>& nnbin, std::vector<unsigned>& indices ) const {
+     259   112427827 :   plumed_dbg_assert( gtype==flat ); unsigned kk=index; indices[0]=index%nnbin[0];
+     260   220890781 :   for(unsigned i=1; i<dimension-1; ++i) {
+     261   108462954 :     kk=(kk-indices[i-1])/nnbin[i-1];
+     262   108462954 :     indices[i]=kk%nnbin[i];
+     263             :   }
+     264   112427827 :   if(dimension>=2) { // I think this is wrong
+     265   112411320 :     indices[dimension-1]=(kk-indices[dimension-2])/nnbin[dimension-2];
+     266             :   }
+     267   112427827 : }
+     268             : 
+     269    15879029 : void GridVessel::getIndices( const unsigned& index, std::vector<unsigned>& indices ) const {
+     270    15879029 :   plumed_dbg_assert( gtype==flat ); convertIndexToIndices( index, nbin, indices );
+     271    15879029 : }
+     272             : 
+     273      665380 : void GridVessel::getGridPointCoordinates( const unsigned& ipoint, std::vector<double>& x ) const {
+     274      665380 :   std::vector<unsigned> tindices( dimension ); getGridPointCoordinates( ipoint, tindices, x );
+     275      665380 : }
+     276             : 
+     277    12514073 : void GridVessel::getGridPointCoordinates( const unsigned& ipoint, std::vector<unsigned>& tindices, std::vector<double>& x ) const {
+     278             :   plumed_dbg_assert( bounds_set && x.size()==dimension && tindices.size()==dimension && ipoint<npoints );
+     279    12514073 :   if( gtype==flat ) {
+     280    12508956 :     getFlatGridCoordinates( ipoint, tindices, x );
+     281        5117 :   } else if( gtype==fibonacci ) {
+     282        5117 :     getFibonacciCoordinates( ipoint, x );
+     283             :   } else {
+     284           0 :     plumed_error();
+     285             :   }
+     286    12514073 : }
+     287             : 
+     288    13037802 : void GridVessel::getFlatGridCoordinates( const unsigned& ipoint, std::vector<unsigned>& tindices, std::vector<double>& x ) const {
+     289    13037802 :   plumed_dbg_assert( gtype==flat ); getIndices( ipoint, tindices );
+     290    50950449 :   for(unsigned i=0; i<dimension; ++i) x[i] = min[i] + dx[i]*tindices[i];
+     291    13037802 : }
+     292             : 
+     293       86817 : void GridVessel::getFibonacciCoordinates( const unsigned& ipoint, std::vector<double>& x ) const {
+     294             :   plumed_dbg_assert( gtype==fibonacci );
+     295       86817 :   x[1] = (ipoint*fib_offset) + fib_shift; double r = std::sqrt( 1 - x[1]*x[1] );
+     296       86817 :   double phi = ipoint*fib_increment; x[0] = r*std::cos(phi); x[2] = r*std::sin(phi);
+     297      347268 :   double norm=0; for(unsigned j=0; j<3; ++j) norm+=x[j]*x[j];
+     298      347268 :   norm = std::sqrt(norm); for(unsigned j=0; j<3; ++j) x[j] = x[j] / norm;
+     299       86817 : }
+     300             : 
+     301      528846 : void GridVessel::getSplineNeighbors( const unsigned& mybox, unsigned& nneighbors, std::vector<unsigned>& mysneigh ) const {
+     302      528846 :   plumed_dbg_assert( gtype==flat ); unsigned nneigh=unsigned(pow(2.0,int(dimension)));
+     303      528846 :   if( mysneigh.size()!=nneigh ) mysneigh.resize(nneigh);
+     304             : 
+     305      528846 :   unsigned inind; nneighbors = 0;
+     306      528846 :   std::vector<unsigned> tmp_indices( dimension );
+     307      528846 :   std::vector<unsigned> my_indices( dimension );
+     308      528846 :   getIndices( mybox, my_indices );
+     309     2677614 :   for(unsigned i=0; i<nneigh; ++i) {
+     310             :     unsigned tmp=i; inind=0;
+     311     6513472 :     for(unsigned j=0; j<dimension; ++j) {
+     312     4364704 :       unsigned i0=tmp%2+my_indices[j]; tmp/=2;
+     313     4364704 :       if(!pbc[j] && i0==nbin[j]) continue;
+     314     4323904 :       if( pbc[j] && i0==nbin[j]) i0=0;
+     315     4323904 :       tmp_indices[inind++]=i0;
+     316             :     }
+     317     2148768 :     if(inind==dimension ) {
+     318     2108168 :       unsigned findex=getIndex( tmp_indices );
+     319     2108168 :       mysneigh[nneighbors++]=findex;
+     320     2108168 :       plumed_massert( active[findex], "inactive grid point required for splines");
+     321             :     }
+     322             :   }
+     323      528846 : }
+     324             : 
+     325     6552681 : double GridVessel::getGridElement( const unsigned& ipoint, const unsigned& jelement ) const {
+     326    13105362 :   plumed_assert( bounds_set && ipoint<npoints && jelement<nper && active[ipoint] );
+     327     6552681 :   return getDataElement( nper*ipoint + jelement  );
+     328             : }
+     329             : 
+     330      154208 : void GridVessel::setGridElement( const unsigned& ipoint, const unsigned& jelement, const double& value ) {
+     331             :   plumed_dbg_assert( bounds_set && ipoint<npoints && jelement<nper );
+     332      154208 :   setDataElement( nper*ipoint + jelement, value );
+     333      154208 : }
+     334             : 
+     335       24200 : void GridVessel::setValueAndDerivatives( const unsigned& ipoint, const unsigned& jelement, const double& value, const std::vector<double>& der ) {
+     336             :   plumed_dbg_assert( !noderiv && jelement<getNumberOfComponents() && der.size()==nbin.size() );
+     337       72600 :   setGridElement( ipoint, jelement, value ); for(unsigned i=0; i<der.size(); ++i) setGridElement( ipoint, jelement+1+i, der[i] );
+     338       24200 : }
+     339             : 
+     340        2605 : void GridVessel::addToGridElement( const unsigned& ipoint, const unsigned& jelement, const double& value ) {
+     341             :   plumed_dbg_assert( bounds_set && ipoint<npoints && jelement<nper );
+     342        2605 :   addDataElement( nper*ipoint + jelement, value );
+     343        2605 : }
+     344             : 
+     345       15087 : void GridVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+     346             :   plumed_dbg_assert( myvals.getNumberOfValues()==(nper+1) );
+     347       65138 :   for(unsigned i=0; i<nper; ++i) buffer[bufstart + nper*current + i] += myvals.get(i+1);
+     348       15087 : }
+     349             : 
+     350         118 : void GridVessel::finish( const std::vector<double>& buffer ) {
+     351         118 :   if( wasforced ) getFinalForces( buffer, finalForces );
+     352          98 :   else AveragingVessel::finish( buffer );
+     353         118 : }
+     354             : 
+     355           0 : double GridVessel::getGridElement( const std::vector<unsigned>& indices, const unsigned& jelement ) const {
+     356           0 :   return getGridElement( getIndex( indices ), jelement );
+     357             : }
+     358             : 
+     359           0 : void GridVessel::setGridElement( const std::vector<unsigned>& indices, const unsigned& jelement, const double& value ) {
+     360           0 :   setGridElement( getIndex( indices ), jelement, value );
+     361           0 : }
+     362             : 
+     363      202520 : std::vector<std::string> GridVessel::getMin() const {
+     364      202520 :   plumed_dbg_assert( gtype==flat ); return str_min;
+     365             : }
+     366             : 
+     367      202553 : std::vector<std::string> GridVessel::getMax() const {
+     368      202553 :   plumed_dbg_assert( gtype==flat ); return str_max;
+     369             : }
+     370             : 
+     371      203150 : std::vector<unsigned> GridVessel::getNbin() const {
+     372             :   plumed_dbg_assert( gtype==flat && bounds_set );
+     373      203150 :   std::vector<unsigned> ngrid( dimension );
+     374      605377 :   for(unsigned i=0; i<dimension; ++i) {
+     375      402227 :     if( !pbc[i] ) ngrid[i]=nbin[i] - 1;
+     376       34200 :     else ngrid[i]=nbin[i];
+     377             :   }
+     378      203150 :   return ngrid;
+     379             : }
+     380             : 
+     381       21514 : void GridVessel::getNeighbors( const std::vector<double>& pp, const std::vector<unsigned>& nneigh,
+     382             :                                unsigned& num_neighbors, std::vector<unsigned>& neighbors ) const {
+     383             :   plumed_dbg_assert( bounds_set );
+     384             : 
+     385       21514 :   if( gtype == flat ) {
+     386             :     plumed_dbg_assert( nneigh.size()==dimension );
+     387       21457 :     std::vector<unsigned> indices( dimension );
+     388       85340 :     for(unsigned i=0; i<dimension; ++i) indices[i] = std::floor( (pp[i]-min[i])/dx[i] );
+     389       21457 :     getNeighbors( indices, nneigh, num_neighbors, neighbors );
+     390          57 :   } else if( gtype == fibonacci ) {
+     391          57 :     unsigned find = getFibonacciIndex( pp );
+     392          57 :     num_neighbors = 1 + fib_nlist[find].size();
+     393          57 :     if( neighbors.size()<num_neighbors ) neighbors.resize( num_neighbors );
+     394        4773 :     neighbors[0]=find; for(unsigned i=0; i<fib_nlist[find].size(); ++i) neighbors[1+i] = fib_nlist[find][i];
+     395             :   } else {
+     396           0 :     plumed_error();
+     397             :   }
+     398       21514 : }
+     399             : 
+     400       40878 : void GridVessel::getNeighbors( const std::vector<unsigned>& indices, const std::vector<unsigned>& nneigh,
+     401             :                                unsigned& num_neighbors, std::vector<unsigned>& neighbors ) const {
+     402             :   plumed_dbg_assert( gtype==flat && bounds_set && nneigh.size()==dimension );
+     403             : 
+     404       40878 :   unsigned num_neigh=1; std::vector<unsigned> small_bin( dimension );
+     405      163024 :   for(unsigned i=0; i<dimension; ++i) {
+     406      122146 :     small_bin[i]=(2*nneigh[i]+1);
+     407      122146 :     num_neigh *=small_bin[i];
+     408             :   }
+     409       40878 :   if( neighbors.size()!=num_neigh ) neighbors.resize( num_neigh );
+     410             : 
+     411       40878 :   num_neighbors=0;
+     412       40878 :   std::vector<unsigned> s_indices(dimension), t_indices(dimension);
+     413    96589676 :   for(unsigned index=0; index<num_neigh; ++index) {
+     414             :     bool found=true;
+     415    96548798 :     convertIndexToIndices( index, small_bin, s_indices );
+     416   386166232 :     for(unsigned i=0; i<dimension; ++i) {
+     417   289617434 :       int i0=s_indices[i]-nneigh[i]+indices[i];
+     418   289617434 :       if(!pbc[i] && i0<0)        found=false;
+     419   289617434 :       if(!pbc[i] && i0>=nbin[i]) found=false;
+     420   289617434 :       if( pbc[i] && i0<0)        i0=nbin[i]-(-i0)%nbin[i];
+     421   289617434 :       if( pbc[i] && i0>=nbin[i]) i0%=nbin[i];
+     422   289617434 :       t_indices[i]=static_cast<unsigned>(i0);
+     423             :     }
+     424    96548798 :     if( found ) {
+     425    21093803 :       neighbors[num_neighbors]=getIndex( t_indices );
+     426    21093803 :       num_neighbors++;
+     427             :     }
+     428             :   }
+     429       40878 : }
+     430             : 
+     431          11 : void GridVessel::setCubeUnits( const double& units ) {
+     432          11 :   plumed_dbg_assert( gtype==flat ); cube_units=units;
+     433          11 : }
+     434             : 
+     435           8 : double GridVessel::getCubeUnits() const {
+     436           8 :   plumed_dbg_assert( gtype==flat ); return cube_units;
+     437             : }
+     438             : 
+     439          17 : std::string GridVessel::getInputString() const {
+     440          17 :   std::string mstring="COORDINATES="+arg_names[0];
+     441          23 :   for(unsigned i=1; i<dimension; ++i) mstring+="," + arg_names[i];
+     442          17 :   if( gtype==flat ) {
+     443             :     mstring += " TYPE=flat PBC=";
+     444          17 :     if( pbc[0] ) mstring +="T";
+     445             :     else mstring +="F";
+     446          23 :     for(unsigned i=1; i<dimension; ++i) {
+     447           6 :       if( pbc[i] ) mstring +=",T";
+     448             :       else mstring +=",F";
+     449             :     }
+     450           0 :   } else if( gtype==fibonacci ) {
+     451             :     mstring += " TYPE=fibonacci";
+     452             :   }
+     453          17 :   return mstring;
+     454             : }
+     455             : 
+     456      528846 : double GridVessel::getValueAndDerivatives( const std::vector<double>& x, const unsigned& ind, std::vector<double>& der ) const {
+     457             :   plumed_dbg_assert( gtype==flat && der.size()==dimension && !noderiv && ind<getNumberOfComponents() );
+     458             : 
+     459      528846 :   double X,X2,X3,value=0; der.assign(der.size(),0.0);
+     460      528846 :   std::vector<double> fd(dimension);
+     461      528846 :   std::vector<double> C(dimension);
+     462      528846 :   std::vector<double> D(dimension);
+     463      528846 :   std::vector<double> dder(dimension);
+     464             : 
+     465      528846 :   std::vector<unsigned> nindices(dimension); unsigned n_neigh;
+     466      528846 :   std::vector<unsigned> indices(dimension); getIndices( x, indices );
+     467      528846 :   std::vector<unsigned> neigh; getSplineNeighbors( getIndex(indices), n_neigh, neigh );
+     468      528846 :   std::vector<double> xfloor(dimension); getFlatGridCoordinates( getIndex(x), nindices, xfloor );
+     469             : 
+     470             : // loop over neighbors
+     471     2637014 :   for(unsigned int ipoint=0; ipoint<n_neigh; ++ipoint) {
+     472     2108168 :     double grid=getGridElement(neigh[ipoint], ind*(1+dimension) );
+     473     6391672 :     for(unsigned j=0; j<dimension; ++j) dder[j] = getGridElement( neigh[ipoint], ind*(1+dimension) + 1 + j );
+     474             : 
+     475     2108168 :     getIndices( neigh[ipoint], nindices );
+     476             :     double ff=1.0;
+     477             : 
+     478     6391672 :     for(unsigned j=0; j<dimension; ++j) {
+     479             :       int x0=1;
+     480     4283504 :       if(nindices[j]==indices[j]) x0=0;
+     481     4283504 :       double ddx=dx[j];
+     482     4283504 :       X=std::fabs((x[j]-xfloor[j])/ddx-(double)x0);
+     483     4283504 :       X2=X*X;
+     484     4283504 :       X3=X2*X;
+     485             :       double yy;
+     486     4283504 :       if(std::fabs(grid)<0.0000001) yy=0.0;
+     487     4269657 :       else yy=-dder[j]/grid;
+     488     6445456 :       C[j]=(1.0-3.0*X2+2.0*X3) - (x0?-1.0:1.0)*yy*(X-2.0*X2+X3)*ddx;
+     489     4283504 :       D[j]=( -6.0*X +6.0*X2) - (x0?-1.0:1.0)*yy*(1.0-4.0*X +3.0*X2)*ddx;
+     490     4283504 :       D[j]*=(x0?-1.0:1.0)/ddx;
+     491     4283504 :       ff*=C[j];
+     492             :     }
+     493     6391672 :     for(unsigned j=0; j<dimension; ++j) {
+     494     4283504 :       fd[j]=D[j];
+     495    13052816 :       for(unsigned i=0; i<dimension; ++i) if(i!=j) fd[j]*=C[i];
+     496             :     }
+     497     2108168 :     value+=grid*ff;
+     498     6391672 :     for(unsigned j=0; j<dimension; ++j) der[j]+=grid*fd[j];
+     499             :   }
+     500      528846 :   return value;
+     501             : }
+     502             : 
+     503           3 : void GridVessel::activateThesePoints( const std::vector<bool>& to_activate ) {
+     504             :   plumed_dbg_assert( to_activate.size()==npoints );
+     505       29991 :   for(unsigned i=0; i<npoints; ++i) active[i]=to_activate[i];
+     506           3 : }
+     507             : 
+     508          20 : void GridVessel::setForce( const std::vector<double>& inforces ) {
+     509             :   plumed_dbg_assert( inforces.size()==npoints );
+     510        5725 :   wasforced=true; for(unsigned i=0; i<npoints; ++i) forces[i]=inforces[i];
+     511          20 : }
+     512             : 
+     513    11870273 : bool GridVessel::wasForced() const {
+     514    11870273 :   return wasforced;
+     515             : }
+     516             : 
+     517          20 : bool GridVessel::applyForce( std::vector<double>& fforces ) {
+     518             :   plumed_dbg_assert( fforces.size()==finalForces.size() );
+     519          20 :   if( !wasforced ) return false;
+     520        3815 :   for(unsigned i=0; i<finalForces.size(); ++i) fforces[i]=finalForces[i];
+     521          20 :   wasforced=false; return true;
+     522             : }
+     523             : 
+     524             : }
+     525             : }
+     526             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.h.func-sort-c.html b/coverage/gridtools/GridVessel.h.func-sort-c.html new file mode 100644 index 000000000000..f12e25e993a6 --- /dev/null +++ b/coverage/gridtools/GridVessel.h.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:252889.3 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools10GridVessel14getFinalForcesERKSt6vectorIdSaIdEERS4_0
_ZNK4PLMD9gridtools10GridVessel18getFibonacciCutoffEv2
_ZNK4PLMD9gridtools10GridVessel13getCellVolumeEv4
_ZNK4PLMD9gridtools10GridVessel21getNumberOfComponentsEv47
_ZNK4PLMD9gridtools10GridVessel23getNumberOfBufferPointsEv71
_ZNK4PLMD9gridtools10GridVessel14getGridSpacingEv611
_ZNK4PLMD9gridtools10GridVessel7getTypeB5cxx11Ev26251
_ZNK4PLMD9gridtools10GridVessel8inactiveERKj21151408
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.h.func.html b/coverage/gridtools/GridVessel.h.func.html new file mode 100644 index 000000000000..09bc816e413d --- /dev/null +++ b/coverage/gridtools/GridVessel.h.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:252889.3 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools10GridVessel14getFinalForcesERKSt6vectorIdSaIdEERS4_0
_ZNK4PLMD9gridtools10GridVessel13getCellVolumeEv4
_ZNK4PLMD9gridtools10GridVessel14getGridSpacingEv611
_ZNK4PLMD9gridtools10GridVessel18getFibonacciCutoffEv2
_ZNK4PLMD9gridtools10GridVessel21getNumberOfComponentsEv47
_ZNK4PLMD9gridtools10GridVessel23getNumberOfBufferPointsEv71
_ZNK4PLMD9gridtools10GridVessel7getTypeB5cxx11Ev26251
_ZNK4PLMD9gridtools10GridVessel8inactiveERKj21151408
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/GridVessel.h.gcov.html b/coverage/gridtools/GridVessel.h.gcov.html new file mode 100644 index 000000000000..749431c61fbb --- /dev/null +++ b/coverage/gridtools/GridVessel.h.gcov.html @@ -0,0 +1,364 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/GridVessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - GridVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:252889.3 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_gridtools_GridVessel_h
+      23             : #define __PLUMED_gridtools_GridVessel_h
+      24             : 
+      25             : #include <string>
+      26             : #include <cstring>
+      27             : #include <vector>
+      28             : #include "vesselbase/AveragingVessel.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace gridtools {
+      32             : 
+      33             : class GridVessel : public vesselbase::AveragingVessel {
+      34             :   friend class ActionWithInputGrid;
+      35             :   friend class DumpGrid;
+      36             : private:
+      37             : /// The way that grid points are constructed
+      38             :   enum {flat,fibonacci} gtype;
+      39             : /// Have the minimum and maximum for the grid been set
+      40             :   bool bounds_set;
+      41             : /// The number of points in the grid
+      42             :   unsigned npoints;
+      43             : /// Stuff for fibonacci grids
+      44             :   double root5, golden, igolden, log_golden2;
+      45             : /// Fib increment here is equal to 2*pi*(INVERSE GOLDEN RATIO)
+      46             :   double fib_offset, fib_increment, fib_shift;
+      47             :   std::vector<std::vector<unsigned> > fib_nlist;
+      48             : /// Units for Gaussian Cube file
+      49             :   double cube_units;
+      50             : /// This flag is used to check if the user has created a valid input
+      51             :   bool foundprint;
+      52             : /// The minimum and maximum of the grid stored as doubles
+      53             :   std::vector<double> min, max;
+      54             : /// The numerical distance between adjacent grid points
+      55             :   std::vector<unsigned> stride;
+      56             : /// The number of bins in each grid direction
+      57             :   std::vector<unsigned> nbin;
+      58             : /// The grid point that was requested last by getGridPointCoordinates
+      59             :   unsigned currentGridPoint;
+      60             : /// The forces that will be output at the end of the calculation
+      61             :   std::vector<double> finalForces;
+      62             : protected:
+      63             : /// Is forced
+      64             :   bool wasforced;
+      65             : /// Forces acting on grid elements
+      66             :   std::vector<double> forces;
+      67             : /// Do we have derivatives
+      68             :   bool noderiv;
+      69             : /// The names of the various columns in the grid file
+      70             :   std::vector<std::string> arg_names;
+      71             : /// The number of pieces of information we are storing for each
+      72             : /// point in the grid
+      73             :   unsigned nper;
+      74             : /// Is this direction periodic
+      75             :   std::vector<bool> pbc;
+      76             : /// The minimum and maximum in the grid stored as strings
+      77             :   std::vector<std::string> str_min, str_max;
+      78             : /// The spacing between grid points
+      79             :   std::vector<double> dx;
+      80             : /// The dimensionality of the grid
+      81             :   unsigned dimension;
+      82             : /// Which grid points are we actively accumulating
+      83             :   std::vector<bool> active;
+      84             : /// Convert a point in space the the correspoinding grid point
+      85             :   unsigned getIndex( const std::vector<double>& p ) const ;
+      86             : /// Get the index of the closest point on the fibonacci sphere
+      87             :   unsigned getFibonacciIndex( const std::vector<double>& p ) const ;
+      88             : /// Get the flat grid coordinates
+      89             :   void getFlatGridCoordinates( const unsigned& ipoint, std::vector<unsigned>& tindices, std::vector<double>& x ) const ;
+      90             : /// Get the coordinates on the Fibonacci grid
+      91             :   void getFibonacciCoordinates( const unsigned& ipoint, std::vector<double>& x ) const ;
+      92             : public:
+      93             : /// keywords
+      94             :   static void registerKeywords( Keywords& keys );
+      95             : /// Constructor
+      96             :   explicit GridVessel( const vesselbase::VesselOptions& );
+      97             : /// Remove the derivatives
+      98             :   void setNoDerivatives();
+      99             : /// Get the type of grid we are using
+     100             :   std::string getType() const ;
+     101             : /// Set the minimum and maximum of the grid
+     102             :   virtual void setBounds( const std::vector<std::string>& smin, const std::vector<std::string>& smax, const std::vector<unsigned>& nbins, const std::vector<double>& spacing );
+     103             : /// Get the cutoff to use for the Fibonacci spheres
+     104             :   virtual double getFibonacciCutoff() const ;
+     105             : /// Setup the grid if it is a fibonacci grid on the surface of a sphere
+     106             :   void setupFibonacciGrid( const unsigned& np );
+     107             : /// Get a description of the grid to output to the log
+     108             :   std::string description() override;
+     109             : /// Convert an index into indices
+     110             :   void convertIndexToIndices( const unsigned& index, const std::vector<unsigned>& nnbin, std::vector<unsigned>& indices ) const ;
+     111             : ///  Flatten the grid and get the grid index for a point
+     112             :   unsigned getIndex( const std::vector<unsigned>& indices ) const ;
+     113             : /// Get the indices fof a point
+     114             :   void getIndices( const unsigned& index, std::vector<unsigned>& indices ) const ;
+     115             : /// Get the indices of a particular point
+     116             :   void getIndices( const std::vector<double>& point, std::vector<unsigned>& indices ) const ;
+     117             : /// Operations on one of the elements of grid point i
+     118             :   void setGridElement( const unsigned&, const unsigned&, const double& );
+     119             : /// Add data to an element of the grid
+     120             :   void addToGridElement( const unsigned& ipoint, const unsigned& jelement, const double& value );
+     121             : /// Operations on one of the elements of grid point specified by vector
+     122             :   double getGridElement( const std::vector<unsigned>&, const unsigned& ) const ;
+     123             :   void setGridElement( const std::vector<unsigned>&, const unsigned&, const double& );
+     124             : /// Set the values and derivatives of a particular element
+     125             :   void setValueAndDerivatives( const unsigned&, const unsigned&, const double&, const std::vector<double>& );
+     126             : /// Set the size of the buffer equal to nper*npoints
+     127             :   void resize() override;
+     128             : /// Get the number of points in the grid
+     129             :   unsigned getNumberOfPoints() const;
+     130             : /// Get the coordinates for a point in the grid
+     131             :   void getGridPointCoordinates( const unsigned&, std::vector<double>& ) const ;
+     132             :   void getGridPointCoordinates( const unsigned&, std::vector<unsigned>&, std::vector<double>& ) const ;
+     133             : /// Get the dimensionality of the function
+     134             :   unsigned getDimension() const ;
+     135             : /// Get the number of components in the vector stored on each grid point
+     136             :   virtual unsigned getNumberOfComponents() const ;
+     137             : /// Is the grid periodic in the ith direction
+     138             :   bool isPeriodic( const unsigned& i ) const ;
+     139             : /// Get the number of quantities we have stored at each grid point
+     140             :   unsigned getNumberOfQuantities() const ;
+     141             : /// Get the number of grid points for each dimension
+     142             :   std::vector<unsigned> getNbin() const ;
+     143             : /// Get the name of the ith component
+     144             :   std::string getComponentName( const unsigned& i ) const ;
+     145             : /// Get the vector containing the minimum value of the grid in each dimension
+     146             :   std::vector<std::string> getMin() const ;
+     147             : /// Get the vector containing the maximum value of the grid in each dimension
+     148             :   std::vector<std::string> getMax() const ;
+     149             : /// Get the number of points needed in the buffer
+     150             :   virtual unsigned getNumberOfBufferPoints() const ;
+     151             : /// Get the stride (the distance between the grid points of an index)
+     152             :   const std::vector<unsigned>& getStride() const ;
+     153             : /// Return the volume of one of the grid cells
+     154             :   double getCellVolume() const ;
+     155             : /// Get the value of the ith grid element
+     156             :   virtual double getGridElement( const unsigned&, const unsigned& ) const ;
+     157             : /// Get the set of points neighouring a particular location in space
+     158             :   void getNeighbors( const std::vector<double>& pp, const std::vector<unsigned>& nneigh,
+     159             :                      unsigned& num_neighbours, std::vector<unsigned>& neighbors ) const ;
+     160             : /// Get the neighbors for a set of indices of a point
+     161             :   void getNeighbors( const std::vector<unsigned>& indices, const std::vector<unsigned>& nneigh,
+     162             :                      unsigned& num_neighbors, std::vector<unsigned>& neighbors ) const ;
+     163             : /// Get the points neighboring a particular spline point
+     164             :   void getSplineNeighbors( const unsigned& mybox, unsigned& nneighbors, std::vector<unsigned>& mysneigh ) const ;
+     165             : /// Get the spacing between grid points
+     166             :   const std::vector<double>& getGridSpacing() const ;
+     167             : /// Get the extent of the grid in one of the axis
+     168             :   double getGridExtent( const unsigned& i ) const ;
+     169             : /// Copy data from the action into the grid
+     170             :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const override;
+     171             : /// Finish the calculation
+     172             :   void finish( const std::vector<double>& buffer ) override;
+     173             : /// This ensures that Gaussian cube fies are in correct units
+     174             :   void setCubeUnits( const double& units );
+     175             : /// This ensures that Gaussian cube files are in correct units
+     176             :   double getCubeUnits() const ;
+     177             : /// Return a string containing the input to the grid so we can clone it
+     178             :   std::string getInputString() const ;
+     179             : /// Does this have derivatives
+     180             :   bool noDerivatives() const ;
+     181             : /// Get the value and derivatives at a particular location using spline interpolation
+     182             :   double getValueAndDerivatives( const std::vector<double>& x, const unsigned& ind, std::vector<double>& der ) const ;
+     183             : /// Deactivate all the grid points
+     184             :   void activateThesePoints( const std::vector<bool>& to_activate );
+     185             : /// Is this point active
+     186             :   bool inactive( const unsigned& ip ) const ;
+     187             : /// This retrieves the final force
+     188           0 :   virtual void getFinalForces( const std::vector<double>& buffer, std::vector<double>& finalForces ) { plumed_error(); }
+     189             : /// Apply the forces
+     190             :   void setForce( const std::vector<double>& inforces );
+     191             : /// Was a force added to the grid
+     192             :   bool wasForced() const ;
+     193             : /// And retrieve the forces
+     194             :   bool applyForce( std::vector<double>& fforces ) override;
+     195             : };
+     196             : 
+     197             : inline
+     198             : unsigned GridVessel::getNumberOfQuantities() const {
+     199      440217 :   return nper;
+     200             : }
+     201             : 
+     202             : inline
+     203             : unsigned GridVessel::getNumberOfPoints() const {
+     204      873010 :   return npoints;
+     205             : }
+     206             : 
+     207             : inline
+     208         611 : const std::vector<double>& GridVessel::getGridSpacing() const {
+     209         611 :   if( gtype==flat ) return dx;
+     210           0 :   plumed_merror("dont understand what spacing means for spherical grids");
+     211             : }
+     212             : 
+     213             : inline
+     214           4 : double GridVessel::getCellVolume() const {
+     215           4 :   if( gtype==flat ) {
+     216           8 :     double myvol=1.0; for(unsigned i=0; i<dimension; ++i) myvol *= dx[i];
+     217             :     return myvol;
+     218             :   } else {
+     219           1 :     return 4*pi / static_cast<double>( getNumberOfPoints() );
+     220             :   }
+     221             : }
+     222             : 
+     223             : inline
+     224             : unsigned GridVessel::getDimension() const {
+     225      938454 :   return dimension;
+     226             : }
+     227             : 
+     228             : inline
+     229             : bool GridVessel::isPeriodic( const unsigned& i ) const {
+     230             :   plumed_dbg_assert( gtype==flat );
+     231        7859 :   return pbc[i];
+     232             : }
+     233             : 
+     234             : inline
+     235             : std::string GridVessel::getComponentName( const unsigned& i ) const {
+     236     1012634 :   return arg_names[i];
+     237             : }
+     238             : 
+     239             : inline
+     240          47 : unsigned GridVessel::getNumberOfComponents() const {
+     241          47 :   if( noderiv ) return nper;
+     242          32 :   return nper / ( dimension + 1 );
+     243             : }
+     244             : 
+     245             : inline
+     246             : double GridVessel::getGridExtent( const unsigned& i ) const {
+     247             :   plumed_dbg_assert( gtype==flat );
+     248          40 :   return max[i] - min[i];
+     249             : }
+     250             : 
+     251             : inline
+     252             : bool GridVessel::noDerivatives() const {
+     253       14312 :   return noderiv;
+     254             : }
+     255             : 
+     256             : inline
+     257    21151408 : bool GridVessel::inactive( const unsigned& ip ) const {
+     258             :   plumed_dbg_assert( ip<npoints );
+     259    21151408 :   return !active[ip];
+     260             : }
+     261             : 
+     262             : inline
+     263             : const std::vector<unsigned>& GridVessel::getStride() const {
+     264             :   plumed_dbg_assert( gtype==flat );
+     265             :   return stride;
+     266             : }
+     267             : 
+     268             : inline
+     269          71 : unsigned GridVessel::getNumberOfBufferPoints() const {
+     270         321 :   return npoints;
+     271             : }
+     272             : 
+     273             : inline
+     274       26251 : std::string GridVessel::getType() const {
+     275       26251 :   if( gtype==flat ) return "flat";
+     276         422 :   else if( gtype==fibonacci ) return "fibonacci";
+     277           0 :   plumed_error();
+     278             : }
+     279             : 
+     280             : inline
+     281           2 : double GridVessel::getFibonacciCutoff() const {
+     282           2 :   return 0.0;
+     283             : }
+     284             : 
+     285             : }
+     286             : }
+     287             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.cpp.func-sort-c.html b/coverage/gridtools/HistogramOnGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..b8bf71dfefe8 --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/HistogramOnGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - HistogramOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools15HistogramOnGrid18getFibonacciCutoffEv3
_ZNK4PLMD9gridtools15HistogramOnGrid17noDiscreteKernelsEv19
_ZN4PLMD9gridtools15HistogramOnGrid14getFinalForcesERKSt6vectorIdSaIdEERS4_20
_ZN4PLMD9gridtools15HistogramOnGridC2ERKNS_10vesselbase13VesselOptionsE45
_ZN4PLMD9gridtools15HistogramOnGrid9setBoundsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESC_RKS2_IjSaIjEERKS2_IdSaIdEE50
_ZN4PLMD9gridtools15HistogramOnGrid16registerKeywordsERNS_8KeywordsE65
_ZN4PLMD9gridtools15HistogramOnGrid6finishERKSt6vectorIdSaIdEE156
_ZNK4PLMD9gridtools15HistogramOnGrid15accumulateForceERKjRKdRKSt6vectorIdSaIdEERS8_5744
_ZNK4PLMD9gridtools15HistogramOnGrid21getKernelAndNeighborsERSt6vectorIdSaIdEERjRS2_IjSaIjEE23625
_ZNK4PLMD9gridtools15HistogramOnGrid9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE38461
_ZNK4PLMD9gridtools15HistogramOnGrid10accumulateERKjRKdS5_RKSt6vectorIdSaIdEERS8_40596
_ZNK4PLMD9gridtools15HistogramOnGrid17getVectorOfValuesEv57812
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.cpp.func.html b/coverage/gridtools/HistogramOnGrid.cpp.func.html new file mode 100644 index 000000000000..eb6f30ce2590 --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/HistogramOnGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - HistogramOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15HistogramOnGrid14getFinalForcesERKSt6vectorIdSaIdEERS4_20
_ZN4PLMD9gridtools15HistogramOnGrid16registerKeywordsERNS_8KeywordsE65
_ZN4PLMD9gridtools15HistogramOnGrid6finishERKSt6vectorIdSaIdEE156
_ZN4PLMD9gridtools15HistogramOnGrid9setBoundsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESC_RKS2_IjSaIjEERKS2_IdSaIdEE50
_ZN4PLMD9gridtools15HistogramOnGridC2ERKNS_10vesselbase13VesselOptionsE45
_ZNK4PLMD9gridtools15HistogramOnGrid10accumulateERKjRKdS5_RKSt6vectorIdSaIdEERS8_40596
_ZNK4PLMD9gridtools15HistogramOnGrid15accumulateForceERKjRKdRKSt6vectorIdSaIdEERS8_5744
_ZNK4PLMD9gridtools15HistogramOnGrid17getVectorOfValuesEv57812
_ZNK4PLMD9gridtools15HistogramOnGrid17noDiscreteKernelsEv19
_ZNK4PLMD9gridtools15HistogramOnGrid18getFibonacciCutoffEv3
_ZNK4PLMD9gridtools15HistogramOnGrid21getKernelAndNeighborsERSt6vectorIdSaIdEERjRS2_IjSaIjEE23625
_ZNK4PLMD9gridtools15HistogramOnGrid9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE38461
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.cpp.gcov.html b/coverage/gridtools/HistogramOnGrid.cpp.gcov.html new file mode 100644 index 000000000000..17c96814e300 --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.cpp.gcov.html @@ -0,0 +1,292 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/HistogramOnGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - HistogramOnGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "HistogramOnGrid.h"
+      23             : #include "tools/KernelFunctions.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace gridtools {
+      27             : 
+      28          65 : void HistogramOnGrid::registerKeywords( Keywords& keys ) {
+      29          65 :   GridVessel::registerKeywords( keys );
+      30         130 :   keys.add("compulsory","KERNEL","the type of kernel to use");
+      31         130 :   keys.add("compulsory","BANDWIDTH","the bandwidths");
+      32         130 :   keys.add("compulsory","CONCENTRATION","the concentration parameter for Von Mises-Fisher distributions");
+      33          65 : }
+      34             : 
+      35          45 : HistogramOnGrid::HistogramOnGrid( const vesselbase::VesselOptions& da ):
+      36             :   GridVessel(da),
+      37          45 :   neigh_tot(0),
+      38          45 :   addOneKernelAtATime(false),
+      39          45 :   bandwidths(dimension),
+      40          45 :   discrete(false)
+      41             : {
+      42          90 :   if( getType()=="flat" ) {
+      43          86 :     parse("KERNEL",kerneltype);
+      44          86 :     if( kerneltype=="discrete" || kerneltype=="DISCRETE" ) {
+      45          10 :       discrete=true; setNoDerivatives();
+      46             :     } else {
+      47          66 :       parseVector("BANDWIDTH",bandwidths);
+      48             :     }
+      49             :   } else {
+      50           2 :     parse("CONCENTRATION",von_misses_concentration);
+      51           2 :     von_misses_norm = von_misses_concentration / ( 4*pi*sinh( von_misses_concentration ) );
+      52             :   }
+      53          45 : }
+      54             : 
+      55           3 : double HistogramOnGrid::getFibonacciCutoff() const {
+      56           3 :   return std::log( epsilon / von_misses_norm ) / von_misses_concentration;
+      57             : }
+      58             : 
+      59          19 : bool HistogramOnGrid::noDiscreteKernels() const {
+      60          19 :   return !discrete;
+      61             : }
+      62             : 
+      63          50 : void HistogramOnGrid::setBounds( const std::vector<std::string>& smin, const std::vector<std::string>& smax,
+      64             :                                  const std::vector<unsigned>& nbins, const std::vector<double>& spacing ) {
+      65          50 :   GridVessel::setBounds( smin, smax, nbins, spacing );
+      66          50 :   if( !discrete ) {
+      67          40 :     std::vector<double> point(dimension,0);
+      68          40 :     KernelFunctions kernel( point, bandwidths, kerneltype, "DIAGONAL", 1.0 ); neigh_tot=1;
+      69          80 :     nneigh=kernel.getSupport( dx ); std::vector<double> support( kernel.getContinuousSupport() );
+      70         103 :     for(unsigned i=0; i<dimension; ++i) {
+      71          63 :       if( pbc[i] && 2*support[i]>getGridExtent(i) ) error("bandwidth is too large for periodic grid");
+      72          63 :       neigh_tot *= (2*nneigh[i]+1);
+      73             :     }
+      74             :   }
+      75          50 : }
+      76             : 
+      77       23625 : std::unique_ptr<KernelFunctions> HistogramOnGrid::getKernelAndNeighbors( std::vector<double>& point, unsigned& num_neigh, std::vector<unsigned>& neighbors ) const {
+      78       23625 :   if( discrete ) {
+      79        4222 :     plumed_assert( getType()=="flat" );
+      80        4222 :     num_neigh=1; for(unsigned i=0; i<dimension; ++i) point[i] += 0.5*dx[i];
+      81        2111 :     neighbors[0] = getIndex( point ); return NULL;
+      82       43028 :   } else if( getType()=="flat" ) {
+      83       21457 :     auto kernel=Tools::make_unique<KernelFunctions>( point, bandwidths, kerneltype, "DIAGONAL", 1.0 );
+      84             : // GB: Now values is destroyed when exiting this function.
+      85             : // I think before there was a leak
+      86       21457 :     std::vector<std::unique_ptr<Value>> values=getVectorOfValues();
+      87       64371 :     kernel->normalize( Tools::unique2raw(values) ); getNeighbors( kernel->getCenter(), nneigh, num_neigh, neighbors );
+      88             :     return kernel;
+      89       21571 :   } else if( getType()=="fibonacci" ) {
+      90          57 :     getNeighbors( point, nneigh, num_neigh, neighbors );
+      91             :     return NULL;
+      92             :   } else {
+      93           0 :     plumed_error();
+      94             :   }
+      95             :   return NULL;
+      96             : }
+      97             : 
+      98      115624 : std::vector<std::unique_ptr<Value>> HistogramOnGrid::getVectorOfValues() const {
+      99             :   std::vector<std::unique_ptr<Value>> vv;
+     100      225230 :   for(unsigned i=0; i<dimension; ++i) {
+     101      167418 :     vv.emplace_back(Tools::make_unique<Value>());
+     102      167418 :     if( pbc[i] ) vv[i]->setDomain( str_min[i], str_max[i] );
+     103       64454 :     else vv[i]->setNotPeriodic();
+     104             :   }
+     105       57812 :   return vv;
+     106           0 : }
+     107             : 
+     108       38461 : void HistogramOnGrid::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+     109       38461 :   if( addOneKernelAtATime ) {
+     110             :     plumed_dbg_assert( myvals.getNumberOfValues()==2 && !wasforced );
+     111       14908 :     std::vector<double> der( dimension );
+     112       54492 :     for(unsigned i=0; i<dimension; ++i) der[i]=myvals.getDerivative( 1, i );
+     113       14908 :     accumulate( getAction()->getPositionInCurrentTaskList(current), myvals.get(0), myvals.get(1), der, buffer );
+     114             :   } else {
+     115             :     plumed_dbg_assert( myvals.getNumberOfValues()==dimension+2 );
+     116       23553 :     std::vector<double> point( dimension ); double weight=myvals.get(0)*myvals.get( 1+dimension );
+     117       89610 :     for(unsigned i=0; i<dimension; ++i) point[i]=myvals.get( 1+i );
+     118             :     // Get the kernel
+     119       23553 :     unsigned num_neigh; std::vector<unsigned> neighbors(1);
+     120       23553 :     std::vector<double> der( dimension );
+     121       23553 :     std::unique_ptr<KernelFunctions> kernel=getKernelAndNeighbors( point, num_neigh, neighbors );
+     122             : 
+     123       27879 :     if( !kernel && getType()=="flat" ) {
+     124        2106 :       plumed_dbg_assert( num_neigh==1 ); der.resize(0);
+     125        2106 :       accumulate( neighbors[0], weight, 1.0, der, buffer );
+     126             :     } else {
+     127             :       double totwforce=0.0;
+     128       21447 :       std::vector<double> intforce( 2*dimension, 0.0 );
+     129       21447 :       std::vector<std::unique_ptr<Value>> vv( getVectorOfValues() );
+     130             : 
+     131       21447 :       double newval; std::vector<unsigned> tindices( dimension ); std::vector<double> xx( dimension );
+     132    20582512 :       for(unsigned i=0; i<num_neigh; ++i) {
+     133    20561065 :         unsigned ineigh=neighbors[i];
+     134    20561065 :         if( inactive( ineigh ) ) continue ;
+     135    11848693 :         getGridPointCoordinates( ineigh, tindices, xx );
+     136    11848693 :         if( kernel ) {
+     137    47354528 :           for(unsigned j=0; j<dimension; ++j) vv[j]->set(xx[j]);
+     138    11843920 :           newval = kernel->evaluate( Tools::unique2raw(vv), der, true );
+     139             :         } else {
+     140             :           // Evalulate dot product
+     141       19092 :           double dot=0; for(unsigned j=0; j<dimension; ++j) { dot+=xx[j]*point[j]; der[j]=xx[j]; }
+     142             :           // Von misses distribution for concentration parameter
+     143        4773 :           newval = von_misses_norm*exp( von_misses_concentration*dot );
+     144             :           // And final derivatives
+     145       19092 :           for(unsigned j=0; j<dimension; ++j) der[j] *= von_misses_concentration*newval;
+     146             :         }
+     147    11848693 :         accumulate( ineigh, weight, newval, der, buffer );
+     148    11848693 :         if( wasForced() ) {
+     149        5744 :           accumulateForce( ineigh, weight, der, intforce );
+     150        5744 :           totwforce += myvals.get( 1+dimension )*newval*forces[ineigh];
+     151             :         }
+     152             :       }
+     153       21447 :       if( wasForced() ) {
+     154             :         // Minus sign for kernel here as we are taking derivative with respect to position of center of
+     155             :         // kernel NOT derivative wrt to grid point
+     156         110 :         double pref = 1; if( kernel ) pref = -1;
+     157         110 :         unsigned nder = getAction()->getNumberOfDerivatives();
+     158         110 :         unsigned gridbuf = getNumberOfBufferPoints()*getNumberOfQuantities();
+     159         300 :         for(unsigned j=0; j<dimension; ++j) {
+     160       33940 :           for(unsigned k=0; k<myvals.getNumberActive(); ++k) {
+     161             :             unsigned kder=myvals.getActiveIndex(k);
+     162       33750 :             buffer[ bufstart + gridbuf + kder ] += pref*intforce[j]*myvals.getDerivative( j+1, kder );
+     163             :           }
+     164             :         }
+     165             :         // Accumulate the sum of all the weights
+     166         110 :         buffer[ bufstart + gridbuf + nder ] += myvals.get(0);
+     167             :         // Add the derivatives of the weights into the force -- this is separate loop as weights of all parts are considered together
+     168       32060 :         for(unsigned k=0; k<myvals.getNumberActive(); ++k) {
+     169             :           unsigned kder=myvals.getActiveIndex(k);
+     170       31950 :           buffer[ bufstart + gridbuf + kder ] += totwforce*myvals.getDerivative( 0, kder );
+     171       31950 :           buffer[ bufstart + gridbuf + nder + 1 + kder ] += myvals.getDerivative( 0, kder );
+     172             :         }
+     173             :       }
+     174       21447 :     }
+     175       23553 :   }
+     176       38461 : }
+     177             : 
+     178       40596 : void HistogramOnGrid::accumulate( const unsigned& ipoint, const double& weight, const double& dens, const std::vector<double>& der, std::vector<double>& buffer ) const {
+     179       40596 :   buffer[bufstart+nper*ipoint] += weight*dens;
+     180      168672 :   if( der.size()>0 ) for(unsigned j=0; j<dimension; ++j) buffer[bufstart+nper*ipoint + 1 + j] += weight*der[j];
+     181       40596 : }
+     182             : 
+     183        5744 : void HistogramOnGrid::accumulateForce( const unsigned& ipoint, const double& weight, const std::vector<double>& der, std::vector<double>& intforce ) const {
+     184       18414 :   for(unsigned j=0; j<der.size(); ++j) intforce[j] += forces[ipoint]*weight*der[j];
+     185        5744 : }
+     186             : 
+     187          20 : void HistogramOnGrid::getFinalForces( const std::vector<double>& buffer, std::vector<double>& finalForces ) {
+     188          20 :   if( finalForces.size()!=getAction()->getNumberOfDerivatives() ) finalForces.resize( getAction()->getNumberOfDerivatives() );
+     189             :   // And the final force
+     190          20 :   unsigned nder = getAction()->getNumberOfDerivatives();
+     191             :   // Derivatives due to normalization
+     192          20 :   unsigned gridbuf = getNumberOfBufferPoints()*getNumberOfQuantities();
+     193        3815 :   for(unsigned i=0; i<finalForces.size(); ++i) finalForces[i] = buffer[ bufstart + gridbuf + i ];
+     194             :   // Derivatives due to normalization
+     195          20 :   if( !noAverage() ) {
+     196          15 :     unsigned wderstart = bufstart + gridbuf + nder; double pref=0;
+     197        3620 :     for(unsigned ipoint=0; ipoint<getNumberOfPoints(); ++ipoint) {
+     198        3605 :       pref += forces[ipoint]*buffer[ bufstart + ipoint*nper ] / buffer[wderstart];
+     199             :     }
+     200        3570 :     for(unsigned j=0; j<finalForces.size(); ++j) finalForces[j] -= pref*buffer[ wderstart + 1 + j ];
+     201             :   }
+     202          20 : }
+     203             : 
+     204         156 : void HistogramOnGrid::finish( const std::vector<double>& buffer ) {
+     205         156 :   if( addOneKernelAtATime ) {
+     206       14975 :     for(unsigned i=0; i<getAction()->getCurrentNumberOfActiveTasks(); ++i) {
+     207       69400 :       for(unsigned j=0; j<nper; ++j) addDataElement( nper*getAction()->getActiveTask(i)+j, buffer[bufstart+i*nper+j] );
+     208             :     }
+     209             :   } else {
+     210          89 :     GridVessel::finish( buffer );
+     211             :   }
+     212         156 : }
+     213             : 
+     214             : }
+     215             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.h.func-sort-c.html b/coverage/gridtools/HistogramOnGrid.h.func-sort-c.html new file mode 100644 index 000000000000..64155a6fa262 --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/HistogramOnGrid.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - HistogramOnGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools15HistogramOnGrid23getNumberOfBufferPointsEv269
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.h.func.html b/coverage/gridtools/HistogramOnGrid.h.func.html new file mode 100644 index 000000000000..ab65b9e6333d --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/HistogramOnGrid.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - HistogramOnGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9gridtools15HistogramOnGrid23getNumberOfBufferPointsEv269
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/HistogramOnGrid.h.gcov.html b/coverage/gridtools/HistogramOnGrid.h.gcov.html new file mode 100644 index 000000000000..b460ea4a0461 --- /dev/null +++ b/coverage/gridtools/HistogramOnGrid.h.gcov.html @@ -0,0 +1,148 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/HistogramOnGrid.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - HistogramOnGrid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_gridtools_HistogramOnGrid_h
+      23             : #define __PLUMED_gridtools_HistogramOnGrid_h
+      24             : 
+      25             : #include "GridVessel.h"
+      26             : #include <memory>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : class KernelFunctions;
+      31             : 
+      32             : namespace gridtools {
+      33             : 
+      34             : class HistogramOnGrid : public GridVessel {
+      35             : private:
+      36             :   unsigned neigh_tot;
+      37             :   bool addOneKernelAtATime;
+      38             :   std::string kerneltype;
+      39             :   std::vector<double> bandwidths;
+      40             :   std::vector<unsigned> nneigh;
+      41             : protected:
+      42             :   bool discrete;
+      43             : public:
+      44             :   double  von_misses_norm;
+      45             :   double von_misses_concentration;
+      46             :   static void registerKeywords( Keywords& keys );
+      47             :   explicit HistogramOnGrid( const vesselbase::VesselOptions& da );
+      48             :   void setBounds( const std::vector<std::string>& smin, const std::vector<std::string>& smax,
+      49             :                   const std::vector<unsigned>& nbins, const std::vector<double>& spacing ) override;
+      50             :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const override;
+      51             :   void finish( const std::vector<double>& buffer ) override;
+      52             :   virtual void accumulate( const unsigned& ipoint, const double& weight, const double& dens, const std::vector<double>& der, std::vector<double>& buffer ) const ;
+      53             :   virtual void accumulateForce( const unsigned& ipoint, const double& weight, const std::vector<double>& der, std::vector<double>& intforce ) const ;
+      54             :   unsigned getNumberOfBufferPoints() const override;
+      55             :   std::unique_ptr<KernelFunctions> getKernelAndNeighbors( std::vector<double>& point, unsigned& num_neigh, std::vector<unsigned>& neighbors ) const;
+      56             :   std::vector<std::unique_ptr<Value>> getVectorOfValues() const ;
+      57          19 :   void addOneKernelEachTimeOnly() { addOneKernelAtATime=true; }
+      58             :   void getFinalForces( const std::vector<double>& buffer, std::vector<double>& finalForces ) override;
+      59             :   bool noDiscreteKernels() const ;
+      60             :   double getFibonacciCutoff() const override;
+      61             : };
+      62             : 
+      63             : inline
+      64         269 : unsigned HistogramOnGrid::getNumberOfBufferPoints() const {
+      65         269 :   if( addOneKernelAtATime ) return neigh_tot;
+      66         250 :   return GridVessel::getNumberOfBufferPoints();
+      67             : }
+      68             : 
+      69             : }
+      70             : }
+      71             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/IntegrateGrid.cpp.func-sort-c.html b/coverage/gridtools/IntegrateGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..f8e8d9a54b56 --- /dev/null +++ b/coverage/gridtools/IntegrateGrid.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/IntegrateGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - IntegrateGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13IntegrateGridC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools13IntegrateGridC1ERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools13IntegrateGrid16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD9gridtools13IntegrateGrid7computeERKjRNS_10MultiValueE5705
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/IntegrateGrid.cpp.func.html b/coverage/gridtools/IntegrateGrid.cpp.func.html new file mode 100644 index 000000000000..fda7b910b942 --- /dev/null +++ b/coverage/gridtools/IntegrateGrid.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/IntegrateGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - IntegrateGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools13IntegrateGrid16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD9gridtools13IntegrateGridC1ERKNS_13ActionOptionsE4
_ZN4PLMD9gridtools13IntegrateGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools13IntegrateGrid7computeERKjRNS_10MultiValueE5705
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/IntegrateGrid.cpp.gcov.html b/coverage/gridtools/IntegrateGrid.cpp.gcov.html new file mode 100644 index 000000000000..c9b026f22deb --- /dev/null +++ b/coverage/gridtools/IntegrateGrid.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/IntegrateGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - IntegrateGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "ActionWithIntegral.h"
+      24             : 
+      25             : //+PLUMEDOC GRIDANALYSIS INTEGRATE_GRID
+      26             : /*
+      27             : Calculate the total integral of the function on the input grid
+      28             : 
+      29             : \par Examples
+      30             : 
+      31             : */
+      32             : //+ENDPLUMEDOC
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace gridtools {
+      36             : 
+      37             : class IntegrateGrid : public ActionWithIntegral {
+      38             : public:
+      39             :   static void registerKeywords( Keywords& keys );
+      40             :   explicit IntegrateGrid(const ActionOptions&ao);
+      41             :   void compute( const unsigned& current, MultiValue& myvals ) const override;
+      42             : };
+      43             : 
+      44             : PLUMED_REGISTER_ACTION(IntegrateGrid,"INTEGRATE_GRID")
+      45             : 
+      46           6 : void IntegrateGrid::registerKeywords( Keywords& keys ) {
+      47           6 :   ActionWithIntegral::registerKeywords( keys );
+      48           6 : }
+      49             : 
+      50           4 : IntegrateGrid::IntegrateGrid(const ActionOptions&ao):
+      51             :   Action(ao),
+      52           4 :   ActionWithIntegral(ao)
+      53             : {
+      54           4 : }
+      55             : 
+      56        5705 : void IntegrateGrid::compute( const unsigned& current, MultiValue& myvals ) const {
+      57        5705 :   myvals.setValue( 0, 1.0 ); myvals.setValue( 1, getVolume()*getFunctionValue( current ) );
+      58        5705 :   if( !doNotCalculateDerivatives() ) myvals.addDerivative( 1, current, getVolume() );
+      59        5705 : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html b/coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..abe2b7eb3f99 --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/InterpolateGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - InterpolateGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283093.3 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15InterpolateGrid10isPeriodicEv0
_ZN4PLMD9gridtools15InterpolateGridC2ERKNS_13ActionOptionsE0
_ZN4PLMD9gridtools15InterpolateGridC1ERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools15InterpolateGrid16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD9gridtools15InterpolateGrid21getNumberOfQuantitiesEv8
_ZNK4PLMD9gridtools15InterpolateGrid7computeERKjRNS_10MultiValueE200
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/InterpolateGrid.cpp.func.html b/coverage/gridtools/InterpolateGrid.cpp.func.html new file mode 100644 index 000000000000..057a1b921624 --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/InterpolateGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - InterpolateGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283093.3 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9gridtools15InterpolateGrid10isPeriodicEv0
_ZN4PLMD9gridtools15InterpolateGrid16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD9gridtools15InterpolateGridC1ERKNS_13ActionOptionsE2
_ZN4PLMD9gridtools15InterpolateGridC2ERKNS_13ActionOptionsE0
_ZNK4PLMD9gridtools15InterpolateGrid21getNumberOfQuantitiesEv8
_ZNK4PLMD9gridtools15InterpolateGrid7computeERKjRNS_10MultiValueE200
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/InterpolateGrid.cpp.gcov.html b/coverage/gridtools/InterpolateGrid.cpp.gcov.html new file mode 100644 index 000000000000..0e43dad2bd6d --- /dev/null +++ b/coverage/gridtools/InterpolateGrid.cpp.gcov.html @@ -0,0 +1,188 @@ + + + + + + + + LCOV - plumed test coverage - gridtools/InterpolateGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtools - InterpolateGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283093.3 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "ActionWithInputGrid.h"
+      25             : 
+      26             : //+PLUMEDOC GRIDANALYSIS INTERPOLATE_GRID
+      27             : /*
+      28             : Interpolate a smooth function stored on a grid onto a grid with a smaller grid spacing.
+      29             : 
+      30             : This action takes a function evaluated on a grid as input and can be used to interpolate the values of that
+      31             : function on to a finer grained grid.  The interpolation within this algorithm is done using splines.
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : The input below can be used to post process a trajectory.  It calculates a \ref HISTOGRAM as a function the
+      36             : distance between atoms 1 and 2 using kernel density estimation.  During the calculation the values of the kernels
+      37             : are evaluated at 100 points on a uniform grid between 0.0 and 3.0.  Prior to outputting this function at the end of the
+      38             : simulation this function is interpolated onto a finer grid of 200 points between 0.0 and 3.0.
+      39             : 
+      40             : \plumedfile
+      41             : x: DISTANCE ATOMS=1,2
+      42             : hA1: HISTOGRAM ARG=x GRID_MIN=0.0 GRID_MAX=3.0 GRID_BIN=100 BANDWIDTH=0.1
+      43             : ii: INTERPOLATE_GRID GRID=hA1 GRID_BIN=200
+      44             : DUMPGRID GRID=ii FILE=histo.dat
+      45             : \endplumedfile
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : namespace PLMD {
+      51             : namespace gridtools {
+      52             : 
+      53             : class InterpolateGrid : public ActionWithInputGrid {
+      54             : public:
+      55             :   static void registerKeywords( Keywords& keys );
+      56             :   explicit InterpolateGrid(const ActionOptions&ao);
+      57             :   unsigned getNumberOfQuantities() const override;
+      58             :   void compute( const unsigned& current, MultiValue& myvals ) const override;
+      59           0 :   bool isPeriodic() override { return false; }
+      60             : };
+      61             : 
+      62             : PLUMED_REGISTER_ACTION(InterpolateGrid,"INTERPOLATE_GRID")
+      63             : 
+      64           4 : void InterpolateGrid::registerKeywords( Keywords& keys ) {
+      65           4 :   ActionWithInputGrid::registerKeywords( keys );
+      66           8 :   keys.add("optional","GRID_BIN","the number of bins for the grid");
+      67           8 :   keys.add("optional","GRID_SPACING","the approximate grid spacing (to be used as an alternative or together with GRID_BIN)");
+      68           8 :   keys.remove("KERNEL"); keys.remove("BANDWIDTH");
+      69           4 : }
+      70             : 
+      71           2 : InterpolateGrid::InterpolateGrid(const ActionOptions&ao):
+      72             :   Action(ao),
+      73           2 :   ActionWithInputGrid(ao)
+      74             : {
+      75           2 :   plumed_assert( ingrid->getNumberOfComponents()==1 );
+      76           2 :   if( ingrid->noDerivatives() ) error("cannot interpolate a grid that does not have derivatives");
+      77             :   // Create the input from the old string
+      78           4 :   auto grid=createGrid( "grid", "COMPONENTS=" + getLabel() + " " + ingrid->getInputString()  );
+      79             :   // notice that createGrid also sets mygrid=grid.get()
+      80             : 
+      81           4 :   std::vector<unsigned> nbin; parseVector("GRID_BIN",nbin);
+      82           4 :   std::vector<double> gspacing; parseVector("GRID_SPACING",gspacing);
+      83           2 :   if( nbin.size()!=ingrid->getDimension() && gspacing.size()!=ingrid->getDimension() ) {
+      84           0 :     error("GRID_BIN or GRID_SPACING must be set");
+      85             :   }
+      86             : 
+      87             :   // Need this for creation of tasks
+      88           2 :   grid->setBounds( ingrid->getMin(), ingrid->getMax(), nbin, gspacing );
+      89           2 :   setAveragingAction( std::move(grid), true );
+      90             : 
+      91             :   // Now create task list
+      92         202 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) addTaskToList(i);
+      93             :   // And activate all tasks
+      94           2 :   deactivateAllTasks();
+      95         202 :   for(unsigned i=0; i<mygrid->getNumberOfPoints(); ++i) taskFlags[i]=1;
+      96           2 :   lockContributors();
+      97           2 : }
+      98             : 
+      99           8 : unsigned InterpolateGrid::getNumberOfQuantities() const {
+     100           8 :   return 2 + ingrid->getDimension();
+     101             : }
+     102             : 
+     103         200 : void InterpolateGrid::compute( const unsigned& current, MultiValue& myvals ) const {
+     104         200 :   std::vector<double> pos( mygrid->getDimension() ); mygrid->getGridPointCoordinates( current, pos );
+     105         200 :   std::vector<double> der( mygrid->getDimension() ); double val = getFunctionValueAndDerivatives( pos, der );
+     106             :   myvals.setValue( 0, 1.0 ); myvals.setValue(1, val );
+     107         400 :   for(unsigned i=0; i<mygrid->getDimension(); ++i) myvals.setValue( 2+i, der[i] );
+     108         200 : }
+     109             : 
+     110             : }
+     111             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/index-sort-f.html b/coverage/gridtools/index-sort-f.html new file mode 100644 index 000000000000..309ffe09872f --- /dev/null +++ b/coverage/gridtools/index-sort-f.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1172125293.6 %
Date:2024-02-22 21:58:45Functions:14117082.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AverageOnGrid.h +
60.0%60.0%
+
60.0 %3 / 533.3 %1 / 3
ActionWithIntegral.h +
75.0%75.0%
+
75.0 %3 / 450.0 %1 / 2
FourierTransform.cpp +
83.5%83.5%
+
83.5 %71 / 8557.1 %4 / 7
ContourFindingBase.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
ContourFindingBase.h +
83.3%83.3%
+
83.3 %5 / 666.7 %2 / 3
InterpolateGrid.cpp +
93.3%93.3%
+
93.3 %28 / 3066.7 %4 / 6
FindContour.cpp +
84.1%84.1%
+
84.1 %74 / 8866.7 %6 / 9
DumpCube.cpp +
88.6%88.6%
+
88.6 %31 / 3575.0 %3 / 4
DumpGrid.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
IntegrateGrid.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
GridToXYZ.cpp +
88.6%88.6%
+
88.6 %39 / 4475.0 %3 / 4
FindContourSurface.cpp +
95.7%95.7%
+
95.7 %89 / 9377.8 %7 / 9
GridPrintingBase.cpp +
100.0%
+
100.0 %53 / 5380.0 %4 / 5
ActionWithIntegral.cpp +
100.0%
+
100.0 %22 / 2280.0 %4 / 5
FindSphericalContour.cpp +
95.0%95.0%
+
95.0 %38 / 4080.0 %4 / 5
ActionWithInputGrid.cpp +
91.2%91.2%
+
91.2 %31 / 3483.3 %5 / 6
ConvertToFES.cpp +
97.8%97.8%
+
97.8 %44 / 4583.3 %10 / 12
ActionWithGrid.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
GridVessel.h +
89.3%89.3%
+
89.3 %25 / 2887.5 %7 / 8
GridVessel.cpp +
94.6%94.6%
+
94.6 %316 / 33494.9 %37 / 39
HistogramOnGrid.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
GridPrintingBase.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
GridSearch.h +
95.0%95.0%
+
95.0 %38 / 40100.0 %2 / 2
ActionWithInputGrid.h +
100.0%
+
100.0 %8 / 8100.0 %4 / 4
AverageOnGrid.cpp +
96.2%96.2%
+
96.2 %25 / 26100.0 %4 / 4
HistogramOnGrid.cpp +
98.3%98.3%
+
98.3 %118 / 120100.0 %12 / 12
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/index-sort-l.html b/coverage/gridtools/index-sort-l.html new file mode 100644 index 000000000000..5c27518bc878 --- /dev/null +++ b/coverage/gridtools/index-sort-l.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1172125293.6 %
Date:2024-02-22 21:58:45Functions:14117082.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AverageOnGrid.h +
60.0%60.0%
+
60.0 %3 / 533.3 %1 / 3
ActionWithIntegral.h +
75.0%75.0%
+
75.0 %3 / 450.0 %1 / 2
ContourFindingBase.h +
83.3%83.3%
+
83.3 %5 / 666.7 %2 / 3
FourierTransform.cpp +
83.5%83.5%
+
83.5 %71 / 8557.1 %4 / 7
FindContour.cpp +
84.1%84.1%
+
84.1 %74 / 8866.7 %6 / 9
DumpCube.cpp +
88.6%88.6%
+
88.6 %31 / 3575.0 %3 / 4
GridToXYZ.cpp +
88.6%88.6%
+
88.6 %39 / 4475.0 %3 / 4
GridVessel.h +
89.3%89.3%
+
89.3 %25 / 2887.5 %7 / 8
ActionWithInputGrid.cpp +
91.2%91.2%
+
91.2 %31 / 3483.3 %5 / 6
InterpolateGrid.cpp +
93.3%93.3%
+
93.3 %28 / 3066.7 %4 / 6
GridVessel.cpp +
94.6%94.6%
+
94.6 %316 / 33494.9 %37 / 39
GridSearch.h +
95.0%95.0%
+
95.0 %38 / 40100.0 %2 / 2
FindSphericalContour.cpp +
95.0%95.0%
+
95.0 %38 / 4080.0 %4 / 5
FindContourSurface.cpp +
95.7%95.7%
+
95.7 %89 / 9377.8 %7 / 9
AverageOnGrid.cpp +
96.2%96.2%
+
96.2 %25 / 26100.0 %4 / 4
ConvertToFES.cpp +
97.8%97.8%
+
97.8 %44 / 4583.3 %10 / 12
ActionWithGrid.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
HistogramOnGrid.cpp +
98.3%98.3%
+
98.3 %118 / 120100.0 %12 / 12
GridPrintingBase.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
HistogramOnGrid.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
ActionWithInputGrid.h +
100.0%
+
100.0 %8 / 8100.0 %4 / 4
IntegrateGrid.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
ContourFindingBase.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
ActionWithIntegral.cpp +
100.0%
+
100.0 %22 / 2280.0 %4 / 5
DumpGrid.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
GridPrintingBase.cpp +
100.0%
+
100.0 %53 / 5380.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/gridtools/index.html b/coverage/gridtools/index.html new file mode 100644 index 000000000000..526bdca9be33 --- /dev/null +++ b/coverage/gridtools/index.html @@ -0,0 +1,344 @@ + + + + + + + + LCOV - plumed test coverage - gridtools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - gridtoolsHitTotalCoverage
Test:plumed test coverageLines:1172125293.6 %
Date:2024-02-22 21:58:45Functions:14117082.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionWithGrid.cpp +
98.1%98.1%
+
98.1 %51 / 5285.7 %6 / 7
ActionWithInputGrid.cpp +
91.2%91.2%
+
91.2 %31 / 3483.3 %5 / 6
ActionWithInputGrid.h +
100.0%
+
100.0 %8 / 8100.0 %4 / 4
ActionWithIntegral.cpp +
100.0%
+
100.0 %22 / 2280.0 %4 / 5
ActionWithIntegral.h +
75.0%75.0%
+
75.0 %3 / 450.0 %1 / 2
AverageOnGrid.cpp +
96.2%96.2%
+
96.2 %25 / 26100.0 %4 / 4
AverageOnGrid.h +
60.0%60.0%
+
60.0 %3 / 533.3 %1 / 3
ContourFindingBase.cpp +
100.0%
+
100.0 %11 / 1166.7 %2 / 3
ContourFindingBase.h +
83.3%83.3%
+
83.3 %5 / 666.7 %2 / 3
ConvertToFES.cpp +
97.8%97.8%
+
97.8 %44 / 4583.3 %10 / 12
DumpCube.cpp +
88.6%88.6%
+
88.6 %31 / 3575.0 %3 / 4
DumpGrid.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
FindContour.cpp +
84.1%84.1%
+
84.1 %74 / 8866.7 %6 / 9
FindContourSurface.cpp +
95.7%95.7%
+
95.7 %89 / 9377.8 %7 / 9
FindSphericalContour.cpp +
95.0%95.0%
+
95.0 %38 / 4080.0 %4 / 5
FourierTransform.cpp +
83.5%83.5%
+
83.5 %71 / 8557.1 %4 / 7
GridPrintingBase.cpp +
100.0%
+
100.0 %53 / 5380.0 %4 / 5
GridPrintingBase.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
GridSearch.h +
95.0%95.0%
+
95.0 %38 / 40100.0 %2 / 2
GridToXYZ.cpp +
88.6%88.6%
+
88.6 %39 / 4475.0 %3 / 4
GridVessel.cpp +
94.6%94.6%
+
94.6 %316 / 33494.9 %37 / 39
GridVessel.h +
89.3%89.3%
+
89.3 %25 / 2887.5 %7 / 8
HistogramOnGrid.cpp +
98.3%98.3%
+
98.3 %118 / 120100.0 %12 / 12
HistogramOnGrid.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
IntegrateGrid.cpp +
100.0%
+
100.0 %10 / 1075.0 %3 / 4
InterpolateGrid.cpp +
93.3%93.3%
+
93.3 %28 / 3066.7 %4 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/index-sort-f.html b/coverage/index-sort-f.html new file mode 100644 index 000000000000..225823750969 --- /dev/null +++ b/coverage/index-sort-f.html @@ -0,0 +1,484 @@ + + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:502085961384.2 %
Date:2024-02-22 21:58:45Functions:5264667778.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
config +
41.9%41.9%
+
41.9 %57 / 13642.0 %21 / 50
wrapper +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
piv +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
manyrestraints +
81.1%81.1%
+
81.1 %73 / 9065.0 %13 / 20
dimred +
84.5%84.5%
+
84.5 %546 / 64665.4 %51 / 78
ves +
82.0%82.0%
+
82.0 %5891 / 718065.6 %444 / 677
setup +
97.6%97.6%
+
97.6 %82 / 8466.7 %6 / 9
isdb +
76.9%76.9%
+
76.9 %8782 / 1142769.4 %163 / 235
small_vector +
88.7%88.7%
+
88.7 %63 / 7170.0 %14 / 20
crystallization +
83.6%83.6%
+
83.6 %1000 / 119671.3 %97 / 136
analysis +
88.3%88.3%
+
88.3 %843 / 95571.4 %110 / 154
colvar +
93.9%93.9%
+
93.9 %2056 / 218971.9 %97 / 135
pamm +
81.2%81.2%
+
81.2 %212 / 26172.0 %18 / 25
generic +
95.0%95.0%
+
95.0 %1195 / 125873.6 %109 / 148
multicolvar +
78.9%78.9%
+
78.9 %2353 / 298374.5 %216 / 290
s2cm +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
vatom +
99.6%99.6%
+
99.6 %227 / 22875.0 %9 / 12
membranefusion +
88.1%88.1%
+
88.1 %453 / 51475.0 %9 / 12
function +
85.6%85.6%
+
85.6 %881 / 102976.2 %48 / 63
secondarystructure +
96.6%96.6%
+
96.6 %373 / 38676.9 %20 / 26
funnel +
98.0%98.0%
+
98.0 %247 / 25277.8 %7 / 9
adjmat +
89.3%89.3%
+
89.3 %1023 / 114577.7 %136 / 175
tools +
83.5%83.5%
+
83.5 %5674 / 679977.7 %1060 / 1364
reference +
86.1%86.1%
+
86.1 %668 / 77679.3 %153 / 193
pytorch +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
maze +
85.2%85.2%
+
85.2 %654 / 76880.2 %65 / 81
bias +
91.5%91.5%
+
91.5 %2381 / 260180.6 %100 / 124
sasa +
82.0%82.0%
+
82.0 %996 / 121580.8 %21 / 26
fisst +
79.6%79.6%
+
79.6 %319 / 40180.8 %21 / 26
gridtools +
93.6%93.6%
+
93.6 %1172 / 125282.9 %141 / 170
annfunc +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
eds +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
mapping +
93.7%93.7%
+
93.7 %754 / 80587.5 %77 / 88
cltools +
77.7%77.7%
+
77.7 %1381 / 177889.3 %109 / 122
vesselbase +
92.9%92.9%
+
92.9 %1141 / 122889.6 %232 / 259
core +
86.2%86.2%
+
86.2 %3556 / 412391.7 %1308 / 1427
logmfd +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
opes +
96.1%96.1%
+
96.1 %2142 / 222892.3 %108 / 117
drr +
94.5%94.5%
+
94.5 %1201 / 127194.7 %89 / 94
main +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/index-sort-l.html b/coverage/index-sort-l.html new file mode 100644 index 000000000000..9e360cafb8b4 --- /dev/null +++ b/coverage/index-sort-l.html @@ -0,0 +1,484 @@ + + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:502085961384.2 %
Date:2024-02-22 21:58:45Functions:5264667778.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
config +
41.9%41.9%
+
41.9 %57 / 13642.0 %21 / 50
wrapper +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
piv +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
isdb +
76.9%76.9%
+
76.9 %8782 / 1142769.4 %163 / 235
cltools +
77.7%77.7%
+
77.7 %1381 / 177889.3 %109 / 122
multicolvar +
78.9%78.9%
+
78.9 %2353 / 298374.5 %216 / 290
fisst +
79.6%79.6%
+
79.6 %319 / 40180.8 %21 / 26
main +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
manyrestraints +
81.1%81.1%
+
81.1 %73 / 9065.0 %13 / 20
pamm +
81.2%81.2%
+
81.2 %212 / 26172.0 %18 / 25
sasa +
82.0%82.0%
+
82.0 %996 / 121580.8 %21 / 26
ves +
82.0%82.0%
+
82.0 %5891 / 718065.6 %444 / 677
tools +
83.5%83.5%
+
83.5 %5674 / 679977.7 %1060 / 1364
crystallization +
83.6%83.6%
+
83.6 %1000 / 119671.3 %97 / 136
dimred +
84.5%84.5%
+
84.5 %546 / 64665.4 %51 / 78
maze +
85.2%85.2%
+
85.2 %654 / 76880.2 %65 / 81
function +
85.6%85.6%
+
85.6 %881 / 102976.2 %48 / 63
reference +
86.1%86.1%
+
86.1 %668 / 77679.3 %153 / 193
core +
86.2%86.2%
+
86.2 %3556 / 412391.7 %1308 / 1427
logmfd +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
membranefusion +
88.1%88.1%
+
88.1 %453 / 51475.0 %9 / 12
analysis +
88.3%88.3%
+
88.3 %843 / 95571.4 %110 / 154
small_vector +
88.7%88.7%
+
88.7 %63 / 7170.0 %14 / 20
adjmat +
89.3%89.3%
+
89.3 %1023 / 114577.7 %136 / 175
pytorch +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
s2cm +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
bias +
91.5%91.5%
+
91.5 %2381 / 260180.6 %100 / 124
eds +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
vesselbase +
92.9%92.9%
+
92.9 %1141 / 122889.6 %232 / 259
mapping +
93.7%93.7%
+
93.7 %754 / 80587.5 %77 / 88
gridtools +
93.6%93.6%
+
93.6 %1172 / 125282.9 %141 / 170
colvar +
93.9%93.9%
+
93.9 %2056 / 218971.9 %97 / 135
drr +
94.5%94.5%
+
94.5 %1201 / 127194.7 %89 / 94
generic +
95.0%95.0%
+
95.0 %1195 / 125873.6 %109 / 148
opes +
96.1%96.1%
+
96.1 %2142 / 222892.3 %108 / 117
secondarystructure +
96.6%96.6%
+
96.6 %373 / 38676.9 %20 / 26
annfunc +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
setup +
97.6%97.6%
+
97.6 %82 / 8466.7 %6 / 9
funnel +
98.0%98.0%
+
98.0 %247 / 25277.8 %7 / 9
vatom +
99.6%99.6%
+
99.6 %227 / 22875.0 %9 / 12
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/index.html b/coverage/index.html new file mode 100644 index 000000000000..8069f0694ee7 --- /dev/null +++ b/coverage/index.html @@ -0,0 +1,484 @@ + + + + + + + + LCOV - plumed test coverage + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top levelHitTotalCoverage
Test:plumed test coverageLines:502085961384.2 %
Date:2024-02-22 21:58:45Functions:5264667778.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Directory Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
adjmat +
89.3%89.3%
+
89.3 %1023 / 114577.7 %136 / 175
analysis +
88.3%88.3%
+
88.3 %843 / 95571.4 %110 / 154
annfunc +
97.1%97.1%
+
97.1 %133 / 13783.3 %5 / 6
bias +
91.5%91.5%
+
91.5 %2381 / 260180.6 %100 / 124
cltools +
77.7%77.7%
+
77.7 %1381 / 177889.3 %109 / 122
colvar +
93.9%93.9%
+
93.9 %2056 / 218971.9 %97 / 135
config +
41.9%41.9%
+
41.9 %57 / 13642.0 %21 / 50
core +
86.2%86.2%
+
86.2 %3556 / 412391.7 %1308 / 1427
crystallization +
83.6%83.6%
+
83.6 %1000 / 119671.3 %97 / 136
dimred +
84.5%84.5%
+
84.5 %546 / 64665.4 %51 / 78
drr +
94.5%94.5%
+
94.5 %1201 / 127194.7 %89 / 94
eds +
92.8%92.8%
+
92.8 %451 / 48685.0 %17 / 20
fisst +
79.6%79.6%
+
79.6 %319 / 40180.8 %21 / 26
function +
85.6%85.6%
+
85.6 %881 / 102976.2 %48 / 63
funnel +
98.0%98.0%
+
98.0 %247 / 25277.8 %7 / 9
generic +
95.0%95.0%
+
95.0 %1195 / 125873.6 %109 / 148
gridtools +
93.6%93.6%
+
93.6 %1172 / 125282.9 %141 / 170
isdb +
76.9%76.9%
+
76.9 %8782 / 1142769.4 %163 / 235
logmfd +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
main +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
manyrestraints +
81.1%81.1%
+
81.1 %73 / 9065.0 %13 / 20
mapping +
93.7%93.7%
+
93.7 %754 / 80587.5 %77 / 88
maze +
85.2%85.2%
+
85.2 %654 / 76880.2 %65 / 81
membranefusion +
88.1%88.1%
+
88.1 %453 / 51475.0 %9 / 12
multicolvar +
78.9%78.9%
+
78.9 %2353 / 298374.5 %216 / 290
opes +
96.1%96.1%
+
96.1 %2142 / 222892.3 %108 / 117
pamm +
81.2%81.2%
+
81.2 %212 / 26172.0 %18 / 25
piv +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
pytorch +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
reference +
86.1%86.1%
+
86.1 %668 / 77679.3 %153 / 193
s2cm +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
sasa +
82.0%82.0%
+
82.0 %996 / 121580.8 %21 / 26
secondarystructure +
96.6%96.6%
+
96.6 %373 / 38676.9 %20 / 26
setup +
97.6%97.6%
+
97.6 %82 / 8466.7 %6 / 9
small_vector +
88.7%88.7%
+
88.7 %63 / 7170.0 %14 / 20
tools +
83.5%83.5%
+
83.5 %5674 / 679977.7 %1060 / 1364
vatom +
99.6%99.6%
+
99.6 %227 / 22875.0 %9 / 12
ves +
82.0%82.0%
+
82.0 %5891 / 718065.6 %444 / 677
vesselbase +
92.9%92.9%
+
92.9 %1141 / 122889.6 %232 / 259
wrapper +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/CS2Backbone.cpp.func-sort-c.html b/coverage/isdb/CS2Backbone.cpp.func-sort-c.html new file mode 100644 index 000000000000..6947bd5d4f21 --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.func-sort-c.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage - isdb/CS2Backbone.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - CS2Backbone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91696794.7 %
Date:2024-02-22 21:58:45Functions:222395.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb11CS2BackboneC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb11CS2Backbone10init_ringsERKNS_3PDBE18
_ZN4PLMD4isdb11CS2Backbone10init_typesERKNS_3PDBE18
_ZN4PLMD4isdb11CS2Backbone13update_neighbEv18
_ZN4PLMD4isdb11CS2Backbone23compute_ring_parametersEv18
_ZN4PLMD4isdb11CS2Backbone6updateEv18
_ZN4PLMD4isdb11CS2Backbone9calculateEv18
_ZN4PLMD4isdb11CS2BackboneC1ERKNS_13ActionOptionsE18
_ZN4PLMD4isdb13CS2BackboneDB5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd18
_ZN4PLMD4isdb11CS2Backbone16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD4isdb11CS2Backbone7init_csERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKNS_3PDBE108
_ZN4PLMD4isdb11CS2Backbone8RingInfoC2Ev360
_ZN4PLMD4isdb13CS2BackboneDB6assignEPdRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEd10368
_ZN4PLMD4isdb11CS2Backbone13ChemicalShiftC2Ev10602
_ZN4PLMD4isdb11CS2Backbone16side_chain_atomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10602
_ZN4PLMD4isdb13CS2BackboneDB4kindERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10926
_ZN4PLMD4isdb13CS2BackboneDB9atom_kindERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10926
_ZN4PLMD4isdb13CS2BackboneDB5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEc20430
_ZN4PLMD4isdb13CS2BackboneDB5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEcRSt6vectorIS7_SaIS7_EE20430
_ZN4PLMD4isdb11CS2Backbone9frag2enumERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31806
_ZN4PLMD4isdb11CS2Backbone5isSP2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_47016
_ZN4PLMD4isdb11CS2Backbone10is_chi1_cxERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_145728
_ZN4PLMD4isdb11CS2Backbone14xdist_name_mapERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3599784
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/CS2Backbone.cpp.func.html b/coverage/isdb/CS2Backbone.cpp.func.html new file mode 100644 index 000000000000..aa5b6c8c7918 --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.func.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage - isdb/CS2Backbone.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - CS2Backbone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91696794.7 %
Date:2024-02-22 21:58:45Functions:222395.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb11CS2Backbone10init_ringsERKNS_3PDBE18
_ZN4PLMD4isdb11CS2Backbone10init_typesERKNS_3PDBE18
_ZN4PLMD4isdb11CS2Backbone10is_chi1_cxERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_145728
_ZN4PLMD4isdb11CS2Backbone13ChemicalShiftC2Ev10602
_ZN4PLMD4isdb11CS2Backbone13update_neighbEv18
_ZN4PLMD4isdb11CS2Backbone14xdist_name_mapERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3599784
_ZN4PLMD4isdb11CS2Backbone16registerKeywordsERNS_8KeywordsE20
_ZN4PLMD4isdb11CS2Backbone16side_chain_atomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10602
_ZN4PLMD4isdb11CS2Backbone23compute_ring_parametersEv18
_ZN4PLMD4isdb11CS2Backbone5isSP2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_47016
_ZN4PLMD4isdb11CS2Backbone6updateEv18
_ZN4PLMD4isdb11CS2Backbone7init_csERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKNS_3PDBE108
_ZN4PLMD4isdb11CS2Backbone8RingInfoC2Ev360
_ZN4PLMD4isdb11CS2Backbone9calculateEv18
_ZN4PLMD4isdb11CS2Backbone9frag2enumERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31806
_ZN4PLMD4isdb11CS2BackboneC1ERKNS_13ActionOptionsE18
_ZN4PLMD4isdb11CS2BackboneC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb13CS2BackboneDB4kindERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10926
_ZN4PLMD4isdb13CS2BackboneDB5parseERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd18
_ZN4PLMD4isdb13CS2BackboneDB5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEc20430
_ZN4PLMD4isdb13CS2BackboneDB5splitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEcRSt6vectorIS7_SaIS7_EE20430
_ZN4PLMD4isdb13CS2BackboneDB6assignEPdRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEd10368
_ZN4PLMD4isdb13CS2BackboneDB9atom_kindERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10926
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/CS2Backbone.cpp.gcov.html b/coverage/isdb/CS2Backbone.cpp.gcov.html new file mode 100644 index 000000000000..13125feab8c3 --- /dev/null +++ b/coverage/isdb/CS2Backbone.cpp.gcov.html @@ -0,0 +1,1921 @@ + + + + + + + + LCOV - plumed test coverage - isdb/CS2Backbone.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - CS2Backbone.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91696794.7 %
Date:2024-02-22 21:58:45Functions:222395.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #define cutOffNB      0.60      // buffer distance for neighbour-lists 
+      24             : #define cutOffDist    0.50      // cut off distance for non-bonded pairwise forces
+      25             : #define cutOnDist     0.32      // cut off distance for non-bonded pairwise forces
+      26             : #define cutOffNB2     cutOffNB*cutOffNB // squared buffer distance for neighbour-lists 
+      27             : #define cutOffDist2   cutOffDist*cutOffDist
+      28             : #define cutOnDist2    cutOnDist*cutOnDist
+      29             : #define invswitch     1.0/((cutOffDist2-cutOnDist2)*(cutOffDist2-cutOnDist2)*(cutOffDist2-cutOnDist2))
+      30             : #define cutOffDist4   cutOffDist2*cutOffDist2
+      31             : #define cutMixed      cutOffDist2*cutOffDist2*cutOffDist2 -3.*cutOffDist2*cutOffDist2*cutOnDist2
+      32             : 
+      33             : #include <string>
+      34             : #include <fstream>
+      35             : #include <iterator>
+      36             : #include <sstream>
+      37             : 
+      38             : #include "MetainferenceBase.h"
+      39             : #include "core/ActionRegister.h"
+      40             : #include "tools/Pbc.h"
+      41             : #include "tools/PDB.h"
+      42             : #include "tools/Torsion.h"
+      43             : #include "tools/Communicator.h"
+      44             : 
+      45             : namespace PLMD {
+      46             : namespace isdb {
+      47             : 
+      48             : //+PLUMEDOC ISDB_COLVAR CS2BACKBONE
+      49             : /*
+      50             : Calculates the backbone chemical shifts for a protein.
+      51             : 
+      52             : The functional form is that of CamShift \cite Kohlhoff:2009us. The chemical shift
+      53             : of the selected nuclei can be saved as components. Alternatively one can calculate either
+      54             : the CAMSHIFT score (useful as a collective variable \cite Granata:2013dk or as a scoring
+      55             : function \cite Robustelli:2010dn) or a \ref METAINFERENCE score (using DOSCORE).
+      56             : For these two latter cases experimental chemical shifts must be provided.
+      57             : 
+      58             : CS2BACKBONE calculation can be relatively heavy because it often uses a large number of atoms, it can
+      59             : be run in parallel using MPI and \ref Openmp.
+      60             : 
+      61             : As a general rule, when using \ref CS2BACKBONE or other experimental restraints it may be better to
+      62             : increase the accuracy of the constraint algorithm due to the increased strain on the bonded structure.
+      63             : In the case of GROMACS it is safer to use lincs-iter=2 and lincs-order=6.
+      64             : 
+      65             : In general the system for which chemical shifts are calculated must be completely included in
+      66             : ATOMS and a TEMPLATE pdb file for the same atoms should be provided as well in the folder DATADIR.
+      67             : The system is made automatically whole unless NOPBC is used, in particular if the system is made
+      68             : by multiple chains it is usually better to use NOPBC and make the molecule whole \ref WHOLEMOLECULES
+      69             : selecting an appropriate order of the atoms. The pdb file is needed to the generate a simple topology of the protein.
+      70             : For histidine residues in protonation states different from D the HIE/HSE HIP/HSP name should be used.
+      71             : GLH and ASH can be used for the alternative protonation of GLU and ASP. Non-standard amino acids and other
+      72             : molecules are not yet supported, but in principle they can be named UNK. If multiple chains are present
+      73             : the chain identifier must be in the standard PDB format, together with the TER keyword at the end of each chain.
+      74             : Termini groups like ACE or NME should be removed from the TEMPLATE pdb because they are not recognized by
+      75             : CS2BACKBONE.
+      76             : 
+      77             : Atoms indices in the TEMPLATE file should be numbered from 1 to N where N is the number of atoms used in ATOMS.
+      78             : This is not a problem for simple cases where atoms goes from 1 to N but is instead something to be carefull in case
+      79             : that a terminal group is removed from the PDB file.
+      80             : 
+      81             : In addition to a pdb file one needs to provide a list of chemical shifts to be calculated using one
+      82             : file per nucleus type (CAshifts.dat, CBshifts.dat, Cshifts.dat, Hshifts.dat, HAshifts.dat, Nshifts.dat),
+      83             : add only the files for the nuclei you need, but each file should include all protein residues.
+      84             : A chemical shift for a nucleus is calculated if a value greater than 0 is provided.
+      85             : For practical purposes the value can correspond to the experimental value.
+      86             : Residues numbers should match that used in the pdb file, but must be positive, so double check the pdb.
+      87             : The first and last residue of each chain should be preceded by a # character.
+      88             : 
+      89             : \verbatim
+      90             : CAshifts.dat:
+      91             : #1 0.0
+      92             : 2 55.5
+      93             : 3 58.4
+      94             : .
+      95             : .
+      96             : #last 0.0
+      97             : #first of second chain
+      98             : .
+      99             : #last of second chain
+     100             : \endverbatim
+     101             : 
+     102             : The default behavior is to store the values for the active nuclei in components (ca-#, cb-#,
+     103             : co-#, ha-#, hn-#, nh-# and expca-#, expcb-#, expco-#, expha-#, exphn-#, exp-nh#) with NOEXP it is possible
+     104             : to only store the back-calculated values, where # includes a chain and residue number.
+     105             : 
+     106             : One additional file is always needed in the folder DATADIR: camshift.db. This file includes all the parameters needed to
+     107             : calculate the chemical shifts and can be found in regtest/isdb/rt-cs2backbone/data/ .
+     108             : 
+     109             : Additional material and examples can be also found in the tutorial \ref isdb-1 as well as in the cs2backbone regtests
+     110             : in the isdb folder.
+     111             : 
+     112             : \par Examples
+     113             : 
+     114             : In this first example the chemical shifts are used to calculate a collective variable to be used
+     115             : in NMR driven Metadynamics \cite Granata:2013dk :
+     116             : 
+     117             : \plumedfile
+     118             : #SETTINGS AUXFOLDER=regtest/isdb/rt-cs2backbone/data
+     119             : whole: GROUP ATOMS=2612-2514:-1,961-1:-1,2466-962:-1,2513-2467:-1
+     120             : WHOLEMOLECULES ENTITY0=whole
+     121             : cs: CS2BACKBONE ATOMS=1-2612 DATADIR=data/ TEMPLATE=template.pdb CAMSHIFT NOPBC
+     122             : metad: METAD ARG=cs HEIGHT=0.5 SIGMA=0.1 PACE=200 BIASFACTOR=10
+     123             : PRINT ARG=cs,metad.bias FILE=COLVAR STRIDE=100
+     124             : \endplumedfile
+     125             : 
+     126             : In this second example the chemical shifts are used as replica-averaged restrained as in \cite Camilloni:2012je \cite Camilloni:2013hs .
+     127             : 
+     128             : \plumedfile
+     129             : #SETTINGS AUXFOLDER=regtest/isdb/rt-cs2backbone/data NREPLICAS=2
+     130             : cs: CS2BACKBONE ATOMS=1-174 DATADIR=data/
+     131             : encs: ENSEMBLE ARG=(cs\.hn-.*),(cs\.nh-.*)
+     132             : stcs: STATS ARG=encs.* SQDEVSUM PARARG=(cs\.exphn-.*),(cs\.expnh-.*)
+     133             : RESTRAINT ARG=stcs.sqdevsum AT=0 KAPPA=0 SLOPE=24
+     134             : 
+     135             : PRINT ARG=(cs\.hn-.*),(cs\.nh-.*) FILE=RESTRAINT STRIDE=100
+     136             : 
+     137             : \endplumedfile
+     138             : 
+     139             : This third example show how to use chemical shifts to calculate a \ref METAINFERENCE score .
+     140             : 
+     141             : \plumedfile
+     142             : #SETTINGS AUXFOLDER=regtest/isdb/rt-cs2backbone/data
+     143             : cs: CS2BACKBONE ATOMS=1-174 DATADIR=data/ SIGMA_MEAN0=1.0 DOSCORE
+     144             : csbias: BIASVALUE ARG=cs.score
+     145             : 
+     146             : PRINT ARG=(cs\.hn-.*),(cs\.nh-.*) FILE=CS.dat STRIDE=1000
+     147             : PRINT ARG=cs.score FILE=BIAS STRIDE=100
+     148             : \endplumedfile
+     149             : 
+     150             : */
+     151             : //+ENDPLUMEDOC
+     152             : 
+     153             : class CS2BackboneDB {
+     154             :   enum { STD, GLY, PRO};
+     155             :   enum { HA_ATOM, H_ATOM, N_ATOM, CA_ATOM, CB_ATOM, C_ATOM };
+     156             :   static const unsigned aa_kind = 3;
+     157             :   static const unsigned atm_kind = 6;
+     158             :   static const unsigned numXtraDists = 27;
+     159             : 
+     160             :   // ALA, ARG, ASN, ASP, CYS, GLU, GLN, GLY, HIS, ILE, LEU, LYS, MET, PHE, PRO, SER, THR, TRP, TYR, VAL
+     161             :   double c_aa[aa_kind][atm_kind][20];
+     162             :   double c_aa_prev[aa_kind][atm_kind][20];
+     163             :   double c_aa_succ[aa_kind][atm_kind][20];
+     164             :   double co_bb[aa_kind][atm_kind][16];
+     165             :   double co_sc_[aa_kind][atm_kind][20][20];
+     166             :   double co_xd[aa_kind][atm_kind][numXtraDists];
+     167             :   double co_sphere[aa_kind][atm_kind][2][8];
+     168             :   // for ring current effects
+     169             :   // Phe, Tyr, Trp_1, Trp_2, His
+     170             :   double co_ring[aa_kind][atm_kind][5];
+     171             :   // for dihedral angles
+     172             :   // co * (a * cos(3 * omega + c) + b * cos(omega + d))
+     173             :   double co_da[aa_kind][atm_kind][3];
+     174             :   double pars_da[aa_kind][atm_kind][3][5];
+     175             : 
+     176             : public:
+     177             : 
+     178       10926 :   inline unsigned kind(const std::string &s) {
+     179       10926 :     if(s=="GLY") return GLY;
+     180        9324 :     else if(s=="PRO") return PRO;
+     181             :     return STD;
+     182             :   }
+     183             : 
+     184       10926 :   inline unsigned atom_kind(const std::string &s) {
+     185       10926 :     if(s=="HA")return HA_ATOM;
+     186       10872 :     else if(s=="H") return H_ATOM;
+     187        8010 :     else if(s=="N") return N_ATOM;
+     188        5148 :     else if(s=="CA")return CA_ATOM;
+     189        2160 :     else if(s=="CB")return CB_ATOM;
+     190          54 :     else if(s=="C") return C_ATOM;
+     191             :     return -1;
+     192             :   }
+     193             : 
+     194             :   unsigned get_numXtraDists() {return numXtraDists;}
+     195             : 
+     196             :   //PARAMETERS
+     197             :   inline double * CONSTAACURR(const unsigned a_kind, const unsigned at_kind) {return c_aa[a_kind][at_kind];}
+     198             :   inline double * CONSTAANEXT(const unsigned a_kind, const unsigned at_kind) {return c_aa_succ[a_kind][at_kind];}
+     199             :   inline double * CONSTAAPREV(const unsigned a_kind, const unsigned at_kind) {return c_aa_prev[a_kind][at_kind];}
+     200             :   inline double * CONST_BB2(const unsigned a_kind, const unsigned at_kind) {return co_bb[a_kind][at_kind];}
+     201             :   inline double * CONST_SC2(const unsigned a_kind, const unsigned at_kind, unsigned res_type) { return co_sc_[a_kind][at_kind][res_type];}
+     202             :   inline double * CONST_XD(const unsigned a_kind, const unsigned at_kind) { return co_xd[a_kind][at_kind];}
+     203             :   inline double * CO_SPHERE(const unsigned a_kind, const unsigned at_kind, unsigned exp_type) { return co_sphere[a_kind][at_kind][exp_type];}
+     204             :   inline double * CO_RING(const unsigned a_kind, const unsigned at_kind) { return co_ring[a_kind][at_kind];}
+     205             :   inline double * CO_DA(const unsigned a_kind, const unsigned at_kind) { return co_da[a_kind][at_kind];}
+     206             :   inline double * PARS_DA(const unsigned a_kind, const unsigned at_kind, const unsigned ang_kind) { return pars_da[a_kind][at_kind][ang_kind];}
+     207             : 
+     208          18 :   void parse(const std::string &file, const double dscale) {
+     209          18 :     std::ifstream in;
+     210          18 :     in.open(file.c_str());
+     211          18 :     if(!in) plumed_merror("Unable to open DB file: " + file);
+     212             : 
+     213             :     unsigned c_kind = 0;
+     214             :     unsigned c_atom = 0;
+     215             :     unsigned nline = 0;
+     216             : 
+     217         396 :     for(unsigned i=0; i<3; i++) for(unsigned j=0; j<6; j++) {
+     218        6804 :         for(unsigned k=0; k<20; k++) {
+     219        6480 :           c_aa[i][j][k]=0.;
+     220        6480 :           c_aa_prev[i][j][k]=0.;
+     221        6480 :           c_aa_succ[i][j][k]=0.;
+     222      136080 :           for(unsigned m=0; m<20; m++) co_sc_[i][j][k][m]=0.;
+     223             :         }
+     224        5508 :         for(unsigned k=0; k<16; k++) {co_bb[i][j][k]=0.; }
+     225        2916 :         for(unsigned k=0; k<8; k++) { co_sphere[i][j][0][k]=0.; co_sphere[i][j][1][k]=0.; }
+     226        1296 :         for(unsigned k=0; k<3; k++) {
+     227         972 :           co_da[i][j][k]=0.;
+     228        5832 :           for(unsigned l=0; l<5; l++) pars_da[i][j][k][l]=0.;
+     229             :         }
+     230        1944 :         for(unsigned k=0; k<5; k++) co_ring[i][j][k]=0.;
+     231        9072 :         for(unsigned k=0; k<numXtraDists; k++) co_xd[i][j][k]=0.;
+     232             :       }
+     233             : 
+     234       37710 :     while(!in.eof()) {
+     235             :       std::string line;
+     236       37692 :       getline(in,line);
+     237             :       ++nline;
+     238       37692 :       if(line.compare(0,1,"#")==0) continue;
+     239             :       std::vector<std::string> tok;
+     240             :       std::vector<std::string> tmp;
+     241       40860 :       tok = split(line,' ');
+     242      261828 :       for(unsigned q=0; q<tok.size(); q++)
+     243      241398 :         if(tok[q].size()) tmp.push_back(tok[q]);
+     244       20430 :       tok = tmp;
+     245       20430 :       if(tok.size()==0) continue;
+     246       20412 :       if(tok[0]=="PAR") {
+     247         324 :         c_kind = kind(tok[2]);
+     248         324 :         c_atom = atom_kind(tok[1]);
+     249         324 :         continue;
+     250             :       }
+     251       20088 :       else if(tok[0]=="WEIGHT") {
+     252         324 :         continue;
+     253             :       }
+     254       19764 :       else if(tok[0]=="FLATBTM") {
+     255         324 :         continue;
+     256             :       }
+     257       19440 :       else if (tok[0] == "SCALEHARM") {
+     258         324 :         continue;
+     259             :       }
+     260       19116 :       else if (tok[0] == "TANHAMPLI") {
+     261         324 :         continue;
+     262             :       }
+     263       18792 :       else if (tok[0] == "ENDHARMON") {
+     264         324 :         continue;
+     265             :       }
+     266       18468 :       else if (tok[0] == "MAXRCDEVI") {
+     267         324 :         continue;
+     268             :       }
+     269       18144 :       else if (tok[0] == "RANDCOIL") {
+     270         324 :         continue;
+     271             :       }
+     272       17820 :       else if (tok[0] == "CONST") {
+     273         324 :         continue;
+     274             :       }
+     275       17496 :       else if (tok[0] == "CONSTAA") {
+     276         324 :         assign(c_aa[c_kind][c_atom],tok,1);
+     277         324 :         continue;
+     278             :       }
+     279       17172 :       else if (tok[0] == "CONSTAA-1") {
+     280         324 :         assign(c_aa_prev[c_kind][c_atom],tok,1);
+     281         324 :         continue;
+     282             :       }
+     283       16848 :       else if (tok[0] == "CONSTAA+1") {
+     284         324 :         assign(c_aa_succ[c_kind][c_atom],tok,1);
+     285         324 :         continue;
+     286             :       }
+     287       16524 :       else if (tok[0] == "COBB1") {
+     288         324 :         continue;
+     289             :       }
+     290       16200 :       else if (tok[0] == "COBB2") {
+     291             :         //angstrom to nm
+     292         324 :         assign(co_bb[c_kind][c_atom],tok,dscale);
+     293         324 :         continue;
+     294             :       }
+     295       15876 :       else if (tok[0] == "SPHERE1") {
+     296             :         // angstrom^-3 to nm^-3
+     297         324 :         assign(co_sphere[c_kind][c_atom][0],tok,1./(dscale*dscale*dscale));
+     298         324 :         continue;
+     299             :       }
+     300       15552 :       else if (tok[0] == "SPHERE2") {
+     301             :         //angstrom to nm
+     302         324 :         assign(co_sphere[c_kind][c_atom][1],tok,dscale);
+     303         324 :         continue;
+     304             :       }
+     305       15228 :       else if (tok[0] == "DIHEDRALS") {
+     306         324 :         assign(co_da[c_kind][c_atom],tok,1);
+     307         324 :         continue;
+     308             :       }
+     309       14904 :       else if (tok[0] == "RINGS") {
+     310             :         // angstrom^-3 to nm^-3
+     311         324 :         assign(co_ring[c_kind][c_atom],tok,1./(dscale*dscale*dscale));
+     312        1944 :         for(unsigned i=1; i<tok.size(); i++)
+     313        1620 :           co_ring[c_kind][c_atom][i-1] *= 1000;
+     314         324 :         continue;
+     315         324 :       }
+     316       14580 :       else if (tok[0] == "HBONDS") {
+     317         324 :         continue;
+     318             :       }
+     319       14256 :       else if (tok[0] == "XTRADISTS") {
+     320             :         //angstrom to nm
+     321         324 :         assign(co_xd[c_kind][c_atom],tok,dscale);
+     322         324 :         continue;
+     323             :       }
+     324       13932 :       else if(tok[0]=="DIHEDPHI") {
+     325         324 :         assign(pars_da[c_kind][c_atom][0],tok,1);
+     326         324 :         continue;
+     327             :       }
+     328       13608 :       else if(tok[0]=="DIHEDPSI") {
+     329         324 :         assign(pars_da[c_kind][c_atom][1],tok,1);
+     330         324 :         continue;
+     331             :       }
+     332       13284 :       else if(tok[0]=="DIHEDCHI1") {
+     333         324 :         assign(pars_da[c_kind][c_atom][2],tok,1);
+     334         324 :         continue;
+     335             :       }
+     336             : 
+     337             :       bool ok = false;
+     338             :       const std::string scIdent1 [] = {"COSCALA1", "COSCARG1", "COSCASN1", "COSCASP1", "COSCCYS1", "COSCGLN1", "COSCGLU1",
+     339             :                                        "COSCGLY1", "COSCHIS1", "COSCILE1", "COSCLEU1", "COSCLYS1", "COSCMET1", "COSCPHE1",
+     340             :                                        "COSCPRO1", "COSCSER1", "COSCTHR1", "COSCTRP1", "COSCTYR1", "COSCVAL1"
+     341      272160 :                                       };
+     342             : 
+     343      204120 :       for(unsigned scC = 0; scC < 20; scC++) {
+     344      197640 :         if(tok[0]==scIdent1[scC]) {
+     345             :           ok = true;
+     346             :           break;
+     347             :         }
+     348             :       }
+     349      285120 :       if(ok) continue;
+     350             : 
+     351             :       const std::string scIdent2 [] = {"COSCALA2", "COSCARG2", "COSCASN2", "COSCASP2", "COSCCYS2", "COSCGLN2", "COSCGLU2",
+     352             :                                        "COSCGLY2", "COSCHIS2", "COSCILE2", "COSCLEU2", "COSCLYS2", "COSCMET2", "COSCPHE2",
+     353             :                                        "COSCPRO2", "COSCSER2", "COSCTHR2", "COSCTRP2", "COSCTYR2", "COSCVAL2"
+     354      136080 :                                       };
+     355             : 
+     356       68040 :       for(unsigned scC = 0; scC < 20; scC++) {
+     357       68040 :         if(tok[0]==scIdent2[scC]) {
+     358             :           //angstrom to nm
+     359        6480 :           assign(co_sc_[c_kind][c_atom][scC],tok,dscale);
+     360             :           ok = true; break;
+     361             :         }
+     362             :       }
+     363      142560 :       if(ok) continue;
+     364             : 
+     365           0 :       if(tok.size()) {
+     366           0 :         std::string str_err = "DB WARNING: unrecognized token: " + tok[0];
+     367           0 :         plumed_merror(str_err);
+     368             :       }
+     369      428670 :     }
+     370          18 :     in.close();
+     371          18 :   }
+     372             : 
+     373             : private:
+     374             : 
+     375       20430 :   std::vector<std::string> &split(const std::string &s, char delim, std::vector<std::string> &elems) {
+     376       20430 :     std::stringstream ss(s);
+     377             :     std::string item;
+     378      261828 :     while (getline(ss, item, delim)) {
+     379      241398 :       elems.push_back(item);
+     380             :     }
+     381       20430 :     return elems;
+     382       20430 :   }
+     383             : 
+     384       20430 :   std::vector<std::string> split(const std::string &s, char delim) {
+     385             :     std::vector<std::string> elems;
+     386       20430 :     split(s, delim, elems);
+     387       20430 :     return elems;
+     388           0 :   }
+     389             : 
+     390       10368 :   void assign(double * f, const std::vector<std::string> & v, const double scale) {
+     391      122796 :     for(unsigned i=1; i<v.size(); i++) {
+     392      112428 :       f[i-1] = scale*(atof(v[i].c_str()));
+     393      112428 :       if(std::abs(f[i-1])<0.000001) f[i-1]=0.;
+     394             :     }
+     395       10368 :   }
+     396             : };
+     397             : 
+     398             : class CS2Backbone : public MetainferenceBase {
+     399             :   struct ChemicalShift {
+     400             :     double exp_cs;              // a reference chemical shifts
+     401             :     Value *comp;                // a pointer to the component
+     402             :     unsigned res_kind;          // residue type (STD/GLY/PRO)
+     403             :     unsigned atm_kind;          // nuclues (HA/CA/CB/CO/NH/HN)
+     404             :     unsigned res_type_prev;     // previous residue (ALA/VAL/..)
+     405             :     unsigned res_type_curr;     // current residue (ALA/VAL/..)
+     406             :     unsigned res_type_next;     // next residue (ALA/VAL/..)
+     407             :     std::string res_name;       // residue name
+     408             :     std::string nucleus;        // chemical shift
+     409             :     bool has_chi1;              // does we have a chi1
+     410             :     unsigned csatoms;           // fixed number of atoms used
+     411             :     unsigned totcsatoms;        // number of atoms used
+     412             :     unsigned res_num;           // residue number
+     413             :     unsigned chain;             // chain number
+     414             :     unsigned ipos;              // index of the atom for which we are calculating the chemical shifts
+     415             :     std::vector<unsigned> bb;        // atoms for the previous, current and next backbone
+     416             :     std::vector<unsigned> side_chain;// atoms for the current sidechain
+     417             :     std::vector<int> xd1;            // additional couple of atoms
+     418             :     std::vector<int> xd2;            // additional couple of atoms
+     419             :     std::vector<unsigned> box_nb;    // non-bonded atoms
+     420             : 
+     421       10602 :     ChemicalShift():
+     422       10602 :       exp_cs(0.),
+     423       10602 :       comp(NULL),
+     424       10602 :       res_kind(0),
+     425       10602 :       atm_kind(0),
+     426       10602 :       res_type_prev(0),
+     427       10602 :       res_type_curr(0),
+     428       10602 :       res_type_next(0),
+     429       10602 :       res_name(""),
+     430       10602 :       nucleus(""),
+     431       10602 :       has_chi1(true),
+     432       10602 :       csatoms(0),
+     433       10602 :       totcsatoms(0),
+     434       10602 :       res_num(0),
+     435       10602 :       chain(0),
+     436       10602 :       ipos(0)
+     437             :     {
+     438       10602 :       xd1.reserve(26);
+     439       10602 :       xd2.reserve(26);
+     440       10602 :       box_nb.reserve(150);
+     441       10602 :     }
+     442             :   };
+     443             : 
+     444             :   struct RingInfo {
+     445             :     enum {R_PHE, R_TYR, R_TRP1, R_TRP2, R_HIS};
+     446             :     unsigned rtype;    // one out of five different types
+     447             :     unsigned atom[6];  // up to six member per ring
+     448             :     unsigned numAtoms; // number of ring members (5 or 6)
+     449             :     Vector position;   // center of ring coordinates
+     450             :     Vector normVect;   // ring plane normal std::vector
+     451             :     Vector g[6];       // std::vector of the std::vectors used for normVect
+     452             :     double lengthN2;   // square of length of normVect
+     453             :     double lengthNV;   // length of normVect
+     454         360 :     RingInfo():
+     455         360 :       rtype(0),
+     456         360 :       numAtoms(0),
+     457         360 :       lengthN2(NAN),
+     458        2520 :       lengthNV(NAN)
+     459             :     {
+     460        2520 :       for(unsigned i=0; i<6; i++) atom[i]=0;
+     461         360 :     }
+     462             :   };
+     463             : 
+     464             :   enum aa_t {ALA, ARG, ASN, ASP, CYS, GLN, GLU, GLY, HIS, ILE, LEU, LYS, MET, PHE, PRO, SER, THR, TRP, TYR, VAL, UNK};
+     465             :   enum sequence_t {Np, CAp, HAp, Cp, Op, Nc, Hc, CAc, HAc, Cc, Oc, Nn, Hn, CAn, HAn, Cn, CBc, CGc};
+     466             : 
+     467             :   CS2BackboneDB    db;
+     468             :   std::vector<ChemicalShift> chemicalshifts;
+     469             : 
+     470             :   std::vector<RingInfo> ringInfo;
+     471             :   std::vector<unsigned> type;
+     472             :   std::vector<unsigned> res_num;
+     473             :   unsigned         max_cs_atoms;
+     474             :   unsigned         box_nupdate;
+     475             :   unsigned         box_count;
+     476             :   bool             camshift;
+     477             :   bool             pbc;
+     478             :   bool             serial;
+     479             : 
+     480             :   void init_cs(const std::string &file, const std::string &k, const PDB &pdb);
+     481             :   void update_neighb();
+     482             :   void compute_ring_parameters();
+     483             :   void init_types(const PDB &pdb);
+     484             :   void init_rings(const PDB &pdb);
+     485             :   aa_t frag2enum(const std::string &aa);
+     486             :   std::vector<std::string> side_chain_atoms(const std::string &s);
+     487             :   bool isSP2(const std::string & resType, const std::string & atomName);
+     488             :   bool is_chi1_cx(const std::string & frg, const std::string & atm);
+     489             :   void xdist_name_map(std::string & name);
+     490             : 
+     491             : public:
+     492             : 
+     493             :   explicit CS2Backbone(const ActionOptions&);
+     494             :   static void registerKeywords( Keywords& keys );
+     495             :   void calculate() override;
+     496             :   void update() override;
+     497             : };
+     498             : 
+     499             : PLUMED_REGISTER_ACTION(CS2Backbone,"CS2BACKBONE")
+     500             : 
+     501          20 : void CS2Backbone::registerKeywords( Keywords& keys ) {
+     502          20 :   componentsAreNotOptional(keys);
+     503          20 :   MetainferenceBase::registerKeywords( keys );
+     504          40 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     505          40 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     506          40 :   keys.add("atoms","ATOMS","The atoms to be included in the calculation, e.g. the whole protein.");
+     507          40 :   keys.add("compulsory","DATADIR","data/","The folder with the experimental chemical shifts.");
+     508          40 :   keys.add("compulsory","TEMPLATE","template.pdb","A PDB file of the protein system.");
+     509          40 :   keys.add("compulsory","NEIGH_FREQ","20","Period in step for neighbor list update.");
+     510          40 :   keys.addFlag("CAMSHIFT",false,"Set to TRUE if you to calculate a single CamShift score.");
+     511          40 :   keys.addFlag("NOEXP",false,"Set to TRUE if you don't want to have fixed components with the experimental values.");
+     512          40 :   keys.addOutputComponent("ha","default","the calculated Ha hydrogen chemical shifts");
+     513          40 :   keys.addOutputComponent("hn","default","the calculated H hydrogen chemical shifts");
+     514          40 :   keys.addOutputComponent("nh","default","the calculated N nitrogen chemical shifts");
+     515          40 :   keys.addOutputComponent("ca","default","the calculated Ca carbon chemical shifts");
+     516          40 :   keys.addOutputComponent("cb","default","the calculated Cb carbon chemical shifts");
+     517          40 :   keys.addOutputComponent("co","default","the calculated C' carbon chemical shifts");
+     518          40 :   keys.addOutputComponent("expha","default","the experimental Ha hydrogen chemical shifts");
+     519          40 :   keys.addOutputComponent("exphn","default","the experimental H hydrogen chemical shifts");
+     520          40 :   keys.addOutputComponent("expnh","default","the experimental N nitrogen chemical shifts");
+     521          40 :   keys.addOutputComponent("expca","default","the experimental Ca carbon chemical shifts");
+     522          40 :   keys.addOutputComponent("expcb","default","the experimental Cb carbon chemical shifts");
+     523          40 :   keys.addOutputComponent("expco","default","the experimental C' carbon chemical shifts");
+     524          20 : }
+     525             : 
+     526          18 : CS2Backbone::CS2Backbone(const ActionOptions&ao):
+     527             :   PLUMED_METAINF_INIT(ao),
+     528          18 :   max_cs_atoms(0),
+     529          18 :   camshift(false),
+     530          18 :   pbc(true),
+     531          18 :   serial(false)
+     532             : {
+     533             :   std::vector<AtomNumber> used_atoms;
+     534          18 :   parseAtomList("ATOMS",used_atoms);
+     535             : 
+     536          18 :   parseFlag("CAMSHIFT",camshift);
+     537          18 :   if(camshift&&getDoScore()) plumed_merror("It is not possible to use CAMSHIFT and DOSCORE at the same time");
+     538             : 
+     539          18 :   bool nopbc=!pbc;
+     540          18 :   parseFlag("NOPBC",nopbc);
+     541          18 :   pbc=!nopbc;
+     542             : 
+     543          18 :   parseFlag("SERIAL",serial);
+     544             : 
+     545          18 :   bool noexp=false;
+     546          36 :   parseFlag("NOEXP",noexp);
+     547             : 
+     548             :   std::string stringa_data;
+     549          36 :   parse("DATADIR",stringa_data);
+     550             : 
+     551             :   std::string stringa_template;
+     552          18 :   parse("TEMPLATE",stringa_template);
+     553             : 
+     554          18 :   box_count=0;
+     555          18 :   box_nupdate=20;
+     556          18 :   parse("NEIGH_FREQ", box_nupdate);
+     557             : 
+     558          18 :   std::string stringadb  = stringa_data + std::string("/camshift.db");
+     559          36 :   std::string stringapdb = stringa_data + std::string("/") + stringa_template;
+     560             : 
+     561             :   /* Length conversion (parameters are tuned for angstrom) */
+     562             :   double scale=1.;
+     563          18 :   if(!usingNaturalUnits()) {
+     564          18 :     scale = 10.*getUnits().getLength();
+     565             :   }
+     566             : 
+     567          18 :   log.printf("  Initialization of the predictor ...\n");
+     568          18 :   db.parse(stringadb,scale);
+     569             : 
+     570          18 :   PDB pdb;
+     571          18 :   if( !pdb.read(stringapdb,usingNaturalUnits(),1./scale) ) plumed_merror("missing input file " + stringapdb);
+     572             : 
+     573             :   // first of all we build the list of chemical shifts we want to predict
+     574          18 :   log.printf("  Reading experimental data ...\n"); log.flush();
+     575          36 :   stringadb = stringa_data + std::string("/CAshifts.dat");
+     576          18 :   log.printf("  Initializing CA shifts %s\n", stringadb.c_str());
+     577          18 :   init_cs(stringadb, "CA", pdb);
+     578          36 :   stringadb = stringa_data + std::string("/CBshifts.dat");
+     579          18 :   log.printf("  Initializing CB shifts %s\n", stringadb.c_str());
+     580          18 :   init_cs(stringadb, "CB", pdb);
+     581          36 :   stringadb = stringa_data + std::string("/Cshifts.dat");
+     582          18 :   log.printf("  Initializing C' shifts %s\n", stringadb.c_str());
+     583          18 :   init_cs(stringadb, "C", pdb);
+     584          36 :   stringadb = stringa_data + std::string("/HAshifts.dat");
+     585          18 :   log.printf("  Initializing HA shifts %s\n", stringadb.c_str());
+     586          18 :   init_cs(stringadb, "HA", pdb);
+     587          36 :   stringadb = stringa_data + std::string("/Hshifts.dat");
+     588          18 :   log.printf("  Initializing H shifts %s\n", stringadb.c_str());
+     589          18 :   init_cs(stringadb, "H", pdb);
+     590          36 :   stringadb = stringa_data + std::string("/Nshifts.dat");
+     591          18 :   log.printf("  Initializing N shifts %s\n", stringadb.c_str());
+     592          36 :   init_cs(stringadb, "N", pdb);
+     593             : 
+     594          18 :   if(chemicalshifts.size()==0) plumed_merror("There are no chemical shifts to calculate, there must be at least a not empty file (CA|CB|C|HA|H|N|shifts.dat)");
+     595             : 
+     596          18 :   init_types(pdb);
+     597          18 :   init_rings(pdb);
+     598             : 
+     599          18 :   log<<"  Bibliography "
+     600          36 :      <<plumed.cite("Kohlhoff K, Robustelli P, Cavalli A, Salvatella A, Vendruscolo M, J. Am. Chem. Soc. 131, 13894 (2009)");
+     601          23 :   if(camshift) log<<plumed.cite("Granata D, Camilloni C, Vendruscolo M, Laio A, Proc. Natl. Acad. Sci. USA 110, 6817 (2013)");
+     602          26 :   else log<<plumed.cite("Camilloni C, Robustelli P, De Simone A, Cavalli A, Vendruscolo M, J. Am. Chem. Soc. 134, 3968 (2012)");
+     603          36 :   log<<plumed.cite("Bonomi M, Camilloni C, Bioinformatics, 33, 3999 (2017)");
+     604          18 :   log<<"\n";
+     605             : 
+     606          18 :   if(camshift) {
+     607           5 :     noexp = true;
+     608           5 :     addValueWithDerivatives();
+     609           5 :     setNotPeriodic();
+     610             :   } else {
+     611        7670 :     for(unsigned cs=0; cs<chemicalshifts.size(); cs++) {
+     612        7657 :       std::string num; Tools::convert(chemicalshifts[cs].res_num,num);
+     613        7657 :       std::string chain_num; Tools::convert(chemicalshifts[cs].chain,chain_num);
+     614        7657 :       if(getDoScore()) {
+     615        4712 :         addComponent(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     616        4712 :         componentIsNotPeriodic(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     617        2356 :         chemicalshifts[cs].comp = getPntrToComponent(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     618        4712 :         setParameter(chemicalshifts[cs].exp_cs);
+     619             :       } else {
+     620       10602 :         addComponentWithDerivatives(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     621       10602 :         componentIsNotPeriodic(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     622        5301 :         chemicalshifts[cs].comp = getPntrToComponent(chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     623             :       }
+     624             :     }
+     625          13 :     if(getDoScore()) Initialise(chemicalshifts.size());
+     626             :   }
+     627             : 
+     628          18 :   if(!noexp) {
+     629        7670 :     for(unsigned cs=0; cs<chemicalshifts.size(); cs++) {
+     630        7657 :       std::string num; Tools::convert(chemicalshifts[cs].res_num,num);
+     631        7657 :       std::string chain_num; Tools::convert(chemicalshifts[cs].chain,chain_num);
+     632       15314 :       addComponent("exp"+chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     633       15314 :       componentIsNotPeriodic("exp"+chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     634       15314 :       Value* comp=getPntrToComponent("exp"+chemicalshifts[cs].nucleus+chain_num+"-"+num);
+     635        7657 :       comp->set(chemicalshifts[cs].exp_cs);
+     636             :     }
+     637             :   }
+     638             : 
+     639          18 :   requestAtoms(used_atoms, false);
+     640          18 :   setDerivatives();
+     641          18 :   checkRead();
+     642          36 : }
+     643             : 
+     644         108 : void CS2Backbone::init_cs(const std::string &file, const std::string &nucl, const PDB &pdb) {
+     645             :   // number of chains
+     646             :   std::vector<std::string> chains;
+     647         108 :   pdb.getChainNames( chains );
+     648             :   unsigned ichain=0;
+     649             : 
+     650         108 :   std::ifstream in;
+     651         108 :   in.open(file.c_str());
+     652         108 :   if(!in) return;
+     653         108 :   std::istream_iterator<std::string> iter(in), end;
+     654             :   unsigned begin=0;
+     655             : 
+     656         108 :   while(iter!=end) {
+     657       19008 :     std::string tok = *iter;
+     658             :     ++iter;
+     659       19008 :     if(tok[0]=='#') {
+     660             :       ++iter;
+     661         432 :       if(begin==1) {
+     662             :         begin=0;
+     663         216 :         ichain++;
+     664             :       } else begin=1;
+     665         432 :       continue;
+     666             :     }
+     667             :     int ro = atoi(tok.c_str());
+     668       18576 :     if(ro<0) plumed_merror("Residue numbers should be positive\n");
+     669       18576 :     unsigned resnum = static_cast<unsigned> (ro);
+     670             :     tok = *iter;
+     671             :     ++iter;
+     672             :     double cs = atof(tok.c_str());
+     673       18576 :     if(cs==0) continue;
+     674             : 
+     675             :     unsigned fres, lres;
+     676             :     std::string errmsg;
+     677       11070 :     pdb.getResidueRange(chains[ichain], fres, lres, errmsg);
+     678       11070 :     if(resnum==fres||resnum==lres) plumed_merror("First and Last residue of each chain should be annotated as # in " + file + " Remember that residue numbers should match");
+     679             : 
+     680             :     // check in the PDB for the chain/residue/atom and enable the chemical shift
+     681       11070 :     std::string RES = pdb.getResidueName(resnum, chains[ichain]);
+     682       98766 :     if(RES=="HIE"||RES=="HIP"||RES=="HIS"||RES=="HSP"||RES=="HSE"||RES=="CYS"||RES=="GLH"||RES=="ASH"||RES=="UNK") continue;
+     683       10944 :     if(RES=="GLN"&&nucl=="CB") continue;
+     684       11322 :     if(RES=="ILE"&&nucl=="CB") continue;
+     685       10998 :     if(RES=="PRO"&&nucl=="N") continue;
+     686       10998 :     if(RES=="PRO"&&nucl=="H") continue;
+     687       10998 :     if(RES=="PRO"&&nucl=="CB") continue;
+     688       12240 :     if(RES=="GLY"&&nucl=="HA") continue;
+     689       12240 :     if(RES=="GLY"&&nucl=="CB") continue;
+     690             : 
+     691       10602 :     ChemicalShift tmp_cs;
+     692             : 
+     693       10602 :     tmp_cs.exp_cs = cs;
+     694       10602 :     if(nucl=="CA")      tmp_cs.nucleus = "ca-";
+     695        7668 :     else if(nucl=="CB") tmp_cs.nucleus = "cb-";
+     696        5616 :     else if(nucl=="C")  tmp_cs.nucleus = "co-";
+     697        5616 :     else if(nucl=="HA") tmp_cs.nucleus = "ha-";
+     698        5616 :     else if(nucl=="H")  tmp_cs.nucleus = "hn-";
+     699        2808 :     else if(nucl=="N")  tmp_cs.nucleus = "nh-";
+     700       10602 :     tmp_cs.chain = ichain;
+     701       10602 :     tmp_cs.res_num = resnum;
+     702       10602 :     tmp_cs.res_type_curr = frag2enum(RES);
+     703       10602 :     tmp_cs.res_type_prev = frag2enum(pdb.getResidueName(resnum-1, chains[ichain]));
+     704       10602 :     tmp_cs.res_type_next = frag2enum(pdb.getResidueName(resnum+1, chains[ichain]));
+     705             :     tmp_cs.res_name = RES;
+     706       10602 :     tmp_cs.res_kind = db.kind(RES);
+     707       10602 :     tmp_cs.atm_kind = db.atom_kind(nucl);
+     708       20556 :     if(RES!="ALA"&&RES!="GLY") {tmp_cs.bb.resize(18); tmp_cs.has_chi1=true;}
+     709        2142 :     else {tmp_cs.bb.resize(16); tmp_cs.has_chi1=false;}
+     710             : 
+     711       10602 :     std::vector<AtomNumber> res_atoms = pdb.getAtomsInResidue(resnum, chains[ichain]);
+     712             :     // find the position of the nucleus and of the other backbone atoms as well as for phi/psi/chi
+     713      173268 :     for(unsigned a=0; a<res_atoms.size(); a++) {
+     714      162666 :       std::string AN = pdb.getAtomName(res_atoms[a]);
+     715      162666 :       if(nucl=="HA"&&(AN=="HA"||AN=="HA1"||AN=="HA3")) tmp_cs.ipos = res_atoms[a].index();
+     716      244530 :       else if(nucl=="H"&&(AN=="H"||AN=="HN"))          tmp_cs.ipos = res_atoms[a].index();
+     717      202248 :       else if(nucl=="N"&&AN=="N")                      tmp_cs.ipos = res_atoms[a].index();
+     718      200862 :       else if(nucl=="CA"&&AN=="CA")                    tmp_cs.ipos = res_atoms[a].index();
+     719      188244 :       else if(nucl=="CB"&&AN=="CB")                    tmp_cs.ipos = res_atoms[a].index();
+     720      152064 :       else if(nucl=="C"&&AN=="C" )                     tmp_cs.ipos = res_atoms[a].index();
+     721             :     }
+     722             : 
+     723       10602 :     std::vector<AtomNumber> prev_res_atoms = pdb.getAtomsInResidue(resnum-1, chains[ichain]);
+     724             :     // find the position of the previous residues backbone atoms
+     725      168498 :     for(unsigned a=0; a<prev_res_atoms.size(); a++) {
+     726      157896 :       std::string AN = pdb.getAtomName(prev_res_atoms[a]);
+     727      157896 :       if(AN=="N")                             { tmp_cs.bb[Np]  = prev_res_atoms[a].index(); }
+     728      147294 :       else if(AN=="CA")                       { tmp_cs.bb[CAp] = prev_res_atoms[a].index(); }
+     729      390690 :       else if(AN=="HA"||AN=="HA1"||AN=="HA3") { tmp_cs.bb[HAp] = prev_res_atoms[a].index(); }
+     730      126090 :       else if(AN=="C" )                       { tmp_cs.bb[Cp]  = prev_res_atoms[a].index(); }
+     731      115488 :       else if(AN=="O" )                       { tmp_cs.bb[Op]  = prev_res_atoms[a].index(); }
+     732             :     }
+     733             : 
+     734      173268 :     for(unsigned a=0; a<res_atoms.size(); a++) {
+     735      162666 :       std::string AN = pdb.getAtomName(res_atoms[a]);
+     736      162666 :       if(AN=="N")                                         { tmp_cs.bb[Nc]  = res_atoms[a].index(); }
+     737      438282 :       else if(AN=="H" ||AN=="HN"||(AN=="CD"&&RES=="PRO")) { tmp_cs.bb[Hc]  = res_atoms[a].index(); }
+     738      141462 :       else if(AN=="CA")                                   { tmp_cs.bb[CAc] = res_atoms[a].index(); }
+     739      372870 :       else if(AN=="HA"||AN=="HA1"||AN=="HA3")             { tmp_cs.bb[HAc] = res_atoms[a].index(); }
+     740      120258 :       else if(AN=="C" )                                   { tmp_cs.bb[Cc]  = res_atoms[a].index(); }
+     741      109656 :       else if(AN=="O" )                                   { tmp_cs.bb[Oc]  = res_atoms[a].index(); }
+     742             : 
+     743      318852 :       if(RES!="ALA"&&RES!="GLY") {
+     744      145728 :         if(AN=="CB") tmp_cs.bb[CBc] = res_atoms[a].index();
+     745      145728 :         if(is_chi1_cx(RES,AN)) tmp_cs.bb[CGc] = res_atoms[a].index();
+     746             :       }
+     747             :     }
+     748             : 
+     749       10602 :     std::vector<AtomNumber> next_res_atoms = pdb.getAtomsInResidue(resnum+1, chains[ichain]);
+     750       10602 :     std::string NRES = pdb.getResidueName(resnum+1, chains[ichain]);
+     751             :     // find the position of the previous residues backbone atoms
+     752      168948 :     for(unsigned a=0; a<next_res_atoms.size(); a++) {
+     753      158346 :       std::string AN = pdb.getAtomName(next_res_atoms[a]);
+     754      158346 :       if(AN=="N")                                          { tmp_cs.bb[Nn]  = next_res_atoms[a].index(); }
+     755      426096 :       else if(AN=="H" ||AN=="HN"||(AN=="CD"&&NRES=="PRO")) { tmp_cs.bb[Hn]  = next_res_atoms[a].index(); }
+     756      137142 :       else if(AN=="CA")                                    { tmp_cs.bb[CAn] = next_res_atoms[a].index(); }
+     757      360198 :       else if(AN=="HA"||AN=="HA1"||AN=="HA3")              { tmp_cs.bb[HAn] = next_res_atoms[a].index(); }
+     758      115938 :       else if(AN=="C" )                                    { tmp_cs.bb[Cn]  = next_res_atoms[a].index(); }
+     759             :     }
+     760             : 
+     761             :     // set sidechain atoms
+     762       10602 :     std::vector<std::string> sc_atm = side_chain_atoms(RES);
+     763             : 
+     764      141084 :     for(unsigned sc=0; sc<sc_atm.size(); sc++) {
+     765     2501208 :       for(unsigned aa=0; aa<res_atoms.size(); aa++) {
+     766     2370726 :         if(pdb.getAtomName(res_atoms[aa])==sc_atm[sc]) {
+     767       99162 :           tmp_cs.side_chain.push_back(res_atoms[aa].index());
+     768             :         }
+     769             :       }
+     770             :     }
+     771             : 
+     772             :     // find atoms for extra distances
+     773      286254 :     const std::string atomsP1[] =  {"H", "H", "H", "C", "C", "C", "O", "O", "O", "N", "N", "N", "O", "O", "O", "N", "N", "N", "CG", "CG", "CG", "CG", "CG", "CG", "CG", "CA"};
+     774       10602 :     const int resOffsetP1[] = { 0,   0,   0,  -1,  -1,  -1,   0,   0,   0,   1,   1,   1,   -1,  -1,  -1,  0,   0,   0,   0,    0,    0,    0,    0,    -1,   1,    -1};
+     775             : 
+     776      286254 :     const std::string atomsP2[] =  {"HA", "C", "CB", "HA", "C", "CB", "HA", "N", "CB", "HA", "N", "CB", "HA", "N", "CB", "HA", "N", "CB", "HA", "N", "C", "C", "N", "CA", "CA", "CA"};
+     777       10602 :     const int resOffsetP2[] = { 0,    0,   0,    0,    0,   0,    0,    0,   0,    0,    0,   0,    -1,  -1,   -1,   -1,  -1,   -1,   0,    0,   0,   -1,  1,   0,    0,    1};
+     778             : 
+     779      286254 :     for(unsigned q=0; q<db.get_numXtraDists()-1; q++) {
+     780             :       std::vector<AtomNumber> at1;
+     781      275652 :       if(resOffsetP1[q]== 0) at1 = res_atoms;
+     782      275652 :       if(resOffsetP1[q]==-1) at1 = prev_res_atoms;
+     783      275652 :       if(resOffsetP1[q]==+1) at1 = next_res_atoms;
+     784             : 
+     785             :       std::vector<AtomNumber> at2;
+     786      275652 :       if(resOffsetP2[q]== 0) at2 = res_atoms;
+     787      275652 :       if(resOffsetP2[q]==-1) at2 = prev_res_atoms;
+     788      275652 :       if(resOffsetP2[q]==+1) at2 = next_res_atoms;
+     789             : 
+     790      275652 :       int tmp1 = -1;
+     791     2197566 :       for(unsigned a=0; a<at1.size(); a++) {
+     792     2181708 :         std::string name = pdb.getAtomName(at1[a]);
+     793     2181708 :         xdist_name_map(name);
+     794             : 
+     795     2181708 :         if(name==atomsP1[q]) {
+     796      259794 :           tmp1 = at1[a].index();
+     797             :           break;
+     798             :         }
+     799             :       }
+     800             : 
+     801      275652 :       int tmp2 = -1;
+     802     1427688 :       for(unsigned a=0; a<at2.size(); a++) {
+     803     1418076 :         std::string name = pdb.getAtomName(at2[a]);
+     804     1418076 :         xdist_name_map(name);
+     805             : 
+     806     1418076 :         if(name==atomsP2[q]) {
+     807      266040 :           tmp2 = at2[a].index();
+     808             :           break;
+     809             :         }
+     810             :       }
+     811             : 
+     812      275652 :       tmp_cs.xd1.push_back(tmp1);
+     813      275652 :       tmp_cs.xd2.push_back(tmp2);
+     814             :     }
+     815             : 
+     816             :     // ready to add a new chemical shifts
+     817       10602 :     tmp_cs.csatoms = 1 + 16 + tmp_cs.side_chain.size() + 2*tmp_cs.xd1.size();
+     818       20556 :     if(tmp_cs.res_name!="ALA"&&tmp_cs.res_name!="GLY") tmp_cs.csatoms += 2;
+     819       10602 :     chemicalshifts.push_back(tmp_cs);
+     820      593712 :   }
+     821             : 
+     822         108 :   in.close();
+     823         108 : }
+     824             : 
+     825             : // this assigns an atom-type to each atom of the pdb
+     826          18 : void CS2Backbone::init_types(const PDB &pdb) {
+     827             :   enum atom_t {D_C, D_H, D_N, D_O, D_S, D_C2, D_N2, D_O2};
+     828          18 :   std::vector<AtomNumber> aa = pdb.getAtomNumbers();
+     829       47034 :   for(unsigned i=0; i<aa.size(); i++) {
+     830       47016 :     unsigned frag = pdb.getResidueNumber(aa[i]);
+     831       47016 :     std::string fragName = pdb.getResidueName(aa[i]);
+     832       47016 :     std::string atom_name = pdb.getAtomName(aa[i]);
+     833       47016 :     char atom_type = atom_name[0];
+     834       47016 :     if(isdigit(atom_name[0])) atom_type = atom_name[1];
+     835       47016 :     res_num.push_back(frag);
+     836       47016 :     unsigned t = 0;
+     837       47016 :     if (!isSP2(fragName, atom_name)) {
+     838             :       if (atom_type == 'C') t = D_C;
+     839         468 :       else if (atom_type == 'O') t = D_O;
+     840       23256 :       else if (atom_type == 'H') t = D_H;
+     841        4032 :       else if (atom_type == 'N') t = D_N;
+     842         162 :       else if (atom_type == 'S') t = D_S;
+     843           0 :       else plumed_merror("Unknown atom type: " + atom_name);
+     844             :     } else {
+     845       10080 :       if (atom_type == 'C') t = D_C2;
+     846        4104 :       else if (atom_type == 'O') t = D_O2;
+     847           0 :       else if (atom_type == 'N') t = D_N2;
+     848           0 :       else plumed_merror("Unknown atom type: " + atom_name);
+     849             :     }
+     850       47016 :     type.push_back(t);
+     851             :   }
+     852          18 : }
+     853             : 
+     854          18 : void CS2Backbone::init_rings(const PDB &pdb)
+     855             : {
+     856         126 :   const std::string pheTyr_n[] = {"CG","CD1","CE1","CZ","CE2","CD2"};
+     857         126 :   const std::string trp1_n[]   = {"CD2","CE2","CZ2","CH2","CZ3","CE3"};
+     858         108 :   const std::string trp2_n[]   = {"CG","CD1","NE1","CE2","CD2"};
+     859         108 :   const std::string his_n[]    = {"CG","ND1","CD2","CE1","NE2"};
+     860             : 
+     861             :   // number of chains
+     862             :   std::vector<std::string> chains;
+     863          18 :   pdb.getChainNames( chains );
+     864             :   unsigned total_rings_atoms = 0;
+     865             : 
+     866             :   // cycle over chains
+     867          54 :   for(unsigned i=0; i<chains.size(); i++) {
+     868             :     unsigned start, end;
+     869             :     std::string errmsg;
+     870          36 :     pdb.getResidueRange( chains[i], start, end, errmsg );
+     871             :     // cycle over residues
+     872        3168 :     for(unsigned res=start; res<end; res++) {
+     873        3132 :       std::string frg = pdb.getResidueName(res, chains[i]);
+     874       14364 :       if(!((frg=="PHE")||(frg=="TYR")||(frg=="TRP")||
+     875        8370 :            (frg=="HIS")||(frg=="HIP")||(frg=="HID")||
+     876        5580 :            (frg=="HIE")||(frg=="HSD")||(frg=="HSE")||
+     877             :            (frg=="HSP"))) continue;
+     878             : 
+     879         342 :       std::vector<AtomNumber> frg_atoms = pdb.getAtomsInResidue(res,chains[i]);
+     880             : 
+     881         396 :       if(frg=="PHE"||frg=="TYR") {
+     882         324 :         RingInfo ri;
+     883        6840 :         for(unsigned a=0; a<frg_atoms.size(); a++) {
+     884             :           unsigned atm = frg_atoms[a].index();
+     885       38808 :           for(unsigned aa=0; aa<6; aa++) {
+     886       34236 :             if(pdb.getAtomName(frg_atoms[a])==pheTyr_n[aa]) {
+     887        1944 :               ri.atom[aa] = atm;
+     888        1944 :               break;
+     889             :             }
+     890             :           }
+     891             :         }
+     892         324 :         ri.numAtoms = 6;
+     893         324 :         total_rings_atoms += 6;
+     894         324 :         if(frg=="PHE") ri.rtype = RingInfo::R_PHE;
+     895         324 :         if(frg=="TYR") ri.rtype = RingInfo::R_TYR;
+     896         324 :         ringInfo.push_back(ri);
+     897             : 
+     898          18 :       } else if(frg=="TRP") {
+     899             :         //First ring
+     900          18 :         RingInfo ri;
+     901         450 :         for(unsigned a=0; a<frg_atoms.size(); a++) {
+     902             :           unsigned atm = frg_atoms[a].index();
+     903        2646 :           for(unsigned aa=0; aa<6; aa++) {
+     904        2322 :             if(pdb.getAtomName(frg_atoms[a])==trp1_n[aa]) {
+     905         108 :               ri.atom[aa] = atm;
+     906         108 :               break;
+     907             :             }
+     908             :           }
+     909             :         }
+     910          18 :         ri.numAtoms = 6;
+     911             :         total_rings_atoms += 6;
+     912          18 :         ri.rtype = RingInfo::R_TRP1;
+     913          18 :         ringInfo.push_back(ri);
+     914             :         //Second Ring
+     915          18 :         RingInfo ri2;
+     916         450 :         for(unsigned a=0; a<frg_atoms.size(); a++) {
+     917             :           unsigned atm = frg_atoms[a].index();
+     918        2322 :           for(unsigned aa=0; aa<5; aa++) {
+     919        1980 :             if(pdb.getAtomName(frg_atoms[a])==trp2_n[aa]) {
+     920          90 :               ri2.atom[aa] = atm;
+     921          90 :               break;
+     922             :             }
+     923             :           }
+     924             :         }
+     925          18 :         ri2.numAtoms = 5;
+     926          18 :         total_rings_atoms += 3;
+     927          18 :         ri2.rtype = RingInfo::R_TRP2;
+     928          18 :         ringInfo.push_back(ri2);
+     929             : 
+     930           0 :       } else if((frg=="HIS")||(frg=="HIP")||(frg=="HID")||
+     931           0 :                 (frg=="HIE")||(frg=="HSD")||(frg=="HSE")||
+     932             :                 (frg=="HSP")) {//HIS case
+     933           0 :         RingInfo ri;
+     934           0 :         for(unsigned a=0; a<frg_atoms.size(); a++) {
+     935             :           unsigned atm = frg_atoms[a].index();
+     936           0 :           for(unsigned aa=0; aa<5; aa++) {
+     937           0 :             if(pdb.getAtomName(frg_atoms[a])==his_n[aa]) {
+     938           0 :               ri.atom[aa] = atm;
+     939           0 :               break;
+     940             :             }
+     941             :           }
+     942             :         }
+     943           0 :         ri.numAtoms = 5;
+     944           0 :         total_rings_atoms += 3;
+     945           0 :         ri.rtype = RingInfo::R_HIS;
+     946           0 :         ringInfo.push_back(ri);
+     947             :       } else {
+     948           0 :         plumed_merror("Unknown Ring Fragment: " + frg);
+     949             :       }
+     950             :     }
+     951             :   }
+     952             : 
+     953       10620 :   for(unsigned cs=0; cs<chemicalshifts.size(); cs++) chemicalshifts[cs].csatoms += total_rings_atoms;
+     954         486 : }
+     955             : 
+     956          18 : void CS2Backbone::calculate()
+     957             : {
+     958          18 :   if(pbc) makeWhole();
+     959          18 :   if(getExchangeStep()) box_count=0;
+     960          18 :   if(box_count==0) update_neighb();
+     961          18 :   compute_ring_parameters();
+     962             : 
+     963          18 :   std::vector<double> camshift_sigma2(6);
+     964          18 :   camshift_sigma2[0] = 0.08; // HA
+     965          18 :   camshift_sigma2[1] = 0.30; // HN
+     966          18 :   camshift_sigma2[2] = 9.00; // NH
+     967          18 :   camshift_sigma2[3] = 1.30; // CA
+     968          18 :   camshift_sigma2[4] = 1.56; // CB
+     969          18 :   camshift_sigma2[5] = 1.70; // CO
+     970             : 
+     971             :   std::vector<Vector>   cs_derivs;
+     972             :   std::vector<Vector>   aa_derivs;
+     973             :   std::vector<unsigned> cs_atoms;
+     974             :   std::vector<double>   all_shifts;
+     975             : 
+     976          18 :   cs_derivs.resize(chemicalshifts.size()*max_cs_atoms,Vector(0,0,0));
+     977          18 :   cs_atoms.resize(chemicalshifts.size()*max_cs_atoms,0);
+     978          18 :   all_shifts.resize(chemicalshifts.size(),0);
+     979          18 :   if(camshift||getDoScore()) aa_derivs.resize(getNumberOfAtoms(),Vector(0,0,0));
+     980             : 
+     981          18 :   unsigned stride = comm.Get_size();
+     982          18 :   unsigned rank   = comm.Get_rank();
+     983          18 :   if(serial) {
+     984             :     stride = 1;
+     985             :     rank   = 0;
+     986             :   }
+     987             : 
+     988          18 :   unsigned nt=OpenMP::getNumThreads();
+     989          18 :   if(nt*stride*2>chemicalshifts.size()) nt=1;
+     990             : 
+     991             :   // a single loop over all chemical shifts
+     992          18 :   #pragma omp parallel num_threads(nt)
+     993             :   {
+     994             :     #pragma omp for schedule(dynamic)
+     995             :     for(unsigned cs=rank; cs<chemicalshifts.size(); cs+=stride) {
+     996             :       const unsigned kdx=cs*max_cs_atoms;
+     997             :       const ChemicalShift *myfrag = &chemicalshifts[cs];
+     998             :       const unsigned aa_kind = myfrag->res_kind;
+     999             :       const unsigned at_kind = myfrag->atm_kind;
+    1000             : 
+    1001             :       double shift = db.CONSTAAPREV(aa_kind,at_kind)[myfrag->res_type_prev] +
+    1002             :                      db.CONSTAACURR(aa_kind,at_kind)[myfrag->res_type_curr] +
+    1003             :                      db.CONSTAANEXT(aa_kind,at_kind)[myfrag->res_type_next];
+    1004             : 
+    1005             :       const unsigned ipos = myfrag->ipos;
+    1006             :       cs_atoms[kdx+0] = ipos;
+    1007             :       unsigned atom_counter = 1;
+    1008             : 
+    1009             :       //BACKBONE (PREV CURR NEXT)
+    1010             :       const double * CONST_BB2 = db.CONST_BB2(aa_kind,at_kind);
+    1011             :       const unsigned bbsize = 16;
+    1012             :       for(unsigned q=0; q<bbsize; q++) {
+    1013             :         const double cb2q = CONST_BB2[q];
+    1014             :         if(cb2q==0.) continue;
+    1015             :         const unsigned jpos = myfrag->bb[q];
+    1016             :         if(ipos==jpos) continue;
+    1017             :         const Vector distance = delta(getPosition(jpos),getPosition(ipos));
+    1018             :         const double d = distance.modulo();
+    1019             :         const double fact = cb2q/d;
+    1020             : 
+    1021             :         shift += cb2q*d;
+    1022             :         const Vector der = fact*distance;
+    1023             : 
+    1024             :         cs_derivs[kdx+0] += der;
+    1025             :         cs_derivs[kdx+q+atom_counter] = -der;
+    1026             :         cs_atoms[kdx+q+atom_counter] = jpos;
+    1027             :       }
+    1028             : 
+    1029             :       atom_counter += bbsize;
+    1030             : 
+    1031             :       //DIHEDRAL ANGLES
+    1032             :       const double *CO_DA = db.CO_DA(aa_kind,at_kind);
+    1033             :       //Phi
+    1034             :       {
+    1035             :         const Vector d0 = delta(getPosition(myfrag->bb[Nc]), getPosition(myfrag->bb[Cp]));
+    1036             :         const Vector d1 = delta(getPosition(myfrag->bb[CAc]), getPosition(myfrag->bb[Nc]));
+    1037             :         const Vector d2 = delta(getPosition(myfrag->bb[Cc]), getPosition(myfrag->bb[CAc]));
+    1038             :         Torsion t;
+    1039             :         Vector dd0, dd1, dd2;
+    1040             :         const double t_phi = t.compute(d0,d1,d2,dd0,dd1,dd2);
+    1041             :         const double *PARS_DA = db.PARS_DA(aa_kind,at_kind,0);
+    1042             :         const double val1 = 3.*t_phi+PARS_DA[3];
+    1043             :         const double val2 = t_phi+PARS_DA[4];
+    1044             :         shift += CO_DA[0]*(PARS_DA[0]*std::cos(val1)+PARS_DA[1]*std::cos(val2)+PARS_DA[2]);
+    1045             :         const double fact = -CO_DA[0]*(+3.*PARS_DA[0]*std::sin(val1)+PARS_DA[1]*std::sin(val2));
+    1046             : 
+    1047             :         cs_derivs[kdx+Cp+1] += fact*dd0;
+    1048             :         cs_derivs[kdx+Nc+1] += fact*(dd1-dd0);
+    1049             :         cs_derivs[kdx+CAc+1]+= fact*(dd2-dd1);
+    1050             :         cs_derivs[kdx+Cc+1] += -fact*dd2;
+    1051             :         cs_atoms[kdx+Cp+1] = myfrag->bb[Cp];
+    1052             :         cs_atoms[kdx+Nc+1] = myfrag->bb[Nc];
+    1053             :         cs_atoms[kdx+CAc+1]= myfrag->bb[CAc];
+    1054             :         cs_atoms[kdx+Cc+1] = myfrag->bb[Cc];
+    1055             :       }
+    1056             : 
+    1057             :       //Psi
+    1058             :       {
+    1059             :         const Vector d0 = delta(getPosition(myfrag->bb[CAc]), getPosition(myfrag->bb[Nc]));
+    1060             :         const Vector d1 = delta(getPosition(myfrag->bb[Cc]), getPosition(myfrag->bb[CAc]));
+    1061             :         const Vector d2 = delta(getPosition(myfrag->bb[Nn]), getPosition(myfrag->bb[Cc]));
+    1062             :         Torsion t;
+    1063             :         Vector dd0, dd1, dd2;
+    1064             :         const double t_psi = t.compute(d0,d1,d2,dd0,dd1,dd2);
+    1065             :         const double *PARS_DA = db.PARS_DA(aa_kind,at_kind,1);
+    1066             :         const double val1 = 3.*t_psi+PARS_DA[3];
+    1067             :         const double val2 = t_psi+PARS_DA[4];
+    1068             :         shift += CO_DA[1]*(PARS_DA[0]*std::cos(val1)+PARS_DA[1]*std::cos(val2)+PARS_DA[2]);
+    1069             :         const double fact = -CO_DA[1]*(+3.*PARS_DA[0]*std::sin(val1)+PARS_DA[1]*std::sin(val2));
+    1070             : 
+    1071             :         cs_derivs[kdx+Nc+1] += fact*dd0;
+    1072             :         cs_derivs[kdx+CAc+1] += fact*(dd1-dd0);
+    1073             :         cs_derivs[kdx+Cc+1] += fact*(dd2-dd1);
+    1074             :         cs_derivs[kdx+Nn+1] += -fact*dd2;
+    1075             :         cs_atoms[kdx+Nc+1] = myfrag->bb[Nc];
+    1076             :         cs_atoms[kdx+CAc+1]= myfrag->bb[CAc];
+    1077             :         cs_atoms[kdx+Cc+1] = myfrag->bb[Cc];
+    1078             :         cs_atoms[kdx+Nn+1] = myfrag->bb[Nn];
+    1079             :       }
+    1080             : 
+    1081             :       //Chi
+    1082             :       if(myfrag->has_chi1) {
+    1083             :         const Vector d0 = delta(getPosition(myfrag->bb[CAc]), getPosition(myfrag->bb[Nc]));
+    1084             :         const Vector d1 = delta(getPosition(myfrag->bb[CBc]), getPosition(myfrag->bb[CAc]));
+    1085             :         const Vector d2 = delta(getPosition(myfrag->bb[CGc]), getPosition(myfrag->bb[CBc]));
+    1086             :         Torsion t;
+    1087             :         Vector dd0, dd1, dd2;
+    1088             :         const double t_chi1 = t.compute(d0,d1,d2,dd0,dd1,dd2);
+    1089             :         const double *PARS_DA = db.PARS_DA(aa_kind,at_kind,2);
+    1090             :         const double val1 = 3.*t_chi1+PARS_DA[3];
+    1091             :         const double val2 = t_chi1+PARS_DA[4];
+    1092             :         shift += CO_DA[2]*(PARS_DA[0]*std::cos(val1)+PARS_DA[1]*std::cos(val2)+PARS_DA[2]);
+    1093             :         const double fact = -CO_DA[2]*(+3.*PARS_DA[0]*std::sin(val1)+PARS_DA[1]*std::sin(val2));
+    1094             : 
+    1095             :         cs_derivs[kdx+Nc+1] += fact*dd0;
+    1096             :         cs_derivs[kdx+CAc+1] += fact*(dd1-dd0);
+    1097             :         cs_derivs[kdx+CBc+1] += fact*(dd2-dd1);
+    1098             :         cs_derivs[kdx+CGc+1] += -fact*dd2;
+    1099             :         cs_atoms[kdx+Nc+1]  = myfrag->bb[Nc];
+    1100             :         cs_atoms[kdx+CAc+1] = myfrag->bb[CAc];
+    1101             :         cs_atoms[kdx+CBc+1] = myfrag->bb[CBc];
+    1102             :         cs_atoms[kdx+CGc+1] = myfrag->bb[CGc];
+    1103             : 
+    1104             :         atom_counter += 2;
+    1105             :       }
+    1106             :       //END OF DIHE
+    1107             : 
+    1108             :       //SIDE CHAIN
+    1109             :       const double * CONST_SC2 = db.CONST_SC2(aa_kind,at_kind,myfrag->res_type_curr);
+    1110             :       const unsigned sidsize = myfrag->side_chain.size();
+    1111             :       for(unsigned q=0; q<sidsize; q++) {
+    1112             :         const double cs2q = CONST_SC2[q];
+    1113             :         if(cs2q==0.) continue;
+    1114             :         const unsigned jpos = myfrag->side_chain[q];
+    1115             :         if(ipos==jpos) continue;
+    1116             :         const Vector distance = delta(getPosition(jpos),getPosition(ipos));
+    1117             :         const double d = distance.modulo();
+    1118             :         const double fact = cs2q/d;
+    1119             : 
+    1120             :         shift += cs2q*d;
+    1121             :         const Vector der = fact*distance;
+    1122             :         cs_derivs[kdx+0] += der;
+    1123             :         cs_derivs[kdx+q+atom_counter] = -der;
+    1124             :         cs_atoms[kdx+q+atom_counter] = jpos;
+    1125             :       }
+    1126             : 
+    1127             :       atom_counter += sidsize;
+    1128             : 
+    1129             :       //EXTRA DIST
+    1130             :       const double * CONST_XD  = db.CONST_XD(aa_kind,at_kind);
+    1131             :       const unsigned xdsize=myfrag->xd1.size();
+    1132             :       for(unsigned q=0; q<xdsize; q++) {
+    1133             :         const double cxdq = CONST_XD[q];
+    1134             :         if(cxdq==0.) continue;
+    1135             :         if(myfrag->xd1[q]==-1||myfrag->xd2[q]==-1) continue;
+    1136             :         const Vector distance = delta(getPosition(myfrag->xd1[q]),getPosition(myfrag->xd2[q]));
+    1137             :         const double d = distance.modulo();
+    1138             :         const double fact = cxdq/d;
+    1139             : 
+    1140             :         shift += cxdq*d;
+    1141             :         const Vector der = fact*distance;
+    1142             :         cs_derivs[kdx+2*q+atom_counter  ] = der;
+    1143             :         cs_derivs[kdx+2*q+atom_counter+1] = -der;
+    1144             :         cs_atoms[kdx+2*q+atom_counter] = myfrag->xd2[q];
+    1145             :         cs_atoms[kdx+2*q+atom_counter+1] = myfrag->xd1[q];
+    1146             :       }
+    1147             : 
+    1148             :       atom_counter += 2*xdsize;
+    1149             : 
+    1150             :       //RINGS
+    1151             :       const double *rc = db.CO_RING(aa_kind,at_kind);
+    1152             :       const unsigned rsize = ringInfo.size();
+    1153             :       // cycle over the list of rings
+    1154             :       for(unsigned q=0; q<rsize; q++) {
+    1155             :         // compute angle from ring middle point to current atom position
+    1156             :         // get distance std::vector from query atom to ring center and normal std::vector to ring plane
+    1157             :         const Vector n   = ringInfo[q].normVect;
+    1158             :         const double nL  = ringInfo[q].lengthNV;
+    1159             :         const double inL2 = ringInfo[q].lengthN2;
+    1160             : 
+    1161             :         const Vector d = delta(ringInfo[q].position, getPosition(ipos));
+    1162             :         const double dL2 = d.modulo2();
+    1163             :         double dL  = std::sqrt(dL2);
+    1164             :         const double idL3 = 1./(dL2*dL);
+    1165             : 
+    1166             :         const double dn    = dotProduct(d,n);
+    1167             :         const double dn2   = dn*dn;
+    1168             :         const double dLnL  = dL*nL;
+    1169             :         const double dL_nL = dL/nL;
+    1170             : 
+    1171             :         const double ang2 = dn2*inL2/dL2;
+    1172             :         const double u    = 1.-3.*ang2;
+    1173             :         const double cc   = rc[ringInfo[q].rtype];
+    1174             : 
+    1175             :         shift += cc*u*idL3;
+    1176             : 
+    1177             :         const double fUU    = -6.*dn*inL2;
+    1178             :         const double fUQ    = fUU/dL;
+    1179             :         const Vector gradUQ = fUQ*(dL2*n - dn*d);
+    1180             :         const Vector gradVQ = (3.*dL*u)*d;
+    1181             : 
+    1182             :         const double fact   = cc*idL3*idL3;
+    1183             :         cs_derivs[kdx+0] += fact*(gradUQ - gradVQ);
+    1184             : 
+    1185             :         const double fU       = fUU/nL;
+    1186             :         double OneOverN = 1./6.;
+    1187             :         if(ringInfo[q].numAtoms==5) OneOverN=1./3.;
+    1188             :         const Vector factor2  = OneOverN*n;
+    1189             :         const Vector factor4  = (OneOverN/dL_nL)*d;
+    1190             : 
+    1191             :         const Vector gradV    = -OneOverN*gradVQ;
+    1192             : 
+    1193             :         if(ringInfo[q].numAtoms==6) {
+    1194             :           // update forces on ring atoms
+    1195             :           for(unsigned at=0; at<6; at++) {
+    1196             :             const Vector ab = crossProduct(d,ringInfo[q].g[at]);
+    1197             :             const Vector c  = crossProduct(n,ringInfo[q].g[at]);
+    1198             :             const Vector factor3 = 0.5*dL_nL*c;
+    1199             :             const Vector factor1 = 0.5*ab;
+    1200             :             const Vector gradU   = fU*( dLnL*(factor1 - factor2) -dn*(factor3 - factor4) );
+    1201             :             cs_derivs[kdx+at+atom_counter] = fact*(gradU - gradV);
+    1202             :             cs_atoms[kdx+at+atom_counter] = ringInfo[q].atom[at];
+    1203             :           }
+    1204             :           atom_counter += 6;
+    1205             :         }  else {
+    1206             :           for(unsigned at=0; at<3; at++) {
+    1207             :             const Vector ab = crossProduct(d,ringInfo[q].g[at]);
+    1208             :             const Vector c  = crossProduct(n,ringInfo[q].g[at]);
+    1209             :             const Vector factor3 = dL_nL*c;
+    1210             :             const Vector factor1 = ab;
+    1211             :             const Vector gradU   = fU*( dLnL*(factor1 - factor2) -dn*(factor3 - factor4) );
+    1212             :             cs_derivs[kdx+at+atom_counter] = fact*(gradU - gradV);
+    1213             :           }
+    1214             :           cs_atoms[kdx+atom_counter] = ringInfo[q].atom[0];
+    1215             :           cs_atoms[kdx+atom_counter+1] = ringInfo[q].atom[2];
+    1216             :           cs_atoms[kdx+atom_counter+2] = ringInfo[q].atom[3];
+    1217             :           atom_counter += 3;
+    1218             :         }
+    1219             :       }
+    1220             :       //END OF RINGS
+    1221             : 
+    1222             :       //NON BOND
+    1223             :       const double * CONST_CO_SPHERE3 = db.CO_SPHERE(aa_kind,at_kind,0);
+    1224             :       const double * CONST_CO_SPHERE  = db.CO_SPHERE(aa_kind,at_kind,1);
+    1225             :       const unsigned boxsize = myfrag->box_nb.size();
+    1226             :       for(unsigned q=0; q<boxsize; q++) {
+    1227             :         const unsigned jpos = myfrag->box_nb[q];
+    1228             :         const Vector distance = delta(getPosition(jpos),getPosition(ipos));
+    1229             :         const double d2 = distance.modulo2();
+    1230             : 
+    1231             :         if(d2<cutOffDist2) {
+    1232             :           double factor1  = std::sqrt(d2);
+    1233             :           double dfactor1 = 1./factor1;
+    1234             :           double factor3  = dfactor1*dfactor1*dfactor1;
+    1235             :           double dfactor3 = -3.*factor3*dfactor1*dfactor1;
+    1236             : 
+    1237             :           if(d2>cutOnDist2) {
+    1238             :             const double af = cutOffDist2 - d2;
+    1239             :             const double bf = cutOffDist2 - 3.*cutOnDist2 + 2.*d2;
+    1240             :             const double cf = invswitch*af;
+    1241             :             const double df = cf*af*bf;
+    1242             :             factor1 *= df;
+    1243             :             factor3 *= df;
+    1244             : 
+    1245             :             const double d4  = d2*d2;
+    1246             :             const double af1 = 15.*cutOnDist2*d2;
+    1247             :             const double bf1 = -14.*d4;
+    1248             :             const double cf1 = -3.*cutOffDist2*cutOnDist2 + cutOffDist2*d2;
+    1249             :             const double df1 = af1+bf1+cf1;
+    1250             :             dfactor1 *= cf*(cutOffDist4+df1);
+    1251             : 
+    1252             :             const double af3 = +2.*cutOffDist2*cutOnDist2;
+    1253             :             const double bf3 = d2*(cutOffDist2+cutOnDist2);
+    1254             :             const double cf3 = -2.*d4;
+    1255             :             const double df3 = (af3+bf3+cf3)*d2;
+    1256             :             dfactor3 *= invswitch*(cutMixed+df3);
+    1257             :           }
+    1258             : 
+    1259             :           const unsigned t = type[jpos];
+    1260             :           shift += factor1*CONST_CO_SPHERE[t] + factor3*CONST_CO_SPHERE3[t] ;
+    1261             :           const double fact = dfactor1*CONST_CO_SPHERE[t]+dfactor3*CONST_CO_SPHERE3[t];
+    1262             :           const Vector der  = fact*distance;
+    1263             : 
+    1264             :           cs_derivs[kdx+0] += der;
+    1265             :           cs_derivs[kdx+q+atom_counter] = -der;
+    1266             :           cs_atoms[kdx+q+atom_counter] = jpos;
+    1267             :         }
+    1268             :       }
+    1269             :       //END NON BOND
+    1270             : 
+    1271             :       atom_counter += boxsize;
+    1272             :       all_shifts[cs] = shift;
+    1273             :     }
+    1274             :   }
+    1275             : 
+    1276          18 :   ++box_count;
+    1277          18 :   if(box_count == box_nupdate) box_count = 0;
+    1278             : 
+    1279          18 :   if(!camshift) {
+    1280          13 :     if(!serial) {
+    1281          13 :       if(!getDoScore()) {
+    1282           9 :         comm.Sum(&cs_derivs[0][0], 3*cs_derivs.size());
+    1283           9 :         comm.Sum(&cs_atoms[0], cs_atoms.size());
+    1284             :       }
+    1285          13 :       comm.Sum(&all_shifts[0], chemicalshifts.size());
+    1286             :     }
+    1287        7670 :     for(unsigned cs=0; cs<chemicalshifts.size(); cs++) {
+    1288        7657 :       Value *comp = chemicalshifts[cs].comp;
+    1289        7657 :       comp->set(all_shifts[cs]);
+    1290        7657 :       if(getDoScore()) setCalcData(cs, all_shifts[cs]);
+    1291             :       else {
+    1292        5301 :         const unsigned kdx=cs*max_cs_atoms;
+    1293        5301 :         Tensor csvirial;
+    1294     1270127 :         for(unsigned i=0; i<chemicalshifts[cs].totcsatoms; i++) {
+    1295     1264826 :           setAtomsDerivatives(comp,cs_atoms[kdx+i],cs_derivs[kdx+i]);
+    1296     1264826 :           csvirial-=Tensor(getPosition(cs_atoms[kdx+i]),cs_derivs[kdx+i]);
+    1297             :         }
+    1298        5301 :         setBoxDerivatives(comp,csvirial);
+    1299             :       }
+    1300             :     }
+    1301          13 :     if(!getDoScore()) return;
+    1302             :   }
+    1303             : 
+    1304           9 :   double score = 0.;
+    1305             : 
+    1306             :   /* Metainference */
+    1307           9 :   if(getDoScore()) {
+    1308           4 :     score = getScore();
+    1309        1182 :     for(unsigned cs=rank; cs<chemicalshifts.size(); cs+=stride) {
+    1310        1178 :       const unsigned kdx=cs*max_cs_atoms;
+    1311             :       const double fact = getMetaDer(cs);
+    1312      282215 :       for(unsigned i=0; i<chemicalshifts[cs].totcsatoms; i++) {
+    1313      281037 :         aa_derivs[cs_atoms[kdx+i]] += cs_derivs[kdx+i]*fact;
+    1314             :       }
+    1315             :     }
+    1316             :   }
+    1317             : 
+    1318             :   /* camshift */
+    1319           9 :   if(camshift) {
+    1320        1772 :     for(unsigned cs=rank; cs<chemicalshifts.size(); cs+=stride) {
+    1321        1767 :       const unsigned kdx=cs*max_cs_atoms;
+    1322        1767 :       score += (all_shifts[cs] - chemicalshifts[cs].exp_cs)*(all_shifts[cs] - chemicalshifts[cs].exp_cs)/camshift_sigma2[chemicalshifts[cs].atm_kind];
+    1323        1767 :       double fact = 2.0*(all_shifts[cs] - chemicalshifts[cs].exp_cs)/camshift_sigma2[chemicalshifts[cs].atm_kind];
+    1324      423482 :       for(unsigned i=0; i<chemicalshifts[cs].totcsatoms; i++) {
+    1325      421715 :         aa_derivs[cs_atoms[kdx+i]] += cs_derivs[kdx+i]*fact;
+    1326             :       }
+    1327             :     }
+    1328             :   }
+    1329             : 
+    1330           9 :   if(!serial) {
+    1331           9 :     comm.Sum(&aa_derivs[0][0], 3*aa_derivs.size());
+    1332           9 :     if(camshift) comm.Sum(&score, 1);
+    1333             :   }
+    1334             : 
+    1335           9 :   Tensor virial;
+    1336       13069 :   for(unsigned i=rank; i<getNumberOfAtoms(); i+=stride) {
+    1337       13060 :     virial += Tensor(getPosition(i), aa_derivs[i]);
+    1338             :   }
+    1339             : 
+    1340           9 :   if(!serial) {
+    1341           9 :     comm.Sum(&virial[0][0], 9);
+    1342             :   }
+    1343             : 
+    1344             :   /* calculate final derivatives */
+    1345             :   Value* val;
+    1346           9 :   if(getDoScore()) {
+    1347           4 :     val=getPntrToComponent("score");
+    1348           4 :     setScore(score);
+    1349             :   } else {
+    1350             :     val=getPntrToValue();
+    1351           5 :     setValue(score);
+    1352             :   }
+    1353             : 
+    1354             :   /* at this point we cycle over all atoms */
+    1355       23517 :   for(unsigned i=0; i<getNumberOfAtoms(); i++) setAtomsDerivatives(val, i,  aa_derivs[i]);
+    1356           9 :   setBoxDerivatives(val,-virial);
+    1357             : }
+    1358             : 
+    1359          18 : void CS2Backbone::update_neighb() {
+    1360             :   // cycle over chemical shifts
+    1361          18 :   unsigned nt=OpenMP::getNumThreads();
+    1362          18 :   #pragma omp parallel for num_threads(nt)
+    1363             :   for(unsigned cs=0; cs<chemicalshifts.size(); cs++) {
+    1364             :     const unsigned boxsize = getNumberOfAtoms();
+    1365             :     chemicalshifts[cs].box_nb.clear();
+    1366             :     chemicalshifts[cs].box_nb.reserve(150);
+    1367             :     const unsigned res_curr = res_num[chemicalshifts[cs].ipos];
+    1368             :     for(unsigned bat=0; bat<boxsize; bat++) {
+    1369             :       const unsigned res_dist = std::abs(static_cast<int>(res_curr-res_num[bat]));
+    1370             :       if(res_dist<2) continue;
+    1371             :       const Vector distance = delta(getPosition(bat),getPosition(chemicalshifts[cs].ipos));
+    1372             :       const double d2=distance.modulo2();
+    1373             :       if(d2<cutOffNB2) chemicalshifts[cs].box_nb.push_back(bat);
+    1374             :     }
+    1375             :     chemicalshifts[cs].totcsatoms = chemicalshifts[cs].csatoms + chemicalshifts[cs].box_nb.size();
+    1376             :   }
+    1377          18 :   max_cs_atoms=0;
+    1378       10620 :   for(unsigned cs=0; cs<chemicalshifts.size(); cs++) {
+    1379       10602 :     if(chemicalshifts[cs].totcsatoms>max_cs_atoms) max_cs_atoms = chemicalshifts[cs].totcsatoms;
+    1380             :   }
+    1381          18 : }
+    1382             : 
+    1383          18 : void CS2Backbone::compute_ring_parameters() {
+    1384         378 :   for(unsigned i=0; i<ringInfo.size(); i++) {
+    1385         360 :     const unsigned size = ringInfo[i].numAtoms;
+    1386         360 :     if(size==6) {
+    1387         342 :       ringInfo[i].g[0] = delta(getPosition(ringInfo[i].atom[4]),getPosition(ringInfo[i].atom[2]));
+    1388         342 :       ringInfo[i].g[1] = delta(getPosition(ringInfo[i].atom[5]),getPosition(ringInfo[i].atom[3]));
+    1389         342 :       ringInfo[i].g[2] = delta(getPosition(ringInfo[i].atom[0]),getPosition(ringInfo[i].atom[4]));
+    1390         342 :       ringInfo[i].g[3] = delta(getPosition(ringInfo[i].atom[1]),getPosition(ringInfo[i].atom[5]));
+    1391         342 :       ringInfo[i].g[4] = delta(getPosition(ringInfo[i].atom[2]),getPosition(ringInfo[i].atom[0]));
+    1392         342 :       ringInfo[i].g[5] = delta(getPosition(ringInfo[i].atom[3]),getPosition(ringInfo[i].atom[1]));
+    1393             :       // ring center
+    1394         342 :       Vector midP = getPosition(ringInfo[i].atom[0]);
+    1395        2052 :       for(unsigned j=1; j<size; j++) midP += getPosition(ringInfo[i].atom[j]);
+    1396         342 :       ringInfo[i].position = midP/6.;
+    1397             :       // compute normal std::vector to plane
+    1398         342 :       Vector n1 = crossProduct(ringInfo[i].g[2], -ringInfo[i].g[4]);
+    1399         342 :       Vector n2 = crossProduct(ringInfo[i].g[5], -ringInfo[i].g[1]);
+    1400         342 :       ringInfo[i].normVect = 0.5*(n1 + n2);
+    1401             :     }  else {
+    1402          18 :       ringInfo[i].g[0] = delta(getPosition(ringInfo[i].atom[3]),getPosition(ringInfo[i].atom[2]));
+    1403          18 :       ringInfo[i].g[1] = delta(getPosition(ringInfo[i].atom[0]),getPosition(ringInfo[i].atom[3]));
+    1404          18 :       ringInfo[i].g[2] = delta(getPosition(ringInfo[i].atom[2]),getPosition(ringInfo[i].atom[0]));
+    1405             :       // ring center
+    1406          18 :       ringInfo[i].position = (getPosition(ringInfo[i].atom[0])+getPosition(ringInfo[i].atom[2])+getPosition(ringInfo[i].atom[3]))/3.;
+    1407             :       // ring plane normal std::vector
+    1408          18 :       ringInfo[i].normVect = crossProduct(ringInfo[i].g[1],-ringInfo[i].g[2]);
+    1409             : 
+    1410             :     }
+    1411             :     // calculate squared length and length of normal std::vector
+    1412         360 :     ringInfo[i].lengthN2 = 1./ringInfo[i].normVect.modulo2();
+    1413         360 :     ringInfo[i].lengthNV = 1./std::sqrt(ringInfo[i].lengthN2);
+    1414             :   }
+    1415          18 : }
+    1416             : 
+    1417       31806 : CS2Backbone::aa_t CS2Backbone::frag2enum(const std::string &aa) {
+    1418             :   aa_t type = ALA;
+    1419       31806 :   if (aa == "ALA") type = ALA;
+    1420       29934 :   else if (aa == "ARG") type = ARG;
+    1421       28548 :   else if (aa == "ASN") type = ASN;
+    1422       26910 :   else if (aa == "ASP") type = ASP;
+    1423       25380 :   else if (aa == "ASH") type = ASP;
+    1424       25380 :   else if (aa == "CYS") type = CYS;
+    1425       24858 :   else if (aa == "CYM") type = CYS;
+    1426       24858 :   else if (aa == "GLN") type = GLN;
+    1427       24390 :   else if (aa == "GLU") type = GLU;
+    1428       22068 :   else if (aa == "GLH") type = GLU;
+    1429       22068 :   else if (aa == "GLY") type = GLY;
+    1430       16974 :   else if (aa == "HIS") type = HIS;
+    1431       16974 :   else if (aa == "HSE") type = HIS;
+    1432       16974 :   else if (aa == "HIE") type = HIS;
+    1433       16974 :   else if (aa == "HSP") type = HIS;
+    1434       16974 :   else if (aa == "HIP") type = HIS;
+    1435       16974 :   else if (aa == "HSD") type = HIS;
+    1436       16974 :   else if (aa == "HID") type = HIS;
+    1437       16974 :   else if (aa == "ILE") type = ILE;
+    1438       15174 :   else if (aa == "LEU") type = LEU;
+    1439       13536 :   else if (aa == "LYS") type = LYS;
+    1440       10746 :   else if (aa == "MET") type = MET;
+    1441        9936 :   else if (aa == "PHE") type = PHE;
+    1442        6876 :   else if (aa == "PRO") type = PRO;
+    1443        5940 :   else if (aa == "SER") type = SER;
+    1444        4302 :   else if (aa == "THR") type = THR;
+    1445        2196 :   else if (aa == "TRP") type = TRP;
+    1446        1980 :   else if (aa == "TYR") type = TYR;
+    1447        1602 :   else if (aa == "VAL") type = VAL;
+    1448           0 :   else if (aa == "UNK") type = UNK;
+    1449           0 :   else plumed_merror("Error converting std::string " + aa + " into amino acid index: not a valid 3-letter code");
+    1450       31806 :   return type;
+    1451             : }
+    1452             : 
+    1453       10602 : std::vector<std::string> CS2Backbone::side_chain_atoms(const std::string &s) {
+    1454             :   std::vector<std::string> sc;
+    1455             : 
+    1456       10602 :   if(s=="ALA") {
+    1457         648 :     sc.push_back( "CB" );
+    1458         648 :     sc.push_back( "HB1" );
+    1459         648 :     sc.push_back( "HB2" );
+    1460         648 :     sc.push_back( "HB3" );
+    1461         648 :     return sc;
+    1462        9954 :   } else if(s=="ARG") {
+    1463         468 :     sc.push_back( "CB" );
+    1464         468 :     sc.push_back( "CG" );
+    1465         468 :     sc.push_back( "CD" );
+    1466         468 :     sc.push_back( "NE" );
+    1467         468 :     sc.push_back( "CZ" );
+    1468         468 :     sc.push_back( "NH1" );
+    1469         468 :     sc.push_back( "NH2" );
+    1470         468 :     sc.push_back( "NH3" );
+    1471         468 :     sc.push_back( "HB1" );
+    1472         468 :     sc.push_back( "HB2" );
+    1473         468 :     sc.push_back( "HB3" );
+    1474         468 :     sc.push_back( "HG1" );
+    1475         468 :     sc.push_back( "HG2" );
+    1476         468 :     sc.push_back( "HG3" );
+    1477         468 :     sc.push_back( "HD1" );
+    1478         468 :     sc.push_back( "HD2" );
+    1479         468 :     sc.push_back( "HD3" );
+    1480         468 :     sc.push_back( "HE" );
+    1481         468 :     sc.push_back( "HH11" );
+    1482         468 :     sc.push_back( "HH12" );
+    1483         468 :     sc.push_back( "HH21" );
+    1484         468 :     sc.push_back( "HH22" );
+    1485         468 :     sc.push_back( "1HH1" );
+    1486         468 :     sc.push_back( "2HH1" );
+    1487         468 :     sc.push_back( "1HH2" );
+    1488         468 :     sc.push_back( "2HH2" );
+    1489         468 :     return sc;
+    1490        9486 :   } else if(s=="ASN") {
+    1491         594 :     sc.push_back( "CB" );
+    1492         594 :     sc.push_back( "CG" );
+    1493         594 :     sc.push_back( "OD1" );
+    1494         594 :     sc.push_back( "ND2" );
+    1495         594 :     sc.push_back( "HB1" );
+    1496         594 :     sc.push_back( "HB2" );
+    1497         594 :     sc.push_back( "HB3" );
+    1498         594 :     sc.push_back( "HD21" );
+    1499         594 :     sc.push_back( "HD22" );
+    1500         594 :     sc.push_back( "1HD2" );
+    1501         594 :     sc.push_back( "2HD2" );
+    1502         594 :     return sc;
+    1503       17226 :   } else if(s=="ASP"||s=="ASH") {
+    1504         558 :     sc.push_back( "CB" );
+    1505         558 :     sc.push_back( "CG" );
+    1506         558 :     sc.push_back( "OD1" );
+    1507         558 :     sc.push_back( "OD2" );
+    1508         558 :     sc.push_back( "HB1" );
+    1509         558 :     sc.push_back( "HB2" );
+    1510         558 :     sc.push_back( "HB3" );
+    1511         558 :     return sc;
+    1512       16668 :   } else if(s=="CYS"||s=="CYM") {
+    1513           0 :     sc.push_back( "CB" );
+    1514           0 :     sc.push_back( "SG" );
+    1515           0 :     sc.push_back( "HB1" );
+    1516           0 :     sc.push_back( "HB2" );
+    1517           0 :     sc.push_back( "HB3" );
+    1518           0 :     sc.push_back( "HG1" );
+    1519           0 :     sc.push_back( "HG" );
+    1520           0 :     return sc;
+    1521        8334 :   } else if(s=="GLN") {
+    1522         162 :     sc.push_back( "CB" );
+    1523         162 :     sc.push_back( "CG" );
+    1524         162 :     sc.push_back( "CD" );
+    1525         162 :     sc.push_back( "OE1" );
+    1526         162 :     sc.push_back( "NE2" );
+    1527         162 :     sc.push_back( "HB1" );
+    1528         162 :     sc.push_back( "HB2" );
+    1529         162 :     sc.push_back( "HB3" );
+    1530         162 :     sc.push_back( "HG1" );
+    1531         162 :     sc.push_back( "HG2" );
+    1532         162 :     sc.push_back( "HG3" );
+    1533         162 :     sc.push_back( "HE21" );
+    1534         162 :     sc.push_back( "HE22" );
+    1535         162 :     sc.push_back( "1HE2" );
+    1536         162 :     sc.push_back( "2HE2" );
+    1537         162 :     return sc;
+    1538       15552 :   } else if(s=="GLU"||s=="GLH") {
+    1539         792 :     sc.push_back( "CB" );
+    1540         792 :     sc.push_back( "CG" );
+    1541         792 :     sc.push_back( "CD" );
+    1542         792 :     sc.push_back( "OE1" );
+    1543         792 :     sc.push_back( "OE2" );
+    1544         792 :     sc.push_back( "HB1" );
+    1545         792 :     sc.push_back( "HB2" );
+    1546         792 :     sc.push_back( "HB3" );
+    1547         792 :     sc.push_back( "HG1" );
+    1548         792 :     sc.push_back( "HG2" );
+    1549         792 :     sc.push_back( "HG3" );
+    1550         792 :     return sc;
+    1551        7380 :   } else if(s=="GLY") {
+    1552        1494 :     sc.push_back( "HA2" );
+    1553        1494 :     return sc;
+    1554       41202 :   } else if(s=="HIS"||s=="HSE"||s=="HIE"||s=="HSD"||s=="HID"||s=="HIP"||s=="HSP") {
+    1555           0 :     sc.push_back( "CB" );
+    1556           0 :     sc.push_back( "CG" );
+    1557           0 :     sc.push_back( "ND1" );
+    1558           0 :     sc.push_back( "CD2" );
+    1559           0 :     sc.push_back( "CE1" );
+    1560           0 :     sc.push_back( "NE2" );
+    1561           0 :     sc.push_back( "HB1" );
+    1562           0 :     sc.push_back( "HB2" );
+    1563           0 :     sc.push_back( "HB3" );
+    1564           0 :     sc.push_back( "HD1" );
+    1565           0 :     sc.push_back( "HD2" );
+    1566           0 :     sc.push_back( "HE1" );
+    1567           0 :     sc.push_back( "HE2" );
+    1568           0 :     return sc;
+    1569        5886 :   } else if(s=="ILE") {
+    1570         540 :     sc.push_back( "CB" );
+    1571         540 :     sc.push_back( "CG1" );
+    1572         540 :     sc.push_back( "CG2" );
+    1573         540 :     sc.push_back( "CD" );
+    1574         540 :     sc.push_back( "HB" );
+    1575         540 :     sc.push_back( "HG11" );
+    1576         540 :     sc.push_back( "HG12" );
+    1577         540 :     sc.push_back( "HG21" );
+    1578         540 :     sc.push_back( "HG22" );
+    1579         540 :     sc.push_back( "HG23" );
+    1580         540 :     sc.push_back( "1HG1" );
+    1581         540 :     sc.push_back( "2HG1" );
+    1582         540 :     sc.push_back( "1HG2" );
+    1583         540 :     sc.push_back( "2HG2" );
+    1584         540 :     sc.push_back( "3HG2" );
+    1585         540 :     sc.push_back( "HD1" );
+    1586         540 :     sc.push_back( "HD2" );
+    1587         540 :     sc.push_back( "HD3" );
+    1588         540 :     return sc;
+    1589        5346 :   } else if(s=="LEU") {
+    1590         648 :     sc.push_back( "CB" );
+    1591         648 :     sc.push_back( "CG" );
+    1592         648 :     sc.push_back( "CD1" );
+    1593         648 :     sc.push_back( "CD2" );
+    1594         648 :     sc.push_back( "HB1" );
+    1595         648 :     sc.push_back( "HB2" );
+    1596         648 :     sc.push_back( "HB3" );
+    1597         648 :     sc.push_back( "HG" );
+    1598         648 :     sc.push_back( "HD11" );
+    1599         648 :     sc.push_back( "HD12" );
+    1600         648 :     sc.push_back( "HD13" );
+    1601         648 :     sc.push_back( "HD21" );
+    1602         648 :     sc.push_back( "HD22" );
+    1603         648 :     sc.push_back( "HD23" );
+    1604         648 :     sc.push_back( "1HD1" );
+    1605         648 :     sc.push_back( "2HD1" );
+    1606         648 :     sc.push_back( "3HD1" );
+    1607         648 :     sc.push_back( "1HD2" );
+    1608         648 :     sc.push_back( "2HD2" );
+    1609         648 :     sc.push_back( "3HD2" );
+    1610         648 :     return sc;
+    1611        4698 :   } else if(s=="LYS") {
+    1612        1008 :     sc.push_back( "CB" );
+    1613        1008 :     sc.push_back( "CG" );
+    1614        1008 :     sc.push_back( "CD" );
+    1615        1008 :     sc.push_back( "CE" );
+    1616        1008 :     sc.push_back( "NZ" );
+    1617        1008 :     sc.push_back( "HB1" );
+    1618        1008 :     sc.push_back( "HB2" );
+    1619        1008 :     sc.push_back( "HB3" );
+    1620        1008 :     sc.push_back( "HG1" );
+    1621        1008 :     sc.push_back( "HG2" );
+    1622        1008 :     sc.push_back( "HG3" );
+    1623        1008 :     sc.push_back( "HD1" );
+    1624        1008 :     sc.push_back( "HD2" );
+    1625        1008 :     sc.push_back( "HD3" );
+    1626        1008 :     sc.push_back( "HE1" );
+    1627        1008 :     sc.push_back( "HE2" );
+    1628        1008 :     sc.push_back( "HE3" );
+    1629        1008 :     sc.push_back( "HZ1" );
+    1630        1008 :     sc.push_back( "HZ2" );
+    1631        1008 :     sc.push_back( "HZ3" );
+    1632        1008 :     return sc;
+    1633        3690 :   } else if(s=="MET") {
+    1634         288 :     sc.push_back( "CB" );
+    1635         288 :     sc.push_back( "CG" );
+    1636         288 :     sc.push_back( "SD" );
+    1637         288 :     sc.push_back( "CE" );
+    1638         288 :     sc.push_back( "HB1" );
+    1639         288 :     sc.push_back( "HB2" );
+    1640         288 :     sc.push_back( "HB3" );
+    1641         288 :     sc.push_back( "HG1" );
+    1642         288 :     sc.push_back( "HG2" );
+    1643         288 :     sc.push_back( "HG3" );
+    1644         288 :     sc.push_back( "HE1" );
+    1645         288 :     sc.push_back( "HE2" );
+    1646         288 :     sc.push_back( "HE3" );
+    1647         288 :     return sc;
+    1648        3402 :   } else if(s=="PHE") {
+    1649        1098 :     sc.push_back( "CB" );
+    1650        1098 :     sc.push_back( "CG" );
+    1651        1098 :     sc.push_back( "CD1" );
+    1652        1098 :     sc.push_back( "CD2" );
+    1653        1098 :     sc.push_back( "CE1" );
+    1654        1098 :     sc.push_back( "CE2" );
+    1655        1098 :     sc.push_back( "CZ" );
+    1656        1098 :     sc.push_back( "HB1" );
+    1657        1098 :     sc.push_back( "HB2" );
+    1658        1098 :     sc.push_back( "HB3" );
+    1659        1098 :     sc.push_back( "HD1" );
+    1660        1098 :     sc.push_back( "HD2" );
+    1661        1098 :     sc.push_back( "HD3" );
+    1662        1098 :     sc.push_back( "HE1" );
+    1663        1098 :     sc.push_back( "HE2" );
+    1664        1098 :     sc.push_back( "HE3" );
+    1665        1098 :     sc.push_back( "HZ" );
+    1666        1098 :     return sc;
+    1667        2304 :   } else if(s=="PRO") {
+    1668         108 :     sc.push_back( "CB" );
+    1669         108 :     sc.push_back( "CG" );
+    1670         108 :     sc.push_back( "CD" );
+    1671         108 :     sc.push_back( "HB1" );
+    1672         108 :     sc.push_back( "HB2" );
+    1673         108 :     sc.push_back( "HB3" );
+    1674         108 :     sc.push_back( "HG1" );
+    1675         108 :     sc.push_back( "HG2" );
+    1676         108 :     sc.push_back( "HG3" );
+    1677         108 :     sc.push_back( "HD1" );
+    1678         108 :     sc.push_back( "HD2" );
+    1679         108 :     sc.push_back( "HD3" );
+    1680         108 :     return sc;
+    1681        2196 :   } else if(s=="SER") {
+    1682         630 :     sc.push_back( "CB" );
+    1683         630 :     sc.push_back( "OG" );
+    1684         630 :     sc.push_back( "HB1" );
+    1685         630 :     sc.push_back( "HB2" );
+    1686         630 :     sc.push_back( "HB3" );
+    1687         630 :     sc.push_back( "HG1" );
+    1688         630 :     sc.push_back( "HG" );
+    1689         630 :     return sc;
+    1690        1566 :   } else if(s=="THR") {
+    1691         774 :     sc.push_back( "CB" );
+    1692         774 :     sc.push_back( "OG1" );
+    1693         774 :     sc.push_back( "CG2" );
+    1694         774 :     sc.push_back( "HB" );
+    1695         774 :     sc.push_back( "HG1" );
+    1696         774 :     sc.push_back( "HG21" );
+    1697         774 :     sc.push_back( "HG22" );
+    1698         774 :     sc.push_back( "HG23" );
+    1699         774 :     sc.push_back( "1HG2" );
+    1700         774 :     sc.push_back( "2HG2" );
+    1701         774 :     sc.push_back( "3HG2" );
+    1702         774 :     return sc;
+    1703         792 :   } else if(s=="TRP") {
+    1704          72 :     sc.push_back( "CB" );
+    1705          72 :     sc.push_back( "CG" );
+    1706          72 :     sc.push_back( "CD1" );
+    1707          72 :     sc.push_back( "CD2" );
+    1708          72 :     sc.push_back( "NE1" );
+    1709          72 :     sc.push_back( "CE2" );
+    1710          72 :     sc.push_back( "CE3" );
+    1711          72 :     sc.push_back( "CZ2" );
+    1712          72 :     sc.push_back( "CZ3" );
+    1713          72 :     sc.push_back( "CH2" );
+    1714          72 :     sc.push_back( "HB1" );
+    1715          72 :     sc.push_back( "HB2" );
+    1716          72 :     sc.push_back( "HB3" );
+    1717          72 :     sc.push_back( "HD1" );
+    1718          72 :     sc.push_back( "HE1" );
+    1719          72 :     sc.push_back( "HE3" );
+    1720          72 :     sc.push_back( "HZ2" );
+    1721          72 :     sc.push_back( "HZ3" );
+    1722          72 :     sc.push_back( "HH2" );
+    1723          72 :     return sc;
+    1724         720 :   } else if(s=="TYR") {
+    1725         144 :     sc.push_back( "CB" );
+    1726         144 :     sc.push_back( "CG" );
+    1727         144 :     sc.push_back( "CD1" );
+    1728         144 :     sc.push_back( "CD2" );
+    1729         144 :     sc.push_back( "CE1" );
+    1730         144 :     sc.push_back( "CE2" );
+    1731         144 :     sc.push_back( "CZ" );
+    1732         144 :     sc.push_back( "OH" );
+    1733         144 :     sc.push_back( "HB1" );
+    1734         144 :     sc.push_back( "HB2" );
+    1735         144 :     sc.push_back( "HB3" );
+    1736         144 :     sc.push_back( "HD1" );
+    1737         144 :     sc.push_back( "HD2" );
+    1738         144 :     sc.push_back( "HD3" );
+    1739         144 :     sc.push_back( "HE1" );
+    1740         144 :     sc.push_back( "HE2" );
+    1741         144 :     sc.push_back( "HE3" );
+    1742         144 :     sc.push_back( "HH" );
+    1743         144 :     return sc;
+    1744         576 :   } else if(s=="VAL") {
+    1745         576 :     sc.push_back( "CB" );
+    1746         576 :     sc.push_back( "CG1" );
+    1747         576 :     sc.push_back( "CG2" );
+    1748         576 :     sc.push_back( "HB" );
+    1749         576 :     sc.push_back( "HG11" );
+    1750         576 :     sc.push_back( "HG12" );
+    1751         576 :     sc.push_back( "HG13" );
+    1752         576 :     sc.push_back( "HG21" );
+    1753         576 :     sc.push_back( "HG22" );
+    1754         576 :     sc.push_back( "HG23" );
+    1755         576 :     sc.push_back( "1HG1" );
+    1756         576 :     sc.push_back( "2HG1" );
+    1757         576 :     sc.push_back( "3HG1" );
+    1758         576 :     sc.push_back( "1HG2" );
+    1759         576 :     sc.push_back( "2HG2" );
+    1760         576 :     sc.push_back( "3HG2" );
+    1761         576 :     return sc;
+    1762           0 :   } else plumed_merror("Sidechain atoms unknown: " + s);
+    1763           0 : }
+    1764             : 
+    1765       47016 : bool CS2Backbone::isSP2(const std::string & resType, const std::string & atomName) {
+    1766             :   bool sp2 = false;
+    1767       47016 :   if (atomName == "C") return true;
+    1768       43848 :   if (atomName == "O") return true;
+    1769             : 
+    1770       40716 :   if(resType == "TRP") {
+    1771         396 :     if      (atomName == "CG")  sp2 = true;
+    1772         378 :     else if (atomName == "CD1") sp2 = true;
+    1773         360 :     else if (atomName == "CD2") sp2 = true;
+    1774         342 :     else if (atomName == "CE2") sp2 = true;
+    1775         324 :     else if (atomName == "CE3") sp2 = true;
+    1776         306 :     else if (atomName == "CZ2") sp2 = true;
+    1777         288 :     else if (atomName == "CZ3") sp2 = true;
+    1778         270 :     else if (atomName == "CH2") sp2 = true;
+    1779       40320 :   } else if (resType == "ASP") {
+    1780        1656 :     if      (atomName == "CG")  sp2 = true;
+    1781        1494 :     else if (atomName == "OD1") sp2 = true;
+    1782        1332 :     else if (atomName == "OD2") sp2 = true;
+    1783       38664 :   } else if (resType == "GLU") {
+    1784        2844 :     if      (atomName == "CD")  sp2 = true;
+    1785        2628 :     else if (atomName == "OE1") sp2 = true;
+    1786        2412 :     else if (atomName == "OE2") sp2 = true;
+    1787       35820 :   } else if (resType == "ARG") {
+    1788        2772 :     if (atomName == "CZ") sp2 = true;
+    1789       33048 :   } else if (resType == "HIS") {
+    1790           0 :     if      (atomName == "CG")  sp2 = true;
+    1791           0 :     else if (atomName == "ND1") sp2 = true;
+    1792           0 :     else if (atomName == "CD2") sp2 = true;
+    1793           0 :     else if (atomName == "CE1") sp2 = true;
+    1794           0 :     else if (atomName == "NE2") sp2 = true;
+    1795       33048 :   } else if (resType == "PHE") {
+    1796        5184 :     if      (atomName == "CG")  sp2 = true;
+    1797        4896 :     else if (atomName == "CD1") sp2 = true;
+    1798        4608 :     else if (atomName == "CD2") sp2 = true;
+    1799        4320 :     else if (atomName == "CE1") sp2 = true;
+    1800        4032 :     else if (atomName == "CE2") sp2 = true;
+    1801        3744 :     else if (atomName == "CZ")  sp2 = true;
+    1802       27864 :   } else if (resType == "TYR") {
+    1803         684 :     if      (atomName == "CG")  sp2 = true;
+    1804         648 :     else if (atomName == "CD1") sp2 = true;
+    1805         612 :     else if (atomName == "CD2") sp2 = true;
+    1806         576 :     else if (atomName == "CE1") sp2 = true;
+    1807         540 :     else if (atomName == "CE2") sp2 = true;
+    1808         504 :     else if (atomName == "CZ")  sp2 = true;
+    1809       27180 :   } else if (resType == "ASN") {
+    1810        1944 :     if      (atomName == "CG")  sp2 = true;
+    1811        1782 :     else if (atomName == "OD1") sp2 = true;
+    1812       25236 :   } else if (resType == "GLN") {
+    1813         810 :     if      (atomName == "CD")  sp2 = true;
+    1814         756 :     else if (atomName == "OE1") sp2 = true;
+    1815             :   }
+    1816             : 
+    1817             :   return sp2;
+    1818             : }
+    1819             : 
+    1820      145728 : bool CS2Backbone::is_chi1_cx(const std::string & frg, const std::string & atm) {
+    1821      145728 :   if(atm=="CG")                                        return true;
+    1822      139788 :   if((frg == "CYS")&&(atm =="SG"))                     return true;
+    1823      288792 :   if(((frg == "ILE")||(frg == "VAL"))&&(atm == "CG1")) return true;
+    1824      145602 :   if((frg == "SER")&&(atm == "OG"))                    return true;
+    1825      148878 :   if((frg == "THR")&&(atm == "OG1"))                   return true;
+    1826             : 
+    1827             :   return false;
+    1828             : }
+    1829             : 
+    1830     3599784 : void CS2Backbone::xdist_name_map(std::string & name) {
+    1831     7199568 :   if((name == "OT1")||(name == "OC1")) name = "O";
+    1832    10799352 :   else if ((name == "HN") || (name == "HT1") || (name == "H1")) name = "H";
+    1833     7139232 :   else if ((name == "CG1")|| (name == "OG")||
+    1834     7159572 :            (name == "SG") || (name == "OG1")) name = "CG";
+    1835     7040070 :   else if ((name == "HA1")|| (name == "HA3")) name = "HA";
+    1836     3599784 : }
+    1837             : 
+    1838          18 : void CS2Backbone::update() {
+    1839             :   // write status file
+    1840          18 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+    1841          18 : }
+    1842             : 
+    1843             : }
+    1844             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Caliber.cpp.func-sort-c.html b/coverage/isdb/Caliber.cpp.func-sort-c.html new file mode 100644 index 000000000000..0be3e0e7f201 --- /dev/null +++ b/coverage/isdb/Caliber.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Caliber.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Caliber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11614778.9 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7Caliber14get_sigma_meanEdRKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7Caliber18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7CaliberC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7CaliberC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb7Caliber16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4isdb7Caliber17replica_averagingEdRSt6vectorIdSaIdEE2004
_ZN4PLMD4isdb7Caliber9calculateEv2004
_ZN4PLMD4isdb7Caliber9getSplineEj2004
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Caliber.cpp.func.html b/coverage/isdb/Caliber.cpp.func.html new file mode 100644 index 000000000000..50224e278648 --- /dev/null +++ b/coverage/isdb/Caliber.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Caliber.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Caliber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11614778.9 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7Caliber14get_sigma_meanEdRKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7Caliber16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4isdb7Caliber17replica_averagingEdRSt6vectorIdSaIdEE2004
_ZN4PLMD4isdb7Caliber18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb7Caliber9calculateEv2004
_ZN4PLMD4isdb7Caliber9getSplineEj2004
_ZN4PLMD4isdb7CaliberC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb7CaliberC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Caliber.cpp.gcov.html b/coverage/isdb/Caliber.cpp.gcov.html new file mode 100644 index 000000000000..505e8aa7b3bc --- /dev/null +++ b/coverage/isdb/Caliber.cpp.gcov.html @@ -0,0 +1,424 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Caliber.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Caliber.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11614778.9 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "bias/Bias.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Communicator.h"
+      26             : #include <fstream>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace isdb {
+      30             : 
+      31             : //+PLUMEDOC ISDB_BIAS CALIBER
+      32             : /*
+      33             : Add a time-dependent, harmonic restraint on one or more variables.
+      34             : 
+      35             : This allows implementing a maximum caliber restraint on one or more experimental time series by replica-averaged restrained simulations.
+      36             : See \cite Capelli:2018jt .
+      37             : 
+      38             : The time resolved experiments are read from a text file and intermediate values are obtained by splines.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : In the following example a restraint is applied on the time evolution of a saxs spectrum
+      43             : 
+      44             : \plumedfile
+      45             : MOLINFO STRUCTURE=first.pdb
+      46             : 
+      47             : # Define saxs variable
+      48             : SAXS ...
+      49             : LABEL=saxs
+      50             : ATOMISTIC
+      51             : ATOMS=1-436
+      52             : QVALUE1=0.02 # Q-value at which calculate the scattering
+      53             : QVALUE2=0.0808
+      54             : QVALUE3=0.1264
+      55             : QVALUE4=0.1568
+      56             : QVALUE5=0.172
+      57             : QVALUE6=0.1872
+      58             : QVALUE7=0.2176
+      59             : QVALUE8=0.2328
+      60             : QVALUE9=0.248
+      61             : QVALUE10=0.2632
+      62             : QVALUE11=0.2936
+      63             : QVALUE12=0.3088
+      64             : QVALUE13=0.324
+      65             : QVALUE14=0.3544
+      66             : QVALUE15=0.4
+      67             : ... SAXS
+      68             : 
+      69             : 
+      70             : #define the caliber restraint
+      71             : CALIBER ...
+      72             :   ARG=(saxs\.q_.*)
+      73             :   FILE=expsaxs.dat
+      74             :   KAPPA=10
+      75             :   LABEL=cal0
+      76             :   STRIDE=10
+      77             :   REGRES_ZERO=200
+      78             :   AVERAGING=200
+      79             : ... CALIBER
+      80             : \endplumedfile
+      81             : 
+      82             : In particular the file expsaxs.dat contains the time traces for the 15 intensities at the selected scattering lengths, organized as time, q_1, etc.
+      83             : The strength of the bias is automatically evaluated from the standard error of the mean over AVERAGING steps and multiplied by KAPPA. This is useful when working with multiple experimental data
+      84             : Because \ref SAXS is usually defined in a manner that is irrespective of a scaling factor the scaling is evaluated from a linear fit every REGRES_ZERO step. Alternatively it can be given as a fixed constant as SCALE.
+      85             : The bias is here applied every tenth step.
+      86             : 
+      87             : */
+      88             : //+ENDPLUMEDOC
+      89             : 
+      90             : 
+      91             : class Caliber : public bias::Bias {
+      92             : public:
+      93             :   explicit Caliber(const ActionOptions&);
+      94             :   void calculate();
+      95             :   static void registerKeywords( Keywords& keys );
+      96             : private:
+      97             :   std::vector<double> time;
+      98             :   std::vector< std::vector<double> > var;
+      99             :   std::vector< std::vector<double> > dvar;
+     100             :   double   mult;
+     101             :   double   scale_;
+     102             :   bool     master;
+     103             :   unsigned replica_;
+     104             :   unsigned nrep_;
+     105             :   // scale and offset regression
+     106             :   bool doregres_zero_;
+     107             :   int  nregres_zero_;
+     108             :   // force constant
+     109             :   unsigned optsigmamean_stride_;
+     110             :   std::vector<double> sigma_mean2_;
+     111             :   std::vector< std::vector<double> > sigma_mean2_last_;
+     112             :   std::vector<Value*> x0comp;
+     113             :   std::vector<Value*> kcomp;
+     114             :   std::vector<Value*> mcomp;
+     115             :   Value* valueScale;
+     116             : 
+     117             :   void get_sigma_mean(const double fact, const std::vector<double> &mean);
+     118             :   void replica_averaging(const double fact, std::vector<double> &mean);
+     119             :   double getSpline(const unsigned iarg);
+     120             :   void do_regression_zero(const std::vector<double> &mean);
+     121             : };
+     122             : 
+     123             : PLUMED_REGISTER_ACTION(Caliber,"CALIBER")
+     124             : 
+     125           6 : void Caliber::registerKeywords( Keywords& keys ) {
+     126           6 :   Bias::registerKeywords(keys);
+     127           6 :   keys.use("ARG");
+     128          12 :   keys.addFlag("NOENSEMBLE",false,"don't perform any replica-averaging");
+     129          12 :   keys.add("compulsory","FILE","the name of the file containing the time-resolved values");
+     130          12 :   keys.add("compulsory","KAPPA","a force constant, this can be use to scale a constant estimated on-the-fly using AVERAGING");
+     131          12 :   keys.add("optional","AVERAGING", "Stride for calculation of the optimum kappa, if 0 only KAPPA is used.");
+     132          12 :   keys.add("compulsory","TSCALE","1.0","Apply a time scaling on the experimental time scale");
+     133          12 :   keys.add("compulsory","SCALE","1.0","Apply a constant scaling on the data provided as arguments");
+     134          12 :   keys.add("optional","REGRES_ZERO","stride for regression with zero offset");
+     135          12 :   keys.addOutputComponent("x0","default","the instantaneous value of the center of the potential");
+     136          12 :   keys.addOutputComponent("mean","default","the current average value of the calculated observable");
+     137          12 :   keys.addOutputComponent("kappa","default","the current force constant");
+     138          12 :   keys.addOutputComponent("scale","REGRES_ZERO","the current scaling constant");
+     139           6 : }
+     140             : 
+     141           4 : Caliber::Caliber(const ActionOptions&ao):
+     142             :   PLUMED_BIAS_INIT(ao),
+     143           4 :   mult(0),
+     144           4 :   scale_(1),
+     145           4 :   doregres_zero_(false),
+     146           4 :   nregres_zero_(0),
+     147           4 :   optsigmamean_stride_(0)
+     148             : {
+     149           8 :   parse("KAPPA",mult);
+     150             :   std::string filename;
+     151           8 :   parse("FILE",filename);
+     152           4 :   if( filename.length()==0 ) error("No external variable file was specified");
+     153           4 :   unsigned averaging=0;
+     154           4 :   parse("AVERAGING", averaging);
+     155           4 :   if(averaging>0) optsigmamean_stride_ = averaging;
+     156           4 :   double tscale=1.0;
+     157           4 :   parse("TSCALE", tscale);
+     158           4 :   if(tscale<=0.) error("The time scale factor must be greater than 0.");
+     159           4 :   parse("SCALE", scale_);
+     160           4 :   if(scale_==0.) error("The time scale factor cannot be 0.");
+     161             :   // regression with zero intercept
+     162           4 :   parse("REGRES_ZERO", nregres_zero_);
+     163           4 :   if(nregres_zero_>0) {
+     164             :     // set flag
+     165           0 :     doregres_zero_=true;
+     166           0 :     log.printf("  doing regression with zero intercept with stride: %d\n", nregres_zero_);
+     167             :   }
+     168             : 
+     169             : 
+     170           4 :   bool noensemble = false;
+     171           4 :   parseFlag("NOENSEMBLE", noensemble);
+     172             : 
+     173           4 :   checkRead();
+     174             : 
+     175             :   // set up replica stuff
+     176           4 :   master = (comm.Get_rank()==0);
+     177           4 :   if(master) {
+     178           4 :     nrep_    = multi_sim_comm.Get_size();
+     179           4 :     replica_ = multi_sim_comm.Get_rank();
+     180           4 :     if(noensemble) nrep_ = 1;
+     181             :   } else {
+     182           0 :     nrep_    = 0;
+     183           0 :     replica_ = 0;
+     184             :   }
+     185           4 :   comm.Sum(&nrep_,1);
+     186           4 :   comm.Sum(&replica_,1);
+     187             : 
+     188             :   const unsigned narg = getNumberOfArguments();
+     189           4 :   sigma_mean2_.resize(narg,1);
+     190           4 :   sigma_mean2_last_.resize(narg);
+     191           8 :   for(unsigned j=0; j<narg; j++) sigma_mean2_last_[j].push_back(0.000001);
+     192             : 
+     193           4 :   log.printf("  Time resolved data from file %s\n",filename.c_str());
+     194           4 :   std::ifstream varfile(filename.c_str());
+     195           4 :   if(varfile.fail()) error("Cannot open "+filename);
+     196           4 :   var.resize(narg);
+     197           4 :   dvar.resize(narg);
+     198        2012 :   while (!varfile.eof()) {
+     199             :     double tempT, tempVar;
+     200             :     varfile >> tempT;
+     201        2008 :     time.push_back(tempT/tscale);
+     202        4016 :     for(unsigned i=0; i<narg; i++) {
+     203             :       varfile >> tempVar;
+     204        2008 :       var[i].push_back(tempVar);
+     205             :     }
+     206             :   }
+     207           4 :   varfile.close();
+     208             : 
+     209           4 :   const double deltat = time[1] - time[0];
+     210           8 :   for(unsigned i=0; i<narg; i++) {
+     211        2012 :     for(unsigned j=0; j<var[i].size(); j++) {
+     212        2008 :       if(j==0) dvar[i].push_back((var[i][j+1] - var[i][j])/(deltat));
+     213        2004 :       else if(j==var[i].size()-1) dvar[i].push_back((var[i][j] - var[i][j-1])/(deltat));
+     214        2000 :       else dvar[i].push_back((var[i][j+1] - var[i][j-1])/(2.*deltat));
+     215             :     }
+     216             :   }
+     217             : 
+     218           8 :   for(unsigned i=0; i<narg; i++) {
+     219           4 :     std::string num; Tools::convert(i,num);
+     220          12 :     addComponent("x0-"+num); componentIsNotPeriodic("x0-"+num); x0comp.push_back(getPntrToComponent("x0-"+num));
+     221          12 :     addComponent("kappa-"+num); componentIsNotPeriodic("kappa-"+num); kcomp.push_back(getPntrToComponent("kappa-"+num));
+     222          12 :     addComponent("mean-"+num); componentIsNotPeriodic("mean-"+num); mcomp.push_back(getPntrToComponent("mean-"+num));
+     223             :   }
+     224             : 
+     225           4 :   if(doregres_zero_) {
+     226           0 :     addComponent("scale");
+     227           0 :     componentIsNotPeriodic("scale");
+     228           0 :     valueScale=getPntrToComponent("scale");
+     229             :   }
+     230             : 
+     231           8 :   log<<"  Bibliography "<<plumed.cite("Capelli, Tiana, Camilloni, J Chem Phys, 148, 184114");
+     232           8 : }
+     233             : 
+     234           0 : void Caliber::get_sigma_mean(const double fact, const std::vector<double> &mean)
+     235             : {
+     236           0 :   const unsigned narg = getNumberOfArguments();
+     237           0 :   const double dnrep = static_cast<double>(nrep_);
+     238             : 
+     239           0 :   if(sigma_mean2_last_[0].size()==optsigmamean_stride_) for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[i].erase(sigma_mean2_last_[i].begin());
+     240           0 :   std::vector<double> sigma_mean2_now(narg,0);
+     241           0 :   if(master) {
+     242           0 :     for(unsigned i=0; i<narg; ++i) {
+     243           0 :       double tmp = getArgument(i)-mean[i];
+     244           0 :       sigma_mean2_now[i] = fact*tmp*tmp;
+     245             :     }
+     246           0 :     if(nrep_>1) multi_sim_comm.Sum(&sigma_mean2_now[0], narg);
+     247             :   }
+     248           0 :   comm.Sum(&sigma_mean2_now[0], narg);
+     249             : 
+     250           0 :   for(unsigned i=0; i<narg; ++i) {
+     251           0 :     sigma_mean2_last_[i].push_back(sigma_mean2_now[i]/dnrep);
+     252           0 :     sigma_mean2_[i] = *max_element(sigma_mean2_last_[i].begin(), sigma_mean2_last_[i].end());
+     253             :   }
+     254           0 : }
+     255             : 
+     256        2004 : void Caliber::replica_averaging(const double fact, std::vector<double> &mean)
+     257             : {
+     258        2004 :   const unsigned narg = getNumberOfArguments();
+     259        2004 :   if(master) {
+     260        4008 :     for(unsigned i=0; i<narg; ++i) mean[i] = fact*getArgument(i);
+     261        2004 :     if(nrep_>1) multi_sim_comm.Sum(&mean[0], narg);
+     262             :   }
+     263        2004 :   comm.Sum(&mean[0], narg);
+     264        2004 : }
+     265             : 
+     266        2004 : double Caliber::getSpline(const unsigned iarg)
+     267             : {
+     268        2004 :   const double deltat = time[1] - time[0];
+     269        2004 :   const int tindex = static_cast<int>(getTime()/deltat);
+     270             : 
+     271             :   unsigned start, end;
+     272        2004 :   start=tindex;
+     273        2004 :   if(tindex+1<var[iarg].size()) end=tindex+2;
+     274           0 :   else end=var[iarg].size();
+     275             : 
+     276             :   double value=0;
+     277        6012 :   for(unsigned ipoint=start; ipoint<end; ++ipoint) {
+     278        4008 :     double grid=var[iarg][ipoint];
+     279        4008 :     double dder=dvar[iarg][ipoint];
+     280             :     double yy=0.;
+     281        4008 :     if(std::abs(grid)>0.0000001) yy=-dder/grid;
+     282             : 
+     283             :     int x0=1;
+     284        4008 :     if(ipoint==tindex) x0=0;
+     285             : 
+     286        4008 :     double X=std::abs((getTime()-time[tindex])/deltat-(double)x0);
+     287        4008 :     double X2=X*X;
+     288        4008 :     double X3=X2*X;
+     289        4008 :     double C=(1.0-3.0*X2+2.0*X3) - (x0?-1.0:1.0)*yy*(X-2.0*X2+X3)*deltat;
+     290             : 
+     291        4008 :     value+=grid*C;
+     292             :   }
+     293        2004 :   return value;
+     294             : }
+     295             : 
+     296           0 : void Caliber::do_regression_zero(const std::vector<double> &mean)
+     297             : {
+     298             : // parameters[i] = scale_ * mean[i]: find scale_ with linear regression
+     299             :   double num = 0.0;
+     300             :   double den = 0.0;
+     301           0 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     302           0 :     num += mean[i] * getSpline(i);
+     303           0 :     den += mean[i] * mean[i];
+     304             :   }
+     305           0 :   if(den>0) {
+     306           0 :     scale_ = num / den;
+     307             :   } else {
+     308           0 :     scale_ = 1.0;
+     309             :   }
+     310           0 : }
+     311             : 
+     312        2004 : void Caliber::calculate()
+     313             : {
+     314        2004 :   const unsigned narg = getNumberOfArguments();
+     315        2004 :   const double dnrep = static_cast<double>(nrep_);
+     316        2004 :   const double fact = 1.0/dnrep;
+     317             : 
+     318        2004 :   std::vector<double> mean(narg,0);
+     319        2004 :   std::vector<double> dmean_x(narg,fact);
+     320        2004 :   replica_averaging(fact, mean);
+     321        2004 :   if(optsigmamean_stride_>0) get_sigma_mean(fact, mean);
+     322             : 
+     323             :   // in case of regression with zero intercept, calculate scale
+     324        2004 :   if(doregres_zero_ && getStep()%nregres_zero_==0) do_regression_zero(mean);
+     325             : 
+     326             :   double ene=0;
+     327        4008 :   for(unsigned i=0; i<narg; ++i) {
+     328        2004 :     const double x0 = getSpline(i);
+     329        2004 :     const double kappa = mult*dnrep/sigma_mean2_[i];
+     330        2004 :     const double cv=difference(i,x0,scale_*mean[i]);
+     331        2004 :     const double f=-kappa*cv*dmean_x[i]/scale_;
+     332        2004 :     setOutputForce(i,f);
+     333        2004 :     ene+=0.5*kappa*cv*cv;
+     334        2004 :     x0comp[i]->set(x0);
+     335        2004 :     kcomp[i]->set(kappa);
+     336        2004 :     mcomp[i]->set(mean[i]);
+     337             :   }
+     338             : 
+     339        2004 :   if(doregres_zero_) valueScale->set(scale_);
+     340             : 
+     341        2004 :   setBias(ene);
+     342        2004 : }
+     343             : 
+     344             : }
+     345             : }
+     346             : 
+     347             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMI.cpp.func-sort-c.html b/coverage/isdb/EMMI.cpp.func-sort-c.html new file mode 100644 index 000000000000..dfeeb46b5d34 --- /dev/null +++ b/coverage/isdb/EMMI.cpp.func-sort-c.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - isdb/EMMI.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - EMMI.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:58977975.6 %
Date:2024-02-22 21:58:45Functions:293974.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4EMMI11read_statusEv0
_ZN4PLMD4isdb4EMMI11scaleEnergyEd0
_ZN4PLMD4isdb4EMMI12doMonteCarloEv0
_ZN4PLMD4isdb4EMMI12doRegressionEv0
_ZN4PLMD4isdb4EMMI13get_annealingEx0
_ZN4PLMD4isdb4EMMI15read_exp_errorsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI17read_exp_overlapsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI19write_model_overlapEx0
_ZN4PLMD4isdb4EMMI8doAcceptEddd0
_ZN4PLMD4isdb4EMMIC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb4EMMI29calculateNumericalDerivativesEPNS_15ActionWithValueE9
_ZN4PLMD4isdb4EMMI14setDerivativesEv20
_ZN4PLMD4isdb4EMMI17turnOnDerivativesEv20
_ZN4PLMD4isdb4EMMI22calculate_useful_stuffEd20
_ZN4PLMD4isdb4EMMI9get_GMM_dERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD4isdb4EMMI9get_GMM_mERSt6vectorINS_10AtomNumberESaIS3_EE20
_ZN4PLMD4isdb4EMMIC1ERKNS_13ActionOptionsE20
_ZN4PLMD4isdb4EMMI16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD4isdb4EMMI12lockRequestsEv30
_ZN4PLMD4isdb4EMMI14unlockRequestsEv30
_ZN4PLMD4isdb4EMMI5applyEv30
_ZN4PLMD4isdb4EMMI7prepareEv30
_ZN4PLMD4isdb4EMMI10get_medianERSt6vectorIdSaIdEE40
_ZN4PLMD4isdb4EMMI22getNumberOfDerivativesEv72
_ZN4PLMD4isdb4EMMI11check_GMM_dERKNS_13VectorGenericILj6EEEd1962
_ZN4PLMD4isdb4EMMI16get_self_overlapEj1962
_ZN4PLMD4isdb4EMMI18calculate_MarginalEv5451
_ZN4PLMD4isdb4EMMI18calculate_OutliersEv5451
_ZN4PLMD4isdb4EMMI15calculate_GaussEv5463
_ZN4PLMD4isdb4EMMI12print_statusEx10904
_ZN4PLMD4isdb4EMMI20update_neighbor_listEv16355
_ZN4PLMD4isdb4EMMI11get_weightsERdS2_S2_16365
_ZN4PLMD4isdb4EMMI17calculate_overlapEv16365
_ZN4PLMD4isdb4EMMI17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE16365
_ZN4PLMD4isdb4EMMI9calculateEv16365
_ZN4PLMD4isdb4EMMI21get_prefactor_inverseERKNS_13VectorGenericILj6EEES5_ddRS3_S6_1621458
_ZN4PLMD4isdb4EMMI11get_overlapERKNS_13VectorGenericILj3EEES5_dRKNS2_ILj6EEERS3_3732816
_ZN4PLMD4isdb4EMMI19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE9844626
_ZN4PLMD4isdb4EMMI15get_exp_overlapERKNS_13VectorGenericILj3EEES5_RKNS2_ILj6EEE59085036
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMI.cpp.func.html b/coverage/isdb/EMMI.cpp.func.html new file mode 100644 index 000000000000..cce0c1519783 --- /dev/null +++ b/coverage/isdb/EMMI.cpp.func.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - isdb/EMMI.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - EMMI.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:58977975.6 %
Date:2024-02-22 21:58:45Functions:293974.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4EMMI10get_medianERSt6vectorIdSaIdEE40
_ZN4PLMD4isdb4EMMI11check_GMM_dERKNS_13VectorGenericILj6EEEd1962
_ZN4PLMD4isdb4EMMI11get_overlapERKNS_13VectorGenericILj3EEES5_dRKNS2_ILj6EEERS3_3732816
_ZN4PLMD4isdb4EMMI11get_weightsERdS2_S2_16365
_ZN4PLMD4isdb4EMMI11read_statusEv0
_ZN4PLMD4isdb4EMMI11scaleEnergyEd0
_ZN4PLMD4isdb4EMMI12doMonteCarloEv0
_ZN4PLMD4isdb4EMMI12doRegressionEv0
_ZN4PLMD4isdb4EMMI12lockRequestsEv30
_ZN4PLMD4isdb4EMMI12print_statusEx10904
_ZN4PLMD4isdb4EMMI13get_annealingEx0
_ZN4PLMD4isdb4EMMI14setDerivativesEv20
_ZN4PLMD4isdb4EMMI14unlockRequestsEv30
_ZN4PLMD4isdb4EMMI15calculate_GaussEv5463
_ZN4PLMD4isdb4EMMI15get_exp_overlapERKNS_13VectorGenericILj3EEES5_RKNS2_ILj6EEE59085036
_ZN4PLMD4isdb4EMMI15read_exp_errorsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI16get_self_overlapEj1962
_ZN4PLMD4isdb4EMMI16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD4isdb4EMMI17calculate_overlapEv16365
_ZN4PLMD4isdb4EMMI17read_exp_overlapsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb4EMMI17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE16365
_ZN4PLMD4isdb4EMMI17turnOnDerivativesEv20
_ZN4PLMD4isdb4EMMI18calculate_MarginalEv5451
_ZN4PLMD4isdb4EMMI18calculate_OutliersEv5451
_ZN4PLMD4isdb4EMMI19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE9844626
_ZN4PLMD4isdb4EMMI19write_model_overlapEx0
_ZN4PLMD4isdb4EMMI20update_neighbor_listEv16355
_ZN4PLMD4isdb4EMMI21get_prefactor_inverseERKNS_13VectorGenericILj6EEES5_ddRS3_S6_1621458
_ZN4PLMD4isdb4EMMI22calculate_useful_stuffEd20
_ZN4PLMD4isdb4EMMI22getNumberOfDerivativesEv72
_ZN4PLMD4isdb4EMMI29calculateNumericalDerivativesEPNS_15ActionWithValueE9
_ZN4PLMD4isdb4EMMI5applyEv30
_ZN4PLMD4isdb4EMMI7prepareEv30
_ZN4PLMD4isdb4EMMI8doAcceptEddd0
_ZN4PLMD4isdb4EMMI9calculateEv16365
_ZN4PLMD4isdb4EMMI9get_GMM_dERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20
_ZN4PLMD4isdb4EMMI9get_GMM_mERSt6vectorINS_10AtomNumberESaIS3_EE20
_ZN4PLMD4isdb4EMMIC1ERKNS_13ActionOptionsE20
_ZN4PLMD4isdb4EMMIC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMI.cpp.gcov.html b/coverage/isdb/EMMI.cpp.gcov.html new file mode 100644 index 000000000000..c20f63388112 --- /dev/null +++ b/coverage/isdb/EMMI.cpp.gcov.html @@ -0,0 +1,1824 @@ + + + + + + + + LCOV - plumed test coverage - isdb/EMMI.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - EMMI.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:58977975.6 %
Date:2024-02-22 21:58:45Functions:293974.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionWithValue.h"
+      23             : #include "core/ActionAtomistic.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "tools/Matrix.h"
+      28             : #include "tools/Communicator.h"
+      29             : #include "core/GenericMolInfo.h"
+      30             : #include "core/ActionSet.h"
+      31             : #include "tools/File.h"
+      32             : #include "tools/Random.h"
+      33             : 
+      34             : #include <string>
+      35             : #include <map>
+      36             : #include <numeric>
+      37             : #include <ctime>
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace isdb {
+      41             : 
+      42             : //+PLUMEDOC ISDB_COLVAR EMMI
+      43             : /*
+      44             : Calculate the fit of a structure or ensemble of structures with a cryo-EM density map.
+      45             : 
+      46             : This action implements the multi-scale Bayesian approach to cryo-EM data fitting introduced in  Ref. \cite Hanot113951 .
+      47             : This method allows efficient and accurate structural modeling of cryo-electron microscopy density maps at multiple scales, from coarse-grained to atomistic resolution, by addressing the presence of random and systematic errors in the data, sample heterogeneity, data correlation, and noise correlation.
+      48             : 
+      49             : The experimental density map is fit by a Gaussian Mixture Model (GMM), which is provided as an external file specified by the keyword
+      50             : GMM_FILE. We are currently working on a web server to perform
+      51             : this operation. In the meantime, the user can request a stand-alone version of the GMM code at massimiliano.bonomi_AT_gmail.com.
+      52             : 
+      53             : When run in single-replica mode, this action allows atomistic, flexible refinement of an individual structure into a density map.
+      54             : Combined with a multi-replica framework (such as the -multi option in GROMACS), the user can model an ensemble of structures using
+      55             : the Metainference approach \cite Bonomi:2016ip .
+      56             : 
+      57             : \warning
+      58             : To use \ref EMMI, the user should always add a \ref MOLINFO line and specify a pdb file of the system.
+      59             : 
+      60             : \note
+      61             : To enhance sampling in single-structure refinement, one can use a Replica Exchange Method, such as Parallel Tempering.
+      62             : In this case, the user should add the NO_AVER flag to the input line. To use a replica-based enhanced sampling scheme such as
+      63             : Parallel-Bias Metadynamics (\ref PBMETAD), one should use the REWEIGHT flag and pass the Metadynamics bias using the ARG keyword.
+      64             : 
+      65             : \note
+      66             : \ref EMMI can be used in combination with periodic and non-periodic systems. In the latter case, one should
+      67             : add the NOPBC flag to the input line
+      68             : 
+      69             : \par Examples
+      70             : 
+      71             : In this example, we perform a single-structure refinement based on an experimental cryo-EM map. The map is fit with a GMM, whose
+      72             : parameters are listed in the file GMM_fit.dat. This file contains one line per GMM component in the following format:
+      73             : 
+      74             : \plumedfile
+      75             : #! FIELDS Id Weight Mean_0 Mean_1 Mean_2 Cov_00 Cov_01 Cov_02 Cov_11 Cov_12 Cov_22 Beta
+      76             :      0  2.9993805e+01   6.54628 10.37820 -0.92988  2.078920e-02 1.216254e-03 5.990827e-04 2.556246e-02 8.411835e-03 2.486254e-02  1
+      77             :      1  2.3468312e+01   6.56095 10.34790 -0.87808  1.879859e-02 6.636049e-03 3.682865e-04 3.194490e-02 1.750524e-03 3.017100e-02  1
+      78             :      ...
+      79             : \endplumedfile
+      80             : 
+      81             : To accelerate the computation of the Bayesian score, one can:
+      82             : - use neighbor lists, specified by the keywords NL_CUTOFF and NL_STRIDE;
+      83             : - calculate the restraint every other step (or more).
+      84             : 
+      85             : All the heavy atoms of the system are used to calculate the density map. This list can conveniently be provided
+      86             : using a GROMACS index file.
+      87             : 
+      88             : The input file looks as follows:
+      89             : 
+      90             : \plumedfile
+      91             : # include pdb info
+      92             : MOLINFO STRUCTURE=prot.pdb
+      93             : 
+      94             : #  all heavy atoms
+      95             : protein-h: GROUP NDX_FILE=index.ndx NDX_GROUP=Protein-H
+      96             : 
+      97             : # create EMMI score
+      98             : gmm: EMMI NOPBC SIGMA_MIN=0.01 TEMP=300.0 NL_STRIDE=100 NL_CUTOFF=0.01 GMM_FILE=GMM_fit.dat ATOMS=protein-h
+      99             : 
+     100             : # translate into bias - apply every 2 steps
+     101             : emr: BIASVALUE ARG=gmm.scoreb STRIDE=2
+     102             : 
+     103             : PRINT ARG=emr.* FILE=COLVAR STRIDE=500 FMT=%20.10f
+     104             : \endplumedfile
+     105             : 
+     106             : 
+     107             : */
+     108             : //+ENDPLUMEDOC
+     109             : 
+     110             : class EMMI :
+     111             :   public ActionAtomistic,
+     112             :   public ActionWithArguments,
+     113             :   public ActionWithValue
+     114             : {
+     115             : private:
+     116             : 
+     117             : // temperature in kbt
+     118             :   double kbt_;
+     119             : // model GMM - atom types
+     120             :   std::vector<unsigned> GMM_m_type_;
+     121             : // model GMM - list of atom sigmas - one per atom type
+     122             :   std::vector<double> GMM_m_s_;
+     123             : // model GMM - list of atom weights - one per atom type
+     124             :   std::vector<double> GMM_m_w_;
+     125             : // data GMM - means, weights, and covariances + beta option
+     126             :   std::vector<Vector>             GMM_d_m_;
+     127             :   std::vector<double>             GMM_d_w_;
+     128             :   std::vector< VectorGeneric<6> > GMM_d_cov_;
+     129             :   std::vector<int>                GMM_d_beta_;
+     130             :   std::vector < std::vector<int> >     GMM_d_grps_;
+     131             : // overlaps
+     132             :   std::vector<double> ovmd_;
+     133             :   std::vector<double> ovdd_;
+     134             :   std::vector<double> ovmd_ave_;
+     135             : // and derivatives
+     136             :   std::vector<Vector> ovmd_der_;
+     137             :   std::vector<Vector> atom_der_;
+     138             :   std::vector<double> GMMid_der_;
+     139             : // constants
+     140             :   double cfact_;
+     141             :   double inv_sqrt2_, sqrt2_pi_;
+     142             : // metainference
+     143             :   unsigned nrep_;
+     144             :   unsigned replica_;
+     145             :   std::vector<double> sigma_;
+     146             :   std::vector<double> sigma_min_;
+     147             :   std::vector<double> sigma_max_;
+     148             :   std::vector<double> dsigma_;
+     149             : // list of prefactors for overlap between two Gaussians
+     150             : // pre_fact = 1.0 / (2pi)**1.5 / std::sqrt(det_md) * Wm * Wd
+     151             :   std::vector<double> pre_fact_;
+     152             : // inverse of the sum of model and data covariances matrices
+     153             :   std::vector< VectorGeneric<6> > inv_cov_md_;
+     154             : // neighbor list
+     155             :   double   nl_cutoff_;
+     156             :   unsigned nl_stride_;
+     157             :   bool first_time_;
+     158             :   bool no_aver_;
+     159             :   std::vector<unsigned> nl_;
+     160             : // parallel stuff
+     161             :   unsigned size_;
+     162             :   unsigned rank_;
+     163             : // pbc
+     164             :   bool pbc_;
+     165             : // Monte Carlo stuff
+     166             :   int      MCstride_;
+     167             :   double   MCaccept_;
+     168             :   double   MCtrials_;
+     169             :   Random   random_;
+     170             :   // status stuff
+     171             :   unsigned int statusstride_;
+     172             :   std::string       statusfilename_;
+     173             :   OFile        statusfile_;
+     174             :   bool         first_status_;
+     175             :   // regression
+     176             :   unsigned nregres_;
+     177             :   double scale_;
+     178             :   double scale_min_;
+     179             :   double scale_max_;
+     180             :   double dscale_;
+     181             :   // tabulated exponential
+     182             :   double dpcutoff_;
+     183             :   double dexp_;
+     184             :   unsigned nexp_;
+     185             :   std::vector<double> tab_exp_;
+     186             :   // simulated annealing
+     187             :   unsigned nanneal_;
+     188             :   double   kanneal_;
+     189             :   double   anneal_;
+     190             :   // prior exponent
+     191             :   double prior_;
+     192             :   // noise type
+     193             :   unsigned noise_;
+     194             :   // total score and virial;
+     195             :   double ene_;
+     196             :   Tensor virial_;
+     197             :   // model overlap file
+     198             :   unsigned int ovstride_;
+     199             :   std::string       ovfilename_;
+     200             : 
+     201             :   // Reweighting additions
+     202             :   bool do_reweight_;
+     203             :   bool first_time_w_;
+     204             :   std::vector<double> forces;
+     205             :   std::vector<double> forcesToApply;
+     206             : 
+     207             :   // average weights
+     208             :   double decay_w_;
+     209             :   std::vector<double> average_weights_;
+     210             : 
+     211             : // write file with model overlap
+     212             :   void write_model_overlap(long long int step);
+     213             : // get median of std::vector
+     214             :   double get_median(std::vector<double> &v);
+     215             : // annealing
+     216             :   double get_annealing(long long int step);
+     217             : // do regression
+     218             :   double scaleEnergy(double s);
+     219             :   double doRegression();
+     220             : // read and write status
+     221             :   void read_status();
+     222             :   void print_status(long long int step);
+     223             : // accept or reject
+     224             :   bool doAccept(double oldE, double newE, double kbt);
+     225             : // do MonteCarlo
+     226             :   void doMonteCarlo();
+     227             : // read error file
+     228             :   std::vector<double> read_exp_errors(const std::string & errfile);
+     229             : // read experimental overlaps
+     230             :   std::vector<double> read_exp_overlaps(const std::string & ovfile);
+     231             : // calculate model GMM weights and covariances
+     232             :   std::vector<double> get_GMM_m(std::vector<AtomNumber> &atoms);
+     233             : // read data GMM file
+     234             :   void get_GMM_d(const std::string & gmm_file);
+     235             : // check GMM data
+     236             :   void check_GMM_d(const VectorGeneric<6> &cov, double w);
+     237             : // auxiliary method
+     238             :   void calculate_useful_stuff(double reso);
+     239             : // get pref_fact and inv_cov_md
+     240             :   double get_prefactor_inverse (const VectorGeneric<6> &GMM_cov_0, const VectorGeneric<6> &GMM_cov_1,
+     241             :                                 double GMM_w_0, double GMM_w_1,
+     242             :                                 VectorGeneric<6> &sum, VectorGeneric<6> &inv_sum);
+     243             : // calculate self overlaps between data GMM components - ovdd_
+     244             :   double get_self_overlap(unsigned id);
+     245             : // calculate overlap between two Gaussians
+     246             :   double get_overlap(const Vector &m_m, const Vector &d_m, double pre_fact,
+     247             :                      const VectorGeneric<6> &inv_cov_md, Vector &ov_der);
+     248             : // calculate exponent of overlap for neighbor list update
+     249             :   double get_exp_overlap(const Vector &m_m, const Vector &d_m,
+     250             :                          const VectorGeneric<6> &inv_cov_md);
+     251             : // update the neighbor list
+     252             :   void update_neighbor_list();
+     253             : // calculate overlap
+     254             :   void calculate_overlap();
+     255             : // Gaussian noise
+     256             :   void calculate_Gauss();
+     257             : // Outliers noise
+     258             :   void calculate_Outliers();
+     259             : // Marginal noise
+     260             :   void calculate_Marginal();
+     261             : 
+     262             :   // See MetainferenceBase
+     263             :   void get_weights(double &weight, double &norm, double &neff);
+     264             : 
+     265             : public:
+     266             :   static void registerKeywords( Keywords& keys );
+     267             :   explicit EMMI(const ActionOptions&);
+     268             :   // needed for reweighting
+     269             :   void setDerivatives();
+     270             :   void turnOnDerivatives() override;
+     271             :   unsigned getNumberOfDerivatives() override;
+     272             :   void lockRequests() override;
+     273             :   void unlockRequests() override;
+     274             :   void calculateNumericalDerivatives( ActionWithValue* a ) override;
+     275             :   void apply() override;
+     276             :   void setArgDerivatives(Value *v, const double &d);
+     277             :   void setAtomsDerivatives(Value*v, const unsigned i, const Vector&d);
+     278             :   void setBoxDerivatives(Value*v, const Tensor&d);
+     279             : // active methods:
+     280             :   void prepare() override;
+     281             :   void calculate() override;
+     282             : };
+     283             : 
+     284             : inline
+     285          20 : void EMMI::setDerivatives() {
+     286             :   // Get appropriate number of derivatives
+     287             :   // Derivatives are first for arguments and then for atoms
+     288             :   unsigned nder;
+     289          20 :   if( getNumberOfAtoms()>0 ) {
+     290          20 :     nder = 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     291             :   } else {
+     292           0 :     nder = getNumberOfArguments();
+     293             :   }
+     294             : 
+     295             :   // Resize all derivative arrays
+     296          20 :   forces.resize( nder ); forcesToApply.resize( nder );
+     297          92 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(nder);
+     298          20 : }
+     299             : 
+     300             : inline
+     301          20 : void EMMI::turnOnDerivatives() {
+     302          20 :   ActionWithValue::turnOnDerivatives();
+     303          20 : }
+     304             : 
+     305             : inline
+     306          72 : unsigned EMMI::getNumberOfDerivatives() {
+     307          72 :   if( getNumberOfAtoms()>0 ) {
+     308          72 :     return 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     309             :   }
+     310           0 :   return getNumberOfArguments();
+     311             : }
+     312             : 
+     313             : inline
+     314          30 : void EMMI::lockRequests() {
+     315             :   ActionAtomistic::lockRequests();
+     316             :   ActionWithArguments::lockRequests();
+     317          30 : }
+     318             : 
+     319             : inline
+     320          30 : void EMMI::unlockRequests() {
+     321             :   ActionAtomistic::unlockRequests();
+     322             :   ActionWithArguments::unlockRequests();
+     323          30 : }
+     324             : 
+     325             : inline
+     326           9 : void EMMI::calculateNumericalDerivatives( ActionWithValue* a=NULL ) {
+     327           9 :   if( getNumberOfArguments()>0 ) {
+     328           0 :     ActionWithArguments::calculateNumericalDerivatives( a );
+     329             :   }
+     330           9 :   if( getNumberOfAtoms()>0 ) {
+     331           9 :     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
+     332          39 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     333          30 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) if(getPntrToComponent(j)->hasDerivatives()) save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
+     334             :     }
+     335           9 :     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
+     336          39 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     337          30 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) if(getPntrToComponent(j)->hasDerivatives()) getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
+     338             :     }
+     339             :   }
+     340           9 : }
+     341             : 
+     342             : inline
+     343          30 : void EMMI::apply() {
+     344          30 :   bool wasforced=false; forcesToApply.assign(forcesToApply.size(),0.0);
+     345         162 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     346         132 :     if( getPntrToComponent(i)->applyForce( forces ) ) {
+     347             :       wasforced=true;
+     348           0 :       for(unsigned i=0; i<forces.size(); ++i) forcesToApply[i]+=forces[i];
+     349             :     }
+     350             :   }
+     351          30 :   if( wasforced ) {
+     352           0 :     unsigned ind=0; addForcesOnArguments( 0, forcesToApply, ind );
+     353           0 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, ind );
+     354             :   }
+     355          30 : }
+     356             : 
+     357             : inline
+     358             : void EMMI::setArgDerivatives(Value *v, const double &d) {
+     359             :   v->addDerivative(0,d);
+     360             : }
+     361             : 
+     362             : inline
+     363     9844626 : void EMMI::setAtomsDerivatives(Value*v, const unsigned i, const Vector&d) {
+     364     9844626 :   const unsigned noa=getNumberOfArguments();
+     365     9844626 :   v->addDerivative(noa+3*i+0,d[0]);
+     366     9844626 :   v->addDerivative(noa+3*i+1,d[1]);
+     367     9844626 :   v->addDerivative(noa+3*i+2,d[2]);
+     368     9844626 : }
+     369             : 
+     370             : inline
+     371       16365 : void EMMI::setBoxDerivatives(Value* v,const Tensor&d) {
+     372       16365 :   const unsigned noa=getNumberOfArguments();
+     373             :   const unsigned nat=getNumberOfAtoms();
+     374       16365 :   v->addDerivative(noa+3*nat+0,d(0,0));
+     375       16365 :   v->addDerivative(noa+3*nat+1,d(0,1));
+     376       16365 :   v->addDerivative(noa+3*nat+2,d(0,2));
+     377       16365 :   v->addDerivative(noa+3*nat+3,d(1,0));
+     378       16365 :   v->addDerivative(noa+3*nat+4,d(1,1));
+     379       16365 :   v->addDerivative(noa+3*nat+5,d(1,2));
+     380       16365 :   v->addDerivative(noa+3*nat+6,d(2,0));
+     381       16365 :   v->addDerivative(noa+3*nat+7,d(2,1));
+     382       16365 :   v->addDerivative(noa+3*nat+8,d(2,2));
+     383       16365 : }
+     384             : 
+     385             : PLUMED_REGISTER_ACTION(EMMI,"EMMI")
+     386             : 
+     387          22 : void EMMI::registerKeywords( Keywords& keys ) {
+     388          22 :   Action::registerKeywords( keys );
+     389          22 :   ActionAtomistic::registerKeywords( keys );
+     390          22 :   ActionWithValue::registerKeywords( keys );
+     391          22 :   ActionWithArguments::registerKeywords( keys );
+     392          22 :   keys.use("ARG");
+     393          44 :   keys.add("atoms","ATOMS","atoms for which we calculate the density map, typically all heavy atoms");
+     394          44 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     395          44 :   keys.add("compulsory","GMM_FILE","file with the parameters of the GMM components");
+     396          44 :   keys.add("compulsory","NL_CUTOFF","The cutoff in overlap for the neighbor list");
+     397          44 :   keys.add("compulsory","NL_STRIDE","The frequency with which we are updating the neighbor list");
+     398          44 :   keys.add("compulsory","SIGMA_MIN","minimum uncertainty");
+     399          44 :   keys.add("compulsory","RESOLUTION", "Cryo-EM map resolution");
+     400          44 :   keys.add("compulsory","NOISETYPE","functional form of the noise (GAUSS, OUTLIERS, MARGINAL)");
+     401          44 :   keys.add("optional","SIGMA0","initial value of the uncertainty");
+     402          44 :   keys.add("optional","DSIGMA","MC step for uncertainties");
+     403          44 :   keys.add("optional","MC_STRIDE", "Monte Carlo stride");
+     404          44 :   keys.add("optional","ERR_FILE","file with experimental or GMM fit errors");
+     405          44 :   keys.add("optional","OV_FILE","file with experimental overlaps");
+     406          44 :   keys.add("optional","NORM_DENSITY","integral of the experimental density");
+     407          44 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart");
+     408          44 :   keys.add("optional","WRITE_STRIDE","write the status to a file every N steps, this can be used for restart");
+     409          44 :   keys.add("optional","REGRESSION","regression stride");
+     410          44 :   keys.add("optional","REG_SCALE_MIN","regression minimum scale");
+     411          44 :   keys.add("optional","REG_SCALE_MAX","regression maximum scale");
+     412          44 :   keys.add("optional","REG_DSCALE","regression maximum scale MC move");
+     413          44 :   keys.add("optional","SCALE","scale factor");
+     414          44 :   keys.add("optional","ANNEAL", "Length of annealing cycle");
+     415          44 :   keys.add("optional","ANNEAL_FACT", "Annealing temperature factor");
+     416          44 :   keys.add("optional","TEMP","temperature");
+     417          44 :   keys.add("optional","PRIOR", "exponent of uncertainty prior");
+     418          44 :   keys.add("optional","WRITE_OV_STRIDE","write model overlaps every N steps");
+     419          44 :   keys.add("optional","WRITE_OV","write a file with model overlaps");
+     420          44 :   keys.add("optional","AVERAGING", "Averaging window for weights");
+     421          44 :   keys.addFlag("NO_AVER",false,"don't do ensemble averaging in multi-replica mode");
+     422          44 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the ARG as energy");
+     423          22 :   componentsAreNotOptional(keys);
+     424          44 :   keys.addOutputComponent("scoreb","default","Bayesian score");
+     425          44 :   keys.addOutputComponent("acc",   "NOISETYPE","MC acceptance for uncertainty");
+     426          44 :   keys.addOutputComponent("scale", "REGRESSION","scale factor");
+     427          44 :   keys.addOutputComponent("accscale", "REGRESSION","MC acceptance for scale regression");
+     428          44 :   keys.addOutputComponent("enescale", "REGRESSION","MC energy for scale regression");
+     429          44 :   keys.addOutputComponent("anneal","ANNEAL","annealing factor");
+     430          44 :   keys.addOutputComponent("weight",       "REWEIGHT",     "weights of the weighted average");
+     431          44 :   keys.addOutputComponent("biasDer",      "REWEIGHT",     "derivatives with respect to the bias");
+     432          44 :   keys.addOutputComponent("sigma",      "NOISETYPE",     "uncertainty in the forward models and experiment");
+     433          44 :   keys.addOutputComponent("neff",         "default",      "effective number of replicas");
+     434          22 : }
+     435             : 
+     436          20 : EMMI::EMMI(const ActionOptions&ao):
+     437             :   Action(ao),
+     438             :   ActionAtomistic(ao),
+     439             :   ActionWithArguments(ao),
+     440             :   ActionWithValue(ao),
+     441          20 :   inv_sqrt2_(0.707106781186548),
+     442          20 :   sqrt2_pi_(0.797884560802865),
+     443          20 :   first_time_(true), no_aver_(false), pbc_(true),
+     444          20 :   MCstride_(1), MCaccept_(0.), MCtrials_(0.),
+     445          40 :   statusstride_(0), first_status_(true),
+     446          20 :   nregres_(0), scale_(1.),
+     447          20 :   dpcutoff_(15.0), nexp_(1000000), nanneal_(0),
+     448          40 :   kanneal_(0.), anneal_(1.), prior_(1.), ovstride_(0),
+     449          20 :   do_reweight_(false), first_time_w_(true), decay_w_(1.)
+     450             : {
+     451             :   // periodic boundary conditions
+     452          20 :   bool nopbc=!pbc_;
+     453          20 :   parseFlag("NOPBC",nopbc);
+     454          20 :   pbc_=!nopbc;
+     455             : 
+     456             :   // list of atoms
+     457             :   std::vector<AtomNumber> atoms;
+     458          40 :   parseAtomList("ATOMS", atoms);
+     459             : 
+     460             :   // file with data GMM
+     461             :   std::string GMM_file;
+     462          40 :   parse("GMM_FILE", GMM_file);
+     463             : 
+     464             :   // type of data noise
+     465             :   std::string noise;
+     466          40 :   parse("NOISETYPE",noise);
+     467          20 :   if      (noise=="GAUSS")   noise_ = 0;
+     468          12 :   else if(noise=="OUTLIERS") noise_ = 1;
+     469           6 :   else if(noise=="MARGINAL") noise_ = 2;
+     470           0 :   else error("Unknown noise type!");
+     471             : 
+     472             :   // minimum value for error
+     473             :   double sigma_min;
+     474          20 :   parse("SIGMA_MIN", sigma_min);
+     475          20 :   if(sigma_min<0) error("SIGMA_MIN should be greater or equal to zero");
+     476             : 
+     477             :   // the following parameters must be specified with noise type 0 and 1
+     478             :   double sigma_ini, dsigma;
+     479          20 :   if(noise_!=2) {
+     480             :     // initial value of the uncertainty
+     481          14 :     parse("SIGMA0", sigma_ini);
+     482          14 :     if(sigma_ini<=0) error("you must specify a positive SIGMA0");
+     483             :     // MC parameters
+     484          14 :     parse("DSIGMA", dsigma);
+     485          14 :     if(dsigma<0) error("you must specify a positive DSIGMA");
+     486          14 :     parse("MC_STRIDE", MCstride_);
+     487          14 :     if(dsigma>0 && MCstride_<=0) error("you must specify a positive MC_STRIDE");
+     488             :     // status file parameters
+     489          14 :     parse("WRITE_STRIDE", statusstride_);
+     490          14 :     if(statusstride_==0) error("you must specify a positive WRITE_STRIDE");
+     491          28 :     parse("STATUS_FILE",  statusfilename_);
+     492          28 :     if(statusfilename_=="") statusfilename_ = "MISTATUS"+getLabel();
+     493           0 :     else                    statusfilename_ = statusfilename_+getLabel();
+     494             :   }
+     495             : 
+     496             :   // error file
+     497             :   std::string errfile;
+     498          40 :   parse("ERR_FILE", errfile);
+     499             : 
+     500             :   // file with experimental overlaps
+     501             :   std::string ovfile;
+     502          20 :   parse("OV_FILE", ovfile);
+     503             : 
+     504             :   // integral of the experimetal density
+     505          20 :   double norm_d = 0.0;
+     506          20 :   parse("NORM_DENSITY", norm_d);
+     507             : 
+     508             :   // temperature
+     509          20 :   kbt_ = getkBT();
+     510             : 
+     511             :   // exponent of uncertainty prior
+     512          20 :   parse("PRIOR",prior_);
+     513             : 
+     514             :   // simulated annealing stuff
+     515          20 :   parse("ANNEAL", nanneal_);
+     516          20 :   parse("ANNEAL_FACT", kanneal_);
+     517          20 :   if(nanneal_>0 && kanneal_<=1.0) error("with ANNEAL, ANNEAL_FACT must be greater than 1");
+     518             : 
+     519             :   // regression stride
+     520          20 :   parse("REGRESSION",nregres_);
+     521             :   // other regression parameters
+     522          20 :   if(nregres_>0) {
+     523           0 :     parse("REG_SCALE_MIN",scale_min_);
+     524           0 :     parse("REG_SCALE_MAX",scale_max_);
+     525           0 :     parse("REG_DSCALE",dscale_);
+     526             :     // checks
+     527           0 :     if(scale_max_<=scale_min_) error("with REGRESSION, REG_SCALE_MAX must be greater than REG_SCALE_MIN");
+     528           0 :     if(dscale_<=0.) error("with REGRESSION, REG_DSCALE must be positive");
+     529             :   }
+     530             : 
+     531             :   // scale factor
+     532          20 :   parse("SCALE", scale_);
+     533             : 
+     534             :   // read map resolution
+     535             :   double reso;
+     536          20 :   parse("RESOLUTION", reso);
+     537          20 :   if(reso<=0.) error("RESOLUTION should be strictly positive");
+     538             : 
+     539             :   // neighbor list stuff
+     540          20 :   parse("NL_CUTOFF",nl_cutoff_);
+     541          20 :   if(nl_cutoff_<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     542          20 :   parse("NL_STRIDE",nl_stride_);
+     543          20 :   if(nl_stride_==0) error("NL_STRIDE should be explicitly specified and positive");
+     544             : 
+     545             :   // averaging or not
+     546          20 :   parseFlag("NO_AVER",no_aver_);
+     547             : 
+     548             :   // write overlap file
+     549          20 :   parse("WRITE_OV_STRIDE", ovstride_);
+     550          20 :   parse("WRITE_OV", ovfilename_);
+     551          20 :   if(ovstride_>0 && ovfilename_=="") error("With WRITE_OV_STRIDE you must specify WRITE_OV");
+     552             : 
+     553             :   // set parallel stuff
+     554          20 :   size_=comm.Get_size();
+     555          20 :   rank_=comm.Get_rank();
+     556             : 
+     557             :   // get number of replicas
+     558          20 :   if(rank_==0) {
+     559          14 :     if(no_aver_) {
+     560          12 :       nrep_ = 1;
+     561             :     } else {
+     562           2 :       nrep_ = multi_sim_comm.Get_size();
+     563             :     }
+     564          14 :     replica_ = multi_sim_comm.Get_rank();
+     565             :   } else {
+     566           6 :     nrep_ = 0;
+     567           6 :     replica_ = 0;
+     568             :   }
+     569          20 :   comm.Sum(&nrep_,1);
+     570          20 :   comm.Sum(&replica_,1);
+     571             : 
+     572             :   // Reweighting flag
+     573          20 :   parseFlag("REWEIGHT", do_reweight_);
+     574          20 :   if(do_reweight_&&getNumberOfArguments()!=1) error("To REWEIGHT one must provide one single bias as an argument");
+     575          20 :   if(do_reweight_&&no_aver_) error("REWEIGHT cannot be used with NO_AVER");
+     576          20 :   if(do_reweight_&&nrep_<2) error("REWEIGHT can only be used in parallel with 2 or more replicas");
+     577          20 :   if(!getRestart()) average_weights_.resize(nrep_, 1./static_cast<double>(nrep_));
+     578           0 :   else average_weights_.resize(nrep_, 0.);
+     579             : 
+     580          20 :   unsigned averaging=0;
+     581          20 :   parse("AVERAGING", averaging);
+     582          20 :   if(averaging>0) {
+     583           2 :     decay_w_ = 1./static_cast<double> (averaging);
+     584             :   }
+     585             : 
+     586          20 :   checkRead();
+     587             : 
+     588          20 :   log.printf("  atoms involved : ");
+     589       10876 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial());
+     590          20 :   log.printf("\n");
+     591          20 :   log.printf("  GMM data file : %s\n", GMM_file.c_str());
+     592          20 :   if(no_aver_) log.printf("  without ensemble averaging\n");
+     593          20 :   log.printf("  type of data noise : %s\n", noise.c_str());
+     594          20 :   log.printf("  neighbor list cutoff : %lf\n", nl_cutoff_);
+     595          20 :   log.printf("  neighbor list stride : %u\n",  nl_stride_);
+     596          20 :   log.printf("  minimum uncertainty : %f\n",sigma_min);
+     597          20 :   log.printf("  scale factor : %lf\n",scale_);
+     598          20 :   if(nregres_>0) {
+     599           0 :     log.printf("  regression stride : %u\n", nregres_);
+     600           0 :     log.printf("  regression minimum scale : %lf\n", scale_min_);
+     601           0 :     log.printf("  regression maximum scale : %lf\n", scale_max_);
+     602           0 :     log.printf("  regression maximum scale MC move : %lf\n", dscale_);
+     603             :   }
+     604          20 :   if(noise_!=2) {
+     605          14 :     log.printf("  initial value of the uncertainty : %f\n",sigma_ini);
+     606          14 :     log.printf("  max MC move in uncertainty : %f\n",dsigma);
+     607          14 :     log.printf("  MC stride : %u\n", MCstride_);
+     608          14 :     log.printf("  reading/writing to status file : %s\n",statusfilename_.c_str());
+     609          14 :     log.printf("  with stride : %u\n",statusstride_);
+     610             :   }
+     611          20 :   if(errfile.size()>0) log.printf("  reading experimental errors from file : %s\n", errfile.c_str());
+     612          20 :   if(ovfile.size()>0)  log.printf("  reading experimental overlaps from file : %s\n", ovfile.c_str());
+     613          20 :   log.printf("  temperature of the system in energy unit : %f\n",kbt_);
+     614          20 :   log.printf("  prior exponent : %f\n",prior_);
+     615          20 :   log.printf("  number of replicas for averaging: %u\n",nrep_);
+     616          20 :   log.printf("  id of the replica : %u\n",replica_);
+     617          20 :   if(nanneal_>0) {
+     618           0 :     log.printf("  length of annealing cycle : %u\n",nanneal_);
+     619           0 :     log.printf("  annealing factor : %f\n",kanneal_);
+     620             :   }
+     621          20 :   if(ovstride_>0) {
+     622           0 :     log.printf("  stride for writing model overlaps : %u\n",ovstride_);
+     623           0 :     log.printf("  file for writing model overlaps : %s\n", ovfilename_.c_str());
+     624             :   }
+     625             : 
+     626             :   // set constant quantity before calculating stuff
+     627          20 :   cfact_ = 1.0/pow( 2.0*pi, 1.5 );
+     628             : 
+     629             :   // calculate model GMM constant parameters
+     630          20 :   std::vector<double> GMM_m_w = get_GMM_m(atoms);
+     631             : 
+     632             :   // read data GMM parameters
+     633          20 :   get_GMM_d(GMM_file);
+     634          20 :   log.printf("  number of GMM components : %u\n", static_cast<unsigned>(GMM_d_m_.size()));
+     635             : 
+     636             :   // normalize atom weight map
+     637          40 :   if(norm_d <= 0.0) norm_d = accumulate(GMM_d_w_.begin(), GMM_d_w_.end(), 0.0);
+     638             :   double norm_m = accumulate(GMM_m_w.begin(),  GMM_m_w.end(),  0.0);
+     639             :   // renormalization
+     640         100 :   for(unsigned i=0; i<GMM_m_w_.size(); ++i) GMM_m_w_[i] *= norm_d / norm_m;
+     641             : 
+     642             :   // read experimental errors
+     643             :   std::vector<double> exp_err;
+     644          20 :   if(errfile.size()>0) exp_err = read_exp_errors(errfile);
+     645             : 
+     646             :   // get self overlaps between data GMM components
+     647          20 :   if(ovfile.size()>0) {
+     648           0 :     ovdd_ = read_exp_overlaps(ovfile);
+     649             :   } else {
+     650        1982 :     for(unsigned i=0; i<GMM_d_m_.size(); ++i) {
+     651        1962 :       double ov = get_self_overlap(i);
+     652        1962 :       ovdd_.push_back(ov);
+     653             :     }
+     654             :   }
+     655             : 
+     656          20 :   log.printf("  number of GMM groups : %u\n", static_cast<unsigned>(GMM_d_grps_.size()));
+     657             :   // cycle on GMM groups
+     658          40 :   for(unsigned Gid=0; Gid<GMM_d_grps_.size(); ++Gid) {
+     659          20 :     log.printf("    group %d\n", Gid);
+     660             :     // calculate median overlap and experimental error
+     661             :     std::vector<double> ovdd;
+     662             :     std::vector<double> err;
+     663             :     // cycle on the group members
+     664        1982 :     for(unsigned i=0; i<GMM_d_grps_[Gid].size(); ++i) {
+     665             :       // GMM id
+     666        1962 :       int GMMid = GMM_d_grps_[Gid][i];
+     667             :       // add to experimental error
+     668        1962 :       if(errfile.size()>0) err.push_back(exp_err[GMMid]);
+     669        1962 :       else                 err.push_back(0.);
+     670             :       // add to GMM overlap
+     671        1962 :       ovdd.push_back(ovdd_[GMMid]);
+     672             :     }
+     673             :     // calculate median quantities
+     674          20 :     double ovdd_m = get_median(ovdd);
+     675          20 :     double err_m  = get_median(err);
+     676             :     // print out statistics
+     677          20 :     log.printf("     # of members : %zu\n", GMM_d_grps_[Gid].size());
+     678          20 :     log.printf("     median overlap : %lf\n", ovdd_m);
+     679          20 :     log.printf("     median error : %lf\n", err_m);
+     680             :     // add minimum value of sigma for this group of GMMs
+     681          20 :     sigma_min_.push_back(std::sqrt(err_m*err_m+sigma_min*ovdd_m*sigma_min*ovdd_m));
+     682             :     // these are only needed with Gaussian and Outliers noise models
+     683          20 :     if(noise_!=2) {
+     684             :       // set dsigma
+     685          14 :       dsigma_.push_back(dsigma * ovdd_m);
+     686             :       // set sigma max
+     687          14 :       sigma_max_.push_back(10.0*ovdd_m + sigma_min_[Gid] + dsigma_[Gid]);
+     688             :       // initialize sigma
+     689          28 :       sigma_.push_back(std::max(sigma_min_[Gid],std::min(sigma_ini*ovdd_m,sigma_max_[Gid])));
+     690             :     }
+     691             :   }
+     692             : 
+     693             :   // read status file if restarting
+     694          20 :   if(getRestart() && noise_!=2) read_status();
+     695             : 
+     696             :   // calculate auxiliary stuff
+     697          20 :   calculate_useful_stuff(reso);
+     698             : 
+     699             :   // prepare data and derivative std::vectors
+     700          20 :   ovmd_.resize(ovdd_.size());
+     701          20 :   ovmd_ave_.resize(ovdd_.size());
+     702          20 :   atom_der_.resize(GMM_m_type_.size());
+     703          20 :   GMMid_der_.resize(ovdd_.size());
+     704             : 
+     705             :   // clear things that are no longer needed
+     706             :   GMM_d_cov_.clear();
+     707             : 
+     708             :   // add components
+     709          40 :   addComponentWithDerivatives("scoreb"); componentIsNotPeriodic("scoreb");
+     710             : 
+     711          48 :   if(noise_!=2) {addComponent("acc"); componentIsNotPeriodic("acc");}
+     712             : 
+     713          20 :   if(nregres_>0) {
+     714           0 :     addComponent("scale");     componentIsNotPeriodic("scale");
+     715           0 :     addComponent("accscale");  componentIsNotPeriodic("accscale");
+     716           0 :     addComponent("enescale");  componentIsNotPeriodic("enescale");
+     717             :   }
+     718             : 
+     719          20 :   if(nanneal_>0) {addComponent("anneal"); componentIsNotPeriodic("anneal");}
+     720             : 
+     721          20 :   if(do_reweight_) {
+     722           4 :     addComponent("biasDer");
+     723           4 :     componentIsNotPeriodic("biasDer");
+     724           4 :     addComponent("weight");
+     725           4 :     componentIsNotPeriodic("weight");
+     726             :   }
+     727             : 
+     728          40 :   addComponent("neff");
+     729          20 :   componentIsNotPeriodic("neff");
+     730             : 
+     731          34 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+     732          14 :     std::string num; Tools::convert(i, num);
+     733          28 :     addComponent("sigma-"+num); componentIsNotPeriodic("sigma-"+num);
+     734          28 :     getPntrToComponent("sigma-"+num)->set(sigma_[i]);
+     735             :   }
+     736             : 
+     737             :   // initialize random seed
+     738             :   unsigned iseed;
+     739          20 :   if(rank_==0) iseed = time(NULL)+replica_;
+     740           6 :   else iseed = 0;
+     741          20 :   comm.Sum(&iseed, 1);
+     742          20 :   random_.setSeed(-iseed);
+     743             : 
+     744             :   // request the atoms
+     745          20 :   requestAtoms(atoms);
+     746          20 :   setDerivatives();
+     747             : 
+     748             :   // print bibliography
+     749          40 :   log<<"  Bibliography "<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     750          40 :   log<<plumed.cite("Hanot, Bonomi, Greenberg, Sali, Nilges, Vendruscolo, Pellarin, bioRxiv doi: 10.1101/113951 (2017)");
+     751          40 :   log<<plumed.cite("Bonomi, Pellarin, Vendruscolo, Biophys. J. 114, 1604 (2018)");
+     752          22 :   if(do_reweight_) log<<plumed.cite("Bonomi, Camilloni, Vendruscolo, Sci. Rep. 6, 31232 (2016)");
+     753          22 :   if(!no_aver_ && nrep_>1)log<<plumed.cite("Bonomi, Camilloni, Cavalli, Vendruscolo, Sci. Adv. 2, e150117 (2016)");
+     754          20 :   log<<"\n";
+     755          20 : }
+     756             : 
+     757           0 : void EMMI::write_model_overlap(long long int step)
+     758             : {
+     759           0 :   OFile ovfile;
+     760           0 :   ovfile.link(*this);
+     761           0 :   std::string num; Tools::convert(step,num);
+     762           0 :   std::string name = ovfilename_+"-"+num;
+     763           0 :   ovfile.open(name);
+     764             :   ovfile.setHeavyFlush();
+     765           0 :   ovfile.fmtField("%10.7e ");
+     766             : // write overlaps
+     767           0 :   for(int i=0; i<ovmd_.size(); ++i) {
+     768           0 :     ovfile.printField("Model", ovmd_[i]);
+     769           0 :     ovfile.printField("ModelScaled", scale_ * ovmd_[i]);
+     770           0 :     ovfile.printField("Data", ovdd_[i]);
+     771           0 :     ovfile.printField();
+     772             :   }
+     773           0 :   ovfile.close();
+     774           0 : }
+     775             : 
+     776          40 : double EMMI::get_median(std::vector<double> &v)
+     777             : {
+     778             : // dimension of std::vector
+     779          40 :   unsigned size = v.size();
+     780             : // in case of only one entry
+     781          40 :   if (size==1) {
+     782           0 :     return v[0];
+     783             :   } else {
+     784             :     // reorder std::vector
+     785          40 :     sort(v.begin(), v.end());
+     786             :     // odd or even?
+     787          40 :     if (size%2==0) {
+     788           4 :       return (v[size/2-1]+v[size/2])/2.0;
+     789             :     } else {
+     790          36 :       return v[size/2];
+     791             :     }
+     792             :   }
+     793             : }
+     794             : 
+     795           0 : void EMMI::read_status()
+     796             : {
+     797             :   double MDtime;
+     798             : // open file
+     799             :   auto ifile = Tools::make_unique<IFile>();
+     800           0 :   ifile->link(*this);
+     801           0 :   if(ifile->FileExist(statusfilename_)) {
+     802           0 :     ifile->open(statusfilename_);
+     803           0 :     while(ifile->scanField("MD_time", MDtime)) {
+     804           0 :       for(unsigned i=0; i<sigma_.size(); ++i) {
+     805             :         // convert i to std::string
+     806           0 :         std::string num; Tools::convert(i,num);
+     807             :         // read entries
+     808           0 :         ifile->scanField("s"+num, sigma_[i]);
+     809             :       }
+     810             :       // new line
+     811           0 :       ifile->scanField();
+     812             :     }
+     813           0 :     ifile->close();
+     814             :   } else {
+     815           0 :     error("Cannot find status file "+statusfilename_+"\n");
+     816             :   }
+     817           0 : }
+     818             : 
+     819       10904 : void EMMI::print_status(long long int step)
+     820             : {
+     821             : // if first time open the file
+     822       10904 :   if(first_status_) {
+     823          14 :     first_status_ = false;
+     824          14 :     statusfile_.link(*this);
+     825          14 :     statusfile_.open(statusfilename_);
+     826             :     statusfile_.setHeavyFlush();
+     827          28 :     statusfile_.fmtField("%6.3e ");
+     828             :   }
+     829             : // write fields
+     830       10904 :   double MDtime = static_cast<double>(step)*getTimeStep();
+     831       10904 :   statusfile_.printField("MD_time", MDtime);
+     832       21808 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+     833             :     // convert i to std::string
+     834       10904 :     std::string num; Tools::convert(i,num);
+     835             :     // print entry
+     836       21808 :     statusfile_.printField("s"+num, sigma_[i]);
+     837             :   }
+     838       10904 :   statusfile_.printField();
+     839       10904 : }
+     840             : 
+     841           0 : bool EMMI::doAccept(double oldE, double newE, double kbt) {
+     842             :   bool accept = false;
+     843             :   // calculate delta energy
+     844           0 :   double delta = ( newE - oldE ) / kbt;
+     845             :   // if delta is negative always accept move
+     846           0 :   if( delta < 0.0 ) {
+     847             :     accept = true;
+     848             :   } else {
+     849             :     // otherwise extract random number
+     850           0 :     double s = random_.RandU01();
+     851           0 :     if( s < std::exp(-delta) ) { accept = true; }
+     852             :   }
+     853           0 :   return accept;
+     854             : }
+     855             : 
+     856           0 : void EMMI::doMonteCarlo()
+     857             : {
+     858             :   // extract random GMM group
+     859           0 :   unsigned nGMM = static_cast<unsigned>(std::floor(random_.RandU01()*static_cast<double>(GMM_d_grps_.size())));
+     860           0 :   if(nGMM==GMM_d_grps_.size()) nGMM -= 1;
+     861             : 
+     862             :   // generate random move
+     863           0 :   double shift = dsigma_[nGMM] * ( 2.0 * random_.RandU01() - 1.0 );
+     864             :   // new sigma
+     865           0 :   double new_s = sigma_[nGMM] + shift;
+     866             :   // check boundaries
+     867           0 :   if(new_s > sigma_max_[nGMM]) {new_s = 2.0 * sigma_max_[nGMM] - new_s;}
+     868           0 :   if(new_s < sigma_min_[nGMM]) {new_s = 2.0 * sigma_min_[nGMM] - new_s;}
+     869             :   // old s2
+     870           0 :   double old_inv_s2 = 1.0 / sigma_[nGMM] / sigma_[nGMM];
+     871             :   // new s2
+     872           0 :   double new_inv_s2 = 1.0 / new_s / new_s;
+     873             : 
+     874             :   // cycle on GMM group and calculate old and new energy
+     875             :   double old_ene = 0.0;
+     876             :   double new_ene = 0.0;
+     877           0 :   double ng = static_cast<double>(GMM_d_grps_[nGMM].size());
+     878             : 
+     879             :   // in case of Gaussian noise
+     880           0 :   if(noise_==0) {
+     881             :     double chi2 = 0.0;
+     882           0 :     for(unsigned i=0; i<GMM_d_grps_[nGMM].size(); ++i) {
+     883             :       // id GMM component
+     884           0 :       int GMMid = GMM_d_grps_[nGMM][i];
+     885             :       // deviation
+     886           0 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] );
+     887             :       // add to chi2
+     888           0 :       chi2 += dev * dev;
+     889             :     }
+     890             :     // final energy calculation: add normalization and prior
+     891           0 :     old_ene = 0.5 * kbt_ * ( chi2 * old_inv_s2 - (ng+prior_) * std::log(old_inv_s2) );
+     892           0 :     new_ene = 0.5 * kbt_ * ( chi2 * new_inv_s2 - (ng+prior_) * std::log(new_inv_s2) );
+     893             :   }
+     894             : 
+     895             :   // in case of Outliers noise
+     896           0 :   if(noise_==1) {
+     897           0 :     for(unsigned i=0; i<GMM_d_grps_[nGMM].size(); ++i) {
+     898             :       // id GMM component
+     899           0 :       int GMMid = GMM_d_grps_[nGMM][i];
+     900             :       // calculate deviation
+     901           0 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] );
+     902             :       // add to energies
+     903           0 :       old_ene += std::log1p( 0.5 * dev * dev * old_inv_s2);
+     904           0 :       new_ene += std::log1p( 0.5 * dev * dev * new_inv_s2);
+     905             :     }
+     906             :     // final energy calculation: add normalization and prior
+     907           0 :     old_ene = kbt_ * ( old_ene + (ng+prior_) * std::log(sigma_[nGMM]) );
+     908           0 :     new_ene = kbt_ * ( new_ene + (ng+prior_) * std::log(new_s) );
+     909             :   }
+     910             : 
+     911             :   // increment number of trials
+     912           0 :   MCtrials_ += 1.0;
+     913             : 
+     914             :   // accept or reject
+     915           0 :   bool accept = doAccept(old_ene/anneal_, new_ene/anneal_, kbt_);
+     916           0 :   if(accept) {
+     917           0 :     sigma_[nGMM] = new_s;
+     918           0 :     MCaccept_ += 1.0;
+     919             :   }
+     920             :   // local communication
+     921           0 :   if(rank_!=0) {
+     922           0 :     for(unsigned i=0; i<sigma_.size(); ++i) sigma_[i] = 0.0;
+     923           0 :     MCaccept_ = 0.0;
+     924             :   }
+     925           0 :   if(size_>1) {
+     926           0 :     comm.Sum(&sigma_[0], sigma_.size());
+     927           0 :     comm.Sum(&MCaccept_, 1);
+     928             :   }
+     929             : 
+     930             :   // update sigma output
+     931           0 :   std::string num; Tools::convert(nGMM, num);
+     932           0 :   getPntrToComponent("sigma-"+num)->set(sigma_[nGMM]);
+     933           0 : }
+     934             : 
+     935           0 : std::vector<double> EMMI::read_exp_errors(const std::string & errfile)
+     936             : {
+     937             :   int nexp, idcomp;
+     938             :   double err;
+     939             :   std::vector<double> exp_err;
+     940             : // open file
+     941           0 :   IFile *ifile = new IFile();
+     942           0 :   if(ifile->FileExist(errfile)) {
+     943           0 :     ifile->open(errfile);
+     944             :     // scan for number of experimental errors
+     945           0 :     ifile->scanField("Nexp", nexp);
+     946             :     // cycle on GMM components
+     947           0 :     while(ifile->scanField("Id",idcomp)) {
+     948             :       // total experimental error
+     949           0 :       double err_tot = 0.0;
+     950             :       // cycle on number of experimental overlaps
+     951           0 :       for(unsigned i=0; i<nexp; ++i) {
+     952           0 :         std::string ss; Tools::convert(i,ss);
+     953           0 :         ifile->scanField("Err"+ss, err);
+     954             :         // add to total error
+     955           0 :         err_tot += err*err;
+     956             :       }
+     957             :       // new line
+     958           0 :       ifile->scanField();
+     959             :       // calculate RMSE
+     960           0 :       err_tot = std::sqrt(err_tot/static_cast<double>(nexp));
+     961             :       // add to global
+     962           0 :       exp_err.push_back(err_tot);
+     963             :     }
+     964           0 :     ifile->close();
+     965             :   } else {
+     966           0 :     error("Cannot find ERR_FILE "+errfile+"\n");
+     967             :   }
+     968           0 :   return exp_err;
+     969             : }
+     970             : 
+     971           0 : std::vector<double> EMMI::read_exp_overlaps(const std::string & ovfile)
+     972             : {
+     973             :   int idcomp;
+     974             :   double ov;
+     975             :   std::vector<double> ovdd;
+     976             : // open file
+     977           0 :   IFile *ifile = new IFile();
+     978           0 :   if(ifile->FileExist(ovfile)) {
+     979           0 :     ifile->open(ovfile);
+     980             :     // cycle on GMM components
+     981           0 :     while(ifile->scanField("Id",idcomp)) {
+     982             :       // read experimental overlap
+     983           0 :       ifile->scanField("Overlap", ov);
+     984             :       // add to ovdd
+     985           0 :       ovdd.push_back(ov);
+     986             :       // new line
+     987           0 :       ifile->scanField();
+     988             :     }
+     989           0 :     ifile->close();
+     990             :   } else {
+     991           0 :     error("Cannot find OV_FILE "+ovfile+"\n");
+     992             :   }
+     993           0 :   return ovdd;
+     994             : }
+     995             : 
+     996          20 : std::vector<double> EMMI::get_GMM_m(std::vector<AtomNumber> &atoms)
+     997             : {
+     998             :   // list of weights - one per atom
+     999             :   std::vector<double> GMM_m_w;
+    1000             : 
+    1001          20 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    1002             :   // map of atom types to A and B coefficients of scattering factor
+    1003             :   // f(s) = A * exp(-B*s**2)
+    1004             :   // B is in Angstrom squared
+    1005             :   // map between an atom type and an index
+    1006             :   std::map<std::string, unsigned> type_map;
+    1007          20 :   type_map["C"]=0;
+    1008          20 :   type_map["O"]=1;
+    1009          20 :   type_map["N"]=2;
+    1010          20 :   type_map["S"]=3;
+    1011             :   // fill in sigma std::vector
+    1012          20 :   GMM_m_s_.push_back(0.01*15.146);  // type 0
+    1013          20 :   GMM_m_s_.push_back(0.01*8.59722); // type 1
+    1014          20 :   GMM_m_s_.push_back(0.01*11.1116); // type 2
+    1015          20 :   GMM_m_s_.push_back(0.01*15.8952); // type 3
+    1016             :   // fill in weight std::vector
+    1017          20 :   GMM_m_w_.push_back(2.49982); // type 0
+    1018          20 :   GMM_m_w_.push_back(1.97692); // type 1
+    1019          20 :   GMM_m_w_.push_back(2.20402); // type 2
+    1020          20 :   GMM_m_w_.push_back(5.14099); // type 3
+    1021             : 
+    1022             :   // check if MOLINFO line is present
+    1023          20 :   if( moldat ) {
+    1024          20 :     log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+    1025       10876 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    1026             :       // get atom name
+    1027       10856 :       std::string name = moldat->getAtomName(atoms[i]);
+    1028             :       char type;
+    1029             :       // get atom type
+    1030       10856 :       char first = name.at(0);
+    1031             :       // GOLDEN RULE: type is first letter, if not a number
+    1032       10856 :       if (!isdigit(first)) {
+    1033             :         type = first;
+    1034             :         // otherwise is the second
+    1035             :       } else {
+    1036           0 :         type = name.at(1);
+    1037             :       }
+    1038             :       // check if key in map
+    1039       10856 :       std::string type_s = std::string(1,type);
+    1040       10856 :       if(type_map.find(type_s) != type_map.end()) {
+    1041             :         // save atom type
+    1042       10856 :         GMM_m_type_.push_back(type_map[type_s]);
+    1043             :         // this will be normalized in the final density
+    1044       10856 :         GMM_m_w.push_back(GMM_m_w_[type_map[type_s]]);
+    1045             :       } else {
+    1046           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    1047             :       }
+    1048             :     }
+    1049             :   } else {
+    1050           0 :     error("MOLINFO DATA not found\n");
+    1051             :   }
+    1052          20 :   return GMM_m_w;
+    1053             : }
+    1054             : 
+    1055        1962 : void EMMI::check_GMM_d(const VectorGeneric<6> &cov, double w)
+    1056             : {
+    1057             : 
+    1058             : // check if positive defined, by calculating the 3 leading principal minors
+    1059        1962 :   double pm1 = cov[0];
+    1060        1962 :   double pm2 = cov[0]*cov[3]-cov[1]*cov[1];
+    1061        1962 :   double pm3 = cov[0]*(cov[3]*cov[5]-cov[4]*cov[4])-cov[1]*(cov[1]*cov[5]-cov[4]*cov[2])+cov[2]*(cov[1]*cov[4]-cov[3]*cov[2]);
+    1062             : // apply Sylvester’s criterion
+    1063        1962 :   if(pm1<=0.0 || pm2<=0.0 || pm3<=0.0)
+    1064           0 :     error("check data GMM: covariance matrix is not positive defined");
+    1065             : 
+    1066             : // check if weight is positive
+    1067        1962 :   if(w<=0) error("check data GMM: weight must be positive");
+    1068        1962 : }
+    1069             : 
+    1070             : // read GMM data file in PLUMED format:
+    1071          20 : void EMMI::get_GMM_d(const std::string & GMM_file)
+    1072             : {
+    1073          20 :   VectorGeneric<6> cov;
+    1074             : 
+    1075             : // open file
+    1076             :   auto ifile=Tools::make_unique<IFile>();
+    1077          20 :   if(ifile->FileExist(GMM_file)) {
+    1078          20 :     ifile->open(GMM_file);
+    1079             :     int idcomp;
+    1080        3964 :     while(ifile->scanField("Id",idcomp)) {
+    1081             :       int beta;
+    1082             :       double w, m0, m1, m2;
+    1083        3924 :       ifile->scanField("Weight",w);
+    1084        3924 :       ifile->scanField("Mean_0",m0);
+    1085        3924 :       ifile->scanField("Mean_1",m1);
+    1086        3924 :       ifile->scanField("Mean_2",m2);
+    1087        3924 :       ifile->scanField("Cov_00",cov[0]);
+    1088        3924 :       ifile->scanField("Cov_01",cov[1]);
+    1089        3924 :       ifile->scanField("Cov_02",cov[2]);
+    1090        3924 :       ifile->scanField("Cov_11",cov[3]);
+    1091        3924 :       ifile->scanField("Cov_12",cov[4]);
+    1092        3924 :       ifile->scanField("Cov_22",cov[5]);
+    1093        1962 :       ifile->scanField("Beta",beta);
+    1094             :       // check input
+    1095        1962 :       check_GMM_d(cov, w);
+    1096             :       // check beta
+    1097        1962 :       if(beta<0) error("Beta must be positive!");
+    1098             :       // center of the Gaussian
+    1099        1962 :       GMM_d_m_.push_back(Vector(m0,m1,m2));
+    1100             :       // covariance matrix
+    1101        1962 :       GMM_d_cov_.push_back(cov);
+    1102             :       // weight
+    1103        1962 :       GMM_d_w_.push_back(w);
+    1104             :       // beta
+    1105        1962 :       GMM_d_beta_.push_back(beta);
+    1106             :       // new line
+    1107        1962 :       ifile->scanField();
+    1108             :     }
+    1109             :   } else {
+    1110           0 :     error("Cannot find GMM_FILE "+GMM_file+"\n");
+    1111             :   }
+    1112             :   // now create a set from beta (unique set of values)
+    1113          20 :   std::set<int> bu(GMM_d_beta_.begin(), GMM_d_beta_.end());
+    1114             :   // now prepare the group std::vector
+    1115          20 :   GMM_d_grps_.resize(bu.size());
+    1116             :   // and fill it in
+    1117        1982 :   for(unsigned i=0; i<GMM_d_beta_.size(); ++i) {
+    1118        1962 :     if(GMM_d_beta_[i]>=GMM_d_grps_.size()) error("Check Beta values");
+    1119        1962 :     GMM_d_grps_[GMM_d_beta_[i]].push_back(i);
+    1120             :   }
+    1121          20 : }
+    1122             : 
+    1123          20 : void EMMI::calculate_useful_stuff(double reso)
+    1124             : {
+    1125             :   // We use the following definition for resolution:
+    1126             :   // the Fourier transform of the density distribution in real space
+    1127             :   // f(s) falls to 1/e of its maximum value at wavenumber 1/resolution
+    1128             :   // i.e. from f(s) = A * exp(-B*s**2) -> Res = std::sqrt(B).
+    1129             :   // average value of B
+    1130             :   double Bave = 0.0;
+    1131       10876 :   for(unsigned i=0; i<GMM_m_type_.size(); ++i) {
+    1132       10856 :     Bave += GMM_m_s_[GMM_m_type_[i]];
+    1133             :   }
+    1134          20 :   Bave /= static_cast<double>(GMM_m_type_.size());
+    1135             :   // calculate blur factor
+    1136             :   double blur = 0.0;
+    1137          20 :   if(reso*reso>Bave) blur = reso*reso-Bave;
+    1138          36 :   else warning("PLUMED should not be used with maps at resolution better than 0.3 nm");
+    1139             :   // add blur to B
+    1140         100 :   for(unsigned i=0; i<GMM_m_s_.size(); ++i) GMM_m_s_[i] += blur;
+    1141             :   // calculate average resolution
+    1142             :   double ave_res = 0.0;
+    1143       10876 :   for(unsigned i=0; i<GMM_m_type_.size(); ++i) {
+    1144       10856 :     ave_res += std::sqrt(GMM_m_s_[GMM_m_type_[i]]);
+    1145             :   }
+    1146          20 :   ave_res = ave_res / static_cast<double>(GMM_m_type_.size());
+    1147          20 :   log.printf("  experimental map resolution : %3.2f\n", reso);
+    1148          20 :   log.printf("  predicted map resolution : %3.2f\n", ave_res);
+    1149          20 :   log.printf("  blur factor : %f\n", blur);
+    1150             :   // now calculate useful stuff
+    1151          20 :   VectorGeneric<6> cov, sum, inv_sum;
+    1152             :   // cycle on all atoms types (4 for the moment)
+    1153         100 :   for(unsigned i=0; i<GMM_m_s_.size(); ++i) {
+    1154             :     // the Gaussian in density (real) space is the FT of scattering factor
+    1155             :     // f(r) = A * (pi/B)**1.5 * exp(-pi**2/B*r**2)
+    1156          80 :     double s = std::sqrt ( 0.5 * GMM_m_s_[i] ) / pi;
+    1157             :     // covariance matrix for spherical Gaussian
+    1158          80 :     cov[0]=s*s; cov[1]=0.0; cov[2]=0.0;
+    1159          80 :     cov[3]=s*s; cov[4]=0.0;
+    1160          80 :     cov[5]=s*s;
+    1161             :     // cycle on all data GMM
+    1162        7928 :     for(unsigned j=0; j<GMM_d_m_.size(); ++j) {
+    1163             :       // we need the sum of the covariance matrices
+    1164       54936 :       for(unsigned k=0; k<6; ++k) sum[k] = cov[k] + GMM_d_cov_[j][k];
+    1165             :       // and to calculate its determinant
+    1166        7848 :       double det = sum[0]*(sum[3]*sum[5]-sum[4]*sum[4]);
+    1167        7848 :       det -= sum[1]*(sum[1]*sum[5]-sum[4]*sum[2]);
+    1168        7848 :       det += sum[2]*(sum[1]*sum[4]-sum[3]*sum[2]);
+    1169             :       // calculate prefactor - model weights are already normalized
+    1170        7848 :       double pre_fact =  cfact_ / std::sqrt(det) * GMM_d_w_[j] * GMM_m_w_[i];
+    1171             :       // and its inverse
+    1172        7848 :       inv_sum[0] = (sum[3]*sum[5] - sum[4]*sum[4])/det;
+    1173        7848 :       inv_sum[1] = (sum[2]*sum[4] - sum[1]*sum[5])/det;
+    1174        7848 :       inv_sum[2] = (sum[1]*sum[4] - sum[2]*sum[3])/det;
+    1175        7848 :       inv_sum[3] = (sum[0]*sum[5] - sum[2]*sum[2])/det;
+    1176        7848 :       inv_sum[4] = (sum[2]*sum[1] - sum[0]*sum[4])/det;
+    1177        7848 :       inv_sum[5] = (sum[0]*sum[3] - sum[1]*sum[1])/det;
+    1178             :       // now we store the prefactor
+    1179        7848 :       pre_fact_.push_back(pre_fact);
+    1180             :       // and the inverse of the sum
+    1181        7848 :       inv_cov_md_.push_back(inv_sum);
+    1182             :     }
+    1183             :   }
+    1184             :   // tabulate exponential
+    1185          20 :   dexp_ = dpcutoff_ / static_cast<double> (nexp_-1);
+    1186    20000020 :   for(unsigned i=0; i<nexp_; ++i) {
+    1187    20000000 :     tab_exp_.push_back(std::exp(-static_cast<double>(i) * dexp_));
+    1188             :   }
+    1189          20 : }
+    1190             : 
+    1191             : // get prefactors
+    1192     1621458 : double EMMI::get_prefactor_inverse
+    1193             : (const VectorGeneric<6> &GMM_cov_0, const VectorGeneric<6> &GMM_cov_1,
+    1194             :  double GMM_w_0, double GMM_w_1,
+    1195             :  VectorGeneric<6> &sum, VectorGeneric<6> &inv_sum)
+    1196             : {
+    1197             : // we need the sum of the covariance matrices
+    1198    11350206 :   for(unsigned k=0; k<6; ++k) sum[k] = GMM_cov_0[k] + GMM_cov_1[k];
+    1199             : 
+    1200             : // and to calculate its determinant
+    1201     1621458 :   double det = sum[0]*(sum[3]*sum[5]-sum[4]*sum[4]);
+    1202     1621458 :   det -= sum[1]*(sum[1]*sum[5]-sum[4]*sum[2]);
+    1203     1621458 :   det += sum[2]*(sum[1]*sum[4]-sum[3]*sum[2]);
+    1204             : 
+    1205             : // the prefactor is
+    1206     1621458 :   double pre_fact =  cfact_ / std::sqrt(det) * GMM_w_0 * GMM_w_1;
+    1207             : 
+    1208             : // and its inverse
+    1209     1621458 :   inv_sum[0] = (sum[3]*sum[5] - sum[4]*sum[4])/det;
+    1210     1621458 :   inv_sum[1] = (sum[2]*sum[4] - sum[1]*sum[5])/det;
+    1211     1621458 :   inv_sum[2] = (sum[1]*sum[4] - sum[2]*sum[3])/det;
+    1212     1621458 :   inv_sum[3] = (sum[0]*sum[5] - sum[2]*sum[2])/det;
+    1213     1621458 :   inv_sum[4] = (sum[2]*sum[1] - sum[0]*sum[4])/det;
+    1214     1621458 :   inv_sum[5] = (sum[0]*sum[3] - sum[1]*sum[1])/det;
+    1215             : 
+    1216             : // return pre-factor
+    1217     1621458 :   return pre_fact;
+    1218             : }
+    1219             : 
+    1220        1962 : double EMMI::get_self_overlap(unsigned id)
+    1221             : {
+    1222             :   double ov_tot = 0.0;
+    1223        1962 :   VectorGeneric<6> sum, inv_sum;
+    1224        1962 :   Vector ov_der;
+    1225             : // start loop
+    1226     1623420 :   for(unsigned i=0; i<GMM_d_m_.size(); ++i) {
+    1227             :     // call auxiliary method
+    1228     1621458 :     double pre_fact = get_prefactor_inverse(GMM_d_cov_[id], GMM_d_cov_[i],
+    1229     1621458 :                                             GMM_d_w_[id],   GMM_d_w_[i], sum, inv_sum);
+    1230             :     // add overlap to ov_tot
+    1231     1621458 :     ov_tot += get_overlap(GMM_d_m_[id], GMM_d_m_[i], pre_fact, inv_sum, ov_der);
+    1232             :   }
+    1233             : // and return it
+    1234        1962 :   return ov_tot;
+    1235             : }
+    1236             : 
+    1237             : // get overlap and derivatives
+    1238     3732816 : double EMMI::get_overlap(const Vector &m_m, const Vector &d_m, double pre_fact,
+    1239             :                          const VectorGeneric<6> &inv_cov_md, Vector &ov_der)
+    1240             : {
+    1241     3732816 :   Vector md;
+    1242             :   // calculate std::vector difference m_m-d_m with/without pbc
+    1243     3732816 :   if(pbc_) md = pbcDistance(d_m, m_m);
+    1244     3732816 :   else     md = delta(d_m, m_m);
+    1245             :   // calculate product of transpose of md and inv_cov_md
+    1246     3732816 :   double p_x = md[0]*inv_cov_md[0]+md[1]*inv_cov_md[1]+md[2]*inv_cov_md[2];
+    1247     3732816 :   double p_y = md[0]*inv_cov_md[1]+md[1]*inv_cov_md[3]+md[2]*inv_cov_md[4];
+    1248     3732816 :   double p_z = md[0]*inv_cov_md[2]+md[1]*inv_cov_md[4]+md[2]*inv_cov_md[5];
+    1249             :   // calculate product of prod and md
+    1250     3732816 :   double ov = md[0]*p_x+md[1]*p_y+md[2]*p_z;
+    1251             :   // final calculation
+    1252     3732816 :   ov = pre_fact * std::exp(-0.5*ov);
+    1253             :   // derivatives
+    1254     3732816 :   ov_der = ov * Vector(p_x, p_y, p_z);
+    1255     3732816 :   return ov;
+    1256             : }
+    1257             : 
+    1258             : // get the exponent of the overlap
+    1259    59085036 : double EMMI::get_exp_overlap(const Vector &m_m, const Vector &d_m,
+    1260             :                              const VectorGeneric<6> &inv_cov_md)
+    1261             : {
+    1262    59085036 :   Vector md;
+    1263             :   // calculate std::vector difference m_m-d_m with/without pbc
+    1264    59085036 :   if(pbc_) md = pbcDistance(d_m, m_m);
+    1265    59085036 :   else     md = delta(d_m, m_m);
+    1266             :   // calculate product of transpose of md and inv_cov_md
+    1267    59085036 :   double p_x = md[0]*inv_cov_md[0]+md[1]*inv_cov_md[1]+md[2]*inv_cov_md[2];
+    1268    59085036 :   double p_y = md[0]*inv_cov_md[1]+md[1]*inv_cov_md[3]+md[2]*inv_cov_md[4];
+    1269    59085036 :   double p_z = md[0]*inv_cov_md[2]+md[1]*inv_cov_md[4]+md[2]*inv_cov_md[5];
+    1270             :   // calculate product of prod and md
+    1271    59085036 :   double ov = md[0]*p_x+md[1]*p_y+md[2]*p_z;
+    1272    59085036 :   return ov;
+    1273             : }
+    1274             : 
+    1275       16355 : void EMMI::update_neighbor_list()
+    1276             : {
+    1277             :   // dimension of GMM and atom std::vectors
+    1278       16355 :   unsigned GMM_d_size = GMM_d_m_.size();
+    1279       16355 :   unsigned GMM_m_size = GMM_m_type_.size();
+    1280             :   // local neighbor list
+    1281             :   std::vector < unsigned > nl_l;
+    1282             :   // clear old neighbor list
+    1283       16355 :   nl_.clear();
+    1284             : 
+    1285             :   // cycle on GMM components - in parallel
+    1286      116273 :   for(unsigned id=rank_; id<GMM_d_size; id+=size_) {
+    1287             :     // overlap lists and map
+    1288             :     std::vector<double> ov_l;
+    1289             :     std::map<double, unsigned> ov_m;
+    1290             :     // total overlap with id
+    1291             :     double ov_tot = 0.0;
+    1292             :     // cycle on all atoms
+    1293    59184954 :     for(unsigned im=0; im<GMM_m_size; ++im) {
+    1294             :       // get index in auxiliary lists
+    1295    59085036 :       unsigned kaux = GMM_m_type_[im] * GMM_d_size + id;
+    1296             :       // calculate exponent of overlap
+    1297    59085036 :       double expov = get_exp_overlap(GMM_d_m_[id], getPosition(im), inv_cov_md_[kaux]);
+    1298             :       // get index of 0.5*expov in tabulated exponential
+    1299    59085036 :       unsigned itab = static_cast<unsigned> (round( 0.5*expov/dexp_ ));
+    1300             :       // check boundaries and skip atom in case
+    1301    59085036 :       if(itab >= tab_exp_.size()) continue;
+    1302             :       // in case calculate overlap
+    1303     4133388 :       double ov = pre_fact_[kaux] * tab_exp_[itab];
+    1304             :       // add to list
+    1305     4133388 :       ov_l.push_back(ov);
+    1306             :       // and map to retrieve atom index
+    1307     4133388 :       ov_m[ov] = im;
+    1308             :       // increase ov_tot
+    1309     4133388 :       ov_tot += ov;
+    1310             :     }
+    1311             :     // check if zero size -> ov_tot = 0
+    1312       99918 :     if(ov_l.size()==0) continue;
+    1313             :     // define cutoff
+    1314       99842 :     double ov_cut = ov_tot * nl_cutoff_;
+    1315             :     // sort ov_l in ascending order
+    1316       99842 :     std::sort(ov_l.begin(), ov_l.end());
+    1317             :     // integrate ov_l
+    1318             :     double res = 0.0;
+    1319     2146102 :     for(unsigned i=0; i<ov_l.size(); ++i) {
+    1320     2146102 :       res += ov_l[i];
+    1321             :       // if exceeding the cutoff for overlap, stop
+    1322     2146102 :       if(res >= ov_cut) break;
+    1323             :       else ov_m.erase(ov_l[i]);
+    1324             :     }
+    1325             :     // now add atoms to neighborlist
+    1326     2186970 :     for(std::map<double, unsigned>::iterator it=ov_m.begin(); it!=ov_m.end(); ++it)
+    1327     2087128 :       nl_l.push_back(id*GMM_m_size+it->second);
+    1328             :     // end cycle on GMM components in parallel
+    1329             :   }
+    1330             :   // find total dimension of neighborlist
+    1331       16355 :   std::vector <int> recvcounts(size_, 0);
+    1332       16355 :   recvcounts[rank_] = nl_l.size();
+    1333       16355 :   comm.Sum(&recvcounts[0], size_);
+    1334             :   int tot_size = accumulate(recvcounts.begin(), recvcounts.end(), 0);
+    1335             :   // resize neighbor stuff
+    1336       16355 :   nl_.resize(tot_size);
+    1337             :   // calculate std::vector of displacement
+    1338       16355 :   std::vector<int> disp(size_);
+    1339       16355 :   disp[0] = 0;
+    1340             :   int rank_size = 0;
+    1341       27257 :   for(unsigned i=0; i<size_-1; ++i) {
+    1342       10902 :     rank_size += recvcounts[i];
+    1343       10902 :     disp[i+1] = rank_size;
+    1344             :   }
+    1345             :   // Allgather neighbor list
+    1346       16355 :   comm.Allgatherv(&nl_l[0], recvcounts[rank_], &nl_[0], &recvcounts[0], &disp[0]);
+    1347             :   // now resize derivatives
+    1348       16355 :   ovmd_der_.resize(tot_size);
+    1349       16355 : }
+    1350             : 
+    1351          30 : void EMMI::prepare()
+    1352             : {
+    1353          30 :   if(getExchangeStep()) first_time_=true;
+    1354          30 : }
+    1355             : 
+    1356             : // overlap calculator
+    1357       16365 : void EMMI::calculate_overlap() {
+    1358             : 
+    1359       16365 :   if(first_time_ || getExchangeStep() || getStep()%nl_stride_==0) {
+    1360       16355 :     update_neighbor_list();
+    1361       16355 :     first_time_=false;
+    1362             :   }
+    1363             : 
+    1364             :   // clean temporary std::vectors
+    1365      174342 :   for(unsigned i=0; i<ovmd_.size(); ++i)     ovmd_[i] = 0.0;
+    1366     3168864 :   for(unsigned i=0; i<ovmd_der_.size(); ++i) ovmd_der_[i] = Vector(0,0,0);
+    1367             : 
+    1368             :   // we have to cycle over all model and data GMM components in the neighbor list
+    1369       16365 :   unsigned GMM_d_size = GMM_d_m_.size();
+    1370       16365 :   unsigned GMM_m_size = GMM_m_type_.size();
+    1371     2127723 :   for(unsigned i=rank_; i<nl_.size(); i=i+size_) {
+    1372             :     // get data (id) and atom (im) indexes
+    1373     2111358 :     unsigned id = nl_[i] / GMM_m_size;
+    1374     2111358 :     unsigned im = nl_[i] % GMM_m_size;
+    1375             :     // get index in auxiliary lists
+    1376     2111358 :     unsigned kaux = GMM_m_type_[im] * GMM_d_size + id;
+    1377             :     // add overlap with im component of model GMM
+    1378     2111358 :     ovmd_[id] += get_overlap(GMM_d_m_[id], getPosition(im), pre_fact_[kaux],
+    1379     2111358 :                              inv_cov_md_[kaux], ovmd_der_[i]);
+    1380             :   }
+    1381             :   // communicate stuff
+    1382       16365 :   if(size_>1) {
+    1383       10902 :     comm.Sum(&ovmd_[0], ovmd_.size());
+    1384       10902 :     comm.Sum(&ovmd_der_[0][0], 3*ovmd_der_.size());
+    1385             :   }
+    1386       16365 : }
+    1387             : 
+    1388           0 : double EMMI::scaleEnergy(double s)
+    1389             : {
+    1390             :   double ene = 0.0;
+    1391           0 :   for(unsigned i=0; i<ovdd_.size(); ++i) {
+    1392           0 :     ene += std::log( abs ( s * ovmd_ave_[i] - ovdd_[i] ) );
+    1393             :   }
+    1394           0 :   return ene;
+    1395             : }
+    1396             : 
+    1397           0 : double EMMI::doRegression()
+    1398             : {
+    1399             : // standard MC parameters
+    1400             :   unsigned MCsteps = 100000;
+    1401             :   double kbtmin = 1.0;
+    1402             :   double kbtmax = 10.0;
+    1403             :   unsigned ncold = 5000;
+    1404             :   unsigned nhot = 2000;
+    1405             :   double MCacc = 0.0;
+    1406             :   double kbt, ebest, scale_best;
+    1407             : 
+    1408             : // initial value of scale factor and energy
+    1409           0 :   double scale = random_.RandU01() * ( scale_max_ - scale_min_ ) + scale_min_;
+    1410           0 :   double ene = scaleEnergy(scale);
+    1411             : // set best energy
+    1412           0 :   ebest = ene;
+    1413             : 
+    1414             : // MC loop
+    1415           0 :   for(unsigned istep=0; istep<MCsteps; ++istep) {
+    1416             :     // get temperature
+    1417           0 :     if(istep%(ncold+nhot)<ncold) kbt = kbtmin;
+    1418             :     else kbt = kbtmax;
+    1419             :     // propose move in scale
+    1420           0 :     double ds = dscale_ * ( 2.0 * random_.RandU01() - 1.0 );
+    1421           0 :     double new_scale = scale + ds;
+    1422             :     // check boundaries
+    1423           0 :     if(new_scale > scale_max_) {new_scale = 2.0 * scale_max_ - new_scale;}
+    1424           0 :     if(new_scale < scale_min_) {new_scale = 2.0 * scale_min_ - new_scale;}
+    1425             :     // new energy
+    1426           0 :     double new_ene = scaleEnergy(new_scale);
+    1427             :     // accept or reject
+    1428           0 :     bool accept = doAccept(ene, new_ene, kbt);
+    1429             :     // in case of acceptance
+    1430           0 :     if(accept) {
+    1431             :       scale = new_scale;
+    1432             :       ene = new_ene;
+    1433           0 :       MCacc += 1.0;
+    1434             :     }
+    1435             :     // save best
+    1436           0 :     if(ene<ebest) {
+    1437           0 :       ebest = ene;
+    1438           0 :       scale_best = scale;
+    1439             :     }
+    1440             :   }
+    1441             : // calculate acceptance
+    1442           0 :   double accscale = MCacc / static_cast<double>(MCsteps);
+    1443             : // global communication
+    1444           0 :   if(!no_aver_ && nrep_>1) {
+    1445           0 :     if(replica_!=0) {
+    1446           0 :       scale_best = 0.0;
+    1447           0 :       ebest = 0.0;
+    1448           0 :       accscale = 0.0;
+    1449             :     }
+    1450           0 :     if(rank_==0) {
+    1451           0 :       multi_sim_comm.Sum(&scale_best, 1);
+    1452           0 :       multi_sim_comm.Sum(&ebest, 1);
+    1453           0 :       multi_sim_comm.Sum(&accscale, 1);
+    1454             :     }
+    1455             :   }
+    1456             :   // local communication
+    1457           0 :   if(rank_!=0) {
+    1458           0 :     scale_best = 0.0;
+    1459           0 :     ebest = 0.0;
+    1460           0 :     accscale = 0.0;
+    1461             :   }
+    1462           0 :   if(size_>1) {
+    1463           0 :     comm.Sum(&scale_best, 1);
+    1464           0 :     comm.Sum(&ebest, 1);
+    1465           0 :     comm.Sum(&accscale, 1);
+    1466             :   }
+    1467             : // set scale parameters
+    1468           0 :   getPntrToComponent("accscale")->set(accscale);
+    1469           0 :   getPntrToComponent("enescale")->set(ebest);
+    1470             : // return scale value
+    1471           0 :   return scale_best;
+    1472             : }
+    1473             : 
+    1474           0 : double EMMI::get_annealing(long long int step)
+    1475             : {
+    1476             : // default no annealing
+    1477             :   double fact = 1.0;
+    1478             : // position in annealing cycle
+    1479           0 :   unsigned nc = step%(4*nanneal_);
+    1480             : // useful doubles
+    1481           0 :   double ncd = static_cast<double>(nc);
+    1482           0 :   double nn  = static_cast<double>(nanneal_);
+    1483             : // set fact
+    1484           0 :   if(nc>=nanneal_   && nc<2*nanneal_) fact = (kanneal_-1.0) / nn * ( ncd - nn ) + 1.0;
+    1485           0 :   if(nc>=2*nanneal_ && nc<3*nanneal_) fact = kanneal_;
+    1486           0 :   if(nc>=3*nanneal_)                  fact = (1.0-kanneal_) / nn * ( ncd - 3.0*nn) + kanneal_;
+    1487           0 :   return fact;
+    1488             : }
+    1489             : 
+    1490       16365 : void EMMI::get_weights(double &weight, double &norm, double &neff)
+    1491             : {
+    1492       16365 :   const double dnrep = static_cast<double>(nrep_);
+    1493             :   // calculate the weights either from BIAS
+    1494       16365 :   if(do_reweight_) {
+    1495          12 :     std::vector<double> bias(nrep_,0);
+    1496          12 :     if(rank_==0) {
+    1497          12 :       bias[replica_] = getArgument(0);
+    1498          12 :       if(nrep_>1) multi_sim_comm.Sum(&bias[0], nrep_);
+    1499             :     }
+    1500          12 :     comm.Sum(&bias[0], nrep_);
+    1501             : 
+    1502             :     // accumulate weights
+    1503          12 :     if(!first_time_w_) {
+    1504          30 :       for(unsigned i=0; i<nrep_; ++i) {
+    1505          20 :         const double delta=bias[i]-average_weights_[i];
+    1506             :         // FIXME: multiplying by fractional decay here causes problems with numerical derivatives,
+    1507             :         // probably because we're making several calls to calculate(), causing accumulation
+    1508             :         // of epsilons. Maybe we can work on a temporary copy of the action instead?
+    1509          20 :         average_weights_[i]+=decay_w_*delta;
+    1510             :       }
+    1511             :     } else {
+    1512           2 :       first_time_w_ = false;
+    1513           6 :       for(unsigned i=0; i<nrep_; ++i) average_weights_[i] = bias[i];
+    1514             :     }
+    1515             : 
+    1516             :     // set average back into bias and set norm to one
+    1517          12 :     const double maxbias = *(std::max_element(average_weights_.begin(), average_weights_.end()));
+    1518          36 :     for(unsigned i=0; i<nrep_; ++i) bias[i] = std::exp((average_weights_[i]-maxbias)/kbt_);
+    1519             :     // set local weight, norm and weight variance
+    1520          12 :     weight = bias[replica_];
+    1521             :     double w2=0.;
+    1522          36 :     for(unsigned i=0; i<nrep_; ++i) {
+    1523          24 :       w2 += bias[i]*bias[i];
+    1524          24 :       norm += bias[i];
+    1525             :     }
+    1526          12 :     neff = norm*norm/w2;
+    1527          24 :     getPntrToComponent("weight")->set(weight/norm);
+    1528             :   } else {
+    1529             :     // or arithmetic ones
+    1530       16353 :     neff = dnrep;
+    1531       16353 :     weight = 1.0;
+    1532       16353 :     norm = dnrep;
+    1533             :   }
+    1534       16365 :   getPntrToComponent("neff")->set(neff);
+    1535       16365 : }
+    1536             : 
+    1537       16365 : void EMMI::calculate()
+    1538             : {
+    1539             : 
+    1540             : // calculate CV
+    1541       16365 :   calculate_overlap();
+    1542             : 
+    1543             :   // rescale factor for ensemble average
+    1544       16365 :   double weight = 0.;
+    1545       16365 :   double neff = 0.;
+    1546       16365 :   double norm = 0.;
+    1547       16365 :   get_weights(weight, norm, neff);
+    1548             : 
+    1549             :   // in case of ensemble averaging, calculate average overlap
+    1550       16365 :   if(!no_aver_ && nrep_>1) {
+    1551             :     // if master node, calculate average across replicas
+    1552          12 :     if(rank_==0) {
+    1553       10812 :       for(unsigned i=0; i<ovmd_.size(); ++i) ovmd_ave_[i] = weight / norm * ovmd_[i];
+    1554          12 :       multi_sim_comm.Sum(&ovmd_ave_[0], ovmd_ave_.size());
+    1555             :     } else {
+    1556           0 :       for(unsigned i=0; i<ovmd_ave_.size(); ++i) ovmd_ave_[i] = 0.0;
+    1557             :     }
+    1558             :     // local communication
+    1559          12 :     if(size_>1) comm.Sum(&ovmd_ave_[0], ovmd_ave_.size());
+    1560             :   } else {
+    1561      163530 :     for(unsigned i=0; i<ovmd_.size(); ++i) ovmd_ave_[i] = ovmd_[i];
+    1562             :   }
+    1563             : 
+    1564             :   // get time step
+    1565       16365 :   long long int step = getStep();
+    1566             : 
+    1567             :   // do regression
+    1568       16365 :   if(nregres_>0) {
+    1569           0 :     if(step%nregres_==0 && !getExchangeStep()) scale_ = doRegression();
+    1570             :     // set scale component
+    1571           0 :     getPntrToComponent("scale")->set(scale_);
+    1572             :   }
+    1573             : 
+    1574             :   // write model overlap to file
+    1575       16365 :   if(ovstride_>0 && step%ovstride_==0) write_model_overlap(step);
+    1576             : 
+    1577             :   // clear energy and virial
+    1578       16365 :   ene_ = 0.0;
+    1579       16365 :   virial_.zero();
+    1580             : 
+    1581             :   // Gaussian noise
+    1582       16365 :   if(noise_==0) calculate_Gauss();
+    1583             : 
+    1584             :   // Outliers noise
+    1585       16365 :   if(noise_==1) calculate_Outliers();
+    1586             : 
+    1587             :   // Marginal noise
+    1588       16365 :   if(noise_==2) calculate_Marginal();
+    1589             : 
+    1590             :   // get annealing rescale factor
+    1591       16365 :   if(nanneal_>0) {
+    1592           0 :     anneal_ = get_annealing(step);
+    1593           0 :     getPntrToComponent("anneal")->set(anneal_);
+    1594             :   }
+    1595             : 
+    1596             :   // annealing rescale
+    1597       16365 :   ene_ /= anneal_;
+    1598             : 
+    1599       16365 :   std::vector<double> GMMid_der_av_(GMMid_der_.size(), 0.0);
+    1600             :   // in case of ensemble averaging
+    1601       16365 :   if(!no_aver_ && nrep_>1) {
+    1602             :     // if master node, sum der_GMMid derivatives and ene
+    1603          12 :     if(rank_==0) {
+    1604       10812 :       for(unsigned i=0; i<GMMid_der_.size(); ++i) {
+    1605       10800 :         GMMid_der_av_[i] = (weight / norm) * GMMid_der_[i];
+    1606             :       }
+    1607          12 :       multi_sim_comm.Sum(&GMMid_der_av_[0], GMMid_der_av_.size());
+    1608          12 :       multi_sim_comm.Sum(&ene_, 1);
+    1609             :     } else {
+    1610             :       // set der_GMMid derivatives and energy to zero
+    1611           0 :       for(unsigned i=0; i<GMMid_der_av_.size(); ++i) GMMid_der_av_[i]=0.0;
+    1612           0 :       ene_ = 0.0;
+    1613             :     }
+    1614             :     // local communication
+    1615          12 :     if(size_>1) {
+    1616           0 :       comm.Sum(&GMMid_der_av_[0], GMMid_der_av_.size());
+    1617           0 :       comm.Sum(&ene_, 1);
+    1618             :     }
+    1619             :   } else {
+    1620      163530 :     for (unsigned i = 0; i < GMMid_der_.size(); ++i) {
+    1621      147177 :       GMMid_der_av_[i] = GMMid_der_[i];
+    1622             :     }
+    1623             :   }
+    1624             : 
+    1625             :   // clean temporary std::vector
+    1626     9860991 :   for(unsigned i=0; i<atom_der_.size(); ++i) atom_der_[i] = Vector(0,0,0);
+    1627             : 
+    1628             :   // get derivatives of bias with respect to atoms
+    1629     2127723 :   for(unsigned i=rank_; i<nl_.size(); i=i+size_) {
+    1630             :     // get indexes of data and model component
+    1631     2111358 :     unsigned id = nl_[i] / GMM_m_type_.size();
+    1632     2111358 :     unsigned im = nl_[i] % GMM_m_type_.size();
+    1633             :     // chain rule + replica normalization
+    1634     2111358 :     Vector tot_der = GMMid_der_av_[id] * ovmd_der_[i] * scale_ / anneal_;
+    1635     2111358 :     Vector pos;
+    1636     2111358 :     if(pbc_) pos = pbcDistance(GMM_d_m_[id], getPosition(im)) + GMM_d_m_[id];
+    1637     2111358 :     else     pos = getPosition(im);
+    1638             :     // increment derivatives and virial
+    1639     2111358 :     atom_der_[im] += tot_der;
+    1640     2111358 :     virial_ += Tensor(pos, -tot_der);
+    1641             :   }
+    1642             : 
+    1643             :   // communicate local derivatives and virial
+    1644       16365 :   if(size_>1) {
+    1645       10902 :     comm.Sum(&atom_der_[0][0], 3*atom_der_.size());
+    1646       10902 :     comm.Sum(virial_);
+    1647             :   }
+    1648             : 
+    1649             :   // set derivatives, virial, and score
+    1650     9860991 :   for(unsigned i=0; i<atom_der_.size(); ++i) setAtomsDerivatives(getPntrToComponent("scoreb"), i, atom_der_[i]);
+    1651       16365 :   setBoxDerivatives(getPntrToComponent("scoreb"), virial_);
+    1652       16365 :   getPntrToComponent("scoreb")->set(ene_);
+    1653             : 
+    1654       16365 :   if (do_reweight_) {
+    1655             :     double w_tmp = 0.;
+    1656       10812 :     for (unsigned i = 0; i < ovmd_.size(); ++i) {
+    1657       10800 :       w_tmp += (ovmd_[i] - ovmd_ave_[i]) * GMMid_der_[i];
+    1658             :     }
+    1659          12 :     w_tmp *= scale_ * (weight / norm) / kbt_ * decay_w_;
+    1660             : 
+    1661          12 :     setArgDerivatives(getPntrToComponent("scoreb"), w_tmp);
+    1662          24 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1663             :   }
+    1664             : 
+    1665             :   // This part is needed only for Gaussian and Outliers noise models
+    1666       16365 :   if(noise_!=2) {
+    1667             : 
+    1668             :     // do Montecarlo
+    1669       10914 :     if(dsigma_[0]>0 && step%MCstride_==0 && !getExchangeStep()) doMonteCarlo();
+    1670             : 
+    1671             :     // print status
+    1672       10914 :     if(step%statusstride_==0) print_status(step);
+    1673             : 
+    1674             :     // calculate acceptance ratio
+    1675       10914 :     double acc = MCaccept_ / MCtrials_;
+    1676             : 
+    1677             :     // set value
+    1678       21828 :     getPntrToComponent("acc")->set(acc);
+    1679             : 
+    1680             :   }
+    1681             : 
+    1682       16365 : }
+    1683             : 
+    1684        5463 : void EMMI::calculate_Gauss()
+    1685             : {
+    1686             :   // cycle on all the GMM groups
+    1687       10926 :   for(unsigned i=0; i<GMM_d_grps_.size(); ++i) {
+    1688             :     double eneg = 0.0;
+    1689             :     // cycle on all the members of the group
+    1690       65322 :     for(unsigned j=0; j<GMM_d_grps_[i].size(); ++j) {
+    1691             :       // id of the GMM component
+    1692       59859 :       int GMMid = GMM_d_grps_[i][j];
+    1693             :       // calculate deviation
+    1694       59859 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] ) / sigma_[i];
+    1695             :       // add to group energy
+    1696       59859 :       eneg += 0.5 * dev * dev;
+    1697             :       // store derivative for later
+    1698       59859 :       GMMid_der_[GMMid] = kbt_ * dev / sigma_[i];
+    1699             :     }
+    1700             :     // add to total energy along with normalizations and prior
+    1701        5463 :     ene_ += kbt_ * ( eneg + (static_cast<double>(GMM_d_grps_[i].size())+prior_) * std::log(sigma_[i]) );
+    1702             :   }
+    1703        5463 : }
+    1704             : 
+    1705        5451 : void EMMI::calculate_Outliers()
+    1706             : {
+    1707             :   // cycle on all the GMM groups
+    1708       10902 :   for(unsigned i=0; i<GMM_d_grps_.size(); ++i) {
+    1709             :     // cycle on all the members of the group
+    1710             :     double eneg = 0.0;
+    1711       54510 :     for(unsigned j=0; j<GMM_d_grps_[i].size(); ++j) {
+    1712             :       // id of the GMM component
+    1713       49059 :       int GMMid = GMM_d_grps_[i][j];
+    1714             :       // calculate deviation
+    1715       49059 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] ) / sigma_[i];
+    1716             :       // add to group energy
+    1717       49059 :       eneg += std::log1p( 0.5 * dev * dev );
+    1718             :       // store derivative for later
+    1719       49059 :       GMMid_der_[GMMid] = kbt_ / ( 1.0 + 0.5 * dev * dev ) * dev / sigma_[i];
+    1720             :     }
+    1721             :     // add to total energy along with normalizations and prior
+    1722        5451 :     ene_ += kbt_ * ( eneg + (static_cast<double>(GMM_d_grps_[i].size())+prior_) * std::log(sigma_[i]) );
+    1723             :   }
+    1724        5451 : }
+    1725             : 
+    1726        5451 : void EMMI::calculate_Marginal()
+    1727             : {
+    1728             :   // cycle on all the GMM groups
+    1729       10902 :   for(unsigned i=0; i<GMM_d_grps_.size(); ++i) {
+    1730             :     // cycle on all the members of the group
+    1731       54510 :     for(unsigned j=0; j<GMM_d_grps_[i].size(); ++j) {
+    1732             :       // id of the GMM component
+    1733       49059 :       int GMMid = GMM_d_grps_[i][j];
+    1734             :       // calculate deviation
+    1735       49059 :       double dev = ( scale_*ovmd_ave_[GMMid]-ovdd_[GMMid] );
+    1736             :       // calculate errf
+    1737       49059 :       double errf = erf ( dev * inv_sqrt2_ / sigma_min_[i] );
+    1738             :       // add to group energy
+    1739       49059 :       ene_ += -kbt_ * std::log ( 0.5 / dev * errf ) ;
+    1740             :       // store derivative for later
+    1741       49059 :       GMMid_der_[GMMid] = - kbt_/errf*sqrt2_pi_*std::exp(-0.5*dev*dev/sigma_min_[i]/sigma_min_[i])/sigma_min_[i]+kbt_/dev;
+    1742             :     }
+    1743             :   }
+    1744        5451 : }
+    1745             : 
+    1746             : }
+    1747             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMIVox.cpp.func-sort-c.html b/coverage/isdb/EMMIVox.cpp.func-sort-c.html new file mode 100644 index 000000000000..95d77c9f91e9 --- /dev/null +++ b/coverage/isdb/EMMIVox.cpp.func-sort-c.html @@ -0,0 +1,177 @@ + + + + + + + + LCOV - plumed test coverage - isdb/EMMIVox.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - EMMIVox.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:366485.6 %
Date:2024-02-22 21:58:45Functions:1263.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7EMMIVOX10get_medianESt6vectorIdSaIdEE0
_ZN4PLMD4isdb7EMMIVOX10update_gpuEv0
_ZN4PLMD4isdb7EMMIVOX11get_overlapERKNS_13VectorGenericILj3EEES5_RKNS2_ILj5EEES8_d0
_ZN4PLMD4isdb7EMMIVOX11prepare_gpuEv0
_ZN4PLMD4isdb7EMMIVOX11read_statusEv0
_ZN4PLMD4isdb7EMMIVOX12get_exp_dataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb7EMMIVOX12print_statusEl0
_ZN4PLMD4isdb7EMMIVOX14calculate_corrEv0
_ZN4PLMD4isdb7EMMIVOX14calculate_fmodEv0
_ZN4PLMD4isdb7EMMIVOX15calculate_scoreEv0
_ZN4PLMD4isdb7EMMIVOX15get_Model_paramERSt6vectorINS_10AtomNumberESaIS3_EE0
_ZN4PLMD4isdb7EMMIVOX17doMonteCarloBfactEv0
_ZN4PLMD4isdb7EMMIVOX18do_neighbor_sphereEv0
_ZN4PLMD4isdb7EMMIVOX18get_close_residuesEv0
_ZN4PLMD4isdb7EMMIVOX18initialize_BfactorEd0
_ZN4PLMD4isdb7EMMIVOX18push_auxiliary_gpuEv0
_ZN4PLMD4isdb7EMMIVOX19write_model_densityEl0
_ZN4PLMD4isdb7EMMIVOX20update_neighbor_listEv0
_ZN4PLMD4isdb7EMMIVOX21get_auxiliary_vectorsEv0
_ZN4PLMD4isdb7EMMIVOX22update_neighbor_sphereEv0
_ZN4PLMD4isdb7EMMIVOX7prepareEv0
_ZN4PLMD4isdb7EMMIVOX8doAcceptEddd0
_ZN4PLMD4isdb7EMMIVOX9calculateEv0
_ZN4PLMD4isdb7EMMIVOXC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7EMMIVOXC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7EMMIVOX16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMIVox.cpp.func.html b/coverage/isdb/EMMIVox.cpp.func.html new file mode 100644 index 000000000000..165ca6303eed --- /dev/null +++ b/coverage/isdb/EMMIVox.cpp.func.html @@ -0,0 +1,177 @@ + + + + + + + + LCOV - plumed test coverage - isdb/EMMIVox.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - EMMIVox.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:366485.6 %
Date:2024-02-22 21:58:45Functions:1263.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7EMMIVOX10get_medianESt6vectorIdSaIdEE0
_ZN4PLMD4isdb7EMMIVOX10update_gpuEv0
_ZN4PLMD4isdb7EMMIVOX11get_overlapERKNS_13VectorGenericILj3EEES5_RKNS2_ILj5EEES8_d0
_ZN4PLMD4isdb7EMMIVOX11prepare_gpuEv0
_ZN4PLMD4isdb7EMMIVOX11read_statusEv0
_ZN4PLMD4isdb7EMMIVOX12get_exp_dataERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD4isdb7EMMIVOX12print_statusEl0
_ZN4PLMD4isdb7EMMIVOX14calculate_corrEv0
_ZN4PLMD4isdb7EMMIVOX14calculate_fmodEv0
_ZN4PLMD4isdb7EMMIVOX15calculate_scoreEv0
_ZN4PLMD4isdb7EMMIVOX15get_Model_paramERSt6vectorINS_10AtomNumberESaIS3_EE0
_ZN4PLMD4isdb7EMMIVOX16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4isdb7EMMIVOX17doMonteCarloBfactEv0
_ZN4PLMD4isdb7EMMIVOX18do_neighbor_sphereEv0
_ZN4PLMD4isdb7EMMIVOX18get_close_residuesEv0
_ZN4PLMD4isdb7EMMIVOX18initialize_BfactorEd0
_ZN4PLMD4isdb7EMMIVOX18push_auxiliary_gpuEv0
_ZN4PLMD4isdb7EMMIVOX19write_model_densityEl0
_ZN4PLMD4isdb7EMMIVOX20update_neighbor_listEv0
_ZN4PLMD4isdb7EMMIVOX21get_auxiliary_vectorsEv0
_ZN4PLMD4isdb7EMMIVOX22update_neighbor_sphereEv0
_ZN4PLMD4isdb7EMMIVOX7prepareEv0
_ZN4PLMD4isdb7EMMIVOX8doAcceptEddd0
_ZN4PLMD4isdb7EMMIVOX9calculateEv0
_ZN4PLMD4isdb7EMMIVOXC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7EMMIVOXC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/EMMIVox.cpp.gcov.html b/coverage/isdb/EMMIVox.cpp.gcov.html new file mode 100644 index 000000000000..3e0eb22dd5d7 --- /dev/null +++ b/coverage/isdb/EMMIVox.cpp.gcov.html @@ -0,0 +1,1655 @@ + + + + + + + + LCOV - plumed test coverage - isdb/EMMIVox.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - EMMIVox.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:366485.6 %
Date:2024-02-22 21:58:45Functions:1263.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #ifdef __PLUMED_HAS_LIBTORCH
+      24             : #include "colvar/Colvar.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : #include "tools/Communicator.h"
+      28             : #include "tools/Matrix.h"
+      29             : #include "core/GenericMolInfo.h"
+      30             : #include "core/ActionSet.h"
+      31             : #include "tools/File.h"
+      32             : #include "tools/OpenMP.h"
+      33             : #include <string>
+      34             : #include <cmath>
+      35             : #include <map>
+      36             : #include <numeric>
+      37             : #include <ctime>
+      38             : #include "tools/Random.h"
+      39             : 
+      40             : #include <torch/torch.h>
+      41             : #include <torch/script.h>
+      42             : 
+      43             : #ifndef M_PI
+      44             : #define M_PI           3.14159265358979323846
+      45             : #endif
+      46             : 
+      47             : namespace PLMD {
+      48             : namespace isdb {
+      49             : 
+      50             : //+PLUMEDOC ISDB_COLVAR EMMIVOX
+      51             : /*
+      52             : Bayesian single-structure and ensemble refinement with cryo-EM maps.
+      53             : 
+      54             : This action implements the Bayesian approach for single-structure and ensemble refinement from cryo-EM maps introduced <a href="https://www.biorxiv.org/content/10.1101/2023.10.18.562710v1">here</a>.
+      55             : EMMIVox does not require fitting the cryo-EM map with a Gaussian Mixture Model, as done in \ref EMMI, but uses directly the voxels in the deposited map.
+      56             : 
+      57             : When run in single-replica mode, this action allows atomistic, flexible refinement (and B-factors inference) of an individual structure into a density map.
+      58             : A coarse-grained forward model can also be used in combination with the MARTINI force field.
+      59             : Combined with a multi-replica framework (such as the -multi option in GROMACS), the user can model an ensemble of structures using
+      60             : the Metainference approach \cite Bonomi:2016ip . The approach can be used to model continous dynamics of flexible regions as well as semi-ordered waters, lipids, and ions.
+      61             : 
+      62             : \warning
+      63             :     To use EMMIVOX, PLUMED must be linked against the LibTorch library as described \ref ISDB "here"
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : Complete tutorials for single-structure and ensemble refinement can be found <a href="https://github.com/maxbonomi/EMMIVox">here</a>.
+      68             : 
+      69             : */
+      70             : //+ENDPLUMEDOC
+      71             : 
+      72             : class EMMIVOX : public Colvar {
+      73             : 
+      74             : private:
+      75             : 
+      76             : // temperature in kbt
+      77             :   double kbt_;
+      78             : // model - atom types
+      79             :   std::vector<unsigned> Model_type_;
+      80             : // model - list of atom sigmas - one per atom type
+      81             :   std::vector<Vector5d> Model_s_;
+      82             : // model - list of atom weights - one per atom type
+      83             :   std::vector<Vector5d> Model_w_;
+      84             : // model - map between residue/chain IDs and list of atoms
+      85             :   std::map< std::pair<unsigned,std::string>, std::vector<unsigned> > Model_resmap_;
+      86             : // model - list of residue/chain IDs per atom
+      87             :   std::vector< std::pair<unsigned,std::string> > Model_res_;
+      88             : // model - list of neighboring voxels per atom
+      89             :   std::vector< std::vector<unsigned> > Model_nb_;
+      90             : // model - map between residue/chain ID and bfactor
+      91             :   std::map< std::pair<unsigned, std::string>, double> Model_b_;
+      92             : // model - global list of residue/chain IDs
+      93             :   std::vector< std::pair<unsigned,std::string> > Model_rlist_;
+      94             : // model density
+      95             :   std::vector<double> ovmd_;
+      96             : 
+      97             : // data map - voxel position
+      98             :   std::vector<Vector> Map_m_;
+      99             : // data map - density
+     100             :   std::vector<double> ovdd_;
+     101             : // data map - error
+     102             :   std::vector<double> exp_err_;
+     103             : 
+     104             : // derivatives
+     105             :   std::vector<Vector> ovmd_der_;
+     106             :   std::vector<Vector> atom_der_;
+     107             :   std::vector<double> score_der_;
+     108             : // constants
+     109             :   double inv_sqrt2_, sqrt2_pi_, inv_pi2_;
+     110             :   std::vector<Vector5d> pref_;
+     111             :   std::vector<Vector5d> invs2_;
+     112             :   std::vector<Vector5d> cfact_;
+     113             :   std::vector<double> cut_;
+     114             : // metainference
+     115             :   unsigned nrep_;
+     116             :   unsigned replica_;
+     117             :   std::vector<double> ismin_;
+     118             : // neighbor list
+     119             :   double nl_dist_cutoff_;
+     120             :   double nl_gauss_cutoff_;
+     121             :   unsigned nl_stride_;
+     122             :   bool first_time_;
+     123             :   std::vector< std::pair<unsigned,unsigned> > nl_;
+     124             :   std::vector< std::pair<unsigned,unsigned> > ns_;
+     125             :   std::vector<Vector> refpos_;
+     126             : // averaging
+     127             :   bool no_aver_;
+     128             : // correlation;
+     129             :   bool do_corr_;
+     130             : // Monte Carlo stuff
+     131             :   Random   random_;
+     132             :   // Scale and Offset
+     133             :   double scale_;
+     134             :   double offset_;
+     135             : // Bfact Monte Carlo
+     136             :   double   dbfact_;
+     137             :   double   bfactmin_;
+     138             :   double   bfactmax_;
+     139             :   double   bfactsig_;
+     140             :   bool     bfactnoc_;
+     141             :   bool     bfactread_;
+     142             :   int      MCBstride_;
+     143             :   double   MCBaccept_;
+     144             :   double   MCBtrials_;
+     145             : // residue neighbor list
+     146             :   std::vector< std::vector<unsigned> > nl_res_;
+     147             :   bool bfactemin_;
+     148             : // Martini scattering factors
+     149             :   bool martini_;
+     150             :   // status stuff
+     151             :   unsigned int statusstride_;
+     152             :   std::string       statusfilename_;
+     153             :   OFile        statusfile_;
+     154             :   bool         first_status_;
+     155             :   // total energy and virial
+     156             :   double ene_;
+     157             :   Tensor virial_;
+     158             :   double eps_;
+     159             :   // model density file
+     160             :   unsigned int mapstride_;
+     161             :   std::string       mapfilename_;
+     162             :   // Libtorch stuff
+     163             :   bool gpu_;
+     164             :   torch::Tensor ovmd_gpu_;
+     165             :   torch::Tensor ovmd_der_gpu_;
+     166             :   torch::Tensor ismin_gpu_;
+     167             :   torch::Tensor ovdd_gpu_;
+     168             :   torch::Tensor Map_m_gpu_;
+     169             :   torch::Tensor pref_gpu_;
+     170             :   torch::Tensor invs2_gpu_;
+     171             :   torch::Tensor nl_id_gpu_;
+     172             :   torch::Tensor nl_im_gpu_;
+     173             :   torch::Tensor pref_nl_gpu_;
+     174             :   torch::Tensor invs2_nl_gpu_;
+     175             :   torch::Tensor Map_m_nl_gpu_;
+     176             :   torch::DeviceType device_t_;
+     177             : //
+     178             : // write file with model density
+     179             :   void write_model_density(long int step);
+     180             : // get median of vector
+     181             :   double get_median(std::vector<double> v);
+     182             : // read and write status
+     183             :   void read_status();
+     184             :   void print_status(long int step);
+     185             : // accept or reject
+     186             :   bool doAccept(double oldE, double newE, double kbt);
+     187             : // vector of close residues
+     188             :   void get_close_residues();
+     189             : // do MonteCarlo for Bfactor
+     190             :   void doMonteCarloBfact();
+     191             : // calculate model parameters
+     192             :   std::vector<double> get_Model_param(std::vector<AtomNumber> &atoms);
+     193             : // read data file
+     194             :   void get_exp_data(const std::string &datafile);
+     195             : // auxiliary methods
+     196             :   void prepare_gpu();
+     197             :   void initialize_Bfactor(double reso);
+     198             :   void get_auxiliary_vectors();
+     199             :   void push_auxiliary_gpu();
+     200             : // calculate overlap between two Gaussians
+     201             :   double get_overlap(const Vector &d_m, const Vector &m_m,
+     202             :                      const Vector5d &cfact, const Vector5d &m_s, double bfact);
+     203             : // update the neighbor list
+     204             :   void update_neighbor_list();
+     205             : // update data on device
+     206             :   void update_gpu();
+     207             : // update the neighbor sphere
+     208             :   void update_neighbor_sphere();
+     209             :   bool do_neighbor_sphere();
+     210             : // calculate forward model and score on device
+     211             :   void calculate_fmod();
+     212             :   void calculate_score();
+     213             : // calculate correlation
+     214             :   void calculate_corr();
+     215             : 
+     216             : public:
+     217             :   static void registerKeywords( Keywords& keys );
+     218             :   explicit EMMIVOX(const ActionOptions&);
+     219             : // active methods:
+     220             :   void prepare() override;
+     221             :   void calculate() override;
+     222             : };
+     223             : 
+     224             : PLUMED_REGISTER_ACTION(EMMIVOX,"EMMIVOX")
+     225             : 
+     226           2 : void EMMIVOX::registerKeywords( Keywords& keys ) {
+     227           2 :   Colvar::registerKeywords( keys );
+     228           4 :   keys.add("atoms","ATOMS","atoms used in the calculation of the density map, typically all heavy atoms");
+     229           4 :   keys.add("compulsory","DATA_FILE","file with cryo-EM map");
+     230           4 :   keys.add("compulsory","RESOLUTION", "cryo-EM map resolution");
+     231           4 :   keys.add("compulsory","NORM_DENSITY","integral of experimental density");
+     232           4 :   keys.add("compulsory","WRITE_STRIDE","stride for writing status file");
+     233           4 :   keys.add("optional","NL_DIST_CUTOFF","neighbor list distance cutoff");
+     234           4 :   keys.add("optional","NL_GAUSS_CUTOFF","neighbor list Gaussian sigma cutoff");
+     235           4 :   keys.add("optional","NL_STRIDE","neighbor list update frequency");
+     236           4 :   keys.add("optional","SIGMA_MIN","minimum density error");
+     237           4 :   keys.add("optional","DBFACT","Bfactor MC step");
+     238           4 :   keys.add("optional","BFACT_MAX","Bfactor maximum value");
+     239           4 :   keys.add("optional","MCBFACT_STRIDE", "Bfactor MC stride");
+     240           4 :   keys.add("optional","BFACT_SIGMA","Bfactor sigma prior");
+     241           4 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart");
+     242           4 :   keys.add("optional","SCALE","scale factor");
+     243           4 :   keys.add("optional","OFFSET","offset");
+     244           4 :   keys.add("optional","TEMP","temperature");
+     245           4 :   keys.add("optional","WRITE_MAP","file with model density");
+     246           4 :   keys.add("optional","WRITE_MAP_STRIDE","stride for writing model density to file");
+     247           4 :   keys.addFlag("NO_AVER",false,"no ensemble averaging in multi-replica mode");
+     248           4 :   keys.addFlag("CORRELATION",false,"calculate correlation coefficient");
+     249           4 :   keys.addFlag("GPU",false,"calculate EMMIVOX on GPU with Libtorch");
+     250           4 :   keys.addFlag("BFACT_NOCHAIN",false,"Do not use chain ID for Bfactor MC");
+     251           4 :   keys.addFlag("BFACT_READ",false,"Read Bfactor on RESTART (automatic with DBFACT>0)");
+     252           4 :   keys.addFlag("BFACT_MINIMIZE",false,"Accept only moves that decrease energy");
+     253           4 :   keys.addFlag("MARTINI",false,"Use Martini scattering factors");
+     254           2 :   componentsAreNotOptional(keys);
+     255           4 :   keys.addOutputComponent("scoreb","default","Bayesian score");
+     256           4 :   keys.addOutputComponent("scale", "default","scale factor");
+     257           4 :   keys.addOutputComponent("offset","default","offset");
+     258           4 :   keys.addOutputComponent("accB",  "default", "Bfactor MC acceptance");
+     259           4 :   keys.addOutputComponent("kbt",   "default", "temperature in energy unit");
+     260           4 :   keys.addOutputComponent("corr",  "CORRELATION", "correlation coefficient");
+     261           2 : }
+     262             : 
+     263           0 : EMMIVOX::EMMIVOX(const ActionOptions&ao):
+     264             :   PLUMED_COLVAR_INIT(ao),
+     265           0 :   nl_dist_cutoff_(1.0), nl_gauss_cutoff_(3.0), nl_stride_(50),
+     266           0 :   first_time_(true), no_aver_(false), do_corr_(false),
+     267           0 :   scale_(1.), offset_(0.),
+     268           0 :   dbfact_(0.0), bfactmin_(0.05), bfactmax_(5.0),
+     269           0 :   bfactsig_(0.1), bfactnoc_(false), bfactread_(false),
+     270           0 :   MCBstride_(1), MCBaccept_(0.), MCBtrials_(0.), bfactemin_(false),
+     271           0 :   martini_(false), statusstride_(0), first_status_(true),
+     272           0 :   eps_(0.0001), mapstride_(0), gpu_(false)
+     273             : {
+     274             :   // set constants
+     275           0 :   inv_sqrt2_ = 1.0/sqrt(2.0);
+     276           0 :   sqrt2_pi_  = sqrt(2.0 / M_PI);
+     277           0 :   inv_pi2_   = 0.5 / M_PI / M_PI;
+     278             : 
+     279             :   // list of atoms
+     280             :   std::vector<AtomNumber> atoms;
+     281           0 :   parseAtomList("ATOMS", atoms);
+     282             : 
+     283             :   // file with experimental cryo-EM map
+     284             :   std::string datafile;
+     285           0 :   parse("DATA_FILE", datafile);
+     286             : 
+     287             :   // neighbor list cutoffs
+     288           0 :   parse("NL_DIST_CUTOFF",nl_dist_cutoff_);
+     289           0 :   parse("NL_GAUSS_CUTOFF",nl_gauss_cutoff_);
+     290             :   // checks
+     291           0 :   if(nl_dist_cutoff_<=0. && nl_gauss_cutoff_<=0.) error("You must specify either NL_DIST_CUTOFF or NL_GAUSS_CUTOFF or both");
+     292           0 :   if(nl_gauss_cutoff_<=0.) nl_gauss_cutoff_ = 1.0e+10;
+     293           0 :   if(nl_dist_cutoff_<=0.) nl_dist_cutoff_ = 1.0e+10;
+     294             :   // neighbor list update stride
+     295           0 :   parse("NL_STRIDE",nl_stride_);
+     296           0 :   if(nl_stride_<=0) error("NL_STRIDE must be explicitly specified and positive");
+     297             : 
+     298             :   // minimum value for error
+     299           0 :   double sigma_min = 0.2;
+     300           0 :   parse("SIGMA_MIN", sigma_min);
+     301           0 :   if(sigma_min<0.) error("SIGMA_MIN must be greater or equal to zero");
+     302             : 
+     303             :   // status file parameters
+     304           0 :   parse("WRITE_STRIDE", statusstride_);
+     305           0 :   if(statusstride_<=0) error("you must specify a positive WRITE_STRIDE");
+     306           0 :   parse("STATUS_FILE",  statusfilename_);
+     307           0 :   if(statusfilename_=="") statusfilename_ = "EMMIStatus"+getLabel();
+     308             : 
+     309             :   // integral of the experimetal density
+     310             :   double norm_d;
+     311           0 :   parse("NORM_DENSITY", norm_d);
+     312             : 
+     313             :   // temperature
+     314           0 :   kbt_ = getkBT();
+     315             : 
+     316             :   // scale and offset
+     317           0 :   parse("SCALE", scale_);
+     318           0 :   parse("OFFSET",offset_);
+     319             : 
+     320             :   // B-factors MC
+     321           0 :   parse("DBFACT",dbfact_);
+     322             :   // read Bfactors
+     323           0 :   parseFlag("BFACT_READ",bfactread_);
+     324             :   // do not use chains
+     325           0 :   parseFlag("BFACT_NOCHAIN",bfactnoc_);
+     326             :   // other parameters
+     327           0 :   if(dbfact_>0.) {
+     328           0 :     parse("MCBFACT_STRIDE",MCBstride_);
+     329           0 :     parse("BFACT_MAX",bfactmax_);
+     330           0 :     parse("BFACT_SIGMA",bfactsig_);
+     331           0 :     parseFlag("BFACT_MINIMIZE",bfactemin_);
+     332             :     // checks
+     333           0 :     if(MCBstride_<=0) error("you must specify a positive MCBFACT_STRIDE");
+     334           0 :     if(bfactmax_<=bfactmin_) error("you must specify a positive BFACT_MAX");
+     335           0 :     if(MCBstride_%nl_stride_!=0) error("MCBFACT_STRIDE must be multiple of NL_STRIDE");
+     336           0 :     if(bfactsig_<=0.) error("you must specify a positive BFACT_SIGMA");
+     337             :   }
+     338             : 
+     339             :   // read map resolution
+     340             :   double reso;
+     341           0 :   parse("RESOLUTION", reso);
+     342           0 :   if(reso<=0.) error("RESOLUTION must be strictly positive");
+     343             : 
+     344             :   // averaging or not
+     345           0 :   parseFlag("NO_AVER",no_aver_);
+     346             : 
+     347             :   // calculate correlation coefficient
+     348           0 :   parseFlag("CORRELATION",do_corr_);
+     349             : 
+     350             :   // write density file
+     351           0 :   parse("WRITE_MAP_STRIDE", mapstride_);
+     352           0 :   parse("WRITE_MAP", mapfilename_);
+     353           0 :   if(mapstride_>0 && mapfilename_=="") error("With WRITE_MAP_STRIDE you must specify WRITE_MAP");
+     354             : 
+     355             :   // use GPU?
+     356           0 :   parseFlag("GPU",gpu_);
+     357             :   // set device
+     358           0 :   if (gpu_ && torch::cuda::is_available()) {
+     359           0 :     device_t_ = torch::kCUDA;
+     360             :   } else {
+     361           0 :     device_t_ = torch::kCPU;
+     362           0 :     gpu_ = false;
+     363             :   }
+     364             : 
+     365             : // Martini model
+     366           0 :   parseFlag("MARTINI",martini_);
+     367             : 
+     368             :   // check read
+     369           0 :   checkRead();
+     370             : 
+     371             :   // set parallel stuff
+     372           0 :   unsigned mpisize=comm.Get_size();
+     373           0 :   if(mpisize>1) error("EMMIVOX supports only OpenMP parallelization");
+     374             : 
+     375             :   // get number of replicas
+     376           0 :   if(no_aver_) {
+     377           0 :     nrep_ = 1;
+     378             :   } else {
+     379           0 :     nrep_ = multi_sim_comm.Get_size();
+     380             :   }
+     381           0 :   replica_ = multi_sim_comm.Get_rank();
+     382             : 
+     383           0 :   if(nrep_>1 && dbfact_>0) error("Bfactor sampling not supported with ensemble averaging");
+     384             : 
+     385           0 :   log.printf("  number of atoms involved : %u\n", atoms.size());
+     386           0 :   log.printf("  experimental density map : %s\n", datafile.c_str());
+     387           0 :   if(no_aver_) log.printf("  without ensemble averaging\n");
+     388           0 :   if(gpu_) {log.printf("  running on GPU \n");}
+     389           0 :   else {log.printf("  running on CPU \n");}
+     390           0 :   if(nl_dist_cutoff_ <1.0e+10) log.printf("  neighbor list distance cutoff : %lf\n", nl_dist_cutoff_);
+     391           0 :   if(nl_gauss_cutoff_<1.0e+10) log.printf("  neighbor list Gaussian sigma cutoff : %lf\n", nl_gauss_cutoff_);
+     392           0 :   log.printf("  neighbor list update stride : %u\n",  nl_stride_);
+     393           0 :   log.printf("  minimum density error : %f\n", sigma_min);
+     394           0 :   log.printf("  scale factor : %lf\n", scale_);
+     395           0 :   log.printf("  offset : %lf\n", offset_);
+     396           0 :   log.printf("  reading/writing to status file : %s\n", statusfilename_.c_str());
+     397           0 :   log.printf("  with stride : %u\n", statusstride_);
+     398           0 :   if(dbfact_>0) {
+     399           0 :     log.printf("  maximum Bfactor MC move : %f\n", dbfact_);
+     400           0 :     log.printf("  stride MC move : %u\n", MCBstride_);
+     401           0 :     log.printf("  using prior with sigma : %f\n", bfactsig_);
+     402             :   }
+     403           0 :   if(bfactread_) log.printf("  reading Bfactors from file : %s\n", statusfilename_.c_str());
+     404           0 :   log.printf("  temperature of the system in energy unit : %f\n", kbt_);
+     405           0 :   if(nrep_>1) {
+     406           0 :     log.printf("  number of replicas for averaging: %u\n", nrep_);
+     407           0 :     log.printf("  replica ID : %u\n", replica_);
+     408             :   }
+     409           0 :   if(mapstride_>0) {
+     410           0 :     log.printf("  writing model density to file : %s\n", mapfilename_.c_str());
+     411           0 :     log.printf("  with stride : %u\n", mapstride_);
+     412             :   }
+     413           0 :   if(martini_) log.printf("  using Martini scattering factors\n");
+     414             : 
+     415             :   // calculate model constant parameters
+     416           0 :   std::vector<double> Model_w = get_Model_param(atoms);
+     417             : 
+     418             :   // read experimental map and errors
+     419           0 :   get_exp_data(datafile);
+     420           0 :   log.printf("  number of voxels : %u\n", static_cast<unsigned>(ovdd_.size()));
+     421             : 
+     422             :   // normalize atom weight map
+     423             :   double norm_m = accumulate(Model_w.begin(),  Model_w.end(),  0.0);
+     424             :   // renormalization and constant factor on atom types
+     425           0 :   for(unsigned i=0; i<Model_w_.size(); ++i) {
+     426           0 :     Vector5d cf;
+     427           0 :     for(unsigned j=0; j<5; ++j) {
+     428           0 :       Model_w_[i][j] *= norm_d / norm_m;
+     429           0 :       cf[j] = Model_w_[i][j]/pow( 2.0*pi, 1.5 );
+     430             :     }
+     431           0 :     cfact_.push_back(cf);
+     432             :   }
+     433             : 
+     434             :   // median density
+     435           0 :   double ovdd_m = get_median(ovdd_);
+     436             :   // median experimental error
+     437           0 :   double err_m  = get_median(exp_err_);
+     438             :   // minimum error
+     439           0 :   double minerr = sigma_min*ovdd_m;
+     440             :   // print out statistics
+     441           0 :   log.printf("     median density : %lf\n", ovdd_m);
+     442           0 :   log.printf("     minimum error  : %lf\n", minerr);
+     443           0 :   log.printf("     median error   : %lf\n", err_m);
+     444             :   // populate ismin: cycle on all voxels
+     445           0 :   for(unsigned id=0; id<ovdd_.size(); ++id) {
+     446             :     // define smin
+     447           0 :     double smin = std::max(minerr, exp_err_[id]);
+     448             :     // and to ismin_
+     449           0 :     ismin_.push_back(1.0/smin);
+     450             :   }
+     451             : 
+     452             :   // prepare gpu stuff: map centers, data, and error
+     453           0 :   prepare_gpu();
+     454             : 
+     455             :   // initialize Bfactors
+     456           0 :   initialize_Bfactor(reso);
+     457             : 
+     458             :   // read status file if restarting
+     459           0 :   if(getRestart() || bfactread_) read_status();
+     460             : 
+     461             :   // prepare auxiliary vectors
+     462           0 :   get_auxiliary_vectors();
+     463             : 
+     464             :   // prepare other vectors: data and derivatives
+     465           0 :   ovmd_.resize(ovdd_.size());
+     466           0 :   atom_der_.resize(Model_type_.size());
+     467           0 :   score_der_.resize(ovdd_.size());
+     468             : 
+     469             :   // add components
+     470           0 :   addComponentWithDerivatives("scoreb"); componentIsNotPeriodic("scoreb");
+     471           0 :   addComponent("scale");                 componentIsNotPeriodic("scale");
+     472           0 :   addComponent("offset");                componentIsNotPeriodic("offset");
+     473           0 :   addComponent("kbt");                   componentIsNotPeriodic("kbt");
+     474           0 :   if(dbfact_>0)   {addComponent("accB"); componentIsNotPeriodic("accB");}
+     475           0 :   if(do_corr_)    {addComponent("corr"); componentIsNotPeriodic("corr");}
+     476             : 
+     477             :   // initialize random seed
+     478           0 :   unsigned iseed = time(NULL)+replica_;
+     479           0 :   random_.setSeed(-iseed);
+     480             : 
+     481             :   // request atoms
+     482           0 :   requestAtoms(atoms);
+     483             : 
+     484             :   // print bibliography
+     485           0 :   log<<"  Bibliography "<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     486           0 :   log<<plumed.cite("Hoff, Thomasen, Lindorff-Larsen, Bonomi, bioRxiv (2023) doi: 10.1101/2023.10.18.562710");
+     487           0 :   if(!no_aver_ && nrep_>1)log<<plumed.cite("Bonomi, Camilloni, Cavalli, Vendruscolo, Sci. Adv. 2, e150117 (2016)");
+     488           0 :   log<<"\n";
+     489           0 : }
+     490             : 
+     491           0 : void EMMIVOX::prepare_gpu()
+     492             : {
+     493             :   // number of data points
+     494           0 :   int nd = ovdd_.size();
+     495             :   // 1) put ismin_ on device_t_
+     496           0 :   ismin_gpu_ = torch::from_blob(ismin_.data(), {nd}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+     497             :   // 2) put ovdd_ on device_t_
+     498           0 :   ovdd_gpu_  = torch::from_blob(ovdd_.data(),  {nd}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+     499             :   // 3) put Map_m_ on device_t_
+     500           0 :   std::vector<double> Map_m_gpu(3*nd);
+     501           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     502             :   for(int i=0; i<nd; ++i) {
+     503             :     Map_m_gpu[i]      = Map_m_[i][0];
+     504             :     Map_m_gpu[i+nd]   = Map_m_[i][1];
+     505             :     Map_m_gpu[i+2*nd] = Map_m_[i][2];
+     506             :   }
+     507             :   // libtorch tensor
+     508           0 :   Map_m_gpu_ = torch::from_blob(Map_m_gpu.data(), {3,nd}, torch::kFloat64).clone().to(torch::kFloat32).to(device_t_);
+     509           0 : }
+     510             : 
+     511           0 : void EMMIVOX::write_model_density(long int step)
+     512             : {
+     513           0 :   OFile ovfile;
+     514           0 :   ovfile.link(*this);
+     515           0 :   std::string num; Tools::convert(step,num);
+     516           0 :   std::string name = mapfilename_+"-"+num;
+     517           0 :   ovfile.open(name);
+     518             :   ovfile.setHeavyFlush();
+     519           0 :   ovfile.fmtField("%10.7e ");
+     520             : // write density
+     521           0 :   for(unsigned i=0; i<ovmd_.size(); ++i) {
+     522           0 :     ovfile.printField("Model", ovmd_[i]);
+     523           0 :     ovfile.printField("ModelScaled", scale_ * ovmd_[i] + offset_);
+     524           0 :     ovfile.printField("Data", ovdd_[i]);
+     525           0 :     ovfile.printField();
+     526             :   }
+     527           0 :   ovfile.close();
+     528           0 : }
+     529             : 
+     530           0 : double EMMIVOX::get_median(std::vector<double> v)
+     531             : {
+     532             : // dimension of vector
+     533           0 :   unsigned size = v.size();
+     534             : // in case of only one entry
+     535           0 :   if (size==1) {
+     536           0 :     return v[0];
+     537             :   } else {
+     538             :     // reorder vector
+     539           0 :     sort(v.begin(), v.end());
+     540             :     // odd or even?
+     541           0 :     if (size%2==0) {
+     542           0 :       return (v[size/2-1]+v[size/2])/2.0;
+     543             :     } else {
+     544           0 :       return v[size/2];
+     545             :     }
+     546             :   }
+     547             : }
+     548             : 
+     549           0 : void EMMIVOX::read_status()
+     550             : {
+     551             :   double MDtime;
+     552             : // open file
+     553           0 :   IFile *ifile = new IFile();
+     554           0 :   ifile->link(*this);
+     555           0 :   if(ifile->FileExist(statusfilename_)) {
+     556           0 :     ifile->open(statusfilename_);
+     557           0 :     while(ifile->scanField("MD_time", MDtime)) {
+     558             :       // read scale and offset
+     559           0 :       ifile->scanField("scale", scale_);
+     560           0 :       ifile->scanField("offset", offset_);
+     561             :       // read bfactors if doing fitting of reading it at restart
+     562           0 :       if(dbfact_>0 || bfactread_) {
+     563             :         // cycle on residues
+     564           0 :         for(unsigned ir=0; ir<Model_rlist_.size(); ++ir) {
+     565             :           // key: pair of residue/chain IDs
+     566             :           std::pair<unsigned,std::string> key = Model_rlist_[ir];
+     567             :           // convert ires to std::string
+     568           0 :           std::string num; Tools::convert(key.first,num);
+     569             :           // read entry
+     570           0 :           std::string ch = key.second;
+     571           0 :           if(ch==" ") ch="";
+     572           0 :           ifile->scanField("bf-"+num+":"+ch, Model_b_[key]);
+     573             :         }
+     574             :       }
+     575             :       // new line
+     576           0 :       ifile->scanField();
+     577             :     }
+     578           0 :     ifile->close();
+     579             :   } else {
+     580           0 :     error("Cannot find status file "+statusfilename_+"\n");
+     581             :   }
+     582           0 :   delete ifile;
+     583           0 : }
+     584             : 
+     585           0 : void EMMIVOX::print_status(long int step)
+     586             : {
+     587             : // if first time open the file
+     588           0 :   if(first_status_) {
+     589           0 :     first_status_ = false;
+     590           0 :     statusfile_.link(*this);
+     591           0 :     statusfile_.open(statusfilename_);
+     592             :     statusfile_.setHeavyFlush();
+     593           0 :     statusfile_.fmtField("%10.7e ");
+     594             :   }
+     595             : // write fields
+     596           0 :   double MDtime = static_cast<double>(step)*getTimeStep();
+     597           0 :   statusfile_.printField("MD_time", MDtime);
+     598             :   // write scale and offset
+     599           0 :   statusfile_.printField("scale", scale_);
+     600           0 :   statusfile_.printField("offset", offset_);
+     601             :   // write bfactors only if doing fitting or reading bfactors
+     602           0 :   if(dbfact_>0 || bfactread_) {
+     603             :     // cycle on residues
+     604           0 :     for(unsigned ir=0; ir<Model_rlist_.size(); ++ir) {
+     605             :       // key: pair of residue/chain IDs
+     606             :       std::pair<unsigned,std::string> key = Model_rlist_[ir];
+     607             :       // bfactor from map
+     608           0 :       double bf = Model_b_[key];
+     609             :       // convert ires to std::string
+     610           0 :       std::string num; Tools::convert(key.first,num);
+     611             :       // print entry
+     612           0 :       statusfile_.printField("bf-"+num+":"+key.second, bf);
+     613             :     }
+     614             :   }
+     615           0 :   statusfile_.printField();
+     616           0 : }
+     617             : 
+     618           0 : bool EMMIVOX::doAccept(double oldE, double newE, double kbt)
+     619             : {
+     620             :   bool accept = false;
+     621             :   // calculate delta energy
+     622           0 :   double delta = ( newE - oldE ) / kbt;
+     623             :   // if delta is negative always accept move
+     624           0 :   if( delta < 0.0 ) {
+     625             :     accept = true;
+     626             :   } else {
+     627             :     // otherwise extract random number
+     628           0 :     double s = random_.RandU01();
+     629           0 :     if( s < exp(-delta) ) { accept = true; }
+     630             :   }
+     631           0 :   return accept;
+     632             : }
+     633             : 
+     634           0 : std::vector<double> EMMIVOX::get_Model_param(std::vector<AtomNumber> &atoms)
+     635             : {
+     636             :   // check if MOLINFO line is present
+     637           0 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     638           0 :   if(!moldat) error("MOLINFO DATA not found\n");
+     639           0 :   log<<"  MOLINFO DATA found with label " <<moldat->getLabel()<<", using proper atom names\n";
+     640             : 
+     641             :   // list of weights - one per atom
+     642             :   std::vector<double> Model_w;
+     643             :   // 5-Gaussians parameters
+     644             :   // map of atom types to A and B coefficients of scattering factor
+     645             :   // f(s) = A * exp(-B*s**2)
+     646             :   // B is in Angstrom squared
+     647             :   // Elastic atomic scattering factors of electrons for neutral atoms
+     648             :   // and s up to 6.0 A^-1: as implemented in PLUMED
+     649             :   // map between an atom type and an index
+     650             :   std::map<std::string, unsigned> type_map;
+     651             :   // atomistic types
+     652           0 :   type_map["C"]=0;  type_map["O"]=1;  type_map["N"]=2;
+     653           0 :   type_map["S"]=3;  type_map["P"]=4;  type_map["F"]=5;
+     654           0 :   type_map["NA"]=6; type_map["MG"]=7; type_map["CL"]=8;
+     655           0 :   type_map["CA"]=9; type_map["K"]=10; type_map["ZN"]=11;
+     656             :   // Martini types
+     657           0 :   type_map["ALA_BB"]=12;    type_map["ALA_SC1"]=13;   type_map["CYS_BB"]=14;
+     658           0 :   type_map["CYS_SC1"]=15;   type_map["ASP_BB"]=16;    type_map["ASP_SC1"]=17;
+     659           0 :   type_map["GLU_BB"]=18;    type_map["GLU_SC1"]=19;   type_map["PHE_BB"]=20;
+     660           0 :   type_map["PHE_SC1"]=21;   type_map["PHE_SC2"]=22;   type_map["PHE_SC3"]=23;
+     661           0 :   type_map["GLY_BB"]=24;    type_map["HIS_BB"]=25;    type_map["HIS_SC1"]=26;
+     662           0 :   type_map["HIS_SC2"]=27;   type_map["HIS_SC3"]=28;   type_map["ILE_BB"]=29;
+     663           0 :   type_map["ILE_SC1"]=30;   type_map["LYS_BB"]=31;    type_map["LYS_SC1"]=32;
+     664           0 :   type_map["LYS_SC2"]=33;   type_map["LEU_BB"]=34;    type_map["LEU_SC1"]=35;
+     665           0 :   type_map["MET_BB"]=36;    type_map["MET_SC1"]=37;   type_map["ASN_BB"]=38;
+     666           0 :   type_map["ASN_SC1"]=39;   type_map["PRO_BB"]=40;    type_map["PRO_SC1"]=41;
+     667           0 :   type_map["GLN_BB"]=42;    type_map["GLN_SC1"]=43;   type_map["ARG_BB"]=44;
+     668           0 :   type_map["ARG_SC1"]=45;   type_map["ARG_SC2"]=46;   type_map["SER_BB"]=47;
+     669           0 :   type_map["SER_SC1"]=48;   type_map["THR_BB"]=49;    type_map["THR_SC1"]=50;
+     670           0 :   type_map["VAL_BB"]=51;    type_map["VAL_SC1"]=52;   type_map["TRP_BB"]=53;
+     671           0 :   type_map["TRP_SC1"]=54;   type_map["TRP_SC2"]=55;   type_map["TRP_SC3"]=56;
+     672           0 :   type_map["TRP_SC4"]=57;   type_map["TRP_SC5"]=58;   type_map["TYR_BB"]=59;
+     673           0 :   type_map["TYR_SC1"]=60;   type_map["TYR_SC2"]=61;   type_map["TYR_SC3"]=62;
+     674           0 :   type_map["TYR_SC4"]=63;
+     675             :   // fill in sigma vector for atoms
+     676           0 :   Model_s_.push_back(0.01*Vector5d(0.114,1.0825,5.4281,17.8811,51.1341));   // C
+     677           0 :   Model_s_.push_back(0.01*Vector5d(0.0652,0.6184,2.9449,9.6298,28.2194));   // O
+     678           0 :   Model_s_.push_back(0.01*Vector5d(0.0541,0.5165,2.8207,10.6297,34.3764));  // N
+     679           0 :   Model_s_.push_back(0.01*Vector5d(0.0838,0.7788,4.3462,15.5846,44.63655)); // S
+     680           0 :   Model_s_.push_back(0.01*Vector5d(0.0977,0.9084,4.9654,18.5471,54.3648));  // P
+     681           0 :   Model_s_.push_back(0.01*Vector5d(0.0613,0.5753,2.6858,8.8214,25.6668));   // F
+     682           0 :   Model_s_.push_back(0.01*Vector5d(0.1684,1.7150,8.8386,50.8265,147.2073)); // NA
+     683           0 :   Model_s_.push_back(0.01*Vector5d(0.1356,1.3579,6.9255,32.3165,92.1138));  // MG
+     684           0 :   Model_s_.push_back(0.01*Vector5d(0.0694,0.6443,3.5351,12.5058,35.8633));  // CL
+     685           0 :   Model_s_.push_back(0.01*Vector5d(0.1742,1.8329,8.8407,47.4583,134.9613)); // CA
+     686           0 :   Model_s_.push_back(0.01*Vector5d(0.1660,1.6906,8.7447,46.7825,165.6923)); // K
+     687           0 :   Model_s_.push_back(0.01*Vector5d(0.0876,0.8650,3.8612,18.8726,64.7016));  // ZN
+     688             :   // fill in sigma vector for Martini beads
+     689           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // ALA_BB
+     690           0 :   Model_s_.push_back(0.01*Vector5d(0.500000,0.500000,0.500000,0.500000,0.500000)); // ALA_SC1
+     691           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // CYS_BB
+     692           0 :   Model_s_.push_back(0.01*Vector5d(8.500000,8.500000,8.500000,8.500000,8.500000)); // CYS_SC1
+     693           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // ASP_BB
+     694           0 :   Model_s_.push_back(0.01*Vector5d(17.000000,17.000000,17.000000,17.000000,17.000000)); // ASP_SC1
+     695           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // GLU_BB
+     696           0 :   Model_s_.push_back(0.01*Vector5d(24.000000,24.000000,24.000000,24.000000,24.000000)); // GLU_SC1
+     697           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // PHE_BB
+     698           0 :   Model_s_.push_back(0.01*Vector5d(17.500000,17.500000,17.500000,17.500000,17.500000)); // PHE_SC1
+     699           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // PHE_SC2
+     700           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // PHE_SC3
+     701           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // GLY_BB
+     702           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // HIS_BB
+     703           0 :   Model_s_.push_back(0.01*Vector5d(11.500000,11.500000,11.500000,11.500000,11.500000)); // HIS_SC1
+     704           0 :   Model_s_.push_back(0.01*Vector5d(9.000000,9.000000,9.000000,9.000000,9.000000)); // HIS_SC2
+     705           0 :   Model_s_.push_back(0.01*Vector5d(8.500000,8.500000,8.500000,8.500000,8.500000)); // HIS_SC3
+     706           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // ILE_BB
+     707           0 :   Model_s_.push_back(0.01*Vector5d(25.500000,25.500000,25.500000,25.500000,25.500000)); // ILE_SC1
+     708           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // LYS_BB
+     709           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // LYS_SC1
+     710           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // LYS_SC2
+     711           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // LEU_BB
+     712           0 :   Model_s_.push_back(0.01*Vector5d(21.500000,21.500000,21.500000,21.500000,21.500000)); // LEU_SC1
+     713           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // MET_BB
+     714           0 :   Model_s_.push_back(0.01*Vector5d(22.500000,22.500000,22.500000,22.500000,22.500000)); // MET_SC1
+     715           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // ASN_BB
+     716           0 :   Model_s_.push_back(0.01*Vector5d(18.500000,18.500000,18.500000,18.500000,18.500000)); // ASN_SC1
+     717           0 :   Model_s_.push_back(0.01*Vector5d(23.500000,23.500000,23.500000,23.500000,23.500000)); // PRO_BB
+     718           0 :   Model_s_.push_back(0.01*Vector5d(17.500000,17.500000,17.500000,17.500000,17.500000)); // PRO_SC1
+     719           0 :   Model_s_.push_back(0.01*Vector5d(22.000000,22.000000,22.000000,22.000000,22.000000)); // GLN_BB
+     720           0 :   Model_s_.push_back(0.01*Vector5d(24.500000,24.500000,24.500000,24.500000,24.500000)); // GLN_SC1
+     721           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // ARG_BB
+     722           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // ARG_SC1
+     723           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // ARG_SC2
+     724           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // SER_BB
+     725           0 :   Model_s_.push_back(0.01*Vector5d(9.000000,9.000000,9.000000,9.000000,9.000000)); // SER_SC1
+     726           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // THR_BB
+     727           0 :   Model_s_.push_back(0.01*Vector5d(17.000000,17.000000,17.000000,17.000000,17.000000)); // THR_SC1
+     728           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // VAL_BB
+     729           0 :   Model_s_.push_back(0.01*Vector5d(18.000000,18.000000,18.000000,18.000000,18.000000)); // VAL_SC1
+     730           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // TRP_BB
+     731           0 :   Model_s_.push_back(0.01*Vector5d(11.500000,11.500000,11.500000,11.500000,11.500000)); // TRP_SC1
+     732           0 :   Model_s_.push_back(0.01*Vector5d(9.000000,9.000000,9.000000,9.000000,9.000000)); // TRP_SC2
+     733           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TRP_SC3
+     734           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TRP_SC4
+     735           0 :   Model_s_.push_back(0.01*Vector5d(9.500000,9.500000,9.500000,9.500000,9.500000)); // TRP_SC5
+     736           0 :   Model_s_.push_back(0.01*Vector5d(23.000000,23.000000,23.000000,23.000000,23.000000)); // TYR_BB
+     737           0 :   Model_s_.push_back(0.01*Vector5d(12.000000,12.000000,12.000000,12.000000,12.000000)); // TYR_SC1
+     738           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TYR_SC2
+     739           0 :   Model_s_.push_back(0.01*Vector5d(11.000000,11.000000,11.000000,11.000000,11.000000)); // TYR_SC3
+     740           0 :   Model_s_.push_back(0.01*Vector5d(8.500000,8.500000,8.500000,8.500000,8.500000)); // TYR_SC4
+     741             :   // fill in weight vector for atoms
+     742           0 :   Model_w_.push_back(Vector5d(0.0489,0.2091,0.7537,1.1420,0.3555)); // C
+     743           0 :   Model_w_.push_back(Vector5d(0.0365,0.1729,0.5805,0.8814,0.3121)); // O
+     744           0 :   Model_w_.push_back(Vector5d(0.0267,0.1328,0.5301,1.1020,0.4215)); // N
+     745           0 :   Model_w_.push_back(Vector5d(0.0915,0.4312,1.0847,2.4671,1.0852)); // S
+     746           0 :   Model_w_.push_back(Vector5d(0.1005,0.4615,1.0663,2.5854,1.2725)); // P
+     747           0 :   Model_w_.push_back(Vector5d(0.0382,0.1822,0.5972,0.7707,0.2130)); // F
+     748           0 :   Model_w_.push_back(Vector5d(0.1260,0.6442,0.8893,1.8197,1.2988)); // NA
+     749           0 :   Model_w_.push_back(Vector5d(0.1130,0.5575,0.9046,2.1580,1.4735)); // MG
+     750           0 :   Model_w_.push_back(Vector5d(0.0799,0.3891,1.0037,2.3332,1.0507)); // CL
+     751           0 :   Model_w_.push_back(Vector5d(0.2355,0.9916,2.3959,3.7252,2.5647)); // CA
+     752           0 :   Model_w_.push_back(Vector5d(0.2149,0.8703,2.4999,2.3591,3.0318)); // K
+     753           0 :   Model_w_.push_back(Vector5d(0.1780,0.8096,1.6744,1.9499,1.4495)); // ZN
+     754             :   // fill in weight vector for Martini beads
+     755           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ALA_BB
+     756           0 :   Model_w_.push_back(Vector5d(0.100000,0.100000,0.100000,0.100000,0.100000)); // ALA_SC1
+     757           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // CYS_BB
+     758           0 :   Model_w_.push_back(Vector5d(1.100000,1.100000,1.100000,1.100000,1.100000)); // CYS_SC1
+     759           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // ASP_BB
+     760           0 :   Model_w_.push_back(Vector5d(1.700000,1.700000,1.700000,1.700000,1.700000)); // ASP_SC1
+     761           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // GLU_BB
+     762           0 :   Model_w_.push_back(Vector5d(2.300000,2.300000,2.300000,2.300000,2.300000)); // GLU_SC1
+     763           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // PHE_BB
+     764           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // PHE_SC1
+     765           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // PHE_SC2
+     766           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // PHE_SC3
+     767           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // GLY_BB
+     768           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // HIS_BB
+     769           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // HIS_SC1
+     770           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // HIS_SC2
+     771           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // HIS_SC3
+     772           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // ILE_BB
+     773           0 :   Model_w_.push_back(Vector5d(2.000000,2.000000,2.000000,2.000000,2.000000)); // ILE_SC1
+     774           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // LYS_BB
+     775           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // LYS_SC1
+     776           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // LYS_SC2
+     777           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // LEU_BB
+     778           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // LEU_SC1
+     779           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // MET_BB
+     780           0 :   Model_w_.push_back(Vector5d(2.300000,2.300000,2.300000,2.300000,2.300000)); // MET_SC1
+     781           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ASN_BB
+     782           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ASN_SC1
+     783           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // PRO_BB
+     784           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // PRO_SC1
+     785           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // GLN_BB
+     786           0 :   Model_w_.push_back(Vector5d(2.300000,2.300000,2.300000,2.300000,2.300000)); // GLN_SC1
+     787           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // ARG_BB
+     788           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // ARG_SC1
+     789           0 :   Model_w_.push_back(Vector5d(1.800000,1.800000,1.800000,1.800000,1.800000)); // ARG_SC2
+     790           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // SER_BB
+     791           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // SER_SC1
+     792           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // THR_BB
+     793           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // THR_SC1
+     794           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // VAL_BB
+     795           0 :   Model_w_.push_back(Vector5d(1.400000,1.400000,1.400000,1.400000,1.400000)); // VAL_SC1
+     796           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // TRP_BB
+     797           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TRP_SC1
+     798           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // TRP_SC2
+     799           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TRP_SC3
+     800           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TRP_SC4
+     801           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // TRP_SC5
+     802           0 :   Model_w_.push_back(Vector5d(1.900000,1.900000,1.900000,1.900000,1.900000)); // TYR_BB
+     803           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TYR_SC1
+     804           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TYR_SC2
+     805           0 :   Model_w_.push_back(Vector5d(0.900000,0.900000,0.900000,0.900000,0.900000)); // TYR_SC3
+     806           0 :   Model_w_.push_back(Vector5d(0.800000,0.800000,0.800000,0.800000,0.800000)); // TYR_SC4
+     807             :   // cycle on atoms
+     808           0 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     809             :     // get atom name
+     810           0 :     std::string name = moldat->getAtomName(atoms[i]);
+     811             :     // get residue name
+     812           0 :     std::string resname = moldat->getResidueName(atoms[i]);
+     813             :     // type of atoms/bead
+     814             :     std::string type_s;
+     815             :     // Martini model
+     816           0 :     if(martini_) {
+     817           0 :       type_s = resname+"_"+name;
+     818             :       // Atomistic model
+     819             :     } else {
+     820             :       char type;
+     821             :       // get atom type
+     822           0 :       char first = name.at(0);
+     823             :       // GOLDEN RULE: type is first letter, if not a number
+     824           0 :       if (!isdigit(first)) {
+     825             :         type = first;
+     826             :         // otherwise is the second
+     827             :       } else {
+     828           0 :         type = name.at(1);
+     829             :       }
+     830             :       // convert to std::string
+     831           0 :       type_s = std::string(1,type);
+     832             :       // special cases
+     833           0 :       if(name=="SOD" || name=="NA" || name =="Na") type_s = "NA";
+     834           0 :       if(name=="MG"  || name=="Mg")                type_s = "MG";
+     835           0 :       if(name=="CLA" || name=="CL" || name =="Cl") type_s = "CL";
+     836           0 :       if((resname=="CAL" || resname=="CA") && (name=="CAL" || name=="CA" || name =="C0")) type_s = "CA";
+     837           0 :       if(name=="POT" || name=="K")                 type_s = "K";
+     838           0 :       if(name=="ZN"  || name=="Zn")                type_s = "ZN";
+     839             :     }
+     840             :     // check if key in map
+     841           0 :     if(type_map.find(type_s) != type_map.end()) {
+     842             :       // save atom type
+     843           0 :       Model_type_.push_back(type_map[type_s]);
+     844             :       // this will be normalized in the final density
+     845           0 :       Vector5d w = Model_w_[type_map[type_s]];
+     846           0 :       Model_w.push_back(w[0]+w[1]+w[2]+w[3]+w[4]);
+     847             :       // get residue id
+     848           0 :       unsigned ires = moldat->getResidueNumber(atoms[i]);
+     849             :       // and chain
+     850           0 :       std::string c ("*");
+     851           0 :       if(!bfactnoc_) c = moldat->getChainID(atoms[i]);
+     852             :       // define pair residue/chain IDs
+     853             :       std::pair<unsigned,std::string> key = std::make_pair(ires,c);
+     854             :       // add to map between residue/chain and list of atoms
+     855           0 :       Model_resmap_[key].push_back(i);
+     856             :       // and global list of residue/chain per atom
+     857           0 :       Model_res_.push_back(key);
+     858             :       // initialize Bfactor map
+     859           0 :       Model_b_[key] = 0.0;
+     860             :     } else {
+     861           0 :       error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+     862             :     }
+     863             :   }
+     864             :   // create ordered vector of residue-chain IDs
+     865           0 :   for(unsigned i=0; i<Model_res_.size(); ++i) {
+     866             :     std::pair<unsigned,std::string> key = Model_res_[i];
+     867             :     // search in Model_rlist_
+     868           0 :     if(find(Model_rlist_.begin(), Model_rlist_.end(), key) == Model_rlist_.end())
+     869           0 :       Model_rlist_.push_back(key);
+     870             :   }
+     871             :   // return weights
+     872           0 :   return Model_w;
+     873             : }
+     874             : 
+     875             : // read experimental data file in PLUMED format:
+     876           0 : void EMMIVOX::get_exp_data(const std::string &datafile)
+     877             : {
+     878           0 :   Vector pos;
+     879             :   double dens, err;
+     880             :   int idcomp;
+     881             : 
+     882             : // open file
+     883           0 :   IFile *ifile = new IFile();
+     884           0 :   if(ifile->FileExist(datafile)) {
+     885           0 :     ifile->open(datafile);
+     886           0 :     while(ifile->scanField("Id",idcomp)) {
+     887           0 :       ifile->scanField("Pos_0",pos[0]);
+     888           0 :       ifile->scanField("Pos_1",pos[1]);
+     889           0 :       ifile->scanField("Pos_2",pos[2]);
+     890           0 :       ifile->scanField("Density",dens);
+     891           0 :       ifile->scanField("Error",err);
+     892             :       // voxel center
+     893           0 :       Map_m_.push_back(pos);
+     894             :       // experimental density
+     895           0 :       ovdd_.push_back(dens);
+     896             :       // error
+     897           0 :       exp_err_.push_back(err);
+     898             :       // new line
+     899           0 :       ifile->scanField();
+     900             :     }
+     901           0 :     ifile->close();
+     902             :   } else {
+     903           0 :     error("Cannot find DATA_FILE "+datafile+"\n");
+     904             :   }
+     905           0 :   delete ifile;
+     906           0 : }
+     907             : 
+     908           0 : void EMMIVOX::initialize_Bfactor(double reso)
+     909             : {
+     910           0 :   double bfactini = 0.0;
+     911             :   // if doing Bfactor Monte Carlo
+     912           0 :   if(dbfact_>0) {
+     913             :     // initialize B factor based on empirical relation between resolution and average bfactor
+     914             :     // calculated on ~8000 cryo-EM data with resolution < 5 Ang
+     915             :     // Bfact = A*reso**2+B; with A=6.95408 B=-2.45697/100.0 nm^2
+     916           0 :     bfactini = 6.95408*reso*reso - 0.01*2.45697;
+     917             :     // check for min and max
+     918           0 :     bfactini = std::min(bfactmax_, std::max(bfactmin_, bfactini));
+     919             :   }
+     920             :   // set initial Bfactor
+     921           0 :   for(std::map< std::pair<unsigned,std::string>, double>::iterator it=Model_b_.begin(); it!=Model_b_.end(); ++it) {
+     922           0 :     it->second = bfactini;
+     923             :   }
+     924           0 :   log.printf("  experimental map resolution : %3.2f\n", reso);
+     925             :   // if doing Bfactor Monte Carlo
+     926           0 :   if(dbfact_>0) {
+     927           0 :     log.printf("  minimum Bfactor value : %3.2f\n", bfactmin_);
+     928           0 :     log.printf("  maximum Bfactor value : %3.2f\n", bfactmax_);
+     929           0 :     log.printf("  initial Bfactor value : %3.2f\n", bfactini);
+     930             :   }
+     931           0 : }
+     932             : 
+     933             : // prepare auxiliary vectors
+     934           0 : void EMMIVOX::get_auxiliary_vectors()
+     935             : {
+     936             : // number of atoms
+     937           0 :   unsigned natoms = Model_res_.size();
+     938             : // clear lists
+     939           0 :   pref_.clear(); invs2_.clear(); cut_.clear();
+     940             : // resize
+     941           0 :   pref_.resize(natoms); invs2_.resize(natoms); cut_.resize(natoms);
+     942             : // cycle on all atoms
+     943           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     944             :   for(unsigned im=0; im<natoms; ++im) {
+     945             :     // get atom type
+     946             :     unsigned atype = Model_type_[im];
+     947             :     // get residue/chain IDs
+     948             :     std::pair<unsigned,std::string> key = Model_res_[im];
+     949             :     // get bfactor
+     950             :     double bfact = Model_b_[key];
+     951             :     // sigma for 5 gaussians
+     952             :     Vector5d m_s = Model_s_[atype];
+     953             :     // calculate constant quantities
+     954             :     Vector5d pref, invs2;
+     955             :     // calculate cutoff
+     956             :     double n = 0.0;
+     957             :     double d = 0.0;
+     958             :     for(unsigned j=0; j<5; ++j) {
+     959             :       // total value of b
+     960             :       double m_b = m_s[j] + bfact/4.0;
+     961             :       // calculate invs2
+     962             :       invs2[j] = 1.0/(inv_pi2_*m_b);
+     963             :       // prefactor
+     964             :       pref[j]  = cfact_[atype][j] * pow(invs2[j],1.5);
+     965             :       // cutoff
+     966             :       n += pref[j] / invs2[j];
+     967             :       d += pref[j];
+     968             :     }
+     969             :     // put into global lists
+     970             :     pref_[im]  = pref;
+     971             :     invs2_[im] = invs2;
+     972             :     cut_[im] = std::min(nl_dist_cutoff_, sqrt(n/d)*nl_gauss_cutoff_);
+     973             :   }
+     974             :   // push to GPU
+     975           0 :   push_auxiliary_gpu();
+     976           0 : }
+     977             : 
+     978           0 : void EMMIVOX::push_auxiliary_gpu()
+     979             : {
+     980             :   // 1) create vector of pref_ and invs2_
+     981           0 :   int natoms = Model_type_.size();
+     982           0 :   std::vector<double> pref(5*natoms), invs2(5*natoms);
+     983           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     984             :   for(int i=0; i<natoms; ++i) {
+     985             :     for(int j=0; j<5; ++j) {
+     986             :       pref[i+j*natoms]  = pref_[i][j];
+     987             :       invs2[i+j*natoms] = invs2_[i][j];
+     988             :     }
+     989             :   }
+     990             :   // 2) initialize gpu tensors
+     991           0 :   pref_gpu_  = torch::from_blob(pref.data(),  {5,natoms}, torch::kFloat64).clone().to(torch::kFloat32).to(device_t_);
+     992           0 :   invs2_gpu_ = torch::from_blob(invs2.data(), {5,natoms}, torch::kFloat64).clone().to(torch::kFloat32).to(device_t_);
+     993           0 : }
+     994             : 
+     995           0 : void EMMIVOX::get_close_residues()
+     996             : {
+     997             :   // clear neighbor list
+     998           0 :   nl_res_.clear(); nl_res_.resize(Model_rlist_.size());
+     999             : 
+    1000             :   // loop in parallel
+    1001           0 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1002             :   {
+    1003             :     // private variable
+    1004             :     std::vector< std::vector<unsigned> > nl_res_l(Model_rlist_.size());
+    1005             :     // cycle on residues/chains #1
+    1006             :     #pragma omp for
+    1007             :     for(unsigned i=0; i<Model_rlist_.size()-1; ++i) {
+    1008             : 
+    1009             :       // key1: pair of residue/chain IDs
+    1010             :       std::pair<unsigned,std::string> key1 = Model_rlist_[i];
+    1011             : 
+    1012             :       // cycle over residues/chains #2
+    1013             :       for(unsigned j=i+1; j<Model_rlist_.size(); ++j) {
+    1014             : 
+    1015             :         // key2: pair of residue/chain IDs
+    1016             :         std::pair<unsigned,std::string> key2 = Model_rlist_[j];
+    1017             : 
+    1018             :         // set flag neighbor
+    1019             :         bool neigh = false;
+    1020             : 
+    1021             :         // cycle over all the atoms belonging to key1
+    1022             :         for(unsigned im1=0; im1<Model_resmap_[key1].size(); ++im1) {
+    1023             :           // get atom position #1
+    1024             :           Vector pos1 = getPosition(Model_resmap_[key1][im1]);
+    1025             :           // cycle over all the atoms belonging to key2
+    1026             :           for(unsigned im2=0; im2<Model_resmap_[key2].size(); ++im2) {
+    1027             :             // get atom position #2
+    1028             :             Vector pos2 = getPosition(Model_resmap_[key2][im2]);
+    1029             :             // if closer than 0.5 nm, then residues key1 and key2 are neighbors
+    1030             :             if(delta(pos1,pos2).modulo()<0.5) {
+    1031             :               // set neighbors
+    1032             :               neigh = true;
+    1033             :               // and exit
+    1034             :               break;
+    1035             :             }
+    1036             :           }
+    1037             :           // check if neighbor already found
+    1038             :           if(neigh) break;
+    1039             :         }
+    1040             : 
+    1041             :         // if neighbors, add to local list
+    1042             :         if(neigh) {
+    1043             :           nl_res_l[i].push_back(j);
+    1044             :           nl_res_l[j].push_back(i);
+    1045             :         }
+    1046             :       }
+    1047             :     }
+    1048             :     // add to global list
+    1049             :     #pragma omp critical
+    1050             :     {
+    1051             :       for(unsigned i=0; i<nl_res_.size(); ++i)
+    1052             :         nl_res_[i].insert(nl_res_[i].end(), nl_res_l[i].begin(), nl_res_l[i].end());
+    1053             :     }
+    1054             :   }
+    1055           0 : }
+    1056             : 
+    1057           0 : void EMMIVOX::doMonteCarloBfact()
+    1058             : {
+    1059             : // update residue neighbor list
+    1060           0 :   get_close_residues();
+    1061             : 
+    1062             : // cycle over residues/chains
+    1063           0 :   for(unsigned ir=0; ir<Model_rlist_.size(); ++ir) {
+    1064             : 
+    1065             :     // key: pair of residue/chain IDs
+    1066             :     std::pair<unsigned,std::string> key = Model_rlist_[ir];
+    1067             :     // old bfactor
+    1068           0 :     double bfactold = Model_b_[key];
+    1069             : 
+    1070             :     // propose move in bfactor
+    1071           0 :     double bfactnew = bfactold + dbfact_ * ( 2.0 * random_.RandU01() - 1.0 );
+    1072             :     // check boundaries
+    1073           0 :     if(bfactnew > bfactmax_) {bfactnew = 2.0*bfactmax_ - bfactnew;}
+    1074           0 :     if(bfactnew < bfactmin_) {bfactnew = 2.0*bfactmin_ - bfactnew;}
+    1075             : 
+    1076             :     // useful quantities
+    1077             :     std::map<unsigned, double> deltaov;
+    1078             : 
+    1079           0 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1080             :     {
+    1081             :       // private variables
+    1082             :       std::map<unsigned, double> deltaov_l;
+    1083             :       #pragma omp for
+    1084             :       // cycle over all the atoms belonging to key (residue/chain)
+    1085             :       for(unsigned ia=0; ia<Model_resmap_[key].size(); ++ia) {
+    1086             : 
+    1087             :         // get atom id
+    1088             :         unsigned im = Model_resmap_[key][ia];
+    1089             :         // get atom type
+    1090             :         unsigned atype = Model_type_[im];
+    1091             :         // sigma for 5 Gaussians
+    1092             :         Vector5d m_s = Model_s_[atype];
+    1093             :         // prefactors
+    1094             :         Vector5d cfact = cfact_[atype];
+    1095             :         // and position
+    1096             :         Vector pos = getPosition(im);
+    1097             : 
+    1098             :         // cycle on all the neighboring voxels affected by a change in Bfactor
+    1099             :         for(unsigned i=0; i<Model_nb_[im].size(); ++i) {
+    1100             :           // voxel id
+    1101             :           unsigned id = Model_nb_[im][i];
+    1102             :           // get contribution to density in id before change
+    1103             :           double dold = get_overlap(Map_m_[id], pos, cfact, m_s, bfactold);
+    1104             :           // get contribution after change
+    1105             :           double dnew = get_overlap(Map_m_[id], pos, cfact, m_s, bfactnew);
+    1106             :           // update delta density
+    1107             :           deltaov_l[id] += dnew-dold;
+    1108             :         }
+    1109             :       }
+    1110             :       // add to global list
+    1111             :       #pragma omp critical
+    1112             :       {
+    1113             :         for(std::map<unsigned,double>::iterator itov=deltaov_l.begin(); itov!=deltaov_l.end(); ++itov)
+    1114             :           deltaov[itov->first] += itov->second;
+    1115             :       }
+    1116             :     }
+    1117             : 
+    1118             :     // now calculate new and old score
+    1119             :     double old_ene = 0.0;
+    1120             :     double new_ene = 0.0;
+    1121             : 
+    1122             :     // cycle on all affected voxels
+    1123           0 :     for(std::map<unsigned,double>::iterator itov=deltaov.begin(); itov!=deltaov.end(); ++itov) {
+    1124             :       // id of the component
+    1125           0 :       unsigned id = itov->first;
+    1126             :       // new value
+    1127           0 :       double ovmdnew = ovmd_[id]+itov->second;
+    1128             :       // deviations
+    1129           0 :       double devold = scale_ * ovmd_[id] + offset_ - ovdd_[id];
+    1130           0 :       double devnew = scale_ * ovmdnew   + offset_ - ovdd_[id];
+    1131             :       // inverse of sigma_min
+    1132           0 :       double ismin = ismin_[id];
+    1133             :       // scores
+    1134           0 :       if(devold==0.0) {
+    1135           0 :         old_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1136             :       } else {
+    1137           0 :         old_ene += -kbt_ * std::log( 0.5 / devold * erf ( devold * inv_sqrt2_ * ismin ));
+    1138             :       }
+    1139           0 :       if(devnew==0.0) {
+    1140           0 :         new_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1141             :       } else {
+    1142           0 :         new_ene += -kbt_ * std::log( 0.5 / devnew * erf ( devnew * inv_sqrt2_ * ismin ));
+    1143             :       }
+    1144             :     }
+    1145             : 
+    1146             :     // list of neighboring residues
+    1147           0 :     std::vector<unsigned> close = nl_res_[ir];
+    1148             :     // add restraint to keep Bfactors of close residues close
+    1149           0 :     for(unsigned i=0; i<close.size(); ++i) {
+    1150             :       // residue/chain IDs of neighbor
+    1151           0 :       std::pair<unsigned,std::string> keyn = Model_rlist_[close[i]];
+    1152             :       // deviations
+    1153           0 :       double devold = bfactold - Model_b_[keyn];
+    1154           0 :       double devnew = bfactnew - Model_b_[keyn];
+    1155             :       // inverse of sigma_min
+    1156           0 :       double ismin = 1.0 / bfactsig_;
+    1157             :       // scores
+    1158           0 :       if(devold==0.0) {
+    1159           0 :         old_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1160             :       } else {
+    1161           0 :         old_ene += -kbt_ * std::log( 0.5 / devold * erf ( devold * inv_sqrt2_ * ismin ));
+    1162             :       }
+    1163           0 :       if(devnew==0.0) {
+    1164           0 :         new_ene += -kbt_ * std::log( 0.5 * sqrt2_pi_ * ismin );
+    1165             :       } else {
+    1166           0 :         new_ene += -kbt_ * std::log( 0.5 / devnew * erf ( devnew * inv_sqrt2_ * ismin ));
+    1167             :       }
+    1168             :     }
+    1169             : 
+    1170             :     // increment number of trials
+    1171           0 :     MCBtrials_ += 1.0;
+    1172             : 
+    1173             :     // accept or reject
+    1174             :     bool accept = false;
+    1175           0 :     if(bfactemin_) {
+    1176           0 :       if(new_ene < old_ene) accept = true;
+    1177             :     } else {
+    1178           0 :       accept = doAccept(old_ene, new_ene, kbt_);
+    1179             :     }
+    1180             : 
+    1181             :     // in case of acceptance
+    1182           0 :     if(accept) {
+    1183             :       // update acceptance rate
+    1184           0 :       MCBaccept_ += 1.0;
+    1185             :       // update bfactor
+    1186           0 :       Model_b_[key] = bfactnew;
+    1187             :       // change all the ovmd_ affected
+    1188           0 :       for(std::map<unsigned,double>::iterator itov=deltaov.begin(); itov!=deltaov.end(); ++itov)
+    1189           0 :         ovmd_[itov->first] += itov->second;
+    1190             :     }
+    1191             : 
+    1192             :   } // end cycle on bfactors
+    1193             : 
+    1194             : // update auxiliary lists (to update pref_gpu_, invs2_gpu_, and cut_ on CPU/GPU)
+    1195           0 :   get_auxiliary_vectors();
+    1196             : // update neighbor list (new cut_ + update pref_nl_gpu_ and invs2_nl_gpu_ on GPU)
+    1197           0 :   update_neighbor_list();
+    1198             : // recalculate fmod (to update derivatives)
+    1199           0 :   calculate_fmod();
+    1200           0 : }
+    1201             : 
+    1202             : // get overlap
+    1203           0 : double EMMIVOX::get_overlap(const Vector &d_m, const Vector &m_m,
+    1204             :                             const Vector5d &cfact, const Vector5d &m_s, double bfact)
+    1205             : {
+    1206             :   // calculate vector difference
+    1207           0 :   Vector md = delta(m_m, d_m);
+    1208             :   // norm squared
+    1209           0 :   double md2 = md[0]*md[0]+md[1]*md[1]+md[2]*md[2];
+    1210             :   // cycle on 5 Gaussians
+    1211             :   double ov_tot = 0.0;
+    1212           0 :   for(unsigned j=0; j<5; ++j) {
+    1213             :     // total value of b
+    1214           0 :     double m_b = m_s[j]+bfact/4.0;
+    1215             :     // calculate invs2
+    1216           0 :     double invs2 = 1.0/(inv_pi2_*m_b);
+    1217             :     // final calculation
+    1218           0 :     ov_tot += cfact[j] * pow(invs2, 1.5) * std::exp(-0.5 * md2 * invs2);
+    1219             :   }
+    1220           0 :   return ov_tot;
+    1221             : }
+    1222             : 
+    1223           0 : void EMMIVOX::update_neighbor_sphere()
+    1224             : {
+    1225             :   // number of atoms
+    1226           0 :   unsigned natoms = Model_type_.size();
+    1227             :   // clear neighbor sphere
+    1228             :   ns_.clear();
+    1229             :   // store reference positions
+    1230           0 :   refpos_ = getPositions();
+    1231             : 
+    1232             :   // cycle on voxels - in parallel
+    1233           0 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1234             :   {
+    1235             :     // private variables
+    1236             :     std::vector< std::pair<unsigned,unsigned> > ns_l;
+    1237             :     #pragma omp for
+    1238             :     for(unsigned id=0; id<ovdd_.size(); ++id) {
+    1239             :       // grid point
+    1240             :       Vector d_m = Map_m_[id];
+    1241             :       // cycle on atoms
+    1242             :       for(unsigned im=0; im<natoms; ++im) {
+    1243             :         // calculate distance
+    1244             :         double dist = delta(getPosition(im), d_m).modulo();
+    1245             :         // add to local list
+    1246             :         if(dist<=2.0*cut_[im]) ns_l.push_back(std::make_pair(id,im));
+    1247             :       }
+    1248             :     }
+    1249             :     // add to global list
+    1250             :     #pragma omp critical
+    1251             :     ns_.insert(ns_.end(), ns_l.begin(), ns_l.end());
+    1252             :   }
+    1253           0 : }
+    1254             : 
+    1255           0 : bool EMMIVOX::do_neighbor_sphere()
+    1256             : {
+    1257           0 :   std::vector<double> dist(getPositions().size());
+    1258             :   bool update = false;
+    1259             : 
+    1260             : // calculate displacement
+    1261           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1262             :   for(unsigned im=0; im<dist.size(); ++im) {
+    1263             :     dist[im] = delta(getPosition(im),refpos_[im]).modulo()/cut_[im];
+    1264             :   }
+    1265             : 
+    1266             : // check if update or not
+    1267           0 :   double maxdist = *max_element(dist.begin(), dist.end());
+    1268           0 :   if(maxdist>=1.0) update=true;
+    1269             : 
+    1270             : // return if update or not
+    1271           0 :   return update;
+    1272             : }
+    1273             : 
+    1274           0 : void EMMIVOX::update_neighbor_list()
+    1275             : {
+    1276             :   // number of atoms
+    1277           0 :   unsigned natoms = Model_type_.size();
+    1278             :   // clear neighbor list
+    1279             :   nl_.clear();
+    1280             : 
+    1281             :   // cycle on neighbour sphere - in parallel
+    1282           0 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1283             :   {
+    1284             :     // private variables
+    1285             :     std::vector< std::pair<unsigned,unsigned> > nl_l;
+    1286             :     #pragma omp for
+    1287             :     for(unsigned long long i=0; i<ns_.size(); ++i) {
+    1288             :       // calculate distance
+    1289             :       double dist = delta(Map_m_[ns_[i].first], getPosition(ns_[i].second)).modulo();
+    1290             :       // add to local neighbour list
+    1291             :       if(dist<=cut_[ns_[i].second]) nl_l.push_back(ns_[i]);
+    1292             :     }
+    1293             :     // add to global list
+    1294             :     #pragma omp critical
+    1295             :     nl_.insert(nl_.end(), nl_l.begin(), nl_l.end());
+    1296             :   }
+    1297             : 
+    1298             :   // new dimension of neighbor list
+    1299             :   unsigned long long nl_size = nl_.size();
+    1300             :   // now resize derivatives
+    1301           0 :   ovmd_der_.resize(nl_size);
+    1302             : 
+    1303             :   // in case of B-factors sampling - at the right step
+    1304           0 :   if(dbfact_>0 && getStep()%MCBstride_==0) {
+    1305             :     // clear vectors
+    1306           0 :     Model_nb_.clear(); Model_nb_.resize(natoms);
+    1307             :     // cycle over the neighbor list to creat a list of voxels per atom
+    1308           0 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1309             :     {
+    1310             :       // private variables
+    1311             :       std::vector< std::vector<unsigned> > Model_nb_l(natoms);
+    1312             :       #pragma omp for
+    1313             :       for(unsigned long long i=0; i<nl_size; ++i) {
+    1314             :         Model_nb_l[nl_[i].second].push_back(nl_[i].first);
+    1315             :       }
+    1316             :       // add to global list
+    1317             :       #pragma omp critical
+    1318             :       {
+    1319             :         for(unsigned i=0; i<natoms; ++i)
+    1320             :           Model_nb_[i].insert(Model_nb_[i].end(), Model_nb_l[i].begin(), Model_nb_l[i].end());
+    1321             :       }
+    1322             :     }
+    1323             :   }
+    1324             : 
+    1325             :   // transfer data to gpu
+    1326           0 :   update_gpu();
+    1327           0 : }
+    1328             : 
+    1329           0 : void EMMIVOX::update_gpu()
+    1330             : {
+    1331             :   // dimension of neighbor list
+    1332             :   long long nl_size = nl_.size();
+    1333             :   // create useful vectors
+    1334           0 :   std::vector<int> nl_id(nl_size), nl_im(nl_size);
+    1335           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1336             :   for(unsigned long long i=0; i<nl_size; ++i) {
+    1337             :     nl_id[i] = static_cast<int>(nl_[i].first);
+    1338             :     nl_im[i] = static_cast<int>(nl_[i].second);
+    1339             :   }
+    1340             :   // create tensors on device
+    1341           0 :   nl_id_gpu_ = torch::from_blob(nl_id.data(), {nl_size}, torch::kInt32).clone().to(device_t_);
+    1342           0 :   nl_im_gpu_ = torch::from_blob(nl_im.data(), {nl_size}, torch::kInt32).clone().to(device_t_);
+    1343             :   // now we need to create pref_nl_gpu_ [5,nl_size]
+    1344           0 :   pref_nl_gpu_  = torch::index_select(pref_gpu_,1,nl_im_gpu_);
+    1345             :   // and invs2_nl_gpu_ [5,nl_size]
+    1346           0 :   invs2_nl_gpu_ = torch::index_select(invs2_gpu_,1,nl_im_gpu_);
+    1347             :   // and Map_m_nl_gpu_ [3,nl_size]
+    1348           0 :   Map_m_nl_gpu_ = torch::index_select(Map_m_gpu_,1,nl_id_gpu_);
+    1349           0 : }
+    1350             : 
+    1351           0 : void EMMIVOX::prepare()
+    1352             : {
+    1353           0 :   if(getExchangeStep()) first_time_=true;
+    1354           0 : }
+    1355             : 
+    1356             : // calculate forward model on gpu
+    1357           0 : void EMMIVOX::calculate_fmod()
+    1358             : {
+    1359             :   // number of atoms
+    1360           0 :   int natoms = Model_type_.size();
+    1361             :   // number of data points
+    1362           0 :   int nd = ovdd_.size();
+    1363             : 
+    1364             :   // fill positions in in parallel
+    1365           0 :   std::vector<double> posg(3*natoms);
+    1366           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1367             :   for (int i=0; i<natoms; ++i) {
+    1368             :     // fill vectors
+    1369             :     posg[i]          = getPosition(i)[0];
+    1370             :     posg[i+natoms]   = getPosition(i)[1];
+    1371             :     posg[i+2*natoms] = getPosition(i)[2];
+    1372             :   }
+    1373             :   // transfer positions to pos_gpu [3,natoms]
+    1374           0 :   torch::Tensor pos_gpu = torch::from_blob(posg.data(), {3,natoms}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+    1375             :   // create pos_nl_gpu_ [3,nl_size]
+    1376           0 :   torch::Tensor pos_nl_gpu = torch::index_select(pos_gpu,1,nl_im_gpu_);
+    1377             :   // calculate vector difference [3,nl_size]
+    1378           0 :   torch::Tensor md = Map_m_nl_gpu_ - pos_nl_gpu;
+    1379             :   // calculate norm squared by column [1,nl_size]
+    1380           0 :   torch::Tensor md2 = torch::sum(md*md,0);
+    1381             :   // calculate density [5,nl_size]
+    1382           0 :   torch::Tensor ov = pref_nl_gpu_ * torch::exp(-0.5 * md2 * invs2_nl_gpu_);
+    1383             :   // and derivatives [5,nl_size]
+    1384           0 :   ovmd_der_gpu_ = invs2_nl_gpu_ * ov;
+    1385             :   // sum density over 5 columns [1,nl_size]
+    1386           0 :   ov = torch::sum(ov,0);
+    1387             :   // sum contributions from the same atom
+    1388           0 :   auto options = torch::TensorOptions().device(device_t_).dtype(torch::kFloat32);
+    1389           0 :   ovmd_gpu_ = torch::zeros({nd}, options);
+    1390           0 :   ovmd_gpu_.index_add_(0, nl_id_gpu_, ov);
+    1391             :   // sum derivatives over 5 rows [1,nl_size] and multiply by md [3,nl_size]
+    1392           0 :   ovmd_der_gpu_ = md * torch::sum(ovmd_der_gpu_,0);
+    1393             : 
+    1394             :   // in case of metainference: average them across replicas
+    1395           0 :   if(!no_aver_ && nrep_>1) {
+    1396             :     // communicate ovmd_gpu_ to CPU [1, nd]
+    1397           0 :     torch::Tensor ovmd_cpu = ovmd_gpu_.detach().to(torch::kCPU).to(torch::kFloat64);
+    1398             :     // and put them in ovmd_
+    1399           0 :     ovmd_ = std::vector<double>(ovmd_cpu.data_ptr<double>(), ovmd_cpu.data_ptr<double>() + ovmd_cpu.numel());
+    1400             :     // sum across replicas
+    1401           0 :     multi_sim_comm.Sum(&ovmd_[0], nd);
+    1402             :     // and divide by number of replicas
+    1403           0 :     double escale = 1.0 / static_cast<double>(nrep_);
+    1404           0 :     for(int i=0; i<nd; ++i) ovmd_[i] *= escale;
+    1405             :     // put back on device
+    1406           0 :     ovmd_gpu_ = torch::from_blob(ovmd_.data(), {nd}, torch::kFloat64).to(torch::kFloat32).to(device_t_);
+    1407             :   }
+    1408             : 
+    1409             :   // communicate back model density
+    1410             :   // this is needed only in certain situations
+    1411           0 :   long int step = getStep();
+    1412             :   bool do_comm = false;
+    1413           0 :   if(mapstride_>0 && step%mapstride_==0) do_comm = true;
+    1414           0 :   if(dbfact_>0    && step%MCBstride_==0) do_comm = true;
+    1415           0 :   if(do_corr_) do_comm = true;
+    1416             :   // in case of metainference: already communicated
+    1417           0 :   if(!no_aver_ && nrep_>1) do_comm = false;
+    1418           0 :   if(do_comm) {
+    1419             :     // communicate ovmd_gpu_ to CPU [1, nd]
+    1420           0 :     torch::Tensor ovmd_cpu = ovmd_gpu_.detach().to(torch::kCPU).to(torch::kFloat64);
+    1421             :     // and put them in ovmd_
+    1422           0 :     ovmd_ = std::vector<double>(ovmd_cpu.data_ptr<double>(), ovmd_cpu.data_ptr<double>() + ovmd_cpu.numel());
+    1423             :   }
+    1424           0 : }
+    1425             : 
+    1426             : // calculate score
+    1427           0 : void EMMIVOX::calculate_score()
+    1428             : {
+    1429             :   // number of atoms
+    1430           0 :   int natoms = Model_type_.size();
+    1431             : 
+    1432             :   // calculate deviation model/data [1, nd]
+    1433           0 :   torch::Tensor dev = scale_ * ovmd_gpu_ + offset_ - ovdd_gpu_;
+    1434             :   // error function [1, nd]
+    1435           0 :   torch::Tensor errf = torch::erf( dev * inv_sqrt2_ * ismin_gpu_ );
+    1436             :   // take care of dev = zero
+    1437           0 :   torch::Tensor zeros_d = torch::ne(dev, 0.0);
+    1438             :   // redefine dev
+    1439           0 :   dev = dev * zeros_d + eps_ * torch::logical_not(zeros_d);
+    1440             :   // take care of errf = zero
+    1441           0 :   torch::Tensor zeros_e = torch::ne(errf, 0.0);
+    1442             :   // redefine errf
+    1443           0 :   errf = errf * zeros_e + eps_ * torch::logical_not(zeros_e);
+    1444             :   // logical AND: both dev and errf different from zero
+    1445             :   torch::Tensor zeros = torch::logical_and(zeros_d, zeros_e);
+    1446             :   // energy - with limit dev going to zero
+    1447           0 :   torch::Tensor ene = 0.5 * ( errf / dev * zeros + torch::logical_not(zeros) * sqrt2_pi_ *  ismin_gpu_);
+    1448             :   // logarithm and sum
+    1449           0 :   ene = -kbt_ * torch::sum(torch::log(ene));
+    1450             :   // and derivatives [1, nd]
+    1451           0 :   torch::Tensor d_der = -kbt_ * zeros * ( sqrt2_pi_ * torch::exp( -0.5 * dev * dev * ismin_gpu_ * ismin_gpu_ ) * ismin_gpu_ / errf - 1.0 / dev );
+    1452             :   // tensor for derivatives wrt atoms [1, nl_size]
+    1453           0 :   torch::Tensor der_gpu = torch::index_select(d_der,0,nl_id_gpu_);
+    1454             :   // multiply by ovmd_der_gpu_ and scale [3, nl_size]
+    1455           0 :   der_gpu = ovmd_der_gpu_ * scale_ * der_gpu;
+    1456             :   // sum contributions for each atom
+    1457           0 :   auto options = torch::TensorOptions().device(device_t_).dtype(torch::kFloat32);
+    1458           0 :   torch::Tensor atoms_der_gpu = torch::zeros({3,natoms}, options);
+    1459           0 :   atoms_der_gpu.index_add_(1, nl_im_gpu_, der_gpu);
+    1460             : 
+    1461             :   // FINAL STUFF
+    1462             :   //
+    1463             :   // 1) communicate total energy to CPU
+    1464           0 :   torch::Tensor ene_cpu = ene.detach().to(torch::kCPU).to(torch::kFloat64);
+    1465           0 :   ene_ = *ene_cpu.data_ptr<double>();
+    1466             :   // with marginal, simply multiply by number of replicas!
+    1467           0 :   if(!no_aver_ && nrep_>1) ene_ *= static_cast<double>(nrep_);
+    1468             :   //
+    1469             :   // 2) communicate derivatives to CPU
+    1470           0 :   torch::Tensor atom_der_cpu = atoms_der_gpu.detach().to(torch::kCPU).to(torch::kFloat64);
+    1471             :   // convert to std::vector<double>
+    1472           0 :   std::vector<double> atom_der = std::vector<double>(atom_der_cpu.data_ptr<double>(), atom_der_cpu.data_ptr<double>() + atom_der_cpu.numel());
+    1473             :   // and put in atom_der_
+    1474           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1475             :   for(int i=0; i<natoms; ++i) {
+    1476             :     atom_der_[i] = Vector(atom_der[i],atom_der[i+natoms],atom_der[i+2*natoms]);
+    1477             :   }
+    1478             :   //
+    1479             :   // 3) calculate virial on CPU
+    1480           0 :   Tensor virial;
+    1481             :   // declare omp reduction for Tensors
+    1482             :   #pragma omp declare reduction( sumTensor : Tensor : omp_out += omp_in )
+    1483             : 
+    1484           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads()) reduction (sumTensor : virial)
+    1485             :   for(int i=0; i<natoms; ++i) {
+    1486             :     virial += Tensor(getPosition(i), -atom_der_[i]);
+    1487             :   }
+    1488             :   // store virial
+    1489           0 :   virial_ = virial;
+    1490           0 : }
+    1491             : 
+    1492           0 : void EMMIVOX::calculate()
+    1493             : {
+    1494             :   // get time step
+    1495           0 :   long int step = getStep();
+    1496             : 
+    1497             :   // set temperature value
+    1498           0 :   getPntrToComponent("kbt")->set(kbt_);
+    1499             : 
+    1500             :   // neighbor list update
+    1501           0 :   if(first_time_ || getExchangeStep() || step%nl_stride_==0) {
+    1502             :     // check if time to update neighbor sphere
+    1503             :     bool update = false;
+    1504           0 :     if(first_time_ || getExchangeStep()) update = true;
+    1505           0 :     else update = do_neighbor_sphere();
+    1506             :     // update neighbor sphere
+    1507           0 :     if(update) update_neighbor_sphere();
+    1508             :     // update neighbor list
+    1509           0 :     update_neighbor_list();
+    1510             :     // set flag
+    1511           0 :     first_time_=false;
+    1512             :   }
+    1513             : 
+    1514             :   // calculate forward model
+    1515           0 :   calculate_fmod();
+    1516             : 
+    1517             :   // Monte Carlo on bfactors
+    1518           0 :   if(dbfact_>0) {
+    1519             :     double acc = 0.0;
+    1520             :     // do Monte Carlo
+    1521           0 :     if(step%MCBstride_==0 && !getExchangeStep() && step>0) doMonteCarloBfact();
+    1522             :     // calculate acceptance ratio
+    1523           0 :     if(MCBtrials_>0) acc = MCBaccept_ / MCBtrials_;
+    1524             :     // set value
+    1525           0 :     getPntrToComponent("accB")->set(acc);
+    1526             :   }
+    1527             : 
+    1528             :   // calculate score
+    1529           0 :   calculate_score();
+    1530             : 
+    1531             :   // set score, virial, and derivatives
+    1532           0 :   Value* score = getPntrToComponent("scoreb");
+    1533           0 :   score->set(ene_);
+    1534           0 :   setBoxDerivatives(score, virial_);
+    1535           0 :   #pragma omp parallel for
+    1536             :   for(unsigned i=0; i<atom_der_.size(); ++i) setAtomsDerivatives(score, i, atom_der_[i]);
+    1537             :   // set scale and offset value
+    1538           0 :   getPntrToComponent("scale")->set(scale_);
+    1539           0 :   getPntrToComponent("offset")->set(offset_);
+    1540             :   // calculate correlation coefficient
+    1541           0 :   if(do_corr_) calculate_corr();
+    1542             :   // PRINT other quantities to files
+    1543             :   // - status file
+    1544           0 :   if(step%statusstride_==0) print_status(step);
+    1545             :   // - density file
+    1546           0 :   if(mapstride_>0 && step%mapstride_==0) write_model_density(step);
+    1547           0 : }
+    1548             : 
+    1549           0 : void EMMIVOX::calculate_corr()
+    1550             : {
+    1551             : // number of data points
+    1552           0 :   double nd = static_cast<double>(ovdd_.size());
+    1553             : // average ovmd_ and ovdd_
+    1554           0 :   double ave_md = std::accumulate(ovmd_.begin(), ovmd_.end(), 0.) / nd;
+    1555           0 :   double ave_dd = std::accumulate(ovdd_.begin(), ovdd_.end(), 0.) / nd;
+    1556             : // calculate correlation
+    1557             :   double num = 0.;
+    1558             :   double den1 = 0.;
+    1559             :   double den2 = 0.;
+    1560           0 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads()) reduction( + : num, den1, den2)
+    1561             :   for(unsigned i=0; i<ovdd_.size(); ++i) {
+    1562             :     double md = ovmd_[i]-ave_md;
+    1563             :     double dd = ovdd_[i]-ave_dd;
+    1564             :     num  += md*dd;
+    1565             :     den1 += md*md;
+    1566             :     den2 += dd*dd;
+    1567             :   }
+    1568             : // correlation coefficient
+    1569           0 :   double cc = num / sqrt(den1*den2);
+    1570             : // set plumed
+    1571           0 :   getPntrToComponent("corr")->set(cc);
+    1572           0 : }
+    1573             : 
+    1574             : 
+    1575             : }
+    1576             : }
+    1577             : 
+    1578             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/FretEfficiency.cpp.func-sort-c.html b/coverage/isdb/FretEfficiency.cpp.func-sort-c.html new file mode 100644 index 000000000000..b963d98e4395 --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/FretEfficiency.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - FretEfficiency.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343694.4 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb14FretEfficiencyC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb14FretEfficiencyC1ERKNS_13ActionOptionsE14
_ZN4PLMD4isdb14FretEfficiency16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4isdb14FretEfficiency9calculateEv238
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/FretEfficiency.cpp.func.html b/coverage/isdb/FretEfficiency.cpp.func.html new file mode 100644 index 000000000000..96673a28bbff --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/FretEfficiency.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - FretEfficiency.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343694.4 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb14FretEfficiency16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4isdb14FretEfficiency9calculateEv238
_ZN4PLMD4isdb14FretEfficiencyC1ERKNS_13ActionOptionsE14
_ZN4PLMD4isdb14FretEfficiencyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/FretEfficiency.cpp.gcov.html b/coverage/isdb/FretEfficiency.cpp.gcov.html new file mode 100644 index 000000000000..467226de1339 --- /dev/null +++ b/coverage/isdb/FretEfficiency.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + + LCOV - plumed test coverage - isdb/FretEfficiency.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - FretEfficiency.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:343694.4 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "colvar/Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Pbc.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace isdb {
+      32             : 
+      33             : //+PLUMEDOC ISDB_COLVAR FRET
+      34             : /*
+      35             : Calculates the FRET efficiency between a pair of atoms.
+      36             : The efficiency is calculated using the Forster relation:
+      37             : 
+      38             : \f[
+      39             : E=\frac{1}{1+(R/R_0)^6}
+      40             : \f]
+      41             : 
+      42             : where \f$R\f$ is the distance and \f$R_0\f$ is the Forster radius.
+      43             : 
+      44             : By default the distance is computed taking into account periodic
+      45             : boundary conditions. This behavior can be changed with the NOPBC flag.
+      46             : 
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : The following input tells plumed to print the FRET efficiencies
+      51             : calculated as a function of the distance between atoms 3 and 5 and
+      52             : the distance between atoms 2 and 4.
+      53             : \plumedfile
+      54             : fe1:  FRET ATOMS=3,5 R0=5.5
+      55             : fe2:  FRET ATOMS=2,4 R0=5.5
+      56             : PRINT ARG=fe1,fe2
+      57             : \endplumedfile
+      58             : 
+      59             : The following input computes the FRET efficiency calculated on the
+      60             : terminal atoms of a polymer
+      61             : of 100 atoms and keeps it at a value around 0.5.
+      62             : \plumedfile
+      63             : WHOLEMOLECULES ENTITY0=1-100
+      64             : fe: FRET ATOMS=1,100 R0=5.5 NOPBC
+      65             : RESTRAINT ARG=fe KAPPA=100 AT=0.5
+      66             : \endplumedfile
+      67             : 
+      68             : Notice that NOPBC is used
+      69             : to be sure that if the distance is larger than half the simulation
+      70             : box the distance is compute properly. Also notice that, since many MD
+      71             : codes break molecules across cell boundary, it might be necessary to
+      72             : use the \ref WHOLEMOLECULES keyword (also notice that it should be
+      73             : _before_ FRET).
+      74             : Just be sure that the ordered list provide to WHOLEMOLECULES has the following
+      75             : properties:
+      76             : - Consecutive atoms should be closer than half-cell throughout the entire simulation.
+      77             : - Atoms required later for the distance (e.g. 1 and 100) should be included in the list
+      78             : 
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : 
+      82             : class FretEfficiency : public Colvar {
+      83             :   bool pbc;
+      84             :   double R0_;
+      85             : 
+      86             : public:
+      87             :   static void registerKeywords( Keywords& keys );
+      88             :   explicit FretEfficiency(const ActionOptions&);
+      89             : // active methods:
+      90             :   void calculate() override;
+      91             : };
+      92             : 
+      93             : PLUMED_REGISTER_ACTION(FretEfficiency,"FRET")
+      94             : 
+      95          16 : void FretEfficiency::registerKeywords( Keywords& keys ) {
+      96          16 :   Colvar::registerKeywords( keys );
+      97          32 :   keys.add("atoms","ATOMS","the pair of atom that we are calculating the distance between");
+      98          32 :   keys.add("compulsory","R0","The value of the Forster radius.");
+      99          16 : }
+     100             : 
+     101          14 : FretEfficiency::FretEfficiency(const ActionOptions&ao):
+     102             :   PLUMED_COLVAR_INIT(ao),
+     103          14 :   pbc(true)
+     104             : {
+     105             :   std::vector<AtomNumber> atoms;
+     106          28 :   parseAtomList("ATOMS",atoms);
+     107          14 :   if(atoms.size()!=2)
+     108           0 :     error("Number of specified atoms should be 2");
+     109          14 :   parse("R0",R0_);
+     110          14 :   bool nopbc=!pbc;
+     111          14 :   parseFlag("NOPBC",nopbc);
+     112          14 :   pbc=!nopbc;
+     113          14 :   checkRead();
+     114             : 
+     115          14 :   log.printf("  between atoms %d %d\n",atoms[0].serial(),atoms[1].serial());
+     116          14 :   log.printf("  with Forster radius set to %lf\n",R0_);
+     117             : 
+     118          14 :   if(pbc) log.printf("  using periodic boundary conditions\n");
+     119           0 :   else    log.printf("  without periodic boundary conditions\n");
+     120             : 
+     121          28 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     122             : 
+     123          14 :   addValueWithDerivatives();
+     124          14 :   setNotPeriodic();
+     125             : 
+     126          14 :   requestAtoms(atoms);
+     127          14 : }
+     128             : 
+     129             : 
+     130             : // calculator
+     131         238 : void FretEfficiency::calculate() {
+     132             : 
+     133         238 :   if(pbc) makeWhole();
+     134             : 
+     135         238 :   Vector distance=delta(getPosition(0),getPosition(1));
+     136         238 :   const double dist_mod=distance.modulo();
+     137         238 :   const double inv_dist_mod=1.0/dist_mod;
+     138             : 
+     139         238 :   const double ratiosix=std::pow(dist_mod/R0_,6);
+     140         238 :   const double fret_eff = 1.0/(1.0+ratiosix);
+     141             : 
+     142         238 :   const double der = -6.0*fret_eff*fret_eff*ratiosix*inv_dist_mod;
+     143             : 
+     144         238 :   setAtomsDerivatives(0,-inv_dist_mod*der*distance);
+     145         476 :   setAtomsDerivatives(1, inv_dist_mod*der*distance);
+     146             :   setBoxDerivativesNoPbc();
+     147         238 :   setValue(fret_eff);
+     148             : 
+     149         238 : }
+     150             : 
+     151             : }
+     152             : }
+     153             : 
+     154             : 
+     155             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Jcoupling.cpp.func-sort-c.html b/coverage/isdb/Jcoupling.cpp.func-sort-c.html new file mode 100644 index 000000000000..a0d6ae8b6f0b --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Jcoupling.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Jcoupling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16017293.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb9JCouplingC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb9JCouplingC1ERKNS_13ActionOptionsE6
_ZN4PLMD4isdb9JCoupling16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD4isdb9JCoupling6updateEv16
_ZN4PLMD4isdb9JCoupling9calculateEv16
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Jcoupling.cpp.func.html b/coverage/isdb/Jcoupling.cpp.func.html new file mode 100644 index 000000000000..aa40a9d681e6 --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Jcoupling.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Jcoupling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16017293.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb9JCoupling16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD4isdb9JCoupling6updateEv16
_ZN4PLMD4isdb9JCoupling9calculateEv16
_ZN4PLMD4isdb9JCouplingC1ERKNS_13ActionOptionsE6
_ZN4PLMD4isdb9JCouplingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Jcoupling.cpp.gcov.html b/coverage/isdb/Jcoupling.cpp.gcov.html new file mode 100644 index 000000000000..cab0edc9b1fb --- /dev/null +++ b/coverage/isdb/Jcoupling.cpp.gcov.html @@ -0,0 +1,471 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Jcoupling.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Jcoupling.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16017293.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetainferenceBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Pbc.h"
+      25             : #include "tools/Torsion.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace isdb {
+      29             : 
+      30             : //+PLUMEDOC ISDB_COLVAR JCOUPLING
+      31             : /*
+      32             : Calculates \f$^3J\f$ coupling constants for a dihedral angle.
+      33             : 
+      34             : The J-coupling between two atoms is given by the Karplus relation:
+      35             : 
+      36             : \f[
+      37             : ^3J(\theta)=A\cos^2(\theta+\Delta\theta)+B\cos(\theta+\Delta\theta)+C
+      38             : \f]
+      39             : 
+      40             : where \f$A\f$, \f$B\f$ and \f$C\f$ are the Karplus parameters and \f$\Delta\theta\f$ is an additional constant
+      41             : added on to the dihedral angle \f$\theta\f$. The Karplus parameters are determined empirically and are dependent
+      42             : on the type of J-coupling.
+      43             : 
+      44             : This collective variable computes the J-couplings for a set of atoms defining a dihedral angle. You can specify
+      45             : the atoms involved using the \ref MOLINFO notation. You can also specify the experimental couplings using the
+      46             :  COUPLING keywords. These will be included in the output. You must choose the type of
+      47             : coupling using the type keyword, you can also supply custom Karplus parameters using TYPE=CUSTOM and the A, B, C
+      48             : and SHIFT keywords. You will need to make sure you are using the correct dihedral angle:
+      49             : 
+      50             : - Ha-N: \f$\psi\f$
+      51             : - Ha-HN: \f$\phi\f$
+      52             : - N-C\f$\gamma\f$: \f$\chi_1\f$
+      53             : - CO-C\f$\gamma\f$: \f$\chi_1\f$
+      54             : 
+      55             : J-couplings can be used to calculate a Metainference score using the internal keyword DOSCORE and all the options
+      56             : of \ref METAINFERENCE .
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : In the following example we calculate the Ha-N J-coupling from a set of atoms involved in
+      61             : dihedral \f$\psi\f$ angles in the peptide backbone. We also add the experimental data points and compute
+      62             : the correlation and other measures and finally print the results.
+      63             : 
+      64             : \plumedfile
+      65             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      66             : MOLINFO MOLTYPE=protein STRUCTURE=peptide.pdb
+      67             : WHOLEMOLECULES ENTITY0=1-111
+      68             : 
+      69             : JCOUPLING ...
+      70             :     TYPE=HAN
+      71             :     ATOMS1=@psi-2 COUPLING1=-0.49
+      72             :     ATOMS2=@psi-4 COUPLING2=-0.54
+      73             :     ATOMS3=@psi-5 COUPLING3=-0.53
+      74             :     ATOMS4=@psi-7 COUPLING4=-0.39
+      75             :     ATOMS5=@psi-8 COUPLING5=-0.39
+      76             :     LABEL=jhan
+      77             : ... JCOUPLING
+      78             : 
+      79             : jhanst: STATS ARG=(jhan\.j-.*) PARARG=(jhan\.exp-.*)
+      80             : 
+      81             : PRINT ARG=jhanst.*,jhan.* FILE=COLVAR STRIDE=100
+      82             : \endplumedfile
+      83             : 
+      84             : */
+      85             : //+ENDPLUMEDOC
+      86             : 
+      87             : class JCoupling :
+      88             :   public MetainferenceBase
+      89             : {
+      90             : private:
+      91             :   bool pbc;
+      92             :   enum { HAN, HAHN, CCG, NCG, CUSTOM };
+      93             :   unsigned ncoupl_;
+      94             :   double ka_;
+      95             :   double kb_;
+      96             :   double kc_;
+      97             :   double kshift_;
+      98             : 
+      99             : public:
+     100             :   static void registerKeywords(Keywords& keys);
+     101             :   explicit JCoupling(const ActionOptions&);
+     102             :   void calculate() override;
+     103             :   void update() override;
+     104             : };
+     105             : 
+     106             : PLUMED_REGISTER_ACTION(JCoupling, "JCOUPLING")
+     107             : 
+     108           8 : void JCoupling::registerKeywords(Keywords& keys) {
+     109           8 :   componentsAreNotOptional(keys);
+     110           8 :   MetainferenceBase::registerKeywords(keys);
+     111          16 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     112          16 :   keys.add("numbered", "ATOMS", "the 4 atoms involved in each of the bonds for which you wish to calculate the J-coupling. "
+     113             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one J-coupling will be "
+     114             :            "calculated for each ATOMS keyword you specify.");
+     115          16 :   keys.reset_style("ATOMS", "atoms");
+     116          16 :   keys.add("compulsory", "TYPE", "Type of J-coupling to compute (HAN,HAHN,CCG,NCG,CUSTOM)");
+     117          16 :   keys.add("optional", "A", "Karplus parameter A");
+     118          16 :   keys.add("optional", "B", "Karplus parameter B");
+     119          16 :   keys.add("optional", "C", "Karplus parameter C");
+     120          16 :   keys.add("optional", "SHIFT", "Angle shift in radians");
+     121          16 :   keys.add("numbered", "COUPLING", "Add an experimental value for each coupling");
+     122          16 :   keys.addOutputComponent("j", "default", "the calculated J-coupling");
+     123          16 :   keys.addOutputComponent("exp", "COUPLING", "the experimental J-coupling");
+     124           8 : }
+     125             : 
+     126           6 : JCoupling::JCoupling(const ActionOptions&ao):
+     127             :   PLUMED_METAINF_INIT(ao),
+     128           6 :   pbc(true)
+     129             : {
+     130           6 :   bool nopbc = !pbc;
+     131           6 :   parseFlag("NOPBC", nopbc);
+     132           6 :   pbc =! nopbc;
+     133             : 
+     134             :   // Read in the atoms
+     135             :   std::vector<AtomNumber> t, atoms;
+     136           6 :   for (int i = 1; ; ++i) {
+     137          68 :     parseAtomList("ATOMS", i, t );
+     138          34 :     if (t.empty()) {
+     139             :       break;
+     140             :     }
+     141             : 
+     142          28 :     if (t.size() != 4) {
+     143             :       std::string ss;
+     144           0 :       Tools::convert(i, ss);
+     145           0 :       error("ATOMS" + ss + " keyword has the wrong number of atoms");
+     146             :     }
+     147             : 
+     148             :     // This makes the distance calculation easier later on (see Torsion implementation)
+     149          28 :     atoms.push_back(t[0]);
+     150          28 :     atoms.push_back(t[1]);
+     151          28 :     atoms.push_back(t[1]);
+     152          28 :     atoms.push_back(t[2]);
+     153          28 :     atoms.push_back(t[2]);
+     154          28 :     atoms.push_back(t[3]);
+     155          28 :     t.resize(0);
+     156          28 :   }
+     157             : 
+     158             :   // We now have 6 atoms per datapoint
+     159           6 :   ncoupl_ = atoms.size()/6;
+     160             : 
+     161             :   // Parse J-Coupling type, this will determine the Karplus parameters
+     162             :   unsigned jtype_ = CUSTOM;
+     163             :   std::string string_type;
+     164          12 :   parse("TYPE", string_type);
+     165           6 :   if(string_type == "HAN") {
+     166             :     jtype_ = HAN;
+     167           5 :   } else if(string_type == "HAHN") {
+     168             :     jtype_ = HAHN;
+     169           2 :   } else if(string_type == "CCG") {
+     170             :     jtype_ = CCG;
+     171           1 :   } else if(string_type == "NCG") {
+     172             :     jtype_ = NCG;
+     173           0 :   } else if(string_type == "CUSTOM") {
+     174             :     jtype_ = CUSTOM;
+     175             :   } else {
+     176           0 :     error("Unknown J-coupling type!");
+     177             :   }
+     178             : 
+     179             :   // Optionally add an experimental value (like with RDCs)
+     180             :   std::vector<double> coupl;
+     181           6 :   coupl.resize( ncoupl_ );
+     182             :   unsigned ntarget=0;
+     183          13 :   for(unsigned i=0; i<ncoupl_; ++i) {
+     184          24 :     if( !parseNumbered( "COUPLING", i+1, coupl[i] ) ) break;
+     185           7 :     ntarget++;
+     186             :   }
+     187             :   bool addcoupling=false;
+     188           6 :   if(ntarget!=ncoupl_ && ntarget!=0) error("found wrong number of COUPLING values");
+     189           6 :   if(ntarget==ncoupl_) addcoupling=true;
+     190           6 :   if(getDoScore()&&!addcoupling) error("with DOSCORE you need to set the COUPLING values");
+     191             : 
+     192             :   // For custom types we allow use of custom Karplus parameters
+     193           6 :   if (jtype_ == CUSTOM) {
+     194           0 :     parse("A", ka_);
+     195           0 :     parse("B", kb_);
+     196           0 :     parse("C", kc_);
+     197           0 :     parse("SHIFT", kshift_);
+     198             :   }
+     199             : 
+     200           6 :   log << "  Bibliography ";
+     201          12 :   log<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     202             : 
+     203             :   // Set Karplus parameters
+     204           6 :   switch (jtype_) {
+     205           1 :   case HAN:
+     206           1 :     ka_ = -0.88;
+     207           1 :     kb_ = -0.61;
+     208           1 :     kc_ = -0.27;
+     209           1 :     kshift_ = pi / 3.0;
+     210           2 :     log << plumed.cite("Wang A C, Bax A, J. Am. Chem. Soc. 117, 1810 (1995)");
+     211           1 :     log<<"\n";
+     212           1 :     log.printf("  J-coupling type is HAN, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     213             :     break;
+     214           3 :   case HAHN:
+     215           3 :     ka_ = 7.09;
+     216           3 :     kb_ = -1.42;
+     217           3 :     kc_ = 1.55;
+     218           3 :     kshift_ = -pi / 3.0;
+     219           6 :     log << plumed.cite("Hu J-S, Bax A, J. Am. Chem. Soc. 119, 6360 (1997)");
+     220           3 :     log<<"\n";
+     221           3 :     log.printf("  J-coupling type is HAHN, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     222             :     break;
+     223           1 :   case CCG:
+     224           1 :     ka_ = 2.31;
+     225           1 :     kb_ = -0.87;
+     226           1 :     kc_ = 0.55;
+     227           1 :     kshift_ = (2.0 * pi) / 3.0;
+     228           2 :     log << plumed.cite("Perez C, Löhr F, Rüterjans H, Schmidt J, J. Am. Chem. Soc. 123, 7081 (2001)");
+     229           1 :     log<<"\n";
+     230           1 :     log.printf("  J-coupling type is CCG, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     231             :     break;
+     232           1 :   case NCG:
+     233           1 :     ka_ = 1.29;
+     234           1 :     kb_ = -0.49;
+     235           1 :     kc_ = 0.37;
+     236           1 :     kshift_ = 0.0;
+     237           2 :     log << plumed.cite("Perez C, Löhr F, Rüterjans H, Schmidt J, J. Am. Chem. Soc. 123, 7081 (2001)");
+     238           1 :     log<<"\n";
+     239           1 :     log.printf("  J-coupling type is NCG, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     240             :     break;
+     241           0 :   case CUSTOM:
+     242           0 :     log<<"\n";
+     243           0 :     log.printf("  J-coupling type is custom, with A: %f, B: %f, C: %f, angle shift: %f\n", ka_, kb_, kc_, kshift_);
+     244             :     break;
+     245             :   }
+     246             : 
+     247          34 :   for (unsigned i = 0; i < ncoupl_; ++i) {
+     248          28 :     log.printf("  The %uth J-Coupling is calculated from atoms : %d %d %d %d.",
+     249          28 :                i+1, atoms[6*i].serial(), atoms[6*i+1].serial(), atoms[6*i+3].serial(), atoms[6*i+5].serial());
+     250          28 :     if (addcoupling) {
+     251           7 :       log.printf(" Experimental J-Coupling is %f.", coupl[i]);
+     252             :     }
+     253          28 :     log.printf("\n");
+     254             :   }
+     255             : 
+     256           6 :   if (pbc) {
+     257           0 :     log.printf("  using periodic boundary conditions\n");
+     258             :   } else {
+     259           6 :     log.printf("  without periodic boundary conditions\n");
+     260             :   }
+     261             : 
+     262           6 :   if(!getDoScore()) {
+     263          26 :     for (unsigned i = 0; i < ncoupl_; i++) {
+     264          21 :       std::string num; Tools::convert(i, num);
+     265          42 :       addComponentWithDerivatives("j-" + num);
+     266          42 :       componentIsNotPeriodic("j-" + num);
+     267             :     }
+     268             :   } else {
+     269           8 :     for (unsigned i = 0; i < ncoupl_; i++) {
+     270           7 :       std::string num; Tools::convert(i, num);
+     271          14 :       addComponent("j-" + num);
+     272          14 :       componentIsNotPeriodic("j-" + num);
+     273             :     }
+     274             :   }
+     275             : 
+     276           6 :   if (addcoupling||getDoScore()) {
+     277           8 :     for (unsigned i = 0; i < ncoupl_; i++) {
+     278           7 :       std::string num; Tools::convert(i, num);
+     279          14 :       addComponent("exp-" + num);
+     280           7 :       componentIsNotPeriodic("exp-" + num);
+     281           7 :       Value* comp = getPntrToComponent("exp-" + num);
+     282           7 :       comp->set(coupl[i]);
+     283             :     }
+     284             :   }
+     285             : 
+     286           6 :   requestAtoms(atoms, false);
+     287           6 :   if(getDoScore()) {
+     288           1 :     setParameters(coupl);
+     289           1 :     Initialise(ncoupl_);
+     290             :   }
+     291           6 :   setDerivatives();
+     292           6 :   checkRead();
+     293           6 : }
+     294             : 
+     295          16 : void JCoupling::calculate()
+     296             : {
+     297          16 :   if (pbc) makeWhole();
+     298          16 :   std::vector<Vector> deriv(ncoupl_*6);
+     299          16 :   std::vector<double> j(ncoupl_,0.);
+     300             : 
+     301          16 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+     302             :   {
+     303             :     #pragma omp for
+     304             :     // Loop through atoms, with steps of 6 atoms (one iteration per datapoint)
+     305             :     for (unsigned r=0; r<ncoupl_; r++) {
+     306             :       // Index is the datapoint index
+     307             :       unsigned a0 = 6*r;
+     308             : 
+     309             :       // 6 atoms -> 3 vectors
+     310             :       Vector d0 = delta(getPosition(a0+1), getPosition(a0));
+     311             :       Vector d1 = delta(getPosition(a0+3), getPosition(a0+2));
+     312             :       Vector d2 = delta(getPosition(a0+5), getPosition(a0+4));
+     313             : 
+     314             :       // Calculate dihedral with 3 vectors, get the derivatives
+     315             :       Vector dd0, dd1, dd2;
+     316             :       PLMD::Torsion t;
+     317             :       double torsion = t.compute(d0, d1, d2, dd0, dd1, dd2);
+     318             : 
+     319             :       // Calculate the Karplus relation and its derivative
+     320             :       double theta = torsion + kshift_;
+     321             :       double cos_theta = std::cos(theta);
+     322             :       double sin_theta = std::sin(theta);
+     323             :       j[r] = ka_*cos_theta*cos_theta + kb_*cos_theta + kc_;
+     324             :       double derj = -2.*ka_*sin_theta*cos_theta - kb_*sin_theta;
+     325             : 
+     326             :       dd0 *= derj;
+     327             :       dd1 *= derj;
+     328             :       dd2 *= derj;
+     329             : 
+     330             :       if(getDoScore()) setCalcData(r, j[r]);
+     331             :       deriv[a0] =  dd0;
+     332             :       deriv[a0+1] = -dd0;
+     333             :       deriv[a0+2] =  dd1;
+     334             :       deriv[a0+3] = -dd1;
+     335             :       deriv[a0+4] =  dd2;
+     336             :       deriv[a0+5] = -dd2;
+     337             :     }
+     338             :   }
+     339             : 
+     340          16 :   if(getDoScore()) {
+     341             :     /* Metainference */
+     342           6 :     double score = getScore();
+     343           6 :     setScore(score);
+     344             : 
+     345             :     /* calculate final derivatives */
+     346           6 :     Tensor virial;
+     347           6 :     Value* val=getPntrToComponent("score");
+     348          48 :     for (unsigned r=0; r<ncoupl_; r++) {
+     349          42 :       const unsigned a0 = 6*r;
+     350          42 :       setAtomsDerivatives(val, a0, deriv[a0]*getMetaDer(r));
+     351          42 :       setAtomsDerivatives(val, a0+1, deriv[a0+1]*getMetaDer(r));
+     352          42 :       setAtomsDerivatives(val, a0+2, deriv[a0+2]*getMetaDer(r));
+     353          42 :       setAtomsDerivatives(val, a0+3, deriv[a0+3]*getMetaDer(r));
+     354          42 :       setAtomsDerivatives(val, a0+4, deriv[a0+4]*getMetaDer(r));
+     355          42 :       setAtomsDerivatives(val, a0+5, deriv[a0+5]*getMetaDer(r));
+     356          42 :       virial-=Tensor(getPosition(a0), deriv[a0]*getMetaDer(r));
+     357          42 :       virial-=Tensor(getPosition(a0+1), deriv[a0+1]*getMetaDer(r));
+     358          42 :       virial-=Tensor(getPosition(a0+2), deriv[a0+2]*getMetaDer(r));
+     359          42 :       virial-=Tensor(getPosition(a0+3), deriv[a0+3]*getMetaDer(r));
+     360          42 :       virial-=Tensor(getPosition(a0+4), deriv[a0+4]*getMetaDer(r));
+     361          42 :       virial-=Tensor(getPosition(a0+5), deriv[a0+5]*getMetaDer(r));
+     362             :     }
+     363           6 :     setBoxDerivatives(val, virial);
+     364             :   } else {
+     365          66 :     for (unsigned r=0; r<ncoupl_; r++) {
+     366          56 :       const unsigned a0 = 6*r;
+     367          56 :       std::string num; Tools::convert(r,num);
+     368          56 :       Value* val=getPntrToComponent("j-"+num);
+     369          56 :       val->set(j[r]);
+     370          56 :       setAtomsDerivatives(val, a0, deriv[a0]);
+     371          56 :       setAtomsDerivatives(val, a0+1, deriv[a0+1]);
+     372          56 :       setAtomsDerivatives(val, a0+2, deriv[a0+2]);
+     373          56 :       setAtomsDerivatives(val, a0+3, deriv[a0+3]);
+     374          56 :       setAtomsDerivatives(val, a0+4, deriv[a0+4]);
+     375          56 :       setAtomsDerivatives(val, a0+5, deriv[a0+5]);
+     376          56 :       Tensor virial;
+     377          56 :       virial-=Tensor(getPosition(a0), deriv[a0]);
+     378          56 :       virial-=Tensor(getPosition(a0+1), deriv[a0+1]);
+     379          56 :       virial-=Tensor(getPosition(a0+2), deriv[a0+2]);
+     380          56 :       virial-=Tensor(getPosition(a0+3), deriv[a0+3]);
+     381          56 :       virial-=Tensor(getPosition(a0+4), deriv[a0+4]);
+     382          56 :       virial-=Tensor(getPosition(a0+5), deriv[a0+5]);
+     383          56 :       setBoxDerivatives(val, virial);
+     384             :     }
+     385             :   }
+     386          16 : }
+     387             : 
+     388          16 : void JCoupling::update() {
+     389             :   // write status file
+     390          16 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     391          16 : }
+     392             : 
+     393             : }
+     394             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Metainference.cpp.func-sort-c.html b/coverage/isdb/Metainference.cpp.func-sort-c.html new file mode 100644 index 000000000000..2c0ee0478373 --- /dev/null +++ b/coverage/isdb/Metainference.cpp.func-sort-c.html @@ -0,0 +1,181 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Metainference.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Metainference.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:73987784.3 %
Date:2024-02-22 21:58:45Functions:242788.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb13Metainference18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb13MetainferenceC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb13MetainferenceD2Ev0
_ZN4PLMD4isdb13Metainference16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb13Metainference11writeStatusEv19
_ZN4PLMD4isdb13MetainferenceC1ERKNS_13ActionOptionsE19
_ZN4PLMD4isdb13MetainferenceD0Ev19
_ZN4PLMD4isdb13MetainferenceD1Ev19
_ZN4PLMD4isdb13Metainference16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD4isdb13Metainference11getEnergyGJERKSt6vectorIdSaIdEES6_dd36
_ZN4PLMD4isdb13Metainference14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb13Metainference17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_48
_ZN4PLMD4isdb13Metainference17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_52
_ZN4PLMD4isdb13Metainference16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_54
_ZN4PLMD4isdb13Metainference12getEnergySPEERKSt6vectorIdSaIdEES6_dd144
_ZN4PLMD4isdb13Metainference12getEnergyGJEERKSt6vectorIdSaIdEES6_dd152
_ZN4PLMD4isdb13Metainference11getEnergySPERKSt6vectorIdSaIdEES6_dd156
_ZN4PLMD4isdb13Metainference15moveScaleOffsetERKSt6vectorIdSaIdEERd168
_ZN4PLMD4isdb13Metainference10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb178
_ZN4PLMD4isdb13Metainference11get_weightsEjRdS2_S2_178
_ZN4PLMD4isdb13Metainference12doMonteCarloERKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference14get_sigma_meanEjdddRKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference17replica_averagingEddRSt6vectorIdSaIdEES5_178
_ZN4PLMD4isdb13Metainference6updateEv178
_ZN4PLMD4isdb13Metainference9calculateEv178
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Metainference.cpp.func.html b/coverage/isdb/Metainference.cpp.func.html new file mode 100644 index 000000000000..ec05be180f3b --- /dev/null +++ b/coverage/isdb/Metainference.cpp.func.html @@ -0,0 +1,181 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Metainference.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Metainference.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:73987784.3 %
Date:2024-02-22 21:58:45Functions:242788.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb13Metainference10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb178
_ZN4PLMD4isdb13Metainference11getEnergyGJERKSt6vectorIdSaIdEES6_dd36
_ZN4PLMD4isdb13Metainference11getEnergySPERKSt6vectorIdSaIdEES6_dd156
_ZN4PLMD4isdb13Metainference11get_weightsEjRdS2_S2_178
_ZN4PLMD4isdb13Metainference11writeStatusEv19
_ZN4PLMD4isdb13Metainference12doMonteCarloERKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference12getEnergyGJEERKSt6vectorIdSaIdEES6_dd152
_ZN4PLMD4isdb13Metainference12getEnergySPEERKSt6vectorIdSaIdEES6_dd144
_ZN4PLMD4isdb13Metainference14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb13Metainference14get_sigma_meanEjdddRKSt6vectorIdSaIdEE178
_ZN4PLMD4isdb13Metainference15moveScaleOffsetERKSt6vectorIdSaIdEERd168
_ZN4PLMD4isdb13Metainference16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_54
_ZN4PLMD4isdb13Metainference16registerKeywordsERNS_8KeywordsE21
_ZN4PLMD4isdb13Metainference17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_52
_ZN4PLMD4isdb13Metainference17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_48
_ZN4PLMD4isdb13Metainference17replica_averagingEddRSt6vectorIdSaIdEES5_178
_ZN4PLMD4isdb13Metainference18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb13Metainference19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb13Metainference6updateEv178
_ZN4PLMD4isdb13Metainference9calculateEv178
_ZN4PLMD4isdb13Metainference9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb13MetainferenceC1ERKNS_13ActionOptionsE19
_ZN4PLMD4isdb13MetainferenceC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb13MetainferenceD0Ev19
_ZN4PLMD4isdb13MetainferenceD1Ev19
_ZN4PLMD4isdb13MetainferenceD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Metainference.cpp.gcov.html b/coverage/isdb/Metainference.cpp.gcov.html new file mode 100644 index 000000000000..f199e600793b --- /dev/null +++ b/coverage/isdb/Metainference.cpp.gcov.html @@ -0,0 +1,1879 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Metainference.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Metainference.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:73987784.3 %
Date:2024-02-22 21:58:45Functions:242788.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "bias/Bias.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Value.h"
+      27             : #include "tools/File.h"
+      28             : #include "tools/OpenMP.h"
+      29             : #include "tools/Random.h"
+      30             : #include "tools/Communicator.h"
+      31             : #include <chrono>
+      32             : #include <numeric>
+      33             : 
+      34             : #ifndef M_PI
+      35             : #define M_PI           3.14159265358979323846
+      36             : #endif
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace isdb {
+      40             : 
+      41             : //+PLUMEDOC ISDB_BIAS METAINFERENCE
+      42             : /*
+      43             : Calculates the Metainference energy for a set of experimental data.
+      44             : 
+      45             : Metainference \cite Bonomi:2016ip is a Bayesian framework
+      46             : to model heterogeneous systems by integrating prior information with noisy, ensemble-averaged data.
+      47             : Metainference models a system and quantifies the level of noise in the data by considering a set of replicas of the system.
+      48             : 
+      49             : Calculated experimental data are given in input as ARG while reference experimental values
+      50             : can be given either from fixed components of other actions using PARARG or as numbers using
+      51             : PARAMETERS. The default behavior is that of averaging the data over the available replicas,
+      52             : if this is not wanted the keyword NOENSEMBLE prevent this averaging.
+      53             : 
+      54             : Metadynamics Metainference \cite Bonomi:2016ge or more in general biased Metainference requires the knowledge of
+      55             : biasing potential in order to calculate the weighted average. In this case the value of the bias
+      56             : can be provided as the last argument in ARG and adding the keyword REWEIGHT. To avoid the noise
+      57             : resulting from the instantaneous value of the bias the weight of each replica can be averaged
+      58             : over a give time using the keyword AVERAGING.
+      59             : 
+      60             : The data can be averaged by using multiple replicas and weighted for a bias if present.
+      61             : The functional form of Metainference can be chosen among four variants selected
+      62             : with NOISE=GAUSS,MGAUSS,OUTLIERS,MOUTLIERS,GENERIC which correspond to modelling the noise for
+      63             : the arguments as a single gaussian common to all the data points, a gaussian per data
+      64             : point, a single long-tailed gaussian common to all the data points, a log-tailed
+      65             :  gaussian per data point or using two distinct noises as for the most general formulation of Metainference.
+      66             : In this latter case the noise of the replica-averaging is gaussian (one per data point) and the noise for
+      67             : the comparison with the experimental data can chosen using the keyword LIKELIHOOD
+      68             : between gaussian or log-normal (one per data point), furthermore the evolution of the estimated average
+      69             : over an infinite number of replicas is driven by DFTILDE.
+      70             : 
+      71             : As for Metainference theory there are two sigma values: SIGMA_MEAN0 represent the
+      72             : error of calculating an average quantity using a finite set of replica and should
+      73             : be set as small as possible following the guidelines for replica-averaged simulations
+      74             : in the framework of the Maximum Entropy Principle. Alternatively, this can be obtained
+      75             : automatically using the internal sigma mean optimization as introduced in \cite Lohr:2017gc
+      76             : (OPTSIGMAMEAN=SEM), in this second case sigma_mean is estimated from the maximum standard error
+      77             : of the mean either over the simulation or over a defined time using the keyword AVERAGING.
+      78             : SIGMA_BIAS is an uncertainty parameter, sampled by a MC algorithm in the bounded interval
+      79             : defined by SIGMA_MIN and SIGMA_MAX. The initial value is set at SIGMA0. The MC move is a
+      80             : random displacement of maximum value equal to DSIGMA. If the number of data point is
+      81             : too large and the acceptance rate drops it is possible to make the MC move over mutually
+      82             : exclusive, random subset of size MC_CHUNKSIZE and run more than one move setting MC_STEPS
+      83             : in such a way that MC_CHUNKSIZE*MC_STEPS will cover all the data points.
+      84             : 
+      85             : Calculated and experimental data can be compared modulo a scaling factor and/or an offset
+      86             : using SCALEDATA and/or ADDOFFSET, the sampling is obtained by a MC algorithm either using
+      87             : a flat or a gaussian prior setting it with SCALE_PRIOR or OFFSET_PRIOR.
+      88             : 
+      89             : \par Examples
+      90             : 
+      91             : In the following example we calculate a set of \ref RDC, take the replica-average of
+      92             : them and comparing them with a set of experimental values. RDCs are compared with
+      93             : the experimental data but for a multiplication factor SCALE that is also sampled by
+      94             : MC on-the-fly
+      95             : 
+      96             : \plumedfile
+      97             : RDC ...
+      98             : LABEL=rdc
+      99             : SCALE=0.0001
+     100             : GYROM=-72.5388
+     101             : ATOMS1=22,23
+     102             : ATOMS2=25,27
+     103             : ATOMS3=29,31
+     104             : ATOMS4=33,34
+     105             : ... RDC
+     106             : 
+     107             : METAINFERENCE ...
+     108             : ARG=rdc.*
+     109             : NOISETYPE=MGAUSS
+     110             : PARAMETERS=1.9190,2.9190,3.9190,4.9190
+     111             : SCALEDATA SCALE0=1 SCALE_MIN=0.1 SCALE_MAX=3 DSCALE=0.01
+     112             : SIGMA0=0.01 SIGMA_MIN=0.00001 SIGMA_MAX=3 DSIGMA=0.01
+     113             : SIGMA_MEAN0=0.001
+     114             : LABEL=spe
+     115             : ... METAINFERENCE
+     116             : 
+     117             : PRINT ARG=spe.bias FILE=BIAS STRIDE=1
+     118             : \endplumedfile
+     119             : 
+     120             : in the following example instead of using one uncertainty parameter per data point we use
+     121             : a single uncertainty value in a long-tailed gaussian to take into account for outliers, furthermore
+     122             : the data are weighted for the bias applied to other variables of the system.
+     123             : 
+     124             : \plumedfile
+     125             : RDC ...
+     126             : LABEL=rdc
+     127             : SCALE=0.0001
+     128             : GYROM=-72.5388
+     129             : ATOMS1=22,23
+     130             : ATOMS2=25,27
+     131             : ATOMS3=29,31
+     132             : ATOMS4=33,34
+     133             : ... RDC
+     134             : 
+     135             : cv1: TORSION ATOMS=1,2,3,4
+     136             : cv2: TORSION ATOMS=2,3,4,5
+     137             : mm: METAD ARG=cv1,cv2 HEIGHT=0.5 SIGMA=0.3,0.3 PACE=200 BIASFACTOR=8 WALKERS_MPI
+     138             : 
+     139             : METAINFERENCE ...
+     140             : #SETTINGS NREPLICAS=2
+     141             : ARG=rdc.*,mm.bias
+     142             : REWEIGHT
+     143             : NOISETYPE=OUTLIERS
+     144             : PARAMETERS=1.9190,2.9190,3.9190,4.9190
+     145             : SCALEDATA SCALE0=1 SCALE_MIN=0.1 SCALE_MAX=3 DSCALE=0.01
+     146             : SIGMA0=0.01 SIGMA_MIN=0.00001 SIGMA_MAX=3 DSIGMA=0.01
+     147             : SIGMA_MEAN0=0.001
+     148             : LABEL=spe
+     149             : ... METAINFERENCE
+     150             : \endplumedfile
+     151             : 
+     152             : (See also \ref RDC, \ref PBMETAD).
+     153             : 
+     154             : */
+     155             : //+ENDPLUMEDOC
+     156             : 
+     157             : class Metainference : public bias::Bias
+     158             : {
+     159             :   // experimental values
+     160             :   std::vector<double> parameters;
+     161             :   // noise type
+     162             :   unsigned noise_type_;
+     163             :   enum { GAUSS, MGAUSS, OUTLIERS, MOUTLIERS, GENERIC };
+     164             :   unsigned gen_likelihood_;
+     165             :   enum { LIKE_GAUSS, LIKE_LOGN };
+     166             :   // scale is data scaling factor
+     167             :   // noise type
+     168             :   unsigned scale_prior_;
+     169             :   enum { SC_GAUSS, SC_FLAT };
+     170             :   bool   doscale_;
+     171             :   double scale_;
+     172             :   double scale_mu_;
+     173             :   double scale_min_;
+     174             :   double scale_max_;
+     175             :   double Dscale_;
+     176             :   // scale is data scaling factor
+     177             :   // noise type
+     178             :   unsigned offset_prior_;
+     179             :   bool   dooffset_;
+     180             :   double offset_;
+     181             :   double offset_mu_;
+     182             :   double offset_min_;
+     183             :   double offset_max_;
+     184             :   double Doffset_;
+     185             :   // scale and offset regression
+     186             :   bool doregres_zero_;
+     187             :   int  nregres_zero_;
+     188             :   // sigma is data uncertainty
+     189             :   std::vector<double> sigma_;
+     190             :   std::vector<double> sigma_min_;
+     191             :   std::vector<double> sigma_max_;
+     192             :   std::vector<double> Dsigma_;
+     193             :   // sigma_mean is uncertainty in the mean estimate
+     194             :   std::vector<double> sigma_mean2_;
+     195             :   // this is the estimator of the mean value per replica for generic metainference
+     196             :   std::vector<double> ftilde_;
+     197             :   double Dftilde_;
+     198             : 
+     199             :   // temperature in kbt
+     200             :   double   kbt_;
+     201             : 
+     202             :   // Monte Carlo stuff
+     203             :   std::vector<Random> random;
+     204             :   unsigned MCsteps_;
+     205             :   long long unsigned MCaccept_;
+     206             :   long long unsigned MCacceptScale_;
+     207             :   long long unsigned MCacceptFT_;
+     208             :   long long unsigned MCtrial_;
+     209             :   unsigned MCchunksize_;
+     210             : 
+     211             :   // output
+     212             :   Value*   valueScale;
+     213             :   Value*   valueOffset;
+     214             :   Value*   valueAccept;
+     215             :   Value*   valueAcceptScale;
+     216             :   Value*   valueAcceptFT;
+     217             :   std::vector<Value*> valueSigma;
+     218             :   std::vector<Value*> valueSigmaMean;
+     219             :   std::vector<Value*> valueFtilde;
+     220             : 
+     221             :   // restart
+     222             :   unsigned write_stride_;
+     223             :   OFile    sfile_;
+     224             : 
+     225             :   // others
+     226             :   bool         firstTime;
+     227             :   std::vector<bool> firstTimeW;
+     228             :   bool     master;
+     229             :   bool     do_reweight_;
+     230             :   unsigned do_optsigmamean_;
+     231             :   unsigned nrep_;
+     232             :   unsigned replica_;
+     233             :   unsigned narg;
+     234             : 
+     235             :   // selector
+     236             :   std::string selector_;
+     237             : 
+     238             :   // optimize sigma mean
+     239             :   std::vector< std::vector < std::vector <double> > > sigma_mean2_last_;
+     240             :   unsigned optsigmamean_stride_;
+     241             :   // optimize sigma max
+     242             :   unsigned N_optimized_step_;
+     243             :   unsigned optimized_step_;
+     244             :   bool sigmamax_opt_done_;
+     245             :   std::vector<double> sigma_max_est_;
+     246             : 
+     247             :   // average weights
+     248             :   unsigned                   average_weights_stride_;
+     249             :   std::vector< std::vector <double> >  average_weights_;
+     250             : 
+     251             :   double getEnergyMIGEN(const std::vector<double> &mean, const std::vector<double> &ftilde, const std::vector<double> &sigma,
+     252             :                         const double scale, const double offset);
+     253             :   double getEnergySP(const std::vector<double> &mean, const std::vector<double> &sigma,
+     254             :                      const double scale, const double offset);
+     255             :   double getEnergySPE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     256             :                       const double scale, const double offset);
+     257             :   double getEnergyGJ(const std::vector<double> &mean, const std::vector<double> &sigma,
+     258             :                      const double scale, const double offset);
+     259             :   double getEnergyGJE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     260             :                       const double scale, const double offset);
+     261             :   void moveTilde(const std::vector<double> &mean_, double &old_energy);
+     262             :   void moveScaleOffset(const std::vector<double> &mean_, double &old_energy);
+     263             :   void moveSigmas(const std::vector<double> &mean_, double &old_energy, const unsigned i, const std::vector<unsigned> &indices, bool &breaknow);
+     264             :   double doMonteCarlo(const std::vector<double> &mean);
+     265             :   void getEnergyForceMIGEN(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     266             :   void getEnergyForceSP(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     267             :   void getEnergyForceSPE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     268             :   void getEnergyForceGJ(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     269             :   void getEnergyForceGJE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     270             :   void get_weights(const unsigned iselect, double &weight, double &norm, double &neff);
+     271             :   void replica_averaging(const double weight, const double norm, std::vector<double> &mean, std::vector<double> &dmean_b);
+     272             :   void get_sigma_mean(const unsigned iselect, const double weight, const double norm, const double neff, const std::vector<double> &mean);
+     273             :   void writeStatus();
+     274             :   void do_regression_zero(const std::vector<double> &mean);
+     275             : 
+     276             : public:
+     277             :   explicit Metainference(const ActionOptions&);
+     278             :   ~Metainference();
+     279             :   void calculate() override;
+     280             :   void update() override;
+     281             :   static void registerKeywords(Keywords& keys);
+     282             : };
+     283             : 
+     284             : 
+     285             : PLUMED_REGISTER_ACTION(Metainference,"METAINFERENCE")
+     286             : 
+     287          21 : void Metainference::registerKeywords(Keywords& keys) {
+     288          21 :   Bias::registerKeywords(keys);
+     289          21 :   keys.use("ARG");
+     290          42 :   keys.add("optional","PARARG","reference values for the experimental data, these can be provided as arguments without derivatives");
+     291          42 :   keys.add("optional","PARAMETERS","reference values for the experimental data");
+     292          42 :   keys.addFlag("NOENSEMBLE",false,"don't perform any replica-averaging");
+     293          42 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the latest ARG as energy");
+     294          42 :   keys.add("optional","AVERAGING", "Stride for calculation of averaged weights and sigma_mean");
+     295          42 :   keys.add("compulsory","NOISETYPE","MGAUSS","functional form of the noise (GAUSS,MGAUSS,OUTLIERS,MOUTLIERS,GENERIC)");
+     296          42 :   keys.add("compulsory","LIKELIHOOD","GAUSS","the likelihood for the GENERIC metainference model, GAUSS or LOGN");
+     297          42 :   keys.add("compulsory","DFTILDE","0.1","fraction of sigma_mean used to evolve ftilde");
+     298          42 :   keys.addFlag("SCALEDATA",false,"Set to TRUE if you want to sample a scaling factor common to all values and replicas");
+     299          42 :   keys.add("compulsory","SCALE0","1.0","initial value of the scaling factor");
+     300          42 :   keys.add("compulsory","SCALE_PRIOR","FLAT","either FLAT or GAUSSIAN");
+     301          42 :   keys.add("optional","SCALE_MIN","minimum value of the scaling factor");
+     302          42 :   keys.add("optional","SCALE_MAX","maximum value of the scaling factor");
+     303          42 :   keys.add("optional","DSCALE","maximum MC move of the scaling factor");
+     304          42 :   keys.addFlag("ADDOFFSET",false,"Set to TRUE if you want to sample an offset common to all values and replicas");
+     305          42 :   keys.add("compulsory","OFFSET0","0.0","initial value of the offset");
+     306          42 :   keys.add("compulsory","OFFSET_PRIOR","FLAT","either FLAT or GAUSSIAN");
+     307          42 :   keys.add("optional","OFFSET_MIN","minimum value of the offset");
+     308          42 :   keys.add("optional","OFFSET_MAX","maximum value of the offset");
+     309          42 :   keys.add("optional","DOFFSET","maximum MC move of the offset");
+     310          42 :   keys.add("optional","REGRES_ZERO","stride for regression with zero offset");
+     311          42 :   keys.add("compulsory","SIGMA0","1.0","initial value of the uncertainty parameter");
+     312          42 :   keys.add("compulsory","SIGMA_MIN","0.0","minimum value of the uncertainty parameter");
+     313          42 :   keys.add("compulsory","SIGMA_MAX","10.","maximum value of the uncertainty parameter");
+     314          42 :   keys.add("optional","DSIGMA","maximum MC move of the uncertainty parameter");
+     315          42 :   keys.add("compulsory","OPTSIGMAMEAN","NONE","Set to NONE/SEM to manually set sigma mean, or to estimate it on the fly");
+     316          42 :   keys.add("optional","SIGMA_MEAN0","starting value for the uncertainty in the mean estimate");
+     317          42 :   keys.add("optional","SIGMA_MAX_STEPS", "Number of steps used to optimise SIGMA_MAX, before that the SIGMA_MAX value is used");
+     318          42 :   keys.add("optional","TEMP","the system temperature - this is only needed if code doesn't pass the temperature to plumed");
+     319          42 :   keys.add("optional","MC_STEPS","number of MC steps");
+     320          42 :   keys.add("optional","MC_CHUNKSIZE","MC chunksize");
+     321          42 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart/continuation of Metainference");
+     322          42 :   keys.add("compulsory","WRITE_STRIDE","10000","write the status to a file every N steps, this can be used for restart/continuation");
+     323          42 :   keys.add("optional","SELECTOR","name of selector");
+     324          42 :   keys.add("optional","NSELECT","range of values for selector [0, N-1]");
+     325          21 :   keys.use("RESTART");
+     326          42 :   keys.addOutputComponent("sigma",        "default",      "uncertainty parameter");
+     327          42 :   keys.addOutputComponent("sigmaMean",    "default",      "uncertainty in the mean estimate");
+     328          42 :   keys.addOutputComponent("neff",         "default",      "effective number of replicas");
+     329          42 :   keys.addOutputComponent("acceptSigma",  "default",      "MC acceptance for sigma values");
+     330          42 :   keys.addOutputComponent("acceptScale",  "SCALEDATA",    "MC acceptance for scale value");
+     331          42 :   keys.addOutputComponent("acceptFT",     "GENERIC",      "MC acceptance for general metainference f tilde value");
+     332          42 :   keys.addOutputComponent("weight",       "REWEIGHT",     "weights of the weighted average");
+     333          42 :   keys.addOutputComponent("biasDer",      "REWEIGHT",     "derivatives with respect to the bias");
+     334          42 :   keys.addOutputComponent("scale",        "SCALEDATA",    "scale parameter");
+     335          42 :   keys.addOutputComponent("offset",       "ADDOFFSET",    "offset parameter");
+     336          42 :   keys.addOutputComponent("ftilde",       "GENERIC",      "ensemble average estimator");
+     337          21 : }
+     338             : 
+     339          19 : Metainference::Metainference(const ActionOptions&ao):
+     340             :   PLUMED_BIAS_INIT(ao),
+     341          19 :   doscale_(false),
+     342          19 :   scale_(1.),
+     343          19 :   scale_mu_(0),
+     344          19 :   scale_min_(1),
+     345          19 :   scale_max_(-1),
+     346          19 :   Dscale_(-1),
+     347          19 :   dooffset_(false),
+     348          19 :   offset_(0.),
+     349          19 :   offset_mu_(0),
+     350          19 :   offset_min_(1),
+     351          19 :   offset_max_(-1),
+     352          19 :   Doffset_(-1),
+     353          19 :   doregres_zero_(false),
+     354          19 :   nregres_zero_(0),
+     355          19 :   Dftilde_(0.1),
+     356          19 :   random(3),
+     357          19 :   MCsteps_(1),
+     358          19 :   MCaccept_(0),
+     359          19 :   MCacceptScale_(0),
+     360          19 :   MCacceptFT_(0),
+     361          19 :   MCtrial_(0),
+     362          19 :   MCchunksize_(0),
+     363          19 :   write_stride_(0),
+     364          19 :   firstTime(true),
+     365          19 :   do_reweight_(false),
+     366          19 :   do_optsigmamean_(0),
+     367          19 :   optsigmamean_stride_(0),
+     368          19 :   N_optimized_step_(0),
+     369          19 :   optimized_step_(0),
+     370          19 :   sigmamax_opt_done_(false),
+     371          19 :   average_weights_stride_(1)
+     372             : {
+     373          19 :   bool noensemble = false;
+     374          19 :   parseFlag("NOENSEMBLE", noensemble);
+     375             : 
+     376             :   // set up replica stuff
+     377          19 :   master = (comm.Get_rank()==0);
+     378          19 :   if(master) {
+     379          11 :     nrep_    = multi_sim_comm.Get_size();
+     380          11 :     replica_ = multi_sim_comm.Get_rank();
+     381          11 :     if(noensemble) nrep_ = 1;
+     382             :   } else {
+     383           8 :     nrep_    = 0;
+     384           8 :     replica_ = 0;
+     385             :   }
+     386          19 :   comm.Sum(&nrep_,1);
+     387          19 :   comm.Sum(&replica_,1);
+     388             : 
+     389          19 :   unsigned nsel = 1;
+     390          19 :   parse("SELECTOR", selector_);
+     391          38 :   parse("NSELECT", nsel);
+     392             :   // do checks
+     393          19 :   if(selector_.length()>0 && nsel<=1) error("With SELECTOR active, NSELECT must be greater than 1");
+     394          19 :   if(selector_.length()==0 && nsel>1) error("With NSELECT greater than 1, you must specify SELECTOR");
+     395             : 
+     396             :   // initialise firstTimeW
+     397          19 :   firstTimeW.resize(nsel, true);
+     398             : 
+     399             :   // reweight implies a different number of arguments (the latest one must always be the bias)
+     400          19 :   parseFlag("REWEIGHT", do_reweight_);
+     401          19 :   if(do_reweight_&&nrep_<2) error("REWEIGHT can only be used in parallel with 2 or more replicas");
+     402          34 :   if(!getRestart()) average_weights_.resize(nsel, std::vector<double> (nrep_, 1./static_cast<double>(nrep_)));
+     403           8 :   else average_weights_.resize(nsel, std::vector<double> (nrep_, 0.));
+     404          19 :   narg = getNumberOfArguments();
+     405          19 :   if(do_reweight_) narg--;
+     406             : 
+     407          19 :   unsigned averaging=0;
+     408          19 :   parse("AVERAGING", averaging);
+     409          19 :   if(averaging>0) {
+     410           0 :     average_weights_stride_ = averaging;
+     411           0 :     optsigmamean_stride_    = averaging;
+     412             :   }
+     413             : 
+     414          38 :   parseVector("PARAMETERS",parameters);
+     415          19 :   if(parameters.size()!=static_cast<unsigned>(narg)&&!parameters.empty())
+     416           0 :     error("Size of PARAMETERS array should be either 0 or the same as of the number of arguments in ARG1");
+     417             : 
+     418             :   std::vector<Value*> arg2;
+     419          38 :   parseArgumentList("PARARG",arg2);
+     420          19 :   if(!arg2.empty()) {
+     421           4 :     if(parameters.size()>0) error("It is not possible to use PARARG and PARAMETERS together");
+     422           4 :     if(arg2.size()!=narg) error("Size of PARARG array should be the same as number for arguments in ARG");
+     423        2360 :     for(unsigned i=0; i<arg2.size(); i++) {
+     424        2356 :       parameters.push_back(arg2[i]->get());
+     425        2356 :       if(arg2[i]->hasDerivatives()==true) error("PARARG can only accept arguments without derivatives");
+     426             :     }
+     427             :   }
+     428             : 
+     429          19 :   if(parameters.size()!=narg)
+     430           0 :     error("PARARG or PARAMETERS arrays should include the same number of elements as the arguments in ARG");
+     431             : 
+     432             :   std::string stringa_noise;
+     433          38 :   parse("NOISETYPE",stringa_noise);
+     434          19 :   if(stringa_noise=="GAUSS")           noise_type_ = GAUSS;
+     435          18 :   else if(stringa_noise=="MGAUSS")     noise_type_ = MGAUSS;
+     436          10 :   else if(stringa_noise=="OUTLIERS")   noise_type_ = OUTLIERS;
+     437           5 :   else if(stringa_noise=="MOUTLIERS")  noise_type_ = MOUTLIERS;
+     438           1 :   else if(stringa_noise=="GENERIC")    noise_type_ = GENERIC;
+     439           0 :   else error("Unknown noise type!");
+     440             : 
+     441          19 :   if(noise_type_== GENERIC) {
+     442             :     std::string stringa_like;
+     443           2 :     parse("LIKELIHOOD",stringa_like);
+     444           1 :     if(stringa_like=="GAUSS") gen_likelihood_ = LIKE_GAUSS;
+     445           0 :     else if(stringa_like=="LOGN") gen_likelihood_ = LIKE_LOGN;
+     446           0 :     else error("Unknown likelihood type!");
+     447             : 
+     448           2 :     parse("DFTILDE",Dftilde_);
+     449             :   }
+     450             : 
+     451          38 :   parse("WRITE_STRIDE",write_stride_);
+     452             :   std::string status_file_name_;
+     453          38 :   parse("STATUS_FILE",status_file_name_);
+     454          38 :   if(status_file_name_=="") status_file_name_ = "MISTATUS"+getLabel();
+     455           0 :   else                      status_file_name_ = status_file_name_+getLabel();
+     456             : 
+     457             :   std::string stringa_optsigma;
+     458          38 :   parse("OPTSIGMAMEAN", stringa_optsigma);
+     459          19 :   if(stringa_optsigma=="NONE")      do_optsigmamean_=0;
+     460           0 :   else if(stringa_optsigma=="SEM")  do_optsigmamean_=1;
+     461           0 :   else if(stringa_optsigma=="SEM_MAX")  do_optsigmamean_=2;
+     462             : 
+     463          19 :   unsigned aver_max_steps=0;
+     464          19 :   parse("SIGMA_MAX_STEPS", aver_max_steps);
+     465          19 :   if(aver_max_steps==0&&do_optsigmamean_==2) aver_max_steps=averaging*2000;
+     466          19 :   if(aver_max_steps>0&&do_optsigmamean_<2) error("SIGMA_MAX_STEPS can only be used together with OPTSIGMAMEAN=SEM_MAX");
+     467          19 :   if(aver_max_steps>0&&do_optsigmamean_==2) N_optimized_step_=aver_max_steps;
+     468          19 :   if(aver_max_steps>0&&aver_max_steps<averaging) error("SIGMA_MAX_STEPS must be greater than AVERAGING");
+     469             : 
+     470             :   // resize std::vector for sigma_mean history
+     471          19 :   sigma_mean2_last_.resize(nsel);
+     472          38 :   for(unsigned i=0; i<nsel; i++) sigma_mean2_last_[i].resize(narg);
+     473             : 
+     474             :   std::vector<double> read_sigma_mean_;
+     475          19 :   parseVector("SIGMA_MEAN0",read_sigma_mean_);
+     476          19 :   if(do_optsigmamean_==0 && read_sigma_mean_.size()==0 && !getRestart())
+     477           0 :     error("If you don't use OPTSIGMAMEAN and you are not RESTARTING then you MUST SET SIGMA_MEAN0");
+     478             : 
+     479          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     480          13 :     if(read_sigma_mean_.size()==narg) {
+     481           0 :       sigma_mean2_.resize(narg);
+     482           0 :       for(unsigned i=0; i<narg; i++) sigma_mean2_[i]=read_sigma_mean_[i]*read_sigma_mean_[i];
+     483          13 :     } else if(read_sigma_mean_.size()==1) {
+     484          13 :       sigma_mean2_.resize(narg,read_sigma_mean_[0]*read_sigma_mean_[0]);
+     485           0 :     } else if(read_sigma_mean_.size()==0) {
+     486           0 :       sigma_mean2_.resize(narg,0.000001);
+     487             :     } else {
+     488           0 :       error("SIGMA_MEAN0 can accept either one single value or as many values as the arguments (with NOISETYPE=MGAUSS|MOUTLIERS)");
+     489             :     }
+     490             :     // set the initial value for the history
+     491        2416 :     for(unsigned i=0; i<nsel; i++) for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j].push_back(sigma_mean2_[j]);
+     492             :   } else {
+     493           6 :     if(read_sigma_mean_.size()==1) {
+     494           6 :       sigma_mean2_.resize(1, read_sigma_mean_[0]*read_sigma_mean_[0]);
+     495           0 :     } else if(read_sigma_mean_.size()==0) {
+     496           0 :       sigma_mean2_.resize(1, 0.000001);
+     497             :     } else {
+     498           0 :       error("If you want to use more than one SIGMA_MEAN0 you should use NOISETYPE=MGAUSS|MOUTLIERS");
+     499             :     }
+     500             :     // set the initial value for the history
+     501          37 :     for(unsigned i=0; i<nsel; i++) for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j].push_back(sigma_mean2_[0]);
+     502             :   }
+     503             : 
+     504          19 :   parseFlag("SCALEDATA", doscale_);
+     505          19 :   if(doscale_) {
+     506             :     std::string stringa_noise;
+     507          24 :     parse("SCALE_PRIOR",stringa_noise);
+     508          12 :     if(stringa_noise=="GAUSSIAN")  scale_prior_ = SC_GAUSS;
+     509          12 :     else if(stringa_noise=="FLAT") scale_prior_ = SC_FLAT;
+     510           0 :     else error("Unknown SCALE_PRIOR type!");
+     511          12 :     parse("SCALE0",scale_);
+     512          12 :     parse("DSCALE",Dscale_);
+     513          12 :     if(Dscale_<0.) error("DSCALE must be set when using SCALEDATA");
+     514          12 :     if(scale_prior_==SC_GAUSS) {
+     515           0 :       scale_mu_=scale_;
+     516             :     } else {
+     517          12 :       parse("SCALE_MIN",scale_min_);
+     518          12 :       parse("SCALE_MAX",scale_max_);
+     519          12 :       if(scale_max_<scale_min_) error("SCALE_MAX and SCALE_MIN must be set when using SCALE_PRIOR=FLAT");
+     520             :     }
+     521             :   }
+     522             : 
+     523          19 :   parseFlag("ADDOFFSET", dooffset_);
+     524          19 :   if(dooffset_) {
+     525             :     std::string stringa_noise;
+     526           4 :     parse("OFFSET_PRIOR",stringa_noise);
+     527           2 :     if(stringa_noise=="GAUSSIAN")  offset_prior_ = SC_GAUSS;
+     528           2 :     else if(stringa_noise=="FLAT") offset_prior_ = SC_FLAT;
+     529           0 :     else error("Unknown OFFSET_PRIOR type!");
+     530           2 :     parse("OFFSET0",offset_);
+     531           2 :     parse("DOFFSET",Doffset_);
+     532           2 :     if(offset_prior_==SC_GAUSS) {
+     533           0 :       offset_mu_=offset_;
+     534           0 :       if(Doffset_<0.) error("DOFFSET must be set when using OFFSET_PRIOR=GAUSS");
+     535             :     } else {
+     536           2 :       parse("OFFSET_MIN",offset_min_);
+     537           2 :       parse("OFFSET_MAX",offset_max_);
+     538           2 :       if(Doffset_<0) Doffset_ = 0.05*(offset_max_ - offset_min_);
+     539           2 :       if(offset_max_<offset_min_) error("OFFSET_MAX and OFFSET_MIN must be set when using OFFSET_PRIOR=FLAT");
+     540             :     }
+     541             :   }
+     542             : 
+     543             :   // regression with zero intercept
+     544          19 :   parse("REGRES_ZERO", nregres_zero_);
+     545          19 :   if(nregres_zero_>0) {
+     546             :     // set flag
+     547           0 :     doregres_zero_=true;
+     548             :     // check if already sampling scale and offset
+     549           0 :     if(doscale_)  error("REGRES_ZERO and SCALEDATA are mutually exclusive");
+     550           0 :     if(dooffset_) error("REGRES_ZERO and ADDOFFSET are mutually exclusive");
+     551             :   }
+     552             : 
+     553             :   std::vector<double> readsigma;
+     554          19 :   parseVector("SIGMA0",readsigma);
+     555          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma.size()>1)
+     556           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     557          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     558          13 :     sigma_.resize(readsigma.size());
+     559          13 :     sigma_=readsigma;
+     560           6 :   } else sigma_.resize(1, readsigma[0]);
+     561             : 
+     562             :   std::vector<double> readsigma_min;
+     563          19 :   parseVector("SIGMA_MIN",readsigma_min);
+     564          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_min.size()>1)
+     565           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     566          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     567          13 :     sigma_min_.resize(readsigma_min.size());
+     568          13 :     sigma_min_=readsigma_min;
+     569           6 :   } else sigma_min_.resize(1, readsigma_min[0]);
+     570             : 
+     571             :   std::vector<double> readsigma_max;
+     572          19 :   parseVector("SIGMA_MAX",readsigma_max);
+     573          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_max.size()>1)
+     574           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     575          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     576          13 :     sigma_max_.resize(readsigma_max.size());
+     577          13 :     sigma_max_=readsigma_max;
+     578           6 :   } else sigma_max_.resize(1, readsigma_max[0]);
+     579             : 
+     580          19 :   if(sigma_max_.size()!=sigma_min_.size()) error("The number of values for SIGMA_MIN and SIGMA_MAX must be the same");
+     581             : 
+     582             :   std::vector<double> read_dsigma;
+     583          19 :   parseVector("DSIGMA",read_dsigma);
+     584          19 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_max.size()>1)
+     585           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     586          19 :   if(read_dsigma.size()>0) {
+     587          19 :     Dsigma_.resize(read_dsigma.size());
+     588          19 :     Dsigma_=read_dsigma;
+     589             :   } else {
+     590           0 :     Dsigma_.resize(sigma_max_.size(), -1.);
+     591             :     /* in this case Dsigma is initialised after reading the restart file if present */
+     592             :   }
+     593             : 
+     594             :   // monte carlo stuff
+     595          19 :   parse("MC_STEPS",MCsteps_);
+     596          19 :   parse("MC_CHUNKSIZE", MCchunksize_);
+     597             :   // get temperature
+     598          19 :   kbt_ = getkBT();
+     599          19 :   if(kbt_==0.0) error("Unless the MD engine passes the temperature to plumed, you must specify it using TEMP");
+     600             : 
+     601          19 :   checkRead();
+     602             : 
+     603             :   // set sigma_bias
+     604          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     605          13 :     if(sigma_.size()==1) {
+     606          13 :       double tmp = sigma_[0];
+     607          13 :       sigma_.resize(narg, tmp);
+     608           0 :     } else if(sigma_.size()>1&&sigma_.size()!=narg) {
+     609           0 :       error("SIGMA0 can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     610             :     }
+     611          13 :     if(sigma_min_.size()==1) {
+     612          13 :       double tmp = sigma_min_[0];
+     613          13 :       sigma_min_.resize(narg, tmp);
+     614           0 :     } else if(sigma_min_.size()>1&&sigma_min_.size()!=narg) {
+     615           0 :       error("SIGMA_MIN can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     616             :     }
+     617          13 :     if(sigma_max_.size()==1) {
+     618          13 :       double tmp = sigma_max_[0];
+     619          13 :       sigma_max_.resize(narg, tmp);
+     620           0 :     } else if(sigma_max_.size()>1&&sigma_max_.size()!=narg) {
+     621           0 :       error("SIGMA_MAX can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     622             :     }
+     623          13 :     if(Dsigma_.size()==1) {
+     624          13 :       double tmp = Dsigma_[0];
+     625          13 :       Dsigma_.resize(narg, tmp);
+     626           0 :     } else if(Dsigma_.size()>1&&Dsigma_.size()!=narg) {
+     627           0 :       error("DSIGMA can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     628             :     }
+     629             :   }
+     630             : 
+     631          19 :   sigma_max_est_.resize(sigma_max_.size(), 0.);
+     632             : 
+     633          19 :   IFile restart_sfile;
+     634          19 :   restart_sfile.link(*this);
+     635          19 :   if(getRestart()&&restart_sfile.FileExist(status_file_name_)) {
+     636           4 :     firstTime = false;
+     637           8 :     for(unsigned i=0; i<nsel; i++) firstTimeW[i] = false;
+     638           4 :     restart_sfile.open(status_file_name_);
+     639           4 :     log.printf("  Restarting from %s\n", status_file_name_.c_str());
+     640             :     double dummy;
+     641           8 :     if(restart_sfile.scanField("time",dummy)) {
+     642             :       // check for syncronisation
+     643           4 :       std::vector<double> dummy_time(nrep_,0);
+     644           4 :       if(master&&nrep_>1) {
+     645           2 :         dummy_time[replica_] = dummy;
+     646           2 :         multi_sim_comm.Sum(dummy_time);
+     647             :       }
+     648           4 :       comm.Sum(dummy_time);
+     649           8 :       for(unsigned i=1; i<nrep_; i++) {
+     650           4 :         std::string msg = "METAINFERENCE restart files " + status_file_name_ + "  are not in sync";
+     651           4 :         if(dummy_time[i]!=dummy_time[0]) plumed_merror(msg);
+     652             :       }
+     653             :       // nsel
+     654           8 :       for(unsigned i=0; i<sigma_mean2_last_.size(); i++) {
+     655             :         std::string msg_i;
+     656           4 :         Tools::convert(i,msg_i);
+     657             :         // narg
+     658           4 :         if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     659          20 :           for(unsigned j=0; j<narg; ++j) {
+     660             :             std::string msg_j;
+     661          16 :             Tools::convert(j,msg_j);
+     662          16 :             std::string msg = msg_i+"_"+msg_j;
+     663             :             double read_sm;
+     664          16 :             restart_sfile.scanField("sigmaMean_"+msg,read_sm);
+     665          16 :             sigma_mean2_last_[i][j][0] = read_sm*read_sm;
+     666             :           }
+     667             :         }
+     668           4 :         if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+     669             :           double read_sm;
+     670             :           std::string msg_j;
+     671           0 :           Tools::convert(0,msg_j);
+     672           0 :           std::string msg = msg_i+"_"+msg_j;
+     673           0 :           restart_sfile.scanField("sigmaMean_"+msg,read_sm);
+     674           0 :           for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j][0] = read_sm*read_sm;
+     675             :         }
+     676             :       }
+     677             : 
+     678          20 :       for(unsigned i=0; i<sigma_.size(); ++i) {
+     679             :         std::string msg;
+     680          16 :         Tools::convert(i,msg);
+     681          32 :         restart_sfile.scanField("sigma_"+msg,sigma_[i]);
+     682             :       }
+     683          20 :       for(unsigned i=0; i<sigma_max_.size(); ++i) {
+     684             :         std::string msg;
+     685          16 :         Tools::convert(i,msg);
+     686          16 :         restart_sfile.scanField("sigma_max_"+msg,sigma_max_[i]);
+     687          16 :         sigmamax_opt_done_=true;
+     688             :       }
+     689           4 :       if(noise_type_==GENERIC) {
+     690           0 :         for(unsigned i=0; i<ftilde_.size(); ++i) {
+     691             :           std::string msg;
+     692           0 :           Tools::convert(i,msg);
+     693           0 :           restart_sfile.scanField("ftilde_"+msg,ftilde_[i]);
+     694             :         }
+     695             :       }
+     696           4 :       restart_sfile.scanField("scale0_",scale_);
+     697           4 :       restart_sfile.scanField("offset0_",offset_);
+     698             : 
+     699           8 :       for(unsigned i=0; i<nsel; i++) {
+     700             :         std::string msg;
+     701           4 :         Tools::convert(i,msg);
+     702             :         double tmp_w;
+     703           4 :         restart_sfile.scanField("weight_"+msg,tmp_w);
+     704           4 :         if(master) {
+     705           2 :           average_weights_[i][replica_] = tmp_w;
+     706           2 :           if(nrep_>1) multi_sim_comm.Sum(&average_weights_[i][0], nrep_);
+     707             :         }
+     708           4 :         comm.Sum(&average_weights_[i][0], nrep_);
+     709             :       }
+     710             : 
+     711             :     }
+     712           4 :     restart_sfile.scanField();
+     713           4 :     restart_sfile.close();
+     714             :   }
+     715             : 
+     716             :   /* If DSIGMA is not yet initialised do it now */
+     717        2415 :   for(unsigned i=0; i<sigma_max_.size(); i++) if(Dsigma_[i]==-1) Dsigma_[i] = 0.05*(sigma_max_[i] - sigma_min_[i]);
+     718             : 
+     719          19 :   switch(noise_type_) {
+     720           1 :   case GENERIC:
+     721           1 :     log.printf("  with general metainference ");
+     722           1 :     if(gen_likelihood_==LIKE_GAUSS) log.printf(" and a gaussian likelihood\n");
+     723           0 :     else if(gen_likelihood_==LIKE_LOGN) log.printf(" and a log-normal likelihood\n");
+     724           1 :     log.printf("  ensemble average parameter sampled with a step %lf of sigma_mean\n", Dftilde_);
+     725             :     break;
+     726           1 :   case GAUSS:
+     727           1 :     log.printf("  with gaussian noise and a single noise parameter for all the data\n");
+     728             :     break;
+     729           8 :   case MGAUSS:
+     730           8 :     log.printf("  with gaussian noise and a noise parameter for each data point\n");
+     731             :     break;
+     732           5 :   case OUTLIERS:
+     733           5 :     log.printf("  with long tailed gaussian noise and a single noise parameter for all the data\n");
+     734             :     break;
+     735           4 :   case MOUTLIERS:
+     736           4 :     log.printf("  with long tailed gaussian noise and a noise parameter for each data point\n");
+     737             :     break;
+     738             :   }
+     739             : 
+     740          19 :   if(doscale_) {
+     741             :     // check that the scale value is the same for all replicas
+     742          12 :     std::vector<double> dummy_scale(nrep_,0);
+     743          12 :     if(master&&nrep_>1) {
+     744           6 :       dummy_scale[replica_] = scale_;
+     745           6 :       multi_sim_comm.Sum(dummy_scale);
+     746             :     }
+     747          12 :     comm.Sum(dummy_scale);
+     748          24 :     for(unsigned i=1; i<nrep_; i++) {
+     749          12 :       std::string msg = "The SCALE value must be the same for all replicas: check your input or restart file";
+     750          12 :       if(dummy_scale[i]!=dummy_scale[0]) plumed_merror(msg);
+     751             :     }
+     752          12 :     log.printf("  sampling a common scaling factor with:\n");
+     753          12 :     log.printf("    initial scale parameter %f\n",scale_);
+     754          12 :     if(scale_prior_==SC_GAUSS) {
+     755           0 :       log.printf("    gaussian prior with mean %f and width %f\n",scale_mu_,Dscale_);
+     756             :     }
+     757          12 :     if(scale_prior_==SC_FLAT) {
+     758          12 :       log.printf("    flat prior between %f - %f\n",scale_min_,scale_max_);
+     759          12 :       log.printf("    maximum MC move of scale parameter %f\n",Dscale_);
+     760             :     }
+     761             :   }
+     762             : 
+     763          19 :   if(dooffset_) {
+     764             :     // check that the offset value is the same for all replicas
+     765           2 :     std::vector<double> dummy_offset(nrep_,0);
+     766           2 :     if(master&&nrep_>1) {
+     767           0 :       dummy_offset[replica_] = offset_;
+     768           0 :       multi_sim_comm.Sum(dummy_offset);
+     769             :     }
+     770           2 :     comm.Sum(dummy_offset);
+     771           2 :     for(unsigned i=1; i<nrep_; i++) {
+     772           0 :       std::string msg = "The OFFSET value must be the same for all replicas: check your input or restart file";
+     773           0 :       if(dummy_offset[i]!=dummy_offset[0]) plumed_merror(msg);
+     774             :     }
+     775           2 :     log.printf("  sampling a common offset with:\n");
+     776           2 :     log.printf("    initial offset parameter %f\n",offset_);
+     777           2 :     if(offset_prior_==SC_GAUSS) {
+     778           0 :       log.printf("    gaussian prior with mean %f and width %f\n",offset_mu_,Doffset_);
+     779             :     }
+     780           2 :     if(offset_prior_==SC_FLAT) {
+     781           2 :       log.printf("    flat prior between %f - %f\n",offset_min_,offset_max_);
+     782           2 :       log.printf("    maximum MC move of offset parameter %f\n",Doffset_);
+     783             :     }
+     784             :   }
+     785             : 
+     786          19 :   if(doregres_zero_)
+     787           0 :     log.printf("  doing regression with zero intercept with stride: %d\n", nregres_zero_);
+     788             : 
+     789          19 :   log.printf("  number of experimental data points %u\n",narg);
+     790          19 :   log.printf("  number of replicas %u\n",nrep_);
+     791          19 :   log.printf("  initial data uncertainties");
+     792        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f", sigma_[i]);
+     793          19 :   log.printf("\n");
+     794          19 :   log.printf("  minimum data uncertainties");
+     795        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_min_[i]);
+     796          19 :   log.printf("\n");
+     797          19 :   log.printf("  maximum data uncertainties");
+     798        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_max_[i]);
+     799          19 :   log.printf("\n");
+     800          19 :   log.printf("  maximum MC move of data uncertainties");
+     801        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",Dsigma_[i]);
+     802          19 :   log.printf("\n");
+     803          19 :   log.printf("  temperature of the system %f\n",kbt_);
+     804          19 :   log.printf("  MC steps %u\n",MCsteps_);
+     805          19 :   log.printf("  initial standard errors of the mean");
+     806        2415 :   for(unsigned i=0; i<sigma_mean2_.size(); ++i) log.printf(" %f", std::sqrt(sigma_mean2_[i]));
+     807          19 :   log.printf("\n");
+     808             : 
+     809          19 :   if(do_reweight_) {
+     810          32 :     addComponent("biasDer");
+     811          32 :     componentIsNotPeriodic("biasDer");
+     812          32 :     addComponent("weight");
+     813          32 :     componentIsNotPeriodic("weight");
+     814             :   }
+     815             : 
+     816          38 :   addComponent("neff");
+     817          19 :   componentIsNotPeriodic("neff");
+     818             : 
+     819          19 :   if(doscale_ || doregres_zero_) {
+     820          24 :     addComponent("scale");
+     821          12 :     componentIsNotPeriodic("scale");
+     822          12 :     valueScale=getPntrToComponent("scale");
+     823             :   }
+     824             : 
+     825          19 :   if(dooffset_) {
+     826           4 :     addComponent("offset");
+     827           2 :     componentIsNotPeriodic("offset");
+     828           2 :     valueOffset=getPntrToComponent("offset");
+     829             :   }
+     830             : 
+     831          19 :   if(dooffset_||doscale_) {
+     832          28 :     addComponent("acceptScale");
+     833          14 :     componentIsNotPeriodic("acceptScale");
+     834          14 :     valueAcceptScale=getPntrToComponent("acceptScale");
+     835             :   }
+     836             : 
+     837          19 :   if(noise_type_==GENERIC) {
+     838           2 :     addComponent("acceptFT");
+     839           1 :     componentIsNotPeriodic("acceptFT");
+     840           1 :     valueAcceptFT=getPntrToComponent("acceptFT");
+     841             :   }
+     842             : 
+     843          38 :   addComponent("acceptSigma");
+     844          19 :   componentIsNotPeriodic("acceptSigma");
+     845          19 :   valueAccept=getPntrToComponent("acceptSigma");
+     846             : 
+     847          19 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     848        2403 :     for(unsigned i=0; i<sigma_mean2_.size(); ++i) {
+     849        2390 :       std::string num; Tools::convert(i,num);
+     850        4780 :       addComponent("sigmaMean-"+num); componentIsNotPeriodic("sigmaMean-"+num);
+     851        2390 :       valueSigmaMean.push_back(getPntrToComponent("sigmaMean-"+num));
+     852        4780 :       getPntrToComponent("sigmaMean-"+num)->set(std::sqrt(sigma_mean2_[i]));
+     853        4780 :       addComponent("sigma-"+num); componentIsNotPeriodic("sigma-"+num);
+     854        2390 :       valueSigma.push_back(getPntrToComponent("sigma-"+num));
+     855        2390 :       getPntrToComponent("sigma-"+num)->set(sigma_[i]);
+     856        2390 :       if(noise_type_==GENERIC) {
+     857           4 :         addComponent("ftilde-"+num); componentIsNotPeriodic("ftilde-"+num);
+     858           2 :         valueFtilde.push_back(getPntrToComponent("ftilde-"+num));
+     859             :       }
+     860             :     }
+     861          13 :   } else {
+     862          12 :     addComponent("sigmaMean"); componentIsNotPeriodic("sigmaMean");
+     863           6 :     valueSigmaMean.push_back(getPntrToComponent("sigmaMean"));
+     864          12 :     getPntrToComponent("sigmaMean")->set(std::sqrt(sigma_mean2_[0]));
+     865          12 :     addComponent("sigma"); componentIsNotPeriodic("sigma");
+     866           6 :     valueSigma.push_back(getPntrToComponent("sigma"));
+     867          12 :     getPntrToComponent("sigma")->set(sigma_[0]);
+     868             :   }
+     869             : 
+     870             :   // initialize random seed
+     871             :   unsigned iseed;
+     872          19 :   if(master) {
+     873          11 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     874          11 :     iseed = static_cast<unsigned>(ts)+replica_;
+     875             :   } else {
+     876           8 :     iseed = 0;
+     877             :   }
+     878          19 :   comm.Sum(&iseed, 1);
+     879             :   // this is used for ftilde and sigma both the move and the acceptance
+     880             :   // this is different for each replica
+     881          19 :   random[0].setSeed(-iseed);
+     882          19 :   if(doscale_||dooffset_) {
+     883             :     // in this case we want the same seed everywhere
+     884          14 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     885          14 :     iseed = static_cast<unsigned>(ts);
+     886          14 :     if(master&&nrep_>1) multi_sim_comm.Bcast(iseed,0);
+     887          14 :     comm.Bcast(iseed,0);
+     888             :     // this is used for scale and offset sampling and acceptance
+     889          14 :     random[1].setSeed(-iseed);
+     890             :   }
+     891             :   // this is used for random chunk of sigmas, and it is different for each replica
+     892          19 :   if(master) {
+     893          11 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     894          11 :     iseed = static_cast<unsigned>(ts)+replica_;
+     895             :   } else {
+     896           8 :     iseed = 0;
+     897             :   }
+     898          19 :   comm.Sum(&iseed, 1);
+     899          19 :   random[2].setSeed(-iseed);
+     900             : 
+     901             :   // outfile stuff
+     902          19 :   if(write_stride_>0) {
+     903          19 :     sfile_.link(*this);
+     904          19 :     sfile_.open(status_file_name_);
+     905             :   }
+     906             : 
+     907          38 :   log<<"  Bibliography "<<plumed.cite("Bonomi, Camilloni, Cavalli, Vendruscolo, Sci. Adv. 2, e150117 (2016)");
+     908          35 :   if(do_reweight_) log<<plumed.cite("Bonomi, Camilloni, Vendruscolo, Sci. Rep. 6, 31232 (2016)");
+     909          19 :   if(do_optsigmamean_>0) log<<plumed.cite("Loehr, Jussupow, Camilloni, J. Chem. Phys. 146, 165102 (2017)");
+     910          38 :   log<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     911          19 :   log<<"\n";
+     912          38 : }
+     913             : 
+     914          38 : Metainference::~Metainference()
+     915             : {
+     916          19 :   if(sfile_.isOpen()) sfile_.close();
+     917         114 : }
+     918             : 
+     919         156 : double Metainference::getEnergySP(const std::vector<double> &mean, const std::vector<double> &sigma,
+     920             :                                   const double scale, const double offset)
+     921             : {
+     922         156 :   const double scale2 = scale*scale;
+     923         156 :   const double sm2    = sigma_mean2_[0];
+     924         156 :   const double ss2    = sigma[0]*sigma[0] + scale2*sm2;
+     925         156 :   const double sss    = sigma[0]*sigma[0] + sm2;
+     926             : 
+     927             :   double ene = 0.0;
+     928         156 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     929             :   {
+     930             :     #pragma omp for reduction( + : ene)
+     931             :     for(unsigned i=0; i<narg; ++i) {
+     932             :       const double dev = scale*mean[i]-parameters[i]+offset;
+     933             :       const double a2 = 0.5*dev*dev + ss2;
+     934             :       if(sm2 > 0.0) {
+     935             :         ene += std::log(2.0*a2/(1.0-std::exp(-a2/sm2)));
+     936             :       }
+     937             :       else {
+     938             :         ene += std::log(2.0*a2);
+     939             :       }
+     940             :     }
+     941             :   }
+     942             :   // add one single Jeffrey's prior and one normalisation per data point
+     943         156 :   ene += 0.5*std::log(sss) + static_cast<double>(narg)*0.5*std::log(0.5*M_PI*M_PI/ss2);
+     944         156 :   if(doscale_ || doregres_zero_) ene += 0.5*std::log(sss);
+     945         156 :   if(dooffset_) ene += 0.5*std::log(sss);
+     946         156 :   return kbt_ * ene;
+     947             : }
+     948             : 
+     949         144 : double Metainference::getEnergySPE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     950             :                                    const double scale, const double offset)
+     951             : {
+     952         144 :   const double scale2 = scale*scale;
+     953             :   double ene = 0.0;
+     954         144 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     955             :   {
+     956             :     #pragma omp for reduction( + : ene)
+     957             :     for(unsigned i=0; i<narg; ++i) {
+     958             :       const double sm2 = sigma_mean2_[i];
+     959             :       const double ss2 = sigma[i]*sigma[i] + scale2*sm2;
+     960             :       const double sss = sigma[i]*sigma[i] + sm2;
+     961             :       const double dev = scale*mean[i]-parameters[i]+offset;
+     962             :       const double a2  = 0.5*dev*dev + ss2;
+     963             :       if(sm2 > 0.0) {
+     964             :         ene += 0.5*std::log(sss) + 0.5*std::log(0.5*M_PI*M_PI/ss2) + std::log(2.0*a2/(1.0-std::exp(-a2/sm2)));
+     965             :       }
+     966             :       else {
+     967             :         ene += 0.5*std::log(sss) + 0.5*std::log(0.5*M_PI*M_PI/ss2) + std::log(2.0*a2);
+     968             :       }
+     969             :       if(doscale_ || doregres_zero_)  ene += 0.5*std::log(sss);
+     970             :       if(dooffset_) ene += 0.5*std::log(sss);
+     971             :     }
+     972             :   }
+     973         144 :   return kbt_ * ene;
+     974             : }
+     975             : 
+     976          48 : double Metainference::getEnergyMIGEN(const std::vector<double> &mean, const std::vector<double> &ftilde, const std::vector<double> &sigma,
+     977             :                                      const double scale, const double offset)
+     978             : {
+     979             :   double ene = 0.0;
+     980          48 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     981             :   {
+     982             :     #pragma omp for reduction( + : ene)
+     983             :     for(unsigned i=0; i<narg; ++i) {
+     984             :       const double inv_sb2  = 1./(sigma[i]*sigma[i]);
+     985             :       const double inv_sm2  = 1./sigma_mean2_[i];
+     986             :       double devb = 0;
+     987             :       if(gen_likelihood_==LIKE_GAUSS)     devb = scale*ftilde[i]-parameters[i]+offset;
+     988             :       else if(gen_likelihood_==LIKE_LOGN) devb = std::log(scale*ftilde[i]/parameters[i]);
+     989             :       double devm = mean[i] - ftilde[i];
+     990             :       // deviation + normalisation + jeffrey
+     991             :       double normb = 0.;
+     992             :       if(gen_likelihood_==LIKE_GAUSS)     normb = -0.5*std::log(0.5/M_PI*inv_sb2);
+     993             :       else if(gen_likelihood_==LIKE_LOGN) normb = -0.5*std::log(0.5/M_PI*inv_sb2/(parameters[i]*parameters[i]));
+     994             :       const double normm         = -0.5*std::log(0.5/M_PI*inv_sm2);
+     995             :       const double jeffreys      = -0.5*std::log(2.*inv_sb2);
+     996             :       ene += 0.5*devb*devb*inv_sb2 + 0.5*devm*devm*inv_sm2 + normb + normm + jeffreys;
+     997             :       if(doscale_ || doregres_zero_)  ene += jeffreys;
+     998             :       if(dooffset_) ene += jeffreys;
+     999             :     }
+    1000             :   }
+    1001          48 :   return kbt_ * ene;
+    1002             : }
+    1003             : 
+    1004          36 : double Metainference::getEnergyGJ(const std::vector<double> &mean, const std::vector<double> &sigma,
+    1005             :                                   const double scale, const double offset)
+    1006             : {
+    1007          36 :   const double scale2  = scale*scale;
+    1008          36 :   const double inv_s2  = 1./(sigma[0]*sigma[0] + scale2*sigma_mean2_[0]);
+    1009          36 :   const double inv_sss = 1./(sigma[0]*sigma[0] + sigma_mean2_[0]);
+    1010             : 
+    1011             :   double ene = 0.0;
+    1012          36 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+    1013             :   {
+    1014             :     #pragma omp for reduction( + : ene)
+    1015             :     for(unsigned i=0; i<narg; ++i) {
+    1016             :       double dev = scale*mean[i]-parameters[i]+offset;
+    1017             :       ene += 0.5*dev*dev*inv_s2;
+    1018             :     }
+    1019             :   }
+    1020          36 :   const double normalisation = -0.5*std::log(0.5/M_PI*inv_s2);
+    1021          36 :   const double jeffreys = -0.5*std::log(2.*inv_sss);
+    1022             :   // add Jeffrey's prior in case one sigma for all data points + one normalisation per datapoint
+    1023          36 :   ene += jeffreys + static_cast<double>(narg)*normalisation;
+    1024          36 :   if(doscale_ || doregres_zero_)  ene += jeffreys;
+    1025          36 :   if(dooffset_) ene += jeffreys;
+    1026             : 
+    1027          36 :   return kbt_ * ene;
+    1028             : }
+    1029             : 
+    1030         152 : double Metainference::getEnergyGJE(const std::vector<double> &mean, const std::vector<double> &sigma,
+    1031             :                                    const double scale, const double offset)
+    1032             : {
+    1033         152 :   const double scale2 = scale*scale;
+    1034             : 
+    1035             :   double ene = 0.0;
+    1036         152 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+    1037             :   {
+    1038             :     #pragma omp for reduction( + : ene)
+    1039             :     for(unsigned i=0; i<narg; ++i) {
+    1040             :       const double inv_s2  = 1./(sigma[i]*sigma[i] + scale2*sigma_mean2_[i]);
+    1041             :       const double inv_sss = 1./(sigma[i]*sigma[i] + sigma_mean2_[i]);
+    1042             :       double dev = scale*mean[i]-parameters[i]+offset;
+    1043             :       // deviation + normalisation + jeffrey
+    1044             :       const double normalisation = -0.5*std::log(0.5/M_PI*inv_s2);
+    1045             :       const double jeffreys      = -0.5*std::log(2.*inv_sss);
+    1046             :       ene += 0.5*dev*dev*inv_s2 + normalisation + jeffreys;
+    1047             :       if(doscale_ || doregres_zero_)  ene += jeffreys;
+    1048             :       if(dooffset_) ene += jeffreys;
+    1049             :     }
+    1050             :   }
+    1051         152 :   return kbt_ * ene;
+    1052             : }
+    1053             : 
+    1054          12 : void Metainference::moveTilde(const std::vector<double> &mean_, double &old_energy)
+    1055             : {
+    1056          12 :   std::vector<double> new_ftilde(sigma_.size());
+    1057          12 :   new_ftilde = ftilde_;
+    1058             : 
+    1059             :   // change all tildes
+    1060          36 :   for(unsigned j=0; j<sigma_.size(); j++) {
+    1061          24 :     const double r3 = random[0].Gaussian();
+    1062          24 :     const double ds3 = Dftilde_*std::sqrt(sigma_mean2_[j])*r3;
+    1063          24 :     new_ftilde[j] = ftilde_[j] + ds3;
+    1064             :   }
+    1065             :   // calculate new energy
+    1066          12 :   double new_energy = getEnergyMIGEN(mean_,new_ftilde,sigma_,scale_,offset_);
+    1067             : 
+    1068             :   // accept or reject
+    1069          12 :   const double delta = ( new_energy - old_energy ) / kbt_;
+    1070             :   // if delta is negative always accept move
+    1071          12 :   if( delta <= 0.0 ) {
+    1072          12 :     old_energy = new_energy;
+    1073          12 :     ftilde_ = new_ftilde;
+    1074          12 :     MCacceptFT_++;
+    1075             :     // otherwise extract random number
+    1076             :   } else {
+    1077           0 :     const double s = random[0].RandU01();
+    1078           0 :     if( s < std::exp(-delta) ) {
+    1079           0 :       old_energy = new_energy;
+    1080           0 :       ftilde_ = new_ftilde;
+    1081           0 :       MCacceptFT_++;
+    1082             :     }
+    1083             :   }
+    1084          12 : }
+    1085             : 
+    1086         168 : void Metainference::moveScaleOffset(const std::vector<double> &mean_, double &old_energy)
+    1087             : {
+    1088         168 :   double new_scale = scale_;
+    1089             : 
+    1090         168 :   if(doscale_) {
+    1091         144 :     if(scale_prior_==SC_FLAT) {
+    1092         144 :       const double r1 = random[1].Gaussian();
+    1093         144 :       const double ds1 = Dscale_*r1;
+    1094         144 :       new_scale += ds1;
+    1095             :       // check boundaries
+    1096         144 :       if(new_scale > scale_max_) {new_scale = 2.0 * scale_max_ - new_scale;}
+    1097         144 :       if(new_scale < scale_min_) {new_scale = 2.0 * scale_min_ - new_scale;}
+    1098             :     } else {
+    1099           0 :       const double r1 = random[1].Gaussian();
+    1100           0 :       const double ds1 = 0.5*(scale_mu_-new_scale)+Dscale_*std::exp(1)/M_PI*r1;
+    1101           0 :       new_scale += ds1;
+    1102             :     }
+    1103             :   }
+    1104             : 
+    1105         168 :   double new_offset = offset_;
+    1106             : 
+    1107         168 :   if(dooffset_) {
+    1108          24 :     if(offset_prior_==SC_FLAT) {
+    1109          24 :       const double r1 = random[1].Gaussian();
+    1110          24 :       const double ds1 = Doffset_*r1;
+    1111          24 :       new_offset += ds1;
+    1112             :       // check boundaries
+    1113          24 :       if(new_offset > offset_max_) {new_offset = 2.0 * offset_max_ - new_offset;}
+    1114          24 :       if(new_offset < offset_min_) {new_offset = 2.0 * offset_min_ - new_offset;}
+    1115             :     } else {
+    1116           0 :       const double r1 = random[1].Gaussian();
+    1117           0 :       const double ds1 = 0.5*(offset_mu_-new_offset)+Doffset_*std::exp(1)/M_PI*r1;
+    1118           0 :       new_offset += ds1;
+    1119             :     }
+    1120             :   }
+    1121             : 
+    1122             :   // calculate new energy
+    1123             :   double new_energy = 0.;
+    1124             : 
+    1125         168 :   switch(noise_type_) {
+    1126          12 :   case GAUSS:
+    1127          12 :     new_energy = getEnergyGJ(mean_,sigma_,new_scale,new_offset);
+    1128             :     break;
+    1129          48 :   case MGAUSS:
+    1130          48 :     new_energy = getEnergyGJE(mean_,sigma_,new_scale,new_offset);
+    1131             :     break;
+    1132          48 :   case OUTLIERS:
+    1133          48 :     new_energy = getEnergySP(mean_,sigma_,new_scale,new_offset);
+    1134             :     break;
+    1135          48 :   case MOUTLIERS:
+    1136          48 :     new_energy = getEnergySPE(mean_,sigma_,new_scale,new_offset);
+    1137             :     break;
+    1138          12 :   case GENERIC:
+    1139          12 :     new_energy = getEnergyMIGEN(mean_,ftilde_,sigma_,new_scale,new_offset);
+    1140             :     break;
+    1141             :   }
+    1142             : 
+    1143             :   // for the scale/offset we need to consider the total energy
+    1144         168 :   std::vector<double> totenergies(2);
+    1145         168 :   if(master) {
+    1146          96 :     totenergies[0] = old_energy;
+    1147          96 :     totenergies[1] = new_energy;
+    1148          96 :     if(nrep_>1) multi_sim_comm.Sum(totenergies);
+    1149             :   } else {
+    1150          72 :     totenergies[0] = 0;
+    1151          72 :     totenergies[1] = 0;
+    1152             :   }
+    1153         168 :   comm.Sum(totenergies);
+    1154             : 
+    1155             :   // accept or reject
+    1156         168 :   const double delta = ( totenergies[1] - totenergies[0] ) / kbt_;
+    1157             :   // if delta is negative always accept move
+    1158         168 :   if( delta <= 0.0 ) {
+    1159         168 :     old_energy = new_energy;
+    1160         168 :     scale_ = new_scale;
+    1161         168 :     offset_ = new_offset;
+    1162         168 :     MCacceptScale_++;
+    1163             :     // otherwise extract random number
+    1164             :   } else {
+    1165           0 :     double s = random[1].RandU01();
+    1166           0 :     if( s < std::exp(-delta) ) {
+    1167           0 :       old_energy = new_energy;
+    1168           0 :       scale_ = new_scale;
+    1169           0 :       offset_ = new_offset;
+    1170           0 :       MCacceptScale_++;
+    1171             :     }
+    1172             :   }
+    1173         168 : }
+    1174             : 
+    1175         178 : void Metainference::moveSigmas(const std::vector<double> &mean_, double &old_energy, const unsigned i, const std::vector<unsigned> &indices, bool &breaknow)
+    1176             : {
+    1177         178 :   std::vector<double> new_sigma(sigma_.size());
+    1178         178 :   new_sigma = sigma_;
+    1179             : 
+    1180             :   // change MCchunksize_ sigmas
+    1181         178 :   if (MCchunksize_ > 0) {
+    1182           0 :     if ((MCchunksize_ * i) >= sigma_.size()) {
+    1183             :       // This means we are not moving any sigma, so we should break immediately
+    1184           0 :       breaknow = true;
+    1185             :     }
+    1186             : 
+    1187             :     // change random sigmas
+    1188           0 :     for(unsigned j=0; j<MCchunksize_; j++) {
+    1189           0 :       const unsigned shuffle_index = j + MCchunksize_ * i;
+    1190           0 :       if (shuffle_index >= sigma_.size()) {
+    1191             :         // Going any further will segfault but we should still evaluate the sigmas we changed
+    1192             :         break;
+    1193             :       }
+    1194           0 :       const unsigned index = indices[shuffle_index];
+    1195           0 :       const double r2 = random[0].Gaussian();
+    1196           0 :       const double ds2 = Dsigma_[index]*r2;
+    1197           0 :       new_sigma[index] = sigma_[index] + ds2;
+    1198             :       // check boundaries
+    1199           0 :       if(new_sigma[index] > sigma_max_[index]) {new_sigma[index] = 2.0 * sigma_max_[index] - new_sigma[index];}
+    1200           0 :       if(new_sigma[index] < sigma_min_[index]) {new_sigma[index] = 2.0 * sigma_min_[index] - new_sigma[index];}
+    1201             :     }
+    1202             :   } else {
+    1203             :     // change all sigmas
+    1204        3008 :     for(unsigned j=0; j<sigma_.size(); j++) {
+    1205        2830 :       const double r2 = random[0].Gaussian();
+    1206        2830 :       const double ds2 = Dsigma_[j]*r2;
+    1207        2830 :       new_sigma[j] = sigma_[j] + ds2;
+    1208             :       // check boundaries
+    1209        2830 :       if(new_sigma[j] > sigma_max_[j]) {new_sigma[j] = 2.0 * sigma_max_[j] - new_sigma[j];}
+    1210        2830 :       if(new_sigma[j] < sigma_min_[j]) {new_sigma[j] = 2.0 * sigma_min_[j] - new_sigma[j];}
+    1211             :     }
+    1212             :   }
+    1213             : 
+    1214         178 :   if (breaknow) {
+    1215             :     // We didnt move any sigmas, so no sense in evaluating anything
+    1216             :     return;
+    1217             :   }
+    1218             : 
+    1219             :   // calculate new energy
+    1220             :   double new_energy = 0.;
+    1221         178 :   switch(noise_type_) {
+    1222          12 :   case GAUSS:
+    1223          12 :     new_energy = getEnergyGJ(mean_,new_sigma,scale_,offset_);
+    1224             :     break;
+    1225          52 :   case MGAUSS:
+    1226          52 :     new_energy = getEnergyGJE(mean_,new_sigma,scale_,offset_);
+    1227             :     break;
+    1228          54 :   case OUTLIERS:
+    1229          54 :     new_energy = getEnergySP(mean_,new_sigma,scale_,offset_);
+    1230             :     break;
+    1231          48 :   case MOUTLIERS:
+    1232          48 :     new_energy = getEnergySPE(mean_,new_sigma,scale_,offset_);
+    1233             :     break;
+    1234          12 :   case GENERIC:
+    1235          12 :     new_energy = getEnergyMIGEN(mean_,ftilde_,new_sigma,scale_,offset_);
+    1236             :     break;
+    1237             :   }
+    1238             : 
+    1239             :   // accept or reject
+    1240         178 :   const double delta = ( new_energy - old_energy ) / kbt_;
+    1241             :   // if delta is negative always accept move
+    1242         178 :   if( delta <= 0.0 ) {
+    1243         178 :     old_energy = new_energy;
+    1244         178 :     sigma_ = new_sigma;
+    1245         178 :     MCaccept_++;
+    1246             :     // otherwise extract random number
+    1247             :   } else {
+    1248           0 :     const double s = random[0].RandU01();
+    1249           0 :     if( s < std::exp(-delta) ) {
+    1250           0 :       old_energy = new_energy;
+    1251           0 :       sigma_ = new_sigma;
+    1252           0 :       MCaccept_++;
+    1253             :     }
+    1254             :   }
+    1255             : }
+    1256             : 
+    1257         178 : double Metainference::doMonteCarlo(const std::vector<double> &mean_)
+    1258             : {
+    1259             :   // calculate old energy with the updated coordinates
+    1260         178 :   double old_energy=0.;
+    1261             : 
+    1262         178 :   switch(noise_type_) {
+    1263          12 :   case GAUSS:
+    1264          12 :     old_energy = getEnergyGJ(mean_,sigma_,scale_,offset_);
+    1265          12 :     break;
+    1266          52 :   case MGAUSS:
+    1267          52 :     old_energy = getEnergyGJE(mean_,sigma_,scale_,offset_);
+    1268          52 :     break;
+    1269          54 :   case OUTLIERS:
+    1270          54 :     old_energy = getEnergySP(mean_,sigma_,scale_,offset_);
+    1271          54 :     break;
+    1272          48 :   case MOUTLIERS:
+    1273          48 :     old_energy = getEnergySPE(mean_,sigma_,scale_,offset_);
+    1274          48 :     break;
+    1275          12 :   case GENERIC:
+    1276          12 :     old_energy = getEnergyMIGEN(mean_,ftilde_,sigma_,scale_,offset_);
+    1277          12 :     break;
+    1278             :   }
+    1279             : 
+    1280             :   // do not run MC if this is a replica-exchange trial
+    1281         178 :   if(!getExchangeStep()) {
+    1282             : 
+    1283             :     // Create std::vector of random sigma indices
+    1284             :     std::vector<unsigned> indices;
+    1285         178 :     if (MCchunksize_ > 0) {
+    1286           0 :       for (unsigned j=0; j<sigma_.size(); j++) {
+    1287           0 :         indices.push_back(j);
+    1288             :       }
+    1289           0 :       random[2].Shuffle(indices);
+    1290             :     }
+    1291         178 :     bool breaknow = false;
+    1292             : 
+    1293             :     // cycle on MC steps
+    1294         356 :     for(unsigned i=0; i<MCsteps_; ++i) {
+    1295         178 :       MCtrial_++;
+    1296             :       // propose move for ftilde
+    1297         178 :       if(noise_type_==GENERIC) moveTilde(mean_, old_energy);
+    1298             :       // propose move for scale and/or offset
+    1299         178 :       if(doscale_||dooffset_) moveScaleOffset(mean_, old_energy);
+    1300             :       // propose move for sigma
+    1301         178 :       moveSigmas(mean_, old_energy, i, indices, breaknow);
+    1302             :       // exit from the loop if this is the case
+    1303         178 :       if(breaknow) break;
+    1304             :     }
+    1305             : 
+    1306             :     /* save the result of the sampling */
+    1307             :     /* ftilde */
+    1308         178 :     if(noise_type_==GENERIC) {
+    1309          12 :       double accept = static_cast<double>(MCacceptFT_) / static_cast<double>(MCtrial_);
+    1310          12 :       valueAcceptFT->set(accept);
+    1311          36 :       for(unsigned i=0; i<sigma_.size(); i++) valueFtilde[i]->set(ftilde_[i]);
+    1312             :     }
+    1313             :     /* scale and offset */
+    1314         178 :     if(doscale_ || doregres_zero_) valueScale->set(scale_);
+    1315         178 :     if(dooffset_) valueOffset->set(offset_);
+    1316         178 :     if(doscale_||dooffset_) {
+    1317         168 :       double accept = static_cast<double>(MCacceptScale_) / static_cast<double>(MCtrial_);
+    1318         168 :       valueAcceptScale->set(accept);
+    1319             :     }
+    1320             :     /* sigmas */
+    1321        3008 :     for(unsigned i=0; i<sigma_.size(); i++) valueSigma[i]->set(sigma_[i]);
+    1322         178 :     double accept = static_cast<double>(MCaccept_) / static_cast<double>(MCtrial_);
+    1323         178 :     valueAccept->set(accept);
+    1324             :   }
+    1325             : 
+    1326             :   // here we sum the score over the replicas to get the full metainference score that we save as a bias
+    1327         178 :   if(master) {
+    1328         104 :     if(nrep_>1) multi_sim_comm.Sum(old_energy);
+    1329             :   } else {
+    1330          74 :     old_energy=0;
+    1331             :   }
+    1332         178 :   comm.Sum(old_energy);
+    1333             : 
+    1334             :   // this is the energy with current coordinates and parameters
+    1335         178 :   return old_energy;
+    1336             : }
+    1337             : 
+    1338             : /*
+    1339             :    In the following energy-force functions we don't add the normalisation and the jeffreys priors
+    1340             :    because they are not needed for the forces, the correct MetaInference energy is the one calculated
+    1341             :    in the Monte-Carlo
+    1342             : */
+    1343             : 
+    1344          54 : void Metainference::getEnergyForceSP(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1345             :                                      const std::vector<double> &dmean_b)
+    1346             : {
+    1347          54 :   const double scale2 = scale_*scale_;
+    1348          54 :   const double sm2    = sigma_mean2_[0];
+    1349          54 :   const double ss2    = sigma_[0]*sigma_[0] + scale2*sm2;
+    1350          54 :   std::vector<double> f(narg,0);
+    1351             : 
+    1352          54 :   if(master) {
+    1353          30 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1354             :     {
+    1355             :       #pragma omp for
+    1356             :       for(unsigned i=0; i<narg; ++i) {
+    1357             :         const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1358             :         const double a2 = 0.5*dev*dev + ss2;
+    1359             :         if(sm2 > 0.0) {
+    1360             :           const double t = std::exp(-a2/sm2);
+    1361             :           const double dt = 1./t;
+    1362             :           const double dit = 1./(1.-dt);
+    1363             :           f[i] = -scale_*dev*(dit/sm2 + 1./a2);
+    1364             :         }
+    1365             :         else {
+    1366             :           f[i] = -scale_*dev*(1./a2);
+    1367             :         }
+    1368             :       }
+    1369             :     }
+    1370             :     // collect contribution to forces and energy from other replicas
+    1371          30 :     if(nrep_>1) multi_sim_comm.Sum(&f[0],narg);
+    1372             :   }
+    1373             :   // intra-replica summation
+    1374          54 :   comm.Sum(&f[0],narg);
+    1375             : 
+    1376             :   double w_tmp = 0.;
+    1377         288 :   for(unsigned i=0; i<narg; ++i) {
+    1378         234 :     setOutputForce(i, kbt_*f[i]*dmean_x[i]);
+    1379         234 :     w_tmp += kbt_*f[i]*dmean_b[i];
+    1380             :   }
+    1381             : 
+    1382          54 :   if(do_reweight_) {
+    1383          48 :     setOutputForce(narg, w_tmp);
+    1384          96 :     getPntrToComponent("biasDer")->set(-w_tmp);
+    1385             :   }
+    1386          54 : }
+    1387             : 
+    1388          48 : void Metainference::getEnergyForceSPE(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1389             :                                       const std::vector<double> &dmean_b)
+    1390             : {
+    1391          48 :   const double scale2 = scale_*scale_;
+    1392          48 :   std::vector<double> f(narg,0);
+    1393             : 
+    1394          48 :   if(master) {
+    1395          24 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1396             :     {
+    1397             :       #pragma omp for
+    1398             :       for(unsigned i=0; i<narg; ++i) {
+    1399             :         const double sm2 = sigma_mean2_[i];
+    1400             :         const double ss2 = sigma_[i]*sigma_[i] + scale2*sm2;
+    1401             :         const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1402             :         const double a2  = 0.5*dev*dev + ss2;
+    1403             :         if(sm2 > 0.0) {
+    1404             :           const double t   = std::exp(-a2/sm2);
+    1405             :           const double dt  = 1./t;
+    1406             :           const double dit = 1./(1.-dt);
+    1407             :           f[i] = -scale_*dev*(dit/sm2 + 1./a2);
+    1408             :         }
+    1409             :         else {
+    1410             :           f[i] = -scale_*dev*(1./a2);
+    1411             :         }
+    1412             :       }
+    1413             :     }
+    1414             :     // collect contribution to forces and energy from other replicas
+    1415          24 :     if(nrep_>1) multi_sim_comm.Sum(&f[0],narg);
+    1416             :   }
+    1417          48 :   comm.Sum(&f[0],narg);
+    1418             : 
+    1419             :   double w_tmp = 0.;
+    1420         240 :   for(unsigned i=0; i<narg; ++i) {
+    1421         192 :     setOutputForce(i, kbt_ * dmean_x[i] * f[i]);
+    1422         192 :     w_tmp += kbt_ * dmean_b[i] *f[i];
+    1423             :   }
+    1424             : 
+    1425          48 :   if(do_reweight_) {
+    1426          48 :     setOutputForce(narg, w_tmp);
+    1427          96 :     getPntrToComponent("biasDer")->set(-w_tmp);
+    1428             :   }
+    1429          48 : }
+    1430             : 
+    1431          12 : void Metainference::getEnergyForceGJ(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1432             :                                      const std::vector<double> &dmean_b)
+    1433             : {
+    1434          12 :   const double scale2 = scale_*scale_;
+    1435          12 :   double inv_s2=0.;
+    1436             : 
+    1437          12 :   if(master) {
+    1438          12 :     inv_s2 = 1./(sigma_[0]*sigma_[0] + scale2*sigma_mean2_[0]);
+    1439          12 :     if(nrep_>1) multi_sim_comm.Sum(inv_s2);
+    1440             :   }
+    1441          12 :   comm.Sum(inv_s2);
+    1442             : 
+    1443             :   double w_tmp = 0.;
+    1444          12 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(w_tmp)
+    1445             :   {
+    1446             :     #pragma omp for reduction( + : w_tmp)
+    1447             :     for(unsigned i=0; i<narg; ++i) {
+    1448             :       const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1449             :       const double mult = dev*scale_*inv_s2;
+    1450             :       setOutputForce(i, -kbt_*dmean_x[i]*mult);
+    1451             :       w_tmp += kbt_*dmean_b[i]*mult;
+    1452             :     }
+    1453             :   }
+    1454             : 
+    1455          12 :   if(do_reweight_) {
+    1456           0 :     setOutputForce(narg, -w_tmp);
+    1457           0 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1458             :   }
+    1459          12 : }
+    1460             : 
+    1461          52 : void Metainference::getEnergyForceGJE(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1462             :                                       const std::vector<double> &dmean_b)
+    1463             : {
+    1464          52 :   const double scale2 = scale_*scale_;
+    1465          52 :   std::vector<double> inv_s2(sigma_.size(),0.);
+    1466             : 
+    1467          52 :   if(master) {
+    1468        1300 :     for(unsigned i=0; i<sigma_.size(); ++i) inv_s2[i] = 1./(sigma_[i]*sigma_[i] + scale2*sigma_mean2_[i]);
+    1469          26 :     if(nrep_>1) multi_sim_comm.Sum(&inv_s2[0],sigma_.size());
+    1470             :   }
+    1471          52 :   comm.Sum(&inv_s2[0],sigma_.size());
+    1472             : 
+    1473             :   double w_tmp = 0.;
+    1474          52 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(w_tmp)
+    1475             :   {
+    1476             :     #pragma omp for reduction( + : w_tmp)
+    1477             :     for(unsigned i=0; i<narg; ++i) {
+    1478             :       const double dev  = scale_*mean[i]-parameters[i]+offset_;
+    1479             :       const double mult = dev*scale_*inv_s2[i];
+    1480             :       setOutputForce(i, -kbt_*dmean_x[i]*mult);
+    1481             :       w_tmp += kbt_*dmean_b[i]*mult;
+    1482             :     }
+    1483             :   }
+    1484             : 
+    1485          52 :   if(do_reweight_) {
+    1486          52 :     setOutputForce(narg, -w_tmp);
+    1487         104 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1488             :   }
+    1489          52 : }
+    1490             : 
+    1491          12 : void Metainference::getEnergyForceMIGEN(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b)
+    1492             : {
+    1493          12 :   std::vector<double> inv_s2(sigma_.size(),0.);
+    1494          12 :   std::vector<double> dev(sigma_.size(),0.);
+    1495          12 :   std::vector<double> dev2(sigma_.size(),0.);
+    1496             : 
+    1497          36 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+    1498          24 :     inv_s2[i]   = 1./sigma_mean2_[i];
+    1499          24 :     if(master) {
+    1500          24 :       dev[i]  = (mean[i]-ftilde_[i]);
+    1501          24 :       dev2[i] = dev[i]*dev[i];
+    1502             :     }
+    1503             :   }
+    1504          12 :   if(master&&nrep_>1) {
+    1505           0 :     multi_sim_comm.Sum(&dev[0],dev.size());
+    1506           0 :     multi_sim_comm.Sum(&dev2[0],dev2.size());
+    1507             :   }
+    1508          12 :   comm.Sum(&dev[0],dev.size());
+    1509          12 :   comm.Sum(&dev2[0],dev2.size());
+    1510             : 
+    1511             :   double dene_b = 0.;
+    1512          12 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(dene_b)
+    1513             :   {
+    1514             :     #pragma omp for reduction( + : dene_b)
+    1515             :     for(unsigned i=0; i<narg; ++i) {
+    1516             :       const double dene_x  = kbt_*inv_s2[i]*dmean_x[i]*dev[i];
+    1517             :       dene_b += kbt_*inv_s2[i]*dmean_b[i]*dev[i];
+    1518             :       setOutputForce(i, -dene_x);
+    1519             :     }
+    1520             :   }
+    1521             : 
+    1522          12 :   if(do_reweight_) {
+    1523           0 :     setOutputForce(narg, -dene_b);
+    1524           0 :     getPntrToComponent("biasDer")->set(dene_b);
+    1525             :   }
+    1526          12 : }
+    1527             : 
+    1528         178 : void Metainference::get_weights(const unsigned iselect, double &weight, double &norm, double &neff)
+    1529             : {
+    1530         178 :   const double dnrep = static_cast<double>(nrep_);
+    1531             :   // calculate the weights either from BIAS
+    1532         178 :   if(do_reweight_) {
+    1533         148 :     std::vector<double> bias(nrep_,0);
+    1534         148 :     if(master) {
+    1535          74 :       bias[replica_] = getArgument(narg);
+    1536          74 :       if(nrep_>1) multi_sim_comm.Sum(&bias[0], nrep_);
+    1537             :     }
+    1538         148 :     comm.Sum(&bias[0], nrep_);
+    1539             : 
+    1540             :     // accumulate weights
+    1541         148 :     const double decay = 1./static_cast<double> (average_weights_stride_);
+    1542         148 :     if(!firstTimeW[iselect]) {
+    1543         408 :       for(unsigned i=0; i<nrep_; ++i) {
+    1544         272 :         const double delta=bias[i]-average_weights_[iselect][i];
+    1545         272 :         average_weights_[iselect][i]+=decay*delta;
+    1546             :       }
+    1547             :     } else {
+    1548             :       firstTimeW[iselect] = false;
+    1549          36 :       for(unsigned i=0; i<nrep_; ++i) average_weights_[iselect][i] = bias[i];
+    1550             :     }
+    1551             : 
+    1552             :     // set average back into bias and set norm to one
+    1553         148 :     const double maxbias = *(std::max_element(average_weights_[iselect].begin(), average_weights_[iselect].end()));
+    1554         444 :     for(unsigned i=0; i<nrep_; ++i) bias[i] = std::exp((average_weights_[iselect][i]-maxbias)/kbt_);
+    1555             :     // set local weight, norm and weight variance
+    1556         148 :     weight = bias[replica_];
+    1557             :     double w2=0.;
+    1558         444 :     for(unsigned i=0; i<nrep_; ++i) {
+    1559         296 :       w2 += bias[i]*bias[i];
+    1560         296 :       norm += bias[i];
+    1561             :     }
+    1562         148 :     neff = norm*norm/w2;
+    1563         296 :     getPntrToComponent("weight")->set(weight/norm);
+    1564             :   } else {
+    1565             :     // or arithmetic ones
+    1566          30 :     neff = dnrep;
+    1567          30 :     weight = 1.0;
+    1568          30 :     norm = dnrep;
+    1569             :   }
+    1570         178 :   getPntrToComponent("neff")->set(neff);
+    1571         178 : }
+    1572             : 
+    1573         178 : void Metainference::get_sigma_mean(const unsigned iselect, const double weight, const double norm, const double neff, const std::vector<double> &mean)
+    1574             : {
+    1575         178 :   const double dnrep    = static_cast<double>(nrep_);
+    1576         178 :   std::vector<double> sigma_mean2_tmp(sigma_mean2_.size(), 0.);
+    1577             : 
+    1578         178 :   if(do_optsigmamean_>0) {
+    1579             :     // remove first entry of the history std::vector
+    1580           0 :     if(sigma_mean2_last_[iselect][0].size()==optsigmamean_stride_&&optsigmamean_stride_>0)
+    1581           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[iselect][i].erase(sigma_mean2_last_[iselect][i].begin());
+    1582             :     /* this is the current estimate of sigma mean for each argument
+    1583             :        there is one of this per argument in any case  because it is
+    1584             :        the maximum among these to be used in case of GAUSS/OUTLIER */
+    1585           0 :     std::vector<double> sigma_mean2_now(narg,0);
+    1586           0 :     if(master) {
+    1587           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_now[i] = weight*(getArgument(i)-mean[i])*(getArgument(i)-mean[i]);
+    1588           0 :       if(nrep_>1) multi_sim_comm.Sum(&sigma_mean2_now[0], narg);
+    1589             :     }
+    1590           0 :     comm.Sum(&sigma_mean2_now[0], narg);
+    1591           0 :     for(unsigned i=0; i<narg; ++i) sigma_mean2_now[i] *= 1.0/(neff-1.)/norm;
+    1592             : 
+    1593             :     // add sigma_mean2 to history
+    1594           0 :     if(optsigmamean_stride_>0) {
+    1595           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[iselect][i].push_back(sigma_mean2_now[i]);
+    1596             :     } else {
+    1597           0 :       for(unsigned i=0; i<narg; ++i) if(sigma_mean2_now[i] > sigma_mean2_last_[iselect][i][0]) sigma_mean2_last_[iselect][i][0] = sigma_mean2_now[i];
+    1598             :     }
+    1599             : 
+    1600           0 :     if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1601           0 :       for(unsigned i=0; i<narg; ++i) {
+    1602             :         /* set to the maximum in history std::vector */
+    1603           0 :         sigma_mean2_tmp[i] = *max_element(sigma_mean2_last_[iselect][i].begin(), sigma_mean2_last_[iselect][i].end());
+    1604             :         /* the standard error of the mean */
+    1605           0 :         valueSigmaMean[i]->set(std::sqrt(sigma_mean2_tmp[i]));
+    1606           0 :         if(noise_type_==GENERIC) {
+    1607           0 :           sigma_min_[i] = std::sqrt(sigma_mean2_tmp[i]);
+    1608           0 :           if(sigma_[i] < sigma_min_[i]) sigma_[i] = sigma_min_[i];
+    1609             :         }
+    1610             :       }
+    1611           0 :     } else if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1612             :       // find maximum for each data point
+    1613             :       std::vector <double> max_values;
+    1614           0 :       for(unsigned i=0; i<narg; ++i) max_values.push_back(*max_element(sigma_mean2_last_[iselect][i].begin(), sigma_mean2_last_[iselect][i].end()));
+    1615             :       // find maximum across data points
+    1616           0 :       const double max_now = *max_element(max_values.begin(), max_values.end());
+    1617             :       // set new value
+    1618           0 :       sigma_mean2_tmp[0] = max_now;
+    1619           0 :       valueSigmaMean[0]->set(std::sqrt(sigma_mean2_tmp[0]));
+    1620             :     }
+    1621             :     // endif sigma mean optimization
+    1622             :     // start sigma max optimization
+    1623           0 :     if(do_optsigmamean_>1&&!sigmamax_opt_done_) {
+    1624           0 :       for(unsigned i=0; i<sigma_max_.size(); i++) {
+    1625           0 :         if(sigma_max_est_[i]<sigma_mean2_tmp[i]&&optimized_step_>optsigmamean_stride_) sigma_max_est_[i]=sigma_mean2_tmp[i];
+    1626             :         // ready to set once and for all the value of sigma_max
+    1627           0 :         if(optimized_step_==N_optimized_step_) {
+    1628           0 :           sigmamax_opt_done_=true;
+    1629           0 :           for(unsigned i=0; i<sigma_max_.size(); i++) {
+    1630           0 :             sigma_max_[i]=std::sqrt(sigma_max_est_[i]*dnrep);
+    1631           0 :             Dsigma_[i] = 0.05*(sigma_max_[i] - sigma_min_[i]);
+    1632           0 :             if(sigma_[i]>sigma_max_[i]) sigma_[i]=sigma_max_[i];
+    1633             :           }
+    1634             :         }
+    1635             :       }
+    1636           0 :       optimized_step_++;
+    1637             :     }
+    1638             :     // end sigma max optimization
+    1639             :   } else {
+    1640         178 :     if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1641        2876 :       for(unsigned i=0; i<narg; ++i) {
+    1642        2764 :         sigma_mean2_tmp[i] = sigma_mean2_last_[iselect][i][0];
+    1643        2764 :         valueSigmaMean[i]->set(std::sqrt(sigma_mean2_tmp[i]));
+    1644             :       }
+    1645          66 :     } else if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1646          66 :       sigma_mean2_tmp[0] = sigma_mean2_last_[iselect][0][0];
+    1647          66 :       valueSigmaMean[0]->set(std::sqrt(sigma_mean2_tmp[0]));
+    1648             :     }
+    1649             :   }
+    1650             : 
+    1651         178 :   sigma_mean2_ = sigma_mean2_tmp;
+    1652         178 : }
+    1653             : 
+    1654         178 : void Metainference::replica_averaging(const double weight, const double norm, std::vector<double> &mean, std::vector<double> &dmean_b)
+    1655             : {
+    1656         178 :   if(master) {
+    1657        1660 :     for(unsigned i=0; i<narg; ++i) mean[i] = weight/norm*getArgument(i);
+    1658         104 :     if(nrep_>1) multi_sim_comm.Sum(&mean[0], narg);
+    1659             :   }
+    1660         178 :   comm.Sum(&mean[0], narg);
+    1661             :   // set the derivative of the mean with respect to the bias
+    1662        3200 :   for(unsigned i=0; i<narg; ++i) dmean_b[i] = weight/norm/kbt_*(getArgument(i)-mean[i])/static_cast<double>(average_weights_stride_);
+    1663             : 
+    1664             :   // this is only for generic metainference
+    1665         178 :   if(firstTime) {ftilde_ = mean; firstTime = false;}
+    1666         178 : }
+    1667             : 
+    1668           0 : void Metainference::do_regression_zero(const std::vector<double> &mean)
+    1669             : {
+    1670             : // parameters[i] = scale_ * mean[i]: find scale_ with linear regression
+    1671             :   double num = 0.0;
+    1672             :   double den = 0.0;
+    1673           0 :   for(unsigned i=0; i<parameters.size(); ++i) {
+    1674           0 :     num += mean[i] * parameters[i];
+    1675           0 :     den += mean[i] * mean[i];
+    1676             :   }
+    1677           0 :   if(den>0) {
+    1678           0 :     scale_ = num / den;
+    1679             :   } else {
+    1680           0 :     scale_ = 1.0;
+    1681             :   }
+    1682           0 : }
+    1683             : 
+    1684         178 : void Metainference::calculate()
+    1685             : {
+    1686             :   // get step
+    1687         178 :   const long long int step = getStep();
+    1688             : 
+    1689             :   unsigned iselect = 0;
+    1690             :   // set the value of selector for  REM-like stuff
+    1691         178 :   if(selector_.length()>0) iselect = static_cast<unsigned>(plumed.passMap[selector_]);
+    1692             : 
+    1693             :   /* 1) collect weights */
+    1694         178 :   double weight = 0.;
+    1695         178 :   double neff = 0.;
+    1696         178 :   double norm = 0.;
+    1697         178 :   get_weights(iselect, weight, norm, neff);
+    1698             : 
+    1699             :   /* 2) calculate average */
+    1700         178 :   std::vector<double> mean(narg,0);
+    1701             :   // this is the derivative of the mean with respect to the argument
+    1702         178 :   std::vector<double> dmean_x(narg,weight/norm);
+    1703             :   // this is the derivative of the mean with respect to the bias
+    1704         178 :   std::vector<double> dmean_b(narg,0);
+    1705             :   // calculate it
+    1706         178 :   replica_averaging(weight, norm, mean, dmean_b);
+    1707             : 
+    1708             :   /* 3) calculates parameters */
+    1709         178 :   get_sigma_mean(iselect, weight, norm, neff, mean);
+    1710             : 
+    1711             :   // in case of regression with zero intercept, calculate scale
+    1712         178 :   if(doregres_zero_ && step%nregres_zero_==0) do_regression_zero(mean);
+    1713             : 
+    1714             :   /* 4) run monte carlo */
+    1715         178 :   double ene = doMonteCarlo(mean);
+    1716             : 
+    1717             :   // calculate bias and forces
+    1718         178 :   switch(noise_type_) {
+    1719          12 :   case GAUSS:
+    1720          12 :     getEnergyForceGJ(mean, dmean_x, dmean_b);
+    1721             :     break;
+    1722          52 :   case MGAUSS:
+    1723          52 :     getEnergyForceGJE(mean, dmean_x, dmean_b);
+    1724             :     break;
+    1725          54 :   case OUTLIERS:
+    1726          54 :     getEnergyForceSP(mean, dmean_x, dmean_b);
+    1727             :     break;
+    1728          48 :   case MOUTLIERS:
+    1729          48 :     getEnergyForceSPE(mean, dmean_x, dmean_b);
+    1730             :     break;
+    1731          12 :   case GENERIC:
+    1732          12 :     getEnergyForceMIGEN(mean, dmean_x, dmean_b);
+    1733             :     break;
+    1734             :   }
+    1735             : 
+    1736         178 :   setBias(ene);
+    1737         178 : }
+    1738             : 
+    1739          19 : void Metainference::writeStatus()
+    1740             : {
+    1741          19 :   sfile_.rewind();
+    1742          19 :   sfile_.printField("time",getTimeStep()*getStep());
+    1743             :   //nsel
+    1744          38 :   for(unsigned i=0; i<sigma_mean2_last_.size(); i++) {
+    1745             :     std::string msg_i,msg_j;
+    1746          19 :     Tools::convert(i,msg_i);
+    1747             :     std::vector <double> max_values;
+    1748             :     //narg
+    1749        2434 :     for(unsigned j=0; j<narg; ++j) {
+    1750        2415 :       Tools::convert(j,msg_j);
+    1751        2415 :       std::string msg = msg_i+"_"+msg_j;
+    1752        2415 :       if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1753        7170 :         sfile_.printField("sigmaMean_"+msg,std::sqrt(*max_element(sigma_mean2_last_[i][j].begin(), sigma_mean2_last_[i][j].end())));
+    1754             :       } else {
+    1755             :         // find maximum for each data point
+    1756          50 :         max_values.push_back(*max_element(sigma_mean2_last_[i][j].begin(), sigma_mean2_last_[i][j].end()));
+    1757             :       }
+    1758             :     }
+    1759          19 :     if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1760             :       // find maximum across data points
+    1761           6 :       const double max_now = std::sqrt(*max_element(max_values.begin(), max_values.end()));
+    1762           6 :       Tools::convert(0,msg_j);
+    1763           6 :       std::string msg = msg_i+"_"+msg_j;
+    1764          12 :       sfile_.printField("sigmaMean_"+msg, max_now);
+    1765             :     }
+    1766             :   }
+    1767        2415 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+    1768             :     std::string msg;
+    1769        2396 :     Tools::convert(i,msg);
+    1770        4792 :     sfile_.printField("sigma_"+msg,sigma_[i]);
+    1771             :   }
+    1772        2415 :   for(unsigned i=0; i<sigma_max_.size(); ++i) {
+    1773             :     std::string msg;
+    1774        2396 :     Tools::convert(i,msg);
+    1775        4792 :     sfile_.printField("sigma_max_"+msg,sigma_max_[i]);
+    1776             :   }
+    1777          19 :   if(noise_type_==GENERIC) {
+    1778           3 :     for(unsigned i=0; i<ftilde_.size(); ++i) {
+    1779             :       std::string msg;
+    1780           2 :       Tools::convert(i,msg);
+    1781           4 :       sfile_.printField("ftilde_"+msg,ftilde_[i]);
+    1782             :     }
+    1783             :   }
+    1784          19 :   sfile_.printField("scale0_",scale_);
+    1785          19 :   sfile_.printField("offset0_",offset_);
+    1786          38 :   for(unsigned i=0; i<average_weights_.size(); i++) {
+    1787             :     std::string msg_i;
+    1788          19 :     Tools::convert(i,msg_i);
+    1789          38 :     sfile_.printField("weight_"+msg_i,average_weights_[i][replica_]);
+    1790             :   }
+    1791          19 :   sfile_.printField();
+    1792          19 :   sfile_.flush();
+    1793          19 : }
+    1794             : 
+    1795         178 : void Metainference::update() {
+    1796             :   // write status file
+    1797         178 :   if(write_stride_>0&& (getStep()%write_stride_==0 || getCPT()) ) writeStatus();
+    1798         178 : }
+    1799             : 
+    1800             : }
+    1801             : }
+    1802             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.cpp.func-sort-c.html b/coverage/isdb/MetainferenceBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..d1babb2d73d0 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.func-sort-c.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:75488585.2 %
Date:2024-02-22 21:58:45Functions:232882.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb17MetainferenceBase8SelectorEv0
_ZN4PLMD4isdb17MetainferenceBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb17MetainferenceBaseD0Ev0
_ZN4PLMD4isdb17MetainferenceBaseD1Ev0
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_6
_ZN4PLMD4isdb17MetainferenceBase11getEnergySPERKSt6vectorIdSaIdEES6_dd12
_ZN4PLMD4isdb17MetainferenceBase19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb17MetainferenceBase9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb17MetainferenceBase10InitialiseEj31
_ZN4PLMD4isdb17MetainferenceBase14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb17MetainferenceBase11writeStatusEv100
_ZN4PLMD4isdb17MetainferenceBaseC2ERKNS_13ActionOptionsE100
_ZN4PLMD4isdb17MetainferenceBaseD2Ev100
_ZN4PLMD4isdb17MetainferenceBase16registerKeywordsERNS_8KeywordsE116
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_160
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_271
_ZN4PLMD4isdb17MetainferenceBase12getEnergyGJEERKSt6vectorIdSaIdEES6_dd368
_ZN4PLMD4isdb17MetainferenceBase11getEnergyGJERKSt6vectorIdSaIdEES6_dd554
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_1776
_ZN4PLMD4isdb17MetainferenceBase15moveScaleOffsetERKSt6vectorIdSaIdEERd1848
_ZN4PLMD4isdb17MetainferenceBase10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb2225
_ZN4PLMD4isdb17MetainferenceBase11get_weightsERdS2_S2_2225
_ZN4PLMD4isdb17MetainferenceBase12doMonteCarloERKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase14get_sigma_meanEdddRKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase17replica_averagingEddRSt6vectorIdSaIdEES5_2225
_ZN4PLMD4isdb17MetainferenceBase8getScoreEv2225
_ZN4PLMD4isdb17MetainferenceBase12getEnergySPEERKSt6vectorIdSaIdEES6_dd5328
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.cpp.func.html b/coverage/isdb/MetainferenceBase.cpp.func.html new file mode 100644 index 000000000000..4c8511dd6d64 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.func.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:75488585.2 %
Date:2024-02-22 21:58:45Functions:232882.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase10InitialiseEj31
_ZN4PLMD4isdb17MetainferenceBase10moveSigmasERKSt6vectorIdSaIdEERdjRKS2_IjSaIjEERb2225
_ZN4PLMD4isdb17MetainferenceBase11getEnergyGJERKSt6vectorIdSaIdEES6_dd554
_ZN4PLMD4isdb17MetainferenceBase11getEnergySPERKSt6vectorIdSaIdEES6_dd12
_ZN4PLMD4isdb17MetainferenceBase11get_weightsERdS2_S2_2225
_ZN4PLMD4isdb17MetainferenceBase11writeStatusEv100
_ZN4PLMD4isdb17MetainferenceBase12doMonteCarloERKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase12getEnergyGJEERKSt6vectorIdSaIdEES6_dd368
_ZN4PLMD4isdb17MetainferenceBase12getEnergySPEERKSt6vectorIdSaIdEES6_dd5328
_ZN4PLMD4isdb17MetainferenceBase14getEnergyMIGENERKSt6vectorIdSaIdEES6_S6_dd48
_ZN4PLMD4isdb17MetainferenceBase14get_sigma_meanEdddRKSt6vectorIdSaIdEE2225
_ZN4PLMD4isdb17MetainferenceBase15moveScaleOffsetERKSt6vectorIdSaIdEERd1848
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceGJERKSt6vectorIdSaIdEES6_S6_271
_ZN4PLMD4isdb17MetainferenceBase16getEnergyForceSPERKSt6vectorIdSaIdEES6_S6_6
_ZN4PLMD4isdb17MetainferenceBase16registerKeywordsERNS_8KeywordsE116
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceGJEERKSt6vectorIdSaIdEES6_S6_160
_ZN4PLMD4isdb17MetainferenceBase17getEnergyForceSPEERKSt6vectorIdSaIdEES6_S6_1776
_ZN4PLMD4isdb17MetainferenceBase17replica_averagingEddRSt6vectorIdSaIdEES5_2225
_ZN4PLMD4isdb17MetainferenceBase18do_regression_zeroERKSt6vectorIdSaIdEE0
_ZN4PLMD4isdb17MetainferenceBase19getEnergyForceMIGENERKSt6vectorIdSaIdEES6_S6_12
_ZN4PLMD4isdb17MetainferenceBase8SelectorEv0
_ZN4PLMD4isdb17MetainferenceBase8getScoreEv2225
_ZN4PLMD4isdb17MetainferenceBase9moveTildeERKSt6vectorIdSaIdEERd12
_ZN4PLMD4isdb17MetainferenceBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb17MetainferenceBaseC2ERKNS_13ActionOptionsE100
_ZN4PLMD4isdb17MetainferenceBaseD0Ev0
_ZN4PLMD4isdb17MetainferenceBaseD1Ev0
_ZN4PLMD4isdb17MetainferenceBaseD2Ev100
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.cpp.gcov.html b/coverage/isdb/MetainferenceBase.cpp.gcov.html new file mode 100644 index 000000000000..a06c3fa3071f --- /dev/null +++ b/coverage/isdb/MetainferenceBase.cpp.gcov.html @@ -0,0 +1,1637 @@ + + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:75488585.2 %
Date:2024-02-22 21:58:45Functions:232882.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetainferenceBase.h"
+      23             : #include "tools/File.h"
+      24             : #include <chrono>
+      25             : #include <numeric>
+      26             : 
+      27             : #ifndef M_PI
+      28             : #define M_PI           3.14159265358979323846
+      29             : #endif
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace isdb {
+      33             : 
+      34         116 : void MetainferenceBase::registerKeywords( Keywords& keys ) {
+      35         116 :   Action::registerKeywords(keys);
+      36         116 :   ActionAtomistic::registerKeywords(keys);
+      37         116 :   ActionWithValue::registerKeywords(keys);
+      38         116 :   ActionWithArguments::registerKeywords(keys);
+      39         116 :   componentsAreNotOptional(keys);
+      40         116 :   keys.use("ARG");
+      41         232 :   keys.addFlag("DOSCORE",false,"activate metainference");
+      42         232 :   keys.addFlag("NOENSEMBLE",false,"don't perform any replica-averaging");
+      43         232 :   keys.addFlag("REWEIGHT",false,"simple REWEIGHT using the ARG as energy");
+      44         232 :   keys.add("optional","AVERAGING", "Stride for calculation of averaged weights and sigma_mean");
+      45         232 :   keys.add("compulsory","NOISETYPE","MGAUSS","functional form of the noise (GAUSS,MGAUSS,OUTLIERS,MOUTLIERS,GENERIC)");
+      46         232 :   keys.add("compulsory","LIKELIHOOD","GAUSS","the likelihood for the GENERIC metainference model, GAUSS or LOGN");
+      47         232 :   keys.add("compulsory","DFTILDE","0.1","fraction of sigma_mean used to evolve ftilde");
+      48         232 :   keys.addFlag("SCALEDATA",false,"Set to TRUE if you want to sample a scaling factor common to all values and replicas");
+      49         232 :   keys.add("compulsory","SCALE0","1.0","initial value of the scaling factor");
+      50         232 :   keys.add("compulsory","SCALE_PRIOR","FLAT","either FLAT or GAUSSIAN");
+      51         232 :   keys.add("optional","SCALE_MIN","minimum value of the scaling factor");
+      52         232 :   keys.add("optional","SCALE_MAX","maximum value of the scaling factor");
+      53         232 :   keys.add("optional","DSCALE","maximum MC move of the scaling factor");
+      54         232 :   keys.addFlag("ADDOFFSET",false,"Set to TRUE if you want to sample an offset common to all values and replicas");
+      55         232 :   keys.add("compulsory","OFFSET0","0.0","initial value of the offset");
+      56         232 :   keys.add("compulsory","OFFSET_PRIOR","FLAT","either FLAT or GAUSSIAN");
+      57         232 :   keys.add("optional","OFFSET_MIN","minimum value of the offset");
+      58         232 :   keys.add("optional","OFFSET_MAX","maximum value of the offset");
+      59         232 :   keys.add("optional","DOFFSET","maximum MC move of the offset");
+      60         232 :   keys.add("optional","REGRES_ZERO","stride for regression with zero offset");
+      61         232 :   keys.add("compulsory","SIGMA0","1.0","initial value of the uncertainty parameter");
+      62         232 :   keys.add("compulsory","SIGMA_MIN","0.0","minimum value of the uncertainty parameter");
+      63         232 :   keys.add("compulsory","SIGMA_MAX","10.","maximum value of the uncertainty parameter");
+      64         232 :   keys.add("optional","DSIGMA","maximum MC move of the uncertainty parameter");
+      65         232 :   keys.add("compulsory","OPTSIGMAMEAN","NONE","Set to NONE/SEM to manually set sigma mean, or to estimate it on the fly");
+      66         232 :   keys.add("optional","SIGMA_MEAN0","starting value for the uncertainty in the mean estimate");
+      67         232 :   keys.add("optional","SIGMA_MAX_STEPS", "Number of steps used to optimise SIGMA_MAX, before that the SIGMA_MAX value is used");
+      68         232 :   keys.add("optional","TEMP","the system temperature - this is only needed if code doesn't pass the temperature to plumed");
+      69         232 :   keys.add("optional","MC_STEPS","number of MC steps");
+      70         232 :   keys.add("optional","MC_CHUNKSIZE","MC chunksize");
+      71         232 :   keys.add("optional","STATUS_FILE","write a file with all the data useful for restart/continuation of Metainference");
+      72         232 :   keys.add("compulsory","WRITE_STRIDE","10000","write the status to a file every N steps, this can be used for restart/continuation");
+      73         232 :   keys.add("optional","SELECTOR","name of selector");
+      74         232 :   keys.add("optional","NSELECT","range of values for selector [0, N-1]");
+      75         116 :   keys.use("RESTART");
+      76         232 :   keys.addOutputComponent("score",        "default",      "the Metainference score");
+      77         232 :   keys.addOutputComponent("sigma",        "default",      "uncertainty parameter");
+      78         232 :   keys.addOutputComponent("sigmaMean",    "default",      "uncertainty in the mean estimate");
+      79         232 :   keys.addOutputComponent("neff",         "default",      "effective number of replicas");
+      80         232 :   keys.addOutputComponent("acceptSigma",  "default",      "MC acceptance for sigma values");
+      81         232 :   keys.addOutputComponent("acceptScale",  "SCALEDATA",    "MC acceptance for scale value");
+      82         232 :   keys.addOutputComponent("acceptFT",     "GENERIC",      "MC acceptance for general metainference f tilde value");
+      83         232 :   keys.addOutputComponent("weight",       "REWEIGHT",     "weights of the weighted average");
+      84         232 :   keys.addOutputComponent("biasDer",      "REWEIGHT",     "derivatives with respect to the bias");
+      85         232 :   keys.addOutputComponent("scale",        "SCALEDATA",    "scale parameter");
+      86         232 :   keys.addOutputComponent("offset",       "ADDOFFSET",    "offset parameter");
+      87         232 :   keys.addOutputComponent("ftilde",       "GENERIC",      "ensemble average estimator");
+      88         116 : }
+      89             : 
+      90         100 : MetainferenceBase::MetainferenceBase(const ActionOptions&ao):
+      91             :   Action(ao),
+      92             :   ActionAtomistic(ao),
+      93             :   ActionWithArguments(ao),
+      94             :   ActionWithValue(ao),
+      95         100 :   doscore_(false),
+      96         100 :   write_stride_(0),
+      97         100 :   narg(0),
+      98         100 :   doscale_(false),
+      99         100 :   scale_(1.),
+     100         100 :   scale_mu_(0),
+     101         100 :   scale_min_(1),
+     102         100 :   scale_max_(-1),
+     103         100 :   Dscale_(-1),
+     104         100 :   dooffset_(false),
+     105         100 :   offset_(0.),
+     106         100 :   offset_mu_(0),
+     107         100 :   offset_min_(1),
+     108         100 :   offset_max_(-1),
+     109         100 :   Doffset_(-1),
+     110         100 :   doregres_zero_(false),
+     111         100 :   nregres_zero_(0),
+     112         100 :   Dftilde_(0.1),
+     113         100 :   random(3),
+     114         100 :   MCsteps_(1),
+     115         100 :   MCaccept_(0),
+     116         100 :   MCacceptScale_(0),
+     117         100 :   MCacceptFT_(0),
+     118         100 :   MCtrial_(0),
+     119         100 :   MCchunksize_(0),
+     120         100 :   firstTime(true),
+     121         100 :   do_reweight_(false),
+     122         100 :   do_optsigmamean_(0),
+     123         100 :   nsel_(1),
+     124         100 :   iselect(0),
+     125         100 :   optsigmamean_stride_(0),
+     126         100 :   N_optimized_step_(0),
+     127         100 :   optimized_step_(0),
+     128         100 :   sigmamax_opt_done_(false),
+     129         100 :   decay_w_(1.)
+     130             : {
+     131         100 :   parseFlag("DOSCORE", doscore_);
+     132             : 
+     133         100 :   bool noensemble = false;
+     134         100 :   parseFlag("NOENSEMBLE", noensemble);
+     135             : 
+     136             :   // set up replica stuff
+     137         100 :   master = (comm.Get_rank()==0);
+     138         100 :   if(master) {
+     139          62 :     nrep_    = multi_sim_comm.Get_size();
+     140          62 :     replica_ = multi_sim_comm.Get_rank();
+     141          62 :     if(noensemble) nrep_ = 1;
+     142             :   } else {
+     143          38 :     nrep_    = 0;
+     144          38 :     replica_ = 0;
+     145             :   }
+     146         100 :   comm.Sum(&nrep_,1);
+     147         100 :   comm.Sum(&replica_,1);
+     148             : 
+     149         100 :   parse("SELECTOR", selector_);
+     150         200 :   parse("NSELECT", nsel_);
+     151             :   // do checks
+     152         100 :   if(selector_.length()>0 && nsel_<=1) error("With SELECTOR active, NSELECT must be greater than 1");
+     153         100 :   if(selector_.length()==0 && nsel_>1) error("With NSELECT greater than 1, you must specify SELECTOR");
+     154             : 
+     155             :   // initialise firstTimeW
+     156         100 :   firstTimeW.resize(nsel_, true);
+     157             : 
+     158             :   // reweight implies a different number of arguments (the latest one must always be the bias)
+     159         100 :   parseFlag("REWEIGHT", do_reweight_);
+     160         100 :   if(do_reweight_&&getNumberOfArguments()!=1) error("To REWEIGHT one must provide one single bias as an argument");
+     161         100 :   if(do_reweight_&&nrep_<2) error("REWEIGHT can only be used in parallel with 2 or more replicas");
+     162         199 :   if(!getRestart()) average_weights_.resize(nsel_, std::vector<double> (nrep_, 1./static_cast<double>(nrep_)));
+     163           2 :   else average_weights_.resize(nsel_, std::vector<double> (nrep_, 0.));
+     164             : 
+     165         100 :   unsigned averaging=0;
+     166         100 :   parse("AVERAGING", averaging);
+     167         100 :   if(averaging>0) {
+     168           0 :     decay_w_ = 1./static_cast<double> (averaging);
+     169           0 :     optsigmamean_stride_ = averaging;
+     170             :   }
+     171             : 
+     172             :   std::string stringa_noise;
+     173         200 :   parse("NOISETYPE",stringa_noise);
+     174         100 :   if(stringa_noise=="GAUSS")           noise_type_ = GAUSS;
+     175          93 :   else if(stringa_noise=="MGAUSS")     noise_type_ = MGAUSS;
+     176          10 :   else if(stringa_noise=="OUTLIERS")   noise_type_ = OUTLIERS;
+     177           9 :   else if(stringa_noise=="MOUTLIERS")  noise_type_ = MOUTLIERS;
+     178           1 :   else if(stringa_noise=="GENERIC")    noise_type_ = GENERIC;
+     179           0 :   else error("Unknown noise type!");
+     180             : 
+     181         100 :   if(noise_type_== GENERIC) {
+     182             :     std::string stringa_like;
+     183           2 :     parse("LIKELIHOOD",stringa_like);
+     184           1 :     if(stringa_like=="GAUSS") gen_likelihood_ = LIKE_GAUSS;
+     185           0 :     else if(stringa_like=="LOGN") gen_likelihood_ = LIKE_LOGN;
+     186           0 :     else error("Unknown likelihood type!");
+     187             : 
+     188           2 :     parse("DFTILDE",Dftilde_);
+     189             :   }
+     190             : 
+     191         100 :   parse("WRITE_STRIDE",write_stride_);
+     192         200 :   parse("STATUS_FILE",status_file_name_);
+     193         200 :   if(status_file_name_=="") status_file_name_ = "MISTATUS"+getLabel();
+     194           0 :   else                      status_file_name_ = status_file_name_+getLabel();
+     195             : 
+     196             :   std::string stringa_optsigma;
+     197         200 :   parse("OPTSIGMAMEAN", stringa_optsigma);
+     198         100 :   if(stringa_optsigma=="NONE")      do_optsigmamean_=0;
+     199           4 :   else if(stringa_optsigma=="SEM")  do_optsigmamean_=1;
+     200           0 :   else if(stringa_optsigma=="SEM_MAX")  do_optsigmamean_=2;
+     201             : 
+     202         100 :   unsigned aver_max_steps=0;
+     203         100 :   parse("SIGMA_MAX_STEPS", aver_max_steps);
+     204         100 :   if(aver_max_steps==0&&do_optsigmamean_==2) aver_max_steps=averaging*2000;
+     205         100 :   if(aver_max_steps>0&&do_optsigmamean_<2) error("SIGMA_MAX_STEPS can only be used together with OPTSIGMAMEAN=SEM_MAX");
+     206         100 :   if(aver_max_steps>0&&do_optsigmamean_==2) N_optimized_step_=aver_max_steps;
+     207         100 :   if(aver_max_steps>0&&aver_max_steps<averaging) error("SIGMA_MAX_STEPS must be greater than AVERAGING");
+     208             : 
+     209             :   std::vector<double> read_sigma_mean_;
+     210         100 :   parseVector("SIGMA_MEAN0",read_sigma_mean_);
+     211         100 :   if(do_optsigmamean_==0 && read_sigma_mean_.size()==0 && !getRestart() && doscore_)
+     212           0 :     error("If you don't use OPTSIGMAMEAN and you are not RESTARTING then you MUST SET SIGMA_MEAN0");
+     213             : 
+     214         100 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     215          92 :     if(read_sigma_mean_.size()>0) {
+     216          23 :       sigma_mean2_.resize(read_sigma_mean_.size());
+     217          46 :       for(unsigned i=0; i<read_sigma_mean_.size(); i++) sigma_mean2_[i]=read_sigma_mean_[i]*read_sigma_mean_[i];
+     218             :     } else {
+     219          69 :       sigma_mean2_.resize(1,0.000001);
+     220             :     }
+     221             :   } else {
+     222           8 :     if(read_sigma_mean_.size()==1) {
+     223           8 :       sigma_mean2_.resize(1, read_sigma_mean_[0]*read_sigma_mean_[0]);
+     224           0 :     } else if(read_sigma_mean_.size()==0) {
+     225           0 :       sigma_mean2_.resize(1, 0.000001);
+     226             :     } else {
+     227           0 :       error("If you want to use more than one SIGMA_MEAN0 you should use NOISETYPE=MGAUSS|MOUTLIERS");
+     228             :     }
+     229             :   }
+     230             : 
+     231         100 :   parseFlag("SCALEDATA", doscale_);
+     232         100 :   if(doscale_) {
+     233             :     std::string stringa_noise;
+     234          24 :     parse("SCALE_PRIOR",stringa_noise);
+     235          12 :     if(stringa_noise=="GAUSSIAN")  scale_prior_ = SC_GAUSS;
+     236          12 :     else if(stringa_noise=="FLAT") scale_prior_ = SC_FLAT;
+     237           0 :     else error("Unknown SCALE_PRIOR type!");
+     238          12 :     parse("SCALE0",scale_);
+     239          12 :     parse("DSCALE",Dscale_);
+     240          12 :     if(Dscale_<0.) error("DSCALE must be set when using SCALEDATA");
+     241          12 :     if(scale_prior_==SC_GAUSS) {
+     242           0 :       scale_mu_=scale_;
+     243             :     } else {
+     244          12 :       parse("SCALE_MIN",scale_min_);
+     245          12 :       parse("SCALE_MAX",scale_max_);
+     246          12 :       if(scale_max_<scale_min_) error("SCALE_MAX and SCALE_MIN must be set when using SCALE_PRIOR=FLAT");
+     247             :     }
+     248             :   }
+     249             : 
+     250         100 :   parseFlag("ADDOFFSET", dooffset_);
+     251         100 :   if(dooffset_) {
+     252             :     std::string stringa_noise;
+     253           4 :     parse("OFFSET_PRIOR",stringa_noise);
+     254           2 :     if(stringa_noise=="GAUSSIAN")  offset_prior_ = SC_GAUSS;
+     255           2 :     else if(stringa_noise=="FLAT") offset_prior_ = SC_FLAT;
+     256           0 :     else error("Unknown OFFSET_PRIOR type!");
+     257           2 :     parse("OFFSET0",offset_);
+     258           2 :     parse("DOFFSET",Doffset_);
+     259           2 :     if(offset_prior_==SC_GAUSS) {
+     260           0 :       offset_mu_=offset_;
+     261           0 :       if(Doffset_<0.) error("DOFFSET must be set when using OFFSET_PRIOR=GAUSS");
+     262             :     } else {
+     263           2 :       parse("OFFSET_MIN",offset_min_);
+     264           2 :       parse("OFFSET_MAX",offset_max_);
+     265           2 :       if(Doffset_<0) Doffset_ = 0.05*(offset_max_ - offset_min_);
+     266           2 :       if(offset_max_<offset_min_) error("OFFSET_MAX and OFFSET_MIN must be set when using OFFSET_PRIOR=FLAT");
+     267             :     }
+     268             :   }
+     269             : 
+     270             :   // regression with zero intercept
+     271         100 :   parse("REGRES_ZERO", nregres_zero_);
+     272         100 :   if(nregres_zero_>0) {
+     273             :     // set flag
+     274           0 :     doregres_zero_=true;
+     275             :     // check if already sampling scale and offset
+     276           0 :     if(doscale_)  error("REGRES_ZERO and SCALEDATA are mutually exclusive");
+     277           0 :     if(dooffset_) error("REGRES_ZERO and ADDOFFSET are mutually exclusive");
+     278             :   }
+     279             : 
+     280             :   std::vector<double> readsigma;
+     281         100 :   parseVector("SIGMA0",readsigma);
+     282         100 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma.size()>1)
+     283           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     284         100 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     285          92 :     sigma_.resize(readsigma.size());
+     286          92 :     sigma_=readsigma;
+     287           8 :   } else sigma_.resize(1, readsigma[0]);
+     288             : 
+     289             :   std::vector<double> readsigma_min;
+     290         100 :   parseVector("SIGMA_MIN",readsigma_min);
+     291         100 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_min.size()>1)
+     292           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     293         100 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     294          92 :     sigma_min_.resize(readsigma_min.size());
+     295          92 :     sigma_min_=readsigma_min;
+     296           8 :   } else sigma_min_.resize(1, readsigma_min[0]);
+     297             : 
+     298             :   std::vector<double> readsigma_max;
+     299         100 :   parseVector("SIGMA_MAX",readsigma_max);
+     300         100 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_max.size()>1)
+     301           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     302         100 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     303          92 :     sigma_max_.resize(readsigma_max.size());
+     304          92 :     sigma_max_=readsigma_max;
+     305           8 :   } else sigma_max_.resize(1, readsigma_max[0]);
+     306             : 
+     307         100 :   if(sigma_max_.size()!=sigma_min_.size()) error("The number of values for SIGMA_MIN and SIGMA_MAX must be the same");
+     308             : 
+     309             :   std::vector<double> read_dsigma;
+     310         100 :   parseVector("DSIGMA",read_dsigma);
+     311         100 :   if((noise_type_!=MGAUSS&&noise_type_!=MOUTLIERS&&noise_type_!=GENERIC)&&readsigma_max.size()>1)
+     312           0 :     error("If you want to use more than one SIGMA you should use NOISETYPE=MGAUSS|MOUTLIERS|GENERIC");
+     313         100 :   if(read_dsigma.size()>0) {
+     314          31 :     Dsigma_.resize(read_dsigma.size());
+     315          31 :     Dsigma_=read_dsigma;
+     316             :   } else {
+     317          69 :     Dsigma_.resize(sigma_max_.size(), -1.);
+     318             :     /* in this case Dsigma is initialised after reading the restart file if present */
+     319             :   }
+     320             : 
+     321             :   // monte carlo stuff
+     322         100 :   parse("MC_STEPS",MCsteps_);
+     323         100 :   parse("MC_CHUNKSIZE", MCchunksize_);
+     324             :   // get temperature
+     325         100 :   kbt_=getkBT();
+     326         100 :   if(kbt_==0.0&&doscore_) error("Unless the MD engine passes the temperature to plumed, you must specify it using TEMP");
+     327             : 
+     328             :   // initialize random seed
+     329             :   unsigned iseed;
+     330         100 :   if(master) {
+     331          62 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     332          62 :     iseed = static_cast<unsigned>(ts)+replica_;
+     333             :   } else {
+     334          38 :     iseed = 0;
+     335             :   }
+     336         100 :   comm.Sum(&iseed, 1);
+     337             :   // this is used for ftilde and sigma both the move and the acceptance
+     338             :   // this is different for each replica
+     339         100 :   random[0].setSeed(-iseed);
+     340         100 :   if(doscale_||dooffset_) {
+     341             :     // in this case we want the same seed everywhere
+     342          14 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     343          14 :     iseed = static_cast<unsigned>(ts);
+     344          14 :     if(master&&nrep_>1) multi_sim_comm.Bcast(iseed,0);
+     345          14 :     comm.Bcast(iseed,0);
+     346             :     // this is used for scale and offset sampling and acceptance
+     347          14 :     random[1].setSeed(-iseed);
+     348             :   }
+     349             :   // this is used for random chunk of sigmas, and it is different for each replica
+     350         100 :   if(master) {
+     351          62 :     auto ts = std::chrono::time_point_cast<std::chrono::nanoseconds>(std::chrono::steady_clock::now()).time_since_epoch().count();
+     352          62 :     iseed = static_cast<unsigned>(ts)+replica_;
+     353             :   } else {
+     354          38 :     iseed = 0;
+     355             :   }
+     356         100 :   comm.Sum(&iseed, 1);
+     357         100 :   random[2].setSeed(-iseed);
+     358             : 
+     359             :   // outfile stuff
+     360         100 :   if(write_stride_>0&&doscore_) {
+     361          31 :     sfile_.link(*this);
+     362          31 :     sfile_.open(status_file_name_);
+     363             :   }
+     364             : 
+     365         100 : }
+     366             : 
+     367         100 : MetainferenceBase::~MetainferenceBase()
+     368             : {
+     369         100 :   if(sfile_.isOpen()) sfile_.close();
+     370         500 : }
+     371             : 
+     372          31 : void MetainferenceBase::Initialise(const unsigned input)
+     373             : {
+     374             :   setNarg(input);
+     375          31 :   if(narg!=parameters.size()) {
+     376           0 :     std::string num1; Tools::convert(parameters.size(),num1);
+     377           0 :     std::string num2; Tools::convert(narg,num2);
+     378           0 :     std::string msg = "The number of experimental values " + num1 +" must be the same of the calculated values " + num2;
+     379           0 :     error(msg);
+     380             :   }
+     381             : 
+     382             :   // resize std::vector for sigma_mean history
+     383          31 :   sigma_mean2_last_.resize(nsel_);
+     384          62 :   for(unsigned i=0; i<nsel_; i++) sigma_mean2_last_[i].resize(narg);
+     385          31 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     386          23 :     if(sigma_mean2_.size()==1) {
+     387          23 :       double tmp = sigma_mean2_[0];
+     388          23 :       sigma_mean2_.resize(narg, tmp);
+     389           0 :     } else if(sigma_mean2_.size()>1&&sigma_mean2_.size()!=narg) {
+     390           0 :       error("SIGMA_MEAN0 can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     391             :     }
+     392             :     // set the initial value for the history
+     393        2516 :     for(unsigned i=0; i<nsel_; i++) for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j].push_back(sigma_mean2_[j]);
+     394             :   } else {
+     395             :     // set the initial value for the history
+     396          43 :     for(unsigned i=0; i<nsel_; i++) for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j].push_back(sigma_mean2_[0]);
+     397             :   }
+     398             : 
+     399             :   // set sigma_bias
+     400          31 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     401          23 :     if(sigma_.size()==1) {
+     402          23 :       double tmp = sigma_[0];
+     403          23 :       sigma_.resize(narg, tmp);
+     404           0 :     } else if(sigma_.size()>1&&sigma_.size()!=narg) {
+     405           0 :       error("SIGMA0 can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     406             :     }
+     407          23 :     if(sigma_min_.size()==1) {
+     408          23 :       double tmp = sigma_min_[0];
+     409          23 :       sigma_min_.resize(narg, tmp);
+     410           0 :     } else if(sigma_min_.size()>1&&sigma_min_.size()!=narg) {
+     411           0 :       error("SIGMA_MIN can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     412             :     }
+     413          23 :     if(sigma_max_.size()==1) {
+     414          23 :       double tmp = sigma_max_[0];
+     415          23 :       sigma_max_.resize(narg, tmp);
+     416           0 :     } else if(sigma_max_.size()>1&&sigma_max_.size()!=narg) {
+     417           0 :       error("SIGMA_MAX can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     418             :     }
+     419          23 :     if(Dsigma_.size()==1) {
+     420          23 :       double tmp = Dsigma_[0];
+     421          23 :       Dsigma_.resize(narg, tmp);
+     422           0 :     } else if(Dsigma_.size()>1&&Dsigma_.size()!=narg) {
+     423           0 :       error("DSIGMA can accept either one single value or as many values as the number of arguments (with NOISETYPE=MGAUSS|MOUTLIERS|GENERIC)");
+     424             :     }
+     425             :   }
+     426             : 
+     427          31 :   sigma_max_est_.resize(sigma_max_.size(), 0.);
+     428             : 
+     429          31 :   IFile restart_sfile;
+     430          31 :   restart_sfile.link(*this);
+     431          31 :   if(getRestart()&&restart_sfile.FileExist(status_file_name_)) {
+     432           1 :     firstTime = false;
+     433           2 :     for(unsigned i=0; i<nsel_; i++) firstTimeW[i] = false;
+     434           1 :     restart_sfile.open(status_file_name_);
+     435           1 :     log.printf("  Restarting from %s\n", status_file_name_.c_str());
+     436             :     double dummy;
+     437           2 :     if(restart_sfile.scanField("time",dummy)) {
+     438             :       // check for syncronisation
+     439           1 :       std::vector<double> dummy_time(nrep_,0);
+     440           1 :       if(master&&nrep_>1) {
+     441           0 :         dummy_time[replica_] = dummy;
+     442           0 :         multi_sim_comm.Sum(dummy_time);
+     443             :       }
+     444           1 :       comm.Sum(dummy_time);
+     445           1 :       for(unsigned i=1; i<nrep_; i++) {
+     446           0 :         std::string msg = "METAINFERENCE restart files " + status_file_name_ + "  are not in sync";
+     447           0 :         if(dummy_time[i]!=dummy_time[0]) plumed_merror(msg);
+     448             :       }
+     449             :       // nsel
+     450           2 :       for(unsigned i=0; i<sigma_mean2_last_.size(); i++) {
+     451             :         std::string msg_i;
+     452           1 :         Tools::convert(i,msg_i);
+     453             :         // narg
+     454           1 :         if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     455           0 :           for(unsigned j=0; j<narg; ++j) {
+     456             :             std::string msg_j;
+     457           0 :             Tools::convert(j,msg_j);
+     458           0 :             std::string msg = msg_i+"_"+msg_j;
+     459             :             double read_sm;
+     460           0 :             restart_sfile.scanField("sigmaMean_"+msg,read_sm);
+     461           0 :             sigma_mean2_last_[i][j][0] = read_sm*read_sm;
+     462             :           }
+     463             :         }
+     464           1 :         if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+     465             :           double read_sm;
+     466             :           std::string msg_j;
+     467           1 :           Tools::convert(0,msg_j);
+     468           1 :           std::string msg = msg_i+"_"+msg_j;
+     469           1 :           restart_sfile.scanField("sigmaMean_"+msg,read_sm);
+     470           8 :           for(unsigned j=0; j<narg; j++) sigma_mean2_last_[i][j][0] = read_sm*read_sm;
+     471             :         }
+     472             :       }
+     473             : 
+     474           2 :       for(unsigned i=0; i<sigma_.size(); ++i) {
+     475             :         std::string msg;
+     476           1 :         Tools::convert(i,msg);
+     477           2 :         restart_sfile.scanField("sigma_"+msg,sigma_[i]);
+     478             :       }
+     479           2 :       for(unsigned i=0; i<sigma_max_.size(); ++i) {
+     480             :         std::string msg;
+     481           1 :         Tools::convert(i,msg);
+     482           1 :         restart_sfile.scanField("sigma_max_"+msg,sigma_max_[i]);
+     483           1 :         sigmamax_opt_done_=true;
+     484             :       }
+     485           1 :       if(noise_type_==GENERIC) {
+     486           0 :         for(unsigned i=0; i<ftilde_.size(); ++i) {
+     487             :           std::string msg;
+     488           0 :           Tools::convert(i,msg);
+     489           0 :           restart_sfile.scanField("ftilde_"+msg,ftilde_[i]);
+     490             :         }
+     491             :       }
+     492           1 :       restart_sfile.scanField("scale0_",scale_);
+     493           1 :       restart_sfile.scanField("offset0_",offset_);
+     494             : 
+     495           2 :       for(unsigned i=0; i<nsel_; i++) {
+     496             :         std::string msg;
+     497           1 :         Tools::convert(i,msg);
+     498             :         double tmp_w;
+     499           1 :         restart_sfile.scanField("weight_"+msg,tmp_w);
+     500           1 :         if(master) {
+     501           1 :           average_weights_[i][replica_] = tmp_w;
+     502           1 :           if(nrep_>1) multi_sim_comm.Sum(&average_weights_[i][0], nrep_);
+     503             :         }
+     504           1 :         comm.Sum(&average_weights_[i][0], nrep_);
+     505             :       }
+     506             : 
+     507             :     }
+     508           1 :     restart_sfile.scanField();
+     509           1 :     restart_sfile.close();
+     510             :   }
+     511             : 
+     512             :   /* If DSIGMA is not yet initialised do it now */
+     513        2509 :   for(unsigned i=0; i<sigma_max_.size(); i++) if(Dsigma_[i]==-1) Dsigma_[i] = 0.05*(sigma_max_[i] - sigma_min_[i]);
+     514             : 
+     515          62 :   addComponentWithDerivatives("score");
+     516          31 :   componentIsNotPeriodic("score");
+     517          31 :   valueScore=getPntrToComponent("score");
+     518             : 
+     519          31 :   if(do_reweight_) {
+     520          44 :     addComponent("biasDer");
+     521          44 :     componentIsNotPeriodic("biasDer");
+     522          44 :     addComponent("weight");
+     523          44 :     componentIsNotPeriodic("weight");
+     524             :   }
+     525             : 
+     526          62 :   addComponent("neff");
+     527          31 :   componentIsNotPeriodic("neff");
+     528             : 
+     529          31 :   if(doscale_ || doregres_zero_) {
+     530          24 :     addComponent("scale");
+     531          12 :     componentIsNotPeriodic("scale");
+     532          12 :     valueScale=getPntrToComponent("scale");
+     533             :   }
+     534             : 
+     535          31 :   if(dooffset_) {
+     536           4 :     addComponent("offset");
+     537           2 :     componentIsNotPeriodic("offset");
+     538           2 :     valueOffset=getPntrToComponent("offset");
+     539             :   }
+     540             : 
+     541          31 :   if(dooffset_||doscale_) {
+     542          28 :     addComponent("acceptScale");
+     543          14 :     componentIsNotPeriodic("acceptScale");
+     544          14 :     valueAcceptScale=getPntrToComponent("acceptScale");
+     545             :   }
+     546             : 
+     547          31 :   if(noise_type_==GENERIC) {
+     548           2 :     addComponent("acceptFT");
+     549           1 :     componentIsNotPeriodic("acceptFT");
+     550           1 :     valueAcceptFT=getPntrToComponent("acceptFT");
+     551             :   }
+     552             : 
+     553          62 :   addComponent("acceptSigma");
+     554          31 :   componentIsNotPeriodic("acceptSigma");
+     555          31 :   valueAccept=getPntrToComponent("acceptSigma");
+     556             : 
+     557          31 :   if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+     558        2493 :     for(unsigned i=0; i<sigma_mean2_.size(); ++i) {
+     559        2470 :       std::string num; Tools::convert(i,num);
+     560        4940 :       addComponent("sigmaMean-"+num); componentIsNotPeriodic("sigmaMean-"+num);
+     561        2470 :       valueSigmaMean.push_back(getPntrToComponent("sigmaMean-"+num));
+     562        4940 :       getPntrToComponent("sigmaMean-"+num)->set(std::sqrt(sigma_mean2_[i]));
+     563        4940 :       addComponent("sigma-"+num); componentIsNotPeriodic("sigma-"+num);
+     564        2470 :       valueSigma.push_back(getPntrToComponent("sigma-"+num));
+     565        2470 :       getPntrToComponent("sigma-"+num)->set(sigma_[i]);
+     566        2470 :       if(noise_type_==GENERIC) {
+     567           4 :         addComponent("ftilde-"+num); componentIsNotPeriodic("ftilde-"+num);
+     568           2 :         valueFtilde.push_back(getPntrToComponent("ftilde-"+num));
+     569             :       }
+     570             :     }
+     571          23 :   } else {
+     572          16 :     addComponent("sigmaMean"); componentIsNotPeriodic("sigmaMean");
+     573           8 :     valueSigmaMean.push_back(getPntrToComponent("sigmaMean"));
+     574          16 :     getPntrToComponent("sigmaMean")->set(std::sqrt(sigma_mean2_[0]));
+     575          16 :     addComponent("sigma"); componentIsNotPeriodic("sigma");
+     576           8 :     valueSigma.push_back(getPntrToComponent("sigma"));
+     577          16 :     getPntrToComponent("sigma")->set(sigma_[0]);
+     578             :   }
+     579             : 
+     580          31 :   switch(noise_type_) {
+     581           1 :   case GENERIC:
+     582           1 :     log.printf("  with general metainference ");
+     583           1 :     if(gen_likelihood_==LIKE_GAUSS) log.printf(" and a gaussian likelihood\n");
+     584           0 :     else if(gen_likelihood_==LIKE_LOGN) log.printf(" and a log-normal likelihood\n");
+     585           1 :     log.printf("  ensemble average parameter sampled with a step %lf of sigma_mean\n", Dftilde_);
+     586             :     break;
+     587           7 :   case GAUSS:
+     588           7 :     log.printf("  with gaussian noise and a single noise parameter for all the data\n");
+     589             :     break;
+     590          14 :   case MGAUSS:
+     591          14 :     log.printf("  with gaussian noise and a noise parameter for each data point\n");
+     592             :     break;
+     593           1 :   case OUTLIERS:
+     594           1 :     log.printf("  with long tailed gaussian noise and a single noise parameter for all the data\n");
+     595             :     break;
+     596           8 :   case MOUTLIERS:
+     597           8 :     log.printf("  with long tailed gaussian noise and a noise parameter for each data point\n");
+     598             :     break;
+     599             :   }
+     600             : 
+     601          31 :   if(doscale_) {
+     602             :     // check that the scale value is the same for all replicas
+     603          12 :     std::vector<double> dummy_scale(nrep_,0);
+     604          12 :     if(master&&nrep_>1) {
+     605           6 :       dummy_scale[replica_] = scale_;
+     606           6 :       multi_sim_comm.Sum(dummy_scale);
+     607             :     }
+     608          12 :     comm.Sum(dummy_scale);
+     609          24 :     for(unsigned i=1; i<nrep_; i++) {
+     610          12 :       std::string msg = "The SCALE value must be the same for all replicas: check your input or restart file";
+     611          12 :       if(dummy_scale[i]!=dummy_scale[0]) plumed_merror(msg);
+     612             :     }
+     613          12 :     log.printf("  sampling a common scaling factor with:\n");
+     614          12 :     log.printf("    initial scale parameter %f\n",scale_);
+     615          12 :     if(scale_prior_==SC_GAUSS) {
+     616           0 :       log.printf("    gaussian prior with mean %f and width %f\n",scale_mu_,Dscale_);
+     617             :     }
+     618          12 :     if(scale_prior_==SC_FLAT) {
+     619          12 :       log.printf("    flat prior between %f - %f\n",scale_min_,scale_max_);
+     620          12 :       log.printf("    maximum MC move of scale parameter %f\n",Dscale_);
+     621             :     }
+     622             :   }
+     623             : 
+     624          31 :   if(dooffset_) {
+     625             :     // check that the offset value is the same for all replicas
+     626           2 :     std::vector<double> dummy_offset(nrep_,0);
+     627           2 :     if(master&&nrep_>1) {
+     628           0 :       dummy_offset[replica_] = offset_;
+     629           0 :       multi_sim_comm.Sum(dummy_offset);
+     630             :     }
+     631           2 :     comm.Sum(dummy_offset);
+     632           2 :     for(unsigned i=1; i<nrep_; i++) {
+     633           0 :       std::string msg = "The OFFSET value must be the same for all replicas: check your input or restart file";
+     634           0 :       if(dummy_offset[i]!=dummy_offset[0]) plumed_merror(msg);
+     635             :     }
+     636           2 :     log.printf("  sampling a common offset with:\n");
+     637           2 :     log.printf("    initial offset parameter %f\n",offset_);
+     638           2 :     if(offset_prior_==SC_GAUSS) {
+     639           0 :       log.printf("    gaussian prior with mean %f and width %f\n",offset_mu_,Doffset_);
+     640             :     }
+     641           2 :     if(offset_prior_==SC_FLAT) {
+     642           2 :       log.printf("    flat prior between %f - %f\n",offset_min_,offset_max_);
+     643           2 :       log.printf("    maximum MC move of offset parameter %f\n",Doffset_);
+     644             :     }
+     645             :   }
+     646             : 
+     647          31 :   if(doregres_zero_)
+     648           0 :     log.printf("  doing regression with zero intercept with stride: %d\n", nregres_zero_);
+     649             : 
+     650          31 :   log.printf("  number of experimental data points %u\n",narg);
+     651          31 :   log.printf("  number of replicas %u\n",nrep_);
+     652          31 :   log.printf("  initial data uncertainties");
+     653        2509 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f", sigma_[i]);
+     654          31 :   log.printf("\n");
+     655          31 :   log.printf("  minimum data uncertainties");
+     656        2509 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_min_[i]);
+     657          31 :   log.printf("\n");
+     658          31 :   log.printf("  maximum data uncertainties");
+     659        2509 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_max_[i]);
+     660          31 :   log.printf("\n");
+     661          31 :   log.printf("  maximum MC move of data uncertainties");
+     662        2509 :   for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",Dsigma_[i]);
+     663          31 :   log.printf("\n");
+     664          31 :   log.printf("  temperature of the system %f\n",kbt_);
+     665          31 :   log.printf("  MC steps %u\n",MCsteps_);
+     666          31 :   log.printf("  initial standard errors of the mean");
+     667        2509 :   for(unsigned i=0; i<sigma_mean2_.size(); ++i) log.printf(" %f", std::sqrt(sigma_mean2_[i]));
+     668          31 :   log.printf("\n");
+     669             : 
+     670             :   //resize the number of metainference derivatives and the number of back-calculated data
+     671          31 :   metader_.resize(narg, 0.);
+     672          31 :   calc_data_.resize(narg, 0.);
+     673             : 
+     674          62 :   log<<"  Bibliography "<<plumed.cite("Bonomi, Camilloni, Cavalli, Vendruscolo, Sci. Adv. 2, e150117 (2016)");
+     675          53 :   if(do_reweight_) log<<plumed.cite("Bonomi, Camilloni, Vendruscolo, Sci. Rep. 6, 31232 (2016)");
+     676          35 :   if(do_optsigmamean_>0) log<<plumed.cite("Loehr, Jussupow, Camilloni, J. Chem. Phys. 146, 165102 (2017)");
+     677          62 :   log<<plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     678          31 :   log<<"\n";
+     679          31 : }
+     680             : 
+     681           0 : void MetainferenceBase::Selector()
+     682             : {
+     683           0 :   iselect = 0;
+     684             :   // set the value of selector for  REM-like stuff
+     685           0 :   if(selector_.length()>0) iselect = static_cast<unsigned>(plumed.passMap[selector_]);
+     686           0 : }
+     687             : 
+     688          12 : double MetainferenceBase::getEnergySP(const std::vector<double> &mean, const std::vector<double> &sigma,
+     689             :                                       const double scale, const double offset)
+     690             : {
+     691          12 :   const double scale2 = scale*scale;
+     692          12 :   const double sm2    = sigma_mean2_[0];
+     693          12 :   const double ss2    = sigma[0]*sigma[0] + scale2*sm2;
+     694          12 :   const double sss    = sigma[0]*sigma[0] + sm2;
+     695             : 
+     696             :   double ene = 0.0;
+     697          12 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     698             :   {
+     699             :     #pragma omp for reduction( + : ene)
+     700             :     for(unsigned i=0; i<narg; ++i) {
+     701             :       const double dev = scale*mean[i]-parameters[i]+offset;
+     702             :       const double a2 = 0.5*dev*dev + ss2;
+     703             :       if(sm2 > 0.0) {
+     704             :         ene += std::log(2.0*a2/(1.0-std::exp(-a2/sm2)));
+     705             :       }
+     706             :       else {
+     707             :         ene += std::log(2.0*a2);
+     708             :       }
+     709             :     }
+     710             :   }
+     711             :   // add one single Jeffrey's prior and one normalisation per data point
+     712          12 :   ene += 0.5*std::log(sss) + static_cast<double>(narg)*0.5*std::log(0.5*M_PI*M_PI/ss2);
+     713          12 :   if(doscale_ || doregres_zero_) ene += 0.5*std::log(sss);
+     714          12 :   if(dooffset_) ene += 0.5*std::log(sss);
+     715          12 :   return kbt_ * ene;
+     716             : }
+     717             : 
+     718        5328 : double MetainferenceBase::getEnergySPE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     719             :                                        const double scale, const double offset)
+     720             : {
+     721        5328 :   const double scale2 = scale*scale;
+     722             :   double ene = 0.0;
+     723        5328 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     724             :   {
+     725             :     #pragma omp for reduction( + : ene)
+     726             :     for(unsigned i=0; i<narg; ++i) {
+     727             :       const double sm2 = sigma_mean2_[i];
+     728             :       const double ss2 = sigma[i]*sigma[i] + scale2*sm2;
+     729             :       const double sss = sigma[i]*sigma[i] + sm2;
+     730             :       const double dev = scale*mean[i]-parameters[i]+offset;
+     731             :       const double a2  = 0.5*dev*dev + ss2;
+     732             :       if(sm2 > 0.0) {
+     733             :         ene += 0.5*std::log(sss) + 0.5*std::log(0.5*M_PI*M_PI/ss2) + std::log(2.0*a2/(1.0-std::exp(-a2/sm2)));
+     734             :       }
+     735             :       else {
+     736             :         ene += 0.5*std::log(sss) + 0.5*std::log(0.5*M_PI*M_PI/ss2) + std::log(2.0*a2);
+     737             :       }
+     738             :       if(doscale_ || doregres_zero_)  ene += 0.5*std::log(sss);
+     739             :       if(dooffset_) ene += 0.5*std::log(sss);
+     740             :     }
+     741             :   }
+     742        5328 :   return kbt_ * ene;
+     743             : }
+     744             : 
+     745          48 : double MetainferenceBase::getEnergyMIGEN(const std::vector<double> &mean, const std::vector<double> &ftilde, const std::vector<double> &sigma,
+     746             :     const double scale, const double offset)
+     747             : {
+     748             :   double ene = 0.0;
+     749          48 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     750             :   {
+     751             :     #pragma omp for reduction( + : ene)
+     752             :     for(unsigned i=0; i<narg; ++i) {
+     753             :       const double inv_sb2  = 1./(sigma[i]*sigma[i]);
+     754             :       const double inv_sm2  = 1./sigma_mean2_[i];
+     755             :       double devb = 0;
+     756             :       if(gen_likelihood_==LIKE_GAUSS)     devb = scale*ftilde[i]-parameters[i]+offset;
+     757             :       else if(gen_likelihood_==LIKE_LOGN) devb = std::log(scale*ftilde[i]/parameters[i]);
+     758             :       double devm = mean[i] - ftilde[i];
+     759             :       // deviation + normalisation + jeffrey
+     760             :       double normb = 0.;
+     761             :       if(gen_likelihood_==LIKE_GAUSS)     normb = -0.5*std::log(0.5/M_PI*inv_sb2);
+     762             :       else if(gen_likelihood_==LIKE_LOGN) normb = -0.5*std::log(0.5/M_PI*inv_sb2/(parameters[i]*parameters[i]));
+     763             :       const double normm         = -0.5*std::log(0.5/M_PI*inv_sm2);
+     764             :       const double jeffreys      = -0.5*std::log(2.*inv_sb2);
+     765             :       ene += 0.5*devb*devb*inv_sb2 + 0.5*devm*devm*inv_sm2 + normb + normm + jeffreys;
+     766             :       if(doscale_ || doregres_zero_)  ene += jeffreys;
+     767             :       if(dooffset_) ene += jeffreys;
+     768             :     }
+     769             :   }
+     770          48 :   return kbt_ * ene;
+     771             : }
+     772             : 
+     773         554 : double MetainferenceBase::getEnergyGJ(const std::vector<double> &mean, const std::vector<double> &sigma,
+     774             :                                       const double scale, const double offset)
+     775             : {
+     776         554 :   const double scale2  = scale*scale;
+     777         554 :   const double inv_s2  = 1./(sigma[0]*sigma[0] + scale2*sigma_mean2_[0]);
+     778         554 :   const double inv_sss = 1./(sigma[0]*sigma[0] + sigma_mean2_[0]);
+     779             : 
+     780             :   double ene = 0.0;
+     781         554 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     782             :   {
+     783             :     #pragma omp for reduction( + : ene)
+     784             :     for(unsigned i=0; i<narg; ++i) {
+     785             :       double dev = scale*mean[i]-parameters[i]+offset;
+     786             :       ene += 0.5*dev*dev*inv_s2;
+     787             :     }
+     788             :   }
+     789         554 :   const double normalisation = -0.5*std::log(0.5/M_PI*inv_s2);
+     790         554 :   const double jeffreys = -0.5*std::log(2.*inv_sss);
+     791             :   // add Jeffrey's prior in case one sigma for all data points + one normalisation per datapoint
+     792         554 :   ene += jeffreys + static_cast<double>(narg)*normalisation;
+     793         554 :   if(doscale_ || doregres_zero_)  ene += jeffreys;
+     794         554 :   if(dooffset_) ene += jeffreys;
+     795             : 
+     796         554 :   return kbt_ * ene;
+     797             : }
+     798             : 
+     799         368 : double MetainferenceBase::getEnergyGJE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     800             :                                        const double scale, const double offset)
+     801             : {
+     802         368 :   const double scale2 = scale*scale;
+     803             : 
+     804             :   double ene = 0.0;
+     805         368 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(ene)
+     806             :   {
+     807             :     #pragma omp for reduction( + : ene)
+     808             :     for(unsigned i=0; i<narg; ++i) {
+     809             :       const double inv_s2  = 1./(sigma[i]*sigma[i] + scale2*sigma_mean2_[i]);
+     810             :       const double inv_sss = 1./(sigma[i]*sigma[i] + sigma_mean2_[i]);
+     811             :       double dev = scale*mean[i]-parameters[i]+offset;
+     812             :       // deviation + normalisation + jeffrey
+     813             :       const double normalisation = -0.5*std::log(0.5/M_PI*inv_s2);
+     814             :       const double jeffreys      = -0.5*std::log(2.*inv_sss);
+     815             :       ene += 0.5*dev*dev*inv_s2 + normalisation + jeffreys;
+     816             :       if(doscale_ || doregres_zero_)  ene += jeffreys;
+     817             :       if(dooffset_) ene += jeffreys;
+     818             :     }
+     819             :   }
+     820         368 :   return kbt_ * ene;
+     821             : }
+     822             : 
+     823          12 : void MetainferenceBase::moveTilde(const std::vector<double> &mean_, double &old_energy)
+     824             : {
+     825          12 :   std::vector<double> new_ftilde(sigma_.size());
+     826          12 :   new_ftilde = ftilde_;
+     827             : 
+     828             :   // change all tildes
+     829          36 :   for(unsigned j=0; j<sigma_.size(); j++) {
+     830          24 :     const double r3 = random[0].Gaussian();
+     831          24 :     const double ds3 = Dftilde_*std::sqrt(sigma_mean2_[j])*r3;
+     832          24 :     new_ftilde[j] = ftilde_[j] + ds3;
+     833             :   }
+     834             :   // calculate new energy
+     835          12 :   double new_energy = getEnergyMIGEN(mean_,new_ftilde,sigma_,scale_,offset_);
+     836             : 
+     837             :   // accept or reject
+     838          12 :   const double delta = ( new_energy - old_energy ) / kbt_;
+     839             :   // if delta is negative always accept move
+     840          12 :   if( delta <= 0.0 ) {
+     841          12 :     old_energy = new_energy;
+     842          12 :     ftilde_ = new_ftilde;
+     843          12 :     MCacceptFT_++;
+     844             :     // otherwise extract random number
+     845             :   } else {
+     846           0 :     const double s = random[0].RandU01();
+     847           0 :     if( s < std::exp(-delta) ) {
+     848           0 :       old_energy = new_energy;
+     849           0 :       ftilde_ = new_ftilde;
+     850           0 :       MCacceptFT_++;
+     851             :     }
+     852             :   }
+     853          12 : }
+     854             : 
+     855        1848 : void MetainferenceBase::moveScaleOffset(const std::vector<double> &mean_, double &old_energy)
+     856             : {
+     857        1848 :   double new_scale = scale_;
+     858             : 
+     859        1848 :   if(doscale_) {
+     860        1824 :     if(scale_prior_==SC_FLAT) {
+     861        1824 :       const double r1 = random[1].Gaussian();
+     862        1824 :       const double ds1 = Dscale_*r1;
+     863        1824 :       new_scale += ds1;
+     864             :       // check boundaries
+     865        1824 :       if(new_scale > scale_max_) {new_scale = 2.0 * scale_max_ - new_scale;}
+     866        1824 :       if(new_scale < scale_min_) {new_scale = 2.0 * scale_min_ - new_scale;}
+     867             :     } else {
+     868           0 :       const double r1 = random[1].Gaussian();
+     869           0 :       const double ds1 = 0.5*(scale_mu_-new_scale)+Dscale_*std::exp(1)/M_PI*r1;
+     870           0 :       new_scale += ds1;
+     871             :     }
+     872             :   }
+     873             : 
+     874        1848 :   double new_offset = offset_;
+     875             : 
+     876        1848 :   if(dooffset_) {
+     877          24 :     if(offset_prior_==SC_FLAT) {
+     878          24 :       const double r1 = random[1].Gaussian();
+     879          24 :       const double ds1 = Doffset_*r1;
+     880          24 :       new_offset += ds1;
+     881             :       // check boundaries
+     882          24 :       if(new_offset > offset_max_) {new_offset = 2.0 * offset_max_ - new_offset;}
+     883          24 :       if(new_offset < offset_min_) {new_offset = 2.0 * offset_min_ - new_offset;}
+     884             :     } else {
+     885           0 :       const double r1 = random[1].Gaussian();
+     886           0 :       const double ds1 = 0.5*(offset_mu_-new_offset)+Doffset_*std::exp(1)/M_PI*r1;
+     887           0 :       new_offset += ds1;
+     888             :     }
+     889             :   }
+     890             : 
+     891             :   // calculate new energy
+     892             :   double new_energy = 0.;
+     893             : 
+     894        1848 :   switch(noise_type_) {
+     895          12 :   case GAUSS:
+     896          12 :     new_energy = getEnergyGJ(mean_,sigma_,new_scale,new_offset);
+     897             :     break;
+     898          48 :   case MGAUSS:
+     899          48 :     new_energy = getEnergyGJE(mean_,sigma_,new_scale,new_offset);
+     900             :     break;
+     901           0 :   case OUTLIERS:
+     902           0 :     new_energy = getEnergySP(mean_,sigma_,new_scale,new_offset);
+     903             :     break;
+     904        1776 :   case MOUTLIERS:
+     905        1776 :     new_energy = getEnergySPE(mean_,sigma_,new_scale,new_offset);
+     906             :     break;
+     907          12 :   case GENERIC:
+     908          12 :     new_energy = getEnergyMIGEN(mean_,ftilde_,sigma_,new_scale,new_offset);
+     909             :     break;
+     910             :   }
+     911             : 
+     912             :   // for the scale/offset we need to consider the total energy
+     913        1848 :   std::vector<double> totenergies(2);
+     914        1848 :   if(master) {
+     915         936 :     totenergies[0] = old_energy;
+     916         936 :     totenergies[1] = new_energy;
+     917         936 :     if(nrep_>1) multi_sim_comm.Sum(totenergies);
+     918             :   } else {
+     919         912 :     totenergies[0] = 0;
+     920         912 :     totenergies[1] = 0;
+     921             :   }
+     922        1848 :   comm.Sum(totenergies);
+     923             : 
+     924             :   // accept or reject
+     925        1848 :   const double delta = ( totenergies[1] - totenergies[0] ) / kbt_;
+     926             :   // if delta is negative always accept move
+     927        1848 :   if( delta <= 0.0 ) {
+     928        1848 :     old_energy = new_energy;
+     929        1848 :     scale_ = new_scale;
+     930        1848 :     offset_ = new_offset;
+     931        1848 :     MCacceptScale_++;
+     932             :     // otherwise extract random number
+     933             :   } else {
+     934           0 :     double s = random[1].RandU01();
+     935           0 :     if( s < std::exp(-delta) ) {
+     936           0 :       old_energy = new_energy;
+     937           0 :       scale_ = new_scale;
+     938           0 :       offset_ = new_offset;
+     939           0 :       MCacceptScale_++;
+     940             :     }
+     941             :   }
+     942        1848 : }
+     943             : 
+     944        2225 : void MetainferenceBase::moveSigmas(const std::vector<double> &mean_, double &old_energy, const unsigned i, const std::vector<unsigned> &indices, bool &breaknow)
+     945             : {
+     946        2225 :   std::vector<double> new_sigma(sigma_.size());
+     947        2225 :   new_sigma = sigma_;
+     948             : 
+     949             :   // change MCchunksize_ sigmas
+     950        2225 :   if (MCchunksize_ > 0) {
+     951           0 :     if ((MCchunksize_ * i) >= sigma_.size()) {
+     952             :       // This means we are not moving any sigma, so we should break immediately
+     953           0 :       breaknow = true;
+     954             :     }
+     955             : 
+     956             :     // change random sigmas
+     957           0 :     for(unsigned j=0; j<MCchunksize_; j++) {
+     958           0 :       const unsigned shuffle_index = j + MCchunksize_ * i;
+     959           0 :       if (shuffle_index >= sigma_.size()) {
+     960             :         // Going any further will segfault but we should still evaluate the sigmas we changed
+     961             :         break;
+     962             :       }
+     963           0 :       const unsigned index = indices[shuffle_index];
+     964           0 :       const double r2 = random[0].Gaussian();
+     965           0 :       const double ds2 = Dsigma_[index]*r2;
+     966           0 :       new_sigma[index] = sigma_[index] + ds2;
+     967             :       // check boundaries
+     968           0 :       if(new_sigma[index] > sigma_max_[index]) {new_sigma[index] = 2.0 * sigma_max_[index] - new_sigma[index];}
+     969           0 :       if(new_sigma[index] < sigma_min_[index]) {new_sigma[index] = 2.0 * sigma_min_[index] - new_sigma[index];}
+     970             :     }
+     971             :   } else {
+     972             :     // change all sigmas
+     973       13486 :     for(unsigned j=0; j<sigma_.size(); j++) {
+     974       11261 :       const double r2 = random[0].Gaussian();
+     975       11261 :       const double ds2 = Dsigma_[j]*r2;
+     976       11261 :       new_sigma[j] = sigma_[j] + ds2;
+     977             :       // check boundaries
+     978       11261 :       if(new_sigma[j] > sigma_max_[j]) {new_sigma[j] = 2.0 * sigma_max_[j] - new_sigma[j];}
+     979       11261 :       if(new_sigma[j] < sigma_min_[j]) {new_sigma[j] = 2.0 * sigma_min_[j] - new_sigma[j];}
+     980             :     }
+     981             :   }
+     982             : 
+     983        2225 :   if (breaknow) {
+     984             :     // We didnt move any sigmas, so no sense in evaluating anything
+     985             :     return;
+     986             :   }
+     987             : 
+     988             :   // calculate new energy
+     989             :   double new_energy = 0.;
+     990        2225 :   switch(noise_type_) {
+     991         271 :   case GAUSS:
+     992         271 :     new_energy = getEnergyGJ(mean_,new_sigma,scale_,offset_);
+     993             :     break;
+     994         160 :   case MGAUSS:
+     995         160 :     new_energy = getEnergyGJE(mean_,new_sigma,scale_,offset_);
+     996             :     break;
+     997           6 :   case OUTLIERS:
+     998           6 :     new_energy = getEnergySP(mean_,new_sigma,scale_,offset_);
+     999             :     break;
+    1000        1776 :   case MOUTLIERS:
+    1001        1776 :     new_energy = getEnergySPE(mean_,new_sigma,scale_,offset_);
+    1002             :     break;
+    1003          12 :   case GENERIC:
+    1004          12 :     new_energy = getEnergyMIGEN(mean_,ftilde_,new_sigma,scale_,offset_);
+    1005             :     break;
+    1006             :   }
+    1007             : 
+    1008             :   // accept or reject
+    1009        2225 :   const double delta = ( new_energy - old_energy ) / kbt_;
+    1010             :   // if delta is negative always accept move
+    1011        2225 :   if( delta <= 0.0 ) {
+    1012        2225 :     old_energy = new_energy;
+    1013        2225 :     sigma_ = new_sigma;
+    1014        2225 :     MCaccept_++;
+    1015             :     // otherwise extract random number
+    1016             :   } else {
+    1017           0 :     const double s = random[0].RandU01();
+    1018           0 :     if( s < std::exp(-delta) ) {
+    1019           0 :       old_energy = new_energy;
+    1020           0 :       sigma_ = new_sigma;
+    1021           0 :       MCaccept_++;
+    1022             :     }
+    1023             :   }
+    1024             : }
+    1025             : 
+    1026        2225 : double MetainferenceBase::doMonteCarlo(const std::vector<double> &mean_)
+    1027             : {
+    1028             :   // calculate old energy with the updated coordinates
+    1029        2225 :   double old_energy=0.;
+    1030             : 
+    1031        2225 :   switch(noise_type_) {
+    1032         271 :   case GAUSS:
+    1033         271 :     old_energy = getEnergyGJ(mean_,sigma_,scale_,offset_);
+    1034         271 :     break;
+    1035         160 :   case MGAUSS:
+    1036         160 :     old_energy = getEnergyGJE(mean_,sigma_,scale_,offset_);
+    1037         160 :     break;
+    1038           6 :   case OUTLIERS:
+    1039           6 :     old_energy = getEnergySP(mean_,sigma_,scale_,offset_);
+    1040           6 :     break;
+    1041        1776 :   case MOUTLIERS:
+    1042        1776 :     old_energy = getEnergySPE(mean_,sigma_,scale_,offset_);
+    1043        1776 :     break;
+    1044          12 :   case GENERIC:
+    1045          12 :     old_energy = getEnergyMIGEN(mean_,ftilde_,sigma_,scale_,offset_);
+    1046          12 :     break;
+    1047             :   }
+    1048             : 
+    1049             :   // do not run MC if this is a replica-exchange trial
+    1050        2225 :   if(!getExchangeStep()) {
+    1051             : 
+    1052             :     // Create std::vector of random sigma indices
+    1053             :     std::vector<unsigned> indices;
+    1054        2225 :     if (MCchunksize_ > 0) {
+    1055           0 :       for (unsigned j=0; j<sigma_.size(); j++) {
+    1056           0 :         indices.push_back(j);
+    1057             :       }
+    1058           0 :       random[2].Shuffle(indices);
+    1059             :     }
+    1060        2225 :     bool breaknow = false;
+    1061             : 
+    1062             :     // cycle on MC steps
+    1063        4450 :     for(unsigned i=0; i<MCsteps_; ++i) {
+    1064        2225 :       MCtrial_++;
+    1065             :       // propose move for ftilde
+    1066        2225 :       if(noise_type_==GENERIC) moveTilde(mean_, old_energy);
+    1067             :       // propose move for scale and/or offset
+    1068        2225 :       if(doscale_||dooffset_) moveScaleOffset(mean_, old_energy);
+    1069             :       // propose move for sigma
+    1070        2225 :       moveSigmas(mean_, old_energy, i, indices, breaknow);
+    1071             :       // exit from the loop if this is the case
+    1072        2225 :       if(breaknow) break;
+    1073             :     }
+    1074             : 
+    1075             :     /* save the result of the sampling */
+    1076             :     /* ftilde */
+    1077        2225 :     if(noise_type_==GENERIC) {
+    1078          12 :       double accept = static_cast<double>(MCacceptFT_) / static_cast<double>(MCtrial_);
+    1079          12 :       valueAcceptFT->set(accept);
+    1080          36 :       for(unsigned i=0; i<sigma_.size(); i++) valueFtilde[i]->set(ftilde_[i]);
+    1081             :     }
+    1082             :     /* scale and offset */
+    1083        2225 :     if(doscale_ || doregres_zero_) valueScale->set(scale_);
+    1084        2225 :     if(dooffset_) valueOffset->set(offset_);
+    1085        2225 :     if(doscale_||dooffset_) {
+    1086        1848 :       double accept = static_cast<double>(MCacceptScale_) / static_cast<double>(MCtrial_);
+    1087        1848 :       valueAcceptScale->set(accept);
+    1088             :     }
+    1089             :     /* sigmas */
+    1090       13486 :     for(unsigned i=0; i<sigma_.size(); i++) valueSigma[i]->set(sigma_[i]);
+    1091        2225 :     double accept = static_cast<double>(MCaccept_) / static_cast<double>(MCtrial_);
+    1092        2225 :     valueAccept->set(accept);
+    1093             :   }
+    1094             : 
+    1095             :   // here we sum the score over the replicas to get the full metainference score that we save as a bias
+    1096        2225 :   if(master) {
+    1097        1227 :     if(nrep_>1) multi_sim_comm.Sum(old_energy);
+    1098             :   } else {
+    1099         998 :     old_energy=0;
+    1100             :   }
+    1101        2225 :   comm.Sum(old_energy);
+    1102             : 
+    1103             :   // this is the energy with current coordinates and parameters
+    1104        2225 :   return old_energy;
+    1105             : }
+    1106             : 
+    1107             : /*
+    1108             :    In the following energy-force functions we don't add the normalisation and the jeffreys priors
+    1109             :    because they are not needed for the forces, the correct MetaInference energy is the one calculated
+    1110             :    in the Monte-Carlo
+    1111             : */
+    1112             : 
+    1113           6 : void MetainferenceBase::getEnergyForceSP(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1114             :     const std::vector<double> &dmean_b)
+    1115             : {
+    1116           6 :   const double scale2 = scale_*scale_;
+    1117           6 :   const double sm2    = sigma_mean2_[0];
+    1118           6 :   const double ss2    = sigma_[0]*sigma_[0] + scale2*sm2;
+    1119           6 :   std::vector<double> f(narg,0);
+    1120             : 
+    1121           6 :   if(master) {
+    1122           6 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1123             :     {
+    1124             :       #pragma omp for
+    1125             :       for(unsigned i=0; i<narg; ++i) {
+    1126             :         const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1127             :         const double a2 = 0.5*dev*dev + ss2;
+    1128             :         if(sm2 > 0.0) {
+    1129             :           const double t = std::exp(-a2/sm2);
+    1130             :           const double dt = 1./t;
+    1131             :           const double dit = 1./(1.-dt);
+    1132             :           f[i] = -scale_*dev*(dit/sm2 + 1./a2);
+    1133             :         }
+    1134             :         else {
+    1135             :           f[i] = -scale_*dev*(1./a2);
+    1136             :         }
+    1137             :       }
+    1138             :     }
+    1139             :     // collect contribution to forces and energy from other replicas
+    1140           6 :     if(nrep_>1) multi_sim_comm.Sum(&f[0],narg);
+    1141             :   }
+    1142             :   // intra-replica summation
+    1143           6 :   comm.Sum(&f[0],narg);
+    1144             : 
+    1145             :   double w_tmp = 0.;
+    1146          48 :   for(unsigned i=0; i<narg; ++i) {
+    1147          42 :     setMetaDer(i, -kbt_*f[i]*dmean_x[i]);
+    1148          42 :     w_tmp += kbt_*f[i]*dmean_b[i];
+    1149             :   }
+    1150             : 
+    1151           6 :   if(do_reweight_) {
+    1152           0 :     setArgDerivatives(valueScore, -w_tmp);
+    1153           0 :     getPntrToComponent("biasDer")->set(-w_tmp);
+    1154             :   }
+    1155           6 : }
+    1156             : 
+    1157        1776 : void MetainferenceBase::getEnergyForceSPE(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1158             :     const std::vector<double> &dmean_b)
+    1159             : {
+    1160        1776 :   const double scale2 = scale_*scale_;
+    1161        1776 :   std::vector<double> f(narg,0);
+    1162             : 
+    1163        1776 :   if(master) {
+    1164         888 :     #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1165             :     {
+    1166             :       #pragma omp for
+    1167             :       for(unsigned i=0; i<narg; ++i) {
+    1168             :         const double sm2 = sigma_mean2_[i];
+    1169             :         const double ss2 = sigma_[i]*sigma_[i] + scale2*sm2;
+    1170             :         const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1171             :         const double a2  = 0.5*dev*dev + ss2;
+    1172             :         if(sm2 > 0.0) {
+    1173             :           const double t   = std::exp(-a2/sm2);
+    1174             :           const double dt  = 1./t;
+    1175             :           const double dit = 1./(1.-dt);
+    1176             :           f[i] = -scale_*dev*(dit/sm2 + 1./a2);
+    1177             :         }
+    1178             :         else {
+    1179             :           f[i] = -scale_*dev*(1./a2);
+    1180             :         }
+    1181             :       }
+    1182             :     }
+    1183             :     // collect contribution to forces and energy from other replicas
+    1184         888 :     if(nrep_>1) multi_sim_comm.Sum(&f[0],narg);
+    1185             :   }
+    1186        1776 :   comm.Sum(&f[0],narg);
+    1187             : 
+    1188             :   double w_tmp = 0.;
+    1189        8880 :   for(unsigned i=0; i<narg; ++i) {
+    1190        7104 :     setMetaDer(i, -kbt_ * dmean_x[i] * f[i]);
+    1191        7104 :     w_tmp += kbt_ * dmean_b[i] *f[i];
+    1192             :   }
+    1193             : 
+    1194        1776 :   if(do_reweight_) {
+    1195        1776 :     setArgDerivatives(valueScore, -w_tmp);
+    1196        3552 :     getPntrToComponent("biasDer")->set(-w_tmp);
+    1197             :   }
+    1198        1776 : }
+    1199             : 
+    1200         271 : void MetainferenceBase::getEnergyForceGJ(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1201             :     const std::vector<double> &dmean_b)
+    1202             : {
+    1203         271 :   const double scale2 = scale_*scale_;
+    1204         271 :   double inv_s2=0.;
+    1205             : 
+    1206         271 :   if(master) {
+    1207         229 :     inv_s2 = 1./(sigma_[0]*sigma_[0] + scale2*sigma_mean2_[0]);
+    1208         229 :     if(nrep_>1) multi_sim_comm.Sum(inv_s2);
+    1209             :   }
+    1210         271 :   comm.Sum(inv_s2);
+    1211             : 
+    1212         271 :   double w_tmp = 0.;
+    1213         271 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(w_tmp)
+    1214             :   {
+    1215             :     #pragma omp for reduction( + : w_tmp)
+    1216             :     for(unsigned i=0; i<narg; ++i) {
+    1217             :       const double dev = scale_*mean[i]-parameters[i]+offset_;
+    1218             :       const double mult = dev*scale_*inv_s2;
+    1219             :       setMetaDer(i, kbt_*dmean_x[i]*mult);
+    1220             :       w_tmp += kbt_*dmean_b[i]*mult;
+    1221             :     }
+    1222             :   }
+    1223             : 
+    1224         271 :   if(do_reweight_) {
+    1225          84 :     setArgDerivatives(valueScore, w_tmp);
+    1226         168 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1227             :   }
+    1228         271 : }
+    1229             : 
+    1230         160 : void MetainferenceBase::getEnergyForceGJE(const std::vector<double> &mean, const std::vector<double> &dmean_x,
+    1231             :     const std::vector<double> &dmean_b)
+    1232             : {
+    1233         160 :   const double scale2 = scale_*scale_;
+    1234         160 :   std::vector<double> inv_s2(sigma_.size(),0.);
+    1235             : 
+    1236         160 :   if(master) {
+    1237        2044 :     for(unsigned i=0; i<sigma_.size(); ++i) inv_s2[i] = 1./(sigma_[i]*sigma_[i] + scale2*sigma_mean2_[i]);
+    1238          92 :     if(nrep_>1) multi_sim_comm.Sum(&inv_s2[0],sigma_.size());
+    1239             :   }
+    1240         160 :   comm.Sum(&inv_s2[0],sigma_.size());
+    1241             : 
+    1242         160 :   double w_tmp = 0.;
+    1243         160 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(w_tmp)
+    1244             :   {
+    1245             :     #pragma omp for reduction( + : w_tmp)
+    1246             :     for(unsigned i=0; i<narg; ++i) {
+    1247             :       const double dev  = scale_*mean[i]-parameters[i]+offset_;
+    1248             :       const double mult = dev*scale_*inv_s2[i];
+    1249             :       setMetaDer(i, kbt_*dmean_x[i]*mult);
+    1250             :       w_tmp += kbt_*dmean_b[i]*mult;
+    1251             :     }
+    1252             :   }
+    1253             : 
+    1254         160 :   if(do_reweight_) {
+    1255          76 :     setArgDerivatives(valueScore, w_tmp);
+    1256         152 :     getPntrToComponent("biasDer")->set(w_tmp);
+    1257             :   }
+    1258         160 : }
+    1259             : 
+    1260          12 : void MetainferenceBase::getEnergyForceMIGEN(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b)
+    1261             : {
+    1262          12 :   std::vector<double> inv_s2(sigma_.size(),0.);
+    1263          12 :   std::vector<double> dev(sigma_.size(),0.);
+    1264          12 :   std::vector<double> dev2(sigma_.size(),0.);
+    1265             : 
+    1266          36 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+    1267          24 :     inv_s2[i]   = 1./sigma_mean2_[i];
+    1268          24 :     if(master) {
+    1269          24 :       dev[i]  = (mean[i]-ftilde_[i]);
+    1270          24 :       dev2[i] = dev[i]*dev[i];
+    1271             :     }
+    1272             :   }
+    1273          12 :   if(master&&nrep_>1) {
+    1274           0 :     multi_sim_comm.Sum(&dev[0],dev.size());
+    1275           0 :     multi_sim_comm.Sum(&dev2[0],dev2.size());
+    1276             :   }
+    1277          12 :   comm.Sum(&dev[0],dev.size());
+    1278          12 :   comm.Sum(&dev2[0],dev2.size());
+    1279             : 
+    1280          12 :   double dene_b = 0.;
+    1281          12 :   #pragma omp parallel num_threads(OpenMP::getNumThreads()) shared(dene_b)
+    1282             :   {
+    1283             :     #pragma omp for reduction( + : dene_b)
+    1284             :     for(unsigned i=0; i<narg; ++i) {
+    1285             :       const double dene_x  = kbt_*inv_s2[i]*dmean_x[i]*dev[i];
+    1286             :       dene_b += kbt_*inv_s2[i]*dmean_b[i]*dev[i];
+    1287             :       setMetaDer(i, dene_x);
+    1288             :     }
+    1289             :   }
+    1290             : 
+    1291          12 :   if(do_reweight_) {
+    1292           0 :     setArgDerivatives(valueScore, dene_b);
+    1293           0 :     getPntrToComponent("biasDer")->set(dene_b);
+    1294             :   }
+    1295          12 : }
+    1296             : 
+    1297        2225 : void MetainferenceBase::get_weights(double &weight, double &norm, double &neff)
+    1298             : {
+    1299        2225 :   const double dnrep = static_cast<double>(nrep_);
+    1300             :   // calculate the weights either from BIAS
+    1301        2225 :   if(do_reweight_) {
+    1302        1936 :     std::vector<double> bias(nrep_,0);
+    1303        1936 :     if(master) {
+    1304         980 :       bias[replica_] = getArgument(0);
+    1305         980 :       if(nrep_>1) multi_sim_comm.Sum(&bias[0], nrep_);
+    1306             :     }
+    1307        1936 :     comm.Sum(&bias[0], nrep_);
+    1308             : 
+    1309             :     // accumulate weights
+    1310        1936 :     if(!firstTimeW[iselect]) {
+    1311        5742 :       for(unsigned i=0; i<nrep_; ++i) {
+    1312        3828 :         const double delta=bias[i]-average_weights_[iselect][i];
+    1313        3828 :         average_weights_[iselect][i]+=decay_w_*delta;
+    1314             :       }
+    1315             :     } else {
+    1316             :       firstTimeW[iselect] = false;
+    1317          66 :       for(unsigned i=0; i<nrep_; ++i) average_weights_[iselect][i] = bias[i];
+    1318             :     }
+    1319             : 
+    1320             :     // set average back into bias and set norm to one
+    1321        1936 :     const double maxbias = *(std::max_element(average_weights_[iselect].begin(), average_weights_[iselect].end()));
+    1322        5808 :     for(unsigned i=0; i<nrep_; ++i) bias[i] = std::exp((average_weights_[iselect][i]-maxbias)/kbt_);
+    1323             :     // set local weight, norm and weight variance
+    1324        1936 :     weight = bias[replica_];
+    1325             :     double w2=0.;
+    1326        5808 :     for(unsigned i=0; i<nrep_; ++i) {
+    1327        3872 :       w2 += bias[i]*bias[i];
+    1328        3872 :       norm += bias[i];
+    1329             :     }
+    1330        1936 :     neff = norm*norm/w2;
+    1331        3872 :     getPntrToComponent("weight")->set(weight/norm);
+    1332             :   } else {
+    1333             :     // or arithmetic ones
+    1334         289 :     neff = dnrep;
+    1335         289 :     weight = 1.0;
+    1336         289 :     norm = dnrep;
+    1337             :   }
+    1338        2225 :   getPntrToComponent("neff")->set(neff);
+    1339        2225 : }
+    1340             : 
+    1341        2225 : void MetainferenceBase::get_sigma_mean(const double weight, const double norm, const double neff, const std::vector<double> &mean)
+    1342             : {
+    1343        2225 :   const double dnrep    = static_cast<double>(nrep_);
+    1344        2225 :   std::vector<double> sigma_mean2_tmp(sigma_mean2_.size());
+    1345             : 
+    1346        2225 :   if(do_optsigmamean_>0) {
+    1347             :     // remove first entry of the history std::vector
+    1348          84 :     if(sigma_mean2_last_[iselect][0].size()==optsigmamean_stride_&&optsigmamean_stride_>0)
+    1349           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[iselect][i].erase(sigma_mean2_last_[iselect][i].begin());
+    1350             :     /* this is the current estimate of sigma mean for each argument
+    1351             :        there is one of this per argument in any case  because it is
+    1352             :        the maximum among these to be used in case of GAUSS/OUTLIER */
+    1353          84 :     std::vector<double> sigma_mean2_now(narg,0);
+    1354          84 :     if(master) {
+    1355         672 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_now[i] = weight*(calc_data_[i]-mean[i])*(calc_data_[i]-mean[i]);
+    1356          42 :       if(nrep_>1) multi_sim_comm.Sum(&sigma_mean2_now[0], narg);
+    1357             :     }
+    1358          84 :     comm.Sum(&sigma_mean2_now[0], narg);
+    1359        1344 :     for(unsigned i=0; i<narg; ++i) sigma_mean2_now[i] *= 1.0/(neff-1.)/norm;
+    1360             : 
+    1361             :     // add sigma_mean2 to history
+    1362          84 :     if(optsigmamean_stride_>0) {
+    1363           0 :       for(unsigned i=0; i<narg; ++i) sigma_mean2_last_[iselect][i].push_back(sigma_mean2_now[i]);
+    1364             :     } else {
+    1365        1344 :       for(unsigned i=0; i<narg; ++i) if(sigma_mean2_now[i] > sigma_mean2_last_[iselect][i][0]) sigma_mean2_last_[iselect][i][0] = sigma_mean2_now[i];
+    1366             :     }
+    1367             : 
+    1368          84 :     if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1369        1344 :       for(unsigned i=0; i<narg; ++i) {
+    1370             :         /* set to the maximum in history std::vector */
+    1371        2520 :         sigma_mean2_tmp[i] = *max_element(sigma_mean2_last_[iselect][i].begin(), sigma_mean2_last_[iselect][i].end());
+    1372             :         /* the standard error of the mean */
+    1373        1260 :         valueSigmaMean[i]->set(std::sqrt(sigma_mean2_tmp[i]));
+    1374        1260 :         if(noise_type_==GENERIC) {
+    1375           0 :           sigma_min_[i] = std::sqrt(sigma_mean2_tmp[i]);
+    1376           0 :           if(sigma_[i] < sigma_min_[i]) sigma_[i] = sigma_min_[i];
+    1377             :         }
+    1378             :       }
+    1379           0 :     } else if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1380             :       // find maximum for each data point
+    1381             :       std::vector <double> max_values;
+    1382           0 :       for(unsigned i=0; i<narg; ++i) max_values.push_back(*max_element(sigma_mean2_last_[iselect][i].begin(), sigma_mean2_last_[iselect][i].end()));
+    1383             :       // find maximum across data points
+    1384           0 :       const double max_now = *max_element(max_values.begin(), max_values.end());
+    1385             :       // set new value
+    1386           0 :       sigma_mean2_tmp[0] = max_now;
+    1387           0 :       valueSigmaMean[0]->set(std::sqrt(sigma_mean2_tmp[0]));
+    1388             :     }
+    1389             :     // endif sigma mean optimization
+    1390             :     // start sigma max optimization
+    1391          84 :     if(do_optsigmamean_>1&&!sigmamax_opt_done_) {
+    1392           0 :       for(unsigned i=0; i<sigma_max_.size(); i++) {
+    1393           0 :         if(sigma_max_est_[i]<sigma_mean2_tmp[i]&&optimized_step_>optsigmamean_stride_) sigma_max_est_[i]=sigma_mean2_tmp[i];
+    1394             :         // ready to set once and for all the value of sigma_max
+    1395           0 :         if(optimized_step_==N_optimized_step_) {
+    1396           0 :           sigmamax_opt_done_=true;
+    1397           0 :           for(unsigned i=0; i<sigma_max_.size(); i++) {
+    1398           0 :             sigma_max_[i]=std::sqrt(sigma_max_est_[i]*dnrep);
+    1399           0 :             Dsigma_[i] = 0.05*(sigma_max_[i] - sigma_min_[i]);
+    1400           0 :             if(sigma_[i]>sigma_max_[i]) sigma_[i]=sigma_max_[i];
+    1401             :           }
+    1402             :         }
+    1403             :       }
+    1404           0 :       optimized_step_++;
+    1405             :     }
+    1406             :     // end sigma max optimization
+    1407             :   } else {
+    1408        2141 :     if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1409       11588 :       for(unsigned i=0; i<narg; ++i) {
+    1410        9724 :         sigma_mean2_tmp[i] = sigma_mean2_last_[iselect][i][0];
+    1411        9724 :         valueSigmaMean[i]->set(std::sqrt(sigma_mean2_tmp[i]));
+    1412             :       }
+    1413         277 :     } else if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1414         277 :       sigma_mean2_tmp[0] = sigma_mean2_last_[iselect][0][0];
+    1415         277 :       valueSigmaMean[0]->set(std::sqrt(sigma_mean2_tmp[0]));
+    1416             :     }
+    1417             :   }
+    1418             : 
+    1419        2225 :   sigma_mean2_ = sigma_mean2_tmp;
+    1420        2225 : }
+    1421             : 
+    1422        2225 : void MetainferenceBase::replica_averaging(const double weight, const double norm, std::vector<double> &mean, std::vector<double> &dmean_b)
+    1423             : {
+    1424        2225 :   if(master) {
+    1425        7472 :     for(unsigned i=0; i<narg; ++i) mean[i] = weight/norm*calc_data_[i];
+    1426        1227 :     if(nrep_>1) multi_sim_comm.Sum(&mean[0], narg);
+    1427             :   }
+    1428        2225 :   comm.Sum(&mean[0], narg);
+    1429             :   // set the derivative of the mean with respect to the bias
+    1430       14052 :   for(unsigned i=0; i<narg; ++i) dmean_b[i] = weight/norm/kbt_*(calc_data_[i]-mean[i])*decay_w_;
+    1431             : 
+    1432             :   // this is only for generic metainference
+    1433        2225 :   if(firstTime) {ftilde_ = mean; firstTime = false;}
+    1434        2225 : }
+    1435             : 
+    1436           0 : void MetainferenceBase::do_regression_zero(const std::vector<double> &mean)
+    1437             : {
+    1438             : // parameters[i] = scale_ * mean[i]: find scale_ with linear regression
+    1439             :   double num = 0.0;
+    1440             :   double den = 0.0;
+    1441           0 :   for(unsigned i=0; i<parameters.size(); ++i) {
+    1442           0 :     num += mean[i] * parameters[i];
+    1443           0 :     den += mean[i] * mean[i];
+    1444             :   }
+    1445           0 :   if(den>0) {
+    1446           0 :     scale_ = num / den;
+    1447             :   } else {
+    1448           0 :     scale_ = 1.0;
+    1449             :   }
+    1450           0 : }
+    1451             : 
+    1452        2225 : double MetainferenceBase::getScore()
+    1453             : {
+    1454             :   /* Metainference */
+    1455             :   /* 1) collect weights */
+    1456        2225 :   double weight = 0.;
+    1457        2225 :   double neff = 0.;
+    1458        2225 :   double norm = 0.;
+    1459        2225 :   get_weights(weight, norm, neff);
+    1460             : 
+    1461             :   /* 2) calculate average */
+    1462        2225 :   std::vector<double> mean(getNarg(),0);
+    1463             :   // this is the derivative of the mean with respect to the argument
+    1464        2225 :   std::vector<double> dmean_x(getNarg(),weight/norm);
+    1465             :   // this is the derivative of the mean with respect to the bias
+    1466        2225 :   std::vector<double> dmean_b(getNarg(),0);
+    1467             :   // calculate it
+    1468        2225 :   replica_averaging(weight, norm, mean, dmean_b);
+    1469             : 
+    1470             :   /* 3) calculates parameters */
+    1471        2225 :   get_sigma_mean(weight, norm, neff, mean);
+    1472             : 
+    1473             :   // in case of regression with zero intercept, calculate scale
+    1474        2225 :   if(doregres_zero_ && getStep()%nregres_zero_==0) do_regression_zero(mean);
+    1475             : 
+    1476             :   /* 4) run monte carlo */
+    1477        2225 :   double ene = doMonteCarlo(mean);
+    1478             : 
+    1479             :   // calculate bias and forces
+    1480        2225 :   switch(noise_type_) {
+    1481         271 :   case GAUSS:
+    1482         271 :     getEnergyForceGJ(mean, dmean_x, dmean_b);
+    1483             :     break;
+    1484         160 :   case MGAUSS:
+    1485         160 :     getEnergyForceGJE(mean, dmean_x, dmean_b);
+    1486             :     break;
+    1487           6 :   case OUTLIERS:
+    1488           6 :     getEnergyForceSP(mean, dmean_x, dmean_b);
+    1489             :     break;
+    1490        1776 :   case MOUTLIERS:
+    1491        1776 :     getEnergyForceSPE(mean, dmean_x, dmean_b);
+    1492             :     break;
+    1493          12 :   case GENERIC:
+    1494          12 :     getEnergyForceMIGEN(mean, dmean_x, dmean_b);
+    1495             :     break;
+    1496             :   }
+    1497             : 
+    1498        2225 :   return ene;
+    1499             : }
+    1500             : 
+    1501         100 : void MetainferenceBase::writeStatus()
+    1502             : {
+    1503         100 :   if(!doscore_) return;
+    1504          31 :   sfile_.rewind();
+    1505          31 :   sfile_.printField("time",getTimeStep()*getStep());
+    1506             :   //nsel
+    1507          62 :   for(unsigned i=0; i<sigma_mean2_last_.size(); i++) {
+    1508             :     std::string msg_i,msg_j;
+    1509          31 :     Tools::convert(i,msg_i);
+    1510             :     std::vector <double> max_values;
+    1511             :     //narg
+    1512        2528 :     for(unsigned j=0; j<narg; ++j) {
+    1513        2497 :       Tools::convert(j,msg_j);
+    1514        2497 :       std::string msg = msg_i+"_"+msg_j;
+    1515        2497 :       if(noise_type_==MGAUSS||noise_type_==MOUTLIERS||noise_type_==GENERIC) {
+    1516        7410 :         sfile_.printField("sigmaMean_"+msg,std::sqrt(*max_element(sigma_mean2_last_[i][j].begin(), sigma_mean2_last_[i][j].end())));
+    1517             :       } else {
+    1518             :         // find maximum for each data point
+    1519          54 :         max_values.push_back(*max_element(sigma_mean2_last_[i][j].begin(), sigma_mean2_last_[i][j].end()));
+    1520             :       }
+    1521             :     }
+    1522          31 :     if(noise_type_==GAUSS||noise_type_==OUTLIERS) {
+    1523             :       // find maximum across data points
+    1524           8 :       const double max_now = std::sqrt(*max_element(max_values.begin(), max_values.end()));
+    1525           8 :       Tools::convert(0,msg_j);
+    1526           8 :       std::string msg = msg_i+"_"+msg_j;
+    1527          16 :       sfile_.printField("sigmaMean_"+msg, max_now);
+    1528             :     }
+    1529             :   }
+    1530        2509 :   for(unsigned i=0; i<sigma_.size(); ++i) {
+    1531             :     std::string msg;
+    1532        2478 :     Tools::convert(i,msg);
+    1533        4956 :     sfile_.printField("sigma_"+msg,sigma_[i]);
+    1534             :   }
+    1535        2509 :   for(unsigned i=0; i<sigma_max_.size(); ++i) {
+    1536             :     std::string msg;
+    1537        2478 :     Tools::convert(i,msg);
+    1538        4956 :     sfile_.printField("sigma_max_"+msg,sigma_max_[i]);
+    1539             :   }
+    1540          31 :   if(noise_type_==GENERIC) {
+    1541           3 :     for(unsigned i=0; i<ftilde_.size(); ++i) {
+    1542             :       std::string msg;
+    1543           2 :       Tools::convert(i,msg);
+    1544           4 :       sfile_.printField("ftilde_"+msg,ftilde_[i]);
+    1545             :     }
+    1546             :   }
+    1547          31 :   sfile_.printField("scale0_",scale_);
+    1548          31 :   sfile_.printField("offset0_",offset_);
+    1549          62 :   for(unsigned i=0; i<average_weights_.size(); i++) {
+    1550             :     std::string msg_i;
+    1551          31 :     Tools::convert(i,msg_i);
+    1552          62 :     sfile_.printField("weight_"+msg_i,average_weights_[i][replica_]);
+    1553             :   }
+    1554          31 :   sfile_.printField();
+    1555          31 :   sfile_.flush();
+    1556             : }
+    1557             : 
+    1558             : }
+    1559             : }
+    1560             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.h.func-sort-c.html b/coverage/isdb/MetainferenceBase.h.func-sort-c.html new file mode 100644 index 000000000000..0b50847c3554 --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717397.3 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase13setParametersERKSt6vectorIdSaIdEE27
_ZN4PLMD4isdb17MetainferenceBase29calculateNumericalDerivativesEPNS_15ActionWithValueE75
_ZN4PLMD4isdb17MetainferenceBase14setDerivativesEv100
_ZN4PLMD4isdb17MetainferenceBase12lockRequestsEv705
_ZN4PLMD4isdb17MetainferenceBase14unlockRequestsEv705
_ZN4PLMD4isdb17MetainferenceBase5applyEv705
_ZN4PLMD4isdb17MetainferenceBase8setScoreEd2225
_ZN4PLMD4isdb17MetainferenceBase17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE11908
_ZN4PLMD4isdb17MetainferenceBase19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE2391632
_ZN4PLMD4isdb17MetainferenceBase17turnOnDerivativesEv3480207
_ZN4PLMD4isdb17MetainferenceBase22getNumberOfDerivativesEv4099243132
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.h.func.html b/coverage/isdb/MetainferenceBase.h.func.html new file mode 100644 index 000000000000..ebf3d87bb5bc --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717397.3 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb17MetainferenceBase12lockRequestsEv705
_ZN4PLMD4isdb17MetainferenceBase13setParametersERKSt6vectorIdSaIdEE27
_ZN4PLMD4isdb17MetainferenceBase14setDerivativesEv100
_ZN4PLMD4isdb17MetainferenceBase14unlockRequestsEv705
_ZN4PLMD4isdb17MetainferenceBase17setBoxDerivativesEPNS_5ValueERKNS_13TensorGenericILj3ELj3EEE11908
_ZN4PLMD4isdb17MetainferenceBase17turnOnDerivativesEv3480207
_ZN4PLMD4isdb17MetainferenceBase19setAtomsDerivativesEPNS_5ValueEjRKNS_13VectorGenericILj3EEE2391632
_ZN4PLMD4isdb17MetainferenceBase22getNumberOfDerivativesEv4099243132
_ZN4PLMD4isdb17MetainferenceBase29calculateNumericalDerivativesEPNS_15ActionWithValueE75
_ZN4PLMD4isdb17MetainferenceBase5applyEv705
_ZN4PLMD4isdb17MetainferenceBase8setScoreEd2225
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/MetainferenceBase.h.gcov.html b/coverage/isdb/MetainferenceBase.h.gcov.html new file mode 100644 index 000000000000..3cfd88e51eac --- /dev/null +++ b/coverage/isdb/MetainferenceBase.h.gcov.html @@ -0,0 +1,463 @@ + + + + + + + + LCOV - plumed test coverage - isdb/MetainferenceBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - MetainferenceBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:717397.3 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_isdb_MetainferenceBase_h
+      23             : #define __PLUMED_isdb_MetainferenceBase_h
+      24             : 
+      25             : #include "core/ActionWithValue.h"
+      26             : #include "core/ActionAtomistic.h"
+      27             : #include "core/ActionWithArguments.h"
+      28             : #include "tools/Communicator.h"
+      29             : #include "core/PlumedMain.h"
+      30             : #include "tools/Random.h"
+      31             : #include "tools/OpenMP.h"
+      32             : 
+      33             : #define PLUMED_METAINF_INIT(ao) Action(ao),MetainferenceBase(ao)
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace isdb {
+      37             : 
+      38             : /**
+      39             : \ingroup INHERIT
+      40             : This is the abstract base class to use for implementing new ISDB Metainference actions, within it there is
+      41             : information as to how to go about implementing a new Metainference action.
+      42             : */
+      43             : 
+      44             : class MetainferenceBase :
+      45             :   public ActionAtomistic,
+      46             :   public ActionWithArguments,
+      47             :   public ActionWithValue
+      48             : {
+      49             : private:
+      50             :   std::vector<double> forces;
+      51             :   std::vector<double> forcesToApply;
+      52             : 
+      53             :   // activate metainference
+      54             :   bool doscore_;
+      55             :   unsigned write_stride_;
+      56             :   // number of experimental data
+      57             :   unsigned narg;
+      58             :   // experimental data
+      59             :   std::vector<double> parameters;
+      60             :   // metainference derivatives
+      61             :   std::vector<double> metader_;
+      62             :   // vector of back-calculated experimental data
+      63             :   std::vector<double> calc_data_;
+      64             : 
+      65             :   // noise type
+      66             :   unsigned noise_type_;
+      67             :   enum { GAUSS, MGAUSS, OUTLIERS, MOUTLIERS, GENERIC };
+      68             :   unsigned gen_likelihood_;
+      69             :   enum { LIKE_GAUSS, LIKE_LOGN };
+      70             :   bool   doscale_;
+      71             :   unsigned scale_prior_;
+      72             :   enum { SC_GAUSS, SC_FLAT };
+      73             :   double scale_;
+      74             :   double scale_mu_;
+      75             :   double scale_min_;
+      76             :   double scale_max_;
+      77             :   double Dscale_;
+      78             :   // scale is data scaling factor
+      79             :   // noise type
+      80             :   unsigned offset_prior_;
+      81             :   bool   dooffset_;
+      82             :   double offset_;
+      83             :   double offset_mu_;
+      84             :   double offset_min_;
+      85             :   double offset_max_;
+      86             :   double Doffset_;
+      87             :   // scale and offset regression
+      88             :   bool doregres_zero_;
+      89             :   int  nregres_zero_;
+      90             :   // sigma is data uncertainty
+      91             :   std::vector<double> sigma_;
+      92             :   std::vector<double> sigma_min_;
+      93             :   std::vector<double> sigma_max_;
+      94             :   std::vector<double> Dsigma_;
+      95             :   // sigma_mean is uncertainty in the mean estimate
+      96             :   std::vector<double> sigma_mean2_;
+      97             :   // this is the estimator of the mean value per replica for generic metainference
+      98             :   std::vector<double> ftilde_;
+      99             :   double Dftilde_;
+     100             : 
+     101             :   // temperature in kbt
+     102             :   double   kbt_;
+     103             : 
+     104             :   // Monte Carlo stuff
+     105             :   std::vector<Random> random;
+     106             :   unsigned MCsteps_;
+     107             :   long long unsigned MCaccept_;
+     108             :   long long unsigned MCacceptScale_;
+     109             :   long long unsigned MCacceptFT_;
+     110             :   long long unsigned MCtrial_;
+     111             :   unsigned MCchunksize_;
+     112             : 
+     113             :   // output
+     114             :   Value*   valueScore;
+     115             :   Value*   valueScale;
+     116             :   Value*   valueOffset;
+     117             :   Value*   valueAccept;
+     118             :   Value*   valueAcceptScale;
+     119             :   Value*   valueAcceptFT;
+     120             :   std::vector<Value*> valueSigma;
+     121             :   std::vector<Value*> valueSigmaMean;
+     122             :   std::vector<Value*> valueFtilde;
+     123             : 
+     124             :   // restart
+     125             :   std::string status_file_name_;
+     126             :   OFile    sfile_;
+     127             : 
+     128             :   // others
+     129             :   bool     firstTime;
+     130             :   std::vector<bool> firstTimeW;
+     131             :   bool     master;
+     132             :   bool     do_reweight_;
+     133             :   unsigned do_optsigmamean_;
+     134             :   unsigned nrep_;
+     135             :   unsigned replica_;
+     136             : 
+     137             :   // selector
+     138             :   unsigned nsel_;
+     139             :   std::string selector_;
+     140             :   unsigned iselect;
+     141             : 
+     142             :   // optimize sigma mean
+     143             :   std::vector< std::vector < std::vector <double> > > sigma_mean2_last_;
+     144             :   unsigned optsigmamean_stride_;
+     145             :   // optimize sigma max
+     146             :   unsigned N_optimized_step_;
+     147             :   unsigned optimized_step_;
+     148             :   bool sigmamax_opt_done_;
+     149             :   std::vector<double> sigma_max_est_;
+     150             : 
+     151             :   // average weights
+     152             :   double decay_w_;
+     153             :   std::vector< std::vector <double> >  average_weights_;
+     154             : 
+     155             :   double getEnergyMIGEN(const std::vector<double> &mean, const std::vector<double> &ftilde, const std::vector<double> &sigma,
+     156             :                         const double scale, const double offset);
+     157             :   double getEnergySP(const std::vector<double> &mean, const std::vector<double> &sigma,
+     158             :                      const double scale, const double offset);
+     159             :   double getEnergySPE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     160             :                       const double scale, const double offset);
+     161             :   double getEnergyGJ(const std::vector<double> &mean, const std::vector<double> &sigma,
+     162             :                      const double scale, const double offset);
+     163             :   double getEnergyGJE(const std::vector<double> &mean, const std::vector<double> &sigma,
+     164             :                       const double scale, const double offset);
+     165             :   void setMetaDer(const unsigned index, const double der);
+     166             :   void getEnergyForceSP(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     167             :   void getEnergyForceSPE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     168             :   void getEnergyForceGJ(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     169             :   void getEnergyForceGJE(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     170             :   void getEnergyForceMIGEN(const std::vector<double> &mean, const std::vector<double> &dmean_x, const std::vector<double> &dmean_b);
+     171             :   double getCalcData(const unsigned index);
+     172             :   void get_weights(double &weight, double &norm, double &neff);
+     173             :   void replica_averaging(const double weight, const double norm, std::vector<double> &mean, std::vector<double> &dmean_b);
+     174             :   void get_sigma_mean(const double weight, const double norm, const double neff, const std::vector<double> &mean);
+     175             :   void do_regression_zero(const std::vector<double> &mean);
+     176             :   void moveTilde(const std::vector<double> &mean_, double &old_energy);
+     177             :   void moveScaleOffset(const std::vector<double> &mean_, double &old_energy);
+     178             :   void moveSigmas(const std::vector<double> &mean_, double &old_energy, const unsigned i, const std::vector<unsigned> &indices, bool &breaknow);
+     179             :   double doMonteCarlo(const std::vector<double> &mean);
+     180             : 
+     181             : public:
+     182             :   static void registerKeywords( Keywords& keys );
+     183             :   explicit MetainferenceBase(const ActionOptions&);
+     184             :   ~MetainferenceBase();
+     185             :   void Initialise(const unsigned input);
+     186             :   void Selector();
+     187             :   unsigned getNarg();
+     188             :   void setNarg(const unsigned input);
+     189             :   void setParameters(const std::vector<double>& input);
+     190             :   void setParameter(const double input);
+     191             :   void setCalcData(const unsigned index, const double datum);
+     192             :   void setCalcData(const std::vector<double>& data);
+     193             :   bool getDoScore();
+     194             :   unsigned getWstride();
+     195             :   double getScore();
+     196             :   void setScore(const double score);
+     197             :   void setDerivatives();
+     198             :   double getMetaDer(const unsigned index);
+     199             :   void writeStatus();
+     200             :   void turnOnDerivatives() override;
+     201             :   unsigned getNumberOfDerivatives() override;
+     202             :   void lockRequests() override;
+     203             :   void unlockRequests() override;
+     204             :   void calculateNumericalDerivatives( ActionWithValue* a ) override;
+     205             :   void apply() override;
+     206             :   void setArgDerivatives(Value *v, const double &d);
+     207             :   void setAtomsDerivatives(Value*v, const unsigned i, const Vector&d);
+     208             :   void setBoxDerivatives(Value*v, const Tensor&d);
+     209             : };
+     210             : 
+     211             : inline
+     212             : void MetainferenceBase::setNarg(const unsigned input)
+     213             : {
+     214          31 :   narg = input;
+     215             : }
+     216             : 
+     217             : inline
+     218             : bool MetainferenceBase::getDoScore()
+     219             : {
+     220       22370 :   return doscore_;
+     221             : }
+     222             : 
+     223             : inline
+     224             : unsigned MetainferenceBase::getWstride()
+     225             : {
+     226        1410 :   return write_stride_;
+     227             : }
+     228             : 
+     229             : inline
+     230             : unsigned MetainferenceBase::getNarg()
+     231             : {
+     232        2225 :   return narg;
+     233             : }
+     234             : 
+     235             : inline
+     236             : void MetainferenceBase::setMetaDer(const unsigned index, const double der)
+     237             : {
+     238        7146 :   metader_[index] = der;
+     239             : }
+     240             : 
+     241             : inline
+     242             : double MetainferenceBase::getMetaDer(const unsigned index)
+     243             : {
+     244      909788 :   return metader_[index];
+     245             : }
+     246             : 
+     247             : inline
+     248             : double MetainferenceBase::getCalcData(const unsigned index)
+     249             : {
+     250             :   return calc_data_[index];
+     251             : }
+     252             : 
+     253             : inline
+     254             : void MetainferenceBase::setCalcData(const unsigned index, const double datum)
+     255             : {
+     256        3868 :   calc_data_[index] = datum;
+     257        3868 : }
+     258             : 
+     259             : inline
+     260             : void MetainferenceBase::setCalcData(const std::vector<double>& data)
+     261             : {
+     262             :   for(unsigned i=0; i<data.size(); i++) calc_data_[i] = data[i];
+     263             : }
+     264             : 
+     265             : inline
+     266          27 : void MetainferenceBase::setParameters(const std::vector<double>& input) {
+     267         168 :   for(unsigned i=0; i<input.size(); i++) parameters.push_back(input[i]);
+     268          27 : }
+     269             : 
+     270             : inline
+     271             : void MetainferenceBase::setParameter(const double input) {
+     272        2356 :   parameters.push_back(input);
+     273        2356 : }
+     274             : 
+     275             : inline
+     276        2225 : void MetainferenceBase::setScore(const double score) {
+     277        2225 :   valueScore->set(score);
+     278        2225 : }
+     279             : 
+     280             : inline
+     281         100 : void MetainferenceBase::setDerivatives() {
+     282             :   // Get appropriate number of derivatives
+     283             :   // Derivatives are first for arguments and then for atoms
+     284             :   unsigned nder;
+     285         100 :   if( getNumberOfAtoms()>0 ) {
+     286         100 :     nder = 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     287             :   } else {
+     288           0 :     nder = getNumberOfArguments();
+     289             :   }
+     290             : 
+     291             :   // Resize all derivative arrays
+     292         100 :   forces.resize( nder ); forcesToApply.resize( nder );
+     293       21340 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(nder);
+     294         100 : }
+     295             : 
+     296             : inline
+     297     3480207 : void MetainferenceBase::turnOnDerivatives() {
+     298     3480207 :   ActionWithValue::turnOnDerivatives();
+     299     3480207 : }
+     300             : 
+     301             : inline
+     302  4099243132 : unsigned MetainferenceBase::getNumberOfDerivatives() {
+     303  4099243132 :   if( getNumberOfAtoms()>0 ) {
+     304  4099243132 :     return 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     305             :   }
+     306           0 :   return getNumberOfArguments();
+     307             : }
+     308             : 
+     309             : inline
+     310         705 : void MetainferenceBase::lockRequests() {
+     311             :   ActionAtomistic::lockRequests();
+     312             :   ActionWithArguments::lockRequests();
+     313         705 : }
+     314             : 
+     315             : inline
+     316         705 : void MetainferenceBase::unlockRequests() {
+     317             :   ActionAtomistic::unlockRequests();
+     318             :   ActionWithArguments::unlockRequests();
+     319         705 : }
+     320             : 
+     321             : inline
+     322          75 : void MetainferenceBase::calculateNumericalDerivatives( ActionWithValue* a=NULL ) {
+     323          75 :   if( getNumberOfArguments()>0 ) {
+     324          48 :     ActionWithArguments::calculateNumericalDerivatives( a );
+     325             :   }
+     326          75 :   if( getNumberOfAtoms()>0 ) {
+     327          75 :     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
+     328        1293 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     329        2322 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) if(getPntrToComponent(j)->hasDerivatives()) save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
+     330             :     }
+     331          75 :     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
+     332        1293 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     333        2322 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) if(getPntrToComponent(j)->hasDerivatives()) getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
+     334             :     }
+     335             :   }
+     336          75 : }
+     337             : 
+     338             : inline
+     339         705 : void MetainferenceBase::apply() {
+     340         705 :   bool wasforced=false; forcesToApply.assign(forcesToApply.size(),0.0);
+     341       32862 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     342       32157 :     if( getPntrToComponent(i)->applyForce( forces ) ) {
+     343             :       wasforced=true;
+     344    41664408 :       for(unsigned i=0; i<forces.size(); ++i) forcesToApply[i]+=forces[i];
+     345             :     }
+     346             :   }
+     347         705 :   if( wasforced ) {
+     348         350 :     unsigned ind=0; addForcesOnArguments( 0, forcesToApply, ind );
+     349         350 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, ind );
+     350             :   }
+     351         705 : }
+     352             : 
+     353             : inline
+     354             : void MetainferenceBase::setArgDerivatives(Value *v, const double &d) {
+     355         160 :   v->addDerivative(0,d);
+     356             : }
+     357             : 
+     358             : inline
+     359     2391632 : void MetainferenceBase::setAtomsDerivatives(Value*v, const unsigned i, const Vector&d) {
+     360     2391632 :   const unsigned noa=getNumberOfArguments();
+     361     2391632 :   v->addDerivative(noa+3*i+0,d[0]);
+     362     2391632 :   v->addDerivative(noa+3*i+1,d[1]);
+     363     2391632 :   v->addDerivative(noa+3*i+2,d[2]);
+     364     2391632 : }
+     365             : 
+     366             : inline
+     367       11908 : void MetainferenceBase::setBoxDerivatives(Value* v,const Tensor&d) {
+     368       11908 :   const unsigned noa=getNumberOfArguments();
+     369             :   const unsigned nat=getNumberOfAtoms();
+     370       11908 :   v->addDerivative(noa+3*nat+0,d(0,0));
+     371       11908 :   v->addDerivative(noa+3*nat+1,d(0,1));
+     372       11908 :   v->addDerivative(noa+3*nat+2,d(0,2));
+     373       11908 :   v->addDerivative(noa+3*nat+3,d(1,0));
+     374       11908 :   v->addDerivative(noa+3*nat+4,d(1,1));
+     375       11908 :   v->addDerivative(noa+3*nat+5,d(1,2));
+     376       11908 :   v->addDerivative(noa+3*nat+6,d(2,0));
+     377       11908 :   v->addDerivative(noa+3*nat+7,d(2,1));
+     378       11908 :   v->addDerivative(noa+3*nat+8,d(2,2));
+     379       11908 : }
+     380             : 
+     381             : 
+     382             : }
+     383             : }
+     384             : 
+     385             : #endif
+     386             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/NOE.cpp.func-sort-c.html b/coverage/isdb/NOE.cpp.func-sort-c.html new file mode 100644 index 000000000000..83a138808bcb --- /dev/null +++ b/coverage/isdb/NOE.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/NOE.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - NOE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10210498.1 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3NOEC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb3NOEC1ERKNS_13ActionOptionsE11
_ZN4PLMD4isdb3NOE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4isdb3NOE6updateEv132
_ZN4PLMD4isdb3NOE9calculateEv456
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/NOE.cpp.func.html b/coverage/isdb/NOE.cpp.func.html new file mode 100644 index 000000000000..dfeefc6393d4 --- /dev/null +++ b/coverage/isdb/NOE.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/NOE.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - NOE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10210498.1 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3NOE16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4isdb3NOE6updateEv132
_ZN4PLMD4isdb3NOE9calculateEv456
_ZN4PLMD4isdb3NOEC1ERKNS_13ActionOptionsE11
_ZN4PLMD4isdb3NOEC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/NOE.cpp.gcov.html b/coverage/isdb/NOE.cpp.gcov.html new file mode 100644 index 000000000000..e13003970b53 --- /dev/null +++ b/coverage/isdb/NOE.cpp.gcov.html @@ -0,0 +1,351 @@ + + + + + + + + LCOV - plumed test coverage - isdb/NOE.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - NOE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10210498.1 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetainferenceBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/NeighborList.h"
+      25             : #include "tools/Pbc.h"
+      26             : #include <memory>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace isdb {
+      30             : 
+      31             : //+PLUMEDOC ISDB_COLVAR NOE
+      32             : /*
+      33             : Calculates NOE intensities as sums of 1/r^6, also averaging over multiple equivalent atoms
+      34             :  or ambiguous NOE.
+      35             : 
+      36             : Each NOE is defined by two groups containing the same number of atoms, distances are
+      37             : calculated in pairs, transformed in 1/r^6, summed and saved as components.
+      38             : 
+      39             : \f[
+      40             : NOE() = (\frac{1}{N_{eq}}\sum_j^{N_{eq}} (\frac{1}{r_j^6}))
+      41             : \f]
+      42             : 
+      43             : NOE can be used to calculate a Metainference score over one or more replicas using the intrinsic implementation
+      44             : of \ref METAINFERENCE that is activated by DOSCORE.
+      45             : 
+      46             : \par Examples
+      47             : In the following examples three noes are defined, the first is calculated based on the distances
+      48             : of atom 1-2 and 3-2; the second is defined by the distance 5-7 and the third by the distances
+      49             : 4-15,4-16,8-15,8-16. \ref METAINFERENCE is activated using DOSCORE.
+      50             : 
+      51             : \plumedfile
+      52             : NOE ...
+      53             : GROUPA1=1,3 GROUPB1=2,2 NOEDIST1=0.6
+      54             : GROUPA2=5 GROUPB2=7 NOEDIST2=0.6
+      55             : GROUPA3=4,4,8,8 GROUPB3=15,16,15,16 NOEDIST3=0.6
+      56             : DOSCORE
+      57             : SIGMA_MEAN0=1
+      58             : LABEL=noes
+      59             : ... NOE
+      60             : 
+      61             : PRINT ARG=noes.* FILE=colvar
+      62             : \endplumedfile
+      63             : 
+      64             : */
+      65             : //+ENDPLUMEDOC
+      66             : 
+      67             : class NOE :
+      68             :   public MetainferenceBase
+      69             : {
+      70             : private:
+      71             :   bool             pbc;
+      72             :   std::vector<unsigned> nga;
+      73             :   std::unique_ptr<NeighborList> nl;
+      74             :   unsigned         tot_size;
+      75             : public:
+      76             :   static void registerKeywords( Keywords& keys );
+      77             :   explicit NOE(const ActionOptions&);
+      78             :   void calculate() override;
+      79             :   void update() override;
+      80             : };
+      81             : 
+      82             : PLUMED_REGISTER_ACTION(NOE,"NOE")
+      83             : 
+      84          13 : void NOE::registerKeywords( Keywords& keys ) {
+      85          13 :   componentsAreNotOptional(keys);
+      86          13 :   MetainferenceBase::registerKeywords(keys);
+      87          26 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      88          26 :   keys.add("numbered","GROUPA","the atoms involved in each of the contacts you wish to calculate. "
+      89             :            "Keywords like GROUPA1, GROUPA2, GROUPA3,... should be listed and one contact will be "
+      90             :            "calculated for each ATOM keyword you specify.");
+      91          26 :   keys.add("numbered","GROUPB","the atoms involved in each of the contacts you wish to calculate. "
+      92             :            "Keywords like GROUPB1, GROUPB2, GROUPB3,... should be listed and one contact will be "
+      93             :            "calculated for each ATOM keyword you specify.");
+      94          26 :   keys.reset_style("GROUPA","atoms");
+      95          26 :   keys.reset_style("GROUPB","atoms");
+      96          26 :   keys.add("numbered","NOEDIST","Add an experimental value for each NOE.");
+      97          26 :   keys.addOutputComponent("noe","default","the # NOE");
+      98          26 :   keys.addOutputComponent("exp","NOEDIST","the # NOE experimental distance");
+      99          13 : }
+     100             : 
+     101          11 : NOE::NOE(const ActionOptions&ao):
+     102             :   PLUMED_METAINF_INIT(ao),
+     103          11 :   pbc(true)
+     104             : {
+     105          11 :   bool nopbc=!pbc;
+     106          11 :   parseFlag("NOPBC",nopbc);
+     107          11 :   pbc=!nopbc;
+     108             : 
+     109             :   // Read in the atoms
+     110             :   std::vector<AtomNumber> t, ga_lista, gb_lista;
+     111          22 :   for(int i=1;; ++i ) {
+     112          66 :     parseAtomList("GROUPA", i, t );
+     113          33 :     if( t.empty() ) break;
+     114          55 :     for(unsigned j=0; j<t.size(); j++) ga_lista.push_back(t[j]);
+     115          22 :     nga.push_back(t.size());
+     116          22 :     t.resize(0);
+     117          22 :   }
+     118             :   std::vector<unsigned> ngb;
+     119          22 :   for(int i=1;; ++i ) {
+     120          66 :     parseAtomList("GROUPB", i, t );
+     121          33 :     if( t.empty() ) break;
+     122          55 :     for(unsigned j=0; j<t.size(); j++) gb_lista.push_back(t[j]);
+     123          22 :     ngb.push_back(t.size());
+     124          22 :     if(ngb[i-1]!=nga[i-1]) error("The same number of atoms is expected for the same GROUPA-GROUPB couple");
+     125          22 :     t.resize(0);
+     126          22 :   }
+     127          11 :   if(nga.size()!=ngb.size()) error("There should be the same number of GROUPA and GROUPB keywords");
+     128             :   // Create neighbour lists
+     129          22 :   nl=Tools::make_unique<NeighborList>(ga_lista,gb_lista,false,true,pbc,getPbc(),comm);
+     130             : 
+     131             :   // Optionally add an experimental value (like with RDCs)
+     132             :   std::vector<double> noedist;
+     133          11 :   noedist.resize( nga.size() );
+     134             :   unsigned ntarget=0;
+     135          29 :   for(unsigned i=0; i<nga.size(); ++i) {
+     136          40 :     if( !parseNumbered( "NOEDIST", i+1, noedist[i] ) ) break;
+     137          18 :     ntarget++;
+     138             :   }
+     139             :   bool addexp=false;
+     140          11 :   if(ntarget!=nga.size() && ntarget!=0) error("found wrong number of NOEDIST values");
+     141          11 :   if(ntarget==nga.size()) addexp=true;
+     142          11 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the NOEDIST values");
+     143             : 
+     144             :   // Output details of all contacts
+     145             :   unsigned index=0;
+     146          33 :   for(unsigned i=0; i<nga.size(); ++i) {
+     147          22 :     log.printf("  The %uth NOE is calculated using %u equivalent couples of atoms\n", i, nga[i]);
+     148          55 :     for(unsigned j=0; j<nga[i]; j++) {
+     149          33 :       log.printf("    couple %u is %d %d.\n", j, ga_lista[index].serial(), gb_lista[index].serial() );
+     150          33 :       index++;
+     151             :     }
+     152             :   }
+     153          11 :   tot_size = index;
+     154             : 
+     155          11 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     156           0 :   else         log.printf("  without periodic boundary conditions\n");
+     157             : 
+     158          22 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     159             : 
+     160          11 :   if(!getDoScore()) {
+     161          21 :     for(unsigned i=0; i<nga.size(); i++) {
+     162          14 :       std::string num; Tools::convert(i,num);
+     163          28 :       addComponentWithDerivatives("noe-"+num);
+     164          28 :       componentIsNotPeriodic("noe-"+num);
+     165             :     }
+     166           7 :     if(addexp) {
+     167          15 :       for(unsigned i=0; i<nga.size(); i++) {
+     168          10 :         std::string num; Tools::convert(i,num);
+     169          20 :         addComponent("exp-"+num);
+     170          10 :         componentIsNotPeriodic("exp-"+num);
+     171          10 :         Value* comp=getPntrToComponent("exp-"+num);
+     172          10 :         comp->set(noedist[i]);
+     173             :       }
+     174             :     }
+     175             :   } else {
+     176          12 :     for(unsigned i=0; i<nga.size(); i++) {
+     177           8 :       std::string num; Tools::convert(i,num);
+     178          16 :       addComponent("noe-"+num);
+     179          16 :       componentIsNotPeriodic("noe-"+num);
+     180             :     }
+     181          12 :     for(unsigned i=0; i<nga.size(); i++) {
+     182           8 :       std::string num; Tools::convert(i,num);
+     183          16 :       addComponent("exp-"+num);
+     184           8 :       componentIsNotPeriodic("exp-"+num);
+     185           8 :       Value* comp=getPntrToComponent("exp-"+num);
+     186           8 :       comp->set(noedist[i]);
+     187             :     }
+     188             :   }
+     189             : 
+     190          11 :   requestAtoms(nl->getFullAtomList(), false);
+     191          11 :   if(getDoScore()) {
+     192           4 :     setParameters(noedist);
+     193           4 :     Initialise(nga.size());
+     194             :   }
+     195          11 :   setDerivatives();
+     196          11 :   checkRead();
+     197          11 : }
+     198             : 
+     199         456 : void NOE::calculate()
+     200             : {
+     201         456 :   const unsigned ngasz=nga.size();
+     202         456 :   std::vector<Vector> deriv(tot_size, Vector{0,0,0});
+     203             : 
+     204         456 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     205             :   for(unsigned i=0; i<ngasz; i++) {
+     206             :     Tensor dervir;
+     207             :     double noe=0;
+     208             :     unsigned index=0;
+     209             :     for(unsigned k=0; k<i; k++) index+=nga[k];
+     210             :     std::string num; Tools::convert(i,num);
+     211             :     Value* val=getPntrToComponent("noe-"+num);
+     212             :     // cycle over equivalent atoms
+     213             :     for(unsigned j=0; j<nga[i]; j++) {
+     214             :       const unsigned i0=nl->getClosePair(index+j).first;
+     215             :       const unsigned i1=nl->getClosePair(index+j).second;
+     216             : 
+     217             :       Vector distance;
+     218             :       if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     219             :       else    distance=delta(getPosition(i0),getPosition(i1));
+     220             : 
+     221             :       const double ir2=1./distance.modulo2();
+     222             :       const double ir6=ir2*ir2*ir2;
+     223             :       const double ir8=6*ir6*ir2;
+     224             : 
+     225             :       noe += ir6;
+     226             :       deriv[index+j] = ir8*distance;
+     227             :       if(!getDoScore()) {
+     228             :         dervir += Tensor(distance, deriv[index+j]);
+     229             :         setAtomsDerivatives(val, i0,  deriv[index+j]);
+     230             :         setAtomsDerivatives(val, i1, -deriv[index+j]);
+     231             :       }
+     232             :     }
+     233             :     val->set(noe);
+     234             :     if(!getDoScore()) {
+     235             :       setBoxDerivatives(val, dervir);
+     236             :     } else setCalcData(i, noe);
+     237             :   }
+     238             : 
+     239         456 :   if(getDoScore()) {
+     240             :     /* Metainference */
+     241          48 :     Tensor dervir;
+     242          48 :     double score = getScore();
+     243          48 :     setScore(score);
+     244             : 
+     245             :     /* calculate final derivatives */
+     246          48 :     Value* val=getPntrToComponent("score");
+     247         144 :     for(unsigned i=0; i<ngasz; i++) {
+     248             :       unsigned index=0;
+     249         144 :       for(unsigned k=0; k<i; k++) index+=nga[k];
+     250             :       // cycle over equivalent atoms
+     251         240 :       for(unsigned j=0; j<nga[i]; j++) {
+     252         144 :         const unsigned i0=nl->getClosePair(index+j).first;
+     253         144 :         const unsigned i1=nl->getClosePair(index+j).second;
+     254             : 
+     255         144 :         Vector distance;
+     256         144 :         if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     257           0 :         else    distance=delta(getPosition(i0),getPosition(i1));
+     258             : 
+     259         144 :         dervir += Tensor(distance,deriv[index+j]*getMetaDer(i));
+     260         144 :         setAtomsDerivatives(val, i0,  deriv[index+j]*getMetaDer(i));
+     261         144 :         setAtomsDerivatives(val, i1, -deriv[index+j]*getMetaDer(i));
+     262             :       }
+     263             :     }
+     264          48 :     setBoxDerivatives(val, dervir);
+     265             :   }
+     266         456 : }
+     267             : 
+     268         132 : void NOE::update() {
+     269             :   // write status file
+     270         132 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     271         132 : }
+     272             : 
+     273             : }
+     274             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/PRE.cpp.func-sort-c.html b/coverage/isdb/PRE.cpp.func-sort-c.html new file mode 100644 index 000000000000..12ffb5b05032 --- /dev/null +++ b/coverage/isdb/PRE.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/PRE.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - PRE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11912992.2 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3PREC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb3PREC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb3PRE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4isdb3PRE6updateEv20
_ZN4PLMD4isdb3PRE9calculateEv350
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/PRE.cpp.func.html b/coverage/isdb/PRE.cpp.func.html new file mode 100644 index 000000000000..fd4ce826c76e --- /dev/null +++ b/coverage/isdb/PRE.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/PRE.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - PRE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11912992.2 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3PRE16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4isdb3PRE6updateEv20
_ZN4PLMD4isdb3PRE9calculateEv350
_ZN4PLMD4isdb3PREC1ERKNS_13ActionOptionsE4
_ZN4PLMD4isdb3PREC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/PRE.cpp.gcov.html b/coverage/isdb/PRE.cpp.gcov.html new file mode 100644 index 000000000000..fb88d628e01d --- /dev/null +++ b/coverage/isdb/PRE.cpp.gcov.html @@ -0,0 +1,417 @@ + + + + + + + + LCOV - plumed test coverage - isdb/PRE.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - PRE.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11912992.2 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetainferenceBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/NeighborList.h"
+      25             : #include "tools/Pbc.h"
+      26             : #include <memory>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace isdb {
+      30             : 
+      31             : //+PLUMEDOC ISDB_COLVAR PRE
+      32             : /*
+      33             : Calculates the Paramagnetic Resonance Enhancement intensity ratio between a spin label atom and a list of atoms .
+      34             : 
+      35             : The reference atom for the spin label is added with SPINLABEL, the affected atom(s)
+      36             : are give as numbered GROUPA1, GROUPA2, ...
+      37             : The additional parameters needed for the calculation are given as INEPT, the inept
+      38             : time, TAUC the correlation time, OMEGA, the Larmor frequency and RTWO for the relaxation
+      39             : time.
+      40             : 
+      41             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : In the following example five PRE intensities are calculated using the distance between the
+      46             : oxygen of the spin label and the backbone hydrogen atoms. Omega is the NMR frequency, RTWO the
+      47             : R2 for the hydrogen atoms, INEPT of 8 ms for the experiment and a TAUC of 1.21 ns
+      48             : 
+      49             : \plumedfile
+      50             : PRE ...
+      51             : LABEL=HN_pre
+      52             : INEPT=8
+      53             : TAUC=1.21
+      54             : OMEGA=900
+      55             : SPINLABEL=1818
+      56             : GROUPA1=86  RTWO1=0.0120272827
+      57             : GROUPA2=177 RTWO2=0.0263953158
+      58             : GROUPA3=285 RTWO3=0.0058899829
+      59             : GROUPA4=335 RTWO4=0.0102072646
+      60             : GROUPA5=451 RTWO5=0.0086341843
+      61             : ... PRE
+      62             : 
+      63             : PRINT ARG=HN_pre.* FILE=PRE.dat STRIDE=1
+      64             : 
+      65             : \endplumedfile
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : class PRE :
+      71             :   public MetainferenceBase
+      72             : {
+      73             : private:
+      74             :   bool             pbc;
+      75             :   bool             doratio;
+      76             :   double           constant;
+      77             :   double           inept;
+      78             :   std::vector<double>   rtwo;
+      79             :   std::vector<unsigned> nga;
+      80             :   std::unique_ptr<NeighborList> nl;
+      81             :   unsigned         tot_size;
+      82             : public:
+      83             :   static void registerKeywords( Keywords& keys );
+      84             :   explicit PRE(const ActionOptions&);
+      85             :   void calculate() override;
+      86             :   void update() override;
+      87             : };
+      88             : 
+      89             : PLUMED_REGISTER_ACTION(PRE,"PRE")
+      90             : 
+      91           6 : void PRE::registerKeywords( Keywords& keys ) {
+      92           6 :   componentsAreNotOptional(keys);
+      93           6 :   MetainferenceBase::registerKeywords(keys);
+      94          12 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      95          12 :   keys.addFlag("NORATIO",false,"Set to TRUE if you want to compute PRE without Intensity Ratio");
+      96          12 :   keys.add("compulsory","INEPT","is the INEPT time (in ms).");
+      97          12 :   keys.add("compulsory","TAUC","is the correlation time (in ns) for this electron-nuclear interaction.");
+      98          12 :   keys.add("compulsory","OMEGA","is the Larmor frequency of the nuclear spin (in MHz).");
+      99          12 :   keys.add("atoms","SPINLABEL","The atom to be used as the paramagnetic center.");
+     100          12 :   keys.add("numbered","GROUPA","the atoms involved in each of the contacts you wish to calculate. "
+     101             :            "Keywords like GROUPA1, GROUPA2, GROUPA3,... should be listed and one contact will be "
+     102             :            "calculated for each ATOM keyword you specify.");
+     103          12 :   keys.reset_style("GROUPA","atoms");
+     104          12 :   keys.add("numbered","RTWO","The relaxation of the atom/atoms in the corresponding GROUPA of atoms. "
+     105             :            "Keywords like RTWO1, RTWO2, RTWO3,... should be listed.");
+     106          12 :   keys.add("numbered","PREINT","Add an experimental value for each PRE.");
+     107          12 :   keys.addOutputComponent("pre","default","the # PRE");
+     108          12 :   keys.addOutputComponent("exp","PREINT","the # PRE experimental intensity");
+     109           6 : }
+     110             : 
+     111           4 : PRE::PRE(const ActionOptions&ao):
+     112             :   PLUMED_METAINF_INIT(ao),
+     113           4 :   pbc(true),
+     114           4 :   doratio(true)
+     115             : {
+     116           4 :   bool nopbc=!pbc;
+     117           4 :   parseFlag("NOPBC",nopbc);
+     118           4 :   pbc=!nopbc;
+     119             : 
+     120           4 :   bool noratio=!doratio;
+     121           4 :   parseFlag("NORATIO",noratio);
+     122           4 :   doratio=!noratio;
+     123             : 
+     124             :   std::vector<AtomNumber> atom;
+     125           8 :   parseAtomList("SPINLABEL",atom);
+     126           4 :   if(atom.size()!=1) error("Number of specified atom should be 1");
+     127             : 
+     128             :   // Read in the atoms
+     129             :   std::vector<AtomNumber> t, ga_lista, gb_lista;
+     130          12 :   for(int i=1;; ++i ) {
+     131          32 :     parseAtomList("GROUPA", i, t );
+     132          16 :     if( t.empty() ) break;
+     133          28 :     for(unsigned j=0; j<t.size(); j++) {ga_lista.push_back(t[j]); gb_lista.push_back(atom[0]);}
+     134          12 :     nga.push_back(t.size());
+     135          12 :     t.resize(0);
+     136          12 :   }
+     137             : 
+     138             :   // Read in reference values
+     139           4 :   rtwo.resize( nga.size() );
+     140           4 :   if(doratio) {
+     141             :     unsigned ntarget=0;
+     142           4 :     for(unsigned i=0; i<nga.size(); ++i) {
+     143           8 :       if( !parseNumbered( "RTWO", i+1, rtwo[i] ) ) break;
+     144           0 :       ntarget++;
+     145             :     }
+     146           4 :     if( ntarget==0 ) {
+     147           4 :       parse("RTWO",rtwo[0]);
+     148          12 :       for(unsigned i=1; i<nga.size(); ++i) rtwo[i]=rtwo[0];
+     149           0 :     } else if( ntarget!=nga.size() ) error("found wrong number of RTWO values");
+     150             :   }
+     151             : 
+     152           4 :   double tauc=0.;
+     153           4 :   parse("TAUC",tauc);
+     154           4 :   if(tauc==0.) error("TAUC must be set");
+     155             : 
+     156           4 :   double omega=0.;
+     157           4 :   parse("OMEGA",omega);
+     158           4 :   if(omega==0.) error("OMEGA must be set");
+     159             : 
+     160           4 :   inept=0.;
+     161           4 :   if(doratio) {
+     162           4 :     parse("INEPT",inept);
+     163           4 :     if(inept==0.) error("INEPT must be set");
+     164           4 :     inept *= 0.001; // ms2s
+     165             :   }
+     166             : 
+     167             :   const double ns2s   = 0.000000001;
+     168             :   const double MHz2Hz = 1000000.;
+     169             :   const double Kappa  = 12300000000.00; // this is 1/15*S*(S+1)*gamma^2*g^2*beta^2
+     170             :   // where gamma is the nuclear gyromagnetic ratio,
+     171             :   // g is the electronic g factor, and beta is the Bohr magneton
+     172             :   // in nm^6/s^2
+     173           4 :   constant = (4.*tauc*ns2s+(3.*tauc*ns2s)/(1+omega*omega*MHz2Hz*MHz2Hz*tauc*tauc*ns2s*ns2s))*Kappa;
+     174             : 
+     175             :   // Optionally add an experimental value (like with RDCs)
+     176             :   std::vector<double> exppre;
+     177           4 :   exppre.resize( nga.size() );
+     178             :   unsigned ntarget=0;
+     179          10 :   for(unsigned i=0; i<nga.size(); ++i) {
+     180          16 :     if( !parseNumbered( "PREINT", i+1, exppre[i] ) ) break;
+     181           6 :     ntarget++;
+     182             :   }
+     183             :   bool addexp=false;
+     184           4 :   if(ntarget!=nga.size() && ntarget!=0) error("found wrong number of PREINT values");
+     185           4 :   if(ntarget==nga.size()) addexp=true;
+     186           4 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the PREINT values");
+     187             : 
+     188             :   // Create neighbour lists
+     189           8 :   nl=Tools::make_unique<NeighborList>(gb_lista,ga_lista,false,true,pbc,getPbc(),comm);
+     190             : 
+     191             :   // Output details of all contacts
+     192             :   unsigned index=0;
+     193          16 :   for(unsigned i=0; i<nga.size(); ++i) {
+     194          12 :     log.printf("  The %uth PRE is calculated using %u equivalent atoms:\n", i, nga[i]);
+     195          12 :     log.printf("    %d", ga_lista[index].serial());
+     196          12 :     index++;
+     197          16 :     for(unsigned j=1; j<nga[i]; j++) {
+     198           4 :       log.printf(" %d", ga_lista[index].serial());
+     199           4 :       index++;
+     200             :     }
+     201          12 :     log.printf("\n");
+     202             :   }
+     203           4 :   tot_size = index;
+     204             : 
+     205           4 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     206           0 :   else         log.printf("  without periodic boundary conditions\n");
+     207             : 
+     208           8 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     209             : 
+     210           4 :   if(!getDoScore()) {
+     211           8 :     for(unsigned i=0; i<nga.size(); i++) {
+     212           6 :       std::string num; Tools::convert(i,num);
+     213          12 :       addComponentWithDerivatives("pre-"+num);
+     214          12 :       componentIsNotPeriodic("pre-"+num);
+     215             :     }
+     216           2 :     if(addexp) {
+     217           0 :       for(unsigned i=0; i<nga.size(); i++) {
+     218           0 :         std::string num; Tools::convert(i,num);
+     219           0 :         addComponent("exp-"+num);
+     220           0 :         componentIsNotPeriodic("exp-"+num);
+     221           0 :         Value* comp=getPntrToComponent("exp-"+num);
+     222           0 :         comp->set(exppre[i]);
+     223             :       }
+     224             :     }
+     225             :   } else {
+     226           8 :     for(unsigned i=0; i<nga.size(); i++) {
+     227           6 :       std::string num; Tools::convert(i,num);
+     228          12 :       addComponent("pre-"+num);
+     229          12 :       componentIsNotPeriodic("pre-"+num);
+     230             :     }
+     231           8 :     for(unsigned i=0; i<nga.size(); i++) {
+     232           6 :       std::string num; Tools::convert(i,num);
+     233          12 :       addComponent("exp-"+num);
+     234           6 :       componentIsNotPeriodic("exp-"+num);
+     235           6 :       Value* comp=getPntrToComponent("exp-"+num);
+     236           6 :       comp->set(exppre[i]);
+     237             :     }
+     238             :   }
+     239             : 
+     240           4 :   requestAtoms(nl->getFullAtomList(), false);
+     241           4 :   if(getDoScore()) {
+     242           2 :     setParameters(exppre);
+     243           2 :     Initialise(nga.size());
+     244             :   }
+     245           4 :   setDerivatives();
+     246           4 :   checkRead();
+     247           4 : }
+     248             : 
+     249         350 : void PRE::calculate()
+     250             : {
+     251         350 :   std::vector<Vector> deriv(tot_size, Vector{0,0,0});
+     252         350 :   std::vector<double> fact(nga.size(), 0.);
+     253             : 
+     254             :   // cycle over the number of PRE
+     255         350 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+     256             :   for(unsigned i=0; i<nga.size(); i++) {
+     257             :     Tensor dervir;
+     258             :     double pre=0;
+     259             :     unsigned index=0;
+     260             :     for(unsigned k=0; k<i; k++) index+=nga[k];
+     261             :     const double c_aver=constant/static_cast<double>(nga[i]);
+     262             :     std::string num; Tools::convert(i,num);
+     263             :     Value* val=getPntrToComponent("pre-"+num);
+     264             :     // cycle over equivalent atoms
+     265             :     for(unsigned j=0; j<nga[i]; j++) {
+     266             :       // the first atom is always the same (the paramagnetic group)
+     267             :       const unsigned i0=nl->getClosePair(index+j).first;
+     268             :       const unsigned i1=nl->getClosePair(index+j).second;
+     269             : 
+     270             :       Vector distance;
+     271             :       if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     272             :       else    distance=delta(getPosition(i0),getPosition(i1));
+     273             : 
+     274             :       const double r2=distance.modulo2();
+     275             :       const double r6=r2*r2*r2;
+     276             :       const double r8=r6*r2;
+     277             :       const double tmpir6=c_aver/r6;
+     278             :       const double tmpir8=-6.*c_aver/r8;
+     279             : 
+     280             :       pre += tmpir6;
+     281             :       deriv[index+j] = -tmpir8*distance;
+     282             :       if(!getDoScore()) dervir   +=  Tensor(distance,deriv[index+j]);
+     283             :     }
+     284             :     double tmpratio;
+     285             :     if(!doratio) {
+     286             :       tmpratio = pre ; //prova a caso per vedere se lui da problemi
+     287             :       fact[i] = 1.; //prova a caso per vedere se lui da problemi
+     288             :     } else {
+     289             :       tmpratio = rtwo[i]*std::exp(-pre*inept) / (rtwo[i]+pre);
+     290             :       fact[i] = -tmpratio*(inept+1./(rtwo[i]+pre));
+     291             :     }
+     292             :     const double ratio = tmpratio;
+     293             :     val->set(ratio) ;
+     294             :     if(!getDoScore()) {
+     295             :       setBoxDerivatives(val, fact[i]*dervir);
+     296             :       for(unsigned j=0; j<nga[i]; j++) {
+     297             :         const unsigned i0=nl->getClosePair(index+j).first;
+     298             :         const unsigned i1=nl->getClosePair(index+j).second;
+     299             :         setAtomsDerivatives(val, i0,  fact[i]*deriv[index+j]);
+     300             :         setAtomsDerivatives(val, i1, -fact[i]*deriv[index+j]);
+     301             :       }
+     302             :     } else setCalcData(i, ratio);
+     303             :   }
+     304             : 
+     305         350 :   if(getDoScore()) {
+     306             :     /* Metainference */
+     307         175 :     Tensor dervir;
+     308         175 :     double score = getScore();
+     309         175 :     setScore(score);
+     310             : 
+     311             :     /* calculate final derivatives */
+     312         175 :     Value* val=getPntrToComponent("score");
+     313         700 :     for(unsigned i=0; i<nga.size(); i++) {
+     314             :       unsigned index=0;
+     315        1050 :       for(unsigned k=0; k<i; k++) index+=nga[k];
+     316             :       // cycle over equivalent atoms
+     317        1225 :       for(unsigned j=0; j<nga[i]; j++) {
+     318         700 :         const unsigned i0=nl->getClosePair(index+j).first;
+     319         700 :         const unsigned i1=nl->getClosePair(index+j).second;
+     320             : 
+     321         700 :         Vector distance;
+     322         700 :         if(pbc) distance=pbcDistance(getPosition(i0),getPosition(i1));
+     323           0 :         else    distance=delta(getPosition(i0),getPosition(i1));
+     324             : 
+     325         700 :         dervir += Tensor(distance,fact[i]*deriv[index+j]*getMetaDer(i));
+     326         700 :         setAtomsDerivatives(val, i0,  fact[i]*deriv[index+j]*getMetaDer(i));
+     327         700 :         setAtomsDerivatives(val, i1, -fact[i]*deriv[index+j]*getMetaDer(i));
+     328             :       }
+     329             :     }
+     330         175 :     setBoxDerivatives(val, dervir);
+     331             :   }
+     332         350 : }
+     333             : 
+     334          20 : void PRE::update() {
+     335             :   // write status file
+     336          20 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     337          20 : }
+     338             : 
+     339             : }
+     340             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/RDC.cpp.func-sort-c.html b/coverage/isdb/RDC.cpp.func-sort-c.html new file mode 100644 index 000000000000..e3714e689889 --- /dev/null +++ b/coverage/isdb/RDC.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - isdb/RDC.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - RDC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:17018193.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3RDCC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb3RDC6do_svdEv5
_ZN4PLMD4isdb3RDCC1ERKNS_13ActionOptionsE29
_ZN4PLMD4isdb3RDC16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD4isdb3RDC6updateEv327
_ZN4PLMD4isdb3RDC9calculateEv2172
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/RDC.cpp.func.html b/coverage/isdb/RDC.cpp.func.html new file mode 100644 index 000000000000..1cbb932d0435 --- /dev/null +++ b/coverage/isdb/RDC.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - isdb/RDC.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - RDC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:17018193.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb3RDC16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD4isdb3RDC6do_svdEv5
_ZN4PLMD4isdb3RDC6updateEv327
_ZN4PLMD4isdb3RDC9calculateEv2172
_ZN4PLMD4isdb3RDCC1ERKNS_13ActionOptionsE29
_ZN4PLMD4isdb3RDCC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/RDC.cpp.gcov.html b/coverage/isdb/RDC.cpp.gcov.html new file mode 100644 index 000000000000..900470a56ce8 --- /dev/null +++ b/coverage/isdb/RDC.cpp.gcov.html @@ -0,0 +1,598 @@ + + + + + + + + LCOV - plumed test coverage - isdb/RDC.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - RDC.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:17018193.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetainferenceBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Pbc.h"
+      25             : 
+      26             : #ifdef __PLUMED_HAS_GSL
+      27             : #include <gsl/gsl_vector.h>
+      28             : #include <gsl/gsl_matrix.h>
+      29             : #include <gsl/gsl_linalg.h>
+      30             : #include <gsl/gsl_blas.h>
+      31             : #endif
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace isdb {
+      35             : 
+      36             : //+PLUMEDOC ISDB_COLVAR RDC
+      37             : /*
+      38             : Calculates the (Residual) Dipolar Coupling between two atoms.
+      39             : 
+      40             : The Dipolar Coupling between two nuclei depends on the \f$\theta\f$ angle between
+      41             : the inter-nuclear vector and the external magnetic field.
+      42             : 
+      43             : \f[
+      44             : D=D_{max}0.5(3\cos^2(\theta)-1)
+      45             : \f]
+      46             : 
+      47             : where
+      48             : 
+      49             : \f[
+      50             : D_{max}=-\mu_0\gamma_1\gamma_2h/(8\pi^3r^3)
+      51             : \f]
+      52             : 
+      53             : that is the maximal value of the dipolar coupling for the two nuclear spins with gyromagnetic ratio \f$\gamma\f$.
+      54             : \f$\mu\f$ is the magnetic constant and h is the Planck constant.
+      55             : 
+      56             : Common Gyromagnetic Ratios (C.G.S)
+      57             : - H(1) 26.7513
+      58             : - C(13) 6.7261
+      59             : - N(15) -2.7116
+      60             : and their products (this is what is given in input using the keyword GYROM)
+      61             : - N-H -72.5388
+      62             : - C-H 179.9319
+      63             : - C-N -18.2385
+      64             : - C-C 45.2404
+      65             : 
+      66             : In isotropic media DCs average to zero because of the rotational
+      67             : averaging, but when the rotational symmetry is broken, either through the introduction of an alignment medium or for molecules
+      68             : with highly anisotropic paramagnetic susceptibility, then the average of the DCs is not zero and it is possible to measure a Residual Dipolar Coupling (RDCs).
+      69             : 
+      70             : This collective variable calculates the Dipolar Coupling for a set of couple of atoms using
+      71             : the above definition.
+      72             : 
+      73             : In a standard MD simulation the average over time of the DC should then be zero. If one wants to model the meaning of a set of measured RDCs it is possible to try to solve the following problem: "what is the distribution of structures and orientations that reproduce the measured RDCs".
+      74             : 
+      75             : This collective variable can then be use to break the rotational symmetry of a simulation by imposing that the average of the DCs over the conformational ensemble must be equal to the measured RDCs \cite Camilloni:2015ka . Since measured RDCs are also a function of the fraction of aligned molecules in the sample it is better to compare them modulo a constant or looking at the correlation.
+      76             : 
+      77             : Alternatively if the molecule is rigid it is possible to use the experimental data to calculate the alignment tensor and the use that to back calculate the RDCs, this is what is usually call the Single Value Decomposition approach. In this case the code rely on the
+      78             : a set of function from the GNU Scientific Library (GSL). (With SVD forces are not currently implemented).
+      79             : 
+      80             : Replica-Averaged simulations can be performed using RDCs, \ref ENSEMBLE, \ref STATS and \ref RESTRAINT .
+      81             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+      82             : 
+      83             : Additional material and examples can be also found in the tutorial \ref isdb-1
+      84             : 
+      85             : \par Examples
+      86             : In the following example five N-H RDCs are defined and averaged over multiple replicas,
+      87             : their correlation is then calculated with respect to a set of experimental data and restrained.
+      88             : In addition, and only for analysis purposes, the same RDCs each single conformation are calculated
+      89             : using a Single Value Decomposition algorithm, then averaged and again compared with the experimental data.
+      90             : 
+      91             : \plumedfile
+      92             : #SETTINGS NREPLICAS=2
+      93             : RDC ...
+      94             : GYROM=-72.5388
+      95             : SCALE=0.001
+      96             : ATOMS1=20,21
+      97             : ATOMS2=37,38
+      98             : ATOMS3=56,57
+      99             : ATOMS4=76,77
+     100             : ATOMS5=92,93
+     101             : LABEL=nh
+     102             : ... RDC
+     103             : 
+     104             : erdc: ENSEMBLE ARG=nh.*
+     105             : 
+     106             : st: STATS ARG=erdc.* PARAMETERS=8.17,-8.271,-10.489,-9.871,-9.152
+     107             : 
+     108             : rdce: RESTRAINT ARG=st.corr KAPPA=0. SLOPE=-25000.0 AT=1.
+     109             : 
+     110             : RDC ...
+     111             : GYROM=-72.5388
+     112             : SVD
+     113             : ATOMS1=20,21 COUPLING1=8.17
+     114             : ATOMS2=37,38 COUPLING2=-8.271
+     115             : ATOMS3=56,57 COUPLING3=-10.489
+     116             : ATOMS4=76,77 COUPLING4=-9.871
+     117             : ATOMS5=92,93 COUPLING5=-9.152
+     118             : LABEL=svd
+     119             : ... RDC
+     120             : 
+     121             : esvd: ENSEMBLE ARG=(svd\.rdc-.*)
+     122             : 
+     123             : st_svd: STATS ARG=esvd.* PARAMETERS=8.17,-8.271,-10.489,-9.871,-9.152
+     124             : 
+     125             : PRINT ARG=st.corr,st_svd.corr,rdce.bias FILE=colvar
+     126             : \endplumedfile
+     127             : 
+     128             : */
+     129             : //+ENDPLUMEDOC
+     130             : 
+     131             : //+PLUMEDOC ISDB_COLVAR PCS
+     132             : /*
+     133             : Calculates the Pseudo-contact shift of a nucleus determined by the presence of a metal ion susceptible to anisotropic magnetization.
+     134             : 
+     135             : The PCS of an atomic nucleus depends on the \f$\theta\f$ angle between the vector from the spin-label to the nucleus
+     136             :  and the external magnetic field and the module of the vector itself \cite Camilloni:2015jf . While in principle the averaging
+     137             : resulting from the tumbling should remove the pseudo-contact shift, in presence of the NMR magnetic field the magnetically anisotropic molecule bound to system will break the rotational symmetry does resulting in measurable values for the PCS and RDC.
+     138             : 
+     139             : PCS values can also be calculated using a Single Value Decomposition approach, in this case the code rely on the
+     140             : a set of function from the GNU Scientific Library (GSL). (With SVD forces are not currently implemented).
+     141             : 
+     142             : Replica-Averaged simulations can be performed using PCS values, \ref ENSEMBLE, \ref STATS and \ref RESTRAINT .
+     143             : Metainference simulations can be performed with this CV and \ref METAINFERENCE .
+     144             : 
+     145             : \par Examples
+     146             : 
+     147             : In the following example five PCS values are defined and their correlation with
+     148             : respect to a set of experimental data is calculated and restrained. In addition,
+     149             : and only for analysis purposes, the same PCS values are calculated using a Single Value
+     150             : Decomposition algorithm.
+     151             : 
+     152             : \plumedfile
+     153             : PCS ...
+     154             : ATOMS1=20,21
+     155             : ATOMS2=20,38
+     156             : ATOMS3=20,57
+     157             : ATOMS4=20,77
+     158             : ATOMS5=20,93
+     159             : LABEL=nh
+     160             : ... PCS
+     161             : 
+     162             : enh: ENSEMBLE ARG=nh.*
+     163             : 
+     164             : st: STATS ARG=enh.* PARAMETERS=8.17,-8.271,-10.489,-9.871,-9.152
+     165             : 
+     166             : pcse: RESTRAINT ARG=st.corr KAPPA=0. SLOPE=-25000.0 AT=1.
+     167             : 
+     168             : PRINT ARG=st.corr,pcse.bias FILE=colvar
+     169             : \endplumedfile
+     170             : 
+     171             : */
+     172             : //+ENDPLUMEDOC
+     173             : 
+     174             : class RDC :
+     175             :   public MetainferenceBase
+     176             : {
+     177             : private:
+     178             :   double         Const;
+     179             :   double         mu_s;
+     180             :   double         scale;
+     181             :   std::vector<double> coupl;
+     182             :   bool           svd;
+     183             :   bool           pbc;
+     184             : 
+     185             : #ifdef __PLUMED_HAS_GSL
+     186             : /// Auxiliary class to delete a gsl_vector.
+     187             : /// If used somewhere else we can move it.
+     188             :   struct gsl_vector_deleter {
+     189             :     void operator()(gsl_vector* p) {
+     190          25 :       gsl_vector_free(p);
+     191          25 :     }
+     192             :   };
+     193             : 
+     194             : /// unique_ptr to a gsl_vector.
+     195             : /// Gets deleted when going out of scope.
+     196             :   typedef std::unique_ptr<gsl_vector,gsl_vector_deleter> gsl_vector_unique_ptr;
+     197             : 
+     198             : /// Auxiliary class to delete a gsl_matrix.
+     199             : /// If used somewhere else we can move it.
+     200             :   struct gsl_matrix_deleter {
+     201             :     void operator()(gsl_matrix* p) {
+     202          15 :       gsl_matrix_free(p);
+     203          15 :     }
+     204             :   };
+     205             : 
+     206             : /// unique_ptr to a gsl_matrix.
+     207             : /// Gets deleted when going out of scope.
+     208             :   typedef std::unique_ptr<gsl_matrix,gsl_matrix_deleter> gsl_matrix_unique_ptr;
+     209             : #endif
+     210             : 
+     211             : 
+     212             :   void do_svd();
+     213             : public:
+     214             :   explicit RDC(const ActionOptions&);
+     215             :   static void registerKeywords( Keywords& keys );
+     216             :   void calculate() override;
+     217             :   void update() override;
+     218             : };
+     219             : 
+     220             : PLUMED_REGISTER_ACTION(RDC,"RDC")
+     221             : PLUMED_REGISTER_ACTION(RDC,"PCS")
+     222             : 
+     223          33 : void RDC::registerKeywords( Keywords& keys ) {
+     224          33 :   componentsAreNotOptional(keys);
+     225          33 :   MetainferenceBase::registerKeywords(keys);
+     226          66 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     227          66 :   keys.add("numbered","ATOMS","the couple of atoms involved in each of the bonds for which you wish to calculate the RDC. "
+     228             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one dipolar coupling will be "
+     229             :            "calculated for each ATOMS keyword you specify.");
+     230          66 :   keys.reset_style("ATOMS","atoms");
+     231          66 :   keys.add("compulsory","GYROM","1.","Add the product of the gyromagnetic constants for the bond. ");
+     232          66 :   keys.add("compulsory","SCALE","1.","Add the scaling factor to take into account concentration and other effects. ");
+     233          66 :   keys.addFlag("SVD",false,"Set to TRUE if you want to back calculate using Single Value Decomposition (need GSL at compilation time).");
+     234          66 :   keys.add("numbered","COUPLING","Add an experimental value for each coupling (needed by SVD and useful for \\ref STATS).");
+     235          66 :   keys.addOutputComponent("rdc","default","the calculated # RDC");
+     236          66 :   keys.addOutputComponent("exp","SVD/COUPLING","the experimental # RDC");
+     237          66 :   keys.addOutputComponent("Sxx","SVD","Tensor component");
+     238          66 :   keys.addOutputComponent("Syy","SVD","Tensor component");
+     239          66 :   keys.addOutputComponent("Szz","SVD","Tensor component");
+     240          66 :   keys.addOutputComponent("Sxy","SVD","Tensor component");
+     241          66 :   keys.addOutputComponent("Sxz","SVD","Tensor component");
+     242          66 :   keys.addOutputComponent("Syz","SVD","Tensor component");
+     243          33 : }
+     244             : 
+     245          29 : RDC::RDC(const ActionOptions&ao):
+     246             :   PLUMED_METAINF_INIT(ao),
+     247          29 :   Const(1.),
+     248          29 :   mu_s(1.),
+     249          29 :   scale(1.),
+     250          29 :   pbc(true)
+     251             : {
+     252          29 :   bool nopbc=!pbc;
+     253          29 :   parseFlag("NOPBC",nopbc);
+     254          29 :   pbc=!nopbc;
+     255             : 
+     256             :   const double RDCConst = 0.3356806;
+     257             :   const double PCSConst = 1.0;
+     258             : 
+     259          29 :   if( getName().find("RDC")!=std::string::npos) { Const *= RDCConst; }
+     260           0 :   else if( getName().find("PCS")!=std::string::npos) { Const *= PCSConst; }
+     261             : 
+     262             :   // Read in the atoms
+     263             :   std::vector<AtomNumber> t, atoms;
+     264          29 :   for(int i=1;; ++i ) {
+     265         292 :     parseAtomList("ATOMS", i, t );
+     266         146 :     if( t.empty() ) break;
+     267         117 :     if( t.size()!=2 ) {
+     268           0 :       std::string ss; Tools::convert(i,ss);
+     269           0 :       error("ATOMS" + ss + " keyword has the wrong number of atoms");
+     270             :     }
+     271         117 :     atoms.push_back(t[0]);
+     272         117 :     atoms.push_back(t[1]);
+     273         117 :     t.resize(0);
+     274         117 :   }
+     275             : 
+     276          29 :   const unsigned ndata = atoms.size()/2;
+     277             : 
+     278             :   // Read in GYROMAGNETIC constants
+     279          29 :   parse("GYROM", mu_s);
+     280          29 :   if(mu_s==0.) error("GYROM cannot be 0");
+     281             : 
+     282             :   // Read in SCALING factors
+     283          29 :   parse("SCALE", scale);
+     284          29 :   if(scale==0.) error("SCALE cannot be 0");
+     285             : 
+     286          29 :   svd=false;
+     287          29 :   parseFlag("SVD",svd);
+     288             : #ifndef __PLUMED_HAS_GSL
+     289             :   if(svd) error("You CANNOT use SVD without GSL. Recompile PLUMED with GSL!\n");
+     290             : #endif
+     291          29 :   if(svd&&getDoScore()) error("It is not possible to use SVD and METAINFERENCE together");
+     292             : 
+     293             :   // Optionally add an experimental value
+     294          29 :   coupl.resize( ndata );
+     295             :   unsigned ntarget=0;
+     296          82 :   for(unsigned i=0; i<ndata; ++i) {
+     297         138 :     if( !parseNumbered( "COUPLING", i+1, coupl[i] ) ) break;
+     298          53 :     ntarget++;
+     299             :   }
+     300             :   bool addexp=false;
+     301          29 :   if(ntarget!=ndata && ntarget!=0) error("found wrong number of COUPLING values");
+     302          29 :   if(ntarget==ndata) addexp=true;
+     303          29 :   if(getDoScore()&&!addexp) error("with DOSCORE you need to set the COUPLING values");
+     304          29 :   if(svd&&!addexp) error("with SVD you need to set the COUPLING values");
+     305             : 
+     306             : 
+     307             :   // Output details of all contacts
+     308          29 :   log.printf("  Gyromagnetic moment is %f. Scaling factor is %f.",mu_s,scale);
+     309         146 :   for(unsigned i=0; i<ndata; ++i) {
+     310         117 :     log.printf("  The %uth Bond Dipolar Coupling is calculated from atoms : %d %d.", i+1, atoms[2*i].serial(), atoms[2*i+1].serial());
+     311         117 :     if(addexp) log.printf(" Experimental coupling is %f.", coupl[i]);
+     312         117 :     log.printf("\n");
+     313             :   }
+     314             : 
+     315          29 :   log<<"  Bibliography "
+     316          58 :      <<plumed.cite("Camilloni C, Vendruscolo M, J. Phys. Chem. B 119, 653 (2015)")
+     317          87 :      <<plumed.cite("Camilloni C, Vendruscolo M, Biochemistry 54, 7470 (2015)");
+     318          58 :   log<< plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     319             : 
+     320             : 
+     321          29 :   if(!getDoScore()&&!svd) {
+     322          80 :     for(unsigned i=0; i<ndata; i++) {
+     323          64 :       std::string num; Tools::convert(i,num);
+     324         128 :       addComponentWithDerivatives("rdc-"+num);
+     325         128 :       componentIsNotPeriodic("rdc-"+num);
+     326             :     }
+     327          16 :     if(addexp) {
+     328           0 :       for(unsigned i=0; i<ndata; i++) {
+     329           0 :         std::string num; Tools::convert(i,num);
+     330           0 :         addComponent("exp-"+num);
+     331           0 :         componentIsNotPeriodic("exp-"+num);
+     332           0 :         Value* comp=getPntrToComponent("exp-"+num);
+     333           0 :         comp->set(coupl[i]);
+     334             :       }
+     335             :     }
+     336             :   } else {
+     337          66 :     for(unsigned i=0; i<ndata; i++) {
+     338          53 :       std::string num; Tools::convert(i,num);
+     339         106 :       addComponentWithDerivatives("rdc-"+num);
+     340         106 :       componentIsNotPeriodic("rdc-"+num);
+     341             :     }
+     342          66 :     for(unsigned i=0; i<ndata; i++) {
+     343          53 :       std::string num; Tools::convert(i,num);
+     344         106 :       addComponent("exp-"+num);
+     345          53 :       componentIsNotPeriodic("exp-"+num);
+     346          53 :       Value* comp=getPntrToComponent("exp-"+num);
+     347          53 :       comp->set(coupl[i]);
+     348             :     }
+     349             :   }
+     350             : 
+     351          29 :   if(svd) {
+     352           3 :     addComponent("Sxx"); componentIsNotPeriodic("Sxx");
+     353           3 :     addComponent("Syy"); componentIsNotPeriodic("Syy");
+     354           3 :     addComponent("Szz"); componentIsNotPeriodic("Szz");
+     355           3 :     addComponent("Sxy"); componentIsNotPeriodic("Sxy");
+     356           3 :     addComponent("Sxz"); componentIsNotPeriodic("Sxz");
+     357           3 :     addComponent("Syz"); componentIsNotPeriodic("Syz");
+     358             :   }
+     359             : 
+     360          29 :   requestAtoms(atoms, false);
+     361          29 :   if(getDoScore()) {
+     362          12 :     setParameters(coupl);
+     363          12 :     Initialise(coupl.size());
+     364             :   }
+     365          29 :   setDerivatives();
+     366          29 :   checkRead();
+     367          29 : }
+     368             : 
+     369           5 : void RDC::do_svd()
+     370             : {
+     371             : #ifdef __PLUMED_HAS_GSL
+     372           5 :   gsl_vector_unique_ptr rdc_vec(gsl_vector_alloc(coupl.size())),
+     373           5 :                         S(gsl_vector_alloc(5)),
+     374           5 :                         Stmp(gsl_vector_alloc(5)),
+     375           5 :                         work(gsl_vector_alloc(5)),
+     376           5 :                         bc(gsl_vector_alloc(coupl.size()));
+     377             : 
+     378           5 :   gsl_matrix_unique_ptr coef_mat(gsl_matrix_alloc(coupl.size(),5)),
+     379           5 :                         A(gsl_matrix_alloc(coupl.size(),5)),
+     380           5 :                         V(gsl_matrix_alloc(5,5));
+     381             : 
+     382           5 :   gsl_matrix_set_zero(coef_mat.get());
+     383           5 :   gsl_vector_set_zero(bc.get());
+     384             : 
+     385             :   unsigned index=0;
+     386           5 :   std::vector<double> dmax(coupl.size());
+     387          30 :   for(unsigned r=0; r<getNumberOfAtoms(); r+=2) {
+     388          25 :     Vector  distance;
+     389          25 :     if(pbc) distance = pbcDistance(getPosition(r),getPosition(r+1));
+     390           0 :     else    distance = delta(getPosition(r),getPosition(r+1));
+     391          25 :     double d    = distance.modulo();
+     392          25 :     double d2   = d*d;
+     393          25 :     double d3   = d2*d;
+     394          25 :     double id3  = 1./d3;
+     395          25 :     double max  = -Const*mu_s*scale;
+     396          25 :     dmax[index] = id3*max;
+     397          25 :     double mu_x = distance[0]/d;
+     398          25 :     double mu_y = distance[1]/d;
+     399          25 :     double mu_z = distance[2]/d;
+     400          25 :     gsl_vector_set(rdc_vec.get(),index,coupl[index]/dmax[index]);
+     401          25 :     gsl_matrix_set(coef_mat.get(),index,0,gsl_matrix_get(coef_mat.get(),index,0)+(mu_x*mu_x-mu_z*mu_z));
+     402          25 :     gsl_matrix_set(coef_mat.get(),index,1,gsl_matrix_get(coef_mat.get(),index,1)+(mu_y*mu_y-mu_z*mu_z));
+     403          25 :     gsl_matrix_set(coef_mat.get(),index,2,gsl_matrix_get(coef_mat.get(),index,2)+(2.0*mu_x*mu_y));
+     404          25 :     gsl_matrix_set(coef_mat.get(),index,3,gsl_matrix_get(coef_mat.get(),index,3)+(2.0*mu_x*mu_z));
+     405          25 :     gsl_matrix_set(coef_mat.get(),index,4,gsl_matrix_get(coef_mat.get(),index,4)+(2.0*mu_y*mu_z));
+     406          25 :     index++;
+     407             :   }
+     408           5 :   gsl_matrix_memcpy(A.get(),coef_mat.get());
+     409           5 :   gsl_linalg_SV_decomp(A.get(), V.get(), Stmp.get(), work.get());
+     410           5 :   gsl_linalg_SV_solve(A.get(), V.get(), Stmp.get(), rdc_vec.get(), S.get());
+     411             :   /* tensor */
+     412             :   Value* tensor;
+     413           5 :   tensor=getPntrToComponent("Sxx");
+     414           5 :   double Sxx = gsl_vector_get(S.get(),0);
+     415             :   tensor->set(Sxx);
+     416           5 :   tensor=getPntrToComponent("Syy");
+     417           5 :   double Syy = gsl_vector_get(S.get(),1);
+     418             :   tensor->set(Syy);
+     419           5 :   tensor=getPntrToComponent("Szz");
+     420           5 :   double Szz = -Sxx-Syy;
+     421             :   tensor->set(Szz);
+     422           5 :   tensor=getPntrToComponent("Sxy");
+     423           5 :   double Sxy = gsl_vector_get(S.get(),2);
+     424             :   tensor->set(Sxy);
+     425           5 :   tensor=getPntrToComponent("Sxz");
+     426           5 :   double Sxz = gsl_vector_get(S.get(),3);
+     427             :   tensor->set(Sxz);
+     428           5 :   tensor=getPntrToComponent("Syz");
+     429           5 :   double Syz = gsl_vector_get(S.get(),4);
+     430             :   tensor->set(Syz);
+     431             : 
+     432           5 :   gsl_blas_dgemv(CblasNoTrans, 1.0, coef_mat.get(), S.get(), 0., bc.get());
+     433          30 :   for(index=0; index<coupl.size(); index++) {
+     434          25 :     double rdc = gsl_vector_get(bc.get(),index)*dmax[index];
+     435          25 :     Value* val=getPntrToComponent(index);
+     436             :     val->set(rdc);
+     437             :   }
+     438             : #endif
+     439           5 : }
+     440             : 
+     441        2172 : void RDC::calculate()
+     442             : {
+     443        2172 :   if(svd) {
+     444           5 :     do_svd();
+     445           5 :     return;
+     446             :   }
+     447             : 
+     448        2167 :   const double max  = -Const*scale*mu_s;
+     449             :   const unsigned N=getNumberOfAtoms();
+     450        2167 :   std::vector<Vector> dRDC(N/2, Vector{0.,0.,0.});
+     451             : 
+     452             :   /* RDC Calculations and forces */
+     453        2167 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+     454             :   {
+     455             :     #pragma omp for
+     456             :     for(unsigned r=0; r<N; r+=2)
+     457             :     {
+     458             :       const unsigned index=r/2;
+     459             :       Vector  distance;
+     460             :       if(pbc) distance   = pbcDistance(getPosition(r),getPosition(r+1));
+     461             :       else    distance   = delta(getPosition(r),getPosition(r+1));
+     462             :       const double d2    = distance.modulo2();
+     463             :       const double ind   = 1./std::sqrt(d2);
+     464             :       const double ind2  = 1./d2;
+     465             :       const double ind3  = ind2*ind;
+     466             :       const double x2    = distance[0]*distance[0]*ind2;
+     467             :       const double y2    = distance[1]*distance[1]*ind2;
+     468             :       const double z2    = distance[2]*distance[2]*ind2;
+     469             :       const double dmax  = ind3*max;
+     470             :       const double ddmax = dmax*ind2;
+     471             : 
+     472             :       const double rdc   = 0.5*dmax*(3.*z2-1.);
+     473             :       const double prod_xy = (x2+y2-4.*z2);
+     474             :       const double prod_z =  (3.*x2 + 3.*y2 - 2.*z2);
+     475             : 
+     476             :       dRDC[index] = -1.5*ddmax*distance;
+     477             :       dRDC[index][0] *= prod_xy;
+     478             :       dRDC[index][1] *= prod_xy;
+     479             :       dRDC[index][2] *= prod_z;
+     480             : 
+     481             :       std::string num; Tools::convert(index,num);
+     482             :       Value* val=getPntrToComponent("rdc-"+num);
+     483             :       val->set(rdc);
+     484             :       if(!getDoScore()) {
+     485             :         setBoxDerivatives(val, Tensor(distance,dRDC[index]));
+     486             :         setAtomsDerivatives(val, r,  dRDC[index]);
+     487             :         setAtomsDerivatives(val, r+1, -dRDC[index]);
+     488             :       } else setCalcData(index, rdc);
+     489             :     }
+     490             :   }
+     491             : 
+     492        2167 :   if(getDoScore()) {
+     493             :     /* Metainference */
+     494        1824 :     Tensor dervir;
+     495        1824 :     double score = getScore();
+     496        1824 :     setScore(score);
+     497             : 
+     498             :     /* calculate final derivatives */
+     499        1824 :     Value* val=getPntrToComponent("score");
+     500        9120 :     for(unsigned r=0; r<N; r+=2)
+     501             :     {
+     502        7296 :       const unsigned index=r/2;
+     503        7296 :       Vector  distance;
+     504        7296 :       if(pbc) distance   = pbcDistance(getPosition(r),getPosition(r+1));
+     505           0 :       else    distance   = delta(getPosition(r),getPosition(r+1));
+     506        7296 :       const Vector der = dRDC[index]*getMetaDer(index);
+     507        7296 :       dervir += Tensor(distance, der);
+     508        7296 :       setAtomsDerivatives(val, r,  der);
+     509        7296 :       setAtomsDerivatives(val, r+1, -der);
+     510             :     }
+     511        1824 :     setBoxDerivatives(val, dervir);
+     512             :   }
+     513             : }
+     514             : 
+     515         327 : void RDC::update() {
+     516             :   // write status file
+     517         327 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+     518         327 : }
+     519             : 
+     520             : }
+     521             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Rescale.cpp.func-sort-c.html b/coverage/isdb/Rescale.cpp.func-sort-c.html new file mode 100644 index 000000000000..593326b9e563 --- /dev/null +++ b/coverage/isdb/Rescale.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Rescale.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Rescale.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2118611.3 %
Date:2024-02-22 21:58:45Functions:1128.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7Rescale10print_biasEx0
_ZN4PLMD4isdb7Rescale11proposeMoveEjjj0
_ZN4PLMD4isdb7Rescale12doMonteCarloEjdRKSt6vectorIdSaIdEES6_0
_ZN4PLMD4isdb7Rescale8doAcceptEdd0
_ZN4PLMD4isdb7Rescale9calculateEv0
_ZN4PLMD4isdb7Rescale9read_biasEv0
_ZN4PLMD4isdb7RescaleC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleD0Ev0
_ZN4PLMD4isdb7RescaleD1Ev0
_ZN4PLMD4isdb7RescaleD2Ev0
_ZN4PLMD4isdb7Rescale16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Rescale.cpp.func.html b/coverage/isdb/Rescale.cpp.func.html new file mode 100644 index 000000000000..7fdad0aa0fb0 --- /dev/null +++ b/coverage/isdb/Rescale.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Rescale.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Rescale.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2118611.3 %
Date:2024-02-22 21:58:45Functions:1128.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb7Rescale10print_biasEx0
_ZN4PLMD4isdb7Rescale11proposeMoveEjjj0
_ZN4PLMD4isdb7Rescale12doMonteCarloEjdRKSt6vectorIdSaIdEES6_0
_ZN4PLMD4isdb7Rescale16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4isdb7Rescale8doAcceptEdd0
_ZN4PLMD4isdb7Rescale9calculateEv0
_ZN4PLMD4isdb7Rescale9read_biasEv0
_ZN4PLMD4isdb7RescaleC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb7RescaleD0Ev0
_ZN4PLMD4isdb7RescaleD1Ev0
_ZN4PLMD4isdb7RescaleD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Rescale.cpp.gcov.html b/coverage/isdb/Rescale.cpp.gcov.html new file mode 100644 index 000000000000..8ef97cc321e7 --- /dev/null +++ b/coverage/isdb/Rescale.cpp.gcov.html @@ -0,0 +1,590 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Rescale.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Rescale.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2118611.3 %
Date:2024-02-22 21:58:45Functions:1128.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : /*
+      23             : 
+      24             : */
+      25             : #include "bias/Bias.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/Value.h"
+      29             : #include "tools/File.h"
+      30             : #include "tools/Random.h"
+      31             : #include "tools/Communicator.h"
+      32             : #include <ctime>
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace isdb {
+      36             : 
+      37             : //+PLUMEDOC ISDB_BIAS RESCALE
+      38             : /*
+      39             : Scales the value of an another action, being a Collective Variable or a Bias.
+      40             : 
+      41             : The rescaling factor is determined by a parameter defined on a logarithmic grid of dimension NBIN in the range
+      42             : from 1 to MAX_RESCALE. The current value of the rescaling parameter is stored and shared across
+      43             : other actions using a \ref SELECTOR. A Monte Carlo procedure is used to update the value
+      44             : of the rescaling factor every MC_STRIDE steps of molecular dynamics. Well-tempered metadynamics, defined by the
+      45             : parameters W0 and BIASFACTOR, is used to enhance the sampling in the space of the rescaling factor.
+      46             : The well-tempered metadynamics bias potential is written to the file BFILE every BSTRIDE steps and read
+      47             : when restarting the simulation using the directive \ref RESTART.
+      48             : 
+      49             : \note
+      50             : Additional arguments not to be scaled, one for each bin in the rescaling parameter ladder, can be
+      51             : provided at the end of the ARG list. The number of such arguments is specified by the option NOT_RESCALED.
+      52             : These arguments will be not be scaled, but they will be
+      53             : considered as bias potentials and used in the computation of the Metropolis
+      54             : acceptance probability when proposing a move in the rescaling parameter. See example below.
+      55             : 
+      56             : \note
+      57             : If PLUMED is running in a multiple-replica framework (for example using the -multi option in GROMACS),
+      58             : the arguments will be summed across replicas, unless the NOT_SHARED option is used. Also, the value of the
+      59             : \ref SELECTOR will be shared and thus will be the same in all replicas.
+      60             : 
+      61             : \par Examples
+      62             : 
+      63             : In this example we use \ref RESCALE to implement a simulated-tempering like approach.
+      64             : The total potential energy of the system is scaled by a parameter defined on a logarithmic grid
+      65             : of 5 bins in the range from 1 to 1.5.
+      66             : A well-tempered metadynamics bias potential is used to ensure diffusion in the space of the rescaling
+      67             : parameter.
+      68             : 
+      69             : \plumedfile
+      70             : ene: ENERGY
+      71             : 
+      72             : SELECTOR NAME=GAMMA VALUE=0
+      73             : 
+      74             : RESCALE ...
+      75             : LABEL=res ARG=ene TEMP=300
+      76             : SELECTOR=GAMMA MAX_RESCALE=1.5 NBIN=5
+      77             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
+      78             : ...
+      79             : 
+      80             : PRINT FILE=COLVAR ARG=* STRIDE=100
+      81             : \endplumedfile
+      82             : 
+      83             : In this second example, we add to the simulated-tempering approach introduced above
+      84             : one Parallel Bias metadynamics simulation (see \ref PBMETAD) for each value of the rescaling parameter.
+      85             : At each moment of the simulation, only one of the \ref PBMETAD
+      86             : actions is activated, based on the current value of the associated \ref SELECTOR.
+      87             : The \ref PBMETAD bias potentials are not scaled, but just used in the calculation of
+      88             : the Metropolis acceptance probability when proposing a move in the rescaling parameter.
+      89             : 
+      90             : \plumedfile
+      91             : ene: ENERGY
+      92             : d: DISTANCE ATOMS=1,2
+      93             : 
+      94             : SELECTOR NAME=GAMMA VALUE=0
+      95             : 
+      96             : pbmetad0: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=0 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.0
+      97             : pbmetad1: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=1 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.1
+      98             : pbmetad2: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=2 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.2
+      99             : pbmetad3: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=3 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.3
+     100             : pbmetad4: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=4 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.4
+     101             : 
+     102             : RESCALE ...
+     103             : LABEL=res TEMP=300
+     104             : ARG=ene,pbmetad0.bias,pbmetad1.bias,pbmetad2.bias,pbmetad3.bias,pbmetad4.bias
+     105             : SELECTOR=GAMMA MAX_RESCALE=1.5 NOT_RESCALED=5 NBIN=5
+     106             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
+     107             : ...
+     108             : 
+     109             : PRINT FILE=COLVAR ARG=* STRIDE=100
+     110             : \endplumedfile
+     111             : 
+     112             : 
+     113             : 
+     114             : */
+     115             : //+ENDPLUMEDOC
+     116             : 
+     117             : class Rescale : public bias::Bias
+     118             : {
+     119             :   // gamma parameter
+     120             :   std::vector<double> gamma_;
+     121             :   double         w0_;
+     122             :   double         biasf_;
+     123             :   std::vector<double> bias_;
+     124             :   std::vector<double> expo_;
+     125             :   std::vector<unsigned> shared_;
+     126             :   unsigned nores_;
+     127             :   // bias
+     128             :   unsigned int   Biasstride_;
+     129             :   unsigned int   Biaspace_;
+     130             :   std::string         Biasfilename_;
+     131             :   bool           first_bias_;
+     132             :   OFile          Biasfile_;
+     133             :   // temperature in kbt
+     134             :   double kbt_;
+     135             :   // Monte Carlo stuff
+     136             :   unsigned MCsteps_;
+     137             :   unsigned MCstride_;
+     138             :   long long int MCfirst_;
+     139             :   long long unsigned MCaccgamma_;
+     140             :   // replica stuff
+     141             :   unsigned nrep_;
+     142             :   unsigned replica_;
+     143             :   // selector
+     144             :   std::string selector_;
+     145             : 
+     146             :   // Monte Carlo
+     147             :   void doMonteCarlo(unsigned igamma, double oldE, const std::vector<double> & args, const std::vector<double> & bargs);
+     148             :   unsigned proposeMove(unsigned x, unsigned xmin, unsigned xmax);
+     149             :   bool doAccept(double oldE, double newE);
+     150             :   // read and print bias
+     151             :   void read_bias();
+     152             :   void print_bias(long long int step);
+     153             : 
+     154             : public:
+     155             :   explicit Rescale(const ActionOptions&);
+     156             :   ~Rescale();
+     157             :   void calculate();
+     158             :   static void registerKeywords(Keywords& keys);
+     159             : };
+     160             : 
+     161             : 
+     162             : PLUMED_REGISTER_ACTION(Rescale,"RESCALE")
+     163             : 
+     164           2 : void Rescale::registerKeywords(Keywords& keys) {
+     165           2 :   Bias::registerKeywords(keys);
+     166           2 :   keys.use("ARG");
+     167           4 :   keys.add("compulsory","TEMP","temperature");
+     168           4 :   keys.add("compulsory","SELECTOR", "name of the SELECTOR used for rescaling");
+     169           4 :   keys.add("compulsory","MAX_RESCALE","maximum values for rescaling");
+     170           4 :   keys.add("compulsory","NBIN","number of bins for gamma grid");
+     171           4 :   keys.add("compulsory","W0", "initial bias height");
+     172           4 :   keys.add("compulsory","BIASFACTOR", "bias factor");
+     173           4 :   keys.add("compulsory","BSTRIDE", "stride for writing bias");
+     174           4 :   keys.add("compulsory","BFILE", "file name for bias");
+     175           4 :   keys.add("optional","NOT_SHARED",   "list of arguments (from 1 to N) not summed across replicas");
+     176           4 :   keys.add("optional","NOT_RESCALED", "these last N arguments will not be scaled");
+     177           4 :   keys.add("optional","MC_STEPS","number of MC steps");
+     178           4 :   keys.add("optional","MC_STRIDE","MC stride");
+     179           4 :   keys.add("optional","PACE", "Pace for adding bias, in MC stride unit");
+     180           2 :   componentsAreNotOptional(keys);
+     181           4 :   keys.addOutputComponent("igamma",  "default","gamma parameter");
+     182           4 :   keys.addOutputComponent("accgamma","default","MC acceptance for gamma");
+     183           4 :   keys.addOutputComponent("wtbias",  "default","well-tempered bias");
+     184           2 : }
+     185             : 
+     186           0 : Rescale::Rescale(const ActionOptions&ao):
+     187             :   PLUMED_BIAS_INIT(ao),
+     188           0 :   nores_(0), Biaspace_(1), first_bias_(true),
+     189           0 :   MCsteps_(1), MCstride_(1), MCfirst_(-1), MCaccgamma_(0)
+     190             : {
+     191             :   // set up replica stuff
+     192           0 :   if(comm.Get_rank()==0) {
+     193           0 :     nrep_    = multi_sim_comm.Get_size();
+     194           0 :     replica_ = multi_sim_comm.Get_rank();
+     195             :   } else {
+     196           0 :     nrep_    = 0;
+     197           0 :     replica_ = 0;
+     198             :   }
+     199           0 :   comm.Sum(&nrep_,1);
+     200           0 :   comm.Sum(&replica_,1);
+     201             : 
+     202             :   // wt-parameters
+     203           0 :   parse("W0", w0_);
+     204           0 :   parse("BIASFACTOR", biasf_);
+     205             : 
+     206             :   // selector name
+     207           0 :   parse("SELECTOR", selector_);
+     208             : 
+     209             :   // number of bins for gamma ladder
+     210             :   unsigned nbin;
+     211           0 :   parse("NBIN", nbin);
+     212             : 
+     213             :   // number of bias
+     214           0 :   parse("NOT_RESCALED", nores_);
+     215           0 :   if(nores_>0 && nores_!=nbin) error("The number of non scaled arguments must be equal to either 0 or the number of bins");
+     216             : 
+     217             :   // maximum value of rescale
+     218             :   std::vector<double> max_rescale;
+     219           0 :   parseVector("MAX_RESCALE", max_rescale);
+     220             :   // check dimension of max_rescale
+     221           0 :   if(max_rescale.size()!=(getNumberOfArguments()-nores_))
+     222           0 :     error("Size of MAX_RESCALE array must be equal to the number of arguments that will to be scaled");
+     223             : 
+     224             :   // calculate exponents
+     225           0 :   double igamma_max = static_cast<double>(nbin);
+     226           0 :   for(unsigned i=0; i<max_rescale.size(); ++i)
+     227           0 :     expo_.push_back(std::log(max_rescale[i])/std::log(igamma_max));
+     228             : 
+     229             :   // allocate gamma grid and set bias to zero
+     230           0 :   for(unsigned i=0; i<nbin; ++i) {
+     231             :     // bias grid
+     232           0 :     bias_.push_back(0.0);
+     233             :     // gamma ladder
+     234           0 :     double gamma = std::exp( static_cast<double>(i) / static_cast<double>(nbin-1) * std::log(igamma_max) );
+     235           0 :     gamma_.push_back(gamma);
+     236             :   }
+     237             :   // print bias to file
+     238           0 :   parse("BSTRIDE", Biasstride_);
+     239           0 :   parse("BFILE",   Biasfilename_);
+     240             : 
+     241             :   // create vectors of shared arguments
+     242             :   // by default they are all shared
+     243           0 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) shared_.push_back(1);
+     244             :   // share across replicas or not
+     245             :   std::vector<unsigned> not_shared;
+     246           0 :   parseVector("NOT_SHARED", not_shared);
+     247             :   // and change the non-shared
+     248           0 :   for(unsigned i=0; i<not_shared.size(); ++i) {
+     249           0 :     if((not_shared[i]-1)>=(getNumberOfArguments()-nores_) && nrep_>1)
+     250           0 :       error("NOT_RESCALED args must always be shared when using multiple replicas");
+     251           0 :     if((not_shared[i]-1)>=getNumberOfArguments())
+     252           0 :       error("NOT_SHARED args should be lower than total number of arguments");
+     253           0 :     shared_[not_shared[i]-1] = 0;
+     254             :   }
+     255             : 
+     256             :   // monte carlo stuff
+     257           0 :   parse("MC_STEPS",MCsteps_);
+     258           0 :   parse("MC_STRIDE",MCstride_);
+     259             :   // adjust for multiple-time steps
+     260           0 :   MCstride_ *= getStride();
+     261             :   // read bias deposition pace
+     262           0 :   parse("PACE", Biaspace_);
+     263             :   // multiply by MCstride
+     264           0 :   Biaspace_ *= MCstride_;
+     265             : 
+     266             :   // get temperature
+     267           0 :   kbt_=getkBT();
+     268             : 
+     269           0 :   checkRead();
+     270             : 
+     271           0 :   log.printf("  temperature of the system in energy unit %f\n",kbt_);
+     272           0 :   log.printf("  name of the SELECTOR use for this action %s\n",selector_.c_str());
+     273           0 :   log.printf("  number of bins in grid %u\n",nbin);
+     274           0 :   log.printf("  number of arguments that will not be scaled %u\n",nores_);
+     275           0 :   if(nrep_>1) log<<"  number of arguments that will not be summed across replicas "<<not_shared.size()<<"\n";
+     276           0 :   log.printf("  biasfactor %f\n",biasf_);
+     277           0 :   log.printf("  initial hills height %f\n",w0_);
+     278           0 :   log.printf("  stride to write bias to file %u\n",Biasstride_);
+     279           0 :   log.printf("  write bias to file : %s\n",Biasfilename_.c_str());
+     280           0 :   log.printf("  number of replicas %u\n",nrep_);
+     281           0 :   log.printf("  number of MC steps %d\n",MCsteps_);
+     282           0 :   log.printf("  do MC every %d steps\n", MCstride_);
+     283           0 :   log.printf("\n");
+     284             : 
+     285           0 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+     286             : 
+     287             : 
+     288             :   // add components
+     289           0 :   addComponent("igamma");   componentIsNotPeriodic("igamma");
+     290           0 :   addComponent("accgamma"); componentIsNotPeriodic("accgamma");
+     291           0 :   addComponent("wtbias");   componentIsNotPeriodic("wtbias");
+     292             : 
+     293             :   // initialize random seed
+     294           0 :   srand (time(NULL));
+     295             : 
+     296             :   // read bias if restarting
+     297           0 :   if(getRestart()) read_bias();
+     298           0 : }
+     299             : 
+     300           0 : Rescale::~Rescale()
+     301             : {
+     302           0 :   Biasfile_.close();
+     303           0 : }
+     304             : 
+     305           0 : void Rescale::read_bias()
+     306             : {
+     307             : // open file
+     308             :   auto ifile=Tools::make_unique<IFile>();
+     309           0 :   ifile->link(*this);
+     310           0 :   if(ifile->FileExist(Biasfilename_)) {
+     311           0 :     ifile->open(Biasfilename_);
+     312             :     // read all the lines, store last value of bias
+     313             :     double MDtime;
+     314           0 :     while(ifile->scanField("MD_time",MDtime)) {
+     315           0 :       for(unsigned i=0; i<bias_.size(); ++i) {
+     316             :         // convert i to string
+     317           0 :         std::stringstream ss;
+     318             :         ss << i;
+     319             :         // label
+     320           0 :         std::string label = "b" + ss.str();
+     321             :         // read entry
+     322           0 :         ifile->scanField(label, bias_[i]);
+     323           0 :       }
+     324             :       // new line
+     325           0 :       ifile->scanField();
+     326             :     }
+     327           0 :     ifile->close();
+     328             :   } else {
+     329           0 :     error("Cannot find bias file "+Biasfilename_+"\n");
+     330             :   }
+     331           0 : }
+     332             : 
+     333           0 : unsigned Rescale::proposeMove(unsigned x, unsigned xmin, unsigned xmax)
+     334             : {
+     335           0 :   int xmin_i = static_cast<int>(xmin);
+     336           0 :   int xmax_i = static_cast<int>(xmax);
+     337             :   int dx;
+     338           0 :   int r = rand() % 2;
+     339           0 :   if( r % 2 == 0 ) dx = +1;
+     340             :   else             dx = -1;
+     341             : // new index, integer
+     342           0 :   int x_new = static_cast<int>(x) + dx;
+     343             : // check boundaries
+     344           0 :   if(x_new >= xmax_i) x_new = xmax_i-1;
+     345             :   if(x_new <  xmin_i) x_new = xmin_i;
+     346           0 :   return static_cast<unsigned>(x_new);
+     347             : }
+     348             : 
+     349           0 : bool Rescale::doAccept(double oldE, double newE)
+     350             : {
+     351             :   bool accept = false;
+     352             :   // calculate delta energy
+     353           0 :   double delta = ( newE - oldE ) / kbt_;
+     354             :   // if delta is negative always accept move
+     355           0 :   if( delta < 0.0 ) {
+     356             :     accept = true;
+     357             :   } else {
+     358             :     // otherwise extract random number
+     359           0 :     double s = static_cast<double>(rand()) / RAND_MAX;
+     360           0 :     if( s < std::exp(-delta) ) { accept = true; }
+     361             :   }
+     362           0 :   return accept;
+     363             : }
+     364             : 
+     365           0 : void Rescale::doMonteCarlo(unsigned igamma, double oldE,
+     366             :                            const std::vector<double> & args, const std::vector<double> & bargs)
+     367             : {
+     368             :   double oldB, newB;
+     369             : 
+     370             : // cycle on MC steps
+     371           0 :   for(unsigned i=0; i<MCsteps_; ++i) {
+     372             :     // propose move in igamma
+     373           0 :     unsigned new_igamma = proposeMove(igamma, 0, gamma_.size());
+     374             :     // calculate new energy
+     375             :     double newE = 0.0;
+     376           0 :     for(unsigned j=0; j<args.size(); ++j) {
+     377             :       // calculate energy term
+     378           0 :       double fact = 1.0/pow(gamma_[new_igamma], expo_[j]) - 1.0;
+     379           0 :       newE += args[j] * fact;
+     380             :     }
+     381             :     // calculate contributions from non-rescaled terms
+     382           0 :     if(bargs.size()>0) {
+     383           0 :       oldB = bias_[igamma]+bargs[igamma];
+     384           0 :       newB = bias_[new_igamma]+bargs[new_igamma];
+     385             :     } else {
+     386           0 :       oldB = bias_[igamma];
+     387           0 :       newB = bias_[new_igamma];
+     388             :     }
+     389             :     // accept or reject
+     390           0 :     bool accept = doAccept(oldE+oldB, newE+newB);
+     391           0 :     if(accept) {
+     392           0 :       igamma = new_igamma;
+     393             :       oldE = newE;
+     394           0 :       MCaccgamma_++;
+     395             :     }
+     396             :   }
+     397             : // send values of gamma to all replicas
+     398           0 :   if(comm.Get_rank()==0) {
+     399           0 :     if(multi_sim_comm.Get_rank()!=0) igamma = 0;
+     400           0 :     multi_sim_comm.Sum(&igamma, 1);
+     401             :   } else {
+     402           0 :     igamma = 0;
+     403             :   }
+     404             : // local communication
+     405           0 :   comm.Sum(&igamma, 1);
+     406             : 
+     407             : // set the value of gamma into passMap
+     408           0 :   plumed.passMap[selector_]=static_cast<double>(igamma);
+     409           0 : }
+     410             : 
+     411           0 : void Rescale::print_bias(long long int step)
+     412             : {
+     413             : // if first time open the file
+     414           0 :   if(first_bias_) {
+     415           0 :     first_bias_ = false;
+     416           0 :     Biasfile_.link(*this);
+     417           0 :     Biasfile_.open(Biasfilename_);
+     418             :     Biasfile_.setHeavyFlush();
+     419           0 :     Biasfile_.fmtField("%30.5f");
+     420             :   }
+     421             : 
+     422             : // write fields
+     423           0 :   double MDtime = static_cast<double>(step)*getTimeStep();
+     424           0 :   Biasfile_.printField("MD_time", MDtime);
+     425           0 :   for(unsigned i=0; i<bias_.size(); ++i) {
+     426             :     // convert i to string
+     427           0 :     std::stringstream ss;
+     428             :     ss << i;
+     429             :     // label
+     430           0 :     std::string label = "b" + ss.str();
+     431             :     // print entry
+     432           0 :     Biasfile_.printField(label, bias_[i]);
+     433           0 :   }
+     434           0 :   Biasfile_.printField();
+     435           0 : }
+     436             : 
+     437           0 : void Rescale::calculate()
+     438             : {
+     439             :   // get the current value of the selector
+     440           0 :   unsigned igamma = static_cast<unsigned>(plumed.passMap[selector_]);
+     441             : 
+     442             :   // collect data from other replicas
+     443           0 :   std::vector<double> all_args(getNumberOfArguments(), 0.0);
+     444             :   // first calculate arguments
+     445           0 :   for(unsigned i=0; i<all_args.size(); ++i) {
+     446           0 :     double arg = getArgument(i);
+     447             :     // sum shared arguments across replicas
+     448           0 :     if(shared_[i]==1) {
+     449           0 :       if(comm.Get_rank()==0) multi_sim_comm.Sum(arg);
+     450           0 :       else                   arg = 0.0;
+     451           0 :       if(comm.Get_size()>1)  comm.Sum(arg);
+     452             :     }
+     453             :     // put into all_args
+     454           0 :     all_args[i] = arg;
+     455             :   }
+     456             : 
+     457             :   // now separate terms that should be rescaled
+     458             :   std::vector<double> args;
+     459           0 :   if(getNumberOfArguments()-nores_>0) args.resize(getNumberOfArguments()-nores_);
+     460           0 :   for(unsigned i=0; i<args.size(); ++i)  args[i]  = all_args[i];
+     461             :   // and terms that should not
+     462             :   std::vector<double> bargs;
+     463           0 :   if(nores_>0) bargs.resize(nores_);
+     464           0 :   for(unsigned i=0; i<bargs.size(); ++i) bargs[i] = all_args[i+args.size()];
+     465             : 
+     466             :   // calculate energy and forces, only on rescaled terms
+     467             :   double ene = 0.0;
+     468           0 :   for(unsigned i=0; i<args.size(); ++i) {
+     469             :     // calculate energy term
+     470           0 :     double fact = 1.0/pow(gamma_[igamma], expo_[i]) - 1.0;
+     471           0 :     ene += args[i] * fact;
+     472             :     // add force
+     473           0 :     setOutputForce(i, -fact);
+     474             :   }
+     475             : 
+     476             :   // set to zero on the others
+     477           0 :   for(unsigned i=0; i<bargs.size(); ++i) setOutputForce(i+args.size(), 0.0);
+     478             : 
+     479             :   // set value of the bias
+     480           0 :   setBias(ene);
+     481             :   // set value of the wt-bias
+     482           0 :   getPntrToComponent("wtbias")->set(bias_[igamma]);
+     483             :   // set values of gamma
+     484           0 :   getPntrToComponent("igamma")->set(igamma);
+     485             :   // get time step
+     486           0 :   long long int step = getStep();
+     487           0 :   if(MCfirst_==-1) MCfirst_=step;
+     488             :   // calculate gamma acceptance
+     489           0 :   double MCtrials = std::floor(static_cast<double>(step-MCfirst_) / static_cast<double>(MCstride_))+1.0;
+     490           0 :   double accgamma = static_cast<double>(MCaccgamma_) / static_cast<double>(MCsteps_) / MCtrials;
+     491           0 :   getPntrToComponent("accgamma")->set(accgamma);
+     492             : 
+     493             :   // do MC at the right time step
+     494           0 :   if(step%MCstride_==0&&!getExchangeStep()) doMonteCarlo(igamma, ene, args, bargs);
+     495             : 
+     496             :   // add well-tempered like bias
+     497           0 :   if(step%Biaspace_==0) {
+     498             :     // get updated igamma
+     499           0 :     unsigned igamma = static_cast<unsigned>(plumed.passMap[selector_]);
+     500             :     // add "Gaussian"
+     501           0 :     double kbDT = kbt_ * ( biasf_ - 1.0 );
+     502           0 :     bias_[igamma] += w0_ * std::exp(-bias_[igamma] / kbDT);
+     503             :   }
+     504             : 
+     505             :   // print bias
+     506           0 :   if(step%Biasstride_==0) print_bias(step);
+     507             : 
+     508           0 : }
+     509             : 
+     510             : 
+     511             : }
+     512             : }
+     513             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/SAXS.cpp.func-sort-c.html b/coverage/isdb/SAXS.cpp.func-sort-c.html new file mode 100644 index 000000000000..b27b4d0836b7 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.func-sort-c.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage - isdb/SAXS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - SAXS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4919615479.9 %
Date:2024-02-22 21:58:45Functions:212391.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4SAXS13calculate_gpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_0
_ZN4PLMD4isdb4SAXSC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb4SAXS16calculateAFFsansERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd2
_ZN4PLMD4isdb4SAXS12calculateAFFERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd4
_ZN4PLMD4isdb4SAXS19resolution_functionEv4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansDERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansHERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_4
_ZN4PLMD4isdb4SAXS15getOnebeadparamERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_RKS5_IjSaIjEE6
_ZN4PLMD4isdb4SAXS14sasa_calculateERSt6vectorIbSaIbEE8
_ZN4PLMD4isdb4SAXS17getMartiniFFparamERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EE8
_ZN4PLMD4isdb4SAXS9calcNlistERSt6vectorIS2_IiSaIiEESaIS4_EE8
_ZN4PLMD4isdb4SAXS13readLCPOparamERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EEj10
_ZN4PLMD4isdb4SAXS14setupLCPOparamB5cxx11Ev10
_ZN4PLMD4isdb4SAXS17getOnebeadMappingERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EE10
_ZN4PLMD4isdb4SAXSC1ERKNS_13ActionOptionsE32
_ZN4PLMD4isdb4SAXS16registerKeywordsERNS_8KeywordsE36
_ZN4PLMD4isdb4SAXS13calculate_cpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_192
_ZN4PLMD4isdb4SAXS6updateEv192
_ZN4PLMD4isdb4SAXS9calculateEv192
_ZN4PLMD4isdb4SAXS3i0eEd660
_ZN4PLMD4isdb4SAXS6chbevlEdRKSt6vectorIdSaIdEE660
_ZN4PLMD4isdb4SAXS13spline_coeffsERSt6vectorIdSaIdEES5_814
_ZN4PLMD4isdb4SAXS13interpolationERSt6vectorINS1_12SplineCoeffsESaIS3_EEd134310
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/SAXS.cpp.func.html b/coverage/isdb/SAXS.cpp.func.html new file mode 100644 index 000000000000..c615e3bd1641 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.func.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage - isdb/SAXS.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - SAXS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4919615479.9 %
Date:2024-02-22 21:58:45Functions:212391.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb4SAXS12calculateAFFERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd4
_ZN4PLMD4isdb4SAXS13calculate_cpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_192
_ZN4PLMD4isdb4SAXS13calculate_gpuERSt6vectorINS_13VectorGenericILj3EEESaIS4_EES7_0
_ZN4PLMD4isdb4SAXS13interpolationERSt6vectorINS1_12SplineCoeffsESaIS3_EEd134310
_ZN4PLMD4isdb4SAXS13readLCPOparamERKSt6vectorIS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EESaISA_EEj10
_ZN4PLMD4isdb4SAXS13spline_coeffsERSt6vectorIdSaIdEES5_814
_ZN4PLMD4isdb4SAXS14sasa_calculateERSt6vectorIbSaIbEE8
_ZN4PLMD4isdb4SAXS14setupLCPOparamB5cxx11Ev10
_ZN4PLMD4isdb4SAXS15getOnebeadparamERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_RKS5_IjSaIjEE6
_ZN4PLMD4isdb4SAXS16calculateAFFsansERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EEd2
_ZN4PLMD4isdb4SAXS16registerKeywordsERNS_8KeywordsE36
_ZN4PLMD4isdb4SAXS17getMartiniFFparamERKSt6vectorINS_10AtomNumberESaIS3_EERS2_IS2_IeSaIeEESaIS9_EE8
_ZN4PLMD4isdb4SAXS17getOnebeadMappingERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EE10
_ZN4PLMD4isdb4SAXS19resolution_functionEv4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansDERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_4
_ZN4PLMD4isdb4SAXS21getOnebeadparam_sansHERKNS_3PDBERKSt6vectorINS_10AtomNumberESaIS6_EERS5_IS5_IeSaIeEESaISC_EESF_SF_4
_ZN4PLMD4isdb4SAXS3i0eEd660
_ZN4PLMD4isdb4SAXS6chbevlEdRKSt6vectorIdSaIdEE660
_ZN4PLMD4isdb4SAXS6updateEv192
_ZN4PLMD4isdb4SAXS9calcNlistERSt6vectorIS2_IiSaIiEESaIS4_EE8
_ZN4PLMD4isdb4SAXS9calculateEv192
_ZN4PLMD4isdb4SAXSC1ERKNS_13ActionOptionsE32
_ZN4PLMD4isdb4SAXSC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/SAXS.cpp.gcov.html b/coverage/isdb/SAXS.cpp.gcov.html new file mode 100644 index 000000000000..c0ec9ead3302 --- /dev/null +++ b/coverage/isdb/SAXS.cpp.gcov.html @@ -0,0 +1,7939 @@ + + + + + + + + LCOV - plumed test coverage - isdb/SAXS.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - SAXS.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4919615479.9 %
Date:2024-02-22 21:58:45Functions:212391.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : /*
+      23             :  This class was originally written by Alexander Jussupow
+      24             :  Arrayfire implementation by Alexander Jussupow and CC
+      25             :  Extension for the middleman algorithm (now removed) by Max Muehlbauer
+      26             :  Refactoring for hySAXS Martini form factors for Nucleic Acids by Cristina Paissoni
+      27             :  Refactoring for hySAS OneBead form factors with solvent correction by Federico Ballabio and Riccardo Capelli
+      28             :  Resolution function by Henrique Musseli Cezar
+      29             : */
+      30             : 
+      31             : #include "MetainferenceBase.h"
+      32             : #include "core/ActionRegister.h"
+      33             : #include "core/ActionSet.h"
+      34             : #include "core/GenericMolInfo.h"
+      35             : #include "tools/MolDataClass.h"
+      36             : #include "tools/Communicator.h"
+      37             : #include "tools/Pbc.h"
+      38             : #include "tools/PDB.h"
+      39             : #include "tools/Tools.h"
+      40             : #include "tools/IFile.h"
+      41             : 
+      42             : #include <map>
+      43             : #include <iterator>
+      44             : #include <iostream>
+      45             : #include <algorithm>
+      46             : #include <cctype>
+      47             : 
+      48             : #ifdef __PLUMED_HAS_ARRAYFIRE
+      49             : #include <arrayfire.h>
+      50             : #include <af/util.h>
+      51             : #ifdef __PLUMED_HAS_ARRAYFIRE_CUDA
+      52             : #include <cuda_runtime.h>
+      53             : #include <cublas_v2.h>
+      54             : #include <af/cuda.h>
+      55             : #elif __PLUMED_HAS_ARRAYFIRE_OCL
+      56             : #include <af/opencl.h>
+      57             : #endif
+      58             : #endif
+      59             : 
+      60             : #ifndef M_PI
+      61             : #define M_PI           3.14159265358979323846
+      62             : #endif
+      63             : 
+      64             : namespace PLMD {
+      65             : namespace isdb {
+      66             : 
+      67             : //+PLUMEDOC ISDB_COLVAR SAXS
+      68             : /*
+      69             : Calculates SAXS intensity.
+      70             : 
+      71             : SAXS intensities are calculated for a set of scattering vectors using QVALUE keywords numbered from 1.
+      72             : Form factors can be assigned either by polynomial expansion of any order by using the PARAMETERS keywords, or
+      73             : automatically matched to atoms using the ATOMISTIC flag by reading a PDB file. Alternatively to the atomistic
+      74             : representation, two types of coarse-grained mapping are available:
+      75             : - MARTINI.
+      76             : - ONEBEAD.
+      77             : 
+      78             : Whether for PARAMETERS, ATOMISTIC, and ONEBEAD the user must provide an all-atom PDB file via MOLINFO before the
+      79             : SAXS instruction. MARTINI requires a mapping scheme consisting of a PDB file that contains both the all-atom
+      80             : and MARTINI representations, and a bead position file (e.g., bead1: CENTER ATOMS=1,5,7,11,12 WEIGHTS=14,12,12,
+      81             : 12,16).
+      82             : 
+      83             : ONEBEAD scheme consists in a single-bead per amino acid residue or three-bead for nucleic acid residue (one for
+      84             : the phosphate group, one for the pentose sugar, one for the nucleobase). PLUMED creates a virtual bead on which
+      85             : the SAXS calculations are performed, centred on the COM of all atoms belonging to the bead. It is possible to
+      86             : account for the contribution of the solvation layer to the SAXS intensity by adding a correction term for the
+      87             : solvent accessible beads only: the form factors of the amino acids / phosphate groups / pentose sugars /
+      88             : nucleobases with a SASA (computed via LCPO algorithm) greater than a threshold are corrected according to an
+      89             : electron density term. Both the surface cut-off threshold and the electron density term can be set by the user
+      90             : with the SASA_CUTOFF and SOLVATION_CORRECTION keywords. Moreover, SASA stride calculation can be modified using
+      91             : SOLVATION_STRIDE, which is set to 10 steps by default.
+      92             : ONEBEAD requires an additional PDB file to perform mapping conversion, which must be provided via TEMPLATE
+      93             : keyword. This PDB file should only include the atoms for which the SAXS intensity will be computed.
+      94             : The AMBER OL3 (RNA) and OL15 (DNA) naming is required for nucleic acids.
+      95             : Two additional bead types are available for DNA and RNA besides phosphate group, pentose sugar, and nucleobase:
+      96             : - 5'-end pentose sugar capped with an hydroxyl moiety at C5' (the residue name in the PDB must be followed by
+      97             : "5", e.g., DC5 or C5 for cytosine in DNA and RNA, respectively);
+      98             : - 3'-end pentose sugar capped with an hydroxyl moiety at C3' (the residue name in the PDB must be followed by
+      99             : "3", e.g., DC3 or C3 for cytosine in DNA and RNA, respectively).
+     100             : 
+     101             : Experimental reference intensities can be added using the EXPINT keywords. All these values must be normalised
+     102             : to the SAXS intensity at q = 0. To facilitate this operation, the SCALE_EXPINT keyword can be used to provide
+     103             : the intensity at q = 0. Each EXPINT is divided by SCALE_EXPINT.
+     104             : The maximum QVALUE for ONEBEAD is set to 0.3 inverse angstroms.
+     105             : The solvent density, that by default is set to 0.334 electrons per cubic angstrom (bulk water), can be modified
+     106             : using the SOLVDENS keyword.
+     107             : 
+     108             : The ABSOLUTE flag can be used in order to calculate intensities in the absolute scale. It is only available for
+     109             : the ATOMISTIC scheme and cannot be used with SCALE_EXPINT.
+     110             : 
+     111             : By default SAXS is calculated using Debye on CPU, by adding the GPU flag it is possible to solve the equation on
+     112             : a GPU if the ARRAYFIRE libraries are installed and correctly linked.
+     113             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+     114             : 
+     115             : \par Examples
+     116             : in the following example the SAXS intensities are calculated using single-bead per residue approximation, with a
+     117             : SASA threshold of 1 square nanometer and a solvation term of 0.04. Each experimental intensity is divided by
+     118             : 1.4002, which is the corresponding theoretical intensity value at q = 0. The form factors are selected according
+     119             : to the PDB file specified by TEMPLATE keyword.
+     120             : 
+     121             : \plumedfile
+     122             : MOLINFO STRUCTURE=template_AA.pdb
+     123             : 
+     124             : SAXS ...
+     125             : LABEL=SAXS
+     126             : ATOMS=1-355
+     127             : ONEBEAD
+     128             : TEMPLATE=template_AA.pdb
+     129             : SOLVDENS=0.334
+     130             : SOLVATION_CORRECTION=0.04
+     131             : SOLVATION_STRIDE=1
+     132             : SASA_CUTOFF=1.0
+     133             : SCALE_EXPINT=1.4002
+     134             : QVALUE1=0.03 EXPINT1=1.0902
+     135             : QVALUE2=0.06 EXPINT2=0.790632
+     136             : QVALUE3=0.09 EXPINT3=0.453808
+     137             : QVALUE4=0.12 EXPINT4=0.254737
+     138             : QVALUE5=0.15 EXPINT5=0.154928
+     139             : QVALUE6=0.18 EXPINT6=0.0921503
+     140             : QVALUE7=0.21 EXPINT7=0.052633
+     141             : QVALUE8=0.24 EXPINT8=0.0276557
+     142             : QVALUE9=0.27 EXPINT9=0.0122775
+     143             : QVALUE10=0.30 EXPINT10=0.00880634
+     144             : ... SAXS
+     145             : 
+     146             : PRINT ARG=(SAXS\.q-.*),(SAXS\.exp-.*) FILE=saxsdata STRIDE=1
+     147             : 
+     148             : \endplumedfile
+     149             : 
+     150             : */
+     151             : //+ENDPLUMEDOC
+     152             : 
+     153             : //+PLUMEDOC ISDB_COLVAR SANS
+     154             : /*
+     155             : Calculates SANS intensity.
+     156             : 
+     157             : SANS intensities are calculated for a set of scattering vectors using QVALUE keywords numbered from 1.
+     158             : Form factors are automatically assigned to atoms using the ATOMISTIC flag by reading a PDB file, by reading
+     159             : the scattering lengths with the PARAMETERS keyword from input or with the PARAMETERSFILE keyword or, alternatively,
+     160             : a ONEBEAD coarse-grained implementation is available.
+     161             : 
+     162             : Both for ATOMISTIC and ONEBEAD the user must provide an all-atom PDB file via MOLINFO before the SANS instruction.
+     163             : 
+     164             : ONEBEAD scheme consists in a single-bead per amino acid residue or three-bead for nucleic acid residue (one for
+     165             : the phosphate group, one for the pentose sugar, one for the nucleobase). PLUMED creates a virtual bead on which
+     166             : the SANS calculations are performed, centred on the COM of all atoms belonging to the bead. It is possible to
+     167             : account for the contribution of the solvation layer to the SAXS intensity by adding a correction term for the
+     168             : solvent accessible beads only: the form factors of the amino acids / phosphate groups / pentose sugars /
+     169             : nucleobases with a SASA (computed via LCPO algorithm) greater than a threshold are corrected according to an
+     170             : electron density term. Both the surface cut-off threshold and the electron density term can be set by the user
+     171             : with the SASA_CUTOFF and SOLVATION_CORRECTION keywords. Moreover, SASA stride calculation can be modified using
+     172             : SOLVATION_STRIDE, which is set to 10 steps by default. The deuteration of the solvent-exposed residues is chosen
+     173             : with a probability equal to the deuterium concentration in the buffer. The deuterated residues are updated with a
+     174             : stride equal to SOLVATION_STRIDE. The fraction of deuterated water can be set with DEUTER_CONC, the default value
+     175             : is 0.
+     176             : ONEBEAD requires an additional PDB file to perform mapping conversion, which must be provided via TEMPLATE
+     177             : keyword. This PDB file should only include the atoms for which the SANS intensity will be computed.
+     178             : The AMBER OL3 (RNA) and OL15 (DNA) naming is required for nucleic acids.
+     179             : Two additional bead types are available for DNA and RNA besides phosphate group, pentose sugar, and nucleobase:
+     180             : - 5'-end pentose sugar capped with an hydroxyl moiety at C5' (the residue name in the PDB must be followed by "5",
+     181             : e.g., DC5 or C5 for cytosine in DNA and RNA, respectively);
+     182             : - 3'-end pentose sugar capped with an hydroxyl moiety at C3' (the residue name in the PDB must be followed by "3",
+     183             : e.g., DC3 or C3 for cytosine in DNA and RNA, respectively).
+     184             : 
+     185             : PLEASE NOTE: at the moment, we DO NOT explicitly take into account deuterated residues in the ATOMISTIC
+     186             : representation, but we correct the solvent contribution via the DEUTER_CONC keyword.
+     187             : 
+     188             : Experimental reference intensities can be added using the EXPINT keywords. All these values must be normalised
+     189             : to the SANS intensity at q = 0. To facilitate this operation, the SCALE_EXPINT keyword can be used to provide
+     190             : the intensity at q = 0. Each EXPINT is divided by SCALE_EXPINT.
+     191             : The maximum QVALUE for ONEBEAD is set to 0.3 inverse angstroms.
+     192             : The solvent density, that by default is set to 0.334 electrons per cubic angstrom (bulk water), can be modified
+     193             : using the SOLVDENS keyword.
+     194             : 
+     195             : The ABSOLUTE flag can be used in order to calculate intensities in the absolute scale. It is only available for
+     196             : the ATOMISTIC scheme and cannot be used with SCALE_EXPINT.
+     197             : 
+     198             : By default SANS is calculated using Debye on CPU, by adding the GPU flag it is possible to solve the equation on a
+     199             : GPU if the ARRAYFIRE libraries are installed and correctly linked.
+     200             : \ref METAINFERENCE can be activated using DOSCORE and the other relevant keywords.
+     201             : 
+     202             : \par Examples
+     203             : in the following example the SANS intensities are calculated at atomistic resolution. The form factors are assigned
+     204             : according to the PDB file specified in the MOLINFO. Each experimental intensity is divided by 1.4002, which is the
+     205             : corresponding theoretical intensity value at q = 0. The deuterated water fraction is set to 48%.
+     206             : 
+     207             : \plumedfile
+     208             : MOLINFO STRUCTURE=template_AA.pdb
+     209             : 
+     210             : SANS ...
+     211             : LABEL=SANS
+     212             : ATOMS=1-355
+     213             : ATOMISTIC
+     214             : SCALE_EXPINT=1.4002
+     215             : DEUTER_CONC=0.48
+     216             : QVALUE1=0.03 EXPINT1=1.0902
+     217             : QVALUE2=0.06 EXPINT2=0.790632
+     218             : QVALUE3=0.09 EXPINT3=0.453808
+     219             : QVALUE4=0.12 EXPINT4=0.254737
+     220             : QVALUE5=0.15 EXPINT5=0.154928
+     221             : QVALUE6=0.18 EXPINT6=0.0921503
+     222             : QVALUE7=0.21 EXPINT7=0.052633
+     223             : QVALUE8=0.24 EXPINT8=0.0276557
+     224             : QVALUE9=0.27 EXPINT9=0.0122775
+     225             : QVALUE10=0.30 EXPINT10=0.00880634
+     226             : ... SANS
+     227             : 
+     228             : PRINT ARG=(SANS\.q-.*),(SANS\.exp-.*) FILE=sansdata STRIDE=1
+     229             : 
+     230             : \endplumedfile
+     231             : 
+     232             : */
+     233             : //+ENDPLUMEDOC
+     234             : 
+     235             : class SAXS :
+     236             :   public MetainferenceBase
+     237             : {
+     238             : private:
+     239             :   enum { H, C, N, O, P, S, NTT };
+     240             :   enum { ALA_BB, ARG_BB, ARG_SC1, ARG_SC2, ASN_BB, ASN_SC1, ASP_BB, ASP_SC1, CYS_BB, CYS_SC1,
+     241             :          GLN_BB, GLN_SC1, GLU_BB, GLU_SC1, GLY_BB, HIS_BB, HIS_SC1, HIS_SC2, HIS_SC3, ILE_BB,
+     242             :          ILE_SC1, LEU_BB, LEU_SC1, LYS_BB, LYS_SC1, LYS_SC2, MET_BB, MET_SC1, PHE_BB, PHE_SC1,
+     243             :          PHE_SC2, PHE_SC3, PRO_BB, PRO_SC1, SER_BB, SER_SC1, THR_BB, THR_SC1, TRP_BB, TRP_SC1,
+     244             :          TRP_SC2, TRP_SC3, TRP_SC4, TYR_BB, TYR_SC1, TYR_SC2, TYR_SC3, VAL_BB, VAL_SC1, A_BB1,
+     245             :          A_BB2, A_BB3, A_SC1, A_SC2, A_SC3, A_SC4, A_3TE, A_5TE, A_TE3, A_TE5, C_BB1, C_BB2,
+     246             :          C_BB3, C_SC1, C_SC2, C_SC3, C_3TE, C_5TE, C_TE3, C_TE5, G_BB1, G_BB2, G_BB3, G_SC1,
+     247             :          G_SC2, G_SC3, G_SC4, G_3TE, G_5TE, G_TE3, G_TE5, U_BB1, U_BB2, U_BB3, U_SC1, U_SC2,
+     248             :          U_SC3, U_3TE, U_5TE, U_TE3, U_TE5, DA_BB1, DA_BB2, DA_BB3, DA_SC1, DA_SC2, DA_SC3,
+     249             :          DA_SC4, DA_3TE, DA_5TE, DA_TE3, DA_TE5, DC_BB1, DC_BB2, DC_BB3, DC_SC1, DC_SC2, DC_SC3,
+     250             :          DC_3TE, DC_5TE, DC_TE3, DC_TE5, DG_BB1, DG_BB2, DG_BB3, DG_SC1, DG_SC2, DG_SC3, DG_SC4,
+     251             :          DG_3TE, DG_5TE, DG_TE3, DG_TE5, DT_BB1, DT_BB2, DT_BB3, DT_SC1, DT_SC2, DT_SC3, DT_3TE,
+     252             :          DT_5TE, DT_TE3, DT_TE5, NMARTINI
+     253             :        };
+     254             :   enum { TRP, TYR, PHE, HIS, HIP, ARG, LYS, CYS, ASP, GLU, ILE, LEU, MET, ASN, PRO, GLN, SER, THR, VAL, ALA, GLY,
+     255             :          BASE_A, BASE_C, BASE_T, BASE_G, BASE_U,
+     256             :          BB_DNA, BB_DNA_5, BB_DNA_3,
+     257             :          BB_RNA, BB_RNA_5, BB_RNA_3,
+     258             :          BB_PO2,
+     259             :          NONEBEAD
+     260             :        };
+     261             :   struct SplineCoeffs {
+     262             :     double a;
+     263             :     double b;
+     264             :     double c;
+     265             :     double d;
+     266             :     double x;
+     267             :   };
+     268             :   bool saxs;
+     269             :   bool absolute;
+     270             :   bool pbc;
+     271             :   bool serial;
+     272             :   bool gpu;
+     273             :   bool onebead;
+     274             :   bool resolution;
+     275             :   bool isFirstStep;
+     276             :   int  deviceid;
+     277             :   unsigned nres;
+     278             :   std::vector<unsigned> atoi;
+     279             :   std::vector<unsigned> atoms_per_bead;
+     280             :   std::vector<double>   atoms_masses;
+     281             :   std::vector<double>   q_list;
+     282             :   std::vector<double>   FF_rank;
+     283             :   std::vector<std::vector<double> > FF_value_vacuum;
+     284             :   std::vector<std::vector<double> > FF_value_solv;
+     285             :   std::vector<std::vector<double> > FF_value_mixed;
+     286             :   std::vector<std::vector<double> > FF_value;
+     287             :   std::vector<std::vector<float> >  FFf_value;
+     288             :   // SANS:
+     289             :   std::vector<std::vector<double> > FF_value_vacuum_H;
+     290             :   std::vector<std::vector<double> > FF_value_solv_H;
+     291             :   std::vector<std::vector<double> > FF_value_mixed_H;
+     292             :   std::vector<std::vector<double> > FF_value_vacuum_D;
+     293             :   std::vector<std::vector<double> > FF_value_mixed_D;
+     294             : 
+     295             :   std::vector<std::vector<double> > LCPOparam;
+     296             :   std::vector<unsigned> residue_atom;
+     297             : 
+     298             :   double rho, rho_corr, sasa_cutoff;
+     299             :   double deuter_conc;
+     300             :   unsigned solv_stride;
+     301             :   std::vector<double> Iq0_vac;
+     302             :   std::vector<double> Iq0_solv;
+     303             :   std::vector<double> Iq0_mix;
+     304             :   double Iq0;
+     305             : 
+     306             :   // SANS:
+     307             :   std::vector<double> Iq0_vac_H;
+     308             :   std::vector<double> Iq0_solv_H;
+     309             :   std::vector<double> Iq0_mix_H;
+     310             :   std::vector<double> Iq0_vac_D;
+     311             :   std::vector<double> Iq0_mix_D;
+     312             :   unsigned int Nj;
+     313             :   std::vector<std::vector<double> > qj_list;
+     314             :   std::vector<std::vector<double> > Rij;
+     315             :   std::vector<double> sigma_res;
+     316             : 
+     317             :   // Chebyshev polynomial coefficients for i0e(x) used for resolution function
+     318             :   // values taken from cephes library
+     319             :   const std::vector<double> A = {
+     320             :     -4.41534164647933937950E-18,
+     321             :       3.33079451882223809783E-17,
+     322             :       -2.43127984654795469359E-16,
+     323             :       1.71539128555513303061E-15,
+     324             :       -1.16853328779934516808E-14,
+     325             :       7.67618549860493561688E-14,
+     326             :       -4.85644678311192946090E-13,
+     327             :       2.95505266312963983461E-12,
+     328             :       -1.72682629144155570723E-11,
+     329             :       9.67580903537323691224E-11,
+     330             :       -5.18979560163526290666E-10,
+     331             :       2.65982372468238665035E-9,
+     332             :       -1.30002500998624804212E-8,
+     333             :       6.04699502254191894932E-8,
+     334             :       -2.67079385394061173391E-7,
+     335             :       1.11738753912010371815E-6,
+     336             :       -4.41673835845875056359E-6,
+     337             :       1.64484480707288970893E-5,
+     338             :       -5.75419501008210370398E-5,
+     339             :       1.88502885095841655729E-4,
+     340             :       -5.76375574538582365885E-4,
+     341             :       1.63947561694133579842E-3,
+     342             :       -4.32430999505057594430E-3,
+     343             :       1.05464603945949983183E-2,
+     344             :       -2.37374148058994688156E-2,
+     345             :       4.93052842396707084878E-2,
+     346             :       -9.49010970480476444210E-2,
+     347             :       1.71620901522208775349E-1,
+     348             :       -3.04682672343198398683E-1,
+     349             :       6.76795274409476084995E-1
+     350             :     };
+     351             :   const std::vector<double> B = {
+     352             :     -7.23318048787475395456E-18,
+     353             :       -4.83050448594418207126E-18,
+     354             :       4.46562142029675999901E-17,
+     355             :       3.46122286769746109310E-17,
+     356             :       -2.82762398051658348494E-16,
+     357             :       -3.42548561967721913462E-16,
+     358             :       1.77256013305652638360E-15,
+     359             :       3.81168066935262242075E-15,
+     360             :       -9.55484669882830764870E-15,
+     361             :       -4.15056934728722208663E-14,
+     362             :       1.54008621752140982691E-14,
+     363             :       3.85277838274214270114E-13,
+     364             :       7.18012445138366623367E-13,
+     365             :       -1.79417853150680611778E-12,
+     366             :       -1.32158118404477131188E-11,
+     367             :       -3.14991652796324136454E-11,
+     368             :       1.18891471078464383424E-11,
+     369             :       4.94060238822496958910E-10,
+     370             :       3.39623202570838634515E-9,
+     371             :       2.26666899049817806459E-8,
+     372             :       2.04891858946906374183E-7,
+     373             :       2.89137052083475648297E-6,
+     374             :       6.88975834691682398426E-5,
+     375             :       3.36911647825569408990E-3,
+     376             :       8.04490411014108831608E-1
+     377             :     };
+     378             : 
+     379             :   void calculate_gpu(std::vector<Vector> &pos, std::vector<Vector> &deriv);
+     380             :   void calculate_cpu(std::vector<Vector> &pos, std::vector<Vector> &deriv);
+     381             :   void getMartiniFFparam(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter);
+     382             :   void getOnebeadparam(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac, std::vector<std::vector<long double> > &parameter_mix, std::vector<std::vector<long double> > &parameter_solv, const std::vector<unsigned> & residue_atom);
+     383             :   unsigned getOnebeadMapping(const PDB &pdb, const std::vector<AtomNumber> &atoms);
+     384             :   double calculateAFF(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double rho);
+     385             :   std::map<std::string, std::vector<double> > setupLCPOparam();
+     386             :   void readLCPOparam(const std::vector<std::vector<std::string> > &AtomResidueName, unsigned natoms);
+     387             :   void calcNlist(std::vector<std::vector<int> > &Nlist);
+     388             :   void sasa_calculate(std::vector<bool> &solv_res);
+     389             :   // SANS:
+     390             :   void getOnebeadparam_sansH(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_H, std::vector<std::vector<long double> > &parameter_mix_H, std::vector<std::vector<long double> > &parameter_solv_H);
+     391             :   void getOnebeadparam_sansD(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_D, std::vector<std::vector<long double> > &parameter_mix_D);
+     392             :   double calculateAFFsans(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double deuter_conc);
+     393             :   void resolution_function();
+     394             :   std::vector<SplineCoeffs> spline_coeffs(std::vector<double> &x, std::vector<double> &y);
+     395             :   inline double interpolation(std::vector<SplineCoeffs> &coeffs, double x);
+     396             :   inline double i0e(double x);
+     397             :   double chbevl(double x, const std::vector<double> &coeffs);
+     398             : 
+     399             : public:
+     400             :   static void registerKeywords( Keywords& keys );
+     401             :   explicit SAXS(const ActionOptions&);
+     402             :   void calculate() override;
+     403             :   void update() override;
+     404             : };
+     405             : 
+     406             : PLUMED_REGISTER_ACTION(SAXS,"SAXS")
+     407             : PLUMED_REGISTER_ACTION(SAXS,"SANS")
+     408             : 
+     409          36 : void SAXS::registerKeywords(Keywords& keys) {
+     410          36 :   componentsAreNotOptional(keys);
+     411          36 :   MetainferenceBase::registerKeywords(keys);
+     412          72 :   keys.addFlag("NOPBC",false,"Ignore the periodic boundary conditions when calculating distances");
+     413          72 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     414          72 :   keys.add("compulsory","DEVICEID","-1","Identifier of the GPU to be used");
+     415          72 :   keys.addFlag("GPU",false,"Calculate SAXS using ARRAYFIRE on an accelerator device");
+     416          72 :   keys.addFlag("ABSOLUTE",false,"Absolute intensity: the intensities for each q-value are not normalised for the intensity at q=0.");
+     417          72 :   keys.addFlag("ATOMISTIC",false,"Calculate SAXS for an atomistic model");
+     418          72 :   keys.addFlag("MARTINI",false,"Calculate SAXS for a Martini model");
+     419          72 :   keys.addFlag("ONEBEAD",false,"calculate SAXS for a single bead model");
+     420          72 :   keys.add("compulsory","TEMPLATE","template.pdb","A PDB file is required for ONEBEAD mapping");
+     421          72 :   keys.add("atoms","ATOMS","The atoms to be included in the calculation, e.g. the whole protein");
+     422          72 :   keys.add("numbered","QVALUE","Selected scattering lengths in inverse angstroms are given as QVALUE1, QVALUE2, ...");
+     423          72 :   keys.add("numbered","PARAMETERS","Used parameter Keywords like PARAMETERS1, PARAMETERS2. These are used to calculate the form factor for the \\f$i\\f$th atom/bead");
+     424          72 :   keys.add("optional","PARAMETERSFILE","Read the PARAMETERS from a file");
+     425          72 :   keys.add("compulsory","DEUTER_CONC","0.","Fraction of deuterated solvent");
+     426          72 :   keys.add("compulsory","SOLVDENS","0.334","Density of the solvent to be used for the correction of atomistic form factors");
+     427          72 :   keys.add("compulsory","SOLVATION_CORRECTION","0.0","Solvation layer electron density correction (ONEBEAD only)");
+     428          72 :   keys.add("compulsory","SASA_CUTOFF","1.0","SASA value to consider a residue as exposed to the solvent (ONEBEAD only)");
+     429          72 :   keys.add("numbered","EXPINT","Add an experimental value for each q value");
+     430          72 :   keys.add("numbered","SIGMARES","Variance of Gaussian distribution describing the deviation in the scattering angle for each q value");
+     431          72 :   keys.add("compulsory","N","10","Number of points in the resolution function integral");
+     432          72 :   keys.add("compulsory","SOLVATION_STRIDE","10","Number of steps between every new residues solvation estimation via LCPO (ONEBEAD only)");
+     433          72 :   keys.add("compulsory","SCALE_EXPINT","1.0","Scaling value for experimental data normalization");
+     434          72 :   keys.addOutputComponent("q","default","The # SAXS of q");
+     435          72 :   keys.addOutputComponent("exp","EXPINT","The # experimental intensity");
+     436          36 : }
+     437             : 
+     438          32 : SAXS::SAXS(const ActionOptions&ao):
+     439             :   PLUMED_METAINF_INIT(ao),
+     440          32 :   saxs(true),
+     441          32 :   absolute(false),
+     442          32 :   pbc(true),
+     443          32 :   serial(false),
+     444          32 :   gpu(false),
+     445          32 :   onebead(false),
+     446          32 :   isFirstStep(true),
+     447          32 :   deviceid(-1)
+     448             : {
+     449          32 :   if( getName().find("SAXS")!=std::string::npos) { saxs=true; }
+     450          10 :   else if( getName().find("SANS")!=std::string::npos) { saxs=false; }
+     451             : 
+     452             :   std::vector<AtomNumber> atoms;
+     453          64 :   parseAtomList("ATOMS",atoms);
+     454          32 :   unsigned size = atoms.size();
+     455             : 
+     456          32 :   parseFlag("SERIAL",serial);
+     457             : 
+     458          32 :   bool nopbc=!pbc;
+     459          32 :   parseFlag("NOPBC",nopbc);
+     460          32 :   pbc=!nopbc;
+     461          32 :   if(pbc)      log.printf("  using periodic boundary conditions\n");
+     462          16 :   else         log.printf("  without periodic boundary conditions\n");
+     463             : 
+     464          32 :   parseFlag("GPU",gpu);
+     465             : #ifndef  __PLUMED_HAS_ARRAYFIRE
+     466          32 :   if(gpu) error("To use the GPU mode PLUMED must be compiled with ARRAYFIRE");
+     467             : #endif
+     468             : 
+     469          32 :   parse("DEVICEID",deviceid);
+     470             : #ifdef  __PLUMED_HAS_ARRAYFIRE
+     471             :   if(gpu&&comm.Get_rank()==0) {
+     472             :     // if not set try to check the one set by the API
+     473             :     if(deviceid==-1) deviceid=plumed.getGpuDeviceId();
+     474             :     // if still not set use 0
+     475             :     if(deviceid==-1) deviceid=0;
+     476             : #ifdef  __PLUMED_HAS_ARRAYFIRE_CUDA
+     477             :     af::setDevice(afcu::getNativeId(deviceid));
+     478             : #elif   __PLUMED_HAS_ARRAYFIRE_OCL
+     479             :     af::setDevice(afcl::getNativeId(deviceid));
+     480             : #else
+     481             :     af::setDevice(deviceid);
+     482             : #endif
+     483             :     af::info();
+     484             :   }
+     485             : #endif
+     486             : 
+     487          32 :   bool atomistic=false;
+     488          32 :   parseFlag("ATOMISTIC",atomistic);
+     489          32 :   if(atomistic) log.printf("  using ATOMISTIC form factors\n");
+     490          32 :   bool martini=false;
+     491          32 :   parseFlag("MARTINI",martini);
+     492          32 :   if(martini) log.printf("  using MARTINI form factors\n");
+     493          32 :   onebead=false;
+     494          32 :   parseFlag("ONEBEAD",onebead);
+     495          32 :   if(onebead) log.printf("  using ONEBEAD form factors\n");
+     496             :   bool fromfile=false;
+     497             :   std::string parametersfile;
+     498          64 :   parse("PARAMETERSFILE",parametersfile);
+     499          32 :   if (parametersfile.length() != 0) fromfile=true;
+     500           4 :   if(fromfile) log.printf("  will read form factors from file\n");
+     501          32 :   parseFlag("ABSOLUTE",absolute);
+     502             : 
+     503          32 :   if(martini&&atomistic) error("You cannot use MARTINI and ATOMISTIC at the same time");
+     504          32 :   if(martini&&onebead) error("You cannot use MARTINI and ONEBEAD at the same time");
+     505          32 :   if(onebead&&atomistic) error("You cannot use ONEBEAD and ATOMISTIC at the same time");
+     506          32 :   if((martini)&&(!saxs)) error("MARTINI cannot be used with SANS");
+     507          32 :   if((fromfile)&&((atomistic)||(martini)||(onebead))) {
+     508           0 :     error("You cannot read parameters from file and use ATOMISTIC/MARTINI/ONEBEAD");
+     509             :   }
+     510             : 
+     511             :   unsigned ntarget=0;
+     512             :   for(unsigned i=0;; ++i) {
+     513             :     double t_list;
+     514         736 :     if( !parseNumbered( "QVALUE", i+1, t_list) ) break;
+     515         336 :     if(t_list<=0.) error("QVALUE cannot be less or equal to zero!\n");
+     516         336 :     if(onebead&&t_list>0.3) error("ONEBEAD mapping QVALUE must be smaller or equal to 0.3");
+     517         336 :     q_list.push_back(t_list);
+     518         336 :     ntarget++;
+     519         336 :   }
+     520             :   const unsigned numq = ntarget;
+     521             : 
+     522         368 :   for(unsigned i=0; i<numq; ++i) {
+     523         336 :     if(q_list[i]==0.) error("it is not possible to set q=0\n");
+     524         336 :     if(i>0&&q_list[i]<q_list[i-1]) error("QVALUE must be in ascending order");
+     525         336 :     log.printf("  my q: %lf \n",q_list[i]);
+     526             :   }
+     527             : 
+     528          32 :   rho = 0.334;
+     529          32 :   parse("SOLVDENS", rho);
+     530          32 :   log.printf("  Solvent density: %lf\n", rho);
+     531             : 
+     532          32 :   double scale_expint=1.;
+     533          32 :   parse("SCALE_EXPINT",scale_expint);
+     534             : 
+     535          32 :   if((!atomistic&&absolute)||(absolute&&scale_expint!=1)) error("ABSOLUTE can be used only combined with ATOMISTIC without SCALE_EXPINT");
+     536          38 :   if(atomistic) log.printf("  Scale for intensities: %s\n", absolute ? "absolute" : "normalised");
+     537             : 
+     538          32 :   double correction = 0.00;
+     539          32 :   parse("SOLVATION_CORRECTION", correction);
+     540          32 :   rho_corr=rho-correction;
+     541          32 :   if(onebead) log.printf("  Solvation density contribution: %lf\n", correction);
+     542          32 :   if((atomistic||martini||fromfile)&&(rho_corr!=rho)) log.printf("  Solvation density contribution is taken into account in ONEBEAD only\n");
+     543             : 
+     544          32 :   solv_stride = 10;
+     545          32 :   parse("SOLVATION_STRIDE", solv_stride);
+     546          32 :   if(solv_stride < 1.) error("SOLVATION_STRIDE must be greater than 0");
+     547          32 :   if(onebead&&(rho_corr!=rho)) log.printf("  SASA calculation stride: %u\n", solv_stride);
+     548             : 
+     549          32 :   sasa_cutoff = 1.0;
+     550          32 :   parse("SASA_CUTOFF", sasa_cutoff);
+     551          32 :   if(sasa_cutoff <= 0.) error("SASA_CUTOFF must be greater than 0");
+     552             : 
+     553          32 :   deuter_conc = 0.;
+     554          32 :   parse("DEUTER_CONC", deuter_conc);
+     555          32 :   if ((deuter_conc)&&(fromfile)) error("DEUTER_CONC cannot be used with PARAMETERSFILE");
+     556          32 :   if(deuter_conc < 0. || deuter_conc > 1.) error("DEUTER_CONC must be in 0-1 range");
+     557          32 :   if ((atomistic||onebead)&&(!saxs)) log.printf("  Solvent deuterium fraction: %lf/1.000000\n", deuter_conc);
+     558             : 
+     559          32 :   PDB pdb;
+     560          32 :   if(onebead) {
+     561             :     std::string template_name;
+     562          10 :     parse("TEMPLATE",template_name);
+     563          10 :     log.printf("  Template for ONEBEAD mapping conversion: %s\n", template_name.c_str());
+     564          10 :     if( !pdb.read(template_name,usingNaturalUnits(),1.) ) plumed_merror("missing input file " + template_name);
+     565             :   }
+     566             : 
+     567             :   // preliminary mapping for onebead representation
+     568          32 :   if(onebead) {
+     569          10 :     LCPOparam.resize(size);
+     570          10 :     nres = getOnebeadMapping(pdb, atoms);
+     571          10 :     if(saxs) {
+     572           6 :       Iq0_vac.resize(nres);
+     573           6 :       Iq0_solv.resize(nres);
+     574           6 :       Iq0_mix.resize(nres);
+     575             :     } else { // SANS
+     576           4 :       Iq0_vac_H.resize(nres);
+     577           4 :       Iq0_solv_H.resize(nres);
+     578           4 :       Iq0_mix_H.resize(nres);
+     579           4 :       Iq0_vac_D.resize(nres);
+     580           4 :       Iq0_mix_D.resize(nres);
+     581             :     }
+     582          10 :     atoi.resize(nres);
+     583             :   } else {
+     584          22 :     atoi.resize(size);
+     585             :   }
+     586             : 
+     587          32 :   Iq0=0;
+     588             :   std::vector<std::vector<long double> > FF_tmp;
+     589             :   std::vector<std::vector<long double> > FF_tmp_vac;
+     590             :   std::vector<std::vector<long double> > FF_tmp_mix;
+     591             :   std::vector<std::vector<long double> > FF_tmp_solv;
+     592             :   // SANS
+     593             :   std::vector<std::vector<long double> > FF_tmp_vac_H;
+     594             :   std::vector<std::vector<long double> > FF_tmp_mix_H;
+     595             :   std::vector<std::vector<long double> > FF_tmp_solv_H;
+     596             :   std::vector<std::vector<long double> > FF_tmp_vac_D;
+     597             :   std::vector<std::vector<long double> > FF_tmp_mix_D;
+     598             :   std::vector<std::vector<long double> > parameter_H;
+     599             :   std::vector<std::vector<long double> > parameter_D;
+     600             : 
+     601          32 :   if(!atomistic&&!martini&&!onebead&&!fromfile) { // read PARAMETERS from PLUMED file
+     602           4 :     if (saxs) {
+     603             :       // read in parameter std::vector
+     604             :       std::vector<std::vector<long double> > parameter;
+     605           4 :       parameter.resize(size);
+     606             :       ntarget=0;
+     607          36 :       for(unsigned i=0; i<size; ++i) {
+     608          64 :         if( !parseNumberedVector( "PARAMETERS", i+1, parameter[i]) ) break;
+     609          32 :         ntarget++;
+     610             :       }
+     611           4 :       if( ntarget!=size ) error("found wrong number of parameter std::vectors");
+     612           4 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     613          36 :       for(unsigned i=0; i<size; ++i) {
+     614          32 :         atoi[i]=i;
+     615         128 :         for(unsigned k=0; k<numq; ++k) {
+     616         480 :           for(unsigned j=0; j<parameter[i].size(); ++j) {
+     617         384 :             FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     618             :           }
+     619             :         }
+     620             :       }
+     621          36 :       for(unsigned i=0; i<size; ++i) Iq0+=parameter[i][0];
+     622           4 :       Iq0 *= Iq0;
+     623           4 :     }
+     624             :     else { // SANS
+     625             :       std::vector<long double> parameter;
+     626           0 :       parameter.resize(size);
+     627             :       ntarget=0;
+     628           0 :       for(unsigned i=0; i<size; ++i) {
+     629           0 :         if( !parseNumbered( "PARAMETERS", i+1, parameter[i]) ) break;
+     630           0 :         ntarget++;
+     631             :       }
+     632           0 :       if( ntarget!=size ) error("found wrong number of parameter std::vectors");
+     633           0 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     634           0 :       for(unsigned i=0; i<size; ++i) {
+     635           0 :         atoi[i]=i;
+     636           0 :         for(unsigned k=0; k<numq; ++k) {
+     637           0 :           FF_tmp[k][i]+= parameter[i];
+     638             :         }
+     639             :       }
+     640           0 :       for(unsigned i=0; i<size; ++i) Iq0+=parameter[i];
+     641           0 :       Iq0 *= Iq0;
+     642             :     }
+     643          28 :   } else if (fromfile) { // read PARAMETERS from user-provided file
+     644           4 :     log.printf("  Reading PARAMETERS from file: %s\n", parametersfile.c_str());
+     645           4 :     if (saxs) {
+     646           0 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     647             :       std::vector<std::vector<long double> > parameter;
+     648           0 :       parameter.resize(size);
+     649             : 
+     650           0 :       IFile ifile;
+     651           0 :       ifile.open(parametersfile);
+     652             :       std::string line;
+     653             : 
+     654             :       ntarget=0;
+     655           0 :       while(ifile.getline(line)) {
+     656           0 :         Tools::ltrim(line);
+     657           0 :         Tools::trimComments(line);
+     658           0 :         if (line.empty()) continue;
+     659           0 :         if (ntarget > size) error("PARAMETERSFILE has more PARAMETERS than there are scattering centers");
+     660           0 :         std::string num; Tools::convert(ntarget+1,num);
+     661           0 :         std::vector<std::string> lineread{line};
+     662           0 :         if (!Tools::parseVector(lineread, "PARAMETERS"+num, parameter[ntarget], -1)) error("Missing PARAMETERS or PARAMETERS not sorted");
+     663             :         ntarget++;
+     664           0 :       }
+     665           0 :       if( ntarget!=size ) error("found wrong number of PARAMETERS in file");
+     666             : 
+     667           0 :       for(unsigned i=0; i<size; ++i) {
+     668           0 :         atoi[i]=i;
+     669           0 :         for(unsigned k=0; k<numq; ++k) {
+     670           0 :           for(unsigned j=0; j<parameter[i].size(); ++j) {
+     671           0 :             FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     672             :           }
+     673             :         }
+     674             :       }
+     675           0 :       for(unsigned i=0; i<size; ++i) Iq0+=parameter[i][0];
+     676           0 :       Iq0 *= Iq0;
+     677           0 :     } else { // SANS
+     678           4 :       FF_tmp.resize(numq,std::vector<long double>(size));
+     679             : 
+     680           4 :       IFile ifile;
+     681           4 :       ifile.open(parametersfile);
+     682             :       std::string line;
+     683             : 
+     684             :       ntarget=0;
+     685        1084 :       while(ifile.getline(line)) {
+     686        1080 :         Tools::ltrim(line);
+     687        1080 :         Tools::trimComments(line);
+     688        1080 :         if (line.empty()) continue;
+     689        1080 :         if (ntarget > size) error("PARAMETERSFILE has more PARAMETERS than there are scattering centers");
+     690        1080 :         std::string num; Tools::convert(ntarget+1,num);
+     691        2160 :         std::vector<std::string> lineread{line};
+     692             :         long double scatlen;
+     693        1080 :         atoi[ntarget]=ntarget;
+     694        2160 :         if (!Tools::parse(lineread, "PARAMETERS"+num, scatlen, -1)) error("Missing PARAMETERS or PARAMETERS not sorted");
+     695       17280 :         for(unsigned k=0; k<numq; ++k) {
+     696       16200 :           FF_tmp[k][ntarget] = scatlen;
+     697             :         }
+     698             :         ntarget++;
+     699        1080 :       }
+     700           4 :       if( ntarget!=size ) error("found wrong number of PARAMETERS in file");
+     701        1084 :       for(unsigned i=0; i<size; ++i) Iq0+=FF_tmp[0][i];
+     702           4 :       Iq0 *= Iq0;
+     703           4 :     }
+     704          24 :   } else if(onebead) {
+     705          10 :     if(saxs) {
+     706             :       // read built-in ONEBEAD parameters
+     707           6 :       FF_tmp_vac.resize(numq,std::vector<long double>(NONEBEAD));
+     708           6 :       FF_tmp_mix.resize(numq,std::vector<long double>(NONEBEAD));
+     709           6 :       FF_tmp_solv.resize(numq,std::vector<long double>(NONEBEAD));
+     710           6 :       std::vector<std::vector<long double> > parameter_vac(NONEBEAD);
+     711           6 :       std::vector<std::vector<long double> > parameter_mix(NONEBEAD);
+     712           6 :       std::vector<std::vector<long double> > parameter_solv(NONEBEAD);
+     713           6 :       getOnebeadparam(pdb, atoms, parameter_vac, parameter_mix, parameter_solv,residue_atom);
+     714         204 :       for(unsigned i=0; i<NONEBEAD; ++i) {
+     715        1980 :         for(unsigned k=0; k<numq; ++k) {
+     716       14256 :           for(unsigned j=0; j<parameter_vac[i].size(); ++j) {
+     717       12474 :             FF_tmp_vac[k][i]+= parameter_vac[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     718             :           }
+     719       14256 :           for(unsigned j=0; j<parameter_mix[i].size(); ++j) {
+     720       12474 :             FF_tmp_mix[k][i]+= parameter_mix[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     721             :           }
+     722       14256 :           for(unsigned j=0; j<parameter_solv[i].size(); ++j) {
+     723       12474 :             FF_tmp_solv[k][i]+= parameter_solv[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     724             :           }
+     725             :         }
+     726             :       }
+     727        1294 :       for(unsigned i=0; i<nres; ++i) {
+     728        1288 :         Iq0_vac[i]=parameter_vac[atoi[i]][0];
+     729        1288 :         Iq0_mix[i]=parameter_mix[atoi[i]][0];
+     730        1288 :         Iq0_solv[i]=parameter_solv[atoi[i]][0];
+     731             :       }
+     732           6 :     } else { // SANS
+     733             :       // read built-in ONEBEAD parameters
+     734           4 :       FF_tmp_vac_H.resize(numq,std::vector<long double>(NONEBEAD));
+     735           4 :       FF_tmp_mix_H.resize(numq,std::vector<long double>(NONEBEAD));
+     736           4 :       FF_tmp_solv_H.resize(numq,std::vector<long double>(NONEBEAD));
+     737           4 :       FF_tmp_vac_D.resize(numq,std::vector<long double>(NONEBEAD));
+     738           4 :       FF_tmp_mix_D.resize(numq,std::vector<long double>(NONEBEAD));
+     739           4 :       std::vector<std::vector<long double> > parameter_vac_H(NONEBEAD);
+     740           4 :       std::vector<std::vector<long double> > parameter_mix_H(NONEBEAD);
+     741           4 :       std::vector<std::vector<long double> > parameter_solv_H(NONEBEAD);
+     742           4 :       std::vector<std::vector<long double> > parameter_vac_D(NONEBEAD);
+     743           4 :       std::vector<std::vector<long double> > parameter_mix_D(NONEBEAD);
+     744           4 :       getOnebeadparam_sansH(pdb, atoms, parameter_vac_H, parameter_mix_H, parameter_solv_H);
+     745           4 :       getOnebeadparam_sansD(pdb, atoms, parameter_vac_D, parameter_mix_D);
+     746         136 :       for(unsigned i=0; i<NONEBEAD; ++i) {
+     747        1320 :         for(unsigned k=0; k<numq; ++k) {
+     748        9504 :           for(unsigned j=0; j<parameter_vac_H[i].size(); ++j) { // same number of parameters
+     749        8316 :             FF_tmp_vac_H[k][i]+= parameter_vac_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     750        8316 :             FF_tmp_vac_D[k][i]+= parameter_vac_D[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     751             :           }
+     752        9504 :           for(unsigned j=0; j<parameter_mix_H[i].size(); ++j) {
+     753        8316 :             FF_tmp_mix_H[k][i]+= parameter_mix_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     754        8316 :             FF_tmp_mix_D[k][i]+= parameter_mix_D[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     755             :           }
+     756        9504 :           for(unsigned j=0; j<parameter_solv_H[i].size(); ++j) {
+     757        8316 :             FF_tmp_solv_H[k][i]+= parameter_solv_H[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     758             :           }
+     759             :         }
+     760             :       }
+     761         880 :       for(unsigned i=0; i<nres; ++i) {
+     762         876 :         Iq0_vac_H[i]=parameter_vac_H[atoi[i]][0];
+     763         876 :         Iq0_mix_H[i]=parameter_mix_H[atoi[i]][0];
+     764         876 :         Iq0_solv_H[i]=parameter_solv_H[atoi[i]][0];
+     765         876 :         Iq0_vac_D[i]=parameter_vac_D[atoi[i]][0];
+     766         876 :         Iq0_mix_D[i]=parameter_mix_D[atoi[i]][0];
+     767             :       }
+     768           4 :     }
+     769          14 :   } else if(martini) {
+     770             :     // read built-in MARTINI parameters
+     771          16 :     FF_tmp.resize(numq,std::vector<long double>(NMARTINI));
+     772             :     std::vector<std::vector<long double> > parameter;
+     773           8 :     parameter.resize(NMARTINI);
+     774           8 :     getMartiniFFparam(atoms, parameter);
+     775        1072 :     for(unsigned i=0; i<NMARTINI; ++i) {
+     776       17024 :       for(unsigned k=0; k<numq; ++k) {
+     777      127680 :         for(unsigned j=0; j<parameter[i].size(); ++j) {
+     778      111720 :           FF_tmp[k][i]+= parameter[i][j]*std::pow(static_cast<long double>(q_list[k]),j);
+     779             :         }
+     780             :       }
+     781             :     }
+     782        8400 :     for(unsigned i=0; i<size; ++i) Iq0+=parameter[atoi[i]][0];
+     783           8 :     Iq0 *= Iq0;
+     784          14 :   } else if(atomistic) {
+     785           6 :     FF_tmp.resize(numq,std::vector<long double>(NTT));
+     786           6 :     if(saxs) Iq0=calculateAFF(atoms, FF_tmp, rho);
+     787           2 :     else Iq0=calculateAFFsans(atoms, FF_tmp, deuter_conc);
+     788           6 :     Iq0 *= Iq0;
+     789             :   }
+     790             : 
+     791             :   std::vector<double> expint;
+     792          32 :   expint.resize( numq );
+     793             :   ntarget=0;
+     794         224 :   for(unsigned i=0; i<numq; ++i) {
+     795         416 :     if( !parseNumbered( "EXPINT", i+1, expint[i] ) ) break;
+     796         192 :     ntarget++;
+     797             :   }
+     798         224 :   std::transform(expint.begin(), expint.begin() + ntarget, expint.begin(), [scale_expint](double x) { return x / scale_expint; });
+     799             :   bool exp=false;
+     800          32 :   if(ntarget!=numq && ntarget!=0) error("found wrong number of EXPINT values");
+     801          32 :   if(ntarget==numq) exp=true;
+     802          32 :   if(getDoScore()&&!exp) error("with DOSCORE you need to set the EXPINT values");
+     803             : 
+     804          32 :   sigma_res.resize( numq );
+     805          32 :   resolution=false;
+     806             :   ntarget=0;
+     807          92 :   for(unsigned i=0; i<numq; ++i) {
+     808         176 :     if( !parseNumbered( "SIGMARES", i+1, sigma_res[i] ) ) break;
+     809          60 :     ntarget++;
+     810             :   }
+     811          32 :   if(ntarget!=numq && ntarget!=0) error("found wrong number of SIGMARES values");
+     812          32 :   if(ntarget==numq) resolution=true;
+     813             : 
+     814          32 :   if(gpu && resolution) error("Resolution function is not supported in GPUs");
+     815             : 
+     816          32 :   Nj = 10;
+     817          32 :   parse("N", Nj);
+     818          32 :   if (Nj < 2) error("N should be larger than 1");
+     819          32 :   if (resolution) log.printf("  Resolution function with N: %d\n", Nj);
+     820             : 
+     821          32 :   if(!gpu) {
+     822          32 :     FF_rank.resize(numq);
+     823             :     unsigned n_atom_types;
+     824          32 :     if(onebead) {
+     825          10 :       FF_value.resize(nres,std::vector<double>(numq));
+     826             :       n_atom_types=NONEBEAD;
+     827          10 :       if(saxs) {
+     828           6 :         FF_value_vacuum.resize(n_atom_types,std::vector<double>(numq));
+     829           6 :         FF_value_solv.resize(n_atom_types,std::vector<double>(numq));
+     830          12 :         FF_value_mixed.resize(n_atom_types,std::vector<double>(numq));
+     831             :       } else {
+     832           4 :         FF_value_vacuum_H.resize(n_atom_types,std::vector<double>(numq));
+     833           4 :         FF_value_solv_H.resize(n_atom_types,std::vector<double>(numq));
+     834           4 :         FF_value_mixed_H.resize(n_atom_types,std::vector<double>(numq));
+     835           4 :         FF_value_vacuum_D.resize(n_atom_types,std::vector<double>(numq));
+     836           8 :         FF_value_mixed_D.resize(n_atom_types,std::vector<double>(numq));
+     837             :       }
+     838             :     } else {
+     839          44 :       FF_value.resize(size,std::vector<double>(numq));
+     840             :     }
+     841         368 :     for(unsigned k=0; k<numq; ++k) {
+     842         336 :       if(!onebead) {
+     843      332970 :         for(unsigned i=0; i<size; ++i) FF_value[i][k] = static_cast<double>(FF_tmp[k][atoi[i]])/(std::sqrt(Iq0));
+     844      332970 :         for(unsigned i=0; i<size; ++i) FF_rank[k] += FF_value[i][k]*FF_value[i][k];
+     845             :       } else {
+     846          90 :         if(saxs) {
+     847        1836 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     848        1782 :             FF_value_vacuum[i][k] = static_cast<double>(FF_tmp_vac[k][i]);
+     849        1782 :             FF_value_mixed[i][k] = static_cast<double>(FF_tmp_mix[k][i]);
+     850        1782 :             FF_value_solv[i][k] = static_cast<double>(FF_tmp_solv[k][i]);
+     851             :           }
+     852             :         } else { // SANS
+     853        1224 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     854        1188 :             FF_value_vacuum_H[i][k] = static_cast<double>(FF_tmp_vac_H[k][i]);
+     855        1188 :             FF_value_mixed_H[i][k] = static_cast<double>(FF_tmp_mix_H[k][i]);
+     856        1188 :             FF_value_solv_H[i][k] = static_cast<double>(FF_tmp_solv_H[k][i]);
+     857        1188 :             FF_value_vacuum_D[i][k] = static_cast<double>(FF_tmp_vac_D[k][i]);
+     858        1188 :             FF_value_mixed_D[i][k] = static_cast<double>(FF_tmp_mix_D[k][i]);
+     859             :           }
+     860             :         }
+     861             :       }
+     862             :     }
+     863             :   } else {
+     864             :     unsigned n_atom_types;
+     865           0 :     if(onebead) {
+     866           0 :       FFf_value.resize(numq,std::vector<float>(nres));
+     867             :       n_atom_types=NONEBEAD;
+     868           0 :       if(saxs) {
+     869           0 :         FF_value_vacuum.resize(n_atom_types,std::vector<double>(numq));
+     870           0 :         FF_value_solv.resize(n_atom_types,std::vector<double>(numq));
+     871           0 :         FF_value_mixed.resize(n_atom_types,std::vector<double>(numq));
+     872             :       } else { // SANS
+     873           0 :         FF_value_vacuum_H.resize(n_atom_types,std::vector<double>(numq));
+     874           0 :         FF_value_solv_H.resize(n_atom_types,std::vector<double>(numq));
+     875           0 :         FF_value_mixed_H.resize(n_atom_types,std::vector<double>(numq));
+     876           0 :         FF_value_vacuum_D.resize(n_atom_types,std::vector<double>(numq));
+     877           0 :         FF_value_mixed_D.resize(n_atom_types,std::vector<double>(numq));
+     878             :       }
+     879             :     } else {
+     880           0 :       FFf_value.resize(numq,std::vector<float>(size));
+     881             :     }
+     882           0 :     for(unsigned k=0; k<numq; ++k) {
+     883           0 :       if(!onebead) {
+     884           0 :         for(unsigned i=0; i<size; ++i) {
+     885           0 :           FFf_value[k][i] = static_cast<float>(FF_tmp[k][atoi[i]])/(std::sqrt(Iq0));
+     886             :         }
+     887             :       } else {
+     888           0 :         if(saxs) {
+     889           0 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     890           0 :             FF_value_vacuum[i][k] = static_cast<double>(FF_tmp_vac[k][i]);
+     891           0 :             FF_value_mixed[i][k] = static_cast<double>(FF_tmp_mix[k][i]);
+     892           0 :             FF_value_solv[i][k] = static_cast<double>(FF_tmp_solv[k][i]);
+     893             :           }
+     894             :         } else { // SANS
+     895           0 :           for(unsigned i=0; i<n_atom_types; ++i) {
+     896           0 :             FF_value_vacuum_H[i][k] = static_cast<double>(FF_tmp_vac_H[k][i]);
+     897           0 :             FF_value_mixed_H[i][k] = static_cast<double>(FF_tmp_mix_H[k][i]);
+     898           0 :             FF_value_solv_H[i][k] = static_cast<double>(FF_tmp_solv_H[k][i]);
+     899           0 :             FF_value_vacuum_D[i][k] = static_cast<double>(FF_tmp_vac_D[k][i]);
+     900           0 :             FF_value_mixed_D[i][k] = static_cast<double>(FF_tmp_mix_D[k][i]);
+     901             :           }
+     902             :         }
+     903             :       }
+     904             :     }
+     905             :   }
+     906             : 
+     907          32 :   if(!getDoScore()) {
+     908         288 :     for(unsigned i=0; i<numq; ++i) {
+     909         264 :       std::string num; Tools::convert(i,num);
+     910         528 :       addComponentWithDerivatives("q-"+num);
+     911         528 :       componentIsNotPeriodic("q-"+num);
+     912             :     }
+     913          24 :     if(exp) {
+     914         128 :       for(unsigned i=0; i<numq; ++i) {
+     915         120 :         std::string num; Tools::convert(i,num);
+     916         240 :         addComponent("exp-"+num);
+     917         120 :         componentIsNotPeriodic("exp-"+num);
+     918         120 :         Value* comp=getPntrToComponent("exp-"+num);
+     919         120 :         comp->set(expint[i]);
+     920             :       }
+     921             :     }
+     922             :   } else {
+     923          80 :     for(unsigned i=0; i<numq; ++i) {
+     924          72 :       std::string num; Tools::convert(i,num);
+     925         144 :       addComponent("q-"+num);
+     926         144 :       componentIsNotPeriodic("q-"+num);
+     927             :     }
+     928          80 :     for(unsigned i=0; i<numq; ++i) {
+     929          72 :       std::string num; Tools::convert(i,num);
+     930         144 :       addComponent("exp-"+num);
+     931          72 :       componentIsNotPeriodic("exp-"+num);
+     932          72 :       Value* comp=getPntrToComponent("exp-"+num);
+     933          72 :       comp->set(expint[i]);
+     934             :     }
+     935             :   }
+     936             : 
+     937             :   // convert units to nm^-1
+     938         368 :   for(unsigned i=0; i<numq; ++i) {
+     939         336 :     q_list[i]=q_list[i]*10.0;    // factor 10 to convert from A^-1 to nm^-1
+     940         336 :     if (resolution) sigma_res[i]=sigma_res[i]*10.0;
+     941             :   }
+     942             : 
+     943             :   // compute resolution function after converting units
+     944          32 :   if (resolution) {
+     945           4 :     qj_list.resize(numq, std::vector<double>(Nj));
+     946           4 :     Rij.resize(numq, std::vector<double>(Nj));
+     947             :     // compute Rij and qj_list
+     948           4 :     resolution_function();
+     949             :   }
+     950             : 
+     951          32 :   log<<"  Bibliography ";
+     952          32 :   if(martini) {
+     953          16 :     log<<plumed.cite("Niebling, Björling, Westenhoff, J Appl Crystallogr 47, 1190–1198 (2014)");
+     954          16 :     log<<plumed.cite("Paissoni, Jussupow, Camilloni, J Appl Crystallogr 52, 394-402 (2019)");
+     955             :   }
+     956          32 :   if(atomistic) {
+     957          12 :     log<<plumed.cite("Fraser, MacRae, Suzuki, J. Appl. Crystallogr., 11, 693–694 (1978)");
+     958          12 :     log<<plumed.cite("Brown, Fox, Maslen, O'Keefe, Willis, International Tables for Crystallography C, 554–595 (International Union of Crystallography, 2006)");
+     959             :   }
+     960          32 :   if(resolution) {
+     961           8 :     log<<plumed.cite("Pedersen, Posselt, Mortensen, J. Appl. Crystallogr., 23, 321–333 (1990)");
+     962             :   }
+     963             : 
+     964          64 :   log<< plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)");
+     965          32 :   log<<"\n";
+     966             : 
+     967          32 :   requestAtoms(atoms, false);
+     968             : 
+     969          32 :   if(getDoScore()) {
+     970           8 :     setParameters(expint);
+     971           8 :     Initialise(numq);
+     972             :   }
+     973          32 :   setDerivatives();
+     974          32 :   checkRead();
+     975          64 : }
+     976             : 
+     977             : // calculates SASA neighbor list
+     978           8 : void SAXS::calcNlist(std::vector<std::vector<int> > &Nlist)
+     979             : {
+     980             :   unsigned natoms = getNumberOfAtoms();
+     981       28596 :   for(unsigned i = 0; i < natoms; ++i) {
+     982       28588 :     if (LCPOparam[i].size()>0) {
+     983    24279400 :       for (unsigned j = 0; j < i; ++j) {
+     984    24266020 :         if (LCPOparam[j].size()>0) {
+     985    11213664 :           double Delta_ij_mod = modulo(delta(getPosition(i), getPosition(j)))*10.;
+     986    11213664 :           double overlapD = LCPOparam[i][0]+LCPOparam[j][0];
+     987    11213664 :           if(Delta_ij_mod < overlapD) {
+     988      259140 :             Nlist.at(i).push_back(j);
+     989      259140 :             Nlist.at(j).push_back(i);
+     990             :           }
+     991             :         }
+     992             :       }
+     993             :     }
+     994             :   }
+     995             : 
+     996           8 : }
+     997             : 
+     998             : // calculates SASA according to LCPO algorithm
+     999           8 : void SAXS::sasa_calculate(std::vector<bool> &solv_res) {
+    1000             :   unsigned natoms = getNumberOfAtoms();
+    1001           8 :   std::vector<std::vector<int> > Nlist(natoms);
+    1002           8 :   calcNlist(Nlist);
+    1003           8 :   std::vector<double> sasares(nres, 0.);
+    1004             : 
+    1005           8 :   #pragma omp parallel num_threads(OpenMP::getNumThreads())
+    1006             :   {
+    1007             :     std::vector<double> private_sasares(nres, 0.);
+    1008             :     #pragma omp for
+    1009             :     for (unsigned i = 0; i < natoms; ++i) {
+    1010             :       if (LCPOparam[i].size() > 1 && LCPOparam[i][1] > 0.0) {
+    1011             :         double Aij = 0.0;
+    1012             :         double Aijk = 0.0;
+    1013             :         double Ajk = 0.0;
+    1014             :         double ri = LCPOparam[i][0];
+    1015             :         double S1 = 4.*M_PI*ri*ri;
+    1016             :         for (unsigned j = 0; j < Nlist[i].size(); ++j) {
+    1017             :           double d_ij = modulo(delta( getPosition(i), getPosition(Nlist[i][j]) ))*10.;
+    1018             :           double rj = LCPOparam[Nlist[i][j]][0];
+    1019             :           double Aijt = (2.*M_PI*ri*(ri-d_ij/2.-((ri*ri-rj*rj)/(2.*d_ij))));
+    1020             :           double Ajkt = 0.0;
+    1021             :           for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); ++k) {
+    1022             :             if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+    1023             :               double d_jk = modulo(delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) ))*10.;
+    1024             :               double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+    1025             :               double sjk =  (2.*M_PI*rj*(rj-d_jk/2.-((rj*rj-rk*rk)/(2.*d_jk))));
+    1026             :               Ajkt += sjk;
+    1027             :             }
+    1028             :           }
+    1029             :           Aijk += (Aijt * Ajkt);
+    1030             :           Aij += Aijt;
+    1031             :           Ajk += Ajkt;
+    1032             :         }
+    1033             :         double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+    1034             :         if (sasai > 0) {
+    1035             :           private_sasares[residue_atom[i]] += sasai / 100.0;
+    1036             :         }
+    1037             :       }
+    1038             :     }
+    1039             :     #pragma omp critical
+    1040             :     { // combining private_sasares into sasares
+    1041             :       for (unsigned i = 0; i < nres; ++i) {
+    1042             :         sasares[i] += private_sasares[i];
+    1043             :       }
+    1044             :     }
+    1045             :   }
+    1046        1760 :   for(unsigned i=0; i<nres; ++i) { // updating solv_res based on sasares
+    1047        1752 :     if(sasares[i]>sasa_cutoff) solv_res[i] = 1;
+    1048             :     else solv_res[i] = 0;
+    1049             :   }
+    1050           8 : }
+    1051             : 
+    1052           0 : void SAXS::calculate_gpu(std::vector<Vector> &pos, std::vector<Vector> &deriv)
+    1053             : {
+    1054             : #ifdef __PLUMED_HAS_ARRAYFIRE
+    1055             :   unsigned size;
+    1056             :   if(onebead) size = nres;
+    1057             :   else size = getNumberOfAtoms();
+    1058             :   const unsigned numq = q_list.size();
+    1059             : 
+    1060             :   std::vector<float> sum;
+    1061             :   sum.resize(numq);
+    1062             : 
+    1063             :   std::vector<float> dd;
+    1064             :   dd.resize(size*3*numq);
+    1065             : 
+    1066             :   // on gpu only the master rank run the calculation
+    1067             :   if(comm.Get_rank()==0) {
+    1068             :     std::vector<float> posi;
+    1069             :     posi.resize(3*size);
+    1070             :     #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    1071             :     for (unsigned i=0; i<size; ++i) {
+    1072             :       const Vector tmp = pos[i];
+    1073             :       posi[3*i]   = static_cast<float>(tmp[0]);
+    1074             :       posi[3*i+1] = static_cast<float>(tmp[1]);
+    1075             :       posi[3*i+2] = static_cast<float>(tmp[2]);
+    1076             :     }
+    1077             : 
+    1078             :     // create array a and b containing atomic coordinates
+    1079             : #ifdef  __PLUMED_HAS_ARRAYFIRE_CUDA
+    1080             :     af::setDevice(afcu::getNativeId(deviceid));
+    1081             : #elif   __PLUMED_HAS_ARRAYFIRE_OCL
+    1082             :     af::setDevice(afcl::getNativeId(deviceid));
+    1083             : #else
+    1084             :     af::setDevice(deviceid);
+    1085             : #endif
+    1086             :     // 3,size,1,1
+    1087             :     af::array pos_a = af::array(3, size, &posi.front());
+    1088             :     // size,3,1,1
+    1089             :     pos_a = af::moddims(pos_a.T(), size, 3, 1);
+    1090             :     // size,3,1,1
+    1091             :     af::array pos_b = pos_a(af::span, af::span);
+    1092             :     // size,1,3,1
+    1093             :     pos_a = af::moddims(pos_a, size, 1, 3);
+    1094             :     // 1,size,3,1
+    1095             :     pos_b = af::moddims(pos_b, 1, size, 3);
+    1096             : 
+    1097             :     // size,size,3,1
+    1098             :     af::array pos_a_t = af::tile(pos_a, 1, size, 1);
+    1099             :     // size,size,3,1: for some reason we need this
+    1100             :     pos_a_t = af::moddims(pos_a_t, size, size, 3);
+    1101             :     // size,size,3,1
+    1102             :     af::array pos_b_t = af::tile(pos_b, size, 1, 1);
+    1103             :     // size,size,3,1: for some reason we need this
+    1104             :     pos_b_t = af::moddims(pos_b_t, size, size, 3);
+    1105             :     // size,size,3,1
+    1106             :     af::array xyz_dist = pos_a_t - pos_b_t;
+    1107             :     // size,size,1,1
+    1108             :     af::array square = af::sum(xyz_dist*xyz_dist,2);
+    1109             :     // size,size,1,1
+    1110             :     af::array dist_sqrt = af::sqrt(square);
+    1111             :     // replace the zero of square with one to avoid nan in the derivatives (the number does not matter because this are multiplied by zero)
+    1112             :     af::replace(square,!(af::iszero(square)),1.);
+    1113             :     // size,size,3,1
+    1114             :     xyz_dist = xyz_dist / af::tile(square, 1, 1, 3);
+    1115             :     // numq,1,1,1
+    1116             :     af::array sum_device   = af::constant(0, numq, f32);
+    1117             :     // numq,size,3,1
+    1118             :     af::array deriv_device = af::constant(0, numq, size, 3, f32);
+    1119             : 
+    1120             :     for (unsigned k=0; k<numq; ++k) {
+    1121             :       // calculate FF matrix
+    1122             :       // size,1,1,1
+    1123             :       af::array AFF_value(size, &FFf_value[k].front());
+    1124             :       // size,size,1,1
+    1125             :       af::array FFdist_mod = af::tile(AFF_value(af::span), 1, size)*af::transpose(af::tile(AFF_value(af::span), 1, size));
+    1126             : 
+    1127             :       // get q
+    1128             :       const float qvalue = static_cast<float>(q_list[k]);
+    1129             :       // size,size,1,1
+    1130             :       af::array dist_q = qvalue*dist_sqrt;
+    1131             :       // size,size,1
+    1132             :       af::array dist_sin = af::sin(dist_q)/dist_q;
+    1133             :       af::replace(dist_sin,!(af::isNaN(dist_sin)),1.);
+    1134             :       // 1,1,1,1
+    1135             :       sum_device(k) = af::sum(af::flat(dist_sin)*af::flat(FFdist_mod));
+    1136             : 
+    1137             :       // size,size,1,1
+    1138             :       af::array tmp = FFdist_mod*(dist_sin - af::cos(dist_q));
+    1139             :       // size,size,3,1
+    1140             :       af::array dd_all = af::tile(tmp, 1, 1, 3)*xyz_dist;
+    1141             :       // it should become 1,size,3
+    1142             :       deriv_device(k, af::span, af::span) = af::sum(dd_all,0);
+    1143             :     }
+    1144             : 
+    1145             :     // read out results
+    1146             :     sum_device.host(&sum.front());
+    1147             : 
+    1148             :     deriv_device = af::reorder(deriv_device, 2, 1, 0);
+    1149             :     deriv_device = af::flat(deriv_device);
+    1150             :     deriv_device.host(&dd.front());
+    1151             :   }
+    1152             : 
+    1153             :   comm.Bcast(dd, 0);
+    1154             :   comm.Bcast(sum, 0);
+    1155             : 
+    1156             :   for(unsigned k=0; k<numq; ++k) {
+    1157             :     std::string num; Tools::convert(k,num);
+    1158             :     Value* val=getPntrToComponent("q-"+num);
+    1159             :     val->set(sum[k]);
+    1160             :     if(getDoScore()) setCalcData(k, sum[k]);
+    1161             :     for(unsigned i=0; i<size; ++i) {
+    1162             :       const unsigned di = k*size*3+i*3;
+    1163             :       deriv[k*size+i] = Vector(2.*dd[di+0],2.*dd[di+1],2.*dd[di+2]);
+    1164             :     }
+    1165             :   }
+    1166             : #endif
+    1167           0 : }
+    1168             : 
+    1169         192 : void SAXS::calculate_cpu(std::vector<Vector> &pos, std::vector<Vector> &deriv)
+    1170             : {
+    1171             :   unsigned size;
+    1172         192 :   if(onebead) size = nres;
+    1173             :   else size = getNumberOfAtoms();
+    1174         192 :   const unsigned numq = q_list.size();
+    1175             : 
+    1176         192 :   unsigned stride = comm.Get_size();
+    1177         192 :   unsigned rank   = comm.Get_rank();
+    1178         192 :   if(serial) {
+    1179             :     stride = 1;
+    1180             :     rank   = 0;
+    1181             :   }
+    1182         192 :   std::vector<double> sum(numq,0);
+    1183         192 :   unsigned nt=OpenMP::getNumThreads();
+    1184         192 :   #pragma omp parallel num_threads(nt)
+    1185             :   {
+    1186             :     std::vector<Vector> omp_deriv(deriv.size());
+    1187             :     std::vector<double> omp_sum(numq,0);
+    1188             :     #pragma omp for nowait
+    1189             :     for (unsigned i=rank; i<size-1; i+=stride) {
+    1190             :       Vector posi = pos[i];
+    1191             :       for (unsigned j=i+1; j<size ; ++j) {
+    1192             :         Vector c_distances = delta(posi,pos[j]);
+    1193             :         double m_distances = c_distances.modulo();
+    1194             :         c_distances = c_distances/m_distances/m_distances;
+    1195             :         for (unsigned k=0; k<numq; ++k) {
+    1196             :           unsigned kdx=k*size;
+    1197             :           double qdist = q_list[k]*m_distances;
+    1198             :           double FFF = 2.*FF_value[i][k]*FF_value[j][k];
+    1199             :           double tsq = std::sin(qdist)/qdist;
+    1200             :           double tcq = std::cos(qdist);
+    1201             :           double tmp = FFF*(tcq-tsq);
+    1202             :           Vector dd  = c_distances*tmp;
+    1203             :           if(nt>1) {
+    1204             :             omp_deriv[kdx+i] -=dd;
+    1205             :             omp_deriv[kdx+j] +=dd;
+    1206             :             omp_sum[k] += FFF*tsq;
+    1207             :           } else {
+    1208             :             deriv[kdx+i] -= dd;
+    1209             :             deriv[kdx+j] += dd;
+    1210             :             sum[k] += FFF*tsq;
+    1211             :           }
+    1212             :         }
+    1213             :       }
+    1214             :     }
+    1215             :     #pragma omp critical
+    1216             :     if(nt>1) {
+    1217             :       for(unsigned i=0; i<deriv.size(); ++i) deriv[i]+=omp_deriv[i];
+    1218             :       for(unsigned k=0; k<numq; ++k) sum[k]+=omp_sum[k];
+    1219             :     }
+    1220             :   }
+    1221             : 
+    1222         192 :   if(!serial) {
+    1223         190 :     comm.Sum(&deriv[0][0], 3*deriv.size());
+    1224         190 :     comm.Sum(&sum[0], numq);
+    1225             :   }
+    1226             : 
+    1227         192 :   if (resolution) {
+    1228             :     // get spline for scatering curve
+    1229           4 :     std::vector<SplineCoeffs> scatt_coeffs = spline_coeffs(q_list, sum);
+    1230             : 
+    1231             :     // get spline for the derivatives
+    1232             :     // copy the deriv to a new vector and zero deriv
+    1233           4 :     std::vector<Vector> old_deriv(deriv);
+    1234           4 :     memset(&deriv[0][0], 0.0, deriv.size() * sizeof deriv[0]);
+    1235             : 
+    1236           4 :     unsigned nt=OpenMP::getNumThreads();
+    1237         274 :     for (unsigned i=rank; i<size; i+=stride) {
+    1238         270 :       std::vector<double> deriv_i_x(numq);
+    1239         270 :       std::vector<double> deriv_i_y(numq);
+    1240         270 :       std::vector<double> deriv_i_z(numq);
+    1241             : 
+    1242             :       std::vector<SplineCoeffs> deriv_coeffs_x;
+    1243             :       std::vector<SplineCoeffs> deriv_coeffs_y;
+    1244             :       std::vector<SplineCoeffs> deriv_coeffs_z;
+    1245        4320 :       for (unsigned k=0; k<numq; k++) {
+    1246        4050 :         unsigned kdx = k*size;
+    1247        4050 :         deriv_i_x[k] = old_deriv[kdx+i][0];
+    1248        4050 :         deriv_i_y[k] = old_deriv[kdx+i][1];
+    1249        4050 :         deriv_i_z[k] = old_deriv[kdx+i][2];
+    1250             :       }
+    1251         270 :       deriv_coeffs_x = spline_coeffs(q_list, deriv_i_x);
+    1252         270 :       deriv_coeffs_y = spline_coeffs(q_list, deriv_i_y);
+    1253         270 :       deriv_coeffs_z = spline_coeffs(q_list, deriv_i_z);
+    1254             : 
+    1255             :       // compute derivative with the smearing using the resolution function
+    1256         270 :       #pragma omp parallel for num_threads(nt)
+    1257             :       for (unsigned k=0; k<numq; k++) {
+    1258             :         unsigned kdx = k*size;
+    1259             :         double dq = qj_list[k][1] - qj_list[k][0];
+    1260             :         for (unsigned j=0; j<Nj; j++) {
+    1261             :           deriv[kdx+i][0] += Rij[k][j] * interpolation(deriv_coeffs_x, qj_list[k][j]) * dq;
+    1262             :           deriv[kdx+i][1] += Rij[k][j] * interpolation(deriv_coeffs_y, qj_list[k][j]) * dq;
+    1263             :           deriv[kdx+i][2] += Rij[k][j] * interpolation(deriv_coeffs_z, qj_list[k][j]) * dq;
+    1264             :         }
+    1265             :       }
+    1266             :     }
+    1267             : 
+    1268           4 :     if(!serial) {
+    1269           4 :       comm.Sum(&deriv[0][0], 3*deriv.size());
+    1270             :     }
+    1271             : 
+    1272             :     // compute the smeared spectra using the resolution function
+    1273           4 :     #pragma omp parallel for num_threads(nt)
+    1274             :     for (unsigned i=0; i<numq; i++) {
+    1275             :       sum[i] = 0.;
+    1276             :       double dq = qj_list[i][1] - qj_list[i][0];
+    1277             :       for (unsigned j=0; j<Nj; j++) {
+    1278             :         sum[i] += Rij[i][j] * interpolation(scatt_coeffs, qj_list[i][j]) * dq;
+    1279             :       }
+    1280             :     }
+    1281             :   }
+    1282             : 
+    1283        1968 :   for (unsigned k=0; k<numq; ++k) {
+    1284        1776 :     sum[k]+=FF_rank[k];
+    1285        1776 :     std::string num; Tools::convert(k,num);
+    1286        1776 :     Value* val=getPntrToComponent("q-"+num);
+    1287        1776 :     val->set(sum[k]);
+    1288        1776 :     if(getDoScore()) setCalcData(k, sum[k]);
+    1289             :   }
+    1290         192 : }
+    1291             : 
+    1292         192 : void SAXS::calculate()
+    1293             : {
+    1294         192 :   if(pbc) makeWhole();
+    1295             : 
+    1296         192 :   const size_t size = getNumberOfAtoms();
+    1297             :   const size_t numq = q_list.size();
+    1298             : 
+    1299             :   // these are the derivatives associated to the coarse graining
+    1300         192 :   std::vector<Vector> aa_deriv(size);
+    1301             : 
+    1302             :   size_t beads_size = size;
+    1303         192 :   if(onebead) beads_size = nres;
+    1304             :   // these are the derivatives particle,q
+    1305         192 :   std::vector<Vector> bd_deriv(numq*beads_size);
+    1306             : 
+    1307         192 :   std::vector<Vector> beads_pos(beads_size);
+    1308         192 :   if(onebead) {
+    1309        2174 :     for(unsigned resid=0; resid<nres; resid++) {
+    1310             :       double sum_mass = 0.;
+    1311        2164 :       Vector sum_pos = Vector(0,0,0);
+    1312     7693792 :       for(unsigned atom_id=0; atom_id<size; atom_id++) {
+    1313     7691628 :         if(residue_atom[atom_id] == resid) {
+    1314       35466 :           aa_deriv[atom_id] = Vector(atoms_masses[atom_id],atoms_masses[atom_id],atoms_masses[atom_id]);
+    1315       35466 :           sum_pos += atoms_masses[atom_id] * getPosition(atom_id); // getPosition(first_atom+atom_id)
+    1316       35466 :           sum_mass += atoms_masses[atom_id];
+    1317             :         }
+    1318             :       }
+    1319        2164 :       beads_pos[resid] = sum_pos/sum_mass;
+    1320     7693792 :       for(unsigned atom_id=0; atom_id<size; atom_id++) {
+    1321     7691628 :         if(residue_atom[atom_id] == resid) {
+    1322       35466 :           aa_deriv[atom_id] /= sum_mass;
+    1323             :         }
+    1324             :       }
+    1325             :     }
+    1326             :     // SASA
+    1327          10 :     std::vector<bool> solv_res(nres, 0);
+    1328          10 :     if(saxs) {
+    1329           6 :       if(getStep()%solv_stride == 0 || isFirstStep) {
+    1330           6 :         isFirstStep = 0;
+    1331           6 :         if(rho_corr!=rho) sasa_calculate(solv_res);
+    1332           6 :         Iq0=0.;
+    1333        1294 :         for(unsigned i=0; i<nres; ++i) {
+    1334        1288 :           if(solv_res[i] == 1 ) {
+    1335         182 :             Iq0 += std::sqrt((Iq0_vac[i]+(rho_corr*rho_corr)*Iq0_solv[i]-rho_corr*Iq0_mix[i]));
+    1336             :           } else {
+    1337        1106 :             Iq0 += std::sqrt((Iq0_vac[i]+(rho*rho)*Iq0_solv[i]-rho*Iq0_mix[i]));
+    1338             :           }
+    1339             :         }
+    1340             :         // Form Factors
+    1341          60 :         for(unsigned k=0; k<numq; ++k) {
+    1342       11646 :           for(unsigned i=0; i<nres; ++i) {
+    1343       11592 :             if(!gpu) {
+    1344       11592 :               if(solv_res[i] == 0) { // buried
+    1345        9954 :                 FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho*rho*FF_value_solv[atoi[i]][k] - rho*FF_value_mixed[atoi[i]][k]))/Iq0;
+    1346             :               } else { // surface
+    1347        1638 :                 FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho_corr*rho_corr*FF_value_solv[atoi[i]][k] - rho_corr*FF_value_mixed[atoi[i]][k]))/Iq0;
+    1348             :               }
+    1349             :             } else {
+    1350           0 :               if(solv_res[i] == 0) { // buried
+    1351           0 :                 FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho*rho*FF_value_solv[atoi[i]][k] - rho*FF_value_mixed[atoi[i]][k]))/Iq0);
+    1352             :               } else { // surface
+    1353           0 :                 FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum[atoi[i]][k] + rho_corr*rho_corr*FF_value_solv[atoi[i]][k] - rho_corr*FF_value_mixed[atoi[i]][k]))/Iq0);
+    1354             :               }
+    1355             :             }
+    1356             :           }
+    1357             :         }
+    1358           6 :         if(!gpu) {
+    1359          60 :           for(unsigned k=0; k<numq; ++k) {
+    1360          54 :             FF_rank[k]=0.;
+    1361       11646 :             for(unsigned i=0; i<nres; ++i) {
+    1362       11592 :               FF_rank[k]+=FF_value[i][k]*FF_value[i][k];
+    1363             :             }
+    1364             :           }
+    1365             :         }
+    1366             :       }
+    1367             :     } else { // SANS
+    1368           4 :       std::vector<bool> deut_res(nres, 0);
+    1369           4 :       double solv_sc_length = 0.1*(0.580 + 2.*((1. - deuter_conc) * (-0.374) + deuter_conc * 0.667)); // per water electron (10 electrons)
+    1370           4 :       double rho_sans = rho * solv_sc_length;
+    1371           4 :       double rho_sans_corr = rho_corr * solv_sc_length;
+    1372           4 :       if(getStep()%solv_stride == 0 || isFirstStep) {
+    1373           4 :         isFirstStep = 0;
+    1374           4 :         if(deuter_conc!=0.||rho != rho_corr) sasa_calculate(solv_res);
+    1375           4 :         Iq0=0.;
+    1376         880 :         for(unsigned i=0; i<nres; ++i) {
+    1377         876 :           if(solv_res[i] == 1 ) {
+    1378         182 :             if(rand()/RAND_MAX<deuter_conc) {
+    1379           0 :               Iq0 += std::sqrt(std::fabs(Iq0_vac_D[i] + rho_sans_corr*rho_sans_corr*Iq0_solv_H[i] - rho_sans_corr*Iq0_mix_D[i]));
+    1380             :               deut_res[i] = 1;
+    1381             :             } else {
+    1382         182 :               Iq0 += std::sqrt(std::fabs(Iq0_vac_H[i] + rho_sans_corr*rho_sans_corr*Iq0_solv_H[i] - rho_sans_corr*Iq0_mix_H[i]));
+    1383             :             }
+    1384             :           } else {
+    1385         694 :             Iq0 += std::sqrt(std::fabs(Iq0_vac_H[i] + rho_sans*rho_sans*Iq0_solv_H[i] - rho_sans*Iq0_mix_H[i]));
+    1386             :           }
+    1387             :         }
+    1388             :         // Form Factors
+    1389          40 :         for(unsigned k=0; k<numq; ++k) {
+    1390        7920 :           for(unsigned i=0; i<nres; ++i) {
+    1391        7884 :             if(!gpu) {
+    1392        7884 :               if(solv_res[i] == 0) { // hydrogen
+    1393        6246 :                 FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans*rho_sans*FF_value_solv_H[atoi[i]][k] - rho_sans*FF_value_mixed_H[atoi[i]][k]))/Iq0;
+    1394             :               } else {
+    1395        1638 :                 if(deut_res[i] == 0) {
+    1396        1638 :                   FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_H[atoi[i]][k]))/Iq0;
+    1397             :                 } else {
+    1398           0 :                   FF_value[i][k] = std::sqrt(std::fabs(FF_value_vacuum_D[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_D[atoi[i]][k]))/Iq0;
+    1399             :                 }
+    1400             :               }
+    1401             :             } else {
+    1402           0 :               if(solv_res[i] == 0) { // hydrogen
+    1403           0 :                 FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans*rho_sans*FF_value_solv_H[atoi[i]][k] - rho_sans*FF_value_mixed_H[atoi[i]][k]))/Iq0);
+    1404             :               } else {
+    1405           0 :                 if(deut_res[i] == 0) {
+    1406           0 :                   FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum_H[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_H[atoi[i]][k]))/Iq0);
+    1407             :                 } else {
+    1408           0 :                   FFf_value[k][i] = static_cast<float>(std::sqrt(std::fabs(FF_value_vacuum_D[atoi[i]][k] + rho_sans_corr*rho_sans_corr*FF_value_solv_H[atoi[i]][k] - rho_sans_corr*FF_value_mixed_D[atoi[i]][k]))/Iq0);
+    1409             :                 }
+    1410             :               }
+    1411             :             }
+    1412             :           }
+    1413             :         }
+    1414           4 :         if(!gpu) {
+    1415          40 :           for(unsigned k=0; k<numq; ++k) {
+    1416          36 :             FF_rank[k]=0.;
+    1417        7920 :             for(unsigned i=0; i<nres; ++i) {
+    1418        7884 :               FF_rank[k]+=FF_value[i][k]*FF_value[i][k];
+    1419             :             }
+    1420             :           }
+    1421             :         }
+    1422             :       }
+    1423             :     }
+    1424             :     // not ONEBEAD
+    1425             :   } else {
+    1426       59898 :     for(unsigned i=0; i<size; ++i) {
+    1427       59716 :       beads_pos[i] = getPosition(i);
+    1428             :     }
+    1429         364 :     aa_deriv = std::vector<Vector>(size,(Vector(1,1,1)));
+    1430             :   }
+    1431             : 
+    1432         192 :   if(gpu) calculate_gpu(beads_pos, bd_deriv);
+    1433         192 :   else calculate_cpu(beads_pos, bd_deriv);
+    1434             : 
+    1435         192 :   if(getDoScore()) {
+    1436             :     /* Metainference */
+    1437         168 :     double score = getScore();
+    1438         168 :     setScore(score);
+    1439             :   }
+    1440             : 
+    1441        1968 :   for (unsigned k=0; k<numq; ++k) {
+    1442        1776 :     const unsigned kdx=k*beads_size;
+    1443        1776 :     Tensor deriv_box;
+    1444             :     Value* val;
+    1445        1776 :     if(!getDoScore()) {
+    1446         264 :       std::string num; Tools::convert(k,num);
+    1447         264 :       val=getPntrToComponent("q-"+num);
+    1448             : 
+    1449         264 :       if(onebead) {
+    1450             :         unsigned atom_id=0;
+    1451       19566 :         for(unsigned i=0; i<beads_size; ++i) {
+    1452      338670 :           for(unsigned j=0; j<atoms_per_bead[i]; ++j) {
+    1453      319194 :             setAtomsDerivatives(val, atom_id, Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0], \
+    1454      319194 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1], \
+    1455      319194 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]) );
+    1456      319194 :             deriv_box += Tensor(getPosition(atom_id),Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0], \
+    1457      319194 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1], \
+    1458      638388 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]) );
+    1459      319194 :             atom_id++;
+    1460             :           }
+    1461             :         }
+    1462             :       } else {
+    1463      311502 :         for(unsigned i=0; i<beads_size; ++i) {
+    1464      311328 :           setAtomsDerivatives(val, i, Vector(bd_deriv[kdx+i][0], \
+    1465      311328 :                                              bd_deriv[kdx+i][1], \
+    1466      311328 :                                              bd_deriv[kdx+i][2]) );
+    1467      622656 :           deriv_box += Tensor(getPosition(i),Vector(bd_deriv[kdx+i][0], \
+    1468      311328 :                               bd_deriv[kdx+i][1], \
+    1469      622656 :                               bd_deriv[kdx+i][2]) );
+    1470             :         }
+    1471             :       }
+    1472             :     } else {
+    1473        1512 :       val=getPntrToComponent("score");
+    1474        1512 :       if(onebead) {
+    1475             :         unsigned atom_id=0;
+    1476           0 :         for(unsigned i=0; i<beads_size; ++i) {
+    1477           0 :           for(unsigned j=0; j<atoms_per_bead[i]; ++j) {
+    1478           0 :             setAtomsDerivatives(val, atom_id, Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0]*getMetaDer(k),
+    1479           0 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1]*getMetaDer(k),
+    1480           0 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1481           0 :             deriv_box += Tensor(getPosition(atom_id),Vector(aa_deriv[atom_id][0]*bd_deriv[kdx+i][0]*getMetaDer(k),
+    1482           0 :                                 aa_deriv[atom_id][1]*bd_deriv[kdx+i][1]*getMetaDer(k),
+    1483           0 :                                 aa_deriv[atom_id][2]*bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1484           0 :             atom_id++;
+    1485             :           }
+    1486             :         }
+    1487             :       } else {
+    1488      450828 :         for(unsigned i=0; i<beads_size; ++i) {
+    1489      449316 :           setAtomsDerivatives(val, i, Vector(bd_deriv[kdx+i][0]*getMetaDer(k),
+    1490      449316 :                                              bd_deriv[kdx+i][1]*getMetaDer(k),
+    1491      449316 :                                              bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1492      898632 :           deriv_box += Tensor(getPosition(i),Vector(bd_deriv[kdx+i][0]*getMetaDer(k),
+    1493      449316 :                               bd_deriv[kdx+i][1]*getMetaDer(k),
+    1494      898632 :                               bd_deriv[kdx+i][2]*getMetaDer(k)) );
+    1495             :         }
+    1496             :       }
+    1497             :     }
+    1498        1776 :     setBoxDerivatives(val, -deriv_box);
+    1499             :   }
+    1500         192 : }
+    1501             : 
+    1502         192 : void SAXS::update() {
+    1503             :   // write status file
+    1504         192 :   if(getWstride()>0&& (getStep()%getWstride()==0 || getCPT()) ) writeStatus();
+    1505         192 : }
+    1506             : 
+    1507          10 : unsigned SAXS::getOnebeadMapping(const PDB &pdb, const std::vector<AtomNumber> &atoms) {
+    1508          10 :   std::vector<std::string> chains; pdb.getChainNames( chains );
+    1509             :   std::vector<std::vector<std::string> > AtomResidueName;
+    1510             : 
+    1511          10 :   atoms_masses.resize(atoms.size());
+    1512          10 :   residue_atom.resize(atoms.size());
+    1513             : 
+    1514             :   // cycle over chains
+    1515          24 :   for(unsigned i=0; i<chains.size(); ++i) {
+    1516             :     unsigned start, end;
+    1517             :     std::string errmsg;
+    1518          14 :     pdb.getResidueRange(chains[i], start, end, errmsg);
+    1519          14 :     AtomResidueName.resize(2);
+    1520             :     // cycle over residues
+    1521        2110 :     for(unsigned res=start; res<=end; res++) {
+    1522        2096 :       std::string Rname = pdb.getResidueName(res, chains[i]);
+    1523        2096 :       Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    1524        2096 :       std::vector<AtomNumber> res_atoms = pdb.getAtomsInResidue(res, chains[i]);
+    1525             :       unsigned first_time=1;
+    1526        2096 :       std::vector<std::vector<unsigned> > tmp_residue_atom; tmp_residue_atom.resize(3);
+    1527             :       // cycle over atoms
+    1528       37562 :       for(unsigned a=0; a<res_atoms.size(); a++) {
+    1529             :         // operations shared among all beads
+    1530       35466 :         std::string Aname=pdb.getAtomName(res_atoms[a]);
+    1531       35466 :         AtomResidueName[0].push_back(Aname);
+    1532       35466 :         AtomResidueName[1].push_back(Rname);
+    1533             :         char type;
+    1534       35466 :         char first = Aname.at(0);
+    1535             :         // We assume that element symbol is first letter, if not a number
+    1536       35466 :         if (!isdigit(first)) {
+    1537             :           type = first;
+    1538             :           // otherwise is the second
+    1539             :         } else {
+    1540           0 :           type = Aname.at(1);
+    1541             :         }
+    1542       35466 :         if (type == 'H') atoms_masses[res_atoms[a].index()] = 1.008;
+    1543       10384 :         else if(type == 'C') atoms_masses[res_atoms[a].index()] = 12.011;
+    1544        2772 :         else if(type == 'N') atoms_masses[res_atoms[a].index()] = 14.007;
+    1545        3270 :         else if(type == 'O') atoms_masses[res_atoms[a].index()] = 15.999;
+    1546          90 :         else if(type == 'S') atoms_masses[res_atoms[a].index()] = 32.065;
+    1547          32 :         else if(type == 'P') atoms_masses[res_atoms[a].index()] = 30.974;
+    1548             :         else {
+    1549           0 :           error("Unknown element in mass extraction\n");
+    1550             :         }
+    1551       70932 :         if(pdb.allowedResidue("protein",Rname)) {
+    1552       34390 :           if(first_time) {
+    1553        2060 :             atoms_per_bead.push_back(res_atoms.size());
+    1554             :             first_time = 0;
+    1555             :           }
+    1556       34390 :           residue_atom[res_atoms[a].index()] = atoms_per_bead.size()-1;
+    1557             :         } else {
+    1558             :           // check for nucleic acids
+    1559             :           // Pentose bead
+    1560        4840 :           if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  || Aname=="O3'"  ||
+    1561        3940 :               Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  || Aname=="C1'"  || Aname=="H5'"  ||
+    1562        3076 :               Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  || Aname=="H2'"  || Aname=="H2''" ||
+    1563        2660 :               Aname=="H2'2" || Aname=="H1'"  || Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" ||
+    1564        3536 :               Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T"  ||
+    1565             :               Aname=="H3T" ) {
+    1566         584 :             tmp_residue_atom[0].push_back(res_atoms[a].index());
+    1567             :           }
+    1568             :           // Nucleobase bead
+    1569        2172 :           else if(Aname=="N1"  || Aname=="N2"  || Aname=="N3"  || Aname=="N4"  || Aname=="N6"  ||
+    1570        1884 :                   Aname=="N7"  || Aname=="N9"  || Aname=="C2"  || Aname=="C4"  || Aname=="C5"  ||
+    1571        1272 :                   Aname=="C6"  || Aname=="C7"  || Aname=="C8"  || Aname=="O2"  || Aname=="O4"  ||
+    1572         912 :                   Aname=="O6"  || Aname=="H1"  || Aname=="H2"  || Aname=="H3"  || Aname=="H5"  ||
+    1573         480 :                   Aname=="H6"  || Aname=="H8"  || Aname=="H21" || Aname=="H22" || Aname=="H41" ||
+    1574         972 :                   Aname=="H42" || Aname=="H61" || Aname=="H62" || Aname=="H71" || Aname=="H72" ||
+    1575             :                   Aname=="H73" ) {
+    1576         396 :             tmp_residue_atom[1].push_back(res_atoms[a].index());
+    1577             :           }
+    1578             :           // PO2 bead
+    1579          96 :           else if(Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" || Aname=="O1P" ||
+    1580          96 :                   Aname=="O2P" || Aname=="O3P" ) {
+    1581          96 :             tmp_residue_atom[2].push_back(res_atoms[a].index());
+    1582             :           }
+    1583             :           // error
+    1584           0 :           else error("Atom name "+Aname+" cannot be indexed to any bead. Check the PDB.");
+    1585             :         }
+    1586             :       }
+    1587        4192 :       if(!pdb.allowedResidue("protein",Rname)) {
+    1588          36 :         atoms_per_bead.push_back(tmp_residue_atom[0].size());
+    1589         620 :         for(unsigned tmp_i=0; tmp_i<tmp_residue_atom[0].size(); tmp_i++) residue_atom[tmp_residue_atom[0][tmp_i]]=atoms_per_bead.size()-1;
+    1590          36 :         atoms_per_bead.push_back(tmp_residue_atom[1].size());
+    1591         432 :         for(unsigned tmp_i=0; tmp_i<tmp_residue_atom[1].size(); tmp_i++) residue_atom[tmp_residue_atom[1][tmp_i]]=atoms_per_bead.size()-1;
+    1592          36 :         if(tmp_residue_atom[2].size()>0) {
+    1593          32 :           atoms_per_bead.push_back(tmp_residue_atom[2].size());
+    1594         128 :           for(unsigned tmp_i=0; tmp_i<tmp_residue_atom[2].size(); tmp_i++) residue_atom[tmp_residue_atom[2][tmp_i]]=atoms_per_bead.size()-1;
+    1595             :         }
+    1596             :       }
+    1597        2096 :     }
+    1598             :   }
+    1599          10 :   readLCPOparam(AtomResidueName, atoms.size());
+    1600          10 :   return atoms_per_bead.size();
+    1601          10 : }
+    1602             : 
+    1603           8 : void SAXS::getMartiniFFparam(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter)
+    1604             : {
+    1605           8 :   parameter[ALA_BB].push_back(9.045);
+    1606           8 :   parameter[ALA_BB].push_back(-0.098114);
+    1607           8 :   parameter[ALA_BB].push_back(7.54281);
+    1608           8 :   parameter[ALA_BB].push_back(-1.97438);
+    1609           8 :   parameter[ALA_BB].push_back(-8.32689);
+    1610           8 :   parameter[ALA_BB].push_back(6.09318);
+    1611           8 :   parameter[ALA_BB].push_back(-1.18913);
+    1612             : 
+    1613           8 :   parameter[ARG_BB].push_back(10.729);
+    1614           8 :   parameter[ARG_BB].push_back(-0.0392574);
+    1615           8 :   parameter[ARG_BB].push_back(1.15382);
+    1616           8 :   parameter[ARG_BB].push_back(-0.155999);
+    1617           8 :   parameter[ARG_BB].push_back(-2.43619);
+    1618           8 :   parameter[ARG_BB].push_back(1.72922);
+    1619           8 :   parameter[ARG_BB].push_back(-0.33799);
+    1620             : 
+    1621           8 :   parameter[ARG_SC1].push_back(-2.796);
+    1622           8 :   parameter[ARG_SC1].push_back(0.472403);
+    1623           8 :   parameter[ARG_SC1].push_back(8.07424);
+    1624           8 :   parameter[ARG_SC1].push_back(4.37299);
+    1625           8 :   parameter[ARG_SC1].push_back(-10.7398);
+    1626           8 :   parameter[ARG_SC1].push_back(4.95677);
+    1627           8 :   parameter[ARG_SC1].push_back(-0.725797);
+    1628             : 
+    1629           8 :   parameter[ARG_SC2].push_back(15.396);
+    1630           8 :   parameter[ARG_SC2].push_back(0.0636736);
+    1631           8 :   parameter[ARG_SC2].push_back(-1.258);
+    1632           8 :   parameter[ARG_SC2].push_back(1.93135);
+    1633           8 :   parameter[ARG_SC2].push_back(-4.45031);
+    1634           8 :   parameter[ARG_SC2].push_back(2.49356);
+    1635           8 :   parameter[ARG_SC2].push_back(-0.410721);
+    1636             : 
+    1637           8 :   parameter[ASN_BB].push_back(10.738);
+    1638           8 :   parameter[ASN_BB].push_back(-0.0402162);
+    1639           8 :   parameter[ASN_BB].push_back(1.03007);
+    1640           8 :   parameter[ASN_BB].push_back(-0.254174);
+    1641           8 :   parameter[ASN_BB].push_back(-2.12015);
+    1642           8 :   parameter[ASN_BB].push_back(1.55535);
+    1643           8 :   parameter[ASN_BB].push_back(-0.30963);
+    1644             : 
+    1645           8 :   parameter[ASN_SC1].push_back(9.249);
+    1646           8 :   parameter[ASN_SC1].push_back(-0.0148678);
+    1647           8 :   parameter[ASN_SC1].push_back(5.52169);
+    1648           8 :   parameter[ASN_SC1].push_back(0.00853212);
+    1649           8 :   parameter[ASN_SC1].push_back(-6.71992);
+    1650           8 :   parameter[ASN_SC1].push_back(3.93622);
+    1651           8 :   parameter[ASN_SC1].push_back(-0.64973);
+    1652             : 
+    1653           8 :   parameter[ASP_BB].push_back(10.695);
+    1654           8 :   parameter[ASP_BB].push_back(-0.0410247);
+    1655           8 :   parameter[ASP_BB].push_back(1.03656);
+    1656           8 :   parameter[ASP_BB].push_back(-0.298558);
+    1657           8 :   parameter[ASP_BB].push_back(-2.06064);
+    1658           8 :   parameter[ASP_BB].push_back(1.53495);
+    1659           8 :   parameter[ASP_BB].push_back(-0.308365);
+    1660             : 
+    1661           8 :   parameter[ASP_SC1].push_back(9.476);
+    1662           8 :   parameter[ASP_SC1].push_back(-0.0254664);
+    1663           8 :   parameter[ASP_SC1].push_back(5.57899);
+    1664           8 :   parameter[ASP_SC1].push_back(-0.395027);
+    1665           8 :   parameter[ASP_SC1].push_back(-5.9407);
+    1666           8 :   parameter[ASP_SC1].push_back(3.48836);
+    1667           8 :   parameter[ASP_SC1].push_back(-0.569402);
+    1668             : 
+    1669           8 :   parameter[CYS_BB].push_back(10.698);
+    1670           8 :   parameter[CYS_BB].push_back(-0.0233493);
+    1671           8 :   parameter[CYS_BB].push_back(1.18257);
+    1672           8 :   parameter[CYS_BB].push_back(0.0684464);
+    1673           8 :   parameter[CYS_BB].push_back(-2.792);
+    1674           8 :   parameter[CYS_BB].push_back(1.88995);
+    1675           8 :   parameter[CYS_BB].push_back(-0.360229);
+    1676             : 
+    1677           8 :   parameter[CYS_SC1].push_back(8.199);
+    1678           8 :   parameter[CYS_SC1].push_back(-0.0261569);
+    1679           8 :   parameter[CYS_SC1].push_back(6.79677);
+    1680           8 :   parameter[CYS_SC1].push_back(-0.343845);
+    1681           8 :   parameter[CYS_SC1].push_back(-5.03578);
+    1682           8 :   parameter[CYS_SC1].push_back(2.7076);
+    1683           8 :   parameter[CYS_SC1].push_back(-0.420714);
+    1684             : 
+    1685           8 :   parameter[GLN_BB].push_back(10.728);
+    1686           8 :   parameter[GLN_BB].push_back(-0.0391984);
+    1687           8 :   parameter[GLN_BB].push_back(1.09264);
+    1688           8 :   parameter[GLN_BB].push_back(-0.261555);
+    1689           8 :   parameter[GLN_BB].push_back(-2.21245);
+    1690           8 :   parameter[GLN_BB].push_back(1.62071);
+    1691           8 :   parameter[GLN_BB].push_back(-0.322325);
+    1692             : 
+    1693           8 :   parameter[GLN_SC1].push_back(8.317);
+    1694           8 :   parameter[GLN_SC1].push_back(-0.229045);
+    1695           8 :   parameter[GLN_SC1].push_back(12.6338);
+    1696           8 :   parameter[GLN_SC1].push_back(-7.6719);
+    1697           8 :   parameter[GLN_SC1].push_back(-5.8376);
+    1698           8 :   parameter[GLN_SC1].push_back(5.53784);
+    1699           8 :   parameter[GLN_SC1].push_back(-1.12604);
+    1700             : 
+    1701           8 :   parameter[GLU_BB].push_back(10.694);
+    1702           8 :   parameter[GLU_BB].push_back(-0.0521961);
+    1703           8 :   parameter[GLU_BB].push_back(1.11153);
+    1704           8 :   parameter[GLU_BB].push_back(-0.491995);
+    1705           8 :   parameter[GLU_BB].push_back(-1.86236);
+    1706           8 :   parameter[GLU_BB].push_back(1.45332);
+    1707           8 :   parameter[GLU_BB].push_back(-0.29708);
+    1708             : 
+    1709           8 :   parameter[GLU_SC1].push_back(8.544);
+    1710           8 :   parameter[GLU_SC1].push_back(-0.249555);
+    1711           8 :   parameter[GLU_SC1].push_back(12.8031);
+    1712           8 :   parameter[GLU_SC1].push_back(-8.42696);
+    1713           8 :   parameter[GLU_SC1].push_back(-4.66486);
+    1714           8 :   parameter[GLU_SC1].push_back(4.90004);
+    1715           8 :   parameter[GLU_SC1].push_back(-1.01204);
+    1716             : 
+    1717           8 :   parameter[GLY_BB].push_back(9.977);
+    1718           8 :   parameter[GLY_BB].push_back(-0.0285799);
+    1719           8 :   parameter[GLY_BB].push_back(1.84236);
+    1720           8 :   parameter[GLY_BB].push_back(-0.0315192);
+    1721           8 :   parameter[GLY_BB].push_back(-2.88326);
+    1722           8 :   parameter[GLY_BB].push_back(1.87323);
+    1723           8 :   parameter[GLY_BB].push_back(-0.345773);
+    1724             : 
+    1725           8 :   parameter[HIS_BB].push_back(10.721);
+    1726           8 :   parameter[HIS_BB].push_back(-0.0379337);
+    1727           8 :   parameter[HIS_BB].push_back(1.06028);
+    1728           8 :   parameter[HIS_BB].push_back(-0.236143);
+    1729           8 :   parameter[HIS_BB].push_back(-2.17819);
+    1730           8 :   parameter[HIS_BB].push_back(1.58357);
+    1731           8 :   parameter[HIS_BB].push_back(-0.31345);
+    1732             : 
+    1733           8 :   parameter[HIS_SC1].push_back(-0.424);
+    1734           8 :   parameter[HIS_SC1].push_back(0.665176);
+    1735           8 :   parameter[HIS_SC1].push_back(3.4369);
+    1736           8 :   parameter[HIS_SC1].push_back(2.93795);
+    1737           8 :   parameter[HIS_SC1].push_back(-5.18288);
+    1738           8 :   parameter[HIS_SC1].push_back(2.12381);
+    1739           8 :   parameter[HIS_SC1].push_back(-0.284224);
+    1740             : 
+    1741           8 :   parameter[HIS_SC2].push_back(5.363);
+    1742           8 :   parameter[HIS_SC2].push_back(-0.0176945);
+    1743           8 :   parameter[HIS_SC2].push_back(2.9506);
+    1744           8 :   parameter[HIS_SC2].push_back(-0.387018);
+    1745           8 :   parameter[HIS_SC2].push_back(-1.83951);
+    1746           8 :   parameter[HIS_SC2].push_back(0.9703);
+    1747           8 :   parameter[HIS_SC2].push_back(-0.1458);
+    1748             : 
+    1749           8 :   parameter[HIS_SC3].push_back(5.784);
+    1750           8 :   parameter[HIS_SC3].push_back(-0.0293129);
+    1751           8 :   parameter[HIS_SC3].push_back(2.74167);
+    1752           8 :   parameter[HIS_SC3].push_back(-0.520875);
+    1753           8 :   parameter[HIS_SC3].push_back(-1.62949);
+    1754           8 :   parameter[HIS_SC3].push_back(0.902379);
+    1755           8 :   parameter[HIS_SC3].push_back(-0.139957);
+    1756             : 
+    1757           8 :   parameter[ILE_BB].push_back(10.699);
+    1758           8 :   parameter[ILE_BB].push_back(-0.0188962);
+    1759           8 :   parameter[ILE_BB].push_back(1.217);
+    1760           8 :   parameter[ILE_BB].push_back(0.242481);
+    1761           8 :   parameter[ILE_BB].push_back(-3.13898);
+    1762           8 :   parameter[ILE_BB].push_back(2.07916);
+    1763           8 :   parameter[ILE_BB].push_back(-0.392574);
+    1764             : 
+    1765           8 :   parameter[ILE_SC1].push_back(-4.448);
+    1766           8 :   parameter[ILE_SC1].push_back(1.20996);
+    1767           8 :   parameter[ILE_SC1].push_back(11.5141);
+    1768           8 :   parameter[ILE_SC1].push_back(6.98895);
+    1769           8 :   parameter[ILE_SC1].push_back(-19.1948);
+    1770           8 :   parameter[ILE_SC1].push_back(9.89207);
+    1771           8 :   parameter[ILE_SC1].push_back(-1.60877);
+    1772             : 
+    1773           8 :   parameter[LEU_BB].push_back(10.692);
+    1774           8 :   parameter[LEU_BB].push_back(-0.0414917);
+    1775           8 :   parameter[LEU_BB].push_back(1.1077);
+    1776           8 :   parameter[LEU_BB].push_back(-0.288062);
+    1777           8 :   parameter[LEU_BB].push_back(-2.17187);
+    1778           8 :   parameter[LEU_BB].push_back(1.59879);
+    1779           8 :   parameter[LEU_BB].push_back(-0.318545);
+    1780             : 
+    1781           8 :   parameter[LEU_SC1].push_back(-4.448);
+    1782           8 :   parameter[LEU_SC1].push_back(2.1063);
+    1783           8 :   parameter[LEU_SC1].push_back(6.72381);
+    1784           8 :   parameter[LEU_SC1].push_back(14.6954);
+    1785           8 :   parameter[LEU_SC1].push_back(-23.7197);
+    1786           8 :   parameter[LEU_SC1].push_back(10.7247);
+    1787           8 :   parameter[LEU_SC1].push_back(-1.59146);
+    1788             : 
+    1789           8 :   parameter[LYS_BB].push_back(10.706);
+    1790           8 :   parameter[LYS_BB].push_back(-0.0468629);
+    1791           8 :   parameter[LYS_BB].push_back(1.09477);
+    1792           8 :   parameter[LYS_BB].push_back(-0.432751);
+    1793           8 :   parameter[LYS_BB].push_back(-1.94335);
+    1794           8 :   parameter[LYS_BB].push_back(1.49109);
+    1795           8 :   parameter[LYS_BB].push_back(-0.302589);
+    1796             : 
+    1797           8 :   parameter[LYS_SC1].push_back(-2.796);
+    1798           8 :   parameter[LYS_SC1].push_back(0.508044);
+    1799           8 :   parameter[LYS_SC1].push_back(7.91436);
+    1800           8 :   parameter[LYS_SC1].push_back(4.54097);
+    1801           8 :   parameter[LYS_SC1].push_back(-10.8051);
+    1802           8 :   parameter[LYS_SC1].push_back(4.96204);
+    1803           8 :   parameter[LYS_SC1].push_back(-0.724414);
+    1804             : 
+    1805           8 :   parameter[LYS_SC2].push_back(3.070);
+    1806           8 :   parameter[LYS_SC2].push_back(-0.0101448);
+    1807           8 :   parameter[LYS_SC2].push_back(4.67994);
+    1808           8 :   parameter[LYS_SC2].push_back(-0.792529);
+    1809           8 :   parameter[LYS_SC2].push_back(-2.09142);
+    1810           8 :   parameter[LYS_SC2].push_back(1.02933);
+    1811           8 :   parameter[LYS_SC2].push_back(-0.137787);
+    1812             : 
+    1813           8 :   parameter[MET_BB].push_back(10.671);
+    1814           8 :   parameter[MET_BB].push_back(-0.0433724);
+    1815           8 :   parameter[MET_BB].push_back(1.13784);
+    1816           8 :   parameter[MET_BB].push_back(-0.40768);
+    1817           8 :   parameter[MET_BB].push_back(-2.00555);
+    1818           8 :   parameter[MET_BB].push_back(1.51673);
+    1819           8 :   parameter[MET_BB].push_back(-0.305547);
+    1820             : 
+    1821           8 :   parameter[MET_SC1].push_back(5.85);
+    1822           8 :   parameter[MET_SC1].push_back(-0.0485798);
+    1823           8 :   parameter[MET_SC1].push_back(17.0391);
+    1824           8 :   parameter[MET_SC1].push_back(-3.65327);
+    1825           8 :   parameter[MET_SC1].push_back(-13.174);
+    1826           8 :   parameter[MET_SC1].push_back(8.68286);
+    1827           8 :   parameter[MET_SC1].push_back(-1.56095);
+    1828             : 
+    1829           8 :   parameter[PHE_BB].push_back(10.741);
+    1830           8 :   parameter[PHE_BB].push_back(-0.0317275);
+    1831           8 :   parameter[PHE_BB].push_back(1.15599);
+    1832           8 :   parameter[PHE_BB].push_back(0.0276187);
+    1833           8 :   parameter[PHE_BB].push_back(-2.74757);
+    1834           8 :   parameter[PHE_BB].push_back(1.88783);
+    1835           8 :   parameter[PHE_BB].push_back(-0.363525);
+    1836             : 
+    1837           8 :   parameter[PHE_SC1].push_back(-0.636);
+    1838           8 :   parameter[PHE_SC1].push_back(0.527882);
+    1839           8 :   parameter[PHE_SC1].push_back(6.77612);
+    1840           8 :   parameter[PHE_SC1].push_back(3.18508);
+    1841           8 :   parameter[PHE_SC1].push_back(-8.92826);
+    1842           8 :   parameter[PHE_SC1].push_back(4.29752);
+    1843           8 :   parameter[PHE_SC1].push_back(-0.65187);
+    1844             : 
+    1845           8 :   parameter[PHE_SC2].push_back(-0.424);
+    1846           8 :   parameter[PHE_SC2].push_back(0.389174);
+    1847           8 :   parameter[PHE_SC2].push_back(4.11761);
+    1848           8 :   parameter[PHE_SC2].push_back(2.29527);
+    1849           8 :   parameter[PHE_SC2].push_back(-4.7652);
+    1850           8 :   parameter[PHE_SC2].push_back(1.97023);
+    1851           8 :   parameter[PHE_SC2].push_back(-0.262318);
+    1852             : 
+    1853           8 :   parameter[PHE_SC3].push_back(-0.424);
+    1854           8 :   parameter[PHE_SC3].push_back(0.38927);
+    1855           8 :   parameter[PHE_SC3].push_back(4.11708);
+    1856           8 :   parameter[PHE_SC3].push_back(2.29623);
+    1857           8 :   parameter[PHE_SC3].push_back(-4.76592);
+    1858           8 :   parameter[PHE_SC3].push_back(1.97055);
+    1859           8 :   parameter[PHE_SC3].push_back(-0.262381);
+    1860             : 
+    1861           8 :   parameter[PRO_BB].push_back(11.434);
+    1862           8 :   parameter[PRO_BB].push_back(-0.033323);
+    1863           8 :   parameter[PRO_BB].push_back(0.472014);
+    1864           8 :   parameter[PRO_BB].push_back(-0.290854);
+    1865           8 :   parameter[PRO_BB].push_back(-1.81409);
+    1866           8 :   parameter[PRO_BB].push_back(1.39751);
+    1867           8 :   parameter[PRO_BB].push_back(-0.280407);
+    1868             : 
+    1869           8 :   parameter[PRO_SC1].push_back(-2.796);
+    1870           8 :   parameter[PRO_SC1].push_back(0.95668);
+    1871           8 :   parameter[PRO_SC1].push_back(6.84197);
+    1872           8 :   parameter[PRO_SC1].push_back(6.43774);
+    1873           8 :   parameter[PRO_SC1].push_back(-12.5068);
+    1874           8 :   parameter[PRO_SC1].push_back(5.64597);
+    1875           8 :   parameter[PRO_SC1].push_back(-0.825206);
+    1876             : 
+    1877           8 :   parameter[SER_BB].push_back(10.699);
+    1878           8 :   parameter[SER_BB].push_back(-0.0325828);
+    1879           8 :   parameter[SER_BB].push_back(1.20329);
+    1880           8 :   parameter[SER_BB].push_back(-0.0674351);
+    1881           8 :   parameter[SER_BB].push_back(-2.60749);
+    1882           8 :   parameter[SER_BB].push_back(1.80318);
+    1883           8 :   parameter[SER_BB].push_back(-0.346803);
+    1884             : 
+    1885           8 :   parameter[SER_SC1].push_back(3.298);
+    1886           8 :   parameter[SER_SC1].push_back(-0.0366801);
+    1887           8 :   parameter[SER_SC1].push_back(5.11077);
+    1888           8 :   parameter[SER_SC1].push_back(-1.46774);
+    1889           8 :   parameter[SER_SC1].push_back(-1.48421);
+    1890           8 :   parameter[SER_SC1].push_back(0.800326);
+    1891           8 :   parameter[SER_SC1].push_back(-0.108314);
+    1892             : 
+    1893           8 :   parameter[THR_BB].push_back(10.697);
+    1894           8 :   parameter[THR_BB].push_back(-0.0242955);
+    1895           8 :   parameter[THR_BB].push_back(1.24671);
+    1896           8 :   parameter[THR_BB].push_back(0.146423);
+    1897           8 :   parameter[THR_BB].push_back(-2.97429);
+    1898           8 :   parameter[THR_BB].push_back(1.97513);
+    1899           8 :   parameter[THR_BB].push_back(-0.371479);
+    1900             : 
+    1901           8 :   parameter[THR_SC1].push_back(2.366);
+    1902           8 :   parameter[THR_SC1].push_back(0.0297604);
+    1903           8 :   parameter[THR_SC1].push_back(11.9216);
+    1904           8 :   parameter[THR_SC1].push_back(-9.32503);
+    1905           8 :   parameter[THR_SC1].push_back(1.9396);
+    1906           8 :   parameter[THR_SC1].push_back(0.0804861);
+    1907           8 :   parameter[THR_SC1].push_back(-0.0302721);
+    1908             : 
+    1909           8 :   parameter[TRP_BB].push_back(10.689);
+    1910           8 :   parameter[TRP_BB].push_back(-0.0265879);
+    1911           8 :   parameter[TRP_BB].push_back(1.17819);
+    1912           8 :   parameter[TRP_BB].push_back(0.0386457);
+    1913           8 :   parameter[TRP_BB].push_back(-2.75634);
+    1914           8 :   parameter[TRP_BB].push_back(1.88065);
+    1915           8 :   parameter[TRP_BB].push_back(-0.360217);
+    1916             : 
+    1917           8 :   parameter[TRP_SC1].push_back(0.084);
+    1918           8 :   parameter[TRP_SC1].push_back(0.752407);
+    1919           8 :   parameter[TRP_SC1].push_back(5.3802);
+    1920           8 :   parameter[TRP_SC1].push_back(4.09281);
+    1921           8 :   parameter[TRP_SC1].push_back(-9.28029);
+    1922           8 :   parameter[TRP_SC1].push_back(4.45923);
+    1923           8 :   parameter[TRP_SC1].push_back(-0.689008);
+    1924             : 
+    1925           8 :   parameter[TRP_SC2].push_back(5.739);
+    1926           8 :   parameter[TRP_SC2].push_back(0.0298492);
+    1927           8 :   parameter[TRP_SC2].push_back(4.60446);
+    1928           8 :   parameter[TRP_SC2].push_back(1.34463);
+    1929           8 :   parameter[TRP_SC2].push_back(-5.69968);
+    1930           8 :   parameter[TRP_SC2].push_back(2.84924);
+    1931           8 :   parameter[TRP_SC2].push_back(-0.433781);
+    1932             : 
+    1933           8 :   parameter[TRP_SC3].push_back(-0.424);
+    1934           8 :   parameter[TRP_SC3].push_back(0.388576);
+    1935           8 :   parameter[TRP_SC3].push_back(4.11859);
+    1936           8 :   parameter[TRP_SC3].push_back(2.29485);
+    1937           8 :   parameter[TRP_SC3].push_back(-4.76255);
+    1938           8 :   parameter[TRP_SC3].push_back(1.96849);
+    1939           8 :   parameter[TRP_SC3].push_back(-0.262015);
+    1940             : 
+    1941           8 :   parameter[TRP_SC4].push_back(-0.424);
+    1942           8 :   parameter[TRP_SC4].push_back(0.387685);
+    1943           8 :   parameter[TRP_SC4].push_back(4.12153);
+    1944           8 :   parameter[TRP_SC4].push_back(2.29144);
+    1945           8 :   parameter[TRP_SC4].push_back(-4.7589);
+    1946           8 :   parameter[TRP_SC4].push_back(1.96686);
+    1947           8 :   parameter[TRP_SC4].push_back(-0.261786);
+    1948             : 
+    1949           8 :   parameter[TYR_BB].push_back(10.689);
+    1950           8 :   parameter[TYR_BB].push_back(-0.0193526);
+    1951           8 :   parameter[TYR_BB].push_back(1.18241);
+    1952           8 :   parameter[TYR_BB].push_back(0.207318);
+    1953           8 :   parameter[TYR_BB].push_back(-3.0041);
+    1954           8 :   parameter[TYR_BB].push_back(1.99335);
+    1955           8 :   parameter[TYR_BB].push_back(-0.376482);
+    1956             : 
+    1957           8 :   parameter[TYR_SC1].push_back(-0.636);
+    1958           8 :   parameter[TYR_SC1].push_back(0.528902);
+    1959           8 :   parameter[TYR_SC1].push_back(6.78168);
+    1960           8 :   parameter[TYR_SC1].push_back(3.17769);
+    1961           8 :   parameter[TYR_SC1].push_back(-8.93667);
+    1962           8 :   parameter[TYR_SC1].push_back(4.30692);
+    1963           8 :   parameter[TYR_SC1].push_back(-0.653993);
+    1964             : 
+    1965           8 :   parameter[TYR_SC2].push_back(-0.424);
+    1966           8 :   parameter[TYR_SC2].push_back(0.388811);
+    1967           8 :   parameter[TYR_SC2].push_back(4.11851);
+    1968           8 :   parameter[TYR_SC2].push_back(2.29545);
+    1969           8 :   parameter[TYR_SC2].push_back(-4.7668);
+    1970           8 :   parameter[TYR_SC2].push_back(1.97131);
+    1971           8 :   parameter[TYR_SC2].push_back(-0.262534);
+    1972             : 
+    1973           8 :   parameter[TYR_SC3].push_back(4.526);
+    1974           8 :   parameter[TYR_SC3].push_back(-0.00381305);
+    1975           8 :   parameter[TYR_SC3].push_back(5.8567);
+    1976           8 :   parameter[TYR_SC3].push_back(-0.214086);
+    1977           8 :   parameter[TYR_SC3].push_back(-4.63649);
+    1978           8 :   parameter[TYR_SC3].push_back(2.52869);
+    1979           8 :   parameter[TYR_SC3].push_back(-0.39894);
+    1980             : 
+    1981           8 :   parameter[VAL_BB].push_back(10.691);
+    1982           8 :   parameter[VAL_BB].push_back(-0.0162929);
+    1983           8 :   parameter[VAL_BB].push_back(1.24446);
+    1984           8 :   parameter[VAL_BB].push_back(0.307914);
+    1985           8 :   parameter[VAL_BB].push_back(-3.27446);
+    1986           8 :   parameter[VAL_BB].push_back(2.14788);
+    1987           8 :   parameter[VAL_BB].push_back(-0.403259);
+    1988             : 
+    1989           8 :   parameter[VAL_SC1].push_back(-3.516);
+    1990           8 :   parameter[VAL_SC1].push_back(1.62307);
+    1991           8 :   parameter[VAL_SC1].push_back(5.43064);
+    1992           8 :   parameter[VAL_SC1].push_back(9.28809);
+    1993           8 :   parameter[VAL_SC1].push_back(-14.9927);
+    1994           8 :   parameter[VAL_SC1].push_back(6.6133);
+    1995           8 :   parameter[VAL_SC1].push_back(-0.964977);
+    1996             : 
+    1997           8 :   parameter[A_BB1].push_back(32.88500000);
+    1998           8 :   parameter[A_BB1].push_back(0.08339900);
+    1999           8 :   parameter[A_BB1].push_back(-7.36054400);
+    2000           8 :   parameter[A_BB1].push_back(2.19220300);
+    2001           8 :   parameter[A_BB1].push_back(-3.56523400);
+    2002           8 :   parameter[A_BB1].push_back(2.33326900);
+    2003           8 :   parameter[A_BB1].push_back(-0.39785500);
+    2004             : 
+    2005           8 :   parameter[A_BB2].push_back(3.80600000);
+    2006           8 :   parameter[A_BB2].push_back(-0.10727600);
+    2007           8 :   parameter[A_BB2].push_back(9.58854100);
+    2008           8 :   parameter[A_BB2].push_back(-6.23740500);
+    2009           8 :   parameter[A_BB2].push_back(-0.48267300);
+    2010           8 :   parameter[A_BB2].push_back(1.14119500);
+    2011           8 :   parameter[A_BB2].push_back(-0.21385600);
+    2012             : 
+    2013           8 :   parameter[A_BB3].push_back(3.59400000);
+    2014           8 :   parameter[A_BB3].push_back(0.04537300);
+    2015           8 :   parameter[A_BB3].push_back(9.59178900);
+    2016           8 :   parameter[A_BB3].push_back(-1.29202200);
+    2017           8 :   parameter[A_BB3].push_back(-7.10851000);
+    2018           8 :   parameter[A_BB3].push_back(4.05571200);
+    2019           8 :   parameter[A_BB3].push_back(-0.63372500);
+    2020             : 
+    2021           8 :   parameter[A_SC1].push_back(6.67100000);
+    2022           8 :   parameter[A_SC1].push_back(-0.00855300);
+    2023           8 :   parameter[A_SC1].push_back(1.63222400);
+    2024           8 :   parameter[A_SC1].push_back(-0.06466200);
+    2025           8 :   parameter[A_SC1].push_back(-1.48694200);
+    2026           8 :   parameter[A_SC1].push_back(0.78544600);
+    2027           8 :   parameter[A_SC1].push_back(-0.12083500);
+    2028             : 
+    2029           8 :   parameter[A_SC2].push_back(5.95100000);
+    2030           8 :   parameter[A_SC2].push_back(-0.02606600);
+    2031           8 :   parameter[A_SC2].push_back(2.54399900);
+    2032           8 :   parameter[A_SC2].push_back(-0.48436900);
+    2033           8 :   parameter[A_SC2].push_back(-1.55357400);
+    2034           8 :   parameter[A_SC2].push_back(0.86466900);
+    2035           8 :   parameter[A_SC2].push_back(-0.13509000);
+    2036             : 
+    2037           8 :   parameter[A_SC3].push_back(11.39400000);
+    2038           8 :   parameter[A_SC3].push_back(0.00871300);
+    2039           8 :   parameter[A_SC3].push_back(-0.23891300);
+    2040           8 :   parameter[A_SC3].push_back(0.48919400);
+    2041           8 :   parameter[A_SC3].push_back(-1.75289400);
+    2042           8 :   parameter[A_SC3].push_back(0.99267500);
+    2043           8 :   parameter[A_SC3].push_back(-0.16291300);
+    2044             : 
+    2045           8 :   parameter[A_SC4].push_back(6.45900000);
+    2046           8 :   parameter[A_SC4].push_back(0.01990600);
+    2047           8 :   parameter[A_SC4].push_back(4.17970400);
+    2048           8 :   parameter[A_SC4].push_back(0.97629900);
+    2049           8 :   parameter[A_SC4].push_back(-5.03297800);
+    2050           8 :   parameter[A_SC4].push_back(2.55576700);
+    2051           8 :   parameter[A_SC4].push_back(-0.39150500);
+    2052             : 
+    2053           8 :   parameter[A_3TE].push_back(4.23000000);
+    2054           8 :   parameter[A_3TE].push_back(0.00064800);
+    2055           8 :   parameter[A_3TE].push_back(0.92124600);
+    2056           8 :   parameter[A_3TE].push_back(0.08064300);
+    2057           8 :   parameter[A_3TE].push_back(-0.39054400);
+    2058           8 :   parameter[A_3TE].push_back(0.12429100);
+    2059           8 :   parameter[A_3TE].push_back(-0.01122700);
+    2060             : 
+    2061           8 :   parameter[A_5TE].push_back(4.23000000);
+    2062           8 :   parameter[A_5TE].push_back(0.00039300);
+    2063           8 :   parameter[A_5TE].push_back(0.92305100);
+    2064           8 :   parameter[A_5TE].push_back(0.07747500);
+    2065           8 :   parameter[A_5TE].push_back(-0.38792100);
+    2066           8 :   parameter[A_5TE].push_back(0.12323800);
+    2067           8 :   parameter[A_5TE].push_back(-0.01106600);
+    2068             : 
+    2069           8 :   parameter[A_TE3].push_back(7.82400000);
+    2070           8 :   parameter[A_TE3].push_back(-0.04881000);
+    2071           8 :   parameter[A_TE3].push_back(8.21557900);
+    2072           8 :   parameter[A_TE3].push_back(-0.89491400);
+    2073           8 :   parameter[A_TE3].push_back(-9.54293700);
+    2074           8 :   parameter[A_TE3].push_back(6.33122200);
+    2075           8 :   parameter[A_TE3].push_back(-1.16672900);
+    2076             : 
+    2077           8 :   parameter[A_TE5].push_back(8.03600000);
+    2078           8 :   parameter[A_TE5].push_back(0.01641200);
+    2079           8 :   parameter[A_TE5].push_back(5.14902200);
+    2080           8 :   parameter[A_TE5].push_back(0.83419700);
+    2081           8 :   parameter[A_TE5].push_back(-7.59068300);
+    2082           8 :   parameter[A_TE5].push_back(4.52063200);
+    2083           8 :   parameter[A_TE5].push_back(-0.78260800);
+    2084             : 
+    2085           8 :   parameter[C_BB1].push_back(32.88500000);
+    2086           8 :   parameter[C_BB1].push_back(0.08311100);
+    2087           8 :   parameter[C_BB1].push_back(-7.35432100);
+    2088           8 :   parameter[C_BB1].push_back(2.18610000);
+    2089           8 :   parameter[C_BB1].push_back(-3.55788300);
+    2090           8 :   parameter[C_BB1].push_back(2.32918700);
+    2091           8 :   parameter[C_BB1].push_back(-0.39720000);
+    2092             : 
+    2093           8 :   parameter[C_BB2].push_back(3.80600000);
+    2094           8 :   parameter[C_BB2].push_back(-0.10808100);
+    2095           8 :   parameter[C_BB2].push_back(9.61612600);
+    2096           8 :   parameter[C_BB2].push_back(-6.28595400);
+    2097           8 :   parameter[C_BB2].push_back(-0.45187000);
+    2098           8 :   parameter[C_BB2].push_back(1.13326000);
+    2099           8 :   parameter[C_BB2].push_back(-0.21320300);
+    2100             : 
+    2101           8 :   parameter[C_BB3].push_back(3.59400000);
+    2102           8 :   parameter[C_BB3].push_back(0.04484200);
+    2103           8 :   parameter[C_BB3].push_back(9.61919800);
+    2104           8 :   parameter[C_BB3].push_back(-1.33582800);
+    2105           8 :   parameter[C_BB3].push_back(-7.07200400);
+    2106           8 :   parameter[C_BB3].push_back(4.03952900);
+    2107           8 :   parameter[C_BB3].push_back(-0.63098200);
+    2108             : 
+    2109           8 :   parameter[C_SC1].push_back(5.95100000);
+    2110           8 :   parameter[C_SC1].push_back(-0.02911300);
+    2111           8 :   parameter[C_SC1].push_back(2.59700400);
+    2112           8 :   parameter[C_SC1].push_back(-0.55507700);
+    2113           8 :   parameter[C_SC1].push_back(-1.56344600);
+    2114           8 :   parameter[C_SC1].push_back(0.88956200);
+    2115           8 :   parameter[C_SC1].push_back(-0.14061300);
+    2116             : 
+    2117           8 :   parameter[C_SC2].push_back(11.62100000);
+    2118           8 :   parameter[C_SC2].push_back(0.01366100);
+    2119           8 :   parameter[C_SC2].push_back(-0.25959200);
+    2120           8 :   parameter[C_SC2].push_back(0.48918300);
+    2121           8 :   parameter[C_SC2].push_back(-1.52550500);
+    2122           8 :   parameter[C_SC2].push_back(0.83644100);
+    2123           8 :   parameter[C_SC2].push_back(-0.13407300);
+    2124             : 
+    2125           8 :   parameter[C_SC3].push_back(5.01900000);
+    2126           8 :   parameter[C_SC3].push_back(-0.03276100);
+    2127           8 :   parameter[C_SC3].push_back(5.53776900);
+    2128           8 :   parameter[C_SC3].push_back(-0.95105000);
+    2129           8 :   parameter[C_SC3].push_back(-3.71130800);
+    2130           8 :   parameter[C_SC3].push_back(2.16146000);
+    2131           8 :   parameter[C_SC3].push_back(-0.34918600);
+    2132             : 
+    2133           8 :   parameter[C_3TE].push_back(4.23000000);
+    2134           8 :   parameter[C_3TE].push_back(0.00057300);
+    2135           8 :   parameter[C_3TE].push_back(0.92174800);
+    2136           8 :   parameter[C_3TE].push_back(0.07964500);
+    2137           8 :   parameter[C_3TE].push_back(-0.38965700);
+    2138           8 :   parameter[C_3TE].push_back(0.12392500);
+    2139           8 :   parameter[C_3TE].push_back(-0.01117000);
+    2140             : 
+    2141           8 :   parameter[C_5TE].push_back(4.23000000);
+    2142           8 :   parameter[C_5TE].push_back(0.00071000);
+    2143           8 :   parameter[C_5TE].push_back(0.92082800);
+    2144           8 :   parameter[C_5TE].push_back(0.08150600);
+    2145           8 :   parameter[C_5TE].push_back(-0.39127000);
+    2146           8 :   parameter[C_5TE].push_back(0.12455900);
+    2147           8 :   parameter[C_5TE].push_back(-0.01126300);
+    2148             : 
+    2149           8 :   parameter[C_TE3].push_back(7.82400000);
+    2150           8 :   parameter[C_TE3].push_back(-0.05848300);
+    2151           8 :   parameter[C_TE3].push_back(8.29319900);
+    2152           8 :   parameter[C_TE3].push_back(-1.12563800);
+    2153           8 :   parameter[C_TE3].push_back(-9.42197600);
+    2154           8 :   parameter[C_TE3].push_back(6.35441700);
+    2155           8 :   parameter[C_TE3].push_back(-1.18356900);
+    2156             : 
+    2157           8 :   parameter[C_TE5].push_back(8.03600000);
+    2158           8 :   parameter[C_TE5].push_back(0.00493500);
+    2159           8 :   parameter[C_TE5].push_back(4.92622000);
+    2160           8 :   parameter[C_TE5].push_back(0.64810700);
+    2161           8 :   parameter[C_TE5].push_back(-7.05100000);
+    2162           8 :   parameter[C_TE5].push_back(4.26064400);
+    2163           8 :   parameter[C_TE5].push_back(-0.74819100);
+    2164             : 
+    2165           8 :   parameter[G_BB1].push_back(32.88500000);
+    2166           8 :   parameter[G_BB1].push_back(0.08325400);
+    2167           8 :   parameter[G_BB1].push_back(-7.35736000);
+    2168           8 :   parameter[G_BB1].push_back(2.18914800);
+    2169           8 :   parameter[G_BB1].push_back(-3.56154800);
+    2170           8 :   parameter[G_BB1].push_back(2.33120600);
+    2171           8 :   parameter[G_BB1].push_back(-0.39752300);
+    2172             : 
+    2173           8 :   parameter[G_BB2].push_back(3.80600000);
+    2174           8 :   parameter[G_BB2].push_back(-0.10788300);
+    2175           8 :   parameter[G_BB2].push_back(9.60930800);
+    2176           8 :   parameter[G_BB2].push_back(-6.27402500);
+    2177           8 :   parameter[G_BB2].push_back(-0.46192700);
+    2178           8 :   parameter[G_BB2].push_back(1.13737000);
+    2179           8 :   parameter[G_BB2].push_back(-0.21383100);
+    2180             : 
+    2181           8 :   parameter[G_BB3].push_back(3.59400000);
+    2182           8 :   parameter[G_BB3].push_back(0.04514500);
+    2183           8 :   parameter[G_BB3].push_back(9.61234700);
+    2184           8 :   parameter[G_BB3].push_back(-1.31542100);
+    2185           8 :   parameter[G_BB3].push_back(-7.09150500);
+    2186           8 :   parameter[G_BB3].push_back(4.04706200);
+    2187           8 :   parameter[G_BB3].push_back(-0.63201000);
+    2188             : 
+    2189           8 :   parameter[G_SC1].push_back(6.67100000);
+    2190           8 :   parameter[G_SC1].push_back(-0.00863200);
+    2191           8 :   parameter[G_SC1].push_back(1.63252300);
+    2192           8 :   parameter[G_SC1].push_back(-0.06567200);
+    2193           8 :   parameter[G_SC1].push_back(-1.48680500);
+    2194           8 :   parameter[G_SC1].push_back(0.78565600);
+    2195           8 :   parameter[G_SC1].push_back(-0.12088900);
+    2196             : 
+    2197           8 :   parameter[G_SC2].push_back(11.39400000);
+    2198           8 :   parameter[G_SC2].push_back(0.00912200);
+    2199           8 :   parameter[G_SC2].push_back(-0.22869000);
+    2200           8 :   parameter[G_SC2].push_back(0.49616400);
+    2201           8 :   parameter[G_SC2].push_back(-1.75039000);
+    2202           8 :   parameter[G_SC2].push_back(0.98649200);
+    2203           8 :   parameter[G_SC2].push_back(-0.16141600);
+    2204             : 
+    2205           8 :   parameter[G_SC3].push_back(10.90100000);
+    2206           8 :   parameter[G_SC3].push_back(0.02208700);
+    2207           8 :   parameter[G_SC3].push_back(0.17032800);
+    2208           8 :   parameter[G_SC3].push_back(0.73280800);
+    2209           8 :   parameter[G_SC3].push_back(-1.95292000);
+    2210           8 :   parameter[G_SC3].push_back(0.98357600);
+    2211           8 :   parameter[G_SC3].push_back(-0.14790900);
+    2212             : 
+    2213           8 :   parameter[G_SC4].push_back(6.45900000);
+    2214           8 :   parameter[G_SC4].push_back(0.02023700);
+    2215           8 :   parameter[G_SC4].push_back(4.17655400);
+    2216           8 :   parameter[G_SC4].push_back(0.98731800);
+    2217           8 :   parameter[G_SC4].push_back(-5.04352800);
+    2218           8 :   parameter[G_SC4].push_back(2.56059400);
+    2219           8 :   parameter[G_SC4].push_back(-0.39234300);
+    2220             : 
+    2221           8 :   parameter[G_3TE].push_back(4.23000000);
+    2222           8 :   parameter[G_3TE].push_back(0.00066300);
+    2223           8 :   parameter[G_3TE].push_back(0.92118800);
+    2224           8 :   parameter[G_3TE].push_back(0.08062700);
+    2225           8 :   parameter[G_3TE].push_back(-0.39041600);
+    2226           8 :   parameter[G_3TE].push_back(0.12419400);
+    2227           8 :   parameter[G_3TE].push_back(-0.01120500);
+    2228             : 
+    2229           8 :   parameter[G_5TE].push_back(4.23000000);
+    2230           8 :   parameter[G_5TE].push_back(0.00062800);
+    2231           8 :   parameter[G_5TE].push_back(0.92133500);
+    2232           8 :   parameter[G_5TE].push_back(0.08029900);
+    2233           8 :   parameter[G_5TE].push_back(-0.39015300);
+    2234           8 :   parameter[G_5TE].push_back(0.12411600);
+    2235           8 :   parameter[G_5TE].push_back(-0.01119900);
+    2236             : 
+    2237           8 :   parameter[G_TE3].push_back(7.82400000);
+    2238           8 :   parameter[G_TE3].push_back(-0.05177400);
+    2239           8 :   parameter[G_TE3].push_back(8.34606700);
+    2240           8 :   parameter[G_TE3].push_back(-1.02936300);
+    2241           8 :   parameter[G_TE3].push_back(-9.55211900);
+    2242           8 :   parameter[G_TE3].push_back(6.37776600);
+    2243           8 :   parameter[G_TE3].push_back(-1.17898000);
+    2244             : 
+    2245           8 :   parameter[G_TE5].push_back(8.03600000);
+    2246           8 :   parameter[G_TE5].push_back(0.00525100);
+    2247           8 :   parameter[G_TE5].push_back(4.71070600);
+    2248           8 :   parameter[G_TE5].push_back(0.66746900);
+    2249           8 :   parameter[G_TE5].push_back(-6.72538700);
+    2250           8 :   parameter[G_TE5].push_back(4.03644100);
+    2251           8 :   parameter[G_TE5].push_back(-0.70605700);
+    2252             : 
+    2253           8 :   parameter[U_BB1].push_back(32.88500000);
+    2254           8 :   parameter[U_BB1].push_back(0.08321400);
+    2255           8 :   parameter[U_BB1].push_back(-7.35634900);
+    2256           8 :   parameter[U_BB1].push_back(2.18826800);
+    2257           8 :   parameter[U_BB1].push_back(-3.56047400);
+    2258           8 :   parameter[U_BB1].push_back(2.33064700);
+    2259           8 :   parameter[U_BB1].push_back(-0.39744000);
+    2260             : 
+    2261           8 :   parameter[U_BB2].push_back(3.80600000);
+    2262           8 :   parameter[U_BB2].push_back(-0.10773100);
+    2263           8 :   parameter[U_BB2].push_back(9.60099900);
+    2264           8 :   parameter[U_BB2].push_back(-6.26131900);
+    2265           8 :   parameter[U_BB2].push_back(-0.46668300);
+    2266           8 :   parameter[U_BB2].push_back(1.13698100);
+    2267           8 :   parameter[U_BB2].push_back(-0.21351600);
+    2268             : 
+    2269           8 :   parameter[U_BB3].push_back(3.59400000);
+    2270           8 :   parameter[U_BB3].push_back(0.04544300);
+    2271           8 :   parameter[U_BB3].push_back(9.59625900);
+    2272           8 :   parameter[U_BB3].push_back(-1.29222200);
+    2273           8 :   parameter[U_BB3].push_back(-7.11143200);
+    2274           8 :   parameter[U_BB3].push_back(4.05687700);
+    2275           8 :   parameter[U_BB3].push_back(-0.63382800);
+    2276             : 
+    2277           8 :   parameter[U_SC1].push_back(5.95100000);
+    2278           8 :   parameter[U_SC1].push_back(-0.02924500);
+    2279           8 :   parameter[U_SC1].push_back(2.59668700);
+    2280           8 :   parameter[U_SC1].push_back(-0.56118700);
+    2281           8 :   parameter[U_SC1].push_back(-1.56477100);
+    2282           8 :   parameter[U_SC1].push_back(0.89265100);
+    2283           8 :   parameter[U_SC1].push_back(-0.14130800);
+    2284             : 
+    2285           8 :   parameter[U_SC2].push_back(10.90100000);
+    2286           8 :   parameter[U_SC2].push_back(0.02178900);
+    2287           8 :   parameter[U_SC2].push_back(0.18839000);
+    2288           8 :   parameter[U_SC2].push_back(0.72223100);
+    2289           8 :   parameter[U_SC2].push_back(-1.92581600);
+    2290           8 :   parameter[U_SC2].push_back(0.96654300);
+    2291           8 :   parameter[U_SC2].push_back(-0.14501300);
+    2292             : 
+    2293           8 :   parameter[U_SC3].push_back(5.24600000);
+    2294           8 :   parameter[U_SC3].push_back(-0.04586500);
+    2295           8 :   parameter[U_SC3].push_back(5.89978100);
+    2296           8 :   parameter[U_SC3].push_back(-1.50664700);
+    2297           8 :   parameter[U_SC3].push_back(-3.17054400);
+    2298           8 :   parameter[U_SC3].push_back(1.93717100);
+    2299           8 :   parameter[U_SC3].push_back(-0.31701000);
+    2300             : 
+    2301           8 :   parameter[U_3TE].push_back(4.23000000);
+    2302           8 :   parameter[U_3TE].push_back(0.00067500);
+    2303           8 :   parameter[U_3TE].push_back(0.92102300);
+    2304           8 :   parameter[U_3TE].push_back(0.08100800);
+    2305           8 :   parameter[U_3TE].push_back(-0.39084300);
+    2306           8 :   parameter[U_3TE].push_back(0.12441900);
+    2307           8 :   parameter[U_3TE].push_back(-0.01124900);
+    2308             : 
+    2309           8 :   parameter[U_5TE].push_back(4.23000000);
+    2310           8 :   parameter[U_5TE].push_back(0.00059000);
+    2311           8 :   parameter[U_5TE].push_back(0.92154600);
+    2312           8 :   parameter[U_5TE].push_back(0.07968200);
+    2313           8 :   parameter[U_5TE].push_back(-0.38950100);
+    2314           8 :   parameter[U_5TE].push_back(0.12382500);
+    2315           8 :   parameter[U_5TE].push_back(-0.01115100);
+    2316             : 
+    2317           8 :   parameter[U_TE3].push_back(7.82400000);
+    2318           8 :   parameter[U_TE3].push_back(-0.02968100);
+    2319           8 :   parameter[U_TE3].push_back(7.93783200);
+    2320           8 :   parameter[U_TE3].push_back(-0.33078100);
+    2321           8 :   parameter[U_TE3].push_back(-10.14120200);
+    2322           8 :   parameter[U_TE3].push_back(6.63334700);
+    2323           8 :   parameter[U_TE3].push_back(-1.22111200);
+    2324             : 
+    2325           8 :   parameter[U_TE5].push_back(8.03600000);
+    2326           8 :   parameter[U_TE5].push_back(-0.00909700);
+    2327           8 :   parameter[U_TE5].push_back(4.33193500);
+    2328           8 :   parameter[U_TE5].push_back(0.43416500);
+    2329           8 :   parameter[U_TE5].push_back(-5.80831400);
+    2330           8 :   parameter[U_TE5].push_back(3.52438800);
+    2331           8 :   parameter[U_TE5].push_back(-0.62382400);
+    2332             : 
+    2333           8 :   parameter[DA_BB1].push_back(32.88500000);
+    2334           8 :   parameter[DA_BB1].push_back(0.08179900);
+    2335           8 :   parameter[DA_BB1].push_back(-7.31735900);
+    2336           8 :   parameter[DA_BB1].push_back(2.15614500);
+    2337           8 :   parameter[DA_BB1].push_back(-3.52263200);
+    2338           8 :   parameter[DA_BB1].push_back(2.30604700);
+    2339           8 :   parameter[DA_BB1].push_back(-0.39270100);
+    2340             : 
+    2341           8 :   parameter[DA_BB2].push_back(3.80600000);
+    2342           8 :   parameter[DA_BB2].push_back(-0.10597700);
+    2343           8 :   parameter[DA_BB2].push_back(9.52537500);
+    2344           8 :   parameter[DA_BB2].push_back(-6.12991000);
+    2345           8 :   parameter[DA_BB2].push_back(-0.54092600);
+    2346           8 :   parameter[DA_BB2].push_back(1.15429100);
+    2347           8 :   parameter[DA_BB2].push_back(-0.21503500);
+    2348             : 
+    2349           8 :   parameter[DA_BB3].push_back(-1.35600000);
+    2350           8 :   parameter[DA_BB3].push_back(0.58928300);
+    2351           8 :   parameter[DA_BB3].push_back(6.71894100);
+    2352           8 :   parameter[DA_BB3].push_back(4.14050900);
+    2353           8 :   parameter[DA_BB3].push_back(-9.65859900);
+    2354           8 :   parameter[DA_BB3].push_back(4.43185000);
+    2355           8 :   parameter[DA_BB3].push_back(-0.64657300);
+    2356             : 
+    2357           8 :   parameter[DA_SC1].push_back(6.67100000);
+    2358           8 :   parameter[DA_SC1].push_back(-0.00871400);
+    2359           8 :   parameter[DA_SC1].push_back(1.63289100);
+    2360           8 :   parameter[DA_SC1].push_back(-0.06637700);
+    2361           8 :   parameter[DA_SC1].push_back(-1.48632900);
+    2362           8 :   parameter[DA_SC1].push_back(0.78551800);
+    2363           8 :   parameter[DA_SC1].push_back(-0.12087300);
+    2364             : 
+    2365           8 :   parameter[DA_SC2].push_back(5.95100000);
+    2366           8 :   parameter[DA_SC2].push_back(-0.02634300);
+    2367           8 :   parameter[DA_SC2].push_back(2.54864300);
+    2368           8 :   parameter[DA_SC2].push_back(-0.49015800);
+    2369           8 :   parameter[DA_SC2].push_back(-1.55386900);
+    2370           8 :   parameter[DA_SC2].push_back(0.86630200);
+    2371           8 :   parameter[DA_SC2].push_back(-0.13546200);
+    2372             : 
+    2373           8 :   parameter[DA_SC3].push_back(11.39400000);
+    2374           8 :   parameter[DA_SC3].push_back(0.00859500);
+    2375           8 :   parameter[DA_SC3].push_back(-0.25471400);
+    2376           8 :   parameter[DA_SC3].push_back(0.48718800);
+    2377           8 :   parameter[DA_SC3].push_back(-1.74520000);
+    2378           8 :   parameter[DA_SC3].push_back(0.99246200);
+    2379           8 :   parameter[DA_SC3].push_back(-0.16351900);
+    2380             : 
+    2381           8 :   parameter[DA_SC4].push_back(6.45900000);
+    2382           8 :   parameter[DA_SC4].push_back(0.01991800);
+    2383           8 :   parameter[DA_SC4].push_back(4.17962300);
+    2384           8 :   parameter[DA_SC4].push_back(0.97469100);
+    2385           8 :   parameter[DA_SC4].push_back(-5.02950400);
+    2386           8 :   parameter[DA_SC4].push_back(2.55371800);
+    2387           8 :   parameter[DA_SC4].push_back(-0.39113400);
+    2388             : 
+    2389           8 :   parameter[DA_3TE].push_back(4.23000000);
+    2390           8 :   parameter[DA_3TE].push_back(0.00062600);
+    2391           8 :   parameter[DA_3TE].push_back(0.92142000);
+    2392           8 :   parameter[DA_3TE].push_back(0.08016400);
+    2393           8 :   parameter[DA_3TE].push_back(-0.39000300);
+    2394           8 :   parameter[DA_3TE].push_back(0.12402500);
+    2395           8 :   parameter[DA_3TE].push_back(-0.01117900);
+    2396             : 
+    2397           8 :   parameter[DA_5TE].push_back(4.23000000);
+    2398           8 :   parameter[DA_5TE].push_back(0.00055500);
+    2399           8 :   parameter[DA_5TE].push_back(0.92183900);
+    2400           8 :   parameter[DA_5TE].push_back(0.07907600);
+    2401           8 :   parameter[DA_5TE].push_back(-0.38895100);
+    2402           8 :   parameter[DA_5TE].push_back(0.12359600);
+    2403           8 :   parameter[DA_5TE].push_back(-0.01111600);
+    2404             : 
+    2405           8 :   parameter[DA_TE3].push_back(2.87400000);
+    2406           8 :   parameter[DA_TE3].push_back(0.00112900);
+    2407           8 :   parameter[DA_TE3].push_back(12.51167200);
+    2408           8 :   parameter[DA_TE3].push_back(-7.67548000);
+    2409           8 :   parameter[DA_TE3].push_back(-2.02234000);
+    2410           8 :   parameter[DA_TE3].push_back(2.50837100);
+    2411           8 :   parameter[DA_TE3].push_back(-0.49458500);
+    2412             : 
+    2413           8 :   parameter[DA_TE5].push_back(8.03600000);
+    2414           8 :   parameter[DA_TE5].push_back(0.00473100);
+    2415           8 :   parameter[DA_TE5].push_back(4.65554400);
+    2416           8 :   parameter[DA_TE5].push_back(0.66424100);
+    2417           8 :   parameter[DA_TE5].push_back(-6.62131300);
+    2418           8 :   parameter[DA_TE5].push_back(3.96107400);
+    2419           8 :   parameter[DA_TE5].push_back(-0.69075800);
+    2420             : 
+    2421           8 :   parameter[DC_BB1].push_back(32.88500000);
+    2422           8 :   parameter[DC_BB1].push_back(0.08189900);
+    2423           8 :   parameter[DC_BB1].push_back(-7.32493500);
+    2424           8 :   parameter[DC_BB1].push_back(2.15976900);
+    2425           8 :   parameter[DC_BB1].push_back(-3.52612100);
+    2426           8 :   parameter[DC_BB1].push_back(2.31058600);
+    2427           8 :   parameter[DC_BB1].push_back(-0.39402700);
+    2428             : 
+    2429           8 :   parameter[DC_BB2].push_back(3.80600000);
+    2430           8 :   parameter[DC_BB2].push_back(-0.10559800);
+    2431           8 :   parameter[DC_BB2].push_back(9.52527700);
+    2432           8 :   parameter[DC_BB2].push_back(-6.12131700);
+    2433           8 :   parameter[DC_BB2].push_back(-0.54899400);
+    2434           8 :   parameter[DC_BB2].push_back(1.15592900);
+    2435           8 :   parameter[DC_BB2].push_back(-0.21494500);
+    2436             : 
+    2437           8 :   parameter[DC_BB3].push_back(-1.35600000);
+    2438           8 :   parameter[DC_BB3].push_back(0.55525700);
+    2439           8 :   parameter[DC_BB3].push_back(6.80305500);
+    2440           8 :   parameter[DC_BB3].push_back(4.05924700);
+    2441           8 :   parameter[DC_BB3].push_back(-9.61034700);
+    2442           8 :   parameter[DC_BB3].push_back(4.41253800);
+    2443           8 :   parameter[DC_BB3].push_back(-0.64315100);
+    2444             : 
+    2445           8 :   parameter[DC_SC1].push_back(5.95100000);
+    2446           8 :   parameter[DC_SC1].push_back(-0.02899900);
+    2447           8 :   parameter[DC_SC1].push_back(2.59587800);
+    2448           8 :   parameter[DC_SC1].push_back(-0.55388300);
+    2449           8 :   parameter[DC_SC1].push_back(-1.56395100);
+    2450           8 :   parameter[DC_SC1].push_back(0.88967400);
+    2451           8 :   parameter[DC_SC1].push_back(-0.14062500);
+    2452             : 
+    2453           8 :   parameter[DC_SC2].push_back(11.62100000);
+    2454           8 :   parameter[DC_SC2].push_back(0.01358100);
+    2455           8 :   parameter[DC_SC2].push_back(-0.24913000);
+    2456           8 :   parameter[DC_SC2].push_back(0.48787200);
+    2457           8 :   parameter[DC_SC2].push_back(-1.52867300);
+    2458           8 :   parameter[DC_SC2].push_back(0.83694900);
+    2459           8 :   parameter[DC_SC2].push_back(-0.13395300);
+    2460             : 
+    2461           8 :   parameter[DC_SC3].push_back(5.01900000);
+    2462           8 :   parameter[DC_SC3].push_back(-0.03298400);
+    2463           8 :   parameter[DC_SC3].push_back(5.54242800);
+    2464           8 :   parameter[DC_SC3].push_back(-0.96081500);
+    2465           8 :   parameter[DC_SC3].push_back(-3.71051600);
+    2466           8 :   parameter[DC_SC3].push_back(2.16500200);
+    2467           8 :   parameter[DC_SC3].push_back(-0.35023400);
+    2468             : 
+    2469           8 :   parameter[DC_3TE].push_back(4.23000000);
+    2470           8 :   parameter[DC_3TE].push_back(0.00055700);
+    2471           8 :   parameter[DC_3TE].push_back(0.92181400);
+    2472           8 :   parameter[DC_3TE].push_back(0.07924000);
+    2473           8 :   parameter[DC_3TE].push_back(-0.38916400);
+    2474           8 :   parameter[DC_3TE].push_back(0.12369900);
+    2475           8 :   parameter[DC_3TE].push_back(-0.01113300);
+    2476             : 
+    2477           8 :   parameter[DC_5TE].push_back(4.23000000);
+    2478           8 :   parameter[DC_5TE].push_back(0.00066500);
+    2479           8 :   parameter[DC_5TE].push_back(0.92103900);
+    2480           8 :   parameter[DC_5TE].push_back(0.08064600);
+    2481           8 :   parameter[DC_5TE].push_back(-0.39034900);
+    2482           8 :   parameter[DC_5TE].push_back(0.12417600);
+    2483           8 :   parameter[DC_5TE].push_back(-0.01120600);
+    2484             : 
+    2485           8 :   parameter[DC_TE3].push_back(2.87400000);
+    2486           8 :   parameter[DC_TE3].push_back(-0.05235500);
+    2487           8 :   parameter[DC_TE3].push_back(13.09201200);
+    2488           8 :   parameter[DC_TE3].push_back(-9.48128200);
+    2489           8 :   parameter[DC_TE3].push_back(-0.14958600);
+    2490           8 :   parameter[DC_TE3].push_back(1.75537200);
+    2491           8 :   parameter[DC_TE3].push_back(-0.39347500);
+    2492             : 
+    2493           8 :   parameter[DC_TE5].push_back(8.03600000);
+    2494           8 :   parameter[DC_TE5].push_back(-0.00513600);
+    2495           8 :   parameter[DC_TE5].push_back(4.67705700);
+    2496           8 :   parameter[DC_TE5].push_back(0.48333300);
+    2497           8 :   parameter[DC_TE5].push_back(-6.34511000);
+    2498           8 :   parameter[DC_TE5].push_back(3.83388500);
+    2499           8 :   parameter[DC_TE5].push_back(-0.67367800);
+    2500             : 
+    2501           8 :   parameter[DG_BB1].push_back(32.88500000);
+    2502           8 :   parameter[DG_BB1].push_back(0.08182900);
+    2503           8 :   parameter[DG_BB1].push_back(-7.32133900);
+    2504           8 :   parameter[DG_BB1].push_back(2.15767900);
+    2505           8 :   parameter[DG_BB1].push_back(-3.52369700);
+    2506           8 :   parameter[DG_BB1].push_back(2.30839600);
+    2507           8 :   parameter[DG_BB1].push_back(-0.39348300);
+    2508             : 
+    2509           8 :   parameter[DG_BB2].push_back(3.80600000);
+    2510           8 :   parameter[DG_BB2].push_back(-0.10618100);
+    2511           8 :   parameter[DG_BB2].push_back(9.54169000);
+    2512           8 :   parameter[DG_BB2].push_back(-6.15177600);
+    2513           8 :   parameter[DG_BB2].push_back(-0.53462400);
+    2514           8 :   parameter[DG_BB2].push_back(1.15581300);
+    2515           8 :   parameter[DG_BB2].push_back(-0.21567000);
+    2516             : 
+    2517           8 :   parameter[DG_BB3].push_back(-1.35600000);
+    2518           8 :   parameter[DG_BB3].push_back(0.57489100);
+    2519           8 :   parameter[DG_BB3].push_back(6.75164700);
+    2520           8 :   parameter[DG_BB3].push_back(4.11300900);
+    2521           8 :   parameter[DG_BB3].push_back(-9.63394600);
+    2522           8 :   parameter[DG_BB3].push_back(4.41675400);
+    2523           8 :   parameter[DG_BB3].push_back(-0.64339900);
+    2524             : 
+    2525           8 :   parameter[DG_SC1].push_back(6.67100000);
+    2526           8 :   parameter[DG_SC1].push_back(-0.00886600);
+    2527           8 :   parameter[DG_SC1].push_back(1.63333000);
+    2528           8 :   parameter[DG_SC1].push_back(-0.06892100);
+    2529           8 :   parameter[DG_SC1].push_back(-1.48683500);
+    2530           8 :   parameter[DG_SC1].push_back(0.78670800);
+    2531           8 :   parameter[DG_SC1].push_back(-0.12113900);
+    2532             : 
+    2533           8 :   parameter[DG_SC2].push_back(11.39400000);
+    2534           8 :   parameter[DG_SC2].push_back(0.00907900);
+    2535           8 :   parameter[DG_SC2].push_back(-0.22475500);
+    2536           8 :   parameter[DG_SC2].push_back(0.49535100);
+    2537           8 :   parameter[DG_SC2].push_back(-1.75324900);
+    2538           8 :   parameter[DG_SC2].push_back(0.98767400);
+    2539           8 :   parameter[DG_SC2].push_back(-0.16150800);
+    2540             : 
+    2541           8 :   parameter[DG_SC3].push_back(10.90100000);
+    2542           8 :   parameter[DG_SC3].push_back(0.02207600);
+    2543           8 :   parameter[DG_SC3].push_back(0.17932200);
+    2544           8 :   parameter[DG_SC3].push_back(0.73253200);
+    2545           8 :   parameter[DG_SC3].push_back(-1.95554900);
+    2546           8 :   parameter[DG_SC3].push_back(0.98339900);
+    2547           8 :   parameter[DG_SC3].push_back(-0.14763600);
+    2548             : 
+    2549           8 :   parameter[DG_SC4].push_back(6.45900000);
+    2550           8 :   parameter[DG_SC4].push_back(0.02018400);
+    2551           8 :   parameter[DG_SC4].push_back(4.17705400);
+    2552           8 :   parameter[DG_SC4].push_back(0.98531700);
+    2553           8 :   parameter[DG_SC4].push_back(-5.04354900);
+    2554           8 :   parameter[DG_SC4].push_back(2.56123700);
+    2555           8 :   parameter[DG_SC4].push_back(-0.39249300);
+    2556             : 
+    2557           8 :   parameter[DG_3TE].push_back(4.23000000);
+    2558           8 :   parameter[DG_3TE].push_back(0.00061700);
+    2559           8 :   parameter[DG_3TE].push_back(0.92140100);
+    2560           8 :   parameter[DG_3TE].push_back(0.08016400);
+    2561           8 :   parameter[DG_3TE].push_back(-0.39003500);
+    2562           8 :   parameter[DG_3TE].push_back(0.12406900);
+    2563           8 :   parameter[DG_3TE].push_back(-0.01119200);
+    2564             : 
+    2565           8 :   parameter[DG_5TE].push_back(4.23000000);
+    2566           8 :   parameter[DG_5TE].push_back(0.00064900);
+    2567           8 :   parameter[DG_5TE].push_back(0.92110500);
+    2568           8 :   parameter[DG_5TE].push_back(0.08031500);
+    2569           8 :   parameter[DG_5TE].push_back(-0.38997000);
+    2570           8 :   parameter[DG_5TE].push_back(0.12401200);
+    2571           8 :   parameter[DG_5TE].push_back(-0.01118100);
+    2572             : 
+    2573           8 :   parameter[DG_TE3].push_back(2.87400000);
+    2574           8 :   parameter[DG_TE3].push_back(0.00182000);
+    2575           8 :   parameter[DG_TE3].push_back(12.41507000);
+    2576           8 :   parameter[DG_TE3].push_back(-7.47384800);
+    2577           8 :   parameter[DG_TE3].push_back(-2.11864700);
+    2578           8 :   parameter[DG_TE3].push_back(2.50112600);
+    2579           8 :   parameter[DG_TE3].push_back(-0.48652200);
+    2580             : 
+    2581           8 :   parameter[DG_TE5].push_back(8.03600000);
+    2582           8 :   parameter[DG_TE5].push_back(0.00676400);
+    2583           8 :   parameter[DG_TE5].push_back(4.65989200);
+    2584           8 :   parameter[DG_TE5].push_back(0.78482500);
+    2585           8 :   parameter[DG_TE5].push_back(-6.86460600);
+    2586           8 :   parameter[DG_TE5].push_back(4.11675400);
+    2587           8 :   parameter[DG_TE5].push_back(-0.72249100);
+    2588             : 
+    2589           8 :   parameter[DT_BB1].push_back(32.88500000);
+    2590           8 :   parameter[DT_BB1].push_back(0.08220100);
+    2591           8 :   parameter[DT_BB1].push_back(-7.33006800);
+    2592           8 :   parameter[DT_BB1].push_back(2.16636500);
+    2593           8 :   parameter[DT_BB1].push_back(-3.53465700);
+    2594           8 :   parameter[DT_BB1].push_back(2.31447600);
+    2595           8 :   parameter[DT_BB1].push_back(-0.39445400);
+    2596             : 
+    2597           8 :   parameter[DT_BB2].push_back(3.80600000);
+    2598           8 :   parameter[DT_BB2].push_back(-0.10723000);
+    2599           8 :   parameter[DT_BB2].push_back(9.56675000);
+    2600           8 :   parameter[DT_BB2].push_back(-6.20236100);
+    2601           8 :   parameter[DT_BB2].push_back(-0.49550400);
+    2602           8 :   parameter[DT_BB2].push_back(1.14300600);
+    2603           8 :   parameter[DT_BB2].push_back(-0.21420000);
+    2604             : 
+    2605           8 :   parameter[DT_BB3].push_back(-1.35600000);
+    2606           8 :   parameter[DT_BB3].push_back(0.56737900);
+    2607           8 :   parameter[DT_BB3].push_back(6.76595400);
+    2608           8 :   parameter[DT_BB3].push_back(4.08976100);
+    2609           8 :   parameter[DT_BB3].push_back(-9.61512500);
+    2610           8 :   parameter[DT_BB3].push_back(4.40975100);
+    2611           8 :   parameter[DT_BB3].push_back(-0.64239800);
+    2612             : 
+    2613           8 :   parameter[DT_SC1].push_back(5.95100000);
+    2614           8 :   parameter[DT_SC1].push_back(-0.02926500);
+    2615           8 :   parameter[DT_SC1].push_back(2.59630300);
+    2616           8 :   parameter[DT_SC1].push_back(-0.56152200);
+    2617           8 :   parameter[DT_SC1].push_back(-1.56532600);
+    2618           8 :   parameter[DT_SC1].push_back(0.89322800);
+    2619           8 :   parameter[DT_SC1].push_back(-0.14142900);
+    2620             : 
+    2621           8 :   parameter[DT_SC2].push_back(10.90100000);
+    2622           8 :   parameter[DT_SC2].push_back(0.02183400);
+    2623           8 :   parameter[DT_SC2].push_back(0.19463000);
+    2624           8 :   parameter[DT_SC2].push_back(0.72393000);
+    2625           8 :   parameter[DT_SC2].push_back(-1.93199500);
+    2626           8 :   parameter[DT_SC2].push_back(0.96856300);
+    2627           8 :   parameter[DT_SC2].push_back(-0.14512600);
+    2628             : 
+    2629           8 :   parameter[DT_SC3].push_back(4.31400000);
+    2630           8 :   parameter[DT_SC3].push_back(-0.07745600);
+    2631           8 :   parameter[DT_SC3].push_back(12.49820300);
+    2632           8 :   parameter[DT_SC3].push_back(-7.64994200);
+    2633           8 :   parameter[DT_SC3].push_back(-3.00359600);
+    2634           8 :   parameter[DT_SC3].push_back(3.26263300);
+    2635           8 :   parameter[DT_SC3].push_back(-0.64498600);
+    2636             : 
+    2637           8 :   parameter[DT_3TE].push_back(4.23000000);
+    2638           8 :   parameter[DT_3TE].push_back(0.00062000);
+    2639           8 :   parameter[DT_3TE].push_back(0.92141100);
+    2640           8 :   parameter[DT_3TE].push_back(0.08030900);
+    2641           8 :   parameter[DT_3TE].push_back(-0.39021500);
+    2642           8 :   parameter[DT_3TE].push_back(0.12414000);
+    2643           8 :   parameter[DT_3TE].push_back(-0.01120100);
+    2644             : 
+    2645           8 :   parameter[DT_5TE].push_back(4.23000000);
+    2646           8 :   parameter[DT_5TE].push_back(0.00063700);
+    2647           8 :   parameter[DT_5TE].push_back(0.92130800);
+    2648           8 :   parameter[DT_5TE].push_back(0.08026900);
+    2649           8 :   parameter[DT_5TE].push_back(-0.39007500);
+    2650           8 :   parameter[DT_5TE].push_back(0.12406600);
+    2651           8 :   parameter[DT_5TE].push_back(-0.01118800);
+    2652             : 
+    2653           8 :   parameter[DT_TE3].push_back(2.87400000);
+    2654           8 :   parameter[DT_TE3].push_back(-0.00251200);
+    2655           8 :   parameter[DT_TE3].push_back(12.43576400);
+    2656           8 :   parameter[DT_TE3].push_back(-7.55343800);
+    2657           8 :   parameter[DT_TE3].push_back(-2.07363500);
+    2658           8 :   parameter[DT_TE3].push_back(2.51279300);
+    2659           8 :   parameter[DT_TE3].push_back(-0.49437100);
+    2660             : 
+    2661           8 :   parameter[DT_TE5].push_back(8.03600000);
+    2662           8 :   parameter[DT_TE5].push_back(0.00119900);
+    2663           8 :   parameter[DT_TE5].push_back(4.91762300);
+    2664           8 :   parameter[DT_TE5].push_back(0.65637000);
+    2665           8 :   parameter[DT_TE5].push_back(-7.23392500);
+    2666           8 :   parameter[DT_TE5].push_back(4.44636600);
+    2667           8 :   parameter[DT_TE5].push_back(-0.79467800);
+    2668             : 
+    2669           8 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    2670           8 :   if( moldat ) {
+    2671        8400 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    2672        8392 :       std::string Aname = moldat->getAtomName(atoms[i]);
+    2673        8392 :       std::string Rname = moldat->getResidueName(atoms[i]);
+    2674        8392 :       if(Rname=="ALA") {
+    2675          72 :         if(Aname=="BB") {
+    2676          72 :           atoi[i]=ALA_BB;
+    2677           0 :         } else error("Atom name not known: "+Aname);
+    2678        8320 :       } else if(Rname=="ARG") {
+    2679         420 :         if(Aname=="BB") {
+    2680         140 :           atoi[i]=ARG_BB;
+    2681         280 :         } else if(Aname=="SC1") {
+    2682         140 :           atoi[i]=ARG_SC1;
+    2683         140 :         } else if(Aname=="SC2") {
+    2684         140 :           atoi[i]=ARG_SC2;
+    2685           0 :         } else error("Atom name not known: "+Aname);
+    2686        7900 :       } else if(Rname=="ASN") {
+    2687         240 :         if(Aname=="BB") {
+    2688         120 :           atoi[i]=ASN_BB;
+    2689         120 :         } else if(Aname=="SC1") {
+    2690         120 :           atoi[i]=ASN_SC1;
+    2691           0 :         } else error("Atom name not known: "+Aname);
+    2692        7660 :       } else if(Rname=="ASP") {
+    2693         368 :         if(Aname=="BB") {
+    2694         184 :           atoi[i]=ASP_BB;
+    2695         184 :         } else if(Aname=="SC1") {
+    2696         184 :           atoi[i]=ASP_SC1;
+    2697           0 :         } else error("Atom name not known: "+Aname);
+    2698        7292 :       } else if(Rname=="CYS") {
+    2699          16 :         if(Aname=="BB") {
+    2700           8 :           atoi[i]=CYS_BB;
+    2701           8 :         } else if(Aname=="SC1") {
+    2702           8 :           atoi[i]=CYS_SC1;
+    2703           0 :         } else error("Atom name not known: "+Aname);
+    2704        7276 :       } else if(Rname=="GLN") {
+    2705         224 :         if(Aname=="BB") {
+    2706         112 :           atoi[i]=GLN_BB;
+    2707         112 :         } else if(Aname=="SC1") {
+    2708         112 :           atoi[i]=GLN_SC1;
+    2709           0 :         } else error("Atom name not known: "+Aname);
+    2710        7052 :       } else if(Rname=="GLU") {
+    2711         480 :         if(Aname=="BB") {
+    2712         240 :           atoi[i]=GLU_BB;
+    2713         240 :         } else if(Aname=="SC1") {
+    2714         240 :           atoi[i]=GLU_SC1;
+    2715           0 :         } else error("Atom name not known: "+Aname);
+    2716        6572 :       } else if(Rname=="GLY") {
+    2717         116 :         if(Aname=="BB") {
+    2718         116 :           atoi[i]=GLY_BB;
+    2719           0 :         } else error("Atom name not known: "+Aname);
+    2720        6456 :       } else if(Rname=="HIS") {
+    2721         576 :         if(Aname=="BB") {
+    2722         144 :           atoi[i]=HIS_BB;
+    2723         432 :         } else if(Aname=="SC1") {
+    2724         144 :           atoi[i]=HIS_SC1;
+    2725         288 :         } else if(Aname=="SC2") {
+    2726         144 :           atoi[i]=HIS_SC2;
+    2727         144 :         } else if(Aname=="SC3") {
+    2728         144 :           atoi[i]=HIS_SC3;
+    2729           0 :         } else error("Atom name not known: "+Aname);
+    2730        5880 :       } else if(Rname=="ILE") {
+    2731         584 :         if(Aname=="BB") {
+    2732         292 :           atoi[i]=ILE_BB;
+    2733         292 :         } else if(Aname=="SC1") {
+    2734         292 :           atoi[i]=ILE_SC1;
+    2735           0 :         } else error("Atom name not known: "+Aname);
+    2736        5296 :       } else if(Rname=="LEU") {
+    2737         448 :         if(Aname=="BB") {
+    2738         224 :           atoi[i]=LEU_BB;
+    2739         224 :         } else if(Aname=="SC1") {
+    2740         224 :           atoi[i]=LEU_SC1;
+    2741           0 :         } else error("Atom name not known: "+Aname);
+    2742        4848 :       } else if(Rname=="LYS") {
+    2743         792 :         if(Aname=="BB") {
+    2744         264 :           atoi[i]=LYS_BB;
+    2745         528 :         } else if(Aname=="SC1") {
+    2746         264 :           atoi[i]=LYS_SC1;
+    2747         264 :         } else if(Aname=="SC2") {
+    2748         264 :           atoi[i]=LYS_SC2;
+    2749           0 :         } else error("Atom name not known: "+Aname);
+    2750        4056 :       } else if(Rname=="MET") {
+    2751          80 :         if(Aname=="BB") {
+    2752          40 :           atoi[i]=MET_BB;
+    2753          40 :         } else if(Aname=="SC1") {
+    2754          40 :           atoi[i]=MET_SC1;
+    2755           0 :         } else error("Atom name not known: "+Aname);
+    2756        3976 :       } else if(Rname=="PHE") {
+    2757         512 :         if(Aname=="BB") {
+    2758         128 :           atoi[i]=PHE_BB;
+    2759         384 :         } else if(Aname=="SC1") {
+    2760         128 :           atoi[i]=PHE_SC1;
+    2761         256 :         } else if(Aname=="SC2") {
+    2762         128 :           atoi[i]=PHE_SC2;
+    2763         128 :         } else if(Aname=="SC3") {
+    2764         128 :           atoi[i]=PHE_SC3;
+    2765           0 :         } else error("Atom name not known: "+Aname);
+    2766        3464 :       } else if(Rname=="PRO") {
+    2767         128 :         if(Aname=="BB") {
+    2768          64 :           atoi[i]=PRO_BB;
+    2769          64 :         } else if(Aname=="SC1") {
+    2770          64 :           atoi[i]=PRO_SC1;
+    2771           0 :         } else error("Atom name not known: "+Aname);
+    2772        3336 :       } else if(Rname=="SER") {
+    2773         248 :         if(Aname=="BB") {
+    2774         124 :           atoi[i]=SER_BB;
+    2775         124 :         } else if(Aname=="SC1") {
+    2776         124 :           atoi[i]=SER_SC1;
+    2777           0 :         } else error("Atom name not known: "+Aname);
+    2778        3088 :       } else if(Rname=="THR") {
+    2779         288 :         if(Aname=="BB") {
+    2780         144 :           atoi[i]=THR_BB;
+    2781         144 :         } else if(Aname=="SC1") {
+    2782         144 :           atoi[i]=THR_SC1;
+    2783           0 :         } else error("Atom name not known: "+Aname);
+    2784        2800 :       } else if(Rname=="TRP") {
+    2785           0 :         if(Aname=="BB") {
+    2786           0 :           atoi[i]=TRP_BB;
+    2787           0 :         } else if(Aname=="SC1") {
+    2788           0 :           atoi[i]=TRP_SC1;
+    2789           0 :         } else if(Aname=="SC2") {
+    2790           0 :           atoi[i]=TRP_SC2;
+    2791           0 :         } else if(Aname=="SC3") {
+    2792           0 :           atoi[i]=TRP_SC3;
+    2793           0 :         } else if(Aname=="SC4") {
+    2794           0 :           atoi[i]=TRP_SC4;
+    2795           0 :         } else error("Atom name not known: "+Aname);
+    2796        2800 :       } else if(Rname=="TYR") {
+    2797         544 :         if(Aname=="BB") {
+    2798         136 :           atoi[i]=TYR_BB;
+    2799         408 :         } else if(Aname=="SC1") {
+    2800         136 :           atoi[i]=TYR_SC1;
+    2801         272 :         } else if(Aname=="SC2") {
+    2802         136 :           atoi[i]=TYR_SC2;
+    2803         136 :         } else if(Aname=="SC3") {
+    2804         136 :           atoi[i]=TYR_SC3;
+    2805           0 :         } else error("Atom name not known: "+Aname);
+    2806        2256 :       } else if(Rname=="VAL") {
+    2807         288 :         if(Aname=="BB") {
+    2808         144 :           atoi[i]=VAL_BB;
+    2809         144 :         } else if(Aname=="SC1") {
+    2810         144 :           atoi[i]=VAL_SC1;
+    2811           0 :         } else error("Atom name not known: "+Aname);
+    2812        1968 :       } else if(Rname=="  A") {
+    2813           0 :         if(Aname=="BB1") {
+    2814           0 :           atoi[i]=A_BB1;
+    2815           0 :         } else if(Aname=="BB2") {
+    2816           0 :           atoi[i]=A_BB2;
+    2817           0 :         } else if(Aname=="BB3") {
+    2818           0 :           atoi[i]=A_BB3;
+    2819           0 :         } else if(Aname=="SC1") {
+    2820           0 :           atoi[i]=A_SC1;
+    2821           0 :         } else if(Aname=="SC2") {
+    2822           0 :           atoi[i]=A_SC2;
+    2823           0 :         } else if(Aname=="SC3") {
+    2824           0 :           atoi[i]=A_SC3;
+    2825           0 :         } else if(Aname=="SC4") {
+    2826           0 :           atoi[i]=A_SC4;
+    2827           0 :         } else if(Aname=="3TE") {
+    2828           0 :           atoi[i]=A_3TE;
+    2829           0 :         } else if(Aname=="5TE") {
+    2830           0 :           atoi[i]=A_5TE;
+    2831           0 :         } else if(Aname=="TE3") {
+    2832           0 :           atoi[i]=A_TE3;
+    2833           0 :         } else if(Aname=="TE5") {
+    2834           0 :           atoi[i]=A_TE5;
+    2835           0 :         } else error("Atom name not known: "+Aname);
+    2836        1968 :       } else if(Rname=="  C") {
+    2837           0 :         if(Aname=="BB1") {
+    2838           0 :           atoi[i]=C_BB1;
+    2839           0 :         } else if(Aname=="BB2") {
+    2840           0 :           atoi[i]=C_BB2;
+    2841           0 :         } else if(Aname=="BB3") {
+    2842           0 :           atoi[i]=C_BB3;
+    2843           0 :         } else if(Aname=="SC1") {
+    2844           0 :           atoi[i]=C_SC1;
+    2845           0 :         } else if(Aname=="SC2") {
+    2846           0 :           atoi[i]=C_SC2;
+    2847           0 :         } else if(Aname=="SC3") {
+    2848           0 :           atoi[i]=C_SC3;
+    2849           0 :         } else if(Aname=="3TE") {
+    2850           0 :           atoi[i]=C_3TE;
+    2851           0 :         } else if(Aname=="5TE") {
+    2852           0 :           atoi[i]=C_5TE;
+    2853           0 :         } else if(Aname=="TE3") {
+    2854           0 :           atoi[i]=C_TE3;
+    2855           0 :         } else if(Aname=="TE5") {
+    2856           0 :           atoi[i]=C_TE5;
+    2857           0 :         } else error("Atom name not known: "+Aname);
+    2858        1968 :       } else if(Rname=="  G") {
+    2859           0 :         if(Aname=="BB1") {
+    2860           0 :           atoi[i]=G_BB1;
+    2861           0 :         } else if(Aname=="BB2") {
+    2862           0 :           atoi[i]=G_BB2;
+    2863           0 :         } else if(Aname=="BB3") {
+    2864           0 :           atoi[i]=G_BB3;
+    2865           0 :         } else if(Aname=="SC1") {
+    2866           0 :           atoi[i]=G_SC1;
+    2867           0 :         } else if(Aname=="SC2") {
+    2868           0 :           atoi[i]=G_SC2;
+    2869           0 :         } else if(Aname=="SC3") {
+    2870           0 :           atoi[i]=G_SC3;
+    2871           0 :         } else if(Aname=="SC4") {
+    2872           0 :           atoi[i]=G_SC4;
+    2873           0 :         } else if(Aname=="3TE") {
+    2874           0 :           atoi[i]=G_3TE;
+    2875           0 :         } else if(Aname=="5TE") {
+    2876           0 :           atoi[i]=G_5TE;
+    2877           0 :         } else if(Aname=="TE3") {
+    2878           0 :           atoi[i]=G_TE3;
+    2879           0 :         } else if(Aname=="TE5") {
+    2880           0 :           atoi[i]=G_TE5;
+    2881           0 :         } else error("Atom name not known: "+Aname);
+    2882        1968 :       } else if(Rname=="  U") {
+    2883           0 :         if(Aname=="BB1") {
+    2884           0 :           atoi[i]=U_BB1;
+    2885           0 :         } else if(Aname=="BB2") {
+    2886           0 :           atoi[i]=U_BB2;
+    2887           0 :         } else if(Aname=="BB3") {
+    2888           0 :           atoi[i]=U_BB3;
+    2889           0 :         } else if(Aname=="SC1") {
+    2890           0 :           atoi[i]=U_SC1;
+    2891           0 :         } else if(Aname=="SC2") {
+    2892           0 :           atoi[i]=U_SC2;
+    2893           0 :         } else if(Aname=="SC3") {
+    2894           0 :           atoi[i]=U_SC3;
+    2895           0 :         } else if(Aname=="3TE") {
+    2896           0 :           atoi[i]=U_3TE;
+    2897           0 :         } else if(Aname=="5TE") {
+    2898           0 :           atoi[i]=U_5TE;
+    2899           0 :         } else if(Aname=="TE3") {
+    2900           0 :           atoi[i]=U_TE3;
+    2901           0 :         } else if(Aname=="TE5") {
+    2902           0 :           atoi[i]=U_TE5;
+    2903           0 :         } else error("Atom name not known: "+Aname);
+    2904        1968 :       } else if(Rname==" DA") {
+    2905         696 :         if(Aname=="BB1") {
+    2906          96 :           atoi[i]=DA_BB1;
+    2907         600 :         } else if(Aname=="BB2") {
+    2908          96 :           atoi[i]=DA_BB2;
+    2909         504 :         } else if(Aname=="BB3") {
+    2910          96 :           atoi[i]=DA_BB3;
+    2911         408 :         } else if(Aname=="SC1") {
+    2912         100 :           atoi[i]=DA_SC1;
+    2913         308 :         } else if(Aname=="SC2") {
+    2914         100 :           atoi[i]=DA_SC2;
+    2915         208 :         } else if(Aname=="SC3") {
+    2916         100 :           atoi[i]=DA_SC3;
+    2917         108 :         } else if(Aname=="SC4") {
+    2918         100 :           atoi[i]=DA_SC4;
+    2919           8 :         } else if(Aname=="3TE") {
+    2920           0 :           atoi[i]=DA_3TE;
+    2921           8 :         } else if(Aname=="5TE") {
+    2922           0 :           atoi[i]=DA_5TE;
+    2923           8 :         } else if(Aname=="TE3") {
+    2924           4 :           atoi[i]=DA_TE3;
+    2925           4 :         } else if(Aname=="TE5") {
+    2926           4 :           atoi[i]=DA_TE5;
+    2927           0 :         } else error("Atom name not known: "+Aname);
+    2928        1272 :       } else if(Rname==" DC") {
+    2929         312 :         if(Aname=="BB1") {
+    2930          52 :           atoi[i]=DC_BB1;
+    2931         260 :         } else if(Aname=="BB2") {
+    2932          52 :           atoi[i]=DC_BB2;
+    2933         208 :         } else if(Aname=="BB3") {
+    2934          52 :           atoi[i]=DC_BB3;
+    2935         156 :         } else if(Aname=="SC1") {
+    2936          52 :           atoi[i]=DC_SC1;
+    2937         104 :         } else if(Aname=="SC2") {
+    2938          52 :           atoi[i]=DC_SC2;
+    2939          52 :         } else if(Aname=="SC3") {
+    2940          52 :           atoi[i]=DC_SC3;
+    2941           0 :         } else if(Aname=="3TE") {
+    2942           0 :           atoi[i]=DC_3TE;
+    2943           0 :         } else if(Aname=="5TE") {
+    2944           0 :           atoi[i]=DC_5TE;
+    2945           0 :         } else if(Aname=="TE3") {
+    2946           0 :           atoi[i]=DC_TE3;
+    2947           0 :         } else if(Aname=="TE5") {
+    2948           0 :           atoi[i]=DC_TE5;
+    2949           0 :         } else error("Atom name not known: "+Aname);
+    2950         960 :       } else if(Rname==" DG") {
+    2951         364 :         if(Aname=="BB1") {
+    2952          52 :           atoi[i]=DG_BB1;
+    2953         312 :         } else if(Aname=="BB2") {
+    2954          52 :           atoi[i]=DG_BB2;
+    2955         260 :         } else if(Aname=="BB3") {
+    2956          52 :           atoi[i]=DG_BB3;
+    2957         208 :         } else if(Aname=="SC1") {
+    2958          52 :           atoi[i]=DG_SC1;
+    2959         156 :         } else if(Aname=="SC2") {
+    2960          52 :           atoi[i]=DG_SC2;
+    2961         104 :         } else if(Aname=="SC3") {
+    2962          52 :           atoi[i]=DG_SC3;
+    2963          52 :         } else if(Aname=="SC4") {
+    2964          52 :           atoi[i]=DG_SC4;
+    2965           0 :         } else if(Aname=="3TE") {
+    2966           0 :           atoi[i]=DG_3TE;
+    2967           0 :         } else if(Aname=="5TE") {
+    2968           0 :           atoi[i]=DG_5TE;
+    2969           0 :         } else if(Aname=="TE3") {
+    2970           0 :           atoi[i]=DG_TE3;
+    2971           0 :         } else if(Aname=="TE5") {
+    2972           0 :           atoi[i]=DG_TE5;
+    2973           0 :         } else error("Atom name not known: "+Aname);
+    2974         596 :       } else if(Rname==" DT") {
+    2975         596 :         if(Aname=="BB1") {
+    2976          96 :           atoi[i]=DT_BB1;
+    2977         500 :         } else if(Aname=="BB2") {
+    2978          96 :           atoi[i]=DT_BB2;
+    2979         404 :         } else if(Aname=="BB3") {
+    2980          96 :           atoi[i]=DT_BB3;
+    2981         308 :         } else if(Aname=="SC1") {
+    2982         100 :           atoi[i]=DT_SC1;
+    2983         208 :         } else if(Aname=="SC2") {
+    2984         100 :           atoi[i]=DT_SC2;
+    2985         108 :         } else if(Aname=="SC3") {
+    2986         100 :           atoi[i]=DT_SC3;
+    2987           8 :         } else if(Aname=="3TE") {
+    2988           0 :           atoi[i]=DT_3TE;
+    2989           8 :         } else if(Aname=="5TE") {
+    2990           0 :           atoi[i]=DT_5TE;
+    2991           8 :         } else if(Aname=="TE3") {
+    2992           4 :           atoi[i]=DT_TE3;
+    2993           4 :         } else if(Aname=="TE5") {
+    2994           4 :           atoi[i]=DT_TE5;
+    2995           0 :         } else error("Atom name not known: "+Aname);
+    2996           0 :       } else error("Residue not known: "+Rname);
+    2997             :     }
+    2998             :   } else {
+    2999           0 :     error("MOLINFO DATA not found\n");
+    3000             :   }
+    3001           8 : }
+    3002             : 
+    3003           6 : void SAXS::getOnebeadparam(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac, std::vector<std::vector<long double> > &parameter_mix, std::vector<std::vector<long double> > &parameter_solv, const std::vector<unsigned> & residue_atom)
+    3004             : {
+    3005             : 
+    3006           6 :   parameter_solv[TRP].push_back(60737.60249988003);
+    3007           6 :   parameter_solv[TRP].push_back(-77.75716755173752);
+    3008           6 :   parameter_solv[TRP].push_back(-205962.98557711052);
+    3009           6 :   parameter_solv[TRP].push_back(-62013.46984155453);
+    3010           6 :   parameter_solv[TRP].push_back(680710.7592231638);
+    3011           6 :   parameter_solv[TRP].push_back(-681336.8777362367);
+    3012           6 :   parameter_solv[TRP].push_back(211473.65530642506);
+    3013             : 
+    3014           6 :   parameter_solv[TYR].push_back(46250.80359987982);
+    3015           6 :   parameter_solv[TYR].push_back(-45.8287864681578);
+    3016           6 :   parameter_solv[TYR].push_back(-143872.91752817619);
+    3017           6 :   parameter_solv[TYR].push_back(-39049.68736409533);
+    3018           6 :   parameter_solv[TYR].push_back(441321.71874090104);
+    3019           6 :   parameter_solv[TYR].push_back(-434478.0972346327);
+    3020           6 :   parameter_solv[TYR].push_back(133179.3694641212);
+    3021             : 
+    3022           6 :   parameter_solv[PHE].push_back(42407.164900118914);
+    3023           6 :   parameter_solv[PHE].push_back(-159.1980754191431);
+    3024           6 :   parameter_solv[PHE].push_back(-123847.86192757386);
+    3025           6 :   parameter_solv[PHE].push_back(-41797.69041575073);
+    3026           6 :   parameter_solv[PHE].push_back(380283.7035277073);
+    3027           6 :   parameter_solv[PHE].push_back(-361432.67247521743);
+    3028           6 :   parameter_solv[PHE].push_back(107750.64978068044);
+    3029             : 
+    3030           6 :   parameter_solv[HIP].push_back(24473.47360011923);
+    3031           6 :   parameter_solv[HIP].push_back(-111.64156672747428);
+    3032           6 :   parameter_solv[HIP].push_back(-65826.16993707925);
+    3033           6 :   parameter_solv[HIP].push_back(-23305.91329798928);
+    3034           6 :   parameter_solv[HIP].push_back(194795.11911635034);
+    3035           6 :   parameter_solv[HIP].push_back(-180454.49458095312);
+    3036           6 :   parameter_solv[HIP].push_back(52699.374196745615);
+    3037             : 
+    3038           6 :   parameter_solv[ARG].push_back(34106.70239988039);
+    3039           6 :   parameter_solv[ARG].push_back(152.7472727640246);
+    3040           6 :   parameter_solv[ARG].push_back(-117086.49392248681);
+    3041           6 :   parameter_solv[ARG].push_back(-19664.229479267167);
+    3042           6 :   parameter_solv[ARG].push_back(364454.0909203641);
+    3043           6 :   parameter_solv[ARG].push_back(-382075.8018312776);
+    3044           6 :   parameter_solv[ARG].push_back(122775.75036605193);
+    3045             : 
+    3046           6 :   parameter_solv[LYS].push_back(32292.090000118922);
+    3047           6 :   parameter_solv[LYS].push_back(-111.97371180593888);
+    3048           6 :   parameter_solv[LYS].push_back(-91953.10997619898);
+    3049           6 :   parameter_solv[LYS].push_back(-30690.807047993283);
+    3050           6 :   parameter_solv[LYS].push_back(282092.40760143084);
+    3051           6 :   parameter_solv[LYS].push_back(-269503.2592457489);
+    3052           6 :   parameter_solv[LYS].push_back(80777.81552915688);
+    3053             : 
+    3054           6 :   parameter_solv[CYS].push_back(11352.902500119093);
+    3055           6 :   parameter_solv[CYS].push_back(-45.5226331859686);
+    3056           6 :   parameter_solv[CYS].push_back(-20925.085562607524);
+    3057           6 :   parameter_solv[CYS].push_back(-5662.685408989286);
+    3058           6 :   parameter_solv[CYS].push_back(38559.10376731146);
+    3059           6 :   parameter_solv[CYS].push_back(-27885.23426006181);
+    3060           6 :   parameter_solv[CYS].push_back(6280.15058191397);
+    3061             : 
+    3062           6 :   parameter_solv[ASP].push_back(13511.73760011933);
+    3063           6 :   parameter_solv[ASP].push_back(-59.929111107656595);
+    3064           6 :   parameter_solv[ASP].push_back(-25849.869639655575);
+    3065           6 :   parameter_solv[ASP].push_back(-7541.669448872824);
+    3066           6 :   parameter_solv[ASP].push_back(50760.92045144903);
+    3067           6 :   parameter_solv[ASP].push_back(-37677.87583269734);
+    3068           6 :   parameter_solv[ASP].push_back(8745.7056219399);
+    3069             : 
+    3070           6 :   parameter_solv[GLU].push_back(20443.280400119456);
+    3071           6 :   parameter_solv[GLU].push_back(-113.77561814283207);
+    3072           6 :   parameter_solv[GLU].push_back(-45587.79314626863);
+    3073           6 :   parameter_solv[GLU].push_back(-16187.556837331254);
+    3074           6 :   parameter_solv[GLU].push_back(112609.65830609271);
+    3075           6 :   parameter_solv[GLU].push_back(-93362.05323205091);
+    3076           6 :   parameter_solv[GLU].push_back(24519.557866124724);
+    3077             : 
+    3078           6 :   parameter_solv[ILE].push_back(27858.948100119596);
+    3079           6 :   parameter_solv[ILE].push_back(-159.27355145839834);
+    3080           6 :   parameter_solv[ILE].push_back(-61571.43463039565);
+    3081           6 :   parameter_solv[ILE].push_back(-21324.879474559468);
+    3082           6 :   parameter_solv[ILE].push_back(144070.7572894681);
+    3083           6 :   parameter_solv[ILE].push_back(-115021.81959095894);
+    3084           6 :   parameter_solv[ILE].push_back(28939.085108838968);
+    3085             : 
+    3086           6 :   parameter_solv[LEU].push_back(27858.948100119596);
+    3087           6 :   parameter_solv[LEU].push_back(-165.61892007509647);
+    3088           6 :   parameter_solv[LEU].push_back(-62564.568746500125);
+    3089           6 :   parameter_solv[LEU].push_back(-22465.332149768525);
+    3090           6 :   parameter_solv[LEU].push_back(151616.79489291538);
+    3091           6 :   parameter_solv[LEU].push_back(-122905.6119395393);
+    3092           6 :   parameter_solv[LEU].push_back(31436.664377885514);
+    3093             : 
+    3094           6 :   parameter_solv[MET].push_back(25609.60090011981);
+    3095           6 :   parameter_solv[MET].push_back(-135.38857843066708);
+    3096           6 :   parameter_solv[MET].push_back(-67771.01108177133);
+    3097           6 :   parameter_solv[MET].push_back(-25228.934337676077);
+    3098           6 :   parameter_solv[MET].push_back(199649.95030712147);
+    3099           6 :   parameter_solv[MET].push_back(-182251.94895101967);
+    3100           6 :   parameter_solv[MET].push_back(52502.88444247481);
+    3101             : 
+    3102           6 :   parameter_solv[ASN].push_back(14376.010000119095);
+    3103           6 :   parameter_solv[ASN].push_back(-67.65579048748472);
+    3104           6 :   parameter_solv[ASN].push_back(-28302.87809850141);
+    3105           6 :   parameter_solv[ASN].push_back(-8577.439830985548);
+    3106           6 :   parameter_solv[ASN].push_back(57532.879075695324);
+    3107           6 :   parameter_solv[ASN].push_back(-43261.79286366774);
+    3108           6 :   parameter_solv[ASN].push_back(10186.448634149085);
+    3109             : 
+    3110           6 :   parameter_solv[PRO].push_back(16866.21690011944);
+    3111           6 :   parameter_solv[PRO].push_back(-70.84327801054884);
+    3112           6 :   parameter_solv[PRO].push_back(-31465.84064925844);
+    3113           6 :   parameter_solv[PRO].push_back(-8653.3693368317);
+    3114           6 :   parameter_solv[PRO].push_back(58032.28250733714);
+    3115           6 :   parameter_solv[PRO].push_back(-41521.01146771431);
+    3116           6 :   parameter_solv[PRO].push_back(9184.530596102064);
+    3117             : 
+    3118           6 :   parameter_solv[GLN].push_back(21503.289600119);
+    3119           6 :   parameter_solv[GLN].push_back(-121.30164008960246);
+    3120           6 :   parameter_solv[GLN].push_back(-50468.580981118175);
+    3121           6 :   parameter_solv[GLN].push_back(-18462.49098408308);
+    3122           6 :   parameter_solv[GLN].push_back(132718.44904081387);
+    3123           6 :   parameter_solv[GLN].push_back(-113787.22666510186);
+    3124           6 :   parameter_solv[GLN].push_back(30920.348610969988);
+    3125             : 
+    3126           6 :   parameter_solv[SER].push_back(9181.472400119354);
+    3127           6 :   parameter_solv[SER].push_back(-28.77519915767741);
+    3128           6 :   parameter_solv[SER].push_back(-15205.543144104717);
+    3129           6 :   parameter_solv[SER].push_back(-3377.782176346411);
+    3130           6 :   parameter_solv[SER].push_back(23345.555771001076);
+    3131           6 :   parameter_solv[SER].push_back(-15312.694356014094);
+    3132           6 :   parameter_solv[SER].push_back(3013.8428466148);
+    3133             : 
+    3134           6 :   parameter_solv[THR].push_back(15020.953600119403);
+    3135           6 :   parameter_solv[THR].push_back(-61.91004832631006);
+    3136           6 :   parameter_solv[THR].push_back(-27814.537889259853);
+    3137           6 :   parameter_solv[THR].push_back(-7532.227289701552);
+    3138           6 :   parameter_solv[THR].push_back(50586.30566118166);
+    3139           6 :   parameter_solv[THR].push_back(-35943.866131120165);
+    3140           6 :   parameter_solv[THR].push_back(7880.093558764326);
+    3141             : 
+    3142           6 :   parameter_solv[VAL].push_back(19647.628900119355);
+    3143           6 :   parameter_solv[VAL].push_back(-89.04983250107853);
+    3144           6 :   parameter_solv[VAL].push_back(-38050.09958470928);
+    3145           6 :   parameter_solv[VAL].push_back(-10921.427112288537);
+    3146           6 :   parameter_solv[VAL].push_back(72774.32322962297);
+    3147           6 :   parameter_solv[VAL].push_back(-52689.060152305225);
+    3148           6 :   parameter_solv[VAL].push_back(11806.492503632868);
+    3149             : 
+    3150           6 :   parameter_solv[ALA].push_back(7515.156100119276);
+    3151           6 :   parameter_solv[ALA].push_back(-20.226381685697746);
+    3152           6 :   parameter_solv[ALA].push_back(-11761.841094237716);
+    3153           6 :   parameter_solv[ALA].push_back(-2341.4929468980367);
+    3154           6 :   parameter_solv[ALA].push_back(16545.385777961936);
+    3155           6 :   parameter_solv[ALA].push_back(-10397.175253025776);
+    3156           6 :   parameter_solv[ALA].push_back(1921.5264606725107);
+    3157             : 
+    3158           6 :   parameter_solv[GLY].push_back(3594.002500119159);
+    3159           6 :   parameter_solv[GLY].push_back(-6.910836154887606);
+    3160           6 :   parameter_solv[GLY].push_back(-4937.354220666574);
+    3161           6 :   parameter_solv[GLY].push_back(-785.4549468992149);
+    3162           6 :   parameter_solv[GLY].push_back(5852.854429532936);
+    3163           6 :   parameter_solv[GLY].push_back(-3391.2927115487832);
+    3164           6 :   parameter_solv[GLY].push_back(552.3280571490722);
+    3165             : 
+    3166           6 :   parameter_solv[HIS].push_back(22888.664100119073);
+    3167           6 :   parameter_solv[HIS].push_back(-133.86265270962434);
+    3168           6 :   parameter_solv[HIS].push_back(-57533.51591635819);
+    3169           6 :   parameter_solv[HIS].push_back(-21767.293192014684);
+    3170           6 :   parameter_solv[HIS].push_back(161255.14120001195);
+    3171           6 :   parameter_solv[HIS].push_back(-142176.64081149307);
+    3172           6 :   parameter_solv[HIS].push_back(39642.61185646193);
+    3173             : 
+    3174           6 :   parameter_mix[TRP].push_back(48294.0117571196);
+    3175           6 :   parameter_mix[TRP].push_back(-205.45879626487798);
+    3176           6 :   parameter_mix[TRP].push_back(-148816.1858118254);
+    3177           6 :   parameter_mix[TRP].push_back(-54968.030079609875);
+    3178           6 :   parameter_mix[TRP].push_back(491793.79967057955);
+    3179           6 :   parameter_mix[TRP].push_back(-476312.9117969879);
+    3180           6 :   parameter_mix[TRP].push_back(144159.96165644142);
+    3181             : 
+    3182           6 :   parameter_mix[TYR].push_back(36984.20240312081);
+    3183           6 :   parameter_mix[TYR].push_back(-83.86380083812203);
+    3184           6 :   parameter_mix[TYR].push_back(-108820.52211887162);
+    3185           6 :   parameter_mix[TYR].push_back(-33934.69818901515);
+    3186           6 :   parameter_mix[TYR].push_back(341504.736372253);
+    3187           6 :   parameter_mix[TYR].push_back(-334008.1748614056);
+    3188           6 :   parameter_mix[TYR].push_back(102033.08077851454);
+    3189             : 
+    3190           6 :   parameter_mix[PHE].push_back(32119.469231338233);
+    3191           6 :   parameter_mix[PHE].push_back(-172.96940450568917);
+    3192           6 :   parameter_mix[PHE].push_back(-85831.4326887122);
+    3193           6 :   parameter_mix[PHE].push_back(-33193.32405438845);
+    3194           6 :   parameter_mix[PHE].push_back(262940.64471909316);
+    3195           6 :   parameter_mix[PHE].push_back(-243540.06898907054);
+    3196           6 :   parameter_mix[PHE].push_back(71084.54387480798);
+    3197             : 
+    3198           6 :   parameter_mix[HIP].push_back(22833.36414923898);
+    3199           6 :   parameter_mix[HIP].push_back(-134.0493955562186);
+    3200           6 :   parameter_mix[HIP].push_back(-55325.55607328898);
+    3201           6 :   parameter_mix[HIP].push_back(-21898.314938881984);
+    3202           6 :   parameter_mix[HIP].push_back(159995.6912885654);
+    3203           6 :   parameter_mix[HIP].push_back(-142968.19796084083);
+    3204           6 :   parameter_mix[HIP].push_back(40417.44581470003);
+    3205             : 
+    3206           6 :   parameter_mix[ARG].push_back(31385.401600920715);
+    3207           6 :   parameter_mix[ARG].push_back(36.114094042884254);
+    3208           6 :   parameter_mix[ARG].push_back(-103730.44467490204);
+    3209           6 :   parameter_mix[ARG].push_back(-27036.249157905615);
+    3210           6 :   parameter_mix[ARG].push_back(347011.0339314942);
+    3211           6 :   parameter_mix[ARG].push_back(-358879.9736802336);
+    3212           6 :   parameter_mix[ARG].push_back(114432.18361399164);
+    3213             : 
+    3214           6 :   parameter_mix[LYS].push_back(25511.35812671878);
+    3215           6 :   parameter_mix[LYS].push_back(-130.4381491986372);
+    3216           6 :   parameter_mix[LYS].push_back(-69258.61236879184);
+    3217           6 :   parameter_mix[LYS].push_back(-27066.36783798707);
+    3218           6 :   parameter_mix[LYS].push_back(220092.65231165203);
+    3219           6 :   parameter_mix[LYS].push_back(-207794.5056092443);
+    3220           6 :   parameter_mix[LYS].push_back(61665.57004630315);
+    3221             : 
+    3222           6 :   parameter_mix[CYS].push_back(11505.517261618916);
+    3223           6 :   parameter_mix[CYS].push_back(-33.60468076978334);
+    3224           6 :   parameter_mix[CYS].push_back(-18328.882710004465);
+    3225           6 :   parameter_mix[CYS].push_back(-3956.9113649567626);
+    3226           6 :   parameter_mix[CYS].push_back(27546.35146501212);
+    3227           6 :   parameter_mix[CYS].push_back(-18024.826330595406);
+    3228           6 :   parameter_mix[CYS].push_back(3551.2207387570024);
+    3229             : 
+    3230           6 :   parameter_mix[ASP].push_back(13713.858501879382);
+    3231           6 :   parameter_mix[ASP].push_back(-51.33286241257164);
+    3232           6 :   parameter_mix[ASP].push_back(-23807.8549764091);
+    3233           6 :   parameter_mix[ASP].push_back(-6153.667315935503);
+    3234           6 :   parameter_mix[ASP].push_back(41296.118377286424);
+    3235           6 :   parameter_mix[ASP].push_back(-28740.28391184026);
+    3236           6 :   parameter_mix[ASP].push_back(6132.671533319127);
+    3237             : 
+    3238           6 :   parameter_mix[GLU].push_back(19156.03660739947);
+    3239           6 :   parameter_mix[GLU].push_back(-110.90600703589246);
+    3240           6 :   parameter_mix[GLU].push_back(-40319.3351514524);
+    3241           6 :   parameter_mix[GLU].push_back(-14679.813393816446);
+    3242           6 :   parameter_mix[GLU].push_back(96769.28565573556);
+    3243           6 :   parameter_mix[GLU].push_back(-77909.09315520026);
+    3244           6 :   parameter_mix[GLU].push_back(19770.047062759568);
+    3245             : 
+    3246           6 :   parameter_mix[ILE].push_back(20693.06215917923);
+    3247           6 :   parameter_mix[ILE].push_back(-102.87208880594848);
+    3248           6 :   parameter_mix[ILE].push_back(-41080.44036311675);
+    3249           6 :   parameter_mix[ILE].push_back(-12874.439649378206);
+    3250           6 :   parameter_mix[ILE].push_back(84947.33147117581);
+    3251           6 :   parameter_mix[ILE].push_back(-63779.07871450237);
+    3252           6 :   parameter_mix[ILE].push_back(14938.919981690511);
+    3253             : 
+    3254           6 :   parameter_mix[LEU].push_back(20693.062159179233);
+    3255           6 :   parameter_mix[LEU].push_back(-114.09539845409269);
+    3256           6 :   parameter_mix[LEU].push_back(-42417.3431074524);
+    3257           6 :   parameter_mix[LEU].push_back(-14393.801090829746);
+    3258           6 :   parameter_mix[LEU].push_back(93640.48403643962);
+    3259           6 :   parameter_mix[LEU].push_back(-71990.10354816525);
+    3260           6 :   parameter_mix[LEU].push_back(17299.01082057651);
+    3261             : 
+    3262           6 :   parameter_mix[MET].push_back(22400.800002738917);
+    3263           6 :   parameter_mix[MET].push_back(-138.14469221559762);
+    3264           6 :   parameter_mix[MET].push_back(-53013.97694299946);
+    3265           6 :   parameter_mix[MET].push_back(-21079.899452619244);
+    3266           6 :   parameter_mix[MET].push_back(148607.1089339919);
+    3267           6 :   parameter_mix[MET].push_back(-129827.63962878387);
+    3268           6 :   parameter_mix[MET].push_back(35882.3297822684);
+    3269             : 
+    3270           6 :   parameter_mix[ASN].push_back(14384.287416519475);
+    3271           6 :   parameter_mix[ASN].push_back(-55.24976731179147);
+    3272           6 :   parameter_mix[ASN].push_back(-25372.978199926372);
+    3273           6 :   parameter_mix[ASN].push_back(-6646.452004616925);
+    3274           6 :   parameter_mix[ASN].push_back(44594.5027556148);
+    3275           6 :   parameter_mix[ASN].push_back(-31202.511764907107);
+    3276           6 :   parameter_mix[ASN].push_back(6703.764135873442);
+    3277             : 
+    3278           6 :   parameter_mix[PRO].push_back(13503.797145659117);
+    3279           6 :   parameter_mix[PRO].push_back(-38.58316011847087);
+    3280           6 :   parameter_mix[PRO].push_back(-21446.17847324053);
+    3281           6 :   parameter_mix[PRO].push_back(-4480.55896170459);
+    3282           6 :   parameter_mix[PRO].push_back(31274.287350083254);
+    3283           6 :   parameter_mix[PRO].push_back(-19984.249229169505);
+    3284           6 :   parameter_mix[PRO].push_back(3782.272312712745);
+    3285             : 
+    3286           6 :   parameter_mix[GLN].push_back(19938.23724683901);
+    3287           6 :   parameter_mix[GLN].push_back(-121.24884503048865);
+    3288           6 :   parameter_mix[GLN].push_back(-43928.589472297834);
+    3289           6 :   parameter_mix[GLN].push_back(-16805.069757865473);
+    3290           6 :   parameter_mix[GLN].push_back(112831.61348476357);
+    3291           6 :   parameter_mix[GLN].push_back(-93979.08819184235);
+    3292           6 :   parameter_mix[GLN].push_back(24741.563493163732);
+    3293             : 
+    3294           6 :   parameter_mix[SER].push_back(8813.67020471935);
+    3295           6 :   parameter_mix[SER].push_back(-18.291615317790175);
+    3296           6 :   parameter_mix[SER].push_back(-12585.074732466266);
+    3297           6 :   parameter_mix[SER].push_back(-2064.454891600786);
+    3298           6 :   parameter_mix[SER].push_back(15273.905065790364);
+    3299           6 :   parameter_mix[SER].push_back(-8813.056005263466);
+    3300           6 :   parameter_mix[SER].push_back(1404.9812302289881);
+    3301             : 
+    3302           6 :   parameter_mix[THR].push_back(13233.997179639062);
+    3303           6 :   parameter_mix[THR].push_back(-39.40454157416847);
+    3304           6 :   parameter_mix[THR].push_back(-21430.58717233547);
+    3305           6 :   parameter_mix[THR].push_back(-4566.332853710876);
+    3306           6 :   parameter_mix[THR].push_back(31717.497780073558);
+    3307           6 :   parameter_mix[THR].push_back(-20299.614304281313);
+    3308           6 :   parameter_mix[THR].push_back(3837.207224537505);
+    3309             : 
+    3310           6 :   parameter_mix[VAL].push_back(15135.438016299158);
+    3311           6 :   parameter_mix[VAL].push_back(-51.415141550353205);
+    3312           6 :   parameter_mix[VAL].push_back(-25859.078442379723);
+    3313           6 :   parameter_mix[VAL].push_back(-6007.697291593915);
+    3314           6 :   parameter_mix[VAL].push_back(40997.969600345634);
+    3315           6 :   parameter_mix[VAL].push_back(-27036.257386814148);
+    3316           6 :   parameter_mix[VAL].push_back(5328.922363811635);
+    3317             : 
+    3318           6 :   parameter_mix[ALA].push_back(6586.942863819189);
+    3319           6 :   parameter_mix[ALA].push_back(-10.96713559950907);
+    3320           6 :   parameter_mix[ALA].push_back(-8758.836131731925);
+    3321           6 :   parameter_mix[ALA].push_back(-1223.1723720922605);
+    3322           6 :   parameter_mix[ALA].push_back(9475.182453543037);
+    3323           6 :   parameter_mix[ALA].push_back(-5124.611191433804);
+    3324           6 :   parameter_mix[ALA].push_back(721.7625962949869);
+    3325             : 
+    3326           6 :   parameter_mix[GLY].push_back(3596.0718542192762);
+    3327           6 :   parameter_mix[GLY].push_back(-4.079285964028122);
+    3328           6 :   parameter_mix[GLY].push_back(-4089.4217504382686);
+    3329           6 :   parameter_mix[GLY].push_back(-450.9650932154967);
+    3330           6 :   parameter_mix[GLY].push_back(3737.026778223427);
+    3331           6 :   parameter_mix[GLY].push_back(-1862.9856575810572);
+    3332           6 :   parameter_mix[GLY].push_back(222.97288276257262);
+    3333             : 
+    3334           6 :   parameter_mix[HIS].push_back(21779.124723299232);
+    3335           6 :   parameter_mix[HIS].push_back(-131.4603421188538);
+    3336           6 :   parameter_mix[HIS].push_back(-49068.74667421681);
+    3337           6 :   parameter_mix[HIS].push_back(-18685.909496392127);
+    3338           6 :   parameter_mix[HIS].push_back(127724.60792384286);
+    3339           6 :   parameter_mix[HIS].push_back(-107419.22159440348);
+    3340           6 :   parameter_mix[HIS].push_back(28577.228634530744);
+    3341             : 
+    3342           6 :   parameter_vac[TRP].push_back(9599.949107368187);
+    3343           6 :   parameter_vac[TRP].push_back(-66.35331786175249);
+    3344           6 :   parameter_vac[TRP].push_back(-26311.640290970638);
+    3345           6 :   parameter_vac[TRP].push_back(-11577.314600529338);
+    3346           6 :   parameter_vac[TRP].push_back(85847.52554160352);
+    3347           6 :   parameter_vac[TRP].push_back(-79417.17065742958);
+    3348           6 :   parameter_vac[TRP].push_back(23090.348430572863);
+    3349             : 
+    3350           6 :   parameter_vac[TYR].push_back(7393.553846412945);
+    3351           6 :   parameter_vac[TYR].push_back(-27.51954035778316);
+    3352           6 :   parameter_vac[TYR].push_back(-20329.10485615286);
+    3353           6 :   parameter_vac[TYR].push_back(-7444.276340508767);
+    3354           6 :   parameter_vac[TYR].push_back(66343.22315132803);
+    3355           6 :   parameter_vac[TYR].push_back(-64470.58721639446);
+    3356           6 :   parameter_vac[TYR].push_back(19614.63563898146);
+    3357             : 
+    3358           6 :   parameter_vac[PHE].push_back(6081.874997705279);
+    3359           6 :   parameter_vac[PHE].push_back(-40.474695969500104);
+    3360           6 :   parameter_vac[PHE].push_back(-14354.627390498901);
+    3361           6 :   parameter_vac[PHE].push_back(-6156.69750315959);
+    3362           6 :   parameter_vac[PHE].push_back(42580.84239395237);
+    3363           6 :   parameter_vac[PHE].push_back(-37704.09749809582);
+    3364           6 :   parameter_vac[PHE].push_back(10543.005717478625);
+    3365             : 
+    3366           6 :   parameter_vac[HIP].push_back(5325.791987063724);
+    3367           6 :   parameter_vac[HIP].push_back(-35.512112257530156);
+    3368           6 :   parameter_vac[HIP].push_back(-11488.443296477566);
+    3369           6 :   parameter_vac[HIP].push_back(-4916.724935318093);
+    3370           6 :   parameter_vac[HIP].push_back(32134.338675979947);
+    3371           6 :   parameter_vac[HIP].push_back(-27388.387595464188);
+    3372           6 :   parameter_vac[HIP].push_back(7359.899986748838);
+    3373             : 
+    3374           6 :   parameter_vac[ARG].push_back(7220.306892248294);
+    3375           6 :   parameter_vac[ARG].push_back(-20.65912886190997);
+    3376           6 :   parameter_vac[ARG].push_back(-22700.70129646048);
+    3377           6 :   parameter_vac[ARG].push_back(-8696.901551172636);
+    3378           6 :   parameter_vac[ARG].push_back(83641.36257312517);
+    3379           6 :   parameter_vac[ARG].push_back(-85237.33676336925);
+    3380           6 :   parameter_vac[ARG].push_back(26899.162688310953);
+    3381             : 
+    3382           6 :   parameter_vac[LYS].push_back(5038.613120729022);
+    3383           6 :   parameter_vac[LYS].push_back(-34.08366887546492);
+    3384           6 :   parameter_vac[LYS].push_back(-12812.921120433106);
+    3385           6 :   parameter_vac[LYS].push_back(-5843.761329082788);
+    3386           6 :   parameter_vac[LYS].push_back(42419.08427856609);
+    3387           6 :   parameter_vac[LYS].push_back(-39460.49038159249);
+    3388           6 :   parameter_vac[LYS].push_back(11542.320830663035);
+    3389             : 
+    3390           6 :   parameter_vac[CYS].push_back(2915.0458981763995);
+    3391           6 :   parameter_vac[CYS].push_back(-5.380571839804511);
+    3392           6 :   parameter_vac[CYS].push_back(-3865.366285883624);
+    3393           6 :   parameter_vac[CYS].push_back(-602.3275271136284);
+    3394           6 :   parameter_vac[CYS].push_back(4524.133086072617);
+    3395           6 :   parameter_vac[CYS].push_back(-2537.87137720241);
+    3396           6 :   parameter_vac[CYS].push_back(381.52870758240016);
+    3397             : 
+    3398           6 :   parameter_vac[ASP].push_back(3479.750728224898);
+    3399           6 :   parameter_vac[ASP].push_back(-10.33897891836596);
+    3400           6 :   parameter_vac[ASP].push_back(-5382.628188436401);
+    3401           6 :   parameter_vac[ASP].push_back(-1183.8060939576694);
+    3402           6 :   parameter_vac[ASP].push_back(8100.082378727997);
+    3403           6 :   parameter_vac[ASP].push_back(-5162.630696148773);
+    3404           6 :   parameter_vac[ASP].push_back(958.993022379732);
+    3405             : 
+    3406           6 :   parameter_vac[GLU].push_back(4487.461543955491);
+    3407           6 :   parameter_vac[GLU].push_back(-26.671865751817936);
+    3408           6 :   parameter_vac[GLU].push_back(-8829.738168429001);
+    3409           6 :   parameter_vac[GLU].push_back(-3297.668395415257);
+    3410           6 :   parameter_vac[GLU].push_back(20686.457747123466);
+    3411           6 :   parameter_vac[GLU].push_back(-16030.814134196151);
+    3412           6 :   parameter_vac[GLU].push_back(3858.4457728083275);
+    3413             : 
+    3414           6 :   parameter_vac[ILE].push_back(3842.5968201937776);
+    3415           6 :   parameter_vac[ILE].push_back(-13.848165050578492);
+    3416           6 :   parameter_vac[ILE].push_back(-6480.062699452774);
+    3417           6 :   parameter_vac[ILE].push_back(-1636.3888925440413);
+    3418           6 :   parameter_vac[ILE].push_back(10967.333210698738);
+    3419           6 :   parameter_vac[ILE].push_back(-7483.704914714421);
+    3420           6 :   parameter_vac[ILE].push_back(1548.5696047594895);
+    3421             : 
+    3422           6 :   parameter_vac[LEU].push_back(3842.5968201937785);
+    3423           6 :   parameter_vac[LEU].push_back(-16.2745108270949);
+    3424           6 :   parameter_vac[LEU].push_back(-6807.110269770606);
+    3425           6 :   parameter_vac[LEU].push_back(-1926.6303434106014);
+    3426           6 :   parameter_vac[LEU].push_back(12577.952756390941);
+    3427           6 :   parameter_vac[LEU].push_back(-8829.40489330961);
+    3428           6 :   parameter_vac[LEU].push_back(1882.919316016889);
+    3429             : 
+    3430           6 :   parameter_vac[MET].push_back(4898.512892967389);
+    3431           6 :   parameter_vac[MET].push_back(-30.588244886468207);
+    3432           6 :   parameter_vac[MET].push_back(-10159.093665859045);
+    3433           6 :   parameter_vac[MET].push_back(-4025.0261508449653);
+    3434           6 :   parameter_vac[MET].push_back(26007.394369425827);
+    3435           6 :   parameter_vac[MET].push_back(-21199.218680206573);
+    3436           6 :   parameter_vac[MET].push_back(5423.004225853842);
+    3437             : 
+    3438           6 :   parameter_vac[ASN].push_back(3598.1423998115492);
+    3439           6 :   parameter_vac[ASN].push_back(-10.357995638888545);
+    3440           6 :   parameter_vac[ASN].push_back(-5565.603011562138);
+    3441           6 :   parameter_vac[ASN].push_back(-1190.3294930971967);
+    3442           6 :   parameter_vac[ASN].push_back(8227.920711951123);
+    3443           6 :   parameter_vac[ASN].push_back(-5222.61541118056);
+    3444           6 :   parameter_vac[ASN].push_back(968.593406702772);
+    3445             : 
+    3446           6 :   parameter_vac[PRO].push_back(2702.925890807494);
+    3447           6 :   parameter_vac[PRO].push_back(-4.11690159421177);
+    3448           6 :   parameter_vac[PRO].push_back(-3395.325331307625);
+    3449           6 :   parameter_vac[PRO].push_back(-458.95242128002894);
+    3450           6 :   parameter_vac[PRO].push_back(3584.3640448715823);
+    3451           6 :   parameter_vac[PRO].push_back(-1921.4140769384692);
+    3452           6 :   parameter_vac[PRO].push_back(267.08577848319516);
+    3453             : 
+    3454           6 :   parameter_vac[GLN].push_back(4621.773132292556);
+    3455           6 :   parameter_vac[GLN].push_back(-29.511778489038818);
+    3456           6 :   parameter_vac[GLN].push_back(-9486.077450010192);
+    3457           6 :   parameter_vac[GLN].push_back(-3768.5756897489828);
+    3458           6 :   parameter_vac[GLN].push_back(23828.07111260487);
+    3459           6 :   parameter_vac[GLN].push_back(-19110.205836780202);
+    3460           6 :   parameter_vac[GLN].push_back(4791.718204894083);
+    3461             : 
+    3462           6 :   parameter_vac[SER].push_back(2115.1504654043965);
+    3463           6 :   parameter_vac[SER].push_back(-2.4158378234251234);
+    3464           6 :   parameter_vac[SER].push_back(-2488.1131972903822);
+    3465           6 :   parameter_vac[SER].push_back(-263.64072945387693);
+    3466           6 :   parameter_vac[SER].push_back(2251.376687850687);
+    3467           6 :   parameter_vac[SER].push_back(-1066.0790768852626);
+    3468           6 :   parameter_vac[SER].push_back(105.5155397911316);
+    3469             : 
+    3470           6 :   parameter_vac[THR].push_back(2914.9061707158835);
+    3471           6 :   parameter_vac[THR].push_back(-5.032844592364407);
+    3472           6 :   parameter_vac[THR].push_back(-3903.2546253886653);
+    3473           6 :   parameter_vac[THR].push_back(-559.4734271244915);
+    3474           6 :   parameter_vac[THR].push_back(4315.044828297787);
+    3475           6 :   parameter_vac[THR].push_back(-2331.211908177365);
+    3476           6 :   parameter_vac[THR].push_back(323.76849758109853);
+    3477             : 
+    3478           6 :   parameter_vac[VAL].push_back(2914.8744247581953);
+    3479           6 :   parameter_vac[VAL].push_back(-5.847217106105881);
+    3480           6 :   parameter_vac[VAL].push_back(-4096.370479502377);
+    3481           6 :   parameter_vac[VAL].push_back(-655.2917606620404);
+    3482           6 :   parameter_vac[VAL].push_back(4888.77261250007);
+    3483           6 :   parameter_vac[VAL].push_back(-2765.7552774385167);
+    3484           6 :   parameter_vac[VAL].push_back(421.9081598033515);
+    3485             : 
+    3486           6 :   parameter_vac[ALA].push_back(1443.3438146824446);
+    3487           6 :   parameter_vac[ALA].push_back(-1.1234573178567506);
+    3488           6 :   parameter_vac[ALA].push_back(-1492.4547663363514);
+    3489           6 :   parameter_vac[ALA].push_back(-121.47935619968672);
+    3490           6 :   parameter_vac[ALA].push_back(1139.689871538201);
+    3491           6 :   parameter_vac[ALA].push_back(-483.8336547914466);
+    3492           6 :   parameter_vac[ALA].push_back(32.48231950404626);
+    3493             : 
+    3494           6 :   parameter_vac[GLY].push_back(899.5356000422925);
+    3495           6 :   parameter_vac[GLY].push_back(-0.5200880084066986);
+    3496           6 :   parameter_vac[GLY].push_back(-787.5892053280859);
+    3497           6 :   parameter_vac[GLY].push_back(-56.07596224884467);
+    3498           6 :   parameter_vac[GLY].push_back(546.4212287680981);
+    3499           6 :   parameter_vac[GLY].push_back(-222.2667666932616);
+    3500           6 :   parameter_vac[GLY].push_back(12.474587265791476);
+    3501             : 
+    3502           6 :   parameter_vac[HIS].push_back(5180.842705000207);
+    3503           6 :   parameter_vac[HIS].push_back(-29.578973475252766);
+    3504           6 :   parameter_vac[HIS].push_back(-10323.417251934066);
+    3505           6 :   parameter_vac[HIS].push_back(-3788.977215582307);
+    3506           6 :   parameter_vac[HIS].push_back(24427.720792289427);
+    3507           6 :   parameter_vac[HIS].push_back(-19307.35836837878);
+    3508           6 :   parameter_vac[HIS].push_back(4780.831414992477);
+    3509             : 
+    3510             :   // NUCLEIC ACIDS
+    3511             : 
+    3512           6 :   parameter_solv[BB_PO2].push_back(575.5201001192197);
+    3513           6 :   parameter_solv[BB_PO2].push_back(-0.6126595489733868);
+    3514           6 :   parameter_solv[BB_PO2].push_back(-623.3371092254897);
+    3515           6 :   parameter_solv[BB_PO2].push_back(-68.05795957022156);
+    3516           6 :   parameter_solv[BB_PO2].push_back(561.8052621243662);
+    3517           6 :   parameter_solv[BB_PO2].push_back(-283.39573309540344);
+    3518           6 :   parameter_solv[BB_PO2].push_back(35.55001698010027);
+    3519             : 
+    3520           6 :   parameter_solv[BB_DNA].push_back(21211.009600118316);
+    3521           6 :   parameter_solv[BB_DNA].push_back(-90.18805990529991);
+    3522           6 :   parameter_solv[BB_DNA].push_back(-39731.1337351215);
+    3523           6 :   parameter_solv[BB_DNA].push_back(-10920.373563712878);
+    3524           6 :   parameter_solv[BB_DNA].push_back(72882.21702424977);
+    3525           6 :   parameter_solv[BB_DNA].push_back(-51747.487078112754);
+    3526           6 :   parameter_solv[BB_DNA].push_back(11308.67842901876);
+    3527             : 
+    3528           6 :   parameter_solv[BB_DNA_5].push_back(22737.624100119025);
+    3529           6 :   parameter_solv[BB_DNA_5].push_back(-102.72714886664163);
+    3530           6 :   parameter_solv[BB_DNA_5].push_back(-43685.329677789705);
+    3531           6 :   parameter_solv[BB_DNA_5].push_back(-12564.259374093454);
+    3532           6 :   parameter_solv[BB_DNA_5].push_back(83454.87540484876);
+    3533           6 :   parameter_solv[BB_DNA_5].push_back(-60367.15652138888);
+    3534           6 :   parameter_solv[BB_DNA_5].push_back(13507.33372986899);
+    3535             : 
+    3536           6 :   parameter_solv[BB_DNA_3].push_back(22737.62410011902);
+    3537           6 :   parameter_solv[BB_DNA_3].push_back(-101.57816684452263);
+    3538           6 :   parameter_solv[BB_DNA_3].push_back(-43488.53670557616);
+    3539           6 :   parameter_solv[BB_DNA_3].push_back(-12345.056184958417);
+    3540           6 :   parameter_solv[BB_DNA_3].push_back(81963.5236411489);
+    3541           6 :   parameter_solv[BB_DNA_3].push_back(-58791.59443618196);
+    3542           6 :   parameter_solv[BB_DNA_3].push_back(13003.199362335576);
+    3543             : 
+    3544           6 :   parameter_solv[BB_RNA].push_back(23953.752900120977);
+    3545           6 :   parameter_solv[BB_RNA].push_back(-117.35779348824401);
+    3546           6 :   parameter_solv[BB_RNA].push_back(-47644.41735332837);
+    3547           6 :   parameter_solv[BB_RNA].push_back(-14641.556643789863);
+    3548           6 :   parameter_solv[BB_RNA].push_back(96893.48627050382);
+    3549           6 :   parameter_solv[BB_RNA].push_back(-72249.62534169314);
+    3550           6 :   parameter_solv[BB_RNA].push_back(16792.05552105538);
+    3551             : 
+    3552           6 :   parameter_solv[BB_RNA_5].push_back(25574.406400119024);
+    3553           6 :   parameter_solv[BB_RNA_5].push_back(-131.99642772933734);
+    3554           6 :   parameter_solv[BB_RNA_5].push_back(-52136.51404531249);
+    3555           6 :   parameter_solv[BB_RNA_5].push_back(-16682.14273917604);
+    3556           6 :   parameter_solv[BB_RNA_5].push_back(110278.019216394);
+    3557           6 :   parameter_solv[BB_RNA_5].push_back(-83715.92027818545);
+    3558           6 :   parameter_solv[BB_RNA_5].push_back(19875.891337706045);
+    3559             : 
+    3560           6 :   parameter_solv[BB_RNA_3].push_back(25574.406400119024);
+    3561           6 :   parameter_solv[BB_RNA_3].push_back(-127.96875237036166);
+    3562           6 :   parameter_solv[BB_RNA_3].push_back(-51407.183917584385);
+    3563           6 :   parameter_solv[BB_RNA_3].push_back(-15922.900669975606);
+    3564           6 :   parameter_solv[BB_RNA_3].push_back(105078.58889106264);
+    3565           6 :   parameter_solv[BB_RNA_3].push_back(-78289.16276190648);
+    3566           6 :   parameter_solv[BB_RNA_3].push_back(18156.83214344118);
+    3567             : 
+    3568           6 :   parameter_solv[BASE_A].push_back(13282.562500119211);
+    3569           6 :   parameter_solv[BASE_A].push_back(-76.45124168404048);
+    3570           6 :   parameter_solv[BASE_A].push_back(-28376.06994108963);
+    3571           6 :   parameter_solv[BASE_A].push_back(-9972.910773722022);
+    3572           6 :   parameter_solv[BASE_A].push_back(65873.86341939073);
+    3573           6 :   parameter_solv[BASE_A].push_back(-52064.33492910885);
+    3574           6 :   parameter_solv[BASE_A].push_back(12931.608989412513);
+    3575             : 
+    3576           6 :   parameter_solv[BASE_C].push_back(10600.76160011891);
+    3577           6 :   parameter_solv[BASE_C].push_back(-49.1670871249108);
+    3578           6 :   parameter_solv[BASE_C].push_back(-20239.818742072875);
+    3579           6 :   parameter_solv[BASE_C].push_back(-6020.278780090207);
+    3580           6 :   parameter_solv[BASE_C].push_back(39632.13288981881);
+    3581           6 :   parameter_solv[BASE_C].push_back(-28954.779736165576);
+    3582           6 :   parameter_solv[BASE_C].push_back(6551.541109526305);
+    3583             : 
+    3584           6 :   parameter_solv[BASE_G].push_back(15470.384400119934);
+    3585           6 :   parameter_solv[BASE_G].push_back(-93.8013620200972);
+    3586           6 :   parameter_solv[BASE_G].push_back(-36188.29687013545);
+    3587           6 :   parameter_solv[BASE_G].push_back(-13717.685098209471);
+    3588           6 :   parameter_solv[BASE_G].push_back(95658.18473657136);
+    3589           6 :   parameter_solv[BASE_G].push_back(-81262.37811451119);
+    3590           6 :   parameter_solv[BASE_G].push_back(21841.903930943085);
+    3591             : 
+    3592           6 :   parameter_solv[BASE_T].push_back(17210.81610011936);
+    3593           6 :   parameter_solv[BASE_T].push_back(-93.10189802920208);
+    3594           6 :   parameter_solv[BASE_T].push_back(-36466.51927689957);
+    3595           6 :   parameter_solv[BASE_T].push_back(-12425.55615716932);
+    3596           6 :   parameter_solv[BASE_T].push_back(83847.427808925);
+    3597           6 :   parameter_solv[BASE_T].push_back(-66735.64997846584);
+    3598           6 :   parameter_solv[BASE_T].push_back(16757.3463987507);
+    3599             : 
+    3600           6 :   parameter_solv[BASE_U].push_back(10909.802500119395);
+    3601           6 :   parameter_solv[BASE_U].push_back(-46.17712672768298);
+    3602           6 :   parameter_solv[BASE_U].push_back(-20149.67695512526);
+    3603           6 :   parameter_solv[BASE_U].push_back(-5590.242961204435);
+    3604           6 :   parameter_solv[BASE_U].push_back(37169.2740983132);
+    3605           6 :   parameter_solv[BASE_U].push_back(-26475.631627167604);
+    3606           6 :   parameter_solv[BASE_U].push_back(5808.201015156168);
+    3607             : 
+    3608           6 :   parameter_mix[BB_PO2].push_back(1487.2888381188868);
+    3609           6 :   parameter_mix[BB_PO2].push_back(-0.6155376265599789);
+    3610           6 :   parameter_mix[BB_PO2].push_back(-1181.5076027691764);
+    3611           6 :   parameter_mix[BB_PO2].push_back(-66.25027450710594);
+    3612           6 :   parameter_mix[BB_PO2].push_back(697.0421991965113);
+    3613           6 :   parameter_mix[BB_PO2].push_back(-261.8559466354847);
+    3614           6 :   parameter_mix[BB_PO2].push_back(9.974337082362194);
+    3615             : 
+    3616           6 :   parameter_mix[BB_DNA].push_back(17766.29474499878);
+    3617           6 :   parameter_mix[BB_DNA].push_back(-48.97330188566253);
+    3618           6 :   parameter_mix[BB_DNA].push_back(-28199.563596327207);
+    3619           6 :   parameter_mix[BB_DNA].push_back(-5623.82085602494);
+    3620           6 :   parameter_mix[BB_DNA].push_back(39646.22954828498);
+    3621           6 :   parameter_mix[BB_DNA].push_back(-24658.81157651943);
+    3622           6 :   parameter_mix[BB_DNA].push_back(4453.73906293146);
+    3623             : 
+    3624           6 :   parameter_mix[BB_DNA_5].push_back(18696.09744203927);
+    3625           6 :   parameter_mix[BB_DNA_5].push_back(-56.29408880833802);
+    3626           6 :   parameter_mix[BB_DNA_5].push_back(-30486.108599707608);
+    3627           6 :   parameter_mix[BB_DNA_5].push_back(-6524.195857141158);
+    3628           6 :   parameter_mix[BB_DNA_5].push_back(45280.80142686446);
+    3629           6 :   parameter_mix[BB_DNA_5].push_back(-29007.98616567993);
+    3630           6 :   parameter_mix[BB_DNA_5].push_back(5488.566965501818);
+    3631             : 
+    3632           6 :   parameter_mix[BB_DNA_3].push_back(18696.097442039274);
+    3633           6 :   parameter_mix[BB_DNA_3].push_back(-55.5645003501971);
+    3634           6 :   parameter_mix[BB_DNA_3].push_back(-30422.262113654506);
+    3635           6 :   parameter_mix[BB_DNA_3].push_back(-6409.659659309089);
+    3636           6 :   parameter_mix[BB_DNA_3].push_back(44605.76043515699);
+    3637           6 :   parameter_mix[BB_DNA_3].push_back(-28295.62152988411);
+    3638           6 :   parameter_mix[BB_DNA_3].push_back(5262.5765863484);
+    3639             : 
+    3640           6 :   parameter_mix[BB_RNA].push_back(21356.177105457366);
+    3641           6 :   parameter_mix[BB_RNA].push_back(-76.73490647754872);
+    3642           6 :   parameter_mix[BB_RNA].push_back(-36845.234814782816);
+    3643           6 :   parameter_mix[BB_RNA].push_back(-9066.559625582728);
+    3644           6 :   parameter_mix[BB_RNA].push_back(61167.998793390485);
+    3645           6 :   parameter_mix[BB_RNA].push_back(-41467.23384423218);
+    3646           6 :   parameter_mix[BB_RNA].push_back(8518.937793863257);
+    3647             : 
+    3648           6 :   parameter_mix[BB_RNA_5].push_back(22386.63276427916);
+    3649           6 :   parameter_mix[BB_RNA_5].push_back(-85.70426456933487);
+    3650           6 :   parameter_mix[BB_RNA_5].push_back(-39490.50298502025);
+    3651           6 :   parameter_mix[BB_RNA_5].push_back(-10223.702594972712);
+    3652           6 :   parameter_mix[BB_RNA_5].push_back(68450.60459618448);
+    3653           6 :   parameter_mix[BB_RNA_5].push_back(-47409.91098159006);
+    3654           6 :   parameter_mix[BB_RNA_5].push_back(10031.136138513202);
+    3655             : 
+    3656           6 :   parameter_mix[BB_RNA_3].push_back(22386.63276427916);
+    3657           6 :   parameter_mix[BB_RNA_3].push_back(-81.93760812351479);
+    3658           6 :   parameter_mix[BB_RNA_3].push_back(-39031.70571520093);
+    3659           6 :   parameter_mix[BB_RNA_3].push_back(-9666.316086142708);
+    3660           6 :   parameter_mix[BB_RNA_3].push_back(65120.07128126262);
+    3661           6 :   parameter_mix[BB_RNA_3].push_back(-44110.13603681317);
+    3662           6 :   parameter_mix[BB_RNA_3].push_back(9036.76498256983);
+    3663             : 
+    3664           6 :   parameter_mix[BASE_A].push_back(15897.31116611889);
+    3665           6 :   parameter_mix[BASE_A].push_back(-67.86385832953485);
+    3666           6 :   parameter_mix[BASE_A].push_back(-28851.754660951636);
+    3667           6 :   parameter_mix[BASE_A].push_back(-8144.431687170413);
+    3668           6 :   parameter_mix[BASE_A].push_back(53606.39082954489);
+    3669           6 :   parameter_mix[BASE_A].push_back(-38083.51243782253);
+    3670           6 :   parameter_mix[BASE_A].push_back(8293.47107993253);
+    3671             : 
+    3672           6 :   parameter_mix[BASE_C].push_back(11733.2828871599);
+    3673           6 :   parameter_mix[BASE_C].push_back(-38.76775400274115);
+    3674           6 :   parameter_mix[BASE_C].push_back(-19318.84666423464);
+    3675           6 :   parameter_mix[BASE_C].push_back(-4507.915522704176);
+    3676           6 :   parameter_mix[BASE_C].push_back(30576.57671286052);
+    3677           6 :   parameter_mix[BASE_C].push_back(-20132.46696910844);
+    3678           6 :   parameter_mix[BASE_C].push_back(3947.8727087996162);
+    3679             : 
+    3680           6 :   parameter_mix[BASE_G].push_back(19146.612417237808);
+    3681           6 :   parameter_mix[BASE_G].push_back(-102.37046638004914);
+    3682           6 :   parameter_mix[BASE_G].push_back(-38718.96478190546);
+    3683           6 :   parameter_mix[BASE_G].push_back(-13238.106081860074);
+    3684           6 :   parameter_mix[BASE_G].push_back(87309.07460288722);
+    3685           6 :   parameter_mix[BASE_G].push_back(-68364.82442984737);
+    3686           6 :   parameter_mix[BASE_G].push_back(16815.362401369);
+    3687             : 
+    3688           6 :   parameter_mix[BASE_T].push_back(17050.440260819163);
+    3689           6 :   parameter_mix[BASE_T].push_back(-76.33750600643376);
+    3690           6 :   parameter_mix[BASE_T].push_back(-31849.539096715005);
+    3691           6 :   parameter_mix[BASE_T].push_back(-9484.498992751434);
+    3692           6 :   parameter_mix[BASE_T].push_back(62881.895771680494);
+    3693           6 :   parameter_mix[BASE_T].push_back(-46531.948557759024);
+    3694           6 :   parameter_mix[BASE_T].push_back(10734.196329884822);
+    3695             : 
+    3696           6 :   parameter_mix[BASE_U].push_back(11904.095265219023);
+    3697           6 :   parameter_mix[BASE_U].push_back(-34.67511054915295);
+    3698           6 :   parameter_mix[BASE_U].push_back(-18842.275003104005);
+    3699           6 :   parameter_mix[BASE_U].push_back(-3993.1174764890684);
+    3700           6 :   parameter_mix[BASE_U].push_back(27663.625106762345);
+    3701           6 :   parameter_mix[BASE_U].push_back(-17577.387831701515);
+    3702           6 :   parameter_mix[BASE_U].push_back(3273.183903219142);
+    3703             : 
+    3704           6 :   parameter_vac[BB_PO2].push_back(960.8822037291127);
+    3705           6 :   parameter_vac[BB_PO2].push_back(-0.09312135742159174);
+    3706           6 :   parameter_vac[BB_PO2].push_back(-469.39643497461844);
+    3707           6 :   parameter_vac[BB_PO2].push_back(-9.779346709041985);
+    3708           6 :   parameter_vac[BB_PO2].push_back(162.1581550003227);
+    3709           6 :   parameter_vac[BB_PO2].push_back(-37.06686233305618);
+    3710           6 :   parameter_vac[BB_PO2].push_back(-4.695586672655664);
+    3711             : 
+    3712           6 :   parameter_vac[BB_DNA].push_back(3720.2522996838984);
+    3713           6 :   parameter_vac[BB_DNA].push_back(-5.4229642176938);
+    3714           6 :   parameter_vac[BB_DNA].push_back(-4800.897672711981);
+    3715           6 :   parameter_vac[BB_DNA].push_back(-597.2274673070993);
+    3716           6 :   parameter_vac[BB_DNA].push_back(4825.908840953665);
+    3717           6 :   parameter_vac[BB_DNA].push_back(-2451.397454446564);
+    3718           6 :   parameter_vac[BB_DNA].push_back(294.93071756645685);
+    3719             : 
+    3720           6 :   parameter_vac[BB_DNA_5].push_back(3843.234214262163);
+    3721           6 :   parameter_vac[BB_DNA_5].push_back(-6.423078416284452);
+    3722           6 :   parameter_vac[BB_DNA_5].push_back(-5112.1216386963115);
+    3723           6 :   parameter_vac[BB_DNA_5].push_back(-713.8373583426668);
+    3724           6 :   parameter_vac[BB_DNA_5].push_back(5547.545382516269);
+    3725           6 :   parameter_vac[BB_DNA_5].push_back(-2973.5659871174225);
+    3726           6 :   parameter_vac[BB_DNA_5].push_back(407.2789106630427);
+    3727             : 
+    3728           6 :   parameter_vac[BB_DNA_3].push_back(3843.234214262163);
+    3729           6 :   parameter_vac[BB_DNA_3].push_back(-6.268636561475645);
+    3730           6 :   parameter_vac[BB_DNA_3].push_back(-5103.192931218086);
+    3731           6 :   parameter_vac[BB_DNA_3].push_back(-693.8705734390547);
+    3732           6 :   parameter_vac[BB_DNA_3].push_back(5443.979645097035);
+    3733           6 :   parameter_vac[BB_DNA_3].push_back(-2871.4337477324893);
+    3734           6 :   parameter_vac[BB_DNA_3].push_back(377.3062915349831);
+    3735             : 
+    3736           6 :   parameter_vac[BB_RNA].push_back(4760.071443398374);
+    3737           6 :   parameter_vac[BB_RNA].push_back(-11.0990475402486);
+    3738           6 :   parameter_vac[BB_RNA].push_back(-6934.713566418421);
+    3739           6 :   parameter_vac[BB_RNA].push_back(-1256.5202524085096);
+    3740           6 :   parameter_vac[BB_RNA].push_back(9024.962587066922);
+    3741           6 :   parameter_vac[BB_RNA].push_back(-5386.842667932241);
+    3742           6 :   parameter_vac[BB_RNA].push_back(907.42947751372);
+    3743             : 
+    3744           6 :   parameter_vac[BB_RNA_5].push_back(4899.051406033406);
+    3745           6 :   parameter_vac[BB_RNA_5].push_back(-12.279240472628238);
+    3746           6 :   parameter_vac[BB_RNA_5].push_back(-7276.273570813667);
+    3747           6 :   parameter_vac[BB_RNA_5].push_back(-1400.9520839250868);
+    3748           6 :   parameter_vac[BB_RNA_5].push_back(9912.215823228895);
+    3749           6 :   parameter_vac[BB_RNA_5].push_back(-6079.2565270404075);
+    3750           6 :   parameter_vac[BB_RNA_5].push_back(1073.53428175472);
+    3751             : 
+    3752           6 :   parameter_vac[BB_RNA_3].push_back(4899.051406033406);
+    3753           6 :   parameter_vac[BB_RNA_3].push_back(-11.642804195148194);
+    3754           6 :   parameter_vac[BB_RNA_3].push_back(-7213.774619570996);
+    3755           6 :   parameter_vac[BB_RNA_3].push_back(-1317.4463949342964);
+    3756           6 :   parameter_vac[BB_RNA_3].push_back(9450.928929264686);
+    3757           6 :   parameter_vac[BB_RNA_3].push_back(-5643.856117200917);
+    3758           6 :   parameter_vac[BB_RNA_3].push_back(949.4698817407918);
+    3759             : 
+    3760           6 :   parameter_vac[BASE_A].push_back(4756.697028810353);
+    3761           6 :   parameter_vac[BASE_A].push_back(-12.158940746852812);
+    3762           6 :   parameter_vac[BASE_A].push_back(-7106.473423744205);
+    3763           6 :   parameter_vac[BASE_A].push_back(-1376.295184173137);
+    3764           6 :   parameter_vac[BASE_A].push_back(9747.132255557788);
+    3765           6 :   parameter_vac[BASE_A].push_back(-5900.026637038756);
+    3766           6 :   parameter_vac[BASE_A].push_back(1004.6226388342955);
+    3767             : 
+    3768           6 :   parameter_vac[BASE_C].push_back(3246.698975674651);
+    3769           6 :   parameter_vac[BASE_C].push_back(-6.125036521218687);
+    3770           6 :   parameter_vac[BASE_C].push_back(-4280.666521437201);
+    3771           6 :   parameter_vac[BASE_C].push_back(-684.0183580843932);
+    3772           6 :   parameter_vac[BASE_C].push_back(5077.062889522692);
+    3773           6 :   parameter_vac[BASE_C].push_back(-2870.3239317750963);
+    3774           6 :   parameter_vac[BASE_C].push_back(434.51551177863547);
+    3775             : 
+    3776           6 :   parameter_vac[BASE_G].push_back(5924.105658596052);
+    3777           6 :   parameter_vac[BASE_G].push_back(-23.097956587232552);
+    3778           6 :   parameter_vac[BASE_G].push_back(-10149.526301285418);
+    3779           6 :   parameter_vac[BASE_G].push_back(-2752.9166169522528);
+    3780           6 :   parameter_vac[BASE_G].push_back(18239.32985385683);
+    3781           6 :   parameter_vac[BASE_G].push_back(-12749.277858800957);
+    3782           6 :   parameter_vac[BASE_G].push_back(2715.354663787367);
+    3783             : 
+    3784           6 :   parameter_vac[BASE_T].push_back(4222.889713694404);
+    3785           6 :   parameter_vac[BASE_T].push_back(-12.15861456306705);
+    3786           6 :   parameter_vac[BASE_T].push_back(-6395.50289789404);
+    3787           6 :   parameter_vac[BASE_T].push_back(-1421.3942549301012);
+    3788           6 :   parameter_vac[BASE_T].push_back(9757.061008720135);
+    3789           6 :   parameter_vac[BASE_T].push_back(-6399.630933839126);
+    3790           6 :   parameter_vac[BASE_T].push_back(1258.9874225605438);
+    3791             : 
+    3792           6 :   parameter_vac[BASE_U].push_back(3247.251361465539);
+    3793           6 :   parameter_vac[BASE_U].push_back(-5.211020853261115);
+    3794           6 :   parameter_vac[BASE_U].push_back(-4125.165310360279);
+    3795           6 :   parameter_vac[BASE_U].push_back(-575.1860235473902);
+    3796           6 :   parameter_vac[BASE_U].push_back(4457.6562621371495);
+    3797           6 :   parameter_vac[BASE_U].push_back(-2368.7250146912766);
+    3798           6 :   parameter_vac[BASE_U].push_back(313.23997718445014);
+    3799             : 
+    3800       21178 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    3801       21172 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    3802       21172 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    3803       21172 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    3804       21172 :     if(Rname=="ALA") {
+    3805        1098 :       atoi[residue_atom[i]]=ALA;
+    3806       20074 :     } else if(Rname=="ARG") {
+    3807        1296 :       atoi[residue_atom[i]]=ARG;
+    3808       18778 :     } else if(Rname=="ASN") {
+    3809        1080 :       atoi[residue_atom[i]]=ASN;
+    3810       17698 :     } else if(Rname=="ASP") {
+    3811         936 :       atoi[residue_atom[i]]=ASP;
+    3812       16762 :     } else if(Rname=="CYS") {
+    3813          72 :       atoi[residue_atom[i]]=CYS;
+    3814       16690 :     } else if(Rname=="GLN") {
+    3815        1596 :       atoi[residue_atom[i]]=GLN;
+    3816       15094 :     } else if(Rname=="GLU") {
+    3817         714 :       atoi[residue_atom[i]]=GLU;
+    3818       14380 :     } else if(Rname=="GLY") {
+    3819         972 :       atoi[residue_atom[i]]=GLY;
+    3820       13408 :     } else if(Rname=="HIS") {
+    3821           0 :       atoi[residue_atom[i]]=HIS;
+    3822       13408 :     } else if(Rname=="HID") {
+    3823           0 :       atoi[residue_atom[i]]=HIS;
+    3824       13408 :     } else if(Rname=="HIE") {
+    3825         216 :       atoi[residue_atom[i]]=HIS;
+    3826       13192 :     } else if(Rname=="HIP") {
+    3827           0 :       atoi[residue_atom[i]]=HIP;
+    3828             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    3829       13192 :     } else if(Rname=="HSD") {
+    3830           0 :       atoi[residue_atom[i]]=HIS;
+    3831       13192 :     } else if(Rname=="HSE") {
+    3832           0 :       atoi[residue_atom[i]]=HIS;
+    3833       13192 :     } else if(Rname=="HSP") {
+    3834           0 :       atoi[residue_atom[i]]=HIP;
+    3835       13192 :     } else if(Rname=="ILE") {
+    3836        1296 :       atoi[residue_atom[i]]=ILE;
+    3837       11896 :     } else if(Rname=="LEU") {
+    3838        2280 :       atoi[residue_atom[i]]=LEU;
+    3839        9616 :     } else if(Rname=="LYS") {
+    3840        1560 :       atoi[residue_atom[i]]=LYS;
+    3841        8056 :     } else if(Rname=="MET") {
+    3842         912 :       atoi[residue_atom[i]]=MET;
+    3843        7144 :     } else if(Rname=="PHE") {
+    3844        1512 :       atoi[residue_atom[i]]=PHE;
+    3845        5632 :     } else if(Rname=="PRO") {
+    3846        1122 :       atoi[residue_atom[i]]=PRO;
+    3847        4510 :     } else if(Rname=="SER") {
+    3848         792 :       atoi[residue_atom[i]]=SER;
+    3849        3718 :     } else if(Rname=="THR") {
+    3850         756 :       atoi[residue_atom[i]]=THR;
+    3851        2962 :     } else if(Rname=="TRP") {
+    3852           0 :       atoi[residue_atom[i]]=TRP;
+    3853        2962 :     } else if(Rname=="TYR") {
+    3854         792 :       atoi[residue_atom[i]]=TYR;
+    3855        2170 :     } else if(Rname=="VAL") {
+    3856        1632 :       atoi[residue_atom[i]]=VAL;
+    3857             :     }
+    3858             :     // NUCLEIC ACIDS
+    3859             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    3860             :     // RNA - G
+    3861         538 :     else if(Rname=="G") {
+    3862           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3863           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3864           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3865           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3866           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3867           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3868           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    3869           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    3870           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    3871           0 :         atoi[residue_atom[i]]=BB_RNA;
+    3872           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3873           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3874           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3875           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3876           0 :         atoi[residue_atom[i]]=BASE_G;
+    3877           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3878             :       // RNA - G3
+    3879         538 :     } else if(Rname=="G3") {
+    3880           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3881           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3882           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3883           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    3884           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    3885           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    3886           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    3887           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    3888           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    3889           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    3890           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3891           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3892           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3893           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3894           0 :         atoi[residue_atom[i]]=BASE_G;
+    3895           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3896             :       // RNA - G5
+    3897         538 :     } else if(Rname=="G5") {
+    3898           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3899           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3900           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3901           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    3902           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    3903           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    3904           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    3905           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    3906           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    3907           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    3908           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    3909           0 :         atoi[residue_atom[i]]=BASE_G;
+    3910           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3911             :       // RNA - U
+    3912         538 :     } else if(Rname=="U") {
+    3913        1554 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3914        1176 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3915          42 :         atoi [residue_atom[i]]=BB_PO2;
+    3916        1372 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3917        1148 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3918         924 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3919         714 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    3920         644 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    3921         840 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    3922         224 :         atoi[residue_atom[i]]=BB_RNA;
+    3923         476 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    3924         252 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    3925         196 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    3926         154 :         atoi[residue_atom[i]]=BASE_U;
+    3927           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3928             :       // RNA - U3
+    3929         118 :     } else if(Rname=="U3") {
+    3930         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3931         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3932           6 :         atoi [residue_atom[i]]=BB_PO2;
+    3933         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    3934         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    3935         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    3936         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    3937          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    3938          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    3939          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    3940          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    3941          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    3942          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    3943          22 :         atoi[residue_atom[i]]=BASE_U;
+    3944           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3945             :       // RNA - U5
+    3946          56 :     } else if(Rname=="U5") {
+    3947         204 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3948         172 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3949         140 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3950         108 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    3951          88 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    3952          78 :           Aname=="H2'1" || Aname=="H5T" ) {
+    3953          34 :         atoi[residue_atom[i]]=BB_RNA_5;
+    3954          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    3955          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    3956          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    3957          22 :         atoi[residue_atom[i]]=BASE_U;
+    3958           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3959             :       // RNA - A
+    3960           0 :     } else if(Rname=="A") {
+    3961           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3962           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3963           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3964           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3965           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3966           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    3967           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    3968           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    3969           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    3970           0 :         atoi[residue_atom[i]]=BB_RNA;
+    3971           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    3972           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    3973           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    3974           0 :                 Aname=="H61" || Aname=="H62" ) {
+    3975           0 :         atoi[residue_atom[i]]=BASE_A;
+    3976           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3977             :       // RNA - A3
+    3978           0 :     } else if(Rname=="A3") {
+    3979           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    3980           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    3981           0 :         atoi [residue_atom[i]]=BB_PO2;
+    3982           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    3983           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    3984           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    3985           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    3986           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    3987           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    3988           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    3989           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    3990           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    3991           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    3992           0 :                 Aname=="H61" || Aname=="H62" ) {
+    3993           0 :         atoi[residue_atom[i]]=BASE_A;
+    3994           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    3995             :       // RNA - A5
+    3996           0 :     } else if(Rname=="A5") {
+    3997           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    3998           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    3999           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4000           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    4001           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    4002           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    4003           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    4004           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4005           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4006           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4007           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4008           0 :         atoi[residue_atom[i]]=BASE_A;
+    4009           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4010             :       // RNA - C
+    4011           0 :     } else if(Rname=="C") {
+    4012           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4013           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4014           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4015           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4016           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4017           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4018           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    4019           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    4020           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    4021           0 :         atoi[residue_atom[i]]=BB_RNA;
+    4022           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4023           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4024           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4025           0 :         atoi[residue_atom[i]]=BASE_C;
+    4026           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4027             :       // RNA - C3
+    4028           0 :     } else if(Rname=="C3") {
+    4029           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4030           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4031           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4032           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    4033           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    4034           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    4035           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    4036           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    4037           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    4038           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    4039           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4040           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4041           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4042           0 :         atoi[residue_atom[i]]=BASE_C;
+    4043           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4044             :       // RNA - C5
+    4045           0 :     } else if(Rname=="C5") {
+    4046           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4047           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    4048           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    4049           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    4050           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    4051           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    4052           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    4053           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4054           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4055           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4056           0 :         atoi[residue_atom[i]]=BASE_C;
+    4057           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4058             :       // DNA - G
+    4059           0 :     } else if(Rname=="DG") {
+    4060           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4061           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4062           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4063           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4064           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4065           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4066           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4067           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4068           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4069           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4070           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4071           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4072           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4073           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4074           0 :         atoi[residue_atom[i]]=BASE_G;
+    4075           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4076             :       // DNA - G3
+    4077           0 :     } else if(Rname=="DG3") {
+    4078           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4079           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4080           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4081           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4082           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4083           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4084           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    4085           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4086             :                 Aname=="H3T" ) {
+    4087           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    4088           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4089           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4090           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4091           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4092           0 :         atoi[residue_atom[i]]=BASE_G;
+    4093           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4094             :       // DNA - G5
+    4095           0 :     } else if(Rname=="DG5") {
+    4096           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4097           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4098           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4099           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4100           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4101             :           Aname=="H5T" ) {
+    4102           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4103           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    4104           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    4105           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    4106           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    4107           0 :         atoi[residue_atom[i]]=BASE_G;
+    4108           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4109             :       // DNA - T
+    4110           0 :     } else if(Rname=="DT") {
+    4111           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4112           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4113           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4114           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4115           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4116           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4117           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4118           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4119           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4120           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4121           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    4122           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    4123           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    4124           0 :                 Aname=="H72" || Aname=="H73" ) {
+    4125           0 :         atoi[residue_atom[i]]=BASE_T;
+    4126           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4127             :       // DNA - T3
+    4128           0 :     } else if(Rname=="DT3") {
+    4129           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4130           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4131           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4132           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4133           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4134           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4135           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    4136           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4137             :                 Aname=="H3T" ) {
+    4138           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    4139           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    4140           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    4141           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    4142           0 :                 Aname=="H72" || Aname=="H73" ) {
+    4143           0 :         atoi[residue_atom[i]]=BASE_T;
+    4144           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4145             :       // DNA - T5
+    4146           0 :     } else if(Rname=="DT5") {
+    4147           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4148           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4149           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4150           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4151           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4152             :           Aname=="H5T" ) {
+    4153           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4154           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    4155           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    4156           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    4157           0 :                 Aname=="H72" || Aname=="H73" ) {
+    4158           0 :         atoi[residue_atom[i]]=BASE_T;
+    4159           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4160             :       // DNA - A
+    4161           0 :     } else if(Rname=="DA") {
+    4162           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4163           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4164           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4165           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4166           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4167           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4168           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4169           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4170           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4171           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4172           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4173           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4174           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4175           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4176           0 :         atoi[residue_atom[i]]=BASE_A;
+    4177           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4178             :       // DNA - A3
+    4179           0 :     } else if(Rname=="DA3") {
+    4180           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4181           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4182           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4183           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4184           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4185           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4186           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    4187           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4188             :                 Aname=="H3T" ) {
+    4189           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    4190           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4191           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4192           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4193           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4194           0 :         atoi[residue_atom[i]]=BASE_A;
+    4195           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4196             :       // DNA - A5
+    4197           0 :     } else if(Rname=="DA5") {
+    4198           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4199           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4200           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4201           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4202           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4203             :           Aname=="H5T" ) {
+    4204           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4205           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    4206           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    4207           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    4208           0 :                 Aname=="H61" || Aname=="H62" ) {
+    4209           0 :         atoi[residue_atom[i]]=BASE_A;
+    4210           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4211             :       // DNA - C
+    4212           0 :     } else if(Rname=="DC") {
+    4213           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4214           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4215           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4216           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4217           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4218           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4219           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4220           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    4221           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    4222           0 :         atoi[residue_atom[i]]=BB_DNA;
+    4223           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4224           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4225           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4226           0 :         atoi[residue_atom[i]]=BASE_C;
+    4227           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4228             :       // DNA - C3
+    4229           0 :     } else if(Rname=="DC3") {
+    4230           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    4231           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    4232           0 :         atoi [residue_atom[i]]=BB_PO2;
+    4233           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4234           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    4235           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4236           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    4237           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4238             :                 Aname=="H3T" ) {
+    4239           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    4240           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4241           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4242           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4243           0 :         atoi[residue_atom[i]]=BASE_C;
+    4244           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4245             :       // DNA - C5
+    4246           0 :     } else if(Rname=="DC5") {
+    4247           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    4248           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    4249           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    4250           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    4251           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    4252             :           Aname=="H5T" ) {
+    4253           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    4254           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    4255           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    4256           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    4257           0 :         atoi[residue_atom[i]]=BASE_C;
+    4258           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    4259           0 :     } else error("Residue not known: "+Rname);
+    4260             :   }
+    4261           6 : }
+    4262             : 
+    4263           4 : void SAXS::getOnebeadparam_sansH(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_H, std::vector<std::vector<long double> > &parameter_mix_H, std::vector<std::vector<long double> > &parameter_solv_H)
+    4264             : {
+    4265           4 :   parameter_solv_H[TRP].push_back(60737.60249988011);
+    4266           4 :   parameter_solv_H[TRP].push_back(-77.77344118516487);
+    4267           4 :   parameter_solv_H[TRP].push_back(-205962.80436572764);
+    4268           4 :   parameter_solv_H[TRP].push_back(-62014.18523271781);
+    4269           4 :   parameter_solv_H[TRP].push_back(680712.0512548896);
+    4270           4 :   parameter_solv_H[TRP].push_back(-681337.967312983);
+    4271           4 :   parameter_solv_H[TRP].push_back(211474.00338118695);
+    4272             : 
+    4273           4 :   parameter_solv_H[TYR].push_back(46250.803599880084);
+    4274           4 :   parameter_solv_H[TYR].push_back(-45.827646837514614);
+    4275           4 :   parameter_solv_H[TYR].push_back(-143872.94597686914);
+    4276           4 :   parameter_solv_H[TYR].push_back(-39049.51580628132);
+    4277           4 :   parameter_solv_H[TYR].push_back(441321.31246635393);
+    4278           4 :   parameter_solv_H[TYR].push_back(-434477.6826175059);
+    4279           4 :   parameter_solv_H[TYR].push_back(133179.21673104732);
+    4280             : 
+    4281           4 :   parameter_solv_H[PHE].push_back(42407.164900118914);
+    4282           4 :   parameter_solv_H[PHE].push_back(-159.20054549009086);
+    4283           4 :   parameter_solv_H[PHE].push_back(-123847.83591352346);
+    4284           4 :   parameter_solv_H[PHE].push_back(-41797.78884558073);
+    4285           4 :   parameter_solv_H[PHE].push_back(380283.87543872406);
+    4286           4 :   parameter_solv_H[PHE].push_back(-361432.81356389285);
+    4287           4 :   parameter_solv_H[PHE].push_back(107750.69385054041);
+    4288             : 
+    4289           4 :   parameter_solv_H[HIP].push_back(24473.473600119047);
+    4290           4 :   parameter_solv_H[HIP].push_back(-111.6412807124612);
+    4291           4 :   parameter_solv_H[HIP].push_back(-65826.17293437096);
+    4292           4 :   parameter_solv_H[HIP].push_back(-23305.902022201855);
+    4293           4 :   parameter_solv_H[HIP].push_back(194795.09953510275);
+    4294           4 :   parameter_solv_H[HIP].push_back(-180454.47859494278);
+    4295           4 :   parameter_solv_H[HIP].push_back(52699.36922660704);
+    4296             : 
+    4297           4 :   parameter_solv_H[ARG].push_back(34106.70239988039);
+    4298           4 :   parameter_solv_H[ARG].push_back(152.74468231268114);
+    4299           4 :   parameter_solv_H[ARG].push_back(-117086.46040369231);
+    4300           4 :   parameter_solv_H[ARG].push_back(-19664.37512726012);
+    4301           4 :   parameter_solv_H[ARG].push_back(364454.3721646173);
+    4302           4 :   parameter_solv_H[ARG].push_back(-382076.05102190404);
+    4303           4 :   parameter_solv_H[ARG].push_back(122775.83306003918);
+    4304             : 
+    4305           4 :   parameter_solv_H[LYS].push_back(32292.09000011877);
+    4306           4 :   parameter_solv_H[LYS].push_back(-111.97888350941923);
+    4307           4 :   parameter_solv_H[LYS].push_back(-91953.05212591762);
+    4308           4 :   parameter_solv_H[LYS].push_back(-30691.03615444628);
+    4309           4 :   parameter_solv_H[LYS].push_back(282092.82233263896);
+    4310           4 :   parameter_solv_H[LYS].push_back(-269503.6095978623);
+    4311           4 :   parameter_solv_H[LYS].push_back(80777.92760273012);
+    4312             : 
+    4313           4 :   parameter_solv_H[CYS].push_back(11352.902500119093);
+    4314           4 :   parameter_solv_H[CYS].push_back(-45.52255488723637);
+    4315           4 :   parameter_solv_H[CYS].push_back(-20925.086525675117);
+    4316           4 :   parameter_solv_H[CYS].push_back(-5662.681335644281);
+    4317           4 :   parameter_solv_H[CYS].push_back(38559.09602816144);
+    4318           4 :   parameter_solv_H[CYS].push_back(-27885.22747486708);
+    4319           4 :   parameter_solv_H[CYS].push_back(6280.148346561226);
+    4320             : 
+    4321           4 :   parameter_solv_H[ASP].push_back(13511.73760011933);
+    4322           4 :   parameter_solv_H[ASP].push_back(-59.92934247210642);
+    4323           4 :   parameter_solv_H[ASP].push_back(-25849.867077822244);
+    4324           4 :   parameter_solv_H[ASP].push_back(-7541.679510407563);
+    4325           4 :   parameter_solv_H[ASP].push_back(50760.93853987092);
+    4326           4 :   parameter_solv_H[ASP].push_back(-37677.89102528413);
+    4327           4 :   parameter_solv_H[ASP].push_back(8745.710458140105);
+    4328             : 
+    4329           4 :   parameter_solv_H[GLU].push_back(20443.280400119456);
+    4330           4 :   parameter_solv_H[GLU].push_back(-113.77513581661388);
+    4331           4 :   parameter_solv_H[GLU].push_back(-45587.79863958479);
+    4332           4 :   parameter_solv_H[GLU].push_back(-16187.534798976243);
+    4333           4 :   parameter_solv_H[GLU].push_back(112609.61802147207);
+    4334           4 :   parameter_solv_H[GLU].push_back(-93362.01894077536);
+    4335           4 :   parameter_solv_H[GLU].push_back(24519.546829431332);
+    4336             : 
+    4337           4 :   parameter_solv_H[ILE].push_back(27858.948100119596);
+    4338           4 :   parameter_solv_H[ILE].push_back(-159.27394962770595);
+    4339           4 :   parameter_solv_H[ILE].push_back(-61571.43025249802);
+    4340           4 :   parameter_solv_H[ILE].push_back(-21324.89659912433);
+    4341           4 :   parameter_solv_H[ILE].push_back(144070.7880009225);
+    4342           4 :   parameter_solv_H[ILE].push_back(-115021.84534734003);
+    4343           4 :   parameter_solv_H[ILE].push_back(28939.093300284097);
+    4344             : 
+    4345           4 :   parameter_solv_H[LEU].push_back(27858.948100119596);
+    4346           4 :   parameter_solv_H[LEU].push_back(-165.61872365361);
+    4347           4 :   parameter_solv_H[LEU].push_back(-62564.5706162518);
+    4348           4 :   parameter_solv_H[LEU].push_back(-22465.325666767214);
+    4349           4 :   parameter_solv_H[LEU].push_back(151616.7844050042);
+    4350           4 :   parameter_solv_H[LEU].push_back(-122905.60389771541);
+    4351           4 :   parameter_solv_H[LEU].push_back(31436.66201442061);
+    4352             : 
+    4353           4 :   parameter_solv_H[MET].push_back(25609.60090011981);
+    4354           4 :   parameter_solv_H[MET].push_back(-135.38816369794569);
+    4355           4 :   parameter_solv_H[MET].push_back(-67771.01548433342);
+    4356           4 :   parameter_solv_H[MET].push_back(-25228.91756660071);
+    4357           4 :   parameter_solv_H[MET].push_back(199649.92084565928);
+    4358           4 :   parameter_solv_H[MET].push_back(-182251.9246506795);
+    4359           4 :   parameter_solv_H[MET].push_back(52502.876819125115);
+    4360             : 
+    4361           4 :   parameter_solv_H[ASN].push_back(14376.010000119095);
+    4362           4 :   parameter_solv_H[ASN].push_back(-67.65587848183215);
+    4363           4 :   parameter_solv_H[ASN].push_back(-28302.877059425664);
+    4364           4 :   parameter_solv_H[ASN].push_back(-8577.444107282141);
+    4365           4 :   parameter_solv_H[ASN].push_back(57532.88704197217);
+    4366           4 :   parameter_solv_H[ASN].push_back(-43261.79974462857);
+    4367           4 :   parameter_solv_H[ASN].push_back(10186.450874679671);
+    4368             : 
+    4369           4 :   parameter_solv_H[PRO].push_back(16866.21690011944);
+    4370           4 :   parameter_solv_H[PRO].push_back(-70.84312112734995);
+    4371           4 :   parameter_solv_H[PRO].push_back(-31465.8423531932);
+    4372           4 :   parameter_solv_H[PRO].push_back(-8653.362744540535);
+    4373           4 :   parameter_solv_H[PRO].push_back(58032.27079924916);
+    4374           4 :   parameter_solv_H[PRO].push_back(-41521.001733021694);
+    4375           4 :   parameter_solv_H[PRO].push_back(9184.527523759205);
+    4376             : 
+    4377           4 :   parameter_solv_H[GLN].push_back(21503.289600119);
+    4378           4 :   parameter_solv_H[GLN].push_back(-121.3012777474678);
+    4379           4 :   parameter_solv_H[GLN].push_back(-50468.58503443957);
+    4380           4 :   parameter_solv_H[GLN].push_back(-18462.47495329696);
+    4381           4 :   parameter_solv_H[GLN].push_back(132718.42007501892);
+    4382           4 :   parameter_solv_H[GLN].push_back(-113787.20224345029);
+    4383           4 :   parameter_solv_H[GLN].push_back(30920.340813688686);
+    4384             : 
+    4385           4 :   parameter_solv_H[SER].push_back(9181.47240011935);
+    4386           4 :   parameter_solv_H[SER].push_back(-28.775273124392083);
+    4387           4 :   parameter_solv_H[SER].push_back(-15205.54229808512);
+    4388           4 :   parameter_solv_H[SER].push_back(-3377.785599913673);
+    4389           4 :   parameter_solv_H[SER].push_back(23345.562090489493);
+    4390           4 :   parameter_solv_H[SER].push_back(-15312.699787471944);
+    4391           4 :   parameter_solv_H[SER].push_back(3013.844610647712);
+    4392             : 
+    4393           4 :   parameter_solv_H[THR].push_back(15020.953600119403);
+    4394           4 :   parameter_solv_H[THR].push_back(-61.909951810375105);
+    4395           4 :   parameter_solv_H[THR].push_back(-27814.538986050964);
+    4396           4 :   parameter_solv_H[THR].push_back(-7532.222992514079);
+    4397           4 :   parameter_solv_H[THR].push_back(50586.29804970814);
+    4398           4 :   parameter_solv_H[THR].push_back(-35943.85986777198);
+    4399           4 :   parameter_solv_H[THR].push_back(7880.091610023207);
+    4400             : 
+    4401           4 :   parameter_solv_H[VAL].push_back(19647.628900119355);
+    4402           4 :   parameter_solv_H[VAL].push_back(-89.04968136833762);
+    4403           4 :   parameter_solv_H[VAL].push_back(-38050.10118919102);
+    4404           4 :   parameter_solv_H[VAL].push_back(-10921.421066774372);
+    4405           4 :   parameter_solv_H[VAL].push_back(72774.31277743122);
+    4406           4 :   parameter_solv_H[VAL].push_back(-52689.05168504517);
+    4407           4 :   parameter_solv_H[VAL].push_back(11806.48989635518);
+    4408             : 
+    4409           4 :   parameter_solv_H[ALA].push_back(7515.156100119273);
+    4410           4 :   parameter_solv_H[ALA].push_back(-20.226317591188526);
+    4411           4 :   parameter_solv_H[ALA].push_back(-11761.841775007797);
+    4412           4 :   parameter_solv_H[ALA].push_back(-2341.4903622033885);
+    4413           4 :   parameter_solv_H[ALA].push_back(16545.381259883452);
+    4414           4 :   parameter_solv_H[ALA].push_back(-10397.171546969075);
+    4415           4 :   parameter_solv_H[ALA].push_back(1921.5253045340198);
+    4416             : 
+    4417           4 :   parameter_solv_H[GLY].push_back(3594.002500119159);
+    4418           4 :   parameter_solv_H[GLY].push_back(-6.910832388009796);
+    4419           4 :   parameter_solv_H[GLY].push_back(-4937.3542895091905);
+    4420           4 :   parameter_solv_H[GLY].push_back(-785.4545979203357);
+    4421           4 :   parameter_solv_H[GLY].push_back(5852.853693316741);
+    4422           4 :   parameter_solv_H[GLY].push_back(-3391.2920205126734);
+    4423           4 :   parameter_solv_H[GLY].push_back(552.3278183161507);
+    4424             : 
+    4425           4 :   parameter_solv_H[HIS].push_back(22888.664100119073);
+    4426           4 :   parameter_solv_H[HIS].push_back(-133.86281863999585);
+    4427           4 :   parameter_solv_H[HIS].push_back(-57533.51412287858);
+    4428           4 :   parameter_solv_H[HIS].push_back(-21767.300111408193);
+    4429           4 :   parameter_solv_H[HIS].push_back(161255.15347073504);
+    4430           4 :   parameter_solv_H[HIS].push_back(-142176.65100718598);
+    4431           4 :   parameter_solv_H[HIS].push_back(39642.61507384587);
+    4432             : 
+    4433           4 :   parameter_mix_H[TRP].push_back(2974.6515001192306);
+    4434           4 :   parameter_mix_H[TRP].push_back(-18.361939022074825);
+    4435           4 :   parameter_mix_H[TRP].push_back(-7284.637435770752);
+    4436           4 :   parameter_mix_H[TRP].push_back(-2945.7969900381895);
+    4437           4 :   parameter_mix_H[TRP].push_back(21235.01878657283);
+    4438           4 :   parameter_mix_H[TRP].push_back(-18909.7406035548);
+    4439           4 :   parameter_mix_H[TRP].push_back(5324.324204245179);
+    4440             : 
+    4441           4 :   parameter_mix_H[TYR].push_back(2029.7362801192114);
+    4442           4 :   parameter_mix_H[TYR].push_back(-6.983186065527884);
+    4443           4 :   parameter_mix_H[TYR].push_back(-5041.996113037476);
+    4444           4 :   parameter_mix_H[TYR].push_back(-1744.5213085724158);
+    4445           4 :   parameter_mix_H[TYR].push_back(15329.420227814338);
+    4446           4 :   parameter_mix_H[TYR].push_back(-14648.322529889958);
+    4447           4 :   parameter_mix_H[TYR].push_back(4405.608657083287);
+    4448             : 
+    4449           4 :   parameter_mix_H[PHE].push_back(1704.6885401192117);
+    4450           4 :   parameter_mix_H[PHE].push_back(-10.077274979133408);
+    4451           4 :   parameter_mix_H[PHE].push_back(-3769.440088334303);
+    4452           4 :   parameter_mix_H[PHE].push_back(-1574.6255694551546);
+    4453           4 :   parameter_mix_H[PHE].push_back(10996.32497868798);
+    4454           4 :   parameter_mix_H[PHE].push_back(-9840.68281283696);
+    4455           4 :   parameter_mix_H[PHE].push_back(2792.098605716682);
+    4456             : 
+    4457           4 :   parameter_mix_H[HIP].push_back(1376.0462401192394);
+    4458           4 :   parameter_mix_H[HIP].push_back(-8.576320475413144);
+    4459           4 :   parameter_mix_H[HIP].push_back(-2796.8327726392167);
+    4460           4 :   parameter_mix_H[HIP].push_back(-1165.0473128576);
+    4461           4 :   parameter_mix_H[HIP].push_back(7495.063650365717);
+    4462           4 :   parameter_mix_H[HIP].push_back(-6331.20422098132);
+    4463           4 :   parameter_mix_H[HIP].push_back(1692.637366093312);
+    4464             : 
+    4465           4 :   parameter_mix_H[ARG].push_back(1280.940480119178);
+    4466           4 :   parameter_mix_H[ARG].push_back(-7.411214928783748);
+    4467           4 :   parameter_mix_H[ARG].push_back(-3747.6200569785033);
+    4468           4 :   parameter_mix_H[ARG].push_back(-1766.5282176004569);
+    4469           4 :   parameter_mix_H[ARG].push_back(14307.817638456267);
+    4470           4 :   parameter_mix_H[ARG].push_back(-14297.104122885643);
+    4471           4 :   parameter_mix_H[ARG].push_back(4450.526244207772);
+    4472             : 
+    4473           4 :   parameter_mix_H[LYS].push_back(570.7272001192143);
+    4474           4 :   parameter_mix_H[LYS].push_back(-5.371742288956095);
+    4475           4 :   parameter_mix_H[LYS].push_back(-1255.9868267793006);
+    4476           4 :   parameter_mix_H[LYS].push_back(-748.3071074443138);
+    4477           4 :   parameter_mix_H[LYS].push_back(4534.824932304509);
+    4478           4 :   parameter_mix_H[LYS].push_back(-4125.307867230812);
+    4479           4 :   parameter_mix_H[LYS].push_back(1178.781491068295);
+    4480             : 
+    4481           4 :   parameter_mix_H[CYS].push_back(410.21750011921864);
+    4482           4 :   parameter_mix_H[CYS].push_back(-0.7655651758449595);
+    4483           4 :   parameter_mix_H[CYS].push_back(-523.8897033718782);
+    4484           4 :   parameter_mix_H[CYS].push_back(-89.88478273744425);
+    4485           4 :   parameter_mix_H[CYS].push_back(655.3313542467919);
+    4486           4 :   parameter_mix_H[CYS].push_back(-407.87897719750896);
+    4487           4 :   parameter_mix_H[CYS].push_back(76.50541508448237);
+    4488             : 
+    4489           4 :   parameter_mix_H[ASP].push_back(893.6531201192147);
+    4490           4 :   parameter_mix_H[ASP].push_back(-3.0756255172248874);
+    4491           4 :   parameter_mix_H[ASP].push_back(-1453.1760425275006);
+    4492           4 :   parameter_mix_H[ASP].push_back(-365.0424824614137);
+    4493           4 :   parameter_mix_H[ASP].push_back(2443.570600976796);
+    4494           4 :   parameter_mix_H[ASP].push_back(-1679.8996339740277);
+    4495           4 :   parameter_mix_H[ASP].push_back(352.33054461512455);
+    4496             : 
+    4497           4 :   parameter_mix_H[GLU].push_back(1075.4955601191884);
+    4498           4 :   parameter_mix_H[GLU].push_back(-6.917429973203965);
+    4499           4 :   parameter_mix_H[GLU].push_back(-2262.861870389347);
+    4500           4 :   parameter_mix_H[GLU].push_back(-909.8078514527992);
+    4501           4 :   parameter_mix_H[GLU].push_back(5841.923857549836);
+    4502           4 :   parameter_mix_H[GLU].push_back(-4784.620969556751);
+    4503           4 :   parameter_mix_H[GLU].push_back(1230.873134652953);
+    4504             : 
+    4505           4 :   parameter_mix_H[ILE].push_back(466.0127201192081);
+    4506           4 :   parameter_mix_H[ILE].push_back(-0.9323443258150218);
+    4507           4 :   parameter_mix_H[ILE].push_back(-576.7178005955719);
+    4508           4 :   parameter_mix_H[ILE].push_back(-103.03003361062478);
+    4509           4 :   parameter_mix_H[ILE].push_back(706.4269951176641);
+    4510           4 :   parameter_mix_H[ILE].push_back(-420.4412859632717);
+    4511           4 :   parameter_mix_H[ILE].push_back(71.53175726608731);
+    4512             : 
+    4513           4 :   parameter_mix_H[LEU].push_back(466.0127201192081);
+    4514           4 :   parameter_mix_H[LEU].push_back(-1.9793605752606065);
+    4515           4 :   parameter_mix_H[LEU].push_back(-718.3988478701591);
+    4516           4 :   parameter_mix_H[LEU].push_back(-227.36409339012113);
+    4517           4 :   parameter_mix_H[LEU].push_back(1389.2058254917304);
+    4518           4 :   parameter_mix_H[LEU].push_back(-990.0033118748643);
+    4519           4 :   parameter_mix_H[LEU].push_back(213.15736815883042);
+    4520             : 
+    4521           4 :   parameter_mix_H[MET].push_back(562.9855401192196);
+    4522           4 :   parameter_mix_H[MET].push_back(-3.7994094933771643);
+    4523           4 :   parameter_mix_H[MET].push_back(-1139.6331862451661);
+    4524           4 :   parameter_mix_H[MET].push_back(-516.6313269725724);
+    4525           4 :   parameter_mix_H[MET].push_back(3268.957245190869);
+    4526           4 :   parameter_mix_H[MET].push_back(-2809.178864807947);
+    4527           4 :   parameter_mix_H[MET].push_back(761.4832732100416);
+    4528             : 
+    4529           4 :   parameter_mix_H[ASN].push_back(828.7488001191887);
+    4530           4 :   parameter_mix_H[ASN].push_back(-2.1275493073799625);
+    4531           4 :   parameter_mix_H[ASN].push_back(-1222.248291388804);
+    4532           4 :   parameter_mix_H[ASN].push_back(-238.94210659613537);
+    4533           4 :   parameter_mix_H[ASN].push_back(1660.8322402171973);
+    4534           4 :   parameter_mix_H[ASN].push_back(-1008.7934996077323);
+    4535           4 :   parameter_mix_H[ASN].push_back(173.6082238625797);
+    4536             : 
+    4537           4 :   parameter_mix_H[PRO].push_back(578.4409801192146);
+    4538           4 :   parameter_mix_H[PRO].push_back(-0.5379505780909722);
+    4539           4 :   parameter_mix_H[PRO].push_back(-648.146493857212);
+    4540           4 :   parameter_mix_H[PRO].push_back(-56.67223895342921);
+    4541           4 :   parameter_mix_H[PRO].push_back(509.88860586987437);
+    4542           4 :   parameter_mix_H[PRO].push_back(-214.57871784725265);
+    4543           4 :   parameter_mix_H[PRO].push_back(11.99659463759968);
+    4544             : 
+    4545           4 :   parameter_mix_H[GLN].push_back(989.2334401191976);
+    4546           4 :   parameter_mix_H[GLN].push_back(-6.307760694331967);
+    4547           4 :   parameter_mix_H[GLN].push_back(-1971.7067150503622);
+    4548           4 :   parameter_mix_H[GLN].push_back(-791.333088386235);
+    4549           4 :   parameter_mix_H[GLN].push_back(4900.009768434847);
+    4550           4 :   parameter_mix_H[GLN].push_back(-3909.7740976374153);
+    4551           4 :   parameter_mix_H[GLN].push_back(975.4952613244343);
+    4552             : 
+    4553           4 :   parameter_mix_H[SER].push_back(426.39900011920196);
+    4554           4 :   parameter_mix_H[SER].push_back(-0.42304498358319664);
+    4555           4 :   parameter_mix_H[SER].push_back(-484.2066027682147);
+    4556           4 :   parameter_mix_H[SER].push_back(-45.38968988754228);
+    4557           4 :   parameter_mix_H[SER].push_back(401.3420977115044);
+    4558           4 :   parameter_mix_H[SER].push_back(-178.0861461692512);
+    4559           4 :   parameter_mix_H[SER].push_back(13.540349238730284);
+    4560             : 
+    4561           4 :   parameter_mix_H[THR].push_back(525.0470401191992);
+    4562           4 :   parameter_mix_H[THR].push_back(-0.7419102811534484);
+    4563           4 :   parameter_mix_H[THR].push_back(-652.7134808154495);
+    4564           4 :   parameter_mix_H[THR].push_back(-80.39481224407903);
+    4565           4 :   parameter_mix_H[THR].push_back(641.5487902728123);
+    4566           4 :   parameter_mix_H[THR].push_back(-320.4227667104819);
+    4567           4 :   parameter_mix_H[THR].push_back(36.03558531183942);
+    4568             : 
+    4569           4 :   parameter_mix_H[VAL].push_back(414.6228601192123);
+    4570           4 :   parameter_mix_H[VAL].push_back(-0.35889335250521337);
+    4571           4 :   parameter_mix_H[VAL].push_back(-453.11631644097474);
+    4572           4 :   parameter_mix_H[VAL].push_back(-36.402101097644284);
+    4573           4 :   parameter_mix_H[VAL].push_back(336.24049431626804);
+    4574           4 :   parameter_mix_H[VAL].push_back(-127.42235327515239);
+    4575           4 :   parameter_mix_H[VAL].push_back(0.8013280923923705);
+    4576             : 
+    4577           4 :   parameter_mix_H[ALA].push_back(285.21010011920816);
+    4578           4 :   parameter_mix_H[ALA].push_back(-0.1573012439142169);
+    4579           4 :   parameter_mix_H[ALA].push_back(-282.8945838800694);
+    4580           4 :   parameter_mix_H[ALA].push_back(-16.32030056827785);
+    4581           4 :   parameter_mix_H[ALA].push_back(178.065895049598);
+    4582           4 :   parameter_mix_H[ALA].push_back(-60.27423229179658);
+    4583           4 :   parameter_mix_H[ALA].push_back(-1.4695219304131588);
+    4584             : 
+    4585           4 :   parameter_mix_H[GLY].push_back(207.18720011920414);
+    4586           4 :   parameter_mix_H[GLY].push_back(-0.1036587134183235);
+    4587           4 :   parameter_mix_H[GLY].push_back(-185.70794948240638);
+    4588           4 :   parameter_mix_H[GLY].push_back(-11.008101039836257);
+    4589           4 :   parameter_mix_H[GLY].push_back(115.30600405624061);
+    4590           4 :   parameter_mix_H[GLY].push_back(-42.46629718037158);
+    4591           4 :   parameter_mix_H[GLY].push_back(0.9238928987070913);
+    4592             : 
+    4593           4 :   parameter_mix_H[HIS].push_back(1443.9117601192354);
+    4594           4 :   parameter_mix_H[HIS].push_back(-7.478618745973115);
+    4595           4 :   parameter_mix_H[HIS].push_back(-2715.0835155803215);
+    4596           4 :   parameter_mix_H[HIS].push_back(-918.5243015382779);
+    4597           4 :   parameter_mix_H[HIS].push_back(5821.6258431396);
+    4598           4 :   parameter_mix_H[HIS].push_back(-4415.32722209556);
+    4599           4 :   parameter_mix_H[HIS].push_back(1044.7044029209756);
+    4600           4 :   parameter_vac_H[TRP].push_back(36.42122511920832);
+    4601           4 :   parameter_vac_H[TRP].push_back(-0.36925500341767903);
+    4602           4 :   parameter_vac_H[TRP].push_back(-51.34228792835503);
+    4603           4 :   parameter_vac_H[TRP].push_back(-34.10021080004831);
+    4604           4 :   parameter_vac_H[TRP].push_back(132.647034983933);
+    4605           4 :   parameter_vac_H[TRP].push_back(-82.89152328934257);
+    4606           4 :   parameter_vac_H[TRP].push_back(13.029994092013231);
+    4607             : 
+    4608           4 :   parameter_vac_H[TYR].push_back(22.268961119209557);
+    4609           4 :   parameter_vac_H[TYR].push_back(-0.1995573892347673);
+    4610           4 :   parameter_vac_H[TYR].push_back(-36.54202179838511);
+    4611           4 :   parameter_vac_H[TYR].push_back(-23.820801043096694);
+    4612           4 :   parameter_vac_H[TYR].push_back(127.46799692275353);
+    4613           4 :   parameter_vac_H[TYR].push_back(-107.63783234245744);
+    4614           4 :   parameter_vac_H[TYR].push_back(28.180858902960775);
+    4615             : 
+    4616           4 :   parameter_vac_H[PHE].push_back(17.131321119209627);
+    4617           4 :   parameter_vac_H[PHE].push_back(-0.15766725674246446);
+    4618           4 :   parameter_vac_H[PHE].push_back(-19.19964432024534);
+    4619           4 :   parameter_vac_H[PHE].push_back(-12.34326882843138);
+    4620           4 :   parameter_vac_H[PHE].push_back(38.17216645824474);
+    4621           4 :   parameter_vac_H[PHE].push_back(-11.245288857407298);
+    4622           4 :   parameter_vac_H[PHE].push_back(-3.8114731300899343);
+    4623             : 
+    4624           4 :   parameter_vac_H[HIP].push_back(19.34240411920875);
+    4625           4 :   parameter_vac_H[HIP].push_back(-0.13533410292592593);
+    4626           4 :   parameter_vac_H[HIP].push_back(-25.924121027387276);
+    4627           4 :   parameter_vac_H[HIP].push_back(-12.36586927492752);
+    4628           4 :   parameter_vac_H[HIP].push_back(56.75268702111191);
+    4629           4 :   parameter_vac_H[HIP].push_back(-31.126240293638094);
+    4630           4 :   parameter_vac_H[HIP].push_back(2.749811579250848);
+    4631             : 
+    4632           4 :   parameter_vac_H[ARG].push_back(12.027024119209557);
+    4633           4 :   parameter_vac_H[ARG].push_back(-0.41927538341868287);
+    4634           4 :   parameter_vac_H[ARG].push_back(-22.137566939867042);
+    4635           4 :   parameter_vac_H[ARG].push_back(-43.22615008762667);
+    4636           4 :   parameter_vac_H[ARG].push_back(165.77466655520323);
+    4637           4 :   parameter_vac_H[ARG].push_back(-140.68664871425898);
+    4638           4 :   parameter_vac_H[ARG].push_back(36.67401195170306);
+    4639             : 
+    4640           4 :   parameter_vac_H[LYS].push_back(2.5217441192093717);
+    4641           4 :   parameter_vac_H[LYS].push_back(-0.0032825476242835413);
+    4642           4 :   parameter_vac_H[LYS].push_back(14.019071697737793);
+    4643           4 :   parameter_vac_H[LYS].push_back(7.8634074595069245);
+    4644           4 :   parameter_vac_H[LYS].push_back(-82.44639716451474);
+    4645           4 :   parameter_vac_H[LYS].push_back(94.32937851921197);
+    4646           4 :   parameter_vac_H[LYS].push_back(-32.324473823417);
+    4647             : 
+    4648           4 :   parameter_vac_H[CYS].push_back(3.705624880856525);
+    4649           4 :   parameter_vac_H[CYS].push_back(0.005214780840206113);
+    4650           4 :   parameter_vac_H[CYS].push_back(1.25680902661715);
+    4651           4 :   parameter_vac_H[CYS].push_back(0.5779209425501814);
+    4652           4 :   parameter_vac_H[CYS].push_back(-3.716408071089366);
+    4653           4 :   parameter_vac_H[CYS].push_back(2.3947518943233117);
+    4654           4 :   parameter_vac_H[CYS].push_back(-0.40204949737133333);
+    4655             : 
+    4656           4 :   parameter_vac_H[ASP].push_back(14.776336119209605);
+    4657           4 :   parameter_vac_H[ASP].push_back(-0.037351220316916435);
+    4658           4 :   parameter_vac_H[ASP].push_back(-18.556358387626286);
+    4659           4 :   parameter_vac_H[ASP].push_back(-4.1737354794552886);
+    4660           4 :   parameter_vac_H[ASP].push_back(28.424721213037405);
+    4661           4 :   parameter_vac_H[ASP].push_back(-17.51389895324883);
+    4662           4 :   parameter_vac_H[ASP].push_back(2.9729111724708597);
+    4663             : 
+    4664           4 :   parameter_vac_H[GLU].push_back(14.145121119208973);
+    4665           4 :   parameter_vac_H[GLU].push_back(-0.11468766098213011);
+    4666           4 :   parameter_vac_H[GLU].push_back(-26.272637652294613);
+    4667           4 :   parameter_vac_H[GLU].push_back(-13.769758826440151);
+    4668           4 :   parameter_vac_H[GLU].push_back(80.4575683578491);
+    4669           4 :   parameter_vac_H[GLU].push_back(-64.19346347075);
+    4670           4 :   parameter_vac_H[GLU].push_back(15.545440117656236);
+    4671             : 
+    4672           4 :   parameter_vac_H[ILE].push_back(1.9488158808808775);
+    4673           4 :   parameter_vac_H[ILE].push_back(0.05873132133874459);
+    4674           4 :   parameter_vac_H[ILE].push_back(12.032778845884135);
+    4675           4 :   parameter_vac_H[ILE].push_back(7.148416980612881);
+    4676           4 :   parameter_vac_H[ILE].push_back(-41.87377843832961);
+    4677           4 :   parameter_vac_H[ILE].push_back(33.96120749582283);
+    4678           4 :   parameter_vac_H[ILE].push_back(-8.362535852631256);
+    4679             : 
+    4680           4 :   parameter_vac_H[LEU].push_back(1.9488158808977816);
+    4681           4 :   parameter_vac_H[LEU].push_back(0.0778305500414777);
+    4682           4 :   parameter_vac_H[LEU].push_back(12.333370614594);
+    4683           4 :   parameter_vac_H[LEU].push_back(9.449427967560764);
+    4684           4 :   parameter_vac_H[LEU].push_back(-52.65457680603262);
+    4685           4 :   parameter_vac_H[LEU].push_back(44.681877289399615);
+    4686           4 :   parameter_vac_H[LEU].push_back(-11.460498338671227);
+    4687             : 
+    4688           4 :   parameter_vac_H[MET].push_back(3.0940808808117652);
+    4689           4 :   parameter_vac_H[MET].push_back(0.04903755678213222);
+    4690           4 :   parameter_vac_H[MET].push_back(8.981927022922049);
+    4691           4 :   parameter_vac_H[MET].push_back(8.654862771879014);
+    4692           4 :   parameter_vac_H[MET].push_back(-57.09889409156816);
+    4693           4 :   parameter_vac_H[MET].push_back(58.87704775164829);
+    4694           4 :   parameter_vac_H[MET].push_back(-18.60431990258862);
+    4695             : 
+    4696           4 :   parameter_vac_H[ASN].push_back(11.943936119209074);
+    4697           4 :   parameter_vac_H[ASN].push_back(-0.0005000836239497835);
+    4698           4 :   parameter_vac_H[ASN].push_back(-9.581236453763157);
+    4699           4 :   parameter_vac_H[ASN].push_back(0.16244025786232308);
+    4700           4 :   parameter_vac_H[ASN].push_back(2.9276580099749574);
+    4701           4 :   parameter_vac_H[ASN].push_back(2.133535783835143);
+    4702           4 :   parameter_vac_H[ASN].push_back(-1.5709968820975018);
+    4703             : 
+    4704           4 :   parameter_vac_H[PRO].push_back(4.9595288808229245);
+    4705           4 :   parameter_vac_H[PRO].push_back(0.017853932680793515);
+    4706           4 :   parameter_vac_H[PRO].push_back(4.5421559293101605);
+    4707           4 :   parameter_vac_H[PRO].push_back(2.008455612787203);
+    4708           4 :   parameter_vac_H[PRO].push_back(-12.444117841318494);
+    4709           4 :   parameter_vac_H[PRO].push_back(8.511723688836447);
+    4710           4 :   parameter_vac_H[PRO].push_back(-1.6337543903496765);
+    4711             : 
+    4712           4 :   parameter_vac_H[GLN].push_back(11.377129119208574);
+    4713           4 :   parameter_vac_H[GLN].push_back(-0.0674805307761209);
+    4714           4 :   parameter_vac_H[GLN].push_back(-16.56692720411458);
+    4715           4 :   parameter_vac_H[GLN].push_back(-6.477707440126834);
+    4716           4 :   parameter_vac_H[GLN].push_back(34.78232259512621);
+    4717           4 :   parameter_vac_H[GLN].push_back(-19.450886909938312);
+    4718           4 :   parameter_vac_H[GLN].push_back(1.944286925108988);
+    4719             : 
+    4720           4 :   parameter_vac_H[SER].push_back(4.95062488096605);
+    4721           4 :   parameter_vac_H[SER].push_back(0.004676435440506079);
+    4722           4 :   parameter_vac_H[SER].push_back(-0.1896653085608564);
+    4723           4 :   parameter_vac_H[SER].push_back(0.5142284931977218);
+    4724           4 :   parameter_vac_H[SER].push_back(-2.8946087252759893);
+    4725           4 :   parameter_vac_H[SER].push_back(2.1031239401634836);
+    4726           4 :   parameter_vac_H[SER].push_back(-0.38226443516361713);
+    4727             : 
+    4728           4 :   parameter_vac_H[THR].push_back(4.588163880808971);
+    4729           4 :   parameter_vac_H[THR].push_back(0.018587905993982613);
+    4730           4 :   parameter_vac_H[THR].push_back(3.5289861308270214);
+    4731           4 :   parameter_vac_H[THR].push_back(2.0780583604591567);
+    4732           4 :   parameter_vac_H[THR].push_back(-12.3802007068414);
+    4733           4 :   parameter_vac_H[THR].push_back(8.720986674116094);
+    4734           4 :   parameter_vac_H[THR].push_back(-1.683256475122275);
+    4735             : 
+    4736           4 :   parameter_vac_H[VAL].push_back(2.187440880853519);
+    4737           4 :   parameter_vac_H[VAL].push_back(0.028351524826584255);
+    4738           4 :   parameter_vac_H[VAL].push_back(8.36584512491955);
+    4739           4 :   parameter_vac_H[VAL].push_back(3.1686206615123926);
+    4740           4 :   parameter_vac_H[VAL].push_back(-19.81959917770108);
+    4741           4 :   parameter_vac_H[VAL].push_back(13.293003038570571);
+    4742           4 :   parameter_vac_H[VAL].push_back(-2.4595257726774125);
+    4743             : 
+    4744           4 :   parameter_vac_H[ALA].push_back(2.7060248808167935);
+    4745           4 :   parameter_vac_H[ALA].push_back(0.004618897267213416);
+    4746           4 :   parameter_vac_H[ALA].push_back(2.4990261487383947);
+    4747           4 :   parameter_vac_H[ALA].push_back(0.49579332664340864);
+    4748           4 :   parameter_vac_H[ALA].push_back(-3.850400071630347);
+    4749           4 :   parameter_vac_H[ALA].push_back(1.9501161562030942);
+    4750           4 :   parameter_vac_H[ALA].push_back(-0.18332582719788362);
+    4751             : 
+    4752           4 :   parameter_vac_H[GLY].push_back(2.985983880876256);
+    4753           4 :   parameter_vac_H[GLY].push_back(0.0005033131808079042);
+    4754           4 :   parameter_vac_H[GLY].push_back(-0.42250170279962684);
+    4755           4 :   parameter_vac_H[GLY].push_back(0.05620517453257455);
+    4756           4 :   parameter_vac_H[GLY].push_back(-0.16801962822020733);
+    4757           4 :   parameter_vac_H[GLY].push_back(0.23635459648780555);
+    4758           4 :   parameter_vac_H[GLY].push_back(-0.06585244715658795);
+    4759             : 
+    4760           4 :   parameter_vac_H[HIS].push_back(22.77198411920933);
+    4761           4 :   parameter_vac_H[HIS].push_back(-0.06607491006655417);
+    4762           4 :   parameter_vac_H[HIS].push_back(-27.277710268717247);
+    4763           4 :   parameter_vac_H[HIS].push_back(-5.674444390934355);
+    4764           4 :   parameter_vac_H[HIS].push_back(33.4059567406171);
+    4765           4 :   parameter_vac_H[HIS].push_back(-11.60826210271092);
+    4766           4 :   parameter_vac_H[HIS].push_back(-1.7359607560773076);
+    4767             : 
+    4768             :   // NUCLEIC ACIDS
+    4769             : 
+    4770             :   // BB_PO2 H and D parameters are identical as there is no H or D in the bead.
+    4771           4 :   parameter_solv_H[BB_PO2].push_back(575.5201001192197);
+    4772           4 :   parameter_solv_H[BB_PO2].push_back(-0.6126595489733864);
+    4773           4 :   parameter_solv_H[BB_PO2].push_back(-623.3371092254899);
+    4774           4 :   parameter_solv_H[BB_PO2].push_back(-68.05795957022144);
+    4775           4 :   parameter_solv_H[BB_PO2].push_back(561.8052621243661);
+    4776           4 :   parameter_solv_H[BB_PO2].push_back(-283.39573309540276);
+    4777           4 :   parameter_solv_H[BB_PO2].push_back(35.550016980100295);
+    4778             : 
+    4779           4 :   parameter_solv_H[BB_DNA].push_back(21211.009600118316);
+    4780           4 :   parameter_solv_H[BB_DNA].push_back(-90.18805990529991);
+    4781           4 :   parameter_solv_H[BB_DNA].push_back(-39731.13373512149);
+    4782           4 :   parameter_solv_H[BB_DNA].push_back(-10920.373563712872);
+    4783           4 :   parameter_solv_H[BB_DNA].push_back(72882.21702424981);
+    4784           4 :   parameter_solv_H[BB_DNA].push_back(-51747.487078112776);
+    4785           4 :   parameter_solv_H[BB_DNA].push_back(11308.678429018755);
+    4786             : 
+    4787           4 :   parameter_solv_H[BB_DNA_5].push_back(22737.624100119025);
+    4788           4 :   parameter_solv_H[BB_DNA_5].push_back(-102.72714886664161);
+    4789           4 :   parameter_solv_H[BB_DNA_5].push_back(-43685.329677789734);
+    4790           4 :   parameter_solv_H[BB_DNA_5].push_back(-12564.25937409345);
+    4791           4 :   parameter_solv_H[BB_DNA_5].push_back(83454.87540484878);
+    4792           4 :   parameter_solv_H[BB_DNA_5].push_back(-60367.15652138887);
+    4793           4 :   parameter_solv_H[BB_DNA_5].push_back(13507.333729868991);
+    4794             : 
+    4795           4 :   parameter_solv_H[BB_DNA_3].push_back(22737.62410011902);
+    4796           4 :   parameter_solv_H[BB_DNA_3].push_back(-101.57816684452251);
+    4797           4 :   parameter_solv_H[BB_DNA_3].push_back(-43488.536705576145);
+    4798           4 :   parameter_solv_H[BB_DNA_3].push_back(-12345.056184958425);
+    4799           4 :   parameter_solv_H[BB_DNA_3].push_back(81963.52364114887);
+    4800           4 :   parameter_solv_H[BB_DNA_3].push_back(-58791.59443618196);
+    4801           4 :   parameter_solv_H[BB_DNA_3].push_back(13003.199362335583);
+    4802             : 
+    4803           4 :   parameter_solv_H[BB_RNA].push_back(23953.752900120977);
+    4804           4 :   parameter_solv_H[BB_RNA].push_back(-117.35779348824417);
+    4805           4 :   parameter_solv_H[BB_RNA].push_back(-47644.41735332843);
+    4806           4 :   parameter_solv_H[BB_RNA].push_back(-14641.556643789861);
+    4807           4 :   parameter_solv_H[BB_RNA].push_back(96893.48627050371);
+    4808           4 :   parameter_solv_H[BB_RNA].push_back(-72249.62534169303);
+    4809           4 :   parameter_solv_H[BB_RNA].push_back(16792.055521055358);
+    4810             : 
+    4811           4 :   parameter_solv_H[BB_RNA_5].push_back(25574.406400119024);
+    4812           4 :   parameter_solv_H[BB_RNA_5].push_back(-131.99642772933734);
+    4813           4 :   parameter_solv_H[BB_RNA_5].push_back(-52136.51404531251);
+    4814           4 :   parameter_solv_H[BB_RNA_5].push_back(-16682.14273917604);
+    4815           4 :   parameter_solv_H[BB_RNA_5].push_back(110278.01921639398);
+    4816           4 :   parameter_solv_H[BB_RNA_5].push_back(-83715.92027818544);
+    4817           4 :   parameter_solv_H[BB_RNA_5].push_back(19875.89133770605);
+    4818             : 
+    4819           4 :   parameter_solv_H[BB_RNA_3].push_back(25574.406400119027);
+    4820           4 :   parameter_solv_H[BB_RNA_3].push_back(-127.96875237036166);
+    4821           4 :   parameter_solv_H[BB_RNA_3].push_back(-51407.18391758439);
+    4822           4 :   parameter_solv_H[BB_RNA_3].push_back(-15922.900669975606);
+    4823           4 :   parameter_solv_H[BB_RNA_3].push_back(105078.5888910626);
+    4824           4 :   parameter_solv_H[BB_RNA_3].push_back(-78289.16276190645);
+    4825           4 :   parameter_solv_H[BB_RNA_3].push_back(18156.832143441192);
+    4826             : 
+    4827           4 :   parameter_solv_H[BASE_A].push_back(13282.562500119211);
+    4828           4 :   parameter_solv_H[BASE_A].push_back(-76.45124168404048);
+    4829           4 :   parameter_solv_H[BASE_A].push_back(-28376.06994108963);
+    4830           4 :   parameter_solv_H[BASE_A].push_back(-9972.910773722022);
+    4831           4 :   parameter_solv_H[BASE_A].push_back(65873.86341939073);
+    4832           4 :   parameter_solv_H[BASE_A].push_back(-52064.33492910885);
+    4833           4 :   parameter_solv_H[BASE_A].push_back(12931.608989412513);
+    4834             : 
+    4835           4 :   parameter_solv_H[BASE_C].push_back(10600.76160011891);
+    4836           4 :   parameter_solv_H[BASE_C].push_back(-49.1670871249108);
+    4837           4 :   parameter_solv_H[BASE_C].push_back(-20239.818742072875);
+    4838           4 :   parameter_solv_H[BASE_C].push_back(-6020.278780090207);
+    4839           4 :   parameter_solv_H[BASE_C].push_back(39632.13288981881);
+    4840           4 :   parameter_solv_H[BASE_C].push_back(-28954.779736165576);
+    4841           4 :   parameter_solv_H[BASE_C].push_back(6551.541109526305);
+    4842             : 
+    4843           4 :   parameter_solv_H[BASE_G].push_back(15470.384400119934);
+    4844           4 :   parameter_solv_H[BASE_G].push_back(-93.8013620200972);
+    4845           4 :   parameter_solv_H[BASE_G].push_back(-36188.29687013545);
+    4846           4 :   parameter_solv_H[BASE_G].push_back(-13717.685098209471);
+    4847           4 :   parameter_solv_H[BASE_G].push_back(95658.18473657136);
+    4848           4 :   parameter_solv_H[BASE_G].push_back(-81262.37811451119);
+    4849           4 :   parameter_solv_H[BASE_G].push_back(21841.903930943085);
+    4850             : 
+    4851           4 :   parameter_solv_H[BASE_T].push_back(17210.81610011936);
+    4852           4 :   parameter_solv_H[BASE_T].push_back(-93.10189802920208);
+    4853           4 :   parameter_solv_H[BASE_T].push_back(-36466.51927689957);
+    4854           4 :   parameter_solv_H[BASE_T].push_back(-12425.55615716932);
+    4855           4 :   parameter_solv_H[BASE_T].push_back(83847.427808925);
+    4856           4 :   parameter_solv_H[BASE_T].push_back(-66735.64997846584);
+    4857           4 :   parameter_solv_H[BASE_T].push_back(16757.3463987507);
+    4858             : 
+    4859           4 :   parameter_solv_H[BASE_U].push_back(10909.802500119395);
+    4860           4 :   parameter_solv_H[BASE_U].push_back(-46.17712672768298);
+    4861           4 :   parameter_solv_H[BASE_U].push_back(-20149.67695512526);
+    4862           4 :   parameter_solv_H[BASE_U].push_back(-5590.242961204435);
+    4863           4 :   parameter_solv_H[BASE_U].push_back(37169.2740983132);
+    4864           4 :   parameter_solv_H[BASE_U].push_back(-26475.631627167604);
+    4865           4 :   parameter_solv_H[BASE_U].push_back(5808.201015156168);
+    4866             : 
+    4867           4 :   parameter_mix_H[BB_PO2].push_back(80.12660011920252);
+    4868           4 :   parameter_mix_H[BB_PO2].push_back(-0.0278885551982023);
+    4869           4 :   parameter_mix_H[BB_PO2].push_back(-60.532194918222984);
+    4870           4 :   parameter_mix_H[BB_PO2].push_back(-2.976882903409687);
+    4871           4 :   parameter_mix_H[BB_PO2].push_back(33.30645116638125);
+    4872           4 :   parameter_mix_H[BB_PO2].push_back(-11.601573219761374);
+    4873           4 :   parameter_mix_H[BB_PO2].push_back(0.12551046492022422);
+    4874             : 
+    4875           4 :   parameter_mix_H[BB_DNA].push_back(712.7621601191935);
+    4876           4 :   parameter_mix_H[BB_DNA].push_back(-0.3228709821198571);
+    4877           4 :   parameter_mix_H[BB_DNA].push_back(-784.5118228559945);
+    4878           4 :   parameter_mix_H[BB_DNA].push_back(-27.196125702249613);
+    4879           4 :   parameter_mix_H[BB_DNA].push_back(410.0185035102729);
+    4880           4 :   parameter_mix_H[BB_DNA].push_back(-54.453513369320355);
+    4881           4 :   parameter_mix_H[BB_DNA].push_back(-44.85506789237683);
+    4882             : 
+    4883           4 :   parameter_mix_H[BB_DNA_5].push_back(625.175339965785);
+    4884           4 :   parameter_mix_H[BB_DNA_5].push_back(0.2691706617748245);
+    4885           4 :   parameter_mix_H[BB_DNA_5].push_back(-582.8721350420001);
+    4886           4 :   parameter_mix_H[BB_DNA_5].push_back(46.512408351374326);
+    4887           4 :   parameter_mix_H[BB_DNA_5].push_back(-58.93886949899108);
+    4888           4 :   parameter_mix_H[BB_DNA_5].push_back(307.29720336085046);
+    4889           4 :   parameter_mix_H[BB_DNA_5].push_back(-131.71996309259953);
+    4890             : 
+    4891           4 :   parameter_mix_H[BB_DNA_3].push_back(625.1753399401266);
+    4892           4 :   parameter_mix_H[BB_DNA_3].push_back(0.08763234414546289);
+    4893           4 :   parameter_mix_H[BB_DNA_3].push_back(-606.8067575087485);
+    4894           4 :   parameter_mix_H[BB_DNA_3].push_back(20.84427254872218);
+    4895           4 :   parameter_mix_H[BB_DNA_3].push_back(92.53523123608991);
+    4896           4 :   parameter_mix_H[BB_DNA_3].push_back(162.04688035654937);
+    4897           4 :   parameter_mix_H[BB_DNA_3].push_back(-89.13571774638052);
+    4898             : 
+    4899           4 :   parameter_mix_H[BB_RNA].push_back(936.9775801191857);
+    4900           4 :   parameter_mix_H[BB_RNA].push_back(-1.3233686929680253);
+    4901           4 :   parameter_mix_H[BB_RNA].push_back(-1212.1627155263773);
+    4902           4 :   parameter_mix_H[BB_RNA].push_back(-141.35324744384351);
+    4903           4 :   parameter_mix_H[BB_RNA].push_back(1155.8281658363026);
+    4904           4 :   parameter_mix_H[BB_RNA].push_back(-548.9340055857343);
+    4905           4 :   parameter_mix_H[BB_RNA].push_back(50.81734777881503);
+    4906             : 
+    4907           4 :   parameter_mix_H[BB_RNA_5].push_back(848.5355201165631);
+    4908           4 :   parameter_mix_H[BB_RNA_5].push_back(-0.49570338490120175);
+    4909           4 :   parameter_mix_H[BB_RNA_5].push_back(-976.1033073783973);
+    4910           4 :   parameter_mix_H[BB_RNA_5].push_back(-32.943532187986605);
+    4911           4 :   parameter_mix_H[BB_RNA_5].push_back(475.66177061923884);
+    4912           4 :   parameter_mix_H[BB_RNA_5].push_back(17.51955845824258);
+    4913           4 :   parameter_mix_H[BB_RNA_5].push_back(-96.74451972314769);
+    4914             : 
+    4915           4 :   parameter_mix_H[BB_RNA_3].push_back(848.5355201192122);
+    4916           4 :   parameter_mix_H[BB_RNA_3].push_back(-0.8301109354355396);
+    4917           4 :   parameter_mix_H[BB_RNA_3].push_back(-1019.9524389785406);
+    4918           4 :   parameter_mix_H[BB_RNA_3].push_back(-84.1388451424885);
+    4919           4 :   parameter_mix_H[BB_RNA_3].push_back(787.1277245040931);
+    4920           4 :   parameter_mix_H[BB_RNA_3].push_back(-294.67807432795627);
+    4921           4 :   parameter_mix_H[BB_RNA_3].push_back(-1.3214626461251089);
+    4922             : 
+    4923           4 :   parameter_mix_H[BASE_A].push_back(1504.9345001191857);
+    4924           4 :   parameter_mix_H[BASE_A].push_back(-3.5306888452552663);
+    4925           4 :   parameter_mix_H[BASE_A].push_back(-2234.3933572775572);
+    4926           4 :   parameter_mix_H[BASE_A].push_back(-380.0255208494757);
+    4927           4 :   parameter_mix_H[BASE_A].push_back(2726.27802432048);
+    4928           4 :   parameter_mix_H[BASE_A].push_back(-1490.8825754968443);
+    4929           4 :   parameter_mix_H[BASE_A].push_back(199.7501110740159);
+    4930             : 
+    4931           4 :   parameter_mix_H[BASE_C].push_back(939.8188801192172);
+    4932           4 :   parameter_mix_H[BASE_C].push_back(-1.489638186262854);
+    4933           4 :   parameter_mix_H[BASE_C].push_back(-1244.5515798554075);
+    4934           4 :   parameter_mix_H[BASE_C].push_back(-161.3972705672055);
+    4935           4 :   parameter_mix_H[BASE_C].push_back(1276.3568466722545);
+    4936           4 :   parameter_mix_H[BASE_C].push_back(-643.3057776225742);
+    4937           4 :   parameter_mix_H[BASE_C].push_back(72.75963113826273);
+    4938             : 
+    4939           4 :   parameter_mix_H[BASE_G].push_back(1768.434840119199);
+    4940           4 :   parameter_mix_H[BASE_G].push_back(-6.505347007077434);
+    4941           4 :   parameter_mix_H[BASE_G].push_back(-2919.3856777898427);
+    4942           4 :   parameter_mix_H[BASE_G].push_back(-701.2456464463938);
+    4943           4 :   parameter_mix_H[BASE_G].push_back(4464.594230284102);
+    4944           4 :   parameter_mix_H[BASE_G].push_back(-2733.138521295608);
+    4945           4 :   parameter_mix_H[BASE_G].push_back(458.1177706235891);
+    4946             : 
+    4947           4 :   parameter_mix_H[BASE_T].push_back(1179.3981001192033);
+    4948           4 :   parameter_mix_H[BASE_T].push_back(-3.2037849252756527);
+    4949           4 :   parameter_mix_H[BASE_T].push_back(-1821.255498763799);
+    4950           4 :   parameter_mix_H[BASE_T].push_back(-371.01993266441303);
+    4951           4 :   parameter_mix_H[BASE_T].push_back(2604.074226688971);
+    4952           4 :   parameter_mix_H[BASE_T].push_back(-1648.1965787713084);
+    4953           4 :   parameter_mix_H[BASE_T].push_back(307.2962186436368);
+    4954             : 
+    4955           4 :   parameter_mix_H[BASE_U].push_back(956.3442001192266);
+    4956           4 :   parameter_mix_H[BASE_U].push_back(-1.724458000760567);
+    4957           4 :   parameter_mix_H[BASE_U].push_back(-1287.9746970192687);
+    4958           4 :   parameter_mix_H[BASE_U].push_back(-192.74748379510373);
+    4959           4 :   parameter_mix_H[BASE_U].push_back(1459.0789258833893);
+    4960           4 :   parameter_mix_H[BASE_U].push_back(-810.0763075080915);
+    4961           4 :   parameter_mix_H[BASE_U].push_back(119.81810290248339);
+    4962             : 
+    4963           4 :   parameter_vac_H[BB_PO2].push_back(2.7889001116093275);
+    4964           4 :   parameter_vac_H[BB_PO2].push_back(-0.00011178884266113128);
+    4965           4 :   parameter_vac_H[BB_PO2].push_back(-1.1702605818380667);
+    4966           4 :   parameter_vac_H[BB_PO2].push_back(-0.011278044036819933);
+    4967           4 :   parameter_vac_H[BB_PO2].push_back(0.3214006584089025);
+    4968           4 :   parameter_vac_H[BB_PO2].push_back(-0.04097165983591666);
+    4969           4 :   parameter_vac_H[BB_PO2].push_back(-0.017525098100539722);
+    4970             : 
+    4971           4 :   parameter_vac_H[BB_DNA].push_back(5.987809026456476);
+    4972           4 :   parameter_vac_H[BB_DNA].push_back(9.945454528827912e-05);
+    4973           4 :   parameter_vac_H[BB_DNA].push_back(-1.1884708569330031);
+    4974           4 :   parameter_vac_H[BB_DNA].push_back(-0.007457733256362841);
+    4975           4 :   parameter_vac_H[BB_DNA].push_back(0.05666858781418339);
+    4976           4 :   parameter_vac_H[BB_DNA].push_back(-0.15158797629971757);
+    4977           4 :   parameter_vac_H[BB_DNA].push_back(0.11642340861329734);
+    4978             : 
+    4979           4 :   parameter_vac_H[BB_DNA_5].push_back(4.297328944539055);
+    4980           4 :   parameter_vac_H[BB_DNA_5].push_back(0.0014793971885106831);
+    4981           4 :   parameter_vac_H[BB_DNA_5].push_back(1.3961088365255605);
+    4982           4 :   parameter_vac_H[BB_DNA_5].push_back(0.08974639858979384);
+    4983           4 :   parameter_vac_H[BB_DNA_5].push_back(-1.5198099705167643);
+    4984           4 :   parameter_vac_H[BB_DNA_5].push_back(-0.12127122359433733);
+    4985           4 :   parameter_vac_H[BB_DNA_5].push_back(0.4134601046223601);
+    4986             : 
+    4987           4 :   parameter_vac_H[BB_DNA_3].push_back(4.297328886488132);
+    4988           4 :   parameter_vac_H[BB_DNA_3].push_back(0.0041802954281271905);
+    4989           4 :   parameter_vac_H[BB_DNA_3].push_back(1.6065462295705266);
+    4990           4 :   parameter_vac_H[BB_DNA_3].push_back(0.4399805535688805);
+    4991           4 :   parameter_vac_H[BB_DNA_3].push_back(-3.3806711791929804);
+    4992           4 :   parameter_vac_H[BB_DNA_3].push_back(1.6729551563628675);
+    4993           4 :   parameter_vac_H[BB_DNA_3].push_back(-0.10911063067909885);
+    4994             : 
+    4995           4 :   parameter_vac_H[BB_RNA].push_back(9.162728984394093);
+    4996           4 :   parameter_vac_H[BB_RNA].push_back(0.00019952321584579868);
+    4997           4 :   parameter_vac_H[BB_RNA].push_back(-4.744748946331966);
+    4998           4 :   parameter_vac_H[BB_RNA].push_back(0.025106563403946364);
+    4999           4 :   parameter_vac_H[BB_RNA].push_back(1.2302956694109803);
+    5000           4 :   parameter_vac_H[BB_RNA].push_back(0.12359062278096915);
+    5001           4 :   parameter_vac_H[BB_RNA].push_back(-0.1725633367685285);
+    5002             : 
+    5003           4 :   parameter_vac_H[BB_RNA_5].push_back(7.038408898671503);
+    5004           4 :   parameter_vac_H[BB_RNA_5].push_back(0.005106788424920148);
+    5005           4 :   parameter_vac_H[BB_RNA_5].push_back(-0.8981588221803118);
+    5006           4 :   parameter_vac_H[BB_RNA_5].push_back(0.4922588155214312);
+    5007           4 :   parameter_vac_H[BB_RNA_5].push_back(-2.6667853454023644);
+    5008           4 :   parameter_vac_H[BB_RNA_5].push_back(1.533316567240718);
+    5009           4 :   parameter_vac_H[BB_RNA_5].push_back(-0.07199604869737707);
+    5010             : 
+    5011           4 :   parameter_vac_H[BB_RNA_3].push_back(7.038408892621863);
+    5012           4 :   parameter_vac_H[BB_RNA_3].push_back(0.002993083907266898);
+    5013           4 :   parameter_vac_H[BB_RNA_3].push_back(-1.3626596831098492);
+    5014           4 :   parameter_vac_H[BB_RNA_3].push_back(0.3138856961130113);
+    5015           4 :   parameter_vac_H[BB_RNA_3].push_back(-1.684185014289391);
+    5016           4 :   parameter_vac_H[BB_RNA_3].push_back(1.1862168720864616);
+    5017           4 :   parameter_vac_H[BB_RNA_3].push_back(-0.1443894172417523);
+    5018             : 
+    5019           4 :   parameter_vac_H[BASE_A].push_back(42.62784088079008);
+    5020           4 :   parameter_vac_H[BASE_A].push_back(0.02302908536431516);
+    5021           4 :   parameter_vac_H[BASE_A].push_back(-33.22707177297222);
+    5022           4 :   parameter_vac_H[BASE_A].push_back(2.6853748424439834);
+    5023           4 :   parameter_vac_H[BASE_A].push_back(-1.6632902891624768);
+    5024           4 :   parameter_vac_H[BASE_A].push_back(11.905766349515268);
+    5025           4 :   parameter_vac_H[BASE_A].push_back(-4.547083454788805);
+    5026             : 
+    5027           4 :   parameter_vac_H[BASE_C].push_back(20.83009588079022);
+    5028           4 :   parameter_vac_H[BASE_C].push_back(0.017055822321768378);
+    5029           4 :   parameter_vac_H[BASE_C].push_back(-8.349634734370916);
+    5030           4 :   parameter_vac_H[BASE_C].push_back(1.9324634367723073);
+    5031           4 :   parameter_vac_H[BASE_C].push_back(-8.435199734060882);
+    5032           4 :   parameter_vac_H[BASE_C].push_back(8.272798368731268);
+    5033           4 :   parameter_vac_H[BASE_C].push_back(-1.986671440757263);
+    5034             : 
+    5035           4 :   parameter_vac_H[BASE_G].push_back(50.53788088079374);
+    5036           4 :   parameter_vac_H[BASE_G].push_back(0.024035597617780367);
+    5037           4 :   parameter_vac_H[BASE_G].push_back(-47.94916639302998);
+    5038           4 :   parameter_vac_H[BASE_G].push_back(3.143375731466498);
+    5039           4 :   parameter_vac_H[BASE_G].push_back(4.297009866708155);
+    5040           4 :   parameter_vac_H[BASE_G].push_back(15.855448505050578);
+    5041           4 :   parameter_vac_H[BASE_G].push_back(-7.827484135873966);
+    5042             : 
+    5043           4 :   parameter_vac_H[BASE_T].push_back(20.20502488079069);
+    5044           4 :   parameter_vac_H[BASE_T].push_back(0.033659966153300002);
+    5045           4 :   parameter_vac_H[BASE_T].push_back(-6.057999187718758);
+    5046           4 :   parameter_vac_H[BASE_T].push_back(4.146969282504351);
+    5047           4 :   parameter_vac_H[BASE_T].push_back(-20.664315319574357);
+    5048           4 :   parameter_vac_H[BASE_T].push_back(19.982178623201648);
+    5049           4 :   parameter_vac_H[BASE_T].push_back(-5.440921587349456);
+    5050             : 
+    5051           4 :   parameter_vac_H[BASE_U].push_back(20.958084119209754);
+    5052           4 :   parameter_vac_H[BASE_U].push_back(-0.005164660707148803);
+    5053           4 :   parameter_vac_H[BASE_U].push_back(-14.53831312442302);
+    5054           4 :   parameter_vac_H[BASE_U].push_back(-0.5276995756310442);
+    5055           4 :   parameter_vac_H[BASE_U].push_back(7.060900707522138);
+    5056           4 :   parameter_vac_H[BASE_U].push_back(-1.8988408480951036);
+    5057           4 :   parameter_vac_H[BASE_U].push_back(-0.215000567681094);
+    5058             : 
+    5059       14298 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    5060       14294 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    5061       14294 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    5062       14294 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    5063       14294 :     if(Rname=="ALA") {
+    5064         732 :       atoi[residue_atom[i]]=ALA;
+    5065       13562 :     } else if(Rname=="ARG") {
+    5066         864 :       atoi[residue_atom[i]]=ARG;
+    5067       12698 :     } else if(Rname=="ASN") {
+    5068         720 :       atoi[residue_atom[i]]=ASN;
+    5069       11978 :     } else if(Rname=="ASP") {
+    5070         624 :       atoi[residue_atom[i]]=ASP;
+    5071       11354 :     } else if(Rname=="CYS") {
+    5072          48 :       atoi[residue_atom[i]]=CYS;
+    5073       11306 :     } else if(Rname=="GLN") {
+    5074        1064 :       atoi[residue_atom[i]]=GLN;
+    5075       10242 :     } else if(Rname=="GLU") {
+    5076         476 :       atoi[residue_atom[i]]=GLU;
+    5077        9766 :     } else if(Rname=="GLY") {
+    5078         648 :       atoi[residue_atom[i]]=GLY;
+    5079        9118 :     } else if(Rname=="HIS") {
+    5080           0 :       atoi[residue_atom[i]]=HIS;
+    5081        9118 :     } else if(Rname=="HID") {
+    5082           0 :       atoi[residue_atom[i]]=HIS;
+    5083        9118 :     } else if(Rname=="HIE") {
+    5084         144 :       atoi[residue_atom[i]]=HIS;
+    5085        8974 :     } else if(Rname=="HIP") {
+    5086           0 :       atoi[residue_atom[i]]=HIP;
+    5087             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    5088        8974 :     } else if(Rname=="HSD") {
+    5089           0 :       atoi[residue_atom[i]]=HIS;
+    5090        8974 :     } else if(Rname=="HSE") {
+    5091           0 :       atoi[residue_atom[i]]=HIS;
+    5092        8974 :     } else if(Rname=="HSP") {
+    5093           0 :       atoi[residue_atom[i]]=HIP;
+    5094        8974 :     } else if(Rname=="ILE") {
+    5095         864 :       atoi[residue_atom[i]]=ILE;
+    5096        8110 :     } else if(Rname=="LEU") {
+    5097        1520 :       atoi[residue_atom[i]]=LEU;
+    5098        6590 :     } else if(Rname=="LYS") {
+    5099        1040 :       atoi[residue_atom[i]]=LYS;
+    5100        5550 :     } else if(Rname=="MET") {
+    5101         608 :       atoi[residue_atom[i]]=MET;
+    5102        4942 :     } else if(Rname=="PHE") {
+    5103        1008 :       atoi[residue_atom[i]]=PHE;
+    5104        3934 :     } else if(Rname=="PRO") {
+    5105         748 :       atoi[residue_atom[i]]=PRO;
+    5106        3186 :     } else if(Rname=="SER") {
+    5107         528 :       atoi[residue_atom[i]]=SER;
+    5108        2658 :     } else if(Rname=="THR") {
+    5109         504 :       atoi[residue_atom[i]]=THR;
+    5110        2154 :     } else if(Rname=="TRP") {
+    5111           0 :       atoi[residue_atom[i]]=TRP;
+    5112        2154 :     } else if(Rname=="TYR") {
+    5113         528 :       atoi[residue_atom[i]]=TYR;
+    5114        1626 :     } else if(Rname=="VAL") {
+    5115        1088 :       atoi[residue_atom[i]]=VAL;
+    5116             :     }
+    5117             :     // NUCLEIC ACIDS
+    5118             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    5119             :     // RNA - G
+    5120         538 :     else if(Rname=="G") {
+    5121           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5122           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5123           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5124           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5125           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5126           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5127           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5128           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5129           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5130           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5131           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5132           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5133           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5134           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5135           0 :         atoi[residue_atom[i]]=BASE_G;
+    5136           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5137             :       // RNA - G3
+    5138         538 :     } else if(Rname=="G3") {
+    5139           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5140           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5141           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5142           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5143           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5144           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5145           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5146           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5147           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5148           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5149           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5150           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5151           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5152           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5153           0 :         atoi[residue_atom[i]]=BASE_G;
+    5154           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5155             :       // RNA - G5
+    5156         538 :     } else if(Rname=="G5") {
+    5157           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5158           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5159           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5160           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5161           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5162           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5163           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5164           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5165           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5166           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5167           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5168           0 :         atoi[residue_atom[i]]=BASE_G;
+    5169           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5170             :       // RNA - U
+    5171         538 :     } else if(Rname=="U") {
+    5172        1554 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5173        1176 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5174          42 :         atoi [residue_atom[i]]=BB_PO2;
+    5175        1372 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5176        1148 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5177         924 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5178         714 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5179         644 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5180         840 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5181         224 :         atoi[residue_atom[i]]=BB_RNA;
+    5182         476 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5183         252 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5184         196 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5185         154 :         atoi[residue_atom[i]]=BASE_U;
+    5186           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5187             :       // RNA - U3
+    5188         118 :     } else if(Rname=="U3") {
+    5189         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5190         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5191           6 :         atoi [residue_atom[i]]=BB_PO2;
+    5192         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5193         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5194         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5195         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5196          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5197          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5198          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5199          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5200          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5201          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5202          22 :         atoi[residue_atom[i]]=BASE_U;
+    5203           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5204             :       // RNA - U5
+    5205          56 :     } else if(Rname=="U5") {
+    5206         204 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5207         172 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5208         140 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5209         108 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5210          88 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5211          78 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5212          34 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5213          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    5214          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    5215          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    5216          22 :         atoi[residue_atom[i]]=BASE_U;
+    5217           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5218             :       // RNA - A
+    5219           0 :     } else if(Rname=="A") {
+    5220           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5221           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5222           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5223           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5224           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5225           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5226           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5227           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5228           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5229           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5230           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5231           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5232           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5233           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5234           0 :         atoi[residue_atom[i]]=BASE_A;
+    5235           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5236             :       // RNA - A3
+    5237           0 :     } else if(Rname=="A3") {
+    5238           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5239           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5240           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5241           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5242           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5243           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5244           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5245           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5246           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5247           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5248           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5249           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5250           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5251           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5252           0 :         atoi[residue_atom[i]]=BASE_A;
+    5253           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5254             :       // RNA - A5
+    5255           0 :     } else if(Rname=="A5") {
+    5256           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5257           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5258           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5259           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5260           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5261           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5262           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5263           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5264           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5265           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5266           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5267           0 :         atoi[residue_atom[i]]=BASE_A;
+    5268           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5269             :       // RNA - C
+    5270           0 :     } else if(Rname=="C") {
+    5271           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5272           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5273           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5274           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5275           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5276           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5277           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    5278           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    5279           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    5280           0 :         atoi[residue_atom[i]]=BB_RNA;
+    5281           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5282           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5283           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5284           0 :         atoi[residue_atom[i]]=BASE_C;
+    5285           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5286             :       // RNA - C3
+    5287           0 :     } else if(Rname=="C3") {
+    5288           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5289           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5290           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5291           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    5292           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    5293           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    5294           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    5295           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    5296           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    5297           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    5298           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5299           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5300           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5301           0 :         atoi[residue_atom[i]]=BASE_C;
+    5302           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5303             :       // RNA - C5
+    5304           0 :     } else if(Rname=="C5") {
+    5305           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5306           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    5307           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    5308           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    5309           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    5310           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    5311           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    5312           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5313           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5314           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5315           0 :         atoi[residue_atom[i]]=BASE_C;
+    5316           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5317             :       // DNA - G
+    5318           0 :     } else if(Rname=="DG") {
+    5319           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5320           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5321           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5322           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5323           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5324           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5325           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5326           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5327           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5328           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5329           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5330           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5331           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5332           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5333           0 :         atoi[residue_atom[i]]=BASE_G;
+    5334           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5335             :       // DNA - G3
+    5336           0 :     } else if(Rname=="DG3") {
+    5337           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5338           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5339           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5340           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5341           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5342           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5343           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5344           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5345             :                 Aname=="H3T" ) {
+    5346           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5347           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5348           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5349           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5350           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5351           0 :         atoi[residue_atom[i]]=BASE_G;
+    5352           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5353             :       // DNA - G5
+    5354           0 :     } else if(Rname=="DG5") {
+    5355           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5356           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5357           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5358           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5359           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5360             :           Aname=="H5T" ) {
+    5361           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5362           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    5363           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    5364           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    5365           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    5366           0 :         atoi[residue_atom[i]]=BASE_G;
+    5367           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5368             :       // DNA - T
+    5369           0 :     } else if(Rname=="DT") {
+    5370           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5371           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5372           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5373           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5374           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5375           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5376           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5377           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5378           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5379           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5380           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5381           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5382           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5383           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5384           0 :         atoi[residue_atom[i]]=BASE_T;
+    5385           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5386             :       // DNA - T3
+    5387           0 :     } else if(Rname=="DT3") {
+    5388           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5389           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5390           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5391           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5392           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5393           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5394           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5395           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5396             :                 Aname=="H3T" ) {
+    5397           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5398           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5399           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5400           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5401           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5402           0 :         atoi[residue_atom[i]]=BASE_T;
+    5403           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5404             :       // DNA - T5
+    5405           0 :     } else if(Rname=="DT5") {
+    5406           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5407           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5408           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5409           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5410           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5411             :           Aname=="H5T" ) {
+    5412           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5413           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    5414           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    5415           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    5416           0 :                 Aname=="H72" || Aname=="H73" ) {
+    5417           0 :         atoi[residue_atom[i]]=BASE_T;
+    5418           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5419             :       // DNA - A
+    5420           0 :     } else if(Rname=="DA") {
+    5421           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5422           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5423           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5424           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5425           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5426           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5427           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5428           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5429           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5430           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5431           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5432           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5433           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5434           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5435           0 :         atoi[residue_atom[i]]=BASE_A;
+    5436           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5437             :       // DNA - A3
+    5438           0 :     } else if(Rname=="DA3") {
+    5439           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5440           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5441           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5442           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5443           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5444           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5445           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5446           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5447             :                 Aname=="H3T" ) {
+    5448           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5449           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5450           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5451           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5452           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5453           0 :         atoi[residue_atom[i]]=BASE_A;
+    5454           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5455             :       // DNA - A5
+    5456           0 :     } else if(Rname=="DA5") {
+    5457           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5458           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5459           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5460           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5461           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5462             :           Aname=="H5T" ) {
+    5463           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5464           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    5465           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    5466           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    5467           0 :                 Aname=="H61" || Aname=="H62" ) {
+    5468           0 :         atoi[residue_atom[i]]=BASE_A;
+    5469           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5470             :       // DNA - C
+    5471           0 :     } else if(Rname=="DC") {
+    5472           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5473           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5474           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5475           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5476           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5477           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5478           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5479           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    5480           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    5481           0 :         atoi[residue_atom[i]]=BB_DNA;
+    5482           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5483           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5484           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5485           0 :         atoi[residue_atom[i]]=BASE_C;
+    5486           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5487             :       // DNA - C3
+    5488           0 :     } else if(Rname=="DC3") {
+    5489           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    5490           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    5491           0 :         atoi [residue_atom[i]]=BB_PO2;
+    5492           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5493           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    5494           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5495           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    5496           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5497             :                 Aname=="H3T" ) {
+    5498           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    5499           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5500           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5501           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5502           0 :         atoi[residue_atom[i]]=BASE_C;
+    5503           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5504             :       // DNA - C5
+    5505           0 :     } else if(Rname=="DC5") {
+    5506           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    5507           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    5508           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    5509           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    5510           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    5511             :           Aname=="H5T" ) {
+    5512           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    5513           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    5514           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    5515           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    5516           0 :         atoi[residue_atom[i]]=BASE_C;
+    5517           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    5518           0 :     } else error("Residue not known: "+Rname);
+    5519             :   }
+    5520           4 : }
+    5521             : 
+    5522           4 : void SAXS::getOnebeadparam_sansD(const PDB &pdb, const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &parameter_vac_D, std::vector<std::vector<long double> > &parameter_mix_D)
+    5523             : { // parameter_solv is identical in SAXS/SANS_H/SANS_D since it depends exclusively on param_v. For that reason we kept param_solv only in SAXS and SANS_H.
+    5524           4 :   parameter_mix_D[TRP].push_back(8105.740500119327);
+    5525           4 :   parameter_mix_D[TRP].push_back(-41.785616935469804);
+    5526           4 :   parameter_mix_D[TRP].push_back(-25456.92790554363);
+    5527           4 :   parameter_mix_D[TRP].push_back(-10058.20599969184);
+    5528           4 :   parameter_mix_D[TRP].push_back(86171.76479108425);
+    5529           4 :   parameter_mix_D[TRP].push_back(-83227.63139882773);
+    5530           4 :   parameter_mix_D[TRP].push_back(25121.390436258724);
+    5531             : 
+    5532           4 :   parameter_mix_D[TYR].push_back(6059.530560118732);
+    5533           4 :   parameter_mix_D[TYR].push_back(-24.522695525705736);
+    5534           4 :   parameter_mix_D[TYR].push_back(-17180.858815360847);
+    5535           4 :   parameter_mix_D[TYR].push_back(-5990.1358528219325);
+    5536           4 :   parameter_mix_D[TYR].push_back(52936.46126637543);
+    5537           4 :   parameter_mix_D[TYR].push_back(-50150.0042622683);
+    5538           4 :   parameter_mix_D[TYR].push_back(14914.553672440441);
+    5539             : 
+    5540           4 :   parameter_mix_D[PHE].push_back(5563.404880119222);
+    5541           4 :   parameter_mix_D[PHE].push_back(-33.609784645922794);
+    5542           4 :   parameter_mix_D[PHE].push_back(-14576.935030777448);
+    5543           4 :   parameter_mix_D[PHE].push_back(-5759.170105553782);
+    5544           4 :   parameter_mix_D[PHE].push_back(43316.895956549866);
+    5545           4 :   parameter_mix_D[PHE].push_back(-39106.58694570862);
+    5546           4 :   parameter_mix_D[PHE].push_back(11143.375742877468);
+    5547             : 
+    5548           4 :   parameter_mix_D[HIP].push_back(3981.7108801192553);
+    5549           4 :   parameter_mix_D[HIP].push_back(-23.788371565946427);
+    5550           4 :   parameter_mix_D[HIP].push_back(-9471.73953776056);
+    5551           4 :   parameter_mix_D[HIP].push_back(-3690.3981577198365);
+    5552           4 :   parameter_mix_D[HIP].push_back(26365.958584217453);
+    5553           4 :   parameter_mix_D[HIP].push_back(-23067.58974902849);
+    5554           4 :   parameter_mix_D[HIP].push_back(6390.507451097114);
+    5555             : 
+    5556           4 :   parameter_mix_D[ARG].push_back(6279.489359881259);
+    5557           4 :   parameter_mix_D[ARG].push_back(1.2061878338083583);
+    5558           4 :   parameter_mix_D[ARG].push_back(-20305.413937989913);
+    5559           4 :   parameter_mix_D[ARG].push_back(-5621.666335222669);
+    5560           4 :   parameter_mix_D[ARG].push_back(67341.96785520067);
+    5561           4 :   parameter_mix_D[ARG].push_back(-68849.15464591733);
+    5562           4 :   parameter_mix_D[ARG].push_back(21773.0630363882);
+    5563             : 
+    5564           4 :   parameter_mix_D[LYS].push_back(5434.487400119193);
+    5565           4 :   parameter_mix_D[LYS].push_back(-29.32356328987909);
+    5566           4 :   parameter_mix_D[LYS].push_back(-14363.66155749977);
+    5567           4 :   parameter_mix_D[LYS].push_back(-5650.383128516514);
+    5568           4 :   parameter_mix_D[LYS].push_back(44573.73888236887);
+    5569           4 :   parameter_mix_D[LYS].push_back(-41515.980945300485);
+    5570           4 :   parameter_mix_D[LYS].push_back(12181.965046747513);
+    5571             : 
+    5572           4 :   parameter_mix_D[CYS].push_back(1519.4030001192032);
+    5573           4 :   parameter_mix_D[CYS].push_back(-3.564386334921097);
+    5574           4 :   parameter_mix_D[CYS].push_back(-2275.813167459516);
+    5575           4 :   parameter_mix_D[CYS].push_back(-409.54431591328125);
+    5576           4 :   parameter_mix_D[CYS].push_back(2969.5412742839258);
+    5577           4 :   parameter_mix_D[CYS].push_back(-1798.3157146799638);
+    5578           4 :   parameter_mix_D[CYS].push_back(314.568167888235);
+    5579             : 
+    5580           4 :   parameter_mix_D[ASP].push_back(1861.6998401191709);
+    5581           4 :   parameter_mix_D[ASP].push_back(-5.349780637260551);
+    5582           4 :   parameter_mix_D[ASP].push_back(-2960.36741510377);
+    5583           4 :   parameter_mix_D[ASP].push_back(-621.8270745040523);
+    5584           4 :   parameter_mix_D[ASP].push_back(4334.798300452934);
+    5585           4 :   parameter_mix_D[ASP].push_back(-2776.8560521554878);
+    5586           4 :   parameter_mix_D[ASP].push_back(527.9777182094936);
+    5587             : 
+    5588           4 :   parameter_mix_D[GLU].push_back(2861.6017201192253);
+    5589           4 :   parameter_mix_D[GLU].push_back(-13.146456903921809);
+    5590           4 :   parameter_mix_D[GLU].push_back(-5393.408563875243);
+    5591           4 :   parameter_mix_D[GLU].push_back(-1646.460570818364);
+    5592           4 :   parameter_mix_D[GLU].push_back(10884.544923253858);
+    5593           4 :   parameter_mix_D[GLU].push_back(-8159.923373048856);
+    5594           4 :   parameter_mix_D[GLU].push_back(1914.545660397314);
+    5595             : 
+    5596           4 :   parameter_mix_D[ILE].push_back(4288.585540119189);
+    5597           4 :   parameter_mix_D[ILE].push_back(-19.937215352880365);
+    5598           4 :   parameter_mix_D[ILE].push_back(-8324.540144463375);
+    5599           4 :   parameter_mix_D[ILE].push_back(-2431.835931316717);
+    5600           4 :   parameter_mix_D[ILE].push_back(16079.9912986194);
+    5601           4 :   parameter_mix_D[ILE].push_back(-11637.693060394462);
+    5602           4 :   parameter_mix_D[ILE].push_back(2600.8258068480495);
+    5603             : 
+    5604           4 :   parameter_mix_D[LEU].push_back(4288.585540119186);
+    5605           4 :   parameter_mix_D[LEU].push_back(-21.50343599461759);
+    5606           4 :   parameter_mix_D[LEU].push_back(-8479.703435720274);
+    5607           4 :   parameter_mix_D[LEU].push_back(-2647.8693829269596);
+    5608           4 :   parameter_mix_D[LEU].push_back(17297.18115838578);
+    5609           4 :   parameter_mix_D[LEU].push_back(-12826.972408323161);
+    5610           4 :   parameter_mix_D[LEU].push_back(2953.1262521615645);
+    5611             : 
+    5612           4 :   parameter_mix_D[MET].push_back(3561.6276801191552);
+    5613           4 :   parameter_mix_D[MET].push_back(-22.19323392975885);
+    5614           4 :   parameter_mix_D[MET].push_back(-8348.33907053846);
+    5615           4 :   parameter_mix_D[MET].push_back(-3323.053272414289);
+    5616           4 :   parameter_mix_D[MET].push_back(23153.238909304255);
+    5617           4 :   parameter_mix_D[MET].push_back(-20091.960440908682);
+    5618           4 :   parameter_mix_D[MET].push_back(5518.759669687693);
+    5619             : 
+    5620           4 :   parameter_mix_D[ASN].push_back(2326.5396001192003);
+    5621           4 :   parameter_mix_D[ASN].push_back(-8.634908921289112);
+    5622           4 :   parameter_mix_D[ASN].push_back(-4057.4552636749636);
+    5623           4 :   parameter_mix_D[ASN].push_back(-1032.743130124821);
+    5624           4 :   parameter_mix_D[ASN].push_back(6957.141592429445);
+    5625           4 :   parameter_mix_D[ASN].push_back(-4808.265318722317);
+    5626           4 :   parameter_mix_D[ASN].push_back(1016.3944815533755);
+    5627             : 
+    5628           4 :   parameter_mix_D[PRO].push_back(2471.1663601191985);
+    5629           4 :   parameter_mix_D[PRO].push_back(-6.360795284260088);
+    5630           4 :   parameter_mix_D[PRO].push_back(-3825.4533158429153);
+    5631           4 :   parameter_mix_D[PRO].push_back(-728.7164844824666);
+    5632           4 :   parameter_mix_D[PRO].push_back(5195.036303827973);
+    5633           4 :   parameter_mix_D[PRO].push_back(-3183.733716480742);
+    5634           4 :   parameter_mix_D[PRO].push_back(563.2376162754107);
+    5635             : 
+    5636           4 :   parameter_mix_D[GLN].push_back(3431.669280119236);
+    5637           4 :   parameter_mix_D[GLN].push_back(-19.412747205646166);
+    5638           4 :   parameter_mix_D[GLN].push_back(-7298.017973002134);
+    5639           4 :   parameter_mix_D[GLN].push_back(-2659.3014182337706);
+    5640           4 :   parameter_mix_D[GLN].push_back(17890.76595805173);
+    5641           4 :   parameter_mix_D[GLN].push_back(-14684.603067192957);
+    5642           4 :   parameter_mix_D[GLN].push_back(3814.338335151394);
+    5643             : 
+    5644           4 :   parameter_mix_D[SER].push_back(1423.885200119192);
+    5645           4 :   parameter_mix_D[SER].push_back(-2.586428606204385);
+    5646           4 :   parameter_mix_D[SER].push_back(-1966.7369507188134);
+    5647           4 :   parameter_mix_D[SER].push_back(-289.17277383434106);
+    5648           4 :   parameter_mix_D[SER].push_back(2209.478296043199);
+    5649           4 :   parameter_mix_D[SER].push_back(-1216.1521614944);
+    5650           4 :   parameter_mix_D[SER].push_back(177.0615931546754);
+    5651             : 
+    5652           4 :   parameter_mix_D[THR].push_back(2311.2364801191825);
+    5653           4 :   parameter_mix_D[THR].push_back(-6.258071321531929);
+    5654           4 :   parameter_mix_D[THR].push_back(-3656.295629081312);
+    5655           4 :   parameter_mix_D[THR].push_back(-716.4013890357804);
+    5656           4 :   parameter_mix_D[THR].push_back(5071.656317108832);
+    5657           4 :   parameter_mix_D[THR].push_back(-3125.8076789667816);
+    5658           4 :   parameter_mix_D[THR].push_back(555.9775741081131);
+    5659             : 
+    5660           4 :   parameter_mix_D[VAL].push_back(3041.128320119224);
+    5661           4 :   parameter_mix_D[VAL].push_back(-9.314034190716423);
+    5662           4 :   parameter_mix_D[VAL].push_back(-5075.684780220629);
+    5663           4 :   parameter_mix_D[VAL].push_back(-1070.7083380665008);
+    5664           4 :   parameter_mix_D[VAL].push_back(7455.654515006894);
+    5665           4 :   parameter_mix_D[VAL].push_back(-4701.19187164774);
+    5666           4 :   parameter_mix_D[VAL].push_back(863.4906179388547);
+    5667             : 
+    5668           4 :   parameter_mix_D[ALA].push_back(1187.65300011922);
+    5669           4 :   parameter_mix_D[ALA].push_back(-1.7011187932116822);
+    5670           4 :   parameter_mix_D[ALA].push_back(-1521.0113615359212);
+    5671           4 :   parameter_mix_D[ALA].push_back(-187.93745840575576);
+    5672           4 :   parameter_mix_D[ALA].push_back(1514.6745873304449);
+    5673           4 :   parameter_mix_D[ALA].push_back(-775.3890045113897);
+    5674           4 :   parameter_mix_D[ALA].push_back(96.41428177656567);
+    5675             : 
+    5676           4 :   parameter_mix_D[GLY].push_back(581.6349001192067);
+    5677           4 :   parameter_mix_D[GLY].push_back(-0.5877833598361395);
+    5678           4 :   parameter_mix_D[GLY].push_back(-640.0421286186524);
+    5679           4 :   parameter_mix_D[GLY].push_back(-64.58515074152534);
+    5680           4 :   parameter_mix_D[GLY].push_back(551.9509853583185);
+    5681           4 :   parameter_mix_D[GLY].push_back(-264.1522021146006);
+    5682           4 :   parameter_mix_D[GLY].push_back(28.36986478439301);
+    5683             : 
+    5684           4 :   parameter_mix_D[HIS].push_back(3648.812220119277);
+    5685           4 :   parameter_mix_D[HIS].push_back(-22.703075403555548);
+    5686           4 :   parameter_mix_D[HIS].push_back(-8260.235189881098);
+    5687           4 :   parameter_mix_D[HIS].push_back(-3190.3176569039265);
+    5688           4 :   parameter_mix_D[HIS].push_back(21589.074332364213);
+    5689           4 :   parameter_mix_D[HIS].push_back(-18108.640157613925);
+    5690           4 :   parameter_mix_D[HIS].push_back(4801.237639634437);
+    5691             : 
+    5692           4 :   parameter_vac_D[TRP].push_back(270.43802511921314);
+    5693           4 :   parameter_vac_D[TRP].push_back(-2.196022464340772);
+    5694           4 :   parameter_vac_D[TRP].push_back(-780.9546710244318);
+    5695           4 :   parameter_vac_D[TRP].push_back(-371.1573508312626);
+    5696           4 :   parameter_vac_D[TRP].push_back(2668.7678731652445);
+    5697           4 :   parameter_vac_D[TRP].push_back(-2478.2920954223678);
+    5698           4 :   parameter_vac_D[TRP].push_back(722.3731624901676);
+    5699             : 
+    5700           4 :   parameter_vac_D[TYR].push_back(198.471744119211);
+    5701           4 :   parameter_vac_D[TYR].push_back(-1.236792846228289);
+    5702           4 :   parameter_vac_D[TYR].push_back(-508.0448711054671);
+    5703           4 :   parameter_vac_D[TYR].push_back(-210.55908129481216);
+    5704           4 :   parameter_vac_D[TYR].push_back(1558.3884734212413);
+    5705           4 :   parameter_vac_D[TYR].push_back(-1418.36319255665);
+    5706           4 :   parameter_vac_D[TYR].push_back(407.21567613893296);
+    5707             : 
+    5708           4 :   parameter_vac_D[PHE].push_back(182.46606411921402);
+    5709           4 :   parameter_vac_D[PHE].push_back(-1.2708008333861447);
+    5710           4 :   parameter_vac_D[PHE].push_back(-424.50905926426054);
+    5711           4 :   parameter_vac_D[PHE].push_back(-177.97207825696387);
+    5712           4 :   parameter_vac_D[PHE].push_back(1180.839971941918);
+    5713           4 :   parameter_vac_D[PHE].push_back(-1004.004765231886);
+    5714           4 :   parameter_vac_D[PHE].push_back(269.34384064610344);
+    5715             : 
+    5716           4 :   parameter_vac_D[HIP].push_back(161.95107611920753);
+    5717           4 :   parameter_vac_D[HIP].push_back(-0.9661246983835707);
+    5718           4 :   parameter_vac_D[HIP].push_back(-332.04673226423995);
+    5719           4 :   parameter_vac_D[HIP].push_back(-125.41755194926544);
+    5720           4 :   parameter_vac_D[HIP].push_back(808.705672166199);
+    5721           4 :   parameter_vac_D[HIP].push_back(-648.8340711218191);
+    5722           4 :   parameter_vac_D[HIP].push_back(163.71251277400307);
+    5723             : 
+    5724           4 :   parameter_vac_D[ARG].push_back(289.0340011192071);
+    5725           4 :   parameter_vac_D[ARG].push_back(-1.4195753436279361);
+    5726           4 :   parameter_vac_D[ARG].push_back(-836.3864005546434);
+    5727           4 :   parameter_vac_D[ARG].push_back(-346.7081039129904);
+    5728           4 :   parameter_vac_D[ARG].push_back(2922.003491580559);
+    5729           4 :   parameter_vac_D[ARG].push_back(-2864.816533173085);
+    5730           4 :   parameter_vac_D[ARG].push_back(877.9525045072293);
+    5731             : 
+    5732           4 :   parameter_vac_D[LYS].push_back(228.64464111920753);
+    5733           4 :   parameter_vac_D[LYS].push_back(-1.686580749083617);
+    5734           4 :   parameter_vac_D[LYS].push_back(-544.8870548339771);
+    5735           4 :   parameter_vac_D[LYS].push_back(-252.11087773186324);
+    5736           4 :   parameter_vac_D[LYS].push_back(1693.784850493428);
+    5737           4 :   parameter_vac_D[LYS].push_back(-1514.2375008160348);
+    5738           4 :   parameter_vac_D[LYS].push_back(427.0713155512121);
+    5739             : 
+    5740           4 :   parameter_vac_D[CYS].push_back(50.836900116324315);
+    5741           4 :   parameter_vac_D[CYS].push_back(-0.040204572899665315);
+    5742           4 :   parameter_vac_D[CYS].push_back(-55.592868149339424);
+    5743           4 :   parameter_vac_D[CYS].push_back(-4.341359624977117);
+    5744           4 :   parameter_vac_D[CYS].push_back(41.55290573185214);
+    5745           4 :   parameter_vac_D[CYS].push_back(-17.248208429078456);
+    5746           4 :   parameter_vac_D[CYS].push_back(1.0736187172140528);
+    5747             : 
+    5748           4 :   parameter_vac_D[ASP].push_back(64.12806411920792);
+    5749           4 :   parameter_vac_D[ASP].push_back(-0.08245818875074411);
+    5750           4 :   parameter_vac_D[ASP].push_back(-78.95500211069523);
+    5751           4 :   parameter_vac_D[ASP].push_back(-9.030157332821238);
+    5752           4 :   parameter_vac_D[ASP].push_back(74.72033164806712);
+    5753           4 :   parameter_vac_D[ASP].push_back(-36.71042192737952);
+    5754           4 :   parameter_vac_D[ASP].push_back(4.0989206257493676);
+    5755             : 
+    5756           4 :   parameter_vac_D[GLU].push_back(100.14004911920799);
+    5757           4 :   parameter_vac_D[GLU].push_back(-0.28685123265362006);
+    5758           4 :   parameter_vac_D[GLU].push_back(-152.44619103423773);
+    5759           4 :   parameter_vac_D[GLU].push_back(-32.99432901288321);
+    5760           4 :   parameter_vac_D[GLU].push_back(225.5853175183811);
+    5761           4 :   parameter_vac_D[GLU].push_back(-144.8489352831419);
+    5762           4 :   parameter_vac_D[GLU].push_back(27.49692658880534);
+    5763             : 
+    5764           4 :   parameter_vac_D[ILE].push_back(165.04540911921134);
+    5765           4 :   parameter_vac_D[ILE].push_back(-0.5061553029227089);
+    5766           4 :   parameter_vac_D[ILE].push_back(-275.1890586090823);
+    5767           4 :   parameter_vac_D[ILE].push_back(-57.288063177375356);
+    5768           4 :   parameter_vac_D[ILE].push_back(398.9780357099449);
+    5769           4 :   parameter_vac_D[ILE].push_back(-245.42678814428692);
+    5770           4 :   parameter_vac_D[ILE].push_back(42.72941025472001);
+    5771             : 
+    5772           4 :   parameter_vac_D[LEU].push_back(165.04540911921134);
+    5773           4 :   parameter_vac_D[LEU].push_back(-0.580034983510499);
+    5774           4 :   parameter_vac_D[LEU].push_back(-281.30910057877514);
+    5775           4 :   parameter_vac_D[LEU].push_back(-66.19427345166183);
+    5776           4 :   parameter_vac_D[LEU].push_back(445.19214155995115);
+    5777           4 :   parameter_vac_D[LEU].push_back(-287.0653610399624);
+    5778           4 :   parameter_vac_D[LEU].push_back(53.86626261066706);
+    5779             : 
+    5780           4 :   parameter_vac_D[MET].push_back(123.83238411920684);
+    5781           4 :   parameter_vac_D[MET].push_back(-0.7698672022751385);
+    5782           4 :   parameter_vac_D[MET].push_back(-251.2481622173618);
+    5783           4 :   parameter_vac_D[MET].push_back(-100.67742019193848);
+    5784           4 :   parameter_vac_D[MET].push_back(641.1563254731632);
+    5785           4 :   parameter_vac_D[MET].push_back(-524.8742634212379);
+    5786           4 :   parameter_vac_D[MET].push_back(135.36487813767542);
+    5787             : 
+    5788           4 :   parameter_vac_D[ASN].push_back(94.12880411921148);
+    5789           4 :   parameter_vac_D[ASN].push_back(-0.22986194121078912);
+    5790           4 :   parameter_vac_D[ASN].push_back(-138.78769705028003);
+    5791           4 :   parameter_vac_D[ASN].push_back(-25.896846049402594);
+    5792           4 :   parameter_vac_D[ASN].push_back(184.55609781654326);
+    5793           4 :   parameter_vac_D[ASN].push_back(-110.14043851975404);
+    5794           4 :   parameter_vac_D[ASN].push_back(18.388834098004153);
+    5795             : 
+    5796           4 :   parameter_vac_D[PRO].push_back(90.51619611920745);
+    5797           4 :   parameter_vac_D[PRO].push_back(-0.0977238494110807);
+    5798           4 :   parameter_vac_D[PRO].push_back(-109.43531311067846);
+    5799           4 :   parameter_vac_D[PRO].push_back(-10.592981104983805);
+    5800           4 :   parameter_vac_D[PRO].push_back(93.64863466237733);
+    5801           4 :   parameter_vac_D[PRO].push_back(-42.348197720920865);
+    5802           4 :   parameter_vac_D[PRO].push_back(3.5854078482704574);
+    5803             : 
+    5804           4 :   parameter_vac_D[GLN].push_back(136.91340111920806);
+    5805           4 :   parameter_vac_D[GLN].push_back(-0.7259026842220699);
+    5806           4 :   parameter_vac_D[GLN].push_back(-257.0347011897067);
+    5807           4 :   parameter_vac_D[GLN].push_back(-89.99600255417684);
+    5808           4 :   parameter_vac_D[GLN].push_back(570.3890595917421);
+    5809           4 :   parameter_vac_D[GLN].push_back(-438.8977029769549);
+    5810           4 :   parameter_vac_D[GLN].push_back(105.48846039376491);
+    5811             : 
+    5812           4 :   parameter_vac_D[SER].push_back(55.20490011583253);
+    5813           4 :   parameter_vac_D[SER].push_back(-0.038078030710377984);
+    5814           4 :   parameter_vac_D[SER].push_back(-58.79085960838952);
+    5815           4 :   parameter_vac_D[SER].push_back(-4.067364063406562);
+    5816           4 :   parameter_vac_D[SER].push_back(41.319899403658475);
+    5817           4 :   parameter_vac_D[SER].push_back(-15.865682241288962);
+    5818           4 :   parameter_vac_D[SER].push_back(0.5028409006168431);
+    5819             : 
+    5820           4 :   parameter_vac_D[THR].push_back(88.90604111920842);
+    5821           4 :   parameter_vac_D[THR].push_back(-0.11566717587697625);
+    5822           4 :   parameter_vac_D[THR].push_back(-114.4541243837681);
+    5823           4 :   parameter_vac_D[THR].push_back(-12.541537413808342);
+    5824           4 :   parameter_vac_D[THR].push_back(106.4974738790947);
+    5825           4 :   parameter_vac_D[THR].push_back(-50.15009912825225);
+    5826           4 :   parameter_vac_D[THR].push_back(4.719349514074467);
+    5827             : 
+    5828           4 :   parameter_vac_D[VAL].push_back(117.67910411920792);
+    5829           4 :   parameter_vac_D[VAL].push_back(-0.18187311248567883);
+    5830           4 :   parameter_vac_D[VAL].push_back(-162.8697844894754);
+    5831           4 :   parameter_vac_D[VAL].push_back(-19.769248288711825);
+    5832           4 :   parameter_vac_D[VAL].push_back(162.59270939168965);
+    5833           4 :   parameter_vac_D[VAL].push_back(-79.37261506441627);
+    5834           4 :   parameter_vac_D[VAL].push_back(8.230771959393175);
+    5835             : 
+    5836           4 :   parameter_vac_D[ALA].push_back(46.92250011448002);
+    5837           4 :   parameter_vac_D[ALA].push_back(-0.020339064649444412);
+    5838           4 :   parameter_vac_D[ALA].push_back(-44.41584945233503);
+    5839           4 :   parameter_vac_D[ALA].push_back(-2.1483754537886113);
+    5840           4 :   parameter_vac_D[ALA].push_back(25.713667829058785);
+    5841           4 :   parameter_vac_D[ALA].push_back(-8.222782061575268);
+    5842           4 :   parameter_vac_D[ALA].push_back(-0.2521732728817875);
+    5843             : 
+    5844           4 :   parameter_vac_D[GLY].push_back(23.532201119209795);
+    5845           4 :   parameter_vac_D[GLY].push_back(-0.00628609590047614);
+    5846           4 :   parameter_vac_D[GLY].push_back(-17.28421910139733);
+    5847           4 :   parameter_vac_D[GLY].push_back(-0.6641226821159686);
+    5848           4 :   parameter_vac_D[GLY].push_back(8.536119110048007);
+    5849           4 :   parameter_vac_D[GLY].push_back(-2.5438638688361466);
+    5850           4 :   parameter_vac_D[GLY].push_back(-0.11165675928832643);
+    5851             : 
+    5852           4 :   parameter_vac_D[HIS].push_back(145.41948111920982);
+    5853           4 :   parameter_vac_D[HIS].push_back(-0.8548328183368781);
+    5854           4 :   parameter_vac_D[HIS].push_back(-290.8653238004162);
+    5855           4 :   parameter_vac_D[HIS].push_back(-107.85375269366395);
+    5856           4 :   parameter_vac_D[HIS].push_back(685.7025818759361);
+    5857           4 :   parameter_vac_D[HIS].push_back(-538.2592043545858);
+    5858           4 :   parameter_vac_D[HIS].push_back(132.17357375729733);
+    5859             : 
+    5860             :   // NUCLEIC ACIDS
+    5861             : 
+    5862           4 :   parameter_mix_D[BB_PO2].push_back(80.12660011920252);
+    5863           4 :   parameter_mix_D[BB_PO2].push_back(-0.02788855519820236);
+    5864           4 :   parameter_mix_D[BB_PO2].push_back(-60.53219491822279);
+    5865           4 :   parameter_mix_D[BB_PO2].push_back(-2.9768829034096806);
+    5866           4 :   parameter_mix_D[BB_PO2].push_back(33.30645116638123);
+    5867           4 :   parameter_mix_D[BB_PO2].push_back(-11.601573219761375);
+    5868           4 :   parameter_mix_D[BB_PO2].push_back(0.12551046492022438);
+    5869             : 
+    5870           4 :   parameter_mix_D[BB_DNA].push_back(2835.3195201193003);
+    5871           4 :   parameter_mix_D[BB_DNA].push_back(-7.954301723608173);
+    5872           4 :   parameter_mix_D[BB_DNA].push_back(-4509.325563460958);
+    5873           4 :   parameter_mix_D[BB_DNA].push_back(-909.1870692311344);
+    5874           4 :   parameter_mix_D[BB_DNA].push_back(6375.156903893768);
+    5875           4 :   parameter_mix_D[BB_DNA].push_back(-3956.4787847570715);
+    5876           4 :   parameter_mix_D[BB_DNA].push_back(708.9872879613656);
+    5877             : 
+    5878           4 :   parameter_mix_D[BB_DNA_5].push_back(3136.73358011921);
+    5879           4 :   parameter_mix_D[BB_DNA_5].push_back(-10.023435855160427);
+    5880           4 :   parameter_mix_D[BB_DNA_5].push_back(-5208.921666368173);
+    5881           4 :   parameter_mix_D[BB_DNA_5].push_back(-1160.4403539440214);
+    5882           4 :   parameter_mix_D[BB_DNA_5].push_back(7962.598421448727);
+    5883           4 :   parameter_mix_D[BB_DNA_5].push_back(-5149.059857691847);
+    5884           4 :   parameter_mix_D[BB_DNA_5].push_back(984.5217027570121);
+    5885             : 
+    5886           4 :   parameter_mix_D[BB_DNA_3].push_back(3136.73358011921);
+    5887           4 :   parameter_mix_D[BB_DNA_3].push_back(-9.618834865806274);
+    5888           4 :   parameter_mix_D[BB_DNA_3].push_back(-5164.249220443828);
+    5889           4 :   parameter_mix_D[BB_DNA_3].push_back(-1103.2721475326382);
+    5890           4 :   parameter_mix_D[BB_DNA_3].push_back(7633.46089052312);
+    5891           4 :   parameter_mix_D[BB_DNA_3].push_back(-4826.171688395644);
+    5892           4 :   parameter_mix_D[BB_DNA_3].push_back(888.1820863683546);
+    5893             : 
+    5894           4 :   parameter_mix_D[BB_RNA].push_back(3192.5955601188807);
+    5895           4 :   parameter_mix_D[BB_RNA].push_back(-11.475781582628308);
+    5896           4 :   parameter_mix_D[BB_RNA].push_back(-5486.264576931735);
+    5897           4 :   parameter_mix_D[BB_RNA].push_back(-1344.2878288415961);
+    5898           4 :   parameter_mix_D[BB_RNA].push_back(9035.26109892441);
+    5899           4 :   parameter_mix_D[BB_RNA].push_back(-6068.471909763036);
+    5900           4 :   parameter_mix_D[BB_RNA].push_back(1226.3696076463866);
+    5901             : 
+    5902           4 :   parameter_mix_D[BB_RNA_5].push_back(3512.1630401192215);
+    5903           4 :   parameter_mix_D[BB_RNA_5].push_back(-14.191020069433975);
+    5904           4 :   parameter_mix_D[BB_RNA_5].push_back(-6293.687102187508);
+    5905           4 :   parameter_mix_D[BB_RNA_5].push_back(-1689.3688494490984);
+    5906           4 :   parameter_mix_D[BB_RNA_5].push_back(11193.448566821942);
+    5907           4 :   parameter_mix_D[BB_RNA_5].push_back(-7806.9064399949375);
+    5908           4 :   parameter_mix_D[BB_RNA_5].push_back(1662.4594983069844);
+    5909             : 
+    5910           4 :   parameter_mix_D[BB_RNA_3].push_back(3512.1630401192215);
+    5911           4 :   parameter_mix_D[BB_RNA_3].push_back(-12.978118135595812);
+    5912           4 :   parameter_mix_D[BB_RNA_3].push_back(-6149.290195451877);
+    5913           4 :   parameter_mix_D[BB_RNA_3].push_back(-1515.8309761505627);
+    5914           4 :   parameter_mix_D[BB_RNA_3].push_back(10176.605450440278);
+    5915           4 :   parameter_mix_D[BB_RNA_3].push_back(-6813.250569884159);
+    5916           4 :   parameter_mix_D[BB_RNA_3].push_back(1366.823518955858);
+    5917             : 
+    5918           4 :   parameter_mix_D[BASE_A].push_back(2464.736500119229);
+    5919           4 :   parameter_mix_D[BASE_A].push_back(-12.127452038444783);
+    5920           4 :   parameter_mix_D[BASE_A].push_back(-4710.661256689607);
+    5921           4 :   parameter_mix_D[BASE_A].push_back(-1462.6964141954452);
+    5922           4 :   parameter_mix_D[BASE_A].push_back(9451.725575888277);
+    5923           4 :   parameter_mix_D[BASE_A].push_back(-6883.018479948857);
+    5924           4 :   parameter_mix_D[BASE_A].push_back(1540.1526599737797);
+    5925             : 
+    5926           4 :   parameter_mix_D[BASE_C].push_back(1797.2697601191685);
+    5927           4 :   parameter_mix_D[BASE_C].push_back(-5.963855532295215);
+    5928           4 :   parameter_mix_D[BASE_C].push_back(-2955.077717756034);
+    5929           4 :   parameter_mix_D[BASE_C].push_back(-689.4543508746372);
+    5930           4 :   parameter_mix_D[BASE_C].push_back(4665.914740532565);
+    5931           4 :   parameter_mix_D[BASE_C].push_back(-3051.4605913706982);
+    5932           4 :   parameter_mix_D[BASE_C].push_back(590.2201952719585);
+    5933             : 
+    5934           4 :   parameter_mix_D[BASE_G].push_back(2804.271480119049);
+    5935           4 :   parameter_mix_D[BASE_G].push_back(-16.928072935469974);
+    5936           4 :   parameter_mix_D[BASE_G].push_back(-5989.82519987899);
+    5937           4 :   parameter_mix_D[BASE_G].push_back(-2275.490326521775);
+    5938           4 :   parameter_mix_D[BASE_G].push_back(15007.832401865428);
+    5939           4 :   parameter_mix_D[BASE_G].push_back(-12287.520690325606);
+    5940           4 :   parameter_mix_D[BASE_G].push_back(3172.98306575258);
+    5941             : 
+    5942           4 :   parameter_mix_D[BASE_T].push_back(2545.0860001192113);
+    5943           4 :   parameter_mix_D[BASE_T].push_back(-10.975141620541738);
+    5944           4 :   parameter_mix_D[BASE_T].push_back(-4636.058358764447);
+    5945           4 :   parameter_mix_D[BASE_T].push_back(-1340.3746388296138);
+    5946           4 :   parameter_mix_D[BASE_T].push_back(8850.604320505428);
+    5947           4 :   parameter_mix_D[BASE_T].push_back(-6421.852532013674);
+    5948           4 :   parameter_mix_D[BASE_T].push_back(1443.371517335904);
+    5949             : 
+    5950           4 :   parameter_mix_D[BASE_U].push_back(1608.7389001192062);
+    5951           4 :   parameter_mix_D[BASE_U].push_back(-3.9816849036181434);
+    5952           4 :   parameter_mix_D[BASE_U].push_back(-2411.056432130769);
+    5953           4 :   parameter_mix_D[BASE_U].push_back(-451.8236361945487);
+    5954           4 :   parameter_mix_D[BASE_U].push_back(3220.4418252803644);
+    5955           4 :   parameter_mix_D[BASE_U].push_back(-1944.2515577994325);
+    5956           4 :   parameter_mix_D[BASE_U].push_back(332.9259542628691);
+    5957             : 
+    5958           4 :   parameter_vac_D[BB_PO2].push_back(2.7889001116093284);
+    5959           4 :   parameter_vac_D[BB_PO2].push_back(-0.00011178884266113128);
+    5960           4 :   parameter_vac_D[BB_PO2].push_back(-1.1702605818380654);
+    5961           4 :   parameter_vac_D[BB_PO2].push_back(-0.011278044036819927);
+    5962           4 :   parameter_vac_D[BB_PO2].push_back(0.3214006584089024);
+    5963           4 :   parameter_vac_D[BB_PO2].push_back(-0.04097165983591666);
+    5964           4 :   parameter_vac_D[BB_PO2].push_back(-0.017525098100539684);
+    5965             : 
+    5966           4 :   parameter_vac_D[BB_DNA].push_back(94.75075611920529);
+    5967           4 :   parameter_vac_D[BB_DNA].push_back(-0.13973533952241124);
+    5968           4 :   parameter_vac_D[BB_DNA].push_back(-123.45402430039046);
+    5969           4 :   parameter_vac_D[BB_DNA].push_back(-15.19494522082691);
+    5970           4 :   parameter_vac_D[BB_DNA].push_back(123.34749914811465);
+    5971           4 :   parameter_vac_D[BB_DNA].push_back(-61.038507985345504);
+    5972           4 :   parameter_vac_D[BB_DNA].push_back(6.601587478585944);
+    5973             : 
+    5974           4 :   parameter_vac_D[BB_DNA_5].push_back(108.18080111920679);
+    5975           4 :   parameter_vac_D[BB_DNA_5].push_back(-0.2055953690887981);
+    5976           4 :   parameter_vac_D[BB_DNA_5].push_back(-150.7924892157235);
+    5977           4 :   parameter_vac_D[BB_DNA_5].push_back(-22.700459516383198);
+    5978           4 :   parameter_vac_D[BB_DNA_5].push_back(172.2599851655527);
+    5979           4 :   parameter_vac_D[BB_DNA_5].push_back(-93.4983124807692);
+    5980           4 :   parameter_vac_D[BB_DNA_5].push_back(12.867661230942868);
+    5981             : 
+    5982           4 :   parameter_vac_D[BB_DNA_3].push_back(108.18080111920537);
+    5983           4 :   parameter_vac_D[BB_DNA_3].push_back(-0.18263717534168372);
+    5984           4 :   parameter_vac_D[BB_DNA_3].push_back(-148.5918817744255);
+    5985           4 :   parameter_vac_D[BB_DNA_3].push_back(-19.90799847398835);
+    5986           4 :   parameter_vac_D[BB_DNA_3].push_back(157.55184203379557);
+    5987           4 :   parameter_vac_D[BB_DNA_3].push_back(-80.28471270058103);
+    5988           4 :   parameter_vac_D[BB_DNA_3].push_back(9.313712500298278);
+    5989             : 
+    5990           4 :   parameter_vac_D[BB_RNA].push_back(106.37859611922117);
+    5991           4 :   parameter_vac_D[BB_RNA].push_back(-0.2380766148121975);
+    5992           4 :   parameter_vac_D[BB_RNA].push_back(-153.74131338570024);
+    5993           4 :   parameter_vac_D[BB_RNA].push_back(-26.415436217574932);
+    5994           4 :   parameter_vac_D[BB_RNA].push_back(191.90585451112776);
+    5995           4 :   parameter_vac_D[BB_RNA].push_back(-109.61737794316868);
+    5996           4 :   parameter_vac_D[BB_RNA].push_back(16.663804191332204);
+    5997             : 
+    5998           4 :   parameter_vac_D[BB_RNA_5].push_back(120.58236111920618);
+    5999           4 :   parameter_vac_D[BB_RNA_5].push_back(-0.340258533619014);
+    6000           4 :   parameter_vac_D[BB_RNA_5].push_back(-186.08333929996334);
+    6001           4 :   parameter_vac_D[BB_RNA_5].push_back(-38.493337147644795);
+    6002           4 :   parameter_vac_D[BB_RNA_5].push_back(266.2262415641144);
+    6003           4 :   parameter_vac_D[BB_RNA_5].push_back(-164.73088478359585);
+    6004           4 :   parameter_vac_D[BB_RNA_5].push_back(29.07014157680879);
+    6005             : 
+    6006           4 :   parameter_vac_D[BB_RNA_3].push_back(120.5823611192099);
+    6007           4 :   parameter_vac_D[BB_RNA_3].push_back(-0.274146129206928);
+    6008           4 :   parameter_vac_D[BB_RNA_3].push_back(-179.24499182395388);
+    6009           4 :   parameter_vac_D[BB_RNA_3].push_back(-30.315729372259426);
+    6010           4 :   parameter_vac_D[BB_RNA_3].push_back(222.2645581367648);
+    6011           4 :   parameter_vac_D[BB_RNA_3].push_back(-125.13581171514033);
+    6012           4 :   parameter_vac_D[BB_RNA_3].push_back(18.350308154920107);
+    6013             : 
+    6014           4 :   parameter_vac_D[BASE_A].push_back(114.34024911921);
+    6015           4 :   parameter_vac_D[BASE_A].push_back(-0.4136665918383359);
+    6016           4 :   parameter_vac_D[BASE_A].push_back(-192.33138384655922);
+    6017           4 :   parameter_vac_D[BASE_A].push_back(-46.74428306691412);
+    6018           4 :   parameter_vac_D[BASE_A].push_back(312.9511030981905);
+    6019           4 :   parameter_vac_D[BASE_A].push_back(-199.6349962647333);
+    6020           4 :   parameter_vac_D[BASE_A].push_back(36.15938693202153);
+    6021             : 
+    6022           4 :   parameter_vac_D[BASE_C].push_back(76.17798411921166);
+    6023           4 :   parameter_vac_D[BASE_C].push_back(-0.1444475142707445);
+    6024           4 :   parameter_vac_D[BASE_C].push_back(-102.66873668949485);
+    6025           4 :   parameter_vac_D[BASE_C].push_back(-15.813768367725821);
+    6026           4 :   parameter_vac_D[BASE_C].push_back(119.63436338715553);
+    6027           4 :   parameter_vac_D[BASE_C].push_back(-64.22251971660583);
+    6028           4 :   parameter_vac_D[BASE_C].push_back(8.351952332828862);
+    6029             : 
+    6030           4 :   parameter_vac_D[BASE_G].push_back(127.08052911921965);
+    6031           4 :   parameter_vac_D[BASE_G].push_back(-0.7137457014712297);
+    6032           4 :   parameter_vac_D[BASE_G].push_back(-239.67686838772786);
+    6033           4 :   parameter_vac_D[BASE_G].push_back(-88.53661981200943);
+    6034           4 :   parameter_vac_D[BASE_G].push_back(556.7254485453866);
+    6035           4 :   parameter_vac_D[BASE_G].push_back(-432.0234649577737);
+    6036           4 :   parameter_vac_D[BASE_G].push_back(104.407200463848);
+    6037             : 
+    6038           4 :   parameter_vac_D[BASE_T].push_back(94.09000011920868);
+    6039           4 :   parameter_vac_D[BASE_T].push_back(-0.27147149980458524);
+    6040           4 :   parameter_vac_D[BASE_T].push_back(-143.65649702254174);
+    6041           4 :   parameter_vac_D[BASE_T].push_back(-30.861235738371892);
+    6042           4 :   parameter_vac_D[BASE_T].push_back(212.3643014774958);
+    6043           4 :   parameter_vac_D[BASE_T].push_back(-133.06675501066275);
+    6044           4 :   parameter_vac_D[BASE_T].push_back(23.951588200687073);
+    6045             : 
+    6046           4 :   parameter_vac_D[BASE_U].push_back(59.30540111665979);
+    6047           4 :   parameter_vac_D[BASE_U].push_back(-0.06146929846591808);
+    6048           4 :   parameter_vac_D[BASE_U].push_back(-67.43680950211682);
+    6049           4 :   parameter_vac_D[BASE_U].push_back(-6.625289749170134);
+    6050           4 :   parameter_vac_D[BASE_U].push_back(58.37012229348065);
+    6051           4 :   parameter_vac_D[BASE_U].push_back(-26.23044613101723);
+    6052           4 :   parameter_vac_D[BASE_U].push_back(2.061238351422343);
+    6053             : 
+    6054       14298 :   for(unsigned i=0; i<atoms.size(); ++i) {
+    6055       14294 :     std::string Aname = pdb.getAtomName(atoms[i]);
+    6056       14294 :     std::string Rname = pdb.getResidueName(atoms[i]);
+    6057       14294 :     Rname.erase(std::remove_if(Rname.begin(), Rname.end(), ::isspace),Rname.end());
+    6058       14294 :     if(Rname=="ALA") {
+    6059         732 :       atoi[residue_atom[i]]=ALA;
+    6060       13562 :     } else if(Rname=="ARG") {
+    6061         864 :       atoi[residue_atom[i]]=ARG;
+    6062       12698 :     } else if(Rname=="ASN") {
+    6063         720 :       atoi[residue_atom[i]]=ASN;
+    6064       11978 :     } else if(Rname=="ASP") {
+    6065         624 :       atoi[residue_atom[i]]=ASP;
+    6066       11354 :     } else if(Rname=="CYS") {
+    6067          48 :       atoi[residue_atom[i]]=CYS;
+    6068       11306 :     } else if(Rname=="GLN") {
+    6069        1064 :       atoi[residue_atom[i]]=GLN;
+    6070       10242 :     } else if(Rname=="GLU") {
+    6071         476 :       atoi[residue_atom[i]]=GLU;
+    6072        9766 :     } else if(Rname=="GLY") {
+    6073         648 :       atoi[residue_atom[i]]=GLY;
+    6074        9118 :     } else if(Rname=="HIS") {
+    6075           0 :       atoi[residue_atom[i]]=HIS;
+    6076        9118 :     } else if(Rname=="HID") {
+    6077           0 :       atoi[residue_atom[i]]=HIS;
+    6078        9118 :     } else if(Rname=="HIE") {
+    6079         144 :       atoi[residue_atom[i]]=HIS;
+    6080        8974 :     } else if(Rname=="HIP") {
+    6081           0 :       atoi[residue_atom[i]]=HIP;
+    6082             :       // CHARMM NAMING FOR PROTONATION STATES OF HISTIDINE
+    6083        8974 :     } else if(Rname=="HSD") {
+    6084           0 :       atoi[residue_atom[i]]=HIS;
+    6085        8974 :     } else if(Rname=="HSE") {
+    6086           0 :       atoi[residue_atom[i]]=HIS;
+    6087        8974 :     } else if(Rname=="HSP") {
+    6088           0 :       atoi[residue_atom[i]]=HIP;
+    6089        8974 :     } else if(Rname=="ILE") {
+    6090         864 :       atoi[residue_atom[i]]=ILE;
+    6091        8110 :     } else if(Rname=="LEU") {
+    6092        1520 :       atoi[residue_atom[i]]=LEU;
+    6093        6590 :     } else if(Rname=="LYS") {
+    6094        1040 :       atoi[residue_atom[i]]=LYS;
+    6095        5550 :     } else if(Rname=="MET") {
+    6096         608 :       atoi[residue_atom[i]]=MET;
+    6097        4942 :     } else if(Rname=="PHE") {
+    6098        1008 :       atoi[residue_atom[i]]=PHE;
+    6099        3934 :     } else if(Rname=="PRO") {
+    6100         748 :       atoi[residue_atom[i]]=PRO;
+    6101        3186 :     } else if(Rname=="SER") {
+    6102         528 :       atoi[residue_atom[i]]=SER;
+    6103        2658 :     } else if(Rname=="THR") {
+    6104         504 :       atoi[residue_atom[i]]=THR;
+    6105        2154 :     } else if(Rname=="TRP") {
+    6106           0 :       atoi[residue_atom[i]]=TRP;
+    6107        2154 :     } else if(Rname=="TYR") {
+    6108         528 :       atoi[residue_atom[i]]=TYR;
+    6109        1626 :     } else if(Rname=="VAL") {
+    6110        1088 :       atoi[residue_atom[i]]=VAL;
+    6111             :     }
+    6112             :     // NUCLEIC ACIDS
+    6113             :     // nucleobases are not automatically populated as an additional check on the health of the PDB.
+    6114             :     // RNA - G
+    6115         538 :     else if(Rname=="G") {
+    6116           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6117           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6118           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6119           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6120           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6121           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6122           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6123           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6124           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6125           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6126           0 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6127           0 :                  Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6128           0 :                  Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6129           0 :                  Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6130           0 :         atoi[residue_atom[i]]=BASE_G;
+    6131           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6132             :       // RNA - G3
+    6133         538 :     } else if(Rname=="G3") {
+    6134           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6135           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6136           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6137           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6138           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6139           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6140           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6141           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6142           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6143           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6144           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6145           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6146           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6147           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6148           0 :         atoi[residue_atom[i]]=BASE_G;
+    6149           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6150             :       // RNA - G5
+    6151         538 :     } else if(Rname=="G5") {
+    6152           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6153           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6154           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6155           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6156           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6157           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6158           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6159           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6160           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6161           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6162           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6163           0 :         atoi[residue_atom[i]]=BASE_G;
+    6164           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6165             :       // RNA - U
+    6166         538 :     } else if(Rname=="U") {
+    6167        1554 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6168        1176 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6169          42 :         atoi [residue_atom[i]]=BB_PO2;
+    6170        1372 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6171        1148 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6172         924 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6173         714 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6174         644 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6175         840 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6176         224 :         atoi[residue_atom[i]]=BB_RNA;
+    6177         476 :       } else if( Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    6178         252 :                  Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    6179         196 :                  Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    6180         154 :         atoi[residue_atom[i]]=BASE_U;
+    6181           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6182             :       // RNA - U3
+    6183         118 :     } else if(Rname=="U3") {
+    6184         230 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6185         174 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6186           6 :         atoi [residue_atom[i]]=BB_PO2;
+    6187         204 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6188         172 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6189         140 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6190         110 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6191          94 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6192          78 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6193          34 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6194          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    6195          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    6196          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    6197          22 :         atoi[residue_atom[i]]=BASE_U;
+    6198           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6199             :       // RNA - U5
+    6200          56 :     } else if(Rname=="U5") {
+    6201         204 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6202         172 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6203         140 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6204         108 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6205          88 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6206          78 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6207          34 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6208          68 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="O2" || Aname=="N3" ||
+    6209          36 :                 Aname=="C4" || Aname=="O4"  || Aname=="C5" || Aname=="C6" ||
+    6210          28 :                 Aname=="H3" || Aname=="H5"  || Aname=="H6") {
+    6211          22 :         atoi[residue_atom[i]]=BASE_U;
+    6212           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6213             :       // RNA - A
+    6214           0 :     } else if(Rname=="A") {
+    6215           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6216           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6217           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6218           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6219           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6220           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6221           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6222           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6223           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6224           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6225           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6226           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6227           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6228           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6229           0 :         atoi[residue_atom[i]]=BASE_A;
+    6230           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6231             :       // RNA - A3
+    6232           0 :     } else if(Rname=="A3") {
+    6233           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6234           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6235           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6236           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6237           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6238           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6239           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6240           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6241           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6242           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6243           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6244           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6245           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6246           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6247           0 :         atoi[residue_atom[i]]=BASE_A;
+    6248           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6249             :       // RNA - A5
+    6250           0 :     } else if(Rname=="A5") {
+    6251           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6252           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6253           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6254           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6255           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6256           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6257           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6258           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6259           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6260           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6261           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6262           0 :         atoi[residue_atom[i]]=BASE_A;
+    6263           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6264             :       // RNA - C
+    6265           0 :     } else if(Rname=="C") {
+    6266           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6267           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6268           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6269           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6270           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6271           0 :                 Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6272           0 :                 Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="H3T"  ||
+    6273           0 :                 Aname=="HO5'" || Aname=="HO3'" || Aname=="HO2'" || Aname=="H5'1" ||
+    6274           0 :                 Aname=="H5'2" || Aname=="HO'2" || Aname=="H2'1" || Aname=="H5T" ) {
+    6275           0 :         atoi[residue_atom[i]]=BB_RNA;
+    6276           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6277           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6278           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6279           0 :         atoi[residue_atom[i]]=BASE_C;
+    6280           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6281             :       // RNA - C3
+    6282           0 :     } else if(Rname=="C3") {
+    6283           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6284           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6285           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6286           0 :       } else if(Aname=="O5'"  || Aname=="C5'" || Aname=="O4'"  || Aname=="C4'"  ||
+    6287           0 :                 Aname=="O3'"  || Aname=="C3'" || Aname=="O2'"  || Aname=="C2'"  ||
+    6288           0 :                 Aname=="C1'"  || Aname=="H5'" || Aname=="H5''" || Aname=="H4'"  ||
+    6289           0 :                 Aname=="H3'"  || Aname=="H2'" || Aname=="H1'"  || Aname=="H3T"  ||
+    6290           0 :                 Aname=="H2'1" || Aname=="HO3'"|| Aname=="HO2'" || Aname=="H5'1" ||
+    6291           0 :                 Aname=="H5'2" || Aname=="HO'2" ) {
+    6292           0 :         atoi[residue_atom[i]]=BB_RNA_3;
+    6293           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6294           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6295           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6296           0 :         atoi[residue_atom[i]]=BASE_C;
+    6297           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6298             :       // RNA - C5
+    6299           0 :     } else if(Rname=="C5") {
+    6300           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6301           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="O2'"  || Aname=="C2'"  ||
+    6302           0 :           Aname=="C1'"  || Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  ||
+    6303           0 :           Aname=="H3'"  || Aname=="H2'"  || Aname=="H1'"  || Aname=="HO5'" ||
+    6304           0 :           Aname=="HO2'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="HO'2" ||
+    6305           0 :           Aname=="H2'1" || Aname=="H5T" ) {
+    6306           0 :         atoi[residue_atom[i]]=BB_RNA_5;
+    6307           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6308           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6309           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6310           0 :         atoi[residue_atom[i]]=BASE_C;
+    6311           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6312             :       // DNA - G
+    6313           0 :     } else if(Rname=="DG") {
+    6314           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6315           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6316           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6317           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6318           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6319           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6320           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6321           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6322           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6323           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6324           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6325           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6326           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6327           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6328           0 :         atoi[residue_atom[i]]=BASE_G;
+    6329           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6330             :       // DNA - G3
+    6331           0 :     } else if(Rname=="DG3") {
+    6332           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6333           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6334           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6335           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6336           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6337           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6338           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6339           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6340             :                 Aname=="H3T" ) {
+    6341           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6342           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6343           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6344           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6345           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6346           0 :         atoi[residue_atom[i]]=BASE_G;
+    6347           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6348             :       // DNA - G5
+    6349           0 :     } else if(Rname=="DG5") {
+    6350           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6351           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6352           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6353           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6354           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6355             :           Aname=="H5T" ) {
+    6356           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6357           0 :       } else if(Aname=="N1" || Aname=="C2"  || Aname=="N2" || Aname=="N3" ||
+    6358           0 :                 Aname=="C4" || Aname=="C5"  || Aname=="C6" || Aname=="O6" ||
+    6359           0 :                 Aname=="N7" || Aname=="C8"  || Aname=="N9" || Aname=="H1" ||
+    6360           0 :                 Aname=="H8" || Aname=="H21" || Aname=="H22" ) {
+    6361           0 :         atoi[residue_atom[i]]=BASE_G;
+    6362           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6363             :       // DNA - T
+    6364           0 :     } else if(Rname=="DT") {
+    6365           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6366           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6367           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6368           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6369           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6370           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6371           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6372           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6373           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6374           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6375           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6376           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6377           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6378           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6379           0 :         atoi[residue_atom[i]]=BASE_T;
+    6380           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6381             :       // DNA - T3
+    6382           0 :     } else if(Rname=="DT3") {
+    6383           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6384           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6385           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6386           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6387           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6388           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6389           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6390           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6391             :                 Aname=="H3T" ) {
+    6392           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6393           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6394           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6395           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6396           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6397           0 :         atoi[residue_atom[i]]=BASE_T;
+    6398           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6399             :       // DNA - T5
+    6400           0 :     } else if(Rname=="DT5") {
+    6401           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6402           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6403           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6404           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6405           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6406             :           Aname=="H5T" ) {
+    6407           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6408           0 :       } else if(Aname=="N1"  || Aname=="C2"  || Aname=="O2"  || Aname=="N3"  ||
+    6409           0 :                 Aname=="C4"  || Aname=="O4"  || Aname=="C5"  || Aname=="C6"  ||
+    6410           0 :                 Aname=="C7"  || Aname=="H3"  || Aname=="H6"  || Aname=="H71" ||
+    6411           0 :                 Aname=="H72" || Aname=="H73" ) {
+    6412           0 :         atoi[residue_atom[i]]=BASE_T;
+    6413           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6414             :       // DNA - A
+    6415           0 :     } else if(Rname=="DA") {
+    6416           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6417           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6418           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6419           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6420           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6421           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6422           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6423           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6424           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6425           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6426           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6427           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6428           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6429           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6430           0 :         atoi[residue_atom[i]]=BASE_A;
+    6431           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6432             :       // DNA - A3
+    6433           0 :     } else if(Rname=="DA3") {
+    6434           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6435           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6436           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6437           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6438           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6439           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6440           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6441           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6442             :                 Aname=="H3T" ) {
+    6443           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6444           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6445           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6446           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6447           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6448           0 :         atoi[residue_atom[i]]=BASE_A;
+    6449           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6450             :       // DNA - A5
+    6451           0 :     } else if(Rname=="DA5") {
+    6452           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6453           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6454           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6455           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6456           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6457             :           Aname=="H5T" ) {
+    6458           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6459           0 :       } else if(Aname=="N1"  || Aname=="C2" || Aname=="N3" || Aname=="C4" ||
+    6460           0 :                 Aname=="C5"  || Aname=="C6" || Aname=="N6" || Aname=="N7" ||
+    6461           0 :                 Aname=="C8"  || Aname=="N9" || Aname=="H2" || Aname=="H8" ||
+    6462           0 :                 Aname=="H61" || Aname=="H62" ) {
+    6463           0 :         atoi[residue_atom[i]]=BASE_A;
+    6464           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6465             :       // DNA - C
+    6466           0 :     } else if(Rname=="DC") {
+    6467           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6468           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6469           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6470           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6471           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6472           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6473           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6474           0 :                 Aname=="HO3'" || Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" ||
+    6475           0 :                 Aname=="H2'2" || Aname=="H5T"  || Aname=="H3T" ) {
+    6476           0 :         atoi[residue_atom[i]]=BB_DNA;
+    6477           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6478           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6479           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6480           0 :         atoi[residue_atom[i]]=BASE_C;
+    6481           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6482             :       // DNA - C3
+    6483           0 :     } else if(Rname=="DC3") {
+    6484           0 :       if( Aname=="P"   || Aname=="OP1" || Aname=="OP2" || Aname=="OP3" ||
+    6485           0 :           Aname=="O1P" || Aname=="O2P" || Aname=="O3P" ) {
+    6486           0 :         atoi [residue_atom[i]]=BB_PO2;
+    6487           0 :       } else if(Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6488           0 :                 Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  || Aname=="C1'"  ||
+    6489           0 :                 Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6490           0 :                 Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO3'" ||
+    6491           0 :                 Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6492             :                 Aname=="H3T" ) {
+    6493           0 :         atoi[residue_atom[i]]=BB_DNA_3;
+    6494           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6495           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6496           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6497           0 :         atoi[residue_atom[i]]=BASE_C;
+    6498           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6499             :       // DNA - C5
+    6500           0 :     } else if(Rname=="DC5") {
+    6501           0 :       if( Aname=="O5'"  || Aname=="C5'"  || Aname=="O4'"  || Aname=="C4'"  ||
+    6502           0 :           Aname=="O3'"  || Aname=="C3'"  || Aname=="C2'"  ||  Aname=="C1'" ||
+    6503           0 :           Aname=="H5'"  || Aname=="H5''" || Aname=="H4'"  || Aname=="H3'"  ||
+    6504           0 :           Aname=="H2'"  || Aname=="H2''" || Aname=="H1'"  || Aname=="HO5'" ||
+    6505           0 :           Aname=="H5'1" || Aname=="H5'2" || Aname=="H2'1" || Aname=="H2'2" ||
+    6506             :           Aname=="H5T" ) {
+    6507           0 :         atoi[residue_atom[i]]=BB_DNA_5;
+    6508           0 :       } else if(Aname=="N1" || Aname=="C2" || Aname=="O2"  || Aname=="N3" ||
+    6509           0 :                 Aname=="C4" || Aname=="N4" || Aname=="C5"  || Aname=="C6" ||
+    6510           0 :                 Aname=="H5" || Aname=="H6" || Aname=="H41" || Aname=="H42" ) {
+    6511           0 :         atoi[residue_atom[i]]=BASE_C;
+    6512           0 :       } else error("Atom name "+Aname+" is not defined for residue "+Rname+". Check the PDB.");
+    6513           0 :     } else error("Residue not known: "+Rname);
+    6514             :   }
+    6515           4 : }
+    6516             : 
+    6517           4 : double SAXS::calculateAFF(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double rho)
+    6518             : {
+    6519             :   std::map<std::string, unsigned> AA_map;
+    6520           4 :   AA_map["H"] = H;
+    6521           4 :   AA_map["C"] = C;
+    6522           4 :   AA_map["N"] = N;
+    6523           4 :   AA_map["O"] = O;
+    6524           4 :   AA_map["P"] = P;
+    6525           4 :   AA_map["S"] = S;
+    6526             : 
+    6527             :   std::vector<std::vector<double> > param_a;
+    6528             :   std::vector<std::vector<double> > param_b;
+    6529             :   std::vector<double> param_c;
+    6530             :   std::vector<double> param_v;
+    6531             : 
+    6532           4 :   param_a.resize(NTT, std::vector<double>(5));
+    6533           4 :   param_b.resize(NTT, std::vector<double>(5));
+    6534           4 :   param_c.resize(NTT);
+    6535           4 :   param_v.resize(NTT);
+    6536             : 
+    6537           4 :   param_a[H][0] = 0.493002; param_b[H][0] = 10.5109; param_c[H] = 0.003038;
+    6538           4 :   param_a[H][1] = 0.322912; param_b[H][1] = 26.1257; param_v[H] = 5.15;
+    6539           4 :   param_a[H][2] = 0.140191; param_b[H][2] = 3.14236;
+    6540           4 :   param_a[H][3] = 0.040810; param_b[H][3] = 57.7997;
+    6541           4 :   param_a[H][4] = 0.0;      param_b[H][4] = 1.0;
+    6542             : 
+    6543           4 :   param_a[C][0] = 2.31000; param_b[C][0] = 20.8439; param_c[C] = 0.215600;
+    6544           4 :   param_a[C][1] = 1.02000; param_b[C][1] = 10.2075; param_v[C] = 16.44;
+    6545           4 :   param_a[C][2] = 1.58860; param_b[C][2] = 0.56870;
+    6546           4 :   param_a[C][3] = 0.86500; param_b[C][3] = 51.6512;
+    6547           4 :   param_a[C][4] = 0.0;     param_b[C][4] = 1.0;
+    6548             : 
+    6549           4 :   param_a[N][0] = 12.2126; param_b[N][0] = 0.00570; param_c[N] = -11.529;
+    6550           4 :   param_a[N][1] = 3.13220; param_b[N][1] = 9.89330; param_v[N] = 2.49;
+    6551           4 :   param_a[N][2] = 2.01250; param_b[N][2] = 28.9975;
+    6552           4 :   param_a[N][3] = 1.16630; param_b[N][3] = 0.58260;
+    6553           4 :   param_a[N][4] = 0.0;     param_b[N][4] = 1.0;
+    6554             : 
+    6555           4 :   param_a[O][0] = 3.04850; param_b[O][0] = 13.2771; param_c[O] = 0.250800 ;
+    6556           4 :   param_a[O][1] = 2.28680; param_b[O][1] = 5.70110; param_v[O] = 9.13;
+    6557           4 :   param_a[O][2] = 1.54630; param_b[O][2] = 0.32390;
+    6558           4 :   param_a[O][3] = 0.86700; param_b[O][3] = 32.9089;
+    6559           4 :   param_a[O][4] = 0.0;     param_b[O][4] = 1.0;
+    6560             : 
+    6561           4 :   param_a[P][0] = 6.43450; param_b[P][0] = 1.90670; param_c[P] = 1.11490;
+    6562           4 :   param_a[P][1] = 4.17910; param_b[P][1] = 27.1570; param_v[P] = 5.73;
+    6563           4 :   param_a[P][2] = 1.78000; param_b[P][2] = 0.52600;
+    6564           4 :   param_a[P][3] = 1.49080; param_b[P][3] = 68.1645;
+    6565           4 :   param_a[P][4] = 0.0;     param_b[P][4] = 1.0;
+    6566             : 
+    6567           4 :   param_a[S][0] = 6.90530; param_b[S][0] = 1.46790; param_c[S] = 0.866900;
+    6568           4 :   param_a[S][1] = 5.20340; param_b[S][1] = 22.2151; param_v[S] = 19.86;
+    6569           4 :   param_a[S][2] = 1.43790; param_b[S][2] = 0.25360;
+    6570           4 :   param_a[S][3] = 1.58630; param_b[S][3] = 56.1720;
+    6571           4 :   param_a[S][4] = 0.0;     param_b[S][4] = 1.0;
+    6572             : 
+    6573           4 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    6574             : 
+    6575             :   double Iq0=0.;
+    6576           4 :   if( moldat ) {
+    6577             :     // cycle over the atom types
+    6578          28 :     for(unsigned i=0; i<NTT; ++i) {
+    6579          24 :       const double volr = std::pow(param_v[i], (2.0/3.0)) /(4. * M_PI);
+    6580             :       // cycle over q
+    6581         240 :       for(unsigned k=0; k<q_list.size(); ++k) {
+    6582         216 :         const double q = q_list[k];
+    6583         216 :         const double s = q / (4. * M_PI);
+    6584         216 :         FF_tmp[k][i] = param_c[i];
+    6585             :         // SUM [a_i * EXP( - b_i * (q/4pi)^2 )] Waasmaier and Kirfel (1995)
+    6586        1080 :         for(unsigned j=0; j<4; ++j) {
+    6587         864 :           FF_tmp[k][i] += param_a[i][j]*std::exp(-param_b[i][j]*s*s);
+    6588             :         }
+    6589             :         // subtract solvation: rho * v_i * EXP( (- v_i^(2/3) / (4pi)) * q^2  ) // since  D in Fraser 1978 is 2*s
+    6590         216 :         FF_tmp[k][i] -= rho*param_v[i]*std::exp(-volr*q*q);
+    6591             :       }
+    6592             :     }
+    6593             :     // cycle over the atoms to assign the atom type and calculate I0
+    6594       14298 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    6595             :       // get atom name
+    6596       14294 :       std::string name = moldat->getAtomName(atoms[i]);
+    6597             :       char type;
+    6598             :       // get atom type
+    6599       14294 :       char first = name.at(0);
+    6600             :       // GOLDEN RULE: type is first letter, if not a number
+    6601       14294 :       if (!isdigit(first)) {
+    6602             :         type = first;
+    6603             :         // otherwise is the second
+    6604             :       } else {
+    6605           0 :         type = name.at(1);
+    6606             :       }
+    6607       14294 :       std::string type_s = std::string(1,type);
+    6608       14294 :       if(AA_map.find(type_s) != AA_map.end()) {
+    6609       14294 :         const unsigned index=AA_map[type_s];
+    6610       14294 :         atoi[i] = AA_map[type_s];
+    6611       71470 :         for(unsigned j=0; j<4; ++j) Iq0 += param_a[index][j];
+    6612       14294 :         Iq0 = Iq0 -rho*param_v[index] + param_c[index];
+    6613             :       } else {
+    6614           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    6615             :       }
+    6616             :     }
+    6617             :   } else {
+    6618           0 :     error("MOLINFO DATA not found\n");
+    6619             :   }
+    6620           4 :   if(absolute) Iq0 = 1;
+    6621             : 
+    6622           4 :   return Iq0;
+    6623           4 : }
+    6624             : 
+    6625           2 : double SAXS::calculateAFFsans(const std::vector<AtomNumber> &atoms, std::vector<std::vector<long double> > &FF_tmp, const double deuter_conc)
+    6626             : {
+    6627             :   std::map<std::string, unsigned> AA_map;
+    6628           2 :   AA_map["H"] = H;
+    6629           2 :   AA_map["C"] = C;
+    6630           2 :   AA_map["N"] = N;
+    6631           2 :   AA_map["O"] = O;
+    6632           2 :   AA_map["P"] = P;
+    6633           2 :   AA_map["S"] = S;
+    6634             : 
+    6635             :   std::vector<double> param_b;
+    6636             :   std::vector<double> param_v;
+    6637             : 
+    6638           2 :   param_b.resize(NTT);
+    6639           2 :   param_v.resize(NTT);
+    6640             : 
+    6641           2 :   param_b[H] = -0.374; param_v[H] = 5.15;
+    6642             :   // param_b[D] = 0.667;
+    6643           2 :   param_b[C] =  0.665;  param_v[C] = 16.44;
+    6644           2 :   param_b[N] =  0.94;   param_v[N] = 2.49;
+    6645           2 :   param_b[O] =  0.580;  param_v[O] = 9.13;
+    6646           2 :   param_b[P] =  0.51;   param_v[P] = 5.73;
+    6647           2 :   param_b[S] =  0.28;   param_v[S] = 19.86;
+    6648             : 
+    6649           2 :   double solv_sc_length = 0.1*(param_b[O] + 2.*((1. - deuter_conc) * param_b[H] + deuter_conc * 0.667)); // per water electron (10 electrons)
+    6650             : 
+    6651           2 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+    6652             : 
+    6653             :   double Iq0=0.;
+    6654           2 :   if( moldat ) {
+    6655             :     // cycle over the atom types
+    6656          14 :     for(unsigned i=0; i<NTT; ++i) {
+    6657          12 :       double volr = std::pow(param_v[i], (2.0/3.0)) /(4. * M_PI);
+    6658             :       // cycle over q
+    6659         120 :       for(unsigned k=0; k<q_list.size(); ++k) {
+    6660         108 :         const double q = q_list[k];
+    6661         108 :         FF_tmp[k][i] = param_b[i];
+    6662             :         // subtract solvation: rho * v_i * EXP( (- v_i^(2/3) / (4pi)) * q^2  ) // since  D in Fraser 1978 is 2*s
+    6663         108 :         FF_tmp[k][i] -= solv_sc_length*rho*param_v[i]*std::exp(-volr*q*q);
+    6664             :       }
+    6665             :     }
+    6666             :     // cycle over the atoms to assign the atom type and calculate I0
+    6667        6880 :     for(unsigned i=0; i<atoms.size(); ++i) {
+    6668             :       // get atom name
+    6669        6878 :       std::string name = moldat->getAtomName(atoms[i]);
+    6670             :       char type;
+    6671             :       // get atom type
+    6672        6878 :       char first = name.at(0);
+    6673             :       // GOLDEN RULE: type is first letter, if not a number
+    6674        6878 :       if (!isdigit(first)) {
+    6675             :         type = first;
+    6676             :         // otherwise is the second
+    6677             :       } else {
+    6678           0 :         type = name.at(1);
+    6679             :       }
+    6680        6878 :       std::string type_s = std::string(1,type);
+    6681        6878 :       if(AA_map.find(type_s) != AA_map.end()) {
+    6682        6878 :         const unsigned index=AA_map[type_s];
+    6683        6878 :         atoi[i] = AA_map[type_s];
+    6684        6878 :         Iq0 += param_b[index]-solv_sc_length*rho*param_v[index];
+    6685             :       } else {
+    6686           0 :         error("Wrong atom type "+type_s+" from atom name "+name+"\n");
+    6687             :       }
+    6688             :     }
+    6689             :   } else {
+    6690           0 :     error("MOLINFO DATA not found\n");
+    6691             :   }
+    6692           2 :   if(absolute) Iq0 = 1;
+    6693             : 
+    6694           2 :   return Iq0;
+    6695             : }
+    6696             : 
+    6697          10 : std::map<std::string, std::vector<double> > SAXS::setupLCPOparam() {
+    6698             :   std::map<std::string, std::vector<double> > lcpomap;
+    6699             : 
+    6700             :   // We arbitrarily set OC1/OT1 as the charged oxygen.
+    6701             : 
+    6702          10 :   lcpomap["ALA_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6703          10 :   lcpomap["ALA_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6704          10 :   lcpomap["ALA_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6705          10 :   lcpomap["ALA_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6706          10 :   lcpomap["ALA_CB"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6707          10 :   lcpomap["ALA_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6708          10 :   lcpomap["ALA_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6709          10 :   lcpomap["ALA_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6710          10 :   lcpomap["ALA_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6711          10 :   lcpomap["ALA_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6712             : 
+    6713          10 :   lcpomap["ASP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6714          10 :   lcpomap["ASP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6715          10 :   lcpomap["ASP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6716          10 :   lcpomap["ASP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6717          10 :   lcpomap["ASP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6718          10 :   lcpomap["ASP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6719          10 :   lcpomap["ASP_OD1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6720          10 :   lcpomap["ASP_OD2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6721          10 :   lcpomap["ASP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6722          10 :   lcpomap["ASP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6723          10 :   lcpomap["ASP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6724          10 :   lcpomap["ASP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6725          10 :   lcpomap["ASP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6726             : 
+    6727          10 :   lcpomap["ASN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6728          10 :   lcpomap["ASN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6729          10 :   lcpomap["ASN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6730          10 :   lcpomap["ASN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6731          10 :   lcpomap["ASN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6732          10 :   lcpomap["ASN_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6733          10 :   lcpomap["ASN_OD1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6734          10 :   lcpomap["ASN_ND2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6735          10 :   lcpomap["ASN_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6736          10 :   lcpomap["ASN_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6737          10 :   lcpomap["ASN_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6738          10 :   lcpomap["ASN_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6739          10 :   lcpomap["ASN_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6740             : 
+    6741          10 :   lcpomap["ARG_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6742          10 :   lcpomap["ARG_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6743          10 :   lcpomap["ARG_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6744          10 :   lcpomap["ARG_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6745          10 :   lcpomap["ARG_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6746          10 :   lcpomap["ARG_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6747          10 :   lcpomap["ARG_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6748          10 :   lcpomap["ARG_NE"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6749          10 :   lcpomap["ARG_NH1"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6750          10 :   lcpomap["ARG_NH2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6751          10 :   lcpomap["ARG_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6752          10 :   lcpomap["ARG_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6753          10 :   lcpomap["ARG_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6754          10 :   lcpomap["ARG_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6755          10 :   lcpomap["ARG_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6756          10 :   lcpomap["ARG_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6757             : 
+    6758          10 :   lcpomap["CYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6759          10 :   lcpomap["CYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6760          10 :   lcpomap["CYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6761          10 :   lcpomap["CYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6762          10 :   lcpomap["CYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6763          10 :   lcpomap["CYS_SG"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+    6764          10 :   lcpomap["CYS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6765          10 :   lcpomap["CYS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6766          10 :   lcpomap["CYS_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6767          10 :   lcpomap["CYS_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6768          10 :   lcpomap["CYS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6769             : 
+    6770          10 :   lcpomap["GLU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6771          10 :   lcpomap["GLU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6772          10 :   lcpomap["GLU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6773          10 :   lcpomap["GLU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6774          10 :   lcpomap["GLU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6775          10 :   lcpomap["GLU_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6776          10 :   lcpomap["GLU_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6777          10 :   lcpomap["GLU_OE1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6778          10 :   lcpomap["GLU_OE2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    6779          10 :   lcpomap["GLU_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6780          10 :   lcpomap["GLU_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6781          10 :   lcpomap["GLU_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6782          10 :   lcpomap["GLU_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6783          10 :   lcpomap["GLU_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6784             : 
+    6785          10 :   lcpomap["GLN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6786          10 :   lcpomap["GLN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6787          10 :   lcpomap["GLN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6788          10 :   lcpomap["GLN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6789          10 :   lcpomap["GLN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6790          10 :   lcpomap["GLN_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6791          10 :   lcpomap["GLN_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6792          10 :   lcpomap["GLN_OE1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6793          10 :   lcpomap["GLN_NE2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6794          10 :   lcpomap["GLN_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6795          10 :   lcpomap["GLN_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6796          10 :   lcpomap["GLN_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6797          10 :   lcpomap["GLN_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6798          10 :   lcpomap["GLN_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6799             : 
+    6800          10 :   lcpomap["GLY_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6801          10 :   lcpomap["GLY_CA"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6802          10 :   lcpomap["GLY_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6803          10 :   lcpomap["GLY_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6804          10 :   lcpomap["GLY_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6805          10 :   lcpomap["GLY_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6806          10 :   lcpomap["GLY_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6807          10 :   lcpomap["GLY_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6808          10 :   lcpomap["GLY_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6809             : 
+    6810          10 :   lcpomap["HIS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6811          10 :   lcpomap["HIS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6812          10 :   lcpomap["HIS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6813          10 :   lcpomap["HIS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6814          10 :   lcpomap["HIS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6815          10 :   lcpomap["HIS_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6816          10 :   lcpomap["HIS_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6817          10 :   lcpomap["HIS_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6818          10 :   lcpomap["HIS_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6819          10 :   lcpomap["HIS_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6820          10 :   lcpomap["HIS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6821          10 :   lcpomap["HIS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6822          10 :   lcpomap["HIS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6823             : 
+    6824          10 :   lcpomap["HIE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6825          10 :   lcpomap["HIE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6826          10 :   lcpomap["HIE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6827          10 :   lcpomap["HIE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6828          10 :   lcpomap["HIE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6829          10 :   lcpomap["HIE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6830          10 :   lcpomap["HIE_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6831          10 :   lcpomap["HIE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6832          10 :   lcpomap["HIE_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6833          10 :   lcpomap["HIE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6834          10 :   lcpomap["HIE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6835          10 :   lcpomap["HIE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6836          10 :   lcpomap["HIE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6837             : 
+    6838          10 :   lcpomap["HSE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6839          10 :   lcpomap["HSE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6840          10 :   lcpomap["HSE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6841          10 :   lcpomap["HSE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6842          10 :   lcpomap["HSE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6843          10 :   lcpomap["HSE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6844          10 :   lcpomap["HSE_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6845          10 :   lcpomap["HSE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6846          10 :   lcpomap["HSE_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6847          10 :   lcpomap["HSE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6848          10 :   lcpomap["HSE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6849          10 :   lcpomap["HSE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6850          10 :   lcpomap["HSE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6851             : 
+    6852          10 :   lcpomap["HID_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6853          10 :   lcpomap["HID_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6854          10 :   lcpomap["HID_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6855          10 :   lcpomap["HID_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6856          10 :   lcpomap["HID_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6857          10 :   lcpomap["HID_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6858          10 :   lcpomap["HID_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6859          10 :   lcpomap["HID_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6860          10 :   lcpomap["HID_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6861          10 :   lcpomap["HID_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6862          10 :   lcpomap["HID_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6863          10 :   lcpomap["HID_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6864          10 :   lcpomap["HID_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6865             : 
+    6866          10 :   lcpomap["HSD_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6867          10 :   lcpomap["HSD_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6868          10 :   lcpomap["HSD_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6869          10 :   lcpomap["HSD_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6870          10 :   lcpomap["HSD_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6871          10 :   lcpomap["HSD_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6872          10 :   lcpomap["HSD_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6873          10 :   lcpomap["HSD_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6874          10 :   lcpomap["HSD_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6875          10 :   lcpomap["HSD_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6876          10 :   lcpomap["HSD_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6877          10 :   lcpomap["HSD_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6878          10 :   lcpomap["HSD_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6879             : 
+    6880          10 :   lcpomap["HIP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6881          10 :   lcpomap["HIP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6882          10 :   lcpomap["HIP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6883          10 :   lcpomap["HIP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6884          10 :   lcpomap["HIP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6885          10 :   lcpomap["HIP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6886          10 :   lcpomap["HIP_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6887          10 :   lcpomap["HIP_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6888          10 :   lcpomap["HIP_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6889          10 :   lcpomap["HIP_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6890          10 :   lcpomap["HIP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6891          10 :   lcpomap["HIP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6892          10 :   lcpomap["HIP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6893             : 
+    6894          10 :   lcpomap["HSP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6895          10 :   lcpomap["HSP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6896          10 :   lcpomap["HSP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6897          10 :   lcpomap["HSP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6898          10 :   lcpomap["HSP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6899          10 :   lcpomap["HSP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6900          10 :   lcpomap["HSP_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6901          10 :   lcpomap["HSP_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6902          10 :   lcpomap["HSP_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6903          10 :   lcpomap["HSP_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6904          10 :   lcpomap["HSP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6905          10 :   lcpomap["HSP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6906          10 :   lcpomap["HSP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6907             : 
+    6908          10 :   lcpomap["ILE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6909          10 :   lcpomap["ILE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6910          10 :   lcpomap["ILE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6911          10 :   lcpomap["ILE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6912          10 :   lcpomap["ILE_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6913          10 :   lcpomap["ILE_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6914          10 :   lcpomap["ILE_CG1"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6915          10 :   lcpomap["ILE_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6916          10 :   lcpomap["ILE_CD"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6917          10 :   lcpomap["ILE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6918          10 :   lcpomap["ILE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6919          10 :   lcpomap["ILE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6920          10 :   lcpomap["ILE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6921          10 :   lcpomap["ILE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6922             : 
+    6923          10 :   lcpomap["LEU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6924          10 :   lcpomap["LEU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6925          10 :   lcpomap["LEU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6926          10 :   lcpomap["LEU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6927          10 :   lcpomap["LEU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6928          10 :   lcpomap["LEU_CG"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6929          10 :   lcpomap["LEU_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6930          10 :   lcpomap["LEU_CD2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6931          10 :   lcpomap["LEU_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6932          10 :   lcpomap["LEU_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6933          10 :   lcpomap["LEU_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6934          10 :   lcpomap["LEU_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6935          10 :   lcpomap["LEU_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6936             : 
+    6937          10 :   lcpomap["LYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6938          10 :   lcpomap["LYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6939          10 :   lcpomap["LYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6940          10 :   lcpomap["LYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6941          10 :   lcpomap["LYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6942          10 :   lcpomap["LYS_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6943          10 :   lcpomap["LYS_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6944          10 :   lcpomap["LYS_CE"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6945          10 :   lcpomap["LYS_NZ"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+    6946          10 :   lcpomap["LYS_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6947          10 :   lcpomap["LYS_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6948          10 :   lcpomap["LYS_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6949          10 :   lcpomap["LYS_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6950          10 :   lcpomap["LYS_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6951             : 
+    6952          10 :   lcpomap["MET_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6953          10 :   lcpomap["MET_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6954          10 :   lcpomap["MET_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6955          10 :   lcpomap["MET_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6956          10 :   lcpomap["MET_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6957          10 :   lcpomap["MET_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6958          10 :   lcpomap["MET_SD"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+    6959          10 :   lcpomap["MET_CE"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    6960          10 :   lcpomap["MET_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6961          10 :   lcpomap["MET_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6962          10 :   lcpomap["MET_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6963          10 :   lcpomap["MET_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6964          10 :   lcpomap["MET_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6965             : 
+    6966          10 :   lcpomap["PHE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6967          10 :   lcpomap["PHE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6968          10 :   lcpomap["PHE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6969          10 :   lcpomap["PHE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6970          10 :   lcpomap["PHE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6971          10 :   lcpomap["PHE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6972          10 :   lcpomap["PHE_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6973          10 :   lcpomap["PHE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6974          10 :   lcpomap["PHE_CZ"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6975          10 :   lcpomap["PHE_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6976          10 :   lcpomap["PHE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    6977          10 :   lcpomap["PHE_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6978          10 :   lcpomap["PHE_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6979          10 :   lcpomap["PHE_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6980          10 :   lcpomap["PHE_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6981          10 :   lcpomap["PHE_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6982             : 
+    6983          10 :   lcpomap["PRO_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6984          10 :   lcpomap["PRO_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6985          10 :   lcpomap["PRO_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6986          10 :   lcpomap["PRO_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6987          10 :   lcpomap["PRO_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6988          10 :   lcpomap["PRO_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6989          10 :   lcpomap["PRO_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    6990          10 :   lcpomap["PRO_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6991          10 :   lcpomap["PRO_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6992          10 :   lcpomap["PRO_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6993          10 :   lcpomap["PRO_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    6994          10 :   lcpomap["PRO_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    6995             : 
+    6996          10 :   lcpomap["SER_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    6997          10 :   lcpomap["SER_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    6998          10 :   lcpomap["SER_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    6999          10 :   lcpomap["SER_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7000          10 :   lcpomap["SER_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7001          10 :   lcpomap["SER_OG"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7002          10 :   lcpomap["SER_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7003          10 :   lcpomap["SER_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7004          10 :   lcpomap["SER_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7005          10 :   lcpomap["SER_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7006          10 :   lcpomap["SER_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7007             : 
+    7008          10 :   lcpomap["THR_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7009          10 :   lcpomap["THR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7010          10 :   lcpomap["THR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7011          10 :   lcpomap["THR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7012          10 :   lcpomap["THR_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7013          10 :   lcpomap["THR_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7014          10 :   lcpomap["THR_OG1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7015          10 :   lcpomap["THR_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7016          10 :   lcpomap["THR_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7017          10 :   lcpomap["THR_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7018          10 :   lcpomap["THR_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7019          10 :   lcpomap["THR_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7020             : 
+    7021          10 :   lcpomap["TRP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7022          10 :   lcpomap["TRP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7023          10 :   lcpomap["TRP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7024          10 :   lcpomap["TRP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7025          10 :   lcpomap["TRP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7026          10 :   lcpomap["TRP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7027          10 :   lcpomap["TRP_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7028          10 :   lcpomap["TRP_NE1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+    7029          10 :   lcpomap["TRP_CE2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7030          10 :   lcpomap["TRP_CZ2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7031          10 :   lcpomap["TRP_CH2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7032          10 :   lcpomap["TRP_CZ3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7033          10 :   lcpomap["TRP_CE3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7034          10 :   lcpomap["TRP_CD2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7035          10 :   lcpomap["TRP_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7036          10 :   lcpomap["TRP_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7037          10 :   lcpomap["TRP_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7038          10 :   lcpomap["TRP_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7039          10 :   lcpomap["TRP_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7040             : 
+    7041          10 :   lcpomap["TYR_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+    7042          10 :   lcpomap["TYR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7043          10 :   lcpomap["TYR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7044          10 :   lcpomap["TYR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7045          10 :   lcpomap["TYR_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+    7046          10 :   lcpomap["TYR_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7047          10 :   lcpomap["TYR_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7048          10 :   lcpomap["TYR_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7049          10 :   lcpomap["TYR_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7050          10 :   lcpomap["TYR_OH"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+    7051          10 :   lcpomap["TYR_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7052          10 :   lcpomap["TYR_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+    7053          10 :   lcpomap["TYR_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7054          10 :   lcpomap["TYR_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7055          10 :   lcpomap["TYR_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7056          10 :   lcpomap["TYR_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7057          10 :   lcpomap["TYR_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7058             : 
+    7059          10 :   lcpomap["VAL_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+    7060          10 :   lcpomap["VAL_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7061          10 :   lcpomap["VAL_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+    7062          10 :   lcpomap["VAL_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7063          10 :   lcpomap["VAL_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+    7064          10 :   lcpomap["VAL_CG1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7065          10 :   lcpomap["VAL_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+    7066          10 :   lcpomap["VAL_OC1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7067          10 :   lcpomap["VAL_OC2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7068          10 :   lcpomap["VAL_OT1"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7069          10 :   lcpomap["VAL_OT2"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+    7070          10 :   lcpomap["VAL_OXT"] = { 1.6,  0.88857,  -0.33421,  -0.0018683,  0.00049372};
+    7071             : 
+    7072             :   // nucleic acids - WARNING: ONLY AMBER (OL3-rna/ol15-dna) FORMAT
+    7073             : 
+    7074          10 :   lcpomap["A3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7075          10 :   lcpomap["A3_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7076          10 :   lcpomap["A3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7077          10 :   lcpomap["A3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7078          10 :   lcpomap["A3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7079          10 :   lcpomap["A3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7080          10 :   lcpomap["A3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7081          10 :   lcpomap["A3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7082          10 :   lcpomap["A3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7083          10 :   lcpomap["A3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7084          10 :   lcpomap["A3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7085          10 :   lcpomap["A3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7086          10 :   lcpomap["A3_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7087          10 :   lcpomap["A3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7088          10 :   lcpomap["A3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7089          10 :   lcpomap["A3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7090          10 :   lcpomap["A3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7091          10 :   lcpomap["A3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7092          10 :   lcpomap["A3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7093          10 :   lcpomap["A3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7094          10 :   lcpomap["A3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7095          10 :   lcpomap["A3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7096          10 :   lcpomap["A3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7097          10 :   lcpomap["A3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7098          10 :   lcpomap["A3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7099          10 :   lcpomap["A3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7100             : 
+    7101          10 :   lcpomap["A5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7102          10 :   lcpomap["A5_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7103          10 :   lcpomap["A5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7104          10 :   lcpomap["A5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7105          10 :   lcpomap["A5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7106          10 :   lcpomap["A5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7107          10 :   lcpomap["A5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7108          10 :   lcpomap["A5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7109          10 :   lcpomap["A5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7110          10 :   lcpomap["A5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7111          10 :   lcpomap["A5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7112          10 :   lcpomap["A5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7113          10 :   lcpomap["A5_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7114          10 :   lcpomap["A5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7115          10 :   lcpomap["A5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7116          10 :   lcpomap["A5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7117          10 :   lcpomap["A5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7118          10 :   lcpomap["A5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7119          10 :   lcpomap["A5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7120          10 :   lcpomap["A5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7121          10 :   lcpomap["A5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7122          10 :   lcpomap["A5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7123          10 :   lcpomap["A5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7124          10 :   lcpomap["A5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7125          10 :   lcpomap["A5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7126          10 :   lcpomap["A5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7127             : 
+    7128          10 :   lcpomap["A_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7129          10 :   lcpomap["A_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7130          10 :   lcpomap["A_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7131          10 :   lcpomap["A_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7132          10 :   lcpomap["A_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7133          10 :   lcpomap["A_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7134          10 :   lcpomap["A_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7135          10 :   lcpomap["A_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7136          10 :   lcpomap["A_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7137          10 :   lcpomap["A_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7138          10 :   lcpomap["A_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7139          10 :   lcpomap["A_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7140          10 :   lcpomap["A_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7141          10 :   lcpomap["A_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7142          10 :   lcpomap["A_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7143          10 :   lcpomap["A_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7144          10 :   lcpomap["A_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7145          10 :   lcpomap["A_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7146          10 :   lcpomap["A_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7147          10 :   lcpomap["A_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7148          10 :   lcpomap["A_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7149          10 :   lcpomap["A_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7150          10 :   lcpomap["A_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7151          10 :   lcpomap["A_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7152          10 :   lcpomap["A_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7153          10 :   lcpomap["A_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7154             : 
+    7155          10 :   lcpomap["C3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7156          10 :   lcpomap["C3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7157          10 :   lcpomap["C3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7158          10 :   lcpomap["C3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7159          10 :   lcpomap["C3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7160          10 :   lcpomap["C3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7161          10 :   lcpomap["C3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7162          10 :   lcpomap["C3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7163          10 :   lcpomap["C3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7164          10 :   lcpomap["C3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7165          10 :   lcpomap["C3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7166          10 :   lcpomap["C3_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7167          10 :   lcpomap["C3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7168          10 :   lcpomap["C3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7169          10 :   lcpomap["C3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7170          10 :   lcpomap["C3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7171          10 :   lcpomap["C3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7172          10 :   lcpomap["C3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7173          10 :   lcpomap["C3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7174          10 :   lcpomap["C3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7175          10 :   lcpomap["C3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7176          10 :   lcpomap["C3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7177          10 :   lcpomap["C3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7178          10 :   lcpomap["C3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7179             : 
+    7180          10 :   lcpomap["C5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7181          10 :   lcpomap["C5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7182          10 :   lcpomap["C5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7183          10 :   lcpomap["C5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7184          10 :   lcpomap["C5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7185          10 :   lcpomap["C5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7186          10 :   lcpomap["C5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7187          10 :   lcpomap["C5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7188          10 :   lcpomap["C5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7189          10 :   lcpomap["C5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7190          10 :   lcpomap["C5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7191          10 :   lcpomap["C5_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7192          10 :   lcpomap["C5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7193          10 :   lcpomap["C5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7194          10 :   lcpomap["C5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7195          10 :   lcpomap["C5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7196          10 :   lcpomap["C5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7197          10 :   lcpomap["C5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7198          10 :   lcpomap["C5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7199          10 :   lcpomap["C5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7200          10 :   lcpomap["C5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7201          10 :   lcpomap["C5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7202          10 :   lcpomap["C5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7203          10 :   lcpomap["C5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7204             : 
+    7205          10 :   lcpomap["C_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7206          10 :   lcpomap["C_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7207          10 :   lcpomap["C_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7208          10 :   lcpomap["C_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7209          10 :   lcpomap["C_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7210          10 :   lcpomap["C_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7211          10 :   lcpomap["C_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7212          10 :   lcpomap["C_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7213          10 :   lcpomap["C_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7214          10 :   lcpomap["C_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7215          10 :   lcpomap["C_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7216          10 :   lcpomap["C_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7217          10 :   lcpomap["C_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7218          10 :   lcpomap["C_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7219          10 :   lcpomap["C_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7220          10 :   lcpomap["C_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7221          10 :   lcpomap["C_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7222          10 :   lcpomap["C_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7223          10 :   lcpomap["C_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7224          10 :   lcpomap["C_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7225          10 :   lcpomap["C_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7226          10 :   lcpomap["C_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7227          10 :   lcpomap["C_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7228          10 :   lcpomap["C_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7229             : 
+    7230          10 :   lcpomap["DA3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7231          10 :   lcpomap["DA3_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7232          10 :   lcpomap["DA3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7233          10 :   lcpomap["DA3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7234          10 :   lcpomap["DA3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7235          10 :   lcpomap["DA3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7236          10 :   lcpomap["DA3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7237          10 :   lcpomap["DA3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7238          10 :   lcpomap["DA3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7239          10 :   lcpomap["DA3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7240          10 :   lcpomap["DA3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7241          10 :   lcpomap["DA3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7242          10 :   lcpomap["DA3_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7243          10 :   lcpomap["DA3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7244          10 :   lcpomap["DA3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7245          10 :   lcpomap["DA3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7246          10 :   lcpomap["DA3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7247          10 :   lcpomap["DA3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7248          10 :   lcpomap["DA3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7249          10 :   lcpomap["DA3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7250          10 :   lcpomap["DA3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7251          10 :   lcpomap["DA3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7252          10 :   lcpomap["DA3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7253          10 :   lcpomap["DA3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7254          10 :   lcpomap["DA3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7255             : 
+    7256          10 :   lcpomap["DA5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7257          10 :   lcpomap["DA5_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7258          10 :   lcpomap["DA5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7259          10 :   lcpomap["DA5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7260          10 :   lcpomap["DA5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7261          10 :   lcpomap["DA5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7262          10 :   lcpomap["DA5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7263          10 :   lcpomap["DA5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7264          10 :   lcpomap["DA5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7265          10 :   lcpomap["DA5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7266          10 :   lcpomap["DA5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7267          10 :   lcpomap["DA5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7268          10 :   lcpomap["DA5_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7269          10 :   lcpomap["DA5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7270          10 :   lcpomap["DA5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7271          10 :   lcpomap["DA5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7272          10 :   lcpomap["DA5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7273          10 :   lcpomap["DA5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7274          10 :   lcpomap["DA5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7275          10 :   lcpomap["DA5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7276          10 :   lcpomap["DA5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7277          10 :   lcpomap["DA5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7278          10 :   lcpomap["DA5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7279          10 :   lcpomap["DA5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7280          10 :   lcpomap["DA5_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7281             : 
+    7282          10 :   lcpomap["DA_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7283          10 :   lcpomap["DA_C2"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7284          10 :   lcpomap["DA_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7285          10 :   lcpomap["DA_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7286          10 :   lcpomap["DA_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7287          10 :   lcpomap["DA_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7288          10 :   lcpomap["DA_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7289          10 :   lcpomap["DA_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7290          10 :   lcpomap["DA_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7291          10 :   lcpomap["DA_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7292          10 :   lcpomap["DA_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7293          10 :   lcpomap["DA_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7294          10 :   lcpomap["DA_N6"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7295          10 :   lcpomap["DA_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7296          10 :   lcpomap["DA_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7297          10 :   lcpomap["DA_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7298          10 :   lcpomap["DA_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7299          10 :   lcpomap["DA_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7300          10 :   lcpomap["DA_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7301          10 :   lcpomap["DA_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7302          10 :   lcpomap["DA_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7303          10 :   lcpomap["DA_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7304          10 :   lcpomap["DA_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7305          10 :   lcpomap["DA_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7306          10 :   lcpomap["DA_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7307             : 
+    7308          10 :   lcpomap["DC3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7309          10 :   lcpomap["DC3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7310          10 :   lcpomap["DC3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7311          10 :   lcpomap["DC3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7312          10 :   lcpomap["DC3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7313          10 :   lcpomap["DC3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7314          10 :   lcpomap["DC3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7315          10 :   lcpomap["DC3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7316          10 :   lcpomap["DC3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7317          10 :   lcpomap["DC3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7318          10 :   lcpomap["DC3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7319          10 :   lcpomap["DC3_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7320          10 :   lcpomap["DC3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7321          10 :   lcpomap["DC3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7322          10 :   lcpomap["DC3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7323          10 :   lcpomap["DC3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7324          10 :   lcpomap["DC3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7325          10 :   lcpomap["DC3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7326          10 :   lcpomap["DC3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7327          10 :   lcpomap["DC3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7328          10 :   lcpomap["DC3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7329          10 :   lcpomap["DC3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7330          10 :   lcpomap["DC3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7331             : 
+    7332          10 :   lcpomap["DC5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7333          10 :   lcpomap["DC5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7334          10 :   lcpomap["DC5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7335          10 :   lcpomap["DC5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7336          10 :   lcpomap["DC5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7337          10 :   lcpomap["DC5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7338          10 :   lcpomap["DC5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7339          10 :   lcpomap["DC5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7340          10 :   lcpomap["DC5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7341          10 :   lcpomap["DC5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7342          10 :   lcpomap["DC5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7343          10 :   lcpomap["DC5_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7344          10 :   lcpomap["DC5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7345          10 :   lcpomap["DC5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7346          10 :   lcpomap["DC5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7347          10 :   lcpomap["DC5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7348          10 :   lcpomap["DC5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7349          10 :   lcpomap["DC5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7350          10 :   lcpomap["DC5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7351          10 :   lcpomap["DC5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7352          10 :   lcpomap["DC5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7353          10 :   lcpomap["DC5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7354          10 :   lcpomap["DC5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7355             : 
+    7356          10 :   lcpomap["DC_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7357          10 :   lcpomap["DC_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7358          10 :   lcpomap["DC_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7359          10 :   lcpomap["DC_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7360          10 :   lcpomap["DC_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7361          10 :   lcpomap["DC_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7362          10 :   lcpomap["DC_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7363          10 :   lcpomap["DC_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7364          10 :   lcpomap["DC_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7365          10 :   lcpomap["DC_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7366          10 :   lcpomap["DC_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7367          10 :   lcpomap["DC_N4"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7368          10 :   lcpomap["DC_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7369          10 :   lcpomap["DC_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7370          10 :   lcpomap["DC_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7371          10 :   lcpomap["DC_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7372          10 :   lcpomap["DC_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7373          10 :   lcpomap["DC_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7374          10 :   lcpomap["DC_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7375          10 :   lcpomap["DC_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7376          10 :   lcpomap["DC_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7377          10 :   lcpomap["DC_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7378          10 :   lcpomap["DC_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7379             : 
+    7380          10 :   lcpomap["DG3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7381          10 :   lcpomap["DG3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7382          10 :   lcpomap["DG3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7383          10 :   lcpomap["DG3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7384          10 :   lcpomap["DG3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7385          10 :   lcpomap["DG3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7386          10 :   lcpomap["DG3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7387          10 :   lcpomap["DG3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7388          10 :   lcpomap["DG3_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7389          10 :   lcpomap["DG3_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7390          10 :   lcpomap["DG3_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7391          10 :   lcpomap["DG3_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7392          10 :   lcpomap["DG3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7393          10 :   lcpomap["DG3_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7394          10 :   lcpomap["DG3_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7395          10 :   lcpomap["DG3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7396          10 :   lcpomap["DG3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7397          10 :   lcpomap["DG3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7398          10 :   lcpomap["DG3_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7399          10 :   lcpomap["DG3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7400          10 :   lcpomap["DG3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7401          10 :   lcpomap["DG3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7402          10 :   lcpomap["DG3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7403          10 :   lcpomap["DG3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7404          10 :   lcpomap["DG3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7405          10 :   lcpomap["DG3_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7406             : 
+    7407          10 :   lcpomap["DG5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7408          10 :   lcpomap["DG5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7409          10 :   lcpomap["DG5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7410          10 :   lcpomap["DG5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7411          10 :   lcpomap["DG5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7412          10 :   lcpomap["DG5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7413          10 :   lcpomap["DG5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7414          10 :   lcpomap["DG5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7415          10 :   lcpomap["DG5_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7416          10 :   lcpomap["DG5_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7417          10 :   lcpomap["DG5_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7418          10 :   lcpomap["DG5_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7419          10 :   lcpomap["DG5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7420          10 :   lcpomap["DG5_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7421          10 :   lcpomap["DG5_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7422          10 :   lcpomap["DG5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7423          10 :   lcpomap["DG5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7424          10 :   lcpomap["DG5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7425          10 :   lcpomap["DG5_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7426          10 :   lcpomap["DG5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7427          10 :   lcpomap["DG5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7428          10 :   lcpomap["DG5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7429          10 :   lcpomap["DG5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7430          10 :   lcpomap["DG5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7431          10 :   lcpomap["DG5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7432          10 :   lcpomap["DG5_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7433             : 
+    7434          10 :   lcpomap["DG_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7435          10 :   lcpomap["DG_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7436          10 :   lcpomap["DG_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7437          10 :   lcpomap["DG_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7438          10 :   lcpomap["DG_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7439          10 :   lcpomap["DG_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7440          10 :   lcpomap["DG_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7441          10 :   lcpomap["DG_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7442          10 :   lcpomap["DG_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7443          10 :   lcpomap["DG_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7444          10 :   lcpomap["DG_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7445          10 :   lcpomap["DG_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7446          10 :   lcpomap["DG_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7447          10 :   lcpomap["DG_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7448          10 :   lcpomap["DG_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7449          10 :   lcpomap["DG_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7450          10 :   lcpomap["DG_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7451          10 :   lcpomap["DG_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7452          10 :   lcpomap["DG_O6"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7453          10 :   lcpomap["DG_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7454          10 :   lcpomap["DG_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7455          10 :   lcpomap["DG_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7456          10 :   lcpomap["DG_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7457          10 :   lcpomap["DG_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7458          10 :   lcpomap["DG_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7459          10 :   lcpomap["DG_P"]   = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7460             : 
+    7461          10 :   lcpomap["DT3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7462          10 :   lcpomap["DT3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7463          10 :   lcpomap["DT3_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7464          10 :   lcpomap["DT3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7465          10 :   lcpomap["DT3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7466          10 :   lcpomap["DT3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7467          10 :   lcpomap["DT3_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7468          10 :   lcpomap["DT3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7469          10 :   lcpomap["DT3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7470          10 :   lcpomap["DT3_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    7471          10 :   lcpomap["DT3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7472          10 :   lcpomap["DT3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7473          10 :   lcpomap["DT3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7474          10 :   lcpomap["DT3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7475          10 :   lcpomap["DT3_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7476          10 :   lcpomap["DT3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7477          10 :   lcpomap["DT3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7478          10 :   lcpomap["DT3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7479          10 :   lcpomap["DT3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7480          10 :   lcpomap["DT3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7481          10 :   lcpomap["DT3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7482          10 :   lcpomap["DT3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7483          10 :   lcpomap["DT3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7484          10 :   lcpomap["DT3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7485             : 
+    7486          10 :   lcpomap["DT5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7487          10 :   lcpomap["DT5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7488          10 :   lcpomap["DT5_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7489          10 :   lcpomap["DT5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7490          10 :   lcpomap["DT5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7491          10 :   lcpomap["DT5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7492          10 :   lcpomap["DT5_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7493          10 :   lcpomap["DT5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7494          10 :   lcpomap["DT5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7495          10 :   lcpomap["DT5_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    7496          10 :   lcpomap["DT5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7497          10 :   lcpomap["DT5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7498          10 :   lcpomap["DT5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7499          10 :   lcpomap["DT5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7500          10 :   lcpomap["DT5_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7501          10 :   lcpomap["DT5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7502          10 :   lcpomap["DT5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7503          10 :   lcpomap["DT5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7504          10 :   lcpomap["DT5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7505          10 :   lcpomap["DT5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7506          10 :   lcpomap["DT5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7507          10 :   lcpomap["DT5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7508          10 :   lcpomap["DT5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7509          10 :   lcpomap["DT5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7510             : 
+    7511          10 :   lcpomap["DT_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7512          10 :   lcpomap["DT_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7513          10 :   lcpomap["DT_C2'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7514          10 :   lcpomap["DT_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7515          10 :   lcpomap["DT_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7516          10 :   lcpomap["DT_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7517          10 :   lcpomap["DT_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7518          10 :   lcpomap["DT_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7519          10 :   lcpomap["DT_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7520          10 :   lcpomap["DT_C7"]  = { 1.7,  0.77887, -0.28063, -1.2968e-03, 3.9328e-04 };
+    7521          10 :   lcpomap["DT_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7522          10 :   lcpomap["DT_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7523          10 :   lcpomap["DT_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7524          10 :   lcpomap["DT_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7525          10 :   lcpomap["DT_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7526          10 :   lcpomap["DT_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7527          10 :   lcpomap["DT_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7528          10 :   lcpomap["DT_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7529          10 :   lcpomap["DT_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7530          10 :   lcpomap["DT_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7531          10 :   lcpomap["DT_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7532          10 :   lcpomap["DT_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7533          10 :   lcpomap["DT_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7534          10 :   lcpomap["DT_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7535             : 
+    7536          10 :   lcpomap["G3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7537          10 :   lcpomap["G3_C2"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7538          10 :   lcpomap["G3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7539          10 :   lcpomap["G3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7540          10 :   lcpomap["G3_C4"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7541          10 :   lcpomap["G3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7542          10 :   lcpomap["G3_C5"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7543          10 :   lcpomap["G3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7544          10 :   lcpomap["G3_C6"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7545          10 :   lcpomap["G3_C8"] = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7546          10 :   lcpomap["G3_N1"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7547          10 :   lcpomap["G3_N2"] = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7548          10 :   lcpomap["G3_N3"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7549          10 :   lcpomap["G3_N7"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7550          10 :   lcpomap["G3_N9"] = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7551          10 :   lcpomap["G3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7552          10 :   lcpomap["G3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7553          10 :   lcpomap["G3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7554          10 :   lcpomap["G3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7555          10 :   lcpomap["G3_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7556          10 :   lcpomap["G3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7557          10 :   lcpomap["G3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7558          10 :   lcpomap["G3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7559          10 :   lcpomap["G3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7560          10 :   lcpomap["G3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7561          10 :   lcpomap["G3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7562          10 :   lcpomap["G3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7563             : 
+    7564          10 :   lcpomap["G5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7565          10 :   lcpomap["G5_C2"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7566          10 :   lcpomap["G5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7567          10 :   lcpomap["G5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7568          10 :   lcpomap["G5_C4"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7569          10 :   lcpomap["G5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7570          10 :   lcpomap["G5_C5"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7571          10 :   lcpomap["G5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7572          10 :   lcpomap["G5_C6"] = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7573          10 :   lcpomap["G5_C8"] = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7574          10 :   lcpomap["G5_N1"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7575          10 :   lcpomap["G5_N2"] = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7576          10 :   lcpomap["G5_N3"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7577          10 :   lcpomap["G5_N7"] = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7578          10 :   lcpomap["G5_N9"] = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7579          10 :   lcpomap["G5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7580          10 :   lcpomap["G5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7581          10 :   lcpomap["G5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7582          10 :   lcpomap["G5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7583          10 :   lcpomap["G5_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7584          10 :   lcpomap["G5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7585          10 :   lcpomap["G5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7586          10 :   lcpomap["G5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7587          10 :   lcpomap["G5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7588          10 :   lcpomap["G5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7589          10 :   lcpomap["G5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7590          10 :   lcpomap["G5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7591             : 
+    7592          10 :   lcpomap["G_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7593          10 :   lcpomap["G_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7594          10 :   lcpomap["G_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7595          10 :   lcpomap["G_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7596          10 :   lcpomap["G_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7597          10 :   lcpomap["G_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7598          10 :   lcpomap["G_C5"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7599          10 :   lcpomap["G_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7600          10 :   lcpomap["G_C6"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7601          10 :   lcpomap["G_C8"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7602          10 :   lcpomap["G_N1"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7603          10 :   lcpomap["G_N2"]  = { 1.65,  0.73511, -0.22116, -8.9148e-04, 2.523e-04 };
+    7604          10 :   lcpomap["G_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7605          10 :   lcpomap["G_N7"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7606          10 :   lcpomap["G_N9"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7607          10 :   lcpomap["G_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7608          10 :   lcpomap["G_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7609          10 :   lcpomap["G_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7610          10 :   lcpomap["G_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7611          10 :   lcpomap["G_O6"] = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7612          10 :   lcpomap["G_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7613          10 :   lcpomap["G_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7614          10 :   lcpomap["G_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7615          10 :   lcpomap["G_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7616          10 :   lcpomap["G_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7617          10 :   lcpomap["G_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7618          10 :   lcpomap["G_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7619             : 
+    7620          10 :   lcpomap["U3_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7621          10 :   lcpomap["U3_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7622          10 :   lcpomap["U3_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7623          10 :   lcpomap["U3_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7624          10 :   lcpomap["U3_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7625          10 :   lcpomap["U3_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7626          10 :   lcpomap["U3_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7627          10 :   lcpomap["U3_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7628          10 :   lcpomap["U3_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7629          10 :   lcpomap["U3_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7630          10 :   lcpomap["U3_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7631          10 :   lcpomap["U3_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7632          10 :   lcpomap["U3_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7633          10 :   lcpomap["U3_O3'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7634          10 :   lcpomap["U3_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7635          10 :   lcpomap["U3_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7636          10 :   lcpomap["U3_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7637          10 :   lcpomap["U3_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7638          10 :   lcpomap["U3_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7639          10 :   lcpomap["U3_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7640          10 :   lcpomap["U3_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7641          10 :   lcpomap["U3_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7642          10 :   lcpomap["U3_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7643          10 :   lcpomap["U3_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7644             : 
+    7645          10 :   lcpomap["U5_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7646          10 :   lcpomap["U5_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7647          10 :   lcpomap["U5_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7648          10 :   lcpomap["U5_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7649          10 :   lcpomap["U5_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7650          10 :   lcpomap["U5_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7651          10 :   lcpomap["U5_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7652          10 :   lcpomap["U5_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7653          10 :   lcpomap["U5_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7654          10 :   lcpomap["U5_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7655          10 :   lcpomap["U5_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7656          10 :   lcpomap["U5_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7657          10 :   lcpomap["U5_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7658          10 :   lcpomap["U5_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7659          10 :   lcpomap["U5_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7660          10 :   lcpomap["U5_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7661          10 :   lcpomap["U5_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7662          10 :   lcpomap["U5_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7663          10 :   lcpomap["U5_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7664          10 :   lcpomap["U5_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7665          10 :   lcpomap["U5_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7666          10 :   lcpomap["U5_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7667          10 :   lcpomap["U5_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7668          10 :   lcpomap["U5_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7669             : 
+    7670          10 :   lcpomap["U_C1'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7671          10 :   lcpomap["U_C2"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7672          10 :   lcpomap["U_C2'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7673          10 :   lcpomap["U_C3'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7674          10 :   lcpomap["U_C4"]  = { 1.7,  0.070344, -0.019015, -2.2009e-05, 1.6875e-05 };
+    7675          10 :   lcpomap["U_C4'"] = { 1.7,  0.23348, -0.072627, -2.0079e-04, 7.967e-05 };
+    7676          10 :   lcpomap["U_C5"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7677          10 :   lcpomap["U_C5'"] = { 1.7,  0.56482, -0.19608, -1.0219e-03, 2.658e-04 };
+    7678          10 :   lcpomap["U_C6"]  = { 1.7,  0.51245, -0.15966, -1.9781e-04, 1.6392e-04 };
+    7679          10 :   lcpomap["U_N1"]  = { 1.65,  0.062577, -0.017874, -8.312e-05, 1.9849e-05 };
+    7680          10 :   lcpomap["U_N3"]  = { 1.65,  0.41102, -0.12254, -7.5448e-05, 1.1804e-04 };
+    7681          10 :   lcpomap["U_O2"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7682          10 :   lcpomap["U_O2'"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7683          10 :   lcpomap["U_O3'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7684          10 :   lcpomap["U_O4"]  = { 1.6,  0.68563, -0.1868, -1.35573e-03, 2.3743e-04 };
+    7685          10 :   lcpomap["U_O4'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7686          10 :   lcpomap["U_O5'"] = { 1.6,  0.49392, -0.16038, -1.5512e-04, 1.6453e-04 };
+    7687          10 :   lcpomap["U_OP1"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7688          10 :   lcpomap["U_OP2"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7689          10 :   lcpomap["U_OP3"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7690          10 :   lcpomap["U_O1P"] = { 1.6,  0.77914, -0.25262, -1.6056e-03, 3.5071e-04 };
+    7691          10 :   lcpomap["U_O2P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7692          10 :   lcpomap["U_O3P"] = { 1.6,  0.88857, -0.33421, -1.8683e-03, 4.9372e-04 };
+    7693          10 :   lcpomap["U_P"] = { 1.9,  0.03873,  -0.0089339, 8.3582e-06,  3.0381e-06};
+    7694             : 
+    7695          10 :   return lcpomap;
+    7696             : }
+    7697             : 
+    7698             : // assigns LCPO parameters to each atom reading from database
+    7699          10 : void SAXS::readLCPOparam(const std::vector<std::vector<std::string> > &AtomResidueName, unsigned natoms)
+    7700             : {
+    7701          10 :   std::map<std::string, std::vector<double> > lcpomap = setupLCPOparam();
+    7702             : 
+    7703       35476 :   for(unsigned i=0; i<natoms; ++i)
+    7704             :   {
+    7705       35466 :     if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S' || (AtomResidueName[0][i][0]=='P'))) {
+    7706       16548 :       std::string identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+    7707       16548 :       std::vector<double> LCPOparamVector = lcpomap.at(identifier);
+    7708             :       double rs = 0.14;
+    7709       16548 :       LCPOparam[i].push_back(LCPOparamVector[0]+rs*10.);
+    7710       16548 :       LCPOparam[i].push_back(LCPOparamVector[1]);
+    7711       16548 :       LCPOparam[i].push_back(LCPOparamVector[2]);
+    7712       16548 :       LCPOparam[i].push_back(LCPOparamVector[3]);
+    7713       16548 :       LCPOparam[i].push_back(LCPOparamVector[4]);
+    7714             :     }
+    7715             :   }
+    7716             : 
+    7717       35476 :   for(unsigned i=0; i<natoms; ++i) {
+    7718       35466 :     if (LCPOparam[i].size()==0 ) {
+    7719       18918 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S') || (AtomResidueName[0][i][0]=='P')) {
+    7720           0 :         std::cout << "Could not find LCPO paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << std::endl;
+    7721           0 :         error ("missing LCPO parameters\n");
+    7722             :       }
+    7723             :     }
+    7724             :   }
+    7725             : 
+    7726          10 :   if (AtomResidueName[0][0] == "N") {
+    7727          10 :     LCPOparam[0][1] = 7.3511e-01;
+    7728          10 :     LCPOparam[0][2] = -2.2116e-01;
+    7729          10 :     LCPOparam[0][3] = -8.9148e-04;
+    7730          10 :     LCPOparam[0][4] = 2.5230e-04;
+    7731             :   }
+    7732             : 
+    7733          10 :   if (AtomResidueName[0][natoms-1] == "O") {
+    7734           0 :     LCPOparam[natoms-1][1] = 8.8857e-01;
+    7735           0 :     LCPOparam[natoms-1][2] = -3.3421e-01;
+    7736           0 :     LCPOparam[natoms-1][3] = -1.8683e-03;
+    7737           0 :     LCPOparam[natoms-1][4] = 4.9372e-04;
+    7738             :   }
+    7739          10 : }
+    7740             : 
+    7741           4 : void SAXS::resolution_function()
+    7742             : {
+    7743           4 :   const unsigned numq = q_list.size();
+    7744             : 
+    7745             :   // only OpenMP because numq might be smaller than the number of ranks
+    7746           4 :   #pragma omp parallel for num_threads(OpenMP::getNumThreads())
+    7747             :   for (unsigned i=0; i<numq; i++) {
+    7748             :     double qi = q_list[i];
+    7749             :     double dq = 6*sigma_res[i]/(Nj-1);
+    7750             :     double sigma_sq = sigma_res[i]*sigma_res[i];
+    7751             :     double qstart = qi - 3*sigma_res[i];
+    7752             :     for (unsigned j=0; j<Nj; j++) {
+    7753             :       double qj = qstart + j*dq;
+    7754             :       double I0exp = i0e(qj*qi/sigma_sq);
+    7755             : 
+    7756             :       qj_list[i][j] = qj;
+    7757             :       Rij[i][j] = (qj/sigma_sq)*std::exp(-0.5*(qj - qi)*(qj - qi)/sigma_sq)*I0exp;
+    7758             :     }
+    7759             :   }
+    7760           4 : }
+    7761             : 
+    7762             : // i0e function from cephes
+    7763             : // compute I0(x) * exp (-x), with I0 being the modified Bessel function
+    7764             : // of first kind and zeroth order.
+    7765         660 : inline double SAXS::i0e(double x)
+    7766             : {
+    7767             :   double y = 0.0;
+    7768             : 
+    7769         660 :   if (x < 0)
+    7770           0 :     x = -x;
+    7771         660 :   if (x <= 8.0) {
+    7772           0 :     y = (x/2.0) - 2.0;
+    7773           0 :     return chbevl(y, A);
+    7774             :   }
+    7775             : 
+    7776         660 :   return chbevl(32.0/x - 2.0, B) / sqrt(x);
+    7777             : }
+    7778             : 
+    7779         660 : double SAXS::chbevl(double x, const std::vector<double> &coeffs)
+    7780             : {
+    7781             :   double b0, b1, b2;
+    7782         660 :   unsigned n = coeffs.size();
+    7783             : 
+    7784         660 :   b0 = coeffs[0];
+    7785             :   b1 = 0.0;
+    7786             :   b2 = 0.0;
+    7787             : 
+    7788       16500 :   for (unsigned i = 1; i < n; i++) {
+    7789             :     b2 = b1;
+    7790             :     b1 = b0;
+    7791       15840 :     b0 = x * b1 - b2 + coeffs[i];
+    7792             :   }
+    7793         660 :   return 0.5 * (b0 - b2);
+    7794             : }
+    7795             : 
+    7796      134310 : inline double SAXS::interpolation(std::vector<SplineCoeffs> &coeffs, double x)
+    7797             : {
+    7798             :   unsigned s = 0;
+    7799     1002034 :   while ((x >= q_list[s+1]) && (s+1 < q_list.size()-1)) s++;
+    7800             : 
+    7801      134310 :   double dx = x - coeffs[s].x;
+    7802      134310 :   return coeffs[s].a + coeffs[s].b*dx + coeffs[s].c*dx*dx + coeffs[s].d*dx*dx*dx;
+    7803             : }
+    7804             : 
+    7805             : // natural bc cubic spline implementation from the Wikipedia algorithm
+    7806             : // modified from https://stackoverflow.com/a/19216702/3254658
+    7807         814 : std::vector<SAXS::SplineCoeffs> SAXS::spline_coeffs(std::vector<double> &x, std::vector<double> &y)
+    7808             : {
+    7809         814 :   unsigned n = x.size()-1;
+    7810             :   std::vector<double> a;
+    7811         814 :   a.insert(a.begin(), y.begin(), y.end());
+    7812         814 :   std::vector<double> b(n);
+    7813         814 :   std::vector<double> d(n);
+    7814             :   std::vector<double> h;
+    7815             : 
+    7816       12210 :   for(unsigned i=0; i<n; i++)
+    7817       11396 :     h.push_back(x[i+1]-x[i]);
+    7818             : 
+    7819             :   std::vector<double> alpha;
+    7820         814 :   alpha.push_back(0);
+    7821       11396 :   for(unsigned i=1; i<n; i++)
+    7822       10582 :     alpha.push_back( 3*(a[i+1]-a[i])/h[i] - 3*(a[i]-a[i-1])/h[i-1]  );
+    7823             : 
+    7824         814 :   std::vector<double> c(n+1);
+    7825         814 :   std::vector<double> l(n+1);
+    7826         814 :   std::vector<double> mu(n+1);
+    7827         814 :   std::vector<double> z(n+1);
+    7828         814 :   l[0] = 1;
+    7829         814 :   mu[0] = 0;
+    7830         814 :   z[0] = 0;
+    7831             : 
+    7832       11396 :   for(unsigned i=1; i<n; i++) {
+    7833       10582 :     l[i] = 2 *(x[i+1]-x[i-1])-h[i-1]*mu[i-1];
+    7834       10582 :     mu[i] = h[i]/l[i];
+    7835       10582 :     z[i] = (alpha[i]-h[i-1]*z[i-1])/l[i];
+    7836             :   }
+    7837             : 
+    7838         814 :   l[n] = 1;
+    7839         814 :   z[n] = 0;
+    7840         814 :   c[n] = 0;
+    7841             : 
+    7842       12210 :   for(int j=n-1; j>=0; j--) {
+    7843       11396 :     c[j] = z[j] - mu[j] * c[j+1];
+    7844       11396 :     b[j] = (a[j+1]-a[j])/h[j]-h[j]*(c[j+1]+2*c[j])/3;
+    7845       11396 :     d[j] = (c[j+1]-c[j])/3/h[j];
+    7846             :   }
+    7847             : 
+    7848         814 :   std::vector<SplineCoeffs> output_set(n);
+    7849       12210 :   for(unsigned i=0; i<n; i++) {
+    7850       11396 :     output_set[i].a = a[i];
+    7851       11396 :     output_set[i].b = b[i];
+    7852       11396 :     output_set[i].c = c[i];
+    7853       11396 :     output_set[i].d = d[i];
+    7854       11396 :     output_set[i].x = x[i];
+    7855             :   }
+    7856             : 
+    7857         814 :   return output_set;
+    7858             : }
+    7859             : 
+    7860             : 
+    7861             : }//namespace isdb
+    7862             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Select.cpp.func-sort-c.html b/coverage/isdb/Select.cpp.func-sort-c.html new file mode 100644 index 000000000000..a7b81bbe4f23 --- /dev/null +++ b/coverage/isdb/Select.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Select.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Select.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb6SelectC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb6SelectC1ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb6Select16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4isdb6Select9calculateEv8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Select.cpp.func.html b/coverage/isdb/Select.cpp.func.html new file mode 100644 index 000000000000..b9df399b5ffc --- /dev/null +++ b/coverage/isdb/Select.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Select.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Select.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb6Select16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4isdb6Select9calculateEv8
_ZN4PLMD4isdb6SelectC1ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb6SelectC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Select.cpp.gcov.html b/coverage/isdb/Select.cpp.gcov.html new file mode 100644 index 000000000000..837e49721526 --- /dev/null +++ b/coverage/isdb/Select.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Select.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Select.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : /*
+      23             : 
+      24             : */
+      25             : #include "function/Function.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace isdb {
+      31             : 
+      32             : //+PLUMEDOC ISDB_FUNCTION SELECT
+      33             : /*
+      34             : Selects an argument based on the value of a \ref SELECTOR.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : In this example we use a simulated-tempering like approach activated by the \ref RESCALE action.
+      39             : For each value of the scale parameter, we perform an independent Parallel Bias Metadynamics
+      40             : simulation (see \ref PBMETAD). At each moment of the simulation, only one of the \ref PBMETAD
+      41             : actions is activated, based on the current value of the associated \ref SELECTOR.
+      42             : The \ref SELECT action can then be used to print out the value of the (active) \ref PBMETAD bias potential.
+      43             : 
+      44             : \plumedfile
+      45             : ene:  ENERGY
+      46             : d: DISTANCE ATOMS=1,2
+      47             : 
+      48             : SELECTOR NAME=GAMMA VALUE=0
+      49             : 
+      50             : pbmetad0: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=0 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.0
+      51             : pbmetad1: PBMETAD ARG=d SELECTOR=GAMMA SELECTOR_ID=1 SIGMA=0.1 PACE=500 HEIGHT=1 BIASFACTOR=8 FILE=HILLS.1
+      52             : 
+      53             : RESCALE ...
+      54             : LABEL=res ARG=ene,pbmetad0.bias,pbmetad1.bias TEMP=300
+      55             : SELECTOR=GAMMA MAX_RESCALE=1.2 NOT_RESCALED=2 NBIN=2
+      56             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
+      57             : ...
+      58             : 
+      59             : pbactive: SELECT ARG=pbmetad0.bias,pbmetad1.bias SELECTOR=GAMMA
+      60             : 
+      61             : PRINT ARG=pbactive STRIDE=100 FILE=COLVAR
+      62             : \endplumedfile
+      63             : 
+      64             : */
+      65             : //+ENDPLUMEDOC
+      66             : 
+      67             : class Select : public function::Function
+      68             : {
+      69             :   std::string selector_;
+      70             : 
+      71             : public:
+      72             :   explicit Select(const ActionOptions&);
+      73             :   void calculate();
+      74             :   static void registerKeywords(Keywords& keys);
+      75             : };
+      76             : 
+      77             : PLUMED_REGISTER_ACTION(Select,"SELECT")
+      78             : 
+      79           4 : void Select::registerKeywords(Keywords& keys) {
+      80           4 :   Function::registerKeywords(keys);
+      81           4 :   keys.use("ARG");
+      82           8 :   keys.add("compulsory","SELECTOR","name of the variable used to select");
+      83           4 : }
+      84             : 
+      85           2 : Select::Select(const ActionOptions&ao):
+      86           2 :   Action(ao), Function(ao)
+      87             : {
+      88             :   // name of selector
+      89           2 :   parse("SELECTOR", selector_);
+      90             : 
+      91           2 :   addValueWithDerivatives(); setNotPeriodic();
+      92           2 :   checkRead();
+      93             : 
+      94           2 :   log.printf("  select based on %s\n",selector_.c_str());
+      95           4 :   log << " Bibliography" << plumed.cite("Bonomi, Camilloni, Bioinformatics, 33, 3999 (2017)") << "\n";
+      96             : 
+      97           2 : }
+      98             : 
+      99           8 : void Select::calculate()
+     100             : {
+     101           8 :   unsigned iselect = static_cast<unsigned>(plumed.passMap[selector_]);
+     102             : 
+     103             :   // check if iselect is smaller than the number of arguments
+     104           8 :   if(iselect>=getNumberOfArguments()) error("the value of the SELECTOR is greater than the number of arguments!");
+     105             : 
+     106             :   // put all the derivatives to zero
+     107          24 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) setDerivative(i, 0.0);
+     108             : 
+     109             :   // set value and derivative for selected argument
+     110           8 :   setValue(getArgument(iselect));
+     111             :   setDerivative(iselect, 1.0);
+     112           8 : }
+     113             : 
+     114             : }
+     115             : }
+     116             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Selector.cpp.func-sort-c.html b/coverage/isdb/Selector.cpp.func-sort-c.html new file mode 100644 index 000000000000..d4d88153b14d --- /dev/null +++ b/coverage/isdb/Selector.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Selector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Selector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:111384.6 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb8Selector5applyEv0
_ZN4PLMD4isdb8Selector9calculateEv0
_ZN4PLMD4isdb8SelectorC2ERKNS_13ActionOptionsE2
_ZN4PLMD4isdb8Selector16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Selector.cpp.func.html b/coverage/isdb/Selector.cpp.func.html new file mode 100644 index 000000000000..f828545b4985 --- /dev/null +++ b/coverage/isdb/Selector.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Selector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Selector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:111384.6 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb8Selector16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4isdb8Selector5applyEv0
_ZN4PLMD4isdb8Selector9calculateEv0
_ZN4PLMD4isdb8SelectorC2ERKNS_13ActionOptionsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Selector.cpp.gcov.html b/coverage/isdb/Selector.cpp.gcov.html new file mode 100644 index 000000000000..47ac0b4913aa --- /dev/null +++ b/coverage/isdb/Selector.cpp.gcov.html @@ -0,0 +1,169 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Selector.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Selector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:111384.6 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/Action.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include <string>
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace isdb {
+      29             : 
+      30             : //+PLUMEDOC ISDB_GENERIC SELECTOR
+      31             : /*
+      32             : Defines a variable (of the type double) inside the PLUMED code that can be used and modified by other actions.
+      33             : 
+      34             : A \ref SELECTOR can be used for example to activate or modify a bias based on its current value.
+      35             : 
+      36             : \par Examples
+      37             : 
+      38             : A typical example is the simulated-tempering like approach activated by \ref RESCALE.
+      39             : In this example the total potential energy of the system is scaled
+      40             : by a parameter defined on a grid of dimension NBIN in the range from 1 to MAX_RESCALE.
+      41             : The value of the scaling parameter is determined by the current value of the \ref SELECTOR GAMMA.
+      42             : The value of the \ref SELECTOR is updated by a MC protocol inside the \ref RESCALE class.
+      43             : A well-tempered metadynamics potential is used to enhance sampling in the \ref SELECTOR space.
+      44             : 
+      45             : \plumedfile
+      46             : ene:  ENERGY
+      47             : 
+      48             : SELECTOR NAME=GAMMA VALUE=0
+      49             : 
+      50             : RESCALE ...
+      51             : LABEL=res ARG=ene TEMP=300
+      52             : SELECTOR=GAMMA MAX_RESCALE=1.2 NBIN=2
+      53             : W0=1000 BIASFACTOR=100.0 BSTRIDE=2000 BFILE=bias.dat
+      54             : ...
+      55             : 
+      56             : PRINT FILE=COLVAR ARG=* STRIDE=100
+      57             : \endplumedfile
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : class Selector:
+      63             :   public Action
+      64             : {
+      65             : public:
+      66             :   static void registerKeywords( Keywords& keys );
+      67             :   explicit Selector(const ActionOptions&ao);
+      68           0 :   void calculate() override {}
+      69           0 :   void apply() override {}
+      70             : };
+      71             : 
+      72             : PLUMED_REGISTER_ACTION(Selector,"SELECTOR")
+      73             : 
+      74           4 : void Selector::registerKeywords( Keywords& keys ) {
+      75           4 :   Action::registerKeywords(keys);
+      76           8 :   keys.add("compulsory","NAME","name of the SELECTOR");
+      77           8 :   keys.add("compulsory","VALUE","set (initial) value of the SELECTOR");
+      78           4 : }
+      79             : 
+      80           2 : Selector::Selector(const ActionOptions&ao):
+      81           2 :   Action(ao)
+      82             : {
+      83             :   std::string name;
+      84           2 :   parse("NAME", name);
+      85             :   double value;
+      86           2 :   parse("VALUE", value);
+      87           2 :   plumed.passMap[name] = value;
+      88           2 : }
+      89             : 
+      90             : }
+      91             : }
+      92             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Shadow.cpp.func-sort-c.html b/coverage/isdb/Shadow.cpp.func-sort-c.html new file mode 100644 index 000000000000..e780d4137c71 --- /dev/null +++ b/coverage/isdb/Shadow.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Shadow.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Shadow.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:65710.5 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb6Shadow16update_referenceEv0
_ZN4PLMD4isdb6Shadow9calculateEv0
_ZN4PLMD4isdb6ShadowC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb6ShadowC2ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb6Shadow16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Shadow.cpp.func.html b/coverage/isdb/Shadow.cpp.func.html new file mode 100644 index 000000000000..74abe4851b1f --- /dev/null +++ b/coverage/isdb/Shadow.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Shadow.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Shadow.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:65710.5 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4isdb6Shadow16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD4isdb6Shadow16update_referenceEv0
_ZN4PLMD4isdb6Shadow9calculateEv0
_ZN4PLMD4isdb6ShadowC1ERKNS_13ActionOptionsE0
_ZN4PLMD4isdb6ShadowC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/Shadow.cpp.gcov.html b/coverage/isdb/Shadow.cpp.gcov.html new file mode 100644 index 000000000000..dc2151a212fe --- /dev/null +++ b/coverage/isdb/Shadow.cpp.gcov.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage - isdb/Shadow.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdb - Shadow.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:65710.5 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2022 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "colvar/Colvar.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Communicator.h"
+      26             : #include "tools/Pbc.h"
+      27             : #include "tools/RMSD.h"
+      28             : #include <string>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace isdb {
+      32             : 
+      33             : //+PLUMEDOC ISDB_COLVAR SHADOW
+      34             : /*
+      35             : Communicate atoms positions among replicas and calculate the \ref RMSD with respect to a mother (reference) simulation.
+      36             : 
+      37             : The option \ref UPDATE allows to specify the stride for communication between mother and replica systems.
+      38             : The flag \ref REFERENCE needs to be specified in the input file of the mother replica.
+      39             : This action must be run in a multi-replica framework (such as the -multi option in GROMACS).
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : In this example, we perform a simulation of a RNA molecule using two replicas: a mother and a shadow replica.
+      44             : The mother simulation communicates the coordinates of the RNA backbone to the replica every 100 steps.
+      45             : The RMSD of the replica with respect to the mother is calculated on the RNA backbone atoms and an \ref UPPER_WALLS is applied at 0.2 nm.
+      46             : The mother replica contains also the \ref UPPER_WALLS action. However, the forces on the RNA atoms of the mother replica are automatically set to zero
+      47             : inside the \ref SHADOW action.
+      48             : 
+      49             : The input file for the mother simulation looks as follows:
+      50             : 
+      51             : \plumedfile
+      52             : # Reference PDB
+      53             : MOLINFO STRUCTURE=conf_emin_PLUMED.pdb WHOLE
+      54             : # Define RNA nucleic backbone
+      55             : rna: GROUP ATOMS=1,2,5,6,33,36,37,40,41,67,70,71,74,75,98,101,102,105,106,131,134,135,138,139,165,168,169,172,173,198,201,202,205,206,228,231,232,235,236,259,262,263,266,267,289,292,293,296,297,323,326,327,330,331,356,359,360,363,364,390,393,394,397,398,421,424,425,428,429,452,455,456,459,460,482,485,486,489,490,516,519,520,523,524,550,553,554,557,558,584,587,588,591,592,617,620,621,624,625,651,654,655,658,659,682,685,686,689,690,712,715,716,719,720,743,746,747,750,751,773,776,777,780,781,804,807,808,811,812,834,837,838,841,842,868,871,872,875,876,899,902,903,906,907
+      56             : # Reconstruct RNA PBC
+      57             : WHOLEMOLECULES ENTITY0=rna EMST STRIDE=1
+      58             : 
+      59             : # Define shadow RMSD on RNA backbone
+      60             : rmsd: SHADOW ATOMS=rna NOPBC UPDATE=100 REFERENCE
+      61             : # Add upper wall - derivatives are set to zero inside SHADOW action
+      62             : uws: UPPER_WALLS ARG=rmsd AT=0.2 KAPPA=10000.0 STRIDE=1
+      63             : 
+      64             : # Print useful info
+      65             : PRINT FILE=COLVAR STRIDE=500 ARG=rmsd,uws.bias
+      66             : \endplumedfile
+      67             : 
+      68             : while the input file for a shadow replica looks like:
+      69             : 
+      70             : \plumedfile
+      71             : # Reference PDB
+      72             : MOLINFO STRUCTURE=conf_emin_PLUMED.pdb WHOLE
+      73             : # Define RNA nucleic backbone
+      74             : rna: GROUP ATOMS=1,2,5,6,33,36,37,40,41,67,70,71,74,75,98,101,102,105,106,131,134,135,138,139,165,168,169,172,173,198,201,202,205,206,228,231,232,235,236,259,262,263,266,267,289,292,293,296,297,323,326,327,330,331,356,359,360,363,364,390,393,394,397,398,421,424,425,428,429,452,455,456,459,460,482,485,486,489,490,516,519,520,523,524,550,553,554,557,558,584,587,588,591,592,617,620,621,624,625,651,654,655,658,659,682,685,686,689,690,712,715,716,719,720,743,746,747,750,751,773,776,777,780,781,804,807,808,811,812,834,837,838,841,842,868,871,872,875,876,899,902,903,906,907
+      75             : # Reconstruct RNA PBC
+      76             : WHOLEMOLECULES ENTITY0=rna EMST STRIDE=1
+      77             : 
+      78             : # Define shadow RMSD on RNA backbone
+      79             : rmsd: SHADOW ATOMS=rna NOPBC UPDATE=100
+      80             : # Add upper wall
+      81             : uws: UPPER_WALLS ARG=rmsd AT=0.2 KAPPA=10000.0 STRIDE=1
+      82             : 
+      83             : # Print useful info
+      84             : PRINT FILE=COLVAR STRIDE=500 ARG=rmsd,uws.bias
+      85             : \endplumedfile
+      86             : 
+      87             : */
+      88             : //+ENDPLUMEDOC
+      89             : 
+      90             : class Shadow : public Colvar {
+      91             : // private stuff
+      92             :   bool isreference_;
+      93             :   unsigned nupdate_;
+      94             :   bool pbc_;
+      95             :   bool first_time_;
+      96             : // RMSD object
+      97             :   PLMD::RMSD rmsd_;
+      98             : // parallel stuff
+      99             :   unsigned size_;
+     100             :   unsigned rank_;
+     101             : // update reference
+     102             :   void update_reference();
+     103             : 
+     104             : public:
+     105             :   static void registerKeywords( Keywords& keys );
+     106             :   explicit Shadow(const ActionOptions&);
+     107             : // active methods:
+     108             :   void calculate() override;
+     109             : };
+     110             : 
+     111             : PLUMED_REGISTER_ACTION(Shadow,"SHADOW")
+     112             : 
+     113           2 : void Shadow::registerKeywords( Keywords& keys ) {
+     114           2 :   Colvar::registerKeywords( keys );
+     115           4 :   keys.add("atoms","ATOMS","atoms for which we calculate the shadow RMSD");
+     116           4 :   keys.add("compulsory","UPDATE","stride for updating reference coordinates");
+     117           4 :   keys.addFlag("REFERENCE",false,"this is the reference replica");
+     118           2 : }
+     119             : 
+     120           0 : Shadow::Shadow(const ActionOptions&ao):
+     121             :   PLUMED_COLVAR_INIT(ao),
+     122           0 :   isreference_(false), nupdate_(1), pbc_(true), first_time_(true)
+     123             : {
+     124             :   // list of atoms
+     125             :   std::vector<AtomNumber> atoms;
+     126           0 :   parseAtomList("ATOMS",atoms);
+     127             :   // update stride
+     128           0 :   parse("UPDATE",nupdate_);
+     129             : 
+     130             :   // is this the reference replica
+     131           0 :   parseFlag("REFERENCE",isreference_);
+     132             : 
+     133             :   // periodic boundary conditions
+     134           0 :   bool nopbc=!pbc_;
+     135           0 :   parseFlag("NOPBC",nopbc);
+     136           0 :   pbc_=!nopbc;
+     137             : 
+     138             :   // set intra-replica (openmp) parallel stuff
+     139           0 :   size_ = comm.Get_size();
+     140           0 :   rank_ = comm.Get_rank();
+     141             : 
+     142             :   // get number of (MPI) replicas
+     143           0 :   int nrep = 0;
+     144           0 :   int replica = 0;
+     145             :   // only if openmp master
+     146           0 :   if(rank_==0) {
+     147           0 :     nrep    = multi_sim_comm.Get_size();
+     148           0 :     replica = multi_sim_comm.Get_rank();
+     149             :   }
+     150           0 :   comm.Sum(&nrep,1);
+     151           0 :   comm.Sum(&replica,1);
+     152             :   // check number of replicas
+     153             :   //if(nrep<2) error("SHADOW must be used with at least two replicas");
+     154             : 
+     155           0 :   checkRead();
+     156             : 
+     157           0 :   log.printf("  atoms involved : ");
+     158           0 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial());
+     159           0 :   log.printf("\n");
+     160           0 :   log.printf("  stride for updating reference coordinates : %d\n", nupdate_);
+     161           0 :   log.printf("  number of replicas : %d\n", nrep);
+     162           0 :   log.printf("  replica id : %d\n", replica);
+     163           0 :   if(isreference_) log.printf("  this is the reference replica\n");
+     164             : 
+     165             :   // add value and set periodicity
+     166           0 :   addValueWithDerivatives(); setNotPeriodic();
+     167             : 
+     168             :   // request atoms
+     169           0 :   requestAtoms(atoms);
+     170           0 : }
+     171             : 
+     172           0 : void Shadow::update_reference()
+     173             : {
+     174             : // number of atoms
+     175             :   unsigned natoms = getNumberOfAtoms();
+     176             : // initialize rmsd variables
+     177           0 :   std::vector<double> align(natoms,1.0);
+     178           0 :   std::vector<double> displace(natoms,1.0);
+     179           0 :   std::vector<Vector> reference(natoms);
+     180             : 
+     181             : // first get the reference coordinates
+     182             : // if master openmp task
+     183           0 :   if(rank_==0) {
+     184             :     // if reference replica
+     185           0 :     if(isreference_) reference = getPositions();
+     186             :     // share coordinates
+     187           0 :     multi_sim_comm.Sum(&reference[0][0], 3*natoms);
+     188             :   }
+     189             : // now intra replica (openmp) communication
+     190           0 :   if(size_>1) comm.Sum(&reference[0][0], 3*natoms);
+     191             : 
+     192             : // clear the rmsd object
+     193           0 :   rmsd_.clear();
+     194             : // and initialize it
+     195           0 :   rmsd_.set(align,displace,reference,"OPTIMAL");
+     196           0 : }
+     197             : 
+     198           0 : void Shadow::calculate()
+     199             : {
+     200             :   // make whole
+     201           0 :   if(pbc_) makeWhole();
+     202             : 
+     203             :   // if it is time, update reference coordinates
+     204           0 :   if(first_time_ || getStep()%nupdate_==0) {
+     205           0 :     update_reference();
+     206           0 :     first_time_ = false;
+     207             :   }
+     208             : 
+     209             :   // calculate RMSD and derivatives
+     210           0 :   std::vector<Vector> derivatives(getNumberOfAtoms());
+     211           0 :   double rmsd = rmsd_.calculate(getPositions(), derivatives);
+     212             : 
+     213             :   // set RMSD value
+     214           0 :   setValue(rmsd);
+     215             :   // if this is not the reference replica, add derivatives
+     216           0 :   if(!isreference_) {
+     217           0 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) setAtomsDerivatives(i, derivatives[i]);
+     218             :   }
+     219             :   // set virial
+     220           0 :   setBoxDerivativesNoPbc();
+     221           0 : }
+     222             : 
+     223             : }
+     224             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/index-sort-f.html b/coverage/isdb/index-sort-f.html new file mode 100644 index 000000000000..6dae4cc9c77b --- /dev/null +++ b/coverage/isdb/index-sort-f.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:87821142776.9 %
Date:2024-02-22 21:58:45Functions:16323569.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EMMIVox.cpp +
5.6%5.6%
+
5.6 %36 / 6483.8 %1 / 26
Rescale.cpp +
11.3%11.3%
+
11.3 %21 / 1868.3 %1 / 12
Shadow.cpp +
10.5%10.5%
+
10.5 %6 / 5720.0 %1 / 5
Selector.cpp +
84.6%84.6%
+
84.6 %11 / 1350.0 %2 / 4
Caliber.cpp +
78.9%78.9%
+
78.9 %116 / 14762.5 %5 / 8
EMMI.cpp +
75.6%75.6%
+
75.6 %589 / 77974.4 %29 / 39
FretEfficiency.cpp +
94.4%94.4%
+
94.4 %34 / 3675.0 %3 / 4
Select.cpp +
100.0%
+
100.0 %19 / 1975.0 %3 / 4
PRE.cpp +
92.2%92.2%
+
92.2 %119 / 12980.0 %4 / 5
NOE.cpp +
98.1%98.1%
+
98.1 %102 / 10480.0 %4 / 5
Jcoupling.cpp +
93.0%93.0%
+
93.0 %160 / 17280.0 %4 / 5
MetainferenceBase.cpp +
85.2%85.2%
+
85.2 %754 / 88582.1 %23 / 28
RDC.cpp +
93.9%93.9%
+
93.9 %170 / 18183.3 %5 / 6
Metainference.cpp +
84.3%84.3%
+
84.3 %739 / 87788.9 %24 / 27
SAXS.cpp +
79.9%79.9%
+
79.9 %4919 / 615491.3 %21 / 23
CS2Backbone.cpp +
94.7%94.7%
+
94.7 %916 / 96795.7 %22 / 23
MetainferenceBase.h +
97.3%97.3%
+
97.3 %71 / 73100.0 %11 / 11
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/index-sort-l.html b/coverage/isdb/index-sort-l.html new file mode 100644 index 000000000000..917beb04cefe --- /dev/null +++ b/coverage/isdb/index-sort-l.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:87821142776.9 %
Date:2024-02-22 21:58:45Functions:16323569.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
EMMIVox.cpp +
5.6%5.6%
+
5.6 %36 / 6483.8 %1 / 26
Shadow.cpp +
10.5%10.5%
+
10.5 %6 / 5720.0 %1 / 5
Rescale.cpp +
11.3%11.3%
+
11.3 %21 / 1868.3 %1 / 12
EMMI.cpp +
75.6%75.6%
+
75.6 %589 / 77974.4 %29 / 39
Caliber.cpp +
78.9%78.9%
+
78.9 %116 / 14762.5 %5 / 8
SAXS.cpp +
79.9%79.9%
+
79.9 %4919 / 615491.3 %21 / 23
Metainference.cpp +
84.3%84.3%
+
84.3 %739 / 87788.9 %24 / 27
Selector.cpp +
84.6%84.6%
+
84.6 %11 / 1350.0 %2 / 4
MetainferenceBase.cpp +
85.2%85.2%
+
85.2 %754 / 88582.1 %23 / 28
PRE.cpp +
92.2%92.2%
+
92.2 %119 / 12980.0 %4 / 5
Jcoupling.cpp +
93.0%93.0%
+
93.0 %160 / 17280.0 %4 / 5
RDC.cpp +
93.9%93.9%
+
93.9 %170 / 18183.3 %5 / 6
FretEfficiency.cpp +
94.4%94.4%
+
94.4 %34 / 3675.0 %3 / 4
CS2Backbone.cpp +
94.7%94.7%
+
94.7 %916 / 96795.7 %22 / 23
MetainferenceBase.h +
97.3%97.3%
+
97.3 %71 / 73100.0 %11 / 11
NOE.cpp +
98.1%98.1%
+
98.1 %102 / 10480.0 %4 / 5
Select.cpp +
100.0%
+
100.0 %19 / 1975.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/isdb/index.html b/coverage/isdb/index.html new file mode 100644 index 000000000000..6afc2862ce6a --- /dev/null +++ b/coverage/isdb/index.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - isdb + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - isdbHitTotalCoverage
Test:plumed test coverageLines:87821142776.9 %
Date:2024-02-22 21:58:45Functions:16323569.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
CS2Backbone.cpp +
94.7%94.7%
+
94.7 %916 / 96795.7 %22 / 23
Caliber.cpp +
78.9%78.9%
+
78.9 %116 / 14762.5 %5 / 8
EMMI.cpp +
75.6%75.6%
+
75.6 %589 / 77974.4 %29 / 39
EMMIVox.cpp +
5.6%5.6%
+
5.6 %36 / 6483.8 %1 / 26
FretEfficiency.cpp +
94.4%94.4%
+
94.4 %34 / 3675.0 %3 / 4
Jcoupling.cpp +
93.0%93.0%
+
93.0 %160 / 17280.0 %4 / 5
Metainference.cpp +
84.3%84.3%
+
84.3 %739 / 87788.9 %24 / 27
MetainferenceBase.cpp +
85.2%85.2%
+
85.2 %754 / 88582.1 %23 / 28
MetainferenceBase.h +
97.3%97.3%
+
97.3 %71 / 73100.0 %11 / 11
NOE.cpp +
98.1%98.1%
+
98.1 %102 / 10480.0 %4 / 5
PRE.cpp +
92.2%92.2%
+
92.2 %119 / 12980.0 %4 / 5
RDC.cpp +
93.9%93.9%
+
93.9 %170 / 18183.3 %5 / 6
Rescale.cpp +
11.3%11.3%
+
11.3 %21 / 1868.3 %1 / 12
SAXS.cpp +
79.9%79.9%
+
79.9 %4919 / 615491.3 %21 / 23
Select.cpp +
100.0%
+
100.0 %19 / 1975.0 %3 / 4
Selector.cpp +
84.6%84.6%
+
84.6 %11 / 1350.0 %2 / 4
Shadow.cpp +
10.5%10.5%
+
10.5 %6 / 5720.0 %1 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/LogMFD.cpp.func-sort-c.html b/coverage/logmfd/LogMFD.cpp.func-sort-c.html new file mode 100644 index 000000000000..6499c107f51e --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - logmfd/LogMFD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfd - LogMFD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32637187.9 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6logmfd6LogMFDC2ERKNS_13ActionOptionsE0
_ZN4PLMD6logmfd6LogMFDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd6LogMFD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6logmfd6LogMFD8updateVSEv5
_ZN4PLMD6logmfd6LogMFD9updateNVEEv5
_ZN4PLMD6logmfd6LogMFD9updateNVTEv5
_ZN4PLMD6logmfd6LogMFD10updateWorkEv15
_ZN4PLMD6logmfd6LogMFD13calcMeanForceEv15
_ZN4PLMD6logmfd6LogMFD8calcClogEv40
_ZN4PLMD6logmfd6LogMFD8calcFlogEv55
_ZN4PLMD6logmfd6LogMFD8calcEkinEv83
_ZN4PLMD6logmfd6LogMFD6updateEv1500
_ZN4PLMD6logmfd6LogMFD9calculateEv1500
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/LogMFD.cpp.func.html b/coverage/logmfd/LogMFD.cpp.func.html new file mode 100644 index 000000000000..6af9ad5fdf39 --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - logmfd/LogMFD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfd - LogMFD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32637187.9 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6logmfd6LogMFD10updateWorkEv15
_ZN4PLMD6logmfd6LogMFD13calcMeanForceEv15
_ZN4PLMD6logmfd6LogMFD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD6logmfd6LogMFD6updateEv1500
_ZN4PLMD6logmfd6LogMFD8calcClogEv40
_ZN4PLMD6logmfd6LogMFD8calcEkinEv83
_ZN4PLMD6logmfd6LogMFD8calcFlogEv55
_ZN4PLMD6logmfd6LogMFD8updateVSEv5
_ZN4PLMD6logmfd6LogMFD9calculateEv1500
_ZN4PLMD6logmfd6LogMFD9updateNVEEv5
_ZN4PLMD6logmfd6LogMFD9updateNVTEv5
_ZN4PLMD6logmfd6LogMFDC1ERKNS_13ActionOptionsE3
_ZN4PLMD6logmfd6LogMFDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/LogMFD.cpp.gcov.html b/coverage/logmfd/LogMFD.cpp.gcov.html new file mode 100644 index 000000000000..ca19abfa5fa7 --- /dev/null +++ b/coverage/logmfd/LogMFD.cpp.gcov.html @@ -0,0 +1,1317 @@ + + + + + + + + LCOV - plumed test coverage - logmfd/LogMFD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfd - LogMFD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32637187.9 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019
+       3             : National Institute of Advanced Industrial Science and Technology (AIST), Japan.
+       4             : This file contains module for LogMFD method proposed by Tetsuya Morishita(AIST).
+       5             : 
+       6             : The LogMFD module is free software: you can redistribute it and/or modify
+       7             : it under the terms of the GNU Lesser General Public License as published by
+       8             : the Free Software Foundation, either version 3 of the License, or
+       9             : (at your option) any later version.
+      10             : 
+      11             : The LogMFD module is distributed in the hope that it will be useful,
+      12             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             : GNU Lesser General Public License for more details.
+      15             : 
+      16             : You should have received a copy of the GNU Lesser General Public License
+      17             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : 
+      20             : //+PLUMEDOC LOGMFDMOD_BIAS LOGMFD
+      21             : /*
+      22             : Used to perform LogMFD, LogPD, and TAMD/d-AFED.
+      23             : 
+      24             : \section LogMFD LogMFD
+      25             : 
+      26             : Consider a physical system of \f$N_q\f$ particles, for which the Hamiltonian is given as
+      27             : 
+      28             : \f[
+      29             :   {H_{\rm MD}}\left( {\bf{\Gamma}} \right) = \sum\limits_{j = 1}^{{N_q}} {\frac{{{\bf{p}}_j^2}}{{2{m_j}}}}  + \Phi \left( {\bf{q}} \right)
+      30             : \f]
+      31             : 
+      32             : where \f${\bf q}_j\f$, \f${\bf p}_j\f$ (\f$\bf{\Gamma}={\bf q},{\bf p}\f$), and \f$m_j\f$ are the position, momentum, and mass of particle \f$j\f$ respectively,
+      33             : and \f$\Phi\f$ is the potential energy function for \f${\bf q}\f$.
+      34             : The free energy \f$F({\bf X})\f$ as a function of a set of \f$N\f$ collective variables (CVs) is given as
+      35             : 
+      36             : \f{eqnarray*}{
+      37             :   F\left( {{\bf X}} \right) &=&  - {k_B}T\log \int {\exp \left[ { - \beta {H_{\rm MD}}} \right]\prod\limits_{i = 1}^N {\delta \left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)} d{\bf{\Gamma }}} \\
+      38             :   &\simeq&  - {k_B}T\log \int {\exp \left[ { - \beta \left\{ {{H_{\rm MD}} + \sum\limits_i^N {\frac{{{K_i}}}{2}{{\left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)}^2}} } \right\}} \right]} d{\bf{\Gamma }}
+      39             : \f}
+      40             : 
+      41             : where \f$\bf{s}\f$ are the CVs, \f$k_B\f$ is Boltzmann constant, \f$\beta=1/k_BT\f$,
+      42             : and \f$K_i\f$ is the spring constant which is large enough to invoke
+      43             : 
+      44             : \f[
+      45             :  \delta \left( x \right) = \lim_{k \to \infty } \sqrt {\beta k/2\pi} \exp \left( -\beta kx^2/2 \right)
+      46             : \f]
+      47             : 
+      48             : In mean-force dynamics, \f${\bf X}\f$ are treated as fictitious dynamical variables, which are associated with the following Hamiltonian,
+      49             : 
+      50             : \f[
+      51             :  {H_{\rm log}} = \sum\limits_{i = 1}^N {\frac{{P_{{X_i}}^2}}{{2{M_i}}} + \Psi \left( {{\bf X}} \right)}
+      52             : \f]
+      53             : 
+      54             : where \f${P_{{X_i}}}\f$  and \f$M_i\f$ are the momentum and mass of \f$X_i\f$, respectively, and \f$\Psi\f$ is the potential function for \f${\bf X}\f$.
+      55             : We assume that \f$\Psi\f$ is a functional of \f$F({\bf X})\f$; \f$Ψ[F({\bf X})]\f$. The simplest form of \f$\Psi\f$ is \f$\Psi = F({\bf X})\f$,
+      56             : which corresponds to TAMD/d-AFED \cite AbramsJ2008, \cite Maragliano2006 (or the extended Lagrangian dynamics in the limit of the adiabatic decoupling between \f$\bf{q}\f$ and \f${\bf X}\f$).
+      57             :  In the case of LogMFD, the following form of \f$\Psi\f$ is introduced \cite MorishitaLogMFD;
+      58             : 
+      59             : 
+      60             : \f[
+      61             :   {\Psi _{\rm log}}\left( {{\bf X}} \right) = \gamma \log \left[ {\alpha F\left( {{\bf X}} \right) + 1} \right]
+      62             : \f]
+      63             : 
+      64             : where \f$\alpha\f$ (ALPHA) and \f$\gamma\f$ (GAMMA) are positive parameters. The logarithmic form of \f$\Psi_{\rm log}\f$ ensures the dynamics of \f${\bf X}\f$ on a much smoother energy surface [i.e., \f$\Psi_{\rm log}({\bf X})\f$] than \f$F({\bf X})\f$, thus enhancing the sampling in the \f${\bf X}\f$-space. The parameters \f$\alpha\f$ and \f$\gamma\f$ determine the degree of flatness of \f$\Psi_{\rm log}\f$, but adjusting only \f$\alpha\f$ is normally sufficient to have a relatively flat surface (with keeping the relation \f$\gamma=1/\alpha\f$).
+      65             : 
+      66             : The equation of motion for \f$X_i\f$ in LogMFD (no thermostat) is
+      67             : 
+      68             : \f[
+      69             :  {M_i}{\ddot X_i} =  - \left( {\frac{{\alpha \gamma }}{{\alpha F + 1}}} \right)\frac{{\partial F}}{{\partial {X_i}}}
+      70             : \f]
+      71             : 
+      72             : where \f$-\partial F/\partial X_i\f$  is evaluated as a canonical average under the condition that \f${\bf X}\f$ is fixed;
+      73             : 
+      74             : \f{eqnarray*}{
+      75             :  - \frac{{\partial F}}{{\partial {X_i}}} &\simeq& \frac{1}{Z}\int {{K_i}\left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)\exp \left[ { - \beta \left\{ {{H_{\rm MD}} + \sum\limits_i^N {\frac{{{K_i}}}{2}{{\left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)}^2}} } \right\}} \right]} d{\bf{\Gamma }}\\
+      76             :  &\equiv& {\left\langle {{K_i}\left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)} \right\rangle _{{\bf X}}}
+      77             : \f}
+      78             : 
+      79             : where
+      80             : 
+      81             : \f[
+      82             :  Z = \int {\exp \left[ { - \beta \left\{ {{H_{\rm MD}} + \sum\limits_i^N {\frac{{{K_i}}}{2}{{\left( {{s_i}\left( {{\bf q}} \right) - {X_i}} \right)}^2}} } \right\}} \right]} d{\bf{\Gamma }}
+      83             : \f]
+      84             : 
+      85             : The mean-force (MF) is practically evaluated by performing a shot-time canonical MD run of \f$N_m\f$ steps each time \f${\bf X}\f$ is updated according to the equation of motion for \f${\bf X}\f$.
+      86             : 
+      87             : If the canonical average for the MF is effectively converged, the dynamical variables \f${\bf q}\f$ and \f${\bf X}\f$ are decoupled and they evolve adiabatically, which can be exploited for the on-the-fly evaluation of \f$F({\bf X})\f$. I.e., \f$H_{\rm log}\f$ should be a constant of motion in this case, thus \f$F({\bf X})\f$ can be evaluated each time \f${\bf X}\f$ is updated as
+      88             : 
+      89             : 
+      90             : \f[
+      91             :  F\left( {{{\bf X}}\left( t \right)} \right) = \frac{1}{\alpha} \left[
+      92             :   \exp \frac{1}{\gamma} \left\{ \left( H_{\rm log} - \sum_i \frac{P_{X_i}^2}{2M_i} \right) \right\} - 1 \right]
+      93             : \f]
+      94             : 
+      95             : 
+      96             : This means that \f$F({\bf X})\f$ can be constructed without post processing (on-the-fly free energy reconstruction). Note that the on-the-fly free energy reconstruction is also possible in TAMD/d-AFED if the Hamiltonian-like conserved quantity is available (e.g., the Nose-Hoover type dynamics).
+      97             : 
+      98             : 
+      99             : 
+     100             : \section LogPD LogPD
+     101             : 
+     102             : 
+     103             : The accuracy in the MF is critical to the on-the-fly free energy reconstruction. To improve the evaluation of the MF, parallel-dynamics (PD) is incorporated into LogMFD, leading to logarithmic parallel-dynamics (LogPD) \cite MorishitaLogPD.
+     104             : 
+     105             : 
+     106             : In PD, the MF is evaluated by a non-equilibrium path-ensemble based on the Crooks-Jarzynski non-equilibrium work relation. To this end, multiple replicas of the MD system which run in parallel are introduced. The CVs [\f${\bf s}({\bf q})\f$] in each replica is restrained to the same value of \f${\bf X}(t)\f$. A canonical MD run with \f$N_m\f$ steps is performed in each replica, then the MF on \f$X_i\f$ is evaluated using the MD trajectories from all replicas.
+     107             : The MF is practically calculated as
+     108             : 
+     109             : 
+     110             : \f[
+     111             :  - \frac{{\partial F}}{{\partial {X_i}}} = \sum\limits_{k = 1}^{{N_r}} {{W_k}} \sum\limits_{n = 1}^{{N_m}} {\frac{1}{{{N_m}}}{K_i}\left[ {{s_i}\left( {{{\bf q}}_n^k} \right) - {X_i}} \right]}
+     112             : \f]
+     113             : 
+     114             : 
+     115             : 
+     116             : where \f${\bf q}^k_n\f$  indicates the \f${\bf q}\f$-configuration at time step \f$n\f$ in the \f$N_m\f$-step shot-time MD run in the \f$k\f$th replica among \f$N_r\f$ replicas. \f$W_k\f$ is given as
+     117             : 
+     118             : \f[
+     119             :  {W_k} = \frac{{{e^{ - \beta {w_k}\left( t \right)}}}}{{\sum\limits_{k=1}^{{N_r}} {{e^{ - \beta {w_k}\left( t \right)}}} }}
+     120             : \f]
+     121             : 
+     122             : 
+     123             : where
+     124             : 
+     125             : 
+     126             : \f[
+     127             :  {w_k}\left( t \right) = \int\limits_{{X_0}}^{X\left( t \right)} {\sum\limits_{i=1}^N {\frac{{\partial H_{\rm MD}^k}}{{\partial {X_i}}}d{X_i}} }
+     128             : \f]
+     129             : 
+     130             : \f[
+     131             :  H_{\rm MD}^k\left( {{\bf{\Gamma }},{{\bf X}}} \right) = {H_{\rm MD}}\left( {{{\bf{\Gamma }}^k}} \right) + \sum\limits_{i = 1}^N {\frac{{{K_i}}}{2}{{\left( {s_i^k - {X_i}} \right)}^2}}
+     132             : \f]
+     133             : 
+     134             : and \f$s^k_i\f$ is the \f$i\f$th CV in the \f$k\f$th replica.
+     135             : 
+     136             : \f$W_k\f$ comes from the Crooks-Jarzynski non-equilibrium work relation by which we can evaluate an equilibrium ensemble average from a set of non-equilibrium trajectories. Note that, to avoid possible numerical errors in the exponential function, the following form of \f$W_k\f$ is instead used in PLUMED,
+     137             : 
+     138             : \f[
+     139             :  {W_k}\left( t \right) = \frac{{\exp \left[ { - \beta \left\{ {{w_k}\left( t \right) - {w_{\min }}\left( t \right)} \right\}} \right]}}{{\sum\nolimits_k {\exp \left[ { - \beta \left\{ {{w_k}\left( t \right) - {w_{\min }}\left( t \right)} \right\}} \right]} }}
+     140             : \f]
+     141             : 
+     142             : where
+     143             : 
+     144             : \f[
+     145             :  {w_{\min }}\left( t \right) = {\rm Min}_k\left[ {{w_k}\left( t \right)} \right]
+     146             : \f]
+     147             : 
+     148             : 
+     149             : With the MF evaluated using the PD approach, free energy profiles can be reconstructed more efficiently (requiring less elapsed computing time) in LogPD than with a single MD system in LogMFD. In the case that there exist more than one stable state separated by high energy barriers in the hidden subspace orthogonal to the CV-subspace, LogPD is particularly of use to incorporate all the contributions from such hidden states with appropriate weights (in the limit \f$N_r\to\infty\f$ ).
+     150             : 
+     151             : Note that LogPD calculations should always be initiated with an equilibrium \f${\bf q}\f$-configuration in each replica, because the Crooks-Jarzynski non-equilibrium work relation is invoked. Also note that LogPD is currently available only with Gromacs, while LogMFD can be performed with LAMMPS, Gromacs, Quantum Espresso, NAMD, and so on.
+     152             : 
+     153             : \section Thermostat Using LogMFD/PD with a thermostat
+     154             : 
+     155             : Introducing a thermostat on \f${\bf X}\f$ is often recommended in LogMFD/PD to maintain the adiabatic decoupling between \f${\bf q}\f$ and \f${\bf X}\f$. In the framework of the LogMFD approach, the Nose-Hoover type thermostat and the Gaussian isokinetic (velocity scaling) thermostat can be used to control the kinetic energy of \f${\bf X}\f$.
+     156             : 
+     157             : \subsection Nose-Hoover Nose-Hoover LogMFD/PD
+     158             : 
+     159             : The equation of motion for \f$X_i\f$ coupled to a Nose-Hoover thermostat variable \f$\eta\f$ (single heat bath) is
+     160             : 
+     161             : \f[
+     162             :  {M_i}{\ddot X_i} =  - \left( {\frac{{\alpha \gamma }}{{\alpha F + 1}}} \right)\frac{{\partial F}}{{\partial {X_i}}} - {M_i}{\dot X_i}\dot \eta
+     163             : \f]
+     164             : 
+     165             : The equation of motion for \f$\eta\f$ is
+     166             : 
+     167             : \f[
+     168             :  Q\ddot \eta  = \sum\limits_{i = 1}^N {\frac{{P_{{X_i}}^2}}{{{M_i}}} - N{k_B}T}
+     169             : \f]
+     170             : 
+     171             : where \f$N\f$ is the number of the CVs. Since the following pseudo-Hamiltonian is a constant of motion in Nose-Hoover LogMFD/PD,
+     172             : 
+     173             : \f[
+     174             :  H_{\rm log}^{\rm NH} = \sum\limits_{i = 1}^N {\frac{{P_{{X_i}}^2}}{{2{M_i}}} + \gamma \log \left[ {\alpha F\left( {{\bf X}} \right) + 1} \right] + \frac{1}{2}Q{{\dot \eta }^2} + N{k_B}T\eta}
+     175             : \f]
+     176             : 
+     177             : \f$F({\bf X}(t))\f$ is obtained at each MFD step as
+     178             : 
+     179             : \f[
+     180             :  F\left( {{{\bf X}}\left( t \right)} \right) = \frac{1}{\alpha }\left[ {\exp \left\{ {{{ \frac{1}{\gamma} \left( {H_{\rm log}^{\rm NH} - \sum_i {\frac{{P_{{X_i}}^2}}{{2{M_i}}}}  - \frac{1}{2}Q{{\dot \eta }^2} - N{k_B}T\eta} \right)}  }} \right\} - 1} \right]
+     181             : \f]
+     182             : 
+     183             : 
+     184             : 
+     185             : \subsection VS Velocity scaling LogMFD/PD
+     186             : 
+     187             : The velocity scaling algorithm (which is equivalent to the Gaussian isokinetic dynamics in the limit \f$\Delta t\to 0\f$) can also be employed to control the velocity of \f${\bf X}\f$, \f$\bf{V}_x\f$.
+     188             : 
+     189             : The following algorithm is introduced to perform isokinetic LogMFD calculations \cite MorishitaVsLogMFD;
+     190             : 
+     191             : \f{eqnarray*}{
+     192             : {V_{{X_i}}}\left( {{t_{n + 1}}} \right)
+     193             : &=&
+     194             :  V_{X_i}^\prime \left( {{t_n}} \right) + \Delta t \left[
+     195             :   { - \left( {\frac{{\alpha \gamma }}{{\alpha F\left( {{t_n}} \right) + 1}}} \right)
+     196             :   \frac{{\partial F\left( {{t_n}} \right)}}{{\partial {X_i}}}}
+     197             :  \right]\\
+     198             : S\left( {{t_{n + 1}}} \right)
+     199             : &=&
+     200             :  \sqrt {\frac{{N{k_B}T}}{{\sum\limits_i {{M_i}V_{{X_i}}^2\left( {{t_{n + 1}}} \right)} }}} \\
+     201             : {V_{{X_i}}}^\prime \left( {{t_{n + 1}}} \right)
+     202             : &=&
+     203             : S\left( {{t_{n + 1}}} \right){V_{{X_i}}}\left( {{t_{n + 1}}} \right)\\
+     204             : {X_i}\left( {{t_{n + 1}}} \right)
+     205             : &=&
+     206             : {X_i}\left( {{t_n}} \right) + \Delta t V_{X_i}^\prime \left( {{t_{n + 1}}} \right)\\
+     207             : {\Psi_{\rm log}}\left( {{t_{n + 1}}} \right)
+     208             : &=&
+     209             : N{k_B}T\log S\left( {{t_{n + 1}}} \right) + {\Psi_{\rm log}}\left( {{t_n}} \right)\\
+     210             : F\left( {{t_{n + 1}}} \right)
+     211             : &=&
+     212             : \frac{1}{\alpha} \left[
+     213             :   \exp \left\{ \Psi_{\rm log} \left( t_{n+1} \right) / \gamma \right\} - 1
+     214             : \right]
+     215             : \f}
+     216             : 
+     217             : Note that \f$V_{X_i}^\prime\left( {{t_0}} \right)\f$ is assumed to be initially given, which meets the following relation,
+     218             : 
+     219             : \f[
+     220             :   \sum\limits_{i = 1}^N M_i V_{X_i}^{\prime 2} \left( t_0 \right)  = N{k_B}{T}
+     221             : \f]
+     222             : 
+     223             : It should be stressed that, in the same way as in the NVE and Nose-Hoover LogMFD/PD, \f$F({\bf X}(t))\f$ can be evaluated at each MFD step (on-the-fly free energy reconstruction) in Velocity Scaling LogMFD/PD.
+     224             : 
+     225             : 
+     226             : \par Examples
+     227             : \section Examples Examples
+     228             : 
+     229             : \subsection Example-LoGMFD Example of LogMFD
+     230             : 
+     231             : The following input file tells plumed to restrain collective variables
+     232             : to the fictitious dynamical variables in LogMFD/PD.
+     233             : 
+     234             : plumed.dat
+     235             : \plumedfile
+     236             : UNITS TIME=fs LENGTH=1.0 ENERGY=kcal/mol MASS=1.0 CHARGE=1.0
+     237             : phi: TORSION ATOMS=5,7,9,15
+     238             : psi: TORSION ATOMS=7,9,15,17
+     239             : 
+     240             : # LogMFD
+     241             : LOGMFD ...
+     242             : LABEL=logmfd
+     243             : ARG=phi,psi
+     244             : KAPPA=1000.0,1000.0
+     245             : DELTA_T=1.0
+     246             : INTERVAL=200
+     247             : TEMP=300.0
+     248             : FLOG=2.0
+     249             : MFICT=5000000,5000000
+     250             : VFICT=3.5e-4,3.5e-4
+     251             : ALPHA=4.0
+     252             : THERMOSTAT=NVE
+     253             : FICT_MAX=3.15,3.15
+     254             : FICT_MIN=-3.15,-3.15
+     255             : ... LOGMFD
+     256             : \endplumedfile
+     257             : 
+     258             : To submit this simulation with Gromacs, use the following command line
+     259             : to execute a LogMFD run with Gromacs-MD.
+     260             : Here topol.tpr is the input file
+     261             : which contains atomic coordinates and Gromacs parameters.
+     262             : 
+     263             : \verbatim
+     264             : gmx_mpi mdrun -s topol.tpr -plumed
+     265             : \endverbatim
+     266             : 
+     267             : This command will output files named logmfd.out and replica.out.
+     268             : 
+     269             : The output file logmfd.out records free energy and all fictitious dynamical variables at every MFD step.
+     270             : 
+     271             : logmfd.out
+     272             : 
+     273             : \verbatim
+     274             : # LogMFD
+     275             : # CVs : phi psi
+     276             : # Mass for CV particles : 5000000.000000 5000000.000000
+     277             : # Mass for thermostat   :   11923.224809
+     278             : # 1:iter_mfd, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,
+     279             : # 6:phi_fict(t), 7:phi_vfict(t), 8:phi_force(t),
+     280             : # 9:psi_fict(t), 10:psi_vfict(t), 11:psi_force(t),
+     281             :        0       2.000000     308.221983       0.000000       0.000000      -2.442363       0.000350       5.522717       2.426650       0.000350       7.443177
+     282             :        1       1.995466     308.475775       0.000000       0.000000      -2.442013       0.000350      -4.406246       2.427000       0.000350      11.531345
+     283             :        2       1.992970     308.615664       0.000000       0.000000      -2.441663       0.000350      -3.346513       2.427350       0.000350      15.763196
+     284             :        3       1.988619     308.859946       0.000000       0.000000      -2.441313       0.000350       6.463092       2.427701       0.000351       6.975422
+     285             : ...
+     286             : \endverbatim
+     287             : 
+     288             : The output file replica.out records all collective variables at every MFD step.
+     289             : 
+     290             : replica.out
+     291             : 
+     292             : \verbatim
+     293             :  Replica No. 0 of 1.
+     294             : # 1:iter_mfd, 2:work, 3:weight,
+     295             : # 4:phi(q)
+     296             : # 5:psi(q)
+     297             :        0    0.000000e+00     1.000000e+00       -2.436841       2.434093
+     298             :        1   -4.539972e-03     1.000000e+00       -2.446420       2.438531
+     299             :        2   -7.038516e-03     1.000000e+00       -2.445010       2.443114
+     300             :        3   -1.139672e-02     1.000000e+00       -2.434850       2.434677
+     301             : ...
+     302             : \endverbatim
+     303             : 
+     304             : \subsection Example-LogPD Example of LogPD
+     305             : 
+     306             : Use the following command line to execute a LogPD run using two MD replicas (note that only Gromacs is currently available for LogPD).
+     307             : Here 0/topol.tpr and 1/topol.tpr are the input files,
+     308             : each containing the atomic coordinates for the corresponding replica and Gromacs parameters. All the directories, 0/ and 1/, should contain the same plumed.dat.
+     309             : 
+     310             : \verbatim
+     311             : mpirun -np 2 gmx_mpi mdrun -s topol -plumed -multidir 0 1
+     312             : \endverbatim
+     313             : 
+     314             : This command will output files named logmfd.out in 0/, and replica.out.0 and replica.out.1 in 0/ and 1/, respectively.
+     315             : 
+     316             : The output file logmfd.out records free energy and all fictitious dynamical variables at every MFD step.
+     317             : 
+     318             : logmfd.out
+     319             : 
+     320             : \verbatim
+     321             : # LogPD, replica parallel of LogMFD
+     322             : # number of replica : 2
+     323             : # CVs : phi psi
+     324             : # Mass for CV particles : 5000000.000000 5000000.000000
+     325             : # Mass for thermostat   :   11923.224809
+     326             : # 1:iter_mfd, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,
+     327             : # 6:phi_fict(t), 7:phi_vfict(t), 8:phi_force(t),
+     328             : # 9:psi_fict(t), 10:psi_vfict(t), 11:psi_force(t),
+     329             :        0       2.000000     308.221983       0.000000       0.000000      -2.417903       0.000350       4.930899       2.451475       0.000350      -3.122024
+     330             :        1       1.999367     308.257404       0.000000       0.000000      -2.417552       0.000350       0.851133       2.451825       0.000350      -1.552718
+     331             :        2       1.999612     308.243683       0.000000       0.000000      -2.417202       0.000350      -1.588175       2.452175       0.000350       1.601274
+     332             :        3       1.999608     308.243922       0.000000       0.000000      -2.416852       0.000350       4.267745       2.452525       0.000350      -4.565621
+     333             : ...
+     334             : \endverbatim
+     335             : 
+     336             : 
+     337             : The output file replica.out.0 records all collective variables and the Jarzynski weight of replica No.0 at every MFD step.
+     338             : 
+     339             : replica.out.0
+     340             : 
+     341             : \verbatim
+     342             : # Replica No. 0 of 2.
+     343             : # 1:iter_mfd, 2:work, 3:weight,
+     344             : # 4:phi(q)
+     345             : # 5:psi(q)
+     346             :        0    0.000000e+00     5.000000e-01       -2.412607       2.446191
+     347             :        1   -4.649101e-06     4.994723e-01       -2.421403       2.451318
+     348             :        2    1.520985e-03     4.983996e-01       -2.420269       2.455049
+     349             :        3    1.588855e-03     4.983392e-01       -2.411081       2.447394
+     350             : ...
+     351             : \endverbatim
+     352             : 
+     353             : The output file replica.out.1 records all collective variables and the Jarzynski weight of replica No.1 at every MFD step.
+     354             : 
+     355             : replica.out.1
+     356             : 
+     357             : \verbatim
+     358             : # Replica No. 1 of 2.
+     359             : # 1:iter_mfd, 2:work, 3:weight,
+     360             : # 4:phi(q)
+     361             : # 5:psi(q)
+     362             :        0    0.000000e+00     5.000000e-01       -2.413336       2.450516
+     363             :        1   -1.263077e-03     5.005277e-01       -2.412009       2.449229
+     364             :        2   -2.295444e-03     5.016004e-01       -2.417322       2.452512
+     365             :        3   -2.371507e-03     5.016608e-01       -2.414078       2.448521
+     366             : ...
+     367             : \endverbatim
+     368             : 
+     369             : */
+     370             : //+ENDPLUMEDOC
+     371             : 
+     372             : #include "bias/Bias.h"
+     373             : #include "core/ActionRegister.h"
+     374             : #include "tools/Communicator.h"
+     375             : 
+     376             : #include <iostream>
+     377             : 
+     378             : using namespace std;
+     379             : using namespace PLMD;
+     380             : using namespace bias;
+     381             : 
+     382             : namespace PLMD {
+     383             : namespace logmfd {
+     384             : /**
+     385             :    \brief class for LogMFD parameters, variables and subroutines.
+     386             :  */
+     387             : class LogMFD : public Bias {
+     388             :   bool firsttime;               ///< flag that indicates first MFD step or not.
+     389             :   int    step_initial;          ///< initial MD step.
+     390             :   int    interval;              ///< input parameter, period of MD steps when fictitious dynamical variables are evolved.
+     391             :   double delta_t;               ///< input parameter, one time step of MFD when fictitious dynamical variables are evolved.
+     392             :   string thermostat;            ///< input parameter, type of thermostat for canonical dyanamics.
+     393             :   double kbt;                   ///< k_B*temperature
+     394             :   double kbtpd;                   ///< k_B*temperature for PD
+     395             : 
+     396             :   int    TAMD;                  ///< input parameter, perform TAMD instead of LogMFD.
+     397             :   double alpha;                 ///< input parameter, alpha parameter for LogMFD.
+     398             :   double gamma;                 ///< input parameter, gamma parameter for LogMFD.
+     399             :   std::vector<double> kappa;    ///< input parameter, strength of the harmonic restraining potential.
+     400             : 
+     401             :   std::vector<double> fict_max; ///< input parameter, maximum of each fictitous dynamical variable.
+     402             :   std::vector<double> fict_min; ///< input parameter, minimum of each fictitous dynamical variable.
+     403             : 
+     404             : 
+     405             :   std::vector<double>  fict;    ///< current values of each fictitous dynamical variable.
+     406             :   std::vector<double> vfict;    ///< current velocity of each fictitous dynamical variable.
+     407             :   std::vector<double> mfict;    ///< mass of each fictitous dynamical variable.
+     408             : 
+     409             :   double xeta;                  ///< current eta variable of thermostat.
+     410             :   double veta;                  ///< current velocity of eta variable of thermostat.
+     411             :   double meta;                  ///< mass of eta variable of thermostat.
+     412             : 
+     413             :   double phivs;                 ///< potential used in VS method
+     414             :   double work;                  ///< current works done by fictitious dynamical variables in this replica.
+     415             :   double weight;                ///< current weight of this replica.
+     416             :   double flog;                  ///< current free energy
+     417             :   double hlog;                  ///< value invariant
+     418             : 
+     419             :   struct {
+     420             :     std::vector<double>  fict;
+     421             :     std::vector<double> vfict;
+     422             :     std::vector<double> ffict;
+     423             :     double xeta;
+     424             :     double veta;
+     425             :     double phivs;
+     426             :     double work;
+     427             :     double weight;
+     428             :   } backup;
+     429             : 
+     430             :   std::vector<double> ffict;    ///< current force of each fictitous dynamical variable.
+     431             :   std::vector<double> fict_ave; ///< averaged values of each collective variable.
+     432             : 
+     433             :   std::vector<Value*>  fictValue; ///< pointers to fictitious dynamical variables
+     434             :   std::vector<Value*> vfictValue; ///< pointers to velocity of fictitious dynamical variables
+     435             : 
+     436             : public:
+     437             :   static void registerKeywords(Keywords& keys);
+     438             : 
+     439             :   explicit LogMFD(const ActionOptions&);
+     440             :   void calculate();
+     441             :   void update();
+     442             :   void updateNVE();
+     443             :   void updateNVT();
+     444             :   void updateVS();
+     445             :   void updateWork();
+     446             :   void calcMeanForce();
+     447             :   double calcEkin();
+     448             :   double calcFlog();
+     449             :   double calcClog();
+     450             : 
+     451             : private:
+     452             :   double sgn( double x ) {
+     453          55 :     return x>0.0 ? 1.0 : x<0.0 ? -1.0 : 0.0;
+     454             :   }
+     455             : };
+     456             : 
+     457             : PLUMED_REGISTER_ACTION(LogMFD,"LOGMFD")
+     458             : 
+     459             : /**
+     460             :    \brief instruction of parameters for Plumed manual.
+     461             : */
+     462           5 : void LogMFD::registerKeywords(Keywords& keys) {
+     463           5 :   Bias::registerKeywords(keys);
+     464           5 :   keys.use("ARG");
+     465          10 :   keys.add("compulsory","INTERVAL",
+     466             :            "Period of MD steps (\\f$N_m\\f$) to update fictitious dynamical variables." );
+     467          10 :   keys.add("compulsory","DELTA_T",
+     468             :            "Time step for the fictitious dynamical variables (DELTA_T=1 often works)." );
+     469          10 :   keys.add("compulsory","THERMOSTAT",
+     470             :            "Type of thermostat for the fictitious dynamical variables. NVE, NVT, VS are available." );
+     471          10 :   keys.add("optional","TEMP",
+     472             :            "Target temperature for the fictitious dynamical variables in LogMFD/PD. "
+     473             :            "It is recommended to set TEMP to be the same as "
+     474             :            "the temperature of the MD system in any thermostated LogMFD/PD run. "
+     475             :            "If not provided, it will be taken from the temperature of the MD system (Gromacs only)." );
+     476             : 
+     477          10 :   keys.add("optional","TAMD",
+     478             :            "When TAMD=1, TAMD/d-AFED calculations can be performed instead of LogMFD. Otherwise, the LogMFD protocol is switched on (default)." );
+     479             : 
+     480          10 :   keys.add("optional","ALPHA",
+     481             :            "Alpha parameter for LogMFD. "
+     482             :            "If not provided or provided as 0, it will be taken as 1/gamma. "
+     483             :            "If gamma is also not provided, Alpha is set as 4, which is a sensible value when the unit of kcal/mol is used." );
+     484          10 :   keys.add("optional","GAMMA",
+     485             :            "Gamma parameter for LogMFD. "
+     486             :            "If not provided or provided as 0, it will be taken as 1/alpha. "
+     487             :            "If alpha is also not provided, Gamma is set as 0.25, which is a sensible value when the unit of kcal/mol is used." );
+     488          10 :   keys.add("compulsory","KAPPA",
+     489             :            "Spring constant of the harmonic restraining potential." );
+     490             : 
+     491          10 :   keys.add("compulsory","FICT_MAX",
+     492             :            "Maximum values reachable for the fictitious dynamical variables. The variables will elastically bounce back at the boundary (mirror boundary)." );
+     493          10 :   keys.add("compulsory","FICT_MIN",
+     494             :            "Minimum values reachable for the fictitious dynamical variables. The variables will elastically bounce back at the boundary (mirror boundary)." );
+     495             : 
+     496          10 :   keys.add("optional","FICT",
+     497             :            "The initial values of the fictitious dynamical variables. "
+     498             :            "If not provided, they are set equal to their corresponding CVs for the initial atomic configuration." );
+     499          10 :   keys.add("optional","VFICT",
+     500             :            "The initial velocities of the fictitious dynamical variables. "
+     501             :            "If not provided, they will be taken as 0. "
+     502             :            "If THERMOSTAT=VS, they are instead automatically adjusted according to TEMP. "  );
+     503          10 :   keys.add("optional","MFICT",
+     504             :            "Masses of each fictitious dynamical variable. "
+     505             :            "If not provided, they will be taken as 10000." );
+     506             : 
+     507          10 :   keys.add("optional","XETA",
+     508             :            "The initial eta variable of the Nose-Hoover thermostat "
+     509             :            "for the fictitious dynamical variables. "
+     510             :            "If not provided, it will be taken as 0." );
+     511          10 :   keys.add("optional","VETA",
+     512             :            "The initial velocity of eta variable. "
+     513             :            "If not provided, it will be taken as 0." );
+     514          10 :   keys.add("optional","META",
+     515             :            "Mass of eta variable. "
+     516             :            "If not provided, it will be taken as \\f$N*kb*T*100*100\\f$." );
+     517             : 
+     518          10 :   keys.add("compulsory","FLOG",
+     519             :            "The initial free energy value in the LogMFD/PD run."
+     520             :            "The origin of the free energy profile is adjusted by FLOG to "
+     521             :            "realize \\f$F({\\bf X}(t)) > 0\\f$ at any \\f${\\bf X}(t)\\f$, "
+     522             :            "resulting in enhanced barrier-crossing. "
+     523             :            "(The value of \\f$H_{\\rm log}\\f$ is automatically "
+     524             :            "set according to FLOG). "
+     525             :            "In fact, \\f$F({\\bf X}(t))\\f$ is correctly "
+     526             :            "estimated in PLUMED even when \\f$F({\\bf X}(t)) < 0\\f$ in "
+     527             :            "the LogMFD/PD run." );
+     528             : 
+     529          10 :   keys.add("optional","WORK",
+     530             :            "The initial value of the work done by fictitious dynamical "
+     531             :            "variables in each replica. "
+     532             :            "If not provided, it will be taken as 0.");
+     533             : 
+     534          10 :   keys.add("optional","TEMPPD",
+     535             :            "Temperature of the Boltzmann factor in the Jarzynski weight in LogPD (Gromacs only). "
+     536             :            "TEMPPD should be the same as the "
+     537             :            "temperature of the MD system, while TEMP may be (in principle) different from it. "
+     538             :            "If not provided, TEMPPD is set to be the same value as TEMP." );
+     539             : 
+     540           5 :   componentsAreNotOptional(keys);
+     541          10 :   keys.addOutputComponent("_fict","default",
+     542             :                           "For example, the fictitious collective variable for LogMFD is specified as "
+     543             :                           "ARG=dist12 and LABEL=logmfd in LOGMFD section in Plumed input file, "
+     544             :                           "the associated fictitious dynamical variable can be specified as "
+     545             :                           "PRINT ARG=dist12,logmfd.dist12_fict FILE=COLVAR");
+     546          10 :   keys.addOutputComponent("_vfict","default",
+     547             :                           "For example, the fictitious collective variable for LogMFD is specified as "
+     548             :                           "ARG=dist12 and LABEL=logmfd in LOGMFD section in Plumed input file, the "
+     549             :                           "velocity of the associated fictitious dynamical variable can be specified as "
+     550             :                           "PRINT ARG=dist12,logmfd.dist12_vfict FILE=COLVAR");
+     551           5 : }
+     552             : 
+     553             : 
+     554             : /**
+     555             :    \brief constructor of LogMFD class
+     556             :    \details This constructor initializes all parameters and variables,
+     557             :    reads input file and set value of parameters and initial value of variables,
+     558             :    and writes messages as Plumed log.
+     559             : */
+     560           3 : LogMFD::LogMFD( const ActionOptions& ao ):
+     561             :   PLUMED_BIAS_INIT(ao),
+     562           3 :   firsttime(true),
+     563           3 :   step_initial(0),
+     564           3 :   interval(10),
+     565           3 :   delta_t(1.0),
+     566           6 :   thermostat("NVE"),
+     567           3 :   kbt(-1.0),
+     568           3 :   kbtpd(-1.0),
+     569           3 :   TAMD(0),
+     570           3 :   alpha(0.0),
+     571           3 :   gamma(0.0),
+     572           3 :   kappa(getNumberOfArguments(),0.0),
+     573           3 :   fict_max(getNumberOfArguments(),0.0),
+     574           3 :   fict_min(getNumberOfArguments(),0.0),
+     575           3 :   fict (getNumberOfArguments(),-999.0), // -999 means no initial values given in plumed.dat
+     576           3 :   vfict(getNumberOfArguments(),0.0),
+     577           3 :   mfict(getNumberOfArguments(),10000.0),
+     578           3 :   xeta(0.0),
+     579           3 :   veta(0.0),
+     580           3 :   meta(0.0),
+     581           3 :   flog(0.0),
+     582           3 :   hlog(0.0),
+     583           3 :   phivs(0.0),
+     584           3 :   work(0.0),
+     585           3 :   weight(0.0),
+     586           3 :   ffict(getNumberOfArguments(),0.0),
+     587           3 :   fict_ave(getNumberOfArguments(),0.0),
+     588           3 :   fictValue(getNumberOfArguments(),NULL),
+     589           9 :   vfictValue(getNumberOfArguments(),NULL)
+     590             : {
+     591           3 :   backup.fict.resize(getNumberOfArguments(),0.0);
+     592           3 :   backup.vfict.resize(getNumberOfArguments(),0.0);
+     593           3 :   backup.ffict.resize(getNumberOfArguments(),0.0);
+     594           3 :   backup.xeta = 0.0;
+     595           3 :   backup.veta = 0.0;
+     596           3 :   backup.phivs = 0.0;
+     597           3 :   backup.work = 0.0;
+     598           3 :   backup.weight = 0.0;
+     599             : 
+     600           3 :   parse("INTERVAL",interval);
+     601           3 :   parse("DELTA_T",delta_t);
+     602           3 :   parse("THERMOSTAT",thermostat);
+     603           3 :   kbt = getkBT(); // read as temperature
+     604           3 :   parse("TEMPPD",kbtpd); // read as temperature
+     605             : 
+     606           3 :   parse("TAMD",TAMD);
+     607           3 :   parse("ALPHA",alpha);
+     608           3 :   parse("GAMMA",gamma);
+     609           3 :   parseVector("KAPPA",kappa);
+     610             : 
+     611           3 :   parseVector("FICT_MAX",fict_max);
+     612           3 :   parseVector("FICT_MIN",fict_min);
+     613             : 
+     614           3 :   parseVector("FICT",fict);
+     615           3 :   parseVector("VFICT",vfict);
+     616           3 :   parseVector("MFICT",mfict);
+     617             : 
+     618           3 :   parse("XETA",xeta);
+     619           3 :   parse("VETA",veta);
+     620           3 :   parse("META",meta);
+     621             : 
+     622           3 :   parse("FLOG",flog);
+     623             : 
+     624             :   // read initial value of work for each replica of LogPD
+     625           3 :   if( multi_sim_comm.Get_size()>1 ) {
+     626           0 :     vector<double> vwork(multi_sim_comm.Get_size(),0.0);
+     627           0 :     parseVector("WORK",vwork);
+     628             :     // initial work of this replica
+     629           0 :     work = vwork[multi_sim_comm.Get_rank()];
+     630             :   }
+     631             :   else {
+     632           3 :     work = 0.0;
+     633             :   }
+     634             : 
+     635           3 :   if( kbtpd>=0.0 ) {
+     636           0 :     kbtpd *= getKBoltzmann();
+     637             :   }
+     638             :   else {
+     639           3 :     kbtpd = kbt;
+     640             :   }
+     641             : 
+     642           3 :   if( meta == 0.0 ) {
+     643           2 :     const double nkt = getNumberOfArguments()*kbt;
+     644           2 :     meta = nkt*100.0*100.0;
+     645             :   }
+     646             : 
+     647           3 :   if(alpha == 0.0 && gamma == 0.0) {
+     648           0 :     alpha = 4.0;
+     649           0 :     gamma = 1 / alpha;
+     650             :   }
+     651           3 :   else if(alpha != 0.0 && gamma == 0.0) {
+     652           3 :     gamma = 1 / alpha;
+     653             :   }
+     654           0 :   else if(alpha == 0.0 && gamma != 0.0) {
+     655           0 :     alpha = 1 / gamma;
+     656             :   }
+     657             : 
+     658           3 :   checkRead();
+     659             : 
+     660             :   // output messaages to Plumed's log file
+     661           3 :   if( multi_sim_comm.Get_size()>1 ) {
+     662           0 :     if( TAMD ) {
+     663           0 :       log.printf("TAMD-PD, replica parallel of TAMD, no logarithmic flattening.\n");
+     664             :     }
+     665             :     else {
+     666           0 :       log.printf("LogPD, replica parallel of LogMFD.\n");
+     667             :     }
+     668           0 :     log.printf("number of replica : %d.\n", multi_sim_comm.Get_size() );
+     669             :   }
+     670             :   else {
+     671           3 :     if( TAMD ) {
+     672           0 :       log.printf("TAMD, no logarithmic flattening.\n");
+     673             :     }
+     674             :     else {
+     675           3 :       log.printf("LogMFD, logarithmic flattening.\n");
+     676             :     }
+     677             :   }
+     678             : 
+     679           3 :   log.printf("  with harmonic force constant      ");
+     680           6 :   for(unsigned i=0; i<kappa.size(); i++) log.printf(" %f",kappa[i]);
+     681           3 :   log.printf("\n");
+     682             : 
+     683           3 :   log.printf("  with interval of cv(ideal) update ");
+     684           3 :   log.printf(" %d", interval);
+     685           3 :   log.printf("\n");
+     686             : 
+     687           3 :   log.printf("  with time step of cv(ideal) update ");
+     688           3 :   log.printf(" %f", delta_t);
+     689           3 :   log.printf("\n");
+     690             : 
+     691           3 :   if( !TAMD ) {
+     692           3 :     log.printf("  with alpha, gamma                 ");
+     693           3 :     log.printf(" %f %f", alpha, gamma);
+     694           3 :     log.printf("\n");
+     695             :   }
+     696             : 
+     697           3 :   log.printf("  with Thermostat for cv(ideal)     ");
+     698           3 :   log.printf(" %s", thermostat.c_str());
+     699           3 :   log.printf("\n");
+     700             : 
+     701           3 :   log.printf("  with initial free energy          ");
+     702           3 :   log.printf(" %f", flog);
+     703           3 :   log.printf("\n");
+     704             : 
+     705           3 :   log.printf("  with mass of cv(ideal)");
+     706           6 :   for(unsigned i=0; i<mfict.size(); i++) log.printf(" %f", mfict[i]);
+     707           3 :   log.printf("\n");
+     708             : 
+     709           3 :   log.printf("  with initial value of cv(ideal)");
+     710           6 :   for(unsigned i=0; i<fict.size(); i++) log.printf(" %f", fict[i]);
+     711           3 :   log.printf("\n");
+     712             : 
+     713           3 :   log.printf("  with initial velocity of cv(ideal)");
+     714           6 :   for(unsigned i=0; i<vfict.size(); i++) log.printf(" %f", vfict[i]);
+     715           3 :   log.printf("\n");
+     716             : 
+     717           3 :   log.printf("  with maximum value of cv(ideal)    ");
+     718           6 :   for(unsigned i=0; i<fict_max.size(); i++) log.printf(" %f",fict_max[i]);
+     719           3 :   log.printf("\n");
+     720             : 
+     721           3 :   log.printf("  with minimum value of cv(ideal)    ");
+     722           6 :   for(unsigned i=0; i<fict_min.size(); i++) log.printf(" %f",fict_min[i]);
+     723           3 :   log.printf("\n");
+     724             : 
+     725           3 :   log.printf("  and kbt                           ");
+     726           3 :   log.printf(" %f\n",kbt);
+     727           3 :   log.printf(" kbt for PD %f\n",kbtpd);
+     728             : 
+     729             :   // setup Value* variables
+     730           6 :   for(unsigned i=0; i<getNumberOfArguments(); i++) {
+     731           3 :     std::string comp = getPntrToArgument(i)->getName()+"_fict";
+     732           6 :     addComponentWithDerivatives(comp);
+     733             : 
+     734           3 :     if(getPntrToArgument(i)->isPeriodic()) {
+     735             :       std::string a,b;
+     736           0 :       getPntrToArgument(i)->getDomain(a,b);
+     737           0 :       componentIsPeriodic(comp,a,b);
+     738             :     }
+     739             :     else {
+     740           3 :       componentIsNotPeriodic(comp);
+     741             :     }
+     742           3 :     fictValue[i] = getPntrToComponent(comp);
+     743             : 
+     744           6 :     comp = getPntrToArgument(i)->getName()+"_vfict";
+     745           3 :     addComponent(comp);
+     746             : 
+     747           3 :     componentIsNotPeriodic(comp);
+     748           3 :     vfictValue[i] = getPntrToComponent(comp);
+     749             :   }
+     750           3 : }
+     751             : 
+     752             : /**
+     753             :    \brief calculate forces for fictitious variables at every MD steps.
+     754             :    \details This function calculates initial values of fictitious variables
+     755             :    and write header messages to LogMFD log files at the first MFD step,
+     756             :    calculates restraining fources comes from difference between the fictitious variable
+     757             :    and collective variable at every MD steps.
+     758             : */
+     759        1500 : void LogMFD::calculate() {
+     760        1500 :   if( firsttime ) {
+     761           3 :     firsttime = false;
+     762             : 
+     763           3 :     step_initial = getStep();
+     764             : 
+     765             :     // set initial values of fictitious variables if they were not specified.
+     766           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     767           3 :       if( fict[i] != -999.0 ) continue; // -999 means no initial values given in plumed.dat
+     768             : 
+     769             :       // use the collective variables as the initial of the fictitious variable.
+     770           0 :       fict[i] = getArgument(i);
+     771             : 
+     772             :       // average values of fictitious variables by all replica.
+     773           0 :       if( multi_sim_comm.Get_size()>1 ) {
+     774           0 :         multi_sim_comm.Sum(fict[i]);
+     775           0 :         fict[i] /= multi_sim_comm.Get_size();
+     776             :       }
+     777             :     }
+     778             : 
+     779             :     // initialize accumulation value to zero
+     780           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     781           3 :       fict_ave[i] = 0.0;
+     782             :     }
+     783             : 
+     784             :     // calculate invariant for NVE
+     785           3 :     if(thermostat == "NVE") {
+     786             :       // kinetic energy
+     787           1 :       const double ekin = calcEkin();
+     788             :       // potential energy
+     789           1 :       const double pot = TAMD ? flog : sgn(flog)*gamma * std::log1p( alpha*fabs(flog) );
+     790             :       // invariant
+     791           1 :       hlog = pot + ekin;
+     792             :     }
+     793           2 :     else if(thermostat == "NVT") {
+     794           1 :       const double nkt = getNumberOfArguments()*kbt;
+     795             :       // kinetic energy
+     796           1 :       const double ekin = calcEkin();
+     797             :       // bath energy
+     798           1 :       const double ekin_bath = 0.5*veta*veta*meta + xeta*nkt;
+     799             :       // potential energy
+     800           1 :       const double pot = TAMD ? flog : sgn(flog)*gamma * std::log1p( alpha*fabs(flog) );
+     801             :       // invariant
+     802           1 :       hlog = pot + ekin + ekin_bath;
+     803             :     }
+     804           1 :     else if(thermostat == "VS") {
+     805             :       // kinetic energy
+     806           1 :       const double ekin = calcEkin();
+     807           1 :       if( ekin == 0.0 ) { // this means VFICT is not given.
+     808             :         // initial velocities
+     809           2 :         for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     810           1 :           vfict[i] = sqrt(kbt/mfict[i]);
+     811             :         }
+     812             :       }
+     813             :       else {
+     814           0 :         const double nkt = getNumberOfArguments()*kbt;
+     815           0 :         const double svs = sqrt(nkt/ekin/2);
+     816           0 :         for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     817           0 :           vfict[i] *= svs; // scale velocities
+     818             :         }
+     819             :       }
+     820             :       // initial VS potential
+     821           1 :       phivs = TAMD ? flog : sgn(flog)* gamma*std::log1p( alpha*fabs(flog) );
+     822             : 
+     823             :       // invariant
+     824           1 :       hlog = 0.0;
+     825             :     }
+     826             : 
+     827           3 :     weight = 1.0; // for replica parallel
+     828             : 
+     829             :     // open LogMFD's log file
+     830           3 :     if( multi_sim_comm.Get_rank()==0 && comm.Get_rank()==0 ) {
+     831           3 :       FILE *outlog = std::fopen("logmfd.out", "w");
+     832             : 
+     833             :       // output messages to LogMFD's log file
+     834           3 :       if( multi_sim_comm.Get_size()>1 ) {
+     835             :         fprintf(outlog, "# LogPD, replica parallel of LogMFD\n");
+     836           0 :         fprintf(outlog, "# number of replica : %d\n", multi_sim_comm.Get_size() );
+     837             :       }
+     838             :       else {
+     839             :         fprintf(outlog, "# LogMFD\n");
+     840             :       }
+     841             : 
+     842             :       fprintf(outlog, "# CVs :");
+     843           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     844             :         fprintf(outlog, " %s",  getPntrToArgument(i)->getName().c_str() );
+     845             :       }
+     846             :       fprintf(outlog, "\n");
+     847             : 
+     848             :       fprintf(outlog, "# Mass for CV particles :");
+     849           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     850           3 :         fprintf(outlog, "%15.6f", mfict[i]);
+     851             :       }
+     852             :       fprintf(outlog, "\n");
+     853             : 
+     854             :       fprintf(outlog, "# Mass for thermostat   :");
+     855           3 :       fprintf(outlog, "%15.6f", meta);
+     856             :       fprintf(outlog, "\n");
+     857             :       fprintf(outlog, "# 1:iter_mfd, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,\n");
+     858             : 
+     859           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     860           3 :         fprintf(outlog, "# %u:%s_fict(t), %u:%s_vfict(t), %u:%s_force(t),\n",
+     861             :                 6+i*3, getPntrToArgument(i)->getName().c_str(),
+     862             :                 7+i*3, getPntrToArgument(i)->getName().c_str(),
+     863           3 :                 8+i*3, getPntrToArgument(i)->getName().c_str() );
+     864             :       }
+     865           3 :       fclose(outlog);
+     866             :     }
+     867             : 
+     868           3 :     if( comm.Get_rank()==0 ) {
+     869             :       // the number of replica is added to file name to distingwish replica.
+     870           3 :       FILE *outlog2 = fopen("replica.out", "w");
+     871           6 :       fprintf(outlog2, "# Replica No. %d of %d.\n",
+     872           3 :               multi_sim_comm.Get_rank(), multi_sim_comm.Get_size() );
+     873             : 
+     874             :       fprintf(outlog2, "# 1:iter_mfd, 2:work, 3:weight,\n");
+     875           6 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     876           3 :         fprintf(outlog2, "# %u:%s(q)\n",
+     877             :                 4+i, getPntrToArgument(i)->getName().c_str() );
+     878             :       }
+     879           3 :       fclose(outlog2);
+     880             :     }
+     881             : 
+     882             :     // output messages to Plumed's log file
+     883             :     //    log.printf("LOGMFD thermostat parameters Xeta Veta Meta");
+     884             :     //    log.printf(" %f %f %f", xeta, veta, meta);
+     885             :     //    log.printf("\n");
+     886             :     //    log.printf("# 1:iter_mfd, 2:Flog, 3:2*Ekin/gkb[K], 4:eta, 5:Veta,");
+     887             :     //    log.printf("# 6:X1(t), 7:V1(t), 8:F1(t), 9:X2(t), 10:V2(t), 11:F2(t), ...");
+     888             : 
+     889             :   } // firsttime
+     890             : 
+     891             :   // calculate force for fictitious variable
+     892             :   double ene=0.0;
+     893        3000 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     894             :     // difference between fictitious variable and collective variable.
+     895        1500 :     const double diff = difference(i,fict[i],getArgument(i));
+     896             :     // restraining force.
+     897        1500 :     const double f = -kappa[i]*diff;
+     898        1500 :     setOutputForce(i,f);
+     899             : 
+     900             :     // restraining energy.
+     901        1500 :     ene += 0.5*kappa[i]*diff*diff;
+     902             : 
+     903             :     // accumulate force, later it will be averaged.
+     904        1500 :     ffict[i] += -f;
+     905             : 
+     906             :     // accumulate varience of collective variable, later it will be averaged.
+     907        1500 :     fict_ave[i] += diff;
+     908             :   }
+     909             : 
+     910        1500 :   setBias(ene);
+     911        3000 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     912             :     // correct fict so that it is inside [min:max].
+     913        1500 :     double tmp = fict[i];
+     914        1500 :     fict[i] = fictValue[i]->bringBackInPbc(fict[i]);
+     915        1500 :     fictValue[i]->set(fict[i]);
+     916        1500 :     vfictValue[i]->set(vfict[i]);
+     917             :   }
+     918        1500 : } // calculate
+     919             : 
+     920             : /**
+     921             :    \brief update fictitious variables.
+     922             :    \details This function manages evolution of fictitious variables.
+     923             :    This function calculates mean force, updates fictitious variables by one MFD step,
+     924             :    bounces back variables, updates free energy, and record logs.
+     925             : */
+     926        1500 : void LogMFD::update() {
+     927        1500 :   if( (getStep()-step_initial)%interval != interval-1 ) return;
+     928             : 
+     929          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     930          15 :     backup.fict[i]  =  fict[i];
+     931          15 :     backup.vfict[i] = vfict[i];
+     932             :   }
+     933          15 :   backup.xeta = xeta;
+     934          15 :   backup.veta = veta;
+     935          15 :   backup.phivs = phivs;
+     936          15 :   backup.work = work;
+     937          15 :   backup.weight = weight;
+     938             : 
+     939             :   // calc mean force for fictitious variables
+     940          15 :   calcMeanForce();
+     941             : 
+     942             :   // record log for fictitious variables
+     943          15 :   if( multi_sim_comm.Get_rank()==0 && comm.Get_rank()==0 ) {
+     944          15 :     const double ekin = calcEkin();
+     945          15 :     const double temp = 2.0*ekin/getNumberOfArguments()/getKBoltzmann();
+     946             : 
+     947          15 :     FILE *outlog = std::fopen("logmfd.out", "a");
+     948          15 :     fprintf(outlog, "%*d", 8, (int)(getStep()-step_initial)/interval);
+     949          15 :     fprintf(outlog, "%15.6f", flog);
+     950             :     fprintf(outlog, "%15.6f", temp);
+     951          15 :     fprintf(outlog, "%15.6f", xeta);
+     952          15 :     fprintf(outlog, "%15.6f", veta);
+     953          30 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     954          15 :       fprintf(outlog, "%15.6f", fict[i]);
+     955          15 :       fprintf(outlog, "%15.6f", vfict[i]);
+     956          15 :       fprintf(outlog, "%15.6f", ffict[i]);
+     957             :     }
+     958             :     fprintf(outlog," \n");
+     959          15 :     fclose(outlog);
+     960             :   }
+     961             : 
+     962             :   // record log for collective variables
+     963          15 :   if( comm.Get_rank()==0 ) {
+     964             :     // the number of replica is added to file name to distingwish replica.
+     965          15 :     FILE *outlog2 = fopen("replica.out", "a");
+     966          15 :     fprintf(outlog2, "%*d", 8, (int)(getStep()-step_initial)/interval);
+     967          15 :     fprintf(outlog2, "%16.6e ", work);
+     968          15 :     fprintf(outlog2, "%16.6e ", weight);
+     969          30 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     970          15 :       fprintf(outlog2, "%15.6f", fict_ave[i]);
+     971             :     }
+     972             :     fprintf(outlog2," \n");
+     973          15 :     fclose(outlog2);
+     974             :   }
+     975             : 
+     976             :   // update fictitious variables
+     977          15 :   if(thermostat == "NVE") {
+     978           5 :     updateNVE();
+     979             :   }
+     980          10 :   else if(thermostat == "NVT") {
+     981           5 :     updateNVT();
+     982             :   }
+     983           5 :   else if(thermostat == "VS") {
+     984           5 :     updateVS();
+     985             :   }
+     986             : 
+     987             :   // update work done by fictitious dynamical variables
+     988          15 :   updateWork();
+     989             : 
+     990             :   // check boundary
+     991             :   bool reject = false;
+     992          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     993          15 :     if( fict[i] < fict_min[i] || fict_max[i] < fict[i] ) {
+     994             :       reject = true;
+     995           0 :       backup.vfict[i] *= -1.0;
+     996             :     }
+     997             :   }
+     998          15 :   if( reject ) {
+     999           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1000           0 :       fict[i] = backup.fict[i];
+    1001           0 :       vfict[i] = backup.vfict[i];
+    1002             :     }
+    1003           0 :     xeta = backup.xeta;
+    1004           0 :     veta = backup.veta;
+    1005           0 :     phivs = backup.phivs;
+    1006           0 :     work = backup.work;
+    1007           0 :     weight = backup.weight;
+    1008             :   }
+    1009             : 
+    1010             :   // update free energy
+    1011          15 :   flog = calcFlog();
+    1012             : 
+    1013             :   // reset mean force
+    1014          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1015          15 :     ffict[i] = 0.0;
+    1016          15 :     fict_ave[i] = 0.0;
+    1017             :   }
+    1018             : 
+    1019             : } // update
+    1020             : 
+    1021             : /**
+    1022             :    \brief update fictitious variables by NVE mechanics.
+    1023             :    \details This function updates ficitious variables by one NVE-MFD step using mean forces
+    1024             :    and flattening coefficient and free energy.
+    1025             :  */
+    1026           5 : void LogMFD::updateNVE() {
+    1027           5 :   const double dt = delta_t;
+    1028             : 
+    1029             :   // get latest free energy and flattening coefficient
+    1030           5 :   flog = calcFlog();
+    1031           5 :   const double clog = calcClog();
+    1032             : 
+    1033             :   // update all ficitious variables by one MFD step
+    1034          10 :   for( unsigned i=0; i<getNumberOfArguments(); ++i ) {
+    1035             :     // update velocity (full step)
+    1036           5 :     vfict[i]+=clog*ffict[i]*dt/mfict[i];
+    1037             :     // update position (full step)
+    1038           5 :     fict[i]+=vfict[i]*dt;
+    1039             :   }
+    1040           5 : } // updateNVE
+    1041             : 
+    1042             : /**
+    1043             :    \brief update fictitious variables by NVT mechanics.
+    1044             :    \details This function updates ficitious variables by one NVT-MFD step using mean forces
+    1045             :    and flattening coefficient and free energy.
+    1046             :  */
+    1047           5 : void LogMFD::updateNVT() {
+    1048           5 :   const double dt = delta_t;
+    1049           5 :   const double nkt = getNumberOfArguments()*kbt;
+    1050             : 
+    1051             :   // backup vfict
+    1052          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1053           5 :     backup.vfict[i] = vfict[i];
+    1054             :   }
+    1055             : 
+    1056             :   const int niter=5;
+    1057          30 :   for(unsigned j=0; j<niter; ++j) {
+    1058             :     // get latest free energy and flattening coefficient
+    1059          25 :     flog = calcFlog();
+    1060          25 :     const double clog = calcClog();
+    1061             : 
+    1062             :     // restore vfict from backup.vfict
+    1063          50 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1064          25 :       vfict[i] = backup.vfict[i];
+    1065             :     }
+    1066             : 
+    1067             :     // evolve vfict from backup.vfict by dt/2
+    1068          50 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1069          25 :       vfict[i] *= exp(-0.25*dt*veta);
+    1070          25 :       vfict[i] += 0.5*dt*clog*ffict[i]/mfict[i];
+    1071          25 :       vfict[i] *= exp(-0.25*dt*veta);
+    1072             :     }
+    1073             :   }
+    1074             : 
+    1075             :   // get latest free energy and flattening coefficient
+    1076           5 :   flog = calcFlog();
+    1077           5 :   const double clog = calcClog();
+    1078             : 
+    1079             :   // evolve vfict by dt/2, and evolve fict by dt
+    1080          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1081           5 :     vfict[i] *= exp(-0.25*dt*veta);
+    1082           5 :     vfict[i] += 0.5*dt*clog*ffict[i]/mfict[i];
+    1083           5 :     vfict[i] *= exp(-0.25*dt*veta);
+    1084           5 :     fict[i]  += dt*vfict[i];
+    1085             :   }
+    1086             : 
+    1087             :   // evolve xeta and veta by dt
+    1088           5 :   xeta += 0.5*dt*veta;
+    1089           5 :   const double ekin = calcEkin();
+    1090           5 :   veta += dt*(2.0*ekin-nkt)/meta;
+    1091           5 :   xeta += 0.5*dt*veta;
+    1092           5 : } // updateNVT
+    1093             : 
+    1094             : /**
+    1095             :    \brief update fictitious variables by VS mechanics.
+    1096             :    \details This function updates ficitious variables by one VS-MFD step using mean forces
+    1097             :    and flattening coefficient and free energy.
+    1098             :  */
+    1099           5 : void LogMFD::updateVS() {
+    1100           5 :   const double dt = delta_t;
+    1101           5 :   const double nkt = getNumberOfArguments()*kbt;
+    1102             : 
+    1103             :   // get latest free energy and flattening coefficient
+    1104           5 :   flog = calcFlog();
+    1105           5 :   const double clog = calcClog();
+    1106             : 
+    1107          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1108             :     // update velocity (full step)
+    1109           5 :     vfict[i] += clog*ffict[i]*dt/mfict[i];
+    1110             :   }
+    1111             : 
+    1112           5 :   const double ekin = calcEkin();
+    1113           5 :   const double svs = sqrt(nkt/ekin/2);
+    1114             : 
+    1115          10 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1116             :     // update position (full step)
+    1117           5 :     vfict[i] *= svs;
+    1118           5 :     fict[i] += vfict[i]*dt;
+    1119             :   }
+    1120             : 
+    1121             :   // evolve VS potential
+    1122           5 :   phivs += nkt*std::log(svs);
+    1123           5 : } // updateVS
+    1124             : 
+    1125             : /**
+    1126             :    \brief update work done by fictious variables.
+    1127             :    \details This function updates work done by ficitious variables.
+    1128             :  */
+    1129          15 : void LogMFD::updateWork() {
+    1130             :   // accumulate work, it was initialized as 0.0
+    1131          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1132          15 :     work -= backup.ffict[i] * vfict[i] * delta_t;
+    1133             :   }
+    1134          15 : } // updateWork
+    1135             : 
+    1136             : /**
+    1137             :    \brief calculate mean force for fictitious variables.
+    1138             :    \details This function calculates mean forces by averaging forces accumulated during one MFD step,
+    1139             :    update work variables done by fictitious variables by one MFD step,
+    1140             :    calculate weight variable of this replica for LogPD.
+    1141             : */
+    1142          15 : void LogMFD::calcMeanForce() {
+    1143             :   // cale temporal mean force for each CV
+    1144          30 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1145          15 :     ffict[i] /= interval;
+    1146             :     // backup force of replica
+    1147          15 :     backup.ffict[i] = ffict[i];
+    1148             :     // average of diff (getArgument(i)-fict[i])
+    1149          15 :     fict_ave[i] /= interval;
+    1150             :     // average of getArgument(i)
+    1151          15 :     fict_ave[i] += fict[i];
+    1152             : 
+    1153             :     // correct fict_ave so that it is inside [min:max].
+    1154          15 :     fict_ave[i] = fictValue[i]->bringBackInPbc(fict_ave[i]);
+    1155             :   }
+    1156             : 
+    1157             :   // for replica parallel
+    1158          15 :   if( multi_sim_comm.Get_size()>1 ) {
+    1159             :     // find the minimum work among all replicas
+    1160           0 :     double work_min = work;
+    1161           0 :     multi_sim_comm.Min(work_min);
+    1162             : 
+    1163             :     // weight of this replica.
+    1164             :     // here, work is reduced by work_min to avoid all exp(-work/kbt)s disconverge
+    1165           0 :     if( kbtpd == 0.0 ) {
+    1166           0 :       weight = work==work_min ? 1.0 : 0.0;
+    1167             :     }
+    1168             :     else {
+    1169           0 :       weight = exp(-(work-work_min)/kbtpd);
+    1170             :     }
+    1171             : 
+    1172             :     // normalize the weight
+    1173           0 :     double sum_weight = weight;
+    1174           0 :     multi_sim_comm.Sum(sum_weight);
+    1175           0 :     weight /= sum_weight;
+    1176             : 
+    1177             :     // weighting force of this replica
+    1178           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1179           0 :       ffict[i] *= weight;
+    1180             :     }
+    1181             : 
+    1182             :     // averaged mean forces of all replica.
+    1183           0 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1184           0 :       multi_sim_comm.Sum(ffict[i]);
+    1185             :     }
+    1186             :     // now, mean force is obtained.
+    1187             :   }
+    1188          15 : } // calcMeanForce
+    1189             : 
+    1190             : /**
+    1191             :    \brief calculate kinetic energy of fictitious variables.
+    1192             :    \retval kinetic energy.
+    1193             :    \details This function calculates sum of kinetic energy of all fictitious variables.
+    1194             :  */
+    1195          83 : double LogMFD::calcEkin() {
+    1196             :   double ekin=0.0;
+    1197         166 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+    1198          83 :     ekin += mfict[i]*vfict[i]*vfict[i]*0.5;
+    1199             :   }
+    1200          83 :   return ekin;
+    1201             : } // calcEkin
+    1202             : 
+    1203             : /**
+    1204             :    \brief calculate free energy of fictitious variables.
+    1205             :    \retval free energy.
+    1206             :    \details This function calculates free energy by using invariant of canonical mechanics.
+    1207             :  */
+    1208          55 : double LogMFD::calcFlog() {
+    1209          55 :   const double nkt = getNumberOfArguments()*kbt;
+    1210          55 :   const double ekin = calcEkin();
+    1211             :   double pot;
+    1212             : 
+    1213          55 :   if (thermostat == "NVE") {
+    1214          10 :     pot = hlog - ekin;
+    1215             :   }
+    1216          45 :   else if (thermostat == "NVT") {
+    1217          35 :     const double ekin_bath = 0.5*veta*veta*meta+xeta*nkt;
+    1218          35 :     pot = hlog - ekin - ekin_bath;
+    1219             :   }
+    1220          10 :   else if (thermostat == "VS") {
+    1221          10 :     pot = phivs;
+    1222             :   }
+    1223             :   else {
+    1224             :     pot = 0.0; // never occurs
+    1225             :   }
+    1226             : 
+    1227         110 :   return TAMD ? pot : sgn(pot)*expm1(fabs(pot)/gamma)/alpha;
+    1228             : } // calcFlog
+    1229             : 
+    1230             : /**
+    1231             :    \brief calculate coefficient for flattening.
+    1232             :    \retval flattering coefficient.
+    1233             :    \details This function returns 1.0 for TAMD, flattening coefficient for LogMFD.
+    1234             :  */
+    1235          40 : double LogMFD::calcClog() {
+    1236          40 :   return TAMD ? 1.0 : alpha*gamma/(alpha*fabs(flog)+1.0);
+    1237             : } // calcClog
+    1238             : 
+    1239             : } // logmfd
+    1240             : } // PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/index-sort-f.html b/coverage/logmfd/index-sort-f.html new file mode 100644 index 000000000000..41e35d347a8d --- /dev/null +++ b/coverage/logmfd/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - logmfd + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfdHitTotalCoverage
Test:plumed test coverageLines:32637187.9 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/index-sort-l.html b/coverage/logmfd/index-sort-l.html new file mode 100644 index 000000000000..5237dfa03f9f --- /dev/null +++ b/coverage/logmfd/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - logmfd + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfdHitTotalCoverage
Test:plumed test coverageLines:32637187.9 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/logmfd/index.html b/coverage/logmfd/index.html new file mode 100644 index 000000000000..ff4961a81350 --- /dev/null +++ b/coverage/logmfd/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - logmfd + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - logmfdHitTotalCoverage
Test:plumed test coverageLines:32637187.9 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LogMFD.cpp +
87.9%87.9%
+
87.9 %326 / 37192.3 %12 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/index-sort-f.html b/coverage/main/index-sort-f.html new file mode 100644 index 000000000000..d3b2662a2b92 --- /dev/null +++ b/coverage/main/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
main.cpp +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/index-sort-l.html b/coverage/main/index-sort-l.html new file mode 100644 index 000000000000..7d214591cea7 --- /dev/null +++ b/coverage/main/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
main.cpp +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/index.html b/coverage/main/index.html new file mode 100644 index 000000000000..761cdb1df8bf --- /dev/null +++ b/coverage/main/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - main + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mainHitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
main.cpp +
80.0%80.0%
+
80.0 %12 / 15100.0 %1 / 1
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/main.cpp.func-sort-c.html b/coverage/main/main.cpp.func-sort-c.html new file mode 100644 index 000000000000..f993485bbe03 --- /dev/null +++ b/coverage/main/main.cpp.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - main/main.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - main - main.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
main4144
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/main.cpp.func.html b/coverage/main/main.cpp.func.html new file mode 100644 index 000000000000..7cbe2cc903e8 --- /dev/null +++ b/coverage/main/main.cpp.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - main/main.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - main - main.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
main4144
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/main/main.cpp.gcov.html b/coverage/main/main.cpp.gcov.html new file mode 100644 index 000000000000..39927f85c5a4 --- /dev/null +++ b/coverage/main/main.cpp.gcov.html @@ -0,0 +1,148 @@ + + + + + + + + LCOV - plumed test coverage - main/main.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - main - main.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121580.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "wrapper/Plumed.h"
+      23             : #include <cstring>
+      24             : 
+      25             : #ifdef __PLUMED_HAS_MPI
+      26             : #include <mpi.h>
+      27             : #endif
+      28             : 
+      29             : /**
+      30             :   This main uses only the interface published in
+      31             :   Plumed.h. The object file generated from this .cpp
+      32             :   is the only part of the plumed library that should
+      33             :   not be linked with external MD codes, so as
+      34             :   to avoid linker error.
+      35             : */
+      36        4144 : int main(int argc,char**argv) {
+      37             : #ifdef __PLUMED_HAS_MPI
+      38             :   bool nompi=false;
+      39        8589 :   for(unsigned iarg=1; iarg<argc; iarg++) {
+      40        7948 :     if(!std::strcmp(argv[iarg],"--no-mpi")) nompi=true;
+      41        7948 :     if(!std::strcmp(argv[iarg],"--mpi"))    nompi=false;
+      42             : // stop at first non-option
+      43        7948 :     if(argv[iarg] && argv[iarg][0]!='-') break;
+      44             :   }
+      45        4144 :   if(!nompi) MPI_Init(&argc,&argv);
+      46             : #endif
+      47        4144 :   int ret=0;
+      48             : 
+      49             :   try {
+      50             :     PLMD::Plumed p;
+      51             :     p.cmd("CLTool setArgc",&argc);
+      52        4144 :     p.cmd("CLTool setArgv",argv);
+      53             : #ifdef __PLUMED_HAS_MPI
+      54        4144 :     if(!nompi) {
+      55             :       MPI_Comm comm;
+      56         340 :       MPI_Comm_dup(MPI_COMM_WORLD,&comm);
+      57             :       p.cmd("CLTool setMPIComm",&comm);
+      58             :     }
+      59             : #endif
+      60             :     p.cmd("CLTool run",&ret);
+      61             : // end block deletes p also in case an exception occurs
+      62           0 :   } catch(...) {
+      63             : // exception is rethrown and results in a call to terminate
+      64           0 :     throw;
+      65           0 :   }
+      66             : 
+      67             : #ifdef __PLUMED_HAS_MPI
+      68        4144 :   if(!nompi) MPI_Finalize();
+      69             : #endif
+      70        4144 :   return ret;
+      71             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/LWalls.cpp.func-sort-c.html b/coverage/manyrestraints/LWalls.cpp.func-sort-c.html new file mode 100644 index 000000000000..a25c0e56ebb2 --- /dev/null +++ b/coverage/manyrestraints/LWalls.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/LWalls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - LWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:82334.8 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints6LWallsC1ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints6LWallsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD14manyrestraints6LWalls13calcPotentialERKdRd0
_ZN4PLMD14manyrestraints6LWalls16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/LWalls.cpp.func.html b/coverage/manyrestraints/LWalls.cpp.func.html new file mode 100644 index 000000000000..14a23b39737d --- /dev/null +++ b/coverage/manyrestraints/LWalls.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/LWalls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - LWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:82334.8 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints6LWalls16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD14manyrestraints6LWallsC1ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints6LWallsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD14manyrestraints6LWalls13calcPotentialERKdRd0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/LWalls.cpp.gcov.html b/coverage/manyrestraints/LWalls.cpp.gcov.html new file mode 100644 index 000000000000..05e6d08ca224 --- /dev/null +++ b/coverage/manyrestraints/LWalls.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/LWalls.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - LWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:82334.8 %
Date:2024-02-22 21:58:45Functions:1425.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ManyRestraintsBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace manyrestraints {
+      27             : 
+      28             : //+PLUMEDOC MCOLVARB LWALLS
+      29             : /*
+      30             : Add \ref LOWER_WALLS restraints on all the multicolvar values
+      31             : 
+      32             : This action takes the set of values calculated by the colvar specified by label in the DATA
+      33             : keyword and places a restraint on each quantity, \f$x\f$, with the following functional form:
+      34             : 
+      35             : \f$
+      36             :   k((x-a+o)/s)^e
+      37             : \f$
+      38             : 
+      39             : \f$k\f$ (KAPPA) is an energy constant in internal unit of the code, \f$s\f$ (EPS) a rescaling factor and
+      40             : \f$e\f$ (EXP) the exponent determining the power law. By default: EXP = 2, EPS = 1.0, OFF = 0.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : The following set of commands can be used to stop any of the 800 atoms in group A from moving more than 2.46425 nm
+      45             : in the z direction from atom 34137.  This is done by adding a lower wall on the z-distance between all the atoms in
+      46             : group A and the position of 34137.
+      47             : 
+      48             : \plumedfile
+      49             : l: ZDISTANCES GROUPA=1-800 GROUPB=34137 NOPBC
+      50             : LWALLS DATA=l AT=2.46465 KAPPA=150.0 EXP=2 EPS=1 OFFSET=0 LABEL=lwall
+      51             : \endplumedfile
+      52             : 
+      53             : 
+      54             : */
+      55             : //+ENDPLUMEDOC
+      56             : 
+      57             : 
+      58             : class LWalls : public ManyRestraintsBase {
+      59             : private:
+      60             :   double at;
+      61             :   double kappa;
+      62             :   double exp;
+      63             :   double eps;
+      64             :   double offset;
+      65             : public:
+      66             :   static void registerKeywords( Keywords& keys );
+      67             :   explicit LWalls( const ActionOptions& );
+      68             :   double calcPotential( const double& val, double& df ) const override;
+      69             : };
+      70             : 
+      71             : PLUMED_REGISTER_ACTION(LWalls,"LWALLS")
+      72             : 
+      73           2 : void LWalls::registerKeywords( Keywords& keys ) {
+      74           2 :   ManyRestraintsBase::registerKeywords( keys );
+      75           4 :   keys.add("compulsory","AT","the radius of the sphere");
+      76           4 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      77           4 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      78           4 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      79           4 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      80           2 : }
+      81             : 
+      82           0 : LWalls::LWalls(const ActionOptions& ao):
+      83             :   Action(ao),
+      84           0 :   ManyRestraintsBase(ao)
+      85             : {
+      86           0 :   parse("AT",at);
+      87           0 :   parse("OFFSET",offset);
+      88           0 :   parse("EPS",eps);
+      89           0 :   parse("EXP",exp);
+      90           0 :   parse("KAPPA",kappa);
+      91           0 :   checkRead();
+      92           0 : }
+      93             : 
+      94           0 : double LWalls::calcPotential( const double& val, double& df ) const {
+      95           0 :   double uscale = (val - at + offset)/eps;
+      96           0 :   if( uscale < 0. ) {
+      97           0 :     double power = pow( uscale, exp );
+      98           0 :     df = ( kappa / eps ) * exp * power / uscale;
+      99             : 
+     100           0 :     return kappa*power;
+     101             :   }
+     102             : 
+     103             :   return 0.0;
+     104             : }
+     105             : 
+     106             : }
+     107             : }
+     108             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.cpp.func-sort-c.html b/coverage/manyrestraints/ManyRestraintsBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..7de13d028508 --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/ManyRestraintsBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - ManyRestraintsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC2ERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints18ManyRestraintsBase16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD14manyrestraints18ManyRestraintsBase5applyEv10
_ZN4PLMD14manyrestraints18ManyRestraintsBase28doJobsRequiredBeforeTaskListEv740
_ZNK4PLMD14manyrestraints18ManyRestraintsBase27transformBridgedDerivativesERKjRNS_10MultiValueES5_14800
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.cpp.func.html b/coverage/manyrestraints/ManyRestraintsBase.cpp.func.html new file mode 100644 index 000000000000..d1243ad117de --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/ManyRestraintsBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - ManyRestraintsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints18ManyRestraintsBase16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD14manyrestraints18ManyRestraintsBase28doJobsRequiredBeforeTaskListEv740
_ZN4PLMD14manyrestraints18ManyRestraintsBase5applyEv10
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints18ManyRestraintsBaseC2ERKNS_13ActionOptionsE2
_ZNK4PLMD14manyrestraints18ManyRestraintsBase27transformBridgedDerivativesERKjRNS_10MultiValueES5_14800
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.cpp.gcov.html b/coverage/manyrestraints/ManyRestraintsBase.cpp.gcov.html new file mode 100644 index 000000000000..494ab84f723c --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.cpp.gcov.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/ManyRestraintsBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - ManyRestraintsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3737100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ManyRestraintsBase.h"
+      23             : #include "vesselbase/Vessel.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace manyrestraints {
+      27             : 
+      28           6 : void ManyRestraintsBase::registerKeywords( Keywords& keys ) {
+      29           6 :   Action::registerKeywords( keys );
+      30           6 :   ActionWithValue::registerKeywords( keys );
+      31           6 :   ActionWithVessel::registerKeywords( keys );
+      32           6 :   ActionWithInputVessel::registerKeywords( keys );
+      33           6 :   ActionPilot::registerKeywords( keys );
+      34          12 :   keys.add("hidden","STRIDE","the frequency with which the forces due to the bias should be calculated.  This can be used to correctly set up multistep algorithms");
+      35           6 :   keys.remove("TOL");
+      36          12 :   keys.addOutputComponent("bias","default","the instantaneous value of the bias potentials");
+      37           6 : }
+      38             : 
+      39           2 : ManyRestraintsBase::ManyRestraintsBase(const ActionOptions& ao):
+      40             :   Action(ao),
+      41             :   ActionWithValue(ao),
+      42             :   ActionPilot(ao),
+      43             :   ActionWithVessel(ao),
+      44           2 :   ActionWithInputVessel(ao)
+      45             : {
+      46             :   // Read in the vessel we are action on
+      47           2 :   readArgument("bridge");
+      48           2 :   aves=dynamic_cast<ActionWithVessel*>( getDependencies()[0] );
+      49             : 
+      50           2 :   plumed_assert( getDependencies().size()==1 && aves );
+      51           2 :   log.printf("  adding restraints on variables calculated by %s action with label %s\n",
+      52           2 :              aves->getName().c_str(),aves->getLabel().c_str());
+      53             : 
+      54             :   // Add a task list in order to avoid problems
+      55          42 :   for(unsigned i=0; i<aves->getFullNumberOfTasks(); ++i) addTaskToList( aves->getTaskCode(i) );
+      56             :   // And turn on the derivatives (note problems here because of ActionWithValue)
+      57           2 :   turnOnDerivatives(); needsDerivatives();
+      58             : 
+      59             :   // Now create the vessel
+      60           2 :   std::string fake_input="LABEL=bias";
+      61           2 :   addVessel( "SUM", fake_input, 0 );
+      62           2 :   readVesselKeywords();
+      63           2 : }
+      64             : 
+      65         740 : void ManyRestraintsBase::doJobsRequiredBeforeTaskList() {
+      66         740 :   ActionWithVessel::doJobsRequiredBeforeTaskList();
+      67         740 :   ActionWithValue::clearDerivatives();
+      68         740 : }
+      69             : 
+      70       14800 : void ManyRestraintsBase::transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const {
+      71             :   outvals.setValue( 0, invals.get(0) );
+      72             : 
+      73             :   // Get the potential
+      74       14800 :   double dval=0, val=calcPotential( invals.get(1), dval );
+      75             : 
+      76             :   outvals.setValue( 1, val );
+      77      236800 :   for(unsigned i=0; i<invals.getNumberActive(); ++i) {
+      78      222000 :     unsigned jder=invals.getActiveIndex(i);
+      79      222000 :     outvals.addDerivative( 1, jder, dval*invals.getDerivative( 1, jder ) );
+      80             :   }
+      81             : 
+      82             :   // Now update the outvals derivatives lists
+      83             :   outvals.emptyActiveMembers();
+      84      236800 :   for(unsigned j=0; j<invals.getNumberActive(); ++j) outvals.updateIndex( invals.getActiveIndex(j) );
+      85             :   outvals.completeUpdate();
+      86       14800 :   return;
+      87             : }
+      88             : 
+      89          10 : void ManyRestraintsBase::apply() {
+      90             :   plumed_dbg_assert( getNumberOfComponents()==1 );
+      91          10 :   getPntrToComponent(0)->addForce( -1.0*getStride() );
+      92          10 : }
+      93             : 
+      94             : }
+      95             : }
+      96             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.h.func-sort-c.html b/coverage/manyrestraints/ManyRestraintsBase.h.func-sort-c.html new file mode 100644 index 000000000000..e2ad5e4b1d02 --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/ManyRestraintsBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - ManyRestraintsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5771.4 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints18ManyRestraintsBase10isPeriodicEv0
_ZNK4PLMD14manyrestraints18ManyRestraintsBase11performTaskERKjS3_RNS_10MultiValueE0
_ZN4PLMD14manyrestraints18ManyRestraintsBase9calculateEv5
_ZN4PLMD14manyrestraints18ManyRestraintsBase16clearDerivativesEv10
_ZN4PLMD14manyrestraints18ManyRestraintsBase17applyBridgeForcesERKSt6vectorIdSaIdEE10
_ZN4PLMD14manyrestraints18ManyRestraintsBase22getNumberOfDerivativesEv14828
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.h.func.html b/coverage/manyrestraints/ManyRestraintsBase.h.func.html new file mode 100644 index 000000000000..710340c1f6d3 --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/ManyRestraintsBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - ManyRestraintsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5771.4 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints18ManyRestraintsBase10isPeriodicEv0
_ZN4PLMD14manyrestraints18ManyRestraintsBase16clearDerivativesEv10
_ZN4PLMD14manyrestraints18ManyRestraintsBase17applyBridgeForcesERKSt6vectorIdSaIdEE10
_ZN4PLMD14manyrestraints18ManyRestraintsBase22getNumberOfDerivativesEv14828
_ZN4PLMD14manyrestraints18ManyRestraintsBase9calculateEv5
_ZNK4PLMD14manyrestraints18ManyRestraintsBase11performTaskERKjS3_RNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/ManyRestraintsBase.h.gcov.html b/coverage/manyrestraints/ManyRestraintsBase.h.gcov.html new file mode 100644 index 000000000000..c04cc80d3160 --- /dev/null +++ b/coverage/manyrestraints/ManyRestraintsBase.h.gcov.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/ManyRestraintsBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - ManyRestraintsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5771.4 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_manyrestraints_ManyRestraintsBase_h
+      23             : #define __PLUMED_manyrestraints_ManyRestraintsBase_h
+      24             : 
+      25             : #include "core/ActionAtomistic.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : #include "core/ActionPilot.h"
+      28             : #include "vesselbase/ActionWithVessel.h"
+      29             : #include "vesselbase/ActionWithInputVessel.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace manyrestraints {
+      33             : 
+      34             : class ManyRestraintsBase :
+      35             :   public ActionWithValue,
+      36             :   public ActionPilot,
+      37             :   public vesselbase::ActionWithVessel,
+      38             :   public vesselbase::ActionWithInputVessel
+      39             : {
+      40             : private:
+      41             : /// Pointer to underlying action with vessel
+      42             :   vesselbase::ActionWithVessel* aves;
+      43             : public:
+      44             :   static void registerKeywords( Keywords& keys );
+      45             :   explicit ManyRestraintsBase(const ActionOptions&);
+      46           0 :   bool isPeriodic() override { return false; }
+      47             :   unsigned getNumberOfDerivatives() override;
+      48             : /// Routines that have to be defined so as not to have problems with virtual methods
+      49             :   void deactivate_task( const unsigned & task_index ) {};
+      50             : /// Don't actually clear the derivatives when this is called from plumed main.
+      51             : /// They are calculated inside another action and clearing them would be bad
+      52          10 :   void clearDerivatives() override {}
+      53             : /// Do jobs required before tasks are undertaken
+      54             :   void doJobsRequiredBeforeTaskList() override;
+      55             : /// This actually does the calculation
+      56             :   void transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const override;
+      57             : /// Calculate the potential
+      58             :   virtual double calcPotential( const double& val, double& df ) const=0;
+      59             : // Calculate does nothing
+      60           5 :   void calculate() override {};
+      61             : /// This should never be called
+      62           0 :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override { plumed_error(); }
+      63             : /// Deactivate task now does nothing
+      64             :   void apply() override;
+      65          10 :   void applyBridgeForces( const std::vector<double>& bb ) override { plumed_assert( bb.size()==0 ); }
+      66             : };
+      67             : 
+      68             : inline
+      69       14828 : unsigned ManyRestraintsBase::getNumberOfDerivatives() {
+      70       14828 :   return aves->getNumberOfDerivatives();
+      71             : }
+      72             : 
+      73             : }
+      74             : }
+      75             : 
+      76             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/UWalls.cpp.func-sort-c.html b/coverage/manyrestraints/UWalls.cpp.func-sort-c.html new file mode 100644 index 000000000000..716ce6e45a2a --- /dev/null +++ b/coverage/manyrestraints/UWalls.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/UWalls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - UWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints6UWallsC2ERKNS_13ActionOptionsE0
_ZN4PLMD14manyrestraints6UWallsC1ERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints6UWalls16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD14manyrestraints6UWalls13calcPotentialERKdRd14800
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/UWalls.cpp.func.html b/coverage/manyrestraints/UWalls.cpp.func.html new file mode 100644 index 000000000000..c06333c11b1b --- /dev/null +++ b/coverage/manyrestraints/UWalls.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/UWalls.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - UWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14manyrestraints6UWalls16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD14manyrestraints6UWallsC1ERKNS_13ActionOptionsE2
_ZN4PLMD14manyrestraints6UWallsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD14manyrestraints6UWalls13calcPotentialERKdRd14800
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/UWalls.cpp.gcov.html b/coverage/manyrestraints/UWalls.cpp.gcov.html new file mode 100644 index 000000000000..0b67d1c59453 --- /dev/null +++ b/coverage/manyrestraints/UWalls.cpp.gcov.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints/UWalls.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraints - UWalls.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ManyRestraintsBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace manyrestraints {
+      27             : 
+      28             : //+PLUMEDOC MCOLVARB UWALLS
+      29             : /*
+      30             : Add \ref UPPER_WALLS restraints on all the multicolvar values
+      31             : 
+      32             : This action takes the set of values calculated by the colvar specified by label in the DATA
+      33             : keyword and places a restraint on each quantity, \f$x\f$, with the following functional form:
+      34             : 
+      35             : \f$
+      36             :   k((x-a+o)/s)^e
+      37             : \f$
+      38             : 
+      39             : \f$k\f$ (KAPPA) is an energy constant in internal unit of the code, \f$s\f$ (EPS) a rescaling factor and
+      40             : \f$e\f$ (EXP) the exponent determining the power law. By default: EXP = 2, EPS = 1.0, OFF = 0.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : The following set of commands can be used to stop a cluster composed of 20 atoms subliming.  The position of
+      45             : the center of mass of the cluster is calculated by the \ref COM command labelled c1.  The \ref DISTANCES
+      46             : command labelled d1 is then used to calculate the distance between each of the 20 atoms in the cluster
+      47             : and the center of mass of the cluster.  These distances are then passed to the UWALLS command, which adds
+      48             : a \ref UPPER_WALLS restraint on each of them and thereby prevents each of them from moving very far from the center
+      49             : of mass of the cluster.
+      50             : 
+      51             : \plumedfile
+      52             : COM ATOMS=1-20 LABEL=c1
+      53             : DISTANCES GROUPA=c1 GROUPB=1-20 LABEL=d1
+      54             : UWALLS DATA=d1 AT=2.5 KAPPA=0.2 LABEL=sr
+      55             : \endplumedfile
+      56             : 
+      57             : 
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : 
+      62             : class UWalls : public ManyRestraintsBase {
+      63             : private:
+      64             :   double at;
+      65             :   double kappa;
+      66             :   double exp;
+      67             :   double eps;
+      68             :   double offset;
+      69             : public:
+      70             :   static void registerKeywords( Keywords& keys );
+      71             :   explicit UWalls( const ActionOptions& );
+      72             :   double calcPotential( const double& val, double& df ) const override;
+      73             : };
+      74             : 
+      75             : PLUMED_REGISTER_ACTION(UWalls,"UWALLS")
+      76             : 
+      77           4 : void UWalls::registerKeywords( Keywords& keys ) {
+      78           4 :   ManyRestraintsBase::registerKeywords( keys );
+      79           8 :   keys.add("compulsory","AT","the radius of the sphere");
+      80           8 :   keys.add("compulsory","KAPPA","the force constant for the wall.  The k_i in the expression for a wall.");
+      81           8 :   keys.add("compulsory","OFFSET","0.0","the offset for the start of the wall.  The o_i in the expression for a wall.");
+      82           8 :   keys.add("compulsory","EXP","2.0","the powers for the walls.  The e_i in the expression for a wall.");
+      83           8 :   keys.add("compulsory","EPS","1.0","the values for s_i in the expression for a wall");
+      84           4 : }
+      85             : 
+      86           2 : UWalls::UWalls(const ActionOptions& ao):
+      87             :   Action(ao),
+      88           2 :   ManyRestraintsBase(ao)
+      89             : {
+      90           2 :   parse("AT",at);
+      91           2 :   parse("OFFSET",offset);
+      92           2 :   parse("EPS",eps);
+      93           2 :   parse("EXP",exp);
+      94           2 :   parse("KAPPA",kappa);
+      95           2 :   checkRead();
+      96           2 : }
+      97             : 
+      98       14800 : double UWalls::calcPotential( const double& val, double& df ) const {
+      99       14800 :   double uscale = (val - at + offset)/eps;
+     100       14800 :   if( uscale > 0. ) {
+     101        1036 :     double power = pow( uscale, exp );
+     102        1036 :     df = ( kappa / eps ) * exp * power / uscale;
+     103             : 
+     104        1036 :     return kappa*power;
+     105             :   }
+     106             : 
+     107             :   return 0.0;
+     108             : }
+     109             : 
+     110             : }
+     111             : }
+     112             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/index-sort-f.html b/coverage/manyrestraints/index-sort-f.html new file mode 100644 index 000000000000..6b90dff6a522 --- /dev/null +++ b/coverage/manyrestraints/index-sort-f.html @@ -0,0 +1,124 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraintsHitTotalCoverage
Test:plumed test coverageLines:739081.1 %
Date:2024-02-22 21:58:45Functions:132065.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LWalls.cpp +
34.8%34.8%
+
34.8 %8 / 2325.0 %1 / 4
ManyRestraintsBase.h +
71.4%71.4%
+
71.4 %5 / 766.7 %4 / 6
UWalls.cpp +
100.0%
+
100.0 %23 / 2375.0 %3 / 4
ManyRestraintsBase.cpp +
100.0%
+
100.0 %37 / 3783.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/index-sort-l.html b/coverage/manyrestraints/index-sort-l.html new file mode 100644 index 000000000000..8eb3759f9cda --- /dev/null +++ b/coverage/manyrestraints/index-sort-l.html @@ -0,0 +1,124 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraintsHitTotalCoverage
Test:plumed test coverageLines:739081.1 %
Date:2024-02-22 21:58:45Functions:132065.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LWalls.cpp +
34.8%34.8%
+
34.8 %8 / 2325.0 %1 / 4
ManyRestraintsBase.h +
71.4%71.4%
+
71.4 %5 / 766.7 %4 / 6
UWalls.cpp +
100.0%
+
100.0 %23 / 2375.0 %3 / 4
ManyRestraintsBase.cpp +
100.0%
+
100.0 %37 / 3783.3 %5 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/manyrestraints/index.html b/coverage/manyrestraints/index.html new file mode 100644 index 000000000000..d00c9e8bd62a --- /dev/null +++ b/coverage/manyrestraints/index.html @@ -0,0 +1,124 @@ + + + + + + + + LCOV - plumed test coverage - manyrestraints + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - manyrestraintsHitTotalCoverage
Test:plumed test coverageLines:739081.1 %
Date:2024-02-22 21:58:45Functions:132065.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
LWalls.cpp +
34.8%34.8%
+
34.8 %8 / 2325.0 %1 / 4
ManyRestraintsBase.cpp +
100.0%
+
100.0 %37 / 3783.3 %5 / 6
ManyRestraintsBase.h +
71.4%71.4%
+
71.4 %5 / 766.7 %4 / 6
UWalls.cpp +
100.0%
+
100.0 %23 / 2375.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/AdaptivePath.cpp.func-sort-c.html b/coverage/mapping/AdaptivePath.cpp.func-sort-c.html new file mode 100644 index 000000000000..df0ce9f9a717 --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - mapping/AdaptivePath.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - AdaptivePath.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9910396.1 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12AdaptivePathC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping12AdaptivePathC1ERKNS_13ActionOptionsE1
_ZN4PLMD7mapping12AdaptivePath16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7mapping12AdaptivePath6updateEv101
_ZN4PLMD7mapping12AdaptivePath9calculateEv101
_ZN4PLMD7mapping12AdaptivePath9getLambdaEv101
_ZNK4PLMD7mapping12AdaptivePath11performTaskERKjS3_RNS_10MultiValueE2020
_ZNK4PLMD7mapping12AdaptivePath11transformHDERKdRd2020
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/AdaptivePath.cpp.func.html b/coverage/mapping/AdaptivePath.cpp.func.html new file mode 100644 index 000000000000..1cdde256c6e5 --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - mapping/AdaptivePath.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - AdaptivePath.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9910396.1 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12AdaptivePath16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7mapping12AdaptivePath6updateEv101
_ZN4PLMD7mapping12AdaptivePath9calculateEv101
_ZN4PLMD7mapping12AdaptivePath9getLambdaEv101
_ZN4PLMD7mapping12AdaptivePathC1ERKNS_13ActionOptionsE1
_ZN4PLMD7mapping12AdaptivePathC2ERKNS_13ActionOptionsE0
_ZNK4PLMD7mapping12AdaptivePath11performTaskERKjS3_RNS_10MultiValueE2020
_ZNK4PLMD7mapping12AdaptivePath11transformHDERKdRd2020
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/AdaptivePath.cpp.gcov.html b/coverage/mapping/AdaptivePath.cpp.gcov.html new file mode 100644 index 000000000000..a8e61f0d32d0 --- /dev/null +++ b/coverage/mapping/AdaptivePath.cpp.gcov.html @@ -0,0 +1,336 @@ + + + + + + + + LCOV - plumed test coverage - mapping/AdaptivePath.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - AdaptivePath.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9910396.1 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Mapping.h"
+      23             : #include "TrigonometricPathVessel.h"
+      24             : #include "PathReparameterization.h"
+      25             : #include "reference/Direction.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/ActionSet.h"
+      29             : #include "core/GenericMolInfo.h"
+      30             : 
+      31             : //+PLUMEDOC COLVAR ADAPTIVE_PATH
+      32             : /*
+      33             : Compute path collective variables that adapt to the lowest free energy path connecting states A and B.
+      34             : 
+      35             : The Path Collective Variables developed by Branduardi and co-workers \cite brand07 allow one
+      36             : to compute the progress along a high-dimensional path and the distance from the high-dimensional
+      37             : path.  The progress along the path (s) is computed using:
+      38             : 
+      39             : \f[
+      40             : s = i_2 + \textrm{sign}(i_2-i_1) \frac{ \sqrt{( \mathbf{v}_1\cdot\mathbf{v}_2 )^2 - |\mathbf{v}_3|^2(|\mathbf{v}_1|^2 - |\mathbf{v}_2|^2) } }{2|\mathbf{v}_3|^2} - \frac{\mathbf{v}_1\cdot\mathbf{v}_3 - |\mathbf{v}_3|^2}{2|\mathbf{v}_3|^2}
+      41             : \f]
+      42             : 
+      43             : In this expression \f$\mathbf{v}_1\f$ and \f$\mathbf{v}_3\f$ are the vectors connecting the current position to the closest and second closest node of the path,
+      44             : respectfully and \f$i_1\f$ and \f$i_2\f$ are the projections of the closest and second closest frames of the path. \f$\mathbf{v}_2\f$, meanwhile, is the
+      45             : vector connecting the closest frame to the second closest frame.  The distance from the path, \f$z\f$ is calculated using:
+      46             : 
+      47             : \f[
+      48             : z = \sqrt{ \left[ |\mathbf{v}_1|^2 - |\mathbf{v}_2| \left( \frac{ \sqrt{( \mathbf{v}_1\cdot\mathbf{v}_2 )^2 - |\mathbf{v}_3|^2(|\mathbf{v}_1|^2 - |\mathbf{v}_2|^2) } }{2|\mathbf{v}_3|^2} - \frac{\mathbf{v}_1\cdot\mathbf{v}_3 - |\mathbf{v}_3|^2}{2|\mathbf{v}_3|^2} \right) \right]^2 }
+      49             : \f]
+      50             : 
+      51             : Notice that these are the definitions of \f$s\f$ and \f$z\f$ that are used by \ref PATH when the GPATH option is employed.  The reason for this is that
+      52             : the adaptive path method implemented in this action was inspired by the work of Diaz and Ensing in which these formula were used \cite BerndAdaptivePath.
+      53             : To learn more about how the path is adapted we strongly recommend reading this paper.
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : The input below provides an example that shows how the adaptive path works. The path is updated every 50 steps of
+      58             : MD based on the data accumulated during the preceding 50 time steps.
+      59             : 
+      60             : \plumedfile
+      61             : d1: DISTANCE ATOMS=1,2 COMPONENTS
+      62             : pp: ADAPTIVE_PATH TYPE=EUCLIDEAN FIXED=2,5 UPDATE=50 WFILE=out-path.pdb WSTRIDE=50 REFERENCE=mypath.pdb
+      63             : PRINT ARG=d1.x,d1.y,pp.* FILE=colvar
+      64             : \endplumedfile
+      65             : 
+      66             : In the case above the distance between frames is calculated based on the \f$x\f$ and \f$y\f$ components of the vector connecting
+      67             : atoms 1 and 2.  As such an extract from the input reference path (mypath.pdb) would look as follows:
+      68             : 
+      69             : \auxfile{mypath.pdb}
+      70             : REMARK ARG=d1.x,d1.y d1.x=1.12 d1.y=-.60
+      71             : END
+      72             : REMARK ARG=d1.x,d1.y d1.x=.99 d1.y=-.45
+      73             : END
+      74             : REMARK ARG=d1.x,d1.y d1.x=.86 d1.y=-.30
+      75             : END
+      76             : REMARK ARG=d1.x,d1.y d1.x=.73 d1.y=-.15
+      77             : END
+      78             : REMARK ARG=d1.x,d1.y d1.x=.60 d1.y=0
+      79             : END
+      80             : REMARK ARG=d1.x,d1.y d1.x=.47 d1.y=.15
+      81             : END
+      82             : \endauxfile
+      83             : 
+      84             : Notice that one can also use RMSD frames in place of arguments like those above.
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : namespace PLMD {
+      90             : namespace mapping {
+      91             : 
+      92             : class AdaptivePath : public Mapping {
+      93             : private:
+      94             :   OFile pathfile;
+      95             :   std::string ofmt;
+      96             :   double fadefact, tolerance;
+      97             :   unsigned update_str, wstride;
+      98             :   std::vector<unsigned> fixedn;
+      99             :   TrigonometricPathVessel* mypathv;
+     100             :   std::vector<double> wsum;
+     101             :   Direction displacement,displacement2;
+     102             :   std::vector<Direction> pdisplacements;
+     103             : public:
+     104             :   static void registerKeywords( Keywords& keys );
+     105             :   explicit AdaptivePath(const ActionOptions&);
+     106             :   void calculate() override;
+     107             :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override;
+     108         101 :   double getLambda() override { return 0.0; }
+     109             :   double transformHD( const double& dist, double& df ) const override;
+     110             :   void update() override;
+     111             : };
+     112             : 
+     113             : PLUMED_REGISTER_ACTION(AdaptivePath,"ADAPTIVE_PATH")
+     114             : 
+     115           3 : void AdaptivePath::registerKeywords( Keywords& keys ) {
+     116           3 :   Mapping::registerKeywords( keys ); keys.remove("PROPERTY");
+     117           6 :   keys.add("compulsory","FIXED","the positions in the list of input frames of the two path nodes whose positions remain fixed during the path optimization");
+     118           6 :   keys.add("compulsory","HALFLIFE","-1","the number of MD steps after which a previously measured path distance weighs only 50% in the average. This option may increase convergence by allowing to forget the memory of a bad initial guess path. The default is to set this to infinity");
+     119           6 :   keys.add("compulsory","UPDATE","the frequency with which the path should be updated");
+     120           6 :   keys.add("compulsory","TOLERANCE","1E-6","the tolerance to use for the path updating algorithm that makes all frames equidistant");
+     121           6 :   keys.add("optional","WFILE","file on which to write out the path");
+     122           6 :   keys.add("compulsory","FMT","%f","the format to use for output files");
+     123           6 :   keys.add("optional","WSTRIDE","frequency with which to write out the path");
+     124           3 : }
+     125             : 
+     126           1 : AdaptivePath::AdaptivePath(const ActionOptions& ao):
+     127             :   Action(ao),
+     128             :   Mapping(ao),
+     129           1 :   fixedn(2),
+     130           2 :   displacement(ReferenceConfigurationOptions("DIRECTION")),
+     131           3 :   displacement2(ReferenceConfigurationOptions("DIRECTION"))
+     132             : {
+     133           2 :   setLowMemOption( true ); parseVector("FIXED",fixedn);
+     134           1 :   if( fixedn[0]<1 || fixedn[1]>getNumberOfReferencePoints() ) error("fixed nodes must be in range from 0 to number of nodes");
+     135           1 :   if( fixedn[0]>=fixedn[1] ) error("invalid selection for fixed nodes first index provided must be smaller than second index");
+     136           1 :   log.printf("  fixing position of frames numbered %u and %u \n",fixedn[0],fixedn[1]);
+     137           1 :   fixedn[0]--; fixedn[1]--;   // Set fixed notes with c++ indexing starting from zero
+     138           2 :   parse("UPDATE",update_str); if( update_str<1 ) error("update frequency for path should be greater than or equal to one");
+     139           1 :   log.printf("  updating path every %u MD steps \n",update_str);
+     140             : 
+     141           1 :   double halflife; parse("HALFLIFE",halflife);
+     142           1 :   if( halflife<0 ) fadefact=1.0;
+     143             :   else {
+     144           0 :     fadefact = exp( -0.693147180559945 / static_cast<double>(halflife) );
+     145           0 :     log.printf("  weight of contribution to frame halves every %f steps \n",halflife);
+     146             :   }
+     147             : 
+     148             :   // Create the list of tasks (and reset projections of frames)
+     149           1 :   PDB mypdb; mypdb.setAtomNumbers( getAbsoluteIndexes() ); mypdb.addBlockEnd( getAbsoluteIndexes().size() );
+     150           1 :   std::vector<std::string> argument_names( getNumberOfArguments() );
+     151           3 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) argument_names[i] = getPntrToArgument(i)->getName();
+     152           1 :   if( argument_names.size()>0 ) mypdb.setArgumentNames( argument_names );
+     153           1 :   displacement.read( mypdb ); displacement2.read( mypdb );
+     154          21 :   for(int i=0; i<getNumberOfReferencePoints(); ++i) {
+     155          40 :     addTaskToList( i ); pdisplacements.push_back( Direction(ReferenceConfigurationOptions("DIRECTION")) );
+     156          40 :     property.find("spath")->second[i] = static_cast<double>( i - static_cast<int>(fixedn[0]) ) / static_cast<double>( fixedn[1] - fixedn[0] );
+     157          20 :     pdisplacements[i].read( mypdb ); wsum.push_back( 0.0 );
+     158             :   }
+     159           2 :   plumed_assert( getPropertyValue( fixedn[0], "spath" )==0.0 && getPropertyValue( fixedn[1], "spath" )==1.0 );
+     160             :   // And activate them all
+     161           1 :   deactivateAllTasks();
+     162          21 :   for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+     163           1 :   lockContributors();
+     164             : 
+     165             :   // Setup the vessel to hold the trig path
+     166           1 :   std::string input; addVessel("GPATH", input, -1 );
+     167           1 :   readVesselKeywords();
+     168             :   // Check that there is only one vessel - the one holding the trig path
+     169             :   plumed_dbg_assert( getNumberOfVessels()==1 );
+     170             :   // Retrieve the path vessel
+     171           1 :   mypathv = dynamic_cast<TrigonometricPathVessel*>( getPntrToVessel(0) );
+     172           1 :   plumed_assert( mypathv );
+     173             : 
+     174             :   // Information for write out
+     175           2 :   std::string wfilename; parse("WFILE",wfilename);
+     176           1 :   if( wfilename.length()>0 ) {
+     177           2 :     wstride=0; parse("WSTRIDE",wstride); parse("FMT",ofmt);
+     178           1 :     pathfile.link(*this); pathfile.open( wfilename ); pathfile.setHeavyFlush();
+     179           1 :     if( wstride<update_str ) error("makes no sense to write out path more frequently than update stride");
+     180           1 :     log.printf("  writing path out every %u steps to file named %s with format %s \n",wstride,wfilename.c_str(),ofmt.c_str());
+     181             :   }
+     182           2 :   log<<"  Bibliography "<<plumed.cite("Diaz Leines and Ensing, Phys. Rev. Lett. 109, 020601 (2012)")<<"\n";
+     183           1 : }
+     184             : 
+     185         101 : void AdaptivePath::calculate() {
+     186         101 :   runAllTasks();
+     187         101 : }
+     188             : 
+     189        2020 : void AdaptivePath::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     190             :   // This builds a pack to hold the derivatives
+     191        2020 :   ReferenceValuePack mypack( getNumberOfArguments(), getNumberOfAtoms(), myvals );
+     192        2020 :   finishPackSetup( current, mypack );
+     193             :   // Calculate the distance from the frame
+     194        2020 :   double val=calculateDistanceFunction( current, mypack, true );
+     195             :   // Put the element value in element zero
+     196             :   myvals.setValue( 0, val ); myvals.setValue( 1, 1.0 );
+     197        2020 :   return;
+     198        2020 : }
+     199             : 
+     200        2020 : double AdaptivePath::transformHD( const double& dist, double& df ) const {
+     201        2020 :   df=1.0; return dist;
+     202             : }
+     203             : 
+     204         101 : void AdaptivePath::update() {
+     205         101 :   double weight2 = -1.*mypathv->dx;
+     206         101 :   double weight1 = 1.0 + mypathv->dx;
+     207         101 :   if( weight1>1.0 ) {
+     208           0 :     weight1=1.0; weight2=0.0;
+     209         101 :   } else if( weight2>1.0 ) {
+     210           0 :     weight1=0.0; weight2=1.0;
+     211             :   }
+     212             :   // Add projections to dispalcement accumulators
+     213         101 :   ReferenceConfiguration* myref = getReferenceConfiguration( mypathv->iclose1 );
+     214         101 :   myref->extractDisplacementVector( getPositions(), getArguments(), mypathv->cargs, false, displacement );
+     215         101 :   getReferenceConfiguration( mypathv->iclose2 )->extractDisplacementVector( myref->getReferencePositions(), getArguments(), myref->getReferenceArguments(), false, displacement2 );
+     216         101 :   displacement.addDirection( -mypathv->dx, displacement2 );
+     217         101 :   pdisplacements[mypathv->iclose1].addDirection( weight1, displacement );
+     218         101 :   pdisplacements[mypathv->iclose2].addDirection( weight2, displacement );
+     219             :   // Update weight accumulators
+     220         101 :   wsum[mypathv->iclose1] *= fadefact;
+     221         101 :   wsum[mypathv->iclose2] *= fadefact;
+     222         101 :   wsum[mypathv->iclose1] += weight1;
+     223         101 :   wsum[mypathv->iclose2] += weight2;
+     224             : 
+     225             :   // This does the update of the path if it is time to
+     226         101 :   if( (getStep()>0) && (getStep()%update_str==0) ) {
+     227           2 :     wsum[fixedn[0]]=wsum[fixedn[1]]=0.;
+     228          42 :     for(unsigned inode=0; inode<getNumberOfReferencePoints(); ++inode) {
+     229          40 :       if( wsum[inode]>0 ) {
+     230             :         // First displace the node by the weighted direction
+     231           6 :         getReferenceConfiguration( inode )->displaceReferenceConfiguration( 1./wsum[inode], pdisplacements[inode] );
+     232             :         // Reset the displacement
+     233           6 :         pdisplacements[inode].zeroDirection();
+     234             :       }
+     235             :     }
+     236             :     // Now ensure all the nodes of the path are equally spaced
+     237           2 :     PathReparameterization myspacings( getPbc(), getArguments(), getAllReferenceConfigurations() );
+     238           2 :     myspacings.reparameterize( fixedn[0], fixedn[1], tolerance );
+     239           2 :   }
+     240         101 :   if( (getStep()>0) && (getStep()%wstride==0) ) {
+     241           2 :     pathfile<<"# PATH AT STEP "<<getStep();
+     242           2 :     pathfile.printf(" TIME %f \n",getTime());
+     243             :     std::vector<std::unique_ptr<ReferenceConfiguration>>& myconfs=getAllReferenceConfigurations();
+     244           2 :     auto* mymoldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     245           2 :     std::vector<std::string> argument_names( getNumberOfArguments() );
+     246           6 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) argument_names[i] = getPntrToArgument(i)->getName();
+     247           2 :     PDB mypdb; mypdb.setArgumentNames( argument_names );
+     248          42 :     for(unsigned i=0; i<myconfs.size(); ++i) {
+     249          80 :       pathfile.printf("REMARK TYPE=%s\n", myconfs[i]->getName().c_str() );
+     250          40 :       mypdb.setAtomPositions( myconfs[i]->getReferencePositions() );
+     251         120 :       for(unsigned j=0; j<getNumberOfArguments(); ++j) mypdb.setArgumentValue( getPntrToArgument(j)->getName(), myconfs[i]->getReferenceArgument(j) );
+     252          40 :       mypdb.print( getUnits().getLength()/0.1, mymoldat, pathfile, ofmt );
+     253             :     }
+     254           2 :     pathfile.flush();
+     255           2 :   }
+     256         101 : }
+     257             : 
+     258             : }
+     259             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Mapping.cpp.func-sort-c.html b/coverage/mapping/Mapping.cpp.func-sort-c.html new file mode 100644 index 000000000000..f347399a7cca --- /dev/null +++ b/coverage/mapping/Mapping.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - mapping/Mapping.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - Mapping.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8210578.1 %
Date:2024-02-22 21:58:45Functions:81266.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7Mapping15getArgumentNameB5cxx11ERj0
_ZN4PLMD7mapping7Mapping29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7Mapping9getLambdaEv0
_ZN4PLMD7mapping7MappingC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping7MappingC2ERKNS_13ActionOptionsE10
_ZZN4PLMD7mapping7MappingC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_10
_ZN4PLMD7mapping7Mapping16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD7mapping7Mapping17turnOnDerivativesEv19
_ZN4PLMD7mapping7Mapping5applyEv5015
_ZN4PLMD7mapping7Mapping25getReferenceConfigurationERKj13175
_ZNK4PLMD7mapping7Mapping15finishPackSetupERKjRNS_18ReferenceValuePackE172372
_ZNK4PLMD7mapping7Mapping25calculateDistanceFunctionERKjRNS_18ReferenceValuePackERKb172372
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Mapping.cpp.func.html b/coverage/mapping/Mapping.cpp.func.html new file mode 100644 index 000000000000..90f23c6c0c52 --- /dev/null +++ b/coverage/mapping/Mapping.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - mapping/Mapping.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - Mapping.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8210578.1 %
Date:2024-02-22 21:58:45Functions:81266.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7Mapping15getArgumentNameB5cxx11ERj0
_ZN4PLMD7mapping7Mapping16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD7mapping7Mapping17turnOnDerivativesEv19
_ZN4PLMD7mapping7Mapping25getReferenceConfigurationERKj13175
_ZN4PLMD7mapping7Mapping29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7Mapping5applyEv5015
_ZN4PLMD7mapping7Mapping9getLambdaEv0
_ZN4PLMD7mapping7MappingC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping7MappingC2ERKNS_13ActionOptionsE10
_ZNK4PLMD7mapping7Mapping15finishPackSetupERKjRNS_18ReferenceValuePackE172372
_ZNK4PLMD7mapping7Mapping25calculateDistanceFunctionERKjRNS_18ReferenceValuePackERKb172372
_ZZN4PLMD7mapping7MappingC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Mapping.cpp.gcov.html b/coverage/mapping/Mapping.cpp.gcov.html new file mode 100644 index 000000000000..36b0eba57c6a --- /dev/null +++ b/coverage/mapping/Mapping.cpp.gcov.html @@ -0,0 +1,289 @@ + + + + + + + + LCOV - plumed test coverage - mapping/Mapping.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - Mapping.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8210578.1 %
Date:2024-02-22 21:58:45Functions:81266.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Mapping.h"
+      23             : #include "vesselbase/Vessel.h"
+      24             : #include "reference/MetricRegister.h"
+      25             : #include "reference/ReferenceAtoms.h"
+      26             : #include "tools/PDB.h"
+      27             : #include "tools/Matrix.h"
+      28             : #include "core/PlumedMain.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace mapping {
+      32             : 
+      33          16 : void Mapping::registerKeywords( Keywords& keys ) {
+      34          16 :   Action::registerKeywords( keys );
+      35          16 :   ActionWithValue::registerKeywords( keys );
+      36          16 :   ActionWithArguments::registerKeywords( keys );
+      37          16 :   ActionAtomistic::registerKeywords( keys );
+      38          16 :   vesselbase::ActionWithVessel::registerKeywords( keys );
+      39          32 :   keys.add("compulsory","REFERENCE","a pdb file containing the set of reference configurations");
+      40          32 :   keys.add("compulsory","PROPERTY","the property to be used in the index. This should be in the REMARK of the reference");
+      41          32 :   keys.add("compulsory","TYPE","OPTIMAL-FAST","the manner in which distances are calculated. More information on the different "
+      42             :            "metrics that are available in PLUMED can be found in the section of the manual on "
+      43             :            "\\ref dists");
+      44          32 :   keys.addFlag("DISABLE_CHECKS",false,"disable checks on reference input structures.");
+      45          16 : }
+      46             : 
+      47          10 : Mapping::Mapping(const ActionOptions&ao):
+      48             :   Action(ao),
+      49             :   ActionAtomistic(ao),
+      50             :   ActionWithArguments(ao),
+      51             :   ActionWithValue(ao),
+      52          10 :   ActionWithVessel(ao)
+      53             : {
+      54             :   // Read the input
+      55          10 :   std::string mtype; parse("TYPE",mtype);
+      56          10 :   bool skipchecks; parseFlag("DISABLE_CHECKS",skipchecks);
+      57             : 
+      58             :   // Read the properties we require
+      59             :   bool ispath=false;
+      60          20 :   if( keywords.exists("PROPERTY") ) {
+      61           6 :     std::vector<std::string> propnames; parseVector("PROPERTY",propnames);
+      62           3 :     if(propnames.size()==0) error("no properties were specified");
+      63           9 :     for(unsigned i=0; i<propnames.size(); ++i) property.insert( std::pair<std::string,std::vector<double> >( propnames[i], std::vector<double>() ) );
+      64           3 :   } else {
+      65          14 :     property.insert( std::pair<std::string,std::vector<double> >( "spath", std::vector<double>() ) ); ispath=true;
+      66             :   }
+      67             : 
+      68             :   // Open reference file
+      69          10 :   std::string reference; parse("REFERENCE",reference);
+      70             : 
+      71          10 :   FILE* fp=this->fopen(reference.c_str(),"r");
+      72          10 :   if(!fp) error("could not open reference file " + reference );
+      73             : 
+      74             :   // call fclose when exiting this block
+      75          10 :   auto deleter=[this](FILE* f) { this->fclose(f); };
+      76             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+      77             : 
+      78             :   // Read all reference configurations
+      79             :   bool do_read=true; unsigned nfram=0; double wnorm=0., ww;
+      80         426 :   while (do_read) {
+      81             :     // Read the pdb file
+      82         426 :     PDB mypdb; do_read=mypdb.readFromFilepointer(fp,usingNaturalUnits(),0.1/getUnits().getLength());
+      83             :     // Break if we are done
+      84         426 :     if( !do_read ) break ;
+      85             :     // Check for required properties
+      86         416 :     if( !ispath ) {
+      87             :       double prop;
+      88         378 :       for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+      89         252 :         if( !mypdb.getArgumentValue( it->first, prop ) ) error("pdb input does not have contain property named " + it->first );
+      90         252 :         it->second.push_back(prop);
+      91             :       }
+      92             :     } else {
+      93         580 :       property.find("spath")->second.push_back( myframes.size()+1 );
+      94             :     }
+      95             :     // Fix argument names
+      96         416 :     expandArgKeywordInPDB( mypdb );
+      97             :     // And read the frame
+      98         416 :     myframes.emplace_back( metricRegister().create<ReferenceConfiguration>( mtype, mypdb ) );
+      99         832 :     if( !mypdb.getArgumentValue( "WEIGHT", ww ) ) ww=1.0;
+     100         416 :     weights.push_back( ww ); wnorm+=ww; nfram++;
+     101         426 :   }
+     102             : 
+     103          10 :   if(nfram==0 ) error("no reference configurations were specified");
+     104          10 :   log.printf("  found %u configurations in file %s\n",nfram,reference.c_str() );
+     105         426 :   for(unsigned i=0; i<weights.size(); ++i) weights[i] = weights[i]/wnorm;
+     106             : 
+     107             :   // Finish the setup of the mapping object
+     108             :   // Get the arguments and atoms that are required
+     109             :   std::vector<AtomNumber> atoms; std::vector<std::string> args;
+     110         426 :   for(unsigned i=0; i<myframes.size(); ++i) { myframes[i]->getAtomRequests( atoms, skipchecks ); myframes[i]->getArgumentRequests( args, skipchecks ); }
+     111          10 :   std::vector<Value*> req_args; interpretArgumentList( args, req_args );
+     112          10 :   if( req_args.size()>0 && atoms.size()>0 ) error("cannot mix atoms and arguments");
+     113          10 :   if( req_args.size()>0 ) requestArguments( req_args );
+     114          10 :   if( atoms.size()>0 ) {
+     115           8 :     log.printf("  found %zu atoms in input \n",atoms.size());
+     116           8 :     log.printf("  with indices : ");
+     117         112 :     for(unsigned i=0; i<atoms.size(); ++i) {
+     118         104 :       if(i%25==0) log<<"\n";
+     119         104 :       log.printf("%d ",atoms[i].serial());
+     120             :     }
+     121           8 :     log.printf("\n");
+     122           8 :     requestAtoms( atoms );
+     123             :   }
+     124             :   // Duplicate all frames (duplicates are used by sketch-map)
+     125             :   // mymap->duplicateFrameList();
+     126             :   // fframes.resize( 2*nfram, 0.0 ); dfframes.resize( 2*nfram, 0.0 );
+     127             :   // plumed_assert( !mymap->mappingNeedsSetup() );
+     128             :   // Resize all derivative arrays
+     129             :   // mymap->setNumberOfAtomsAndArguments( atoms.size(), args.size() );
+     130             :   // Resize forces array
+     131          10 :   if( getNumberOfAtoms()>0 ) {
+     132           8 :     forcesToApply.resize( 3*getNumberOfAtoms() + 9 + getNumberOfArguments() );
+     133             :   } else {
+     134           2 :     forcesToApply.resize( getNumberOfArguments() );
+     135             :   }
+     136          30 : }
+     137             : 
+     138          19 : void Mapping::turnOnDerivatives() {
+     139          19 :   ActionWithValue::turnOnDerivatives();
+     140          19 :   needsDerivatives();
+     141          19 : }
+     142             : 
+     143           0 : double Mapping::getLambda() {
+     144           0 :   plumed_merror("lambda is not defined in this mapping type");
+     145             : }
+     146             : 
+     147           0 : std::string Mapping::getArgumentName( unsigned& iarg ) {
+     148           0 :   if( iarg < getNumberOfArguments() ) return getPntrToArgument(iarg)->getName();
+     149           0 :   unsigned iatom=iarg - getNumberOfArguments();
+     150           0 :   std::string atnum; Tools::convert( getAbsoluteIndex(iatom).serial(),atnum);
+     151           0 :   unsigned icomp=iatom%3;
+     152           0 :   if(icomp==0) return "pos" + atnum + "x";
+     153           0 :   if(icomp==1) return "pos" + atnum + "y";
+     154           0 :   return "pos" + atnum + "z";
+     155             : }
+     156             : 
+     157      172372 : void Mapping::finishPackSetup( const unsigned& ifunc, ReferenceValuePack& mypack ) const {
+     158             :   mypack.setValIndex(0);
+     159      172372 :   unsigned nargs2=myframes[ifunc]->getNumberOfReferenceArguments();
+     160      172372 :   unsigned nat2=myframes[ifunc]->getNumberOfReferencePositions();
+     161      172372 :   if( mypack.getNumberOfAtoms()!=nat2 || mypack.getNumberOfArguments()!=nargs2 ) mypack.resize( nargs2, nat2 );
+     162      172372 :   if( nat2>0 ) {
+     163      137592 :     ReferenceAtoms* myat2=dynamic_cast<ReferenceAtoms*>( myframes[ifunc].get() ); plumed_dbg_assert( myat2 );
+     164     1926288 :     for(unsigned i=0; i<nat2; ++i) mypack.setAtomIndex( i, myat2->getAtomIndex(i) );
+     165             :   }
+     166      172372 : }
+     167             : 
+     168      172372 : double Mapping::calculateDistanceFunction( const unsigned& ifunc, ReferenceValuePack& myder, const bool& squared ) const {
+     169             :   // Calculate the distance
+     170      172372 :   double dd = myframes[ifunc]->calculate( getPositions(), getPbc(), getArguments(), myder, squared );
+     171             :   // Transform distance by whatever
+     172      172372 :   double df, ff=transformHD( dd, df ); myder.scaleAllDerivatives( df );
+     173             :   // And the virial
+     174      172372 :   if( getNumberOfAtoms()>0 && !myder.virialWasSet() ) {
+     175      137592 :     Tensor tvir; tvir.zero();
+     176     1926288 :     for(unsigned i=0; i<myder.getNumberOfAtoms(); ++i) tvir +=-1.0*Tensor( getPosition( myder.getAtomIndex(i) ), myder.getAtomDerivative(i) );
+     177      137592 :     myder.addBoxDerivatives( tvir );
+     178             :   }
+     179      172372 :   return ff;
+     180             : }
+     181             : 
+     182       13175 : ReferenceConfiguration* Mapping::getReferenceConfiguration( const unsigned& ifunc ) {
+     183       13175 :   return myframes[ifunc].get();
+     184             : }
+     185             : 
+     186           0 : void Mapping::calculateNumericalDerivatives( ActionWithValue* a ) {
+     187           0 :   if( getNumberOfArguments()>0 ) {
+     188           0 :     ActionWithArguments::calculateNumericalDerivatives( a );
+     189             :   }
+     190           0 :   if( getNumberOfAtoms()>0 ) {
+     191           0 :     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
+     192           0 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     193           0 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
+     194             :     }
+     195           0 :     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
+     196           0 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     197           0 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
+     198             :     }
+     199             :   }
+     200           0 : }
+     201             : 
+     202        5015 : void Mapping::apply() {
+     203        5015 :   if( getForcesFromVessels( forcesToApply ) ) {
+     204           0 :     unsigned ind=0; addForcesOnArguments( 0, forcesToApply, ind );
+     205           0 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, ind );
+     206             :   }
+     207        5015 : }
+     208             : 
+     209             : }
+     210             : }
+     211             : 
+     212             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Mapping.h.func-sort-c.html b/coverage/mapping/Mapping.h.func-sort-c.html new file mode 100644 index 000000000000..cc3aca2234eb --- /dev/null +++ b/coverage/mapping/Mapping.h.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - mapping/Mapping.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - Mapping.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121392.3 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7Mapping10isPeriodicEv0
_ZN4PLMD7mapping7Mapping12lockRequestsEv5015
_ZN4PLMD7mapping7Mapping14unlockRequestsEv5015
_ZN4PLMD7mapping7Mapping22getNumberOfDerivativesEv20192
_ZNK4PLMD7mapping7Mapping16getPropertyValueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30972
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Mapping.h.func.html b/coverage/mapping/Mapping.h.func.html new file mode 100644 index 000000000000..60d2f142a7a4 --- /dev/null +++ b/coverage/mapping/Mapping.h.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - mapping/Mapping.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - Mapping.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121392.3 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7Mapping10isPeriodicEv0
_ZN4PLMD7mapping7Mapping12lockRequestsEv5015
_ZN4PLMD7mapping7Mapping14unlockRequestsEv5015
_ZN4PLMD7mapping7Mapping22getNumberOfDerivativesEv20192
_ZNK4PLMD7mapping7Mapping16getPropertyValueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE30972
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Mapping.h.gcov.html b/coverage/mapping/Mapping.h.gcov.html new file mode 100644 index 000000000000..3d3e2110b1a8 --- /dev/null +++ b/coverage/mapping/Mapping.h.gcov.html @@ -0,0 +1,224 @@ + + + + + + + + LCOV - plumed test coverage - mapping/Mapping.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - Mapping.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121392.3 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_mapping_Mapping_h
+      23             : #define __PLUMED_mapping_Mapping_h
+      24             : 
+      25             : #include "core/ActionAtomistic.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : #include "core/ActionWithArguments.h"
+      28             : #include "vesselbase/ActionWithVessel.h"
+      29             : #include "reference/ReferenceConfiguration.h"
+      30             : #include <vector>
+      31             : #include <map>
+      32             : #include <memory>
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : class PDB;
+      37             : 
+      38             : namespace mapping {
+      39             : 
+      40             : class Mapping :
+      41             :   public ActionAtomistic,
+      42             :   public ActionWithArguments,
+      43             :   public ActionWithValue,
+      44             :   public vesselbase::ActionWithVessel
+      45             : {
+      46             :   friend class PropertyMap;
+      47             :   friend class TrigonometricPathVessel;
+      48             :   friend class AdaptivePath;
+      49             : private:
+      50             : //  The derivative wrt to the distance from the frame
+      51             :   std::vector<double> dfframes;
+      52             : /// This holds all the reference information
+      53             :   std::vector<std::unique_ptr<ReferenceConfiguration> > myframes;
+      54             : /// The forces on each of the derivatives (used in apply)
+      55             :   std::vector<double> forcesToApply;
+      56             : /// The weights of the various configurations
+      57             :   std::vector<double> weights;
+      58             : /// The list of properties in the property map
+      59             :   std::map<std::string,std::vector<double> > property;
+      60             : protected:
+      61             : /// The (transformed) distance from each frame
+      62             :   std::vector<double> fframes;
+      63             : /// Get the number of frames in the path
+      64             :   unsigned getNumberOfReferencePoints() const;
+      65             : /// Finish the setup of the referenceValuePack by transferring atoms and args
+      66             :   void finishPackSetup( const unsigned& ifunc, ReferenceValuePack& mypack ) const ;
+      67             : /// Calculate the value of the distance from the ith frame
+      68             :   double calculateDistanceFunction( const unsigned& ifunc, ReferenceValuePack& myder, const bool& squared ) const ;
+      69             : /// Get the value of the weight
+      70             :   double getWeight( const unsigned& weight ) const ;
+      71             : /// Return the vector of refernece configurations
+      72             :   std::vector<std::unique_ptr<ReferenceConfiguration>>& getAllReferenceConfigurations();
+      73             : /// Return a pointer to one of the reference configurations
+      74             :   ReferenceConfiguration* getReferenceConfiguration( const unsigned& ifunc );
+      75             : public:
+      76             :   static void registerKeywords( Keywords& keys );
+      77             :   explicit Mapping(const ActionOptions&);
+      78             : /// Overload the virtual functions that appear in both ActionAtomistic and ActionWithArguments
+      79             :   void turnOnDerivatives() override;
+      80             :   void calculateNumericalDerivatives( ActionWithValue* a=NULL ) override;
+      81             :   void lockRequests() override;
+      82             :   void unlockRequests() override;
+      83             : /// Distance from a point is never periodic
+      84           0 :   bool isPeriodic() override { return false; }
+      85             : /// Get the number of derivatives for this action
+      86             :   unsigned getNumberOfDerivatives() override;  // N.B. This is replacing the virtual function in ActionWithValue
+      87             : /// Get the value of lambda for paths and property maps
+      88             :   virtual double getLambda();
+      89             : /// This does the transformation of the distance by whatever function is required
+      90             :   virtual double transformHD( const double& dist, double& df ) const=0;
+      91             : /// Get the number of properties we are projecting onto
+      92             :   unsigned getNumberOfProperties() const ;
+      93             : /// Get the name of the ith argument
+      94             :   std::string getArgumentName( unsigned& iarg );
+      95             : /// Get the value of the ith property for the current frame
+      96             :   double getPropertyValue( const unsigned& current, const std::string& name ) const ;
+      97             : /// Apply the forces
+      98             :   void apply() override;
+      99             : };
+     100             : 
+     101             : inline
+     102             : unsigned Mapping::getNumberOfReferencePoints() const {
+     103         469 :   return myframes.size();
+     104             : }
+     105             : 
+     106             : inline
+     107       20192 : unsigned Mapping::getNumberOfDerivatives() {
+     108             :   unsigned nat=getNumberOfAtoms();
+     109       20192 :   if(nat>0) return 3*nat + 9 + getNumberOfArguments();
+     110        2612 :   return getNumberOfArguments();
+     111             : }
+     112             : 
+     113             : inline
+     114        5015 : void Mapping::lockRequests() {
+     115             :   ActionWithArguments::lockRequests();
+     116             :   ActionAtomistic::lockRequests();
+     117        5015 : }
+     118             : 
+     119             : inline
+     120        5015 : void Mapping::unlockRequests() {
+     121             :   ActionWithArguments::unlockRequests();
+     122             :   ActionAtomistic::unlockRequests();
+     123        5015 : }
+     124             : 
+     125             : inline
+     126       30972 : double Mapping::getPropertyValue( const unsigned& cur, const std::string& name ) const {
+     127       30972 :   return property.find(name)->second[cur];
+     128             : }
+     129             : 
+     130             : inline
+     131             : double Mapping::getWeight( const unsigned& current ) const {
+     132             :   return weights[current];
+     133             : }
+     134             : 
+     135             : inline
+     136             : std::vector<std::unique_ptr<ReferenceConfiguration>>& Mapping::getAllReferenceConfigurations() {
+     137           2 :   return myframes;
+     138             : }
+     139             : 
+     140             : inline
+     141             : unsigned Mapping::getNumberOfProperties() const {
+     142           3 :   return property.size();
+     143             : }
+     144             : 
+     145             : }
+     146             : }
+     147             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PCAVars.cpp.func-sort-c.html b/coverage/mapping/PCAVars.cpp.func-sort-c.html new file mode 100644 index 000000000000..4437376f5307 --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PCAVars.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PCAVars.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12614388.1 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7PCAVars29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7PCAVarsC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping7PCAVarsC1ERKNS_13ActionOptionsE5
_ZZN4PLMD7mapping7PCAVarsC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_5
_ZN4PLMD7mapping7PCAVars16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7mapping7PCAVars22getNumberOfDerivativesEv36
_ZN4PLMD7mapping7PCAVars12lockRequestsEv55
_ZN4PLMD7mapping7PCAVars14unlockRequestsEv55
_ZN4PLMD7mapping7PCAVars5applyEv55
_ZN4PLMD7mapping7PCAVars9calculateEv55
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PCAVars.cpp.func.html b/coverage/mapping/PCAVars.cpp.func.html new file mode 100644 index 000000000000..67b59fa6d97f --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PCAVars.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PCAVars.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12614388.1 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping7PCAVars12lockRequestsEv55
_ZN4PLMD7mapping7PCAVars14unlockRequestsEv55
_ZN4PLMD7mapping7PCAVars16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7mapping7PCAVars22getNumberOfDerivativesEv36
_ZN4PLMD7mapping7PCAVars29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD7mapping7PCAVars5applyEv55
_ZN4PLMD7mapping7PCAVars9calculateEv55
_ZN4PLMD7mapping7PCAVarsC1ERKNS_13ActionOptionsE5
_ZN4PLMD7mapping7PCAVarsC2ERKNS_13ActionOptionsE0
_ZZN4PLMD7mapping7PCAVarsC4ERKNS_13ActionOptionsEENKUlP8_IO_FILEE_clES6_5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PCAVars.cpp.gcov.html b/coverage/mapping/PCAVars.cpp.gcov.html new file mode 100644 index 000000000000..c09c61c48252 --- /dev/null +++ b/coverage/mapping/PCAVars.cpp.gcov.html @@ -0,0 +1,536 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PCAVars.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PCAVars.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12614388.1 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionWithValue.h"
+      23             : #include "core/ActionAtomistic.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "reference/MetricRegister.h"
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "reference/Direction.h"
+      29             : #include "tools/Pbc.h"
+      30             : 
+      31             : //+PLUMEDOC COLVAR PCAVARS
+      32             : /*
+      33             : Projection on principal component eigenvectors or other high dimensional linear subspace
+      34             : 
+      35             : The collective variables described in \ref dists allow one to calculate the distance between the
+      36             : instantaneous structure adopted by the system and some high-dimensional, reference configuration.  The
+      37             : problem with doing this is that, as one gets further and further from the reference configuration, the
+      38             : distance from it becomes a progressively poorer and poorer collective variable.  This happens because
+      39             : the ``number" of structures at a distance \f$d\f$ from a reference configuration is proportional to \f$d^N\f$ in
+      40             : an \f$N\f$ dimensional space.  Consequently, when \f$d\f$ is small the distance from the reference configuration
+      41             : may well be a good collective variable.  However, when \f$d\f$ is large it is unlikely that the distance from the reference
+      42             : structure is a good CV.  When the distance is large there will almost certainly be markedly different
+      43             : configuration that have the same CV value and hence barriers in transverse degrees of
+      44             : freedom.
+      45             : 
+      46             : For these reasons dimensionality reduction is often employed so a projection \f$\mathbf{s}\f$ of a high-dimensional configuration
+      47             : \f$\mathbf{X}\f$ in a lower dimensionality space using a function:
+      48             : 
+      49             : \f[
+      50             : \mathbf{s} = F(\mathbf{X}-\mathbf{X}^{ref})
+      51             : \f]
+      52             : 
+      53             : where here we have introduced some high-dimensional reference configuration \f$\mathbf{X}^{ref}\f$.  By far the simplest way to
+      54             : do this is to use some linear operator for \f$F\f$.  That is to say we find a low-dimensional projection
+      55             : by rotating the basis vectors using some linear algebra:
+      56             : 
+      57             : \f[
+      58             : \mathbf{s}_i = \sum_k A_{ik} ( X_{k} - X_{k}^{ref} )
+      59             : \f]
+      60             : 
+      61             : Here \f$A\f$ is a \f$d\f$ by \f$D\f$ matrix where \f$D\f$ is the dimensionality of the high dimensional space and \f$d\f$ is
+      62             : the dimensionality of the lower dimensional subspace.  In plumed when this kind of projection you can use the majority
+      63             : of the metrics detailed on \ref dists to calculate the displacement, \f$\mathbf{X}-\mathbf{X}^{ref}\f$, from the reference configuration.
+      64             : The matrix \f$A\f$ can be found by various means including principal component analysis and normal mode analysis.  In both these methods the
+      65             : rows of \f$A\f$ would be the principle eigenvectors of a square matrix.  For PCA the covariance while for normal modes the Hessian.
+      66             : 
+      67             : \bug It is not possible to use the \ref DRMSD metric with this variable.  You can get around this by listing the set of distances you wish to calculate for your DRMSD in the plumed file explicitly and using the EUCLIDEAN metric.  MAHALONOBIS and NORM-EUCLIDEAN also do not work with this variable but using these options makes little sense when projecting on a linear subspace.
+      68             : 
+      69             : \par Examples
+      70             : 
+      71             : The following input calculates a projection on a linear subspace where the displacements
+      72             : from the reference configuration are calculated using the OPTIMAL metric.  Consequently,
+      73             : both translation of the center of mass of the atoms and rotation of the reference
+      74             : frame are removed from these displacements.  The matrix \f$A\f$ and the reference
+      75             : configuration \f$R^{ref}\f$ are specified in the pdb input file reference.pdb and the
+      76             : value of all projections (and the residual) are output to a file called colvar2.
+      77             : 
+      78             : \plumedfile
+      79             : PCAVARS REFERENCE=reference.pdb TYPE=OPTIMAL LABEL=pca2
+      80             : PRINT ARG=pca2.* FILE=colvar2
+      81             : \endplumedfile
+      82             : 
+      83             : The reference configurations can be specified using a pdb file.  The first configuration that you provide is the reference configuration,
+      84             : which is referred to in the above as \f$X^{ref}\f$ subsequent configurations give the directions of row vectors that are contained in
+      85             : the matrix \f$A\f$ above.  These directions can be specified by specifying a second configuration - in this case a vector will
+      86             : be constructed by calculating the displacement of this second configuration from the reference configuration.  A pdb input prepared
+      87             : in this way would look as follows:
+      88             : 
+      89             : \auxfile{reference.pdb}
+      90             : REMARK TYPE=OPTIMAL
+      91             : ATOM      2  CH3 ACE     1      12.932 -14.718  -6.016  1.00  1.00
+      92             : ATOM      5  C   ACE     1      21.312  -9.928  -5.946  1.00  1.00
+      93             : ATOM      9  CA  ALA     2      19.462 -11.088  -8.986  1.00  1.00
+      94             : ATOM     13  HB2 ALA     2      21.112 -10.688 -12.476  1.00  1.00
+      95             : ATOM     15  C   ALA     2      19.422   7.978 -14.536  1.00  1.00
+      96             : ATOM     20 HH31 NME     3      20.122  -9.928 -17.746  1.00  1.00
+      97             : ATOM     21 HH32 NME     3      18.572 -13.148 -16.346  1.00  1.00
+      98             : END
+      99             : REMARK TYPE=OPTIMAL
+     100             : ATOM      2  CH3 ACE     1      13.932 -14.718  -6.016  1.00  1.00
+     101             : ATOM      5  C   ACE     1      20.312  -9.928  -5.946  1.00  1.00
+     102             : ATOM      9  CA  ALA     2      18.462 -11.088  -8.986  1.00  1.00
+     103             : ATOM     13  HB2 ALA     2      20.112 -11.688 -12.476  1.00  1.00
+     104             : ATOM     15  C   ALA     2      19.422   7.978 -12.536  1.00  1.00
+     105             : ATOM     20 HH31 NME     3      20.122  -9.928 -17.746  1.00  1.00
+     106             : ATOM     21 HH32 NME     3      18.572 -13.148 -16.346  1.00  1.00
+     107             : END
+     108             : \endauxfile
+     109             : 
+     110             : Alternatively, the second configuration can specify the components of \f$A\f$ explicitly.  In this case you need to include the
+     111             : keyword TYPE=DIRECTION in the remarks to the pdb as shown below.
+     112             : 
+     113             : \verbatim
+     114             : ATOM      2  CH3 ACE     1      12.932 -14.718  -6.016  1.00  1.00
+     115             : ATOM      5  C   ACE     1      21.312  -9.928  -5.946  1.00  1.00
+     116             : ATOM      9  CA  ALA     2      19.462 -11.088  -8.986  1.00  1.00
+     117             : ATOM     13  HB2 ALA     2      21.112 -10.688 -12.476  1.00  1.00
+     118             : ATOM     15  C   ALA     2      19.422   7.978 -14.536  1.00  1.00
+     119             : ATOM     20 HH31 NME     3      20.122  -9.928 -17.746  1.00  1.00
+     120             : ATOM     21 HH32 NME     3      18.572 -13.148 -16.346  1.00  1.00
+     121             : END
+     122             : REMARK TYPE=DIRECTION
+     123             : ATOM      2  CH3 ACE     1      0.1414  0.3334 -0.0302  1.00  0.00
+     124             : ATOM      5  C   ACE     1      0.0893 -0.1095 -0.1434  1.00  0.00
+     125             : ATOM      9  CA  ALA     2      0.0207 -0.321   0.0321  1.00  0.00
+     126             : ATOM     13  HB2 ALA     2      0.0317 -0.6085  0.0783  1.00  0.00
+     127             : ATOM     15  C   ALA     2      0.1282 -0.4792  0.0797  1.00  0.00
+     128             : ATOM     20 HH31 NME     3      0.0053 -0.465   0.0309  1.00  0.00
+     129             : ATOM     21 HH32 NME     3     -0.1019 -0.4261 -0.0082  1.00  0.00
+     130             : END
+     131             : \endverbatim
+     132             : 
+     133             : If your metric involves arguments the labels of these arguments in your plumed input file should be specified in the REMARKS
+     134             : for each of the frames of your path.  An input file in this case might look like this:
+     135             : 
+     136             : \verbatim
+     137             : DESCRIPTION: a pca eigenvector specified using the start point and direction in the HD space.
+     138             : REMARK WEIGHT=1.0
+     139             : REMARK ARG=d1,d2
+     140             : REMARK d1=1.0 d2=1.0
+     141             : END
+     142             : REMARK TYPE=DIRECTION
+     143             : REMARK ARG=d1,d2
+     144             : REMARK d1=0.1 d2=0.25
+     145             : END
+     146             : \endverbatim
+     147             : 
+     148             : Here we are working with the EUCLIDEAN metric and notice that we have specified the components of \f$A\f$ using DIRECTION.
+     149             : Consequently, the values of d1 and d2 in the second frame above do not specify a particular coordinate in the high-dimensional
+     150             : space as in they do in the first frame.  Instead these values are the coefficients that can be used to construct a linear combination of d1 and d2.
+     151             : If we wanted to specify the direction in this metric using the start and end point of the vector we would write:
+     152             : 
+     153             : \verbatim
+     154             : DESCRIPTION: a pca eigenvector specified using the start and end point of a vector in the HD space.
+     155             : REMARK WEIGHT=1.0
+     156             : REMARK ARG=d1,d2
+     157             : REMARK d1=1.0 d2=1.0
+     158             : END
+     159             : REMARK ARG=d1,d2
+     160             : REMARK d1=1.1 d2=1.25
+     161             : END
+     162             : \endverbatim
+     163             : 
+     164             : */
+     165             : //+ENDPLUMEDOC
+     166             : 
+     167             : namespace PLMD {
+     168             : namespace mapping {
+     169             : 
+     170             : class PCAVars :
+     171             :   public ActionWithValue,
+     172             :   public ActionAtomistic,
+     173             :   public ActionWithArguments
+     174             : {
+     175             : private:
+     176             : /// The holders for the derivatives
+     177             :   MultiValue myvals;
+     178             :   ReferenceValuePack mypack;
+     179             : /// The position of the reference configuration (the one we align to)
+     180             :   std::unique_ptr<ReferenceConfiguration> myref;
+     181             : /// The eigenvectors we are interested in
+     182             :   std::vector<Direction> directions;
+     183             : /// Stuff for applying forces
+     184             :   std::vector<double> forces, forcesToApply;
+     185             :   bool nopbc;
+     186             : public:
+     187             :   static void registerKeywords( Keywords& keys );
+     188             :   explicit PCAVars(const ActionOptions&);
+     189             :   unsigned getNumberOfDerivatives() override;
+     190             :   void lockRequests() override;
+     191             :   void unlockRequests() override;
+     192             :   void calculateNumericalDerivatives( ActionWithValue* a ) override;
+     193             :   void calculate() override;
+     194             :   void apply() override;
+     195             : };
+     196             : 
+     197             : PLUMED_REGISTER_ACTION(PCAVars,"PCAVARS")
+     198             : 
+     199           7 : void PCAVars::registerKeywords( Keywords& keys ) {
+     200           7 :   Action::registerKeywords( keys );
+     201           7 :   ActionWithValue::registerKeywords( keys );
+     202           7 :   ActionAtomistic::registerKeywords( keys );
+     203           7 :   ActionWithArguments::registerKeywords( keys );
+     204           7 :   componentsAreNotOptional(keys); keys.use("ARG");
+     205          14 :   keys.addOutputComponent("eig","default","the projections on each eigenvalue are stored on values labeled eig-1, eig-2, ...");
+     206          14 :   keys.addOutputComponent("residual","default","the distance of the configuration from the linear subspace defined "
+     207             :                           "by the vectors, eig-1, eig2, ... that are contained in the rows of A.");
+     208          14 :   keys.add("compulsory","REFERENCE","a pdb file containing the reference configuration and configurations that define the directions for each eigenvector");
+     209          14 :   keys.add("compulsory","TYPE","OPTIMAL","The method we are using for alignment to the reference structure");
+     210          14 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     211           7 : }
+     212             : 
+     213           5 : PCAVars::PCAVars(const ActionOptions& ao):
+     214             :   Action(ao),
+     215             :   ActionWithValue(ao),
+     216             :   ActionAtomistic(ao),
+     217             :   ActionWithArguments(ao),
+     218          10 :   myvals(1,0),
+     219           5 :   mypack(0,0,myvals),
+     220          10 :   nopbc(false)
+     221             : {
+     222             : 
+     223             :   // What type of distance are we calculating
+     224           5 :   std::string mtype; parse("TYPE",mtype);
+     225             : 
+     226          10 :   parseFlag("NOPBC",nopbc);
+     227             : 
+     228             :   // Open reference file
+     229          10 :   std::string reference; parse("REFERENCE",reference);
+     230           5 :   FILE* fp=this->fopen(reference.c_str(),"r");
+     231           5 :   if(!fp) error("could not open reference file " + reference );
+     232             : 
+     233             :   // call fclose when exiting this block
+     234           5 :   auto deleter=[this](FILE* f) { this->fclose(f); };
+     235             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     236             : 
+     237             :   // Read all reference configurations
+     238             :   // MultiReferenceBase myframes( "", false );
+     239             :   std::vector<std::unique_ptr<ReferenceConfiguration> > myframes;
+     240             :   bool do_read=true; unsigned nfram=0;
+     241          20 :   while (do_read) {
+     242          20 :     PDB mypdb;
+     243             :     // Read the pdb file
+     244          20 :     do_read=mypdb.readFromFilepointer(fp,usingNaturalUnits(),0.1/getUnits().getLength());
+     245             :     // Fix argument names
+     246          20 :     if(do_read) {
+     247          15 :       if( nfram==0 ) {
+     248          10 :         myref=metricRegister().create<ReferenceConfiguration>( mtype, mypdb );
+     249           5 :         Direction* tdir = dynamic_cast<Direction*>( myref.get() );
+     250           5 :         if( tdir ) error("first frame should be reference configuration - not direction of vector");
+     251           5 :         if( !myref->pcaIsEnabledForThisReference() ) error("can't do PCA with reference type " + mtype );
+     252             :         // std::vector<std::string> remarks( mypdb.getRemark() ); std::string rtype;
+     253             :         // bool found=Tools::parse( remarks, "TYPE", rtype );
+     254             :         // if(!found){ std::vector<std::string> newrem(1); newrem[0]="TYPE="+mtype; mypdb.addRemark(newrem); }
+     255             :         // myframes.push_back( metricRegister().create<ReferenceConfiguration>( "", mypdb ) );
+     256             :       } else {
+     257          10 :         auto mymsd = metricRegister().create<ReferenceConfiguration>( "", mypdb );
+     258          10 :         myframes.emplace_back( std::move(mymsd) );
+     259          10 :       }
+     260          15 :       nfram++;
+     261             :     } else {
+     262             :       break;
+     263             :     }
+     264          20 :   }
+     265             : 
+     266           5 :   if( nfram<=1 ) error("no eigenvectors were specified");
+     267           5 :   log.printf("  found %u eigenvectors in file %s \n",nfram-1,reference.c_str() );
+     268             : 
+     269             :   // Finish the setup of the mapping object
+     270             :   // Get the arguments and atoms that are required
+     271           5 :   std::vector<AtomNumber> atoms; myref->getAtomRequests( atoms, false );
+     272           5 :   std::vector<std::string> args; myref->getArgumentRequests( args, false );
+     273           5 :   if( atoms.size()>0 ) {
+     274           5 :     log.printf("  found %zu atoms in input \n",atoms.size());
+     275           5 :     log.printf("  with indices : ");
+     276          40 :     for(unsigned i=0; i<atoms.size(); ++i) {
+     277          35 :       if(i%25==0) log<<"\n";
+     278          35 :       log.printf("%d ",atoms[i].serial());
+     279             :     }
+     280           5 :     log.printf("\n");
+     281             :   }
+     282           5 :   requestAtoms( atoms ); std::vector<Value*> req_args;
+     283           5 :   interpretArgumentList( args, req_args ); requestArguments( req_args );
+     284             : 
+     285             :   // And now check that the atoms/arguments are the same in all the eigenvalues
+     286          15 :   for(unsigned i=0; i<myframes.size(); ++i) { myframes[i]->getAtomRequests( atoms, false ); myframes[i]->getArgumentRequests( args, false ); }
+     287             : 
+     288             :   // Setup the derivative pack
+     289           5 :   if( atoms.size()>0 ) myvals.resize( 1, args.size() + 3*atoms.size() + 9 );
+     290           0 :   else myvals.resize( 1, args.size() );
+     291           5 :   mypack.resize( args.size(), atoms.size() );
+     292          40 :   for(unsigned i=0; i<atoms.size(); ++i) mypack.setAtomIndex( i, i );
+     293             :   /// This sets up all the storage data required by PCA in the pack
+     294           5 :   myref->setupPCAStorage( mypack );
+     295             : 
+     296             :   // Check there are no periodic arguments
+     297           5 :   for(unsigned i=0; i<getNumberOfArguments(); ++i) {
+     298           0 :     if( getPntrToArgument(i)->isPeriodic() ) error("cannot use periodic variables in pca projections");
+     299             :   }
+     300             :   // Work out if the user wants to normalise the input vector
+     301           5 :   checkRead();
+     302             : 
+     303           5 :   if(nopbc) log.printf("  without periodic boundary conditions\n");
+     304           4 :   else      log.printf("  using periodic boundary conditions\n");
+     305             : 
+     306             :   // Resize the matrices that will hold our eivenvectors
+     307           5 :   PDB mypdb; mypdb.setAtomNumbers( atoms ); mypdb.addBlockEnd( atoms.size() );
+     308           5 :   if( args.size()>0 ) mypdb.setArgumentNames( args );
+     309             :   // Resize the matrices that will hold our eivenvectors
+     310          15 :   for(unsigned i=0; i<myframes.size(); ++i) {
+     311          20 :     directions.push_back( Direction(ReferenceConfigurationOptions("DIRECTION"))); directions[i].read( mypdb );
+     312             :   }
+     313             : 
+     314             :   // Create fake periodic boundary condition (these would only be used for DRMSD which is not allowed)
+     315             :   // Now calculate the eigenvectors
+     316          15 :   for(unsigned i=0; i<myframes.size(); ++i) {
+     317             :     // Calculate distance from reference configuration
+     318          10 :     myframes[i]->extractDisplacementVector( myref->getReferencePositions(), getArguments(), myref->getReferenceArguments(), true, directions[i] );
+     319             :     // Create a component to store the output
+     320          10 :     std::string num; Tools::convert( i+1, num );
+     321          30 :     addComponentWithDerivatives("eig-"+num); componentIsNotPeriodic("eig-"+num);
+     322             :   }
+     323          15 :   addComponentWithDerivatives("residual"); componentIsNotPeriodic("residual");
+     324             : 
+     325             :   // Get appropriate number of derivatives
+     326             :   unsigned nder;
+     327           5 :   if( getNumberOfAtoms()>0 ) {
+     328           5 :     nder = 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     329             :   } else {
+     330             :     nder = getNumberOfArguments();
+     331             :   }
+     332             : 
+     333             :   // Resize all derivative arrays
+     334           5 :   forces.resize( nder ); forcesToApply.resize( nder );
+     335          20 :   for(int i=0; i<getNumberOfComponents(); ++i) getPntrToComponent(i)->resizeDerivatives(nder);
+     336          20 : }
+     337             : 
+     338          36 : unsigned PCAVars::getNumberOfDerivatives() {
+     339          36 :   if( getNumberOfAtoms()>0 ) {
+     340          36 :     return 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
+     341             :   }
+     342           0 :   return getNumberOfArguments();
+     343             : }
+     344             : 
+     345          55 : void PCAVars::lockRequests() {
+     346             :   ActionWithArguments::lockRequests();
+     347             :   ActionAtomistic::lockRequests();
+     348          55 : }
+     349             : 
+     350          55 : void PCAVars::unlockRequests() {
+     351             :   ActionWithArguments::unlockRequests();
+     352             :   ActionAtomistic::unlockRequests();
+     353          55 : }
+     354             : 
+     355          55 : void PCAVars::calculate() {
+     356             : 
+     357          55 :   if(!nopbc && getNumberOfAtoms()>0) makeWhole();
+     358             : 
+     359             :   // Clear the reference value pack
+     360          55 :   mypack.clear();
+     361             :   // Calculate distance between instaneous configuration and reference
+     362          55 :   double dist = myref->calculate( getPositions(), getPbc(), getArguments(), mypack, true );
+     363             : 
+     364             :   // Start accumulating residual by adding derivatives of distance
+     365          55 :   Value* resid=getPntrToComponent( getNumberOfComponents()-1 ); unsigned nargs=getNumberOfArguments();
+     366          55 :   for(unsigned j=0; j<getNumberOfArguments(); ++j) resid->addDerivative( j, mypack.getArgumentDerivative(j) );
+     367         440 :   for(unsigned j=0; j<getNumberOfAtoms(); ++j) {
+     368         385 :     Vector ader=mypack.getAtomDerivative( j );
+     369        1540 :     for(unsigned k=0; k<3; ++k) resid->addDerivative( nargs +3*j+k, ader[k] );
+     370             :   }
+     371             :   // Retrieve the values of all arguments
+     372          55 :   std::vector<double> args( getNumberOfArguments() ); for(unsigned i=0; i<getNumberOfArguments(); ++i) args[i]=getArgument(i);
+     373             : 
+     374             :   // Now calculate projections on pca vectors
+     375          55 :   Vector adif, ader; Tensor fvir, tvir;
+     376         165 :   for(int i=0; i<getNumberOfComponents()-1; ++i) { // One less component as we also have residual
+     377         110 :     double proj=myref->projectDisplacementOnVector( directions[i], getArguments(), args, mypack );
+     378             :     // And now accumulate derivatives
+     379         110 :     Value* eid=getPntrToComponent(i);
+     380         110 :     for(unsigned j=0; j<getNumberOfArguments(); ++j) eid->addDerivative( j, mypack.getArgumentDerivative(j) );
+     381         110 :     if( getNumberOfAtoms()>0 ) {
+     382         110 :       tvir.zero();
+     383         880 :       for(unsigned j=0; j<getNumberOfAtoms(); ++j) {
+     384         770 :         Vector myader=mypack.getAtomDerivative(j);
+     385        3080 :         for(unsigned k=0; k<3; ++k) {
+     386        2310 :           eid->addDerivative( nargs + 3*j+k, myader[k] );
+     387        2310 :           resid->addDerivative( nargs + 3*j+k, -2*proj*myader[k] );
+     388             :         }
+     389         770 :         tvir += -1.0*Tensor( getPosition(j), myader );
+     390             :       }
+     391         440 :       for(unsigned j=0; j<3; ++j) {
+     392        1320 :         for(unsigned k=0; k<3; ++k) eid->addDerivative( nargs + 3*getNumberOfAtoms() + 3*j + k, tvir(j,k) );
+     393             :       }
+     394             :     }
+     395         110 :     dist -= proj*proj; // Subtract square from total squared distance to get residual squared
+     396             :     // Derivatives of residual
+     397         110 :     for(unsigned j=0; j<getNumberOfArguments(); ++j) resid->addDerivative( j, -2*proj*eid->getDerivative(j) );
+     398             :     // for(unsigned j=0;j<getNumberOfArguments();++j) resid->addDerivative( j, -2*proj*arg_eigv(i,j) );
+     399             :     // And set final value
+     400         110 :     getPntrToComponent(i)->set( proj );
+     401             :   }
+     402          55 :   dist=std::sqrt(dist);
+     403             :   resid->set( dist );
+     404             : 
+     405             :   // Take square root of residual derivatives
+     406          55 :   double prefactor = 0.5 / dist;
+     407          55 :   for(unsigned j=0; j<getNumberOfArguments(); ++j) resid->setDerivative( j, prefactor*resid->getDerivative(j) );
+     408         440 :   for(unsigned j=0; j<getNumberOfAtoms(); ++j) {
+     409        1540 :     for(unsigned k=0; k<3; ++k) resid->setDerivative( nargs + 3*j+k, prefactor*resid->getDerivative( nargs+3*j+k ) );
+     410             :   }
+     411             : 
+     412             :   // And finally virial for residual
+     413          55 :   if( getNumberOfAtoms()>0 ) {
+     414          55 :     tvir.zero();
+     415         440 :     for(unsigned j=0; j<getNumberOfAtoms(); ++j) {
+     416        1540 :       Vector ader; for(unsigned k=0; k<3; ++k) ader[k]=resid->getDerivative( nargs + 3*j+k );
+     417         385 :       tvir += -1.0*Tensor( getPosition(j), ader );
+     418             :     }
+     419         220 :     for(unsigned j=0; j<3; ++j) {
+     420         660 :       for(unsigned k=0; k<3; ++k) resid->addDerivative( nargs + 3*getNumberOfAtoms() + 3*j + k, tvir(j,k) );
+     421             :     }
+     422             :   }
+     423             : 
+     424          55 : }
+     425             : 
+     426           0 : void PCAVars::calculateNumericalDerivatives( ActionWithValue* a ) {
+     427           0 :   if( getNumberOfArguments()>0 ) {
+     428           0 :     ActionWithArguments::calculateNumericalDerivatives( a );
+     429             :   }
+     430           0 :   if( getNumberOfAtoms()>0 ) {
+     431           0 :     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
+     432           0 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     433           0 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
+     434             :     }
+     435           0 :     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
+     436           0 :     for(int j=0; j<getNumberOfComponents(); ++j) {
+     437           0 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
+     438             :     }
+     439             :   }
+     440           0 : }
+     441             : 
+     442          55 : void PCAVars::apply() {
+     443             : 
+     444          55 :   bool wasforced=false; forcesToApply.assign(forcesToApply.size(),0.0);
+     445         220 :   for(int i=0; i<getNumberOfComponents(); ++i) {
+     446         165 :     if( getPntrToComponent(i)->applyForce( forces ) ) {
+     447             :       wasforced=true;
+     448           0 :       for(unsigned i=0; i<forces.size(); ++i) forcesToApply[i]+=forces[i];
+     449             :     }
+     450             :   }
+     451          55 :   if( wasforced ) {
+     452           0 :     unsigned ind=0; addForcesOnArguments( 0, forcesToApply, ind );
+     453           0 :     if( getNumberOfAtoms()>0 ) setForcesOnAtoms( forcesToApply, ind );
+     454             :   }
+     455             : 
+     456          55 : }
+     457             : 
+     458             : }
+     459             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Path.cpp.func-sort-c.html b/coverage/mapping/Path.cpp.func-sort-c.html new file mode 100644 index 000000000000..6805c611c7ee --- /dev/null +++ b/coverage/mapping/Path.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - mapping/Path.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - Path.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping4PathC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping4PathC1ERKNS_13ActionOptionsE6
_ZN4PLMD7mapping4Path16registerKeywordsERNS_8KeywordsE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Path.cpp.func.html b/coverage/mapping/Path.cpp.func.html new file mode 100644 index 000000000000..c9742d9d22a3 --- /dev/null +++ b/coverage/mapping/Path.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - mapping/Path.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - Path.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping4Path16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD7mapping4PathC1ERKNS_13ActionOptionsE6
_ZN4PLMD7mapping4PathC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/Path.cpp.gcov.html b/coverage/mapping/Path.cpp.gcov.html new file mode 100644 index 000000000000..6911d95959af --- /dev/null +++ b/coverage/mapping/Path.cpp.gcov.html @@ -0,0 +1,242 @@ + + + + + + + + LCOV - plumed test coverage - mapping/Path.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - Path.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PathBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC COLVAR PATH
+      26             : /*
+      27             : Path collective variables with a more flexible framework for the distance metric being used.
+      28             : 
+      29             : The Path Collective Variables developed by Branduardi and co-workers \cite brand07 allow one
+      30             : to compute the progress along a high-dimensional path and the distance from the high-dimensional
+      31             : path.  The progress along the path (s) is computed using:
+      32             : 
+      33             : \f[
+      34             : s = \frac{ \sum_{i=1}^N i \exp( -\lambda R[X - X_i] ) }{ \sum_{i=1}^N \exp( -\lambda R[X - X_i] ) }
+      35             : \f]
+      36             : 
+      37             : while the distance from the path (z) is measured using:
+      38             : 
+      39             : \f[
+      40             : z = -\frac{1}{\lambda} \ln\left[ \sum_{i=1}^N \exp( -\lambda R[X - X_i] ) \right]
+      41             : \f]
+      42             : 
+      43             : In these expressions \f$N\f$ high-dimensional frames (\f$X_i\f$) are used to describe the path in the high-dimensional
+      44             : space. The two expressions above are then functions of the distances from each of the high-dimensional frames \f$R[X - X_i]\f$.
+      45             : Within PLUMED there are multiple ways to define the distance from a high-dimensional configuration.  You could calculate
+      46             : the RMSD distance or you could calculate the amount by which a set of collective variables change.  As such this implementation
+      47             : of the path CV allows one to use all the difference distance metrics that are discussed in \ref dists. This is as opposed to
+      48             : the alternative implementation of path (\ref PATHMSD) which is a bit faster but which only allows one to use the RMSD distance.
+      49             : 
+      50             : The \f$s\f$ and \f$z\f$ variables are calculated using the above formulas by default.  However, there is an alternative method
+      51             : of calculating these collective variables, which is detailed in \cite bernd-path.  This alternative method uses the tools of
+      52             : geometry (as opposed to algebra, which is used in the equations above).  In this alternative formula the progress along the path
+      53             : \f$s\f$ is calculated using:
+      54             : 
+      55             : \f[
+      56             : s = i_2 + \textrm{sign}(i_2-i_1) \frac{ \sqrt{( \mathbf{v}_1\cdot\mathbf{v}_2 )^2 - |\mathbf{v}_3|^2(|\mathbf{v}_1|^2 - |\mathbf{v}_2|^2) } }{2|\mathbf{v}_3|^2} - \frac{\mathbf{v}_1\cdot\mathbf{v}_3 - |\mathbf{v}_3|^2}{2|\mathbf{v}_3|^2}
+      57             : \f]
+      58             : 
+      59             : where \f$\mathbf{v}_1\f$ and \f$\mathbf{v}_3\f$ are the vectors connecting the current position to the closest and second closest node of the path,
+      60             : respectfully and \f$i_1\f$ and \f$i_2\f$ are the projections of the closest and second closest frames of the path. \f$\mathbf{v}_2\f$, meanwhile, is the
+      61             : vector connecting the closest frame to the second closest frame.  The distance from the path, \f$z\f$ is calculated using:
+      62             : 
+      63             : \f[
+      64             : z = \sqrt{ \left[ |\mathbf{v}_1|^2 - |\mathbf{v}_2| \left( \frac{ \sqrt{( \mathbf{v}_1\cdot\mathbf{v}_2 )^2 - |\mathbf{v}_3|^2(|\mathbf{v}_1|^2 - |\mathbf{v}_2|^2) } }{2|\mathbf{v}_3|^2} - \frac{\mathbf{v}_1\cdot\mathbf{v}_3 - |\mathbf{v}_3|^2}{2|\mathbf{v}_3|^2} \right) \right]^2 }
+      65             : \f]
+      66             : 
+      67             : The symbols here are as they were for \f$s\f$.  If you would like to use these equations to calculate \f$s\f$ and \f$z\f$ then you should use the GPATH flag.
+      68             : The values of \f$s\f$ and \f$z\f$ can then be referenced using the gspath and gzpath labels.
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : In the example below the path is defined using RMSD distance from frames.
+      73             : 
+      74             : \plumedfile
+      75             : p1: PATH REFERENCE=file.pdb TYPE=OPTIMAL LAMBDA=500.0
+      76             : PRINT ARG=p1.spath,p1.zpath STRIDE=1 FILE=colvar FMT=%8.4f
+      77             : \endplumedfile
+      78             : 
+      79             : The reference frames in the path are defined in the pdb file shown below.  In this frame
+      80             : each configuration in the path is separated by a line containing just the word END.
+      81             : 
+      82             : \auxfile{file.pdb}
+      83             : ATOM      1  CL  ALA     1      -3.171   0.295   2.045  1.00  1.00
+      84             : ATOM      5  CLP ALA     1      -1.819  -0.143   1.679  1.00  1.00
+      85             : ATOM      6  OL  ALA     1      -1.177  -0.889   2.401  1.00  1.00
+      86             : ATOM      7  NL  ALA     1      -1.313   0.341   0.529  1.00  1.00
+      87             : END
+      88             : ATOM      1  CL  ALA     1      -3.175   0.365   2.024  1.00  1.00
+      89             : ATOM      5  CLP ALA     1      -1.814  -0.106   1.685  1.00  1.00
+      90             : ATOM      6  OL  ALA     1      -1.201  -0.849   2.425  1.00  1.00
+      91             : ATOM      7  NL  ALA     1      -1.296   0.337   0.534  1.00  1.00
+      92             : END
+      93             : ATOM      1  CL  ALA     1      -2.990   0.383   2.277  1.00  1.00
+      94             : ATOM      5  CLP ALA     1      -1.664  -0.085   1.831  1.00  1.00
+      95             : ATOM      6  OL  ALA     1      -0.987  -0.835   2.533  1.00  1.00
+      96             : ATOM      7  NL  ALA     1      -1.227   0.364   0.646  1.00  1.00
+      97             : END
+      98             : \endauxfile
+      99             : 
+     100             : In the example below the path is defined using the values of two torsional angles (t1 and t2).
+     101             : In addition, the \f$s\f$ and \f$z\f$ are calculated using the geometric expressions described
+     102             : above rather than the algebraic expressions that are used by default.
+     103             : 
+     104             : \plumedfile
+     105             : t1: TORSION ATOMS=5,7,9,15
+     106             : t2: TORSION ATOMS=7,9,15,17
+     107             : pp: PATH TYPE=EUCLIDEAN REFERENCE=epath.pdb GPATH NOSPATH NOZPATH
+     108             : PRINT ARG=pp.* FILE=colvar
+     109             : \endplumedfile
+     110             : 
+     111             : Notice that the LAMBDA parameter is not required here as we are not calculating \f$s\f$ and \f$s\f$
+     112             : using the algebraic formulas defined earlier.  The positions of the frames in the path are defined
+     113             : in the file epath.pdb.  An extract from this file looks as shown below.
+     114             : 
+     115             : \auxfile{epath.pdb}
+     116             : REMARK ARG=t1,t2 t1=-4.25053  t2=3.88053
+     117             : END
+     118             : REMARK ARG=t1,t2 t1=-4.11     t2=3.75
+     119             : END
+     120             : REMARK ARG=t1,t2 t1=-3.96947  t2=3.61947
+     121             : END
+     122             : \endauxfile
+     123             : 
+     124             : The remarks in this pdb file tell PLUMED the labels that are being used to define the position in the
+     125             : high dimensional space and the values that these arguments have at each point on the path.
+     126             : 
+     127             : */
+     128             : //+ENDPLUMEDOC
+     129             : 
+     130             : namespace PLMD {
+     131             : namespace mapping {
+     132             : 
+     133             : class Path : public PathBase {
+     134             : public:
+     135             :   static void registerKeywords( Keywords& keys );
+     136             :   explicit Path(const ActionOptions&);
+     137             : };
+     138             : 
+     139             : PLUMED_REGISTER_ACTION(Path,"PATH")
+     140             : 
+     141           8 : void Path::registerKeywords( Keywords& keys ) {
+     142           8 :   PathBase::registerKeywords( keys ); keys.remove("PROPERTY");
+     143          16 :   keys.addFlag("NOSPATH",false,"do not calculate the spath position");
+     144          16 :   keys.remove("LOWMEM"); keys.use("GPATH");
+     145           8 : }
+     146             : 
+     147           6 : Path::Path(const ActionOptions& ao):
+     148             :   Action(ao),
+     149           6 :   PathBase(ao)
+     150             : {
+     151             :   setLowMemOption( true );
+     152          12 :   bool nos; parseFlag("NOSPATH",nos);
+     153             : 
+     154             :   std::string empty;
+     155           6 :   if(!nos) {
+     156           4 :     if( getLambda()==0 ) error("you must set LAMBDA parameter in order to calculate spath position.  Use LAMBDA/NOSPATH keyword");
+     157             :     empty="LABEL=spath";
+     158           8 :     addVessel("SPATH",empty,0);
+     159             :   }
+     160           6 :   readVesselKeywords();
+     161           6 :   checkRead();
+     162           6 : }
+     163             : 
+     164             : }
+     165             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathBase.cpp.func-sort-c.html b/coverage/mapping/PathBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..9a64ddbd3d48 --- /dev/null +++ b/coverage/mapping/PathBase.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping8PathBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping8PathBaseC2ERKNS_13ActionOptionsE9
_ZN4PLMD7mapping8PathBase16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD7mapping8PathBase9getLambdaEv1103
_ZN4PLMD7mapping8PathBase9calculateEv4914
_ZNK4PLMD7mapping8PathBase11performTaskERKjS3_RNS_10MultiValueE170352
_ZNK4PLMD7mapping8PathBase11transformHDERKdRd170352
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathBase.cpp.func.html b/coverage/mapping/PathBase.cpp.func.html new file mode 100644 index 000000000000..cc4fb1257b95 --- /dev/null +++ b/coverage/mapping/PathBase.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping8PathBase16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD7mapping8PathBase9calculateEv4914
_ZN4PLMD7mapping8PathBase9getLambdaEv1103
_ZN4PLMD7mapping8PathBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping8PathBaseC2ERKNS_13ActionOptionsE9
_ZNK4PLMD7mapping8PathBase11performTaskERKjS3_RNS_10MultiValueE170352
_ZNK4PLMD7mapping8PathBase11transformHDERKdRd170352
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathBase.cpp.gcov.html b/coverage/mapping/PathBase.cpp.gcov.html new file mode 100644 index 000000000000..68ca3e2e1765 --- /dev/null +++ b/coverage/mapping/PathBase.cpp.gcov.html @@ -0,0 +1,162 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PathBase.h"
+      23             : #include "tools/SwitchingFunction.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace mapping {
+      27             : 
+      28          13 : void PathBase::registerKeywords( Keywords& keys ) {
+      29          13 :   Mapping::registerKeywords( keys );
+      30          26 :   keys.add("compulsory","LAMBDA","0","the value of the lambda parameter for paths");
+      31          26 :   keys.addFlag("NOZPATH",false,"do not calculate the zpath position");
+      32          13 : }
+      33             : 
+      34           9 : PathBase::PathBase(const ActionOptions& ao):
+      35             :   Action(ao),
+      36           9 :   Mapping(ao)
+      37             : {
+      38             :   setLowMemOption( true );
+      39           9 :   weightHasDerivatives=true;
+      40           9 :   bool noz; parseFlag("NOZPATH",noz);
+      41           9 :   parse("LAMBDA",lambda);
+      42             : 
+      43             :   // Create the list of tasks
+      44         405 :   for(unsigned i=0; i<getNumberOfReferencePoints(); ++i) addTaskToList( i );
+      45             :   // And activate them all
+      46           9 :   deactivateAllTasks();
+      47         405 :   for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+      48           9 :   lockContributors();
+      49             : 
+      50           9 :   std::string empty="LABEL=zpath";
+      51           9 :   if(!noz) {
+      52           7 :     if( lambda==0 ) error("you must set LAMDBA value in order to calculate ZPATH coordinate.  Use LAMBDA/NOZPATH keyword");
+      53          14 :     addVessel("ZPATH",empty,0);
+      54             :   }
+      55           9 : }
+      56             : 
+      57        1103 : double PathBase::getLambda() {
+      58        1103 :   return lambda;
+      59             : }
+      60             : 
+      61        4914 : void PathBase::calculate() {
+      62             :   // Loop over all frames is now performed by ActionWithVessel
+      63        4914 :   runAllTasks();
+      64        4914 : }
+      65             : 
+      66      170352 : void PathBase::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+      67             :   // This builds a pack to hold the derivatives
+      68      170352 :   ReferenceValuePack mypack( getNumberOfArguments(), getNumberOfAtoms(), myvals );
+      69      170352 :   finishPackSetup( current, mypack );
+      70             :   // Calculate the distance from the frame
+      71      170352 :   double val=calculateDistanceFunction( current, mypack, true );
+      72             :   // Put the element value in element zero
+      73             :   myvals.setValue( 0, val ); myvals.setValue( 1, 1.0 );
+      74      170352 :   return;
+      75      170352 : }
+      76             : 
+      77      170352 : double PathBase::transformHD( const double& dist, double& df ) const {
+      78      170352 :   if( lambda==0 ) { df=1; return dist; }
+      79      114660 :   double val = exp( -dist*lambda );
+      80      114660 :   df = -lambda*val;
+      81      114660 :   return val;
+      82             : }
+      83             : 
+      84             : }
+      85             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathReparameterization.cpp.func-sort-c.html b/coverage/mapping/PathReparameterization.cpp.func-sort-c.html new file mode 100644 index 000000000000..7e67f35a96a3 --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathReparameterization.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathReparameterization.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6565100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping22PathReparameterization14reparameterizeERKiS3_RKd4
_ZN4PLMD7mapping22PathReparameterizationC2ERKNS_3PbcERKSt6vectorIPNS_5ValueESaIS7_EERS5_ISt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteISD_EESaISG_EE4
_ZN4PLMD7mapping22PathReparameterization18reparameterizePartERKiS3_RKdS5_10
_ZN4PLMD7mapping22PathReparameterization23calcCurrentPathSpacingsERKiS3_71
_ZNK4PLMD7mapping22PathReparameterization7loopEndERKiS3_S3_1741
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathReparameterization.cpp.func.html b/coverage/mapping/PathReparameterization.cpp.func.html new file mode 100644 index 000000000000..898acd8f954f --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathReparameterization.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathReparameterization.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6565100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping22PathReparameterization14reparameterizeERKiS3_RKd4
_ZN4PLMD7mapping22PathReparameterization18reparameterizePartERKiS3_RKdS5_10
_ZN4PLMD7mapping22PathReparameterization23calcCurrentPathSpacingsERKiS3_71
_ZN4PLMD7mapping22PathReparameterizationC2ERKNS_3PbcERKSt6vectorIPNS_5ValueESaIS7_EERS5_ISt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteISD_EESaISG_EE4
_ZNK4PLMD7mapping22PathReparameterization7loopEndERKiS3_S3_1741
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathReparameterization.cpp.gcov.html b/coverage/mapping/PathReparameterization.cpp.gcov.html new file mode 100644 index 000000000000..aa3e4b9a7f99 --- /dev/null +++ b/coverage/mapping/PathReparameterization.cpp.gcov.html @@ -0,0 +1,223 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathReparameterization.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathReparameterization.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6565100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PathReparameterization.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace mapping {
+      26             : 
+      27           4 : PathReparameterization::PathReparameterization( const Pbc& ipbc, const std::vector<Value*>& iargs, std::vector<std::unique_ptr<ReferenceConfiguration>>& pp ):
+      28           4 :   mydpack( 1, pp[0]->getNumberOfReferenceArguments() + 3*pp[0]->getNumberOfReferencePositions() + 9 ),
+      29           4 :   mypack( pp[0]->getNumberOfReferenceArguments(), pp[0]->getNumberOfReferencePositions(), mydpack ),
+      30           8 :   mydir(ReferenceConfigurationOptions("DIRECTION")),
+      31           4 :   pbc(ipbc),
+      32           4 :   args(iargs),
+      33           4 :   mypath(pp),
+      34           4 :   len(pp.size()),
+      35           4 :   sumlen(pp.size()),
+      36           4 :   sfrac(pp.size()),
+      37           8 :   MAXCYCLES(100)
+      38             : {
+      39           4 :   mypdb.setAtomNumbers(  pp[0]->getAbsoluteIndexes() ); mypdb.addBlockEnd( pp[0]->getAbsoluteIndexes().size() );
+      40           4 :   if( pp[0]->getArgumentNames().size()>0 ) mypdb.setArgumentNames( pp[0]->getArgumentNames() );
+      41           4 :   mydir.read( mypdb ); mydir.zeroDirection(); pp[0]->setupPCAStorage( mypack );
+      42           4 : }
+      43             : 
+      44        1741 : bool PathReparameterization::loopEnd( const int& index, const int& end, const int& inc ) const {
+      45        1741 :   if( inc>0 && index<end ) return false;
+      46         270 :   else if( inc<0 && index>end ) return false;
+      47             :   return true;
+      48             : }
+      49             : 
+      50          71 : void PathReparameterization::calcCurrentPathSpacings( const int& istart, const int& iend ) {
+      51             :   plumed_dbg_assert( istart<len.size() && iend<len.size() );
+      52          71 :   len[istart] = sumlen[istart]=0;
+      53             :   //printf("HELLO PATH SPACINGS ARE CURRENTLY \n");
+      54             : 
+      55             :   // Get the spacings given we can go forward and backwards
+      56          71 :   int incr=1; if( istart>iend ) { incr=-1; }
+      57             : 
+      58         657 :   for(int i=istart+incr; loopEnd(i,iend+incr,incr)==false; i+=incr) {
+      59         586 :     len[i] = mypath[i-incr]->calc( mypath[i]->getReferencePositions(), pbc, args, mypath[i]->getReferenceArguments(), mypack, false );
+      60         586 :     sumlen[i] = sumlen[i-incr] + len[i];
+      61             :     //printf("FRAME %d TO FRAME %d EQUALS %f : %f \n",i-incr,i,len[i],sumlen[i] );
+      62             :   }
+      63          71 : }
+      64             : 
+      65          10 : void PathReparameterization::reparameterizePart( const int& istart, const int& iend, const double& target, const double& TOL ) {
+      66          10 :   calcCurrentPathSpacings( istart, iend ); unsigned cfin;
+      67             :   // If a target separation is set we fix where we want the nodes
+      68          10 :   int incr=1; if( istart>iend ) { incr=-1; }
+      69             : 
+      70          10 :   if( target>0 ) {
+      71           6 :     if( iend>istart ) {
+      72          19 :       for(unsigned i=istart; i<iend+1; ++i) sfrac[i] = target*(i-istart);
+      73             :     } else {
+      74          14 :       for(int i=istart-1; i>iend-1; --i) sfrac[i]=target*(istart-i);
+      75             :     }
+      76           6 :     cfin = iend+incr;
+      77             :   } else {
+      78           4 :     cfin = iend;
+      79             :   }
+      80             : 
+      81             :   std::vector<Direction> newpath;
+      82         170 :   for(unsigned i=0; i<mypath.size(); ++i) {
+      83         320 :     newpath.push_back( Direction(ReferenceConfigurationOptions("DIRECTION")) ); newpath[i].read( mypdb );
+      84             :   }
+      85             : 
+      86             :   double prevsum=0.;
+      87          71 :   for(unsigned iter=0; iter<MAXCYCLES; ++iter) {
+      88          71 :     if( std::fabs(sumlen[iend] - prevsum)<=TOL ) break ;
+      89             :     prevsum = sumlen[iend];
+      90             :     // If no target is set we redistribute length
+      91          61 :     if( target<0 ) {
+      92          49 :       plumed_assert( istart<iend );
+      93          49 :       double dr = sumlen[iend] / static_cast<double>( iend - istart );
+      94         531 :       for(unsigned i=istart; i<iend; ++i) sfrac[i] = dr*(i-istart);
+      95             :     }
+      96             : 
+      97             :     // Now compute positions of new nodes in path
+      98         542 :     for(int i=istart+incr; loopEnd(i,cfin,incr)==false; i+=incr) {
+      99         481 :       int k = istart;
+     100        2567 :       while( !((sumlen[k] < sfrac[i]) && (sumlen[k+incr]>=sfrac[i])) ) {
+     101        2093 :         k+=incr;
+     102        2093 :         if( cfin==iend && k>= iend+1 ) plumed_merror("path reparameterization error");
+     103        2093 :         else if( cfin==(iend+1) && k>=iend ) { k=iend-1; break; }
+     104        2090 :         else if( cfin==(iend-1) && k<=iend ) { k=iend+1; break; }
+     105             :       }
+     106         481 :       double dr = (sfrac[i]-sumlen[k])/len[k+incr];
+     107             :       // Calculate the displacement between the appropriate points
+     108             :       // double dd = mypath[k]->calc( mypath[k+incr]->getReferencePositions(), pbc, args, mypath[k+incr]->getReferenceArguments(), mypack, true );
+     109             :       // Copy the reference configuration from the configuration to a tempory direction
+     110         481 :       newpath[i].setDirection( mypath[k]->getReferencePositions(), mypath[k]->getReferenceArguments() );
+     111             :       // Get the displacement of the path
+     112         481 :       mypath[k]->extractDisplacementVector( mypath[k+incr]->getReferencePositions(), args, mypath[k+incr]->getReferenceArguments(), false, mydir );
+     113             :       // Set our direction equal to the displacement
+     114             :       // mydir.setDirection( mypack );
+     115             :       // Shift the reference configuration by this amount
+     116         481 :       newpath[i].displaceReferenceConfiguration( dr, mydir );
+     117             :     }
+     118             : 
+     119             :     // Copy the positions of the new path to the new paths
+     120         542 :     for(int i=istart+incr; loopEnd(i,cfin,incr)==false; i+=incr) {
+     121         481 :       mypdb.setAtomPositions( newpath[i].getReferencePositions() );
+     122        1415 :       for(unsigned j=0; j<newpath[i].getNumberOfReferenceArguments(); ++j) mypdb.setArgumentValue( mypath[i]->getArgumentNames()[j], newpath[i].getReferenceArgument(j) );
+     123         481 :       mypath[i]->read( mypdb );
+     124             :     }
+     125             : 
+     126             :     // Recompute the separations between frames
+     127          61 :     calcCurrentPathSpacings( istart, iend );
+     128             :   }
+     129          10 : }
+     130             : 
+     131           4 : void PathReparameterization::reparameterize( const int& ifix1, const int& ifix2, const double& TOL ) {
+     132             :   plumed_dbg_assert( ifix1<ifix2 );
+     133             :   // First reparameterize the part between the fixed frames
+     134           4 :   reparameterizePart( ifix1, ifix2, -1.0, TOL );
+     135             : 
+     136             :   // Get the separation between frames which we will use to set the remaining frames
+     137           4 :   double target = sumlen[ifix2] / ( ifix2 - ifix1 );
+     138             : 
+     139             :   // And reparameterize the beginning and end of the path
+     140           4 :   if( ifix1>0 ) reparameterizePart( ifix1, 0, target, TOL );
+     141           4 :   if( ifix2<(mypath.size()-1) ) reparameterizePart( ifix2, mypath.size()-1, target, TOL );
+     142             : //  calcCurrentPathSpacings( 0, mypath.size()-1 );
+     143           4 : }
+     144             : 
+     145             : }
+     146             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathTools.cpp.func-sort-c.html b/coverage/mapping/PathTools.cpp.func-sort-c.html new file mode 100644 index 000000000000..6817bc9fa3c2 --- /dev/null +++ b/coverage/mapping/PathTools.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12312598.4 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping9PathTools4mainEP8_IO_FILES3_RNS_12CommunicatorE4
_ZNK4PLMD7mapping9PathTools11descriptionB5cxx11Ev4
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMe6createERKNS_13CLToolOptionsE8
_ZN4PLMD7mapping9PathToolsC2ERKNS_13CLToolOptionsE8
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeC2Ev4187
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeD2Ev4187
_ZN4PLMD7mapping9PathTools16registerKeywordsERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathTools.cpp.func.html b/coverage/mapping/PathTools.cpp.func.html new file mode 100644 index 000000000000..2d729b07bc82 --- /dev/null +++ b/coverage/mapping/PathTools.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12312598.4 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMe6createERKNS_13CLToolOptionsE8
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeC2Ev4187
_ZN4PLMD7mapping12_GLOBAL__N_119PathToolsRegisterMeD2Ev4187
_ZN4PLMD7mapping9PathTools16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD7mapping9PathTools4mainEP8_IO_FILES3_RNS_12CommunicatorE4
_ZN4PLMD7mapping9PathToolsC2ERKNS_13CLToolOptionsE8
_ZNK4PLMD7mapping9PathTools11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PathTools.cpp.gcov.html b/coverage/mapping/PathTools.cpp.gcov.html new file mode 100644 index 000000000000..382cf0a9051d --- /dev/null +++ b/coverage/mapping/PathTools.cpp.gcov.html @@ -0,0 +1,388 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PathTools.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PathTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12312598.4 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "cltools/CLTool.h"
+      23             : #include "core/CLToolRegister.h"
+      24             : #include "tools/Tools.h"
+      25             : #include "tools/Pbc.h"
+      26             : #include "core/Value.h"
+      27             : #include "reference/ReferenceConfiguration.h"
+      28             : #include "PathReparameterization.h"
+      29             : #include "reference/MetricRegister.h"
+      30             : #include <cstdio>
+      31             : #include <string>
+      32             : #include <vector>
+      33             : #include <iostream>
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace mapping {
+      37             : 
+      38             : //+PLUMEDOC TOOLS pathtools
+      39             : /*
+      40             : pathtools can be used to construct paths from pdb data
+      41             : 
+      42             : The path CVs in PLUMED are curvilinear coordinates through a high dimensional vector space.
+      43             : Enhanced sampling calculations are often run using the progress along the paths and the distance from the path as CVs
+      44             : as this provides a convenient way of defining a reaction coordinate for a complicated process.  This method is explained
+      45             : in the documentation for \ref PATH.
+      46             : 
+      47             : The path itself is an ordered set of equally-spaced, high-dimensional frames the way in which these frames
+      48             : should be constructed will depend on the problem in hand.  In other words, you will need to understand the reaction
+      49             : you wish to study in order to select a sensible set of frames to use in your path CV.  This tool provides two
+      50             : methods that may be useful when it comes to constructing paths; namely:
+      51             : 
+      52             : - A tool that takes in an initial guess path in which the frames are not equally spaced.  This tool adjusts the positions
+      53             : of the frames in order to make them equally spaced so that they can be used as the basis for a path CV.
+      54             : 
+      55             : - A tool that takes two frames as input and that allows you to return a linear path connecting these two frames.  The
+      56             : output from this method may be useful as an initial guess path.  It is arguable that a linear path rather defeats the
+      57             : purpose of the path CV method, however, as the whole purpose is to be able to define non-linear paths.
+      58             : 
+      59             : Notice that you can use these two methods and take advantage of all the ways of measuring \ref dists that are available within
+      60             : PLUMED. The way you do this with each of these tools described above is explained in the example below.
+      61             : 
+      62             : \par Examples
+      63             : 
+      64             : The example below shows how you can take a set of unequally spaced frames from a pdb file named in_path.pdb
+      65             : and use pathtools to make them equally spaced so that they can be used as the basis for a path CV.  The file
+      66             : containing this final path is named final_path.pdb.
+      67             : 
+      68             : \verbatim
+      69             : plumed pathtools --path in_path.pdb --metric EUCLIDEAN --out final_path.pdb
+      70             : \endverbatim
+      71             : 
+      72             : The example below shows how can create an initial linear path connecting the two pdb frames in start.pdb and
+      73             : end.pdb.  In this case the path output to path.pdb will consist of 6 frames: the initial and final frames that
+      74             : were contained in start.pdb and end.pdb as well as four equally spaced frames along the vector connecting
+      75             : start.pdb to end.pdb.
+      76             : 
+      77             : \verbatim
+      78             : plumed pathtools --start start.pdb --end end.pdb --nframes 4 --metric OPTIMAL --out path.pdb
+      79             : \endverbatim
+      80             : 
+      81             : Often the idea with path collective variables is to create a path connecting some initial state A to some final state B.  You would
+      82             : in this case have representative configurations from your A and B states defined in the input files to pathtools
+      83             : that we have called start.pdb and end.pdb in the example above.  Furthermore, it may be useful to have a few frames
+      84             : before your start frame and after your end frame.  You can use path tools to create these extended paths as shown below.
+      85             : In this case the final path would now consist of 8 frames.  Four of these frames would lie on the vector connecting state
+      86             : A to state B, there would be one frame each at start.pdb and end.pdb as well as one frame just before start.pdb and one
+      87             : frame just after end.pdb.  All these frames would be equally spaced.
+      88             : 
+      89             : \verbatim
+      90             : plumed pathtools --start start.pdb --end end.pdb --nframes 4 --metric OPTIMAL --out path.pdb --nframes-before-start 2 --nframes-after-end 2
+      91             : \endverbatim
+      92             : 
+      93             : Notice also that when you re-parameterize paths you must choose two frames to fix.  Generally you chose to fix the states
+      94             : that are representative of your states A and B.  By default pathtools will fix the first and last frames.  You can, however,
+      95             : change the states to fix by taking advantage of the fixed flag as shown below.
+      96             : 
+      97             : \verbatim
+      98             : plumed pathtools --path inpath.pdb --metric EUCLIDEAN --out outpath.pdb --fixed 2,12
+      99             : \endverbatim
+     100             : 
+     101             : */
+     102             : //+ENDPLUMEDOC
+     103             : 
+     104             : class PathTools :
+     105             :   public CLTool
+     106             : {
+     107             : public:
+     108             :   static void registerKeywords( Keywords& keys );
+     109             :   explicit PathTools(const CLToolOptions& co );
+     110             :   int main(FILE* in, FILE*out,Communicator& pc);
+     111           4 :   std::string description()const {
+     112           4 :     return "print out a description of the keywords for an action in html";
+     113             :   }
+     114             : };
+     115             : 
+     116       12569 : PLUMED_REGISTER_CLTOOL(PathTools,"pathtools")
+     117             : 
+     118        4187 : void PathTools::registerKeywords( Keywords& keys ) {
+     119        4187 :   CLTool::registerKeywords( keys );
+     120        8374 :   keys.add("atoms","--start","a pdb file that contains the structure for the initial frame of your path");
+     121        8374 :   keys.add("atoms","--end","a pdb file that contains the structure for the final frame of your path");
+     122        8374 :   keys.add("atoms-1","--path","a pdb file that contains an initial path in which the frames are not equally spaced");
+     123        8374 :   keys.add("compulsory","--fixed","0","the frames to fix when constructing the path using --path");
+     124        8374 :   keys.add("compulsory","--metric","the measure to use to calculate the distance between frames");
+     125        8374 :   keys.add("compulsory","--out","the name of the file on which to output your path");
+     126        8374 :   keys.add("compulsory","--arg-fmt","%f","the format to use for argument values in your frames");
+     127        8374 :   keys.add("compulsory","--tolerance","1E-4","the tolerance to use for the algorithm that is used to re-parameterize the path");
+     128        8374 :   keys.add("compulsory","--nframes-before-start","1","the number of frames to include in the path before the first frame");
+     129        8374 :   keys.add("compulsory","--nframes","1","the number of frames between the start and end frames in your path");
+     130        8374 :   keys.add("compulsory","--nframes-after-end","1","the number of frames to put after the last frame of your path");
+     131        4187 : }
+     132             : 
+     133           8 : PathTools::PathTools(const CLToolOptions& co ):
+     134           8 :   CLTool(co)
+     135             : {
+     136           8 :   inputdata=commandline;
+     137           8 : }
+     138             : 
+     139           4 : int PathTools::main(FILE* in, FILE*out,Communicator& pc) {
+     140           8 :   std::string mtype; parse("--metric",mtype);
+     141           8 :   std::string ifilename; parse("--path",ifilename);
+     142           8 :   std::string ofmt; parse("--arg-fmt",ofmt);
+     143           8 :   std::string ofilename; parse("--out",ofilename);
+     144           4 :   if( ifilename.length()>0 ) {
+     145             :     std::fprintf(out,"Reparameterising path in file named %s so that all frames are equally spaced \n",ifilename.c_str() );
+     146           2 :     FILE* fp=std::fopen(ifilename.c_str(),"r");
+     147             : // call fclose when fp goes out of scope
+     148           2 :     auto deleter=[](auto f) { if(f) std::fclose(f); };
+     149             :     std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     150             :     bool do_read=true; std::vector<std::unique_ptr<ReferenceConfiguration>> frames;
+     151          24 :     while (do_read) {
+     152          22 :       PDB mypdb;
+     153             :       // Read the pdb file
+     154          22 :       do_read=mypdb.readFromFilepointer(fp,false,0.1);
+     155          22 :       if( do_read ) {
+     156          20 :         auto mymsd(metricRegister().create<ReferenceConfiguration>( mtype, mypdb ));
+     157          20 :         frames.emplace_back( std::move(mymsd) );
+     158          20 :       }
+     159          22 :     }
+     160           4 :     std::vector<unsigned> fixed; parseVector("--fixed",fixed);
+     161           2 :     if( fixed.size()==1 ) {
+     162           1 :       if( fixed[0]!=0 ) error("input to --fixed should be two integers");
+     163           1 :       fixed.resize(2); fixed[0]=0; fixed[1]=frames.size()-1;
+     164           1 :     } else if( fixed.size()==2 ) {
+     165           1 :       if( fixed[0]>(frames.size()-1) || fixed[1]>(frames.size()-1) ) {
+     166           0 :         error("input to --fixed should be two numbers between 0 and the number of frames-1");
+     167             :       }
+     168             :     } else {
+     169           0 :       error("input to --fixed should be two integers");
+     170             :     }
+     171             :     std::vector<AtomNumber> atoms; std::vector<std::string> arg_names;
+     172          22 :     for(unsigned i=0; i<frames.size(); ++i) {
+     173             :       frames[i]->getAtomRequests( atoms);
+     174          20 :       frames[i]->getArgumentRequests( arg_names );
+     175             :     }
+     176             :     // Generate stuff to reparameterize
+     177           2 :     Pbc fake_pbc; std::vector<std::unique_ptr<Value>> vals;
+     178           4 :     for(unsigned i=0; i<frames[0]->getNumberOfReferenceArguments(); ++i) {
+     179           2 :       vals.emplace_back(Tools::make_unique<Value>()); vals[vals.size()-1]->setNotPeriodic();
+     180             :     }
+     181             : 
+     182             :     // temporary pointes used to make the conversion once
+     183             : 
+     184           2 :     auto vals_ptr=Tools::unique2raw(vals);
+     185             :     // And reparameterize
+     186           2 :     PathReparameterization myparam( fake_pbc, vals_ptr, frames );
+     187             :     // And make all points equally spaced
+     188           4 :     double tol; parse("--tolerance",tol); myparam.reparameterize( fixed[0], fixed[1], tol );
+     189             : 
+     190             :     // Output data on spacings
+     191             :     double mean=0;
+     192           2 :     MultiValue myvpack( 1, frames[0]->getNumberOfReferenceArguments() + 3*frames[0]->getNumberOfReferencePositions() + 9 );
+     193           2 :     ReferenceValuePack mypack( frames[0]->getNumberOfReferenceArguments(), frames[0]->getNumberOfReferencePositions(), myvpack );
+     194          20 :     for(unsigned i=1; i<frames.size(); ++i) {
+     195          18 :       double len = frames[i]->calc( frames[i-1]->getReferencePositions(), fake_pbc, vals_ptr, frames[i-1]->getReferenceArguments(), mypack, false );
+     196             :       printf("FINAL DISTANCE BETWEEN FRAME %u AND %u IS %f \n",i-1,i,len );
+     197          18 :       mean+=len*len;
+     198             :     }
+     199           2 :     printf("SUGGESTED LAMBDA PARAMETER IS THUS %f \n",2.3/(mean/static_cast<double>( frames.size()-1 )) );
+     200             : 
+     201             :     // Delete all the frames
+     202           2 :     OFile ofile; ofile.open(ofilename);
+     203           2 :     std::vector<std::string> argnames; frames[0]->getArgumentRequests( argnames );
+     204           2 :     std::vector<AtomNumber> atindices; frames[0]->getAtomRequests( atindices );
+     205           2 :     PDB mypdb; mypdb.setAtomNumbers( atindices ); mypdb.setArgumentNames( argnames );
+     206          22 :     for(unsigned i=0; i<frames.size(); ++i) {
+     207          20 :       mypdb.setAtomPositions( frames[i]->getReferencePositions() );
+     208          40 :       for(unsigned j=0; j<argnames.size(); ++j) mypdb.setArgumentValue( argnames[j], frames[i]->getReferenceArguments()[j] );
+     209          20 :       ofile.printf("REMARK TYPE=%s\n",mtype.c_str() );
+     210          20 :       mypdb.print( 10, NULL, ofile, ofmt );
+     211             :     }
+     212             :     // Delete the vals as we don't need them
+     213             :     // for(unsigned i=0; i<vals.size(); ++i) delete vals[i];
+     214             :     // Return as we are done
+     215             :     return 0;
+     216          10 :   }
+     217             : 
+     218             : // Read initial frame
+     219           2 :   std::string istart; parse("--start",istart);
+     220           2 :   PDB mystartpdb;
+     221             :   {
+     222           2 :     FILE* fp2=std::fopen(istart.c_str(),"r");
+     223             : // call fclose when fp goes out of scope
+     224           2 :     auto deleter=[](auto f) { std::fclose(f); };
+     225             :     std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp2,deleter);
+     226           2 :     if( istart.length()==0 ) error("input is missing use --istart + --iend or --path");
+     227           2 :     if( !mystartpdb.readFromFilepointer(fp2,false,0.1) ) error("could not read fila " + istart);
+     228             :   }
+     229           2 :   auto sframe=metricRegister().create<ReferenceConfiguration>( mtype, mystartpdb );
+     230             : 
+     231             : // Read final frame
+     232           2 :   std::string iend; parse("--end",iend);
+     233           2 :   PDB myendpdb;
+     234             :   {
+     235           2 :     FILE* fp1=std::fopen(iend.c_str(),"r");
+     236             : // call fclose when fp goes out of scope
+     237           2 :     auto deleter=[](auto f) { std::fclose(f); };
+     238             :     std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp1,deleter);
+     239           2 :     if( iend.length()==0 ) error("input is missing using --istart + --iend or --path");
+     240           2 :     if( !myendpdb.readFromFilepointer(fp1,false,0.1) ) error("could not read fila " + iend);
+     241             :   }
+     242           2 :   auto eframe=metricRegister().create<ReferenceConfiguration>( mtype, myendpdb );
+     243             : 
+     244             : // Get atoms and arg requests
+     245             :   std::vector<AtomNumber> atoms; std::vector<std::string> arg_names;
+     246           2 :   sframe->getAtomRequests( atoms); eframe->getAtomRequests( atoms);
+     247           2 :   sframe->getArgumentRequests( arg_names ); eframe->getArgumentRequests( arg_names );
+     248             : 
+     249             : // Now read in the rest of the instructions
+     250             :   unsigned nbefore, nbetween, nafter;
+     251           6 :   parse("--nframes-before-start",nbefore); parse("--nframes",nbetween); parse("--nframes-after-end",nafter);
+     252           2 :   nbetween++;
+     253             :   std::fprintf(out,"Generating linear path connecting structure in file named %s to structure in file named %s \n",istart.c_str(),iend.c_str() );
+     254           2 :   std::fprintf(out,"A path consisting of %u equally-spaced frames before the initial structure, %u frames between the initial and final structures "
+     255             :                "and %u frames after the final structure will be created \n",nbefore,nbetween,nafter);
+     256             : 
+     257             : // Create a vector of arguments to use for calculating displacements
+     258           2 :   Pbc fpbc;
+     259             :   std::vector<std::unique_ptr<Value>> args;
+     260           4 :   for(unsigned i=0; i<eframe->getNumberOfReferenceArguments(); ++i) {
+     261           2 :     args.emplace_back(Tools::make_unique<Value>()); args[args.size()-1]->setNotPeriodic();
+     262             :   }
+     263             : 
+     264             :   // convert pointer once:
+     265           2 :   auto args_ptr=Tools::unique2raw(args);
+     266             : 
+     267             : // Calculate the distance between the start and the end
+     268           2 :   MultiValue myvpack( 1, sframe->getNumberOfReferenceArguments() + 3*sframe->getNumberOfReferencePositions() + 9);
+     269           2 :   ReferenceValuePack mypack( sframe->getNumberOfReferenceArguments(), sframe->getNumberOfReferencePositions(), myvpack );
+     270           2 :   sframe->calc( eframe->getReferencePositions(), fpbc, args_ptr, eframe->getReferenceArguments(), mypack, false );
+     271             : // And the spacing between frames
+     272           2 :   double delr = 1.0 / static_cast<double>( nbetween );
+     273             : // Calculate the vector connecting the start to the end
+     274           2 :   PDB mypdb; mypdb.setAtomNumbers( sframe->getAbsoluteIndexes() ); mypdb.addBlockEnd( sframe->getAbsoluteIndexes().size() );
+     275           2 :   if( sframe->getArgumentNames().size()>0 ) mypdb.setArgumentNames( sframe->getArgumentNames() );
+     276           4 :   Direction mydir(ReferenceConfigurationOptions("DIRECTION")); sframe->setupPCAStorage( mypack ); mydir.read( mypdb ); mydir.zeroDirection();
+     277           2 :   sframe->extractDisplacementVector( eframe->getReferencePositions(), args_ptr, eframe->getReferenceArguments(), false, mydir );
+     278             : 
+     279             : // Now create frames
+     280           2 :   OFile ofile; ofile.open(ofilename); unsigned nframes=0;
+     281           4 :   Direction pos(ReferenceConfigurationOptions("DIRECTION")); pos.read( mypdb );
+     282           4 :   for(int i=0; i<nbefore; ++i) {
+     283           2 :     pos.setDirection( sframe->getReferencePositions(), sframe->getReferenceArguments() );
+     284           2 :     pos.displaceReferenceConfiguration( -i*delr, mydir );
+     285           2 :     mypdb.setAtomPositions( pos.getReferencePositions() );
+     286           4 :     for(unsigned j=0; j<pos.getReferenceArguments().size(); ++j) mypdb.setArgumentValue( sframe->getArgumentNames()[j], pos.getReferenceArgument(j) );
+     287           2 :     ofile.printf("REMARK TYPE=%s\n",mtype.c_str() );
+     288           2 :     mypdb.print( 10, NULL, ofile, ofmt ); nframes++;
+     289             :   }
+     290           8 :   for(unsigned i=1; i<nbetween; ++i) {
+     291           6 :     pos.setDirection( sframe->getReferencePositions(), sframe->getReferenceArguments() );
+     292           6 :     pos.displaceReferenceConfiguration( i*delr, mydir );
+     293           6 :     mypdb.setAtomPositions( pos.getReferencePositions() );
+     294          16 :     for(unsigned j=0; j<pos.getReferenceArguments().size(); ++j) mypdb.setArgumentValue( sframe->getArgumentNames()[j], pos.getReferenceArgument(j) );
+     295           6 :     ofile.printf("REMARK TYPE=%s\n",mtype.c_str() );
+     296           6 :     mypdb.print( 10, NULL, ofile, ofmt ); nframes++;
+     297             :   }
+     298           7 :   for(unsigned i=0; i<nafter; ++i) {
+     299           5 :     pos.setDirection( eframe->getReferencePositions(), eframe->getReferenceArguments() );
+     300           5 :     pos.displaceReferenceConfiguration( i*delr, mydir );
+     301           5 :     mypdb.setAtomPositions( pos.getReferencePositions() );
+     302          13 :     for(unsigned j=0; j<pos.getReferenceArguments().size(); ++j) mypdb.setArgumentValue( sframe->getArgumentNames()[j], pos.getReferenceArgument(j) );
+     303           5 :     ofile.printf("REMARK TYPE=%s\n",mtype.c_str() );
+     304           5 :     mypdb.print( 10, NULL, ofile, ofmt ); nframes++;
+     305             :   }
+     306             : 
+     307           2 :   ofile.close(); return 0;
+     308          10 : }
+     309             : 
+     310             : } // End of namespace
+     311             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PropertyMap.cpp.func-sort-c.html b/coverage/mapping/PropertyMap.cpp.func-sort-c.html new file mode 100644 index 000000000000..aa33a999af32 --- /dev/null +++ b/coverage/mapping/PropertyMap.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PropertyMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PropertyMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11PropertyMapC2ERKNS_13ActionOptionsE0
_ZN4PLMD7mapping11PropertyMapC1ERKNS_13ActionOptionsE3
_ZN4PLMD7mapping11PropertyMap16registerKeywordsERNS_8KeywordsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PropertyMap.cpp.func.html b/coverage/mapping/PropertyMap.cpp.func.html new file mode 100644 index 000000000000..4499ffc235cc --- /dev/null +++ b/coverage/mapping/PropertyMap.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PropertyMap.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PropertyMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11PropertyMap16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD7mapping11PropertyMapC1ERKNS_13ActionOptionsE3
_ZN4PLMD7mapping11PropertyMapC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/PropertyMap.cpp.gcov.html b/coverage/mapping/PropertyMap.cpp.gcov.html new file mode 100644 index 000000000000..f36b85afd77d --- /dev/null +++ b/coverage/mapping/PropertyMap.cpp.gcov.html @@ -0,0 +1,206 @@ + + + + + + + + LCOV - plumed test coverage - mapping/PropertyMap.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - PropertyMap.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PathBase.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : //+PLUMEDOC COLVAR GPROPERTYMAP
+      26             : /*
+      27             : Property maps but with a more flexible framework for the distance metric being used.
+      28             : 
+      29             : This colvar calculates a property map using the formalism developed by Spiwok \cite Spiwok:2011ce.
+      30             : In essence if you have the value of some property, \f$X_i\f$, that it takes at a set of high-dimensional
+      31             : positions then you calculate the value of the property at some arbitrary point in the high-dimensional space
+      32             : using:
+      33             : 
+      34             : \f[
+      35             : X=\frac{\sum_i X_i*\exp(-\lambda D_i(x))}{\sum_i  \exp(-\lambda D_i(x))}
+      36             : \f]
+      37             : 
+      38             : Within PLUMED there are multiple ways to define the distance from a high-dimensional configuration, \f$D_i\f$.  You could calculate
+      39             : the RMSD distance or you could calculate the amount by which a set of collective variables change.  As such this implementation
+      40             : of the property map allows one to use all the different distance metric that are discussed in \ref dists. This is as opposed to
+      41             : the alternative implementation \ref PROPERTYMAP which is a bit faster but which only allows one to use the RMSD distance.
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : The input shown below can be used to calculate the interpolated values of two properties called X and Y based on the values
+      46             : that these properties take at a set of reference configurations and using the formula above.  For this input the distances
+      47             : between the reference configurations and the instantaneous configurations are calculated using the OPTIMAL metric that is
+      48             : discussed at length in the manual pages on \ref RMSD.
+      49             : 
+      50             : \plumedfile
+      51             : p2: GPROPERTYMAP REFERENCE=allv.pdb PROPERTY=X,Y LAMBDA=69087
+      52             : PRINT ARG=p2.X,p2.Y,p2.zpath STRIDE=1 FILE=colvar
+      53             : \endplumedfile
+      54             : 
+      55             : The additional input file for this calculation, which contains the reference frames and the values of X and Y at these reference
+      56             : points has the following format.
+      57             : 
+      58             : \auxfile{allv.pdb}
+      59             : REMARK X=1 Y=2
+      60             : ATOM      1  CL  ALA     1      -3.171   0.295   2.045  1.00  1.00
+      61             : ATOM      5  CLP ALA     1      -1.819  -0.143   1.679  1.00  1.00
+      62             : ATOM      6  OL  ALA     1      -1.177  -0.889   2.401  1.00  1.00
+      63             : ATOM      7  NL  ALA     1      -1.313   0.341   0.529  1.00  1.00
+      64             : ATOM      8  HL  ALA     1      -1.845   0.961  -0.011  1.00  1.00
+      65             : ATOM      9  CA  ALA     1      -0.003  -0.019   0.021  1.00  1.00
+      66             : ATOM     10  HA  ALA     1       0.205  -1.051   0.259  1.00  1.00
+      67             : ATOM     11  CB  ALA     1       0.009   0.135  -1.509  1.00  1.00
+      68             : ATOM     15  CRP ALA     1       1.121   0.799   0.663  1.00  1.00
+      69             : ATOM     16  OR  ALA     1       1.723   1.669   0.043  1.00  1.00
+      70             : ATOM     17  NR  ALA     1       1.423   0.519   1.941  1.00  1.00
+      71             : ATOM     18  HR  ALA     1       0.873  -0.161   2.413  1.00  1.00
+      72             : ATOM     19  CR  ALA     1       2.477   1.187   2.675  1.00  1.00
+      73             : END
+      74             : FIXED
+      75             : REMARK X=2 Y=3
+      76             : ATOM      1  CL  ALA     1      -3.175   0.365   2.024  1.00  1.00
+      77             : ATOM      5  CLP ALA     1      -1.814  -0.106   1.685  1.00  1.00
+      78             : ATOM      6  OL  ALA     1      -1.201  -0.849   2.425  1.00  1.00
+      79             : ATOM      7  NL  ALA     1      -1.296   0.337   0.534  1.00  1.00
+      80             : ATOM      8  HL  ALA     1      -1.807   0.951  -0.044  1.00  1.00
+      81             : ATOM      9  CA  ALA     1       0.009  -0.067   0.033  1.00  1.00
+      82             : ATOM     10  HA  ALA     1       0.175  -1.105   0.283  1.00  1.00
+      83             : ATOM     11  CB  ALA     1       0.027   0.046  -1.501  1.00  1.00
+      84             : ATOM     15  CRP ALA     1       1.149   0.725   0.654  1.00  1.00
+      85             : ATOM     16  OR  ALA     1       1.835   1.491  -0.011  1.00  1.00
+      86             : ATOM     17  NR  ALA     1       1.380   0.537   1.968  1.00  1.00
+      87             : ATOM     18  HR  ALA     1       0.764  -0.060   2.461  1.00  1.00
+      88             : ATOM     19  CR  ALA     1       2.431   1.195   2.683  1.00  1.00
+      89             : END
+      90             : \endauxfile
+      91             : 
+      92             : */
+      93             : //+ENDPLUMEDOC
+      94             : 
+      95             : namespace PLMD {
+      96             : namespace mapping {
+      97             : 
+      98             : class PropertyMap : public PathBase {
+      99             : public:
+     100             :   static void registerKeywords( Keywords& keys );
+     101             :   explicit PropertyMap(const ActionOptions&);
+     102             : };
+     103             : 
+     104             : PLUMED_REGISTER_ACTION(PropertyMap,"GPROPERTYMAP")
+     105             : 
+     106           5 : void PropertyMap::registerKeywords( Keywords& keys ) {
+     107           5 :   PathBase::registerKeywords( keys );
+     108           5 :   ActionWithValue::useCustomisableComponents( keys );
+     109          10 :   keys.addFlag("NOMAPPING",false,"do not calculate the position on the manifold");
+     110           5 : }
+     111             : 
+     112           3 : PropertyMap::PropertyMap(const ActionOptions& ao):
+     113             :   Action(ao),
+     114           3 :   PathBase(ao)
+     115             : {
+     116           6 :   bool nos; parseFlag("NOMAPPING",nos);
+     117             : 
+     118             :   std::string empty;
+     119           3 :   if(!nos) {
+     120           9 :     for(std::map<std::string,std::vector<double> >::iterator it=property.begin(); it!=property.end(); ++it) {
+     121          18 :       empty="LABEL="+it->first; addVessel( "SPATH", empty, 0 );
+     122             :     }
+     123             :   }
+     124           3 :   readVesselKeywords();
+     125           3 :   checkRead();
+     126           3 : }
+     127             : 
+     128             : }
+     129             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/SpathVessel.cpp.func-sort-c.html b/coverage/mapping/SpathVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..577da12a4d59 --- /dev/null +++ b/coverage/mapping/SpathVessel.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - mapping/SpathVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - SpathVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11SpathVessel16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD7mapping11SpathVessel16value_descriptorB5cxx11Ev10
_ZN4PLMD7mapping11SpathVesselC2ERKNS_10vesselbase13VesselOptionsE10
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE10
_ZN4PLMD7mapping11SpathVessel14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeC2Ev4187
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeD2Ev4187
_ZN4PLMD7mapping11SpathVessel7prepareEv5460
_ZNK4PLMD7mapping11SpathVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE27391
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/SpathVessel.cpp.func.html b/coverage/mapping/SpathVessel.cpp.func.html new file mode 100644 index 000000000000..25e77690d210 --- /dev/null +++ b/coverage/mapping/SpathVessel.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - mapping/SpathVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - SpathVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11SpathVessel14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD7mapping11SpathVessel16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD7mapping11SpathVessel16value_descriptorB5cxx11Ev10
_ZN4PLMD7mapping11SpathVessel7prepareEv5460
_ZN4PLMD7mapping11SpathVesselC2ERKNS_10vesselbase13VesselOptionsE10
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE10
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeC2Ev4187
_ZN4PLMD7mapping12_GLOBAL__N_121SpathVesselRegisterMeD2Ev4187
_ZNK4PLMD7mapping11SpathVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE27391
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/SpathVessel.cpp.gcov.html b/coverage/mapping/SpathVessel.cpp.gcov.html new file mode 100644 index 000000000000..72990c6bfcdb --- /dev/null +++ b/coverage/mapping/SpathVessel.cpp.gcov.html @@ -0,0 +1,164 @@ + + + + + + + + LCOV - plumed test coverage - mapping/SpathVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - SpathVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2929100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "vesselbase/VesselRegister.h"
+      23             : #include "vesselbase/FunctionVessel.h"
+      24             : #include "Mapping.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace mapping {
+      28             : 
+      29             : class SpathVessel : public vesselbase::FunctionVessel {
+      30             : private:
+      31             :   bool foundoneclose;
+      32             :   Mapping* mymap;
+      33             : public:
+      34             :   static void registerKeywords( Keywords& keys );
+      35             :   static void reserveKeyword( Keywords& keys );
+      36             :   explicit SpathVessel( const vesselbase::VesselOptions& da );
+      37             :   std::string value_descriptor() override;
+      38             :   void prepare() override;
+      39             :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_index ) const override;
+      40             : };
+      41             : 
+      42       12571 : PLUMED_REGISTER_VESSEL(SpathVessel,"SPATH")
+      43             : 
+      44          10 : void SpathVessel::registerKeywords( Keywords& keys ) {
+      45          10 :   FunctionVessel::registerKeywords(keys);
+      46          10 : }
+      47             : 
+      48        4187 : void SpathVessel::reserveKeyword( Keywords& keys ) {
+      49        8374 :   keys.reserve("vessel","SPATH","docs should not appear");
+      50        8374 :   keys.addOutputComponent("spath","SPATH","the position on the path");
+      51        4187 : }
+      52             : 
+      53          10 : SpathVessel::SpathVessel( const vesselbase::VesselOptions& da ):
+      54             :   FunctionVessel(da),
+      55          10 :   foundoneclose(false)
+      56             : {
+      57          10 :   mymap=dynamic_cast<Mapping*>( getAction() );
+      58          10 :   plumed_massert( mymap, "SpathVessel can only be used with mappings");
+      59             :   // Retrieve the index of the property in the underlying mapping
+      60          10 :   usetol=true; norm=true;
+      61             : 
+      62         430 :   for(unsigned i=0; i<mymap->getFullNumberOfTasks(); ++i) {
+      63         420 :     if( mymap->getTaskCode(i)!=mymap->getPositionInFullTaskList(i) ) error("mismatched tasks and codes");
+      64             :   }
+      65          10 : }
+      66             : 
+      67          10 : std::string SpathVessel::value_descriptor() {
+      68          10 :   return "the position on the path";
+      69             : }
+      70             : 
+      71        5460 : void SpathVessel::prepare() {
+      72        5460 :   foundoneclose=false;
+      73        5460 : }
+      74             : 
+      75       27391 : void SpathVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_index ) const {
+      76       27391 :   double pp=mymap->getPropertyValue( current, getLabel() ), weight=myvals.get(0);
+      77       27391 :   if( weight<getTolerance() ) return;
+      78       27391 :   unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
+      79       27391 :   buffer[bufstart] += weight*pp; buffer[bufstart+1+nderivatives] += weight;
+      80       27391 :   if( getAction()->derivativesAreRequired() ) {
+      81       23478 :     myvals.chainRule( 0, 0, 1, 0, pp, bufstart, buffer );
+      82       23478 :     myvals.chainRule( 0, 1, 1, 0, 1.0, bufstart, buffer );
+      83             :   }
+      84             : }
+      85             : 
+      86             : }
+      87             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/TrigonometricPathVessel.cpp.func-sort-c.html b/coverage/mapping/TrigonometricPathVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..2c6142933b30 --- /dev/null +++ b/coverage/mapping/TrigonometricPathVessel.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - mapping/TrigonometricPathVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - TrigonometricPathVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13413897.1 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE3
_ZN4PLMD7mapping23TrigonometricPathVessel11descriptionB5cxx11Ev3
_ZN4PLMD7mapping23TrigonometricPathVessel16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7mapping23TrigonometricPathVesselC2ERKNS_10vesselbase13VesselOptionsE3
_ZN4PLMD7mapping23TrigonometricPathVessel6resizeEv7
_ZN4PLMD7mapping23TrigonometricPathVessel10applyForceERSt6vectorIdSaIdEE1193
_ZN4PLMD7mapping23TrigonometricPathVessel6finishERKSt6vectorIdSaIdEE1193
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMeC2Ev4187
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMeD2Ev4187
_ZN4PLMD7mapping23TrigonometricPathVessel14reserveKeywordERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/TrigonometricPathVessel.cpp.func.html b/coverage/mapping/TrigonometricPathVessel.cpp.func.html new file mode 100644 index 000000000000..2f8a3ff2247c --- /dev/null +++ b/coverage/mapping/TrigonometricPathVessel.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - mapping/TrigonometricPathVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - TrigonometricPathVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13413897.1 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE3
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMeC2Ev4187
_ZN4PLMD7mapping12_GLOBAL__N_133TrigonometricPathVesselRegisterMeD2Ev4187
_ZN4PLMD7mapping23TrigonometricPathVessel10applyForceERSt6vectorIdSaIdEE1193
_ZN4PLMD7mapping23TrigonometricPathVessel11descriptionB5cxx11Ev3
_ZN4PLMD7mapping23TrigonometricPathVessel14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD7mapping23TrigonometricPathVessel16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD7mapping23TrigonometricPathVessel6finishERKSt6vectorIdSaIdEE1193
_ZN4PLMD7mapping23TrigonometricPathVessel6resizeEv7
_ZN4PLMD7mapping23TrigonometricPathVesselC2ERKNS_10vesselbase13VesselOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/TrigonometricPathVessel.cpp.gcov.html b/coverage/mapping/TrigonometricPathVessel.cpp.gcov.html new file mode 100644 index 000000000000..9b517586ec0e --- /dev/null +++ b/coverage/mapping/TrigonometricPathVessel.cpp.gcov.html @@ -0,0 +1,306 @@ + + + + + + + + LCOV - plumed test coverage - mapping/TrigonometricPathVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - TrigonometricPathVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13413897.1 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "TrigonometricPathVessel.h"
+      23             : #include "vesselbase/VesselRegister.h"
+      24             : #include "tools/PDB.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace mapping {
+      28             : 
+      29       12564 : PLUMED_REGISTER_VESSEL(TrigonometricPathVessel,"GPATH")
+      30             : 
+      31           3 : void TrigonometricPathVessel::registerKeywords( Keywords& keys ) {
+      32           3 :   StoreDataVessel::registerKeywords(keys);
+      33           3 : }
+      34             : 
+      35        4187 : void TrigonometricPathVessel::reserveKeyword( Keywords& keys ) {
+      36        8374 :   keys.reserve("vessel","GPATH","calculate the position on the path using trigonometry");
+      37        8374 :   keys.addOutputComponent("gspath","GPATH","the position on the path calculated using trigonometry");
+      38        8374 :   keys.addOutputComponent("gzpath","GPATH","the distance from the path calculated using trigonometry");
+      39        4187 : }
+      40             : 
+      41           3 : TrigonometricPathVessel::TrigonometricPathVessel( const vesselbase::VesselOptions& da ):
+      42             :   StoreDataVessel(da),
+      43           6 :   projdir(ReferenceConfigurationOptions("DIRECTION")),
+      44           3 :   mydpack1( 1, getAction()->getNumberOfDerivatives() ),
+      45           3 :   mydpack2( 1, getAction()->getNumberOfDerivatives() ),
+      46           3 :   mydpack3( 1, getAction()->getNumberOfDerivatives() ),
+      47           3 :   mypack1( 0, 0, mydpack1 ),
+      48           3 :   mypack2( 0, 0, mydpack2 ),
+      49           9 :   mypack3( 0, 0, mydpack3 )
+      50             : {
+      51           3 :   mymap=dynamic_cast<Mapping*>( getAction() );
+      52           3 :   plumed_massert( mymap, "Trigonometric path vessel can only be used with mappings");
+      53             :   // Retrieve the index of the property in the underlying mapping
+      54           3 :   if( mymap->getNumberOfProperties()!=1 ) error("cannot use trigonometric paths when there are multiple properties");
+      55             : 
+      56         125 :   for(unsigned i=0; i<mymap->getFullNumberOfTasks(); ++i) {
+      57         122 :     if( mymap->getTaskCode(i)!=mymap->getPositionInFullTaskList(i) ) error("mismatched tasks and codes");
+      58             :   }
+      59           6 :   mymap->addComponentWithDerivatives("gspath"); mymap->componentIsNotPeriodic("gspath");
+      60           3 :   sp=mymap->copyOutput( mymap->getNumberOfComponents()-1 ); sp->resizeDerivatives( mymap->getNumberOfDerivatives() );
+      61           6 :   mymap->addComponentWithDerivatives("gzpath"); mymap->componentIsNotPeriodic("gzpath");
+      62           3 :   zp=mymap->copyOutput( mymap->getNumberOfComponents()-1 ); zp->resizeDerivatives( mymap->getNumberOfDerivatives() );
+      63             : 
+      64             :   // Check we have PCA
+      65           3 :   ReferenceConfiguration* ref0=mymap->getReferenceConfiguration(0);
+      66         125 :   for(unsigned i=0; i<mymap->getFullNumberOfTasks(); ++i) {
+      67         122 :     if( !(mymap->getReferenceConfiguration(i))->pcaIsEnabledForThisReference() ) error("pca must be implemented in order to use trigometric path");
+      68         244 :     if( ref0->getName()!=(mymap->getReferenceConfiguration(i))->getName() ) error("cannot use mixed metrics");
+      69         122 :     if( mymap->getNumberOfAtoms()!=(mymap->getReferenceConfiguration(i))->getNumberOfReferencePositions() ) error("all frames must use the same set of atoms");
+      70         122 :     if( mymap->getNumberOfArguments()!=(mymap->getReferenceConfiguration(i))->getNumberOfReferenceArguments() ) error("all frames must use the same set of arguments");
+      71             :   }
+      72             : 
+      73           3 :   cargs.resize( mymap->getNumberOfArguments() ); std::vector<std::string> argument_names( mymap->getNumberOfArguments() );
+      74           7 :   for(unsigned i=0; i<mymap->getNumberOfArguments(); ++i) argument_names[i] = (mymap->getPntrToArgument(i))->getName();
+      75           3 :   PDB mypdb; mypdb.setAtomNumbers( mymap->getAbsoluteIndexes() ); mypdb.addBlockEnd( mymap->getAbsoluteIndexes().size() );
+      76           3 :   if( argument_names.size()>0 ) mypdb.setArgumentNames( argument_names );
+      77           3 :   projdir.read( mypdb );
+      78           3 :   mypack1.resize( mymap->getNumberOfArguments(), mymap->getNumberOfAtoms() ); ref0->setupPCAStorage( mypack1 );
+      79           3 :   mypack2.resize( mymap->getNumberOfArguments(), mymap->getNumberOfAtoms() ); ref0->setupPCAStorage( mypack2 );
+      80           3 :   mypack3.resize( mymap->getNumberOfArguments(), mymap->getNumberOfAtoms() );
+      81          16 :   for(unsigned i=0; i<mymap->getNumberOfAtoms(); ++i) { mypack1.setAtomIndex(i,i); mypack2.setAtomIndex(i,i); mypack3.setAtomIndex(i,i); }
+      82           3 :   mypack1_stashd_atoms.resize( mymap->getNumberOfAtoms() ); mypack1_stashd_args.resize( mymap->getNumberOfArguments() );
+      83           3 : }
+      84             : 
+      85           3 : std::string TrigonometricPathVessel::description() {
+      86           3 :   return "values gspath and gzpath contain the position on and distance from the path calculated using trigonometry";
+      87             : }
+      88             : 
+      89           7 : void TrigonometricPathVessel::resize() {
+      90           7 :   StoreDataVessel::resize();
+      91           7 :   if( getAction()->derivativesAreRequired() ) {
+      92           4 :     unsigned nderivatives=getAction()->getNumberOfDerivatives();
+      93           4 :     sp->resizeDerivatives( nderivatives ); zp->resizeDerivatives( nderivatives );
+      94             :   }
+      95           7 : }
+      96             : 
+      97        1193 : void TrigonometricPathVessel::finish( const std::vector<double>& buffer ) {
+      98             :   // Store the data calculated during mpi loop
+      99        1193 :   StoreDataVessel::finish( buffer );
+     100             :   // Get current value of all arguments
+     101        2487 :   for(unsigned i=0; i<cargs.size(); ++i) cargs[i]=mymap->getArgument(i);
+     102             : 
+     103             :   // Determine closest and second closest point to current position
+     104        1193 :   double lambda=mymap->getLambda();
+     105        1193 :   std::vector<double> dist( getNumberOfComponents() ), dist2( getNumberOfComponents() );;
+     106        1193 :   retrieveSequentialValue( 0, false, dist );
+     107        1193 :   retrieveSequentialValue( 1, false, dist2 );
+     108        1193 :   iclose1=getStoreIndex(0); iclose2=getStoreIndex(1);
+     109        1193 :   double mindist1=dist[0], mindist2=dist2[0];
+     110        1193 :   if( lambda>0.0 ) {
+     111           0 :     mindist1=-std::log( dist[0] ) / lambda;
+     112           0 :     mindist2=-std::log( dist2[0] ) / lambda;
+     113             :   }
+     114        1193 :   if( mindist2<mindist1 ) {
+     115             :     double tmp=mindist1; mindist1=mindist2; mindist2=tmp;
+     116         866 :     iclose1=getStoreIndex(1); iclose2=getStoreIndex(0);
+     117             :   }
+     118       56519 :   for(unsigned i=2; i<getNumberOfStoredValues(); ++i) {
+     119       55326 :     retrieveSequentialValue( i, false, dist );
+     120       55326 :     double ndist=dist[0];
+     121       55326 :     if( lambda>0.0 ) ndist=-std::log( dist[0] ) / lambda;
+     122       55326 :     if( ndist<mindist1 ) {
+     123       19737 :       mindist2=mindist1; iclose2=iclose1;
+     124       19737 :       mindist1=ndist; iclose1=getStoreIndex(i);
+     125       35589 :     } else if( ndist<mindist2 ) {
+     126        1062 :       mindist2=ndist; iclose2=getStoreIndex(i);
+     127             :     }
+     128             :   }
+     129             :   // And find third closest point
+     130        1193 :   int isign = iclose1 - iclose2;
+     131             :   if( isign>1 ) isign=1; else if( isign<-1 ) isign=-1;
+     132        1193 :   int iclose3 = iclose1 + isign; double v2v2;
+     133             :   // We now have to compute vectors connecting the three closest points to the
+     134             :   // new point
+     135        1193 :   double v1v1 = (mymap->getReferenceConfiguration( iclose1 ))->calculate( mymap->getPositions(), mymap->getPbc(), mymap->getArguments(), mypack1, true );
+     136        1193 :   double v3v3 = (mymap->getReferenceConfiguration( iclose2 ))->calculate( mymap->getPositions(), mymap->getPbc(), mymap->getArguments(), mypack3, true );
+     137        1193 :   if( iclose3<0 || iclose3>=mymap->getFullNumberOfTasks() ) {
+     138          31 :     ReferenceConfiguration* conf2=mymap->getReferenceConfiguration( iclose1 );
+     139          62 :     v2v2=(mymap->getReferenceConfiguration( iclose2 ))->calc( conf2->getReferencePositions(), mymap->getPbc(), mymap->getArguments(),
+     140          31 :          conf2->getReferenceArguments(), mypack2, true );
+     141          62 :     (mymap->getReferenceConfiguration( iclose2 ))->extractDisplacementVector( conf2->getReferencePositions(), mymap->getArguments(),
+     142          62 :         conf2->getReferenceArguments(), false, projdir );
+     143             :   } else {
+     144        1162 :     ReferenceConfiguration* conf2=mymap->getReferenceConfiguration( iclose3 );
+     145        2324 :     v2v2=(mymap->getReferenceConfiguration( iclose1 ))->calc( conf2->getReferencePositions(), mymap->getPbc(), mymap->getArguments(),
+     146        1162 :          conf2->getReferenceArguments(), mypack2, true );
+     147        2324 :     (mymap->getReferenceConfiguration( iclose1 ))->extractDisplacementVector( conf2->getReferencePositions(), mymap->getArguments(),
+     148        2324 :         conf2->getReferenceArguments(), false, projdir );
+     149             :   }
+     150             : 
+     151             :   // Stash derivatives of v1v1
+     152        2487 :   for(unsigned i=0; i<mymap->getNumberOfArguments(); ++i) mypack1_stashd_args[i]=mypack1.getArgumentDerivative(i);
+     153        1193 :   if( mymap->getNumberOfAtoms()>0 ) {
+     154         546 :     ReferenceAtoms* at = dynamic_cast<ReferenceAtoms*>( mymap->getReferenceConfiguration( iclose1 ) );
+     155             :     const std::vector<double> & displace( at->getDisplace() );
+     156        7644 :     for(unsigned i=0; i<mymap->getNumberOfAtoms(); ++i) {
+     157        7098 :       mypack1_stashd_atoms[i]=mypack1.getAtomDerivative(i); mypack1.getAtomsDisplacementVector()[i] /= displace[i];
+     158             :     }
+     159             :   }
+     160             :   // Calculate the dot product of v1 with v2
+     161        1193 :   double v1v2 = (mymap->getReferenceConfiguration(iclose1))->projectDisplacementOnVector( projdir, mymap->getArguments(), cargs, mypack1 );
+     162             : 
+     163             :   // This computes s value
+     164        1193 :   double spacing = mymap->getPropertyValue( iclose1, (mymap->property.begin())->first ) - mymap->getPropertyValue( iclose2, (mymap->property.begin())->first );
+     165        1193 :   double root = sqrt( v1v2*v1v2 - v2v2 * ( v1v1 - v3v3) );
+     166        1193 :   dx = 0.5 * ( (root + v1v2) / v2v2 - 1.);
+     167        1193 :   double path_s = mymap->getPropertyValue(iclose1, (mymap->property.begin())->first ) + spacing * dx; sp->set( path_s );
+     168        1193 :   double fact = 0.25*spacing / v2v2;
+     169             :   // Derivative of s wrt arguments
+     170        2487 :   for(unsigned i=0; i<mymap->getNumberOfArguments(); ++i) {
+     171        1294 :     sp->setDerivative( i, fact*( mypack2.getArgumentDerivative(i) + (v2v2 * (-mypack1_stashd_args[i] + mypack3.getArgumentDerivative(i))
+     172        1294 :                                  + v1v2*mypack2.getArgumentDerivative(i) )/root ) );
+     173             :   }
+     174             :   // Derivative of s wrt atoms
+     175        1193 :   unsigned narg=mymap->getNumberOfArguments(); Tensor vir; vir.zero(); fact = 0.5*spacing / v2v2;
+     176        1193 :   if( mymap->getNumberOfAtoms()>0 ) {
+     177        7644 :     for(unsigned i=0; i<mymap->getNumberOfAtoms(); ++i) {
+     178        7098 :       Vector ader = fact*(( v1v2*mypack1.getAtomDerivative(i) + 0.5*v2v2*(-mypack1_stashd_atoms[i] + mypack3.getAtomDerivative(i) ) )/root + mypack1.getAtomDerivative(i) );
+     179       28392 :       for(unsigned k=0; k<3; ++k) sp->setDerivative( narg+3*i+k, ader[k] );
+     180        7098 :       vir-=Tensor( mymap->getPosition(i), ader );
+     181             :     }
+     182             :     // Set the virial
+     183         546 :     unsigned nbase=narg+3*mymap->getNumberOfAtoms();
+     184        7098 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) sp->setDerivative( nbase+3*i+j, vir(i,j) );
+     185             :   }
+     186             :   // Now compute z value
+     187        1193 :   ReferenceConfiguration* conf2=mymap->getReferenceConfiguration( iclose1 );
+     188        2386 :   double v4v4=(mymap->getReferenceConfiguration( iclose2 ))->calc( conf2->getReferencePositions(), mymap->getPbc(), mymap->getArguments(),
+     189        1193 :               conf2->getReferenceArguments(), mypack2, true );
+     190             :   // Extract vector connecting frames
+     191        2386 :   (mymap->getReferenceConfiguration( iclose2 ))->extractDisplacementVector( conf2->getReferencePositions(), mymap->getArguments(),
+     192        1193 :       conf2->getReferenceArguments(), false, projdir );
+     193             :   // Calculate projection of vector on line connnecting frames
+     194        1193 :   double proj = (mymap->getReferenceConfiguration(iclose1))->projectDisplacementOnVector( projdir, mymap->getArguments(), cargs, mypack1 );
+     195        1193 :   double path_z = v1v1 + dx*dx*v4v4 - 2*dx*proj;
+     196             :   // Derivatives for z path
+     197        1193 :   path_z = sqrt(path_z); zp->set( path_z ); vir.zero();
+     198        2487 :   for(unsigned i=0; i<mymap->getNumberOfArguments(); ++i) zp->setDerivative( i, (mypack1_stashd_args[i] - 2*dx*mypack1.getArgumentDerivative(i))/(2.0*path_z) );
+     199             :   // Derivative wrt atoms
+     200        1193 :   if( mymap->getNumberOfAtoms()>0 ) {
+     201        7644 :     for(unsigned i=0; i<mymap->getNumberOfAtoms(); ++i) {
+     202       28392 :       Vector dxder; for(unsigned k=0; k<3; ++k) dxder[k] = ( 2*v4v4*dx - 2*proj )*spacing*sp->getDerivative( narg + 3*i+k );
+     203        7098 :       Vector ader = ( mypack1_stashd_atoms[i] - 2.*dx*mypack1.getAtomDerivative(i) + dxder )/ (2.0*path_z);
+     204       28392 :       for(unsigned k=0; k<3; ++k) zp->setDerivative( narg+3*i+k, ader[k] );
+     205        7098 :       vir-=Tensor( mymap->getPosition(i), ader );
+     206             :     }
+     207             :     // Set the virial
+     208         546 :     unsigned nbase=narg+3*mymap->getNumberOfAtoms();
+     209        7098 :     for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) zp->setDerivative( nbase+3*i+j, vir(i,j) );
+     210             :   }
+     211        1193 : }
+     212             : 
+     213        1193 : bool TrigonometricPathVessel::applyForce( std::vector<double>& forces ) {
+     214        1193 :   std::vector<double> tmpforce( forces.size(), 0.0 );
+     215        1193 :   forces.assign(forces.size(),0.0); bool wasforced=false;
+     216        1193 :   if( sp->applyForce( tmpforce ) ) {
+     217             :     wasforced=true;
+     218           0 :     for(unsigned j=0; j<forces.size(); ++j) forces[j]+=tmpforce[j];
+     219             :   }
+     220        1193 :   tmpforce.assign(forces.size(),0.0);
+     221        1193 :   if( zp->applyForce( tmpforce ) ) {
+     222             :     wasforced=true;
+     223           0 :     for(unsigned j=0; j<forces.size(); ++j) forces[j]+=tmpforce[j];
+     224             :   }
+     225        1193 :   return wasforced;
+     226             : }
+     227             : 
+     228             : }
+     229             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/ZpathVessel.cpp.func-sort-c.html b/coverage/mapping/ZpathVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..32eb2613e159 --- /dev/null +++ b/coverage/mapping/ZpathVessel.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - mapping/ZpathVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - ZpathVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11ZpathVessel16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7mapping11ZpathVessel16value_descriptorB5cxx11Ev7
_ZN4PLMD7mapping11ZpathVesselC2ERKNS_10vesselbase13VesselOptionsE7
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE7
_ZN4PLMD7mapping11ZpathVessel14finalTransformERKdRd3822
_ZN4PLMD7mapping11ZpathVessel14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeC2Ev4187
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeD2Ev4187
_ZNK4PLMD7mapping11ZpathVessel13calcTransformERKdRd19565
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/ZpathVessel.cpp.func.html b/coverage/mapping/ZpathVessel.cpp.func.html new file mode 100644 index 000000000000..5a064bda2811 --- /dev/null +++ b/coverage/mapping/ZpathVessel.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - mapping/ZpathVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - ZpathVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD7mapping11ZpathVessel14finalTransformERKdRd3822
_ZN4PLMD7mapping11ZpathVessel14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD7mapping11ZpathVessel16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD7mapping11ZpathVessel16value_descriptorB5cxx11Ev7
_ZN4PLMD7mapping11ZpathVesselC2ERKNS_10vesselbase13VesselOptionsE7
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMe6createERKNS_10vesselbase13VesselOptionsE7
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeC2Ev4187
_ZN4PLMD7mapping12_GLOBAL__N_121ZpathVesselRegisterMeD2Ev4187
_ZNK4PLMD7mapping11ZpathVessel13calcTransformERKdRd19565
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/ZpathVessel.cpp.gcov.html b/coverage/mapping/ZpathVessel.cpp.gcov.html new file mode 100644 index 000000000000..12139bbd0c98 --- /dev/null +++ b/coverage/mapping/ZpathVessel.cpp.gcov.html @@ -0,0 +1,151 @@ + + + + + + + + LCOV - plumed test coverage - mapping/ZpathVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mapping - ZpathVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "vesselbase/VesselRegister.h"
+      23             : #include "vesselbase/FunctionVessel.h"
+      24             : #include "Mapping.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace mapping {
+      28             : 
+      29             : class ZpathVessel : public vesselbase::FunctionVessel {
+      30             : private:
+      31             :   double invlambda;
+      32             : public:
+      33             :   static void registerKeywords( Keywords& keys );
+      34             :   static void reserveKeyword( Keywords& keys );
+      35             :   explicit ZpathVessel( const vesselbase::VesselOptions& da );
+      36             :   std::string value_descriptor() override;
+      37             :   double calcTransform( const double& val, double& dv ) const override;
+      38             :   double finalTransform( const double& val, double& dv ) override;
+      39             : };
+      40             : 
+      41       12568 : PLUMED_REGISTER_VESSEL(ZpathVessel,"ZPATH")
+      42             : 
+      43           7 : void ZpathVessel::registerKeywords( Keywords& keys ) {
+      44           7 :   FunctionVessel::registerKeywords(keys);
+      45           7 : }
+      46             : 
+      47        4187 : void ZpathVessel::reserveKeyword( Keywords& keys ) {
+      48        8374 :   keys.reserve("vessel","ZPATH","calculate the distance from the low dimensionality manifold");
+      49        8374 :   keys.addOutputComponent("zpath","ZPATH","the distance from the path");
+      50        4187 : }
+      51             : 
+      52           7 : ZpathVessel::ZpathVessel( const vesselbase::VesselOptions& da ):
+      53           7 :   FunctionVessel(da)
+      54             : {
+      55           7 :   Mapping* mymap=dynamic_cast<Mapping*>( getAction() );
+      56           7 :   plumed_massert( mymap, "ZpathVessel should only be used with mappings");
+      57           7 :   invlambda = 1.0 / mymap->getLambda(); usetol=true;
+      58           7 : }
+      59             : 
+      60           7 : std::string ZpathVessel::value_descriptor() {
+      61           7 :   return "the distance from the low-dimensional manifold";
+      62             : }
+      63             : 
+      64       19565 : double ZpathVessel::calcTransform( const double& val, double& dv ) const {
+      65       19565 :   dv=0.0; return 1.0;
+      66             : }
+      67             : 
+      68        3822 : double ZpathVessel::finalTransform( const double& val, double& dv ) {
+      69        3822 :   dv = -invlambda / val;
+      70        3822 :   return -invlambda*std::log( val );
+      71             : }
+      72             : 
+      73             : }
+      74             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/index-sort-f.html b/coverage/mapping/index-sort-f.html new file mode 100644 index 000000000000..cb88bedd1cbd --- /dev/null +++ b/coverage/mapping/index-sort-f.html @@ -0,0 +1,204 @@ + + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:75480593.7 %
Date:2024-02-22 21:58:45Functions:778887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PropertyMap.cpp +
100.0%
+
100.0 %14 / 1466.7 %2 / 3
Path.cpp +
100.0%
+
100.0 %14 / 1466.7 %2 / 3
Mapping.cpp +
78.1%78.1%
+
78.1 %82 / 10566.7 %8 / 12
Mapping.h +
92.3%92.3%
+
92.3 %12 / 1380.0 %4 / 5
PCAVars.cpp +
88.1%88.1%
+
88.1 %126 / 14380.0 %8 / 10
PathBase.cpp +
100.0%
+
100.0 %35 / 3585.7 %6 / 7
AdaptivePath.cpp +
96.1%96.1%
+
96.1 %99 / 10387.5 %7 / 8
PathReparameterization.cpp +
100.0%
+
100.0 %65 / 65100.0 %5 / 5
PathTools.cpp +
98.4%98.4%
+
98.4 %123 / 125100.0 %7 / 7
SpathVessel.cpp +
100.0%
+
100.0 %29 / 29100.0 %9 / 9
ZpathVessel.cpp +
100.0%
+
100.0 %21 / 21100.0 %9 / 9
TrigonometricPathVessel.cpp +
97.1%97.1%
+
97.1 %134 / 138100.0 %10 / 10
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/index-sort-l.html b/coverage/mapping/index-sort-l.html new file mode 100644 index 000000000000..9ff446239488 --- /dev/null +++ b/coverage/mapping/index-sort-l.html @@ -0,0 +1,204 @@ + + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:75480593.7 %
Date:2024-02-22 21:58:45Functions:778887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Mapping.cpp +
78.1%78.1%
+
78.1 %82 / 10566.7 %8 / 12
PCAVars.cpp +
88.1%88.1%
+
88.1 %126 / 14380.0 %8 / 10
Mapping.h +
92.3%92.3%
+
92.3 %12 / 1380.0 %4 / 5
AdaptivePath.cpp +
96.1%96.1%
+
96.1 %99 / 10387.5 %7 / 8
TrigonometricPathVessel.cpp +
97.1%97.1%
+
97.1 %134 / 138100.0 %10 / 10
PathTools.cpp +
98.4%98.4%
+
98.4 %123 / 125100.0 %7 / 7
PropertyMap.cpp +
100.0%
+
100.0 %14 / 1466.7 %2 / 3
Path.cpp +
100.0%
+
100.0 %14 / 1466.7 %2 / 3
ZpathVessel.cpp +
100.0%
+
100.0 %21 / 21100.0 %9 / 9
SpathVessel.cpp +
100.0%
+
100.0 %29 / 29100.0 %9 / 9
PathBase.cpp +
100.0%
+
100.0 %35 / 3585.7 %6 / 7
PathReparameterization.cpp +
100.0%
+
100.0 %65 / 65100.0 %5 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/mapping/index.html b/coverage/mapping/index.html new file mode 100644 index 000000000000..dfe4fcbb1616 --- /dev/null +++ b/coverage/mapping/index.html @@ -0,0 +1,204 @@ + + + + + + + + LCOV - plumed test coverage - mapping + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mappingHitTotalCoverage
Test:plumed test coverageLines:75480593.7 %
Date:2024-02-22 21:58:45Functions:778887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AdaptivePath.cpp +
96.1%96.1%
+
96.1 %99 / 10387.5 %7 / 8
Mapping.cpp +
78.1%78.1%
+
78.1 %82 / 10566.7 %8 / 12
Mapping.h +
92.3%92.3%
+
92.3 %12 / 1380.0 %4 / 5
PCAVars.cpp +
88.1%88.1%
+
88.1 %126 / 14380.0 %8 / 10
Path.cpp +
100.0%
+
100.0 %14 / 1466.7 %2 / 3
PathBase.cpp +
100.0%
+
100.0 %35 / 3585.7 %6 / 7
PathReparameterization.cpp +
100.0%
+
100.0 %65 / 65100.0 %5 / 5
PathTools.cpp +
98.4%98.4%
+
98.4 %123 / 125100.0 %7 / 7
PropertyMap.cpp +
100.0%
+
100.0 %14 / 1466.7 %2 / 3
SpathVessel.cpp +
100.0%
+
100.0 %29 / 29100.0 %9 / 9
TrigonometricPathVessel.cpp +
97.1%97.1%
+
97.1 %134 / 138100.0 %10 / 10
ZpathVessel.cpp +
100.0%
+
100.0 %21 / 21100.0 %9 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.cpp.func-sort-c.html b/coverage/maze/Loss.cpp.func-sort-c.html new file mode 100644 index 000000000000..8cf566f8a7eb --- /dev/null +++ b/coverage/maze/Loss.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4LossC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze4LossC1ERKNS_13ActionOptionsE8
_ZN4PLMD4maze4Loss16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4maze4Loss7pairingEd14342730
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.cpp.func.html b/coverage/maze/Loss.cpp.func.html new file mode 100644 index 000000000000..386368148e54 --- /dev/null +++ b/coverage/maze/Loss.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4Loss16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4maze4Loss7pairingEd14342730
_ZN4PLMD4maze4LossC1ERKNS_13ActionOptionsE8
_ZN4PLMD4maze4LossC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.cpp.gcov.html b/coverage/maze/Loss.cpp.gcov.html new file mode 100644 index 000000000000..c176b17dcd2f --- /dev/null +++ b/coverage/maze/Loss.cpp.gcov.html @@ -0,0 +1,191 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Loss.cpp
+      25             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      26             :  */
+      27             : 
+      28             : #include "Loss.h"
+      29             : #include "core/PlumedMain.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace maze {
+      33             : 
+      34             : //+PLUMEDOC MAZE_LOSS MAZE_LOSS
+      35             : /*
+      36             : 
+      37             : Define a coarse-grained loss function describing interactions in a
+      38             : ligand-protein complex, which is minimized during the simulation to
+      39             : obtain ligand unbinding pathways.
+      40             : 
+      41             : The loss function is the following:
+      42             : \f[
+      43             : \mathcal{L}=
+      44             : \sum_{i=1}^{N_p}
+      45             : r_i^{-\alpha}\text{e}^{-\beta r_i^{-\gamma}},
+      46             : \f]
+      47             : where \f$N_p\f$ is the number of ligand-protein atom pairs, \f$r\f$
+      48             : is a re-scaled distance between the \f$i\f$th pair, and \f$\alpha,
+      49             : \beta, \gamma\f$ are the positive parameters defined in that order by
+      50             : the PARAMS keyword.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : The loss function can be defined in the following way:
+      55             : \plumedfile
+      56             : l: MAZE_LOSS PARAMS=1,1,1
+      57             : \endplumedfile
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : // Registers the LOSS action.
+      63             : PLUMED_REGISTER_ACTION(Loss, "MAZE_LOSS")
+      64             : 
+      65          10 : void Loss::registerKeywords(Keywords& keys) {
+      66          10 :   Colvar::registerKeywords(keys);
+      67             : 
+      68          20 :   keys.add(
+      69             :     "compulsory",
+      70             :     "PARAMS",
+      71             :     "Parameters for the loss function."
+      72             :   );
+      73          10 : }
+      74             : 
+      75           8 : Loss::Loss(const ActionOptions& ao)
+      76           8 :   : PLUMED_COLVAR_INIT(ao)
+      77             : {
+      78          16 :   if (keywords.exists("PARAMS")) {
+      79          16 :     parseVector("PARAMS", params_);
+      80             : 
+      81           8 :     plumed_massert(
+      82             :       params_.size() == 3,
+      83             :       "maze> PARAMS should be of size 3: alpha, beta, gamma\n"
+      84             :     );
+      85             : 
+      86           8 :     plumed_massert(
+      87             :       params_[0] > 0 && params_[1] > 0 && params_[2] > 0,
+      88             :       "maze> Each parameter should be positive\n"
+      89             :     );
+      90             : 
+      91           8 :     log.printf("maze> \t Loss parsed with parameters: ");
+      92          32 :     for (size_t i = 0; i < params_.size(); ++i) {
+      93          24 :       log.printf("%f ", params_[i]);
+      94             :     }
+      95           8 :     log.printf("\n");
+      96             :   }
+      97             : 
+      98           8 :   checkRead();
+      99           8 : }
+     100             : 
+     101    14342730 : double Loss::pairing(double distance) {
+     102    14342730 :   double alpha = params_[0];
+     103    14342730 :   double beta = params_[1];
+     104    14342730 :   double gamma = params_[2];
+     105             : 
+     106    28685460 :   if (getUnits().getLengthString() == "nm") {
+     107    14223600 :     distance *= 10.0;
+     108             :   }
+     109             : 
+     110    14342730 :   return pow(distance, -alpha) * exp(-beta * pow(distance, gamma));
+     111             : }
+     112             : 
+     113             : } // namespace maze
+     114             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.h.func-sort-c.html b/coverage/maze/Loss.h.func-sort-c.html new file mode 100644 index 000000000000..a8679a1d3ae4 --- /dev/null +++ b/coverage/maze/Loss.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4Loss9calculateEv0
_ZN4PLMD4maze4LossD0Ev8
_ZN4PLMD4maze4LossD1Ev8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.h.func.html b/coverage/maze/Loss.h.func.html new file mode 100644 index 000000000000..55096fb7a724 --- /dev/null +++ b/coverage/maze/Loss.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze4Loss9calculateEv0
_ZN4PLMD4maze4LossD0Ev8
_ZN4PLMD4maze4LossD1Ev8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Loss.h.gcov.html b/coverage/maze/Loss.h.gcov.html new file mode 100644 index 000000000000..edf38a90f904 --- /dev/null +++ b/coverage/maze/Loss.h.gcov.html @@ -0,0 +1,163 @@ + + + + + + + + LCOV - plumed test coverage - maze/Loss.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Loss.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_maze_Loss_h
+      23             : #define __PLUMED_maze_Loss_h
+      24             : 
+      25             : /**
+      26             :  * @file Loss.h
+      27             :  *
+      28             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      29             :  */
+      30             : 
+      31             : #include "colvar/Colvar.h"
+      32             : #include "core/ActionRegister.h"
+      33             : #include "Core.h"
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace maze {
+      37             : 
+      38             : /**
+      39             :  * @class Loss Loss.h "maze/Loss.h"
+      40             :  *
+      41             :  * @brief Loss function describes a score between a ligand-protein conformation.
+      42             :  *
+      43             :  * Loss function must be defined for an optimizer as it minimizes a loss
+      44             :  * of a ligand-protein conformation in order to simulate the ligand-protein
+      45             :  * dissociation process.
+      46             :  */
+      47             : class Loss: public colvar::Colvar {
+      48             : public:
+      49             :   /**
+      50             :    * PLMD constructor.
+      51             :    *
+      52             :    * @param[in] ao PLMD::ActionOptions&.
+      53             :    */
+      54             :   explicit Loss(const ActionOptions& ao);
+      55             : 
+      56             :   /**
+      57             :    * Destructor.
+      58             :    */
+      59          16 :   ~Loss() { /* Nothing to do. */ }
+      60             : 
+      61             :   /**
+      62             :    * Register PLMD keywords.
+      63             :    *
+      64             :    * @param[in] keys Keywords.
+      65             :    */
+      66             :   static void registerKeywords(Keywords& keys);
+      67             : 
+      68             :   /**
+      69             :    * Calculate a loss of a single pair of ligand-protein atoms.
+      70             :    *
+      71             :    * @param[in] distance Distance between atoms in the pair.
+      72             :    */
+      73             :   double pairing(double distance);
+      74             : 
+      75             :   // Required by the Colvar class.
+      76           0 :   void calculate() override { /* Nothing to do. */ }
+      77             : 
+      78             : protected:
+      79             :   //! Parameters of the loss function.
+      80             :   std::vector<double> params_;
+      81             : };
+      82             : 
+      83             : } // namespace maze
+      84             : } // namespace PLMD
+      85             : 
+      86             : #endif // __PLUMED_maze_Loss_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Member.h.func-sort-c.html b/coverage/maze/Member.h.func-sort-c.html new file mode 100644 index 000000000000..3d61aa3ecc29 --- /dev/null +++ b/coverage/maze/Member.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - maze/Member.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Member.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze6MemberC2Ev304
_ZN4PLMD4maze7compareERNS0_6MemberES2_409
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Member.h.func.html b/coverage/maze/Member.h.func.html new file mode 100644 index 000000000000..b2548400787f --- /dev/null +++ b/coverage/maze/Member.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - maze/Member.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Member.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze6MemberC2Ev304
_ZN4PLMD4maze7compareERNS0_6MemberES2_409
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Member.h.gcov.html b/coverage/maze/Member.h.gcov.html new file mode 100644 index 000000000000..39d23bed2dd2 --- /dev/null +++ b/coverage/maze/Member.h.gcov.html @@ -0,0 +1,143 @@ + + + + + + + + LCOV - plumed test coverage - maze/Member.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Member.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_maze_Member_h
+      23             : #define __PLUMED_maze_Member_h
+      24             : 
+      25             : /**
+      26             :  * @file Member.h
+      27             :  *
+      28             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      29             :  */
+      30             : 
+      31             : #include "Core.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace maze {
+      35             : 
+      36             : /**
+      37             :  * @class Member Member.h "maze/Member.h"
+      38             :  *
+      39             :  * @brief Defines the encoding for a ligand conformation.
+      40             :  *
+      41             :  * The Member class is required by some optimizers. Ligand conformations are
+      42             :  * encoded by a Cartesian translation relative to a ligand conformation from
+      43             :  * the MD simulation. Each translation has a loss (score) which tells how
+      44             :  * preferred is the encoding w.r.t. a chosen loss function.
+      45             :  */
+      46             : struct Member {
+      47             : public:
+      48         304 :   Member()
+      49         304 :     : score(-1),
+      50         304 :       translation({0, 0, 0}) { /* Nothing to do. */ }
+      51             : 
+      52             :   //! Value of the loss function.
+      53             :   double score;
+      54             : 
+      55             :   //! Encoding of a ligand conformation, i.e., its translation.
+      56             :   Vector translation;
+      57             : };
+      58             : 
+      59         409 : inline bool compare(Member& m, Member& n) {
+      60         409 :   return m.score > n.score;
+      61             : }
+      62             : 
+      63             : } // namespace maze
+      64             : } // namespace PLMD
+      65             : 
+      66             : #endif // __PLUMED_maze_Member_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.cpp.func-sort-c.html b/coverage/maze/Memetic.cpp.func-sort-c.html new file mode 100644 index 000000000000..8784554a99ac --- /dev/null +++ b/coverage/maze/Memetic.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze7MemeticC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze7MemeticC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze7Memetic16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze7Memetic8optimizeEv6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.cpp.func.html b/coverage/maze/Memetic.cpp.func.html new file mode 100644 index 000000000000..55dda31d6ef3 --- /dev/null +++ b/coverage/maze/Memetic.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze7Memetic16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze7Memetic8optimizeEv6
_ZN4PLMD4maze7MemeticC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze7MemeticC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.cpp.gcov.html b/coverage/maze/Memetic.cpp.gcov.html new file mode 100644 index 000000000000..fa24064cb3cf --- /dev/null +++ b/coverage/maze/Memetic.cpp.gcov.html @@ -0,0 +1,359 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6060100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Memetic.cpp
+      25             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      26             :  */
+      27             : 
+      28             : #include "Memetic.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace maze {
+      32             : 
+      33             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_MEMETIC_SAMPLING
+      34             : /*
+      35             : 
+      36             : Calculates the biasing direction along which the ligand unbinds by
+      37             : minimizing the \ref MAZE_LOSS function. The optimal biasing direction is
+      38             : determined by performing a population-based memetics search with local
+      39             : heuristics.
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : Every optimizer implemented in the maze module needs a loss function as
+      44             : an argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      45             : 
+      46             : \plumedfile
+      47             : MAZE_MEMETIC_SAMPLING ...
+      48             :   LABEL=ma
+      49             : 
+      50             :   LOSS=l
+      51             : 
+      52             :   N_ITER=10
+      53             :   OPTIMIZER_STRIDE=200
+      54             : 
+      55             :   CAPACITY=20
+      56             : 
+      57             :   LOCAL_SEARCH_ON
+      58             :   N_LOCAL_ITER=10
+      59             :   LOCAL_SEARCH_RATE=0.1
+      60             :   LOCAL_SEARCH_TYPE=stochastic_hill_climbing
+      61             : 
+      62             :   MUTATION_RATE=0.1
+      63             :   MATING_RATE=0.7
+      64             :   CAUCHY_ALPHA=0
+      65             :   CAUCHY_BETA=0.1
+      66             : 
+      67             :   LIGAND=2635-2646
+      68             :   PROTEIN=1-2634
+      69             : ... MAZE_MEMETIC_SAMPLING
+      70             : \endplumedfile
+      71             : 
+      72             : As shown above, each optimizer should be provided with the LIGAND and
+      73             : the PROTEIN keywords.
+      74             : 
+      75             : The neighbor list can be turned on by providing the NLIST keyword.
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : /**
+      81             :  * Register MAZE_MEMETIC_SAMPLING.
+      82             :  */
+      83             : PLUMED_REGISTER_ACTION(Memetic, "MAZE_MEMETIC_SAMPLING")
+      84             : 
+      85           4 : void Memetic::registerKeywords(Keywords& keys) {
+      86           4 :   Optimizer::registerKeywords(keys);
+      87             : 
+      88           8 :   keys.add(
+      89             :     "compulsory",
+      90             :     "CAPACITY",
+      91             :     "Sampling set size."
+      92             :   );
+      93             : 
+      94           8 :   keys.add(
+      95             :     "compulsory",
+      96             :     "MUTATION_RATE",
+      97             :     "Probability of mutation."
+      98             :   );
+      99             : 
+     100           8 :   keys.add(
+     101             :     "compulsory",
+     102             :     "MATING_RATE",
+     103             :     "Probability of mating."
+     104             :   );
+     105             : 
+     106           8 :   keys.add(
+     107             :     "compulsory",
+     108             :     "CAUCHY_ALPHA",
+     109             :     "Mean of Cauchy distribution for sampling."
+     110             :   );
+     111             : 
+     112           8 :   keys.add(
+     113             :     "compulsory",
+     114             :     "CAUCHY_BETA",
+     115             :     "Spread of Cauchy distribution for sampling."
+     116             :   );
+     117             : 
+     118           8 :   keys.addFlag(
+     119             :     "LOCAL_SEARCH_ON",
+     120             :     false,
+     121             :     "Turn local search on."
+     122             :   );
+     123             : 
+     124           8 :   keys.add(
+     125             :     "optional",
+     126             :     "N_LOCAL_ITER",
+     127             :     "Number of local search iterations."
+     128             :   );
+     129             : 
+     130           8 :   keys.add(
+     131             :     "optional",
+     132             :     "LOCAL_SEARCH_RATE",
+     133             :     "Rate of mutation in local search."
+     134             :   );
+     135             : 
+     136           8 :   keys.add(
+     137             :     "optional",
+     138             :     "LOCAL_SEARCH_TYPE",
+     139             :     "Type of local search."
+     140             :   );
+     141           4 : }
+     142             : 
+     143           2 : Memetic::Memetic(const ActionOptions& ao)
+     144             :   : PLUMED_OPT_INIT(ao),
+     145           2 :     bound_(true),
+     146           2 :     score_worst_(0),
+     147           2 :     score_best_(0),
+     148           2 :     adaptation_(true),
+     149           2 :     coding_len_(3),
+     150           2 :     local_search_on_(false)
+     151             : {
+     152           2 :   log.printf("maze> Memetic sampling.\n");
+     153             : 
+     154           4 :   if (keywords.exists("CAPACITY")) {
+     155           2 :     parse("CAPACITY", capacity_);
+     156             : 
+     157           2 :     plumed_massert(
+     158             :       capacity_ > 0,
+     159             :       "maze> CAPACITY should be explicitly specified and positive.\n"
+     160             :     );
+     161             : 
+     162           2 :     log.printf(
+     163             :       "maze> CAPACITY read: %u.\n",
+     164             :       capacity_
+     165             :     );
+     166             :   }
+     167             : 
+     168           4 :   if (keywords.exists("MUTATION_RATE")) {
+     169           2 :     parse("MUTATION_RATE", mutation_rate_);
+     170             : 
+     171           2 :     plumed_massert(
+     172             :       mutation_rate_ > 0 && mutation_rate_ <= 1,
+     173             :       "maze> MUTATION_RATE should be in [0, 1).\n"
+     174             :     );
+     175             : 
+     176           2 :     log.printf(
+     177             :       "maze> MUTATION_RATE read: %f.\n",
+     178             :       mutation_rate_
+     179             :     );
+     180             :   }
+     181             : 
+     182           4 :   if (keywords.exists("MATING_RATE")) {
+     183           2 :     parse("MATING_RATE", mating_rate_);
+     184             : 
+     185           2 :     plumed_massert(
+     186             :       mating_rate_ > 0 && mating_rate_ <= 1,
+     187             :       "maze> MATING_RATE should be in [0, 1).\n"
+     188             :     );
+     189             : 
+     190           2 :     log.printf(
+     191             :       "maze> MATING_RATE read: %f.\n",
+     192             :       mating_rate_
+     193             :     );
+     194             :   }
+     195             : 
+     196           4 :   if (keywords.exists("CAUCHY_ALPHA")) {
+     197           2 :     parse("CAUCHY_ALPHA", cauchy_mean_alpha_);
+     198             : 
+     199           2 :     log.printf(
+     200             :       "maze> CAUCHY_ALPHA read: %f.\n",
+     201             :       cauchy_mean_alpha_
+     202             :     );
+     203             :   }
+     204             : 
+     205           4 :   if (keywords.exists("CAUCHY_BETA")) {
+     206           2 :     parse("CAUCHY_BETA", cauchy_mean_beta_);
+     207             : 
+     208           2 :     plumed_massert(
+     209             :       cauchy_mean_beta_ > 0,
+     210             :       "maze> CAUCHY_BETA should be explicitly specified and positive.\n"
+     211             :     );
+     212             : 
+     213           2 :     log.printf(
+     214             :       "maze> CAUCHY_BETA read: %f.\n",
+     215             :       cauchy_mean_beta_
+     216             :     );
+     217             :   }
+     218             : 
+     219           4 :   if (keywords.exists("LOCAL_SEARCH_ON")) {
+     220           2 :     parseFlag("LOCAL_SEARCH_ON", local_search_on_);
+     221             : 
+     222           2 :     log.printf("maze> LOCAL_SEARCH_ON enabled: %d.\n", local_search_on_);
+     223             :   }
+     224             : 
+     225           2 :   if (local_search_on_) {
+     226           1 :     parse("N_LOCAL_ITER", n_local_iterations_);
+     227             : 
+     228           1 :     plumed_massert(
+     229             :       n_local_iterations_ > 0,
+     230             :       "maze> N_LOCAL_ITER should be explicitly specified and positive.\n"
+     231             :     );
+     232             : 
+     233           1 :     log.printf(
+     234             :       "maze> N_LOCAL_ITER read: %u.\n",
+     235             :       n_local_iterations_
+     236             :     );
+     237             : 
+     238           1 :     parse("LOCAL_SEARCH_RATE", local_search_rate_);
+     239             : 
+     240           1 :     plumed_massert(
+     241             :       local_search_rate_ > 0 && local_search_rate_ <= 1,
+     242             :       "maze> LOCAL_SEARCH_RATE should be in [0, 1).\n"
+     243             :     );
+     244             : 
+     245           1 :     log.printf(
+     246             :       "maze> LOCAL_SEARCH_RATE read: %f.\n",
+     247             :       local_search_rate_
+     248             :     );
+     249             : 
+     250           2 :     parse("LOCAL_SEARCH_TYPE", local_search_type_);
+     251             : 
+     252           1 :     plumed_massert(
+     253             :       local_search_type_ == "stochastic_hill_climbing" ||
+     254             :       local_search_type_ == "adaptive_random_search",
+     255             :       "maze> LOCAL_SEARCH_TYPE should be: "
+     256             :       "stochastic_hill_climbing, or adaptive_random_search.\n"
+     257             :     );
+     258             : 
+     259           1 :     log.printf(
+     260             :       "maze> LOCAL_SEARCH_TYPE read: %s.\n",
+     261             :       local_search_type_.c_str()
+     262             :     );
+     263             :   }
+     264             : 
+     265           2 :   set_n_global_iterations(n_iter_);
+     266             : 
+     267           4 :   set_label("MEMETIC_SAMPLING");
+     268             : 
+     269             :   start_step_0();
+     270             : 
+     271           2 :   checkRead();
+     272           2 : }
+     273             : 
+     274           6 : void Memetic::optimize() {
+     275           6 :   Vector t = solve();
+     276             : 
+     277             :   set_opt(t);
+     278           6 :   set_opt_value(score());
+     279           6 : }
+     280             : 
+     281             : } // namespace maze
+     282             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.h.func-sort-c.html b/coverage/maze/Memetic.h.func-sort-c.html new file mode 100644 index 000000000000..ae1a6bb97114 --- /dev/null +++ b/coverage/maze/Memetic.h.func-sort-c.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-02-22 21:58:45Functions:142070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze7Memetic10score_meanEv0
_ZN4PLMD4maze7Memetic12luus_jaakolaERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic22adaptive_random_searchERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic28random_restart_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic9annealingERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZNK4PLMD4maze7Memetic12print_statusEv0
_ZN4PLMD4maze7Memetic9crossoverERNS0_6MemberES3_3
_ZN4PLMD4maze7Memetic24stochastic_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE5
_ZN4PLMD4maze7Memetic18initialize_membersEv6
_ZN4PLMD4maze7Memetic5solveEv6
_ZN4PLMD4maze7Memetic12local_searchERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic12sort_membersEv30
_ZN4PLMD4maze7Memetic13score_membersEv30
_ZN4PLMD4maze7Memetic18selection_rouletteEv30
_ZN4PLMD4maze7Memetic6matingERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic8mutationERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic13create_codingEv36
_ZN4PLMD4maze7Memetic8mutationERNS0_6MemberE54
_ZN4PLMD4maze7Memetic13out_of_boundsEd60
_ZN4PLMD4maze7Memetic12score_memberERKNS_13VectorGenericILj3EEE230
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.h.func.html b/coverage/maze/Memetic.h.func.html new file mode 100644 index 000000000000..60ecf53b23e9 --- /dev/null +++ b/coverage/maze/Memetic.h.func.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-02-22 21:58:45Functions:142070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze7Memetic10score_meanEv0
_ZN4PLMD4maze7Memetic12local_searchERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic12luus_jaakolaERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic12score_memberERKNS_13VectorGenericILj3EEE230
_ZN4PLMD4maze7Memetic12sort_membersEv30
_ZN4PLMD4maze7Memetic13create_codingEv36
_ZN4PLMD4maze7Memetic13out_of_boundsEd60
_ZN4PLMD4maze7Memetic13score_membersEv30
_ZN4PLMD4maze7Memetic18initialize_membersEv6
_ZN4PLMD4maze7Memetic18selection_rouletteEv30
_ZN4PLMD4maze7Memetic22adaptive_random_searchERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic24stochastic_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE5
_ZN4PLMD4maze7Memetic28random_restart_hill_climbingERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic5solveEv6
_ZN4PLMD4maze7Memetic6matingERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic8mutationERNS0_6MemberE54
_ZN4PLMD4maze7Memetic8mutationERSt6vectorINS0_6MemberESaIS3_EE30
_ZN4PLMD4maze7Memetic9annealingERNS0_6MemberERKSt6vectorIdSaIdEE0
_ZN4PLMD4maze7Memetic9crossoverERNS0_6MemberES3_3
_ZNK4PLMD4maze7Memetic12print_statusEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Memetic.h.gcov.html b/coverage/maze/Memetic.h.gcov.html new file mode 100644 index 000000000000..ce355051bf20 --- /dev/null +++ b/coverage/maze/Memetic.h.gcov.html @@ -0,0 +1,883 @@ + + + + + + + + LCOV - plumed test coverage - maze/Memetic.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Memetic.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12320161.2 %
Date:2024-02-22 21:58:45Functions:142070.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_maze_Memetic_h
+      23             : #define __PLUMED_maze_Memetic_h
+      24             : 
+      25             : /**
+      26             :  * @file Memetic.h
+      27             :  *
+      28             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      29             :  */
+      30             : 
+      31             : #include "core/ActionRegister.h"
+      32             : 
+      33             : #include "Core.h"
+      34             : #include "Member.h"
+      35             : #include "Optimizer.h"
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace maze {
+      39             : 
+      40             : /**
+      41             :  * @class Memetic Memetic.h "maze/Memetic.h"
+      42             :  *
+      43             :  * @brief Memetic algorithms for the optimization of the loss function.
+      44             :  */
+      45             : class Memetic: public Optimizer {
+      46             : public:
+      47             :   /**
+      48             :    * PLMD constructor.
+      49             :    *
+      50             :    * @param[in] ao PLMD::ActionOptions&.
+      51             :    */
+      52             :   explicit Memetic(const ActionOptions& ao);
+      53             : 
+      54             :   /**
+      55             :    * Registers PLMD keywords.
+      56             :    *
+      57             :    * @param[in] keys Keywords.
+      58             :    */
+      59             :   static void registerKeywords(Keywords& keys);
+      60             : 
+      61             :   /**
+      62             :    * Each class deriving from Optimizer needs to override this function.
+      63             :    */
+      64             :   void optimize() override;
+      65             : 
+      66             : private:
+      67             :   /**
+      68             :    * Create a set of translations relative to the ligand, each translation
+      69             :    * encodes a probable biasing direction.
+      70             :    */
+      71             :   void initialize_members();
+      72             : 
+      73             :   /**
+      74             :    * Score each translation by the loss function.
+      75             :    */
+      76             :   void score_members();
+      77             : 
+      78             :   /**
+      79             :    * Calculate the mean score.
+      80             :    */
+      81             :   double score_mean();
+      82             : 
+      83             :   /**
+      84             :    * Sort the population using heaps, required for finding a minimum of the loss
+      85             :    * function.
+      86             :    */
+      87             :   void sort_members();
+      88             : 
+      89             :   /**
+      90             :    * Encode a ligand conformation.
+      91             :    */
+      92             :   Vector create_coding();
+      93             : 
+      94             :   /**
+      95             :    * Check if the vector length is out of bounds.
+      96             :    *
+      97             :    * @param[in] v Vector length.
+      98             :    */
+      99             :   bool out_of_bounds(double v);
+     100             : 
+     101             :   /**
+     102             :    * Score a single member.
+     103             :    *
+     104             :    * @param[in] v Member's translation.
+     105             :    */
+     106             :   double score_member(const Vector& v);
+     107             : 
+     108             :   /**
+     109             :    * Print a status.
+     110             :    */
+     111             :   void print_status() const;
+     112             : 
+     113             :   /**
+     114             :    * Select a new population using the roulette selection.
+     115             :    */
+     116             :   void selection_roulette();
+     117             : 
+     118             :   /**
+     119             :    * Perform mating in the population.
+     120             :    *
+     121             :    * @param[in,out] members Population.
+     122             :    */
+     123             :   void mating(std::vector<Member>& members);
+     124             : 
+     125             :   /**
+     126             :    * Mate two members.
+     127             :    *
+     128             :    * @param[in,out] m1 1st member.
+     129             :    * @param[in,out] m2 2nd member.
+     130             :    */
+     131             :   void crossover(Member& m1, Member& m2);
+     132             : 
+     133             :   /**
+     134             :    * Mutate a member.
+     135             :    *
+     136             :    * @param[in,out] m Member.
+     137             :    */
+     138             :   void mutation(Member& m);
+     139             : 
+     140             :   /**
+     141             :    * Mutate the population.
+     142             :    *
+     143             :    * @param[in,out] members Population.
+     144             :    */
+     145             :   void mutation(std::vector<Member>& members);
+     146             : 
+     147             : protected:
+     148             :   /**
+     149             :    * Local searches to improve global solutions.
+     150             :    */
+     151             : 
+     152             :   /**
+     153             :    * Stochastic hill climbing.
+     154             :    *
+     155             :    * Neighbors with better or equal cost should be accepted, allowing the
+     156             :    * technique to navigate across plateaus in the response surface.
+     157             :    *
+     158             :    * @param[in,out] m Member.
+     159             :    * @param[in] params None.
+     160             :    */
+     161             :   void stochastic_hill_climbing(
+     162             :     Member& m,
+     163             :     /* none */ const std::vector<double>& params = {}
+     164             :   );
+     165             : 
+     166             :   /**
+     167             :    * Random-restart hill climbing.
+     168             :    *
+     169             :    * The algorithm can be restarted and repeated a number of  times after it
+     170             :    * converges to provide an improved result.
+     171             :    *
+     172             :    * @param[in,out] m Member.
+     173             :    * @param[in] params Number of restarts.
+     174             :    */
+     175             :   void random_restart_hill_climbing(
+     176             :     Member& m,
+     177             :     /* n_restarts */ const std::vector<double>& params = {10}
+     178             :   );
+     179             : 
+     180             :   /**
+     181             :    * Solis-Wets random walk.
+     182             :    *
+     183             :    * Adaptive random search algorithm was designed to address the limitations of
+     184             :    * the fixed step size. The strategy for adaptive random search is to
+     185             :    * continually approximate the optimal step size required to reach the global
+     186             :    * optimum in the search space. This is achieved by trialling and adopting
+     187             :    * smaller or larger step sizes only if they result in an improvement in the
+     188             :    * search performance.
+     189             :    *
+     190             :    * Very large step sizes are trialled with a much lower frequency. This
+     191             :    * strategy of preferring large moves is intended to allow the technique to
+     192             :    * escape local optima. Smaller step sizes are adopted if no improvement is
+     193             :    * made for an extended period.
+     194             :    *
+     195             :    * @param[in,out] m Member.
+     196             :    * @param[in] params
+     197             :    */
+     198             :   void adaptive_random_search(
+     199             :     Member& m,
+     200             :     /* */ const std::vector<double>& params = {1.0, 1.e-5, 2.0, 2.0, 3.0, 3.0}
+     201             :   );
+     202             : 
+     203             :   /**
+     204             :    * Luus–Jaakola heuristics.
+     205             :    *
+     206             :    * @param[in,out] m Member.
+     207             :    * @param[in] params Bounds.
+     208             :    */
+     209             :   void luus_jaakola(
+     210             :     Member& m,
+     211             :     /* bounds */ const std::vector<double>& params
+     212             :   );
+     213             : 
+     214             :   /**
+     215             :    * Local annealing.
+     216             :    *
+     217             :    * @param[in,out] m Member.
+     218             :    * @param[in] params T, alpha.
+     219             :    */
+     220             :   void annealing(
+     221             :     Member& m,
+     222             :     /* T, alpha */const std::vector<double>& params = {300.0, 0.95}
+     223             :   );
+     224             : 
+     225             :   /**
+     226             :    * Apply local search to members.
+     227             :    *
+     228             :    * @param[in,out] members Population.
+     229             :    */
+     230             :   void local_search(std::vector<Member>& members);
+     231             : 
+     232             : protected:
+     233             :   /**
+     234             :    * Return an optimal biasing direction.
+     235             :    */
+     236             :   Vector solve();
+     237             : 
+     238             : public:
+     239             :   /**
+     240             :    * Setters and getters.
+     241             :    */
+     242             : 
+     243             :   unsigned int get_capacity() const;
+     244             :   void set_capacity(unsigned int);
+     245             : 
+     246             :   unsigned int get_coding_len() const;
+     247             :   void set_coding_len(unsigned int);
+     248             : 
+     249             :   unsigned int get_n_local_iterations() const;
+     250             :   void set_n_local_iterations(unsigned int);
+     251             : 
+     252             :   unsigned int get_n_global_iterations() const;
+     253             :   void set_n_global_iterations(unsigned int);
+     254             : 
+     255             :   double get_mutation_rate() const;
+     256             :   void set_mutation_rate(double);
+     257             : 
+     258             :   double get_mating_rate() const;
+     259             :   void set_mating_rate(double);
+     260             : 
+     261             :   double get_cauchy_mean() const;
+     262             :   void set_cauchy_mean(double);
+     263             : 
+     264             :   double get_cauchy_spread() const;
+     265             :   void set_cauchy_spread(double);
+     266             : 
+     267             :   bool is_local_search_on() const;
+     268             :   void local_search_on();
+     269             :   void local_search_off();
+     270             : 
+     271             :   double get_local_search_rate() const;
+     272             :   void set_local_search_rate(double);
+     273             : 
+     274             :   std::string get_local_search_type() const;
+     275             :   void set_local_search_type(const std::string&);
+     276             : 
+     277             : protected:
+     278             :   //! Population
+     279             :   std::vector<Member> members_;
+     280             : 
+     281             :   //! Bound
+     282             :   double bound_;
+     283             : 
+     284             :   //! Scores
+     285             :   double score_worst_;
+     286             :   double score_best_;
+     287             :   Member member_best_;
+     288             : 
+     289             :   //! If a local search is performed
+     290             :   bool adaptation_;
+     291             : 
+     292             : protected:
+     293             :   //! Size of population
+     294             :   unsigned int capacity_;
+     295             :   //! Length of coding
+     296             :   unsigned int coding_len_;
+     297             : 
+     298             :   //! Number of local search iterations
+     299             :   unsigned int n_local_iterations_;
+     300             :   //! Number of global search iterations, doomsday
+     301             :   unsigned int n_global_iterations_;
+     302             : 
+     303             :   //! Probability of mutation
+     304             :   double mutation_rate_;
+     305             :   //! Probability of mating
+     306             :   double mating_rate_;
+     307             : 
+     308             :   //! Mean and spread of cauchy sampler
+     309             :   double cauchy_mean_alpha_;
+     310             :   double cauchy_mean_beta_;
+     311             : 
+     312             :   //! If local search is employed in sampling
+     313             :   bool local_search_on_;
+     314             :   //! Rate of local mutation
+     315             :   double local_search_rate_;
+     316             :   //! Type of local search, stochastic_hill_climbing or adaptive_random_search
+     317             :   std::string local_search_type_;
+     318             : };
+     319             : 
+     320           6 : void Memetic::initialize_members() {
+     321           6 :   members_.clear();
+     322           6 :   members_.resize(capacity_);
+     323             : 
+     324          42 :   for (size_t i = 0; i < capacity_; ++i) {
+     325          36 :     Member m{};
+     326             : 
+     327          36 :     m.score=0;
+     328          36 :     m.translation=create_coding();
+     329             : 
+     330          36 :     members_.at(i) = m;
+     331             :   }
+     332           6 : }
+     333             : 
+     334          30 : void Memetic::score_members() {
+     335         210 :   for (size_t i = 0; i < members_.size(); ++i) {
+     336         180 :     double s = score_member(members_[i].translation);
+     337         180 :     members_[i].score=s;
+     338             :   }
+     339          30 : }
+     340             : 
+     341          30 : void Memetic::sort_members() {
+     342          30 :   std::make_heap(
+     343             :     members_.begin(),
+     344             :     members_.end(),
+     345             :     compare
+     346             :   );
+     347             : 
+     348          30 :   std::sort_heap(
+     349             :     members_.begin(),
+     350             :     members_.end(),
+     351             :     compare
+     352             :   );
+     353             : 
+     354          30 :   member_best_ = members_[capacity_ - 1];
+     355          30 :   score_best_ = members_[capacity_ - 1].score;
+     356          30 :   score_worst_ = members_[0].score;
+     357          30 : }
+     358             : 
+     359           0 : double Memetic::score_mean() {
+     360           0 :   auto acc = [](double s, const Member& m) { return s + m.score; };
+     361             : 
+     362             :   return std::accumulate(
+     363             :            members_.begin(),
+     364             :            members_.end(),
+     365             :            0.0,
+     366           0 :            acc) / capacity_;
+     367             : }
+     368             : 
+     369          30 : void Memetic::selection_roulette() {
+     370          30 :   std::vector<Member> sel(members_);
+     371          30 :   std::vector<double> rel_scores(capacity_, 0.0);
+     372             : 
+     373         210 :   for (std::size_t i = 0; i < capacity_; ++i) {
+     374         180 :     double r = 1.0 / (members_[i].score + 0.01);
+     375         180 :     rel_scores.at(i) = r;
+     376             :   }
+     377             : 
+     378          30 :   std::vector<double> cum_sum(capacity_, 0.0);
+     379          30 :   std::partial_sum(
+     380             :     rel_scores.begin(),
+     381             :     rel_scores.end(),
+     382             :     cum_sum.begin(),
+     383             :     std::plus<double>()
+     384             :   );
+     385             : 
+     386          30 :   double sum = cum_sum.back();
+     387             :   members_.clear();
+     388          30 :   members_.resize(capacity_);
+     389             :   int chosen = -1;
+     390             : 
+     391         210 :   for (size_t j = 0; j < capacity_; ++j) {
+     392             :     double probability=rnd::next_double(sum);
+     393         708 :     for (size_t i = 0; i < cum_sum.size(); ++i) {
+     394         708 :       if (cum_sum[i] > probability) {
+     395         180 :         chosen = i;
+     396             : 
+     397         180 :         members_.at(j).score = sel.at(chosen).score;
+     398         180 :         members_.at(j).translation = sel.at(chosen).translation;
+     399             : 
+     400         180 :         break;
+     401             :       }
+     402             :     }
+     403             :   }
+     404          30 : }
+     405             : 
+     406           3 : void Memetic::crossover(Member& s1, Member& s2) {
+     407           3 :   size_t i = rnd::next_int(1, coding_len_ - 1);
+     408             : 
+     409           3 :   Member z1(s1);
+     410           3 :   Member z2(s2);
+     411             : 
+     412           9 :   for (size_t j = i; j < coding_len_; ++j) {
+     413           6 :     z1.translation[j] = s2.translation[j];
+     414           6 :     z2.translation[j] = s1.translation[j];
+     415             :   }
+     416             : 
+     417           3 :   if (!out_of_bounds(z1.translation.modulo()) && !out_of_bounds(z2.translation.modulo())) {
+     418           3 :     s1 = z1;
+     419           3 :     s2 = z2;
+     420             :   }
+     421           3 : }
+     422             : 
+     423          54 : void Memetic::mutation(Member& m) {
+     424          54 :   int which = rnd::next_int(coding_len_);
+     425          54 :   double v = rnd::next_cauchy(cauchy_mean_alpha_, cauchy_mean_beta_);
+     426          54 :   m.translation[which] += v;
+     427          54 :   if (out_of_bounds(m.translation.modulo())) {
+     428          17 :     m.translation[which] -= v;
+     429             :   }
+     430          54 : }
+     431             : 
+     432          30 : void Memetic::mutation(std::vector<Member>& m) {
+     433         210 :   for (std::vector<Member>::iterator it = m.begin(), end = m.end(); it != end; ++it) {
+     434         180 :     double r = rnd::next_double();
+     435         180 :     if (r < mutation_rate_) {
+     436           4 :       mutation(*it);
+     437             :     }
+     438             :   }
+     439          30 : }
+     440             : 
+     441           5 : void Memetic::stochastic_hill_climbing(
+     442             :   Member& m,
+     443             :   const std::vector<double>& params)
+     444             : {
+     445          55 :   for (std::size_t i = 0; i < n_local_iterations_; ++i) {
+     446          50 :     Member n;
+     447          50 :     n.translation = m.translation;
+     448          50 :     mutation(n);
+     449          50 :     double score_n = score_member(n.translation);
+     450             : 
+     451          50 :     if (m.score > score_n) {
+     452          16 :       m.translation = n.translation;
+     453             :     }
+     454             :   }
+     455           5 : }
+     456             : 
+     457           0 : void Memetic::random_restart_hill_climbing(
+     458             :   Member& m,
+     459             :   const std::vector<double>& params)
+     460             : {
+     461           0 :   unsigned int n_restarts = static_cast<int>(params[0]);
+     462           0 :   std::vector<Member> s(n_restarts);
+     463             :   unsigned int ndx = 0;
+     464           0 :   double min = m.score;
+     465             : 
+     466           0 :   for (std::size_t r = 0; r < n_restarts; ++r) {
+     467           0 :     Member n = m;
+     468           0 :     stochastic_hill_climbing(n);
+     469           0 :     s[r] = n;
+     470             : 
+     471           0 :     if (min > n.score) {
+     472             :       min = n.score;
+     473           0 :       ndx = r;
+     474             :     }
+     475             :   }
+     476             : 
+     477           0 :   m = s[ndx];
+     478           0 : }
+     479             : 
+     480           0 : void Memetic::annealing(
+     481             :   Member& m,
+     482             :   const std::vector<double>& params)
+     483             : {
+     484           0 :   double T = params[0];
+     485           0 :   double alpha = params[1];
+     486             : 
+     487           0 :   for (std::size_t i = 0; i < n_local_iterations_; ++i) {
+     488           0 :     Member n = m;
+     489           0 :     mutation(n);
+     490           0 :     double score_n = score_member(n.translation);
+     491             : 
+     492             :     double probability = std::min(
+     493           0 :                            1.0,
+     494           0 :                            std::exp(-(score_n - m.score) / T)
+     495           0 :                          );
+     496             : 
+     497           0 :     double r = rnd::next_double();
+     498             : 
+     499           0 :     if (r < probability) {
+     500           0 :       m = n;
+     501             :     }
+     502             : 
+     503           0 :     T *= alpha;
+     504             :   }
+     505           0 : }
+     506             : 
+     507           0 : void Memetic::luus_jaakola(
+     508             :   Member& m,
+     509             :   const std::vector<double>& params)
+     510             : {
+     511             :   /* TODO */
+     512           0 : }
+     513             : 
+     514           0 : void Memetic::adaptive_random_search(
+     515             :   Member& m,
+     516             :   const std::vector<double>& params)
+     517             : {
+     518           0 :   double rho_start = params[0];
+     519           0 :   double rho_lower_bound = params[1];
+     520           0 :   double ex = params[2];
+     521           0 :   double ct = params[3];
+     522           0 :   int s_ex = static_cast<int>(params[4]);
+     523           0 :   int f_ct = static_cast<int>(params[5]);
+     524             : 
+     525             :   unsigned int k = 0;
+     526           0 :   Vector xk = m.translation;
+     527             :   int ns = 0;
+     528             :   int nf = 0;
+     529           0 :   Vector bk;
+     530           0 :   bk.zero();
+     531             :   double rho_k = rho_start;
+     532             : 
+     533           0 :   while (rho_k > rho_lower_bound && k < n_local_iterations_) {
+     534           0 :     if (ns >= s_ex) {
+     535           0 :       rho_k *= ex;
+     536             :     }
+     537           0 :     else if (nf >= f_ct) {
+     538           0 :       rho_k *= ct;
+     539             :     }
+     540             : 
+     541           0 :     std::vector<double> chiv = rnd::next_double(-rho_k, rho_k, 3);
+     542           0 :     Vector chi = tls::vector2Vector(chiv);
+     543           0 :     Vector tmp;
+     544             : 
+     545           0 :     for (unsigned int i = 0; i < 3; ++i) {
+     546           0 :       tmp[i] = 2.0 * (xk[i] - chi[i]);
+     547             :     }
+     548             : 
+     549           0 :     double score_chi = score_member(chi);
+     550           0 :     double score_xk = score_member(xk);
+     551           0 :     double score_tmp = score_member(tmp);
+     552             : 
+     553           0 :     if (score_chi < score_xk) {
+     554           0 :       ns++;
+     555             :       nf = 0;
+     556             : 
+     557           0 :       for (unsigned int i = 0; i < 3; i++) {
+     558           0 :         bk[i] = 0.2 * bk[i] + 0.4 * (chi[i] - xk[i]);
+     559           0 :         xk[i] = chi[i];
+     560             :       }
+     561             :     }
+     562           0 :     else if (score_tmp < score_xk && score_xk <= score_chi) {
+     563           0 :       ns++;
+     564             :       nf = 0;
+     565             : 
+     566           0 :       for (unsigned int i = 0; i < 3; i++) {
+     567           0 :         bk[i] = bk[i] - 0.4 * (chi[i] - xk[i]);
+     568           0 :         xk[i] = 2.0 * xk[i] - chi[i];
+     569             :       }
+     570             :     }
+     571             :     else {
+     572             :       ns = 0;
+     573           0 :       nf++;
+     574             : 
+     575           0 :       for (unsigned int i = 0; i < 3; i++) {
+     576           0 :         bk[i] = 0.5 * bk[i];
+     577             :       }
+     578             :     }
+     579             : 
+     580           0 :     k++;
+     581             :   }
+     582             : 
+     583           0 :   m.translation = xk;
+     584           0 : }
+     585             : 
+     586          30 : void Memetic::local_search(std::vector<Member>& m) {
+     587          30 :   adaptation_ = true;
+     588             : 
+     589          30 :   if (local_search_on_) {
+     590         105 :     for (std::size_t i = 0; i < capacity_; ++i) {
+     591          90 :       double probability = rnd::next_double();
+     592             : 
+     593          90 :       if (probability < local_search_rate_) {
+     594           5 :         if (local_search_type_ == "stochastic_hill_climbing")
+     595          10 :           stochastic_hill_climbing(m[i]);
+     596           0 :         else if (local_search_type_ == "adaptive_random_search")
+     597           0 :           adaptive_random_search(m[i]);
+     598           0 :         else if (local_search_type_ == "random_restart_hill_climbing")
+     599           0 :           random_restart_hill_climbing(m[i]);
+     600             :       }
+     601             :     }
+     602             :   }
+     603             : 
+     604          30 :   adaptation_ = false;
+     605          30 : }
+     606             : 
+     607          30 : void Memetic::mating(std::vector<Member>& m) {
+     608             :   std::vector<Member> offspring;
+     609             : 
+     610         120 :   while (m.size() != 0) {
+     611          90 :     int j = rnd::next_int(m.size());
+     612          90 :     int i = rnd::next_int(m.size());
+     613             : 
+     614         135 :     while (i == j) {
+     615          45 :       j=rnd::next_int(m.size());
+     616             :     }
+     617             : 
+     618          90 :     Member m1 = m[i];
+     619          90 :     Member m2 = m[j];
+     620             : 
+     621          90 :     if (i > j) {
+     622             :       m.erase(m.begin() + i);
+     623             :       m.erase(m.begin() + j);
+     624             :     }
+     625          41 :     else if (j > i) {
+     626             :       m.erase(m.begin() + j);
+     627             :       m.erase(m.begin() + i);
+     628             :     }
+     629             : 
+     630          90 :     double probability = rnd::next_double();
+     631          90 :     if (probability < mating_rate_) {
+     632           3 :       crossover(m1, m2);
+     633             :     }
+     634             : 
+     635          90 :     offspring.push_back(m1);
+     636          90 :     offspring.push_back(m2);
+     637             :   }
+     638             : 
+     639          30 :   m = offspring;
+     640             :   offspring.clear();
+     641          30 : }
+     642             : 
+     643          36 : Vector Memetic::create_coding() {
+     644          36 :   double s = sampling_radius();
+     645             :   double r = rnd::next_double(s);
+     646             : 
+     647          36 :   return rnd::next_plmd_vector(r);
+     648             : }
+     649             : 
+     650          60 : bool Memetic::out_of_bounds(double v) {
+     651          60 :   double s = sampling_radius();
+     652             : 
+     653          60 :   return v > s;
+     654             : }
+     655             : 
+     656         230 : double Memetic::score_member(const Vector& coding) {
+     657             :   double action = 0;
+     658         230 :   Vector distance;
+     659         230 :   const unsigned nl_size = neighbor_list_->size();
+     660         230 :   Vector dev = coding;
+     661             : 
+     662         230 :   #pragma omp parallel num_threads(get_n_threads_openmp())
+     663             :   {
+     664             :     #pragma omp for reduction(+:action)
+     665             :     for (unsigned int i = 0; i < nl_size; i++) {
+     666             :       unsigned i0 = neighbor_list_->getClosePair(i).first;
+     667             :       unsigned i1 = neighbor_list_->getClosePair(i).second;
+     668             : 
+     669             :       if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     670             :         continue;
+     671             :       }
+     672             : 
+     673             :       if (pbc_) {
+     674             :         distance = pbcDistance(getPosition(i0) + dev, getPosition(i1));
+     675             :       }
+     676             :       else {
+     677             :         distance = delta(getPosition(i0) + dev, getPosition(i1));
+     678             :       }
+     679             : 
+     680             :       action += pairing(distance.modulo());
+     681             :     }
+     682             :   }
+     683             : 
+     684         230 :   return action;
+     685             : }
+     686             : 
+     687           0 : void Memetic::print_status() const {
+     688           0 :   log.printf("Lowest score: %f \n", score_best_);
+     689           0 : }
+     690             : 
+     691           6 : Vector Memetic::solve() {
+     692           6 :   initialize_members();
+     693             : 
+     694             :   size_t epoch = 0;
+     695          36 :   while (epoch < n_global_iterations_) {
+     696          30 :     score_members();
+     697             : 
+     698          30 :     selection_roulette();
+     699          30 :     mating(members_);
+     700          30 :     mutation(members_);
+     701          30 :     local_search(members_);
+     702             : 
+     703          30 :     sort_members();
+     704             : 
+     705          30 :     epoch++;
+     706             :   }
+     707             : 
+     708           6 :   return member_best_.translation / member_best_.translation.modulo();
+     709             : }
+     710             : 
+     711             : inline unsigned int Memetic::get_capacity() const {
+     712             :   return capacity_;
+     713             : }
+     714             : 
+     715             : inline void Memetic::set_capacity(unsigned int capacity) {
+     716             :   capacity_ = capacity;
+     717             : }
+     718             : 
+     719             : inline unsigned int Memetic::get_coding_len() const {
+     720             :   return coding_len_;
+     721             : }
+     722             : 
+     723             : inline void Memetic::set_coding_len(unsigned int coding_len) {
+     724             :   coding_len_ = coding_len;
+     725             : }
+     726             : 
+     727             : inline unsigned int Memetic::get_n_global_iterations() const {
+     728             :   return n_global_iterations_;
+     729             : }
+     730             : 
+     731             : inline void Memetic::set_n_global_iterations(unsigned int n_global_iterations) {
+     732           2 :   n_global_iterations_ = n_global_iterations;
+     733             : }
+     734             : 
+     735             : inline unsigned int Memetic::get_n_local_iterations() const {
+     736             :   return n_local_iterations_;
+     737             : }
+     738             : 
+     739             : inline void Memetic::set_n_local_iterations(unsigned int n_local_iterations) {
+     740             :   n_local_iterations_ = n_local_iterations;
+     741             : }
+     742             : 
+     743             : inline double Memetic::get_mating_rate() const {
+     744             :   return mating_rate_;
+     745             : }
+     746             : 
+     747             : inline void Memetic::set_mating_rate(double mating_rate) {
+     748             :   mating_rate_ = mating_rate;
+     749             : }
+     750             : 
+     751             : inline double Memetic::get_mutation_rate() const {
+     752             :   return mutation_rate_;
+     753             : }
+     754             : 
+     755             : inline void Memetic::set_mutation_rate(double mutation_rate) {
+     756             :   mutation_rate_ = mutation_rate;
+     757             : }
+     758             : 
+     759             : inline double Memetic::get_cauchy_mean() const {
+     760             :   return cauchy_mean_alpha_;
+     761             : }
+     762             : 
+     763             : inline void Memetic::set_cauchy_mean(double cauchy_mean_alpha) {
+     764             :   cauchy_mean_alpha_ = cauchy_mean_alpha;
+     765             : }
+     766             : 
+     767             : inline double Memetic::get_cauchy_spread() const {
+     768             :   return cauchy_mean_beta_;
+     769             : }
+     770             : 
+     771             : inline void Memetic::set_cauchy_spread(double cauchy_mean_beta) {
+     772             :   cauchy_mean_beta_ = cauchy_mean_beta;
+     773             : }
+     774             : 
+     775             : inline bool Memetic::is_local_search_on() const {
+     776             :   return local_search_on_;
+     777             : }
+     778             : 
+     779             : inline void Memetic::local_search_on() {
+     780             :   local_search_on_ = true;
+     781             : }
+     782             : 
+     783             : inline void Memetic::local_search_off() {
+     784             :   local_search_on_ = false;
+     785             : }
+     786             : 
+     787             : inline double Memetic::get_local_search_rate() const {
+     788             :   return local_search_rate_;
+     789             : }
+     790             : 
+     791             : inline void Memetic::set_local_search_rate(double local_search_rate) {
+     792             :   local_search_rate_ = local_search_rate;
+     793             : }
+     794             : 
+     795             : inline std::string Memetic::get_local_search_type() const {
+     796             :   return local_search_type_;
+     797             : }
+     798             : 
+     799             : inline void Memetic::set_local_search_type(const std::string& local_search_type) {
+     800             :   local_search_type_ = local_search_type;
+     801             : }
+     802             : 
+     803             : } // namespace maze
+     804             : } // namespace PLMD
+     805             : 
+     806             : #endif // __PLUMED_maze_Memetic_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer.cpp.func-sort-c.html b/coverage/maze/Optimizer.cpp.func-sort-c.html new file mode 100644 index 000000000000..0ad6c03cf391 --- /dev/null +++ b/coverage/maze/Optimizer.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16218090.0 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9OptimizerC1ERKNS_13ActionOptionsE0
_ZNK4PLMD4maze9Optimizer14center_of_massEv6
_ZN4PLMD4maze9OptimizerC2ERKNS_13ActionOptionsE7
_ZN4PLMD4maze9Optimizer16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD4maze9Optimizer7prepareEv210
_ZN4PLMD4maze9Optimizer9calculateEv210
_ZN4PLMD4maze9Optimizer9update_nlEv210
_ZN4PLMD4maze9Optimizer5scoreEv226
_ZN4PLMD4maze9Optimizer15sampling_radiusEv309
_ZNK4PLMD4maze9Optimizer7pairingEd14342730
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer.cpp.func.html b/coverage/maze/Optimizer.cpp.func.html new file mode 100644 index 000000000000..f1062a92f638 --- /dev/null +++ b/coverage/maze/Optimizer.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16218090.0 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9Optimizer15sampling_radiusEv309
_ZN4PLMD4maze9Optimizer16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD4maze9Optimizer5scoreEv226
_ZN4PLMD4maze9Optimizer7prepareEv210
_ZN4PLMD4maze9Optimizer9calculateEv210
_ZN4PLMD4maze9Optimizer9update_nlEv210
_ZN4PLMD4maze9OptimizerC1ERKNS_13ActionOptionsE0
_ZN4PLMD4maze9OptimizerC2ERKNS_13ActionOptionsE7
_ZNK4PLMD4maze9Optimizer14center_of_massEv6
_ZNK4PLMD4maze9Optimizer7pairingEd14342730
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer.cpp.gcov.html b/coverage/maze/Optimizer.cpp.gcov.html new file mode 100644 index 000000000000..f3513cdaa0a7 --- /dev/null +++ b/coverage/maze/Optimizer.cpp.gcov.html @@ -0,0 +1,587 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16218090.0 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Optimizer.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "Optimizer.h"
+      30             : #include "core/PlumedMain.h"
+      31             : #include "tools/Tools.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace maze {
+      35             : 
+      36          17 : void Optimizer::registerKeywords(Keywords& keys) {
+      37          17 :   Colvar::registerKeywords(keys);
+      38             : 
+      39          34 :   keys.addFlag(
+      40             :     "SERIAL",
+      41             :     false,
+      42             :     "Perform the simulation in serial -- used only for debugging purposes, "
+      43             :     "should not be used otherwise."
+      44             :   );
+      45             : 
+      46          34 :   keys.addFlag(
+      47             :     "PAIR",
+      48             :     false,
+      49             :     "Pair only the 1st element of the 1st group with the 1st element in the "
+      50             :     "second, etc."
+      51             :   );
+      52             : 
+      53          34 :   keys.addFlag(
+      54             :     "NLIST",
+      55             :     false,
+      56             :     "Use a neighbor list of ligand-protein atom pairs to speed up the "
+      57             :     "calculating of the distances."
+      58             :   );
+      59             : 
+      60          34 :   keys.add(
+      61             :     "optional",
+      62             :     "NL_CUTOFF",
+      63             :     "Neighbor list cut-off for the distances of ligand-protein atom pairs."
+      64             :   );
+      65             : 
+      66          34 :   keys.add(
+      67             :     "optional",
+      68             :     "NL_STRIDE",
+      69             :     "Update stride for the ligand-protein atom pairs in the neighbor list."
+      70             :   );
+      71             : 
+      72          34 :   keys.add(
+      73             :     "compulsory",
+      74             :     "N_ITER",
+      75             :     "Number of optimization steps. Required only for optimizers, do not pass "
+      76             :     "this keyword to the fake optimizers (results in crash) , e.g., random "
+      77             :     "walk, steered MD, or random acceleration MD."
+      78             :   );
+      79             : 
+      80          34 :   keys.add(
+      81             :     "optional",
+      82             :     "LOSS",
+      83             :     "Loss function describing ligand-protein interactions required by every "
+      84             :     "optimizer."
+      85             :   );
+      86             : 
+      87          34 :   keys.add(
+      88             :     "atoms",
+      89             :     "LIGAND",
+      90             :     "Indices of ligand atoms."
+      91             :   );
+      92             : 
+      93          34 :   keys.add(
+      94             :     "atoms",
+      95             :     "PROTEIN",
+      96             :     "Indices of protein atoms."
+      97             :   );
+      98             : 
+      99          34 :   keys.add(
+     100             :     "compulsory",
+     101             :     "OPTIMIZER_STRIDE",
+     102             :     "Optimizer stride. Sets up a callback function that launches the "
+     103             :     "optimization process every OPTIMIZER_STRIDE."
+     104             :   );
+     105             : 
+     106          17 :   componentsAreNotOptional(keys);
+     107             : 
+     108          34 :   keys.addOutputComponent(
+     109             :     "x",
+     110             :     "default",
+     111             :     "Optimal biasing direction; x component."
+     112             :   );
+     113             : 
+     114          34 :   keys.addOutputComponent(
+     115             :     "y",
+     116             :     "default",
+     117             :     "Optimal biasing direction; y component."
+     118             :   );
+     119             : 
+     120          34 :   keys.addOutputComponent(
+     121             :     "z",
+     122             :     "default",
+     123             :     "Optimal biasing direction; z component."
+     124             :   );
+     125             : 
+     126          34 :   keys.addOutputComponent(
+     127             :     "loss",
+     128             :     "default",
+     129             :     "Loss function value defined by the provided pairing function."
+     130             :   );
+     131             : 
+     132          34 :   keys.addOutputComponent(
+     133             :     "sr",
+     134             :     "default",
+     135             :     "Sampling radius. Reduces sampling to the local proximity of the ligand "
+     136             :     "position."
+     137             :   );
+     138          17 : }
+     139             : 
+     140           7 : Optimizer::Optimizer(const ActionOptions& ao)
+     141             :   : PLUMED_COLVAR_INIT(ao),
+     142           7 :     first_step_(true),
+     143           7 :     opt_value_(0.0),
+     144           7 :     pbc_(true),
+     145           7 :     sampling_r_(0.0),
+     146           7 :     serial_(false),
+     147           7 :     validate_list_(true),
+     148           7 :     first_time_(true)
+     149             : {
+     150           7 :   parseFlag("SERIAL", serial_);
+     151             : 
+     152          14 :   if (keywords.exists("LOSS")) {
+     153           7 :     std::vector<std::string> loss_labels(0);
+     154          14 :     parseVector("LOSS", loss_labels);
+     155             : 
+     156           7 :     plumed_massert(
+     157             :       loss_labels.size() > 0,
+     158             :       "maze> Something went wrong with the LOSS keyword.\n"
+     159             :     );
+     160             : 
+     161           7 :     std::string error_msg = "";
+     162           7 :     vec_loss_ = tls::get_pointers_labels<Loss*>(
+     163             :                   loss_labels,
+     164           7 :                   plumed.getActionSet(),
+     165             :                   error_msg
+     166             :                 );
+     167             : 
+     168           7 :     if (error_msg.size() > 0) {
+     169           0 :       plumed_merror(
+     170             :         "maze> Error in the LOSS keyword " + getName() + ": " + error_msg
+     171             :       );
+     172             :     }
+     173             : 
+     174           7 :     loss_ = vec_loss_[0];
+     175           7 :     log.printf("maze> Loss function linked to the optimizer.\n");
+     176           7 :   }
+     177             : 
+     178          14 :   if (keywords.exists("N_ITER")) {
+     179           3 :     parse("N_ITER", n_iter_);
+     180             : 
+     181           3 :     plumed_massert(
+     182             :       n_iter_ > 0,
+     183             :       "maze> N_ITER should be explicitly specified and positive.\n"
+     184             :     );
+     185             : 
+     186           3 :     log.printf(
+     187             :       "maze> Optimizer will run %u iterations once launched.\n",
+     188             :       n_iter_
+     189             :     );
+     190             :   }
+     191             : 
+     192             :   std::vector<AtomNumber> ga_list, gb_list;
+     193           7 :   parseAtomList("LIGAND", ga_list);
+     194           7 :   parseAtomList("PROTEIN", gb_list);
+     195             : 
+     196           7 :   bool nopbc = !pbc_;
+     197           7 :   parseFlag("NOPBC", nopbc);
+     198             : 
+     199           7 :   bool do_pair = false;
+     200           7 :   parseFlag("PAIR", do_pair);
+     201             : 
+     202           7 :   nl_stride_ = 0;
+     203           7 :   bool do_neigh = false;
+     204           7 :   parseFlag("NLIST", do_neigh);
+     205             : 
+     206           7 :   if (do_neigh) {
+     207          14 :     if (keywords.exists("NL_CUTOFF")) {
+     208           7 :       parse("NL_CUTOFF", nl_cutoff_);
+     209             : 
+     210           7 :       plumed_massert(
+     211             :         nl_cutoff_ > 0,
+     212             :         "maze> NL_CUTOFF should be explicitly specified and positive.\n"
+     213             :       );
+     214             :     }
+     215             : 
+     216          14 :     if (keywords.exists("NL_STRIDE")) {
+     217           7 :       parse("NL_STRIDE", nl_stride_);
+     218             : 
+     219           7 :       plumed_massert(
+     220             :         nl_stride_ > 0,
+     221             :         "maze> NL_STRIDE should be explicitly specified and positive.\n"
+     222             :       );
+     223             :     }
+     224             :   }
+     225             : 
+     226           7 :   if (gb_list.size() > 0) {
+     227           7 :     if (do_neigh) {
+     228           7 :       neighbor_list_ = Tools::make_unique<NeighborList>(
+     229             :                          ga_list,
+     230             :                          gb_list,
+     231             :                          serial_,
+     232             :                          do_pair,
+     233           7 :                          pbc_,
+     234             :                          getPbc(),
+     235             :                          comm,
+     236           7 :                          nl_cutoff_,
+     237           7 :                          nl_stride_
+     238             :                        );
+     239             :     }
+     240             :     else {
+     241           0 :       neighbor_list_=Tools::make_unique<NeighborList>(
+     242             :                        ga_list,
+     243             :                        gb_list,
+     244             :                        serial_,
+     245             :                        do_pair,
+     246           0 :                        pbc_,
+     247             :                        getPbc(),
+     248             :                        comm
+     249             :                      );
+     250             :     }
+     251             :   }
+     252             :   else {
+     253           0 :     if (do_neigh) {
+     254           0 :       neighbor_list_ = Tools::make_unique<NeighborList>(
+     255             :                          ga_list,
+     256             :                          serial_,
+     257           0 :                          pbc_,
+     258             :                          getPbc(),
+     259             :                          comm,
+     260           0 :                          nl_cutoff_,
+     261           0 :                          nl_stride_
+     262             :                        );
+     263             :     }
+     264             :     else {
+     265           0 :       neighbor_list_=Tools::make_unique<NeighborList>(
+     266             :                        ga_list,
+     267             :                        serial_,
+     268           0 :                        pbc_,
+     269             :                        getPbc(),
+     270             :                        comm
+     271             :                      );
+     272             :     }
+     273             :   }
+     274             : 
+     275           7 :   requestAtoms(neighbor_list_->getFullAtomList());
+     276             : 
+     277           7 :   log.printf(
+     278             :     "maze> Loss will be calculated between two groups of %u and %u atoms.\n",
+     279             :     static_cast<unsigned>(ga_list.size()),
+     280             :     static_cast<unsigned>(gb_list.size())
+     281             :   );
+     282             : 
+     283           7 :   log.printf(
+     284             :     "maze> First group (LIGAND): from %d to %d.\n",
+     285             :     ga_list[0].serial(),
+     286             :     ga_list[ga_list.size()-1].serial()
+     287             :   );
+     288             : 
+     289           7 :   if (gb_list.size() > 0) {
+     290           7 :     log.printf(
+     291             :       "maze> Second group (PROTEIN): from %d to %d.\n",
+     292             :       gb_list[0].serial(),
+     293             :       gb_list[gb_list.size()-1].serial()
+     294             :     );
+     295             :   }
+     296             : 
+     297           7 :   if (pbc_) {
+     298           7 :     log.printf("maze> Using periodic boundary conditions.\n");
+     299             :   }
+     300             :   else {
+     301           0 :     log.printf("maze> Without periodic boundary conditions.\n");
+     302             :   }
+     303             : 
+     304           7 :   if (do_pair) {
+     305           0 :     log.printf("maze> With PAIR option.\n");
+     306             :   }
+     307             : 
+     308           7 :   if (do_neigh) {
+     309           7 :     log.printf(
+     310             :       "maze> Using neighbor lists updated every %d steps and cutoff %f.\n",
+     311             :       nl_stride_,
+     312             :       nl_cutoff_
+     313             :     );
+     314             :   }
+     315             : 
+     316             :   // OpenMP
+     317           7 :   stride_ = comm.Get_size();
+     318           7 :   rank_ = comm.Get_rank();
+     319             : 
+     320           7 :   n_threads_ = OpenMP::getNumThreads();
+     321           7 :   unsigned int nn = neighbor_list_->size();
+     322             : 
+     323           7 :   if (n_threads_ * stride_ * 10 > nn) {
+     324           0 :     n_threads_ = nn / stride_ / 10;
+     325             :   }
+     326             : 
+     327           7 :   if (n_threads_ == 0) {
+     328           0 :     n_threads_ = 1;
+     329             :   }
+     330             : 
+     331          14 :   if (keywords.exists("OPTIMIZER_STRIDE")) {
+     332           7 :     parse("OPTIMIZER_STRIDE", optimizer_stride_);
+     333             : 
+     334           7 :     plumed_massert(
+     335             :       optimizer_stride_,
+     336             :       "maze> OPTIMIZER_STRIDE should be explicitly specified and positive.\n"
+     337             :     );
+     338             : 
+     339           7 :     log.printf(
+     340             :       "maze> Launching optimization every %u steps.\n",
+     341             :       optimizer_stride_
+     342             :     );
+     343             :   }
+     344             : 
+     345           7 :   rnd::randomize();
+     346             : 
+     347           7 :   opt_.zero();
+     348             : 
+     349          14 :   addComponentWithDerivatives("x");
+     350          14 :   componentIsNotPeriodic("x");
+     351             : 
+     352          14 :   addComponentWithDerivatives("y");
+     353          14 :   componentIsNotPeriodic("y");
+     354             : 
+     355          14 :   addComponentWithDerivatives("z");
+     356          14 :   componentIsNotPeriodic("z");
+     357             : 
+     358          14 :   addComponent("loss");
+     359          14 :   componentIsNotPeriodic("loss");
+     360             : 
+     361          14 :   addComponent("sr");
+     362           7 :   componentIsNotPeriodic("sr");
+     363             : 
+     364           7 :   value_x_ = getPntrToComponent("x");
+     365           7 :   value_y_ = getPntrToComponent("y");
+     366           7 :   value_z_ = getPntrToComponent("z");
+     367           7 :   value_action_ = getPntrToComponent("loss");
+     368           7 :   value_sampling_radius_ = getPntrToComponent("sr");
+     369           7 : }
+     370             : 
+     371    14342730 : double Optimizer::pairing(double distance) const {
+     372    14342730 :   return loss_->pairing(distance);
+     373             : }
+     374             : 
+     375           6 : Vector Optimizer::center_of_mass() const {
+     376           6 :   const unsigned nl_size = neighbor_list_->size();
+     377             : 
+     378           6 :   Vector center_of_mass;
+     379           6 :   center_of_mass.zero();
+     380             :   double mass = 0;
+     381             : 
+     382      189654 :   for (unsigned int i = 0; i < nl_size; ++i) {
+     383      189648 :     unsigned int i0 = neighbor_list_->getClosePair(i).first;
+     384      189648 :     center_of_mass += getPosition(i0) * getMass(i0);
+     385      189648 :     mass += getMass(i0);
+     386             :   }
+     387             : 
+     388           6 :   return center_of_mass / mass;
+     389             : }
+     390             : 
+     391         210 : void Optimizer::prepare() {
+     392         210 :   if (neighbor_list_->getStride() > 0) {
+     393         210 :     if (first_time_ || (getStep() % neighbor_list_->getStride() == 0)) {
+     394           7 :       requestAtoms(neighbor_list_->getFullAtomList());
+     395             : 
+     396           7 :       validate_list_ = true;
+     397           7 :       first_time_ = false;
+     398             :     }
+     399             :     else {
+     400         203 :       requestAtoms(neighbor_list_->getReducedAtomList());
+     401             : 
+     402         203 :       validate_list_ = false;
+     403             : 
+     404         203 :       if (getExchangeStep()) {
+     405           0 :         plumed_merror(
+     406             :           "maze> Neighbor lists should be updated on exchange steps -- choose "
+     407             :           "an NL_STRIDE which divides the exchange stride.\n");
+     408             :       }
+     409             :     }
+     410             : 
+     411         210 :     if (getExchangeStep()) {
+     412           0 :       first_time_ = true;
+     413             :     }
+     414             :   }
+     415         210 : }
+     416             : 
+     417         226 : double Optimizer::score() {
+     418         226 :   const unsigned nl_size = neighbor_list_->size();
+     419         226 :   Vector distance;
+     420             :   double function = 0;
+     421             : 
+     422         226 :   #pragma omp parallel num_threads(n_threads_)
+     423             :   {
+     424             :     #pragma omp for reduction(+:function)
+     425             :     for(unsigned int i = 0; i < nl_size; i++) {
+     426             :       unsigned i0 = neighbor_list_->getClosePair(i).first;
+     427             :       unsigned i1 = neighbor_list_->getClosePair(i).second;
+     428             : 
+     429             :       if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     430             :         continue;
+     431             :       }
+     432             : 
+     433             :       if (pbc_) {
+     434             :         distance = pbcDistance(getPosition(i0), getPosition(i1));
+     435             :       }
+     436             :       else {
+     437             :         distance = delta(getPosition(i0), getPosition(i1));
+     438             :       }
+     439             : 
+     440             :       function += pairing(distance.modulo());
+     441             :     }
+     442             :   }
+     443             : 
+     444         226 :   return function;
+     445             : }
+     446             : 
+     447         210 : void Optimizer::update_nl() {
+     448         210 :   if (neighbor_list_->getStride() > 0 && validate_list_) {
+     449           7 :     neighbor_list_->update(getPositions());
+     450             :   }
+     451         210 : }
+     452             : 
+     453         309 : double Optimizer::sampling_radius()
+     454             : {
+     455         309 :   const unsigned nl_size=neighbor_list_->size();
+     456         309 :   Vector d;
+     457             :   double min=std::numeric_limits<int>::max();
+     458             : 
+     459     7979001 :   for (unsigned int i = 0; i < nl_size; ++i) {
+     460     7978692 :     unsigned i0 = neighbor_list_->getClosePair(i).first;
+     461     7978692 :     unsigned i1 = neighbor_list_->getClosePair(i).second;
+     462             : 
+     463     7978692 :     if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     464           0 :       continue;
+     465             :     }
+     466             : 
+     467     7978692 :     if (pbc_) {
+     468     7978692 :       d = pbcDistance(getPosition(i0), getPosition(i1));
+     469             :     }
+     470             :     else {
+     471           0 :       d = delta(getPosition(i0), getPosition(i1));
+     472             :     }
+     473             : 
+     474     7978692 :     double dist = d.modulo();
+     475             : 
+     476     7978692 :     if(dist < min) {
+     477             :       min = dist;
+     478             :     }
+     479             :   }
+     480             : 
+     481         309 :   return min;
+     482             : }
+     483             : 
+     484         210 : void Optimizer::calculate() {
+     485         210 :   update_nl();
+     486             : 
+     487         210 :   if (getStep() % optimizer_stride_ == 0 && !first_step_) {
+     488          19 :     optimize();
+     489             : 
+     490          19 :     value_x_->set(opt_[0]);
+     491          19 :     value_y_->set(opt_[1]);
+     492          19 :     value_z_->set(opt_[2]);
+     493             : 
+     494          19 :     value_action_->set(score());
+     495          19 :     value_sampling_radius_->set(sampling_radius());
+     496             :   }
+     497             :   else {
+     498         191 :     first_step_=false;
+     499             : 
+     500         191 :     value_x_->set(opt_[0]);
+     501         191 :     value_y_->set(opt_[1]);
+     502         191 :     value_z_->set(opt_[2]);
+     503             : 
+     504         191 :     value_action_->set(score());
+     505         191 :     value_sampling_radius_->set(sampling_radius());
+     506             :   }
+     507         210 : }
+     508             : 
+     509             : } // namespace maze
+     510             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer.h.func-sort-c.html b/coverage/maze/Optimizer.h.func-sort-c.html new file mode 100644 index 000000000000..db3fc0099c7b --- /dev/null +++ b/coverage/maze/Optimizer.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9OptimizerD2Ev7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer.h.func.html b/coverage/maze/Optimizer.h.func.html new file mode 100644 index 000000000000..34c278375d1c --- /dev/null +++ b/coverage/maze/Optimizer.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze9OptimizerD2Ev7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer.h.gcov.html b/coverage/maze/Optimizer.h.gcov.html new file mode 100644 index 000000000000..dbfe7272eaee --- /dev/null +++ b/coverage/maze/Optimizer.h.gcov.html @@ -0,0 +1,434 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1313100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_maze_Optimizer_h
+      23             : #define __PLUMED_maze_Optimizer_h
+      24             : 
+      25             : /**
+      26             :  * @file Optimizer.h
+      27             :  *
+      28             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      29             :  */
+      30             : 
+      31             : #include "colvar/Colvar.h"
+      32             : #include "tools/Communicator.h"
+      33             : #include "tools/OpenMP.h"
+      34             : #include "tools/NeighborList.h"
+      35             : #include "tools/Vector.h"
+      36             : 
+      37             : #include "Core.h"
+      38             : #include "Loss.h"
+      39             : 
+      40             : #include <memory>
+      41             : 
+      42             : #define PLUMED_OPT_INIT(ao) Action(ao), Optimizer(ao)
+      43             : 
+      44             : namespace PLMD {
+      45             : namespace maze {
+      46             : 
+      47             : /**
+      48             :  * @ingroup INHERIT
+      49             :  *
+      50             :  * @class Optimizer Optimizer.h "maze/Optimizer.h"
+      51             :  *
+      52             :  * @brief Base class for implementing optimizers for ligand unbinding.
+      53             :  *
+      54             :  * An optimizer is defined as a colvar that can be passed to Optimizer_Bias.
+      55             :  */
+      56             : class Optimizer: public colvar::Colvar {
+      57             : public:
+      58             :   /**
+      59             :    * PLMD constructor.
+      60             :    *
+      61             :    * @param[in] ao PLMD::ActionOptions&
+      62             :    */
+      63             :   explicit Optimizer(const ActionOptions&);
+      64             : 
+      65             :   /**
+      66             :    * Destructor.
+      67             :    */
+      68           7 :   ~Optimizer() { /* Nothing to do. */ }
+      69             : 
+      70             :   /**
+      71             :    * Registers PLMD keywords.
+      72             :    *
+      73             :    * @param[in] keys PLMD keywords
+      74             :    */
+      75             :   static void registerKeywords(Keywords& keys);
+      76             : 
+      77             :   /**
+      78             :    * The pairing function needs to be overridden by a specific optimizer.
+      79             :    *
+      80             :    * @param[in] distance distance between a pair of atoms
+      81             :    */
+      82             :   virtual double pairing(double distance) const;
+      83             : 
+      84             :   /**
+      85             :    * Optimal values needed for biasing are computed by methods overridding the
+      86             :    * optimize function.
+      87             :    */
+      88             :   virtual void optimize() = 0;
+      89             : 
+      90             :   /**
+      91             :    * Calculate the optimal direction of pulling.
+      92             :    */
+      93             :   void calculate();
+      94             : 
+      95             :   /**
+      96             :    * Prepare the neighbor list.
+      97             :    */
+      98             :   void prepare();
+      99             : 
+     100             :   /**
+     101             :    * Score a ligand-protein configuration.
+     102             :    *
+     103             :    * @return score
+     104             :    */
+     105             :   double score();
+     106             : 
+     107             :   /**
+     108             :    * Calculate sampling radius as the minimal distance between two groups in
+     109             :    * neighbors list.
+     110             :    *
+     111             :    * @return minimal distance of ligand-protein atom pairs
+     112             :    */
+     113             :   double sampling_radius();
+     114             : 
+     115             :   /**
+     116             :    * Load new positions of atoms in the neighbor list.
+     117             :    */
+     118             :   void update_nl();
+     119             : 
+     120             :   /**
+     121             :    * Calculate the center of mass.
+     122             :    *
+     123             :    * @return center of mass
+     124             :    */
+     125             :   Vector center_of_mass() const;
+     126             : 
+     127             : public:
+     128             :   /**
+     129             :    * Getters and setters.
+     130             :    */
+     131             : 
+     132             :   std::string get_label() const;
+     133             :   void set_label(const std::string&);
+     134             : 
+     135             :   // Start optimizer at time = 0.
+     136             :   void start_step_0();
+     137             : 
+     138             :   // Start optimizer at time = optimizer stride.
+     139             :   void start_step_stride();
+     140             : 
+     141             :   Vector get_opt() const;
+     142             :   void set_opt(Vector);
+     143             : 
+     144             :   double get_opt_value() const;
+     145             :   void set_opt_value(double);
+     146             : 
+     147             :   unsigned int get_optimizer_stride() const;
+     148             :   void set_optimizer_stride(unsigned int);
+     149             : 
+     150             :   bool is_pbc_on() const;
+     151             :   void pbc_on();
+     152             :   void pbc_off();
+     153             : 
+     154             :   unsigned int get_n_iterations() const;
+     155             :   void set_n_iterations(unsigned int);
+     156             : 
+     157             :   double get_sampling_radius() const;
+     158             :   void set_sampling_radius(double);
+     159             : 
+     160             :   unsigned int get_rank_openmp() const;
+     161             :   void set_rank_openmp(unsigned int);
+     162             : 
+     163             :   unsigned int get_stride_openmp() const;
+     164             :   void set_stride_openmp(unsigned int);
+     165             : 
+     166             :   unsigned int get_n_threads_openmp() const;
+     167             :   void set_n_threads_openmp(unsigned int);
+     168             : 
+     169             :   unsigned int get_nl_stride() const;
+     170             :   void set_nl_stride(unsigned int);
+     171             : 
+     172             :   double get_nl_cutofff() const;
+     173             :   void set_nl_cutoff(double);
+     174             : 
+     175             : protected:
+     176             :   //! Optimizer label.
+     177             :   std::string label_;
+     178             : 
+     179             :   //! Start either at time =  0 or time = optimizer stride.
+     180             :   bool first_step_;
+     181             : 
+     182             :   //! Biasing direction.
+     183             :   Vector opt_;
+     184             : 
+     185             :   //! Current loss function value.
+     186             :   double opt_value_;
+     187             : 
+     188             :   //! Optimizer stride.
+     189             :   unsigned int optimizer_stride_;
+     190             : 
+     191             :   //! Periodic boundary conditions.
+     192             :   bool pbc_;
+     193             : 
+     194             :   //! Number of global iterations.
+     195             :   unsigned int n_iter_;
+     196             : 
+     197             :   //! Sampling radius.
+     198             :   double sampling_r_;
+     199             : 
+     200             :   /**
+     201             :    * OpenMP
+     202             :    */
+     203             :   unsigned int rank_;
+     204             :   unsigned int stride_;
+     205             :   unsigned int n_threads_;
+     206             : 
+     207             :   //! Neighbor list of ligand-protein atom pairs.
+     208             :   std::unique_ptr<NeighborList> neighbor_list_;
+     209             : 
+     210             :   //! Neighbor list cut-off.
+     211             :   double nl_cutoff_;
+     212             : 
+     213             :   //! Neighbor list stride.
+     214             :   int nl_stride_;
+     215             : 
+     216             : private:
+     217             :   bool serial_;
+     218             :   bool validate_list_;
+     219             :   bool first_time_;
+     220             : 
+     221             :   //! Pointer to the loss function.
+     222             :   Loss* loss_;
+     223             :   std::vector<Loss*> vec_loss_;
+     224             : 
+     225             : public:
+     226             :   /*
+     227             :    * Pointers to PLMD components.
+     228             :    */
+     229             : 
+     230             :   //! Biased cv.
+     231             :   Value* value_x_;
+     232             :   Value* value_y_;
+     233             :   Value* value_z_;
+     234             : 
+     235             :   //! Loss value.
+     236             :   Value* value_action_;
+     237             :   //! Sampling radiues value.
+     238             :   Value* value_sampling_radius_;
+     239             : };
+     240             : 
+     241             : /*
+     242             :  * Getters and setters.
+     243             :  */
+     244             : 
+     245             : inline void Optimizer::set_nl_cutoff(double nl_cutoff) {
+     246             :   nl_cutoff_=nl_cutoff;
+     247             : }
+     248             : 
+     249             : inline double Optimizer::get_nl_cutofff() const {
+     250             :   return nl_cutoff_;
+     251             : }
+     252             : 
+     253             : inline void Optimizer::set_nl_stride(unsigned int nl_stride) {
+     254             :   nl_stride_=nl_stride;
+     255             : }
+     256             : 
+     257             : inline unsigned int Optimizer::get_nl_stride() const {
+     258             :   return nl_stride_;
+     259             : }
+     260             : 
+     261             : inline void Optimizer::set_n_threads_openmp(unsigned int n_threads) {
+     262             :   n_threads_=n_threads;
+     263             : }
+     264             : 
+     265             : inline unsigned int Optimizer::get_n_threads_openmp() const {
+     266         260 :   return n_threads_;
+     267             : }
+     268             : 
+     269             : inline void Optimizer::set_stride_openmp(unsigned int stride) {
+     270             :   stride_=stride;
+     271             : }
+     272             : 
+     273             : inline unsigned int Optimizer::get_stride_openmp() const {
+     274             :   return stride_;
+     275             : }
+     276             : 
+     277             : inline void Optimizer::set_rank_openmp(unsigned int rank) {
+     278             :   rank_=rank;
+     279             : }
+     280             : 
+     281             : inline unsigned int Optimizer::get_rank_openmp() const {
+     282             :   return rank_;
+     283             : }
+     284             : 
+     285             : inline void Optimizer::set_sampling_radius(double sampling_r) {
+     286             :   sampling_r_=sampling_r;
+     287             : }
+     288             : 
+     289             : inline double Optimizer::get_sampling_radius() const {
+     290             :   return sampling_r_;
+     291             : }
+     292             : 
+     293             : inline void Optimizer::set_n_iterations(unsigned int n_iter) {
+     294             :   n_iter_=n_iter;
+     295             : }
+     296             : 
+     297             : inline unsigned int Optimizer::get_n_iterations() const {
+     298          33 :   return n_iter_;
+     299             : }
+     300             : 
+     301             : inline void Optimizer::pbc_off() {
+     302             :   pbc_=false;
+     303             : }
+     304             : 
+     305             : inline void Optimizer::pbc_on() {
+     306             :   pbc_=true;
+     307             : }
+     308             : 
+     309             : inline bool Optimizer::is_pbc_on() const {
+     310             :   return pbc_==true;
+     311             : }
+     312             : 
+     313             : inline void Optimizer::set_optimizer_stride(unsigned int optimizer_stride) {
+     314             :   optimizer_stride_=optimizer_stride;
+     315             : }
+     316             : 
+     317             : inline unsigned int Optimizer::get_optimizer_stride() const {
+     318           1 :   return optimizer_stride_;
+     319             : }
+     320             : 
+     321             : inline void Optimizer::set_opt_value(double opt_value) {
+     322          46 :   opt_value_=opt_value;
+     323          30 : }
+     324             : 
+     325             : inline double Optimizer::get_opt_value() const {
+     326             :   return opt_value_;
+     327             : }
+     328             : 
+     329             : // cppcheck-suppress passedByValue
+     330             : inline void Optimizer::set_opt(Vector opt) {
+     331          44 :   opt_=opt;
+     332             : }
+     333             : 
+     334             : inline Vector Optimizer::get_opt() const {
+     335           3 :   return opt_;
+     336             : }
+     337             : 
+     338             : inline void Optimizer::set_label(const std::string& label) {
+     339           7 :   label_=label;
+     340           7 : }
+     341             : 
+     342             : inline std::string Optimizer::get_label() const {
+     343           1 :   return label_;
+     344             : }
+     345             : 
+     346             : inline void Optimizer::start_step_0() {
+     347           5 :   first_step_=false;
+     348             : }
+     349             : 
+     350             : inline void Optimizer::start_step_stride() {
+     351           2 :   first_step_=true;
+     352             : }
+     353             : 
+     354             : } // namespace maze
+     355             : } // namespace PLMD
+     356             : 
+     357             : #endif // __PLUMED_maze_Optimizer_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer_Bias.cpp.func-sort-c.html b/coverage/maze/Optimizer_Bias.cpp.func-sort-c.html new file mode 100644 index 000000000000..351fb5096772 --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer_Bias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer_Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959797.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze13OptimizerBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze13OptimizerBiasC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze13OptimizerBiasD0Ev1
_ZN4PLMD4maze13OptimizerBiasD1Ev1
_ZN4PLMD4maze13OptimizerBias16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze13OptimizerBias9calculateEv30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer_Bias.cpp.func.html b/coverage/maze/Optimizer_Bias.cpp.func.html new file mode 100644 index 000000000000..ebcc97d1dca9 --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer_Bias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer_Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959797.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze13OptimizerBias16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze13OptimizerBias9calculateEv30
_ZN4PLMD4maze13OptimizerBiasC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze13OptimizerBiasC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze13OptimizerBiasD0Ev1
_ZN4PLMD4maze13OptimizerBiasD1Ev1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Optimizer_Bias.cpp.gcov.html b/coverage/maze/Optimizer_Bias.cpp.gcov.html new file mode 100644 index 000000000000..01118f2eeccf --- /dev/null +++ b/coverage/maze/Optimizer_Bias.cpp.gcov.html @@ -0,0 +1,511 @@ + + + + + + + + LCOV - plumed test coverage - maze/Optimizer_Bias.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Optimizer_Bias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:959797.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Optimizer_Bias.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  *
+      28             :  * @code
+      29             :  * @article{rydzewski2018finding,
+      30             :  *   title={Finding Multiple Reaction Pathways of Ligand Unbinding},
+      31             :  *   author={Rydzewski, J and Valsson, O},
+      32             :  *   journal={arXiv preprint arXiv:1808.08089},
+      33             :  *   year={2018}
+      34             :  * }
+      35             :  * @endcode
+      36             :  */
+      37             : 
+      38             : #include "core/ActionRegister.h"
+      39             : #include "core/PlumedMain.h"
+      40             : 
+      41             : #include "bias/Bias.h"
+      42             : 
+      43             : #include "Optimizer.h"
+      44             : #include "Tools.h"
+      45             : 
+      46             : namespace PLMD {
+      47             : namespace maze {
+      48             : 
+      49             : //+PLUMEDOC MAZE_BIAS MAZE_OPTIMIZER_BIAS
+      50             : /*
+      51             : 
+      52             : Biases the ligand along the direction calculated by the chosen \ref MAZE_OPTIMIZER.
+      53             : 
+      54             : OptimizerBias is a class deriving from Bias, and it is used to adaptively
+      55             : bias a ligand-protein system toward an optimal solution found by the chosen
+      56             : optimizer.
+      57             : 
+      58             : Remember to define the loss function (\ref MAZE_LOSS) and the optimizer
+      59             : (\ref MAZE_OPTIMIZER) prior to the adaptive bias for the optimizer.
+      60             : 
+      61             : The adaptive bias potential is the following:
+      62             : \f[
+      63             :   V({\bf x}_t)=\alpha
+      64             :     \left(wt -
+      65             :       ({\bf x} - {\bf x}^*_{t-\tau})
+      66             :       \cdot
+      67             :       \frac{{\bf x}^*_t - {\bf x}_t}{\|{\bf x}^*_t-{\bf x}_t\|}
+      68             :     \right)^2,
+      69             : \f]
+      70             : where \f${\bf x}^*_t\f$ is the optimal solution at time \f$t\f$, \f$w\f$ is the
+      71             : biasing rate, \f$\tau\f$ is the interval at which the loss function is minimized,
+      72             : and \f$\alpha\f$ is a scaled force constant.
+      73             : 
+      74             : \par Examples
+      75             : 
+      76             : In the following example the bias potential biases a ligand atom (which have to be
+      77             : given as an argument) with the biasing rate equal to 0.02 A/ps, and the biasing
+      78             : constant equal to 3.6 kcal/(mol A). It also takes an optimizer (see
+      79             : \ref MAZE_OPTIMIZER).
+      80             : 
+      81             : \plumedfile
+      82             : UNITS LENGTH=A TIME=ps ENERGY=kcal/mol
+      83             : 
+      84             : p: POSITION ATOM=2635 NOPBC
+      85             : 
+      86             : MAZE_OPTIMIZER_BIAS ...
+      87             :   LABEL=bias
+      88             : 
+      89             :   ARG=p.x,p.y,p.z
+      90             : 
+      91             :   BIASING_RATE=0.02
+      92             :   ALPHA=3.6
+      93             : 
+      94             :   OPTIMIZER=opt
+      95             : ... MAZE_OPTIMIZER_BIAS
+      96             : \endplumedfile
+      97             : 
+      98             : */
+      99             : //+ENDPLUMEDOC
+     100             : 
+     101             : /**
+     102             :  * @class OptimizerBias OptimizerBias.cpp "maze/OptimizerBias.cpp"
+     103             :  *
+     104             :  * @brief Adaptive bias for the maze optimizers.
+     105             :  *
+     106             :  * OptimizerBias is a class deriving from Bias, and it is used to adaptively
+     107             :  * bias a system toward an optimal solution found by an optimizer.
+     108             :  */
+     109             : class OptimizerBias: public bias::Bias {
+     110             : public:
+     111             :   /**
+     112             :    * Standard PLUMED2 constructor.
+     113             :    *
+     114             :    * @param ao ActionOptions&.
+     115             :    */
+     116             :   explicit OptimizerBias(const ActionOptions& ao);
+     117             : 
+     118             :   /**
+     119             :    * Destructor.
+     120             :    */
+     121           3 :   ~OptimizerBias() { /* Nothing to do. */ }
+     122             : 
+     123             :   /**
+     124             :    * Register PLUMED2 keywords.
+     125             :    *
+     126             :    * @param keys Keywords.
+     127             :    */
+     128             :   static void registerKeywords(Keywords& keys);
+     129             : 
+     130             :   /**
+     131             :    * Calculate the adaptive biasing potential for ligand unbinding.
+     132             :    */
+     133             :   void calculate();
+     134             : 
+     135             : private:
+     136             :   /**
+     137             :    * Biased collective variable with Cartesian components, i.e., position,
+     138             :    * center of mass.
+     139             :    */
+     140             :   std::vector<Value*> args_;
+     141             : 
+     142             :   /**
+     143             :    * Pointer to the optimizer used to minimize the collective variable for
+     144             :    * ligand unbinding.
+     145             :    */
+     146             :   Optimizer* optimizer_;
+     147             :   std::vector<Optimizer*> opt_pntrs_;
+     148             : 
+     149             :   //! Adaptive bias potential and the corresponding force.
+     150             :   double bias_;
+     151             :   double force_;
+     152             : 
+     153             :   /*
+     154             :    * Parameters of the adaptive biasing potential:
+     155             :    *  alpha_            rescaled force constant
+     156             :    *  biasing_speed     biasing rate
+     157             :    *  biasing_stride    biasing stride
+     158             :    *  biasing_direction biasing direction
+     159             :    */
+     160             : 
+     161             :   //! Rescaled force constant.
+     162             :   double alpha_;
+     163             :   //! Biasing rate.
+     164             :   double biasing_speed_;
+     165             :   //! Biasing stride.
+     166             :   int biasing_stride_;
+     167             : 
+     168             :   /**
+     169             :    * Biasing direction is approximated by an optimal solution found by an
+     170             :    * optimizer.
+     171             :    */
+     172             :   Vector biasing_direction_;
+     173             : 
+     174             :   //! Total distance traveled by biased atoms.
+     175             :   double total_distance_;
+     176             : 
+     177             :   //! Previous value of the collective variable.
+     178             :   Vector cv0_;
+     179             : 
+     180             :   /*
+     181             :    * Pointers to PLUMED2 output components.
+     182             :    */
+     183             : 
+     184             :   //! Biased collective variable components.
+     185             :   Value* value_dir_x_;
+     186             :   Value* value_dir_y_;
+     187             :   Value* value_dir_z_;
+     188             : 
+     189             :   //! Values of the bias and its force.
+     190             :   Value* value_bias_;
+     191             :   Value* value_force_;
+     192             : 
+     193             :   //! Total distance.
+     194             :   Value* value_total_distance_;
+     195             : };
+     196             : 
+     197             : // Register OPTIMIZER_BIAS as a keyword for PLUMED2 input files.
+     198             : PLUMED_REGISTER_ACTION(OptimizerBias, "MAZE_OPTIMIZER_BIAS")
+     199             : 
+     200           3 : void OptimizerBias::registerKeywords(Keywords& keys) {
+     201           3 :   Bias::registerKeywords(keys);
+     202             : 
+     203           3 :   keys.use("ARG");
+     204             : 
+     205           6 :   keys.add(
+     206             :     "compulsory",
+     207             :     "BIASING_RATE",
+     208             :     "Biasing rate."
+     209             :   );
+     210             : 
+     211           6 :   keys.add(
+     212             :     "compulsory",
+     213             :     "ALPHA",
+     214             :     "Rescaled force constant."
+     215             :   );
+     216             : 
+     217           6 :   keys.add(
+     218             :     "compulsory",
+     219             :     "OPTIMIZER",
+     220             :     "Optimization technique to minimize the collective variable for ligand\
+     221             :      unbinding: RANDOM_WALK,\
+     222             :                 STEERED_MD,\
+     223             :                 RANDOM_ACCELERATION_MD,\
+     224             :                 SIMULATED_ANNEALING,\
+     225             :                 MEMETIC_SAMPLING"
+     226             :   );
+     227             : 
+     228           3 :   componentsAreNotOptional(keys);
+     229             : 
+     230           6 :   keys.addOutputComponent(
+     231             :     "force2",
+     232             :     "default",
+     233             :     "Square of the biasing force."
+     234             :   );
+     235             : 
+     236           6 :   keys.addOutputComponent(
+     237             :     "x",
+     238             :     "default",
+     239             :     "Optimal biasing direction: x component."
+     240             :   );
+     241             : 
+     242           6 :   keys.addOutputComponent(
+     243             :     "y",
+     244             :     "default",
+     245             :     "Optimal biasing direction: y component."
+     246             :   );
+     247             : 
+     248           6 :   keys.addOutputComponent(
+     249             :     "z",
+     250             :     "default",
+     251             :     "Optimal biasing direction: z component."
+     252             :   );
+     253             : 
+     254           6 :   keys.addOutputComponent(
+     255             :     "tdist",
+     256             :     "default",
+     257             :     "Total distance traveled by biased atoms."
+     258             :   );
+     259           3 : }
+     260             : 
+     261           1 : OptimizerBias::OptimizerBias(const ActionOptions& ao)
+     262             :   : PLUMED_BIAS_INIT(ao),
+     263           1 :     bias_(0.0),
+     264           1 :     force_(0.0),
+     265           1 :     total_distance_(0.0)
+     266             : {
+     267           1 :   log.printf(
+     268             :     "maze> You are using the maze module of PLUMED2,\
+     269             :     please read and cite "
+     270             :   );
+     271             : 
+     272           2 :   log << plumed.cite("Rydzewski J. and Valsson O., arXiv:1808.08089, 2018");
+     273           1 :   log.printf("\n");
+     274             : 
+     275           1 :   args_ = getArguments();
+     276           1 :   log.printf(
+     277             :     "maze> Number of args %zu\n",
+     278             :     args_.size()
+     279             :   );
+     280             : 
+     281           1 :   if (!args_.empty()) {
+     282           1 :     log.printf("maze> With arguments");
+     283           4 :     for (unsigned i = 0; i < args_.size(); i++) {
+     284           3 :       log.printf(" %s", args_[i]->getName().c_str());
+     285             :     }
+     286           1 :     log.printf("\n");
+     287             :   }
+     288             : 
+     289           2 :   if (keywords.exists("ALPHA")) {
+     290           1 :     parse("ALPHA", alpha_);
+     291             : 
+     292           1 :     plumed_massert(
+     293             :       alpha_>0,
+     294             :       "maze> ALPHA should be explicitly specified and positive.\n"
+     295             :     );
+     296             : 
+     297           1 :     log.printf(
+     298             :       "maze> ALPHA read: %f [kcal/mol/A].\n",
+     299             :       alpha_
+     300             :     );
+     301             :   }
+     302             : 
+     303           2 :   if (keywords.exists("BIASING_RATE")) {
+     304           1 :     parse("BIASING_RATE", biasing_speed_);
+     305             : 
+     306           1 :     plumed_massert(
+     307             :       biasing_speed_>0,
+     308             :       "maze> BIASING_RATE should be explicitly specified and positive.\n"
+     309             :     );
+     310             : 
+     311           1 :     log.printf(
+     312             :       "maze> BIASING_RATE read: %f [A/ps].\n",
+     313             :       biasing_speed_
+     314             :     );
+     315             :   }
+     316             : 
+     317           2 :   if (keywords.exists("OPTIMIZER")) {
+     318           1 :     std::vector<std::string> opt_labels(0);
+     319           2 :     parseVector("OPTIMIZER", opt_labels);
+     320             : 
+     321           1 :     plumed_massert(
+     322             :       opt_labels.size() > 0,
+     323             :       "maze> Problem with OPTIMIZER keyword.\n"
+     324             :     );
+     325             : 
+     326           1 :     std::string error_msg = "";
+     327           2 :     opt_pntrs_ = tls::get_pointers_labels<Optimizer*>(
+     328             :                    opt_labels,
+     329           1 :                    plumed.getActionSet(),
+     330             :                    error_msg
+     331             :                  );
+     332             : 
+     333           1 :     if (error_msg.size() > 0) {
+     334           0 :       plumed_merror(
+     335             :         "maze> Error in keyword OPTIMIZER of " + getName() + ": " + error_msg
+     336             :       );
+     337             :     }
+     338             : 
+     339           1 :     optimizer_ = opt_pntrs_[0];
+     340           1 :     log.printf(
+     341             :       "maze> Optimizer linked: %s.\n",
+     342           0 :       optimizer_->get_label().c_str()
+     343             :     );
+     344             : 
+     345           1 :     biasing_stride_=optimizer_->get_optimizer_stride();
+     346           1 :   }
+     347             : 
+     348           1 :   checkRead();
+     349             : 
+     350           2 :   addComponent("force2");
+     351           2 :   componentIsNotPeriodic("force2");
+     352             : 
+     353           2 :   addComponent("x");
+     354           2 :   componentIsNotPeriodic("x");
+     355             : 
+     356           2 :   addComponent("y");
+     357           2 :   componentIsNotPeriodic("y");
+     358             : 
+     359           2 :   addComponent("z");
+     360           2 :   componentIsNotPeriodic("z");
+     361             : 
+     362           2 :   addComponent("tdist");
+     363           1 :   componentIsNotPeriodic("tdist");
+     364             : 
+     365           1 :   biasing_direction_.zero();
+     366           1 :   cv0_.zero();
+     367             : 
+     368           1 :   value_bias_ = getPntrToComponent("bias");
+     369           1 :   value_force_ = getPntrToComponent("force2");
+     370             : 
+     371           1 :   value_dir_x_ = getPntrToComponent("x");
+     372           1 :   value_dir_y_ = getPntrToComponent("y");
+     373           1 :   value_dir_z_ = getPntrToComponent("z");
+     374             : 
+     375           1 :   value_total_distance_=getPntrToComponent("tdist");
+     376           1 : }
+     377             : 
+     378          30 : void OptimizerBias::calculate() {
+     379             :   // Unpack arguments and optimizers.
+     380             :   Vector cv(
+     381             :     args_[0]->get(),
+     382             :     args_[1]->get(),
+     383             :     args_[2]->get()
+     384          30 :   );
+     385             : 
+     386             :   Vector opt_direction(
+     387          30 :     optimizer_->value_x_->get(),
+     388          30 :     optimizer_->value_y_->get(),
+     389          30 :     optimizer_->value_z_->get()
+     390          30 :   );
+     391             : 
+     392          30 :   if (getStep() == 0) {
+     393           1 :     cv0_=cv;
+     394             :   }
+     395             : 
+     396             :   /*
+     397             :    * For details see a paper by Rydzewski and Valsson.
+     398             :    */
+     399          30 :   double dot = dotProduct(cv - cv0_, biasing_direction_);
+     400          30 :   double delta_cv = biasing_speed_ * getTime() - (dot + total_distance_);
+     401             : 
+     402          30 :   double sign = tls::sgn(delta_cv);
+     403             : 
+     404          30 :   bias_ = alpha_ * delta_cv * delta_cv;
+     405          30 :   force_ = 2.0 * sign * alpha_ * fabs(delta_cv);
+     406             : 
+     407          30 :   if (getStep() % biasing_stride_ == 0) {
+     408           3 :     biasing_direction_ = opt_direction;
+     409           3 :     cv0_ = cv;
+     410           3 :     total_distance_ += dot;
+     411             :   }
+     412             : 
+     413             :   /*
+     414             :    * Return the biasing force to MD engine.
+     415             :    */
+     416          30 :   setOutputForce(0, force_ * biasing_direction_[0]);
+     417          30 :   setOutputForce(1, force_ * biasing_direction_[1]);
+     418          30 :   setOutputForce(2, force_ * biasing_direction_[2]);
+     419             : 
+     420             :   /*
+     421             :    * Set values for PLUMED2 outputs.
+     422             :    */
+     423          30 :   value_bias_->set(bias_);
+     424          30 :   value_force_->set(force_);
+     425             : 
+     426          30 :   value_total_distance_->set(total_distance_);
+     427             : 
+     428          30 :   value_dir_x_->set(biasing_direction_[0]);
+     429          30 :   value_dir_y_->set(biasing_direction_[1]);
+     430          30 :   value_dir_z_->set(biasing_direction_[2]);
+     431          30 : }
+     432             : 
+     433             : } // namespace maze
+     434             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html b/coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html new file mode 100644 index 000000000000..0feb55ab47e0 --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Acceleration_MD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Acceleration_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze22Random_Acceleration_MDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze22Random_Acceleration_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze22Random_Acceleration_MD8optimizeEv2
_ZN4PLMD4maze22Random_Acceleration_MD16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Acceleration_MD.cpp.func.html b/coverage/maze/Random_Acceleration_MD.cpp.func.html new file mode 100644 index 000000000000..bffd915333b8 --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Acceleration_MD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Acceleration_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze22Random_Acceleration_MD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze22Random_Acceleration_MD8optimizeEv2
_ZN4PLMD4maze22Random_Acceleration_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze22Random_Acceleration_MDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Acceleration_MD.cpp.gcov.html b/coverage/maze/Random_Acceleration_MD.cpp.gcov.html new file mode 100644 index 000000000000..3789e37a6a45 --- /dev/null +++ b/coverage/maze/Random_Acceleration_MD.cpp.gcov.html @@ -0,0 +1,280 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Acceleration_MD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Acceleration_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Random_Acceleration_MD.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "Optimizer.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_RANDOM_ACCELERATION_MD
+      36             : /*
+      37             : 
+      38             : Performs random acceleration MD within the protein matrix.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : Every optimizer implemented in the maze module needs a loss function as
+      43             : an argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      44             : 
+      45             : \plumedfile
+      46             : MAZE_RANDOM_ACCELERATION_MD ...
+      47             :   LABEL=rw
+      48             : 
+      49             :   OPTIMIZER_STRIDE=_
+      50             :   LOSS=l
+      51             :   RMIN=_
+      52             : 
+      53             :   LIGAND=2635-2646
+      54             :   PROTEIN=1-2634
+      55             : ... MAZE_RANDOM_ACCELERATION_MD
+      56             : \endplumedfile
+      57             : 
+      58             : As shown above, each optimizer should be provided with the LIGAND and
+      59             : the PROTEIN keywords.
+      60             : 
+      61             : */
+      62             : //+ENDPLUMEDOC
+      63             : 
+      64             : /**
+      65             :  * @class Random_Acceleration_MD Random_Acceleration_MD.cpp
+      66             :  *  "maze/Random_Acceleration_MD.cpp"
+      67             :  *
+      68             :  * @brief Perform RAMD simulation.
+      69             :  */
+      70             : class Random_Acceleration_MD: public Optimizer {
+      71             : public:
+      72             :   /**
+      73             :    * PLMD constructor.
+      74             :    *
+      75             :    * @param[in] ao PLMD::ActionOptions&
+      76             :    */
+      77             :   explicit Random_Acceleration_MD(const ActionOptions&);
+      78             : 
+      79             :   /**
+      80             :    * Registers PLMD keywords.
+      81             :    *
+      82             :    * @param[in] keys PLMD keywords
+      83             :    */
+      84             :   static void registerKeywords(Keywords&);
+      85             : 
+      86             :   /**
+      87             :    * Each class deriving from Optimizer needs to override this function.
+      88             :    */
+      89             :   void optimize() override;
+      90             : 
+      91             : private:
+      92             :   //! Threshold distance that the ligand needs to pass.
+      93             :   double r_min_;
+      94             : 
+      95             :   //! Total distance.
+      96             :   double total_dist_;
+      97             : 
+      98             :   //! Distance.
+      99             :   double dist_;
+     100             : 
+     101             :   //! Ligand center of mass.
+     102             :   Vector com_;
+     103             : 
+     104             :   //! PLMD value for distance.
+     105             :   Value* value_dist_;
+     106             : 
+     107             :   //! PLMD value for total distance.
+     108             :   Value* value_total_dist_;
+     109             : };
+     110             : 
+     111             : // Register MAZE_RANDOM_ACCELERATION_MD.
+     112             : PLUMED_REGISTER_ACTION(Random_Acceleration_MD, "MAZE_RANDOM_ACCELERATION_MD")
+     113             : 
+     114           3 : void Random_Acceleration_MD::registerKeywords(Keywords& keys) {
+     115           3 :   Optimizer::registerKeywords(keys);
+     116             : 
+     117           3 :   keys.remove("N_ITER");
+     118             : 
+     119           6 :   keys.add(
+     120             :     "compulsory",
+     121             :     "R_MIN",
+     122             :     "Minimal distance traveled before sampling a new direction of biasing."
+     123             :   );
+     124             : 
+     125           6 :   keys.addOutputComponent(
+     126             :     "dist",
+     127             :     "default",
+     128             :     "Distance traveled in one sampling interval."
+     129             :   );
+     130             : 
+     131           6 :   keys.addOutputComponent(
+     132             :     "tdist",
+     133             :     "default",
+     134             :     "Total distance traveled by biased atoms."
+     135             :   );
+     136           3 : }
+     137             : 
+     138           1 : Random_Acceleration_MD::Random_Acceleration_MD(const ActionOptions& ao)
+     139             :   : PLUMED_OPT_INIT(ao),
+     140           1 :     total_dist_(0.0),
+     141           1 :     dist_(0.0) {
+     142           1 :   log.printf("maze> Random accelerated molecular dynamics.\n");
+     143             : 
+     144           2 :   if(keywords.exists("R_MIN")) {
+     145           1 :     parse("R_MIN", r_min_);
+     146             : 
+     147           1 :     plumed_massert(
+     148             :       r_min_ > 0,
+     149             :       "maze> R_MIN should be explicitly specified and positive.\n"
+     150             :     );
+     151             : 
+     152           1 :     log.printf(
+     153             :       "maze> R_MIN read: %f [A].\n",
+     154             :       r_min_
+     155             :     );
+     156             :   }
+     157             : 
+     158           1 :   set_label("RANDOM_ACCELERATION_MD");
+     159           1 :   set_opt(rnd::next_plmd_vector());
+     160             :   set_opt_value(0.0);
+     161             : 
+     162             :   start_step_stride();
+     163             : 
+     164           1 :   checkRead();
+     165             : 
+     166           1 :   com_ = center_of_mass();
+     167             : 
+     168           2 :   addComponent("dist");
+     169           1 :   componentIsNotPeriodic("dist");
+     170           1 :   value_dist_ = getPntrToComponent("dist");
+     171             : 
+     172           2 :   addComponent("tdist");
+     173           1 :   componentIsNotPeriodic("tdist");
+     174           1 :   value_total_dist_ = getPntrToComponent("tdist");
+     175           1 : }
+     176             : 
+     177           2 : void Random_Acceleration_MD::optimize() {
+     178           2 :   Vector c = center_of_mass();
+     179           2 :   Vector d;
+     180             : 
+     181           2 :   if (pbc_) {
+     182           2 :     d = pbcDistance(c, com_);
+     183             :   }
+     184             :   else {
+     185           0 :     d = delta(c, com_);
+     186             :   }
+     187             : 
+     188           2 :   dist_ = d.modulo();
+     189           2 :   total_dist_ += dist_;
+     190             : 
+     191           2 :   if(dist_ < r_min_) {
+     192           0 :     set_opt(rnd::next_plmd_vector());
+     193             :   }
+     194             : 
+     195           2 :   set_opt_value(score());
+     196           2 :   com_ = c;
+     197             : 
+     198           2 :   value_dist_->set(dist_);
+     199           2 :   value_total_dist_->set(total_dist_);
+     200           2 : }
+     201             : 
+     202             : } // namespace maze
+     203             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.cpp.func-sort-c.html b/coverage/maze/Random_MT.cpp.func-sort-c.html new file mode 100644 index 000000000000..e252558f3575 --- /dev/null +++ b/coverage/maze/Random_MT.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd8next_intEii3
_ZN4PLMD4maze3rnd11next_cauchyEdd54
_ZN4PLMD4maze3rnd11next_doubleEdd246
_ZN4PLMD4maze3rnd8next_intEi279
_ZN4PLMD4maze3rnd11next_doubleEv536
_ZN4PLMD4maze3rnd6mt_engEv1125
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.cpp.func.html b/coverage/maze/Random_MT.cpp.func.html new file mode 100644 index 000000000000..710a7ff5e254 --- /dev/null +++ b/coverage/maze/Random_MT.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd11next_cauchyEdd54
_ZN4PLMD4maze3rnd11next_doubleEdd246
_ZN4PLMD4maze3rnd11next_doubleEv536
_ZN4PLMD4maze3rnd6mt_engEv1125
_ZN4PLMD4maze3rnd8next_intEi279
_ZN4PLMD4maze3rnd8next_intEii3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.cpp.gcov.html b/coverage/maze/Random_MT.cpp.gcov.html new file mode 100644 index 000000000000..8d41e9205163 --- /dev/null +++ b/coverage/maze/Random_MT.cpp.gcov.html @@ -0,0 +1,158 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Random_MT.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  *
+      28             :  * @brief Dummy cpp file.
+      29             :  */
+      30             : 
+      31             : #include "Random_MT.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace maze {
+      35             : 
+      36        1125 : std::mt19937_64& rnd::mt_eng() {
+      37        1132 :   static std::mt19937_64 mt{};
+      38             : 
+      39        1125 :   return mt;
+      40             : }
+      41             : 
+      42         246 : double rnd::next_double(double f, double e) {
+      43         246 :   static std::uniform_real_distribution<double> dist_double(f, e);
+      44             :   std::uniform_real_distribution<double>::param_type p(f, e);
+      45             :   dist_double.param(p);
+      46             : 
+      47         246 :   return dist_double(mt_eng());
+      48             : }
+      49             : 
+      50         536 : double rnd::next_double() {
+      51         536 :   static std::uniform_real_distribution<double> dist_double(0, 1);
+      52             :   std::uniform_real_distribution<double>::param_type p(0, 1);
+      53             :   dist_double.param(p);
+      54             : 
+      55         536 :   return dist_double(mt_eng());
+      56             : }
+      57             : 
+      58         279 : int rnd::next_int(int e) {
+      59         279 :   static std::uniform_int_distribution<int> dist_int(0, e-1);
+      60         279 :   std::uniform_int_distribution<int>::param_type p(0, e-1);
+      61             :   dist_int.param(p);
+      62             : 
+      63         279 :   return dist_int(mt_eng());
+      64             : }
+      65             : 
+      66           3 : int rnd::next_int(int f, int e) {
+      67           3 :   static std::uniform_int_distribution<int> dist_int(f, e-1);
+      68           3 :   std::uniform_int_distribution<int>::param_type p(f, e-1);
+      69             :   dist_int.param(p);
+      70             : 
+      71           3 :   return dist_int(mt_eng());
+      72             : }
+      73             : 
+      74          54 : double rnd::next_cauchy(double m, double s) {
+      75          54 :   static std::cauchy_distribution<double> dist_cauchy(m, s);
+      76             : 
+      77          54 :   return dist_cauchy(mt_eng());
+      78             : }
+      79             : 
+      80             : } // namespace maze
+      81             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.h.func-sort-c.html b/coverage/maze/Random_MT.h.func-sort-c.html new file mode 100644 index 000000000000..bef61a331cda --- /dev/null +++ b/coverage/maze/Random_MT.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121770.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd11next_doubleEddm0
_ZN4PLMD4maze3rnd9randomizeEv7
_ZN4PLMD4maze3rnd16next_plmd_vectorEd66
_ZN4PLMD4maze3rnd16next_plmd_vectorEv73
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.h.func.html b/coverage/maze/Random_MT.h.func.html new file mode 100644 index 000000000000..539d4affe140 --- /dev/null +++ b/coverage/maze/Random_MT.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121770.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3rnd11next_doubleEddm0
_ZN4PLMD4maze3rnd16next_plmd_vectorEd66
_ZN4PLMD4maze3rnd16next_plmd_vectorEv73
_ZN4PLMD4maze3rnd9randomizeEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_MT.h.gcov.html b/coverage/maze/Random_MT.h.gcov.html new file mode 100644 index 000000000000..492c44d55c58 --- /dev/null +++ b/coverage/maze/Random_MT.h.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_MT.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_MT.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121770.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_maze_Random_MT_h
+      23             : #define __PLUMED_maze_Random_MT_h
+      24             : 
+      25             : /**
+      26             :  * @file Random_MT.h
+      27             :  *
+      28             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      29             :  */
+      30             : 
+      31             : #include "Core.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace maze {
+      35             : 
+      36             : /**
+      37             :  * @class rnd Random_MT.h "maze/Random_MT.h"
+      38             :  *
+      39             :  * @brief Mersenne Twister sampler for random variables.
+      40             :  *
+      41             :  * Supports generating integers, doubles, and std::vectors and PLMD::Vectors
+      42             :  * within a given range.
+      43             :  */
+      44             : class rnd {
+      45             : public:
+      46             :   /**
+      47             :    * Initialize MT sampler engine based on std::mt19937_64.
+      48             :    */
+      49             :   static std::mt19937_64& mt_eng();
+      50             : 
+      51             :   /**
+      52             :    * Feed a random seed.
+      53             :    */
+      54             :   static void randomize();
+      55             : 
+      56             :   /**
+      57             :    * Returns a random double from the Cauchy distribution.
+      58             :    *
+      59             :    * @param m mean
+      60             :    * @param s spread
+      61             :    */
+      62             :   static double next_cauchy(double m, double s);
+      63             : 
+      64             :   /**
+      65             :    * Returns a random int from the uniform distribution from a [f, e) range.
+      66             :    *
+      67             :    * @param f begin
+      68             :    * @param e end
+      69             :    */
+      70             :   static int next_int(int f, int e);
+      71             :   static int next_int(int e);
+      72             : 
+      73             :   /**
+      74             :    * Returns a random double from the uniform distribution from a [f, e) range.
+      75             :    */
+      76             :   static double next_double(double f, double e);
+      77             :   static double next_double(double e);
+      78             :   static double next_double();
+      79             : 
+      80             :   /**
+      81             :    * Returns a random vector<double> from the uniform distribution from a [f, e)
+      82             :    * range of length n.
+      83             :    */
+      84             :   static std::vector<double> next_double(double f, double e, std::size_t n);
+      85             : 
+      86             :   /**
+      87             :    * Returns a random PLMD::Vector of length r.
+      88             :    */
+      89             :   static Vector next_plmd_vector();
+      90             :   static Vector next_plmd_vector(double r);
+      91             : 
+      92             :   /**
+      93             :    * Returns a random std::vector of length r.
+      94             :    */
+      95             :   static std::vector<double> next_std_vector();
+      96             :   static std::vector<double> next_std_vector(double r);
+      97             : };
+      98             : 
+      99          66 : inline Vector rnd::next_plmd_vector(double r) {
+     100          66 :   return next_plmd_vector() * r;
+     101             : }
+     102             : 
+     103             : inline std::vector<double> rnd::next_std_vector(double r) {
+     104             :   double t = next_double() * 2.0 * pi;
+     105             :   double p = next_double() * pi;
+     106             : 
+     107             :   return std::vector<double> {
+     108             :     r * std::sin(p) * std::cos(t),
+     109             :     r * std::sin(t) * std::sin(p),
+     110             :     r * std::cos(p)
+     111             :   };
+     112             : }
+     113             : 
+     114           0 : inline std::vector<double> rnd::next_double(double f, double e, size_t n) {
+     115           0 :   std::vector<double> t(n);
+     116           0 :   for (std::size_t i=0; i < n; ++i) {
+     117           0 :     t[i] = next_double(f, e);
+     118             :   }
+     119             : 
+     120           0 :   return t;
+     121             : }
+     122             : 
+     123          73 : inline Vector rnd::next_plmd_vector() {
+     124          73 :   double t = next_double() * 2.0 * pi;
+     125          73 :   double p = next_double() * pi;
+     126             : 
+     127             :   return Vector(
+     128          73 :            std::sin(p) * std::cos(t),
+     129          73 :            std::sin(t) * std::sin(p),
+     130             :            std::cos(p)
+     131          73 :          );
+     132             : }
+     133             : 
+     134             : inline std::vector<double> rnd::next_std_vector() {
+     135             :   double t = next_double() * 2.0 * pi;
+     136             :   double p = next_double() * pi;
+     137             : 
+     138             :   return std::vector<double> {
+     139             :     std::sin(p) * std::cos(t),
+     140             :     std::sin(t) * std::sin(p),
+     141             :     std::cos(p)
+     142             :   };
+     143             : }
+     144             : 
+     145             : inline double rnd::next_double(double e) {
+     146         246 :   return next_double(0, e);
+     147             : }
+     148             : 
+     149           7 : inline void rnd::randomize() {
+     150           7 :   mt_eng().seed(time(0));
+     151           7 : }
+     152             : 
+     153             : } // namespace maze
+     154             : } // namespace PLMD
+     155             : 
+     156             : #endif // __PLUMED_maze_Random_MT_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Walk.cpp.func-sort-c.html b/coverage/maze/Random_Walk.cpp.func-sort-c.html new file mode 100644 index 000000000000..ebe5ff6512cd --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Walk.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Walk.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze11Random_WalkC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze11Random_WalkC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze11Random_Walk16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze11Random_Walk8optimizeEv6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Walk.cpp.func.html b/coverage/maze/Random_Walk.cpp.func.html new file mode 100644 index 000000000000..efd49b2957e9 --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Walk.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Walk.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze11Random_Walk16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4maze11Random_Walk8optimizeEv6
_ZN4PLMD4maze11Random_WalkC1ERKNS_13ActionOptionsE2
_ZN4PLMD4maze11Random_WalkC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Random_Walk.cpp.gcov.html b/coverage/maze/Random_Walk.cpp.gcov.html new file mode 100644 index 000000000000..5ac7271cd95d --- /dev/null +++ b/coverage/maze/Random_Walk.cpp.gcov.html @@ -0,0 +1,201 @@ + + + + + + + + LCOV - plumed test coverage - maze/Random_Walk.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Random_Walk.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Random_Walk.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "Optimizer.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_RANDOM_WALK
+      36             : /*
+      37             : 
+      38             : Fake optimizer that can be used for debugging.
+      39             : 
+      40             : This is dummy optimizer that can be used for debugging and monitoring
+      41             : purposes. It returns a random direction of biasing, changed every
+      42             : OPTIMIZER_STRIDE.
+      43             : 
+      44             : Performs a random walk within the protein matrix.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : Every optimizer implemented in the maze module needs a loss function as
+      49             : an argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      50             : 
+      51             : \plumedfile
+      52             : MAZE_RANDOM_WALK ...
+      53             :   LABEL=rw
+      54             : 
+      55             :   LOSS=l
+      56             :   OPTIMIZER_STRIDE=200
+      57             : 
+      58             :   LIGAND=2635-2646
+      59             :   PROTEIN=1-2634
+      60             : ... MAZE_RANDOM_WALK
+      61             : \endplumedfile
+      62             : 
+      63             : As shown above, each optimizer should be provided with the LIGAND and
+      64             : the PROTEIN keywords.
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : /**
+      70             :  * @class Random_Walk Random_Walk.cpp "maze/Random_Walk.cpp"
+      71             :  *
+      72             :  * @brief Perform a random walk within the protein matrix.
+      73             :  */
+      74             : class Random_Walk: public Optimizer {
+      75             : public:
+      76             :   /**
+      77             :    * PLMD constructor.
+      78             :    *
+      79             :    * @param[in] ao PLMD::ActionOptions&
+      80             :    */
+      81             :   explicit Random_Walk(const ActionOptions& ao);
+      82             : 
+      83             :   /**
+      84             :    * Registers PLMD keywords.
+      85             :    *
+      86             :    * @param[in] keys PLMD keywords
+      87             :    */
+      88             :   static void registerKeywords(Keywords&);
+      89             : 
+      90             :   /**
+      91             :    * Each class deriving from Optimizer needs to override this function.
+      92             :    */
+      93             :   void optimize() override;
+      94             : };
+      95             : 
+      96             : // Register MAZE_RANDOM_WALK.
+      97             : PLUMED_REGISTER_ACTION(Random_Walk, "MAZE_RANDOM_WALK")
+      98             : 
+      99           4 : void Random_Walk::registerKeywords(Keywords& keys) {
+     100           4 :   Optimizer::registerKeywords(keys);
+     101             : 
+     102           4 :   keys.remove("N_ITER");
+     103           4 : }
+     104             : 
+     105           2 : Random_Walk::Random_Walk(const ActionOptions& ao)
+     106           2 :   : PLUMED_OPT_INIT(ao)
+     107             : {
+     108           2 :   log.printf("maze> Fake optimizer that returns a next step as random,\
+     109             :     can be used to monitor loss, and for debugging and regtests purposes.\n");
+     110             : 
+     111           4 :   set_label("RANDOM_WALK");
+     112             : 
+     113             :   start_step_0();
+     114             : 
+     115           2 :   checkRead();
+     116           2 : }
+     117             : 
+     118           6 : void Random_Walk::optimize() {
+     119           6 :   set_opt(rnd::next_plmd_vector());
+     120           6 :   set_opt_value(score());
+     121           6 : }
+     122             : 
+     123             : } // namespace maze
+     124             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Simulated_Annealing.cpp.func-sort-c.html b/coverage/maze/Simulated_Annealing.cpp.func-sort-c.html new file mode 100644 index 000000000000..213bf22a020d --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - maze/Simulated_Annealing.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Simulated_Annealing.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434987.8 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze19Simulated_AnnealingC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze19Simulated_AnnealingC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze19Simulated_Annealing16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze19Simulated_Annealing8optimizeEv3
_ZN4PLMD4maze19Simulated_Annealing20decrease_probabilityEj30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Simulated_Annealing.cpp.func.html b/coverage/maze/Simulated_Annealing.cpp.func.html new file mode 100644 index 000000000000..06934b88478f --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - maze/Simulated_Annealing.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Simulated_Annealing.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434987.8 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze19Simulated_Annealing16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze19Simulated_Annealing20decrease_probabilityEj30
_ZN4PLMD4maze19Simulated_Annealing8optimizeEv3
_ZN4PLMD4maze19Simulated_AnnealingC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze19Simulated_AnnealingC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Simulated_Annealing.cpp.gcov.html b/coverage/maze/Simulated_Annealing.cpp.gcov.html new file mode 100644 index 000000000000..2f1c8e73f02c --- /dev/null +++ b/coverage/maze/Simulated_Annealing.cpp.gcov.html @@ -0,0 +1,352 @@ + + + + + + + + LCOV - plumed test coverage - maze/Simulated_Annealing.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Simulated_Annealing.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434987.8 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Simulated_Annealing.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "Optimizer.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_SIMULATED_ANNEALING
+      36             : /*
+      37             : 
+      38             : Calculates the biasing direction along which the ligand unbinds by minimizing
+      39             : the \ref MAZE_LOSS function. The optimal biasing direction is determined by
+      40             : performing simulated annealing.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : Every optimizer implemented in the maze module needs a loss function as an
+      45             : argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      46             : 
+      47             : In the following example simulated annealing is launched for 1000 iterations
+      48             : as the optimizer for the loss function every 200 ps. The geometric cooling
+      49             : scheme is used.
+      50             : 
+      51             : \plumedfile
+      52             : UNITS LENGTH=A TIME=ps ENERGY=kcal/mol
+      53             : 
+      54             : MAZE_SIMULATED_ANNEALING ...
+      55             :   LABEL=sa
+      56             : 
+      57             :   LOSS=l
+      58             : 
+      59             :   N_ITER=1000
+      60             :   OPTIMIZER_STRIDE=200
+      61             : 
+      62             :   PROBABILITY_DECREASER=300
+      63             :   COOLING=0.95
+      64             :   COOLING_TYPE=geometric
+      65             : 
+      66             :   LIGAND=2635-2646
+      67             :   PROTEIN=1-2634
+      68             : ... MAZE_SIMULATED_ANNEALING
+      69             : \endplumedfile
+      70             : 
+      71             : As shown above, each optimizer should be provided with the LIGAND and
+      72             : the PROTEIN keywords.
+      73             : 
+      74             : */
+      75             : //+ENDPLUMEDOC
+      76             : 
+      77             : /**
+      78             :  * @class Simulated_Annealing Simulated_Annealing.cpp "maze/Simulated_Annealing.cpp"
+      79             :  *
+      80             :  * @brief Perform simulated annealing to compute an optimal bias direction.
+      81             :  */
+      82             : class Simulated_Annealing: public Optimizer {
+      83             : public:
+      84             :   /**
+      85             :    * PLMD constructor.
+      86             :    *
+      87             :    * @param[in] ao PLMD::ActionOptions&.
+      88             :    */
+      89             :   explicit Simulated_Annealing(const ActionOptions& ao);
+      90             : 
+      91             :   /**
+      92             :    * Register PLMD keywords.
+      93             :    *
+      94             :    * @param[in] keys Keywords.
+      95             :    */
+      96             :   static void registerKeywords(Keywords& keys);
+      97             : 
+      98             :   /**
+      99             :    * Each class deriving from Optimizer needs to override this function.
+     100             :    */
+     101             :   void optimize() override;
+     102             : 
+     103             :   /**
+     104             :    * Reduce the temperature parameter.
+     105             :    */
+     106             :   void decrease_probability(unsigned int);
+     107             : 
+     108             : private:
+     109             :   //! Temperature parameter.
+     110             :   double probability_decreaser_;
+     111             : 
+     112             :   //! Cooling factor.
+     113             :   double cooling_factor_;
+     114             : 
+     115             :   //! Cooling scheme.
+     116             :   std::string cooling_scheme_;
+     117             : };
+     118             : 
+     119             : // Register MAZE_SIMULATED_ANNEALING.
+     120             : PLUMED_REGISTER_ACTION(Simulated_Annealing, "MAZE_SIMULATED_ANNEALING")
+     121             : 
+     122           3 : void Simulated_Annealing::registerKeywords(Keywords& keys) {
+     123           3 :   Optimizer::registerKeywords(keys);
+     124             : 
+     125           6 :   keys.add(
+     126             :     "compulsory",
+     127             :     "PROBABILITY_DECREASER",
+     128             :     "Temperature-like parameter that is decreased during optimization to modify "
+     129             :     "the Metropolis-Hastings acceptance probability."
+     130             :   );
+     131             : 
+     132           6 :   keys.add(
+     133             :     "compulsory",
+     134             :     "COOLING",
+     135             :     "Reduction factor for PROBABILITY_DECREASER, should be in (0, 1]."
+     136             :   );
+     137             : 
+     138           6 :   keys.add(
+     139             :     "compulsory",
+     140             :     "COOLING_SCHEME",
+     141             :     "Cooling scheme: geometric."
+     142             :   );
+     143           3 : }
+     144             : 
+     145           1 : Simulated_Annealing::Simulated_Annealing(const ActionOptions& ao)
+     146           1 :   : PLUMED_OPT_INIT(ao)
+     147             : {
+     148           1 :   log.printf("maze> Simulated annealing optimizer.\n");
+     149             : 
+     150           2 :   if(keywords.exists("COOLING")) {
+     151           1 :     parse("COOLING", cooling_factor_);
+     152             : 
+     153           1 :     plumed_massert(
+     154             :       cooling_factor_ > 0 && cooling_factor_ <= 1,
+     155             :       "maze> COOLING should be in (0, 1]; preferably 0.95.\n"
+     156             :     );
+     157             :   }
+     158             : 
+     159           2 :   if(keywords.exists("PROBABILITY_DECREASER")) {
+     160           1 :     parse("PROBABILITY_DECREASER", probability_decreaser_);
+     161             : 
+     162           1 :     plumed_massert(
+     163             :       probability_decreaser_ > 0,
+     164             :       "maze> PROBABILITY_DECREASER should be explicitly specified and positive.\n");
+     165             :   }
+     166             : 
+     167           2 :   if(keywords.exists("COOLING_SCHEME")) {
+     168           1 :     parse("COOLING_SCHEME", cooling_scheme_);
+     169             : 
+     170           1 :     log.printf(
+     171             :       "maze> COOLING_SCHEME read: %s.\n",
+     172             :       cooling_scheme_.c_str()
+     173             :     );
+     174             :   }
+     175             : 
+     176           2 :   set_label("SIMULATED_ANNEALING");
+     177             : 
+     178             :   // Calculate an optimal direction at the beginning of the MD simulation.
+     179             :   start_step_0();
+     180             : 
+     181           1 :   checkRead();
+     182           1 : }
+     183             : 
+     184          30 : void Simulated_Annealing::decrease_probability(unsigned int time) {
+     185          30 :   if (cooling_scheme_ == "linear") {
+     186           0 :     probability_decreaser_ -= time * cooling_factor_;
+     187             :   }
+     188          30 :   else if (cooling_scheme_ == "exponential") {
+     189           0 :     probability_decreaser_ *= pow(cooling_factor_, time);
+     190             :   }
+     191          30 :   else if (cooling_scheme_ == "geometric") {
+     192          30 :     probability_decreaser_ *= cooling_factor_;
+     193             :   }
+     194           0 :   else if (cooling_scheme_ == "logarithmic") {
+     195           0 :     probability_decreaser_ = cooling_factor_ / std::log(time + 1);
+     196             :   }
+     197           0 :   else if (cooling_scheme_ == "hoffman") {
+     198           0 :     probability_decreaser_ = (cooling_factor_ - 1) / std::log(time);
+     199             :   }
+     200          30 : }
+     201             : 
+     202           3 : void Simulated_Annealing::optimize() {
+     203           3 :   sampling_r_ = sampling_radius();
+     204             :   double rad_s;
+     205           3 :   const unsigned nl_size = neighbor_list_->size();
+     206             : 
+     207           3 :   Vector distance, distance_next;
+     208             : 
+     209          33 :   for (unsigned int iter=0; iter < get_n_iterations(); ++iter) {
+     210             :     double action = 0;
+     211             :     double action_next = 0;
+     212             : 
+     213          30 :     rad_s = rnd::next_double(sampling_r_);
+     214          30 :     Vector dev = rnd::next_plmd_vector(rad_s);
+     215             : 
+     216          30 :     #pragma omp parallel num_threads(get_n_threads_openmp())
+     217             :     {
+     218             :       #pragma omp for reduction(+:action_next, action)
+     219             :       for (unsigned int i=0; i < nl_size; i++) {
+     220             :         unsigned i0 = neighbor_list_->getClosePair(i).first;
+     221             :         unsigned i1 = neighbor_list_->getClosePair(i).second;
+     222             : 
+     223             :         if (getAbsoluteIndex(i0) == getAbsoluteIndex(i1)) {
+     224             :           continue;
+     225             :         }
+     226             : 
+     227             :         if (pbc_) {
+     228             :           distance = pbcDistance(
+     229             :                        getPosition(i0) + get_opt(),
+     230             :                        getPosition(i1)
+     231             :                      );
+     232             : 
+     233             :           distance_next = pbcDistance(
+     234             :                             getPosition(i0) + dev,
+     235             :                             getPosition(i1)
+     236             :                           );
+     237             :         }
+     238             :         else {
+     239             :           distance = delta(
+     240             :                        getPosition(i0) + get_opt(),
+     241             :                        getPosition(i1)
+     242             :                      );
+     243             : 
+     244             :           distance_next = delta(
+     245             :                             getPosition(i0) + dev,
+     246             :                             getPosition(i1)
+     247             :                           );
+     248             :         }
+     249             : 
+     250             :         action += pairing(distance.modulo());
+     251             :         action_next += pairing(distance_next.modulo());
+     252             :       }
+     253             :     }
+     254             : 
+     255             :     double p = std::min(
+     256          60 :                  1.0,
+     257          30 :                  std::exp(-(action_next - action) / probability_decreaser_)
+     258          30 :                );
+     259             : 
+     260          30 :     double r = rnd::next_double();
+     261             : 
+     262          30 :     if (r < p) {
+     263             :       set_opt(dev);
+     264             :       set_opt_value(action_next);
+     265             :     }
+     266             : 
+     267          30 :     decrease_probability(iter);
+     268             :   }
+     269             : 
+     270           3 :   Vector s = get_opt() / modulo(get_opt());
+     271             :   set_opt(s);
+     272           3 : }
+     273             : 
+     274             : } // namespace maze
+     275             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Steered_MD.cpp.func-sort-c.html b/coverage/maze/Steered_MD.cpp.func-sort-c.html new file mode 100644 index 000000000000..514bf46d3587 --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Steered_MD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Steered_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313296.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze10Steered_MDC2ERKNS_13ActionOptionsE0
_ZN4PLMD4maze10Steered_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze10Steered_MD8optimizeEv2
_ZN4PLMD4maze10Steered_MD16registerKeywordsERNS_8KeywordsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Steered_MD.cpp.func.html b/coverage/maze/Steered_MD.cpp.func.html new file mode 100644 index 000000000000..c77c07840611 --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Steered_MD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Steered_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313296.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze10Steered_MD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD4maze10Steered_MD8optimizeEv2
_ZN4PLMD4maze10Steered_MDC1ERKNS_13ActionOptionsE1
_ZN4PLMD4maze10Steered_MDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Steered_MD.cpp.gcov.html b/coverage/maze/Steered_MD.cpp.gcov.html new file mode 100644 index 000000000000..229c0a2be6c8 --- /dev/null +++ b/coverage/maze/Steered_MD.cpp.gcov.html @@ -0,0 +1,253 @@ + + + + + + + + LCOV - plumed test coverage - maze/Steered_MD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Steered_MD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:313296.9 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /**
+      24             :  * @file Steered_MD.cpp
+      25             :  *
+      26             :  * @author J. Rydzewski (jr@fizyka.umk.pl)
+      27             :  */
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "Optimizer.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace maze {
+      34             : 
+      35             : //+PLUMEDOC MAZE_OPTIMIZER MAZE_STEERED_MD
+      36             : /*
+      37             : 
+      38             : Performs a linear unbinding along a predefined biasing direction that
+      39             : needs to be provided using the PULLING keyword.
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : Every optimizer implemented in the maze module needs a loss function as
+      44             : an argument, and it should be passed using the \ref MAZE_LOSS keyword.
+      45             : 
+      46             : \plumedfile
+      47             : MAZE_STEERED_MD ...
+      48             :   LABEL=smd
+      49             : 
+      50             :   LOSS=l
+      51             :   PULLING=0.3,0.3,0.3
+      52             :   OPTIMIZER_STRIDE=_
+      53             : 
+      54             :   LIGAND=2635-2646
+      55             :   PROTEIN=1-2634
+      56             : ... MAZE_STEERED_MD
+      57             : \endplumedfile
+      58             : 
+      59             : As shown above, each optimizer should be provided with the LIGAND and
+      60             : the PROTEIN keywords.
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : /**
+      66             :  * @class Steered_MD Steered_MD.cpp "maze/Steered_MD.cpp"
+      67             :  * @brief Performs steered MD simulation.
+      68             :  */
+      69             : class Steered_MD: public Optimizer {
+      70             : public:
+      71             :   /**
+      72             :    * PLMD constructor.
+      73             :    *
+      74             :    * @param[in] ao PLMD::ActionOptions&
+      75             :    */
+      76             :   explicit Steered_MD(const ActionOptions& ao);
+      77             : 
+      78             :   /**
+      79             :    * Registers PLMD keywords.
+      80             :    *
+      81             :    * @param[in] keys PLMD keywords
+      82             :    */
+      83             :   static void registerKeywords(Keywords&);
+      84             : 
+      85             :   /**
+      86             :    * Each class deriving from Optimizer needs to override this function.
+      87             :    */
+      88             :   void optimize() override;
+      89             : 
+      90             : private:
+      91             :   //! Total distance traveled by the ligand.
+      92             :   double total_dist_;
+      93             : 
+      94             :   //! Ligand center of mass.
+      95             :   Vector com_;
+      96             : 
+      97             :   //! Constant direction of biasing.
+      98             :   Vector pulling_;
+      99             : 
+     100             :   //! PLMD::Value of total distance.
+     101             :   Value* value_total_dist_;
+     102             : };
+     103             : 
+     104             : // Register MAZE_STEERED_MD.
+     105             : PLUMED_REGISTER_ACTION(Steered_MD, "MAZE_STEERED_MD")
+     106             : 
+     107           3 : void Steered_MD::registerKeywords(Keywords& keys) {
+     108           3 :   Optimizer::registerKeywords(keys);
+     109             : 
+     110           3 :   keys.remove("N_ITER");
+     111             : 
+     112           6 :   keys.add(
+     113             :     "compulsory",
+     114             :     "PULLING",
+     115             :     "Constant biasing direction."
+     116             :   );
+     117             : 
+     118           6 :   keys.addOutputComponent(
+     119             :     "tdist",
+     120             :     "default",
+     121             :     "Total distance traveled by biased atoms."
+     122             :   );
+     123           3 : }
+     124             : 
+     125           1 : Steered_MD::Steered_MD(const ActionOptions& ao)
+     126             :   : PLUMED_OPT_INIT(ao),
+     127           1 :     total_dist_(0.0)
+     128             : {
+     129           1 :   log.printf("maze> Steered MD.\n");
+     130             : 
+     131           2 :   if (keywords.exists("PULLING")) {
+     132             :     std::vector<double> v;
+     133           1 :     parseVector("PULLING", v);
+     134           1 :     pulling_ = tls::vector2Vector(v);
+     135             : 
+     136           1 :     log.printf("maze> PULLING read.\n");
+     137             :   }
+     138             : 
+     139           2 :   set_label("STEERED_MD");
+     140             :   set_opt(pulling_);
+     141             :   set_opt_value(0.0);
+     142             : 
+     143             :   start_step_stride();
+     144             : 
+     145           1 :   checkRead();
+     146             : 
+     147           1 :   com_ = center_of_mass();
+     148             : 
+     149           2 :   addComponent("tdist");
+     150           1 :   componentIsNotPeriodic("tdist");
+     151           1 :   value_total_dist_ = getPntrToComponent("tdist");
+     152           1 : }
+     153             : 
+     154           2 : void Steered_MD::optimize() {
+     155           2 :   Vector c = center_of_mass();
+     156           2 :   Vector d;
+     157             : 
+     158           2 :   if (pbc_) {
+     159           2 :     d = pbcDistance(c, com_);
+     160             :   }
+     161             :   else {
+     162           0 :     d = delta(c, com_);
+     163             :   }
+     164             : 
+     165           2 :   double dist = d.modulo();
+     166           2 :   total_dist_ += dist;
+     167             : 
+     168             :   set_opt(pulling_);
+     169           2 :   set_opt_value(score());
+     170           2 :   com_ = c;
+     171             : 
+     172           2 :   value_total_dist_->set(total_dist_);
+     173           2 : }
+     174             : 
+     175             : } // namespace maze
+     176             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Tools.h.func-sort-c.html b/coverage/maze/Tools.h.func-sort-c.html new file mode 100644 index 000000000000..cb8881801032 --- /dev/null +++ b/coverage/maze/Tools.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Tools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3tls13vector2VectorIdEENS_13VectorGenericILj3EEERKSt6vectorIT_SaIS6_EE1
_ZN4PLMD4maze3tls19get_pointers_labelsIPNS0_9OptimizerEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_1
_ZN4PLMD4maze3tls19get_pointers_labelsIPNS0_4LossEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_7
_ZN4PLMD4maze3tls3sgnIdEEiT_30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Tools.h.func.html b/coverage/maze/Tools.h.func.html new file mode 100644 index 000000000000..b9808b37ad7f --- /dev/null +++ b/coverage/maze/Tools.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - maze/Tools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4maze3tls13vector2VectorIdEENS_13VectorGenericILj3EEERKSt6vectorIT_SaIS6_EE1
_ZN4PLMD4maze3tls19get_pointers_labelsIPNS0_4LossEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_7
_ZN4PLMD4maze3tls19get_pointers_labelsIPNS0_9OptimizerEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_1
_ZN4PLMD4maze3tls3sgnIdEEiT_30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/Tools.h.gcov.html b/coverage/maze/Tools.h.gcov.html new file mode 100644 index 000000000000..b6a0c7057357 --- /dev/null +++ b/coverage/maze/Tools.h.gcov.html @@ -0,0 +1,257 @@ + + + + + + + + LCOV - plumed test coverage - maze/Tools.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - maze - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2019 Jakub Rydzewski (jr@fizyka.umk.pl). All rights reserved.
+       3             : 
+       4             : See http://www.maze-code.github.io for more information.
+       5             : 
+       6             : This file is part of maze.
+       7             : 
+       8             : maze is free software: you can redistribute it and/or modify it under the
+       9             : terms of the GNU Lesser General Public License as published by the Free
+      10             : Software Foundation, either version 3 of the License, or (at your option)
+      11             : any later version.
+      12             : 
+      13             : maze is distributed in the hope that it will be useful, but WITHOUT ANY
+      14             : WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+      15             : FOR A PARTICULAR PURPOSE.
+      16             : 
+      17             : See the GNU Lesser General Public License for more details.
+      18             : 
+      19             : You should have received a copy of the GNU Lesser General Public License
+      20             : along with maze. If not, see <https://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_maze_Tools_h
+      23             : #define __PLUMED_maze_Tools_h
+      24             : 
+      25             : /**
+      26             :  * @file Tools.h
+      27             :  *
+      28             :  * @author J. Rydzewski
+      29             :  */
+      30             : 
+      31             : #include "core/ActionSet.h"
+      32             : #include "tools/Vector.h"
+      33             : #include "Core.h"
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace maze {
+      37             : 
+      38             : /**
+      39             :  * @class tls Tools.h "maze/Tools.h"
+      40             :  *
+      41             :  * @brief Helper functions.
+      42             :  */
+      43             : class tls {
+      44             : public:
+      45             :   template<typename T> static int sgn(T val);
+      46             : 
+      47             :   template<typename T>
+      48             :   static std::vector<std::string> get_labels_actions(const ActionSet&);
+      49             : 
+      50             :   template<typename T>
+      51             :   static T get_pointer_label(
+      52             :     const std::string&,
+      53             :     const ActionSet&, std::string&
+      54             :   );
+      55             : 
+      56             :   template<typename T>
+      57             :   static std::vector<T> get_pointers_labels(
+      58             :     const std::vector<std::string>&,
+      59             :     const ActionSet&, std::string&
+      60             :   );
+      61             : 
+      62             :   template<typename T>
+      63             :   static std::vector<T> Vector2vector(const Vector&);
+      64             : 
+      65             :   template<typename T>
+      66             :   static Vector vector2Vector(const std::vector<T>&);
+      67             : 
+      68             :   template<typename T>
+      69             :   static T vector_l(const std::vector<T>&);
+      70             : 
+      71             :   template<typename T>
+      72             :   static std::vector<T> vector_n(const std::vector<T>&);
+      73             : 
+      74             :   template<typename T>
+      75             :   static T mean(const std::vector<T>&);
+      76             : 
+      77             :   template<typename T>
+      78             :   static T std(const std::vector<T>&);
+      79             : 
+      80             :   struct delete_ptr {
+      81             :     template<typename T> void operator()(T t) {
+      82             :       delete t;
+      83             :     }
+      84             :   };
+      85             : };
+      86             : 
+      87             : template<typename T>
+      88             : T tls::std(const std::vector<T>& v) {
+      89             :   T m=mean(v);
+      90             :   T sq_sum=std::inner_product(v.begin(), v.end(), v.begin(), 0.0);
+      91             : 
+      92             :   return std::sqrt(sq_sum/v.size()-m*m);
+      93             : }
+      94             : 
+      95             : template<typename T>
+      96             : T tls::mean(const std::vector<T>& v) {
+      97             :   return std::accumulate(v.begin(), v.end(), 0.0)/v.size();
+      98             : }
+      99             : 
+     100             : template<typename T>
+     101             : T tls::vector_l(const std::vector<T>& v) {
+     102             :   return std::sqrt(std::inner_product(v.begin(), v.end(), v.begin(), 0.0));
+     103             : }
+     104             : 
+     105             : template<typename T>
+     106             : std::vector<T> tls::vector_n(const std::vector<T>& v) {
+     107             :   double l=vector_l(v);
+     108             :   std::vector<double> n;
+     109             :   for(std::size_t i=0; i<v.size(); ++i)
+     110             :     n.push_back(v[i]/l);
+     111             : 
+     112             :   return n;
+     113             : }
+     114             : 
+     115             : template<typename T>
+     116             : std::vector<T> tls::Vector2vector(const Vector& v) {
+     117             :   std::vector<T> t= {v[0], v[1], v[2]};
+     118             : 
+     119             :   return t;
+     120             : }
+     121             : 
+     122             : template<typename T>
+     123           1 : Vector tls::vector2Vector(const std::vector<T>& v) {
+     124           1 :   Vector t(v[0], v[1], v[2]);
+     125             : 
+     126           1 :   return t;
+     127             : }
+     128             : 
+     129             : template<typename T>
+     130          30 : int tls::sgn(T val) {
+     131          30 :   return (T(0)<val)-(val<T(0));
+     132             : }
+     133             : 
+     134             : template<typename T>
+     135             : std::vector<std::string> tls::get_labels_actions(const ActionSet& actionset) {
+     136             :   std::vector<std::string> action_str(0);
+     137             :   std::vector<T> action_pntrs=actionset.select<T>();
+     138             : 
+     139             :   for(unsigned int i=0; i<action_pntrs.size(); i++)
+     140             :     action_str.push_back(action_pntrs[i]->getLabel());
+     141             : 
+     142             :   return action_str;
+     143             : }
+     144             : 
+     145             : template<typename T> T
+     146             : tls::get_pointer_label(
+     147             :   const std::string& action_label,
+     148             :   const ActionSet& actionset,
+     149             :   std::string& error_msg) {
+     150             : 
+     151             :   std::vector<std::string> action_labels(1);
+     152             :   action_labels[0]=action_label;
+     153             :   std::vector<T> action_pntrs=get_pointers_labels<T>(action_labels, actionset, error_msg);
+     154             : 
+     155             :   return action_pntrs[0];
+     156             : }
+     157             : 
+     158             : template<typename T>
+     159           8 : std::vector<T> tls::get_pointers_labels(
+     160             :   const std::vector<std::string>& action_labels,
+     161             :   const ActionSet& actionset,
+     162             :   std::string& error_msg) {
+     163             : 
+     164           8 :   std::vector<T> action_pntrs(action_labels.size(), NULL);
+     165             :   error_msg="";
+     166           8 :   std::vector<std::string> missing(0);
+     167             : 
+     168          16 :   for(unsigned int i=0; i<action_labels.size(); i++) {
+     169           8 :     action_pntrs[i]=actionset.selectWithLabel<T>(action_labels[i]);
+     170           8 :     if(action_pntrs[i]==NULL)
+     171           0 :       missing.push_back(action_labels[i]);
+     172             :   }
+     173             : 
+     174           8 :   return action_pntrs;
+     175           8 : }
+     176             : 
+     177             : } // namespace maze
+     178             : } // namespace PLMD
+     179             : 
+     180             : #endif // __PLUMED_maze_Tools_h
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/index-sort-f.html b/coverage/maze/index-sort-f.html new file mode 100644 index 000000000000..3cb0faf04b3a --- /dev/null +++ b/coverage/maze/index-sort-f.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:65476885.2 %
Date:2024-02-22 21:58:45Functions:658180.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Loss.h +
50.0%50.0%
+
50.0 %1 / 266.7 %2 / 3
Memetic.h +
61.2%61.2%
+
61.2 %123 / 20170.0 %14 / 20
Random_Acceleration_MD.cpp +
95.1%95.1%
+
95.1 %39 / 4175.0 %3 / 4
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Loss.cpp +
100.0%
+
100.0 %23 / 2375.0 %3 / 4
Random_Walk.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
Steered_MD.cpp +
96.9%96.9%
+
96.9 %31 / 3275.0 %3 / 4
Memetic.cpp +
100.0%
+
100.0 %60 / 6075.0 %3 / 4
Simulated_Annealing.cpp +
87.8%87.8%
+
87.8 %43 / 4980.0 %4 / 5
Optimizer_Bias.cpp +
97.9%97.9%
+
97.9 %95 / 9783.3 %5 / 6
Optimizer.cpp +
90.0%90.0%
+
90.0 %162 / 18090.0 %9 / 10
Optimizer.h +
100.0%
+
100.0 %13 / 13100.0 %1 / 1
Member.h +
100.0%
+
100.0 %5 / 5100.0 %2 / 2
Tools.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %4 / 4
Random_MT.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/index-sort-l.html b/coverage/maze/index-sort-l.html new file mode 100644 index 000000000000..c6ab474c4e6e --- /dev/null +++ b/coverage/maze/index-sort-l.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:65476885.2 %
Date:2024-02-22 21:58:45Functions:658180.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Loss.h +
50.0%50.0%
+
50.0 %1 / 266.7 %2 / 3
Memetic.h +
61.2%61.2%
+
61.2 %123 / 20170.0 %14 / 20
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Simulated_Annealing.cpp +
87.8%87.8%
+
87.8 %43 / 4980.0 %4 / 5
Optimizer.cpp +
90.0%90.0%
+
90.0 %162 / 18090.0 %9 / 10
Tools.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %4 / 4
Random_Acceleration_MD.cpp +
95.1%95.1%
+
95.1 %39 / 4175.0 %3 / 4
Steered_MD.cpp +
96.9%96.9%
+
96.9 %31 / 3275.0 %3 / 4
Optimizer_Bias.cpp +
97.9%97.9%
+
97.9 %95 / 9783.3 %5 / 6
Member.h +
100.0%
+
100.0 %5 / 5100.0 %2 / 2
Optimizer.h +
100.0%
+
100.0 %13 / 13100.0 %1 / 1
Random_Walk.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
Random_MT.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
Loss.cpp +
100.0%
+
100.0 %23 / 2375.0 %3 / 4
Memetic.cpp +
100.0%
+
100.0 %60 / 6075.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/maze/index.html b/coverage/maze/index.html new file mode 100644 index 000000000000..aa4fd405b100 --- /dev/null +++ b/coverage/maze/index.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - maze + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - mazeHitTotalCoverage
Test:plumed test coverageLines:65476885.2 %
Date:2024-02-22 21:58:45Functions:658180.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Loss.cpp +
100.0%
+
100.0 %23 / 2375.0 %3 / 4
Loss.h +
50.0%50.0%
+
50.0 %1 / 266.7 %2 / 3
Member.h +
100.0%
+
100.0 %5 / 5100.0 %2 / 2
Memetic.cpp +
100.0%
+
100.0 %60 / 6075.0 %3 / 4
Memetic.h +
61.2%61.2%
+
61.2 %123 / 20170.0 %14 / 20
Optimizer.cpp +
90.0%90.0%
+
90.0 %162 / 18090.0 %9 / 10
Optimizer.h +
100.0%
+
100.0 %13 / 13100.0 %1 / 1
Optimizer_Bias.cpp +
97.9%97.9%
+
97.9 %95 / 9783.3 %5 / 6
Random_Acceleration_MD.cpp +
95.1%95.1%
+
95.1 %39 / 4175.0 %3 / 4
Random_MT.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
Random_MT.h +
70.6%70.6%
+
70.6 %12 / 1775.0 %3 / 4
Random_Walk.cpp +
100.0%
+
100.0 %14 / 1475.0 %3 / 4
Simulated_Annealing.cpp +
87.8%87.8%
+
87.8 %43 / 4980.0 %4 / 5
Steered_MD.cpp +
96.9%96.9%
+
96.9 %31 / 3275.0 %3 / 4
Tools.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %4 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html b/coverage/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html new file mode 100644 index 000000000000..e67b1ca47f84 --- /dev/null +++ b/coverage/membranefusion/FusionPoreExpansionP.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreExpansionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreExpansionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13715787.3 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion20fusionPoreExpansionPC2ERKNS_13ActionOptionsE0
_ZN4PLMD14membranefusion20fusionPoreExpansionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion20fusionPoreExpansionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion20fusionPoreExpansionP9calculateEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreExpansionP.cpp.func.html b/coverage/membranefusion/FusionPoreExpansionP.cpp.func.html new file mode 100644 index 000000000000..0e74aa066479 --- /dev/null +++ b/coverage/membranefusion/FusionPoreExpansionP.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreExpansionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreExpansionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13715787.3 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion20fusionPoreExpansionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion20fusionPoreExpansionP9calculateEv4
_ZN4PLMD14membranefusion20fusionPoreExpansionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion20fusionPoreExpansionPC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreExpansionP.cpp.gcov.html b/coverage/membranefusion/FusionPoreExpansionP.cpp.gcov.html new file mode 100644 index 000000000000..003e9280814e --- /dev/null +++ b/coverage/membranefusion/FusionPoreExpansionP.cpp.gcov.html @@ -0,0 +1,682 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreExpansionP.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreExpansionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13715787.3 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2022.
+       3             : 
+       4             : CVs originally developed by the Jochen Hub group from the University of Saarland (Germany)
+       5             : and adapted and implemented in PLUMED by Ary Lautaro Di Bartolo and Diego Masone from the
+       6             : National University of Cuyo (Argentina).
+       7             : 
+       8             : The membranefusion module is free software: you can redistribute it and/or modify
+       9             : it under the terms of the GNU Lesser General Public License as published by
+      10             : the Free Software Foundation, either version 3 of the License, or
+      11             : (at your option) any later version.
+      12             : 
+      13             : The membranefusion module is distributed in the hope that it will be useful,
+      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      16             : GNU Lesser General Public License for more details.
+      17             : 
+      18             : You should have received a copy of the GNU Lesser General Public License
+      19             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      20             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      21             : #include "colvar/Colvar.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include <cmath>
+      24             : #ifdef _OPENMP
+      25             : #if _OPENMP >= 201307
+      26             : #include <omp.h>
+      27             : #endif
+      28             : #endif
+      29             : 
+      30             : namespace PLMD
+      31             : {
+      32             : namespace membranefusion
+      33             : {
+      34             : //+PLUMEDOC MEMBRANEFUSIONMOD_COLVAR FUSIONPOREEXPANSIONP
+      35             : /*
+      36             : A CV for inducing the expansion of a fusion pore from a nucleated fusion pore.
+      37             : 
+      38             : Calculate the collective variable designed by Hub \cite Hub2021  and implemented into PLUMED by Masone and collaborators.
+      39             : This CV is capable of inducing the expansion of the fusion pore from a nucleated fusion pore.
+      40             : 
+      41             : \f[
+      42             : \xi_e = \frac{R(r) - R_0}{R_0}
+      43             : \f]
+      44             : 
+      45             : Where \f$\xi_e\f$ is the CV, \f$R_0\f$ is a normalization constant that makes zero the initial value of \f$\xi_e\f$, and
+      46             : \f$R(r)\f$ is the approximate radius of the fusion pore, which is defined by the number of waters and phosphateoxygens
+      47             : beads within a horizontal layer in the center of both membranes.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : This example induces the expansion of a nucleated fusion pore (\f$\xi_e = 0.75\f$) from a just nucleated fusion pore (\f$\xi_e = 0.00\f$).
+      52             : 
+      53             : \plumedfile
+      54             : lMem: GROUP ATOMS=1-10752,21505-22728,23953-24420 #All the lower membrane beads.
+      55             : uMem: GROUP ATOMS=10753-21504,22729-23952,24421-24888 #All the upper membrane beads.
+      56             : tails: GROUP ATOMS=8-23948:12,12-23952:12,23966-24884:18,23970-24888:18 #All the lipid tails beads (from the lower and upper membrane).
+      57             : waters: GROUP ATOMS=24889-56589  #All the water beads.
+      58             : po4: GROUP ATOMS=2-23942:12,23957-24875:18 #All the lipid phosphateoxygens beads.
+      59             : 
+      60             : fusionPoreExpansion: FUSIONPOREEXPANSIONP UMEMBRANE=uMem LMEMBRANE=lMem TAILS=tails WATERS=waters PHOSPHATEOXYGENS=po4 NSMEM=85 D=7.0 R0=0.57
+      61             : 
+      62             : MOVINGRESTRAINT ...
+      63             :     ARG=fusionPoreExpansion
+      64             :     STEP0=0 AT0=0.0 KAPPA0=10000.0
+      65             :     STEP1=500000 AT1=0.75 KAPPA1=10000.0
+      66             : ...
+      67             : 
+      68             : PRINT ARG=fusionPoreExpansion FILE=COLVAR STRIDE=1
+      69             : 
+      70             : \endplumedfile
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : class fusionPoreExpansionP : public Colvar
+      75             : {
+      76             :   std::vector<AtomNumber> UMEM, LMEM, TAILS, WATERS, POXYGENS;
+      77             :   std::vector<double> NSMEM, DSMEM, HMEM, VO, D, H, RMAX, R0, XCYL, YCYL;
+      78             : 
+      79             : public:
+      80             :   explicit fusionPoreExpansionP(const ActionOptions &);
+      81             :   void calculate() override;
+      82             :   static void registerKeywords(Keywords &keys);
+      83             : };
+      84             : 
+      85             : PLUMED_REGISTER_ACTION(fusionPoreExpansionP, "FUSIONPOREEXPANSIONP")
+      86             : 
+      87           3 : void fusionPoreExpansionP::registerKeywords(Keywords &keys)
+      88             : {
+      89           3 :   Colvar::registerKeywords(keys);
+      90           6 :   keys.add("atoms", "UMEMBRANE", "all the beads of the upper membrane.");
+      91           6 :   keys.add("atoms", "LMEMBRANE", "all the beads of the lower membrane.");
+      92           6 :   keys.add("atoms", "TAILS", "all the tail beads of the system.");
+      93           6 :   keys.add("atoms", "WATERS", "all the water beads of the system.");
+      94           6 :   keys.add("atoms", "PHOSPHATEOXYGENS", "all the lipid phosphateoxygens beads of the system.");
+      95           6 :   keys.add("compulsory", "NSMEM", "the number of slices of the membrane fusion cylinder.");
+      96           6 :   keys.add("optional", "DSMEM", "( default=0.1 ) thickness of the slices of the membrane fusion cylinder.");
+      97           6 :   keys.add("optional", "HMEM", "( default=0.25 ) parameter of the step function θ(x,h) for the membrane fusion.");
+      98           6 :   keys.add("optional", "VO", "( default=0.076879 ) beads' molecular volume.");
+      99           6 :   keys.add("compulsory", "D", "horizontal layer thickness, it depends on the Z separation of the membranes.");
+     100           6 :   keys.add("optional", "H", "( default=0.1 ) parameter of the step function θ(x,h) for the fusion pore expansion.");
+     101           6 :   keys.add("optional", "RMAX", "( default=2.5 ) to avoid effects of membrane undulations in large membranes (more than 256 lipids).");
+     102           6 :   keys.add("compulsory", "R0", "normalization constant that makes 0 the initial value of the CV.");
+     103           6 :   keys.add("optional", "XCYL", "X coordinate of the fixed cylinder, if not present this will be calculated.");
+     104           6 :   keys.add("optional", "YCYL", "X coordinate of the fixed cylinder, if not present this will be calculated.");
+     105           3 : }
+     106             : 
+     107           1 : fusionPoreExpansionP::fusionPoreExpansionP(const ActionOptions &ao) : PLUMED_COLVAR_INIT(ao)
+     108             : {
+     109           2 :   parseAtomList("UMEMBRANE", UMEM);
+     110           1 :   if (UMEM.size() == 0)
+     111           0 :     error("UMEMBRANE has not any atom specified.");
+     112             : 
+     113           2 :   parseAtomList("LMEMBRANE", LMEM);
+     114           1 :   if (LMEM.size() == 0)
+     115           0 :     error("LMEMBRANE has not any atom specified.");
+     116             : 
+     117           2 :   parseAtomList("TAILS", TAILS);
+     118           1 :   if (TAILS.size() == 0)
+     119           0 :     error("TAILS has not any atom specified.");
+     120             : 
+     121           2 :   parseAtomList("WATERS", WATERS);
+     122           1 :   if (WATERS.size() == 0)
+     123           0 :     error("WATERS has not any atom specified.");
+     124             : 
+     125           2 :   parseAtomList("PHOSPHATEOXYGENS", POXYGENS);
+     126           1 :   if (POXYGENS.size() == 0)
+     127           0 :     error("PHOSPHATEOXYGENS has not any atom specified.");
+     128             : 
+     129           2 :   parseVector("NSMEM", NSMEM);
+     130           1 :   if (NSMEM.size() > 1)
+     131           0 :     error("NSMEM cannot take more than one value.");
+     132             : 
+     133           2 :   parseVector("DSMEM", DSMEM);
+     134           1 :   if (DSMEM.size() > 1)
+     135           0 :     error("DSMEM cannot take more than one value.");
+     136           1 :   if (DSMEM.size() == 0)
+     137           0 :     DSMEM.push_back(0.1);
+     138             : 
+     139           2 :   parseVector("HMEM", HMEM);
+     140           1 :   if (HMEM.size() > 1)
+     141           0 :     error("HMEM cannot take more than one value.");
+     142           1 :   if (HMEM.size() == 0)
+     143           0 :     HMEM.push_back(0.25);
+     144             : 
+     145           2 :   parseVector("VO", VO);
+     146           1 :   if (VO.size() > 1)
+     147           0 :     error("VO cannot take more than one value.");
+     148           1 :   if (VO.size() == 0)
+     149           0 :     VO.push_back(0.076879);
+     150             : 
+     151           2 :   parseVector("D", D);
+     152           1 :   if (D.size() > 1)
+     153           0 :     error("D cannot take more than one value.");
+     154             : 
+     155           2 :   parseVector("H", H);
+     156           1 :   if (H.size() > 1)
+     157           0 :     error("H cannot take more than one value.");
+     158           1 :   if (H.size() == 0)
+     159           0 :     H.push_back(0.1);
+     160             : 
+     161           2 :   parseVector("RMAX", RMAX);
+     162           1 :   if (RMAX.size() > 1)
+     163           0 :     error("RMAX cannot take more than one value.");
+     164           1 :   if (RMAX.size() == 0)
+     165           0 :     RMAX.push_back(2.5);
+     166             : 
+     167           2 :   parseVector("R0", R0);
+     168           1 :   if (R0.size() > 1)
+     169           0 :     error("R0 cannot take more than one value.");
+     170             : 
+     171           2 :   parseVector("XCYL", XCYL);
+     172           1 :   if (XCYL.size() > 1)
+     173           0 :     error("XCYL cannot take more than one value.");
+     174           1 :   if (XCYL.size() == 0)
+     175           1 :     XCYL.push_back(-1.0);
+     176             : 
+     177           2 :   parseVector("YCYL", YCYL);
+     178           1 :   if (YCYL.size() > 1)
+     179           0 :     error("YCYL cannot take more than one value.");
+     180           1 :   if (YCYL.size() == 0)
+     181           1 :     YCYL.push_back(-1.0);
+     182             : 
+     183           1 :   checkRead();
+     184             : 
+     185             :   std::vector<AtomNumber> atoms;
+     186       12445 :   for (unsigned i = 0; i < UMEM.size(); i++)
+     187             :   {
+     188       12444 :     atoms.push_back(UMEM[i]);
+     189             :   }
+     190       12445 :   for (unsigned i = 0; i < LMEM.size(); i++)
+     191             :   {
+     192       12444 :     atoms.push_back(LMEM[i]);
+     193             :   }
+     194        4097 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     195             :   {
+     196        4096 :     atoms.push_back(TAILS[i]);
+     197             :   }
+     198       31800 :   for (unsigned i = 0; i < WATERS.size(); i++)
+     199             :   {
+     200       31799 :     atoms.push_back(WATERS[i]);
+     201             :   }
+     202        2049 :   for (unsigned i = 0; i < POXYGENS.size(); i++)
+     203             :   {
+     204        2048 :     atoms.push_back(POXYGENS[i]);
+     205             :   }
+     206             : 
+     207           1 :   addValueWithDerivatives();
+     208           1 :   setNotPeriodic();
+     209           1 :   requestAtoms(atoms);
+     210           1 : }
+     211           4 : void fusionPoreExpansionP::calculate()
+     212             : {
+     213             :   /*************************
+     214             :   *                        *
+     215             :   *         System         *
+     216             :   *                        *
+     217             :   **************************/
+     218             : 
+     219             :   // Box dimensions.
+     220           4 :   double Lx = getBox()[0][0], Ly = getBox()[1][1], Lz = getBox()[2][2];
+     221             : 
+     222             :   // Z center of the upper membrane (uMem) and lower membrane (lMem) for systems with PBC: https://en.wikipedia.org/wiki/Center_of_mass#Systems_with_periodic_boundary_conditions .
+     223             :   double ZuMem, ZuMemcos = 0.0, ZuMemsin = 0.0, uMemAngle, ZlMem, ZlMemcos = 0.0, ZlMemsin = 0.0, lMemAngle;
+     224             : 
+     225             : #ifdef _OPENMP
+     226             : #if _OPENMP >= 201307
+     227           4 :   #pragma omp parallel for private(uMemAngle, lMemAngle) reduction(+:ZuMemcos, ZuMemsin, ZlMemcos, ZlMemsin)
+     228             : #endif
+     229             : #endif
+     230             :   for (unsigned i = 0; i < UMEM.size(); i++)
+     231             :   {
+     232             :     uMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     233             :     lMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + UMEM.size())))[2];
+     234             :     ZuMemcos += cos(uMemAngle);
+     235             :     ZuMemsin += sin(uMemAngle);
+     236             :     ZlMemcos += cos(lMemAngle);
+     237             :     ZlMemsin += sin(lMemAngle);
+     238             :   }
+     239           4 :   ZuMemcos = ZuMemcos / UMEM.size();
+     240           4 :   ZuMemsin = ZuMemsin / UMEM.size();
+     241           4 :   ZuMem = Lz * (atan2(-ZuMemsin, -ZuMemcos) + M_PI) / (2.0 * M_PI);
+     242           4 :   ZlMemcos = ZlMemcos / UMEM.size();
+     243           4 :   ZlMemsin = ZlMemsin / UMEM.size();
+     244           4 :   ZlMem = Lz * (atan2(-ZlMemsin, -ZlMemcos) + M_PI) / (2.0 * M_PI);
+     245             : 
+     246             :   // Z center of the boths membranes (upper and lower).
+     247           4 :   double ZMems = (ZuMem + ZlMem) / 2.0;
+     248             : 
+     249             :   /**************************
+     250             :   *                         *
+     251             :   *   Xcyl_Mem & Ycyl_Mem   *
+     252             :   *                         *
+     253             :   ***************************/
+     254             : 
+     255             :   // Quantity of beads of the membranes.
+     256           4 :   unsigned membraneBeads = UMEM.size() + LMEM.size();
+     257             : 
+     258             :   // Z distance from the lipid tail to the geometric center of both membranes.
+     259             :   double ZTailDistance;
+     260             : 
+     261             :   // Z position of the first slice.
+     262           4 :   double firstSliceZ_Mem = ZMems + (0.0 + 0.5 - NSMEM[0] / 2.0) * DSMEM[0];
+     263             : 
+     264             :   // Z distance between the first slice and the Z center of the membrane.
+     265           8 :   double firstSliceZDist_Mem = pbcDistance(Vector(0.0, 0.0, firstSliceZ_Mem), Vector(0.0, 0.0, ZMems))[2];
+     266             : 
+     267             :   // Position in the cylinder.
+     268             :   double PositionS_Mem;
+     269             : 
+     270             :   // Slices to analyze per particle.
+     271             :   unsigned s1_Mem, s2_Mem;
+     272             : 
+     273             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     274           4 :   std::vector<double> faxial_Mem(TAILS.size() * NSMEM[0]);
+     275             : 
+     276             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     277           4 :   std::vector<double> Fs_Mem(NSMEM[0]);
+     278             : 
+     279             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     280           4 :   std::vector<double> ws_Mem(NSMEM[0]);
+     281             : 
+     282             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     283             :   double W_Mem = 0.0;
+     284             : 
+     285             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     286           4 :   std::vector<double> sx_Mem(NSMEM[0]), sy_Mem(NSMEM[0]), cx_Mem(NSMEM[0]), cy_Mem(NSMEM[0]);
+     287             : 
+     288             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     289             :   double Xsc_Mem = 0.0, Xcc_Mem = 0.0, Ysc_Mem = 0.0, Ycc_Mem = 0.0;
+     290             : 
+     291             :   // Aux.
+     292             :   double x, aux;
+     293             : 
+     294             :   // Scaled position of the lipid tail respect the origin of coordinates.
+     295           4 :   Vector TailPosition;
+     296             : 
+     297             : #ifdef _OPENMP
+     298             : #if _OPENMP >= 201307
+     299             :   #pragma omp declare reduction(vec_double_plus : std::vector<double> : \
+     300             :   std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<double>())) \
+     301             :   initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
+     302             : #endif
+     303             : #endif
+     304             : 
+     305             : #ifdef _OPENMP
+     306             : #if _OPENMP >= 201307
+     307           4 :   #pragma omp parallel for private(ZTailDistance, PositionS_Mem, TailPosition, x, aux, s1_Mem, s2_Mem) reduction(vec_double_plus:Fs_Mem, sx_Mem, sy_Mem, cx_Mem, cy_Mem)
+     308             : #endif
+     309             : #endif
+     310             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     311             :   {
+     312             :     ZTailDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + membraneBeads))[2];
+     313             :     PositionS_Mem = (ZTailDistance + firstSliceZDist_Mem) / DSMEM[0];
+     314             :     // If the following condition is met the particle is in the Z space of the cylinder.
+     315             :     if ((PositionS_Mem >= (-0.5 - HMEM[0])) && (PositionS_Mem <= (NSMEM[0] + 0.5 - 1.0 + HMEM[0])))
+     316             :     {
+     317             :       //Defining the slices to analyze each particle.
+     318             :       if (PositionS_Mem < 1)
+     319             :       {
+     320             :         s1_Mem = 0;
+     321             :         s2_Mem = 2;
+     322             :       }
+     323             :       else if (PositionS_Mem <= (NSMEM[0] - 2.0))
+     324             :       {
+     325             :         s1_Mem = floor(PositionS_Mem) - 1;
+     326             :         s2_Mem = floor(PositionS_Mem) + 1;
+     327             :       }
+     328             :       else
+     329             :       {
+     330             :         s1_Mem = NSMEM[0] - 3;
+     331             :         s2_Mem = NSMEM[0] - 1;
+     332             :       }
+     333             : 
+     334             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     335             : 
+     336             :       for (unsigned s = s1_Mem; s <= s2_Mem; s++)
+     337             :       {
+     338             :         x = (ZTailDistance - (s + 0.5 - NSMEM[0] / 2.0) * DSMEM[0]) * 2.0 / DSMEM[0];
+     339             :         if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     340             :         {
+     341             :           if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     342             :           {
+     343             :             faxial_Mem[i + TAILS.size() * s] = 1.0;
+     344             :             Fs_Mem[s] += 1.0;
+     345             :             sx_Mem[s] += sin(2.0 * M_PI * TailPosition[0]);
+     346             :             sy_Mem[s] += sin(2.0 * M_PI * TailPosition[1]);
+     347             :             cx_Mem[s] += cos(2.0 * M_PI * TailPosition[0]);
+     348             :             cy_Mem[s] += cos(2.0 * M_PI * TailPosition[1]);
+     349             :           }
+     350             :           else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     351             :           {
+     352             :             aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     353             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     354             :             Fs_Mem[s] += aux;
+     355             :             sx_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[0]);
+     356             :             sy_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[1]);
+     357             :             cx_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[0]);
+     358             :             cy_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[1]);
+     359             :           }
+     360             :           else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     361             :           {
+     362             :             aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     363             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     364             :             Fs_Mem[s] += aux;
+     365             :             sx_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[0]));
+     366             :             sy_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[1]));
+     367             :             cx_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[0]));
+     368             :             cy_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[1]));
+     369             :           }
+     370             :         }
+     371             :       }
+     372             :     }
+     373             :   }
+     374             : 
+     375         344 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     376             :   {
+     377         340 :     if (Fs_Mem[s] != 0.0)
+     378             :     {
+     379         340 :       ws_Mem[s] = tanh(Fs_Mem[s]);
+     380         340 :       W_Mem += ws_Mem[s];
+     381         340 :       sx_Mem[s] = sx_Mem[s] / Fs_Mem[s];
+     382         340 :       sy_Mem[s] = sy_Mem[s] / Fs_Mem[s];
+     383         340 :       cx_Mem[s] = cx_Mem[s] / Fs_Mem[s];
+     384         340 :       cy_Mem[s] = cy_Mem[s] / Fs_Mem[s];
+     385         340 :       Xsc_Mem += sx_Mem[s] * ws_Mem[s];
+     386         340 :       Ysc_Mem += sy_Mem[s] * ws_Mem[s];
+     387         340 :       Xcc_Mem += cx_Mem[s] * ws_Mem[s];
+     388         340 :       Ycc_Mem += cy_Mem[s] * ws_Mem[s];
+     389             :     }
+     390             :   }
+     391             : 
+     392           4 :   Xsc_Mem = Xsc_Mem / W_Mem;
+     393           4 :   Ysc_Mem = Ysc_Mem / W_Mem;
+     394           4 :   Xcc_Mem = Xcc_Mem / W_Mem;
+     395           4 :   Ycc_Mem = Ycc_Mem / W_Mem;
+     396             : 
+     397             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     398             :   double Xcyl_Mem, Ycyl_Mem;
+     399             : 
+     400           4 :   if ((XCYL[0] > 0.0) && (YCYL[0] > 0.0))
+     401             :   {
+     402             :     Xcyl_Mem = XCYL[0];
+     403             :     Ycyl_Mem = YCYL[0];
+     404             :   }
+     405             :   else
+     406             :   {
+     407           4 :     Xcyl_Mem = (atan2(-Xsc_Mem, -Xcc_Mem) + M_PI) * Lx / (2 * M_PI);
+     408           4 :     Ycyl_Mem = (atan2(-Ysc_Mem, -Ycc_Mem) + M_PI) * Ly / (2 * M_PI);
+     409             :   }
+     410             : 
+     411             :   /*************************
+     412             :   *                        *
+     413             :   *         Xi_Exp         *
+     414             :   *                        *
+     415             :   **************************/
+     416             : 
+     417             :   // Quantity of beads that could participate in the calculation of the Xi_Chain
+     418           4 :   unsigned chainBeads = WATERS.size() + POXYGENS.size();
+     419             : 
+     420             :   // Quantity of beads that don't participate in the calculation of the Xi_Chain
+     421           4 :   unsigned noChainBeads = (UMEM.size() * 2) + TAILS.size();
+     422             : 
+     423             :   // Center of the cylinder. X and Y are calculated (or defined), Z is the Z component of the geometric center of the membranes.
+     424           8 :   Vector xyzCyl = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMems));
+     425             : 
+     426             :   // Estimation of RO with the Hub 2021 JCTC method. Only needed for the expansion.
+     427           4 :   double RO = R0[0];
+     428             : 
+     429             :   // Number of polar atoms inside the horizontal layer. Eq. 3 Hub 2021 JCTC.
+     430             :   double np = 0.0, fz, fr, fz_prime, fr_prime;
+     431             : 
+     432             :   // Derivative of np. Eq. 8 Hub 2021 JCTC.
+     433           4 :   std::vector<double> d_np_dx(chainBeads), d_np_dy(chainBeads), d_np_dz(chainBeads);
+     434             : 
+     435             :   // Pore radius of the defect. Eq. 2 Hub 2021 JCTC.
+     436             :   double poreR = 1.0;
+     437             : 
+     438             :   // Z center of the Membrane in the RMAX radius.
+     439             :   double ZMemRMAX, ZMemRMAXcos = 0.0, ZMemRMAXsin = 0.0, countAux = 0.0, auxcos, auxsin;
+     440             : 
+     441             :   ZMemRMAX = ZMems;
+     442             : 
+     443             :   // The curvature of large membranes (1024 lipids) makes the Z-center of the membranes not to be representative
+     444             :   // in some sectors, particularly in the region of ​​the defect.
+     445             :   //
+     446             :   // To solve this, the center Z of the membranes in the defect sector is calculated and used to calculate
+     447             :   // the number of polar atoms within the horizontal layer AND in the radious of the defect.
+     448             :   //
+     449             :   // ________       | |       ________
+     450             :   // ________ \_____| |______/ _______<-- Top membrane.
+     451             :   //         \______|P|_______/
+     452             :   //                |O|
+     453             :   //                | |               <-- Z-center of the membranes in the region of the defect.
+     454             :   //          ______|R|_______        <-- Z-center of the membranes
+     455             :   //         / _____|E|______ \ 
+     456             :   //        / /     | |      \ \ 
+     457             :   // ______/ /      | |       \ \______
+     458             :   // _______/                  \_______<-- Bottom membrane.
+     459             : 
+     460             :   // Center of mass for systems with PBC: https://en.wikipedia.org/wiki/Center_of_mass#Systems_with_periodic_boundary_conditions
+     461           4 :   Vector MemCylDistances, distCylinder;
+     462             :   double angle, ri;
+     463             : 
+     464             : #ifdef _OPENMP
+     465             : #if _OPENMP >= 201307
+     466           4 :   #pragma omp parallel for private(MemCylDistances, x, angle, auxcos, auxsin) reduction(+:ZMemRMAXcos, ZMemRMAXsin, countAux)
+     467             : #endif
+     468             : #endif
+     469             :   for (unsigned i = 0; i < membraneBeads; i++)
+     470             : {
+     471             :   MemCylDistances = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)));
+     472             :     x = sqrt(pow(MemCylDistances[0], 2) + pow(MemCylDistances[1], 2)) / RMAX[0];
+     473             :     if (!((x <= -1.0 - H[0]) || (x >= 1.0 + H[0])))
+     474             :     {
+     475             :       angle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     476             :       auxcos = cos(angle);
+     477             :       auxsin = sin(angle);
+     478             :       if (((-1.0 + H[0]) <= x) && (x <= (1.0 - H[0])))
+     479             :       {
+     480             :         ZMemRMAXcos += 1.0 * auxcos;
+     481             :         ZMemRMAXsin += 1.0 * auxsin;
+     482             :         countAux += 1.0;
+     483             :       }
+     484             :       else if (((1.0 - H[0]) < x) && (x < (1.0 + H[0])))
+     485             :       {
+     486             :         ZMemRMAXcos += (0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3)) * auxcos;
+     487             :         ZMemRMAXsin += (0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3)) * auxsin;
+     488             :         countAux += (0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3));
+     489             :       }
+     490             :       else if (((-1.0 - H[0]) < x) && (x < (-1.0 + H[0])))
+     491             :       {
+     492             :         ZMemRMAXcos += (0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3)) * auxcos;
+     493             :         ZMemRMAXsin += (0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3)) * auxsin;
+     494             :         countAux += (0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3));
+     495             :       }
+     496             :     }
+     497             :   }
+     498             : 
+     499           4 :   ZMemRMAXcos = ZMemRMAXcos / countAux;
+     500           4 :   ZMemRMAXsin = ZMemRMAXsin / countAux;
+     501           4 :   ZMemRMAX = Lz * (atan2(-ZMemRMAXsin, -ZMemRMAXcos) + M_PI) / (2.0 * M_PI);
+     502             : 
+     503           4 :   xyzCyl = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMemRMAX));
+     504             : 
+     505             : #ifdef _OPENMP
+     506             : #if _OPENMP >= 201307
+     507           4 :   #pragma omp parallel for private(distCylinder, fz, fz_prime, fr, fr_prime, ri, x) reduction(+:np)
+     508             : #endif
+     509             : #endif
+     510             :   for (unsigned i = 0; i < chainBeads; i++)
+     511             : {
+     512             :   distCylinder = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     513             :     fz = 0.0;
+     514             :     fz_prime = 0.0;
+     515             :     fr = 0.0;
+     516             :     fr_prime = 0.0;
+     517             : 
+     518             :     ri = sqrt(pow(distCylinder[0], 2) + pow(distCylinder[1], 2));
+     519             :     x = ri / RMAX[0];
+     520             :     if (!((x <= -1.0 - H[0]) || (x >= 1.0 + H[0])))
+     521             :     {
+     522             :       if (((-1.0 + H[0]) <= x) && (x <= (1.0 - H[0])))
+     523             :       {
+     524             :         fr = 1.0;
+     525             :       }
+     526             :       else if (((1.0 - H[0]) < x) && (x < (1.0 + H[0])))
+     527             :       {
+     528             :         fr = 0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3);
+     529             :         fr_prime = (-0.75 / H[0] + 0.75 * pow((x - 1.0), 2) / pow(H[0], 3)) / (RMAX[0] * ri);
+     530             :       }
+     531             :       else if (((-1.0 - H[0]) < x) && (x < (-1.0 + H[0])))
+     532             :       {
+     533             :         fr = 0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3);
+     534             :         fr_prime = (0.75 / H[0] - 0.75 * pow((x + 1), 2) / pow(H[0], 3)) / (RMAX[0] * ri);
+     535             :       }
+     536             : 
+     537             :       x = distCylinder[2] * 2.0 / D[0];
+     538             :       if (!((x <= -1.0 - H[0]) || (x >= 1.0 + H[0])))
+     539             :       {
+     540             :         if (((-1.0 + H[0]) <= x) && (x <= (1.0 - H[0])))
+     541             :         {
+     542             :           fz = 1.0;
+     543             :         }
+     544             :         else if (((1.0 - H[0]) < x) && (x < (1.0 + H[0])))
+     545             :         {
+     546             :           fz = 0.5 - 0.75 * (x - 1.0) / H[0] + 0.25 * pow((x - 1.0), 3) / pow(H[0], 3);
+     547             :           fz_prime = (-0.75 / H[0] + 0.75 * pow((x - 1.0), 2) / pow(H[0], 3)) * 2.0 / D[0];
+     548             :         }
+     549             :         else if (((-1.0 - H[0]) < x) && (x < (-1.0 + H[0])))
+     550             :         {
+     551             :           fz = 0.5 + 0.75 * (x + 1.0) / H[0] - 0.25 * pow((x + 1.0), 3) / pow(H[0], 3);
+     552             :           fz_prime = (0.75 / H[0] - 0.75 * pow((x + 1), 2) / pow(H[0], 3)) * 2.0 / D[0];
+     553             :         }
+     554             : 
+     555             :         np += fz * fr;
+     556             :         d_np_dx[i] = fz * fr_prime * distCylinder[0];
+     557             :         d_np_dy[i] = fz * fr_prime * distCylinder[1];
+     558             :         d_np_dz[i] = fz_prime * fr;
+     559             :       }
+     560             :     }
+     561             :   }
+     562           4 :   poreR = sqrt(np * VO[0] / (M_PI * D[0]));
+     563             : 
+     564             :   // This is the CV that describes the Pore Expansion.
+     565           4 :   double Xi_Exp = (poreR - RO) / RO;
+     566             : 
+     567             :   // Derivatives vector.
+     568           4 :   std::vector<Vector> derivatives(chainBeads);
+     569             : 
+     570             :   // Aux for the derivatives calculations. Eq. 7 Hub 2021 JCTC.
+     571             :   double fact2 = 0.0;
+     572             : 
+     573           4 :   if (poreR != 0.0)
+     574             : {
+     575           4 :   fact2 = VO[0] / (2.0 * M_PI * RO * D[0] * poreR);
+     576             :   }
+     577             : 
+     578             :   // Distances from the oxygens to center of the cylinder.
+     579           4 :   std::vector<Vector> CylDistances(chainBeads);
+     580             : 
+     581             : #ifdef _OPENMP
+     582             : #if _OPENMP >= 201307
+     583           4 :   #pragma omp parallel for
+     584             : #endif
+     585             : #endif
+     586             :   for (unsigned i = 0; i < chainBeads; i++)
+     587             : {
+     588             :   derivatives[i][0] = fact2 * d_np_dx[i];
+     589             :     derivatives[i][1] = fact2 * d_np_dy[i];
+     590             :     derivatives[i][2] = fact2 * d_np_dz[i];
+     591             :     CylDistances[i] = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     592             :   }
+     593             : 
+     594           4 :   Tensor virial;
+     595      135392 :   for (unsigned i = 0; i < chainBeads; i++)
+     596             : {
+     597      135388 :   setAtomsDerivatives((i + noChainBeads), derivatives[i]);
+     598      135388 :     virial -= Tensor(CylDistances[i], derivatives[i]);
+     599             :   }
+     600             : 
+     601           4 :   setValue(Xi_Exp);
+     602           4 :   setBoxDerivatives(virial);
+     603           4 : }
+     604             : }
+     605             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreNucleationP.cpp.func-sort-c.html b/coverage/membranefusion/FusionPoreNucleationP.cpp.func-sort-c.html new file mode 100644 index 000000000000..0836112acdd4 --- /dev/null +++ b/coverage/membranefusion/FusionPoreNucleationP.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreNucleationP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreNucleationP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18320788.4 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion21fusionPoreNucleationPC2ERKNS_13ActionOptionsE0
_ZN4PLMD14membranefusion21fusionPoreNucleationPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion21fusionPoreNucleationP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion21fusionPoreNucleationP9calculateEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreNucleationP.cpp.func.html b/coverage/membranefusion/FusionPoreNucleationP.cpp.func.html new file mode 100644 index 000000000000..3c6c79992b4f --- /dev/null +++ b/coverage/membranefusion/FusionPoreNucleationP.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreNucleationP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreNucleationP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18320788.4 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion21fusionPoreNucleationP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion21fusionPoreNucleationP9calculateEv4
_ZN4PLMD14membranefusion21fusionPoreNucleationPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion21fusionPoreNucleationPC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/FusionPoreNucleationP.cpp.gcov.html b/coverage/membranefusion/FusionPoreNucleationP.cpp.gcov.html new file mode 100644 index 000000000000..49d9ad12d0c5 --- /dev/null +++ b/coverage/membranefusion/FusionPoreNucleationP.cpp.gcov.html @@ -0,0 +1,884 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/FusionPoreNucleationP.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - FusionPoreNucleationP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18320788.4 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2022.
+       3             : 
+       4             : CVs originally developed by the Jochen Hub group from the University of Saarland (Germany)
+       5             : and adapted and implemented in PLUMED by Ary Lautaro Di Bartolo and Diego Masone from the
+       6             : National University of Cuyo (Argentina).
+       7             : 
+       8             : The membranefusion module is free software: you can redistribute it and/or modify
+       9             : it under the terms of the GNU Lesser General Public License as published by
+      10             : the Free Software Foundation, either version 3 of the License, or
+      11             : (at your option) any later version.
+      12             : 
+      13             : The membranefusion module is distributed in the hope that it will be useful,
+      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      16             : GNU Lesser General Public License for more details.
+      17             : 
+      18             : You should have received a copy of the GNU Lesser General Public License
+      19             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      20             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      21             : #include "colvar/Colvar.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include <cmath>
+      24             : #ifdef _OPENMP
+      25             : #if _OPENMP >= 201307
+      26             : #include <omp.h>
+      27             : #endif
+      28             : #endif
+      29             : 
+      30             : namespace PLMD
+      31             : {
+      32             : namespace membranefusion
+      33             : {
+      34             : //+PLUMEDOC MEMBRANEFUSIONMOD_COLVAR FUSIONPORENUCLEATIONP
+      35             : /*
+      36             : A CV for inducing the nucleation of the fusion pore from a hemifusion stalk.
+      37             : 
+      38             : Calculate the collective variable designed by Hub and collaborators \cite Hub2017 and
+      39             : implemented into PLUMED by Masone and collaborators.
+      40             : This CV is capable of inducing the nucleation of the fusion pore from a hemifusion stalk.
+      41             : 
+      42             : \f[
+      43             : \xi_n = \frac{1}{N_{sn}} \sum_{s=0}^{N_{sn}-1} \delta_{sn} (N_{sn}^{(p)})
+      44             : \f]
+      45             : 
+      46             : Where \f$\xi_n\f$ is the CV, \f$N_{sn}\f$ is the number of slices of the cylinder that make up the CV,
+      47             : \f$\delta_{sn}\f$ is a continuos function in the interval [0 1] (\f$\delta_{sf} = 0\f$ for no beads in the slice s, and
+      48             : \f$\delta_{sf} = 1\f$ for 1 or more beads in the slice s) and \f$N_{sf}^{(p)}\f$ accounts for the number of water and
+      49             : phosphateoxygens beads within the slice s.
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : This example induces the nucleation of the fusion pore (\f$\xi_n = 1.0\f$) from a hemifusion stalk (\f$\xi_n = 0.2\f$).
+      54             : 
+      55             : \plumedfile
+      56             : 
+      57             : lMem: GROUP ATOMS=1-10752,21505-22728,23953-24420 #All the lower membrane beads.
+      58             : uMem: GROUP ATOMS=10753-21504,22729-23952,24421-24888 #All the upper membrane beads.
+      59             : tails: GROUP ATOMS=8-23948:12,12-23952:12,23966-24884:18,23970-24888:18 #All the lipid tails beads (from the lower and upper membrane).
+      60             : waters: GROUP ATOMS=24889-56490 #All the water beads.
+      61             : po4: GROUP ATOMS=2-23942:12,23957-24875:18 #All the lipid phosphateoxygens beads.
+      62             : 
+      63             : fusionPoreNucleation: FUSIONPORENUCLEATIONP UMEMBRANE=uMem LMEMBRANE=lMem TAILS=tails WATERS=waters PHOSPHATEOXYGENS=po4 NSMEM=85 NS=45
+      64             : 
+      65             : MOVINGRESTRAINT ...
+      66             :     ARG=fusionPoreNucleation
+      67             :     STEP0=0 AT0=0.2 KAPPA0=10000.0
+      68             :     STEP1=500000 AT1=1.0 KAPPA1=10000.0
+      69             : ...
+      70             : 
+      71             : PRINT ARG=fusionPoreNucleation FILE=COLVAR STRIDE=1
+      72             : 
+      73             : \endplumedfile
+      74             : 
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : class fusionPoreNucleationP : public Colvar
+      78             : {
+      79             :   std::vector<AtomNumber> UMEM, LMEM, TAILS, WATERS, POXYGENS;
+      80             :   std::vector<double> NSMEM, DSMEM, HMEM, NS, DS, HCH, RCYL, ZETA, ONEOVERS2C2CUTOFF, XCYL, YCYL;
+      81             : 
+      82             : public:
+      83             :   explicit fusionPoreNucleationP(const ActionOptions &);
+      84             :   void calculate() override;
+      85             :   static void registerKeywords(Keywords &keys);
+      86             : };
+      87             : 
+      88             : PLUMED_REGISTER_ACTION(fusionPoreNucleationP, "FUSIONPORENUCLEATIONP")
+      89             : 
+      90           3 : void fusionPoreNucleationP::registerKeywords(Keywords &keys)
+      91             : {
+      92           3 :   Colvar::registerKeywords(keys);
+      93           6 :   keys.add("atoms", "UMEMBRANE", "all the beads of the upper membrane.");
+      94           6 :   keys.add("atoms", "LMEMBRANE", "all the beads of the lower membrane.");
+      95           6 :   keys.add("atoms", "TAILS", "all the tail beads of the system.");
+      96           6 :   keys.add("atoms", "WATERS", "all the water beads of the system.");
+      97           6 :   keys.add("atoms", "PHOSPHATEOXYGENS", "all the lipid phosphateoxygens beads of the system.");
+      98           6 :   keys.add("compulsory", "NSMEM", "the number of slices of the membrane fusion cylinder.");
+      99           6 :   keys.add("optional", "DSMEM", "( default=0.1 ) thickness of the slices of the membrane fusion cylinder.");
+     100           6 :   keys.add("optional", "HMEM", "( default=0.25 ) parameter of the step function θ(x,h) for the membrane fusion.");
+     101           6 :   keys.add("compulsory", "NS", "the number of slices of the membrane-spanning cylinder in such a way that when the bilayers are flat and parallel the CV is equal to 0.2.");
+     102           6 :   keys.add("optional", "DS", "( default=0.25 ) thickness of the slices of the membrane-spanning cylinder.");
+     103           6 :   keys.add("optional", "HCH", "( default=0.25 ) parameter of the step function θ(x,h) for the CV.");
+     104           6 :   keys.add("optional", "RCYL", "( default=0.8 ) the radius of the membrane-spanning cylinder.");
+     105           6 :   keys.add("optional", "ZETA", "( default=0.75 ) parameter of the switch function ψ(x,ζ).");
+     106           6 :   keys.add("optional", "ONEOVERS2C2CUTOFF", "( default=500 ) cut off large values for the derivative of the atan2 function to avoid violate energy.");
+     107           6 :   keys.add("optional", "XCYL", "X coordinate of the fixed cylinder, if not present this will be calculated.");
+     108           6 :   keys.add("optional", "YCYL", "X coordinate of the fixed cylinder, if not present this will be calculated.");
+     109           3 : }
+     110             : 
+     111           1 : fusionPoreNucleationP::fusionPoreNucleationP(const ActionOptions &ao) : PLUMED_COLVAR_INIT(ao)
+     112             : {
+     113           2 :   parseAtomList("UMEMBRANE", UMEM);
+     114           1 :   if (UMEM.size() == 0)
+     115           0 :     error("UMEMBRANE has not any atom specified.");
+     116             : 
+     117           2 :   parseAtomList("LMEMBRANE", LMEM);
+     118           1 :   if (LMEM.size() == 0)
+     119           0 :     error("LMEMBRANE has not any atom specified.");
+     120             : 
+     121           2 :   parseAtomList("TAILS", TAILS);
+     122           1 :   if (TAILS.size() == 0)
+     123           0 :     error("TAILS has not any atom specified.");
+     124             : 
+     125           2 :   parseAtomList("WATERS", WATERS);
+     126           1 :   if (WATERS.size() == 0)
+     127           0 :     error("WATERS has not any atom specified.");
+     128             : 
+     129           2 :   parseAtomList("PHOSPHATEOXYGENS", POXYGENS);
+     130           1 :   if (POXYGENS.size() == 0)
+     131           0 :     error("PHOSPHATEOXYGENS has not any atom specified.");
+     132             : 
+     133           2 :   parseVector("NSMEM", NSMEM);
+     134           1 :   if (NSMEM.size() > 1)
+     135           0 :     error("NSMEM cannot take more than one value.");
+     136             : 
+     137           2 :   parseVector("DSMEM", DSMEM);
+     138           1 :   if (DSMEM.size() > 1)
+     139           0 :     error("DSMEM cannot take more than one value.");
+     140           1 :   if (DSMEM.size() == 0)
+     141           0 :     DSMEM.push_back(0.1);
+     142             : 
+     143           2 :   parseVector("HMEM", HMEM);
+     144           1 :   if (HMEM.size() > 1)
+     145           0 :     error("HMEM cannot take more than one value.");
+     146           1 :   if (HMEM.size() == 0)
+     147           0 :     HMEM.push_back(0.25);
+     148             : 
+     149           2 :   parseVector("NS", NS);
+     150           1 :   if (NS.size() > 1)
+     151           0 :     error("NS cannot take more than one value.");
+     152             : 
+     153           2 :   parseVector("DS", DS);
+     154           1 :   if (DS.size() > 1)
+     155           0 :     error("DS cannot take more than one value.");
+     156           1 :   if (DS.size() == 0)
+     157           0 :     DS.push_back(0.25);
+     158             : 
+     159           2 :   parseVector("HCH", HCH);
+     160           1 :   if (HCH.size() > 1)
+     161           0 :     error("H cannot take more than one value.");
+     162           1 :   if (HCH.size() == 0)
+     163           0 :     HCH.push_back(0.25);
+     164             : 
+     165           2 :   parseVector("RCYL", RCYL);
+     166           1 :   if (RCYL.size() > 1)
+     167           0 :     error("RCYL cannot take more than one value.");
+     168           1 :   if (RCYL.size() == 0)
+     169           0 :     RCYL.push_back(0.8);
+     170             : 
+     171           2 :   parseVector("ZETA", ZETA);
+     172           1 :   if (ZETA.size() > 1)
+     173           0 :     error("ZETA cannot take more than one value.");
+     174           1 :   if (ZETA.size() == 0)
+     175           0 :     ZETA.push_back(0.75);
+     176             : 
+     177           2 :   parseVector("ONEOVERS2C2CUTOFF", ONEOVERS2C2CUTOFF);
+     178           1 :   if (ONEOVERS2C2CUTOFF.size() > 1)
+     179           0 :     error("ONEOVERS2C2CUTOFF cannot take more than one value.");
+     180           1 :   if (ONEOVERS2C2CUTOFF.size() == 0)
+     181           1 :     ONEOVERS2C2CUTOFF.push_back(500);
+     182             : 
+     183           2 :   parseVector("XCYL", XCYL);
+     184           1 :   if (XCYL.size() > 1)
+     185           0 :     error("XCYL cannot take more than one value.");
+     186           1 :   if (XCYL.size() == 0)
+     187           1 :     XCYL.push_back(-1.0);
+     188             : 
+     189           2 :   parseVector("YCYL", YCYL);
+     190           1 :   if (YCYL.size() > 1)
+     191           0 :     error("YCYL cannot take more than one value.");
+     192           1 :   if (YCYL.size() == 0)
+     193           1 :     YCYL.push_back(-1.0);
+     194             : 
+     195           1 :   checkRead();
+     196             : 
+     197             :   std::vector<AtomNumber> atoms;
+     198       12445 :   for (unsigned i = 0; i < UMEM.size(); i++)
+     199             :   {
+     200       12444 :     atoms.push_back(UMEM[i]);
+     201             :   }
+     202       12445 :   for (unsigned i = 0; i < LMEM.size(); i++)
+     203             :   {
+     204       12444 :     atoms.push_back(LMEM[i]);
+     205             :   }
+     206        4097 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     207             :   {
+     208        4096 :     atoms.push_back(TAILS[i]);
+     209             :   }
+     210       31603 :   for (unsigned i = 0; i < WATERS.size(); i++)
+     211             :   {
+     212       31602 :     atoms.push_back(WATERS[i]);
+     213             :   }
+     214        2049 :   for (unsigned i = 0; i < POXYGENS.size(); i++)
+     215             :   {
+     216        2048 :     atoms.push_back(POXYGENS[i]);
+     217             :   }
+     218             : 
+     219           1 :   addValueWithDerivatives();
+     220           1 :   setNotPeriodic();
+     221           1 :   requestAtoms(atoms);
+     222           1 : }
+     223             : 
+     224           4 : void fusionPoreNucleationP::calculate()
+     225             : {
+     226             :   /*************************
+     227             :   *                        *
+     228             :   *         System         *
+     229             :   *                        *
+     230             :   **************************/
+     231             : 
+     232             :   // Box dimensions.
+     233           4 :   double Lx = getBox()[0][0], Ly = getBox()[1][1], Lz = getBox()[2][2];
+     234             : 
+     235             :   // Z center of the upper membrane (uMem) and lower membrane (lMem) for systems with PBC: https://en.wikipedia.org/wiki/Center_of_mass#Systems_with_periodic_boundary_conditions .
+     236             :   double ZuMem, ZuMemcos = 0.0, ZuMemsin = 0.0, uMemAngle, ZlMem, ZlMemcos = 0.0, ZlMemsin = 0.0, lMemAngle;
+     237             : 
+     238             : #ifdef _OPENMP
+     239             : #if _OPENMP >= 201307
+     240           4 :   #pragma omp parallel for private(uMemAngle, lMemAngle) reduction(+:ZuMemcos, ZuMemsin, ZlMemcos, ZlMemsin)
+     241             : #endif
+     242             : #endif
+     243             :   for (unsigned i = 0; i < UMEM.size(); i++)
+     244             :   {
+     245             :     uMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     246             :     lMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + UMEM.size())))[2];
+     247             :     ZuMemcos += cos(uMemAngle);
+     248             :     ZuMemsin += sin(uMemAngle);
+     249             :     ZlMemcos += cos(lMemAngle);
+     250             :     ZlMemsin += sin(lMemAngle);
+     251             :   }
+     252           4 :   ZuMemcos = ZuMemcos / UMEM.size();
+     253           4 :   ZuMemsin = ZuMemsin / UMEM.size();
+     254           4 :   ZuMem = Lz * (atan2(-ZuMemsin, -ZuMemcos) + M_PI) / (2.0 * M_PI);
+     255           4 :   ZlMemcos = ZlMemcos / UMEM.size();
+     256           4 :   ZlMemsin = ZlMemsin / UMEM.size();
+     257           4 :   ZlMem = Lz * (atan2(-ZlMemsin, -ZlMemcos) + M_PI) / (2.0 * M_PI);
+     258             : 
+     259             :   // Z center of the boths membranes (upper and lower).
+     260           4 :   double ZMems = (ZuMem + ZlMem) / 2.0;
+     261             : 
+     262             :   /**************************
+     263             :   *                         *
+     264             :   *   Xcyl_Mem & Ycyl_Mem   *
+     265             :   *                         *
+     266             :   ***************************/
+     267             : 
+     268             :   // Quantity of beads of the membranes.
+     269           4 :   unsigned membraneBeads = UMEM.size() + LMEM.size();
+     270             : 
+     271             :   // Z distance from the lipid tail to the geometric center of both membranes.
+     272             :   double ZTailDistance;
+     273             : 
+     274             :   // Z position of the first slice.
+     275           4 :   double firstSliceZ_Mem = ZMems + (0.0 + 0.5 - NSMEM[0] / 2.0) * DSMEM[0];
+     276             : 
+     277             :   // Z distance between the first slice and the Z center of the membrane.
+     278           8 :   double firstSliceZDist_Mem = pbcDistance(Vector(0.0, 0.0, firstSliceZ_Mem), Vector(0.0, 0.0, ZMems))[2];
+     279             : 
+     280             :   // Position in the cylinder.
+     281             :   double PositionS_Mem;
+     282             : 
+     283             :   // Slices to analyze per particle.
+     284             :   unsigned s1_Mem, s2_Mem;
+     285             : 
+     286             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     287           4 :   std::vector<double> faxial_Mem(TAILS.size() * NSMEM[0]);
+     288             : 
+     289             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     290           4 :   std::vector<double> Fs_Mem(NSMEM[0]);
+     291             : 
+     292             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     293           4 :   std::vector<double> ws_Mem(NSMEM[0]);
+     294             : 
+     295             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     296             :   double W_Mem = 0.0;
+     297             : 
+     298             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     299           4 :   std::vector<double> sx_Mem(NSMEM[0]), sy_Mem(NSMEM[0]), cx_Mem(NSMEM[0]), cy_Mem(NSMEM[0]);
+     300             : 
+     301             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     302             :   double Xsc_Mem = 0.0, Xcc_Mem = 0.0, Ysc_Mem = 0.0, Ycc_Mem = 0.0;
+     303             : 
+     304             :   // Aux.
+     305             :   double x, aux;
+     306             : 
+     307             :   // Scaled position of the lipid tail respect the origin of coordinates.
+     308           4 :   Vector TailPosition;
+     309             : 
+     310             : #ifdef _OPENMP
+     311             : #if _OPENMP >= 201307
+     312             :   #pragma omp declare reduction(vec_double_plus : std::vector<double> : \
+     313             :   std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<double>())) \
+     314             :   initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
+     315             : #endif
+     316             : #endif
+     317             : 
+     318             : #ifdef _OPENMP
+     319             : #if _OPENMP >= 201307
+     320           4 :   #pragma omp parallel for private(ZTailDistance, PositionS_Mem, s1_Mem, s2_Mem, TailPosition, x, aux) reduction(vec_double_plus:Fs_Mem, sx_Mem, sy_Mem, cx_Mem, cy_Mem)
+     321             : #endif
+     322             : #endif
+     323             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     324             :   {
+     325             :     ZTailDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + membraneBeads))[2];
+     326             :     PositionS_Mem = (ZTailDistance + firstSliceZDist_Mem) / DSMEM[0];
+     327             :     // If the following condition is met the particle is in the Z space of the cylinder.
+     328             :     if ((PositionS_Mem >= (-0.5 - HMEM[0])) && (PositionS_Mem <= (NSMEM[0] + 0.5 - 1.0 + HMEM[0])))
+     329             :     {
+     330             :       //Defining the slices to analyze each particle.
+     331             :       if (PositionS_Mem < 1)
+     332             :       {
+     333             :         s1_Mem = 0;
+     334             :         s2_Mem = 2;
+     335             :       }
+     336             :       else if (PositionS_Mem <= (NSMEM[0] - 2.0))
+     337             :       {
+     338             :         s1_Mem = floor(PositionS_Mem) - 1;
+     339             :         s2_Mem = floor(PositionS_Mem) + 1;
+     340             :       }
+     341             :       else
+     342             :       {
+     343             :         s1_Mem = NSMEM[0] - 3;
+     344             :         s2_Mem = NSMEM[0] - 1;
+     345             :       }
+     346             : 
+     347             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     348             : 
+     349             :       for (unsigned s = s1_Mem; s <= s2_Mem; s++)
+     350             :       {
+     351             :         x = (ZTailDistance - (s + 0.5 - NSMEM[0] / 2.0) * DSMEM[0]) * 2.0 / DSMEM[0];
+     352             :         if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     353             :         {
+     354             :           if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     355             :           {
+     356             :             faxial_Mem[i + TAILS.size() * s] = 1.0;
+     357             :             Fs_Mem[s] += 1.0;
+     358             :             sx_Mem[s] += sin(2.0 * M_PI * TailPosition[0]);
+     359             :             sy_Mem[s] += sin(2.0 * M_PI * TailPosition[1]);
+     360             :             cx_Mem[s] += cos(2.0 * M_PI * TailPosition[0]);
+     361             :             cy_Mem[s] += cos(2.0 * M_PI * TailPosition[1]);
+     362             :           }
+     363             :           else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     364             :           {
+     365             :             aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     366             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     367             :             Fs_Mem[s] += aux;
+     368             :             sx_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[0]);
+     369             :             sy_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[1]);
+     370             :             cx_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[0]);
+     371             :             cy_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[1]);
+     372             :           }
+     373             :           else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     374             :           {
+     375             :             aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     376             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     377             :             Fs_Mem[s] += aux;
+     378             :             sx_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[0]));
+     379             :             sy_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[1]));
+     380             :             cx_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[0]));
+     381             :             cy_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[1]));
+     382             :           }
+     383             :         }
+     384             :       }
+     385             :     }
+     386             :   }
+     387             : 
+     388         344 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     389             :   {
+     390         340 :     if (Fs_Mem[s] != 0.0)
+     391             :     {
+     392         339 :       ws_Mem[s] = tanh(Fs_Mem[s]);
+     393         339 :       W_Mem += ws_Mem[s];
+     394         339 :       sx_Mem[s] = sx_Mem[s] / Fs_Mem[s];
+     395         339 :       sy_Mem[s] = sy_Mem[s] / Fs_Mem[s];
+     396         339 :       cx_Mem[s] = cx_Mem[s] / Fs_Mem[s];
+     397         339 :       cy_Mem[s] = cy_Mem[s] / Fs_Mem[s];
+     398         339 :       Xsc_Mem += sx_Mem[s] * ws_Mem[s];
+     399         339 :       Ysc_Mem += sy_Mem[s] * ws_Mem[s];
+     400         339 :       Xcc_Mem += cx_Mem[s] * ws_Mem[s];
+     401         339 :       Ycc_Mem += cy_Mem[s] * ws_Mem[s];
+     402             :     }
+     403             :   }
+     404             : 
+     405           4 :   Xsc_Mem = Xsc_Mem / W_Mem;
+     406           4 :   Ysc_Mem = Ysc_Mem / W_Mem;
+     407           4 :   Xcc_Mem = Xcc_Mem / W_Mem;
+     408           4 :   Ycc_Mem = Ycc_Mem / W_Mem;
+     409             : 
+     410             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     411             :   double Xcyl_Mem, Ycyl_Mem;
+     412             : 
+     413           4 :   if ((XCYL[0] > 0.0) && (YCYL[0] > 0.0))
+     414             :   {
+     415             :     Xcyl_Mem = XCYL[0];
+     416             :     Ycyl_Mem = YCYL[0];
+     417             :   }
+     418             :   else
+     419             :   {
+     420           4 :     Xcyl_Mem = (atan2(-Xsc_Mem, -Xcc_Mem) + M_PI) * Lx / (2 * M_PI);
+     421           4 :     Ycyl_Mem = (atan2(-Ysc_Mem, -Ycc_Mem) + M_PI) * Ly / (2 * M_PI);
+     422             :   }
+     423             : 
+     424             :   /*************************
+     425             :   *                        *
+     426             :   *        Xi_n            *
+     427             :   *                        *
+     428             :   **************************/
+     429             : 
+     430             :   // Eq. 1 Hub & Awasthi JCTC 2017. This is the CV that describes de Pore Nucleation.
+     431           4 :   double Xi_n = 0.0;
+     432             : 
+     433             :   // Quantity of beads that could participate in the calculation of the Xi_Chain
+     434           4 :   unsigned chainBeads = WATERS.size() + POXYGENS.size();
+     435             : 
+     436             :   // Quantity of beads that don't participate in the calculation of the Xi_Chain
+     437           4 :   unsigned noChainBeads = (UMEM.size() * 2) + TAILS.size();
+     438             : 
+     439             :   // Z Distances from the oxygens to the geometric center of the membranes.
+     440             :   double ZMemDistance;
+     441             : 
+     442             :   // Scaled positions of the oxygens to respect of the origin of coordinates.
+     443           4 :   Vector Position;
+     444             : 
+     445             :   // Distance from the water/phosphate group to the defect cylinder.
+     446           4 :   Vector distCylinder;
+     447             : 
+     448             :   // Center of the cylinder. XY components are calculated (or defined), Z is the Z geometric center of the membranes of the system.
+     449           8 :   Vector xyzCyl_Mem = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMems));
+     450             : 
+     451             :   // Average of the radius of the water and lipid cylinder.
+     452           4 :   double RCYLAVERAGE = RCYL[0] * (1 + HCH[0]);
+     453             : 
+     454             :   // Conditions.
+     455             :   bool condition1, condition2, condition3;
+     456             : 
+     457             :   // Z position of the first slice.
+     458           4 :   double firstSliceZ = ZMems + (0.0 + 0.5 - NS[0] / 2.0) * DS[0];
+     459             : 
+     460             :   // Z distance between the first slice and the Z center of the membrane.
+     461           4 :   double firstSliceZDist = pbcDistance(Vector(0.0, 0.0, firstSliceZ), Vector(0.0, 0.0, ZMems))[2];
+     462             : 
+     463             :   // Position in the cylinder.
+     464             :   double PositionS;
+     465             : 
+     466             :   // Mark the particles to analyze.
+     467           4 :   std::vector<double> analyzeThisParticle(chainBeads);
+     468             : 
+     469             :   // Slices to analyze per particle.
+     470           4 :   std::vector<unsigned> s1(chainBeads), s2(chainBeads);
+     471             : 
+     472             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     473           4 :   std::vector<double> faxial(chainBeads * NS[0]);
+     474             : 
+     475             :   // Eq. 16 Hub & Awasthi JCTC 2017.
+     476           4 :   std::vector<double> d_faxial_dz(chainBeads * NS[0]);
+     477             : 
+     478             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     479           4 :   std::vector<double> Fs(NS[0]);
+     480             : 
+     481             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     482           4 :   std::vector<double> ws(NS[0]);
+     483             : 
+     484             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     485             :   double W = 0.0;
+     486             : 
+     487             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     488           4 :   std::vector<double> sx(NS[0]), sy(NS[0]), cx(NS[0]), cy(NS[0]);
+     489             : 
+     490             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     491             :   double Xsc = 0.0, Xcc = 0.0, Ysc = 0.0, Ycc = 0.0;
+     492             : 
+     493             : #ifdef _OPENMP
+     494             : #if _OPENMP >= 201307
+     495           4 :   #pragma omp parallel for private(distCylinder, aux, condition1, condition2, condition3, ZMemDistance, PositionS, Position, x) reduction(vec_double_plus:Fs, sx, sy, cx, cy)
+     496             : #endif
+     497             : #endif
+     498             :   for (unsigned i = 0; i < chainBeads; i++)
+     499             : {
+     500             :   distCylinder = pbcDistance(xyzCyl_Mem, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     501             :     aux = sqrt(pow(distCylinder[0], 2) + pow(distCylinder[1], 2));
+     502             :     condition1 = ((aux / RCYLAVERAGE) < 1.0);
+     503             :     condition2 = ((pbcDistance(Vector(0.0, 0.0, ZuMem), getPosition(i + noChainBeads))[2] > 0) && (aux / RCYLAVERAGE) < 2.0);
+     504             :     condition3 = ((pbcDistance(getPosition(i + noChainBeads), Vector(0.0, 0.0, ZlMem))[2] > 0) && (aux / RCYLAVERAGE) < 2.0);
+     505             :     if (condition1 || condition2 || condition3)
+     506             :     {
+     507             :       ZMemDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + noChainBeads))[2];
+     508             :       PositionS = (ZMemDistance + firstSliceZDist) / DS[0];
+     509             :       // If the following condition is met the particle is in the Z space of the cylinder.
+     510             :       if ((PositionS >= (-0.5 - HCH[0])) && (PositionS <= (NS[0] + 0.5 - 1.0 + HCH[0])))
+     511             :       {
+     512             :         analyzeThisParticle[i] = 1.0;
+     513             : 
+     514             :         //Defining the slices to analyze each particle.
+     515             :         if (PositionS < 1)
+     516             :         {
+     517             :           s1[i] = 0;
+     518             :           s2[i] = 2;
+     519             :         }
+     520             :         else if (PositionS <= (NS[0] - 2.0))
+     521             :         {
+     522             :           s1[i] = floor(PositionS) - 1;
+     523             :           s2[i] = floor(PositionS) + 1;
+     524             :         }
+     525             :         else
+     526             :         {
+     527             :           s1[i] = NS[0] - 3;
+     528             :           s2[i] = NS[0] - 1;
+     529             :         }
+     530             : 
+     531             :         Position = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     532             : 
+     533             :         for (unsigned s = s1[i]; s <= s2[i]; s++)
+     534             :         {
+     535             :           x = (ZMemDistance - (s + 0.5 - NS[0] / 2.0) * DS[0]) * 2.0 / DS[0];
+     536             :           if (!((x <= -1.0 - HCH[0]) || (x >= 1.0 + HCH[0])))
+     537             :           {
+     538             :             if (((-1.0 + HCH[0]) <= x) && (x <= (1.0 - HCH[0])))
+     539             :             {
+     540             :               faxial[i + chainBeads * s] = 1.0;
+     541             :               Fs[s] += 1.0;
+     542             :               sx[s] += sin(2.0 * M_PI * Position[0]);
+     543             :               sy[s] += sin(2.0 * M_PI * Position[1]);
+     544             :               cx[s] += cos(2.0 * M_PI * Position[0]);
+     545             :               cy[s] += cos(2.0 * M_PI * Position[1]);
+     546             :             }
+     547             :             else if (((1.0 - HCH[0]) < x) && (x < (1.0 + HCH[0])))
+     548             :             {
+     549             :               aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HCH[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     550             :               faxial[i + chainBeads * s] = aux;
+     551             :               d_faxial_dz[i + chainBeads * s] = ((-3.0 / (4.0 * HCH[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HCH[0], 3)))) * 2.0 / DS[0];
+     552             :               Fs[s] += aux;
+     553             :               sx[s] += aux * sin(2.0 * M_PI * Position[0]);
+     554             :               sy[s] += aux * sin(2.0 * M_PI * Position[1]);
+     555             :               cx[s] += aux * cos(2.0 * M_PI * Position[0]);
+     556             :               cy[s] += aux * cos(2.0 * M_PI * Position[1]);
+     557             :             }
+     558             :             else if (((-1.0 - HCH[0]) < x) && (x < (-1.0 + HCH[0])))
+     559             :             {
+     560             :               aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HCH[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     561             :               faxial[i + chainBeads * s] = aux;
+     562             :               d_faxial_dz[i + chainBeads * s] = ((3.0 / (4.0 * HCH[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HCH[0], 3)))) * 2.0 / DS[0];
+     563             :               Fs[s] += aux;
+     564             :               sx[s] += (aux * sin(2.0 * M_PI * Position[0]));
+     565             :               sy[s] += (aux * sin(2.0 * M_PI * Position[1]));
+     566             :               cx[s] += (aux * cos(2.0 * M_PI * Position[0]));
+     567             :               cy[s] += (aux * cos(2.0 * M_PI * Position[1]));
+     568             :             }
+     569             :           }
+     570             :         }
+     571             :       }
+     572             :     }
+     573             :   }
+     574             : 
+     575         184 :   for (unsigned s = 0; s < NS[0]; s++)
+     576             :   {
+     577         180 :     if (Fs[s] != 0.0)
+     578             :     {
+     579          49 :       ws[s] = tanh(Fs[s]);
+     580          49 :       W += ws[s];
+     581          49 :       sx[s] = sx[s] / Fs[s];
+     582          49 :       sy[s] = sy[s] / Fs[s];
+     583          49 :       cx[s] = cx[s] / Fs[s];
+     584          49 :       cy[s] = cy[s] / Fs[s];
+     585          49 :       Xsc += sx[s] * ws[s];
+     586          49 :       Ysc += sy[s] * ws[s];
+     587          49 :       Xcc += cx[s] * ws[s];
+     588          49 :       Ycc += cy[s] * ws[s];
+     589             :     }
+     590             :   }
+     591             : 
+     592           4 :   Xsc = Xsc / W;
+     593           4 :   Ysc = Ysc / W;
+     594           4 :   Xcc = Xcc / W;
+     595           4 :   Ycc = Ycc / W;
+     596             : 
+     597             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     598             :   double Xcyl, Ycyl;
+     599             : 
+     600             :   Xcyl = Xcyl_Mem;
+     601             :   Ycyl = Ycyl_Mem;
+     602             : 
+     603             :   // Eq. 25, 26 and 27 Hub & Awasthi JCTC 2017.
+     604             :   double d_sx_dx, d_sx_dz, d_sy_dy, d_sy_dz, d_cx_dx, d_cx_dz, d_cy_dy, d_cy_dz;
+     605             : 
+     606             :   // Eq. 29 Hub & Awasthi JCTC 2017.
+     607             :   double d_ws_dz;
+     608             : 
+     609             :   // Eq. 31, 32 and 33 Hub & Awasthi JCTC 2017
+     610             :   double d_Xsc_dx, d_Xsc_dz, d_Xcc_dx, d_Xcc_dz, d_Ysc_dy, d_Ysc_dz, d_Ycc_dy, d_Ycc_dz;
+     611             : 
+     612             :   // Center of the cylinder. X and Y are calculated (or defined), Z is the Z component of the geometric center of the membranes.
+     613           4 :   Vector xyzCyl = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl, Ycyl, ZMems));
+     614             : 
+     615             :   // Distances from the oxygens to center of the cylinder.
+     616           4 :   std::vector<Vector> CylDistances(chainBeads);
+     617             : 
+     618             :   // Modulo of the XY distances from the oxygens to the center of the cylinder.
+     619             :   double ri;
+     620             : 
+     621             :   // Eq. 8 Hub & Awasthi JCTC 2017.
+     622             :   double fradial;
+     623             : 
+     624             :   // Eq. 15 Hub & Awasthi JCTC 2017.
+     625           4 :   std::vector<double> d_fradial_dx(chainBeads), d_fradial_dy(chainBeads);
+     626             : 
+     627             :   // Eq. 35, 36, 37 and 38 Hub & Awasthi JCTC 2017.
+     628           4 :   std::vector<double> d_Xcyl_dx(chainBeads), d_Xcyl_dz(chainBeads), d_Ycyl_dy(chainBeads), d_Ycyl_dz(chainBeads);
+     629             : 
+     630             :   // To avoid rare instabilities auxX and auxY are truncated at a configurable value (default 500).
+     631           4 :   double auxX = (1 / (pow(Xsc, 2) + pow(Xcc, 2))), auxY = (1 / (pow(Ysc, 2) + pow(Ycc, 2)));
+     632             : 
+     633           4 :   if (auxX > ONEOVERS2C2CUTOFF[0])
+     634             :   {
+     635           0 :     auxX = Lx * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     636             :   }
+     637             :   else
+     638             :   {
+     639           4 :     auxX = Lx * auxX / (2 * M_PI);
+     640             :   }
+     641             : 
+     642           4 :   if (auxY > ONEOVERS2C2CUTOFF[0])
+     643             :   {
+     644           0 :     auxY = Ly * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     645             :   }
+     646             :   else
+     647             :   {
+     648           4 :     auxY = Ly * auxY / (2 * M_PI);
+     649             :   }
+     650             : 
+     651             :   //Number of oxygens within the slice s of the membrane-spanning cylinder.
+     652           4 :   std::vector<double> Nsp(NS[0]), psi(NS[0]), d_psi(NS[0]);
+     653             : 
+     654             :   // Eq. 3 Hub & Awasthi JCTC 2017.
+     655           4 :   double b = (ZETA[0] / (1.0 - ZETA[0])), c = ((1.0 - ZETA[0]) * exp(b));
+     656             : 
+     657             :   // Eq. 19 Hub & Awasthi JCTC 2017.
+     658           4 :   std::vector<double> fradial_d_faxial_dz(chainBeads * NS[0]);
+     659             : 
+     660             :   // Eq. 20 Hub & Awasthi JCTC 2017.
+     661           4 :   std::vector<double> Axs(NS[0]), Ays(NS[0]);
+     662             : 
+     663             : #ifdef _OPENMP
+     664             : #if _OPENMP >= 201307
+     665           4 :   #pragma omp parallel for private(d_Xsc_dx,d_Xcc_dx,d_Ysc_dy,d_Ycc_dy,d_Xsc_dz,d_Xcc_dz,d_Ysc_dz,d_Ycc_dz,d_sx_dx,d_sy_dy,d_cx_dx,d_cy_dy,d_sx_dz,d_sy_dz,d_cx_dz,d_cy_dz,d_ws_dz,ri,x,fradial) reduction(vec_double_plus: Nsp, Axs, Ays)
+     666             : #endif
+     667             : #endif
+     668             :   for (unsigned i = 0; i < chainBeads; i++)
+     669             : {
+     670             :   CylDistances[i] = pbcDistance(xyzCyl, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     671             :     if (analyzeThisParticle[i])
+     672             :     {
+     673             :       Position = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + noChainBeads)));
+     674             :       d_Xsc_dx = 0.0;
+     675             :       d_Xcc_dx = 0.0;
+     676             :       d_Ysc_dy = 0.0;
+     677             :       d_Ycc_dy = 0.0;
+     678             :       d_Xsc_dz = 0.0;
+     679             :       d_Xcc_dz = 0.0;
+     680             :       d_Ysc_dz = 0.0;
+     681             :       d_Ycc_dz = 0.0;
+     682             :       for (unsigned s = s1[i]; s <= s2[i]; s++)
+     683             :       {
+     684             :         if (Fs[s] != 0.0)
+     685             :         {
+     686             :           d_sx_dx = faxial[i + chainBeads * s] * 2.0 * M_PI * cos(2.0 * M_PI * Position[0]) / (Lx * Fs[s]);
+     687             :           d_sy_dy = faxial[i + chainBeads * s] * 2.0 * M_PI * cos(2.0 * M_PI * Position[1]) / (Ly * Fs[s]);
+     688             :           d_cx_dx = -faxial[i + chainBeads * s] * 2.0 * M_PI * sin(2.0 * M_PI * Position[0]) / (Lx * Fs[s]);
+     689             :           d_cy_dy = -faxial[i + chainBeads * s] * 2.0 * M_PI * sin(2.0 * M_PI * Position[1]) / (Ly * Fs[s]);
+     690             :           d_Xsc_dx += ws[s] * d_sx_dx / W;
+     691             :           d_Xcc_dx += ws[s] * d_cx_dx / W;
+     692             :           d_Ysc_dy += ws[s] * d_sy_dy / W;
+     693             :           d_Ycc_dy += ws[s] * d_cy_dy / W;
+     694             : 
+     695             :           d_sx_dz = d_faxial_dz[i + chainBeads * s] * (sin(2.0 * M_PI * Position[0]) - sx[s]) / Fs[s];
+     696             :           d_sy_dz = d_faxial_dz[i + chainBeads * s] * (sin(2.0 * M_PI * Position[1]) - sy[s]) / Fs[s];
+     697             :           d_cx_dz = d_faxial_dz[i + chainBeads * s] * (cos(2.0 * M_PI * Position[0]) - cx[s]) / Fs[s];
+     698             :           d_cy_dz = d_faxial_dz[i + chainBeads * s] * (cos(2.0 * M_PI * Position[1]) - cy[s]) / Fs[s];
+     699             :           d_ws_dz = (1 - pow(ws[s], 2)) * d_faxial_dz[i + chainBeads * s];
+     700             :           d_Xsc_dz += (ws[s] * d_sx_dz + d_ws_dz * (sx[s] - Xsc)) / W;
+     701             :           d_Xcc_dz += (ws[s] * d_cx_dz + d_ws_dz * (cx[s] - Xcc)) / W;
+     702             :           d_Ysc_dz += (ws[s] * d_sy_dz + d_ws_dz * (sy[s] - Ysc)) / W;
+     703             :           d_Ycc_dz += (ws[s] * d_cy_dz + d_ws_dz * (cy[s] - Ycc)) / W;
+     704             :         }
+     705             :       }
+     706             :       d_Xcyl_dx[i] = auxX * (-Xsc * d_Xcc_dx + Xcc * d_Xsc_dx);
+     707             :       d_Xcyl_dz[i] = auxX * (-Xsc * d_Xcc_dz + Xcc * d_Xsc_dz);
+     708             :       d_Ycyl_dy[i] = auxY * (-Ysc * d_Ycc_dy + Ycc * d_Ysc_dy);
+     709             :       d_Ycyl_dz[i] = auxY * (-Ysc * d_Ycc_dz + Ycc * d_Ysc_dz);
+     710             : 
+     711             :       ri = sqrt(pow(CylDistances[i][0], 2) + pow(CylDistances[i][1], 2));
+     712             :       x = ri / RCYL[0];
+     713             :       if (!((x <= -1.0 - HCH[0]) || (x >= 1.0 + HCH[0])))
+     714             :       {
+     715             :         if (((-1.0 + HCH[0]) <= x) && (x <= (1.0 - HCH[0])))
+     716             :         {
+     717             :           fradial = 1.0;
+     718             :         }
+     719             :         else if (((1.0 - HCH[0]) < x) && (x < (1.0 + HCH[0])))
+     720             :         {
+     721             :           fradial = 0.5 - ((3.0 * x - 3.0) / (4.0 * HCH[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     722             :           d_fradial_dx[i] = ((-3.0 / (4.0 * HCH[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HCH[0], 3)))) * CylDistances[i][0] / (RCYL[0] * ri);
+     723             :           d_fradial_dy[i] = ((-3.0 / (4.0 * HCH[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HCH[0], 3)))) * CylDistances[i][1] / (RCYL[0] * ri);
+     724             :         }
+     725             :         else if (((-1.0 - HCH[0]) < x) && (x < (-1.0 + HCH[0])))
+     726             :         {
+     727             :           fradial = 0.5 + ((3.0 * x + 3.0) / (4.0 * HCH[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HCH[0], 3)));
+     728             :           d_fradial_dx[i] = ((3.0 / (4.0 * HCH[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HCH[0], 3)))) * CylDistances[i][0] / (RCYL[0] * ri);
+     729             :           d_fradial_dy[i] = ((3.0 / (4.0 * HCH[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HCH[0], 3)))) * CylDistances[i][1] / (RCYL[0] * ri);
+     730             :         }
+     731             : 
+     732             :         for (unsigned s = s1[i]; s <= s2[i]; s++)
+     733             :         {
+     734             :           Nsp[s] += fradial * faxial[i + chainBeads * s];
+     735             :           Axs[s] += faxial[i + chainBeads * s] * d_fradial_dx[i];
+     736             :           Ays[s] += faxial[i + chainBeads * s] * d_fradial_dy[i];
+     737             :           fradial_d_faxial_dz[i + chainBeads * s] = fradial * d_faxial_dz[i + chainBeads * s];
+     738             :         }
+     739             :       }
+     740             :     }
+     741             :   }
+     742             : 
+     743         184 :   for (unsigned s = 0; s < NS[0]; s++)
+     744             :   {
+     745         180 :     if (Nsp[s] <= 1.0)
+     746             :     {
+     747         149 :       psi[s] = ZETA[0] * Nsp[s];
+     748         149 :       d_psi[s] = ZETA[0];
+     749         149 :       Xi_n += psi[s];
+     750             :     }
+     751             :     else
+     752             :     {
+     753          31 :       psi[s] = 1.0 - c * exp(-b * Nsp[s]);
+     754          31 :       d_psi[s] = b * c * exp(-b * Nsp[s]);
+     755          31 :       Xi_n += psi[s];
+     756             :     }
+     757             :   }
+     758             : 
+     759           4 :   Xi_n = Xi_n / NS[0];
+     760             : 
+     761             :   // Eq. 18 Hub & Awasthi JCTC 2017.
+     762           4 :   std::vector<double> faxial_d_fradial_dx(chainBeads * NS[0]), faxial_d_fradial_dy(chainBeads * NS[0]), faxial_d_fradial_dz(chainBeads * NS[0]);
+     763             : 
+     764             :   // Eq. 13 Hub & Awasthi JCTC 2017 modified to considere the Heaviside_Chain step function (this only affect during the transition).
+     765           4 :   std::vector<Vector> derivatives_Chain(chainBeads);
+     766             : 
+     767             : #ifdef _OPENMP
+     768             : #if _OPENMP >= 201307
+     769           4 :   #pragma omp parallel for private(aux)
+     770             : #endif
+     771             : #endif
+     772             :   for (unsigned i = 0; i < chainBeads; i++)
+     773             : {
+     774             :   if (analyzeThisParticle[i])
+     775             :     {
+     776             :       for (unsigned s = s1[i]; s <= s2[i]; s++)
+     777             :       {
+     778             :         if (faxial[i + chainBeads * s])
+     779             :         {
+     780             :           faxial_d_fradial_dx[i + chainBeads * s] = faxial[i + chainBeads * s] * d_fradial_dx[i] - d_Xcyl_dx[i] * Axs[s];
+     781             :           faxial_d_fradial_dy[i + chainBeads * s] = faxial[i + chainBeads * s] * d_fradial_dy[i] - d_Ycyl_dy[i] * Ays[s];
+     782             :           faxial_d_fradial_dz[i + chainBeads * s] = -d_Xcyl_dz[i] * Axs[s] - d_Ycyl_dz[i] * Ays[s];
+     783             :         }
+     784             :       }
+     785             : 
+     786             :       for (unsigned s = s1[i]; s <= s2[i]; s++)
+     787             :       {
+     788             :         aux = d_psi[s] / NS[0];
+     789             :         derivatives_Chain[i][0] += aux * faxial_d_fradial_dx[i + chainBeads * s];
+     790             :         derivatives_Chain[i][1] += aux * faxial_d_fradial_dy[i + chainBeads * s];
+     791             :         derivatives_Chain[i][2] += aux * (faxial_d_fradial_dz[i + chainBeads * s] + fradial_d_faxial_dz[i + chainBeads * s]);
+     792             :       }
+     793             :     }
+     794             :   }
+     795             : 
+     796           4 :   Tensor virial;
+     797      134604 :   for (unsigned i = 0; i < chainBeads; i++)
+     798             : {
+     799      134600 :   setAtomsDerivatives((i + noChainBeads), derivatives_Chain[i]);
+     800      134600 :     virial -= Tensor(CylDistances[i], derivatives_Chain[i]);
+     801             :   }
+     802             : 
+     803           4 :   setValue(Xi_n);
+     804           4 :   setBoxDerivatives(virial);
+     805           4 : }
+     806             : }
+     807             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/MemFusionP.cpp.func-sort-c.html b/coverage/membranefusion/MemFusionP.cpp.func-sort-c.html new file mode 100644 index 000000000000..b08d59663ac7 --- /dev/null +++ b/coverage/membranefusion/MemFusionP.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/MemFusionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - MemFusionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13315088.7 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion10memFusionPC2ERKNS_13ActionOptionsE0
_ZN4PLMD14membranefusion10memFusionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion10memFusionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion10memFusionP9calculateEv3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/MemFusionP.cpp.func.html b/coverage/membranefusion/MemFusionP.cpp.func.html new file mode 100644 index 000000000000..47dd590609db --- /dev/null +++ b/coverage/membranefusion/MemFusionP.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/MemFusionP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - MemFusionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13315088.7 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14membranefusion10memFusionP16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD14membranefusion10memFusionP9calculateEv3
_ZN4PLMD14membranefusion10memFusionPC1ERKNS_13ActionOptionsE1
_ZN4PLMD14membranefusion10memFusionPC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/MemFusionP.cpp.gcov.html b/coverage/membranefusion/MemFusionP.cpp.gcov.html new file mode 100644 index 000000000000..9a4fca1462d2 --- /dev/null +++ b/coverage/membranefusion/MemFusionP.cpp.gcov.html @@ -0,0 +1,685 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion/MemFusionP.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusion - MemFusionP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13315088.7 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2022.
+       3             : 
+       4             : CVs originally developed by the Jochen Hub group from the University of Saarland (Germany)
+       5             : and adapted and implemented in PLUMED by Ary Lautaro Di Bartolo and Diego Masone from the
+       6             : National University of Cuyo (Argentina).
+       7             : 
+       8             : The membranefusion module is free software: you can redistribute it and/or modify
+       9             : it under the terms of the GNU Lesser General Public License as published by
+      10             : the Free Software Foundation, either version 3 of the License, or
+      11             : (at your option) any later version.
+      12             : 
+      13             : The membranefusion module is distributed in the hope that it will be useful,
+      14             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      15             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      16             : GNU Lesser General Public License for more details.
+      17             : 
+      18             : You should have received a copy of the GNU Lesser General Public License
+      19             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      20             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      21             : #include "colvar/Colvar.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include <cmath>
+      24             : #ifdef _OPENMP
+      25             : #if _OPENMP >= 201307
+      26             : #include <omp.h>
+      27             : #endif
+      28             : #endif
+      29             : 
+      30             : namespace PLMD
+      31             : {
+      32             : namespace membranefusion
+      33             : {
+      34             : //+PLUMEDOC MEMBRANEFUSIONMOD_COLVAR MEMFUSIONP
+      35             : /*
+      36             : Calculate a CV that can induce the formation of the hemifusion stalk between two initially flat and planar bilayers.
+      37             : 
+      38             : Calculate the collective variable designed by Hub and collaborators \cite Hub2017 and
+      39             : implemented into PLUMED by Masone and collaborators \cite DiBartolo2022 .
+      40             : This CV is capable of inducing the formation of the hemifusion stalk between two initially flat and planar bilayers
+      41             : surrounded by water molecules.
+      42             : 
+      43             : \f[
+      44             : \xi_f = \frac{1}{N_{sf}} \sum_{s=0}^{N_{sf}-1} \delta_{sf} (N_{sf}^{(p)})
+      45             : \f]
+      46             : 
+      47             : Where \f$\xi_f\f$ is the CV, \f$N_{sf}\f$ is the number of slices of the cylinder that make up the CV,
+      48             : \f$\delta_{sf}\f$ is a continuos function in the interval [0 1] (\f$\delta_{sf} = 0\f$ for no beads in the slice s, and
+      49             : \f$\delta_{sf} = 1\f$ for 1 or more beads in the slice s) and \f$N_{sf}^{(p)}\f$ accounts for the number of tail beads
+      50             : within the slice s.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : This example induces a hemifusion stalk (\f$\xi_f = 0.85\f$) from a pair of initially flat membranes (\f$\xi_f = 0.2\f$).
+      55             : 
+      56             : \plumedfile
+      57             : lMem: GROUP ATOMS=1-12288 #All the lower membrane beads.
+      58             : uMem: GROUP ATOMS=12289-24576 #All the upper membrane beads.
+      59             : tails: GROUP ATOMS=8-24572:12,12-24576:12 #All the lipid tails beads (from the lower and upper membrane).
+      60             : 
+      61             : memFusion: MEMFUSIONP UMEMBRANE=uMem LMEMBRANE=lMem TAILS=tails NSMEM=70 DSMEM=0.1 HMEM=0.25 RCYLMEM=1.75 ZETAMEM=0.5
+      62             : 
+      63             : MOVINGRESTRAINT ...
+      64             :     ARG=memFusion
+      65             :     STEP0=0 AT0=0.2 KAPPA0=10000.0
+      66             :     STEP1=500000 AT1=0.85 KAPPA1=10000.0
+      67             : ...
+      68             : 
+      69             : PRINT ARG=memFusion FILE=COLVAR STRIDE=1
+      70             : 
+      71             : \endplumedfile
+      72             : 
+      73             : You can test this CV with another example in this <a href="https://github.com/lautarodibartolo/MemFusion/tree/main/ExampleParallel">GitHub folder</a>.
+      74             : 
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : 
+      78             : class memFusionP : public Colvar
+      79             : {
+      80             :   std::vector<AtomNumber> UMEM, LMEM, TAILS;
+      81             :   std::vector<double> NSMEM, DSMEM, HMEM, RCYLMEM, ZETAMEM, ONEOVERS2C2CUTOFF, XCYL, YCYL;
+      82             : 
+      83             : public:
+      84             :   explicit memFusionP(const ActionOptions &);
+      85             :   void calculate() override;
+      86             :   static void registerKeywords(Keywords &keys);
+      87             : };
+      88             : 
+      89             : PLUMED_REGISTER_ACTION(memFusionP, "MEMFUSIONP")
+      90             : 
+      91           3 : void memFusionP::registerKeywords(Keywords &keys)
+      92             : {
+      93           3 :   Colvar::registerKeywords(keys);
+      94           6 :   keys.add("atoms", "UMEMBRANE", "all the beads of the upper membrane");
+      95           6 :   keys.add("atoms", "LMEMBRANE", "all the beads of the lower membrane");
+      96           6 :   keys.add("atoms", "TAILS", "all the tail beads of the system");
+      97           6 :   keys.add("compulsory", "NSMEM", "the number of slices of the membrane fusion cylinder in such a way that when the bilayers are flat and parallel the CV is equal to 0.2.");
+      98           6 :   keys.add("optional", "DSMEM", "( default=0.1) thickness of the slices of the membrane fusion cylinder.");
+      99           6 :   keys.add("optional", "HMEM", "( default=0.25 ) parameter of the step function θ(x,h) for the membrane fusion.");
+     100           6 :   keys.add("optional", "RCYLMEM", "( default=1.75 ) the radius of the membrane fusion cylinder.");
+     101           6 :   keys.add("optional", "ZETAMEM", "( default=0.5 ) occupation factor.");
+     102           6 :   keys.add("optional", "ONEOVERS2C2CUTOFF", "( default=500 ) cut off large values for the derivative of the atan2 function.");
+     103           6 :   keys.add("optional", "XCYL", "X coordinate of the fixed cylinder, if not present this will be calculated.");
+     104           6 :   keys.add("optional", "YCYL", "Y coordinate of the fixed cylinder, if not present this will be calculated.");
+     105           3 : }
+     106             : 
+     107           1 : memFusionP::memFusionP(const ActionOptions &ao) : PLUMED_COLVAR_INIT(ao)
+     108             : {
+     109           2 :   parseAtomList("UMEMBRANE", UMEM);
+     110           1 :   if (UMEM.size() == 0)
+     111           0 :     error("UMEMBRANE has not any atom specified.");
+     112             : 
+     113           2 :   parseAtomList("LMEMBRANE", LMEM);
+     114           1 :   if (LMEM.size() == 0)
+     115           0 :     error("LMEMBRANE has not any atom specified.");
+     116             : 
+     117           2 :   parseAtomList("TAILS", TAILS);
+     118           1 :   if (TAILS.size() == 0)
+     119           0 :     error("TAILS has not any atom specified.");
+     120             : 
+     121           2 :   parseVector("NSMEM", NSMEM);
+     122           1 :   if (NSMEM.size() > 1)
+     123           0 :     error("NSMEM cannot take more than one value.");
+     124             : 
+     125           2 :   parseVector("DSMEM", DSMEM);
+     126           1 :   if (DSMEM.size() > 1)
+     127           0 :     error("DSMEM cannot take more than one value.");
+     128           1 :   if (DSMEM.size() == 0)
+     129           0 :     DSMEM.push_back(0.1);
+     130             : 
+     131           2 :   parseVector("HMEM", HMEM);
+     132           1 :   if (HMEM.size() > 1)
+     133           0 :     error("HMEM cannot take more than one value.");
+     134           1 :   if (HMEM.size() == 0)
+     135           0 :     HMEM.push_back(0.25);
+     136             : 
+     137           2 :   parseVector("RCYLMEM", RCYLMEM);
+     138           1 :   if (RCYLMEM.size() > 1)
+     139           0 :     error("RCYLMEM cannot take more than one value.");
+     140           1 :   if (RCYLMEM.size() == 0)
+     141           0 :     RCYLMEM.push_back(1.75);
+     142             : 
+     143           2 :   parseVector("ZETAMEM", ZETAMEM);
+     144           1 :   if (ZETAMEM.size() > 1)
+     145           0 :     error("ZETA cannot take more than one value.");
+     146           1 :   if (ZETAMEM.size() == 0)
+     147           0 :     ZETAMEM.push_back(0.5);
+     148             : 
+     149           2 :   parseVector("ONEOVERS2C2CUTOFF", ONEOVERS2C2CUTOFF);
+     150           1 :   if (ONEOVERS2C2CUTOFF.size() > 1)
+     151           0 :     error("ONEOVERS2C2CUTOFF cannot take more than one value.");
+     152           1 :   if (ONEOVERS2C2CUTOFF.size() == 0)
+     153           1 :     ONEOVERS2C2CUTOFF.push_back(500);
+     154             : 
+     155           2 :   parseVector("XCYL", XCYL);
+     156           1 :   if (XCYL.size() > 1)
+     157           0 :     error("XCYL cannot take more than one value.");
+     158           1 :   if (XCYL.size() == 0)
+     159           1 :     XCYL.push_back(-1.0);
+     160             : 
+     161           2 :   parseVector("YCYL", YCYL);
+     162           1 :   if (YCYL.size() > 1)
+     163           0 :     error("YCYL cannot take more than one value.");
+     164           1 :   if (YCYL.size() == 0)
+     165           1 :     YCYL.push_back(-1.0);
+     166             : 
+     167           1 :   checkRead();
+     168             : 
+     169             :   std::vector<AtomNumber> atoms;
+     170       12289 :   for (unsigned i = 0; i < UMEM.size(); i++)
+     171             :   {
+     172       12288 :     atoms.push_back(UMEM[i]);
+     173             :   }
+     174       12289 :   for (unsigned i = 0; i < LMEM.size(); i++)
+     175             :   {
+     176       12288 :     atoms.push_back(LMEM[i]);
+     177             :   }
+     178        4097 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     179             :   {
+     180        4096 :     atoms.push_back(TAILS[i]);
+     181             :   }
+     182             : 
+     183           1 :   addValueWithDerivatives();
+     184           1 :   setNotPeriodic();
+     185           1 :   requestAtoms(atoms);
+     186           1 : }
+     187             : 
+     188           3 : void memFusionP::calculate()
+     189             : {
+     190             :   /**************************
+     191             :    *                        *
+     192             :    *         System         *
+     193             :    *                        *
+     194             :    **************************/
+     195             : 
+     196             :   // Box dimensions.
+     197           3 :   double Lx = getBox()[0][0], Ly = getBox()[1][1], Lz = getBox()[2][2];
+     198             : 
+     199             :   // Z center of the upper membrane (uMem) and lower membrane (lMem) for systems with PBC: https://en.wikipedia.org/wiki/Center_of_mass#Systems_with_periodic_boundary_conditions .
+     200             :   double ZuMem, ZuMemcos = 0.0, ZuMemsin = 0.0, uMemAngle, ZlMem, ZlMemcos = 0.0, ZlMemsin = 0.0, lMemAngle;
+     201             : 
+     202             : #ifdef _OPENMP
+     203             : #if _OPENMP >= 201307
+     204           3 :   #pragma omp parallel for private(uMemAngle, lMemAngle) reduction(+:ZuMemcos, ZuMemsin, ZlMemcos, ZlMemsin)
+     205             : #endif
+     206             : #endif
+     207             :   for (unsigned i = 0; i < UMEM.size(); i++)
+     208             :   {
+     209             :     uMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i)))[2];
+     210             :     lMemAngle = 2.0 * M_PI * getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + UMEM.size())))[2];
+     211             :     ZuMemcos += cos(uMemAngle);
+     212             :     ZuMemsin += sin(uMemAngle);
+     213             :     ZlMemcos += cos(lMemAngle);
+     214             :     ZlMemsin += sin(lMemAngle);
+     215             :   }
+     216             : 
+     217           3 :   ZuMemcos = ZuMemcos / UMEM.size();
+     218           3 :   ZuMemsin = ZuMemsin / UMEM.size();
+     219           3 :   ZlMemcos = ZlMemcos / UMEM.size();
+     220           3 :   ZlMemsin = ZlMemsin / UMEM.size();
+     221             : 
+     222           3 :   ZuMem = Lz * (atan2(-ZuMemsin, -ZuMemcos) + M_PI) / (2.0 * M_PI);
+     223           3 :   ZlMem = Lz * (atan2(-ZlMemsin, -ZlMemcos) + M_PI) / (2.0 * M_PI);
+     224             : 
+     225             :   // Z center of the boths membranes (upper and lower).
+     226           3 :   double ZMems = (ZuMem + ZlMem) / 2.0;
+     227             : 
+     228             :   /*************************
+     229             :    *                        *
+     230             :    *         Xi_Mem         *
+     231             :    *                        *
+     232             :    **************************/
+     233             : 
+     234             :   // Quantity of beads of the membranes.
+     235           3 :   unsigned membraneBeads = UMEM.size() + LMEM.size();
+     236             : 
+     237             :   // Z distance from the lipid tail to the geometric center of both membranes.
+     238             :   double ZTailDistance;
+     239             : 
+     240             :   // Z position of the first slice.
+     241           3 :   double firstSliceZ_Mem = ZMems + (0.0 + 0.5 - NSMEM[0] / 2.0) * DSMEM[0];
+     242             : 
+     243             :   // Z distance between the first slice and the Z center of the membrane.
+     244           6 :   double firstSliceZDist_Mem = pbcDistance(Vector(0.0, 0.0, firstSliceZ_Mem), Vector(0.0, 0.0, ZMems))[2];
+     245             : 
+     246             :   // Position in the cylinder.
+     247             :   double PositionS_Mem;
+     248             : 
+     249             :   // Slices to analyze per particle.
+     250           3 :   std::vector<unsigned> s1_Mem(TAILS.size()), s2_Mem(TAILS.size());
+     251             : 
+     252             :   // Mark the particles to analyze.
+     253           3 :   std::vector<double> analyzeThisParticle_Mem(TAILS.size());
+     254             : 
+     255             :   // Eq. 7 Hub & Awasthi JCTC 2017.
+     256           3 :   std::vector<double> faxial_Mem(TAILS.size() * NSMEM[0]);
+     257             : 
+     258             :   // Eq. 16 Hub & Awasthi JCTC 2017.
+     259           3 :   std::vector<double> d_faxial_Mem_dz(TAILS.size() * NSMEM[0]);
+     260             : 
+     261             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     262           3 :   std::vector<double> Fs_Mem(NSMEM[0]);
+     263             : 
+     264             :   // Eq. 11 Hub & Awasthi JCTC 2017.
+     265           3 :   std::vector<double> ws_Mem(NSMEM[0]);
+     266             : 
+     267             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     268             :   double W_Mem = 0.0;
+     269             : 
+     270             :   // Eq. 21 and 22 Hub & Awasthi JCTC 2017.
+     271           3 :   std::vector<double> sx_Mem(NSMEM[0]), sy_Mem(NSMEM[0]), cx_Mem(NSMEM[0]), cy_Mem(NSMEM[0]);
+     272             : 
+     273             :   // Eq. 10 Hub & Awasthi JCTC 2017.
+     274             :   double Xsc_Mem = 0.0, Xcc_Mem = 0.0, Ysc_Mem = 0.0, Ycc_Mem = 0.0;
+     275             : 
+     276             :   // Aux.
+     277             :   double x, aux;
+     278             : 
+     279             :   // Scaled position of the lipid tail respect the origin of coordinates.
+     280           3 :   Vector TailPosition;
+     281             : 
+     282             :   // Thanks stack overflow.
+     283             : #ifdef _OPENMP
+     284             : #if _OPENMP >= 201307
+     285             :   #pragma omp declare reduction(vec_double_plus : std::vector<double> : \
+     286             :   std::transform(omp_out.begin(), omp_out.end(), omp_in.begin(), omp_out.begin(), std::plus<double>())) \
+     287             :   initializer(omp_priv = decltype(omp_orig)(omp_orig.size()))
+     288             : #endif
+     289             : #endif
+     290             : 
+     291             : #ifdef _OPENMP
+     292             : #if _OPENMP >= 201307
+     293           3 :   #pragma omp parallel for private(ZTailDistance, PositionS_Mem, TailPosition, x, aux) reduction(vec_double_plus:Fs_Mem, sx_Mem, sy_Mem, cx_Mem, cy_Mem)
+     294             : #endif
+     295             : #endif
+     296             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     297             :   {
+     298             :     ZTailDistance = pbcDistance(Vector(0.0, 0.0, ZMems), getPosition(i + membraneBeads))[2];
+     299             :     PositionS_Mem = (ZTailDistance + firstSliceZDist_Mem) / DSMEM[0];
+     300             :     // If the following condition is met the particle is in the Z space of the cylinder.
+     301             :     if ((PositionS_Mem >= (-0.5 - HMEM[0])) && (PositionS_Mem <= (NSMEM[0] + 0.5 - 1.0 + HMEM[0])))
+     302             :     {
+     303             :       analyzeThisParticle_Mem[i] = 1.0;
+     304             :       // Defining the slices to analyze each particle.
+     305             :       if (PositionS_Mem < 1)
+     306             :       {
+     307             :         s1_Mem[i] = 0;
+     308             :         s2_Mem[i] = 2;
+     309             :       }
+     310             :       else if (PositionS_Mem <= (NSMEM[0] - 2.0))
+     311             :       {
+     312             :         s1_Mem[i] = floor(PositionS_Mem) - 1;
+     313             :         s2_Mem[i] = floor(PositionS_Mem) + 1;
+     314             :       }
+     315             :       else
+     316             :       {
+     317             :         s1_Mem[i] = NSMEM[0] - 3;
+     318             :         s2_Mem[i] = NSMEM[0] - 1;
+     319             :       }
+     320             : 
+     321             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     322             : 
+     323             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     324             :       {
+     325             :         x = (ZTailDistance - (s + 0.5 - NSMEM[0] / 2.0) * DSMEM[0]) * 2.0 / DSMEM[0];
+     326             :         if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     327             :         {
+     328             :           if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     329             :           {
+     330             :             faxial_Mem[i + TAILS.size() * s] = 1.0;
+     331             :             Fs_Mem[s] += 1.0;
+     332             :             sx_Mem[s] += sin(2.0 * M_PI * TailPosition[0]);
+     333             :             sy_Mem[s] += sin(2.0 * M_PI * TailPosition[1]);
+     334             :             cx_Mem[s] += cos(2.0 * M_PI * TailPosition[0]);
+     335             :             cy_Mem[s] += cos(2.0 * M_PI * TailPosition[1]);
+     336             :           }
+     337             :           else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     338             :           {
+     339             :             aux = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     340             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     341             :             d_faxial_Mem_dz[i + TAILS.size() * s] = ((-3.0 / (4.0 * HMEM[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * 2.0 / DSMEM[0];
+     342             :             Fs_Mem[s] += aux;
+     343             :             sx_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[0]);
+     344             :             sy_Mem[s] += aux * sin(2.0 * M_PI * TailPosition[1]);
+     345             :             cx_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[0]);
+     346             :             cy_Mem[s] += aux * cos(2.0 * M_PI * TailPosition[1]);
+     347             :           }
+     348             :           else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     349             :           {
+     350             :             aux = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     351             :             faxial_Mem[i + TAILS.size() * s] = aux;
+     352             :             d_faxial_Mem_dz[i + TAILS.size() * s] = ((3.0 / (4.0 * HMEM[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * 2.0 / DSMEM[0];
+     353             :             Fs_Mem[s] += aux;
+     354             :             sx_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[0]));
+     355             :             sy_Mem[s] += (aux * sin(2.0 * M_PI * TailPosition[1]));
+     356             :             cx_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[0]));
+     357             :             cy_Mem[s] += (aux * cos(2.0 * M_PI * TailPosition[1]));
+     358             :           }
+     359             :         }
+     360             :       }
+     361             :     }
+     362             :   }
+     363             : 
+     364         213 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     365             :   {
+     366         210 :     if (Fs_Mem[s] != 0.0)
+     367             :     {
+     368         106 :       ws_Mem[s] = tanh(Fs_Mem[s]);
+     369         106 :       W_Mem += ws_Mem[s];
+     370         106 :       sx_Mem[s] = sx_Mem[s] / Fs_Mem[s];
+     371         106 :       sy_Mem[s] = sy_Mem[s] / Fs_Mem[s];
+     372         106 :       cx_Mem[s] = cx_Mem[s] / Fs_Mem[s];
+     373         106 :       cy_Mem[s] = cy_Mem[s] / Fs_Mem[s];
+     374         106 :       Xsc_Mem += sx_Mem[s] * ws_Mem[s];
+     375         106 :       Ysc_Mem += sy_Mem[s] * ws_Mem[s];
+     376         106 :       Xcc_Mem += cx_Mem[s] * ws_Mem[s];
+     377         106 :       Ycc_Mem += cy_Mem[s] * ws_Mem[s];
+     378             :     }
+     379             :   }
+     380             : 
+     381           3 :   Xsc_Mem = Xsc_Mem / W_Mem;
+     382           3 :   Ysc_Mem = Ysc_Mem / W_Mem;
+     383           3 :   Xcc_Mem = Xcc_Mem / W_Mem;
+     384           3 :   Ycc_Mem = Ycc_Mem / W_Mem;
+     385             : 
+     386             :   // Eq. 12 Hub & Awasthi JCTC 2017.
+     387             :   double Xcyl_Mem, Ycyl_Mem;
+     388             : 
+     389           3 :   if ((XCYL[0] > 0.0) && (YCYL[0] > 0.0))
+     390             :   {
+     391             :     Xcyl_Mem = XCYL[0];
+     392             :     Ycyl_Mem = YCYL[0];
+     393             :   }
+     394             :   else
+     395             :   {
+     396           3 :     Xcyl_Mem = (atan2(-Xsc_Mem, -Xcc_Mem) + M_PI) * Lx / (2 * M_PI);
+     397           3 :     Ycyl_Mem = (atan2(-Ysc_Mem, -Ycc_Mem) + M_PI) * Ly / (2 * M_PI);
+     398             :   }
+     399             : 
+     400             :   // Eq. 25, 26 and 27 Hub & Awasthi JCTC 2017.
+     401             :   double d_sx_Mem_dx, d_sx_Mem_dz, d_sy_Mem_dy, d_sy_Mem_dz, d_cx_Mem_dx, d_cx_Mem_dz, d_cy_Mem_dy, d_cy_Mem_dz;
+     402             : 
+     403             :   // Eq. 29 Hub & Awasthi JCTC 2017.
+     404             :   double d_ws_Mem_dz;
+     405             : 
+     406             :   // Eq. 31, 32 and 33 Hub & Awasthi JCTC 2017
+     407             :   double d_Xsc_Mem_dx, d_Xsc_Mem_dz, d_Xcc_Mem_dx, d_Xcc_Mem_dz, d_Ysc_Mem_dy, d_Ysc_Mem_dz, d_Ycc_Mem_dy, d_Ycc_Mem_dz;
+     408             : 
+     409             :   // Center of the cylinder. XY components are calculated (or defined), Z is the Z geometric center of the membranes of the system.
+     410           6 :   Vector xyzCyl_Mem = pbcDistance(Vector(0.0, 0.0, 0.0), Vector(Xcyl_Mem, Ycyl_Mem, ZMems));
+     411             : 
+     412             :   // Distances from the lipid tails to center of the cylinder.
+     413           3 :   std::vector<Vector> CylDistances_Mem(TAILS.size());
+     414             : 
+     415             :   // XY distance from the lipid tails to the center of the cylinder.
+     416             :   double ri_Mem;
+     417             : 
+     418             :   // Eq. 8 Hub & Awasthi JCTC 2017.
+     419             :   double fradial_Mem = 0;
+     420             : 
+     421             :   // Eq. 15 Hub & Awasthi JCTC 2017.
+     422           3 :   std::vector<double> d_fradial_Mem_dx(TAILS.size()), d_fradial_Mem_dy(TAILS.size());
+     423             : 
+     424             :   // Eq. 35, 36, 37 and 38 Hub & Awasthi JCTC 2017.
+     425           3 :   std::vector<double> d_Xcyl_Mem_dx(TAILS.size()), d_Xcyl_Mem_dz(TAILS.size()), d_Ycyl_Mem_dy(TAILS.size()), d_Ycyl_Mem_dz(TAILS.size());
+     426             : 
+     427             :   // To avoid rare instabilities auxX_Mem and auxY_Mem are truncated at a configurable value (default = 500).
+     428           3 :   double auxX_Mem = (1 / (pow(Xsc_Mem, 2) + pow(Xcc_Mem, 2))), auxY_Mem = (1 / (pow(Ysc_Mem, 2) + pow(Ycc_Mem, 2)));
+     429             : 
+     430           3 :   if (auxX_Mem > ONEOVERS2C2CUTOFF[0])
+     431             :   {
+     432           0 :     auxX_Mem = Lx * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     433             :   }
+     434             :   else
+     435             :   {
+     436           3 :     auxX_Mem = Lx * auxX_Mem / (2 * M_PI);
+     437             :   }
+     438             : 
+     439           3 :   if (auxY_Mem > ONEOVERS2C2CUTOFF[0])
+     440             :   {
+     441           0 :     auxY_Mem = Ly * ONEOVERS2C2CUTOFF[0] / (2 * M_PI);
+     442             :   }
+     443             :   else
+     444             :   {
+     445           3 :     auxY_Mem = Ly * auxY_Mem / (2 * M_PI);
+     446             :   }
+     447             : 
+     448             :   // Number of lipid tails within the slice s of the membranes cylinder.
+     449           3 :   std::vector<double> Nsp_Mem(NSMEM[0]), psi_Mem(NSMEM[0]), d_psi_Mem(NSMEM[0]);
+     450             : 
+     451             :   // Eq. 3 Hub & Awasthi JCTC 2017.
+     452           3 :   double b_Mem = (ZETAMEM[0] / (1.0 - ZETAMEM[0])), c_Mem = ((1.0 - ZETAMEM[0]) * exp(b_Mem));
+     453             : 
+     454             :   // Eq. 19 Hub & Awasthi JCTC 2017.
+     455           3 :   std::vector<double> fradial_Mem_d_faxial_Mem_dz(TAILS.size() * NSMEM[0]);
+     456             : 
+     457             :   // Eq. 20 Hub & Awasthi JCTC 2017.
+     458           3 :   std::vector<double> Axs_Mem(NSMEM[0]), Ays_Mem(NSMEM[0]);
+     459             : 
+     460             :   // Eq. 1 Hub & Awasthi JCTC 2017. This is the CV that describes de Pore Nucleation.
+     461           3 :   double Xi_Mem = 0.0;
+     462             : 
+     463             : #ifdef _OPENMP
+     464             : #if _OPENMP >= 201307
+     465           3 :   #pragma omp parallel for private(TailPosition,d_Xsc_Mem_dx,d_Xcc_Mem_dx,d_Ysc_Mem_dy,d_Ycc_Mem_dy,d_Xsc_Mem_dz,d_Xcc_Mem_dz,d_Ysc_Mem_dz,d_Ycc_Mem_dz,d_sx_Mem_dx,d_sy_Mem_dy,d_cx_Mem_dx,d_cy_Mem_dy,d_sx_Mem_dz,d_sy_Mem_dz,d_cx_Mem_dz,d_cy_Mem_dz,d_ws_Mem_dz,ri_Mem,x,fradial_Mem) reduction(vec_double_plus: Nsp_Mem, Axs_Mem, Ays_Mem)
+     466             : #endif
+     467             : #endif
+     468             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     469             :   {
+     470             :     if (analyzeThisParticle_Mem[i])
+     471             :     {
+     472             :       TailPosition = getPbc().realToScaled(pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     473             :       d_Xsc_Mem_dx = 0.0;
+     474             :       d_Xcc_Mem_dx = 0.0;
+     475             :       d_Ysc_Mem_dy = 0.0;
+     476             :       d_Ycc_Mem_dy = 0.0;
+     477             :       d_Xsc_Mem_dz = 0.0;
+     478             :       d_Xcc_Mem_dz = 0.0;
+     479             :       d_Ysc_Mem_dz = 0.0;
+     480             :       d_Ycc_Mem_dz = 0.0;
+     481             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     482             :       {
+     483             :         if (Fs_Mem[s] != 0.0)
+     484             :         {
+     485             :           d_sx_Mem_dx = faxial_Mem[i + TAILS.size() * s] * 2.0 * M_PI * cos(2.0 * M_PI * TailPosition[0]) / (Lx * Fs_Mem[s]);
+     486             :           d_sy_Mem_dy = faxial_Mem[i + TAILS.size() * s] * 2.0 * M_PI * cos(2.0 * M_PI * TailPosition[1]) / (Ly * Fs_Mem[s]);
+     487             :           d_cx_Mem_dx = -faxial_Mem[i + TAILS.size() * s] * 2.0 * M_PI * sin(2.0 * M_PI * TailPosition[0]) / (Lx * Fs_Mem[s]);
+     488             :           d_cy_Mem_dy = -faxial_Mem[i + TAILS.size() * s] * 2.0 * M_PI * sin(2.0 * M_PI * TailPosition[1]) / (Ly * Fs_Mem[s]);
+     489             :           d_Xsc_Mem_dx += ws_Mem[s] * d_sx_Mem_dx / W_Mem;
+     490             :           d_Xcc_Mem_dx += ws_Mem[s] * d_cx_Mem_dx / W_Mem;
+     491             :           d_Ysc_Mem_dy += ws_Mem[s] * d_sy_Mem_dy / W_Mem;
+     492             :           d_Ycc_Mem_dy += ws_Mem[s] * d_cy_Mem_dy / W_Mem;
+     493             : 
+     494             :           d_sx_Mem_dz = d_faxial_Mem_dz[i + TAILS.size() * s] * (sin(2.0 * M_PI * TailPosition[0]) - sx_Mem[s]) / Fs_Mem[s];
+     495             :           d_sy_Mem_dz = d_faxial_Mem_dz[i + TAILS.size() * s] * (sin(2.0 * M_PI * TailPosition[1]) - sy_Mem[s]) / Fs_Mem[s];
+     496             :           d_cx_Mem_dz = d_faxial_Mem_dz[i + TAILS.size() * s] * (cos(2.0 * M_PI * TailPosition[0]) - cx_Mem[s]) / Fs_Mem[s];
+     497             :           d_cy_Mem_dz = d_faxial_Mem_dz[i + TAILS.size() * s] * (cos(2.0 * M_PI * TailPosition[1]) - cy_Mem[s]) / Fs_Mem[s];
+     498             :           d_ws_Mem_dz = (1 - pow(ws_Mem[s], 2)) * d_faxial_Mem_dz[i + TAILS.size() * s];
+     499             :           d_Xsc_Mem_dz += (ws_Mem[s] * d_sx_Mem_dz + d_ws_Mem_dz * (sx_Mem[s] - Xsc_Mem)) / W_Mem;
+     500             :           d_Xcc_Mem_dz += (ws_Mem[s] * d_cx_Mem_dz + d_ws_Mem_dz * (cx_Mem[s] - Xcc_Mem)) / W_Mem;
+     501             :           d_Ysc_Mem_dz += (ws_Mem[s] * d_sy_Mem_dz + d_ws_Mem_dz * (sy_Mem[s] - Ysc_Mem)) / W_Mem;
+     502             :           d_Ycc_Mem_dz += (ws_Mem[s] * d_cy_Mem_dz + d_ws_Mem_dz * (cy_Mem[s] - Ycc_Mem)) / W_Mem;
+     503             :         }
+     504             :       }
+     505             :       d_Xcyl_Mem_dx[i] = auxX_Mem * (-Xsc_Mem * d_Xcc_Mem_dx + Xcc_Mem * d_Xsc_Mem_dx);
+     506             :       d_Xcyl_Mem_dz[i] = auxX_Mem * (-Xsc_Mem * d_Xcc_Mem_dz + Xcc_Mem * d_Xsc_Mem_dz);
+     507             :       d_Ycyl_Mem_dy[i] = auxY_Mem * (-Ysc_Mem * d_Ycc_Mem_dy + Ycc_Mem * d_Ysc_Mem_dy);
+     508             :       d_Ycyl_Mem_dz[i] = auxY_Mem * (-Ysc_Mem * d_Ycc_Mem_dz + Ycc_Mem * d_Ysc_Mem_dz);
+     509             : 
+     510             :       CylDistances_Mem[i] = pbcDistance(xyzCyl_Mem, pbcDistance(Vector(0.0, 0.0, 0.0), getPosition(i + membraneBeads)));
+     511             :       ri_Mem = sqrt(pow(CylDistances_Mem[i][0], 2) + pow(CylDistances_Mem[i][1], 2));
+     512             :       x = ri_Mem / RCYLMEM[0];
+     513             :       if (!((x <= -1.0 - HMEM[0]) || (x >= 1.0 + HMEM[0])))
+     514             :       {
+     515             :         if (((-1.0 + HMEM[0]) <= x) && (x <= (1.0 - HMEM[0])))
+     516             :         {
+     517             :           fradial_Mem = 1.0;
+     518             :         }
+     519             :         else if (((1.0 - HMEM[0]) < x) && (x < (1.0 + HMEM[0])))
+     520             :         {
+     521             :           fradial_Mem = 0.5 - ((3.0 * x - 3.0) / (4.0 * HMEM[0])) + (pow((x - 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     522             :           d_fradial_Mem_dx[i] = ((-3.0 / (4.0 * HMEM[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * CylDistances_Mem[i][0] / (RCYLMEM[0] * ri_Mem);
+     523             :           d_fradial_Mem_dy[i] = ((-3.0 / (4.0 * HMEM[0])) + ((3.0 * pow((x - 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * CylDistances_Mem[i][1] / (RCYLMEM[0] * ri_Mem);
+     524             :         }
+     525             :         else if (((-1.0 - HMEM[0]) < x) && (x < (-1.0 + HMEM[0])))
+     526             :         {
+     527             :           fradial_Mem = 0.5 + ((3.0 * x + 3.0) / (4.0 * HMEM[0])) - (pow((x + 1.0), 3) / (4.0 * pow(HMEM[0], 3)));
+     528             :           d_fradial_Mem_dx[i] = ((3.0 / (4.0 * HMEM[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * CylDistances_Mem[i][0] / (RCYLMEM[0] * ri_Mem);
+     529             :           d_fradial_Mem_dy[i] = ((3.0 / (4.0 * HMEM[0])) - ((3.0 * pow((x + 1), 2)) / (4.0 * pow(HMEM[0], 3)))) * CylDistances_Mem[i][1] / (RCYLMEM[0] * ri_Mem);
+     530             :         }
+     531             : 
+     532             :         for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     533             :         {
+     534             :           Nsp_Mem[s] += fradial_Mem * faxial_Mem[i + TAILS.size() * s];
+     535             :           Axs_Mem[s] += faxial_Mem[i + TAILS.size() * s] * d_fradial_Mem_dx[i];
+     536             :           Ays_Mem[s] += faxial_Mem[i + TAILS.size() * s] * d_fradial_Mem_dy[i];
+     537             :           fradial_Mem_d_faxial_Mem_dz[i + TAILS.size() * s] = fradial_Mem * d_faxial_Mem_dz[i + TAILS.size() * s];
+     538             :         }
+     539             :       }
+     540             :     }
+     541             :   }
+     542             : 
+     543         213 :   for (unsigned s = 0; s < NSMEM[0]; s++)
+     544             :   {
+     545         210 :     if (Nsp_Mem[s] <= 1.0)
+     546             :     {
+     547         166 :       psi_Mem[s] = ZETAMEM[0] * Nsp_Mem[s];
+     548         166 :       d_psi_Mem[s] = ZETAMEM[0];
+     549         166 :       Xi_Mem += psi_Mem[s];
+     550             :     }
+     551             :     else
+     552             :     {
+     553          44 :       psi_Mem[s] = 1.0 - c_Mem * exp(-b_Mem * Nsp_Mem[s]);
+     554          44 :       d_psi_Mem[s] = b_Mem * c_Mem * exp(-b_Mem * Nsp_Mem[s]);
+     555          44 :       Xi_Mem += psi_Mem[s];
+     556             :     }
+     557             :   }
+     558             : 
+     559           3 :   Xi_Mem = Xi_Mem / NSMEM[0];
+     560             : 
+     561             :   // Eq. 18 Hub & Awasthi JCTC 2017.
+     562           3 :   std::vector<double> faxial_Mem_d_fradial_Mem_dx(TAILS.size() * NSMEM[0]), faxial_Mem_d_fradial_Mem_dy(TAILS.size() * NSMEM[0]), faxial_Mem_d_fradial_Mem_dz(TAILS.size() * NSMEM[0]);
+     563             : 
+     564             :   // Eq. 13 Hub & Awasthi JCTC 2017.
+     565           3 :   std::vector<Vector> derivatives_Mem(TAILS.size());
+     566             : 
+     567             : #ifdef _OPENMP
+     568             : #if _OPENMP >= 201307
+     569           3 :   #pragma omp parallel for private(aux)
+     570             : #endif
+     571             : #endif
+     572             :   for (unsigned i = 0; i < TAILS.size(); i++)
+     573             :   {
+     574             :     if (analyzeThisParticle_Mem[i])
+     575             :     {
+     576             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     577             :       {
+     578             :         if (faxial_Mem[i + TAILS.size() * s])
+     579             :         {
+     580             :           faxial_Mem_d_fradial_Mem_dx[i + TAILS.size() * s] = faxial_Mem[i + TAILS.size() * s] * d_fradial_Mem_dx[i] - d_Xcyl_Mem_dx[i] * Axs_Mem[s];
+     581             :           faxial_Mem_d_fradial_Mem_dy[i + TAILS.size() * s] = faxial_Mem[i + TAILS.size() * s] * d_fradial_Mem_dy[i] - d_Ycyl_Mem_dy[i] * Ays_Mem[s];
+     582             :           faxial_Mem_d_fradial_Mem_dz[i + TAILS.size() * s] = -d_Xcyl_Mem_dz[i] * Axs_Mem[s] - d_Ycyl_Mem_dz[i] * Ays_Mem[s];
+     583             :         }
+     584             :       }
+     585             : 
+     586             :       for (unsigned s = s1_Mem[i]; s <= s2_Mem[i]; s++)
+     587             :       {
+     588             :         aux = d_psi_Mem[s] / NSMEM[0];
+     589             :         derivatives_Mem[i][0] += aux * faxial_Mem_d_fradial_Mem_dx[i + TAILS.size() * s];
+     590             :         derivatives_Mem[i][1] += aux * faxial_Mem_d_fradial_Mem_dy[i + TAILS.size() * s];
+     591             :         derivatives_Mem[i][2] += aux * (faxial_Mem_d_fradial_Mem_dz[i + TAILS.size() * s] + fradial_Mem_d_faxial_Mem_dz[i + TAILS.size() * s]);
+     592             :       }
+     593             :     }
+     594             :   }
+     595             : 
+     596             :   // Derivatives and virial for the Xi_Mem.
+     597           3 :   Tensor virial;
+     598       12291 :   for (unsigned i = 0; i < TAILS.size(); i++)
+     599             :   {
+     600       12288 :     setAtomsDerivatives((i + membraneBeads), derivatives_Mem[i]);
+     601       12288 :     virial -= Tensor(CylDistances_Mem[i], derivatives_Mem[i]);
+     602             :   }
+     603             : 
+     604           3 :   setValue(Xi_Mem);
+     605           3 :   setBoxDerivatives(virial);
+     606           3 : }
+     607             : }
+     608             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/index-sort-f.html b/coverage/membranefusion/index-sort-f.html new file mode 100644 index 000000000000..45da955aafe7 --- /dev/null +++ b/coverage/membranefusion/index-sort-f.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusionHitTotalCoverage
Test:plumed test coverageLines:45351488.1 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
MemFusionP.cpp +
88.7%88.7%
+
88.7 %133 / 15075.0 %3 / 4
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %137 / 15775.0 %3 / 4
FusionPoreNucleationP.cpp +
88.4%88.4%
+
88.4 %183 / 20775.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/index-sort-l.html b/coverage/membranefusion/index-sort-l.html new file mode 100644 index 000000000000..6fbaacb22adb --- /dev/null +++ b/coverage/membranefusion/index-sort-l.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusionHitTotalCoverage
Test:plumed test coverageLines:45351488.1 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %137 / 15775.0 %3 / 4
FusionPoreNucleationP.cpp +
88.4%88.4%
+
88.4 %183 / 20775.0 %3 / 4
MemFusionP.cpp +
88.7%88.7%
+
88.7 %133 / 15075.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/membranefusion/index.html b/coverage/membranefusion/index.html new file mode 100644 index 000000000000..2c804561579f --- /dev/null +++ b/coverage/membranefusion/index.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - membranefusion + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - membranefusionHitTotalCoverage
Test:plumed test coverageLines:45351488.1 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FusionPoreExpansionP.cpp +
87.3%87.3%
+
87.3 %137 / 15775.0 %3 / 4
FusionPoreNucleationP.cpp +
88.4%88.4%
+
88.4 %183 / 20775.0 %3 / 4
MemFusionP.cpp +
88.7%88.7%
+
88.7 %133 / 15075.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.cpp.func-sort-c.html b/coverage/multicolvar/ActionVolume.cpp.func-sort-c.html new file mode 100644 index 000000000000..eed9b1b1109f --- /dev/null +++ b/coverage/multicolvar/ActionVolume.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/ActionVolume.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - ActionVolume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3939100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12ActionVolumeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12ActionVolumeC2ERKNS_13ActionOptionsE28
_ZN4PLMD11multicolvar12ActionVolume16registerKeywordsERNS_8KeywordsE40
_ZNK4PLMD11multicolvar12ActionVolume19calculateAllVolumesERKjRNS_10MultiValueE69358
_ZNK4PLMD11multicolvar12ActionVolume18inVolumeOfInterestERKj148129
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.cpp.func.html b/coverage/multicolvar/ActionVolume.cpp.func.html new file mode 100644 index 000000000000..0dabf6810b2b --- /dev/null +++ b/coverage/multicolvar/ActionVolume.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/ActionVolume.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - ActionVolume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3939100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12ActionVolume16registerKeywordsERNS_8KeywordsE40
_ZN4PLMD11multicolvar12ActionVolumeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12ActionVolumeC2ERKNS_13ActionOptionsE28
_ZNK4PLMD11multicolvar12ActionVolume18inVolumeOfInterestERKj148129
_ZNK4PLMD11multicolvar12ActionVolume19calculateAllVolumesERKjRNS_10MultiValueE69358
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.cpp.gcov.html b/coverage/multicolvar/ActionVolume.cpp.gcov.html new file mode 100644 index 000000000000..dd5cfc4f9dfa --- /dev/null +++ b/coverage/multicolvar/ActionVolume.cpp.gcov.html @@ -0,0 +1,161 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/ActionVolume.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - ActionVolume.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3939100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionVolume.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace multicolvar {
+      26             : 
+      27          40 : void ActionVolume::registerKeywords( Keywords& keys ) {
+      28          40 :   VolumeGradientBase::registerKeywords( keys );
+      29         120 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+      30         120 :   keys.use("MEAN"); keys.use("LESS_THAN"); keys.use("MORE_THAN");
+      31         120 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("SUM");
+      32          80 :   keys.add("compulsory","SIGMA","the width of the function to be used for kernel density estimation");
+      33          80 :   keys.add("compulsory","KERNEL","gaussian","the type of kernel function to be used");
+      34          80 :   keys.addFlag("OUTSIDE",false,"calculate quantities for colvars that are on atoms outside the region of interest");
+      35          40 : }
+      36             : 
+      37          28 : ActionVolume::ActionVolume(const ActionOptions&ao):
+      38             :   Action(ao),
+      39          28 :   VolumeGradientBase(ao)
+      40             : {
+      41             :   // Find number of quantities
+      42          28 :   if( getPntrToMultiColvar()->isDensity() ) nquantities=2;                           // Value + weight
+      43          17 :   else if( getPntrToMultiColvar()->getNumberOfQuantities()==2 ) nquantities=2;       // Value + weight
+      44           2 :   else nquantities = 1 + getPntrToMultiColvar()->getNumberOfQuantities()-2 + 1;      // Norm  + vector + weight
+      45             : 
+      46             :   // Output some nice information
+      47          28 :   std::string functype=getPntrToMultiColvar()->getName();
+      48         279 :   std::transform( functype.begin(), functype.end(), functype.begin(), [](unsigned char c) { return std::tolower(c); } );
+      49          28 :   log.printf("  calculating %s inside region of insterest\n",functype.c_str() );
+      50             : 
+      51          28 :   parseFlag("OUTSIDE",not_in); sigma=0.0;
+      52          81 :   if( keywords.exists("SIGMA") ) parse("SIGMA",sigma);
+      53          84 :   if( keywords.exists("KERNEL") ) parse("KERNEL",kerneltype);
+      54             : 
+      55          28 :   if( getPntrToMultiColvar()->isDensity() ) {
+      56             :     std::string input;
+      57          22 :     addVessel( "SUM", input, -1 );  // -1 here means that this value will be named getLabel()
+      58             :   }
+      59          28 :   readVesselKeywords();
+      60          28 : }
+      61             : 
+      62       69358 : void ActionVolume::calculateAllVolumes( const unsigned& curr, MultiValue& outvals ) const {
+      63       69358 :   Vector catom_pos=getPntrToMultiColvar()->getCentralAtomPos( curr );
+      64             : 
+      65       69358 :   double weight; Vector wdf; Tensor vir; std::vector<Vector> refders( getNumberOfAtoms() );
+      66       69358 :   weight=calculateNumberInside( catom_pos, wdf, vir, refders );
+      67       69358 :   if( not_in ) {
+      68        4000 :     weight = 1.0 - weight; wdf *= -1.; vir *=-1;
+      69        8000 :     for(unsigned i=0; i<refders.size(); ++i) refders[i]*=-1;
+      70             :   }
+      71       69358 :   setNumberInVolume( 0, curr, weight, wdf, vir, refders, outvals );
+      72       69358 : }
+      73             : 
+      74      148129 : bool ActionVolume::inVolumeOfInterest( const unsigned& curr ) const {
+      75      148129 :   Vector catom_pos=getPntrToMultiColvar()->getCentralAtomPos( curr );
+      76      148129 :   Vector wdf; Tensor vir; std::vector<Vector> refders( getNumberOfAtoms() );
+      77      148129 :   double weight=calculateNumberInside( catom_pos, wdf, vir, refders );
+      78      148129 :   if( not_in ) weight = 1.0 - weight;
+      79      148129 :   if( weight<getTolerance() ) return false;
+      80             :   return true;
+      81             : }
+      82             : 
+      83             : }
+      84             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.h.func-sort-c.html b/coverage/multicolvar/ActionVolume.h.func-sort-c.html new file mode 100644 index 000000000000..261ae0bbd483 --- /dev/null +++ b/coverage/multicolvar/ActionVolume.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/ActionVolume.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - ActionVolume.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar12ActionVolume21getNumberOfQuantitiesEv71213
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.h.func.html b/coverage/multicolvar/ActionVolume.h.func.html new file mode 100644 index 000000000000..bbb8f72921f9 --- /dev/null +++ b/coverage/multicolvar/ActionVolume.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/ActionVolume.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - ActionVolume.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar12ActionVolume21getNumberOfQuantitiesEv71213
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/ActionVolume.h.gcov.html b/coverage/multicolvar/ActionVolume.h.gcov.html new file mode 100644 index 000000000000..ea30bda4097b --- /dev/null +++ b/coverage/multicolvar/ActionVolume.h.gcov.html @@ -0,0 +1,164 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/ActionVolume.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - ActionVolume.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_multicolvar_ActionVolume_h
+      23             : #define __PLUMED_multicolvar_ActionVolume_h
+      24             : 
+      25             : #include "tools/HistogramBead.h"
+      26             : #include "VolumeGradientBase.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace multicolvar {
+      30             : 
+      31             : /**
+      32             : \ingroup INHERIT
+      33             : This is the abstract base class to use for implementing a new way of defining a particular region of the simulation
+      34             : box. You can use this to calculate the number of atoms inside that part or the average value of a quantity like the
+      35             : coordination number inside that part of the cell.
+      36             : */
+      37             : 
+      38             : class ActionVolume : public VolumeGradientBase {
+      39             : private:
+      40             : /// Number of quantities in use in this colvar
+      41             :   unsigned nquantities;
+      42             : /// The value of sigma
+      43             :   double sigma;
+      44             : /// Are we interested in the area outside the colvar
+      45             :   bool not_in;
+      46             : /// The kernel type for this histogram
+      47             :   std::string kerneltype;
+      48             : protected:
+      49             :   double getSigma() const ;
+      50             :   std::string getKernelType() const ;
+      51             : public:
+      52             :   static void registerKeywords( Keywords& keys );
+      53             :   explicit ActionVolume(const ActionOptions&);
+      54             : /// Get the number of quantities that are calculated each time
+      55             :   unsigned getNumberOfQuantities() const override;
+      56             : /// Calculate whats in the volume
+      57             :   void calculateAllVolumes( const unsigned& curr, MultiValue& outvals ) const override;
+      58             : /// This calculates whether or not a particular is inside the box of interest
+      59             : /// this is used for neighbour list with volumes
+      60             :   bool inVolumeOfInterest( const unsigned& curr ) const ;
+      61             :   virtual double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const=0;
+      62             :   unsigned getCentralAtomElementIndex();
+      63             : };
+      64             : 
+      65             : inline
+      66       71213 : unsigned ActionVolume::getNumberOfQuantities() const {
+      67       71213 :   return nquantities;
+      68             : }
+      69             : 
+      70             : inline
+      71             : double ActionVolume::getSigma() const {
+      72       98014 :   return sigma;
+      73             : }
+      74             : 
+      75             : inline
+      76             : std::string ActionVolume::getKernelType() const {
+      77       58014 :   return kerneltype;
+      78             : }
+      79             : 
+      80             : inline
+      81             : unsigned ActionVolume::getCentralAtomElementIndex() {
+      82             :   return 1;
+      83             : }
+      84             : 
+      85             : }
+      86             : }
+      87             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html b/coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html new file mode 100644 index 000000000000..854b394658cf --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/AlphaBeta.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - AlphaBeta.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505787.7 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9AlphaBeta10isPeriodicEv0
_ZN4PLMD11multicolvar9AlphaBetaC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar9AlphaBetaC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar9AlphaBeta16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD11multicolvar9AlphaBeta7computeERKjRNS0_13AtomValuePackE40
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AlphaBeta.cpp.func.html b/coverage/multicolvar/AlphaBeta.cpp.func.html new file mode 100644 index 000000000000..9d8cfd763cab --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/AlphaBeta.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - AlphaBeta.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505787.7 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9AlphaBeta10isPeriodicEv0
_ZN4PLMD11multicolvar9AlphaBeta16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar9AlphaBetaC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar9AlphaBetaC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar9AlphaBeta7computeERKjRNS0_13AtomValuePackE40
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AlphaBeta.cpp.gcov.html b/coverage/multicolvar/AlphaBeta.cpp.gcov.html new file mode 100644 index 000000000000..f1c9ead731b1 --- /dev/null +++ b/coverage/multicolvar/AlphaBeta.cpp.gcov.html @@ -0,0 +1,281 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/AlphaBeta.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - AlphaBeta.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505787.7 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "tools/Torsion.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace multicolvar {
+      32             : 
+      33             : //+PLUMEDOC COLVAR ALPHABETA
+      34             : /*
+      35             : Measures a distance including pbc between the instantaneous values of a set of torsional angles and set of reference values.
+      36             : 
+      37             : This colvar calculates the following quantity.
+      38             : 
+      39             : \f[
+      40             : s = \frac{1}{2} \sum_i \left[ 1 + \cos( \phi_i - \phi_i^{\textrm{Ref}} ) \right]
+      41             : \f]
+      42             : 
+      43             : where the \f$\phi_i\f$ values are the instantaneous values for the \ref TORSION angles of interest.
+      44             : The \f$\phi_i^{\textrm{Ref}}\f$ values are the user-specified reference values for the torsional angles.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : The following provides an example of the input for an alpha beta similarity.
+      49             : 
+      50             : \plumedfile
+      51             : ALPHABETA ...
+      52             : ATOMS1=168,170,172,188 REFERENCE1=3.14
+      53             : ATOMS2=170,172,188,190 REFERENCE2=3.14
+      54             : ATOMS3=188,190,192,230 REFERENCE3=3.14
+      55             : LABEL=ab
+      56             : ... ALPHABETA
+      57             : PRINT ARG=ab FILE=colvar STRIDE=10
+      58             : \endplumedfile
+      59             : 
+      60             : Because all the reference values are the same we can calculate the same quantity using
+      61             : 
+      62             : \plumedfile
+      63             : ALPHABETA ...
+      64             : ATOMS1=168,170,172,188 REFERENCE=3.14
+      65             : ATOMS2=170,172,188,190
+      66             : ATOMS3=188,190,192,230
+      67             : LABEL=ab
+      68             : ... ALPHABETA
+      69             : PRINT ARG=ab FILE=colvar STRIDE=10
+      70             : \endplumedfile
+      71             : 
+      72             : Writing out the atoms involved in all the torsion angles in this way can be rather tedious. Thankfully if you are working with protein you
+      73             : can avoid this by using the \ref MOLINFO command.  PLUMED uses the pdb file that you provide to this command to learn
+      74             : about the topology of the protein molecule.  This means that you can specify torsion angles using the following syntax:
+      75             : 
+      76             : \plumedfile
+      77             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      78             : MOLINFO MOLTYPE=protein STRUCTURE=myprotein.pdb
+      79             : ALPHABETA ...
+      80             : ATOMS1=@phi-3 REFERENCE=3.14
+      81             : ATOMS2=@psi-3
+      82             : ATOMS3=@phi-4
+      83             : LABEL=ab
+      84             : ... ALPHABETA
+      85             : PRINT ARG=ab FILE=colvar STRIDE=10
+      86             : \endplumedfile
+      87             : 
+      88             : Here, \@phi-3 tells plumed that you would like to calculate the \f$\phi\f$ angle in the third residue of the protein.
+      89             : Similarly \@psi-4 tells plumed that you want to calculate the \f$\psi\f$ angle of the fourth residue of the protein.
+      90             : 
+      91             : 
+      92             : */
+      93             : //+ENDPLUMEDOC
+      94             : 
+      95             : class AlphaBeta : public MultiColvarBase {
+      96             : private:
+      97             :   std::vector<double> target;
+      98             :   std::vector<double> coefficient;
+      99             : public:
+     100             :   static void registerKeywords( Keywords& keys );
+     101             :   explicit AlphaBeta(const ActionOptions&);
+     102             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+     103           0 :   bool isPeriodic() override { return false; }
+     104             : };
+     105             : 
+     106             : PLUMED_REGISTER_ACTION(AlphaBeta,"ALPHABETA")
+     107             : 
+     108           3 : void AlphaBeta::registerKeywords( Keywords& keys ) {
+     109           3 :   MultiColvarBase::registerKeywords( keys );
+     110           6 :   keys.add("numbered","ATOMS","the atoms involved in each of the alpha-beta variables you wish to calculate. "
+     111             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one alpha-beta values will be "
+     112             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     113             :            "specify the indices of four atoms).  The eventual number of quantities calculated by this "
+     114             :            "action will depend on what functions of the distribution you choose to calculate.");
+     115           6 :   keys.reset_style("ATOMS","atoms");
+     116           6 :   keys.add("numbered","REFERENCE","the reference values for each of the torsional angles.  If you use a single REFERENCE value the "
+     117             :            "same reference value is used for all torsional angles");
+     118           6 :   keys.add("numbered","COEFFICIENT","the coefficient for each of the torsional angles.  If you use a single COEFFICIENT value the "
+     119             :            "same reference value is used for all torsional angles");
+     120           6 :   keys.reset_style("REFERENCE","compulsory");
+     121           6 :   keys.reset_style("COEFFICIENT","optional");
+     122           3 : }
+     123             : 
+     124           1 : AlphaBeta::AlphaBeta(const ActionOptions&ao):
+     125             :   Action(ao),
+     126           1 :   MultiColvarBase(ao)
+     127             : {
+     128             :   // Read in the atoms
+     129             :   std::vector<AtomNumber> all_atoms;
+     130           1 :   readAtomsLikeKeyword( "ATOMS", 4, all_atoms );
+     131           1 :   setupMultiColvarBase( all_atoms );
+     132             :   // Resize target
+     133           1 :   target.resize( getFullNumberOfTasks() );
+     134             :   // Resize coeff
+     135           1 :   coefficient.resize( getFullNumberOfTasks(), 1.0);
+     136             :   // Setup central atom indices
+     137           1 :   std::vector<bool> catom_ind(4, false);
+     138           1 :   catom_ind[1]=catom_ind[2]=true;
+     139           1 :   setAtomsForCentralAtom( catom_ind );
+     140             : 
+     141             :   // Read in reference values
+     142             :   unsigned ntarget=0;
+     143           1 :   for(unsigned i=0; i<target.size(); ++i) {
+     144           2 :     if( !parseNumbered( "REFERENCE", i+1, target[i] ) ) break;
+     145           0 :     ntarget++;
+     146             :   }
+     147           1 :   if( ntarget==0 ) {
+     148           1 :     parse("REFERENCE",target[0]);
+     149           8 :     for(unsigned i=1; i<target.size(); ++i) target[i]=target[0];
+     150           0 :   } else if( ntarget!=target.size() ) {
+     151           0 :     error("found wrong number of REFERENCE values");
+     152             :   }
+     153             : 
+     154             :   // Read in reference values
+     155             :   unsigned ncoefficient=0;
+     156           1 :   for(unsigned i=0; i<coefficient.size(); ++i) {
+     157           2 :     if( !parseNumbered( "COEFFICIENT", i+1, coefficient[i] ) ) break;
+     158           0 :     ncoefficient++;
+     159             :   }
+     160           1 :   if( ncoefficient==0 ) {
+     161           1 :     parse("COEFFICIENT",coefficient[0]);
+     162           8 :     for(unsigned i=1; i<coefficient.size(); ++i) coefficient[i]=coefficient[0];
+     163           0 :   } else if( ncoefficient !=coefficient.size() ) {
+     164           0 :     error("found wrong number of COEFFICIENT values");
+     165             :   }
+     166             : 
+     167             :   // And setup the ActionWithVessel
+     168           1 :   if( getNumberOfVessels()==0 ) {
+     169             :     std::string fake_input;
+     170           1 :     addVessel( "SUM", fake_input, -1 );  // -1 here means that this value will be named getLabel()
+     171           1 :     readVesselKeywords();  // This makes sure resizing is done
+     172             :   }
+     173             : 
+     174             :   // And check everything has been read in correctly
+     175           1 :   checkRead();
+     176           1 : }
+     177             : 
+     178          40 : double AlphaBeta::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     179          40 :   const Vector d0=getSeparation(myatoms.getPosition(1),myatoms.getPosition(0));
+     180          40 :   const Vector d1=getSeparation(myatoms.getPosition(2),myatoms.getPosition(1));
+     181          40 :   const Vector d2=getSeparation(myatoms.getPosition(3),myatoms.getPosition(2));
+     182             : 
+     183          40 :   Vector dd0,dd1,dd2;
+     184             :   PLMD::Torsion t;
+     185          40 :   const double value  = t.compute(d0,d1,d2,dd0,dd1,dd2);
+     186          40 :   const double svalue = -0.5*coefficient[tindex]*std::sin(value-target[tindex]);
+     187          40 :   const double cvalue = coefficient[tindex]*(1.+std::cos(value-target[tindex]));
+     188             : 
+     189          40 :   dd0 *= svalue;
+     190          40 :   dd1 *= svalue;
+     191          40 :   dd2 *= svalue;
+     192             : 
+     193          40 :   addAtomDerivatives(1, 0, dd0, myatoms);
+     194          40 :   addAtomDerivatives(1, 1, dd1-dd0, myatoms);
+     195          40 :   addAtomDerivatives(1, 2, dd2-dd1, myatoms);
+     196          40 :   addAtomDerivatives(1, 3, -dd2, myatoms);
+     197             : 
+     198          40 :   myatoms.addBoxDerivatives(1, -(extProduct(d0,dd0)+extProduct(d1,dd1)+extProduct(d2,dd2)));
+     199             : 
+     200          40 :   return 0.5*cvalue;
+     201             : }
+     202             : 
+     203             : }
+     204             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Angles.cpp.func-sort-c.html b/coverage/multicolvar/Angles.cpp.func-sort-c.html new file mode 100644 index 000000000000..e49f7eb018eb --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Angles.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Angles.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:627483.8 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6AnglesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar6AnglesC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar6Angles16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar6Angles10isPeriodicEv6
_ZNK4PLMD11multicolvar6Angles7computeERKjRNS0_13AtomValuePackE26964
_ZNK4PLMD11multicolvar6Angles15calculateWeightERKjRKdRNS0_13AtomValuePackE48510
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Angles.cpp.func.html b/coverage/multicolvar/Angles.cpp.func.html new file mode 100644 index 000000000000..b72788f4fcb4 --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Angles.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Angles.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:627483.8 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6Angles10isPeriodicEv6
_ZN4PLMD11multicolvar6Angles16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar6AnglesC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar6AnglesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar6Angles15calculateWeightERKjRKdRNS0_13AtomValuePackE48510
_ZNK4PLMD11multicolvar6Angles7computeERKjRNS0_13AtomValuePackE26964
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Angles.cpp.gcov.html b/coverage/multicolvar/Angles.cpp.gcov.html new file mode 100644 index 000000000000..91a0088a83df --- /dev/null +++ b/coverage/multicolvar/Angles.cpp.gcov.html @@ -0,0 +1,297 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Angles.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Angles.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:627483.8 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "tools/Angle.h"
+      25             : #include "tools/SwitchingFunction.h"
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace multicolvar {
+      33             : 
+      34             : //+PLUMEDOC MCOLVAR ANGLES
+      35             : /*
+      36             : Calculate functions of the distribution of angles .
+      37             : 
+      38             : You can use this command to calculate functions such as:
+      39             : 
+      40             : \f[
+      41             :  f(x) = \sum_{ijk} g( \theta_{ijk} )
+      42             : \f]
+      43             : 
+      44             : Alternatively you can use this command to calculate functions such as:
+      45             : 
+      46             : \f[
+      47             : f(x) = \sum_{ijk} s(r_{ij})s(r_{jk}) g(\theta_{ijk})
+      48             : \f]
+      49             : 
+      50             : where \f$s(r)\f$ is a \ref switchingfunction.  This second form means that you can
+      51             : use this to calculate functions of the angles in the first coordination sphere of
+      52             : an atom / molecule \cite lj-recon.
+      53             : 
+      54             : \par Examples
+      55             : 
+      56             : The following example instructs plumed to find the average of two angles and to
+      57             : print it to a file
+      58             : 
+      59             : \plumedfile
+      60             : ANGLES ATOMS1=1,2,3 ATOMS2=4,5,6 MEAN LABEL=a1
+      61             : PRINT ARG=a1.mean FILE=colvar
+      62             : \endplumedfile
+      63             : 
+      64             : The following example tells plumed to calculate all angles involving
+      65             : at least one atom from GROUPA and two atoms from GROUPB in which the distances
+      66             : are less than 1.0. The number of angles between \f$\frac{\pi}{4}\f$ and
+      67             : \f$\frac{3\pi}{4}\f$ is then output
+      68             : 
+      69             : \plumedfile
+      70             : ANGLES GROUPA=1-10 GROUPB=11-100 BETWEEN={GAUSSIAN LOWER=0.25pi UPPER=0.75pi} SWITCH={GAUSSIAN R_0=1.0} LABEL=a1
+      71             : PRINT ARG=a1.between FILE=colvar
+      72             : \endplumedfile
+      73             : 
+      74             : This final example instructs plumed to calculate all the angles in the first coordination
+      75             : spheres of the atoms. The bins for a normalized histogram of the distribution is then output
+      76             : 
+      77             : \plumedfile
+      78             : ANGLES GROUP=1-38 HISTOGRAM={GAUSSIAN LOWER=0.0 UPPER=pi NBINS=20} SWITCH={GAUSSIAN R_0=1.0} LABEL=a1
+      79             : PRINT ARG=a1.* FILE=colvar
+      80             : \endplumedfile
+      81             : 
+      82             : */
+      83             : //+ENDPLUMEDOC
+      84             : 
+      85             : class Angles : public MultiColvarBase {
+      86             : private:
+      87             :   bool use_sf;
+      88             :   double rcut2_1, rcut2_2;
+      89             :   SwitchingFunction sf1;
+      90             :   SwitchingFunction sf2;
+      91             : public:
+      92             :   static void registerKeywords( Keywords& keys );
+      93             :   explicit Angles(const ActionOptions&);
+      94             : /// Updates neighbor list
+      95             :   double compute( const unsigned& tindex, AtomValuePack& ) const override;
+      96             : /// Returns the number of coordinates of the field
+      97             :   double calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& ) const override;
+      98           6 :   bool isPeriodic() override { return false; }
+      99             : };
+     100             : 
+     101             : PLUMED_REGISTER_ACTION(Angles,"ANGLES")
+     102             : 
+     103           4 : void Angles::registerKeywords( Keywords& keys ) {
+     104           4 :   MultiColvarBase::registerKeywords( keys );
+     105           8 :   keys.use("MEAN"); keys.use("LESS_THAN");
+     106          12 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MORE_THAN");
+     107             :   // Could also add Region here in theory
+     108           8 :   keys.add("numbered","ATOMS","the atoms involved in each of the angles you wish to calculate. "
+     109             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one angle will be "
+     110             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     111             :            "provide the indices of three atoms).  The eventual number of quantities calculated by this "
+     112             :            "action will depend on what functions of the distribution you choose to calculate.");
+     113           8 :   keys.reset_style("ATOMS","atoms");
+     114           8 :   keys.add("atoms-1","GROUP","Calculate angles for each distinct set of three atoms in the group");
+     115           8 :   keys.add("atoms-2","GROUPA","A group of central atoms about which angles should be calculated");
+     116           8 :   keys.add("atoms-2","GROUPB","When used in conjunction with GROUPA this keyword instructs plumed "
+     117             :            "to calculate all distinct angles involving one atom from GROUPA "
+     118             :            "and two atoms from GROUPB. The atom from GROUPA is the central atom.");
+     119           8 :   keys.add("atoms-3","GROUPC","This must be used in conjunction with GROUPA and GROUPB.  All angles "
+     120             :            "involving one atom from GROUPA, one atom from GROUPB and one atom from "
+     121             :            "GROUPC are calculated. The GROUPA atoms are assumed to be the central "
+     122             :            "atoms");
+     123           8 :   keys.add("optional","SWITCH","A switching function that ensures that only angles between atoms that "
+     124             :            "are within a certain fixed cutoff are calculated. The following provides "
+     125             :            "information on the \\ref switchingfunction that are available.");
+     126           8 :   keys.add("optional","SWITCHA","A switching function on the distance between the atoms in group A and the atoms in "
+     127             :            "group B");
+     128           8 :   keys.add("optional","SWITCHB","A switching function on the distance between the atoms in group A and the atoms in "
+     129             :            "group B");
+     130           4 : }
+     131             : 
+     132           2 : Angles::Angles(const ActionOptions&ao):
+     133             :   Action(ao),
+     134             :   MultiColvarBase(ao),
+     135           2 :   use_sf(false)
+     136             : {
+     137           4 :   std::string sfinput,errors; parse("SWITCH",sfinput);
+     138           2 :   if( sfinput.length()>0 ) {
+     139           2 :     use_sf=true;
+     140           2 :     weightHasDerivatives=true;
+     141           2 :     sf1.set(sfinput,errors);
+     142           2 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     143           2 :     sf2.set(sfinput,errors);
+     144           2 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     145           4 :     log.printf("  only calculating angles for atoms separated by less than %s\n", sf1.description().c_str() );
+     146             :   } else {
+     147           0 :     parse("SWITCHA",sfinput);
+     148           0 :     if(sfinput.length()>0) {
+     149           0 :       use_sf=true;
+     150           0 :       weightHasDerivatives=true;
+     151           0 :       sf1.set(sfinput,errors);
+     152           0 :       if( errors.length()!=0 ) error("problem reading SWITCHA keyword : " + errors );
+     153           0 :       sfinput.clear(); parse("SWITCHB",sfinput);
+     154           0 :       if(sfinput.length()==0) error("found SWITCHA keyword without SWITCHB");
+     155           0 :       sf2.set(sfinput,errors);
+     156           0 :       if( errors.length()!=0 ) error("problem reading SWITCHB keyword : " + errors );
+     157           0 :       log.printf("  only calculating angles when the distance between GROUPA and GROUPB atoms is less than %s\n", sf1.description().c_str() );
+     158           0 :       log.printf("  only calculating angles when the distance between GROUPA and GROUPC atoms is less than %s\n", sf2.description().c_str() );
+     159             :     }
+     160             :   }
+     161             :   // Read in the atoms
+     162             :   std::vector<AtomNumber> all_atoms;
+     163           4 :   readGroupKeywords( "GROUP", "GROUPA", "GROUPB", "GROUPC", false, true, all_atoms );
+     164           2 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 3, all_atoms );
+     165           2 :   setupMultiColvarBase( all_atoms );
+     166             :   // Set cutoff for link cells
+     167           2 :   if( use_sf ) {
+     168           2 :     setLinkCellCutoff( sf1.get_dmax() );
+     169           2 :     rcut2_1=sf1.get_dmax()*sf1.get_dmax();
+     170           2 :     rcut2_2=sf2.get_dmax()*sf2.get_dmax();
+     171             :   }
+     172             : 
+     173             :   // And check everything has been read in correctly
+     174           2 :   checkRead();
+     175             :   // Setup stuff for central atom
+     176           2 :   std::vector<bool> catom_ind(3, false); catom_ind[0]=true;
+     177           2 :   setAtomsForCentralAtom( catom_ind );
+     178           2 : }
+     179             : 
+     180       48510 : double Angles::calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const {
+     181       48510 :   if(!use_sf) return 1.0;
+     182       48510 :   Vector dij=getSeparation( myatoms.getPosition(0), myatoms.getPosition(2) );
+     183       48510 :   Vector dik=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     184             : 
+     185             :   double w1, w2, dw1, dw2, wtot;
+     186       48510 :   double ldij = dij.modulo2(), ldik = dik.modulo2();
+     187             : 
+     188       48510 :   if( use_sf ) {
+     189       48510 :     if( ldij>rcut2_1 || ldik>rcut2_2 ) return 0.0;
+     190             :   }
+     191             : 
+     192       48510 :   w1=sf1.calculateSqr( ldij, dw1 );
+     193       48510 :   w2=sf2.calculateSqr( ldik, dw2 );
+     194       48510 :   wtot=w1*w2; dw1*=weight*w2; dw2*=weight*w1;
+     195             : 
+     196       48510 :   addAtomDerivatives( 0, 1, dw2*dik, myatoms );
+     197       48510 :   addAtomDerivatives( 0, 0, -dw1*dij - dw2*dik, myatoms );
+     198       48510 :   addAtomDerivatives( 0, 2, dw1*dij, myatoms );
+     199       48510 :   myatoms.addBoxDerivatives( 0, (-dw1)*Tensor(dij,dij) + (-dw2)*Tensor(dik,dik) );
+     200       48510 :   return wtot;
+     201             : }
+     202             : 
+     203       26964 : double Angles::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     204       26964 :   Vector dij=getSeparation( myatoms.getPosition(0), myatoms.getPosition(2) );
+     205       26964 :   Vector dik=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     206             : 
+     207       26964 :   Vector ddij,ddik; PLMD::Angle a;
+     208       26964 :   double angle=a.compute(dij,dik,ddij,ddik);
+     209             : 
+     210             :   // And finish the calculation
+     211       26964 :   addAtomDerivatives( 1, 1, ddik, myatoms );
+     212       26964 :   addAtomDerivatives( 1, 0, - ddik - ddij, myatoms );
+     213       26964 :   addAtomDerivatives( 1, 2, ddij, myatoms );
+     214       26964 :   myatoms.addBoxDerivatives( 1, -(Tensor(dij,ddij)+Tensor(dik,ddik)) );
+     215             : 
+     216       26964 :   return angle;
+     217             : }
+     218             : 
+     219             : }
+     220             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.cpp.func-sort-c.html b/coverage/multicolvar/AtomValuePack.cpp.func-sort-c.html new file mode 100644 index 000000000000..6c2d55b62a87 --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/AtomValuePack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - AtomValuePack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13AtomValuePack23setupAtomsFromLinkCellsERKSt6vectorIjSaIjEERKNS_13VectorGenericILj3EEERKNS_9LinkCellsE222049
_ZN4PLMD11multicolvar13AtomValuePackC2ERNS_10MultiValueEPKNS0_15MultiColvarBaseE449465
_ZN4PLMD11multicolvar13AtomValuePack18updateUsingIndicesEv520525
_ZN4PLMD11multicolvar13AtomValuePack17addComDerivativesERKiRKNS_13VectorGenericILj3EEERKNS0_9CatomPackE980606
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.cpp.func.html b/coverage/multicolvar/AtomValuePack.cpp.func.html new file mode 100644 index 000000000000..2c9029b19d77 --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/AtomValuePack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - AtomValuePack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13AtomValuePack17addComDerivativesERKiRKNS_13VectorGenericILj3EEERKNS0_9CatomPackE980606
_ZN4PLMD11multicolvar13AtomValuePack18updateUsingIndicesEv520525
_ZN4PLMD11multicolvar13AtomValuePack23setupAtomsFromLinkCellsERKSt6vectorIjSaIjEERKNS_13VectorGenericILj3EEERKNS_9LinkCellsE222049
_ZN4PLMD11multicolvar13AtomValuePackC2ERNS_10MultiValueEPKNS0_15MultiColvarBaseE449465
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.cpp.gcov.html b/coverage/multicolvar/AtomValuePack.cpp.gcov.html new file mode 100644 index 000000000000..af72964b676a --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.cpp.gcov.html @@ -0,0 +1,177 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/AtomValuePack.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - AtomValuePack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AtomValuePack.h"
+      23             : #include "CatomPack.h"
+      24             : #include "tools/LinkCells.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace multicolvar {
+      28             : 
+      29      449465 : AtomValuePack::AtomValuePack( MultiValue& vals, MultiColvarBase const * mcolv ):
+      30      449465 :   myvals(vals),
+      31      449465 :   mycolv(mcolv),
+      32      449465 :   natoms(0),
+      33      449465 :   indices( vals.getIndices() ),
+      34      449465 :   sort_vector( vals.getSortIndices() ),
+      35      449465 :   myatoms( vals.getAtomVector() )
+      36             : {
+      37      449465 :   if( indices.size()!=mcolv->getNumberOfAtoms() ) {
+      38       23867 :     indices.resize( mcolv->getNumberOfAtoms() );
+      39       23867 :     sort_vector.resize( mcolv->getNumberOfAtoms() );
+      40       23867 :     myatoms.resize( mcolv->getNumberOfAtoms() );
+      41             :   }
+      42      449465 : }
+      43             : 
+      44      222049 : unsigned AtomValuePack::setupAtomsFromLinkCells( const std::vector<unsigned>& cind, const Vector& cpos, const LinkCells& linkcells ) {
+      45      222049 :   if( cells_required.size()!=linkcells.getNumberOfCells() ) cells_required.resize( linkcells.getNumberOfCells() );
+      46             :   // Build the list of cells that we need
+      47      222049 :   unsigned ncells_required=0; linkcells.addRequiredCells( linkcells.findMyCell( cpos ), ncells_required, cells_required );
+      48             :   // Now build the list of atoms we need
+      49      483914 :   natoms=cind.size(); for(unsigned i=0; i<natoms; ++i) indices[i]=cind[i];
+      50      222049 :   linkcells.retrieveAtomsInCells( ncells_required, cells_required, natoms, indices );
+      51             : //  linkcells.retrieveNeighboringAtoms( cpos, natoms, indices );
+      52   401982235 :   for(unsigned i=0; i<natoms; ++i) myatoms[i]=mycolv->getPositionOfAtomForLinkCells( indices[i] ) - cpos;
+      53      222049 :   if( mycolv->usesPbc() ) mycolv->applyPbc( myatoms, natoms );
+      54      222049 :   return natoms;
+      55             : }
+      56             : 
+      57      520525 : void AtomValuePack::updateUsingIndices() {
+      58      520525 :   if( myvals.updateComplete() ) return;
+      59             : 
+      60             :   unsigned jactive=0;
+      61   400639880 :   for(unsigned i=0; i<natoms; ++i) {
+      62   400323723 :     unsigned base=3*indices[i];
+      63   400323723 :     if( myvals.isActive( base ) ) { sort_vector[jactive]=indices[i]; jactive++; }
+      64             :   }
+      65      316157 :   std::sort( sort_vector.begin(), sort_vector.begin()+jactive );
+      66             : 
+      67      316157 :   myvals.emptyActiveMembers();
+      68     4446322 :   for(unsigned i=0; i<jactive; ++i) {
+      69     4130165 :     unsigned base=3*sort_vector[i]; // indices[i];
+      70     4130165 :     myvals.putIndexInActiveArray( base );
+      71     4130165 :     myvals.putIndexInActiveArray( base + 1 );
+      72     4130165 :     myvals.putIndexInActiveArray( base + 2 );
+      73             :   }
+      74      316157 :   unsigned nvir=3*mycolv->getNumberOfAtoms();
+      75      316157 :   if( myvals.isActive( nvir ) ) {
+      76     2074530 :     for(unsigned i=0; i<9; ++i) myvals.putIndexInActiveArray( nvir + i );
+      77             :   }
+      78      316157 :   myvals.completeUpdate();
+      79             : }
+      80             : 
+      81      980606 : void AtomValuePack::addComDerivatives( const int& ind, const Vector& der, const CatomPack& catom_der ) {
+      82      980606 :   if( ind<0 ) {
+      83      109936 :     for(unsigned ider=0; ider<catom_der.getNumberOfAtomsWithDerivatives(); ++ider) {
+      84       57432 :       unsigned jder=3*catom_der.getIndex(ider);
+      85       57432 :       myvals.addTemporyDerivative( jder+0, catom_der.getDerivative(ider,0,der) );
+      86       57432 :       myvals.addTemporyDerivative( jder+1, catom_der.getDerivative(ider,1,der) );
+      87       57432 :       myvals.addTemporyDerivative( jder+2, catom_der.getDerivative(ider,2,der) );
+      88             :     }
+      89             :   } else {
+      90     1861132 :     for(unsigned ider=0; ider<catom_der.getNumberOfAtomsWithDerivatives(); ++ider) {
+      91      933030 :       unsigned jder=3*catom_der.getIndex(ider);
+      92      933030 :       myvals.addDerivative( ind, jder+0, catom_der.getDerivative(ider,0,der) );
+      93      933030 :       myvals.addDerivative( ind, jder+1, catom_der.getDerivative(ider,1,der) );
+      94      933030 :       myvals.addDerivative( ind, jder+2, catom_der.getDerivative(ider,2,der) );
+      95             :     }
+      96             :   }
+      97      980606 : }
+      98             : 
+      99             : }
+     100             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.h.func-sort-c.html b/coverage/multicolvar/AtomValuePack.h.func-sort-c.html new file mode 100644 index 000000000000..8ccf8e206616 --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/AtomValuePack.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - AtomValuePack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13AtomValuePack17updateDynamicListEv141871
_ZN4PLMD11multicolvar13AtomValuePack7setAtomERKjS3_571753
_ZN4PLMD11multicolvar13AtomValuePack24addTemporyBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE2314127
_ZN4PLMD11multicolvar13AtomValuePack26addTemporyAtomsDerivativesERKjRKNS_13VectorGenericILj3EEE4575750
_ZN4PLMD11multicolvar13AtomValuePack17addBoxDerivativesERKjRKNS_13TensorGenericILj3ELj3EEE57137172
_ZN4PLMD11multicolvar13AtomValuePack19addAtomsDerivativesERKjS3_RKNS_13VectorGenericILj3EEE113229879
_ZNK4PLMD11multicolvar13AtomValuePack16getAbsoluteIndexERKj117937031
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.h.func.html b/coverage/multicolvar/AtomValuePack.h.func.html new file mode 100644 index 000000000000..9e65c1ba005c --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/AtomValuePack.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - AtomValuePack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13AtomValuePack17addBoxDerivativesERKjRKNS_13TensorGenericILj3ELj3EEE57137172
_ZN4PLMD11multicolvar13AtomValuePack17updateDynamicListEv141871
_ZN4PLMD11multicolvar13AtomValuePack19addAtomsDerivativesERKjS3_RKNS_13VectorGenericILj3EEE113229879
_ZN4PLMD11multicolvar13AtomValuePack24addTemporyBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE2314127
_ZN4PLMD11multicolvar13AtomValuePack26addTemporyAtomsDerivativesERKjRKNS_13VectorGenericILj3EEE4575750
_ZN4PLMD11multicolvar13AtomValuePack7setAtomERKjS3_571753
_ZNK4PLMD11multicolvar13AtomValuePack16getAbsoluteIndexERKj117937031
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/AtomValuePack.h.gcov.html b/coverage/multicolvar/AtomValuePack.h.gcov.html new file mode 100644 index 000000000000..6141a2f49c8a --- /dev/null +++ b/coverage/multicolvar/AtomValuePack.h.gcov.html @@ -0,0 +1,292 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/AtomValuePack.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - AtomValuePack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:394195.1 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_multicolvar_AtomValuePack_h
+      23             : #define __PLUMED_multicolvar_AtomValuePack_h
+      24             : 
+      25             : #include "tools/MultiValue.h"
+      26             : #include "MultiColvarBase.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : class LinkCells;
+      31             : 
+      32             : namespace multicolvar {
+      33             : 
+      34             : class CatomPack;
+      35             : 
+      36      449411 : class AtomValuePack {
+      37             :   friend class MultiColvarBase;
+      38             :   friend class LocalAverage;
+      39             : private:
+      40             : /// Copy of the values that we are adding to
+      41             :   MultiValue& myvals;
+      42             : /// Copy of the underlying multicolvar
+      43             :   MultiColvarBase const * mycolv;
+      44             : /// Number of atoms at the moment
+      45             :   unsigned natoms;
+      46             : /// Atom indices
+      47             :   std::vector<unsigned>& indices;
+      48             : /// This is used to sort the atom indices
+      49             :   std::vector<unsigned>& sort_vector;
+      50             : /// This holds atom positions
+      51             :   std::vector<Vector>& myatoms;
+      52             : /// This is stuff for link cells
+      53             :   std::vector<unsigned> cells_required;
+      54             : ///
+      55             :   void addAtomsDerivatives( const unsigned&, const unsigned&, const Vector& );
+      56             : ///
+      57             :   void addTemporyAtomsDerivatives( const unsigned& jder, const Vector& der );
+      58             : public:
+      59             :   AtomValuePack( MultiValue& vals, MultiColvarBase const * mcolv );
+      60             : /// Set the number of atoms
+      61             :   void setNumberOfAtoms( const unsigned& );
+      62             : /// Set the index for one of the atoms
+      63             :   void setIndex( const unsigned&, const unsigned& );
+      64             : ///
+      65             :   void setAtomIndex( const unsigned& j, const unsigned& ind );
+      66             : ///
+      67             :   void setAtom( const unsigned& j, const unsigned& ind );
+      68             : ///
+      69             :   unsigned setupAtomsFromLinkCells( const std::vector<unsigned>& cind, const Vector& cpos, const LinkCells& linkcells );
+      70             : ///
+      71             :   unsigned getIndex( const unsigned& j ) const ;
+      72             : ///
+      73             :   unsigned getNumberOfAtoms() const ;
+      74             : ///
+      75             :   unsigned getNumberOfDerivatives() const ;
+      76             : /// Get the position of the ith atom
+      77             :   Vector& getPosition( const unsigned& );
+      78             : /// Get the absolute index of the ith atom in the list
+      79             :   AtomNumber getAbsoluteIndex( const unsigned& j ) const ;
+      80             : ///
+      81             :   void setValue( const unsigned&, const double& );
+      82             : ///
+      83             :   void addValue( const unsigned& ival, const double& vv );
+      84             : ///
+      85             :   double getValue( const unsigned& ) const ;
+      86             : ///
+      87             :   void addBoxDerivatives( const unsigned&, const Tensor& );
+      88             : ///
+      89             :   void addTemporyBoxDerivatives( const Tensor& vir );
+      90             : ///
+      91             :   void updateUsingIndices();
+      92             : ///
+      93             :   void updateDynamicList();
+      94             : ///
+      95             :   void addComDerivatives( const int&, const Vector&, const CatomPack& );
+      96             : ///
+      97             :   MultiValue& getUnderlyingMultiValue();
+      98             : ///
+      99             :   void addDerivative( const unsigned&, const unsigned&, const double& );
+     100             : };
+     101             : 
+     102             : inline
+     103             : void AtomValuePack::setNumberOfAtoms( const unsigned& nat ) {
+     104      230896 :   natoms=nat;
+     105             : }
+     106             : 
+     107             : inline
+     108             : unsigned AtomValuePack::getNumberOfAtoms() const {
+     109   522586210 :   return natoms;
+     110             : }
+     111             : 
+     112             : inline
+     113             : unsigned AtomValuePack::getNumberOfDerivatives() const {
+     114         110 :   return myvals.getNumberOfDerivatives();
+     115             : }
+     116             : 
+     117             : inline
+     118             : void AtomValuePack::setIndex( const unsigned& j, const unsigned& ind ) {
+     119             :   plumed_dbg_assert( j<natoms ); indices[j]=ind;
+     120             : }
+     121             : 
+     122             : inline
+     123             : void AtomValuePack::setAtomIndex( const unsigned& j, const unsigned& ind ) {
+     124      605402 :   plumed_dbg_assert( j<natoms ); indices[j]=ind;
+     125             : }
+     126             : 
+     127             : inline
+     128      571753 : void AtomValuePack::setAtom( const unsigned& j, const unsigned& ind ) {
+     129      571753 :   setAtomIndex( j, ind ); myatoms[j]=mycolv->getPositionOfAtomForLinkCells( ind );
+     130      571753 : }
+     131             : 
+     132             : inline
+     133             : unsigned AtomValuePack::getIndex( const unsigned& j ) const {
+     134   680755938 :   plumed_dbg_assert( j<natoms ); return indices[j];
+     135             : }
+     136             : 
+     137             : inline
+     138   117937031 : AtomNumber AtomValuePack::getAbsoluteIndex( const unsigned& j ) const {
+     139   117937031 :   plumed_dbg_assert( j<natoms ); unsigned jatom=indices[j];
+     140   117937031 :   if( mycolv->atom_lab[jatom].first>0 ) {
+     141           0 :     unsigned mmc=mycolv->atom_lab[jatom].first - 1;
+     142           0 :     return (mycolv->mybasemulticolvars[mmc])->getAbsoluteIndexOfCentralAtom( mycolv->atom_lab[jatom].second );
+     143             :   }
+     144   117937031 :   return mycolv->getAbsoluteIndex( mycolv->atom_lab[jatom].second );
+     145             : }
+     146             : 
+     147             : inline
+     148             : Vector& AtomValuePack::getPosition( const unsigned& iatom ) {
+     149             :   plumed_dbg_assert( iatom<natoms );
+     150   139721584 :   return myatoms[iatom];
+     151             : }
+     152             : 
+     153             : inline
+     154             : void AtomValuePack::setValue( const unsigned& ival, const double& vv ) {
+     155      698507 :   myvals.setValue( ival, vv );
+     156             : }
+     157             : 
+     158             : inline
+     159             : void AtomValuePack::addValue( const unsigned& ival, const double& vv ) {
+     160    63014961 :   myvals.addValue( ival, vv );
+     161             : }
+     162             : 
+     163             : inline
+     164             : double AtomValuePack::getValue( const unsigned& ival ) const {
+     165     3464306 :   return myvals.get( ival );
+     166             : }
+     167             : 
+     168             : inline
+     169             : void AtomValuePack::addDerivative( const unsigned& ival, const unsigned& jder, const double& der ) {
+     170    40573338 :   myvals.addDerivative( ival, jder, der );
+     171             : }
+     172             : 
+     173             : inline
+     174   113229879 : void AtomValuePack::addAtomsDerivatives( const unsigned& ival, const unsigned& jder, const Vector& der ) {
+     175             :   plumed_dbg_assert( jder<natoms );
+     176   113229879 :   myvals.addDerivative( ival, 3*indices[jder] + 0, der[0] );
+     177   113229879 :   myvals.addDerivative( ival, 3*indices[jder] + 1, der[1] );
+     178   113229879 :   myvals.addDerivative( ival, 3*indices[jder] + 2, der[2] );
+     179   113229879 : }
+     180             : 
+     181             : inline
+     182     4575750 : void AtomValuePack::addTemporyAtomsDerivatives( const unsigned& jder, const Vector& der ) {
+     183             :   plumed_dbg_assert( jder<natoms );
+     184     4575750 :   myvals.addTemporyDerivative( 3*indices[jder] + 0, der[0] );
+     185     4575750 :   myvals.addTemporyDerivative( 3*indices[jder] + 1, der[1] );
+     186     4575750 :   myvals.addTemporyDerivative( 3*indices[jder] + 2, der[2] );
+     187     4575750 : }
+     188             : 
+     189             : inline
+     190     2314127 : void AtomValuePack::addTemporyBoxDerivatives( const Tensor& vir ) {
+     191     2314127 :   unsigned nvir=3*mycolv->getNumberOfAtoms();
+     192    30083651 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) myvals.addTemporyDerivative( nvir + 3*i+j, vir(i,j) );
+     193     2314127 : }
+     194             : 
+     195             : inline
+     196    57137172 : void AtomValuePack::addBoxDerivatives( const unsigned& ival, const Tensor& vir ) {
+     197    57137172 :   unsigned nvir=3*mycolv->getNumberOfAtoms();
+     198   742783236 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) myvals.addDerivative( ival, nvir + 3*i+j, vir(i,j) );
+     199    57137172 : }
+     200             : 
+     201             : inline
+     202      141871 : void AtomValuePack::updateDynamicList() {
+     203      141871 :   if( myvals.updateComplete() ) return;
+     204             :   myvals.updateDynamicList();
+     205             : }
+     206             : 
+     207             : inline
+     208             : MultiValue& AtomValuePack::getUnderlyingMultiValue() {
+     209     4809736 :   return myvals;
+     210             : }
+     211             : 
+     212             : }
+     213             : }
+     214             : #endif
+     215             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Bridge.cpp.func-sort-c.html b/coverage/multicolvar/Bridge.cpp.func-sort-c.html new file mode 100644 index 000000000000..3bb2efb0c3ea --- /dev/null +++ b/coverage/multicolvar/Bridge.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Bridge.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Bridge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:415278.8 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6Bridge10isPeriodicEv0
_ZN4PLMD11multicolvar6BridgeC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar6BridgeC1ERKNS_13ActionOptionsE8
_ZN4PLMD11multicolvar6Bridge16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD11multicolvar6Bridge7computeERKjRNS0_13AtomValuePackE537
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Bridge.cpp.func.html b/coverage/multicolvar/Bridge.cpp.func.html new file mode 100644 index 000000000000..e8c99579dd82 --- /dev/null +++ b/coverage/multicolvar/Bridge.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Bridge.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Bridge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:415278.8 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar6Bridge10isPeriodicEv0
_ZN4PLMD11multicolvar6Bridge16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD11multicolvar6BridgeC1ERKNS_13ActionOptionsE8
_ZN4PLMD11multicolvar6BridgeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar6Bridge7computeERKjRNS0_13AtomValuePackE537
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Bridge.cpp.gcov.html b/coverage/multicolvar/Bridge.cpp.gcov.html new file mode 100644 index 000000000000..ad74236f99cd --- /dev/null +++ b/coverage/multicolvar/Bridge.cpp.gcov.html @@ -0,0 +1,232 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Bridge.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Bridge.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:415278.8 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "tools/SwitchingFunction.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace multicolvar {
+      32             : 
+      33             : //+PLUMEDOC MCOLVAR BRIDGE
+      34             : /*
+      35             : Calculate the number of atoms that bridge two parts of a structure
+      36             : 
+      37             : This quantity calculates:
+      38             : 
+      39             : \f[
+      40             :  f(x) = \sum_{ijk} s_A(r_{ij})s_B(r_{ik})
+      41             : \f]
+      42             : 
+      43             : where the sum over \f$i\f$ is over all the ``bridging atoms" and
+      44             : \f$s_A\f$ and \f$s_B\f$ are \ref switchingfunction.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : The following example instructs plumed to calculate the number of water molecules
+      49             : that are bridging between atoms 1-10 and atoms 11-20 and to print the value
+      50             : to a file
+      51             : 
+      52             : \plumedfile
+      53             : w1: BRIDGE BRIDGING_ATOMS=100-200 GROUPA=1-10 GROUPB=11-20 SWITCH={RATIONAL R_0=0.2}
+      54             : PRINT ARG=w1 FILE=colvar
+      55             : \endplumedfile
+      56             : 
+      57             : */
+      58             : //+ENDPLUMEDOC
+      59             : 
+      60             : class Bridge : public MultiColvarBase {
+      61             : private:
+      62             :   Vector dij, dik;
+      63             :   SwitchingFunction sf1;
+      64             :   SwitchingFunction sf2;
+      65             : public:
+      66             :   static void registerKeywords( Keywords& keys );
+      67             :   explicit Bridge(const ActionOptions&);
+      68             : // active methods:
+      69             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      70           0 :   bool isPeriodic() override { return false; }
+      71             : };
+      72             : 
+      73             : PLUMED_REGISTER_ACTION(Bridge,"BRIDGE")
+      74             : 
+      75          10 : void Bridge::registerKeywords( Keywords& keys ) {
+      76          10 :   MultiColvarBase::registerKeywords( keys );
+      77          20 :   keys.add("atoms-2","BRIDGING_ATOMS","The list of atoms that can form the bridge between the two interesting parts "
+      78             :            "of the structure.");
+      79          20 :   keys.add("atoms-2","GROUPA","The list of atoms that are in the first interesting part of the structure");
+      80          20 :   keys.add("atoms-2","GROUPB","The list of atoms that are in the second interesting part of the structure");
+      81          20 :   keys.add("optional","SWITCH","The parameters of the two \\ref switchingfunction in the above formula");
+      82          20 :   keys.add("optional","SWITCHA","The \\ref switchingfunction on the distance between bridging atoms and the atoms in "
+      83             :            "group A");
+      84          20 :   keys.add("optional","SWITCHB","The \\ref switchingfunction on the distance between the bridging atoms and the atoms in "
+      85             :            "group B");
+      86          10 : }
+      87             : 
+      88           8 : Bridge::Bridge(const ActionOptions&ao):
+      89             :   Action(ao),
+      90           8 :   MultiColvarBase(ao)
+      91             : {
+      92             :   // Read in the atoms
+      93             :   std::vector<AtomNumber> all_atoms;
+      94          16 :   readThreeGroups("GROUPA","GROUPB","BRIDGING_ATOMS",false,true,all_atoms);
+      95             :   // Setup the multicolvar base
+      96           8 :   setupMultiColvarBase( all_atoms );
+      97             :   // Setup Central atom atoms
+      98           8 :   std::vector<bool> catom_ind(3, false); catom_ind[0]=true;
+      99           8 :   setAtomsForCentralAtom( catom_ind );
+     100             : 
+     101          16 :   std::string sfinput,errors; parse("SWITCH",sfinput);
+     102           8 :   if( sfinput.length()>0 ) {
+     103           8 :     sf1.set(sfinput,errors);
+     104           8 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     105           8 :     sf2.set(sfinput,errors);
+     106           8 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     107             :   } else {
+     108           0 :     parse("SWITCHA",sfinput);
+     109           0 :     if(sfinput.length()>0) {
+     110           0 :       weightHasDerivatives=true;
+     111           0 :       sf1.set(sfinput,errors);
+     112           0 :       if( errors.length()!=0 ) error("problem reading SWITCHA keyword : " + errors );
+     113           0 :       sfinput.clear(); parse("SWITCHB",sfinput);
+     114           0 :       if(sfinput.length()==0) error("found SWITCHA keyword without SWITCHB");
+     115           0 :       sf2.set(sfinput,errors);
+     116           0 :       if( errors.length()!=0 ) error("problem reading SWITCHB keyword : " + errors );
+     117             :     } else {
+     118           0 :       error("missing definition of switching functions");
+     119             :     }
+     120             :   }
+     121           8 :   log.printf("  distance between bridging atoms and atoms in GROUPA must be less than %s\n",sf1.description().c_str());
+     122           8 :   log.printf("  distance between bridging atoms and atoms in GROUPB must be less than %s\n",sf2.description().c_str());
+     123             : 
+     124             :   // Setup link cells
+     125           8 :   setLinkCellCutoff( sf1.get_dmax() + sf2.get_dmax() );
+     126             : 
+     127             :   // And setup the ActionWithVessel
+     128           8 :   if( getNumberOfVessels()!=0 ) error("should not have vessels for this action");
+     129             :   std::string fake_input;
+     130           8 :   addVessel( "SUM", fake_input, -1 );  // -1 here means that this value will be named getLabel()
+     131           8 :   readVesselKeywords();
+     132             :   // And check everything has been read in correctly
+     133           8 :   checkRead();
+     134           8 : }
+     135             : 
+     136         537 : double Bridge::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     137             :   double tot=0;
+     138       21359 :   for(unsigned i=2; i<myatoms.getNumberOfAtoms(); ++i) {
+     139       20822 :     Vector dij=getSeparation( myatoms.getPosition(i), myatoms.getPosition(0) );
+     140       20822 :     double dw1, w1=sf1.calculateSqr( dij.modulo2(), dw1 );
+     141       20822 :     Vector dik=getSeparation( myatoms.getPosition(i), myatoms.getPosition(1) );
+     142       20822 :     double dw2, w2=sf2.calculateSqr( dik.modulo2(), dw2 );
+     143             : 
+     144       20822 :     tot += w1*w2;
+     145             :     // And finish the calculation
+     146       20822 :     addAtomDerivatives( 1, 0,  w2*dw1*dij, myatoms );
+     147       20822 :     addAtomDerivatives( 1, 1,  w1*dw2*dik, myatoms );
+     148       20822 :     addAtomDerivatives( 1, i, -w1*dw2*dik-w2*dw1*dij, myatoms );
+     149       20822 :     myatoms.addBoxDerivatives( 1, w1*(-dw2)*Tensor(dik,dik)+w2*(-dw1)*Tensor(dij,dij) );
+     150             :   }
+     151         537 :   return tot;
+     152             : }
+     153             : 
+     154             : }
+     155             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func-sort-c.html b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func-sort-c.html new file mode 100644 index 000000000000..f81c7d9edb3c --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/BridgedMultiColvarFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - BridgedMultiColvarFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525692.9 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction15deactivate_taskERKj0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17applyBridgeForcesERKSt6vectorIdSaIdEE21
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction10isPeriodicEv34
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC2ERKNS_13ActionOptionsE44
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17turnOnDerivativesEv55
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction29calculateNumericalDerivativesEPNS_15ActionWithValueE60
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction16registerKeywordsERNS_8KeywordsE70
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction18getCentralAtomPackERKjS3_RNS0_9CatomPackE11462
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction11performTaskERKjS3_RNS_10MultiValueE13042
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction27transformBridgedDerivativesERKjRNS_10MultiValueES5_100985
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func.html b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func.html new file mode 100644 index 000000000000..f7024e11708a --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/BridgedMultiColvarFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - BridgedMultiColvarFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525692.9 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction10isPeriodicEv34
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction15deactivate_taskERKj0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction16registerKeywordsERNS_8KeywordsE70
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17applyBridgeForcesERKSt6vectorIdSaIdEE21
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17turnOnDerivativesEv55
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction18getCentralAtomPackERKjS3_RNS0_9CatomPackE11462
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction29calculateNumericalDerivativesEPNS_15ActionWithValueE60
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunctionC2ERKNS_13ActionOptionsE44
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction11performTaskERKjS3_RNS_10MultiValueE13042
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction27transformBridgedDerivativesERKjRNS_10MultiValueES5_100985
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.cpp.gcov.html b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.gcov.html new file mode 100644 index 000000000000..70329f25de92 --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/BridgedMultiColvarFunction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - BridgedMultiColvarFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525692.9 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "BridgedMultiColvarFunction.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "CatomPack.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace multicolvar {
+      29             : 
+      30          70 : void BridgedMultiColvarFunction::registerKeywords( Keywords& keys ) {
+      31          70 :   MultiColvarBase::registerKeywords( keys );
+      32         140 :   keys.add("compulsory","DATA","The multicolvar that calculates the set of base quantities that we are interested in");
+      33          70 : }
+      34             : 
+      35          44 : BridgedMultiColvarFunction::BridgedMultiColvarFunction(const ActionOptions&ao):
+      36             :   Action(ao),
+      37          44 :   MultiColvarBase(ao)
+      38             : {
+      39          44 :   std::string mlab; parse("DATA",mlab);
+      40          44 :   mycolv = plumed.getActionSet().selectWithLabel<MultiColvarBase*>(mlab);
+      41          44 :   if(!mycolv) error("action labeled " + mlab + " does not exist or is not a multicolvar");
+      42             : 
+      43             :   // When using numerical derivatives here we must use numerical derivatives
+      44             :   // in base multicolvar
+      45          44 :   if( checkNumericalDerivatives() ) mycolv->useNumericalDerivatives();
+      46             : 
+      47          44 :   myBridgeVessel = mycolv->addBridgingVessel( this ); addDependency(mycolv);
+      48          44 :   weightHasDerivatives=true; usespecies=mycolv->usespecies;
+      49             :   // Number of tasks is the same as the number in the underlying MultiColvar
+      50       20060 :   for(unsigned i=0; i<mycolv->getFullNumberOfTasks(); ++i) addTaskToList( mycolv->getTaskCode(i) );
+      51          44 : }
+      52             : 
+      53          55 : void BridgedMultiColvarFunction::turnOnDerivatives() {
+      54          55 :   BridgedMultiColvarFunction* check = dynamic_cast<BridgedMultiColvarFunction*>( mycolv );
+      55          55 :   if( check ) {
+      56           0 :     if( check->getNumberOfAtoms()>0 ) error("cannot calculate required derivatives of this quantity");
+      57             :   }
+      58          55 :   MultiColvarBase::turnOnDerivatives();
+      59          55 : }
+      60             : 
+      61      100985 : void BridgedMultiColvarFunction::transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const {
+      62      100985 :   completeTask( current, invals, outvals );
+      63             : 
+      64             :   // Now update the outvals derivatives lists
+      65      100985 :   if( derivativesAreRequired() ) {
+      66             :     outvals.emptyActiveMembers();
+      67       94076 :     if( mycolv->isDensity() ) {
+      68      173680 :       for(unsigned j=0; j<3; ++j) outvals.putIndexInActiveArray( 3*current+j );
+      69      434200 :       for(unsigned j=invals.getNumberOfDerivatives()-9; j<invals.getNumberOfDerivatives(); ++j) outvals.putIndexInActiveArray(j);
+      70             :     } else {
+      71     3766585 :       for(unsigned j=0; j<invals.getNumberActive(); ++j) outvals.putIndexInActiveArray( invals.getActiveIndex(j) );
+      72             :     }
+      73      342431 :     for(unsigned j=invals.getNumberOfDerivatives(); j<outvals.getNumberOfDerivatives(); ++j) outvals.putIndexInActiveArray( j );
+      74             :     outvals.completeUpdate();
+      75             :   }
+      76      100985 : }
+      77             : 
+      78       13042 : void BridgedMultiColvarFunction::performTask( const unsigned& taskIndex, const unsigned& current, MultiValue& myvals ) const {
+      79             :   // This allows us to speed up the code as we don't need to reallocate memory on every call of perform task
+      80       13042 :   MultiValue& invals=myBridgeVessel->getTemporyMultiValue();
+      81       26080 :   if( invals.getNumberOfValues()!=mycolv->getNumberOfQuantities() ||
+      82       13038 :       invals.getNumberOfDerivatives()!=mycolv->getNumberOfDerivatives() ) {
+      83           4 :     invals.resize( mycolv->getNumberOfQuantities(), mycolv->getNumberOfDerivatives() );
+      84             :   }
+      85       13042 :   invals.clearAll(); mycolv->performTask( taskIndex, current, invals );
+      86       13042 :   transformBridgedDerivatives( taskIndex, invals, myvals );
+      87       13042 : }
+      88             : 
+      89          60 : void BridgedMultiColvarFunction::calculateNumericalDerivatives( ActionWithValue* a ) {
+      90          60 :   if(!a) {
+      91          60 :     a=dynamic_cast<ActionWithValue*>(this);
+      92          60 :     plumed_massert(a,"cannot compute numerical derivatives for an action without values");
+      93             :   }
+      94          60 :   if( myBridgeVessel ) {
+      95          60 :     myBridgeVessel->completeNumericalDerivatives();
+      96             :   } else {
+      97           0 :     error("numerical derivatives are not implemented");
+      98             :   }
+      99          60 : }
+     100             : 
+     101          21 : void BridgedMultiColvarFunction::applyBridgeForces( const std::vector<double>& bb ) {
+     102          21 :   if( getNumberOfAtoms()==0 ) return ;
+     103             : 
+     104          42 :   for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     105          21 :     Vector f; f[0] = bb[3*i+0]; f[1] = bb[3*i+1]; f[2] = bb[3*i+2];
+     106          21 :     addForce( getValueIndices( getAbsoluteIndex(i) ), f );
+     107             :   }
+     108             : }
+     109             : 
+     110          34 : bool BridgedMultiColvarFunction::isPeriodic() {
+     111          34 :   return mycolv->isPeriodic();
+     112             : }
+     113             : 
+     114           0 : void BridgedMultiColvarFunction::deactivate_task( const unsigned& taskno ) {
+     115           0 :   plumed_merror("This should never be called");
+     116             : }
+     117             : 
+     118       11462 : void BridgedMultiColvarFunction::getCentralAtomPack( const unsigned& basn, const unsigned& curr, CatomPack& mypack ) {
+     119       11462 :   return mycolv->getCentralAtomPack( basn, curr, mypack );
+     120             : }
+     121             : 
+     122             : }
+     123             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.h.func-sort-c.html b/coverage/multicolvar/BridgedMultiColvarFunction.h.func-sort-c.html new file mode 100644 index 000000000000..5464779dbabd --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.h.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/BridgedMultiColvarFunction.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - BridgedMultiColvarFunction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:122352.2 %
Date:2024-02-22 21:58:45Functions:71258.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17isCurrentlyActiveERKj0
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction26normalizeVectorDerivativesERNS_10MultiValueE0
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction29getPositionOfAtomForLinkCellsERKj0
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction7computeERKjRNS0_13AtomValuePackE0
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction18getAbsoluteIndexesEv5
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction29getAbsoluteIndexOfCentralAtomERKj156
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction9calculateEv725
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction16clearDerivativesEv785
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction5applyEv785
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17getCentralAtomPosERKj78336
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction22getNumberOfDerivativesEv128426
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.h.func.html b/coverage/multicolvar/BridgedMultiColvarFunction.h.func.html new file mode 100644 index 000000000000..f4145d2c4e56 --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.h.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/BridgedMultiColvarFunction.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - BridgedMultiColvarFunction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:122352.2 %
Date:2024-02-22 21:58:45Functions:71258.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction16clearDerivativesEv785
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17getCentralAtomPosERKj78336
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction17isCurrentlyActiveERKj0
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction22getNumberOfDerivativesEv128426
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction5applyEv785
_ZN4PLMD11multicolvar26BridgedMultiColvarFunction9calculateEv725
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction18getAbsoluteIndexesEv5
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction26normalizeVectorDerivativesERNS_10MultiValueE0
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction29getAbsoluteIndexOfCentralAtomERKj156
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction29getPositionOfAtomForLinkCellsERKj0
_ZNK4PLMD11multicolvar26BridgedMultiColvarFunction7computeERKjRNS0_13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/BridgedMultiColvarFunction.h.gcov.html b/coverage/multicolvar/BridgedMultiColvarFunction.h.gcov.html new file mode 100644 index 000000000000..197395a82a88 --- /dev/null +++ b/coverage/multicolvar/BridgedMultiColvarFunction.h.gcov.html @@ -0,0 +1,224 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/BridgedMultiColvarFunction.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - BridgedMultiColvarFunction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:122352.2 %
Date:2024-02-22 21:58:45Functions:71258.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_multicolvar_BridgedMultiColvarFunction_h
+      23             : #define __PLUMED_multicolvar_BridgedMultiColvarFunction_h
+      24             : 
+      25             : #include "vesselbase/BridgeVessel.h"
+      26             : #include "MultiColvarBase.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace multicolvar {
+      30             : 
+      31             : class BridgedMultiColvarFunction : public MultiColvarBase {
+      32             :   friend class MultiColvarBase;
+      33             :   friend class MultiColvarFunction;
+      34             : private:
+      35             : /// This is used for storing positions properly
+      36             :   Vector tmp_p;
+      37             : /// The action that is calculating the colvars of interest
+      38             :   MultiColvarBase* mycolv;
+      39             : /// The vessel that bridges
+      40             :   vesselbase::BridgeVessel* myBridgeVessel;
+      41             : /// Everything for controlling the updating of neighbor lists
+      42             :   bool firsttime;
+      43             :   int updateFreq;
+      44             : protected:
+      45             : /// Deactivate all the atoms in the list
+      46             :   void deactivateAllAtoms();
+      47             : /// Activate the nth atom in the list
+      48             :   void setAtomActive( const unsigned& n );
+      49             : public:
+      50             :   static void registerKeywords( Keywords& keys );
+      51             :   explicit BridgedMultiColvarFunction(const ActionOptions&);
+      52             : /// Get a pointer to the base multicolvar
+      53             :   MultiColvarBase* getPntrToMultiColvar() const ;
+      54             : /// Don't actually clear the derivatives when this is called from plumed main.
+      55             : /// They are calculated inside another action and clearing them would be bad
+      56         785 :   void clearDerivatives() override {}
+      57             : /// Check nothing impossible being done with derivatives
+      58             :   void turnOnDerivatives() override;
+      59             : /// Get the number of derivatives for this action
+      60             :   unsigned getNumberOfDerivatives() override;
+      61             : /// Get the size of the atoms with derivatives array
+      62             :   unsigned getSizeOfAtomsWithDerivatives();
+      63             : /// Is the output quantity periodic
+      64             :   bool isPeriodic() override;
+      65             : /// Routines that have to be defined so as not to have problems with virtual methods
+      66             :   void deactivate_task( const unsigned& taskno );
+      67         725 :   void calculate() override {}
+      68             : /// This does the task
+      69             :   void transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const override;
+      70             :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override;
+      71             :   virtual void completeTask( const unsigned& curr, MultiValue& invals, MultiValue& outvals ) const=0;
+      72             : /// Get the central atom position
+      73             :   Vector retrieveCentralAtomPos();
+      74             : /// Get the index of the central atom
+      75             :   AtomNumber getAbsoluteIndexOfCentralAtom( const unsigned& i ) const override;
+      76             : /// Get indicecs involved in this colvar
+      77             :   const std::vector<AtomNumber> & getAbsoluteIndexes()const override;
+      78             : /// We need our own calculate numerical derivatives here
+      79             :   void calculateNumericalDerivatives( ActionWithValue* a=NULL ) override;
+      80         785 :   void apply() override {};
+      81             : /// Is this atom currently being copied
+      82             :   bool isCurrentlyActive( const unsigned& ) override;
+      83             : /// This should not be called
+      84             :   Vector calculateCentralAtomPosition() { plumed_error(); }
+      85           0 :   double compute( const unsigned& tindex, AtomValuePack& myvals ) const override { plumed_error(); }
+      86             :   Vector getPositionOfAtomForLinkCells( const unsigned& iatom ) const override;
+      87             :   void getIndexList( const unsigned& ntotal, const unsigned& jstore, const unsigned& maxder, std::vector<unsigned>& indices );
+      88             :   void applyBridgeForces( const std::vector<double>& bb ) override;
+      89             :   Vector getCentralAtomPos( const unsigned& curr ) override;
+      90             :   void normalizeVector( std::vector<double>& vals ) const override;
+      91             :   void normalizeVectorDerivatives( MultiValue& myvals ) const override;
+      92             :   void getCentralAtomPack( const unsigned& basn, const unsigned& curr, CatomPack& mypack ) override;
+      93             : };
+      94             : 
+      95             : inline
+      96           5 : const std::vector<AtomNumber> & BridgedMultiColvarFunction::getAbsoluteIndexes() const {
+      97           5 :   return mycolv->getAbsoluteIndexes();
+      98             : }
+      99             : 
+     100             : inline
+     101             : MultiColvarBase* BridgedMultiColvarFunction::getPntrToMultiColvar() const {
+     102      890107 :   return mycolv;
+     103             : }
+     104             : 
+     105             : inline
+     106      128426 : unsigned BridgedMultiColvarFunction::getNumberOfDerivatives() {
+     107      128426 :   return mycolv->getNumberOfDerivatives() + 3*getNumberOfAtoms();
+     108             : }
+     109             : 
+     110             : inline
+     111           0 : bool BridgedMultiColvarFunction::isCurrentlyActive( const unsigned& code ) {
+     112           0 :   return mycolv->isCurrentlyActive( code );
+     113             : }
+     114             : 
+     115             : inline
+     116             : unsigned BridgedMultiColvarFunction::getSizeOfAtomsWithDerivatives() {
+     117             :   return mycolv->getNumberOfAtoms();
+     118             : }
+     119             : 
+     120             : inline
+     121           0 : Vector BridgedMultiColvarFunction::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
+     122           0 :   return mycolv->getPositionOfAtomForLinkCells(iatom);
+     123             : }
+     124             : 
+     125             : inline
+     126       78336 : Vector BridgedMultiColvarFunction::getCentralAtomPos( const unsigned& curr ) {
+     127       78336 :   return mycolv->getCentralAtomPos( curr );
+     128             : }
+     129             : 
+     130             : inline
+     131         156 : AtomNumber BridgedMultiColvarFunction::getAbsoluteIndexOfCentralAtom(const unsigned& i) const {
+     132         156 :   return mycolv->getAbsoluteIndexOfCentralAtom(i);
+     133             : }
+     134             : 
+     135             : inline
+     136           0 : void BridgedMultiColvarFunction::normalizeVector( std::vector<double>& vals ) const {
+     137           0 :   mycolv->normalizeVector( vals );
+     138           0 : }
+     139             : 
+     140             : inline
+     141           0 : void BridgedMultiColvarFunction::normalizeVectorDerivatives( MultiValue& myvals ) const {
+     142           0 :   mycolv->normalizeVectorDerivatives( myvals );
+     143           0 : }
+     144             : 
+     145             : }
+     146             : }
+     147             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.cpp.func-sort-c.html b/coverage/multicolvar/CatomPack.cpp.func-sort-c.html new file mode 100644 index 000000000000..f0686f7b50df --- /dev/null +++ b/coverage/multicolvar/CatomPack.cpp.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CatomPack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CatomPack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack6resizeERKj114577
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.cpp.func.html b/coverage/multicolvar/CatomPack.cpp.func.html new file mode 100644 index 000000000000..5ae44ab915ab --- /dev/null +++ b/coverage/multicolvar/CatomPack.cpp.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CatomPack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CatomPack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack6resizeERKj114577
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.cpp.gcov.html b/coverage/multicolvar/CatomPack.cpp.gcov.html new file mode 100644 index 000000000000..d0fda3f2d3dd --- /dev/null +++ b/coverage/multicolvar/CatomPack.cpp.gcov.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CatomPack.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CatomPack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "CatomPack.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace multicolvar {
+      26             : 
+      27      114577 : void CatomPack::resize( const unsigned& size ) {
+      28      114577 :   indices.resize(size); derivs.resize(size);
+      29      114577 : }
+      30             : 
+      31             : }
+      32             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.h.func-sort-c.html b/coverage/multicolvar/CatomPack.h.func-sort-c.html new file mode 100644 index 000000000000..2871b973d8b2 --- /dev/null +++ b/coverage/multicolvar/CatomPack.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CatomPack.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CatomPack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack13setDerivativeERKjRKNS_13TensorGenericILj3ELj3EEE676112
_ZNK4PLMD11multicolvar9CatomPack13getDerivativeERKjS3_RKNS_13VectorGenericILj3EEE3404445
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.h.func.html b/coverage/multicolvar/CatomPack.h.func.html new file mode 100644 index 000000000000..d88bb9a2258c --- /dev/null +++ b/coverage/multicolvar/CatomPack.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CatomPack.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CatomPack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9CatomPack13setDerivativeERKjRKNS_13TensorGenericILj3ELj3EEE676112
_ZNK4PLMD11multicolvar9CatomPack13getDerivativeERKjS3_RKNS_13VectorGenericILj3EEE3404445
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CatomPack.h.gcov.html b/coverage/multicolvar/CatomPack.h.gcov.html new file mode 100644 index 000000000000..0b63cc7be295 --- /dev/null +++ b/coverage/multicolvar/CatomPack.h.gcov.html @@ -0,0 +1,155 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CatomPack.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CatomPack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_multicolvar_CatomPack_h
+      23             : #define __PLUMED_multicolvar_CatomPack_h
+      24             : 
+      25             : #include <vector>
+      26             : #include "tools/Exception.h"
+      27             : #include "tools/Tensor.h"
+      28             : #include "tools/Vector.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace multicolvar {
+      32             : 
+      33      114695 : class CatomPack {
+      34             : private:
+      35             :   std::vector<unsigned> indices;
+      36             :   std::vector<Tensor> derivs;
+      37             : public:
+      38             :   void resize( const unsigned& );
+      39             :   void setIndex( const unsigned&, const unsigned& );
+      40             :   void setDerivative( const unsigned&, const Tensor& );
+      41             :   unsigned getNumberOfAtomsWithDerivatives() const ;
+      42             :   unsigned getIndex( const unsigned& ) const ;
+      43             :   double getDerivative( const unsigned&, const unsigned&, const Vector& ) const ;
+      44             : };
+      45             : 
+      46             : inline
+      47             : void CatomPack::setIndex( const unsigned& jind, const unsigned& ind ) {
+      48             :   plumed_dbg_assert( jind<indices.size() );
+      49      676112 :   indices[jind]=ind;
+      50             : }
+      51             : 
+      52             : inline
+      53      676112 : void CatomPack::setDerivative( const unsigned& jind, const Tensor& der ) {
+      54             :   plumed_dbg_assert( jind<indices.size() );
+      55      676112 :   derivs[jind]=der;
+      56      676112 : }
+      57             : 
+      58             : inline
+      59             : unsigned CatomPack::getNumberOfAtomsWithDerivatives() const {
+      60     2870978 :   return indices.size();
+      61             : }
+      62             : 
+      63             : inline
+      64             : unsigned CatomPack::getIndex( const unsigned& jind ) const {
+      65             :   plumed_dbg_assert( jind<indices.size() );
+      66     1133001 :   return indices[jind];
+      67             : }
+      68             : 
+      69             : inline
+      70     3404445 : double CatomPack::getDerivative( const unsigned& iatom, const unsigned& jcomp, const Vector& df ) const {
+      71             :   plumed_dbg_assert( iatom<indices.size() );
+      72     3404445 :   return df[jcomp]*derivs[iatom](jcomp,0) + df[jcomp]*derivs[iatom](jcomp,1) + df[jcomp]*derivs[iatom](jcomp,2);
+      73             : }
+      74             : 
+      75             : }
+      76             : }
+      77             : 
+      78             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CenterOfMultiColvar.cpp.func-sort-c.html b/coverage/multicolvar/CenterOfMultiColvar.cpp.func-sort-c.html new file mode 100644 index 000000000000..d761c9ae2e54 --- /dev/null +++ b/coverage/multicolvar/CenterOfMultiColvar.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CenterOfMultiColvar.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CenterOfMultiColvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:788196.3 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19CenterOfMultiColvarC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar19CenterOfMultiColvarC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar19CenterOfMultiColvar9calculateEv4
_ZN4PLMD11multicolvar19CenterOfMultiColvar16registerKeywordsERNS_8KeywordsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CenterOfMultiColvar.cpp.func.html b/coverage/multicolvar/CenterOfMultiColvar.cpp.func.html new file mode 100644 index 000000000000..f27f91d070b7 --- /dev/null +++ b/coverage/multicolvar/CenterOfMultiColvar.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CenterOfMultiColvar.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CenterOfMultiColvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:788196.3 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19CenterOfMultiColvar16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar19CenterOfMultiColvar9calculateEv4
_ZN4PLMD11multicolvar19CenterOfMultiColvarC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar19CenterOfMultiColvarC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CenterOfMultiColvar.cpp.gcov.html b/coverage/multicolvar/CenterOfMultiColvar.cpp.gcov.html new file mode 100644 index 000000000000..cd20f9ca6142 --- /dev/null +++ b/coverage/multicolvar/CenterOfMultiColvar.cpp.gcov.html @@ -0,0 +1,298 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CenterOfMultiColvar.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CenterOfMultiColvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:788196.3 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionWithVirtualAtom.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include "MultiColvarBase.h"
+      27             : #include "CatomPack.h"
+      28             : #include "BridgedMultiColvarFunction.h"
+      29             : #include "vesselbase/StoreDataVessel.h"
+      30             : 
+      31             : //+PLUMEDOC VATOM CENTER_OF_MULTICOLVAR
+      32             : /*
+      33             : Calculate a a weighted average position based on the value of some multicolvar.
+      34             : 
+      35             : This action calculates the position of a new virtual atom using the following formula:
+      36             : 
+      37             : \f[
+      38             : x_\alpha = \frac{1}{2\pi} \arctan \left[ \frac{ \sum_i w_i f_i \sin\left( 2\pi x_{i,\alpha} \right) }{ \sum_i w_i f_i \cos\left( 2\pi x_{i,\alpha} \right) } \right]
+      39             : \f]
+      40             : 
+      41             : Where in this expression the \f$w_i\f$ values are a set of weights calculated within a multicolvar
+      42             : action and the \f$f_i\f$ are the values of the multicolvar functions. The \f$x_{i,\alpha}\f$ values are
+      43             : the positions (in scaled coordinates) associated with each of the multicolvars calculated.
+      44             : 
+      45             : \bug The virial contribution for this type of virtual atom is not currently evaluated so do not use in bias functions unless the volume of the cell is fixed
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : Lets suppose that you are examining the formation of liquid droplets from gas.  You may want to
+      50             : determine the center of mass of any of the droplets formed.  In doing this calculation you recognize that
+      51             : the atoms in the liquid droplets will have a higher coordination number than those in the surrounding gas.
+      52             : As you want to calculate the position of the droplets you thus recognize that these atoms with high coordination
+      53             : numbers should have a high weight in the weighted average you are using to calculate the position of the droplet.
+      54             : You can thus calculate the position of the droplet using an input like the one shown below:
+      55             : 
+      56             : \plumedfile
+      57             : c1: COORDINATIONNUMBER LOWMEM SPECIES=1-512 SWITCH={EXP D_0=4.0 R_0=0.5}
+      58             : cc: CENTER_OF_MULTICOLVAR DATA=c1
+      59             : \endplumedfile
+      60             : 
+      61             : The first line here calculates the coordination numbers of all the atoms in the system.  The virtual atom then uses the values
+      62             : of the coordination numbers calculated by the action labelled c1 when it calculates the Berry Phase average described above.
+      63             : (N.B. the \f$w_i\f$ in the above expression are all set equal to 1 in this case)
+      64             : 
+      65             : The above input is fine we can, however, refine this somewhat by making use of a multicolvar transform action as shown below:
+      66             : 
+      67             : \plumedfile
+      68             : c1: COORDINATIONNUMBER SPECIES=1-512 SWITCH={EXP D_0=4.0 R_0=0.5}
+      69             : cf: MTRANSFORM_MORE DATA=c1 SWITCH={RATIONAL D_0=2.0 R_0=0.1} LOWMEM
+      70             : cc: CENTER_OF_MULTICOLVAR DATA=cf
+      71             : \endplumedfile
+      72             : 
+      73             : This input once again calculates the coordination numbers of all the atoms in the system.  The middle line then transforms these
+      74             : coordination numbers to numbers between 0 and 1.  Essentially any atom with a coordination number larger than 2.0 is given a weight
+      75             : of one and below this value the transformed value decays to zero.  It is these transformed coordination numbers that are used to calculate
+      76             : the Berry phase average described in the previous section.
+      77             : 
+      78             : */
+      79             : //+ENDPLUMEDOC
+      80             : 
+      81             : namespace PLMD {
+      82             : namespace multicolvar {
+      83             : 
+      84             : 
+      85             : class CenterOfMultiColvar : public ActionWithVirtualAtom {
+      86             : private:
+      87             :   unsigned comp;
+      88             :   vesselbase::StoreDataVessel* mystash;
+      89             :   MultiColvarBase* mycolv;
+      90             : public:
+      91             :   static void registerKeywords( Keywords& keys );
+      92             :   explicit CenterOfMultiColvar(const ActionOptions&ao);
+      93             :   void calculate() override;
+      94             : };
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(CenterOfMultiColvar,"CENTER_OF_MULTICOLVAR")
+      97             : 
+      98           5 : void CenterOfMultiColvar::registerKeywords(Keywords& keys) {
+      99           5 :   ActionWithVirtualAtom::registerKeywords(keys);
+     100          10 :   keys.add("compulsory","DATA","find the average value for a multicolvar");
+     101          10 :   keys.add("optional","COMPONENT","if your input multicolvar is a vector then specify which component you would like to use in calculating the weight");
+     102           5 : }
+     103             : 
+     104           3 : CenterOfMultiColvar::CenterOfMultiColvar(const ActionOptions&ao):
+     105             :   Action(ao),
+     106           3 :   ActionWithVirtualAtom(ao)
+     107             : {
+     108           3 :   std::string mlab; parse("DATA",mlab);
+     109           3 :   mycolv= plumed.getActionSet().selectWithLabel<MultiColvarBase*>(mlab);
+     110           3 :   if(!mycolv) error("action labelled " +  mlab + " does not exist or does not have vessels");
+     111             :   // Copy the atoms from the input multicolvar
+     112           3 :   BridgedMultiColvarFunction* mybr=dynamic_cast<BridgedMultiColvarFunction*>( mycolv );
+     113           3 :   if( mybr ) {
+     114           2 :     requestAtoms( (mybr->getPntrToMultiColvar())->getAbsoluteIndexes() ); comp=1;
+     115             :   } else {
+     116           1 :     if( mycolv->getNumberOfQuantities()>5 ) {
+     117           0 :       int incomp=-1; parse("COMPONENT",incomp);
+     118           0 :       if( incomp<0 ) error("vector input but component was not specified");
+     119           0 :       comp=incomp;
+     120             :     } else {
+     121           1 :       comp=1;
+     122             :     }
+     123           1 :     requestAtoms( mycolv->getAbsoluteIndexes () );
+     124             :   }
+     125             :   // We need the derivatives
+     126           3 :   mycolv->turnOnDerivatives(); addDependency(mycolv);
+     127           3 :   mystash = mycolv->buildDataStashes( NULL );
+     128           3 :   log.printf("  building center of mass based on weights calculated in multicolvar action named %s \n",mycolv->getLabel().c_str() );
+     129           3 : }
+     130             : 
+     131           4 : void CenterOfMultiColvar::calculate() {
+     132             :   // Retrieve the periodic boundary conditions
+     133           4 :   const Pbc& pbc=mycolv->getPbc();
+     134           4 :   if( !pbc.isOrthorombic() ) error("Berry phase does not work for non orthorhombic cells");
+     135             : 
+     136             :   // Create a multivalue to store the derivatives
+     137           4 :   MultiValue myvals( 7, mycolv->getNumberOfDerivatives() ); myvals.clearAll();
+     138           4 :   MultiValue tvals( mycolv->getNumberOfQuantities(), mycolv->getNumberOfDerivatives() );
+     139           4 :   tvals.clearAll();
+     140             : 
+     141             :   // Now loop over all active multicolvars
+     142           4 :   Vector stmp, ctmp, scom, ccom, sder, cder;
+     143           4 :   scom.zero(); ccom.zero(); double norm=0;
+     144           4 :   std::vector<double> cvals( mycolv->getNumberOfQuantities() );
+     145        1818 :   for(unsigned i=0; i<mystash->getNumberOfStoredValues(); ++i) {
+     146             :     // Retrieve value and derivatives
+     147        1814 :     mystash->retrieveSequentialValue( i, false, cvals );
+     148        1814 :     mystash->retrieveDerivatives( mycolv->getPositionInFullTaskList(i), false, tvals );
+     149             :     // Convert position into fractionals
+     150        1814 :     Vector fpos = pbc.realToScaled( mycolv->getCentralAtomPos( mycolv->getPositionInFullTaskList(i) ) );
+     151             :     // Now accumulate Berry phase averages
+     152        7256 :     for(unsigned j=0; j<3; ++j) {
+     153        5442 :       stmp[j] = std::sin( 2*pi*fpos[j] ); ctmp[j] = std::cos( 2*pi*fpos[j] );
+     154        5442 :       scom[j] += cvals[0]*cvals[comp]*stmp[j]; ccom[j] += cvals[0]*cvals[comp]*ctmp[j];
+     155        5442 :       double icell = 1.0 / getPbc().getBox().getRow(j).modulo();
+     156        5442 :       sder[j] = 2*pi*icell*cvals[0]*cvals[comp]*std::cos( 2*pi*fpos[j] );
+     157        5442 :       cder[j]=-2*pi*icell*cvals[0]*cvals[comp]*std::sin( 2*pi*fpos[j] );
+     158             :     }
+     159             :     // Now accumulate derivatives
+     160     1623560 :     for(unsigned k=0; k<tvals.getNumberActive(); ++k) {
+     161     1621746 :       unsigned icomp=tvals.getActiveIndex(k);
+     162     1621746 :       myvals.addDerivative( 0, icomp, cvals[0]*tvals.getDerivative( comp, icomp ) + cvals[comp]*tvals.getDerivative( 0, icomp ) );
+     163     6486984 :       for(unsigned k=0; k<3; ++k) {
+     164     4865238 :         myvals.addDerivative( 1+k, icomp, stmp[k]*( cvals[0]*tvals.getDerivative( comp, icomp ) +
+     165     4865238 :                               cvals[comp]*tvals.getDerivative( 0, icomp ) ) );
+     166     4865238 :         myvals.addDerivative( 4+k, icomp, ctmp[k]*( cvals[0]*tvals.getDerivative( comp, icomp ) +
+     167     4865238 :                               cvals[comp]*tvals.getDerivative( 0, icomp ) ) );
+     168             :       }
+     169             :     }
+     170             :     // Get the central atom pack
+     171        1814 :     CatomPack mypack; mycolv->getCentralAtomPack( 0, mycolv->getPositionInFullTaskList(i), mypack );
+     172        3628 :     for(unsigned j=0; j<mypack.getNumberOfAtomsWithDerivatives(); ++j) {
+     173        1814 :       unsigned jder=3*mypack.getIndex(j);
+     174             :       // Derivatives of sine
+     175        1814 :       myvals.addDerivative( 1, jder+0, mypack.getDerivative(j, 0, sder) );
+     176        1814 :       myvals.addDerivative( 2, jder+1, mypack.getDerivative(j, 1, sder) );
+     177        1814 :       myvals.addDerivative( 3, jder+2, mypack.getDerivative(j, 2, sder) );
+     178             :       // Derivatives of cosine
+     179        1814 :       myvals.addDerivative( 4, jder+0, mypack.getDerivative(j, 0, cder) );
+     180        1814 :       myvals.addDerivative( 5, jder+1, mypack.getDerivative(j, 1, cder) );
+     181        1814 :       myvals.addDerivative( 6, jder+2, mypack.getDerivative(j, 2, cder) );
+     182             :     }
+     183        1814 :     norm += cvals[0]*cvals[comp]; tvals.clearAll();
+     184             :   }
+     185             : 
+     186             :   // And now finish Berry phase average
+     187           4 :   scom /= norm; ccom /=norm; Vector cpos;
+     188          16 :   for(unsigned j=0; j<3; ++j) cpos[j] = std::atan2( scom[j], ccom[j] ) / (2*pi);
+     189           4 :   Vector cart_pos = pbc.scaledToReal( cpos );
+     190           4 :   setPosition(cart_pos); setMass(1.0);   // This could be much cleverer but not without changing many things in PLMED
+     191             : 
+     192             :   // And derivatives
+     193           4 :   Vector tander; myvals.updateDynamicList(); double inv_weight = 1.0 / norm;
+     194          16 :   for(unsigned j=0; j<3; ++j) {
+     195          12 :     double tmp = scom[j] / ccom[j];
+     196          12 :     tander[j] = getPbc().getBox().getRow(j).modulo() / (2*pi*( 1 + tmp*tmp ));
+     197             :   }
+     198        5578 :   for(unsigned i=0; i<myvals.getNumberActive(); ++i) {
+     199        5574 :     unsigned ider=myvals.getActiveIndex(i);
+     200       22296 :     for(unsigned j=0; j<3; ++j) {
+     201       16722 :       double sderv = inv_weight*myvals.getDerivative(1+j,ider) - inv_weight*scom[j]*myvals.getDerivative(0,ider);
+     202       16722 :       double cderv = inv_weight*myvals.getDerivative(4+j,ider) - inv_weight*ccom[j]*myvals.getDerivative(0,ider);
+     203       16722 :       myvals.setDerivative( 1+j, ider, tander[j]*(sderv/ccom[j]  - scom[j]*cderv/(ccom[j]*ccom[j])) );
+     204             :       //if( j==2 ) std::printf("DERIV %d %10.4f %10.4f %10.4f %10.4f \n",i,myvals.getDerivative(0,ider),sderv,cderv,myvals.getDerivative(1+j,ider ) );
+     205             :     }
+     206             :   }
+     207             : 
+     208             :   // Atom derivatives
+     209           4 :   std::vector<Tensor> fderiv( getNumberOfAtoms() );
+     210        2052 :   for(unsigned j=0; j<getNumberOfAtoms(); ++j) {
+     211        8192 :     for(unsigned k=0; k<3; ++k) {
+     212       22758 :       if( myvals.isActive(3*j+k) ) for(unsigned n=0; n<3; ++n) fderiv[j](k,n) = myvals.getDerivative( 1+n, 3*j+k );
+     213        2424 :       else for(unsigned n=0; n<3; ++n) fderiv[j](k,n) = 0;
+     214             :     }
+     215             :   }
+     216           4 :   setAtomsDerivatives( fderiv );
+     217             :   // Box derivatives?
+     218           4 : }
+     219             : 
+     220             : }
+     221             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CoordinationNumbers.cpp.func-sort-c.html b/coverage/multicolvar/CoordinationNumbers.cpp.func-sort-c.html new file mode 100644 index 000000000000..ce243a3d82f4 --- /dev/null +++ b/coverage/multicolvar/CoordinationNumbers.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CoordinationNumbers.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CoordinationNumbers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19CoordinationNumbersC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar19CoordinationNumbersC1ERKNS_13ActionOptionsE52
_ZN4PLMD11multicolvar19CoordinationNumbers16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD11multicolvar19CoordinationNumbers10isPeriodicEv856
_ZNK4PLMD11multicolvar19CoordinationNumbers7computeERKjRNS0_13AtomValuePackE37088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CoordinationNumbers.cpp.func.html b/coverage/multicolvar/CoordinationNumbers.cpp.func.html new file mode 100644 index 000000000000..83496607348f --- /dev/null +++ b/coverage/multicolvar/CoordinationNumbers.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CoordinationNumbers.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CoordinationNumbers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19CoordinationNumbers10isPeriodicEv856
_ZN4PLMD11multicolvar19CoordinationNumbers16registerKeywordsERNS_8KeywordsE54
_ZN4PLMD11multicolvar19CoordinationNumbersC1ERKNS_13ActionOptionsE52
_ZN4PLMD11multicolvar19CoordinationNumbersC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar19CoordinationNumbers7computeERKjRNS0_13AtomValuePackE37088
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/CoordinationNumbers.cpp.gcov.html b/coverage/multicolvar/CoordinationNumbers.cpp.gcov.html new file mode 100644 index 000000000000..ad730ee009d1 --- /dev/null +++ b/coverage/multicolvar/CoordinationNumbers.cpp.gcov.html @@ -0,0 +1,261 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/CoordinationNumbers.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - CoordinationNumbers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "tools/NeighborList.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/SwitchingFunction.h"
+      27             : 
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace multicolvar {
+      33             : 
+      34             : //+PLUMEDOC MCOLVAR COORDINATIONNUMBER
+      35             : /*
+      36             : Calculate the coordination numbers of atoms so that you can then calculate functions of the distribution of
+      37             :  coordination numbers such as the minimum, the number less than a certain quantity and so on.
+      38             : 
+      39             : So that the calculated coordination numbers have continuous derivatives the following function is used:
+      40             : 
+      41             : \f[
+      42             : s = \frac{ 1 - \left(\frac{r-d_0}{r_0}\right)^n } { 1 - \left(\frac{r-d_0}{r_0}\right)^m }
+      43             : \f]
+      44             : 
+      45             : If R_POWER is set, this will use the product of pairwise distance
+      46             : raised to the R_POWER with the coordination number function defined
+      47             : above. This was used in White and Voth \cite white2014efficient as a
+      48             : way of indirectly biasing radial distribution functions. Note that in
+      49             : that reference this function is referred to as moments of coordination
+      50             : number, but here we call them powers to distinguish from the existing
+      51             : MOMENTS keyword of Multicolvars.
+      52             : 
+      53             : \par Examples
+      54             : 
+      55             : The following input tells plumed to calculate the coordination numbers of atoms 1-100 with themselves.
+      56             : The minimum coordination number is then calculated.
+      57             : \plumedfile
+      58             : COORDINATIONNUMBER SPECIES=1-100 R_0=1.0 MIN={BETA=0.1}
+      59             : \endplumedfile
+      60             : 
+      61             : The following input tells plumed to calculate how many atoms from 1-100 are within 3.0 of each of the atoms
+      62             : from 101-110.  In the first 101 is the central atom, in the second 102 is the central atom and so on.  The
+      63             : number of coordination numbers more than 6 is then computed.
+      64             : \plumedfile
+      65             : COORDINATIONNUMBER SPECIESA=101-110 SPECIESB=1-100 R_0=3.0 MORE_THAN={RATIONAL R_0=6.0 NN=6 MM=12 D_0=0}
+      66             : \endplumedfile
+      67             : 
+      68             : The following input tells plumed to calculate the mean coordination number of all atoms with themselves
+      69             : and its powers. An explicit cutoff is set for each of 8.
+      70             : \plumedfile
+      71             : cn0: COORDINATIONNUMBER SPECIES=1-10 SWITCH={RATIONAL R_0=1.0 D_MAX=8} MEAN
+      72             : cn1: COORDINATIONNUMBER SPECIES=1-10 SWITCH={RATIONAL R_0=1.0 D_MAX=8} R_POWER=1 MEAN
+      73             : cn2: COORDINATIONNUMBER SPECIES=1-10 SWITCH={RATIONAL R_0=1.0 D_MAX=8} R_POWER=2 MEAN
+      74             : PRINT ARG=cn0.mean,cn1.mean,cn2.mean STRIDE=1 FILE=cn_out
+      75             : \endplumedfile
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : 
+      81             : class CoordinationNumbers : public MultiColvarBase {
+      82             : private:
+      83             :   double rcut2;
+      84             :   int r_power;
+      85             :   SwitchingFunction switchingFunction;
+      86             : public:
+      87             :   static void registerKeywords( Keywords& keys );
+      88             :   explicit CoordinationNumbers(const ActionOptions&);
+      89             : // active methods:
+      90             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      91             : /// Returns the number of coordinates of the field
+      92         856 :   bool isPeriodic() override { return false; }
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(CoordinationNumbers,"COORDINATIONNUMBER")
+      96             : 
+      97          54 : void CoordinationNumbers::registerKeywords( Keywords& keys ) {
+      98          54 :   MultiColvarBase::registerKeywords( keys );
+      99         162 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+     100         108 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     101         108 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     102         108 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     103         108 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     104         108 :   keys.add("optional","R_POWER","Multiply the coordination number function by a power of r, "
+     105             :            "as done in White and Voth (see note above, default: no)");
+     106         108 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+     107             :            "The following provides information on the \\ref switchingfunction that are available. "
+     108             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     109             :   // Use actionWithDistributionKeywords
+     110         216 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+     111         216 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     112         162 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     113          54 : }
+     114             : 
+     115          52 : CoordinationNumbers::CoordinationNumbers(const ActionOptions&ao):
+     116             :   Action(ao),
+     117             :   MultiColvarBase(ao),
+     118          52 :   r_power(0)
+     119             : {
+     120             : 
+     121             :   // Read in the switching function
+     122         104 :   std::string sw, errors; parse("SWITCH",sw);
+     123          52 :   if(sw.length()>0) {
+     124          50 :     switchingFunction.set(sw,errors);
+     125          50 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     126             :   } else {
+     127           2 :     double r_0=-1.0, d_0; int nn, mm;
+     128           4 :     parse("NN",nn); parse("MM",mm);
+     129           4 :     parse("R_0",r_0); parse("D_0",d_0);
+     130           2 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     131           2 :     switchingFunction.set(nn,mm,r_0,d_0);
+     132             : 
+     133             :   }
+     134          52 :   log.printf("  coordination of central atom and those within %s\n",( switchingFunction.description() ).c_str() );
+     135             : 
+     136             :   //get cutoff of switching function
+     137          52 :   double rcut = switchingFunction.get_dmax();
+     138             : 
+     139             :   //parse power
+     140          52 :   parse("R_POWER", r_power);
+     141          52 :   if(r_power > 0) {
+     142           4 :     log.printf("  Multiplying switching function by r^%d\n", r_power);
+     143           4 :     double offset = switchingFunction.calculate(rcut*0.9999, rcut2) * std::pow(rcut*0.9999, r_power);
+     144           4 :     log.printf("  You will have a discontinuous jump of %f to 0 near the cutoff of your switching function. "
+     145             :                "Consider setting D_MAX or reducing R_POWER if this is large\n", offset);
+     146             :   }
+     147             : 
+     148             :   // Set the link cell cutoff
+     149          52 :   setLinkCellCutoff( rcut );
+     150          52 :   rcut2 = rcut * rcut;
+     151             : 
+     152             :   // And setup the ActionWithVessel
+     153          52 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms ); checkRead();
+     154          52 : }
+     155             : 
+     156       37088 : double CoordinationNumbers::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     157             :   // Calculate the coordination number
+     158             :   double dfunc, sw, d, raised;
+     159     3822803 :   for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     160             :     Vector& distance=myatoms.getPosition(i);
+     161             :     double d2;
+     162     7107372 :     if ( (d2=distance[0]*distance[0])<rcut2 &&
+     163     3321657 :          (d2+=distance[1]*distance[1])<rcut2 &&
+     164     6676366 :          (d2+=distance[2]*distance[2])<rcut2 &&
+     165             :          d2>epsilon ) {
+     166             : 
+     167     2633753 :       sw = switchingFunction.calculateSqr( d2, dfunc );
+     168     2633753 :       if(r_power > 0) {
+     169       19350 :         d = std::sqrt(d2); raised = std::pow( d, r_power - 1 );
+     170       19350 :         accumulateSymmetryFunction( 1, i, sw * raised * d,
+     171       19350 :                                     (dfunc * d * raised + sw * r_power * raised / d) * distance,
+     172       38700 :                                     (-dfunc * d * raised - sw * r_power * raised / d) * Tensor(distance, distance),
+     173             :                                     myatoms );
+     174             :       } else {
+     175     2614403 :         accumulateSymmetryFunction( 1, i, sw, (dfunc)*distance, (-dfunc)*Tensor(distance,distance), myatoms );
+     176             :       }
+     177             :     }
+     178             :   }
+     179             : 
+     180       37088 :   return myatoms.getValue(1);
+     181             : }
+     182             : 
+     183             : }
+     184             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Density.cpp.func-sort-c.html b/coverage/multicolvar/Density.cpp.func-sort-c.html new file mode 100644 index 000000000000..950ad563d2e1 --- /dev/null +++ b/coverage/multicolvar/Density.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Density.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Density.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:162369.6 %
Date:2024-02-22 21:58:45Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar7Density12getIndexListERKjS3_S3_RSt6vectorIjSaIjEE0
_ZN4PLMD11multicolvar7Density15getValueForTaskERKjRSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar7DensityC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar7Density28hasDifferentiableOrientationEv0
_ZN4PLMD11multicolvar7Density10isPeriodicEv4
_ZN4PLMD11multicolvar7DensityC1ERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar7Density16registerKeywordsERNS_8KeywordsE13
_ZNK4PLMD11multicolvar7Density7computeERKjRNS0_13AtomValuePackE15955
_ZNK4PLMD11multicolvar7Density9isDensityEv200727
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Density.cpp.func.html b/coverage/multicolvar/Density.cpp.func.html new file mode 100644 index 000000000000..538eb0d5a7f2 --- /dev/null +++ b/coverage/multicolvar/Density.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Density.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Density.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:162369.6 %
Date:2024-02-22 21:58:45Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar7Density10isPeriodicEv4
_ZN4PLMD11multicolvar7Density12getIndexListERKjS3_S3_RSt6vectorIjSaIjEE0
_ZN4PLMD11multicolvar7Density15getValueForTaskERKjRSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar7Density16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD11multicolvar7DensityC1ERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar7DensityC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar7Density28hasDifferentiableOrientationEv0
_ZNK4PLMD11multicolvar7Density7computeERKjRNS0_13AtomValuePackE15955
_ZNK4PLMD11multicolvar7Density9isDensityEv200727
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Density.cpp.gcov.html b/coverage/multicolvar/Density.cpp.gcov.html new file mode 100644 index 000000000000..bd5637b8be8d --- /dev/null +++ b/coverage/multicolvar/Density.cpp.gcov.html @@ -0,0 +1,182 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Density.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Density.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:162369.6 %
Date:2024-02-22 21:58:45Functions:5955.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : #include <string>
+      27             : #include <cmath>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace multicolvar {
+      31             : 
+      32             : //+PLUMEDOC MCOLVAR DENSITY
+      33             : /*
+      34             : Calculate functions of the density of atoms as a function of the box.  This allows one to calculate
+      35             :  the number of atoms in half the box.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : The following example calculates the number of atoms in one half of the simulation box.
+      40             : 
+      41             : \plumedfile
+      42             : DENSITY SPECIES=1-100 LABEL=d
+      43             : AROUND ATOM=101 DATA=d SIGMA=0.1 XLOWER=0.0 XUPPER=0.5 LABEL=d1
+      44             : PRINT ARG=d1.* FILE=colvar1 FMT=%8.4f
+      45             : \endplumedfile
+      46             : 
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : 
+      51             : class Density : public MultiColvarBase {
+      52             : public:
+      53             :   static void registerKeywords( Keywords& keys );
+      54             :   explicit Density(const ActionOptions&);
+      55             : // active methods:
+      56             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      57             :   /// Returns the number of coordinates of the field
+      58           4 :   bool isPeriodic() override { return false; }
+      59      200727 :   bool isDensity() const override { return true; }
+      60           0 :   bool hasDifferentiableOrientation() const override { return true; }
+      61             : //  void addOrientationDerivativesToBase( const unsigned& iatom, const unsigned& jstore, const unsigned& base_cv_no,
+      62             : //                                        const std::vector<double>& weight, MultiColvarFunction* func ){}
+      63             :   void getIndexList( const unsigned& ntotal, const unsigned& jstore, const unsigned& maxder, std::vector<unsigned>& indices );
+      64             : //  unsigned getNumberOfQuantities();
+      65             :   void getValueForTask( const unsigned& iatom, std::vector<double>& vals );
+      66             : };
+      67             : 
+      68             : PLUMED_REGISTER_ACTION(Density,"DENSITY")
+      69             : 
+      70          13 : void Density::registerKeywords( Keywords& keys ) {
+      71          13 :   MultiColvarBase::registerKeywords( keys );
+      72          13 :   keys.use("SPECIES");
+      73          13 : }
+      74             : 
+      75          11 : Density::Density(const ActionOptions&ao):
+      76             :   Action(ao),
+      77          11 :   MultiColvarBase(ao)
+      78             : {
+      79          11 :   std::vector<AtomNumber> all_atoms; parseMultiColvarAtomList("SPECIES", -1, all_atoms);
+      80          11 :   ablocks.resize(1); ablocks[0].resize( atom_lab.size() );
+      81         489 :   for(unsigned i=0; i<atom_lab.size(); ++i) { addTaskToList(i); ablocks[0][i]=i; }
+      82          11 :   setupMultiColvarBase( all_atoms );
+      83             :   // And check everything has been read in correctly
+      84          11 :   checkRead();
+      85          11 : }
+      86             : 
+      87       15955 : double Density::compute( const unsigned& tindex, AtomValuePack& myvals ) const {
+      88       15955 :   return 1.0;
+      89             : }
+      90             : 
+      91           0 : void Density::getIndexList( const unsigned& ntotal, const unsigned& jstore, const unsigned& maxder, std::vector<unsigned>& indices ) {
+      92           0 :   indices[jstore]=0;
+      93           0 : }
+      94             : 
+      95             : // unsigned Density::getNumberOfQuantities(){
+      96             : //    return 2;
+      97             : // }
+      98             : 
+      99           0 : void Density::getValueForTask( const unsigned& iatom, std::vector<double>& vals ) {
+     100           0 :   plumed_dbg_assert( vals.size()==2 ); vals[0]=vals[1]=1.0;
+     101           0 : }
+     102             : 
+     103             : }
+     104             : }
+     105             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DihedralCorrelation.cpp.func-sort-c.html b/coverage/multicolvar/DihedralCorrelation.cpp.func-sort-c.html new file mode 100644 index 000000000000..df7a92b9ddf8 --- /dev/null +++ b/coverage/multicolvar/DihedralCorrelation.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/DihedralCorrelation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DihedralCorrelation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:484998.0 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19DihedralCorrelation10isPeriodicEv0
_ZN4PLMD11multicolvar19DihedralCorrelationC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar19DihedralCorrelationC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar19DihedralCorrelation16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD11multicolvar19DihedralCorrelation7computeERKjRNS0_13AtomValuePackE590
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DihedralCorrelation.cpp.func.html b/coverage/multicolvar/DihedralCorrelation.cpp.func.html new file mode 100644 index 000000000000..1bbd28ebd0ab --- /dev/null +++ b/coverage/multicolvar/DihedralCorrelation.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/DihedralCorrelation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DihedralCorrelation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:484998.0 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19DihedralCorrelation10isPeriodicEv0
_ZN4PLMD11multicolvar19DihedralCorrelation16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar19DihedralCorrelationC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar19DihedralCorrelationC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar19DihedralCorrelation7computeERKjRNS0_13AtomValuePackE590
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DihedralCorrelation.cpp.gcov.html b/coverage/multicolvar/DihedralCorrelation.cpp.gcov.html new file mode 100644 index 000000000000..63838a7a245a --- /dev/null +++ b/coverage/multicolvar/DihedralCorrelation.cpp.gcov.html @@ -0,0 +1,251 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/DihedralCorrelation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DihedralCorrelation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:484998.0 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "tools/Torsion.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace multicolvar {
+      32             : 
+      33             : //+PLUMEDOC COLVAR DIHCOR
+      34             : /*
+      35             : Measures the degree of similarity between dihedral angles.
+      36             : 
+      37             : This colvar calculates the following quantity.
+      38             : 
+      39             : \f[
+      40             : s = \frac{1}{2} \sum_i \left[ 1 + \cos( \phi_i - \psi_i ) \right]
+      41             : \f]
+      42             : 
+      43             : where the \f$\phi_i\f$ and \f$\psi\f$ values and the instantaneous values for the \ref TORSION angles of interest.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : The following provides an example input for the DIHCOR action
+      48             : 
+      49             : \plumedfile
+      50             : DIHCOR ...
+      51             :   ATOMS1=1,2,3,4,5,6,7,8
+      52             :   ATOMS2=5,6,7,8,9,10,11,12
+      53             :   LABEL=dih
+      54             : ... DIHCOR
+      55             : PRINT ARG=dih FILE=colvar STRIDE=10
+      56             : \endplumedfile
+      57             : 
+      58             : In the above input we are calculating the correlation between the torsion angle involving atoms 1, 2, 3 and 4 and the torsion angle
+      59             : involving atoms 5, 6, 7 and 8.  This is then added to the correlation between the torsion angle involving atoms 5, 6, 7 and 8 and the
+      60             : correlation angle involving atoms 9, 10, 11 and 12.
+      61             : 
+      62             : Writing out the atoms involved in all the torsion angles in this way can be rather tedious. Thankfully if you are working with protein you
+      63             : can avoid this by using the \ref MOLINFO command.  PLUMED uses the pdb file that you provide to this command to learn
+      64             : about the topology of the protein molecule.  This means that you can specify torsion angles using the following syntax:
+      65             : 
+      66             : \plumedfile
+      67             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      68             : MOLINFO MOLTYPE=protein STRUCTURE=myprotein.pdb
+      69             : dih: DIHCOR ...
+      70             : ATOMS1=@phi-3,@psi-3
+      71             : ATOMS2=@psi-3,@phi-4
+      72             : ATOMS3=@phi-4,@psi-4
+      73             : ...
+      74             : PRINT ARG=dih FILE=colvar STRIDE=10
+      75             : \endplumedfile
+      76             : 
+      77             : Here, \@phi-3 tells plumed that you would like to calculate the \f$\phi\f$ angle in the third residue of the protein.
+      78             : Similarly \@psi-4 tells plumed that you want to calculate the \f$\psi\f$ angle of the fourth residue of the protein.
+      79             : 
+      80             : */
+      81             : //+ENDPLUMEDOC
+      82             : 
+      83             : class DihedralCorrelation : public MultiColvarBase {
+      84             : private:
+      85             : public:
+      86             :   static void registerKeywords( Keywords& keys );
+      87             :   explicit DihedralCorrelation(const ActionOptions&);
+      88             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      89           0 :   bool isPeriodic() override { return false; }
+      90             : };
+      91             : 
+      92             : PLUMED_REGISTER_ACTION(DihedralCorrelation,"DIHCOR")
+      93             : 
+      94           4 : void DihedralCorrelation::registerKeywords( Keywords& keys ) {
+      95           4 :   MultiColvarBase::registerKeywords( keys );
+      96           8 :   keys.add("numbered","ATOMS","the atoms involved in each of the dihedral correlation values you wish to calculate. "
+      97             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one dihedral correlation will be "
+      98             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+      99             :            "specify the indices of 8 atoms).  The eventual number of quantities calculated by this "
+     100             :            "action will depend on what functions of the distribution you choose to calculate.");
+     101           8 :   keys.reset_style("ATOMS","atoms");
+     102           4 : }
+     103             : 
+     104           2 : DihedralCorrelation::DihedralCorrelation(const ActionOptions&ao):
+     105             :   Action(ao),
+     106           2 :   MultiColvarBase(ao)
+     107             : {
+     108             :   // Read in the atoms
+     109             :   std::vector<AtomNumber> all_atoms;
+     110           2 :   readAtomsLikeKeyword( "ATOMS", 8, all_atoms );
+     111           2 :   setupMultiColvarBase( all_atoms );
+     112             :   // Stuff for central atoms
+     113           2 :   std::vector<bool> catom_ind(8, false);
+     114           6 :   catom_ind[1]=catom_ind[2]=catom_ind[5]=catom_ind[6]=true;
+     115           2 :   setAtomsForCentralAtom( catom_ind );
+     116             : 
+     117             :   // And setup the ActionWithVessel
+     118           2 :   if( getNumberOfVessels()==0 ) {
+     119             :     std::string fake_input;
+     120           2 :     addVessel( "SUM", fake_input, -1 );  // -1 here means that this value will be named getLabel()
+     121           2 :     readVesselKeywords();  // This makes sure resizing is done
+     122             :   }
+     123             : 
+     124             :   // And check everything has been read in correctly
+     125           2 :   checkRead();
+     126           2 : }
+     127             : 
+     128         590 : double DihedralCorrelation::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     129         590 :   const Vector d10=getSeparation(myatoms.getPosition(1),myatoms.getPosition(0));
+     130         590 :   const Vector d11=getSeparation(myatoms.getPosition(2),myatoms.getPosition(1));
+     131         590 :   const Vector d12=getSeparation(myatoms.getPosition(3),myatoms.getPosition(2));
+     132             : 
+     133         590 :   Vector dd10,dd11,dd12;
+     134             :   PLMD::Torsion t1;
+     135         590 :   const double phi1  = t1.compute(d10,d11,d12,dd10,dd11,dd12);
+     136             : 
+     137         590 :   const Vector d20=getSeparation(myatoms.getPosition(5),myatoms.getPosition(4));
+     138         590 :   const Vector d21=getSeparation(myatoms.getPosition(6),myatoms.getPosition(5));
+     139         590 :   const Vector d22=getSeparation(myatoms.getPosition(7),myatoms.getPosition(6));
+     140             : 
+     141         590 :   Vector dd20,dd21,dd22;
+     142             :   PLMD::Torsion t2;
+     143         590 :   const double phi2 = t2.compute( d20, d21, d22, dd20, dd21, dd22 );
+     144             : 
+     145             :   // Calculate value
+     146         590 :   const double diff = phi2 - phi1;
+     147         590 :   const double value = 0.5*(1.+std::cos(diff));
+     148             :   // Derivatives wrt phi1
+     149         590 :   const double dval = 0.5*std::sin(diff);
+     150         590 :   dd10 *= dval;
+     151         590 :   dd11 *= dval;
+     152         590 :   dd12 *= dval;
+     153             :   // And add
+     154         590 :   addAtomDerivatives(1, 0, dd10, myatoms );
+     155         590 :   addAtomDerivatives(1, 1, dd11-dd10, myatoms );
+     156         590 :   addAtomDerivatives(1, 2, dd12-dd11, myatoms );
+     157         590 :   addAtomDerivatives(1, 3, -dd12, myatoms );
+     158         590 :   myatoms.addBoxDerivatives  (1, -(extProduct(d10,dd10)+extProduct(d11,dd11)+extProduct(d12,dd12)));
+     159             :   // Derivative wrt phi2
+     160         590 :   dd20 *= -dval;
+     161         590 :   dd21 *= -dval;
+     162         590 :   dd22 *= -dval;
+     163             :   // And add
+     164         590 :   addAtomDerivatives(1, 4, dd20, myatoms );
+     165         590 :   addAtomDerivatives(1, 5, dd21-dd20, myatoms );
+     166         590 :   addAtomDerivatives(1, 6, dd22-dd21, myatoms );
+     167         590 :   addAtomDerivatives(1, 7, -dd22, myatoms );
+     168         590 :   myatoms.addBoxDerivatives(1, -(extProduct(d20,dd20)+extProduct(d21,dd21)+extProduct(d22,dd22)));
+     169             : 
+     170         590 :   return value;
+     171             : }
+     172             : 
+     173             : }
+     174             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DistanceFromContour.cpp.func-sort-c.html b/coverage/multicolvar/DistanceFromContour.cpp.func-sort-c.html new file mode 100644 index 000000000000..23f9f616247e --- /dev/null +++ b/coverage/multicolvar/DistanceFromContour.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/DistanceFromContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DistanceFromContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13115286.2 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19DistanceFromContour10isPeriodicEv0
_ZN4PLMD11multicolvar19DistanceFromContourC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar19DistanceFromContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar19DistanceFromContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar19DistanceFromContour5applyEv137
_ZN4PLMD11multicolvar19DistanceFromContour9calculateEv137
_ZN4PLMD11multicolvar19DistanceFromContour24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_3115
_ZNK4PLMD11multicolvar19DistanceFromContour7computeERKjRNS0_13AtomValuePackE3115
_ZNK4PLMD11multicolvar19DistanceFromContour9isDensityEv3115
_ZNK4PLMD11multicolvar19DistanceFromContour21getNumberOfQuantitiesEv6230
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DistanceFromContour.cpp.func.html b/coverage/multicolvar/DistanceFromContour.cpp.func.html new file mode 100644 index 000000000000..760c198bc03b --- /dev/null +++ b/coverage/multicolvar/DistanceFromContour.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/DistanceFromContour.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DistanceFromContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13115286.2 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar19DistanceFromContour10isPeriodicEv0
_ZN4PLMD11multicolvar19DistanceFromContour16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar19DistanceFromContour24getDifferenceFromContourERKSt6vectorIdSaIdEERS4_3115
_ZN4PLMD11multicolvar19DistanceFromContour5applyEv137
_ZN4PLMD11multicolvar19DistanceFromContour9calculateEv137
_ZN4PLMD11multicolvar19DistanceFromContourC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar19DistanceFromContourC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar19DistanceFromContour21getNumberOfQuantitiesEv6230
_ZNK4PLMD11multicolvar19DistanceFromContour7computeERKjRNS0_13AtomValuePackE3115
_ZNK4PLMD11multicolvar19DistanceFromContour9isDensityEv3115
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DistanceFromContour.cpp.gcov.html b/coverage/multicolvar/DistanceFromContour.cpp.gcov.html new file mode 100644 index 000000000000..d9783e2d6fbb --- /dev/null +++ b/coverage/multicolvar/DistanceFromContour.cpp.gcov.html @@ -0,0 +1,419 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/DistanceFromContour.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DistanceFromContour.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13115286.2 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/KernelFunctions.h"
+      26             : #include "tools/RootFindingBase.h"
+      27             : #include "vesselbase/ValueVessel.h"
+      28             : 
+      29             : //+PLUMEDOC COLVAR DISTANCE_FROM_CONTOUR
+      30             : /*
+      31             : Calculate the perpendicular distance from a Willard-Chandler dividing surface.
+      32             : 
+      33             : Suppose that you have calculated a multicolvar.  By doing so you have calculated a
+      34             : set of colvars, \f$s_i\f$, and each of these colvars has a well defined position in
+      35             : space \f$(x_i,y_i,z_i)\f$.  You can use this information to calculate a phase-field
+      36             : model of the colvar density using:
+      37             : 
+      38             : \f[
+      39             : p(x,y,x) = \sum_{i} s_i K\left[\frac{x-x_i}{\sigma_x},\frac{y-y_i}{\sigma_y},\frac{z-z_i}{\sigma_z} \right]
+      40             : \f]
+      41             : 
+      42             : In this expression \f$\sigma_x, \sigma_y\f$ and \f$\sigma_z\f$ are bandwidth parameters and
+      43             : \f$K\f$ is one of the \ref kernelfunctions.  This is what is done within \ref MULTICOLVARDENS
+      44             : 
+      45             : The Willard-Chandler surface is a surface of constant density in the above phase field \f$p(x,y,z)\f$.
+      46             : In other words, it is a set of points, \f$(x',y',z')\f$, in your box which have:
+      47             : 
+      48             : \f[
+      49             : p(x',y',z') = \rho
+      50             : \f]
+      51             : 
+      52             : where \f$\rho\f$ is some target density.  This action calculates the distance projected on the \f$x, y\f$ or
+      53             : \f$z\f$ axis between the position of some test particle and this surface of constant field density.
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : In this example atoms 2-100 are assumed to be concentrated along some part of the \f$z\f$ axis so that you
+      58             : an interface between a liquid/solid and the vapor.  The quantity dc measures the distance between the
+      59             : surface at which the density of 2-100 atoms is equal to 0.2 and the position of the test particle atom 1.
+      60             : 
+      61             : \plumedfile
+      62             : dens: DENSITY SPECIES=2-100
+      63             : dc: DISTANCE_FROM_CONTOUR DATA=dens ATOM=1 BANDWIDTH=0.5,0.5,0.5 DIR=z CONTOUR=0.2
+      64             : \endplumedfile
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : namespace PLMD {
+      70             : namespace multicolvar {
+      71             : 
+      72             : class DistanceFromContour : public MultiColvarBase {
+      73             : private:
+      74             :   unsigned dir;
+      75             :   bool derivTime;
+      76             :   double rcut2;
+      77             :   double contour;
+      78             :   double pbc_param;
+      79             :   std::string kerneltype;
+      80             :   std::vector<std::unique_ptr<Value>> pval;
+      81             :   std::vector<double> bw, pos1, pos2, dirv, dirv2;
+      82             :   std::vector<double> forces;
+      83             :   std::vector<unsigned> perp_dirs;
+      84             :   vesselbase::ValueVessel* myvalue_vessel;
+      85             :   vesselbase::ValueVessel* myderiv_vessel;
+      86             :   RootFindingBase<DistanceFromContour> mymin;
+      87             : public:
+      88             :   static void registerKeywords( Keywords& keys );
+      89             :   explicit DistanceFromContour( const ActionOptions& );
+      90        3115 :   bool isDensity() const override { return true; }
+      91             :   void calculate() override;
+      92             :   unsigned getNumberOfQuantities() const override;
+      93           0 :   bool isPeriodic() override { return false; }
+      94             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      95             :   double getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der );
+      96             : // We need an apply action as we are using an independent value
+      97             :   void apply() override;
+      98             : };
+      99             : 
+     100             : PLUMED_REGISTER_ACTION(DistanceFromContour,"DISTANCE_FROM_CONTOUR")
+     101             : 
+     102           3 : void DistanceFromContour::registerKeywords( Keywords& keys ) {
+     103           3 :   MultiColvarBase::registerKeywords( keys );
+     104           6 :   keys.addOutputComponent("dist1","default","the distance between the reference atom and the nearest contour");
+     105           6 :   keys.addOutputComponent("dist2","default","the distance between the reference atom and the other contour");
+     106           6 :   keys.addOutputComponent("qdist","default","the differentiable (squared) distance between the two contours (see above)");
+     107           6 :   keys.addOutputComponent("thickness","default","the distance between the two contours on the line from the reference atom");
+     108           6 :   keys.add("compulsory","DATA","The input base multicolvar which is being used to calculate the contour");
+     109           6 :   keys.add("atoms","ATOM","The atom whose perpendicular distance we are calculating from the contour");
+     110           6 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density estimation");
+     111           6 :   keys.add("compulsory","KERNEL","gaussian","the kernel function you are using.  More details on  the kernels available "
+     112             :            "in plumed plumed can be found in \\ref kernelfunctions.");
+     113           6 :   keys.add("compulsory","DIR","the direction perpendicular to the contour that you are looking for");
+     114           6 :   keys.add("compulsory","CONTOUR","the value we would like for the contour");
+     115           6 :   keys.add("compulsory","TOLERANCE","0.1","this parameter is used to manage periodic boundary conditions.  The problem "
+     116             :            "here is that we can be between contours even when we are not within the membrane "
+     117             :            "because of periodic boundary conditions.  When we are in the contour, however, we "
+     118             :            "should have it so that the sums of the absolute values of the distances to the two "
+     119             :            "contours is approximately the distance between the two contours.  There can be numerical errors in these calculations, however, so "
+     120             :            "we specify a small tolerance here");
+     121           3 : }
+     122             : 
+     123           1 : DistanceFromContour::DistanceFromContour( const ActionOptions& ao ):
+     124             :   Action(ao),
+     125             :   MultiColvarBase(ao),
+     126           1 :   derivTime(false),
+     127           1 :   bw(3),
+     128           1 :   pos1(3,0.0),
+     129           1 :   pos2(3,0.0),
+     130           1 :   dirv(3,0.0),
+     131           1 :   dirv2(3,0.0),
+     132           1 :   perp_dirs(2),
+     133           2 :   mymin(this)
+     134             : {
+     135             :   // Read in the multicolvar/atoms
+     136           1 :   std::vector<AtomNumber> all_atoms; parse("TOLERANCE",pbc_param);
+     137           1 :   bool read2 = parseMultiColvarAtomList("DATA", -1, all_atoms);
+     138           1 :   if( !read2 ) error("missing DATA keyword");
+     139           1 :   bool read1 = parseMultiColvarAtomList("ATOM", -1, all_atoms);
+     140           1 :   if( !read1 ) error("missing ATOM keyword");
+     141           1 :   if( all_atoms.size()!=1 ) error("should only be one atom specified");
+     142             :   // Read in the center of the binding object
+     143           1 :   log.printf("  computing distance of atom %d from contour \n",all_atoms[0].serial() );
+     144           1 :   setupMultiColvarBase( all_atoms ); forces.resize( 3*getNumberOfAtoms() + 9 );
+     145           1 :   if( getNumberOfBaseMultiColvars()!=1 ) error("should only be one input multicolvar");
+     146             : 
+     147             :   // Get the direction
+     148           2 :   std::string ldir; parse("DIR",ldir );
+     149           1 :   if( ldir=="x" ) { dir=0; perp_dirs[0]=1; perp_dirs[1]=2; dirv[0]=1; dirv2[0]=-1; }
+     150           1 :   else if( ldir=="y" ) { dir=1; perp_dirs[0]=0; perp_dirs[1]=2; dirv[1]=1; dirv2[1]=-1; }
+     151           1 :   else if( ldir=="z" ) { dir=2; perp_dirs[0]=0; perp_dirs[1]=1; dirv[2]=1; dirv2[2]=-1; }
+     152           0 :   else error(ldir + " is not a valid direction use x, y or z");
+     153             : 
+     154             :   // Read in details of phase field construction
+     155           3 :   parseVector("BANDWIDTH",bw); parse("KERNEL",kerneltype); parse("CONTOUR",contour);
+     156           1 :   log.printf("  searching for contour in %s direction at %f in phase field for multicolvar %s \n",ldir.c_str(), contour, mybasemulticolvars[0]->getLabel().c_str() );
+     157           1 :   log.printf("  constructing phase field using %s kernels with bandwidth (%f, %f, %f) \n",kerneltype.c_str(), bw[0], bw[1], bw[2] );
+     158             : 
+     159             :   // Now create a task list
+     160           2 :   for(unsigned i=0; i<mybasemulticolvars[0]->getFullNumberOfTasks(); ++i) addTaskToList(i);
+     161             :   // And a cutoff
+     162           1 :   std::vector<double> pp( bw.size(),0 );
+     163           2 :   KernelFunctions kernel( pp, bw, kerneltype, "DIAGONAL", 1.0 );
+     164           1 :   double rcut = kernel.getCutoff( bw[0] );
+     165           3 :   for(unsigned j=1; j<bw.size(); ++j) {
+     166           2 :     if( kernel.getCutoff(bw[j])>rcut ) rcut=kernel.getCutoff(bw[j]);
+     167             :   }
+     168           1 :   rcut2=rcut*rcut;
+     169             :   // Create the values
+     170           3 :   addComponent("thickness"); componentIsNotPeriodic("thickness");
+     171           3 :   addComponent("dist1"); componentIsNotPeriodic("dist1");
+     172           3 :   addComponent("dist2"); componentIsNotPeriodic("dist2");
+     173           3 :   addComponentWithDerivatives("qdist"); componentIsNotPeriodic("qdist");
+     174             :   // Create sum vessels
+     175           1 :   std::string fake_input; std::string deriv_input="COMPONENT=2";
+     176           1 :   if( mybasemulticolvars[0]->isDensity() ) {
+     177           3 :     addVessel( "SUM", fake_input, -1 ); addVessel( "SUM", deriv_input, -1 );
+     178             :   } else {
+     179           0 :     addVessel( "MEAN", fake_input, -1 ); addVessel( "MEAN", deriv_input, -1 );
+     180             :   }
+     181             :   // And convert to a value vessel so we can get the final value
+     182           1 :   myvalue_vessel = dynamic_cast<vesselbase::ValueVessel*>( getPntrToVessel(0) );
+     183           1 :   myderiv_vessel = dynamic_cast<vesselbase::ValueVessel*>( getPntrToVessel(1) );
+     184           1 :   plumed_assert( myvalue_vessel && myderiv_vessel ); resizeFunctions();
+     185             : 
+     186             :   // Create the vector of values that holds the position
+     187           4 :   for(unsigned i=0; i<3; ++i) pval.emplace_back( Tools::make_unique<Value>() );
+     188           1 : }
+     189             : 
+     190        6230 : unsigned DistanceFromContour::getNumberOfQuantities() const {
+     191        6230 :   return 3;
+     192             : }
+     193             : 
+     194         137 : void DistanceFromContour::calculate() {
+     195             :   // Check box is orthorhombic
+     196         137 :   if( !getPbc().isOrthorombic() ) error("cell box must be orthorhombic");
+     197             : 
+     198             :   // The nanoparticle is at the origin of our coordinate system
+     199         137 :   pos1[0]=pos1[1]=pos1[2]=0.0; pos2[0]=pos2[1]=pos2[2]=0.0;
+     200             : 
+     201             :   // Set bracket as center of mass of membrane in active region
+     202         137 :   deactivateAllTasks();
+     203         137 :   Vector myvec = getSeparation( getPosition(getNumberOfAtoms()-1), getPosition(0) ); pos2[dir]=myvec[dir];
+     204         137 :   taskFlags[0]=1; double mindist = myvec.modulo2();
+     205         137 :   for(unsigned j=1; j<getNumberOfAtoms()-1; ++j) {
+     206           0 :     Vector distance=getSeparation( getPosition(getNumberOfAtoms()-1), getPosition(j) );
+     207             :     double d2;
+     208           0 :     if( (d2=distance[perp_dirs[0]]*distance[perp_dirs[0]])<rcut2 &&
+     209           0 :         (d2+=distance[perp_dirs[1]]*distance[perp_dirs[1]])<rcut2 ) {
+     210           0 :       d2+=distance[dir]*distance[dir];
+     211           0 :       if( d2<mindist && std::fabs(distance[dir])>epsilon ) { pos2[dir]=distance[dir]; mindist = d2; }
+     212           0 :       taskFlags[j]=1;
+     213             :     }
+     214             :   }
+     215         137 :   lockContributors(); derivTime=false;
+     216             :   // pos1 position of the nanoparticle, in the first time
+     217             :   // pos2 is the position of the closer atom in the membrane with respect the nanoparticle
+     218             :   // fa = distance between pos1 and the contour
+     219             :   // fb = distance between pos2 and the contour
+     220         137 :   std::vector<double> faked(3);
+     221         137 :   double fa = getDifferenceFromContour( pos1, faked );
+     222         137 :   double fb = getDifferenceFromContour( pos2, faked );
+     223         137 :   if( fa*fb>0 ) {
+     224           0 :     unsigned maxtries = std::floor( ( getBox()(dir,dir) ) / bw[dir] );
+     225           0 :     for(unsigned i=0; i<maxtries; ++i) {
+     226           0 :       double sign=(pos2[dir]>0)? -1 : +1; // If the nanoparticle is inside the membrane push it out
+     227           0 :       pos1[dir] += sign*bw[dir]; fa = getDifferenceFromContour( pos1, faked );
+     228           0 :       if( fa*fb<0 ) break;
+     229             :       // if fa*fb is less than zero the new pos 1 is outside the contour
+     230             :     }
+     231             :   }
+     232             :   // Set direction for contour search
+     233         137 :   dirv[dir] = pos2[dir] - pos1[dir];
+     234             :   // Bracket for second root starts in center of membrane
+     235         137 :   double fc = getDifferenceFromContour( pos2, faked );
+     236         137 :   if( fc*fb>0 ) {
+     237             :     // first time is true, because fc=fb
+     238             :     // push pos2 from its initial position inside the membrane towards the second contourn
+     239         137 :     unsigned maxtries = std::floor( ( getBox()(dir,dir) ) / bw[dir] );
+     240         230 :     for(unsigned i=0; i<maxtries; ++i) {
+     241         230 :       double sign=(dirv[dir]>0)? +1 : -1;
+     242         230 :       pos2[dir] += sign*bw[dir]; fc = getDifferenceFromContour( pos2, faked );
+     243         230 :       if( fc*fb<0 ) break;
+     244             :     }
+     245         137 :     dirv2[dir] = ( pos1[dir] + dirv[dir] ) - pos2[dir];
+     246             :   }
+     247             : 
+     248             :   // Now do a search for the two contours
+     249         137 :   mymin.lsearch( dirv, pos1, &DistanceFromContour::getDifferenceFromContour );
+     250             :   // Save the first value
+     251         137 :   Vector root1; root1.zero(); root1[dir] = pval[dir]->get();
+     252         137 :   mymin.lsearch( dirv2, pos2, &DistanceFromContour::getDifferenceFromContour );
+     253             :   // Calculate the separation between the two roots using PBC
+     254         137 :   Vector root2; root2.zero(); root2[dir]=pval[dir]->get();
+     255         137 :   Vector sep = getSeparation( root1, root2 ); double spacing = std::fabs( sep[dir] ); plumed_assert( spacing>epsilon );
+     256         137 :   getPntrToComponent("thickness")->set( spacing );
+     257             : 
+     258             :   // Make sure the sign is right
+     259         137 :   double predir=(root1[dir]*root2[dir]<0)? -1 : 1;
+     260             :   // This deals with periodic boundary conditions - if we are inside the membrane the sum of the absolute
+     261             :   // distances from the contours should add up to the spacing.  When this is not the case we must be outside
+     262             :   // the contour
+     263             :   // if( predir==-1 && (std::fabs(root1[dir])+std::fabs(root2[dir]))>(spacing+pbc_param) ) predir=1;
+     264             :   // Set the final value to root that is closest to the "origin" = position of atom
+     265         137 :   if( std::fabs(root1[dir])<std::fabs(root2[dir]) ) {
+     266         137 :     getPntrToComponent("dist1")->set( predir*std::fabs(root1[dir]) );
+     267         274 :     getPntrToComponent("dist2")->set( std::fabs(root2[dir]) );
+     268             :   } else {
+     269           0 :     getPntrToComponent("dist1")->set( predir*std::fabs(root2[dir]) );
+     270           0 :     getPntrToComponent("dist2")->set( std::fabs(root1[dir]) );
+     271             :   }
+     272         137 :   getPntrToComponent("qdist")->set( root2[dir]*root1[dir] );
+     273             : 
+     274             :   // Now calculate the derivatives
+     275         137 :   if( !doNotCalculateDerivatives() ) {
+     276         137 :     Value* ival=myvalue_vessel->getFinalValue(); ival->clearDerivatives();
+     277         548 :     std::vector<double> root1v(3); for(unsigned i=0; i<3; ++i) root1v[i]=root1[i];
+     278         137 :     derivTime=true; std::vector<double> der(3); getDifferenceFromContour( root1v, der ); double prefactor;
+     279         137 :     if( mybasemulticolvars[0]->isDensity() ) prefactor = root2[dir] / myderiv_vessel->getOutputValue();
+     280           0 :     else plumed_error();
+     281         137 :     Value* val=getPntrToComponent("qdist");
+     282        2192 :     for(unsigned i=0; i<val->getNumberOfDerivatives(); ++i) val->setDerivative( i, -prefactor*ival->getDerivative(i) );
+     283         137 :     ival->clearDerivatives();
+     284         548 :     std::vector<double> root2v(3); for(unsigned i=0; i<3; ++i) root2v[i]=root2[i];
+     285         137 :     getDifferenceFromContour( root2v, der );
+     286         137 :     if( mybasemulticolvars[0]->isDensity() ) prefactor = root1[dir] / myderiv_vessel->getOutputValue();
+     287           0 :     else plumed_error();
+     288        2192 :     for(unsigned i=0; i<val->getNumberOfDerivatives(); ++i) val->addDerivative( i, -prefactor*ival->getDerivative(i) );
+     289             :   }
+     290         137 : }
+     291             : 
+     292        3115 : double DistanceFromContour::getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) {
+     293             :   std::string min, max;
+     294       12460 :   for(unsigned j=0; j<3; ++j) {
+     295        9345 :     Tools::convert( -0.5*getBox()(j,j), min );
+     296        9345 :     Tools::convert( +0.5*getBox()(j,j), max );
+     297        9345 :     pval[j]->setDomain( min, max ); pval[j]->set( x[j] );
+     298             :   }
+     299        3115 :   runAllTasks();
+     300        6230 :   return myvalue_vessel->getOutputValue() - contour;
+     301             : }
+     302             : 
+     303        3115 : double DistanceFromContour::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     304        3115 :   Vector distance = getSeparation( getPosition(getNumberOfAtoms()-1), myatoms.getPosition(0) );
+     305       12460 :   std::vector<double> pp(3), der(3,0); for(unsigned j=0; j<3; ++j) pp[j] = distance[j];
+     306             : 
+     307             :   // convert the pointer once
+     308        3115 :   auto pval_ptr=Tools::unique2raw(pval);
+     309             : 
+     310             :   // Now create the kernel and evaluate
+     311        3115 :   KernelFunctions kernel( pp, bw, kerneltype, "DIAGONAL", 1.0 );
+     312        3115 :   kernel.normalize( pval_ptr ); double newval = kernel.evaluate( pval_ptr, der, true );
+     313             : 
+     314        3115 :   if( mybasemulticolvars[0]->isDensity() ) {
+     315        3115 :     if( !doNotCalculateDerivatives() && derivTime ) {
+     316             :       MultiValue& myvals=myatoms.getUnderlyingMultiValue();
+     317         274 :       Vector vder; unsigned basen=myvals.getNumberOfDerivatives() - 12;
+     318        1096 :       for(unsigned i=0; i<3; ++i) {
+     319         822 :         vder[i]=der[i]; myvals.addDerivative( 1, basen+i, vder[i] );
+     320             :       }
+     321         274 :       myatoms.setValue( 2, der[dir] );
+     322         274 :       addAtomDerivatives( 1, 0, -vder, myatoms );
+     323         274 :       myatoms.addBoxDerivatives( 1, Tensor(vder,distance) );
+     324             :     }
+     325        3115 :     myatoms.setValue( 0, 1.0 ); return newval;
+     326             :   }
+     327             : 
+     328             :   // This does the stuff for averaging
+     329             :   myatoms.setValue( 0, newval );
+     330             : 
+     331             :   // This gets the average if we are using a phase field
+     332           0 :   std::vector<double> cvals( mybasemulticolvars[0]->getNumberOfQuantities() );
+     333           0 :   mybasedata[0]->retrieveValueWithIndex( tindex, false, cvals );
+     334           0 :   return newval*cvals[0]*cvals[1];
+     335             : }
+     336             : 
+     337         137 : void DistanceFromContour::apply() {
+     338         274 :   unsigned ind=0; if( getPntrToComponent("qdist")->applyForce( forces ) ) setForcesOnAtoms( forces, ind );
+     339         137 : }
+     340             : 
+     341             : }
+     342             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Distances.cpp.func-sort-c.html b/coverage/multicolvar/Distances.cpp.func-sort-c.html new file mode 100644 index 000000000000..666ecf3d2302 --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Distances.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Distances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424495.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9DistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar9DistancesC1ERKNS_13ActionOptionsE51
_ZN4PLMD11multicolvar9Distances16registerKeywordsERNS_8KeywordsE53
_ZN4PLMD11multicolvar9Distances10isPeriodicEv111
_ZNK4PLMD11multicolvar9Distances7computeERKjRNS0_13AtomValuePackE15275
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Distances.cpp.func.html b/coverage/multicolvar/Distances.cpp.func.html new file mode 100644 index 000000000000..c6d9ec5e7734 --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Distances.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Distances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424495.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9Distances10isPeriodicEv111
_ZN4PLMD11multicolvar9Distances16registerKeywordsERNS_8KeywordsE53
_ZN4PLMD11multicolvar9DistancesC1ERKNS_13ActionOptionsE51
_ZN4PLMD11multicolvar9DistancesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar9Distances7computeERKjRNS0_13AtomValuePackE15275
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Distances.cpp.gcov.html b/coverage/multicolvar/Distances.cpp.gcov.html new file mode 100644 index 000000000000..4e5a891daab6 --- /dev/null +++ b/coverage/multicolvar/Distances.cpp.gcov.html @@ -0,0 +1,288 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Distances.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Distances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:424495.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "vesselbase/LessThan.h"
+      26             : #include "vesselbase/Between.h"
+      27             : 
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace multicolvar {
+      33             : 
+      34             : //+PLUMEDOC MCOLVAR DISTANCES
+      35             : /*
+      36             : Calculate the distances between one or many pairs of atoms.  You can then calculate functions of the distribution of
+      37             :  distances such as the minimum, the number less than a certain quantity and so on.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : The following input tells plumed to calculate the distances between atoms 3 and 5 and between atoms 1 and 2 and to
+      42             : print the minimum for these two distances.
+      43             : \plumedfile
+      44             : d1: DISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
+      45             : PRINT ARG=d1.min
+      46             : \endplumedfile
+      47             : (See also \ref PRINT).
+      48             : 
+      49             : The following input tells plumed to calculate the distances between atoms 3 and 5 and between atoms 1 and 2
+      50             : and then to calculate the number of these distances that are less than 0.1 nm.  The number of distances
+      51             : less than 0.1nm is then printed to a file.
+      52             : \plumedfile
+      53             : d1: DISTANCES ATOMS1=3,5 ATOMS2=1,2 LESS_THAN={RATIONAL R_0=0.1}
+      54             : PRINT ARG=d1.lessthan
+      55             : \endplumedfile
+      56             : (See also \ref PRINT \ref switchingfunction).
+      57             : 
+      58             : The following input tells plumed to calculate all the distances between atoms 1, 2 and 3 (i.e. the distances between atoms
+      59             : 1 and 2, atoms 1 and 3 and atoms 2 and 3).  The average of these distances is then calculated.
+      60             : \plumedfile
+      61             : d1: DISTANCES GROUP=1-3 MEAN
+      62             : PRINT ARG=d1.mean
+      63             : \endplumedfile
+      64             : (See also \ref PRINT)
+      65             : 
+      66             : The following input tells plumed to calculate all the distances between the atoms in GROUPA and the atoms in GROUPB.
+      67             : In other words the distances between atoms 1 and 2 and the distance between atoms 1 and 3.  The number of distances
+      68             : more than 0.1 is then printed to a file.
+      69             : \plumedfile
+      70             : d1: DISTANCES GROUPA=1 GROUPB=2,3 MORE_THAN={RATIONAL R_0=0.1}
+      71             : PRINT ARG=d1.morethan
+      72             : \endplumedfile
+      73             : (See also \ref PRINT \ref switchingfunction)
+      74             : 
+      75             : 
+      76             : \par Calculating minimum distances
+      77             : 
+      78             : To calculate and print the minimum distance between two groups of atoms you use the following commands
+      79             : 
+      80             : \plumedfile
+      81             : d1: DISTANCES GROUPA=1-10 GROUPB=11-20 MIN={BETA=500.}
+      82             : PRINT ARG=d1.min FILE=colvar STRIDE=10
+      83             : \endplumedfile
+      84             : (see \ref DISTANCES and \ref PRINT)
+      85             : 
+      86             : In order to ensure that the minimum value has continuous derivatives we use the following function:
+      87             : 
+      88             : \f[
+      89             : s = \frac{\beta}{ \log \sum_i \exp\left( \frac{\beta}{s_i} \right) }
+      90             : \f]
+      91             : 
+      92             : where \f$\beta\f$ is a user specified parameter.
+      93             : 
+      94             : This input is used rather than a separate MINDIST colvar so that the same routine and the same input style can be
+      95             : used to calculate minimum coordination numbers (see \ref COORDINATIONNUMBER), minimum
+      96             : angles (see \ref ANGLES) and many other variables.
+      97             : 
+      98             : This new way of calculating mindist is part of plumed 2's multicolvar functionality.  These special actions
+      99             : allow you to calculate multiple functions of a distribution of simple collective variables.  As an example you
+     100             : can calculate the number of distances less than 1.0, the minimum distance, the number of distances more than
+     101             : 2.0 and the number of distances between 1.0 and 2.0 by using the following command:
+     102             : 
+     103             : \plumedfile
+     104             : d1: DISTANCES ...
+     105             :  GROUPA=1-10 GROUPB=11-20
+     106             :  LESS_THAN={RATIONAL R_0=1.0}
+     107             :  MORE_THAN={RATIONAL R_0=2.0}
+     108             :  BETWEEN={GAUSSIAN LOWER=1.0 UPPER=2.0}
+     109             :  MIN={BETA=500.}
+     110             : ...
+     111             : PRINT ARG=d1.lessthan,d1.morethan,d1.between,d1.min FILE=colvar STRIDE=10
+     112             : \endplumedfile
+     113             : (see \ref DISTANCES and \ref PRINT)
+     114             : 
+     115             : A calculation performed this way is fast because the expensive part of the calculation - the calculation of all the distances - is only
+     116             : done once per step.  Furthermore, it can be made faster by using the TOL keyword to discard those distance that make only a small contributions
+     117             : to the final values together with the NL_STRIDE keyword, which ensures that the distances that make only a small contribution to the final values aren't
+     118             : calculated at every step.
+     119             : 
+     120             : */
+     121             : //+ENDPLUMEDOC
+     122             : 
+     123             : 
+     124             : class Distances : public MultiColvarBase {
+     125             : private:
+     126             : public:
+     127             :   static void registerKeywords( Keywords& keys );
+     128             :   explicit Distances(const ActionOptions&);
+     129             : // active methods:
+     130             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+     131             : /// Returns the number of coordinates of the field
+     132         111 :   bool isPeriodic() override { return false; }
+     133             : };
+     134             : 
+     135             : PLUMED_REGISTER_ACTION(Distances,"DISTANCES")
+     136             : 
+     137          53 : void Distances::registerKeywords( Keywords& keys ) {
+     138          53 :   MultiColvarBase::registerKeywords( keys );
+     139         159 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     140         212 :   keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN"); // keys.use("DHENERGY");
+     141         212 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     142         106 :   keys.add("numbered","ATOMS","the atoms involved in each of the distances you wish to calculate. "
+     143             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one distance will be "
+     144             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     145             :            "specify the indices of two atoms).  The eventual number of quantities calculated by this "
+     146             :            "action will depend on what functions of the distribution you choose to calculate.");
+     147         106 :   keys.reset_style("ATOMS","atoms");
+     148         106 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     149         106 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+     150             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+     151         106 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+     152             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+     153          53 : }
+     154             : 
+     155          51 : Distances::Distances(const ActionOptions&ao):
+     156             :   Action(ao),
+     157          51 :   MultiColvarBase(ao)
+     158             : {
+     159             :   // Read in the atoms
+     160             :   std::vector<AtomNumber> all_atoms;
+     161         102 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     162          86 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+     163          51 :   setupMultiColvarBase( all_atoms );
+     164             :   // And check everything has been read in correctly
+     165          51 :   checkRead();
+     166             : 
+     167             :   // Now check if we can use link cells
+     168          51 :   if( getNumberOfVessels()>0 ) {
+     169             :     bool use_link=false; double rcut;
+     170          49 :     vesselbase::LessThan* lt=dynamic_cast<vesselbase::LessThan*>( getPntrToVessel(0) );
+     171          49 :     if( lt ) {
+     172          16 :       use_link=true; rcut=lt->getCutoff();
+     173             :     } else {
+     174          33 :       vesselbase::Between* bt=dynamic_cast<vesselbase::Between*>( getPntrToVessel(0) );
+     175          33 :       if( bt ) { use_link=true; rcut=bt->getCutoff(); }
+     176             :     }
+     177             :     if( use_link ) {
+     178          76 :       for(unsigned i=1; i<getNumberOfVessels(); ++i) {
+     179          30 :         vesselbase::LessThan* lt2=dynamic_cast<vesselbase::LessThan*>( getPntrToVessel(i) );
+     180          30 :         vesselbase::Between* bt=dynamic_cast<vesselbase::Between*>( getPntrToVessel(i) );
+     181          30 :         if( lt2 ) {
+     182           0 :           double tcut=lt2->getCutoff();
+     183           0 :           if( tcut>rcut ) rcut=tcut;
+     184          30 :         } else if( bt ) {
+     185          30 :           double tcut=bt->getCutoff();
+     186          30 :           if( tcut>rcut ) rcut=tcut;
+     187             :         } else {
+     188             :           use_link=false;
+     189             :         }
+     190             :       }
+     191             :     }
+     192          49 :     if( use_link ) setLinkCellCutoff( rcut );
+     193             :   }
+     194          51 : }
+     195             : 
+     196       15275 : double Distances::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     197       15275 :   Vector distance;
+     198       15275 :   distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     199       15275 :   const double value=distance.modulo();
+     200       15275 :   const double invvalue=1.0/value;
+     201             : 
+     202             :   // And finish the calculation
+     203       15275 :   addAtomDerivatives( 1, 0,-invvalue*distance, myatoms );
+     204       15275 :   addAtomDerivatives( 1, 1, invvalue*distance, myatoms );
+     205       15275 :   myatoms.addBoxDerivatives( 1, -invvalue*Tensor(distance,distance) );
+     206       15275 :   return value;
+     207             : }
+     208             : 
+     209             : }
+     210             : }
+     211             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html b/coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html new file mode 100644 index 000000000000..d14ee4fc2bb0 --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/DumpMultiColvar.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DumpMultiColvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:667193.0 %
Date:2024-02-22 21:58:45Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15DumpMultiColvar29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD11multicolvar15DumpMultiColvarC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15DumpMultiColvarD2Ev0
_ZN4PLMD11multicolvar15DumpMultiColvarC1ERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar15DumpMultiColvarD0Ev22
_ZN4PLMD11multicolvar15DumpMultiColvarD1Ev22
_ZN4PLMD11multicolvar15DumpMultiColvar16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD11multicolvar15DumpMultiColvar5applyEv74
_ZN4PLMD11multicolvar15DumpMultiColvar6updateEv74
_ZN4PLMD11multicolvar15DumpMultiColvar9calculateEv74
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DumpMultiColvar.cpp.func.html b/coverage/multicolvar/DumpMultiColvar.cpp.func.html new file mode 100644 index 000000000000..1adfd86a0f2d --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/DumpMultiColvar.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DumpMultiColvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:667193.0 %
Date:2024-02-22 21:58:45Functions:71070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15DumpMultiColvar16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD11multicolvar15DumpMultiColvar29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD11multicolvar15DumpMultiColvar5applyEv74
_ZN4PLMD11multicolvar15DumpMultiColvar6updateEv74
_ZN4PLMD11multicolvar15DumpMultiColvar9calculateEv74
_ZN4PLMD11multicolvar15DumpMultiColvarC1ERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar15DumpMultiColvarC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15DumpMultiColvarD0Ev22
_ZN4PLMD11multicolvar15DumpMultiColvarD1Ev22
_ZN4PLMD11multicolvar15DumpMultiColvarD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html b/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html new file mode 100644 index 000000000000..af9b4cbd2356 --- /dev/null +++ b/coverage/multicolvar/DumpMultiColvar.cpp.gcov.html @@ -0,0 +1,258 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/DumpMultiColvar.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - DumpMultiColvar.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:667193.0 %
Date:2024-02-22 21:58:45Functions:71070.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionAtomistic.h"
+      23             : #include "core/ActionPilot.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Pbc.h"
+      26             : #include "tools/File.h"
+      27             : #include "tools/Units.h"
+      28             : #include <cstdio>
+      29             : #include "core/GenericMolInfo.h"
+      30             : #include "core/ActionSet.h"
+      31             : #include "MultiColvarBase.h"
+      32             : #include "vesselbase/ActionWithInputVessel.h"
+      33             : #include "vesselbase/StoreDataVessel.h"
+      34             : 
+      35             : namespace PLMD
+      36             : {
+      37             : namespace multicolvar {
+      38             : 
+      39             : //+PLUMEDOC PRINTANALYSIS DUMPMULTICOLVAR
+      40             : /*
+      41             : Dump atom positions and multicolvar on a file.
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : In this examples we calculate the distances between the  atoms of the first and the second
+      46             : group and we write them in the file MULTICOLVAR.xyz. For each couple it writes the
+      47             : coordinates of their geometric center and their distance.
+      48             : 
+      49             : \plumedfile
+      50             : pos:   GROUP ATOMS=220,221,235,236,247,248,438,439,450,451,534,535
+      51             : neg:   GROUP ATOMS=65,68,138,182,185,267,270,291,313,316,489,583,621,711
+      52             : DISTANCES GROUPA=pos GROUPB=neg LABEL=slt
+      53             : 
+      54             : DUMPMULTICOLVAR DATA=slt FILE=MULTICOLVAR.xyz
+      55             : \endplumedfile
+      56             : 
+      57             : (see also \ref DISTANCES)
+      58             : 
+      59             : */
+      60             : //+ENDPLUMEDOC
+      61             : 
+      62             : class DumpMultiColvar:
+      63             :   public ActionPilot,
+      64             :   public ActionAtomistic,
+      65             :   public vesselbase::ActionWithInputVessel
+      66             : {
+      67             :   OFile of;
+      68             :   double lenunit;
+      69             :   MultiColvarBase* mycolv;
+      70             :   std::string fmt_xyz;
+      71             : public:
+      72             :   explicit DumpMultiColvar(const ActionOptions&);
+      73             :   ~DumpMultiColvar();
+      74             :   static void registerKeywords( Keywords& keys );
+      75          74 :   void calculate() override {}
+      76           0 :   void calculateNumericalDerivatives( ActionWithValue* vv ) override { plumed_error(); }
+      77          74 :   void apply() override {}
+      78             :   void update() override;
+      79             : };
+      80             : 
+      81             : PLUMED_REGISTER_ACTION(DumpMultiColvar,"DUMPMULTICOLVAR")
+      82             : 
+      83          24 : void DumpMultiColvar::registerKeywords( Keywords& keys ) {
+      84          24 :   Action::registerKeywords( keys );
+      85          24 :   ActionAtomistic::registerKeywords( keys );
+      86          24 :   ActionPilot::registerKeywords( keys );
+      87          24 :   ActionWithInputVessel::registerKeywords( keys );
+      88          48 :   keys.add("compulsory","STRIDE","1","the frequency with which the atoms should be output");
+      89          48 :   keys.add("compulsory", "FILE", "file on which to output coordinates");
+      90          48 :   keys.add("compulsory", "UNITS","PLUMED","the units in which to print out the coordinates. PLUMED means internal PLUMED units");
+      91          48 :   keys.add("optional","PRECISION","The number of digits in trajectory file");
+      92          48 :   keys.add("atoms","ORIGIN","You can use this keyword to specify the position of an atom as an origin. The positions output will then be displayed relative to that origin");
+      93          24 : }
+      94             : 
+      95          22 : DumpMultiColvar::DumpMultiColvar(const ActionOptions&ao):
+      96             :   Action(ao),
+      97             :   ActionPilot(ao),
+      98             :   ActionAtomistic(ao),
+      99          22 :   ActionWithInputVessel(ao)
+     100             : {
+     101          44 :   readArgument("store");
+     102          22 :   mycolv = dynamic_cast<MultiColvarBase*>( getDependencies()[0] );
+     103          22 :   plumed_assert( getDependencies().size()==1 );
+     104          22 :   if(!mycolv) error("action labeled " + getDependencies()[0]->getLabel() + " is not a multicolvar");
+     105          22 :   log.printf("  printing colvars calculated by action %s \n",mycolv->getLabel().c_str() );
+     106             : 
+     107             :   std::vector<AtomNumber> atom;
+     108          44 :   parseAtomList("ORIGIN",atom);
+     109          22 :   if( atom.size()>1 ) error("should only be one atom specified");
+     110          22 :   if( atom.size()==1 ) log.printf("  origin is at position of atom : %d\n",atom[0].serial() );
+     111             : 
+     112          44 :   std::string file; parse("FILE",file);
+     113          22 :   if(file.length()==0) error("name out output file was not specified");
+     114          22 :   std::string type=Tools::extension(file);
+     115          22 :   log<<"  file name "<<file<<"\n";
+     116          22 :   if(type!="xyz") error("can only print xyz file type with DUMPMULTICOLVAR");
+     117             : 
+     118             :   fmt_xyz="%f";
+     119             : 
+     120          44 :   std::string precision; parse("PRECISION",precision);
+     121          22 :   if(precision.length()>0) {
+     122          11 :     int p; Tools::convert(precision,p);
+     123          11 :     log<<"  with precision "<<p<<"\n";
+     124             :     std::string a,b;
+     125          11 :     Tools::convert(p+5,a);
+     126          11 :     Tools::convert(p,b);
+     127          22 :     fmt_xyz="%"+a+"."+b+"f";
+     128             :   }
+     129             : 
+     130          44 :   std::string unitname; parse("UNITS",unitname);
+     131          22 :   if(unitname!="PLUMED") {
+     132           1 :     Units myunit; myunit.setLength(unitname);
+     133           1 :     lenunit=getUnits().getLength()/myunit.getLength();
+     134           1 :   }
+     135          21 :   else lenunit=1.0;
+     136             : 
+     137          22 :   checkRead();
+     138          22 :   of.link(*this);
+     139          22 :   of.open(file);
+     140          22 :   log.printf("  printing atom positions in %s units \n", unitname.c_str() );
+     141          22 :   requestAtoms(atom); addDependency( mycolv );
+     142          22 : }
+     143             : 
+     144          74 : void DumpMultiColvar::update() {
+     145          74 :   of.printf("%u\n",mycolv->getCurrentNumberOfActiveTasks());
+     146          74 :   const Tensor & t(mycolv->getPbc().getBox());
+     147          74 :   if(mycolv->getPbc().isOrthorombic()) {
+     148         148 :     of.printf((" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
+     149             :   } else {
+     150           0 :     of.printf((" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz+"\n").c_str(),
+     151           0 :               lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     152           0 :               lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     153           0 :               lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     154             :              );
+     155             :   }
+     156          74 :   vesselbase::StoreDataVessel* stash=dynamic_cast<vesselbase::StoreDataVessel*>( getPntrToArgument() );
+     157             :   plumed_dbg_assert( stash );
+     158          74 :   std::vector<double> cvals( mycolv->getNumberOfQuantities() );
+     159       13974 :   for(unsigned i=0; i<mycolv->getCurrentNumberOfActiveTasks(); ++i) {
+     160             :     const char* defname="X";
+     161             :     const char* name=defname;
+     162             : 
+     163       13900 :     Vector apos = mycolv->getCentralAtomPos( mycolv->getPositionInFullTaskList(i) );
+     164       25058 :     if( getNumberOfAtoms()>0 ) apos=pbcDistance( getPosition(0), apos );
+     165       27800 :     of.printf(("%s "+fmt_xyz+" "+fmt_xyz+" "+fmt_xyz).c_str(),name,lenunit*apos[0],lenunit*apos[1],lenunit*apos[2]);
+     166       13900 :     stash->retrieveSequentialValue( i, true, cvals );
+     167       13900 :     if( mycolv->weightWithDerivatives() ) {
+     168        2370 :       for(unsigned j=0; j<cvals.size(); ++j) of.printf((" "+fmt_xyz).c_str(),cvals[j]);
+     169             :     } else {
+     170       27884 :       for(unsigned j=1; j<cvals.size(); ++j) of.printf((" "+fmt_xyz).c_str(),cvals[j]);
+     171             :     }
+     172       13900 :     of.printf("\n");
+     173             :   }
+     174          74 : }
+     175             : 
+     176          44 : DumpMultiColvar::~DumpMultiColvar() {
+     177          44 : }
+     178             : 
+     179             : 
+     180             : }
+     181             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterBetween.cpp.func-sort-c.html b/coverage/multicolvar/FilterBetween.cpp.func-sort-c.html new file mode 100644 index 000000000000..6766d528fd2d --- /dev/null +++ b/coverage/multicolvar/FilterBetween.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/FilterBetween.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - FilterBetween.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222781.5 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13FilterBetweenC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar13FilterBetweenC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar13FilterBetween16registerKeywordsERNS_8KeywordsE7
_ZNK4PLMD11multicolvar13FilterBetween11applyFilterERKdRd735
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterBetween.cpp.func.html b/coverage/multicolvar/FilterBetween.cpp.func.html new file mode 100644 index 000000000000..927d42793c15 --- /dev/null +++ b/coverage/multicolvar/FilterBetween.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/FilterBetween.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - FilterBetween.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222781.5 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13FilterBetween16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD11multicolvar13FilterBetweenC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar13FilterBetweenC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar13FilterBetween11applyFilterERKdRd735
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterBetween.cpp.gcov.html b/coverage/multicolvar/FilterBetween.cpp.gcov.html new file mode 100644 index 000000000000..aa7ef6bff748 --- /dev/null +++ b/coverage/multicolvar/FilterBetween.cpp.gcov.html @@ -0,0 +1,272 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/FilterBetween.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - FilterBetween.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:222781.5 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/HistogramBead.h"
+      24             : #include "MultiColvarFilter.h"
+      25             : 
+      26             : //+PLUMEDOC MTRANSFORMS MTRANSFORM_BETWEEN
+      27             : /*
+      28             : This action can be used to transform the colvar values calculated by a MultiColvar using a histogram bead
+      29             : 
+      30             : In this action each colvar, \f$s_i\f$, calculated by MultiColvar is transformed by a \ref histogrambead function that
+      31             : is equal to one if the colvar is within a certain range and which is equal to zero otherwise.  In other words, we
+      32             : compute:
+      33             : 
+      34             : \f[
+      35             : f_i = \int_a^b K\left( \frac{s-s_i}{w} \right)
+      36             : \f]
+      37             : 
+      38             : where \f$a, b\f$ and \f$w\f$ are parameters.
+      39             : 
+      40             : It is important to understand the distinction between what is done here and what is done by \ref MFILTER_BETWEEN.
+      41             : In \ref MFILTER_BETWEEN a weight, \f$w_i\f$ for the colvar is calculated using the \ref histogrambead.  If one calculates the
+      42             : MEAN for \ref MFILTER_BETWEEN one is thus calculating:
+      43             : 
+      44             : \f[
+      45             : \mu = \frac{ \sum_i f_i s_i }{ \sum_i f_i}
+      46             : \f]
+      47             : 
+      48             : In this action by contrast the colvar is being transformed by the \ref histogrambead.  If one thus calculates a MEAN for
+      49             : this action one computes:
+      50             : 
+      51             : \f[
+      52             : \mu = \frac{ \sum_{i=1}^N f_i }{ N }
+      53             : \f]
+      54             : 
+      55             : In other words, you are calculating the mean for the transformed colvar.
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : The following input gives an example of how a \ref MTRANSFORM_BETWEEN action can be used to duplicate
+      60             : functionality that is elsewhere in PLUMED.
+      61             : 
+      62             : \plumedfile
+      63             : DISTANCES ...
+      64             :  GROUPA=1-10 GROUPB=11-20
+      65             :  LABEL=d1
+      66             : ... DISTANCES
+      67             : MTRANSFORM_BETWEEN DATA=d1 LOWER=1.0 UPPER=2.0 SMEAR=0.5
+      68             : \endplumedfile
+      69             : 
+      70             : In this case you can achieve the same result by using:
+      71             : 
+      72             : \plumedfile
+      73             : DISTANCES ...
+      74             :  GROUPA=1-10 GROUPB=11-20
+      75             :  BETWEEN={GAUSSIAN LOWER=1.0 UPPER=2.0}
+      76             : ... DISTANCES
+      77             : \endplumedfile
+      78             : (see \ref DISTANCES)
+      79             : 
+      80             : The advantage of \ref MTRANSFORM_BETWEEN comes, however, if you want to use transformed colvars as input
+      81             : for \ref MULTICOLVARDENS
+      82             : 
+      83             : */
+      84             : //+ENDPLUMEDOC
+      85             : 
+      86             : //+PLUMEDOC MFILTERS MFILTER_BETWEEN
+      87             : /*
+      88             : This action can be used to filter the colvar values calculated by a \ref mcolv
+      89             : so that one can compute the mean and so on for only those multicolvars within a certain range.
+      90             : 
+      91             : This action can be used to create a dynamic group of atom based on the value of a multicolvar.
+      92             : In this action a multicolvar is within the dynamic group if its value lies in a particular range.
+      93             : In actuality a weight, \f$w_i\f$  is ascribed to each colvar, \f$s_i\f$ calculated by a multicolvar
+      94             : and this weight measures the degree to which a colvar is a member of the group.  This weight is
+      95             : calculated using a \ref histogrambead so it is given by:
+      96             : 
+      97             : \f[
+      98             : w_i = \int_a^b K\left( \frac{s - s_i}{w} \right)
+      99             : \f]
+     100             : 
+     101             : where \f$a, b\f$ and \f$w\f$ are parameters.  If one calculates a function of the set of multicolvars
+     102             : these weights are included in the calculation.  As such if one calculates the MEAN, \f$\mu\f$ of a filtered
+     103             : multicolvar what is computed is the following:
+     104             : 
+     105             : \f[
+     106             : \mu = \frac{ \sum_i w_i s_i }{ \sum_i w_i}
+     107             : \f]
+     108             : 
+     109             : One is thus calculating the mean for those colvars that are within the range of interest.
+     110             : 
+     111             : \par Examples
+     112             : 
+     113             : The example shown below calculates the mean for those distances that are between 0 and 3 nm in length
+     114             : 
+     115             : \plumedfile
+     116             : DISTANCES GROUPA=1 GROUPB=2-50 MEAN LABEL=d1
+     117             : MFILTER_BETWEEN DATA=d1 LOWER=0 UPPER=3.0 SMEAR=0.0001 MEAN LABEL=d4
+     118             : \endplumedfile
+     119             : 
+     120             : More complicated things can be done by using the label of a filter as input to a new multicolvar as shown
+     121             : in the example below.  Here the coordination numbers of all atoms are computed.  The atoms with a coordination
+     122             : number between 4 and 6 are then identified using the filter.  This reduced list of atoms is then used as input
+     123             : to a second coordination number calculation.  This second coordination number thus measures the number of atoms
+     124             : 4-6 coordinated atoms each of the 4-6 coordination atoms is bound to.
+     125             : 
+     126             : \plumedfile
+     127             : c1: COORDINATIONNUMBER SPECIES=1-150 SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0}
+     128             : cf: MFILTER_BETWEEN DATA=c1 LOWER=4 UPPER=6 SMEAR=0.5 LOWMEM
+     129             : c2: COORDINATIONNUMBER SPECIES=cf SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0} MORE_THAN={RATIONAL D_0=2.0 R_0=0.1}
+     130             : \endplumedfile
+     131             : 
+     132             : */
+     133             : //+ENDPLUMEDOC
+     134             : 
+     135             : namespace PLMD {
+     136             : namespace multicolvar {
+     137             : 
+     138             : class FilterBetween : public MultiColvarFilter {
+     139             : private:
+     140             :   HistogramBead hb;
+     141             : public:
+     142             :   static void registerKeywords( Keywords& keys );
+     143             :   explicit FilterBetween(const ActionOptions& ao);
+     144             :   double applyFilter( const double& val, double& df ) const override;
+     145             : };
+     146             : 
+     147             : PLUMED_REGISTER_ACTION(FilterBetween,"MFILTER_BETWEEN")
+     148             : PLUMED_REGISTER_ACTION(FilterBetween,"MTRANSFORM_BETWEEN")
+     149             : 
+     150           7 : void FilterBetween::registerKeywords( Keywords& keys ) {
+     151           7 :   MultiColvarFilter::registerKeywords( keys );
+     152          14 :   keys.add("compulsory","LOWER","the lower boundary for the range of interest");
+     153          14 :   keys.add("compulsory","UPPER","the upper boundary for the range of interest");
+     154          14 :   keys.add("compulsory","SMEAR","0.5","the amount by which to smear the value for kernel density estimation");
+     155          14 :   keys.add("optional","BEAD","This keywords is used if you want to employ an alternative to the function defined above. "
+     156             :            "The following provides information on the \\ref histogrambead that are available. "
+     157             :            "When this keyword is present you no longer need the LOWER, UPPER and SMEAR keywords.");
+     158           7 : }
+     159             : 
+     160           3 : FilterBetween::FilterBetween(const ActionOptions& ao):
+     161             :   Action(ao),
+     162           3 :   MultiColvarFilter(ao)
+     163             : {
+     164             :   // Read in the switching function
+     165           6 :   std::string sw, errors; parse("BEAD",sw);
+     166           3 :   if( getPntrToMultiColvar()->isPeriodic() ) {
+     167           0 :     std::string min, max; getPntrToMultiColvar()->retrieveDomain( min, max );
+     168           0 :     double mlow, mhigh; Tools::convert( min,mlow ); Tools::convert( max, mhigh);
+     169           0 :     hb.isPeriodic( mlow, mhigh );
+     170             :   } else {
+     171             :     hb.isNotPeriodic();
+     172             :   }
+     173             : 
+     174           3 :   if(sw.length()>0) {
+     175           0 :     hb.set(sw,errors);
+     176           0 :     if( errors.length()!=0 ) error("problem reading BEAD keyword : " + errors );
+     177             :   } else {
+     178             :     double l, u, s; std::string ll, uu, ss;
+     179           9 :     parse("LOWER",l); parse("UPPER",u); parse("SMEAR",s);
+     180           3 :     Tools::convert(l,ll); Tools::convert(u,uu); Tools::convert(s,ss);
+     181           6 :     sw="GAUSSIAN LOWER=" + ll + " UPPER=" + uu + " SMEAR=" + ss;
+     182           3 :     hb.set(sw,errors); plumed_massert(errors.length()==0,"problems with bead" + errors);
+     183             :   }
+     184           3 :   log.printf("  filtering colvar values and focussing only on those values in range %s\n",( hb.description() ).c_str() );
+     185             : 
+     186           3 :   checkRead();
+     187           3 : }
+     188             : 
+     189         735 : double FilterBetween::applyFilter( const double& val, double& df ) const {
+     190         735 :   double f = hb.calculate( val, df );
+     191         735 :   return f;
+     192             : }
+     193             : 
+     194             : }
+     195             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterLessThan.cpp.func-sort-c.html b/coverage/multicolvar/FilterLessThan.cpp.func-sort-c.html new file mode 100644 index 000000000000..61caeb0fe7c8 --- /dev/null +++ b/coverage/multicolvar/FilterLessThan.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/FilterLessThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - FilterLessThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202580.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterLessC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar10FilterLessC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar10FilterLess16registerKeywordsERNS_8KeywordsE8
_ZNK4PLMD11multicolvar10FilterLess11applyFilterERKdRd2486
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterLessThan.cpp.func.html b/coverage/multicolvar/FilterLessThan.cpp.func.html new file mode 100644 index 000000000000..cc352deb124d --- /dev/null +++ b/coverage/multicolvar/FilterLessThan.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/FilterLessThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - FilterLessThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202580.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterLess16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD11multicolvar10FilterLessC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar10FilterLessC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar10FilterLess11applyFilterERKdRd2486
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterLessThan.cpp.gcov.html b/coverage/multicolvar/FilterLessThan.cpp.gcov.html new file mode 100644 index 000000000000..e8cbe010d36c --- /dev/null +++ b/coverage/multicolvar/FilterLessThan.cpp.gcov.html @@ -0,0 +1,240 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/FilterLessThan.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - FilterLessThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202580.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/SwitchingFunction.h"
+      24             : #include "MultiColvarFilter.h"
+      25             : 
+      26             : //+PLUMEDOC MTRANSFORMS MTRANSFORM_LESS
+      27             : /*
+      28             : This action can be used to transform the colvar values calculated by a multicovar using a switching function
+      29             : 
+      30             : In this action each colvar, \f$s_i\f$, calculated by \ref mcolv is transformed by a \ref switchingfunction function that
+      31             : is equal to one if the colvar is less than a certain target value and which is equal to zero otherwise.
+      32             : It is important to understand the distinction between what is done here and what is done by \ref MFILTER_LESS.
+      33             : In \ref MFILTER_LESS a weight, \f$w_i\f$ for the colvar is calculated using the \ref switchingfunction.  If one calculates the
+      34             : MEAN for \ref MFILTER_LESS one is thus calculating:
+      35             : 
+      36             : \f[
+      37             : \mu = \frac{ \sum_i \sigma(s_i) s_i }{\sum_i \simga(s_i) }
+      38             : \f]
+      39             : 
+      40             : where \f$\sigma\f$ is the \ref switchingfunction.  In this action by contrast the colvar is being transformed by
+      41             : the \ref switchingfunction.  If one thus calculates a MEAN for this action one computes:
+      42             : 
+      43             : \f[
+      44             : \mu = \frac{ \sum_{i=1}^N \simga(s_i) }{ N }
+      45             : \f]
+      46             : 
+      47             : In other words, you are calculating the mean for the transformed colvar.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : The following input gives an example of how a MTRANSFORM_LESS action can be used to duplicate
+      52             : functionality that is elsewhere in PLUMED.
+      53             : 
+      54             : \plumedfile
+      55             : DISTANCES ...
+      56             :  GROUPA=1-10 GROUPB=11-20
+      57             :  LABEL=d1
+      58             : ... DISTANCES
+      59             : MTRANSFORM_LESS DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001}
+      60             : \endplumedfile
+      61             : 
+      62             : In this case you can achieve the same result by using:
+      63             : 
+      64             : \plumedfile
+      65             : DISTANCES ...
+      66             :  GROUPA=1-10 GROUPB=11-20
+      67             :  LESS_THAN={GAUSSIAN D_0=1.5 R_0=0.00001}
+      68             : ... DISTANCES
+      69             : \endplumedfile
+      70             : (see \ref DISTANCES)
+      71             : 
+      72             : The advantage of MTRANSFORM_LESS comes, however, if you want to use transformed colvars as input
+      73             : for \ref MULTICOLVARDENS
+      74             : 
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : 
+      78             : //+PLUMEDOC MFILTERS MFILTER_LESS
+      79             : /*
+      80             : This action can be used to filter the distribution of colvar values in a \ref mcolv
+      81             : so that one can compute the mean and so on for only those multicolvars less than a tolerance.
+      82             : 
+      83             : This action can be used to create a dynamic group of atom based on the value of a multicolvar.
+      84             : In this action a multicolvar is within the dynamic group if its value is less than a target.
+      85             : In actuality a weight, \f$w_i\f$ is ascribed to each colvar, \f$s_i\f$ calculated by a multicolvar
+      86             : and this weight measures the degree to which a colvar is a member of the group.  This weight is a number
+      87             : between 0 and 1 that is calculated using a \ref switchingfunction , \f$\sigma\f$.
+      88             : If one calculates a function of the set of multicolvars
+      89             : these weights are included in the calculation.  As such if one calculates the MEAN, \f$\mu\f$ of a filtered
+      90             : multicolvar what is computed is the following:
+      91             : 
+      92             : \f[
+      93             : \mu = \frac{ \sum_i w_i s_i }{ \sum_i w_i}
+      94             : \f]
+      95             : 
+      96             : One is thus calculating the mean for those colvars that are less than the target.
+      97             : 
+      98             : \par Examples
+      99             : 
+     100             : The example shown below calculates the mean for those distances that less than 1.5 nm in length
+     101             : 
+     102             : \plumedfile
+     103             : DISTANCES GROUPA=1 GROUPB=2-50 MEAN LABEL=d1
+     104             : MFILTER_LESS DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001} MEAN LABEL=d4
+     105             : \endplumedfile
+     106             : 
+     107             : */
+     108             : //+ENDPLUMEDOC
+     109             : 
+     110             : namespace PLMD {
+     111             : namespace multicolvar {
+     112             : 
+     113             : class FilterLess : public MultiColvarFilter {
+     114             : private:
+     115             :   SwitchingFunction sf;
+     116             : public:
+     117             :   static void registerKeywords( Keywords& keys );
+     118             :   explicit FilterLess(const ActionOptions& ao);
+     119             :   double applyFilter( const double& val, double& df ) const override;
+     120             : };
+     121             : 
+     122             : PLUMED_REGISTER_ACTION(FilterLess,"MFILTER_LESS")
+     123             : PLUMED_REGISTER_ACTION(FilterLess,"MTRANSFORM_LESS")
+     124             : 
+     125           8 : void FilterLess::registerKeywords( Keywords& keys ) {
+     126           8 :   MultiColvarFilter::registerKeywords( keys );
+     127          16 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     128          16 :   keys.add("compulsory","MM","0","The m parameter of the switching function ");
+     129          16 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     130          16 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     131          16 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+     132             :            "The following provides information on the \\ref switchingfunction that are available. "
+     133             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     134           8 : }
+     135             : 
+     136           4 : FilterLess::FilterLess(const ActionOptions& ao):
+     137             :   Action(ao),
+     138           4 :   MultiColvarFilter(ao)
+     139             : {
+     140             :   // Read in the switching function
+     141           8 :   std::string sw, errors; parse("SWITCH",sw);
+     142           4 :   if(sw.length()>0) {
+     143           4 :     sf.set(sw,errors);
+     144           4 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     145             :   } else {
+     146           0 :     double r_0=-1.0, d_0; int nn, mm;
+     147           0 :     parse("NN",nn); parse("MM",mm);
+     148           0 :     parse("R_0",r_0); parse("D_0",d_0);
+     149           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     150           0 :     sf.set(nn,mm,r_0,d_0);
+     151             :   }
+     152           4 :   log.printf("  filtering colvar values and focussing only on those less than %s\n",( sf.description() ).c_str() );
+     153             : 
+     154           4 :   checkRead();
+     155           4 : }
+     156             : 
+     157        2486 : double FilterLess::applyFilter( const double& val, double& df ) const {
+     158        2486 :   double f = sf.calculate( val, df ); df*=val;
+     159        2486 :   return f;
+     160             : }
+     161             : 
+     162             : }
+     163             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterMoreThan.cpp.func-sort-c.html b/coverage/multicolvar/FilterMoreThan.cpp.func-sort-c.html new file mode 100644 index 000000000000..6a8c2873e5bc --- /dev/null +++ b/coverage/multicolvar/FilterMoreThan.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/FilterMoreThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - FilterMoreThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202580.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterMoreC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar10FilterMoreC1ERKNS_13ActionOptionsE7
_ZN4PLMD11multicolvar10FilterMore16registerKeywordsERNS_8KeywordsE11
_ZNK4PLMD11multicolvar10FilterMore11applyFilterERKdRd16806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterMoreThan.cpp.func.html b/coverage/multicolvar/FilterMoreThan.cpp.func.html new file mode 100644 index 000000000000..d1d13124936f --- /dev/null +++ b/coverage/multicolvar/FilterMoreThan.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/FilterMoreThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - FilterMoreThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202580.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10FilterMore16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD11multicolvar10FilterMoreC1ERKNS_13ActionOptionsE7
_ZN4PLMD11multicolvar10FilterMoreC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar10FilterMore11applyFilterERKdRd16806
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/FilterMoreThan.cpp.gcov.html b/coverage/multicolvar/FilterMoreThan.cpp.gcov.html new file mode 100644 index 000000000000..3e69d5339588 --- /dev/null +++ b/coverage/multicolvar/FilterMoreThan.cpp.gcov.html @@ -0,0 +1,257 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/FilterMoreThan.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - FilterMoreThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202580.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/SwitchingFunction.h"
+      24             : #include "MultiColvarFilter.h"
+      25             : 
+      26             : //+PLUMEDOC MTRANSFORMS MTRANSFORM_MORE
+      27             : /*
+      28             : This action can be used to transform the colvar values calculated by a multicolvar using one minus a switching function
+      29             : 
+      30             : In this action each colvar, \f$s_i\f$, calculated by \ref mcolv is transformed by a \ref switchingfunction function that
+      31             : is equal to one if the colvar is greater than a certain target value and which is equal to zero otherwise.
+      32             : It is important to understand the distinction between what is done here and what is done by \ref MFILTER_MORE.
+      33             : In \ref MFILTER_MORE a weight, \f$w_i\f$ for the colvar is calculated using the \ref histogrambead.  If one calculates the
+      34             : MEAN for \ref MFILTER_MORE one is thus calculating:
+      35             : 
+      36             : \f[
+      37             : \mu = \frac{ \sum_i [1 - \sigma(s_i) ] s_i }{\sum_i [1 - \sigma(s_i)] }
+      38             : \f]
+      39             : 
+      40             : where \f$\sigma\f$ is the \ref switchingfunction.  In this action by contrast the colvar is being transformed by the \ref switchingfunction.
+      41             : If one thus calculates a MEAN for this action one computes:
+      42             : 
+      43             : \f[
+      44             : \mu = \frac{ \sum_{i=1}^N 1 - \sigma(s_i) }{ N }
+      45             : \f]
+      46             : 
+      47             : In other words, you are calculating the mean for the transformed colvar.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : The following input gives an example of how a MTRANSFORM_MORE action can be used to duplicate
+      52             : functionality that is elsewhere in PLUMED.
+      53             : 
+      54             : \plumedfile
+      55             : DISTANCES ...
+      56             :  GROUPA=1-10 GROUPB=11-20
+      57             :  LABEL=d1
+      58             : ... DISTANCES
+      59             : MTRANSFORM_MORE DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001}
+      60             : \endplumedfile
+      61             : 
+      62             : In this case you can achieve the same result by using:
+      63             : 
+      64             : \plumedfile
+      65             : DISTANCES ...
+      66             :  GROUPA=1-10 GROUPB=11-20
+      67             :  MORE_THAN={GAUSSIAN D_0=1.5 R_0=0.00001}
+      68             : ... DISTANCES
+      69             : \endplumedfile
+      70             : (see \ref DISTANCES)
+      71             : 
+      72             : The advantage of MTRANSFORM_MORE comes, however, if you want to use transformed colvars as input
+      73             : for \ref MULTICOLVARDENS
+      74             : 
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : 
+      78             : //+PLUMEDOC MFILTERS MFILTER_MORE
+      79             : /*
+      80             : This action can be used to filter the distribution of colvar values in a \ref mcolv
+      81             : so that one can compute the mean and so on for only those multicolvars more than a tolerance.
+      82             : 
+      83             : This action can be used to create a dynamic group of atom based on the value of a multicolvar.
+      84             : In this action a multicolvar is within the dynamic group if its value is greater than a target.
+      85             : In actuality a weight, \f$w_i\f$  is ascribed to each colvar, \f$s_i\f$ calculated by a multicolvar
+      86             : and this weight measures the degree to which a colvar is a member of the group.  This weight is
+      87             : calculated using a \ref switchingfunction , \f$\sigma\f$ so it is given by:
+      88             : 
+      89             : \f[
+      90             : w_i = 1 - \sigma(s_i)
+      91             : \f]
+      92             : 
+      93             : If one calculates a function of the set of multicolvars
+      94             : these weights are included in the calculation.  As such if one calculates the MEAN, \f$\mu\f$ of a filtered
+      95             : multicolvar what is computed is the following:
+      96             : 
+      97             : \f[
+      98             : \mu = \frac{ \sum_i w_i s_i }{ \sum_i w_i}
+      99             : \f]
+     100             : 
+     101             : One is thus calculating the mean for those colvars that are greater than the target.
+     102             : 
+     103             : \par Examples
+     104             : 
+     105             : The example shown below calculates the mean for those distances that greater than 1.5 nm in length
+     106             : 
+     107             : \plumedfile
+     108             : DISTANCES GROUPA=1 GROUPB=2-50 MEAN LABEL=d1
+     109             : MFILTER_MORE DATA=d1 SWITCH={GAUSSIAN D_0=1.5 R_0=0.00001} MEAN LABEL=d4
+     110             : \endplumedfile
+     111             : 
+     112             : More complicated things can be done by using the label of a filter as input to a new multicolvar as shown
+     113             : in the example below.  Here the coordination numbers of all atoms are computed.  The atoms with a coordination
+     114             : number greater than 2 are then identified using the filter.  This reduced list of atoms is then used as input
+     115             : to a second coordination number calculation.  This second coordination number thus measures the number of
+     116             : two-coordinated atoms that each of the two-coordinated atoms is bound to.
+     117             : 
+     118             : \plumedfile
+     119             : c1: COORDINATIONNUMBER SPECIES=1-150 SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0}
+     120             : cf: MFILTER_MORE DATA=c1 SWITCH={RATIONAL D_0=2.0 R_0=0.1} LOWMEM
+     121             : c2: COORDINATIONNUMBER SPECIES=cf SWITCH={EXP D_0=4.0 R_0=0.5 D_MAX=6.0} MORE_THAN={RATIONAL D_0=2.0 R_0=0.1}
+     122             : \endplumedfile
+     123             : 
+     124             : */
+     125             : //+ENDPLUMEDOC
+     126             : 
+     127             : namespace PLMD {
+     128             : namespace multicolvar {
+     129             : 
+     130             : class FilterMore : public MultiColvarFilter {
+     131             : private:
+     132             :   SwitchingFunction sf;
+     133             : public:
+     134             :   static void registerKeywords( Keywords& keys );
+     135             :   explicit FilterMore(const ActionOptions& ao);
+     136             :   double applyFilter( const double& val, double& df ) const override;
+     137             : };
+     138             : 
+     139             : PLUMED_REGISTER_ACTION(FilterMore,"MFILTER_MORE")
+     140             : PLUMED_REGISTER_ACTION(FilterMore,"MTRANSFORM_MORE")
+     141             : 
+     142          11 : void FilterMore::registerKeywords( Keywords& keys ) {
+     143          11 :   MultiColvarFilter::registerKeywords( keys );
+     144          22 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     145          22 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     146          22 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     147          22 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     148          22 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+     149             :            "The following provides information on the \\ref switchingfunction that are available. "
+     150             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     151          11 : }
+     152             : 
+     153           7 : FilterMore::FilterMore(const ActionOptions& ao):
+     154             :   Action(ao),
+     155           7 :   MultiColvarFilter(ao)
+     156             : {
+     157             :   // Read in the switching function
+     158          14 :   std::string sw, errors; parse("SWITCH",sw);
+     159           7 :   if(sw.length()>0) {
+     160           7 :     sf.set(sw,errors);
+     161           7 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     162             :   } else {
+     163           0 :     double r_0=-1.0, d_0; int nn, mm;
+     164           0 :     parse("NN",nn); parse("MM",mm);
+     165           0 :     parse("R_0",r_0); parse("D_0",d_0);
+     166           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     167           0 :     sf.set(nn,mm,r_0,d_0);
+     168             :   }
+     169           7 :   log.printf("  filtering colvar values and focussing only on those more than %s\n",( sf.description() ).c_str() );
+     170             : 
+     171           7 :   checkRead();
+     172           7 : }
+     173             : 
+     174       16806 : double FilterMore::applyFilter( const double& val, double& df ) const {
+     175       16806 :   double f = 1.0 - sf.calculate( val, df ); df*=-val;
+     176       16806 :   return f;
+     177             : }
+     178             : 
+     179             : }
+     180             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html b/coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html new file mode 100644 index 000000000000..32e99d77da59 --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/InPlaneDistances.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - InPlaneDistances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:94619.6 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar16InPlaneDistances10isPeriodicEv0
_ZN4PLMD11multicolvar16InPlaneDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16InPlaneDistancesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16InPlaneDistances7computeERKjRNS0_13AtomValuePackE0
_ZN4PLMD11multicolvar16InPlaneDistances16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/InPlaneDistances.cpp.func.html b/coverage/multicolvar/InPlaneDistances.cpp.func.html new file mode 100644 index 000000000000..45c0fdc84dad --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/InPlaneDistances.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - InPlaneDistances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:94619.6 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar16InPlaneDistances10isPeriodicEv0
_ZN4PLMD11multicolvar16InPlaneDistances16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar16InPlaneDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16InPlaneDistancesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16InPlaneDistances7computeERKjRNS0_13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/InPlaneDistances.cpp.gcov.html b/coverage/multicolvar/InPlaneDistances.cpp.gcov.html new file mode 100644 index 000000000000..1dc16dcaea44 --- /dev/null +++ b/coverage/multicolvar/InPlaneDistances.cpp.gcov.html @@ -0,0 +1,224 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/InPlaneDistances.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - InPlaneDistances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:94619.6 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "tools/SwitchingFunction.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "vesselbase/LessThan.h"
+      27             : #include "vesselbase/Between.h"
+      28             : #include "tools/Angle.h"
+      29             : 
+      30             : #include <string>
+      31             : #include <cmath>
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace multicolvar {
+      35             : 
+      36             : //+PLUMEDOC MCOLVAR INPLANEDISTANCES
+      37             : /*
+      38             : Calculate distances in the plane perpendicular to an axis
+      39             : 
+      40             : Each quantity calculated in this CV uses the positions of two atoms, this indices of which are specified using the VECTORSTART and VECTOREND keywords, to specify the
+      41             : orientation of a vector, \f$\mathbf{n}\f$.  The perpendicular distance between this vector and the position of some third atom is then computed using:
+      42             : \f[
+      43             :  x_j = |\mathbf{r}_{j}| \sin (\theta_j)
+      44             : \f]
+      45             : where \f$\mathbf{r}_j\f$ is the distance between one of the two atoms that define the vector \f$\mathbf{n}\f$ and a third atom (atom \f$j\f$) and where \f$\theta_j\f$
+      46             : is the angle between the vector \f$\mathbf{n}\f$ and the vector \f$\mathbf{r}_{j}\f$.  The \f$x_j\f$ values for each of the atoms specified using the GROUP keyword are calculated.
+      47             : Keywords such as MORE_THAN and LESS_THAN can then be used to calculate the number of these quantities that are more or less than a given cutoff.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : The following input can be used to calculate the number of atoms that have indices greater than 3 and less than 101 that
+      52             : are within a cylinder with a radius of 0.3 nm that has its long axis aligned with the vector connecting atoms 1 and 2.
+      53             : 
+      54             : \plumedfile
+      55             : d1: INPLANEDISTANCES VECTORSTART=1 VECTOREND=2 GROUP=3-100 LESS_THAN={RATIONAL D_0=0.2 R_0=0.1}
+      56             : PRINT ARG=d1.lessthan FILE=colvar
+      57             : \endplumedfile
+      58             : 
+      59             : 
+      60             : */
+      61             : //+ENDPLUMEDOC
+      62             : 
+      63             : class InPlaneDistances : public MultiColvarBase {
+      64             : public:
+      65             :   static void registerKeywords( Keywords& keys );
+      66             :   explicit InPlaneDistances(const ActionOptions&);
+      67             : // active methods:
+      68             :   double compute(const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      69           0 :   bool isPeriodic() override { return false; }
+      70             : };
+      71             : 
+      72             : PLUMED_REGISTER_ACTION(InPlaneDistances,"INPLANEDISTANCES")
+      73             : 
+      74           2 : void InPlaneDistances::registerKeywords( Keywords& keys ) {
+      75           2 :   MultiColvarBase::registerKeywords( keys );
+      76           6 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      77           8 :   keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN");
+      78           8 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      79           4 :   keys.add("atoms","VECTORSTART","The first atom position that is used to define the normal to the plane of interest");
+      80           4 :   keys.add("atoms","VECTOREND","The second atom position that is used to define the normal to the plane of interest");
+      81           4 :   keys.add("atoms-2","GROUP","The set of atoms for which you wish to calculate the in plane distance ");
+      82           2 : }
+      83             : 
+      84           0 : InPlaneDistances::InPlaneDistances(const ActionOptions&ao):
+      85             :   Action(ao),
+      86           0 :   MultiColvarBase(ao)
+      87             : {
+      88             :   // Read in the atoms
+      89             :   std::vector<AtomNumber> all_atoms;
+      90           0 :   readThreeGroups("GROUP","VECTORSTART","VECTOREND",false,false,all_atoms);
+      91           0 :   setupMultiColvarBase( all_atoms );
+      92             : 
+      93             :   // Setup the multicolvar base
+      94           0 :   setupMultiColvarBase( all_atoms ); readVesselKeywords();
+      95             :   // Check atoms are OK
+      96           0 :   if( getFullNumberOfTasks()!=getNumberOfAtoms()-2 ) error("you should specify one atom for VECTORSTART and one atom for VECTOREND only");
+      97             :   // And check everything has been read in correctly
+      98           0 :   checkRead();
+      99             : 
+     100             : // Now check if we can use link cells
+     101           0 :   if( getNumberOfVessels()>0 ) {
+     102             :     bool use_link=false; double rcut;
+     103           0 :     vesselbase::LessThan* lt=dynamic_cast<vesselbase::LessThan*>( getPntrToVessel(0) );
+     104           0 :     if( lt ) {
+     105           0 :       use_link=true; rcut=lt->getCutoff();
+     106             :     } else {
+     107           0 :       vesselbase::Between* bt=dynamic_cast<vesselbase::Between*>( getPntrToVessel(0) );
+     108           0 :       if( bt ) {
+     109           0 :         use_link=true; rcut=bt->getCutoff();
+     110             :       }
+     111             :     }
+     112             :     if( use_link ) {
+     113           0 :       for(unsigned i=1; i<getNumberOfVessels(); ++i) {
+     114           0 :         vesselbase::LessThan* lt2=dynamic_cast<vesselbase::LessThan*>( getPntrToVessel(i) );
+     115           0 :         vesselbase::Between* bt=dynamic_cast<vesselbase::Between*>( getPntrToVessel(i) );
+     116           0 :         if( lt2 ) {
+     117           0 :           double tcut=lt2->getCutoff();
+     118           0 :           if( tcut>rcut ) rcut=tcut;
+     119           0 :         } else if( bt ) {
+     120           0 :           double tcut=bt->getCutoff();
+     121           0 :           if( tcut>rcut ) rcut=tcut;
+     122             :         } else {
+     123             :           use_link=false;
+     124             :         }
+     125             :       }
+     126             :     }
+     127           0 :     if( use_link ) setLinkCellCutoff( rcut );
+     128             :   }
+     129           0 : }
+     130             : 
+     131           0 : double InPlaneDistances::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     132           0 :   Vector normal=getSeparation( myatoms.getPosition(1), myatoms.getPosition(2) );
+     133           0 :   Vector dir=getSeparation( myatoms.getPosition(1), myatoms.getPosition(0) );
+     134           0 :   PLMD::Angle a; Vector ddij, ddik; double angle=a.compute(normal,dir,ddij,ddik);
+     135           0 :   double sangle=std::sin(angle), cangle=std::cos(angle);
+     136           0 :   double dd=dir.modulo(), invdd=1.0/dd, val=dd*sangle;
+     137             : 
+     138           0 :   addAtomDerivatives( 1, 0, dd*cangle*ddik + sangle*invdd*dir, myatoms );
+     139           0 :   addAtomDerivatives( 1, 1, -dd*cangle*(ddik+ddij) - sangle*invdd*dir, myatoms );
+     140           0 :   addAtomDerivatives( 1, 2, dd*cangle*ddij, myatoms );
+     141           0 :   myatoms.addBoxDerivatives( 1, -dd*cangle*(Tensor(normal,ddij)+Tensor(dir,ddik)) - sangle*invdd*Tensor(dir,dir) );
+     142             : 
+     143           0 :   return val;
+     144             : }
+     145             : 
+     146             : }
+     147             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/LocalAverage.cpp.func-sort-c.html b/coverage/multicolvar/LocalAverage.cpp.func-sort-c.html new file mode 100644 index 000000000000..67ae6a6d4880 --- /dev/null +++ b/coverage/multicolvar/LocalAverage.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/LocalAverage.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - LocalAverage.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10613479.1 %
Date:2024-02-22 21:58:45Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12LocalAverageC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar12LocalAverage15normalizeVectorERSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar12LocalAverage10isPeriodicEv3
_ZN4PLMD11multicolvar12LocalAverageC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12LocalAverage16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD11multicolvar12LocalAverage21getNumberOfQuantitiesEv71
_ZNK4PLMD11multicolvar12LocalAverage7computeERKjRNS0_13AtomValuePackE1004
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/LocalAverage.cpp.func.html b/coverage/multicolvar/LocalAverage.cpp.func.html new file mode 100644 index 000000000000..3ab0351034c5 --- /dev/null +++ b/coverage/multicolvar/LocalAverage.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/LocalAverage.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - LocalAverage.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10613479.1 %
Date:2024-02-22 21:58:45Functions:5771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12LocalAverage10isPeriodicEv3
_ZN4PLMD11multicolvar12LocalAverage16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD11multicolvar12LocalAverageC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar12LocalAverageC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar12LocalAverage15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD11multicolvar12LocalAverage21getNumberOfQuantitiesEv71
_ZNK4PLMD11multicolvar12LocalAverage7computeERKjRNS0_13AtomValuePackE1004
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/LocalAverage.cpp.gcov.html b/coverage/multicolvar/LocalAverage.cpp.gcov.html new file mode 100644 index 000000000000..23aba048a1da --- /dev/null +++ b/coverage/multicolvar/LocalAverage.cpp.gcov.html @@ -0,0 +1,407 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/LocalAverage.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - LocalAverage.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10613479.1 %
Date:2024-02-22 21:58:45Functions:5771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/SwitchingFunction.h"
+      26             : 
+      27             : //+PLUMEDOC MCOLVARF LOCAL_AVERAGE
+      28             : /*
+      29             : Calculate averages over spherical regions centered on atoms
+      30             : 
+      31             : As is explained in <a href="http://www.youtube.com/watch?v=iDvZmbWE5ps"> this video </a> certain multicolvars
+      32             : calculate one scalar quantity or one vector for each of the atoms in the system.  For example
+      33             : \ref COORDINATIONNUMBER measures the coordination number of each of the atoms in the system and \ref Q4 measures
+      34             : the fourth order Steinhardt parameter for each of the atoms in the system.  These quantities provide tell us something about
+      35             : the disposition of the atoms in the first coordination sphere of each of the atoms of interest.  Lechner and Dellago \cite dellago-q6
+      36             : have suggested that one can probe local order in a system by taking the average value of such symmetry functions over
+      37             : the atoms within a spherical cutoff of each of these atoms in the systems.  When this is done with Steinhardt parameters
+      38             : they claim this gives a coordinate that is better able to distinguish solid and liquid configurations of Lennard-Jones atoms.
+      39             : 
+      40             : You can calculate such locally averaged quantities within plumed by using the LOCAL_AVERAGE command.  This command calculates
+      41             : the following atom-centered quantities:
+      42             : 
+      43             : \f[
+      44             : s_i = \frac{ c_i + \sum_j \sigma(r_{ij})c_j }{ 1 + \sum_j \sigma(r_{ij}) }
+      45             : \f]
+      46             : 
+      47             : where the \f$c_i\f$ and \f$c_j\f$ values can be for any one of the symmetry functions that can be calculated using plumed
+      48             : multicolvars.  The function \f$\sigma( r_{ij} )\f$ is a \ref switchingfunction that acts on the distance between
+      49             : atoms \f$i\f$ and \f$j\f$.  Lechner and Dellago suggest that the parameters of this function should be set so that it the function is equal to one
+      50             : when atom \f$j\f$ is in the first coordination sphere of atom \f$i\f$ and is zero otherwise.
+      51             : 
+      52             : The \f$s_i\f$ quantities calculated using the above command can be again thought of as atom-centered symmetry functions.  They
+      53             : thus operate much like multicolvars.  You can thus calculate properties of the distribution of \f$s_i\f$ values using MEAN, LESS_THAN, HISTOGRAM
+      54             : and so on.  You can also probe the value of these averaged variables in regions of the box by using the command in tandem with the
+      55             : \ref AROUND command.
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : This example input calculates the coordination numbers for all the atoms in the system.  These coordination numbers are then averaged over
+      60             : spherical regions.  The number of averaged coordination numbers that are greater than 4 is then output to a file.
+      61             : 
+      62             : \plumedfile
+      63             : COORDINATIONNUMBER SPECIES=1-64 D_0=1.3 R_0=0.2 LABEL=d1
+      64             : LOCAL_AVERAGE SPECIES=d1 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MORE_THAN={RATIONAL R_0=4} LABEL=la
+      65             : PRINT ARG=la.* FILE=colvar
+      66             : \endplumedfile
+      67             : 
+      68             : This example input calculates the \f$q_4\f$ (see \ref Q4) vectors for each of the atoms in the system.  These vectors are then averaged
+      69             : component by component over a spherical region.  The average value for this quantity is then output to a file.  This calculates the
+      70             : quantities that were used in the paper by Lechner and Dellago \cite dellago-q6
+      71             : 
+      72             : \plumedfile
+      73             : Q4 SPECIES=1-64 SWITCH={RATIONAL D_0=1.3 R_0=0.2} LABEL=q4
+      74             : LOCAL_AVERAGE SPECIES=q4 SWITCH={RATIONAL D_0=1.3 R_0=0.2} MEAN LABEL=la
+      75             : PRINT ARG=la.* FILE=colvar
+      76             : \endplumedfile
+      77             : 
+      78             : */
+      79             : //+ENDPLUMEDOC
+      80             : 
+      81             : namespace PLMD {
+      82             : namespace multicolvar {
+      83             : 
+      84             : class LocalAverage : public MultiColvarBase {
+      85             : private:
+      86             : /// Cutoff
+      87             :   double rcut2;
+      88             : /// The switching function that tells us if atoms are close enough together
+      89             :   SwitchingFunction switchingFunction;
+      90             : public:
+      91             :   static void registerKeywords( Keywords& keys );
+      92             :   explicit LocalAverage(const ActionOptions&);
+      93             : /// We have to overwrite this here
+      94             :   unsigned getNumberOfQuantities() const override;
+      95             : /// Actually do the calculation
+      96             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      97             : /// We overwrite this in order to have dumpmulticolvar working for local average
+      98           0 :   void normalizeVector( std::vector<double>& vals ) const override {}
+      99             : /// Is the variable periodic
+     100           3 :   bool isPeriodic() override { return false; }
+     101             : };
+     102             : 
+     103             : PLUMED_REGISTER_ACTION(LocalAverage,"LOCAL_AVERAGE")
+     104             : 
+     105           6 : void LocalAverage::registerKeywords( Keywords& keys ) {
+     106           6 :   MultiColvarBase::registerKeywords( keys );
+     107          12 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+     108          12 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+     109          12 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+     110          12 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+     111          12 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+     112             :            "The following provides information on the \\ref switchingfunction that are available. "
+     113             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     114             :   // Use actionWithDistributionKeywords
+     115          18 :   keys.use("SPECIES"); keys.use("SPECIESA"); keys.use("SPECIESB");
+     116          24 :   keys.remove("LOWMEM"); keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN");
+     117          18 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     118          12 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+     119          18 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+     120          18 :   if( keys.reserved("VSUM") ) keys.use("VSUM");
+     121           6 : }
+     122             : 
+     123           4 : LocalAverage::LocalAverage(const ActionOptions& ao):
+     124             :   Action(ao),
+     125           4 :   MultiColvarBase(ao)
+     126             : {
+     127           4 :   if( getNumberOfBaseMultiColvars()>1 ) error("local average with more than one base colvar makes no sense");
+     128             :   // Read in the switching function
+     129           8 :   std::string sw, errors; parse("SWITCH",sw);
+     130           4 :   if(sw.length()>0) {
+     131           4 :     switchingFunction.set(sw,errors);
+     132             :   } else {
+     133           0 :     double r_0=-1.0, d_0; int nn, mm;
+     134           0 :     parse("NN",nn); parse("MM",mm);
+     135           0 :     parse("R_0",r_0); parse("D_0",d_0);
+     136           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     137           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+     138             :   }
+     139           4 :   log.printf("  averaging over central molecule and those within %s\n",( switchingFunction.description() ).c_str() );
+     140           4 :   rcut2 = switchingFunction.get_dmax()*switchingFunction.get_dmax();
+     141           4 :   setLinkCellCutoff( switchingFunction.get_dmax() );
+     142           4 :   std::vector<AtomNumber> all_atoms; setupMultiColvarBase( all_atoms );
+     143           4 : }
+     144             : 
+     145          71 : unsigned LocalAverage::getNumberOfQuantities() const {
+     146          71 :   return getBaseMultiColvar(0)->getNumberOfQuantities();
+     147             : }
+     148             : 
+     149        1004 : double LocalAverage::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     150             :   double sw, dfunc; MultiValue& myvals = myatoms.getUnderlyingMultiValue();
+     151        1004 :   std::vector<double> values( getBaseMultiColvar(0)->getNumberOfQuantities() );
+     152             : 
+     153        1004 :   getInputData( 0, false, myatoms, values );
+     154             :   myvals.addTemporyValue( values[0] );
+     155        1004 :   if( values.size()>2 ) {
+     156       27108 :     for(unsigned j=2; j<values.size(); ++j) myatoms.addValue( j, values[0]*values[j] );
+     157             :   } else {
+     158           0 :     myatoms.addValue( 1, values[0]*values[1] );
+     159             :   }
+     160             : 
+     161        1004 :   if( !doNotCalculateDerivatives() ) {
+     162        1004 :     MultiValue& myder=getInputDerivatives( 0, false, myatoms );
+     163             : 
+     164             :     // Convert input atom to local index
+     165             :     unsigned katom = myatoms.getIndex( 0 ); plumed_dbg_assert( katom<atom_lab.size() ); plumed_dbg_assert( atom_lab[katom].first>0 );
+     166             :     // Find base colvar
+     167        1004 :     unsigned mmc=atom_lab[katom].first - 1; plumed_dbg_assert( mybasemulticolvars[mmc]->taskIsCurrentlyActive( atom_lab[katom].second ) );
+     168             :     // Get start of indices for this atom
+     169        1004 :     unsigned basen=0; for(unsigned i=0; i<mmc; ++i) basen+=mybasemulticolvars[i]->getNumberOfDerivatives() - 9;
+     170             :     plumed_dbg_assert( basen%3==0 ); // Check the number of atoms is consistent with input derivatives
+     171             : 
+     172        1004 :     unsigned virbas = myvals.getNumberOfDerivatives()-9;
+     173        1004 :     if( values.size()>2 ) {
+     174       53663 :       for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     175             :         unsigned jder=myder.getActiveIndex(j);
+     176       52659 :         if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     177       43623 :           unsigned kder=basen+jder;
+     178     1177821 :           for(unsigned k=2; k<values.size(); ++k) {
+     179     1134198 :             myatoms.addDerivative( k, kder, values[0]*myder.getDerivative(k,jder) );
+     180     1134198 :             myatoms.addDerivative( k, kder, values[k]*myder.getDerivative(0,jder) );
+     181             :           }
+     182             :         } else {
+     183        9036 :           unsigned kder=virbas + (jder - mybasemulticolvars[mmc]->getNumberOfDerivatives() + 9);
+     184      243972 :           for(unsigned k=2; k<values.size(); ++k) {
+     185      234936 :             myatoms.addDerivative( k, kder, values[0]*myder.getDerivative(k,jder) );
+     186      234936 :             myatoms.addDerivative( k, kder, values[k]*myder.getDerivative(0,jder) );
+     187             :           }
+     188             :         }
+     189             :       }
+     190             :     } else {
+     191           0 :       for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     192             :         unsigned jder=myder.getActiveIndex(j);
+     193           0 :         if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     194           0 :           unsigned kder=basen+jder;
+     195           0 :           myatoms.addDerivative( 1, kder, values[0]*myder.getDerivative(1,jder) );
+     196           0 :           myatoms.addDerivative( 1, kder, values[1]*myder.getDerivative(0,jder) );
+     197             :         } else {
+     198           0 :           unsigned kder=virbas + (jder - mybasemulticolvars[mmc]->getNumberOfDerivatives() + 9);
+     199           0 :           myatoms.addDerivative( 1, kder, values[0]*myder.getDerivative(1,jder) );
+     200           0 :           myatoms.addDerivative( 1, kder, values[1]*myder.getDerivative(0,jder) );
+     201             :         }
+     202             :       }
+     203             :     }
+     204       53663 :     for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     205             :       unsigned jder=myder.getActiveIndex(j);
+     206       52659 :       if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     207       43623 :         unsigned kder=basen+jder;
+     208       43623 :         myvals.addTemporyDerivative( kder, myder.getDerivative(0, jder) );
+     209             :       } else {
+     210        9036 :         unsigned kder=virbas + (jder - mybasemulticolvars[mmc]->getNumberOfDerivatives() + 9);
+     211        9036 :         myvals.addTemporyDerivative( kder, myder.getDerivative(0, jder) );
+     212             :       }
+     213             :     }
+     214        1004 :     myder.clearAll();
+     215             :   }
+     216             : 
+     217       78226 :   for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     218             :     Vector& distance=myatoms.getPosition(i);  // getSeparation( myatoms.getPosition(0), myatoms.getPosition(i) );
+     219             :     double d2;
+     220      123529 :     if ( (d2=distance[0]*distance[0])<rcut2 &&
+     221       46307 :          (d2+=distance[1]*distance[1])<rcut2 &&
+     222      103834 :          (d2+=distance[2]*distance[2])<rcut2 &&
+     223             :          d2>epsilon) {
+     224             : 
+     225       16025 :       sw = switchingFunction.calculateSqr( d2, dfunc );
+     226             : 
+     227       16025 :       getInputData( i, false, myatoms, values );
+     228       16025 :       if( values.size()>2 ) {
+     229      432675 :         for(unsigned j=2; j<values.size(); ++j) myatoms.addValue( j, sw*values[0]*values[j] );
+     230             :       } else {
+     231           0 :         myatoms.addValue( 1, sw*values[0]*values[1] );
+     232             :       }
+     233             :       myvals.addTemporyValue(sw);
+     234             : 
+     235       16025 :       if( !doNotCalculateDerivatives() ) {
+     236       16025 :         Tensor vir(distance,distance);
+     237       16025 :         MultiValue& myder=getInputDerivatives( i, false, myatoms );
+     238             : 
+     239             :         // Convert input atom to local index
+     240             :         unsigned katom = myatoms.getIndex( i ); plumed_dbg_assert( katom<atom_lab.size() ); plumed_dbg_assert( atom_lab[katom].first>0 );
+     241             :         // Find base colvar
+     242       16025 :         unsigned mmc=atom_lab[katom].first - 1; plumed_dbg_assert( mybasemulticolvars[mmc]->taskIsCurrentlyActive( atom_lab[katom].second ) );
+     243             :         // Get start of indices for this atom
+     244       22331 :         unsigned basen=0; for(unsigned j=0; j<mmc; ++j) basen+=mybasemulticolvars[j]->getNumberOfDerivatives() - 9;
+     245             :         plumed_dbg_assert( basen%3==0 ); // Check the number of atoms is consistent with input derivatives
+     246             : 
+     247       16025 :         unsigned virbas = myvals.getNumberOfDerivatives()-9;
+     248       16025 :         if( values.size()>2 ) {
+     249     1523879 :           for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     250             :             unsigned jder=myder.getActiveIndex(j);
+     251     1507854 :             if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     252     1363629 :               unsigned kder=basen+jder;
+     253    36817983 :               for(unsigned k=2; k<values.size(); ++k) {
+     254    35454354 :                 myatoms.addDerivative( k, kder, sw*values[0]*myder.getDerivative(k,jder) );
+     255    35454354 :                 myatoms.addDerivative( k, kder, sw*values[k]*myder.getDerivative(0,jder) );
+     256             :               }
+     257             :             } else {
+     258      144225 :               unsigned kder=virbas + (jder - mybasemulticolvars[mmc]->getNumberOfDerivatives() + 9);
+     259     3894075 :               for(unsigned k=2; k<values.size(); ++k) {
+     260     3749850 :                 myatoms.addDerivative( k, kder, sw*values[0]*myder.getDerivative(k,jder) );
+     261     3749850 :                 myatoms.addDerivative( k, kder, sw*values[k]*myder.getDerivative(0,jder) );
+     262             :               }
+     263             :             }
+     264             :           }
+     265      432675 :           for(unsigned k=2; k<values.size(); ++k) {
+     266      416650 :             addAtomDerivatives( k, 0, (-dfunc)*values[0]*values[k]*distance, myatoms );
+     267      416650 :             addAtomDerivatives( k, i, (+dfunc)*values[0]*values[k]*distance, myatoms );
+     268      416650 :             myatoms.addBoxDerivatives( k, (-dfunc)*values[0]*values[k]*vir );
+     269             :           }
+     270             :         } else {
+     271           0 :           for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     272             :             unsigned jder=myder.getActiveIndex(j);
+     273           0 :             if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     274           0 :               unsigned kder=basen+jder;
+     275           0 :               myatoms.addDerivative( 1, kder, sw*values[0]*myder.getDerivative(1,jder) );
+     276           0 :               myatoms.addDerivative( 1, kder, sw*values[1]*myder.getDerivative(0,jder) );
+     277             :             } else {
+     278           0 :               unsigned kder=virbas + (jder - mybasemulticolvars[mmc]->getNumberOfDerivatives() + 9);
+     279           0 :               myatoms.addDerivative( 1, kder, sw*values[0]*myder.getDerivative(1,jder) );
+     280           0 :               myatoms.addDerivative( 1, kder, sw*values[1]*myder.getDerivative(0,jder) );
+     281             :             }
+     282             :           }
+     283           0 :           addAtomDerivatives( 1, 0, (-dfunc)*values[0]*values[1]*distance, myatoms );
+     284           0 :           addAtomDerivatives( 1, i, (+dfunc)*values[0]*values[1]*distance, myatoms );
+     285           0 :           myatoms.addBoxDerivatives( 1, (-dfunc)*values[0]*values[1]*vir );
+     286             :         }
+     287             :         // And the bit we use to average the vector
+     288       16025 :         addAtomDerivatives( -1, 0, (-dfunc)*values[0]*distance, myatoms );
+     289       16025 :         addAtomDerivatives( -1, i, (+dfunc)*values[0]*distance, myatoms );
+     290     1523879 :         for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     291             :           unsigned jder=myder.getActiveIndex(j);
+     292     1507854 :           if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     293     1363629 :             unsigned kder=basen+jder;
+     294     1363629 :             myvals.addTemporyDerivative( kder, sw*myder.getDerivative(0, jder) );
+     295             :           } else {
+     296      144225 :             unsigned kder=virbas + (jder - mybasemulticolvars[mmc]->getNumberOfDerivatives() + 9);
+     297      144225 :             myvals.addTemporyDerivative( kder, sw*myder.getDerivative(0, jder) );
+     298             :           }
+     299             :         }
+     300       16025 :         myatoms.addTemporyBoxDerivatives( (-dfunc)*values[0]*vir );
+     301       16025 :         myder.clearAll();
+     302             :       }
+     303             :     }
+     304             :   }
+     305             : 
+     306             :   // Set the tempory weight
+     307        1004 :   updateActiveAtoms( myatoms );
+     308        1004 :   if( values.size()>2) {
+     309             :     double norm=0;
+     310       27108 :     for(unsigned i=2; i<values.size(); ++i) {
+     311       26104 :       myvals.quotientRule( i, i );
+     312             :       // Calculate length of vector
+     313       26104 :       norm+=myvals.get(i)*myvals.get(i);
+     314             :     }
+     315        1004 :     norm=sqrt(norm); myatoms.setValue(1, norm); double inorm = 1.0 / norm;
+     316      165719 :     for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
+     317      164715 :       unsigned jder=myvals.getActiveIndex(j);
+     318     4447305 :       for(unsigned i=2; i<values.size(); ++i) {
+     319     4282590 :         myvals.addDerivative( 1, jder, myvals.get(i)*inorm*myvals.getDerivative(i,jder) );
+     320             :       }
+     321             :     }
+     322             :   } else {
+     323           0 :     myvals.quotientRule( 1, 1 );
+     324             :   }
+     325             : 
+     326        1004 :   return myatoms.getValue(1);
+     327             : }
+     328             : 
+     329             : }
+     330             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.cpp.func-sort-c.html b/coverage/multicolvar/MultiColvarBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..2f0e979dfc95 --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.cpp.func-sort-c.html @@ -0,0 +1,237 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:58365289.4 %
Date:2024-02-22 21:58:45Functions:404197.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15MultiColvarBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15MultiColvarBase9buildSetsEv4
_ZNK4PLMD11multicolvar15MultiColvarBase17getLinkCellCutoffEv8
_ZN4PLMD11multicolvar15MultiColvarBase15readThreeGroupsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RKbSB_RSt6vectorINS_10AtomNumberESaISD_EE10
_ZN4PLMD11multicolvar15MultiColvarBase17readGroupKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_S9_RKbSB_RSt6vectorINS_10AtomNumberESaISD_EE12
_ZN4PLMD11multicolvar15MultiColvarBase22setAtomsForCentralAtomERKSt6vectorIbSaIbEE19
_ZN4PLMD11multicolvar15MultiColvarBase20readAtomsLikeKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiRSt6vectorINS_10AtomNumberESaISD_EE49
_ZN4PLMD11multicolvar15MultiColvarBase13readTwoGroupsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RSt6vectorINS_10AtomNumberESaISB_EE77
_ZN4PLMD11multicolvar15MultiColvarBase21resizeBookeepingArrayERKjS3_97
_ZNK4PLMD11multicolvar15MultiColvarBase21splitInputDerivativesERKjS3_S3_S3_RKSt6vectorIdSaIdEERNS_10MultiValueERNS0_13AtomValuePackE106
_ZN4PLMD11multicolvar15MultiColvarBase17setLinkCellCutoffERKdd192
_ZN4PLMD11multicolvar15MultiColvarBase29calculateNumericalDerivativesEPNS_15ActionWithValueE213
_ZN4PLMD11multicolvar15MultiColvarBase20setupMultiColvarBaseERKSt6vectorINS_10AtomNumberESaIS3_EE310
_ZN4PLMD11multicolvar15MultiColvarBaseC2ERKNS_13ActionOptionsE352
_ZN4PLMD11multicolvar15MultiColvarBase17turnOnDerivativesEv461
_ZN4PLMD11multicolvar15MultiColvarBase18filtersUsedAsInputEv467
_ZN4PLMD11multicolvar15MultiColvarBase24parseMultiColvarAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiRSt6vectorINS_10AtomNumberESaISD_EE474
_ZN4PLMD11multicolvar15MultiColvarBase16registerKeywordsERNS_8KeywordsE502
_ZN4PLMD11multicolvar15MultiColvarBase14setupLinkCellsEv1940
_ZN4PLMD11multicolvar15MultiColvarBase5applyEv1996
_ZN4PLMD11multicolvar15MultiColvarBase7prepareEv2961
_ZN4PLMD11multicolvar15MultiColvarBase27setupNonUseSpeciesLinkCellsERKj4629
_ZN4PLMD11multicolvar15MultiColvarBase13retrieveAtomsEv6551
_ZN4PLMD11multicolvar15MultiColvarBase9calculateEv9026
_ZN4PLMD11multicolvar15MultiColvarBase18setupActiveTaskSetERSt6vectorIjSaIjEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9075
_ZNK4PLMD11multicolvar15MultiColvarBase21mergeInputDerivativesERKjS3_S3_S3_RKSt6vectorIdSaIdEERNS_10MultiValueERNS0_13AtomValuePackE38245
_ZNK4PLMD11multicolvar15MultiColvarBase19getInputDerivativesERKjRKbRKNS0_13AtomValuePackE54449
_ZNK4PLMD11multicolvar15MultiColvarBase8applyPbcERSt6vectorINS_13VectorGenericILj3EEESaIS4_EEj222049
_ZNK4PLMD11multicolvar15MultiColvarBase15calculateWeightERKjRKdRNS0_13AtomValuePackE244248
_ZNK4PLMD11multicolvar15MultiColvarBase18decodeIndexToAtomsERKjRSt6vectorIjSaIjEE245988
_ZNK4PLMD11multicolvar15MultiColvarBase11performTaskERKjS3_RNS_10MultiValueE449362
_ZNK4PLMD11multicolvar15MultiColvarBase20setupCurrentAtomListERKjRNS0_13AtomValuePackE452891
_ZN4PLMD11multicolvar15MultiColvarBase18getCentralAtomPackERKjS3_RNS0_9CatomPackE642832
_ZNK4PLMD11multicolvar15MultiColvarBase17updateActiveAtomsERNS0_13AtomValuePackE662396
_ZNK4PLMD11multicolvar15MultiColvarBase17addComDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE980606
_ZNK4PLMD11multicolvar15MultiColvarBase12getInputDataERKjRKbRKNS0_13AtomValuePackERSt6vectorIdSaIdEE1124044
_ZNK4PLMD11multicolvar15MultiColvarBase18addAtomDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE1503319
_ZN4PLMD11multicolvar15MultiColvarBase17getCentralAtomPosERKj2558087
_ZN4PLMD11multicolvar15MultiColvarBase13addTaskToListERKj12512704
_ZNK4PLMD11multicolvar15MultiColvarBase26accumulateSymmetryFunctionERKiRKjRKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERNS0_13AtomValuePackE65138769
_ZNK4PLMD11multicolvar15MultiColvarBase13getSeparationERKNS_13VectorGenericILj3EEES5_121150995
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.cpp.func.html b/coverage/multicolvar/MultiColvarBase.cpp.func.html new file mode 100644 index 000000000000..82e82aaa465d --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.cpp.func.html @@ -0,0 +1,237 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:58365289.4 %
Date:2024-02-22 21:58:45Functions:404197.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15MultiColvarBase13addTaskToListERKj12512704
_ZN4PLMD11multicolvar15MultiColvarBase13readTwoGroupsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RSt6vectorINS_10AtomNumberESaISB_EE77
_ZN4PLMD11multicolvar15MultiColvarBase13retrieveAtomsEv6551
_ZN4PLMD11multicolvar15MultiColvarBase14setupLinkCellsEv1940
_ZN4PLMD11multicolvar15MultiColvarBase15readThreeGroupsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_RKbSB_RSt6vectorINS_10AtomNumberESaISD_EE10
_ZN4PLMD11multicolvar15MultiColvarBase16registerKeywordsERNS_8KeywordsE502
_ZN4PLMD11multicolvar15MultiColvarBase17getCentralAtomPosERKj2558087
_ZN4PLMD11multicolvar15MultiColvarBase17readGroupKeywordsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_S9_S9_RKbSB_RSt6vectorINS_10AtomNumberESaISD_EE12
_ZN4PLMD11multicolvar15MultiColvarBase17setLinkCellCutoffERKdd192
_ZN4PLMD11multicolvar15MultiColvarBase17turnOnDerivativesEv461
_ZN4PLMD11multicolvar15MultiColvarBase18filtersUsedAsInputEv467
_ZN4PLMD11multicolvar15MultiColvarBase18getCentralAtomPackERKjS3_RNS0_9CatomPackE642832
_ZN4PLMD11multicolvar15MultiColvarBase18setupActiveTaskSetERSt6vectorIjSaIjEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE9075
_ZN4PLMD11multicolvar15MultiColvarBase20readAtomsLikeKeywordERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiRSt6vectorINS_10AtomNumberESaISD_EE49
_ZN4PLMD11multicolvar15MultiColvarBase20setupMultiColvarBaseERKSt6vectorINS_10AtomNumberESaIS3_EE310
_ZN4PLMD11multicolvar15MultiColvarBase21resizeBookeepingArrayERKjS3_97
_ZN4PLMD11multicolvar15MultiColvarBase22setAtomsForCentralAtomERKSt6vectorIbSaIbEE19
_ZN4PLMD11multicolvar15MultiColvarBase24parseMultiColvarAtomListERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKiRSt6vectorINS_10AtomNumberESaISD_EE474
_ZN4PLMD11multicolvar15MultiColvarBase27setupNonUseSpeciesLinkCellsERKj4629
_ZN4PLMD11multicolvar15MultiColvarBase29calculateNumericalDerivativesEPNS_15ActionWithValueE213
_ZN4PLMD11multicolvar15MultiColvarBase5applyEv1996
_ZN4PLMD11multicolvar15MultiColvarBase7prepareEv2961
_ZN4PLMD11multicolvar15MultiColvarBase9buildSetsEv4
_ZN4PLMD11multicolvar15MultiColvarBase9calculateEv9026
_ZN4PLMD11multicolvar15MultiColvarBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15MultiColvarBaseC2ERKNS_13ActionOptionsE352
_ZNK4PLMD11multicolvar15MultiColvarBase11performTaskERKjS3_RNS_10MultiValueE449362
_ZNK4PLMD11multicolvar15MultiColvarBase12getInputDataERKjRKbRKNS0_13AtomValuePackERSt6vectorIdSaIdEE1124044
_ZNK4PLMD11multicolvar15MultiColvarBase13getSeparationERKNS_13VectorGenericILj3EEES5_121150995
_ZNK4PLMD11multicolvar15MultiColvarBase15calculateWeightERKjRKdRNS0_13AtomValuePackE244248
_ZNK4PLMD11multicolvar15MultiColvarBase17addComDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE980606
_ZNK4PLMD11multicolvar15MultiColvarBase17getLinkCellCutoffEv8
_ZNK4PLMD11multicolvar15MultiColvarBase17updateActiveAtomsERNS0_13AtomValuePackE662396
_ZNK4PLMD11multicolvar15MultiColvarBase18addAtomDerivativesERKiRKjRKNS_13VectorGenericILj3EEERNS0_13AtomValuePackE1503319
_ZNK4PLMD11multicolvar15MultiColvarBase18decodeIndexToAtomsERKjRSt6vectorIjSaIjEE245988
_ZNK4PLMD11multicolvar15MultiColvarBase19getInputDerivativesERKjRKbRKNS0_13AtomValuePackE54449
_ZNK4PLMD11multicolvar15MultiColvarBase20setupCurrentAtomListERKjRNS0_13AtomValuePackE452891
_ZNK4PLMD11multicolvar15MultiColvarBase21mergeInputDerivativesERKjS3_S3_S3_RKSt6vectorIdSaIdEERNS_10MultiValueERNS0_13AtomValuePackE38245
_ZNK4PLMD11multicolvar15MultiColvarBase21splitInputDerivativesERKjS3_S3_S3_RKSt6vectorIdSaIdEERNS_10MultiValueERNS0_13AtomValuePackE106
_ZNK4PLMD11multicolvar15MultiColvarBase26accumulateSymmetryFunctionERKiRKjRKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERNS0_13AtomValuePackE65138769
_ZNK4PLMD11multicolvar15MultiColvarBase8applyPbcERSt6vectorINS_13VectorGenericILj3EEESaIS4_EEj222049
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.cpp.gcov.html b/coverage/multicolvar/MultiColvarBase.cpp.gcov.html new file mode 100644 index 000000000000..4b29f13890ee --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.cpp.gcov.html @@ -0,0 +1,1165 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:58365289.4 %
Date:2024-02-22 21:58:45Functions:404197.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "ActionVolume.h"
+      24             : #include "MultiColvarFilter.h"
+      25             : #include "vesselbase/Vessel.h"
+      26             : #include "vesselbase/BridgeVessel.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include "core/ActionSet.h"
+      29             : #include "tools/Pbc.h"
+      30             : #include "AtomValuePack.h"
+      31             : #include <vector>
+      32             : #include <string>
+      33             : #include <limits>
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace multicolvar {
+      37             : 
+      38         502 : void MultiColvarBase::registerKeywords( Keywords& keys ) {
+      39         502 :   Action::registerKeywords( keys );
+      40         502 :   ActionWithValue::registerKeywords( keys );
+      41         502 :   ActionAtomistic::registerKeywords( keys );
+      42        1004 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+      43         502 :   ActionWithVessel::registerKeywords( keys );
+      44        1004 :   keys.add("hidden","NL_STRIDE","the frequency with which the neighbor list should be updated. Between neighbour list update steps all quantities "
+      45             :            "that contributed less than TOL at the previous neighbor list update step are ignored.");
+      46         502 :   keys.setComponentsIntroduction("When the label of this action is used as the input for a second you are not referring to a scalar quantity as you are in "
+      47             :                                  "regular collective variables.  The label is used to reference the full set of quantities calculated by "
+      48             :                                  "the action.  This is usual when using \\ref multicolvarfunction. Generally when doing this the previously calculated "
+      49             :                                  "multicolvar will be referenced using the DATA keyword rather than ARG.\n\n"
+      50             :                                  "This Action can be used to calculate the following scalar quantities directly.  These quantities are calculated by "
+      51             :                                  "employing the keywords listed below. "
+      52             :                                  "These quantities can then be referenced elsewhere in the input file by using this Action's label "
+      53             :                                  "followed by a dot and the name of the quantity. Some of them can be calculated multiple times "
+      54             :                                  "with different parameters.  In this case the quantities calculated can be referenced elsewhere in the "
+      55             :                                  "input by using the name of the quantity followed by a numerical identifier "
+      56             :                                  "e.g. <em>label</em>.lessthan-1, <em>label</em>.lessthan-2 etc.  When doing this and, for clarity we have "
+      57             :                                  "made it so that the user can set a particular label for each of the components. As such by using the LABEL keyword in the description of the keyword "
+      58             :                                  "input you can customize the component name");
+      59        1004 :   keys.reserve("atoms-3","SPECIES","this keyword is used for colvars such as coordination number. In that context it specifies that plumed should calculate "
+      60             :                "one coordination number for each of the atoms specified.  Each of these coordination numbers specifies how many of the "
+      61             :                "other specified atoms are within a certain cutoff of the central atom.  You can specify the atoms here as another multicolvar "
+      62             :                "action or using a MultiColvarFilter or ActionVolume action.  When you do so the quantity is calculated for those atoms specified "
+      63             :                "in the previous multicolvar.  This is useful if you would like to calculate the Steinhardt parameter for those atoms that have a "
+      64             :                "coordination number more than four for example");
+      65        1004 :   keys.reserve("atoms-4","SPECIESA","this keyword is used for colvars such as the coordination number.  In that context it species that plumed should calculate "
+      66             :                "one coordination number for each of the atoms specified in SPECIESA.  Each of these coordination numbers specifies how many "
+      67             :                "of the atoms specifies using SPECIESB is within the specified cutoff.  As with the species keyword the input can also be specified "
+      68             :                "using the label of another multicolvar");
+      69        1004 :   keys.reserve("atoms-4","SPECIESB","this keyword is used for colvars such as the coordination number.  It must appear with SPECIESA.  For a full explanation see "
+      70             :                "the documentation for that keyword");
+      71        1004 :   keys.add("hidden","ALL_INPUT_SAME_TYPE","remove this keyword to remove certain checks in the input on the sanity of your input file.  See code for details");
+      72         502 : }
+      73             : 
+      74         352 : MultiColvarBase::MultiColvarBase(const ActionOptions&ao):
+      75             :   Action(ao),
+      76             :   ActionAtomistic(ao),
+      77             :   ActionWithValue(ao),
+      78             :   ActionWithVessel(ao),
+      79         352 :   usepbc(false),
+      80         352 :   allthirdblockintasks(false),
+      81         352 :   uselinkforthree(false),
+      82         352 :   linkcells(comm),
+      83         352 :   threecells(comm),
+      84         352 :   setup_completed(false),
+      85         352 :   atomsWereRetrieved(false),
+      86         352 :   matsums(false),
+      87         352 :   usespecies(false),
+      88         704 :   nblock(0)
+      89             : {
+      90         704 :   if( keywords.exists("NOPBC") ) {
+      91         352 :     bool nopbc=!usepbc; parseFlag("NOPBC",nopbc);
+      92         352 :     usepbc=!nopbc;
+      93             :   }
+      94         704 :   if( keywords.exists("SPECIESA") ) { matsums=usespecies=true; }
+      95         352 : }
+      96             : 
+      97          49 : void MultiColvarBase::readAtomsLikeKeyword( const std::string & key, const int& natoms, std::vector<AtomNumber>& all_atoms ) {
+      98          49 :   plumed_assert( !usespecies );
+      99          49 :   if( all_atoms.size()>0 ) return;
+     100             : 
+     101             :   std::vector<AtomNumber> t;
+     102          49 :   for(int i=1;; ++i ) {
+     103         973 :     parseAtomList(key, i, t );
+     104         973 :     if( t.empty() ) break;
+     105             : 
+     106         924 :     log.printf("  Colvar %d is calculated from atoms : ", i);
+     107        3456 :     for(unsigned j=0; j<t.size(); ++j) log.printf("%d ",t[j].serial() );
+     108         924 :     log.printf("\n");
+     109             : 
+     110         924 :     if( i==1 && natoms<0 ) { ablocks.resize(t.size()); }
+     111         918 :     else if( i==1 ) ablocks.resize(natoms);
+     112         924 :     if( t.size()!=ablocks.size() ) {
+     113           0 :       std::string ss; Tools::convert(i,ss);
+     114           0 :       error(key + ss + " keyword has the wrong number of atoms");
+     115             :     }
+     116        3456 :     for(unsigned j=0; j<ablocks.size(); ++j) {
+     117        2532 :       ablocks[j].push_back( ablocks.size()*(i-1)+j ); all_atoms.push_back( t[j] );
+     118        2532 :       atom_lab.push_back( std::pair<unsigned,unsigned>( 0, ablocks.size()*(i-1)+j ) );
+     119             :     }
+     120         924 :     t.resize(0);
+     121         924 :   }
+     122          49 :   if( all_atoms.size()>0 ) {
+     123          49 :     nblock=0;
+     124         973 :     for(unsigned i=0; i<ablocks[0].size(); ++i) addTaskToList( i );
+     125             :   }
+     126             : }
+     127             : 
+     128         474 : bool MultiColvarBase::parseMultiColvarAtomList(const std::string& key, const int& num, std::vector<AtomNumber>& t) {
+     129             :   std::vector<std::string> mlabs;
+     130         474 :   if( num<0 ) parseVector(key,mlabs);
+     131           0 :   else parseNumberedVector(key,num,mlabs);
+     132             : 
+     133         474 :   if( mlabs.size()==0 ) return false;
+     134             : 
+     135         323 :   std::string mname; unsigned found_mcolv=mlabs.size();
+     136         450 :   for(unsigned i=0; i<mlabs.size(); ++i) {
+     137         328 :     MultiColvarBase* mycolv = plumed.getActionSet().selectWithLabel<MultiColvarBase*>(mlabs[i]);
+     138         328 :     if(!mycolv) { found_mcolv=i; break; }
+     139             :     // Check all base multicolvars are of same type
+     140         127 :     if( i==0 ) {
+     141         122 :       mname = mycolv->getName();
+     142         244 :       if( keywords.exists("ALL_INPUT_SAME_TYPE") && mycolv->isPeriodic() ) error("multicolvar functions don't work with this multicolvar");
+     143             :     } else {
+     144          10 :       if( keywords.exists("ALL_INPUT_SAME_TYPE") && mname!=mycolv->getName() ) error("All input multicolvars must be of same type");
+     145             :     }
+     146             :     // And track which variable stores each colvar
+     147     4458438 :     for(unsigned j=0; j<mycolv->getFullNumberOfTasks(); ++j) atom_lab.push_back( std::pair<unsigned,unsigned>( mybasemulticolvars.size()+1, j ) );
+     148             :     // And store the multicolvar base
+     149         127 :     mybasemulticolvars.push_back( mycolv );
+     150             :     // And create a basedata stash
+     151         127 :     mybasedata.push_back( mybasemulticolvars[mybasemulticolvars.size()-1]->buildDataStashes( this ) );
+     152             :     // Check if weight has derivatives
+     153         127 :     if( mybasemulticolvars[ mybasemulticolvars.size()-1 ]->weightHasDerivatives ) weightHasDerivatives=true;
+     154         127 :     plumed_assert( mybasemulticolvars.size()==mybasedata.size() );
+     155             :   }
+     156             :   // Have we conventional atoms to read in
+     157         323 :   if( found_mcolv==0 ) {
+     158         201 :     std::vector<AtomNumber> tt; ActionAtomistic::interpretAtomList( mlabs, tt );
+     159       89846 :     for(unsigned i=0; i<tt.size(); ++i) { atom_lab.push_back( std::pair<unsigned,unsigned>( 0, t.size() + i ) ); }
+     160         201 :     log.printf("  keyword %s takes atoms : ", key.c_str() );
+     161       89846 :     for(unsigned i=0; i<tt.size(); ++i) { t.push_back( tt[i] ); log.printf("%d ",tt[i].serial() ); }
+     162         201 :     log.printf("\n");
+     163         122 :   } else if( found_mcolv==mlabs.size() ) {
+     164         122 :     if( checkNumericalDerivatives() ) error("cannot use NUMERICAL_DERIVATIVES keyword with dynamic groups as input");
+     165         122 :     log.printf("  keyword %s takes dynamic groups of atoms constructed from multicolvars labelled : ", key.c_str() );
+     166         249 :     for(unsigned i=0; i<mlabs.size(); ++i) log.printf("%s ",mlabs[i].c_str() );
+     167         122 :     log.printf("\n");
+     168           0 :   } else if( found_mcolv<mlabs.size() ) {
+     169           0 :     error("cannot mix multicolvar input and atom input in one line");
+     170             :   }
+     171             :   return true;
+     172         474 : }
+     173             : 
+     174          77 : void MultiColvarBase::readTwoGroups( const std::string& key0, const std::string& key1, const std::string& key2, std::vector<AtomNumber>& all_atoms ) {
+     175          77 :   plumed_dbg_assert( keywords.exists(key0) && keywords.exists(key1) && keywords.exists(key2) ); ablocks.resize( 2 );
+     176             : 
+     177          77 :   if( parseMultiColvarAtomList(key0,-1,all_atoms) ) {
+     178          78 :     nblock=atom_lab.size(); for(unsigned i=0; i<2; ++i) ablocks[i].resize(nblock);
+     179          26 :     resizeBookeepingArray( nblock, nblock );
+     180        5486 :     for(unsigned i=0; i<nblock; ++i) ablocks[0][i]=ablocks[1][i]=i;
+     181        5460 :     for(unsigned i=1; i<nblock; ++i) {
+     182     4216329 :       for(unsigned j=0; j<i; ++j) {
+     183     4210895 :         bookeeping(i,j).first=getFullNumberOfTasks();
+     184     4210895 :         addTaskToList( i*nblock + j );
+     185     4210895 :         bookeeping(i,j).second=getFullNumberOfTasks();
+     186             :       }
+     187             :     }
+     188             :   } else {
+     189          51 :     parseMultiColvarAtomList(key1,-1,all_atoms);
+     190          68 :     ablocks[0].resize( atom_lab.size() ); for(unsigned i=0; i<ablocks[0].size(); ++i) ablocks[0][i]=i;
+     191          51 :     parseMultiColvarAtomList(key2,-1,all_atoms);
+     192        1120 :     ablocks[1].resize( atom_lab.size() - ablocks[0].size() ); for(unsigned i=0; i<ablocks[1].size(); ++i) ablocks[1][i]=ablocks[0].size() + i;
+     193             : 
+     194          51 :     if( ablocks[0].size()>ablocks[1].size() ) nblock = ablocks[0].size();
+     195          51 :     else nblock=ablocks[1].size();
+     196             : 
+     197          51 :     resizeBookeepingArray( ablocks[0].size(), ablocks[1].size() );
+     198          68 :     for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     199        1126 :       for(unsigned j=0; j<ablocks[1].size(); ++j) {
+     200        1109 :         bookeeping(i,j).first=getFullNumberOfTasks();
+     201        1109 :         if( atom_lab[ablocks[0][i]].first>0 && atom_lab[ablocks[1][j]].first>0 ) {
+     202           0 :           if( mybasemulticolvars[atom_lab[ablocks[0][i]].first-1]->getLabel()!=mybasemulticolvars[atom_lab[ablocks[1][j]].first-1]->getLabel() &&
+     203           0 :               atom_lab[ablocks[0][i]].second!=atom_lab[ablocks[1][j]].second ) addTaskToList( i*nblock + j );
+     204        1109 :         } else if( all_atoms[atom_lab[ablocks[0][i]].second]!=all_atoms[atom_lab[ablocks[1][j]].second] ) addTaskToList( i*nblock + j );
+     205        1109 :         bookeeping(i,j).second=getFullNumberOfTasks();
+     206             :       }
+     207             :     }
+     208             :   }
+     209          77 : }
+     210             : 
+     211          12 : void MultiColvarBase::readGroupKeywords( const std::string& key0, const std::string& key1, const std::string& key2, const std::string& key3,
+     212             :     const bool& no_third_dim_accum, const bool& symmetric, std::vector<AtomNumber>& all_atoms ) {
+     213          12 :   plumed_dbg_assert( keywords.exists(key0) && keywords.exists(key1) && keywords.exists(key2) && keywords.exists(key3) ); ablocks.resize( 3 );
+     214             : 
+     215          12 :   if( parseMultiColvarAtomList(key0,-1,all_atoms) ) {
+     216          10 :     if( no_third_dim_accum ) {
+     217          10 :       nblock=atom_lab.size(); ablocks[0].resize(nblock); ablocks[1].resize( nblock );
+     218        1481 :       for(unsigned i=0; i<ablocks[0].size(); ++i) ablocks[0][i]=ablocks[1][i]=i;
+     219          10 :       resizeBookeepingArray( nblock, nblock );
+     220          10 :       if( symmetric ) {
+     221             :         // This ensures that later parts of the code don't switch off allthirdblockintasks
+     222        1343 :         for(unsigned i=0; i<nblock; ++i) { bookeeping(i,i).first=0; bookeeping(i,i).second=1; }
+     223        1337 :         for(unsigned i=1; i<nblock; ++i) {
+     224      222447 :           for(unsigned j=0; j<i; ++j) {
+     225      221116 :             bookeeping(j,i).first=bookeeping(i,j).first=getFullNumberOfTasks();
+     226      221116 :             addTaskToList( i*nblock + j );
+     227      221116 :             bookeeping(j,i).second=bookeeping(i,j).second=getFullNumberOfTasks();
+     228             :           }
+     229             :         }
+     230             :       } else {
+     231         138 :         for(unsigned i=0; i<nblock; ++i) {
+     232        8344 :           for(unsigned j=0; j<nblock; ++j) {
+     233        8210 :             if( i==j ) continue ;
+     234        8076 :             bookeeping(i,j).first=getFullNumberOfTasks();
+     235        8076 :             addTaskToList( i*nblock + j );
+     236        8076 :             bookeeping(i,j).second=getFullNumberOfTasks();
+     237             :           }
+     238             :         }
+     239             :       }
+     240          10 :       if( !parseMultiColvarAtomList(key3,-1,all_atoms) ) error("missing required keyword " + key3 + " in input");
+     241          10 :       ablocks[2].resize( atom_lab.size() - ablocks[0].size() );
+     242       49845 :       for(unsigned i=0; i<ablocks[2].size(); ++i) ablocks[2][i]=ablocks[0].size() + i;
+     243             :     } else {
+     244           0 :       nblock=atom_lab.size(); for(unsigned i=0; i<3; ++i) ablocks[i].resize(nblock);
+     245           0 :       resizeBookeepingArray( nblock, nblock );
+     246           0 :       for(unsigned i=0; i<nblock; ++i) { ablocks[0][i]=i; ablocks[1][i]=i; ablocks[2][i]=i; }
+     247           0 :       if( symmetric ) {
+     248           0 :         for(unsigned i=2; i<nblock; ++i) {
+     249           0 :           for(unsigned j=1; j<i; ++j) {
+     250           0 :             bookeeping(i,j).first=getFullNumberOfTasks();
+     251           0 :             for(unsigned k=0; k<j; ++k) addTaskToList( i*nblock*nblock + j*nblock + k );
+     252           0 :             bookeeping(i,j).second=getFullNumberOfTasks();
+     253             :           }
+     254             :         }
+     255             :       } else {
+     256           0 :         for(unsigned i=0; i<nblock; ++i) {
+     257           0 :           for(unsigned j=0; j<nblock; ++j) {
+     258           0 :             if( i==j ) continue;
+     259           0 :             bookeeping(i,j).first=getFullNumberOfTasks();
+     260           0 :             for(unsigned k=0; k<nblock; ++k) {
+     261           0 :               if( i!=k && j!=k ) addTaskToList( i*nblock*nblock + j*nblock + k );
+     262             :             }
+     263           0 :             bookeeping(i,j).first=getFullNumberOfTasks();
+     264             :           }
+     265             :         }
+     266             :       }
+     267             :     }
+     268             :   } else {
+     269           2 :     readThreeGroups( key1, key2, key3, true, no_third_dim_accum, all_atoms );
+     270             :   }
+     271             : 
+     272          12 : }
+     273             : 
+     274          10 : void MultiColvarBase::readThreeGroups( const std::string& key1, const std::string& key2, const std::string& key3,
+     275             :                                        const bool& allow2, const bool& no_third_dim_accum, std::vector<AtomNumber>& all_atoms ) {
+     276          10 :   plumed_dbg_assert( keywords.exists(key1) && keywords.exists(key2) && keywords.exists(key3) ); ablocks.resize( 3 );
+     277             : 
+     278          10 :   bool readkey1=parseMultiColvarAtomList(key1,-1,all_atoms);
+     279          31 :   ablocks[0].resize( atom_lab.size() ); for(unsigned i=0; i<ablocks[0].size(); ++i) ablocks[0][i]=i;
+     280          10 :   bool readkey2=parseMultiColvarAtomList(key2,-1,all_atoms);
+     281          10 :   if( !readkey1 && !readkey2 ) return ;
+     282         225 :   ablocks[1].resize( atom_lab.size() - ablocks[0].size() ); for(unsigned i=0; i<ablocks[1].size(); ++i) ablocks[1][i]=ablocks[0].size() + i;
+     283             : 
+     284          10 :   resizeBookeepingArray( ablocks[0].size(), ablocks[1].size() );
+     285          10 :   bool readkey3=parseMultiColvarAtomList(key3,-1,all_atoms);
+     286          10 :   if( !readkey3 && !allow2 ) {
+     287           0 :     error("missing atom specification " + key3);
+     288          10 :   } else if( !readkey3 ) {
+     289           2 :     if( ablocks[1].size()>ablocks[0].size() ) nblock=ablocks[1].size();
+     290           0 :     else nblock=ablocks[0].size();
+     291             : 
+     292           2 :     ablocks[2].resize( ablocks[1].size() );
+     293         200 :     for(unsigned i=0; i<ablocks[1].size(); ++i) ablocks[2][i]=ablocks[0].size() + i;
+     294           4 :     for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     295         198 :       for(unsigned j=1; j<ablocks[1].size(); ++j) {
+     296         196 :         bookeeping(i,j).first=getFullNumberOfTasks();
+     297        9898 :         for(unsigned k=0; k<j; ++k) {
+     298        9702 :           if( atom_lab[ablocks[0][i]].first>0 && atom_lab[ablocks[1][j]].first>0 && atom_lab[ablocks[2][k]].first>0 ) {
+     299           0 :             if( mybasemulticolvars[atom_lab[ablocks[0][i]].first-1]->getLabel()!=mybasemulticolvars[atom_lab[ablocks[1][j]].first-1]->getLabel() &&
+     300           0 :                 mybasemulticolvars[atom_lab[ablocks[0][i]].first-1]->getLabel()!=mybasemulticolvars[atom_lab[ablocks[2][k]].first-1]->getLabel() &&
+     301           0 :                 mybasemulticolvars[atom_lab[ablocks[1][j]].first-1]->getLabel()!=mybasemulticolvars[atom_lab[ablocks[2][k]].first-1]->getLabel() &&
+     302           0 :                 atom_lab[ablocks[0][i]].second!=atom_lab[ablocks[1][j]].second && atom_lab[ablocks[0][i]].second!=atom_lab[ablocks[2][k]].second &&
+     303           0 :                 atom_lab[ablocks[1][j]].second!=atom_lab[ablocks[2][k]].second )  addTaskToList( nblock*nblock*i + nblock*j + k );
+     304        9702 :           } else if( all_atoms[atom_lab[ablocks[0][i]].second]!=all_atoms[atom_lab[ablocks[1][j]].second] &&
+     305        9702 :                      all_atoms[atom_lab[ablocks[0][i]].second]!=all_atoms[atom_lab[ablocks[2][k]].second] &&
+     306        9702 :                      all_atoms[atom_lab[ablocks[1][j]].second]!=all_atoms[atom_lab[ablocks[2][k]].second] ) addTaskToList( nblock*nblock*i + nblock*j + k );
+     307             :         }
+     308         196 :         bookeeping(i,j).second=getFullNumberOfTasks();
+     309             :       }
+     310             :     }
+     311             :   } else {
+     312           8 :     ablocks[2].resize( atom_lab.size() - ablocks[1].size() - ablocks[0].size() );
+     313        3182 :     for(unsigned i=0; i<ablocks[2].size(); ++i) ablocks[2][i] = ablocks[0].size() + ablocks[1].size() + i;
+     314             : 
+     315           8 :     if( ablocks[1].size()>ablocks[0].size() ) nblock=ablocks[1].size();
+     316           8 :     else nblock=ablocks[0].size();
+     317           8 :     if( ablocks[2].size()>nblock ) nblock=ablocks[2].size();
+     318             : 
+     319           8 :     unsigned  kcount; if( no_third_dim_accum ) kcount=1; else kcount=ablocks[2].size();
+     320             : 
+     321          27 :     for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     322         128 :       for(unsigned j=0; j<ablocks[1].size(); ++j) {
+     323         109 :         bookeeping(i,j).first=getFullNumberOfTasks();
+     324         218 :         for(unsigned k=0; k<kcount; ++k) {
+     325         109 :           if( no_third_dim_accum ) addTaskToList( nblock*i + j  );
+     326           0 :           else if( atom_lab[ablocks[0][i]].first>0 && atom_lab[ablocks[1][j]].first>0 && atom_lab[ablocks[2][k]].first>0 ) {
+     327           0 :             if( mybasemulticolvars[atom_lab[ablocks[0][i]].first-1]->getLabel()!=mybasemulticolvars[atom_lab[ablocks[1][j]].first-1]->getLabel() &&
+     328           0 :                 mybasemulticolvars[atom_lab[ablocks[0][i]].first-1]->getLabel()!=mybasemulticolvars[atom_lab[ablocks[2][k]].first-1]->getLabel() &&
+     329           0 :                 mybasemulticolvars[atom_lab[ablocks[1][j]].first-1]->getLabel()!=mybasemulticolvars[atom_lab[ablocks[2][k]].first-1]->getLabel() &&
+     330           0 :                 atom_lab[ablocks[0][i]].second!=atom_lab[ablocks[1][j]].second && atom_lab[ablocks[0][i]].second!=atom_lab[ablocks[2][k]].second &&
+     331           0 :                 atom_lab[ablocks[1][j]].second!=atom_lab[ablocks[2][k]].second ) addTaskToList( nblock*nblock*i + nblock*j + k );
+     332           0 :           } else if( all_atoms[atom_lab[ablocks[0][i]].second]!=all_atoms[atom_lab[ablocks[1][j]].second] &&
+     333           0 :                      all_atoms[atom_lab[ablocks[0][i]].second]!=all_atoms[atom_lab[ablocks[2][k]].second] &&
+     334           0 :                      all_atoms[atom_lab[ablocks[1][j]].second]!=all_atoms[atom_lab[ablocks[2][k]].second] ) addTaskToList( nblock*nblock*i + nblock*j + k );
+     335             :         }
+     336         109 :         bookeeping(i,j).second=getFullNumberOfTasks();
+     337             :       }
+     338             :     }
+     339             :   }
+     340             : }
+     341             : 
+     342           4 : void MultiColvarBase::buildSets() {
+     343             :   std::vector<AtomNumber> fake_atoms;
+     344           8 :   if( !parseMultiColvarAtomList("DATA",-1,fake_atoms) ) error("missing DATA keyword");
+     345           4 :   if( fake_atoms.size()>0 ) error("no atoms should appear in the specification for this object.  Input should be other multicolvars");
+     346             : 
+     347           4 :   nblock = mybasemulticolvars[0]->getFullNumberOfTasks();
+     348          11 :   for(unsigned i=0; i<mybasemulticolvars.size(); ++i) {
+     349           7 :     if( mybasemulticolvars[i]->getFullNumberOfTasks()!=nblock ) {
+     350           0 :       error("mismatch between numbers of tasks in various base multicolvars");
+     351             :     }
+     352             :   }
+     353           4 :   ablocks.resize( mybasemulticolvars.size() ); usespecies=false;
+     354          11 :   for(unsigned i=0; i<mybasemulticolvars.size(); ++i) {
+     355           7 :     ablocks[i].resize( nblock );
+     356          27 :     for(unsigned j=0; j<nblock; ++j) ablocks[i][j]=i*nblock+j;
+     357             :   }
+     358          15 :   for(unsigned i=0; i<nblock; ++i) {
+     359          11 :     if( mybasemulticolvars.size()<4 ) {
+     360          11 :       unsigned cvcode=0, tmpc=1;
+     361          31 :       for(unsigned j=0; j<ablocks.size(); ++j) { cvcode += i*tmpc; tmpc *= nblock; }
+     362          11 :       addTaskToList( cvcode );
+     363             :     } else {
+     364           0 :       addTaskToList( i );
+     365             :     }
+     366             :   }
+     367           4 :   mybasedata[0]->resizeTemporyMultiValues( mybasemulticolvars.size() ); setupMultiColvarBase( fake_atoms );
+     368           4 : }
+     369             : 
+     370    12512704 : void MultiColvarBase::addTaskToList( const unsigned& taskCode ) {
+     371    12512704 :   plumed_assert( getNumberOfVessels()==0 );
+     372    12512704 :   ActionWithVessel::addTaskToList( taskCode );
+     373    12512704 : }
+     374             : 
+     375          97 : void MultiColvarBase::resizeBookeepingArray( const unsigned& num1, const unsigned& num2 ) {
+     376          97 :   bookeeping.resize( num1, num2 );
+     377        7066 :   for(unsigned i=0; i<num1; ++i) {
+     378     8887414 :     for(unsigned j=0; j<num2; ++j) { bookeeping(i,j).first=0; bookeeping(i,j).second=0; }
+     379             :   }
+     380          97 : }
+     381             : 
+     382         310 : void MultiColvarBase::setupMultiColvarBase( const std::vector<AtomNumber>& atoms ) {
+     383         310 :   if( !matsums && atom_lab.size()==0 ) error("No atoms have been read in");
+     384             :   std::vector<AtomNumber> all_atoms;
+     385             :   // Setup decoder array
+     386         310 :   if( !usespecies && nblock>0 ) {
+     387             : 
+     388          63 :     ncentral=ablocks.size(); use_for_central_atom.resize( ablocks.size(), true );
+     389          63 :     numberForCentralAtom = 1.0 / static_cast<double>( ablocks.size() );
+     390          63 :     if( ablocks.size()==3 ) {
+     391          20 :       allthirdblockintasks=uselinkforthree=true;
+     392        1512 :       for(unsigned i=0; i<bookeeping.nrows(); ++i) {
+     393      453578 :         for(unsigned j=0; j<bookeeping.ncols(); ++j) {
+     394      452086 :           unsigned ntper = bookeeping(i,j).second - bookeeping(i,j).first;
+     395      452086 :           if( i==j && ntper==0 ) {
+     396         136 :             continue;
+     397      451950 :           } else if( ntper == 1 && allthirdblockintasks ) {
+     398      451756 :             allthirdblockintasks=true;
+     399         194 :           } else if( ntper != ablocks[2].size() ) {
+     400         194 :             allthirdblockintasks=uselinkforthree=false;
+     401             :           } else {
+     402           0 :             allthirdblockintasks=false;
+     403             :           }
+     404             :         }
+     405             :       }
+     406             :     }
+     407             : 
+     408          63 :     if( allthirdblockintasks ) {
+     409          18 :       decoder.resize(2); plumed_assert( ablocks.size()==3 );
+     410             :       // Check if number of atoms is too large
+     411          18 :       if( std::pow( double(nblock), 2.0 )>std::numeric_limits<unsigned>::max() ) error("number of atoms in groups is too big for PLUMED to handle");
+     412             :     } else {
+     413          45 :       decoder.resize( ablocks.size() );
+     414             :       // Check if number of atoms is too large
+     415          45 :       if( std::pow( double(nblock), double(ablocks.size()) )>std::numeric_limits<unsigned>::max() ) error("number of atoms in groups is too big for PLUMED to handle");
+     416             :     }
+     417         190 :     unsigned code=1; for(unsigned i=0; i<decoder.size(); ++i) { decoder[decoder.size()-1-i]=code; code *= nblock; }
+     418         247 :   } else if( !usespecies ) {
+     419          88 :     ncentral=ablocks.size(); use_for_central_atom.resize( ablocks.size(), true );
+     420          88 :     numberForCentralAtom = 1.0 / static_cast<double>( ablocks.size() );
+     421         318 :   } else if( keywords.exists("SPECIESA") ) {
+     422         101 :     plumed_assert( atom_lab.size()==0 && all_atoms.size()==0 );
+     423         101 :     ablocks.resize( 1 ); bool readspecies=parseMultiColvarAtomList("SPECIES", -1, all_atoms);
+     424         101 :     if( readspecies ) {
+     425       41493 :       ablocks[0].resize( atom_lab.size() ); for(unsigned i=0; i<atom_lab.size(); ++i) { addTaskToList(i); ablocks[0][i]=i; }
+     426             :     } else {
+     427          40 :       if( !parseMultiColvarAtomList("SPECIESA", -1, all_atoms) ) error("missing SPECIES/SPECIESA keyword");
+     428          20 :       unsigned nat1=atom_lab.size();
+     429          40 :       if( !parseMultiColvarAtomList("SPECIESB", -1, all_atoms) ) error("missing SPECIESB keyword");
+     430          20 :       unsigned nat2=atom_lab.size() - nat1;
+     431             : 
+     432         759 :       for(unsigned i=0; i<nat1; ++i) addTaskToList(i);
+     433          20 :       ablocks[0].resize( nat2 );
+     434        3726 :       for(unsigned i=0; i<nat2; ++i) {
+     435             :         bool found=false; unsigned inum=0;
+     436      288729 :         for(unsigned j=0; j<nat1; ++j) {
+     437      285201 :           if( atom_lab[nat1+i].first>0 && atom_lab[j].first>0 ) {
+     438      252720 :             if( atom_lab[nat1+i].first==atom_lab[j].first &&
+     439           0 :                 mybasemulticolvars[atom_lab[nat1+i].first-1]->getAbsoluteIndexOfCentralAtom(atom_lab[nat1+i].second)==
+     440      252720 :                 mybasemulticolvars[atom_lab[j].first-1]->getAbsoluteIndexOfCentralAtom(atom_lab[j].second) ) { found=true; inum=j; break; }
+     441       32481 :           } else if( atom_lab[nat1+i].first>0 ) {
+     442           0 :             if( mybasemulticolvars[atom_lab[nat1+i].first-1]->getAbsoluteIndexOfCentralAtom(atom_lab[nat1+i].second)==
+     443           0 :                 all_atoms[atom_lab[j].second] ) { found=true; inum=nat1 + i; break; }
+     444       32481 :           } else if( atom_lab[j].first>0 ) {
+     445           0 :             if( all_atoms[atom_lab[nat1+i].second]==
+     446           0 :                 mybasemulticolvars[atom_lab[j].first-1]->getAbsoluteIndexOfCentralAtom(atom_lab[j].second) ) { found=true; inum=nat1+i; break; }
+     447       32481 :           } else if( all_atoms[atom_lab[nat1+i].second]==all_atoms[atom_lab[j].second] ) { found=true; inum=j; break; }
+     448             :         }
+     449             :         // This prevents mistakes being made in colvar setup
+     450         178 :         if( found ) { ablocks[0][i]=inum; }
+     451        3528 :         else { ablocks[0][i]=nat1 + i; }
+     452             :       }
+     453             :     }
+     454             :   }
+     455         310 :   if( mybasemulticolvars.size()>0 ) {
+     456         246 :     for(unsigned i=0; i<mybasedata.size(); ++i) {
+     457         127 :       mybasedata[i]->resizeTemporyMultiValues(2); mybasemulticolvars[i]->my_tmp_capacks.resize(2);
+     458             :     }
+     459             :   }
+     460             : 
+     461             :   // Copy lists of atoms involved from base multicolvars
+     462             :   std::vector<AtomNumber> tmp_atoms;
+     463         437 :   for(unsigned i=0; i<mybasemulticolvars.size(); ++i) {
+     464         127 :     tmp_atoms=mybasemulticolvars[i]->getAbsoluteIndexes();
+     465      416316 :     for(unsigned j=0; j<tmp_atoms.size(); ++j) all_atoms.push_back( tmp_atoms[j] );
+     466             :   }
+     467             :   // Copy atom lists from input
+     468       59581 :   for(unsigned i=0; i<atoms.size(); ++i) all_atoms.push_back( atoms[i] );
+     469             : 
+     470             :   // Now make sure we get all the atom positions
+     471         310 :   ActionAtomistic::requestAtoms( all_atoms );
+     472             :   // And setup dependencies
+     473         437 :   for(unsigned i=0; i<mybasemulticolvars.size(); ++i) addDependency( mybasemulticolvars[i] );
+     474             : 
+     475             :   // Setup underlying ActionWithVessel
+     476         310 :   readVesselKeywords();
+     477         310 : }
+     478             : 
+     479          19 : void MultiColvarBase::setAtomsForCentralAtom( const std::vector<bool>& catom_ind ) {
+     480          19 :   unsigned nat=0; plumed_assert( catom_ind.size()==ablocks.size() );
+     481          89 :   for(unsigned i=0; i<catom_ind.size(); ++i) {
+     482          70 :     use_for_central_atom[i]=catom_ind[i];
+     483          70 :     if( use_for_central_atom[i] ) nat++;
+     484             :   }
+     485          19 :   plumed_dbg_assert( nat>0 ); ncentral=nat;
+     486          19 :   numberForCentralAtom = 1.0 / static_cast<double>( nat );
+     487          19 : }
+     488             : 
+     489         461 : void MultiColvarBase::turnOnDerivatives() {
+     490         461 :   ActionWithValue::turnOnDerivatives();
+     491         461 :   needsDerivatives();
+     492         461 :   forcesToApply.resize( getNumberOfDerivatives() );
+     493         461 : }
+     494             : 
+     495         192 : void MultiColvarBase::setLinkCellCutoff( const double& lcut, double tcut ) {
+     496         192 :   plumed_assert( usespecies || ablocks.size()<4 );
+     497         192 :   if( tcut<0 ) tcut=lcut;
+     498             : 
+     499         192 :   if( !linkcells.enabled() ) {
+     500         192 :     linkcells.setCutoff( lcut );
+     501         192 :     threecells.setCutoff( tcut );
+     502             :   } else {
+     503           0 :     if( lcut>linkcells.getCutoff() ) linkcells.setCutoff( lcut );
+     504           0 :     if( tcut>threecells.getCutoff() ) threecells.setCutoff( tcut );
+     505             :   }
+     506         192 : }
+     507             : 
+     508           8 : double MultiColvarBase::getLinkCellCutoff()  const {
+     509           8 :   return linkcells.getCutoff();
+     510             : }
+     511             : 
+     512        1940 : void MultiColvarBase::setupLinkCells() {
+     513        1940 :   if( (!usespecies && nblock==0) || !linkcells.enabled() ) return ;
+     514             :   // Retrieve any atoms that haven't already been retrieved
+     515        1319 :   for(std::vector<MultiColvarBase*>::iterator p=mybasemulticolvars.begin(); p!=mybasemulticolvars.end(); ++p) {
+     516         203 :     (*p)->retrieveAtoms();
+     517             :   }
+     518        1116 :   retrieveAtoms();
+     519             : 
+     520             :   unsigned iblock;
+     521        1116 :   if( usespecies ) {
+     522             :     iblock=0;
+     523         217 :   } else if( ablocks.size()<4 ) {
+     524             :     iblock=1;
+     525             :   } else {
+     526           0 :     plumed_error();
+     527             :   }
+     528             : 
+     529             :   // Count number of currently active atoms
+     530        1116 :   nactive_atoms=0;
+     531      387954 :   for(unsigned i=0; i<ablocks[iblock].size(); ++i) {
+     532      386838 :     if( isCurrentlyActive( ablocks[iblock][i] ) ) nactive_atoms++;
+     533             :   }
+     534             : 
+     535        1116 :   if( nactive_atoms>0 ) {
+     536        1116 :     std::vector<Vector> ltmp_pos( nactive_atoms );
+     537        1116 :     std::vector<unsigned> ltmp_ind( nactive_atoms );
+     538             : 
+     539        1116 :     nactive_atoms=0;
+     540        1116 :     if( usespecies ) {
+     541      366639 :       for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     542      365740 :         if( !isCurrentlyActive( ablocks[0][i] ) ) continue;
+     543      365644 :         ltmp_ind[nactive_atoms]=ablocks[0][i];
+     544      365644 :         ltmp_pos[nactive_atoms]=getPositionOfAtomForLinkCells( ltmp_ind[nactive_atoms] );
+     545      365644 :         nactive_atoms++;
+     546             :       }
+     547             :     } else {
+     548       21315 :       for(unsigned i=0; i<ablocks[1].size(); ++i) {
+     549       21098 :         if( !isCurrentlyActive( ablocks[1][i] ) ) continue;
+     550       16178 :         ltmp_ind[nactive_atoms]=i;
+     551       16178 :         ltmp_pos[nactive_atoms]=getPositionOfAtomForLinkCells( ablocks[1][i] );
+     552       16178 :         nactive_atoms++;
+     553             :       }
+     554             :     }
+     555             : 
+     556             :     // Build the lists for the link cells
+     557        1116 :     linkcells.buildCellLists( ltmp_pos, ltmp_ind, getPbc() );
+     558             :   }
+     559             : }
+     560             : 
+     561        4629 : void MultiColvarBase::setupNonUseSpeciesLinkCells( const unsigned& my_always_active ) {
+     562        4629 :   plumed_assert( !usespecies );
+     563        4629 :   if( nblock==0 || !linkcells.enabled() ) return ;
+     564         210 :   deactivateAllTasks();
+     565             :   std::vector<unsigned> requiredlinkcells;
+     566             : 
+     567         210 :   if( !uselinkforthree && nactive_atoms>0 ) {
+     568             :     // Get some parallel info
+     569         156 :     unsigned stride=comm.Get_size();
+     570         156 :     unsigned rank=comm.Get_rank();
+     571         156 :     if( serialCalculation() ) { stride=1; rank=0; }
+     572             : 
+     573             :     // Ensure we only do tasks where atoms are in appropriate link cells
+     574         156 :     std::vector<unsigned> linked_atoms( 1+ablocks[1].size() );
+     575        5757 :     for(unsigned i=rank; i<ablocks[0].size(); i+=stride) {
+     576        5601 :       if( !isCurrentlyActive( ablocks[0][i] ) ) continue;
+     577        2622 :       unsigned natomsper=1; linked_atoms[0]=my_always_active;  // Note we always check atom 0 because it is simpler than changing LinkCells.cpp
+     578        2622 :       linkcells.retrieveNeighboringAtoms( getPositionOfAtomForLinkCells( ablocks[0][i] ), requiredlinkcells, natomsper, linked_atoms );
+     579      205705 :       for(unsigned j=0; j<natomsper; ++j) {
+     580      353118 :         for(unsigned k=bookeeping(i,linked_atoms[j]).first; k<bookeeping(i,linked_atoms[j]).second; ++k) taskFlags[k]=1;
+     581             :       }
+     582             :     }
+     583         210 :   } else if( nactive_atoms>0 ) {
+     584             :     // Get some parallel info
+     585          54 :     unsigned stride=comm.Get_size();
+     586          54 :     unsigned rank=comm.Get_rank();
+     587          54 :     if( serialCalculation() ) { stride=1; rank=0; }
+     588             : 
+     589             :     unsigned nactive_three=0;
+     590       66599 :     for(unsigned i=0; i<ablocks[2].size(); ++i) {
+     591       66545 :       if( isCurrentlyActive( ablocks[2][i] ) ) nactive_three++;
+     592             :     }
+     593             : 
+     594          54 :     std::vector<Vector> lttmp_pos( nactive_three );
+     595          54 :     std::vector<unsigned> lttmp_ind( nactive_three );
+     596             : 
+     597             :     nactive_three=0;
+     598          54 :     if( allthirdblockintasks ) {
+     599       66599 :       for(unsigned i=0; i<ablocks[2].size(); ++i) {
+     600       66545 :         if( !isCurrentlyActive( ablocks[2][i] ) ) continue;
+     601       66545 :         lttmp_ind[nactive_three]=ablocks[2][i];
+     602       66545 :         lttmp_pos[nactive_three]=getPositionOfAtomForLinkCells( ablocks[2][i] );
+     603       66545 :         nactive_three++;
+     604             :       }
+     605             :     } else {
+     606           0 :       for(unsigned i=0; i<ablocks[2].size(); ++i) {
+     607           0 :         if( !isCurrentlyActive( ablocks[2][i] ) ) continue;
+     608           0 :         lttmp_ind[nactive_three]=i;
+     609           0 :         lttmp_pos[nactive_three]=getPositionOfAtomForLinkCells( ablocks[2][i] );
+     610           0 :         nactive_three++;
+     611             :       }
+     612             :     }
+     613             :     // Build the list of the link cells
+     614          54 :     threecells.buildCellLists( lttmp_pos, lttmp_ind, getPbc() );
+     615             : 
+     616             :     // Ensure we only do tasks where atoms are in appropriate link cells
+     617          54 :     std::vector<unsigned> linked_atoms( 1+ablocks[1].size() );
+     618          54 :     std::vector<unsigned> tlinked_atoms( 1+ablocks[2].size() );
+     619         633 :     for(unsigned i=rank; i<ablocks[0].size(); i+=stride) {
+     620         579 :       if( !isCurrentlyActive( ablocks[0][i] ) ) continue;
+     621         579 :       unsigned natomsper=1; linked_atoms[0]=my_always_active;  // Note we always check atom 0 because it is simpler than changing LinkCells.cpp
+     622         579 :       linkcells.retrieveNeighboringAtoms( getPositionOfAtomForLinkCells( ablocks[0][i] ), requiredlinkcells, natomsper, linked_atoms );
+     623         579 :       if( allthirdblockintasks ) {
+     624       71832 :         for(unsigned j=0; j<natomsper; ++j) {
+     625      142372 :           for(unsigned k=bookeeping(i,linked_atoms[j]).first; k<bookeeping(i,linked_atoms[j]).second; ++k) taskFlags[k]=1;
+     626             :         }
+     627             :       } else {
+     628           0 :         unsigned ntatomsper=1; tlinked_atoms[0]=lttmp_ind[0];
+     629           0 :         threecells.retrieveNeighboringAtoms( getPositionOfAtomForLinkCells( ablocks[0][i] ), requiredlinkcells, ntatomsper, tlinked_atoms );
+     630           0 :         for(unsigned j=0; j<natomsper; ++j) {
+     631           0 :           for(unsigned k=0; k<ntatomsper; ++k) taskFlags[bookeeping(i,linked_atoms[j]).first+tlinked_atoms[k]]=1;
+     632             :         }
+     633             :       }
+     634             :     }
+     635             :   }
+     636         210 :   if( !serialCalculation() ) comm.Sum( taskFlags );
+     637         210 :   lockContributors();
+     638             : }
+     639             : 
+     640      245988 : void MultiColvarBase::decodeIndexToAtoms( const unsigned& taskCode, std::vector<unsigned>& atoms ) const {
+     641             :   plumed_dbg_assert( !usespecies && nblock>0 );
+     642      245988 :   if( atoms.size()!=decoder.size() ) atoms.resize( decoder.size() );
+     643             : 
+     644      245988 :   unsigned scode = taskCode;
+     645      786464 :   for(unsigned i=0; i<decoder.size(); ++i) {
+     646      540476 :     unsigned ind=( scode / decoder[i] );
+     647      540476 :     atoms[i] = ablocks[i][ind];
+     648      540476 :     scode -= ind*decoder[i];
+     649             :   }
+     650      245988 : }
+     651             : 
+     652      452891 : bool MultiColvarBase::setupCurrentAtomList( const unsigned& taskCode, AtomValuePack& myatoms ) const {
+     653      452891 :   if( isDensity() ) {
+     654       19070 :     myatoms.setNumberOfAtoms( 1 ); myatoms.setAtom( 0, taskCode ); return true;
+     655      433821 :   } else if( usespecies ) {
+     656      182233 :     std::vector<unsigned> task_atoms(1); task_atoms[0]=taskCode;
+     657      182233 :     unsigned natomsper=myatoms.setupAtomsFromLinkCells( task_atoms, getPositionOfAtomForLinkCells( taskCode ), linkcells );
+     658      182233 :     return natomsper>1;
+     659      251588 :   } else if( matsums ) {
+     660             :     myatoms.setNumberOfAtoms( getNumberOfAtoms() );
+     661       52798 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) myatoms.setAtom( i, i );
+     662      251147 :   } else if( allthirdblockintasks ) {
+     663       39816 :     plumed_dbg_assert( ablocks.size()==3 ); std::vector<unsigned> atoms(2); decodeIndexToAtoms( taskCode, atoms );
+     664       39816 :     myatoms.setupAtomsFromLinkCells( atoms, getPositionOfAtomForLinkCells( atoms[0] ), threecells );
+     665      211331 :   } else if( nblock>0 ) {
+     666      179551 :     std::vector<unsigned> atoms( ablocks.size() );
+     667      179551 :     decodeIndexToAtoms( taskCode, atoms ); myatoms.setNumberOfAtoms( ablocks.size() );
+     668      587153 :     for(unsigned i=0; i<ablocks.size(); ++i) myatoms.setAtom( i, atoms[i] );
+     669             :   } else {
+     670       31780 :     myatoms.setNumberOfAtoms( ablocks.size() );
+     671      124504 :     for(unsigned i=0; i<ablocks.size(); ++i) myatoms.setAtom( i, ablocks[i][taskCode] );
+     672             :   }
+     673             :   return true;
+     674             : }
+     675             : 
+     676        9075 : void MultiColvarBase::setupActiveTaskSet( std::vector<unsigned>& active_tasks, const std::string& input_label ) {
+     677        9075 :   if( !setup_completed ) {
+     678             :     bool justVolumes=false;
+     679        1932 :     if( usespecies ) {
+     680             :       justVolumes=true;
+     681        1438 :       for(unsigned i=0; i<getNumberOfVessels(); ++i) {
+     682        1318 :         vesselbase::StoreDataVessel* mys=dynamic_cast<vesselbase::StoreDataVessel*>( getPntrToVessel(i) );
+     683        1318 :         if( mys ) continue;
+     684         810 :         vesselbase::BridgeVessel* myb=dynamic_cast<vesselbase::BridgeVessel*>( getPntrToVessel(i) );
+     685         810 :         if( !myb ) { justVolumes=false; break; }
+     686          38 :         ActionVolume* myv=dynamic_cast<ActionVolume*>( myb->getOutputAction() );
+     687          38 :         if( !myv ) { justVolumes=false; break; }
+     688             :       }
+     689             :     }
+     690        1932 :     deactivateAllTasks();
+     691        1932 :     if( justVolumes && mydata ) {
+     692          88 :       if( mydata->getNumberOfDataUsers()==0 ) justVolumes=false;
+     693             : 
+     694         137 :       for(unsigned i=0; i<mydata->getNumberOfDataUsers(); ++i) {
+     695          49 :         MultiColvarBase* myu=dynamic_cast<MultiColvarBase*>( mydata->getDataUser(i) );
+     696          49 :         if( myu ) {
+     697          49 :           myu->setupActiveTaskSet( taskFlags, getLabel() );
+     698             :         } else {
+     699           0 :           for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+     700             :         }
+     701             :       }
+     702             :     }
+     703        1932 :     if( justVolumes ) {
+     704         160 :       for(unsigned j=0; j<getNumberOfVessels(); ++j) {
+     705          80 :         vesselbase::BridgeVessel* myb=dynamic_cast<vesselbase::BridgeVessel*>( getPntrToVessel(j) );
+     706          80 :         if( !myb ) continue ;
+     707          32 :         ActionVolume* myv=dynamic_cast<ActionVolume*>( myb->getOutputAction() );
+     708          32 :         if( !myv ) continue ;
+     709          32 :         myv->retrieveAtoms(); myv->setupRegions();
+     710             : 
+     711      148161 :         for(unsigned i=0; i<getFullNumberOfTasks(); ++i) {
+     712      148129 :           if( myv->inVolumeOfInterest(i) ) taskFlags[i]=1;
+     713             :         }
+     714             :       }
+     715             :     } else {
+     716     4886705 :       for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+     717             :     }
+     718             : 
+     719             :     // Now activate all this class
+     720        1932 :     lockContributors();
+     721             :     // Setup the link cells
+     722        1932 :     setupLinkCells();
+     723             :     // Ensures that setup is not performed multiple times during one cycle
+     724        1932 :     setup_completed=true;
+     725             :   }
+     726             : 
+     727             :   // And activate the tasks in input action
+     728        9075 :   if( getLabel()!=input_label ) {
+     729             :     int input_code=-1;
+     730          61 :     for(unsigned i=0; i<mybasemulticolvars.size(); ++i) {
+     731          61 :       if( mybasemulticolvars[i]->getLabel()==input_label ) { input_code=i+1; break; }
+     732             :     }
+     733             : 
+     734          49 :     MultiValue my_tvals( getNumberOfQuantities(), getNumberOfDerivatives() );
+     735          49 :     AtomValuePack mytmp_atoms( my_tvals, this );
+     736      148234 :     for(unsigned i=0; i<getFullNumberOfTasks(); ++i) {
+     737      148185 :       if( !taskIsCurrentlyActive(i) ) continue;
+     738        3529 :       setupCurrentAtomList( getTaskCode(i), mytmp_atoms );
+     739      254796 :       for(unsigned j=0; j<mytmp_atoms.getNumberOfAtoms(); ++j) {
+     740             :         unsigned itask=mytmp_atoms.getIndex(j);
+     741      251267 :         if( atom_lab[itask].first==input_code ) active_tasks[ atom_lab[itask].second ]=1;
+     742             :       }
+     743             :     }
+     744          49 :   }
+     745        9075 : }
+     746             : 
+     747         467 : bool MultiColvarBase::filtersUsedAsInput() {
+     748             :   bool inputAreFilters=false;
+     749         728 :   for(unsigned i=0; i<mybasemulticolvars.size(); ++i) {
+     750         261 :     MultiColvarFilter* myfilt=dynamic_cast<MultiColvarFilter*>( mybasemulticolvars[i] );
+     751         261 :     if( myfilt || mybasemulticolvars[i]->filtersUsedAsInput() ) inputAreFilters=true;
+     752             :   }
+     753         467 :   return inputAreFilters;
+     754             : }
+     755             : 
+     756        9026 : void MultiColvarBase::calculate() {
+     757             :   // Recursive function that sets up tasks
+     758        9026 :   setupActiveTaskSet( taskFlags, getLabel() );
+     759             : 
+     760             :   // Check for filters and rerun setup of link cells if there are any
+     761        9026 :   if( mybasemulticolvars.size()>0 && filtersUsedAsInput() ) setupLinkCells();
+     762             : 
+     763             :   //  Setup the link cells if we are not using species
+     764        9026 :   if( !usespecies && ablocks.size()>1 ) {
+     765             :     // This loop finds the first active atom, which is always checked because
+     766             :     // of a peculiarity in linkcells
+     767        4629 :     unsigned first_active=std::numeric_limits<unsigned>::max();
+     768        4763 :     for(unsigned i=0; i<ablocks[0].size(); ++i) {
+     769        4763 :       if( !isCurrentlyActive( ablocks[1][i] ) ) continue;
+     770             :       else {
+     771        4629 :         first_active=i; break;
+     772             :       }
+     773             :     }
+     774        4629 :     setupNonUseSpeciesLinkCells( first_active );
+     775             :   }
+     776             :   // And run all tasks
+     777        9026 :   runAllTasks();
+     778        9026 : }
+     779             : 
+     780         213 : void MultiColvarBase::calculateNumericalDerivatives( ActionWithValue* a ) {
+     781         213 :   if( mybasemulticolvars.size()>0 ) plumed_merror("cannot calculate numerical derivatives for this quantity");
+     782         213 :   calculateAtomicNumericalDerivatives( this, 0 );
+     783         213 : }
+     784             : 
+     785        2961 : void MultiColvarBase::prepare() {
+     786        2961 :   setup_completed=false; atomsWereRetrieved=false;
+     787        2961 : }
+     788             : 
+     789        6551 : void MultiColvarBase::retrieveAtoms() {
+     790        6551 :   if( !atomsWereRetrieved ) { ActionAtomistic::retrieveAtoms(); atomsWereRetrieved=true; }
+     791        6551 : }
+     792             : 
+     793       38245 : void MultiColvarBase::mergeInputDerivatives( const unsigned& ival, const unsigned& start, const unsigned& end,
+     794             :     const unsigned& jatom, const std::vector<double>& der,
+     795             :     MultiValue& myder, AtomValuePack& myatoms ) const {
+     796             :   MultiValue& myvals=myatoms.getUnderlyingMultiValue();
+     797             :   plumed_dbg_assert( ival<myatoms.getUnderlyingMultiValue().getNumberOfValues() );
+     798             :   plumed_dbg_assert( start<myder.getNumberOfValues() && end<=myder.getNumberOfValues() );
+     799             :   plumed_dbg_assert( der.size()==myder.getNumberOfValues() && jatom<myatoms.getNumberOfAtoms() );
+     800             :   // Convert input atom to local index
+     801             :   unsigned katom = myatoms.getIndex( jatom ); plumed_dbg_assert( katom<atom_lab.size() ); plumed_dbg_assert( atom_lab[katom].first>0 );
+     802             :   // Find base colvar
+     803       38245 :   unsigned mmc=atom_lab[katom].first - 1; plumed_dbg_assert( mybasemulticolvars[mmc]->taskIsCurrentlyActive( atom_lab[katom].second ) );
+     804             :   // Get start of indices for this atom
+     805       38855 :   unsigned basen=0; for(unsigned i=0; i<mmc; ++i) basen+=mybasemulticolvars[i]->getNumberOfDerivatives() - 9;
+     806             :   plumed_dbg_assert( basen%3==0 ); // Check the number of atoms is consistent with input derivatives
+     807       38245 :   unsigned virbas = myvals.getNumberOfDerivatives()-9;
+     808     4805851 :   for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     809             :     unsigned jder=myder.getActiveIndex(j);
+     810     4767606 :     if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     811     4434561 :       unsigned kder=basen+jder;
+     812   110197260 :       for(unsigned icomp=start; icomp<end; ++icomp) {
+     813   105762699 :         myvals.addDerivative( ival, kder, der[icomp]*myder.getDerivative( icomp, jder ) );
+     814             :       }
+     815             :     } else {
+     816      333045 :       unsigned kder=virbas + (jder - mybasemulticolvars[mmc]->getNumberOfDerivatives() + 9);
+     817     7551360 :       for(unsigned icomp=start; icomp<end; ++icomp) {
+     818     7218315 :         myvals.addDerivative( ival, kder, der[icomp]*myder.getDerivative( icomp, jder ) );
+     819             :       }
+     820             :     }
+     821             :   }
+     822       38245 : }
+     823             : 
+     824         106 : void MultiColvarBase::splitInputDerivatives( const unsigned& ival, const unsigned& start, const unsigned& end,
+     825             :     const unsigned& jatom, const std::vector<double>& der,
+     826             :     MultiValue& myder, AtomValuePack& myatoms ) const {
+     827             :   MultiValue& myvals=myatoms.getUnderlyingMultiValue();
+     828             :   plumed_dbg_assert( ival<myder.getNumberOfValues() );
+     829             :   plumed_dbg_assert( start<myvals.getNumberOfValues() && end<=myvals.getNumberOfValues() );
+     830             :   plumed_dbg_assert( der.size()==myatoms.getUnderlyingMultiValue().getNumberOfValues() && jatom<myatoms.getNumberOfAtoms() );
+     831             :   // Convert input atom to local index
+     832             :   unsigned katom = myatoms.getIndex( jatom ); plumed_dbg_assert( katom<atom_lab.size() ); plumed_dbg_assert( atom_lab[katom].first>0 );
+     833             :   // Find base colvar
+     834         106 :   unsigned mmc=atom_lab[katom].first - 1; plumed_dbg_assert( mybasemulticolvars[mmc]->taskIsCurrentlyActive( atom_lab[katom].second ) );
+     835             :   // Get start of indices for this atom
+     836         154 :   unsigned basen=0; for(unsigned i=0; i<mmc; ++i) basen+=mybasemulticolvars[i]->getNumberOfDerivatives() - 9;
+     837             :   plumed_dbg_assert( basen%3==0 ); // Check the number of atoms is consistent with input derivatives
+     838         106 :   unsigned virbas = myvals.getNumberOfDerivatives()-9;
+     839       19534 :   for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     840             :     unsigned jder=myder.getActiveIndex(j);
+     841       19428 :     if( jder<mybasemulticolvars[mmc]->getNumberOfDerivatives()-9 ) {
+     842       18474 :       unsigned kder=basen+jder; plumed_assert( kder<myvals.getNumberOfDerivatives() );
+     843       39942 :       for(unsigned icomp=start; icomp<end; ++icomp) {
+     844       21468 :         myvals.addDerivative( icomp, kder, der[icomp]*myder.getDerivative( ival, jder ) );
+     845             :       }
+     846             :     } else {
+     847         954 :       unsigned kder=virbas + (jder - mybasemulticolvars[mmc]->getNumberOfDerivatives() + 9);
+     848        3942 :       for(unsigned icomp=start; icomp<end; ++icomp) {
+     849        2988 :         myvals.addDerivative( icomp, kder, der[icomp]*myder.getDerivative( ival, jder ) );
+     850             :       }
+     851             :     }
+     852             :   }
+     853         106 : }
+     854             : 
+     855      980606 : void MultiColvarBase::addComDerivatives( const int& ival, const unsigned& iatom, const Vector& der, multicolvar::AtomValuePack& myatoms ) const {
+     856             :   plumed_dbg_assert( ival<static_cast<int>(myatoms.getUnderlyingMultiValue().getNumberOfValues()) && iatom<myatoms.getNumberOfAtoms() );
+     857             :   // Convert input atom to local index
+     858             :   unsigned katom = myatoms.getIndex( iatom ); plumed_dbg_assert( atom_lab[katom].first>0 );
+     859             :   // Find base colvar
+     860      980606 :   unsigned mmc = atom_lab[katom].first - 1; plumed_dbg_assert( mybasemulticolvars[mmc]->taskIsCurrentlyActive( atom_lab[katom].second ) );
+     861      980606 :   if( usespecies && iatom==0 ) { myatoms.addComDerivatives( ival, der, mybasemulticolvars[mmc]->my_tmp_capacks[0] ); return; }
+     862             : 
+     863             :   // Get start of indices for this atom
+     864      721370 :   unsigned basen=0; for(unsigned i=0; i<mmc; ++i) basen+=(mybasemulticolvars[i]->getNumberOfDerivatives() - 9) / 3;
+     865      526683 :   mybasemulticolvars[mmc]->getCentralAtomPack( basen, atom_lab[katom].second, mybasemulticolvars[mmc]->my_tmp_capacks[1] );
+     866      526683 :   myatoms.addComDerivatives( ival, der, mybasemulticolvars[mmc]->my_tmp_capacks[1] );
+     867             : }
+     868             : 
+     869     1124044 : void MultiColvarBase::getInputData( const unsigned& ind, const bool& normed,
+     870             :                                     const multicolvar::AtomValuePack& myatoms,
+     871             :                                     std::vector<double>& orient ) const {
+     872             :   // Converint input atom to local index
+     873             :   unsigned katom = myatoms.getIndex(ind); plumed_dbg_assert( atom_lab[katom].first>0 );
+     874             :   // Find base colvar
+     875     1124044 :   unsigned mmc = atom_lab[katom].first - 1; plumed_dbg_assert( mybasemulticolvars[mmc]->taskIsCurrentlyActive( atom_lab[katom].second ) );
+     876             :   // Check if orient is the correct size
+     877     1124044 :   if( orient.size()!=mybasemulticolvars[mmc]->getNumberOfQuantities() ) orient.resize( mybasemulticolvars[mmc]->getNumberOfQuantities() );
+     878             :   // Retrieve the value
+     879     1124044 :   mybasedata[mmc]->retrieveValueWithIndex( atom_lab[katom].second, normed, orient );
+     880     1124044 : }
+     881             : 
+     882       54449 : MultiValue& MultiColvarBase::getInputDerivatives( const unsigned& iatom, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const {
+     883             :   // Converint input atom to local index
+     884             :   unsigned katom = myatoms.getIndex(iatom); plumed_dbg_assert( atom_lab[katom].first>0 );
+     885             :   // Find base colvar
+     886       54449 :   unsigned mmc = atom_lab[katom].first - 1; plumed_dbg_assert( mybasemulticolvars[mmc]->taskIsCurrentlyActive( atom_lab[katom].second ) );
+     887       54449 :   if( usespecies && !normed && iatom==0 ) return mybasedata[mmc]->getTemporyMultiValue(0);
+     888             : 
+     889       52651 :   unsigned oval=0; if( iatom>0 ) oval=1;
+     890       52651 :   MultiValue& myder=mybasedata[mmc]->getTemporyMultiValue(oval);
+     891      105263 :   if( myder.getNumberOfValues()!=mybasemulticolvars[mmc]->getNumberOfQuantities() ||
+     892       52612 :       myder.getNumberOfDerivatives()!=mybasemulticolvars[mmc]->getNumberOfDerivatives() ) {
+     893          39 :     myder.resize( mybasemulticolvars[mmc]->getNumberOfQuantities(), mybasemulticolvars[mmc]->getNumberOfDerivatives() );
+     894             :   }
+     895       52651 :   mybasedata[mmc]->retrieveDerivatives( atom_lab[katom].second, normed, myder );
+     896             :   return myder;
+     897             : }
+     898             : 
+     899    65138769 : void MultiColvarBase::accumulateSymmetryFunction( const int& ival, const unsigned& iatom, const double& val, const Vector& der, const Tensor& vir, multicolvar::AtomValuePack& myatoms ) const {
+     900             :   plumed_dbg_assert( usespecies ); unsigned katom=myatoms.getIndex(0), jatom=myatoms.getIndex(iatom);
+     901    65138769 :   double weight0=1.0; if( atom_lab[katom].first>0 ) weight0=mybasedata[atom_lab[katom].first-1]->retrieveWeightWithIndex( atom_lab[katom].second );
+     902    65138769 :   double weighti=1.0; if( atom_lab[jatom].first>0 ) weighti=mybasedata[atom_lab[jatom].first-1]->retrieveWeightWithIndex( atom_lab[jatom].second );
+     903             :   // Accumulate the value
+     904    65138769 :   if( ival<0 ) myatoms.getUnderlyingMultiValue().addTemporyValue( weight0*weighti*val );
+     905    62372141 :   else myatoms.addValue( ival, weight0*weighti*val );
+     906             : 
+     907             :   // Return if we don't need derivatives
+     908    65138769 :   if( doNotCalculateDerivatives() ) return ;
+     909             :   // And virial
+     910    58765246 :   if( ival<0 ) myatoms.addTemporyBoxDerivatives( weight0*weighti*vir );
+     911    56477371 :   else myatoms.addBoxDerivatives( ival, weight0*weighti*vir );
+     912             : 
+     913             :   // Add derivatives of central atom
+     914    58765246 :   if( atom_lab[katom].first>0 ) {
+     915         794 :     addComDerivatives( ival, 0, -weight0*weighti*der, myatoms );
+     916         794 :     std::vector<double> tmpder( mybasemulticolvars[atom_lab[katom].first - 1]->getNumberOfQuantities(), 0. );
+     917         794 :     tmpder[0]=weighti*val; mergeInputDerivatives( ival, 0, 1, 0, tmpder, getInputDerivatives(0, false, myatoms), myatoms );
+     918             :   } else {
+     919    58764452 :     if( ival<0 ) myatoms.addTemporyAtomsDerivatives( 0, -der );
+     920    56476577 :     else myatoms.addAtomsDerivatives( ival, 0, -der );
+     921             :   }
+     922             :   // Add derivatives of atom in coordination sphere
+     923    58765246 :   if( atom_lab[jatom].first>0 ) {
+     924         794 :     addComDerivatives( ival, iatom, weight0*weighti*der, myatoms );
+     925         794 :     std::vector<double> tmpder( mybasemulticolvars[atom_lab[katom].first - 1]->getNumberOfQuantities(), 0. );
+     926         794 :     tmpder[0]=weight0*val; mergeInputDerivatives( ival, 0, 1, iatom, tmpder, getInputDerivatives(iatom, false, myatoms), myatoms );
+     927             :   } else {
+     928    58764452 :     if( ival<0 ) myatoms.addTemporyAtomsDerivatives( iatom, der );
+     929    56476577 :     else myatoms.addAtomsDerivatives( ival, iatom, der );
+     930             :   }
+     931             : }
+     932             : 
+     933     1503319 : void MultiColvarBase::addAtomDerivatives( const int& ival, const unsigned& iatom, const Vector& der, multicolvar::AtomValuePack& myatoms ) const {
+     934     1503319 :   if( doNotCalculateDerivatives() ) return ;
+     935             :   unsigned jatom=myatoms.getIndex(iatom);
+     936             : 
+     937     1255743 :   if( atom_lab[jatom].first>0 ) {
+     938      979018 :     addComDerivatives( ival, iatom, der, myatoms );
+     939             :   } else {
+     940      276725 :     if( ival<0 ) myatoms.addTemporyAtomsDerivatives( iatom, der );
+     941      276725 :     else myatoms.addAtomsDerivatives( ival, iatom, der );
+     942             :   }
+     943             : }
+     944             : 
+     945      244248 : double MultiColvarBase::calculateWeight( const unsigned& current, const double& weight, AtomValuePack& myvals ) const {
+     946      244248 :   return 1.0;
+     947             : }
+     948             : 
+     949      449362 : void MultiColvarBase::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     950      449362 :   AtomValuePack myatoms( myvals, this );
+     951             :   // Retrieve the atom list
+     952      449362 :   if( !setupCurrentAtomList( current, myatoms ) ) return;
+     953             :   // Get weight due to dynamic groups
+     954      449242 :   double weight = 1.0;
+     955      449242 :   if( !matsums ) {
+     956   386210286 :     for(unsigned i=0; i<myatoms.getNumberOfAtoms(); ++i) {
+     957   385940040 :       if( atom_lab[myatoms.getIndex(i)].first==0 ) continue;
+     958             :       // Only need to do first two atoms for things like TopologyMatrix, HbondMatrix, Bridge and so on
+     959      244017 :       if( allthirdblockintasks && i>1 ) break;
+     960      244017 :       unsigned mmc = atom_lab[myatoms.getIndex(i)].first - 1;
+     961      244017 :       weight *= mybasedata[mmc]->retrieveWeightWithIndex( atom_lab[myatoms.getIndex(i)].second );
+     962             :     }
+     963      178996 :   } else if( usespecies ) {
+     964      178555 :     if( atom_lab[myatoms.getIndex(0)].first>0 ) {
+     965        9073 :       if( mybasedata[atom_lab[myatoms.getIndex(0)].first-1]->retrieveWeightWithIndex( atom_lab[myatoms.getIndex(0)].second )<epsilon ) weight=0.;
+     966             :     }
+     967             :   }
+     968             :   // Do a quick check on the size of this contribution
+     969      449242 :   double multweight = calculateWeight( current, weight, myatoms );
+     970      449242 :   if( weight*multweight<getTolerance() ) {
+     971      121536 :     updateActiveAtoms( myatoms );
+     972             :     return;
+     973             :   }
+     974             :   myatoms.setValue( 0, weight*multweight );
+     975             :   // Deal with derivatives of weights due to dynamic groups
+     976      327706 :   if( !matsums && !doNotCalculateDerivatives() && mybasemulticolvars.size()>0 ) {
+     977       39416 :     MultiValue& outder=myatoms.getUnderlyingMultiValue(); MultiValue myder(0,0);
+     978      115123 :     for(unsigned i=0; i<myatoms.getNumberOfAtoms(); ++i) {
+     979             :       // Neglect any atoms without differentiable weights
+     980       75707 :       if( atom_lab[myatoms.getIndex(i)].first==0 ) continue;
+     981             : 
+     982             :       // Retrieve derivatives
+     983       75707 :       unsigned mmc = atom_lab[myatoms.getIndex(i)].first - 1;
+     984       75707 :       if( myder.getNumberOfValues()!=mybasemulticolvars[mmc]->getNumberOfQuantities() || myder.getNumberOfDerivatives()!=mybasemulticolvars[mmc]->getNumberOfDerivatives() ) {
+     985       39416 :         myder.resize( mybasemulticolvars[mmc]->getNumberOfQuantities(), mybasemulticolvars[mmc]->getNumberOfDerivatives() );
+     986             :       }
+     987       75707 :       mybasedata[mmc]->retrieveDerivatives( atom_lab[myatoms.getIndex(i)].second, false, myder );
+     988             : 
+     989             :       // Retrieve the prefactor (product of all other weights)
+     990       75707 :       double prefactor = multweight*weight / mybasedata[mmc]->retrieveWeightWithIndex( atom_lab[myatoms.getIndex(i)].second );
+     991             :       // And accumulate the derivatives
+     992     2927141 :       for(unsigned j=0; j<myder.getNumberActive(); ++j) { unsigned jder=myder.getActiveIndex(j); outder.addDerivative( 0, jder, prefactor*myder.getDerivative(0,jder) ); }
+     993       75707 :       myder.clearAll();
+     994             :     }
+     995       39416 :   }
+     996             :   // Retrieve derivative stuff for central atom
+     997      327706 :   if( !doNotCalculateDerivatives() ) {
+     998      208303 :     if( usespecies && mybasemulticolvars.size()>0 && atom_lab[myatoms.getIndex(0)].first>0 ) {
+     999        1610 :       unsigned mmc = atom_lab[0].first - 1;
+    1000        1610 :       MultiValue& myder=mybasedata[mmc]->getTemporyMultiValue(0);
+    1001        3208 :       if( myder.getNumberOfValues()!=mybasemulticolvars[mmc]->getNumberOfQuantities() ||
+    1002        1598 :           myder.getNumberOfDerivatives()!=mybasemulticolvars[mmc]->getNumberOfDerivatives() ) {
+    1003          12 :         myder.resize( mybasemulticolvars[mmc]->getNumberOfQuantities(), mybasemulticolvars[mmc]->getNumberOfDerivatives() );
+    1004             :       }
+    1005        1610 :       mybasedata[mmc]->retrieveDerivatives( atom_lab[myatoms.getIndex(0)].second, false, myder );
+    1006        1610 :       unsigned basen=0; for(unsigned i=0; i<mmc; ++i) basen+=mybasemulticolvars[i]->getNumberOfDerivatives() - 9;
+    1007        1610 :       mybasemulticolvars[mmc]->getCentralAtomPack( basen, atom_lab[myatoms.getIndex(0)].second,  mybasemulticolvars[mmc]->my_tmp_capacks[0] );
+    1008             :     }
+    1009             :   }
+    1010             :   // Compute everything
+    1011      327706 :   double vv=compute( task_index, myatoms ); updateActiveAtoms( myatoms );
+    1012             :   myatoms.setValue( 1, vv );
+    1013      327706 :   return;
+    1014             : }
+    1015             : 
+    1016      662396 : void MultiColvarBase::updateActiveAtoms( AtomValuePack& myatoms ) const {
+    1017      662396 :   if( mybasemulticolvars.size()==0 ) myatoms.updateUsingIndices();
+    1018      141871 :   else myatoms.updateDynamicList();
+    1019      662396 : }
+    1020             : 
+    1021     2558087 : Vector MultiColvarBase::getCentralAtomPos( const unsigned& taskIndex ) {
+    1022     2558087 :   unsigned curr=getTaskCode( taskIndex );
+    1023             : 
+    1024     2558087 :   if( usespecies || isDensity() ) {
+    1025     1264098 :     return getPositionOfAtomForLinkCells(curr);
+    1026     1293989 :   } else if( nblock>0 ) {
+    1027             :     // double factor=1.0/static_cast<double>( ablocks.size() );
+    1028        2130 :     Vector mypos; mypos.zero();
+    1029        2130 :     std::vector<unsigned> atoms( ablocks.size() ); decodeIndexToAtoms( curr, atoms );
+    1030        6390 :     for(unsigned i=0; i<ablocks.size(); ++i) {
+    1031        4260 :       if( use_for_central_atom[i] ) mypos+=numberForCentralAtom*getPositionOfAtomForLinkCells(atoms[i]);
+    1032             :     }
+    1033        2130 :     return mypos;
+    1034             :   } else {
+    1035     1291859 :     Vector mypos; mypos.zero();
+    1036     5138646 :     for(unsigned i=0; i<ablocks.size(); ++i) {
+    1037     3846787 :       if( use_for_central_atom[i] ) mypos+=numberForCentralAtom*getPositionOfAtomForLinkCells(ablocks[i][curr]);
+    1038             :     }
+    1039     1291859 :     return mypos;
+    1040             :   }
+    1041             : }
+    1042             : 
+    1043      642832 : void MultiColvarBase::getCentralAtomPack( const unsigned& basn, const unsigned& taskIndex, CatomPack& mypack ) {
+    1044      642832 :   unsigned curr=getTaskCode( taskIndex );
+    1045             : 
+    1046      642832 :   if(usespecies) {
+    1047      502418 :     if( mypack.getNumberOfAtomsWithDerivatives()!=1 ) mypack.resize(1);
+    1048      502418 :     mypack.setIndex( 0, basn + curr );
+    1049      502418 :     mypack.setDerivative( 0, Tensor::identity() );
+    1050      140414 :   } else if( nblock>0 ) {
+    1051           0 :     if( mypack.getNumberOfAtomsWithDerivatives()!=ncentral ) mypack.resize(ncentral);
+    1052           0 :     unsigned k=0;
+    1053           0 :     std::vector<unsigned> atoms( ablocks.size() ); decodeIndexToAtoms( curr, atoms );
+    1054           0 :     for(unsigned i=0; i<ablocks.size(); ++i) {
+    1055           0 :       if( use_for_central_atom[i] ) {
+    1056           0 :         mypack.setIndex( k, basn + atoms[i] );
+    1057           0 :         mypack.setDerivative( k, numberForCentralAtom*Tensor::identity() );
+    1058           0 :         k++;
+    1059             :       }
+    1060             :     }
+    1061             :   } else {
+    1062      140414 :     if( mypack.getNumberOfAtomsWithDerivatives()!=ncentral ) mypack.resize(ncentral);
+    1063      140414 :     unsigned k=0;
+    1064      316748 :     for(unsigned i=0; i<ablocks.size(); ++i) {
+    1065      176334 :       if( use_for_central_atom[i] ) {
+    1066      173694 :         mypack.setIndex( k, basn + ablocks[i][curr] );
+    1067      173694 :         mypack.setDerivative( k, numberForCentralAtom*Tensor::identity() );
+    1068      173694 :         k++;
+    1069             :       }
+    1070             :     }
+    1071             :   }
+    1072      642832 : }
+    1073             : 
+    1074   121150995 : Vector MultiColvarBase::getSeparation( const Vector& vec1, const Vector& vec2 ) const {
+    1075   121150995 :   if(usepbc) { return pbcDistance( vec1, vec2 ); }
+    1076           0 :   else { return delta( vec1, vec2 ); }
+    1077             : }
+    1078             : 
+    1079      222049 : void MultiColvarBase::applyPbc(std::vector<Vector>& dlist, unsigned int max_index) const {
+    1080      222049 :   if (usepbc) pbcApply(dlist, max_index);
+    1081      222049 : }
+    1082             : 
+    1083        1996 : void MultiColvarBase::apply() {
+    1084        1996 :   unsigned ind=0; if( getForcesFromVessels( forcesToApply ) ) setForcesOnAtoms( forcesToApply, ind );
+    1085        1996 : }
+    1086             : 
+    1087             : }
+    1088             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.h.func-sort-c.html b/coverage/multicolvar/MultiColvarBase.h.func-sort-c.html new file mode 100644 index 000000000000..6c257d13e759 --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.h.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232785.2 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15MultiColvarBase22doNotCalculateDirectorEv0
_ZNK4PLMD11multicolvar15MultiColvarBase28hasDifferentiableOrientationEv0
_ZNK4PLMD11multicolvar15MultiColvarBase29getAbsoluteIndexOfCentralAtomERKj156
_ZN4PLMD11multicolvar15MultiColvarBaseD2Ev352
_ZNK4PLMD11multicolvar15MultiColvarBase10threadSafeEv4462
_ZN4PLMD11multicolvar15MultiColvarBase17isCurrentlyActiveERKj917710
_ZNK4PLMD11multicolvar15MultiColvarBase9isDensityEv1816069
_ZN4PLMD11multicolvar15MultiColvarBase22getNumberOfDerivativesEv9180420
_ZNK4PLMD11multicolvar15MultiColvarBase25doNotCalculateDerivativesEv69913268
_ZNK4PLMD11multicolvar15MultiColvarBase29getPositionOfAtomForLinkCellsERKj405597365
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.h.func.html b/coverage/multicolvar/MultiColvarBase.h.func.html new file mode 100644 index 000000000000..b9f578daafc8 --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.h.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232785.2 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15MultiColvarBase17isCurrentlyActiveERKj917710
_ZN4PLMD11multicolvar15MultiColvarBase22doNotCalculateDirectorEv0
_ZN4PLMD11multicolvar15MultiColvarBase22getNumberOfDerivativesEv9180420
_ZN4PLMD11multicolvar15MultiColvarBaseD2Ev352
_ZNK4PLMD11multicolvar15MultiColvarBase10threadSafeEv4462
_ZNK4PLMD11multicolvar15MultiColvarBase25doNotCalculateDerivativesEv69913268
_ZNK4PLMD11multicolvar15MultiColvarBase28hasDifferentiableOrientationEv0
_ZNK4PLMD11multicolvar15MultiColvarBase29getAbsoluteIndexOfCentralAtomERKj156
_ZNK4PLMD11multicolvar15MultiColvarBase29getPositionOfAtomForLinkCellsERKj405597365
_ZNK4PLMD11multicolvar15MultiColvarBase9isDensityEv1816069
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarBase.h.gcov.html b/coverage/multicolvar/MultiColvarBase.h.gcov.html new file mode 100644 index 000000000000..7b9b3a25fa28 --- /dev/null +++ b/coverage/multicolvar/MultiColvarBase.h.gcov.html @@ -0,0 +1,351 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232785.2 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_multicolvar_MultiColvarBase_h
+      23             : #define __PLUMED_multicolvar_MultiColvarBase_h
+      24             : 
+      25             : #include "core/ActionAtomistic.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : #include "tools/DynamicList.h"
+      28             : #include "tools/LinkCells.h"
+      29             : #include "vesselbase/StoreDataVessel.h"
+      30             : #include "vesselbase/ActionWithVessel.h"
+      31             : #include "CatomPack.h"
+      32             : #include <vector>
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace multicolvar {
+      36             : 
+      37             : class AtomValuePack;
+      38             : class BridgedMultiColvarFunction;
+      39             : class ActionVolume;
+      40             : 
+      41             : class MultiColvarBase :
+      42             :   public ActionAtomistic,
+      43             :   public ActionWithValue,
+      44             :   public vesselbase::ActionWithVessel
+      45             : {
+      46             :   friend class BridgedMultiColvarFunction;
+      47             :   friend class VolumeGradientBase;
+      48             :   friend class MultiColvarFilter;
+      49             :   friend class AtomValuePack;
+      50             : private:
+      51             : /// Use periodic boundary conditions
+      52             :   bool usepbc;
+      53             : /// The forces we are going to apply to things
+      54             :   std::vector<double> forcesToApply;
+      55             : /// We use this to say that all the atoms in the third block should are in the tasks
+      56             :   bool allthirdblockintasks;
+      57             : /// In certain cases we can make three atom link cells faster
+      58             :   bool uselinkforthree;
+      59             : /// Number of atoms that are active on this step
+      60             :   unsigned nactive_atoms;
+      61             : /// Stuff for link cells - this is used to make coordination number like variables faster
+      62             :   LinkCells linkcells;
+      63             : /// Link cells for third block of atoms
+      64             :   LinkCells threecells;
+      65             : /// Number of atoms that are being used for central atom position
+      66             :   unsigned ncentral;
+      67             : /// Bool vector telling us which atoms are required to calculate central atom position
+      68             :   std::vector<bool> use_for_central_atom;
+      69             : /// Vector of tempory holders for central atom values
+      70             :   std::vector<CatomPack> my_tmp_capacks;
+      71             : /// 1/number of atoms involved in central atoms
+      72             :   double numberForCentralAtom;
+      73             : /// Ensures that setup is only performed once per loop
+      74             :   bool setup_completed;
+      75             : /// Ensures that retrieving of atoms is only done once per calculation loop
+      76             :   bool atomsWereRetrieved;
+      77             : /// Add derivatives of center of mass position
+      78             :   void addComDerivatives( const int& ival, const unsigned& iatom, const Vector& der, multicolvar::AtomValuePack& myatoms ) const ;
+      79             : protected:
+      80             : /// This is used to keep track of what is calculated where
+      81             :   std::vector< std::pair<unsigned,unsigned> > atom_lab;
+      82             : /// The vessels in these multicolvars in which the data is stored
+      83             :   std::vector<vesselbase::StoreDataVessel*> mybasedata;
+      84             : /// The multicolvars from which we construct these quantities
+      85             :   std::vector<MultiColvarBase*> mybasemulticolvars;
+      86             : /// This remembers where the boundaries are for the tasks. It makes link cells work fast
+      87             :   Matrix<std::pair<unsigned,unsigned> > bookeeping;
+      88             : /// Function that recursively checks if filters have been used in the input to a multicolvar
+      89             : /// we need this to ensure that setupLinkCells is run in calculate with some actions
+      90             :   bool filtersUsedAsInput();
+      91             : /// This resizes the arrays that are used for link cell update
+      92             :   void resizeBookeepingArray( const unsigned& num1, const unsigned& num2 );
+      93             : /// Are we doing sums of matrix rows
+      94             :   bool matsums;
+      95             : /// Using the species keyword to read in atoms
+      96             :   bool usespecies;
+      97             : /// Number of atoms in each block
+      98             :   unsigned nblock;
+      99             : /// This is used when turning cvcodes into atom numbers
+     100             :   std::vector<unsigned> decoder;
+     101             : /// Blocks of atom numbers
+     102             :   std::vector< std::vector<unsigned> > ablocks;
+     103             : /// Add a task to the list of tasks
+     104             :   void addTaskToList( const unsigned& taskCode );
+     105             : /// Finish setting up the multicolvar base
+     106             :   void setupMultiColvarBase( const std::vector<AtomNumber>& atoms );
+     107             : /// This routine take the vector of input derivatives and adds all the vectors to ivalth output derivatives
+     108             : /// In other words end-start sets of derivatives come in and one set of derivatives come out
+     109             :   void mergeInputDerivatives( const unsigned& ival, const unsigned& start, const unsigned& end, const unsigned& jatom,
+     110             :                               const std::vector<double>& der, MultiValue& myder, AtomValuePack& myatoms ) const ;
+     111             : /// This routine take the ith set of input derivatives and adds it to each of the (end-start) output derivatives
+     112             : /// In other words one set of derivatives comes in and end-start sets of derivatives come out
+     113             :   void splitInputDerivatives( const unsigned& ival, const unsigned& start, const unsigned& end,
+     114             :                               const unsigned& jatom, const std::vector<double>& der,
+     115             :                               MultiValue& myder, AtomValuePack& myatoms ) const ;
+     116             : /// This is used to accumulate functions of the coordination sphere.  Ensures weights are taken into account
+     117             :   void accumulateSymmetryFunction( const int& ival, const unsigned& iatom, const double& val, const Vector& der, const Tensor& vir, multicolvar::AtomValuePack& myatoms ) const ;
+     118             : /// Set which atoms are to be used to calculate the central atom position
+     119             :   void setAtomsForCentralAtom( const std::vector<bool>& catom_ind );
+     120             : /// Set the value of the cutoff for the link cells
+     121             :   void setLinkCellCutoff( const double& lcut, double tcut=-1.0 );
+     122             : /// Setup the link cells and neighbour list stuff
+     123             :   void setupActiveTaskSet( std::vector<unsigned>& active_tasks, const std::string& input_label );
+     124             : /// Setup link cells in order to make this calculation faster
+     125             :   void setupLinkCells();
+     126             : /// Get the cutoff for the link cells
+     127             :   double getLinkCellCutoff()  const ;
+     128             : /// This does setup of link cell stuff that is specific to the non-use of the usespecies keyword
+     129             :   void setupNonUseSpeciesLinkCells( const unsigned& );
+     130             : /// This sets up the list of atoms that are involved in this colvar
+     131             :   bool setupCurrentAtomList( const unsigned& taskCode, AtomValuePack& myatoms ) const ;
+     132             : /// Decode indices if there are 2 or 3 atoms involved
+     133             :   void decodeIndexToAtoms( const unsigned& taskCode, std::vector<unsigned>& atoms ) const ;
+     134             : /// Read in some atoms
+     135             :   bool parseMultiColvarAtomList(const std::string& key, const int& num, std::vector<AtomNumber>& t);
+     136             : /// Read in ATOMS keyword
+     137             :   void readAtomsLikeKeyword( const std::string & key, const int& natoms, std::vector<AtomNumber>& all_atoms );
+     138             : /// Read in two groups of atoms and setup multicolvars to calculate
+     139             :   void readTwoGroups( const std::string& key0, const std::string& key1, const std::string& key2, std::vector<AtomNumber>& all_atoms );
+     140             : /// Read in three groups of atoms
+     141             :   void readGroupKeywords( const std::string& key0, const std::string& key1, const std::string& key2, const std::string& key3,
+     142             :                           const bool& no_third_dim_accum, const bool& symmetric, std::vector<AtomNumber>& all_atoms );
+     143             : /// Read in three groups of atoms and construct CVs involving at least one
+     144             :   void readThreeGroups( const std::string& key1, const std::string& key2, const std::string& key3,
+     145             :                         const bool& allow2, const bool& no_third_dim_accum, std::vector<AtomNumber>& all_atoms );
+     146             : /// Build sets by taking one multicolvar from each base
+     147             :   void buildSets();
+     148             : public:
+     149             :   explicit MultiColvarBase(const ActionOptions&);
+     150        1408 :   ~MultiColvarBase() {}
+     151             :   static void registerKeywords( Keywords& keys );
+     152             : /// Turn on the derivatives
+     153             :   void turnOnDerivatives() override;
+     154             : /// Get the separation between a pair of vectors
+     155             :   Vector getSeparation( const Vector& vec1, const Vector& vec2 ) const ;
+     156             : /// Do we use pbc to calculate this quantity
+     157             :   bool usesPbc() const ;
+     158             : /// Apply PBCs over a set of distance vectors
+     159             :   void applyPbc(std::vector<Vector>& dlist, unsigned max_index=0) const;
+     160             : /// Is it safe to use multithreading
+     161        4462 :   bool threadSafe() const override { return !(mybasemulticolvars.size()>0); }
+     162             : /// Do some setup before the calculation
+     163             :   void prepare() override;
+     164             : /// This is overwritten here in order to make sure that we do not retrieve atoms multiple times
+     165             :   void retrieveAtoms() override;
+     166             : /// Do the calculation
+     167             :   void calculate() override;
+     168             : /// Calculate numerical derivatives
+     169             :   void calculateNumericalDerivatives( ActionWithValue* a=NULL ) override;
+     170             : /// Perform one of the tasks
+     171             :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override;
+     172             : /// Update the active atoms
+     173             :   virtual void updateActiveAtoms( AtomValuePack& myatoms ) const ;
+     174             : /// This gets the position of an atom for the link cell setup
+     175             :   virtual Vector getPositionOfAtomForLinkCells( const unsigned& iatom ) const ;
+     176             : /// Get the absolute index of the central atom
+     177             :   virtual AtomNumber getAbsoluteIndexOfCentralAtom( const unsigned& i ) const ;
+     178             : /// This is replaced once we have a function to calculate the cv
+     179             :   virtual double compute( const unsigned& tindex, AtomValuePack& myatoms ) const=0;
+     180             : /// Apply the forces from this action
+     181             :   void apply() override;
+     182             : /// Get the number of derivatives for this action
+     183             :   unsigned getNumberOfDerivatives() override;  // N.B. This is replacing the virtual function in ActionWithValue
+     184             : /// Checks if an task is being performed at the present time
+     185             :   virtual bool isCurrentlyActive( const unsigned& code );
+     186             : /// Add some derivatives to a particular component of a particular atom
+     187             :   void addAtomDerivatives( const int&, const unsigned&, const Vector&, multicolvar::AtomValuePack& ) const ;
+     188             : ///
+     189             :   virtual void getCentralAtomPack( const unsigned& basn, const unsigned& curr, CatomPack& mypack);
+     190             : /// Get the index where the central atom is stored
+     191             :   virtual Vector getCentralAtomPos( const unsigned& curr );
+     192             : /// You can use this to screen contributions that are very small so we can avoid expensive (and pointless) calculations
+     193             :   virtual double calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const ;
+     194             : /// Is this a density?
+     195     1816069 :   virtual bool isDensity() const { return false; }
+     196             : /// Is the iatom'th stored value currently active
+     197             :   bool storedValueIsActive( const unsigned& iatom );
+     198             : /// This is true if multicolvar is calculating a vector or if the multicolvar is the density
+     199           0 :   virtual bool hasDifferentiableOrientation() const { return false; }
+     200             : /// This makes sure we are not calculating the director when we do LocalAverage
+     201           0 :   virtual void doNotCalculateDirector() {}
+     202             : /// Ensure that derivatives are only calculated when needed
+     203             :   bool doNotCalculateDerivatives() const override;
+     204             : /// Get the icolv th base multicolvar
+     205             :   MultiColvarBase* getBaseMultiColvar( const unsigned& icolv ) const ;
+     206             : /// Get the number of base multicolvars
+     207             :   unsigned getNumberOfBaseMultiColvars() const ;
+     208             : /// Get an input data
+     209             :   virtual void getInputData( const unsigned& ind, const bool& normed, const multicolvar::AtomValuePack& myatoms, std::vector<double>& orient ) const ;
+     210             : /// Retrieve the input derivatives
+     211             :   virtual MultiValue& getInputDerivatives( const unsigned& iatom, const bool& normed, const multicolvar::AtomValuePack& myatoms ) const ;
+     212             : };
+     213             : 
+     214             : inline
+     215      917710 : bool MultiColvarBase::isCurrentlyActive( const unsigned& code ) {
+     216      917710 :   if( setup_completed && atom_lab[code].first>0 ) {
+     217       17644 :     unsigned mmc=atom_lab[code].first - 1;
+     218       17644 :     return mybasedata[mmc]->storedValueIsActive( atom_lab[code].second );
+     219             :   }
+     220             :   return true;
+     221             : }
+     222             : 
+     223             : inline
+     224         156 : AtomNumber MultiColvarBase::getAbsoluteIndexOfCentralAtom( const unsigned& iatom ) const {
+     225             :   plumed_dbg_assert( iatom<atom_lab.size() );
+     226         156 :   if( atom_lab[iatom].first>0  ) {
+     227           0 :     unsigned mmc=atom_lab[iatom].first - 1;
+     228           0 :     return mybasemulticolvars[mmc]->getAbsoluteIndexOfCentralAtom( atom_lab[iatom].second );
+     229             :   }
+     230             :   plumed_dbg_assert( usespecies );
+     231         156 :   return ActionAtomistic::getAbsoluteIndex( atom_lab[getTaskCode(iatom)].second );
+     232             : }
+     233             : 
+     234             : inline
+     235   405597365 : Vector MultiColvarBase::getPositionOfAtomForLinkCells( const unsigned& iatom ) const {
+     236             :   plumed_dbg_assert( iatom<atom_lab.size() );
+     237   405597365 :   if( atom_lab[iatom].first>0  ) {
+     238     2292134 :     unsigned mmc=atom_lab[iatom].first - 1;
+     239     2292134 :     return mybasemulticolvars[mmc]->getCentralAtomPos( atom_lab[iatom].second );
+     240             :   }
+     241   403305231 :   return ActionAtomistic::getPosition( atom_lab[iatom].second );
+     242             : }
+     243             : 
+     244             : inline
+     245     9180420 : unsigned MultiColvarBase::getNumberOfDerivatives() {
+     246     9180420 :   return 3*getNumberOfAtoms()+9;
+     247             : }
+     248             : 
+     249             : inline
+     250             : bool MultiColvarBase::usesPbc() const {
+     251      222049 :   return usepbc;
+     252             : }
+     253             : 
+     254             : inline
+     255    69913268 : bool MultiColvarBase::doNotCalculateDerivatives() const {
+     256    69913268 :   if( !dertime ) return true;
+     257    69225548 :   return ActionWithValue::doNotCalculateDerivatives();
+     258             : }
+     259             : 
+     260             : inline
+     261             : unsigned MultiColvarBase::getNumberOfBaseMultiColvars() const {
+     262         178 :   return mybasemulticolvars.size();
+     263             : }
+     264             : 
+     265             : inline
+     266             : MultiColvarBase* MultiColvarBase::getBaseMultiColvar( const unsigned& icolv ) const {
+     267             :   plumed_dbg_assert( icolv<mybasemulticolvars.size() );
+     268       25010 :   return mybasemulticolvars[icolv];
+     269             : }
+     270             : 
+     271             : }
+     272             : }
+     273             : 
+     274             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarCombine.cpp.func-sort-c.html b/coverage/multicolvar/MultiColvarCombine.cpp.func-sort-c.html new file mode 100644 index 000000000000..ce78d5842230 --- /dev/null +++ b/coverage/multicolvar/MultiColvarCombine.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarCombine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarCombine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18MultiColvarCombineC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar18MultiColvarCombine10isPeriodicEv1
_ZN4PLMD11multicolvar18MultiColvarCombineC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarCombine16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD11multicolvar18MultiColvarCombine7computeERKjRNS0_13AtomValuePackE15
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarCombine.cpp.func.html b/coverage/multicolvar/MultiColvarCombine.cpp.func.html new file mode 100644 index 000000000000..847134cbb78d --- /dev/null +++ b/coverage/multicolvar/MultiColvarCombine.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarCombine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarCombine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18MultiColvarCombine10isPeriodicEv1
_ZN4PLMD11multicolvar18MultiColvarCombine16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar18MultiColvarCombineC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarCombineC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar18MultiColvarCombine7computeERKjRNS0_13AtomValuePackE15
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarCombine.cpp.gcov.html b/coverage/multicolvar/MultiColvarCombine.cpp.gcov.html new file mode 100644 index 000000000000..9809ba2dbf66 --- /dev/null +++ b/coverage/multicolvar/MultiColvarCombine.cpp.gcov.html @@ -0,0 +1,172 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarCombine.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarCombine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : #include <string>
+      27             : #include <cmath>
+      28             : 
+      29             : //+PLUMEDOC MCOLVARF MCOLV_COMBINE
+      30             : /*
+      31             : Calculate linear combinations of multiple multicolvars
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace multicolvar {
+      40             : 
+      41             : class MultiColvarCombine : public MultiColvarBase {
+      42             : private:
+      43             :   std::vector<double> coeff;
+      44             : public:
+      45             :   static void registerKeywords( Keywords& keys );
+      46             :   explicit MultiColvarCombine(const ActionOptions&);
+      47             : /// Actually do the calculation
+      48             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      49             : /// Is the variable periodic
+      50           1 :   bool isPeriodic() override { return false; }
+      51             : };
+      52             : 
+      53             : PLUMED_REGISTER_ACTION(MultiColvarCombine,"MCOLV_COMBINE")
+      54             : 
+      55           3 : void MultiColvarCombine::registerKeywords( Keywords& keys ) {
+      56           3 :   MultiColvarBase::registerKeywords( keys );
+      57           6 :   keys.add("compulsory","DATA","the multicolvars you are calculating linear combinations for");
+      58           6 :   keys.add("compulsory","COEFFICIENTS","1.0","the coefficients to use for the various multicolvars");
+      59          15 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("SUM"); keys.use("LESS_THAN"); keys.use("HISTOGRAM");
+      60          21 :   keys.use("MIN"); keys.use("MAX"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("ALT_MIN"); keys.use("BETWEEN"); keys.use("MOMENTS");
+      61           3 : }
+      62             : 
+      63           1 : MultiColvarCombine::MultiColvarCombine(const ActionOptions& ao):
+      64             :   Action(ao),
+      65           1 :   MultiColvarBase(ao)
+      66             : {
+      67           1 :   buildSets();
+      68           3 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+      69           2 :     if( mybasemulticolvars[i]->weightWithDerivatives() ) error("cannot combine multicolvars with weights");
+      70             :   }
+      71           1 :   coeff.resize( getNumberOfBaseMultiColvars() );
+      72           1 :   parseVector("COEFFICIENTS",coeff);
+      73           1 :   log.printf("  coefficients of multicolvars %f", coeff[0] );
+      74           2 :   for(unsigned i=1; i<coeff.size(); ++i) log.printf(", %f", coeff[i] );
+      75           1 :   log.printf("\n");
+      76           1 : }
+      77             : 
+      78          15 : double MultiColvarCombine::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+      79          15 :   double dot=0; std::vector<double> tval(2);
+      80          45 :   for(unsigned i=0; i<coeff.size(); ++i) {
+      81          30 :     getInputData( i, false, myatoms, tval );
+      82          30 :     dot += coeff[i]*tval[1];
+      83             :   }
+      84          15 :   if( !doNotCalculateDerivatives() ) {
+      85          15 :     std::vector<double> cc(2);
+      86          45 :     for(unsigned i=0; i<coeff.size(); ++i) {
+      87          30 :       cc[1]=coeff[i]; MultiValue& myder=getInputDerivatives( i, false, myatoms );
+      88          30 :       splitInputDerivatives( 1, 1, 2, i, cc, myder, myatoms );
+      89             :     }
+      90             :   }
+      91          15 :   return dot;
+      92             : }
+      93             : 
+      94             : }
+      95             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarDensity.cpp.func-sort-c.html b/coverage/multicolvar/MultiColvarDensity.cpp.func-sort-c.html new file mode 100644 index 000000000000..58ab49355085 --- /dev/null +++ b/coverage/multicolvar/MultiColvarDensity.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarDensity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarDensity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11513883.3 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18MultiColvarDensity10isPeriodicEv0
_ZN4PLMD11multicolvar18MultiColvarDensityC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar18MultiColvarDensityC1ERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar18MultiColvarDensity16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD11multicolvar18MultiColvarDensity12clearAverageEv18
_ZN4PLMD11multicolvar18MultiColvarDensity19prepareForAveragingEv26
_ZN4PLMD11multicolvar18MultiColvarDensity5applyEv34
_ZNK4PLMD11multicolvar18MultiColvarDensity21getNumberOfQuantitiesEv62
_ZNK4PLMD11multicolvar18MultiColvarDensity7computeERKjRNS_10MultiValueE21152
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarDensity.cpp.func.html b/coverage/multicolvar/MultiColvarDensity.cpp.func.html new file mode 100644 index 000000000000..4a812b451c52 --- /dev/null +++ b/coverage/multicolvar/MultiColvarDensity.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarDensity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarDensity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11513883.3 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18MultiColvarDensity10isPeriodicEv0
_ZN4PLMD11multicolvar18MultiColvarDensity12clearAverageEv18
_ZN4PLMD11multicolvar18MultiColvarDensity16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD11multicolvar18MultiColvarDensity19prepareForAveragingEv26
_ZN4PLMD11multicolvar18MultiColvarDensity5applyEv34
_ZN4PLMD11multicolvar18MultiColvarDensityC1ERKNS_13ActionOptionsE11
_ZN4PLMD11multicolvar18MultiColvarDensityC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar18MultiColvarDensity21getNumberOfQuantitiesEv62
_ZNK4PLMD11multicolvar18MultiColvarDensity7computeERKjRNS_10MultiValueE21152
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarDensity.cpp.gcov.html b/coverage/multicolvar/MultiColvarDensity.cpp.gcov.html new file mode 100644 index 000000000000..c112824c58ca --- /dev/null +++ b/coverage/multicolvar/MultiColvarDensity.cpp.gcov.html @@ -0,0 +1,374 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarDensity.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarDensity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11513883.3 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/Pbc.h"
+      24             : #include "tools/Units.h"
+      25             : #include <cstdio>
+      26             : #include "core/PlumedMain.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "MultiColvarBase.h"
+      29             : #include "gridtools/ActionWithGrid.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace multicolvar {
+      33             : 
+      34             : //+PLUMEDOC GRIDCALC MULTICOLVARDENS
+      35             : /*
+      36             : Evaluate the average value of a multicolvar on a grid.
+      37             : 
+      38             : This keyword allows one to construct a phase field representation for a symmetry function from
+      39             : an atomistic description.  If each atom has an associated order parameter, \f$\phi_i\f$ then a
+      40             : smooth phase field function \f$\phi(r)\f$ can be computed using:
+      41             : 
+      42             : \f[
+      43             : \phi(\mathbf{r}) = \frac{\sum_i K(\mathbf{r}-\mathbf{r}_i) \phi_i }{ \sum_i K(\mathbf{r} - \mathbf{r}_i )}
+      44             : \f]
+      45             : 
+      46             : where \f$\mathbf{r}_i\f$ is the position of atom \f$i\f$, the sums run over all the atoms input
+      47             : and \f$K(\mathbf{r} - \mathbf{r}_i)\f$ is one of the \ref kernelfunctions implemented in plumed.
+      48             : This action calculates the above function on a grid, which can then be used in the input to further
+      49             : actions.
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : The following example shows perhaps the simplest way in which this action can be used.  The following
+      54             : input computes the density of atoms at each point on the grid and outputs this quantity to a file.  In
+      55             : other words this input instructs plumed to calculate \f$\rho(\mathbf{r}) = \sum_i K(\mathbf{r} - \mathbf{r}_i )\f$
+      56             : 
+      57             : \plumedfile
+      58             : dens: DENSITY SPECIES=1-100
+      59             : grid: MULTICOLVARDENS DATA=dens ORIGIN=1 DIR=xyz NBINS=100,100,100 BANDWIDTH=0.05,0.05,0.05 STRIDE=1
+      60             : DUMPGRID GRID=grid STRIDE=500 FILE=density
+      61             : \endplumedfile
+      62             : 
+      63             : In the above example density is added to the grid on every step.  The PRINT_GRID instruction thus tells PLUMED to
+      64             : output the average density at each point on the grid every 500 steps of simulation.  Notice that the that grid output
+      65             : on step 1000 is an average over all 1000 frames of the trajectory.  If you would like to analyze these two blocks
+      66             : of data separately you must use the CLEAR flag.
+      67             : 
+      68             : This second example computes an order parameter (in this case \ref FCCUBIC) and constructs a phase field model
+      69             : for this order parameter using the equation above.
+      70             : 
+      71             : \plumedfile
+      72             : fcc: FCCUBIC SPECIES=1-5184 SWITCH={CUBIC D_0=1.2 D_MAX=1.5} ALPHA=27
+      73             : dens: MULTICOLVARDENS DATA=fcc ORIGIN=1 DIR=xyz NBINS=14,14,28 BANDWIDTH=1.0,1.0,1.0 STRIDE=1 CLEAR=1
+      74             : DUMPCUBE GRID=dens STRIDE=1 FILE=dens.cube
+      75             : \endplumedfile
+      76             : 
+      77             : In this example the phase field model is computed and output to a file on every step of the simulation.  Furthermore,
+      78             : because the CLEAR=1 keyword is set on the MULTICOLVARDENS line each Gaussian cube file output is a phase field
+      79             : model for a particular trajectory frame. The average value accumulated thus far is cleared at the start of every single
+      80             : timestep and there is no averaging over trajectory frames in this case.
+      81             : 
+      82             : */
+      83             : //+ENDPLUMEDOC
+      84             : 
+      85             : class MultiColvarDensity : public gridtools::ActionWithGrid {
+      86             :   bool fractional;
+      87             :   MultiColvarBase* mycolv;
+      88             :   std::vector<unsigned> nbins;
+      89             :   std::vector<double> gspacing;
+      90             :   std::vector<bool> confined;
+      91             :   std::vector<double> cmin, cmax;
+      92             :   vesselbase::StoreDataVessel* stash;
+      93             :   Vector origin;
+      94             :   std::vector<unsigned> directions;
+      95             : public:
+      96             :   explicit MultiColvarDensity(const ActionOptions&);
+      97             :   static void registerKeywords( Keywords& keys );
+      98             :   unsigned getNumberOfQuantities() const override;
+      99           0 :   bool isPeriodic() override { return false; }
+     100             :   void clearAverage() override;
+     101             :   void prepareForAveraging() override;
+     102             :   void compute( const unsigned&, MultiValue& ) const override;
+     103          34 :   void apply() override {}
+     104             : };
+     105             : 
+     106             : PLUMED_REGISTER_ACTION(MultiColvarDensity,"MULTICOLVARDENS")
+     107             : 
+     108          13 : void MultiColvarDensity::registerKeywords( Keywords& keys ) {
+     109          13 :   gridtools::ActionWithGrid::registerKeywords( keys );
+     110          26 :   keys.add("atoms","ORIGIN","we will use the position of this atom as the origin");
+     111          26 :   keys.add("compulsory","DATA","the multicolvar which you would like to calculate the density profile for");
+     112          26 :   keys.add("compulsory","DIR","the direction in which to calculate the density profile");
+     113          26 :   keys.add("optional","NBINS","the number of bins to use to represent the density profile");
+     114          26 :   keys.add("optional","SPACING","the approximate grid spacing (to be used as an alternative or together with NBINS)");
+     115          26 :   keys.addFlag("FRACTIONAL",false,"use fractional coordinates for the various axes");
+     116          26 :   keys.addFlag("XREDUCED",false,"limit the calculation of the density/average to a portion of the z-axis only");
+     117          26 :   keys.add("optional","XLOWER","this is required if you are using XREDUCED. It specifies the lower bound for the region of the x-axis that for "
+     118             :            "which you are calculating the density/average");
+     119          26 :   keys.add("optional","XUPPER","this is required if you are using XREDUCED. It specifies the upper bound for the region of the x-axis that for "
+     120             :            "which you are calculating the density/average");
+     121          26 :   keys.addFlag("YREDUCED",false,"limit the calculation of the density/average to a portion of the y-axis only");
+     122          26 :   keys.add("optional","YLOWER","this is required if you are using YREDUCED. It specifies the lower bound for the region of the y-axis that for "
+     123             :            "which you are calculating the density/average");
+     124          26 :   keys.add("optional","YUPPER","this is required if you are using YREDUCED. It specifies the upper bound for the region of the y-axis that for "
+     125             :            "which you are calculating the density/average");
+     126          26 :   keys.addFlag("ZREDUCED",false,"limit the calculation of the density/average to a portion of the z-axis only");
+     127          26 :   keys.add("optional","ZLOWER","this is required if you are using ZREDUCED. It specifies the lower bound for the region of the z-axis that for "
+     128             :            "which you are calculating the density/average");
+     129          26 :   keys.add("optional","ZUPPER","this is required if you are using ZREDUCED. It specifies the upper bound for the region of the z-axis that for "
+     130             :            "which you are calculating the density/average");
+     131          13 : }
+     132             : 
+     133          11 : MultiColvarDensity::MultiColvarDensity(const ActionOptions&ao):
+     134             :   Action(ao),
+     135          11 :   ActionWithGrid(ao)
+     136             : {
+     137             :   std::vector<AtomNumber> atom;
+     138          22 :   parseAtomList("ORIGIN",atom);
+     139          11 :   if( atom.size()!=1 ) error("should only be one atom specified");
+     140          11 :   log.printf("  origin is at position of atom : %d\n",atom[0].serial() );
+     141             : 
+     142          11 :   std::string mlab; parse("DATA",mlab);
+     143          11 :   mycolv = plumed.getActionSet().selectWithLabel<MultiColvarBase*>(mlab);
+     144          11 :   if(!mycolv) error("action labelled " +  mlab + " does not exist or is not a MultiColvar");
+     145          11 :   stash = mycolv->buildDataStashes( NULL );
+     146             : 
+     147          22 :   parseFlag("FRACTIONAL",fractional);
+     148          11 :   std::string direction; parse("DIR",direction);
+     149          11 :   log.printf("  calculating for %s density profile along ", mycolv->getLabel().c_str() );
+     150          11 :   if( direction=="x" ) {
+     151           8 :     log.printf("x axis");
+     152           8 :     directions.resize(1); directions[0]=0;
+     153           3 :   } else if( direction=="y" ) {
+     154           0 :     log.printf("y axis");
+     155           0 :     directions.resize(1); directions[0]=1;
+     156           3 :   } else if( direction=="z" ) {
+     157           0 :     log.printf("z axis");
+     158           0 :     directions.resize(1); directions[0]=2;
+     159           3 :   } else if( direction=="xy" ) {
+     160           0 :     log.printf("x and y axes");
+     161           0 :     directions.resize(2); directions[0]=0; directions[1]=1;
+     162           3 :   } else if( direction=="xz" ) {
+     163           0 :     log.printf("x and z axes");
+     164           0 :     directions.resize(2); directions[0]=0; directions[1]=2;
+     165           3 :   } else if( direction=="yz" ) {
+     166           0 :     log.printf("y and z axis");
+     167           0 :     directions.resize(2); directions[0]=1; directions[1]=2;
+     168           3 :   } else if( direction=="xyz" ) {
+     169           3 :     log.printf("x, y and z axes");
+     170           3 :     directions.resize(3); directions[0]=0; directions[1]=1; directions[2]=2;
+     171             :   } else {
+     172           0 :     error( direction + " is not valid gradient direction");
+     173             :   }
+     174          11 :   log.printf(" for colvars calculated by action %s \n",mycolv->getLabel().c_str() );
+     175          33 :   parseVector("NBINS",nbins); parseVector("SPACING",gspacing);
+     176          11 :   if( nbins.size()!=directions.size() && gspacing.size()!=directions.size() ) error("NBINS or SPACING must be set");
+     177             : 
+     178          11 :   confined.resize( directions.size() ); cmin.resize( directions.size(), 0 ); cmax.resize( directions.size(), 0 );
+     179          28 :   for(unsigned i=0; i<directions.size(); ++i) {
+     180          17 :     if( directions[i]==0 ) {
+     181          22 :       bool tflag; parseFlag("XREDUCED",tflag); confined[i]=tflag;
+     182          11 :       if( confined[i] ) {
+     183           0 :         cmin[i]=cmax[i]=0.0; parse("XLOWER",cmin[i]); parse("XUPPER",cmax[i]);
+     184           0 :         if( fractional ) error("XREDUCED is incompatible with FRACTIONAL");
+     185           0 :         if( std::abs(cmin[i]-cmax[i])<epsilon ) error("range set for x axis makes no sense");
+     186           0 :         log.printf("  confining calculation in x direction to between %f and %f \n",cmin[i],cmax[i]);
+     187             :       }
+     188           6 :     } else if( directions[i]==1 ) {
+     189           6 :       bool tflag; parseFlag("YREDUCED",tflag); confined[i]=tflag;
+     190           3 :       if( confined[i] ) {
+     191           0 :         cmin[i]=cmax[i]=0.0; parse("YLOWER",cmin[i]); parse("YUPPER",cmax[i]);
+     192           0 :         if( fractional ) error("YREDUCED is incompatible with FRACTIONAL");
+     193           0 :         if( std::abs(cmin[i]-cmax[i])<epsilon ) error("range set for y axis makes no sense");
+     194           0 :         log.printf("  confining calculation in y direction to between %f and %f \n",cmin[i],cmax[i]);
+     195             :       }
+     196           3 :     } else if( directions[i]==2 ) {
+     197           6 :       bool tflag; parseFlag("ZREDUCED",tflag); confined[i]=tflag;
+     198           3 :       if( confined[i] ) {
+     199           2 :         cmin[i]=cmax[i]=0.0; parse("ZLOWER",cmin[i]); parse("ZUPPER",cmax[i]);
+     200           1 :         if( fractional ) error("ZREDUCED is incompatible with FRACTIONAL");
+     201           1 :         if( std::abs(cmin[i]-cmax[i])<epsilon ) error("range set for z axis search makes no sense");
+     202           1 :         log.printf("  confining calculation in z direction to between %f and %f \n",cmin[i],cmax[i]);
+     203             :       }
+     204             :     }
+     205             :   }
+     206             : 
+     207             :   std::string vstring;
+     208          11 :   if( confined[0] ) vstring +="PBC=F";
+     209             :   else vstring += " PBC=T";
+     210          17 :   for(unsigned i=1; i<directions.size(); ++i) {
+     211           6 :     if( confined[i] ) vstring += ",F";
+     212             :     else vstring += ",T";
+     213             :   }
+     214          22 :   vstring +=" COMPONENTS=" + mycolv->getLabel() + ".dens";
+     215             :   vstring +=" COORDINATES=";
+     216          11 :   if( directions[0]==0 ) vstring+="x";
+     217           0 :   else if( directions[0]==1 ) vstring+="y";
+     218           0 :   else if( directions[0]==2 ) vstring+="z";
+     219          17 :   for(unsigned i=1; i<directions.size(); ++i) {
+     220           6 :     if( directions[i]==0 ) vstring+=",x";
+     221           6 :     else if( directions[i]==1 ) vstring+=",y";
+     222           3 :     else if( directions[i]==2 ) vstring+=",z";
+     223             :   }
+     224             :   // Create a task list
+     225       10899 :   for(unsigned i=0; i<mycolv->getFullNumberOfTasks(); ++i) addTaskToList(i);
+     226             :   // And create the grid
+     227          11 :   std::unique_ptr<gridtools::GridVessel> grid;
+     228          14 :   if( mycolv->isDensity() ) grid=createGrid( "histogram", vstring );
+     229          16 :   else grid=createGrid( "average", vstring );
+     230             :   // cppcheck-suppress danglingLifetime
+     231          11 :   mygrid=grid.get();
+     232             :   // And finish the grid setup
+     233          11 :   setAveragingAction( std::move(grid), true );
+     234             : 
+     235             :   // Enusre units for cube files are set correctly
+     236          11 :   if( !fractional ) {
+     237          11 :     if( usingNaturalUnits() ) mygrid->setCubeUnits( 1.0/0.5292 );
+     238           1 :     else mygrid->setCubeUnits( getUnits().getLength()/.05929 );
+     239             :   }
+     240             : 
+     241          11 :   checkRead(); requestAtoms(atom);
+     242             :   // Stupid dependencies cleared by requestAtoms - why GBussi why? That's got me so many times
+     243          11 :   addDependency( mycolv );
+     244          22 : }
+     245             : 
+     246          62 : unsigned MultiColvarDensity::getNumberOfQuantities() const {
+     247          62 :   return directions.size() + 2;
+     248             : }
+     249             : 
+     250          18 : void MultiColvarDensity::clearAverage() {
+     251          18 :   std::vector<double> min(directions.size()), max(directions.size());
+     252          18 :   std::vector<std::string> gmin(directions.size()), gmax(directions.size());;
+     253          46 :   for(unsigned i=0; i<directions.size(); ++i) { min[i]=-0.5; max[i]=0.5; }
+     254          18 :   if( !fractional ) {
+     255          18 :     if( !mycolv->getPbc().isOrthorombic() ) {
+     256           0 :       error("I think that density profiles with non-orthorhombic cells don't work.  If you want it have a look and see if you can work it out");
+     257             :     }
+     258             : 
+     259          46 :     for(unsigned i=0; i<directions.size(); ++i) {
+     260          28 :       if( !confined[i] ) {
+     261          25 :         min[i]*=mycolv->getBox()(directions[i],directions[i]);
+     262          25 :         max[i]*=mycolv->getBox()(directions[i],directions[i]);
+     263             :       } else {
+     264           3 :         min[i]=cmin[i]; max[i]=cmax[i];
+     265             :       }
+     266             :     }
+     267             :   }
+     268          46 :   for(unsigned i=0; i<directions.size(); ++i) { Tools::convert(min[i],gmin[i]); Tools::convert(max[i],gmax[i]); }
+     269          18 :   ActionWithAveraging::clearAverage();
+     270          18 :   mygrid->setBounds( gmin, gmax, nbins, gspacing ); resizeFunctions();
+     271          36 : }
+     272             : 
+     273          26 : void MultiColvarDensity::prepareForAveraging() {
+     274          62 :   for(unsigned i=0; i<directions.size(); ++i) {
+     275          36 :     if( confined[i] ) continue;
+     276          33 :     std::string max; Tools::convert( 0.5*mycolv->getBox()(directions[i],directions[i]), max );
+     277          33 :     if( max!=mygrid->getMax()[i] ) error("box size should be fixed.  Use FRACTIONAL");
+     278             :   }
+     279             :   // Ensure we only work with active multicolvars
+     280          26 :   deactivateAllTasks();
+     281       21178 :   for(unsigned i=0; i<stash->getNumberOfStoredValues(); ++i) taskFlags[i]=1;
+     282          26 :   lockContributors();
+     283             :   // Retrieve the origin
+     284          26 :   origin = getPosition(0);
+     285          26 : }
+     286             : 
+     287       21152 : void MultiColvarDensity::compute( const unsigned& current, MultiValue& myvals ) const {
+     288       21152 :   std::vector<double> cvals( mycolv->getNumberOfQuantities() ); stash->retrieveSequentialValue( current, false, cvals );
+     289       21152 :   Vector fpos, apos = pbcDistance( origin, mycolv->getCentralAtomPos( mycolv->getPositionInFullTaskList(current) ) );
+     290       21152 :   if( fractional ) { fpos = getPbc().realToScaled( apos ); } else { fpos=apos; }
+     291             : 
+     292       84566 :   myvals.setValue( 0, cweight*cvals[0] ); for(unsigned j=0; j<directions.size(); ++j) myvals.setValue( 1+j, fpos[ directions[j] ] );
+     293       21152 :   myvals.setValue( 1+directions.size(), cvals[1] );
+     294       21152 : }
+     295             : 
+     296             : }
+     297             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.cpp.func-sort-c.html b/coverage/multicolvar/MultiColvarFilter.cpp.func-sort-c.html new file mode 100644 index 000000000000..7f8cf628cc17 --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarFilter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarFilter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:334082.5 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar17MultiColvarFilter15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar17MultiColvarFilterC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar17MultiColvarFilterC2ERKNS_13ActionOptionsE14
_ZN4PLMD11multicolvar17MultiColvarFilter16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD11multicolvar17MultiColvarFilter28doJobsRequiredBeforeTaskListEv46
_ZNK4PLMD11multicolvar17MultiColvarFilter12completeTaskERKjRNS_10MultiValueES5_20027
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.cpp.func.html b/coverage/multicolvar/MultiColvarFilter.cpp.func.html new file mode 100644 index 000000000000..31c4d38ca2e4 --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarFilter.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarFilter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:334082.5 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar17MultiColvarFilter15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar17MultiColvarFilter16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD11multicolvar17MultiColvarFilter28doJobsRequiredBeforeTaskListEv46
_ZN4PLMD11multicolvar17MultiColvarFilterC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar17MultiColvarFilterC2ERKNS_13ActionOptionsE14
_ZNK4PLMD11multicolvar17MultiColvarFilter12completeTaskERKjRNS_10MultiValueES5_20027
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.cpp.gcov.html b/coverage/multicolvar/MultiColvarFilter.cpp.gcov.html new file mode 100644 index 000000000000..52fd8184b947 --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.cpp.gcov.html @@ -0,0 +1,171 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarFilter.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarFilter.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:334082.5 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarFilter.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace multicolvar {
+      26             : 
+      27          26 : void MultiColvarFilter::registerKeywords( Keywords& keys ) {
+      28          26 :   BridgedMultiColvarFunction::registerKeywords( keys );
+      29          78 :   if( keys.reserved("VMEAN") ) keys.use("VMEAN");
+      30         104 :   keys.use("MEAN"); keys.use("MOMENTS"); keys.use("MIN"); keys.use("MAX");
+      31          78 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      32          26 : }
+      33             : 
+      34          14 : MultiColvarFilter::MultiColvarFilter(const ActionOptions&ao):
+      35             :   Action(ao),
+      36          14 :   BridgedMultiColvarFunction(ao)
+      37             : {
+      38          14 :   if( getPntrToMultiColvar()->isDensity() ) error("filtering/transforming density makes no sense");
+      39             : 
+      40          14 :   if( getName().find("MFILTER")!=std::string::npos ) filter=true;
+      41             :   else {
+      42           1 :     plumed_assert( getName().find("MTRANSFORM")!=std::string::npos );
+      43           1 :     filter=false;
+      44             :   }
+      45             : 
+      46          14 :   readVesselKeywords();
+      47          14 : }
+      48             : 
+      49          46 : void MultiColvarFilter::doJobsRequiredBeforeTaskList() {
+      50          46 :   ActionWithValue::clearDerivatives();
+      51          46 :   ActionWithVessel::doJobsRequiredBeforeTaskList();
+      52          46 : }
+      53             : 
+      54       20027 : void MultiColvarFilter::completeTask( const unsigned& curr, MultiValue& invals, MultiValue& outvals ) const {
+      55       20027 :   invals.copyValues( outvals );
+      56       20027 :   if( derivativesAreRequired() ) invals.copyDerivatives( outvals );
+      57             : 
+      58             :   // Retrieve the value of the multicolvar and apply filter
+      59       20027 :   double val=invals.get(1), df, weight=applyFilter( val, df );
+      60             : 
+      61             :   // Now propegate derivatives
+      62       20027 :   if( filter && !getPntrToMultiColvar()->weightHasDerivatives ) {
+      63             :     outvals.setValue( 0, weight );
+      64       18447 :     if( derivativesAreRequired() ) {
+      65     2268072 :       for(unsigned i=0; i<invals.getNumberActive(); ++i) {
+      66     2253501 :         unsigned jder=invals.getActiveIndex(i);
+      67     2253501 :         outvals.addDerivative( 0, jder, df*invals.getDerivative(1, jder ) );
+      68             :       }
+      69             :     }
+      70        1580 :   } else if( filter ) {
+      71           0 :     double ww=outvals.get(0); outvals.setValue( 0, ww*weight );
+      72           0 :     if( derivativesAreRequired() ) {
+      73           0 :       for(unsigned i=0; i<outvals.getNumberActive(); ++i) {
+      74           0 :         unsigned ider=outvals.getActiveIndex(i);
+      75           0 :         outvals.setDerivative( 0, ider, weight*outvals.getDerivative(1,ider) + ww*df*outvals.getDerivative(0,ider) );
+      76             :       }
+      77             :     }
+      78             :   } else {
+      79             :     outvals.setValue( 1, weight );
+      80        1580 :     if( derivativesAreRequired() ) {
+      81       80912 :       for(unsigned i=0; i<invals.getNumberActive(); ++i) {
+      82       79332 :         unsigned jder=invals.getActiveIndex(i);
+      83       79332 :         outvals.setDerivative( 1, jder, df*invals.getDerivative(1, jder ) );
+      84             :       }
+      85             :     }
+      86             :   }
+      87       20027 : }
+      88             : 
+      89           0 : void MultiColvarFilter::addBridgeForces( const std::vector<double>& bb ) {
+      90             :   plumed_dbg_assert( bb.size()==0 );
+      91           0 : }
+      92             : 
+      93             : }
+      94             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.h.func-sort-c.html b/coverage/multicolvar/MultiColvarFilter.h.func-sort-c.html new file mode 100644 index 000000000000..561492aa5561 --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarFilter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarFilter.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar17MultiColvarFilter21getNumberOfQuantitiesEv28202
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.h.func.html b/coverage/multicolvar/MultiColvarFilter.h.func.html new file mode 100644 index 000000000000..cc2a6f38f510 --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarFilter.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarFilter.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar17MultiColvarFilter21getNumberOfQuantitiesEv28202
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarFilter.h.gcov.html b/coverage/multicolvar/MultiColvarFilter.h.gcov.html new file mode 100644 index 000000000000..c3004bfb3ada --- /dev/null +++ b/coverage/multicolvar/MultiColvarFilter.h.gcov.html @@ -0,0 +1,140 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarFilter.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarFilter.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_multicolvar_MultiColvarFilter_h
+      23             : #define __PLUMED_multicolvar_MultiColvarFilter_h
+      24             : 
+      25             : #include "tools/HistogramBead.h"
+      26             : #include "BridgedMultiColvarFunction.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace multicolvar {
+      30             : 
+      31             : /**
+      32             : \ingroup INHERIT
+      33             : This is the abstract base class to use for implementing a new way of filtering collective variable values
+      34             : to see whether or not they are within a certain range
+      35             : */
+      36             : 
+      37             : class MultiColvarFilter : public BridgedMultiColvarFunction {
+      38             : private:
+      39             : /// Are we doing a filtering of the coordinates or a transoformation
+      40             :   bool filter;
+      41             : public:
+      42             :   static void registerKeywords( Keywords& keys );
+      43             :   explicit MultiColvarFilter(const ActionOptions&);
+      44             : /// Do everything required to setup the derivatives
+      45             :   void doJobsRequiredBeforeTaskList() override;
+      46             : /// Get the number of quantities in the colvar
+      47             :   unsigned getNumberOfQuantities() const override;
+      48             : /// Actually do what we are asked
+      49             :   void completeTask( const unsigned& curr, MultiValue& invals, MultiValue& outvals ) const override;
+      50             : /// Do the filtering
+      51             :   virtual double applyFilter( const double& val, double& df ) const=0;
+      52             : /// Just checks there are no bridging forces
+      53             :   void addBridgeForces( const std::vector<double>& bb );
+      54             : };
+      55             : 
+      56             : inline
+      57       28202 : unsigned MultiColvarFilter::getNumberOfQuantities() const {
+      58       28202 :   return getPntrToMultiColvar()->getNumberOfQuantities();
+      59             : }
+      60             : 
+      61             : }
+      62             : }
+      63             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarProduct.cpp.func-sort-c.html b/coverage/multicolvar/MultiColvarProduct.cpp.func-sort-c.html new file mode 100644 index 000000000000..b67759477879 --- /dev/null +++ b/coverage/multicolvar/MultiColvarProduct.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarProduct.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarProduct.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18MultiColvarProductC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar18MultiColvarProduct10isPeriodicEv1
_ZN4PLMD11multicolvar18MultiColvarProductC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarProduct16registerKeywordsERNS_8KeywordsE3
_ZNK4PLMD11multicolvar18MultiColvarProduct7computeERKjRNS0_13AtomValuePackE15
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarProduct.cpp.func.html b/coverage/multicolvar/MultiColvarProduct.cpp.func.html new file mode 100644 index 000000000000..7012c00a2c04 --- /dev/null +++ b/coverage/multicolvar/MultiColvarProduct.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarProduct.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarProduct.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18MultiColvarProduct10isPeriodicEv1
_ZN4PLMD11multicolvar18MultiColvarProduct16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar18MultiColvarProductC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar18MultiColvarProductC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar18MultiColvarProduct7computeERKjRNS0_13AtomValuePackE15
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/MultiColvarProduct.cpp.gcov.html b/coverage/multicolvar/MultiColvarProduct.cpp.gcov.html new file mode 100644 index 000000000000..fe73557e8b05 --- /dev/null +++ b/coverage/multicolvar/MultiColvarProduct.cpp.gcov.html @@ -0,0 +1,166 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/MultiColvarProduct.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - MultiColvarProduct.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : #include <string>
+      27             : #include <cmath>
+      28             : 
+      29             : //+PLUMEDOC MCOLVARF MCOLV_PRODUCT
+      30             : /*
+      31             : Calculate a product of multiple multicolvars
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace multicolvar {
+      40             : 
+      41             : class MultiColvarProduct : public MultiColvarBase {
+      42             : private:
+      43             : public:
+      44             :   static void registerKeywords( Keywords& keys );
+      45             :   explicit MultiColvarProduct(const ActionOptions&);
+      46             : /// Actually do the calculation
+      47             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      48             : /// Is the variable periodic
+      49           1 :   bool isPeriodic() override { return false; }
+      50             : };
+      51             : 
+      52             : PLUMED_REGISTER_ACTION(MultiColvarProduct,"MCOLV_PRODUCT")
+      53             : 
+      54           3 : void MultiColvarProduct::registerKeywords( Keywords& keys ) {
+      55           3 :   MultiColvarBase::registerKeywords( keys );
+      56           6 :   keys.add("compulsory","DATA","the multicolvars you are calculating the product of");
+      57          15 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("SUM"); keys.use("LESS_THAN"); keys.use("HISTOGRAM");
+      58          21 :   keys.use("MIN"); keys.use("MAX"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("ALT_MIN"); keys.use("BETWEEN"); keys.use("MOMENTS");
+      59           3 : }
+      60             : 
+      61           1 : MultiColvarProduct::MultiColvarProduct(const ActionOptions& ao):
+      62             :   Action(ao),
+      63           1 :   MultiColvarBase(ao)
+      64             : {
+      65           1 :   buildSets();
+      66           3 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+      67           2 :     if( mybasemulticolvars[i]->weightWithDerivatives() ) error("cannot take product of multicolvars with weights");
+      68             :   }
+      69           1 : }
+      70             : 
+      71          15 : double MultiColvarProduct::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+      72          15 :   double dot=1; std::vector<double> tval(2);
+      73          45 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+      74          30 :     getInputData( i, false, myatoms, tval );
+      75          30 :     dot *= tval[1];
+      76             :   }
+      77          15 :   if( !doNotCalculateDerivatives() ) {
+      78          15 :     std::vector<double> cc(2);
+      79          45 :     for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+      80          30 :       getInputData( i, false, myatoms, cc ); cc[1] = dot / cc[1];
+      81          30 :       MultiValue& myder=getInputDerivatives( i, false, myatoms );
+      82          30 :       splitInputDerivatives( 1, 1, 2, i, cc, myder, myatoms );
+      83             :     }
+      84             :   }
+      85          15 :   return dot;
+      86             : }
+      87             : 
+      88             : }
+      89             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/NumberOfLinks.cpp.func-sort-c.html b/coverage/multicolvar/NumberOfLinks.cpp.func-sort-c.html new file mode 100644 index 000000000000..d907c53ee221 --- /dev/null +++ b/coverage/multicolvar/NumberOfLinks.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/NumberOfLinks.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - NumberOfLinks.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505689.3 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13NumberOfLinks10isPeriodicEv0
_ZN4PLMD11multicolvar13NumberOfLinksC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar13NumberOfLinksC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar13NumberOfLinks16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD11multicolvar13NumberOfLinks15calculateWeightERKjRKdRNS0_13AtomValuePackE8064
_ZNK4PLMD11multicolvar13NumberOfLinks7computeERKjRNS0_13AtomValuePackE8064
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/NumberOfLinks.cpp.func.html b/coverage/multicolvar/NumberOfLinks.cpp.func.html new file mode 100644 index 000000000000..a5f6074e3fd0 --- /dev/null +++ b/coverage/multicolvar/NumberOfLinks.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/NumberOfLinks.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - NumberOfLinks.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505689.3 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar13NumberOfLinks10isPeriodicEv0
_ZN4PLMD11multicolvar13NumberOfLinks16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD11multicolvar13NumberOfLinksC1ERKNS_13ActionOptionsE4
_ZN4PLMD11multicolvar13NumberOfLinksC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar13NumberOfLinks15calculateWeightERKjRKdRNS0_13AtomValuePackE8064
_ZNK4PLMD11multicolvar13NumberOfLinks7computeERKjRNS0_13AtomValuePackE8064
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/NumberOfLinks.cpp.gcov.html b/coverage/multicolvar/NumberOfLinks.cpp.gcov.html new file mode 100644 index 000000000000..a5e6c97065ab --- /dev/null +++ b/coverage/multicolvar/NumberOfLinks.cpp.gcov.html @@ -0,0 +1,252 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/NumberOfLinks.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - NumberOfLinks.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:505689.3 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/SwitchingFunction.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : //+PLUMEDOC MCOLVARF NLINKS
+      31             : /*
+      32             : Calculate number of pairs of atoms/molecules that are linked
+      33             : 
+      34             : In its simplest guise this coordinate calculates a coordination number.  Each pair
+      35             : of atoms is assumed "linked" if they are within some cutoff of each other.  In more
+      36             : complex applications each entity is a vector and this quantity measures whether
+      37             : pairs of vectors are (a) within a certain cutoff and (b) if the two vectors have
+      38             : similar orientations.  The vectors on individual atoms could be Steinhardt parameters
+      39             : (see \ref Q3, \ref Q4 and \ref Q6) or they could describe some internal vector in a molecule.
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : The following calculates how many bonds there are in a system containing 64 atoms and outputs
+      44             : this quantity to a file.
+      45             : 
+      46             : \plumedfile
+      47             : DENSITY SPECIES=1-64 LABEL=d1
+      48             : NLINKS GROUP=d1 SWITCH={RATIONAL D_0=1.3 R_0=0.2} LABEL=dd
+      49             : PRINT ARG=dd FILE=colvar
+      50             : \endplumedfile
+      51             : 
+      52             : The following calculates how many pairs of neighboring atoms in a system containing 64 atoms have
+      53             : similar dispositions for the atoms in their coordination sphere.  This calculation uses the
+      54             : dot product of the Q6 vectors on adjacent atoms to measure whether or not two atoms have the same
+      55             : ``orientation"
+      56             : 
+      57             : \plumedfile
+      58             : Q6 SPECIES=1-64 SWITCH={RATIONAL D_0=1.3 R_0=0.2} LABEL=q6
+      59             : NLINKS GROUP=q6 SWITCH={RATIONAL D_0=1.3 R_0=0.2} LABEL=dd
+      60             : PRINT ARG=dd FILE=colvar
+      61             : \endplumedfile
+      62             : 
+      63             : */
+      64             : //+ENDPLUMEDOC
+      65             : 
+      66             : namespace PLMD {
+      67             : namespace multicolvar {
+      68             : 
+      69             : class NumberOfLinks : public MultiColvarBase {
+      70             : private:
+      71             : /// The values of the quantities in the dot products
+      72             :   std::vector<double> orient0, orient1;
+      73             : /// The switching function that tells us if atoms are close enough together
+      74             :   SwitchingFunction switchingFunction;
+      75             : public:
+      76             :   static void registerKeywords( Keywords& keys );
+      77             :   explicit NumberOfLinks(const ActionOptions&);
+      78             : /// Do the stuff with the switching functions
+      79             :   double calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const override;
+      80             : /// Actually do the calculation
+      81             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      82             : /// Is the variable periodic
+      83           0 :   bool isPeriodic() override { return false; }
+      84             : };
+      85             : 
+      86             : PLUMED_REGISTER_ACTION(NumberOfLinks,"NLINKS")
+      87             : 
+      88           6 : void NumberOfLinks::registerKeywords( Keywords& keys ) {
+      89           6 :   MultiColvarBase::registerKeywords( keys );
+      90          12 :   keys.add("atoms","GROUP","");
+      91          12 :   keys.add("atoms-1","GROUPA","");
+      92          12 :   keys.add("atoms-1","GROUPB","");
+      93          12 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
+      94          12 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
+      95          12 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      96          12 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
+      97          12 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
+      98             :            "The following provides information on the \\ref switchingfunction that are available. "
+      99             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
+     100             :   // Use actionWithDistributionKeywords
+     101           6 :   keys.remove("LOWMEM");
+     102          12 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+     103           6 : }
+     104             : 
+     105           4 : NumberOfLinks::NumberOfLinks(const ActionOptions& ao):
+     106             :   Action(ao),
+     107           4 :   MultiColvarBase(ao)
+     108             : {
+     109             :   // The weight of this does have derivatives
+     110           4 :   weightHasDerivatives=true;
+     111             : 
+     112             :   // Read in the switching function
+     113           8 :   std::string sw, errors; parse("SWITCH",sw);
+     114           4 :   if(sw.length()>0) {
+     115           4 :     switchingFunction.set(sw,errors);
+     116             :   } else {
+     117           0 :     double r_0=-1.0, d_0; int nn, mm;
+     118           0 :     parse("NN",nn); parse("MM",mm);
+     119           0 :     parse("R_0",r_0); parse("D_0",d_0);
+     120           0 :     if( r_0<0.0 ) error("you must set a value for R_0");
+     121           0 :     switchingFunction.set(nn,mm,r_0,d_0);
+     122             :   }
+     123           8 :   log.printf("  calculating number of links with atoms separation of %s\n",( switchingFunction.description() ).c_str() );
+     124           8 :   std::vector<AtomNumber> all_atoms; readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     125           4 :   setupMultiColvarBase( all_atoms ); setLinkCellCutoff( switchingFunction.get_dmax() );
+     126             : 
+     127           8 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+     128           4 :     if( !getBaseMultiColvar(i)->hasDifferentiableOrientation() ) error("cannot use multicolvar of type " + getBaseMultiColvar(i)->getName() );
+     129             :   }
+     130             : 
+     131             :   // Create holders for the collective variable
+     132           4 :   readVesselKeywords();
+     133           4 :   plumed_assert( getNumberOfVessels()==0 );
+     134           4 :   std::string input; addVessel( "SUM", input, -1 );
+     135           4 :   readVesselKeywords();
+     136           4 : }
+     137             : 
+     138        8064 : double NumberOfLinks::calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const {
+     139        8064 :   Vector distance = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     140        8064 :   double dfunc, sw = switchingFunction.calculateSqr( distance.modulo2(), dfunc );
+     141             : 
+     142        8064 :   if( !doNotCalculateDerivatives() ) {
+     143        8064 :     addAtomDerivatives( 0, 0, (-dfunc)*weight*distance, myatoms );
+     144        8064 :     addAtomDerivatives( 0, 1, (dfunc)*weight*distance, myatoms );
+     145        8064 :     myatoms.addBoxDerivatives( 0, (-dfunc)*weight*Tensor(distance,distance) );
+     146             :   }
+     147        8064 :   return sw;
+     148             : }
+     149             : 
+     150        8064 : double NumberOfLinks::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     151        8064 :   if( getBaseMultiColvar(0)->getNumberOfQuantities()<3 ) return 1.0;
+     152             : 
+     153        8064 :   unsigned ncomp=getBaseMultiColvar(0)->getNumberOfQuantities();
+     154             : 
+     155        8064 :   std::vector<double> orient0( ncomp ), orient1( ncomp );
+     156        8064 :   getInputData( 0, true, myatoms, orient0 );
+     157        8064 :   getInputData( 1, true, myatoms, orient1 );
+     158             : 
+     159             :   double dot=0;
+     160      185472 :   for(unsigned k=2; k<orient0.size(); ++k) {
+     161      177408 :     dot+=orient0[k]*orient1[k];
+     162             :   }
+     163             : 
+     164        8064 :   if( !doNotCalculateDerivatives() ) {
+     165        8064 :     MultiValue& myder0=getInputDerivatives( 0, true, myatoms );
+     166        8064 :     mergeInputDerivatives( 1, 2, orient1.size(), 0, orient1, myder0, myatoms );
+     167        8064 :     MultiValue& myder1=getInputDerivatives( 1, true, myatoms );
+     168        8064 :     mergeInputDerivatives( 1, 2, orient0.size(), 1, orient0, myder1, myatoms );
+     169             :   }
+     170             : 
+     171             :   return dot;
+     172             : }
+     173             : 
+     174             : }
+     175             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Torsions.cpp.func-sort-c.html b/coverage/multicolvar/Torsions.cpp.func-sort-c.html new file mode 100644 index 000000000000..43e8f95ea0f4 --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Torsions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Torsions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar8TorsionsC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar8Torsions14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_2
_ZN4PLMD11multicolvar8TorsionsC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar8Torsions16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar8Torsions10isPeriodicEv5
_ZNK4PLMD11multicolvar8Torsions7computeERKjRNS0_13AtomValuePackE36
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Torsions.cpp.func.html b/coverage/multicolvar/Torsions.cpp.func.html new file mode 100644 index 000000000000..1e330b1a1cc7 --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Torsions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Torsions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar8Torsions10isPeriodicEv5
_ZN4PLMD11multicolvar8Torsions14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_2
_ZN4PLMD11multicolvar8Torsions16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar8TorsionsC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar8TorsionsC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar8Torsions7computeERKjRNS0_13AtomValuePackE36
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/Torsions.cpp.gcov.html b/coverage/multicolvar/Torsions.cpp.gcov.html new file mode 100644 index 000000000000..33cb3149736d --- /dev/null +++ b/coverage/multicolvar/Torsions.cpp.gcov.html @@ -0,0 +1,212 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/Torsions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - Torsions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "tools/Torsion.h"
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace multicolvar {
+      32             : 
+      33             : //+PLUMEDOC MCOLVAR TORSIONS
+      34             : /*
+      35             : Calculate whether or not a set of torsional angles are within a particular range.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : The following provides an example of the input for the TORSIONS command
+      40             : 
+      41             : \plumedfile
+      42             : TORSIONS ...
+      43             : ATOMS1=168,170,172,188
+      44             : ATOMS2=170,172,188,190
+      45             : ATOMS3=188,190,192,230
+      46             : BETWEEN={GAUSSIAN LOWER=0 UPPER=pi SMEAR=0.1}
+      47             : LABEL=ab
+      48             : ... TORSIONS
+      49             : PRINT ARG=ab.* FILE=colvar STRIDE=10
+      50             : \endplumedfile
+      51             : 
+      52             : Writing out the atoms involved in all the torsion angles in this way can be rather tedious. Thankfully if you are working with protein you
+      53             : can avoid this by using the \ref MOLINFO command.  PLUMED uses the pdb file that you provide to this command to learn
+      54             : about the topology of the protein molecule.  This means that you can specify torsion angles using the following syntax:
+      55             : 
+      56             : \plumedfile
+      57             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      58             : MOLINFO MOLTYPE=protein STRUCTURE=myprotein.pdb
+      59             : TORSIONS ...
+      60             : ATOMS1=@phi-3
+      61             : ATOMS2=@psi-3
+      62             : ATOMS3=@phi-4
+      63             : BETWEEN={GAUSSIAN LOWER=0 UPPER=pi SMEAR=0.1}
+      64             : LABEL=ab
+      65             : ... TORSIONS
+      66             : PRINT ARG=ab.* FILE=colvar STRIDE=10
+      67             : \endplumedfile
+      68             : 
+      69             : Here, \@phi-3 tells plumed that you would like to calculate the \f$\phi\f$ angle in the third residue of the protein.
+      70             : Similarly \@psi-4 tells plumed that you want to calculate the \f$\psi\f$ angle of the fourth residue of the protein.
+      71             : 
+      72             : 
+      73             : */
+      74             : //+ENDPLUMEDOC
+      75             : 
+      76             : class Torsions : public MultiColvarBase {
+      77             : public:
+      78             :   static void registerKeywords( Keywords& keys );
+      79             :   explicit Torsions(const ActionOptions&);
+      80             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      81           5 :   bool isPeriodic() override { return true; }
+      82           2 :   void retrieveDomain( std::string& min, std::string& max ) override { min="-pi"; max="pi"; }
+      83             : };
+      84             : 
+      85             : PLUMED_REGISTER_ACTION(Torsions,"TORSIONS")
+      86             : 
+      87           4 : void Torsions::registerKeywords( Keywords& keys ) {
+      88           4 :   MultiColvarBase::registerKeywords( keys );
+      89           8 :   keys.add("numbered","ATOMS","the atoms involved in each of the torsion angles you wish to calculate. "
+      90             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one torsion will be "
+      91             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+      92             :            "provide the indices of four atoms).  The eventual number of quantities calculated by this "
+      93             :            "action will depend on what functions of the distribution you choose to calculate.");
+      94           8 :   keys.reset_style("ATOMS","atoms");
+      95           8 :   keys.use("BETWEEN"); keys.use("HISTOGRAM");
+      96           4 : }
+      97             : 
+      98           2 : Torsions::Torsions(const ActionOptions&ao):
+      99             :   Action(ao),
+     100           2 :   MultiColvarBase(ao)
+     101             : {
+     102             :   // Read in the atoms
+     103           2 :   int natoms=4; std::vector<AtomNumber> all_atoms;
+     104           2 :   readAtomsLikeKeyword( "ATOMS", natoms, all_atoms );
+     105           2 :   setupMultiColvarBase( all_atoms );
+     106           2 :   std::vector<bool> catom_ind(4, false);
+     107           2 :   catom_ind[1]=catom_ind[2]=true;
+     108           2 :   setAtomsForCentralAtom( catom_ind );
+     109             :   // Read in the vessels
+     110           2 :   readVesselKeywords();
+     111             :   // And check everything has been read in correctly
+     112           2 :   checkRead();
+     113           2 : }
+     114             : 
+     115          36 : double Torsions::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     116          36 :   Vector d0,d1,d2;
+     117          36 :   d0=getSeparation(myatoms.getPosition(1),myatoms.getPosition(0));
+     118          36 :   d1=getSeparation(myatoms.getPosition(2),myatoms.getPosition(1));
+     119          36 :   d2=getSeparation(myatoms.getPosition(3),myatoms.getPosition(2));
+     120             : 
+     121          36 :   Vector dd0,dd1,dd2; PLMD::Torsion t;
+     122          36 :   double value  = t.compute(d0,d1,d2,dd0,dd1,dd2);
+     123             : 
+     124          36 :   addAtomDerivatives(1,0,dd0,myatoms);
+     125          36 :   addAtomDerivatives(1,1,dd1-dd0,myatoms);
+     126          36 :   addAtomDerivatives(1,2,dd2-dd1,myatoms);
+     127          36 :   addAtomDerivatives(1,3,-dd2,myatoms);
+     128             : 
+     129          36 :   myatoms.addBoxDerivatives  (1, -(extProduct(d0,dd0)+extProduct(d1,dd1)+extProduct(d2,dd2)));
+     130             : 
+     131          36 :   return value;
+     132             : }
+     133             : 
+     134             : }
+     135             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeAround.cpp.func-sort-c.html b/coverage/multicolvar/VolumeAround.cpp.func-sort-c.html new file mode 100644 index 000000000000..e733c1779b59 --- /dev/null +++ b/coverage/multicolvar/VolumeAround.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeAround.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeAround.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4747100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12VolumeAroundC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12VolumeAroundC1ERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12VolumeAround16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD11multicolvar12VolumeAround12setupRegionsEv317
_ZNK4PLMD11multicolvar12VolumeAround21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE56393
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeAround.cpp.func.html b/coverage/multicolvar/VolumeAround.cpp.func.html new file mode 100644 index 000000000000..096d3cd208b3 --- /dev/null +++ b/coverage/multicolvar/VolumeAround.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeAround.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeAround.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4747100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12VolumeAround12setupRegionsEv317
_ZN4PLMD11multicolvar12VolumeAround16registerKeywordsERNS_8KeywordsE24
_ZN4PLMD11multicolvar12VolumeAroundC1ERKNS_13ActionOptionsE22
_ZN4PLMD11multicolvar12VolumeAroundC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar12VolumeAround21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE56393
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeAround.cpp.gcov.html b/coverage/multicolvar/VolumeAround.cpp.gcov.html new file mode 100644 index 000000000000..f731a1ba8f0d --- /dev/null +++ b/coverage/multicolvar/VolumeAround.cpp.gcov.html @@ -0,0 +1,231 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeAround.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeAround.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4747100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/Pbc.h"
+      24             : #include "ActionVolume.h"
+      25             : 
+      26             : //+PLUMEDOC VOLUMES AROUND
+      27             : /*
+      28             : This quantity can be used to calculate functions of the distribution of collective variables for the atoms that lie in a particular, user-specified part of of the cell.
+      29             : 
+      30             : Each of the base quantities calculated by a multicolvar can can be assigned to a particular point in three
+      31             : dimensional space. For example, if we have the coordination numbers for all the atoms in the
+      32             : system each coordination number can be assumed to lie on the position of the central atom.
+      33             : Because each base quantity can be assigned to a particular point in space we can calculate functions of the
+      34             : distribution of base quantities in a particular part of the box by using:
+      35             : 
+      36             : \f[
+      37             : \overline{s}_{\tau} = \frac{ \sum_i f(s_i) w(x_i,y_i,z_i) }{ \sum_i w(x_i,y_i,z_i) }
+      38             : \f]
+      39             : 
+      40             : where the sum is over the collective variables, \f$s_i\f$, each of which can be thought to be at \f$ (x_i,y_i,z_i)\f$.
+      41             : The function \f$ w(x_i,y_i,z_i) \f$ measures whether or not the system is in the subregion of interest. It
+      42             : is equal to:
+      43             : 
+      44             : \f[
+      45             : w(x_i,y_i,z_i) = \int_{xl}^{xu} \int_{yl}^{yu} \int_{zl}^{zu} \textrm{d}x\textrm{d}y\textrm{d}z K\left( \frac{x - x_i}{\sigma} \right)K\left( \frac{y - y_i}{\sigma} \right)K\left( \frac{z - z_i}{\sigma} \right)
+      46             : \f]
+      47             : 
+      48             : where \f$K\f$ is one of the kernel functions described on \ref histogrambead and \f$\sigma\f$ is a bandwidth parameter.
+      49             : The function \f$(s_i)\f$ can be any of the usual LESS_THAN, MORE_THAN, WITHIN etc that are used in all other multicolvars.
+      50             : 
+      51             : When AROUND is used with the \ref DENSITY action the number of atoms in the specified region is calculated
+      52             : 
+      53             : \par Examples
+      54             : 
+      55             : The following commands tell plumed to calculate the average coordination number for the atoms
+      56             : that have x (in fractional coordinates) within 2.0 nm of the com of mass c1. The final value will be labeled s.mean.
+      57             : \plumedfile
+      58             : COM ATOMS=1-100 LABEL=c1
+      59             : COORDINATIONNUMBER SPECIES=1-100 R_0=1.0 LABEL=c
+      60             : AROUND DATA=c ATOM=c1 XLOWER=-2.0 XUPPER=2.0 SIGMA=0.1 MEAN LABEL=s
+      61             : \endplumedfile
+      62             : 
+      63             : */
+      64             : //+ENDPLUMEDOC
+      65             : 
+      66             : namespace PLMD {
+      67             : namespace multicolvar {
+      68             : 
+      69             : class VolumeAround : public ActionVolume {
+      70             : private:
+      71             :   Vector origin;
+      72             :   bool dox, doy, doz;
+      73             :   double xlow, xhigh;
+      74             :   double ylow, yhigh;
+      75             :   double zlow, zhigh;
+      76             : public:
+      77             :   static void registerKeywords( Keywords& keys );
+      78             :   explicit VolumeAround(const ActionOptions& ao);
+      79             :   void setupRegions() override;
+      80             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+      81             : };
+      82             : 
+      83             : PLUMED_REGISTER_ACTION(VolumeAround,"AROUND")
+      84             : 
+      85          24 : void VolumeAround::registerKeywords( Keywords& keys ) {
+      86          24 :   ActionVolume::registerKeywords( keys );
+      87          48 :   keys.add("atoms","ATOM","the atom whose vicinity we are interested in examining");
+      88          48 :   keys.add("compulsory","XLOWER","0.0","the lower boundary in x relative to the x coordinate of the atom (0 indicates use full extent of box).");
+      89          48 :   keys.add("compulsory","XUPPER","0.0","the upper boundary in x relative to the x coordinate of the atom (0 indicates use full extent of box).");
+      90          48 :   keys.add("compulsory","YLOWER","0.0","the lower boundary in y relative to the y coordinate of the atom (0 indicates use full extent of box).");
+      91          48 :   keys.add("compulsory","YUPPER","0.0","the upper boundary in y relative to the y coordinate of the atom (0 indicates use full extent of box).");
+      92          48 :   keys.add("compulsory","ZLOWER","0.0","the lower boundary in z relative to the z coordinate of the atom (0 indicates use full extent of box).");
+      93          48 :   keys.add("compulsory","ZUPPER","0.0","the upper boundary in z relative to the z coordinate of the atom (0 indicates use full extent of box).");
+      94          24 : }
+      95             : 
+      96          22 : VolumeAround::VolumeAround(const ActionOptions& ao):
+      97             :   Action(ao),
+      98          22 :   ActionVolume(ao)
+      99             : {
+     100             :   std::vector<AtomNumber> atom;
+     101          44 :   parseAtomList("ATOM",atom);
+     102          22 :   if( atom.size()!=1 ) error("should only be one atom specified");
+     103          22 :   log.printf("  boundaries for region are calculated based on positions of atom : %d\n",atom[0].serial() );
+     104             : 
+     105          44 :   dox=true; parse("XLOWER",xlow); parse("XUPPER",xhigh);
+     106          44 :   doy=true; parse("YLOWER",ylow); parse("YUPPER",yhigh);
+     107          44 :   doz=true; parse("ZLOWER",zlow); parse("ZUPPER",zhigh);
+     108          22 :   if( xlow==0.0 && xhigh==0.0 ) dox=false;
+     109          22 :   if( ylow==0.0 && yhigh==0.0 ) doy=false;
+     110          22 :   if( zlow==0.0 && zhigh==0.0 ) doz=false;
+     111          22 :   if( !dox && !doy && !doz ) error("no subregion defined use XLOWER, XUPPER, YLOWER, YUPPER, ZLOWER, ZUPPER");
+     112          22 :   log.printf("  boundaries for region (region of interest about atom) : x %f %f, y %f %f, z %f %f \n",xlow,xhigh,ylow,yhigh,zlow,zhigh);
+     113          22 :   checkRead(); requestAtoms(atom);
+     114          22 : }
+     115             : 
+     116         317 : void VolumeAround::setupRegions() { }
+     117             : 
+     118       56393 : double VolumeAround::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     119             :   // Setup the histogram bead
+     120      112786 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( getKernelType() );
+     121             : 
+     122             :   // Calculate position of atom wrt to origin
+     123       56393 :   Vector fpos=pbcDistance( getPosition(0), cpos );
+     124             :   double xcontr, ycontr, zcontr, xder, yder, zder;
+     125       56393 :   if( dox ) {
+     126       32393 :     bead.set( xlow, xhigh, getSigma() );
+     127       32393 :     xcontr=bead.calculate( fpos[0], xder );
+     128             :   } else {
+     129       24000 :     xcontr=1.; xder=0.;
+     130             :   }
+     131       56393 :   if( doy ) {
+     132       32000 :     bead.set( ylow, yhigh, getSigma() );
+     133       32000 :     ycontr=bead.calculate( fpos[1], yder );
+     134             :   } else {
+     135       24393 :     ycontr=1.; yder=0.;
+     136             :   }
+     137       56393 :   if( doz ) {
+     138       32000 :     bead.set( zlow, zhigh, getSigma() );
+     139       32000 :     zcontr=bead.calculate( fpos[2], zder );
+     140             :   } else {
+     141       24393 :     zcontr=1.; zder=0.;
+     142             :   }
+     143       56393 :   derivatives[0]=xder*ycontr*zcontr;
+     144       56393 :   derivatives[1]=xcontr*yder*zcontr;
+     145       56393 :   derivatives[2]=xcontr*ycontr*zder;
+     146             :   // Add derivatives wrt to position of origin atom
+     147       56393 :   refders[0] = -derivatives;
+     148             :   // Add virial contribution
+     149       56393 :   vir -= Tensor(fpos,derivatives);
+     150       56393 :   return xcontr*ycontr*zcontr;
+     151             : }
+     152             : 
+     153             : }
+     154             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeBetweenContours.cpp.func-sort-c.html b/coverage/multicolvar/VolumeBetweenContours.cpp.func-sort-c.html new file mode 100644 index 000000000000..dbce7befe893 --- /dev/null +++ b/coverage/multicolvar/VolumeBetweenContours.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeBetweenContours.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeBetweenContours.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:64912.2 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar16VolumeInEnvelope12setupRegionsEv0
_ZN4PLMD11multicolvar16VolumeInEnvelopeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16VolumeInEnvelopeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16VolumeInEnvelope21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
_ZN4PLMD11multicolvar16VolumeInEnvelope16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeBetweenContours.cpp.func.html b/coverage/multicolvar/VolumeBetweenContours.cpp.func.html new file mode 100644 index 000000000000..065e3db6c5ef --- /dev/null +++ b/coverage/multicolvar/VolumeBetweenContours.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeBetweenContours.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeBetweenContours.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:64912.2 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar16VolumeInEnvelope12setupRegionsEv0
_ZN4PLMD11multicolvar16VolumeInEnvelope16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar16VolumeInEnvelopeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16VolumeInEnvelopeC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16VolumeInEnvelope21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeBetweenContours.cpp.gcov.html b/coverage/multicolvar/VolumeBetweenContours.cpp.gcov.html new file mode 100644 index 000000000000..1b71497ff695 --- /dev/null +++ b/coverage/multicolvar/VolumeBetweenContours.cpp.gcov.html @@ -0,0 +1,223 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeBetweenContours.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeBetweenContours.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:64912.2 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/Pbc.h"
+      24             : #include "tools/KernelFunctions.h"
+      25             : #include "tools/SwitchingFunction.h"
+      26             : #include "ActionVolume.h"
+      27             : #include <memory>
+      28             : 
+      29             : //+PLUMEDOC VOLUMES INENVELOPE
+      30             : /*
+      31             : This quantity can be used to calculate functions of the distribution of collective variables for the atoms that lie in a region where the density of a certain type of atom is high.
+      32             : 
+      33             : This collective variable can be used to determine whether colvars are within region where the density
+      34             : of a particular atom is high.  This is achieved by calculating the following function at the point where
+      35             : the atom is located \f$(x,y,z)\f$:
+      36             : 
+      37             : \f[
+      38             : w_j = 1 - \sigma\left[ \sum_{i=1}^N K\left( \frac{x-x_i}{\sigma_x},\frac{y-y_i}{\sigma_y},\frac{z-z_i}{\sigma_z} \right) \right]
+      39             : \f]
+      40             : 
+      41             : Here \f$\sigma\f$ is a \ref switchingfunction and \f$K\f$ is a \ref kernelfunctions.  The sum runs over the atoms
+      42             : specified using the ATOMS keyword and a \f$w_j\f$ value is calculated for each of the central atoms of the input
+      43             : multicolvar.
+      44             : 
+      45             : \par Examples
+      46             : 
+      47             : The input below calculates a density field from the positions of atoms 1-14400.  The number of the atoms
+      48             : that are specified in the DENSITY action that are within a region where the density field is greater than
+      49             : 2.0 is then calculated.
+      50             : 
+      51             : \plumedfile
+      52             : d1: DENSITY SPECIES=14401-74134:3 LOWMEM
+      53             : fi: INENVELOPE DATA=d1 ATOMS=1-14400 CONTOUR={RATIONAL D_0=2.0 R_0=1.0} BANDWIDTH=0.1,0.1,0.1 LOWMEM
+      54             : PRINT ARG=fi FILE=colvar
+      55             : \endplumedfile
+      56             : 
+      57             : */
+      58             : //+ENDPLUMEDOC
+      59             : 
+      60             : namespace PLMD {
+      61             : namespace multicolvar {
+      62             : 
+      63             : class VolumeInEnvelope : public ActionVolume {
+      64             : private:
+      65             :   LinkCells mylinks;
+      66             :   std::unique_ptr<KernelFunctions> kernel;
+      67             :   std::vector<std::unique_ptr<Value>> pos;
+      68             :   std::vector<Vector> ltmp_pos;
+      69             :   std::vector<unsigned> ltmp_ind;
+      70             :   SwitchingFunction sfunc;
+      71             : public:
+      72             :   static void registerKeywords( Keywords& keys );
+      73             :   explicit VolumeInEnvelope(const ActionOptions& ao);
+      74             :   void setupRegions() override;
+      75             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+      76             : };
+      77             : 
+      78             : PLUMED_REGISTER_ACTION(VolumeInEnvelope,"INENVELOPE")
+      79             : 
+      80           2 : void VolumeInEnvelope::registerKeywords( Keywords& keys ) {
+      81           2 :   ActionVolume::registerKeywords( keys ); keys.remove("SIGMA");
+      82           4 :   keys.add("atoms","ATOMS","the atom whose positions we are constructing a field from");
+      83           4 :   keys.add("compulsory","BANDWIDTH","the bandwidths for kernel density estimation");
+      84           4 :   keys.add("compulsory","CONTOUR","a switching function that tells PLUMED how large the density should be");
+      85           2 : }
+      86             : 
+      87           0 : VolumeInEnvelope::VolumeInEnvelope(const ActionOptions& ao):
+      88             :   Action(ao),
+      89             :   ActionVolume(ao),
+      90           0 :   mylinks(comm)
+      91             : {
+      92           0 :   std::vector<AtomNumber> atoms; parseAtomList("ATOMS",atoms);
+      93           0 :   log.printf("  creating density field from atoms : ");
+      94           0 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial() );
+      95           0 :   log.printf("\n"); ltmp_ind.resize( atoms.size() ); ltmp_pos.resize( atoms.size() );
+      96           0 :   for(unsigned i=0; i<atoms.size(); ++i) ltmp_ind[i]=i;
+      97             : 
+      98           0 :   std::string sw, errors; parse("CONTOUR",sw);
+      99           0 :   if(sw.length()==0) error("missing CONTOURkeyword");
+     100           0 :   sfunc.set(sw,errors);
+     101           0 :   if( errors.length()!=0 ) error("problem reading RADIUS keyword : " + errors );
+     102           0 :   log.printf("  density at atom must be larger than %s \n", ( sfunc.description() ).c_str() );
+     103             : 
+     104           0 :   std::vector<double> pp(3,0.0), bandwidth(3); parseVector("BANDWIDTH",bandwidth);
+     105           0 :   log.printf("  using %s kernel with bandwidths %f %f %f \n",getKernelType().c_str(),bandwidth[0],bandwidth[1],bandwidth[2] );
+     106           0 :   kernel=Tools::make_unique<KernelFunctions>( pp, bandwidth, getKernelType(), "DIAGONAL", 1.0 );
+     107           0 :   for(unsigned i=0; i<3; ++i) { pos.emplace_back(Tools::make_unique<Value>()); pos[i]->setNotPeriodic(); }
+     108           0 :   std::vector<double> csupport( kernel->getContinuousSupport() );
+     109           0 :   double maxs = csupport[0];
+     110           0 :   for(unsigned i=1; i<csupport.size(); ++i) {
+     111           0 :     if( csupport[i]>maxs ) maxs = csupport[i];
+     112             :   }
+     113           0 :   checkRead(); requestAtoms(atoms); mylinks.setCutoff( maxs );
+     114           0 : }
+     115             : 
+     116           0 : void VolumeInEnvelope::setupRegions() {
+     117           0 :   for(unsigned i=0; i<ltmp_ind.size(); ++i) { ltmp_pos[i]=getPosition(i); }
+     118           0 :   mylinks.buildCellLists( ltmp_pos, ltmp_ind, getPbc() );
+     119           0 : }
+     120             : 
+     121           0 : double VolumeInEnvelope::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     122           0 :   unsigned ncells_required=0, natoms=1; std::vector<unsigned> cells_required( mylinks.getNumberOfCells() ), indices( 1 + getNumberOfAtoms() );
+     123           0 :   mylinks.addRequiredCells( mylinks.findMyCell( cpos ), ncells_required, cells_required );
+     124           0 :   indices[0]=getNumberOfAtoms(); mylinks.retrieveAtomsInCells( ncells_required, cells_required, natoms, indices );
+     125           0 :   double value=0; std::vector<double> der(3); Vector tder;
+     126             : 
+     127             :   // convert pointer once
+     128           0 :   auto pos_ptr=Tools::unique2raw(pos);
+     129             : 
+     130           0 :   for(unsigned i=1; i<natoms; ++i) {
+     131           0 :     Vector dist = getSeparation( cpos, getPosition( indices[i] ) );
+     132           0 :     for(unsigned j=0; j<3; ++j) pos[j]->set( dist[j] );
+     133           0 :     value += kernel->evaluate( pos_ptr, der, true );
+     134           0 :     for(unsigned j=0; j<3; ++j) {
+     135           0 :       derivatives[j] -= der[j]; refders[ indices[i] ][j] += der[j]; tder[j]=der[j];
+     136             :     }
+     137           0 :     vir -= Tensor( tder, dist );
+     138             :   }
+     139           0 :   double deriv, fval = sfunc.calculate( value, deriv );
+     140           0 :   derivatives *= -deriv*value; vir *= -deriv*value;
+     141           0 :   for(unsigned i=1; i<natoms; ++i) refders[ indices[i] ] *= -deriv*value;
+     142           0 :   return 1.0 - fval;
+     143             : }
+     144             : 
+     145             : }
+     146             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeCavity.cpp.func-sort-c.html b/coverage/multicolvar/VolumeCavity.cpp.func-sort-c.html new file mode 100644 index 000000000000..1e17244aa783 --- /dev/null +++ b/coverage/multicolvar/VolumeCavity.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeCavity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeCavity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16921379.3 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12VolumeCavityC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12VolumeCavityD2Ev0
_ZN4PLMD11multicolvar12VolumeCavityC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12VolumeCavityD0Ev2
_ZN4PLMD11multicolvar12VolumeCavityD1Ev2
_ZN4PLMD11multicolvar12VolumeCavity16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar12VolumeCavity6updateEv120
_ZN4PLMD11multicolvar12VolumeCavity12setupRegionsEv1620
_ZNK4PLMD11multicolvar12VolumeCavity21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE1620
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeCavity.cpp.func.html b/coverage/multicolvar/VolumeCavity.cpp.func.html new file mode 100644 index 000000000000..a8b8e7102260 --- /dev/null +++ b/coverage/multicolvar/VolumeCavity.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeCavity.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeCavity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16921379.3 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar12VolumeCavity12setupRegionsEv1620
_ZN4PLMD11multicolvar12VolumeCavity16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD11multicolvar12VolumeCavity6updateEv120
_ZN4PLMD11multicolvar12VolumeCavityC1ERKNS_13ActionOptionsE2
_ZN4PLMD11multicolvar12VolumeCavityC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar12VolumeCavityD0Ev2
_ZN4PLMD11multicolvar12VolumeCavityD1Ev2
_ZN4PLMD11multicolvar12VolumeCavityD2Ev0
_ZNK4PLMD11multicolvar12VolumeCavity21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE1620
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeCavity.cpp.gcov.html b/coverage/multicolvar/VolumeCavity.cpp.gcov.html new file mode 100644 index 000000000000..55d9a5e61de6 --- /dev/null +++ b/coverage/multicolvar/VolumeCavity.cpp.gcov.html @@ -0,0 +1,487 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeCavity.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeCavity.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:16921379.3 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/Units.h"
+      24             : #include "tools/Pbc.h"
+      25             : #include "ActionVolume.h"
+      26             : 
+      27             : //+PLUMEDOC VOLUMES CAVITY
+      28             : /*
+      29             : This quantity can be used to calculate functions of the distribution of collective variables for the atoms that lie in a box defined by the positions of four atoms.
+      30             : 
+      31             : Each of the base quantities calculated by a multicolvar can can be assigned to a particular point in three
+      32             : dimensional space. For example, if we have the coordination numbers for all the atoms in the
+      33             : system each coordination number can be assumed to lie on the position of the central atom.
+      34             : Because each base quantity can be assigned to a particular point in space we can calculate functions of the
+      35             : distribution of base quantities in a particular part of the box by using:
+      36             : 
+      37             : \f[
+      38             : \overline{s}_{\tau} = \frac{ \sum_i f(s_i) w(u_i,v_i,w_i) }{ \sum_i w(u_i,v_i,w_i) }
+      39             : \f]
+      40             : 
+      41             : where the sum is over the collective variables, \f$s_i\f$, each of which can be thought to be at \f$ (u_i,v_i,z_i)\f$.
+      42             : The function \f$(s_i)\f$ can be any of the usual LESS_THAN, MORE_THAN, WITHIN etc that are used in all other multicolvars.
+      43             : Notice that here (at variance with what is done in \ref AROUND) we have transformed from the usual \f$(x_i,y_i,z_i)\f$
+      44             : position to a position in \f$ (u_i,v_i,z_i)\f$.  This is done using a rotation matrix as follows:
+      45             : 
+      46             : \f[
+      47             : \left(
+      48             : \begin{matrix}
+      49             :  u_i \\
+      50             :  v_i \\
+      51             :  w_i
+      52             : \end{matrix}
+      53             : \right) = \mathbf{R}
+      54             : \left(
+      55             : \begin{matrix}
+      56             :  x_i - x_o \\
+      57             :  y_i - y_o \\
+      58             :  z_i - z_o
+      59             : \end{matrix}
+      60             : \right)
+      61             : \f]
+      62             : 
+      63             : where \f$\mathbf{R}\f$ is a rotation matrix that is calculated by constructing a set of three orthonormal vectors from the
+      64             : reference positions specified by the user. The first of these unit vectors points from the first reference atom to the second.
+      65             : The second is then the normal to the plane containing atoms 1,2 and 3 and the the third is the unit vector orthogonal to
+      66             : these first two vectors.  \f$(x_o,y_o,z_o)\f$, meanwhile, specifies the position of the first reference atom.
+      67             : 
+      68             : In the previous function \f$ w(u_i,v_i,w_i) \f$ measures whether or not the system is in the subregion of interest. It
+      69             : is equal to:
+      70             : 
+      71             : \f[
+      72             : w(u_i,v_i,w_i) = \int_{0}^{u'} \int_{0}^{v'} \int_{0}^{w'} \textrm{d}u\textrm{d}v\textrm{d}w
+      73             :    K\left( \frac{u - u_i}{\sigma} \right)K\left( \frac{v - v_i}{\sigma} \right)K\left( \frac{w - w_i}{\sigma} \right)
+      74             : \f]
+      75             : 
+      76             : where \f$K\f$ is one of the kernel functions described on \ref histogrambead and \f$\sigma\f$ is a bandwidth parameter.
+      77             : The vector connecting atom 1 to atom 4 is used to define the extent of the box in each of the \f$u\f$, \f$v\f$ and \f$w\f$
+      78             : directions.  Essentially the vector connecting atom 1 to atom 4 is projected onto the three unit vectors
+      79             : described above and the resulting projections determine the \f$u'\f$, \f$v'\f$ and \f$w'\f$ parameters in the above expression.
+      80             : 
+      81             : \par Examples
+      82             : 
+      83             : The following commands tell plumed to calculate the number of atoms in an ion channel in a protein.
+      84             : The extent of the channel is calculated from the positions of atoms 1, 4, 5 and 11. The final value will be labeled cav.
+      85             : 
+      86             : \plumedfile
+      87             : d1: DENSITY SPECIES=20-500
+      88             : CAVITY DATA=d1 ATOMS=1,4,5,11 SIGMA=0.1 LABEL=cav
+      89             : \endplumedfile
+      90             : 
+      91             : The following command tells plumed to calculate the coordination numbers (with other water molecules) for the water
+      92             : molecules in the protein channel described above.  The average coordination number and the number of coordination
+      93             : numbers more than 4 is then calculated.  The values of these two quantities are given the labels cav.mean and cav.morethan
+      94             : 
+      95             : \plumedfile
+      96             : d1: COORDINATIONNUMBER SPECIES=20-500 R_0=0.1
+      97             : CAVITY DATA=d1 ATOMS=1,4,5,11 SIGMA=0.1 MEAN MORE_THAN={RATIONAL R_0=4} LABEL=cav
+      98             : \endplumedfile
+      99             : 
+     100             : */
+     101             : //+ENDPLUMEDOC
+     102             : 
+     103             : namespace PLMD {
+     104             : namespace multicolvar {
+     105             : 
+     106             : class VolumeCavity : public ActionVolume {
+     107             : private:
+     108             :   bool boxout;
+     109             :   OFile boxfile;
+     110             :   double lenunit;
+     111             :   double jacob_det;
+     112             :   double len_bi, len_cross, len_perp, sigma;
+     113             :   Vector origin, bi, cross, perp;
+     114             :   std::vector<Vector> dlbi, dlcross, dlperp;
+     115             :   std::vector<Tensor> dbi, dcross, dperp;
+     116             : public:
+     117             :   static void registerKeywords( Keywords& keys );
+     118             :   explicit VolumeCavity(const ActionOptions& ao);
+     119             :   ~VolumeCavity();
+     120             :   void setupRegions() override;
+     121             :   void update() override;
+     122             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+     123             : };
+     124             : 
+     125             : PLUMED_REGISTER_ACTION(VolumeCavity,"CAVITY")
+     126             : 
+     127           4 : void VolumeCavity::registerKeywords( Keywords& keys ) {
+     128           4 :   ActionVolume::registerKeywords( keys );
+     129           8 :   keys.add("atoms","ATOMS","the positions of four atoms that define spatial extent of the cavity");
+     130           8 :   keys.addFlag("PRINT_BOX",false,"write out the positions of the corners of the box to an xyz file");
+     131           8 :   keys.add("optional","FILE","the file on which to write out the box coordinates");
+     132           8 :   keys.add("optional","UNITS","( default=nm ) the units in which to write out the corners of the box");
+     133           4 : }
+     134             : 
+     135           2 : VolumeCavity::VolumeCavity(const ActionOptions& ao):
+     136             :   Action(ao),
+     137             :   ActionVolume(ao),
+     138           2 :   boxout(false),
+     139           2 :   lenunit(1.0),
+     140           2 :   dlbi(4),
+     141           2 :   dlcross(4),
+     142           2 :   dlperp(4),
+     143           2 :   dbi(3),
+     144           2 :   dcross(3),
+     145           4 :   dperp(3)
+     146             : {
+     147             :   std::vector<AtomNumber> atoms;
+     148           4 :   parseAtomList("ATOMS",atoms);
+     149           2 :   if( atoms.size()!=4 ) error("number of atoms should be equal to four");
+     150             : 
+     151           2 :   log.printf("  boundaries for region are calculated based on positions of atoms : ");
+     152          10 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial() );
+     153           2 :   log.printf("\n");
+     154             : 
+     155           2 :   boxout=false; parseFlag("PRINT_BOX",boxout);
+     156           2 :   if(boxout) {
+     157           0 :     std::string boxfname; parse("FILE",boxfname);
+     158           0 :     if(boxfname.length()==0) error("no name for box file specified");
+     159           0 :     std::string unitname; parse("UNITS",unitname);
+     160           0 :     if ( unitname.length()>0 ) {
+     161           0 :       Units u; u.setLength(unitname);
+     162           0 :       lenunit=getUnits().getLength()/u.getLength();
+     163           0 :     } else {
+     164             :       unitname="nm";
+     165             :     }
+     166           0 :     boxfile.link(*this);
+     167           0 :     boxfile.open( boxfname );
+     168           0 :     log.printf("  printing box coordinates on file named %s in %s \n",boxfname.c_str(), unitname.c_str() );
+     169             :   }
+     170             : 
+     171           2 :   checkRead();
+     172           2 :   requestAtoms(atoms);
+     173             :   // We have to readd the dependency because requestAtoms removes it
+     174           2 :   addDependency( getPntrToMultiColvar() );
+     175           2 : }
+     176             : 
+     177           4 : VolumeCavity::~VolumeCavity() {
+     178           4 : }
+     179             : 
+     180        1620 : void VolumeCavity::setupRegions() {
+     181             :   // Make some space for things
+     182        1620 :   Vector d1, d2, d3;
+     183             : 
+     184             :   // Retrieve the sigma value
+     185        1620 :   sigma=getSigma();
+     186             :   // Set the position of the origin
+     187        1620 :   origin=getPosition(0);
+     188             : 
+     189             :   // Get two vectors
+     190        1620 :   d1 = pbcDistance(origin,getPosition(1));
+     191        1620 :   double d1l=d1.modulo();
+     192        1620 :   d2 = pbcDistance(origin,getPosition(2));
+     193             : 
+     194             :   // Find the vector connecting the origin to the top corner of
+     195             :   // the subregion
+     196        1620 :   d3 = pbcDistance(origin,getPosition(3));
+     197             : 
+     198             :   // Create a set of unit vectors
+     199        1620 :   bi = d1 / d1l; len_bi=dotProduct( d3, bi );
+     200        1620 :   cross = crossProduct( d1, d2 ); double crossmod=cross.modulo();
+     201        1620 :   cross = cross / crossmod; len_cross=dotProduct( d3, cross );
+     202        1620 :   perp = crossProduct( cross, bi ); len_perp=dotProduct( d3, perp );
+     203             : 
+     204             :   // Calculate derivatives of box shape with respect to atoms
+     205        1620 :   double d1l3=d1l*d1l*d1l;
+     206        1620 :   dbi[0](0,0) = ( -(d1[1]*d1[1]+d1[2]*d1[2])/d1l3 );   // dx/dx
+     207        1620 :   dbi[0](0,1) = (  d1[0]*d1[1]/d1l3 );                 // dx/dy
+     208        1620 :   dbi[0](0,2) = (  d1[0]*d1[2]/d1l3 );                 // dx/dz
+     209        1620 :   dbi[0](1,0) = (  d1[1]*d1[0]/d1l3 );                 // dy/dx
+     210        1620 :   dbi[0](1,1) = ( -(d1[0]*d1[0]+d1[2]*d1[2])/d1l3 );   // dy/dy
+     211        1620 :   dbi[0](1,2) = (  d1[1]*d1[2]/d1l3 );
+     212        1620 :   dbi[0](2,0) = (  d1[2]*d1[0]/d1l3 );
+     213        1620 :   dbi[0](2,1) = (  d1[2]*d1[1]/d1l3 );
+     214        1620 :   dbi[0](2,2) = ( -(d1[1]*d1[1]+d1[0]*d1[0])/d1l3 );
+     215             : 
+     216        1620 :   dbi[1](0,0) = ( (d1[1]*d1[1]+d1[2]*d1[2])/d1l3 );
+     217        1620 :   dbi[1](0,1) = ( -d1[0]*d1[1]/d1l3 );
+     218        1620 :   dbi[1](0,2) = ( -d1[0]*d1[2]/d1l3 );
+     219        1620 :   dbi[1](1,0) = ( -d1[1]*d1[0]/d1l3 );
+     220        1620 :   dbi[1](1,1) = ( (d1[0]*d1[0]+d1[2]*d1[2])/d1l3 );
+     221        1620 :   dbi[1](1,2) = ( -d1[1]*d1[2]/d1l3 );
+     222        1620 :   dbi[1](2,0) = ( -d1[2]*d1[0]/d1l3 );
+     223        1620 :   dbi[1](2,1) = ( -d1[2]*d1[1]/d1l3 );
+     224        1620 :   dbi[1](2,2) = ( (d1[1]*d1[1]+d1[0]*d1[0])/d1l3 );
+     225        1620 :   dbi[2].zero();
+     226             : 
+     227        1620 :   Tensor tcderiv; double cmod3=crossmod*crossmod*crossmod; Vector ucross=crossmod*cross;
+     228        1620 :   tcderiv.setCol( 0, crossProduct( d1, Vector(-1.0,0.0,0.0) ) + crossProduct( Vector(-1.0,0.0,0.0), d2 ) );
+     229        1620 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,-1.0,0.0) ) + crossProduct( Vector(0.0,-1.0,0.0), d2 ) );
+     230        1620 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,-1.0) ) + crossProduct( Vector(0.0,0.0,-1.0), d2 ) );
+     231        1620 :   dcross[0](0,0)=( tcderiv(0,0)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dx/dx
+     232        1620 :   dcross[0](0,1)=( tcderiv(0,1)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dx/dy
+     233        1620 :   dcross[0](0,2)=( tcderiv(0,2)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dx/dz
+     234        1620 :   dcross[0](1,0)=( tcderiv(1,0)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dy/dx
+     235        1620 :   dcross[0](1,1)=( tcderiv(1,1)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dy/dy
+     236        1620 :   dcross[0](1,2)=( tcderiv(1,2)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dy/dz
+     237        1620 :   dcross[0](2,0)=( tcderiv(2,0)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dz/dx
+     238        1620 :   dcross[0](2,1)=( tcderiv(2,1)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dz/dy
+     239        1620 :   dcross[0](2,2)=( tcderiv(2,2)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dz/dz
+     240             : 
+     241        1620 :   tcderiv.setCol( 0, crossProduct( Vector(1.0,0.0,0.0), d2 ) );
+     242        1620 :   tcderiv.setCol( 1, crossProduct( Vector(0.0,1.0,0.0), d2 ) );
+     243        1620 :   tcderiv.setCol( 2, crossProduct( Vector(0.0,0.0,1.0), d2 ) );
+     244        1620 :   dcross[1](0,0)=( tcderiv(0,0)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dx/dx
+     245        1620 :   dcross[1](0,1)=( tcderiv(0,1)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dx/dy
+     246        1620 :   dcross[1](0,2)=( tcderiv(0,2)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dx/dz
+     247        1620 :   dcross[1](1,0)=( tcderiv(1,0)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dy/dx
+     248        1620 :   dcross[1](1,1)=( tcderiv(1,1)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dy/dy
+     249        1620 :   dcross[1](1,2)=( tcderiv(1,2)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dy/dz
+     250        1620 :   dcross[1](2,0)=( tcderiv(2,0)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dz/dx
+     251        1620 :   dcross[1](2,1)=( tcderiv(2,1)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dz/dy
+     252        1620 :   dcross[1](2,2)=( tcderiv(2,2)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dz/dz
+     253             : 
+     254        1620 :   tcderiv.setCol( 0, crossProduct( d1, Vector(1.0,0.0,0.0) ) );
+     255        1620 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,1.0,0.0) ) );
+     256        1620 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,1.0) ) );
+     257        1620 :   dcross[2](0,0)=( tcderiv(0,0)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dx/dx
+     258        1620 :   dcross[2](0,1)=( tcderiv(0,1)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dx/dy
+     259        1620 :   dcross[2](0,2)=( tcderiv(0,2)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dx/dz
+     260        1620 :   dcross[2](1,0)=( tcderiv(1,0)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dy/dx
+     261        1620 :   dcross[2](1,1)=( tcderiv(1,1)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dy/dy
+     262        1620 :   dcross[2](1,2)=( tcderiv(1,2)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dy/dz
+     263        1620 :   dcross[2](2,0)=( tcderiv(2,0)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dz/dx
+     264        1620 :   dcross[2](2,1)=( tcderiv(2,1)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dz/dy
+     265        1620 :   dcross[2](2,2)=( tcderiv(2,2)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dz/dz
+     266             : 
+     267        1620 :   dperp[0].setCol( 0, ( crossProduct( dcross[0].getCol(0), bi ) + crossProduct( cross, dbi[0].getCol(0) ) ) );
+     268        1620 :   dperp[0].setCol( 1, ( crossProduct( dcross[0].getCol(1), bi ) + crossProduct( cross, dbi[0].getCol(1) ) ) );
+     269        1620 :   dperp[0].setCol( 2, ( crossProduct( dcross[0].getCol(2), bi ) + crossProduct( cross, dbi[0].getCol(2) ) ) );
+     270             : 
+     271        1620 :   dperp[1].setCol( 0, ( crossProduct( dcross[1].getCol(0), bi ) + crossProduct( cross, dbi[1].getCol(0) ) ) );
+     272        1620 :   dperp[1].setCol( 1, ( crossProduct( dcross[1].getCol(1), bi ) + crossProduct( cross, dbi[1].getCol(1) ) ) );
+     273        1620 :   dperp[1].setCol( 2, ( crossProduct( dcross[1].getCol(2), bi ) + crossProduct( cross, dbi[1].getCol(2) ) ) );
+     274             : 
+     275        1620 :   dperp[2].setCol( 0, ( crossProduct( dcross[2].getCol(0), bi ) ) );
+     276        1620 :   dperp[2].setCol( 1, ( crossProduct( dcross[2].getCol(1), bi ) ) );
+     277        1620 :   dperp[2].setCol( 2, ( crossProduct( dcross[2].getCol(2), bi ) ) );
+     278             : 
+     279             :   // Ensure that all lengths are positive
+     280        1620 :   if( len_bi<0 ) {
+     281           0 :     bi=-bi; len_bi=-len_bi;
+     282           0 :     for(unsigned i=0; i<3; ++i) dbi[i]*=-1.0;
+     283             :   }
+     284        1620 :   if( len_cross<0 ) {
+     285           0 :     cross=-cross; len_cross=-len_cross;
+     286           0 :     for(unsigned i=0; i<3; ++i) dcross[i]*=-1.0;
+     287             :   }
+     288        1620 :   if( len_perp<0 ) {
+     289           0 :     perp=-perp; len_perp=-len_perp;
+     290           0 :     for(unsigned i=0; i<3; ++i) dperp[i]*=-1.0;
+     291             :   }
+     292        1620 :   if( len_bi<=0 || len_cross<=0 || len_perp<=0 ) plumed_merror("Invalid box coordinates");
+     293             : 
+     294             :   // Now derivatives of lengths
+     295        1620 :   Tensor dd3( Tensor::identity() );
+     296        1620 :   dlbi[0] = matmul(d3,dbi[0]) - matmul(bi,dd3);
+     297        1620 :   dlbi[1] = matmul(d3,dbi[1]);
+     298        1620 :   dlbi[2] = matmul(d3,dbi[2]);
+     299        1620 :   dlbi[3] = matmul(bi,dd3);
+     300             : 
+     301        1620 :   dlcross[0] = matmul(d3,dcross[0]) - matmul(cross,dd3);
+     302        1620 :   dlcross[1] = matmul(d3,dcross[1]);
+     303        1620 :   dlcross[2] = matmul(d3,dcross[2]);
+     304        1620 :   dlcross[3] = matmul(cross,dd3);
+     305             : 
+     306        1620 :   dlperp[0] = matmul(d3,dperp[0]) - matmul(perp,dd3);
+     307        1620 :   dlperp[1] = matmul(d3,dperp[1]);
+     308        1620 :   dlperp[2] = matmul(d3,dperp[2]);
+     309        1620 :   dlperp[3] = matmul(perp,dd3);
+     310             : 
+     311             :   // Need to calculate the jacobian
+     312        1620 :   Tensor jacob;
+     313        1620 :   jacob(0,0)=bi[0]; jacob(1,0)=bi[1]; jacob(2,0)=bi[2];
+     314        1620 :   jacob(0,1)=cross[0]; jacob(1,1)=cross[1]; jacob(2,1)=cross[2];
+     315        1620 :   jacob(0,2)=perp[0]; jacob(1,2)=perp[1]; jacob(2,2)=perp[2];
+     316        1620 :   jacob_det = std::fabs( jacob.determinant() );
+     317        1620 : }
+     318             : 
+     319         120 : void VolumeCavity::update() {
+     320         120 :   if(boxout) {
+     321           0 :     boxfile.printf("%d\n",8);
+     322           0 :     const Tensor & t(getPbc().getBox());
+     323           0 :     if(getPbc().isOrthorombic()) {
+     324           0 :       boxfile.printf(" %f %f %f\n",lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
+     325             :     } else {
+     326           0 :       boxfile.printf(" %f %f %f %f %f %f %f %f %f\n",
+     327           0 :                      lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     328           0 :                      lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     329           0 :                      lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     330             :                     );
+     331             :     }
+     332           0 :     boxfile.printf("AR %f %f %f \n",lenunit*origin[0],lenunit*origin[1],lenunit*origin[2]);
+     333           0 :     Vector ut, vt, wt;
+     334           0 :     ut = origin + len_bi*bi;
+     335           0 :     vt = origin + len_cross*cross;
+     336           0 :     wt = origin + len_perp*perp;
+     337           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]), lenunit*(ut[1]), lenunit*(ut[2]) );
+     338           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]), lenunit*(vt[1]), lenunit*(vt[2]) );
+     339           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(wt[0]), lenunit*(wt[1]), lenunit*(wt[2]) );
+     340           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_bi*bi[0]),
+     341           0 :                    lenunit*(vt[1]+len_bi*bi[1]),
+     342           0 :                    lenunit*(vt[2]+len_bi*bi[2]) );
+     343           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]+len_perp*perp[0]),
+     344           0 :                    lenunit*(ut[1]+len_perp*perp[1]),
+     345           0 :                    lenunit*(ut[2]+len_perp*perp[2]) );
+     346           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]),
+     347           0 :                    lenunit*(vt[1]+len_perp*perp[1]),
+     348           0 :                    lenunit*(vt[2]+len_perp*perp[2]) );
+     349           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]+len_bi*bi[0]),
+     350           0 :                    lenunit*(vt[1]+len_perp*perp[1]+len_bi*bi[1]),
+     351           0 :                    lenunit*(vt[2]+len_perp*perp[2]+len_bi*bi[2]) );
+     352             :   }
+     353         120 : }
+     354             : 
+     355        1620 : double VolumeCavity::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& rderiv ) const {
+     356             :   // Setup the histogram bead
+     357        3240 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( getKernelType() );
+     358             : 
+     359             :   // Calculate distance of atom from origin of new coordinate frame
+     360        1620 :   Vector datom=pbcDistance( origin, cpos );
+     361             :   double ucontr, uder, vcontr, vder, wcontr, wder;
+     362             : 
+     363             :   // Calculate contribution from integral along bi
+     364        1620 :   bead.set( 0, len_bi, sigma );
+     365        1620 :   double upos=dotProduct( datom, bi );
+     366        1620 :   ucontr=bead.calculate( upos, uder );
+     367        1620 :   double udlen=bead.uboundDerivative( upos );
+     368        1620 :   double uder2 = bead.lboundDerivative( upos ) - udlen;
+     369             : 
+     370             :   // Calculate contribution from integral along cross
+     371        1620 :   bead.set( 0, len_cross, sigma );
+     372        1620 :   double vpos=dotProduct( datom, cross );
+     373        1620 :   vcontr=bead.calculate( vpos, vder );
+     374        1620 :   double vdlen=bead.uboundDerivative( vpos );
+     375        1620 :   double vder2 = bead.lboundDerivative( vpos ) - vdlen;
+     376             : 
+     377             :   // Calculate contribution from integral along perp
+     378        1620 :   bead.set( 0, len_perp, sigma );
+     379        1620 :   double wpos=dotProduct( datom, perp );
+     380        1620 :   wcontr=bead.calculate( wpos, wder );
+     381        1620 :   double wdlen=bead.uboundDerivative( wpos );
+     382        1620 :   double wder2 = bead.lboundDerivative( wpos ) - wdlen;
+     383             : 
+     384        1620 :   Vector dfd; dfd[0]=uder*vcontr*wcontr; dfd[1]=ucontr*vder*wcontr; dfd[2]=ucontr*vcontr*wder;
+     385        1620 :   derivatives[0] = (dfd[0]*bi[0]+dfd[1]*cross[0]+dfd[2]*perp[0]);
+     386        1620 :   derivatives[1] = (dfd[0]*bi[1]+dfd[1]*cross[1]+dfd[2]*perp[1]);
+     387        1620 :   derivatives[2] = (dfd[0]*bi[2]+dfd[1]*cross[2]+dfd[2]*perp[2]);
+     388        1620 :   double tot = ucontr*vcontr*wcontr*jacob_det;
+     389             : 
+     390             :   // Add reference atom derivatives
+     391        1620 :   dfd[0]=uder2*vcontr*wcontr; dfd[1]=ucontr*vder2*wcontr; dfd[2]=ucontr*vcontr*wder2;
+     392        1620 :   Vector dfld; dfld[0]=udlen*vcontr*wcontr; dfld[1]=ucontr*vdlen*wcontr; dfld[2]=ucontr*vcontr*wdlen;
+     393        1620 :   rderiv[0] = dfd[0]*matmul(datom,dbi[0]) + dfd[1]*matmul(datom,dcross[0]) + dfd[2]*matmul(datom,dperp[0]) +
+     394        3240 :               dfld[0]*dlbi[0] + dfld[1]*dlcross[0] + dfld[2]*dlperp[0] - derivatives;
+     395        1620 :   rderiv[1] = dfd[0]*matmul(datom,dbi[1]) + dfd[1]*matmul(datom,dcross[1]) + dfd[2]*matmul(datom,dperp[1]) +
+     396        3240 :               dfld[0]*dlbi[1] + dfld[1]*dlcross[1] + dfld[2]*dlperp[1];
+     397        1620 :   rderiv[2] = dfd[0]*matmul(datom,dbi[2]) + dfd[1]*matmul(datom,dcross[2]) + dfd[2]*matmul(datom,dperp[2]) +
+     398        3240 :               dfld[0]*dlbi[2] + dfld[1]*dlcross[2] + dfld[2]*dlperp[2];
+     399        1620 :   rderiv[3] = dfld[0]*dlbi[3] + dfld[1]*dlcross[3] + dfld[2]*dlperp[3];
+     400             : 
+     401        1620 :   vir.zero(); vir-=Tensor( cpos,derivatives );
+     402        8100 :   for(unsigned i=0; i<4; ++i) {
+     403        6480 :     vir -= Tensor( getPosition(i), rderiv[i] );
+     404             :   }
+     405             : 
+     406        1620 :   return tot;
+     407             : }
+     408             : 
+     409             : }
+     410             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.cpp.func-sort-c.html b/coverage/multicolvar/VolumeGradientBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..bee7faef1941 --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeGradientBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeGradientBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:455778.9 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18VolumeGradientBase15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar18VolumeGradientBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar18VolumeGradientBase12requestAtomsERKSt6vectorINS_10AtomNumberESaIS3_EE30
_ZN4PLMD11multicolvar18VolumeGradientBaseC2ERKNS_13ActionOptionsE30
_ZN4PLMD11multicolvar18VolumeGradientBase16registerKeywordsERNS_8KeywordsE44
_ZN4PLMD11multicolvar18VolumeGradientBase28doJobsRequiredBeforeTaskListEv2239
_ZNK4PLMD11multicolvar18VolumeGradientBase12completeTaskERKjRNS_10MultiValueES5_80958
_ZNK4PLMD11multicolvar18VolumeGradientBase17setNumberInVolumeERKjS3_RKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERKSt6vectorIS7_SaIS7_EERNS_10MultiValueE115758
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.cpp.func.html b/coverage/multicolvar/VolumeGradientBase.cpp.func.html new file mode 100644 index 000000000000..23240d9b2a20 --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeGradientBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeGradientBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:455778.9 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar18VolumeGradientBase12requestAtomsERKSt6vectorINS_10AtomNumberESaIS3_EE30
_ZN4PLMD11multicolvar18VolumeGradientBase15addBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD11multicolvar18VolumeGradientBase16registerKeywordsERNS_8KeywordsE44
_ZN4PLMD11multicolvar18VolumeGradientBase28doJobsRequiredBeforeTaskListEv2239
_ZN4PLMD11multicolvar18VolumeGradientBaseC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar18VolumeGradientBaseC2ERKNS_13ActionOptionsE30
_ZNK4PLMD11multicolvar18VolumeGradientBase12completeTaskERKjRNS_10MultiValueES5_80958
_ZNK4PLMD11multicolvar18VolumeGradientBase17setNumberInVolumeERKjS3_RKdRKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEERKSt6vectorIS7_SaIS7_EERNS_10MultiValueE115758
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.cpp.gcov.html b/coverage/multicolvar/VolumeGradientBase.cpp.gcov.html new file mode 100644 index 000000000000..51934d6dbfae --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.cpp.gcov.html @@ -0,0 +1,230 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeGradientBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeGradientBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:455778.9 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "VolumeGradientBase.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "CatomPack.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace multicolvar {
+      29             : 
+      30          44 : void VolumeGradientBase::registerKeywords( Keywords& keys ) {
+      31          44 :   BridgedMultiColvarFunction::registerKeywords( keys );
+      32          44 : }
+      33             : 
+      34          30 : VolumeGradientBase::VolumeGradientBase(const ActionOptions&ao):
+      35             :   Action(ao),
+      36          30 :   BridgedMultiColvarFunction(ao)
+      37             : {
+      38          30 : }
+      39             : 
+      40          30 : void VolumeGradientBase::requestAtoms( const std::vector<AtomNumber>& atoms ) {
+      41          30 :   ActionAtomistic::requestAtoms(atoms); bridgeVariable=3*atoms.size();
+      42             :   std::map<std::string,bool> checklabs;
+      43         210 :   for(const auto & p : getDependencies() ) checklabs.insert(std::pair<std::string,bool>(p->getLabel(),false));
+      44         342 :   for(const auto & p : plumed.getActionSet() ) {
+      45         342 :     if( p->getLabel()==getPntrToMultiColvar()->getLabel() ) break;
+      46         168 :     if( checklabs.count(p->getLabel()) ) checklabs[p->getLabel()]=true;
+      47             :   }
+      48         198 :   for(const auto & p : checklabs ) {
+      49         168 :     if( !p.second ) error("the input for the virtual atoms used in the input for this action must appear in the input file before the input multicolvar");
+      50             :   }
+      51          30 :   addDependency( getPntrToMultiColvar() );
+      52          30 :   tmpforces.resize( 3*atoms.size()+9 );
+      53          30 : }
+      54             : 
+      55        2239 : void VolumeGradientBase::doJobsRequiredBeforeTaskList() {
+      56        2239 :   ActionWithValue::clearDerivatives();
+      57        2239 :   retrieveAtoms(); setupRegions();
+      58        2239 :   ActionWithVessel::doJobsRequiredBeforeTaskList();
+      59        2239 : }
+      60             : 
+      61       80958 : void VolumeGradientBase::completeTask( const unsigned& curr, MultiValue& invals, MultiValue& outvals ) const {
+      62       80958 :   if( getPntrToMultiColvar()->isDensity() ) {
+      63             :     outvals.setValue(0, 1.0); outvals.setValue(1, 1.0);
+      64             :   } else {
+      65             :     // Copy derivatives of the colvar and the value of the colvar
+      66       37538 :     invals.copyValues( outvals );
+      67       37538 :     if( derivativesAreRequired() ) invals.copyDerivatives( outvals );
+      68             :   }
+      69       80958 :   calculateAllVolumes( curr, outvals );
+      70       80958 : }
+      71             : 
+      72      115758 : void VolumeGradientBase::setNumberInVolume( const unsigned& ivol, const unsigned& curr, const double& weight,
+      73             :     const Vector& wdf, const Tensor& virial, const std::vector<Vector>& refders,
+      74             :     MultiValue& outvals ) const {
+      75             :   MultiColvarBase* mcolv=getPntrToMultiColvar();
+      76      115758 :   if( !mcolv->weightHasDerivatives ) {
+      77             :     outvals.setValue(ivol, weight );
+      78      115758 :     if( derivativesAreRequired() ) {
+      79      112725 :       CatomPack catom; mcolv->getCentralAtomPack( 0, curr, catom );
+      80      253450 :       for(unsigned i=0; i<catom.getNumberOfAtomsWithDerivatives(); ++i) {
+      81      140725 :         unsigned jatom=3*catom.getIndex(i);
+      82      140725 :         outvals.addDerivative( ivol, jatom+0, catom.getDerivative(i,0,wdf) );
+      83      140725 :         outvals.addDerivative( ivol, jatom+1, catom.getDerivative(i,1,wdf) );
+      84      140725 :         outvals.addDerivative( ivol, jatom+2, catom.getDerivative(i,2,wdf) );
+      85             :       }
+      86      112725 :       unsigned nmder=getPntrToMultiColvar()->getNumberOfDerivatives();
+      87     1465425 :       for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) outvals.addDerivative( ivol, nmder-9+3*i+j, virial(i,j) );
+      88      230310 :       for(unsigned i=0; i<refders.size(); ++i) {
+      89      117585 :         unsigned iatom=nmder+3*i;
+      90             : 
+      91      117585 :         outvals.addDerivative( ivol, iatom+0, refders[i][0] );
+      92      117585 :         outvals.addDerivative( ivol, iatom+1, refders[i][1] );
+      93      117585 :         outvals.addDerivative( ivol, iatom+2, refders[i][2] );
+      94             :       }
+      95             :     }
+      96           0 :   } else if(ivol==0) {
+      97           0 :     double ww=outvals.get(0); outvals.setValue(ivol,ww*weight);
+      98           0 :     if( derivativesAreRequired() ) {
+      99           0 :       plumed_merror("This needs testing");
+     100             : #if 0
+     101             :       CatomPack catom; mcolv->getCentralAtomPack( 0, curr, catom );
+     102             :       for(unsigned i=0; i<catom.getNumberOfAtomsWithDerivatives(); ++i) {
+     103             :         unsigned jatom=3*catom.getIndex(i);
+     104             :         outvals.addDerivative( ivol, jatom+0, weight*outvals.getDerivative(ivol,jatom+0) + ww*catom.getDerivative(i,0,wdf) );
+     105             :         outvals.addDerivative( ivol, jatom+1, weight*outvals.getDerivative(ivol,jatom+1) + ww*catom.getDerivative(i,1,wdf) );
+     106             :         outvals.addDerivative( ivol, jatom+2, weight*outvals.getDerivative(ivol,jatom+2) + ww*catom.getDerivative(i,2,wdf) );
+     107             :       }
+     108             :       unsigned nmder=getPntrToMultiColvar()->getNumberOfDerivatives();
+     109             :       for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) outvals.addDerivative( ivol, nmder-9+3*i+j, ww*virial(i,j) );
+     110             :       for(unsigned i=0; i<refders.size(); ++i) {
+     111             :         unsigned iatom=nmder+3*i;
+     112             :         outvals.addDerivative( ivol, iatom+0, ww*refders[i][0] );
+     113             :         outvals.addDerivative( ivol, iatom+1, ww*refders[i][1] );
+     114             :         outvals.addDerivative( ivol, iatom+2, ww*refders[i][2] );
+     115             :       }
+     116             : #endif
+     117             :     }
+     118             :   } else {
+     119           0 :     double ww=outvals.get(0); outvals.setValue(ivol,ww*weight);
+     120           0 :     if( derivativesAreRequired() ) {
+     121           0 :       plumed_merror("This needs testing");
+     122             : #if 0
+     123             :       CatomPack catom; mcolv->getCentralAtomPack( 0, curr, catom );
+     124             :       for(unsigned i=0; i<catom.getNumberOfAtomsWithDerivatives(); ++i) {
+     125             :         unsigned jatom=3*catom.getIndex(i);
+     126             :         outvals.addDerivative( ivol, jatom+0, ww*catom.getDerivative(i,0,wdf) );
+     127             :         outvals.addDerivative( ivol, jatom+1, ww*catom.getDerivative(i,1,wdf) );
+     128             :         outvals.addDerivative( ivol, jatom+2, ww*catom.getDerivative(i,2,wdf) );
+     129             :       }
+     130             :       unsigned nmder=getPntrToMultiColvar()->getNumberOfDerivatives();
+     131             :       for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) outvals.addDerivative( ivol, nmder-9+3*i+j, ww*virial(i,j) );
+     132             :       for(unsigned i=0; i<refders.size(); ++i) {
+     133             :         unsigned iatom=nmder+3*i;
+     134             :         outvals.addDerivative( ivol, iatom+0, ww*refders[i][0] );
+     135             :         outvals.addDerivative( ivol, iatom+1, ww*refders[i][1] );
+     136             :         outvals.addDerivative( ivol, iatom+2, ww*refders[i][2] );
+     137             :       }
+     138             : #endif
+     139             :     }
+     140             :   }
+     141      115758 : }
+     142             : 
+     143           0 : void VolumeGradientBase::addBridgeForces( const std::vector<double>& bb ) {
+     144             :   plumed_dbg_assert( bb.size()==tmpforces.size()-9 );
+     145             :   // Forces on local atoms
+     146           0 :   for(unsigned i=0; i<bb.size(); ++i) tmpforces[i]=bb[i];
+     147             :   // Virial contribution is zero
+     148           0 :   for(unsigned i=bb.size(); i<bb.size()+9; ++i) tmpforces[i]=0.0;
+     149           0 :   unsigned ind=0; setForcesOnAtoms( tmpforces, ind );
+     150           0 : }
+     151             : 
+     152             : }
+     153             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.h.func-sort-c.html b/coverage/multicolvar/VolumeGradientBase.h.func-sort-c.html new file mode 100644 index 000000000000..f4c9d72f8faa --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeGradientBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeGradientBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar18VolumeGradientBase11getPositionEi240427
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.h.func.html b/coverage/multicolvar/VolumeGradientBase.h.func.html new file mode 100644 index 000000000000..02c7045de871 --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeGradientBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeGradientBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD11multicolvar18VolumeGradientBase11getPositionEi240427
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeGradientBase.h.gcov.html b/coverage/multicolvar/VolumeGradientBase.h.gcov.html new file mode 100644 index 000000000000..77ac3ba6f127 --- /dev/null +++ b/coverage/multicolvar/VolumeGradientBase.h.gcov.html @@ -0,0 +1,171 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeGradientBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeGradientBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_multicolvar_VolumeGradientBase_h
+      23             : #define __PLUMED_multicolvar_VolumeGradientBase_h
+      24             : 
+      25             : #include "BridgedMultiColvarFunction.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace multicolvar {
+      29             : 
+      30             : class VolumeGradientBase : public BridgedMultiColvarFunction {
+      31             :   friend class MultiColvarBase;
+      32             : private:
+      33             : /// This is used to store forces temporarily in apply
+      34             :   std::vector<double> tmpforces;
+      35             : protected:
+      36             : /// Get the cell box
+      37             :   const Tensor & getBox() const;
+      38             : /// Get reference to Pbc
+      39             :   const Pbc & getPbc() const;
+      40             : /// Calculate distance between two points
+      41             :   Vector pbcDistance( const Vector& v1, const Vector& v2) const;
+      42             : /// Get position of atom
+      43             :   Vector getPosition( int iatom ) const ;
+      44             : /// Request the atoms
+      45             :   void requestAtoms( const std::vector<AtomNumber>& atoms );
+      46             : /// Set the number in the volume
+      47             :   void setNumberInVolume( const unsigned&, const unsigned&, const double&, const Vector&, const Tensor&, const std::vector<Vector>&, MultiValue& ) const ;
+      48             : public:
+      49             :   static void registerKeywords( Keywords& keys );
+      50             :   explicit VolumeGradientBase(const ActionOptions&);
+      51             : /// Do jobs required before tasks are undertaken
+      52             :   void doJobsRequiredBeforeTaskList() override;
+      53             : /// Actually do what we are asked
+      54             :   void completeTask( const unsigned& curr, MultiValue& invals, MultiValue& outvals ) const override;
+      55             : /// Calculate what is in the volumes
+      56             :   virtual void calculateAllVolumes( const unsigned& curr, MultiValue& outvals ) const=0;
+      57             : /// Setup the regions that this is based on
+      58             :   virtual void setupRegions()=0;
+      59             : /// Forces here are applied through the bridge
+      60             :   void addBridgeForces( const std::vector<double>& bb );
+      61             : };
+      62             : 
+      63             : inline
+      64             : const Tensor & VolumeGradientBase::getBox()const {
+      65             :   return getPntrToMultiColvar()->getBox();
+      66             : }
+      67             : 
+      68             : inline
+      69             : const Pbc & VolumeGradientBase::getPbc() const {
+      70             :   return getPntrToMultiColvar()->getPbc();
+      71             : }
+      72             : 
+      73             : inline
+      74             : Vector VolumeGradientBase::pbcDistance( const Vector& v1, const Vector& v2) const {
+      75             :   return getPntrToMultiColvar()->pbcDistance(v1,v2);
+      76             : }
+      77             : 
+      78             : inline
+      79      240427 : Vector VolumeGradientBase::getPosition( int iatom ) const {
+      80      240427 :   if( !checkNumericalDerivatives() ) return ActionAtomistic::getPosition(iatom);
+      81             : // This is for numerical derivatives of quantity wrt to the local atoms
+      82       12480 :   Vector tmp_p = ActionAtomistic::getPosition(iatom);
+      83       12480 :   if( bridgeVariable<3*getNumberOfAtoms() ) {
+      84        5760 :     if( static_cast<int>(bridgeVariable)>=3*iatom && static_cast<int>(bridgeVariable)<(iatom+1)*3 ) tmp_p[bridgeVariable%3]+=sqrt(epsilon);
+      85             :   }
+      86             : // This makes sure that numerical derivatives of virial are calculated correctly
+      87       12480 :   tmp_p = ActionAtomistic::getPbc().realToScaled( tmp_p );
+      88       12480 :   tmp_p = getPbc().scaledToReal( tmp_p );
+      89       12480 :   return tmp_p;
+      90             : }
+      91             : 
+      92             : }
+      93             : }
+      94             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInCylinder.cpp.func-sort-c.html b/coverage/multicolvar/VolumeInCylinder.cpp.func-sort-c.html new file mode 100644 index 000000000000..325bd96430cc --- /dev/null +++ b/coverage/multicolvar/VolumeInCylinder.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeInCylinder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeInCylinder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:464895.8 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar16VolumeInCylinderC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar16VolumeInCylinderC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar16VolumeInCylinder16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar16VolumeInCylinder12setupRegionsEv20
_ZNK4PLMD11multicolvar16VolumeInCylinder21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE4000
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInCylinder.cpp.func.html b/coverage/multicolvar/VolumeInCylinder.cpp.func.html new file mode 100644 index 000000000000..74de67365f9d --- /dev/null +++ b/coverage/multicolvar/VolumeInCylinder.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeInCylinder.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeInCylinder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:464895.8 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar16VolumeInCylinder12setupRegionsEv20
_ZN4PLMD11multicolvar16VolumeInCylinder16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD11multicolvar16VolumeInCylinderC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar16VolumeInCylinderC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar16VolumeInCylinder21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE4000
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInCylinder.cpp.gcov.html b/coverage/multicolvar/VolumeInCylinder.cpp.gcov.html new file mode 100644 index 000000000000..e2804a649ac2 --- /dev/null +++ b/coverage/multicolvar/VolumeInCylinder.cpp.gcov.html @@ -0,0 +1,237 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeInCylinder.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeInCylinder.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:464895.8 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/Pbc.h"
+      24             : #include "tools/SwitchingFunction.h"
+      25             : #include "ActionVolume.h"
+      26             : 
+      27             : //+PLUMEDOC VOLUMES INCYLINDER
+      28             : /*
+      29             : This quantity can be used to calculate functions of the distribution of collective variables for the atoms that lie in a particular, user-specified part of of the cell.
+      30             : 
+      31             : Each of the base quantities calculated by a multicolvar can can be assigned to a particular point in three
+      32             : dimensional space. For example, if we have the coordination numbers for all the atoms in the
+      33             : system each coordination number can be assumed to lie on the position of the central atom.
+      34             : Because each base quantity can be assigned to a particular point in space we can calculate functions of the
+      35             : distribution of base quantities in a particular part of the box by using:
+      36             : 
+      37             : \f[
+      38             : \overline{s}_{\tau} = \frac{ \sum_i f(s_i) \sigma(r_{xy}) }{ \sum_i \sigma(r_{xy}) }
+      39             : \f]
+      40             : 
+      41             : where the sum is over the collective variables, \f$s_i\f$, each of which can be thought to be at \f$ (x_i,y_i,z_i)\f$.
+      42             : The function \f$\sigma\f$ is a \ref switchingfunction that acts on the distance between the point at which the
+      43             : collective is located \f$(x_i,y_i,z_i)\f$ and the position of the atom that was specified using the ORIGIN keyword
+      44             : projected in the xy plane if DIRECTION=z is used.  In other words:
+      45             : \f[
+      46             : r_{xy} = sqrt{ ( x_i - x_0)^2 + ( y_i - y_0)^2 }
+      47             : \f]
+      48             : In short this function, \f$\sigma(r_{xy})\f$, measures whether or not the CV is within a cylinder that
+      49             : runs along the axis specified using the DIRECTION keyword and that is centered on the position of the atom specified using
+      50             : ORIGIN.
+      51             : 
+      52             : The function \f$(s_i)\f$ can be any of the usual LESS_THAN, MORE_THAN, WITHIN etc that are used in all other multicolvars.
+      53             : 
+      54             : When INCYLINDER is used with the \ref DENSITY action the number of atoms in the specified region is calculated
+      55             : 
+      56             : \par Examples
+      57             : 
+      58             : The input below can be use to calculate the average coordination numbers for those atoms that are within a cylindrical tube
+      59             : of radius 1.5 nm that is centered on the position of atom 101 and that has its long axis parallel to the z-axis.
+      60             : 
+      61             : \plumedfile
+      62             : c1: COORDINATIONNUMBER SPECIES=1-100 SWITCH={RATIONAL R_0=0.1}
+      63             : d2: INCYLINDER ATOM=101 DATA=c1 DIRECTION=Z RADIUS={TANH R_0=1.5} SIGMA=0.1 LOWER=-0.1 UPPER=0.1 MEAN
+      64             : PRINT ARG=d2.* FILE=colvar
+      65             : \endplumedfile
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : namespace PLMD {
+      71             : namespace multicolvar {
+      72             : 
+      73             : class VolumeInCylinder : public ActionVolume {
+      74             : private:
+      75             :   bool docylinder;
+      76             :   Vector origin;
+      77             :   HistogramBead bead;
+      78             :   std::vector<unsigned> dir;
+      79             :   SwitchingFunction switchingFunction;
+      80             : public:
+      81             :   static void registerKeywords( Keywords& keys );
+      82             :   explicit VolumeInCylinder (const ActionOptions& ao);
+      83             :   void setupRegions() override;
+      84             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+      85             : };
+      86             : 
+      87             : PLUMED_REGISTER_ACTION(VolumeInCylinder,"INCYLINDER")
+      88             : 
+      89           3 : void VolumeInCylinder::registerKeywords( Keywords& keys ) {
+      90           3 :   ActionVolume::registerKeywords( keys );
+      91           6 :   keys.add("atoms","ATOM","the atom whose vicinity we are interested in examining");
+      92           6 :   keys.add("compulsory","DIRECTION","the direction of the long axis of the cylinder. Must be x, y or z");
+      93           6 :   keys.add("compulsory","RADIUS","a switching function that gives the extent of the cylinder in the plane perpendicular to the direction");
+      94           6 :   keys.add("compulsory","LOWER","0.0","the lower boundary on the direction parallel to the long axis of the cylinder");
+      95           6 :   keys.add("compulsory","UPPER","0.0","the upper boundary on the direction parallel to the long axis of the cylinder");
+      96           6 :   keys.reset_style("SIGMA","optional");
+      97           3 : }
+      98             : 
+      99           1 : VolumeInCylinder::VolumeInCylinder(const ActionOptions& ao):
+     100             :   Action(ao),
+     101             :   ActionVolume(ao),
+     102           1 :   docylinder(false)
+     103             : {
+     104             :   std::vector<AtomNumber> atom;
+     105           2 :   parseAtomList("ATOM",atom);
+     106           1 :   if( atom.size()!=1 ) error("should only be one atom specified");
+     107           1 :   log.printf("  center of cylinder is at position of atom : %d\n",atom[0].serial() );
+     108             : 
+     109           2 :   std::string sdir; parse("DIRECTION",sdir);
+     110           1 :   if( sdir=="X") {dir.push_back(1); dir.push_back(2); dir.push_back(0); }
+     111           1 :   else if( sdir=="Y") {dir.push_back(0); dir.push_back(2); dir.push_back(1); }
+     112           1 :   else if( sdir=="Z") {dir.push_back(0); dir.push_back(1); dir.push_back(2); }
+     113           0 :   else { error(sdir + "is not a valid direction.  Should be X, Y or Z"); }
+     114           1 :   log.printf("  cylinder's long axis is along %s axis\n",sdir.c_str() );
+     115             : 
+     116           2 :   std::string sw, errors; parse("RADIUS",sw);
+     117           1 :   if(sw.length()==0) error("missing RADIUS keyword");
+     118           1 :   switchingFunction.set(sw,errors);
+     119           1 :   if( errors.length()!=0 ) error("problem reading RADIUS keyword : " + errors );
+     120           1 :   log.printf("  radius of cylinder is given by %s \n", ( switchingFunction.description() ).c_str() );
+     121             : 
+     122           2 :   double min, max; parse("LOWER",min); parse("UPPER",max);
+     123           1 :   if( min!=0.0 ||  max!=0.0 ) {
+     124           1 :     if( min>max ) error("minimum of cylinder should be less than maximum");
+     125           1 :     docylinder=true;
+     126           1 :     log.printf("  cylinder extends from %f to %f along the %s axis\n",min,max,sdir.c_str() );
+     127           2 :     bead.isNotPeriodic(); bead.setKernelType( getKernelType() ); bead.set( min, max, getSigma() );
+     128             :   }
+     129             : 
+     130           1 :   checkRead(); requestAtoms(atom);
+     131           1 : }
+     132             : 
+     133          20 : void VolumeInCylinder::setupRegions() { }
+     134             : 
+     135        4000 : double VolumeInCylinder::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     136             :   // Calculate position of atom wrt to origin
+     137        4000 :   Vector fpos=pbcDistance( getPosition(0), cpos );
+     138             : 
+     139             :   double vcylinder, dcylinder;
+     140        4000 :   if( docylinder ) {
+     141        4000 :     vcylinder=bead.calculate( fpos[dir[2]], dcylinder );
+     142             :   } else {
+     143           0 :     vcylinder=1.0; dcylinder=0.0;
+     144             :   }
+     145             : 
+     146        4000 :   const double dd = fpos[dir[0]]*fpos[dir[0]] + fpos[dir[1]]*fpos[dir[1]];
+     147        4000 :   double dfunc, vswitch = switchingFunction.calculateSqr( dd, dfunc );
+     148        4000 :   derivatives.zero(); double value=vswitch*vcylinder;
+     149        4000 :   derivatives[dir[0]]=vcylinder*dfunc*fpos[dir[0]];
+     150        4000 :   derivatives[dir[1]]=vcylinder*dfunc*fpos[dir[1]];
+     151        4000 :   derivatives[dir[2]]=vswitch*dcylinder;
+     152             :   // Add derivatives wrt to position of origin atom
+     153        4000 :   refders[0] = -derivatives;
+     154             :   // Add virial contribution
+     155        4000 :   vir -= Tensor(fpos,derivatives);
+     156        4000 :   return value;
+     157             : }
+     158             : 
+     159             : }
+     160             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInSphere.cpp.func-sort-c.html b/coverage/multicolvar/VolumeInSphere.cpp.func-sort-c.html new file mode 100644 index 000000000000..da89be6a6160 --- /dev/null +++ b/coverage/multicolvar/VolumeInSphere.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeInSphere.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeInSphere.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar14VolumeInSphereC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar14VolumeInSphereC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar14VolumeInSphere16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar14VolumeInSphere12setupRegionsEv82
_ZNK4PLMD11multicolvar14VolumeInSphere21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE155474
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInSphere.cpp.func.html b/coverage/multicolvar/VolumeInSphere.cpp.func.html new file mode 100644 index 000000000000..2061ef1870cd --- /dev/null +++ b/coverage/multicolvar/VolumeInSphere.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeInSphere.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeInSphere.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar14VolumeInSphere12setupRegionsEv82
_ZN4PLMD11multicolvar14VolumeInSphere16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD11multicolvar14VolumeInSphereC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar14VolumeInSphereC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar14VolumeInSphere21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE155474
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeInSphere.cpp.gcov.html b/coverage/multicolvar/VolumeInSphere.cpp.gcov.html new file mode 100644 index 000000000000..4b04a5f873b5 --- /dev/null +++ b/coverage/multicolvar/VolumeInSphere.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeInSphere.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeInSphere.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2525100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/Pbc.h"
+      24             : #include "tools/SwitchingFunction.h"
+      25             : #include "ActionVolume.h"
+      26             : 
+      27             : //+PLUMEDOC VOLUMES INSPHERE
+      28             : /*
+      29             : This quantity can be used to calculate functions of the distribution of collective variables for the atoms that lie in a particular, user-specified part of of the cell.
+      30             : 
+      31             : Each of the base quantities calculated by a multicolvar can can be assigned to a particular point in three
+      32             : dimensional space. For example, if we have the coordination numbers for all the atoms in the
+      33             : system each coordination number can be assumed to lie on the position of the central atom.
+      34             : Because each base quantity can be assigned to a particular point in space we can calculate functions of the
+      35             : distribution of base quantities in a particular part of the box by using:
+      36             : 
+      37             : \f[
+      38             : \overline{s}_{\tau} = \frac{ \sum_i f(s_i) \sigma(r) }{ \sum_i \sigma(r) }
+      39             : \f]
+      40             : 
+      41             : where the sum is over the collective variables, \f$s_i\f$, each of which can be thought to be at \f$ (x_i,y_i,z_i)\f$.
+      42             : The function \f$\sigma\f$ is a \ref switchingfunction that acts on the distance between the point at which the
+      43             : collective is located \f$(x_i,y_i,z_i)\f$ and the position of the atom that was specified using the ORIGIN keyword.
+      44             : In other words:
+      45             : \f[
+      46             : r = sqrt{ ( x_i - x_0)^2 + ( y_i - y_0)^2 + ( z_i - z_0)^2}
+      47             : \f]
+      48             : In short this function, \f$\sigma(r_{xy})\f$, measures whether or not the CV is within a sphere that is
+      49             : centered on the position of the atom specified using the keyword ORIGIN.
+      50             : 
+      51             : The function \f$(s_i)\f$ can be any of the usual LESS_THAN, MORE_THAN, WITHIN etc that are used in all other multicolvars.
+      52             : 
+      53             : When INCYLINDER is used with the \ref DENSITY action the number of atoms in the specified region is calculated
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : The input below can be use to calculate the average coordination numbers for those atoms that are within a sphere
+      58             : of radius 1.5 nm that is centered on the position of atom 101.
+      59             : 
+      60             : \plumedfile
+      61             : c1: COORDINATIONNUMBER SPECIES=1-100 SWITCH={RATIONAL R_0=0.1}
+      62             : d2: INSPHERE ATOM=101 DATA=c1 RADIUS={TANH R_0=1.5} MEAN
+      63             : PRINT ARG=d2.* FILE=colvar
+      64             : \endplumedfile
+      65             : 
+      66             : */
+      67             : //+ENDPLUMEDOC
+      68             : 
+      69             : namespace PLMD {
+      70             : namespace multicolvar {
+      71             : 
+      72             : class VolumeInSphere : public ActionVolume {
+      73             : private:
+      74             :   Vector origin;
+      75             :   SwitchingFunction switchingFunction;
+      76             : public:
+      77             :   static void registerKeywords( Keywords& keys );
+      78             :   explicit VolumeInSphere(const ActionOptions& ao);
+      79             :   void setupRegions() override;
+      80             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+      81             : };
+      82             : 
+      83             : PLUMED_REGISTER_ACTION(VolumeInSphere,"INSPHERE")
+      84             : 
+      85           5 : void VolumeInSphere::registerKeywords( Keywords& keys ) {
+      86           5 :   ActionVolume::registerKeywords( keys );
+      87          10 :   keys.add("atoms","ATOM","the atom whose vicinity we are interested in examining");
+      88          10 :   keys.add("compulsory","RADIUS","the switching function that tells us the extent of the spherical region of interest");
+      89           5 :   keys.remove("SIGMA");
+      90           5 : }
+      91             : 
+      92           3 : VolumeInSphere::VolumeInSphere(const ActionOptions& ao):
+      93             :   Action(ao),
+      94           3 :   ActionVolume(ao)
+      95             : {
+      96             :   std::vector<AtomNumber> atom;
+      97           6 :   parseAtomList("ATOM",atom);
+      98           3 :   if( atom.size()!=1 ) error("should only be one atom specified");
+      99           3 :   log.printf("  center of sphere is at position of atom : %d\n",atom[0].serial() );
+     100             : 
+     101           6 :   std::string sw, errors; parse("RADIUS",sw);
+     102           3 :   if(sw.length()==0) error("missing RADIUS keyword");
+     103           3 :   switchingFunction.set(sw,errors);
+     104           3 :   if( errors.length()!=0 ) error("problem reading RADIUS keyword : " + errors );
+     105           3 :   log.printf("  radius of sphere is given by %s \n", ( switchingFunction.description() ).c_str() );
+     106             : 
+     107           3 :   checkRead(); requestAtoms(atom);
+     108           3 : }
+     109             : 
+     110          82 : void VolumeInSphere::setupRegions() { }
+     111             : 
+     112      155474 : double VolumeInSphere::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const {
+     113             :   // Calculate position of atom wrt to origin
+     114      155474 :   Vector fpos=pbcDistance( getPosition(0), cpos );
+     115      155474 :   double dfunc, value = switchingFunction.calculateSqr( fpos.modulo2(), dfunc );
+     116      155474 :   derivatives.zero(); derivatives = dfunc*fpos; refders[0] = -derivatives;
+     117             :   // Add a virial contribution
+     118      155474 :   vir -= Tensor(fpos,derivatives);
+     119      155474 :   return value;
+     120             : }
+     121             : 
+     122             : }
+     123             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeTetrapore.cpp.func-sort-c.html b/coverage/multicolvar/VolumeTetrapore.cpp.func-sort-c.html new file mode 100644 index 000000000000..685c1d9f4f16 --- /dev/null +++ b/coverage/multicolvar/VolumeTetrapore.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeTetrapore.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeTetrapore.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:72313.0 %
Date:2024-02-22 21:58:45Functions:1911.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15VolumeTetrapore12setupRegionsEv0
_ZN4PLMD11multicolvar15VolumeTetrapore6updateEv0
_ZN4PLMD11multicolvar15VolumeTetraporeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15VolumeTetraporeC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15VolumeTetraporeD0Ev0
_ZN4PLMD11multicolvar15VolumeTetraporeD1Ev0
_ZN4PLMD11multicolvar15VolumeTetraporeD2Ev0
_ZNK4PLMD11multicolvar15VolumeTetrapore21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
_ZN4PLMD11multicolvar15VolumeTetrapore16registerKeywordsERNS_8KeywordsE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeTetrapore.cpp.func.html b/coverage/multicolvar/VolumeTetrapore.cpp.func.html new file mode 100644 index 000000000000..65fd3b8774b6 --- /dev/null +++ b/coverage/multicolvar/VolumeTetrapore.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeTetrapore.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeTetrapore.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:72313.0 %
Date:2024-02-22 21:58:45Functions:1911.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar15VolumeTetrapore12setupRegionsEv0
_ZN4PLMD11multicolvar15VolumeTetrapore16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD11multicolvar15VolumeTetrapore6updateEv0
_ZN4PLMD11multicolvar15VolumeTetraporeC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15VolumeTetraporeC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar15VolumeTetraporeD0Ev0
_ZN4PLMD11multicolvar15VolumeTetraporeD1Ev0
_ZN4PLMD11multicolvar15VolumeTetraporeD2Ev0
_ZNK4PLMD11multicolvar15VolumeTetrapore21calculateNumberInsideERKNS_13VectorGenericILj3EEERS3_RNS_13TensorGenericILj3ELj3EEERSt6vectorIS3_SaIS3_EE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/VolumeTetrapore.cpp.gcov.html b/coverage/multicolvar/VolumeTetrapore.cpp.gcov.html new file mode 100644 index 000000000000..a61f17193427 --- /dev/null +++ b/coverage/multicolvar/VolumeTetrapore.cpp.gcov.html @@ -0,0 +1,522 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/VolumeTetrapore.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - VolumeTetrapore.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:72313.0 %
Date:2024-02-22 21:58:45Functions:1911.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/Units.h"
+      24             : #include "tools/Pbc.h"
+      25             : #include "ActionVolume.h"
+      26             : 
+      27             : //+PLUMEDOC VOLUMES TETRAHEDRALPORE
+      28             : /*
+      29             : This quantity can be used to calculate functions of the distribution of collective variables for the atoms lie that lie in a box defined by the positions of four atoms at the corners of a tetrahedron.
+      30             : 
+      31             : Each of the base quantities calculated by a multicolvar can can be assigned to a particular point in three
+      32             : dimensional space. For example, if we have the coordination numbers for all the atoms in the
+      33             : system each coordination number can be assumed to lie on the position of the central atom.
+      34             : Because each base quantity can be assigned to a particular point in space we can calculate functions of the
+      35             : distribution of base quantities in a particular part of the box by using:
+      36             : 
+      37             : \f[
+      38             : \overline{s}_{\tau} = \frac{ \sum_i f(s_i) w(u_i,v_i,w_i) }{ \sum_i w(u_i,v_i,w_i) }
+      39             : \f]
+      40             : 
+      41             : where the sum is over the collective variables, \f$s_i\f$, each of which can be thought to be at \f$ (u_i,v_i,z_i)\f$.
+      42             : The function \f$(s_i)\f$ can be any of the usual LESS_THAN, MORE_THAN, WITHIN etc that are used in all other multicolvars.
+      43             : Notice that here (at variance with what is done in \ref AROUND) we have transformed from the usual \f$(x_i,y_i,z_i)\f$
+      44             : position to a position in \f$ (u_i,v_i,z_i)\f$.  This is done using a rotation matrix as follows:
+      45             : 
+      46             : \f[
+      47             : \left(
+      48             : \begin{matrix}
+      49             :  u_i \\
+      50             :  v_i \\
+      51             :  w_i
+      52             : \end{matrix}
+      53             : \right) = \mathbf{R}
+      54             : \left(
+      55             : \begin{matrix}
+      56             :  x_i - x_o \\
+      57             :  y_i - y_o \\
+      58             :  z_i - z_o
+      59             : \end{matrix}
+      60             : \right)
+      61             : \f]
+      62             : 
+      63             : where \f$\mathbf{R}\f$ is a rotation matrix that is calculated by constructing a set of three orthonormal vectors from the
+      64             : reference positions specified by the user.  Initially unit vectors are found by calculating the bisector, \f$\mathbf{b}\f$, and
+      65             : cross product, \f$\mathbf{c}\f$, of the vectors connecting atoms 1 and 2.  A third unit vector, \f$\mathbf{p}\f$ is then found by taking the cross
+      66             : product between the cross product calculated during the first step, \f$\mathbf{c}\f$ and the bisector, \f$\mathbf{b}\f$.  From this
+      67             : second cross product \f$\mathbf{p}\f$ and the bisector \f$\mathbf{b}\f$ two new vectors are calculated using:
+      68             : 
+      69             : \f[
+      70             : v_1 = \cos\left(\frac{\pi}{4}\right)\mathbf{b} + \sin\left(\frac{\pi}{4}\right)\mathbf{p} \qquad \textrm{and} \qquad
+      71             : v_2 = \cos\left(\frac{\pi}{4}\right)\mathbf{b} - \sin\left(\frac{\pi}{4}\right)\mathbf{p}
+      72             : \f]
+      73             : 
+      74             : In the previous function \f$ w(u_i,v_i,w_i) \f$ measures whether or not the system is in the subregion of interest. It
+      75             : is equal to:
+      76             : 
+      77             : \f[
+      78             : w(u_i,v_i,w_i) = \int_{0}^{u'} \int_{0}^{v'} \int_{0}^{w'} \textrm{d}u\textrm{d}v\textrm{d}w
+      79             :    K\left( \frac{u - u_i}{\sigma} \right)K\left( \frac{v - v_i}{\sigma} \right)K\left( \frac{w - w_i}{\sigma} \right)
+      80             : \f]
+      81             : 
+      82             : where \f$K\f$ is one of the kernel functions described on \ref histogrambead and \f$\sigma\f$ is a bandwidth parameter.
+      83             : The values of \f$u'\f$ and \f$v'\f$ are found by finding the projections of the vectors connecting atoms 1 and 2 and 1
+      84             : and 3 \f$v_1\f$ and \f$v_2\f$.  This gives four projections: the largest two projections are used in the remainder of
+      85             : the calculations.  \f$w'\f$ is calculated by taking the projection of the vector connecting atoms 1 and 4 on the vector
+      86             : \f$\mathbf{c}\f$.  Notice that the manner by which this box is constructed differs from the way this is done in \ref CAVITY.
+      87             : This is in fact the only point of difference between these two actions.
+      88             : 
+      89             : \par Examples
+      90             : 
+      91             : The following commands tell plumed to calculate the number of atom inside a tetrahedral cavity.  The extent of the tetrahedral
+      92             : cavity is calculated from the positions of atoms 1, 4, 5, and 11,  The final value will be labeled cav.
+      93             : 
+      94             : \plumedfile
+      95             : d1: DENSITY SPECIES=20-500
+      96             : TETRAHEDRALPORE DATA=d1 ATOMS=1,4,5,11 SIGMA=0.1 LABEL=cav
+      97             : \endplumedfile
+      98             : 
+      99             : The following command tells plumed to calculate the coordination numbers (with other water molecules) for the water
+     100             : molecules in the tetrahedral cavity described above.  The average coordination number and the number of coordination
+     101             : numbers more than 4 is then calculated.  The values of these two quantities are given the labels cav.mean and cav.morethan
+     102             : 
+     103             : \plumedfile
+     104             : d1: COORDINATIONNUMBER SPECIES=20-500 R_0=0.1
+     105             : CAVITY DATA=d1 ATOMS=1,4,5,11 SIGMA=0.1 MEAN MORE_THAN={RATIONAL R_0=4} LABEL=cav
+     106             : \endplumedfile
+     107             : 
+     108             : */
+     109             : //+ENDPLUMEDOC
+     110             : 
+     111             : namespace PLMD {
+     112             : namespace multicolvar {
+     113             : 
+     114             : class VolumeTetrapore : public ActionVolume {
+     115             : private:
+     116             :   bool boxout;
+     117             :   OFile boxfile;
+     118             :   double lenunit;
+     119             :   double jacob_det;
+     120             :   double len_bi, len_cross, len_perp, sigma;
+     121             :   Vector origin, bi, cross, perp;
+     122             :   std::vector<Vector> dlbi, dlcross, dlperp;
+     123             :   std::vector<Tensor> dbi, dcross, dperp;
+     124             : public:
+     125             :   static void registerKeywords( Keywords& keys );
+     126             :   explicit VolumeTetrapore(const ActionOptions& ao);
+     127             :   ~VolumeTetrapore();
+     128             :   void setupRegions() override;
+     129             :   void update() override;
+     130             :   double calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& refders ) const override;
+     131             : };
+     132             : 
+     133             : PLUMED_REGISTER_ACTION(VolumeTetrapore,"TETRAHEDRALPORE")
+     134             : 
+     135           2 : void VolumeTetrapore::registerKeywords( Keywords& keys ) {
+     136           2 :   ActionVolume::registerKeywords( keys );
+     137           4 :   keys.add("atoms","ATOMS","the positions of four atoms that define spatial extent of the cavity");
+     138           4 :   keys.addFlag("PRINT_BOX",false,"write out the positions of the corners of the box to an xyz file");
+     139           4 :   keys.add("optional","FILE","the file on which to write out the box coordinates");
+     140           4 :   keys.add("optional","UNITS","( default=nm ) the units in which to write out the corners of the box");
+     141           2 : }
+     142             : 
+     143           0 : VolumeTetrapore::VolumeTetrapore(const ActionOptions& ao):
+     144             :   Action(ao),
+     145             :   ActionVolume(ao),
+     146           0 :   boxout(false),
+     147           0 :   lenunit(1.0),
+     148           0 :   dlbi(4),
+     149           0 :   dlcross(4),
+     150           0 :   dlperp(4),
+     151           0 :   dbi(3),
+     152           0 :   dcross(3),
+     153           0 :   dperp(3)
+     154             : {
+     155             :   std::vector<AtomNumber> atoms;
+     156           0 :   parseAtomList("ATOMS",atoms);
+     157           0 :   if( atoms.size()!=4 ) error("number of atoms should be equal to four");
+     158             : 
+     159           0 :   log.printf("  boundaries for region are calculated based on positions of atoms : ");
+     160           0 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf("%d ",atoms[i].serial() );
+     161           0 :   log.printf("\n");
+     162             : 
+     163           0 :   boxout=false; parseFlag("PRINT_BOX",boxout);
+     164           0 :   if(boxout) {
+     165           0 :     std::string boxfname; parse("FILE",boxfname);
+     166           0 :     if(boxfname.length()==0) error("no name for box file specified");
+     167           0 :     std::string unitname; parse("UNITS",unitname);
+     168           0 :     if ( unitname.length()>0 ) {
+     169           0 :       Units u; u.setLength(unitname);
+     170           0 :       lenunit=getUnits().getLength()/u.getLength();
+     171           0 :     } else {
+     172             :       unitname="nm";
+     173             :     }
+     174           0 :     boxfile.link(*this);
+     175           0 :     boxfile.open( boxfname );
+     176           0 :     log.printf("  printing box coordinates on file named %s in %s \n",boxfname.c_str(), unitname.c_str() );
+     177             :   }
+     178             : 
+     179           0 :   checkRead();
+     180           0 :   requestAtoms(atoms);
+     181             :   // We have to readd the dependency because requestAtoms removes it
+     182           0 :   addDependency( getPntrToMultiColvar() );
+     183           0 : }
+     184             : 
+     185           0 : VolumeTetrapore::~VolumeTetrapore() {
+     186           0 : }
+     187             : 
+     188           0 : void VolumeTetrapore::setupRegions() {
+     189             :   // Make some space for things
+     190           0 :   Vector d1, d2, d3;
+     191             : 
+     192             :   // Retrieve the sigma value
+     193           0 :   sigma=getSigma();
+     194             :   // Set the position of the origin
+     195           0 :   origin=getPosition(0);
+     196             : 
+     197             :   // Get two vectors
+     198           0 :   d1 = pbcDistance(origin,getPosition(1));
+     199           0 :   d2 = pbcDistance(origin,getPosition(2));
+     200             : 
+     201             :   // Find the vector connecting the origin to the top corner of
+     202             :   // the subregion
+     203           0 :   d3 = pbcDistance(origin,getPosition(3));
+     204             : 
+     205             :   // Create a set of unit vectors
+     206           0 :   Vector bisector = d1 + d2; double bmod=bisector.modulo(); bisector=bisector/bmod;
+     207             : 
+     208             :   // bi = d1 / d1l; len_bi=dotProduct( d3, bi );
+     209           0 :   cross = crossProduct( d1, d2 ); double crossmod=cross.modulo();
+     210           0 :   cross = cross / crossmod; len_cross=dotProduct( d3, cross );
+     211           0 :   Vector truep = crossProduct( cross, bisector );
+     212             : 
+     213             :   // These are our true vectors 45 degrees from bisector
+     214           0 :   bi = std::cos(pi/4.0)*bisector + std::sin(pi/4.0)*truep;
+     215           0 :   perp = std::cos(pi/4.0)*bisector - std::sin(pi/4.0)*truep;
+     216             : 
+     217             :   // And the lengths of the various parts average distance to opposite corners of tetetrahedron
+     218           0 :   len_bi = dotProduct( d1, bi ); double len_bi2 = dotProduct( d2, bi ); unsigned lbi=1;
+     219           0 :   if( len_bi2>len_bi ) { len_bi=len_bi2; lbi=2; }
+     220           0 :   len_perp = dotProduct( d1, perp ); double len_perp2 = dotProduct( d2, perp ); unsigned lpi=1;
+     221           0 :   if( len_perp2>len_perp ) { len_perp=len_perp2; lpi=2; }
+     222           0 :   plumed_assert( lbi!=lpi );
+     223             : 
+     224           0 :   Tensor tcderiv; double cmod3=crossmod*crossmod*crossmod; Vector ucross=crossmod*cross;
+     225           0 :   tcderiv.setCol( 0, crossProduct( d1, Vector(-1.0,0.0,0.0) ) + crossProduct( Vector(-1.0,0.0,0.0), d2 ) );
+     226           0 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,-1.0,0.0) ) + crossProduct( Vector(0.0,-1.0,0.0), d2 ) );
+     227           0 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,-1.0) ) + crossProduct( Vector(0.0,0.0,-1.0), d2 ) );
+     228           0 :   dcross[0](0,0)=( tcderiv(0,0)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dx/dx
+     229           0 :   dcross[0](0,1)=( tcderiv(0,1)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dx/dy
+     230           0 :   dcross[0](0,2)=( tcderiv(0,2)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dx/dz
+     231           0 :   dcross[0](1,0)=( tcderiv(1,0)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dy/dx
+     232           0 :   dcross[0](1,1)=( tcderiv(1,1)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dy/dy
+     233           0 :   dcross[0](1,2)=( tcderiv(1,2)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dy/dz
+     234           0 :   dcross[0](2,0)=( tcderiv(2,0)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dz/dx
+     235           0 :   dcross[0](2,1)=( tcderiv(2,1)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dz/dy
+     236           0 :   dcross[0](2,2)=( tcderiv(2,2)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dz/dz
+     237             : 
+     238           0 :   tcderiv.setCol( 0, crossProduct( Vector(1.0,0.0,0.0), d2 ) );
+     239           0 :   tcderiv.setCol( 1, crossProduct( Vector(0.0,1.0,0.0), d2 ) );
+     240           0 :   tcderiv.setCol( 2, crossProduct( Vector(0.0,0.0,1.0), d2 ) );
+     241           0 :   dcross[1](0,0)=( tcderiv(0,0)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dx/dx
+     242           0 :   dcross[1](0,1)=( tcderiv(0,1)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dx/dy
+     243           0 :   dcross[1](0,2)=( tcderiv(0,2)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dx/dz
+     244           0 :   dcross[1](1,0)=( tcderiv(1,0)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dy/dx
+     245           0 :   dcross[1](1,1)=( tcderiv(1,1)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dy/dy
+     246           0 :   dcross[1](1,2)=( tcderiv(1,2)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dy/dz
+     247           0 :   dcross[1](2,0)=( tcderiv(2,0)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dz/dx
+     248           0 :   dcross[1](2,1)=( tcderiv(2,1)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dz/dy
+     249           0 :   dcross[1](2,2)=( tcderiv(2,2)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dz/dz
+     250             : 
+     251           0 :   tcderiv.setCol( 0, crossProduct( d1, Vector(1.0,0.0,0.0) ) );
+     252           0 :   tcderiv.setCol( 1, crossProduct( d1, Vector(0.0,1.0,0.0) ) );
+     253           0 :   tcderiv.setCol( 2, crossProduct( d1, Vector(0.0,0.0,1.0) ) );
+     254           0 :   dcross[2](0,0)=( tcderiv(0,0)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dx/dx
+     255           0 :   dcross[2](0,1)=( tcderiv(0,1)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dx/dy
+     256           0 :   dcross[2](0,2)=( tcderiv(0,2)/crossmod - ucross[0]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dx/dz
+     257           0 :   dcross[2](1,0)=( tcderiv(1,0)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dy/dx
+     258           0 :   dcross[2](1,1)=( tcderiv(1,1)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dy/dy
+     259           0 :   dcross[2](1,2)=( tcderiv(1,2)/crossmod - ucross[1]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dy/dz
+     260           0 :   dcross[2](2,0)=( tcderiv(2,0)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,0) + ucross[1]*tcderiv(1,0) + ucross[2]*tcderiv(2,0))/cmod3 );    // dz/dx
+     261           0 :   dcross[2](2,1)=( tcderiv(2,1)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,1) + ucross[1]*tcderiv(1,1) + ucross[2]*tcderiv(2,1))/cmod3 );    // dz/dy
+     262           0 :   dcross[2](2,2)=( tcderiv(2,2)/crossmod - ucross[2]*(ucross[0]*tcderiv(0,2) + ucross[1]*tcderiv(1,2) + ucross[2]*tcderiv(2,2))/cmod3 );    // dz/dz
+     263             : 
+     264           0 :   std::vector<Tensor> dbisector(3);
+     265           0 :   double bmod3=bmod*bmod*bmod; Vector ubisector=bmod*bisector;
+     266           0 :   dbisector[0](0,0)= -2.0/bmod + 2*ubisector[0]*ubisector[0]/bmod3;
+     267           0 :   dbisector[0](0,1)= 2*ubisector[0]*ubisector[1]/bmod3;
+     268           0 :   dbisector[0](0,2)= 2*ubisector[0]*ubisector[2]/bmod3;
+     269           0 :   dbisector[0](1,0)= 2*ubisector[1]*ubisector[0]/bmod3;
+     270           0 :   dbisector[0](1,1)= -2.0/bmod + 2*ubisector[1]*ubisector[1]/bmod3;
+     271           0 :   dbisector[0](1,2)= 2*ubisector[1]*ubisector[2]/bmod3;
+     272           0 :   dbisector[0](2,0)= 2*ubisector[2]*ubisector[0]/bmod3;
+     273           0 :   dbisector[0](2,1)= 2*ubisector[2]*ubisector[1]/bmod3;
+     274           0 :   dbisector[0](2,2)= -2.0/bmod + 2*ubisector[2]*ubisector[2]/bmod3;
+     275             : 
+     276           0 :   dbisector[1](0,0)= 1.0/bmod - ubisector[0]*ubisector[0]/bmod3;
+     277           0 :   dbisector[1](0,1)= -ubisector[0]*ubisector[1]/bmod3;
+     278           0 :   dbisector[1](0,2)= -ubisector[0]*ubisector[2]/bmod3;
+     279           0 :   dbisector[1](1,0)= -ubisector[1]*ubisector[0]/bmod3;
+     280           0 :   dbisector[1](1,1)= 1.0/bmod - ubisector[1]*ubisector[1]/bmod3;
+     281           0 :   dbisector[1](1,2)= -ubisector[1]*ubisector[2]/bmod3;
+     282           0 :   dbisector[1](2,0)= -ubisector[2]*ubisector[0]/bmod3;
+     283           0 :   dbisector[1](2,1)= -ubisector[2]*ubisector[1]/bmod3;
+     284           0 :   dbisector[1](2,2)=1.0/bmod - ubisector[2]*ubisector[2]/bmod3;
+     285             : 
+     286           0 :   dbisector[2](0,0)=1.0/bmod - ubisector[0]*ubisector[0]/bmod3;
+     287           0 :   dbisector[2](0,1)= -ubisector[0]*ubisector[1]/bmod3;
+     288           0 :   dbisector[2](0,2)= -ubisector[0]*ubisector[2]/bmod3;
+     289           0 :   dbisector[2](1,0)= -ubisector[1]*ubisector[0]/bmod3;
+     290           0 :   dbisector[2](1,1)=1.0/bmod - ubisector[1]*ubisector[1]/bmod3;
+     291           0 :   dbisector[2](1,2)= -ubisector[1]*ubisector[2]/bmod3;
+     292           0 :   dbisector[2](2,0)= -ubisector[2]*ubisector[0]/bmod3;
+     293           0 :   dbisector[2](2,1)= -ubisector[2]*ubisector[1]/bmod3;
+     294           0 :   dbisector[2](2,2)=1.0/bmod - ubisector[2]*ubisector[2]/bmod3;
+     295             : 
+     296           0 :   std::vector<Tensor> dtruep(3);
+     297           0 :   dtruep[0].setCol( 0, ( crossProduct( dcross[0].getCol(0), bisector ) + crossProduct( cross, dbisector[0].getCol(0) ) ) );
+     298           0 :   dtruep[0].setCol( 1, ( crossProduct( dcross[0].getCol(1), bisector ) + crossProduct( cross, dbisector[0].getCol(1) ) ) );
+     299           0 :   dtruep[0].setCol( 2, ( crossProduct( dcross[0].getCol(2), bisector ) + crossProduct( cross, dbisector[0].getCol(2) ) ) );
+     300             : 
+     301           0 :   dtruep[1].setCol( 0, ( crossProduct( dcross[1].getCol(0), bisector ) + crossProduct( cross, dbisector[1].getCol(0) ) ) );
+     302           0 :   dtruep[1].setCol( 1, ( crossProduct( dcross[1].getCol(1), bisector ) + crossProduct( cross, dbisector[1].getCol(1) ) ) );
+     303           0 :   dtruep[1].setCol( 2, ( crossProduct( dcross[1].getCol(2), bisector ) + crossProduct( cross, dbisector[1].getCol(2) ) ) );
+     304             : 
+     305           0 :   dtruep[2].setCol( 0, ( crossProduct( dcross[2].getCol(0), bisector ) + crossProduct( cross, dbisector[2].getCol(0) ) ) );
+     306           0 :   dtruep[2].setCol( 1, ( crossProduct( dcross[2].getCol(1), bisector ) + crossProduct( cross, dbisector[2].getCol(1) ) ) );
+     307           0 :   dtruep[2].setCol( 2, ( crossProduct( dcross[2].getCol(2), bisector ) + crossProduct( cross, dbisector[2].getCol(2) ) ) );
+     308             : 
+     309             :   // Now convert these to the derivatives of the true axis
+     310           0 :   for(unsigned i=0; i<3; ++i) {
+     311           0 :     dbi[i] = std::cos(pi/4.0)*dbisector[i] + std::sin(pi/4.0)*dtruep[i];
+     312           0 :     dperp[i] = std::cos(pi/4.0)*dbisector[i] - std::sin(pi/4.0)*dtruep[i];
+     313             :   }
+     314             : 
+     315             :   // Ensure that all lengths are positive
+     316           0 :   if( len_bi<0 ) {
+     317           0 :     bi=-bi; len_bi=-len_bi;
+     318           0 :     for(unsigned i=0; i<3; ++i) dbi[i]*=-1.0;
+     319             :   }
+     320           0 :   if( len_cross<0 ) {
+     321           0 :     cross=-cross; len_cross=-len_cross;
+     322           0 :     for(unsigned i=0; i<3; ++i) dcross[i]*=-1.0;
+     323             :   }
+     324           0 :   if( len_perp<0 ) {
+     325           0 :     perp=-perp; len_perp=-len_perp;
+     326           0 :     for(unsigned i=0; i<3; ++i) dperp[i]*=-1.0;
+     327             :   }
+     328           0 :   if( len_bi<=0 || len_cross<=0 || len_perp<=0 ) plumed_merror("Invalid box coordinates");
+     329             : 
+     330             :   // Now derivatives of lengths
+     331           0 :   Tensor dd3( Tensor::identity() ); Vector ddb2=d1; if( lbi==2 ) ddb2=d2;
+     332           0 :   dlbi[1].zero(); dlbi[2].zero(); dlbi[3].zero();
+     333           0 :   dlbi[0] = matmul(ddb2,dbi[0]) - matmul(bi,dd3);
+     334           0 :   dlbi[lbi] = matmul(ddb2,dbi[lbi]) + matmul(bi,dd3);  // Derivative wrt d1
+     335             : 
+     336           0 :   dlcross[0] = matmul(d3,dcross[0]) - matmul(cross,dd3);
+     337           0 :   dlcross[1] = matmul(d3,dcross[1]);
+     338           0 :   dlcross[2] = matmul(d3,dcross[2]);
+     339           0 :   dlcross[3] = matmul(cross,dd3);
+     340             : 
+     341           0 :   ddb2=d1; if( lpi==2 ) ddb2=d2;
+     342           0 :   dlperp[1].zero(); dlperp[2].zero(); dlperp[3].zero();
+     343           0 :   dlperp[0] = matmul(ddb2,dperp[0]) - matmul( perp, dd3 );
+     344           0 :   dlperp[lpi] = matmul(ddb2,dperp[lpi]) + matmul(perp, dd3);
+     345             : 
+     346             :   // Need to calculate the jacobian
+     347           0 :   Tensor jacob;
+     348           0 :   jacob(0,0)=bi[0]; jacob(1,0)=bi[1]; jacob(2,0)=bi[2];
+     349           0 :   jacob(0,1)=cross[0]; jacob(1,1)=cross[1]; jacob(2,1)=cross[2];
+     350           0 :   jacob(0,2)=perp[0]; jacob(1,2)=perp[1]; jacob(2,2)=perp[2];
+     351           0 :   jacob_det = std::fabs( jacob.determinant() );
+     352           0 : }
+     353             : 
+     354           0 : void VolumeTetrapore::update() {
+     355           0 :   if(boxout) {
+     356           0 :     boxfile.printf("%d\n",8);
+     357           0 :     const Tensor & t(getPbc().getBox());
+     358           0 :     if(getPbc().isOrthorombic()) {
+     359           0 :       boxfile.printf(" %f %f %f\n",lenunit*t(0,0),lenunit*t(1,1),lenunit*t(2,2));
+     360             :     } else {
+     361           0 :       boxfile.printf(" %f %f %f %f %f %f %f %f %f\n",
+     362           0 :                      lenunit*t(0,0),lenunit*t(0,1),lenunit*t(0,2),
+     363           0 :                      lenunit*t(1,0),lenunit*t(1,1),lenunit*t(1,2),
+     364           0 :                      lenunit*t(2,0),lenunit*t(2,1),lenunit*t(2,2)
+     365             :                     );
+     366             :     }
+     367           0 :     boxfile.printf("AR %f %f %f \n",lenunit*origin[0],lenunit*origin[1],lenunit*origin[2]);
+     368           0 :     Vector ut, vt, wt;
+     369           0 :     ut = origin + len_bi*bi;
+     370           0 :     vt = origin + len_cross*cross;
+     371           0 :     wt = origin + len_perp*perp;
+     372           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]), lenunit*(ut[1]), lenunit*(ut[2]) );
+     373           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]), lenunit*(vt[1]), lenunit*(vt[2]) );
+     374           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(wt[0]), lenunit*(wt[1]), lenunit*(wt[2]) );
+     375           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_bi*bi[0]),
+     376           0 :                    lenunit*(vt[1]+len_bi*bi[1]),
+     377           0 :                    lenunit*(vt[2]+len_bi*bi[2]) );
+     378           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(ut[0]+len_perp*perp[0]),
+     379           0 :                    lenunit*(ut[1]+len_perp*perp[1]),
+     380           0 :                    lenunit*(ut[2]+len_perp*perp[2]) );
+     381           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]),
+     382           0 :                    lenunit*(vt[1]+len_perp*perp[1]),
+     383           0 :                    lenunit*(vt[2]+len_perp*perp[2]) );
+     384           0 :     boxfile.printf("AR %f %f %f \n",lenunit*(vt[0]+len_perp*perp[0]+len_bi*bi[0]),
+     385           0 :                    lenunit*(vt[1]+len_perp*perp[1]+len_bi*bi[1]),
+     386           0 :                    lenunit*(vt[2]+len_perp*perp[2]+len_bi*bi[2]) );
+     387             :   }
+     388           0 : }
+     389             : 
+     390           0 : double VolumeTetrapore::calculateNumberInside( const Vector& cpos, Vector& derivatives, Tensor& vir, std::vector<Vector>& rderiv ) const {
+     391             :   // Setup the histogram bead
+     392           0 :   HistogramBead bead; bead.isNotPeriodic(); bead.setKernelType( getKernelType() );
+     393             : 
+     394             :   // Calculate distance of atom from origin of new coordinate frame
+     395           0 :   Vector datom=pbcDistance( origin, cpos );
+     396             :   double ucontr, uder, vcontr, vder, wcontr, wder;
+     397             : 
+     398             :   // Calculate contribution from integral along bi
+     399           0 :   bead.set( 0, len_bi, sigma );
+     400           0 :   double upos=dotProduct( datom, bi );
+     401           0 :   ucontr=bead.calculate( upos, uder );
+     402           0 :   double udlen=bead.uboundDerivative( upos );
+     403           0 :   double uder2 = bead.lboundDerivative( upos ) - udlen;
+     404             : 
+     405             :   // Calculate contribution from integral along cross
+     406           0 :   bead.set( 0, len_cross, sigma );
+     407           0 :   double vpos=dotProduct( datom, cross );
+     408           0 :   vcontr=bead.calculate( vpos, vder );
+     409           0 :   double vdlen=bead.uboundDerivative( vpos );
+     410           0 :   double vder2 = bead.lboundDerivative( vpos ) - vdlen;
+     411             : 
+     412             :   // Calculate contribution from integral along perp
+     413           0 :   bead.set( 0, len_perp, sigma );
+     414           0 :   double wpos=dotProduct( datom, perp );
+     415           0 :   wcontr=bead.calculate( wpos, wder );
+     416           0 :   double wdlen=bead.uboundDerivative( wpos );
+     417           0 :   double wder2 = bead.lboundDerivative( wpos ) - wdlen;
+     418             : 
+     419           0 :   Vector dfd; dfd[0]=uder*vcontr*wcontr; dfd[1]=ucontr*vder*wcontr; dfd[2]=ucontr*vcontr*wder;
+     420           0 :   derivatives[0] = (dfd[0]*bi[0]+dfd[1]*cross[0]+dfd[2]*perp[0]);
+     421           0 :   derivatives[1] = (dfd[0]*bi[1]+dfd[1]*cross[1]+dfd[2]*perp[1]);
+     422           0 :   derivatives[2] = (dfd[0]*bi[2]+dfd[1]*cross[2]+dfd[2]*perp[2]);
+     423           0 :   double tot = ucontr*vcontr*wcontr*jacob_det;
+     424             : 
+     425             :   // Add reference atom derivatives
+     426           0 :   dfd[0]=uder2*vcontr*wcontr; dfd[1]=ucontr*vder2*wcontr; dfd[2]=ucontr*vcontr*wder2;
+     427           0 :   Vector dfld; dfld[0]=udlen*vcontr*wcontr; dfld[1]=ucontr*vdlen*wcontr; dfld[2]=ucontr*vcontr*wdlen;
+     428           0 :   rderiv[0] = dfd[0]*matmul(datom,dbi[0]) + dfd[1]*matmul(datom,dcross[0]) + dfd[2]*matmul(datom,dperp[0]) +
+     429           0 :               dfld[0]*dlbi[0] + dfld[1]*dlcross[0] + dfld[2]*dlperp[0] - derivatives;
+     430           0 :   rderiv[1] = dfd[0]*matmul(datom,dbi[1]) + dfd[1]*matmul(datom,dcross[1]) + dfd[2]*matmul(datom,dperp[1]) +
+     431           0 :               dfld[0]*dlbi[1] + dfld[1]*dlcross[1] + dfld[2]*dlperp[1];
+     432           0 :   rderiv[2] = dfd[0]*matmul(datom,dbi[2]) + dfd[1]*matmul(datom,dcross[2]) + dfd[2]*matmul(datom,dperp[2]) +
+     433           0 :               dfld[0]*dlbi[2] + dfld[1]*dlcross[2] + dfld[2]*dlperp[2];
+     434           0 :   rderiv[3] = dfld[0]*dlbi[3] + dfld[1]*dlcross[3] + dfld[2]*dlperp[3];
+     435             : 
+     436           0 :   vir.zero(); vir-=Tensor( cpos,derivatives );
+     437           0 :   for(unsigned i=0; i<4; ++i) {
+     438           0 :     vir -= Tensor( getPosition(i), rderiv[i] );
+     439             :   }
+     440             : 
+     441           0 :   return tot;
+     442             : }
+     443             : 
+     444             : }
+     445             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XAngle.cpp.func-sort-c.html b/coverage/multicolvar/XAngle.cpp.func-sort-c.html new file mode 100644 index 000000000000..433cc5490081 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XAngle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XAngle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:474897.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar7XAnglesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar7XAngles10isPeriodicEv3
_ZN4PLMD11multicolvar7XAnglesC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar7XAngles16registerKeywordsERNS_8KeywordsE9
_ZNK4PLMD11multicolvar7XAngles7computeERKjRNS0_13AtomValuePackE50
_ZNK4PLMD11multicolvar7XAngles15calculateWeightERKjRKdRNS0_13AtomValuePackE110
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XAngle.cpp.func.html b/coverage/multicolvar/XAngle.cpp.func.html new file mode 100644 index 000000000000..8ae1aa3e15d8 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XAngle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XAngle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:474897.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar7XAngles10isPeriodicEv3
_ZN4PLMD11multicolvar7XAngles16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD11multicolvar7XAnglesC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar7XAnglesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar7XAngles15calculateWeightERKjRKdRNS0_13AtomValuePackE110
_ZNK4PLMD11multicolvar7XAngles7computeERKjRNS0_13AtomValuePackE50
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XAngle.cpp.gcov.html b/coverage/multicolvar/XAngle.cpp.gcov.html new file mode 100644 index 000000000000..bc4b0f104be3 --- /dev/null +++ b/coverage/multicolvar/XAngle.cpp.gcov.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XAngle.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XAngle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:474897.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Angle.h"
+      26             : #include "tools/SwitchingFunction.h"
+      27             : 
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace multicolvar {
+      33             : 
+      34             : //+PLUMEDOC MCOLVAR XANGLES
+      35             : /*
+      36             : Calculate the angles between the vector connecting two atoms and the x axis.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : The following input tells plumed to calculate the angles between the x-axis and the vector connecting atom 3 to atom 5 and between the x-axis
+      41             : and the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then
+      42             : \plumedfile
+      43             : XANGLES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1} LABEL=d1
+      44             : PRINT ARG=d1.min
+      45             : \endplumedfile
+      46             : (See also \ref PRINT).
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : //+PLUMEDOC MCOLVAR YANGLES
+      51             : /*
+      52             : Calculate the angles between the vector connecting two atoms and the y axis.
+      53             : 
+      54             : \par Examples
+      55             : 
+      56             : The following input tells plumed to calculate the angles between the y-axis and the vector connecting atom 3 to atom 5 and between the y-axis
+      57             : and the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then
+      58             : \plumedfile
+      59             : YANGLES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1} LABEL=d1
+      60             : PRINT ARG=d1.min
+      61             : \endplumedfile
+      62             : (See also \ref PRINT).
+      63             : */
+      64             : //+ENDPLUMEDOC
+      65             : 
+      66             : //+PLUMEDOC MCOLVAR ZANGLES
+      67             : /*
+      68             : Calculate the angles between the vector connecting two atoms and the z axis.
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : The following input tells plumed to calculate the angles between the z-axis and the vector connecting atom 3 to atom 5 and between the z-axis
+      73             : and the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then
+      74             : \plumedfile
+      75             : ZANGLES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1} LABEL=d1
+      76             : PRINT ARG=d1.min
+      77             : \endplumedfile
+      78             : (See also \ref PRINT).
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : 
+      82             : 
+      83             : 
+      84             : class XAngles : public MultiColvarBase {
+      85             : private:
+      86             :   bool use_sf;
+      87             :   unsigned myc;
+      88             :   SwitchingFunction sf1;
+      89             : public:
+      90             :   static void registerKeywords( Keywords& keys );
+      91             :   explicit XAngles(const ActionOptions&);
+      92             : // active methods:
+      93             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+      94             :   double calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& ) const override;
+      95             : /// Returns the number of coordinates of the field
+      96           3 :   bool isPeriodic() override { return false; }
+      97             : };
+      98             : 
+      99             : PLUMED_REGISTER_ACTION(XAngles,"XANGLES")
+     100             : PLUMED_REGISTER_ACTION(XAngles,"YANGLES")
+     101             : PLUMED_REGISTER_ACTION(XAngles,"ZANGLES")
+     102             : 
+     103           9 : void XAngles::registerKeywords( Keywords& keys ) {
+     104           9 :   MultiColvarBase::registerKeywords( keys );
+     105          18 :   keys.use("MAX"); keys.use("ALT_MIN");
+     106          27 :   keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN");
+     107          18 :   keys.use("LOWEST"); keys.use("HIGHEST");
+     108          36 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     109          18 :   keys.add("numbered","ATOMS","the atoms involved in each of the angles you wish to calculate. "
+     110             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one angle will be "
+     111             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     112             :            "specify the indices of two atoms).  The eventual number of quantities calculated by this "
+     113             :            "action will depend on what functions of the distribution you choose to calculate.");
+     114          18 :   keys.reset_style("ATOMS","atoms");
+     115          18 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     116          18 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+     117             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+     118          18 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+     119             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+     120          18 :   keys.add("optional","SWITCH","A switching function that ensures that only angles are only computed when atoms are within "
+     121             :            "are within a certain fixed cutoff. The following provides information on the \\ref switchingfunction that are available.");
+     122           9 : }
+     123             : 
+     124           3 : XAngles::XAngles(const ActionOptions&ao):
+     125             :   Action(ao),
+     126             :   MultiColvarBase(ao),
+     127           3 :   use_sf(false)
+     128             : {
+     129           3 :   if( getName().find("X")!=std::string::npos) myc=0;
+     130           2 :   else if( getName().find("Y")!=std::string::npos) myc=1;
+     131           2 :   else if( getName().find("Z")!=std::string::npos) myc=2;
+     132           0 :   else plumed_error();
+     133             : 
+     134             :   // Read in switching function
+     135           6 :   std::string sfinput, errors; parse("SWITCH",sfinput);
+     136           3 :   if( sfinput.length()>0 ) {
+     137           2 :     use_sf=true; weightHasDerivatives=true;
+     138           2 :     sf1.set(sfinput,errors);
+     139           2 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     140           2 :     log.printf("  only calculating angles for atoms separated by less than %s\n", sf1.description().c_str() );
+     141           2 :     setLinkCellCutoff( sf1.get_dmax() );
+     142             :   }
+     143             : 
+     144             :   // Read in the atoms
+     145             :   std::vector<AtomNumber> all_atoms;
+     146           6 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     147           4 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+     148           3 :   setupMultiColvarBase( all_atoms );
+     149             :   // And check everything has been read in correctly
+     150           3 :   checkRead();
+     151           3 : }
+     152             : 
+     153         110 : double XAngles::calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const {
+     154         110 :   if(!use_sf) return 1.0;
+     155             : 
+     156         100 :   Vector distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     157         100 :   double dw, w = sf1.calculateSqr( distance.modulo2(), dw );
+     158         100 :   addAtomDerivatives( 0, 0, (-dw)*distance, myatoms );
+     159         100 :   addAtomDerivatives( 0, 1, (+dw)*distance, myatoms );
+     160         100 :   myatoms.addBoxDerivatives( 0, (-dw)*Tensor(distance,distance) );
+     161         100 :   return w;
+     162             : }
+     163             : 
+     164          50 : double XAngles::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     165          50 :   Vector ddij, ddik, axis, distance; axis.zero(); axis[myc]=1;
+     166          50 :   distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     167          50 :   PLMD::Angle a; double angle=a.compute( distance, axis, ddij, ddik );
+     168             : 
+     169          50 :   addAtomDerivatives( 1, 0, -ddij, myatoms );
+     170          50 :   addAtomDerivatives( 1, 1, ddij, myatoms );
+     171          50 :   myatoms.addBoxDerivatives( 1, -Tensor( distance,ddij ) );
+     172          50 :   return angle;
+     173             : }
+     174             : 
+     175             : }
+     176             : }
+     177             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XDistances.cpp.func-sort-c.html b/coverage/multicolvar/XDistances.cpp.func-sort-c.html new file mode 100644 index 000000000000..643687477756 --- /dev/null +++ b/coverage/multicolvar/XDistances.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XDistances.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XDistances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303390.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10XDistancesC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar10XDistancesC1ERKNS_13ActionOptionsE1
_ZNK4PLMD11multicolvar10XDistances7computeERKjRNS0_13AtomValuePackE2
_ZN4PLMD11multicolvar10XDistances10isPeriodicEv4
_ZN4PLMD11multicolvar10XDistances16registerKeywordsERNS_8KeywordsE7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XDistances.cpp.func.html b/coverage/multicolvar/XDistances.cpp.func.html new file mode 100644 index 000000000000..349c0fdc704b --- /dev/null +++ b/coverage/multicolvar/XDistances.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XDistances.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XDistances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303390.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar10XDistances10isPeriodicEv4
_ZN4PLMD11multicolvar10XDistances16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD11multicolvar10XDistancesC1ERKNS_13ActionOptionsE1
_ZN4PLMD11multicolvar10XDistancesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar10XDistances7computeERKjRNS0_13AtomValuePackE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XDistances.cpp.gcov.html b/coverage/multicolvar/XDistances.cpp.gcov.html new file mode 100644 index 000000000000..b07c65e5991b --- /dev/null +++ b/coverage/multicolvar/XDistances.cpp.gcov.html @@ -0,0 +1,318 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XDistances.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XDistances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303390.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : #include <string>
+      27             : #include <cmath>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace multicolvar {
+      31             : 
+      32             : //+PLUMEDOC MCOLVAR XDISTANCES
+      33             : /*
+      34             : Calculate the x components of the vectors connecting one or many pairs of atoms.
+      35             : You can then calculate functions of the distribution of values such as the minimum, the number less than a certain quantity and so on.
+      36             : 
+      37             : \par Examples
+      38             : 
+      39             : The following input tells plumed to calculate the x-component of the vector connecting atom 3 to atom 5 and
+      40             : the x-component of the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then
+      41             : printed
+      42             : \plumedfile
+      43             : d1: XDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
+      44             : PRINT ARG=d1.min
+      45             : \endplumedfile
+      46             : (See also \ref PRINT).
+      47             : 
+      48             : 
+      49             : The following input tells plumed to calculate the x-component of the vector connecting atom 3 to atom 5 and
+      50             : the x-component of the vector connecting atom 1 to atom 2.  The number of values that are
+      51             : less than 0.1nm is then printed to a file.
+      52             : \plumedfile
+      53             : d1: XDISTANCES ATOMS1=3,5 ATOMS2=1,2 LESS_THAN={RATIONAL R_0=0.1}
+      54             : PRINT ARG=d1.lessthan
+      55             : \endplumedfile
+      56             : (See also \ref PRINT \ref switchingfunction).
+      57             : 
+      58             : The following input tells plumed to calculate the x-components of all the distinct vectors that can be created
+      59             : between atoms 1, 2 and 3 (i.e. the vectors between atoms 1 and 2, atoms 1 and 3 and atoms 2 and 3).
+      60             : The average of these quantities is then calculated.
+      61             : \plumedfile
+      62             : d1: XDISTANCES GROUP=1-3 MEAN
+      63             : PRINT ARG=d1.mean
+      64             : \endplumedfile
+      65             : (See also \ref PRINT)
+      66             : 
+      67             : The following input tells plumed to calculate all the vectors connecting the the atoms in GROUPA to the atoms in GROUPB.
+      68             : In other words the vector between atoms 1 and 2 and the vector between atoms 1 and 3.  The number of values
+      69             : more than 0.1 is then printed to a file.
+      70             : \plumedfile
+      71             : d1: XDISTANCES GROUPA=1 GROUPB=2,3 MORE_THAN={RATIONAL R_0=0.1}
+      72             : PRINT ARG=d1.morethan
+      73             : \endplumedfile
+      74             : (See also \ref PRINT \ref switchingfunction)
+      75             : */
+      76             : //+ENDPLUMEDOC
+      77             : 
+      78             : //+PLUMEDOC MCOLVAR YDISTANCES
+      79             : /*
+      80             : Calculate the y components of the vectors connecting one or many pairs of atoms.
+      81             : You can then calculate functions of the distribution of values such as the minimum, the number less than a certain quantity and so on.
+      82             : 
+      83             : \par Examples
+      84             : 
+      85             : The following input tells plumed to calculate the y-component of the vector connecting atom 3 to atom 5 and
+      86             : the y-component of the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then
+      87             : printed
+      88             : \plumedfile
+      89             : d1: YDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
+      90             : PRINT ARG=d1.min
+      91             : \endplumedfile
+      92             : (See also \ref PRINT).
+      93             : 
+      94             : 
+      95             : The following input tells plumed to calculate the y-component of the vector connecting atom 3 to atom 5 and
+      96             : the y-component of the vector connecting atom 1 to atom 2.  The number of values that are
+      97             : less than 0.1nm is then printed to a file.
+      98             : \plumedfile
+      99             : d1: YDISTANCES ATOMS1=3,5 ATOMS2=1,2 LESS_THAN={RATIONAL R_0=0.1}
+     100             : PRINT ARG=d1.lessthan
+     101             : \endplumedfile
+     102             : (See also \ref PRINT \ref switchingfunction).
+     103             : 
+     104             : The following input tells plumed to calculate the y-components of all the distinct vectors that can be created
+     105             : between atoms 1, 2 and 3 (i.e. the vectors between atoms 1 and 2, atoms 1 and 3 and atoms 2 and 3).
+     106             : The average of these quantities is then calculated.
+     107             : \plumedfile
+     108             : d1: YDISTANCES GROUP=1-3 MEAN
+     109             : PRINT ARG=d1.mean
+     110             : \endplumedfile
+     111             : (See also \ref PRINT)
+     112             : 
+     113             : The following input tells plumed to calculate all the vectors connecting the the atoms in GROUPA to the atoms in GROUPB.
+     114             : In other words the vector between atoms 1 and 2 and the vector between atoms 1 and 3.  The number of values
+     115             : more than 0.1 is then printed to a file.
+     116             : \plumedfile
+     117             : d1: YDISTANCES GROUPA=1 GROUPB=2,3 MORE_THAN={RATIONAL R_0=0.1}
+     118             : PRINT ARG=d1.morethan
+     119             : \endplumedfile
+     120             : (See also \ref PRINT \ref switchingfunction)
+     121             : 
+     122             : */
+     123             : //+ENDPLUMEDOC
+     124             : 
+     125             : //+PLUMEDOC MCOLVAR ZDISTANCES
+     126             : /*
+     127             : Calculate the z components of the vectors connecting one or many pairs of atoms.
+     128             : You can then calculate functions of the distribution of values such as the minimum, the number less than a certain quantity and so on.
+     129             : 
+     130             : \par Examples
+     131             : 
+     132             : The following input tells plumed to calculate the z-component of the vector connecting atom 3 to atom 5 and
+     133             : the z-component of the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then
+     134             : printed
+     135             : \plumedfile
+     136             : d1: ZDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
+     137             : PRINT ARG=d1.min
+     138             : \endplumedfile
+     139             : (See also \ref PRINT).
+     140             : 
+     141             : 
+     142             : The following input tells plumed to calculate the z-component of the vector connecting atom 3 to atom 5 and
+     143             : the z-component of the vector connecting atom 1 to atom 2.  The number of values that are
+     144             : less than 0.1nm is then printed to a file.
+     145             : \plumedfile
+     146             : d1: ZDISTANCES ATOMS1=3,5 ATOMS2=1,2 LESS_THAN={RATIONAL R_0=0.1}
+     147             : PRINT ARG=d1.lessthan
+     148             : \endplumedfile
+     149             : (See also \ref PRINT \ref switchingfunction).
+     150             : 
+     151             : The following input tells plumed to calculate the z-components of all the distinct vectors that can be created
+     152             : between atoms 1, 2 and 3 (i.e. the vectors between atoms 1 and 2, atoms 1 and 3 and atoms 2 and 3).
+     153             : The average of these quantities is then calculated.
+     154             : \plumedfile
+     155             : d1: ZDISTANCES GROUP=1-3 MEAN
+     156             : PRINT ARG=d1.mean
+     157             : \endplumedfile
+     158             : (See also \ref PRINT)
+     159             : 
+     160             : The following input tells plumed to calculate all the vectors connecting the the atoms in GROUPA to the atoms in GROUPB.
+     161             : In other words the vector between atoms 1 and 2 and the vector between atoms 1 and 3.  The number of values
+     162             : more than 0.1 is then printed to a file.
+     163             : \plumedfile
+     164             : d1: ZDISTANCES GROUPA=1 GROUPB=2,3 MORE_THAN={RATIONAL R_0=0.1}
+     165             : PRINT ARG=d1.morethan
+     166             : \endplumedfile
+     167             : (See also \ref PRINT \ref switchingfunction)
+     168             : 
+     169             : */
+     170             : //+ENDPLUMEDOC
+     171             : 
+     172             : 
+     173             : class XDistances : public MultiColvarBase {
+     174             : private:
+     175             :   unsigned myc;
+     176             : public:
+     177             :   static void registerKeywords( Keywords& keys );
+     178             :   explicit XDistances(const ActionOptions&);
+     179             : // active methods:
+     180             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+     181             : /// Returns the number of coordinates of the field
+     182           4 :   bool isPeriodic() override { return false; }
+     183             : };
+     184             : 
+     185             : PLUMED_REGISTER_ACTION(XDistances,"XDISTANCES")
+     186             : PLUMED_REGISTER_ACTION(XDistances,"YDISTANCES")
+     187             : PLUMED_REGISTER_ACTION(XDistances,"ZDISTANCES")
+     188             : 
+     189           7 : void XDistances::registerKeywords( Keywords& keys ) {
+     190           7 :   MultiColvarBase::registerKeywords( keys );
+     191          14 :   keys.use("MAX"); keys.use("ALT_MIN");
+     192          21 :   keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN");
+     193          14 :   keys.use("LOWEST"); keys.use("HIGHEST");
+     194          28 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     195          14 :   keys.add("numbered","ATOMS","the atoms involved in each of the distances you wish to calculate. "
+     196             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one distance will be "
+     197             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     198             :            "specify the indices of two atoms).  The eventual number of quantities calculated by this "
+     199             :            "action will depend on what functions of the distribution you choose to calculate.");
+     200          14 :   keys.reset_style("ATOMS","atoms");
+     201          14 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     202          14 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+     203             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+     204          14 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+     205             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+     206           7 : }
+     207             : 
+     208           1 : XDistances::XDistances(const ActionOptions&ao):
+     209             :   Action(ao),
+     210           1 :   MultiColvarBase(ao)
+     211             : {
+     212           1 :   if( getName().find("X")!=std::string::npos) myc=0;
+     213           0 :   else if( getName().find("Y")!=std::string::npos) myc=1;
+     214           0 :   else if( getName().find("Z")!=std::string::npos) myc=2;
+     215           0 :   else plumed_error();
+     216             : 
+     217             :   // Read in the atoms
+     218             :   std::vector<AtomNumber> all_atoms;
+     219           2 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     220           2 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+     221           1 :   setupMultiColvarBase( all_atoms );
+     222             :   // And check everything has been read in correctly
+     223           1 :   checkRead();
+     224           1 : }
+     225             : 
+     226           2 : double XDistances::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     227           2 :   Vector distance;
+     228           2 :   distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     229           2 :   const double value=distance[myc];
+     230             : 
+     231           2 :   Vector myvec; myvec.zero();
+     232             :   // And finish the calculation
+     233           2 :   myvec[myc]=+1; addAtomDerivatives( 1, 1, myvec, myatoms );
+     234           2 :   myvec[myc]=-1; addAtomDerivatives( 1, 0, myvec, myatoms );
+     235           2 :   myatoms.addBoxDerivatives( 1, Tensor(distance,myvec) );
+     236           2 :   return value;
+     237             : }
+     238             : 
+     239             : }
+     240             : }
+     241             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYDistances.cpp.func-sort-c.html b/coverage/multicolvar/XYDistances.cpp.func-sort-c.html new file mode 100644 index 000000000000..f02d3461a685 --- /dev/null +++ b/coverage/multicolvar/XYDistances.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XYDistances.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XYDistances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:113630.6 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar11XYDistances10isPeriodicEv0
_ZN4PLMD11multicolvar11XYDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11XYDistancesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar11XYDistances7computeERKjRNS0_13AtomValuePackE0
_ZN4PLMD11multicolvar11XYDistances16registerKeywordsERNS_8KeywordsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYDistances.cpp.func.html b/coverage/multicolvar/XYDistances.cpp.func.html new file mode 100644 index 000000000000..e2ed613638ba --- /dev/null +++ b/coverage/multicolvar/XYDistances.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XYDistances.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XYDistances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:113630.6 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar11XYDistances10isPeriodicEv0
_ZN4PLMD11multicolvar11XYDistances16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD11multicolvar11XYDistancesC1ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar11XYDistancesC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar11XYDistances7computeERKjRNS0_13AtomValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYDistances.cpp.gcov.html b/coverage/multicolvar/XYDistances.cpp.gcov.html new file mode 100644 index 000000000000..f2246ee730cf --- /dev/null +++ b/coverage/multicolvar/XYDistances.cpp.gcov.html @@ -0,0 +1,246 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XYDistances.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XYDistances.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:113630.6 %
Date:2024-02-22 21:58:45Functions:1520.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : 
+      26             : #include <string>
+      27             : #include <cmath>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace multicolvar {
+      31             : 
+      32             : //+PLUMEDOC MCOLVAR XYDISTANCES
+      33             : /*
+      34             : Calculate distance between a pair of atoms neglecting the z-component.
+      35             : 
+      36             : You can then calculate functions of the distribution of values such as the minimum, the number less than a certain quantity and so on.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : The following input tells plumed to calculate the projection of the length of the vector connecting atom 3
+      41             : to atom 5 projected in the xy-plane and the projection of the length of the vector
+      42             : the vector connecting atom 1 to atom 2 in the xy-plane.  The minimum of these two quantities is then
+      43             : printed
+      44             : \plumedfile
+      45             : d1: XYDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
+      46             : PRINT ARG=d1.min
+      47             : \endplumedfile
+      48             : (See also \ref PRINT).
+      49             : 
+      50             : */
+      51             : //+ENDPLUMEDOC
+      52             : 
+      53             : //+PLUMEDOC MCOLVAR XZDISTANCES
+      54             : /*
+      55             : Calculate distance between a pair of atoms neglecting the y-component.
+      56             : 
+      57             : You can then calculate functions of the distribution of
+      58             : values such as the minimum, the number less than a certain quantity and so on.
+      59             : 
+      60             : \par Examples
+      61             : 
+      62             : The following input tells plumed to calculate the projection of the length of the vector connecting atom 3
+      63             : to atom 5 projected in the xz-plane and the projection of the length of the vector
+      64             : the vector connecting atom 1 to atom 2 in the xz-plane.  The minimum of these two quantities is then
+      65             : printed
+      66             : \plumedfile
+      67             : d1: XZDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
+      68             : PRINT ARG=d1.min
+      69             : \endplumedfile
+      70             : (See also \ref PRINT).
+      71             : 
+      72             : */
+      73             : //+ENDPLUMEDOC
+      74             : 
+      75             : //+PLUMEDOC MCOLVAR YZDISTANCES
+      76             : /*
+      77             : Calculate distance between a pair of atoms neglecting the x-component.
+      78             : 
+      79             : You can then calculate functions of the distribution of
+      80             : values such as the minimum, the number less than a certain quantity and so on.
+      81             : 
+      82             : \par Examples
+      83             : 
+      84             : The following input tells plumed to calculate the projection of the length of the vector connecting atom 3
+      85             : to atom 5 in the yz-plane and the projection of the length of the vector
+      86             : the vector connecting atom 1 to atom 2 in the yz-plane.  The minimum of these two quantities is then
+      87             : printed
+      88             : \plumedfile
+      89             : d1: YZDISTANCES ATOMS1=3,5 ATOMS2=1,2 MIN={BETA=0.1}
+      90             : PRINT ARG=d1.min
+      91             : \endplumedfile
+      92             : (See also \ref PRINT).
+      93             : 
+      94             : */
+      95             : //+ENDPLUMEDOC
+      96             : 
+      97             : 
+      98             : class XYDistances : public MultiColvarBase {
+      99             : private:
+     100             :   unsigned myc1, myc2;
+     101             : public:
+     102             :   static void registerKeywords( Keywords& keys );
+     103             :   explicit XYDistances(const ActionOptions&);
+     104             : // active methods:
+     105             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+     106             : /// Returns the number of coordinates of the field
+     107           0 :   bool isPeriodic() override { return false; }
+     108             : };
+     109             : 
+     110             : PLUMED_REGISTER_ACTION(XYDistances,"XYDISTANCES")
+     111             : PLUMED_REGISTER_ACTION(XYDistances,"XZDISTANCES")
+     112             : PLUMED_REGISTER_ACTION(XYDistances,"YZDISTANCES")
+     113             : 
+     114           6 : void XYDistances::registerKeywords( Keywords& keys ) {
+     115           6 :   MultiColvarBase::registerKeywords( keys );
+     116          12 :   keys.use("MAX"); keys.use("ALT_MIN");
+     117          30 :   keys.use("MEAN"); keys.use("MIN"); keys.use("LESS_THAN"); keys.use("LOWEST"); keys.use("HIGHEST");
+     118          24 :   keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     119          12 :   keys.add("numbered","ATOMS","the atoms involved in each of the distances you wish to calculate. "
+     120             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one distance will be "
+     121             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     122             :            "specify the indices of two atoms).  The eventual number of quantities calculated by this "
+     123             :            "action will depend on what functions of the distribution you choose to calculate.");
+     124          12 :   keys.reset_style("ATOMS","atoms");
+     125          12 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     126          12 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+     127             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+     128          12 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+     129             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+     130           6 : }
+     131             : 
+     132           0 : XYDistances::XYDistances(const ActionOptions&ao):
+     133             :   Action(ao),
+     134           0 :   MultiColvarBase(ao)
+     135             : {
+     136           0 :   if( getName().find("XY")!=std::string::npos) {
+     137           0 :     myc1=0; myc2=1;
+     138           0 :   } else if( getName().find("XZ")!=std::string::npos) {
+     139           0 :     myc1=0; myc2=2;
+     140           0 :   } else if( getName().find("YZ")!=std::string::npos) {
+     141           0 :     myc1=1; myc2=2;
+     142           0 :   } else plumed_error();
+     143             : 
+     144             :   // Read in the atoms
+     145             :   std::vector<AtomNumber> all_atoms;
+     146           0 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     147           0 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+     148           0 :   setupMultiColvarBase( all_atoms );
+     149             :   // And check everything has been read in correctly
+     150           0 :   checkRead();
+     151           0 : }
+     152             : 
+     153           0 : double XYDistances::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     154           0 :   Vector distance;
+     155           0 :   distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     156           0 :   const double value=std::sqrt(distance[myc1]*distance[myc1] + distance[myc2]*distance[myc2] );
+     157           0 :   const double invvalue=1.0/value;
+     158             : 
+     159           0 :   Vector myvec; myvec.zero();
+     160             :   // And finish the calculation
+     161           0 :   myvec[myc1]=+invvalue*distance[myc1]; myvec[myc2]=+invvalue*distance[myc2]; addAtomDerivatives( 1, 1, myvec, myatoms  );
+     162           0 :   myvec[myc1]=-invvalue*distance[myc1]; myvec[myc2]=-invvalue*distance[myc2]; addAtomDerivatives( 1, 0, myvec, myatoms );
+     163           0 :   myatoms.addBoxDerivatives( 1, Tensor(distance,myvec) );
+     164           0 :   return value;
+     165             : }
+     166             : 
+     167             : }
+     168             : }
+     169             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYTorsion.cpp.func-sort-c.html b/coverage/multicolvar/XYTorsion.cpp.func-sort-c.html new file mode 100644 index 000000000000..e67a07e8d617 --- /dev/null +++ b/coverage/multicolvar/XYTorsion.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XYTorsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XYTorsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525398.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9XYTorsionC2ERKNS_13ActionOptionsE0
_ZN4PLMD11multicolvar9XYTorsion14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1
_ZN4PLMD11multicolvar9XYTorsion10isPeriodicEv3
_ZN4PLMD11multicolvar9XYTorsionC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar9XYTorsion16registerKeywordsERNS_8KeywordsE15
_ZNK4PLMD11multicolvar9XYTorsion7computeERKjRNS0_13AtomValuePackE50
_ZNK4PLMD11multicolvar9XYTorsion15calculateWeightERKjRKdRNS0_13AtomValuePackE110
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYTorsion.cpp.func.html b/coverage/multicolvar/XYTorsion.cpp.func.html new file mode 100644 index 000000000000..3e80f984cc98 --- /dev/null +++ b/coverage/multicolvar/XYTorsion.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XYTorsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XYTorsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525398.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11multicolvar9XYTorsion10isPeriodicEv3
_ZN4PLMD11multicolvar9XYTorsion14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1
_ZN4PLMD11multicolvar9XYTorsion16registerKeywordsERNS_8KeywordsE15
_ZN4PLMD11multicolvar9XYTorsionC1ERKNS_13ActionOptionsE3
_ZN4PLMD11multicolvar9XYTorsionC2ERKNS_13ActionOptionsE0
_ZNK4PLMD11multicolvar9XYTorsion15calculateWeightERKjRKdRNS0_13AtomValuePackE110
_ZNK4PLMD11multicolvar9XYTorsion7computeERKjRNS0_13AtomValuePackE50
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/XYTorsion.cpp.gcov.html b/coverage/multicolvar/XYTorsion.cpp.gcov.html new file mode 100644 index 000000000000..cb270cd892ed --- /dev/null +++ b/coverage/multicolvar/XYTorsion.cpp.gcov.html @@ -0,0 +1,311 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar/XYTorsion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvar - XYTorsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525398.1 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiColvarBase.h"
+      23             : #include "AtomValuePack.h"
+      24             : #include "core/ActionRegister.h"
+      25             : #include "tools/Torsion.h"
+      26             : #include "tools/SwitchingFunction.h"
+      27             : 
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace multicolvar {
+      33             : 
+      34             : //+PLUMEDOC MCOLVAR XYTORSIONS
+      35             : /*
+      36             : Calculate the torsional angle around the x axis from the positive y direction.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : The following input tells plumed to calculate the angle around the x direction between the positive y-axis and the vector connecting atom 3 to atom 5 and
+      41             : the angle around the x direction between the positive y axis and the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then output
+      42             : \plumedfile
+      43             : d1: XYTORSIONS ATOMS1=3,5 ATOMS2=1,2 BETWEEN={GAUSSIAN LOWER=0 UPPER=pi SMEAR=0.1}
+      44             : PRINT ARG=d1.between
+      45             : \endplumedfile
+      46             : (See also \ref PRINT).
+      47             : */
+      48             : //+ENDPLUMEDOC
+      49             : 
+      50             : //+PLUMEDOC MCOLVAR XZTORSIONS
+      51             : /*
+      52             : Calculate the torsional angle around the x axis from the positive z direction.
+      53             : 
+      54             : \par Examples
+      55             : 
+      56             : The following input tells plumed to calculate the angle around the x direction between the positive z-axis and the vector connecting atom 3 to atom 5 and
+      57             : the angle around the x direction between the positive z direction and the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then output
+      58             : \plumedfile
+      59             : d1: XZTORSIONS ATOMS1=3,5 ATOMS2=1,2 BETWEEN={GAUSSIAN LOWER=0 UPPER=pi SMEAR=0.1}
+      60             : PRINT ARG=d1.*
+      61             : \endplumedfile
+      62             : (See also \ref PRINT).
+      63             : */
+      64             : //+ENDPLUMEDOC
+      65             : 
+      66             : //+PLUMEDOC MCOLVAR YXTORSIONS
+      67             : /*
+      68             : Calculate the torsional angle around the y axis from the positive x direction.
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : The following input tells plumed to calculate the angle around the y direction between the positive x-direction and the vector connecting atom 3 to atom 5 and
+      73             : the angle around the y direction between the positive x axis and the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then output
+      74             : \plumedfile
+      75             : d1: YXTORSIONS ATOMS1=3,5 ATOMS2=1,2 BETWEEN={GAUSSIAN LOWER=0 UPPER=pi SMEAR=0.1}
+      76             : PRINT ARG=d1.*
+      77             : \endplumedfile
+      78             : (See also \ref PRINT).
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : 
+      82             : //+PLUMEDOC MCOLVAR YZTORSIONS
+      83             : /*
+      84             : Calculate the torsional angle around the y axis from the positive z direction.
+      85             : 
+      86             : \par Examples
+      87             : 
+      88             : The following input tells plumed to calculate the angle around the y direction between the positive z-direction and the vector connecting atom 3 to atom 5 and
+      89             : the angle around the y direction between the positive z direction and the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then output
+      90             : \plumedfile
+      91             : d1: YZTORSIONS ATOMS1=3,5 ATOMS2=1,2 BETWEEN={GAUSSIAN LOWER=0 UPPER=pi SMEAR=0.1}
+      92             : PRINT ARG=d1.*
+      93             : \endplumedfile
+      94             : (See also \ref PRINT).
+      95             : */
+      96             : //+ENDPLUMEDOC
+      97             : 
+      98             : //+PLUMEDOC MCOLVAR ZXTORSIONS
+      99             : /*
+     100             : Calculate the torsional angle around the z axis from the positive x direction.
+     101             : 
+     102             : \par Examples
+     103             : 
+     104             : The following input tells plumed to calculate the angle around the z direction between the positive x-direction and the vector connecting atom 3 to atom 5 and
+     105             : the angle around the z direction between the positive x-direction and the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then output
+     106             : \plumedfile
+     107             : d1: ZXTORSIONS ATOMS1=3,5 ATOMS2=1,2 BETWEEN={GAUSSIAN LOWER=0 UPPER=pi SMEAR=0.1}
+     108             : PRINT ARG=d1.*
+     109             : \endplumedfile
+     110             : (See also \ref PRINT).
+     111             : */
+     112             : //+ENDPLUMEDOC
+     113             : 
+     114             : //+PLUMEDOC MCOLVAR ZYTORSIONS
+     115             : /*
+     116             : Calculate the torsional angle around the z axis from the positive y direction.
+     117             : 
+     118             : \par Examples
+     119             : 
+     120             : The following input tells plumed to calculate the angle around the z direction between the positive y-axis and the vector connecting atom 3 to atom 5 and
+     121             : the angle around the z direction between the positive y axis and the vector connecting atom 1 to atom 2.  The minimum of these two quantities is then output
+     122             : \plumedfile
+     123             : d1: ZYTORSIONS ATOMS1=3,5 ATOMS2=1,2 BETWEEN={GAUSSIAN LOWER=0 UPPER=pi SMEAR=0.1}
+     124             : PRINT ARG=d1.*
+     125             : \endplumedfile
+     126             : (See also \ref PRINT).
+     127             : */
+     128             : //+ENDPLUMEDOC
+     129             : 
+     130             : 
+     131             : 
+     132             : 
+     133             : class XYTorsion : public MultiColvarBase {
+     134             : private:
+     135             :   bool use_sf;
+     136             :   unsigned myc1, myc2;
+     137             :   SwitchingFunction sf1;
+     138             : public:
+     139             :   static void registerKeywords( Keywords& keys );
+     140             :   explicit XYTorsion(const ActionOptions&);
+     141             : // active methods:
+     142             :   double compute( const unsigned& tindex, AtomValuePack& myatoms ) const override;
+     143             :   double calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& ) const override;
+     144             : /// Returns the number of coordinates of the field
+     145           3 :   bool isPeriodic() override { return true; }
+     146           1 :   void retrieveDomain( std::string& min, std::string& max) override { min="-pi"; max="pi"; }
+     147             : };
+     148             : 
+     149             : PLUMED_REGISTER_ACTION(XYTorsion,"XYTORSIONS")
+     150             : PLUMED_REGISTER_ACTION(XYTorsion,"XZTORSIONS")
+     151             : PLUMED_REGISTER_ACTION(XYTorsion,"YXTORSIONS")
+     152             : PLUMED_REGISTER_ACTION(XYTorsion,"YZTORSIONS")
+     153             : PLUMED_REGISTER_ACTION(XYTorsion,"ZXTORSIONS")
+     154             : PLUMED_REGISTER_ACTION(XYTorsion,"ZYTORSIONS")
+     155             : 
+     156          15 : void XYTorsion::registerKeywords( Keywords& keys ) {
+     157          15 :   MultiColvarBase::registerKeywords( keys );
+     158          30 :   keys.use("MAX"); keys.use("ALT_MIN");
+     159          30 :   keys.use("MEAN"); keys.use("MIN");
+     160          30 :   keys.use("LOWEST"); keys.use("HIGHEST");
+     161          45 :   keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+     162          30 :   keys.add("numbered","ATOMS","the atoms involved in each of the torsion angles you wish to calculate. "
+     163             :            "Keywords like ATOMS1, ATOMS2, ATOMS3,... should be listed and one torsion will be "
+     164             :            "calculated for each ATOM keyword you specify (all ATOM keywords should "
+     165             :            "specify the indices of two atoms).  The eventual number of quantities calculated by this "
+     166             :            "action will depend on what functions of the distribution you choose to calculate.");
+     167          30 :   keys.reset_style("ATOMS","atoms");
+     168          30 :   keys.add("atoms-1","GROUP","Calculate the distance between each distinct pair of atoms in the group");
+     169          30 :   keys.add("atoms-2","GROUPA","Calculate the distances between all the atoms in GROUPA and all "
+     170             :            "the atoms in GROUPB. This must be used in conjunction with GROUPB.");
+     171          30 :   keys.add("atoms-2","GROUPB","Calculate the distances between all the atoms in GROUPA and all the atoms "
+     172             :            "in GROUPB. This must be used in conjunction with GROUPA.");
+     173          30 :   keys.add("optional","SWITCH","A switching function that ensures that only angles are only computed when atoms are within "
+     174             :            "are within a certain fixed cutoff. The following provides information on the \\ref switchingfunction that are available.");
+     175          15 : }
+     176             : 
+     177           3 : XYTorsion::XYTorsion(const ActionOptions&ao):
+     178             :   Action(ao),
+     179             :   MultiColvarBase(ao),
+     180           3 :   use_sf(false)
+     181             : {
+     182           3 :   if( getName().find("XY")!=std::string::npos) { myc1=0; myc2=1; }
+     183           3 :   else if( getName().find("XZ")!=std::string::npos) { myc1=0; myc2=2; }
+     184           3 :   else if( getName().find("YX")!=std::string::npos) { myc1=1; myc2=0; }
+     185           3 :   else if( getName().find("YZ")!=std::string::npos) { myc1=1; myc2=2; }
+     186           3 :   else if( getName().find("ZX")!=std::string::npos) { myc1=2; myc2=0; }
+     187           1 :   else if( getName().find("ZY")!=std::string::npos) { myc1=2; myc2=1; }
+     188           0 :   else plumed_error();
+     189             : 
+     190             :   // Read in switching function
+     191           6 :   std::string sfinput, errors; parse("SWITCH",sfinput);
+     192           3 :   if( sfinput.length()>0 ) {
+     193           2 :     use_sf=true; weightHasDerivatives=true;
+     194           2 :     sf1.set(sfinput,errors);
+     195           2 :     if( errors.length()!=0 ) error("problem reading SWITCH keyword : " + errors );
+     196           2 :     log.printf("  only calculating angles for atoms separated by less than %s\n", sf1.description().c_str() );
+     197           2 :     setLinkCellCutoff( sf1.get_dmax() );
+     198             :   }
+     199             : 
+     200             :   // Read in the atoms
+     201             :   std::vector<AtomNumber> all_atoms;
+     202           6 :   readTwoGroups( "GROUP", "GROUPA", "GROUPB", all_atoms );
+     203           4 :   if( atom_lab.size()==0 ) readAtomsLikeKeyword( "ATOMS", 2, all_atoms );
+     204           3 :   setupMultiColvarBase( all_atoms );
+     205             :   // And check everything has been read in correctly
+     206           3 :   checkRead();
+     207           3 : }
+     208             : 
+     209         110 : double XYTorsion::calculateWeight( const unsigned& taskCode, const double& weight, AtomValuePack& myatoms ) const {
+     210         110 :   if(!use_sf) return 1.0;
+     211             : 
+     212         100 :   Vector distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     213         100 :   double dw, w = sf1.calculateSqr( distance.modulo2(), dw );
+     214         100 :   addAtomDerivatives( 0, 0, (-dw)*distance, myatoms );
+     215         100 :   addAtomDerivatives( 0, 1, (+dw)*distance, myatoms );
+     216         100 :   myatoms.addBoxDerivatives( 0, (-dw)*Tensor(distance,distance) );
+     217         100 :   return w;
+     218             : }
+     219             : 
+     220          50 : double XYTorsion::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
+     221          50 :   Vector dd0, dd1, dd2, axis, rot, distance;
+     222          50 :   axis.zero(); rot.zero(); rot[myc1]=1; axis[myc2]=1;
+     223          50 :   distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
+     224          50 :   PLMD::Torsion t; double torsion=t.compute( distance, rot, axis, dd0, dd1, dd2 );
+     225             : 
+     226          50 :   addAtomDerivatives( 1, 0, -dd0, myatoms );
+     227          50 :   addAtomDerivatives( 1, 1, dd0, myatoms );
+     228          50 :   myatoms.addBoxDerivatives( 1, -extProduct(distance,dd0) );
+     229          50 :   return torsion;
+     230             : }
+     231             : 
+     232             : }
+     233             : }
+     234             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/index-sort-f.html b/coverage/multicolvar/index-sort-f.html new file mode 100644 index 000000000000..ab01a1a10d5e --- /dev/null +++ b/coverage/multicolvar/index-sort-f.html @@ -0,0 +1,524 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:2353298378.9 %
Date:2024-02-22 21:58:45Functions:21629074.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
VolumeTetrapore.cpp +
3.0%3.0%
+
3.0 %7 / 23111.1 %1 / 9
XYDistances.cpp +
30.6%30.6%
+
30.6 %11 / 3620.0 %1 / 5
InPlaneDistances.cpp +
19.6%19.6%
+
19.6 %9 / 4620.0 %1 / 5
VolumeBetweenContours.cpp +
12.2%12.2%
+
12.2 %6 / 4920.0 %1 / 5
Density.cpp +
69.6%69.6%
+
69.6 %16 / 2355.6 %5 / 9
BridgedMultiColvarFunction.h +
52.2%52.2%
+
52.2 %12 / 2358.3 %7 / 12
AlphaBeta.cpp +
87.7%87.7%
+
87.7 %50 / 5760.0 %3 / 5
Bridge.cpp +
78.8%78.8%
+
78.8 %41 / 5260.0 %3 / 5
DihedralCorrelation.cpp +
98.0%98.0%
+
98.0 %48 / 4960.0 %3 / 5
NumberOfLinks.cpp +
89.3%89.3%
+
89.3 %50 / 5666.7 %4 / 6
MultiColvarFilter.cpp +
82.5%82.5%
+
82.5 %33 / 4066.7 %4 / 6
DumpMultiColvar.cpp +
93.0%93.0%
+
93.0 %66 / 7170.0 %7 / 10
LocalAverage.cpp +
79.1%79.1%
+
79.1 %106 / 13471.4 %5 / 7
CenterOfMultiColvar.cpp +
96.3%96.3%
+
96.3 %78 / 8175.0 %3 / 4
FilterMoreThan.cpp +
80.0%80.0%
+
80.0 %20 / 2575.0 %3 / 4
FilterLessThan.cpp +
80.0%80.0%
+
80.0 %20 / 2575.0 %3 / 4
FilterBetween.cpp +
81.5%81.5%
+
81.5 %22 / 2775.0 %3 / 4
VolumeGradientBase.cpp +
78.9%78.9%
+
78.9 %45 / 5775.0 %6 / 8
VolumeCavity.cpp +
79.3%79.3%
+
79.3 %169 / 21377.8 %7 / 9
MultiColvarDensity.cpp +
83.3%83.3%
+
83.3 %115 / 13877.8 %7 / 9
CoordinationNumbers.cpp +
100.0%
+
100.0 %49 / 4980.0 %4 / 5
VolumeInCylinder.cpp +
95.8%95.8%
+
95.8 %46 / 4880.0 %4 / 5
Distances.cpp +
95.5%95.5%
+
95.5 %42 / 4480.0 %4 / 5
XDistances.cpp +
90.9%90.9%
+
90.9 %30 / 3380.0 %4 / 5
MultiColvarProduct.cpp +
100.0%
+
100.0 %25 / 2580.0 %4 / 5
ActionVolume.cpp +
100.0%
+
100.0 %39 / 3980.0 %4 / 5
VolumeAround.cpp +
100.0%
+
100.0 %47 / 4780.0 %4 / 5
MultiColvarCombine.cpp +
100.0%
+
100.0 %30 / 3080.0 %4 / 5
VolumeInSphere.cpp +
100.0%
+
100.0 %25 / 2580.0 %4 / 5
MultiColvarBase.h +
85.2%85.2%
+
85.2 %23 / 2780.0 %8 / 10
DistanceFromContour.cpp +
86.2%86.2%
+
86.2 %131 / 15280.0 %8 / 10
BridgedMultiColvarFunction.cpp +
92.9%92.9%
+
92.9 %52 / 5681.8 %9 / 11
Torsions.cpp +
100.0%
+
100.0 %32 / 3283.3 %5 / 6
Angles.cpp +
83.8%83.8%
+
83.8 %62 / 7483.3 %5 / 6
XAngle.cpp +
97.9%97.9%
+
97.9 %47 / 4883.3 %5 / 6
XYTorsion.cpp +
98.1%98.1%
+
98.1 %52 / 5385.7 %6 / 7
MultiColvarBase.cpp +
89.4%89.4%
+
89.4 %583 / 65297.6 %40 / 41
MultiColvarFilter.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
CatomPack.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
ActionVolume.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
VolumeGradientBase.h +
100.0%
+
100.0 %8 / 8100.0 %1 / 1
CatomPack.h +
100.0%
+
100.0 %9 / 9100.0 %2 / 2
AtomValuePack.cpp +
100.0%
+
100.0 %49 / 49100.0 %4 / 4
AtomValuePack.h +
95.1%95.1%
+
95.1 %39 / 41100.0 %7 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/index-sort-l.html b/coverage/multicolvar/index-sort-l.html new file mode 100644 index 000000000000..306468d2a51d --- /dev/null +++ b/coverage/multicolvar/index-sort-l.html @@ -0,0 +1,524 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:2353298378.9 %
Date:2024-02-22 21:58:45Functions:21629074.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
VolumeTetrapore.cpp +
3.0%3.0%
+
3.0 %7 / 23111.1 %1 / 9
VolumeBetweenContours.cpp +
12.2%12.2%
+
12.2 %6 / 4920.0 %1 / 5
InPlaneDistances.cpp +
19.6%19.6%
+
19.6 %9 / 4620.0 %1 / 5
XYDistances.cpp +
30.6%30.6%
+
30.6 %11 / 3620.0 %1 / 5
BridgedMultiColvarFunction.h +
52.2%52.2%
+
52.2 %12 / 2358.3 %7 / 12
Density.cpp +
69.6%69.6%
+
69.6 %16 / 2355.6 %5 / 9
Bridge.cpp +
78.8%78.8%
+
78.8 %41 / 5260.0 %3 / 5
VolumeGradientBase.cpp +
78.9%78.9%
+
78.9 %45 / 5775.0 %6 / 8
LocalAverage.cpp +
79.1%79.1%
+
79.1 %106 / 13471.4 %5 / 7
VolumeCavity.cpp +
79.3%79.3%
+
79.3 %169 / 21377.8 %7 / 9
FilterMoreThan.cpp +
80.0%80.0%
+
80.0 %20 / 2575.0 %3 / 4
FilterLessThan.cpp +
80.0%80.0%
+
80.0 %20 / 2575.0 %3 / 4
FilterBetween.cpp +
81.5%81.5%
+
81.5 %22 / 2775.0 %3 / 4
MultiColvarFilter.cpp +
82.5%82.5%
+
82.5 %33 / 4066.7 %4 / 6
MultiColvarDensity.cpp +
83.3%83.3%
+
83.3 %115 / 13877.8 %7 / 9
Angles.cpp +
83.8%83.8%
+
83.8 %62 / 7483.3 %5 / 6
MultiColvarBase.h +
85.2%85.2%
+
85.2 %23 / 2780.0 %8 / 10
DistanceFromContour.cpp +
86.2%86.2%
+
86.2 %131 / 15280.0 %8 / 10
AlphaBeta.cpp +
87.7%87.7%
+
87.7 %50 / 5760.0 %3 / 5
NumberOfLinks.cpp +
89.3%89.3%
+
89.3 %50 / 5666.7 %4 / 6
MultiColvarBase.cpp +
89.4%89.4%
+
89.4 %583 / 65297.6 %40 / 41
XDistances.cpp +
90.9%90.9%
+
90.9 %30 / 3380.0 %4 / 5
BridgedMultiColvarFunction.cpp +
92.9%92.9%
+
92.9 %52 / 5681.8 %9 / 11
DumpMultiColvar.cpp +
93.0%93.0%
+
93.0 %66 / 7170.0 %7 / 10
AtomValuePack.h +
95.1%95.1%
+
95.1 %39 / 41100.0 %7 / 7
Distances.cpp +
95.5%95.5%
+
95.5 %42 / 4480.0 %4 / 5
VolumeInCylinder.cpp +
95.8%95.8%
+
95.8 %46 / 4880.0 %4 / 5
CenterOfMultiColvar.cpp +
96.3%96.3%
+
96.3 %78 / 8175.0 %3 / 4
XAngle.cpp +
97.9%97.9%
+
97.9 %47 / 4883.3 %5 / 6
DihedralCorrelation.cpp +
98.0%98.0%
+
98.0 %48 / 4960.0 %3 / 5
XYTorsion.cpp +
98.1%98.1%
+
98.1 %52 / 5385.7 %6 / 7
MultiColvarFilter.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
CatomPack.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
ActionVolume.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
VolumeGradientBase.h +
100.0%
+
100.0 %8 / 8100.0 %1 / 1
CatomPack.h +
100.0%
+
100.0 %9 / 9100.0 %2 / 2
MultiColvarProduct.cpp +
100.0%
+
100.0 %25 / 2580.0 %4 / 5
VolumeInSphere.cpp +
100.0%
+
100.0 %25 / 2580.0 %4 / 5
MultiColvarCombine.cpp +
100.0%
+
100.0 %30 / 3080.0 %4 / 5
Torsions.cpp +
100.0%
+
100.0 %32 / 3283.3 %5 / 6
ActionVolume.cpp +
100.0%
+
100.0 %39 / 3980.0 %4 / 5
VolumeAround.cpp +
100.0%
+
100.0 %47 / 4780.0 %4 / 5
CoordinationNumbers.cpp +
100.0%
+
100.0 %49 / 4980.0 %4 / 5
AtomValuePack.cpp +
100.0%
+
100.0 %49 / 49100.0 %4 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/multicolvar/index.html b/coverage/multicolvar/index.html new file mode 100644 index 000000000000..9ba0bc578d55 --- /dev/null +++ b/coverage/multicolvar/index.html @@ -0,0 +1,524 @@ + + + + + + + + LCOV - plumed test coverage - multicolvar + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - multicolvarHitTotalCoverage
Test:plumed test coverageLines:2353298378.9 %
Date:2024-02-22 21:58:45Functions:21629074.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionVolume.cpp +
100.0%
+
100.0 %39 / 3980.0 %4 / 5
ActionVolume.h +
100.0%
+
100.0 %4 / 4100.0 %1 / 1
AlphaBeta.cpp +
87.7%87.7%
+
87.7 %50 / 5760.0 %3 / 5
Angles.cpp +
83.8%83.8%
+
83.8 %62 / 7483.3 %5 / 6
AtomValuePack.cpp +
100.0%
+
100.0 %49 / 49100.0 %4 / 4
AtomValuePack.h +
95.1%95.1%
+
95.1 %39 / 41100.0 %7 / 7
Bridge.cpp +
78.8%78.8%
+
78.8 %41 / 5260.0 %3 / 5
BridgedMultiColvarFunction.cpp +
92.9%92.9%
+
92.9 %52 / 5681.8 %9 / 11
BridgedMultiColvarFunction.h +
52.2%52.2%
+
52.2 %12 / 2358.3 %7 / 12
CatomPack.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
CatomPack.h +
100.0%
+
100.0 %9 / 9100.0 %2 / 2
CenterOfMultiColvar.cpp +
96.3%96.3%
+
96.3 %78 / 8175.0 %3 / 4
CoordinationNumbers.cpp +
100.0%
+
100.0 %49 / 4980.0 %4 / 5
Density.cpp +
69.6%69.6%
+
69.6 %16 / 2355.6 %5 / 9
DihedralCorrelation.cpp +
98.0%98.0%
+
98.0 %48 / 4960.0 %3 / 5
DistanceFromContour.cpp +
86.2%86.2%
+
86.2 %131 / 15280.0 %8 / 10
Distances.cpp +
95.5%95.5%
+
95.5 %42 / 4480.0 %4 / 5
DumpMultiColvar.cpp +
93.0%93.0%
+
93.0 %66 / 7170.0 %7 / 10
FilterBetween.cpp +
81.5%81.5%
+
81.5 %22 / 2775.0 %3 / 4
FilterLessThan.cpp +
80.0%80.0%
+
80.0 %20 / 2575.0 %3 / 4
FilterMoreThan.cpp +
80.0%80.0%
+
80.0 %20 / 2575.0 %3 / 4
InPlaneDistances.cpp +
19.6%19.6%
+
19.6 %9 / 4620.0 %1 / 5
LocalAverage.cpp +
79.1%79.1%
+
79.1 %106 / 13471.4 %5 / 7
MultiColvarBase.cpp +
89.4%89.4%
+
89.4 %583 / 65297.6 %40 / 41
MultiColvarBase.h +
85.2%85.2%
+
85.2 %23 / 2780.0 %8 / 10
MultiColvarCombine.cpp +
100.0%
+
100.0 %30 / 3080.0 %4 / 5
MultiColvarDensity.cpp +
83.3%83.3%
+
83.3 %115 / 13877.8 %7 / 9
MultiColvarFilter.cpp +
82.5%82.5%
+
82.5 %33 / 4066.7 %4 / 6
MultiColvarFilter.h +
100.0%
+
100.0 %2 / 2100.0 %1 / 1
MultiColvarProduct.cpp +
100.0%
+
100.0 %25 / 2580.0 %4 / 5
NumberOfLinks.cpp +
89.3%89.3%
+
89.3 %50 / 5666.7 %4 / 6
Torsions.cpp +
100.0%
+
100.0 %32 / 3283.3 %5 / 6
VolumeAround.cpp +
100.0%
+
100.0 %47 / 4780.0 %4 / 5
VolumeBetweenContours.cpp +
12.2%12.2%
+
12.2 %6 / 4920.0 %1 / 5
VolumeCavity.cpp +
79.3%79.3%
+
79.3 %169 / 21377.8 %7 / 9
VolumeGradientBase.cpp +
78.9%78.9%
+
78.9 %45 / 5775.0 %6 / 8
VolumeGradientBase.h +
100.0%
+
100.0 %8 / 8100.0 %1 / 1
VolumeInCylinder.cpp +
95.8%95.8%
+
95.8 %46 / 4880.0 %4 / 5
VolumeInSphere.cpp +
100.0%
+
100.0 %25 / 2580.0 %4 / 5
VolumeTetrapore.cpp +
3.0%3.0%
+
3.0 %7 / 23111.1 %1 / 9
XAngle.cpp +
97.9%97.9%
+
97.9 %47 / 4883.3 %5 / 6
XDistances.cpp +
90.9%90.9%
+
90.9 %30 / 3380.0 %4 / 5
XYDistances.cpp +
30.6%30.6%
+
30.6 %11 / 3620.0 %1 / 5
XYTorsion.cpp +
98.1%98.1%
+
98.1 %52 / 5385.7 %6 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVcustom.cpp.func-sort-c.html b/coverage/opes/ECVcustom.cpp.func-sort-c.html new file mode 100644 index 000000000000..8cb61b707b35 --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVcustom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVcustom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9210092.0 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9ECVcustomC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes9ECVcustom15initECVs_observERKSt6vectorIdSaIdEEjj1
_ZN4PLMD4opes9ECVcustom16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVcustom8initECVsEv2
_ZN4PLMD4opes9ECVcustomC1ERKNS_13ActionOptionsE2
_ZNK4PLMD4opes9ECVcustom10getIndex_kEv2
_ZNK4PLMD4opes9ECVcustom10getLambdasB5cxx11Ev2
_ZN4PLMD4opes9ECVcustom13getPntrToECVsEj4
_ZN4PLMD4opes9ECVcustom16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVcustom16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4opes9ECVcustom13calculateECVsEPKd91
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVcustom.cpp.func.html b/coverage/opes/ECVcustom.cpp.func.html new file mode 100644 index 000000000000..9d938dfc540c --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVcustom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVcustom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9210092.0 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9ECVcustom13calculateECVsEPKd91
_ZN4PLMD4opes9ECVcustom13getPntrToECVsEj4
_ZN4PLMD4opes9ECVcustom15initECVs_observERKSt6vectorIdSaIdEEjj1
_ZN4PLMD4opes9ECVcustom16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVcustom16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVcustom16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4opes9ECVcustom8initECVsEv2
_ZN4PLMD4opes9ECVcustomC1ERKNS_13ActionOptionsE2
_ZN4PLMD4opes9ECVcustomC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes9ECVcustom10getIndex_kEv2
_ZNK4PLMD4opes9ECVcustom10getLambdasB5cxx11Ev2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVcustom.cpp.gcov.html b/coverage/opes/ECVcustom.cpp.gcov.html new file mode 100644 index 000000000000..33fbeda49373 --- /dev/null +++ b/coverage/opes/ECVcustom.cpp.gcov.html @@ -0,0 +1,315 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVcustom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVcustom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9210092.0 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : 
+      22             : namespace PLMD {
+      23             : namespace opes {
+      24             : 
+      25             : //+PLUMEDOC OPES_EXPANSION_CV ECV_CUSTOM
+      26             : /*
+      27             : Use some given CVs as a set of expansion collective variables (ECVs).
+      28             : 
+      29             : This can be useful e.g. for quickly testing new ECVs, but from a performance point of view it is probably better to implement a new ECV class.
+      30             : 
+      31             : By default the ARGs are expeted to be energies, \f$\Delta U_i\f$, and are then multiplied by the inverse temperature \f$\beta\f$
+      32             : \f[
+      33             :   \Delta u_i=\beta \Delta U_i\, .
+      34             : \f]
+      35             : Use the DIMENSIONLESS flag to avoid this multiplication.
+      36             : 
+      37             : The flag ADD_P0 adds also the unbiased distribution to the target.
+      38             : It is possible to specify a BARRIER as in \ref ECV_UMBRELLAS_LINE, to avoid a too high initial bias.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : \plumedfile
+      43             : ene: ENERGY
+      44             : t1: CUSTOM PERIODIC=NO ARG=ene FUNC=(300/500-1)*x
+      45             : t2: CUSTOM PERIODIC=NO ARG=ene FUNC=(300/1000-1)*x
+      46             : ecv: ECV_CUSTOM ARG=t1,t2 TEMP=300 ADD_P0
+      47             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      48             : \endplumedfile
+      49             : 
+      50             : It is equivalent to the following:
+      51             : 
+      52             : \plumedfile
+      53             : ene: ENERGY
+      54             : ecv: ECV_MULTITHERMAL ARG=ene TEMP=300 TEMP_SET_ALL=300,500,1000
+      55             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      56             : \endplumedfile
+      57             : 
+      58             : */
+      59             : //+ENDPLUMEDOC
+      60             : 
+      61             : class ECVcustom :
+      62             :   public ExpansionCVs
+      63             : {
+      64             : private:
+      65             :   unsigned P0_contribution_;
+      66             :   double barrier_;
+      67             :   double beta0_;
+      68             : 
+      69             :   std::vector< std::vector<double> > ECVs_;
+      70             :   std::vector< std::vector<double> > derECVs_;
+      71             :   void initECVs();
+      72             : 
+      73             : public:
+      74             :   explicit ECVcustom(const ActionOptions&);
+      75             :   static void registerKeywords(Keywords& keys);
+      76             :   void calculateECVs(const double *) override;
+      77             :   const double * getPntrToECVs(unsigned) override;
+      78             :   const double * getPntrToDerECVs(unsigned) override;
+      79             :   std::vector< std::vector<unsigned> > getIndex_k() const override;
+      80             :   std::vector<std::string> getLambdas() const override;
+      81             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+      82             :   void initECVs_restart(const std::vector<std::string>&) override;
+      83             : };
+      84             : 
+      85             : PLUMED_REGISTER_ACTION(ECVcustom,"ECV_CUSTOM")
+      86             : 
+      87           4 : void ECVcustom::registerKeywords(Keywords& keys)
+      88             : {
+      89           4 :   ExpansionCVs::registerKeywords(keys);
+      90           4 :   keys.remove("ARG");
+      91           8 :   keys.add("compulsory","ARG","the labels of the single ECVs. \\f$\\Delta U_i\\f$, in energy units");
+      92           8 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+      93           8 :   keys.addFlag("DIMENSIONLESS",false,"consider ARG as dimensionless rather than an energy, thus do not multiply it by \\f$\\beta\\f$");
+      94           8 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+      95           4 : }
+      96             : 
+      97           2 : ECVcustom::ECVcustom(const ActionOptions&ao)
+      98             :   : Action(ao)
+      99             :   , ExpansionCVs(ao)
+     100           2 :   , beta0_(1./kbt_)
+     101             : {
+     102             : //set beta0_
+     103             :   bool dimensionless;
+     104           2 :   parseFlag("DIMENSIONLESS",dimensionless);
+     105           2 :   if(dimensionless)
+     106           0 :     beta0_=1;
+     107             : 
+     108             : //set P0_contribution_
+     109           2 :   bool add_P0=false;
+     110           2 :   parseFlag("ADD_P0",add_P0);
+     111           2 :   if(add_P0)
+     112           2 :     P0_contribution_=1;
+     113             :   else
+     114           0 :     P0_contribution_=0;
+     115             : 
+     116             : //set barrier_
+     117           2 :   barrier_=std::numeric_limits<double>::infinity();
+     118           2 :   parse("BARRIER",barrier_);
+     119             : 
+     120           2 :   checkRead();
+     121             : 
+     122             : //set ECVs stuff
+     123           2 :   totNumECVs_=getNumberOfArguments()+P0_contribution_;
+     124           2 :   ECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     125           2 :   derECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     126           6 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     127           4 :     derECVs_[j][j+P0_contribution_]=beta0_; //always constant
+     128             : 
+     129             : //print some info
+     130           2 :   if(dimensionless)
+     131           0 :     log.printf(" -- DIMENSIONLESS: the ARG is not multiplied by beta\n");
+     132           2 :   if(barrier_!=std::numeric_limits<double>::infinity())
+     133             :   {
+     134           0 :     log.printf("  guess for free energy BARRIER = %g\n",barrier_);
+     135           0 :     if(dimensionless)
+     136           0 :       log.printf("    also the BARRIER is considered to be DIMENSIONLESS\n");
+     137             :   }
+     138           2 :   if(P0_contribution_==1)
+     139           2 :     log.printf(" -- ADD_P0: the target includes also the unbiased probability itself\n");
+     140           2 : }
+     141             : 
+     142          91 : void ECVcustom::calculateECVs(const double * cv)
+     143             : {
+     144         273 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     145         182 :     ECVs_[j][j+P0_contribution_]=beta0_*cv[j];
+     146             :   //derivative is constant
+     147          91 : }
+     148             : 
+     149           4 : const double * ECVcustom::getPntrToECVs(unsigned j)
+     150             : {
+     151           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     152           4 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     153           4 :   return &ECVs_[j][0];
+     154             : }
+     155             : 
+     156           4 : const double * ECVcustom::getPntrToDerECVs(unsigned j)
+     157             : {
+     158           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     159           4 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     160           4 :   return &derECVs_[j][0];
+     161             : }
+     162             : 
+     163           2 : std::vector< std::vector<unsigned> > ECVcustom::getIndex_k() const
+     164             : {
+     165           2 :   plumed_massert(isReady_ && totNumECVs_>0,"cannot access getIndex_k() of ECV before initialization");
+     166           2 :   std::vector< std::vector<unsigned> > index_k(totNumECVs_,std::vector<unsigned>(getNumberOfArguments()));
+     167           8 :   for(unsigned k=0; k<totNumECVs_; k++)
+     168          18 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     169          12 :       if(k==j+P0_contribution_)
+     170           4 :         index_k[k][j]=k;
+     171           2 :   return index_k;
+     172           0 : }
+     173             : 
+     174           2 : std::vector<std::string> ECVcustom::getLambdas() const
+     175             : {
+     176           2 :   std::vector<std::string> lambdas(totNumECVs_);
+     177           2 :   if(P0_contribution_==1)
+     178             :   {
+     179           2 :     std::ostringstream subs;
+     180           2 :     subs<<"P0";
+     181           4 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     182           2 :       subs<<"_P0";
+     183           2 :     lambdas[0]=subs.str();
+     184           2 :   }
+     185           6 :   for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     186             :   {
+     187           4 :     const unsigned kk=k-P0_contribution_;
+     188           4 :     std::ostringstream subs;
+     189             : //the getLambdas method is const, so it complains if one tries to access a non-const pointer, hence the const_cast
+     190           4 :     if(kk==0)
+     191             :       subs<<const_cast<ECVcustom *>(this)->getPntrToArgument(kk)->getName();
+     192             :     else
+     193           2 :       subs<<"NaN";
+     194           8 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     195             :     {
+     196           4 :       if(kk==j)
+     197           2 :         subs<<"_"<<const_cast<ECVcustom *>(this)->getPntrToArgument(kk)->getName();
+     198             :       else
+     199           2 :         subs<<"_NaN";
+     200             :     }
+     201           4 :     lambdas[k]=subs.str();
+     202           4 :   }
+     203           2 :   return lambdas;
+     204           0 : }
+     205             : 
+     206           2 : void ECVcustom::initECVs()
+     207             : {
+     208           2 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     209           2 :   isReady_=true;
+     210           2 :   log.printf("  *%4u ECVs for %s\n",totNumECVs_,getName().c_str());
+     211           2 : }
+     212             : 
+     213           1 : void ECVcustom::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     214             : {
+     215           1 :   initECVs();
+     216           1 :   calculateECVs(&all_obs_cvs[index_j]);
+     217           3 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     218           4 :     ECVs_[j][j+P0_contribution_]=std::min(barrier_*beta0_,ECVs_[j][j+P0_contribution_]);
+     219           1 : }
+     220             : 
+     221           1 : void ECVcustom::initECVs_restart(const std::vector<std::string>& lambdas)
+     222             : {
+     223             :   std::size_t pos=0;
+     224           2 :   for(unsigned j=0; j<getNumberOfArguments()-1; j++)
+     225           1 :     pos=lambdas[0].find("_",pos+1); //checking only lambdas[0] is hopefully enough
+     226           1 :   plumed_massert(pos<lambdas[0].length(),"this should not happen, fewer '_' than expected in "+getName());
+     227           1 :   pos=lambdas[0].find("_",pos+1);
+     228           1 :   plumed_massert(pos>lambdas[0].length(),"this should not happen, more '_' than expected in "+getName());
+     229             : 
+     230           1 :   std::vector<std::string> myLambdas=getLambdas();
+     231           1 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     232           1 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     233             : 
+     234           1 :   initECVs();
+     235           1 : }
+     236             : 
+     237             : }
+     238             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVlinear.cpp.func-sort-c.html b/coverage/opes/ECVlinear.cpp.func-sort-c.html new file mode 100644 index 000000000000..9eb5c68ba1b7 --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVlinear.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVlinear.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11411995.8 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9ECVlinearC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes9ECVlinear16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVlinear15initECVs_observERKSt6vectorIdSaIdEEjj3
_ZN4PLMD4opes9ECVlinear13getPntrToECVsEj4
_ZN4PLMD4opes9ECVlinear16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVlinear8initECVsEv4
_ZN4PLMD4opes9ECVlinearC1ERKNS_13ActionOptionsE4
_ZNK4PLMD4opes9ECVlinear10getLambdasB5cxx11Ev4
_ZN4PLMD4opes9ECVlinear16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4opes9ECVlinear13calculateECVsEPKd182
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVlinear.cpp.func.html b/coverage/opes/ECVlinear.cpp.func.html new file mode 100644 index 000000000000..65695a029ea2 --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVlinear.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVlinear.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11411995.8 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9ECVlinear13calculateECVsEPKd182
_ZN4PLMD4opes9ECVlinear13getPntrToECVsEj4
_ZN4PLMD4opes9ECVlinear15initECVs_observERKSt6vectorIdSaIdEEjj3
_ZN4PLMD4opes9ECVlinear16getPntrToDerECVsEj4
_ZN4PLMD4opes9ECVlinear16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes9ECVlinear16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD4opes9ECVlinear8initECVsEv4
_ZN4PLMD4opes9ECVlinearC1ERKNS_13ActionOptionsE4
_ZN4PLMD4opes9ECVlinearC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes9ECVlinear10getLambdasB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVlinear.cpp.gcov.html b/coverage/opes/ECVlinear.cpp.gcov.html new file mode 100644 index 000000000000..5bbc9525fd4a --- /dev/null +++ b/coverage/opes/ECVlinear.cpp.gcov.html @@ -0,0 +1,345 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVlinear.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVlinear.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11411995.8 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : 
+      22             : namespace PLMD {
+      23             : namespace opes {
+      24             : 
+      25             : //+PLUMEDOC OPES_EXPANSION_CV ECV_LINEAR
+      26             : /*
+      27             : Linear expansion, according to a parameter lambda.
+      28             : 
+      29             : This can be used e.g. for thermodynamic integration, or for multibaric simulations, in which case lambda=pressure.
+      30             : It can also be used for multithermal simulations, but for simplicity it is more convenient to use \ref ECV_MULTITHERMAL.
+      31             : 
+      32             : The difference in Hamiltonian \f$\Delta U\f$ is expected as ARG.
+      33             : \f[
+      34             :   \Delta u_\lambda=\beta \lambda \Delta U\, .
+      35             : \f]
+      36             : Use the DIMENSIONLESS flag to avoid multiplying for the inverse temperature \f$\beta\f$.
+      37             : 
+      38             : By defauly the needed steps in lambda are automatically guessed from few initial unbiased MD steps, as descibed in \cite Invernizzi2020unified.
+      39             : Otherwise one can set this number with LAMBDA_STEPS.
+      40             : In both cases the steps will be uniformly distriuted.
+      41             : Finally, one can use instead the keyword LAMBDA_SET_ALL and explicitly provide each lambda value.
+      42             : 
+      43             : \par Examples
+      44             : 
+      45             : Typical multibaric simulation:
+      46             : 
+      47             : \plumedfile
+      48             : vol: VOLUME
+      49             : ecv: ECV_LINEAR ...
+      50             :   ARG=vol
+      51             :   TEMP=300
+      52             :   LAMBDA=0.06022140857*2000 #2 kbar
+      53             :   LAMBDA_MIN=0.06022140857  #1 bar
+      54             :   LAMBDA_MAX=0.06022140857*4000 #4 kbar
+      55             : ...
+      56             : opes: OPES_EXPANDED ARG=ecv.vol PACE=500
+      57             : \endplumedfile
+      58             : 
+      59             : Typical thermodynamic integration:
+      60             : 
+      61             : \plumedfile
+      62             : DeltaU: EXTRACV NAME=energy_difference
+      63             : ecv: ECV_LINEAR ARG=DeltaU TEMP=300
+      64             : opes: OPES_EXPANDED ARG=ecv.* PACE=100
+      65             : \endplumedfile
+      66             : 
+      67             : Notice that by defauly LAMBDA=0, LAMBDA_MIN=0 and LAMBDA_MAX=1, which is the typical case for thermodynamic integration.
+      68             : 
+      69             : */
+      70             : //+ENDPLUMEDOC
+      71             : 
+      72             : class ECVlinear :
+      73             :   public ExpansionCVs
+      74             : {
+      75             : private:
+      76             :   bool todoAutomatic_;
+      77             :   bool geom_spacing_;
+      78             :   double beta0_;
+      79             :   double lambda0_;
+      80             :   std::vector<double> ECVs_;
+      81             :   std::vector<double> derECVs_; //beta0*(lambda_k-lambda0)
+      82             :   void initECVs();
+      83             : 
+      84             : public:
+      85             :   explicit ECVlinear(const ActionOptions&);
+      86             :   static void registerKeywords(Keywords& keys);
+      87             :   void calculateECVs(const double *) override;
+      88             :   const double * getPntrToECVs(unsigned) override;
+      89             :   const double * getPntrToDerECVs(unsigned) override;
+      90             :   std::vector<std::string> getLambdas() const override;
+      91             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+      92             :   void initECVs_restart(const std::vector<std::string>&) override;
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(ECVlinear,"ECV_LINEAR")
+      96             : 
+      97           6 : void ECVlinear::registerKeywords(Keywords& keys)
+      98             : {
+      99           6 :   ExpansionCVs::registerKeywords(keys);
+     100           6 :   keys.remove("ARG");
+     101          12 :   keys.add("compulsory","ARG","the label of the Hamiltonian difference. \\f$\\Delta U\\f$");
+     102          12 :   keys.add("compulsory","LAMBDA","0","the lambda at which the underlying simulation runs");
+     103          12 :   keys.add("optional","LAMBDA_MIN","( default=0 ) the minimum of the lambda range");
+     104          12 :   keys.add("optional","LAMBDA_MAX","( default=1 ) the maximum of the lambda range");
+     105          12 :   keys.add("optional","LAMBDA_STEPS","uniformly place the lambda values, for a total of LAMBDA_STEPS");
+     106          12 :   keys.add("optional","LAMBDA_SET_ALL","manually set all the lamdbas");
+     107          12 :   keys.addFlag("DIMENSIONLESS",false,"ARG is considered dimensionless rather than an energy, thus is not multiplied by \\f$\\beta\\f$");
+     108          12 :   keys.addFlag("GEOM_SPACING",false,"use geometrical spacing in lambda instead of linear spacing");
+     109           6 : }
+     110             : 
+     111           4 : ECVlinear::ECVlinear(const ActionOptions&ao)
+     112             :   : Action(ao)
+     113             :   , ExpansionCVs(ao)
+     114           4 :   , todoAutomatic_(false)
+     115           4 :   , beta0_(1./kbt_)
+     116             : {
+     117           4 :   plumed_massert(getNumberOfArguments()==1,"only DeltaU should be given as ARG");
+     118             : 
+     119             : //set beta0_
+     120             :   bool dimensionless;
+     121           4 :   parseFlag("DIMENSIONLESS",dimensionless);
+     122           4 :   if(dimensionless)
+     123           1 :     beta0_=1;
+     124             : 
+     125             : //parse lambda info
+     126           4 :   parse("LAMBDA",lambda0_);
+     127             :   const double myNone=std::numeric_limits<double>::lowest(); //quiet_NaN is not supported by some intel compiler
+     128           4 :   double lambda_min=myNone;
+     129           4 :   double lambda_max=myNone;
+     130           4 :   parse("LAMBDA_MIN",lambda_min);
+     131           4 :   parse("LAMBDA_MAX",lambda_max);
+     132           4 :   unsigned lambda_steps=0;
+     133           8 :   parse("LAMBDA_STEPS",lambda_steps);
+     134             :   std::vector<double> lambdas;
+     135           4 :   parseVector("LAMBDA_SET_ALL",lambdas);
+     136           4 :   parseFlag("GEOM_SPACING",geom_spacing_);
+     137             : 
+     138           4 :   checkRead();
+     139             : 
+     140             : //set the diff vector using lambdas
+     141           4 :   if(lambdas.size()>0)
+     142             :   {
+     143           1 :     plumed_massert(lambda_steps==0,"cannot set both LAMBDA_STEPS and LAMBDA_SET_ALL");
+     144           1 :     plumed_massert(lambda_min==myNone && lambda_max==myNone,"cannot set both LAMBDA_SET_ALL and LAMBDA_MIN/MAX");
+     145           1 :     plumed_massert(lambdas.size()>=2,"set at least 2 lambdas with LAMBDA_SET_ALL");
+     146           4 :     for(unsigned k=0; k<lambdas.size()-1; k++)
+     147           3 :       plumed_massert(lambdas[k]<=lambdas[k+1],"LAMBDA_SET_ALL must be properly ordered");
+     148           1 :     lambda_min=lambdas[0];
+     149           1 :     lambda_max=lambdas[lambdas.size()-1];
+     150           1 :     derECVs_.resize(lambdas.size());
+     151           5 :     for(unsigned k=0; k<derECVs_.size(); k++)
+     152           4 :       derECVs_[k]=beta0_*(lambdas[k]-lambda0_);
+     153             :   }
+     154             :   else
+     155             :   { //get LAMBDA_MIN and LAMBDA_MAX
+     156           3 :     if(lambda_min==myNone)
+     157             :     {
+     158           0 :       lambda_min=0;
+     159           0 :       log.printf("  no LAMBDA_MIN provided, using LAMBDA_MIN = %g\n",lambda_min);
+     160             :     }
+     161           3 :     if(lambda_max==myNone)
+     162             :     {
+     163           1 :       lambda_max=1;
+     164           1 :       log.printf("  no LAMBDA_MAX provided, using LAMBDA_MAX = %g\n",lambda_max);
+     165             :     }
+     166           3 :     plumed_massert(lambda_max>=lambda_min,"LAMBDA_MAX should be bigger than LAMBDA_MIN");
+     167           3 :     derECVs_.resize(2);
+     168           3 :     derECVs_[0]=beta0_*(lambda_min-lambda0_);
+     169           3 :     derECVs_[1]=beta0_*(lambda_max-lambda0_);
+     170           3 :     if(lambda_min==lambda_max && lambda_steps==0)
+     171           0 :       lambda_steps=1;
+     172           3 :     if(lambda_steps>0)
+     173           2 :       derECVs_=getSteps(derECVs_[0],derECVs_[1],lambda_steps,"LAMBDA",geom_spacing_,beta0_*lambda0_);
+     174             :     else
+     175           2 :       todoAutomatic_=true;
+     176             :   }
+     177           4 :   if(lambda0_<lambda_min || lambda0_>lambda_max)
+     178           1 :     log.printf(" +++ WARNING +++ running at LAMBDA=%g which is outside the chosen lambda range\n",lambda0_);
+     179             : 
+     180             : //print some info
+     181           4 :   log.printf("  running at LAMBDA=%g\n",lambda0_);
+     182           4 :   log.printf("  targeting a lambda range from LAMBDA_MIN=%g to LAMBDA_MAX=%g\n",lambda_min,lambda_max);
+     183           4 :   if(dimensionless)
+     184           1 :     log.printf(" -- DIMENSIONLESS: the ARG is not multiplied by beta\n");
+     185           4 :   if(geom_spacing_)
+     186           1 :     log.printf(" -- GEOM_SPACING: lambdas will be geometrically spaced\n");
+     187           4 : }
+     188             : 
+     189         182 : void ECVlinear::calculateECVs(const double * DeltaU)
+     190             : {
+     191        1587 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     192        1405 :     ECVs_[k]=derECVs_[k]*DeltaU[0];
+     193             : // derivatives never change: derECVs_k=beta0*(lambda_k-lambda0)
+     194         182 : }
+     195             : 
+     196           4 : const double * ECVlinear::getPntrToECVs(unsigned j)
+     197             : {
+     198           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     199           4 :   plumed_massert(j==0,getName()+" has only one CV, the DeltaU");
+     200           4 :   return &ECVs_[0];
+     201             : }
+     202             : 
+     203           4 : const double * ECVlinear::getPntrToDerECVs(unsigned j)
+     204             : {
+     205           4 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     206           4 :   plumed_massert(j==0,getName()+" has only one CV, the DeltaU");
+     207           4 :   return &derECVs_[0];
+     208             : }
+     209             : 
+     210           4 : std::vector<std::string> ECVlinear::getLambdas() const
+     211             : {
+     212           4 :   plumed_massert(!todoAutomatic_,"cannot access lambdas before initializing them");
+     213           4 :   std::vector<std::string> lambdas(derECVs_.size());
+     214          35 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     215             :   {
+     216          31 :     std::ostringstream subs;
+     217          31 :     subs<<derECVs_[k]/beta0_+lambda0_; //lambda_k
+     218          31 :     lambdas[k]=subs.str();
+     219          31 :   }
+     220           4 :   return lambdas;
+     221           0 : }
+     222             : 
+     223           4 : void ECVlinear::initECVs()
+     224             : {
+     225           4 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     226           4 :   plumed_massert(!todoAutomatic_,"this should not happen");
+     227           4 :   totNumECVs_=derECVs_.size();
+     228           4 :   ECVs_.resize(derECVs_.size());
+     229           4 :   isReady_=true;
+     230           4 :   log.printf("  *%4lu lambdas for %s\n",derECVs_.size(),getName().c_str());
+     231           4 : }
+     232             : 
+     233           3 : void ECVlinear::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     234             : {
+     235           3 :   if(todoAutomatic_) //estimate the steps in lambda from observations
+     236             :   {
+     237           1 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j<ncv,"initECVs_observ parameters are inconsistent");
+     238           1 :     std::vector<double> obs_cv(all_obs_cvs.size()/ncv); //copy only useful observation (would be better not to copy...)
+     239          11 :     for(unsigned t=0; t<obs_cv.size(); t++)
+     240          10 :       obs_cv[t]=all_obs_cvs[t*ncv+index_j];
+     241           1 :     const unsigned lambda_steps=estimateNumSteps(derECVs_[0],derECVs_[1],obs_cv,"LAMBDA");
+     242           1 :     if(beta0_!=1)
+     243           0 :       log.printf("    (spacing is in beta0 units)\n");
+     244           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],lambda_steps,"LAMBDA",geom_spacing_,beta0_*lambda0_);
+     245           1 :     todoAutomatic_=false;
+     246             :   }
+     247           3 :   initECVs();
+     248           3 :   calculateECVs(&all_obs_cvs[index_j]);
+     249           3 : }
+     250             : 
+     251           1 : void ECVlinear::initECVs_restart(const std::vector<std::string>& lambdas)
+     252             : {
+     253           1 :   std::size_t pos=lambdas[0].find("_");
+     254           1 :   plumed_massert(pos==std::string::npos,"this should not happen, only one CV is used in "+getName());
+     255           1 :   if(todoAutomatic_)
+     256             :   {
+     257           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],lambdas.size(),"LAMBDA",geom_spacing_,beta0_*lambda0_);
+     258           1 :     todoAutomatic_=false;
+     259             :   }
+     260           1 :   std::vector<std::string> myLambdas=getLambdas();
+     261           1 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     262           1 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     263             : 
+     264           1 :   initECVs();
+     265           1 : }
+     266             : 
+     267             : }
+     268             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermal.cpp.func-sort-c.html b/coverage/opes/ECVmultiThermal.cpp.func-sort-c.html new file mode 100644 index 000000000000..408dd1530a69 --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10711295.5 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes15ECVmultiThermalC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes15ECVmultiThermal16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes15ECVmultiThermal15initECVs_observERKSt6vectorIdSaIdEEjj8
_ZN4PLMD4opes15ECVmultiThermal13getPntrToECVsEj11
_ZN4PLMD4opes15ECVmultiThermal16getPntrToDerECVsEj11
_ZN4PLMD4opes15ECVmultiThermal8initECVsEv11
_ZN4PLMD4opes15ECVmultiThermalC1ERKNS_13ActionOptionsE11
_ZNK4PLMD4opes15ECVmultiThermal10getLambdasB5cxx11Ev11
_ZN4PLMD4opes15ECVmultiThermal16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4opes15ECVmultiThermal13calculateECVsEPKd586
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermal.cpp.func.html b/coverage/opes/ECVmultiThermal.cpp.func.html new file mode 100644 index 000000000000..42d989ac90ac --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10711295.5 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes15ECVmultiThermal13calculateECVsEPKd586
_ZN4PLMD4opes15ECVmultiThermal13getPntrToECVsEj11
_ZN4PLMD4opes15ECVmultiThermal15initECVs_observERKSt6vectorIdSaIdEEjj8
_ZN4PLMD4opes15ECVmultiThermal16getPntrToDerECVsEj11
_ZN4PLMD4opes15ECVmultiThermal16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes15ECVmultiThermal16registerKeywordsERNS_8KeywordsE13
_ZN4PLMD4opes15ECVmultiThermal8initECVsEv11
_ZN4PLMD4opes15ECVmultiThermalC1ERKNS_13ActionOptionsE11
_ZN4PLMD4opes15ECVmultiThermalC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes15ECVmultiThermal10getLambdasB5cxx11Ev11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermal.cpp.gcov.html b/coverage/opes/ECVmultiThermal.cpp.gcov.html new file mode 100644 index 000000000000..c1e584326c94 --- /dev/null +++ b/coverage/opes/ECVmultiThermal.cpp.gcov.html @@ -0,0 +1,345 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermal.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10711295.5 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : 
+      22             : namespace PLMD {
+      23             : namespace opes {
+      24             : 
+      25             : //+PLUMEDOC OPES_EXPANSION_CV ECV_MULTITHERMAL
+      26             : /*
+      27             : Expand a simulation to sample multiple temperatures simultaneously.
+      28             : 
+      29             : The internal energy \f$U\f$ of of the system should be used as ARG.
+      30             : \f[
+      31             :   \Delta u_{\beta'}=(\beta'-\beta) U\, ,
+      32             : \f]
+      33             : where \f$\beta'\f$ are the temperatures to be sampled and \f$\beta\f$ is the temperature at which the simulation is conducted.
+      34             : In case of fixed volume, the internal energy is simply the potential energy given by the \ref ENERGY colvar\f$U=E\f$, and you will run a multicanonical simulation.
+      35             : If instead the simulation is at fixed pressure \f$p\f$, the contribution of the volume must be added \f$U=E+pV\f$ (see example below).
+      36             : 
+      37             : By defauly the needed steps in temperatures are automatically guessed from few initial unbiased MD steps, as descibed in \cite Invernizzi2020unified.
+      38             : Otherwise you can manually set this number with TEMP_STEPS.
+      39             : In both cases the steps will be geometrically spaced in temperature.
+      40             : Use instead the keyword NO_GEOM_SPACING for a linear spacing in the inverse temperature (beta), that typically increases the focus on lower temperatures.
+      41             : Finally, you can use instead the keyword TEMP_SET_ALL and explicitly provide each temperature.
+      42             : 
+      43             : You can reweight the resulting simulation at any temperature in the chosen range, using e.g. \ref REWEIGHT_TEMP_PRESS.
+      44             : A similar target distribution can be sampled using \ref TD_MULTICANONICAL.
+      45             : 
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : Fixed volume, multicanonical simulation:
+      50             : 
+      51             : \plumedfile
+      52             : ene: ENERGY
+      53             : ecv: ECV_MULTITHERMAL ARG=ene TEMP=300 TEMP_MIN=300 TEMP_MAX=800
+      54             : opes: OPES_EXPANDED ARG=ecv.ene PACE=500
+      55             : \endplumedfile
+      56             : 
+      57             : which, if your MD code passes the temperature to PLUMED, is equivalent to:
+      58             : 
+      59             : \plumedfile
+      60             : ene: ENERGY
+      61             : ecv: ECV_MULTITHERMAL ARG=ene TEMP_MAX=800
+      62             : opes: OPES_EXPANDED ARG=ecv.ene PACE=500
+      63             : \endplumedfile
+      64             : 
+      65             : If instead the pressure is fixed and the volume changes, you shuld calculate the internal energy first, \f$U=E+pV\f$
+      66             : 
+      67             : \plumedfile
+      68             : ene: ENERGY
+      69             : vol: VOLUME
+      70             : intEne: CUSTOM PERIODIC=NO ARG=ene,vol FUNC=x+0.06022140857*y
+      71             : ecv: ECV_MULTITHERMAL ARG=intEne TEMP_MAX=800
+      72             : opes: OPES_EXPANDED ARG=ecv.intEne PACE=500
+      73             : \endplumedfile
+      74             : 
+      75             : Notice that \f$p=0.06022140857\f$ corresponds to 1 bar when using the default PLUMED units.
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : class ECVmultiThermal :
+      81             :   public ExpansionCVs
+      82             : {
+      83             : private:
+      84             :   bool todoAutomatic_;
+      85             :   bool geom_spacing_;
+      86             :   std::vector<double> ECVs_;
+      87             :   std::vector<double> derECVs_; //(beta_k-beta0) or (temp0/temp_k-1)/kbt
+      88             :   void initECVs();
+      89             : 
+      90             : public:
+      91             :   explicit ECVmultiThermal(const ActionOptions&);
+      92             :   static void registerKeywords(Keywords& keys);
+      93             :   void calculateECVs(const double *) override;
+      94             :   const double * getPntrToECVs(unsigned) override;
+      95             :   const double * getPntrToDerECVs(unsigned) override;
+      96             :   std::vector<std::string> getLambdas() const override;
+      97             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+      98             :   void initECVs_restart(const std::vector<std::string>&) override;
+      99             : };
+     100             : 
+     101             : PLUMED_REGISTER_ACTION(ECVmultiThermal,"ECV_MULTITHERMAL")
+     102             : 
+     103          13 : void ECVmultiThermal::registerKeywords(Keywords& keys)
+     104             : {
+     105          13 :   ExpansionCVs::registerKeywords(keys);
+     106          13 :   keys.remove("ARG");
+     107          26 :   keys.add("compulsory","ARG","the label of the internal energy of the system. If volume is fixed it is calculated by the \\ref ENERGY colvar");
+     108          26 :   keys.add("optional","TEMP_MIN","the minimum of the temperature range");
+     109          26 :   keys.add("optional","TEMP_MAX","the maximum of the temperature range");
+     110          26 :   keys.add("optional","TEMP_STEPS","the number of steps in temperature");
+     111          26 :   keys.add("optional","TEMP_SET_ALL","manually set all the temperatures");
+     112          26 :   keys.addFlag("NO_GEOM_SPACING",false,"do not use geometrical spacing in temperature, but instead linear spacing in inverse temperature");
+     113          13 : }
+     114             : 
+     115          11 : ECVmultiThermal::ECVmultiThermal(const ActionOptions&ao)
+     116             :   : Action(ao)
+     117             :   , ExpansionCVs(ao)
+     118          11 :   , todoAutomatic_(false)
+     119             : {
+     120          11 :   plumed_massert(getNumberOfArguments()==1,"only the internal energy should be given as ARG");
+     121             : 
+     122             : //set temp0
+     123          11 :   const double temp0=kbt_/getKBoltzmann();
+     124             : 
+     125             : //parse temp range
+     126          11 :   double temp_min=-1;
+     127          11 :   double temp_max=-1;
+     128          11 :   parse("TEMP_MIN",temp_min);
+     129          11 :   parse("TEMP_MAX",temp_max);
+     130          11 :   unsigned temp_steps=0;
+     131          22 :   parse("TEMP_STEPS",temp_steps);
+     132             :   std::vector<double> temps;
+     133          11 :   parseVector("TEMP_SET_ALL",temps);
+     134          11 :   parseFlag("NO_GEOM_SPACING",geom_spacing_);
+     135          11 :   geom_spacing_=!geom_spacing_;
+     136             : 
+     137          11 :   checkRead();
+     138             : 
+     139             : //set the intermediate temperatures
+     140          11 :   if(temps.size()>0)
+     141             :   {
+     142           2 :     plumed_massert(temp_steps==0,"cannot set both TEMP_STEPS and TEMP_SET_ALL");
+     143           2 :     plumed_massert(temp_min==-1 && temp_max==-1,"cannot set both TEMP_SET_ALL and TEMP_MIN/MAX");
+     144           2 :     plumed_massert(temps.size()>=2,"set at least 2 temperatures");
+     145           2 :     temp_min=temps[0];
+     146           2 :     temp_max=temps[temps.size()-1];
+     147           2 :     derECVs_.resize(temps.size());
+     148          10 :     for(unsigned k=0; k<derECVs_.size(); k++)
+     149             :     {
+     150           8 :       derECVs_[k]=(temp0/temps[k]-1.)/kbt_;
+     151           8 :       if(k<derECVs_.size()-1)
+     152           6 :         plumed_massert(temps[k]<=temps[k+1],"TEMP_SET_ALL must be properly ordered");
+     153             :     }
+     154             :   }
+     155             :   else
+     156             :   { //get TEMP_MIN and TEMP_MAX
+     157           9 :     plumed_massert(temp_min!=-1 || temp_max!=-1,"TEMP_MIN, TEMP_MAX or both, should be set");
+     158           9 :     if(temp_min==-1)
+     159             :     {
+     160           2 :       temp_min=temp0;
+     161           2 :       log.printf("  no TEMP_MIN provided, using TEMP_MIN=TEMP\n");
+     162             :     }
+     163           9 :     if(temp_max==-1)
+     164             :     {
+     165           0 :       temp_max=temp0;
+     166           0 :       log.printf("  no TEMP_MAX provided, using TEMP_MAX=TEMP\n");
+     167             :     }
+     168           9 :     plumed_massert(temp_max>=temp_min,"TEMP_MAX should be bigger than TEMP_MIN");
+     169           9 :     derECVs_.resize(2);
+     170           9 :     derECVs_[0]=(temp0/temp_min-1.)/kbt_;
+     171           9 :     derECVs_[1]=(temp0/temp_max-1.)/kbt_;
+     172           9 :     if(temp_min==temp_max && temp_steps==0)
+     173           0 :       temp_steps=1;
+     174           9 :     if(temp_steps>0)
+     175          14 :       derECVs_=getSteps(derECVs_[0],derECVs_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     176             :     else
+     177           2 :       todoAutomatic_=true;
+     178             :   }
+     179             :   const double tol=1e-3; //if temp is taken from MD engine it might be numerically slightly different
+     180          11 :   if(temp0<(1-tol)*temp_min || temp0>(1+tol)*temp_max)
+     181           0 :     log.printf(" +++ WARNING +++ running at TEMP=%g which is outside the chosen temperature range\n",temp0);
+     182             : 
+     183             : //print some info
+     184          11 :   log.printf("  targeting a temperature range from TEMP_MIN=%g to TEMP_MAX=%g\n",temp_min,temp_max);
+     185          11 :   if(!geom_spacing_)
+     186           1 :     log.printf(" -- NO_GEOM_SPACING: inverse temperatures will be linearly spaced\n");
+     187          11 : }
+     188             : 
+     189         586 : void ECVmultiThermal::calculateECVs(const double * ene)
+     190             : {
+     191        3618 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     192        3032 :     ECVs_[k]=derECVs_[k]*ene[0];
+     193             : // derivatives never change: derECVs_k=(beta_k-beta0)
+     194         586 : }
+     195             : 
+     196          11 : const double * ECVmultiThermal::getPntrToECVs(unsigned j)
+     197             : {
+     198          11 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     199          11 :   plumed_massert(j==0,getName()+" has only one CV, the ENERGY");
+     200          11 :   return &ECVs_[0];
+     201             : }
+     202             : 
+     203          11 : const double * ECVmultiThermal::getPntrToDerECVs(unsigned j)
+     204             : {
+     205          11 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     206          11 :   plumed_massert(j==0,getName()+" has only one CV, the ENERGY");
+     207          11 :   return &derECVs_[0];
+     208             : }
+     209             : 
+     210          11 : std::vector<std::string> ECVmultiThermal::getLambdas() const
+     211             : {
+     212          11 :   plumed_massert(!todoAutomatic_,"cannot access lambdas before initializing them");
+     213          11 :   const double temp0=kbt_/getKBoltzmann();
+     214          11 :   std::vector<std::string> lambdas(derECVs_.size());
+     215          70 :   for(unsigned k=0; k<derECVs_.size(); k++)
+     216             :   {
+     217          59 :     std::ostringstream subs;
+     218          59 :     subs<<temp0/(derECVs_[k]*kbt_+1); //temp_k
+     219          59 :     lambdas[k]=subs.str();
+     220          59 :   }
+     221          11 :   return lambdas;
+     222           0 : }
+     223             : 
+     224          11 : void ECVmultiThermal::initECVs()
+     225             : {
+     226          11 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     227          11 :   plumed_massert(!todoAutomatic_,"this should not happen");
+     228          11 :   totNumECVs_=derECVs_.size();
+     229          11 :   ECVs_.resize(derECVs_.size());
+     230          11 :   isReady_=true;
+     231          11 :   log.printf("  *%4lu temperatures for %s\n",derECVs_.size(),getName().c_str());
+     232          11 : }
+     233             : 
+     234           8 : void ECVmultiThermal::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     235             : {
+     236           8 :   if(todoAutomatic_) //estimate the steps in beta from observations
+     237             :   {
+     238           1 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j<ncv,"initECVs_observ parameters are inconsistent");
+     239           1 :     std::vector<double> obs_ene(all_obs_cvs.size()/ncv); //copy only useful observation (would be better not to copy...)
+     240          11 :     for(unsigned t=0; t<obs_ene.size(); t++)
+     241          10 :       obs_ene[t]=all_obs_cvs[t*ncv+index_j];
+     242           1 :     const unsigned temp_steps=estimateNumSteps(derECVs_[0],derECVs_[1],obs_ene,"TEMP");
+     243           1 :     log.printf("    (spacing is in beta, not in temperature)\n");
+     244           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     245           1 :     todoAutomatic_=false;
+     246             :   }
+     247           8 :   initECVs();
+     248           8 :   calculateECVs(&all_obs_cvs[index_j]);
+     249           8 : }
+     250             : 
+     251           3 : void ECVmultiThermal::initECVs_restart(const std::vector<std::string>& lambdas)
+     252             : {
+     253           3 :   std::size_t pos=lambdas[0].find("_");
+     254           3 :   plumed_massert(pos==std::string::npos,"this should not happen, only one CV is used in "+getName());
+     255           3 :   if(todoAutomatic_)
+     256             :   {
+     257           2 :     derECVs_=getSteps(derECVs_[0],derECVs_[1],lambdas.size(),"TEMP",geom_spacing_,1./kbt_);
+     258           1 :     todoAutomatic_=false;
+     259             :   }
+     260           3 :   std::vector<std::string> myLambdas=getLambdas();
+     261           3 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     262           3 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     263             : 
+     264           3 :   initECVs();
+     265           3 : }
+     266             : 
+     267             : }
+     268             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html b/coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html new file mode 100644 index 000000000000..c4d89db6746b --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermalBaric.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermalBaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:26327296.7 %
Date:2024-02-22 21:58:45Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes20ECVmultiThermalBaricC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes20ECVmultiThermalBaric15initECVs_observERKSt6vectorIdSaIdEEjj6
_ZN4PLMD4opes20ECVmultiThermalBaric8initECVsEv9
_ZN4PLMD4opes20ECVmultiThermalBaricC1ERKNS_13ActionOptionsE9
_ZNK4PLMD4opes20ECVmultiThermalBaric10getIndex_kEv9
_ZN4PLMD4opes20ECVmultiThermalBaric16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD4opes20ECVmultiThermalBaric13getPntrToECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric16getPntrToDerECVsEj18
_ZNK4PLMD4opes20ECVmultiThermalBaric10getLambdasB5cxx11Ev18
_ZZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEENKUljE_clEj230
_ZN4PLMD4opes20ECVmultiThermalBaric13calculateECVsEPKd463
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermalBaric.cpp.func.html b/coverage/opes/ECVmultiThermalBaric.cpp.func.html new file mode 100644 index 000000000000..c1e5f48f84ec --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermalBaric.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermalBaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:26327296.7 %
Date:2024-02-22 21:58:45Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes20ECVmultiThermalBaric13calculateECVsEPKd463
_ZN4PLMD4opes20ECVmultiThermalBaric13getPntrToECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric15initECVs_observERKSt6vectorIdSaIdEEjj6
_ZN4PLMD4opes20ECVmultiThermalBaric16getPntrToDerECVsEj18
_ZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes20ECVmultiThermalBaric16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD4opes20ECVmultiThermalBaric8initECVsEv9
_ZN4PLMD4opes20ECVmultiThermalBaricC1ERKNS_13ActionOptionsE9
_ZN4PLMD4opes20ECVmultiThermalBaricC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes20ECVmultiThermalBaric10getIndex_kEv9
_ZNK4PLMD4opes20ECVmultiThermalBaric10getLambdasB5cxx11Ev18
_ZZN4PLMD4opes20ECVmultiThermalBaric16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEENKUljE_clEj230
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html b/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html new file mode 100644 index 000000000000..c59fbea35d55 --- /dev/null +++ b/coverage/opes/ECVmultiThermalBaric.cpp.gcov.html @@ -0,0 +1,607 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVmultiThermalBaric.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVmultiThermalBaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:26327296.7 %
Date:2024-02-22 21:58:45Functions:111291.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : 
+      22             : namespace PLMD {
+      23             : namespace opes {
+      24             : 
+      25             : //+PLUMEDOC OPES_EXPANSION_CV ECV_MULTITHERMAL_MULTIBARIC
+      26             : /*
+      27             : Expand a simulation to sample multiple temperatures and pressures.
+      28             : 
+      29             : The potential \ref ENERGY, \f$E\f$, and the \ref VOLUME, \f$V\f$, of the system should be used as ARG.
+      30             : \f[
+      31             :   \Delta u_{\beta',p'}=(\beta'-\beta) E + (\beta' p' -\beta p) V\, ,
+      32             : \f]
+      33             : where \f$\beta', p'\f$ are the temperatures and pressures to be sampled, while \f$\beta, p\f$ is the temperature and pressure at which the simulation is conducted.
+      34             : 
+      35             : If instead you wish to sample multiple temperatures and a single pressure, you should use \ref ECV_MULTITHERMAL with as ARG the internal energy \f$U=E+pV\f$.
+      36             : 
+      37             : The TEMP_STEPS and PRESSURE_STEPS are automatically guessed from the initial unbiased steps (see OBSERVATION_STEPS in \ref OPES_EXPANDED), unless explicitly set.
+      38             : The algorithm for this guess is described in \cite Invernizzi2020unified should provide a rough estimate useful for most applications.
+      39             : The pressures are uniformely spaced, while the temperatures steps are geometrically spaced.
+      40             : Use instead the keyword NO_GEOM_SPACING for a linear spacing in inverse temperature (beta).
+      41             : For more detailed control you can use instead TEMP_SET_ALL and/or PRESSURE_SET_ALL to explicitly set all of them.
+      42             : The temperatures and pressures are then combined in a 2D grid.
+      43             : 
+      44             : You can use CUT_CORNER to avoid a high-temperature/low-pressure region.
+      45             : This can be useful e.g. to increase the temperature for greater ergodicity, while avoiding water to vaporize, as in Ref.\cite Invernizzi2020unified.
+      46             : 
+      47             : You can reweight the resulting simulation at any temperature and pressure in chosen target, using e.g. \ref REWEIGHT_TEMP_PRESS.
+      48             : A similar target distribution can be sampled using \ref TD_MULTITHERMAL_MULTIBARIC.
+      49             : 
+      50             : \par Examples
+      51             : 
+      52             : \plumedfile
+      53             : ene: ENERGY
+      54             : vol: VOLUME
+      55             : ecv: ECV_MULTITHERMAL_MULTIBARIC ...
+      56             :   ARG=ene,vol
+      57             :   TEMP=500
+      58             :   TEMP_MIN=270
+      59             :   TEMP_MAX=800
+      60             :   PRESSURE=0.06022140857*2000 #2 kbar
+      61             :   PRESSURE_MIN=0.06022140857  #1 bar
+      62             :   PRESSURE_MAX=0.06022140857*4000 #4 kbar
+      63             :   CUT_CORNER=500,0.06022140857,800,0.06022140857*1000
+      64             : ...
+      65             : opes: OPES_EXPANDED ARG=ecv.* FILE=DeltaF.data PACE=500 WALKERS_MPI
+      66             : \endplumedfile
+      67             : 
+      68             : Notice that \f$p=0.06022140857\f$ corresponds to 1 bar only when using the default PLUMED units.
+      69             : If you modify them via the \ref UNITS command, then the pressure has to be rescaled accordingly.
+      70             : 
+      71             : */
+      72             : //+ENDPLUMEDOC
+      73             : 
+      74             : class ECVmultiThermalBaric :
+      75             :   public ExpansionCVs
+      76             : {
+      77             : private:
+      78             :   bool todoAutomatic_beta_;
+      79             :   bool todoAutomatic_pres_;
+      80             :   bool geom_spacing_;
+      81             :   double pres0_;
+      82             :   std::vector<double> pres_;
+      83             :   std::vector<double> ECVs_beta_;
+      84             :   std::vector<double> ECVs_pres_;
+      85             :   std::vector<double> derECVs_beta_; //(beta_k-beta0) or (temp0/temp_k-1)/kbt
+      86             :   std::vector<double> derECVs_pres_; //(beta_k*pres_kk-beta0*pres0) or (temp0/temp_k*pres_kk-pres0)/kbt
+      87             :   void initECVs();
+      88             : 
+      89             : //CUT_CORNER stuff
+      90             :   double coeff_;
+      91             :   double pres_low_;
+      92             :   double kB_temp_low_;
+      93             : //SET_ALL_TEMP_PRESSURE stuff
+      94             :   std::vector<std::string> custom_lambdas_;
+      95             : 
+      96             : public:
+      97             :   explicit ECVmultiThermalBaric(const ActionOptions&);
+      98             :   static void registerKeywords(Keywords& keys);
+      99             :   void calculateECVs(const double *) override;
+     100             :   const double * getPntrToECVs(unsigned) override;
+     101             :   const double * getPntrToDerECVs(unsigned) override;
+     102             :   std::vector< std::vector<unsigned> > getIndex_k() const override;
+     103             :   std::vector<std::string> getLambdas() const override;
+     104             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+     105             :   void initECVs_restart(const std::vector<std::string>&) override;
+     106             : };
+     107             : 
+     108             : PLUMED_REGISTER_ACTION(ECVmultiThermalBaric,"ECV_MULTITHERMAL_MULTIBARIC")
+     109             : 
+     110          11 : void ECVmultiThermalBaric::registerKeywords(Keywords& keys)
+     111             : {
+     112          11 :   ExpansionCVs::registerKeywords(keys);
+     113          11 :   keys.remove("ARG");
+     114          22 :   keys.add("compulsory","ARG","the labels of the potential energy and of the volume of the system. You can calculate them with \\ref ENERGY and \\ref VOLUME respectively");
+     115             : //temperature
+     116          22 :   keys.add("optional","TEMP_MIN","the minimum of the temperature range");
+     117          22 :   keys.add("optional","TEMP_MAX","the maximum of the temperature range");
+     118          22 :   keys.add("optional","TEMP_STEPS","the number of steps in temperature");
+     119          22 :   keys.add("optional","TEMP_SET_ALL","manually set all the temperatures");
+     120          22 :   keys.addFlag("NO_GEOM_SPACING",false,"do not use geometrical spacing in temperature, but instead linear spacing in inverse temperature");
+     121             : //pressure
+     122          22 :   keys.add("compulsory","PRESSURE","pressure. Use the proper units");
+     123          22 :   keys.add("optional","PRESSURE_MIN","the minimum of the pressure range");
+     124          22 :   keys.add("optional","PRESSURE_MAX","the maximum of the pressure range");
+     125          22 :   keys.add("optional","PRESSURE_STEPS","the number of steps in pressure");
+     126          22 :   keys.add("optional","PRESSURE_SET_ALL","manually set all the pressures");
+     127             : //other
+     128          22 :   keys.add("optional","SET_ALL_TEMP_PRESSURE","manually set all the target temperature_pressure pairs. An underscore separates temperature and pressure, while different points are comma-separated, e.g.: temp1_pres1,temp1_pres2,...");
+     129          22 :   keys.add("optional","CUT_CORNER","avoid region of high temperature and low pressure. Exclude all points below a line in the temperature-pressure plane, defined by two points: \\f$T_{\\text{low}},P_{\\text{low}},T_{\\text{high}},P_{\\text{high}}\\f$");
+     130          11 : }
+     131             : 
+     132           9 : ECVmultiThermalBaric::ECVmultiThermalBaric(const ActionOptions&ao)
+     133             :   : Action(ao)
+     134             :   , ExpansionCVs(ao)
+     135           9 :   , todoAutomatic_beta_(false)
+     136           9 :   , todoAutomatic_pres_(false)
+     137           9 :   , coeff_(0)
+     138           9 :   , pres_low_(0)
+     139           9 :   , kB_temp_low_(0)
+     140             : {
+     141           9 :   plumed_massert(getNumberOfArguments()==2,"ENERGY and VOLUME should be given as ARG");
+     142             : 
+     143             : //set temp0
+     144           9 :   const double kB=getKBoltzmann();
+     145           9 :   const double temp0=kbt_/kB;
+     146             : 
+     147             : //parse temp range
+     148           9 :   double temp_min=-1;
+     149           9 :   double temp_max=-1;
+     150           9 :   parse("TEMP_MIN",temp_min);
+     151           9 :   parse("TEMP_MAX",temp_max);
+     152           9 :   unsigned temp_steps=0;
+     153          18 :   parse("TEMP_STEPS",temp_steps);
+     154             :   std::vector<double> temps;
+     155           9 :   parseVector("TEMP_SET_ALL",temps);
+     156           9 :   parseFlag("NO_GEOM_SPACING",geom_spacing_);
+     157           9 :   geom_spacing_=!geom_spacing_;
+     158             : //parse pressures
+     159           9 :   parse("PRESSURE",pres0_);
+     160             :   const double myNone=std::numeric_limits<double>::lowest(); //quiet_NaN is not supported by some intel compiler
+     161           9 :   double pres_min=myNone; //-1 might be a meaningful pressure
+     162           9 :   double pres_max=myNone;
+     163           9 :   parse("PRESSURE_MIN",pres_min);
+     164           9 :   parse("PRESSURE_MAX",pres_max);
+     165           9 :   unsigned pres_steps=0;
+     166           9 :   parse("PRESSURE_STEPS",pres_steps);
+     167          18 :   parseVector("PRESSURE_SET_ALL",pres_);
+     168             : //other
+     169             :   std::vector<double> cut_corner;
+     170           9 :   parseVector("CUT_CORNER",cut_corner);
+     171           9 :   parseVector("SET_ALL_TEMP_PRESSURE",custom_lambdas_);
+     172             : 
+     173           9 :   checkRead();
+     174             : 
+     175           9 :   if(custom_lambdas_.size()>0)
+     176             :   {
+     177             :     //make sure no incompatible options are used
+     178           2 :     plumed_massert(temps.size()==0,"cannot set both SET_ALL_TEMP_PRESSURE and TEMP_SET_ALL");
+     179           2 :     plumed_massert(pres_.size()==0,"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_SET_ALL");
+     180           2 :     plumed_massert(temp_steps==0,"cannot set both SET_ALL_TEMP_PRESSURE and TEMP_STEPS");
+     181           2 :     plumed_massert(pres_steps==0,"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_STEPS");
+     182           2 :     plumed_massert(temp_min==-1 && temp_max==-1,"cannot set both SET_ALL_TEMP_PRESSURE and TEMP_MIN/MAX");
+     183           2 :     plumed_massert(pres_min==myNone && pres_max==myNone,"cannot set both SET_ALL_TEMP_PRESSURE and PRESSURE_MIN/MAX");
+     184           2 :     plumed_massert(cut_corner.size()==0,"cannot set both SET_ALL_TEMP_PRESSURE and CUT_CORNER");
+     185             : //setup the target temperature-pressure grid
+     186           2 :     derECVs_beta_.resize(custom_lambdas_.size());
+     187           2 :     derECVs_pres_.resize(custom_lambdas_.size());
+     188           2 :     const std::string error_msg="SET_ALL_TEMP_PRESSURE: two underscore-separated values are expected for each comma-separated point, cannot understand: ";
+     189          22 :     for(unsigned i=0; i<custom_lambdas_.size(); i++)
+     190             :     {
+     191             :       try
+     192             :       {
+     193             :         std::size_t pos1;
+     194             :         const double temp_i=std::stod(custom_lambdas_[i],&pos1);
+     195          20 :         plumed_massert(pos1+1<custom_lambdas_[i].size(),error_msg+custom_lambdas_[i]);
+     196          20 :         plumed_massert(custom_lambdas_[i][pos1]=='_',error_msg+custom_lambdas_[i]);
+     197             :         std::size_t pos2;
+     198          20 :         const double pres_i=std::stod(custom_lambdas_[i].substr(pos1+1),&pos2);
+     199          20 :         plumed_massert(pos1+1+pos2==custom_lambdas_[i].size(),error_msg+custom_lambdas_[i]);
+     200             : 
+     201          20 :         derECVs_beta_[i]=(temp0/temp_i-1.)/kbt_;
+     202          20 :         derECVs_pres_[i]=(temp0/temp_i*pres_i-pres0_)/kbt_;
+     203             :       }
+     204           0 :       catch (std::exception &ex)
+     205             :       {
+     206           0 :         plumed_merror(error_msg+custom_lambdas_[i]);
+     207           0 :       }
+     208             :     }
+     209             :   }
+     210             :   else
+     211             :   {
+     212             :     //set the intermediate temperatures
+     213           7 :     if(temps.size()>0)
+     214             :     {
+     215           1 :       plumed_massert(temp_steps==0,"cannot set both TEMP_STEPS and TEMP_SET_ALL");
+     216           1 :       plumed_massert(temp_min==-1 && temp_max==-1,"cannot set both TEMP_SET_ALL and TEMP_MIN/MAX");
+     217           1 :       plumed_massert(temps.size()>=2,"set at least 2 temperatures");
+     218           1 :       temp_min=temps[0];
+     219           1 :       temp_max=temps[temps.size()-1];
+     220           1 :       derECVs_beta_.resize(temps.size());
+     221           5 :       for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     222             :       {
+     223           4 :         derECVs_beta_[k]=(temp0/temps[k]-1.)/kbt_;
+     224           4 :         if(k<derECVs_beta_.size()-1)
+     225           3 :           plumed_massert(temps[k]<=temps[k+1],"TEMP_SET_ALL must be properly ordered");
+     226             :       }
+     227             :     }
+     228             :     else
+     229             :     { //get TEMP_MIN and TEMP_MAX
+     230           6 :       if(temp_min==-1)
+     231             :       {
+     232           0 :         temp_min=temp0;
+     233           0 :         log.printf("  no TEMP_MIN provided, using TEMP_MIN=TEMP\n");
+     234             :       }
+     235           6 :       if(temp_max==-1)
+     236             :       {
+     237           1 :         temp_max=temp0;
+     238           1 :         log.printf("  no TEMP_MAX provided, using TEMP_MAX=TEMP\n");
+     239             :       }
+     240           6 :       plumed_massert(temp_max>=temp_min,"TEMP_MAX should be bigger than TEMP_MIN");
+     241           6 :       derECVs_beta_.resize(2);
+     242           6 :       derECVs_beta_[0]=(temp0/temp_min-1.)/kbt_;
+     243           6 :       derECVs_beta_[1]=(temp0/temp_max-1.)/kbt_;
+     244           6 :       if(temp_min==temp_max && temp_steps==0)
+     245           0 :         temp_steps=1;
+     246           6 :       if(temp_steps>0)
+     247           4 :         derECVs_beta_=getSteps(derECVs_beta_[0],derECVs_beta_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     248             :       else
+     249           4 :         todoAutomatic_beta_=true;
+     250             :     }
+     251             :     const double tol=1e-3; //if temp is taken from MD engine it might be numerically slightly different
+     252           7 :     if(temp0<(1-tol)*temp_min || temp0>(1+tol)*temp_max)
+     253           1 :       log.printf(" +++ WARNING +++ running at TEMP=%g which is outside the chosen temperature range\n",temp0);
+     254             : 
+     255             :     //set the intermediate pressures
+     256           7 :     if(pres_.size()>0)
+     257             :     {
+     258           1 :       plumed_massert(pres_steps==0,"cannot set both PRESSURE_STEPS and PRESSURE_SET_ALL");
+     259           1 :       plumed_massert(pres_min==myNone && pres_max==myNone,"cannot set both PRESSURE_SET_ALL and PRESSURE_MIN/MAX");
+     260           1 :       plumed_massert(pres_.size()>=2,"set at least 2 pressures");
+     261           6 :       for(unsigned kk=0; kk<pres_.size()-1; kk++)
+     262           5 :         plumed_massert(pres_[kk]<=pres_[kk+1],"PRESSURE_SET_ALL must be properly ordered");
+     263           1 :       pres_min=pres_[0];
+     264           1 :       pres_max=pres_[pres_.size()-1];
+     265             :     }
+     266             :     else
+     267             :     { //get PRESSURE_MIN and PRESSURE_MAX
+     268           6 :       if(pres_min==myNone)
+     269             :       {
+     270           3 :         pres_min=pres0_;
+     271           3 :         log.printf("  no PRESSURE_MIN provided, using PRESSURE_MIN=PRESSURE\n");
+     272             :       }
+     273           6 :       if(pres_max==myNone)
+     274             :       {
+     275           2 :         pres_max=pres0_;
+     276           2 :         log.printf("  no PRESSURE_MAX provided, using PRESSURE_MAX=PRESSURE\n");
+     277             :       }
+     278           6 :       plumed_massert(pres_max>=pres_min,"PRESSURE_MAX should be bigger than PRESSURE_MIN");
+     279           6 :       if(pres_min==pres_max && pres_steps==0)
+     280           0 :         pres_steps=1;
+     281           6 :       if(pres_steps>0)
+     282           4 :         pres_=getSteps(pres_min,pres_max,pres_steps,"PRESSURE",false,0);
+     283             :       else
+     284             :       {
+     285           4 :         pres_.resize(2);
+     286           4 :         pres_[0]=pres_min;
+     287           4 :         pres_[1]=pres_max;
+     288           4 :         todoAutomatic_pres_=true;
+     289             :       }
+     290             :     }
+     291           7 :     if(pres0_<pres_min || pres0_>pres_max)
+     292           0 :       log.printf(" +++ WARNING +++ running at PRESSURE=%g which is outside the chosen pressure range\n",pres0_);
+     293             : 
+     294             :     //set CUT_CORNER
+     295           7 :     std::string cc_usage("CUT_CORNER=temp_low,pres_low,temp_high,pres_high");
+     296           7 :     if(cut_corner.size()==4)
+     297             :     {
+     298           6 :       const double temp_low=cut_corner[0];
+     299           6 :       const double pres_low=cut_corner[1];
+     300           6 :       const double temp_high=cut_corner[2];
+     301           6 :       const double pres_high=cut_corner[3];
+     302           6 :       plumed_massert(temp_low<temp_high,"temp_low="+std::to_string(temp_low)+" should be smaller than temp_high="+std::to_string(temp_high)+", "+cc_usage);
+     303           6 :       plumed_massert(temp_low>=temp_min && temp_low<=temp_max,"temp_low="+std::to_string(temp_low)+" is out of temperature range. "+cc_usage);
+     304           6 :       plumed_massert(temp_high>=temp_min && temp_high<=temp_max,"temp_high="+std::to_string(temp_high)+" is out of temperature range. "+cc_usage);
+     305           6 :       plumed_massert(pres_low<pres_high,"pres_low="+std::to_string(pres_low)+" should be smaller than pres_high="+std::to_string(pres_high)+", "+cc_usage);
+     306           6 :       plumed_massert(pres_low>=pres_min && pres_low<=pres_max,"pres_low="+std::to_string(pres_low)+" is out of pressure range. "+cc_usage);
+     307           6 :       plumed_massert(pres_high>=pres_min && pres_high<=pres_max,"pres_high="+std::to_string(pres_high)+" is out of pressure range. "+cc_usage);
+     308           6 :       kB_temp_low_=kB*temp_low;
+     309           6 :       coeff_=(pres_high-pres_low)/(temp_high-temp_low)/kB;
+     310           6 :       plumed_massert(coeff_!=0,"this should not be possible");
+     311           6 :       const double small_value=(temp_high-pres_low)/1e4;
+     312           6 :       pres_low_=pres_low-small_value; //make sure pres_max is included
+     313           6 :       plumed_massert(pres_max>=coeff_*(kB*temp_max-kB_temp_low_)+pres_low_,"please chose a pres_high slightly smaller than PRESSURE_MAX in "+cc_usage);
+     314             :     }
+     315             :     else
+     316             :     {
+     317           1 :       plumed_massert(cut_corner.size()==0,"expected 4 values: "+cc_usage);
+     318             :     }
+     319             :   }
+     320             : 
+     321             : //print some info
+     322           9 :   log.printf("  running at TEMP=%g and PRESSURE=%g\n",temp0,pres0_);
+     323           9 :   log.printf("  targeting a temperature range from TEMP_MIN=%g to TEMP_MAX=%g\n",temp_min,temp_max);
+     324           9 :   if(temp_min==temp_max)
+     325           2 :     log.printf(" +++ WARNING +++ if you only need a multibaric simulation it is more efficient to set it up with ECV_LINEAR\n");
+     326           9 :   log.printf("   and a pressure range from PRESSURE_MIN=%g to PRESSURE_MAX=%g\n",pres_min,pres_max);
+     327           9 :   if(pres_min==pres_max)
+     328           2 :     log.printf(" +++ WARNING +++ if you only need a multithermal simulation it is more efficient to set it up with ECV_MULTITHERMAL\n");
+     329           9 :   if(!geom_spacing_)
+     330           1 :     log.printf(" -- NO_GEOM_SPACING: inverse temperatures will be linearly spaced\n");
+     331           9 :   if(coeff_!=0)
+     332           6 :     log.printf(" -- CUT_CORNER: ignoring some high temperature and low pressure values\n");
+     333           9 : }
+     334             : 
+     335         463 : void ECVmultiThermalBaric::calculateECVs(const double * ene_vol)
+     336             : {
+     337        5925 :   for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     338        5462 :     ECVs_beta_[k]=derECVs_beta_[k]*ene_vol[0];
+     339       50075 :   for(unsigned i=0; i<derECVs_pres_.size(); i++)
+     340       49612 :     ECVs_pres_[i]=derECVs_pres_[i]*ene_vol[1];
+     341             : // derivatives are constant, as usual in linear expansions
+     342         463 : }
+     343             : 
+     344          18 : const double * ECVmultiThermalBaric::getPntrToECVs(unsigned j)
+     345             : {
+     346          18 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     347          18 :   plumed_massert(j==0 || j==1,getName()+" has only two CVs, the ENERGY and the VOLUME");
+     348          18 :   if(j==0)
+     349           9 :     return &ECVs_beta_[0];
+     350             :   else //if (j==1)
+     351           9 :     return &ECVs_pres_[0];
+     352             : }
+     353             : 
+     354          18 : const double * ECVmultiThermalBaric::getPntrToDerECVs(unsigned j)
+     355             : {
+     356          18 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     357          18 :   plumed_massert(j==0 || j==1,getName()+" has only two CVs, the ENERGY and the VOLUME");
+     358          18 :   if(j==0)
+     359           9 :     return &derECVs_beta_[0];
+     360             :   else //if (j==1)
+     361           9 :     return &derECVs_pres_[0];
+     362             : }
+     363             : 
+     364           9 : std::vector< std::vector<unsigned> > ECVmultiThermalBaric::getIndex_k() const
+     365             : {
+     366           9 :   plumed_massert(isReady_ && totNumECVs_>0,"cannot access getIndex_k() of ECV before initialization");
+     367             :   std::vector< std::vector<unsigned> > index_k;
+     368           9 :   if(custom_lambdas_.size()>0)
+     369             :   { //same as default getIndex_k() function
+     370           2 :     plumed_massert(totNumECVs_==custom_lambdas_.size(),"this should not happen");
+     371          22 :     for(unsigned i=0; i<totNumECVs_; i++)
+     372          40 :       index_k.emplace_back(std::vector<unsigned> {i,i});
+     373             :   }
+     374             :   else
+     375             :   {
+     376             :     unsigned i=0;
+     377         146 :     for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     378             :     {
+     379         139 :       const double kB_temp_k=kbt_/(derECVs_beta_[k]*kbt_+1);
+     380         139 :       const double line_k=coeff_*(kB_temp_k-kB_temp_low_)+pres_low_;
+     381        2594 :       for(unsigned kk=0; kk<pres_.size(); kk++)
+     382             :       {
+     383        2455 :         if(coeff_==0 || pres_[kk]>=line_k) //important to be inclusive, thus >=, not just >
+     384             :         {
+     385        2254 :           index_k.emplace_back(std::vector<unsigned> {k,i});
+     386        2254 :           i++;
+     387             :         }
+     388             :       }
+     389             :     }
+     390           7 :     plumed_massert(totNumECVs_==index_k.size(),"this should not happen, is something wrong with CUT_CORNER ?");
+     391             :   }
+     392           9 :   return index_k;
+     393           0 : }
+     394             : 
+     395          18 : std::vector<std::string> ECVmultiThermalBaric::getLambdas() const
+     396             : {
+     397          18 :   if(custom_lambdas_.size()>0)
+     398           4 :     return custom_lambdas_;
+     399             : 
+     400          14 :   plumed_massert(!todoAutomatic_beta_ && !todoAutomatic_pres_,"cannot access lambdas before initializing them");
+     401             :   std::vector<std::string> lambdas;
+     402          14 :   const double kB=getKBoltzmann();
+     403         292 :   for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     404             :   {
+     405         278 :     const double kB_temp_k=kbt_/(derECVs_beta_[k]*kbt_+1);
+     406         278 :     const double line_k=coeff_*(kB_temp_k-kB_temp_low_)+pres_low_;
+     407        5188 :     for(unsigned kk=0; kk<pres_.size(); kk++)
+     408             :     {
+     409        4910 :       if(coeff_==0 || pres_[kk]>=line_k)
+     410             :       {
+     411        4508 :         std::ostringstream subs;
+     412        4508 :         subs<<kB_temp_k/kB<<"_"<<pres_[kk];
+     413        4508 :         lambdas.emplace_back(subs.str());
+     414        4508 :       }
+     415             :     }
+     416             :   }
+     417             :   return lambdas;
+     418          14 : }
+     419             : 
+     420           9 : void ECVmultiThermalBaric::initECVs()
+     421             : {
+     422           9 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     423           9 :   plumed_massert(!todoAutomatic_beta_ && !todoAutomatic_pres_,"this should not happen");
+     424           9 :   totNumECVs_=getLambdas().size(); //slow, but runs only once
+     425           9 :   if(custom_lambdas_.size()>0)
+     426             :   {
+     427           2 :     log.printf("  *%4lu temperatures for %s\n",derECVs_beta_.size(),getName().c_str());
+     428           2 :     log.printf("  *%4lu beta-pressures for %s\n",derECVs_pres_.size(),getName().c_str());
+     429           2 :     log.printf("    -- SET_ALL_TEMP_PRESSURE: total number of temp-pres points is %u\n",totNumECVs_);
+     430             :   }
+     431             :   else
+     432             :   {
+     433           7 :     plumed_massert(derECVs_beta_.size()*pres_.size()>=totNumECVs_,"this should not happen, is something wrong with CUT_CORNER ?");
+     434           7 :     derECVs_pres_.resize(totNumECVs_); //pres is mixed with temp (beta*p*V), thus we need to store all possible
+     435             :     //initialize the derECVs.
+     436             :     //this could be done before and one could avoid storing also beta0, beta_k, etc. but this way the code should be more readable
+     437             :     unsigned i=0;
+     438         146 :     for(unsigned k=0; k<derECVs_beta_.size(); k++)
+     439             :     {
+     440         139 :       const double kB_temp_k=kbt_/(derECVs_beta_[k]*kbt_+1);
+     441         139 :       const double line_k=coeff_*(kB_temp_k-kB_temp_low_)+pres_low_;
+     442        2594 :       for(unsigned kk=0; kk<pres_.size(); kk++)
+     443             :       {
+     444        2455 :         if(coeff_==0 || pres_[kk]>=line_k)
+     445             :         {
+     446        2254 :           derECVs_pres_[i]=(pres_[kk]/kB_temp_k-pres0_/kbt_);
+     447        2254 :           i++;
+     448             :         }
+     449             :       }
+     450             :     }
+     451           7 :     log.printf("  *%4lu temperatures for %s\n",derECVs_beta_.size(),getName().c_str());
+     452           7 :     log.printf("  *%4lu pressures for %s\n",pres_.size(),getName().c_str());
+     453           7 :     if(coeff_!=0)
+     454           6 :       log.printf("    -- CUT_CORNER: %lu temp-pres points were excluded, thus total is %u\n",derECVs_beta_.size()*pres_.size()-totNumECVs_,totNumECVs_);
+     455             :   }
+     456           9 :   ECVs_beta_.resize(derECVs_beta_.size());
+     457           9 :   ECVs_pres_.resize(derECVs_pres_.size());
+     458           9 :   isReady_=true;
+     459           9 : }
+     460             : 
+     461           6 : void ECVmultiThermalBaric::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     462             : {
+     463           6 :   if(todoAutomatic_beta_) //estimate the steps in beta from observations
+     464             :   {
+     465           2 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j<ncv,"initECVs_observ parameters are inconsistent");
+     466           2 :     std::vector<double> obs_ene(all_obs_cvs.size()/ncv); //copy only useful observations
+     467          17 :     for(unsigned t=0; t<obs_ene.size(); t++)
+     468          15 :       obs_ene[t]=all_obs_cvs[t*ncv+index_j]+pres0_*all_obs_cvs[t*ncv+index_j+1]; //U=E+pV
+     469           2 :     const unsigned temp_steps=estimateNumSteps(derECVs_beta_[0],derECVs_beta_[1],obs_ene,"TEMP");
+     470           2 :     log.printf("    (spacing is on beta, not on temperature)\n");
+     471           4 :     derECVs_beta_=getSteps(derECVs_beta_[0],derECVs_beta_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     472           2 :     todoAutomatic_beta_=false;
+     473             :   }
+     474           6 :   if(todoAutomatic_pres_) //estimate the steps in pres from observations
+     475             :   {
+     476           2 :     plumed_massert(all_obs_cvs.size()%ncv==0 && index_j+1<ncv,"initECVs_observ parameters are inconsistent");
+     477           2 :     std::vector<double> obs_vol(all_obs_cvs.size()/ncv); //copy only useful observations
+     478          17 :     for(unsigned t=0; t<obs_vol.size(); t++)
+     479          15 :       obs_vol[t]=all_obs_cvs[t*ncv+index_j+1];
+     480           2 :     const unsigned pres_steps=estimateNumSteps((pres_[0]-pres0_)/kbt_,(pres_[1]-pres0_)/kbt_,obs_vol,"PRESSURE");
+     481           2 :     log.printf("    (spacing is in beta0 units)\n");
+     482           4 :     pres_=getSteps(pres_[0],pres_[1],pres_steps,"PRESSURE",false,0);
+     483           2 :     todoAutomatic_pres_=false;
+     484             :   }
+     485           6 :   initECVs();
+     486           6 :   calculateECVs(&all_obs_cvs[index_j]);
+     487           6 : }
+     488             : 
+     489           3 : void ECVmultiThermalBaric::initECVs_restart(const std::vector<std::string>& lambdas)
+     490             : {
+     491           3 :   std::size_t pos=lambdas[0].find("_");
+     492           3 :   plumed_massert(pos!=std::string::npos,"this should not happen, two CVs are used in "+getName()+", not less");
+     493           3 :   pos=lambdas[0].find("_",pos+1);
+     494           3 :   plumed_massert(pos==std::string::npos,"this should not happen, two CVs are used in "+getName()+", not more");
+     495             : 
+     496         230 :   auto getPres=[&lambdas](const unsigned i) {return lambdas[i].substr(lambdas[i].find("_")+1);};
+     497           3 :   if(todoAutomatic_pres_)
+     498             :   {
+     499             :     unsigned pres_steps=1;
+     500           2 :     std::string pres_min=getPres(0);
+     501          20 :     for(unsigned i=1; i<lambdas.size(); i++) //pres is second, thus increas by 1
+     502             :     {
+     503          20 :       if(getPres(i)==pres_min)
+     504             :         break;
+     505          18 :       pres_steps++;
+     506             :     }
+     507           4 :     pres_=getSteps(pres_[0],pres_[1],pres_steps,"PRESSURE",false,0);
+     508           2 :     todoAutomatic_pres_=false;
+     509             :   }
+     510           3 :   if(todoAutomatic_beta_)
+     511             :   {
+     512             :     unsigned temp_steps=1;
+     513           2 :     std::string pres_max=getPres(pres_.size()-1);
+     514         208 :     for(unsigned i=pres_.size(); i<lambdas.size(); i++)
+     515             :     { //even if CUT_CORNER, the max pressures are all present, for each temp
+     516         206 :       if(getPres(i)==pres_max)
+     517          24 :         temp_steps++;
+     518             :     }
+     519           4 :     derECVs_beta_=getSteps(derECVs_beta_[0],derECVs_beta_[1],temp_steps,"TEMP",geom_spacing_,1./kbt_);
+     520           2 :     todoAutomatic_beta_=false;
+     521             :   }
+     522           3 :   std::vector<std::string> myLambdas=getLambdas();
+     523           3 :   plumed_assert(myLambdas.size()==lambdas.size())<<"RESTART - mismatch in number of "<<getName()<<".\nFrom "<<lambdas.size()<<" labels "<<derECVs_beta_.size()<<" temperatures and "<<pres_.size()<<" pressures were found, for a total of "<<myLambdas.size()<<" estimated steps.\nCheck if the CUT_CORNER or the SET_ALL_TEMP_PRESSURE options are consistent\n";
+     524           3 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     525             : 
+     526           3 :   initECVs();
+     527           3 : }
+     528             : 
+     529             : }
+     530             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html b/coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html new file mode 100644 index 000000000000..fb9d970c0741 --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes16ECVumbrellasFileC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes16ECVumbrellasFile16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes16ECVumbrellasFile15initECVs_observERKSt6vectorIdSaIdEEjj2
_ZN4PLMD4opes16ECVumbrellasFile8initECVsEv3
_ZN4PLMD4opes16ECVumbrellasFileC1ERKNS_13ActionOptionsE3
_ZNK4PLMD4opes16ECVumbrellasFile10getLambdasB5cxx11Ev3
_ZN4PLMD4opes16ECVumbrellasFile16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4opes16ECVumbrellasFile13getPntrToECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile16getPntrToDerECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile13calculateECVsEPKd131
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasFile.cpp.func.html b/coverage/opes/ECVumbrellasFile.cpp.func.html new file mode 100644 index 000000000000..36bf00daef3f --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes16ECVumbrellasFile13calculateECVsEPKd131
_ZN4PLMD4opes16ECVumbrellasFile13getPntrToECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile15initECVs_observERKSt6vectorIdSaIdEEjj2
_ZN4PLMD4opes16ECVumbrellasFile16getPntrToDerECVsEj6
_ZN4PLMD4opes16ECVumbrellasFile16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE1
_ZN4PLMD4opes16ECVumbrellasFile16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD4opes16ECVumbrellasFile8initECVsEv3
_ZN4PLMD4opes16ECVumbrellasFileC1ERKNS_13ActionOptionsE3
_ZN4PLMD4opes16ECVumbrellasFileC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes16ECVumbrellasFile10getLambdasB5cxx11Ev3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasFile.cpp.gcov.html b/coverage/opes/ECVumbrellasFile.cpp.gcov.html new file mode 100644 index 000000000000..21fad8362774 --- /dev/null +++ b/coverage/opes/ECVumbrellasFile.cpp.gcov.html @@ -0,0 +1,372 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812098.3 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : #include "tools/File.h"
+      22             : 
+      23             : namespace PLMD {
+      24             : namespace opes {
+      25             : 
+      26             : //+PLUMEDOC OPES_EXPANSION_CV ECV_UMBRELLAS_FILE
+      27             : /*
+      28             : Target a multiumbrella ensemble, by combining systems each with a parabolic bias potential at a different location.
+      29             : 
+      30             : Any set of collective variables \f$\mathbf{s}\f$ can be used as ARG.
+      31             : The positions \f$\mathbf{s}_i\f$ and dimension \f$\mathbf{\sigma}_i\f$ of the umbrellas are read from file.
+      32             : \f[
+      33             :   \Delta u_{\mathbf{s}_i}(\mathbf{s})=\sum_j^{\text{dim}}\frac{([s]_j-[s_i]_j)^2}{2[\sigma_i]_j^2}\, .
+      34             : \f]
+      35             : Notice that \f$\mathbf{\sigma}_i\f$ is diagonal, thus only one SIGMA per CV has to be specified for each umbrella.
+      36             : You can choose the umbrellas manually, or place them on a grid, or along a path, similar to \ref PATH.
+      37             : They must cover all the CV space that one wishes to sample.
+      38             : 
+      39             : The first column of the umbrellas file is always ignored and must be called "time".
+      40             : You can also use as input file a STATE file from an earlier \ref OPES_METAD run (or an \ref OPES_MEAD_EXPLORE run, if you combine it with other ECVs).
+      41             : 
+      42             : Similarly to \ref ECV_UMBRELLAS_LINE, you should set the flag ADD_P0 if you think your umbrellas might not properly cover all the CV region relevant for the unbiased distribution.
+      43             : You can also use BARRIER to set the maximum barrier height to be explored, and avoid huge biases at the beginning of your simulation.
+      44             : See also Appendix B of Ref.\cite Invernizzi2020unified for more details on these last two options.
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : \plumedfile
+      49             : cv1: DISTANCE ATOMS=1,2
+      50             : cv2: DISTANCE ATOMS=3,4
+      51             : cv3: DISTANCE ATOMS=4,1
+      52             : ecv: ECV_UMBRELLAS_FILE ARG=cv1,cv2,cv3 FILE=Umbrellas.data ADD_P0 BARRIER=70
+      53             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      54             : PRINT FILE=COLVAR STRIDE=500 ARG=cv1,cv2,cv3,opes.bias
+      55             : \endplumedfile
+      56             : 
+      57             : The umbrellas file might look like this:
+      58             : \auxfile{Umbrellas.data}
+      59             : #! FIELDS time cv1 cv2 cv3 sigma_cv1 sigma_cv2 sigma_cv3
+      60             : 1  1.17958  2.93697  1.06109  0.19707  0.28275  0.32427
+      61             : 2  2.04023  2.69714  1.84770  0.22307  0.25933  0.31783
+      62             : 3  1.99693  1.10299  1.13351  0.19517  0.26260  0.37427
+      63             : 4  1.15954  1.37447  2.25975  0.20096  0.27168  0.33353
+      64             : 5  1.10126  2.45936  2.40260  0.19747  0.24215  0.35523
+      65             : \endauxfile
+      66             : 
+      67             : */
+      68             : //+ENDPLUMEDOC
+      69             : 
+      70             : class ECVumbrellasFile :
+      71             :   public ExpansionCVs
+      72             : {
+      73             : private:
+      74             :   double barrier_;
+      75             :   unsigned P0_contribution_;
+      76             :   bool lower_only_;
+      77             : 
+      78             :   std::vector< std::vector<double> > centers_;
+      79             :   std::vector< std::vector<double> > sigmas_;
+      80             : 
+      81             :   std::vector< std::vector<double> > ECVs_;
+      82             :   std::vector< std::vector<double> > derECVs_;
+      83             :   void initECVs();
+      84             : 
+      85             : public:
+      86             :   explicit ECVumbrellasFile(const ActionOptions&);
+      87             :   static void registerKeywords(Keywords& keys);
+      88             :   void calculateECVs(const double *) override;
+      89             :   const double * getPntrToECVs(unsigned) override;
+      90             :   const double * getPntrToDerECVs(unsigned) override;
+      91             :   std::vector<std::string> getLambdas() const override;
+      92             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+      93             :   void initECVs_restart(const std::vector<std::string>&) override;
+      94             : };
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(ECVumbrellasFile,"ECV_UMBRELLAS_FILE")
+      97             : 
+      98           5 : void ECVumbrellasFile::registerKeywords(Keywords& keys)
+      99             : {
+     100           5 :   ExpansionCVs::registerKeywords(keys);
+     101           5 :   keys.use("ARG");
+     102          10 :   keys.add("compulsory","FILE","the name of the file containing the umbrellas");
+     103          10 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+     104          10 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+     105          10 :   keys.addFlag("LOWER_HALF_ONLY",false,"use only the lower half of each umbrella potentials");
+     106           5 : }
+     107             : 
+     108           3 : ECVumbrellasFile::ECVumbrellasFile(const ActionOptions&ao):
+     109             :   Action(ao),
+     110           3 :   ExpansionCVs(ao)
+     111             : {
+     112             : //get number of CVs
+     113             :   const unsigned ncv=getNumberOfArguments();
+     114           3 :   centers_.resize(ncv);
+     115           3 :   sigmas_.resize(ncv);
+     116             : 
+     117             : //set P0_contribution_
+     118           3 :   bool add_P0=false;
+     119           3 :   parseFlag("ADD_P0",add_P0);
+     120           3 :   if(add_P0)
+     121           2 :     P0_contribution_=1;
+     122             :   else
+     123           1 :     P0_contribution_=0;
+     124             : 
+     125             : //set barrier_
+     126           3 :   barrier_=std::numeric_limits<double>::infinity();
+     127           3 :   parse("BARRIER",barrier_);
+     128           6 :   parseFlag("LOWER_HALF_ONLY",lower_only_);
+     129             : 
+     130             : //set umbrellas
+     131             :   std::string umbrellasFileName;
+     132           3 :   parse("FILE",umbrellasFileName);
+     133           3 :   IFile ifile;
+     134           3 :   ifile.link(*this);
+     135           3 :   if(ifile.FileExist(umbrellasFileName))
+     136             :   {
+     137           3 :     log.printf("  reading from FILE '%s'\n",umbrellasFileName.c_str());
+     138           3 :     ifile.open(umbrellasFileName);
+     139           3 :     ifile.allowIgnoredFields();
+     140             :     double time; //first field is ignored
+     141        1332 :     while(ifile.scanField("time",time))
+     142             :     {
+     143        1989 :       for(unsigned j=0; j<ncv; j++)
+     144             :       {
+     145             :         double centers_j;
+     146        1326 :         ifile.scanField(getPntrToArgument(j)->getName(),centers_j);
+     147        1326 :         centers_[j].push_back(centers_j); //this might be slow
+     148             :       }
+     149        1989 :       for(unsigned j=0; j<ncv; j++)
+     150             :       {
+     151             :         double sigmas_j;
+     152        2652 :         ifile.scanField("sigma_"+getPntrToArgument(j)->getName(),sigmas_j);
+     153        1326 :         sigmas_[j].push_back(sigmas_j);
+     154             :       }
+     155         663 :       ifile.scanField();
+     156             :     }
+     157             :   }
+     158             :   else
+     159           0 :     plumed_merror("Umbrellas FILE '"+umbrellasFileName+"' not found");
+     160             : 
+     161           3 :   checkRead();
+     162             : 
+     163             : //extra consistency checks
+     164           3 :   const unsigned sizeUmbrellas=centers_[0].size();
+     165           9 :   for(unsigned j=0; j<ncv; j++)
+     166             :   {
+     167           6 :     plumed_massert(centers_[j].size()==sizeUmbrellas,"mismatch in the number of centers read from file");
+     168           6 :     plumed_massert(sigmas_[j].size()==sizeUmbrellas,"mismatch in the number of sigmas read from file");
+     169             :   }
+     170             : 
+     171             : //set ECVs stuff
+     172           3 :   totNumECVs_=sizeUmbrellas+P0_contribution_;
+     173           3 :   ECVs_.resize(ncv,std::vector<double>(totNumECVs_));
+     174           3 :   derECVs_.resize(ncv,std::vector<double>(totNumECVs_));
+     175             : 
+     176             : //printing some info
+     177           3 :   log.printf("  total number of umbrellas = %u\n",sizeUmbrellas);
+     178           3 :   if(barrier_!=std::numeric_limits<double>::infinity())
+     179           1 :     log.printf("  guess for free energy BARRIER = %g\n",barrier_);
+     180           3 :   if(P0_contribution_==1)
+     181           2 :     log.printf(" -- ADD_P0: the target includes also the unbiased probability itself\n");
+     182           3 :   if(lower_only_)
+     183           1 :     log.printf(" -- LOWER_HALF_ONLY: the ECVs are set to zero for values of the CV above the respective center\n");
+     184           6 : }
+     185             : 
+     186         131 : void ECVumbrellasFile::calculateECVs(const double * cv)
+     187             : {
+     188         131 :   if(lower_only_)
+     189             :   {
+     190         153 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     191             :     {
+     192       22644 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     193             :       {
+     194       22542 :         const unsigned kk=k-P0_contribution_;
+     195       22542 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigmas_[j][kk]; //PBC might be present
+     196       22542 :         if(dist_jk>=0)
+     197             :         {
+     198       11483 :           ECVs_[j][k]=0;
+     199       11483 :           derECVs_[j][k]=0;
+     200             :         }
+     201             :         else
+     202             :         {
+     203       11059 :           ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     204       11059 :           derECVs_[j][k]=dist_jk/sigmas_[j][kk];
+     205             :         }
+     206             :       }
+     207             :     }
+     208             :   }
+     209             :   else
+     210             :   {
+     211         240 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     212             :     {
+     213       35520 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     214             :       {
+     215       35360 :         const unsigned kk=k-P0_contribution_;
+     216       35360 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigmas_[j][kk]; //PBC might be present
+     217       35360 :         ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     218       35360 :         derECVs_[j][k]=dist_jk/sigmas_[j][kk];
+     219             :       }
+     220             :     }
+     221             :   }
+     222         131 : }
+     223             : 
+     224           6 : const double * ECVumbrellasFile::getPntrToECVs(unsigned j)
+     225             : {
+     226           6 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     227           6 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     228           6 :   return &ECVs_[j][0];
+     229             : }
+     230             : 
+     231           6 : const double * ECVumbrellasFile::getPntrToDerECVs(unsigned j)
+     232             : {
+     233           6 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     234           6 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     235           6 :   return &derECVs_[j][0];
+     236             : }
+     237             : 
+     238           3 : std::vector<std::string> ECVumbrellasFile::getLambdas() const
+     239             : { //notice that sigmas are not considered!
+     240           3 :   std::vector<std::string> lambdas(totNumECVs_);
+     241           3 :   if(P0_contribution_==1)
+     242             :   {
+     243           2 :     std::ostringstream subs;
+     244           2 :     subs<<"P0";
+     245           4 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     246           2 :       subs<<"_P0";
+     247           2 :     lambdas[0]=subs.str();
+     248           2 :   }
+     249         666 :   for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     250             :   {
+     251         663 :     const unsigned kk=k-P0_contribution_;
+     252         663 :     std::ostringstream subs;
+     253         663 :     subs<<centers_[0][kk];
+     254        1326 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     255         663 :       subs<<"_"<<centers_[j][kk];
+     256         663 :     lambdas[k]=subs.str();
+     257         663 :   }
+     258           3 :   return lambdas;
+     259           0 : }
+     260             : 
+     261           3 : void ECVumbrellasFile::initECVs()
+     262             : {
+     263           3 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     264           3 :   isReady_=true;
+     265           3 :   log.printf("  *%4u windows for %s\n",totNumECVs_,getName().c_str());
+     266           3 : }
+     267             : 
+     268           2 : void ECVumbrellasFile::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     269             : {
+     270             :   //this non-linear exansion never uses automatic initialization
+     271           2 :   initECVs();
+     272           2 :   calculateECVs(&all_obs_cvs[index_j]); //use only first obs point
+     273           6 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     274         888 :     for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     275        1680 :       ECVs_[j][k]=std::min(barrier_/kbt_,ECVs_[j][k]);
+     276           2 : }
+     277             : 
+     278           1 : void ECVumbrellasFile::initECVs_restart(const std::vector<std::string>& lambdas)
+     279             : {
+     280             :   std::size_t pos=0;
+     281           2 :   for(unsigned j=0; j<getNumberOfArguments()-1; j++)
+     282           1 :     pos=lambdas[0].find("_",pos+1); //checking only lambdas[0] is hopefully enough
+     283           1 :   plumed_massert(pos<lambdas[0].length(),"this should not happen, fewer '_' than expected in "+getName());
+     284           1 :   pos=lambdas[0].find("_",pos+1);
+     285           1 :   plumed_massert(pos>lambdas[0].length(),"this should not happen, more '_' than expected in "+getName());
+     286             : 
+     287           1 :   std::vector<std::string> myLambdas=getLambdas();
+     288           1 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     289           1 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     290             : 
+     291           1 :   initECVs();
+     292           1 : }
+     293             : 
+     294             : }
+     295             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html b/coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html new file mode 100644 index 000000000000..6ed310b7c971 --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasLine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasLine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12913198.5 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes16ECVumbrellasLineC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes16ECVumbrellasLine16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes16ECVumbrellasLine15initECVs_observERKSt6vectorIdSaIdEEjj5
_ZN4PLMD4opes16ECVumbrellasLine8initECVsEv8
_ZN4PLMD4opes16ECVumbrellasLineC1ERKNS_13ActionOptionsE8
_ZNK4PLMD4opes16ECVumbrellasLine10getLambdasB5cxx11Ev8
_ZN4PLMD4opes16ECVumbrellasLine13getPntrToECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine16getPntrToDerECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4opes16ECVumbrellasLine13calculateECVsEPKd433
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasLine.cpp.func.html b/coverage/opes/ECVumbrellasLine.cpp.func.html new file mode 100644 index 000000000000..0513c641fde2 --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasLine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasLine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12913198.5 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes16ECVumbrellasLine13calculateECVsEPKd433
_ZN4PLMD4opes16ECVumbrellasLine13getPntrToECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine15initECVs_observERKSt6vectorIdSaIdEEjj5
_ZN4PLMD4opes16ECVumbrellasLine16getPntrToDerECVsEj10
_ZN4PLMD4opes16ECVumbrellasLine16initECVs_restartERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE3
_ZN4PLMD4opes16ECVumbrellasLine16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD4opes16ECVumbrellasLine8initECVsEv8
_ZN4PLMD4opes16ECVumbrellasLineC1ERKNS_13ActionOptionsE8
_ZN4PLMD4opes16ECVumbrellasLineC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes16ECVumbrellasLine10getLambdasB5cxx11Ev8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ECVumbrellasLine.cpp.gcov.html b/coverage/opes/ECVumbrellasLine.cpp.gcov.html new file mode 100644 index 000000000000..fa651e291a36 --- /dev/null +++ b/coverage/opes/ECVumbrellasLine.cpp.gcov.html @@ -0,0 +1,378 @@ + + + + + + + + LCOV - plumed test coverage - opes/ECVumbrellasLine.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ECVumbrellasLine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12913198.5 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : #include "core/ActionRegister.h"
+      21             : 
+      22             : namespace PLMD {
+      23             : namespace opes {
+      24             : 
+      25             : //+PLUMEDOC OPES_EXPANSION_CV ECV_UMBRELLAS_LINE
+      26             : /*
+      27             : Target a multiumbrella ensemble, by combining systems each with a parabolic bias potential at a different location.
+      28             : 
+      29             : Any set of collective variables \f$\mathbf{s}\f$ can be used as ARG.
+      30             : \f[
+      31             :   \Delta u_{\mathbf{s}_i}(\mathbf{s})=\sum_j^{\text{dim}}\frac{([s]_j-[s_i]_j)^2}{2\sigma^2}\, .
+      32             : \f]
+      33             : The Gaussian umbrellas are placed along a line, from CV_MIN to CV_MAX.
+      34             : The umbrellas are placed at a distance SIGMA*SPACING from each other, if you need more flexibility use \ref ECV_UMBRELLAS_FILE.
+      35             : The unbiased fluctuations in the basin usually are a reasonable guess for the value of SIGMA.
+      36             : Typically, a SPACING greater than 1 can lead to faster convergence, by reducing the total number of umbrellas.
+      37             : The umbrellas can be multidimensional, but the CVs dimensions should be rescaled since a single SIGMA must be used.
+      38             : 
+      39             : The keyword BARRIER can be helpful to avoid breaking your system due to a too strong initial bias.
+      40             : If you think the placed umbrellas will not cover the whole unbiased probability distribution you should add it explicitly to the target, with the flag ADD_P0, for more robust convergence.
+      41             : See also Appendix B of Ref.\cite Invernizzi2020unified for more details on these last two options.
+      42             : 
+      43             : The flag LOWER_HALF_ONLY modifies the ECVs so that they are set to zero when \f$\mathbf{s}>\mathbf{s}_i\f$, as in \ref LOWER_WALLS.
+      44             : This can be useful e.g. when the CV used is the \ref ENERGY and one wants to sample a broad range of high energy values, similar to \ref ECV_MULTITHERMAL but with a flat energy distribution as target.
+      45             : By pushing only from below one can avoid too extreme forces that could crash the simulation.
+      46             : 
+      47             : \par Examples
+      48             : 
+      49             : \plumedfile
+      50             : cv: DISTANCE ATOMS=1,2
+      51             : ecv: ECV_UMBRELLAS_LINE ARG=cv CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5 SPACING=1.5
+      52             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      53             : \endplumedfile
+      54             : 
+      55             : It is also possible to combine different ECV_UMBRELLAS_LINE to build a grid of CV values that will be sampled.
+      56             : For example the following code will sample a whole 2D region of cv1 and cv2.
+      57             : 
+      58             : \plumedfile
+      59             : cv1: DISTANCE ATOMS=1,2
+      60             : ecv2: ECV_UMBRELLAS_LINE ARG=cv1 CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5
+      61             : 
+      62             : cv2: DISTANCE ATOMS=3,4
+      63             : ecv1: ECV_UMBRELLAS_LINE ARG=cv2 CV_MIN=13.8 CV_MAX=21.4 SIGMA=4.3
+      64             : 
+      65             : opes: OPES_EXPANDED ARG=ecv1.*,ecv2.* PACE=500
+      66             : \endplumedfile
+      67             : 
+      68             : */
+      69             : //+ENDPLUMEDOC
+      70             : 
+      71             : class ECVumbrellasLine :
+      72             :   public ExpansionCVs
+      73             : {
+      74             : private:
+      75             :   double barrier_;
+      76             :   unsigned P0_contribution_;
+      77             :   bool lower_only_;
+      78             : 
+      79             :   std::vector< std::vector<double> > centers_;
+      80             :   double sigma_;
+      81             : 
+      82             :   std::vector< std::vector<double> > ECVs_;
+      83             :   std::vector< std::vector<double> > derECVs_;
+      84             :   void initECVs();
+      85             : 
+      86             : public:
+      87             :   explicit ECVumbrellasLine(const ActionOptions&);
+      88             :   static void registerKeywords(Keywords& keys);
+      89             :   void calculateECVs(const double *) override;
+      90             :   const double * getPntrToECVs(unsigned) override;
+      91             :   const double * getPntrToDerECVs(unsigned) override;
+      92             :   std::vector<std::string> getLambdas() const override;
+      93             :   void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) override;
+      94             :   void initECVs_restart(const std::vector<std::string>&) override;
+      95             : };
+      96             : 
+      97             : PLUMED_REGISTER_ACTION(ECVumbrellasLine,"ECV_UMBRELLAS_LINE")
+      98             : 
+      99          10 : void ECVumbrellasLine::registerKeywords(Keywords& keys)
+     100             : {
+     101          10 :   ExpansionCVs::registerKeywords(keys);
+     102          10 :   keys.use("ARG");
+     103          20 :   keys.add("compulsory","CV_MIN","the minimum of the CV range to be explored");
+     104          20 :   keys.add("compulsory","CV_MAX","the maximum of the CV range to be explored");
+     105          20 :   keys.add("compulsory","SIGMA","sigma of the umbrella Gaussians");
+     106          20 :   keys.add("compulsory","SPACING","1","the distance between umbrellas, in units of SIGMA");
+     107          20 :   keys.add("optional","BARRIER","a guess of the free energy barrier to be overcome (better to stay higher than lower)");
+     108          20 :   keys.addFlag("ADD_P0",false,"add the unbiased Boltzmann distribution to the target distribution, to make sure to sample it");
+     109          20 :   keys.addFlag("LOWER_HALF_ONLY",false,"use only the lower half of each umbrella potentials");
+     110          10 : }
+     111             : 
+     112           8 : ECVumbrellasLine::ECVumbrellasLine(const ActionOptions&ao):
+     113             :   Action(ao),
+     114           8 :   ExpansionCVs(ao)
+     115             : {
+     116             : //set P0_contribution_
+     117           8 :   bool add_P0=false;
+     118           8 :   parseFlag("ADD_P0",add_P0);
+     119           8 :   if(add_P0)
+     120           2 :     P0_contribution_=1;
+     121             :   else
+     122           6 :     P0_contribution_=0;
+     123             : 
+     124             : //set barrier_
+     125           8 :   barrier_=std::numeric_limits<double>::infinity();
+     126           8 :   parse("BARRIER",barrier_);
+     127           8 :   parseFlag("LOWER_HALF_ONLY",lower_only_);
+     128             : 
+     129             : //set umbrellas
+     130          16 :   parse("SIGMA",sigma_);
+     131             :   std::vector<double> cv_min;
+     132             :   std::vector<double> cv_max;
+     133           8 :   parseVector("CV_MIN",cv_min);
+     134          16 :   parseVector("CV_MAX",cv_max);
+     135           8 :   plumed_massert(cv_min.size()==getNumberOfArguments(),"wrong number of CV_MINs");
+     136           8 :   plumed_massert(cv_max.size()==getNumberOfArguments(),"wrong number of CV_MAXs");
+     137             :   double spacing;
+     138           8 :   parse("SPACING",spacing);
+     139             :   double length=0;
+     140          18 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     141          10 :     length+=std::pow(cv_max[j]-cv_min[j],2);
+     142           8 :   length=std::sqrt(length);
+     143           8 :   unsigned sizeUmbrellas=1+std::round(length/(sigma_*spacing));
+     144           8 :   centers_.resize(getNumberOfArguments()); //centers_[cv][umbrellas]
+     145             :   unsigned full_period=0;
+     146          18 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     147             :   {
+     148          10 :     centers_[j].resize(sizeUmbrellas);
+     149          10 :     if(sizeUmbrellas>1)
+     150         140 :       for(unsigned k=0; k<sizeUmbrellas; k++)
+     151         130 :         centers_[j][k]=cv_min[j]+k*(cv_max[j]-cv_min[j])/(sizeUmbrellas-1);
+     152             :     else
+     153           0 :       centers_[j][0]=(cv_min[j]+cv_max[j])/2.;
+     154          10 :     if(getPntrToArgument(j)->isPeriodic())
+     155             :     {
+     156             :       double min,max;
+     157             :       std::string min_str,max_str;
+     158          10 :       getPntrToArgument(j)->getDomain(min,max);
+     159          10 :       getPntrToArgument(j)->getDomain(min_str,max_str);
+     160          10 :       plumed_massert(cv_min[j]>=min,"ARG "+std::to_string(j)+": CV_MIN cannot be smaller than the periodic bound "+min_str);
+     161          10 :       plumed_massert(cv_max[j]<=max,"ARG "+std::to_string(j)+": CV_MAX cannot be greater than the periodic bound "+max_str);
+     162          10 :       if(cv_min[j]==min && cv_max[j]==max)
+     163           6 :         full_period++;
+     164             :     }
+     165             :   }
+     166           8 :   if(full_period==getNumberOfArguments() && sizeUmbrellas>1) //first and last are the same point
+     167             :   {
+     168           6 :     sizeUmbrellas--;
+     169          12 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     170           6 :       centers_[j].pop_back();
+     171             :   }
+     172             : 
+     173           8 :   checkRead();
+     174             : 
+     175             : //set ECVs stuff
+     176           8 :   totNumECVs_=sizeUmbrellas+P0_contribution_;
+     177           8 :   ECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     178           8 :   derECVs_.resize(getNumberOfArguments(),std::vector<double>(totNumECVs_));
+     179             : 
+     180             : //printing some info
+     181           8 :   log.printf("  total number of umbrellas = %u\n",sizeUmbrellas);
+     182           8 :   log.printf("    with SIGMA = %g\n",sigma_);
+     183           8 :   log.printf("    and SPACING = %g\n",spacing);
+     184           8 :   if(barrier_!=std::numeric_limits<double>::infinity())
+     185           2 :     log.printf("  guess for free energy BARRIER = %g\n",barrier_);
+     186           8 :   if(P0_contribution_==1)
+     187           2 :     log.printf(" -- ADD_P0: the target includes also the unbiased probability itself\n");
+     188           8 :   if(lower_only_)
+     189           1 :     log.printf(" -- LOWER_HALF_ONLY: the ECVs are set to zero for values of the CV above the respective center\n");
+     190           8 : }
+     191             : 
+     192         433 : void ECVumbrellasLine::calculateECVs(const double * cv)
+     193             : {
+     194         433 :   if(lower_only_)
+     195             :   {
+     196         153 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     197             :     {
+     198        2040 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     199             :       {
+     200        1938 :         const unsigned kk=k-P0_contribution_;
+     201        1938 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigma_; //PBC might be present
+     202        1938 :         if(dist_jk>=0)
+     203             :         {
+     204         933 :           ECVs_[j][k]=0;
+     205         933 :           derECVs_[j][k]=0;
+     206             :         }
+     207             :         else
+     208             :         {
+     209        1005 :           ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     210        1005 :           derECVs_[j][k]=dist_jk/sigma_;
+     211             :         }
+     212             :       }
+     213             :     }
+     214             :   }
+     215             :   else
+     216             :   {
+     217         804 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+     218             :     {
+     219        4678 :       for(unsigned k=P0_contribution_; k<totNumECVs_; k++) //if ADD_P0, the first ECVs=0
+     220             :       {
+     221        4256 :         const unsigned kk=k-P0_contribution_;
+     222        4256 :         const double dist_jk=difference(j,centers_[j][kk],cv[j])/sigma_; //PBC might be present
+     223        4256 :         ECVs_[j][k]=0.5*std::pow(dist_jk,2);
+     224        4256 :         derECVs_[j][k]=dist_jk/sigma_;
+     225             :       }
+     226             :     }
+     227             :   }
+     228         433 : }
+     229             : 
+     230          10 : const double * ECVumbrellasLine::getPntrToECVs(unsigned j)
+     231             : {
+     232          10 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     233          10 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     234          10 :   return &ECVs_[j][0];
+     235             : }
+     236             : 
+     237          10 : const double * ECVumbrellasLine::getPntrToDerECVs(unsigned j)
+     238             : {
+     239          10 :   plumed_massert(isReady_,"cannot access ECVs before initialization");
+     240          10 :   plumed_massert(j<getNumberOfArguments(),getName()+" has fewer CVs");
+     241          10 :   return &derECVs_[j][0];
+     242             : }
+     243             : 
+     244           8 : std::vector<std::string> ECVumbrellasLine::getLambdas() const
+     245             : {
+     246           8 :   std::vector<std::string> lambdas(totNumECVs_);
+     247           8 :   if(P0_contribution_==1)
+     248             :   {
+     249           2 :     std::ostringstream subs;
+     250           2 :     subs<<"P0";
+     251           4 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     252           2 :       subs<<"_P0";
+     253           2 :     lambdas[0]=subs.str();
+     254           2 :   }
+     255          94 :   for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     256             :   {
+     257          86 :     const unsigned kk=k-P0_contribution_;
+     258          86 :     std::ostringstream subs;
+     259          86 :     subs<<centers_[0][kk];
+     260         124 :     for(unsigned j=1; j<getNumberOfArguments(); j++)
+     261          38 :       subs<<"_"<<centers_[j][kk];
+     262          86 :     lambdas[k]=subs.str();
+     263          86 :   }
+     264           8 :   return lambdas;
+     265           0 : }
+     266             : 
+     267           8 : void ECVumbrellasLine::initECVs()
+     268             : {
+     269           8 :   plumed_massert(!isReady_,"initialization should not be called twice");
+     270           8 :   isReady_=true;
+     271           8 :   log.printf("  *%4u windows for %s\n",totNumECVs_,getName().c_str());
+     272           8 : }
+     273             : 
+     274           5 : void ECVumbrellasLine::initECVs_observ(const std::vector<double>& all_obs_cvs,const unsigned ncv,const unsigned index_j)
+     275             : {
+     276             :   //this non-linear exansion never uses automatic initialization
+     277           5 :   initECVs();
+     278           5 :   calculateECVs(&all_obs_cvs[index_j]); //use only first obs point
+     279          11 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+     280          76 :     for(unsigned k=P0_contribution_; k<totNumECVs_; k++)
+     281         123 :       ECVs_[j][k]=std::min(barrier_/kbt_,ECVs_[j][k]);
+     282           5 : }
+     283             : 
+     284           3 : void ECVumbrellasLine::initECVs_restart(const std::vector<std::string>& lambdas)
+     285             : {
+     286             :   std::size_t pos=0;
+     287           4 :   for(unsigned j=0; j<getNumberOfArguments()-1; j++)
+     288           1 :     pos=lambdas[0].find("_",pos+1); //checking only lambdas[0] is hopefully enough
+     289           3 :   plumed_massert(pos<lambdas[0].length(),"this should not happen, fewer '_' than expected in "+getName());
+     290           3 :   pos=lambdas[0].find("_",pos+1);
+     291           3 :   plumed_massert(pos>lambdas[0].length(),"this should not happen, more '_' than expected in "+getName());
+     292             : 
+     293           3 :   std::vector<std::string> myLambdas=getLambdas();
+     294           3 :   plumed_massert(myLambdas.size()==lambdas.size(),"RESTART - mismatch in number of "+getName());
+     295           3 :   plumed_massert(std::equal(myLambdas.begin(),myLambdas.end(),lambdas.begin()),"RESTART - mismatch in lambda values of "+getName());
+     296             : 
+     297           3 :   initECVs();
+     298           3 : }
+     299             : 
+     300             : }
+     301             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.cpp.func-sort-c.html b/coverage/opes/ExpansionCVs.cpp.func-sort-c.html new file mode 100644 index 000000000000..5884645c9d25 --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9610492.3 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVsC1ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6
_ZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_9
_ZNK4PLMD4opes12ExpansionCVs8getStepsEddjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd24
_ZNK4PLMD4opes12ExpansionCVs10getIndex_kEv26
_ZN4PLMD4opes12ExpansionCVsC2ERKNS_13ActionOptionsE37
_ZN4PLMD4opes12ExpansionCVs16registerKeywordsERNS_8KeywordsE49
_ZZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_ENKUldS6_E_clEdS6_109
_ZN4PLMD4opes12ExpansionCVs5applyEv1847
_ZN4PLMD4opes12ExpansionCVs9calculateEv1847
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.cpp.func.html b/coverage/opes/ExpansionCVs.cpp.func.html new file mode 100644 index 000000000000..8bf58edc3ed6 --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9610492.3 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVs16registerKeywordsERNS_8KeywordsE49
_ZN4PLMD4opes12ExpansionCVs5applyEv1847
_ZN4PLMD4opes12ExpansionCVs9calculateEv1847
_ZN4PLMD4opes12ExpansionCVsC1ERKNS_13ActionOptionsE0
_ZN4PLMD4opes12ExpansionCVsC2ERKNS_13ActionOptionsE37
_ZNK4PLMD4opes12ExpansionCVs10getIndex_kEv26
_ZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE6
_ZNK4PLMD4opes12ExpansionCVs8getStepsEddjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd24
_ZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_9
_ZZZNK4PLMD4opes12ExpansionCVs16estimateNumStepsEddRKSt6vectorIdSaIdEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEENKUldS6_E_clEdS6_ENKUldS6_E_clEdS6_109
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.cpp.gcov.html b/coverage/opes/ExpansionCVs.cpp.gcov.html new file mode 100644 index 000000000000..2d1edf82fbd7 --- /dev/null +++ b/coverage/opes/ExpansionCVs.cpp.gcov.html @@ -0,0 +1,299 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9610492.3 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "ExpansionCVs.h"
+      20             : 
+      21             : #include "tools/OpenMP.h"
+      22             : 
+      23             : namespace PLMD {
+      24             : namespace opes {
+      25             : 
+      26          49 : void ExpansionCVs::registerKeywords(Keywords& keys)
+      27             : {
+      28          49 :   Action::registerKeywords(keys);
+      29          49 :   ActionWithValue::registerKeywords(keys);
+      30          49 :   ActionWithArguments::registerKeywords(keys);
+      31          49 :   ActionWithValue::useCustomisableComponents(keys);
+      32          98 :   keys.add("compulsory","TEMP","-1","temperature. If not specified tries to get it from MD engine");
+      33          49 : }
+      34             : 
+      35          37 : ExpansionCVs::ExpansionCVs(const ActionOptions&ao)
+      36             :   : Action(ao)
+      37             :   , ActionWithValue(ao)
+      38             :   , ActionWithArguments(ao)
+      39          37 :   , isReady_(false)
+      40          37 :   , totNumECVs_(0)
+      41             : {
+      42             : //set kbt_
+      43          37 :   const double kB=getKBoltzmann();
+      44          37 :   kbt_=getkBT();
+      45          37 :   log.printf("  temperature = %g, beta = %g\n",kbt_/kB,1./kbt_);
+      46             : 
+      47             : //set components
+      48          37 :   plumed_massert( getNumberOfArguments()!=0, "you must specify the underlying CV");
+      49          90 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+      50             :   {
+      51          53 :     std::string name_j=getPntrToArgument(j)->getName();
+      52          53 :     ActionWithValue::addComponentWithDerivatives(name_j);
+      53          53 :     getPntrToComponent(j)->resizeDerivatives(1);
+      54          53 :     if(getPntrToArgument(j)->isPeriodic()) //it should not be necessary, but why not
+      55             :     {
+      56             :       std::string min,max;
+      57          17 :       getPntrToArgument(j)->getDomain(min,max);
+      58          17 :       getPntrToComponent(j)->setDomain(min,max);
+      59             :     }
+      60             :     else
+      61          36 :       getPntrToComponent(j)->setNotPeriodic();
+      62             :   }
+      63          37 :   plumed_massert((int)getNumberOfArguments()==getNumberOfComponents(),"Expansion CVs have same number of arguments and components");
+      64          37 : }
+      65             : 
+      66        1847 : void ExpansionCVs::calculate()
+      67             : {
+      68        1847 :   std::vector<double> args(getNumberOfArguments());
+      69        4470 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+      70             :   {
+      71        2623 :     args[j]=getArgument(j);
+      72        2623 :     getPntrToComponent(j)->set(args[j]); //components are equal to arguments
+      73        2623 :     getPntrToComponent(j)->addDerivative(0,1.); //the derivative of the identity is 1
+      74             :   }
+      75        1847 :   if(isReady_)
+      76        1417 :     calculateECVs(&args[0]);
+      77        1847 : }
+      78             : 
+      79        1847 : void ExpansionCVs::apply()
+      80             : {
+      81        4470 :   for(unsigned j=0; j<getNumberOfArguments(); j++)
+      82             :   {
+      83        2623 :     std::vector<double> force_j(1);
+      84        2623 :     if(getPntrToComponent(j)->applyForce(force_j)) //a bias is applied?
+      85        2623 :       getPntrToArgument(j)->addForce(force_j[0]); //just tell it to the CV!
+      86             :   }
+      87        1847 : }
+      88             : 
+      89          26 : std::vector< std::vector<unsigned> > ExpansionCVs::getIndex_k() const
+      90             : {
+      91          26 :   plumed_massert(isReady_ && totNumECVs_>0,"cannot access getIndex_k() of ECV before initialization");
+      92          26 :   std::vector< std::vector<unsigned> > index_k(totNumECVs_,std::vector<unsigned>(getNumberOfArguments()));
+      93         869 :   for(unsigned k=0; k<totNumECVs_; k++)
+      94        2391 :     for(unsigned j=0; j<getNumberOfArguments(); j++)
+      95        1548 :       index_k[k][j]=k; //each CV gives rise to the same number of ECVs
+      96          26 :   return index_k;
+      97           0 : }
+      98             : 
+      99             : //following methods are meant to be used only in case of linear expansions
+     100          24 : std::vector<double> ExpansionCVs::getSteps(double lambda_min,double lambda_max,const unsigned lambda_steps,const std::string& msg,const bool geom_spacing, const double shift) const
+     101             : {
+     102          24 :   plumed_massert(!(lambda_min==lambda_max && lambda_steps>1),"cannot have multiple "+msg+"_STEPS if "+msg+"_MIN=="+msg+"_MAX");
+     103          24 :   std::vector<double> lambda(lambda_steps);
+     104          24 :   if(lambda_steps==1)
+     105             :   {
+     106           0 :     lambda[0]=(lambda_min+lambda_max)/2.;
+     107           0 :     log.printf(" +++ WARNING +++ using one single %s as target = %g\n",msg.c_str(),lambda[0]);
+     108             :   }
+     109             :   else
+     110             :   {
+     111          24 :     if(geom_spacing) //geometric spacing
+     112             :     { //this way lambda[k]/lambda[k+1] is constant
+     113          14 :       lambda_min+=shift;
+     114          14 :       lambda_max+=shift;
+     115          14 :       plumed_massert(lambda_min>0,"cannot use GEOM_SPACING when %s_MIN is not greater than zero");
+     116          14 :       plumed_massert(lambda_max>0,"cannot use GEOM_SPACING when %s_MAX is not greater than zero");
+     117          14 :       const double log_lambda_min=std::log(lambda_min);
+     118          14 :       const double log_lambda_max=std::log(lambda_max);
+     119         196 :       for(unsigned k=0; k<lambda.size(); k++)
+     120         182 :         lambda[k]=std::exp(log_lambda_min+k*(log_lambda_max-log_lambda_min)/(lambda_steps-1))-shift;
+     121             :     }
+     122             :     else //linear spacing
+     123         108 :       for(unsigned k=0; k<lambda.size(); k++)
+     124          98 :         lambda[k]=lambda_min+k*(lambda_max-lambda_min)/(lambda_steps-1);
+     125             :   }
+     126          24 :   return lambda;
+     127             : }
+     128             : 
+     129           6 : unsigned ExpansionCVs::estimateNumSteps(const double left_side,const double right_side,const std::vector<double>& obs,const std::string& msg) const
+     130             : { //for linear expansions only, it uses effective sample size (Neff) to estimate the grid spacing
+     131           6 :   if(left_side==0 && right_side==0)
+     132             :   {
+     133           0 :     log.printf(" +++ WARNING +++ %s_MIN and %s_MAX are equal to %s, using single step\n",msg.c_str(),msg.c_str(),msg.c_str());
+     134           0 :     return 1;
+     135             :   }
+     136           9 :   auto get_neff_HWHM=[](const double side,const std::vector<double>& obs) //HWHM = half width at half maximum. neff is in general not symmetric
+     137             :   {
+     138             :     //func: Neff/N-0.5 is a function between -0.5 and 0.5
+     139         109 :     auto func=[](const double delta,const std::vector<double>& obs)
+     140             :     {
+     141             :       double sum_w=0;
+     142             :       double sum_w2=0;
+     143             :       //we could avoid recomputing safe_shift every time, but here speed is not a concern
+     144         218 :       const double safe_shift=delta<0?*std::max_element(obs.begin(),obs.end()):*std::min_element(obs.begin(),obs.end());
+     145         899 :       for(unsigned t=0; t<obs.size(); t++)
+     146             :       {
+     147         790 :         const double w=std::exp(-delta*(obs[t]-safe_shift)); //robust to overflow
+     148         790 :         sum_w+=w;
+     149         790 :         sum_w2+=w*w;
+     150             :       }
+     151         109 :       return sum_w*sum_w/sum_w2/obs.size()-0.5;
+     152             :     };
+     153             :     //here we find the root of func using the regula falsi (false position) method
+     154             :     //but any method would be OK, not much precision is needed. src/tools/RootFindingBase.h looked complicated
+     155             :     const double tolerance=1e-4; //seems to be a good default
+     156             :     double a=0; //default is right side case
+     157             :     double func_a=0.5;
+     158             :     double b=side;
+     159           9 :     double func_b=func(side,obs);
+     160           9 :     if(func_b>=0)
+     161             :       return 0.0; //no zero is present!
+     162           9 :     if(b<0) //left side case
+     163             :     {
+     164             :       std::swap(a,b);
+     165             :       std::swap(func_a,func_b);
+     166             :     }
+     167             :     double c=a;
+     168             :     double func_c=func_a;
+     169         109 :     while(std::abs(func_c)>tolerance)
+     170             :     {
+     171         100 :       if(func_a*func_c>0)
+     172             :       {
+     173             :         a=c;
+     174             :         func_a=func_c;
+     175             :       }
+     176             :       else
+     177             :       {
+     178             :         b=c;
+     179             :         func_b=func_c;
+     180             :       }
+     181         100 :       c=(a*func_b-b*func_a)/(func_b-func_a);
+     182         100 :       func_c=func(c,obs); //func is evaluated only here, it might be expensive
+     183             :     }
+     184           9 :     return std::abs(c);
+     185             :   };
+     186             : 
+     187             : //estimation
+     188             :   double left_HWHM=0;
+     189           6 :   if(left_side!=0)
+     190           4 :     left_HWHM=get_neff_HWHM(left_side,obs);
+     191             :   double right_HWHM=0;
+     192           6 :   if(right_side!=0)
+     193           5 :     right_HWHM=get_neff_HWHM(right_side,obs);
+     194           6 :   if(left_HWHM==0)
+     195             :   {
+     196           2 :     right_HWHM*=2;
+     197           2 :     if(left_side==0)
+     198           2 :       log.printf(" --- %s_MIN is equal to %s\n",msg.c_str(),msg.c_str());
+     199             :     else
+     200           0 :       log.printf(" +++ WARNING +++ %s_MIN is very close to %s\n",msg.c_str(),msg.c_str());
+     201             :   }
+     202           6 :   if(right_HWHM==0)
+     203             :   {
+     204           1 :     left_HWHM*=2;
+     205           1 :     if(right_side==0)
+     206           1 :       log.printf(" --- %s_MAX is equal to %s\n",msg.c_str(),msg.c_str());
+     207             :     else
+     208           0 :       log.printf(" +++ WARNING +++ %s_MAX is very close to %s\n",msg.c_str(),msg.c_str());
+     209             :   }
+     210           6 :   const double grid_spacing=left_HWHM+right_HWHM;
+     211           6 :   log.printf("   estimated %s spacing = %g\n",msg.c_str(),grid_spacing);
+     212           6 :   unsigned steps=std::ceil(std::abs(right_side-left_side)/grid_spacing);
+     213           6 :   if(steps<2 || grid_spacing==0)
+     214             :   {
+     215           0 :     log.printf(" +++ WARNING +++ %s range is very narrow, using %s_MIN and %s_MAX as only steps\n",msg.c_str(),msg.c_str(),msg.c_str());
+     216             :     steps=2;
+     217             :   }
+     218             :   return steps;
+     219             : }
+     220             : 
+     221             : }
+     222             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.h.func-sort-c.html b/coverage/opes/ExpansionCVs.h.func-sort-c.html new file mode 100644 index 000000000000..ac5541dfe933 --- /dev/null +++ b/coverage/opes/ExpansionCVs.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVsD2Ev37
_ZNK4PLMD4opes12ExpansionCVs13getTotNumECVsEv50
_ZN4PLMD4opes12ExpansionCVs22getNumberOfDerivativesEv170
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.h.func.html b/coverage/opes/ExpansionCVs.h.func.html new file mode 100644 index 000000000000..379a88c6969d --- /dev/null +++ b/coverage/opes/ExpansionCVs.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12ExpansionCVs22getNumberOfDerivativesEv170
_ZN4PLMD4opes12ExpansionCVsD2Ev37
_ZNK4PLMD4opes12ExpansionCVs13getTotNumECVsEv50
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/ExpansionCVs.h.gcov.html b/coverage/opes/ExpansionCVs.h.gcov.html new file mode 100644 index 000000000000..eeb15390ce37 --- /dev/null +++ b/coverage/opes/ExpansionCVs.h.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - opes/ExpansionCVs.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - ExpansionCVs.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #ifndef __PLUMED_opes_ExpansionCVs_h
+      20             : #define __PLUMED_opes_ExpansionCVs_h
+      21             : 
+      22             : #include "core/ActionWithValue.h"
+      23             : #include "core/ActionWithArguments.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace opes {
+      27             : 
+      28             : /*
+      29             : \ingroup INHERIT
+      30             : This is the abstract base class to use for implementing expansion CVs (ECVs).
+      31             : ECVs should be used together with the OPESexpanded action.
+      32             : They take as argument regular CVs, and output them as components without modification.
+      33             : */
+      34             : 
+      35             : class ExpansionCVs:
+      36             :   public ActionWithValue,
+      37             :   public ActionWithArguments
+      38             : {
+      39             : protected:
+      40             :   bool isReady_; //true only after initECVs
+      41             :   double kbt_;
+      42             :   unsigned totNumECVs_;
+      43             : 
+      44             : //methods useful for linear expansions
+      45             :   std::vector<double> getSteps(double,double,const unsigned,const std::string&,const bool,const double) const;
+      46             :   unsigned estimateNumSteps(const double,const double,const std::vector<double>&,const std::string&) const;
+      47             : 
+      48             : public:
+      49             :   explicit ExpansionCVs(const ActionOptions&);
+      50          37 :   virtual ~ExpansionCVs() {};
+      51             :   void apply() override;
+      52             :   void calculate() override;
+      53             :   static void registerKeywords(Keywords&);
+      54         170 :   inline unsigned getNumberOfDerivatives() override {return 1;};
+      55             : 
+      56          67 :   inline double getKbT() const {return kbt_;};
+      57          50 :   inline unsigned getTotNumECVs() const {plumed_massert(isReady_,"cannot ask for totNumECVs before ECV isReady"); return totNumECVs_;};
+      58             :   virtual std::vector< std::vector<unsigned> > getIndex_k() const; //might need to override this
+      59             : 
+      60             :   virtual void calculateECVs(const double *) = 0;
+      61             :   virtual const double * getPntrToECVs(unsigned) = 0;
+      62             :   virtual const double * getPntrToDerECVs(unsigned) = 0;
+      63             :   virtual std::vector<std::string> getLambdas() const = 0;
+      64             :   virtual void initECVs_observ(const std::vector<double>&,const unsigned,const unsigned) = 0; //arg: all the observed CVs, the total numer of CVs, the first CV index referring to this ECV
+      65             :   virtual void initECVs_restart(const std::vector<std::string>&) = 0; //arg: the lambdas read from DeltaF_name relative to this ECV
+      66             : };
+      67             : 
+      68             : }
+      69             : }
+      70             : 
+      71             : #endif
+      72             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESexpanded.cpp.func-sort-c.html b/coverage/opes/OPESexpanded.cpp.func-sort-c.html new file mode 100644 index 000000000000..15ca261464d0 --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43144397.3 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12OPESexpandedC2ERKNS_13ActionOptionsE0
_ZN4PLMD4opes12OPESexpanded15dumpStateToFileEv11
_ZN4PLMD4opes12OPESexpanded12init_fromObsEv20
_ZN4PLMD4opes12OPESexpanded13init_linkECVsEv30
_ZN4PLMD4opes12OPESexpanded20init_pntrToECVsClassEv30
_ZN4PLMD4opes12OPESexpandedC1ERKNS_13ActionOptionsE30
_ZN4PLMD4opes12OPESexpanded16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD4opes12OPESexpanded11printDeltaFEv64
_ZZN4PLMD4opes12OPESexpandedC4ERKNS_13ActionOptionsEENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjjE_clESC_jj525
_ZN4PLMD4opes12OPESexpanded12updateDeltaFEd660
_ZN4PLMD4opes12OPESexpanded6updateEv1490
_ZN4PLMD4opes12OPESexpanded9calculateEv1490
_ZNK4PLMD4opes12OPESexpanded12getExpansionEj644469
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESexpanded.cpp.func.html b/coverage/opes/OPESexpanded.cpp.func.html new file mode 100644 index 000000000000..27d11875d87d --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43144397.3 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes12OPESexpanded11printDeltaFEv64
_ZN4PLMD4opes12OPESexpanded12init_fromObsEv20
_ZN4PLMD4opes12OPESexpanded12updateDeltaFEd660
_ZN4PLMD4opes12OPESexpanded13init_linkECVsEv30
_ZN4PLMD4opes12OPESexpanded15dumpStateToFileEv11
_ZN4PLMD4opes12OPESexpanded16registerKeywordsERNS_8KeywordsE32
_ZN4PLMD4opes12OPESexpanded20init_pntrToECVsClassEv30
_ZN4PLMD4opes12OPESexpanded6updateEv1490
_ZN4PLMD4opes12OPESexpanded9calculateEv1490
_ZN4PLMD4opes12OPESexpandedC1ERKNS_13ActionOptionsE30
_ZN4PLMD4opes12OPESexpandedC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4opes12OPESexpanded12getExpansionEj644469
_ZZN4PLMD4opes12OPESexpandedC4ERKNS_13ActionOptionsEENKUlRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjjE_clESC_jj525
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESexpanded.cpp.gcov.html b/coverage/opes/OPESexpanded.cpp.gcov.html new file mode 100644 index 000000000000..09aba826b34e --- /dev/null +++ b/coverage/opes/OPESexpanded.cpp.gcov.html @@ -0,0 +1,1021 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESexpanded.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESexpanded.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:43144397.3 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "bias/Bias.h"
+      20             : #include "core/PlumedMain.h"
+      21             : #include "core/ActionRegister.h"
+      22             : #include "core/ActionSet.h"
+      23             : #include "tools/Communicator.h"
+      24             : #include "tools/File.h"
+      25             : #include "tools/OpenMP.h"
+      26             : 
+      27             : #include "ExpansionCVs.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace opes {
+      31             : 
+      32             : //+PLUMEDOC OPES_BIAS OPES_EXPANDED
+      33             : /*
+      34             : On-the-fly probability enhanced sampling with expanded ensembles for the target distribution.
+      35             : 
+      36             : This method is similar to the OPES method (\ref OPES "OPES") with expanded ensembles target distribution (replica-exchange-like) \cite Invernizzi2020unified.
+      37             : 
+      38             : An expanded ensemble is obtained by summing a set of ensembles at slightly different termodynamic conditions, or with slightly different Hamiltonians.
+      39             : Such ensembles can be sampled via methods like replica exchange, or this \ref OPES_EXPANDED bias action.
+      40             : A typical example is a multicanonical simulation, in which a whole range of temperatures is sampled instead of a single one.
+      41             : 
+      42             : In oreder to define an expanded target ensemble we use \ref EXPANSION_CV "expansion collective variables" (ECVs), \f$\Delta u_\lambda(\mathbf{x})\f$.
+      43             : The bias at step \f$n\f$ is
+      44             : \f[
+      45             :   V_n(\mathbf{x})=-\frac{1}{\beta}\log \left(\frac{1}{N_{\{\lambda\}}}\sum_\lambda e^{-\Delta u_\lambda(\mathbf{x})+\beta\Delta F_n(\lambda)}\right)\, .
+      46             : \f]
+      47             : See Ref.\cite Invernizzi2020unified for more details on the method.
+      48             : 
+      49             : Notice that the estimates in the DELTAFS file are expressed in energy units, and should be multiplied by \f$\beta\f$ to be dimensionless as in Ref.\cite Invernizzi2020unified.
+      50             : The DELTAFS file also contains an estimate of \f$c(t)=\frac{1}{\beta} \log \langle e^{\beta V}\rangle\f$.
+      51             : Similarly to \ref OPES_METAD, it is printed only for reference, since \f$c(t)\f$ reaches a fixed value as the bias converges, and should NOT be used for reweighting.
+      52             : Its value is also needed for restarting a simulation.
+      53             : 
+      54             : You can store the instantaneous \f$\Delta F_n(\lambda)\f$ estimates also in a more readable format using STATE_WFILE and STATE_WSTRIDE.
+      55             : Restart can be done either from a DELTAFS file or from a STATE_RFILE, it is equivalent.
+      56             : 
+      57             : Contrary to \ref OPES_METAD, \ref OPES_EXPANDED does not use kernel density estimation.
+      58             : 
+      59             : \par Examples
+      60             : 
+      61             : \plumedfile
+      62             : # simulate multiple temperatures, as in parallel tempering
+      63             : ene: ENERGY
+      64             : ecv: ECV_MULTITHERMAL ARG=ene TEMP_MAX=1000
+      65             : opes: OPES_EXPANDED ARG=ecv.* PACE=500
+      66             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,opes.bias
+      67             : \endplumedfile
+      68             : 
+      69             : You can easily combine multiple ECVs.
+      70             : The \ref OPES_EXPANDED bias will create a multidimensional target grid to sample all the combinations.
+      71             : 
+      72             : \plumedfile
+      73             : # simulate multiple temperatures while biasing a CV
+      74             : ene: ENERGY
+      75             : dst: DISTANCE ATOMS=1,2
+      76             : 
+      77             : ecv1: ECV_MULTITHERMAL ARG=ene TEMP_SET_ALL=200,300,500,1000
+      78             : ecv2: ECV_UMBRELLAS_LINE ARG=dst CV_MIN=1.2 CV_MAX=4.3 SIGMA=0.5
+      79             : opes: OPES_EXPANDED ARG=ecv1.*,ecv2.* PACE=500 OBSERVATION_STEPS=1
+      80             : 
+      81             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,dst,opes.bias
+      82             : \endplumedfile
+      83             : 
+      84             : If an ECV is based on more than one CV you must provide all the output component, in the proper order.
+      85             : You can use \ref Regex for that, like in the following example.
+      86             : 
+      87             : \plumedfile
+      88             : # simulate multiple temperatures and pressures while biasing a two-CVs linear path
+      89             : ene: ENERGY
+      90             : vol: VOLUME
+      91             : ecv_mtp: ECV_MULTITHERMAL_MULTIBARIC ...
+      92             :   ARG=ene,vol
+      93             :   TEMP=300
+      94             :   TEMP_MIN=200
+      95             :   TEMP_MAX=800
+      96             :   PRESSURE=0.06022140857*1000 #1 kbar
+      97             :   PRESSURE_MIN=0
+      98             :   PRESSURE_MAX=0.06022140857*2000 #2 kbar
+      99             : ...
+     100             : 
+     101             : cv1: DISTANCE ATOMS=1,2
+     102             : cv2: DISTANCE ATOMS=3,4
+     103             : ecv_umb: ECV_UMBRELLAS_LINE ARG=cv1,cv2 TEMP=300 CV_MIN=0.1,0.1 CV_MAX=1.5,1.5 SIGMA=0.2 BARRIER=70
+     104             : 
+     105             : opes: OPES_EXPANDED ARG=(ecv_.*) PACE=500 WALKERS_MPI PRINT_STRIDE=1000
+     106             : 
+     107             : PRINT FILE=COLVAR STRIDE=500 ARG=ene,vol,cv1,cv2,opes.bias
+     108             : \endplumedfile
+     109             : 
+     110             : 
+     111             : */
+     112             : //+ENDPLUMEDOC
+     113             : 
+     114             : class OPESexpanded : public bias::Bias {
+     115             : 
+     116             : private:
+     117             :   bool isFirstStep_;
+     118             :   unsigned NumOMP_;
+     119             :   unsigned NumParallel_;
+     120             :   unsigned rank_;
+     121             :   unsigned NumWalkers_;
+     122             :   unsigned walker_rank_;
+     123             :   unsigned long long counter_;
+     124             :   std::size_t ncv_;
+     125             : 
+     126             :   std::vector<const double *> ECVs_;
+     127             :   std::vector<const double *> derECVs_;
+     128             :   std::vector<opes::ExpansionCVs*> pntrToECVsClass_;
+     129             :   std::vector< std::vector<unsigned> > index_k_;
+     130             : // A note on indexes usage:
+     131             : //  j -> underlying CVs
+     132             : //  i -> DeltaFs
+     133             : //  k -> single ECVs, which might not be trivially numbered
+     134             : //  l -> groups of ECVs, pntrToECVsClass
+     135             : //  h -> subgroups of ECVs, arguments in ECVsClass
+     136             : //  w -> walkers
+     137             : 
+     138             :   double kbt_;
+     139             :   unsigned stride_;
+     140             :   unsigned deltaF_size_; //different from deltaF_.size() if NumParallel_>1
+     141             :   std::vector<double> deltaF_;
+     142             :   std::vector<double> diff_;
+     143             :   double rct_;
+     144             : 
+     145             :   std::vector<double> all_deltaF_;
+     146             :   std::vector<int> all_size_;
+     147             :   std::vector<int> disp_;
+     148             : 
+     149             :   unsigned obs_steps_;
+     150             :   std::vector<double> obs_cvs_;
+     151             : 
+     152             :   bool calc_work_;
+     153             :   double work_;
+     154             : 
+     155             :   unsigned print_stride_;
+     156             :   OFile deltaFsOfile_;
+     157             :   std::vector<std::string> deltaF_name_;
+     158             : 
+     159             :   OFile stateOfile_;
+     160             :   int wStateStride_;
+     161             :   bool storeOldStates_;
+     162             : 
+     163             :   void init_pntrToECVsClass();
+     164             :   void init_linkECVs();
+     165             :   void init_fromObs();
+     166             : 
+     167             :   void printDeltaF();
+     168             :   void dumpStateToFile();
+     169             :   void updateDeltaF(double);
+     170             :   double getExpansion(const unsigned) const;
+     171             : 
+     172             : public:
+     173             :   explicit OPESexpanded(const ActionOptions&);
+     174             :   void calculate() override;
+     175             :   void update() override;
+     176             :   static void registerKeywords(Keywords& keys);
+     177             : };
+     178             : 
+     179             : PLUMED_REGISTER_ACTION(OPESexpanded,"OPES_EXPANDED")
+     180             : 
+     181          32 : void OPESexpanded::registerKeywords(Keywords& keys)
+     182             : {
+     183          32 :   Bias::registerKeywords(keys);
+     184          32 :   keys.remove("ARG");
+     185          64 :   keys.add("compulsory","ARG","the label of the ECVs that define the expansion. You can use an * to make sure all the output components of the ECVs are used, as in the examples above");
+     186          64 :   keys.add("compulsory","PACE","how often the bias is updated");
+     187          64 :   keys.add("compulsory","OBSERVATION_STEPS","100","number of unbiased initial PACE steps to collect statistics for initialization");
+     188             : //DeltaFs and state files
+     189          64 :   keys.add("compulsory","FILE","DELTAFS","a file with the estimate of the relative Delta F for each component of the target and of the global c(t)");
+     190          64 :   keys.add("compulsory","PRINT_STRIDE","100","stride for printing to DELTAFS file, in units of PACE");
+     191          64 :   keys.add("optional","FMT","specify format for DELTAFS file");
+     192          64 :   keys.add("optional","STATE_RFILE","read from this file the Delta F estimates and all the info needed to RESTART the simulation");
+     193          64 :   keys.add("optional","STATE_WFILE","write to this file the Delta F estimates and all the info needed to RESTART the simulation");
+     194          64 :   keys.add("optional","STATE_WSTRIDE","number of MD steps between writing the STATE_WFILE. Default is only on CPT events (but not all MD codes set them)");
+     195          64 :   keys.addFlag("STORE_STATES",false,"append to STATE_WFILE instead of ovewriting it each time");
+     196             : //miscellaneous
+     197          64 :   keys.addFlag("CALC_WORK",false,"calculate the total accumulated work done by the bias since last restart");
+     198          64 :   keys.addFlag("WALKERS_MPI",false,"switch on MPI version of multiple walkers");
+     199          64 :   keys.addFlag("SERIAL",false,"perform calculations in serial");
+     200          32 :   keys.use("RESTART");
+     201          32 :   keys.use("UPDATE_FROM");
+     202          32 :   keys.use("UPDATE_UNTIL");
+     203             : 
+     204             : //output components
+     205          32 :   componentsAreNotOptional(keys);
+     206          64 :   keys.addOutputComponent("work","CALC_WORK","total accumulated work done by the bias");
+     207          32 : }
+     208             : 
+     209          30 : OPESexpanded::OPESexpanded(const ActionOptions&ao)
+     210             :   : PLUMED_BIAS_INIT(ao)
+     211          30 :   , isFirstStep_(true)
+     212          30 :   , counter_(0)
+     213          30 :   , ncv_(getNumberOfArguments())
+     214          30 :   , deltaF_size_(0)
+     215          30 :   , rct_(0)
+     216          30 :   , work_(0)
+     217             : {
+     218             : //set pace
+     219          30 :   parse("PACE",stride_);
+     220          30 :   parse("OBSERVATION_STEPS",obs_steps_);
+     221          30 :   plumed_massert(obs_steps_!=0,"minimum is OBSERVATION_STEPS=1");
+     222          30 :   obs_cvs_.resize(obs_steps_*ncv_);
+     223             : 
+     224             : //deltaFs file
+     225             :   std::string deltaFsFileName;
+     226          30 :   parse("FILE",deltaFsFileName);
+     227          60 :   parse("PRINT_STRIDE",print_stride_);
+     228             :   std::string fmt;
+     229          60 :   parse("FMT",fmt);
+     230             : //output checkpoint of current state
+     231             :   std::string restartFileName;
+     232          60 :   parse("STATE_RFILE",restartFileName);
+     233             :   std::string stateFileName;
+     234          30 :   parse("STATE_WFILE",stateFileName);
+     235          30 :   wStateStride_=0;
+     236          30 :   parse("STATE_WSTRIDE",wStateStride_);
+     237          30 :   storeOldStates_=false;
+     238          30 :   parseFlag("STORE_STATES",storeOldStates_);
+     239          30 :   if(wStateStride_!=0 || storeOldStates_)
+     240           5 :     plumed_massert(stateFileName.length()>0,"filename for storing simulation status not specified, use STATE_WFILE");
+     241          30 :   if(wStateStride_>0)
+     242           5 :     plumed_massert(wStateStride_>=(int)stride_,"STATE_WSTRIDE is in units of MD steps, thus should be a multiple of PACE");
+     243          30 :   if(stateFileName.length()>0 && wStateStride_==0)
+     244           1 :     wStateStride_=-1;//will print only on CPT events (checkpoints set by some MD engines, like gromacs)
+     245             : 
+     246             : //work flag
+     247          30 :   parseFlag("CALC_WORK",calc_work_);
+     248             : 
+     249             : //multiple walkers //external MW for cp2k not supported, but anyway cp2k cannot put bias on energy!
+     250          30 :   bool walkers_mpi=false;
+     251          30 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     252          30 :   if(walkers_mpi)
+     253             :   {
+     254             :     //If this Action is not compiled with MPI the user is informed and we exit gracefully
+     255           4 :     plumed_massert(Communicator::plumedHasMPI(),"Invalid walkers configuration: WALKERS_MPI flag requires MPI compilation");
+     256           4 :     plumed_massert(Communicator::initialized(),"Invalid walkers configuration: WALKERS_MPI needs the communicator correctly initialized.");
+     257             : 
+     258           4 :     if(comm.Get_rank()==0) //multi_sim_comm works on first rank only
+     259             :     {
+     260           4 :       NumWalkers_=multi_sim_comm.Get_size();
+     261           4 :       walker_rank_=multi_sim_comm.Get_rank();
+     262             :     }
+     263           4 :     comm.Bcast(NumWalkers_,0); //if each walker has more than one processor update them all
+     264           4 :     comm.Bcast(walker_rank_,0);
+     265             :   }
+     266             :   else
+     267             :   {
+     268          26 :     NumWalkers_=1;
+     269          26 :     walker_rank_=0;
+     270             :   }
+     271             : 
+     272             : //parallelization stuff
+     273          30 :   NumOMP_=OpenMP::getNumThreads();
+     274          30 :   NumParallel_=comm.Get_size();
+     275          30 :   rank_=comm.Get_rank();
+     276          30 :   bool serial=false;
+     277          30 :   parseFlag("SERIAL",serial);
+     278          30 :   if(serial)
+     279             :   {
+     280           5 :     NumOMP_=1;
+     281           5 :     NumParallel_=1;
+     282           5 :     rank_=0;
+     283             :   }
+     284             : 
+     285          30 :   checkRead();
+     286             : 
+     287             : //check ECVs and link them
+     288          30 :   init_pntrToECVsClass();
+     289             : //set kbt_
+     290          30 :   kbt_=pntrToECVsClass_[0]->getKbT();
+     291          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     292          37 :     plumed_massert(std::abs(kbt_-pntrToECVsClass_[l]->getKbT())<1e-4,"must set same TEMP for each ECV");
+     293             : 
+     294             : //restart if needed
+     295          30 :   if(getRestart())
+     296             :   {
+     297             :     bool stateRestart=true;
+     298          10 :     if(restartFileName.length()==0)
+     299             :     {
+     300             :       stateRestart=false;
+     301             :       restartFileName=deltaFsFileName;
+     302             :     }
+     303          10 :     IFile ifile;
+     304          10 :     ifile.link(*this);
+     305          10 :     if(ifile.FileExist(restartFileName))
+     306             :     {
+     307          10 :       log.printf("  RESTART - make sure all ECVs used are the same as before\n");
+     308          10 :       log.printf("    restarting from: %s\n",restartFileName.c_str());
+     309          10 :       ifile.open(restartFileName);
+     310          10 :       if(stateRestart) //get all info
+     311             :       {
+     312           2 :         log.printf("    it should be a STATE file (not a DELTAFS file)\n");
+     313             :         double time; //not used
+     314           2 :         ifile.scanField("time",time);
+     315           2 :         ifile.scanField("counter",counter_);
+     316           4 :         ifile.scanField("rct",rct_);
+     317             :         std::string tmp_lambda;
+     318          66 :         while(ifile.scanField(getPntrToArgument(0)->getName(),tmp_lambda))
+     319             :         {
+     320          64 :           std::string subs="DeltaF_"+tmp_lambda;
+     321         128 :           for(unsigned jj=1; jj<ncv_; jj++)
+     322             :           {
+     323             :             tmp_lambda.clear();
+     324          64 :             ifile.scanField(getPntrToArgument(jj)->getName(),tmp_lambda);
+     325         128 :             subs+="_"+tmp_lambda;
+     326             :           }
+     327          64 :           deltaF_name_.push_back(subs);
+     328             :           double tmp_deltaF;
+     329          64 :           ifile.scanField("DeltaF",tmp_deltaF);
+     330          64 :           deltaF_.push_back(tmp_deltaF);
+     331          64 :           ifile.scanField();
+     332             :           tmp_lambda.clear();
+     333             :         }
+     334           2 :         log.printf("  successfully read %lu DeltaF values\n",deltaF_name_.size());
+     335           2 :         if(NumParallel_>1)
+     336           2 :           all_deltaF_=deltaF_;
+     337             :       }
+     338             :       else //get just deltaFs names
+     339             :       {
+     340           8 :         ifile.scanFieldList(deltaF_name_);
+     341           8 :         plumed_massert(deltaF_name_.size()>=4,"RESTART - fewer than expected FIELDS found in '"+deltaFsFileName+"' file");
+     342           8 :         plumed_massert(deltaF_name_[deltaF_name_.size()-1]=="print_stride","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     343           8 :         plumed_massert(deltaF_name_[0]=="time","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     344           8 :         plumed_massert(deltaF_name_[1]=="rct","RESTART - coult not find expected FIELDS in '"+deltaFsFileName+"' file");
+     345             :         deltaF_name_.pop_back();
+     346             :         deltaF_name_.erase(deltaF_name_.begin(),deltaF_name_.begin()+2);
+     347             :         std::size_t pos=5; //each name starts with "DeltaF"
+     348          22 :         for(unsigned j=0; j<ncv_; j++)
+     349          14 :           pos=deltaF_name_[0].find("_",pos+1); //checking only first one, hopefully is enough
+     350           8 :         plumed_massert(pos<deltaF_name_[0].length(),"RESTART - fewer '_' than expected in DeltaF fields: did you remove any CV?");
+     351           8 :         pos=deltaF_name_[0].find("_",pos+1);
+     352           8 :         plumed_massert(pos>deltaF_name_[0].length(),"RESTART - more '_' than expected in DeltaF fields: did you add new CV?");
+     353             :       }
+     354             :       //get lambdas, init ECVs and Link them
+     355          10 :       deltaF_size_=deltaF_name_.size();
+     356         525 :       auto getLambdaName=[](const std::string& name,const unsigned start,const unsigned dim)
+     357             :       {
+     358             :         std::size_t pos_start=5; //each name starts with "DeltaF"
+     359        1068 :         for(unsigned j=0; j<=start; j++)
+     360         543 :           pos_start=name.find("_",pos_start+1);
+     361             :         std::size_t pos_end=pos_start;
+     362        1527 :         for(unsigned j=0; j<dim; j++)
+     363        1002 :           pos_end=name.find("_",pos_end+1);
+     364         525 :         pos_start++; //do not include heading "_"
+     365         525 :         return name.substr(pos_start,pos_end-pos_start);
+     366             :       };
+     367          10 :       unsigned index_j=ncv_;
+     368             :       unsigned sizeSkip=1;
+     369          22 :       for(int l=pntrToECVsClass_.size()-1; l>=0; l--)
+     370             :       {
+     371          12 :         const unsigned dim_l=pntrToECVsClass_[l]->getNumberOfArguments();
+     372          12 :         index_j-=dim_l;
+     373          12 :         std::vector<std::string> lambdas_l(1);
+     374          12 :         lambdas_l[0]=getLambdaName(deltaF_name_[0],index_j,dim_l);
+     375         523 :         for(unsigned i=sizeSkip; i<deltaF_size_; i+=sizeSkip)
+     376             :         {
+     377         513 :           std::string tmp_lambda=getLambdaName(deltaF_name_[i],index_j,dim_l);
+     378         513 :           if(tmp_lambda==lambdas_l[0])
+     379             :             break;
+     380         511 :           lambdas_l.push_back(tmp_lambda);
+     381             :         }
+     382          12 :         pntrToECVsClass_[l]->initECVs_restart(lambdas_l);
+     383          12 :         sizeSkip*=lambdas_l.size();
+     384          12 :       }
+     385          10 :       plumed_massert(sizeSkip==deltaF_size_,"RESTART - this should not happen");
+     386          10 :       init_linkECVs(); //link ECVs and initializes index_k_
+     387          10 :       log.printf(" ->%4u DeltaFs in total\n",deltaF_size_);
+     388          10 :       obs_steps_=0; //avoid initializing again
+     389          10 :       if(stateRestart)
+     390             :       {
+     391           2 :         if(NumParallel_>1)
+     392             :         {
+     393           2 :           const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     394             :           unsigned iter=0;
+     395          34 :           for(unsigned i=start; i<start+deltaF_.size(); i++)
+     396          32 :             deltaF_[iter++]=all_deltaF_[i];
+     397             :         }
+     398             :       }
+     399             :       else //read each step
+     400             :       {
+     401           8 :         counter_=1;
+     402             :         unsigned count_lines=0;
+     403           8 :         ifile.allowIgnoredFields(); //this allows for multiple restart, but without checking for consistency between them!
+     404             :         double time;
+     405          48 :         while(ifile.scanField("time",time)) //only number of lines and last line is important
+     406             :         {
+     407             :           unsigned restart_stride;
+     408          16 :           ifile.scanField("print_stride",restart_stride);
+     409          16 :           ifile.scanField("rct",rct_);
+     410          16 :           if(NumParallel_==1)
+     411             :           {
+     412        1014 :             for(unsigned i=0; i<deltaF_size_; i++)
+     413         998 :               ifile.scanField(deltaF_name_[i],deltaF_[i]);
+     414             :           }
+     415             :           else
+     416             :           {
+     417           0 :             const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     418             :             unsigned iter=0;
+     419           0 :             for(unsigned i=start; i<start+deltaF_.size(); i++)
+     420           0 :               ifile.scanField(deltaF_name_[i],deltaF_[iter++]);
+     421             :           }
+     422          16 :           ifile.scanField();
+     423          16 :           if(count_lines>0)
+     424           8 :             counter_+=restart_stride;
+     425          16 :           count_lines++;
+     426             :         }
+     427           8 :         counter_*=NumWalkers_;
+     428           8 :         log.printf("  successfully read %u lines, up to t=%g\n",count_lines,time);
+     429             :       }
+     430          10 :       ifile.reset(false);
+     431          10 :       ifile.close();
+     432             :     }
+     433             :     else //same behaviour as METAD
+     434           0 :       plumed_merror("RESTART requested, but file '"+restartFileName+"' was not found!\n  Set RESTART=NO or provide a restart file");
+     435          10 :     if(NumWalkers_>1) //make sure that all walkers are doing the same thing
+     436             :     {
+     437           2 :       std::vector<unsigned long long> all_counter(NumWalkers_);
+     438           2 :       if(comm.Get_rank()==0)
+     439           2 :         multi_sim_comm.Allgather(counter_,all_counter);
+     440           2 :       comm.Bcast(all_counter,0);
+     441             :       bool same_number_of_steps=true;
+     442           4 :       for(unsigned w=1; w<NumWalkers_; w++)
+     443           2 :         if(all_counter[0]!=all_counter[w])
+     444             :           same_number_of_steps=false;
+     445           2 :       plumed_massert(same_number_of_steps,"RESTART - not all walkers are reading the same file!");
+     446             :     }
+     447          10 :   }
+     448          20 :   else if(restartFileName.length()>0)
+     449           0 :     log.printf(" +++ WARNING +++ the provided STATE_RFILE will be ignored, since RESTART was not requested\n");
+     450             : 
+     451             : //sync all walkers to avoid opening files before reding is over (see also METAD)
+     452          30 :   comm.Barrier();
+     453          30 :   if(comm.Get_rank()==0 && walkers_mpi)
+     454           4 :     multi_sim_comm.Barrier();
+     455             : 
+     456             : //setup DeltaFs file
+     457          30 :   deltaFsOfile_.link(*this);
+     458          30 :   if(NumWalkers_>1)
+     459             :   {
+     460           4 :     if(walker_rank_>0)
+     461             :       deltaFsFileName="/dev/null"; //only first walker writes on file
+     462           8 :     deltaFsOfile_.enforceSuffix("");
+     463             :   }
+     464          30 :   deltaFsOfile_.open(deltaFsFileName);
+     465          30 :   if(fmt.length()>0)
+     466          60 :     deltaFsOfile_.fmtField(" "+fmt);
+     467             :   deltaFsOfile_.setHeavyFlush(); //do I need it?
+     468          30 :   deltaFsOfile_.addConstantField("print_stride");
+     469          30 :   deltaFsOfile_.printField("print_stride",print_stride_);
+     470             : 
+     471             : //open file for storing state
+     472          30 :   if(wStateStride_!=0)
+     473             :   {
+     474           6 :     stateOfile_.link(*this);
+     475           6 :     if(NumWalkers_>1)
+     476             :     {
+     477           0 :       if(walker_rank_>0)
+     478             :         stateFileName="/dev/null"; //only first walker writes on file
+     479           0 :       stateOfile_.enforceSuffix("");
+     480             :     }
+     481           6 :     stateOfile_.open(stateFileName);
+     482           6 :     if(fmt.length()>0)
+     483          12 :       stateOfile_.fmtField(" "+fmt);
+     484             :   }
+     485             : 
+     486             : //add output components
+     487          30 :   if(calc_work_)
+     488             :   {
+     489          12 :     addComponent("work");
+     490          12 :     componentIsNotPeriodic("work");
+     491             :   }
+     492             : 
+     493             : //printing some info
+     494          30 :   log.printf("  updating the bias with PACE = %u\n",stride_);
+     495          30 :   log.printf("  initial unbiased OBSERVATION_STEPS = %u (in units of PACE)\n",obs_steps_);
+     496          30 :   if(wStateStride_>0)
+     497           5 :     log.printf("  state checkpoints are written on file %s every %d MD steps\n",stateFileName.c_str(),wStateStride_);
+     498          30 :   if(wStateStride_==-1)
+     499           1 :     log.printf("  state checkpoints are written on file '%s' only on CPT events (or never if MD code does define them!)\n",stateFileName.c_str());
+     500          30 :   if(walkers_mpi)
+     501           4 :     log.printf(" -- WALKERS_MPI: if multiple replicas are present, they will share the same bias via MPI\n");
+     502          30 :   if(NumWalkers_>1)
+     503             :   {
+     504           4 :     log.printf("  using multiple walkers\n");
+     505           4 :     log.printf("    number of walkers: %u\n",NumWalkers_);
+     506           4 :     log.printf("    walker rank: %u\n",walker_rank_);
+     507             :   }
+     508          30 :   int mw_warning=0;
+     509          30 :   if(!walkers_mpi && comm.Get_rank()==0 && multi_sim_comm.Get_size()>(int)NumWalkers_)
+     510           0 :     mw_warning=1;
+     511          30 :   comm.Bcast(mw_warning,0);
+     512          30 :   if(mw_warning) //log.printf messes up with comm, so never use it without Bcast!
+     513           0 :     log.printf(" +++ WARNING +++ multiple replicas will NOT communicate unless the flag WALKERS_MPI is used\n");
+     514          30 :   if(NumParallel_>1)
+     515           2 :     log.printf("  using multiple MPI processes per simulation: %u\n",NumParallel_);
+     516          30 :   if(NumOMP_>1)
+     517          25 :     log.printf("  using multiple OpenMP threads per simulation: %u\n",NumOMP_);
+     518          30 :   if(serial)
+     519           5 :     log.printf(" -- SERIAL: no loop parallelization, despite %d MPI processes and %u OpenMP threads available\n",comm.Get_size(),OpenMP::getNumThreads());
+     520          30 :   log.printf("  Bibliography: ");
+     521          60 :   log<<plumed.cite("M. Invernizzi, P.M. Piaggi, and M. Parrinello, Phys. Rev. X 10, 041034 (2020)");
+     522          30 :   log.printf("\n");
+     523          30 : }
+     524             : 
+     525        1490 : void OPESexpanded::calculate()
+     526             : {
+     527        1490 :   if(deltaF_size_==0) //no bias before initialization
+     528         325 :     return;
+     529             : 
+     530             : //get diffMax, to avoid over/underflow
+     531        1165 :   double diffMax=-std::numeric_limits<double>::max();
+     532        1165 :   #pragma omp parallel num_threads(NumOMP_)
+     533             :   {
+     534             :     #pragma omp for reduction(max:diffMax)
+     535             :     for(unsigned i=0; i<deltaF_.size(); i++)
+     536             :     {
+     537             :       diff_[i]=(-getExpansion(i)+deltaF_[i]/kbt_);
+     538             :       if(diff_[i]>diffMax)
+     539             :         diffMax=diff_[i];
+     540             :     }
+     541             :   }
+     542        1165 :   if(NumParallel_>1)
+     543         102 :     comm.Max(diffMax);
+     544             : 
+     545             : //calculate the bias and the forces
+     546        1165 :   double sum=0;
+     547        1165 :   std::vector<double> der_sum_cv(ncv_,0);
+     548        1165 :   if(NumOMP_==1)
+     549             :   {
+     550        2730 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     551             :     {
+     552        2520 :       double add_i=std::exp(diff_[i]-diffMax);
+     553        2520 :       sum+=add_i;
+     554             :       //set derivatives
+     555        6960 :       for(unsigned j=0; j<ncv_; j++)
+     556        4440 :         der_sum_cv[j]-=derECVs_[j][index_k_[i][j]]*add_i;
+     557             :     }
+     558             :   }
+     559             :   else
+     560             :   {
+     561         955 :     #pragma omp parallel num_threads(NumOMP_)
+     562             :     {
+     563             :       std::vector<double> omp_der_sum_cv(ncv_,0);
+     564             :       #pragma omp for reduction(+:sum) nowait
+     565             :       for(unsigned i=0; i<deltaF_.size(); i++)
+     566             :       {
+     567             :         double add_i=std::exp(diff_[i]-diffMax);
+     568             :         sum+=add_i;
+     569             :         //set derivatives
+     570             :         for(unsigned j=0; j<ncv_; j++)
+     571             :           omp_der_sum_cv[j]-=derECVs_[j][index_k_[i][j]]*add_i;
+     572             :       }
+     573             :       #pragma omp critical
+     574             :       for(unsigned j=0; j<ncv_; j++)
+     575             :         der_sum_cv[j]+=omp_der_sum_cv[j];
+     576             :     }
+     577             :   }
+     578        1165 :   if(NumParallel_>1)
+     579             :   { //each MPI process has part of the full deltaF_ vector, so must Sum
+     580         102 :     comm.Sum(sum);
+     581         102 :     comm.Sum(der_sum_cv);
+     582             :   }
+     583             : 
+     584             : //set bias and forces
+     585        1165 :   const double bias=-kbt_*(diffMax+std::log(sum/deltaF_size_));
+     586        1165 :   setBias(bias);
+     587        3163 :   for(unsigned j=0; j<ncv_; j++)
+     588        1998 :     setOutputForce(j,kbt_*der_sum_cv[j]/sum);
+     589             : }
+     590             : 
+     591        1490 : void OPESexpanded::update()
+     592             : {
+     593        1490 :   if(isFirstStep_) //skip very first step, as in METAD
+     594             :   {
+     595          30 :     isFirstStep_=false;
+     596          30 :     if(obs_steps_!=1) //if obs_steps_==1 go on with initialization
+     597             :       return;
+     598             :   }
+     599        1464 :   if(getStep()%stride_==0)
+     600             :   {
+     601         739 :     if(obs_steps_>0)
+     602             :     {
+     603         463 :       for(unsigned j=0; j<ncv_; j++)
+     604         304 :         obs_cvs_[counter_*ncv_+j]=getArgument(j);
+     605         159 :       counter_++;
+     606         159 :       if(counter_==obs_steps_)
+     607             :       {
+     608          20 :         log.printf("\nAction %s\n",getName().c_str());
+     609          20 :         init_fromObs();
+     610          20 :         log.printf("Finished initialization\n\n");
+     611          20 :         counter_=NumWalkers_; //all preliminary observations count 1
+     612          20 :         obs_steps_=0; //no more observation
+     613             :       }
+     614         159 :       return;
+     615             :     }
+     616             : 
+     617             :     //update averages
+     618         580 :     const double current_bias=getOutputQuantity(0); //the first value is always the bias
+     619         580 :     if(NumWalkers_==1)
+     620         500 :       updateDeltaF(current_bias);
+     621             :     else
+     622             :     {
+     623          80 :       std::vector<double> cvs(ncv_);
+     624         240 :       for(unsigned j=0; j<ncv_; j++)
+     625         160 :         cvs[j]=getArgument(j);
+     626          80 :       std::vector<double> all_bias(NumWalkers_);
+     627          80 :       std::vector<double> all_cvs(NumWalkers_*ncv_);
+     628          80 :       if(comm.Get_rank()==0)
+     629             :       {
+     630          80 :         multi_sim_comm.Allgather(current_bias,all_bias);
+     631          80 :         multi_sim_comm.Allgather(cvs,all_cvs);
+     632             :       }
+     633          80 :       comm.Bcast(all_bias,0);
+     634          80 :       comm.Bcast(all_cvs,0);
+     635         240 :       for(unsigned w=0; w<NumWalkers_; w++)
+     636             :       {
+     637             :         //calculate ECVs
+     638         160 :         unsigned index_wj=w*ncv_;
+     639         380 :         for(unsigned k=0; k<pntrToECVsClass_.size(); k++)
+     640             :         {
+     641         220 :           pntrToECVsClass_[k]->calculateECVs(&all_cvs[index_wj]);
+     642         220 :           index_wj+=pntrToECVsClass_[k]->getNumberOfArguments();
+     643             :         }
+     644         160 :         updateDeltaF(all_bias[w]);
+     645             :       }
+     646             :     }
+     647             : 
+     648             :     //write DeltaFs to file
+     649         580 :     if((counter_/NumWalkers_-1)%print_stride_==0)
+     650          44 :       printDeltaF();
+     651             : 
+     652             :     //calculate work if requested
+     653         580 :     if(calc_work_)
+     654             :     { //some copy and paste from calculate()
+     655             :       //get diffMax, to avoid over/underflow
+     656         110 :       double diffMax=-std::numeric_limits<double>::max();
+     657         110 :       #pragma omp parallel num_threads(NumOMP_)
+     658             :       {
+     659             :         #pragma omp for reduction(max:diffMax)
+     660             :         for(unsigned i=0; i<deltaF_.size(); i++)
+     661             :         {
+     662             :           diff_[i]=(-getExpansion(i)+deltaF_[i]/kbt_);
+     663             :           if(diff_[i]>diffMax)
+     664             :             diffMax=diff_[i];
+     665             :         }
+     666             :       }
+     667         110 :       if(NumParallel_>1)
+     668          50 :         comm.Max(diffMax);
+     669             :       //calculate the bias
+     670         110 :       double sum=0;
+     671         110 :       #pragma omp parallel num_threads(NumOMP_)
+     672             :       {
+     673             :         #pragma omp for reduction(+:sum) nowait
+     674             :         for(unsigned i=0; i<deltaF_.size(); i++)
+     675             :           sum+=std::exp(diff_[i]-diffMax);
+     676             :       }
+     677         110 :       if(NumParallel_>1)
+     678          50 :         comm.Sum(sum);
+     679         110 :       const double new_bias=-kbt_*(diffMax+std::log(sum/deltaF_size_));
+     680             :       //accumulate work
+     681         110 :       work_+=new_bias-current_bias;
+     682         220 :       getPntrToComponent("work")->set(work_);
+     683             :     }
+     684             :   }
+     685             : 
+     686             : //dump state if requested
+     687        1305 :   if( (wStateStride_>0 && getStep()%wStateStride_==0) || (wStateStride_==-1 && getCPT()) )
+     688          11 :     dumpStateToFile();
+     689             : }
+     690             : 
+     691          30 : void OPESexpanded::init_pntrToECVsClass()
+     692             : {
+     693          30 :   std::vector<opes::ExpansionCVs*> all_pntrToECVsClass=plumed.getActionSet().select<opes::ExpansionCVs*>();
+     694          30 :   plumed_massert(all_pntrToECVsClass.size()>0,"no Expansion CVs found");
+     695          67 :   for(unsigned j=0; j<ncv_; j++)
+     696             :   {
+     697          74 :     std::string error_notECV("all the ARGs of "+getName()+" must be Expansion Collective Variables (ECV)");
+     698          37 :     const unsigned dot_pos=getPntrToArgument(j)->getName().find(".");
+     699          37 :     plumed_massert(dot_pos<getPntrToArgument(j)->getName().size(),error_notECV+", thus contain a dot in the name");
+     700          37 :     unsigned foundECV_l=all_pntrToECVsClass.size();
+     701          44 :     for(unsigned l=0; l<all_pntrToECVsClass.size(); l++)
+     702             :     {
+     703          44 :       if(getPntrToArgument(j)->getName().substr(0,dot_pos)==all_pntrToECVsClass[l]->getLabel())
+     704             :       {
+     705             :         foundECV_l=l;
+     706          37 :         pntrToECVsClass_.push_back(all_pntrToECVsClass[l]);
+     707          37 :         std::string missing_arg="some ECV component is missing from ARG";
+     708          37 :         plumed_massert(j+all_pntrToECVsClass[l]->getNumberOfArguments()<=getNumberOfArguments(),missing_arg);
+     709          90 :         for(unsigned h=0; h<all_pntrToECVsClass[l]->getNumberOfArguments(); h++)
+     710             :         {
+     711          53 :           std::string argName=getPntrToArgument(j+h)->getName();
+     712          53 :           std::string expectedECVname=all_pntrToECVsClass[l]->getComponentsVector()[h];
+     713          53 :           plumed_massert(argName==expectedECVname,missing_arg+", or is in wrong order: given ARG="+argName+" expected ARG="+expectedECVname);
+     714             :         }
+     715          37 :         j+=all_pntrToECVsClass[l]->getNumberOfArguments()-1;
+     716             :         break;
+     717             :       }
+     718             :     }
+     719          37 :     plumed_massert(foundECV_l<all_pntrToECVsClass.size(),error_notECV);
+     720             :   }
+     721          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     722          44 :     for(unsigned ll=l+1; ll<pntrToECVsClass_.size(); ll++)
+     723           7 :       plumed_massert(pntrToECVsClass_[l]->getLabel()!=pntrToECVsClass_[ll]->getLabel(),"cannot use same ECV twice");
+     724          30 : }
+     725             : 
+     726          30 : void OPESexpanded::init_linkECVs()
+     727             : {
+     728             :   //TODO It should be possible to make all of this more straightforward (and probably also faster):
+     729             :   //     - get rid of index_k_, making it trivial for each ECV
+     730             :   //     - store the ECVs_ and derECVs_ vectors here as a contiguous vector, and use pointers in the ECV classes
+     731             :   //     Some caveats:
+     732             :   //     - ECVmultiThermalBaric has a nontrivial index_k_ to avoid duplicates. use duplicates instead
+     733             :   //     - can the ECVs be MPI parallel or it's too complicated?
+     734          30 :   plumed_massert(deltaF_size_>0,"must set deltaF_size_ before calling init_linkECVs()");
+     735          30 :   if(NumParallel_==1)
+     736          28 :     deltaF_.resize(deltaF_size_);
+     737             :   else
+     738             :   {
+     739           2 :     const unsigned extra=(rank_<(deltaF_size_%NumParallel_)?1:0);
+     740           2 :     deltaF_.resize(deltaF_size_/NumParallel_+extra);
+     741             :     //these are used when printing deltaF_ to file
+     742           2 :     all_deltaF_.resize(deltaF_size_);
+     743           2 :     all_size_.resize(NumParallel_,deltaF_size_/NumParallel_);
+     744           2 :     disp_.resize(NumParallel_);
+     745           4 :     for(unsigned r=0; r<NumParallel_-1; r++)
+     746             :     {
+     747           2 :       if(r<deltaF_size_%NumParallel_)
+     748           0 :         all_size_[r]++;
+     749           2 :       disp_[r+1]=disp_[r]+all_size_[r];
+     750             :     }
+     751             :   }
+     752          30 :   diff_.resize(deltaF_.size());
+     753          30 :   ECVs_.resize(ncv_);
+     754          30 :   derECVs_.resize(ncv_);
+     755          30 :   index_k_.resize(deltaF_.size(),std::vector<unsigned>(ncv_));
+     756             :   unsigned index_j=0;
+     757          30 :   unsigned sizeSkip=deltaF_size_;
+     758          67 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     759             :   {
+     760          37 :     std::vector< std::vector<unsigned> > l_index_k(pntrToECVsClass_[l]->getIndex_k());
+     761          37 :     plumed_massert(deltaF_size_%l_index_k.size()==0,"buggy ECV: mismatch between getTotNumECVs() and getIndex_k().size()");
+     762          37 :     plumed_massert(l_index_k[0].size()==pntrToECVsClass_[l]->getNumberOfArguments(),"buggy ECV: mismatch between number of ARG and underlying CVs");
+     763          37 :     sizeSkip/=l_index_k.size();
+     764          90 :     for(unsigned h=0; h<pntrToECVsClass_[l]->getNumberOfArguments(); h++)
+     765             :     {
+     766          53 :       ECVs_[index_j+h]=pntrToECVsClass_[l]->getPntrToECVs(h);
+     767          53 :       derECVs_[index_j+h]=pntrToECVsClass_[l]->getPntrToDerECVs(h);
+     768          53 :       if(NumParallel_==1)
+     769             :       {
+     770       45589 :         for(unsigned i=0; i<deltaF_size_; i++)
+     771       45540 :           index_k_[i][index_j+h]=l_index_k[(i/sizeSkip)%l_index_k.size()][h];
+     772             :       }
+     773             :       else
+     774             :       {
+     775           4 :         const unsigned start=(deltaF_size_/NumParallel_)*rank_+std::min(rank_,deltaF_size_%NumParallel_);
+     776             :         unsigned iter=0;
+     777          68 :         for(unsigned i=start; i<start+deltaF_.size(); i++)
+     778          64 :           index_k_[iter++][index_j+h]=l_index_k[(i/sizeSkip)%l_index_k.size()][h];
+     779             :       }
+     780             :     }
+     781          37 :     index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     782          37 :   }
+     783          30 :   plumed_massert(sizeSkip==1,"this should not happen!");
+     784          30 : }
+     785             : 
+     786          20 : void OPESexpanded::init_fromObs() //This could probably be faster and/or require less memory...
+     787             : {
+     788             : //in case of multiple walkers gather all the statistics
+     789          20 :   if(NumWalkers_>1)
+     790             :   {
+     791           2 :     std::vector<double> all_obs_cv(ncv_*obs_steps_*NumWalkers_);
+     792           2 :     if(comm.Get_rank()==0)
+     793           2 :       multi_sim_comm.Allgather(obs_cvs_,all_obs_cv);
+     794           2 :     comm.Bcast(all_obs_cv,0);
+     795           2 :     obs_cvs_=all_obs_cv; //could this lead to memory issues?
+     796           2 :     obs_steps_*=NumWalkers_;
+     797             :   }
+     798             : 
+     799             : //initialize ECVs from observations
+     800             :   unsigned index_j=0;
+     801          20 :   deltaF_size_=1;
+     802          45 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     803             :   {
+     804          25 :     pntrToECVsClass_[l]->initECVs_observ(obs_cvs_,ncv_,index_j);
+     805          25 :     deltaF_size_*=pntrToECVsClass_[l]->getTotNumECVs(); //ECVs from different exansions will be combined
+     806          25 :     index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     807             :   }
+     808          20 :   plumed_massert(index_j==getNumberOfArguments(),"mismatch between number of linked CVs and number of ARG");
+     809             : //link ECVs and initialize index_k_, mapping each deltaF to a single ECVs set
+     810          20 :   init_linkECVs();
+     811             : 
+     812             : //initialize deltaF_ from obs
+     813             : //for the first point, t=0, the ECVs are calculated by initECVs_observ, setting also any initial guess
+     814             :   index_j=0;
+     815       12379 :   for(unsigned i=0; i<deltaF_.size(); i++)
+     816       56923 :     for(unsigned j=0; j<ncv_; j++)
+     817       44564 :       deltaF_[i]+=kbt_*ECVs_[j][index_k_[i][j]];
+     818         179 :   for(unsigned t=1; t<obs_steps_; t++) //starts from t=1
+     819             :   {
+     820             :     unsigned index_j=0;
+     821         383 :     for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     822             :     {
+     823         224 :       pntrToECVsClass_[l]->calculateECVs(&obs_cvs_[t*ncv_+index_j]);
+     824         224 :       index_j+=pntrToECVsClass_[l]->getNumberOfArguments();
+     825             :     }
+     826      102677 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     827             :     {
+     828      102518 :       const double diff_i=(-getExpansion(i)+deltaF_[i]/kbt_-std::log(t));
+     829      102518 :       if(diff_i>0) //save exp from overflow
+     830       16071 :         deltaF_[i]-=kbt_*(diff_i+std::log1p(std::exp(-diff_i))+std::log1p(-1./(1.+t)));
+     831             :       else
+     832       86447 :         deltaF_[i]-=kbt_*(std::log1p(std::exp(diff_i))+std::log1p(-1./(1.+t)));
+     833             :     }
+     834             :   }
+     835             :   obs_cvs_.clear();
+     836             : 
+     837             : //set deltaF_name_
+     838          20 :   deltaF_name_.resize(deltaF_size_,"DeltaF");
+     839          20 :   unsigned sizeSkip=deltaF_size_;
+     840          45 :   for(unsigned l=0; l<pntrToECVsClass_.size(); l++)
+     841             :   {
+     842          25 :     std::vector<std::string> lambdas_l=pntrToECVsClass_[l]->getLambdas();
+     843          25 :     plumed_massert(lambdas_l.size()==pntrToECVsClass_[l]->getTotNumECVs(),"buggy ECV: mismatch between getTotNumECVs() and getLambdas().size()");
+     844          25 :     sizeSkip/=lambdas_l.size();
+     845       22457 :     for(unsigned i=0; i<deltaF_size_; i++)
+     846       44864 :       deltaF_name_[i]+="_"+lambdas_l[(i/sizeSkip)%lambdas_l.size()];
+     847          25 :   }
+     848             : 
+     849             : //print initialization to file
+     850          20 :   log.printf(" ->%4u DeltaFs in total\n",deltaF_size_);
+     851          20 :   printDeltaF();
+     852          20 : }
+     853             : 
+     854          64 : void OPESexpanded::printDeltaF()
+     855             : {
+     856          64 :   deltaFsOfile_.printField("time",getTime());
+     857          64 :   deltaFsOfile_.printField("rct",rct_);
+     858          64 :   if(NumParallel_==1)
+     859             :   {
+     860       23988 :     for(unsigned i=0; i<deltaF_.size(); i++)
+     861       23926 :       deltaFsOfile_.printField(deltaF_name_[i],deltaF_[i]);
+     862             :   }
+     863             :   else
+     864             :   {
+     865           2 :     comm.Allgatherv(deltaF_,all_deltaF_,&all_size_[0],&disp_[0]); //can we avoid using this big vector?
+     866          66 :     for(unsigned i=0; i<deltaF_size_; i++)
+     867          64 :       deltaFsOfile_.printField(deltaF_name_[i],all_deltaF_[i]);
+     868             :   }
+     869          64 :   deltaFsOfile_.printField();
+     870          64 : }
+     871             : 
+     872          11 : void OPESexpanded::dumpStateToFile()
+     873             : {
+     874             : //rewrite header or rewind file
+     875          11 :   if(storeOldStates_)
+     876           3 :     stateOfile_.clearFields();
+     877           8 :   else if(walker_rank_==0)
+     878           8 :     stateOfile_.rewind();
+     879             : //define fields
+     880          11 :   stateOfile_.addConstantField("time");
+     881          11 :   stateOfile_.addConstantField("counter");
+     882          11 :   stateOfile_.addConstantField("rct");
+     883             : //print
+     884          11 :   stateOfile_.printField("time",getTime());
+     885          11 :   stateOfile_.printField("counter",counter_);
+     886          11 :   stateOfile_.printField("rct",rct_);
+     887          11 :   if(NumParallel_>1)
+     888           0 :     comm.Allgatherv(deltaF_,all_deltaF_,&all_size_[0],&disp_[0]); //can we avoid using this big vector?
+     889         240 :   for(unsigned i=0; i<deltaF_size_; i++)
+     890             :   {
+     891             :     std::size_t pos_start=7; //skip "DeltaF_"
+     892         687 :     for(unsigned j=0; j<ncv_; j++)
+     893             :     {
+     894             :       plumed_dbg_massert(pos_start>6,"not enought _ in deltaF_name_"+std::to_string(i-1)+" string?");
+     895         458 :       const std::size_t pos_end=deltaF_name_[i].find("_",pos_start);
+     896         916 :       stateOfile_.printField(getPntrToArgument(j)->getName(),"  "+deltaF_name_[i].substr(pos_start,pos_end-pos_start));
+     897         458 :       pos_start=pos_end+1;
+     898             :     }
+     899         229 :     if(NumParallel_==1)
+     900         458 :       stateOfile_.printField("DeltaF",deltaF_[i]);
+     901             :     else
+     902           0 :       stateOfile_.printField("DeltaF",all_deltaF_[i]);
+     903         229 :     stateOfile_.printField();
+     904             :   }
+     905             : //make sure file is written even if small
+     906          11 :   if(!storeOldStates_)
+     907           8 :     stateOfile_.flush();
+     908          11 : }
+     909             : 
+     910         660 : void OPESexpanded::updateDeltaF(double bias)
+     911             : {
+     912             :   plumed_dbg_massert(counter_>0,"deltaF_ must be initialized");
+     913         660 :   counter_++;
+     914         660 :   const double arg=(bias-rct_)/kbt_-std::log(counter_-1.);
+     915             :   double increment;
+     916         660 :   if(arg>0) //save exp from overflow
+     917          28 :     increment=kbt_*(arg+std::log1p(std::exp(-arg)));
+     918             :   else
+     919         632 :     increment=kbt_*(std::log1p(std::exp(arg)));
+     920         660 :   #pragma omp parallel num_threads(NumOMP_)
+     921             :   {
+     922             :     #pragma omp for
+     923             :     for(unsigned i=0; i<deltaF_.size(); i++)
+     924             :     {
+     925             :       const double diff_i=(-getExpansion(i)+(bias-rct_+deltaF_[i])/kbt_-std::log(counter_-1.));
+     926             :       if(diff_i>0) //save exp from overflow
+     927             :         deltaF_[i]+=increment-kbt_*(diff_i+std::log1p(std::exp(-diff_i)));
+     928             :       else
+     929             :         deltaF_[i]+=increment-kbt_*std::log1p(std::exp(diff_i));
+     930             :     }
+     931             :   }
+     932         660 :   rct_+=increment+kbt_*std::log1p(-1./counter_);
+     933         660 : }
+     934             : 
+     935      644469 : double OPESexpanded::getExpansion(unsigned i) const
+     936             : {
+     937             :   double expansion=0;
+     938     3003062 :   for(unsigned j=0; j<ncv_; j++)
+     939     2358593 :     expansion+=ECVs_[j][index_k_[i][j]]; //the index_k could be trivially guessed for most ECVs, but unfourtunately not all
+     940      644469 :   return expansion;
+     941             : }
+     942             : 
+     943             : }
+     944             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESmetad.cpp.func-sort-c.html b/coverage/opes/OPESmetad.cpp.func-sort-c.html new file mode 100644 index 000000000000..f9f52a8966a0 --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.func-sort-c.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESmetad.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESmetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:78882395.7 %
Date:2024-02-22 21:58:45Functions:272896.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE11updateNlistERKSt6vectorIdSaIdEE0
_ZN4PLMD4opes9OPESmetadINS0_11explorationEEC1ERKNS_13ActionOptionsE7
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE15dumpStateToFileEv8
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE15dumpStateToFileEv10
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_d106
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE12mergeKernelsERNS3_6kernelERKS4_111
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_126
_ZNK4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE148
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE18getMergeableKernelERKSt6vectorIdSaIdEEj196
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE11updateNlistERKSt6vectorIdSaIdEE250
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6kernelC2EdRKSt6vectorIdSaIdEES9_256
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE12mergeKernelsERNS3_6kernelERKS4_277
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_d277
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6updateEv357
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9calculateEv357
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_387
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_387
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_604
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE18getMergeableKernelERKSt6vectorIdSaIdEEj654
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6updateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9calculateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_754
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6kernelC2EdRKSt6vectorIdSaIdEES9_794
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_2760
_ZNK4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE5821
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESmetad.cpp.func.html b/coverage/opes/OPESmetad.cpp.func.html new file mode 100644 index 000000000000..51b7fa1db09f --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.func.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESmetad.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESmetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:78882395.7 %
Date:2024-02-22 21:58:45Functions:272896.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE11updateNlistERKSt6vectorIdSaIdEE250
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE12mergeKernelsERNS3_6kernelERKS4_277
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_2760
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE15dumpStateToFileEv10
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE16registerKeywordsERNS_8KeywordsE16
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE18getMergeableKernelERKSt6vectorIdSaIdEEj654
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_754
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6kernelC2EdRKSt6vectorIdSaIdEES9_794
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE6updateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_387
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9addKernelEdRKSt6vectorIdSaIdEES8_d277
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEE9calculateEv714
_ZN4PLMD4opes9OPESmetadINS0_11convergenceEEC1ERKNS_13ActionOptionsE14
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE11updateNlistERKSt6vectorIdSaIdEE0
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE12mergeKernelsERNS3_6kernelERKS4_111
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEERS9_SC_604
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE15dumpStateToFileEv8
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE16registerKeywordsERNS_8KeywordsE9
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE18getMergeableKernelERKSt6vectorIdSaIdEEj196
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE21getProbAndDerivativesERKSt6vectorIdSaIdEERS6_387
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6kernelC2EdRKSt6vectorIdSaIdEES9_256
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE6updateEv357
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_126
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9addKernelEdRKSt6vectorIdSaIdEES8_d106
_ZN4PLMD4opes9OPESmetadINS0_11explorationEE9calculateEv357
_ZN4PLMD4opes9OPESmetadINS0_11explorationEEC1ERKNS_13ActionOptionsE7
_ZNK4PLMD4opes9OPESmetadINS0_11convergenceEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE5821
_ZNK4PLMD4opes9OPESmetadINS0_11explorationEE14evaluateKernelERKNS3_6kernelERKSt6vectorIdSaIdEE148
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/OPESmetad.cpp.gcov.html b/coverage/opes/OPESmetad.cpp.gcov.html new file mode 100644 index 000000000000..55a58e2f3530 --- /dev/null +++ b/coverage/opes/OPESmetad.cpp.gcov.html @@ -0,0 +1,1829 @@ + + + + + + + + LCOV - plumed test coverage - opes/OPESmetad.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opes - OPESmetad.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:78882395.7 %
Date:2024-02-22 21:58:45Functions:272896.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2020-2021 of Michele Invernizzi.
+       3             : 
+       4             :    This file is part of the OPES plumed module.
+       5             : 
+       6             :    The OPES plumed module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The OPES plumed module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : #include "bias/Bias.h"
+      20             : #include "core/PlumedMain.h"
+      21             : #include "core/ActionRegister.h"
+      22             : #include "tools/Communicator.h"
+      23             : #include "tools/File.h"
+      24             : #include "tools/OpenMP.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace opes {
+      28             : 
+      29             : //+PLUMEDOC OPES_BIAS OPES_METAD
+      30             : /*
+      31             : On-the-fly probability enhanced sampling with metadynamics-like target distribution.
+      32             : 
+      33             : This On-the-fly probability enhanced sampling (\ref OPES "OPES") method with metadynamics-like target distribution is described in \cite Invernizzi2020rethinking.
+      34             : 
+      35             : This \ref OPES_METAD action samples target distributions defined via their marginal \f$p^{\text{tg}}(\mathbf{s})\f$ over some collective variables (CVs), \f$\mathbf{s}=\mathbf{s}(\mathbf{x})\f$.
+      36             : By default \ref OPES_METAD targets the well-tempered distribution, \f$p^{\text{WT}}(\mathbf{s})\propto [P(\mathbf{s})]^{1/\gamma}\f$, where \f$\gamma\f$ is known as BIASFACTOR.
+      37             : Similarly to \ref METAD, \ref OPES_METAD optimizes the bias on-the-fly, with a given PACE.
+      38             : It does so by reweighting via kernel density estimation the unbiased distribution in the CV space, \f$P(\mathbf{s})\f$.
+      39             : A compression algorithm is used to prevent the number of kernels from growing linearly with the simulation time.
+      40             : The bias at step \f$n\f$ is
+      41             : \f[
+      42             : V_n(\mathbf{s}) = (1-1/\gamma)\frac{1}{\beta}\log\left(\frac{P_n(\mathbf{s})}{Z_n}+\epsilon\right)\, .
+      43             : \f]
+      44             : See Ref.\cite Invernizzi2020rethinking for a complete description of the method.
+      45             : 
+      46             : As an intuitive picture, rather than gradually filling the metastable basins, \ref OPES_METAD quickly tries to get a coarse idea of the full free energy surface (FES), and then slowly refines its details.
+      47             : It has a fast initial exploration phase, and then becomes extremely conservative and does not significantly change the shape of the deposited bias any more, reaching a regime of quasi-static bias.
+      48             : For this reason, it is possible to use standard umbrella sampling reweighting (see \ref REWEIGHT_BIAS) to analyse the trajectory.
+      49             : At <a href="https://github.com/invemichele/opes/tree/master/postprocessing">this link</a> you can find some python scripts that work in a similar way to \ref sum_hills, but the preferred way to obtain a FES with OPES is via reweighting (see \ref opes-metad).
+      50             : The estimated \f$c(t)\f$ is printed for reference only, since it should converge to a fixed value as the bias converges.
+      51             : This \f$c(t)\f$ should NOT be used for reweighting.
+      52             : Similarly, the \f$Z_n\f$ factor is printed only for reference, and it should converge when no new region of the CV-space is explored.
+      53             : 
+      54             : Notice that \ref OPES_METAD is more sensitive to degenerate CVs than \ref METAD.
+      55             : If the employed CVs map different metastable basins onto the same CV-space region, then \ref OPES_METAD will remain stuck rather than completely reshaping the bias.
+      56             : This can be useful to diagnose problems with your collective variable.
+      57             : If it is not possible to improve the set of CVs and remove this degeneracy, then you might instead consider to use \ref OPES_METAD_EXPLORE or \ref METAD.
+      58             : In this way you will be able to obtain an estimate of the FES, but be aware that you most likely will not reach convergence and thus this estimate will be subjected to systematic errors (see e.g. Fig.3 in \cite Pietrucci2017review).
+      59             : On the contrary, if your CVs are not degenerate but only suboptimal, you should converge faster by using \ref OPES_METAD instead of \ref METAD \cite Invernizzi2020rethinking.
+      60             : 
+      61             : The parameter BARRIER should be set to be at least equal to the highest free energy barrier you wish to overcome.
+      62             : If it is much lower than that, you will not cross the barrier, if it is much higher, convergence might take a little longer.
+      63             : If the system has a basin that is clearly more stable than the others, it is better to start the simulation from there.
+      64             : 
+      65             : By default, the kernels SIGMA is adaptive, estimated from the fluctuations over ADAPTIVE_SIGMA_STRIDE simulation steps (similar to \ref METAD ADAPTIVE=DIFF, but contrary to that, no artifacts are introduced and the bias will converge to the correct one).
+      66             : However, notice that depending on the system this might not be the optimal choice for SIGMA.
+      67             : 
+      68             : You can target a uniform flat distribution by explicitly setting BIASFACTOR=inf.
+      69             : However, this should be useful only in very specific cases.
+      70             : 
+      71             : It is possible to take into account also of other bias potentials besides the one of \ref OPES_METAD during the internal reweighting for \f$P(\mathbf{s})\f$ estimation.
+      72             : To do so, one has to add those biases with the EXTRA_BIAS keyword, as in the example below.
+      73             : This allows one to define a custom target distribution by adding another bias potential equal to the desired target free energy and setting BIASFACTOR=inf (see example below).
+      74             : Another possible usage of EXTRA_BIAS is to make sure that \ref OPES_METAD does not push against another fixed bias added to restrain the CVs range (e.g. \ref UPPER_WALLS).
+      75             : 
+      76             : Through the EXCLUDED_REGION keywork, it is possible to specify a region of CV space where no kernels will be deposited.
+      77             : This can be useful for example for making sure the bias does not modify the transition region, thus allowing for rate calculation.
+      78             : See below for an example of how to use this keyword.
+      79             : 
+      80             : Restart can be done from a KERNELS file, but it might be not perfect (due to limited precision when printing kernels to file, or if adaptive SIGMA is used).
+      81             : For an exact restart you must use STATE_RFILE to read a checkpoint with all the needed info.
+      82             : To save such checkpoints, define a STATE_WFILE and choose how often to print them with STATE_WSTRIDE.
+      83             : By default this file is overwritten, but you can instead append to it using the flag STORE_STATES.
+      84             : 
+      85             : Multiple walkers are supported only with MPI communication, via the keyword WALKERS_MPI.
+      86             : 
+      87             : \par Examples
+      88             : 
+      89             : Several examples can be found on the <a href="https://www.plumed-nest.org/browse.html">PLUMED-NEST website</a>, by searching for the OPES keyword.
+      90             : The \ref opes-metad can also be useful to get started with the method.
+      91             : 
+      92             : The following is a minimal working example:
+      93             : 
+      94             : \plumedfile
+      95             : cv: DISTANCE ATOMS=1,2
+      96             : opes: OPES_METAD ARG=cv PACE=200 BARRIER=40
+      97             : PRINT STRIDE=200 FILE=COLVAR ARG=*
+      98             : \endplumedfile
+      99             : 
+     100             : Another more articulated one:
+     101             : 
+     102             : \plumedfile
+     103             : phi: TORSION ATOMS=5,7,9,15
+     104             : psi: TORSION ATOMS=7,9,15,17
+     105             : opes: OPES_METAD ...
+     106             :   FILE=Kernels.data
+     107             :   TEMP=300
+     108             :   ARG=phi,psi
+     109             :   PACE=500
+     110             :   BARRIER=50
+     111             :   SIGMA=0.15,0.15
+     112             :   SIGMA_MIN=0.01,0.01
+     113             :   STATE_RFILE=Restart.data
+     114             :   STATE_WFILE=State.data
+     115             :   STATE_WSTRIDE=500*100
+     116             :   STORE_STATES
+     117             :   WALKERS_MPI
+     118             :   NLIST
+     119             : ...
+     120             : PRINT FMT=%g STRIDE=500 FILE=Colvar.data ARG=phi,psi,opes.*
+     121             : \endplumedfile
+     122             : 
+     123             : Next is an example of how to define a custom target distribution different from the well-tempered one.
+     124             : Here we chose to focus more on the transition state, that is around \f$\phi=0\f$.
+     125             : Our target distribution is a Gaussian centered there, thus the target free energy we want to sample is a parabola, \f$F^{\text{tg}}(\mathbf{s})=-\frac{1}{\beta} \log [p^{\text{tg}}(\mathbf{s})]\f$.
+     126             : 
+     127             : \plumedfile
+     128             : phi: TORSION ATOMS=5,7,9,15
+     129             : FtgValue: CUSTOM ARG=phi PERIODIC=NO FUNC=(x/0.4)^2
+     130             : Ftg: BIASVALUE ARG=FtgValue
+     131             : opes: OPES_METAD ...
+     132             :   ARG=phi
+     133             :   PACE=500
+     134             :   BARRIER=50
+     135             :   SIGMA=0.2
+     136             :   BIASFACTOR=inf
+     137             :   EXTRA_BIAS=Ftg.bias
+     138             : ...
+     139             : PRINT FMT=%g STRIDE=500 FILE=COLVAR ARG=phi,Ftg.bias,opes.bias
+     140             : \endplumedfile
+     141             : 
+     142             : Notice that in order to reweight for the unbiased \f$P(\mathbf{s})\f$ during postprocessing, the total bias `Ftg.bias+opes.bias` must be used.
+     143             : 
+     144             : Finally, an example of how to use the EXCLUDED_REGION keyword.
+     145             : It expects a characteristic function that is different from zero in the region to be excluded.
+     146             : You can use \ref CUSTOM and a combination of the step function to define it.
+     147             : With the following input no kernel is deposited in the transition state region of alanine dipeptide, defined by the interval \f$\phi \in [-0.6, 0.7]\f$:
+     148             : 
+     149             : \plumedfile
+     150             : phi: TORSION ATOMS=5,7,9,15
+     151             : psi: TORSION ATOMS=7,9,15,17
+     152             : xx: CUSTOM PERIODIC=NO ARG=phi FUNC=step(x+0.6)-step(x-0.7)
+     153             : opes: OPES_METAD ...
+     154             :   ARG=phi,psi
+     155             :   PACE=500
+     156             :   BARRIER=30
+     157             :   EXCLUDED_REGION=xx
+     158             :   NLIST
+     159             : ...
+     160             : PRINT FMT=%g STRIDE=500 FILE=COLVAR ARG=phi,psi,xx,opes.*
+     161             : \endplumedfile
+     162             : 
+     163             : */
+     164             : //+ENDPLUMEDOC
+     165             : 
+     166             : template <class mode>
+     167             : class OPESmetad : public bias::Bias {
+     168             : 
+     169             : private:
+     170             :   bool isFirstStep_;
+     171             :   unsigned NumOMP_;
+     172             :   unsigned NumParallel_;
+     173             :   unsigned rank_;
+     174             :   unsigned NumWalkers_;
+     175             :   unsigned walker_rank_;
+     176             :   unsigned long long counter_;
+     177             :   std::size_t ncv_;
+     178             : 
+     179             :   double kbt_;
+     180             :   double biasfactor_;
+     181             :   double bias_prefactor_;
+     182             :   unsigned stride_;
+     183             :   std::vector<double> sigma0_;
+     184             :   std::vector<double> sigma_min_;
+     185             :   unsigned adaptive_sigma_stride_;
+     186             :   unsigned long long adaptive_counter_;
+     187             :   std::vector<double> av_cv_;
+     188             :   std::vector<double> av_M2_;
+     189             :   bool fixed_sigma_;
+     190             :   bool adaptive_sigma_;
+     191             :   double epsilon_;
+     192             :   double sum_weights_;
+     193             :   double sum_weights2_;
+     194             : 
+     195             :   bool no_Zed_;
+     196             :   double Zed_;
+     197             :   double KDEnorm_;
+     198             : 
+     199             :   double threshold2_;
+     200             :   bool recursive_merge_;
+     201             : //kernels are truncated diagonal Gaussians
+     202        1050 :   struct kernel
+     203             :   {
+     204             :     double height;
+     205             :     std::vector<double> center;
+     206             :     std::vector<double> sigma;
+     207        1050 :     kernel(double h, const std::vector<double>& c,const std::vector<double>& s):
+     208        1050 :       height(h),center(c),sigma(s) {}
+     209             :   };
+     210             :   double cutoff2_;
+     211             :   double val_at_cutoff_;
+     212             :   void mergeKernels(kernel&,const kernel&); //merge the second one into the first one
+     213             :   double evaluateKernel(const kernel&,const std::vector<double>&) const;
+     214             :   double evaluateKernel(const kernel&,const std::vector<double>&,std::vector<double>&,std::vector<double>&);
+     215             :   std::vector<kernel> kernels_; //all compressed kernels
+     216             :   OFile kernelsOfile_;
+     217             : //neighbour list stuff
+     218             :   bool nlist_;
+     219             :   double nlist_param_[2];
+     220             :   std::vector<unsigned> nlist_index_;
+     221             :   std::vector<double> nlist_center_;
+     222             :   std::vector<double> nlist_dev2_;
+     223             :   unsigned nlist_steps_;
+     224             :   bool nlist_update_;
+     225             :   bool nlist_pace_reset_;
+     226             : 
+     227             :   bool calc_work_;
+     228             :   double work_;
+     229             :   double old_KDEnorm_;
+     230             :   std::vector<kernel> delta_kernels_;
+     231             : 
+     232             :   Value* excluded_region_;
+     233             :   std::vector<Value*> extra_biases_;
+     234             : 
+     235             :   OFile stateOfile_;
+     236             :   int wStateStride_;
+     237             :   bool storeOldStates_;
+     238             : 
+     239             :   double getProbAndDerivatives(const std::vector<double>&,std::vector<double>&);
+     240             :   void addKernel(const double,const std::vector<double>&,const std::vector<double>&);
+     241             :   void addKernel(const double,const std::vector<double>&,const std::vector<double>&,const double); //also print to file
+     242             :   unsigned getMergeableKernel(const std::vector<double>&,const unsigned);
+     243             :   void updateNlist(const std::vector<double>&);
+     244             :   void dumpStateToFile();
+     245             : 
+     246             : public:
+     247             :   explicit OPESmetad(const ActionOptions&);
+     248             :   void calculate() override;
+     249             :   void update() override;
+     250             :   static void registerKeywords(Keywords& keys);
+     251             : };
+     252             : 
+     253             : struct convergence { static const bool explore=false; };
+     254             : typedef OPESmetad<convergence> OPESmetad_c;
+     255             : PLUMED_REGISTER_ACTION(OPESmetad_c,"OPES_METAD")
+     256             : 
+     257             : //OPES_METAD_EXPLORE is very similar from the point of view of the code,
+     258             : //but conceptually it is better to make it a separate BIAS action
+     259             : 
+     260             : //+PLUMEDOC OPES_BIAS OPES_METAD_EXPLORE
+     261             : /*
+     262             : On-the-fly probability enhanced sampling with well-tempered target distribution in exploreation mode.
+     263             : 
+     264             : On-the-fly probability enhanced sampling with well-tempered target distribution (\ref OPES "OPES") with well-tempered target distribution, exploration mode \cite Invernizzi2022explore .
+     265             : 
+     266             : This \ref OPES_METAD_EXPLORE action samples the well-tempered target distribution, that is defined via its marginal \f$p^{\text{WT}}(\mathbf{s})\propto [P(\mathbf{s})]^{1/\gamma}\f$ over some collective variables (CVs), \f$\mathbf{s}=\mathbf{s}(\mathbf{x})\f$.
+     267             : While \ref OPES_METAD does so by estimating the unbiased distribution \f$P(\mathbf{s})\f$, \ref OPES_METAD_EXPLORE instead estimates on-the-fly the target \f$p^{\text{WT}}(\mathbf{s})\f$ and uses it to define the bias.
+     268             : The bias at step \f$n\f$ is
+     269             : \f[
+     270             : V_n(\mathbf{s}) = (\gamma-1)\frac{1}{\beta}\log\left(\frac{p^{\text{WT}}_n(\mathbf{s})}{Z_n}+\epsilon\right)\, .
+     271             : \f]
+     272             : See Ref.\cite Invernizzi2022explore for a complete description of the method.
+     273             : 
+     274             : Intuitively, while \ref OPES_METAD aims at quickly converging the reweighted free energy, \ref OPES_METAD_EXPLORE aims at quickly sampling the target well-tempered distribution.
+     275             : Given enough simulation time, both will converge to the same bias potential but they do so in a qualitatively different way.
+     276             : Compared to \ref OPES_METAD, \ref OPES_METAD_EXPLORE is more similar to \ref METAD, because it allows the bias to vary significantly, thus enhancing exploration.
+     277             : This goes at the expenses of a typically slower convergence of the reweight estimate.
+     278             : \ref OPES_METAD_EXPLORE can be useful e.g.~for simulating a new system with an unknown BARRIER, or for quickly testing the effectiveness of a new CV that might be degenerate.
+     279             : 
+     280             : Similarly to \ref OPES_METAD, also \ref OPES_METAD_EXPLORE uses a kernel density estimation with the same on-the-fly compression algorithm.
+     281             : The only difference is that the kernels are not weighted, since it estimates the sampled distribution and not the reweighted unbiased one.
+     282             : 
+     283             : All the options of \ref OPES_METAD are also available in \ref OPES_METAD_EXPLORE, except for those that modify the target distribution, since only a well-tempered target is allowed in this case.
+     284             : 
+     285             : \par Examples
+     286             : 
+     287             : The following is a minimal working example:
+     288             : 
+     289             : \plumedfile
+     290             : cv: DISTANCE ATOMS=1,2
+     291             : opes: OPES_METAD_EXPLORE ARG=cv PACE=500 BARRIER=40
+     292             : PRINT STRIDE=100 FILE=COLVAR ARG=cv,opes.*
+     293             : \endplumedfile
+     294             : */
+     295             : //+ENDPLUMEDOC
+     296             : 
+     297             : struct exploration { static const bool explore=true; };
+     298             : typedef OPESmetad<exploration> OPESmetad_e;
+     299             : PLUMED_REGISTER_ACTION(OPESmetad_e,"OPES_METAD_EXPLORE")
+     300             : 
+     301             : template <class mode>
+     302          25 : void OPESmetad<mode>::registerKeywords(Keywords& keys)
+     303             : {
+     304          25 :   Bias::registerKeywords(keys);
+     305          25 :   keys.use("ARG");
+     306          50 :   keys.add("compulsory","TEMP","-1","temperature. If not set, it is taken from MD engine, but not all MD codes provide it");
+     307          50 :   keys.add("compulsory","PACE","the frequency for kernel deposition");
+     308          25 :   std::string info_sigma("the initial widths of the kernels");
+     309             :   if(mode::explore)
+     310             :     info_sigma+=", divided by the square root of gamma";
+     311             :   info_sigma+=". If not set, an adaptive sigma will be used with the given ADAPTIVE_SIGMA_STRIDE";
+     312          50 :   keys.add("compulsory","SIGMA","ADAPTIVE",info_sigma);
+     313          50 :   keys.add("compulsory","BARRIER","the free energy barrier to be overcome. It is used to set BIASFACTOR, EPSILON, and KERNEL_CUTOFF to reasonable values");
+     314          50 :   keys.add("compulsory","COMPRESSION_THRESHOLD","1","merge kernels if closer than this threshold, in units of sigma");
+     315             : //extra options
+     316          50 :   keys.add("optional","ADAPTIVE_SIGMA_STRIDE","number of steps for measuring adaptive sigma. Default is 10xPACE");
+     317          50 :   keys.add("optional","SIGMA_MIN","never reduce SIGMA below this value");
+     318          25 :   std::string info_biasfactor("the gamma bias factor used for the well-tempered target distribution. ");
+     319             :   if(mode::explore)
+     320             :     info_biasfactor+="Cannot be 'inf'";
+     321             :   else
+     322             :     info_biasfactor+="Set to 'inf' for uniform flat target";
+     323          50 :   keys.add("optional","BIASFACTOR",info_biasfactor);
+     324          50 :   keys.add("optional","EPSILON","the value of the regularization constant for the probability");
+     325          50 :   keys.add("optional","KERNEL_CUTOFF","truncate kernels at this distance, in units of sigma");
+     326          50 :   keys.add("optional","NLIST_PARAMETERS","( default=3.0,0.5 ) the two cutoff parameters for the kernels neighbor list");
+     327          50 :   keys.addFlag("NLIST",false,"use neighbor list for kernels summation, faster but experimental");
+     328          50 :   keys.addFlag("NLIST_PACE_RESET",false,"force the reset of the neighbor list at each PACE. Can be useful with WALKERS_MPI");
+     329          50 :   keys.addFlag("FIXED_SIGMA",false,"do not decrease sigma as the simulation proceeds. Can be added in a RESTART, to keep in check the number of compressed kernels");
+     330          50 :   keys.addFlag("RECURSIVE_MERGE_OFF",false,"do not recursively attempt kernel merging when a new one is added");
+     331          50 :   keys.addFlag("NO_ZED",false,"do not normalize over the explored CV space, Z_n=1");
+     332             : //kernels and state files
+     333          50 :   keys.add("compulsory","FILE","KERNELS","a file in which the list of all deposited kernels is stored");
+     334          50 :   keys.add("optional","FMT","specify format for KERNELS file");
+     335          50 :   keys.add("optional","STATE_RFILE","read from this file the compressed kernels and all the info needed to RESTART the simulation");
+     336          50 :   keys.add("optional","STATE_WFILE","write to this file the compressed kernels and all the info needed to RESTART the simulation");
+     337          50 :   keys.add("optional","STATE_WSTRIDE","number of MD steps between writing the STATE_WFILE. Default is only on CPT events (but not all MD codes set them)");
+     338          50 :   keys.addFlag("STORE_STATES",false,"append to STATE_WFILE instead of ovewriting it each time");
+     339             : //miscellaneous
+     340          50 :   keys.add("optional","EXCLUDED_REGION","kernels are not deposited when the action provided here has a nonzero value, see example above");
+     341             :   if(!mode::explore)
+     342          32 :     keys.add("optional","EXTRA_BIAS","consider also these other bias potentials for the internal reweighting. This can be used e.g. for sampling a custom target distribution (see example above)");
+     343          50 :   keys.addFlag("CALC_WORK",false,"calculate the total accumulated work done by the bias since last restart");
+     344          50 :   keys.addFlag("WALKERS_MPI",false,"switch on MPI version of multiple walkers");
+     345          50 :   keys.addFlag("SERIAL",false,"perform calculations in serial");
+     346          25 :   keys.use("RESTART");
+     347          25 :   keys.use("UPDATE_FROM");
+     348          25 :   keys.use("UPDATE_UNTIL");
+     349             : 
+     350             : //output components
+     351          50 :   keys.addOutputComponent("rct","default","estimate of c(t). \\f$\\frac{1}{\\beta}\\log \\langle e^{\\beta V} \\rangle\\f$, should become flat as the simulation converges. Do NOT use for reweighting");
+     352          50 :   keys.addOutputComponent("zed","default","estimate of Z_n. should become flat once no new CV-space region is explored");
+     353          50 :   keys.addOutputComponent("neff","default","effective sample size");
+     354          50 :   keys.addOutputComponent("nker","default","total number of compressed kernels used to represent the bias");
+     355          50 :   keys.addOutputComponent("work","CALC_WORK","total accumulated work done by the bias");
+     356          50 :   keys.addOutputComponent("nlker","NLIST","number of kernels in the neighbor list");
+     357          50 :   keys.addOutputComponent("nlsteps","NLIST","number of steps from last neighbor list update");
+     358          25 : }
+     359             : 
+     360             : template <class mode>
+     361          21 : OPESmetad<mode>::OPESmetad(const ActionOptions& ao)
+     362             :   : PLUMED_BIAS_INIT(ao)
+     363          21 :   , isFirstStep_(true)
+     364          21 :   , counter_(1)
+     365          21 :   , ncv_(getNumberOfArguments())
+     366          21 :   , Zed_(1)
+     367          21 :   , work_(0)
+     368          21 :   , excluded_region_(NULL)
+     369             : {
+     370          42 :   std::string error_in_input1("Error in input in action "+getName()+" with label "+getLabel()+": the keyword ");
+     371          21 :   std::string error_in_input2(" could not be read correctly");
+     372             : 
+     373             : //set kbt_
+     374          21 :   const double kB=getKBoltzmann();
+     375          21 :   kbt_=getkBT();
+     376             : 
+     377             : //other compulsory input
+     378          21 :   parse("PACE",stride_);
+     379             : 
+     380          21 :   double barrier=0;
+     381          21 :   parse("BARRIER",barrier);
+     382          21 :   plumed_massert(barrier>=0,"the BARRIER should be greater than zero");
+     383             : 
+     384          21 :   biasfactor_=barrier/kbt_;
+     385             :   std::string biasfactor_str;
+     386          42 :   parse("BIASFACTOR",biasfactor_str);
+     387          38 :   if(biasfactor_str=="inf" || biasfactor_str=="INF")
+     388             :   {
+     389           4 :     biasfactor_=std::numeric_limits<double>::infinity();
+     390           4 :     bias_prefactor_=1;
+     391             :   }
+     392             :   else
+     393             :   {
+     394          17 :     if(biasfactor_str.length()>0)
+     395           3 :       plumed_massert(Tools::convertNoexcept(biasfactor_str,biasfactor_),error_in_input1+"BIASFACTOR"+error_in_input2);
+     396          17 :     plumed_massert(biasfactor_>1,"BIASFACTOR must be greater than one (use 'inf' for uniform target)");
+     397          17 :     bias_prefactor_=1-1./biasfactor_;
+     398             :   }
+     399             :   if(mode::explore)
+     400             :   {
+     401           7 :     plumed_massert(!std::isinf(biasfactor_),"BIASFACTOR=inf is not compatible with EXPLORE mode");
+     402           7 :     bias_prefactor_=biasfactor_-1;
+     403             :   }
+     404             : 
+     405          21 :   adaptive_sigma_=false;
+     406          21 :   adaptive_sigma_stride_=0;
+     407          42 :   parse("ADAPTIVE_SIGMA_STRIDE",adaptive_sigma_stride_);
+     408             :   std::vector<std::string> sigma_str;
+     409          21 :   parseVector("SIGMA",sigma_str);
+     410          21 :   sigma0_.resize(ncv_);
+     411             :   double dummy;
+     412          21 :   if(sigma_str.size()==1 && !Tools::convertNoexcept(sigma_str[0],dummy))
+     413             :   {
+     414          11 :     plumed_massert(sigma_str[0]=="ADAPTIVE" || sigma_str[0]=="adaptive",error_in_input1+"SIGMA"+error_in_input2);
+     415          11 :     plumed_massert(!std::isinf(biasfactor_),"cannot use BIASFACTOR=inf with adaptive SIGMA");
+     416          11 :     adaptive_counter_=0;
+     417          11 :     if(adaptive_sigma_stride_==0)
+     418           2 :       adaptive_sigma_stride_=10*stride_; //NB: this is arbitrary, chosen from few tests
+     419          11 :     av_cv_.resize(ncv_,0);
+     420          11 :     av_M2_.resize(ncv_,0);
+     421          11 :     plumed_massert(adaptive_sigma_stride_>=stride_,"better to chose ADAPTIVE_SIGMA_STRIDE > PACE");
+     422          11 :     adaptive_sigma_=true;
+     423             :   }
+     424             :   else
+     425             :   {
+     426          10 :     plumed_massert(sigma_str.size()==ncv_,"number of SIGMA parameters does not match number of arguments");
+     427          10 :     plumed_massert(adaptive_sigma_stride_==0,"if SIGMA is not ADAPTIVE you cannot set an ADAPTIVE_SIGMA_STRIDE");
+     428          29 :     for(unsigned i=0; i<ncv_; i++)
+     429             :     {
+     430          19 :       plumed_massert(Tools::convertNoexcept(sigma_str[i],sigma0_[i]),error_in_input1+"SIGMA"+error_in_input2);
+     431             :       if(mode::explore)
+     432           6 :         sigma0_[i]*=std::sqrt(biasfactor_); //the sigma of the target is broader Ftg(s)=1/gamma*F(s)
+     433             :     }
+     434             :   }
+     435          42 :   parseVector("SIGMA_MIN",sigma_min_);
+     436          21 :   plumed_massert(sigma_min_.size()==0 || sigma_min_.size()==ncv_,"number of SIGMA_MIN does not match number of arguments");
+     437          21 :   if(sigma_min_.size()>0 && !adaptive_sigma_)
+     438             :   {
+     439           3 :     for(unsigned i=0; i<ncv_; i++)
+     440           2 :       plumed_massert(sigma_min_[i]<=sigma0_[i],"SIGMA_MIN should be smaller than SIGMA");
+     441             :   }
+     442             : 
+     443          21 :   epsilon_=std::exp(-barrier/bias_prefactor_/kbt_);
+     444          21 :   parse("EPSILON",epsilon_);
+     445          21 :   plumed_massert(epsilon_>0,"you must choose a value for EPSILON greater than zero. Is your BARRIER too high?");
+     446          21 :   sum_weights_=std::pow(epsilon_,bias_prefactor_); //to avoid NANs we start with counter_=1 and w0=exp(beta*V0)
+     447          21 :   sum_weights2_=sum_weights_*sum_weights_;
+     448             : 
+     449          21 :   double cutoff=sqrt(2.*barrier/bias_prefactor_/kbt_);
+     450             :   if(mode::explore)
+     451           7 :     cutoff=sqrt(2.*barrier/kbt_); //otherwise it is too small
+     452          21 :   parse("KERNEL_CUTOFF",cutoff);
+     453          21 :   plumed_massert(cutoff>0,"you must choose a value for KERNEL_CUTOFF greater than zero");
+     454          21 :   cutoff2_=cutoff*cutoff;
+     455          21 :   val_at_cutoff_=std::exp(-0.5*cutoff2_);
+     456             : 
+     457          21 :   threshold2_=1;
+     458          21 :   parse("COMPRESSION_THRESHOLD",threshold2_);
+     459          21 :   threshold2_*=threshold2_;
+     460          21 :   if(threshold2_!=0)
+     461          21 :     plumed_massert(threshold2_>0 && threshold2_<cutoff2_,"COMPRESSION_THRESHOLD cannot be bigger than the KERNEL_CUTOFF");
+     462             : 
+     463             : //setup neighbor list
+     464          21 :   nlist_=false;
+     465          21 :   parseFlag("NLIST",nlist_);
+     466          21 :   nlist_pace_reset_=false;
+     467          21 :   parseFlag("NLIST_PACE_RESET",nlist_pace_reset_);
+     468          21 :   if(nlist_pace_reset_)
+     469           2 :     nlist_=true;
+     470             :   std::vector<double> nlist_param;
+     471          42 :   parseVector("NLIST_PARAMETERS",nlist_param);
+     472          21 :   if(nlist_param.size()==0)
+     473             :   {
+     474          17 :     nlist_param_[0]=3.0;//*cutoff2_ -> max distance of neighbors
+     475          17 :     nlist_param_[1]=0.5;//*nlist_dev2_[i] -> condition for rebuilding
+     476             :   }
+     477             :   else
+     478             :   {
+     479           4 :     nlist_=true;
+     480           4 :     plumed_massert(nlist_param.size()==2,"two cutoff parameters are needed for the neighbor list");
+     481           4 :     plumed_massert(nlist_param[0]>1.0,"the first of NLIST_PARAMETERS must be greater than 1. The smaller the first, the smaller should be the second as well");
+     482           4 :     const double min_PARAM_1=(1.-1./std::sqrt(nlist_param[0]))+0.16;
+     483           4 :     plumed_massert(nlist_param[1]>0,"the second of NLIST_PARAMETERS must be greater than 0");
+     484           4 :     plumed_massert(nlist_param[1]<=min_PARAM_1,"the second of NLIST_PARAMETERS must be smaller to avoid systematic errors. Largest suggested value is: 1.16-1/sqrt(PARAM_0) = "+std::to_string(min_PARAM_1));
+     485           4 :     nlist_param_[0]=nlist_param[0];
+     486           4 :     nlist_param_[1]=nlist_param[1];
+     487             :   }
+     488          21 :   nlist_center_.resize(ncv_);
+     489          21 :   nlist_dev2_.resize(ncv_,0.);
+     490          21 :   nlist_steps_=0;
+     491          21 :   nlist_update_=true;
+     492             : 
+     493             : //optional stuff
+     494          21 :   no_Zed_=false;
+     495          21 :   parseFlag("NO_ZED",no_Zed_);
+     496          21 :   if(no_Zed_)
+     497             :   { //this makes it more gentle in the initial phase
+     498           6 :     sum_weights_=1;
+     499           6 :     sum_weights2_=1;
+     500             :   }
+     501          21 :   fixed_sigma_=false;
+     502          21 :   parseFlag("FIXED_SIGMA",fixed_sigma_);
+     503          21 :   bool recursive_merge_off=false;
+     504          21 :   parseFlag("RECURSIVE_MERGE_OFF",recursive_merge_off);
+     505          21 :   recursive_merge_=!recursive_merge_off;
+     506          42 :   parseFlag("CALC_WORK",calc_work_);
+     507             : 
+     508             : //options involving extra arguments
+     509             :   std::vector<Value*> args;
+     510          42 :   parseArgumentList("EXCLUDED_REGION",args);
+     511          21 :   if(args.size()>0)
+     512             :   {
+     513           2 :     plumed_massert(args.size()==1,"only one characteristic function should define the region to be excluded");
+     514           2 :     requestExtraDependencies(args);
+     515           2 :     excluded_region_=args[0];
+     516             :   }
+     517             :   if(!mode::explore)
+     518             :   {
+     519          28 :     parseArgumentList("EXTRA_BIAS",extra_biases_);
+     520          14 :     if(extra_biases_.size()>0)
+     521           2 :       requestExtraDependencies(extra_biases_);
+     522             :   }
+     523             : 
+     524             : //kernels file
+     525             :   std::string kernelsFileName;
+     526          42 :   parse("FILE",kernelsFileName);
+     527             :   std::string fmt;
+     528          42 :   parse("FMT",fmt);
+     529             : 
+     530             : //output checkpoint of current state
+     531             :   std::string restartFileName;
+     532          42 :   parse("STATE_RFILE",restartFileName);
+     533             :   std::string stateFileName;
+     534          21 :   parse("STATE_WFILE",stateFileName);
+     535          21 :   wStateStride_=0;
+     536          21 :   parse("STATE_WSTRIDE",wStateStride_);
+     537          21 :   storeOldStates_=false;
+     538          21 :   parseFlag("STORE_STATES",storeOldStates_);
+     539          21 :   if(wStateStride_!=0 || storeOldStates_)
+     540          10 :     plumed_massert(stateFileName.length()>0,"filename for storing simulation status not specified, use STATE_WFILE");
+     541          21 :   if(wStateStride_>0)
+     542          10 :     plumed_massert(wStateStride_>=(int)stride_,"STATE_WSTRIDE is in units of MD steps, thus it is suggested to use a multiple of PACE");
+     543          21 :   if(stateFileName.length()>0 && wStateStride_==0)
+     544           1 :     wStateStride_=-1;//will print only on CPT events (checkpoints set by some MD engines, like gromacs)
+     545             : 
+     546             : //multiple walkers //TODO implement also external mw for cp2k
+     547          21 :   bool walkers_mpi=false;
+     548          21 :   parseFlag("WALKERS_MPI",walkers_mpi);
+     549          21 :   if(walkers_mpi)
+     550             :   {
+     551             :     //If this Action is not compiled with MPI the user is informed and we exit gracefully
+     552          10 :     plumed_massert(Communicator::plumedHasMPI(),"Invalid walkers configuration: WALKERS_MPI flag requires MPI compilation");
+     553          10 :     plumed_massert(Communicator::initialized(),"Invalid walkers configuration: WALKERS_MPI needs the communicator correctly initialized.");
+     554             : 
+     555          10 :     if(comm.Get_rank()==0)//multi_sim_comm works on first rank only
+     556             :     {
+     557          10 :       NumWalkers_=multi_sim_comm.Get_size();
+     558          10 :       walker_rank_=multi_sim_comm.Get_rank();
+     559             :     }
+     560          10 :     comm.Bcast(NumWalkers_,0); //if each walker has more than one processor update them all
+     561          10 :     comm.Bcast(walker_rank_,0);
+     562             :   }
+     563             :   else
+     564             :   {
+     565          11 :     NumWalkers_=1;
+     566          11 :     walker_rank_=0;
+     567             :   }
+     568             : 
+     569             : //parallelization stuff
+     570          21 :   NumOMP_=OpenMP::getNumThreads();
+     571          21 :   NumParallel_=comm.Get_size();
+     572          21 :   rank_=comm.Get_rank();
+     573          21 :   bool serial=false;
+     574          21 :   parseFlag("SERIAL",serial);
+     575          21 :   if(serial)
+     576             :   {
+     577           4 :     NumOMP_=1;
+     578           4 :     NumParallel_=1;
+     579           4 :     rank_=0;
+     580             :   }
+     581             : 
+     582          21 :   checkRead();
+     583             : 
+     584             : //restart if needed
+     585             :   bool convertKernelsToState=false;
+     586          21 :   if(getRestart())
+     587             :   {
+     588             :     bool stateRestart=true;
+     589          11 :     if(restartFileName.length()==0)
+     590             :     {
+     591             :       stateRestart=false;
+     592             :       restartFileName=kernelsFileName;
+     593             :     }
+     594          11 :     IFile ifile;
+     595          11 :     ifile.link(*this);
+     596          11 :     if(ifile.FileExist(restartFileName))
+     597             :     {
+     598          11 :       bool tmp_nlist=nlist_;
+     599          11 :       nlist_=false; // NLIST is not needed while restarting
+     600          11 :       ifile.open(restartFileName);
+     601          11 :       log.printf("  RESTART - make sure all used options are compatible\n");
+     602          11 :       log.printf("    restarting from: %s\n",restartFileName.c_str());
+     603          11 :       std::string action_name=getName();
+     604          11 :       if(stateRestart)
+     605             :       {
+     606           6 :         log.printf("    it should be a STATE file (not a KERNELS file)\n");
+     607             :         action_name+="_state";
+     608             :       }
+     609             :       else
+     610             :       {
+     611           5 :         log.printf(" +++ WARNING +++ RESTART from KERNELS might be approximate, use STATE_WFILE and STATE_RFILE to restart from the exact state\n");
+     612             :         action_name+="_kernels";
+     613             :       }
+     614             :       std::string old_action_name;
+     615          11 :       ifile.scanField("action",old_action_name);
+     616          11 :       plumed_massert(action_name==old_action_name,"RESTART - mismatch between old and new action name. Expected '"+action_name+"', but found '"+old_action_name+"'");
+     617             :       std::string old_biasfactor_str;
+     618          22 :       ifile.scanField("biasfactor",old_biasfactor_str);
+     619          21 :       if(old_biasfactor_str=="inf" || old_biasfactor_str=="INF")
+     620             :       {
+     621           1 :         if(!std::isinf(biasfactor_))
+     622           0 :           log.printf(" +++ WARNING +++ previous bias factor was inf while now it is %g\n",biasfactor_);
+     623             :       }
+     624             :       else
+     625             :       {
+     626             :         double old_biasfactor;
+     627          10 :         ifile.scanField("biasfactor",old_biasfactor);
+     628          10 :         if(std::abs(biasfactor_-old_biasfactor)>1e-6*biasfactor_)
+     629           0 :           log.printf(" +++ WARNING +++ previous bias factor was %g while now it is %g. diff = %g\n",old_biasfactor,biasfactor_,biasfactor_-old_biasfactor);
+     630             :       }
+     631             :       double old_epsilon;
+     632          11 :       ifile.scanField("epsilon",old_epsilon);
+     633          11 :       if(std::abs(epsilon_-old_epsilon)>1e-6*epsilon_)
+     634           8 :         log.printf(" +++ WARNING +++ previous epsilon was %g while now it is %g. diff = %g\n",old_epsilon,epsilon_,epsilon_-old_epsilon);
+     635             :       double old_cutoff;
+     636          11 :       ifile.scanField("kernel_cutoff",old_cutoff);
+     637          11 :       if(std::abs(cutoff-old_cutoff)>1e-6*cutoff)
+     638           0 :         log.printf(" +++ WARNING +++ previous kernel_cutoff was %g while now it is %g. diff = %g\n",old_cutoff,cutoff,cutoff-old_cutoff);
+     639             :       double old_threshold;
+     640          11 :       const double threshold=sqrt(threshold2_);
+     641          11 :       ifile.scanField("compression_threshold",old_threshold);
+     642          11 :       if(std::abs(threshold-old_threshold)>1e-6*threshold)
+     643           0 :         log.printf(" +++ WARNING +++ previous compression_threshold was %g while now it is %g. diff = %g\n",old_threshold,threshold,threshold-old_threshold);
+     644          11 :       if(stateRestart)
+     645             :       {
+     646           6 :         ifile.scanField("zed",Zed_);
+     647           6 :         ifile.scanField("sum_weights",sum_weights_);
+     648           6 :         ifile.scanField("sum_weights2",sum_weights2_);
+     649           6 :         ifile.scanField("counter",counter_);
+     650           6 :         if(adaptive_sigma_)
+     651             :         {
+     652           6 :           ifile.scanField("adaptive_counter",adaptive_counter_);
+     653           6 :           if(NumWalkers_==1)
+     654             :           {
+     655           6 :             for(unsigned i=0; i<ncv_; i++)
+     656             :             {
+     657           8 :               ifile.scanField("sigma0_"+getPntrToArgument(i)->getName(),sigma0_[i]);
+     658           8 :               ifile.scanField("av_cv_"+getPntrToArgument(i)->getName(),av_cv_[i]);
+     659           8 :               ifile.scanField("av_M2_"+getPntrToArgument(i)->getName(),av_M2_[i]);
+     660             :             }
+     661             :           }
+     662             :           else
+     663             :           {
+     664          12 :             for(unsigned w=0; w<NumWalkers_; w++)
+     665          24 :               for(unsigned i=0; i<ncv_; i++)
+     666             :               {
+     667             :                 double tmp0,tmp1,tmp2;
+     668          32 :                 const std::string arg_iw=getPntrToArgument(i)->getName()+"_"+std::to_string(w);
+     669          16 :                 ifile.scanField("sigma0_"+arg_iw,tmp0);
+     670          16 :                 ifile.scanField("av_cv_"+arg_iw,tmp1);
+     671          16 :                 ifile.scanField("av_M2_"+arg_iw,tmp2);
+     672          16 :                 if(w==walker_rank_)
+     673             :                 {
+     674           8 :                   sigma0_[i]=tmp0;
+     675           8 :                   av_cv_[i]=tmp1;
+     676           8 :                   av_M2_[i]=tmp2;
+     677             :                 }
+     678             :               }
+     679             :           }
+     680             :         }
+     681             :       }
+     682          33 :       for(unsigned i=0; i<ncv_; i++)
+     683             :       {
+     684          22 :         if(getPntrToArgument(i)->isPeriodic())
+     685             :         {
+     686             :           std::string arg_min,arg_max;
+     687          22 :           getPntrToArgument(i)->getDomain(arg_min,arg_max);
+     688             :           std::string file_min,file_max;
+     689          44 :           ifile.scanField("min_"+getPntrToArgument(i)->getName(),file_min);
+     690          22 :           ifile.scanField("max_"+getPntrToArgument(i)->getName(),file_max);
+     691          22 :           plumed_massert(file_min==arg_min,"RESTART - mismatch between old and new ARG periodicity");
+     692          22 :           plumed_massert(file_max==arg_max,"RESTART - mismatch between old and new ARG periodicity");
+     693             :         }
+     694             :       }
+     695          11 :       if(stateRestart)
+     696             :       {
+     697             :         double time;
+     698          60 :         while(ifile.scanField("time",time))
+     699             :         {
+     700          24 :           std::vector<double> center(ncv_);
+     701          24 :           std::vector<double> sigma(ncv_);
+     702             :           double height;
+     703          72 :           for(unsigned i=0; i<ncv_; i++)
+     704          48 :             ifile.scanField(getPntrToArgument(i)->getName(),center[i]);
+     705          72 :           for(unsigned i=0; i<ncv_; i++)
+     706          96 :             ifile.scanField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+     707          24 :           ifile.scanField("height",height);
+     708          24 :           ifile.scanField();
+     709          24 :           kernels_.emplace_back(height,center,sigma);
+     710             :         }
+     711           6 :         log.printf("    a total of %lu kernels where read\n",kernels_.size());
+     712             :       }
+     713             :       else
+     714             :       {
+     715           5 :         ifile.allowIgnoredFields(); //this allows for multiple restart, but without checking for consistency between them!
+     716             :         double time;
+     717         270 :         while(ifile.scanField("time",time))
+     718             :         {
+     719         130 :           std::vector<double> center(ncv_);
+     720         130 :           std::vector<double> sigma(ncv_);
+     721             :           double height;
+     722             :           double logweight;
+     723         390 :           for(unsigned i=0; i<ncv_; i++)
+     724         260 :             ifile.scanField(getPntrToArgument(i)->getName(),center[i]);
+     725         390 :           for(unsigned i=0; i<ncv_; i++)
+     726         520 :             ifile.scanField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+     727         130 :           if(counter_==(1+walker_rank_) && adaptive_sigma_)
+     728           0 :             sigma0_=sigma;
+     729         130 :           ifile.scanField("height",height);
+     730         130 :           ifile.scanField("logweight",logweight);
+     731         130 :           ifile.scanField();
+     732         130 :           addKernel(height,center,sigma);
+     733         130 :           const double weight=std::exp(logweight);
+     734         130 :           sum_weights_+=weight; //this sum is slightly inaccurate, because when printing some precision is lost
+     735         130 :           sum_weights2_+=weight*weight;
+     736         130 :           counter_++;
+     737             :         }
+     738           5 :         KDEnorm_=mode::explore?counter_:sum_weights_;
+     739           5 :         if(!no_Zed_)
+     740             :         {
+     741           2 :           double sum_uprob=0;
+     742          48 :           for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+     743        1104 :             for(unsigned kk=0; kk<kernels_.size(); kk++)
+     744        1058 :               sum_uprob+=evaluateKernel(kernels_[kk],kernels_[k].center);
+     745           2 :           if(NumParallel_>1)
+     746           0 :             comm.Sum(sum_uprob);
+     747           2 :           Zed_=sum_uprob/KDEnorm_/kernels_.size();
+     748             :         }
+     749           5 :         log.printf("    a total of %llu kernels where read, and compressed to %lu\n",counter_-1,kernels_.size());
+     750             :         convertKernelsToState=true;
+     751             :       }
+     752          11 :       ifile.reset(false);
+     753          11 :       ifile.close();
+     754          11 :       nlist_=tmp_nlist;
+     755             :     }
+     756             :     else //same behaviour as METAD
+     757           0 :       plumed_merror("RESTART requested, but file '"+restartFileName+"' was not found!\n  Set RESTART=NO or provide a restart file");
+     758          11 :     if(NumWalkers_>1) //make sure that all walkers are doing the same thing
+     759             :     {
+     760           6 :       const unsigned kernels_size=kernels_.size();
+     761           6 :       std::vector<unsigned> all_kernels_size(NumWalkers_);
+     762           6 :       if(comm.Get_rank()==0)
+     763           6 :         multi_sim_comm.Allgather(kernels_size,all_kernels_size);
+     764           6 :       comm.Bcast(all_kernels_size,0);
+     765             :       bool same_number_of_kernels=true;
+     766          12 :       for(unsigned w=1; w<NumWalkers_; w++)
+     767           6 :         if(all_kernels_size[0]!=all_kernels_size[w])
+     768             :           same_number_of_kernels=false;
+     769           6 :       plumed_massert(same_number_of_kernels,"RESTART - not all walkers are reading the same file!");
+     770             :     }
+     771          11 :   }
+     772          10 :   else if(restartFileName.length()>0)
+     773           4 :     log.printf(" +++ WARNING +++ the provided STATE_RFILE will be ignored, since RESTART was not requested\n");
+     774             : 
+     775             : //sync all walkers to avoid opening files before reading is over (see also METAD)
+     776          21 :   comm.Barrier();
+     777          21 :   if(comm.Get_rank()==0 && walkers_mpi)
+     778          10 :     multi_sim_comm.Barrier();
+     779             : 
+     780             : //setup output kernels file
+     781          21 :   kernelsOfile_.link(*this);
+     782          21 :   if(NumWalkers_>1)
+     783             :   {
+     784          10 :     if(walker_rank_>0)
+     785             :       kernelsFileName="/dev/null"; //only first walker writes on file
+     786          20 :     kernelsOfile_.enforceSuffix("");
+     787             :   }
+     788          21 :   kernelsOfile_.open(kernelsFileName);
+     789          21 :   if(fmt.length()>0)
+     790          42 :     kernelsOfile_.fmtField(" "+fmt);
+     791             :   kernelsOfile_.setHeavyFlush(); //do I need it?
+     792             :   //define and set const fields
+     793          21 :   kernelsOfile_.addConstantField("action");
+     794          21 :   kernelsOfile_.addConstantField("biasfactor");
+     795          21 :   kernelsOfile_.addConstantField("epsilon");
+     796          21 :   kernelsOfile_.addConstantField("kernel_cutoff");
+     797          21 :   kernelsOfile_.addConstantField("compression_threshold");
+     798          61 :   for(unsigned i=0; i<ncv_; i++)
+     799          40 :     kernelsOfile_.setupPrintValue(getPntrToArgument(i));
+     800          42 :   kernelsOfile_.printField("action",getName()+"_kernels");
+     801          21 :   kernelsOfile_.printField("biasfactor",biasfactor_);
+     802          21 :   kernelsOfile_.printField("epsilon",epsilon_);
+     803          21 :   kernelsOfile_.printField("kernel_cutoff",sqrt(cutoff2_));
+     804          21 :   kernelsOfile_.printField("compression_threshold",sqrt(threshold2_));
+     805             : 
+     806             : //open file for storing state
+     807          21 :   if(wStateStride_!=0)
+     808             :   {
+     809          11 :     stateOfile_.link(*this);
+     810          11 :     if(NumWalkers_>1)
+     811             :     {
+     812           8 :       if(walker_rank_>0)
+     813             :         stateFileName="/dev/null"; //only first walker writes on file
+     814          16 :       stateOfile_.enforceSuffix("");
+     815             :     }
+     816          11 :     stateOfile_.open(stateFileName);
+     817          11 :     if(fmt.length()>0)
+     818          22 :       stateOfile_.fmtField(" "+fmt);
+     819          11 :     if(convertKernelsToState)
+     820           0 :       dumpStateToFile();
+     821             :   }
+     822             : 
+     823             : //set initial old values
+     824          21 :   KDEnorm_=mode::explore?counter_:sum_weights_;
+     825          21 :   old_KDEnorm_=KDEnorm_;
+     826             : 
+     827             : //add and set output components
+     828          42 :   addComponent("rct");
+     829          21 :   componentIsNotPeriodic("rct");
+     830          42 :   getPntrToComponent("rct")->set(kbt_*std::log(sum_weights_/counter_));
+     831          42 :   addComponent("zed");
+     832          21 :   componentIsNotPeriodic("zed");
+     833          42 :   getPntrToComponent("zed")->set(Zed_);
+     834          42 :   addComponent("neff");
+     835          21 :   componentIsNotPeriodic("neff");
+     836          42 :   getPntrToComponent("neff")->set(std::pow(1+sum_weights_,2)/(1+sum_weights2_));
+     837          42 :   addComponent("nker");
+     838          21 :   componentIsNotPeriodic("nker");
+     839          21 :   getPntrToComponent("nker")->set(kernels_.size());
+     840          21 :   if(calc_work_)
+     841             :   {
+     842          14 :     addComponent("work");
+     843          14 :     componentIsNotPeriodic("work");
+     844             :   }
+     845          21 :   if(nlist_)
+     846             :   {
+     847          10 :     addComponent("nlker");
+     848          10 :     componentIsNotPeriodic("nlker");
+     849          10 :     addComponent("nlsteps");
+     850          10 :     componentIsNotPeriodic("nlsteps");
+     851             :   }
+     852             : 
+     853             : //printing some info
+     854          21 :   log.printf("  temperature = %g\n",kbt_/kB);
+     855          21 :   log.printf("  beta = %g\n",1./kbt_);
+     856          21 :   log.printf("  depositing new kernels with PACE = %u\n",stride_);
+     857          21 :   log.printf("  expected BARRIER is %g\n",barrier);
+     858          21 :   log.printf("  using target distribution with BIASFACTOR gamma = %g\n",biasfactor_);
+     859          21 :   if(std::isinf(biasfactor_))
+     860           4 :     log.printf("    (thus a uniform flat target distribution, no well-tempering)\n");
+     861          21 :   if(excluded_region_!=NULL)
+     862           2 :     log.printf(" -- EXCLUDED_REGION: kernels will be deposited only when '%s' is equal to zero\n",excluded_region_->getName().c_str());
+     863          21 :   if(extra_biases_.size()>0)
+     864             :   {
+     865           2 :     log.printf(" -- EXTRA_BIAS: ");
+     866           5 :     for(unsigned e=0; e<extra_biases_.size(); e++)
+     867           3 :       log.printf("%s ",extra_biases_[e]->getName().c_str());
+     868           2 :     log.printf("will be reweighted\n");
+     869             :   }
+     870          21 :   if(adaptive_sigma_)
+     871             :   {
+     872          11 :     log.printf("  adaptive SIGMA will be used, with ADAPTIVE_SIGMA_STRIDE = %u\n",adaptive_sigma_stride_);
+     873          11 :     unsigned x=std::ceil(adaptive_sigma_stride_/stride_);
+     874          11 :     log.printf("    thus the first x kernel depositions will be skipped, x = ADAPTIVE_SIGMA_STRIDE/PACE = %u\n",x);
+     875             :   }
+     876             :   else
+     877             :   {
+     878          10 :     log.printf("  kernels have initial SIGMA = ");
+     879          29 :     for(unsigned i=0; i<ncv_; i++)
+     880          19 :       log.printf(" %g",sigma0_[i]);
+     881          10 :     log.printf("\n");
+     882             :   }
+     883          21 :   if(sigma_min_.size()>0)
+     884             :   {
+     885           3 :     log.printf("  kernels have a SIGMA_MIN = ");
+     886           9 :     for(unsigned i=0; i<ncv_; i++)
+     887           6 :       log.printf(" %g",sigma_min_[i]);
+     888           3 :     log.printf("\n");
+     889             :   }
+     890          21 :   if(fixed_sigma_)
+     891           6 :     log.printf(" -- FIXED_SIGMA: sigma will not decrease as the simulation proceeds\n");
+     892          21 :   log.printf("  kernels are truncated with KERNELS_CUTOFF = %g\n",cutoff);
+     893          21 :   if(cutoff<3.5)
+     894           0 :     log.printf(" +++ WARNING +++ probably kernels are truncated too much\n");
+     895          21 :   log.printf("  the value at cutoff is = %g\n",val_at_cutoff_);
+     896          21 :   log.printf("  regularization EPSILON = %g\n",epsilon_);
+     897          21 :   if(val_at_cutoff_>epsilon_*(1+1e-6))
+     898           0 :     log.printf(" +++ WARNING +++ the KERNEL_CUTOFF might be too small for the given EPSILON\n");
+     899          21 :   log.printf("  kernels will be compressed when closer than COMPRESSION_THRESHOLD = %g\n",sqrt(threshold2_));
+     900          21 :   if(threshold2_==0)
+     901           0 :     log.printf(" +++ WARNING +++ kernels will never merge, expect slowdowns\n");
+     902          21 :   if(!recursive_merge_)
+     903           6 :     log.printf(" -- RECURSIVE_MERGE_OFF: only one merge for each new kernel will be attempted. This is faster only if total number of kernels does not grow too much\n");
+     904          21 :   if(nlist_)
+     905           5 :     log.printf(" -- NLIST: using neighbor list for kernels, with parameters: %g,%g\n",nlist_param_[0],nlist_param_[1]);
+     906          21 :   if(nlist_pace_reset_)
+     907           2 :     log.printf(" -- NLIST_PACE_RESET: forcing the neighbor list to update every PACE\n");
+     908          21 :   if(no_Zed_)
+     909           6 :     log.printf(" -- NO_ZED: using fixed normalization factor = %g\n",Zed_);
+     910          21 :   if(wStateStride_>0)
+     911          10 :     log.printf("  state checkpoints are written on file %s every %d MD steps\n",stateFileName.c_str(),wStateStride_);
+     912          21 :   if(wStateStride_==-1)
+     913           1 :     log.printf("  state checkpoints are written on file %s only on CPT events (or never if MD code does define them!)\n",stateFileName.c_str());
+     914          21 :   if(walkers_mpi)
+     915          10 :     log.printf(" -- WALKERS_MPI: if multiple replicas are present, they will share the same bias via MPI\n");
+     916          21 :   if(NumWalkers_>1)
+     917             :   {
+     918          10 :     log.printf("  using multiple walkers\n");
+     919          10 :     log.printf("    number of walkers: %u\n",NumWalkers_);
+     920          10 :     log.printf("    walker rank: %u\n",walker_rank_);
+     921             :   }
+     922          21 :   int mw_warning=0;
+     923          21 :   if(!walkers_mpi && comm.Get_rank()==0 && multi_sim_comm.Get_size()>(int)NumWalkers_)
+     924           0 :     mw_warning=1;
+     925          21 :   comm.Bcast(mw_warning,0);
+     926          21 :   if(mw_warning) //log.printf messes up with comm, so never use it without Bcast!
+     927           0 :     log.printf(" +++ WARNING +++ multiple replicas will NOT communicate unless the flag WALKERS_MPI is used\n");
+     928          21 :   if(NumParallel_>1)
+     929           4 :     log.printf("  using multiple MPI processes per simulation: %u\n",NumParallel_);
+     930          21 :   if(NumOMP_>1)
+     931          17 :     log.printf("  using multiple OpenMP threads per simulation: %u\n",NumOMP_);
+     932          21 :   if(serial)
+     933           4 :     log.printf(" -- SERIAL: no loop parallelization, despite %d MPI processes and %u OpenMP threads available\n",comm.Get_size(),OpenMP::getNumThreads());
+     934          21 :   log.printf("  Bibliography: ");
+     935          42 :   log<<plumed.cite("M. Invernizzi and M. Parrinello, J. Phys. Chem. Lett. 11, 2731-2736 (2020)");
+     936          14 :   if(mode::explore || adaptive_sigma_)
+     937          28 :     log<<plumed.cite("M. Invernizzi and M. Parrinello, J. Chem. Theory Comput. 18, 3988-3996 (2022)");
+     938          21 :   log.printf("\n");
+     939          42 : }
+     940             : 
+     941             : template <class mode>
+     942        1071 : void OPESmetad<mode>::calculate()
+     943             : {
+     944             : //get cv
+     945        1071 :   std::vector<double> cv(ncv_);
+     946        3111 :   for(unsigned i=0; i<ncv_; i++)
+     947        2040 :     cv[i]=getArgument(i);
+     948             : 
+     949             : //check neighbor list
+     950        1071 :   if(nlist_)
+     951             :   {
+     952         255 :     nlist_steps_++;
+     953         255 :     if(getExchangeStep())
+     954           0 :       nlist_update_=true;
+     955             :     else
+     956             :     {
+     957         275 :       for(unsigned i=0; i<ncv_; i++)
+     958             :       {
+     959         270 :         const double diff_i=difference(i,cv[i],nlist_center_[i]);
+     960         270 :         if(diff_i*diff_i>nlist_param_[1]*nlist_dev2_[i])
+     961             :         {
+     962         250 :           nlist_update_=true;
+     963         250 :           break;
+     964             :         }
+     965             :       }
+     966             :     }
+     967         255 :     if(nlist_update_)
+     968         250 :       updateNlist(cv);
+     969             :   }
+     970             : 
+     971             : //set bias and forces
+     972        1071 :   std::vector<double> der_prob(ncv_,0);
+     973        1071 :   const double prob=getProbAndDerivatives(cv,der_prob);
+     974        1071 :   const double bias=kbt_*bias_prefactor_*std::log(prob/Zed_+epsilon_);
+     975        1071 :   setBias(bias);
+     976        3111 :   for(unsigned i=0; i<ncv_; i++)
+     977        2040 :     setOutputForce(i,-kbt_*bias_prefactor_/(prob/Zed_+epsilon_)*der_prob[i]/Zed_);
+     978        1071 : }
+     979             : 
+     980             : template <class mode>
+     981        1071 : void OPESmetad<mode>::update()
+     982             : {
+     983        1071 :   if(isFirstStep_)//same in MetaD, useful for restarts?
+     984             :   {
+     985          21 :     isFirstStep_=false;
+     986          21 :     return;
+     987             :   }
+     988             : 
+     989             : //update variance if adaptive sigma
+     990        1050 :   if(adaptive_sigma_)
+     991             :   {
+     992         550 :     adaptive_counter_++;
+     993         550 :     unsigned tau=adaptive_sigma_stride_;
+     994         550 :     if(adaptive_counter_<adaptive_sigma_stride_)
+     995          45 :       tau=adaptive_counter_;
+     996        1600 :     for(unsigned i=0; i<ncv_; i++)
+     997             :     { //Welford's online algorithm for standard deviation
+     998             :       const double cv_i=getArgument(i);
+     999        1050 :       const double diff_i=difference(i,av_cv_[i],cv_i);
+    1000        1050 :       av_cv_[i]+=diff_i/tau; //exponentially decaying average
+    1001        1050 :       av_M2_[i]+=diff_i*difference(i,av_cv_[i],cv_i);
+    1002             :     }
+    1003         550 :     if(adaptive_counter_<adaptive_sigma_stride_ && counter_==1) //counter_>1 if restarting
+    1004             :       return; //do not apply bias before having measured sigma
+    1005             :   }
+    1006             : 
+    1007             : //do update
+    1008        1005 :   if(getStep()%stride_==0 && (excluded_region_==NULL || excluded_region_->get()==0))
+    1009             :   {
+    1010         257 :     old_KDEnorm_=KDEnorm_;
+    1011         257 :     delta_kernels_.clear();
+    1012         257 :     unsigned old_nker=kernels_.size();
+    1013             : 
+    1014             :     //get new kernel height
+    1015         257 :     double log_weight=getOutputQuantity(0)/kbt_; //first value is always the current bias
+    1016         277 :     for(unsigned e=0; e<extra_biases_.size(); e++)
+    1017          20 :       log_weight+=extra_biases_[e]->get()/kbt_; //extra biases contribute to the weight
+    1018         257 :     double height=std::exp(log_weight);
+    1019             : 
+    1020             :     //update sum_weights_ and neff
+    1021         257 :     double sum_heights=height;
+    1022         257 :     double sum_heights2=height*height;
+    1023         257 :     if(NumWalkers_>1)
+    1024             :     {
+    1025         126 :       if(comm.Get_rank()==0)
+    1026             :       {
+    1027         126 :         multi_sim_comm.Sum(sum_heights);
+    1028         126 :         multi_sim_comm.Sum(sum_heights2);
+    1029             :       }
+    1030         126 :       comm.Bcast(sum_heights,0);
+    1031         126 :       comm.Bcast(sum_heights2,0);
+    1032             :     }
+    1033         257 :     counter_+=NumWalkers_;
+    1034         257 :     sum_weights_+=sum_heights;
+    1035         257 :     sum_weights2_+=sum_heights2;
+    1036         257 :     const double neff=std::pow(1+sum_weights_,2)/(1+sum_weights2_); //adding 1 makes it more robust at the start
+    1037         257 :     getPntrToComponent("rct")->set(kbt_*std::log(sum_weights_/counter_));
+    1038         257 :     getPntrToComponent("neff")->set(neff);
+    1039             :     if(mode::explore)
+    1040             :     {
+    1041          68 :       KDEnorm_=counter_;
+    1042          68 :       height=1; //plain KDE, bias reweight does not enter here
+    1043             :     }
+    1044             :     else
+    1045         189 :       KDEnorm_=sum_weights_;
+    1046             : 
+    1047             :     //if needed, rescale sigma and height
+    1048         257 :     std::vector<double> sigma=sigma0_;
+    1049         257 :     if(adaptive_sigma_)
+    1050             :     {
+    1051          93 :       const double factor=mode::explore?1:biasfactor_;
+    1052         131 :       if(counter_==1+NumWalkers_) //first time only
+    1053             :       {
+    1054          14 :         for(unsigned i=0; i<ncv_; i++)
+    1055           9 :           av_M2_[i]*=biasfactor_; //from unbiased, thus must be adjusted
+    1056          14 :         for(unsigned i=0; i<ncv_; i++)
+    1057           9 :           sigma0_[i]=std::sqrt(av_M2_[i]/adaptive_counter_/factor);
+    1058           5 :         if(sigma_min_.size()==0)
+    1059             :         {
+    1060          14 :           for(unsigned i=0; i<ncv_; i++)
+    1061           9 :             plumed_massert(sigma0_[i]>1e-6,"ADAPTIVE SIGMA is suspiciously small for CV i="+std::to_string(i)+"\nManually provide SIGMA or set a safe SIGMA_MIN to avoid possible issues");
+    1062             :         }
+    1063             :         else
+    1064             :         {
+    1065           0 :           for(unsigned i=0; i<ncv_; i++)
+    1066           0 :             sigma0_[i]=std::max(sigma0_[i],sigma_min_[i]);
+    1067             :         }
+    1068             :       }
+    1069         388 :       for(unsigned i=0; i<ncv_; i++)
+    1070         257 :         sigma[i]=std::sqrt(av_M2_[i]/adaptive_counter_/factor);
+    1071         131 :       if(sigma_min_.size()==0)
+    1072             :       {
+    1073         238 :         for(unsigned i=0; i<ncv_; i++)
+    1074             :         {
+    1075         157 :           if(sigma[i]<1e-6)
+    1076             :           {
+    1077           0 :             log.printf("+++ WARNING +++ the ADAPTIVE SIGMA is suspiciously small, you should set a safe SIGMA_MIN. 1e-6 will be used here\n");
+    1078           0 :             sigma[i]=1e-6;
+    1079           0 :             sigma_min_.resize(ncv_,1e-6);
+    1080             :           }
+    1081             :         }
+    1082             :       }
+    1083             :       else
+    1084             :       {
+    1085         150 :         for(unsigned i=0; i<ncv_; i++)
+    1086         100 :           sigma[i]=std::max(sigma[i],sigma_min_[i]);
+    1087             :       }
+    1088             :     }
+    1089         257 :     if(!fixed_sigma_)
+    1090             :     {
+    1091          38 :       const double size=mode::explore?counter_:neff; //for EXPLORE neff is not relevant
+    1092         197 :       const double s_rescaling=std::pow(size*(ncv_+2.)/4.,-1./(4+ncv_));
+    1093         576 :       for(unsigned i=0; i<ncv_; i++)
+    1094         379 :         sigma[i]*=s_rescaling;
+    1095         197 :       if(sigma_min_.size()>0)
+    1096             :       {
+    1097         150 :         for(unsigned i=0; i<ncv_; i++)
+    1098         100 :           sigma[i]=std::max(sigma[i],sigma_min_[i]);
+    1099             :       }
+    1100             :     }
+    1101             :     //the height should be divided by sqrt(2*pi)*sigma0_,
+    1102             :     //but this overall factor would be canceled when dividing by Zed
+    1103             :     //thus we skip it altogether, but keep any other sigma rescaling
+    1104         756 :     for(unsigned i=0; i<ncv_; i++)
+    1105         499 :       height*=(sigma0_[i]/sigma[i]);
+    1106             : 
+    1107             :     //get new kernel center
+    1108         257 :     std::vector<double> center(ncv_);
+    1109         756 :     for(unsigned i=0; i<ncv_; i++)
+    1110         499 :       center[i]=getArgument(i);
+    1111             : 
+    1112             :     //add new kernel(s)
+    1113         257 :     if(NumWalkers_==1)
+    1114         131 :       addKernel(height,center,sigma,log_weight);
+    1115             :     else
+    1116             :     {
+    1117         126 :       std::vector<double> all_height(NumWalkers_,0.0);
+    1118         126 :       std::vector<double> all_center(NumWalkers_*ncv_,0.0);
+    1119         126 :       std::vector<double> all_sigma(NumWalkers_*ncv_,0.0);
+    1120         126 :       std::vector<double> all_logweight(NumWalkers_,0.0);
+    1121         126 :       if(comm.Get_rank()==0)
+    1122             :       {
+    1123         126 :         multi_sim_comm.Allgather(height,all_height);
+    1124         126 :         multi_sim_comm.Allgather(center,all_center);
+    1125         126 :         multi_sim_comm.Allgather(sigma,all_sigma);
+    1126         126 :         multi_sim_comm.Allgather(log_weight,all_logweight);
+    1127             :       }
+    1128         126 :       comm.Bcast(all_height,0);
+    1129         126 :       comm.Bcast(all_center,0);
+    1130         126 :       comm.Bcast(all_sigma,0);
+    1131         126 :       comm.Bcast(all_logweight,0);
+    1132         126 :       if(nlist_)
+    1133             :       { //gather all the nlist_index_, so merging can be done using it
+    1134          50 :         std::vector<int> all_nlist_size(NumWalkers_);
+    1135          50 :         if(comm.Get_rank()==0)
+    1136             :         {
+    1137          50 :           all_nlist_size[walker_rank_]=nlist_index_.size();
+    1138          50 :           multi_sim_comm.Sum(all_nlist_size);
+    1139             :         }
+    1140          50 :         comm.Bcast(all_nlist_size,0);
+    1141             :         unsigned tot_size=0;
+    1142         150 :         for(unsigned w=0; w<NumWalkers_; w++)
+    1143         100 :           tot_size+=all_nlist_size[w];
+    1144          50 :         if(tot_size>0)
+    1145             :         {
+    1146          50 :           std::vector<int> disp(NumWalkers_);
+    1147         100 :           for(unsigned w=0; w<NumWalkers_-1; w++)
+    1148          50 :             disp[w+1]=disp[w]+all_nlist_size[w];
+    1149          50 :           std::vector<unsigned> all_nlist_index(tot_size);
+    1150          50 :           if(comm.Get_rank()==0)
+    1151          50 :             multi_sim_comm.Allgatherv(nlist_index_,all_nlist_index,&all_nlist_size[0],&disp[0]);
+    1152          50 :           comm.Bcast(all_nlist_index,0);
+    1153          50 :           std::set<unsigned> nlist_index_set(all_nlist_index.begin(),all_nlist_index.end()); //remove duplicates and sort
+    1154          50 :           nlist_index_.assign(nlist_index_set.begin(),nlist_index_set.end());
+    1155             :         }
+    1156             :       }
+    1157         378 :       for(unsigned w=0; w<NumWalkers_; w++)
+    1158             :       {
+    1159         252 :         std::vector<double> center_w(all_center.begin()+ncv_*w,all_center.begin()+ncv_*(w+1));
+    1160         252 :         std::vector<double> sigma_w(all_sigma.begin()+ncv_*w,all_sigma.begin()+ncv_*(w+1));
+    1161         252 :         addKernel(all_height[w],center_w,sigma_w,all_logweight[w]);
+    1162             :       }
+    1163             :     }
+    1164         257 :     getPntrToComponent("nker")->set(kernels_.size());
+    1165         257 :     if(nlist_)
+    1166             :     {
+    1167         106 :       getPntrToComponent("nlker")->set(nlist_index_.size());
+    1168         106 :       if(nlist_pace_reset_)
+    1169          50 :         nlist_update_=true;
+    1170             :     }
+    1171             : 
+    1172             :     //update Zed_
+    1173         257 :     if(!no_Zed_)
+    1174             :     {
+    1175         197 :       double sum_uprob=0;
+    1176         197 :       const unsigned ks=kernels_.size();
+    1177         197 :       const unsigned ds=delta_kernels_.size();
+    1178         197 :       const bool few_kernels=(ks*ks<(3*ks*ds+2*ds*ds*NumParallel_+100)); //this seems reasonable, but is not rigorous...
+    1179         197 :       if(few_kernels) //really needed? Probably is almost always false
+    1180             :       {
+    1181         147 :         #pragma omp parallel num_threads(NumOMP_)
+    1182             :         {
+    1183             :           #pragma omp for reduction(+:sum_uprob) nowait
+    1184             :           for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1185             :             for(unsigned kk=0; kk<kernels_.size(); kk++)
+    1186             :               sum_uprob+=evaluateKernel(kernels_[kk],kernels_[k].center);
+    1187             :         }
+    1188         147 :         if(NumParallel_>1)
+    1189          50 :           comm.Sum(sum_uprob);
+    1190             :       }
+    1191             :       else
+    1192             :       {
+    1193             :         // Here instead of redoing the full summation, we add only the changes, knowing that
+    1194             :         // uprob = old_uprob + delta_uprob
+    1195             :         // and we also need to consider that in the new sum there are some novel centers and some disappeared ones
+    1196          50 :         double delta_sum_uprob=0;
+    1197          50 :         if(!nlist_)
+    1198             :         {
+    1199           0 :           #pragma omp parallel num_threads(NumOMP_)
+    1200             :           {
+    1201             :             #pragma omp for reduction(+:delta_sum_uprob) nowait
+    1202             :             for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1203             :             {
+    1204             :               for(unsigned d=0; d<delta_kernels_.size(); d++)
+    1205             :               {
+    1206             :                 const double sign=delta_kernels_[d].height<0?-1:1; //take away contribution from kernels that are gone, and add the one from new ones
+    1207             :                 delta_sum_uprob+=evaluateKernel(delta_kernels_[d],kernels_[k].center)+sign*evaluateKernel(kernels_[k],delta_kernels_[d].center);
+    1208             :               }
+    1209             :             }
+    1210             :           }
+    1211             :         }
+    1212             :         else
+    1213             :         {
+    1214          50 :           #pragma omp parallel num_threads(NumOMP_)
+    1215             :           {
+    1216             :             #pragma omp for reduction(+:delta_sum_uprob) nowait
+    1217             :             for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1218             :             {
+    1219             :               const unsigned k=nlist_index_[nk];
+    1220             :               for(unsigned d=0; d<delta_kernels_.size(); d++)
+    1221             :               {
+    1222             :                 const double sign=delta_kernels_[d].height<0?-1:1; //take away contribution from kernels that are gone, and add the one from new ones
+    1223             :                 delta_sum_uprob+=evaluateKernel(delta_kernels_[d],kernels_[k].center)+sign*evaluateKernel(kernels_[k],delta_kernels_[d].center);
+    1224             :               }
+    1225             :             }
+    1226             :           }
+    1227             :         }
+    1228          50 :         if(NumParallel_>1)
+    1229           0 :           comm.Sum(delta_sum_uprob);
+    1230          50 :         #pragma omp parallel num_threads(NumOMP_)
+    1231             :         {
+    1232             :           #pragma omp for reduction(+:delta_sum_uprob)
+    1233             :           for(unsigned d=0; d<delta_kernels_.size(); d++)
+    1234             :           {
+    1235             :             for(unsigned dd=0; dd<delta_kernels_.size(); dd++)
+    1236             :             { //now subtract the delta_uprob added before, but not needed
+    1237             :               const double sign=delta_kernels_[d].height<0?-1:1;
+    1238             :               delta_sum_uprob-=sign*evaluateKernel(delta_kernels_[dd],delta_kernels_[d].center);
+    1239             :             }
+    1240             :           }
+    1241             :         }
+    1242          50 :         sum_uprob=Zed_*old_KDEnorm_*old_nker+delta_sum_uprob;
+    1243             :       }
+    1244         197 :       Zed_=sum_uprob/KDEnorm_/kernels_.size();
+    1245         394 :       getPntrToComponent("zed")->set(Zed_);
+    1246             :     }
+    1247             : 
+    1248             :     //calculate work if requested
+    1249         257 :     if(calc_work_)
+    1250             :     {
+    1251          70 :       std::vector<double> dummy(ncv_); //derivatives are not actually needed
+    1252          70 :       const double prob=getProbAndDerivatives(center,dummy);
+    1253          70 :       const double new_bias=kbt_*bias_prefactor_*std::log(prob/Zed_+epsilon_);
+    1254          70 :       work_+=new_bias-getOutputQuantity(0);
+    1255         140 :       getPntrToComponent("work")->set(work_);
+    1256             :     }
+    1257             :   }
+    1258             : 
+    1259             : //dump state if requested
+    1260        1005 :   if( (wStateStride_>0 && getStep()%wStateStride_==0) || (wStateStride_==-1 && getCPT()) )
+    1261          18 :     dumpStateToFile();
+    1262             : }
+    1263             : 
+    1264             : template <class mode>
+    1265        1141 : double OPESmetad<mode>::getProbAndDerivatives(const std::vector<double>& cv,std::vector<double>& der_prob)
+    1266             : {
+    1267        1141 :   double prob=0.0;
+    1268        1141 :   if(!nlist_)
+    1269             :   {
+    1270         886 :     if(NumOMP_==1 || (unsigned)kernels_.size()<2*NumOMP_*NumParallel_)
+    1271             :     {
+    1272             :       // for performances and thread safety
+    1273         707 :       std::vector<double> dist(ncv_);
+    1274        2647 :       for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1275        1940 :         prob+=evaluateKernel(kernels_[k],cv,der_prob,dist);
+    1276             :     }
+    1277             :     else
+    1278             :     {
+    1279         179 :       #pragma omp parallel num_threads(NumOMP_)
+    1280             :       {
+    1281             :         std::vector<double> omp_deriv(der_prob.size(),0.);
+    1282             :         // for performances and thread safety
+    1283             :         std::vector<double> dist(ncv_);
+    1284             :         #pragma omp for reduction(+:prob) nowait
+    1285             :         for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1286             :           prob+=evaluateKernel(kernels_[k],cv,omp_deriv,dist);
+    1287             :         #pragma omp critical
+    1288             :         for(unsigned i=0; i<ncv_; i++)
+    1289             :           der_prob[i]+=omp_deriv[i];
+    1290             :       }
+    1291             :     }
+    1292             :   }
+    1293             :   else
+    1294             :   {
+    1295         255 :     if(NumOMP_==1 || (unsigned)nlist_index_.size()<2*NumOMP_*NumParallel_)
+    1296             :     {
+    1297             :       // for performances and thread safety
+    1298         230 :       std::vector<double> dist(ncv_);
+    1299         660 :       for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1300         430 :         prob+=evaluateKernel(kernels_[nlist_index_[nk]],cv,der_prob,dist);
+    1301             :     }
+    1302             :     else
+    1303             :     {
+    1304          25 :       #pragma omp parallel num_threads(NumOMP_)
+    1305             :       {
+    1306             :         std::vector<double> omp_deriv(der_prob.size(),0.);
+    1307             :         // for performances and thread safety
+    1308             :         std::vector<double> dist(ncv_);
+    1309             :         #pragma omp for reduction(+:prob) nowait
+    1310             :         for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1311             :           prob+=evaluateKernel(kernels_[nlist_index_[nk]],cv,omp_deriv,dist);
+    1312             :         #pragma omp critical
+    1313             :         for(unsigned i=0; i<ncv_; i++)
+    1314             :           der_prob[i]+=omp_deriv[i];
+    1315             :       }
+    1316             :     }
+    1317             :   }
+    1318        1141 :   if(NumParallel_>1)
+    1319             :   {
+    1320         224 :     comm.Sum(prob);
+    1321         224 :     comm.Sum(der_prob);
+    1322             :   }
+    1323             : //normalize the estimate
+    1324        1141 :   prob/=KDEnorm_;
+    1325        3311 :   for(unsigned i=0; i<ncv_; i++)
+    1326        2170 :     der_prob[i]/=KDEnorm_;
+    1327             : 
+    1328        1141 :   return prob;
+    1329             : }
+    1330             : 
+    1331             : template <class mode>
+    1332         513 : void OPESmetad<mode>::addKernel(const double height,const std::vector<double>& center,const std::vector<double>& sigma)
+    1333             : {
+    1334             :   bool no_match=true;
+    1335         513 :   if(threshold2_!=0)
+    1336             :   {
+    1337         513 :     unsigned taker_k=getMergeableKernel(center,kernels_.size());
+    1338         513 :     if(taker_k<kernels_.size())
+    1339             :     {
+    1340             :       no_match=false;
+    1341         388 :       delta_kernels_.emplace_back(-1*kernels_[taker_k].height,kernels_[taker_k].center,kernels_[taker_k].sigma);
+    1342         776 :       mergeKernels(kernels_[taker_k],kernel(height,center,sigma));
+    1343         388 :       delta_kernels_.push_back(kernels_[taker_k]);
+    1344         388 :       if(recursive_merge_) //the overhead is worth it if it keeps low the total number of kernels
+    1345             :       {
+    1346             :         unsigned giver_k=taker_k;
+    1347         337 :         taker_k=getMergeableKernel(kernels_[giver_k].center,giver_k);
+    1348         337 :         while(taker_k<kernels_.size())
+    1349             :         {
+    1350           0 :           delta_kernels_.pop_back();
+    1351           0 :           delta_kernels_.emplace_back(-1*kernels_[taker_k].height,kernels_[taker_k].center,kernels_[taker_k].sigma);
+    1352           0 :           if(taker_k>giver_k) //saves time when erasing
+    1353             :             std::swap(taker_k,giver_k);
+    1354           0 :           mergeKernels(kernels_[taker_k],kernels_[giver_k]);
+    1355           0 :           delta_kernels_.push_back(kernels_[taker_k]);
+    1356           0 :           kernels_.erase(kernels_.begin()+giver_k);
+    1357           0 :           if(nlist_)
+    1358             :           {
+    1359             :             unsigned giver_nk=0;
+    1360             :             bool found_giver=false;
+    1361           0 :             for(unsigned nk=0; nk<nlist_index_.size(); nk++)
+    1362             :             {
+    1363           0 :               if(found_giver)
+    1364           0 :                 nlist_index_[nk]--; //all the indexes shift due to erase
+    1365           0 :               if(nlist_index_[nk]==giver_k)
+    1366             :               {
+    1367             :                 giver_nk=nk;
+    1368             :                 found_giver=true;
+    1369             :               }
+    1370             :             }
+    1371             :             plumed_dbg_massert(found_giver,"problem with merging and NLIST");
+    1372           0 :             nlist_index_.erase(nlist_index_.begin()+giver_nk);
+    1373             :           }
+    1374             :           giver_k=taker_k;
+    1375           0 :           taker_k=getMergeableKernel(kernels_[giver_k].center,giver_k);
+    1376             :         }
+    1377             :       }
+    1378             :     }
+    1379             :   }
+    1380             :   if(no_match)
+    1381             :   {
+    1382         125 :     kernels_.emplace_back(height,center,sigma);
+    1383         125 :     delta_kernels_.emplace_back(height,center,sigma);
+    1384         125 :     if(nlist_)
+    1385          12 :       nlist_index_.push_back(kernels_.size()-1);
+    1386             :   }
+    1387         513 : }
+    1388             : 
+    1389             : template <class mode>
+    1390         383 : void OPESmetad<mode>::addKernel(const double height,const std::vector<double>& center,const std::vector<double>& sigma,const double logweight)
+    1391             : {
+    1392         383 :   addKernel(height,center,sigma);
+    1393             : //write to file
+    1394         383 :   kernelsOfile_.printField("time",getTime());
+    1395        1134 :   for(unsigned i=0; i<ncv_; i++)
+    1396         751 :     kernelsOfile_.printField(getPntrToArgument(i),center[i]);
+    1397        1134 :   for(unsigned i=0; i<ncv_; i++)
+    1398        1502 :     kernelsOfile_.printField("sigma_"+getPntrToArgument(i)->getName(),sigma[i]);
+    1399         383 :   kernelsOfile_.printField("height",height);
+    1400         383 :   kernelsOfile_.printField("logweight",logweight);
+    1401         383 :   kernelsOfile_.printField();
+    1402         383 : }
+    1403             : 
+    1404             : template <class mode>
+    1405         850 : unsigned OPESmetad<mode>::getMergeableKernel(const std::vector<double>& giver_center,const unsigned giver_k)
+    1406             : { //returns kernels_.size() if no match is found
+    1407         850 :   unsigned min_k=kernels_.size();
+    1408         850 :   double min_norm2=threshold2_;
+    1409         850 :   if(!nlist_)
+    1410             :   {
+    1411         550 :     #pragma omp parallel num_threads(NumOMP_)
+    1412             :     {
+    1413             :       unsigned min_k_omp = min_k;
+    1414             :       double min_norm2_omp = threshold2_;
+    1415             :       #pragma omp for nowait
+    1416             :       for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1417             :       {
+    1418             :         if(k==giver_k) //a kernel should not be merged with itself
+    1419             :           continue;
+    1420             :         double norm2=0;
+    1421             :         for(unsigned i=0; i<ncv_; i++)
+    1422             :         {
+    1423             :           const double dist_i=difference(i,giver_center[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1424             :           norm2+=dist_i*dist_i;
+    1425             :           if(norm2>=min_norm2_omp)
+    1426             :             break;
+    1427             :         }
+    1428             :         if(norm2<min_norm2_omp)
+    1429             :         {
+    1430             :           min_norm2_omp=norm2;
+    1431             :           min_k_omp=k;
+    1432             :         }
+    1433             :       }
+    1434             :       #pragma omp critical
+    1435             :       {
+    1436             :         if(min_norm2_omp < min_norm2)
+    1437             :         {
+    1438             :           min_norm2 = min_norm2_omp;
+    1439             :           min_k = min_k_omp;
+    1440             :         }
+    1441             :       }
+    1442             :     }
+    1443             :   }
+    1444             :   else
+    1445             :   {
+    1446         300 :     #pragma omp parallel num_threads(NumOMP_)
+    1447             :     {
+    1448             :       unsigned min_k_omp = min_k;
+    1449             :       double min_norm2_omp = threshold2_;
+    1450             :       #pragma omp for nowait
+    1451             :       for(unsigned nk=rank_; nk<nlist_index_.size(); nk+=NumParallel_)
+    1452             :       {
+    1453             :         const unsigned k=nlist_index_[nk];
+    1454             :         if(k==giver_k) //a kernel should not be merged with itself
+    1455             :           continue;
+    1456             :         double norm2=0;
+    1457             :         for(unsigned i=0; i<ncv_; i++)
+    1458             :         {
+    1459             :           const double dist_i=difference(i,giver_center[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1460             :           norm2+=dist_i*dist_i;
+    1461             :           if(norm2>=min_norm2)
+    1462             :             break;
+    1463             :         }
+    1464             :         if(norm2<min_norm2_omp)
+    1465             :         {
+    1466             :           min_norm2_omp=norm2;
+    1467             :           min_k_omp=k;
+    1468             :         }
+    1469             :       }
+    1470             :       #pragma omp critical
+    1471             :       {
+    1472             :         if(min_norm2_omp < min_norm2)
+    1473             :         {
+    1474             :           min_norm2 = min_norm2_omp;
+    1475             :           min_k = min_k_omp;
+    1476             :         }
+    1477             :       }
+    1478             :     }
+    1479             :   }
+    1480         850 :   if(NumParallel_>1)
+    1481             :   {
+    1482         134 :     std::vector<double> all_min_norm2(NumParallel_);
+    1483         134 :     std::vector<unsigned> all_min_k(NumParallel_);
+    1484         134 :     comm.Allgather(min_norm2,all_min_norm2);
+    1485         134 :     comm.Allgather(min_k,all_min_k);
+    1486             :     const unsigned best=std::distance(std::begin(all_min_norm2),std::min_element(std::begin(all_min_norm2),std::end(all_min_norm2)));
+    1487         134 :     min_k=all_min_k[best];
+    1488             :   }
+    1489         850 :   return min_k;
+    1490             : }
+    1491             : 
+    1492             : template <class mode>
+    1493         250 : void OPESmetad<mode>::updateNlist(const std::vector<double>& new_center)
+    1494             : {
+    1495         250 :   if(kernels_.size()==0) //no need to check for neighbors
+    1496           6 :     return;
+    1497             : 
+    1498         244 :   nlist_center_=new_center;
+    1499         244 :   nlist_index_.clear();
+    1500             :   //first we gather all the nlist_index
+    1501         244 :   if(NumOMP_==1 || (unsigned)kernels_.size()<2*NumOMP_*NumParallel_)
+    1502             :   {
+    1503         198 :     for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1504             :     {
+    1505             :       double norm2_k=0;
+    1506         444 :       for(unsigned i=0; i<ncv_; i++)
+    1507             :       {
+    1508         296 :         const double dist_ik=difference(i,nlist_center_[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1509         296 :         norm2_k+=dist_ik*dist_ik;
+    1510             :       }
+    1511         148 :       if(norm2_k<=nlist_param_[0]*cutoff2_)
+    1512         104 :         nlist_index_.push_back(k);
+    1513             :     }
+    1514             :   }
+    1515             :   else
+    1516             :   {
+    1517         194 :     #pragma omp parallel num_threads(NumOMP_)
+    1518             :     {
+    1519             :       std::vector<unsigned> private_nlist_index;
+    1520             :       #pragma omp for nowait
+    1521             :       for(unsigned k=rank_; k<kernels_.size(); k+=NumParallel_)
+    1522             :       {
+    1523             :         double norm2_k=0;
+    1524             :         for(unsigned i=0; i<ncv_; i++)
+    1525             :         {
+    1526             :           const double dist_ik=difference(i,nlist_center_[i],kernels_[k].center[i])/kernels_[k].sigma[i];
+    1527             :           norm2_k+=dist_ik*dist_ik;
+    1528             :         }
+    1529             :         if(norm2_k<=nlist_param_[0]*cutoff2_)
+    1530             :           private_nlist_index.push_back(k);
+    1531             :       }
+    1532             :       #pragma omp critical
+    1533             :       nlist_index_.insert(nlist_index_.end(),private_nlist_index.begin(),private_nlist_index.end());
+    1534             :     }
+    1535         194 :     if(recursive_merge_)
+    1536         194 :       std::sort(nlist_index_.begin(),nlist_index_.end());
+    1537             :   }
+    1538         244 :   if(NumParallel_>1)
+    1539             :   {
+    1540         100 :     std::vector<int> all_nlist_size(NumParallel_);
+    1541         100 :     all_nlist_size[rank_]=nlist_index_.size();
+    1542         100 :     comm.Sum(all_nlist_size);
+    1543             :     unsigned tot_size=0;
+    1544         300 :     for(unsigned r=0; r<NumParallel_; r++)
+    1545         200 :       tot_size+=all_nlist_size[r];
+    1546         100 :     if(tot_size>0)
+    1547             :     {
+    1548         100 :       std::vector<int> disp(NumParallel_);
+    1549         200 :       for(unsigned r=0; r<NumParallel_-1; r++)
+    1550         100 :         disp[r+1]=disp[r]+all_nlist_size[r];
+    1551         100 :       std::vector<unsigned> local_nlist_index=nlist_index_;
+    1552         100 :       nlist_index_.resize(tot_size);
+    1553         100 :       comm.Allgatherv(local_nlist_index,nlist_index_,&all_nlist_size[0],&disp[0]);
+    1554         100 :       if(recursive_merge_)
+    1555         100 :         std::sort(nlist_index_.begin(),nlist_index_.end());
+    1556             :     }
+    1557             :   }
+    1558             :   //calculate the square deviation
+    1559         244 :   std::vector<double> dev2(ncv_,0.);
+    1560         773 :   for(unsigned k=rank_; k<nlist_index_.size(); k+=NumParallel_)
+    1561             :   {
+    1562        1587 :     for(unsigned i=0; i<ncv_; i++)
+    1563             :     {
+    1564        1058 :       const double diff_ik=difference(i,nlist_center_[i],kernels_[nlist_index_[k]].center[i]);
+    1565        1058 :       dev2[i]+=diff_ik*diff_ik;
+    1566             :     }
+    1567             :   }
+    1568         244 :   if(NumParallel_>1)
+    1569         100 :     comm.Sum(dev2);
+    1570         732 :   for(unsigned i=0; i<ncv_; i++)
+    1571             :   {
+    1572         488 :     if(dev2[i]==0) //e.g. if nlist_index_.size()==0
+    1573          56 :       nlist_dev2_[i]=std::pow(kernels_.back().sigma[i],2);
+    1574             :     else
+    1575         432 :       nlist_dev2_[i]=dev2[i]/nlist_index_.size();
+    1576             :   }
+    1577         244 :   getPntrToComponent("nlker")->set(nlist_index_.size());
+    1578         244 :   getPntrToComponent("nlsteps")->set(nlist_steps_);
+    1579         244 :   nlist_steps_=0;
+    1580         244 :   nlist_update_=false;
+    1581             : }
+    1582             : 
+    1583             : template <class mode>
+    1584          18 : void OPESmetad<mode>::dumpStateToFile()
+    1585             : {
+    1586             : //gather adaptive sigma info if needed
+    1587             : //doing this while writing to file can lead to misterious slowdowns
+    1588             :   std::vector<double> all_sigma0;
+    1589             :   std::vector<double> all_av_cv;
+    1590             :   std::vector<double> all_av_M2;
+    1591          18 :   if(adaptive_sigma_ && NumWalkers_>1)
+    1592             :   {
+    1593          16 :     all_sigma0.resize(NumWalkers_*ncv_);
+    1594          16 :     all_av_cv.resize(NumWalkers_*ncv_);
+    1595          16 :     all_av_M2.resize(NumWalkers_*ncv_);
+    1596          16 :     if(comm.Get_rank()==0)
+    1597             :     {
+    1598          16 :       multi_sim_comm.Allgather(sigma0_,all_sigma0);
+    1599          16 :       multi_sim_comm.Allgather(av_cv_,all_av_cv);
+    1600          16 :       multi_sim_comm.Allgather(av_M2_,all_av_M2);
+    1601             :     }
+    1602          16 :     comm.Bcast(all_sigma0,0);
+    1603          16 :     comm.Bcast(all_av_cv,0);
+    1604          16 :     comm.Bcast(all_av_M2,0);
+    1605             :   }
+    1606             : 
+    1607             : //rewrite header or rewind file
+    1608          18 :   if(storeOldStates_)
+    1609          16 :     stateOfile_.clearFields();
+    1610           2 :   else if(walker_rank_==0)
+    1611           2 :     stateOfile_.rewind();
+    1612             : //define fields
+    1613          18 :   stateOfile_.addConstantField("action");
+    1614          18 :   stateOfile_.addConstantField("biasfactor");
+    1615          18 :   stateOfile_.addConstantField("epsilon");
+    1616          18 :   stateOfile_.addConstantField("kernel_cutoff");
+    1617          18 :   stateOfile_.addConstantField("compression_threshold");
+    1618          18 :   stateOfile_.addConstantField("zed");
+    1619          18 :   stateOfile_.addConstantField("sum_weights");
+    1620          18 :   stateOfile_.addConstantField("sum_weights2");
+    1621          18 :   stateOfile_.addConstantField("counter");
+    1622          18 :   if(adaptive_sigma_)
+    1623             :   {
+    1624          18 :     stateOfile_.addConstantField("adaptive_counter");
+    1625          18 :     if(NumWalkers_==1)
+    1626             :     {
+    1627           6 :       for(unsigned i=0; i<ncv_; i++)
+    1628             :       {
+    1629           8 :         stateOfile_.addConstantField("sigma0_"+getPntrToArgument(i)->getName());
+    1630           8 :         stateOfile_.addConstantField("av_cv_"+getPntrToArgument(i)->getName());
+    1631           8 :         stateOfile_.addConstantField("av_M2_"+getPntrToArgument(i)->getName());
+    1632             :       }
+    1633             :     }
+    1634             :     else
+    1635             :     {
+    1636          48 :       for(unsigned w=0; w<NumWalkers_; w++)
+    1637          96 :         for(unsigned i=0; i<ncv_; i++)
+    1638             :         {
+    1639         128 :           const std::string arg_iw=getPntrToArgument(i)->getName()+"_"+std::to_string(w);
+    1640          64 :           stateOfile_.addConstantField("sigma0_"+arg_iw);
+    1641          64 :           stateOfile_.addConstantField("av_cv_"+arg_iw);
+    1642         128 :           stateOfile_.addConstantField("av_M2_"+arg_iw);
+    1643             :         }
+    1644             :     }
+    1645             :   }
+    1646             : //print fields
+    1647          54 :   for(unsigned i=0; i<ncv_; i++) //periodicity of CVs
+    1648          36 :     stateOfile_.setupPrintValue(getPntrToArgument(i));
+    1649          36 :   stateOfile_.printField("action",getName()+"_state");
+    1650          18 :   stateOfile_.printField("biasfactor",biasfactor_);
+    1651          18 :   stateOfile_.printField("epsilon",epsilon_);
+    1652          18 :   stateOfile_.printField("kernel_cutoff",sqrt(cutoff2_));
+    1653          18 :   stateOfile_.printField("compression_threshold",sqrt(threshold2_));
+    1654          18 :   stateOfile_.printField("zed",Zed_);
+    1655          18 :   stateOfile_.printField("sum_weights",sum_weights_);
+    1656          18 :   stateOfile_.printField("sum_weights2",sum_weights2_);
+    1657          18 :   stateOfile_.printField("counter",counter_);
+    1658          18 :   if(adaptive_sigma_)
+    1659             :   {
+    1660          18 :     stateOfile_.printField("adaptive_counter",adaptive_counter_);
+    1661          18 :     if(NumWalkers_==1)
+    1662             :     {
+    1663           6 :       for(unsigned i=0; i<ncv_; i++)
+    1664             :       {
+    1665           8 :         stateOfile_.printField("sigma0_"+getPntrToArgument(i)->getName(),sigma0_[i]);
+    1666           8 :         stateOfile_.printField("av_cv_"+getPntrToArgument(i)->getName(),av_cv_[i]);
+    1667           8 :         stateOfile_.printField("av_M2_"+getPntrToArgument(i)->getName(),av_M2_[i]);
+    1668             :       }
+    1669             :     }
+    1670             :     else
+    1671             :     {
+    1672          48 :       for(unsigned w=0; w<NumWalkers_; w++)
+    1673          96 :         for(unsigned i=0; i<ncv_; i++)
+    1674             :         {
+    1675         128 :           const std::string arg_iw=getPntrToArgument(i)->getName()+"_"+std::to_string(w);
+    1676          64 :           stateOfile_.printField("sigma0_"+arg_iw,all_sigma0[w*ncv_+i]);
+    1677          64 :           stateOfile_.printField("av_cv_"+arg_iw,all_av_cv[w*ncv_+i]);
+    1678         128 :           stateOfile_.printField("av_M2_"+arg_iw,all_av_M2[w*ncv_+i]);
+    1679             :         }
+    1680             :     }
+    1681             :   }
+    1682             : //print kernels
+    1683          82 :   for(unsigned k=0; k<kernels_.size(); k++)
+    1684             :   {
+    1685          64 :     stateOfile_.printField("time",getTime()); //this is not very usefull
+    1686         192 :     for(unsigned i=0; i<ncv_; i++)
+    1687         128 :       stateOfile_.printField(getPntrToArgument(i),kernels_[k].center[i]);
+    1688         192 :     for(unsigned i=0; i<ncv_; i++)
+    1689         256 :       stateOfile_.printField("sigma_"+getPntrToArgument(i)->getName(),kernels_[k].sigma[i]);
+    1690          64 :     stateOfile_.printField("height",kernels_[k].height);
+    1691          64 :     stateOfile_.printField();
+    1692             :   }
+    1693             : //make sure file is written even if small
+    1694          18 :   if(!storeOldStates_)
+    1695           2 :     stateOfile_.flush();
+    1696          18 : }
+    1697             : 
+    1698             : template <class mode>
+    1699        5969 : inline double OPESmetad<mode>::evaluateKernel(const kernel& G,const std::vector<double>& x) const
+    1700             : { //NB: cannot be a method of kernel class, because uses external variables (for cutoff)
+    1701             :   double norm2=0;
+    1702       13923 :   for(unsigned i=0; i<ncv_; i++)
+    1703             :   {
+    1704       10288 :     const double dist_i=difference(i,G.center[i],x[i])/G.sigma[i];
+    1705       10288 :     norm2+=dist_i*dist_i;
+    1706       10288 :     if(norm2>=cutoff2_)
+    1707             :       return 0;
+    1708             :   }
+    1709        3635 :   return G.height*(std::exp(-0.5*norm2)-val_at_cutoff_);
+    1710             : }
+    1711             : 
+    1712             : template <class mode>
+    1713        3364 : inline double OPESmetad<mode>::evaluateKernel(const kernel& G,const std::vector<double>& x, std::vector<double>& acc_der, std::vector<double>& dist)
+    1714             : { //NB: cannot be a method of kernel class, because uses external variables (for cutoff)
+    1715             :   double norm2=0;
+    1716        7483 :   for(unsigned i=0; i<ncv_; i++)
+    1717             :   {
+    1718        5578 :     dist[i]=difference(i,G.center[i],x[i])/G.sigma[i];
+    1719        5578 :     norm2+=dist[i]*dist[i];
+    1720        5578 :     if(norm2>=cutoff2_)
+    1721             :       return 0;
+    1722             :   }
+    1723        1905 :   const double val=G.height*(std::exp(-0.5*norm2)-val_at_cutoff_);
+    1724        5576 :   for(unsigned i=0; i<ncv_; i++)
+    1725        3671 :     acc_der[i]-=dist[i]/G.sigma[i]*val; //NB: we accumulate the derivative into der
+    1726             :   return val;
+    1727             : }
+    1728             : 
+    1729             : template <class mode>
+    1730         388 : inline void OPESmetad<mode>::mergeKernels(kernel& k1,const kernel& k2)
+    1731             : {
+    1732         388 :   const double h=k1.height+k2.height;
+    1733        1159 :   for(unsigned i=0; i<k1.center.size(); i++)
+    1734             :   {
+    1735         771 :     const bool isPeriodic_i=getPntrToArgument(i)->isPeriodic();
+    1736         771 :     if(isPeriodic_i)
+    1737         771 :       k1.center[i]=k2.center[i]+difference(i,k2.center[i],k1.center[i]); //fix PBC
+    1738         771 :     const double c_i=(k1.height*k1.center[i]+k2.height*k2.center[i])/h;
+    1739         771 :     const double ss_k1_part=k1.height*(k1.sigma[i]*k1.sigma[i]+k1.center[i]*k1.center[i]);
+    1740         771 :     const double ss_k2_part=k2.height*(k2.sigma[i]*k2.sigma[i]+k2.center[i]*k2.center[i]);
+    1741         771 :     const double ss_i=(ss_k1_part+ss_k2_part)/h-c_i*c_i;
+    1742         771 :     if(isPeriodic_i)
+    1743         771 :       k1.center[i]=bringBackInPbc(i,c_i);
+    1744             :     else
+    1745           0 :       k1.center[i]=c_i;
+    1746         771 :     k1.sigma[i]=sqrt(ss_i);
+    1747             :   }
+    1748         388 :   k1.height=h;
+    1749         388 : }
+    1750             : 
+    1751             : }
+    1752             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/index-sort-f.html b/coverage/opes/index-sort-f.html new file mode 100644 index 000000000000..a092742273ea --- /dev/null +++ b/coverage/opes/index-sort-f.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2142222896.1 %
Date:2024-02-22 21:58:45Functions:10811792.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ECVlinear.cpp +
95.8%95.8%
+
95.8 %114 / 11990.0 %9 / 10
ECVumbrellasFile.cpp +
98.3%98.3%
+
98.3 %118 / 12090.0 %9 / 10
ExpansionCVs.cpp +
92.3%92.3%
+
92.3 %96 / 10490.0 %9 / 10
ECVumbrellasLine.cpp +
98.5%98.5%
+
98.5 %129 / 13190.0 %9 / 10
ECVmultiThermal.cpp +
95.5%95.5%
+
95.5 %107 / 11290.0 %9 / 10
ECVcustom.cpp +
92.0%92.0%
+
92.0 %92 / 10090.9 %10 / 11
ECVmultiThermalBaric.cpp +
96.7%96.7%
+
96.7 %263 / 27291.7 %11 / 12
OPESexpanded.cpp +
97.3%97.3%
+
97.3 %431 / 44392.3 %12 / 13
OPESmetad.cpp +
95.7%95.7%
+
95.7 %788 / 82396.4 %27 / 28
ExpansionCVs.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/index-sort-l.html b/coverage/opes/index-sort-l.html new file mode 100644 index 000000000000..e6e880dbebd8 --- /dev/null +++ b/coverage/opes/index-sort-l.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2142222896.1 %
Date:2024-02-22 21:58:45Functions:10811792.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ECVcustom.cpp +
92.0%92.0%
+
92.0 %92 / 10090.9 %10 / 11
ExpansionCVs.cpp +
92.3%92.3%
+
92.3 %96 / 10490.0 %9 / 10
ECVmultiThermal.cpp +
95.5%95.5%
+
95.5 %107 / 11290.0 %9 / 10
ECVlinear.cpp +
95.8%95.8%
+
95.8 %114 / 11990.0 %9 / 10
OPESmetad.cpp +
95.7%95.7%
+
95.7 %788 / 82396.4 %27 / 28
ECVmultiThermalBaric.cpp +
96.7%96.7%
+
96.7 %263 / 27291.7 %11 / 12
OPESexpanded.cpp +
97.3%97.3%
+
97.3 %431 / 44392.3 %12 / 13
ECVumbrellasFile.cpp +
98.3%98.3%
+
98.3 %118 / 12090.0 %9 / 10
ECVumbrellasLine.cpp +
98.5%98.5%
+
98.5 %129 / 13190.0 %9 / 10
ExpansionCVs.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/opes/index.html b/coverage/opes/index.html new file mode 100644 index 000000000000..f699bd899f8f --- /dev/null +++ b/coverage/opes/index.html @@ -0,0 +1,184 @@ + + + + + + + + LCOV - plumed test coverage - opes + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - opesHitTotalCoverage
Test:plumed test coverageLines:2142222896.1 %
Date:2024-02-22 21:58:45Functions:10811792.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ECVcustom.cpp +
92.0%92.0%
+
92.0 %92 / 10090.9 %10 / 11
ECVlinear.cpp +
95.8%95.8%
+
95.8 %114 / 11990.0 %9 / 10
ECVmultiThermal.cpp +
95.5%95.5%
+
95.5 %107 / 11290.0 %9 / 10
ECVmultiThermalBaric.cpp +
96.7%96.7%
+
96.7 %263 / 27291.7 %11 / 12
ECVumbrellasFile.cpp +
98.3%98.3%
+
98.3 %118 / 12090.0 %9 / 10
ECVumbrellasLine.cpp +
98.5%98.5%
+
98.5 %129 / 13190.0 %9 / 10
ExpansionCVs.cpp +
92.3%92.3%
+
92.3 %96 / 10490.0 %9 / 10
ExpansionCVs.h +
100.0%
+
100.0 %4 / 4100.0 %3 / 3
OPESexpanded.cpp +
97.3%97.3%
+
97.3 %431 / 44392.3 %12 / 13
OPESmetad.cpp +
95.7%95.7%
+
95.7 %788 / 82396.4 %27 / 28
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammHydrogens.cpp.func-sort-c.html b/coverage/pamm/HBPammHydrogens.cpp.func-sort-c.html new file mode 100644 index 000000000000..af3789db2eed --- /dev/null +++ b/coverage/pamm/HBPammHydrogens.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammHydrogens.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammHydrogens.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:517369.9 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm15HBPammHydrogens10isPeriodicEv0
_ZN4PLMD4pamm15HBPammHydrogensC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm15HBPammHydrogensC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm15HBPammHydrogens16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD4pamm15HBPammHydrogens7computeERKjRNS_11multicolvar13AtomValuePackE134
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammHydrogens.cpp.func.html b/coverage/pamm/HBPammHydrogens.cpp.func.html new file mode 100644 index 000000000000..bb7c17f5db8c --- /dev/null +++ b/coverage/pamm/HBPammHydrogens.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammHydrogens.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammHydrogens.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:517369.9 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm15HBPammHydrogens10isPeriodicEv0
_ZN4PLMD4pamm15HBPammHydrogens16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4pamm15HBPammHydrogensC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm15HBPammHydrogensC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4pamm15HBPammHydrogens7computeERKjRNS_11multicolvar13AtomValuePackE134
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammHydrogens.cpp.gcov.html b/coverage/pamm/HBPammHydrogens.cpp.gcov.html new file mode 100644 index 000000000000..d15ca7a29549 --- /dev/null +++ b/coverage/pamm/HBPammHydrogens.cpp.gcov.html @@ -0,0 +1,268 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammHydrogens.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammHydrogens.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:517369.9 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "multicolvar/MultiColvarBase.h"
+      23             : #include "HBPammObject.h"
+      24             : #include "tools/NeighborList.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/SwitchingFunction.h"
+      27             : 
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : using namespace std;
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace pamm {
+      35             : 
+      36             : //+PLUMEDOC MCOLVAR HBPAMM_SH
+      37             : /*
+      38             : Number of HBPAMM hydrogen bonds formed by each hydrogen atom in the system
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : */
+      43             : //+ENDPLUMEDOC
+      44             : 
+      45             : 
+      46             : class HBPammHydrogens : public multicolvar::MultiColvarBase {
+      47             : private:
+      48             :   double rcut2;
+      49             :   unsigned block1upper,block2lower;
+      50             :   Matrix<HBPammObject> hbpamm_obj;
+      51             : public:
+      52             :   static void registerKeywords( Keywords& keys );
+      53             :   explicit HBPammHydrogens(const ActionOptions&);
+      54             : // active methods:
+      55             :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const override;
+      56             : /// Returns the number of coordinates of the field
+      57           0 :   bool isPeriodic() override { return false; }
+      58             : };
+      59             : 
+      60             : PLUMED_REGISTER_ACTION(HBPammHydrogens,"HBPAMM_SH")
+      61             : 
+      62           4 : void HBPammHydrogens::registerKeywords( Keywords& keys ) {
+      63           4 :   multicolvar::MultiColvarBase::registerKeywords( keys );
+      64           8 :   keys.add("atoms-1","HYDROGENS","The list of hydrogen atoms that can form part of a hydrogen bond.  The atoms must be specified using a comma separated list.");
+      65           8 :   keys.add("atoms-1","SITES","The list of atoms which can be part of a hydrogen bond.  When this command is used the set of atoms that can donate a "
+      66             :            "hydrogen bond is assumed to be the same as the set of atoms that can form hydrogen bonds.  The atoms involved must be specified "
+      67             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      68             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      69             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      70             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      71           8 :   keys.add("atoms-2","DONORS","The list of atoms which can donate a hydrogen bond.  The atoms involved must be specified "
+      72             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      73             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      74             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      75             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      76           8 :   keys.add("atoms-2","ACCEPTORS","The list of atoms which can accept a hydrogen bond.  The atoms involved must be specified "
+      77             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      78             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      79             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      80             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      81           8 :   keys.add("numbered","CLUSTERS","the name of the file that contains the definitions of all the kernels for PAMM");
+      82           8 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+      83           8 :   keys.reset_style("CLUSTERS","compulsory");
+      84             :   // Use actionWithDistributionKeywords
+      85          16 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("LESS_THAN"); keys.use("MAX");
+      86          16 :   keys.use("MIN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS");
+      87          16 :   keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("SUM");
+      88           4 : }
+      89             : 
+      90           2 : HBPammHydrogens::HBPammHydrogens(const ActionOptions&ao):
+      91             :   Action(ao),
+      92           2 :   MultiColvarBase(ao)
+      93             : {
+      94             :   // Read in the atoms
+      95           2 :   usespecies=true; weightHasDerivatives=false;
+      96             :   // Read in hydrogen atom indicees
+      97           4 :   std::vector<AtomNumber> all_atoms; parseMultiColvarAtomList("HYDROGENS",-1,all_atoms);
+      98           2 :   if( atom_lab.size()==0 ) error("no hydrogens specified in input file");
+      99             :   // Now create a task list - one task per hydrogen
+     100         136 :   unsigned nH = atom_lab.size(); for(unsigned i=0; i<nH; ++i) addTaskToList(i);
+     101             :   // Read in other atoms in hydrogen bond
+     102           4 :   ablocks.resize(1); parseMultiColvarAtomList("SITES",-1,all_atoms);
+     103           2 :   if( atom_lab.size()>nH ) {
+     104           2 :     block1upper=atom_lab.size() - nH + 1; block2lower=0; ablocks[0].resize( atom_lab.size() - nH );
+     105          69 :     for(unsigned i=nH; i<atom_lab.size(); ++i) ablocks[0][i-nH]=i;
+     106             :   } else {
+     107           0 :     parseMultiColvarAtomList("DONORS",-1,all_atoms);
+     108           0 :     block1upper=block2lower=atom_lab.size() - nH + 1;
+     109           0 :     for(unsigned i=nH; i<atom_lab.size(); ++i) ablocks[0].push_back(i);
+     110           0 :     parseMultiColvarAtomList("ACCEPTORS",-1,all_atoms);
+     111           0 :     if( atom_lab.size()>(block1upper+nH-1) || (block1upper-1)>0 ) error("no acceptor donor pairs in input specified therefore no hydrogen bonds");
+     112           0 :     for(unsigned i=nH+block2lower-1; i<atom_lab.size(); ++i) ablocks[0].push_back(i);
+     113             :   }
+     114           2 :   setupMultiColvarBase( all_atoms );
+     115             : 
+     116           4 :   double reg; parse("REGULARISE",reg);
+     117           2 :   unsigned nnode_t=mybasemulticolvars.size(); if( nnode_t==0 ) nnode_t=1;
+     118           0 :   if( nnode_t==1 ) {
+     119           4 :     std::string errormsg, desc; parse("CLUSTERS",desc);
+     120             :     hbpamm_obj.resize(1,1);
+     121           2 :     hbpamm_obj(0,0).setup(desc, reg, this, errormsg );
+     122           2 :     if( errormsg.length()>0 ) error( errormsg );
+     123             :   } else {
+     124             :     unsigned nr=nnode_t, nc=nnode_t;
+     125             :     hbpamm_obj.resize( nr, nc );
+     126           0 :     for(unsigned i=0; i<nr; ++i) {
+     127             :       // Retrieve the base number
+     128             :       unsigned ibase;
+     129           0 :       if( nc<10 ) {
+     130           0 :         ibase=(i+1)*10;
+     131           0 :       } else if ( nc<100 ) {
+     132           0 :         ibase=(i+1)*100;
+     133             :       } else {
+     134           0 :         error("wow this is an error I never would have expected");
+     135             :       }
+     136             : 
+     137           0 :       for(unsigned j=i; j<nc; ++j) {
+     138           0 :         std::string errormsg, desc; parseNumbered("CLUSTERS",ibase+j+1,desc);
+     139           0 :         if( i==j ) {
+     140           0 :           hbpamm_obj(i,j).setup( desc, reg, this, errormsg );
+     141           0 :           if( errormsg.length()>0 ) error( errormsg );
+     142             :         } else {
+     143           0 :           hbpamm_obj(i,j).setup( desc, reg, this, errormsg );
+     144           0 :           hbpamm_obj(j,i).setup( desc, reg, this, errormsg );
+     145           0 :           if( errormsg.length()>0 ) error( errormsg );
+     146             :         }
+     147             :       }
+     148             :     }
+     149             :   }
+     150             : 
+     151             :   // Set the link cell cutoff
+     152           2 :   double sfmax=0;
+     153           4 :   for(unsigned i=0; i<hbpamm_obj.ncols(); ++i) {
+     154           4 :     for(unsigned j=i; j<hbpamm_obj.nrows(); ++j) {
+     155           2 :       double rcut=hbpamm_obj(i,j).get_cutoff();
+     156           2 :       if( rcut>sfmax ) { sfmax=rcut; }
+     157             :     }
+     158             :   }
+     159           2 :   setLinkCellCutoff( sfmax );
+     160           2 :   rcut2 = sfmax*sfmax;
+     161             : 
+     162             :   // Setup the multicolvar base
+     163           2 :   setupMultiColvarBase( all_atoms );
+     164             :   // And setup the ActionWithVessel
+     165           2 :   checkRead();
+     166           2 : }
+     167             : 
+     168         134 : double HBPammHydrogens::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     169             :   double value=0, md_da ;
+     170             : 
+     171             :   // Calculate the coordination number
+     172        8344 :   for(unsigned i=1; i<myatoms.getNumberOfAtoms(); ++i) {
+     173        8210 :     if( i>block1upper ) continue;
+     174      532552 :     for(unsigned j=1; j<myatoms.getNumberOfAtoms(); ++j) {
+     175      524342 :       if( i==j || j<block2lower ) continue ;
+     176             :       // Get the base colvar numbers
+     177      516132 :       unsigned dno = atom_lab[myatoms.getIndex(i)].first;
+     178      516132 :       unsigned ano = atom_lab[myatoms.getIndex(j)].first;
+     179      516132 :       Vector d_da=getSeparation( myatoms.getPosition(i), myatoms.getPosition(j) );
+     180     1032264 :       if ( (md_da=d_da[0]*d_da[0])<rcut2 &&
+     181      516132 :            (md_da+=d_da[1]*d_da[1])<rcut2 &&
+     182      412196 :            (md_da+=d_da[2]*d_da[2])<rcut2) value += hbpamm_obj(dno,ano).evaluate( i, j, 0, d_da, sqrt(md_da), myatoms );
+     183             :     }
+     184             :   }
+     185             : 
+     186         134 :   return value;
+     187             : }
+     188             : 
+     189             : }
+     190             : }
+     191             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammMatrix.cpp.func-sort-c.html b/coverage/pamm/HBPammMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..abadee648610 --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384290.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12HBPammMatrixC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm12HBPammMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE2
_ZN4PLMD4pamm12HBPammMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12HBPammMatrix16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD4pamm12HBPammMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammMatrix.cpp.func.html b/coverage/pamm/HBPammMatrix.cpp.func.html new file mode 100644 index 000000000000..c84acf091b65 --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384290.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12HBPammMatrix14setupConnectorERKjS3_S3_RKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE2
_ZN4PLMD4pamm12HBPammMatrix16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4pamm12HBPammMatrixC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm12HBPammMatrixC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4pamm12HBPammMatrix7computeERKjRNS_11multicolvar13AtomValuePackE4038
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammMatrix.cpp.gcov.html b/coverage/pamm/HBPammMatrix.cpp.gcov.html new file mode 100644 index 000000000000..9cb37afdebe1 --- /dev/null +++ b/coverage/pamm/HBPammMatrix.cpp.gcov.html @@ -0,0 +1,225 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384290.5 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "adjmat/AdjacencyMatrixBase.h"
+      23             : #include "multicolvar/AtomValuePack.h"
+      24             : #include "HBPammObject.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/KernelFunctions.h"
+      27             : #include "tools/IFile.h"
+      28             : 
+      29             : //+PLUMEDOC MATRIX HBPAMM_MATRIX
+      30             : /*
+      31             : Adjacency matrix in which two electronegative atoms are adjacent if they are hydrogen bonded
+      32             : 
+      33             : \par Examples
+      34             : 
+      35             : */
+      36             : //+ENDPLUMEDOC
+      37             : 
+      38             : 
+      39             : namespace PLMD {
+      40             : namespace pamm {
+      41             : 
+      42             : class HBPammMatrix : public adjmat::AdjacencyMatrixBase {
+      43             : private:
+      44             :   unsigned ndonor_types;
+      45             :   double regulariser;
+      46             :   Matrix<HBPammObject> myhb_objs;
+      47             : public:
+      48             : /// Create manual
+      49             :   static void registerKeywords( Keywords& keys );
+      50             : /// Constructor
+      51             :   explicit HBPammMatrix(const ActionOptions&);
+      52             : /// Setup the connector -- i.e. read in the clusters file
+      53             :   void setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc );
+      54             : ///
+      55             :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const ;
+      56             : ///
+      57             : /// Used to check for connections between atoms
+      58             :   bool checkForConnection( const std::vector<double>& myvals ) const { return !(myvals[1]>epsilon); }
+      59             : };
+      60             : 
+      61             : PLUMED_REGISTER_ACTION(HBPammMatrix,"HBPAMM_MATRIX")
+      62             : 
+      63           4 : void HBPammMatrix::registerKeywords( Keywords& keys ) {
+      64           4 :   adjmat::AdjacencyMatrixBase::registerKeywords( keys );
+      65           8 :   keys.add("atoms-1","SITES","The list of atoms which can be part of a hydrogen bond.  When this command is used the set of atoms that can donate a "
+      66             :            "hydrogen bond is assumed to be the same as the set of atoms that can form hydrogen bonds.  The atoms involved must be specified "
+      67             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      68             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      69             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      70             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      71           8 :   keys.add("atoms-2","DONORS","The list of atoms which can donate a hydrogen bond.  The atoms involved must be specified "
+      72             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      73             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      74             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      75             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      76           8 :   keys.add("atoms-2","ACCEPTORS","The list of atoms which can accept a hydrogen bond.  The atoms involved must be specified "
+      77             :            "as a list of labels of \\ref mcolv or labels of a \\ref multicolvarfunction actions.  If you would just like to use "
+      78             :            "the atomic positions you can use a \\ref DENSITY command to specify a group of atoms.  Specifying your atomic positions using labels of "
+      79             :            "other \\ref mcolv or \\ref multicolvarfunction commands is useful, however, as you can then exploit a much wider "
+      80             :            "variety of functions of the contact matrix as described in \\ref contactmatrix");
+      81           8 :   keys.add("atoms","HYDROGENS","The list of hydrogen atoms that can form part of a hydrogen bond.  The atoms must be specified using a comma separated list, "
+      82             :            "an index range or by using a \\ref GROUP");
+      83           8 :   keys.add("numbered","CLUSTERS","the name of the file that contains the definitions of all the kernels for PAMM");
+      84           8 :   keys.reset_style("CLUSTERS","compulsory"); keys.use("SUM");
+      85           8 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+      86           4 : }
+      87             : 
+      88             : 
+      89           2 : HBPammMatrix::HBPammMatrix(const ActionOptions& ao):
+      90             :   Action(ao),
+      91           2 :   AdjacencyMatrixBase(ao)
+      92             : {
+      93           4 :   readMaxThreeSpeciesMatrix("SITES", "DONORS", "ACCEPTORS", "HYDROGENS", false );
+      94             :   // Retrieve dimensions of hbonding matrix and resize
+      95           2 :   unsigned nrows, ncols; retrieveTypeDimensions( nrows, ncols, ndonor_types );
+      96           2 :   myhb_objs.resize( nrows, ncols );
+      97             :   // Read in the regularisation parameter
+      98           2 :   parse("REGULARISE",regulariser);
+      99             :   // Read in the switching functions
+     100           2 :   parseConnectionDescriptions("CLUSTERS",false,ndonor_types);
+     101             : 
+     102             :   // Find cutoff for link cells
+     103           2 :   double sfmax=0;
+     104           4 :   for(unsigned i=0; i<myhb_objs.ncols(); ++i) {
+     105           4 :     for(unsigned j=i; j<myhb_objs.nrows(); ++j) {
+     106           2 :       double rcut=myhb_objs(i,j).get_cutoff();
+     107           2 :       if( rcut>sfmax ) { sfmax=rcut; }
+     108             :     }
+     109             :   }
+     110           2 :   setLinkCellCutoff( sfmax );
+     111           2 : }
+     112             : 
+     113           2 : void HBPammMatrix::setupConnector( const unsigned& id, const unsigned& i, const unsigned& j, const std::vector<std::string>& desc ) {
+     114           2 :   log.printf("  reading definition of hydrogen bond between between type %u and %u from file %s \n",i,j,desc[0].c_str() );
+     115           2 :   plumed_assert( desc.size()==1 ); std::string errors;
+     116           2 :   if( i==j ) {
+     117           2 :     myhb_objs( i, j ).setup( desc[0], regulariser, this, errors );
+     118             :   } else {
+     119           0 :     myhb_objs( i, j ).setup( desc[0], regulariser, this, errors );
+     120           0 :     myhb_objs( j, i ).setup( desc[0], regulariser, this, errors );
+     121             :   }
+     122           2 :   if( errors.length()>0 ) error( errors );
+     123           2 : }
+     124             : 
+     125        4038 : double HBPammMatrix::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     126        4038 :   Vector d_da = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) ); double md_da = d_da.modulo(); // acceptor - donor
+     127             : 
+     128             :   // Get the base colvar numbers
+     129             :   unsigned ano, dno = getBaseColvarNumber( myatoms.getIndex(0) );
+     130        4038 :   if( ndonor_types==0 ) ano = getBaseColvarNumber( myatoms.getIndex(1) );
+     131           0 :   else ano = getBaseColvarNumber( myatoms.getIndex(1) ) - ndonor_types;
+     132             : 
+     133             :   double value=0;
+     134        4038 :   if( myatoms.getNumberOfAtoms()>3 ) {
+     135             :     const HBPammObject& myhb=myhb_objs(dno,ano);
+     136      520170 :     for(unsigned i=2; i<myatoms.getNumberOfAtoms(); ++i) {
+     137      516132 :       value+=myhb.evaluate( 0, 1, i, d_da, md_da, myatoms );
+     138             :     }
+     139             :   } else {
+     140             :     plumed_dbg_assert( myatoms.getNumberOfAtoms()==3 );
+     141           0 :     value=myhb_objs(dno,ano).evaluate( 0, 1, 2, d_da, md_da, myatoms );
+     142             :   }
+     143             : 
+     144        4038 :   return value;
+     145             : }
+     146             : 
+     147             : }
+     148             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.cpp.func-sort-c.html b/coverage/pamm/HBPammObject.cpp.func-sort-c.html new file mode 100644 index 000000000000..32ce0c522143 --- /dev/null +++ b/coverage/pamm/HBPammObject.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12HBPammObject5setupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKdPNS_11multicolvar15MultiColvarBaseERS7_4
_ZNK4PLMD4pamm12HBPammObject10get_cutoffEv4
_ZNK4PLMD4pamm12HBPammObject8evaluateERKjS3_S3_RKNS_13VectorGenericILj3EEERKdRNS_11multicolvar13AtomValuePackE787016
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.cpp.func.html b/coverage/pamm/HBPammObject.cpp.func.html new file mode 100644 index 000000000000..7e99e931eeb4 --- /dev/null +++ b/coverage/pamm/HBPammObject.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm12HBPammObject5setupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKdPNS_11multicolvar15MultiColvarBaseERS7_4
_ZNK4PLMD4pamm12HBPammObject10get_cutoffEv4
_ZNK4PLMD4pamm12HBPammObject8evaluateERKjS3_S3_RKNS_13VectorGenericILj3EEERKdRNS_11multicolvar13AtomValuePackE787016
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.cpp.gcov.html b/coverage/pamm/HBPammObject.cpp.gcov.html new file mode 100644 index 000000000000..9cc007dc07e1 --- /dev/null +++ b/coverage/pamm/HBPammObject.cpp.gcov.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammObject.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "HBPammObject.h"
+      23             : #include "tools/IFile.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace pamm {
+      27             : 
+      28           4 : void HBPammObject::setup( const std::string& filename, const double& reg, multicolvar::MultiColvarBase* mybase, std::string& errorstr ) {
+      29           4 :   mymulti=mybase; std::vector<std::string> valnames(3);
+      30             :   valnames[0]="ptc"; valnames[1]="ssc"; valnames[2]="adc";
+      31           4 :   std::vector<std::string> min(3), max(3); std::vector<bool> pbc(3, false);
+      32           4 :   mypamm.setup( filename, reg, valnames, pbc, min, max, errorstr );
+      33           4 : }
+      34             : 
+      35           4 : double HBPammObject::get_cutoff() const {
+      36             :   double sfmax=0;
+      37          48 :   for(unsigned k=0; k<mypamm.getNumberOfKernels(); ++k) {
+      38          44 :     double rcut = mypamm.getKernelCenter(k)[2] + mypamm.getKernelSupport(k)[2];
+      39          44 :     if( rcut>sfmax ) { sfmax=rcut; }
+      40             :   }
+      41           4 :   return sfmax;
+      42             : }
+      43             : 
+      44      787016 : double HBPammObject::evaluate( const unsigned& dno, const unsigned& ano, const unsigned& hno,
+      45             :                                const Vector& d_da, const double& md_da, multicolvar::AtomValuePack& myatoms ) const {
+      46      787016 :   Vector d_dh = mymulti->getSeparation( myatoms.getPosition(dno), myatoms.getPosition(hno) ); double md_dh = d_dh.modulo(); // hydrogen - donor
+      47      787016 :   Vector d_ah = mymulti->getSeparation( myatoms.getPosition(ano), myatoms.getPosition(hno) ); double md_ah = d_ah.modulo(); // hydrogen - acceptor
+      48             : 
+      49             :   // Create some vectors locally for pamm evaluation
+      50      787016 :   std::vector<double> invals( 3 ), outvals( mypamm.getNumberOfKernels() );
+      51      787016 :   std::vector<std:: vector<double> > der( mypamm.getNumberOfKernels() );
+      52     9444192 :   for(unsigned i=0; i<der.size(); ++i) der[i].resize(3);
+      53             : 
+      54             :   // Evaluate the pamm object
+      55      787016 :   invals[0]=md_dh - md_ah; invals[1]=md_dh+md_ah; invals[2]=md_da;
+      56      787016 :   mypamm.evaluate( invals, outvals, der );
+      57             : 
+      58      787016 :   if( !mymulti->doNotCalculateDerivatives() ) {
+      59          72 :     mymulti->addAtomDerivatives( 1, dno, ((-der[0][0])/md_dh)*d_dh, myatoms );
+      60          72 :     mymulti->addAtomDerivatives( 1, ano, ((+der[0][0])/md_ah)*d_ah, myatoms  );
+      61          72 :     mymulti->addAtomDerivatives( 1, hno, ((+der[0][0])/md_dh)*d_dh - ((+der[0][0])/md_ah)*d_ah, myatoms );
+      62          72 :     myatoms.addBoxDerivatives( 1, ((-der[0][0])/md_dh)*Tensor(d_dh,d_dh) - ((-der[0][0])/md_ah)*Tensor(d_ah,d_ah) );
+      63          72 :     mymulti->addAtomDerivatives( 1, dno, ((-der[0][1])/md_dh)*d_dh, myatoms );
+      64          72 :     mymulti->addAtomDerivatives( 1, ano, ((-der[0][1])/md_ah)*d_ah, myatoms );
+      65          72 :     mymulti->addAtomDerivatives( 1, hno, ((+der[0][1])/md_dh)*d_dh + ((+der[0][1])/md_ah)*d_ah, myatoms );
+      66          72 :     myatoms.addBoxDerivatives( 1, ((-der[0][1])/md_dh)*Tensor(d_dh,d_dh) + ((-der[0][1])/md_ah)*Tensor(d_ah,d_ah) );
+      67          72 :     mymulti->addAtomDerivatives( 1, dno, ((-der[0][2])/md_da)*d_da, myatoms );
+      68          72 :     mymulti->addAtomDerivatives( 1, ano, ((+der[0][2])/md_da)*d_da, myatoms );
+      69          72 :     myatoms.addBoxDerivatives( 1, ((-der[0][2])/md_da)*Tensor(d_da,d_da) );
+      70             :   }
+      71      787016 :   return outvals[0];
+      72             : 
+      73      787016 : }
+      74             : 
+      75             : }
+      76             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.h.func-sort-c.html b/coverage/pamm/HBPammObject.h.func-sort-c.html new file mode 100644 index 000000000000..c5a3f04ae636 --- /dev/null +++ b/coverage/pamm/HBPammObject.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.h.func.html b/coverage/pamm/HBPammObject.h.func.html new file mode 100644 index 000000000000..9747f5fefc30 --- /dev/null +++ b/coverage/pamm/HBPammObject.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/HBPammObject.h.gcov.html b/coverage/pamm/HBPammObject.h.gcov.html new file mode 100644 index 000000000000..1e35e5032be2 --- /dev/null +++ b/coverage/pamm/HBPammObject.h.gcov.html @@ -0,0 +1,128 @@ + + + + + + + + LCOV - plumed test coverage - pamm/HBPammObject.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - HBPammObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_pamm_HBPammObject_h
+      23             : #define __PLUMED_pamm_HBPammObject_h
+      24             : 
+      25             : #include "tools/Vector.h"
+      26             : #include "multicolvar/AtomValuePack.h"
+      27             : #include "PammObject.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace pamm {
+      31             : 
+      32           8 : class HBPammObject {
+      33             : private:
+      34             : /// The Pamm object underlying this HBPamm calculation
+      35             :   PammObject mypamm;
+      36             : /// Pointer to base class in multicolvar
+      37             :   multicolvar::MultiColvarBase* mymulti=nullptr;
+      38             : public:
+      39             : /// Setup the HBPamm object
+      40             :   void setup( const std::string& filename, const double& reg, multicolvar::MultiColvarBase* mybase, std::string& errorstr );
+      41             : /// Get the cutoff to use throughout
+      42             :   double get_cutoff() const ;
+      43             : /// Evaluate the HBPamm Object
+      44             :   double evaluate( const unsigned& dno, const unsigned& ano, const unsigned& hno,
+      45             :                    const Vector& d_da, const double& md_da, multicolvar::AtomValuePack& myatoms ) const ;
+      46             : };
+      47             : 
+      48             : }
+      49             : }
+      50             : 
+      51             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PAMM.cpp.func-sort-c.html b/coverage/pamm/PAMM.cpp.func-sort-c.html new file mode 100644 index 000000000000..9fb99f31e96c --- /dev/null +++ b/coverage/pamm/PAMM.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - pamm/PAMM.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - PAMM.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:496476.6 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm4PAMM14getCentralAtomEv0
_ZN4PLMD4pamm4PAMM15calculateWeightERNS_11multicolvar13AtomValuePackE0
_ZN4PLMD4pamm4PAMMC2ERKNS_13ActionOptionsE0
_ZN4PLMD4pamm4PAMMC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm4PAMM16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4pamm4PAMM10isPeriodicEv16
_ZNK4PLMD4pamm4PAMM7computeERKjRNS_11multicolvar13AtomValuePackE28
_ZNK4PLMD4pamm4PAMM21getNumberOfQuantitiesEv86
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PAMM.cpp.func.html b/coverage/pamm/PAMM.cpp.func.html new file mode 100644 index 000000000000..8f4bd47d1bc0 --- /dev/null +++ b/coverage/pamm/PAMM.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - pamm/PAMM.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - PAMM.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:496476.6 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm4PAMM10isPeriodicEv16
_ZN4PLMD4pamm4PAMM14getCentralAtomEv0
_ZN4PLMD4pamm4PAMM15calculateWeightERNS_11multicolvar13AtomValuePackE0
_ZN4PLMD4pamm4PAMM16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4pamm4PAMMC1ERKNS_13ActionOptionsE2
_ZN4PLMD4pamm4PAMMC2ERKNS_13ActionOptionsE0
_ZNK4PLMD4pamm4PAMM21getNumberOfQuantitiesEv86
_ZNK4PLMD4pamm4PAMM7computeERKjRNS_11multicolvar13AtomValuePackE28
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PAMM.cpp.gcov.html b/coverage/pamm/PAMM.cpp.gcov.html new file mode 100644 index 000000000000..16f7d8ce5fb6 --- /dev/null +++ b/coverage/pamm/PAMM.cpp.gcov.html @@ -0,0 +1,329 @@ + + + + + + + + LCOV - plumed test coverage - pamm/PAMM.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - PAMM.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:496476.6 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionRegister.h"
+      23             : #include "tools/KernelFunctions.h"
+      24             : #include "tools/IFile.h"
+      25             : #include "multicolvar/MultiColvarBase.h"
+      26             : #include "multicolvar/AtomValuePack.h"
+      27             : #include "PammObject.h"
+      28             : 
+      29             : //+PLUMEDOC MCOLVARF PAMM
+      30             : /*
+      31             : Probabilistic analysis of molecular motifs.
+      32             : 
+      33             : Probabilistic analysis of molecular motifs (PAMM) was introduced in this paper \cite pamm.
+      34             : The essence of this approach involves calculating some large set of collective variables
+      35             : for a set of atoms in a short trajectory and fitting this data using a Gaussian Mixture Model.
+      36             : The idea is that modes in these distributions can be used to identify features such as hydrogen bonds or
+      37             : secondary structure types.
+      38             : 
+      39             : The assumption within this implementation is that the fitting of the Gaussian mixture model has been
+      40             : done elsewhere by a separate code.  You thus provide an input file to this action which contains the
+      41             : means, covariance matrices and weights for a set of Gaussian kernels, \f$\{ \phi \}\f$.  The values and
+      42             : derivatives for the following set of quantities is then computed:
+      43             : 
+      44             : \f[
+      45             : s_k = \frac{ \phi_k}{ \sum_i \phi_i }
+      46             : \f]
+      47             : 
+      48             : Each of the \f$\phi_k\f$ is a Gaussian function that acts on a set of quantities calculated within
+      49             : a \ref mcolv .  These might be \ref TORSIONS, \ref DISTANCES, \ref ANGLES or any one of the many
+      50             : symmetry functions that are available within \ref mcolv actions.  These quantities are then inserted into
+      51             : the set of \f$n\f$ kernels that are in the the input file.   This will be done for multiple sets of values
+      52             : for the input quantities and a final quantity will be calculated by summing the above \f$s_k\f$ values or
+      53             : some transformation of the above.  This sounds less complicated than it is and is best understood by
+      54             : looking through the example given below.
+      55             : 
+      56             : \warning Mixing \ref mcolv actions that are periodic with variables that are not periodic has not been tested
+      57             : 
+      58             : \par Examples
+      59             : 
+      60             : In this example I will explain in detail what the following input is computing:
+      61             : 
+      62             : \plumedfile
+      63             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      64             : MOLINFO MOLTYPE=protein STRUCTURE=M1d.pdb
+      65             : psi: TORSIONS ATOMS1=@psi-2 ATOMS2=@psi-3 ATOMS3=@psi-4
+      66             : phi: TORSIONS ATOMS1=@phi-2 ATOMS2=@phi-3 ATOMS3=@phi-4
+      67             : p: PAMM DATA=phi,psi CLUSTERS=clusters.pamm MEAN1={COMPONENT=1} MEAN2={COMPONENT=2}
+      68             : PRINT ARG=p.mean-1,p.mean-2 FILE=colvar
+      69             : \endplumedfile
+      70             : 
+      71             : The best place to start our explanation is to look at the contents of the clusters.pamm file
+      72             : 
+      73             : \auxfile{clusters.pamm}
+      74             : #! FIELDS height phi psi sigma_phi_phi sigma_phi_psi sigma_psi_phi sigma_psi_psi
+      75             : #! SET multivariate von-misses
+      76             : #! SET kerneltype gaussian
+      77             :       2.97197455E-0001     -1.91983118E+0000      2.25029540E+0000      2.45960237E-0001     -1.30615381E-0001     -1.30615381E-0001      2.40239117E-0001
+      78             :       2.29131448E-0002      1.39809354E+0000      9.54585380E-0002      9.61755708E-0002     -3.55657919E-0002     -3.55657919E-0002      1.06147253E-0001
+      79             :       5.06676398E-0001     -1.09648066E+0000     -7.17867907E-0001      1.40523052E-0001     -1.05385552E-0001     -1.05385552E-0001      1.63290557E-0001
+      80             : \endauxfile
+      81             : 
+      82             : This files contains the parameters of two two-dimensional Gaussian functions.  Each of these Gaussian kernels has a weight, \f$w_k\f$,
+      83             : a vector that specifies the position of its center, \f$\mathbf{c}_k\f$, and a covariance matrix, \f$\Sigma_k\f$.  The \f$\phi_k\f$ functions that
+      84             : we use to calculate our PAMM components are thus:
+      85             : 
+      86             : \f[
+      87             : \phi_k = \frac{w_k}{N_k} \exp\left( -(\mathbf{s} - \mathbf{c}_k)^T \Sigma^{-1}_k (\mathbf{s} - \mathbf{c}_k) \right)
+      88             : \f]
+      89             : 
+      90             : In the above \f$N_k\f$ is a normalization factor that is calculated based on \f$\Sigma\f$.  The vector \f$\mathbf{s}\f$ is a vector of quantities
+      91             : that are calculated by the \ref TORSIONS actions.  This vector must be two dimensional and in this case each component is the value of a
+      92             : torsion angle.  If we look at the two \ref TORSIONS actions in the above we are calculating the \f$\phi\f$ and \f$\psi\f$ backbone torsional
+      93             : angles in a protein (Note the use of \ref MOLINFO to make specification of atoms straightforward).  We thus calculate the values of our
+      94             : 2 \f$ \{ \phi \} \f$  kernels 3 times.  The first time we use the \f$\phi\f$ and \f$\psi\f$ angles in the second residue of the protein,
+      95             : the second time it is the \f$\phi\f$ and \f$\psi\f$ angles of the third residue of the protein and the third time it is the \f$\phi\f$ and \f$\psi\f$ angles
+      96             : of the fourth residue in the protein.  The final two quantities that are output by the print command, p.mean-1 and p.mean-2, are the averages
+      97             : over these three residues for the quantities:
+      98             : \f[
+      99             : s_1 = \frac{ \phi_1}{ \phi_1 + \phi_2 }
+     100             : \f]
+     101             : and
+     102             : \f[
+     103             : s_2 = \frac{ \phi_2}{ \phi_1 + \phi_2 }
+     104             : \f]
+     105             : There is a great deal of flexibility in this input.  We can work with, and examine, any number of components, we can use any set of collective variables
+     106             : and compute these PAMM variables and we can transform the PAMM variables themselves in a large number of different ways when computing these sums.
+     107             : */
+     108             : //+ENDPLUMEDOC
+     109             : 
+     110             : namespace PLMD {
+     111             : namespace pamm {
+     112             : 
+     113             : class PAMM : public multicolvar::MultiColvarBase {
+     114             : private:
+     115             :   PammObject mypamm;
+     116             : public:
+     117             :   static void registerKeywords( Keywords& keys );
+     118             :   explicit PAMM(const ActionOptions&);
+     119             : /// We have to overwrite this here
+     120             :   unsigned getNumberOfQuantities() const override;
+     121             : /// Calculate the weight of this object ( average of input weights )
+     122             :   using PLMD::multicolvar::MultiColvarBase::calculateWeight;
+     123             :   void calculateWeight( multicolvar::AtomValuePack& myatoms );
+     124             : /// Actually do the calculation
+     125             :   double compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const override;
+     126             : /// This returns the position of the central atom
+     127             :   Vector getCentralAtom();
+     128             : /// Is the variable periodic
+     129          16 :   bool isPeriodic() override { return false; }
+     130             : };
+     131             : 
+     132             : PLUMED_REGISTER_ACTION(PAMM,"PAMM")
+     133             : 
+     134           4 : void PAMM::registerKeywords( Keywords& keys ) {
+     135           4 :   MultiColvarBase::registerKeywords( keys );
+     136           8 :   keys.add("compulsory","DATA","the multicolvars from which the pamm coordinates are calculated");
+     137           8 :   keys.add("compulsory","CLUSTERS","the name of the file that contains the definitions of all the clusters");
+     138           8 :   keys.add("compulsory","REGULARISE","0.001","don't allow the denominator to be smaller then this value");
+     139          20 :   keys.use("MEAN"); keys.use("MORE_THAN"); keys.use("SUM"); keys.use("LESS_THAN"); keys.use("HISTOGRAM");
+     140          28 :   keys.use("MIN"); keys.use("MAX"); keys.use("LOWEST"); keys.use("HIGHEST"); keys.use("ALT_MIN"); keys.use("BETWEEN"); keys.use("MOMENTS");
+     141           4 :   keys.setComponentsIntroduction("When the label of this action is used as the input for a second you are not referring to a scalar quantity as you are in "
+     142             :                                  "regular collective variables.  The label is used to reference the full set of quantities calculated by "
+     143             :                                  "the action.  This is usual when using \\ref multicolvarfunction. Generally when doing this the set of PAMM variables "
+     144             :                                  "will be referenced using the DATA keyword rather than ARG.\n\n"
+     145             :                                  "This Action can be used to calculate the following scalar quantities directly from the underlying set of PAMM variables. "
+     146             :                                  "These quantities are calculated by employing the keywords listed below and they can be referenced elsewhere in the input "
+     147             :                                  "file by using this Action's label followed by a dot and the name of the quantity.  The particular PAMM variable that should "
+     148             :                                  "be averaged in a MEAN command or transformed by a switching function in a LESS_THAN command is specified using the COMPONENT "
+     149             :                                  "keyword. COMPONENT=1 refers to the PAMM variable in which the first kernel in your input file is on the numerator, COMPONENT=2 refers to "
+     150             :                                  "PAMM variable in which the second kernel in the input file is on the numerator and so on.  The same quantity can be calculated "
+     151             :                                  "multiple times for different PAMM components by a single PAMM action.  In this case the relevant keyword must appear multiple "
+     152             :                                  "times on the input line followed by a numerical identifier i.e. MEAN1, MEAN2, ...  The quantities calculated when multiple "
+     153             :                                  "MEAN commands appear on the input line can be reference elsewhere in the input file by using the name of the quantity followed "
+     154             :                                  "followed by a numerical identifier e.g. <em>label</em>.lessthan-1, <em>label</em>.lessthan-2 etc.  Alternatively, you can "
+     155             :                                  "customize the labels of the quantities by using the LABEL keyword in the description of the keyword.");
+     156           4 :   keys.remove("ALL_INPUT_SAME_TYPE");
+     157           4 : }
+     158             : 
+     159           2 : PAMM::PAMM(const ActionOptions& ao):
+     160             :   Action(ao),
+     161           2 :   MultiColvarBase(ao)
+     162             : {
+     163             :   // This builds the lists
+     164           2 :   buildSets();
+     165             :   // Check for reasonable input
+     166           5 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+     167           3 :     if( getBaseMultiColvar(i)->getNumberOfQuantities()!=2 ) error("cannot use PAMM with " + getBaseMultiColvar(i)->getName() );
+     168             :   }
+     169             : 
+     170           2 :   bool mixed=getBaseMultiColvar(0)->isPeriodic();
+     171           2 :   std::vector<bool> pbc( getNumberOfBaseMultiColvars() );
+     172           2 :   std::vector<std::string> valnames( getNumberOfBaseMultiColvars() );
+     173           2 :   std::vector<std::string> min( getNumberOfBaseMultiColvars() ), max( getNumberOfBaseMultiColvars() );
+     174           5 :   for(unsigned i=0; i<getNumberOfBaseMultiColvars(); ++i) {
+     175           3 :     if( getBaseMultiColvar(i)->isPeriodic()!=mixed ) warning("mixing of periodic and aperiodic base variables in pamm is untested");
+     176           3 :     pbc[i]=getBaseMultiColvar(i)->isPeriodic();
+     177           3 :     if( pbc[i] ) getBaseMultiColvar(i)->retrieveDomain( min[i], max[i] );
+     178           3 :     valnames[i]=getBaseMultiColvar(i)->getLabel();
+     179             :   }
+     180             : 
+     181           4 :   double regulariser; parse("REGULARISE",regulariser);
+     182           2 :   std::string errorstr, filename; parse("CLUSTERS",filename);
+     183           2 :   mypamm.setup( filename, regulariser, valnames, pbc, min, max, errorstr );
+     184           2 :   if( errorstr.length()>0 ) error( errorstr );
+     185           4 : }
+     186             : 
+     187          86 : unsigned PAMM::getNumberOfQuantities() const {
+     188          86 :   return 1 + mypamm.getNumberOfKernels();
+     189             : }
+     190             : 
+     191           0 : void PAMM::calculateWeight( multicolvar::AtomValuePack& myatoms ) {
+     192             :   unsigned nvars = getNumberOfBaseMultiColvars();
+     193             :   // Weight of point is average of weights of input colvars?
+     194           0 :   std::vector<double> tval(2); double ww=0;
+     195           0 :   for(unsigned i=0; i<nvars; ++i) {
+     196           0 :     getInputData( i, false, myatoms, tval ); ww+=tval[0];
+     197             :   }
+     198           0 :   myatoms.setValue( 0, ww / static_cast<double>( nvars ) );
+     199             : 
+     200           0 :   if(!doNotCalculateDerivatives() ) {
+     201           0 :     double pref = 1.0 / static_cast<double>( nvars );
+     202           0 :     for(unsigned ivar=0; ivar<nvars; ++ivar) {
+     203             :       // Get the values of derivatives
+     204           0 :       const MultiValue& myder=getInputDerivatives( ivar, false, myatoms );
+     205           0 :       for(unsigned j=0; j<myder.getNumberActive(); ++j) {
+     206           0 :         unsigned jder=myder.getActiveIndex(j);
+     207           0 :         myatoms.addDerivative( 0, jder, pref*myder.getDerivative( 0, jder ) );
+     208             :       }
+     209             :     }
+     210             :   }
+     211           0 : }
+     212             : 
+     213          28 : double PAMM::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const {
+     214             :   unsigned nvars = getNumberOfBaseMultiColvars();
+     215          28 :   std::vector<std::vector<double> > tderiv( mypamm.getNumberOfKernels() );
+     216         174 :   for(unsigned i=0; i<tderiv.size(); ++i) tderiv[i].resize( nvars );
+     217          28 :   std::vector<double> tval(2), invals( nvars ), vals( mypamm.getNumberOfKernels() );
+     218             : 
+     219          74 :   for(unsigned i=0; i<nvars; ++i) {
+     220          46 :     getInputData( i, false, myatoms, tval ); invals[i]=tval[1];
+     221             :   }
+     222          28 :   mypamm.evaluate( invals, vals, tderiv );
+     223             : 
+     224             :   // Now set all values other than the first one
+     225             :   // This is because of some peverse choices in multicolvar
+     226         146 :   for(unsigned i=1; i<vals.size(); ++i) myatoms.setValue( 1+i, vals[i] );
+     227             : 
+     228          28 :   if( !doNotCalculateDerivatives() ) {
+     229          28 :     std::vector<double> mypref( 1 + vals.size() );
+     230          74 :     for(unsigned ivar=0; ivar<nvars; ++ivar) {
+     231             :       // Get the values of the derivatives
+     232          46 :       MultiValue& myder = getInputDerivatives( ivar, false, myatoms );
+     233             :       // And calculate the derivatives
+     234         318 :       for(unsigned i=0; i<vals.size(); ++i) mypref[1+i] = tderiv[i][ivar];
+     235             :       // This is basically doing the chain rule to get the final derivatives
+     236          46 :       splitInputDerivatives( 1, 1, 1+vals.size(), ivar, mypref, myder, myatoms );
+     237             :       // And clear the derivatives
+     238          46 :       myder.clearAll();
+     239             :     }
+     240             :   }
+     241             : 
+     242          56 :   return vals[0];
+     243          28 : }
+     244             : 
+     245           0 : Vector PAMM::getCentralAtom() {
+     246             :   // Who knows how this should work
+     247           0 :   plumed_error();
+     248             :   // return Vector(1.0,0.0,0.0);
+     249             : }
+     250             : 
+     251             : }
+     252             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PammObject.cpp.func-sort-c.html b/coverage/pamm/PammObject.cpp.func-sort-c.html new file mode 100644 index 000000000000..a3e6aab07ba5 --- /dev/null +++ b/coverage/pamm/PammObject.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - pamm/PammObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - PammObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384682.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm10PammObjectC2ERKS1_0
_ZN4PLMD4pamm10PammObject5setupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKdRKSt6vectorIS7_SaIS7_EERKSC_IbSaIbEESG_SG_RS7_6
_ZN4PLMD4pamm10PammObjectC2Ev6
_ZNK4PLMD4pamm10PammObject8evaluateERKSt6vectorIdSaIdEERS4_RS2_IS4_SaIS4_EE787044
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PammObject.cpp.func.html b/coverage/pamm/PammObject.cpp.func.html new file mode 100644 index 000000000000..17c45a0520cb --- /dev/null +++ b/coverage/pamm/PammObject.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - pamm/PammObject.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - PammObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384682.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4pamm10PammObject5setupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKdRKSt6vectorIS7_SaIS7_EERKSC_IbSaIbEESG_SG_RS7_6
_ZN4PLMD4pamm10PammObjectC2ERKS1_0
_ZN4PLMD4pamm10PammObjectC2Ev6
_ZNK4PLMD4pamm10PammObject8evaluateERKSt6vectorIdSaIdEERS4_RS2_IS4_SaIS4_EE787044
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PammObject.cpp.gcov.html b/coverage/pamm/PammObject.cpp.gcov.html new file mode 100644 index 000000000000..f04eb44a1b07 --- /dev/null +++ b/coverage/pamm/PammObject.cpp.gcov.html @@ -0,0 +1,180 @@ + + + + + + + + LCOV - plumed test coverage - pamm/PammObject.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - PammObject.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:384682.6 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PammObject.h"
+      23             : #include "tools/IFile.h"
+      24             : #include <memory>
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace pamm {
+      28             : 
+      29           6 : PammObject::PammObject():
+      30           6 :   regulariser(0.001)
+      31             : {
+      32           6 : }
+      33             : 
+      34           0 : PammObject::PammObject( const PammObject& in ):
+      35           0 :   regulariser(in.regulariser),
+      36           0 :   pbc(in.pbc),
+      37           0 :   min(in.min),
+      38           0 :   max(in.max)
+      39             : {
+      40           0 :   for(unsigned i=0; i<in.kernels.size(); ++i) kernels.emplace_back( Tools::make_unique<KernelFunctions>( in.kernels[i].get() ) );
+      41           0 : }
+      42             : 
+      43           6 : void PammObject::setup( const std::string& filename, const double& reg, const std::vector<std::string>& valnames,
+      44             :                         const std::vector<bool>& pbcin, const std::vector<std::string>& imin, const std::vector<std::string>& imax,
+      45             :                         std::string& errorstr ) {
+      46           6 :   IFile ifile; regulariser=reg;
+      47           6 :   if( !ifile.FileExist(filename) ) {
+      48           0 :     errorstr = "could not find file named " + filename;
+      49             :     return;
+      50             :   }
+      51             : 
+      52             :   std::vector<std::unique_ptr<Value>> pos;
+      53           6 :   pbc.resize( valnames.size() );
+      54           6 :   min.resize( valnames.size() );
+      55           6 :   max.resize( valnames.size() );
+      56          21 :   for(unsigned i=0; i<valnames.size(); ++i) {
+      57          15 :     pbc[i]=pbcin[i]; min[i]=imin[i]; max[i]=imax[i];
+      58          15 :     pos.emplace_back( Tools::make_unique<Value>() );
+      59          15 :     if( !pbc[i] ) pos[i]->setNotPeriodic();
+      60           2 :     else pos[i]->setDomain( min[i], max[i] );
+      61             :   }
+      62             : 
+      63           6 :   ifile.open(filename); ifile.allowIgnoredFields(); kernels.resize(0);
+      64             :   for(unsigned k=0;; ++k) {
+      65          59 :     std::unique_ptr<KernelFunctions> kk = KernelFunctions::read( &ifile, false, valnames );
+      66          59 :     if( !kk ) break ;
+      67          53 :     kk->normalize( Tools::unique2raw( pos ) );
+      68          53 :     kernels.emplace_back( std::move(kk) );
+      69          53 :     ifile.scanField();
+      70          59 :   }
+      71           6 :   ifile.close();
+      72           6 : }
+      73             : 
+      74      787044 : void PammObject::evaluate( const std::vector<double>& invar, std::vector<double>& outvals, std::vector<std::vector<double> >& der ) const {
+      75             :   std::vector<std::unique_ptr<Value>> pos;
+      76     3148138 :   for(unsigned i=0; i<pbc.size(); ++i) {
+      77     2361094 :     pos.emplace_back( Tools::make_unique<Value>() );
+      78     2361094 :     if( !pbc[i] ) pos[i]->setNotPeriodic();
+      79          36 :     else pos[i]->setDomain( min[i], max[i] );
+      80             :     // And set the value
+      81     2361094 :     pos[i]->set( invar[i] );
+      82             :   }
+      83             : 
+      84             :   // convert pointers once
+      85      787044 :   auto pos_ptr=Tools::unique2raw(pos);
+      86             : 
+      87             :   // Evaluate the set of kernels
+      88      787044 :   double denom=regulariser; std::vector<double> dderiv( der[0].size(), 0 );
+      89     9444366 :   for(unsigned i=0; i<kernels.size(); ++i) {
+      90     8657322 :     outvals[i]=kernels[i]->evaluate( pos_ptr, der[i] ); denom+=outvals[i];
+      91    34629122 :     for(unsigned j=0; j<der[i].size(); ++j) dderiv[j] += der[i][j];
+      92             :   }
+      93             :   // Evaluate the set of derivatives
+      94     9444366 :   for(unsigned i=0; i<kernels.size(); ++i) {
+      95     8657322 :     outvals[i]/=denom;
+      96    34629122 :     for(unsigned j=0; j<der[i].size(); ++j) der[i][j]=der[i][j]/denom - outvals[i]*dderiv[j]/denom;
+      97             :   }
+      98             : 
+      99      787044 : }
+     100             : 
+     101             : 
+     102             : }
+     103             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PammObject.h.func-sort-c.html b/coverage/pamm/PammObject.h.func-sort-c.html new file mode 100644 index 000000000000..9a6cece4ec4a --- /dev/null +++ b/coverage/pamm/PammObject.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - pamm/PammObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - PammObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PammObject.h.func.html b/coverage/pamm/PammObject.h.func.html new file mode 100644 index 000000000000..0b93dcb51692 --- /dev/null +++ b/coverage/pamm/PammObject.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - pamm/PammObject.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - PammObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/PammObject.h.gcov.html b/coverage/pamm/PammObject.h.gcov.html new file mode 100644 index 000000000000..6813a5ef986d --- /dev/null +++ b/coverage/pamm/PammObject.h.gcov.html @@ -0,0 +1,159 @@ + + + + + + + + LCOV - plumed test coverage - pamm/PammObject.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pamm - PammObject.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_pamm_PammObject_h
+      23             : #define __PLUMED_pamm_PammObject_h
+      24             : 
+      25             : #include <vector>
+      26             : #include "core/Value.h"
+      27             : #include "tools/KernelFunctions.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace pamm {
+      31             : 
+      32             : class PammObject {
+      33             : private:
+      34             : /// Regularisation parameter to use
+      35             :   double regulariser;
+      36             : /// Is the domain periodic
+      37             :   std::vector<bool> pbc;
+      38             : /// The domain of the function
+      39             :   std::vector<std::string> min, max;
+      40             : /// List of kernel functions involved
+      41             :   std::vector<std::unique_ptr<KernelFunctions>> kernels;
+      42             : public:
+      43             : // Explicit definitions for constructor, copy constructor and destructor
+      44             :   PammObject();
+      45             :   PammObject( const PammObject& );
+      46             : /// GB: I fixed this (should return PammObject&, it was returning PammObject
+      47             : // However I am not sure the implementation makes sense.
+      48             :   PammObject& operator=(const PammObject& po) { plumed_error(); regulariser=po.regulariser; return *this; }
+      49             : /// Setup the Pamm object
+      50             :   void setup( const std::string& filename, const double& reg, const std::vector<std::string>& valnames,
+      51             :               const std::vector<bool>& pbcin, const std::vector<std::string>& imin, const std::vector<std::string>& imax,
+      52             :               std::string& errorstr );
+      53             : ///
+      54             :   void evaluate( const std::vector<double>& invar, std::vector<double>& outvals, std::vector<std::vector<double> >& der ) const ;
+      55             : ///
+      56             :   unsigned getNumberOfKernels() const ;
+      57             : ///
+      58             :   std::vector<double> getKernelCenter( const unsigned& kno ) const ;
+      59             : ///
+      60             :   std::vector<double> getKernelSupport( const unsigned& kno ) const ;
+      61             : };
+      62             : 
+      63             : inline
+      64             : unsigned PammObject::getNumberOfKernels() const {
+      65         134 :   return kernels.size();
+      66             : }
+      67             : 
+      68             : inline
+      69             : std::vector<double> PammObject::getKernelCenter( const unsigned& kno ) const {
+      70          44 :   return kernels[kno]->getCenter();
+      71             : }
+      72             : 
+      73             : inline
+      74             : std::vector<double> PammObject::getKernelSupport( const unsigned& kno ) const {
+      75          44 :   return kernels[kno]->getContinuousSupport();
+      76             : }
+      77             : 
+      78             : }
+      79             : }
+      80             : 
+      81             : #endif
+      82             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/index-sort-f.html b/coverage/pamm/index-sort-f.html new file mode 100644 index 000000000000..6a7653c8cf1f --- /dev/null +++ b/coverage/pamm/index-sort-f.html @@ -0,0 +1,154 @@ + + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:21226181.2 %
Date:2024-02-22 21:58:45Functions:182572.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
HBPammHydrogens.cpp +
69.9%69.9%
+
69.9 %51 / 7360.0 %3 / 5
PAMM.cpp +
76.6%76.6%
+
76.6 %49 / 6462.5 %5 / 8
PammObject.cpp +
82.6%82.6%
+
82.6 %38 / 4675.0 %3 / 4
HBPammMatrix.cpp +
90.5%90.5%
+
90.5 %38 / 4280.0 %4 / 5
PammObject.h +
100.0%
+
100.0 %3 / 3-0 / 0
HBPammObject.h +
100.0%
+
100.0 %1 / 1-0 / 0
HBPammObject.cpp +
100.0%
+
100.0 %32 / 32100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/index-sort-l.html b/coverage/pamm/index-sort-l.html new file mode 100644 index 000000000000..9aacb450c4ee --- /dev/null +++ b/coverage/pamm/index-sort-l.html @@ -0,0 +1,154 @@ + + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:21226181.2 %
Date:2024-02-22 21:58:45Functions:182572.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
HBPammHydrogens.cpp +
69.9%69.9%
+
69.9 %51 / 7360.0 %3 / 5
PAMM.cpp +
76.6%76.6%
+
76.6 %49 / 6462.5 %5 / 8
PammObject.cpp +
82.6%82.6%
+
82.6 %38 / 4675.0 %3 / 4
HBPammMatrix.cpp +
90.5%90.5%
+
90.5 %38 / 4280.0 %4 / 5
HBPammObject.h +
100.0%
+
100.0 %1 / 1-0 / 0
PammObject.h +
100.0%
+
100.0 %3 / 3-0 / 0
HBPammObject.cpp +
100.0%
+
100.0 %32 / 32100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pamm/index.html b/coverage/pamm/index.html new file mode 100644 index 000000000000..f83ff522b9e2 --- /dev/null +++ b/coverage/pamm/index.html @@ -0,0 +1,154 @@ + + + + + + + + LCOV - plumed test coverage - pamm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pammHitTotalCoverage
Test:plumed test coverageLines:21226181.2 %
Date:2024-02-22 21:58:45Functions:182572.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
HBPammHydrogens.cpp +
69.9%69.9%
+
69.9 %51 / 7360.0 %3 / 5
HBPammMatrix.cpp +
90.5%90.5%
+
90.5 %38 / 4280.0 %4 / 5
HBPammObject.cpp +
100.0%
+
100.0 %32 / 32100.0 %3 / 3
HBPammObject.h +
100.0%
+
100.0 %1 / 1-0 / 0
PAMM.cpp +
76.6%76.6%
+
76.6 %49 / 6462.5 %5 / 8
PammObject.cpp +
82.6%82.6%
+
82.6 %38 / 4675.0 %3 / 4
PammObject.h +
100.0%
+
100.0 %3 / 3-0 / 0
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/PIV.cpp.func-sort-c.html b/coverage/piv/PIV.cpp.func-sort-c.html new file mode 100644 index 000000000000..75f7f0e612e9 --- /dev/null +++ b/coverage/piv/PIV.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - piv/PIV.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - piv - PIV.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3piv3PIV18checkFieldsAllowedEv0
_ZN4PLMD3piv3PIVC2ERKNS_13ActionOptionsE0
_ZN4PLMD3piv3PIVC1ERKNS_13ActionOptionsE12
_ZN4PLMD3piv3PIV16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3piv3PIV9calculateEv327
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/PIV.cpp.func.html b/coverage/piv/PIV.cpp.func.html new file mode 100644 index 000000000000..3d45b7775f14 --- /dev/null +++ b/coverage/piv/PIV.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - piv/PIV.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - piv - PIV.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3piv3PIV16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3piv3PIV18checkFieldsAllowedEv0
_ZN4PLMD3piv3PIV9calculateEv327
_ZN4PLMD3piv3PIVC1ERKNS_13ActionOptionsE12
_ZN4PLMD3piv3PIVC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/PIV.cpp.gcov.html b/coverage/piv/PIV.cpp.gcov.html new file mode 100644 index 000000000000..1d0349f0d6ca --- /dev/null +++ b/coverage/piv/PIV.cpp.gcov.html @@ -0,0 +1,1340 @@ + + + + + + + + LCOV - plumed test coverage - piv/PIV.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - piv - PIV.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2017 of Pipolo Silvio and Fabio Pietrucci.
+       3             : 
+       4             : The piv module is free software: you can redistribute it and/or modify
+       5             : it under the terms of the GNU Lesser General Public License as published by
+       6             : the Free Software Foundation, either version 3 of the License, or
+       7             : (at your option) any later version.
+       8             : 
+       9             : The piv module is distributed in the hope that it will be useful,
+      10             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      11             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      12             : GNU Lesser General Public License for more details.
+      13             : 
+      14             : You should have received a copy of the GNU Lesser General Public License
+      15             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      16             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      17             : #include "colvar/Colvar.h"
+      18             : #include "core/ActionRegister.h"
+      19             : #include "core/PlumedMain.h"
+      20             : #include "core/ActionWithVirtualAtom.h"
+      21             : #include "tools/NeighborList.h"
+      22             : #include "tools/SwitchingFunction.h"
+      23             : #include "tools/PDB.h"
+      24             : #include "tools/Pbc.h"
+      25             : #include "tools/Communicator.h"
+      26             : #include "tools/Stopwatch.h"
+      27             : #include "core/ActionSet.h"
+      28             : 
+      29             : #include <string>
+      30             : #include <cmath>
+      31             : #include <iostream>
+      32             : 
+      33             : using namespace std;
+      34             : 
+      35             : namespace PLMD
+      36             : {
+      37             : namespace piv
+      38             : {
+      39             : 
+      40             : //+PLUMEDOC PIVMOD_COLVAR PIV
+      41             : /*
+      42             : Calculates the PIV-distance.
+      43             : 
+      44             : PIV distance is the squared Cartesian distance between the PIV \cite gallet2013structural \cite pipolo2017navigating
+      45             : associated to the configuration of the system during the dynamics and a reference configuration provided
+      46             : as input (PDB file format).
+      47             : PIV can be used together with \ref FUNCPATHMSD to define a path in the PIV space.
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : The following example calculates PIV-distances from three reference configurations in Ref1.pdb, Ref2.pdb and Ref3.pdb
+      52             : and prints the results in a file named colvar.
+      53             : Three atoms (PIVATOMS=3) with names (pdb file) A B and C are used to construct the PIV and all PIV blocks (AA, BB, CC, AB, AC, BC) are considered.
+      54             : SFACTOR is a scaling factor that multiplies the contribution to the PIV-distance given by the single PIV block.
+      55             : NLIST sets the use of neighbor lists for calculating atom-atom distances.
+      56             : The SWITCH keyword specifies the parameters of the switching function that transforms atom-atom distances.
+      57             : SORT=1 means that the PIV block elements are sorted (SORT=0 no sorting.)
+      58             : Values for SORT, SFACTOR and the neighbor list parameters have to be specified for each block.
+      59             : The order is the following: AA,BB,CC,AB,AC,BC. If ONLYDIRECT (ONLYCROSS) is used the order is AA,BB,CC (AB,AC,BC).
+      60             : The sorting operation within each PIV block is performed using the counting sort algorithm, PRECISION specifies the size of the counting array.
+      61             : 
+      62             : \plumedfile
+      63             : PIV ...
+      64             : LABEL=Pivd1
+      65             : PRECISION=1000
+      66             : NLIST
+      67             : REF_FILE=Ref1.pdb
+      68             : PIVATOMS=3
+      69             : ATOMTYPES=A,B,C
+      70             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+      71             : SORT=1,1,1,1,1,1
+      72             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+      73             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+      74             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+      75             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+      76             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+      77             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+      78             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+      79             : NL_STRIDE=10,10,10,10,10,10
+      80             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+      81             : ... PIV
+      82             : PIV ...
+      83             : LABEL=Pivd2
+      84             : PRECISION=1000
+      85             : NLIST
+      86             : REF_FILE=Ref2.pdb
+      87             : PIVATOMS=3
+      88             : ATOMTYPES=A,B,C
+      89             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+      90             : SORT=1,1,1,1,1,1
+      91             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+      92             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+      93             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+      94             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+      95             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+      96             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+      97             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+      98             : NL_STRIDE=10,10,10,10,10,10
+      99             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+     100             : ... PIV
+     101             : PIV ...
+     102             : LABEL=Pivd3
+     103             : PRECISION=1000
+     104             : NLIST
+     105             : REF_FILE=Ref3.pdb
+     106             : PIVATOMS=3
+     107             : ATOMTYPES=A,B,C
+     108             : SFACTOR=0.3,0.5,1.0,0.2,0.2,0.2
+     109             : SORT=1,1,1,1,1,1
+     110             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     111             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+     112             : SWITCH3={RATIONAL R_0=0.4 MM=10 NN=5}
+     113             : SWITCH4={RATIONAL R_0=0.5 MM=12 NN=6}
+     114             : SWITCH5={RATIONAL R_0=0.5 MM=12 NN=6}
+     115             : SWITCH6={RATIONAL R_0=0.5 MM=12 NN=6}
+     116             : NL_CUTOFF=0.8,0.6,0.6,0.7,0.7,0.7
+     117             : NL_STRIDE=10,10,10,10,10,10
+     118             : NL_SKIN=0.1,0.1,0.1,0.1,0.1,0.1
+     119             : ... PIV
+     120             : 
+     121             : PRINT ARG=Pivd1,Pivd2,Pivd3 FILE=colvar
+     122             : \endplumedfile
+     123             : 
+     124             : WARNING:
+     125             : Both the "CRYST" and "ATOM" lines of the PDB files must conform precisely to the official pdb format, including the width of each alphanumerical field:
+     126             : 
+     127             : \verbatim
+     128             : CRYST1   31.028   36.957   23.143  89.93  92.31  89.99 P 1           1
+     129             : ATOM      1  OW1 wate    1      15.630  19.750   1.520  1.00  0.00
+     130             : \endverbatim
+     131             : 
+     132             : In each pdb frame, atoms must be numbered in the same order and with the same element symbol as in the input of the MD program.
+     133             : 
+     134             : The following example calculates the PIV-distances from two reference configurations Ref1.pdb and Ref2.pdb
+     135             : and uses PIV-distances to define a Path Collective Variable (\ref FUNCPATHMSD) with only two references (Ref1.pdb and Ref2.pdb).
+     136             : With the VOLUME keyword one scales the atom-atom distances by the cubic root of the ratio between the specified value and the box volume of the initial step of the trajectory file.
+     137             : 
+     138             : \plumedfile
+     139             : PIV ...
+     140             : LABEL=c1
+     141             : PRECISION=1000
+     142             : VOLUME=12.15
+     143             : NLIST
+     144             : REF_FILE=Ref1.pdb
+     145             : PIVATOMS=2
+     146             : ATOMTYPES=A,B
+     147             : ONLYDIRECT
+     148             : SFACTOR=1.0,0.2
+     149             : SORT=1,1
+     150             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     151             : SWITCH2={RATIONAL R_0=0.5 MM=10 NN=5}
+     152             : NL_CUTOFF=1.2,1.2
+     153             : NL_STRIDE=10,10
+     154             : NL_SKIN=0.1,0.1
+     155             : ... PIV
+     156             : PIV ...
+     157             : LABEL=c2
+     158             : PRECISION=1000
+     159             : VOLUME=12.15
+     160             : NLIST
+     161             : REF_FILE=Ref2.pdb
+     162             : PIVATOMS=2
+     163             : ATOMTYPES=A,B
+     164             : ONLYDIRECT
+     165             : SFACTOR=1.0,0.2
+     166             : SORT=1,1
+     167             : SWITCH1={RATIONAL R_0=0.6 MM=12 NN=4}
+     168             : SWITCH2={RATIONAL R_0=0.4 MM=10 NN=5}
+     169             : NL_CUTOFF=1.2,1.2
+     170             : NL_STRIDE=10,10
+     171             : NL_SKIN=0.1,0.1
+     172             : ... PIV
+     173             : 
+     174             : p1: FUNCPATHMSD ARG=c1,c2 LAMBDA=0.180338
+     175             : METAD ARG=p1.s,p1.z SIGMA=0.01,0.2 HEIGHT=0.8 PACE=500   LABEL=res
+     176             : PRINT ARG=c1,c2,p1.s,p1.z,res.bias STRIDE=500  FILE=colvar FMT=%15.6f
+     177             : \endplumedfile
+     178             : 
+     179             : When using PIV please cite \cite pipolo2017navigating .
+     180             : 
+     181             : (See also \ref PRINT)
+     182             : 
+     183             : */
+     184             : //+ENDPLUMEDOC
+     185             : 
+     186             : class PIV      : public Colvar
+     187             : {
+     188             : private:
+     189             :   bool pbc, serial, timer;
+     190             :   ForwardDecl<Stopwatch> stopwatch_fwd;
+     191             :   Stopwatch& stopwatch=*stopwatch_fwd;
+     192             :   int updatePIV;
+     193             :   size_t Nprec;
+     194             :   unsigned Natm,Nlist,NLsize;
+     195             :   double Fvol,Vol0,m_PIVdistance;
+     196             :   std::string ref_file;
+     197             :   std::unique_ptr<NeighborList> nlall;
+     198             :   std::vector<SwitchingFunction> sfs;
+     199             :   std::vector<std:: vector<double> > rPIV;
+     200             :   std::vector<double> scaling,r00;
+     201             :   std::vector<double> nl_skin;
+     202             :   std::vector<double> fmass;
+     203             :   std::vector<bool> dosort;
+     204             :   std::vector<Vector> compos;
+     205             :   std::vector<string> sw;
+     206             :   std::vector<std::unique_ptr<NeighborList>> nl;
+     207             :   std::vector<std::unique_ptr<NeighborList>> nlcom;
+     208             :   std::vector<Vector> m_deriv;
+     209             :   Tensor m_virial;
+     210             :   bool Svol,cross,direct,doneigh,test,CompDer,com;
+     211             : 
+     212             :   /// Local structure, used to store data that should be
+     213             :   /// shared across multiple PIV instances
+     214           6 :   struct SharedData {
+     215             :     int prev_stp=-1;
+     216             :     int init_stp=1;
+     217             :     std:: vector<std:: vector<Vector> > prev_pos;
+     218             :     std:: vector<std:: vector<double> > cPIV;
+     219             :     std:: vector<std:: vector<int> > Atom0;
+     220             :     std:: vector<std:: vector<int> > Atom1;
+     221             :   };
+     222             :   /// Owning pointer. Will only be allocated by the first PIV instance
+     223             :   std::unique_ptr<SharedData> sharedData_unique;
+     224             :   /// Raw pointer. Will have the same value for all PIV instances
+     225             :   SharedData* sharedData=nullptr;
+     226             : 
+     227             : public:
+     228             :   static void registerKeywords( Keywords& keys );
+     229             :   explicit PIV(const ActionOptions&);
+     230             :   // active methods:
+     231             :   virtual void calculate();
+     232           0 :   void checkFieldsAllowed() {}
+     233             : };
+     234             : 
+     235             : PLUMED_REGISTER_ACTION(PIV,"PIV")
+     236             : 
+     237          14 : void PIV::registerKeywords( Keywords& keys )
+     238             : {
+     239          14 :   Colvar::registerKeywords( keys );
+     240          28 :   keys.add("numbered","SWITCH","The switching functions parameter."
+     241             :            "You should specify a Switching function for all PIV blocks."
+     242             :            "Details of the various switching "
+     243             :            "functions you can use are provided on \\ref switchingfunction.");
+     244          28 :   keys.add("compulsory","PRECISION","the precision for approximating reals with integers in sorting.");
+     245          28 :   keys.add("compulsory","REF_FILE","PDB file name that contains the \\f$i\\f$th reference structure.");
+     246          28 :   keys.add("compulsory","PIVATOMS","Number of atoms to use for PIV.");
+     247          28 :   keys.add("compulsory","SORT","Whether to sort or not the PIV block.");
+     248          28 :   keys.add("compulsory","ATOMTYPES","The atom types to use for PIV.");
+     249          28 :   keys.add("optional","SFACTOR","Scale the PIV-distance by such block-specific factor");
+     250          28 :   keys.add("optional","VOLUME","Scale atom-atom distances by the cubic root of the cell volume. The input volume is used to scale the R_0 value of the switching function. ");
+     251          28 :   keys.add("optional","UPDATEPIV","Frequency (in steps) at which the PIV is updated.");
+     252          28 :   keys.addFlag("TEST",false,"Print the actual and reference PIV and exit");
+     253          28 :   keys.addFlag("COM",false,"Use centers of mass of groups of atoms instead of atoms as specified in the Pdb file");
+     254          28 :   keys.addFlag("ONLYCROSS",false,"Use only cross-terms (A-B, A-C, B-C, ...) in PIV");
+     255          28 :   keys.addFlag("ONLYDIRECT",false,"Use only direct-terms (A-A, B-B, C-C, ...) in PIV");
+     256          28 :   keys.addFlag("DERIVATIVES",false,"Activate the calculation of the PIV for every class (needed for numerical derivatives).");
+     257          28 :   keys.addFlag("NLIST",false,"Use a neighbor list for distance calculations.");
+     258          28 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+     259          28 :   keys.addFlag("TIMER",false,"Perform timing analysis on heavy loops.");
+     260          28 :   keys.add("optional","NL_CUTOFF","Neighbor lists cutoff.");
+     261          28 :   keys.add("optional","NL_STRIDE","Update neighbor lists every NL_STRIDE steps.");
+     262          28 :   keys.add("optional","NL_SKIN","The maximum atom displacement tolerated for the neighbor lists update.");
+     263          28 :   keys.reset_style("SWITCH","compulsory");
+     264          14 : }
+     265             : 
+     266          12 : PIV::PIV(const ActionOptions&ao):
+     267             :   PLUMED_COLVAR_INIT(ao),
+     268          12 :   pbc(true),
+     269          12 :   serial(false),
+     270          12 :   timer(false),
+     271          12 :   updatePIV(1),
+     272          12 :   Nprec(1000),
+     273          12 :   Natm(1),
+     274          12 :   Nlist(1),
+     275          12 :   NLsize(1),
+     276          12 :   Fvol(1.),
+     277          12 :   Vol0(0.),
+     278          12 :   m_PIVdistance(0.),
+     279          12 :   rPIV(std:: vector<std:: vector<double> >(Nlist)),
+     280          12 :   scaling(std:: vector<double>(Nlist)),
+     281          12 :   r00(std:: vector<double>(Nlist)),
+     282          12 :   nl_skin(std:: vector<double>(Nlist)),
+     283          12 :   fmass(std:: vector<double>(Nlist)),
+     284          12 :   dosort(std:: vector<bool>(Nlist)),
+     285          12 :   compos(std:: vector<Vector>(NLsize)),
+     286          12 :   sw(std:: vector<string>(Nlist)),
+     287          12 :   nl(Nlist),
+     288          12 :   nlcom(NLsize),
+     289          12 :   m_deriv(std:: vector<Vector>(1)),
+     290          12 :   Svol(false),
+     291          12 :   cross(true),
+     292          12 :   direct(true),
+     293          12 :   doneigh(false),
+     294          12 :   test(false),
+     295          12 :   CompDer(false),
+     296          24 :   com(false)
+     297             : {
+     298          12 :   log << "Starting PIV Constructor\n";
+     299             : 
+     300             :   {
+     301             :     // look for another PIV instance previously allocated
+     302          12 :     auto* previous=plumed.getActionSet().selectLatest<PIV*>(this);
+     303             : 
+     304             :     // Uncommenting the following line, it is possible to force
+     305             :     // a separate object per instance of the PIB object.
+     306             :     // Results are unaffected, but performance is worse.
+     307             :     // I think this is the expected behavior. GB
+     308             :     // previous=nullptr;
+     309             : 
+     310          12 :     if(!previous) {
+     311             :       // if not found, allocate the shared data struct
+     312           6 :       sharedData_unique=Tools::make_unique<SharedData>();
+     313             :       // then set the raw pointer
+     314           6 :       sharedData=sharedData_unique.get();
+     315             :     } else {
+     316             :       // if found, use the previous raw pointer
+     317           6 :       sharedData=previous->sharedData;
+     318           6 :       log << "(a previous PIV action was found)\n";
+     319             :     }
+     320             :   }
+     321             : 
+     322             :   // Precision on the real-to-integer transformation for the sorting
+     323          12 :   parse("PRECISION",Nprec);
+     324          12 :   if(Nprec<2) error("Precision must be => 2");
+     325             : 
+     326             :   // PBC
+     327          12 :   bool nopbc=!pbc;
+     328          12 :   parseFlag("NOPBC",nopbc);
+     329          12 :   pbc=!nopbc;
+     330          12 :   if(pbc) {
+     331          12 :     log << "Using Periodic Boundary Conditions\n";
+     332             :   } else  {
+     333           0 :     log << "Isolated System (NO PBC)\n";
+     334             :   }
+     335             : 
+     336             :   // SERIAL/PARALLEL
+     337          12 :   parseFlag("SERIAL",serial);
+     338          12 :   if(serial) {
+     339           0 :     log << "Serial PIV construction\n";
+     340             :   } else     {
+     341          12 :     log << "Parallel PIV construction\n";
+     342             :   }
+     343             : 
+     344             :   // Derivatives
+     345          12 :   parseFlag("DERIVATIVES",CompDer);
+     346          12 :   if(CompDer) log << "Computing Derivatives\n";
+     347             : 
+     348             :   // Timing
+     349          12 :   parseFlag("TIMER",timer);
+     350          12 :   if(timer) {
+     351           1 :     log << "Timing analysis\n";
+     352           1 :     stopwatch.start();
+     353           1 :     stopwatch.pause();
+     354             :   }
+     355             : 
+     356             :   // Test
+     357          12 :   parseFlag("TEST",test);
+     358             : 
+     359             :   // UPDATEPIV
+     360          24 :   if(keywords.exists("UPDATEPIV")) {
+     361          24 :     parse("UPDATEPIV",updatePIV);
+     362             :   }
+     363             : 
+     364             :   // Test
+     365          12 :   parseFlag("COM",com);
+     366          12 :   if(com) log << "Building PIV using COMs\n";
+     367             : 
+     368             :   // Volume Scaling
+     369          12 :   parse("VOLUME",Vol0);
+     370          12 :   if (Vol0>0) {
+     371          12 :     Svol=true;
+     372             :   }
+     373             : 
+     374             :   // PIV direct and cross blocks
+     375          12 :   bool oc=false,od=false;
+     376          12 :   parseFlag("ONLYCROSS",oc);
+     377          12 :   parseFlag("ONLYDIRECT",od);
+     378          12 :   if (oc&&od) {
+     379           0 :     error("ONLYCROSS and ONLYDIRECT are incompatible options!");
+     380             :   }
+     381          12 :   if(oc) {
+     382           4 :     direct=false;
+     383           4 :     log << "Using only CROSS-PIV blocks\n";
+     384             :   }
+     385          12 :   if(od) {
+     386           4 :     cross=false;
+     387           4 :     log << "Using only DIRECT-PIV blocks\n";
+     388             :   }
+     389             : 
+     390             :   // Atoms for PIV
+     391          12 :   parse("PIVATOMS",Natm);
+     392          12 :   std:: vector<string> atype(Natm);
+     393          12 :   parseVector("ATOMTYPES",atype);
+     394             :   //if(atype.size()!=getNumberOfArguments() && atype.size()!=0) error("not enough values for ATOMTYPES");
+     395             : 
+     396             :   // Reference PDB file
+     397          12 :   parse("REF_FILE",ref_file);
+     398          12 :   PDB mypdb;
+     399          12 :   FILE* fp=fopen(ref_file.c_str(),"r");
+     400          12 :   if (fp!=NULL) {
+     401          12 :     log<<"Opening PDB file with reference frame: "<<ref_file.c_str()<<"\n";
+     402          12 :     mypdb.readFromFilepointer(fp,usingNaturalUnits(),0.1/getUnits().getLength());
+     403          12 :     fclose (fp);
+     404             :   } else {
+     405           0 :     error("Error in reference PDB file");
+     406             :   }
+     407             : 
+     408             :   // Build COM/Atom lists of AtomNumbers (this might be done in PBC.cpp)
+     409             :   // Atomlist or Plist used to build pair lists
+     410          12 :   std:: vector<std:: vector<AtomNumber> > Plist(Natm);
+     411             :   // Atomlist used to build list of atoms for each COM
+     412          12 :   std:: vector<std:: vector<AtomNumber> > comatm(1);
+     413             :   // NLsize is the number of atoms in the pdb cell
+     414          12 :   NLsize=mypdb.getAtomNumbers().size();
+     415             :   // In the following P stands for Point (either an Atom or a COM)
+     416             :   unsigned resnum=0;
+     417             :   // Presind (array size: number of residues) contains the contains the residue number
+     418             :   //   this is because the residue numbers may not always be ordered from 1 to resnum
+     419             :   std:: vector<unsigned> Presind;
+     420             :   // Build Presind
+     421       19404 :   for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     422       19392 :     unsigned rind=mypdb.getResidueNumber(mypdb.getAtomNumbers()[i]);
+     423             :     bool oldres=false;
+     424     7705008 :     for (unsigned j=0; j<Presind.size(); j++) {
+     425     7685616 :       if(rind==Presind[j]) {
+     426             :         oldres=true;
+     427             :       }
+     428             :     }
+     429       19392 :     if(!oldres) {
+     430        4848 :       Presind.push_back(rind);
+     431             :     }
+     432             :   }
+     433          12 :   resnum=Presind.size();
+     434             : 
+     435             :   // Pind0 is the atom/COM used in Nlists (for COM Pind0 is the first atom in the pdb belonging to that COM)
+     436             :   unsigned Pind0size;
+     437          12 :   if(com) {
+     438             :     Pind0size=resnum;
+     439             :   } else {
+     440          12 :     Pind0size=NLsize;
+     441             :   }
+     442          12 :   std:: vector<unsigned> Pind0(Pind0size);
+     443             :   // If COM resize important arrays
+     444          12 :   comatm.resize(NLsize);
+     445          12 :   if(com) {
+     446           0 :     nlcom.resize(NLsize);
+     447           0 :     compos.resize(NLsize);
+     448           0 :     fmass.resize(NLsize,0.);
+     449             :   }
+     450          12 :   log << "Total COM/Atoms: " << Natm*resnum << " \n";
+     451             :   // Build lists of Atoms/COMs for NLists
+     452             :   //   comatm filled also for non_COM calculation for analysis purposes
+     453          36 :   for (unsigned j=0; j<Natm; j++) {
+     454             :     unsigned oind;
+     455       38808 :     for (unsigned i=0; i<Pind0.size(); i++) {
+     456       38784 :       Pind0[i]=0;
+     457             :     }
+     458       38808 :     for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     459             :       // Residue/Atom AtomNumber: used to build NL for COMS/Atoms pairs.
+     460       38784 :       AtomNumber anum=mypdb.getAtomNumbers()[i];
+     461             :       // ResidueName/Atomname associated to atom
+     462       38784 :       string rname=mypdb.getResidueName(anum);
+     463       38784 :       string aname=mypdb.getAtomName(anum);
+     464             :       // Index associated to residue/atom: used to separate COM-lists
+     465       38784 :       unsigned rind=mypdb.getResidueNumber(anum);
+     466             :       unsigned aind=anum.index();
+     467             :       // This builds lists for NL
+     468             :       string Pname;
+     469             :       unsigned Pind;
+     470       38784 :       if(com) {
+     471             :         Pname=rname;
+     472           0 :         for(unsigned l=0; l<resnum; l++) {
+     473           0 :           if(rind==Presind[l]) {
+     474             :             Pind=l;
+     475             :           }
+     476             :         }
+     477             :       } else {
+     478             :         Pname=aname;
+     479             :         Pind=aind;
+     480             :       }
+     481       38784 :       if(Pname==atype[j]) {
+     482       14544 :         if(Pind0[Pind]==0) {
+     483             :           // adding the atomnumber to the atom/COM list for pairs
+     484       14544 :           Plist[j].push_back(anum);
+     485       14544 :           Pind0[Pind]=aind+1;
+     486             :           oind=Pind;
+     487             :         }
+     488             :         // adding the atomnumber to list of atoms for every COM/Atoms
+     489       14544 :         comatm[Pind0[Pind]-1].push_back(anum);
+     490             :       }
+     491             :     }
+     492             :     // Output Lists
+     493          24 :     log << "  Groups of type  " << j << ": " << Plist[j].size() << " \n";
+     494             :     string gname;
+     495             :     unsigned gsize;
+     496          24 :     if(com) {
+     497           0 :       gname=mypdb.getResidueName(comatm[Pind0[oind]-1][0]);
+     498           0 :       gsize=comatm[Pind0[oind]-1].size();
+     499             :     } else {
+     500          48 :       gname=mypdb.getAtomName(comatm[Pind0[oind]-1][0]);
+     501             :       gsize=1;
+     502             :     }
+     503          24 :     log.printf("    %6s %3s %13s %10i %6s\n", "type  ", gname.c_str(),"   containing ",gsize," atoms");
+     504             :   }
+     505             : 
+     506             :   // This is to build the list with all the atoms
+     507             :   std:: vector<AtomNumber> listall;
+     508       19404 :   for (unsigned i=0; i<mypdb.getAtomNumbers().size(); i++) {
+     509       19392 :     listall.push_back(mypdb.getAtomNumbers()[i]);
+     510             :   }
+     511             : 
+     512             :   // PIV blocks and Neighbour Lists
+     513          12 :   Nlist=0;
+     514             :   // Direct adds the A-A ad B-B blocks (N)
+     515          12 :   if(direct) {
+     516           8 :     Nlist=Nlist+unsigned(Natm);
+     517             :   }
+     518             :   // Cross adds the A-B blocks (N*(N-1)/2)
+     519          12 :   if(cross) {
+     520           8 :     Nlist=Nlist+unsigned(double(Natm*(Natm-1))/2.);
+     521             :   }
+     522             :   // Resize vectors according to Nlist
+     523          12 :   rPIV.resize(Nlist);
+     524             : 
+     525             :   // PIV scaled option
+     526          12 :   scaling.resize(Nlist);
+     527          36 :   for(unsigned j=0; j<Nlist; j++) {
+     528          24 :     scaling[j]=1.;
+     529             :   }
+     530          24 :   if(keywords.exists("SFACTOR")) {
+     531          24 :     parseVector("SFACTOR",scaling);
+     532             :     //if(scaling.size()!=getNumberOfArguments() && scaling.size()!=0) error("not enough values for SFACTOR");
+     533             :   }
+     534             :   // Neighbour Lists option
+     535          12 :   parseFlag("NLIST",doneigh);
+     536          12 :   nl.resize(Nlist);
+     537          12 :   nl_skin.resize(Nlist);
+     538          12 :   if(doneigh) {
+     539          12 :     std:: vector<double> nl_cut(Nlist,0.);
+     540          12 :     std:: vector<int> nl_st(Nlist,0);
+     541          12 :     parseVector("NL_CUTOFF",nl_cut);
+     542             :     //if(nl_cut.size()!=getNumberOfArguments() && nl_cut.size()!=0) error("not enough values for NL_CUTOFF");
+     543          12 :     parseVector("NL_STRIDE",nl_st);
+     544             :     //if(nl_st.size()!=getNumberOfArguments() && nl_st.size()!=0) error("not enough values for NL_STRIDE");
+     545          12 :     parseVector("NL_SKIN",nl_skin);
+     546             :     //if(nl_skin.size()!=getNumberOfArguments() && nl_skin.size()!=0) error("not enough values for NL_SKIN");
+     547          36 :     for (unsigned j=0; j<Nlist; j++) {
+     548          24 :       if(nl_cut[j]<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     549          24 :       if(nl_st[j]<=0) error("NL_STRIDE should be explicitly specified and positive");
+     550          24 :       if(nl_skin[j]<=0.) error("NL_SKIN should be explicitly specified and positive");
+     551          24 :       nl_cut[j]=nl_cut[j]+nl_skin[j];
+     552             :     }
+     553          12 :     log << "Creating Neighbor Lists \n";
+     554             :     // WARNING: is nl_cut meaningful here?
+     555          24 :     nlall= Tools::make_unique<NeighborList>(listall,true,pbc,getPbc(),comm,nl_cut[0],nl_st[0]);
+     556          12 :     if(com) {
+     557             :       //Build lists of Atoms for every COM
+     558           0 :       for (unsigned i=0; i<compos.size(); i++) {
+     559             :         // WARNING: is nl_cut meaningful here?
+     560           0 :         nlcom[i] = Tools::make_unique<NeighborList>(comatm[i],true,pbc,getPbc(),comm,nl_cut[0],nl_st[0]);
+     561             :       }
+     562             :     }
+     563             :     unsigned ncnt=0;
+     564             :     // Direct blocks AA, BB, CC, ...
+     565          12 :     if(direct) {
+     566          24 :       for (unsigned j=0; j<Natm; j++) {
+     567          16 :         nl[ncnt]= Tools::make_unique<NeighborList>(Plist[j],true,pbc,getPbc(),comm,nl_cut[j],nl_st[j]);
+     568          16 :         ncnt+=1;
+     569             :       }
+     570             :     }
+     571             :     // Cross blocks AB, AC, BC, ...
+     572          12 :     if(cross) {
+     573          24 :       for (unsigned j=0; j<Natm; j++) {
+     574          24 :         for (unsigned i=j+1; i<Natm; i++) {
+     575          16 :           nl[ncnt]= Tools::make_unique<NeighborList>(Plist[i],Plist[j],true,false,pbc,getPbc(),comm,nl_cut[ncnt],nl_st[ncnt]);
+     576           8 :           ncnt+=1;
+     577             :         }
+     578             :       }
+     579             :     }
+     580             :   } else {
+     581           0 :     log << "WARNING: Neighbor List not activated this has not been tested!!  \n";
+     582           0 :     nlall= Tools::make_unique<NeighborList>(listall,true,pbc,getPbc(),comm);
+     583           0 :     for (unsigned j=0; j<Nlist; j++) {
+     584           0 :       nl[j]= Tools::make_unique<NeighborList>(Plist[j],Plist[j],true,true,pbc,getPbc(),comm);
+     585             :     }
+     586             :   }
+     587             :   // Output Nlist
+     588          12 :   log << "Total Nlists: " << Nlist << " \n";
+     589          36 :   for (unsigned j=0; j<Nlist; j++) {
+     590          24 :     log << "  list " << j+1 << "   size " << nl[j]->size() << " \n";
+     591             :   }
+     592             :   // Calculate COM masses once and for all from lists
+     593          12 :   if(com) {
+     594           0 :     for(unsigned j=0; j<compos.size(); j++) {
+     595             :       double commass=0.;
+     596           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     597           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     598           0 :         commass+=mypdb.getOccupancy()[andx];
+     599             :       }
+     600           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     601           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     602           0 :         if(commass>0.) {
+     603           0 :           fmass[andx]=mypdb.getOccupancy()[andx]/commass;
+     604             :         } else {
+     605           0 :           fmass[andx]=1.;
+     606             :         }
+     607             :       }
+     608             :     }
+     609             :   }
+     610             : 
+     611             :   // Sorting
+     612          12 :   dosort.resize(Nlist);
+     613          12 :   std:: vector<int> ynsort(Nlist);
+     614          12 :   parseVector("SORT",ynsort);
+     615          36 :   for (unsigned i=0; i<Nlist; i++) {
+     616          24 :     if(ynsort[i]==0||CompDer) {
+     617             :       dosort[i]=false;
+     618             :     } else {
+     619             :       dosort[i]=true;
+     620             :     }
+     621             :   }
+     622             : 
+     623             :   //build box vectors and correct for pbc
+     624          12 :   log << "Building the box from PDB data ... \n";
+     625          12 :   Tensor Box=mypdb.getBoxVec();
+     626          12 :   log << "  Done! A,B,C vectors in Cartesian space:  \n";
+     627          12 :   log.printf("  A:  %12.6f%12.6f%12.6f\n", Box[0][0],Box[0][1],Box[0][2]);
+     628          12 :   log.printf("  B:  %12.6f%12.6f%12.6f\n", Box[1][0],Box[1][1],Box[1][2]);
+     629          12 :   log.printf("  C:  %12.6f%12.6f%12.6f\n", Box[2][0],Box[2][1],Box[2][2]);
+     630          12 :   log << "Changing the PBC according to the new box \n";
+     631          12 :   Pbc mypbc;
+     632          12 :   mypbc.setBox(Box);
+     633          12 :   log << "The box volume is " << mypbc.getBox().determinant() << " \n";
+     634             : 
+     635             :   //Compute scaling factor
+     636          12 :   if(Svol) {
+     637          12 :     Fvol=cbrt(Vol0/mypbc.getBox().determinant());
+     638          12 :     log << "Scaling atom distances by  " << Fvol << " \n";
+     639             :   } else {
+     640           0 :     log << "Using unscaled atom distances \n";
+     641             :   }
+     642             : 
+     643          12 :   r00.resize(Nlist);
+     644          12 :   sw.resize(Nlist);
+     645          36 :   for (unsigned j=0; j<Nlist; j++) {
+     646          48 :     if( !parseNumbered( "SWITCH", j+1, sw[j] ) ) break;
+     647             :   }
+     648          12 :   if(CompDer) {
+     649             :     // Set switching function parameters here only if computing derivatives
+     650             :     //   now set at the beginning of the dynamics to solve the r0 issue
+     651           6 :     log << "Switching Function Parameters \n";
+     652           6 :     sfs.resize(Nlist);
+     653             :     std::string errors;
+     654          18 :     for (unsigned j=0; j<Nlist; j++) {
+     655          12 :       if(Svol) {
+     656             :         double r0;
+     657             :         std::string old_r0;
+     658          12 :         vector<string> data=Tools::getWords(sw[j]);
+     659             :         data.erase(data.begin());
+     660          12 :         Tools::parse(data,"R_0",old_r0);
+     661          12 :         Tools::convert(old_r0,r0);
+     662          12 :         r0*=Fvol;
+     663          12 :         std::string new_r0; Tools::convert(r0,new_r0);
+     664          12 :         std::size_t pos = sw[j].find("R_0");
+     665          12 :         sw[j].replace(pos+4,old_r0.size(),new_r0);
+     666          12 :       }
+     667          12 :       sfs[j].set(sw[j],errors);
+     668             :       std::string num;
+     669          12 :       Tools::convert(j+1, num);
+     670          12 :       if( errors.length()!=0 ) error("problem reading SWITCH" + num + " keyword : " + errors );
+     671          12 :       r00[j]=sfs[j].get_r0();
+     672          12 :       log << "  Swf: " << j << "  r0=" << (sfs[j].description()).c_str() << " \n";
+     673             :     }
+     674             :   }
+     675             : 
+     676             :   // build COMs from positions if requested
+     677          12 :   if(com) {
+     678           0 :     for(unsigned j=0; j<compos.size(); j++) {
+     679           0 :       compos[j][0]=0.;
+     680           0 :       compos[j][1]=0.;
+     681           0 :       compos[j][2]=0.;
+     682           0 :       for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     683           0 :         unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     684           0 :         compos[j]+=fmass[andx]*mypdb.getPositions()[andx];
+     685             :       }
+     686             :     }
+     687             :   }
+     688             :   // build the rPIV distances (transformation and sorting is done afterwards)
+     689          12 :   if(CompDer) {
+     690           6 :     log << "  PIV  |  block   |     Size      |     Zeros     |     Ones      |" << " \n";
+     691             :   }
+     692          36 :   for(unsigned j=0; j<Nlist; j++) {
+     693    11516328 :     for(unsigned i=0; i<nl[j]->size(); i++) {
+     694    11516304 :       unsigned i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+     695    11516304 :       unsigned i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+     696             :       //calculate/get COM position of centers i0 and i1
+     697    11516304 :       Vector Pos0,Pos1;
+     698    11516304 :       if(com) {
+     699             :         //if(pbc) makeWhole();
+     700           0 :         Pos0=compos[i0];
+     701           0 :         Pos1=compos[i1];
+     702             :       } else {
+     703    11516304 :         Pos0=mypdb.getPositions()[i0];
+     704    11516304 :         Pos1=mypdb.getPositions()[i1];
+     705             :       }
+     706    11516304 :       Vector ddist;
+     707    11516304 :       if(pbc) {
+     708    11516304 :         ddist=mypbc.distance(Pos0,Pos1);
+     709             :       } else {
+     710           0 :         ddist=delta(Pos0,Pos1);
+     711             :       }
+     712    11516304 :       double df=0.;
+     713             :       // Transformation and sorting done at the first timestep to solve the r0 definition issue
+     714    11516304 :       if(CompDer) {
+     715        1104 :         rPIV[j].push_back(sfs[j].calculate(ddist.modulo()*Fvol, df));
+     716             :       } else {
+     717    11515200 :         rPIV[j].push_back(ddist.modulo()*Fvol);
+     718             :       }
+     719             :     }
+     720          24 :     if(CompDer) {
+     721          12 :       if(dosort[j]) {
+     722           0 :         std::sort(rPIV[j].begin(),rPIV[j].end());
+     723             :       }
+     724             :       int lmt0=0;
+     725             :       int lmt1=0;
+     726        1116 :       for(unsigned i=0; i<rPIV[j].size(); i++) {
+     727        1104 :         if(int(rPIV[j][i]*double(Nprec-1))==0) {
+     728           0 :           lmt0+=1;
+     729             :         }
+     730        1104 :         if(int(rPIV[j][i]*double(Nprec-1))==1) {
+     731           0 :           lmt1+=1;
+     732             :         }
+     733             :       }
+     734          12 :       log.printf("       |%10i|%15zu|%15i|%15i|\n", j, rPIV[j].size(), lmt0, lmt1);
+     735             :     }
+     736             :   }
+     737             : 
+     738          12 :   checkRead();
+     739             :   // From the plumed manual on how to build-up a new Colvar
+     740          24 :   addValueWithDerivatives();
+     741          12 :   requestAtoms(nlall->getFullAtomList());
+     742          12 :   setNotPeriodic();
+     743             :   // getValue()->setPeridodicity(false);
+     744             :   // set size of derivative vector
+     745          12 :   m_deriv.resize(getNumberOfAtoms());
+     746          12 : }
+     747             : 
+     748         327 : void PIV::calculate()
+     749             : {
+     750             : 
+     751             :   // Local variables
+     752             : 
+     753         327 :   if(sharedData_unique) {
+     754             :     // This is executed by the first PIV instance.
+     755             :     // We initialize variables with the correct Nlist.
+     756         321 :     sharedData_unique->prev_pos.resize(Nlist);
+     757         321 :     sharedData_unique->cPIV.resize(Nlist);
+     758         321 :     sharedData_unique->Atom0.resize(Nlist);
+     759         321 :     sharedData_unique->Atom1.resize(Nlist);
+     760             :   }
+     761             : 
+     762             :   // create references to minimize the impact of the code below
+     763         327 :   auto & prev_stp(sharedData->prev_stp);
+     764             :   auto & init_stp(sharedData->init_stp);
+     765             :   auto & prev_pos(sharedData->prev_pos);
+     766             :   auto & cPIV(sharedData->cPIV);
+     767             :   auto & Atom0(sharedData->Atom0);
+     768             :   auto & Atom1(sharedData->Atom1);
+     769             : 
+     770         327 :   std:: vector<std:: vector<int> > A0(Nprec);
+     771         327 :   std:: vector<std:: vector<int> > A1(Nprec);
+     772             :   size_t stride=1;
+     773             :   unsigned rank=0;
+     774             : 
+     775         327 :   if(!serial) {
+     776         327 :     stride=comm.Get_size();
+     777         327 :     rank=comm.Get_rank();
+     778             :   } else {
+     779             :     stride=1;
+     780             :     rank=0;
+     781             :   }
+     782             : 
+     783             :   // Transform (and sort) the rPIV before starting the dynamics
+     784         327 :   if (((prev_stp==-1) || (init_stp==1)) &&!CompDer) {
+     785           6 :     if(prev_stp!=-1) {init_stp=0;}
+     786             :     // Calculate the volume scaling factor
+     787           6 :     if(Svol) {
+     788           6 :       Fvol=cbrt(Vol0/getBox().determinant());
+     789             :     }
+     790             :     //Set switching function parameters
+     791           6 :     log << "\n";
+     792           6 :     log << "REFERENCE PDB # " << prev_stp+2 << " \n";
+     793             :     // Set switching function parameters here only if computing derivatives
+     794             :     //   now set at the beginning of the dynamics to solve the r0 issue
+     795           6 :     log << "Switching Function Parameters \n";
+     796           6 :     sfs.resize(Nlist);
+     797             :     std::string errors;
+     798          18 :     for (unsigned j=0; j<Nlist; j++) {
+     799          12 :       if(Svol) {
+     800             :         double r0;
+     801             :         std::string old_r0;
+     802          12 :         vector<string> data=Tools::getWords(sw[j]);
+     803             :         data.erase(data.begin());
+     804          12 :         Tools::parse(data,"R_0",old_r0);
+     805          12 :         Tools::convert(old_r0,r0);
+     806          12 :         r0*=Fvol;
+     807          12 :         std::string new_r0; Tools::convert(r0,new_r0);
+     808          12 :         std::size_t pos = sw[j].find("R_0");
+     809          12 :         sw[j].replace(pos+4,old_r0.size(),new_r0);
+     810          12 :       }
+     811          12 :       sfs[j].set(sw[j],errors);
+     812             :       std::string num;
+     813          12 :       Tools::convert(j+1, num);
+     814          12 :       if( errors.length()!=0 ) error("problem reading SWITCH" + num + " keyword : " + errors );
+     815          12 :       r00[j]=sfs[j].get_r0();
+     816          12 :       log << "  Swf: " << j << "  r0=" << (sfs[j].description()).c_str() << " \n";
+     817             :     }
+     818             :     //Transform and sort
+     819           6 :     log << "Building Reference PIV Vector \n";
+     820           6 :     log << "  PIV  |  block   |     Size      |     Zeros     |     Ones      |" << " \n";
+     821           6 :     double df=0.;
+     822          18 :     for (unsigned j=0; j<Nlist; j++) {
+     823    11515212 :       for (unsigned i=0; i<rPIV[j].size(); i++) {
+     824    11515200 :         rPIV[j][i]=sfs[j].calculate(rPIV[j][i], df);
+     825             :       }
+     826          12 :       if(dosort[j]) {
+     827          12 :         std::sort(rPIV[j].begin(),rPIV[j].end());
+     828             :       }
+     829             :       int lmt0=0;
+     830             :       int lmt1=0;
+     831    11515212 :       for(unsigned i=0; i<rPIV[j].size(); i++) {
+     832    11515200 :         if(int(rPIV[j][i]*double(Nprec-1))==0) {
+     833          26 :           lmt0+=1;
+     834             :         }
+     835    11515200 :         if(int(rPIV[j][i]*double(Nprec-1))==1) {
+     836       63358 :           lmt1+=1;
+     837             :         }
+     838             :       }
+     839          12 :       log.printf("       |%10i|%15zu|%15i|%15i|\n", j, rPIV[j].size(), lmt0, lmt1);
+     840             :     }
+     841           6 :     log << "\n";
+     842             :   }
+     843             :   // Do the sorting only once per timestep to avoid building the PIV N times for N rPIV PDB structures!
+     844         327 :   if ((getStep()>prev_stp&&getStep()%updatePIV==0)||CompDer) {
+     845         324 :     if (CompDer) log << " Step " << getStep() << "  Computing Derivatives NON-SORTED PIV \n";
+     846             :     //
+     847             :     // build COMs from positions if requested
+     848         324 :     if(com) {
+     849           0 :       if(pbc) makeWhole();
+     850           0 :       for(unsigned j=0; j<compos.size(); j++) {
+     851           0 :         compos[j][0]=0.;
+     852           0 :         compos[j][1]=0.;
+     853           0 :         compos[j][2]=0.;
+     854           0 :         for(unsigned i=0; i<nlcom[j]->getFullAtomList().size(); i++) {
+     855           0 :           unsigned andx=nlcom[j]->getFullAtomList()[i].index();
+     856           0 :           compos[j]+=fmass[andx]*getPosition(andx);
+     857             :         }
+     858             :       }
+     859             :     }
+     860             :     // update neighbor lists when an atom moves out of the Neighbor list skin
+     861         324 :     if (doneigh) {
+     862             :       bool doupdate=false;
+     863             :       // For the first step build previous positions = actual positions
+     864         324 :       if (prev_stp==-1) {
+     865           6 :         bool docom=com;
+     866          18 :         for (unsigned j=0; j<Nlist; j++) {
+     867        9708 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     868        9696 :             Vector Pos;
+     869        9696 :             if(docom) {
+     870           0 :               Pos=compos[i];
+     871             :             } else {
+     872        9696 :               Pos=getPosition(nl[j]->getFullAtomList()[i].index());
+     873             :             }
+     874        9696 :             prev_pos[j].push_back(Pos);
+     875             :           }
+     876             :         }
+     877             :         doupdate=true;
+     878             :       }
+     879             :       // Decide whether to update lists based on atom displacement, every stride
+     880         324 :       std:: vector<std:: vector<Vector> > tmp_pos(Nlist);
+     881         324 :       if (getStep() % nlall->getStride() ==0) {
+     882         324 :         bool docom=com;
+     883         972 :         for (unsigned j=0; j<Nlist; j++) {
+     884       20520 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     885       19872 :             Vector Pos;
+     886       19872 :             if(docom) {
+     887           0 :               Pos=compos[i];
+     888             :             } else {
+     889       19872 :               Pos=getPosition(nl[j]->getFullAtomList()[i].index());
+     890             :             }
+     891       19872 :             tmp_pos[j].push_back(Pos);
+     892       19872 :             if (pbcDistance(tmp_pos[j][i],prev_pos[j][i]).modulo()>=nl_skin[j]) {
+     893             :               doupdate=true;
+     894             :             }
+     895             :           }
+     896             :         }
+     897             :       }
+     898             :       // Update Nlists if needed
+     899         324 :       if (doupdate==true) {
+     900          18 :         for (unsigned j=0; j<Nlist; j++) {
+     901        9708 :           for (unsigned i=0; i<nl[j]->getFullAtomList().size(); i++) {
+     902        9696 :             prev_pos[j][i]=tmp_pos[j][i];
+     903             :           }
+     904          12 :           nl[j]->update(prev_pos[j]);
+     905          12 :           log << " Step " << getStep() << "  Neighbour lists updated " << nl[j]->size() << " \n";
+     906             :         }
+     907             :       }
+     908         324 :     }
+     909             :     // Calculate the volume scaling factor
+     910         324 :     if(Svol) {
+     911         324 :       Fvol=cbrt(Vol0/getBox().determinant());
+     912             :     }
+     913         324 :     Vector ddist;
+     914             :     // Global to local variables
+     915         324 :     bool doserial=serial;
+     916             :     // Build "Nlist" PIV blocks
+     917         972 :     for(unsigned j=0; j<Nlist; j++) {
+     918         648 :       if(dosort[j]) {
+     919             :         // from global to local variables to speedup the for loop with if statements
+     920           6 :         bool docom=com;
+     921           6 :         bool dopbc=pbc;
+     922             :         // Vectors collecting occupancies: OrdVec one rank, OrdVecAll all ranks
+     923           6 :         std:: vector<int> OrdVec(Nprec,0);
+     924           6 :         cPIV[j].resize(0);
+     925           6 :         Atom0[j].resize(0);
+     926           6 :         Atom1[j].resize(0);
+     927             :         // Building distances for the PIV vector at time t
+     928           6 :         if(timer) stopwatch.start("1 Build cPIV");
+     929     5757606 :         for(unsigned i=rank; i<nl[j]->size(); i+=stride) {
+     930     5757600 :           unsigned i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+     931     5757600 :           unsigned i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+     932     5757600 :           Vector Pos0,Pos1;
+     933     5757600 :           if(docom) {
+     934           0 :             Pos0=compos[i0];
+     935           0 :             Pos1=compos[i1];
+     936             :           } else {
+     937     5757600 :             Pos0=getPosition(i0);
+     938     5757600 :             Pos1=getPosition(i1);
+     939             :           }
+     940     5757600 :           if(dopbc) {
+     941     5757600 :             ddist=pbcDistance(Pos0,Pos1);
+     942             :           } else {
+     943           0 :             ddist=delta(Pos0,Pos1);
+     944             :           }
+     945     5757600 :           double df=0.;
+     946             :           //Integer sorting ... faster!
+     947             :           //Transforming distances with the Switching function + real to integer transformation
+     948     5757600 :           int Vint=int(sfs[j].calculate(ddist.modulo()*Fvol, df)*double(Nprec-1)+0.5);
+     949             :           //Integer transformed distance values as index of the Ordering Vector OrdVec
+     950     5757600 :           OrdVec[Vint]+=1;
+     951             :           //Keeps track of atom indices for force and virial calculations
+     952     5757600 :           A0[Vint].push_back(i0);
+     953     5757600 :           A1[Vint].push_back(i1);
+     954             :         }
+     955           6 :         if(timer) stopwatch.stop("1 Build cPIV");
+     956           6 :         if(timer) stopwatch.start("2 Sort cPIV");
+     957           6 :         if(!doserial && comm.initialized()) {
+     958             :           // Vectors keeping track of the dimension and the starting-position of the rank-specific pair vector in the big pair vector.
+     959           0 :           std:: vector<int> Vdim(stride,0);
+     960           0 :           std:: vector<int> Vpos(stride,0);
+     961             :           // Vectors collecting occupancies: OrdVec one rank, OrdVecAll all ranks
+     962           0 :           std:: vector<int> OrdVecAll(stride*Nprec);
+     963             :           // Big vectors containing all Atom indexes for every occupancy (Atom0O(Nprec,n) and Atom1O(Nprec,n) matrices in one vector)
+     964             :           std:: vector<int> Atom0F;
+     965             :           std:: vector<int> Atom1F;
+     966             :           // Vector used to reconstruct arrays
+     967           0 :           std:: vector<unsigned> k(stride,0);
+     968             :           // Zeros might be many, this slows down a lot due to MPI communication
+     969             :           // Avoid passing the zeros (i=1) for atom indices
+     970           0 :           for(unsigned i=1; i<Nprec; i++) {
+     971             :             // Building long vectors with all atom indexes for occupancies ordered from i=1 to i=Nprec-1
+     972             :             // Can this be avoided ???
+     973           0 :             Atom0F.insert(Atom0F.end(),A0[i].begin(),A0[i].end());
+     974           0 :             Atom1F.insert(Atom1F.end(),A1[i].begin(),A1[i].end());
+     975           0 :             A0[i].resize(0);
+     976           0 :             A1[i].resize(0);
+     977             :           }
+     978             :           // Resize partial arrays to fill up for the next PIV block
+     979           0 :           A0[0].resize(0);
+     980           0 :           A1[0].resize(0);
+     981           0 :           A0[Nprec-1].resize(0);
+     982           0 :           A1[Nprec-1].resize(0);
+     983             :           // Avoid passing the zeros (i=1) for atom indices
+     984           0 :           OrdVec[0]=0;
+     985           0 :           OrdVec[Nprec-1]=0;
+     986             : 
+     987             :           // Wait for all ranks before communication of Vectors
+     988           0 :           comm.Barrier();
+     989             : 
+     990             :           // pass the array sizes before passing the arrays
+     991           0 :           int dim=Atom0F.size();
+     992             :           // Vdim and Vpos keep track of the dimension and the starting-position of the rank-specific pair vector in the big pair vector.
+     993           0 :           comm.Allgather(&dim,1,&Vdim[0],1);
+     994             : 
+     995             :           // TO BE IMPROVED: the following may be done by the rank 0 (now every rank does it)
+     996             :           int Fdim=0;
+     997           0 :           for(unsigned i=1; i<stride; i++) {
+     998           0 :             Vpos[i]=Vpos[i-1]+Vdim[i-1];
+     999           0 :             Fdim+=Vdim[i];
+    1000             :           }
+    1001           0 :           Fdim+=Vdim[0];
+    1002             :           // build big vectors for atom pairs on all ranks for all ranks
+    1003           0 :           std:: vector<int> Atom0FAll(Fdim);
+    1004           0 :           std:: vector<int> Atom1FAll(Fdim);
+    1005             :           // TO BE IMPROVED: Allgathers may be substituted by gathers by proc 0
+    1006             :           //   Moreover vectors are gathered head-to-tail and assembled later-on in a serial step.
+    1007             :           // Gather the full Ordering Vector (occupancies). This is what we need to build the PIV
+    1008           0 :           comm.Allgather(&OrdVec[0],Nprec,&OrdVecAll[0],Nprec);
+    1009             :           // Gather the vectors of atom pairs to keep track of the idexes for the forces
+    1010           0 :           comm.Allgatherv(Atom0F.data(),Atom0F.size(),&Atom0FAll[0],&Vdim[0],&Vpos[0]);
+    1011           0 :           comm.Allgatherv(Atom1F.data(),Atom1F.size(),&Atom1FAll[0],&Vdim[0],&Vpos[0]);
+    1012             : 
+    1013             :           // Reconstruct the full vectors from collections of Allgathered parts (this is a serial step)
+    1014             :           // This is the tricky serial step, to assemble together PIV and atom-pair info from head-tail big vectors
+    1015             :           // Loop before on l and then on i would be better but the allgather should be modified
+    1016             :           // Loop on blocks
+    1017             :           //for(unsigned m=0;m<Nlist;m++) {
+    1018             :           // Loop on Ordering Vector size excluding zeros (i=1)
+    1019           0 :           if(timer) stopwatch.stop("2 Sort cPIV");
+    1020           0 :           if(timer) stopwatch.start("3 Reconstruct cPIV");
+    1021           0 :           for(unsigned i=1; i<Nprec; i++) {
+    1022             :             // Loop on the ranks
+    1023           0 :             for(unsigned l=0; l<stride; l++) {
+    1024             :               // Loop on the number of head-to-tail pieces
+    1025           0 :               for(unsigned m=0; m<OrdVecAll[i+l*Nprec]; m++) {
+    1026             :                 // cPIV is the current PIV at time t
+    1027           0 :                 cPIV[j].push_back(double(i)/double(Nprec-1));
+    1028           0 :                 Atom0[j].push_back(Atom0FAll[k[l]+Vpos[l]]);
+    1029           0 :                 Atom1[j].push_back(Atom1FAll[k[l]+Vpos[l]]);
+    1030           0 :                 k[l]+=1;
+    1031             :               }
+    1032             :             }
+    1033             :           }
+    1034           0 :           if(timer) stopwatch.stop("3 Reconstruct cPIV");
+    1035             :         } else {
+    1036     6000000 :           for(unsigned i=1; i<Nprec; i++) {
+    1037    11757594 :             for(unsigned m=0; m<OrdVec[i]; m++) {
+    1038     5757600 :               cPIV[j].push_back(double(i)/double(Nprec-1));
+    1039     5757600 :               Atom0[j].push_back(A0[i][m]);
+    1040     5757600 :               Atom1[j].push_back(A1[i][m]);
+    1041             :             }
+    1042             :           }
+    1043             :         }
+    1044             :       }
+    1045             :     }
+    1046             :   }
+    1047         327 :   Vector distance;
+    1048         327 :   double dfunc=0.;
+    1049             :   // Calculate volume scaling factor
+    1050         327 :   if(Svol) {
+    1051         327 :     Fvol=cbrt(Vol0/getBox().determinant());
+    1052             :   }
+    1053             : 
+    1054             :   // This test may be run by specifying the TEST keyword as input, it pritnts rPIV and cPIV and quits
+    1055         327 :   if(test) {
+    1056             :     unsigned limit=0;
+    1057           0 :     for(unsigned j=0; j<Nlist; j++) {
+    1058           0 :       if(dosort[j]) {
+    1059           0 :         limit = cPIV[j].size();
+    1060             :       } else {
+    1061           0 :         limit = rPIV[j].size();
+    1062             :       }
+    1063           0 :       log.printf("PIV Block:  %6i %12s %6i \n", j, "      Size:", limit);
+    1064           0 :       log.printf("%6s%6s%12s%12s%36s\n","     i","     j", "    c-PIV   ","    r-PIV   ","   i-j distance vector       ");
+    1065           0 :       for(unsigned i=0; i<limit; i++) {
+    1066             :         unsigned i0=0;
+    1067             :         unsigned i1=0;
+    1068           0 :         if(dosort[j]) {
+    1069           0 :           i0=Atom0[j][i];
+    1070           0 :           i1=Atom1[j][i];
+    1071             :         } else {
+    1072           0 :           i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+    1073           0 :           i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+    1074             :         }
+    1075           0 :         Vector Pos0,Pos1;
+    1076           0 :         if(com) {
+    1077           0 :           Pos0=compos[i0];
+    1078           0 :           Pos1=compos[i1];
+    1079             :         } else {
+    1080           0 :           Pos0=getPosition(i0);
+    1081           0 :           Pos1=getPosition(i1);
+    1082             :         }
+    1083           0 :         if(pbc) {
+    1084           0 :           distance=pbcDistance(Pos0,Pos1);
+    1085             :         } else {
+    1086           0 :           distance=delta(Pos0,Pos1);
+    1087             :         }
+    1088           0 :         dfunc=0.;
+    1089             :         double cP,rP;
+    1090           0 :         if(dosort[j]) {
+    1091           0 :           cP = cPIV[j][i];
+    1092           0 :           rP = rPIV[j][rPIV[j].size()-cPIV[j].size()+i];
+    1093             :         } else {
+    1094           0 :           double dm=distance.modulo();
+    1095           0 :           cP = sfs[j].calculate(dm*Fvol, dfunc);
+    1096           0 :           rP = rPIV[j][i];
+    1097             :         }
+    1098           0 :         log.printf("%6i%6i%12.6f%12.6f%12.6f%12.6f%12.6f\n",i0,i1,cP,rP,distance[0],distance[1],distance[2]);
+    1099             :       }
+    1100             :     }
+    1101           0 :     log.printf("This was a test, now exit \n");
+    1102           0 :     exit();
+    1103             :   }
+    1104             : 
+    1105         327 :   if(timer) stopwatch.start("4 Build For Derivatives");
+    1106             :   // non-global variables Nder and Scalevol defined to speedup if structures in cycles
+    1107         327 :   bool Nder=CompDer;
+    1108         327 :   bool Scalevol=Svol;
+    1109         327 :   if(getStep()%updatePIV==0) {
+    1110             :     // set to zero PIVdistance, derivatives and virial when they are calculated
+    1111       29799 :     for(unsigned j=0; j<m_deriv.size(); j++) {
+    1112      117888 :       for(unsigned k=0; k<3; k++) {m_deriv[j][k]=0.;}
+    1113             :     }
+    1114        1308 :     for(unsigned j=0; j<3; j++) {
+    1115        3924 :       for(unsigned k=0; k<3; k++) {
+    1116        2943 :         m_virial[j][k]=0.;
+    1117             :       }
+    1118             :     }
+    1119         327 :     m_PIVdistance=0.;
+    1120             :     // Re-compute atomic distances for derivatives and compute PIV-PIV distance
+    1121         981 :     for(unsigned j=0; j<Nlist; j++) {
+    1122             :       unsigned limit=0;
+    1123             :       // dosorting definition is to speedup if structure in cycles with non-global variables
+    1124         654 :       bool dosorting=dosort[j];
+    1125         654 :       bool docom=com;
+    1126         654 :       bool dopbc=pbc;
+    1127         654 :       if(dosorting) {
+    1128          12 :         limit = cPIV[j].size();
+    1129             :       } else {
+    1130         642 :         limit = rPIV[j].size();
+    1131             :       }
+    1132    11574918 :       for(unsigned i=rank; i<limit; i+=stride) {
+    1133             :         unsigned i0=0;
+    1134             :         unsigned i1=0;
+    1135    11574264 :         if(dosorting) {
+    1136    11515200 :           i0=Atom0[j][i];
+    1137    11515200 :           i1=Atom1[j][i];
+    1138             :         } else {
+    1139       59064 :           i0=(nl[j]->getClosePairAtomNumber(i).first).index();
+    1140       59064 :           i1=(nl[j]->getClosePairAtomNumber(i).second).index();
+    1141             :         }
+    1142    11574264 :         Vector Pos0,Pos1;
+    1143    11574264 :         if(docom) {
+    1144           0 :           Pos0=compos[i0];
+    1145           0 :           Pos1=compos[i1];
+    1146             :         } else {
+    1147    11574264 :           Pos0=getPosition(i0);
+    1148    11574264 :           Pos1=getPosition(i1);
+    1149             :         }
+    1150    11574264 :         if(dopbc) {
+    1151    11574264 :           distance=pbcDistance(Pos0,Pos1);
+    1152             :         } else {
+    1153           0 :           distance=delta(Pos0,Pos1);
+    1154             :         }
+    1155    11574264 :         dfunc=0.;
+    1156             :         // this is needed for dfunc and dervatives
+    1157    11574264 :         double dm=distance.modulo();
+    1158    11574264 :         double tPIV = sfs[j].calculate(dm*Fvol, dfunc);
+    1159             :         // PIV distance
+    1160             :         double coord=0.;
+    1161    11574264 :         if(!dosorting||Nder) {
+    1162       59064 :           coord = tPIV - rPIV[j][i];
+    1163             :         } else {
+    1164    11515200 :           coord = cPIV[j][i] - rPIV[j][rPIV[j].size()-cPIV[j].size()+i];
+    1165             :         }
+    1166             :         // Calculate derivatives, virial, and variable=sum_j (scaling[j] *(cPIV-rPIV)_j^2)
+    1167             :         // WARNING: dfunc=dswf/(Fvol*dm)  (this may change in future Plumed versions)
+    1168    11574264 :         double tmp = 2.*scaling[j]*coord*Fvol*Fvol*dfunc;
+    1169    11574264 :         Vector tmpder = tmp*distance;
+    1170             :         // 0.5*(x_i-x_k)*f_ik         (force on atom k due to atom i)
+    1171    11574264 :         if(docom) {
+    1172           0 :           Vector dist;
+    1173           0 :           for(unsigned k=0; k<nlcom[i0]->getFullAtomList().size(); k++) {
+    1174           0 :             unsigned x0=nlcom[i0]->getFullAtomList()[k].index();
+    1175           0 :             m_deriv[x0] -= tmpder*fmass[x0];
+    1176           0 :             for(unsigned l=0; l<3; l++) {
+    1177           0 :               dist[l]=0.;
+    1178             :             }
+    1179           0 :             Vector P0=getPosition(x0);
+    1180           0 :             for(unsigned l=0; l<nlcom[i0]->getFullAtomList().size(); l++) {
+    1181           0 :               unsigned x1=nlcom[i0]->getFullAtomList()[l].index();
+    1182           0 :               Vector P1=getPosition(x1);
+    1183           0 :               if(dopbc) {
+    1184           0 :                 dist+=pbcDistance(P0,P1);
+    1185             :               } else {
+    1186           0 :                 dist+=delta(P0,P1);
+    1187             :               }
+    1188             :             }
+    1189           0 :             for(unsigned l=0; l<nlcom[i1]->getFullAtomList().size(); l++) {
+    1190           0 :               unsigned x1=nlcom[i1]->getFullAtomList()[l].index();
+    1191           0 :               Vector P1=getPosition(x1);
+    1192           0 :               if(dopbc) {
+    1193           0 :                 dist+=pbcDistance(P0,P1);
+    1194             :               } else {
+    1195           0 :                 dist+=delta(P0,P1);
+    1196             :               }
+    1197             :             }
+    1198           0 :             m_virial    -= 0.25*fmass[x0]*Tensor(dist,tmpder);
+    1199             :           }
+    1200           0 :           for(unsigned k=0; k<nlcom[i1]->getFullAtomList().size(); k++) {
+    1201           0 :             unsigned x1=nlcom[i1]->getFullAtomList()[k].index();
+    1202           0 :             m_deriv[x1] += tmpder*fmass[x1];
+    1203           0 :             for(unsigned l=0; l<3; l++) {
+    1204           0 :               dist[l]=0.;
+    1205             :             }
+    1206           0 :             Vector P1=getPosition(x1);
+    1207           0 :             for(unsigned l=0; l<nlcom[i1]->getFullAtomList().size(); l++) {
+    1208           0 :               unsigned x0=nlcom[i1]->getFullAtomList()[l].index();
+    1209           0 :               Vector P0=getPosition(x0);
+    1210           0 :               if(dopbc) {
+    1211           0 :                 dist+=pbcDistance(P1,P0);
+    1212             :               } else {
+    1213           0 :                 dist+=delta(P1,P0);
+    1214             :               }
+    1215             :             }
+    1216           0 :             for(unsigned l=0; l<nlcom[i0]->getFullAtomList().size(); l++) {
+    1217           0 :               unsigned x0=nlcom[i0]->getFullAtomList()[l].index();
+    1218           0 :               Vector P0=getPosition(x0);
+    1219           0 :               if(dopbc) {
+    1220           0 :                 dist+=pbcDistance(P1,P0);
+    1221             :               } else {
+    1222           0 :                 dist+=delta(P1,P0);
+    1223             :               }
+    1224             :             }
+    1225           0 :             m_virial    += 0.25*fmass[x1]*Tensor(dist,tmpder);
+    1226             :           }
+    1227             :         } else {
+    1228    11574264 :           m_deriv[i0] -= tmpder;
+    1229    11574264 :           m_deriv[i1] += tmpder;
+    1230    11574264 :           m_virial    -= tmp*Tensor(distance,distance);
+    1231             :         }
+    1232    11574264 :         if(Scalevol) {
+    1233    11574264 :           m_virial+=1./3.*tmp*dm*dm*Tensor::identity();
+    1234             :         }
+    1235    11574264 :         m_PIVdistance    += scaling[j]*coord*coord;
+    1236             :       }
+    1237             :     }
+    1238             : 
+    1239         327 :     if (!serial && comm.initialized()) {
+    1240           0 :       comm.Barrier();
+    1241           0 :       comm.Sum(&m_PIVdistance,1);
+    1242           0 :       if(!m_deriv.empty()) comm.Sum(&m_deriv[0][0],3*m_deriv.size());
+    1243           0 :       comm.Sum(&m_virial[0][0],9);
+    1244             :     }
+    1245             :   }
+    1246         327 :   prev_stp=getStep();
+    1247             : 
+    1248             :   //Timing
+    1249         327 :   if(timer) stopwatch.stop("4 Build For Derivatives");
+    1250         327 :   if(timer) {
+    1251           1 :     log.printf("Timings for action %s with label %s \n", getName().c_str(), getLabel().c_str() );
+    1252           1 :     log<<stopwatch;
+    1253             :   }
+    1254             : 
+    1255             :   // Update derivatives, virial, and variable (PIV-distance^2)
+    1256       29799 :   for(unsigned i=0; i<m_deriv.size(); ++i) setAtomsDerivatives(i,m_deriv[i]);
+    1257         327 :   setValue           (m_PIVdistance);
+    1258         327 :   setBoxDerivatives  (m_virial);
+    1259         327 : }
+    1260             : //Close Namespaces at the very beginning
+    1261             : }
+    1262             : }
+    1263             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/index-sort-f.html b/coverage/piv/index-sort-f.html new file mode 100644 index 000000000000..39c8f6d9be0a --- /dev/null +++ b/coverage/piv/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/index-sort-l.html b/coverage/piv/index-sort-l.html new file mode 100644 index 000000000000..6683d0bfa738 --- /dev/null +++ b/coverage/piv/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/piv/index.html b/coverage/piv/index.html new file mode 100644 index 000000000000..0ad322595c7c --- /dev/null +++ b/coverage/piv/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - piv + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pivHitTotalCoverage
Test:plumed test coverageLines:42759571.8 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PIV.cpp +
71.8%71.8%
+
71.8 %427 / 59560.0 %3 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/PytorchModel.cpp.func-sort-c.html b/coverage/pytorch/PytorchModel.cpp.func-sort-c.html new file mode 100644 index 000000000000..b7b725667ca9 --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - pytorch/PytorchModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorch - PytorchModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7pytorch12PytorchModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD8function7pytorch12PytorchModelC1ERKNS_13ActionOptionsE4
_ZN4PLMD8function7pytorch12PytorchModel16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function7pytorch12PytorchModel9calculateEv44
_ZN4PLMD8function7pytorch12PytorchModel16tensor_to_vectorERKN2at6TensorE103
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/PytorchModel.cpp.func.html b/coverage/pytorch/PytorchModel.cpp.func.html new file mode 100644 index 000000000000..d19cac3db55d --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - pytorch/PytorchModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorch - PytorchModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8function7pytorch12PytorchModel16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD8function7pytorch12PytorchModel16tensor_to_vectorERKN2at6TensorE103
_ZN4PLMD8function7pytorch12PytorchModel9calculateEv44
_ZN4PLMD8function7pytorch12PytorchModelC1ERKNS_13ActionOptionsE4
_ZN4PLMD8function7pytorch12PytorchModelC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/PytorchModel.cpp.gcov.html b/coverage/pytorch/PytorchModel.cpp.gcov.html new file mode 100644 index 000000000000..956f878327d3 --- /dev/null +++ b/coverage/pytorch/PytorchModel.cpp.gcov.html @@ -0,0 +1,321 @@ + + + + + + + + LCOV - plumed test coverage - pytorch/PytorchModel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorch - PytorchModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2022-2023 of Luigi Bonati and Enrico Trizio.
+       3             : 
+       4             : The pytorch module is free software: you can redistribute it and/or modify
+       5             : it under the terms of the GNU Lesser General Public License as published by
+       6             : the Free Software Foundation, either version 3 of the License, or
+       7             : (at your option) any later version.
+       8             : 
+       9             : The pytorch module is distributed in the hope that it will be useful,
+      10             : but WITHOUT ANY WARRANTY; without even the implied warranty of
+      11             : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      12             : GNU Lesser General Public License for more details.
+      13             : 
+      14             : You should have received a copy of the GNU Lesser General Public License
+      15             : along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      16             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      17             : 
+      18             : #ifdef __PLUMED_HAS_LIBTORCH
+      19             : // convert LibTorch version to string
+      20             : //#define STRINGIFY(x) #x
+      21             : //#define TOSTR(x) STRINGIFY(x)
+      22             : //#define LIBTORCH_VERSION TO_STR(TORCH_VERSION_MAJOR) "." TO_STR(TORCH_VERSION_MINOR) "." TO_STR(TORCH_VERSION_PATCH)
+      23             : 
+      24             : #include "core/PlumedMain.h"
+      25             : #include "function/Function.h"
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : #include <torch/torch.h>
+      29             : #include <torch/script.h>
+      30             : 
+      31             : #include <fstream>
+      32             : #include <cmath>
+      33             : 
+      34             : // Note: Freezing a ScriptModule (torch::jit::freeze) works only in >=1.11
+      35             : // For 1.8 <= versions <=1.10 we need a hack
+      36             : // (see https://discuss.pytorch.org/t/how-to-check-libtorch-version/77709/4 and also
+      37             : // https://github.com/pytorch/pytorch/blob/dfbd030854359207cb3040b864614affeace11ce/torch/csrc/jit/api/module.cpp#L479)
+      38             : // adapted from NequIP https://github.com/mir-group/nequip
+      39             : #if ( TORCH_VERSION_MAJOR == 2 || TORCH_VERSION_MAJOR == 1 && TORCH_VERSION_MINOR <= 10 )
+      40             : #define DO_TORCH_FREEZE_HACK
+      41             : // For the hack, need more headers:
+      42             : #include <torch/csrc/jit/passes/freeze_module.h>
+      43             : #include <torch/csrc/jit/passes/frozen_graph_optimizations.h>
+      44             : #endif
+      45             : 
+      46             : using namespace std;
+      47             : 
+      48             : namespace PLMD {
+      49             : namespace function {
+      50             : namespace pytorch {
+      51             : 
+      52             : //+PLUMEDOC PYTORCH_FUNCTION PYTORCH_MODEL
+      53             : /*
+      54             : Load a PyTorch model compiled with TorchScript.
+      55             : 
+      56             : This can be a function defined in Python or a more complex model, such as a neural network optimized on a set of data. In both cases the derivatives of the outputs with respect to the inputs are computed using the automatic differentiation (autograd) feature of Pytorch.
+      57             : 
+      58             : By default it is assumed that the model is saved as: `model.ptc`, unless otherwise indicated by the `FILE` keyword. The function automatically checks for the number of output dimensions and creates a component for each of them. The outputs are called node-i with i between 0 and N-1 for N outputs.
+      59             : 
+      60             : Note that this function requires \ref installation-libtorch LibTorch C++ library. Check the instructions in the \ref PYTORCH page to enable the module.
+      61             : 
+      62             : \par Examples
+      63             : Load a model called `torch_model.ptc` that takes as input two dihedral angles and returns two outputs.
+      64             : 
+      65             : \plumedfile
+      66             : #SETTINGS AUXFILE=regtest/pytorch/rt-pytorch_model_2d/torch_model.ptc
+      67             : phi: TORSION ATOMS=5,7,9,15
+      68             : psi: TORSION ATOMS=7,9,15,17
+      69             : model: PYTORCH_MODEL FILE=torch_model.ptc ARG=phi,psi
+      70             : PRINT FILE=COLVAR ARG=model.node-0,model.node-1
+      71             : \endplumedfile
+      72             : 
+      73             : */
+      74             : //+ENDPLUMEDOC
+      75             : 
+      76             : 
+      77             : class PytorchModel :
+      78             :   public Function
+      79             : {
+      80             :   unsigned _n_in;
+      81             :   unsigned _n_out;
+      82             :   torch::jit::script::Module _model;
+      83             :   torch::Device device = torch::kCPU;
+      84             : 
+      85             : public:
+      86             :   explicit PytorchModel(const ActionOptions&);
+      87             :   void calculate();
+      88             :   static void registerKeywords(Keywords& keys);
+      89             : 
+      90             :   std::vector<float> tensor_to_vector(const torch::Tensor& x);
+      91             : };
+      92             : 
+      93             : PLUMED_REGISTER_ACTION(PytorchModel,"PYTORCH_MODEL")
+      94             : 
+      95           6 : void PytorchModel::registerKeywords(Keywords& keys) {
+      96           6 :   Function::registerKeywords(keys);
+      97           6 :   keys.use("ARG");
+      98          12 :   keys.add("optional","FILE","Filename of the PyTorch compiled model");
+      99          12 :   keys.addOutputComponent("node", "default", "Model outputs");
+     100           6 : }
+     101             : 
+     102             : // Auxiliary function to transform torch tensors in std vectors
+     103         103 : std::vector<float> PytorchModel::tensor_to_vector(const torch::Tensor& x) {
+     104         206 :   return std::vector<float>(x.data_ptr<float>(), x.data_ptr<float>() + x.numel());
+     105             : }
+     106             : 
+     107           4 : PytorchModel::PytorchModel(const ActionOptions&ao):
+     108             :   Action(ao),
+     109           4 :   Function(ao)
+     110             : {
+     111             :   // print libtorch version
+     112           4 :   std::stringstream ss;
+     113           4 :   ss << TORCH_VERSION_MAJOR << "." << TORCH_VERSION_MINOR << "." << TORCH_VERSION_PATCH;
+     114             :   std::string version;
+     115           4 :   ss >> version; // extract into the string.
+     116           8 :   log.printf(("  LibTorch version: "+version+"\n").data());
+     117             : 
+     118             :   //number of inputs of the model
+     119           4 :   _n_in=getNumberOfArguments();
+     120             : 
+     121             :   //parse model name
+     122           4 :   std::string fname="model.ptc";
+     123           8 :   parse("FILE",fname);
+     124             : 
+     125             :   //deserialize the model from file
+     126             :   try {
+     127           4 :     _model = torch::jit::load(fname, device);
+     128             :   }
+     129             : 
+     130             :   //if an error is thrown check if the file exists or not
+     131           0 :   catch (const c10::Error& e) {
+     132           0 :     std::ifstream infile(fname);
+     133             :     bool exist = infile.good();
+     134           0 :     infile.close();
+     135           0 :     if (exist) {
+     136           0 :       plumed_merror("Cannot load FILE: '"+fname+"'. Please check that it is a Pytorch compiled model (exported with 'torch.jit.trace' or 'torch.jit.script').");
+     137             :     }
+     138             :     else {
+     139           0 :       plumed_merror("The FILE: '"+fname+"' does not exist.");
+     140             :     }
+     141           0 :   }
+     142           4 :   checkRead();
+     143             : 
+     144             : // Optimize model
+     145             :   _model.eval();
+     146             : #ifdef DO_TORCH_FREEZE_HACK
+     147             :   // Do the hack
+     148             :   // Copied from the implementation of torch::jit::freeze,
+     149             :   // except without the broken check
+     150             :   // See https://github.com/pytorch/pytorch/blob/dfbd030854359207cb3040b864614affeace11ce/torch/csrc/jit/api/module.cpp
+     151             :   bool optimize_numerics = true;  // the default
+     152             :   // the {} is preserved_attrs
+     153             :   auto out_mod = torch::jit::freeze_module(
+     154             :                    _model, {}
+     155           4 :                  );
+     156             :   // See 1.11 bugfix in https://github.com/pytorch/pytorch/pull/71436
+     157           8 :   auto graph = out_mod.get_method("forward").graph();
+     158           4 :   OptimizeFrozenGraph(graph, optimize_numerics);
+     159           4 :   _model = out_mod;
+     160             : #else
+     161             :   // Do it normally
+     162             :   _model = torch::jit::freeze(_model);
+     163             : #endif
+     164             : 
+     165             : // Optimize model for inference
+     166             : #if (TORCH_VERSION_MAJOR == 2 || TORCH_VERSION_MAJOR == 1 && TORCH_VERSION_MINOR >= 10)
+     167           4 :   _model = torch::jit::optimize_for_inference(_model);
+     168             : #endif
+     169             : 
+     170             :   //check the dimension of the output
+     171           4 :   log.printf("  Checking output dimension:\n");
+     172           4 :   std::vector<float> input_test (_n_in);
+     173           4 :   torch::Tensor single_input = torch::tensor(input_test).view({1,_n_in});
+     174           8 :   single_input = single_input.to(device);
+     175             :   std::vector<torch::jit::IValue> inputs;
+     176           4 :   inputs.push_back( single_input );
+     177           8 :   torch::Tensor output = _model.forward( inputs ).toTensor();
+     178           4 :   vector<float> cvs = this->tensor_to_vector (output);
+     179           4 :   _n_out=cvs.size();
+     180             : 
+     181             :   //create components
+     182           9 :   for(unsigned j=0; j<_n_out; j++) {
+     183           5 :     string name_comp = "node-"+std::to_string(j);
+     184           5 :     addComponentWithDerivatives( name_comp );
+     185           5 :     componentIsNotPeriodic( name_comp );
+     186             :   }
+     187             : 
+     188             :   //print log
+     189           4 :   log.printf("  Number of input: %d \n",_n_in);
+     190           4 :   log.printf("  Number of outputs: %d \n",_n_out);
+     191           4 :   log.printf("  Bibliography: ");
+     192           8 :   log<<plumed.cite("Bonati, Trizio, Rizzi and Parrinello, J. Chem. Phys. 159, 014801 (2023)");
+     193           8 :   log<<plumed.cite("Bonati, Rizzi and Parrinello, J. Phys. Chem. Lett. 11, 2998-3004 (2020)");
+     194           4 :   log.printf("\n");
+     195             : 
+     196          12 : }
+     197             : 
+     198             : 
+     199          44 : void PytorchModel::calculate() {
+     200             : 
+     201             :   // retrieve arguments
+     202          44 :   vector<float> current_S(_n_in);
+     203          99 :   for(unsigned i=0; i<_n_in; i++)
+     204          55 :     current_S[i]=getArgument(i);
+     205             :   //convert to tensor
+     206          44 :   torch::Tensor input_S = torch::tensor(current_S).view({1,_n_in}).to(device);
+     207             :   input_S.set_requires_grad(true);
+     208             :   //convert to Ivalue
+     209             :   std::vector<torch::jit::IValue> inputs;
+     210          44 :   inputs.push_back( input_S );
+     211             :   //calculate output
+     212          88 :   torch::Tensor output = _model.forward( inputs ).toTensor();
+     213             : 
+     214             : 
+     215          99 :   for(unsigned j=0; j<_n_out; j++) {
+     216          55 :     auto grad_output = torch::ones({1}).expand({1, 1}).to(device);
+     217         440 :     auto gradient = torch::autograd::grad({output.slice(/*dim=*/1, /*start=*/j, /*end=*/j+1)},
+     218             :     {input_S},
+     219             :     /*grad_outputs=*/ {grad_output},
+     220             :     /*retain_graph=*/true,
+     221             :     /*create_graph=*/false)[0]; // the [0] is to get a tensor and not a vector<at::tensor>
+     222             : 
+     223          55 :     vector<float> der = this->tensor_to_vector ( gradient );
+     224          55 :     string name_comp = "node-"+std::to_string(j);
+     225             :     //set derivatives of component j
+     226         132 :     for(unsigned i=0; i<_n_in; i++)
+     227          77 :       setDerivative( getPntrToComponent(name_comp),i, der[i] );
+     228             :   }
+     229             : 
+     230             :   //set CV values
+     231          44 :   vector<float> cvs = this->tensor_to_vector (output);
+     232          99 :   for(unsigned j=0; j<_n_out; j++) {
+     233          55 :     string name_comp = "node-"+std::to_string(j);
+     234          55 :     getPntrToComponent(name_comp)->set(cvs[j]);
+     235             :   }
+     236             : 
+     237          88 : }
+     238             : 
+     239             : 
+     240             : } //PLMD
+     241             : } //function
+     242             : } //pytorch
+     243             : 
+     244             : #endif //PLUMED_HAS_LIBTORCH
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/index-sort-f.html b/coverage/pytorch/index-sort-f.html new file mode 100644 index 000000000000..5a296ba5ebce --- /dev/null +++ b/coverage/pytorch/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PytorchModel.cpp +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/index-sort-l.html b/coverage/pytorch/index-sort-l.html new file mode 100644 index 000000000000..1d5d4ffcf1c0 --- /dev/null +++ b/coverage/pytorch/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PytorchModel.cpp +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/pytorch/index.html b/coverage/pytorch/index.html new file mode 100644 index 000000000000..35f33fe8b123 --- /dev/null +++ b/coverage/pytorch/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - pytorch + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - pytorchHitTotalCoverage
Test:plumed test coverageLines:626989.9 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
PytorchModel.cpp +
89.9%89.9%
+
89.9 %62 / 6980.0 %4 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.cpp.func-sort-c.html b/coverage/reference/ArgumentOnlyDistance.cpp.func-sort-c.html new file mode 100644 index 000000000000..a9eb7e38ab51 --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/ArgumentOnlyDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ArgumentOnlyDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101662.5 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD20ArgumentOnlyDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD20ArgumentOnlyDistance9calculateERKSt6vectorIPNS_5ValueESaIS3_EERNS_18ReferenceValuePackERKb0
_ZNK4PLMD20ArgumentOnlyDistance4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb299760
_ZN4PLMD20ArgumentOnlyDistanceC2ERKNS_29ReferenceConfigurationOptionsE518364
_ZN4PLMD20ArgumentOnlyDistance4readERKNS_3PDBE518831
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.cpp.func.html b/coverage/reference/ArgumentOnlyDistance.cpp.func.html new file mode 100644 index 000000000000..013e6d3445c1 --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/ArgumentOnlyDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ArgumentOnlyDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101662.5 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD20ArgumentOnlyDistance4readERKNS_3PDBE518831
_ZN4PLMD20ArgumentOnlyDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD20ArgumentOnlyDistanceC2ERKNS_29ReferenceConfigurationOptionsE518364
_ZNK4PLMD20ArgumentOnlyDistance4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb299760
_ZNK4PLMD20ArgumentOnlyDistance9calculateERKSt6vectorIPNS_5ValueESaIS3_EERNS_18ReferenceValuePackERKb0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.cpp.gcov.html b/coverage/reference/ArgumentOnlyDistance.cpp.gcov.html new file mode 100644 index 000000000000..86b13f1539a2 --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.cpp.gcov.html @@ -0,0 +1,130 @@ + + + + + + + + LCOV - plumed test coverage - reference/ArgumentOnlyDistance.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ArgumentOnlyDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:101662.5 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ArgumentOnlyDistance.h"
+      23             : #include "core/Value.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27      518364 : ArgumentOnlyDistance::ArgumentOnlyDistance( const ReferenceConfigurationOptions& ro ):
+      28             :   ReferenceConfiguration(ro),
+      29      518364 :   ReferenceArguments(ro)
+      30             : {
+      31      518364 : }
+      32             : 
+      33      518831 : void ArgumentOnlyDistance::read( const PDB& pdb ) {
+      34      518831 :   readArgumentsFromPDB( pdb );
+      35      518831 : }
+      36             : 
+      37           0 : double ArgumentOnlyDistance::calculate( const std::vector<Value*>& vals, ReferenceValuePack& myder, const bool& squared ) const {
+      38           0 :   std::vector<double> tmparg( vals.size() );
+      39           0 :   for(unsigned i=0; i<vals.size(); ++i) tmparg[i]=vals[i]->get();
+      40           0 :   double d=calculateArgumentDistance( vals, tmparg, myder, squared );
+      41           0 :   if( !myder.updateComplete() ) myder.updateDynamicLists();
+      42           0 :   return d;
+      43             : }
+      44             : 
+      45      299760 : double ArgumentOnlyDistance::calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& arg,
+      46             :                                    ReferenceValuePack& myder, const bool& squared ) const {
+      47             :   plumed_dbg_assert( pos.size()==0 );
+      48      299760 :   double d=calculateArgumentDistance( vals, arg, myder, squared );
+      49      299760 :   if( !myder.updateComplete() ) myder.updateDynamicLists();
+      50      299760 :   return d;
+      51             : }
+      52             : 
+      53             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.h.func-sort-c.html b/coverage/reference/ArgumentOnlyDistance.h.func-sort-c.html new file mode 100644 index 000000000000..555c515d7bd3 --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - reference/ArgumentOnlyDistance.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ArgumentOnlyDistance.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD20ArgumentOnlyDistance28pcaIsEnabledForThisReferenceEv80
_ZN4PLMD20ArgumentOnlyDistance15setupPCAStorageERNS_18ReferenceValuePackE556
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.h.func.html b/coverage/reference/ArgumentOnlyDistance.h.func.html new file mode 100644 index 000000000000..6ed4a7f4ce82 --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - reference/ArgumentOnlyDistance.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ArgumentOnlyDistance.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD20ArgumentOnlyDistance15setupPCAStorageERNS_18ReferenceValuePackE556
_ZN4PLMD20ArgumentOnlyDistance28pcaIsEnabledForThisReferenceEv80
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ArgumentOnlyDistance.h.gcov.html b/coverage/reference/ArgumentOnlyDistance.h.gcov.html new file mode 100644 index 000000000000..017d29c6a1e2 --- /dev/null +++ b/coverage/reference/ArgumentOnlyDistance.h.gcov.html @@ -0,0 +1,122 @@ + + + + + + + + LCOV - plumed test coverage - reference/ArgumentOnlyDistance.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ArgumentOnlyDistance.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_reference_ArgumentOnlyDistance_h
+      23             : #define __PLUMED_reference_ArgumentOnlyDistance_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <string>
+      27             : #include "ReferenceArguments.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : class PDB;
+      32             : class Pbc;
+      33             : 
+      34             : class ArgumentOnlyDistance : public ReferenceArguments {
+      35             : public:
+      36             :   explicit ArgumentOnlyDistance( const ReferenceConfigurationOptions& ro );
+      37             :   void read( const PDB& pdb ) override;
+      38          80 :   bool pcaIsEnabledForThisReference() override { return true; }
+      39         556 :   void setupPCAStorage( ReferenceValuePack& mypack ) override { mypack.switchOnPCAOption(); }
+      40             :   double calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& arg, ReferenceValuePack& myder, const bool& squared ) const override;
+      41             :   double calculate( const std::vector<Value*>& vals, ReferenceValuePack& myder, const bool& squared ) const ;
+      42             : };
+      43             : 
+      44             : }
+      45             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/DRMSD.cpp.func-sort-c.html b/coverage/reference/DRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..4997e31b4890 --- /dev/null +++ b/coverage/reference/DRMSD.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - reference/DRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - DRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535793.0 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5DRMSDC2ERKNS_29ReferenceConfigurationOptionsE2
_ZN4PLMD5DRMSD4readERKNS_3PDBE9
_ZN4PLMD5DRMSD10readBoundsERKNS_3PDBE11
_ZN4PLMD5DRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_17
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE26
_ZN4PLMD5DRMSD13setup_targetsEv26
_ZN4PLMD5DRMSDC1ERKNS_29ReferenceConfigurationOptionsE26
_ZN4PLMD5DRMSD20setBoundsOnDistancesEbdd28
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMeD2Ev4187
_ZNK4PLMD5DRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb20378
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/DRMSD.cpp.func.html b/coverage/reference/DRMSD.cpp.func.html new file mode 100644 index 000000000000..eaf0a4f49b56 --- /dev/null +++ b/coverage/reference/DRMSD.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - reference/DRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - DRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535793.0 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE26
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_115DRMSDRegisterMeD2Ev4187
_ZN4PLMD5DRMSD10readBoundsERKNS_3PDBE11
_ZN4PLMD5DRMSD13setup_targetsEv26
_ZN4PLMD5DRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_17
_ZN4PLMD5DRMSD20setBoundsOnDistancesEbdd28
_ZN4PLMD5DRMSD4readERKNS_3PDBE9
_ZN4PLMD5DRMSDC1ERKNS_29ReferenceConfigurationOptionsE26
_ZN4PLMD5DRMSDC2ERKNS_29ReferenceConfigurationOptionsE2
_ZNK4PLMD5DRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb20378
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/DRMSD.cpp.gcov.html b/coverage/reference/DRMSD.cpp.gcov.html new file mode 100644 index 000000000000..485cf36f23fa --- /dev/null +++ b/coverage/reference/DRMSD.cpp.gcov.html @@ -0,0 +1,194 @@ + + + + + + + + LCOV - plumed test coverage - reference/DRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - DRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535793.0 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DRMSD.h"
+      23             : #include "MetricRegister.h"
+      24             : #include "tools/Pbc.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28       12613 : PLUMED_REGISTER_METRIC(DRMSD,"DRMSD")
+      29             : 
+      30          28 : DRMSD::DRMSD( const ReferenceConfigurationOptions& ro ):
+      31             :   ReferenceConfiguration( ro ),
+      32             :   SingleDomainRMSD( ro ),
+      33          28 :   nopbc(true),
+      34          28 :   bounds_were_set(false),
+      35          28 :   lower(0),
+      36          28 :   upper(std::numeric_limits<double>::max( ))
+      37             : {
+      38          28 : }
+      39             : 
+      40          28 : void DRMSD::setBoundsOnDistances( bool dopbc, double lbound, double ubound ) {
+      41          28 :   bounds_were_set=true; nopbc=!dopbc;
+      42          28 :   lower=lbound; upper=ubound;
+      43          28 : }
+      44             : 
+      45          11 : void DRMSD::readBounds( const PDB& pdb ) {
+      46          11 :   if( bounds_were_set ) return;
+      47           0 :   double tmp; nopbc=pdb.hasFlag("NOPBC");
+      48           0 :   if( pdb.getArgumentValue("LOWER_CUTOFF",tmp) ) lower=tmp;
+      49           0 :   if( pdb.getArgumentValue("UPPER_CUTOFF",tmp) ) upper=tmp;
+      50           0 :   bounds_were_set=true;
+      51             : }
+      52             : 
+      53           9 : void DRMSD::read( const PDB& pdb ) {
+      54           9 :   readAtomsFromPDB( pdb ); readBounds( pdb ); setup_targets();
+      55           9 : }
+      56             : 
+      57          17 : void DRMSD::setReferenceAtoms( const std::vector<Vector>& conf, const std::vector<double>& align_in, const std::vector<double>& displace_in ) {
+      58          17 :   SingleDomainRMSD::setReferenceAtoms( conf, align_in, displace_in );
+      59          17 :   setup_targets();
+      60          17 : }
+      61             : 
+      62          26 : void DRMSD::setup_targets() {
+      63          26 :   plumed_massert( bounds_were_set, "I am missing a call to DRMSD::setBoundsOnDistances");
+      64             : 
+      65          26 :   unsigned natoms = getNumberOfReferencePositions();
+      66         569 :   for(unsigned i=0; i<natoms-1; ++i) {
+      67        7779 :     for(unsigned j=i+1; j<natoms; ++j) {
+      68        7236 :       double distance = delta( getReferencePosition(i), getReferencePosition(j) ).modulo();
+      69        7236 :       if(distance < upper && distance > lower ) {
+      70        6620 :         targets[std::make_pair(i,j)] = distance;
+      71             :       }
+      72             :     }
+      73             :   }
+      74          26 :   if( targets.empty() ) error("drmsd will compare no distances - check upper and lower bounds are sensible");
+      75          26 : }
+      76             : 
+      77       20378 : double DRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
+      78             :   plumed_dbg_assert(!targets.empty());
+      79             : 
+      80       20378 :   Vector distance;
+      81       20378 :   myder.clear();
+      82             :   double drmsd=0.;
+      83     8126088 :   for(const auto & it : targets) {
+      84             : 
+      85     8105710 :     const unsigned i=getAtomIndex( it.first.first );
+      86     8105710 :     const unsigned j=getAtomIndex( it.first.second );
+      87             : 
+      88     8105710 :     if(nopbc) distance=delta( pos[i], pos[j] );
+      89     8076310 :     else      distance=pbc.distance( pos[i], pos[j] );
+      90             : 
+      91     8105710 :     const double len = distance.modulo();
+      92     8105710 :     const double diff = len - it.second;
+      93     8105710 :     const double der = diff / len;
+      94             : 
+      95     8105710 :     drmsd += diff * diff;
+      96     8105710 :     myder.addAtomDerivatives( i, -der * distance );
+      97     8105710 :     myder.addAtomDerivatives( j,  der * distance );
+      98     8105710 :     myder.addBoxDerivatives( - der * Tensor(distance,distance) );
+      99             :   }
+     100             : 
+     101       20378 :   const double inpairs = 1./static_cast<double>(targets.size());
+     102             :   double idrmsd;
+     103             : 
+     104       20378 :   if(squared) {
+     105          10 :     drmsd = drmsd * inpairs;
+     106          10 :     idrmsd = 2.0 * inpairs;
+     107             :   } else {
+     108       20368 :     drmsd = std::sqrt( drmsd * inpairs );
+     109       20368 :     idrmsd = inpairs / drmsd ;
+     110             :   }
+     111             : 
+     112       20378 :   myder.scaleAllDerivatives( idrmsd );
+     113             : 
+     114       20378 :   return drmsd;
+     115             : }
+     116             : 
+     117             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.cpp.func-sort-c.html b/coverage/reference/Direction.cpp.func-sort-c.html new file mode 100644 index 000000000000..083a4752d4d0 --- /dev/null +++ b/coverage/reference/Direction.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - reference/Direction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - Direction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283093.3 %
Date:2024-02-22 21:58:45Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9DirectionC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD9Direction4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb0
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMe6createERKNS_29ReferenceConfigurationOptionsE10
_ZNK4PLMD9Direction25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_10
_ZNK4PLMD9Direction27extractArgumentDisplacementERKSt6vectorIPNS_5ValueESaIS3_EERKS1_IdSaIdEERS9_10
_ZN4PLMD9Direction13zeroDirectionEv12
_ZN4PLMD9Direction4readERKNS_3PDBE219
_ZN4PLMD9DirectionC1ERKNS_29ReferenceConfigurationOptionsE219
_ZN4PLMD9Direction12addDirectionERKdRKS0_303
_ZN4PLMD9Direction12setDirectionERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEE494
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.cpp.func.html b/coverage/reference/Direction.cpp.func.html new file mode 100644 index 000000000000..67274d90fed5 --- /dev/null +++ b/coverage/reference/Direction.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - reference/Direction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - Direction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283093.3 %
Date:2024-02-22 21:58:45Functions:101283.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMe6createERKNS_29ReferenceConfigurationOptionsE10
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_119DirectionRegisterMeD2Ev4187
_ZN4PLMD9Direction12addDirectionERKdRKS0_303
_ZN4PLMD9Direction12setDirectionERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEE494
_ZN4PLMD9Direction13zeroDirectionEv12
_ZN4PLMD9Direction4readERKNS_3PDBE219
_ZN4PLMD9DirectionC1ERKNS_29ReferenceConfigurationOptionsE219
_ZN4PLMD9DirectionC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD9Direction25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_10
_ZNK4PLMD9Direction27extractArgumentDisplacementERKSt6vectorIPNS_5ValueESaIS3_EERKS1_IdSaIdEERS9_10
_ZNK4PLMD9Direction4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.cpp.gcov.html b/coverage/reference/Direction.cpp.gcov.html new file mode 100644 index 000000000000..012d331a84e1 --- /dev/null +++ b/coverage/reference/Direction.cpp.gcov.html @@ -0,0 +1,151 @@ + + + + + + + + LCOV - plumed test coverage - reference/Direction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - Direction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283093.3 %
Date:2024-02-22 21:58:45Functions:101283.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Direction.h"
+      23             : #include "MetricRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27       12581 : PLUMED_REGISTER_METRIC(Direction,"DIRECTION")
+      28             : 
+      29         219 : Direction::Direction( const ReferenceConfigurationOptions& ro ):
+      30             :   ReferenceConfiguration(ro),
+      31             :   ReferenceAtoms(ro),
+      32             :   ReferenceArguments(ro),
+      33         219 :   normalized(false)
+      34             : {
+      35         219 : }
+      36             : 
+      37         219 : void Direction::read( const PDB& pdb ) {
+      38         219 :   readAtomsFromPDB( pdb, true );
+      39         219 :   readArgumentsFromPDB( pdb );
+      40         219 : }
+      41             : 
+      42         494 : void Direction::setDirection( const std::vector<Vector>& conf, const std::vector<double>& args ) {
+      43         494 :   std::vector<double> sigma( args.size(), 1.0 ); setReferenceArguments( args, sigma );
+      44             : 
+      45         494 :   reference_atoms.resize( conf.size() ); align.resize( conf.size() );
+      46         494 :   displace.resize( conf.size() ); atom_der_index.resize( conf.size() );
+      47         715 :   for(unsigned i=0; i<conf.size(); ++i) { align[i]=1.0; displace[i]=1.0; atom_der_index[i]=i; reference_atoms[i]=conf[i]; }
+      48         494 : }
+      49             : 
+      50         303 : void Direction::addDirection( const double& weight, const Direction& dir ) {
+      51             :   plumed_dbg_assert( dir.getNumberOfReferenceArguments()==getNumberOfReferenceArguments() && dir.reference_atoms.size()==reference_atoms.size() );
+      52         909 :   for(unsigned i=0; i<reference_args.size(); ++i) reference_args[i] += weight*dir.reference_args[i];
+      53         303 :   for(unsigned i=0; i<reference_atoms.size(); ++i) reference_atoms[i] += weight*reference_atoms.size()*dir.reference_atoms[i];
+      54         303 : }
+      55             : 
+      56          12 : void Direction::zeroDirection() {
+      57          32 :   for(unsigned i=0; i<reference_args.size(); ++i) reference_args[i] = 0.;
+      58          38 :   for(unsigned i=0; i<reference_atoms.size(); ++i) reference_atoms[i].zero();
+      59          12 : }
+      60             : 
+      61           0 : double Direction::calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& args,
+      62             :                         ReferenceValuePack& myder, const bool& squared ) const {
+      63           0 :   plumed_merror("You should never be calling calc for a direction");
+      64             : }
+      65             : 
+      66          10 : void Direction::extractArgumentDisplacement( const std::vector<Value*>& vals, const std::vector<double>& arg, std::vector<double>& dirout ) const {
+      67          10 :   for(unsigned i=0; i<getNumberOfReferenceArguments(); ++i) dirout[i]=getReferenceArgument(i);
+      68          10 : }
+      69             : 
+      70          10 : void Direction::extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& dirout ) const {
+      71          80 :   for(unsigned i=0; i<getNumberOfAtoms(); ++i) dirout[i]=getReferencePosition(i);
+      72          10 : }
+      73             : 
+      74             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.h.func-sort-c.html b/coverage/reference/Direction.h.func-sort-c.html new file mode 100644 index 000000000000..37ea2b862fc6 --- /dev/null +++ b/coverage/reference/Direction.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - reference/Direction.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - Direction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Direction17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.h.func.html b/coverage/reference/Direction.h.func.html new file mode 100644 index 000000000000..51a3f739efc4 --- /dev/null +++ b/coverage/reference/Direction.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - reference/Direction.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - Direction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Direction17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/Direction.h.gcov.html b/coverage/reference/Direction.h.gcov.html new file mode 100644 index 000000000000..5c6009554bef --- /dev/null +++ b/coverage/reference/Direction.h.gcov.html @@ -0,0 +1,128 @@ + + + + + + + + LCOV - plumed test coverage - reference/Direction.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - Direction.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_reference_Direction_h
+      23             : #define __PLUMED_reference_Direction_h
+      24             : 
+      25             : #include "ReferenceAtoms.h"
+      26             : #include "ReferenceArguments.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : class Direction :
+      31             :   public ReferenceAtoms,
+      32             :   public ReferenceArguments
+      33             : {
+      34             : public:
+      35             :   bool normalized;
+      36             :   explicit Direction( const ReferenceConfigurationOptions& ro );
+      37             :   void read( const PDB& ) override;
+      38             :   double calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& args,
+      39             :                ReferenceValuePack& myder, const bool& squared ) const override;
+      40             :   void setDirection( const std::vector<Vector>& conf, const std::vector<double>& args );
+      41             :   void addDirection( const double& weight, const Direction& dir );
+      42           0 :   void setReferenceAtoms( const std::vector<Vector>& conf, const std::vector<double>& align_in, const std::vector<double>& displace_in ) override { plumed_error(); }
+      43             : /// This allows us to extract the reference positions, which are the direction in this case
+      44             :   void extractArgumentDisplacement( const std::vector<Value*>& vals, const std::vector<double>& arg, std::vector<double>& dirout ) const override;
+      45             :   void extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& dirout ) const override;
+      46             :   void zeroDirection();
+      47             : };
+      48             : 
+      49             : }
+      50             : 
+      51             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/DotProductDistance.cpp.func-sort-c.html b/coverage/reference/DotProductDistance.cpp.func-sort-c.html new file mode 100644 index 000000000000..56d5e02ac7a6 --- /dev/null +++ b/coverage/reference/DotProductDistance.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - reference/DotProductDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - DotProductDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1128.3 %
Date:2024-02-22 21:58:45Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD18DotProductDistance4readERKNS_3PDBE0
_ZN4PLMD18DotProductDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD18DotProductDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD18DotProductDistance25calculateArgumentDistanceERKSt6vectorIPNS_5ValueESaIS3_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb0
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/DotProductDistance.cpp.func.html b/coverage/reference/DotProductDistance.cpp.func.html new file mode 100644 index 000000000000..10a67e2c652f --- /dev/null +++ b/coverage/reference/DotProductDistance.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - reference/DotProductDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - DotProductDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1128.3 %
Date:2024-02-22 21:58:45Functions:2728.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_128DotProductDistanceRegisterMeD2Ev4187
_ZN4PLMD18DotProductDistance4readERKNS_3PDBE0
_ZN4PLMD18DotProductDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD18DotProductDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD18DotProductDistance25calculateArgumentDistanceERKSt6vectorIPNS_5ValueESaIS3_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/DotProductDistance.cpp.gcov.html b/coverage/reference/DotProductDistance.cpp.gcov.html new file mode 100644 index 000000000000..7fb86492a414 --- /dev/null +++ b/coverage/reference/DotProductDistance.cpp.gcov.html @@ -0,0 +1,135 @@ + + + + + + + + LCOV - plumed test coverage - reference/DotProductDistance.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - DotProductDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1128.3 %
Date:2024-02-22 21:58:45Functions:2728.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetricRegister.h"
+      23             : #include "ArgumentOnlyDistance.h"
+      24             : #include "core/Value.h"
+      25             : #include <limits>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : class DotProductDistance : public ArgumentOnlyDistance {
+      30             : public:
+      31             :   explicit DotProductDistance( const ReferenceConfigurationOptions& ro );
+      32             :   void read( const PDB& ) override;
+      33             :   double calculateArgumentDistance( const std::vector<Value*> & vals, const std::vector<double>& arg, ReferenceValuePack& myder, const bool& squared ) const override;
+      34             : };
+      35             : 
+      36       12561 : PLUMED_REGISTER_METRIC(DotProductDistance,"DOTPRODUCT")
+      37             : 
+      38           0 : DotProductDistance::DotProductDistance( const ReferenceConfigurationOptions& ro ):
+      39             :   ReferenceConfiguration(ro),
+      40           0 :   ArgumentOnlyDistance(ro)
+      41             : {
+      42           0 : }
+      43             : 
+      44           0 : void DotProductDistance::read( const PDB& pdb ) {
+      45           0 :   readArgumentsFromPDB( pdb );
+      46           0 : }
+      47             : 
+      48           0 : double DotProductDistance::calculateArgumentDistance( const std::vector<Value*> & vals, const std::vector<double>& arg,
+      49             :     ReferenceValuePack& myder, const bool& squared ) const {
+      50             :   double dot=0.0;
+      51           0 :   for (std::size_t i=0; i<vals.size(); ++i) dot+=getReferenceArgument(i)*arg[i];
+      52           0 :   for (std::size_t i=0; i<vals.size(); ++i) myder.setArgumentDerivatives( i, -getReferenceArgument(i)/dot );
+      53           0 :   if(dot==0.0) dot=std::numeric_limits<double>::min();
+      54           0 :   return -log(dot);
+      55             : }
+      56             : 
+      57             : 
+      58             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/EuclideanDistance.cpp.func-sort-c.html b/coverage/reference/EuclideanDistance.cpp.func-sort-c.html new file mode 100644 index 000000000000..aaff2cede6e1 --- /dev/null +++ b/coverage/reference/EuclideanDistance.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/EuclideanDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - EuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17EuclideanDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeD2Ev4187
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE518364
_ZN4PLMD17EuclideanDistanceC1ERKNS_29ReferenceConfigurationOptionsE518364
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/EuclideanDistance.cpp.func.html b/coverage/reference/EuclideanDistance.cpp.func.html new file mode 100644 index 000000000000..3623ffe853c8 --- /dev/null +++ b/coverage/reference/EuclideanDistance.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/EuclideanDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - EuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE518364
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_127EuclideanDistanceRegisterMeD2Ev4187
_ZN4PLMD17EuclideanDistanceC1ERKNS_29ReferenceConfigurationOptionsE518364
_ZN4PLMD17EuclideanDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/EuclideanDistance.cpp.gcov.html b/coverage/reference/EuclideanDistance.cpp.gcov.html new file mode 100644 index 000000000000..da96c5f4a9ee --- /dev/null +++ b/coverage/reference/EuclideanDistance.cpp.gcov.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - reference/EuclideanDistance.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - EuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetricRegister.h"
+      23             : #include "ArgumentOnlyDistance.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27             : class EuclideanDistance : public ArgumentOnlyDistance {
+      28             : public:
+      29             :   explicit EuclideanDistance( const ReferenceConfigurationOptions& ro );
+      30             : };
+      31             : 
+      32     1049289 : PLUMED_REGISTER_METRIC(EuclideanDistance,"EUCLIDEAN")
+      33             : 
+      34      518364 : EuclideanDistance::EuclideanDistance( const ReferenceConfigurationOptions& ro ):
+      35             :   ReferenceConfiguration(ro),
+      36      518364 :   ArgumentOnlyDistance(ro)
+      37             : {
+      38      518364 : }
+      39             : 
+      40             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntermolecularDRMSD.cpp.func-sort-c.html b/coverage/reference/IntermolecularDRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..92561e82ae9c --- /dev/null +++ b/coverage/reference/IntermolecularDRMSD.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - reference/IntermolecularDRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - IntermolecularDRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19IntermolecularDRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD19IntermolecularDRMSD13setup_targetsEv1
_ZN4PLMD19IntermolecularDRMSD4readERKNS_3PDBE1
_ZN4PLMD19IntermolecularDRMSDC1ERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntermolecularDRMSD.cpp.func.html b/coverage/reference/IntermolecularDRMSD.cpp.func.html new file mode 100644 index 000000000000..496f93bf6153 --- /dev/null +++ b/coverage/reference/IntermolecularDRMSD.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - reference/IntermolecularDRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - IntermolecularDRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_129IntermolecularDRMSDRegisterMeD2Ev4187
_ZN4PLMD19IntermolecularDRMSD13setup_targetsEv1
_ZN4PLMD19IntermolecularDRMSD4readERKNS_3PDBE1
_ZN4PLMD19IntermolecularDRMSDC1ERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD19IntermolecularDRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntermolecularDRMSD.cpp.gcov.html b/coverage/reference/IntermolecularDRMSD.cpp.gcov.html new file mode 100644 index 000000000000..ad2ff376224f --- /dev/null +++ b/coverage/reference/IntermolecularDRMSD.cpp.gcov.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - reference/IntermolecularDRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - IntermolecularDRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1919100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DRMSD.h"
+      23             : #include "MetricRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27             : class IntermolecularDRMSD : public DRMSD {
+      28             : private:
+      29             :   unsigned nblocks;
+      30             :   std::vector<unsigned> blocks;
+      31             : public:
+      32             :   explicit IntermolecularDRMSD( const ReferenceConfigurationOptions& ro );
+      33             :   void read( const PDB& pdb ) override;
+      34             :   void setup_targets() override;
+      35             : };
+      36             : 
+      37       12563 : PLUMED_REGISTER_METRIC(IntermolecularDRMSD,"INTER-DRMSD")
+      38             : 
+      39           1 : IntermolecularDRMSD::IntermolecularDRMSD( const ReferenceConfigurationOptions& ro ):
+      40             :   ReferenceConfiguration( ro ),
+      41             :   DRMSD( ro ),
+      42           1 :   nblocks(0)
+      43             : {
+      44           1 : }
+      45             : 
+      46           1 : void IntermolecularDRMSD::read( const PDB& pdb ) {
+      47           1 :   readAtomsFromPDB( pdb, true ); nblocks = pdb.getNumberOfAtomBlocks(); blocks.resize( nblocks+1 );
+      48           1 :   if( nblocks==1 ) error("Trying to compute intermolecular rmsd but found no TERs in input PDB");
+      49           3 :   blocks[0]=0; for(unsigned i=0; i<nblocks; ++i) blocks[i+1]=pdb.getAtomBlockEnds()[i];
+      50           1 :   readBounds( pdb ); setup_targets();
+      51           1 : }
+      52             : 
+      53           1 : void IntermolecularDRMSD::setup_targets() {
+      54           1 :   plumed_massert( bounds_were_set, "I am missing a call to DRMSD::setBoundsOnDistances");
+      55             : 
+      56           2 :   for(unsigned i=1; i<nblocks; ++i) {
+      57           2 :     for(unsigned j=0; j<i; ++j) {
+      58           4 :       for(unsigned iatom=blocks[i]; iatom<blocks[i+1]; ++iatom) {
+      59          15 :         for(unsigned jatom=blocks[j]; jatom<blocks[j+1]; ++jatom) {
+      60          12 :           double distance = delta( getReferencePosition(iatom), getReferencePosition(jatom) ).modulo();
+      61          12 :           if(distance < upper && distance > lower ) targets[std::make_pair(iatom,jatom)] = distance;
+      62             :         }
+      63             :       }
+      64             :     }
+      65             :   }
+      66           1 : }
+      67             : 
+      68             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntramolecularDRMSD.cpp.func-sort-c.html b/coverage/reference/IntramolecularDRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..4498ab97dc4d --- /dev/null +++ b/coverage/reference/IntramolecularDRMSD.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - reference/IntramolecularDRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - IntramolecularDRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD19IntramolecularDRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD19IntramolecularDRMSD13setup_targetsEv1
_ZN4PLMD19IntramolecularDRMSD4readERKNS_3PDBE1
_ZN4PLMD19IntramolecularDRMSDC1ERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntramolecularDRMSD.cpp.func.html b/coverage/reference/IntramolecularDRMSD.cpp.func.html new file mode 100644 index 000000000000..cece0c3bc1ce --- /dev/null +++ b/coverage/reference/IntramolecularDRMSD.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - reference/IntramolecularDRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - IntramolecularDRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_129IntramolecularDRMSDRegisterMeD2Ev4187
_ZN4PLMD19IntramolecularDRMSD13setup_targetsEv1
_ZN4PLMD19IntramolecularDRMSD4readERKNS_3PDBE1
_ZN4PLMD19IntramolecularDRMSDC1ERKNS_29ReferenceConfigurationOptionsE1
_ZN4PLMD19IntramolecularDRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/IntramolecularDRMSD.cpp.gcov.html b/coverage/reference/IntramolecularDRMSD.cpp.gcov.html new file mode 100644 index 000000000000..5f598122f6ae --- /dev/null +++ b/coverage/reference/IntramolecularDRMSD.cpp.gcov.html @@ -0,0 +1,143 @@ + + + + + + + + LCOV - plumed test coverage - reference/IntramolecularDRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - IntramolecularDRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DRMSD.h"
+      23             : #include "MetricRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27             : class IntramolecularDRMSD : public DRMSD {
+      28             : private:
+      29             :   unsigned nblocks;
+      30             :   std::vector<unsigned> blocks;
+      31             : public:
+      32             :   explicit IntramolecularDRMSD( const ReferenceConfigurationOptions& ro );
+      33             :   void read( const PDB& pdb ) override;
+      34             :   void setup_targets() override;
+      35             : };
+      36             : 
+      37       12563 : PLUMED_REGISTER_METRIC(IntramolecularDRMSD,"INTRA-DRMSD")
+      38             : 
+      39           1 : IntramolecularDRMSD::IntramolecularDRMSD( const ReferenceConfigurationOptions& ro ):
+      40             :   ReferenceConfiguration( ro ),
+      41             :   DRMSD( ro ),
+      42           1 :   nblocks(0)
+      43             : {
+      44           1 : }
+      45             : 
+      46           1 : void IntramolecularDRMSD::read( const PDB& pdb ) {
+      47           1 :   readAtomsFromPDB( pdb, true ); nblocks = pdb.getNumberOfAtomBlocks(); blocks.resize( nblocks+1 );
+      48           1 :   if( nblocks==1 ) error("Trying to compute intramolecular rmsd but found no TERs in input PDB");
+      49           3 :   blocks[0]=0; for(unsigned i=0; i<nblocks; ++i) blocks[i+1]=pdb.getAtomBlockEnds()[i];
+      50           1 :   readBounds( pdb ); setup_targets();
+      51           1 : }
+      52             : 
+      53           1 : void IntramolecularDRMSD::setup_targets() {
+      54           1 :   plumed_massert( bounds_were_set, "I am missing a call to DRMSD::setBoundsOnDistances");
+      55             : 
+      56           3 :   for(unsigned i=0; i<nblocks; ++i) {
+      57           7 :     for(unsigned iatom=blocks[i]+1; iatom<blocks[i+1]; ++iatom) {
+      58          14 :       for(unsigned jatom=blocks[i]; jatom<iatom; ++jatom) {
+      59           9 :         double distance = delta( getReferencePosition(iatom), getReferencePosition(jatom) ).modulo();
+      60           9 :         if(distance < upper && distance > lower ) targets[std::make_pair(iatom,jatom)] = distance;
+      61             :       }
+      62             :     }
+      63             :   }
+      64           1 : }
+      65             : 
+      66             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MahalanobisDistance.cpp.func-sort-c.html b/coverage/reference/MahalanobisDistance.cpp.func-sort-c.html new file mode 100644 index 000000000000..e766f454cbf5 --- /dev/null +++ b/coverage/reference/MahalanobisDistance.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/MahalanobisDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MahalanobisDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1520.0 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD19MahalanobisDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD19MahalanobisDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MahalanobisDistance.cpp.func.html b/coverage/reference/MahalanobisDistance.cpp.func.html new file mode 100644 index 000000000000..8898bac4eb2f --- /dev/null +++ b/coverage/reference/MahalanobisDistance.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/MahalanobisDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MahalanobisDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1520.0 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_129MahalanobisDistanceRegisterMeD2Ev4187
_ZN4PLMD19MahalanobisDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD19MahalanobisDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MahalanobisDistance.cpp.gcov.html b/coverage/reference/MahalanobisDistance.cpp.gcov.html new file mode 100644 index 000000000000..b5f289367964 --- /dev/null +++ b/coverage/reference/MahalanobisDistance.cpp.gcov.html @@ -0,0 +1,118 @@ + + + + + + + + LCOV - plumed test coverage - reference/MahalanobisDistance.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MahalanobisDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1520.0 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetricRegister.h"
+      23             : #include "ArgumentOnlyDistance.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27             : class MahalanobisDistance : public ArgumentOnlyDistance {
+      28             : public:
+      29             :   explicit MahalanobisDistance( const ReferenceConfigurationOptions& ro );
+      30             : };
+      31             : 
+      32       12561 : PLUMED_REGISTER_METRIC(MahalanobisDistance,"MAHALANOBIS")
+      33             : 
+      34           0 : MahalanobisDistance::MahalanobisDistance( const ReferenceConfigurationOptions& ro ):
+      35             :   ReferenceConfiguration(ro),
+      36           0 :   ArgumentOnlyDistance(ro)
+      37             : {
+      38           0 :   hasmetric=true;
+      39           0 : }
+      40             : 
+      41             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.cpp.func-sort-c.html b/coverage/reference/MetricRegister.cpp.func-sort-c.html new file mode 100644 index 000000000000..11ac29d43f25 --- /dev/null +++ b/coverage/reference/MetricRegister.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/MetricRegister.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MetricRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:162080.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14MetricRegisterD2Ev4187
_ZN4PLMD14MetricRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS8_EERKNS_29ReferenceConfigurationOptionsEE46057
_ZN4PLMD14MetricRegister6removeEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS2_EERKNS_29ReferenceConfigurationOptionsEE46057
_ZN4PLMD14MetricRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE518879
_ZN4PLMD14metricRegisterEv610993
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.cpp.func.html b/coverage/reference/MetricRegister.cpp.func.html new file mode 100644 index 000000000000..41365ae16347 --- /dev/null +++ b/coverage/reference/MetricRegister.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/MetricRegister.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MetricRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:162080.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14MetricRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS8_EERKNS_29ReferenceConfigurationOptionsEE46057
_ZN4PLMD14MetricRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE518879
_ZN4PLMD14MetricRegister6removeEPFSt10unique_ptrINS_22ReferenceConfigurationESt14default_deleteIS2_EERKNS_29ReferenceConfigurationOptionsEE46057
_ZN4PLMD14MetricRegisterD2Ev4187
_ZN4PLMD14metricRegisterEv610993
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.cpp.gcov.html b/coverage/reference/MetricRegister.cpp.gcov.html new file mode 100644 index 000000000000..52e6bbeffdf2 --- /dev/null +++ b/coverage/reference/MetricRegister.cpp.gcov.html @@ -0,0 +1,135 @@ + + + + + + + + LCOV - plumed test coverage - reference/MetricRegister.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MetricRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:162080.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetricRegister.h"
+      23             : #include <iostream>
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27        4187 : MetricRegister::~MetricRegister() {
+      28        4187 :   if(m.size()>0) {
+      29           0 :     std::string names="";
+      30           0 :     for(const auto & p : m) names+=p.first+" ";
+      31           0 :     std::cerr<<"WARNING: ReferenceConfiguration "+ names +" has not been properly unregistered. This might lead to memory leak!!\n";
+      32             :   }
+      33        4187 : }
+      34             : 
+      35      610993 : MetricRegister& metricRegister() {
+      36      610993 :   static MetricRegister ans;
+      37      610993 :   return ans;
+      38             : }
+      39             : 
+      40       46057 : void MetricRegister::remove(creator_pointer f) {
+      41      267968 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      42      267968 :     if((*p).second==f) {
+      43       46057 :       m.erase(p); break;
+      44             :     }
+      45             :   }
+      46       46057 : }
+      47             : 
+      48       46057 : void MetricRegister::add( std::string type, creator_pointer f ) {
+      49           0 :   plumed_massert(m.count(type)==0,"type has already been registered");
+      50       46057 :   m.insert(std::pair<std::string,creator_pointer>(type,f));
+      51       46057 : }
+      52             : 
+      53      518879 : bool MetricRegister::check(const std::string & type) {
+      54      518879 :   if( m.count(type)>0 ) return true;
+      55             :   return false;
+      56             : }
+      57             : 
+      58             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.h.func-sort-c.html b/coverage/reference/MetricRegister.h.func-sort-c.html new file mode 100644 index 000000000000..21810d91050b --- /dev/null +++ b/coverage/reference/MetricRegister.h.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - reference/MetricRegister.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MetricRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:181994.7 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14MetricRegister6createINS_20ArgumentOnlyDistanceEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD14MetricRegister6createINS_20ArgumentOnlyDistanceEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE0
_ZN4PLMD14MetricRegister6createINS_15MultiDomainRMSDEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD14MetricRegister6createINS_15MultiDomainRMSDEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE3
_ZN4PLMD14MetricRegister6createINS_5DRMSDEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11
_ZN4PLMD14MetricRegister6createINS_16SingleDomainRMSDEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE45
_ZN4PLMD14MetricRegister6createINS_8RMSDBaseEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE77
_ZN4PLMD14MetricRegister6createINS_8RMSDBaseEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE77
_ZN4PLMD14MetricRegister6createINS_22ReferenceConfigurationEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE518743
_ZN4PLMD14MetricRegister6createINS_22ReferenceConfigurationEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE518743
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.h.func.html b/coverage/reference/MetricRegister.h.func.html new file mode 100644 index 000000000000..574b9643e1ef --- /dev/null +++ b/coverage/reference/MetricRegister.h.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - reference/MetricRegister.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MetricRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:181994.7 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14MetricRegister6createINS_15MultiDomainRMSDEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD14MetricRegister6createINS_15MultiDomainRMSDEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE3
_ZN4PLMD14MetricRegister6createINS_16SingleDomainRMSDEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE45
_ZN4PLMD14MetricRegister6createINS_20ArgumentOnlyDistanceEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD14MetricRegister6createINS_20ArgumentOnlyDistanceEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE0
_ZN4PLMD14MetricRegister6createINS_22ReferenceConfigurationEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE518743
_ZN4PLMD14MetricRegister6createINS_22ReferenceConfigurationEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE518743
_ZN4PLMD14MetricRegister6createINS_5DRMSDEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11
_ZN4PLMD14MetricRegister6createINS_8RMSDBaseEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE77
_ZN4PLMD14MetricRegister6createINS_8RMSDBaseEEESt10unique_ptrIT_St14default_deleteIS4_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_3PDBE77
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MetricRegister.h.gcov.html b/coverage/reference/MetricRegister.h.gcov.html new file mode 100644 index 000000000000..d879336e3d58 --- /dev/null +++ b/coverage/reference/MetricRegister.h.gcov.html @@ -0,0 +1,191 @@ + + + + + + + + LCOV - plumed test coverage - reference/MetricRegister.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MetricRegister.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:181994.7 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_reference_MetricRegister_h
+      23             : #define __PLUMED_reference_MetricRegister_h
+      24             : 
+      25             : #include <string>
+      26             : #include <cstring>
+      27             : #include <vector>
+      28             : #include <map>
+      29             : #include "tools/Exception.h"
+      30             : #include "tools/Tools.h"
+      31             : #include "tools/PDB.h"
+      32             : #include "ReferenceConfiguration.h"
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : class PDB;
+      37             : 
+      38             : class MetricRegister {
+      39             : private:
+      40             : /// Pointer to a function which, given the type for a ReferenceConfiguration, creates it
+      41             :   typedef std::unique_ptr<ReferenceConfiguration> (*creator_pointer)(const ReferenceConfigurationOptions&);
+      42             : /// The set of possible distribution functions we can work with
+      43             :   std::map<std::string,creator_pointer> m;
+      44             : public:
+      45             : /// The destructor
+      46             :   ~MetricRegister();
+      47             : /// Add a new metric to the register of metrics
+      48             :   void add( std::string type, creator_pointer );
+      49             : /// Remove a metric from the register of metrics
+      50             :   void remove(creator_pointer f);
+      51             : /// Verify if a particular metric type is present in the register
+      52             :   bool check(const std::string & type);
+      53             : /// Create a reference configuration and don't set a point of reference
+      54             :   template <class T>
+      55             :   std::unique_ptr<T> create( const std::string& type );
+      56             : /// Create a reference configuration and set the point of reference from the pdb
+      57             :   template <class T>
+      58             :   std::unique_ptr<T> create( const std::string& type, const PDB& pdb );
+      59             : };
+      60             : 
+      61             : MetricRegister& metricRegister();
+      62             : 
+      63             : #define PLUMED_REGISTER_METRIC(classname,type) \
+      64             :   namespace { class classname##RegisterMe{ \
+      65             :     static std::unique_ptr<ReferenceConfiguration> create(const PLMD::ReferenceConfigurationOptions&ro){return PLMD::Tools::make_unique<classname>(ro);} \
+      66             :   public: \
+      67             :     classname##RegisterMe(){PLMD::metricRegister().add(type,create);}; \
+      68             :     ~classname##RegisterMe(){PLMD::metricRegister().remove(create);}; \
+      69             :   } classname##RegisterMeObject; }
+      70             : 
+      71             : template <class T>
+      72      518879 : std::unique_ptr<T> MetricRegister::create( const std::string& type ) {
+      73             :   std::string ftype;
+      74      518879 :   if( type.find("MULTI-")!=std::string::npos ) {
+      75             :     ftype="MULTI";
+      76             :   } else {
+      77      518874 :     std::size_t dash=type.find("-FAST"); // We must remove the fast label
+      78     1037748 :     ftype=type.substr(0,dash);
+      79             :   }
+      80      518879 :   plumed_massert( check(ftype), "metric " + ftype + " does not exist" );
+      81      518879 :   ReferenceConfigurationOptions ro( type );
+      82             : // put immediately the result in a safe pointer
+      83      518879 :   std::unique_ptr<ReferenceConfiguration> conf( m[ftype]( ro ) );
+      84             : // try conversion
+      85         136 :   T*ptr=dynamic_cast<T*>( conf.get() );
+      86             : // if this throws, the unique_ptr conf is deleted.
+      87             : // Notice that with the original version of the code (2.4) an error here
+      88             : // would have lead to a memory leak.
+      89      518879 :   if(!ptr ) plumed_merror( type + " metric is not valid in this context");
+      90             : // release ownership in order to transfer it to returned pointer
+      91             : // cppcheck-suppress ignoredReturnValue
+      92             :   conf.release();
+      93             : // notice that I should pass ptr here rather than conf.release(),
+      94             : // since the type is different
+      95             : // cppcheck-suppress returnDanglingLifetime
+      96      518879 :   return std::unique_ptr<T>(ptr);
+      97      518879 : }
+      98             : 
+      99             : template <class T>
+     100      518823 : std::unique_ptr<T> MetricRegister::create( const std::string& type, const PDB& pdb ) {
+     101             :   std::string rtype;
+     102      518823 :   if( type.length()==0 ) {
+     103          20 :     rtype=pdb.getMtype();
+     104          10 :     plumed_massert(rtype.length()>0, "TYPE not specified in pdb input file");
+     105             :   } else {
+     106             :     rtype=type;
+     107             :   }
+     108      518823 :   std::unique_ptr<T> confout( create<T>( rtype ) );
+     109      518823 :   confout->read( pdb );
+     110      518823 :   return confout;
+     111           0 : }
+     112             : 
+     113             : }
+     114             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MultiDomainRMSD.cpp.func-sort-c.html b/coverage/reference/MultiDomainRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..16465eaa1c13 --- /dev/null +++ b/coverage/reference/MultiDomainRMSD.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - reference/MultiDomainRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MultiDomainRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9010387.4 %
Date:2024-02-22 21:58:45Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15MultiDomainRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_0
_ZN4PLMD15MultiDomainRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD15MultiDomainRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZN4PLMD15MultiDomainRMSD15setupPCAStorageERNS_18ReferenceValuePackE2
_ZN4PLMD15MultiDomainRMSD28pcaIsEnabledForThisReferenceEv2
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE5
_ZN4PLMD15MultiDomainRMSD4readERKNS_3PDBE5
_ZN4PLMD15MultiDomainRMSDC1ERKNS_29ReferenceConfigurationOptionsE5
_ZNK4PLMD15MultiDomainRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb22
_ZNK4PLMD15MultiDomainRMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb37
_ZNK4PLMD15MultiDomainRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE44
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MultiDomainRMSD.cpp.func.html b/coverage/reference/MultiDomainRMSD.cpp.func.html new file mode 100644 index 000000000000..4bf25e99c37d --- /dev/null +++ b/coverage/reference/MultiDomainRMSD.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - reference/MultiDomainRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MultiDomainRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9010387.4 %
Date:2024-02-22 21:58:45Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE5
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_125MultiDomainRMSDRegisterMeD2Ev4187
_ZN4PLMD15MultiDomainRMSD15setupPCAStorageERNS_18ReferenceValuePackE2
_ZN4PLMD15MultiDomainRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_0
_ZN4PLMD15MultiDomainRMSD28pcaIsEnabledForThisReferenceEv2
_ZN4PLMD15MultiDomainRMSD4readERKNS_3PDBE5
_ZN4PLMD15MultiDomainRMSDC1ERKNS_29ReferenceConfigurationOptionsE5
_ZN4PLMD15MultiDomainRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD15MultiDomainRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZNK4PLMD15MultiDomainRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE44
_ZNK4PLMD15MultiDomainRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb22
_ZNK4PLMD15MultiDomainRMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb37
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/MultiDomainRMSD.cpp.gcov.html b/coverage/reference/MultiDomainRMSD.cpp.gcov.html new file mode 100644 index 000000000000..762f7465fb8f --- /dev/null +++ b/coverage/reference/MultiDomainRMSD.cpp.gcov.html @@ -0,0 +1,286 @@ + + + + + + + + LCOV - plumed test coverage - reference/MultiDomainRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - MultiDomainRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9010387.4 %
Date:2024-02-22 21:58:45Functions:101376.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiDomainRMSD.h"
+      23             : #include "SingleDomainRMSD.h"
+      24             : #include "MetricRegister.h"
+      25             : #include "tools/PDB.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29       12571 : PLUMED_REGISTER_METRIC(MultiDomainRMSD,"MULTI")
+      30             : 
+      31           5 : MultiDomainRMSD::MultiDomainRMSD( const ReferenceConfigurationOptions& ro ):
+      32             :   ReferenceConfiguration(ro),
+      33             :   ReferenceAtoms(ro),
+      34           5 :   ftype(ro.getMultiRMSDType())
+      35             : {
+      36           5 : }
+      37             : 
+      38           5 : void MultiDomainRMSD::read( const PDB& pdb ) {
+      39           5 :   unsigned nblocks =  pdb.getNumberOfAtomBlocks();
+      40           5 :   if( nblocks<2 ) error("multidomain RMSD only has one block of atoms");
+      41             : 
+      42             :   std::vector<Vector> positions; std::vector<double> align, displace;
+      43           5 :   std::string num; blocks.resize( nblocks+1 ); blocks[0]=0;
+      44          15 :   for(unsigned i=0; i<nblocks; ++i) blocks[i+1]=pdb.getAtomBlockEnds()[i];
+      45             : 
+      46             :   double tmp, lower=0.0, upper=std::numeric_limits<double>::max( );
+      47          10 :   if( pdb.getArgumentValue("LOWER_CUTOFF",tmp) ) lower=tmp;
+      48          10 :   if( pdb.getArgumentValue("UPPER_CUTOFF",tmp) ) upper=tmp;
+      49           5 :   bool nopbc=pdb.hasFlag("NOPBC");
+      50             : 
+      51           5 :   domains.resize(0); weights.resize(0);
+      52          15 :   for(unsigned i=1; i<=nblocks; ++i) {
+      53          10 :     Tools::convert(i,num);
+      54          10 :     if( ftype=="RMSD" ) {
+      55             :       // parse("TYPE"+num, ftype );
+      56             :       lower=0.0; upper=std::numeric_limits<double>::max( );
+      57           0 :       if( pdb.getArgumentValue("LOWER_CUTOFF"+num,tmp) ) lower=tmp;
+      58           0 :       if( pdb.getArgumentValue("UPPER_CUTOFF"+num,tmp) ) upper=tmp;
+      59           0 :       nopbc=pdb.hasFlag("NOPBC");
+      60             :     }
+      61          10 :     domains.emplace_back( metricRegister().create<SingleDomainRMSD>( ftype ) );
+      62          10 :     positions.resize( blocks[i] - blocks[i-1] );
+      63          10 :     align.resize( blocks[i] - blocks[i-1] );
+      64          10 :     displace.resize( blocks[i] - blocks[i-1] );
+      65             :     unsigned n=0;
+      66          69 :     for(unsigned j=blocks[i-1]; j<blocks[i]; ++j) {
+      67          59 :       positions[n]=pdb.getPositions()[j];
+      68          59 :       align[n]=pdb.getOccupancy()[j];
+      69          59 :       displace[n]=pdb.getBeta()[j];
+      70          59 :       n++;
+      71             :     }
+      72          10 :     domains[i-1]->setBoundsOnDistances( !nopbc, lower, upper );
+      73          10 :     domains[i-1]->setReferenceAtoms( positions, align, displace );
+      74          10 :     domains[i-1]->setupRMSDObject();
+      75             : 
+      76          10 :     double ww=0;
+      77          20 :     if( !pdb.getArgumentValue("WEIGHT"+num,ww) ) weights.push_back( 1.0 );
+      78           0 :     else weights.push_back( ww );
+      79             :   }
+      80             :   // And set the atom numbers for this object
+      81           5 :   indices.resize(0); atom_der_index.resize(0);
+      82          64 :   for(unsigned i=0; i<pdb.size(); ++i) { indices.push_back( pdb.getAtomNumbers()[i] ); atom_der_index.push_back(i); }
+      83             :   // setAtomNumbers( pdb.getAtomNumbers() );
+      84           5 : }
+      85             : 
+      86           0 : void MultiDomainRMSD::setReferenceAtoms( const std::vector<Vector>& conf, const std::vector<double>& align_in, const std::vector<double>& displace_in ) {
+      87           0 :   plumed_error();
+      88             : }
+      89             : 
+      90          37 : double MultiDomainRMSD::calculate( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
+      91          37 :   double totd=0.; Tensor tvirial; std::vector<Vector> mypos; MultiValue tvals( 1, 3*pos.size()+9 );
+      92          37 :   ReferenceValuePack tder( 0, getNumberOfAtoms(), tvals ); myder.clear();
+      93             : 
+      94         111 :   for(unsigned i=0; i<domains.size(); ++i) {
+      95             :     // Must extract appropriate positions here
+      96          74 :     mypos.resize( blocks[i+1] - blocks[i] );
+      97          74 :     if( myder.calcUsingPCAOption() ) domains[i]->setupPCAStorage( tder );
+      98         453 :     unsigned n=0; for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) { tder.setAtomIndex(n,j); mypos[n]=pos[j]; n++; }
+      99         453 :     for(unsigned k=n; k<getNumberOfAtoms(); ++k) tder.setAtomIndex(k,3*pos.size()+10);
+     100             :     // This actually does the calculation
+     101          74 :     totd += weights[i]*domains[i]->calculate( mypos, pbc, tder, true );
+     102             :     // Now merge the derivative
+     103          74 :     myder.copyScaledDerivatives( 0, weights[i], tvals );
+     104             :     // If PCA copy PCA stuff
+     105          74 :     if( myder.calcUsingPCAOption() ) {
+     106             :       unsigned n=0;
+     107          44 :       if( tder.centeredpos.size()>0 ) myder.rot[i]=tder.rot[0];
+     108         198 :       for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) {
+     109         154 :         myder.displacement[j]=weights[i]*tder.displacement[n];  // Multiplication by weights here ensures that normalisation is done correctly
+     110         154 :         if( tder.centeredpos.size()>0 ) {
+     111          77 :           myder.centeredpos[j]=tder.centeredpos[n];
+     112        1001 :           for(unsigned p=0; p<3; ++p) for(unsigned q=0; q<3; ++q) myder.DRotDPos(p,q)[j]=tder.DRotDPos(p,q)[n];
+     113             :         }
+     114         154 :         n++;
+     115             :       }
+     116             :     }
+     117             :     // Make sure virial status is set correctly in output derivative pack
+     118             :     // This is only done here so I do this by using class friendship
+     119          74 :     if( tder.virialWasSet() ) myder.boxWasSet=true;
+     120             :   }
+     121          37 :   if( !myder.updateComplete() ) myder.updateDynamicLists();
+     122             : 
+     123          37 :   if( !squared ) {
+     124          15 :     totd=std::sqrt(totd); double xx=0.5/totd;
+     125          15 :     myder.scaleAllDerivatives( xx );
+     126             :   }
+     127          37 :   return totd;
+     128          37 : }
+     129             : 
+     130          22 : double MultiDomainRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& arg,
+     131             :                               ReferenceValuePack& myder, const bool& squared ) const {
+     132             :   plumed_dbg_assert( vals.size()==0 && pos.size()==getNumberOfAtoms() && arg.size()==0 );
+     133          22 :   return calculate( pos, pbc, myder, squared );
+     134             : }
+     135             : 
+     136           2 : bool MultiDomainRMSD::pcaIsEnabledForThisReference() {
+     137             :   bool enabled=true;
+     138           6 :   for(unsigned i=0; i<domains.size(); ++i) {
+     139           4 :     if( !domains[i]->pcaIsEnabledForThisReference() ) enabled=false;
+     140             :   }
+     141           2 :   return enabled;
+     142             : }
+     143             : 
+     144           2 : void MultiDomainRMSD::setupPCAStorage( ReferenceValuePack& mypack ) {
+     145             :   plumed_dbg_assert( pcaIsEnabledForThisReference() );
+     146             :   mypack.switchOnPCAOption();
+     147           2 :   mypack.displacement.resize( getNumberOfAtoms() );
+     148           2 :   mypack.centeredpos.resize( getNumberOfAtoms() );
+     149           2 :   mypack.DRotDPos.resize(3,3); mypack.rot.resize( domains.size() );
+     150          26 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) mypack.DRotDPos(i,j).resize( getNumberOfAtoms() );
+     151           2 : }
+     152             : 
+     153             : // Vector MultiDomainRMSD::getAtomicDisplacement( const unsigned& iatom ){
+     154             : //   for(unsigned i=0;i<domains.size();++i){
+     155             : //       unsigned n=0;
+     156             : //       for(unsigned j=blocks[i];j<blocks[i+1];++j){
+     157             : //           if( j==iatom ) return weights[i]*domains[i]->getAtomicDisplacement(n);
+     158             : //           n++;
+     159             : //       }
+     160             : //   }
+     161             : // }
+     162             : 
+     163           0 : void MultiDomainRMSD::extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& direction ) const {
+     164             :   std::vector<Vector> mypos, mydir;
+     165           0 :   for(unsigned i=0; i<domains.size(); ++i) {
+     166             :     // Must extract appropriate positions here
+     167           0 :     mypos.resize( blocks[i+1] - blocks[i] ); mydir.resize( blocks[i+1] - blocks[i] );
+     168           0 :     unsigned n=0; for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) { mypos[n]=pos[j]; n++; }
+     169             :     // Do the calculation
+     170           0 :     domains[i]->extractAtomicDisplacement( mypos, mydir );
+     171             :     // Extract the direction
+     172           0 :     n=0; for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) { direction[j]=weights[i]*mydir[n];  n++; }
+     173             :   }
+     174           0 : }
+     175             : 
+     176          44 : double MultiDomainRMSD::projectAtomicDisplacementOnVector( const bool& normalized, const std::vector<Vector>& vecs, ReferenceValuePack& mypack ) const {
+     177          44 :   double totd=0.; std::vector<Vector> tvecs; mypack.clear();
+     178          44 :   MultiValue tvals( 1, mypack.getNumberOfDerivatives() ); ReferenceValuePack tder( 0, getNumberOfAtoms(), tvals );
+     179         132 :   for(unsigned i=0; i<domains.size(); ++i) {
+     180             :     // Must extract appropriate positions here
+     181          88 :     tvecs.resize( blocks[i+1] - blocks[i] ); domains[i]->setupPCAStorage( tder );
+     182          88 :     if( tder.centeredpos.size()>0 ) {
+     183         572 :       for(unsigned p=0; p<3; ++p) for(unsigned q=0; q<3; ++q) tder.DRotDPos(p,q).resize( tvecs.size() );
+     184             :     }
+     185             :     // Extract information from storage pack and put in local pack
+     186          88 :     if( tder.centeredpos.size()>0 ) tder.rot[0]=mypack.rot[i];
+     187             :     unsigned n=0;
+     188         396 :     for(unsigned j=blocks[i]; j<blocks[i+1]; ++j) {
+     189         308 :       tder.setAtomIndex(n,j); tvecs[n] = vecs[j]; tder.displacement[n]=mypack.displacement[j] / weights[i];
+     190         308 :       if( tder.centeredpos.size()>0 ) {
+     191         154 :         tder.centeredpos[n]=mypack.centeredpos[j];
+     192        2002 :         for(unsigned p=0; p<3; ++p) for(unsigned q=0; q<3; ++q) tder.DRotDPos(p,q)[n]=mypack.DRotDPos(p,q)[j];
+     193             :       }
+     194         308 :       n++;
+     195             :     }
+     196         396 :     for(unsigned k=n; k<getNumberOfAtoms(); ++k) tder.setAtomIndex(k,3*vecs.size()+10);
+     197             : 
+     198             :     // Do the calculations
+     199          88 :     totd += weights[i]*domains[i]->projectAtomicDisplacementOnVector( normalized, tvecs, tder );
+     200             : 
+     201             :     // And derivatives
+     202          88 :     mypack.copyScaledDerivatives( 0, weights[i], tvals );
+     203             :   }
+     204          44 :   if( !mypack.updateComplete() ) mypack.updateDynamicLists();
+     205             : 
+     206          44 :   return totd;
+     207          44 : }
+     208             : 
+     209             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/NormalizedEuclideanDistance.cpp.func-sort-c.html b/coverage/reference/NormalizedEuclideanDistance.cpp.func-sort-c.html new file mode 100644 index 000000000000..3dadd5c98857 --- /dev/null +++ b/coverage/reference/NormalizedEuclideanDistance.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/NormalizedEuclideanDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - NormalizedEuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1520.0 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD27NormalizedEuclideanDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD27NormalizedEuclideanDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/NormalizedEuclideanDistance.cpp.func.html b/coverage/reference/NormalizedEuclideanDistance.cpp.func.html new file mode 100644 index 000000000000..cf6112b7d870 --- /dev/null +++ b/coverage/reference/NormalizedEuclideanDistance.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/NormalizedEuclideanDistance.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - NormalizedEuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1520.0 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMe6createERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_137NormalizedEuclideanDistanceRegisterMeD2Ev4187
_ZN4PLMD27NormalizedEuclideanDistanceC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD27NormalizedEuclideanDistanceC2ERKNS_29ReferenceConfigurationOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/NormalizedEuclideanDistance.cpp.gcov.html b/coverage/reference/NormalizedEuclideanDistance.cpp.gcov.html new file mode 100644 index 000000000000..c8dd053db228 --- /dev/null +++ b/coverage/reference/NormalizedEuclideanDistance.cpp.gcov.html @@ -0,0 +1,118 @@ + + + + + + + + LCOV - plumed test coverage - reference/NormalizedEuclideanDistance.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - NormalizedEuclideanDistance.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1520.0 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetricRegister.h"
+      23             : #include "ArgumentOnlyDistance.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27             : class NormalizedEuclideanDistance : public ArgumentOnlyDistance {
+      28             : public:
+      29             :   explicit NormalizedEuclideanDistance( const ReferenceConfigurationOptions& ro );
+      30             : };
+      31             : 
+      32       12561 : PLUMED_REGISTER_METRIC(NormalizedEuclideanDistance,"NORM-EUCLIDEAN")
+      33             : 
+      34           0 : NormalizedEuclideanDistance::NormalizedEuclideanDistance( const ReferenceConfigurationOptions& ro ):
+      35             :   ReferenceConfiguration(ro),
+      36           0 :   ArgumentOnlyDistance(ro)
+      37             : {
+      38           0 :   hasweights=true;
+      39           0 : }
+      40             : 
+      41             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/OptimalRMSD.cpp.func-sort-c.html b/coverage/reference/OptimalRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..ab97f03cc422 --- /dev/null +++ b/coverage/reference/OptimalRMSD.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - reference/OptimalRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - OptimalRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5353100.0 %
Date:2024-02-22 21:58:45Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11OptimalRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD11OptimalRMSD28pcaIsEnabledForThisReferenceEv45
_ZN4PLMD11OptimalRMSD15setupPCAStorageERNS_18ReferenceValuePackE72
_ZN4PLMD11OptimalRMSD4readERKNS_3PDBE427
_ZN4PLMD11OptimalRMSDC1ERKNS_29ReferenceConfigurationOptionsE437
_ZN4PLMD12_GLOBAL__N_121OptimalRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE437
_ZN4PLMD11OptimalRMSD15setupRMSDObjectEv455
_ZNK4PLMD11OptimalRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_1107
_ZNK4PLMD11OptimalRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE1158
_ZN4PLMD12_GLOBAL__N_121OptimalRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_121OptimalRMSDRegisterMeD2Ev4187
_ZNK4PLMD11OptimalRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb218933
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/OptimalRMSD.cpp.func.html b/coverage/reference/OptimalRMSD.cpp.func.html new file mode 100644 index 000000000000..a49b8b32d39a --- /dev/null +++ b/coverage/reference/OptimalRMSD.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - reference/OptimalRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - OptimalRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5353100.0 %
Date:2024-02-22 21:58:45Functions:111291.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11OptimalRMSD15setupPCAStorageERNS_18ReferenceValuePackE72
_ZN4PLMD11OptimalRMSD15setupRMSDObjectEv455
_ZN4PLMD11OptimalRMSD28pcaIsEnabledForThisReferenceEv45
_ZN4PLMD11OptimalRMSD4readERKNS_3PDBE427
_ZN4PLMD11OptimalRMSDC1ERKNS_29ReferenceConfigurationOptionsE437
_ZN4PLMD11OptimalRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_121OptimalRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE437
_ZN4PLMD12_GLOBAL__N_121OptimalRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_121OptimalRMSDRegisterMeD2Ev4187
_ZNK4PLMD11OptimalRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_1107
_ZNK4PLMD11OptimalRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE1158
_ZNK4PLMD11OptimalRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb218933
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/OptimalRMSD.cpp.gcov.html b/coverage/reference/OptimalRMSD.cpp.gcov.html new file mode 100644 index 000000000000..d6e76da295f9 --- /dev/null +++ b/coverage/reference/OptimalRMSD.cpp.gcov.html @@ -0,0 +1,195 @@ + + + + + + + + LCOV - plumed test coverage - reference/OptimalRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - OptimalRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5353100.0 %
Date:2024-02-22 21:58:45Functions:111291.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MetricRegister.h"
+      23             : #include "RMSDBase.h"
+      24             : #include "tools/Matrix.h"
+      25             : #include "tools/RMSD.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : class OptimalRMSD : public RMSDBase {
+      30             : private:
+      31             :   bool fast;
+      32             :   RMSD myrmsd;
+      33             : public:
+      34             :   explicit OptimalRMSD(const ReferenceConfigurationOptions& ro);
+      35             :   void read( const PDB& ) override;
+      36             :   double calc( const std::vector<Vector>& pos, ReferenceValuePack& myder, const bool& squared ) const override;
+      37          45 :   bool pcaIsEnabledForThisReference() override { return true; }
+      38         910 :   void setupRMSDObject() override { myrmsd.clear(); myrmsd.set(getAlign(),getDisplace(),getReferencePositions(),"OPTIMAL"); }
+      39          72 :   void setupPCAStorage( ReferenceValuePack& mypack ) override {
+      40             :     mypack.switchOnPCAOption();
+      41          72 :     mypack.centeredpos.resize( getNumberOfAtoms() );
+      42          72 :     mypack.displacement.resize( getNumberOfAtoms() );
+      43          72 :     mypack.DRotDPos.resize(3,3); mypack.rot.resize(1);
+      44          72 :   }
+      45             :   void extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& direction ) const override;
+      46             :   double projectAtomicDisplacementOnVector( const bool& normalized, const std::vector<Vector>& vecs, ReferenceValuePack& mypack ) const override;
+      47             : };
+      48             : 
+      49       13435 : PLUMED_REGISTER_METRIC(OptimalRMSD,"OPTIMAL")
+      50             : 
+      51         437 : OptimalRMSD::OptimalRMSD(const ReferenceConfigurationOptions& ro ):
+      52             :   ReferenceConfiguration(ro),
+      53         437 :   RMSDBase(ro)
+      54             : {
+      55         437 :   fast=ro.usingFastOption();
+      56         437 : }
+      57             : 
+      58         427 : void OptimalRMSD::read( const PDB& pdb ) {
+      59         427 :   readReference( pdb ); setupRMSDObject();
+      60         427 : }
+      61             : 
+      62      218933 : double OptimalRMSD::calc( const std::vector<Vector>& pos, ReferenceValuePack& myder, const bool& squared ) const {
+      63             :   double d;
+      64      218933 :   if( myder.calcUsingPCAOption() ) {
+      65        2786 :     std::vector<Vector> centeredreference( getNumberOfAtoms () );
+      66        2786 :     d=myrmsd.calc_PCAelements(pos,myder.getAtomVector(),myder.rot[0],myder.DRotDPos,myder.getAtomsDisplacementVector(),myder.centeredpos,centeredreference,squared);
+      67        2786 :     unsigned nat = pos.size();
+      68       48548 :     for(unsigned i=0; i<nat; ++i) { myder.getAtomsDisplacementVector()[i] -= getReferencePosition(i); myder.getAtomsDisplacementVector()[i] *= getDisplace()[i]; }
+      69      216147 :   } else if( fast ) {
+      70      192640 :     if( getAlign()==getDisplace() ) d=myrmsd.optimalAlignment<false,true>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
+      71           2 :     else d=myrmsd.optimalAlignment<false,false>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
+      72             :   } else {
+      73       23507 :     if( getAlign()==getDisplace() ) d=myrmsd.optimalAlignment<true,true>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
+      74         111 :     else d=myrmsd.optimalAlignment<true,false>(getAlign(),getDisplace(),pos,getReferencePositions(),myder.getAtomVector(),squared);
+      75             :   }
+      76    17762561 :   myder.clear(); for(unsigned i=0; i<pos.size(); ++i) myder.setAtomDerivatives( i, myder.getAtomVector()[i] );
+      77      218933 :   if( !myder.updateComplete() ) myder.updateDynamicLists();
+      78      218933 :   return d;
+      79             : }
+      80             : 
+      81        1107 : void OptimalRMSD::extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& direction ) const {
+      82        1107 :   std::vector<Tensor> rot(1);  Matrix<std::vector<Vector> > DRotDPos( 3, 3 );
+      83        1107 :   std::vector<Vector> centeredreference( getNumberOfAtoms() ), centeredpos( getNumberOfAtoms() ), avector( getNumberOfAtoms() );
+      84        1107 :   myrmsd.calc_PCAelements(pos,avector,rot[0],DRotDPos,direction,centeredpos,centeredreference,true);
+      85       15498 :   unsigned nat = pos.size(); for(unsigned i=0; i<nat; ++i) direction[i] = getDisplace()[i]*( direction[i] - getReferencePosition(i) );
+      86        1107 : }
+      87             : 
+      88        1158 : double OptimalRMSD::projectAtomicDisplacementOnVector( const bool& normalized, const std::vector<Vector>& vecs, ReferenceValuePack& mypack ) const {
+      89             :   plumed_dbg_assert( mypack.calcUsingPCAOption() );
+      90             : 
+      91        1158 :   double proj=0.0; mypack.clear();
+      92       15662 :   for(unsigned i=0; i<vecs.size(); ++i) {
+      93       14504 :     proj += dotProduct( mypack.getAtomsDisplacementVector()[i], vecs[i] );
+      94             :   }
+      95        4632 :   for(unsigned a=0; a<3; a++) {
+      96       13896 :     for(unsigned b=0; b<3; b++) {
+      97      140958 :       double tmp1=0.; for(unsigned n=0; n<getNumberOfAtoms(); n++) tmp1+=mypack.centeredpos[n][b]*vecs[n][a];
+      98             : 
+      99      140958 :       for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) {
+     100      130536 :         if( normalized ) mypack.addAtomDerivatives( iat, getDisplace()[iat]*mypack.DRotDPos[a][b][iat]*tmp1 );
+     101      127764 :         else mypack.addAtomDerivatives( iat, mypack.DRotDPos[a][b][iat]*tmp1 );
+     102             :       }
+     103             :     }
+     104             :   }
+     105        1158 :   Tensor trot=mypack.rot[0].transpose();
+     106        1158 :   Vector v1; v1.zero(); double prefactor = 1. / static_cast<double>( getNumberOfAtoms() );
+     107       15662 :   for(unsigned n=0; n<getNumberOfAtoms(); n++) v1+=prefactor*matmul(trot,vecs[n]);
+     108        1158 :   if( normalized ) {
+     109         374 :     for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) mypack.addAtomDerivatives( iat, getDisplace()[iat]*(matmul(trot,vecs[iat]) - v1) );
+     110             :   } else {
+     111       15288 :     for(unsigned iat=0; iat<getNumberOfAtoms(); iat++) mypack.addAtomDerivatives( iat, (matmul(trot,vecs[iat]) - v1) );
+     112             :   }
+     113        1158 :   if( !mypack.updateComplete() ) mypack.updateDynamicLists();
+     114             : 
+     115        1158 :   return proj;
+     116             : }
+     117             : 
+     118             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/RMSDBase.cpp.func-sort-c.html b/coverage/reference/RMSDBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..6f3d33033003 --- /dev/null +++ b/coverage/reference/RMSDBase.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - reference/RMSDBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - RMSDBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8RMSDBaseC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD8RMSDBaseC2ERKNS_29ReferenceConfigurationOptionsE472
_ZNK4PLMD8RMSDBase9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb40496
_ZNK4PLMD8RMSDBase4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb178609
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/RMSDBase.cpp.func.html b/coverage/reference/RMSDBase.cpp.func.html new file mode 100644 index 000000000000..70f502d0a32c --- /dev/null +++ b/coverage/reference/RMSDBase.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - reference/RMSDBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - RMSDBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8RMSDBaseC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD8RMSDBaseC2ERKNS_29ReferenceConfigurationOptionsE472
_ZNK4PLMD8RMSDBase4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb178609
_ZNK4PLMD8RMSDBase9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb40496
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/RMSDBase.cpp.gcov.html b/coverage/reference/RMSDBase.cpp.gcov.html new file mode 100644 index 000000000000..cd44ceef3c76 --- /dev/null +++ b/coverage/reference/RMSDBase.cpp.gcov.html @@ -0,0 +1,119 @@ + + + + + + + + LCOV - plumed test coverage - reference/RMSDBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - RMSDBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:77100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "RMSDBase.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : 
+      26         472 : RMSDBase::RMSDBase( const ReferenceConfigurationOptions& ro ):
+      27             :   ReferenceConfiguration(ro),
+      28         472 :   SingleDomainRMSD(ro)
+      29             : {
+      30         472 : }
+      31             : 
+      32       40496 : double RMSDBase::calculate( const std::vector<Vector>& pos, ReferenceValuePack& myder, const bool& squared ) const {
+      33             : //  clearDerivatives();
+      34       40496 :   return calc( pos, myder, squared );
+      35             : }
+      36             : 
+      37      178609 : double RMSDBase::calc( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
+      38             :   plumed_dbg_assert( pos.size()==getNumberOfAtoms() );
+      39      178609 :   return calc( pos, myder, squared );
+      40             : }
+      41             : 
+      42             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.cpp.func-sort-c.html b/coverage/reference/ReferenceArguments.cpp.func-sort-c.html new file mode 100644 index 000000000000..c1e5091a338a --- /dev/null +++ b/coverage/reference/ReferenceArguments.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceArguments.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceArguments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6710663.2 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceArguments18getReferenceMetricEv0
_ZN4PLMD18ReferenceArgumentsC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD18ReferenceArguments19getArgumentRequestsERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEb187
_ZN4PLMD18ReferenceArguments21setReferenceArgumentsERKSt6vectorIdSaIdEES5_494
_ZN4PLMD18ReferenceArguments22moveReferenceArgumentsERKSt6vectorIdSaIdEE494
_ZN4PLMD18ReferenceArguments26displaceReferenceArgumentsERKdRKSt6vectorIdSaIdEE500
_ZNK4PLMD18ReferenceArguments27extractArgumentDisplacementERKSt6vectorIPNS_5ValueESaIS3_EERKS1_IdSaIdEERS9_1964
_ZNK4PLMD18ReferenceArguments30projectArgDisplacementOnVectorERKSt6vectorIdSaIdEERKS1_IPNS_5ValueESaIS7_EES5_RNS_18ReferenceValuePackE2386
_ZNK4PLMD18ReferenceArguments25calculateArgumentDistanceERKSt6vectorIPNS_5ValueESaIS3_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb299760
_ZN4PLMD18ReferenceArgumentsC2ERKNS_29ReferenceConfigurationOptionsE518583
_ZN4PLMD18ReferenceArguments20readArgumentsFromPDBERKNS_3PDBE519050
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.cpp.func.html b/coverage/reference/ReferenceArguments.cpp.func.html new file mode 100644 index 000000000000..596168315ad6 --- /dev/null +++ b/coverage/reference/ReferenceArguments.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceArguments.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceArguments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6710663.2 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceArguments18getReferenceMetricEv0
_ZN4PLMD18ReferenceArguments19getArgumentRequestsERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEb187
_ZN4PLMD18ReferenceArguments20readArgumentsFromPDBERKNS_3PDBE519050
_ZN4PLMD18ReferenceArguments21setReferenceArgumentsERKSt6vectorIdSaIdEES5_494
_ZN4PLMD18ReferenceArguments22moveReferenceArgumentsERKSt6vectorIdSaIdEE494
_ZN4PLMD18ReferenceArguments26displaceReferenceArgumentsERKdRKSt6vectorIdSaIdEE500
_ZN4PLMD18ReferenceArgumentsC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD18ReferenceArgumentsC2ERKNS_29ReferenceConfigurationOptionsE518583
_ZNK4PLMD18ReferenceArguments25calculateArgumentDistanceERKSt6vectorIPNS_5ValueESaIS3_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb299760
_ZNK4PLMD18ReferenceArguments27extractArgumentDisplacementERKSt6vectorIPNS_5ValueESaIS3_EERKS1_IdSaIdEERS9_1964
_ZNK4PLMD18ReferenceArguments30projectArgDisplacementOnVectorERKSt6vectorIdSaIdEERKS1_IPNS_5ValueESaIS7_EES5_RNS_18ReferenceValuePackE2386
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.cpp.gcov.html b/coverage/reference/ReferenceArguments.cpp.gcov.html new file mode 100644 index 000000000000..b1708de99723 --- /dev/null +++ b/coverage/reference/ReferenceArguments.cpp.gcov.html @@ -0,0 +1,281 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceArguments.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceArguments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6710663.2 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ReferenceArguments.h"
+      23             : #include "ReferenceAtoms.h"
+      24             : #include "tools/OFile.h"
+      25             : #include "core/Value.h"
+      26             : #include "tools/PDB.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30      518583 : ReferenceArguments::ReferenceArguments( const ReferenceConfigurationOptions& ro ):
+      31             :   ReferenceConfiguration(ro),
+      32      518583 :   hasweights(false),
+      33      518583 :   hasmetric(false)
+      34             : {
+      35      518583 : }
+      36             : 
+      37      519050 : void ReferenceArguments::readArgumentsFromPDB( const PDB& pdb ) {
+      38      519050 :   ReferenceAtoms* aref=dynamic_cast<ReferenceAtoms*>( this );
+      39      519050 :   arg_names.resize( pdb.getArgumentNames().size() );
+      40     2015570 :   for(unsigned i=0; i<arg_names.size(); ++i) arg_names[i]=pdb.getArgumentNames()[i];
+      41      519050 :   if( !aref && arg_names.size()==0 ) error("no arguments in input PDB file");
+      42             : 
+      43      519050 :   reference_args.resize( arg_names.size() ); arg_der_index.resize( arg_names.size() );
+      44     2015570 :   for(unsigned i=0; i<arg_names.size(); ++i) {
+      45     1496520 :     if( !pdb.getArgumentValue(arg_names[i], reference_args[i]) ) error("argument " + arg_names[i] + " was not set in pdb input");
+      46     1496520 :     arg_der_index[i]=i;
+      47             :   }
+      48             : 
+      49      519050 :   if( hasweights ) {
+      50           0 :     plumed_massert( !hasmetric, "should not have weights if we are using metric");
+      51           0 :     weights.resize( arg_names.size() ); sqrtweight.resize( arg_names.size() );
+      52           0 :     for(unsigned i=0; i<reference_args.size(); ++i) {
+      53           0 :       if( !pdb.getArgumentValue("sigma_" + arg_names[i], weights[i]) ) error("value sigma_" + arg_names[i] + " was not set in pdb input");
+      54           0 :       sqrtweight[i] = std::sqrt( weights[i] );
+      55             :     }
+      56      519050 :   } else if( hasmetric ) {
+      57             :     plumed_massert( !hasweights, "should not have weights if we are using metric");
+      58           0 :     double thissig; metric.resize( arg_names.size(), arg_names.size() );
+      59           0 :     for(unsigned i=0; i<reference_args.size(); ++i) {
+      60           0 :       for(unsigned j=i; j<reference_args.size(); ++j) {
+      61           0 :         if( !pdb.getArgumentValue("sigma_" + arg_names[i] + "_" + arg_names[j], thissig) ) {
+      62           0 :           error("value sigma_" + arg_names[i] + "_" + arg_names[j] + " was not set in pdb input");
+      63             :         }
+      64           0 :         metric(i,j)=metric(j,i)=thissig;
+      65             :       }
+      66             :     }
+      67             :   } else {
+      68      519050 :     weights.resize( arg_names.size() ); sqrtweight.resize( arg_names.size() );
+      69     2015570 :     for(unsigned i=0; i<weights.size(); ++i) sqrtweight[i]=weights[i]=1.0;
+      70             :   }
+      71      519050 : }
+      72             : 
+      73         494 : void ReferenceArguments::setReferenceArguments( const std::vector<double>& arg_vals, const std::vector<double>& sigma ) {
+      74         494 :   moveReferenceArguments( arg_vals );
+      75             : 
+      76         494 :   if( hasmetric ) {
+      77             :     unsigned k=0;
+      78           0 :     for(unsigned i=0; i<reference_args.size(); ++i) {
+      79           0 :       for(unsigned j=i; j<reference_args.size(); ++j) {
+      80           0 :         metric(i,j)=metric(j,i)=sigma[k]; k++;
+      81             :       }
+      82             :     }
+      83           0 :     plumed_assert( k==sigma.size() );
+      84             :   } else {
+      85         494 :     plumed_assert( reference_args.size()==sigma.size() );
+      86        1448 :     for(unsigned i=0; i<reference_args.size(); ++i) weights[i]=sigma[i];
+      87             :   }
+      88         494 : }
+      89             : 
+      90         494 : void ReferenceArguments::moveReferenceArguments( const std::vector<double>& arg_vals ) {
+      91             :   plumed_dbg_assert( reference_args.size()==arg_vals.size() );
+      92        1448 :   for(unsigned i=0; i<arg_vals.size(); ++i) reference_args[i]=arg_vals[i];
+      93         494 : }
+      94             : 
+      95         187 : void ReferenceArguments::getArgumentRequests( std::vector<std::string>& argout, bool disable_checks ) {
+      96         187 :   arg_der_index.resize( arg_names.size() );
+      97             : 
+      98         187 :   if( argout.size()==0 ) {
+      99          31 :     for(unsigned i=0; i<arg_names.size(); ++i) {
+     100          15 :       argout.push_back( arg_names[i] );
+     101          15 :       arg_der_index[i]=i;
+     102             :     }
+     103             :   } else {
+     104         171 :     if(!disable_checks) {
+     105         171 :       if( arg_names.size()!=argout.size() ) error("mismatched numbers of arguments in pdb frames");
+     106             :     }
+     107         762 :     for(unsigned i=0; i<arg_names.size(); ++i) {
+     108         591 :       if(!disable_checks) {
+     109         591 :         if( argout[i]!=arg_names[i] ) error("found mismatched arguments in pdb frames");
+     110         591 :         arg_der_index[i]=i;
+     111             :       } else {
+     112             :         bool found=false;
+     113           0 :         for(unsigned j=0; j<arg_names.size(); ++j) {
+     114           0 :           if( argout[j]==arg_names[i] ) { found=true; arg_der_index[i]=j; break; }
+     115             :         }
+     116             :         if( !found ) {
+     117           0 :           arg_der_index[i]=argout.size(); argout.push_back( arg_names[i] );
+     118             :         }
+     119             :       }
+     120             :     }
+     121             :   }
+     122         187 : }
+     123             : 
+     124           0 : const std::vector<double>& ReferenceArguments::getReferenceMetric() {
+     125           0 :   if( hasmetric ) {
+     126           0 :     unsigned ntot=(reference_args.size() / 2 )*(reference_args.size()+1);
+     127           0 :     if( trig_metric.size()!=ntot ) trig_metric.resize( ntot );
+     128             :     unsigned k=0;
+     129           0 :     for(unsigned i=0; i<reference_args.size(); ++i) {
+     130           0 :       for(unsigned j=i; j<reference_args.size(); ++j) {
+     131             :         plumed_dbg_assert( std::fabs( metric(i,j)-metric(j,i) ) < epsilon );
+     132           0 :         trig_metric[k]=metric(i,j); k++;
+     133             :       }
+     134             :     }
+     135             :   } else {
+     136           0 :     if( trig_metric.size()!=reference_args.size() ) trig_metric.resize( reference_args.size() );
+     137           0 :     for(unsigned i=0; i<reference_args.size(); ++i) trig_metric[i]=weights[i];
+     138             :   }
+     139           0 :   return trig_metric;
+     140             : }
+     141             : 
+     142      299760 : double ReferenceArguments::calculateArgumentDistance( const std::vector<Value*> & vals, const std::vector<double>& arg,
+     143             :     ReferenceValuePack& myder, const bool& squared ) const {
+     144      299760 :   double r=0; std::vector<double> arg_ders( vals.size() );
+     145      299760 :   if( hasmetric ) {
+     146           0 :     for(unsigned i=0; i<reference_args.size(); ++i) {
+     147           0 :       unsigned ik=arg_der_index[i]; arg_ders[ ik ]=0;
+     148           0 :       double dp_i=vals[ik]->difference( reference_args[i], arg[ik] );
+     149           0 :       for(unsigned j=0; j<reference_args.size(); ++j) {
+     150             :         double dp_j;
+     151           0 :         unsigned jk=arg_der_index[j];
+     152           0 :         if(i==j) dp_j=dp_i;
+     153           0 :         else dp_j=vals[jk]->difference( reference_args[j], arg[jk] );
+     154             : 
+     155           0 :         arg_ders[ ik ]+=2.0*metric(i,j)*dp_j;    // Factor of two for off diagonal terms as you have terms from ij and ji
+     156           0 :         r+=dp_i*dp_j*metric(i,j);
+     157             :       }
+     158             :     }
+     159             :   } else {
+     160     1128420 :     for(unsigned i=0; i<reference_args.size(); ++i) {
+     161      828660 :       unsigned ik=arg_der_index[i];
+     162      828660 :       double dp_i=vals[ik]->difference( reference_args[i], arg[ik] );
+     163      828660 :       r+=weights[i]*dp_i*dp_i; arg_ders[ik]=2.0*weights[i]*dp_i;
+     164             :     }
+     165             :   }
+     166      299760 :   if(!squared) {
+     167         572 :     r=std::sqrt(r); double ir=1.0/(2.0*r);
+     168        1716 :     for(unsigned i=0; i<arg_ders.size(); ++i) myder.setArgumentDerivatives( i, arg_ders[i]*ir );
+     169             :   } else {
+     170     1126704 :     for(unsigned i=0; i<arg_ders.size(); ++i) myder.setArgumentDerivatives( i, arg_ders[i] );
+     171             :   }
+     172      299760 :   return r;
+     173             : }
+     174             : 
+     175        1964 : void ReferenceArguments::extractArgumentDisplacement( const std::vector<Value*>& vals, const std::vector<double>& arg, std::vector<double>& dirout ) const {
+     176        1964 :   if( hasmetric ) {
+     177           0 :     plumed_error();
+     178             :   } else {
+     179        5892 :     for(unsigned j=0; j<reference_args.size(); ++j) {
+     180        3928 :       unsigned jk=arg_der_index[j]; dirout[jk]=sqrtweight[j]*vals[jk]->difference( reference_args[j], arg[jk] );
+     181             :     }
+     182             :   }
+     183        1964 : }
+     184             : 
+     185        2386 : double ReferenceArguments::projectArgDisplacementOnVector( const std::vector<double>& eigv, const std::vector<Value*>& vals, const std::vector<double>& arg, ReferenceValuePack& mypack ) const {
+     186        2386 :   if( hasmetric ) {
+     187           0 :     plumed_error();
+     188             :   } else {
+     189             :     double proj=0;
+     190        7158 :     for(unsigned j=0; j<reference_args.size(); ++j) {
+     191        4772 :       unsigned jk=arg_der_index[j];
+     192        4772 :       proj += eigv[j]*sqrtweight[j]*vals[jk]->difference( reference_args[j], arg[jk] );
+     193        4772 :       mypack.setArgumentDerivatives( jk, eigv[j]*sqrtweight[j] );
+     194             :     }
+     195        2386 :     return proj;
+     196             :   }
+     197             : }
+     198             : 
+     199         500 : void ReferenceArguments::displaceReferenceArguments( const double& weight, const std::vector<double>& displace ) {
+     200             :   plumed_dbg_assert( displace.size()==getNumberOfReferenceArguments() );
+     201        1466 :   for(unsigned i=0; i<displace.size(); ++i) reference_args[i] += weight*displace[i];
+     202         500 : }
+     203             : 
+     204             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.h.func-sort-c.html b/coverage/reference/ReferenceArguments.h.func-sort-c.html new file mode 100644 index 000000000000..d36267c01079 --- /dev/null +++ b/coverage/reference/ReferenceArguments.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceArguments.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceArguments.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceArguments16getArgumentNamesB5cxx11Ev962
_ZNK4PLMD18ReferenceArguments20getReferenceArgumentERKj1020
_ZNK4PLMD18ReferenceArguments29getNumberOfReferenceArgumentsEv39585
_ZNK4PLMD18ReferenceArguments21getReferenceArgumentsEv790964
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.h.func.html b/coverage/reference/ReferenceArguments.h.func.html new file mode 100644 index 000000000000..07af89d28475 --- /dev/null +++ b/coverage/reference/ReferenceArguments.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceArguments.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceArguments.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceArguments16getArgumentNamesB5cxx11Ev962
_ZNK4PLMD18ReferenceArguments20getReferenceArgumentERKj1020
_ZNK4PLMD18ReferenceArguments21getReferenceArgumentsEv790964
_ZNK4PLMD18ReferenceArguments29getNumberOfReferenceArgumentsEv39585
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceArguments.h.gcov.html b/coverage/reference/ReferenceArguments.h.gcov.html new file mode 100644 index 000000000000..781ca61f681a --- /dev/null +++ b/coverage/reference/ReferenceArguments.h.gcov.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceArguments.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceArguments.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_reference_ReferenceArguments_h
+      23             : #define __PLUMED_reference_ReferenceArguments_h
+      24             : 
+      25             : #include "ReferenceConfiguration.h"
+      26             : #include "tools/Matrix.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : /// \ingroup TOOLBOX
+      31             : /// In many applications (e.g. paths, fields, property maps) it is necessary to calculate
+      32             : /// the distance between two configurations.  These distances can be calculated in a variety of
+      33             : /// different ways.  For instance, one can assert that the distance between the two configuration
+      34             : /// is the distance one would have to move all the atoms to transform configuration 1 into configuration
+      35             : /// 2. Alternatively, one could calculate the values of a large set of collective coordinates in the two
+      36             : /// configurations and then calculate the Euclidean distances between these two points in the resulting
+      37             : /// high-dimensional vector space.  Lastly, one can combine these two forms of distance calculation to calculate
+      38             : /// a hybrid distance.  Plumed allows one to use all these forms of distance calculations and also to implement
+      39             : /// new forms of distance.  You should inherit from this class if your distance involves reference colvar values.
+      40             : /// This class and \ref PLMD::ReferenceAtoms mirror the functionalities in \ref PLMD::ActionWithArguments and
+      41             : /// \ref PLMD::ActionAtomistic respectively but for distances.
+      42             : 
+      43             : class ReferenceArguments :
+      44             :   virtual public ReferenceConfiguration
+      45             : {
+      46             :   friend class Direction;
+      47             :   friend class ReferenceConfiguration;
+      48             : private:
+      49             : /// The weights for normed euclidean distance
+      50             :   std::vector<double> weights, sqrtweight;
+      51             : /// The N X N matrix we are using to calculate our Malanobius distance
+      52             :   Matrix<double> metric;
+      53             :   std::vector<double> trig_metric;
+      54             : /// The values of the colvars in the reference configuration
+      55             :   std::vector<double> reference_args;
+      56             : /// The names of the arguments
+      57             :   std::vector<std::string> arg_names;
+      58             : /// The indices for setting derivatives
+      59             :   std::vector<unsigned> arg_der_index;
+      60             : protected:
+      61             : /// Are we reading weights from input
+      62             :   bool hasweights;
+      63             : /// Are we calculating a Malanobius distance
+      64             :   bool hasmetric;
+      65             : /// Read in the atoms from the pdb file
+      66             :   void readArgumentsFromPDB( const PDB& pdb );
+      67             : /// Set the values of the colvars based on their current instantanous values (used in Analysis)
+      68             :   void setReferenceArguments();
+      69             : public:
+      70             :   explicit ReferenceArguments( const ReferenceConfigurationOptions& ro );
+      71             : /// Get the number of reference arguments
+      72             :   unsigned getNumberOfReferenceArguments() const override;
+      73             : /// Get the arguments required
+      74             :   void getArgumentRequests( std::vector<std::string>&, bool disable_checks=false ) override;
+      75             : /// Set the positions of the reference arguments
+      76             :   void setReferenceArguments( const std::vector<double>& arg_vals, const std::vector<double>& sigma );
+      77             : /// Set the positions of the reference arguments
+      78             :   void moveReferenceArguments( const std::vector<double>& arg_vals );
+      79             : /// Get the value of the ith reference argument
+      80             :   double getReferenceArgument( const unsigned& i ) const override;
+      81             : /// Return all the reference arguments
+      82             :   const std::vector<double>& getReferenceArguments() const override;
+      83             :   const std::vector<double>& getReferenceMetric() override;
+      84             : /// Return names
+      85             :   const std::vector<std::string>& getArgumentNames() override;
+      86             : /// Calculate the euclidean/malanobius distance the atoms have moved from the reference
+      87             : /// configuration in CV space
+      88             :   virtual double calculateArgumentDistance( const std::vector<Value*> & vals, const std::vector<double>& arg, ReferenceValuePack& myder, const bool& squared ) const ;
+      89             : /// Displace the positions of the reference atoms
+      90             :   void displaceReferenceArguments( const double& weight, const std::vector<double>& displace );
+      91             : /// Extract the displacement from a position in a space
+      92             :   virtual void extractArgumentDisplacement( const std::vector<Value*>& vals, const std::vector<double>& arg, std::vector<double>& dirout ) const ;
+      93             : /// Project the displacement of the arguments on a vector
+      94             :   double projectArgDisplacementOnVector( const std::vector<double>& eigv, const std::vector<Value*>& vals, const std::vector<double>& arg, ReferenceValuePack& mypack ) const ;
+      95             : };
+      96             : 
+      97             : inline
+      98        1020 : double ReferenceArguments::getReferenceArgument( const unsigned& i ) const {
+      99             :   plumed_dbg_assert( i<reference_args.size() );
+     100        1040 :   return reference_args[i];
+     101             : }
+     102             : 
+     103             : inline
+     104      790964 : const std::vector<double>& ReferenceArguments::getReferenceArguments() const {
+     105      790964 :   return reference_args;
+     106             : }
+     107             : 
+     108             : inline
+     109         962 : const std::vector<std::string>& ReferenceArguments::getArgumentNames() {
+     110         962 :   return arg_names;
+     111             : }
+     112             : 
+     113             : inline
+     114       39585 : unsigned ReferenceArguments::getNumberOfReferenceArguments() const {
+     115       39585 :   return reference_args.size();
+     116             : }
+     117             : 
+     118             : }
+     119             : #endif
+     120             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.cpp.func-sort-c.html b/coverage/reference/ReferenceAtoms.cpp.func-sort-c.html new file mode 100644 index 000000000000..130b5e64ab2d --- /dev/null +++ b/coverage/reference/ReferenceAtoms.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceAtoms.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceAtoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303390.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ReferenceAtomsC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD14ReferenceAtoms15getAtomRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb455
_ZN4PLMD14ReferenceAtoms20singleDomainRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb455
_ZN4PLMD14ReferenceAtoms22displaceReferenceAtomsERKdRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EE494
_ZN4PLMD14ReferenceAtoms16readAtomsFromPDBERKNS_3PDBEb688
_ZN4PLMD14ReferenceAtomsC2ERKNS_29ReferenceConfigurationOptionsE724
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.cpp.func.html b/coverage/reference/ReferenceAtoms.cpp.func.html new file mode 100644 index 000000000000..8380e2ed5bb8 --- /dev/null +++ b/coverage/reference/ReferenceAtoms.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceAtoms.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceAtoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303390.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ReferenceAtoms15getAtomRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb455
_ZN4PLMD14ReferenceAtoms16readAtomsFromPDBERKNS_3PDBEb688
_ZN4PLMD14ReferenceAtoms20singleDomainRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb455
_ZN4PLMD14ReferenceAtoms22displaceReferenceAtomsERKdRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EE494
_ZN4PLMD14ReferenceAtomsC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD14ReferenceAtomsC2ERKNS_29ReferenceConfigurationOptionsE724
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.cpp.gcov.html b/coverage/reference/ReferenceAtoms.cpp.gcov.html new file mode 100644 index 000000000000..a796b2d0bcf3 --- /dev/null +++ b/coverage/reference/ReferenceAtoms.cpp.gcov.html @@ -0,0 +1,202 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceAtoms.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceAtoms.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303390.9 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ReferenceAtoms.h"
+      23             : #include "core/GenericMolInfo.h"
+      24             : #include "tools/OFile.h"
+      25             : #include "tools/PDB.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29         724 : ReferenceAtoms::ReferenceAtoms( const ReferenceConfigurationOptions& ro ):
+      30             :   ReferenceConfiguration(ro),
+      31         724 :   checks_were_disabled(false)
+      32             : {
+      33         724 : }
+      34             : 
+      35         688 : void ReferenceAtoms::readAtomsFromPDB( const PDB& pdb, const bool allowblocks  ) {
+      36         688 :   if( !allowblocks && pdb.getNumberOfAtomBlocks()!=1 ) error("found multi-atom-block pdb format but expecting only one block of atoms");
+      37             : 
+      38         688 :   indices.resize(0); reference_atoms.resize(0); align.resize(0); displace.resize(0); atom_der_index.resize(0);
+      39       10045 :   for(unsigned i=0; i<pdb.size(); ++i) {
+      40        9357 :     indices.push_back( pdb.getAtomNumbers()[i] ); reference_atoms.push_back( pdb.getPositions()[i] );
+      41        9357 :     align.push_back( pdb.getOccupancy()[i] ); displace.push_back( pdb.getBeta()[i] ); atom_der_index.push_back(i);
+      42             :   }
+      43         688 : }
+      44             : 
+      45             : // void ReferenceAtoms::setAtomNumbers( const std::vector<AtomNumber>& numbers ) {
+      46             : //   reference_atoms.resize( numbers.size() ); align.resize( numbers.size() );
+      47             : //   displace.resize( numbers.size() ); atom_der_index.resize( numbers.size() );
+      48             : //   indices.resize( numbers.size() );
+      49             : //   for(unsigned i=0; i<numbers.size(); ++i) {
+      50             : //     indices[i]=numbers[i]; atom_der_index[i]=i;
+      51             : //   }
+      52             : // }
+      53             : 
+      54             : // void ReferenceAtoms::printAtoms( OFile& ofile, const double& lunits ) const {
+      55             : //   plumed_assert( indices.size()==reference_atoms.size() && align.size()==reference_atoms.size() && displace.size()==reference_atoms.size() );
+      56             : //   for(unsigned i=0; i<reference_atoms.size(); ++i) {
+      57             : //     ofile.printf("ATOM  %5d  X   RES  %4u    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+      58             : //                  indices[i].serial(), i,
+      59             : //                  lunits*reference_atoms[i][0], lunits*reference_atoms[i][1], lunits*reference_atoms[i][2],
+      60             : //                  align[i], displace[i] );
+      61             : //   }
+      62             : // }
+      63             : 
+      64             : // bool ReferenceAtoms::parseAtomList( const std::string& key, std::vector<unsigned>& numbers ) {
+      65             : //   plumed_assert( numbers.size()==0 );
+      66             : //
+      67             : //   std::vector<std::string> strings;
+      68             : //   if( !parseVector(key,strings,true) ) return false;
+      69             : //   Tools::interpretRanges(strings);
+      70             : //
+      71             : //   numbers.resize( strings.size() );
+      72             : //   for(unsigned i=0; i<strings.size(); ++i) {
+      73             : //     AtomNumber atom;
+      74             : //     if( !Tools::convert(strings[i],atom ) ) error("could not convert " + strings[i] + " into atom number");
+      75             : //
+      76             : //     bool found=false;
+      77             : //     for(unsigned j=0; j<indices.size(); ++j) {
+      78             : //       if( atom==indices[j] ) { found=true; numbers[i]=j; break; }
+      79             : //     }
+      80             : //     if(!found) error("atom labelled " + strings[i] + " is not present in pdb input file");
+      81             : //   }
+      82             : //   return true;
+      83             : // }
+      84             : 
+      85         455 : void ReferenceAtoms::getAtomRequests( std::vector<AtomNumber>& numbers, bool disable_checks ) {
+      86         455 :   singleDomainRequests(numbers,disable_checks);
+      87         455 : }
+      88             : 
+      89         455 : void ReferenceAtoms::singleDomainRequests( std::vector<AtomNumber>& numbers, bool disable_checks ) {
+      90         455 :   checks_were_disabled=disable_checks;
+      91         455 :   atom_der_index.resize( indices.size() );
+      92             : 
+      93         455 :   if( numbers.size()==0 ) {
+      94        4220 :     for(unsigned i=0; i<indices.size(); ++i) {
+      95        4113 :       numbers.push_back( indices[i] );
+      96        4113 :       atom_der_index[i]=i;
+      97             :     }
+      98             :   } else {
+      99         348 :     if(!disable_checks) {
+     100         348 :       if( numbers.size()!=indices.size() ) error("mismatched numbers of atoms in pdb frames");
+     101             :     }
+     102             : 
+     103        4812 :     for(unsigned i=0; i<indices.size(); ++i) {
+     104             :       bool found=false;
+     105        4464 :       if(!disable_checks) {
+     106        4464 :         if( indices[i]!=numbers[i] ) error("found mismatched reference atoms in pdb frames");
+     107        4464 :         atom_der_index[i]=i;
+     108             :       } else {
+     109           0 :         for(unsigned j=0; j<numbers.size(); ++j) {
+     110           0 :           if( indices[i]==numbers[j] ) { found=true; atom_der_index[i]=j; break; }
+     111             :         }
+     112             :         if( !found ) {
+     113           0 :           atom_der_index[i]=numbers.size(); numbers.push_back( indices[i] );
+     114             :         }
+     115             :       }
+     116             :     }
+     117             :   }
+     118         455 : }
+     119             : 
+     120         494 : void ReferenceAtoms::displaceReferenceAtoms( const double& weight, const std::vector<Vector>& dir ) {
+     121             :   plumed_dbg_assert( dir.size()==reference_atoms.size() );
+     122         715 :   for(unsigned i=0; i<dir.size(); ++i) reference_atoms[i] += weight*dir.size()*dir[i];
+     123         494 : }
+     124             : 
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.h.func-sort-c.html b/coverage/reference/ReferenceAtoms.h.func-sort-c.html new file mode 100644 index 000000000000..26f0476da277 --- /dev/null +++ b/coverage/reference/ReferenceAtoms.h.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceAtoms.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceAtoms.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:111573.3 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD14ReferenceAtoms25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZNK4PLMD14ReferenceAtoms33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE0
_ZN4PLMD14ReferenceAtoms18getAbsoluteIndexesEv4
_ZNK4PLMD14ReferenceAtoms29getNumberOfReferencePositionsEv150276
_ZNK4PLMD14ReferenceAtoms21getReferencePositionsEv2636058
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.h.func.html b/coverage/reference/ReferenceAtoms.h.func.html new file mode 100644 index 000000000000..5355e2f35aa3 --- /dev/null +++ b/coverage/reference/ReferenceAtoms.h.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceAtoms.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceAtoms.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:111573.3 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD14ReferenceAtoms18getAbsoluteIndexesEv4
_ZNK4PLMD14ReferenceAtoms21getReferencePositionsEv2636058
_ZNK4PLMD14ReferenceAtoms25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZNK4PLMD14ReferenceAtoms29getNumberOfReferencePositionsEv150276
_ZNK4PLMD14ReferenceAtoms33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceAtoms.h.gcov.html b/coverage/reference/ReferenceAtoms.h.gcov.html new file mode 100644 index 000000000000..c9a9e3b44ce0 --- /dev/null +++ b/coverage/reference/ReferenceAtoms.h.gcov.html @@ -0,0 +1,240 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceAtoms.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceAtoms.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:111573.3 %
Date:2024-02-22 21:58:45Functions:3560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_reference_ReferenceAtoms_h
+      23             : #define __PLUMED_reference_ReferenceAtoms_h
+      24             : 
+      25             : #include "ReferenceConfiguration.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : class Pbc;
+      30             : 
+      31             : /// \ingroup TOOLBOX
+      32             : /// In many applications (e.g. paths, fields, property maps) it is necessary to calculate
+      33             : /// the distance between two configurations.  These distances can be calculated in a variety of
+      34             : /// different ways.  For instance, one can assert that the distance between the two configuration
+      35             : /// is the distance one would have to move all the atoms to transform configuration 1 into configuration
+      36             : /// 2. Alternatively, one could calculate the values of a large set of collective coordinates in the two
+      37             : /// configurations and then calculate the Euclidean distances between these two points in the resulting
+      38             : /// high-dimensional vector space.  Lastly, one can combine these two forms of distance calculation to calculate
+      39             : /// a hybrid distance.  Plumed allows one to use all these forms of distance calculations and also to implement
+      40             : /// new forms of distance.  You should inherit from this class if your distance involves reference atomic positions.
+      41             : /// This class and \ref PLMD::ReferenceArguments mirror the functionalities in and \ref PLMD::ActionAtomistic
+      42             : /// and \ref PLMD::ActionWithArguments respectively but for distances.
+      43             : 
+      44             : class ReferenceAtoms :
+      45             :   virtual public ReferenceConfiguration
+      46             : {
+      47             :   friend class Direction;
+      48             :   friend class SingleDomainRMSD;
+      49             :   friend class MultiDomainRMSD;
+      50             :   friend class ReferenceConfiguration;
+      51             : private:
+      52             : /// This flag tells us if the user has disabled checking of the input in order to
+      53             : /// do fancy paths with weird inputs
+      54             :   bool checks_were_disabled;
+      55             : /// The atoms to be used to align the instantaneous atomic positions
+      56             : /// to the reference configuration
+      57             :   std::vector<double> align;
+      58             : /// The atoms to be used to calculate the distance the atoms have moved
+      59             : /// from the reference configuration
+      60             :   std::vector<double> displace;
+      61             : /// The positions of the atoms in the reference configuration
+      62             :   std::vector<Vector> reference_atoms;
+      63             : /// The indices of the atoms in the pdb file
+      64             :   std::vector<AtomNumber> indices;
+      65             : /// The indeces for setting derivatives
+      66             :   std::vector<unsigned> atom_der_index;
+      67             : protected:
+      68             : /// Read in the atoms from the pdb file
+      69             :   void readAtomsFromPDB( const PDB&, const bool allowblocks=false );
+      70             : /// Add atom indices to list
+      71             :   void setAtomIndices( const std::vector<AtomNumber>& atomnumbers );
+      72             : /// Read a list of atoms from the pdb input file
+      73             :   bool parseAtomList( const std::string&, std::vector<unsigned>& );
+      74             : /// Get the position of the ith atom
+      75             :   Vector getReferencePosition( const unsigned& iatom ) const ;
+      76             : /// Add derivatives to iatom th atom in list
+      77             : //  void addAtomicDerivatives( const unsigned& , const Vector& );
+      78             : /// Get the atomic derivatives on the ith atom in the list
+      79             : //  Vector retrieveAtomicDerivatives( const unsigned& ) const ;
+      80             : /// Add derivatives to the viral
+      81             : //  void addBoxDerivatives( const Tensor& );
+      82             : /// This does the checks that are always required
+      83             :   void singleDomainRequests( std::vector<AtomNumber>&, bool disable_checks );
+      84             : public:
+      85             :   explicit ReferenceAtoms( const ReferenceConfigurationOptions& ro );
+      86             : /// This returns the number of reference atom positions
+      87             :   unsigned getNumberOfReferencePositions() const override;
+      88             : /// Get the reference positions
+      89             :   const std::vector<Vector> & getReferencePositions() const override;
+      90             : /// This allows us to use a single pos array with RMSD objects using different atom indexes
+      91             :   unsigned getAtomIndex( const unsigned& ) const ;
+      92             : /// Get the atoms required (additional checks are required when we have multiple domains)
+      93             :   void getAtomRequests( std::vector<AtomNumber>&, bool disable_checks=false ) override;
+      94             : /// Set the positions of the reference atoms
+      95             :   virtual void setReferenceAtoms( const std::vector<Vector>& conf, const std::vector<double>& align_in, const std::vector<double>& displace_in )=0;
+      96             : /// Return all atom indexes
+      97             :   const std::vector<AtomNumber>& getAbsoluteIndexes() override;
+      98             : /// This returns how many atoms there should be
+      99             :   unsigned getNumberOfAtoms() const ;
+     100             : /// Displace the positions of the reference atoms a bit
+     101             :   void displaceReferenceAtoms( const double& weight, const std::vector<Vector>& dir );
+     102             : /// Extract a displacement from a position in space
+     103           0 :   virtual void extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& direction ) const {
+     104           0 :     plumed_error();
+     105             :   }
+     106             : /// Project the displacement on a vector
+     107           0 :   virtual double projectAtomicDisplacementOnVector( const bool& normalized, const std::vector<Vector>& eigv, ReferenceValuePack& mypack ) const {
+     108           0 :     plumed_error();
+     109             :   }
+     110             : /// Get the vector of alignment weights
+     111             :   const std::vector<double> & getAlign() const ;
+     112             : /// Get the vector of displacement weights
+     113             :   const std::vector<double> & getDisplace() const ;
+     114             : };
+     115             : 
+     116             : inline
+     117             : const std::vector<double> & ReferenceAtoms::getAlign() const {
+     118      216774 :   return align;
+     119             : }
+     120             : 
+     121             : inline
+     122             : const std::vector<double> & ReferenceAtoms::getDisplace() const {
+     123      216775 :   return displace;
+     124             : }
+     125             : 
+     126             : inline
+     127      150276 : unsigned ReferenceAtoms::getNumberOfReferencePositions() const {
+     128             :   plumed_dbg_assert( atom_der_index.size()==reference_atoms.size() );
+     129      150276 :   return reference_atoms.size();
+     130             : }
+     131             : 
+     132             : inline
+     133             : unsigned ReferenceAtoms::getNumberOfAtoms() const {
+     134      314250 :   return atom_der_index.size(); // reference_atoms.size();
+     135             : }
+     136             : 
+     137             : inline
+     138             : unsigned ReferenceAtoms::getAtomIndex( const unsigned& iatom ) const {
+     139             :   plumed_dbg_assert( iatom<atom_der_index.size() );
+     140             :   plumed_dbg_assert( atom_der_index[iatom]<reference_atoms.size() );
+     141     9894406 :   return atom_der_index[iatom];
+     142             : }
+     143             : 
+     144             : inline
+     145             : Vector ReferenceAtoms::getReferencePosition( const unsigned& iatom ) const {
+     146             :   plumed_dbg_assert( iatom<reference_atoms.size() );
+     147       67480 :   return reference_atoms[iatom];
+     148             : }
+     149             : 
+     150             : inline
+     151     2636058 : const std::vector<Vector> & ReferenceAtoms::getReferencePositions() const {
+     152     2636058 :   return reference_atoms;
+     153             : }
+     154             : 
+     155             : inline
+     156           4 : const std::vector<AtomNumber>& ReferenceAtoms::getAbsoluteIndexes() {
+     157           4 :   return indices;
+     158             : }
+     159             : 
+     160             : 
+     161             : }
+     162             : #endif
+     163             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.cpp.func-sort-c.html b/coverage/reference/ReferenceConfiguration.cpp.func-sort-c.html new file mode 100644 index 000000000000..80222b0a011e --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceConfiguration.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceConfiguration.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-02-22 21:58:45Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD22ReferenceConfiguration5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD22ReferenceConfigurationD0Ev0
_ZNK4PLMD29ReferenceConfigurationOptions16getMultiRMSDTypeB5cxx11Ev5
_ZNK4PLMD22ReferenceConfiguration7getNameB5cxx11Ev284
_ZNK4PLMD29ReferenceConfigurationOptions15usingFastOptionEv437
_ZN4PLMD22ReferenceConfiguration30displaceReferenceConfigurationERKdRNS_9DirectionE500
_ZNK4PLMD22ReferenceConfiguration25extractDisplacementVectorERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IPNS_5ValueESaIS9_EERKS1_IdSaIdEERKbRNS_9DirectionE3081
_ZNK4PLMD22ReferenceConfiguration27projectDisplacementOnVectorERKNS_9DirectionERKSt6vectorIPNS_5ValueESaIS6_EERKS4_IdSaIdEERNS_18ReferenceValuePackE3588
_ZNK4PLMD22ReferenceConfiguration9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERNS_18ReferenceValuePackERKb175359
_ZN4PLMD8distanceERKNS_3PbcERKSt6vectorIPNS_5ValueESaIS5_EEPNS_22ReferenceConfigurationESB_RKb259099
_ZN4PLMD22ReferenceConfigurationC2ERKNS_29ReferenceConfigurationOptionsE519088
_ZN4PLMD29ReferenceConfigurationOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE519088
_ZN4PLMD22ReferenceConfigurationD2Ev519569
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.cpp.func.html b/coverage/reference/ReferenceConfiguration.cpp.func.html new file mode 100644 index 000000000000..80f020d7180f --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceConfiguration.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceConfiguration.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-02-22 21:58:45Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD22ReferenceConfiguration30displaceReferenceConfigurationERKdRNS_9DirectionE500
_ZN4PLMD22ReferenceConfiguration5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD22ReferenceConfigurationC2ERKNS_29ReferenceConfigurationOptionsE519088
_ZN4PLMD22ReferenceConfigurationD0Ev0
_ZN4PLMD22ReferenceConfigurationD2Ev519569
_ZN4PLMD29ReferenceConfigurationOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE519088
_ZN4PLMD8distanceERKNS_3PbcERKSt6vectorIPNS_5ValueESaIS5_EEPNS_22ReferenceConfigurationESB_RKb259099
_ZNK4PLMD22ReferenceConfiguration25extractDisplacementVectorERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IPNS_5ValueESaIS9_EERKS1_IdSaIdEERKbRNS_9DirectionE3081
_ZNK4PLMD22ReferenceConfiguration27projectDisplacementOnVectorERKNS_9DirectionERKSt6vectorIPNS_5ValueESaIS6_EERKS4_IdSaIdEERNS_18ReferenceValuePackE3588
_ZNK4PLMD22ReferenceConfiguration7getNameB5cxx11Ev284
_ZNK4PLMD22ReferenceConfiguration9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERNS_18ReferenceValuePackERKb175359
_ZNK4PLMD29ReferenceConfigurationOptions15usingFastOptionEv437
_ZNK4PLMD29ReferenceConfigurationOptions16getMultiRMSDTypeB5cxx11Ev5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.cpp.gcov.html b/coverage/reference/ReferenceConfiguration.cpp.gcov.html new file mode 100644 index 000000000000..a065dd462bde --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.cpp.gcov.html @@ -0,0 +1,208 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceConfiguration.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceConfiguration.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-02-22 21:58:45Functions:111384.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ReferenceConfiguration.h"
+      23             : #include "ReferenceArguments.h"
+      24             : #include "ReferenceAtoms.h"
+      25             : #include "Direction.h"
+      26             : #include "core/Value.h"
+      27             : #include "tools/OFile.h"
+      28             : #include "tools/PDB.h"
+      29             : #include "core/GenericMolInfo.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33      519088 : ReferenceConfigurationOptions::ReferenceConfigurationOptions( const std::string& type ):
+      34      519088 :   tt(type)
+      35             : {
+      36      519088 : }
+      37             : 
+      38         437 : bool ReferenceConfigurationOptions::usingFastOption() const {
+      39         437 :   return (tt.find("-FAST")!=std::string::npos);
+      40             : }
+      41             : 
+      42           5 : std::string ReferenceConfigurationOptions::getMultiRMSDType() const {
+      43           5 :   plumed_assert( tt.find("MULTI-")!=std::string::npos );
+      44           5 :   std::size_t dot=tt.find_first_of("MULTI-");
+      45           5 :   return tt.substr(dot+6);
+      46             : }
+      47             : 
+      48      519088 : ReferenceConfiguration::ReferenceConfiguration( const ReferenceConfigurationOptions& ro ):
+      49      519088 :   name(ro.tt)
+      50             : {
+      51      519088 : }
+      52             : 
+      53      519569 : ReferenceConfiguration::~ReferenceConfiguration()
+      54             : {
+      55     1039138 : }
+      56             : 
+      57         284 : std::string ReferenceConfiguration::getName() const {
+      58         284 :   return name;
+      59             : }
+      60             : 
+      61           0 : [[noreturn]] void ReferenceConfiguration::error(const std::string& msg) {
+      62           0 :   plumed_merror("error reading reference configuration of type " + name + " : " + msg );
+      63             : }
+      64             : 
+      65      175359 : double ReferenceConfiguration::calculate( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals,
+      66             :     ReferenceValuePack& myder, const bool& squared ) const {
+      67      175359 :   std::vector<double> tmparg( vals.size() );
+      68      248599 :   for(unsigned i=0; i<vals.size(); ++i) tmparg[i]=vals[i]->get();
+      69      350718 :   return calc( pos, pbc, vals, tmparg, myder, squared );
+      70             : }
+      71             : 
+      72         500 : void ReferenceConfiguration::displaceReferenceConfiguration( const double& weight, Direction& dir ) {
+      73         500 :   ReferenceArguments* args=dynamic_cast<ReferenceArguments*>(this);
+      74         500 :   if( args ) args->displaceReferenceArguments( weight, dir.getReferenceArguments() );
+      75         500 :   ReferenceAtoms* atoms=dynamic_cast<ReferenceAtoms*>(this);
+      76         500 :   if( atoms ) atoms->displaceReferenceAtoms( weight, dir.getReferencePositions() );
+      77         500 : }
+      78             : 
+      79        3081 : void ReferenceConfiguration::extractDisplacementVector( const std::vector<Vector>& pos, const std::vector<Value*>& vals,
+      80             :     const std::vector<double>& arg, const bool& nflag,
+      81             :     Direction& mydir ) const {
+      82        3081 :   const ReferenceAtoms* atoms=dynamic_cast<const ReferenceAtoms*>( this );
+      83        3081 :   if( atoms ) atoms->extractAtomicDisplacement( pos, mydir.reference_atoms );
+      84        3081 :   const ReferenceArguments* args=dynamic_cast<const ReferenceArguments*>( this );
+      85        3081 :   if( args ) args->extractArgumentDisplacement( vals, arg, mydir.reference_args );
+      86             : 
+      87             :   // Normalize direction if required
+      88        3081 :   if( nflag ) {
+      89             :     // Calculate length of vector
+      90          10 :     double tmp, norm=0; mydir.normalized = true;
+      91          80 :     for(unsigned i=0; i<mydir.getReferencePositions().size(); ++i) {
+      92         280 :       for(unsigned k=0; k<3; ++k) { tmp=mydir.getReferencePositions()[i][k]; norm+=tmp*tmp; }
+      93             :     }
+      94          10 :     for(unsigned i=0; i<mydir.getReferenceArguments().size(); ++i) { tmp=mydir.getReferenceArguments()[i]; norm+=tmp*tmp; }
+      95          10 :     norm = std::sqrt( norm );
+      96             :     // And normalize
+      97          80 :     for(unsigned i=0; i<mydir.getReferencePositions().size(); ++i) {
+      98         280 :       for(unsigned k=0; k<3; ++k) { mydir.reference_atoms[i][k] /=norm; }
+      99             :     }
+     100          10 :     for(unsigned i=0; i<mydir.getReferenceArguments().size(); ++i) { mydir.reference_args[i] /= norm; }
+     101             :   }
+     102        3081 : }
+     103             : 
+     104        3588 : double ReferenceConfiguration::projectDisplacementOnVector( const Direction& mydir,
+     105             :     const std::vector<Value*>& vals, const std::vector<double>& arg,
+     106             :     ReferenceValuePack& mypack ) const {
+     107             :   double proj=0;
+     108        3588 :   const ReferenceAtoms* atoms=dynamic_cast<const ReferenceAtoms*>( this );
+     109        3588 :   if( atoms ) proj += atoms->projectAtomicDisplacementOnVector( mydir.normalized, mydir.getReferencePositions(), mypack );
+     110        3588 :   const ReferenceArguments* args=dynamic_cast<const ReferenceArguments*>( this );
+     111        3588 :   if( args ) proj += args->projectArgDisplacementOnVector( mydir.getReferenceArguments(), vals, arg, mypack );
+     112        3588 :   return proj;
+     113             : }
+     114             : 
+     115      259099 : double distance( const Pbc& pbc, const std::vector<Value*> & vals, ReferenceConfiguration* ref1, ReferenceConfiguration* ref2, const bool& squared ) {
+     116             :   unsigned nder;
+     117      259099 :   if( ref1->getReferencePositions().size()>0 ) nder=ref1->getReferenceArguments().size() + 3*ref1->getReferencePositions().size() + 9;
+     118      259092 :   else nder=ref1->getReferenceArguments().size();
+     119             : 
+     120      259099 :   MultiValue myvals( 1, nder ); ReferenceValuePack myder( ref1->getReferenceArguments().size(), ref1->getReferencePositions().size(), myvals );
+     121      259099 :   double dist1=ref1->calc( ref2->getReferencePositions(), pbc, vals, ref2->getReferenceArguments(), myder, squared );
+     122             : #ifndef NDEBUG
+     123             :   // Check that A - B = B - A
+     124             :   double dist2=ref2->calc( ref1->getReferencePositions(), pbc, vals, ref1->getReferenceArguments(), myder, squared );
+     125             :   plumed_dbg_assert( std::fabs(dist1-dist2)<epsilon );
+     126             : #endif
+     127      259099 :   return dist1;
+     128      259099 : }
+     129             : 
+     130             : 
+     131             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.h.func-sort-c.html b/coverage/reference/ReferenceConfiguration.h.func-sort-c.html new file mode 100644 index 000000000000..b59c5842127d --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.h.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceConfiguration.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceConfiguration.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:152075.0 %
Date:2024-02-22 21:58:45Functions:81266.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD22ReferenceConfiguration15setupPCAStorageERNS_18ReferenceValuePackE0
_ZN4PLMD22ReferenceConfiguration18getReferenceMetricEv0
_ZN4PLMD22ReferenceConfiguration28pcaIsEnabledForThisReferenceEv0
_ZNK4PLMD22ReferenceConfiguration20getReferenceArgumentERKj0
_ZN4PLMD22ReferenceConfiguration16getArgumentNamesB5cxx11Ev2
_ZN4PLMD22ReferenceConfiguration18getAbsoluteIndexesEv8
_ZN4PLMD22ReferenceConfiguration15getAtomRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb177
_ZN4PLMD22ReferenceConfiguration19getArgumentRequestsERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEb354
_ZNK4PLMD22ReferenceConfiguration21getReferenceArgumentsEv2281
_ZNK4PLMD22ReferenceConfiguration29getNumberOfReferencePositionsEv35978
_ZNK4PLMD22ReferenceConfiguration29getNumberOfReferenceArgumentsEv138192
_ZNK4PLMD22ReferenceConfiguration21getReferencePositionsEv781533
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.h.func.html b/coverage/reference/ReferenceConfiguration.h.func.html new file mode 100644 index 000000000000..009ec31c7fac --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.h.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceConfiguration.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceConfiguration.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:152075.0 %
Date:2024-02-22 21:58:45Functions:81266.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD22ReferenceConfiguration15getAtomRequestsERSt6vectorINS_10AtomNumberESaIS2_EEb177
_ZN4PLMD22ReferenceConfiguration15setupPCAStorageERNS_18ReferenceValuePackE0
_ZN4PLMD22ReferenceConfiguration16getArgumentNamesB5cxx11Ev2
_ZN4PLMD22ReferenceConfiguration18getAbsoluteIndexesEv8
_ZN4PLMD22ReferenceConfiguration18getReferenceMetricEv0
_ZN4PLMD22ReferenceConfiguration19getArgumentRequestsERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEb354
_ZN4PLMD22ReferenceConfiguration28pcaIsEnabledForThisReferenceEv0
_ZNK4PLMD22ReferenceConfiguration20getReferenceArgumentERKj0
_ZNK4PLMD22ReferenceConfiguration21getReferenceArgumentsEv2281
_ZNK4PLMD22ReferenceConfiguration21getReferencePositionsEv781533
_ZNK4PLMD22ReferenceConfiguration29getNumberOfReferenceArgumentsEv138192
_ZNK4PLMD22ReferenceConfiguration29getNumberOfReferencePositionsEv35978
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceConfiguration.h.gcov.html b/coverage/reference/ReferenceConfiguration.h.gcov.html new file mode 100644 index 000000000000..b648e25890f9 --- /dev/null +++ b/coverage/reference/ReferenceConfiguration.h.gcov.html @@ -0,0 +1,250 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceConfiguration.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceConfiguration.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:152075.0 %
Date:2024-02-22 21:58:45Functions:81266.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_reference_ReferenceConfiguration_h
+      23             : #define __PLUMED_reference_ReferenceConfiguration_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <string>
+      27             : #include "tools/Vector.h"
+      28             : #include "tools/Tensor.h"
+      29             : #include "tools/Tools.h"
+      30             : #include "tools/Exception.h"
+      31             : #include "ReferenceValuePack.h"
+      32             : #include "tools/Matrix.h"
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : class Value;
+      37             : class Pbc;
+      38             : class OFile;
+      39             : class PDB;
+      40             : class GenericMolInfo;
+      41             : 
+      42             : /// \ingroup TOOLBOX
+      43             : /// Abstract base class for calculating the distance from a reference configuration.
+      44             : /// A reference configuration can either have a particular set of atoms in a particular
+      45             : /// given configuration or it can be that a particular set of colvars have a particular
+      46             : /// set of values.  It could also be a combination of both.  To allow all the posible
+      47             : /// permutations and in order make it easy to add new ways of calculating the distance
+      48             : /// we have implemented this using polymorphism and multiple inheritance.
+      49             : 
+      50             : class Direction;
+      51             : 
+      52      519088 : class ReferenceConfigurationOptions {
+      53             :   friend class ReferenceConfiguration;
+      54             : private:
+      55             :   std::string tt;
+      56             : public:
+      57             :   explicit ReferenceConfigurationOptions( const std::string& type );
+      58             :   bool usingFastOption() const ;
+      59             :   std::string getMultiRMSDType() const ;
+      60             : };
+      61             : 
+      62             : /// \ingroup INHERIT
+      63             : /// Abstract base class for calculating the distance from a reference configuration.
+      64             : /// A reference configuration can either have a particular set of atoms in a particular
+      65             : /// given configuration or it can be that a particular set of colvars have a particular
+      66             : /// set of values.  It could also be a combination of both.  To allow all the posible
+      67             : /// permutations and in order make it easy to add new ways of calculating the distance
+      68             : /// we have implemented this using polymorphism and multiple inheritance.  The following
+      69             : /// provides \ref AddingAMetric "information" on how to implement a new method for
+      70             : /// calculating the distance between a pair of configurations
+      71             : 
+      72             : class ReferenceConfiguration {
+      73             :   friend class SingleDomainRMSD;
+      74             :   friend double distance( const Pbc& pbc, const std::vector<Value*> & vals, ReferenceConfiguration*, ReferenceConfiguration*, const bool& squared );
+      75             : private:
+      76             : /// The name of this particular config
+      77             :   std::string name;
+      78             : /// A vector containing all the remarks from the pdb input
+      79             :   std::vector<std::string> line;
+      80             : /// These are used to do fake things when we copy frames
+      81             :   std::vector<AtomNumber> fake_atom_numbers;
+      82             :   std::vector<std::string> fake_arg_names;
+      83             : /// These are use by the distance function above
+      84             :   std::vector<Vector> fake_refatoms;
+      85             :   std::vector<double> fake_refargs;
+      86             :   std::vector<double> fake_metric;
+      87             : protected:
+      88             : /// Crash with an error
+      89             :   [[noreturn]] void error(const std::string& msg);
+      90             : public:
+      91             :   explicit ReferenceConfiguration( const ReferenceConfigurationOptions& ro );
+      92             : /// Destructor
+      93             :   virtual ~ReferenceConfiguration();
+      94             : /// Return the name of this metric
+      95             :   std::string getName() const ;
+      96             : ///
+      97             :   virtual unsigned getNumberOfReferencePositions() const ;
+      98             :   virtual unsigned getNumberOfReferenceArguments() const ;
+      99             : /// Retrieve the atoms that are required for this guy
+     100         177 :   virtual void getAtomRequests( std::vector<AtomNumber>&, bool disable_checks=false ) {}
+     101             : /// Retrieve the arguments that are required for this guy
+     102         354 :   virtual void getArgumentRequests( std::vector<std::string>&, bool disable_checks=false ) {}
+     103             : /// Do all local business for setting the configuration
+     104             :   virtual void read( const PDB& )=0;
+     105             : /// Calculate the distance from the reference configuration
+     106             :   double calculate( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, ReferenceValuePack& myder, const bool& squared=false ) const ;
+     107             : /// Calculate the distance from the reference configuration
+     108             :   virtual double calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& args,
+     109             :                        ReferenceValuePack& myder, const bool& squared ) const=0;
+     110             : /// Parse something from the pdb remarks
+     111             : /// Copy derivatives from one frame to this frame
+     112             :   void copyDerivatives( const ReferenceConfiguration* );
+     113             : /// Get one of the referene arguments
+     114           0 :   virtual double getReferenceArgument( const unsigned& i ) const { plumed_error(); }
+     115             : /// These are overwritten in ReferenceArguments and ReferenceAtoms but are required here
+     116             : /// to make PLMD::distance work
+     117             :   virtual const std::vector<Vector>& getReferencePositions() const ;
+     118             :   virtual const std::vector<double>& getReferenceArguments() const ;
+     119             :   virtual const std::vector<double>& getReferenceMetric();
+     120             : /// These are overwritten in ReferenceArguments and ReferenceAtoms to make frame copying work
+     121             :   virtual const std::vector<AtomNumber>& getAbsoluteIndexes();
+     122             :   virtual const std::vector<std::string>& getArgumentNames();
+     123             : /// Extract a Direction giving you the displacement from some position
+     124             :   void extractDisplacementVector( const std::vector<Vector>& pos, const std::vector<Value*>& vals,
+     125             :                                   const std::vector<double>& arg, const bool& nflag,
+     126             :                                   Direction& mydir ) const ;
+     127             : /// Stuff for pca
+     128           0 :   virtual bool pcaIsEnabledForThisReference() { return false; }
+     129             :   double projectDisplacementOnVector( const Direction& mydir, const std::vector<Value*>& vals,
+     130             :                                       const std::vector<double>& arg, ReferenceValuePack& mypack ) const ;
+     131             : /// Stuff to setup pca
+     132           0 :   virtual void setupPCAStorage( ReferenceValuePack& mypack ) { plumed_error(); }
+     133             : /// Move the reference configuration by an amount specified using a Direction
+     134             :   void displaceReferenceConfiguration( const double& weight, Direction& dir );
+     135             : };
+     136             : 
+     137             : inline
+     138      781533 : const std::vector<Vector>& ReferenceConfiguration::getReferencePositions() const {
+     139      781533 :   return fake_refatoms;
+     140             : }
+     141             : 
+     142             : inline
+     143        2281 : const std::vector<double>& ReferenceConfiguration::getReferenceArguments() const {
+     144        2281 :   return fake_refargs;
+     145             : }
+     146             : 
+     147             : inline
+     148           0 : const std::vector<double>& ReferenceConfiguration::getReferenceMetric() {
+     149           0 :   return fake_metric;
+     150             : }
+     151             : 
+     152             : inline
+     153           8 : const std::vector<AtomNumber>& ReferenceConfiguration::getAbsoluteIndexes() {
+     154           8 :   return fake_atom_numbers;
+     155             : }
+     156             : 
+     157             : inline
+     158           2 : const std::vector<std::string>& ReferenceConfiguration::getArgumentNames() {
+     159           2 :   return fake_arg_names;
+     160             : }
+     161             : 
+     162             : inline
+     163       35978 : unsigned ReferenceConfiguration::getNumberOfReferencePositions() const {
+     164       35978 :   return 0;
+     165             : }
+     166             : 
+     167             : inline
+     168      138192 : unsigned ReferenceConfiguration::getNumberOfReferenceArguments() const {
+     169      138192 :   return 0;
+     170             : }
+     171             : 
+     172             : }
+     173             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.cpp.func-sort-c.html b/coverage/reference/ReferenceValuePack.cpp.func-sort-c.html new file mode 100644 index 000000000000..4a3e722325ae --- /dev/null +++ b/coverage/reference/ReferenceValuePack.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceValuePack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceValuePack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceValuePack6resizeERKjS2_104
_ZN4PLMD18ReferenceValuePack21copyScaledDerivativesERKjRKdRKNS_10MultiValueE162
_ZN4PLMD18ReferenceValuePack15moveDerivativesERKjS2_8662
_ZN4PLMD18ReferenceValuePack19scaleAllDerivativesERKd192765
_ZN4PLMD18ReferenceValuePack5clearEv241460
_ZN4PLMD18ReferenceValuePack18updateDynamicListsEv452950
_ZN4PLMD18ReferenceValuePackC2ERKjS2_RNS_10MultiValueE471334
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.cpp.func.html b/coverage/reference/ReferenceValuePack.cpp.func.html new file mode 100644 index 000000000000..f7006617cd96 --- /dev/null +++ b/coverage/reference/ReferenceValuePack.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceValuePack.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceValuePack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceValuePack15moveDerivativesERKjS2_8662
_ZN4PLMD18ReferenceValuePack18updateDynamicListsEv452950
_ZN4PLMD18ReferenceValuePack19scaleAllDerivativesERKd192765
_ZN4PLMD18ReferenceValuePack21copyScaledDerivativesERKjRKdRKNS_10MultiValueE162
_ZN4PLMD18ReferenceValuePack5clearEv241460
_ZN4PLMD18ReferenceValuePack6resizeERKjS2_104
_ZN4PLMD18ReferenceValuePackC2ERKjS2_RNS_10MultiValueE471334
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.cpp.gcov.html b/coverage/reference/ReferenceValuePack.cpp.gcov.html new file mode 100644 index 000000000000..0aec3ba2ece9 --- /dev/null +++ b/coverage/reference/ReferenceValuePack.cpp.gcov.html @@ -0,0 +1,172 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceValuePack.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceValuePack.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ReferenceValuePack.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : 
+      26      471334 : ReferenceValuePack::ReferenceValuePack( const unsigned& nargs, const unsigned& natoms, MultiValue& vals ):
+      27      471334 :   boxWasSet(false),
+      28      471334 :   numberOfArgs(nargs),
+      29      471334 :   oind_set(false),
+      30      471334 :   myvals(vals),
+      31      471334 :   atom_indices(myvals.getIndices()),
+      32      471334 :   pca(false)
+      33             : {
+      34      471334 :   if( atom_indices.size()!=natoms ) { atom_indices.resize( natoms ); myvals.getAtomVector().resize( natoms ); }
+      35      471334 :   if( vals.getNumberOfValues()==1 ) { oind=0; oind_set=true; }
+      36      471334 : }
+      37             : 
+      38         104 : void ReferenceValuePack::resize( const unsigned& nargs, const unsigned& natoms ) {
+      39         104 :   numberOfArgs=nargs; atom_indices.resize( natoms );
+      40         104 :   myvals.getAtomVector().resize( natoms );
+      41         104 : }
+      42             : 
+      43      452950 : void ReferenceValuePack::updateDynamicLists() {
+      44      452950 :   myvals.emptyActiveMembers();
+      45      522510 :   for(unsigned i=0; i<numberOfArgs; ++i) myvals.putIndexInActiveArray( i );
+      46    21590009 :   for(unsigned i=0; i<atom_indices.size(); ++i) {
+      47    21137059 :     unsigned nbase = numberOfArgs + 3*atom_indices[i];
+      48    21137059 :     if( atom_indices[i]<myvals.getNumberOfDerivatives() && myvals.isActive( nbase ) ) {
+      49    18164986 :       myvals.putIndexInActiveArray( nbase+0 ); myvals.putIndexInActiveArray( nbase+1 ); myvals.putIndexInActiveArray( nbase+2 );
+      50             :     }
+      51             :   }
+      52      452950 :   unsigned nbase = myvals.getNumberOfDerivatives() - 9;
+      53             :   // zero is added to all virial components to ensure that these are active in the dynamic list
+      54             :   // if this is not done there is a problem with secondary structure variables
+      55      452950 :   if( atom_indices.size()>0 ) {
+      56     4181700 :     for(unsigned i=0; i<9; ++i) {
+      57     3763530 :       myvals.addDerivative( oind, nbase+i, 0.0 );
+      58     3763530 :       myvals.putIndexInActiveArray( nbase+i );
+      59             :     }
+      60             :   }
+      61      452950 :   myvals.completeUpdate();
+      62      452950 : }
+      63             : 
+      64      241460 : void ReferenceValuePack::clear() {
+      65      241460 :   if( !myvals.updateComplete() ) updateDynamicLists();
+      66      241460 :   myvals.clearAll(); boxWasSet=false;
+      67      241460 : }
+      68             : 
+      69      192765 : void ReferenceValuePack::scaleAllDerivatives( const double& scalef ) {
+      70      192765 :   if( !myvals.updateComplete() ) updateDynamicLists();
+      71             : 
+      72     8856593 :   for(unsigned i=0; i<myvals.getNumberActive(); ++i) {
+      73     8663828 :     unsigned ider=myvals.getActiveIndex(i);
+      74     8663828 :     myvals.setDerivative( oind, ider, scalef*myvals.getDerivative( oind, ider ) );
+      75             :   }
+      76      192765 : }
+      77             : 
+      78         162 : void ReferenceValuePack::copyScaledDerivatives( const unsigned& from, const double& scalef, const MultiValue& tvals ) {
+      79             :   plumed_dbg_assert( tvals.getNumberOfDerivatives()==myvals.getNumberOfDerivatives() );
+      80        3681 :   for(unsigned i=0; i<tvals.getNumberActive(); ++i) {
+      81        3519 :     unsigned ider=tvals.getActiveIndex(i);
+      82        3519 :     myvals.addDerivative( oind, ider, scalef*tvals.getDerivative( from, ider ) );
+      83             :   }
+      84         162 : }
+      85             : 
+      86        8662 : void ReferenceValuePack::moveDerivatives( const unsigned& from, const unsigned& to ) {
+      87        8662 :   if( !myvals.updateComplete() ) updateDynamicLists();
+      88             : 
+      89      866200 :   for(unsigned i=0; i<myvals.getNumberActive(); ++i) {
+      90      857538 :     unsigned ider=myvals.getActiveIndex(i);
+      91      857538 :     myvals.setDerivative( to, ider, myvals.getDerivative( from, ider ) );
+      92             :   }
+      93        8662 : }
+      94             : 
+      95             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.h.func-sort-c.html b/coverage/reference/ReferenceValuePack.h.func-sort-c.html new file mode 100644 index 000000000000..b3b29324ef17 --- /dev/null +++ b/coverage/reference/ReferenceValuePack.h.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceValuePack.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceValuePack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD18ReferenceValuePack17getBoxDerivativesEv600
_ZN4PLMD18ReferenceValuePack17addBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE8268786
_ZN4PLMD18ReferenceValuePack18addAtomDerivativesERKjRKNS_13VectorGenericILj3EEE16356460
_ZNK4PLMD18ReferenceValuePack17getAtomDerivativeERKj17175932
_ZN4PLMD18ReferenceValuePack18setAtomDerivativesERKjRKNS_13VectorGenericILj3EEE17547915
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.h.func.html b/coverage/reference/ReferenceValuePack.h.func.html new file mode 100644 index 000000000000..741189a28752 --- /dev/null +++ b/coverage/reference/ReferenceValuePack.h.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceValuePack.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceValuePack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18ReferenceValuePack17addBoxDerivativesERKNS_13TensorGenericILj3ELj3EEE8268786
_ZN4PLMD18ReferenceValuePack18addAtomDerivativesERKjRKNS_13VectorGenericILj3EEE16356460
_ZN4PLMD18ReferenceValuePack18setAtomDerivativesERKjRKNS_13VectorGenericILj3EEE17547915
_ZNK4PLMD18ReferenceValuePack17getAtomDerivativeERKj17175932
_ZNK4PLMD18ReferenceValuePack17getBoxDerivativesEv600
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/ReferenceValuePack.h.gcov.html b/coverage/reference/ReferenceValuePack.h.gcov.html new file mode 100644 index 000000000000..292a2a847ab9 --- /dev/null +++ b/coverage/reference/ReferenceValuePack.h.gcov.html @@ -0,0 +1,305 @@ + + + + + + + + LCOV - plumed test coverage - reference/ReferenceValuePack.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - ReferenceValuePack.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_reference_ReferenceValuePack_h
+      23             : #define __PLUMED_reference_ReferenceValuePack_h
+      24             : 
+      25             : #include "tools/MultiValue.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : class ReferenceValuePack {
+      30             :   friend class MultiDomainRMSD;
+      31             :   friend class OptimalRMSD;
+      32             : private:
+      33             : /// Was the virial set
+      34             :   bool boxWasSet;
+      35             : ///
+      36             :   unsigned numberOfArgs;
+      37             : ///
+      38             :   bool oind_set;
+      39             :   unsigned oind;
+      40             : /// Copy of the values that we are adding to
+      41             :   MultiValue& myvals;
+      42             : /// Ths list of atom indices
+      43             :   std::vector<unsigned>& atom_indices;
+      44             : /// Are we using pca
+      45             :   bool pca;
+      46             : /// A vector of vectors to save us some overhead for vector resizes
+      47             :   std::vector<Vector> centeredpos;
+      48             : ///
+      49             :   std::vector<Vector> displacement;
+      50             : ///
+      51             :   std::vector<Tensor> rot;
+      52             : ///
+      53             :   Matrix< std::vector<Vector> >  DRotDPos;
+      54             : public:
+      55             :   ReferenceValuePack( const unsigned& nargs, const unsigned& natoms, MultiValue& vals );
+      56             : ///
+      57             :   void resize( const unsigned& nargs, const unsigned& natoms );
+      58             : ///
+      59             :   void clear();
+      60             : ///
+      61             :   unsigned getNumberOfDerivatives() const ;
+      62             : ///
+      63             :   unsigned getNumberOfArguments() const ;
+      64             : ///
+      65             :   unsigned getNumberOfAtoms() const ;
+      66             : ///
+      67             :   void setAtomIndex( const unsigned& iatom, const unsigned& jindex );
+      68             : ///
+      69             :   unsigned getAtomIndex( const unsigned& iatom ) const ;
+      70             : ///
+      71             :   void copyScaledDerivatives( const unsigned& from, const double& scalef, const MultiValue& tvals );
+      72             : ///
+      73             :   void addArgumentDerivatives( const unsigned& iarg, const double& der );
+      74             : ///
+      75             :   void setArgumentDerivatives( const unsigned& iarg, const double& der );
+      76             : ///
+      77             :   void setAtomDerivatives( const unsigned& jder, const Vector& der );
+      78             : ///
+      79             :   void addAtomDerivatives( const unsigned& iatom, const Vector& der );
+      80             : ///
+      81             :   void addBoxDerivatives( const Tensor& vir );
+      82             : ///
+      83             :   bool updateComplete() const ;
+      84             : ///
+      85             :   void updateDynamicLists();
+      86             : ///
+      87             :   void scaleAllDerivatives( const double& scalef );
+      88             : ///
+      89             :   void setValIndex( const unsigned& ind );
+      90             : ///
+      91             :   void moveDerivatives( const unsigned& from, const unsigned& to );
+      92             : ///
+      93             :   bool virialWasSet() const ;
+      94             : ///
+      95             :   Vector getAtomDerivative( const unsigned& iatom ) const ;
+      96             : ///
+      97             :   double getArgumentDerivative( const unsigned& ival ) const ;
+      98             : ///
+      99             :   Tensor getBoxDerivatives() const ;
+     100             : ///
+     101             :   bool calcUsingPCAOption() const ;
+     102             : ///
+     103             :   void switchOnPCAOption();
+     104             : ///
+     105             :   std::vector<Vector>& getAtomVector();
+     106             : ///
+     107             :   std::vector<Vector>& getAtomsDisplacementVector();
+     108             : };
+     109             : 
+     110             : inline
+     111             : unsigned ReferenceValuePack::getNumberOfDerivatives() const {
+     112          44 :   return myvals.getNumberOfDerivatives();
+     113             : }
+     114             : 
+     115             : inline
+     116             : unsigned ReferenceValuePack::getNumberOfArguments() const {
+     117      172372 :   return numberOfArgs;
+     118             : }
+     119             : 
+     120             : inline
+     121             : unsigned ReferenceValuePack::getNumberOfAtoms() const {
+     122     2098660 :   return atom_indices.size();
+     123             : }
+     124             : 
+     125             : inline
+     126             : void ReferenceValuePack::setAtomIndex( const unsigned& iatom, const unsigned& jindex ) {
+     127     2967600 :   plumed_dbg_assert( iatom<atom_indices.size() ); atom_indices[iatom]=jindex;
+     128             : }
+     129             : 
+     130             : inline
+     131             : unsigned ReferenceValuePack::getAtomIndex( const unsigned& iatom ) const {
+     132             :   plumed_dbg_assert( iatom<atom_indices.size() );
+     133     1788696 :   return atom_indices[iatom];
+     134             : }
+     135             : 
+     136             : inline
+     137             : void ReferenceValuePack::addArgumentDerivatives( const unsigned& iarg, const double& der ) {
+     138             :   plumed_dbg_assert( iarg<numberOfArgs && oind_set ); myvals.addDerivative( oind, iarg, der );
+     139             : }
+     140             : 
+     141             : inline
+     142             : void ReferenceValuePack::setArgumentDerivatives( const unsigned& iarg, const double& der ) {
+     143      833432 :   plumed_dbg_assert( iarg<numberOfArgs && oind_set ); myvals.setDerivative( oind, iarg, der );
+     144             : }
+     145             : 
+     146             : inline
+     147             : bool ReferenceValuePack::updateComplete() const {
+     148      520192 :   return myvals.updateComplete();
+     149             : }
+     150             : 
+     151             : inline
+     152    17547915 : void ReferenceValuePack::setAtomDerivatives( const unsigned& jder, const Vector& der ) {
+     153             :   plumed_dbg_assert( oind_set && jder<atom_indices.size() );
+     154    17547915 :   myvals.setDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 0, der[0] );
+     155    17547915 :   myvals.setDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 1, der[1] );
+     156    17547915 :   myvals.setDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 2, der[2] );
+     157    17547915 : }
+     158             : 
+     159             : inline
+     160    16356460 : void ReferenceValuePack::addAtomDerivatives( const unsigned& jder, const Vector& der ) {
+     161             :   plumed_dbg_assert( oind_set && jder<atom_indices.size() );
+     162    16356460 :   myvals.addDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 0, der[0] );
+     163    16356460 :   myvals.addDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 1, der[1] );
+     164    16356460 :   myvals.addDerivative( oind, numberOfArgs + 3*atom_indices[jder] + 2, der[2] );
+     165    16356460 : }
+     166             : 
+     167             : inline
+     168     8268786 : void ReferenceValuePack::addBoxDerivatives( const Tensor& vir ) {
+     169             :   plumed_dbg_assert( oind_set && atom_indices.size()>0 );
+     170     8268786 :   boxWasSet=true; unsigned nbase = myvals.getNumberOfDerivatives() - 9;
+     171   107494218 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) myvals.addDerivative( oind, nbase + 3*i + j, vir(i,j) );
+     172     8268786 : }
+     173             : 
+     174             : inline
+     175             : void ReferenceValuePack::setValIndex( const unsigned& ind ) {
+     176      255233 :   oind=ind; oind_set=true;
+     177             : }
+     178             : 
+     179             : inline
+     180             : bool ReferenceValuePack::virialWasSet() const {
+     181      176799 :   return boxWasSet;
+     182             : }
+     183             : 
+     184             : inline
+     185    17175932 : Vector ReferenceValuePack::getAtomDerivative( const unsigned& iatom ) const {
+     186    17175932 :   Vector tmp; plumed_dbg_assert( oind_set && iatom<atom_indices.size() );
+     187    17175932 :   tmp[0]=myvals.getDerivative( oind, numberOfArgs + 3*atom_indices[iatom] + 0 );
+     188    17175932 :   tmp[1]=myvals.getDerivative( oind, numberOfArgs + 3*atom_indices[iatom] + 1 );
+     189    17175932 :   tmp[2]=myvals.getDerivative( oind, numberOfArgs + 3*atom_indices[iatom] + 2 );
+     190    17175932 :   return tmp;
+     191             : }
+     192             : 
+     193             : inline
+     194             : double ReferenceValuePack::getArgumentDerivative( const unsigned& ival ) const {
+     195             :   plumed_dbg_assert( oind_set && ival<numberOfArgs );
+     196       12614 :   return myvals.getDerivative( oind, ival );
+     197             : }
+     198             : 
+     199             : inline
+     200         600 : Tensor ReferenceValuePack::getBoxDerivatives() const {
+     201         600 :   plumed_dbg_assert( oind_set && boxWasSet ); Tensor tvir; unsigned nbase = myvals.getNumberOfDerivatives() - 9;
+     202        7800 :   for(unsigned i=0; i<3; ++i) for(unsigned j=0; j<3; ++j) tvir(i,j)=myvals.getDerivative( oind, nbase + 3*i + j );
+     203         600 :   return tvir;
+     204             : }
+     205             : 
+     206             : inline
+     207             : bool ReferenceValuePack::calcUsingPCAOption() const {
+     208      219081 :   return pca;
+     209             : }
+     210             : 
+     211             : inline
+     212             : void ReferenceValuePack::switchOnPCAOption() {
+     213         698 :   pca=true;
+     214             : }
+     215             : 
+     216             : inline
+     217             : std::vector<Vector>& ReferenceValuePack::getAtomVector() {
+     218    17766386 :   return myvals.getAtomVector();
+     219             : }
+     220             : 
+     221             : inline
+     222             : std::vector<Vector>& ReferenceValuePack::getAtomsDisplacementVector() {
+     223        3026 :   return displacement;
+     224             : }
+     225             : 
+     226             : }
+     227             : 
+     228             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SimpleRMSD.cpp.func-sort-c.html b/coverage/reference/SimpleRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..74daa73afcda --- /dev/null +++ b/coverage/reference/SimpleRMSD.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - reference/SimpleRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - SimpleRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283384.8 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10SimpleRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZNK4PLMD10SimpleRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZN4PLMD10SimpleRMSD28pcaIsEnabledForThisReferenceEv4
_ZN4PLMD10SimpleRMSD4readERKNS_3PDBE31
_ZN4PLMD10SimpleRMSDC1ERKNS_29ReferenceConfigurationOptionsE35
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE35
_ZN4PLMD10SimpleRMSD15setupPCAStorageERNS_18ReferenceValuePackE68
_ZNK4PLMD10SimpleRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE88
_ZNK4PLMD10SimpleRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb172
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeD2Ev4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SimpleRMSD.cpp.func.html b/coverage/reference/SimpleRMSD.cpp.func.html new file mode 100644 index 000000000000..5ef373a9cacf --- /dev/null +++ b/coverage/reference/SimpleRMSD.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - reference/SimpleRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - SimpleRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283384.8 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10SimpleRMSD15setupPCAStorageERNS_18ReferenceValuePackE68
_ZN4PLMD10SimpleRMSD28pcaIsEnabledForThisReferenceEv4
_ZN4PLMD10SimpleRMSD4readERKNS_3PDBE31
_ZN4PLMD10SimpleRMSDC1ERKNS_29ReferenceConfigurationOptionsE35
_ZN4PLMD10SimpleRMSDC2ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMe6createERKNS_29ReferenceConfigurationOptionsE35
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeC2Ev4187
_ZN4PLMD12_GLOBAL__N_120SimpleRMSDRegisterMeD2Ev4187
_ZNK4PLMD10SimpleRMSD25extractAtomicDisplacementERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_0
_ZNK4PLMD10SimpleRMSD33projectAtomicDisplacementOnVectorERKbRKSt6vectorINS_13VectorGenericILj3EEESaIS5_EERNS_18ReferenceValuePackE88
_ZNK4PLMD10SimpleRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_18ReferenceValuePackERKb172
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SimpleRMSD.cpp.gcov.html b/coverage/reference/SimpleRMSD.cpp.gcov.html new file mode 100644 index 000000000000..50e7789fd346 --- /dev/null +++ b/coverage/reference/SimpleRMSD.cpp.gcov.html @@ -0,0 +1,163 @@ + + + + + + + + LCOV - plumed test coverage - reference/SimpleRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - SimpleRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283384.8 %
Date:2024-02-22 21:58:45Functions:91181.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "RMSDBase.h"
+      23             : #include "MetricRegister.h"
+      24             : #include "tools/RMSD.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28             : class SimpleRMSD : public RMSDBase {
+      29             : private:
+      30             :   RMSD myrmsd;
+      31             : public:
+      32             :   explicit SimpleRMSD( const ReferenceConfigurationOptions& ro );
+      33             :   void read( const PDB& ) override;
+      34             :   double calc( const std::vector<Vector>& pos, ReferenceValuePack& myder, const bool& squared ) const override;
+      35           4 :   bool pcaIsEnabledForThisReference() override { return true; }
+      36          68 :   void setupPCAStorage( ReferenceValuePack& mypack ) override {
+      37          68 :     mypack.switchOnPCAOption(); mypack.getAtomsDisplacementVector().resize( getNumberOfAtoms() );
+      38          68 :   }
+      39             :   void extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& direction ) const override;
+      40             :   double projectAtomicDisplacementOnVector( const bool& normalized, const std::vector<Vector>& vecs, ReferenceValuePack& mypack ) const override;
+      41             : };
+      42             : 
+      43       12631 : PLUMED_REGISTER_METRIC(SimpleRMSD,"SIMPLE")
+      44             : 
+      45          35 : SimpleRMSD::SimpleRMSD( const ReferenceConfigurationOptions& ro ):
+      46             :   ReferenceConfiguration( ro ),
+      47          35 :   RMSDBase( ro )
+      48             : {
+      49          35 : }
+      50             : 
+      51          31 : void SimpleRMSD::read( const PDB& pdb ) {
+      52          31 :   readReference( pdb );
+      53          31 : }
+      54             : 
+      55         172 : double SimpleRMSD::calc( const std::vector<Vector>& pos, ReferenceValuePack& myder, const bool& squared ) const {
+      56         172 :   if( myder.getAtomsDisplacementVector().size()!=pos.size() ) myder.getAtomsDisplacementVector().resize( pos.size() );
+      57         172 :   double d=myrmsd.simpleAlignment( getAlign(), getDisplace(), pos, getReferencePositions(), myder.getAtomVector(), myder.getAtomsDisplacementVector(), squared );
+      58        3997 :   myder.clear(); for(unsigned i=0; i<pos.size(); ++i) myder.setAtomDerivatives( i, myder.getAtomVector()[i] );
+      59         172 :   if( !myder.updateComplete() ) myder.updateDynamicLists();
+      60         172 :   return d;
+      61             : }
+      62             : 
+      63           0 : void SimpleRMSD::extractAtomicDisplacement( const std::vector<Vector>& pos, std::vector<Vector>& direction ) const {
+      64           0 :   std::vector<Vector> tder( getNumberOfAtoms() );
+      65           0 :   myrmsd.simpleAlignment( getAlign(), getDisplace(), pos, getReferencePositions(), tder, direction, true );
+      66           0 :   for(unsigned i=0; i<pos.size(); ++i) direction[i] = getDisplace()[i]*direction[i];
+      67           0 : }
+      68             : 
+      69          88 : double SimpleRMSD::projectAtomicDisplacementOnVector( const bool& normalized, const std::vector<Vector>& vecs, ReferenceValuePack& mypack ) const {
+      70          88 :   plumed_dbg_assert( mypack.calcUsingPCAOption() ); Vector comder; comder.zero();
+      71         550 :   for(unsigned j=0; j<vecs.size(); ++j) {
+      72        1848 :     for(unsigned k=0; k<3; ++k) comder[k] += getAlign()[j]*vecs[j][k];
+      73             :   }
+      74             : 
+      75          88 :   double proj=0; mypack.clear();
+      76         550 :   for(unsigned j=0; j<vecs.size(); ++j) {
+      77        1848 :     for(unsigned k=0; k<3; ++k) {
+      78        1386 :       proj += vecs[j][k]*mypack.getAtomsDisplacementVector()[j][k];
+      79             :     }
+      80         462 :     mypack.setAtomDerivatives( j, vecs[j] - comder );
+      81             :   }
+      82          88 :   if( !mypack.updateComplete() ) mypack.updateDynamicLists();
+      83          88 :   return proj;
+      84             : }
+      85             : 
+      86             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.cpp.func-sort-c.html b/coverage/reference/SingleDomainRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..11279db9b98f --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - reference/SingleDomainRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - SingleDomainRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4545100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSDC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD16SingleDomainRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_45
_ZN4PLMD16SingleDomainRMSD13readReferenceERKNS_3PDBE458
_ZN4PLMD16SingleDomainRMSDC2ERKNS_29ReferenceConfigurationOptionsE500
_ZNK4PLMD16SingleDomainRMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb58046
_ZNK4PLMD16SingleDomainRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb140941
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.cpp.func.html b/coverage/reference/SingleDomainRMSD.cpp.func.html new file mode 100644 index 000000000000..fca584103dbb --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - reference/SingleDomainRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - SingleDomainRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4545100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSD13readReferenceERKNS_3PDBE458
_ZN4PLMD16SingleDomainRMSD17setReferenceAtomsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEESB_45
_ZN4PLMD16SingleDomainRMSDC1ERKNS_29ReferenceConfigurationOptionsE0
_ZN4PLMD16SingleDomainRMSDC2ERKNS_29ReferenceConfigurationOptionsE500
_ZNK4PLMD16SingleDomainRMSD4calcERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERKS1_IPNS_5ValueESaISC_EERKS1_IdSaIdEERNS_18ReferenceValuePackERKb140941
_ZNK4PLMD16SingleDomainRMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERNS_18ReferenceValuePackERKb58046
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.cpp.gcov.html b/coverage/reference/SingleDomainRMSD.cpp.gcov.html new file mode 100644 index 000000000000..d4e56dafec11 --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.cpp.gcov.html @@ -0,0 +1,179 @@ + + + + + + + + LCOV - plumed test coverage - reference/SingleDomainRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - SingleDomainRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4545100.0 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "SingleDomainRMSD.h"
+      23             : #include "tools/PDB.h"
+      24             : #include "DRMSD.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28         500 : SingleDomainRMSD::SingleDomainRMSD( const ReferenceConfigurationOptions& ro ):
+      29             :   ReferenceConfiguration(ro),
+      30         500 :   ReferenceAtoms(ro)
+      31             : {
+      32         500 : }
+      33             : 
+      34         458 : void SingleDomainRMSD::readReference( const PDB& pdb ) {
+      35         458 :   readAtomsFromPDB( pdb );
+      36             :   double wa=0, wd=0;
+      37        9071 :   for(unsigned i=0; i<pdb.size(); ++i) { wa+=align[i]; wd+=displace[i]; }
+      38             : 
+      39         458 :   if(wa>epsilon) {
+      40         456 :     double w=1.0/wa;
+      41        9039 :     for(unsigned i=0; i<pdb.size(); ++i) align[i] *= w;
+      42             :   } else {
+      43           2 :     double w=1.0/pdb.size();
+      44          32 :     for(unsigned i=0; i<pdb.size(); ++i) align[i] = w;
+      45             :   }
+      46             : 
+      47         458 :   if(wd>epsilon) {
+      48         456 :     double w=1.0/wd;
+      49        9039 :     for(unsigned i=0; i<pdb.size(); ++i) displace[i] *= w;
+      50             :   } else {
+      51           2 :     double w=1.0/pdb.size();
+      52          32 :     for(unsigned i=0; i<pdb.size(); ++i) displace[i] = w;
+      53             :   }
+      54             : 
+      55         458 :   Vector center;
+      56        9071 :   for(unsigned i=0; i<pdb.size(); ++i) {
+      57        8613 :     center+=reference_atoms[i]*align[i];
+      58             :   }
+      59        9071 :   for(unsigned i=0; i<pdb.size(); ++i) reference_atoms[i]-=center;
+      60         458 : }
+      61             : 
+      62          45 : void SingleDomainRMSD::setReferenceAtoms( const std::vector<Vector>& conf, const std::vector<double>& align_in, const std::vector<double>& displace_in ) {
+      63          45 :   reference_atoms.resize( conf.size() ); align.resize( conf.size() );
+      64          45 :   displace.resize( conf.size() ); atom_der_index.resize( conf.size() );
+      65             :   double wa=0, wd=0;
+      66        1154 :   for(unsigned i=0; i<conf.size(); ++i) { wa+=align_in[i]; wd+=displace_in[i]; }
+      67             : 
+      68          45 :   if(wa>epsilon) {
+      69          44 :     double w=1.0/wa;
+      70        1145 :     for(unsigned i=0; i<conf.size(); ++i) align[i] = align_in[i] * w;
+      71             :   } else {
+      72           1 :     double w=1.0/conf.size();
+      73           9 :     for(unsigned i=0; i<conf.size(); ++i) align[i] = w;
+      74             :   }
+      75             : 
+      76          45 :   if(wd>epsilon) {
+      77          44 :     double w=1.0/wd;
+      78        1146 :     for(unsigned i=0; i<conf.size(); ++i) displace[i] = displace_in[i] * w;
+      79             :   } else {
+      80           1 :     double w=1.0/conf.size();
+      81           8 :     for(unsigned i=0; i<conf.size(); ++i) displace[i] = w;
+      82             :   }
+      83             : 
+      84          45 :   Vector center;
+      85        1154 :   for(unsigned i=0; i<conf.size(); ++i) {
+      86        1109 :     center+=conf[i]*align[i]; atom_der_index[i]=i;
+      87             :   }
+      88        1154 :   for(unsigned i=0; i<conf.size(); ++i) reference_atoms[i]=conf[i]-center;
+      89          45 :   setupRMSDObject();
+      90          45 : }
+      91             : 
+      92       58046 : double SingleDomainRMSD::calculate( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
+      93       58046 :   return calc( pos, pbc, myder, squared );
+      94             : }
+      95             : 
+      96      140941 : double SingleDomainRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& arg,
+      97             :                                ReferenceValuePack& myder, const bool& squared ) const {
+      98             :   plumed_dbg_assert( vals.size()==0 && pos.size()==getNumberOfAtoms() && arg.size()==0 );
+      99      140941 :   return calc( pos, pbc, myder, squared );
+     100             : }
+     101             : 
+     102             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.h.func-sort-c.html b/coverage/reference/SingleDomainRMSD.h.func-sort-c.html new file mode 100644 index 000000000000..fa4885eda84f --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - reference/SingleDomainRMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - SingleDomainRMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSD15setupRMSDObjectEv27
_ZN4PLMD16SingleDomainRMSD20setBoundsOnDistancesEbdd28
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.h.func.html b/coverage/reference/SingleDomainRMSD.h.func.html new file mode 100644 index 000000000000..8ac9a99fc8f9 --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - reference/SingleDomainRMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - SingleDomainRMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16SingleDomainRMSD15setupRMSDObjectEv27
_ZN4PLMD16SingleDomainRMSD20setBoundsOnDistancesEbdd28
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/SingleDomainRMSD.h.gcov.html b/coverage/reference/SingleDomainRMSD.h.gcov.html new file mode 100644 index 000000000000..2545e34108a6 --- /dev/null +++ b/coverage/reference/SingleDomainRMSD.h.gcov.html @@ -0,0 +1,128 @@ + + + + + + + + LCOV - plumed test coverage - reference/SingleDomainRMSD.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - reference - SingleDomainRMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_reference_SingleDomainRMSD_h
+      23             : #define __PLUMED_reference_SingleDomainRMSD_h
+      24             : 
+      25             : #include "ReferenceAtoms.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : class Pbc;
+      30             : 
+      31             : class SingleDomainRMSD : public ReferenceAtoms {
+      32             : protected:
+      33             :   void readReference( const PDB& pdb );
+      34             : public:
+      35             :   explicit SingleDomainRMSD( const ReferenceConfigurationOptions& ro );
+      36             : /// Set the reference structure
+      37             :   void setReferenceAtoms( const std::vector<Vector>& conf, const std::vector<double>& align_in, const std::vector<double>& displace_in ) override;
+      38             : /// Calculate
+      39             :   double calc( const std::vector<Vector>& pos, const Pbc& pbc, const std::vector<Value*>& vals, const std::vector<double>& arg, ReferenceValuePack& myder, const bool& squared ) const override;
+      40             :   double calculate( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const;
+      41             : /// Calculate the distance using the input position
+      42             :   virtual double calc( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const=0;
+      43             : /// This sets upper and lower bounds on distances to be used in DRMSD (here it does nothing)
+      44          28 :   virtual void setBoundsOnDistances( bool dopbc, double lbound=0.0, double ubound=std::numeric_limits<double>::max( ) ) {};
+      45             : /// This is used by MultiDomainRMSD to setup the RMSD object in Optimal RMSD type
+      46          27 :   virtual void setupRMSDObject() {};
+      47             : };
+      48             : 
+      49             : }
+      50             : 
+      51             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/index-sort-f.html b/coverage/reference/index-sort-f.html new file mode 100644 index 000000000000..c50e75476b00 --- /dev/null +++ b/coverage/reference/index-sort-f.html @@ -0,0 +1,354 @@ + + + + + + + + LCOV - plumed test coverage - reference + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - referenceHitTotalCoverage
Test:plumed test coverageLines:66877686.1 %
Date:2024-02-22 21:58:45Functions:15319379.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Direction.h +
0.0%
+
0.0 %0 / 10.0 %0 / 1
DotProductDistance.cpp +
8.3%8.3%
+
8.3 %1 / 1228.6 %2 / 7
NormalizedEuclideanDistance.cpp +
20.0%20.0%
+
20.0 %1 / 540.0 %2 / 5
MahalanobisDistance.cpp +
20.0%20.0%
+
20.0 %1 / 540.0 %2 / 5
ArgumentOnlyDistance.cpp +
62.5%62.5%
+
62.5 %10 / 1660.0 %3 / 5
ReferenceAtoms.h +
73.3%73.3%
+
73.3 %11 / 1560.0 %3 / 5
ReferenceConfiguration.h +
75.0%75.0%
+
75.0 %15 / 2066.7 %8 / 12
RMSDBase.cpp +
100.0%
+
100.0 %7 / 775.0 %3 / 4
MultiDomainRMSD.cpp +
87.4%87.4%
+
87.4 %90 / 10376.9 %10 / 13
EuclideanDistance.cpp +
100.0%
+
100.0 %4 / 480.0 %4 / 5
MetricRegister.h +
94.7%94.7%
+
94.7 %18 / 1980.0 %8 / 10
SimpleRMSD.cpp +
84.8%84.8%
+
84.8 %28 / 3381.8 %9 / 11
ReferenceArguments.cpp +
63.2%63.2%
+
63.2 %67 / 10681.8 %9 / 11
ReferenceAtoms.cpp +
90.9%90.9%
+
90.9 %30 / 3383.3 %5 / 6
SingleDomainRMSD.cpp +
100.0%
+
100.0 %45 / 4583.3 %5 / 6
Direction.cpp +
93.3%93.3%
+
93.3 %28 / 3083.3 %10 / 12
ReferenceConfiguration.cpp +
96.4%96.4%
+
96.4 %54 / 5684.6 %11 / 13
IntermolecularDRMSD.cpp +
100.0%
+
100.0 %19 / 1985.7 %6 / 7
IntramolecularDRMSD.cpp +
100.0%
+
100.0 %18 / 1885.7 %6 / 7
OptimalRMSD.cpp +
100.0%
+
100.0 %53 / 5391.7 %11 / 12
SingleDomainRMSD.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
ArgumentOnlyDistance.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
ReferenceArguments.h +
100.0%
+
100.0 %8 / 8100.0 %4 / 4
MetricRegister.cpp +
80.0%80.0%
+
80.0 %16 / 20100.0 %5 / 5
ReferenceValuePack.h +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
ReferenceValuePack.cpp +
100.0%
+
100.0 %49 / 49100.0 %7 / 7
DRMSD.cpp +
93.0%93.0%
+
93.0 %53 / 57100.0 %11 / 11
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/index-sort-l.html b/coverage/reference/index-sort-l.html new file mode 100644 index 000000000000..91536e8c300f --- /dev/null +++ b/coverage/reference/index-sort-l.html @@ -0,0 +1,354 @@ + + + + + + + + LCOV - plumed test coverage - reference + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - referenceHitTotalCoverage
Test:plumed test coverageLines:66877686.1 %
Date:2024-02-22 21:58:45Functions:15319379.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Direction.h +
0.0%
+
0.0 %0 / 10.0 %0 / 1
DotProductDistance.cpp +
8.3%8.3%
+
8.3 %1 / 1228.6 %2 / 7
NormalizedEuclideanDistance.cpp +
20.0%20.0%
+
20.0 %1 / 540.0 %2 / 5
MahalanobisDistance.cpp +
20.0%20.0%
+
20.0 %1 / 540.0 %2 / 5
ArgumentOnlyDistance.cpp +
62.5%62.5%
+
62.5 %10 / 1660.0 %3 / 5
ReferenceArguments.cpp +
63.2%63.2%
+
63.2 %67 / 10681.8 %9 / 11
ReferenceAtoms.h +
73.3%73.3%
+
73.3 %11 / 1560.0 %3 / 5
ReferenceConfiguration.h +
75.0%75.0%
+
75.0 %15 / 2066.7 %8 / 12
MetricRegister.cpp +
80.0%80.0%
+
80.0 %16 / 20100.0 %5 / 5
SimpleRMSD.cpp +
84.8%84.8%
+
84.8 %28 / 3381.8 %9 / 11
MultiDomainRMSD.cpp +
87.4%87.4%
+
87.4 %90 / 10376.9 %10 / 13
ReferenceAtoms.cpp +
90.9%90.9%
+
90.9 %30 / 3383.3 %5 / 6
DRMSD.cpp +
93.0%93.0%
+
93.0 %53 / 57100.0 %11 / 11
Direction.cpp +
93.3%93.3%
+
93.3 %28 / 3083.3 %10 / 12
MetricRegister.h +
94.7%94.7%
+
94.7 %18 / 1980.0 %8 / 10
ReferenceConfiguration.cpp +
96.4%96.4%
+
96.4 %54 / 5684.6 %11 / 13
SingleDomainRMSD.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
ArgumentOnlyDistance.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
EuclideanDistance.cpp +
100.0%
+
100.0 %4 / 480.0 %4 / 5
RMSDBase.cpp +
100.0%
+
100.0 %7 / 775.0 %3 / 4
ReferenceArguments.h +
100.0%
+
100.0 %8 / 8100.0 %4 / 4
IntramolecularDRMSD.cpp +
100.0%
+
100.0 %18 / 1885.7 %6 / 7
IntermolecularDRMSD.cpp +
100.0%
+
100.0 %19 / 1985.7 %6 / 7
ReferenceValuePack.h +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
SingleDomainRMSD.cpp +
100.0%
+
100.0 %45 / 4583.3 %5 / 6
ReferenceValuePack.cpp +
100.0%
+
100.0 %49 / 49100.0 %7 / 7
OptimalRMSD.cpp +
100.0%
+
100.0 %53 / 5391.7 %11 / 12
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/reference/index.html b/coverage/reference/index.html new file mode 100644 index 000000000000..a4d2d75cc2d1 --- /dev/null +++ b/coverage/reference/index.html @@ -0,0 +1,354 @@ + + + + + + + + LCOV - plumed test coverage - reference + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - referenceHitTotalCoverage
Test:plumed test coverageLines:66877686.1 %
Date:2024-02-22 21:58:45Functions:15319379.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ArgumentOnlyDistance.cpp +
62.5%62.5%
+
62.5 %10 / 1660.0 %3 / 5
ArgumentOnlyDistance.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
DRMSD.cpp +
93.0%93.0%
+
93.0 %53 / 57100.0 %11 / 11
Direction.cpp +
93.3%93.3%
+
93.3 %28 / 3083.3 %10 / 12
Direction.h +
0.0%
+
0.0 %0 / 10.0 %0 / 1
DotProductDistance.cpp +
8.3%8.3%
+
8.3 %1 / 1228.6 %2 / 7
EuclideanDistance.cpp +
100.0%
+
100.0 %4 / 480.0 %4 / 5
IntermolecularDRMSD.cpp +
100.0%
+
100.0 %19 / 1985.7 %6 / 7
IntramolecularDRMSD.cpp +
100.0%
+
100.0 %18 / 1885.7 %6 / 7
MahalanobisDistance.cpp +
20.0%20.0%
+
20.0 %1 / 540.0 %2 / 5
MetricRegister.cpp +
80.0%80.0%
+
80.0 %16 / 20100.0 %5 / 5
MetricRegister.h +
94.7%94.7%
+
94.7 %18 / 1980.0 %8 / 10
MultiDomainRMSD.cpp +
87.4%87.4%
+
87.4 %90 / 10376.9 %10 / 13
NormalizedEuclideanDistance.cpp +
20.0%20.0%
+
20.0 %1 / 540.0 %2 / 5
OptimalRMSD.cpp +
100.0%
+
100.0 %53 / 5391.7 %11 / 12
RMSDBase.cpp +
100.0%
+
100.0 %7 / 775.0 %3 / 4
ReferenceArguments.cpp +
63.2%63.2%
+
63.2 %67 / 10681.8 %9 / 11
ReferenceArguments.h +
100.0%
+
100.0 %8 / 8100.0 %4 / 4
ReferenceAtoms.cpp +
90.9%90.9%
+
90.9 %30 / 3383.3 %5 / 6
ReferenceAtoms.h +
73.3%73.3%
+
73.3 %11 / 1560.0 %3 / 5
ReferenceConfiguration.cpp +
96.4%96.4%
+
96.4 %54 / 5684.6 %11 / 13
ReferenceConfiguration.h +
75.0%75.0%
+
75.0 %15 / 2066.7 %8 / 12
ReferenceValuePack.cpp +
100.0%
+
100.0 %49 / 49100.0 %7 / 7
ReferenceValuePack.h +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
SimpleRMSD.cpp +
84.8%84.8%
+
84.8 %28 / 3381.8 %9 / 11
SingleDomainRMSD.cpp +
100.0%
+
100.0 %45 / 4583.3 %5 / 6
SingleDomainRMSD.h +
100.0%
+
100.0 %2 / 2100.0 %2 / 2
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ruby.png b/coverage/ruby.png new file mode 100644 index 0000000000000000000000000000000000000000..991b6d4ec9e78be165e3ef757eed1aada287364d GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^FceV#7`HfI^%F z9+AZi4BSE>%y{W;-5;PJOS+@4BLl<6e(pbstUx|nfKQ0)e^Y%R^MdiLxj>4`)5S5Q b;#P73kj=!v_*DHKNFRfztDnm{r-UW|iOwIS literal 0 HcmV?d00001 diff --git a/coverage/s2cm/S2ContactModel.cpp.func-sort-c.html b/coverage/s2cm/S2ContactModel.cpp.func-sort-c.html new file mode 100644 index 000000000000..009438510c54 --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - s2cm/S2ContactModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cm - S2ContactModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4s2cm14S2ContactModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD4s2cm14S2ContactModelD2Ev0
_ZN4PLMD4s2cm14S2ContactModelC1ERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm14S2ContactModelD0Ev24
_ZN4PLMD4s2cm14S2ContactModelD1Ev24
_ZN4PLMD4s2cm14S2ContactModel16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD4s2cm14S2ContactModel7prepareEv48
_ZN4PLMD4s2cm14S2ContactModel9calculateEv5952
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/S2ContactModel.cpp.func.html b/coverage/s2cm/S2ContactModel.cpp.func.html new file mode 100644 index 000000000000..9422c831648e --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - s2cm/S2ContactModel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cm - S2ContactModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4s2cm14S2ContactModel16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD4s2cm14S2ContactModel7prepareEv48
_ZN4PLMD4s2cm14S2ContactModel9calculateEv5952
_ZN4PLMD4s2cm14S2ContactModelC1ERKNS_13ActionOptionsE24
_ZN4PLMD4s2cm14S2ContactModelC2ERKNS_13ActionOptionsE0
_ZN4PLMD4s2cm14S2ContactModelD0Ev24
_ZN4PLMD4s2cm14S2ContactModelD1Ev24
_ZN4PLMD4s2cm14S2ContactModelD2Ev0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/S2ContactModel.cpp.gcov.html b/coverage/s2cm/S2ContactModel.cpp.gcov.html new file mode 100644 index 000000000000..87af56bc118d --- /dev/null +++ b/coverage/s2cm/S2ContactModel.cpp.gcov.html @@ -0,0 +1,402 @@ + + + + + + + + LCOV - plumed test coverage - s2cm/S2ContactModel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cm - S2ContactModel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2021 Omar Valsson
+       3             : 
+       4             :    This file is part of S2 contact model module
+       5             : 
+       6             :    The S2 contact model module is free software: you can redistribute it and/or modify
+       7             :    it under the terms of the GNU Lesser General Public License as published by
+       8             :    the Free Software Foundation, either version 3 of the License, or
+       9             :    (at your option) any later version.
+      10             : 
+      11             :    The S2 contact model module is distributed in the hope that it will be useful,
+      12             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      13             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      14             :    GNU Lesser General Public License for more details.
+      15             : 
+      16             :    You should have received a copy of the GNU Lesser General Public License
+      17             :    along with the S2 contact model module.  If not, see <http://www.gnu.org/licenses/>.
+      18             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      19             : 
+      20             : #include "colvar/Colvar.h"
+      21             : #include "tools/NeighborList.h"
+      22             : #include "tools/Communicator.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : 
+      26             : 
+      27             : #include <string>
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace s2cm {
+      32             : 
+      33             : 
+      34             : //
+      35             : 
+      36             : //+PLUMEDOC S2CMMOD_COLVAR S2CM
+      37             : /*
+      38             : S2 contact model CV.
+      39             : 
+      40             : This CV was used in \cite Palazzesi_s2_2017, based on NH order parameter from \cite Zhang_s2_2002 and methyl order parameter from \cite Ming_s2_2004. Input parameters can be found in the relevant papers.
+      41             : 
+      42             : \par Examples
+      43             : 
+      44             : 
+      45             : */
+      46             : //+ENDPLUMEDOC
+      47             : 
+      48             : 
+      49             : 
+      50             : 
+      51             : 
+      52             : 
+      53             : 
+      54             : class S2ContactModel : public Colvar {
+      55             :   bool pbc_;
+      56             :   bool serial_;
+      57             :   std::unique_ptr<NeighborList> nl;
+      58             :   bool invalidateList;
+      59             :   bool firsttime;
+      60             :   //
+      61             :   double r_eff_;
+      62             :   double inv_r_eff_;
+      63             :   double prefactor_a_;
+      64             :   double exp_b_;
+      65             :   double offset_c_;
+      66             :   double n_i_;
+      67             :   double total_prefactor_;
+      68             :   double r_globalshift_;
+      69             : 
+      70             :   enum ModelType {methyl,nh} modeltype_;
+      71             : 
+      72             :   //
+      73             : public:
+      74             :   explicit S2ContactModel(const ActionOptions&);
+      75             :   ~S2ContactModel();
+      76             :   virtual void calculate();
+      77             :   virtual void prepare();
+      78             :   static void registerKeywords( Keywords& keys );
+      79             : };
+      80             : 
+      81             : PLUMED_REGISTER_ACTION(S2ContactModel,"S2CM")
+      82             : 
+      83          26 : void S2ContactModel::registerKeywords( Keywords& keys ) {
+      84          26 :   Colvar::registerKeywords(keys);
+      85          52 :   keys.addFlag("SERIAL",false,"Perform the calculation in serial - for debug purpose");
+      86          52 :   keys.addFlag("NLIST",false,"Use a neighbour list to speed up the calculation");
+      87          52 :   keys.add("optional","NL_CUTOFF","The cutoff for the neighbour list");
+      88          52 :   keys.add("optional","NL_STRIDE","The frequency with which we are updating the atoms in the neighbour list");
+      89          52 :   keys.add("atoms","METHYL_ATOM","the methyl carbon atom of the residue (i)");
+      90          52 :   keys.add("atoms","NH_ATOMS","the hydrogen atom of the NH group of the residue (i) and carbonyl oxygen of the preceding residue (i-1)");
+      91          52 :   keys.add("atoms","HEAVY_ATOMS","the heavy atoms to be included in the calculation");
+      92             :   //
+      93          52 :   keys.add("compulsory","R_EFF","the effective distance, r_eff in the equation, given in nm.");
+      94          52 :   keys.add("compulsory","PREFACTOR_A","the prefactor, a in the equation");
+      95          52 :   keys.add("compulsory","EXPONENT_B","the exponent, b in the equation");
+      96          52 :   keys.add("compulsory","OFFSET_C","the offset, c in the equation");
+      97          52 :   keys.add("compulsory","N_I"," n_i in the equation");
+      98          52 :   keys.add("optional","R_SHIFT","shift all distances by given amount");
+      99          26 : }
+     100             : 
+     101          24 : S2ContactModel::S2ContactModel(const ActionOptions&ao):
+     102             :   PLUMED_COLVAR_INIT(ao),
+     103          24 :   pbc_(true),
+     104          24 :   serial_(false),
+     105          24 :   invalidateList(true),
+     106          24 :   firsttime(true),
+     107          24 :   r_eff_(0.0),
+     108          24 :   inv_r_eff_(0.0),
+     109          24 :   prefactor_a_(0.0),
+     110          24 :   exp_b_(0.0),
+     111          24 :   offset_c_(0.0),
+     112          24 :   n_i_(0.0),
+     113          24 :   total_prefactor_(0.0),
+     114          24 :   r_globalshift_(0.0),
+     115          24 :   modeltype_(methyl)
+     116             : {
+     117             : 
+     118          48 :   parseFlag("SERIAL",serial_);
+     119             : 
+     120             :   std::vector<AtomNumber> methyl_atom;
+     121          48 :   parseAtomList("METHYL_ATOM",methyl_atom);
+     122             :   std::vector<AtomNumber> nh_atoms;
+     123          48 :   parseAtomList("NH_ATOMS",nh_atoms);
+     124             : 
+     125          24 :   if(methyl_atom.size()==0 && nh_atoms.size()==0) {
+     126           0 :     error("you have to give either METHYL_ATOM or NH_ATOMS");
+     127             :   }
+     128          24 :   if(methyl_atom.size()>0 && nh_atoms.size()>0) {
+     129           0 :     error("you cannot give both METHYL_ATOM or NH_ATOMS");
+     130             :   }
+     131          24 :   if(methyl_atom.size()>0 && methyl_atom.size()!=1) {
+     132           0 :     error("you should give one atom in METHYL_ATOM, the methyl carbon atom of the residue");
+     133             :   }
+     134          24 :   if(nh_atoms.size()>0 && nh_atoms.size()!=2) {
+     135           0 :     error("you should give two atoms in NH_ATOMS, the hydrogen atom of the NH group of the residue (i) and carbonyl oxygen of the preceding residue (i-1)");
+     136             :   }
+     137             : 
+     138             :   std::vector<AtomNumber> heavy_atoms;
+     139          48 :   parseAtomList("HEAVY_ATOMS",heavy_atoms);
+     140          24 :   if(heavy_atoms.size()==0) {
+     141           0 :     error("HEAVY_ATOMS is not given");
+     142             :   }
+     143             : 
+     144             :   std::vector<AtomNumber> main_atoms;
+     145          24 :   if(methyl_atom.size()>0) {
+     146           0 :     modeltype_= methyl;
+     147           0 :     main_atoms = methyl_atom;
+     148          24 :   } else if(nh_atoms.size()>0) {
+     149          24 :     modeltype_= nh;
+     150          24 :     main_atoms = nh_atoms;
+     151             :   }
+     152             : 
+     153          24 :   bool nopbc=!pbc_;
+     154          24 :   parseFlag("NOPBC",nopbc);
+     155          24 :   pbc_=!nopbc;
+     156             : 
+     157             :   // neighbor list stuff
+     158          24 :   bool doneigh=false;
+     159          24 :   double nl_cut=0.0;
+     160          24 :   int nl_st=0;
+     161          24 :   parseFlag("NLIST",doneigh);
+     162          24 :   if(doneigh) {
+     163          12 :     parse("NL_CUTOFF",nl_cut);
+     164          12 :     if(nl_cut<=0.0) error("NL_CUTOFF should be explicitly specified and positive");
+     165          12 :     parse("NL_STRIDE",nl_st);
+     166          12 :     if(nl_st<=0) error("NL_STRIDE should be explicitly specified and positive");
+     167             :   }
+     168             : 
+     169          24 :   parse("R_EFF",r_eff_);
+     170          24 :   inv_r_eff_ = 1.0/r_eff_;
+     171          24 :   parse("PREFACTOR_A",prefactor_a_);
+     172          24 :   parse("EXPONENT_B",exp_b_);
+     173          24 :   parse("OFFSET_C",offset_c_);
+     174             :   unsigned int n_i_int;
+     175          24 :   parse("N_I",n_i_int);
+     176          24 :   n_i_ = static_cast<double>(n_i_int);
+     177          24 :   total_prefactor_ = prefactor_a_/pow(n_i_,exp_b_);
+     178             :   //
+     179          24 :   parse("R_SHIFT",r_globalshift_);
+     180             : 
+     181          24 :   checkRead();
+     182             : 
+     183          24 :   addValueWithDerivatives();
+     184          24 :   setNotPeriodic();
+     185             : 
+     186          24 :   bool dopair=false;
+     187          24 :   if(doneigh) {
+     188          24 :     nl=Tools::make_unique<NeighborList>(main_atoms,heavy_atoms,serial_,dopair,pbc_,getPbc(),comm,nl_cut,nl_st);
+     189             :   }
+     190             :   else {
+     191          24 :     nl=Tools::make_unique<NeighborList>(main_atoms,heavy_atoms,serial_,dopair,pbc_,getPbc(),comm);
+     192             :   }
+     193             : 
+     194          24 :   requestAtoms(nl->getFullAtomList());
+     195             : 
+     196             : 
+     197          24 :   log.printf("  NMR S2 contact model CV, please read and cite ");
+     198          48 :   log << plumed.cite("Palazzesi, Valsson, and Parrinello, J. Phys. Chem. Lett. 8, 4752 (2017) - DOI:10.1021/acs.jpclett.7b01770");
+     199             : 
+     200          24 :   if(modeltype_==methyl) {
+     201           0 :     log << plumed.cite("Ming and Bruschweiler, J. Biomol. NMR, 29, 363 (2004) - DOI:10.1023/B:JNMR.0000032612.70767.35");
+     202           0 :     log.printf("\n");
+     203           0 :     log.printf("  calculation of methyl order parameter using atom %d \n",methyl_atom[0].serial());
+     204             :   }
+     205          24 :   else if(modeltype_==nh) {
+     206          48 :     log << plumed.cite("Zhang and Bruschweiler, J. Am. Chem. Soc. 124, 12654 (2002) - DOI:10.1021/ja027847a");
+     207          24 :     log.printf("\n");
+     208          24 :     log.printf("  calculation of NH order parameter using atoms %d and %d\n",nh_atoms[0].serial(),nh_atoms[1].serial());
+     209             :   }
+     210          24 :   log.printf("  heavy atoms used in the calculation (%u in total):\n",static_cast<unsigned int>(heavy_atoms.size()));
+     211        1872 :   for(unsigned int i=0; i<heavy_atoms.size(); ++i) {
+     212        1848 :     if( (i+1) % 25 == 0 ) {log.printf("  \n");}
+     213        1848 :     log.printf("  %d", heavy_atoms[i].serial());
+     214             :   }
+     215          24 :   log.printf("  \n");
+     216          24 :   log.printf("  total number of distances: %u\n",nl->size());
+     217             :   //
+     218          24 :   log.printf("  using parameters");
+     219          24 :   log.printf(" r_eff=%f,",r_eff_);
+     220          24 :   log.printf(" a=%f,",prefactor_a_);
+     221          24 :   log.printf(" b=%f,",exp_b_);
+     222          24 :   log.printf(" c=%f,",offset_c_);
+     223          24 :   log.printf(" n_i=%u",n_i_int);
+     224          24 :   if(r_globalshift_!=0.0) {
+     225           4 :     log.printf(", r_shift=%f",r_globalshift_);
+     226             :   }
+     227          24 :   log.printf("\n");
+     228          24 :   if(pbc_) {
+     229          12 :     log.printf("  using periodic boundary conditions\n");
+     230             :   } else {
+     231          12 :     log.printf("  without periodic boundary conditions\n");
+     232             :   }
+     233          24 :   if(doneigh) {
+     234          12 :     log.printf("  using neighbor lists with\n");
+     235          12 :     log.printf("  update every %d steps and cutoff %f\n",nl_st,nl_cut);
+     236             :   }
+     237          24 :   if(serial_) {
+     238           0 :     log.printf("  calculation done in serial\n");
+     239             :   }
+     240          24 : }
+     241             : 
+     242          48 : S2ContactModel::~S2ContactModel() {
+     243          48 : }
+     244             : 
+     245          48 : void S2ContactModel::prepare() {
+     246          48 :   if(nl->getStride()>0) {
+     247          24 :     if(firsttime || (getStep()%nl->getStride()==0)) {
+     248          24 :       requestAtoms(nl->getFullAtomList());
+     249          24 :       invalidateList=true;
+     250          24 :       firsttime=false;
+     251             :     } else {
+     252           0 :       requestAtoms(nl->getReducedAtomList());
+     253           0 :       invalidateList=false;
+     254           0 :       if(getExchangeStep()) error("Neighbor lists should be updated on exchange steps - choose a NL_STRIDE which divides the exchange stride!");
+     255             :     }
+     256          24 :     if(getExchangeStep()) firsttime=true;
+     257             :   }
+     258          48 : }
+     259             : 
+     260             : // calculator
+     261        5952 : void S2ContactModel::calculate() {
+     262             : 
+     263        5952 :   Tensor virial;
+     264        5952 :   std::vector<Vector> deriv(getNumberOfAtoms());
+     265             : 
+     266        5952 :   if(nl->getStride()>0 && invalidateList) {
+     267        2976 :     nl->update(getPositions());
+     268             :   }
+     269             : 
+     270        5952 :   unsigned int stride=comm.Get_size();
+     271        5952 :   unsigned int rank=comm.Get_rank();
+     272        5952 :   if(serial_) {
+     273             :     stride=1;
+     274             :     rank=0;
+     275             :   }
+     276             : 
+     277        5952 :   double contact_sum = 0.0;
+     278             : 
+     279        5952 :   const unsigned int nn=nl->size();
+     280             : 
+     281      321408 :   for(unsigned int i=rank; i<nn; i+=stride) {
+     282      315456 :     Vector distance;
+     283      315456 :     unsigned int i0=nl->getClosePair(i).first;
+     284      315456 :     unsigned int i1=nl->getClosePair(i).second;
+     285      315456 :     if(getAbsoluteIndex(i0)==getAbsoluteIndex(i1)) {continue;}
+     286             : 
+     287      315456 :     if(pbc_) {
+     288       86304 :       distance=pbcDistance(getPosition(i0),getPosition(i1));
+     289             :     } else {
+     290      229152 :       distance=delta(getPosition(i0),getPosition(i1));
+     291             :     }
+     292             : 
+     293      315456 :     double exp_arg = exp(-(distance.modulo()-r_globalshift_)*inv_r_eff_);
+     294      315456 :     contact_sum += exp_arg;
+     295             : 
+     296      315456 :     exp_arg /= distance.modulo();
+     297      315456 :     Vector dd(exp_arg*distance);
+     298      315456 :     Tensor vv(dd,distance);
+     299      315456 :     deriv[i0]-=dd;
+     300      315456 :     deriv[i1]+=dd;
+     301      315456 :     virial-=vv;
+     302             :   }
+     303             : 
+     304        5952 :   if(!serial_) {
+     305        5952 :     comm.Sum(contact_sum);
+     306        5952 :     if(!deriv.empty()) {
+     307        5952 :       comm.Sum(&deriv[0][0],3*deriv.size());
+     308             :     }
+     309        5952 :     comm.Sum(virial);
+     310             :   }
+     311             : 
+     312        5952 :   double value = tanh(total_prefactor_*contact_sum);
+     313             :   // using that d/dx[tanh(x)]= 1-[tanh(x)]^2
+     314        5952 :   double deriv_f = -inv_r_eff_*total_prefactor_*(1.0-value*value);
+     315        5952 :   value -= offset_c_;
+     316             : 
+     317      476160 :   for(unsigned int i=0; i<deriv.size(); ++i) {
+     318      470208 :     setAtomsDerivatives(i,deriv_f*deriv[i]);
+     319             :   }
+     320        5952 :   setValue(value);
+     321       11904 :   setBoxDerivatives(deriv_f*virial);
+     322             : 
+     323        5952 : }
+     324             : }
+     325             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/index-sort-f.html b/coverage/s2cm/index-sort-f.html new file mode 100644 index 000000000000..7a5a3b862927 --- /dev/null +++ b/coverage/s2cm/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/index-sort-l.html b/coverage/s2cm/index-sort-l.html new file mode 100644 index 000000000000..8a1b33004564 --- /dev/null +++ b/coverage/s2cm/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/s2cm/index.html b/coverage/s2cm/index.html new file mode 100644 index 000000000000..ffb2d7c33284 --- /dev/null +++ b/coverage/s2cm/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - s2cm + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - s2cmHitTotalCoverage
Test:plumed test coverageLines:15116591.5 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
S2ContactModel.cpp +
91.5%91.5%
+
91.5 %151 / 16575.0 %6 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/index-sort-f.html b/coverage/sasa/index-sort-f.html new file mode 100644 index 000000000000..0a81c5e5de1d --- /dev/null +++ b/coverage/sasa/index-sort-f.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:996121582.0 %
Date:2024-02-22 21:58:45Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_LCPO.cpp +
82.2%82.2%
+
82.2 %518 / 63076.9 %10 / 13
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %478 / 58584.6 %11 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/index-sort-l.html b/coverage/sasa/index-sort-l.html new file mode 100644 index 000000000000..f02b83ff2bd7 --- /dev/null +++ b/coverage/sasa/index-sort-l.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:996121582.0 %
Date:2024-02-22 21:58:45Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %478 / 58584.6 %11 / 13
sasa_LCPO.cpp +
82.2%82.2%
+
82.2 %518 / 63076.9 %10 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/index.html b/coverage/sasa/index.html new file mode 100644 index 000000000000..706316a86eec --- /dev/null +++ b/coverage/sasa/index.html @@ -0,0 +1,104 @@ + + + + + + + + LCOV - plumed test coverage - sasa + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasaHitTotalCoverage
Test:plumed test coverageLines:996121582.0 %
Date:2024-02-22 21:58:45Functions:212680.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
sasa_HASEL.cpp +
81.7%81.7%
+
81.7 %478 / 58584.6 %11 / 13
sasa_LCPO.cpp +
82.2%82.2%
+
82.2 %518 / 63076.9 %10 / 13
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_HASEL.cpp.func-sort-c.html b/coverage/sasa/sasa_HASEL.cpp.func-sort-c.html new file mode 100644 index 000000000000..02f54881521c --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_HASEL.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_HASEL.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:47858581.7 %
Date:2024-02-22 21:58:45Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4sasa10SASA_HASEL13computeDeltaGEv0
_ZN4PLMD4sasa10SASA_HASELC2ERKNS_13ActionOptionsE0
_ZN4PLMD4sasa10SASA_HASEL10readDeltaGEv1
_ZN4PLMD4sasa10SASA_HASEL11readMaxSurfEv1
_ZN4PLMD4sasa10SASA_HASEL15setupMaxSurfMapB5cxx11Ev1
_ZN4PLMD4sasa10SASA_HASEL13readSASAparamEv2
_ZN4PLMD4sasa10SASA_HASEL15setupHASELparamB5cxx11Ev2
_ZN4PLMD4sasa10SASA_HASEL7readPDBEv2
_ZN4PLMD4sasa10SASA_HASELC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa10SASA_HASEL16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4sasa10SASA_HASEL9calcNlistEv24
_ZN4PLMD4sasa10SASA_HASEL9calculateEv24
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_42
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_HASEL.cpp.func.html b/coverage/sasa/sasa_HASEL.cpp.func.html new file mode 100644 index 000000000000..6b3c10591ab7 --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_HASEL.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_HASEL.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:47858581.7 %
Date:2024-02-22 21:58:45Functions:111384.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4sasa10SASA_HASEL10readDeltaGEv1
_ZN4PLMD4sasa10SASA_HASEL11readMaxSurfEv1
_ZN4PLMD4sasa10SASA_HASEL13computeDeltaGEv0
_ZN4PLMD4sasa10SASA_HASEL13readSASAparamEv2
_ZN4PLMD4sasa10SASA_HASEL15setupHASELparamB5cxx11Ev2
_ZN4PLMD4sasa10SASA_HASEL15setupMaxSurfMapB5cxx11Ev1
_ZN4PLMD4sasa10SASA_HASEL16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4sasa10SASA_HASEL7readPDBEv2
_ZN4PLMD4sasa10SASA_HASEL9calcNlistEv24
_ZN4PLMD4sasa10SASA_HASEL9calculateEv24
_ZN4PLMD4sasa10SASA_HASELC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa10SASA_HASELC2ERKNS_13ActionOptionsE0
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_42
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_HASEL.cpp.gcov.html b/coverage/sasa/sasa_HASEL.cpp.gcov.html new file mode 100644 index 000000000000..f679ca7ef35d --- /dev/null +++ b/coverage/sasa/sasa_HASEL.cpp.gcov.html @@ -0,0 +1,1089 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_HASEL.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_HASEL.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:47858581.7 %
Date:2024-02-22 21:58:45Functions:111384.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2021, Andrea Arsiccio
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : 
+      21             : #include "Sasa.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/GenericMolInfo.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include <cstdio>
+      27             : #include <iostream>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : #include <sstream>
+      31             : #include <algorithm>
+      32             : #include <iterator>
+      33             : #include <fstream>
+      34             : 
+      35             : 
+      36             : using namespace std;
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace sasa {
+      40             : 
+      41             : //+PLUMEDOC SASAMOD_COLVAR SASA_HASEL
+      42             : /*
+      43             : Calculates the solvent accessible surface area (SASA) of a protein molecule, or other properties related to it.
+      44             : 
+      45             : The atoms for which the SASA is desired should be indicated with the keyword ATOMS, and a pdb file of the protein must be provided in input with the MOLINFO keyword. The algorithm described in \cite Hasel1988 is used for the calculation. The radius of the solvent is assumed to be 0.14 nm, which is the radius of water molecules. Using the keyword NL_STRIDE it is also possible to specify the frequency with which the neighbor list for the calculation of SASA is updated (the default is every 10 steps).
+      46             : 
+      47             : Different properties can be calculated and selected using the TYPE keyword:
+      48             : 
+      49             : 1) the total SASA (TOTAL);
+      50             : 
+      51             : 2) the free energy of transfer for the protein according to the transfer model (TRANSFER). This keyword can be used, for instance, to compute the transfer of a protein to different temperatures, as detailed in \cite Arsiccio-T-SASA-2021, or to different pressures, as detailed in \cite Arsiccio-P-SASA-2021, or to different osmolyte solutions, as detailed in \cite Arsiccio-C-SASA-2022.
+      52             : 
+      53             : 
+      54             : When the TRANSFER keyword is used, a file with the free energy of transfer values for the sidechains and backbone atoms should be provided (using the keyword DELTAGFILE). Such file should have the following format:
+      55             : 
+      56             : \verbatim
+      57             : 
+      58             : ----------------Sample DeltaG.dat file---------------------
+      59             : ALA     0.711019999999962
+      60             : ARG     -2.24832799999996
+      61             : ASN     -2.74838799999999
+      62             : ASP     -2.5626376
+      63             : CYS     3.89864000000006
+      64             : GLN     -1.76192
+      65             : GLU     -2.38664400000002
+      66             : GLY     0
+      67             : HIS     -3.58152799999999
+      68             : ILE     2.42634399999986
+      69             : LEU     1.77233599999988
+      70             : LYS     -1.92576400000002
+      71             : MET     -0.262827999999956
+      72             : PHE     1.62028800000007
+      73             : PRO     -2.15598800000001
+      74             : SER     -1.60934800000004
+      75             : THR     -0.591559999999987
+      76             : TRP     1.22936000000027
+      77             : TYR     0.775547999999958
+      78             : VAL     2.12779200000011
+      79             : BACKBONE        1.00066920000002
+      80             : -----------------------------------------------------------
+      81             : \endverbatim
+      82             : 
+      83             : where the second column is the free energy of transfer for each sidechain/backbone, in kJ/mol.
+      84             : 
+      85             : A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure (according to \cite Arsiccio-C-SASA-2022, \cite Arsiccio-T-SASA-2021 and \cite Arsiccio-P-SASA-2021) is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module.
+      86             : 
+      87             : 
+      88             : If the DELTAGFILE is not provided, the program computes the free energy of transfer values as if they had to take into account the effect of temperature according to approaches 2 or 3 in the paper \cite Arsiccio-T-SASA-2021. Please read and cite this paper if using the transfer model for computing the effect of temperature in implicit solvent simulations. For this purpose, the keyword APPROACH should be added, and set to either 2 or 3.
+      89             : 
+      90             : The SASA usually makes sense when atoms used for the calculation are all part of the same molecule. When running with periodic boundary conditions, the atoms should be in the proper periodic image. This is done automatically since PLUMED 2.2, by considering the ordered list of atoms and rebuilding the broken entities using a procedure that is equivalent to that done in \ref WHOLEMOLECULES. Notice that rebuilding is local to this action. This is different from \ref WHOLEMOLECULES which actually modifies the coordinates stored in PLUMED.
+      91             : 
+      92             : In case you want to recover the old behavior you should use the NOPBC flag.
+      93             : In that case you need to take care that atoms are in the correct periodic image.
+      94             : 
+      95             : The SASA may also be computed using the SASA_LCPO collective variable, which makes use of the LCPO algorithm \cite Weiser1999. SASA_LCPO is more accurate then SASA_HASEL, but the computation is slower.
+      96             : 
+      97             : 
+      98             : \par Examples
+      99             : 
+     100             : The following input tells plumed to print the total SASA for atoms 10 to 20 in a protein chain.
+     101             : \plumedfile
+     102             : SASA_HASEL TYPE=TOTAL ATOMS=10-20 NL_STRIDE=10 LABEL=sasa
+     103             : PRINT ARG=sasa STRIDE=1 FILE=colvar
+     104             : \endplumedfile
+     105             : 
+     106             : 
+     107             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are read from a file called DeltaG.dat.
+     108             : 
+     109             : \plumedfile
+     110             : SASA_HASEL TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 DELTAGFILE=DeltaG.dat LABEL=sasa
+     111             : 
+     112             : bias: BIASVALUE ARG=sasa
+     113             : 
+     114             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     115             : \endplumedfile
+     116             : 
+     117             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are computed according to \cite Arsiccio-T-SASA-2021, and take into account the effect of temperature using approach 2 as described in the paper.
+     118             : 
+     119             : \plumedfile
+     120             : SASA_HASEL TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 APPROACH=2 LABEL=sasa
+     121             : 
+     122             : bias: BIASVALUE ARG=sasa
+     123             : 
+     124             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     125             : \endplumedfile
+     126             : 
+     127             : */
+     128             : //+ENDPLUMEDOC
+     129             : 
+     130             : class SASA_HASEL : public Colvar {
+     131             : private:
+     132             :   enum CV_TYPE {TOTAL, TRANSFER};
+     133             :   int sasa_type;
+     134             :   bool nopbc;
+     135             :   double rs;
+     136             :   string DeltaGValues;
+     137             :   int approach;
+     138             :   unsigned stride;
+     139             :   unsigned nl_update;
+     140             :   int firstStepFlag;
+     141             :   double Ti;
+     142             :   // cppcheck-suppress duplInheritedMember
+     143             :   std::vector<AtomNumber> atoms;
+     144             :   vector < vector < std::string > > AtomResidueName;
+     145             :   vector < vector < double > > SASAparam;
+     146             :   vector < vector < std::string > > CONNECTparam;
+     147             :   unsigned natoms;
+     148             :   vector < vector < double > > MaxSurf;
+     149             :   vector < vector < double > > DeltaG;
+     150             :   vector < vector < int > > Nlist;
+     151             : public:
+     152             :   static void registerKeywords(Keywords& keys);
+     153             :   explicit SASA_HASEL(const ActionOptions&);
+     154             :   void readPDB();
+     155             :   map<string, vector<std::string> > setupHASELparam();
+     156             :   void readSASAparam();
+     157             :   void calcNlist();
+     158             :   map<string, vector<double> > setupMaxSurfMap();
+     159             :   void readMaxSurf();
+     160             :   void readDeltaG();
+     161             :   void computeDeltaG();
+     162             :   virtual void calculate();
+     163             : };
+     164             : 
+     165             : PLUMED_REGISTER_ACTION(SASA_HASEL,"SASA_HASEL")
+     166             : 
+     167           4 : void SASA_HASEL::registerKeywords(Keywords& keys) {
+     168           4 :   Colvar::registerKeywords(keys);
+     169           8 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the SASA for");
+     170           8 :   keys.add("compulsory","TYPE","TOTAL","The type of calculation you want to perform. Can be TOTAL or TRANSFER");
+     171           8 :   keys.add("compulsory", "NL_STRIDE", "The frequency with which the neighbor list for the calculation of SASA is updated.");
+     172           8 :   keys.add("optional","DELTAGFILE","a file containing the free energy of transfer values for backbone and sidechains atoms. Necessary only if TYPE = TRANSFER. A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and are computed using the temperature value passed by the MD engine");
+     173           8 :   keys.add("optional","APPROACH","either approach 2 or 3. Necessary only if TYPE = TRANSFER and no DELTAGFILE is provided. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, J. Phys. Chem. B, 2021) needs to be used to compute them");
+     174           4 : }
+     175             : 
+     176             : 
+     177           2 : SASA_HASEL::SASA_HASEL(const ActionOptions&ao):
+     178             :   PLUMED_COLVAR_INIT(ao),
+     179           2 :   nopbc(false),
+     180           2 :   stride(10),
+     181           2 :   nl_update(0),
+     182           4 :   DeltaGValues("absent"),
+     183           2 :   Ti(0),
+     184           2 :   firstStepFlag(0)
+     185             : {
+     186           2 :   rs = 0.14;
+     187           2 :   parse("DELTAGFILE",DeltaGValues);
+     188           2 :   parse("APPROACH", approach);
+     189           4 :   parseAtomList("ATOMS",atoms);
+     190           2 :   if(atoms.size()==0) error("no atoms specified");
+     191             :   std::string Type;
+     192           2 :   parse("TYPE",Type);
+     193           2 :   parse("NL_STRIDE", stride);
+     194           2 :   parseFlag("NOPBC",nopbc);
+     195           2 :   checkRead();
+     196             : 
+     197           2 :   if(Type=="TOTAL") sasa_type=TOTAL;
+     198           1 :   else if(Type=="TRANSFER") sasa_type=TRANSFER;
+     199           0 :   else error("Unknown SASA type");
+     200             : 
+     201           2 :   switch(sasa_type)
+     202             :   {
+     203           1 :   case TOTAL:   log.printf("  TOTAL SASA;"); break;
+     204           1 :   case TRANSFER: log.printf("  TRANSFER MODEL;"); break;
+     205             :   }
+     206             : 
+     207           2 :   log.printf("  atoms involved : ");
+     208         242 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     209         240 :     if(i%25==0) log<<"\n";
+     210         240 :     log.printf("%d ",atoms[i].serial());
+     211             :   }
+     212           2 :   log.printf("\n");
+     213             : 
+     214           2 :   if(nopbc) {
+     215           0 :     log<<"  PBC will be ignored\n";
+     216             :   } else {
+     217           2 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     218             :   }
+     219             : 
+     220             : 
+     221           4 :   addValueWithDerivatives(); setNotPeriodic();
+     222           2 :   requestAtoms(atoms);
+     223             : 
+     224           2 :   natoms = getNumberOfAtoms();
+     225           2 :   AtomResidueName.resize(2);
+     226           2 :   SASAparam.resize(natoms);
+     227           2 :   CONNECTparam.resize(natoms);
+     228           2 :   MaxSurf.resize(natoms);
+     229           2 :   DeltaG.resize(natoms+1);
+     230           2 :   Nlist.resize(natoms);
+     231             : 
+     232             : 
+     233           2 : }
+     234             : 
+     235             : 
+     236             : //splits strings into tokens. Used to read into SASA parameters file and into reference pdb file
+     237             : template <class Container>
+     238          42 : void split(const std::string& str, Container& cont)
+     239             : {
+     240          42 :   std::istringstream iss(str);
+     241          84 :   std::copy(std::istream_iterator<std::string>(iss),
+     242          42 :             std::istream_iterator<std::string>(),
+     243             :             std::back_inserter(cont));
+     244          42 : }
+     245             : 
+     246             : 
+     247             : //reads input PDB file provided with MOLINFO, and assigns atom and residue names to each atom involved in the CV
+     248             : 
+     249           2 : void SASA_HASEL::readPDB() {
+     250           2 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     251           2 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     252             :   AtomResidueName[0].clear();
+     253             :   AtomResidueName[1].clear();
+     254             : 
+     255         242 :   for(unsigned i=0; i<natoms; i++) {
+     256         240 :     string Aname = moldat->getAtomName(atoms[i]);
+     257         240 :     string Rname = moldat->getResidueName(atoms[i]);
+     258         240 :     AtomResidueName[0].push_back (Aname);
+     259         240 :     AtomResidueName[1].push_back (Rname);
+     260             :   }
+     261             : 
+     262           2 : }
+     263             : 
+     264             : 
+     265             : //Hasel et al. parameters database
+     266           2 : map<string, vector<std::string> > SASA_HASEL::setupHASELparam() {
+     267             :   map<string, vector<std::string> > haselmap;
+     268          16 :   haselmap["ALA_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     269          16 :   haselmap["ALA_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     270          16 :   haselmap["ALA_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     271          16 :   haselmap["ALA_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     272          16 :   haselmap["ALA_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     273          16 :   haselmap["ALA_CB"] = { "2.0",  "0.88",  "CA",  "Z",  "Z",  "Z", };
+     274          16 :   haselmap["ASP_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     275          16 :   haselmap["ASP_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     276          16 :   haselmap["ASP_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     277          16 :   haselmap["ASP_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     278          16 :   haselmap["ASP_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     279          16 :   haselmap["ASP_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     280          16 :   haselmap["ASP_CG"] = { "1.72",  "1.554",  "CB",  "OD1",  "OD2",  "Z", };
+     281          16 :   haselmap["ASP_OD1"] = { "1.5",  "0.926",  "CG",  "Z",  "Z",  "Z", };
+     282          16 :   haselmap["ASP_OD2"] = { "1.7",  "0.922",  "CG",  "Z",  "Z",  "Z", };
+     283          16 :   haselmap["ASN_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     284          16 :   haselmap["ASN_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     285          16 :   haselmap["ASN_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     286          16 :   haselmap["ASN_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     287          16 :   haselmap["ASN_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     288          16 :   haselmap["ASN_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     289          16 :   haselmap["ASN_CG"] = { "1.7",  "2.149",  "CB",  "OD1",  "ND2",  "Z", };
+     290          16 :   haselmap["ASN_OD1"] = { "1.5",  "0.926",  "CG",  "Z",  "Z",  "Z", };
+     291          16 :   haselmap["ASN_ND2"] = { "1.6",  "1.215",  "CG",  "1HD2",  "1HD2",  "Z", };
+     292          16 :   haselmap["ASN_1HD2"] = { "1.1",  "1.128",  "ND2",  "Z",  "Z",  "Z", };
+     293          16 :   haselmap["ASN_2HD2"] = { "1.1",  "1.128",  "ND2",  "Z",  "Z",  "Z", };
+     294          16 :   haselmap["ARG_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     295          16 :   haselmap["ARG_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     296          16 :   haselmap["ARG_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     297          16 :   haselmap["ARG_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     298          16 :   haselmap["ARG_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     299          16 :   haselmap["ARG_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     300          16 :   haselmap["ARG_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     301          16 :   haselmap["ARG_CD"] = { "1.9",  "1.045",  "CG",  "NE",  "Z",  "Z", };
+     302          16 :   haselmap["ARG_NE"] = { "1.55",  "1.028",  "CD",  "HE",  "CZ",  "Z", };
+     303          16 :   haselmap["ARG_NH1"] = { "1.55",  "1.028",  "CZ",  "1HH1",  "2HH1",  "Z", };
+     304          16 :   haselmap["ARG_NH2"] = { "1.55",  "1.028",  "CZ",  "1HH2",  "2HH2",  "Z", };
+     305          16 :   haselmap["ARG_CZ"] = { "1.72",  "1.554",  "NE",  "NH1",  "NH2",  "Z", };
+     306          16 :   haselmap["ARG_HE"] = { "1.1",  "1.128",  "NE",  "Z",  "Z",  "Z", };
+     307          16 :   haselmap["ARG_1HH2"] = { "1.1",  "1.128",  "NH2",  "Z",  "Z",  "Z", };
+     308          16 :   haselmap["ARG_2HH2"] = { "1.1",  "1.128",  "NH2",  "Z",  "Z",  "Z", };
+     309          16 :   haselmap["ARG_2HH1"] = { "1.1",  "1.128",  "NH1",  "Z",  "Z",  "Z", };
+     310          16 :   haselmap["ARG_1HH1"] = { "1.1",  "1.128",  "NH1",  "Z",  "Z",  "Z", };
+     311          16 :   haselmap["CYS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     312          16 :   haselmap["CYS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     313          16 :   haselmap["CYS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     314          16 :   haselmap["CYS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     315          16 :   haselmap["CYS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     316          16 :   haselmap["CYS_CB"] = { "1.9",  "1.045",  "CA",  "SG",  "Z",  "Z", };
+     317          16 :   haselmap["CYS_SG"] = { "1.8",  "1.121",  "CB",  "HG",  "Z",  "Z", };
+     318          16 :   haselmap["CYS_HG"] = { "1.2",  "0.928",  "SG",  "Z",  "Z",  "Z", };
+     319          16 :   haselmap["GLU_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     320          16 :   haselmap["GLU_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     321          16 :   haselmap["GLU_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     322          16 :   haselmap["GLU_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     323          16 :   haselmap["GLU_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     324          16 :   haselmap["GLU_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     325          16 :   haselmap["GLU_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     326          16 :   haselmap["GLU_CD"] = { "1.72",  "1.554",  "CG",  "OE1",  "OE2",  "Z", };
+     327          16 :   haselmap["GLU_OE1"] = { "1.5",  "0.926",  "CD",  "Z",  "Z",  "Z", };
+     328          16 :   haselmap["GLU_OE2"] = { "1.7",  "0.922",  "CD",  "Z",  "Z",  "Z", };
+     329          16 :   haselmap["GLN_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     330          16 :   haselmap["GLN_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     331          16 :   haselmap["GLN_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     332          16 :   haselmap["GLN_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     333          16 :   haselmap["GLN_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     334          16 :   haselmap["GLN_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     335          16 :   haselmap["GLN_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     336          16 :   haselmap["GLN_CD"] = { "1.72",  "1.554",  "CG",  "OE1",  "NE2",  "Z", };
+     337          16 :   haselmap["GLN_OE1"] = { "1.5",  "0.926",  "CD",  "Z",  "Z",  "Z", };
+     338          16 :   haselmap["GLN_NE2"] = { "1.6",  "1.215",  "CD",  "2HE2",  "1HE2",  "Z", };
+     339          16 :   haselmap["GLN_2HE2"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     340          16 :   haselmap["GLN_1HE2"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     341          16 :   haselmap["GLY_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     342          16 :   haselmap["GLY_CA"] = { "1.7",  "2.149",  "N",  "C",  "Z",  "Z", };
+     343          16 :   haselmap["GLY_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     344          16 :   haselmap["GLY_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     345          16 :   haselmap["GLY_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     346          16 :   haselmap["HIS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     347          16 :   haselmap["HIS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     348          16 :   haselmap["HIS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     349          16 :   haselmap["HIS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     350          16 :   haselmap["HIS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     351          16 :   haselmap["HIS_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     352          16 :   haselmap["HIS_CG"] = { "1.72",  "1.554",  "CB",  "CD2",  "ND1",  "Z", };
+     353          16 :   haselmap["HIS_ND1"] = { "1.55",  "1.028",  "CG",  "CE1",  "Z",  "Z", };
+     354          16 :   haselmap["HIS_CE1"] = { "1.8",  "1.073",  "ND1",  "NE2",  "Z",  "Z", };
+     355          16 :   haselmap["HIS_NE2"] = { "1.55",  "1.413",  "CE1",  "2HE",  "CD2",  "Z", };
+     356          16 :   haselmap["HIS_CD2"] = { "1.8",  "1.073",  "NE2",  "CG",  "Z",  "Z", };
+     357          16 :   haselmap["HIS_2HE"] = { "1.1",  "1.128",  "NE2",  "Z",  "Z",  "Z", };
+     358          16 :   haselmap["ILE_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     359          16 :   haselmap["ILE_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     360          16 :   haselmap["ILE_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     361          16 :   haselmap["ILE_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     362          16 :   haselmap["ILE_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     363          16 :   haselmap["ILE_CB"] = { "1.8",  "1.276",  "CA",  "CG2",  "CG1",  "Z", };
+     364          16 :   haselmap["ILE_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     365          16 :   haselmap["ILE_CG1"] = { "1.9",  "1.045",  "CB",  "CD1",  "Z",  "Z", };
+     366          16 :   haselmap["ILE_CD1"] = { "2.0",  "0.88",  "CG1",  "Z",  "Z",  "Z", };
+     367          16 :   haselmap["LEU_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     368          16 :   haselmap["LEU_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     369          16 :   haselmap["LEU_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     370          16 :   haselmap["LEU_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     371          16 :   haselmap["LEU_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     372          16 :   haselmap["LEU_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     373          16 :   haselmap["LEU_CG"] = { "1.8",  "1.276",  "CB",  "CD1",  "CD2",  "Z", };
+     374          16 :   haselmap["LEU_CD1"] = { "2.0",  "0.88",  "CG",  "Z",  "Z",  "Z", };
+     375          16 :   haselmap["LEU_CD2"] = { "2.0",  "0.88",  "CG",  "Z",  "Z",  "Z", };
+     376          16 :   haselmap["LYS_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     377          16 :   haselmap["LYS_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     378          16 :   haselmap["LYS_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     379          16 :   haselmap["LYS_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     380          16 :   haselmap["LYS_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     381          16 :   haselmap["LYS_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     382          16 :   haselmap["LYS_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     383          16 :   haselmap["LYS_CD"] = { "1.9",  "1.045",  "CG",  "CE",  "Z",  "Z", };
+     384          16 :   haselmap["LYS_CE"] = { "1.9",  "1.045",  "CD",  "NZ",  "Z",  "Z", };
+     385          16 :   haselmap["LYS_NZ"] = { "1.6",  "1.215",  "CE",  "1HZ",  "2HZ",  "3HZ", };
+     386          16 :   haselmap["LYS_1HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     387          16 :   haselmap["LYS_2HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     388          16 :   haselmap["LYS_3HZ"] = { "1.1",  "1.128",  "NZ",  "Z",  "Z",  "Z", };
+     389          16 :   haselmap["MET_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     390          16 :   haselmap["MET_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     391          16 :   haselmap["MET_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     392          16 :   haselmap["MET_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     393          16 :   haselmap["MET_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     394          16 :   haselmap["MET_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     395          16 :   haselmap["MET_CG"] = { "1.9",  "1.045",  "CB",  "SD",  "Z",  "Z", };
+     396          16 :   haselmap["MET_SD"] = { "1.8",  "1.121",  "CG",  "CE",  "Z",  "Z", };
+     397          16 :   haselmap["MET_CE"] = { "2.0",  "0.88",  "SD",  "Z",  "Z",  "Z", };
+     398          16 :   haselmap["PHE_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     399          16 :   haselmap["PHE_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     400          16 :   haselmap["PHE_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     401          16 :   haselmap["PHE_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     402          16 :   haselmap["PHE_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     403          16 :   haselmap["PHE_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     404          16 :   haselmap["PHE_CG"] = { "1.72",  "1.554",  "CB",  "CD1",  "CD2",  "Z", };
+     405          16 :   haselmap["PHE_CD1"] = { "1.8",  "1.073",  "CG",  "CE1",  "Z",  "Z", };
+     406          16 :   haselmap["PHE_CE1"] = { "1.8",  "1.073",  "CD1",  "CZ",  "Z",  "Z", };
+     407          16 :   haselmap["PHE_CZ"] = { "1.8",  "1.073",  "CE1",  "CE2",  "Z",  "Z", };
+     408          16 :   haselmap["PHE_CE2"] = { "1.8",  "1.073",  "CZ",  "CD2",  "Z",  "Z", };
+     409          16 :   haselmap["PHE_CD2"] = { "1.8",  "1.073",  "CE2",  "CG",  "Z",  "Z", };
+     410          16 :   haselmap["PRO_N"] = { "1.55",  "1.028",  "CD",  "CA",  "Z",  "Z", };
+     411          16 :   haselmap["PRO_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     412          16 :   haselmap["PRO_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     413          16 :   haselmap["PRO_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     414          16 :   haselmap["PRO_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     415          16 :   haselmap["PRO_CG"] = { "1.9",  "1.045",  "CB",  "CD",  "Z",  "Z", };
+     416          16 :   haselmap["PRO_CD"] = { "1.9",  "1.045",  "CG",  "N",  "Z",  "Z", };
+     417          16 :   haselmap["SER_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     418          16 :   haselmap["SER_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     419          16 :   haselmap["SER_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     420          16 :   haselmap["SER_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     421          16 :   haselmap["SER_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     422          16 :   haselmap["SER_CB"] = { "1.9",  "1.045",  "CA",  "OG",  "Z",  "Z", };
+     423          16 :   haselmap["SER_OG"] = { "1.52",  "1.08",  "CB",  "HG",  "Z",  "Z", };
+     424          16 :   haselmap["SER_HG"] = { "1.0",  "0.944",  "OG",  "Z",  "Z",  "Z", };
+     425          16 :   haselmap["THR_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     426          16 :   haselmap["THR_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     427          16 :   haselmap["THR_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     428          16 :   haselmap["THR_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     429          16 :   haselmap["THR_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     430          16 :   haselmap["THR_CB"] = { "1.8",  "1.276",  "CA",  "CG2",  "OG1",  "Z", };
+     431          16 :   haselmap["THR_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     432          16 :   haselmap["THR_OG1"] = { "1.52",  "1.08",  "1HG",  "CB",  "Z",  "Z", };
+     433          16 :   haselmap["THR_1HG"] = { "1.0",  "0.944",  "OG1",  "Z",  "Z",  "Z", };
+     434          16 :   haselmap["TRP_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     435          16 :   haselmap["TRP_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     436          16 :   haselmap["TRP_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     437          16 :   haselmap["TRP_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     438          16 :   haselmap["TRP_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     439          16 :   haselmap["TRP_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     440          16 :   haselmap["TRP_CG"] = { "1.72",  "1.554",  "CB",  "CD2",  "CD1",  "Z", };
+     441          16 :   haselmap["TRP_CD1"] = { "1.8",  "1.073",  "CG",  "NE1",  "Z",  "Z", };
+     442          16 :   haselmap["TRP_NE1"] = { "1.55",  "1.413",  "CD1",  "CE2",  "1HE",  "Z", };
+     443          16 :   haselmap["TRP_CE2"] = { "1.72",  "1.554",  "NE1",  "CD2",  "CZ2",  "Z", };
+     444          16 :   haselmap["TRP_CZ2"] = { "1.8",  "1.073",  "CE2",  "CH2",  "Z",  "Z", };
+     445          16 :   haselmap["TRP_CH2"] = { "1.8",  "1.073",  "CZ2",  "CZ3",  "Z",  "Z", };
+     446          16 :   haselmap["TRP_CZ3"] = { "1.8",  "1.073",  "CH2",  "CE3",  "Z",  "Z", };
+     447          16 :   haselmap["TRP_CE3"] = { "1.8",  "1.073",  "CZ3",  "CD2",  "Z",  "Z", };
+     448          16 :   haselmap["TRP_CD2"] = { "1.72",  "1.554",  "CE3",  "CE2",  "CG",  "Z", };
+     449          16 :   haselmap["TRP_1HE"] = { "1.1",  "1.128",  "NE1",  "Z",  "Z",  "Z", };
+     450          16 :   haselmap["TYR_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     451          16 :   haselmap["TYR_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     452          16 :   haselmap["TYR_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     453          16 :   haselmap["TYR_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     454          16 :   haselmap["TYR_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     455          16 :   haselmap["TYR_CB"] = { "1.9",  "1.045",  "CA",  "CG",  "Z",  "Z", };
+     456          16 :   haselmap["TYR_CG"] = { "1.72",  "1.554",  "CB",  "CD1",  "CD2",  "Z", };
+     457          16 :   haselmap["TYR_CD1"] = { "1.8",  "1.073",  "CG",  "CE1",  "Z",  "Z", };
+     458          16 :   haselmap["TYR_CE1"] = { "1.8",  "1.073",  "CD1",  "CZ",  "Z",  "Z", };
+     459          16 :   haselmap["TYR_CZ"] = { "1.72",  "1.554",  "CE1",  "OH",  "CE2",  "Z", };
+     460          16 :   haselmap["TYR_OH"] = { "1.52",  "1.08",  "CZ",  "HH",  "Z",  "Z", };
+     461          16 :   haselmap["TYR_HH"] = { "1.0",  "0.944",  "OH",  "Z",  "Z",  "Z", };
+     462          16 :   haselmap["TYR_CE2"] = { "1.8",  "1.073",  "CZ",  "CD2",  "Z",  "Z", };
+     463          16 :   haselmap["TYR_CD2"] = { "1.8",  "1.073",  "CE2",  "CG",  "Z",  "Z", };
+     464          16 :   haselmap["VAL_N"] = { "1.55",  "1.028",  "H",  "CA",  "Z",  "Z", };
+     465          16 :   haselmap["VAL_CA"] = { "1.7",  "2.149",  "N",  "C",  "CB",  "Z", };
+     466          16 :   haselmap["VAL_C"] = { "1.72",  "1.554",  "CA",  "O",  "Z",  "Z", };
+     467          16 :   haselmap["VAL_O"] = { "1.5",  "0.926",  "C",  "Z",  "Z",  "Z", };
+     468          16 :   haselmap["VAL_H"] = { "1.1",  "1.128",  "N",  "Z",  "Z",  "Z", };
+     469          16 :   haselmap["VAL_CB"] = { "1.8",  "1.276",  "CA",  "CG1",  "CG2",  "Z", };
+     470          16 :   haselmap["VAL_CG1"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     471          16 :   haselmap["VAL_CG2"] = { "2.0",  "0.88",  "CB",  "Z",  "Z",  "Z", };
+     472           2 :   return haselmap;
+     473             : }
+     474             : 
+     475             : //assigns SASA parameters to each atom reading from HASEL parameter database
+     476           2 : void SASA_HASEL::readSASAparam() {
+     477             : 
+     478         242 :   for(unsigned i=0; i<natoms; i++) {
+     479         240 :     SASAparam[i].clear();
+     480             :     CONNECTparam[i].clear();
+     481             :   }
+     482             : 
+     483             :   map<string, vector<std::string> > haselmap;
+     484           4 :   haselmap = setupHASELparam();
+     485             :   vector<std::string> HASELparamVector;
+     486             :   string identifier;
+     487             : 
+     488             : 
+     489         242 :   for(unsigned i=0; i<natoms; i++) {
+     490         480 :     identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+     491         240 :     if (haselmap.find(identifier)!=haselmap.end()) {
+     492         144 :       HASELparamVector = haselmap.at(identifier);
+     493         144 :       SASAparam[i].push_back (std::atof(HASELparamVector[0].c_str())+rs*10);
+     494         144 :       SASAparam[i].push_back (std::atof(HASELparamVector[1].c_str()));
+     495         288 :       CONNECTparam[i].push_back (HASELparamVector[2].c_str());
+     496         288 :       CONNECTparam[i].push_back (HASELparamVector[3].c_str());
+     497         288 :       CONNECTparam[i].push_back (HASELparamVector[4].c_str());
+     498         288 :       CONNECTparam[i].push_back (HASELparamVector[5].c_str());
+     499             :     }
+     500             :   }
+     501             : 
+     502             : 
+     503         242 :   for(unsigned i=0; i<natoms; i++) {
+     504         240 :     if (SASAparam[i].size()==0 ) {
+     505          96 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     506           0 :         cout << "Could not find SASA paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << endl;
+     507           0 :         error ("missing SASA parameters\n");
+     508             :       }
+     509             :     }
+     510             :   }
+     511             : 
+     512             : 
+     513           4 : }
+     514             : 
+     515             : 
+     516             : 
+     517             : //Max Surf values, used only if TYPE=TRANSFER
+     518           1 : map<string, vector<double> > SASA_HASEL::setupMaxSurfMap() {
+     519             :   // Max Surface Area for backbone and sidechain, in nm2
+     520             :   map<string, vector<double> > valuemap;
+     521           1 :   valuemap ["ALA"]= {0.56425,0.584851,};
+     522           1 :   valuemap ["ARG"]= {0.498656,1.808093,};
+     523           1 :   valuemap ["ASN"]= {0.473409,0.818394,};
+     524           1 :   valuemap ["ASP"]= {0.477057,0.977303,};
+     525           1 :   valuemap ["CYS"]= {0.507512,0.791483,};
+     526           1 :   valuemap ["GLN"]= {0.485859,1.281534,};
+     527           1 :   valuemap ["GLU"]= {0.495054,1.464718,};
+     528           1 :   valuemap ["GLY"]= {0.658632,0,};
+     529           1 :   valuemap ["HIS"]= {0.48194,1.118851,};
+     530           1 :   valuemap ["ILE"]= {0.461283,1.450569,};
+     531           1 :   valuemap ["LEU"]= {0.476315,1.498843,};
+     532           1 :   valuemap ["LYS"]= {0.493533,1.619731,};
+     533           1 :   valuemap ["MET"]= {0.507019,1.631904,};
+     534           1 :   valuemap ["PHE"]= {0.457462, 1.275125,};
+     535           1 :   valuemap ["PRO"]= {0.315865,0.859456,};
+     536           1 :   valuemap ["SER"]= {0.48636,0.627233,};
+     537           1 :   valuemap ["THR"]= {0.45064,0.91088,};
+     538           1 :   valuemap ["TRP"]= {0.45762,1.366369,};
+     539           1 :   valuemap ["TYR"]= {0.461826,1.425822,};
+     540           1 :   valuemap ["VAL"]= {0.477054,1.149101,};
+     541           1 :   return valuemap;
+     542             : }
+     543             : 
+     544             : 
+     545             : 
+     546             : //reads maximum surface values per residue type and assigns values to each atom, only used if sasa_type = TRANSFER
+     547             : 
+     548           1 : void SASA_HASEL::readMaxSurf() {
+     549             :   map<string, vector<double> > valuemap;
+     550           2 :   valuemap = setupMaxSurfMap();
+     551             :   vector<double> MaxSurfVector;
+     552             : 
+     553         121 :   for(unsigned i=0; i<natoms; i++) {
+     554         120 :     MaxSurf[i].clear();
+     555         120 :     MaxSurfVector = valuemap.at(AtomResidueName[1][i]);
+     556         120 :     MaxSurf[i].push_back (MaxSurfVector[0]*100);
+     557         120 :     MaxSurf[i].push_back (MaxSurfVector[1]*100);
+     558             :   }
+     559           1 : }
+     560             : 
+     561             : //reads file with free energy values for sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER
+     562             : 
+     563           1 : void SASA_HASEL::readDeltaG() {
+     564             : 
+     565         121 :   for(unsigned i=0; i<natoms; i++) {
+     566         120 :     DeltaG[i].clear();
+     567             :   }
+     568             : 
+     569             :   string DeltaGline;
+     570           1 :   fstream DeltaGFile;
+     571           1 :   DeltaGFile.open(DeltaGValues);
+     572           1 :   if (DeltaGFile) {
+     573             :     int backboneflag = 0;
+     574          23 :     while(getline(DeltaGFile, DeltaGline)) {
+     575          22 :       if(!DeltaGline.empty()) {
+     576             :         std::vector<std::string> DeltaGtoken;
+     577          21 :         split(DeltaGline, DeltaGtoken);
+     578        2541 :         for(unsigned i=0; i<natoms; i++) {
+     579        2520 :           if (DeltaGtoken[0].compare(AtomResidueName[1][i])==0 ) {
+     580         120 :             DeltaG[i].push_back (std::atof(DeltaGtoken[1].c_str()));
+     581             :           }
+     582             :         }
+     583          21 :         if (DeltaGtoken[0].compare("BACKBONE")==0 ) {
+     584             :           backboneflag = 1;
+     585           1 :           DeltaG[natoms].push_back (std::atof(DeltaGtoken[1].c_str()));
+     586             :         }
+     587          21 :       }
+     588             :     }
+     589           1 :     if ( backboneflag == 0) error("Cannot find backbone value in Delta G parameters file\n");
+     590             :   }
+     591           0 :   else error("Cannot open DeltaG file");
+     592             : 
+     593         121 :   for(unsigned i=0; i<natoms; i++) {
+     594         120 :     if (DeltaG[i].size()==0 ) {
+     595           0 :       cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     596           0 :       error ("missing Delta G parameter\n");
+     597             :     }
+     598             :   }
+     599             : 
+     600           2 : }
+     601             : 
+     602             : //computes free energy values for the sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER, and if no DELTAGFILE is provided. In this case, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, JPCB, 2021) needs to be used to compute them.
+     603             : 
+     604           0 : void SASA_HASEL::computeDeltaG() {
+     605             : 
+     606           0 :   for(unsigned i=0; i<natoms; i++) {
+     607           0 :     DeltaG[i].clear();
+     608             :   }
+     609             : 
+     610             :   double T;
+     611           0 :   T = getkBT()/getKBoltzmann();
+     612             : 
+     613           0 :   if (T != Ti) {
+     614           0 :     for(unsigned i=0; i<natoms; i++) {
+     615           0 :       if (approach==2) {
+     616           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     617           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.895);
+     618             :         }
+     619           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     620           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-282.032);
+     621             :         }
+     622           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     623           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-87.846);
+     624             :         }
+     625           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     626           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-16.526);
+     627             :         }
+     628           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     629           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-272.26);
+     630             :         }
+     631           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     632           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-199.707);
+     633             :         }
+     634           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     635           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-131.168);
+     636             :         }
+     637           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     638           0 :           DeltaG[i].push_back (0);
+     639             :         }
+     640           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     641           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-311.694);
+     642             :         }
+     643           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     644           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-567.444);
+     645             :         }
+     646           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     647           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-653.394);
+     648             :         }
+     649           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     650           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-185.549);
+     651             :         }
+     652           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     653           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.007);
+     654             :         }
+     655           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     656           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-688.874);
+     657             :         }
+     658           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     659           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-212.059);
+     660             :         }
+     661           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     662           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+151.957);
+     663             :         }
+     664           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     665           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-239.516);
+     666             :         }
+     667           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     668           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1025.293);
+     669             :         }
+     670           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     671           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-667.261);
+     672             :         }
+     673           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     674           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-435.309);
+     675             :         }
+     676           0 :         DeltaG[natoms].push_back (-0.6962/1000*std::pow(T,2)+0.4426*T-70.015);
+     677             :       }
+     678           0 :       if (approach==3) {
+     679           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     680           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.105);
+     681             :         }
+     682           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     683           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-284.086);
+     684             :         }
+     685           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     686           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-90.597);
+     687             :         }
+     688           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     689           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-19.143);
+     690             :         }
+     691           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     692           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-268.527);
+     693             :         }
+     694           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     695           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-201.559);
+     696             :         }
+     697           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     698           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-133.543);
+     699             :         }
+     700           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     701           0 :           DeltaG[i].push_back (0);
+     702             :         }
+     703           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     704           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-315.398);
+     705             :         }
+     706           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     707           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-564.825);
+     708             :         }
+     709           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     710           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-651.483);
+     711             :         }
+     712           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     713           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-187.485);
+     714             :         }
+     715           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     716           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.242);
+     717             :         }
+     718           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     719           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-687.134);
+     720             :         }
+     721           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     722           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-214.211);
+     723             :         }
+     724           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     725           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+150.289);
+     726             :         }
+     727           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     728           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-240.267);
+     729             :         }
+     730           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     731           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1024.284);
+     732             :         }
+     733           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     734           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-666.484);
+     735             :         }
+     736           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     737           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-433.013);
+     738             :         }
+     739           0 :         DeltaG[natoms].push_back (-0.6927/1000*std::pow(T,2)+0.4404*T-68.724);
+     740             :       }
+     741             :     }
+     742             :   }
+     743             : 
+     744           0 :   Ti = T;
+     745             : 
+     746           0 :   if (firstStepFlag ==0) {
+     747           0 :     if (approach!=2 && approach!=3) {
+     748           0 :       cout << "Unknown approach " << approach << endl;
+     749             :     }
+     750           0 :     for(unsigned i=0; i<natoms; i++) {
+     751           0 :       if (DeltaG[i].size()==0 ) {
+     752           0 :         cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     753           0 :         error ("missing Delta G parameter\n");
+     754             :       }
+     755             :     }
+     756             :   }
+     757           0 : }
+     758             : 
+     759             : 
+     760             : //calculates neighbor list
+     761          24 : void SASA_HASEL::calcNlist() {
+     762          24 :   if(!nopbc) makeWhole();
+     763             : 
+     764        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     765        2880 :     Nlist[i].clear();
+     766             :   }
+     767             : 
+     768        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     769        2880 :     if (SASAparam[i].size()>0) {
+     770      103680 :       for (unsigned j = 0; j < i; j++) {
+     771      101952 :         if (SASAparam[j].size()>0) {
+     772       61344 :           const Vector Delta_ij_vec = delta( getPosition(i), getPosition(j) );
+     773       61344 :           double Delta_ij_mod = Delta_ij_vec.modulo()*10;
+     774       61344 :           double overlapD = SASAparam[i][0]+SASAparam[j][0];
+     775       61344 :           if (Delta_ij_mod < overlapD) {
+     776       26748 :             Nlist.at(i).push_back (j);
+     777       26748 :             Nlist.at(j).push_back (i);
+     778             :           }
+     779             :         }
+     780             :       }
+     781             :     }
+     782             :   }
+     783          24 : }
+     784             : 
+     785             : 
+     786             : //calculates SASA according to Hasel et al., Tetrahedron Computer Methodology Vol. 1, No. 2, pp. 103-116, 1988
+     787          24 : void SASA_HASEL::calculate() {
+     788          24 :   if(!nopbc) makeWhole();
+     789             : 
+     790          24 :   if(getExchangeStep()) nl_update = 0;
+     791          24 :   if (firstStepFlag ==0) {
+     792           2 :     readPDB();
+     793           2 :     readSASAparam();
+     794             :   }
+     795          24 :   if (nl_update == 0) {
+     796          24 :     calcNlist();
+     797             :   }
+     798             : 
+     799             : 
+     800          24 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     801          24 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     802             :   double Si, sasai, bij;
+     803          24 :   double sasa = 0;
+     804          24 :   vector<Vector> derivatives( natoms );
+     805        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     806        2880 :     derivatives[i][0] = 0.;
+     807        2880 :     derivatives[i][1] = 0.;
+     808        2880 :     derivatives[i][2] = 0.;
+     809             :   }
+     810             : 
+     811          24 :   Tensor virial;
+     812          24 :   vector <double> ddij_di(3);
+     813          24 :   vector <double> dbij_di(3);
+     814          24 :   vector <double> dAijt_di(3);
+     815             : 
+     816          24 :   if( sasa_type==TOTAL ) {
+     817        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     818        1440 :       if(SASAparam[i].size() > 0) {
+     819         864 :         double ri = SASAparam[i][0];
+     820         864 :         Si = 4*M_PI*ri*ri;
+     821             :         sasai = 1.0;
+     822             : 
+     823        1728 :         vector <vector <double> > derTerm( Nlist[i].size(), vector <double>(3));
+     824             : 
+     825         864 :         dAijt_di[0] = 0;
+     826         864 :         dAijt_di[1] = 0;
+     827         864 :         dAijt_di[2] = 0;
+     828         864 :         int NumRes_i = moldat->getResidueNumber(atoms[i]);
+     829             : 
+     830       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     831             :           double pij = 0.3516;
+     832             : 
+     833       26748 :           int NumRes_j = moldat->getResidueNumber(atoms[Nlist[i][j]]);
+     834       26748 :           if (NumRes_i==NumRes_j) {
+     835        4320 :             if (CONNECTparam[i][0].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][1].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][2].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][3].compare(AtomResidueName[0][Nlist[i][j]])==0) {
+     836             :               pij = 0.8875;
+     837             :             }
+     838             :           }
+     839       26748 :           if ( abs(NumRes_i-NumRes_j) == 1 ) {
+     840       10380 :             if ((AtomResidueName[0][i] == "N"  && AtomResidueName[0][Nlist[i][j]]== "CA") || (AtomResidueName[0][Nlist[i][j]] == "N"  && AtomResidueName[0][i]== "CA")) {
+     841             :               pij = 0.8875;
+     842             :             }
+     843             :           }
+     844             : 
+     845       26748 :           const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     846       26748 :           double d_ij = d_ij_vec.modulo()*10;
+     847             : 
+     848       26748 :           double rj = SASAparam[Nlist[i][j]][0];
+     849       26748 :           bij = M_PI*ri*(ri+rj-d_ij)*(1+(rj-ri)/d_ij); //Angstrom2
+     850             : 
+     851       26748 :           sasai = sasai*(1-SASAparam[i][1]*pij*bij/Si); //nondimensional
+     852             : 
+     853       26748 :           ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij; //nondimensional
+     854       26748 :           ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     855       26748 :           ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     856             : 
+     857       26748 :           dbij_di[0] = -M_PI*ri*ddij_di[0]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij)); //Angstrom
+     858       26748 :           dbij_di[1] = -M_PI*ri*ddij_di[1]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     859       26748 :           dbij_di[2] = -M_PI*ri*ddij_di[2]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     860             : 
+     861       26748 :           dAijt_di[0] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     862       26748 :           dAijt_di[1] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     863       26748 :           dAijt_di[2] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     864             : 
+     865       26748 :           derTerm[j][0] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     866       26748 :           derTerm[j][1] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     867       26748 :           derTerm[j][2] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     868             : 
+     869             :         }
+     870             : 
+     871         864 :         sasa += Si*sasai/100; //nm2
+     872             : 
+     873         864 :         derivatives[i][0] += Si*sasai/10*dAijt_di[0]; //nm
+     874         864 :         derivatives[i][1] += Si*sasai/10*dAijt_di[1];
+     875         864 :         derivatives[i][2] += Si*sasai/10*dAijt_di[2];
+     876             : 
+     877       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     878       26748 :           derivatives[Nlist[i][j]][0] += Si*sasai/10*derTerm[j][0]; //nm
+     879       26748 :           derivatives[Nlist[i][j]][1] += Si*sasai/10*derTerm[j][1];
+     880       26748 :           derivatives[Nlist[i][j]][2] += Si*sasai/10*derTerm[j][2];
+     881             :         }
+     882         864 :       }
+     883             :     }
+     884             :   }
+     885             : 
+     886             : 
+     887          24 :   if( sasa_type==TRANSFER ) {
+     888             : 
+     889          12 :     if (firstStepFlag ==0) {
+     890           1 :       readMaxSurf();
+     891             :     }
+     892             : 
+     893          12 :     if (firstStepFlag ==0 && DeltaGValues != "absent") {
+     894           1 :       readDeltaG();
+     895             :     }
+     896             : 
+     897          12 :     if (DeltaGValues == "absent") {
+     898           0 :       computeDeltaG();
+     899             :     }
+     900             : 
+     901             : 
+     902        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     903             : 
+     904             : 
+     905             : 
+     906        1440 :       if(SASAparam[i].size() > 0) {
+     907         864 :         double ri = SASAparam[i][0];
+     908         864 :         Si = 4*M_PI*ri*ri;
+     909             :         sasai = 1.0;
+     910             : 
+     911        1728 :         vector <vector <double> > derTerm( Nlist[i].size(), vector <double>(3));
+     912             : 
+     913         864 :         dAijt_di[0] = 0;
+     914         864 :         dAijt_di[1] = 0;
+     915         864 :         dAijt_di[2] = 0;
+     916         864 :         int NumRes_i = moldat->getResidueNumber(atoms[i]);
+     917             : 
+     918       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     919             :           double pij = 0.3516;
+     920             : 
+     921       26748 :           int NumRes_j = moldat->getResidueNumber(atoms[Nlist[i][j]]);
+     922       26748 :           if (NumRes_i==NumRes_j) {
+     923        4320 :             if (CONNECTparam[i][0].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][1].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][2].compare(AtomResidueName[0][Nlist[i][j]])==0 || CONNECTparam[i][3].compare(AtomResidueName[0][Nlist[i][j]])==0) {
+     924             :               pij = 0.8875;
+     925             :             }
+     926             :           }
+     927       26748 :           if ( abs(NumRes_i-NumRes_j) == 1 ) {
+     928       10380 :             if ((AtomResidueName[0][i] == "N"  && AtomResidueName[0][Nlist[i][j]]== "CA") || (AtomResidueName[0][Nlist[i][j]] == "N"  && AtomResidueName[0][i]== "CA")) {
+     929             :               pij = 0.8875;
+     930             :             }
+     931             :           }
+     932             : 
+     933       26748 :           const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     934       26748 :           double d_ij = d_ij_vec.modulo()*10;
+     935             : 
+     936       26748 :           double rj = SASAparam[Nlist[i][j]][0];
+     937       26748 :           bij = M_PI*ri*(ri+rj-d_ij)*(1+(rj-ri)/d_ij); //Angstrom2
+     938             : 
+     939       26748 :           sasai = sasai*(1-SASAparam[i][1]*pij*bij/Si); //nondimensional
+     940             : 
+     941       26748 :           ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij; //nondimensional
+     942       26748 :           ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     943       26748 :           ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     944             : 
+     945       26748 :           dbij_di[0] = -M_PI*ri*ddij_di[0]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij)); //Angstrom
+     946       26748 :           dbij_di[1] = -M_PI*ri*ddij_di[1]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     947       26748 :           dbij_di[2] = -M_PI*ri*ddij_di[2]*(1+(ri+rj)*(rj-ri)/(d_ij*d_ij));
+     948             : 
+     949       26748 :           dAijt_di[0] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     950       26748 :           dAijt_di[1] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     951       26748 :           dAijt_di[2] += -1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     952             : 
+     953       26748 :           derTerm[j][0] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[0]; //Angstrom-1
+     954       26748 :           derTerm[j][1] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[1];
+     955       26748 :           derTerm[j][2] = 1/(Si/(SASAparam[i][1]*pij)-bij)*dbij_di[2];
+     956             : 
+     957             :         }
+     958             : 
+     959        2880 :         if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O" || AtomResidueName[0][i] == "H") {
+     960             : 
+     961         720 :           sasa += Si*sasai/MaxSurf[i][0]*DeltaG[natoms][0]; //kJ/mol
+     962             : 
+     963             : 
+     964         720 :           derivatives[i][0] += Si*sasai*dAijt_di[0]/MaxSurf[i][0]*DeltaG[natoms][0]*10; //kJ/mol/nm
+     965         720 :           derivatives[i][1] += Si*sasai*dAijt_di[1]/MaxSurf[i][0]*DeltaG[natoms][0]*10;
+     966         720 :           derivatives[i][2] += Si*sasai*dAijt_di[2]/MaxSurf[i][0]*DeltaG[natoms][0]*10;
+     967             :         }
+     968             : 
+     969        2880 :         if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O" && AtomResidueName[0][i] != "H") {
+     970         144 :           sasa += Si*sasai/MaxSurf[i][1]*DeltaG[i][0]; //kJ/mol
+     971             : 
+     972         144 :           derivatives[i][0] += Si*sasai*dAijt_di[0]/MaxSurf[i][1]*DeltaG[i][0]*10; //kJ/mol/nm
+     973         144 :           derivatives[i][1] += Si*sasai*dAijt_di[1]/MaxSurf[i][1]*DeltaG[i][0]*10;
+     974         144 :           derivatives[i][2] += Si*sasai*dAijt_di[2]/MaxSurf[i][1]*DeltaG[i][0]*10;
+     975             :         }
+     976             : 
+     977             : 
+     978       27612 :         for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     979       86883 :           if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O" || AtomResidueName[0][i] == "H") {
+     980       22438 :             derivatives[Nlist[i][j]][0] += Si*sasai*10*derTerm[j][0]/MaxSurf[i][0]*DeltaG[natoms][0]; //kJ/mol/nm
+     981       22438 :             derivatives[Nlist[i][j]][1] += Si*sasai*10*derTerm[j][1]/MaxSurf[i][0]*DeltaG[natoms][0];
+     982       22438 :             derivatives[Nlist[i][j]][2] += Si*sasai*10*derTerm[j][2]/MaxSurf[i][0]*DeltaG[natoms][0];
+     983             :           }
+     984             : 
+     985       86883 :           if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O" && AtomResidueName[0][i] != "H") {
+     986        4310 :             derivatives[Nlist[i][j]][0] += Si*sasai*10*derTerm[j][0]/MaxSurf[i][1]*DeltaG[i][0]; //kJ/mol/nm
+     987        4310 :             derivatives[Nlist[i][j]][1] += Si*sasai*10*derTerm[j][1]/MaxSurf[i][1]*DeltaG[i][0];
+     988        4310 :             derivatives[Nlist[i][j]][2] += Si*sasai*10*derTerm[j][2]/MaxSurf[i][1]*DeltaG[i][0];
+     989             :           }
+     990             :         }
+     991         864 :       }
+     992             :     }
+     993             :   }
+     994             : 
+     995             : 
+     996        2904 :   for(unsigned i=0; i<natoms; i++) {
+     997        2880 :     setAtomsDerivatives(i,derivatives[i]);
+     998        2880 :     virial -= Tensor(getPosition(i),derivatives[i]);
+     999             :   }
+    1000             : 
+    1001          24 :   setBoxDerivatives(virial);
+    1002          24 :   setValue(sasa);
+    1003          24 :   firstStepFlag = 1;
+    1004          24 :   ++nl_update;
+    1005          24 :   if (nl_update == stride) {
+    1006          24 :     nl_update = 0;
+    1007             :   }
+    1008             : // setBoxDerivativesNoPbc();
+    1009          24 : }
+    1010             : 
+    1011             : }//namespace sasa
+    1012             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_LCPO.cpp.func-sort-c.html b/coverage/sasa/sasa_LCPO.cpp.func-sort-c.html new file mode 100644 index 000000000000..650f6ed2101c --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_LCPO.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_LCPO.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51863082.2 %
Date:2024-02-22 21:58:45Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_0
_ZN4PLMD4sasa9SASA_LCPO13computeDeltaGEv0
_ZN4PLMD4sasa9SASA_LCPOC2ERKNS_13ActionOptionsE0
_ZN4PLMD4sasa9SASA_LCPO10readDeltaGEv1
_ZN4PLMD4sasa9SASA_LCPO11readMaxSurfEv1
_ZN4PLMD4sasa9SASA_LCPO15setupMaxSurfMapB5cxx11Ev1
_ZN4PLMD4sasa9SASA_LCPO13readLCPOparamEv2
_ZN4PLMD4sasa9SASA_LCPO14setupLCPOparamB5cxx11Ev2
_ZN4PLMD4sasa9SASA_LCPO7readPDBEv2
_ZN4PLMD4sasa9SASA_LCPOC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa9SASA_LCPO16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4sasa9SASA_LCPO9calcNlistEv24
_ZN4PLMD4sasa9SASA_LCPO9calculateEv24
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_LCPO.cpp.func.html b/coverage/sasa/sasa_LCPO.cpp.func.html new file mode 100644 index 000000000000..2fb0be768f87 --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_LCPO.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_LCPO.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51863082.2 %
Date:2024-02-22 21:58:45Functions:101376.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4sasa5splitISt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEEEvRKS8_RT_0
_ZN4PLMD4sasa9SASA_LCPO10readDeltaGEv1
_ZN4PLMD4sasa9SASA_LCPO11readMaxSurfEv1
_ZN4PLMD4sasa9SASA_LCPO13computeDeltaGEv0
_ZN4PLMD4sasa9SASA_LCPO13readLCPOparamEv2
_ZN4PLMD4sasa9SASA_LCPO14setupLCPOparamB5cxx11Ev2
_ZN4PLMD4sasa9SASA_LCPO15setupMaxSurfMapB5cxx11Ev1
_ZN4PLMD4sasa9SASA_LCPO16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD4sasa9SASA_LCPO7readPDBEv2
_ZN4PLMD4sasa9SASA_LCPO9calcNlistEv24
_ZN4PLMD4sasa9SASA_LCPO9calculateEv24
_ZN4PLMD4sasa9SASA_LCPOC1ERKNS_13ActionOptionsE2
_ZN4PLMD4sasa9SASA_LCPOC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/sasa/sasa_LCPO.cpp.gcov.html b/coverage/sasa/sasa_LCPO.cpp.gcov.html new file mode 100644 index 000000000000..3dd2a085d32b --- /dev/null +++ b/coverage/sasa/sasa_LCPO.cpp.gcov.html @@ -0,0 +1,1157 @@ + + + + + + + + LCOV - plumed test coverage - sasa/sasa_LCPO.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - sasa - sasa_LCPO.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:51863082.2 %
Date:2024-02-22 21:58:45Functions:101376.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             : Copyright (c) 2021, Andrea Arsiccio
+       3             : 
+       4             : This software is provided 'as-is', without any express or implied
+       5             : warranty. In no event will the authors be held liable for any damages
+       6             : arising from the use of this software.
+       7             : 
+       8             : Permission is granted to anyone to use this software for any purpose,
+       9             : including commercial applications, and to alter it and redistribute it
+      10             : freely, subject to the following restrictions:
+      11             : 
+      12             : 1. The origin of this software must not be misrepresented; you must not
+      13             :    claim that you wrote the original software. If you use this software
+      14             :    in a product, an acknowledgment in the product documentation would be
+      15             :    appreciated but is not required.
+      16             : 2. Altered source versions must be plainly marked as such, and must not be
+      17             :    misrepresented as being the original software.
+      18             : 3. This notice may not be removed or altered from any source distribution.
+      19             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      20             : 
+      21             : #include "Sasa.h"
+      22             : #include "core/ActionRegister.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/GenericMolInfo.h"
+      25             : #include "core/ActionSet.h"
+      26             : #include <cstdio>
+      27             : #include <iostream>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : #include <sstream>
+      31             : #include <algorithm>
+      32             : #include <iterator>
+      33             : #include <fstream>
+      34             : 
+      35             : 
+      36             : using namespace std;
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace sasa {
+      40             : 
+      41             : //+PLUMEDOC SASAMOD_COLVAR SASA_LCPO
+      42             : /*
+      43             : Calculates the solvent accessible surface area (SASA) of a protein molecule, or other properties related to it.
+      44             : 
+      45             : The atoms for which the SASA is desired should be indicated with the keyword ATOMS, and a pdb file of the protein must be provided in input with the MOLINFO keyword. The LCPO algorithm is used for the calculation (please, read and cite \cite Weiser1999). The radius of the solvent is assumed to be 0.14 nm, which is the radius of water molecules. Using the keyword NL_STRIDE it is also possible to specify the frequency with which the neighbor list for the calculation of the SASA is updated (the default is every 10 steps).
+      46             : 
+      47             : Different properties can be calculated and selected using the TYPE keyword:
+      48             : 
+      49             : 1) the total SASA (TOTAL);
+      50             : 
+      51             : 2) the free energy of transfer for the protein according to the transfer model (TRANSFER). This keyword can be used, for instance, to compute the transfer of a protein to different temperatures, as detailed in \cite Arsiccio-T-SASA-2021, or to different pressures, as detailed in \cite Arsiccio-P-SASA-2021, or to different osmolyte solutions, as detailed in \cite Arsiccio-C-SASA-2022.
+      52             : 
+      53             : 
+      54             : When the TRANSFER keyword is used, a file with the free energy of transfer values for the sidechains and backbone atoms should be provided (using the keyword DELTAGFILE). Such file should have the following format:
+      55             : 
+      56             : \verbatim
+      57             : ----------------Sample DeltaG.dat file---------------------
+      58             : ALA     0.711019999999962
+      59             : ARG     -2.24832799999996
+      60             : ASN     -2.74838799999999
+      61             : ASP     -2.5626376
+      62             : CYS     3.89864000000006
+      63             : GLN     -1.76192
+      64             : GLU     -2.38664400000002
+      65             : GLY     0
+      66             : HIS     -3.58152799999999
+      67             : ILE     2.42634399999986
+      68             : LEU     1.77233599999988
+      69             : LYS     -1.92576400000002
+      70             : MET     -0.262827999999956
+      71             : PHE     1.62028800000007
+      72             : PRO     -2.15598800000001
+      73             : SER     -1.60934800000004
+      74             : THR     -0.591559999999987
+      75             : TRP     1.22936000000027
+      76             : TYR     0.775547999999958
+      77             : VAL     2.12779200000011
+      78             : BACKBONE        1.00066920000002
+      79             : -----------------------------------------------------------
+      80             : \endverbatim
+      81             : 
+      82             : where the second column is the free energy of transfer for each sidechain/backbone, in kJ/mol.
+      83             : 
+      84             : A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure (according to \cite Arsiccio-C-SASA-2022, \cite Arsiccio-T-SASA-2021 and \cite Arsiccio-P-SASA-2021) is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module.
+      85             : 
+      86             : If the DELTAGFILE is not provided, the program computes the free energy of transfer values as if they had to take into account the effect of temperature according to approaches 2 or 3 in the paper \cite Arsiccio-T-SASA-2021. Please read and cite this paper if using the transfer model for computing the effect of temperature in implicit solvent simulations. For this purpose, the keyword APPROACH should be added, and set to either 2 or 3.
+      87             : 
+      88             : The SASA usually makes sense when atoms used for the calculation are all part of the same molecule. When running with periodic boundary conditions, the atoms should be in the proper periodic image. This is done automatically since PLUMED 2.2, by considering the ordered list of atoms and rebuilding the broken entities using a procedure that is equivalent to that done in \ref WHOLEMOLECULES. Notice that rebuilding is local to this action. This is different from \ref WHOLEMOLECULES which actually modifies the coordinates stored in PLUMED.
+      89             : 
+      90             : In case you want to recover the old behavior you should use the NOPBC flag.
+      91             : In that case you need to take care that atoms are in the correct periodic image.
+      92             : 
+      93             : The SASA may also be computed using the SASA_HASEL collective variable, which makes use of the algorithm described in \cite Hasel1988. SASA_HASEL is less accurate then SASA_LCPO, but the computation is faster.
+      94             : 
+      95             : 
+      96             : 
+      97             : \par Examples
+      98             : 
+      99             : The following input tells plumed to print the total SASA for atoms 10 to 20 in a protein chain.
+     100             : \plumedfile
+     101             : SASA_LCPO TYPE=TOTAL ATOMS=10-20 NL_STRIDE=10 LABEL=sasa
+     102             : PRINT ARG=sasa STRIDE=1 FILE=colvar
+     103             : \endplumedfile
+     104             : 
+     105             : 
+     106             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are read from a file called DeltaG.dat.
+     107             : 
+     108             : \plumedfile
+     109             : SASA_LCPO TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 DELTAGFILE=DeltaG.dat LABEL=sasa
+     110             : 
+     111             : bias: BIASVALUE ARG=sasa
+     112             : 
+     113             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     114             : \endplumedfile
+     115             : 
+     116             : The following input tells plumed to compute the transfer free energy for the protein chain containing atoms 10 to 20. Such transfer free energy is then used as a bias in the simulation (e.g., implicit solvent simulations). The free energy of transfer values are computed according to \cite Arsiccio-T-SASA-2021, and take into account the effect of temperature using approach 2 as described in the paper.
+     117             : 
+     118             : \plumedfile
+     119             : SASA_LCPO TYPE=TRANSFER ATOMS=10-20 NL_STRIDE=10 APPROACH=2 LABEL=sasa
+     120             : 
+     121             : bias: BIASVALUE ARG=sasa
+     122             : 
+     123             : PRINT ARG=sasa,bias.* STRIDE=1 FILE=colvar
+     124             : \endplumedfile
+     125             : 
+     126             : */
+     127             : //+ENDPLUMEDOC
+     128             : 
+     129             : class SASA_LCPO : public Colvar {
+     130             : private:
+     131             :   enum CV_TYPE {TOTAL, TRANSFER};
+     132             :   int sasa_type;
+     133             :   bool nopbc;
+     134             :   double rs;
+     135             :   string DeltaGValues;
+     136             :   int approach;
+     137             :   unsigned stride;
+     138             :   unsigned nl_update;
+     139             :   int firstStepFlag;
+     140             :   double Ti;
+     141             :   // cppcheck-suppress duplInheritedMember
+     142             :   std::vector<AtomNumber> atoms;
+     143             :   vector < vector < std::string > > AtomResidueName;
+     144             :   vector < vector < double > > LCPOparam;
+     145             :   unsigned natoms;
+     146             :   vector < vector < double > > MaxSurf;
+     147             :   vector < vector < double > > DeltaG;
+     148             :   vector < vector < int > > Nlist;
+     149             : public:
+     150             :   static void registerKeywords(Keywords& keys);
+     151             :   explicit SASA_LCPO(const ActionOptions&);
+     152             :   void readPDB();
+     153             :   map<string, vector<double> > setupLCPOparam();
+     154             :   void readLCPOparam();
+     155             :   void calcNlist();
+     156             :   map<string, vector<double> > setupMaxSurfMap();
+     157             :   void readMaxSurf();
+     158             :   void readDeltaG();
+     159             :   void computeDeltaG();
+     160             :   virtual void calculate();
+     161             : };
+     162             : 
+     163             : PLUMED_REGISTER_ACTION(SASA_LCPO,"SASA_LCPO")
+     164             : 
+     165           4 : void SASA_LCPO::registerKeywords(Keywords& keys) {
+     166           4 :   Colvar::registerKeywords(keys);
+     167           8 :   keys.add("atoms","ATOMS","the group of atoms that you are calculating the SASA for");
+     168           8 :   keys.add("compulsory","TYPE","TOTAL","The type of calculation you want to perform. Can be TOTAL or TRANSFER");
+     169           8 :   keys.add("compulsory", "NL_STRIDE", "The frequency with which the neighbor list is updated.");
+     170           8 :   keys.add("optional","DELTAGFILE","a file containing the free energy values for backbone and sidechains. Necessary only if TYPE = TRANSFER. A Python script for the computation of free energy of transfer values to describe the effect of osmolyte concentration, temperature and pressure is freely available at https://github.com/andrea-arsiccio/DeltaG-calculation. The script automatically outputs a DeltaG.dat file compatible with this SASA module. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and are computed using the temperature value passed by the MD engine");
+     171           8 :   keys.add("optional","APPROACH","either approach 2 or 3. Necessary only if TYPE = TRANSFER and no DELTAGFILE is provided. If TYPE = TRANSFER and no DELTAGFILE is provided, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, J. Phys. Chem. B, 2021) needs to be used to compute them");
+     172           4 : }
+     173             : 
+     174             : 
+     175           2 : SASA_LCPO::SASA_LCPO(const ActionOptions&ao):
+     176             :   PLUMED_COLVAR_INIT(ao),
+     177           2 :   nopbc(false),
+     178           4 :   DeltaGValues("absent"),
+     179           2 :   Ti(0),
+     180           2 :   stride(10),
+     181           2 :   nl_update(0),
+     182           2 :   firstStepFlag(0)
+     183             : {
+     184           2 :   rs = 0.14;
+     185           2 :   parse("DELTAGFILE",DeltaGValues);
+     186           2 :   parse("APPROACH", approach);
+     187           4 :   parseAtomList("ATOMS",atoms);
+     188           2 :   if(atoms.size()==0) error("no atoms specified");
+     189             :   std::string Type;
+     190           2 :   parse("TYPE",Type);
+     191           2 :   parse("NL_STRIDE", stride);
+     192           2 :   parseFlag("NOPBC",nopbc);
+     193           2 :   checkRead();
+     194             : 
+     195           2 :   if(Type=="TOTAL") sasa_type=TOTAL;
+     196           1 :   else if(Type=="TRANSFER") sasa_type=TRANSFER;
+     197           0 :   else error("Unknown SASA type");
+     198             : 
+     199           2 :   switch(sasa_type)
+     200             :   {
+     201           1 :   case TOTAL:   log.printf("  TOTAL SASA;"); break;
+     202           1 :   case TRANSFER: log.printf("  TRANSFER MODEL;"); break;
+     203             :   }
+     204             : 
+     205           2 :   log.printf("  atoms involved : ");
+     206         242 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     207         240 :     if(i%25==0) log<<"\n";
+     208         240 :     log.printf("%d ",atoms[i].serial());
+     209             :   }
+     210           2 :   log.printf("\n");
+     211             : 
+     212           2 :   if(nopbc) {
+     213           0 :     log<<"  PBC will be ignored\n";
+     214             :   } else {
+     215           2 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     216             :   }
+     217             : 
+     218             : 
+     219           4 :   addValueWithDerivatives(); setNotPeriodic();
+     220           2 :   requestAtoms(atoms);
+     221             : 
+     222           2 :   natoms = getNumberOfAtoms();
+     223           2 :   AtomResidueName.resize(2);
+     224           2 :   LCPOparam.resize(natoms);
+     225           2 :   MaxSurf.resize(natoms);
+     226           2 :   DeltaG.resize(natoms+1);
+     227           2 :   Nlist.resize(natoms);
+     228             : 
+     229             : 
+     230           2 : }
+     231             : 
+     232             : 
+     233             : //splits strings into tokens. Used to read into LCPO parameters file and into reference pdb file
+     234             : template <class Container>
+     235           0 : void split(const std::string& str, Container& cont)
+     236             : {
+     237           0 :   std::istringstream iss(str);
+     238           0 :   std::copy(std::istream_iterator<std::string>(iss),
+     239           0 :             std::istream_iterator<std::string>(),
+     240             :             std::back_inserter(cont));
+     241           0 : }
+     242             : 
+     243             : 
+     244             : //reads input PDB file provided with MOLINFO, and assigns atom and residue names to each atom involved in the CV
+     245             : 
+     246           2 : void SASA_LCPO::readPDB() {
+     247           2 :   auto* moldat = plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     248           2 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     249             :   AtomResidueName[0].clear();
+     250             :   AtomResidueName[1].clear();
+     251             : 
+     252         242 :   for(unsigned i=0; i<natoms; i++) {
+     253         240 :     string Aname = moldat->getAtomName(atoms[i]);
+     254         240 :     string Rname = moldat->getResidueName(atoms[i]);
+     255         240 :     AtomResidueName[0].push_back (Aname);
+     256         240 :     AtomResidueName[1].push_back (Rname);
+     257             :   }
+     258             : 
+     259           2 : }
+     260             : 
+     261             : //LCPO parameters database
+     262           2 : map<string, vector<double> > SASA_LCPO::setupLCPOparam() {
+     263             :   map<string, vector<double> > lcpomap;
+     264           2 :   lcpomap["ALA_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     265           2 :   lcpomap["ALA_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     266           2 :   lcpomap["ALA_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     267           2 :   lcpomap["ALA_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     268           2 :   lcpomap["ALA_CB"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     269           2 :   lcpomap["ASP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     270           2 :   lcpomap["ASP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     271           2 :   lcpomap["ASP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     272           2 :   lcpomap["ASP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     273           2 :   lcpomap["ASP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     274           2 :   lcpomap["ASP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     275           2 :   lcpomap["ASP_OD1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     276           2 :   lcpomap["ASP_OD2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     277           2 :   lcpomap["ASN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     278           2 :   lcpomap["ASN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     279           2 :   lcpomap["ASN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     280           2 :   lcpomap["ASN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     281           2 :   lcpomap["ASN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     282           2 :   lcpomap["ASN_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     283           2 :   lcpomap["ASN_OD1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     284           2 :   lcpomap["ASN_ND2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     285           2 :   lcpomap["ARG_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     286           2 :   lcpomap["ARG_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     287           2 :   lcpomap["ARG_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     288           2 :   lcpomap["ARG_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     289           2 :   lcpomap["ARG_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     290           2 :   lcpomap["ARG_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     291           2 :   lcpomap["ARG_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     292           2 :   lcpomap["ARG_NE"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     293           2 :   lcpomap["ARG_NH1"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     294           2 :   lcpomap["ARG_NH2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     295           2 :   lcpomap["ARG_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     296           2 :   lcpomap["CYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     297           2 :   lcpomap["CYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     298           2 :   lcpomap["CYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     299           2 :   lcpomap["CYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     300           2 :   lcpomap["CYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     301           2 :   lcpomap["CYS_SG"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+     302           2 :   lcpomap["GLU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     303           2 :   lcpomap["GLU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     304           2 :   lcpomap["GLU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     305           2 :   lcpomap["GLU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     306           2 :   lcpomap["GLU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     307           2 :   lcpomap["GLU_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     308           2 :   lcpomap["GLU_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     309           2 :   lcpomap["GLU_OE1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     310           2 :   lcpomap["GLU_OE2"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     311           2 :   lcpomap["GLN_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     312           2 :   lcpomap["GLN_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     313           2 :   lcpomap["GLN_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     314           2 :   lcpomap["GLN_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     315           2 :   lcpomap["GLN_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     316           2 :   lcpomap["GLN_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     317           2 :   lcpomap["GLN_CD"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     318           2 :   lcpomap["GLN_OE1"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     319           2 :   lcpomap["GLN_NE2"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     320           2 :   lcpomap["GLY_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     321           2 :   lcpomap["GLY_CA"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     322           2 :   lcpomap["GLY_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     323           2 :   lcpomap["GLY_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     324           2 :   lcpomap["HIS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     325           2 :   lcpomap["HIS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     326           2 :   lcpomap["HIS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     327           2 :   lcpomap["HIS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     328           2 :   lcpomap["HIS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     329           2 :   lcpomap["HIS_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     330           2 :   lcpomap["HIS_ND1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     331           2 :   lcpomap["HIS_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     332           2 :   lcpomap["HIS_NE2"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     333           2 :   lcpomap["HIS_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     334           2 :   lcpomap["ILE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     335           2 :   lcpomap["ILE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     336           2 :   lcpomap["ILE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     337           2 :   lcpomap["ILE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     338           2 :   lcpomap["ILE_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     339           2 :   lcpomap["ILE_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     340           2 :   lcpomap["ILE_CG1"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     341           2 :   lcpomap["ILE_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     342           2 :   lcpomap["LEU_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     343           2 :   lcpomap["LEU_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     344           2 :   lcpomap["LEU_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     345           2 :   lcpomap["LEU_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     346           2 :   lcpomap["LEU_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     347           2 :   lcpomap["LEU_CG"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     348           2 :   lcpomap["LEU_CD1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     349           2 :   lcpomap["LEU_CD2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     350           2 :   lcpomap["LYS_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     351           2 :   lcpomap["LYS_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     352           2 :   lcpomap["LYS_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     353           2 :   lcpomap["LYS_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     354           2 :   lcpomap["LYS_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     355           2 :   lcpomap["LYS_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     356           2 :   lcpomap["LYS_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     357           2 :   lcpomap["LYS_CE"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     358           2 :   lcpomap["LYS_NZ"] = { 1.65,  0.73511,  -0.22116,  -0.00089148,  0.0002523};
+     359           2 :   lcpomap["MET_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     360           2 :   lcpomap["MET_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     361           2 :   lcpomap["MET_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     362           2 :   lcpomap["MET_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     363           2 :   lcpomap["MET_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     364           2 :   lcpomap["MET_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     365           2 :   lcpomap["MET_SD"] = { 1.9,  0.54581,  -0.19477,  -0.0012873,  0.00029247};
+     366           2 :   lcpomap["MET_CE"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     367           2 :   lcpomap["PHE_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     368           2 :   lcpomap["PHE_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     369           2 :   lcpomap["PHE_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     370           2 :   lcpomap["PHE_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     371           2 :   lcpomap["PHE_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     372           2 :   lcpomap["PHE_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     373           2 :   lcpomap["PHE_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     374           2 :   lcpomap["PHE_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     375           2 :   lcpomap["PHE_CZ"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     376           2 :   lcpomap["PHE_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     377           2 :   lcpomap["PHE_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     378           2 :   lcpomap["PRO_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     379           2 :   lcpomap["PRO_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     380           2 :   lcpomap["PRO_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     381           2 :   lcpomap["PRO_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     382           2 :   lcpomap["PRO_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     383           2 :   lcpomap["PRO_CG"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     384           2 :   lcpomap["PRO_CD"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     385           2 :   lcpomap["SER_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     386           2 :   lcpomap["SER_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     387           2 :   lcpomap["SER_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     388           2 :   lcpomap["SER_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     389           2 :   lcpomap["SER_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     390           2 :   lcpomap["SER_OG"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     391           2 :   lcpomap["THR_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     392           2 :   lcpomap["THR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     393           2 :   lcpomap["THR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     394           2 :   lcpomap["THR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     395           2 :   lcpomap["THR_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     396           2 :   lcpomap["THR_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     397           2 :   lcpomap["THR_OG1"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     398           2 :   lcpomap["TRP_N"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     399           2 :   lcpomap["TRP_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     400           2 :   lcpomap["TRP_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     401           2 :   lcpomap["TRP_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     402           2 :   lcpomap["TRP_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     403           2 :   lcpomap["TRP_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     404           2 :   lcpomap["TRP_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     405           2 :   lcpomap["TRP_NE1"] = { 1.65,  0.41102,  -0.12254,  -7.5448e-05,  0.00011804};
+     406           2 :   lcpomap["TRP_CE2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     407           2 :   lcpomap["TRP_CZ2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     408           2 :   lcpomap["TRP_CH2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     409           2 :   lcpomap["TRP_CZ3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     410           2 :   lcpomap["TRP_CE3"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     411           2 :   lcpomap["TRP_CD2"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     412           2 :   lcpomap["TYR_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+     413           2 :   lcpomap["TYR_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     414           2 :   lcpomap["TYR_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     415           2 :   lcpomap["TYR_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     416           2 :   lcpomap["TYR_CB"] = { 1.7,  0.56482,  -0.19608,  -0.0010219,  0.0002658};
+     417           2 :   lcpomap["TYR_CG"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     418           2 :   lcpomap["TYR_CD1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     419           2 :   lcpomap["TYR_CE1"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     420           2 :   lcpomap["TYR_CZ"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     421           2 :   lcpomap["TYR_OH"] = { 1.6,  0.77914,  -0.25262,  -0.0016056,  0.00035071};
+     422           2 :   lcpomap["TYR_CE2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     423           2 :   lcpomap["TYR_CD2"] = { 1.7,  0.51245,  -0.15966,  -0.00019781,  0.00016392};
+     424           2 :   lcpomap["VAL_N"] = { 1.65,  0.062577,  -0.017874,  -8.312e-05,  1.9849e-05};
+     425           2 :   lcpomap["VAL_CA"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     426           2 :   lcpomap["VAL_C"] = { 1.7,  0.070344,  -0.019015,  -2.2009e-05,  1.6875e-05};
+     427           2 :   lcpomap["VAL_O"] = { 1.6,  0.68563,  -0.1868,  -0.00135573,  0.00023743};
+     428           2 :   lcpomap["VAL_CB"] = { 1.7,  0.23348,  -0.072627,  -0.00020079,  7.967e-05};
+     429           2 :   lcpomap["VAL_CG1"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     430           2 :   lcpomap["VAL_CG2"] = { 1.7,  0.77887,  -0.28063,  -0.0012968,  0.00039328};
+     431           2 :   return lcpomap;
+     432             : }
+     433             : 
+     434             : //assigns LCPO parameters to each atom reading from database
+     435           2 : void SASA_LCPO::readLCPOparam() {
+     436             : 
+     437         242 :   for(unsigned i=0; i<natoms; i++) {
+     438         240 :     LCPOparam[i].clear();
+     439             :   }
+     440             : 
+     441             :   map<string, vector<double> > lcpomap;
+     442           4 :   lcpomap = setupLCPOparam();
+     443             :   vector<double> LCPOparamVector;
+     444             :   string identifier;
+     445         242 :   for(unsigned i=0; i<natoms; i++) {
+     446         240 :     if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     447         240 :       identifier = AtomResidueName[1][i]+"_"+AtomResidueName[0][i];
+     448         120 :       LCPOparamVector = lcpomap.at(identifier);
+     449         120 :       LCPOparam[i].push_back (LCPOparamVector[0]+rs*10);
+     450         120 :       LCPOparam[i].push_back (LCPOparamVector[1]);
+     451         120 :       LCPOparam[i].push_back (LCPOparamVector[2]);
+     452         120 :       LCPOparam[i].push_back (LCPOparamVector[3]);
+     453         120 :       LCPOparam[i].push_back (LCPOparamVector[4]);
+     454             :     }
+     455             :   }
+     456             : 
+     457             : 
+     458         242 :   for(unsigned i=0; i<natoms; i++) {
+     459         240 :     if (LCPOparam[i].size()==0 ) {
+     460         120 :       if ((AtomResidueName[0][i][0]=='O') || (AtomResidueName[0][i][0]=='N') || (AtomResidueName[0][i][0]=='C') || (AtomResidueName[0][i][0]=='S')) {
+     461           0 :         cout << "Could not find LCPO paramaters for atom " << AtomResidueName[0][i] << " of residue " << AtomResidueName[1][i] << endl;
+     462           0 :         error ("missing LCPO parameters\n");
+     463             :       }
+     464             :     }
+     465             :   }
+     466             : 
+     467           2 :   if (AtomResidueName[0][0] == "N") {
+     468           2 :     LCPOparam[0][1] = 7.3511e-01;
+     469           2 :     LCPOparam[0][2] = -2.2116e-01;
+     470           2 :     LCPOparam[0][3] = -8.9148e-04;
+     471           2 :     LCPOparam[0][4] = 2.5230e-04;
+     472             :   }
+     473             : 
+     474           2 :   if (AtomResidueName[0][natoms-1] == "O") {
+     475           2 :     LCPOparam[natoms-1][1] = 8.8857e-01;
+     476           2 :     LCPOparam[natoms-1][2] = -3.3421e-01;
+     477           2 :     LCPOparam[natoms-1][3] = -1.8683e-03;
+     478           2 :     LCPOparam[natoms-1][4] = 4.9372e-04;
+     479             :   }
+     480           2 : }
+     481             : 
+     482             : 
+     483             : //Max Surf values, used only if TYPE=TRANSFER
+     484           1 : map<string, vector<double> > SASA_LCPO::setupMaxSurfMap() {
+     485             :   // Max Surface Area for backbone and sidechain, in nm2
+     486             :   map<string, vector<double> > valuemap;
+     487           1 :   valuemap ["ALA"]= {0.671446,0.420263,};
+     488           1 :   valuemap ["ARG"]= {0.578582,1.95454,};
+     489           1 :   valuemap ["ASN"]= {0.559411,1.07102,};
+     490           1 :   valuemap ["ASP"]= {0.558363,1.03971,};
+     491           1 :   valuemap ["CYS"]= {0.609271,0.657612,};
+     492           1 :   valuemap ["GLN"]= {0.565651,1.433031,};
+     493           1 :   valuemap ["GLU"]= {0.572399,1.41848,};
+     494           1 :   valuemap ["GLY"]= {0.861439,0,};
+     495           1 :   valuemap ["HIS"]= {0.559929,1.143827,};
+     496           1 :   valuemap ["ILE"]= {0.553491,1.25334,};
+     497           1 :   valuemap ["LEU"]= {0.570103,1.260459,};
+     498           1 :   valuemap ["LYS"]= {0.580304,1.687487,};
+     499           1 :   valuemap ["MET"]= {0.5856,1.498954,};
+     500           1 :   valuemap ["PHE"]= {0.54155,1.394861,};
+     501           1 :   valuemap ["PRO"]= {0.456048,0.849461,};
+     502           1 :   valuemap ["SER"]= {0.59074,0.714538,};
+     503           1 :   valuemap ["THR"]= {0.559116,0.951644,};
+     504           1 :   valuemap ["TRP"]= {0.55536,1.59324,};
+     505           1 :   valuemap ["TYR"]= {0.451171,1.566918,};
+     506           1 :   valuemap ["VAL"]= {0.454809,0.928685,};
+     507           1 :   return valuemap;
+     508             : }
+     509             : 
+     510             : 
+     511             : 
+     512             : //reads maximum surface values per residue type and assigns values to each atom, only used if sasa_type = TRANSFER
+     513             : 
+     514           1 : void SASA_LCPO::readMaxSurf() {
+     515             :   map<string, vector<double> > valuemap;
+     516           2 :   valuemap = setupMaxSurfMap();
+     517             :   vector<double> MaxSurfVector;
+     518             : 
+     519         121 :   for(unsigned i=0; i<natoms; i++) {
+     520         120 :     MaxSurf[i].clear();
+     521         120 :     MaxSurfVector = valuemap.at(AtomResidueName[1][i]);
+     522         120 :     MaxSurf[i].push_back (MaxSurfVector[0]*100);
+     523         120 :     MaxSurf[i].push_back (MaxSurfVector[1]*100);
+     524             :   }
+     525           1 : }
+     526             : 
+     527             : //reads file with free energy values for sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER
+     528             : 
+     529           1 : void SASA_LCPO::readDeltaG() {
+     530             : 
+     531         121 :   for(unsigned i=0; i<natoms; i++) {
+     532         120 :     DeltaG[i].clear();
+     533             :   }
+     534             : 
+     535             :   string DeltaGline;
+     536           1 :   fstream DeltaGFile;
+     537           1 :   DeltaGFile.open(DeltaGValues);
+     538           1 :   if (DeltaGFile) {
+     539             :     int backboneflag = 0;
+     540          23 :     while(getline(DeltaGFile, DeltaGline)) {
+     541          22 :       if(!DeltaGline.empty()) {
+     542             :         std::vector<std::string> DeltaGtoken;
+     543          21 :         split(DeltaGline, DeltaGtoken);
+     544        2541 :         for(unsigned i=0; i<natoms; i++) {
+     545        2520 :           if (DeltaGtoken[0].compare(AtomResidueName[1][i])==0 ) {
+     546         120 :             DeltaG[i].push_back (std::atof(DeltaGtoken[1].c_str()));
+     547             :           }
+     548             :         }
+     549          21 :         if (DeltaGtoken[0].compare("BACKBONE")==0 ) {
+     550             :           backboneflag = 1;
+     551           1 :           DeltaG[natoms].push_back (std::atof(DeltaGtoken[1].c_str()));
+     552             :         }
+     553          21 :       }
+     554             :     }
+     555           1 :     if ( backboneflag == 0) error("Cannot find backbone value in Delta G parameters file\n");
+     556             :   }
+     557           0 :   else error("Cannot open DeltaG file");
+     558             : 
+     559         121 :   for(unsigned i=0; i<natoms; i++) {
+     560         120 :     if (DeltaG[i].size()==0 ) {
+     561           0 :       cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     562           0 :       error ("missing Delta G parameter\n");
+     563             :     }
+     564             :   }
+     565             : 
+     566           2 : }
+     567             : 
+     568             : //computes free energy values for the sidechains and for the backbone, and assigns values to each atom. Only used if sasa_type = TRANSFER, and if no DELTAGFILE is provided. In this case, the free energy values are those describing the effect of temperature, and the program must know if approach 2 or 3 (as described in Arsiccio and Shea, Protein Cold Denaturation in Implicit Solvent Simulations: A Transfer Free Energy Approach, JPCB, 2021) needs to be used to compute them.
+     569             : 
+     570           0 : void SASA_LCPO::computeDeltaG() {
+     571             : 
+     572           0 :   for(unsigned i=0; i<natoms; i++) {
+     573           0 :     DeltaG[i].clear();
+     574             :   }
+     575             : 
+     576             :   double T;
+     577           0 :   T = getkBT()/getKBoltzmann();
+     578             : 
+     579           0 :   if (T != Ti) {
+     580           0 :     for(unsigned i=0; i<natoms; i++) {
+     581           0 :       if (approach==2) {
+     582           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     583           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.895);
+     584             :         }
+     585           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     586           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-282.032);
+     587             :         }
+     588           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     589           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-87.846);
+     590             :         }
+     591           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     592           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-16.526);
+     593             :         }
+     594           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     595           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-272.26);
+     596             :         }
+     597           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     598           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-199.707);
+     599             :         }
+     600           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     601           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-131.168);
+     602             :         }
+     603           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     604           0 :           DeltaG[i].push_back (0);
+     605             :         }
+     606           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     607           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-311.694);
+     608             :         }
+     609           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     610           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-567.444);
+     611             :         }
+     612           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     613           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-653.394);
+     614             :         }
+     615           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     616           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-185.549);
+     617             :         }
+     618           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     619           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.007);
+     620             :         }
+     621           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     622           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-688.874);
+     623             :         }
+     624           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     625           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-212.059);
+     626             :         }
+     627           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     628           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+151.957);
+     629             :         }
+     630           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     631           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-239.516);
+     632             :         }
+     633           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     634           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1025.293);
+     635             :         }
+     636           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     637           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-667.261);
+     638             :         }
+     639           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     640           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-435.309);
+     641             :         }
+     642           0 :         DeltaG[natoms].push_back (-0.6962/1000*std::pow(T,2)+0.4426*T-70.015);
+     643             :       }
+     644           0 :       if (approach==3) {
+     645           0 :         if (AtomResidueName[1][i].compare("ALA")==0) {
+     646           0 :           DeltaG[i].push_back (-2.995/1000*std::pow(T,2)+1.808*T-272.105);
+     647             :         }
+     648           0 :         if (AtomResidueName[1][i].compare("ARG")==0) {
+     649           0 :           DeltaG[i].push_back (-3.182/1000*std::pow(T,2)+1.894*T-284.086);
+     650             :         }
+     651           0 :         if (AtomResidueName[1][i].compare("ASN")==0) {
+     652           0 :           DeltaG[i].push_back (-1.047/1000*std::pow(T,2)+0.6068*T-90.597);
+     653             :         }
+     654           0 :         if (AtomResidueName[1][i].compare("ASP")==0) {
+     655           0 :           DeltaG[i].push_back (-0.1794/1000*std::pow(T,2)+0.1091*T-19.143);
+     656             :         }
+     657           0 :         if (AtomResidueName[1][i].compare("CYS")==0) {
+     658           0 :           DeltaG[i].push_back (-3.09/1000*std::pow(T,2)+1.835*T-268.527);
+     659             :         }
+     660           0 :         if (AtomResidueName[1][i].compare("GLN")==0) {
+     661           0 :           DeltaG[i].push_back (-2.23/1000*std::pow(T,2)+1.335*T-201.559);
+     662             :         }
+     663           0 :         if (AtomResidueName[1][i].compare("GLU")==0) {
+     664           0 :           DeltaG[i].push_back (-1.511/1000*std::pow(T,2)+0.8904*T-133.543);
+     665             :         }
+     666           0 :         if (AtomResidueName[1][i].compare("GLY")==0) {
+     667           0 :           DeltaG[i].push_back (0);
+     668             :         }
+     669           0 :         if (AtomResidueName[1][i].compare("HIS")==0) {
+     670           0 :           DeltaG[i].push_back (-3.482/1000*std::pow(T,2)+2.084*T-315.398);
+     671             :         }
+     672           0 :         if (AtomResidueName[1][i].compare("ILE")==0) {
+     673           0 :           DeltaG[i].push_back (-6.364/1000*std::pow(T,2)+3.8*T-564.825);
+     674             :         }
+     675           0 :         if (AtomResidueName[1][i].compare("LEU")==0) {
+     676           0 :           DeltaG[i].push_back (-7.466/1000*std::pow(T,2)+4.417*T-651.483);
+     677             :         }
+     678           0 :         if (AtomResidueName[1][i].compare("LYS")==0) {
+     679           0 :           DeltaG[i].push_back (-2.091/1000*std::pow(T,2)+1.2458*T-187.485);
+     680             :         }
+     681           0 :         if (AtomResidueName[1][i].compare("MET")==0) {
+     682           0 :           DeltaG[i].push_back (-3.807/1000*std::pow(T,2)+2.272*T-339.242);
+     683             :         }
+     684           0 :         if (AtomResidueName[1][i].compare("PHE")==0) {
+     685           0 :           DeltaG[i].push_back (-7.828/1000*std::pow(T,2)+4.644*T-687.134);
+     686             :         }
+     687           0 :         if (AtomResidueName[1][i].compare("PRO")==0) {
+     688           0 :           DeltaG[i].push_back (-2.347/1000*std::pow(T,2)+1.411*T-214.211);
+     689             :         }
+     690           0 :         if (AtomResidueName[1][i].compare("SER")==0) {
+     691           0 :           DeltaG[i].push_back (1.813/1000*std::pow(T,2)-1.05*T+150.289);
+     692             :         }
+     693           0 :         if (AtomResidueName[1][i].compare("THR")==0) {
+     694           0 :           DeltaG[i].push_back (-2.64/1000*std::pow(T,2)+1.591*T-240.267);
+     695             :         }
+     696           0 :         if (AtomResidueName[1][i].compare("TRP")==0) {
+     697           0 :           DeltaG[i].push_back (-11.66/1000*std::pow(T,2)+6.916*T-1024.284);
+     698             :         }
+     699           0 :         if (AtomResidueName[1][i].compare("TYR")==0) {
+     700           0 :           DeltaG[i].push_back (-7.513/1000*std::pow(T,2)+4.478*T-666.484);
+     701             :         }
+     702           0 :         if (AtomResidueName[1][i].compare("VAL")==0) {
+     703           0 :           DeltaG[i].push_back (-4.902/1000*std::pow(T,2)+2.921*T-433.013);
+     704             :         }
+     705           0 :         DeltaG[natoms].push_back (-0.6927/1000*std::pow(T,2)+0.4404*T-68.724);
+     706             :       }
+     707             :     }
+     708             :   }
+     709             : 
+     710           0 :   Ti = T;
+     711             : 
+     712           0 :   if (firstStepFlag ==0) {
+     713           0 :     if (approach!=2 && approach!=3) {
+     714           0 :       cout << "Unknown approach " << approach << endl;
+     715             :     }
+     716           0 :     for(unsigned i=0; i<natoms; i++) {
+     717           0 :       if (DeltaG[i].size()==0 ) {
+     718           0 :         cout << "Delta G value for residue " << AtomResidueName[1][i] << " not found " << endl;
+     719           0 :         error ("missing Delta G parameter\n");
+     720             :       }
+     721             :     }
+     722             :   }
+     723           0 : }
+     724             : 
+     725             : 
+     726             : //calculates neighbor list
+     727          24 : void SASA_LCPO::calcNlist() {
+     728          24 :   if(!nopbc) makeWhole();
+     729             : 
+     730        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     731        2880 :     Nlist[i].clear();
+     732             :   }
+     733             : 
+     734        2904 :   for(unsigned i = 0; i < natoms; i++) {
+     735        2880 :     if (LCPOparam[i].size()>0) {
+     736       87264 :       for (unsigned j = 0; j < i; j++) {
+     737       85824 :         if (LCPOparam[j].size()>0) {
+     738       42480 :           const Vector Delta_ij_vec = delta( getPosition(i), getPosition(j) );
+     739       42480 :           double Delta_ij_mod = Delta_ij_vec.modulo()*10;
+     740       42480 :           double overlapD = LCPOparam[i][0]+LCPOparam[j][0];
+     741       42480 :           if (Delta_ij_mod < overlapD) {
+     742       19030 :             Nlist.at(i).push_back (j);
+     743       19030 :             Nlist.at(j).push_back (i);
+     744             :           }
+     745             :         }
+     746             :       }
+     747             :     }
+     748             :   }
+     749          24 : }
+     750             : 
+     751             : 
+     752             : //calculates SASA according to LCPO algorithm
+     753          24 : void SASA_LCPO::calculate() {
+     754          24 :   if(!nopbc) makeWhole();
+     755             : 
+     756          24 :   if(getExchangeStep()) nl_update = 0;
+     757          24 :   if (firstStepFlag ==0) {
+     758           2 :     readPDB();
+     759           2 :     readLCPOparam();
+     760             :   }
+     761          24 :   if (nl_update == 0) {
+     762          24 :     calcNlist();
+     763             :   }
+     764             : 
+     765             : 
+     766             : 
+     767             :   double S1, Aij, Ajk, Aijk, Aijt, Ajkt, Aikt;
+     768             :   double dAdd;
+     769          24 :   double sasa = 0;
+     770          24 :   vector<Vector> derivatives( natoms );
+     771          24 :   Tensor virial;
+     772          24 :   vector <double> dAijdc_2t(3);
+     773          24 :   vector <double> dSASA_2_neigh_dc(3);
+     774          24 :   vector <double> ddij_di(3);
+     775          24 :   vector <double> ddik_di(3);
+     776             : 
+     777          24 :   if( sasa_type==TOTAL ) {
+     778        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     779        1440 :       derivatives[i][0] = 0.;
+     780        1440 :       derivatives[i][1] = 0.;
+     781        1440 :       derivatives[i][2] = 0.;
+     782        1440 :       if ( LCPOparam[i].size()>1) {
+     783         720 :         if (LCPOparam[i][1]>0.0) {
+     784             :           Aij = 0.0;
+     785             :           Aijk = 0.0;
+     786             :           Ajk = 0.0;
+     787         720 :           double ri = LCPOparam[i][0];
+     788         720 :           S1 = 4*M_PI*ri*ri;
+     789         720 :           vector <double> dAijdc_2(3, 0);
+     790         720 :           vector <double> dAijdc_4(3, 0);
+     791             : 
+     792             : 
+     793       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     794       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     795       19030 :             double d_ij = d_ij_vec.modulo()*10;
+     796             : 
+     797       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
+     798       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
+     799       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
+     800             : 
+     801       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     802             : 
+     803       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
+     804       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     805       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     806             : 
+     807             :             Ajkt = 0.0;
+     808             :             Aikt = 0.0;
+     809             : 
+     810       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
+     811       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
+     812       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
+     813       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
+     814             : 
+     815       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
+     816       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
+     817       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
+     818             : 
+     819       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     820             : 
+     821             : 
+     822       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
+     823       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
+     824       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
+     825             : 
+     826      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
+     827      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+     828      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
+     829      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
+     830             : 
+     831      370872 :                 double d_jk = d_jk_vec.modulo()*10;
+     832      370872 :                 double d_ik = d_ik_vec.modulo()*10;
+     833             : 
+     834      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+     835      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
+     836      370872 :                 Ajkt += sjk;
+     837      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
+     838             : 
+     839      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     840             : 
+     841      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
+     842      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
+     843      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
+     844             : 
+     845             : 
+     846      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
+     847      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
+     848      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
+     849             : 
+     850      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     851             : 
+     852      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
+     853      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
+     854      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
+     855             : 
+     856      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
+     857      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
+     858      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
+     859             : 
+     860             :               }
+     861             :             }
+     862       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
+     863       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
+     864       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
+     865             : 
+     866       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
+     867       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
+     868       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
+     869             : 
+     870       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
+     871       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
+     872       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
+     873             : 
+     874             : 
+     875       19030 :             derivatives[i][0] += (dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/10;
+     876       19030 :             derivatives[i][1] += (dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/10;
+     877       19030 :             derivatives[i][2] += (dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/10;
+     878             : 
+     879             : 
+     880       19030 :             Aijk += (Aijt * Ajkt);
+     881       19030 :             Aij += Aijt;
+     882       19030 :             Ajk += Ajkt;
+     883             : 
+     884       19030 :             dAijdc_2[0] += dAijdc_2t[0];
+     885       19030 :             dAijdc_2[1] += dAijdc_2t[1];
+     886       19030 :             dAijdc_2[2] += dAijdc_2t[2];
+     887             : 
+     888             : 
+     889       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
+     890       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
+     891       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
+     892             : 
+     893             : 
+     894             :           }
+     895         720 :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+     896         720 :           if (sasai > 0 ) sasa += sasai/100;
+     897         720 :           derivatives[i][0] += (dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/10;
+     898         720 :           derivatives[i][1] += (dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/10;
+     899         720 :           derivatives[i][2] += (dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/10;
+     900             :         }
+     901             :       }
+     902        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
+     903             :     }
+     904             :   }
+     905             : 
+     906             : 
+     907             : 
+     908          24 :   if( sasa_type==TRANSFER ) {
+     909             : 
+     910          12 :     if (firstStepFlag ==0) {
+     911           1 :       readMaxSurf();
+     912             :     }
+     913             : 
+     914          12 :     if (firstStepFlag ==0 && DeltaGValues != "absent") {
+     915           1 :       readDeltaG();
+     916             :     }
+     917             : 
+     918          12 :     if (DeltaGValues == "absent") {
+     919           0 :       computeDeltaG();
+     920             :     }
+     921             : 
+     922             : 
+     923        1452 :     for(unsigned i = 0; i < natoms; i++) {
+     924             : 
+     925             : 
+     926             : 
+     927        1440 :       derivatives[i][0] = 0.;
+     928        1440 :       derivatives[i][1] = 0.;
+     929        1440 :       derivatives[i][2] = 0.;
+     930             : 
+     931        1440 :       if ( LCPOparam[i].size()>1) {
+     932         720 :         if (LCPOparam[i][1]>0.0) {
+     933             :           Aij = 0.0;
+     934             :           Aijk = 0.0;
+     935             :           Ajk = 0.0;
+     936         720 :           double ri = LCPOparam[i][0];
+     937         720 :           S1 = 4*M_PI*ri*ri;
+     938         720 :           vector <double> dAijdc_2(3, 0);
+     939         720 :           vector <double> dAijdc_4(3, 0);
+     940             : 
+     941             : 
+     942       19750 :           for (unsigned j = 0; j < Nlist[i].size(); j++) {
+     943       19030 :             const Vector d_ij_vec = delta( getPosition(i), getPosition(Nlist[i][j]) );
+     944       19030 :             double d_ij = d_ij_vec.modulo()*10;
+     945             : 
+     946       19030 :             double rj = LCPOparam[Nlist[i][j]][0];
+     947       19030 :             Aijt = (2*M_PI*ri*(ri-d_ij/2-((ri*ri-rj*rj)/(2*d_ij))));
+     948       19030 :             double sji = (2*M_PI*rj*(rj-d_ij/2+((ri*ri-rj*rj)/(2*d_ij))));
+     949             : 
+     950       19030 :             dAdd = M_PI*rj*(-(ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     951       19030 :             ddij_di[0] = -10*(getPosition(Nlist[i][j])[0]-getPosition(i)[0])/d_ij;
+     952       19030 :             ddij_di[1] = -10*(getPosition(Nlist[i][j])[1]-getPosition(i)[1])/d_ij;
+     953       19030 :             ddij_di[2] = -10*(getPosition(Nlist[i][j])[2]-getPosition(i)[2])/d_ij;
+     954             : 
+     955             :             Ajkt = 0.0;
+     956             :             Aikt = 0.0;
+     957             : 
+     958       19030 :             vector <double> dSASA_3_neigh_dc(3, 0.0);
+     959       19030 :             vector <double> dSASA_4_neigh_dc(3, 0.0);
+     960       19030 :             vector <double> dSASA_3_neigh_dc2(3, 0.0);
+     961       19030 :             vector <double> dSASA_4_neigh_dc2(3, 0.0);
+     962             : 
+     963       19030 :             dSASA_2_neigh_dc[0] = dAdd * ddij_di[0];
+     964       19030 :             dSASA_2_neigh_dc[1] = dAdd * ddij_di[1];
+     965       19030 :             dSASA_2_neigh_dc[2] = dAdd * ddij_di[2];
+     966             : 
+     967       19030 :             dAdd = M_PI*ri*((ri*ri-rj*rj)/(d_ij*d_ij)-1);
+     968             : 
+     969       19030 :             dAijdc_2t[0] = dAdd * ddij_di[0];
+     970       19030 :             dAijdc_2t[1] = dAdd * ddij_di[1];
+     971       19030 :             dAijdc_2t[2] = dAdd * ddij_di[2];
+     972             : 
+     973      560038 :             for (unsigned k = 0; k < Nlist[Nlist[i][j]].size(); k++) {
+     974      541008 :               if (std::find (Nlist[i].begin(), Nlist[i].end(), Nlist[Nlist[i][j]][k]) !=  Nlist[i].end()) {
+     975      370872 :                 const Vector d_jk_vec = delta( getPosition(Nlist[i][j]), getPosition(Nlist[Nlist[i][j]][k]) );
+     976      370872 :                 const Vector d_ik_vec = delta( getPosition(i), getPosition(Nlist[Nlist[i][j]][k]) );
+     977             : 
+     978      370872 :                 double d_jk = d_jk_vec.modulo()*10;
+     979      370872 :                 double d_ik = d_ik_vec.modulo()*10;
+     980             : 
+     981      370872 :                 double rk = LCPOparam[Nlist[Nlist[i][j]][k]][0];
+     982      370872 :                 double sjk =  (2*M_PI*rj*(rj-d_jk/2-((rj*rj-rk*rk)/(2*d_jk))));
+     983      370872 :                 Ajkt += sjk;
+     984      370872 :                 Aikt += (2*M_PI*ri*(ri-d_ik/2-((ri*ri-rk*rk)/(2*d_ik))));
+     985             : 
+     986      370872 :                 dAdd = M_PI*ri*((ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     987             : 
+     988      370872 :                 ddik_di[0] = -10*(getPosition(Nlist[Nlist[i][j]][k])[0]-getPosition(i)[0])/d_ik;
+     989      370872 :                 ddik_di[1] = -10*(getPosition(Nlist[Nlist[i][j]][k])[1]-getPosition(i)[1])/d_ik;
+     990      370872 :                 ddik_di[2] = -10*(getPosition(Nlist[Nlist[i][j]][k])[2]-getPosition(i)[2])/d_ik;
+     991             : 
+     992             : 
+     993      370872 :                 dSASA_3_neigh_dc[0] += dAdd*ddik_di[0];
+     994      370872 :                 dSASA_3_neigh_dc[1] += dAdd*ddik_di[1];
+     995      370872 :                 dSASA_3_neigh_dc[2] += dAdd*ddik_di[2];
+     996             : 
+     997      370872 :                 dAdd = M_PI*rk*(-(ri*ri-rk*rk)/(d_ik*d_ik)-1);
+     998             : 
+     999      370872 :                 dSASA_3_neigh_dc2[0] += dAdd*ddik_di[0];
+    1000      370872 :                 dSASA_3_neigh_dc2[1] += dAdd*ddik_di[1];
+    1001      370872 :                 dSASA_3_neigh_dc2[2] += dAdd*ddik_di[2];
+    1002             : 
+    1003      370872 :                 dSASA_4_neigh_dc2[0] += sjk*dAdd*ddik_di[0];
+    1004      370872 :                 dSASA_4_neigh_dc2[1] += sjk*dAdd*ddik_di[1];
+    1005      370872 :                 dSASA_4_neigh_dc2[2] += sjk*dAdd*ddik_di[2];
+    1006             : 
+    1007             :               }
+    1008             :             }
+    1009       19030 :             dSASA_4_neigh_dc[0] = sji*dSASA_3_neigh_dc[0] + dSASA_4_neigh_dc2[0];
+    1010       19030 :             dSASA_4_neigh_dc[1] = sji*dSASA_3_neigh_dc[1] + dSASA_4_neigh_dc2[1];
+    1011       19030 :             dSASA_4_neigh_dc[2] = sji*dSASA_3_neigh_dc[2] + dSASA_4_neigh_dc2[2];
+    1012             : 
+    1013       19030 :             dSASA_3_neigh_dc[0] += dSASA_3_neigh_dc2[0];
+    1014       19030 :             dSASA_3_neigh_dc[1] += dSASA_3_neigh_dc2[1];
+    1015       19030 :             dSASA_3_neigh_dc[2] += dSASA_3_neigh_dc2[2];
+    1016             : 
+    1017       19030 :             dSASA_4_neigh_dc[0] += dSASA_2_neigh_dc[0] * Aikt;
+    1018       19030 :             dSASA_4_neigh_dc[1] += dSASA_2_neigh_dc[1] * Aikt;
+    1019       19030 :             dSASA_4_neigh_dc[2] += dSASA_2_neigh_dc[2] * Aikt;
+    1020             : 
+    1021       19030 :             if (AtomResidueName[0][Nlist[i][j]] == "N" || AtomResidueName[0][Nlist[i][j]] == "CA"  || AtomResidueName[0][Nlist[i][j]] == "C" || AtomResidueName[0][Nlist[i][j]] == "O") {
+    1022       15720 :               derivatives[i][0] += ((dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
+    1023       15720 :               derivatives[i][1] += ((dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
+    1024       15720 :               derivatives[i][2] += ((dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][0]*DeltaG[natoms][0])*10;
+    1025             :             }
+    1026             : 
+    1027       19030 :             if (AtomResidueName[0][Nlist[i][j]] != "N" && AtomResidueName[0][Nlist[i][j]] != "CA"  && AtomResidueName[0][Nlist[i][j]] != "C" && AtomResidueName[0][Nlist[i][j]] != "O") {
+    1028        3310 :               derivatives[i][0] += ((dSASA_2_neigh_dc[0]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[0]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[0]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
+    1029        3310 :               derivatives[i][1] += ((dSASA_2_neigh_dc[1]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[1]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[1]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
+    1030        3310 :               derivatives[i][2] += ((dSASA_2_neigh_dc[2]*LCPOparam[Nlist[i][j]][2] + dSASA_3_neigh_dc[2]*LCPOparam[Nlist[i][j]][3]+dSASA_4_neigh_dc[2]*LCPOparam[Nlist[i][j]][4])/MaxSurf[Nlist[i][j]][1]*DeltaG[Nlist[i][j]][0])*10;
+    1031             :             }
+    1032             : 
+    1033       19030 :             Aijk += (Aijt * Ajkt);
+    1034       19030 :             Aij += Aijt;
+    1035       19030 :             Ajk += Ajkt;
+    1036             : 
+    1037       19030 :             dAijdc_2[0] += dAijdc_2t[0];
+    1038       19030 :             dAijdc_2[1] += dAijdc_2t[1];
+    1039       19030 :             dAijdc_2[2] += dAijdc_2t[2];
+    1040             : 
+    1041       19030 :             dAijdc_4[0] += Ajkt*dAijdc_2t[0];
+    1042       19030 :             dAijdc_4[1] += Ajkt*dAijdc_2t[1];
+    1043       19030 :             dAijdc_4[2] += Ajkt*dAijdc_2t[2];
+    1044             : 
+    1045             :           }
+    1046             :           double sasai = (LCPOparam[i][1]*S1+LCPOparam[i][2]*Aij+LCPOparam[i][3]*Ajk+LCPOparam[i][4]*Aijk);
+    1047             : 
+    1048        2016 :           if (AtomResidueName[0][i] == "N" || AtomResidueName[0][i] == "CA"  || AtomResidueName[0][i] == "C" || AtomResidueName[0][i] == "O") {
+    1049         576 :             if (sasai > 0 ) sasa += (sasai/MaxSurf[i][0]*DeltaG[natoms][0]);
+    1050         576 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1051         576 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1052         576 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][0]*DeltaG[natoms][0])*10;
+    1053             :           }
+    1054             : 
+    1055        2016 :           if (AtomResidueName[0][i] != "N" && AtomResidueName[0][i] != "CA"  && AtomResidueName[0][i] != "C" && AtomResidueName[0][i] != "O") {
+    1056         144 :             if (sasai > 0. ) sasa += (sasai/MaxSurf[i][1]*DeltaG[i][0]);
+    1057         144 :             derivatives[i][0] += ((dAijdc_2[0]*LCPOparam[i][2]+dAijdc_4[0]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1058         144 :             derivatives[i][1] += ((dAijdc_2[1]*LCPOparam[i][2]+dAijdc_4[1]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1059         144 :             derivatives[i][2] += ((dAijdc_2[2]*LCPOparam[i][2]+dAijdc_4[2]*LCPOparam[i][4])/MaxSurf[i][1]*DeltaG[i][0])*10;
+    1060             :           }
+    1061             :         }
+    1062             :       }
+    1063        1440 :       virial -= Tensor(getPosition(i),derivatives[i]);
+    1064             :     }
+    1065             :   }
+    1066             : 
+    1067             : 
+    1068        2904 :   for(unsigned i=0; i<natoms; i++) { setAtomsDerivatives(i,derivatives[i]);}
+    1069          24 :   setBoxDerivatives(virial);
+    1070          24 :   setValue(sasa);
+    1071          24 :   firstStepFlag = 1;
+    1072          24 :   ++nl_update;
+    1073          24 :   if (nl_update == stride) {
+    1074          24 :     nl_update = 0;
+    1075             :   }
+    1076             : // setBoxDerivativesNoPbc();
+    1077          24 : }
+    1078             : 
+    1079             : }//namespace sasa
+    1080             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..22043aa121be --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/AlphaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AlphaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure9AlphaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure9AlphaRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure9AlphaRMSD16registerKeywordsERNS_8KeywordsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AlphaRMSD.cpp.func.html b/coverage/secondarystructure/AlphaRMSD.cpp.func.html new file mode 100644 index 000000000000..62fbf418b6a3 --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/AlphaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AlphaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure9AlphaRMSD16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD18secondarystructure9AlphaRMSDC1ERKNS_13ActionOptionsE3
_ZN4PLMD18secondarystructure9AlphaRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html b/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html new file mode 100644 index 000000000000..638c1e0bd98e --- /dev/null +++ b/coverage/secondarystructure/AlphaRMSD.cpp.gcov.html @@ -0,0 +1,234 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/AlphaRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AlphaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4949100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "SecondaryStructureRMSD.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace secondarystructure {
+      27             : 
+      28             : //+PLUMEDOC COLVAR ALPHARMSD
+      29             : /*
+      30             : Probe the alpha helical content of a protein structure.
+      31             : 
+      32             : Any chain of six contiguous residues in a protein chain can form an alpha helix. This
+      33             : colvar thus generates the set of all possible six residue sections and calculates
+      34             : the RMSD distance between the configuration in which the residues find themselves
+      35             : and an idealized alpha helical structure. These distances can be calculated by either
+      36             : aligning the instantaneous structure with the reference structure and measuring each
+      37             : atomic displacement or by calculating differences between the set of inter-atomic
+      38             : distances in the reference and instantaneous structures.
+      39             : 
+      40             : This colvar is based on the following reference \cite pietrucci09jctc.  The authors of
+      41             : this paper use the set of distances from the alpha helix configurations to measure
+      42             : the number of segments that have an alpha helical configuration. This is done by calculating
+      43             : the following sum of functions of the rmsd distances:
+      44             : 
+      45             : \f[
+      46             : s = \sum_i \frac{ 1 - \left(\frac{r_i-d_0}{r_0}\right)^n } { 1 - \left(\frac{r_i-d_0}{r_0}\right)^m }
+      47             : \f]
+      48             : 
+      49             : where the sum runs over all possible segments of alpha helix.  By default the
+      50             : NN, MM and D_0 parameters are set equal to those used in \cite pietrucci09jctc.  The R_0
+      51             : parameter must be set by the user - the value used in \cite pietrucci09jctc was 0.08 nm.
+      52             : 
+      53             : If you change the function in the above sum you can calculate quantities such as the average
+      54             : distance from a purely the alpha helical configuration or the distance between the set of
+      55             : residues that is closest to an alpha helix and the reference configuration. To do these sorts of
+      56             : calculations you can use the AVERAGE and MIN keywords. In addition you can use the LESS_THAN
+      57             : keyword if you would like to change the form of the switching function. If you use any of these
+      58             : options you no longer need to specify NN, R_0, MM and D_0.
+      59             : 
+      60             : Please be aware that for codes like gromacs you must ensure that plumed
+      61             : reconstructs the chains involved in your CV when you calculate this CV using
+      62             : anything other than TYPE=DRMSD.  For more details as to how to do this see \ref WHOLEMOLECULES.
+      63             : 
+      64             : \par Examples
+      65             : 
+      66             : The following input calculates the number of six residue segments of
+      67             : protein that are in an alpha helical configuration.
+      68             : 
+      69             : \plumedfile
+      70             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      71             : MOLINFO STRUCTURE=helix.pdb
+      72             : alpha: ALPHARMSD RESIDUES=all
+      73             : \endplumedfile
+      74             : 
+      75             : Here the same is done use RMSD instead of DRMSD
+      76             : 
+      77             : \plumedfile
+      78             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      79             : MOLINFO STRUCTURE=helix.pdb
+      80             : WHOLEMOLECULES ENTITY0=1-100
+      81             : alpha: ALPHARMSD RESIDUES=all TYPE=OPTIMAL R_0=0.1
+      82             : \endplumedfile
+      83             : 
+      84             : */
+      85             : //+ENDPLUMEDOC
+      86             : 
+      87             : class AlphaRMSD : public SecondaryStructureRMSD {
+      88             : public:
+      89             :   static void registerKeywords( Keywords& keys );
+      90             :   explicit AlphaRMSD(const ActionOptions&);
+      91             : };
+      92             : 
+      93             : PLUMED_REGISTER_ACTION(AlphaRMSD,"ALPHARMSD")
+      94             : 
+      95           5 : void AlphaRMSD::registerKeywords( Keywords& keys ) {
+      96           5 :   SecondaryStructureRMSD::registerKeywords( keys );
+      97           5 : }
+      98             : 
+      99           3 : AlphaRMSD::AlphaRMSD(const ActionOptions&ao):
+     100             :   Action(ao),
+     101           3 :   SecondaryStructureRMSD(ao)
+     102             : {
+     103             :   // read in the backbone atoms
+     104           3 :   std::vector<unsigned> chains; readBackboneAtoms( "protein", chains);
+     105             : 
+     106             :   // This constructs all conceivable sections of alpha helix in the backbone of the chains
+     107           3 :   unsigned nprevious=0; std::vector<unsigned> nlist(30);
+     108           6 :   for(unsigned i=0; i<chains.size(); ++i) {
+     109           3 :     if( chains[i]<30 ) error("segment of backbone defined is not long enough to form an alpha helix. Each backbone fragment must contain a minimum of 6 residues");
+     110           3 :     unsigned nres=chains[i]/5;
+     111           3 :     if( chains[i]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     112          12 :     for(unsigned ires=0; ires<nres-5; ires++) {
+     113           9 :       unsigned accum=nprevious + 5*ires;
+     114         279 :       for(unsigned k=0; k<30; ++k) nlist[k] = accum+k;
+     115           9 :       addColvar( nlist );
+     116             :     }
+     117           3 :     nprevious+=chains[i];
+     118             :   }
+     119             : 
+     120             :   // Build the reference structure ( in angstroms )
+     121           3 :   std::vector<Vector> reference(30);
+     122           3 :   reference[0] = Vector( 0.733,  0.519,  5.298 ); // N    i
+     123           3 :   reference[1] = Vector( 1.763,  0.810,  4.301 ); // CA
+     124           3 :   reference[2] = Vector( 3.166,  0.543,  4.881 ); // CB
+     125           3 :   reference[3] = Vector( 1.527, -0.045,  3.053 ); // C
+     126           3 :   reference[4] = Vector( 1.646,  0.436,  1.928 ); // O
+     127           3 :   reference[5] = Vector( 1.180, -1.312,  3.254 ); // N    i+1
+     128           3 :   reference[6] = Vector( 0.924, -2.203,  2.126 ); // CA
+     129           3 :   reference[7] = Vector( 0.650, -3.626,  2.626 ); // CB
+     130           3 :   reference[8] = Vector(-0.239, -1.711,  1.261 ); // C
+     131           3 :   reference[9] = Vector(-0.190, -1.815,  0.032 ); // O
+     132           3 :   reference[10] = Vector(-1.280, -1.172,  1.891 ); // N    i+2
+     133           3 :   reference[11] = Vector(-2.416, -0.661,  1.127 ); // CA
+     134           3 :   reference[12] = Vector(-3.548, -0.217,  2.056 ); // CB
+     135           3 :   reference[13] = Vector(-1.964,  0.529,  0.276 ); // C
+     136           3 :   reference[14] = Vector(-2.364,  0.659, -0.880 ); // O
+     137           3 :   reference[15] = Vector(-1.130,  1.391,  0.856 ); // N    i+3
+     138           3 :   reference[16] = Vector(-0.620,  2.565,  0.148 ); // CA
+     139           3 :   reference[17] = Vector( 0.228,  3.439,  1.077 ); // CB
+     140           3 :   reference[18] = Vector( 0.231,  2.129, -1.032 ); // C
+     141           3 :   reference[19] = Vector( 0.179,  2.733, -2.099 ); // O
+     142           3 :   reference[20] = Vector( 1.028,  1.084, -0.833 ); // N    i+4
+     143           3 :   reference[21] = Vector( 1.872,  0.593, -1.919 ); // CA
+     144           3 :   reference[22] = Vector( 2.850, -0.462, -1.397 ); // CB
+     145           3 :   reference[23] = Vector( 1.020,  0.020, -3.049 ); // C
+     146           3 :   reference[24] = Vector( 1.317,  0.227, -4.224 ); // O
+     147           3 :   reference[25] = Vector(-0.051, -0.684, -2.696 ); // N    i+5
+     148           3 :   reference[26] = Vector(-0.927, -1.261, -3.713 ); // CA
+     149           3 :   reference[27] = Vector(-1.933, -2.219, -3.074 ); // CB
+     150           3 :   reference[28] = Vector(-1.663, -0.171, -4.475 ); // C
+     151           3 :   reference[29] = Vector(-1.916, -0.296, -5.673 ); // O
+     152             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
+     153           3 :   setSecondaryStructure( reference, 0.17/getUnits().getLength(), 0.1/getUnits().getLength() );
+     154           3 : }
+     155             : 
+     156             : }
+     157             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..93bdbbea44ef --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/AntibetaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AntibetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:757797.4 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12AntibetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12AntibetaRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12AntibetaRMSD16registerKeywordsERNS_8KeywordsE14
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AntibetaRMSD.cpp.func.html b/coverage/secondarystructure/AntibetaRMSD.cpp.func.html new file mode 100644 index 000000000000..c18d75907024 --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/AntibetaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AntibetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:757797.4 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12AntibetaRMSD16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD18secondarystructure12AntibetaRMSDC1ERKNS_13ActionOptionsE12
_ZN4PLMD18secondarystructure12AntibetaRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html b/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html new file mode 100644 index 000000000000..ccd768abe093 --- /dev/null +++ b/coverage/secondarystructure/AntibetaRMSD.cpp.gcov.html @@ -0,0 +1,286 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/AntibetaRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - AntibetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:757797.4 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "SecondaryStructureRMSD.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace secondarystructure {
+      27             : 
+      28             : //+PLUMEDOC COLVAR ANTIBETARMSD
+      29             : /*
+      30             : Probe the antiparallel beta sheet content of your protein structure.
+      31             : 
+      32             : Two protein segments containing three contiguous residues can form an antiparallel beta sheet.
+      33             : Although if the two segments are part of the same protein chain they must be separated by
+      34             : a minimum of 2 residues to make room for the turn. This colvar thus generates the set of
+      35             : all possible six residue sections that could conceivably form an antiparallel beta sheet
+      36             : and calculates the RMSD distance between the configuration in which the residues find themselves
+      37             : and an idealized antiparallel beta sheet structure. These distances can be calculated by either
+      38             : aligning the instantaneous structure with the reference structure and measuring each
+      39             : atomic displacement or by calculating differences between the set of inter-atomic
+      40             : distances in the reference and instantaneous structures.
+      41             : 
+      42             : This colvar is based on the following reference \cite pietrucci09jctc.  The authors of
+      43             : this paper use the set of distances from the anti parallel beta sheet configurations to measure
+      44             : the number of segments that have an configuration that resembles an anti parallel beta sheet. This is done by calculating
+      45             : the following sum of functions of the rmsd distances:
+      46             : 
+      47             : \f[
+      48             : s = \sum_i \frac{ 1 - \left(\frac{r_i-d_0}{r_0}\right)^n } { 1 - \left(\frac{r_i-d_0}{r_0}\right)^m }
+      49             : \f]
+      50             : 
+      51             : where the sum runs over all possible segments of antiparallel beta sheet.  By default the
+      52             : NN, MM and D_0 parameters are set equal to those used in \cite pietrucci09jctc.  The R_0
+      53             : parameter must be set by the user - the value used in \cite pietrucci09jctc was 0.08 nm.
+      54             : 
+      55             : If you change the function in the above sum you can calculate quantities such as the average
+      56             : distance from a purely configuration composed of pure anti-parallel beta sheets or the distance between the set of
+      57             : residues that is closest to an anti-parallel beta sheet and the reference configuration. To do these sorts of
+      58             : calculations you can use the AVERAGE and MIN keywords. In addition you can use the LESS_THAN
+      59             : keyword if you would like to change the form of the switching function. If you use any of these
+      60             : options you no longer need to specify NN, R_0, MM and D_0.
+      61             : 
+      62             : Please be aware that for codes like gromacs you must ensure that plumed
+      63             : reconstructs the chains involved in your CV when you calculate this CV using
+      64             : anything other than TYPE=DRMSD.  For more details as to how to do this see \ref WHOLEMOLECULES.
+      65             : 
+      66             : \par Examples
+      67             : 
+      68             : The following input calculates the number of six residue segments of
+      69             : protein that are in an antiparallel beta sheet configuration.
+      70             : 
+      71             : \plumedfile
+      72             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      73             : MOLINFO STRUCTURE=beta.pdb
+      74             : ab: ANTIBETARMSD RESIDUES=all STRANDS_CUTOFF=1
+      75             : \endplumedfile
+      76             : 
+      77             : Here the same is done use RMSD instead of DRMSD
+      78             : 
+      79             : \plumedfile
+      80             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      81             : MOLINFO STRUCTURE=helix.pdb
+      82             : WHOLEMOLECULES ENTITY0=1-100
+      83             : hh: ANTIBETARMSD RESIDUES=all TYPE=OPTIMAL R_0=0.1  STRANDS_CUTOFF=1
+      84             : \endplumedfile
+      85             : */
+      86             : //+ENDPLUMEDOC
+      87             : 
+      88             : class AntibetaRMSD : public SecondaryStructureRMSD {
+      89             : public:
+      90             :   static void registerKeywords( Keywords& keys );
+      91             :   explicit AntibetaRMSD(const ActionOptions&);
+      92             : };
+      93             : 
+      94             : PLUMED_REGISTER_ACTION(AntibetaRMSD,"ANTIBETARMSD")
+      95             : 
+      96          14 : void AntibetaRMSD::registerKeywords( Keywords& keys ) {
+      97          14 :   SecondaryStructureRMSD::registerKeywords( keys );
+      98          28 :   keys.add("compulsory","STYLE","all","Antiparallel beta sheets can either form in a single chain or from a pair of chains. If STYLE=all all "
+      99             :            "chain configuration with the appropriate geometry are counted.  If STYLE=inter "
+     100             :            "only sheet-like configurations involving two chains are counted, while if STYLE=intra "
+     101             :            "only sheet-like configurations involving a single chain are counted");
+     102          14 :   keys.use("STRANDS_CUTOFF");
+     103          14 : }
+     104             : 
+     105          12 : AntibetaRMSD::AntibetaRMSD(const ActionOptions&ao):
+     106             :   Action(ao),
+     107          12 :   SecondaryStructureRMSD(ao)
+     108             : {
+     109             :   // read in the backbone atoms
+     110          24 :   std::vector<unsigned> chains; readBackboneAtoms( "protein", chains );
+     111             : 
+     112             :   bool intra_chain(false), inter_chain(false);
+     113          12 :   std::string style; parse("STYLE",style);
+     114          24 :   if( Tools::caseInSensStringCompare(style, "all") ) {
+     115             :     intra_chain=true; inter_chain=true;
+     116           4 :   } else if( Tools::caseInSensStringCompare(style, "inter") ) {
+     117             :     intra_chain=false; inter_chain=true;
+     118           0 :   } else if( Tools::caseInSensStringCompare(style, "intra") ) {
+     119             :     intra_chain=true; inter_chain=false;
+     120             :   } else {
+     121           0 :     error( style + " is not a valid directive for the STYLE keyword");
+     122             :   }
+     123             : 
+     124             :   // Align the atoms based on the positions of these two atoms
+     125          12 :   setAtomsFromStrands( 6, 21 );
+     126             : 
+     127             :   // This constructs all conceivable sections of antibeta sheet in the backbone of the chains
+     128          12 :   if( intra_chain ) {
+     129          10 :     unsigned nprevious=0; std::vector<unsigned> nlist(30);
+     130         173 :     for(unsigned i=0; i<chains.size(); ++i) {
+     131         163 :       if( chains[i]<40 ) error("segment of backbone is not long enough to form an antiparallel beta hairpin. Each backbone fragment must contain a minimum of 8 residues");
+     132             :       // Loop over all possible triples in each 8 residue segment of protein
+     133         163 :       unsigned nres=chains[i]/5;
+     134         163 :       if( chains[i]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     135         330 :       for(unsigned ires=0; ires<nres-7; ires++) {
+     136         344 :         for(unsigned jres=ires+7; jres<nres; jres++) {
+     137        2832 :           for(unsigned k=0; k<15; ++k) {
+     138        2655 :             nlist[k]=nprevious + ires*5+k;
+     139        2655 :             nlist[k+15]=nprevious + (jres-2)*5+k;
+     140             :           }
+     141         177 :           addColvar( nlist );
+     142             :         }
+     143             :       }
+     144         163 :       nprevious+=chains[i];
+     145             :     }
+     146             :   }
+     147          12 :   if( inter_chain ) {
+     148          13 :     if( chains.size()==1 && style!="all" ) error("there is only one chain defined so cannot use inter_chain option");
+     149          12 :     std::vector<unsigned> nlist(30);
+     150         167 :     for(unsigned ichain=1; ichain<chains.size(); ++ichain) {
+     151        1534 :       unsigned iprev=0; for(unsigned i=0; i<ichain; ++i) iprev+=chains[i];
+     152         155 :       unsigned inres=chains[ichain]/5;
+     153         155 :       if( chains[ichain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     154        1075 :       for(unsigned ires=0; ires<inres-2; ++ires) {
+     155        9184 :         for(unsigned jchain=0; jchain<ichain; ++jchain) {
+     156       52328 :           unsigned jprev=0; for(unsigned i=0; i<jchain; ++i) jprev+=chains[i];
+     157        8264 :           unsigned jnres=chains[jchain]/5;
+     158        8264 :           if( chains[jchain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     159       57838 :           for(unsigned jres=0; jres<jnres-2; ++jres) {
+     160      793184 :             for(unsigned k=0; k<15; ++k) {
+     161      743610 :               nlist[k]=iprev+ ires*5+k;
+     162      743610 :               nlist[k+15]=jprev+ jres*5+k;
+     163             :             }
+     164       49574 :             addColvar( nlist );
+     165             :           }
+     166             :         }
+     167             :       }
+     168             :     }
+     169             :   }
+     170             : 
+     171             :   // Build the reference structure ( in angstroms )
+     172          12 :   std::vector<Vector> reference(30);
+     173          12 :   reference[0]=Vector( 2.263, -3.795,  1.722); // N    i
+     174          12 :   reference[1]=Vector( 2.493, -2.426,  2.263); // CA
+     175          12 :   reference[2]=Vector( 3.847, -1.838,  1.761); // CB
+     176          12 :   reference[3]=Vector( 1.301, -1.517,  1.921); // C
+     177          12 :   reference[4]=Vector( 0.852, -1.504,  0.739); // O
+     178          12 :   reference[5]=Vector( 0.818, -0.738,  2.917); // N    i+1
+     179          12 :   reference[6]=Vector(-0.299,  0.243,  2.748); // CA
+     180          12 :   reference[7]=Vector(-1.421, -0.076,  3.757); // CB
+     181          12 :   reference[8]=Vector( 0.273,  1.680,  2.854); // C
+     182          12 :   reference[9]=Vector( 0.902,  1.993,  3.888); // O
+     183          12 :   reference[10]=Vector( 0.119,  2.532,  1.813); // N    i+2
+     184          12 :   reference[11]=Vector( 0.683,  3.916,  1.680); // CA
+     185          12 :   reference[12]=Vector( 1.580,  3.940,  0.395); // CB
+     186          12 :   reference[13]=Vector(-0.394,  5.011,  1.630); // C
+     187          12 :   reference[14]=Vector(-1.459,  4.814,  0.982); // O
+     188          12 :   reference[15]=Vector(-2.962,  3.559, -1.359); // N    j-2
+     189          12 :   reference[16]=Vector(-2.439,  2.526, -2.287); // CA
+     190          12 :   reference[17]=Vector(-1.189,  3.006, -3.087); // CB
+     191          12 :   reference[18]=Vector(-2.081,  1.231, -1.520); // C
+     192          12 :   reference[19]=Vector(-1.524,  1.324, -0.409); // O
+     193          12 :   reference[20]=Vector(-2.326,  0.037, -2.095); // N    j-1
+     194          12 :   reference[21]=Vector(-1.858, -1.269, -1.554); // CA
+     195          12 :   reference[22]=Vector(-3.053, -2.199, -1.291); // CB
+     196          12 :   reference[23]=Vector(-0.869, -1.949, -2.512); // C
+     197          12 :   reference[24]=Vector(-1.255, -2.070, -3.710); // O
+     198          12 :   reference[25]=Vector( 0.326, -2.363, -2.072); // N    j
+     199          12 :   reference[26]=Vector( 1.405, -2.992, -2.872); // CA
+     200          12 :   reference[27]=Vector( 2.699, -2.129, -2.917); // CB
+     201          12 :   reference[28]=Vector( 1.745, -4.399, -2.330); // C
+     202          12 :   reference[29]=Vector( 1.899, -4.545, -1.102); // O
+     203             : 
+     204             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
+     205          12 :   setSecondaryStructure( reference, 0.17/getUnits().getLength(), 0.1/getUnits().getLength() );
+     206          12 : }
+     207             : 
+     208             : }
+     209             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..0d245921cecb --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/ParabetaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - ParabetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10510897.2 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12ParabetaRMSDC2ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure12ParabetaRMSDC1ERKNS_13ActionOptionsE10
_ZN4PLMD18secondarystructure12ParabetaRMSD16registerKeywordsERNS_8KeywordsE12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/ParabetaRMSD.cpp.func.html b/coverage/secondarystructure/ParabetaRMSD.cpp.func.html new file mode 100644 index 000000000000..5a5bc9fcd5fa --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/ParabetaRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - ParabetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10510897.2 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure12ParabetaRMSD16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD18secondarystructure12ParabetaRMSDC1ERKNS_13ActionOptionsE10
_ZN4PLMD18secondarystructure12ParabetaRMSDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html b/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html new file mode 100644 index 000000000000..a04fc1f307de --- /dev/null +++ b/coverage/secondarystructure/ParabetaRMSD.cpp.gcov.html @@ -0,0 +1,320 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/ParabetaRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - ParabetaRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10510897.2 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "SecondaryStructureRMSD.h"
+      23             : #include "core/ActionRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace secondarystructure {
+      27             : 
+      28             : //+PLUMEDOC COLVAR PARABETARMSD
+      29             : /*
+      30             : Probe the parallel beta sheet content of your protein structure.
+      31             : 
+      32             : Two protein segments containing three contiguous residues can form a parallel beta sheet.
+      33             : Although if the two segments are part of the same protein chain they must be separated by
+      34             : a minimum of 3 residues to make room for the turn. This colvar thus generates the set of
+      35             : all possible six residue sections that could conceivably form a parallel beta sheet
+      36             : and calculates the RMSD distance between the configuration in which the residues find themselves
+      37             : and an idealized parallel beta sheet structure. These distances can be calculated by either
+      38             : aligning the instantaneous structure with the reference structure and measuring each
+      39             : atomic displacement or by calculating differences between the set of inter-atomic
+      40             : distances in the reference and instantaneous structures.
+      41             : 
+      42             : This colvar is based on the following reference \cite pietrucci09jctc.  The authors of
+      43             : this paper use the set of distances from the parallel beta sheet configurations to measure
+      44             : the number of segments whose configuration resembles a parallel beta sheet. This is done by calculating
+      45             : the following sum of functions of the rmsd distances:
+      46             : 
+      47             : \f[
+      48             : s = \sum_i \frac{ 1 - \left(\frac{r_i-d_0}{r_0}\right)^n } { 1 - \left(\frac{r_i-d_0}{r_0}\right)^m }
+      49             : \f]
+      50             : 
+      51             : where the sum runs over all possible segments of parallel beta sheet.  By default the
+      52             : NN, MM and D_0 parameters are set equal to those used in \cite pietrucci09jctc.  The R_0
+      53             : parameter must be set by the user - the value used in \cite pietrucci09jctc was 0.08 nm.
+      54             : 
+      55             : If you change the function in the above sum you can calculate quantities such as the average
+      56             : distance from a structure composed of only parallel beta sheets or the distance between the set of
+      57             : residues that is closest to a parallel beta sheet and the reference configuration. To do these sorts of
+      58             : calculations you can use the AVERAGE and MIN keywords. In addition you can use the LESS_THAN
+      59             : keyword if you would like to change the form of the switching function. If you use any of these
+      60             : options you no longer need to specify NN, R_0, MM and D_0.
+      61             : 
+      62             : Please be aware that for codes like gromacs you must ensure that plumed
+      63             : reconstructs the chains involved in your CV when you calculate this CV using
+      64             : anything other than TYPE=DRMSD.  For more details as to how to do this see \ref WHOLEMOLECULES.
+      65             : 
+      66             : \par Examples
+      67             : 
+      68             : The following input calculates the number of six residue segments of
+      69             : protein that are in an parallel beta sheet configuration.
+      70             : 
+      71             : \plumedfile
+      72             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      73             : MOLINFO STRUCTURE=beta.pdb
+      74             : pb: PARABETARMSD RESIDUES=all STRANDS_CUTOFF=1
+      75             : \endplumedfile
+      76             : 
+      77             : Here the same is done use RMSD instead of DRMSD
+      78             : 
+      79             : \plumedfile
+      80             : #SETTINGS MOLFILE=regtest/basic/rt32/helix.pdb
+      81             : MOLINFO STRUCTURE=helix.pdb
+      82             : WHOLEMOLECULES ENTITY0=1-100
+      83             : hh: PARABETARMSD RESIDUES=all TYPE=OPTIMAL R_0=0.1  STRANDS_CUTOFF=1
+      84             : \endplumedfile
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : class ParabetaRMSD : public SecondaryStructureRMSD {
+      90             : public:
+      91             :   static void registerKeywords( Keywords& keys );
+      92             :   explicit ParabetaRMSD(const ActionOptions&);
+      93             : };
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(ParabetaRMSD,"PARABETARMSD")
+      96             : 
+      97          12 : void ParabetaRMSD::registerKeywords( Keywords& keys ) {
+      98          12 :   SecondaryStructureRMSD::registerKeywords( keys );
+      99          24 :   keys.add("compulsory","STYLE","all","Parallel beta sheets can either form in a single chain or from a pair of chains. If STYLE=all all "
+     100             :            "chain configuration with the appropriate geometry are counted.  If STYLE=inter "
+     101             :            "only sheet-like configurations involving two chains are counted, while if STYLE=intra "
+     102             :            "only sheet-like configurations involving a single chain are counted");
+     103          12 :   keys.use("STRANDS_CUTOFF");
+     104          12 : }
+     105             : 
+     106          10 : ParabetaRMSD::ParabetaRMSD(const ActionOptions&ao):
+     107             :   Action(ao),
+     108          10 :   SecondaryStructureRMSD(ao)
+     109             : {
+     110             :   // read in the backbone atoms
+     111          20 :   std::vector<unsigned> chains; readBackboneAtoms( "protein", chains );
+     112             : 
+     113             :   bool intra_chain(false), inter_chain(false);
+     114          10 :   std::string style; parse("STYLE",style);
+     115          20 :   if( Tools::caseInSensStringCompare(style, "all") ) {
+     116             :     intra_chain=true; inter_chain=true;
+     117           0 :   } else if( Tools::caseInSensStringCompare(style, "inter") ) {
+     118             :     intra_chain=false; inter_chain=true;
+     119           0 :   } else if( Tools::caseInSensStringCompare(style, "intra") ) {
+     120             :     intra_chain=true; inter_chain=false;
+     121             :   } else {
+     122           0 :     error( style + " is not a valid directive for the STYLE keyword");
+     123             :   }
+     124             : 
+     125             :   // Align the atoms based on the positions of these two atoms
+     126          10 :   setAtomsFromStrands( 6, 21 );
+     127             : 
+     128             :   // This constructs all conceivable sections of antibeta sheet in the backbone of the chains
+     129          10 :   if( intra_chain ) {
+     130          10 :     unsigned nprevious=0; std::vector<unsigned> nlist(30);
+     131         173 :     for(unsigned i=0; i<chains.size(); ++i) {
+     132         163 :       if( chains[i]<40 ) error("segment of backbone is not long enough to form an antiparallel beta hairpin. Each backbone fragment must contain a minimum of 8 residues");
+     133             :       // Loop over all possible triples in each 8 residue segment of protein
+     134         163 :       unsigned nres=chains[i]/5;
+     135         163 :       if( chains[i]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     136         167 :       for(unsigned ires=0; ires<nres-8; ires++) {
+     137          14 :         for(unsigned jres=ires+6; jres<nres-2; jres++) {
+     138         160 :           for(unsigned k=0; k<15; ++k) {
+     139         150 :             nlist[k]=nprevious + ires*5+k;
+     140         150 :             nlist[k+15]=nprevious + jres*5+k;
+     141             :           }
+     142          10 :           addColvar( nlist );
+     143             :         }
+     144             :       }
+     145         163 :       nprevious+=chains[i];
+     146             :     }
+     147             :   }
+     148             :   // This constructs all conceivable sections of antibeta sheet that form between chains
+     149          10 :   if( inter_chain ) {
+     150          12 :     if( chains.size()==1 && !Tools::caseInSensStringCompare(style, "all") ) error("there is only one chain defined so cannot use inter_chain option");
+     151          10 :     std::vector<unsigned> nlist(30);
+     152         163 :     for(unsigned ichain=1; ichain<chains.size(); ++ichain) {
+     153        1530 :       unsigned iprev=0; for(unsigned i=0; i<ichain; ++i) iprev+=chains[i];
+     154         153 :       unsigned inres=chains[ichain]/5;
+     155         153 :       if( chains[ichain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     156        1071 :       for(unsigned ires=0; ires<inres-2; ++ires) {
+     157        9180 :         for(unsigned jchain=0; jchain<ichain; ++jchain) {
+     158       52326 :           unsigned jprev=0; for(unsigned i=0; i<jchain; ++i) jprev+=chains[i];
+     159        8262 :           unsigned jnres=chains[jchain]/5;
+     160        8262 :           if( chains[jchain]%5!=0 ) error("backbone segment received does not contain a multiple of five residues");
+     161       57834 :           for(unsigned jres=0; jres<jnres-2; ++jres) {
+     162      793152 :             for(unsigned k=0; k<15; ++k) {
+     163      743580 :               nlist[k]=iprev + ires*5+k;
+     164      743580 :               nlist[k+15]=jprev + jres*5+k;
+     165             :             }
+     166       49572 :             addColvar( nlist );
+     167             :           }
+     168             :         }
+     169             :       }
+     170             :     }
+     171             :   }
+     172             : 
+     173             :   // Build the reference structure ( in angstroms )
+     174          10 :   std::vector<Vector> reference(30);
+     175          10 :   reference[0]=Vector( 1.244, -4.620, -2.127); // N    i
+     176          10 :   reference[1]=Vector(-0.016, -4.500, -1.395); // CA
+     177          10 :   reference[2]=Vector( 0.105, -5.089,  0.024); // CB
+     178          10 :   reference[3]=Vector(-0.287, -3.000, -1.301); // C
+     179          10 :   reference[4]=Vector( 0.550, -2.245, -0.822); // O
+     180          10 :   reference[5]=Vector(-1.445, -2.551, -1.779); // N    i+1
+     181          10 :   reference[6]=Vector(-1.752, -1.130, -1.677); // CA
+     182          10 :   reference[7]=Vector(-2.113, -0.550, -3.059); // CB
+     183          10 :   reference[8]=Vector(-2.906, -0.961, -0.689); // C
+     184          10 :   reference[9]=Vector(-3.867, -1.738, -0.695); // O
+     185          10 :   reference[10]=Vector(-2.774,  0.034,  0.190); // N    i+2
+     186          10 :   reference[11]=Vector(-3.788,  0.331,  1.201); // CA
+     187          10 :   reference[12]=Vector(-3.188,  0.300,  2.624); // CB
+     188          10 :   reference[13]=Vector(-4.294,  1.743,  0.937); // C
+     189          10 :   reference[14]=Vector(-3.503,  2.671,  0.821); // O
+     190          10 :   reference[15]=Vector( 4.746, -2.363,  0.188); // N    j
+     191          10 :   reference[16]=Vector( 3.427, -1.839,  0.545); // CA
+     192          10 :   reference[17]=Vector( 3.135, -1.958,  2.074); // CB
+     193          10 :   reference[18]=Vector( 3.346, -0.365,  0.181); // C
+     194          10 :   reference[19]=Vector( 4.237,  0.412,  0.521); // O
+     195          10 :   reference[20]=Vector( 2.261,  0.013, -0.487); // N    j+1
+     196          10 :   reference[21]=Vector( 2.024,  1.401, -0.875); // CA
+     197          10 :   reference[22]=Vector( 1.489,  1.514, -2.313); // CB
+     198          10 :   reference[23]=Vector( 0.914,  1.902,  0.044); // C
+     199          10 :   reference[24]=Vector(-0.173,  1.330,  0.052); // O
+     200          10 :   reference[25]=Vector( 1.202,  2.940,  0.828); // N    j+2
+     201          10 :   reference[26]=Vector( 0.190,  3.507,  1.718); // CA
+     202          10 :   reference[27]=Vector( 0.772,  3.801,  3.104); // CB
+     203          10 :   reference[28]=Vector(-0.229,  4.791,  1.038); // C
+     204          10 :   reference[29]=Vector( 0.523,  5.771,  0.996); // O
+     205             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
+     206          10 :   setSecondaryStructure( reference, 0.17/getUnits().getLength(), 0.1/getUnits().getLength() );
+     207             : 
+     208          10 :   reference[0]=Vector(-1.439, -5.122, -1.144); // N    i
+     209          10 :   reference[1]=Vector(-0.816, -3.803, -1.013); // CA
+     210          10 :   reference[2]=Vector( 0.099, -3.509, -2.206); // CB
+     211          10 :   reference[3]=Vector(-1.928, -2.770, -0.952); // C
+     212          10 :   reference[4]=Vector(-2.991, -2.970, -1.551); // O
+     213          10 :   reference[5]=Vector(-1.698, -1.687, -0.215); // N    i+1
+     214          10 :   reference[6]=Vector(-2.681, -0.613, -0.143); // CA
+     215          10 :   reference[7]=Vector(-3.323, -0.477,  1.267); // CB
+     216          10 :   reference[8]=Vector(-1.984,  0.681, -0.574); // C
+     217          10 :   reference[9]=Vector(-0.807,  0.921, -0.273); // O
+     218          10 :   reference[10]=Vector(-2.716,  1.492, -1.329); // N    i+2
+     219          10 :   reference[11]=Vector(-2.196,  2.731, -1.883); // CA
+     220          10 :   reference[12]=Vector(-2.263,  2.692, -3.418); // CB
+     221          10 :   reference[13]=Vector(-2.989,  3.949, -1.433); // C
+     222          10 :   reference[14]=Vector(-4.214,  3.989, -1.583); // O
+     223          10 :   reference[15]=Vector( 2.464, -4.352,  2.149); // N    j
+     224          10 :   reference[16]=Vector( 3.078, -3.170,  1.541); // CA
+     225          10 :   reference[17]=Vector( 3.398, -3.415,  0.060); // CB
+     226          10 :   reference[18]=Vector( 2.080, -2.021,  1.639); // C
+     227          10 :   reference[19]=Vector( 0.938, -2.178,  1.225); // O
+     228          10 :   reference[20]=Vector( 2.525, -0.886,  2.183); // N    j+1
+     229          10 :   reference[21]=Vector( 1.692,  0.303,  2.346); // CA
+     230          10 :   reference[22]=Vector( 1.541,  0.665,  3.842); // CB
+     231          10 :   reference[23]=Vector( 2.420,  1.410,  1.608); // C
+     232          10 :   reference[24]=Vector( 3.567,  1.733,  1.937); // O
+     233          10 :   reference[25]=Vector( 1.758,  1.976,  0.600); // N    j+2
+     234          10 :   reference[26]=Vector( 2.373,  2.987, -0.238); // CA
+     235          10 :   reference[27]=Vector( 2.367,  2.527, -1.720); // CB
+     236          10 :   reference[28]=Vector( 1.684,  4.331, -0.148); // C
+     237          10 :   reference[29]=Vector( 0.486,  4.430, -0.415); // O
+     238             :   // Store the secondary structure ( last number makes sure we convert to internal units nm )
+     239          10 :   setSecondaryStructure( reference, 0.17/getUnits().getLength(), 0.1/getUnits().getLength() );
+     240          10 : }
+     241             : 
+     242             : }
+     243             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..09c9cdc55c07 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/SecondaryStructureRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - SecondaryStructureRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13814694.5 %
Date:2024-02-22 21:58:45Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC1ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDD0Ev0
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDD1Ev0
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD19setAtomsFromStrandsERKjS3_22
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17readBackboneAtomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIjSaIjEE25
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC2ERKNS_13ActionOptionsE25
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDD2Ev25
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD21setSecondaryStructureERSt6vectorINS_13VectorGenericILj3EEESaIS4_EEdd35
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17turnOnDerivativesEv62
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD5applyEv192
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9calculateEv2568
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9addColvarERKSt6vectorIjSaIjEE99342
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD11performTaskERKjS3_RNS_10MultiValueE400032
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html new file mode 100644 index 000000000000..4f010e55a10b --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/SecondaryStructureRMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - SecondaryStructureRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13814694.5 %
Date:2024-02-22 21:58:45Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17readBackboneAtomsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIjSaIjEE25
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD17turnOnDerivativesEv62
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD19setAtomsFromStrandsERKjS3_22
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD21setSecondaryStructureERSt6vectorINS_13VectorGenericILj3EEESaIS4_EEdd35
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD5applyEv192
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9addColvarERKSt6vectorIjSaIjEE99342
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD9calculateEv2568
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC1ERKNS_13ActionOptionsE0
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDC2ERKNS_13ActionOptionsE25
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDD0Ev0
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDD1Ev0
_ZN4PLMD18secondarystructure22SecondaryStructureRMSDD2Ev25
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD11performTaskERKjS3_RNS_10MultiValueE400032
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html new file mode 100644 index 000000000000..79b0329dc95a --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.cpp.gcov.html @@ -0,0 +1,345 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/SecondaryStructureRMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - SecondaryStructureRMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13814694.5 %
Date:2024-02-22 21:58:45Functions:111478.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "SecondaryStructureRMSD.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "core/ActionSet.h"
+      25             : #include "core/GenericMolInfo.h"
+      26             : #include "vesselbase/Vessel.h"
+      27             : #include "reference/MetricRegister.h"
+      28             : #include "reference/SingleDomainRMSD.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace secondarystructure {
+      32             : 
+      33          31 : void SecondaryStructureRMSD::registerKeywords( Keywords& keys ) {
+      34          31 :   Action::registerKeywords( keys );
+      35          31 :   ActionWithValue::registerKeywords( keys );
+      36          31 :   ActionAtomistic::registerKeywords( keys );
+      37          62 :   keys.add("residues","RESIDUES","this command is used to specify the set of residues that could conceivably form part of the secondary structure. "
+      38             :            "It is possible to use residues numbers as the various chains and residues should have been identified else using an instance of the "
+      39             :            "\\ref MOLINFO action. If you wish to use all the residues from all the chains in your system you can do so by "
+      40             :            "specifying all. Alternatively, if you wish to use a subset of the residues you can specify the particular residues "
+      41             :            "you are interested in as a list of numbers. Please be aware that to form secondary structure elements your chain "
+      42             :            "must contain at least N residues, where N is dependent on the particular secondary structure you are interested in. "
+      43             :            "As such if you define portions of the chain with fewer than N residues the code will crash.");
+      44          62 :   keys.add("compulsory","TYPE","DRMSD","the manner in which RMSD alignment is performed. Should be OPTIMAL, SIMPLE or DRMSD. "
+      45             :            "For more details on the OPTIMAL and SIMPLE methods see \\ref RMSD. For more details on the "
+      46             :            "DRMSD method see \\ref DRMSD.");
+      47          62 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions");
+      48          62 :   keys.add("compulsory","R_0","0.08","The r_0 parameter of the switching function.");
+      49          62 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
+      50          62 :   keys.add("compulsory","NN","8","The n parameter of the switching function");
+      51          62 :   keys.add("compulsory","MM","12","The m parameter of the switching function");
+      52          62 :   keys.reserve("optional","STRANDS_CUTOFF","If in a segment of protein the two strands are further apart then the calculation "
+      53             :                "of the actual RMSD is skipped as the structure is very far from being beta-sheet like. "
+      54             :                "This keyword speeds up the calculation enormously when you are using the LESS_THAN option. "
+      55             :                "However, if you are using some other option, then this cannot be used");
+      56          62 :   keys.addFlag("VERBOSE",false,"write a more detailed output");
+      57          62 :   keys.add("hidden","NL_STRIDE","the frequency with which the neighbor list should be updated. Between neighbour list update steps all quantities "
+      58             :            "that contributed less than TOL at the previous neighbor list update step are ignored.");
+      59          31 :   ActionWithVessel::registerKeywords( keys );
+      60         155 :   keys.use("LESS_THAN"); keys.use("MIN"); keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST");
+      61          31 :   keys.setComponentsIntroduction("By default this Action calculates the number of structural units that are within a certain "
+      62             :                                  "distance of a idealized secondary structure element. This quantity can then be referenced "
+      63             :                                  "elsewhere in the input by using the label of the action. However, this Action can also be used to "
+      64             :                                  "calculate the following quantities by using the keywords as described below.  The quantities then "
+      65             :                                  "calculated can be referenced using the label of the action followed by a dot and then the name "
+      66             :                                  "from the table below.  Please note that you can use the LESS_THAN keyword more than once.  The resulting "
+      67             :                                  "components will be labelled <em>label</em>.lessthan-1, <em>label</em>.lessthan-2 and so on unless you "
+      68             :                                  "exploit the fact that these labels can be given custom labels by using the LABEL keyword in the "
+      69             :                                  "description of you LESS_THAN function that you are computing");
+      70          31 : }
+      71             : 
+      72          25 : SecondaryStructureRMSD::SecondaryStructureRMSD(const ActionOptions&ao):
+      73             :   Action(ao),
+      74             :   ActionAtomistic(ao),
+      75             :   ActionWithValue(ao),
+      76             :   ActionWithVessel(ao),
+      77          25 :   nopbc(false),
+      78          25 :   align_strands(false),
+      79          25 :   s_cutoff2(0),
+      80          25 :   align_atom_1(0),
+      81          25 :   align_atom_2(0)
+      82             : {
+      83          50 :   parse("TYPE",alignType); parseFlag("NOPBC",nopbc);
+      84          25 :   log.printf("  distances from secondary structure elements are calculated using %s algorithm\n",alignType.c_str() );
+      85          50 :   log<<"  Bibliography "<<plumed.cite("Pietrucci and Laio, J. Chem. Theory Comput. 5, 2197 (2009)"); log<<"\n";
+      86             : 
+      87          25 :   parseFlag("VERBOSE",verbose_output);
+      88             : 
+      89          50 :   if( keywords.exists("STRANDS_CUTOFF") ) {
+      90          22 :     double s_cutoff = 0;
+      91          22 :     parse("STRANDS_CUTOFF",s_cutoff); align_strands=true;
+      92          22 :     if( s_cutoff>0) log.printf("  ignoring contributions from strands that are more than %f apart\n",s_cutoff);
+      93          22 :     s_cutoff2=s_cutoff*s_cutoff;
+      94             :   }
+      95          25 : }
+      96             : 
+      97          25 : SecondaryStructureRMSD::~SecondaryStructureRMSD() {
+      98             : // destructor needed to delete forward declarated objects
+      99          50 : }
+     100             : 
+     101          62 : void SecondaryStructureRMSD::turnOnDerivatives() {
+     102          62 :   ActionWithValue::turnOnDerivatives();
+     103          62 :   needsDerivatives();
+     104          62 : }
+     105             : 
+     106          22 : void SecondaryStructureRMSD::setAtomsFromStrands( const unsigned& atom1, const unsigned& atom2 ) {
+     107          22 :   align_atom_1=atom1; align_atom_2=atom2;
+     108          22 : }
+     109             : 
+     110          25 : void SecondaryStructureRMSD::readBackboneAtoms( const std::string& moltype, std::vector<unsigned>& chain_lengths ) {
+     111          25 :   auto* moldat=plumed.getActionSet().selectLatest<GenericMolInfo*>(this);
+     112          25 :   if( ! moldat ) error("Unable to find MOLINFO in input");
+     113             : 
+     114          25 :   std::vector<std::string> resstrings; parseVector( "RESIDUES", resstrings );
+     115          25 :   if( !verbose_output ) {
+     116          25 :     if(resstrings.size()==0) error("residues are not defined, check the keyword RESIDUES");
+     117          50 :     else if( Tools::caseInSensStringCompare(resstrings[0], "all") ) {
+     118             :       resstrings[0]="all";
+     119          21 :       log.printf("  examining all possible secondary structure combinations\n");
+     120             :     } else {
+     121           4 :       log.printf("  examining secondary structure in residue positions : %s \n",resstrings[0].c_str() );
+     122           6 :       for(unsigned i=1; i<resstrings.size(); ++i) log.printf(", %s",resstrings[i].c_str() );
+     123           4 :       log.printf("\n");
+     124             :     }
+     125             :   }
+     126             :   std::vector< std::vector<AtomNumber> > backatoms;
+     127          25 :   moldat->getBackbone( resstrings, moltype, backatoms );
+     128             : 
+     129          25 :   chain_lengths.resize( backatoms.size() );
+     130         358 :   for(unsigned i=0; i<backatoms.size(); ++i) {
+     131         333 :     chain_lengths[i]=backatoms[i].size();
+     132       13593 :     for(unsigned j=0; j<backatoms[i].size(); ++j) all_atoms.push_back( backatoms[i][j] );
+     133             :   }
+     134          25 :   ActionAtomistic::requestAtoms( all_atoms );
+     135          25 :   forcesToApply.resize( getNumberOfDerivatives() );
+     136          25 : }
+     137             : 
+     138       99342 : void SecondaryStructureRMSD::addColvar( const std::vector<unsigned>& newatoms ) {
+     139       99342 :   if( colvar_atoms.size()>0 ) plumed_assert( colvar_atoms[0].size()==newatoms.size() );
+     140       99342 :   if( verbose_output ) {
+     141           0 :     log.printf("  Secondary structure segment %u contains atoms : ", static_cast<unsigned>(colvar_atoms.size()+1));
+     142           0 :     for(unsigned i=0; i<newatoms.size(); ++i) log.printf("%d ",all_atoms[newatoms[i]].serial() );
+     143           0 :     log.printf("\n");
+     144             :   }
+     145       99342 :   addTaskToList( colvar_atoms.size() );
+     146       99342 :   colvar_atoms.push_back( newatoms );
+     147       99342 : }
+     148             : 
+     149          35 : void SecondaryStructureRMSD::setSecondaryStructure( std::vector<Vector>& structure, double bondlength, double units ) {
+     150             :   // If we are in natural units get conversion factor from nm into natural length units
+     151          35 :   if( usingNaturalUnits() ) {
+     152           0 :     error("cannot use this collective variable when using natural units");
+     153             :   }
+     154          35 :   plumed_massert( !(align_strands && align_atom_1==0 && align_atom_2==0), "you must use setAtomsFromStrands with strands cutoff");
+     155             : 
+     156             :   // Convert into correct units
+     157        1085 :   for(unsigned i=0; i<structure.size(); ++i) {
+     158        1050 :     structure[i][0]*=units; structure[i][1]*=units; structure[i][2]*=units;
+     159             :   }
+     160             : 
+     161          35 :   if( references.size()==0 ) {
+     162          25 :     readVesselKeywords();
+     163          25 :     if( getNumberOfVessels()==0 ) {
+     164           4 :       double r0; parse("R_0",r0); double d0; parse("D_0",d0);
+     165           4 :       int nn; parse("NN",nn); int mm; parse("MM",mm);
+     166           2 :       std::ostringstream ostr;
+     167           2 :       ostr<<"RATIONAL R_0="<<r0<<" D_0="<<d0<<" NN="<<nn<<" MM="<<mm;
+     168           2 :       std::string input=ostr.str(); addVessel( "LESS_THAN", input, -1 ); // -1 here means that this value will be named getLabel()
+     169           2 :       readVesselKeywords();  // This makes sure resizing is done
+     170           2 :     }
+     171             :   }
+     172             : 
+     173             :   // Set the reference structure
+     174          35 :   references.emplace_back( metricRegister().create<SingleDomainRMSD>( alignType ) );
+     175          35 :   unsigned nn=references.size()-1;
+     176          35 :   std::vector<double> align( structure.size(), 1.0 ), displace( structure.size(), 1.0 );
+     177          35 :   references[nn]->setBoundsOnDistances( true, bondlength );   // We always use pbc
+     178          35 :   references[nn]->setReferenceAtoms( structure, align, displace );
+     179             : //  references[nn]->setNumberOfAtoms( structure.size() );
+     180             : 
+     181             :   // And prepare the task list
+     182          35 :   deactivateAllTasks();
+     183      148959 :   for(unsigned i=0; i<getFullNumberOfTasks(); ++i) taskFlags[i]=1;
+     184          35 :   lockContributors();
+     185          35 : }
+     186             : 
+     187        2568 : void SecondaryStructureRMSD::calculate() {
+     188        2568 :   runAllTasks();
+     189        2568 : }
+     190             : 
+     191      400032 : void SecondaryStructureRMSD::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     192             :   // Retrieve the positions
+     193      400032 :   std::vector<Vector> pos( references[0]->getNumberOfAtoms() );
+     194      400032 :   const unsigned n=pos.size();
+     195    12400992 :   for(unsigned i=0; i<n; ++i) pos[i]=ActionAtomistic::getPosition( getAtomIndex(current,i) );
+     196             : 
+     197             :   // This does strands cutoff
+     198      400032 :   Vector distance;
+     199      400032 :   if( nopbc ) distance=delta( pos[align_atom_1],pos[align_atom_2] );
+     200      400032 :   else distance=pbcDistance( pos[align_atom_1],pos[align_atom_2] );
+     201      400032 :   if( s_cutoff2>0 ) {
+     202      397524 :     if( distance.modulo2()>s_cutoff2 ) {
+     203             :       myvals.setValue( 0, 0.0 );
+     204      360914 :       return;
+     205             :     }
+     206             :   }
+     207             : 
+     208             :   // This aligns the two strands if this is required
+     209       39118 :   if( alignType!="DRMSD" && align_strands && !nopbc ) {
+     210      382260 :     for(unsigned i=0; i<14; ++i) {
+     211      356776 :       const Vector & first (pos[i]);
+     212      356776 :       Vector & second (pos[i+1]);
+     213      356776 :       second=first+pbcDistance(first,second);
+     214             :     }
+     215      356776 :     for(unsigned i=16; i<n-1; ++i) {
+     216      331292 :       const Vector & first (pos[i]);
+     217      331292 :       Vector & second (pos[i+1]);
+     218      331292 :       second=first+pbcDistance(first,second);
+     219             :     }
+     220       25484 :     Vector origin_old, origin_new; origin_old=pos[align_atom_2];
+     221       25484 :     origin_new=pos[align_atom_1]+distance;
+     222      407744 :     for(unsigned i=15; i<30; ++i) {
+     223      382260 :       pos[i]+=( origin_new - origin_old );
+     224             :     }
+     225       13634 :   } else if( alignType!="DRMSD" && !nopbc ) {
+     226           0 :     for(unsigned i=0; i<n-1; ++i) {
+     227           0 :       const Vector & first (pos[i]);
+     228           0 :       Vector & second (pos[i+1]);
+     229           0 :       second=first+pbcDistance(first,second);
+     230             :     }
+     231             :   }
+     232             :   // Create a holder for the derivatives
+     233       39118 :   ReferenceValuePack mypack( 0, pos.size(), myvals ); mypack.setValIndex( 1 );
+     234     1212658 :   for(unsigned i=0; i<n; ++i) mypack.setAtomIndex( i, getAtomIndex(current,i) );
+     235             : 
+     236             :   // And now calculate the RMSD
+     237             :   const Pbc& pbc=getPbc();
+     238             :   unsigned closest=0;
+     239       39118 :   double r = references[0]->calculate( pos, pbc, mypack, false );
+     240       39118 :   const unsigned rs = references.size();
+     241       57377 :   for(unsigned i=1; i<rs; ++i) {
+     242       18259 :     mypack.setValIndex( i+1 );
+     243       18259 :     double nr=references[i]->calculate( pos, pbc, mypack, false );
+     244       18259 :     if( nr<r ) { closest=i; r=nr; }
+     245             :   }
+     246             : 
+     247             :   // Transfer everything to the value
+     248             :   myvals.setValue( 0, 1.0 ); myvals.setValue( 1, r );
+     249       39118 :   if( closest>0 ) mypack.moveDerivatives( closest+1, 1 );
+     250             : 
+     251       39118 :   if( !mypack.virialWasSet() ) {
+     252       25484 :     Tensor vir;
+     253       25484 :     const unsigned cacs = colvar_atoms[current].size();
+     254      790004 :     for(unsigned i=0; i<cacs; ++i) {
+     255      764520 :       vir+=(-1.0*Tensor( pos[i], mypack.getAtomDerivative(i) ));
+     256             :     }
+     257       25484 :     mypack.setValIndex(1); mypack.addBoxDerivatives( vir );
+     258             :   }
+     259             : 
+     260             :   return;
+     261       39118 : }
+     262             : 
+     263         192 : void SecondaryStructureRMSD::apply() {
+     264         192 :   unsigned ind=0; if( getForcesFromVessels( forcesToApply ) ) setForcesOnAtoms( forcesToApply, ind );
+     265         192 : }
+     266             : 
+     267             : }
+     268             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html b/coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html new file mode 100644 index 000000000000..7cde91bbef6d --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/SecondaryStructureRMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - SecondaryStructureRMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD10isPeriodicEv25
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD21getNumberOfQuantitiesEv5424
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD22getNumberOfDerivativesEv5607
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html b/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html new file mode 100644 index 000000000000..b53b674c6ff2 --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/SecondaryStructureRMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - SecondaryStructureRMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD10isPeriodicEv25
_ZN4PLMD18secondarystructure22SecondaryStructureRMSD22getNumberOfDerivativesEv5607
_ZNK4PLMD18secondarystructure22SecondaryStructureRMSD21getNumberOfQuantitiesEv5424
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html b/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html new file mode 100644 index 000000000000..6edb230fa41e --- /dev/null +++ b/coverage/secondarystructure/SecondaryStructureRMSD.h.gcov.html @@ -0,0 +1,187 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure/SecondaryStructureRMSD.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructure - SecondaryStructureRMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_secondarystructure_SecondaryStructureRMSD_h
+      23             : #define __PLUMED_secondarystructure_SecondaryStructureRMSD_h
+      24             : 
+      25             : #include "core/ActionAtomistic.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : #include "vesselbase/ActionWithVessel.h"
+      28             : #include <vector>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : class SingleDomainRMSD;
+      33             : 
+      34             : namespace secondarystructure {
+      35             : 
+      36             : /// Base action for calculating things like AlphRMSD, AntibetaRMSD, etc
+      37             : 
+      38             : class SecondaryStructureRMSD :
+      39             :   public ActionAtomistic,
+      40             :   public ActionWithValue,
+      41             :   public vesselbase::ActionWithVessel
+      42             : {
+      43             : private:
+      44             : /// Are we operating without periodic boundary conditions
+      45             :   bool nopbc;
+      46             : /// The type of rmsd we are calculating
+      47             :   std::string alignType;
+      48             : /// List of all the atoms we require
+      49             :   std::vector<AtomNumber> all_atoms;
+      50             : /// The atoms involved in each of the secondary structure segments
+      51             :   std::vector< std::vector<unsigned> > colvar_atoms;
+      52             : /// The list of reference configurations
+      53             :   std::vector<std::unique_ptr<SingleDomainRMSD>> references;
+      54             : /// Variables for strands cutoff
+      55             :   bool align_strands;
+      56             :   double s_cutoff2;
+      57             :   unsigned align_atom_1, align_atom_2;
+      58             :   bool verbose_output;
+      59             : /// Tempory variables for getting positions of atoms and applying forces
+      60             :   std::vector<double> forcesToApply;
+      61             : /// Get the index of an atom
+      62             :   unsigned getAtomIndex( const unsigned& current, const unsigned& iatom ) const ;
+      63             : protected:
+      64             : /// Get the atoms in the backbone
+      65             :   void readBackboneAtoms( const std::string& backnames, std::vector<unsigned>& chain_lengths );
+      66             : /// Add a set of atoms to calculat ethe rmsd from
+      67             :   void addColvar( const std::vector<unsigned>& newatoms );
+      68             : /// Set a reference configuration
+      69             :   void setSecondaryStructure( std::vector<Vector>& structure, double bondlength, double units );
+      70             : /// Setup a pair of atoms to use for strands cutoff
+      71             :   void setAtomsFromStrands( const unsigned& atom1, const unsigned& atom2 );
+      72             : public:
+      73             :   static void registerKeywords( Keywords& keys );
+      74             :   explicit SecondaryStructureRMSD(const ActionOptions&);
+      75             :   virtual ~SecondaryStructureRMSD();
+      76             :   unsigned getNumberOfFunctionsInAction();
+      77             :   unsigned getNumberOfDerivatives() override;
+      78             :   unsigned getNumberOfQuantities() const override;
+      79             :   void turnOnDerivatives() override;
+      80             :   void calculate() override;
+      81             :   void performTask( const unsigned&, const unsigned&, MultiValue& ) const override;
+      82             :   void apply() override;
+      83          25 :   bool isPeriodic() override { return false; }
+      84             : };
+      85             : 
+      86             : inline
+      87        5424 : unsigned SecondaryStructureRMSD::getNumberOfQuantities() const {
+      88        5424 :   return 1 + references.size();
+      89             : }
+      90             : 
+      91             : 
+      92             : inline
+      93             : unsigned SecondaryStructureRMSD::getNumberOfFunctionsInAction() {
+      94             :   return colvar_atoms.size();
+      95             : }
+      96             : 
+      97             : inline
+      98        5607 : unsigned SecondaryStructureRMSD::getNumberOfDerivatives() {
+      99        5607 :   return 3*getNumberOfAtoms()+9;
+     100             : }
+     101             : 
+     102             : inline
+     103             : unsigned SecondaryStructureRMSD::getAtomIndex( const unsigned& current, const unsigned& iatom ) const {
+     104    13174500 :   return colvar_atoms[current][iatom];
+     105             : }
+     106             : 
+     107             : }
+     108             : }
+     109             : 
+     110             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/index-sort-f.html b/coverage/secondarystructure/index-sort-f.html new file mode 100644 index 000000000000..cb8af91b0dca --- /dev/null +++ b/coverage/secondarystructure/index-sort-f.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:37338696.6 %
Date:2024-02-22 21:58:45Functions:202676.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ParabetaRMSD.cpp +
97.2%97.2%
+
97.2 %105 / 10866.7 %2 / 3
AntibetaRMSD.cpp +
97.4%97.4%
+
97.4 %75 / 7766.7 %2 / 3
AlphaRMSD.cpp +
100.0%
+
100.0 %49 / 4966.7 %2 / 3
SecondaryStructureRMSD.cpp +
94.5%94.5%
+
94.5 %138 / 14678.6 %11 / 14
SecondaryStructureRMSD.h +
100.0%
+
100.0 %6 / 6100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/index-sort-l.html b/coverage/secondarystructure/index-sort-l.html new file mode 100644 index 000000000000..742e5eef84d2 --- /dev/null +++ b/coverage/secondarystructure/index-sort-l.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:37338696.6 %
Date:2024-02-22 21:58:45Functions:202676.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
SecondaryStructureRMSD.cpp +
94.5%94.5%
+
94.5 %138 / 14678.6 %11 / 14
ParabetaRMSD.cpp +
97.2%97.2%
+
97.2 %105 / 10866.7 %2 / 3
AntibetaRMSD.cpp +
97.4%97.4%
+
97.4 %75 / 7766.7 %2 / 3
SecondaryStructureRMSD.h +
100.0%
+
100.0 %6 / 6100.0 %3 / 3
AlphaRMSD.cpp +
100.0%
+
100.0 %49 / 4966.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/secondarystructure/index.html b/coverage/secondarystructure/index.html new file mode 100644 index 000000000000..2ac2db61c4f7 --- /dev/null +++ b/coverage/secondarystructure/index.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - secondarystructure + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - secondarystructureHitTotalCoverage
Test:plumed test coverageLines:37338696.6 %
Date:2024-02-22 21:58:45Functions:202676.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
AlphaRMSD.cpp +
100.0%
+
100.0 %49 / 4966.7 %2 / 3
AntibetaRMSD.cpp +
97.4%97.4%
+
97.4 %75 / 7766.7 %2 / 3
ParabetaRMSD.cpp +
97.2%97.2%
+
97.2 %105 / 10866.7 %2 / 3
SecondaryStructureRMSD.cpp +
94.5%94.5%
+
94.5 %138 / 14678.6 %11 / 14
SecondaryStructureRMSD.h +
100.0%
+
100.0 %6 / 6100.0 %3 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Load.cpp.func-sort-c.html b/coverage/setup/Load.cpp.func-sort-c.html new file mode 100644 index 000000000000..62f7c5f3a48f --- /dev/null +++ b/coverage/setup/Load.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Load.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Load.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup4LoadC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup4LoadC1ERKNS_13ActionOptionsE4
_ZN4PLMD5setup4Load16registerKeywordsERNS_8KeywordsE6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Load.cpp.func.html b/coverage/setup/Load.cpp.func.html new file mode 100644 index 000000000000..9eaa01b7fc53 --- /dev/null +++ b/coverage/setup/Load.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Load.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Load.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup4Load16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD5setup4LoadC1ERKNS_13ActionOptionsE4
_ZN4PLMD5setup4LoadC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Load.cpp.gcov.html b/coverage/setup/Load.cpp.gcov.html new file mode 100644 index 000000000000..02f975676800 --- /dev/null +++ b/coverage/setup/Load.cpp.gcov.html @@ -0,0 +1,200 @@ + + + + + + + + LCOV - plumed test coverage - setup/Load.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Load.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1010100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionSetup.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Exception.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace setup {
+      29             : 
+      30             : //+PLUMEDOC GENERIC LOAD
+      31             : /*
+      32             : Loads a library, possibly defining new actions.
+      33             : 
+      34             : It is available only
+      35             : on systems allowing for dynamic loading. It can also be fed with a cpp file,
+      36             : in which case the file is compiled first.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : If you have a shared object named extensions.so and want to
+      41             : use the functions implemented within it within PLUMED you can
+      42             : load it with the following syntax
+      43             : 
+      44             : \plumedfile
+      45             : LOAD FILE=extensions.so
+      46             : \endplumedfile
+      47             : 
+      48             : As a more practical example, imagine that you want to make a
+      49             : small change to one collective variable that is already implemented
+      50             : in PLUMED, say \ref DISTANCE . Copy the file `src/colvar/Distance.cpp`
+      51             : into your work directory, rename it as `Distance2.cpp`
+      52             : and  edit it as you wish. It might be better
+      53             : to also replace any occurrence of the string DISTANCE within the file
+      54             : with DISTANCE2, so that both old and new implementation will be available
+      55             : with different names. Then you can compile it into a shared object using
+      56             : \verbatim
+      57             : > plumed mklib Distance2.cpp
+      58             : \endverbatim
+      59             : This will generate a file `Distance2.so` (or `Distance2.dylib` on a mac)
+      60             : that can be loaded.
+      61             : Now you can use your new implementation with the following input
+      62             : \plumedfile
+      63             : # load the new library
+      64             : LOAD FILE=Distance2.so
+      65             : # compute standard distance
+      66             : d: DISTANCE ATOMS=1,10
+      67             : # compute modified distance
+      68             : d2: DISTANCE2 ATOMS=1,10
+      69             : # print them on a file
+      70             : PRINT ARG=d,d2 FILE=compare-them
+      71             : \endplumedfile
+      72             : 
+      73             : You can even skip the initial step and directly feed PLUMED
+      74             : with the `Distance2.cpp` file: it will be compiled on the fly.
+      75             : \plumedfile
+      76             : # load the new definition
+      77             : # this is a cpp file so it will be compiled
+      78             : LOAD FILE=Distance2.cpp
+      79             : # compute standard distance
+      80             : d: DISTANCE ATOMS=1,10
+      81             : # compute modified distance
+      82             : d2: DISTANCE2 ATOMS=1,10
+      83             : # print them on a file
+      84             : PRINT ARG=d,d2 FILE=compare-them
+      85             : \endplumedfile
+      86             : 
+      87             : This will allow to make quick tests while developing your own
+      88             : variables. Of course, after your implementation is ready you might
+      89             : want to add it to the PLUMED source tree and recompile
+      90             : the whole PLUMED.
+      91             : 
+      92             : 
+      93             : */
+      94             : //+ENDPLUMEDOC
+      95             : 
+      96             : class Load :
+      97             :   public virtual ActionSetup
+      98             : {
+      99             : public:
+     100             :   static void registerKeywords( Keywords& keys );
+     101             :   explicit Load(const ActionOptions&ao);
+     102             : };
+     103             : 
+     104             : PLUMED_REGISTER_ACTION(Load,"LOAD")
+     105             : 
+     106           6 : void Load::registerKeywords( Keywords& keys ) {
+     107           6 :   ActionSetup::registerKeywords(keys);
+     108          12 :   keys.add("compulsory","FILE","file to be loaded");
+     109           6 : }
+     110             : 
+     111           4 : Load::Load(const ActionOptions&ao):
+     112             :   Action(ao),
+     113           4 :   ActionSetup(ao)
+     114             : {
+     115             :   std::string f;
+     116           5 :   parse("FILE",f);
+     117           4 :   checkRead();
+     118           4 :   plumed.load(f);
+     119           4 : }
+     120             : 
+     121             : }
+     122             : }
+     123             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Restart.cpp.func-sort-c.html b/coverage/setup/Restart.cpp.func-sort-c.html new file mode 100644 index 000000000000..0ecf76aae902 --- /dev/null +++ b/coverage/setup/Restart.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Restart.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Restart.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup7RestartC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup7RestartC1ERKNS_13ActionOptionsE56
_ZN4PLMD5setup7Restart16registerKeywordsERNS_8KeywordsE58
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Restart.cpp.func.html b/coverage/setup/Restart.cpp.func.html new file mode 100644 index 000000000000..09acfd4fb608 --- /dev/null +++ b/coverage/setup/Restart.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Restart.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Restart.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup7Restart16registerKeywordsERNS_8KeywordsE58
_ZN4PLMD5setup7RestartC1ERKNS_13ActionOptionsE56
_ZN4PLMD5setup7RestartC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Restart.cpp.gcov.html b/coverage/setup/Restart.cpp.gcov.html new file mode 100644 index 000000000000..16b6c6290fde --- /dev/null +++ b/coverage/setup/Restart.cpp.gcov.html @@ -0,0 +1,202 @@ + + + + + + + + LCOV - plumed test coverage - setup/Restart.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Restart.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionSetup.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Exception.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace setup {
+      29             : 
+      30             : //+PLUMEDOC GENERIC RESTART
+      31             : /*
+      32             : Activate restart.
+      33             : 
+      34             : This is a Setup directive and, as such, should appear
+      35             : at the beginning of the input file. It influences the way
+      36             : PLUMED treat files open for writing (see also \ref Files).
+      37             : 
+      38             : Notice that it is also possible to enable or disable restart on a per-action
+      39             : basis using the RESTART keyword on a single action. In this case,
+      40             : the keyword should be assigned a value. RESTART=AUTO means that global
+      41             : settings are used, RESTART=YES or RESTART=NO respectively enable
+      42             : and disable restart for that single action.
+      43             : 
+      44             : \attention
+      45             : This directive can have also other side effects, e.g. on \ref METAD
+      46             : and \ref PBMETAD and on some analysis action.
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : Using the following input:
+      51             : \plumedfile
+      52             : d: DISTANCE ATOMS=1,2
+      53             : PRINT ARG=d FILE=out
+      54             : \endplumedfile
+      55             : a new 'out' file will be created. If an old one is on the way, it will be automatically backed up.
+      56             : 
+      57             : On the other hand, using the following input:
+      58             : \plumedfile
+      59             : RESTART
+      60             : d: DISTANCE ATOMS=1,2
+      61             : PRINT ARG=d FILE=out
+      62             : \endplumedfile
+      63             : the file 'out' will be appended.
+      64             : 
+      65             : In the following case, file out1 will be backed up and file out2 will be concatenated
+      66             : \plumedfile
+      67             : RESTART
+      68             : d1: DISTANCE ATOMS=1,2
+      69             : d2: DISTANCE ATOMS=1,2
+      70             : PRINT ARG=d1 FILE=out1 RESTART=NO
+      71             : PRINT ARG=d2 FILE=out2
+      72             : \endplumedfile
+      73             : 
+      74             : In the following case, file out will backed up even if the MD code thinks that we
+      75             : are restarting. Notice that not all the MD code send to PLUMED information about restarts.
+      76             : If you are not sure, always put `RESTART` when you are restarting and nothing when you aren't
+      77             : \plumedfile
+      78             : RESTART NO
+      79             : d1: DISTANCE ATOMS=1,2
+      80             : PRINT ARG=d1 FILE=out1
+      81             : \endplumedfile
+      82             : 
+      83             : 
+      84             : 
+      85             : 
+      86             : 
+      87             : */
+      88             : //+ENDPLUMEDOC
+      89             : 
+      90             : class Restart :
+      91             :   public virtual ActionSetup
+      92             : {
+      93             : public:
+      94             :   static void registerKeywords( Keywords& keys );
+      95             :   explicit Restart(const ActionOptions&ao);
+      96             : };
+      97             : 
+      98             : PLUMED_REGISTER_ACTION(Restart,"RESTART")
+      99             : 
+     100          58 : void Restart::registerKeywords( Keywords& keys ) {
+     101          58 :   ActionSetup::registerKeywords(keys);
+     102         116 :   keys.addFlag("NO",false,"switch off restart - can be used to override the behavior of the MD engine");
+     103          58 : }
+     104             : 
+     105          56 : Restart::Restart(const ActionOptions&ao):
+     106             :   Action(ao),
+     107          56 :   ActionSetup(ao)
+     108             : {
+     109          56 :   bool no=false;
+     110          56 :   parseFlag("NO",no);
+     111          56 :   bool md=plumed.getRestart();
+     112         111 :   log<<"  MD code "<<(md?"did":"didn't")<<" require restart\n";
+     113          56 :   if(no) {
+     114           1 :     if(md) log<<"  Switching off restart\n";
+     115           1 :     plumed.setRestart(false);
+     116           1 :     log<<"  Not restarting simulation: files will be backed up\n";
+     117             :   } else {
+     118          55 :     if(!md) log<<"  Switching on restart\n";
+     119          55 :     plumed.setRestart(true);
+     120          55 :     log<<"  Restarting simulation: files will be appended\n";
+     121             :   }
+     122          56 : }
+     123             : 
+     124             : }
+     125             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Units.cpp.func-sort-c.html b/coverage/setup/Units.cpp.func-sort-c.html new file mode 100644 index 000000000000..5dbdb052f1e5 --- /dev/null +++ b/coverage/setup/Units.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Units.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup5UnitsC2ERKNS_13ActionOptionsE0
_ZN4PLMD5setup5UnitsC1ERKNS_13ActionOptionsE20
_ZN4PLMD5setup5Units16registerKeywordsERNS_8KeywordsE22
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Units.cpp.func.html b/coverage/setup/Units.cpp.func.html new file mode 100644 index 000000000000..a4f6daee6f5e --- /dev/null +++ b/coverage/setup/Units.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - setup/Units.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5setup5Units16registerKeywordsERNS_8KeywordsE22
_ZN4PLMD5setup5UnitsC1ERKNS_13ActionOptionsE20
_ZN4PLMD5setup5UnitsC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/Units.cpp.gcov.html b/coverage/setup/Units.cpp.gcov.html new file mode 100644 index 000000000000..6b24c520ea98 --- /dev/null +++ b/coverage/setup/Units.cpp.gcov.html @@ -0,0 +1,275 @@ + + + + + + + + LCOV - plumed test coverage - setup/Units.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setup - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545696.4 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "core/ActionSetup.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "tools/Exception.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace setup {
+      29             : 
+      30             : //+PLUMEDOC GENERIC UNITS
+      31             : /*
+      32             : This command sets the internal units for the code.
+      33             : 
+      34             : A new unit can be set by either
+      35             : specifying a conversion factor from the plumed default unit or by using a string
+      36             : corresponding to one of the defined units given below.  This directive MUST
+      37             : appear at the BEGINNING of the plumed.dat file.  The same units must be used
+      38             : throughout the plumed.dat file.
+      39             : 
+      40             : Notice that all input/output will then be made using the specified units.
+      41             : That is: all the input parameters, all the output files, etc. The only
+      42             : exceptions are file formats for which there is a specific convention concerning
+      43             : the units. For example, trajectories written in .gro format (with \ref DUMPATOMS)
+      44             : are going to be always in nm.
+      45             : 
+      46             : The following strings can be used to specify units. Note that the strings are
+      47             : case sensitive.
+      48             : - LENGTH: nm (default), A (for Angstrom), um (for micrometer), Bohr (0.052917721067 nm)
+      49             : - ENERGY: kj/mol (default), j/mol, kcal/mol (4.184 kj/mol), eV (96.48530749925792 kj/mol), Ha (for Hartree, 2625.499638 kj/mol)
+      50             : - TIME: ps (default), fs, ns, atomic (2.418884326509e-5 ps)
+      51             : - MASS: amu (default)
+      52             : - CHARGE: e (default)
+      53             : 
+      54             : 
+      55             : \par Examples
+      56             : 
+      57             : \plumedfile
+      58             : # this is using Angstrom - kj/mol - fs
+      59             : UNITS LENGTH=A TIME=fs
+      60             : 
+      61             : # compute distance between atoms 1 and 4
+      62             : d: DISTANCE ATOMS=1,4
+      63             : 
+      64             : # print time and distance on a COLVAR file
+      65             : PRINT ARG=d FILE=COLVAR
+      66             : 
+      67             : # dump atoms 1 to 100 on a 'out.gro' file
+      68             : DUMPATOMS FILE=out.gro STRIDE=10 ATOMS=1-100
+      69             : 
+      70             : # dump atoms 1 to 100 on a 'out.xyz' file
+      71             : DUMPATOMS FILE=out.xyz STRIDE=10 ATOMS=1-100
+      72             : \endplumedfile
+      73             : 
+      74             : In the `COLVAR` file, time and distance will appear in fs and A respectively, *irrespective* of which units
+      75             : you are using in the host MD code. The coordinates in the `out.gro` file will be expressed in nm,
+      76             : since `gro` files are by convention written in nm. The coordinates in the `out.xyz` file
+      77             : will be written in Angstrom *since we used the UNITS command setting Angstrom units*.
+      78             : Indeed, within PLUMED xyz files are using internal PLUMED units and not necessarily Angstrom!
+      79             : 
+      80             : If a number, x, is found instead of a string, the new unit is equal to x times the default units.
+      81             : Using the following command as first line of the previous example would have lead to an identical result:
+      82             : \plumedfile
+      83             : UNITS LENGTH=0.1 TIME=0.001
+      84             : \endplumedfile
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : class Units :
+      90             :   public virtual ActionSetup
+      91             : {
+      92             : public:
+      93             :   static void registerKeywords( Keywords& keys );
+      94             :   explicit Units(const ActionOptions&ao);
+      95             : };
+      96             : 
+      97             : PLUMED_REGISTER_ACTION(Units,"UNITS")
+      98             : 
+      99          22 : void Units::registerKeywords( Keywords& keys ) {
+     100          22 :   ActionSetup::registerKeywords(keys);
+     101          44 :   keys.add("optional","LENGTH","the units of lengths.  Either specify a conversion factor from the default, nm, or use one of the defined units, A (for angstroms), um (for micrometer), and Bohr.");
+     102          44 :   keys.add("optional","ENERGY","the units of energy.  Either specify a conversion factor from the default, kj/mol, or use one of the defined units, j/mol, kcal/mol and Ha (for Hartree)");
+     103          44 :   keys.add("optional","TIME","the units of time.  Either specify a conversion factor from the default, ps, or use one of the defined units, ns, fs, and atomic");
+     104          44 :   keys.add("optional","MASS","the units of masses.  Specify a conversion factor from the default, amu");
+     105          44 :   keys.add("optional","CHARGE","the units of charges.  Specify a conversion factor from the default, e");
+     106          44 :   keys.addFlag("NATURAL",false,"use natural units");
+     107          22 : }
+     108             : 
+     109          20 : Units::Units(const ActionOptions&ao):
+     110             :   Action(ao),
+     111          20 :   ActionSetup(ao)
+     112             : {
+     113          20 :   PLMD::Units u;
+     114             : 
+     115             :   std::string s;
+     116             : 
+     117             :   s="";
+     118          40 :   parse("LENGTH",s);
+     119          20 :   if(s.length()>0) u.setLength(s);
+     120          38 :   if(u.getLengthString().length()>0 && u.getLengthString()=="nm") {
+     121           8 :     log.printf("  length: %s\n",u.getLengthString().c_str());
+     122             :   }
+     123          22 :   else if(u.getLengthString().length()>0 && u.getLengthString()!="nm") {
+     124          10 :     log.printf("  length: %s = %g nm\n",u.getLengthString().c_str(),u.getLength());
+     125             :   }
+     126             :   else {
+     127           2 :     log.printf("  length: %g nm\n",u.getLength());
+     128             :   }
+     129             : 
+     130             :   s="";
+     131          40 :   parse("ENERGY",s);
+     132          20 :   if(s.length()>0) u.setEnergy(s);
+     133          38 :   if(u.getEnergyString().length()>0 && u.getEnergyString()=="kj/mol") {
+     134          13 :     log.printf("  energy: %s\n",u.getEnergyString().c_str());
+     135             :   }
+     136          12 :   else if(u.getEnergyString().length()>0 && u.getEnergyString()!="kj/mol") {
+     137           5 :     log.printf("  energy: %s = %g kj/mol\n",u.getEnergyString().c_str(),u.getEnergy());
+     138             :   }
+     139             :   else {
+     140           2 :     log.printf("  energy: %g kj/mol\n",u.getEnergy());
+     141             :   }
+     142             : 
+     143             :   s="";
+     144          40 :   parse("TIME",s);
+     145          20 :   if(s.length()>0) u.setTime(s);
+     146          38 :   if(u.getTimeString().length()>0 && u.getTimeString()=="ps") {
+     147          15 :     log.printf("  time: %s\n",u.getTimeString().c_str());
+     148             :   }
+     149           8 :   else if(u.getTimeString().length()>0 && u.getTimeString()!="ps") {
+     150           3 :     log.printf("  time: %s = %g ps\n",u.getTimeString().c_str(),u.getTime());
+     151             :   }
+     152             :   else {
+     153           2 :     log.printf("  time: %g ps\n",u.getTime());
+     154             :   }
+     155             : 
+     156             :   s="";
+     157          40 :   parse("CHARGE",s);
+     158          20 :   if(s.length()>0) u.setCharge(s);
+     159          38 :   if(u.getChargeString().length()>0 && u.getChargeString()=="e") {
+     160          18 :     log.printf("  charge: %s\n",u.getChargeString().c_str());
+     161             :   }
+     162           2 :   else if(u.getChargeString().length()>0 && u.getChargeString()!="e") {
+     163           0 :     log.printf("  charge: %s = %g e\n",u.getChargeString().c_str(),u.getCharge());
+     164             :   }
+     165             :   else {
+     166           2 :     log.printf("  charge: %g e\n",u.getCharge());
+     167             :   }
+     168             : 
+     169             :   s="";
+     170          40 :   parse("MASS",s);
+     171          20 :   if(s.length()>0) u.setMass(s);
+     172          39 :   if(u.getMassString().length()>0 && u.getMassString()=="amu") {
+     173          19 :     log.printf("  mass: %s\n",u.getMassString().c_str());
+     174             :   }
+     175           1 :   else if(u.getMassString().length()>0 && u.getMassString()!="amu") {
+     176           0 :     log.printf("  mass: %s = %g amu\n",u.getMassString().c_str(),u.getMass());
+     177             :   }
+     178             :   else {
+     179           1 :     log.printf("  mass: %g amu\n",u.getMass());
+     180             :   }
+     181             : 
+     182          20 :   bool natural=false;
+     183          20 :   parseFlag("NATURAL",natural);
+     184             : 
+     185          20 :   checkRead();
+     186             : 
+     187          20 :   if(natural) {
+     188           6 :     log.printf("  using natural units\n");
+     189             :   } else {
+     190          14 :     log.printf("  using physical units\n");
+     191             :   }
+     192          20 :   log.printf("  inside PLUMED, Boltzmann constant is %g\n",getKBoltzmann());
+     193             : 
+     194          20 :   plumed.setUnits(natural,u);
+     195          20 : }
+     196             : 
+     197             : }
+     198             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/index-sort-f.html b/coverage/setup/index-sort-f.html new file mode 100644 index 000000000000..f6d162badeb1 --- /dev/null +++ b/coverage/setup/index-sort-f.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:828497.6 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Units.cpp +
96.4%96.4%
+
96.4 %54 / 5666.7 %2 / 3
Restart.cpp +
100.0%
+
100.0 %18 / 1866.7 %2 / 3
Load.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/index-sort-l.html b/coverage/setup/index-sort-l.html new file mode 100644 index 000000000000..a6c95b0e0b3c --- /dev/null +++ b/coverage/setup/index-sort-l.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:828497.6 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Units.cpp +
96.4%96.4%
+
96.4 %54 / 5666.7 %2 / 3
Load.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
Restart.cpp +
100.0%
+
100.0 %18 / 1866.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/setup/index.html b/coverage/setup/index.html new file mode 100644 index 000000000000..b7c0f307ddfa --- /dev/null +++ b/coverage/setup/index.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - setup + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - setupHitTotalCoverage
Test:plumed test coverageLines:828497.6 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Load.cpp +
100.0%
+
100.0 %10 / 1066.7 %2 / 3
Restart.cpp +
100.0%
+
100.0 %18 / 1866.7 %2 / 3
Units.cpp +
96.4%96.4%
+
96.4 %54 / 5666.7 %2 / 3
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/index-sort-f.html b/coverage/small_vector/index-sort-f.html new file mode 100644 index 000000000000..f92aadbda249 --- /dev/null +++ b/coverage/small_vector/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - small_vector + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vectorHitTotalCoverage
Test:plumed test coverageLines:637188.7 %
Date:2024-02-22 21:58:45Functions:142070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
small_vector.h +
88.7%88.7%
+
88.7 %63 / 7170.0 %14 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/index-sort-l.html b/coverage/small_vector/index-sort-l.html new file mode 100644 index 000000000000..21548c087d54 --- /dev/null +++ b/coverage/small_vector/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - small_vector + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vectorHitTotalCoverage
Test:plumed test coverageLines:637188.7 %
Date:2024-02-22 21:58:45Functions:142070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
small_vector.h +
88.7%88.7%
+
88.7 %63 / 7170.0 %14 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/index.html b/coverage/small_vector/index.html new file mode 100644 index 000000000000..ec300618982f --- /dev/null +++ b/coverage/small_vector/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - small_vector + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vectorHitTotalCoverage
Test:plumed test coverageLines:637188.7 %
Date:2024-02-22 21:58:45Functions:142070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
small_vector.h +
88.7%88.7%
+
88.7 %63 / 7170.0 %14 / 20
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/small_vector.h.func-sort-c.html b/coverage/small_vector/small_vector.h.func-sort-c.html new file mode 100644 index 000000000000..c5576a992e80 --- /dev/null +++ b/coverage/small_vector/small_vector.h.func-sort-c.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - small_vector/small_vector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vector - small_vector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:637188.7 %
Date:2024-02-22 21:58:45Functions:142070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE18allocation_end_ptrEv0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE29emplace_into_reallocation_endIJS4_EEEPS4_DpOT_0
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail19allocator_interfaceISaINS_13VectorGenericILj3EEEEE18uninitialized_copyIPS4_Lb1EEES8_T_S9_S8_0
_ZNK4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE18allocation_end_ptrEv0
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE18allocation_end_ptrEv172
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE29emplace_into_reallocation_endIJRPKcRmEEEPS6_DpOT_172
_ZN4PLMD3gch6detail19allocator_interfaceISaISt17basic_string_viewIcSt11char_traitsIcEEEE18uninitialized_copyIPS6_Lb1EEESA_T_SB_SA_172
_ZN4PLMD3gch6detail19allocator_interfaceISaINS_13VectorGenericILj3EEEEE18uninitialized_copyIPKS4_Lb1EEEPS4_T_SB_SA_22886
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE4wipeEv96840
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE14append_elementIJS4_EEEPS4_DpOT_475300
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE24emplace_into_current_endIJS4_EEEPS4_DpOT_475300
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE4wipeEv1132823
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE24emplace_into_current_endIJRPKcRmEEEPS6_DpOT_1147101
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE14append_elementIJRPKcRmEEEPS6_DpOT_1147273
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE19copy_assign_defaultILj6EEERS6_RKNS2_IS5_XT_EEE1279312
_ZNK4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE7end_ptrEv1279312
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE7end_ptrEv2491720
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE7end_ptrEv4559848
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/small_vector.h.func.html b/coverage/small_vector/small_vector.h.func.html new file mode 100644 index 000000000000..fb169f8a09cd --- /dev/null +++ b/coverage/small_vector/small_vector.h.func.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - small_vector/small_vector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vector - small_vector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:637188.7 %
Date:2024-02-22 21:58:45Functions:142070.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE14append_elementIJS4_EEEPS4_DpOT_475300
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE18allocation_end_ptrEv0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE19copy_assign_defaultILj6EEERS6_RKNS2_IS5_XT_EEE1279312
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE24emplace_into_current_endIJS4_EEEPS4_DpOT_475300
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE29emplace_into_reallocation_endIJS4_EEEPS4_DpOT_0
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE4wipeEv96840
_ZN4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE7end_ptrEv2491720
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE14append_elementIJRPKcRmEEEPS6_DpOT_1147273
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE18allocation_end_ptrEv172
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE24emplace_into_current_endIJRPKcRmEEEPS6_DpOT_1147101
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE27throw_allocation_size_errorEv0
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE29emplace_into_reallocation_endIJRPKcRmEEEPS6_DpOT_172
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE4wipeEv1132823
_ZN4PLMD3gch6detail17small_vector_baseISaISt17basic_string_viewIcSt11char_traitsIcEEELj2EE7end_ptrEv4559848
_ZN4PLMD3gch6detail19allocator_interfaceISaINS_13VectorGenericILj3EEEEE18uninitialized_copyIPKS4_Lb1EEEPS4_T_SB_SA_22886
_ZN4PLMD3gch6detail19allocator_interfaceISaINS_13VectorGenericILj3EEEEE18uninitialized_copyIPS4_Lb1EEES8_T_S9_S8_0
_ZN4PLMD3gch6detail19allocator_interfaceISaISt17basic_string_viewIcSt11char_traitsIcEEEE18uninitialized_copyIPS6_Lb1EEESA_T_SB_SA_172
_ZNK4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE18allocation_end_ptrEv0
_ZNK4PLMD3gch6detail17small_vector_baseISaINS_13VectorGenericILj3EEEELj6EE7end_ptrEv1279312
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/small_vector/small_vector.h.gcov.html b/coverage/small_vector/small_vector.h.gcov.html new file mode 100644 index 000000000000..b9dcd69deeae --- /dev/null +++ b/coverage/small_vector/small_vector.h.gcov.html @@ -0,0 +1,6560 @@ + + + + + + + + LCOV - plumed test coverage - small_vector/small_vector.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - small_vector - small_vector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:637188.7 %
Date:2024-02-22 21:58:45Functions:142070.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :  * An implementation of `small_vector` (a vector with a small
+       3             :  * buffer optimization). I would probably have preferred to
+       4             :  * call this `inline_vector`, but I'll just go with the canonical
+       5             :  * name for now.
+       6             :  *
+       7             :  * Copyright © 2020-2021 Gene Harvey
+       8             :  *
+       9             :  * This software may be modified and distributed under the terms
+      10             :  * of the MIT license. See the LICENSE file for details.
+      11             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      12             : #ifndef __PLUMED_small_vector_small_vector_h
+      13             : #define __PLUMED_small_vector_small_vector_h
+      14             : /** small_vector.hpp
+      15             :  * An implementation of `small_vector` (a vector with a small
+      16             :  * buffer optimization). I would probably have preferred to
+      17             :  * call this `inline_vector`, but I'll just go with the canonical
+      18             :  * name for now.
+      19             :  *
+      20             :  * Copyright © 2020-2021 Gene Harvey
+      21             :  *
+      22             :  * This software may be modified and distributed under the terms
+      23             :  * of the MIT license. See the LICENSE file for details.
+      24             :  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
+      25             : 
+      26             : #ifndef PLUMED_GCH_SMALL_VECTOR_HPP
+      27             : #define PLUMED_GCH_SMALL_VECTOR_HPP
+      28             : 
+      29             : #ifdef __clang__
+      30             : #  ifndef PLUMED_GCH_CLANG
+      31             : #    define PLUMED_GCH_CLANG
+      32             : #  endif
+      33             : #  if defined (__cplusplus) && __cplusplus >= 201103L
+      34             : #    ifndef PLUMED_GCH_CLANG_11
+      35             : #      define PLUMED_GCH_CLANG_11
+      36             : #    endif
+      37             : #  endif
+      38             : #  if defined (__cplusplus) && __cplusplus >= 201402L
+      39             : #    ifndef PLUMED_GCH_CLANG_14
+      40             : #      define PLUMED_GCH_CLANG_14
+      41             : #    endif
+      42             : #  endif
+      43             : #  if defined (__cplusplus) && __cplusplus >= 201703L
+      44             : #    ifndef PLUMED_GCH_CLANG_17
+      45             : #      define PLUMED_GCH_CLANG_17
+      46             : #    endif
+      47             : #  endif
+      48             : #  if defined (__cplusplus) && __cplusplus >= 202002L
+      49             : #    ifndef PLUMED_GCH_CLANG_20
+      50             : #      define PLUMED_GCH_CLANG_20
+      51             : #    endif
+      52             : #  endif
+      53             : #endif
+      54             : 
+      55             : #ifndef PLUMED_GCH_CPP14_CONSTEXPR
+      56             : #  if defined (__cpp_constexpr) && __cpp_constexpr >= 201304L
+      57             : #    define PLUMED_GCH_CPP14_CONSTEXPR constexpr
+      58             : #    ifndef PLUMED_GCH_HAS_CPP14_CONSTEXPR
+      59             : #      define PLUMED_GCH_HAS_CPP14_CONSTEXPR
+      60             : #    endif
+      61             : #  else
+      62             : #    define PLUMED_GCH_CPP14_CONSTEXPR
+      63             : #  endif
+      64             : #endif
+      65             : 
+      66             : #ifndef PLUMED_GCH_CPP17_CONSTEXPR
+      67             : #  if defined (__cpp_constexpr) && __cpp_constexpr >= 201603L
+      68             : #    define PLUMED_GCH_CPP17_CONSTEXPR constexpr
+      69             : #    ifndef PLUMED_GCH_HAS_CPP17_CONSTEXPR
+      70             : #      define PLUMED_GCH_HAS_CPP17_CONSTEXPR
+      71             : #    endif
+      72             : #  else
+      73             : #    define PLUMED_GCH_CPP17_CONSTEXPR
+      74             : #  endif
+      75             : #endif
+      76             : 
+      77             : #ifndef PLUMED_GCH_CPP20_CONSTEXPR
+      78             : #  if defined (__cpp_constexpr) && __cpp_constexpr >= 201907L
+      79             : #    define PLUMED_GCH_CPP20_CONSTEXPR constexpr
+      80             : #    ifndef PLUMED_GCH_HAS_CPP20_CONSTEXPR
+      81             : #      define PLUMED_GCH_HAS_CPP20_CONSTEXPR
+      82             : #    endif
+      83             : #  else
+      84             : #    define PLUMED_GCH_CPP20_CONSTEXPR
+      85             : #  endif
+      86             : #endif
+      87             : 
+      88             : #ifndef PLUMED_GCH_NORETURN
+      89             : #  if defined (__has_cpp_attribute) && __has_cpp_attribute (noreturn) >= 200809L
+      90             : #    define PLUMED_GCH_NORETURN [[noreturn]]
+      91             : #  else
+      92             : #    define PLUMED_GCH_NORETURN
+      93             : #  endif
+      94             : #endif
+      95             : 
+      96             : #ifndef PLUMED_GCH_NODISCARD
+      97             : #  if defined (__has_cpp_attribute) && __has_cpp_attribute (nodiscard) >= 201603L
+      98             : #    if ! defined (__clang__) || defined (PLUMED_GCH_CLANG_17)
+      99             : #      define PLUMED_GCH_NODISCARD [[nodiscard]]
+     100             : #    else
+     101             : #      define PLUMED_GCH_NODISCARD
+     102             : #    endif
+     103             : #  else
+     104             : #    define PLUMED_GCH_NODISCARD
+     105             : #  endif
+     106             : #endif
+     107             : 
+     108             : #ifndef PLUMED_GCH_INLINE_VARIABLE
+     109             : #  if defined (__cpp_inline_variables) && __cpp_inline_variables >= 201606L
+     110             : #    define PLUMED_GCH_INLINE_VARIABLE inline
+     111             : #  else
+     112             : #    define PLUMED_GCH_INLINE_VARIABLE
+     113             : #  endif
+     114             : #endif
+     115             : 
+     116             : #ifndef PLUMED_GCH_EMPTY_BASE
+     117             : #  if defined (_MSC_FULL_VER) && _MSC_FULL_VER >= 190023918L
+     118             : #    define PLUMED_GCH_EMPTY_BASE __declspec (empty_bases)
+     119             : #  else
+     120             : #    define PLUMED_GCH_EMPTY_BASE
+     121             : #  endif
+     122             : #endif
+     123             : 
+     124             : #ifndef PLUMED_GCH_IMPLICIT_CONVERSION
+     125             : #  if defined (__cpp_conditional_explicit) && __cpp_conditional_explicit >= 201806L
+     126             : #    define PLUMED_GCH_IMPLICIT_CONVERSION explicit (false)
+     127             : #  else
+     128             : #    define PLUMED_GCH_IMPLICIT_CONVERSION /* implicit */
+     129             : #  endif
+     130             : #endif
+     131             : 
+     132             : #if defined (__cpp_variable_templates) && __cpp_variable_templates >= 201304L
+     133             : #  ifndef PLUMED_GCH_VARIABLE_TEMPLATES
+     134             : #    define PLUMED_GCH_VARIABLE_TEMPLATES
+     135             : #  endif
+     136             : #endif
+     137             : 
+     138             : #if defined (__cpp_deduction_guides) && __cpp_deduction_guides >= 201703L
+     139             : #  ifndef PLUMED_GCH_CTAD_SUPPORT
+     140             : #    define PLUMED_GCH_CTAD_SUPPORT
+     141             : #  endif
+     142             : #endif
+     143             : 
+     144             : #if defined (__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L
+     145             : #  ifndef PLUMED_GCH_CONSTEXPR_IF
+     146             : #    define PLUMED_GCH_CONSTEXPR_IF
+     147             : #  endif
+     148             : #endif
+     149             : 
+     150             : #if defined (__cpp_exceptions) && __cpp_exceptions >= 199711L
+     151             : #  ifndef PLUMED_GCH_EXCEPTIONS
+     152             : #    define PLUMED_GCH_EXCEPTIONS
+     153             : #  endif
+     154             : #endif
+     155             : 
+     156             : #ifndef PLUMED_GCH_TRY
+     157             : #  ifdef PLUMED_GCH_EXCEPTIONS
+     158             : #    define PLUMED_GCH_TRY try
+     159             : #  else
+     160             : #    ifdef PLUMED_GCH_CONSTEXPR_IF
+     161             : #      define PLUMED_GCH_TRY if constexpr (true)
+     162             : #    else
+     163             : #      define PLUMED_GCH_TRY if (true)
+     164             : #    endif
+     165             : #  endif
+     166             : #endif
+     167             : 
+     168             : #ifndef PLUMED_GCH_CATCH
+     169             : #  ifdef PLUMED_GCH_EXCEPTIONS
+     170             : #    define PLUMED_GCH_CATCH(...) catch (__VA_ARGS__)
+     171             : #  else
+     172             : #    ifdef PLUMED_GCH_CONSTEXPR_IF
+     173             : #      define PLUMED_GCH_CATCH(...) else if constexpr (false)
+     174             : #    else
+     175             : #      define PLUMED_GCH_CATCH(...) else if (false)
+     176             : #    endif
+     177             : #  endif
+     178             : #endif
+     179             : 
+     180             : #ifndef PLUMED_GCH_THROW
+     181             : #  ifdef PLUMED_GCH_EXCEPTIONS
+     182             : #    define PLUMED_GCH_THROW throw
+     183             : #  else
+     184             : #    define PLUMED_GCH_THROW
+     185             : #  endif
+     186             : #endif
+     187             : 
+     188             : #ifndef PLUMED_GCH_CONSTEVAL
+     189             : #  if defined (__cpp_consteval) && __cpp_consteval >= 201811L
+     190             : #    define PLUMED_GCH_CONSTEVAL consteval
+     191             : #    ifndef PLUMED_GCH_HAS_CONSTEVAL
+     192             : #      define PLUMED_GCH_HAS_CONSTEVAL
+     193             : #    endif
+     194             : #  else
+     195             : #    define PLUMED_GCH_CONSTEVAL constexpr
+     196             : #  endif
+     197             : #endif
+     198             : 
+     199             : #if defined (__cpp_impl_three_way_comparison) && __cpp_impl_three_way_comparison >= 201907L
+     200             : #  ifndef PLUMED_GCH_IMPL_THREE_WAY_COMPARISON
+     201             : #    define PLUMED_GCH_IMPL_THREE_WAY_COMPARISON
+     202             : #  endif
+     203             : #endif
+     204             : 
+     205             : #if defined (__cpp_concepts) && __cpp_concepts >= 201907L
+     206             : #  ifndef PLUMED_GCH_CONCEPTS
+     207             : #    define PLUMED_GCH_CONCEPTS
+     208             : #  endif
+     209             : #endif
+     210             : 
+     211             : #include <algorithm>
+     212             : #include <cassert>
+     213             : #include <cstddef>
+     214             : #include <cstdint>
+     215             : #include <cstring>
+     216             : #include <initializer_list>
+     217             : #include <iterator>
+     218             : #include <limits>
+     219             : #include <memory>
+     220             : #include <new>
+     221             : #include <type_traits>
+     222             : #include <utility>
+     223             : 
+     224             : #ifdef PLUMED_GCH_IMPL_THREE_WAY_COMPARISON
+     225             : #  if defined (__has_include) && __has_include (<compare>)
+     226             : #    include <compare>
+     227             : #  endif
+     228             : #endif
+     229             : 
+     230             : #ifdef PLUMED_GCH_CONCEPTS
+     231             : #  if defined (__has_include) && __has_include (<concepts>)
+     232             : #    include <concepts>
+     233             : #  endif
+     234             : #endif
+     235             : 
+     236             : #ifdef PLUMED_GCH_STDLIB_INTEROP
+     237             : #  include <array>
+     238             : #  include <valarray>
+     239             : #  include <vector>
+     240             : #endif
+     241             : 
+     242             : #ifdef PLUMED_GCH_EXCEPTIONS
+     243             : #  include <stdexcept>
+     244             : #else
+     245             : #  include <cstdio>
+     246             : #  include <cstdlib>
+     247             : #endif
+     248             : 
+     249             : #if defined (__cpp_lib_three_way_comparison) && __cpp_lib_three_way_comparison >= 201907L
+     250             : #  ifndef PLUMED_GCH_LIB_THREE_WAY_COMPARISON
+     251             : #    define PLUMED_GCH_LIB_THREE_WAY_COMPARISON
+     252             : #  endif
+     253             : #endif
+     254             : 
+     255             : #if defined (__cpp_lib_concepts) && __cpp_lib_concepts >= 202002L
+     256             : #  if ! defined (PLUMED_GCH_LIB_CONCEPTS) && ! defined (PLUMED_GCH_DISABLE_CONCEPTS)
+     257             : #    define PLUMED_GCH_LIB_CONCEPTS
+     258             : #  endif
+     259             : #endif
+     260             : 
+     261             : #if defined (__cpp_lib_is_final) && __cpp_lib_is_final >= 201402L
+     262             : #  ifndef PLUMED_GCH_LIB_IS_FINAL
+     263             : #    define PLUMED_GCH_LIB_IS_FINAL
+     264             : #  endif
+     265             : #endif
+     266             : 
+     267             : #if defined (__cpp_lib_is_constant_evaluated) && __cpp_lib_is_constant_evaluated >= 201811L
+     268             : #  ifndef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+     269             : #    define PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+     270             : #  endif
+     271             : #endif
+     272             : 
+     273             : #if defined (__cpp_lib_is_swappable) && __cpp_lib_is_swappable >= 201603L
+     274             : #  ifndef PLUMED_GCH_LIB_IS_SWAPPABLE
+     275             : #    define PLUMED_GCH_LIB_IS_SWAPPABLE
+     276             : #  endif
+     277             : #endif
+     278             : 
+     279             : #if defined (__cpp_lib_allocator_traits_is_always_equal)
+     280             : #  if __cpp_lib_allocator_traits_is_always_equal >= 201411L
+     281             : #    ifndef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+     282             : #      define PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+     283             : #    endif
+     284             : #  endif
+     285             : #endif
+     286             : 
+     287             : #if defined (__cpp_lib_constexpr_memory) && __cpp_lib_constexpr_memory >= 201811L
+     288             : #  ifndef PLUMED_GCH_LIB_CONSTEXPR_MEMORY
+     289             : #    define PLUMED_GCH_LIB_CONSTEXPR_MEMORY
+     290             : #  endif
+     291             : #endif
+     292             : 
+     293             : // TODO:
+     294             : //   Make sure we don't need any laundering in the internal class functions.
+     295             : //   I also need some sort of test case to actually show where UB is occurring,
+     296             : //   because it's still a bit unclear to me.
+     297             : #if defined (__cpp_lib_launder) && __cpp_lib_launder >= 201606L
+     298             : #  ifndef PLUMED_GCH_LIB_LAUNDER
+     299             : #    define PLUMED_GCH_LIB_LAUNDER
+     300             : #  endif
+     301             : #endif
+     302             : 
+     303             : // defined if the entire thing is available for constexpr
+     304             : #ifndef PLUMED_GCH_SMALL_VECTOR_CONSTEXPR
+     305             : #  if defined (PLUMED_GCH_HAS_CPP20_CONSTEXPR) && defined (PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED) \
+     306             :                                         && defined (PLUMED_GCH_LIB_CONSTEXPR_MEMORY)
+     307             : #    define PLUMED_GCH_SMALL_VECTOR_CONSTEXPR constexpr
+     308             : #    ifndef PLUMED_GCH_HAS_CONSTEXPR_SMALL_VECTOR
+     309             : #      define PLUMED_GCH_HAS_CONSTEXPR_SMALL_VECTOR
+     310             : #    endif
+     311             : #  else
+     312             : #    define PLUMED_GCH_SMALL_VECTOR_CONSTEXPR
+     313             : #  endif
+     314             : #endif
+     315             : 
+     316             : #ifndef PLUMED_GCH_SMALL_VECTOR_DEFAULT_SIZE
+     317             : #  define PLUMED_GCH_SMALL_VECTOR_DEFAULT_SIZE 64
+     318             : #endif
+     319             : 
+     320             : namespace PLMD {
+     321             : namespace gch
+     322             : {
+     323             : 
+     324             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+     325             : 
+     326             : namespace concepts
+     327             : {
+     328             : 
+     329             : template <typename T>
+     330             : concept Complete = requires { sizeof (T); };
+     331             : 
+     332             : // Note: this mirrors the named requirements, not the standard concepts, so we don't require
+     333             : // the destructor to be noexcept for Destructible.
+     334             : template <typename T>
+     335             : concept Destructible = std::is_destructible<T>::value;
+     336             : 
+     337             : template <typename T>
+     338             : concept TriviallyDestructible = std::is_trivially_destructible<T>::value;
+     339             : 
+     340             : template <typename T>
+     341             : concept NoThrowDestructible = std::is_nothrow_destructible<T>::value;
+     342             : 
+     343             : // Note: this mirrors the named requirements, not the standard library concepts,
+     344             : // so we don't require Destructible here.
+     345             : 
+     346             : template <typename T, typename... Args>
+     347             : concept ConstructibleFrom = std::is_constructible<T, Args...>::value;
+     348             : 
+     349             : template <typename T, typename... Args>
+     350             : concept NoThrowConstructibleFrom = std::is_nothrow_constructible<T, Args...>::value;
+     351             : 
+     352             : template <typename From, typename To>
+     353             : concept ConvertibleTo =
+     354             :   std::is_convertible<From, To>::value
+     355             :   &&  requires (typename std::add_rvalue_reference<From>::type (&f) (void))
+     356             : {
+     357             :   static_cast<To> (f ());
+     358             : };
+     359             : 
+     360             : template <typename From, typename To>
+     361             : concept NoThrowConvertibleTo =
+     362             :   std::is_nothrow_convertible<From, To>::value
+     363             :   &&  requires (typename std::add_rvalue_reference<From>::type (&f) (void) noexcept)
+     364             : {
+     365             :   { static_cast<To> (f ()) } noexcept;
+     366             : };
+     367             : 
+     368             : // Note: std::default_initializable requires std::destructible.
+     369             : template <typename T>
+     370             : concept DefaultConstructible =
+     371             :   ConstructibleFrom<T>
+     372             :   &&  requires { T { }; }
+     373             :   &&  requires { ::new (static_cast<void *> (nullptr)) T; };
+     374             : 
+     375             : template <typename T>
+     376             : concept MoveAssignable = std::assignable_from<T&, T>;
+     377             : 
+     378             : template <typename T>
+     379             : concept CopyAssignable =
+     380             :   MoveAssignable<T>
+     381             :   &&  std::assignable_from<T&, T&>
+     382             :   &&  std::assignable_from<T&, const T&>
+     383             :   &&  std::assignable_from<T&, const T>;
+     384             : 
+     385             : template <typename T>
+     386             : concept MoveConstructible = ConstructibleFrom<T, T> && ConvertibleTo<T, T>;
+     387             : 
+     388             : template <typename T>
+     389             : concept NoThrowMoveConstructible =
+     390             :   NoThrowConstructibleFrom<T, T>
+     391             :   &&  NoThrowConvertibleTo<T, T>;
+     392             : 
+     393             : template <typename T>
+     394             : concept CopyConstructible =
+     395             :   MoveConstructible<T>
+     396             :   &&  ConstructibleFrom<T,       T&> && ConvertibleTo<      T&, T>
+     397             :   &&  ConstructibleFrom<T, const T&> && ConvertibleTo<const T&, T>
+     398             :   &&  ConstructibleFrom<T, const T > && ConvertibleTo<const T, T>;
+     399             : 
+     400             : template <typename T>
+     401             : concept NoThrowCopyConstructible =
+     402             :   NoThrowMoveConstructible<T>
+     403             :   &&  NoThrowConstructibleFrom<T,       T&> && NoThrowConvertibleTo<      T&, T>
+     404             :   &&  NoThrowConstructibleFrom<T, const T&> && NoThrowConvertibleTo<const T&, T>
+     405             :   &&  NoThrowConstructibleFrom<T, const T > && NoThrowConvertibleTo<const T, T>;
+     406             : 
+     407             : template <typename T>
+     408             : concept Swappable = std::swappable<T>;
+     409             : 
+     410             : template <typename T>
+     411             : concept EqualityComparable = std::equality_comparable<T>;
+     412             : 
+     413             : // T is a type
+     414             : // X is a Container
+     415             : // A is an Allocator
+     416             : // if X::allocator_type then
+     417             : //   std::same_as<typename X::allocator_type,
+     418             : //                typename std::allocator_traits<A>::template rebind_alloc<T>>
+     419             : // otherwise
+     420             : //   no condition; we use std::allocator<T> regardless of A
+     421             : //
+     422             : // see [22.2.1].16
+     423             : template <typename T, typename X, typename A, typename ...Args>
+     424             : concept EmplaceConstructible =
+     425             :   std::same_as<typename X::value_type, T>
+     426             :   &&  (  (  requires { typename X::allocator_type; } // only perform this check if X is
+     427             :             &&  std::same_as<typename X::allocator_type, // allocator-aware
+     428             :             typename std::allocator_traits<A>::template rebind_alloc<T>>
+     429             :             &&  (  requires (A m, T *p, Args&&... args)
+     430             : {
+     431             :   m.construct (p, std::forward<Args> (args)...);
+     432             : }
+     433             : ||  requires (T *p, Args&&... args)
+     434             : {
+     435             : #if __cplusplus >= 202002L // c++20 fully featured
+     436             :   { std::construct_at (p, std::forward<Args> (args)...) } -> std::same_as<T *>;
+     437             : #else
+     438             :   ::new (std::declval<void *> ()) T (std::declval<Args> ()...);
+     439             : #endif
+     440             : }))
+     441             : ||  (! requires { typename X::allocator_type; }
+     442             :      &&  requires (T *p, Args&&... args)
+     443             : {
+     444             : #if __cplusplus >= 202002L // c++20 fully featured
+     445             :   { std::construct_at (p, std::forward<Args> (args)...) } -> std::same_as<T *>;
+     446             : #else
+     447             :   ::new (std::declval<void *> ()) T (std::declval<Args> ()...);
+     448             : #endif
+     449             : }));
+     450             : 
+     451             : template <typename T, typename X,
+     452             : typename A = typename std::conditional<requires { typename X::allocator_type; },
+     453             :          typename X::allocator_type,
+     454             :          std::allocator<T>>::type>
+     455             :          concept DefaultInsertable = EmplaceConstructible<T, X, A>;
+     456             : 
+     457             : template <typename T, typename X,
+     458             : typename A = typename std::conditional<requires { typename X::allocator_type; },
+     459             :          typename X::allocator_type,
+     460             :          std::allocator<T>>::type>
+     461             :          concept MoveInsertable = EmplaceConstructible<T, X, A, T>;
+     462             : 
+     463             : template <typename T, typename X,
+     464             : typename A = typename std::conditional<requires { typename X::allocator_type; },
+     465             :          typename X::allocator_type,
+     466             :          std::allocator<T>>::type>
+     467             :          concept CopyInsertable = MoveInsertable<T, X, A>
+     468             :                                   &&  EmplaceConstructible<T, X, A,       T&>
+     469             :                                   &&  EmplaceConstructible<T, X, A, const T&>;
+     470             : 
+     471             : // same method as with EmplaceConstructible
+     472             : template <typename T, typename X,
+     473             : typename A = typename std::conditional<requires { typename X::allocator_type; },
+     474             :          typename X::allocator_type,
+     475             :          std::allocator<T>>::type>
+     476             :          concept Erasable =
+     477             :            std::same_as<typename X::value_type, T>
+     478             :            &&  (  (  requires { typename X::allocator_type; } // if X is allocator aware
+     479             :                      &&  std::same_as<typename X::allocator_type,
+     480             :                      typename std::allocator_traits<A>::template rebind_alloc<T>>
+     481             :                   &&  (  requires (A m, T *p)
+     482             : {
+     483             :   m.destroy (p);
+     484             : }
+     485             : ||   std::is_destructible<T>::value))
+     486             : ||  (! requires { typename X::allocator_type; }
+     487             :      &&  std::is_destructible<T>::value));
+     488             : 
+     489             : template <typename T>
+     490             : concept ContextuallyConvertibleToBool = std::constructible_from<bool, T>;
+     491             : 
+     492             : template <typename T>
+     493             : concept BoolConstant = std::derived_from<T, std::true_type>
+     494             : || std::derived_from<T, std::false_type>;
+     495             : 
+     496             : template <typename T>
+     497             : concept NullablePointer =
+     498             : EqualityComparable<T>
+     499             : &&  DefaultConstructible<T>
+     500             : &&  CopyConstructible<T>
+     501             : &&  CopyAssignable<T>
+     502             : &&  Destructible<T>
+     503             : &&  ConstructibleFrom<T, std::nullptr_t>
+     504             : &&  ConvertibleTo<std::nullptr_t, T>
+     505             : &&  requires (T p, T q, std::nullptr_t np)
+     506             : {
+     507             :   T (np);
+     508             :   { p = np   } -> std::same_as<T&>;
+     509             :   { p  != q  } -> ContextuallyConvertibleToBool;
+     510             :   { p  == np } -> ContextuallyConvertibleToBool;
+     511             :   { np == p  } -> ContextuallyConvertibleToBool;
+     512             :   { p  != np } -> ContextuallyConvertibleToBool;
+     513             :   { np != p  } -> ContextuallyConvertibleToBool;
+     514             : };
+     515             : 
+     516             : static_assert (  NullablePointer<int *>);
+     517             : static_assert (! NullablePointer<int>);
+     518             : 
+     519             : template <typename A, typename T, typename U = T *>
+     520             : concept AllocatorFor =
+     521             : NoThrowCopyConstructible<A>
+     522             : &&  requires (A a,
+     523             :               typename std::allocator_traits<A>::template rebind_alloc<U> b,
+     524             :               U xp,
+     525             :               typename std::allocator_traits<A>::pointer p,
+     526             :               typename std::allocator_traits<A>::const_pointer cp,
+     527             :               typename std::allocator_traits<A>::void_pointer vp,
+     528             :               typename std::allocator_traits<A>::const_void_pointer cvp,
+     529             :               typename std::allocator_traits<A>::value_type& r,
+     530             :               typename std::allocator_traits<A>::size_type n)
+     531             : {
+     532             :   /** Inner types **/
+     533             :   // A::pointer
+     534             :   requires NullablePointer<            typename std::allocator_traits<A>::pointer>;
+     535             :   requires std::random_access_iterator<typename std::allocator_traits<A>::pointer>;
+     536             :   requires std::contiguous_iterator<   typename std::allocator_traits<A>::pointer>;
+     537             : 
+     538             :   // A::const_pointer
+     539             :   requires NullablePointer<            typename std::allocator_traits<A>::const_pointer>;
+     540             :   requires std::random_access_iterator<typename std::allocator_traits<A>::const_pointer>;
+     541             :   requires std::contiguous_iterator<   typename std::allocator_traits<A>::const_pointer>;
+     542             : 
+     543             :   requires std::convertible_to<typename std::allocator_traits<A>::pointer,
+     544             :            typename std::allocator_traits<A>::const_pointer>;
+     545             : 
+     546             :   // A::void_pointer
+     547             :   requires NullablePointer<typename std::allocator_traits<A>::void_pointer>;
+     548             : 
+     549             :   requires std::convertible_to<typename std::allocator_traits<A>::pointer,
+     550             :            typename std::allocator_traits<A>::void_pointer>;
+     551             : 
+     552             :   requires std::same_as<typename std::allocator_traits<A>::void_pointer,
+     553             :            typename std::allocator_traits<decltype (b)>::void_pointer>;
+     554             : 
+     555             :   // A::const_void_pointer
+     556             :   requires NullablePointer<typename std::allocator_traits<A>::const_void_pointer>;
+     557             : 
+     558             :   requires std::convertible_to<typename std::allocator_traits<A>::pointer,
+     559             :            typename std::allocator_traits<A>::const_void_pointer>;
+     560             : 
+     561             :   requires std::convertible_to<typename std::allocator_traits<A>::const_pointer,
+     562             :            typename std::allocator_traits<A>::const_void_pointer>;
+     563             : 
+     564             :   requires std::convertible_to<typename std::allocator_traits<A>::void_pointer,
+     565             :            typename std::allocator_traits<A>::const_void_pointer>;
+     566             : 
+     567             :   requires std::same_as<typename std::allocator_traits<A>::const_void_pointer,
+     568             :            typename std::allocator_traits<decltype (b)>::const_void_pointer>;
+     569             : 
+     570             :   // A::value_type
+     571             :   typename A::value_type;
+     572             :   requires std::same_as<typename A::value_type, T>;
+     573             :   requires std::same_as<typename A::value_type,
+     574             :            typename std::allocator_traits<A>::value_type>;
+     575             : 
+     576             :   // A::size_type
+     577             :   requires std::unsigned_integral<typename std::allocator_traits<A>::size_type>;
+     578             : 
+     579             :   // A::difference_type
+     580             :   requires std::signed_integral<typename std::allocator_traits<A>::difference_type>;
+     581             : 
+     582             :   // A::template rebind<U>::other [optional]
+     583             :   requires ! requires { typename A::template rebind<U>::other; }
+     584             :   ||  requires
+     585             :   {
+     586             :     requires std::same_as<decltype (b), typename A::template rebind<U>::other>;
+     587             :     requires std::same_as<A, typename decltype (b)::template rebind<T>::other>;
+     588             :   };
+     589             : 
+     590             :   /** Operations on pointers **/
+     591             :   { *p  } -> std::same_as<typename A::value_type&>;
+     592             :   { *cp } -> std::same_as<const typename A::value_type&>;
+     593             : 
+     594             :   // Language in the standard implies that `decltype (p)` must either
+     595             :   // be a raw pointer or implement `operator->`. There is no mention
+     596             :   // of `std::to_address` or `std::pointer_traits<Ptr>::to_address`.
+     597             :   requires std::same_as<decltype (p), typename A::value_type *>
+     598             :   ||  requires
+     599             :   {
+     600             :     { p.operator-> () } -> std::same_as<typename A::value_type *>;
+     601             :   };
+     602             : 
+     603             :   requires std::same_as<decltype (cp), const typename A::value_type *>
+     604             :   ||  requires
+     605             :   {
+     606             :     { cp.operator-> () } -> std::same_as<const typename A::value_type *>;
+     607             :   };
+     608             : 
+     609             :   { static_cast<decltype (p)> (vp)   } -> std::same_as<decltype (p)>;
+     610             :   { static_cast<decltype (cp)> (cvp) } -> std::same_as<decltype (cp)>;
+     611             : 
+     612             :   { std::pointer_traits<decltype (p)>::pointer_to (r) } -> std::same_as<decltype (p)>;
+     613             : 
+     614             :   /** Storage and lifetime operations **/
+     615             :   // a.allocate (n)
+     616             :   { a.allocate (n) } -> std::same_as<decltype (p)>;
+     617             : 
+     618             :   // a.allocate (n, cvp) [optional]
+     619             :   requires ! requires { a.allocate (n, cvp); }
+     620             :   ||  requires { { a.allocate (n, cvp) } -> std::same_as<decltype (p)>; };
+     621             : 
+     622             :   // a.deallocate (p, n)
+     623             :   { a.deallocate (p, n) } -> std::convertible_to<void>;
+     624             : 
+     625             :   // a.max_size () [optional]
+     626             :   requires ! requires { a.max_size (); }
+     627             :   ||  requires { { a.max_size () } -> std::same_as<decltype (n)>; };
+     628             : 
+     629             :   // a.construct (xp, args) [optional]
+     630             :   requires ! requires { a.construct (xp); }
+     631             :   ||  requires { { a.construct (xp) } -> std::convertible_to<void>; };
+     632             : 
+     633             :   // a.destroy (xp) [optional]
+     634             :   requires ! requires { a.destroy (xp); }
+     635             :   ||  requires { { a.destroy (xp) } -> std::convertible_to<void>; };
+     636             : 
+     637             :   /** Relationship between instances **/
+     638             :   requires NoThrowConstructibleFrom<A, decltype (b)>;
+     639             :   requires NoThrowConstructibleFrom<A, decltype (std::move (b))>;
+     640             : 
+     641             :   requires BoolConstant<typename std::allocator_traits<A>::is_always_equal>;
+     642             : 
+     643             :   /** Influence on container operations **/
+     644             :   // a.select_on_container_copy_construction () [optional]
+     645             :   requires ! requires { a.select_on_container_copy_construction (); }
+     646             :   ||  requires
+     647             :   {
+     648             :     { a.select_on_container_copy_construction () } -> std::same_as<A>;
+     649             :   };
+     650             : 
+     651             :   requires BoolConstant<
+     652             :   typename std::allocator_traits<A>::propagate_on_container_copy_assignment>;
+     653             : 
+     654             :   requires BoolConstant<
+     655             :   typename std::allocator_traits<A>::propagate_on_container_move_assignment>;
+     656             : 
+     657             :   requires BoolConstant<
+     658             :   typename std::allocator_traits<A>::propagate_on_container_swap>;
+     659             : 
+     660             :   { a == b } -> std::same_as<bool>;
+     661             :   { a != b } -> std::same_as<bool>;
+     662             : }
+     663             : &&  requires (A a1, A a2)
+     664             : {
+     665             :   { a1 == a2 } -> std::same_as<bool>;
+     666             :   { a1 != a2 } -> std::same_as<bool>;
+     667             : };
+     668             : 
+     669             : static_assert (AllocatorFor<std::allocator<int>, int>,
+     670             :                "std::allocator<int> failed to meet Allocator concept requirements.");
+     671             : 
+     672             : template <typename A>
+     673             : concept Allocator = AllocatorFor<A, typename A::value_type>;
+     674             : 
+     675             : namespace small_vector
+     676             : {
+     677             : 
+     678             : // Basically, these shut off the concepts if we have an incomplete type.
+     679             : // This namespace is only needed because of issues on Clang
+     680             : // preventing us from short-circuiting for incomplete types.
+     681             : 
+     682             : template <typename T>
+     683             : concept Destructible =
+     684             : ! concepts::Complete<T> || concepts::Destructible<T>;
+     685             : 
+     686             : template <typename T>
+     687             : concept MoveAssignable =
+     688             : ! concepts::Complete<T> || concepts::MoveAssignable<T>;
+     689             : 
+     690             : template <typename T>
+     691             : concept CopyAssignable =
+     692             : ! concepts::Complete<T> || concepts::CopyAssignable<T>;
+     693             : 
+     694             : template <typename T>
+     695             : concept MoveConstructible =
+     696             : ! concepts::Complete<T> || concepts::MoveConstructible<T>;
+     697             : 
+     698             : template <typename T>
+     699             : concept CopyConstructible =
+     700             : ! concepts::Complete<T> || concepts::CopyConstructible<T>;
+     701             : 
+     702             : template <typename T>
+     703             : concept Swappable =
+     704             : ! concepts::Complete<T> || concepts::Swappable<T>;
+     705             : 
+     706             : template <typename T, typename SmallVector, typename Alloc>
+     707             : concept DefaultInsertable =
+     708             : ! concepts::Complete<T> || concepts::DefaultInsertable<T, SmallVector, Alloc>;
+     709             : 
+     710             : template <typename T, typename SmallVector, typename Alloc>
+     711             : concept MoveInsertable =
+     712             : ! concepts::Complete<T> || concepts::MoveInsertable<T, SmallVector, Alloc>;
+     713             : 
+     714             : template <typename T, typename SmallVector, typename Alloc>
+     715             : concept CopyInsertable =
+     716             : ! concepts::Complete<T> || concepts::CopyInsertable<T, SmallVector, Alloc>;
+     717             : 
+     718             : template <typename T, typename SmallVector, typename Alloc>
+     719             : concept Erasable =
+     720             : ! concepts::Complete<T> || concepts::Erasable<T, SmallVector, Alloc>;
+     721             : 
+     722             : template <typename T, typename SmallVector, typename Alloc, typename ...Args>
+     723             : concept EmplaceConstructible =
+     724             : ! concepts::Complete<T> || concepts::EmplaceConstructible<T, SmallVector, Alloc, Args...>;
+     725             : 
+     726             : template <typename Alloc, typename T>
+     727             : concept AllocatorFor =
+     728             : ! concepts::Complete<T> || concepts::AllocatorFor<Alloc, T>;
+     729             : 
+     730             : template <typename Alloc>
+     731             : concept Allocator = AllocatorFor<Alloc, typename Alloc::value_type>;
+     732             : 
+     733             : } // namespace gch::concepts::small_vector
+     734             : 
+     735             : } // namespace gch::concepts
+     736             : 
+     737             : #endif
+     738             : 
+     739             : template <typename Allocator>
+     740             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+     741             : requires concepts::small_vector::Allocator<Allocator>
+     742             : #endif
+     743             : struct default_buffer_size;
+     744             : 
+     745             : template <typename T,
+     746             :           unsigned InlineCapacity = default_buffer_size<std::allocator<T>>::value,
+     747             :           typename Allocator      = std::allocator<T>>
+     748             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+     749             : requires concepts::small_vector::AllocatorFor<Allocator, T>
+     750             : #endif
+     751             : class small_vector;
+     752             : 
+     753             : template <typename Allocator>
+     754             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+     755             : requires concepts::small_vector::Allocator<Allocator>
+     756             : #endif
+     757             : struct default_buffer_size
+     758             : {
+     759             : private:
+     760             :   template <typename, typename Enable = void>
+     761             :   struct is_complete
+     762             : : std::false_type
+     763             :   { };
+     764             : 
+     765             :   template <typename U>
+     766             :   struct is_complete<U, decltype (static_cast<void> (sizeof (U)))>
+     767             : : std::true_type
+     768             :   { };
+     769             : 
+     770             : public:
+     771             :   using allocator_type     = Allocator;
+     772             :   using value_type         = typename std::allocator_traits<allocator_type>::value_type;
+     773             :   using empty_small_vector = small_vector<value_type, 0, allocator_type>;
+     774             : 
+     775             :   static_assert (is_complete<value_type>::value,
+     776             :                  "Calculation of a default number of elements requires that `T` be complete.");
+     777             : 
+     778             :   static constexpr
+     779             :   unsigned
+     780             :   buffer_max = 256;
+     781             : 
+     782             :   static constexpr
+     783             :   unsigned
+     784             :   ideal_total = PLUMED_GCH_SMALL_VECTOR_DEFAULT_SIZE;
+     785             : 
+     786             : #ifndef PLUMED_GCH_UNRESTRICTED_DEFAULT_BUFFER_SIZE
+     787             : 
+     788             :   // FIXME: Some compilers will not emit the error from this static_assert
+     789             :   //        while instantiating a small_vector, and attribute the mistake
+     790             :   //        to some random other function.
+     791             :   // static_assert (sizeof (value_type) <= buffer_max, "`sizeof (T)` too large");
+     792             : 
+     793             : #endif
+     794             : 
+     795             :   static constexpr
+     796             :   unsigned
+     797             :   ideal_buffer = ideal_total - sizeof (empty_small_vector);
+     798             : 
+     799             :   static_assert (sizeof (empty_small_vector) != 0,
+     800             :                  "Empty `small_vector` should not have size 0.");
+     801             : 
+     802             :   static_assert (ideal_buffer < ideal_total,
+     803             :                  "Empty `small_vector` is larger than ideal_total.");
+     804             : 
+     805             :   static constexpr
+     806             :   unsigned
+     807             :   value = (sizeof (value_type) <= ideal_buffer) ? (ideal_buffer / sizeof (value_type)) : 1;
+     808             : };
+     809             : 
+     810             : #ifdef PLUMED_GCH_VARIABLE_TEMPLATES
+     811             : 
+     812             : template <typename Allocator>
+     813             : PLUMED_GCH_INLINE_VARIABLE constexpr
+     814             : unsigned
+     815             : default_buffer_size_v = default_buffer_size<Allocator>::value;
+     816             : 
+     817             : #endif
+     818             : 
+     819             : template <typename Pointer, typename DifferenceType>
+     820             : class small_vector_iterator
+     821             : {
+     822             : public:
+     823             :   using difference_type   = DifferenceType;
+     824             :   using value_type        = typename std::iterator_traits<Pointer>::value_type;
+     825             :   using pointer           = typename std::iterator_traits<Pointer>::pointer;
+     826             :   using reference         = typename std::iterator_traits<Pointer>::reference;
+     827             :   using iterator_category = typename std::iterator_traits<Pointer>::iterator_category;
+     828             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+     829             :   using iterator_concept  = std::contiguous_iterator_tag;
+     830             : #endif
+     831             : 
+     832             : //  small_vector_iterator            (void)                             = impl;
+     833             :   small_vector_iterator            (const small_vector_iterator&)     = default;
+     834             :   small_vector_iterator            (small_vector_iterator&&) noexcept = default;
+     835             :   small_vector_iterator& operator= (const small_vector_iterator&)     = default;
+     836             :   small_vector_iterator& operator= (small_vector_iterator&&) noexcept = default;
+     837             :   ~small_vector_iterator           (void)                             = default;
+     838             : 
+     839             : #ifdef NDEBUG
+     840             :   small_vector_iterator (void) = default;
+     841             : #else
+     842             :   constexpr
+     843             :   small_vector_iterator (void) noexcept
+     844             :     : m_ptr ()
+     845             :   { }
+     846             : #endif
+     847             : 
+     848             :   constexpr explicit
+     849             :   small_vector_iterator (const Pointer& p) noexcept
+     850             :     : m_ptr (p)
+     851             :   { }
+     852             : 
+     853             :   template <typename U, typename D,
+     854             :             typename std::enable_if<std::is_convertible<U, Pointer>::value>::type * = nullptr>
+     855             :   constexpr PLUMED_GCH_IMPLICIT_CONVERSION
+     856             :   small_vector_iterator (const small_vector_iterator<U, D>& other) noexcept
+     857             :     : m_ptr (other.base ())
+     858             :   { }
+     859             : 
+     860             :   PLUMED_GCH_CPP14_CONSTEXPR
+     861             :   small_vector_iterator&
+     862             :   operator++ (void) noexcept
+     863             :   {
+     864             :     ++m_ptr;
+     865             :     return *this;
+     866             :   }
+     867             : 
+     868             :   PLUMED_GCH_CPP14_CONSTEXPR
+     869             :   small_vector_iterator
+     870             :   operator++ (int) noexcept
+     871             :   {
+     872             :     return small_vector_iterator (m_ptr++);
+     873             :   }
+     874             : 
+     875             :   PLUMED_GCH_CPP14_CONSTEXPR
+     876             :   small_vector_iterator&
+     877             :   operator-- (void) noexcept
+     878             :   {
+     879             :     --m_ptr;
+     880             :     return *this;
+     881             :   }
+     882             : 
+     883             :   PLUMED_GCH_CPP14_CONSTEXPR
+     884             :   small_vector_iterator
+     885             :   operator-- (int) noexcept
+     886             :   {
+     887             :     return small_vector_iterator (m_ptr--);
+     888             :   }
+     889             : 
+     890             :   PLUMED_GCH_CPP14_CONSTEXPR
+     891             :   small_vector_iterator&
+     892             :   operator+= (difference_type n) noexcept
+     893             :   {
+     894             :     m_ptr += n;
+     895             :     return *this;
+     896             :   }
+     897             : 
+     898             :   constexpr
+     899             :   small_vector_iterator
+     900             :   operator+ (difference_type n) const noexcept
+     901             :   {
+     902             :     return small_vector_iterator (m_ptr + n);
+     903             :   }
+     904             : 
+     905             :   PLUMED_GCH_CPP14_CONSTEXPR
+     906             :   small_vector_iterator&
+     907             :   operator-= (difference_type n) noexcept
+     908             :   {
+     909             :     m_ptr -= n;
+     910             :     return *this;
+     911             :   }
+     912             : 
+     913             :   constexpr
+     914             :   small_vector_iterator
+     915             :   operator- (difference_type n) const noexcept
+     916             :   {
+     917             :     return small_vector_iterator (m_ptr - n);
+     918             :   }
+     919             : 
+     920             :   constexpr
+     921             :   reference
+     922             :   operator* (void) const noexcept
+     923             :   {
+     924             : #ifdef PLUMED_GCH_LIB_LAUNDER
+     925             :     return launder_and_dereference (m_ptr);
+     926             : #else
+     927             :     return *m_ptr;
+     928             : #endif
+     929             :   }
+     930             : 
+     931             :   constexpr
+     932             :   pointer
+     933             :   operator-> (void) const noexcept
+     934             :   {
+     935             :     return get_pointer (m_ptr);
+     936             :   }
+     937             : 
+     938             :   constexpr
+     939             :   reference
+     940             :   operator[] (difference_type n) const noexcept
+     941             :   {
+     942             : #ifdef PLUMED_GCH_LIB_LAUNDER
+     943   139567730 :     return launder_and_dereference (m_ptr + n);
+     944             : #else
+     945             :     return m_ptr[n];
+     946             : #endif
+     947             :   }
+     948             : 
+     949             :   constexpr
+     950             :   const Pointer&
+     951             :   base (void) const noexcept
+     952             :   {
+     953             :     return m_ptr;
+     954             :   }
+     955             : 
+     956             : private:
+     957             :   template <typename Ptr = Pointer,
+     958             :             typename std::enable_if<std::is_pointer<Ptr>::value, bool>::type = true>
+     959             :   static constexpr
+     960             :   pointer
+     961             :   get_pointer (Pointer ptr) noexcept
+     962             :   {
+     963             :     return ptr;
+     964             :   }
+     965             : 
+     966             :   template <typename Ptr = Pointer,
+     967             :             typename std::enable_if<! std::is_pointer<Ptr>::value, bool>::type = false>
+     968             :   static constexpr
+     969             :   pointer
+     970             :   get_pointer (Pointer ptr) noexcept
+     971             :   {
+     972             :     // Given the requirements for Allocator, Pointer must either be a raw pointer, or
+     973             :     // have a defined operator-> which returns a raw pointer.
+     974             :     return ptr.operator-> ();
+     975             :   }
+     976             : 
+     977             : #ifdef PLUMED_GCH_LIB_LAUNDER
+     978             : 
+     979             :   template <typename Ptr = Pointer,
+     980             :             typename std::enable_if<std::is_pointer<Ptr>::value, bool>::type = true>
+     981             :   static constexpr
+     982             :   reference
+     983             :   launder_and_dereference (Pointer ptr) noexcept
+     984             :   {
+     985             :     return *std::launder (ptr);
+     986             :   }
+     987             : 
+     988             :   template <typename Ptr = Pointer,
+     989             :             typename std::enable_if<! std::is_pointer<Ptr>::value, bool>::type = false>
+     990             :   static constexpr
+     991             :   reference
+     992             :   launder_and_dereference (Pointer ptr) noexcept
+     993             :   {
+     994             :     return *ptr;
+     995             :   }
+     996             : 
+     997             : #endif
+     998             : 
+     999             :   Pointer m_ptr;
+    1000             : };
+    1001             : 
+    1002             : #ifdef PLUMED_GCH_LIB_THREE_WAY_COMPARISON
+    1003             : 
+    1004             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1005             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1006             : constexpr
+    1007             : bool
+    1008             : operator== (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1009             :             const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs)
+    1010             : noexcept (noexcept (lhs.base () == rhs.base ()))
+    1011             : requires requires { { lhs.base () == rhs.base () } -> std::convertible_to<bool>; }
+    1012             : {
+    1013             :   return lhs.base () == rhs.base ();
+    1014             : }
+    1015             : 
+    1016             : template <typename Pointer, typename DifferenceType>
+    1017             : constexpr
+    1018             : bool
+    1019             : operator== (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1020             :             const small_vector_iterator<Pointer, DifferenceType>& rhs)
+    1021             : noexcept (noexcept (lhs.base () == rhs.base ()))
+    1022             : requires requires { { lhs.base () == rhs.base () } -> std::convertible_to<bool>; }
+    1023             : {
+    1024             :   return lhs.base () == rhs.base ();
+    1025             : }
+    1026             : 
+    1027             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1028             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1029             : requires std::three_way_comparable_with<PointerLHS, PointerRHS>
+    1030             : constexpr
+    1031             : auto
+    1032             : operator<=> (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1033             :              const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs)
+    1034             : noexcept (noexcept (lhs.base () <=> rhs.base ()))
+    1035             : {
+    1036             :   return lhs.base () <=> rhs.base ();
+    1037             : }
+    1038             : 
+    1039             : template <typename Pointer, typename DifferenceType>
+    1040             : requires std::three_way_comparable<Pointer>
+    1041             : constexpr
+    1042             : auto
+    1043             : operator<=> (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1044             :              const small_vector_iterator<Pointer, DifferenceType>& rhs)
+    1045             : noexcept (noexcept (lhs.base () <=> rhs.base ()))
+    1046             : {
+    1047             :   return lhs.base () <=> rhs.base ();
+    1048             : }
+    1049             : 
+    1050             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1051             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1052             : constexpr
+    1053             : auto
+    1054             : operator<=> (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1055             :              const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs)
+    1056             : noexcept (noexcept (lhs.base () < rhs.base ()) && noexcept (rhs.base () < lhs.base ()))
+    1057             : {
+    1058             :   using ordering = std::weak_ordering;
+    1059             :   return (lhs.base () < rhs.base ()) ? ordering::less
+    1060             :          : (rhs.base () < lhs.base ()) ? ordering::greater
+    1061             :          : ordering::equivalent;
+    1062             : }
+    1063             : 
+    1064             : template <typename Pointer, typename DifferenceType>
+    1065             : constexpr
+    1066             : auto
+    1067             : operator<=> (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1068             :              const small_vector_iterator<Pointer, DifferenceType>& rhs)
+    1069             : noexcept (noexcept (lhs.base () < rhs.base ()) && noexcept (rhs.base () < lhs.base ()))
+    1070             : {
+    1071             :   using ordering = std::weak_ordering;
+    1072             :   return (lhs.base () < rhs.base ()) ? ordering::less
+    1073             :          : (rhs.base () < lhs.base ()) ? ordering::greater
+    1074             :          : ordering::equivalent;
+    1075             : }
+    1076             : 
+    1077             : #else
+    1078             : 
+    1079             : // Note: Passing this on from "Gaby" in stl_iterator.h -- templated
+    1080             : //       comparisons in generic code should have overloads for both
+    1081             : //       homogenous and heterogeneous types. This is because we get
+    1082             : //       ambiguous overload resolution when std::rel_ops is visible
+    1083             : //       (ie. `using namespace std::rel_ops`).
+    1084             : 
+    1085             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1086             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1087             : constexpr
+    1088             : bool
+    1089             : operator== (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1090             :             const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1091             : {
+    1092             :   return lhs.base () == rhs.base ();
+    1093             : }
+    1094             : 
+    1095             : template <typename Pointer, typename DifferenceType>
+    1096             : constexpr
+    1097             : bool
+    1098             : operator== (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1099             :             const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1100             : {
+    1101             :   return lhs.base () == rhs.base ();
+    1102             : }
+    1103             : 
+    1104             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1105             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1106             : constexpr
+    1107             : bool
+    1108             : operator!= (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1109             :             const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1110             : {
+    1111             :   return lhs.base () != rhs.base ();
+    1112             : }
+    1113             : 
+    1114             : template <typename Pointer, typename DifferenceType>
+    1115             : constexpr
+    1116             : bool
+    1117             : operator!= (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1118             :             const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1119             : {
+    1120             :   return lhs.base () != rhs.base ();
+    1121             : }
+    1122             : 
+    1123             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1124             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1125             : constexpr
+    1126             : bool
+    1127             : operator< (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1128             :            const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1129             : {
+    1130             :   return lhs.base () < rhs.base ();
+    1131             : }
+    1132             : 
+    1133             : template <typename Pointer, typename DifferenceType>
+    1134             : constexpr
+    1135             : bool
+    1136             : operator< (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1137             :            const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1138             : {
+    1139             :   return lhs.base () < rhs.base ();
+    1140             : }
+    1141             : 
+    1142             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1143             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1144             : constexpr
+    1145             : bool
+    1146             : operator>= (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1147             :             const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1148             : {
+    1149             :   return lhs.base () >= rhs.base ();
+    1150             : }
+    1151             : 
+    1152             : template <typename Pointer, typename DifferenceType>
+    1153             : constexpr
+    1154             : bool
+    1155             : operator>= (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1156             :             const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1157             : {
+    1158             :   return lhs.base () >= rhs.base ();
+    1159             : }
+    1160             : 
+    1161             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1162             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1163             : constexpr
+    1164             : bool
+    1165             : operator> (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1166             :            const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1167             : {
+    1168             :   return lhs.base () > rhs.base ();
+    1169             : }
+    1170             : 
+    1171             : template <typename Pointer, typename DifferenceType>
+    1172             : constexpr
+    1173             : bool
+    1174             : operator> (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1175             :            const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1176             : {
+    1177             :   return lhs.base () > rhs.base ();
+    1178             : }
+    1179             : 
+    1180             : template <typename PointerLHS, typename DifferenceTypeLHS,
+    1181             :           typename PointerRHS, typename DifferenceTypeRHS>
+    1182             : constexpr
+    1183             : bool
+    1184             : operator<= (const small_vector_iterator<PointerLHS, DifferenceTypeLHS>& lhs,
+    1185             :             const small_vector_iterator<PointerRHS, DifferenceTypeRHS>& rhs) noexcept
+    1186             : {
+    1187             :   return lhs.base () <= rhs.base ();
+    1188             : }
+    1189             : 
+    1190             : template <typename Pointer, typename DifferenceType>
+    1191             : constexpr
+    1192             : bool
+    1193             : operator<= (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1194             :             const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1195             : {
+    1196             :   return lhs.base () <= rhs.base ();
+    1197             : }
+    1198             : 
+    1199             : #endif
+    1200             : 
+    1201             : template <typename PointerLHS, typename PointerRHS, typename DifferenceType>
+    1202             : constexpr
+    1203             : DifferenceType
+    1204             : operator- (const small_vector_iterator<PointerLHS, DifferenceType>& lhs,
+    1205             :            const small_vector_iterator<PointerRHS, DifferenceType>& rhs) noexcept
+    1206             : {
+    1207             :   return static_cast<DifferenceType> (lhs.base () - rhs.base ());
+    1208             : }
+    1209             : 
+    1210             : template <typename Pointer, typename DifferenceType>
+    1211             : constexpr
+    1212             : DifferenceType
+    1213             : operator- (const small_vector_iterator<Pointer, DifferenceType>& lhs,
+    1214             :            const small_vector_iterator<Pointer, DifferenceType>& rhs) noexcept
+    1215             : {
+    1216             :   return static_cast<DifferenceType> (lhs.base () - rhs.base ());
+    1217             : }
+    1218             : 
+    1219             : template <typename Pointer, typename DifferenceType>
+    1220             : constexpr
+    1221             : small_vector_iterator<Pointer, DifferenceType>
+    1222             : operator+ (DifferenceType n, const small_vector_iterator<Pointer, DifferenceType>& it) noexcept
+    1223             : {
+    1224             :   return it + n;
+    1225             : }
+    1226             : 
+    1227             : namespace detail
+    1228             : {
+    1229             : 
+    1230             : #ifndef PLUMED_GCH_LIB_IS_SWAPPABLE
+    1231             : 
+    1232             : namespace small_vector_adl
+    1233             : {
+    1234             : 
+    1235             : using std::swap;
+    1236             : 
+    1237             : template <typename T, typename Enable = void>
+    1238             : struct is_nothrow_swappable
+    1239             : : std::false_type
+    1240             : { };
+    1241             : 
+    1242             : template <typename T>
+    1243             : struct is_nothrow_swappable<T, decltype (swap (std::declval<T&> (), std::declval<T&> ()))>
+    1244             : : std::integral_constant<bool, noexcept (swap (std::declval<T&> (), std::declval<T&> ()))>
+    1245             : { };
+    1246             : 
+    1247             : }
+    1248             : 
+    1249             : #endif
+    1250             : 
+    1251             : template <typename T, unsigned InlineCapacity>
+    1252             : class inline_storage
+    1253             : {
+    1254             : public:
+    1255             :   using value_ty = T;
+    1256             : 
+    1257             :   inline_storage            (void)                      = default;
+    1258             :   inline_storage            (const inline_storage&)     = delete;
+    1259             :   inline_storage            (inline_storage&&) noexcept = delete;
+    1260             :   inline_storage& operator= (const inline_storage&)     = delete;
+    1261             :   inline_storage& operator= (inline_storage&&) noexcept = delete;
+    1262             :   ~inline_storage           (void)                      = default;
+    1263             : 
+    1264             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    1265             :   value_ty *
+    1266             :   get_inline_ptr (void) noexcept
+    1267             :   {
+    1268      144872 :     return static_cast<value_ty *> (static_cast<void *> (std::addressof (*m_data)));
+    1269             :   }
+    1270             : 
+    1271             :   PLUMED_GCH_NODISCARD constexpr
+    1272             :   const value_ty *
+    1273             :   get_inline_ptr (void) const noexcept
+    1274             :   {
+    1275             :     return static_cast<const value_ty *> (static_cast<const void *> (std::addressof (*m_data)));
+    1276             :   }
+    1277             : 
+    1278             :   static constexpr
+    1279             :   std::size_t
+    1280             :   element_size (void) noexcept
+    1281             :   {
+    1282             :     return sizeof (value_ty);
+    1283             :   }
+    1284             : 
+    1285             :   static constexpr
+    1286             :   std::size_t
+    1287             :   alignment (void) noexcept
+    1288             :   {
+    1289             :     return alignof (value_ty);
+    1290             :   }
+    1291             : 
+    1292             :   static constexpr
+    1293             :   unsigned
+    1294             :   num_elements (void) noexcept
+    1295             :   {
+    1296             :     return InlineCapacity;
+    1297             :   }
+    1298             : 
+    1299             :   static constexpr
+    1300             :   std::size_t
+    1301             :   num_bytes (void) noexcept
+    1302             :   {
+    1303             :     return num_elements () * element_size ();
+    1304             :   }
+    1305             : 
+    1306             : private:
+    1307             :   typename std::aligned_storage<element_size (), alignment ()>::type m_data[num_elements ()];
+    1308             : };
+    1309             : 
+    1310             : template <typename T>
+    1311             : class PLUMED_GCH_EMPTY_BASE inline_storage<T, 0>
+    1312             : {
+    1313             : public:
+    1314             :   using value_ty = T;
+    1315             : 
+    1316             :   inline_storage            (void)                      = default;
+    1317             :   inline_storage            (const inline_storage&)     = delete;
+    1318             :   inline_storage            (inline_storage&&) noexcept = delete;
+    1319             :   inline_storage& operator= (const inline_storage&)     = delete;
+    1320             :   inline_storage& operator= (inline_storage&&) noexcept = delete;
+    1321             :   ~inline_storage           (void)                      = default;
+    1322             : 
+    1323             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    1324             :   value_ty *
+    1325             :   get_inline_ptr (void) noexcept
+    1326             :   {
+    1327             :     return nullptr;
+    1328             :   }
+    1329             : 
+    1330             :   PLUMED_GCH_NODISCARD constexpr
+    1331             :   const value_ty *
+    1332             :   get_inline_ptr (void) const noexcept
+    1333             :   {
+    1334             :     return nullptr;
+    1335             :   }
+    1336             : 
+    1337             :   static constexpr
+    1338             :   std::size_t
+    1339             :   element_size (void) noexcept
+    1340             :   {
+    1341             :     return sizeof (value_ty);
+    1342             :   }
+    1343             : 
+    1344             :   static constexpr
+    1345             :   std::size_t
+    1346             :   alignment (void) noexcept
+    1347             :   {
+    1348             :     return alignof (value_ty);
+    1349             :   }
+    1350             : 
+    1351             :   static constexpr
+    1352             :   unsigned
+    1353             :   num_elements (void) noexcept
+    1354             :   {
+    1355             :     return 0;
+    1356             :   }
+    1357             : 
+    1358             :   static constexpr
+    1359             :   std::size_t
+    1360             :   num_bytes (void) noexcept
+    1361             :   {
+    1362             :     return 0;
+    1363             :   }
+    1364             : };
+    1365             : 
+    1366             : template <typename Allocator, bool AvailableForEBO = std::is_empty<Allocator>::value
+    1367             : #ifdef PLUMED_GCH_LIB_IS_FINAL
+    1368             :           &&! std::is_final<Allocator>::value
+    1369             : #endif // If you are using this with C++11 just don't use an allocator marked as final :P
+    1370             :           >
+    1371             : class allocator_inliner;
+    1372             : 
+    1373             : template <typename Allocator>
+    1374             : class PLUMED_GCH_EMPTY_BASE allocator_inliner<Allocator, true>
+    1375             : : private Allocator
+    1376             : {
+    1377             :   using alloc_traits = std::allocator_traits<Allocator>;
+    1378             : 
+    1379             :   static constexpr
+    1380             :   bool
+    1381             :   copy_assign_is_noop = ! alloc_traits::propagate_on_container_copy_assignment::value;
+    1382             : 
+    1383             :   static constexpr
+    1384             :   bool
+    1385             :   move_assign_is_noop = ! alloc_traits::propagate_on_container_move_assignment::value;
+    1386             : 
+    1387             :   static constexpr
+    1388             :   bool
+    1389             :   swap_is_noop = ! alloc_traits::propagate_on_container_swap::value;
+    1390             : 
+    1391             :   template <bool IsNoOp = copy_assign_is_noop,
+    1392             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1393             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1394             :   void
+    1395             :   maybe_assign (const allocator_inliner&) noexcept { }
+    1396             : 
+    1397             :   template <bool IsNoOp = copy_assign_is_noop,
+    1398             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1399             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1400             :   void
+    1401             :   maybe_assign (const allocator_inliner& other)
+    1402             :   noexcept (noexcept (std::declval<Allocator&> ().operator= (other)))
+    1403             :   {
+    1404             :     Allocator::operator= (other);
+    1405             :   }
+    1406             : 
+    1407             :   template <bool IsNoOp = move_assign_is_noop,
+    1408             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1409             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1410             :   void
+    1411             :   maybe_assign (allocator_inliner&&) noexcept { }
+    1412             : 
+    1413             :   template <bool IsNoOp = move_assign_is_noop,
+    1414             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1415             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1416             :   void
+    1417             :   maybe_assign (allocator_inliner&& other)
+    1418             :   noexcept (noexcept (std::declval<Allocator&> ().operator= (std::move (other))))
+    1419             :   {
+    1420             :     Allocator::operator= (std::move (other));
+    1421             :   }
+    1422             : 
+    1423             : public:
+    1424             :   allocator_inliner            (void)                         = default;
+    1425             :   allocator_inliner            (const allocator_inliner&)     = default;
+    1426             :   allocator_inliner            (allocator_inliner&&) noexcept = default;
+    1427             : //    allocator_inliner& operator= (const allocator_inliner&)     = impl;
+    1428             : //    allocator_inliner& operator= (allocator_inliner&&) noexcept = impl;
+    1429             :   ~allocator_inliner           (void)                         = default;
+    1430             : 
+    1431             :   constexpr explicit
+    1432             :   allocator_inliner (const Allocator& alloc) noexcept
+    1433             :     : Allocator (alloc)
+    1434             :   { }
+    1435             : 
+    1436             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1437             :   allocator_inliner&
+    1438             :   operator= (const allocator_inliner& other)
+    1439             :   noexcept (noexcept (std::declval<allocator_inliner&> ().maybe_assign (other)))
+    1440             :   {
+    1441             :     assert (&other != this
+    1442             :             &&  "`allocator_inliner` should not participate in self-copy-assignment.");
+    1443             :     maybe_assign (other);
+    1444             :     return *this;
+    1445             :   }
+    1446             : 
+    1447             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1448             :   allocator_inliner&
+    1449             :   operator= (allocator_inliner&& other)
+    1450             :   noexcept (noexcept (std::declval<allocator_inliner&> ().maybe_assign (std::move (other))))
+    1451             :   {
+    1452             :     assert (&other != this
+    1453             :             &&  "`allocator_inliner` should not participate in self-move-assignment.");
+    1454             :     maybe_assign (std::move (other));
+    1455             :     return *this;
+    1456             :   }
+    1457             : 
+    1458             :   PLUMED_GCH_CPP14_CONSTEXPR
+    1459             :   Allocator&
+    1460             :   allocator_ref (void) noexcept
+    1461             :   {
+    1462             :     return *this;
+    1463             :   }
+    1464             : 
+    1465             :   constexpr
+    1466             :   const Allocator&
+    1467             :   allocator_ref (void) const noexcept
+    1468             :   {
+    1469             :     return *this;
+    1470             :   }
+    1471             : 
+    1472             :   template <bool IsNoOp = swap_is_noop,
+    1473             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1474             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1475             :   void
+    1476             :   swap (allocator_inliner&)
+    1477             :   { }
+    1478             : 
+    1479             :   template <bool IsNoOp = swap_is_noop,
+    1480             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1481             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1482             :   void
+    1483             :   swap (allocator_inliner& other)
+    1484             :   {
+    1485             :     using std::swap;
+    1486             :     swap (static_cast<Allocator&> (*this), static_cast<Allocator&> (other));
+    1487             :   }
+    1488             : };
+    1489             : 
+    1490             : template <typename Allocator>
+    1491             : class allocator_inliner<Allocator, false>
+    1492             : {
+    1493             :   using alloc_traits = std::allocator_traits<Allocator>;
+    1494             : 
+    1495             :   static constexpr
+    1496             :   bool
+    1497             :   copy_assign_is_noop = ! alloc_traits::propagate_on_container_copy_assignment::value;
+    1498             : 
+    1499             :   static constexpr
+    1500             :   bool
+    1501             :   move_assign_is_noop = ! alloc_traits::propagate_on_container_move_assignment::value;
+    1502             : 
+    1503             :   static constexpr
+    1504             :   bool
+    1505             :   swap_is_noop = ! alloc_traits::propagate_on_container_swap::value;
+    1506             : 
+    1507             :   template <bool IsNoOp = copy_assign_is_noop,
+    1508             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1509             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1510             :   void
+    1511             :   maybe_assign (const allocator_inliner&) noexcept { }
+    1512             : 
+    1513             :   template <bool IsNoOp = copy_assign_is_noop,
+    1514             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1515             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1516             :   void
+    1517             :   maybe_assign (const allocator_inliner& other)
+    1518             :   noexcept (noexcept (std::declval<decltype (other.m_alloc)&> () = other.m_alloc))
+    1519             :   {
+    1520             :     m_alloc = other.m_alloc;
+    1521             :   }
+    1522             : 
+    1523             :   template <bool IsNoOp = move_assign_is_noop,
+    1524             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1525             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1526             :   void
+    1527             :   maybe_assign (allocator_inliner&&) noexcept { }
+    1528             : 
+    1529             :   template <bool IsNoOp = move_assign_is_noop,
+    1530             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1531             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1532             :   void
+    1533             :   maybe_assign (allocator_inliner&& other)
+    1534             :   noexcept (noexcept (std::declval<decltype (other.m_alloc)&> () = std::move (other.m_alloc)))
+    1535             :   {
+    1536             :     m_alloc = std::move (other.m_alloc);
+    1537             :   }
+    1538             : 
+    1539             : public:
+    1540             :   allocator_inliner            (void)                         = default;
+    1541             :   allocator_inliner            (const allocator_inliner&)     = default;
+    1542             :   allocator_inliner            (allocator_inliner&&) noexcept = default;
+    1543             : //    allocator_inliner& operator= (const allocator_inliner&)     = impl;
+    1544             : //    allocator_inliner& operator= (allocator_inliner&&) noexcept = impl;
+    1545             :   ~allocator_inliner           (void)                         = default;
+    1546             : 
+    1547             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    1548             :   allocator_inliner (const Allocator& alloc) noexcept
+    1549             :     : m_alloc (alloc)
+    1550             :   { }
+    1551             : 
+    1552             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1553             :   allocator_inliner&
+    1554             :   operator= (const allocator_inliner& other)
+    1555             :   noexcept (noexcept (std::declval<allocator_inliner&> ().maybe_assign (other)))
+    1556             :   {
+    1557             :     assert (&other != this
+    1558             :             &&  "`allocator_inliner` should not participate in self-copy-assignment.");
+    1559             :     maybe_assign (other);
+    1560             :     return *this;
+    1561             :   }
+    1562             : 
+    1563             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1564             :   allocator_inliner&
+    1565             :   operator= (allocator_inliner&& other)
+    1566             :   noexcept (noexcept (std::declval<allocator_inliner&> ().maybe_assign (std::move (other))))
+    1567             :   {
+    1568             :     assert (&other != this
+    1569             :             &&  "`allocator_inliner` should not participate in self-move-assignment.");
+    1570             :     maybe_assign (std::move (other));
+    1571             :     return *this;
+    1572             :   }
+    1573             : 
+    1574             :   PLUMED_GCH_CPP14_CONSTEXPR
+    1575             :   Allocator&
+    1576             :   allocator_ref (void) noexcept
+    1577             :   {
+    1578             :     return m_alloc;
+    1579             :   }
+    1580             : 
+    1581             :   constexpr
+    1582             :   const Allocator&
+    1583             :   allocator_ref (void) const noexcept
+    1584             :   {
+    1585             :     return m_alloc;
+    1586             :   }
+    1587             : 
+    1588             :   template <bool IsNoOp = swap_is_noop,
+    1589             :             typename std::enable_if<IsNoOp, bool>::type = true>
+    1590             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1591             :   void
+    1592             :   swap (allocator_inliner&)
+    1593             :   { }
+    1594             : 
+    1595             :   template <bool IsNoOp = swap_is_noop,
+    1596             :             typename std::enable_if<! IsNoOp, bool>::type = false>
+    1597             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1598             :   void
+    1599             :   swap (allocator_inliner& other)
+    1600             :   {
+    1601             :     using std::swap;
+    1602             :     swap (m_alloc, other.m_alloc);
+    1603             :   }
+    1604             : 
+    1605             : private:
+    1606             :   Allocator m_alloc;
+    1607             : };
+    1608             : 
+    1609             : template <typename Allocator>
+    1610             : class PLUMED_GCH_EMPTY_BASE allocator_interface
+    1611             : : public allocator_inliner<Allocator>
+    1612             : {
+    1613             : public:
+    1614             :   template <typename, typename = void>
+    1615             :   struct is_complete
+    1616             : : std::false_type
+    1617             :   { };
+    1618             : 
+    1619             :   template <typename U>
+    1620             :   struct is_complete<U, decltype (static_cast<void> (sizeof (U)))>
+    1621             : : std::true_type
+    1622             :   { };
+    1623             : 
+    1624             :   using size_type = typename std::allocator_traits<Allocator>::size_type;
+    1625             : 
+    1626             :   // If difference_type is larger than size_type then we need
+    1627             :   // to rectify that problem.
+    1628             :   using difference_type = typename std::conditional<
+    1629             :                           (
+    1630             :                             static_cast<std::size_t> ((std::numeric_limits<size_type>::max) ())
+    1631             :                             < // less-than
+    1632             :                             static_cast<std::size_t> ((std::numeric_limits<
+    1633             :                                 typename std::allocator_traits<Allocator>::difference_type>::max) ())
+    1634             :                           ),
+    1635             :                           typename std::make_signed<size_type>::type,
+    1636             :                           typename std::allocator_traits<Allocator>::difference_type>::type;
+    1637             : 
+    1638             : private:
+    1639             :   using alloc_base = allocator_inliner<Allocator>;
+    1640             : 
+    1641             : protected:
+    1642             :   using alloc_ty     = Allocator;
+    1643             :   using alloc_traits = std::allocator_traits<alloc_ty>;
+    1644             :   using value_ty     = typename alloc_traits::value_type;
+    1645             :   using ptr          = typename alloc_traits::pointer;
+    1646             :   using cptr         = typename alloc_traits::const_pointer;
+    1647             :   using vptr         = typename alloc_traits::void_pointer;
+    1648             :   using cvptr        = typename alloc_traits::const_void_pointer;
+    1649             : 
+    1650             :   // Select the fastest types larger than the user-facing types. These are only intended for
+    1651             :   // internal computations, and should not have any memory footprint visible to consumers.
+    1652             :   using size_ty =
+    1653             :     typename std::conditional<
+    1654             :     (sizeof (size_type) <= sizeof (std::uint8_t)),
+    1655             :     std::uint_fast8_t,
+    1656             :     typename std::conditional<
+    1657             :     (sizeof (size_type) <= sizeof (std::uint16_t)),
+    1658             :     std::uint_fast16_t,
+    1659             :     typename std::conditional<
+    1660             :     (sizeof (size_type) <= sizeof (std::uint32_t)),
+    1661             :     std::uint_fast32_t,
+    1662             :     typename std::conditional<
+    1663             :     (sizeof (size_type) <= sizeof (std::uint64_t)),
+    1664             :     std::uint_fast64_t,
+    1665             :     size_type
+    1666             :     >::type
+    1667             :     >::type
+    1668             :     >::type
+    1669             :     >::type;
+    1670             : 
+    1671             :   using diff_ty =
+    1672             :     typename std::conditional<
+    1673             :     (sizeof (difference_type) <= sizeof (std::int8_t)),
+    1674             :     std::int_fast8_t,
+    1675             :     typename std::conditional<
+    1676             :     (sizeof (difference_type) <= sizeof (std::int16_t)),
+    1677             :     std::int_fast16_t,
+    1678             :     typename std::conditional<
+    1679             :     (sizeof (difference_type) <= sizeof (std::int32_t)),
+    1680             :     std::int_fast32_t,
+    1681             :     typename std::conditional<
+    1682             :     (sizeof (difference_type) <= sizeof (std::int64_t)),
+    1683             :     std::int_fast64_t,
+    1684             :     difference_type
+    1685             :     >::type
+    1686             :     >::type
+    1687             :     >::type
+    1688             :     >::type;
+    1689             : 
+    1690             :   using alloc_base::allocator_ref;
+    1691             : 
+    1692             : private:
+    1693             :   template <typename ...>
+    1694             :   using void_t = void;
+    1695             : 
+    1696             :   template <bool B>
+    1697             :   using bool_constant = std::integral_constant<bool, B>;
+    1698             : 
+    1699             :   template <typename V, typename Enable = void>
+    1700             :   struct is_trivially_destructible
+    1701             : : std::false_type
+    1702             :   { };
+    1703             : 
+    1704             :   template <typename V>
+    1705             :   struct is_trivially_destructible<V, typename std::enable_if<is_complete<V>::value>::type>
+    1706             : : std::is_trivially_destructible<V>
+    1707             :   { };
+    1708             : 
+    1709             :   template <typename Void, typename T, typename ...Args>
+    1710             :   struct is_trivially_constructible_impl
+    1711             : : std::false_type
+    1712             :   { };
+    1713             : 
+    1714             :   template <typename V, typename ...Args>
+    1715             :   struct is_trivially_constructible_impl<
+    1716             :     typename std::enable_if<is_complete<V>::value>::type,
+    1717             :     V, Args...>
+    1718             : : std::is_trivially_constructible<V, Args...>
+    1719             :   { };
+    1720             : 
+    1721             :   template <typename V, typename ...Args>
+    1722             :   struct is_trivially_constructible
+    1723             : : is_trivially_constructible_impl<void, V, Args...>
+    1724             :   { };
+    1725             : 
+    1726             :   template <typename T, typename Enable = void>
+    1727             :   struct underlying_if_enum
+    1728             :   {
+    1729             :     using type = T;
+    1730             :   };
+    1731             : 
+    1732             :   template <typename T>
+    1733             :   struct underlying_if_enum<T, typename std::enable_if<std::is_enum<T>::value>::type>
+    1734             : : std::underlying_type<T>
+    1735             :   { };
+    1736             : 
+    1737             :   template <typename T>
+    1738             :   using underlying_if_enum_t = typename underlying_if_enum<T>::type;
+    1739             : 
+    1740             :   template <typename, typename = void>
+    1741             :   struct has_ptr_traits_to_address
+    1742             : : std::false_type
+    1743             :   { };
+    1744             : 
+    1745             :   template <typename P>
+    1746             :   struct has_ptr_traits_to_address<P,
+    1747             :                                    void_t<decltype (std::pointer_traits<P>::to_address (std::declval<P> ()))>>
+    1748             : : std::true_type
+    1749             :   { };
+    1750             : 
+    1751             :   template <typename Void, typename A, typename V, typename ...Args>
+    1752             :   struct has_alloc_construct_check
+    1753             : : std::false_type
+    1754             :   { };
+    1755             : 
+    1756             :   template <typename A, typename V, typename ...Args>
+    1757             :   struct has_alloc_construct_check<
+    1758             :     void_t<decltype (std::declval<A&> ().construct (std::declval<V *> (),
+    1759             :                      std::declval<Args> ()...))>,
+    1760             :     A, V, Args...>
+    1761             : : std::true_type
+    1762             :   { };
+    1763             : 
+    1764             :   template <typename Void, typename A, typename V, typename ...Args>
+    1765             :   struct has_alloc_construct_impl
+    1766             : : std::false_type
+    1767             :   { };
+    1768             : 
+    1769             :   template <typename A, typename V, typename ...Args>
+    1770             :   struct has_alloc_construct_impl<typename std::enable_if<is_complete<V>::value>::type,
+    1771             :                                   A, V, Args...>
+    1772             : : has_alloc_construct_check<void, A, V, Args...>
+    1773             :   { };
+    1774             : 
+    1775             :   template <typename A, typename V, typename ...Args>
+    1776             :   struct has_alloc_construct
+    1777             : : has_alloc_construct_impl<void, A, V, Args...>
+    1778             :   { };
+    1779             : 
+    1780             :   template <typename A, typename V, typename ...Args>
+    1781             :   struct must_use_alloc_construct
+    1782             : : bool_constant<! std::is_same<A, std::allocator<V>>::value
+    1783             :                   &&  has_alloc_construct<A, V, Args...>::value>
+    1784             :   { };
+    1785             : 
+    1786             :   template <typename Void, typename A, typename V>
+    1787             :   struct has_alloc_destroy_impl
+    1788             : : std::false_type
+    1789             :   { };
+    1790             : 
+    1791             :   template <typename A, typename V>
+    1792             :   struct has_alloc_destroy_impl<
+    1793             :     void_t<decltype (std::declval<A&> ().destroy (std::declval<V *> ()))>,
+    1794             :     A, V>
+    1795             : : std::true_type
+    1796             :   { };
+    1797             : 
+    1798             :   template <typename A, typename V, typename Enable = void>
+    1799             :   struct has_alloc_destroy
+    1800             : : std::false_type
+    1801             :   { };
+    1802             : 
+    1803             :   template <typename A, typename V>
+    1804             :   struct has_alloc_destroy<A, V, typename std::enable_if<is_complete<V>::value>::type>
+    1805             : : has_alloc_destroy_impl<void, A, V>
+    1806             :   { };
+    1807             : 
+    1808             :   template <typename A, typename V>
+    1809             :   struct must_use_alloc_destroy
+    1810             : : bool_constant<! std::is_same<A, std::allocator<V>>::value
+    1811             :                   &&  has_alloc_destroy<A, V>::value>
+    1812             :   { };
+    1813             : 
+    1814             : public:
+    1815             :   allocator_interface (void)                           = default;
+    1816             : //    allocator_interface (const allocator_interface&)     = impl;
+    1817             :   allocator_interface (allocator_interface&&) noexcept = default;
+    1818             : 
+    1819             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1820             :   allocator_interface&
+    1821             :   operator= (const allocator_interface&) = default;
+    1822             : 
+    1823             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1824             :   allocator_interface&
+    1825             :   operator= (allocator_interface&&) noexcept = default;
+    1826             : 
+    1827             :   ~allocator_interface (void) = default;
+    1828             : 
+    1829             :   PLUMED_GCH_CPP20_CONSTEXPR
+    1830             :   allocator_interface (const allocator_interface& other) noexcept
+    1831             :     : alloc_base (alloc_traits::select_on_container_copy_construction (other.allocator_ref ()))
+    1832             :   { }
+    1833             : 
+    1834             :   constexpr explicit
+    1835             :   allocator_interface (const alloc_ty& alloc) noexcept
+    1836             :     : alloc_base (alloc)
+    1837             :   { }
+    1838             : 
+    1839             :   template <typename T>
+    1840             :   constexpr explicit
+    1841             :   allocator_interface (T&&, const alloc_ty& alloc) noexcept
+    1842             :     : allocator_interface (alloc)
+    1843             :   { }
+    1844             : 
+    1845             :   template <typename, typename, typename = void>
+    1846             :   struct is_memcpyable_integral
+    1847             : : std::false_type
+    1848             :   { };
+    1849             : 
+    1850             :   template <typename From, typename To>
+    1851             :   struct is_memcpyable_integral<From, To,
+    1852             :                                 typename std::enable_if<is_complete<From>::value>::type>
+    1853             :   {
+    1854             :     using from = underlying_if_enum_t<From>;
+    1855             :     using to   = underlying_if_enum_t<To>;
+    1856             : 
+    1857             :     static constexpr
+    1858             :     bool
+    1859             :     value = (sizeof (from) == sizeof (to))
+    1860             :     &&  (std::is_same<bool, from>::value == std::is_same<bool, to>::value)
+    1861             :     &&  std::is_integral<from>::value
+    1862             :     &&  std::is_integral<to>::value;
+    1863             :                         };
+    1864             : 
+    1865             :   template <typename From, typename To>
+    1866             :   struct is_convertible_pointer
+    1867             : : bool_constant<std::is_pointer<From>::value
+    1868             :                   &&  std::is_pointer<To>::value
+    1869             :                   &&  std::is_convertible<From, To>::value>
+    1870             :   { };
+    1871             : 
+    1872             :   // Memcpyable assignment.
+    1873             :   template <typename QualifiedFrom, typename QualifiedTo = value_ty, typename Enable = void>
+    1874             :   struct is_memcpyable
+    1875             : : std::false_type
+    1876             :   { };
+    1877             : 
+    1878             :   template <typename QualifiedFrom, typename QualifiedTo>
+    1879             :   struct is_memcpyable<QualifiedFrom, QualifiedTo,
+    1880             :                        typename std::enable_if<is_complete<QualifiedFrom>::value>::type>
+    1881             :   {
+    1882             :     static_assert (! std::is_reference<QualifiedTo>::value,
+    1883             :                    "QualifiedTo must not be a reference.");
+    1884             : 
+    1885             :     using from = typename std::remove_reference<
+    1886             :       typename std::remove_cv<QualifiedFrom>::type>::type;
+    1887             : 
+    1888             :     using to = typename std::remove_cv<QualifiedTo>::type;
+    1889             : 
+    1890             :     static constexpr
+    1891             :     bool
+    1892             :     value = std::is_trivially_assignable<QualifiedTo&, QualifiedFrom>::value
+    1893             :     &&  std::is_trivially_copyable<to>::value
+    1894             :     &&  (  std::is_same<typename std::remove_cv<from>::type, to>::value
+    1895             :            ||  is_memcpyable_integral<from, to>::value
+    1896             :            ||  is_convertible_pointer<from, to>::value);
+    1897             :                                      };
+    1898             : 
+    1899             :   // Memcpyable construction.
+    1900             :   template <typename QualifiedFrom, typename QualifiedTo>
+    1901             :   struct is_uninitialized_memcpyable_impl
+    1902             :   {
+    1903             :     static_assert (! std::is_reference<QualifiedTo>::value,
+    1904             :                    "QualifiedTo must not be a reference.");
+    1905             : 
+    1906             :     using from = typename std::remove_reference<
+    1907             :       typename std::remove_cv<QualifiedFrom>::type>::type;
+    1908             : 
+    1909             :     using to = typename std::remove_cv<QualifiedTo>::type;
+    1910             : 
+    1911             :     static constexpr
+    1912             :     bool
+    1913             :     value = std::is_trivially_constructible<QualifiedTo, QualifiedFrom>::value
+    1914             :     &&  std::is_trivially_copyable<to>::value
+    1915             :     &&  (  std::is_same<typename std::remove_cv<from>::type, to>::value
+    1916             :            ||  is_memcpyable_integral<from, to>::value
+    1917             :            ||  is_convertible_pointer<from, to>::value)
+    1918             :     &&  (! must_use_alloc_construct<alloc_ty, value_ty, from>::value
+    1919             :          &&! must_use_alloc_destroy<alloc_ty, value_ty>::value);
+    1920             :                                    };
+    1921             : 
+    1922             :   template <typename To, typename ...Args>
+    1923             :   struct is_uninitialized_memcpyable
+    1924             : : std::false_type
+    1925             :   { };
+    1926             : 
+    1927             :   template <typename To, typename From>
+    1928             :   struct is_uninitialized_memcpyable<To, From>
+    1929             : : is_uninitialized_memcpyable_impl<From, To>
+    1930             :   { };
+    1931             : 
+    1932             :   template <typename Iterator>
+    1933             :   struct is_small_vector_iterator
+    1934             : : std::false_type
+    1935             :   { };
+    1936             : 
+    1937             :   template <typename ...Ts>
+    1938             :   struct is_small_vector_iterator<small_vector_iterator<Ts...>>
+    1939             : : std::true_type
+    1940             :   { };
+    1941             : 
+    1942             :   template <typename InputIt>
+    1943             :   struct is_contiguous_iterator
+    1944             : : bool_constant<
+    1945             :     std::is_same<InputIt, ptr>::value
+    1946             :     ||  std::is_same<InputIt, cptr>::value
+    1947             :     ||  is_small_vector_iterator<InputIt>::value
+    1948             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    1949             :     ||  std::contiguous_iterator<InputIt>
+    1950             : #endif
+    1951             : #ifdef PLUMED_GCH_STDLIB_INTEROP
+    1952             :     ||  std::is_same<InputIt, typename std::array<value_ty>::iterator>::value
+    1953             :     ||  std::is_same<InputIt, typename std::array<value_ty>::const_iterator>::value
+    1954             :     ||  (! std::is_same<value_ty, bool>
+    1955             :          &&  (  std::is_same<InputIt, typename std::vector<value_ty>::iterator>::value
+    1956             :                 ||  std::is_same<InputIt, typename std::vector<value_ty>::const_iterator>::value)
+    1957             :                                 )
+    1958             :     ||  std::is_same<InputIt,
+    1959             :                      decltype (std::begin (std::declval<std::valarray<value_ty>&> ()))>::value
+    1960             :     ||  std::is_same<InputIt,
+    1961             :                      decltype (std::begin (std::declval<const std::valarray<value_ty>&> ()))>::value
+    1962             : #endif
+    1963             :     >
+    1964             :   { };
+    1965             : 
+    1966             :   template <typename InputIt>
+    1967             :   struct is_memcpyable_iterator
+    1968             : : bool_constant<is_memcpyable<decltype (*std::declval<InputIt> ())>::value
+    1969             :                   &&  is_contiguous_iterator<InputIt>::value>
+    1970             :   { };
+    1971             : 
+    1972             :   // Unwrap `move_iterator`s.
+    1973             :   template <typename InputIt>
+    1974             :   struct is_memcpyable_iterator<std::move_iterator<InputIt>>
+    1975             : : is_memcpyable_iterator<InputIt>
+    1976             :   { };
+    1977             : 
+    1978             :   template <typename InputIt, typename V = value_ty>
+    1979             :   struct is_uninitialized_memcpyable_iterator
+    1980             : : bool_constant<is_uninitialized_memcpyable<V, decltype (*std::declval<InputIt> ())>::value
+    1981             :                   &&  is_contiguous_iterator<InputIt>::value>
+    1982             :   { };
+    1983             : 
+    1984             :   // unwrap move_iterators
+    1985             :   template <typename U, typename V>
+    1986             :   struct is_uninitialized_memcpyable_iterator<std::move_iterator<U>, V>
+    1987             : : is_uninitialized_memcpyable_iterator<U, V>
+    1988             :   { };
+    1989             : 
+    1990             :   PLUMED_GCH_NORETURN
+    1991             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    1992             :   void
+    1993             :   throw_range_length_error (void)
+    1994             :   {
+    1995             : #ifdef PLUMED_GCH_EXCEPTIONS
+    1996             :     throw std::length_error ("The specified range is too long.");
+    1997             : #else
+    1998             :     std::fprintf (stderr, "[gch::small_vector] The specified range is too long.");
+    1999             :     std::abort ();
+    2000             : #endif
+    2001             :   }
+    2002             : 
+    2003             :   static constexpr
+    2004             :   value_ty *
+    2005             :   to_address (value_ty *p) noexcept
+    2006             :   {
+    2007             :     static_assert (! std::is_function<value_ty>::value, "value_ty is a function pointer.");
+    2008             :     return p;
+    2009             :   }
+    2010             : 
+    2011             :   static constexpr
+    2012             :   const value_ty *
+    2013             :   to_address (const value_ty *p) noexcept
+    2014             :   {
+    2015             :     static_assert (! std::is_function<value_ty>::value, "value_ty is a function pointer.");
+    2016             :     return p;
+    2017             :   }
+    2018             : 
+    2019             :   template <typename Pointer,
+    2020             :             typename std::enable_if<has_ptr_traits_to_address<Pointer>::value>::type * = nullptr>
+    2021             :   static constexpr
+    2022             :   auto
+    2023             :   to_address (const Pointer& p) noexcept
+    2024             :   -> decltype (std::pointer_traits<Pointer>::to_address (p))
+    2025             :   {
+    2026             :     return std::pointer_traits<Pointer>::to_address (p);
+    2027             :   }
+    2028             : 
+    2029             :   template <typename Pointer,
+    2030             :             typename std::enable_if<! has_ptr_traits_to_address<Pointer>::value>::type * = nullptr>
+    2031             :   static constexpr
+    2032             :   auto
+    2033             :   to_address (const Pointer& p) noexcept
+    2034             :   -> decltype (to_address (p.operator-> ()))
+    2035             :   {
+    2036             :     return to_address (p.operator-> ());
+    2037             :   }
+    2038             : 
+    2039             :   template <typename Integer>
+    2040             :   PLUMED_GCH_NODISCARD
+    2041             :   static PLUMED_GCH_CONSTEVAL
+    2042             :   std::size_t
+    2043             :   numeric_max (void) noexcept
+    2044             :   {
+    2045             :     static_assert (0 <= (std::numeric_limits<Integer>::max) (), "Integer is nonpositive.");
+    2046             :     return static_cast<std::size_t> ((std::numeric_limits<Integer>::max) ());
+    2047             :   }
+    2048             : 
+    2049             :   PLUMED_GCH_NODISCARD
+    2050             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2051             :   size_ty
+    2052             :   internal_range_length (cptr first, cptr last) noexcept
+    2053             :   {
+    2054             :     // This is guaranteed to be less than or equal to max size_ty.
+    2055             :     return static_cast<size_ty> (last - first);
+    2056             :   }
+    2057             : 
+    2058             :   template <typename RandomIt>
+    2059             :   PLUMED_GCH_NODISCARD
+    2060             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2061             :   size_ty
+    2062             :   external_range_length_impl (RandomIt first, RandomIt last, std::random_access_iterator_tag)
+    2063             :   {
+    2064             :     assert (0 <= (last - first) && "Invalid range.");
+    2065             :     const auto len = static_cast<std::size_t> (last - first);
+    2066             : #ifndef NDEBUG
+    2067             :     if (numeric_max<size_ty> () < len)
+    2068             :       throw_range_length_error ();
+    2069             : #endif
+    2070             :     return static_cast<size_ty> (len);
+    2071             :   }
+    2072             : 
+    2073             :   template <typename ForwardIt>
+    2074             :   PLUMED_GCH_NODISCARD
+    2075             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2076             :   size_ty
+    2077             :   external_range_length_impl (ForwardIt first, ForwardIt last, std::forward_iterator_tag)
+    2078             :   {
+    2079             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2080             :     if (std::is_constant_evaluated ())
+    2081             :     {
+    2082             :       // Make sure constexpr doesn't get broken by `using namespace std::rel_ops`.
+    2083             :       typename std::iterator_traits<ForwardIt>::difference_type len = 0;
+    2084             :       for (; ! (first == last); ++first)
+    2085             :         ++len;
+    2086             :       assert (static_cast<std::size_t> (len) <= numeric_max<size_ty> ());
+    2087             :       return static_cast<size_ty> (len);
+    2088             :     }
+    2089             : #endif
+    2090             : 
+    2091             :     const auto len = static_cast<std::size_t> (std::distance (first, last));
+    2092             : #ifndef NDEBUG
+    2093             :     if (numeric_max<size_ty> () < len)
+    2094             :       throw_range_length_error ();
+    2095             : #endif
+    2096             :     return static_cast<size_ty> (len);
+    2097             :   }
+    2098             : 
+    2099             :   template <typename ForwardIt,
+    2100             :             typename ItDiffT = typename std::iterator_traits<ForwardIt>::difference_type,
+    2101             :             typename std::enable_if<(numeric_max<size_ty> () < numeric_max<ItDiffT> ()),
+    2102             :                                      bool>::type = true>
+    2103             :             PLUMED_GCH_NODISCARD
+    2104             :             static PLUMED_GCH_CPP17_CONSTEXPR
+    2105             :             size_ty
+    2106             :             external_range_length (ForwardIt first, ForwardIt last)
+    2107             :   {
+    2108             :     using iterator_cat = typename std::iterator_traits<ForwardIt>::iterator_category;
+    2109             :     return external_range_length_impl (first, last, iterator_cat { });
+    2110             :   }
+    2111             : 
+    2112             :   template <typename ForwardIt,
+    2113             :             typename ItDiffT = typename std::iterator_traits<ForwardIt>::difference_type,
+    2114             :             typename std::enable_if<! (numeric_max<size_ty> () < numeric_max<ItDiffT> ()),
+    2115             :                                        bool>::type = false>
+    2116             :             PLUMED_GCH_NODISCARD
+    2117             :             static PLUMED_GCH_CPP17_CONSTEXPR
+    2118             :             size_ty
+    2119             :             external_range_length (ForwardIt first, ForwardIt last) noexcept
+    2120             :   {
+    2121             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2122             :     if (std::is_constant_evaluated ())
+    2123             :     {
+    2124             :       // Make sure constexpr doesn't get broken by `using namespace std::rel_ops`.
+    2125             :       size_ty len = 0;
+    2126             :       for (; ! (first == last); ++first)
+    2127             :         ++len;
+    2128             :       return len;
+    2129             :     }
+    2130             : #endif
+    2131             : 
+    2132       23058 :     return static_cast<size_ty> (std::distance (first, last));
+    2133             :   }
+    2134             : 
+    2135             :   template <typename Iterator,
+    2136             :             typename IteratorDiffT = typename std::iterator_traits<Iterator>::difference_type,
+    2137             :             typename Integer = IteratorDiffT>
+    2138             :   PLUMED_GCH_NODISCARD
+    2139             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2140             :   Iterator
+    2141             :   unchecked_next (Iterator pos, Integer n = 1) noexcept
+    2142             :   {
+    2143     8354110 :     unchecked_advance (pos, static_cast<IteratorDiffT> (n));
+    2144     8377168 :     return pos;
+    2145             :   }
+    2146             : 
+    2147             :   template <typename Iterator,
+    2148             :             typename IteratorDiffT = typename std::iterator_traits<Iterator>::difference_type,
+    2149             :             typename Integer = IteratorDiffT>
+    2150             :   PLUMED_GCH_NODISCARD
+    2151             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2152             :   Iterator
+    2153             :   unchecked_prev (Iterator pos, Integer n = 1) noexcept
+    2154             :   {
+    2155             :     unchecked_advance (pos, -static_cast<IteratorDiffT> (n));
+    2156     1622401 :     return pos;
+    2157             :   }
+    2158             : 
+    2159             :   template <typename Iterator,
+    2160             :             typename IteratorDiffT = typename std::iterator_traits<Iterator>::difference_type,
+    2161             :             typename Integer = IteratorDiffT>
+    2162             :   static PLUMED_GCH_CPP17_CONSTEXPR
+    2163             :   void
+    2164             :   unchecked_advance (Iterator& pos, Integer n) noexcept
+    2165             :   {
+    2166             :     std::advance (pos, static_cast<IteratorDiffT> (n));
+    2167             :   }
+    2168             : 
+    2169             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2170             :   size_ty
+    2171             :   get_max_size (void) const noexcept
+    2172             :   {
+    2173             :     // This is protected from max/min macros.
+    2174             :     return (std::min) (static_cast<size_ty> (alloc_traits::max_size (allocator_ref ())),
+    2175             :                        static_cast<size_ty> (numeric_max<difference_type> ()));
+    2176             :   }
+    2177             : 
+    2178             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2179             :   ptr
+    2180             :   allocate (size_ty n)
+    2181             :   {
+    2182             :     return alloc_traits::allocate (allocator_ref (), static_cast<size_type> (n));
+    2183             :   }
+    2184             : 
+    2185             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2186             :   ptr
+    2187             :   allocate_with_hint (size_ty n, cptr hint)
+    2188             :   {
+    2189             :     return alloc_traits::allocate (allocator_ref (), static_cast<size_type> (n), hint);
+    2190             :   }
+    2191             : 
+    2192             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2193             :   void
+    2194             :   deallocate (ptr p, size_ty n)
+    2195             :   {
+    2196             :     alloc_traits::deallocate (allocator_ref (), to_address (p),
+    2197             :                               static_cast<size_type> (n));
+    2198         172 :   }
+    2199             : 
+    2200             :   template <typename U,
+    2201             :             typename std::enable_if<
+    2202             :               is_uninitialized_memcpyable<value_ty, U>::value>::type * = nullptr>
+    2203             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2204             :   void
+    2205             :   construct (ptr p, U&& val) noexcept
+    2206             :   {
+    2207             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2208             :     if (std::is_constant_evaluated ())
+    2209             :     {
+    2210             :       alloc_traits::construct (allocator_ref (), to_address (p), std::forward<U> (val));
+    2211             :       return;
+    2212             :     }
+    2213             : #endif
+    2214             :     std::memcpy (to_address (p), &val, sizeof (value_ty));
+    2215             :   }
+    2216             : 
+    2217             :   // basically alloc_traits::construct
+    2218             :   // all this is so we can replicate C++20 behavior in the other overload
+    2219             :   template <typename A = alloc_ty, typename V = value_ty, typename ...Args,
+    2220             :             typename std::enable_if<(  sizeof...(Args) != 1
+    2221             :                                        ||! is_uninitialized_memcpyable<V, Args...>::value)
+    2222             :                                     &&  has_alloc_construct<A, V, Args...>::value>::type * = nullptr>
+    2223             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2224             :   void
+    2225             :   construct (ptr p, Args&&... args)
+    2226             :   noexcept (noexcept (alloc_traits::construct (std::declval<alloc_ty&> (),
+    2227             :                       std::declval<value_ty *> (),
+    2228             :                       std::forward<Args> (args)...)))
+    2229             :   {
+    2230             :     alloc_traits::construct (allocator_ref (), to_address (p), std::forward<Args> (args)...);
+    2231             :   }
+    2232             : 
+    2233             :   template <typename A = alloc_ty, typename V = value_ty, typename ...Args,
+    2234             :             void_t<typename std::enable_if<(  sizeof...(Args) != 1
+    2235             :                    ||! is_uninitialized_memcpyable<V, Args...>::value)
+    2236             :                    &&! has_alloc_construct<A, V, Args...>::value>::type,
+    2237             :                    decltype (::new (std::declval<void *> ()) V (std::declval<Args> ()...))
+    2238             :                    > * = nullptr>
+    2239             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2240             :   void
+    2241             :   construct (ptr p, Args&&... args)
+    2242             :   noexcept (noexcept (::new (std::declval<void *> ()) value_ty (std::declval<Args> ()...)))
+    2243             :   {
+    2244             :     construct_at (to_address (p), std::forward<Args> (args)...);
+    2245             :   }
+    2246             : 
+    2247             :   template <typename A = alloc_ty, typename V = value_ty,
+    2248             :             typename std::enable_if<is_trivially_destructible<V>::value
+    2249             :                                     &&! must_use_alloc_destroy<A, V>::value>::type * = nullptr>
+    2250             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2251             :   void
+    2252             :   destroy (ptr) const noexcept
+    2253             :   { }
+    2254             : 
+    2255             :   template <typename A = alloc_ty, typename V = value_ty,
+    2256             :             typename std::enable_if<(! is_trivially_destructible<V>::value
+    2257             :                                      ||  must_use_alloc_destroy<A, V>::value)
+    2258             :                                     &&  has_alloc_destroy<A, V>::value>::type * = nullptr>
+    2259             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2260             :   void
+    2261             :   destroy (ptr p) noexcept
+    2262             :   {
+    2263             :     alloc_traits::destroy (allocator_ref (), to_address (p));
+    2264             :   }
+    2265             : 
+    2266             :   // defined so we match C++20 behavior in all cases.
+    2267             :   template <typename A = alloc_ty, typename V = value_ty,
+    2268             :             typename std::enable_if<(! is_trivially_destructible<V>::value
+    2269             :                                      ||  must_use_alloc_destroy<A, V>::value)
+    2270             :                                     &&! has_alloc_destroy<A, V>::value>::type * = nullptr>
+    2271             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2272             :   void
+    2273             :   destroy (ptr p) noexcept
+    2274             :   {
+    2275             :     destroy_at (to_address (p));
+    2276             :   }
+    2277             : 
+    2278             :   template <typename A = alloc_ty, typename V = value_ty,
+    2279             :             typename std::enable_if<is_trivially_destructible<V>::value
+    2280             :                                     &&! must_use_alloc_destroy<A, V>::value>::type * = nullptr>
+    2281             :   PLUMED_GCH_CPP14_CONSTEXPR
+    2282             :   void
+    2283             :   destroy_range (ptr, ptr) const noexcept
+    2284             :   { }
+    2285             : 
+    2286             :   template <typename A = alloc_ty, typename V = value_ty,
+    2287             :             typename std::enable_if<! is_trivially_destructible<V>::value
+    2288             :                                     ||  must_use_alloc_destroy<A, V>::value>::type * = nullptr>
+    2289             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2290             :   void
+    2291             :   destroy_range (ptr first, ptr last) noexcept
+    2292             :   {
+    2293             :     for (; ! (first == last); ++first)
+    2294             :       destroy (first);
+    2295             :   }
+    2296             : 
+    2297             :   // allowed if trivially copyable and we use the standard allocator
+    2298             :   // and InputIt is a contiguous iterator
+    2299             :   template <typename ForwardIt,
+    2300             :             typename std::enable_if<
+    2301             :               is_uninitialized_memcpyable_iterator<ForwardIt>::value, bool>::type = true>
+    2302             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2303             :   ptr
+    2304       23058 :   uninitialized_copy (ForwardIt first, ForwardIt last, ptr dest) noexcept
+    2305             :   {
+    2306             :     static_assert (std::is_constructible<value_ty, decltype (*first)>::value,
+    2307             :                    "`value_type` must be copy constructible.");
+    2308             : 
+    2309             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2310             :     if (std::is_constant_evaluated ())
+    2311             :       return default_uninitialized_copy (first, last, dest);
+    2312             : #endif
+    2313             : 
+    2314             :     const size_ty num_copy = external_range_length (first, last);
+    2315       23058 :     if (num_copy != 0)
+    2316       23058 :       std::memcpy (to_address (dest), to_address (first), num_copy * sizeof (value_ty));
+    2317       23058 :     return unchecked_next (dest, num_copy);
+    2318             :   }
+    2319             : 
+    2320             :   template <typename ForwardIt,
+    2321             :             typename std::enable_if<
+    2322             :               is_uninitialized_memcpyable_iterator<ForwardIt>::value, bool>::type = true>
+    2323             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2324             :   ptr
+    2325             :   uninitialized_copy (std::move_iterator<ForwardIt> first,
+    2326             :                       std::move_iterator<ForwardIt> last,
+    2327             :                       ptr dest) noexcept
+    2328             :   {
+    2329         172 :     return uninitialized_copy (first.base (), last.base (), dest);
+    2330             :   }
+    2331             : 
+    2332             :   template <typename InputIt,
+    2333             :             typename std::enable_if<
+    2334             :               ! is_uninitialized_memcpyable_iterator<InputIt>::value, bool>::type = false>
+    2335             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2336             :   ptr
+    2337             :   uninitialized_copy (InputIt first, InputIt last, ptr d_first)
+    2338             :   {
+    2339             :     return default_uninitialized_copy (first, last, d_first);
+    2340             :   }
+    2341             : 
+    2342             :   template <typename InputIt>
+    2343             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2344             :   ptr
+    2345             :   default_uninitialized_copy (InputIt first, InputIt last, ptr d_first)
+    2346             :   {
+    2347             :     ptr d_last = d_first;
+    2348             :     PLUMED_GCH_TRY
+    2349             :     {
+    2350             :       // Note: Not != because `using namespace std::rel_ops` can break constexpr.
+    2351             :       for (; ! (first == last); ++first, static_cast<void> (++d_last))
+    2352             :         construct (d_last, *first);
+    2353             :       return d_last;
+    2354             :     }
+    2355             :     PLUMED_GCH_CATCH (...)
+    2356             :     {
+    2357             :       destroy_range (d_first, d_last);
+    2358             :       PLUMED_GCH_THROW;
+    2359             :     }
+    2360             :   }
+    2361             : 
+    2362             :   template <typename A = alloc_ty, typename V = value_ty,
+    2363             :             typename std::enable_if<is_trivially_constructible<V>::value
+    2364             :                                     &&! must_use_alloc_construct<A, V>::value>::type * = nullptr>
+    2365             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2366             :   ptr
+    2367             :   uninitialized_value_construct (ptr first, ptr last)
+    2368             :   {
+    2369             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2370             :     if (std::is_constant_evaluated ())
+    2371             :       return default_uninitialized_value_construct (first, last);
+    2372             : #endif
+    2373             :     std::fill (first, last, value_ty ());
+    2374             :     return last;
+    2375             :   }
+    2376             : 
+    2377             :   template <typename A = alloc_ty, typename V = value_ty,
+    2378             :             typename std::enable_if<! is_trivially_constructible<V>::value
+    2379             :                                     ||  must_use_alloc_construct<A, V>::value>::type * = nullptr>
+    2380             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2381             :   ptr
+    2382             :   uninitialized_value_construct (ptr first, ptr last)
+    2383             :   {
+    2384             :     return default_uninitialized_value_construct (first, last);
+    2385             :   }
+    2386             : 
+    2387             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2388             :   ptr
+    2389             :   default_uninitialized_value_construct (ptr first, ptr last)
+    2390             :   {
+    2391             :     ptr curr = first;
+    2392             :     PLUMED_GCH_TRY
+    2393             :     {
+    2394             :       for (; ! (curr == last); ++curr)
+    2395             :         construct (curr);
+    2396             :       return curr;
+    2397             :     }
+    2398             :     PLUMED_GCH_CATCH (...)
+    2399             :     {
+    2400             :       destroy_range (first, curr);
+    2401             :       PLUMED_GCH_THROW;
+    2402             :     }
+    2403             :   }
+    2404             : 
+    2405             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2406             :   ptr
+    2407             :   uninitialized_fill (ptr first, ptr last)
+    2408             :   {
+    2409             :     return uninitialized_value_construct (first, last);
+    2410             :   }
+    2411             : 
+    2412             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2413             :   ptr
+    2414             :   uninitialized_fill (ptr first, ptr last, const value_ty& val)
+    2415             :   {
+    2416             :     ptr curr = first;
+    2417             :     PLUMED_GCH_TRY
+    2418             :     {
+    2419             :       for (; ! (curr == last); ++curr)
+    2420             :         construct (curr, val);
+    2421             :       return curr;
+    2422             :     }
+    2423             :     PLUMED_GCH_CATCH (...)
+    2424             :     {
+    2425             :       destroy_range (first, curr);
+    2426             :       PLUMED_GCH_THROW;
+    2427             :     }
+    2428             :   }
+    2429             : 
+    2430             : private:
+    2431             :   // If value_ty is an array, replicate C++20 behavior (I don't think that value_ty can
+    2432             :   // actually be an array because of the Erasable requirement, but there shouldn't
+    2433             :   // be any runtime cost for being defensive here).
+    2434             :   template <typename V = value_ty,
+    2435             :             typename std::enable_if<std::is_array<V>::value, bool>::type = true>
+    2436             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2437             :   void
+    2438             :   destroy_at (value_ty *p) noexcept
+    2439             :   {
+    2440             :     for (auto& e : *p)
+    2441             :       destroy_at (std::addressof (e));
+    2442             :   }
+    2443             : 
+    2444             :   template <typename V = value_ty,
+    2445             :             typename std::enable_if<! std::is_array<V>::value, bool>::type = false>
+    2446             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2447             :   void
+    2448             :   destroy_at (value_ty *p) noexcept
+    2449             :   {
+    2450             :     p->~value_ty ();
+    2451             :   }
+    2452             : 
+    2453             :   template <typename V = value_ty, typename ...Args>
+    2454             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2455             :   auto
+    2456             :   construct_at (value_ty *p, Args&&... args)
+    2457             :   noexcept (noexcept (::new (std::declval<void *> ()) V (std::declval<Args> ()...)))
+    2458             :   -> decltype (::new (std::declval<void *> ()) V (std::declval<Args> ()...))
+    2459             :   {
+    2460             : #if defined (PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED) && defined (PLUMED_GCH_LIB_CONSTEXPR_MEMORY)
+    2461             :     if (std::is_constant_evaluated ())
+    2462             :       return std::construct_at (p, std::forward<Args> (args)...);
+    2463             : #endif
+    2464             :     void *vp = const_cast<void *> (static_cast<const volatile void *> (p));
+    2465             :     return ::new (vp) value_ty (std::forward<Args>(args)...);
+    2466             :   }
+    2467             : };
+    2468             : 
+    2469             : template <typename Pointer, typename SizeT>
+    2470             : class small_vector_data_base
+    2471             : {
+    2472             : public:
+    2473             :   using ptr     = Pointer;
+    2474             :   using size_ty = SizeT;
+    2475             : 
+    2476             :   small_vector_data_base            (void)                              = default;
+    2477             :   small_vector_data_base            (const small_vector_data_base&)     = default;
+    2478             :   small_vector_data_base            (small_vector_data_base&&) noexcept = default;
+    2479             :   small_vector_data_base& operator= (const small_vector_data_base&)     = default;
+    2480             :   small_vector_data_base& operator= (small_vector_data_base&&) noexcept = default;
+    2481             :   ~small_vector_data_base           (void)                              = default;
+    2482             : 
+    2483   141987491 :   constexpr ptr     data_ptr (void) const noexcept { return m_data_ptr; }
+    2484     4131892 :   constexpr size_ty capacity (void) const noexcept { return m_capacity; }
+    2485   180715261 :   constexpr size_ty size     (void) const noexcept { return m_size; }
+    2486             : 
+    2487     1277523 :   PLUMED_GCH_CPP20_CONSTEXPR void set_data_ptr (ptr     data_ptr) noexcept { m_data_ptr = data_ptr; }
+    2488     1277523 :   PLUMED_GCH_CPP20_CONSTEXPR void set_capacity (size_ty capacity) noexcept { m_capacity = capacity; }
+    2489     3709582 :   PLUMED_GCH_CPP20_CONSTEXPR void set_size     (size_ty size)     noexcept { m_size     = size;     }
+    2490             : 
+    2491             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2492             :   void
+    2493             :   set (ptr data_ptr, size_ty capacity, size_ty size)
+    2494             :   {
+    2495         172 :     m_data_ptr = data_ptr;
+    2496         172 :     m_capacity = capacity;
+    2497         172 :     m_size     = size;
+    2498             :   }
+    2499             : 
+    2500             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2501             :   void
+    2502             :   swap_data_ptr (small_vector_data_base& other) noexcept
+    2503             :   {
+    2504             :     using std::swap;
+    2505             :     swap (m_data_ptr, other.m_data_ptr);
+    2506             :   }
+    2507             : 
+    2508             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2509             :   void
+    2510             :   swap_capacity (small_vector_data_base& other) noexcept
+    2511             :   {
+    2512             :     using std::swap;
+    2513             :     swap (m_capacity, other.m_capacity);
+    2514             :   }
+    2515             : 
+    2516             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2517             :   void
+    2518             :   swap_size (small_vector_data_base& other) noexcept
+    2519             :   {
+    2520             :     using std::swap;
+    2521             :     swap (m_size, other.m_size);
+    2522             :   }
+    2523             : 
+    2524             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2525             :   void
+    2526             :   swap (small_vector_data_base& other) noexcept
+    2527             :   {
+    2528             :     using std::swap;
+    2529             :     swap (m_data_ptr, other.m_data_ptr);
+    2530             :     swap (m_capacity, other.m_capacity);
+    2531             :     swap (m_size,     other.m_size);
+    2532             :   }
+    2533             : 
+    2534             : private:
+    2535             :   ptr     m_data_ptr;
+    2536             :   size_ty m_capacity;
+    2537             :   size_ty m_size;
+    2538             : };
+    2539             : 
+    2540             : template <typename Pointer, typename SizeT, typename T, unsigned InlineCapacity>
+    2541             : class small_vector_data
+    2542             : : public small_vector_data_base<Pointer, SizeT>
+    2543             : {
+    2544             : public:
+    2545             :   using value_ty = T;
+    2546             : 
+    2547             :   small_vector_data            (void)                         = default;
+    2548             :   small_vector_data            (const small_vector_data&)     = delete;
+    2549             :   small_vector_data            (small_vector_data&&) noexcept = delete;
+    2550             :   small_vector_data& operator= (const small_vector_data&)     = delete;
+    2551             :   small_vector_data& operator= (small_vector_data&&) noexcept = delete;
+    2552             :   ~small_vector_data           (void)                         = default;
+    2553             : 
+    2554             :   PLUMED_GCH_CPP14_CONSTEXPR
+    2555             :   value_ty *
+    2556             :   storage (void) noexcept
+    2557             :   {
+    2558             :     return m_storage.get_inline_ptr ();
+    2559             :   }
+    2560             : 
+    2561             :   constexpr
+    2562             :   const value_ty *
+    2563             :   storage (void) const noexcept
+    2564             :   {
+    2565             :     return m_storage.get_inline_ptr ();
+    2566             :   }
+    2567             : 
+    2568             : private:
+    2569             :   inline_storage<value_ty, InlineCapacity> m_storage;
+    2570             : };
+    2571             : 
+    2572             : template <typename Pointer, typename SizeT, typename T>
+    2573             : class PLUMED_GCH_EMPTY_BASE small_vector_data<Pointer, SizeT, T, 0>
+    2574             : : public  small_vector_data_base<Pointer, SizeT>,
+    2575             : private inline_storage<T, 0>
+    2576             : {
+    2577             :   using base = inline_storage<T, 0>;
+    2578             : 
+    2579             : public:
+    2580             :   using value_ty = T;
+    2581             : 
+    2582             :   small_vector_data            (void)                         = default;
+    2583             :   small_vector_data            (const small_vector_data&)     = delete;
+    2584             :   small_vector_data            (small_vector_data&&) noexcept = delete;
+    2585             :   small_vector_data& operator= (const small_vector_data&)     = delete;
+    2586             :   small_vector_data& operator= (small_vector_data&&) noexcept = delete;
+    2587             :   ~small_vector_data           (void)                         = default;
+    2588             : 
+    2589             :   PLUMED_GCH_CPP14_CONSTEXPR
+    2590             :   value_ty *
+    2591             :   storage (void) noexcept
+    2592             :   {
+    2593             :     return base::get_inline_ptr ();
+    2594             :   }
+    2595             : 
+    2596             :   constexpr
+    2597             :   const value_ty *
+    2598             :   storage (void) const noexcept
+    2599             :   {
+    2600             :     return base::get_inline_ptr ();
+    2601             :   }
+    2602             : };
+    2603             : 
+    2604             : template <typename Allocator, unsigned InlineCapacity>
+    2605             : class small_vector_base
+    2606             : : public allocator_interface<Allocator>
+    2607             : {
+    2608             : public:
+    2609             :   using size_type       = typename allocator_interface<Allocator>::size_type;
+    2610             :   using difference_type = typename allocator_interface<Allocator>::difference_type;
+    2611             : 
+    2612             :   template <typename SameAllocator, unsigned DifferentInlineCapacity>
+    2613             :   friend class small_vector_base;
+    2614             : 
+    2615             : protected:
+    2616             :   using alloc_interface = allocator_interface<Allocator>;
+    2617             :   using alloc_traits    = typename alloc_interface::alloc_traits;
+    2618             :   using alloc_ty        = Allocator;
+    2619             : 
+    2620             :   using value_ty        = typename alloc_interface::value_ty;
+    2621             :   using ptr             = typename alloc_interface::ptr;
+    2622             :   using cptr            = typename alloc_interface::cptr;
+    2623             :   using size_ty         = typename alloc_interface::size_ty;
+    2624             :   using diff_ty         = typename alloc_interface::diff_ty;
+    2625             : 
+    2626             :   static_assert (alloc_interface::template is_complete<value_ty>::value || InlineCapacity == 0,
+    2627             :                  "`value_type` must be complete for instantiation of a non-zero number "
+    2628             :                  "of inline elements.");
+    2629             : 
+    2630             :   template <typename T>
+    2631             :   using is_complete = typename alloc_interface::template is_complete<T>;
+    2632             : 
+    2633             :   using alloc_interface::allocator_ref;
+    2634             :   using alloc_interface::construct;
+    2635             :   using alloc_interface::deallocate;
+    2636             :   using alloc_interface::destroy;
+    2637             :   using alloc_interface::destroy_range;
+    2638             :   using alloc_interface::external_range_length;
+    2639             :   using alloc_interface::get_max_size;
+    2640             :   using alloc_interface::internal_range_length;
+    2641             :   using alloc_interface::to_address;
+    2642             :   using alloc_interface::unchecked_advance;
+    2643             :   using alloc_interface::unchecked_next;
+    2644             :   using alloc_interface::unchecked_prev;
+    2645             :   using alloc_interface::uninitialized_copy;
+    2646             :   using alloc_interface::uninitialized_fill;
+    2647             :   using alloc_interface::uninitialized_value_construct;
+    2648             : 
+    2649             :   template <typename Integer>
+    2650             :   PLUMED_GCH_NODISCARD
+    2651             :   static PLUMED_GCH_CONSTEVAL
+    2652             :   std::size_t
+    2653             :   numeric_max (void) noexcept
+    2654             :   {
+    2655             :     return alloc_interface::template numeric_max<Integer> ();
+    2656             :   }
+    2657             : 
+    2658             :   PLUMED_GCH_NODISCARD
+    2659             :   static PLUMED_GCH_CONSTEVAL
+    2660             :   size_ty
+    2661             :   get_inline_capacity (void) noexcept
+    2662             :   {
+    2663             :     return static_cast<size_ty> (InlineCapacity);
+    2664             :   }
+    2665             : 
+    2666             :   template <typename ...>
+    2667             :   using void_t = void;
+    2668             : 
+    2669             :   template <bool B>
+    2670             :   using bool_constant = std::integral_constant<bool, B>;
+    2671             : 
+    2672             :   template <typename Void, typename AI, typename V, typename ...Args>
+    2673             :   struct is_emplace_constructible_impl
+    2674             : : std::false_type
+    2675             :   {
+    2676             :     using nothrow = std::false_type;
+    2677             :   };
+    2678             : 
+    2679             :   template <typename AI, typename V, typename ...Args>
+    2680             :   struct is_emplace_constructible_impl<
+    2681             :     void_t<typename std::enable_if<is_complete<V>::value>::type,
+    2682             :            decltype (std::declval<AI&> ().construct (std::declval<V *> (),
+    2683             :                      std::declval<Args> ()...))>,
+    2684             :     AI, V, Args...>
+    2685             : : std::true_type
+    2686             :   {
+    2687             :     using nothrow =
+    2688             :     bool_constant<noexcept (std::declval<AI&> ().construct (std::declval<V *> (),
+    2689             :                             std::declval<Args> ()...))>;
+    2690             :                                                            };
+    2691             : 
+    2692             :   template <typename ...Args>
+    2693             :   struct is_emplace_constructible
+    2694             : : is_emplace_constructible_impl<void, alloc_interface, value_ty, Args...>
+    2695             :   { };
+    2696             : 
+    2697             :   template <typename ...Args>
+    2698             :   struct is_nothrow_emplace_constructible
+    2699             : : is_emplace_constructible_impl<void, alloc_interface, value_ty, Args...>::nothrow
+    2700             :   { };
+    2701             : 
+    2702             :   template <typename V = value_ty>
+    2703             :   struct is_explicitly_move_insertable
+    2704             : : is_emplace_constructible<V&&>
+    2705             :   { };
+    2706             : 
+    2707             :   template <typename V = value_ty>
+    2708             :   struct is_explicitly_nothrow_move_insertable
+    2709             : : is_nothrow_emplace_constructible<V&&>
+    2710             :   { };
+    2711             : 
+    2712             :   template <typename V = value_ty>
+    2713             :   struct is_explicitly_copy_insertable
+    2714             : : std::integral_constant<bool, is_emplace_constructible<V&>::value
+    2715             :                            &&  is_emplace_constructible<const V&>::value>
+    2716             :   { };
+    2717             : 
+    2718             :   template <typename V = value_ty>
+    2719             :   struct is_explicitly_nothrow_copy_insertable
+    2720             : : std::integral_constant<bool, is_nothrow_emplace_constructible<V&>::value
+    2721             :                            &&  is_nothrow_emplace_constructible<const V&>::value>
+    2722             :   { };
+    2723             : 
+    2724             :   template <typename AI, typename Enable = void>
+    2725             :   struct is_eraseable
+    2726             : : std::false_type
+    2727             :   { };
+    2728             : 
+    2729             :   template <typename AI>
+    2730             :   struct is_eraseable<AI,
+    2731             :                       void_t<decltype (std::declval<AI&> ().destroy (std::declval<value_ty *> ()))>>
+    2732             : : std::true_type
+    2733             :   { };
+    2734             : 
+    2735             :   template <typename V>
+    2736             :   struct relocate_with_move
+    2737             : #ifdef PLUMED_GCH_NO_STRONG_EXCEPTION_GUARANTEES
+    2738             : : std::true_type
+    2739             : #else
+    2740             : : bool_constant<std::is_nothrow_move_constructible<V>::value
+    2741             :                   ||! is_explicitly_copy_insertable<V>::value>
+    2742             : #endif
+    2743             :   { };
+    2744             : 
+    2745             :   template <typename A>
+    2746             :   struct allocations_are_movable
+    2747             : : bool_constant<std::is_same<std::allocator<value_ty>, A>::value
+    2748             :                   ||  std::allocator_traits<A>::propagate_on_container_move_assignment::value
+    2749             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    2750             :                   ||  std::allocator_traits<A>::is_always_equal::value
+    2751             : #endif
+    2752             :                   >
+    2753             :   { };
+    2754             : 
+    2755             :   template <typename A>
+    2756             :   struct allocations_are_swappable
+    2757             : : bool_constant<std::is_same<std::allocator<value_ty>, A>::value
+    2758             :                   ||  std::allocator_traits<A>::propagate_on_container_swap::value
+    2759             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    2760             :                   ||  std::allocator_traits<A>::is_always_equal::value
+    2761             : #endif
+    2762             :                   >
+    2763             :   { };
+    2764             : 
+    2765             :   template <typename ...Args>
+    2766             :   using is_memcpyable = typename alloc_interface::template is_memcpyable<Args...>;
+    2767             : 
+    2768             :   template <typename ...Args>
+    2769             :   using is_memcpyable_iterator =
+    2770             :   typename alloc_interface::template is_memcpyable_iterator<Args...>;
+    2771             : 
+    2772             :   PLUMED_GCH_NORETURN
+    2773             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2774             :   void
+    2775             :   throw_overflow_error (void)
+    2776             :   {
+    2777             : #ifdef PLUMED_GCH_EXCEPTIONS
+    2778             :     throw std::overflow_error ("The requested conversion would overflow.");
+    2779             : #else
+    2780             :     std::fprintf (stderr, "[gch::small_vector] The requested conversion would overflow.\n");
+    2781             :     std::abort ();
+    2782             : #endif
+    2783             :   }
+    2784             : 
+    2785             :   PLUMED_GCH_NORETURN
+    2786             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2787             :   void
+    2788             :   throw_index_error (void)
+    2789             :   {
+    2790             : #ifdef PLUMED_GCH_EXCEPTIONS
+    2791             :     throw std::out_of_range ("The requested index was out of range.");
+    2792             : #else
+    2793             :     std::fprintf (stderr, "[gch::small_vector] The requested index was out of range.\n");
+    2794             :     std::abort ();
+    2795             : #endif
+    2796             :   }
+    2797             : 
+    2798             :   PLUMED_GCH_NORETURN
+    2799             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2800             :   void
+    2801             :   throw_increment_error (void)
+    2802             :   {
+    2803             : #ifdef PLUMED_GCH_EXCEPTIONS
+    2804             :     throw std::domain_error ("The requested increment was outside of the allowed range.");
+    2805             : #else
+    2806             :     std::fprintf (
+    2807             :       stderr,
+    2808             :       "[gch::small_vector] The requested increment was outside of the allowed range.\n");
+    2809             :     std::abort ();
+    2810             : #endif
+    2811             :   }
+    2812             : 
+    2813             :   PLUMED_GCH_NORETURN
+    2814             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    2815             :   void
+    2816           0 :   throw_allocation_size_error (void)
+    2817             :   {
+    2818             : #ifdef PLUMED_GCH_EXCEPTIONS
+    2819           0 :     throw std::length_error ("The required allocation exceeds the maximum size.");
+    2820             : #else
+    2821             :     std::fprintf (
+    2822             :       stderr,
+    2823             :       "[gch::small_vector] The required allocation exceeds the maximum size.\n");
+    2824             :     std::abort ();
+    2825             : #endif
+    2826             :   }
+    2827             : 
+    2828             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    2829             :   ptr
+    2830             :   ptr_cast (const small_vector_iterator<cptr, diff_ty>& it) noexcept
+    2831             :   {
+    2832             :     return unchecked_next (begin_ptr (), it.base () - begin_ptr ());
+    2833             :   }
+    2834             : 
+    2835             : private:
+    2836             :   class stack_temporary
+    2837             :   {
+    2838             :   public:
+    2839             :     stack_temporary            (void)                       = delete;
+    2840             :     stack_temporary            (const stack_temporary&)     = delete;
+    2841             :     stack_temporary            (stack_temporary&&) noexcept = delete;
+    2842             :     stack_temporary& operator= (const stack_temporary&)     = delete;
+    2843             :     stack_temporary& operator= (stack_temporary&&) noexcept = delete;
+    2844             : //      ~stack_temporary           (void)                       = impl;
+    2845             : 
+    2846             :     template <typename ...Args>
+    2847             :     PLUMED_GCH_CPP20_CONSTEXPR explicit
+    2848             :     stack_temporary (alloc_interface& alloc_iface, Args&&... args)
+    2849             :       : m_interface (alloc_iface)
+    2850             :     {
+    2851             :       m_interface.construct (get_pointer (), std::forward<Args> (args)...);
+    2852             :     }
+    2853             : 
+    2854             :     PLUMED_GCH_CPP20_CONSTEXPR
+    2855             :     ~stack_temporary (void)
+    2856             :     {
+    2857             :       m_interface.destroy (get_pointer ());
+    2858             :     }
+    2859             : 
+    2860             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2861             :     const value_ty&
+    2862             :     get (void) const noexcept
+    2863             :     {
+    2864             :       return *get_pointer ();
+    2865             :     }
+    2866             : 
+    2867             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2868             :     value_ty&&
+    2869             :     release (void) noexcept
+    2870             :     {
+    2871             :       return std::move (*get_pointer ());
+    2872             :     }
+    2873             : 
+    2874             :   private:
+    2875             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2876             :     cptr
+    2877             :     get_pointer (void) const noexcept
+    2878             :     {
+    2879             :       return static_cast<cptr> (static_cast<const void *> (std::addressof (m_data)));
+    2880             :     }
+    2881             : 
+    2882             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2883             :     ptr
+    2884             :     get_pointer (void) noexcept
+    2885             :     {
+    2886             :       return static_cast<ptr> (static_cast<void *> (std::addressof (m_data)));
+    2887             :     }
+    2888             : 
+    2889             :     alloc_interface& m_interface;
+    2890             :     typename std::aligned_storage<sizeof (value_ty), alignof (value_ty)>::type m_data;
+    2891             :   };
+    2892             : 
+    2893             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    2894             : 
+    2895             :   class heap_temporary
+    2896             :   {
+    2897             :   public:
+    2898             :     heap_temporary            (void)                      = delete;
+    2899             :     heap_temporary            (const heap_temporary&)     = delete;
+    2900             :     heap_temporary            (heap_temporary&&) noexcept = delete;
+    2901             :     heap_temporary& operator= (const heap_temporary&)     = delete;
+    2902             :     heap_temporary& operator= (heap_temporary&&) noexcept = delete;
+    2903             : //      ~heap_temporary           (void)                      = impl;
+    2904             : 
+    2905             :     template <typename ...Args>
+    2906             :     PLUMED_GCH_CPP20_CONSTEXPR explicit
+    2907             :     heap_temporary (alloc_interface& alloc_iface, Args&&... args)
+    2908             :       : m_interface (alloc_iface),
+    2909             :         m_data_ptr  (alloc_iface.allocate (sizeof (value_ty)))
+    2910             :     {
+    2911             :       PLUMED_GCH_TRY
+    2912             :       {
+    2913             :         m_interface.construct (m_data_ptr, std::forward<Args> (args)...);
+    2914             :       }
+    2915             :       PLUMED_GCH_CATCH (...)
+    2916             :       {
+    2917             :         m_interface.deallocate (m_data_ptr, sizeof (value_ty));
+    2918             :         PLUMED_GCH_THROW;
+    2919             :       }
+    2920             :     }
+    2921             : 
+    2922             :     PLUMED_GCH_CPP20_CONSTEXPR
+    2923             :     ~heap_temporary (void)
+    2924             :     {
+    2925             :       m_interface.destroy (m_data_ptr);
+    2926             :       m_interface.deallocate (m_data_ptr, sizeof (value_ty));
+    2927             :     }
+    2928             : 
+    2929             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2930             :     const value_ty&
+    2931             :     get (void) const noexcept
+    2932             :     {
+    2933             :       return *m_data_ptr;
+    2934             :     }
+    2935             : 
+    2936             :     PLUMED_GCH_NODISCARD PLUMED_GCH_CPP20_CONSTEXPR
+    2937             :     value_ty&&
+    2938             :     release (void) noexcept
+    2939             :     {
+    2940             :       return std::move (*m_data_ptr);
+    2941             :     }
+    2942             : 
+    2943             :   private:
+    2944             :     alloc_interface& m_interface;
+    2945             :     ptr              m_data_ptr;
+    2946             :   };
+    2947             : 
+    2948             : #endif
+    2949             : 
+    2950             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2951             :   void
+    2952     1229663 :   wipe (void)
+    2953             :   {
+    2954     1229663 :     destroy_range (begin_ptr (), end_ptr ());
+    2955     1229663 :     if (has_allocation ())
+    2956             :       deallocate (data_ptr (), get_capacity ());
+    2957     1229663 :   }
+    2958             : 
+    2959             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2960             :   void
+    2961             :   set_data_ptr (ptr data_ptr) noexcept
+    2962             :   {
+    2963             :     m_data.set_data_ptr (data_ptr);
+    2964             :   }
+    2965             : 
+    2966             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2967             :   void
+    2968             :   set_capacity (size_ty capacity) noexcept
+    2969             :   {
+    2970             :     m_data.set_capacity (static_cast<size_type> (capacity));
+    2971             :   }
+    2972             : 
+    2973             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2974             :   void
+    2975             :   set_size (size_ty size) noexcept
+    2976             :   {
+    2977             :     m_data.set_size (static_cast<size_type> (size));
+    2978     1279312 :   }
+    2979             : 
+    2980             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2981             :   void
+    2982             :   set_data (ptr data_ptr, size_ty capacity, size_ty size) noexcept
+    2983             :   {
+    2984             :     m_data.set (data_ptr, static_cast<size_type> (capacity), static_cast<size_type> (size));
+    2985             :   }
+    2986             : 
+    2987             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2988             :   void
+    2989             :   swap_data_ptr (small_vector_base& other) noexcept
+    2990             :   {
+    2991             :     m_data.swap_data_ptr (other.m_data);
+    2992             :   }
+    2993             : 
+    2994             :   PLUMED_GCH_CPP20_CONSTEXPR
+    2995             :   void
+    2996             :   swap_capacity (small_vector_base& other) noexcept
+    2997             :   {
+    2998             :     m_data.swap_capacity (other.m_data);
+    2999             :   }
+    3000             : 
+    3001             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3002             :   void
+    3003             :   swap_size (small_vector_base& other) noexcept
+    3004             :   {
+    3005             :     m_data.swap_size (other.m_data);
+    3006             :   }
+    3007             : 
+    3008             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3009             :   void
+    3010             :   swap_allocation (small_vector_base& other) noexcept
+    3011             :   {
+    3012             :     m_data.swap (other.m_data);
+    3013             :   }
+    3014             : 
+    3015             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3016             :   void
+    3017             :   reset_data (ptr data_ptr, size_ty capacity, size_ty size)
+    3018             :   {
+    3019         172 :     wipe ();
+    3020             :     m_data.set (data_ptr, static_cast<size_type> (capacity), static_cast<size_type> (size));
+    3021           0 :   }
+    3022             : 
+    3023             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3024             :   void
+    3025             :   increase_size (size_ty n) noexcept
+    3026             :   {
+    3027     1622401 :     m_data.set_size (get_size () + n);
+    3028             :   }
+    3029             : 
+    3030             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3031             :   void
+    3032             :   decrease_size (size_ty n) noexcept
+    3033             :   {
+    3034             :     m_data.set_size (get_size () - n);
+    3035             :   }
+    3036             : 
+    3037             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3038             :   ptr
+    3039             :   unchecked_allocate (size_ty n)
+    3040             :   {
+    3041             :     assert (InlineCapacity < n && "Allocated capacity should be greater than InlineCapacity.");
+    3042             :     return alloc_interface::allocate (n);
+    3043             :   }
+    3044             : 
+    3045             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3046             :   ptr
+    3047             :   unchecked_allocate (size_ty n, cptr hint)
+    3048             :   {
+    3049             :     assert (InlineCapacity < n && "Allocated capacity should be greater than InlineCapacity.");
+    3050             :     return alloc_interface::allocate_with_hint (n, hint);
+    3051             :   }
+    3052             : 
+    3053             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3054             :   ptr
+    3055             :   checked_allocate (size_ty n)
+    3056             :   {
+    3057             :     if (get_max_size () < n)
+    3058             :       throw_allocation_size_error ();
+    3059             :     return unchecked_allocate (n);
+    3060             :   }
+    3061             : 
+    3062             : protected:
+    3063             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    3064             :   size_ty
+    3065             :   unchecked_calculate_new_capacity (const size_ty minimum_required_capacity) const noexcept
+    3066             :   {
+    3067             :     const size_ty current_capacity = get_capacity ();
+    3068             : 
+    3069             :     assert (current_capacity < minimum_required_capacity);
+    3070             : 
+    3071         172 :     if (get_max_size () - current_capacity <= current_capacity)
+    3072             :       return get_max_size ();
+    3073             : 
+    3074             :     // Note: This growth factor might be theoretically superior, but in testing it falls flat:
+    3075             :     // size_ty new_capacity = current_capacity + (current_capacity / 2);
+    3076             : 
+    3077         172 :     const size_ty new_capacity = 2 * current_capacity;
+    3078             :     if (new_capacity < minimum_required_capacity)
+    3079             :       return minimum_required_capacity;
+    3080             :     return new_capacity;
+    3081             :   }
+    3082             : 
+    3083             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    3084             :   size_ty
+    3085             :   checked_calculate_new_capacity (const size_ty minimum_required_capacity) const
+    3086             :   {
+    3087             :     if (get_max_size () < minimum_required_capacity)
+    3088             :       throw_allocation_size_error ();
+    3089             :     return unchecked_calculate_new_capacity (minimum_required_capacity);
+    3090             :   }
+    3091             : 
+    3092             :   template <unsigned I>
+    3093             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3094             :   small_vector_base&
+    3095     1279312 :   copy_assign_default (const small_vector_base<Allocator, I>& other)
+    3096             :   {
+    3097     1279312 :     if (get_capacity () < other.get_size ())
+    3098             :     {
+    3099             :       // Reallocate.
+    3100             :       size_ty new_capacity = unchecked_calculate_new_capacity (other.get_size ());
+    3101           0 :       ptr     new_data_ptr = unchecked_allocate (new_capacity, other.allocation_end_ptr ());
+    3102             : 
+    3103             :       PLUMED_GCH_TRY
+    3104             :       {
+    3105           0 :         uninitialized_copy (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3106             :       }
+    3107             :       PLUMED_GCH_CATCH (...)
+    3108             :       {
+    3109             :         deallocate (new_data_ptr, new_capacity);
+    3110             :         PLUMED_GCH_THROW;
+    3111             :       }
+    3112             : 
+    3113             :       reset_data (new_data_ptr, new_capacity, other.get_size ());
+    3114             :     }
+    3115             :     else
+    3116             :     {
+    3117     1279312 :       if (get_size () < other.get_size ())
+    3118             :       {
+    3119             :         // No reallocation, partially in uninitialized space.
+    3120       22886 :         std::copy_n (other.begin_ptr (), get_size (), begin_ptr ());
+    3121       45772 :         uninitialized_copy (
+    3122             :           unchecked_next (other.begin_ptr (), get_size ()),
+    3123             :           other.end_ptr (),
+    3124             :           end_ptr ());
+    3125             :       }
+    3126             :       else
+    3127             :       {
+    3128     1256426 :         destroy_range (copy_range (other.begin_ptr (), other.end_ptr (), begin_ptr ()),
+    3129             :                        end_ptr ());
+    3130             :       }
+    3131             : 
+    3132             :       // data_ptr and capacity do not change in this case.
+    3133             :       set_size (other.get_size ());
+    3134             :     }
+    3135             : 
+    3136             :     alloc_interface::operator= (other);
+    3137     1279312 :     return *this;
+    3138             :   }
+    3139             : 
+    3140             :   template <unsigned I, typename AT = alloc_traits,
+    3141             :             typename std::enable_if<AT::propagate_on_container_copy_assignment::value
+    3142             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    3143             :                                     &&! AT::is_always_equal::value
+    3144             : #endif
+    3145             :                                     >::type * = nullptr>
+    3146             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3147             :   small_vector_base&
+    3148             :   copy_assign (const small_vector_base<Allocator, I>& other)
+    3149             :   {
+    3150             :     if (other.allocator_ref () == allocator_ref ())
+    3151             :       return copy_assign_default (other);
+    3152             : 
+    3153             :     if (InlineCapacity < other.get_size ())
+    3154             :     {
+    3155             :       alloc_interface new_alloc (other);
+    3156             : 
+    3157             :       const size_ty new_capacity = other.get_size ();
+    3158             :       const ptr new_data_ptr = new_alloc.allocate_with_hint (
+    3159             :                                  new_capacity,
+    3160             :                                  other.allocation_end_ptr ());
+    3161             : 
+    3162             :       PLUMED_GCH_TRY
+    3163             :       {
+    3164             :         uninitialized_copy (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3165             :       }
+    3166             :       PLUMED_GCH_CATCH (...)
+    3167             :       {
+    3168             :         new_alloc.deallocate (new_data_ptr, new_capacity);
+    3169             :         PLUMED_GCH_THROW;
+    3170             :       }
+    3171             : 
+    3172             :       reset_data (new_data_ptr, new_capacity, other.get_size ());
+    3173             :       alloc_interface::operator= (new_alloc);
+    3174             :     }
+    3175             :     else
+    3176             :     {
+    3177             :       if (has_allocation ())
+    3178             :       {
+    3179             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    3180             :         ptr new_data_ptr;
+    3181             :         if (std::is_constant_evaluated ())
+    3182             :         {
+    3183             :           alloc_interface new_alloc (other);
+    3184             :           new_data_ptr = new_alloc.allocate (InlineCapacity);
+    3185             :         }
+    3186             :         else
+    3187             :           new_data_ptr = storage_ptr ();
+    3188             : #else
+    3189             :         const ptr new_data_ptr = storage_ptr ();
+    3190             : #endif
+    3191             : 
+    3192             :         uninitialized_copy (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3193             :         destroy_range (begin_ptr (), end_ptr ());
+    3194             :         deallocate (data_ptr (), get_capacity ());
+    3195             :         set_data_ptr (new_data_ptr);
+    3196             :         set_capacity (InlineCapacity);
+    3197             :       }
+    3198             :       else if (get_size () < other.get_size ())
+    3199             :       {
+    3200             :         std::copy_n (other.begin_ptr (), get_size (), begin_ptr ());
+    3201             :         uninitialized_copy (
+    3202             :           unchecked_next (other.begin_ptr (), get_size ()),
+    3203             :           other.end_ptr (),
+    3204             :           end_ptr ());
+    3205             :       }
+    3206             :       else
+    3207             :       {
+    3208             :         destroy_range (copy_range (other.begin_ptr (), other.end_ptr (), begin_ptr ()),
+    3209             :                        end_ptr ());
+    3210             :       }
+    3211             :       set_size (other.get_size ());
+    3212             :       alloc_interface::operator= (other);
+    3213             :     }
+    3214             : 
+    3215             :     return *this;
+    3216             :   }
+    3217             : 
+    3218             :   template <unsigned I, typename AT = alloc_traits,
+    3219             :             typename std::enable_if<! AT::propagate_on_container_copy_assignment::value
+    3220             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    3221             :                                     ||  AT::is_always_equal::value
+    3222             : #endif
+    3223             :                                     >::type * = nullptr>
+    3224             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3225             :   small_vector_base&
+    3226             :   copy_assign (const small_vector_base<Allocator, I>& other)
+    3227             :   {
+    3228             :     return copy_assign_default (other);
+    3229             :   }
+    3230             : 
+    3231             :   template <unsigned I>
+    3232             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3233             :   void
+    3234             :   move_allocation_pointer (small_vector_base<alloc_ty, I>&& other) noexcept
+    3235             :   {
+    3236             :     reset_data (other.data_ptr (), other.get_capacity (), other.get_size ());
+    3237             :     other.set_default ();
+    3238             :   }
+    3239             : 
+    3240             :   template <unsigned N = InlineCapacity, typename std::enable_if<N == 0>::type * = nullptr>
+    3241             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3242             :   small_vector_base&
+    3243             :   move_assign_default (small_vector_base&& other) noexcept
+    3244             :   {
+    3245             :     move_allocation_pointer (std::move (other));
+    3246             :     alloc_interface::operator= (std::move (other));
+    3247             :     return *this;
+    3248             :   }
+    3249             : 
+    3250             :   template <unsigned LessEqualI,
+    3251             :             typename std::enable_if<(LessEqualI <= InlineCapacity)>::type * = nullptr>
+    3252             :             PLUMED_GCH_CPP20_CONSTEXPR
+    3253             :             small_vector_base&
+    3254             :             move_assign_default (small_vector_base<Allocator, LessEqualI>&& other)
+    3255             :             noexcept (std::is_nothrow_move_assignable<value_ty>::value
+    3256             :                       &&  std::is_nothrow_move_constructible<value_ty>::value)
+    3257             :   {
+    3258             :     // We only move the allocation pointer over if it has strictly greater capacity than
+    3259             :     // the inline capacity of `*this` because allocations can never have a smaller capacity
+    3260             :     // than the inline capacity.
+    3261             :     if (InlineCapacity < other.get_capacity ())
+    3262             :           move_allocation_pointer (std::move (other));
+    3263             :     else
+    3264             :     {
+    3265             :       // We are guaranteed to have sufficient capacity to store the elements.
+    3266             :       if (InlineCapacity < get_capacity ())
+    3267             :       {
+    3268             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    3269             :         ptr new_data_ptr;
+    3270             :         if (std::is_constant_evaluated ())
+    3271             :           new_data_ptr = other.allocate (InlineCapacity);
+    3272             :         else
+    3273             :           new_data_ptr = storage_ptr ();
+    3274             : #else
+    3275             :         const ptr new_data_ptr = storage_ptr ();
+    3276             : #endif
+    3277             : 
+    3278             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3279             :         destroy_range (begin_ptr (), end_ptr ());
+    3280             :         deallocate (data_ptr (), get_capacity ());
+    3281             :         set_data_ptr (new_data_ptr);
+    3282             :         set_capacity (InlineCapacity);
+    3283             :       }
+    3284             :       else if (get_size () < other.get_size ())
+    3285             :       {
+    3286             :         // There are more elements in `other`.
+    3287             :         // Overwrite the existing range and uninitialized move the rest.
+    3288             :         ptr other_pivot = unchecked_next (other.begin_ptr (), get_size ());
+    3289             :         std::move (other.begin_ptr (), other_pivot, begin_ptr ());
+    3290             :         uninitialized_move (other_pivot, other.end_ptr (), end_ptr ());
+    3291             :       }
+    3292             :       else
+    3293             :       {
+    3294             :         // There are the same number or fewer elements in `other`.
+    3295             :         // Overwrite part of the existing range and destroy the rest.
+    3296             :         ptr new_end = std::move (other.begin_ptr (), other.end_ptr (), begin_ptr ());
+    3297             :         destroy_range (new_end, end_ptr ());
+    3298             :       }
+    3299             : 
+    3300             :       set_size (other.get_size ());
+    3301             : 
+    3302             :       // Note: We do not need to deallocate any allocations in `other` because the value of
+    3303             :       //       an object meeting the Allocator named requirements does not change value after
+    3304             :       //       a move.
+    3305             :     }
+    3306             : 
+    3307             :     alloc_interface::operator= (std::move (other));
+    3308             :     return *this;
+    3309             :   }
+    3310             : 
+    3311             :   template <unsigned GreaterI,
+    3312             :             typename std::enable_if<(InlineCapacity < GreaterI)>::type * = nullptr>
+    3313             :             PLUMED_GCH_CPP20_CONSTEXPR
+    3314             :             small_vector_base&
+    3315             :             move_assign_default (small_vector_base<Allocator, GreaterI>&& other)
+    3316             :   {
+    3317             :     if (other.has_allocation ())
+    3318             :       move_allocation_pointer (std::move (other));
+    3319             :     else if (get_capacity () < other.get_size ()
+    3320             :              ||  (has_allocation () && ! (other.allocator_ref () == allocator_ref ())))
+    3321             :     {
+    3322             :       // Reallocate.
+    3323             : 
+    3324             :       // The compiler should be able to optimize this.
+    3325             :       size_ty new_capacity =
+    3326             :         get_capacity () < other.get_size ()
+    3327             :         ? unchecked_calculate_new_capacity (other.get_size ())
+    3328             :         : get_capacity ();
+    3329             : 
+    3330             :       ptr new_data_ptr = other.allocate_with_hint (new_capacity, other.allocation_end_ptr ());
+    3331             : 
+    3332             :       PLUMED_GCH_TRY
+    3333             :       {
+    3334             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3335             :       }
+    3336             :       PLUMED_GCH_CATCH (...)
+    3337             :       {
+    3338             :         other.deallocate (new_data_ptr, new_capacity);
+    3339             :         PLUMED_GCH_THROW;
+    3340             :       }
+    3341             : 
+    3342             :       reset_data (new_data_ptr, new_capacity, other.get_size ());
+    3343             :     }
+    3344             :     else
+    3345             :     {
+    3346             :       if (get_size () < other.get_size ())
+    3347             :       {
+    3348             :         // There are more elements in `other`.
+    3349             :         // Overwrite the existing range and uninitialized move the rest.
+    3350             :         ptr other_pivot = unchecked_next (other.begin_ptr (), get_size ());
+    3351             :         std::move (other.begin_ptr (), other_pivot, begin_ptr ());
+    3352             :         uninitialized_move (other_pivot, other.end_ptr (), end_ptr ());
+    3353             :       }
+    3354             :       else
+    3355             :       {
+    3356             :         // fewer elements in other
+    3357             :         // overwrite part of the existing range and destroy the rest
+    3358             :         ptr new_end = std::move (other.begin_ptr (), other.end_ptr (), begin_ptr ());
+    3359             :         destroy_range (new_end, end_ptr ());
+    3360             :       }
+    3361             : 
+    3362             :       // `data_ptr` and `capacity` do not change in this case.
+    3363             :       set_size (other.get_size ());
+    3364             :     }
+    3365             : 
+    3366             :     alloc_interface::operator= (std::move (other));
+    3367             :     return *this;
+    3368             :   }
+    3369             : 
+    3370             :   template <unsigned I>
+    3371             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3372             :   small_vector_base&
+    3373             :   move_assign_unequal_no_propagate (small_vector_base<Allocator, I>&& other)
+    3374             :   {
+    3375             :     if (get_capacity () < other.get_size ())
+    3376             :     {
+    3377             :       // Reallocate.
+    3378             :       size_ty new_capacity = unchecked_calculate_new_capacity (other.get_size ());
+    3379             :       ptr     new_data_ptr = unchecked_allocate (new_capacity, other.allocation_end_ptr ());
+    3380             : 
+    3381             :       PLUMED_GCH_TRY
+    3382             :       {
+    3383             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    3384             :       }
+    3385             :       PLUMED_GCH_CATCH (...)
+    3386             :       {
+    3387             :         deallocate (new_data_ptr, new_capacity);
+    3388             :         PLUMED_GCH_THROW;
+    3389             :       }
+    3390             : 
+    3391             :       reset_data (new_data_ptr, new_capacity, other.get_size ());
+    3392             :     }
+    3393             :     else
+    3394             :     {
+    3395             :       if (get_size () < other.get_size ())
+    3396             :       {
+    3397             :         // There are more elements in `other`.
+    3398             :         // Overwrite the existing range and uninitialized move the rest.
+    3399             :         ptr other_pivot = unchecked_next (other.begin_ptr (), get_size ());
+    3400             :         std::move (other.begin_ptr (), other_pivot, begin_ptr ());
+    3401             :         uninitialized_move (other_pivot, other.end_ptr (), end_ptr ());
+    3402             :       }
+    3403             :       else
+    3404             :       {
+    3405             :         // There are fewer elements in `other`.
+    3406             :         // Overwrite part of the existing range and destroy the rest.
+    3407             :         destroy_range (
+    3408             :           std::move (other.begin_ptr (), other.end_ptr (), begin_ptr ()),
+    3409             :           end_ptr ());
+    3410             :       }
+    3411             : 
+    3412             :       // data_ptr and capacity do not change in this case
+    3413             :       set_size (other.get_size ());
+    3414             :     }
+    3415             : 
+    3416             :     alloc_interface::operator= (std::move (other));
+    3417             :     return *this;
+    3418             :   }
+    3419             : 
+    3420             :   template <unsigned I, typename A = alloc_ty,
+    3421             :             typename std::enable_if<allocations_are_movable<A>::value>::type * = nullptr>
+    3422             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3423             :   small_vector_base&
+    3424             :   move_assign (small_vector_base<Allocator, I>&& other)
+    3425             :   noexcept (noexcept (
+    3426             :               std::declval<small_vector_base&> ().move_assign_default (std::move (other))))
+    3427             :   {
+    3428             :     return move_assign_default (std::move (other));
+    3429             :   }
+    3430             : 
+    3431             :   template <unsigned I, typename A = alloc_ty,
+    3432             :             typename std::enable_if<! allocations_are_movable<A>::value>::type * = nullptr>
+    3433             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3434             :   small_vector_base&
+    3435             :   move_assign (small_vector_base<Allocator, I>&& other)
+    3436             :   {
+    3437             :     if (other.allocator_ref () == allocator_ref ())
+    3438             :       return move_assign_default (std::move (other));
+    3439             :     return move_assign_unequal_no_propagate (std::move (other));
+    3440             :   }
+    3441             : 
+    3442             :   template <unsigned I = InlineCapacity,
+    3443             :             typename std::enable_if<I == 0>::type * = nullptr>
+    3444             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3445             :   void
+    3446             :   move_initialize (small_vector_base&& other) noexcept
+    3447             :   {
+    3448             :     set_data (other.data_ptr (), other.get_capacity (), other.get_size ());
+    3449             :     other.set_default ();
+    3450             :   }
+    3451             : 
+    3452             :   template <unsigned LessEqualI,
+    3453             :             typename std::enable_if<(LessEqualI <= InlineCapacity)>::type * = nullptr>
+    3454             :             PLUMED_GCH_CPP20_CONSTEXPR
+    3455             :             void
+    3456             :             move_initialize (small_vector_base<Allocator, LessEqualI>&& other)
+    3457             :             noexcept (std::is_nothrow_move_constructible<value_ty>::value)
+    3458             :   {
+    3459             :     if (InlineCapacity < other.get_capacity ())
+    3460             :     {
+    3461             :       set_data (other.data_ptr (), other.get_capacity (), other.get_size ());
+    3462             :       other.set_default ();
+    3463             :     }
+    3464             :     else
+    3465             :     {
+    3466             :       set_to_inline_storage ();
+    3467             :       uninitialized_move (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3468             :       set_size (other.get_size ());
+    3469             :     }
+    3470             :   }
+    3471             : 
+    3472             :   template <unsigned GreaterI,
+    3473             :             typename std::enable_if<(InlineCapacity < GreaterI)>::type * = nullptr>
+    3474             :             PLUMED_GCH_CPP20_CONSTEXPR
+    3475             :             void
+    3476             :             move_initialize (small_vector_base<Allocator, GreaterI>&& other)
+    3477             :   {
+    3478             :     if (other.has_allocation ())
+    3479             :     {
+    3480             :       set_data (other.data_ptr (), other.get_capacity (), other.get_size ());
+    3481             :       other.set_default ();
+    3482             :     }
+    3483             :     else
+    3484             :     {
+    3485             :       if (InlineCapacity < other.get_size ())
+    3486             :       {
+    3487             :         // We may throw in this case.
+    3488             :         set_data_ptr (unchecked_allocate (other.get_size (), other.allocation_end_ptr ()));
+    3489             :         set_capacity (other.get_size ());
+    3490             : 
+    3491             :         PLUMED_GCH_TRY
+    3492             :         {
+    3493             :           uninitialized_move (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3494             :         }
+    3495             :         PLUMED_GCH_CATCH (...)
+    3496             :         {
+    3497             :           deallocate (data_ptr (), get_capacity ());
+    3498             :           PLUMED_GCH_THROW;
+    3499             :         }
+    3500             :       }
+    3501             :       else
+    3502             :       {
+    3503             :         set_to_inline_storage ();
+    3504             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3505             :       }
+    3506             : 
+    3507             :       set_size (other.get_size ());
+    3508             :     }
+    3509             :   }
+    3510             : 
+    3511             : public:
+    3512             : //    small_vector_base            (void)                         = impl;
+    3513             :   small_vector_base            (const small_vector_base&)     = delete;
+    3514             :   small_vector_base            (small_vector_base&&) noexcept = delete;
+    3515             :   small_vector_base& operator= (const small_vector_base&)     = delete;
+    3516             :   small_vector_base& operator= (small_vector_base&&) noexcept = delete;
+    3517             : //    ~small_vector_base           (void)                         = impl;
+    3518             : 
+    3519             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3520     1277523 :   small_vector_base (void) noexcept
+    3521             :   {
+    3522             :     set_default ();
+    3523             :   }
+    3524             : 
+    3525             :   static constexpr struct bypass_tag { } bypass { };
+    3526             : 
+    3527             :   template <unsigned I, typename ...MaybeAlloc>
+    3528             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3529             :   small_vector_base (bypass_tag,
+    3530             :                      const small_vector_base<Allocator, I>& other,
+    3531             :                      const MaybeAlloc&... alloc)
+    3532             :     : alloc_interface (other, alloc...)
+    3533             :   {
+    3534             :     if (InlineCapacity < other.get_size ())
+    3535             :     {
+    3536             :       set_data_ptr (unchecked_allocate (other.get_size (), other.allocation_end_ptr ()));
+    3537             :       set_capacity (other.get_size ());
+    3538             : 
+    3539             :       PLUMED_GCH_TRY
+    3540             :       {
+    3541             :         uninitialized_copy (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3542             :       }
+    3543             :       PLUMED_GCH_CATCH (...)
+    3544             :       {
+    3545             :         deallocate (data_ptr (), get_capacity ());
+    3546             :         PLUMED_GCH_THROW;
+    3547             :       }
+    3548             :     }
+    3549             :     else
+    3550             :     {
+    3551             :       set_to_inline_storage ();
+    3552             :       uninitialized_copy (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3553             :     }
+    3554             : 
+    3555             :     set_size (other.get_size ());
+    3556             :   }
+    3557             : 
+    3558             :   template <unsigned I>
+    3559             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3560             :   small_vector_base (bypass_tag, small_vector_base<Allocator, I>&& other)
+    3561             :   noexcept (std::is_nothrow_move_constructible<value_ty>::value
+    3562             :             ||  (I == 0 && I == InlineCapacity))
+    3563             :     : alloc_interface (std::move (other))
+    3564             :   {
+    3565             :     move_initialize (std::move (other));
+    3566             :   }
+    3567             : 
+    3568             :   template <unsigned I, typename A = alloc_ty,
+    3569             :             typename std::enable_if<std::is_same<std::allocator<value_ty>, A>::value
+    3570             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    3571             :                                     ||  std::allocator_traits<A>::is_always_equal::value
+    3572             : #endif
+    3573             :                                     >::type * = nullptr>
+    3574             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3575             :   small_vector_base (bypass_tag, small_vector_base<Allocator, I>&& other, const alloc_ty&)
+    3576             :   noexcept (noexcept (small_vector_base (bypass, std::move (other))))
+    3577             :     : small_vector_base (bypass, std::move (other))
+    3578             :   { }
+    3579             : 
+    3580             :   template <unsigned I, typename A = alloc_ty,
+    3581             :             typename std::enable_if<! (std::is_same<std::allocator<value_ty>, A>::value
+    3582             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    3583             :                                        ||  std::allocator_traits<A>::is_always_equal::value
+    3584             : #endif
+    3585             :                                                                 )>::type * = nullptr>
+    3586             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3587             :   small_vector_base (bypass_tag, small_vector_base<Allocator, I>&& other, const alloc_ty& alloc)
+    3588             :     : alloc_interface (alloc)
+    3589             :   {
+    3590             :     if (other.allocator_ref () == alloc)
+    3591             :     {
+    3592             :       move_initialize (std::move (other));
+    3593             :       return;
+    3594             :     }
+    3595             : 
+    3596             :     if (InlineCapacity < other.get_size ())
+    3597             :     {
+    3598             :       // We may throw in this case.
+    3599             :       set_data_ptr (unchecked_allocate (other.get_size (), other.allocation_end_ptr ()));
+    3600             :       set_capacity (other.get_size ());
+    3601             : 
+    3602             :       PLUMED_GCH_TRY
+    3603             :       {
+    3604             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3605             :       }
+    3606             :       PLUMED_GCH_CATCH (...)
+    3607             :       {
+    3608             :         deallocate (data_ptr (), get_capacity ());
+    3609             :         PLUMED_GCH_THROW;
+    3610             :       }
+    3611             :     }
+    3612             :     else
+    3613             :     {
+    3614             :       set_to_inline_storage ();
+    3615             :       uninitialized_move (other.begin_ptr (), other.end_ptr (), data_ptr ());
+    3616             :     }
+    3617             : 
+    3618             :     set_size (other.get_size ());
+    3619             :   }
+    3620             : 
+    3621             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    3622             :   small_vector_base (const alloc_ty& alloc) noexcept
+    3623             :     : alloc_interface (alloc)
+    3624             :   {
+    3625             :     set_default ();
+    3626             :   }
+    3627             : 
+    3628             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3629             :   small_vector_base (size_ty count, const alloc_ty& alloc)
+    3630             :     : alloc_interface (alloc)
+    3631             :   {
+    3632             :     if (InlineCapacity < count)
+    3633             :     {
+    3634             :       set_data_ptr (checked_allocate (count));
+    3635             :       set_capacity (count);
+    3636             :     }
+    3637             :     else
+    3638             :       set_to_inline_storage ();
+    3639             : 
+    3640             :     PLUMED_GCH_TRY
+    3641             :     {
+    3642             :       uninitialized_value_construct (begin_ptr (), unchecked_next (begin_ptr (), count));
+    3643             :     }
+    3644             :     PLUMED_GCH_CATCH (...)
+    3645             :     {
+    3646             :       if (has_allocation ())
+    3647             :         deallocate (data_ptr (), get_capacity ());
+    3648             :       PLUMED_GCH_THROW;
+    3649             :     }
+    3650             :     set_size (count);
+    3651             :   }
+    3652             : 
+    3653             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3654             :   small_vector_base (size_ty count, const value_ty& val, const alloc_ty& alloc)
+    3655             :     : alloc_interface (alloc)
+    3656             :   {
+    3657             :     if (InlineCapacity < count)
+    3658             :     {
+    3659             :       set_data_ptr (checked_allocate (count));
+    3660             :       set_capacity (count);
+    3661             :     }
+    3662             :     else
+    3663             :       set_to_inline_storage ();
+    3664             : 
+    3665             :     PLUMED_GCH_TRY
+    3666             :     {
+    3667             :       uninitialized_fill (begin_ptr (), unchecked_next (begin_ptr (), count), val);
+    3668             :     }
+    3669             :     PLUMED_GCH_CATCH (...)
+    3670             :     {
+    3671             :       if (has_allocation ())
+    3672             :         deallocate (data_ptr (), get_capacity ());
+    3673             :       PLUMED_GCH_THROW;
+    3674             :     }
+    3675             :     set_size (count);
+    3676             :   }
+    3677             : 
+    3678             :   template <typename Generator>
+    3679             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3680             :   small_vector_base (size_ty count, Generator& g, const alloc_ty& alloc)
+    3681             :     : alloc_interface (alloc)
+    3682             :   {
+    3683             :     if (InlineCapacity < count)
+    3684             :     {
+    3685             :       set_data_ptr (checked_allocate (count));
+    3686             :       set_capacity (count);
+    3687             :     }
+    3688             :     else
+    3689             :       set_to_inline_storage ();
+    3690             : 
+    3691             :     ptr curr = begin_ptr ();
+    3692             :     const ptr new_end = unchecked_next (begin_ptr (), count);
+    3693             :     PLUMED_GCH_TRY
+    3694             :     {
+    3695             :       for (; ! (curr == new_end); ++curr)
+    3696             :         construct (curr, g ());
+    3697             :     }
+    3698             :     PLUMED_GCH_CATCH (...)
+    3699             :     {
+    3700             :       destroy_range (begin_ptr (), curr);
+    3701             :       if (has_allocation ())
+    3702             :         deallocate (data_ptr (), get_capacity ());
+    3703             :       PLUMED_GCH_THROW;
+    3704             :     }
+    3705             :     set_size (count);
+    3706             :   }
+    3707             : 
+    3708             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    3709             :   template <std::input_iterator InputIt>
+    3710             : #else
+    3711             :   template <typename InputIt>
+    3712             : #endif
+    3713             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3714             :   small_vector_base (InputIt first, InputIt last, std::input_iterator_tag,
+    3715             :                      const alloc_ty& alloc)
+    3716             :     : small_vector_base (alloc)
+    3717             :   {
+    3718             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    3719             :     append_range (first, last, iterator_cat { });
+    3720             :   }
+    3721             : 
+    3722             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    3723             :   template <std::forward_iterator ForwardIt>
+    3724             : #else
+    3725             :   template <typename ForwardIt>
+    3726             : #endif
+    3727             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3728             :   small_vector_base (ForwardIt first, ForwardIt last, std::forward_iterator_tag,
+    3729             :                      const alloc_ty& alloc)
+    3730             :     : alloc_interface (alloc)
+    3731             :   {
+    3732             :     size_ty count = external_range_length (first, last);
+    3733             :     if (InlineCapacity < count)
+    3734             :     {
+    3735             :       set_data_ptr (unchecked_allocate (count));
+    3736             :       set_capacity (count);
+    3737             :       PLUMED_GCH_TRY
+    3738             :       {
+    3739             :         uninitialized_copy (first, last, begin_ptr ());
+    3740             :       }
+    3741             :       PLUMED_GCH_CATCH (...)
+    3742             :       {
+    3743             :         deallocate (data_ptr (), get_capacity ());
+    3744             :         PLUMED_GCH_THROW;
+    3745             :       }
+    3746             :     }
+    3747             :     else
+    3748             :     {
+    3749             :       set_to_inline_storage ();
+    3750             :       uninitialized_copy (first, last, begin_ptr ());
+    3751             :     }
+    3752             : 
+    3753             :     set_size (count);
+    3754             :   }
+    3755             : 
+    3756             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3757             :   ~small_vector_base (void) noexcept
+    3758             :   {
+    3759             :     assert (InlineCapacity <= get_capacity () && "Invalid capacity.");
+    3760     1134787 :     wipe ();
+    3761             :   }
+    3762             : 
+    3763             : protected:
+    3764             : 
+    3765             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3766             :   void
+    3767             :   set_to_inline_storage (void)
+    3768             :   {
+    3769             :     set_capacity (InlineCapacity);
+    3770             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    3771             :     if (std::is_constant_evaluated ())
+    3772             :       return set_data_ptr (alloc_interface::allocate (InlineCapacity));
+    3773             : #endif
+    3774             :     set_data_ptr (storage_ptr ());
+    3775             :   }
+    3776             : 
+    3777             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3778             :   void
+    3779             :   assign_with_copies (size_ty count, const value_ty& val)
+    3780             :   {
+    3781             :     if (get_capacity () < count)
+    3782             :     {
+    3783             :       size_ty new_capacity = checked_calculate_new_capacity (count);
+    3784             :       ptr     new_begin    = unchecked_allocate (new_capacity);
+    3785             : 
+    3786             :       PLUMED_GCH_TRY
+    3787             :       {
+    3788             :         uninitialized_fill (new_begin, unchecked_next (new_begin, count), val);
+    3789             :       }
+    3790             :       PLUMED_GCH_CATCH (...)
+    3791             :       {
+    3792             :         deallocate (new_begin, new_capacity);
+    3793             :         PLUMED_GCH_THROW;
+    3794             :       }
+    3795             : 
+    3796             :       reset_data (new_begin, new_capacity, count);
+    3797             :     }
+    3798             :     else if (get_size () < count)
+    3799             :     {
+    3800             :       std::fill (begin_ptr (), end_ptr (), val);
+    3801             :       uninitialized_fill (end_ptr (), unchecked_next (begin_ptr (), count), val);
+    3802             :       set_size (count);
+    3803             :     }
+    3804             :     else
+    3805             :       erase_range (std::fill_n (begin_ptr (), count, val), end_ptr ());
+    3806             :   }
+    3807             : 
+    3808             :   template <typename InputIt,
+    3809             :             typename std::enable_if<std::is_assignable<
+    3810             :                                       value_ty&,
+    3811             :                                       decltype (*std::declval<InputIt> ())>::value>::type * = nullptr>
+    3812             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3813             :   void
+    3814             :   assign_with_range (InputIt first, InputIt last, std::input_iterator_tag)
+    3815             :   {
+    3816             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    3817             : 
+    3818             :     ptr curr = begin_ptr ();
+    3819             :     for (; ! (end_ptr () == curr || first == last); ++curr, static_cast<void> (++first))
+    3820             :       *curr = *first;
+    3821             : 
+    3822             :     if (first == last)
+    3823             :       erase_to_end (curr);
+    3824             :     else
+    3825             :       append_range (first, last, iterator_cat { });
+    3826             :   }
+    3827             : 
+    3828             :   template <typename ForwardIt,
+    3829             :             typename std::enable_if<std::is_assignable<
+    3830             :                                       value_ty&,
+    3831             :                                       decltype (*std::declval<ForwardIt> ())>::value>::type * = nullptr>
+    3832             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3833             :   void
+    3834             :   assign_with_range (ForwardIt first, ForwardIt last, std::forward_iterator_tag)
+    3835             :   {
+    3836             :     const size_ty count = external_range_length (first, last);
+    3837             :     if (get_capacity () < count)
+    3838             :     {
+    3839             :       size_ty new_capacity = checked_calculate_new_capacity (count);
+    3840             :       ptr     new_begin    = unchecked_allocate (new_capacity);
+    3841             : 
+    3842             :       PLUMED_GCH_TRY
+    3843             :       {
+    3844             :         uninitialized_copy (first, last, new_begin);
+    3845             :       }
+    3846             :       PLUMED_GCH_CATCH (...)
+    3847             :       {
+    3848             :         deallocate (new_begin, new_capacity);
+    3849             :         PLUMED_GCH_THROW;
+    3850             :       }
+    3851             : 
+    3852             :       reset_data (new_begin, new_capacity, count);
+    3853             :     }
+    3854             :     else if (get_size () < count)
+    3855             :     {
+    3856             :       ForwardIt pivot = copy_n_return_in (first, get_size (), begin_ptr ());
+    3857             :       uninitialized_copy (pivot, last, end_ptr ());
+    3858             :       set_size (count);
+    3859             :     }
+    3860             :     else
+    3861             :       erase_range (copy_range (first, last, begin_ptr ()), end_ptr ());
+    3862             :   }
+    3863             : 
+    3864             :   template <typename InputIt,
+    3865             :             typename std::enable_if<! std::is_assignable<
+    3866             :                                       value_ty&,
+    3867             :                                       decltype (*std::declval<InputIt> ())>::value>::type * = nullptr>
+    3868             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3869             :   void
+    3870             :   assign_with_range (InputIt first, InputIt last, std::input_iterator_tag)
+    3871             :   {
+    3872             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    3873             : 
+    3874             :     // If not assignable then destroy all elements and append.
+    3875             :     erase_all ();
+    3876             :     append_range (first, last, iterator_cat { });
+    3877             :   }
+    3878             : 
+    3879             :   // Ie. move-if-noexcept.
+    3880             :   struct strong_exception_policy
+    3881             :   { };
+    3882             : 
+    3883             :   template <typename Policy = void, typename V = value_ty,
+    3884             :             typename std::enable_if<is_explicitly_move_insertable<V>::value
+    3885             :                                     &&  (! std::is_same<Policy, strong_exception_policy>::value
+    3886             :                                          ||  relocate_with_move<V>::value),
+    3887             :                                     bool>::type = true>
+    3888             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3889             :   ptr
+    3890             :   uninitialized_move (ptr first, ptr last, ptr d_first)
+    3891             :   noexcept (std::is_nothrow_move_constructible<value_ty>::value)
+    3892             :   {
+    3893             :     return uninitialized_copy (std::make_move_iterator (first),
+    3894             :                                std::make_move_iterator (last),
+    3895             :                                d_first);
+    3896             :   }
+    3897             : 
+    3898             :   template <typename Policy = void, typename V = value_ty,
+    3899             :             typename std::enable_if<! is_explicitly_move_insertable<V>::value
+    3900             :                                     ||  (  std::is_same<Policy, strong_exception_policy>::value
+    3901             :                                         &&! relocate_with_move<V>::value),
+    3902             :                                     bool>::type = false>
+    3903             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3904             :   ptr
+    3905             :   uninitialized_move (ptr first, ptr last, ptr d_first)
+    3906             :   noexcept (alloc_interface::template is_uninitialized_memcpyable_iterator<ptr>::value)
+    3907             :   {
+    3908             :     return uninitialized_copy (first, last, d_first);
+    3909             :   }
+    3910             : 
+    3911             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3912             :   ptr
+    3913             :   shift_into_uninitialized (ptr pos, size_ty n_shift)
+    3914             :   {
+    3915             :     // Shift elements over to the right into uninitialized space.
+    3916             :     // Returns the start of the shifted range.
+    3917             :     // Precondition: shift < end_ptr () - pos
+    3918             :     assert (n_shift != 0 && "The value of `n_shift` should not be 0.");
+    3919             : 
+    3920             :     const ptr original_end = end_ptr ();
+    3921             :     const ptr pivot        = unchecked_prev (original_end, n_shift);
+    3922             : 
+    3923             :     uninitialized_move (pivot, original_end, original_end);
+    3924             :     increase_size (n_shift);
+    3925             :     return move_right (pos, pivot, original_end);
+    3926             :   }
+    3927             : 
+    3928             :   template <typename ...Args>
+    3929             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3930             :   ptr
+    3931     1622573 :   append_element (Args&&... args)
+    3932             :   {
+    3933     1622573 :     if (get_size () < get_capacity ())
+    3934     1622401 :           return emplace_into_current_end (std::forward<Args> (args)...);
+    3935         172 :     return emplace_into_reallocation_end (std::forward<Args> (args)...);
+    3936             :   }
+    3937             : 
+    3938             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3939             :   ptr
+    3940             :   append_copies (size_ty count, const value_ty& val)
+    3941             :   {
+    3942             :     if (num_uninitialized () < count)
+    3943             :     {
+    3944             :       // Reallocate.
+    3945             :       if (get_max_size () - get_size () < count)
+    3946             :         throw_allocation_size_error ();
+    3947             : 
+    3948             :       size_ty original_size = get_size ();
+    3949             :       size_ty new_size      = get_size () + count;
+    3950             : 
+    3951             :       // The check is handled by the if-guard.
+    3952             :       size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    3953             :       ptr     new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    3954             :       ptr     new_last     = unchecked_next (new_data_ptr, original_size);
+    3955             : 
+    3956             :       PLUMED_GCH_TRY
+    3957             :       {
+    3958             :         new_last = uninitialized_fill (new_last, unchecked_next (new_last, count), val);
+    3959             :         uninitialized_move (begin_ptr (), end_ptr (), new_data_ptr);
+    3960             :       }
+    3961             :       PLUMED_GCH_CATCH (...)
+    3962             :       {
+    3963             :         destroy_range (unchecked_next (new_data_ptr, original_size), new_last);
+    3964             :         deallocate (new_data_ptr, new_capacity);
+    3965             :         PLUMED_GCH_THROW;
+    3966             :       }
+    3967             : 
+    3968             :       reset_data (new_data_ptr, new_capacity, new_size);
+    3969             :       return unchecked_next (new_data_ptr, original_size);
+    3970             :     }
+    3971             :     else
+    3972             :     {
+    3973             :       const ptr ret = end_ptr ();
+    3974             :       uninitialized_fill (ret, unchecked_next (ret, count), val);
+    3975             :       increase_size (count);
+    3976             :       return ret;
+    3977             :     }
+    3978             :   }
+    3979             : 
+    3980             :   template <typename MovePolicy, typename InputIt,
+    3981             :             typename std::enable_if<
+    3982             :               std::is_same<MovePolicy, strong_exception_policy>::value, bool>::type = true>
+    3983             :   PLUMED_GCH_CPP20_CONSTEXPR
+    3984             :   ptr
+    3985             :   append_range (InputIt first, InputIt last, std::input_iterator_tag)
+    3986             :   {
+    3987             :     // Append with a strong exception guarantee.
+    3988             :     size_ty original_size = get_size ();
+    3989             :     for (; ! (first == last); ++first)
+    3990             :     {
+    3991             :       PLUMED_GCH_TRY
+    3992             :       {
+    3993             :         append_element (*first);
+    3994             :       }
+    3995             :       PLUMED_GCH_CATCH (...)
+    3996             :       {
+    3997             :         erase_range (unchecked_next (begin_ptr (), original_size), end_ptr ());
+    3998             :         PLUMED_GCH_THROW;
+    3999             :       }
+    4000             :     }
+    4001             :     return unchecked_next (begin_ptr (), original_size);
+    4002             :   }
+    4003             : 
+    4004             :   template <typename MovePolicy = void, typename InputIt,
+    4005             :             typename std::enable_if<
+    4006             :               ! std::is_same<MovePolicy, strong_exception_policy>::value, bool>::type = false>
+    4007             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4008             :   ptr
+    4009             :   append_range (InputIt first, InputIt last, std::input_iterator_tag)
+    4010             :   {
+    4011             :     size_ty original_size = get_size ();
+    4012             :     for (; ! (first == last); ++first)
+    4013             :       append_element (*first);
+    4014             :     return unchecked_next (begin_ptr (), original_size);
+    4015             :   }
+    4016             : 
+    4017             :   template <typename MovePolicy = void, typename ForwardIt>
+    4018             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4019             :   ptr
+    4020             :   append_range (ForwardIt first, ForwardIt last, std::forward_iterator_tag)
+    4021             :   {
+    4022             :     const size_ty num_insert = external_range_length (first, last);
+    4023             : 
+    4024             :     if (num_uninitialized () < num_insert)
+    4025             :     {
+    4026             :       // Reallocate.
+    4027             :       if (get_max_size () - get_size () < num_insert)
+    4028             :         throw_allocation_size_error ();
+    4029             : 
+    4030             :       size_ty original_size = get_size ();
+    4031             :       size_ty new_size      = get_size () + num_insert;
+    4032             : 
+    4033             :       // The check is handled by the if-guard.
+    4034             :       size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4035             :       ptr     new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4036             :       ptr     new_last     = unchecked_next (new_data_ptr, original_size);
+    4037             : 
+    4038             :       PLUMED_GCH_TRY
+    4039             :       {
+    4040             :         new_last = uninitialized_copy (first, last, new_last);
+    4041             :         uninitialized_move<MovePolicy> (begin_ptr (), end_ptr (), new_data_ptr);
+    4042             :       }
+    4043             :       PLUMED_GCH_CATCH (...)
+    4044             :       {
+    4045             :         destroy_range (unchecked_next (new_data_ptr, original_size), new_last);
+    4046             :         deallocate (new_data_ptr, new_capacity);
+    4047             :         PLUMED_GCH_THROW;
+    4048             :       }
+    4049             : 
+    4050             :       reset_data (new_data_ptr, new_capacity, new_size);
+    4051             :       return unchecked_next (new_data_ptr, original_size);
+    4052             :     }
+    4053             :     else
+    4054             :     {
+    4055             :       ptr ret = end_ptr ();
+    4056             :       uninitialized_copy (first, last, ret);
+    4057             :       increase_size (num_insert);
+    4058             :       return ret;
+    4059             :     }
+    4060             :   }
+    4061             : 
+    4062             :   template <typename ...Args>
+    4063             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4064             :   ptr
+    4065             :   emplace_at (ptr pos, Args&&... args)
+    4066             :   {
+    4067             :     assert (get_size () <= get_capacity () && "size was greater than capacity");
+    4068             : 
+    4069             :     if (get_size () < get_capacity ())
+    4070             :       return emplace_into_current (pos, std::forward<Args> (args)...);
+    4071             :     return emplace_into_reallocation (pos, std::forward<Args> (args)...);
+    4072             :   }
+    4073             : 
+    4074             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4075             :   ptr
+    4076             :   insert_copies (ptr pos, size_ty count, const value_ty& val)
+    4077             :   {
+    4078             :     if (0 == count)
+    4079             :       return pos;
+    4080             : 
+    4081             :     if (end_ptr () == pos)
+    4082             :     {
+    4083             :       if (1 == count)
+    4084             :         return append_element (val);
+    4085             :       return append_copies (count, val);
+    4086             :     }
+    4087             : 
+    4088             :     if (num_uninitialized () < count)
+    4089             :     {
+    4090             :       // Reallocate.
+    4091             :       if (get_max_size () - get_size () < count)
+    4092             :         throw_allocation_size_error ();
+    4093             : 
+    4094             :       const size_ty offset = internal_range_length (begin_ptr (), pos);
+    4095             : 
+    4096             :       const size_ty new_size = get_size () + count;
+    4097             : 
+    4098             :       // The check is handled by the if-guard.
+    4099             :       const size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4100             :       ptr new_data_ptr           = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4101             :       ptr new_first              = unchecked_next (new_data_ptr, offset);
+    4102             :       ptr new_last               = new_first;
+    4103             : 
+    4104             :       PLUMED_GCH_TRY
+    4105             :       {
+    4106             :         uninitialized_fill (new_first, unchecked_next (new_first, count), val);
+    4107             :         unchecked_advance  (new_last, count);
+    4108             : 
+    4109             :         uninitialized_move (begin_ptr (), pos, new_data_ptr);
+    4110             :         new_first = new_data_ptr;
+    4111             :         uninitialized_move (pos, end_ptr (), new_last);
+    4112             :       }
+    4113             :       PLUMED_GCH_CATCH (...)
+    4114             :       {
+    4115             :         destroy_range (new_first, new_last);
+    4116             :         deallocate (new_data_ptr, new_capacity);
+    4117             :         PLUMED_GCH_THROW;
+    4118             :       }
+    4119             : 
+    4120             :       reset_data (new_data_ptr, new_capacity, new_size);
+    4121             :       return unchecked_next (begin_ptr (), offset);
+    4122             :     }
+    4123             :     else
+    4124             :     {
+    4125             :       // If we have fewer to insert than tailing elements after `pos`, we shift into
+    4126             :       // uninitialized and then copy over.
+    4127             : 
+    4128             :       const size_ty tail_size = internal_range_length (pos, end_ptr ());
+    4129             :       if (tail_size < count)
+    4130             :       {
+    4131             :         // The number inserted is larger than the number after `pos`,
+    4132             :         // so part of the input will be used to construct new elements,
+    4133             :         // and another part of it will assign existing ones.
+    4134             :         // In order:
+    4135             :         //   Construct new elements immediately after end_ptr () using the input.
+    4136             :         //   Move-construct existing elements over to the tail.
+    4137             :         //   Assign existing elements using the input.
+    4138             : 
+    4139             :         ptr original_end = end_ptr ();
+    4140             : 
+    4141             :         // Place a portion of the input into the uninitialized section.
+    4142             :         size_ty num_val_tail = count - tail_size;
+    4143             : 
+    4144             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4145             :         if (std::is_constant_evaluated ())
+    4146             :         {
+    4147             :           uninitialized_fill (end_ptr (), unchecked_next (end_ptr (), num_val_tail), val);
+    4148             :           increase_size (num_val_tail);
+    4149             : 
+    4150             :           const heap_temporary tmp (*this, val);
+    4151             : 
+    4152             :           uninitialized_move (pos, original_end, end_ptr ());
+    4153             :           increase_size (tail_size);
+    4154             : 
+    4155             :           std::fill_n (pos, tail_size, tmp.get ());
+    4156             : 
+    4157             :           return pos;
+    4158             :         }
+    4159             : #endif
+    4160             : 
+    4161             :         uninitialized_fill (end_ptr (), unchecked_next (end_ptr (), num_val_tail), val);
+    4162             :         increase_size (num_val_tail);
+    4163             : 
+    4164             :         PLUMED_GCH_TRY
+    4165             :         {
+    4166             :           // We need to handle possible aliasing here.
+    4167             :           const stack_temporary tmp (*this, val);
+    4168             : 
+    4169             :           // Now, move the tail to the end.
+    4170             :           uninitialized_move (pos, original_end, end_ptr ());
+    4171             :           increase_size (tail_size);
+    4172             : 
+    4173             :           PLUMED_GCH_TRY
+    4174             :           {
+    4175             :             // Finally, try to copy the rest of the elements over.
+    4176             :             std::fill_n (pos, tail_size, tmp.get ());
+    4177             :           }
+    4178             :           PLUMED_GCH_CATCH (...)
+    4179             :           {
+    4180             :             // Attempt to roll back and destroy the tail if we fail.
+    4181             :             ptr inserted_end = unchecked_prev (end_ptr (), tail_size);
+    4182             :             move_left (inserted_end, end_ptr (), pos);
+    4183             :             destroy_range (inserted_end, end_ptr ());
+    4184             :             decrease_size (tail_size);
+    4185             :             PLUMED_GCH_THROW;
+    4186             :           }
+    4187             :         }
+    4188             :         PLUMED_GCH_CATCH (...)
+    4189             :         {
+    4190             :           // Destroy the elements constructed from the input.
+    4191             :           destroy_range (original_end, end_ptr ());
+    4192             :           decrease_size (internal_range_length (original_end, end_ptr ()));
+    4193             :           PLUMED_GCH_THROW;
+    4194             :         }
+    4195             :       }
+    4196             :       else
+    4197             :       {
+    4198             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4199             :         if (std::is_constant_evaluated ())
+    4200             :         {
+    4201             :           const heap_temporary tmp (*this, val);
+    4202             : 
+    4203             :           ptr inserted_end = shift_into_uninitialized (pos, count);
+    4204             :           std::fill (pos, inserted_end, tmp.get ());
+    4205             : 
+    4206             :           return pos;
+    4207             :         }
+    4208             : #endif
+    4209             :         const stack_temporary tmp (*this, val);
+    4210             : 
+    4211             :         ptr inserted_end = shift_into_uninitialized (pos, count);
+    4212             : 
+    4213             :         // Attempt to copy over the elements.
+    4214             :         // If we fail we'll attempt a full roll-back.
+    4215             :         PLUMED_GCH_TRY
+    4216             :         {
+    4217             :           std::fill (pos, inserted_end, tmp.get ());
+    4218             :         }
+    4219             :         PLUMED_GCH_CATCH (...)
+    4220             :         {
+    4221             :           ptr original_end = move_left (inserted_end, end_ptr (), pos);
+    4222             :           destroy_range (original_end, end_ptr ());
+    4223             :           decrease_size (count);
+    4224             :           PLUMED_GCH_THROW;
+    4225             :         }
+    4226             :       }
+    4227             :       return pos;
+    4228             :     }
+    4229             :   }
+    4230             : 
+    4231             :   template <typename ForwardIt>
+    4232             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4233             :   ptr
+    4234             :   insert_range_helper (ptr pos, ForwardIt first, ForwardIt last)
+    4235             :   {
+    4236             :     assert (! (first == last) && "The range should not be empty.");
+    4237             :     assert (! (end_ptr () == pos) && "`pos` should not be at the end.");
+    4238             : 
+    4239             :     const size_ty num_insert = external_range_length (first, last);
+    4240             :     if (num_uninitialized () < num_insert)
+    4241             :     {
+    4242             :       // Reallocate.
+    4243             :       if (get_max_size () - get_size () < num_insert)
+    4244             :         throw_allocation_size_error ();
+    4245             : 
+    4246             :       const size_ty offset   = internal_range_length (begin_ptr (), pos);
+    4247             :       const size_ty new_size = get_size () + num_insert;
+    4248             : 
+    4249             :       // The check is handled by the if-guard.
+    4250             :       const size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4251             :       const ptr     new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4252             :       ptr           new_first    = unchecked_next (new_data_ptr, offset);
+    4253             :       ptr           new_last     = new_first;
+    4254             : 
+    4255             :       PLUMED_GCH_TRY
+    4256             :       {
+    4257             :         uninitialized_copy (first, last, new_first);
+    4258             :         unchecked_advance  (new_last, num_insert);
+    4259             : 
+    4260             :         uninitialized_move (begin_ptr (), pos, new_data_ptr);
+    4261             :         new_first = new_data_ptr;
+    4262             :         uninitialized_move (pos, end_ptr (), new_last);
+    4263             :       }
+    4264             :       PLUMED_GCH_CATCH (...)
+    4265             :       {
+    4266             :         destroy_range (new_first, new_last);
+    4267             :         deallocate (new_data_ptr, new_capacity);
+    4268             :         PLUMED_GCH_THROW;
+    4269             :       }
+    4270             : 
+    4271             :       reset_data (new_data_ptr, new_capacity, new_size);
+    4272             :       return unchecked_next (begin_ptr (), offset);
+    4273             :     }
+    4274             :     else
+    4275             :     {
+    4276             :       // if we have fewer to insert than tailing elements after
+    4277             :       // `pos` we shift into uninitialized and then copy over
+    4278             :       const size_ty tail_size = internal_range_length (pos, end_ptr ());
+    4279             :       if (tail_size < num_insert)
+    4280             :       {
+    4281             :         // Use the same method as insert_copies.
+    4282             :         ptr original_end = end_ptr ();
+    4283             :         ForwardIt pivot  = unchecked_next (first, tail_size);
+    4284             : 
+    4285             :         // Place a portion of the input into the uninitialized section.
+    4286             :         uninitialized_copy (pivot, last, end_ptr ());
+    4287             :         increase_size (num_insert - tail_size);
+    4288             : 
+    4289             :         PLUMED_GCH_TRY
+    4290             :         {
+    4291             :           // Now move the tail to the end.
+    4292             :           uninitialized_move (pos, original_end, end_ptr ());
+    4293             :           increase_size (tail_size);
+    4294             : 
+    4295             :           PLUMED_GCH_TRY
+    4296             :           {
+    4297             :             // Finally, try to copy the rest of the elements over.
+    4298             :             copy_range (first, pivot, pos);
+    4299             :           }
+    4300             :           PLUMED_GCH_CATCH (...)
+    4301             :           {
+    4302             :             // Attempt to roll back and destroy the tail if we fail.
+    4303             :             ptr inserted_end = unchecked_prev (end_ptr (), tail_size);
+    4304             :             move_left (inserted_end, end_ptr (), pos);
+    4305             :             destroy_range (inserted_end, end_ptr ());
+    4306             :             decrease_size (tail_size);
+    4307             :             PLUMED_GCH_THROW;
+    4308             :           }
+    4309             :         }
+    4310             :         PLUMED_GCH_CATCH (...)
+    4311             :         {
+    4312             :           // If we throw, destroy the first copy we made.
+    4313             :           destroy_range (original_end, end_ptr ());
+    4314             :           decrease_size (internal_range_length (original_end, end_ptr ()));
+    4315             :           PLUMED_GCH_THROW;
+    4316             :         }
+    4317             :       }
+    4318             :       else
+    4319             :       {
+    4320             :         shift_into_uninitialized (pos, num_insert);
+    4321             : 
+    4322             :         // Attempt to copy over the elements.
+    4323             :         // If we fail we'll attempt a full roll-back.
+    4324             :         PLUMED_GCH_TRY
+    4325             :         {
+    4326             :           copy_range (first, last, pos);
+    4327             :         }
+    4328             :         PLUMED_GCH_CATCH (...)
+    4329             :         {
+    4330             :           ptr inserted_end = unchecked_next (pos, num_insert);
+    4331             :           ptr original_end = move_left (inserted_end, end_ptr (), pos);
+    4332             :           destroy_range (original_end, end_ptr ());
+    4333             :           decrease_size (num_insert);
+    4334             :           PLUMED_GCH_THROW;
+    4335             :         }
+    4336             :       }
+    4337             :       return pos;
+    4338             :     }
+    4339             :   }
+    4340             : 
+    4341             :   template <typename InputIt>
+    4342             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4343             :   ptr
+    4344             :   insert_range (ptr pos, InputIt first, InputIt last, std::input_iterator_tag)
+    4345             :   {
+    4346             :     assert (! (first == last) && "The range should not be empty.");
+    4347             : 
+    4348             :     // Ensure we use this specific overload to give a strong exception guarantee for 1 element.
+    4349             :     if (end_ptr () == pos)
+    4350             :       return append_range (first, last, std::input_iterator_tag { });
+    4351             : 
+    4352             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    4353             :     small_vector_base tmp (first, last, iterator_cat { }, allocator_ref ());
+    4354             : 
+    4355             :     return insert_range_helper (
+    4356             :              pos,
+    4357             :              std::make_move_iterator (tmp.begin_ptr ()),
+    4358             :              std::make_move_iterator (tmp.end_ptr ()));
+    4359             :   }
+    4360             : 
+    4361             :   template <typename ForwardIt>
+    4362             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4363             :   ptr
+    4364             :   insert_range (ptr pos, ForwardIt first, ForwardIt last, std::forward_iterator_tag)
+    4365             :   {
+    4366             :     if (! (end_ptr () == pos))
+    4367             :       return insert_range_helper (pos, first, last);
+    4368             : 
+    4369             :     if (unchecked_next (first) == last)
+    4370             :       return append_element (*first);
+    4371             : 
+    4372             :     using iterator_cat = typename std::iterator_traits<ForwardIt>::iterator_category;
+    4373             :     return append_range (first, last, iterator_cat { });
+    4374             :   }
+    4375             : 
+    4376             :   template <typename ...Args>
+    4377             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4378             :   ptr
+    4379     1622401 :   emplace_into_current_end (Args&&... args)
+    4380             :   {
+    4381     1622401 :     construct (end_ptr (), std::forward<Args> (args)...);
+    4382             :     increase_size (1);
+    4383     1622401 :     return unchecked_prev (end_ptr ());
+    4384             :   }
+    4385             : 
+    4386             :   template <typename V = value_ty,
+    4387             :             typename std::enable_if<
+    4388             :               std::is_nothrow_move_constructible<V>::value>::type * = nullptr>
+    4389             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4390             :   ptr
+    4391             :   emplace_into_current (ptr pos, value_ty&& val)
+    4392             :   {
+    4393             :     if (pos == end_ptr ())
+    4394             :       return emplace_into_current_end (std::move (val));
+    4395             : 
+    4396             :     // In the special case of value_ty&& we don't make a copy because behavior is unspecified
+    4397             :     // when it is an internal element. Hence, we'll take the opportunity to optimize and assume
+    4398             :     // that it isn't an internal element.
+    4399             :     shift_into_uninitialized (pos, 1);
+    4400             :     destroy (pos);
+    4401             :     construct (pos, std::move (val));
+    4402             :     return pos;
+    4403             :   }
+    4404             : 
+    4405             :   template <typename ...Args>
+    4406             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4407             :   ptr
+    4408             :   emplace_into_current (ptr pos, Args&&... args)
+    4409             :   {
+    4410             :     if (pos == end_ptr ())
+    4411             :       return emplace_into_current_end (std::forward<Args> (args)...);
+    4412             : 
+    4413             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4414             :     if (std::is_constant_evaluated ())
+    4415             :     {
+    4416             :       heap_temporary tmp (*this, std::forward<Args> (args)...);
+    4417             :       shift_into_uninitialized (pos, 1);
+    4418             :       *pos = tmp.release ();
+    4419             :       return pos;
+    4420             :     }
+    4421             : #endif
+    4422             : 
+    4423             :     // This is necessary because of possible aliasing.
+    4424             :     stack_temporary tmp (*this, std::forward<Args> (args)...);
+    4425             :     shift_into_uninitialized (pos, 1);
+    4426             :     *pos = tmp.release ();
+    4427             :     return pos;
+    4428             :   }
+    4429             : 
+    4430             :   template <typename ...Args>
+    4431             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4432             :   ptr
+    4433         172 :   emplace_into_reallocation_end (Args&&... args)
+    4434             :   {
+    4435             :     // Appending; strong exception guarantee.
+    4436         172 :     if (get_max_size () == get_size ())
+    4437           0 :       throw_allocation_size_error ();
+    4438             : 
+    4439         172 :     const size_ty new_size = get_size () + 1;
+    4440             : 
+    4441             :     // The check is handled by the if-guard.
+    4442             :     const size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4443         172 :     const ptr     new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4444         172 :     const ptr     emplace_pos  = unchecked_next (new_data_ptr, get_size ());
+    4445             : 
+    4446             :     PLUMED_GCH_TRY
+    4447             :     {
+    4448             :       construct (emplace_pos, std::forward<Args> (args)...);
+    4449             :       PLUMED_GCH_TRY
+    4450             :       {
+    4451         172 :         uninitialized_move<strong_exception_policy> (begin_ptr (), end_ptr (), new_data_ptr);
+    4452             :       }
+    4453             :       PLUMED_GCH_CATCH (...)
+    4454             :       {
+    4455             :         destroy (emplace_pos);
+    4456             :         PLUMED_GCH_THROW;
+    4457             :       }
+    4458             :     }
+    4459             :     PLUMED_GCH_CATCH (...)
+    4460             :     {
+    4461             :       deallocate (new_data_ptr, new_capacity);
+    4462             :       PLUMED_GCH_THROW;
+    4463             :     }
+    4464             : 
+    4465             :     reset_data (new_data_ptr, new_capacity, new_size);
+    4466         172 :     return emplace_pos;
+    4467             :   }
+    4468             : 
+    4469             :   template <typename ...Args>
+    4470             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4471             :   ptr
+    4472             :   emplace_into_reallocation (ptr pos, Args&&... args)
+    4473             :   {
+    4474             :     const size_ty offset = internal_range_length (begin_ptr (), pos);
+    4475             :     if (offset == get_size ())
+    4476             :       return emplace_into_reallocation_end (std::forward<Args> (args)...);
+    4477             : 
+    4478             :     if (get_max_size () == get_size ())
+    4479             :       throw_allocation_size_error ();
+    4480             : 
+    4481             :     const size_ty new_size = get_size () + 1;
+    4482             : 
+    4483             :     // The check is handled by the if-guard.
+    4484             :     const size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4485             :     const ptr     new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4486             :     ptr           new_first    = unchecked_next (new_data_ptr, offset);
+    4487             :     ptr           new_last     = new_first;
+    4488             : 
+    4489             :     PLUMED_GCH_TRY
+    4490             :     {
+    4491             :       construct (new_first, std::forward<Args> (args)...);
+    4492             :       unchecked_advance (new_last, 1);
+    4493             : 
+    4494             :       uninitialized_move (begin_ptr (), pos, new_data_ptr);
+    4495             :       new_first = new_data_ptr;
+    4496             :       uninitialized_move (pos, end_ptr (), new_last);
+    4497             :     }
+    4498             :     PLUMED_GCH_CATCH (...)
+    4499             :     {
+    4500             :       destroy_range (new_first, new_last);
+    4501             :       deallocate (new_data_ptr, new_capacity);
+    4502             :       PLUMED_GCH_THROW;
+    4503             :     }
+    4504             : 
+    4505             :     reset_data (new_data_ptr, new_capacity, new_size);
+    4506             :     return unchecked_next (begin_ptr (), offset);
+    4507             :   }
+    4508             : 
+    4509             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4510             :   ptr
+    4511             :   shrink_to_size (void)
+    4512             :   {
+    4513             :     if (! has_allocation () || get_size () == get_capacity ())
+    4514             :       return begin_ptr ();
+    4515             : 
+    4516             :     // The rest runs only if allocated.
+    4517             : 
+    4518             :     size_ty new_capacity;
+    4519             :     ptr     new_data_ptr;
+    4520             : 
+    4521             :     if (InlineCapacity < get_size ())
+    4522             :     {
+    4523             :       new_capacity = get_size ();
+    4524             :       new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4525             :     }
+    4526             :     else
+    4527             :     {
+    4528             :       // We move to inline storage.
+    4529             :       new_capacity = InlineCapacity;
+    4530             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4531             :       if (std::is_constant_evaluated ())
+    4532             :         new_data_ptr = alloc_interface::allocate (InlineCapacity);
+    4533             :       else
+    4534             :         new_data_ptr = storage_ptr ();
+    4535             : #else
+    4536             :       new_data_ptr = storage_ptr ();
+    4537             : #endif
+    4538             :     }
+    4539             : 
+    4540             :     uninitialized_move (begin_ptr (), end_ptr (), new_data_ptr);
+    4541             : 
+    4542             :     destroy_range (begin_ptr (), end_ptr ());
+    4543             :     deallocate (data_ptr (), get_capacity ());
+    4544             : 
+    4545             :     set_data_ptr (new_data_ptr);
+    4546             :     set_capacity (new_capacity);
+    4547             : 
+    4548             :     return begin_ptr ();
+    4549             :   }
+    4550             : 
+    4551             :   template <typename ...ValueT>
+    4552             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4553             :   void
+    4554             :   resize_with (size_ty new_size, const ValueT&... val)
+    4555             :   {
+    4556             :     // ValueT... should either be value_ty or empty.
+    4557             : 
+    4558             :     if (new_size == 0)
+    4559             :       erase_all ();
+    4560             : 
+    4561             :     if (get_capacity () < new_size)
+    4562             :     {
+    4563             :       // Reallocate.
+    4564             : 
+    4565             :       if (get_max_size () < new_size)
+    4566             :         throw_allocation_size_error ();
+    4567             : 
+    4568             :       const size_ty original_size = get_size ();
+    4569             : 
+    4570             :       // The check is handled by the if-guard.
+    4571             :       const size_ty new_capacity = unchecked_calculate_new_capacity (new_size);
+    4572             :       ptr           new_data_ptr = unchecked_allocate (new_capacity, allocation_end_ptr ());
+    4573             :       ptr           new_last     = unchecked_next (new_data_ptr, original_size);
+    4574             : 
+    4575             :       PLUMED_GCH_TRY
+    4576             :       {
+    4577             :         new_last = uninitialized_fill (
+    4578             :           new_last,
+    4579             :           unchecked_next (new_data_ptr, new_size),
+    4580             :           val...);
+    4581             : 
+    4582             :         // Strong exception guarantee.
+    4583             :         uninitialized_move<strong_exception_policy> (begin_ptr (), end_ptr (), new_data_ptr);
+    4584             :       }
+    4585             :       PLUMED_GCH_CATCH (...)
+    4586             :       {
+    4587             :         destroy_range (unchecked_next (new_data_ptr, original_size), new_last);
+    4588             :         deallocate (new_data_ptr, new_capacity);
+    4589             :         PLUMED_GCH_THROW;
+    4590             :       }
+    4591             : 
+    4592             :       reset_data (new_data_ptr, new_capacity, new_size);
+    4593             :     }
+    4594             :     else if (get_size () < new_size)
+    4595             :     {
+    4596             :       // Construct in the uninitialized section.
+    4597             :       uninitialized_fill (end_ptr (), unchecked_next (begin_ptr (), new_size), val...);
+    4598             :       set_size (new_size);
+    4599             :     }
+    4600             :     else
+    4601             :       erase_range (unchecked_next (begin_ptr (), new_size), end_ptr ());
+    4602             : 
+    4603             :     // Do nothing if the count is the same as the current size.
+    4604             :   }
+    4605             : 
+    4606             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4607             :   void
+    4608             :   request_capacity (size_ty request)
+    4609             :   {
+    4610             :     if (request <= get_capacity ())
+    4611             :       return;
+    4612             : 
+    4613             :     size_ty new_capacity = checked_calculate_new_capacity (request);
+    4614             :     ptr     new_begin    = unchecked_allocate (new_capacity);
+    4615             : 
+    4616             :     PLUMED_GCH_TRY
+    4617             :     {
+    4618             :       uninitialized_move<strong_exception_policy> (begin_ptr (), end_ptr (), new_begin);
+    4619             :     }
+    4620             :     PLUMED_GCH_CATCH (...)
+    4621             :     {
+    4622             :       deallocate (new_begin, new_capacity);
+    4623             :       PLUMED_GCH_THROW;
+    4624             :     }
+    4625             : 
+    4626             :     wipe ();
+    4627             : 
+    4628             :     set_data_ptr (new_begin);
+    4629             :     set_capacity (new_capacity);
+    4630             :   }
+    4631             : 
+    4632             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4633             :   ptr
+    4634             :   erase_at (ptr pos)
+    4635             :   {
+    4636             :     move_left (unchecked_next (pos), end_ptr (), pos);
+    4637             :     erase_last ();
+    4638             :     return pos;
+    4639             :   }
+    4640             : 
+    4641             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4642             :   void
+    4643             :   erase_last (void)
+    4644             :   {
+    4645             :     decrease_size (1);
+    4646             : 
+    4647             :     // The element located at end_ptr is still alive since the size decreased.
+    4648             :     destroy (end_ptr ());
+    4649             :   }
+    4650             : 
+    4651             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4652             :   ptr
+    4653             :   erase_range (ptr first, ptr last)
+    4654             :   {
+    4655             :     if (! (first == last))
+    4656             :       erase_to_end (move_left (last, end_ptr (), first));
+    4657             :     return first;
+    4658             :   }
+    4659             : 
+    4660             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4661             :   void
+    4662             :   erase_to_end (ptr pos)
+    4663             :   {
+    4664             :     assert (0 <= (end_ptr () - pos) && "`pos` was in the uninitialized range");
+    4665             :     if (size_ty change = internal_range_length (pos, end_ptr ()))
+    4666             :     {
+    4667             :       decrease_size (change);
+    4668             :       destroy_range (pos, unchecked_next (pos, change));
+    4669             :     }
+    4670             :   }
+    4671             : 
+    4672             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4673             :   void
+    4674             :   erase_all (void)
+    4675             :   {
+    4676     1297619 :     ptr curr_end = end_ptr ();
+    4677             :     set_size (0);
+    4678             :     destroy_range (begin_ptr (), curr_end);
+    4679             :   }
+    4680             : 
+    4681             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4682             :   void
+    4683             :   swap_elements (small_vector_base& other)
+    4684             :   noexcept (std::is_nothrow_move_constructible<value_ty>::value
+    4685             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    4686             :             &&  std::is_nothrow_swappable<value_ty>::value
+    4687             : #else
+    4688             :             &&  detail::small_vector_adl::is_nothrow_swappable<value_ty>::value
+    4689             : #endif
+    4690             :            )
+    4691             :   {
+    4692             :     assert (get_size () <= other.get_size ());
+    4693             : 
+    4694             :     const ptr other_tail = std::swap_ranges (begin_ptr (), end_ptr (), other.begin_ptr ());
+    4695             :     uninitialized_move (other_tail, other.end_ptr (), end_ptr ());
+    4696             :     destroy_range (other_tail, other.end_ptr ());
+    4697             : 
+    4698             :     swap_size (other);
+    4699             :   }
+    4700             : 
+    4701             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4702             :   void
+    4703             :   swap_default (small_vector_base& other)
+    4704             :   noexcept (std::is_nothrow_move_constructible<value_ty>::value
+    4705             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    4706             :             &&  std::is_nothrow_swappable<value_ty>::value
+    4707             : #else
+    4708             :             &&  detail::small_vector_adl::is_nothrow_swappable<value_ty>::value
+    4709             : #endif
+    4710             :            )
+    4711             :   {
+    4712             :     // This function is used when:
+    4713             :     //   We are using the standard allocator.
+    4714             :     //   The allocators propagate and are equal.
+    4715             :     //   The allocators are always equal.
+    4716             :     //   The allocators do not propagate and are equal.
+    4717             :     //   The allocators propagate and are not equal.
+    4718             : 
+    4719             :     // Not handled:
+    4720             :     //   The allocators do not propagate and are not equal.
+    4721             : 
+    4722             :     assert (get_capacity () <= other.get_capacity ());
+    4723             : 
+    4724             :     if (has_allocation ()) // Implies that `other` also has an allocation.
+    4725             :       swap_allocation (other);
+    4726             :     else if (other.has_allocation ())
+    4727             :     {
+    4728             :       // Note: This will never be constant evaluated because both are always allocated.
+    4729             :       uninitialized_move (begin_ptr (), end_ptr (), other.storage_ptr ());
+    4730             :       destroy_range (begin_ptr (), end_ptr ());
+    4731             : 
+    4732             :       set_data_ptr (other.data_ptr ());
+    4733             :       set_capacity (other.get_capacity ());
+    4734             : 
+    4735             :       other.set_data_ptr (other.storage_ptr ());
+    4736             :       other.set_capacity (InlineCapacity);
+    4737             : 
+    4738             :       swap_size (other);
+    4739             :     }
+    4740             :     else if (get_size () < other.get_size ())
+    4741             :       swap_elements (other);
+    4742             :     else
+    4743             :       other.swap_elements (*this);
+    4744             : 
+    4745             :     alloc_interface::swap (other);
+    4746             :   }
+    4747             : 
+    4748             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4749             :   void
+    4750             :   swap_unequal_no_propagate (small_vector_base& other)
+    4751             :   {
+    4752             :     assert (get_capacity () <= other.get_capacity ());
+    4753             : 
+    4754             :     if (get_capacity () < other.get_size ())
+    4755             :     {
+    4756             :       // Reallocation required.
+    4757             :       // We should always be able to reuse the allocation of `other`.
+    4758             :       const size_ty new_capacity = unchecked_calculate_new_capacity (other.get_size ());
+    4759             :       const ptr     new_data_ptr = unchecked_allocate (new_capacity, end_ptr ());
+    4760             : 
+    4761             :       PLUMED_GCH_TRY
+    4762             :       {
+    4763             :         uninitialized_move (other.begin_ptr (), other.end_ptr (), new_data_ptr);
+    4764             :         PLUMED_GCH_TRY
+    4765             :         {
+    4766             :           destroy_range (
+    4767             :             std::move (begin_ptr (), end_ptr (), other.begin_ptr ()),
+    4768             :             other.end_ptr ());
+    4769             :         }
+    4770             :         PLUMED_GCH_CATCH (...)
+    4771             :         {
+    4772             :           destroy_range (new_data_ptr, unchecked_next (new_data_ptr, other.get_size ()));
+    4773             :           PLUMED_GCH_THROW;
+    4774             :         }
+    4775             :       }
+    4776             :       PLUMED_GCH_CATCH (...)
+    4777             :       {
+    4778             :         deallocate (new_data_ptr, new_capacity);
+    4779             :         PLUMED_GCH_THROW;
+    4780             :       }
+    4781             : 
+    4782             :       destroy_range (begin_ptr (), end_ptr ());
+    4783             :       if (has_allocation ())
+    4784             :         deallocate (data_ptr (), get_capacity ());
+    4785             : 
+    4786             :       set_data_ptr (new_data_ptr);
+    4787             :       set_capacity (new_capacity);
+    4788             :       swap_size (other);
+    4789             :     }
+    4790             :     else if (get_size () < other.get_size ())
+    4791             :       swap_elements (other);
+    4792             :     else
+    4793             :       other.swap_elements (*this);
+    4794             : 
+    4795             :     // This should have no effect.
+    4796             :     alloc_interface::swap (other);
+    4797             :   }
+    4798             : 
+    4799             :   template <typename A = alloc_ty,
+    4800             :             typename std::enable_if<allocations_are_swappable<A>::value
+    4801             :                                     &&  InlineCapacity == 0>::type * = nullptr>
+    4802             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4803             :   void
+    4804             :   swap (small_vector_base& other) noexcept
+    4805             :   {
+    4806             :     swap_allocation (other);
+    4807             :     alloc_interface::swap (other);
+    4808             :   }
+    4809             : 
+    4810             :   template <typename A = alloc_ty,
+    4811             :             typename std::enable_if<allocations_are_swappable<A>::value
+    4812             :                                     &&  InlineCapacity != 0>::type * = nullptr>
+    4813             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4814             :   void
+    4815             :   swap (small_vector_base& other)
+    4816             :   noexcept (std::is_nothrow_move_constructible<value_ty>::value
+    4817             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    4818             :             &&  std::is_nothrow_swappable<value_ty>::value
+    4819             : #else
+    4820             :             &&  detail::small_vector_adl::is_nothrow_swappable<value_ty>::value
+    4821             : #endif
+    4822             :                                          )
+    4823             :   {
+    4824             :     if (get_capacity () < other.get_capacity ())
+    4825             :           swap_default (other);
+    4826             :     else
+    4827             :       other.swap_default (*this);
+    4828             :   }
+    4829             : 
+    4830             :   template <typename A = alloc_ty,
+    4831             :             typename std::enable_if<! allocations_are_swappable<A>::value>::type * = nullptr>
+    4832             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4833             :   void
+    4834             :   swap (small_vector_base& other)
+    4835             :   {
+    4836             :     if (get_capacity () < other.get_capacity ())
+    4837             :     {
+    4838             :       if (other.allocator_ref () == allocator_ref ())
+    4839             :         swap_default (other);
+    4840             :       else
+    4841             :         swap_unequal_no_propagate (other);
+    4842             :     }
+    4843             :     else
+    4844             :     {
+    4845             :       if (other.allocator_ref () == allocator_ref ())
+    4846             :         other.swap_default (*this);
+    4847             :       else
+    4848             :         other.swap_unequal_no_propagate (*this);
+    4849             :     }
+    4850             :   }
+    4851             : 
+    4852             : #ifdef __GLIBCXX__
+    4853             : 
+    4854             :   // These are compatibility fixes for libstdc++ because std::copy doesn't work for
+    4855             :   // `move_iterator`s when constant evaluated.
+    4856             : 
+    4857             :   template <typename InputIt>
+    4858             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    4859             :   InputIt
+    4860             :   unmove_iterator (InputIt it)
+    4861             :   {
+    4862             :     return it;
+    4863             :   }
+    4864             : 
+    4865             :   template <typename InputIt>
+    4866             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    4867             :   auto
+    4868             :   unmove_iterator (std::move_iterator<InputIt> it)
+    4869             :   -> decltype (unmove_iterator (it.base ()))
+    4870             :   {
+    4871             :     return unmove_iterator (it.base ());
+    4872             :   }
+    4873             : 
+    4874             :   template <typename InputIt>
+    4875             :   static PLUMED_GCH_CPP20_CONSTEXPR
+    4876             :   auto
+    4877             :   unmove_iterator (std::reverse_iterator<InputIt> it)
+    4878             :   -> std::reverse_iterator<decltype (unmove_iterator (it.base ()))>
+    4879             :   {
+    4880             :     return std::reverse_iterator<decltype (unmove_iterator (it.base ()))> (
+    4881             :       unmove_iterator (it.base ()));
+    4882             :                                 }
+    4883             : 
+    4884             : #endif
+    4885             : 
+    4886             :   template <typename InputIt>
+    4887             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4888             :   ptr
+    4889             :   copy_range (InputIt first, InputIt last, ptr dest)
+    4890             :   {
+    4891             : #if defined (PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED) && defined (__GLIBCXX__)
+    4892             :     if (    std::is_constant_evaluated ()
+    4893             :             &&! std::is_same<decltype (unmove_iterator (std::declval<InputIt> ())),
+    4894             :                              InputIt>::value)
+    4895             :     {
+    4896             :       return std::move (unmove_iterator (first), unmove_iterator (last), dest);
+    4897             :     }
+    4898             : #endif
+    4899             : 
+    4900             :     return std::copy (first, last, dest);
+    4901             :   }
+    4902             : 
+    4903             :   template <typename InputIt,
+    4904             :             typename std::enable_if<
+    4905             :               is_memcpyable_iterator<InputIt>::value>::type * = nullptr>
+    4906             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4907             :   InputIt
+    4908             :   copy_n_return_in (InputIt first, size_ty count, ptr dest) noexcept
+    4909             :   {
+    4910             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4911             :     if (std::is_constant_evaluated ())
+    4912             :     {
+    4913             :       std::copy_n (first, count, dest);
+    4914             :       return unchecked_next (first, count);
+    4915             :     }
+    4916             : #endif
+    4917             : 
+    4918             :     if (count != 0)
+    4919             :       std::memcpy (to_address (dest), to_address (first), count * sizeof (value_ty));
+    4920             :     // Note: The unsafe cast here should be proven to be safe in the caller function.
+    4921             :     return unchecked_next (first, count);
+    4922             :   }
+    4923             : 
+    4924             :   template <typename InputIt,
+    4925             :             typename std::enable_if<
+    4926             :               is_memcpyable_iterator<InputIt>::value>::type * = nullptr>
+    4927             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4928             :   std::move_iterator<InputIt>
+    4929             :   copy_n_return_in (std::move_iterator<InputIt> first, size_ty count, ptr dest) noexcept
+    4930             :   {
+    4931             :     return std::move_iterator<InputIt> (copy_n_return_in (first.base (), count, dest));
+    4932             :   }
+    4933             : 
+    4934             :   template <typename RandomIt,
+    4935             :             typename std::enable_if<
+    4936             :               ! is_memcpyable_iterator<RandomIt>::value
+    4937             :               &&  std::is_base_of<std::random_access_iterator_tag,
+    4938             :                                   typename std::iterator_traits<RandomIt>::iterator_category>::value
+    4939             :               >::type * = nullptr>
+    4940             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4941             :   RandomIt
+    4942             :   copy_n_return_in (RandomIt first, size_ty count, ptr dest)
+    4943             :   {
+    4944             : #if defined (PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED) && defined (__GLIBCXX__)
+    4945             :     if (    std::is_constant_evaluated ()
+    4946             :             &&! std::is_same<decltype (unmove_iterator (std::declval<RandomIt> ())),
+    4947             :                              RandomIt>::value)
+    4948             :     {
+    4949             :       auto bfirst = unmove_iterator (first);
+    4950             :       auto blast  = unchecked_next (bfirst, count);
+    4951             :       std::move (bfirst, blast, dest);
+    4952             :       return unchecked_next (first, count);
+    4953             :     }
+    4954             : #endif
+    4955             : 
+    4956             :     std::copy_n (first, count, dest);
+    4957             :     // Note: This unsafe cast should be proven safe in the caller function.
+    4958             :     return unchecked_next (first, count);
+    4959             :   }
+    4960             : 
+    4961             :   template <typename InputIt,
+    4962             :             typename std::enable_if<
+    4963             :               ! is_memcpyable_iterator<InputIt>::value
+    4964             :               &&! std::is_base_of<std::random_access_iterator_tag,
+    4965             :                                   typename std::iterator_traits<InputIt>::iterator_category>::value
+    4966             :               >::type * = nullptr>
+    4967             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4968             :   InputIt
+    4969             :   copy_n_return_in (InputIt first, size_ty count, ptr dest)
+    4970             :   {
+    4971             : 
+    4972             :     for (; count != 0; --count, static_cast<void> (++dest), static_cast<void> (++first))
+    4973             :       *dest = *first;
+    4974             :     return first;
+    4975             :   }
+    4976             : 
+    4977             :   template <typename V = value_ty,
+    4978             :             typename std::enable_if<is_memcpyable<V>::value>::type * = nullptr>
+    4979             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4980             :   ptr
+    4981             :   move_left (ptr first, ptr last, ptr d_first)
+    4982             :   {
+    4983             :     // Shift initialized elements to the left.
+    4984             : 
+    4985             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    4986             :     if (std::is_constant_evaluated ())
+    4987             :       return std::move (first, last, d_first);
+    4988             : #endif
+    4989             : 
+    4990             :     const size_ty num_moved = internal_range_length (first, last);
+    4991             :     if (num_moved != 0)
+    4992             :       std::memmove (to_address (d_first), to_address (first), num_moved * sizeof (value_ty));
+    4993             :     return unchecked_next (d_first, num_moved);
+    4994             :   }
+    4995             : 
+    4996             :   template <typename V = value_ty,
+    4997             :             typename std::enable_if<! is_memcpyable<V>::value>::type * = nullptr>
+    4998             :   PLUMED_GCH_CPP20_CONSTEXPR
+    4999             :   ptr
+    5000             :   move_left (ptr first, ptr last, ptr d_first)
+    5001             :   {
+    5002             :     // Shift initialized elements to the left.
+    5003             :     return std::move (first, last, d_first);
+    5004             :   }
+    5005             : 
+    5006             :   template <typename V = value_ty,
+    5007             :             typename std::enable_if<is_memcpyable<V>::value, bool>::type = true>
+    5008             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5009             :   ptr
+    5010             :   move_right (ptr first, ptr last, ptr d_last)
+    5011             :   {
+    5012             :     // Move initialized elements to the right.
+    5013             : 
+    5014             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    5015             :     if (std::is_constant_evaluated ())
+    5016             :       return std::move_backward (first, last, d_last);
+    5017             : #endif
+    5018             : 
+    5019             :     const size_ty num_moved = internal_range_length (first, last);
+    5020             :     const ptr     dest      = unchecked_prev (d_last, num_moved);
+    5021             :     if (num_moved != 0)
+    5022             :       std::memmove (to_address (dest), to_address (first), num_moved * sizeof (value_ty));
+    5023             :     return dest;
+    5024             :   }
+    5025             : 
+    5026             :   template <typename V = value_ty,
+    5027             :             typename std::enable_if<! is_memcpyable<V>::value, bool>::type = false>
+    5028             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5029             :   ptr
+    5030             :   move_right (ptr first, ptr last, ptr d_last)
+    5031             :   {
+    5032             :     // move initialized elements to the right
+    5033             :     // n should not be 0
+    5034             :     return std::move_backward (first, last, d_last);
+    5035             :   }
+    5036             : 
+    5037             : public:
+    5038             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5039             :   void
+    5040             :   set_default (void)
+    5041             :   {
+    5042             :     set_to_inline_storage ();
+    5043             :     set_size (0);
+    5044             :   }
+    5045             : 
+    5046             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    5047             :   ptr
+    5048             :   data_ptr (void) noexcept
+    5049             :   {
+    5050             :     return m_data.data_ptr ();
+    5051             :   }
+    5052             : 
+    5053             :   PLUMED_GCH_NODISCARD constexpr
+    5054             :   cptr
+    5055             :   data_ptr (void) const noexcept
+    5056             :   {
+    5057             :     return m_data.data_ptr ();
+    5058             :   }
+    5059             : 
+    5060             :   PLUMED_GCH_NODISCARD constexpr
+    5061             :   size_ty
+    5062             :   get_capacity (void) const noexcept
+    5063             :   {
+    5064             :     return m_data.capacity ();
+    5065             :   }
+    5066             : 
+    5067             :   PLUMED_GCH_NODISCARD constexpr
+    5068             :   size_ty
+    5069             :   get_size (void) const noexcept
+    5070             :   {
+    5071             :     return m_data.size ();
+    5072             :   }
+    5073             : 
+    5074             :   PLUMED_GCH_NODISCARD constexpr
+    5075             :   size_ty
+    5076             :   num_uninitialized (void) const noexcept
+    5077             :   {
+    5078             :     return get_capacity () - get_size ();
+    5079             :   }
+    5080             : 
+    5081             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    5082             :   ptr
+    5083             :   begin_ptr (void) noexcept
+    5084             :   {
+    5085             :     return data_ptr ();
+    5086             :   }
+    5087             : 
+    5088             :   PLUMED_GCH_NODISCARD
+    5089             :   constexpr
+    5090             :   cptr
+    5091             :   begin_ptr (void) const noexcept
+    5092             :   {
+    5093             :     return data_ptr ();
+    5094             :   }
+    5095             : 
+    5096             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    5097             :   ptr
+    5098     7051568 :   end_ptr (void) noexcept
+    5099             :   {
+    5100     7051568 :     return unchecked_next (begin_ptr (), get_size ());
+    5101             :   }
+    5102             : 
+    5103             :   PLUMED_GCH_NODISCARD constexpr
+    5104             :   cptr
+    5105     1279312 :   end_ptr (void) const noexcept
+    5106             :   {
+    5107     1279312 :     return unchecked_next (begin_ptr (), get_size ());
+    5108             :   }
+    5109             : 
+    5110             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    5111             :   ptr
+    5112         172 :   allocation_end_ptr (void) noexcept
+    5113             :   {
+    5114         172 :     return unchecked_next (begin_ptr (), get_capacity ());
+    5115             :   }
+    5116             : 
+    5117             :   PLUMED_GCH_NODISCARD constexpr
+    5118             :   cptr
+    5119           0 :   allocation_end_ptr (void) const noexcept
+    5120             :   {
+    5121           0 :     return unchecked_next (begin_ptr (), get_capacity ());
+    5122             :   }
+    5123             : 
+    5124             :   PLUMED_GCH_NODISCARD constexpr
+    5125             :   alloc_ty
+    5126             :   copy_allocator (void) const noexcept
+    5127             :   {
+    5128             :     return alloc_ty (allocator_ref ());
+    5129             :   }
+    5130             : 
+    5131             :   PLUMED_GCH_NODISCARD PLUMED_GCH_CPP14_CONSTEXPR
+    5132             :   ptr
+    5133             :   storage_ptr (void) noexcept
+    5134             :   {
+    5135             :     return m_data.storage ();
+    5136             :   }
+    5137             : 
+    5138             :   PLUMED_GCH_NODISCARD constexpr
+    5139             :   cptr
+    5140             :   storage_ptr (void) const noexcept
+    5141             :   {
+    5142             :     return m_data.storage ();
+    5143             :   }
+    5144             : 
+    5145             :   PLUMED_GCH_NODISCARD constexpr
+    5146             :   bool
+    5147             :   has_allocation (void) const noexcept
+    5148             :   {
+    5149             : #ifdef PLUMED_GCH_LIB_IS_CONSTANT_EVALUATED
+    5150             :     if (std::is_constant_evaluated ())
+    5151             :       return true;
+    5152             : #endif
+    5153             :     return InlineCapacity < get_capacity ();
+    5154             :   }
+    5155             : 
+    5156             :   PLUMED_GCH_NODISCARD constexpr
+    5157             :   bool
+    5158             :   is_inlinable (void) const noexcept
+    5159             :   {
+    5160             :     return get_size () <= InlineCapacity;
+    5161             :   }
+    5162             : 
+    5163             : private:
+    5164             :   small_vector_data<ptr, size_type, value_ty, InlineCapacity> m_data;
+    5165             : };
+    5166             : 
+    5167             : } // namespace gch::detail
+    5168             : 
+    5169             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    5170             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5171             : requires concepts::small_vector::AllocatorFor<Allocator, T>
+    5172             : #endif
+    5173             : class small_vector
+    5174             : : private detail::small_vector_base<Allocator, InlineCapacity>
+    5175             : {
+    5176             :   using base = detail::small_vector_base<Allocator, InlineCapacity>;
+    5177             : 
+    5178             : public:
+    5179             :   static_assert (std::is_same<T, typename Allocator::value_type>::value,
+    5180             :                  "`Allocator::value_type` must be the same as `T`.");
+    5181             : 
+    5182             :   template <typename SameT, unsigned DifferentInlineCapacity, typename SameAllocator>
+    5183             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5184             :   requires concepts::small_vector::AllocatorFor<SameAllocator, SameT>
+    5185             : #endif
+    5186             :   friend class small_vector;
+    5187             : 
+    5188             :   using value_type             = T;
+    5189             :   using allocator_type         = Allocator;
+    5190             :   using size_type              = typename base::size_type;
+    5191             :   using difference_type        = typename base::difference_type;
+    5192             :   using reference              =       value_type&;
+    5193             :   using const_reference        = const value_type&;
+    5194             :   using pointer                = typename std::allocator_traits<allocator_type>::pointer;
+    5195             :   using const_pointer          = typename std::allocator_traits<allocator_type>::const_pointer;
+    5196             : 
+    5197             :   using iterator               = small_vector_iterator<pointer, difference_type>;
+    5198             :   using const_iterator         = small_vector_iterator<const_pointer, difference_type>;
+    5199             :   using reverse_iterator       = std::reverse_iterator<iterator>;
+    5200             :   using const_reverse_iterator = std::reverse_iterator<const_iterator>;
+    5201             : 
+    5202             :   static_assert (InlineCapacity <= (std::numeric_limits<size_type>::max) (),
+    5203             :                  "InlineCapacity must be less than or equal to the maximum value of size_type.");
+    5204             : 
+    5205             :   static constexpr
+    5206             :   unsigned
+    5207             :   inline_capacity_v = InlineCapacity;
+    5208             : 
+    5209             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5210             : 
+    5211             : private:
+    5212             :   static constexpr
+    5213             :   bool
+    5214             :   Destructible = concepts::small_vector::Destructible<value_type>;
+    5215             : 
+    5216             :   static constexpr
+    5217             :   bool
+    5218             :   MoveAssignable = concepts::small_vector::MoveAssignable<value_type>;
+    5219             : 
+    5220             :   static constexpr
+    5221             :   bool
+    5222             :   CopyAssignable = concepts::small_vector::CopyAssignable<value_type>;
+    5223             : 
+    5224             :   static constexpr
+    5225             :   bool
+    5226             :   MoveConstructible = concepts::small_vector::MoveConstructible<value_type>;
+    5227             : 
+    5228             :   static constexpr
+    5229             :   bool
+    5230             :   CopyConstructible = concepts::small_vector::CopyConstructible<value_type>;
+    5231             : 
+    5232             :   static constexpr
+    5233             :   bool
+    5234             :   Swappable = concepts::small_vector::Swappable<value_type>;
+    5235             : 
+    5236             :   static constexpr
+    5237             :   bool
+    5238             :   DefaultInsertable = concepts::small_vector::DefaultInsertable<value_type, small_vector,
+    5239             :   allocator_type>;
+    5240             : 
+    5241             :   static constexpr
+    5242             :   bool
+    5243             :   MoveInsertable = concepts::small_vector::MoveInsertable<value_type, small_vector,
+    5244             :   allocator_type>;
+    5245             : 
+    5246             :   static constexpr
+    5247             :   bool
+    5248             :   CopyInsertable = concepts::small_vector::CopyInsertable<value_type, small_vector,
+    5249             :   allocator_type>;
+    5250             : 
+    5251             :   static constexpr
+    5252             :   bool
+    5253             :   Erasable = concepts::small_vector::Erasable<value_type, small_vector, allocator_type>;
+    5254             : 
+    5255             :   template <typename ...Args>
+    5256             :   struct EmplaceConstructible
+    5257             :   {
+    5258             :     static constexpr
+    5259             :     bool
+    5260             :     value = concepts::small_vector::EmplaceConstructible<value_type, small_vector,
+    5261             :         allocator_type, Args...>;
+    5262             :                                                         };
+    5263             : 
+    5264             : public:
+    5265             : 
+    5266             : #endif
+    5267             : 
+    5268             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5269             :   small_vector (void)
+    5270             :   noexcept (noexcept (allocator_type ()))
+    5271             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5272             :   requires concepts::DefaultConstructible<allocator_type>
+    5273             : #endif
+    5274             :     = default;
+    5275             : 
+    5276             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5277             :   small_vector (const small_vector& other)
+    5278             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5279             :   requires CopyInsertable
+    5280             : #endif
+    5281             : : base (base::bypass, other)
+    5282             :   { }
+    5283             : 
+    5284             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5285             :   small_vector (small_vector&& other)
+    5286             :   noexcept (std::is_nothrow_move_constructible<value_type>::value || InlineCapacity == 0)
+    5287             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5288             :   requires MoveInsertable
+    5289             : #endif
+    5290             : : base (base::bypass, std::move (other))
+    5291             :   { }
+    5292             : 
+    5293             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    5294             :   small_vector (const allocator_type& alloc) noexcept
+    5295             :     : base (alloc)
+    5296             :   { }
+    5297             : 
+    5298             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5299             :   small_vector (const small_vector& other, const allocator_type& alloc)
+    5300             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5301             :   requires CopyInsertable
+    5302             : #endif
+    5303             : : base (base::bypass, other, alloc)
+    5304             :   { }
+    5305             : 
+    5306             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5307             :   small_vector (small_vector&& other, const allocator_type& alloc)
+    5308             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5309             :   requires MoveInsertable
+    5310             : #endif
+    5311             : : base (base::bypass, std::move (other), alloc)
+    5312             :   { }
+    5313             : 
+    5314             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    5315             :   small_vector (size_type count, const allocator_type& alloc = allocator_type ())
+    5316             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5317             :   requires DefaultInsertable
+    5318             : #endif
+    5319             : : base (count, alloc)
+    5320             :   { }
+    5321             : 
+    5322             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5323             :   small_vector (size_type count, const_reference value,
+    5324             :                 const allocator_type& alloc = allocator_type ())
+    5325             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5326             :   requires CopyInsertable
+    5327             : #endif
+    5328             : : base (count, value, alloc)
+    5329             :   { }
+    5330             : 
+    5331             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5332             :   template <typename Generator>
+    5333             :   requires std::invocable<Generator&>
+    5334             :   &&  EmplaceConstructible<std::invoke_result_t<Generator&>>::value
+    5335             : #else
+    5336             :   template <typename Generator,
+    5337             :             typename std::enable_if<
+    5338             :               ! std::is_convertible<Generator, const_reference>::value>::type * = nullptr>
+    5339             : #endif
+    5340             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5341             :   small_vector (size_type count, Generator g, const allocator_type& alloc = allocator_type ())
+    5342             :     : base (count, g, alloc)
+    5343             :   { }
+    5344             : 
+    5345             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5346             :   template <std::input_iterator InputIt>
+    5347             :   requires EmplaceConstructible<std::iter_reference_t<InputIt>>::value
+    5348             :   &&  (std::forward_iterator<InputIt> || MoveInsertable)
+    5349             : #else
+    5350             :   template <typename InputIt,
+    5351             :             typename std::enable_if<
+    5352             :               std::is_base_of<
+    5353             :                 std::input_iterator_tag,
+    5354             :                 typename std::iterator_traits<InputIt>::iterator_category>::value
+    5355             :               >::type * = nullptr>
+    5356             : #endif
+    5357             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5358             :   small_vector (InputIt first, InputIt last, const allocator_type& alloc = allocator_type ())
+    5359             :     : base (first, last, typename std::iterator_traits<InputIt>::iterator_category { }, alloc)
+    5360             :   { }
+    5361             : 
+    5362             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5363             :   small_vector (std::initializer_list<value_type> init,
+    5364             :                 const allocator_type& alloc = allocator_type ())
+    5365             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5366             :   requires EmplaceConstructible<const_reference>::value
+    5367             : #endif
+    5368             : : small_vector (init.begin (), init.end (), alloc)
+    5369             :   { }
+    5370             : 
+    5371             :   template <unsigned I>
+    5372             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5373             :   requires CopyInsertable
+    5374             : #endif
+    5375             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    5376             :   small_vector (const small_vector<T, I, Allocator>& other)
+    5377             :     : base (base::bypass, other)
+    5378             :   { }
+    5379             : 
+    5380             :   template <unsigned I>
+    5381             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5382             :   requires MoveInsertable
+    5383             : #endif
+    5384             :   PLUMED_GCH_CPP20_CONSTEXPR explicit
+    5385             :   small_vector (small_vector<T, I, Allocator>&& other)
+    5386             :   noexcept (std::is_nothrow_move_constructible<value_type>::value && I < InlineCapacity)
+    5387             :               : base (base::bypass, std::move (other))
+    5388             :   { }
+    5389             : 
+    5390             :   template <unsigned I>
+    5391             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5392             :   requires CopyInsertable
+    5393             : #endif
+    5394             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5395             :   small_vector (const small_vector<T, I, Allocator>& other, const allocator_type& alloc)
+    5396             :     : base (base::bypass, other, alloc)
+    5397             :   { }
+    5398             : 
+    5399             :   template <unsigned I>
+    5400             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5401             :   requires MoveInsertable
+    5402             : #endif
+    5403             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5404             :   small_vector (small_vector<T, I, Allocator>&& other, const allocator_type& alloc)
+    5405             :     : base (base::bypass, std::move (other), alloc)
+    5406             :   { }
+    5407             : 
+    5408             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5409     1134787 :   ~small_vector (void)
+    5410             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5411             :   requires Erasable
+    5412             : #endif
+    5413             :     = default;
+    5414             : 
+    5415             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5416             :   small_vector&
+    5417             :   operator= (const small_vector& other)
+    5418             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5419             :   requires CopyInsertable && CopyAssignable
+    5420             : #endif
+    5421             :   {
+    5422             :     assign (other);
+    5423             :     return *this;
+    5424             :   }
+    5425             : 
+    5426             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5427             :   small_vector&
+    5428             :   operator= (small_vector&& other)
+    5429             :   noexcept (  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5430             :                  ||  std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value
+    5431             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5432             :                  ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5433             : #endif
+    5434             :               )
+    5435             :               &&  (  (  std::is_nothrow_move_assignable<value_type>::value
+    5436             :                         &&  std::is_nothrow_move_constructible<value_type>::value
+    5437             :                      )
+    5438             :                      ||  InlineCapacity == 0
+    5439             :                   )
+    5440             :            )
+    5441             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5442             :   // Note: The standard says here that
+    5443             :   // std::allocator_traits<allocator_type>::propagate_on_container_move_assignment == false
+    5444             :   // implies MoveInsertable && MoveAssignable, but since we have inline storage we must always
+    5445             :   // require moves [tab:container.alloc.req].
+    5446             :   requires MoveInsertable && MoveAssignable
+    5447             : #endif
+    5448             :   {
+    5449             :     assign (std::move (other));
+    5450             :     return *this;
+    5451             :   }
+    5452             : 
+    5453             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5454             :   small_vector&
+    5455             :   operator= (std::initializer_list<value_type> ilist)
+    5456             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5457             :   requires CopyInsertable && CopyAssignable
+    5458             : #endif
+    5459             :   {
+    5460             :     assign (ilist);
+    5461             :     return *this;
+    5462             :   }
+    5463             : 
+    5464             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5465             :   void
+    5466             :   assign (size_type count, const_reference value)
+    5467             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5468             :   requires CopyInsertable && CopyAssignable
+    5469             : #endif
+    5470             :   {
+    5471             :     base::assign_with_copies (count, value);
+    5472             :   }
+    5473             : 
+    5474             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5475             :   template <std::input_iterator InputIt>
+    5476             :   requires EmplaceConstructible<std::iter_reference_t<InputIt>>::value
+    5477             :   &&  (std::forward_iterator<InputIt> || MoveInsertable)
+    5478             : #else
+    5479             :   template <typename InputIt,
+    5480             :             typename std::enable_if<std::is_base_of<
+    5481             :                                       std::input_iterator_tag,
+    5482             :                                       typename std::iterator_traits<InputIt>::iterator_category
+    5483             :                                       >::value>::type * = nullptr>
+    5484             : #endif
+    5485             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5486             :   void
+    5487             :   assign (InputIt first, InputIt last)
+    5488             :   {
+    5489             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    5490             :     base::assign_with_range (first, last, iterator_cat { });
+    5491             :   }
+    5492             : 
+    5493             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5494             :   void
+    5495             :   assign (std::initializer_list<value_type> ilist)
+    5496             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5497             :   requires EmplaceConstructible<const_reference>::value
+    5498             : #endif
+    5499             :   {
+    5500             :     assign (ilist.begin (), ilist.end ());
+    5501             :   }
+    5502             : 
+    5503             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5504             :   void
+    5505             :   assign (const small_vector& other)
+    5506             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5507             :   requires CopyInsertable && CopyAssignable
+    5508             : #endif
+    5509             :   {
+    5510             :     if (&other != this)
+    5511             :       base::copy_assign (other);
+    5512             :   }
+    5513             : 
+    5514             :   template <unsigned I>
+    5515             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5516             :   requires CopyInsertable && CopyAssignable
+    5517             : #endif
+    5518             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5519             :   void
+    5520             :   assign (const small_vector<T, I, Allocator>& other)
+    5521             :   {
+    5522             :     base::copy_assign (other);
+    5523             :   }
+    5524             : 
+    5525             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5526             :   void
+    5527             :   assign (small_vector&& other)
+    5528             :   noexcept (  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5529             :                  ||  std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value
+    5530             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5531             :                  ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5532             : #endif
+    5533             :               )
+    5534             :               &&  (  (  std::is_nothrow_move_assignable<value_type>::value
+    5535             :                         &&  std::is_nothrow_move_constructible<value_type>::value
+    5536             :                      )
+    5537             :                      ||  InlineCapacity == 0
+    5538             :                   )
+    5539             :            )
+    5540             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5541             :   requires MoveInsertable && MoveAssignable
+    5542             : #endif
+    5543             :   {
+    5544             :     if (&other != this)
+    5545             :       base::move_assign (std::move (other));
+    5546             :   }
+    5547             : 
+    5548             :   template <unsigned I>
+    5549             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5550             :   requires MoveInsertable && MoveAssignable
+    5551             : #endif
+    5552             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5553             :   void
+    5554             :   assign (small_vector<T, I, Allocator>&& other)
+    5555             :   noexcept (  I <= InlineCapacity
+    5556             :                  &&  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5557             :                         ||  std::allocator_traits<Allocator>::propagate_on_container_move_assignment::value
+    5558             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5559             :                         ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5560             : #endif
+    5561             :                                                  )
+    5562             :                  &&  std::is_nothrow_move_assignable<value_type>::value
+    5563             :                  &&  std::is_nothrow_move_constructible<value_type>::value
+    5564             :                                                        )
+    5565             :   {
+    5566             :     base::move_assign (std::move (other));
+    5567             :   }
+    5568             : 
+    5569             : #ifndef PLUMED_GCH_LIB_CONCEPTS
+    5570             :   template <typename ValueType = value_type,
+    5571             :             typename std::enable_if<
+    5572             :               (  std::is_move_constructible<ValueType>::value
+    5573             :                  &&  std::is_move_assignable<ValueType>::value
+    5574             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    5575             :                  &&  std::is_swappable<ValueType>::value
+    5576             : #endif
+    5577             :                                       )
+    5578             :               ||  (  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5579             :                         ||  std::allocator_traits<Allocator>::propagate_on_container_swap::value
+    5580             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5581             :                         ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5582             : #endif
+    5583             :                                                  )
+    5584             :                      &&  InlineCapacity == 0
+    5585             :                                                  )
+    5586             :               >::type * = nullptr>
+    5587             : #endif
+    5588             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5589             :   void
+    5590             :   swap (small_vector& other)
+    5591             :   noexcept (  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5592             :                  ||  std::allocator_traits<Allocator>::propagate_on_container_swap::value
+    5593             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5594             :                  ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5595             : #endif
+    5596             :                                           )
+    5597             :               &&  (  (  std::is_nothrow_move_constructible<value_type>::value
+    5598             :                         &&  std::is_nothrow_move_assignable<value_type>::value
+    5599             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    5600             :                         &&  std::is_nothrow_swappable<value_type>::value
+    5601             : #else
+    5602             :                         &&  detail::small_vector_adl::is_nothrow_swappable<value_type>::value
+    5603             : #endif
+    5604             :                                                      )
+    5605             :                      ||  InlineCapacity == 0
+    5606             :                                                            )
+    5607             :                                                           )
+    5608             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5609             :   requires (MoveInsertable && MoveAssignable && Swappable)
+    5610             :   ||  (  (  std::is_same<std::allocator<value_type>, Allocator>::value
+    5611             :             ||  std::allocator_traits<Allocator>::propagate_on_container_swap::value
+    5612             : #ifdef PLUMED_GCH_LIB_IS_ALWAYS_EQUAL
+    5613             :             ||  std::allocator_traits<Allocator>::is_always_equal::value
+    5614             : #endif
+    5615             :                                      )
+    5616             :          &&  InlineCapacity == 0
+    5617             :                                      )
+    5618             : #endif
+    5619             :   {
+    5620             :     base::swap (other);
+    5621             :   }
+    5622             : 
+    5623             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5624             :   iterator
+    5625             :   begin (void) noexcept
+    5626             :   {
+    5627             :     return iterator { base::begin_ptr () };
+    5628             :   }
+    5629             : 
+    5630             :   constexpr
+    5631             :   const_iterator
+    5632             :   begin (void) const noexcept
+    5633             :   {
+    5634             :     return const_iterator { base::begin_ptr () };
+    5635             :   }
+    5636             : 
+    5637             :   constexpr
+    5638             :   const_iterator
+    5639             :   cbegin (void) const noexcept
+    5640             :   {
+    5641             :     return begin ();
+    5642             :   }
+    5643             : 
+    5644             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5645             :   iterator
+    5646             :   end (void) noexcept
+    5647             :   {
+    5648             :     return iterator { base::end_ptr () };
+    5649             :   }
+    5650             : 
+    5651             :   constexpr
+    5652             :   const_iterator
+    5653             :   end (void) const noexcept
+    5654             :   {
+    5655             :     return const_iterator { base::end_ptr () };
+    5656             :   }
+    5657             : 
+    5658             :   constexpr
+    5659             :   const_iterator
+    5660             :   cend (void) const noexcept
+    5661             :   {
+    5662             :     return end ();
+    5663             :   }
+    5664             : 
+    5665             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5666             :   reverse_iterator
+    5667             :   rbegin (void) noexcept
+    5668             :   {
+    5669             :     return reverse_iterator { end () };
+    5670             :   }
+    5671             : 
+    5672             :   constexpr
+    5673             :   const_reverse_iterator
+    5674             :   rbegin (void) const noexcept
+    5675             :   {
+    5676             :     return const_reverse_iterator { end () };
+    5677             :   }
+    5678             : 
+    5679             :   constexpr
+    5680             :   const_reverse_iterator
+    5681             :   crbegin (void) const noexcept
+    5682             :   {
+    5683             :     return rbegin ();
+    5684             :   }
+    5685             : 
+    5686             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5687             :   reverse_iterator
+    5688             :   rend (void) noexcept
+    5689             :   {
+    5690             :     return reverse_iterator { begin () };
+    5691             :   }
+    5692             : 
+    5693             :   constexpr
+    5694             :   const_reverse_iterator
+    5695             :   rend (void) const noexcept
+    5696             :   {
+    5697             :     return const_reverse_iterator { begin () };
+    5698             :   }
+    5699             : 
+    5700             :   constexpr
+    5701             :   const_reverse_iterator
+    5702             :   crend (void) const noexcept
+    5703             :   {
+    5704             :     return rend ();
+    5705             :   }
+    5706             : 
+    5707             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5708             :   reference
+    5709             :   at (size_type pos)
+    5710             :   {
+    5711             :     if (size () <= pos)
+    5712             :       base::throw_index_error ();
+    5713             :     return begin ()[static_cast<difference_type> (pos)];
+    5714             :   }
+    5715             : 
+    5716             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5717             :   const_reference
+    5718             :   at (size_type pos) const
+    5719             :   {
+    5720             :     if (size () <= pos)
+    5721             :       base::throw_index_error ();
+    5722             :     return begin ()[static_cast<difference_type> (pos)];
+    5723             :   }
+    5724             : 
+    5725             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5726             :   reference
+    5727             :   operator[] (size_type pos)
+    5728             :   {
+    5729             : #ifdef _GLIBCXX_DEBUG
+    5730             :     if (size () <= pos) base::throw_index_error ();
+    5731             : #endif
+    5732             :     return begin ()[static_cast<difference_type> (pos)];
+    5733             :   }
+    5734             : 
+    5735             :   constexpr
+    5736             :   const_reference
+    5737             :   operator[] (size_type pos) const
+    5738             :   {
+    5739             : #ifdef _GLIBCXX_DEBUG
+    5740             :     if (size () <= pos) base::throw_index_error ();
+    5741             : #endif
+    5742             :     return begin ()[static_cast<difference_type> (pos)];
+    5743             :   }
+    5744             : 
+    5745             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5746             :   reference
+    5747             :   front (void)
+    5748             :   {
+    5749             :     return (*this)[0];
+    5750             :   }
+    5751             : 
+    5752             :   constexpr
+    5753             :   const_reference
+    5754             :   front (void) const
+    5755             :   {
+    5756             :     return (*this)[0];
+    5757             :   }
+    5758             : 
+    5759             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5760             :   reference
+    5761             :   back (void)
+    5762             :   {
+    5763             :     return (*this)[size () - 1];
+    5764             :   }
+    5765             : 
+    5766             :   constexpr
+    5767             :   const_reference
+    5768             :   back (void) const
+    5769             :   {
+    5770             :     return (*this)[size () - 1];
+    5771             :   }
+    5772             : 
+    5773             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5774             :   pointer
+    5775             :   data (void) noexcept
+    5776             :   {
+    5777             :     return base::begin_ptr ();
+    5778             :   }
+    5779             : 
+    5780             :   constexpr
+    5781             :   const_pointer
+    5782             :   data (void) const noexcept
+    5783             :   {
+    5784             :     return base::begin_ptr ();
+    5785             :   }
+    5786             : 
+    5787             :   constexpr
+    5788             :   size_type
+    5789             :   size (void) const noexcept
+    5790             :   {
+    5791             :     return static_cast<size_type> (base::get_size ());
+    5792             :   }
+    5793             : 
+    5794             :   PLUMED_GCH_NODISCARD constexpr
+    5795             :   bool
+    5796             :   empty (void) const noexcept
+    5797             :   {
+    5798             :     return size () == 0;
+    5799             :   }
+    5800             : 
+    5801             :   PLUMED_GCH_CPP14_CONSTEXPR
+    5802             :   size_type
+    5803             :   max_size (void) const noexcept
+    5804             :   {
+    5805             :     return static_cast<size_type> (base::get_max_size ());
+    5806             :   }
+    5807             : 
+    5808             :   constexpr
+    5809             :   size_type
+    5810             :   capacity (void) const noexcept
+    5811             :   {
+    5812             :     return static_cast<size_type> (base::get_capacity ());
+    5813             :   }
+    5814             : 
+    5815             :   constexpr
+    5816             :   allocator_type
+    5817             :   get_allocator (void) const noexcept
+    5818             :   {
+    5819             :     return base::copy_allocator ();
+    5820             :   }
+    5821             : 
+    5822             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5823             :   iterator
+    5824             :   insert (const_iterator pos, const_reference value)
+    5825             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5826             :   requires CopyInsertable && CopyAssignable
+    5827             : #endif
+    5828             :   {
+    5829             :     return emplace (pos, value);
+    5830             :   }
+    5831             : 
+    5832             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5833             :   iterator
+    5834             :   insert (const_iterator pos, value_type&& value)
+    5835             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5836             :   requires MoveInsertable && MoveAssignable
+    5837             : #endif
+    5838             :   {
+    5839             :     return emplace (pos, std::move (value));
+    5840             :   }
+    5841             : 
+    5842             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5843             :   iterator
+    5844             :   insert (const_iterator pos, size_type count, const_reference value)
+    5845             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5846             :   requires CopyInsertable && CopyAssignable
+    5847             : #endif
+    5848             :   {
+    5849             :     return iterator (base::insert_copies (base::ptr_cast (pos), count, value));
+    5850             :   }
+    5851             : 
+    5852             :   // Note: Unlike std::vector, this does not require MoveConstructible because we
+    5853             :   //       don't use std::rotate (as was the reason for the change in C++17).
+    5854             :   //       Relevant: https://cplusplus.github.io/LWG/issue2266).
+    5855             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5856             :   template <std::input_iterator InputIt>
+    5857             :   requires EmplaceConstructible<std::iter_reference_t<InputIt>>::value
+    5858             :   &&  MoveInsertable
+    5859             :   &&  MoveAssignable
+    5860             : #else
+    5861             :   template <typename InputIt,
+    5862             :             typename std::enable_if<std::is_base_of<
+    5863             :                                       std::input_iterator_tag,
+    5864             :                                       typename std::iterator_traits<InputIt>::iterator_category
+    5865             :                                       >::value>::type * = nullptr>
+    5866             : #endif
+    5867             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5868             :   iterator
+    5869             :   insert (const_iterator pos, InputIt first, InputIt last)
+    5870             :   {
+    5871             :     if (first == last)
+    5872             :       return iterator (base::ptr_cast (pos));
+    5873             : 
+    5874             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    5875             :     return iterator (base::insert_range (base::ptr_cast (pos), first, last, iterator_cat { }));
+    5876             :   }
+    5877             : 
+    5878             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5879             :   iterator
+    5880             :   insert (const_iterator pos, std::initializer_list<value_type> ilist)
+    5881             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5882             :   requires EmplaceConstructible<const_reference>::value
+    5883             :   &&  MoveInsertable
+    5884             :   &&  MoveAssignable
+    5885             : #endif
+    5886             :   {
+    5887             :     return insert (pos, ilist.begin (), ilist.end ());
+    5888             :   }
+    5889             : 
+    5890             :   template <typename ...Args>
+    5891             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5892             :   requires EmplaceConstructible<Args...>::value
+    5893             :   &&  MoveInsertable
+    5894             :   &&  MoveAssignable
+    5895             : #endif
+    5896             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5897             :   iterator
+    5898             :   emplace (const_iterator pos, Args&&... args)
+    5899             :   {
+    5900             :     return iterator (base::emplace_at (base::ptr_cast (pos), std::forward<Args> (args)...));
+    5901             :   }
+    5902             : 
+    5903             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5904             :   iterator
+    5905             :   erase (const_iterator pos)
+    5906             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5907             :   requires MoveAssignable && Erasable
+    5908             : #endif
+    5909             :   {
+    5910             :     assert (0 <= (pos    - begin ()) && "`pos` is out of bounds (before `begin ()`)."   );
+    5911             :     assert (0 <  (end () - pos)      && "`pos` is out of bounds (at or after `end ()`).");
+    5912             : 
+    5913             :     return iterator (base::erase_at (base::ptr_cast (pos)));
+    5914             :   }
+    5915             : 
+    5916             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5917             :   iterator
+    5918             :   erase (const_iterator first, const_iterator last)
+    5919             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5920             :   requires MoveAssignable && Erasable
+    5921             : #endif
+    5922             :   {
+    5923             :     assert (0 <= (last   - first)    && "Invalid range.");
+    5924             :     assert (0 <= (first  - begin ()) && "`first` is out of bounds (before `begin ()`)."  );
+    5925             :     assert (0 <= (end () - last)     && "`last` is out of bounds (after `end ()`).");
+    5926             : 
+    5927             :     return iterator (base::erase_range (base::ptr_cast (first), base::ptr_cast (last)));
+    5928             :   }
+    5929             : 
+    5930             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5931             :   void
+    5932             :   push_back (const_reference value)
+    5933             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5934             :   requires CopyInsertable
+    5935             : #endif
+    5936             :   {
+    5937             :     emplace_back (value);
+    5938             :   }
+    5939             : 
+    5940             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5941             :   void
+    5942             :   push_back (value_type&& value)
+    5943             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5944             :   requires MoveInsertable
+    5945             : #endif
+    5946             :   {
+    5947             :     emplace_back (std::move (value));
+    5948             :   }
+    5949             : 
+    5950             :   template <typename ...Args>
+    5951             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5952             :   requires EmplaceConstructible<Args...>::value && MoveInsertable
+    5953             : #endif
+    5954             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5955             :   reference
+    5956             :   emplace_back (Args&&... args)
+    5957             :   {
+    5958     1622573 :     return *base::append_element (std::forward<Args> (args)...);
+    5959             :   }
+    5960             : 
+    5961             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5962             :   void
+    5963             :   pop_back (void)
+    5964             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5965             :   requires Erasable
+    5966             : #endif
+    5967             :   {
+    5968             :     assert (! empty () && "`pop_back ()` called on an empty `small_vector`.");
+    5969             :     base::erase_last ();
+    5970             :   }
+    5971             : 
+    5972             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5973             :   void
+    5974             :   reserve (size_type new_capacity)
+    5975             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5976             :   requires MoveInsertable
+    5977             : #endif
+    5978             :   {
+    5979             :     base::request_capacity (new_capacity);
+    5980             :   }
+    5981             : 
+    5982             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5983             :   void
+    5984             :   shrink_to_fit (void)
+    5985             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5986             :   requires MoveInsertable
+    5987             : #endif
+    5988             :   {
+    5989             :     base::shrink_to_size ();
+    5990             :   }
+    5991             : 
+    5992             :   PLUMED_GCH_CPP20_CONSTEXPR
+    5993             :   void
+    5994             :   clear (void) noexcept
+    5995             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    5996             :   requires Erasable
+    5997             : #endif
+    5998             :   {
+    5999     1297619 :     base::erase_all ();
+    6000             :   }
+    6001             : 
+    6002             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6003             :   void
+    6004             :   resize (size_type count)
+    6005             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6006             :   requires MoveInsertable && DefaultInsertable
+    6007             : #endif
+    6008             :   {
+    6009             :     base::resize_with (count);
+    6010             :   }
+    6011             : 
+    6012             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6013             :   void
+    6014             :   resize (size_type count, const_reference value)
+    6015             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6016             :   requires CopyInsertable
+    6017             : #endif
+    6018             :   {
+    6019             :     base::resize_with (count, value);
+    6020             :   }
+    6021             : 
+    6022             :   PLUMED_GCH_NODISCARD constexpr
+    6023             :   bool
+    6024             :   inlined (void) const noexcept
+    6025             :   {
+    6026             :     return ! base::has_allocation ();
+    6027             :   }
+    6028             : 
+    6029             :   PLUMED_GCH_NODISCARD constexpr
+    6030             :   bool
+    6031             :   inlinable (void) const noexcept
+    6032             :   {
+    6033             :     return base::is_inlinable ();
+    6034             :   }
+    6035             : 
+    6036             :   PLUMED_GCH_NODISCARD
+    6037             :   static PLUMED_GCH_CONSTEVAL
+    6038             :   size_type
+    6039             :   inline_capacity (void) noexcept
+    6040             :   {
+    6041             :     return static_cast<size_type> (inline_capacity_v);
+    6042             :   }
+    6043             : 
+    6044             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6045             :   template <std::input_iterator InputIt>
+    6046             :   requires EmplaceConstructible<std::iter_reference_t<InputIt>>::value
+    6047             :   &&  MoveInsertable
+    6048             : #else
+    6049             :   template <typename InputIt,
+    6050             :             typename std::enable_if<std::is_base_of<
+    6051             :                                       std::input_iterator_tag,
+    6052             :                                       typename std::iterator_traits<InputIt>::iterator_category
+    6053             :                                       >::value>::type * = nullptr>
+    6054             : #endif
+    6055             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6056             :   small_vector&
+    6057             :   append (InputIt first, InputIt last)
+    6058             :   {
+    6059             :     using policy = typename base::strong_exception_policy;
+    6060             :     using iterator_cat = typename std::iterator_traits<InputIt>::iterator_category;
+    6061             :     base::template append_range<policy> (first, last, iterator_cat { });
+    6062             :     return *this;
+    6063             :   }
+    6064             : 
+    6065             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6066             :   small_vector&
+    6067             :   append (std::initializer_list<value_type> ilist)
+    6068             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6069             :   requires EmplaceConstructible<const_reference>::value
+    6070             :   &&  MoveInsertable
+    6071             : #endif
+    6072             :   {
+    6073             :     return append (ilist.begin (), ilist.end ());
+    6074             :   }
+    6075             : 
+    6076             :   template <unsigned I>
+    6077             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6078             :   small_vector&
+    6079             :   append (const small_vector<T, I, Allocator>& other)
+    6080             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6081             :   requires CopyInsertable
+    6082             : #endif
+    6083             :   {
+    6084             :     return append (other.begin (), other.end ());
+    6085             :   }
+    6086             : 
+    6087             :   template <unsigned I>
+    6088             :   PLUMED_GCH_CPP20_CONSTEXPR
+    6089             :   small_vector&
+    6090             :   append (small_vector<T, I, Allocator>&& other)
+    6091             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6092             :   requires MoveInsertable
+    6093             : #endif
+    6094             :   {
+    6095             :     // Provide a strong exception guarantee for `other` as well.
+    6096             :     using move_iter_type = typename std::conditional<
+    6097             :       base::template relocate_with_move<value_type>::value,
+    6098             :       std::move_iterator<iterator>,
+    6099             :       iterator>::type;
+    6100             : 
+    6101             :     append (move_iter_type { other.begin () }, move_iter_type { other.end () });
+    6102             :     other.clear ();
+    6103             :     return *this;
+    6104             :   }
+    6105             : };
+    6106             : 
+    6107             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6108             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6109             : bool
+    6110             : operator== (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6111             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6112             : {
+    6113             :   return lhs.size () == rhs.size () && std::equal (lhs.begin (), lhs.end (), rhs.begin ());
+    6114             : }
+    6115             : 
+    6116             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6117             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6118             : bool
+    6119             : operator== (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6120             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6121             : {
+    6122             :   return lhs.size () == rhs.size () && std::equal (lhs.begin (), lhs.end (), rhs.begin ());
+    6123             : }
+    6124             : 
+    6125             : #ifdef PLUMED_GCH_LIB_THREE_WAY_COMPARISON
+    6126             : 
+    6127             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6128             : requires std::three_way_comparable<T>
+    6129             : constexpr
+    6130             : auto
+    6131             : operator<=> (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6132             :              const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6133             : {
+    6134             :   return std::lexicographical_compare_three_way (
+    6135             :     lhs.begin (), lhs.end (),
+    6136             :     rhs.begin (), rhs.end (),
+    6137             :     std::compare_three_way { });
+    6138             : }
+    6139             : 
+    6140             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6141             : requires std::three_way_comparable<T>
+    6142             : constexpr
+    6143             : auto
+    6144             : operator<=> (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6145             :              const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6146             : {
+    6147             :   return std::lexicographical_compare_three_way (
+    6148             :     lhs.begin (), lhs.end (),
+    6149             :     rhs.begin (), rhs.end (),
+    6150             :     std::compare_three_way { });
+    6151             : }
+    6152             : 
+    6153             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6154             : constexpr
+    6155             : auto
+    6156             : operator<=> (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6157             :              const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6158             : {
+    6159             :   constexpr auto comparison = [](const T& l, const T& r) {
+    6160             :     return (l < r) ? std::weak_ordering::less
+    6161             :             : (r < l) ? std::weak_ordering::greater
+    6162             :                : std::weak_ordering::equivalent;
+    6163             :   };
+    6164             : 
+    6165             :   return std::lexicographical_compare_three_way (
+    6166             :            lhs.begin (), lhs.end (),
+    6167             :            rhs.begin (), rhs.end (),
+    6168             :            comparison);
+    6169             : }
+    6170             : 
+    6171             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6172             : constexpr
+    6173             : auto
+    6174             : operator<=> (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6175             :              const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6176             : {
+    6177             :   constexpr auto comparison = [](const T& l, const T& r) {
+    6178             :     return (l < r) ? std::weak_ordering::less
+    6179             :             : (r < l) ? std::weak_ordering::greater
+    6180             :                : std::weak_ordering::equivalent;
+    6181             :   };
+    6182             : 
+    6183             :   return std::lexicographical_compare_three_way (
+    6184             :            lhs.begin (), lhs.end (),
+    6185             :            rhs.begin (), rhs.end (),
+    6186             :            comparison);
+    6187             : }
+    6188             : 
+    6189             : #else
+    6190             : 
+    6191             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6192             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6193             : bool
+    6194             : operator!= (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6195             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6196             : {
+    6197             :   return ! (lhs == rhs);
+    6198             : }
+    6199             : 
+    6200             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6201             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6202             : bool
+    6203             : operator!= (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6204             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6205             : {
+    6206             :   return ! (lhs == rhs);
+    6207             : }
+    6208             : 
+    6209             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6210             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6211             : bool
+    6212             : operator<  (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6213             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6214             : {
+    6215             :   return std::lexicographical_compare (lhs.begin (), lhs.end (), rhs.begin (), rhs.end ());
+    6216             : }
+    6217             : 
+    6218             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6219             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6220             : bool
+    6221             : operator<  (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6222             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6223             : {
+    6224             :   return std::lexicographical_compare (lhs.begin (), lhs.end (), rhs.begin (), rhs.end ());
+    6225             : }
+    6226             : 
+    6227             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6228             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6229             : bool
+    6230             : operator>= (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6231             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6232             : {
+    6233             :   return ! (lhs < rhs);
+    6234             : }
+    6235             : 
+    6236             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6237             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6238             : bool
+    6239             : operator>= (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6240             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6241             : {
+    6242             :   return ! (lhs < rhs);
+    6243             : }
+    6244             : 
+    6245             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6246             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6247             : bool
+    6248             : operator>  (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6249             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6250             : {
+    6251             :   return rhs < lhs;
+    6252             : }
+    6253             : 
+    6254             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6255             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6256             : bool
+    6257             : operator>  (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6258             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6259             : {
+    6260             :   return rhs < lhs;
+    6261             : }
+    6262             : 
+    6263             : template <typename T, unsigned InlineCapacityLHS, unsigned InlineCapacityRHS, typename Allocator>
+    6264             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6265             : bool
+    6266             : operator<= (const small_vector<T, InlineCapacityLHS, Allocator>& lhs,
+    6267             :             const small_vector<T, InlineCapacityRHS, Allocator>& rhs)
+    6268             : {
+    6269             :   return rhs >= lhs;
+    6270             : }
+    6271             : 
+    6272             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6273             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6274             : bool
+    6275             : operator<= (const small_vector<T, InlineCapacity, Allocator>& lhs,
+    6276             :             const small_vector<T, InlineCapacity, Allocator>& rhs)
+    6277             : {
+    6278             :   return rhs >= lhs;
+    6279             : }
+    6280             : 
+    6281             : #endif
+    6282             : 
+    6283             : template <typename T, unsigned InlineCapacity, typename Allocator
+    6284             : #ifndef PLUMED_GCH_LIB_CONCEPTS
+    6285             :           , typename std::enable_if<std::is_move_constructible<T>::value
+    6286             :                                     &&  std::is_move_assignable<T>::value
+    6287             : #ifdef PLUMED_GCH_LIB_IS_SWAPPABLE
+    6288             :                                     &&  std::is_swappable<T>::value
+    6289             : #endif
+    6290             :                                     >::type * = nullptr
+    6291             : #endif
+    6292             :           >
+    6293             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6294             : void
+    6295             : swap (small_vector<T, InlineCapacity, Allocator>& lhs,
+    6296             :       small_vector<T, InlineCapacity, Allocator>& rhs)
+    6297             : noexcept (noexcept (lhs.swap (rhs)))
+    6298             : #ifdef PLUMED_GCH_LIB_CONCEPTS
+    6299             : requires concepts::MoveInsertable<T, small_vector<T, InlineCapacity, Allocator>, Allocator>
+    6300             : && concepts::Swappable<T>
+    6301             : #endif
+    6302             : {
+    6303             :   lhs.swap (rhs);
+    6304             : }
+    6305             : 
+    6306             : template <typename T, unsigned InlineCapacity, typename Allocator, typename U>
+    6307             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6308             : typename small_vector<T, InlineCapacity, Allocator>::size_type
+    6309             : erase (small_vector<T, InlineCapacity, Allocator>& v, const U& value)
+    6310             : {
+    6311             :   const auto original_size = v.size ();
+    6312             :   v.erase (std::remove (v.begin (), v.end (), value), v.end ());
+    6313             :   return original_size - v.size ();
+    6314             : }
+    6315             : 
+    6316             : template <typename T, unsigned InlineCapacity, typename Allocator, typename Pred>
+    6317             : inline PLUMED_GCH_CPP20_CONSTEXPR
+    6318             : typename small_vector<T, InlineCapacity, Allocator>::size_type
+    6319             : erase_if (small_vector<T, InlineCapacity, Allocator>& v, Pred pred)
+    6320             : {
+    6321             :   const auto original_size = v.size ();
+    6322             :   v.erase (std::remove_if (v.begin (), v.end (), pred), v.end ());
+    6323             :   return original_size - v.size ();
+    6324             : }
+    6325             : 
+    6326             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6327             : constexpr
+    6328             : typename small_vector<T, InlineCapacity, Allocator>::iterator
+    6329             : begin (small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6330             : {
+    6331             :   return v.begin ();
+    6332             : }
+    6333             : 
+    6334             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6335             : constexpr
+    6336             : typename small_vector<T, InlineCapacity, Allocator>::const_iterator
+    6337             : begin (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6338             : {
+    6339             :   return v.begin ();
+    6340             : }
+    6341             : 
+    6342             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6343             : constexpr
+    6344             : typename small_vector<T, InlineCapacity, Allocator>::const_iterator
+    6345             : cbegin (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6346             : {
+    6347             :   return begin (v);
+    6348             : }
+    6349             : 
+    6350             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6351             : constexpr
+    6352             : typename small_vector<T, InlineCapacity, Allocator>::iterator
+    6353             : end (small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6354             : {
+    6355             :   return v.end ();
+    6356             : }
+    6357             : 
+    6358             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6359             : constexpr
+    6360             : typename small_vector<T, InlineCapacity, Allocator>::const_iterator
+    6361             : end (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6362             : {
+    6363             :   return v.end ();
+    6364             : }
+    6365             : 
+    6366             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6367             : constexpr
+    6368             : typename small_vector<T, InlineCapacity, Allocator>::const_iterator
+    6369             : cend (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6370             : {
+    6371             :   return end (v);
+    6372             : }
+    6373             : 
+    6374             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6375             : constexpr
+    6376             : typename small_vector<T, InlineCapacity, Allocator>::reverse_iterator
+    6377             : rbegin (small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6378             : {
+    6379             :   return v.rbegin ();
+    6380             : }
+    6381             : 
+    6382             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6383             : constexpr
+    6384             : typename small_vector<T, InlineCapacity, Allocator>::const_reverse_iterator
+    6385             : rbegin (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6386             : {
+    6387             :   return v.rbegin ();
+    6388             : }
+    6389             : 
+    6390             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6391             : constexpr
+    6392             : typename small_vector<T, InlineCapacity, Allocator>::const_reverse_iterator
+    6393             : crbegin (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6394             : {
+    6395             :   return rbegin (v);
+    6396             : }
+    6397             : 
+    6398             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6399             : constexpr
+    6400             : typename small_vector<T, InlineCapacity, Allocator>::reverse_iterator
+    6401             : rend (small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6402             : {
+    6403             :   return v.rend ();
+    6404             : }
+    6405             : 
+    6406             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6407             : constexpr
+    6408             : typename small_vector<T, InlineCapacity, Allocator>::const_reverse_iterator
+    6409             : rend (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6410             : {
+    6411             :   return v.rend ();
+    6412             : }
+    6413             : 
+    6414             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6415             : constexpr
+    6416             : typename small_vector<T, InlineCapacity, Allocator>::const_reverse_iterator
+    6417             : crend (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6418             : {
+    6419             :   return rend (v);
+    6420             : }
+    6421             : 
+    6422             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6423             : constexpr
+    6424             : typename small_vector<T, InlineCapacity, Allocator>::size_type
+    6425             : size (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6426             : {
+    6427             :   return v.size ();
+    6428             : }
+    6429             : 
+    6430             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6431             : constexpr
+    6432             : typename std::common_type<
+    6433             :   std::ptrdiff_t,
+    6434             :   typename std::make_signed<
+    6435             :     typename small_vector<T, InlineCapacity, Allocator>::size_type>::type>::type
+    6436             : ssize (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6437             : {
+    6438             :   using ret_type = typename std::common_type<
+    6439             :     std::ptrdiff_t,
+    6440             :     typename std::make_signed<decltype (v.size ())>::type>::type;
+    6441             :   return static_cast<ret_type> (v.size ());
+    6442             : }
+    6443             : 
+    6444             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6445             : PLUMED_GCH_NODISCARD constexpr
+    6446             : bool
+    6447             : empty (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6448             : {
+    6449             :   return v.empty ();
+    6450             : }
+    6451             : 
+    6452             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6453             : constexpr
+    6454             : typename small_vector<T, InlineCapacity, Allocator>::pointer
+    6455             : data (small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6456             : {
+    6457             :   return v.data ();
+    6458             : }
+    6459             : 
+    6460             : template <typename T, unsigned InlineCapacity, typename Allocator>
+    6461             : constexpr
+    6462             : typename small_vector<T, InlineCapacity, Allocator>::const_pointer
+    6463             : data (const small_vector<T, InlineCapacity, Allocator>& v) noexcept
+    6464             : {
+    6465             :   return v.data ();
+    6466             : }
+    6467             : 
+    6468             : #ifdef PLUMED_GCH_CTAD_SUPPORT
+    6469             : 
+    6470             : template <typename InputIt,
+    6471             :           unsigned InlineCapacity = default_buffer_size<
+    6472             :             std::allocator<typename std::iterator_traits<InputIt>::value_type>>::value,
+    6473             :           typename Allocator = std::allocator<typename std::iterator_traits<InputIt>::value_type>>
+    6474             : small_vector (InputIt, InputIt, Allocator = Allocator ())
+    6475             : -> small_vector<typename std::iterator_traits<InputIt>::value_type, InlineCapacity, Allocator>;
+    6476             : 
+    6477             : #endif
+    6478             : 
+    6479             : } // namespace gch
+    6480             : } // namespace PLMD
+    6481             : 
+    6482             : #endif // PLUMED_GCH_SMALL_VECTOR_HPP
+    6483             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/snow.png b/coverage/snow.png new file mode 100644 index 0000000000000000000000000000000000000000..2cdae107fceec6e7f02ac7acb4a34a82a540caa5 GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^j3CU&3?x-=hn)ga>?NMQuI!iC1^MM!lvI6;R0X`wF|Ns97GD8ntt^-nBo-U3d c6}OTTfNUlP#;5A{K>8RwUHx3vIVCg!071?oo&W#< literal 0 HcmV?d00001 diff --git a/coverage/tools/Angle.cpp.func-sort-c.html b/coverage/tools/Angle.cpp.func-sort-c.html new file mode 100644 index 000000000000..129157fbe932 --- /dev/null +++ b/coverage/tools/Angle.cpp.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD5Angle7computeERKNS_13VectorGenericILj3EEES4_2
_ZNK4PLMD5Angle7computeERKNS_13VectorGenericILj3EEES4_RS2_S5_543453
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Angle.cpp.func.html b/coverage/tools/Angle.cpp.func.html new file mode 100644 index 000000000000..74f7a18e25f9 --- /dev/null +++ b/coverage/tools/Angle.cpp.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Angle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD5Angle7computeERKNS_13VectorGenericILj3EEES4_2
_ZNK4PLMD5Angle7computeERKNS_13VectorGenericILj3EEES4_RS2_S5_543453
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Angle.cpp.gcov.html b/coverage/tools/Angle.cpp.gcov.html new file mode 100644 index 000000000000..e72cb9c89c32 --- /dev/null +++ b/coverage/tools/Angle.cpp.gcov.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - tools/Angle.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Angle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Angle.h"
+      23             : #include "Tools.h"
+      24             : #include <cmath>
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28           2 : double Angle::compute(const Vector& v1,const Vector& v2)const {
+      29           2 :   return std::acos(dotProduct(v1,v2)/(v1.modulo()*v2.modulo()));
+      30             : }
+      31             : 
+      32      543453 : double Angle::compute(const Vector& v1,const Vector& v2,Vector& d1,Vector& d2)const {
+      33      543453 :   const double dp(dotProduct(v1,v2));
+      34             :   const Vector& dp_dv1(v2);
+      35             :   const Vector& dp_dv2(v1);
+      36      543453 :   const double sv1(v1.modulo2());
+      37      543453 :   const double sv2(v2.modulo2());
+      38      543453 :   const Vector dsv1_dv1(2*v1);
+      39      543453 :   const Vector dsv2_dv2(2*v2);
+      40      543453 :   const double nn(1.0/std::sqrt(sv1*sv2));
+      41      543453 :   const Vector dnn_dv1(-0.5*nn/sv1*dsv1_dv1);
+      42      543453 :   const Vector dnn_dv2(-0.5*nn/sv2*dsv2_dv2);
+      43             : 
+      44      543453 :   const double dpnn(dp*nn);
+      45             : 
+      46      543453 :   if(dpnn>=1.0-epsilon) {
+      47           1 :     d1=Vector(0.0,0.0,0.0);
+      48           1 :     d2=Vector(0.0,0.0,0.0);
+      49           1 :     return 0.0;
+      50             :   }
+      51      543452 :   if(dpnn<=-1.0+epsilon) {
+      52           1 :     d1=Vector(0.0,0.0,0.0);
+      53           1 :     d2=Vector(0.0,0.0,0.0);
+      54           1 :     return pi;
+      55             :   }
+      56      543451 :   const Vector ddpnn_dv1(dp*dnn_dv1+dp_dv1*nn);
+      57      543451 :   const Vector ddpnn_dv2(dp*dnn_dv2+dp_dv2*nn);
+      58             : 
+      59      543451 :   const double x(-1.0/std::sqrt(1-dpnn*dpnn));
+      60             : 
+      61      543451 :   d1=x*ddpnn_dv1;
+      62      543451 :   d2=x*ddpnn_dv2;
+      63             : 
+      64             : 
+      65      543451 :   return std::acos(dpnn);
+      66             : }
+      67             : 
+      68             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/AtomNumber.h.func-sort-c.html b/coverage/tools/AtomNumber.h.func-sort-c.html new file mode 100644 index 000000000000..7cb00de3e736 --- /dev/null +++ b/coverage/tools/AtomNumber.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10AtomNumber6serialEj348
_ZN4PLMD10AtomNumber9setSerialEj902703
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/AtomNumber.h.func.html b/coverage/tools/AtomNumber.h.func.html new file mode 100644 index 000000000000..234857ba56fc --- /dev/null +++ b/coverage/tools/AtomNumber.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10AtomNumber6serialEj348
_ZN4PLMD10AtomNumber9setSerialEj902703
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/AtomNumber.h.gcov.html b/coverage/tools/AtomNumber.h.gcov.html new file mode 100644 index 000000000000..795da6cc4e45 --- /dev/null +++ b/coverage/tools/AtomNumber.h.gcov.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - tools/AtomNumber.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - AtomNumber.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1818100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_AtomNumber_h
+      23             : #define __PLUMED_tools_AtomNumber_h
+      24             : 
+      25             : #include "Exception.h"
+      26             : #include <limits>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : /**
+      31             : \ingroup TOOLBOX
+      32             :  Simple class to store the index of an atom.
+      33             :  It is just an unsigned, with all the methods inlined for better efficiency.
+      34             :  Its special thing is that it is only accessed through serial(), index(),
+      35             :  setSerial() and setIndex() methods, so that there
+      36             :  no ambiguity about using the "from 0" (index) or
+      37             :  "from 1" (serial) numbering (names as in VMD convention).
+      38             : */
+      39             : class AtomNumber {
+      40             :   unsigned index_;
+      41             : /// Construct with a given index.
+      42             : /// This constructor is kept private to avoid implicit cast.
+      43             :   explicit AtomNumber(unsigned);
+      44             : public:
+      45             : /// Initialize to index=0 (serial=1)
+      46             :   AtomNumber();
+      47             : /// Returns the serial number
+      48             :   unsigned serial()const;
+      49             : /// Returns the index number
+      50             :   unsigned index()const;
+      51             : /// Sets the atom number by serial, returning a reference to the AtomNumber itself.
+      52             :   AtomNumber & setSerial(unsigned);
+      53             : /// Sets the atom number by index, returning a reference to the AtomNumber itself.
+      54             :   AtomNumber & setIndex(unsigned);
+      55             : /// Returns an AtomNumber with a specified serial.
+      56             :   static AtomNumber serial(unsigned);
+      57             : /// Returns an AtomNumber with a specified index.
+      58             :   static AtomNumber index(unsigned);
+      59             : /// Comparison operators
+      60             :   friend bool operator<(const AtomNumber&,const AtomNumber&);
+      61             : /// Comparison operators
+      62             :   friend bool operator>(const AtomNumber&,const AtomNumber&);
+      63             : /// Comparison operators
+      64             :   friend bool operator<=(const AtomNumber&,const AtomNumber&);
+      65             : /// Comparison operators
+      66             :   friend bool operator>=(const AtomNumber&,const AtomNumber&);
+      67             : /// Comparison operators
+      68             :   friend bool operator==(const AtomNumber&,const AtomNumber&);
+      69             : /// Comparison operators
+      70             :   friend bool operator!=(const AtomNumber&,const AtomNumber&);
+      71             : };
+      72             : 
+      73             : inline
+      74     1599073 : AtomNumber::AtomNumber() {
+      75     1599025 :   index_=0;
+      76             : }
+      77             : 
+      78             : inline
+      79             : AtomNumber::AtomNumber(unsigned i) {
+      80             :   index_=i;
+      81             : }
+      82             : 
+      83             : inline
+      84             : unsigned AtomNumber::serial()const {
+      85      582941 :   return index_+1;
+      86             : }
+      87             : 
+      88             : inline
+      89             : unsigned AtomNumber::index()const {
+      90    24349715 :   return index_;
+      91             : }
+      92             : 
+      93             : inline
+      94      902703 : AtomNumber & AtomNumber::setSerial(unsigned i) {
+      95      902703 :   plumed_massert(i>0,"serial of an atom cannot be zero");
+      96      902703 :   plumed_massert(i<std::numeric_limits<unsigned>::max()/2,"serial cannot be negative");
+      97      902703 :   index_=i-1;
+      98      902703 :   return *this;
+      99             : }
+     100             : 
+     101             : inline
+     102             : AtomNumber & AtomNumber::setIndex(unsigned i) {
+     103          56 :   index_=i;
+     104             :   return *this;
+     105             : }
+     106             : 
+     107             : inline
+     108         348 : AtomNumber AtomNumber::serial(unsigned i) {
+     109         348 :   plumed_massert(i>0,"serial of an atom cannot be zero");
+     110         348 :   plumed_massert(i<std::numeric_limits<unsigned>::max()/2,"serial cannot be negative");
+     111         348 :   return AtomNumber(i-1);
+     112             : }
+     113             : 
+     114             : inline
+     115             : AtomNumber AtomNumber::index(unsigned i) {
+     116             :   return AtomNumber(i);
+     117             : }
+     118             : 
+     119             : inline
+     120             : bool operator<(const AtomNumber&a,const AtomNumber&b) {
+     121   375827180 :   return a.index_<b.index_;
+     122             : }
+     123             : 
+     124             : inline
+     125             : bool operator>(const AtomNumber&a,const AtomNumber&b) {
+     126      811901 :   return a.index_>b.index_;
+     127             : }
+     128             : 
+     129             : inline
+     130             : bool operator<=(const AtomNumber&a,const AtomNumber&b) {
+     131             :   return a.index_<=b.index_;
+     132             : }
+     133             : 
+     134             : inline
+     135             : bool operator>=(const AtomNumber&a,const AtomNumber&b) {
+     136             :   return a.index_>=b.index_;
+     137             : }
+     138             : 
+     139             : inline
+     140             : bool operator==(const AtomNumber&a,const AtomNumber&b) {
+     141   172596672 :   return a.index_==b.index_;
+     142             : }
+     143             : 
+     144             : inline
+     145             : bool operator!=(const AtomNumber&a,const AtomNumber&b) {
+     146   117933074 :   return a.index_!=b.index_;
+     147             : }
+     148             : 
+     149             : }
+     150             : 
+     151             : #endif
+     152             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/BiasRepresentation.cpp.func-sort-c.html b/coverage/tools/BiasRepresentation.cpp.func-sort-c.html new file mode 100644 index 000000000000..0936330534c3 --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.func-sort-c.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - tools/BiasRepresentation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - BiasRepresentation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12917075.9 %
Date:2024-02-22 21:58:45Functions:121963.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18BiasRepresentation13getPtrToValueEj0
_ZN4PLMD18BiasRepresentation14getPtrToValuesEv0
_ZN4PLMD18BiasRepresentation16isRescaledToBiasEv0
_ZN4PLMD18BiasRepresentation21getNumberOfDimensionsEv0
_ZN4PLMD18BiasRepresentation5clearEv0
_ZN4PLMD18BiasRepresentation7getNameB5cxx11Ej0
_ZN4PLMD18BiasRepresentation8getNamesB5cxx11Ev0
_ZN4PLMD18BiasRepresentation17setRescaledToBiasEb1
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESJ_RKS1_IjSaIjEERKS1_IdSaIdEE1
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_IdSaIdEE1
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorE4
_ZN4PLMD18BiasRepresentation12getMinMaxBinERSt6vectorIdSaIdEES4_RS1_IjSaIjEE5
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESJ_RKS1_IjSaIjEEbdd8
_ZN4PLMD18BiasRepresentation7addGridERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EESB_RKS1_IjSaIjEE9
_ZN4PLMD18BiasRepresentation10getGridPtrEv10
_ZN4PLMD18BiasRepresentation13readFromPointEPNS_5IFileE1092
_ZN4PLMD18BiasRepresentation10pushKernelEPNS_5IFileE5563
_ZN4PLMD18BiasRepresentation15hasSigmaInInputEv5563
_ZN4PLMD18BiasRepresentation18getNumberOfKernelsEv5578
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/BiasRepresentation.cpp.func.html b/coverage/tools/BiasRepresentation.cpp.func.html new file mode 100644 index 000000000000..44c3d5581b68 --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.func.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - tools/BiasRepresentation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - BiasRepresentation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12917075.9 %
Date:2024-02-22 21:58:45Functions:121963.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD18BiasRepresentation10getGridPtrEv10
_ZN4PLMD18BiasRepresentation10pushKernelEPNS_5IFileE5563
_ZN4PLMD18BiasRepresentation12getMinMaxBinERSt6vectorIdSaIdEES4_RS1_IjSaIjEE5
_ZN4PLMD18BiasRepresentation13getPtrToValueEj0
_ZN4PLMD18BiasRepresentation13readFromPointEPNS_5IFileE1092
_ZN4PLMD18BiasRepresentation14getPtrToValuesEv0
_ZN4PLMD18BiasRepresentation15hasSigmaInInputEv5563
_ZN4PLMD18BiasRepresentation16isRescaledToBiasEv0
_ZN4PLMD18BiasRepresentation17setRescaledToBiasEb1
_ZN4PLMD18BiasRepresentation18getNumberOfKernelsEv5578
_ZN4PLMD18BiasRepresentation21getNumberOfDimensionsEv0
_ZN4PLMD18BiasRepresentation5clearEv0
_ZN4PLMD18BiasRepresentation7addGridERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EESB_RKS1_IjSaIjEE9
_ZN4PLMD18BiasRepresentation7getNameB5cxx11Ej0
_ZN4PLMD18BiasRepresentation8getNamesB5cxx11Ev0
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorE4
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESJ_RKS1_IjSaIjEERKS1_IdSaIdEE1
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISF_EESJ_RKS1_IjSaIjEEbdd8
_ZN4PLMD18BiasRepresentationC2ERKSt6vectorIPNS_5ValueESaIS3_EERNS_12CommunicatorERKS1_IdSaIdEE1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/BiasRepresentation.cpp.gcov.html b/coverage/tools/BiasRepresentation.cpp.gcov.html new file mode 100644 index 000000000000..0565dcb18a88 --- /dev/null +++ b/coverage/tools/BiasRepresentation.cpp.gcov.html @@ -0,0 +1,364 @@ + + + + + + + + LCOV - plumed test coverage - tools/BiasRepresentation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - BiasRepresentation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12917075.9 %
Date:2024-02-22 21:58:45Functions:121963.2 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "BiasRepresentation.h"
+      23             : #include "core/Value.h"
+      24             : #include "Communicator.h"
+      25             : #include <iostream>
+      26             : #include "KernelFunctions.h"
+      27             : #include "File.h"
+      28             : #include "Grid.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : /// the constructor here
+      33           4 : BiasRepresentation::BiasRepresentation(const std::vector<Value*> & tmpvalues, Communicator &cc ):hasgrid(false),rescaledToBias(false),mycomm(cc) {
+      34           4 :   lowI_=0.0;
+      35           4 :   uppI_=0.0;
+      36           4 :   doInt_=false;
+      37           4 :   ndim=tmpvalues.size();
+      38          12 :   for(int i=0; i<ndim; i++) {
+      39           8 :     values.push_back(tmpvalues[i]);
+      40           8 :     names.push_back(values[i]->getName());
+      41             :   }
+      42           4 : }
+      43             : 
+      44             : /// overload the constructor: add the sigma  at constructor time
+      45           1 : BiasRepresentation::BiasRepresentation(const std::vector<Value*> & tmpvalues, Communicator &cc, const std::vector<double> & sigma ):
+      46           1 :   hasgrid(false), rescaledToBias(false), histosigma(sigma),mycomm(cc)
+      47             : {
+      48           1 :   lowI_=0.0;
+      49           1 :   uppI_=0.0;
+      50           1 :   doInt_=false;
+      51           1 :   ndim=tmpvalues.size();
+      52           3 :   for(int i=0; i<ndim; i++) {
+      53           2 :     values.push_back(tmpvalues[i]);
+      54           2 :     names.push_back(values[i]->getName());
+      55             :   }
+      56           1 : }
+      57             : 
+      58             : /// overload the constructor: add the grid at constructor time
+      59           8 : BiasRepresentation::BiasRepresentation(const std::vector<Value*> & tmpvalues, Communicator &cc, const std::vector<std::string> & gmin, const std::vector<std::string> & gmax,
+      60           8 :                                        const std::vector<unsigned> & nbin, bool doInt, double lowI, double uppI):
+      61           8 :   hasgrid(false), rescaledToBias(false), mycomm(cc)
+      62             : {
+      63           8 :   ndim=tmpvalues.size();
+      64          23 :   for(int i=0; i<ndim; i++) {
+      65          15 :     values.push_back(tmpvalues[i]);
+      66          15 :     names.push_back(values[i]->getName());
+      67             :   }
+      68           8 :   doInt_=doInt;
+      69           8 :   lowI_=lowI;
+      70           8 :   uppI_=uppI;
+      71             :   // initialize the grid
+      72           8 :   addGrid(gmin,gmax,nbin);
+      73           8 : }
+      74             : 
+      75             : /// overload the constructor with some external sigmas: needed for histogram
+      76           1 : BiasRepresentation::BiasRepresentation(const std::vector<Value*> & tmpvalues, Communicator &cc, const std::vector<std::string> & gmin, const std::vector<std::string> & gmax,
+      77           1 :                                        const std::vector<unsigned> & nbin, const std::vector<double> & sigma):
+      78           1 :   hasgrid(false), rescaledToBias(false),histosigma(sigma),mycomm(cc)
+      79             : {
+      80           1 :   lowI_=0.0;
+      81           1 :   uppI_=0.0;
+      82           1 :   doInt_=false;
+      83           1 :   ndim=tmpvalues.size();
+      84           3 :   for(int  i=0; i<ndim; i++) {
+      85           2 :     values.push_back(tmpvalues[i]);
+      86           2 :     names.push_back(values[i]->getName());
+      87             :   }
+      88             :   // initialize the grid
+      89           1 :   addGrid(gmin,gmax,nbin);
+      90           1 : }
+      91             : 
+      92           9 : void BiasRepresentation::addGrid(const std::vector<std::string> & gmin, const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin ) {
+      93           9 :   plumed_massert(hills.size()==0,"you can set the grid before loading the hills");
+      94           9 :   plumed_massert(hasgrid==false,"to build the grid you should not having the grid in this bias representation");
+      95             :   std::string ss; ss="file.free";
+      96          26 :   std::vector<Value*> vv; for(unsigned i=0; i<values.size(); i++) vv.push_back(values[i]);
+      97          18 :   BiasGrid_=Tools::make_unique<Grid>(ss,vv,gmin,gmax,nbin,false,true);
+      98           9 :   hasgrid=true;
+      99           9 : }
+     100             : 
+     101        5563 : bool BiasRepresentation::hasSigmaInInput() {
+     102        5563 :   if(histosigma.size()==0) {return false;} else {return true;}
+     103             : }
+     104             : 
+     105           1 : void BiasRepresentation::setRescaledToBias(bool rescaled) {
+     106           1 :   plumed_massert(hills.size()==0,"you can set the rescaling function only before loading hills");
+     107           1 :   rescaledToBias=rescaled;
+     108           1 : }
+     109             : 
+     110           0 : const bool & BiasRepresentation::isRescaledToBias() {
+     111           0 :   return rescaledToBias;
+     112             : }
+     113             : 
+     114           0 : unsigned BiasRepresentation::getNumberOfDimensions() {
+     115           0 :   return values.size();
+     116             : }
+     117             : 
+     118           0 : std::vector<std::string> BiasRepresentation::getNames() {
+     119           0 :   return names;
+     120             : }
+     121             : 
+     122           0 : const std::string & BiasRepresentation::getName(unsigned i) {
+     123           0 :   return names[i];
+     124             : }
+     125             : 
+     126           0 : const std::vector<Value*>& BiasRepresentation::getPtrToValues() {
+     127           0 :   return values;
+     128             : }
+     129             : 
+     130           0 : Value*  BiasRepresentation::getPtrToValue(unsigned i) {
+     131           0 :   return values[i];
+     132             : }
+     133             : 
+     134        1092 : std::unique_ptr<KernelFunctions> BiasRepresentation::readFromPoint(IFile *ifile) {
+     135        1092 :   std::vector<double> cc( names.size() );
+     136        3276 :   for(unsigned i=0; i<names.size(); ++i) {
+     137        2184 :     ifile->scanField(names[i],cc[i]);
+     138             :   }
+     139        1092 :   double h=1.0;
+     140        2184 :   return Tools::make_unique<KernelFunctions>(cc,histosigma,"stretched-gaussian","DIAGONAL",h);
+     141             : }
+     142             : 
+     143        5563 : void BiasRepresentation::pushKernel( IFile *ifile ) {
+     144        5563 :   std::unique_ptr<KernelFunctions> kk;
+     145             :   // here below the reading of the kernel is completely hidden
+     146        5563 :   if(histosigma.size()==0) {
+     147        4471 :     ifile->allowIgnoredFields();
+     148        8942 :     kk=KernelFunctions::read(ifile,true,names);
+     149             :   } else {
+     150             :     // when doing histogram assume gaussian with a given diagonal sigma
+     151             :     // and neglect all the rest
+     152        2184 :     kk=readFromPoint(ifile);
+     153             :   }
+     154             :   // the bias factor is not something about the kernels but
+     155             :   // must be stored to keep the  bias/free energy duality
+     156             :   std::string dummy; double dummyd;
+     157       11126 :   if(ifile->FieldExist("biasf")) {
+     158        5563 :     ifile->scanField("biasf",dummy);
+     159        5563 :     Tools::convert(dummy,dummyd);
+     160           0 :   } else {dummyd=1.0;}
+     161        5563 :   biasf.push_back(dummyd);
+     162             :   // the domain does not pertain to the kernel but to the values here defined
+     163             :   std::string mins,maxs,minv,maxv,mini,maxi; mins="min_"; maxs="max_";
+     164       16688 :   for(int i=0 ; i<ndim; i++) {
+     165       11125 :     if(values[i]->isPeriodic()) {
+     166       22216 :       ifile->scanField(mins+names[i],minv);
+     167       22216 :       ifile->scanField(maxs+names[i],maxv);
+     168             :       // verify that the domain is correct
+     169       11108 :       values[i]->getDomain(mini,maxi);
+     170       11108 :       plumed_massert(mini==minv,"the input periodicity in hills and in value definition does not match"  );
+     171       11108 :       plumed_massert(maxi==maxv,"the input periodicity in hills and in value definition does not match"  );
+     172             :     }
+     173             :   }
+     174             :   // if grid is defined then it should be added on the grid
+     175             :   //cerr<<"now with "<<hills.size()<<endl;
+     176        5563 :   if(hasgrid) {
+     177             :     std::vector<unsigned> nneighb;
+     178        3375 :     if(doInt_&&(kk->getCenter()[0]+kk->getContinuousSupport()[0] > uppI_ || kk->getCenter()[0]-kk->getContinuousSupport()[0] < lowI_ )) {
+     179           0 :       nneighb=BiasGrid_->getNbin();
+     180        6750 :     } else nneighb=kk->getSupport(BiasGrid_->getDx());
+     181        3375 :     std::vector<Grid::index_t> neighbors=BiasGrid_->getNeighbors(kk->getCenter(),nneighb);
+     182        3375 :     std::vector<double> der(ndim);
+     183        3375 :     std::vector<double> xx(ndim);
+     184        3375 :     if(mycomm.Get_size()==1) {
+     185     1027680 :       for(unsigned i=0; i<neighbors.size(); ++i) {
+     186     1024305 :         Grid::index_t ineigh=neighbors[i];
+     187     3072823 :         for(int j=0; j<ndim; ++j) {der[j]=0.0;}
+     188     1024305 :         BiasGrid_->getPoint(ineigh,xx);
+     189             :         // assign xx to a new vector of values
+     190     3072823 :         for(int j=0; j<ndim; ++j) {values[j]->set(xx[j]);}
+     191             :         double bias;
+     192     1024305 :         if(doInt_) bias=kk->evaluate(values,der,true,doInt_,lowI_,uppI_);
+     193     1024305 :         else bias=kk->evaluate(values,der,true);
+     194     1024305 :         if(rescaledToBias) {
+     195       45234 :           double f=(biasf.back()-1.)/(biasf.back());
+     196       45234 :           bias*=f;
+     197      135702 :           for(int j=0; j<ndim; ++j) {der[j]*=f;}
+     198             :         }
+     199     1024305 :         BiasGrid_->addValueAndDerivatives(ineigh,bias,der);
+     200             :       }
+     201             :     } else {
+     202           0 :       unsigned stride=mycomm.Get_size();
+     203           0 :       unsigned rank=mycomm.Get_rank();
+     204           0 :       std::vector<double> allder(ndim*neighbors.size(),0.0);
+     205           0 :       std::vector<double> allbias(neighbors.size(),0.0);
+     206           0 :       std::vector<double> tmpder(ndim);
+     207           0 :       for(unsigned i=rank; i<neighbors.size(); i+=stride) {
+     208           0 :         Grid::index_t ineigh=neighbors[i];
+     209           0 :         BiasGrid_->getPoint(ineigh,xx);
+     210           0 :         for(int j=0; j<ndim; ++j) {values[j]->set(xx[j]);}
+     211           0 :         if(doInt_) allbias[i]=kk->evaluate(values,der,true,doInt_,lowI_,uppI_);
+     212           0 :         else allbias[i]=kk->evaluate(values,der,true);
+     213           0 :         if(rescaledToBias) {
+     214           0 :           double f=(biasf.back()-1.)/(biasf.back());
+     215           0 :           allbias[i]*=f;
+     216           0 :           for(int j=0; j<ndim; ++j) {tmpder[j]*=f;}
+     217             :         }
+     218             :         // this solution with the temporary vector is rather bad, probably better to take
+     219             :         // a pointer of double as it was in old gaussian
+     220           0 :         for(int j=0; j<ndim; ++j) { allder[ndim*i+j]=tmpder[j]; tmpder[j]=0.;}
+     221             :       }
+     222           0 :       mycomm.Sum(allbias);
+     223           0 :       mycomm.Sum(allder);
+     224           0 :       for(unsigned i=0; i<neighbors.size(); ++i) {
+     225           0 :         Grid::index_t ineigh=neighbors[i];
+     226           0 :         for(int j=0; j<ndim; ++j) {der[j]=allder[ndim*i+j];}
+     227           0 :         BiasGrid_->addValueAndDerivatives(ineigh,allbias[i],der);
+     228             :       }
+     229             :     }
+     230             :   }
+     231        5563 :   hills.emplace_back(std::move(kk));
+     232        5563 : }
+     233             : 
+     234        5578 : int BiasRepresentation::getNumberOfKernels() {
+     235        5578 :   return hills.size();
+     236             : }
+     237             : 
+     238          10 : Grid* BiasRepresentation::getGridPtr() {
+     239          10 :   plumed_massert(hasgrid,"if you want the grid pointer then you should have defined a grid before");
+     240          10 :   return BiasGrid_.get();
+     241             : }
+     242             : 
+     243           5 : void BiasRepresentation::getMinMaxBin(std::vector<double> &vmin, std::vector<double> &vmax, std::vector<unsigned> &vbin) {
+     244             :   std::vector<double> ss,cc,binsize;
+     245           5 :   vmin.clear(); vmin.resize(ndim,10.e20);
+     246           5 :   vmax.clear(); vmax.resize(ndim,-10.e20);
+     247           5 :   vbin.clear(); vbin.resize(ndim);
+     248           5 :   binsize.clear(); binsize.resize(ndim,10.e20);
+     249             :   int ndiv=10; // adjustable parameter: division per support
+     250        2193 :   for(unsigned i=0; i<hills.size(); i++) {
+     251        2188 :     if(histosigma.size()!=0) {
+     252         546 :       ss=histosigma;
+     253             :     } else {
+     254        3284 :       ss=hills[i]->getContinuousSupport();
+     255             :     }
+     256        2188 :     cc=hills[i]->getCenter();
+     257        6564 :     for(int j=0; j<ndim; j++) {
+     258        4376 :       double dmin=cc[j]-ss[j];
+     259        4376 :       double dmax=cc[j]+ss[j];
+     260        4376 :       double ddiv=ss[j]/double(ndiv);
+     261        4376 :       if(dmin<vmin[j])vmin[j]=dmin;
+     262        4376 :       if(dmax>vmax[j])vmax[j]=dmax;
+     263        4376 :       if(ddiv<binsize[j])binsize[j]=ddiv;
+     264             :     }
+     265             :   }
+     266          15 :   for(int j=0; j<ndim; j++) {
+     267             :     // reset to periodicity
+     268          10 :     if(values[j]->isPeriodic()) {
+     269             :       double minv,maxv;
+     270           8 :       values[j]->getDomain(minv,maxv);
+     271           8 :       if(minv>vmin[j])vmin[j]=minv;
+     272           8 :       if(maxv<vmax[j])vmax[j]=maxv;
+     273             :     }
+     274          10 :     vbin[j]=static_cast<unsigned>(std::ceil((vmax[j]-vmin[j])/binsize[j]) );
+     275             :   }
+     276           5 : }
+     277             : 
+     278           0 : void BiasRepresentation::clear() {
+     279           0 :   hills.clear();
+     280             :   // clear the grid
+     281           0 :   if(hasgrid) {
+     282           0 :     BiasGrid_->clear();
+     283             :   }
+     284           0 : }
+     285             : 
+     286             : 
+     287             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Brent1DRootSearch.h.func-sort-c.html b/coverage/tools/Brent1DRootSearch.h.func-sort-c.html new file mode 100644 index 000000000000..8481c427c46b --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/Brent1DRootSearch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Brent1DRootSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:383997.4 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_4GridEEEE6searchEMS3_FdRKdE0
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_4GridEEEE7bracketERKdS6_MS3_FdS6_E0
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_4GridEEEEC2ERKS3_RKd0
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_11multicolvar19DistanceFromContourEEEE6searchEMS4_FdRKdE274
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_11multicolvar19DistanceFromContourEEEE7bracketERKdS7_MS4_FdS7_E274
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_11multicolvar19DistanceFromContourEEEEC2ERKS4_RKd274
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_9gridtools18ContourFindingBaseEEEE6searchEMS4_FdRKdE1242
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_9gridtools18ContourFindingBaseEEEE7bracketERKdS7_MS4_FdS7_E1242
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_9gridtools18ContourFindingBaseEEEEC2ERKS4_RKd1242
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Brent1DRootSearch.h.func.html b/coverage/tools/Brent1DRootSearch.h.func.html new file mode 100644 index 000000000000..cf465414b1bc --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/Brent1DRootSearch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Brent1DRootSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:383997.4 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_11multicolvar19DistanceFromContourEEEE6searchEMS4_FdRKdE274
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_11multicolvar19DistanceFromContourEEEE7bracketERKdS7_MS4_FdS7_E274
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_11multicolvar19DistanceFromContourEEEEC2ERKS4_RKd274
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_4GridEEEE6searchEMS3_FdRKdE0
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_4GridEEEE7bracketERKdS6_MS3_FdS6_E0
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_4GridEEEEC2ERKS3_RKd0
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_9gridtools18ContourFindingBaseEEEE6searchEMS4_FdRKdE1242
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_9gridtools18ContourFindingBaseEEEE7bracketERKdS7_MS4_FdS7_E1242
_ZN4PLMD17Brent1DRootSearchINS_5F1dimINS_9gridtools18ContourFindingBaseEEEEC2ERKS4_RKd1242
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Brent1DRootSearch.h.gcov.html b/coverage/tools/Brent1DRootSearch.h.gcov.html new file mode 100644 index 000000000000..3e2879830c5f --- /dev/null +++ b/coverage/tools/Brent1DRootSearch.h.gcov.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage - tools/Brent1DRootSearch.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Brent1DRootSearch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:383997.4 %
Date:2024-02-22 21:58:45Functions:6966.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Brent1DRootSearch_h
+      23             : #define __PLUMED_tools_Brent1DRootSearch_h
+      24             : 
+      25             : #include "Tools.h"
+      26             : 
+      27             : #include <vector>
+      28             : #include <string>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : /// A class for doing parabolic interpolation and minimisation of
+      33             : /// 1D functions using Brent's method.
+      34             : template <class FCLASS>
+      35        1516 : class Brent1DRootSearch {
+      36             : private:
+      37             : /// Has the minimum been bracketed
+      38             :   bool bracketed;
+      39             : /// The tolerance for the line minimiser
+      40             :   double tol;
+      41             : /// Maximum number of interactions in line minimiser
+      42             :   const unsigned ITMAX;
+      43             : /// A small number that protects against trying to achieve fractional
+      44             : /// accuracy for a minimum that happens to be exactly zero
+      45             :   const double EPS;
+      46             : /// The factor by which to expand the range when bracketing
+      47             :   const double EXPAND;
+      48             : /// This is the type specifier for the function to minimise
+      49             :   typedef double(FCLASS::*eng_pointer)( const double& val );
+      50             : /// Three points bracketting the minimum and the corresponding function values
+      51             :   double ax,bx,fa,fb;
+      52             : /// The class containing the function we are trying to minimise
+      53             :   FCLASS myclass_func;
+      54             : public:
+      55        1516 :   explicit Brent1DRootSearch( const FCLASS& pf,  const double& t=3.0E-8 );
+      56             : /// Bracket the minium
+      57             :   void bracket( const double& ax, const double& xx, eng_pointer eng );
+      58             : /// Find the minimum between two brackets
+      59             :   double search( eng_pointer eng );
+      60             : };
+      61             : 
+      62             : template <class FCLASS>
+      63        1516 : Brent1DRootSearch<FCLASS>::Brent1DRootSearch( const FCLASS& pf, const double& t ):
+      64        1516 :   bracketed(false),
+      65        1516 :   tol(t),
+      66        1516 :   ITMAX(100),
+      67        1516 :   EPS(3.0E-8),
+      68        1516 :   EXPAND(1.6),
+      69        1516 :   ax(0), bx(0),
+      70        1516 :   fa(0), fb(0),
+      71        1516 :   myclass_func(pf)
+      72             : {
+      73        1516 : }
+      74             : 
+      75             : template <class FCLASS>
+      76        1516 : void Brent1DRootSearch<FCLASS>::bracket( const double& a, const double& b, eng_pointer eng ) {
+      77        1516 :   plumed_assert( a!=b ); ax=a; bx=b; fa=(myclass_func.*eng)(a); fb=(myclass_func.*eng)(b);
+      78        1516 :   if ((fa > 0.0 && fb > 0.0) || (fa < 0.0 && fb < 0.0)) plumed_merror("input points do not bracket root");
+      79        1516 :   bracketed=true;
+      80        1516 : }
+      81             : 
+      82             : template <class FCLASS>
+      83        1516 : double Brent1DRootSearch<FCLASS>::search( eng_pointer eng ) {
+      84             :   plumed_dbg_assert( bracketed );
+      85             : 
+      86        1516 :   double cx=bx, d, e, min1, min2, fc=fb, p, q, r, s, tol1, xm;
+      87        8930 :   for(unsigned iter=0; iter<ITMAX; iter++) {
+      88        8930 :     if ( (fb>0.0 && fc>0.0) || (fb<0.0 && fc<0.0) ) { cx=ax; fc=fa; e=d=bx-ax; }
+      89        8930 :     if( std::fabs(fc) < std::fabs(fb) ) { ax=bx; bx=cx; cx=ax; fa=fb; fb=fc; fc=fa; }
+      90        8930 :     tol1=2*EPS*std::fabs(bx)+0.5*tol; xm=0.5*(cx-bx);
+      91        8930 :     if( std::fabs(xm) <= tol1 || fb == 0.0 ) return bx;
+      92        7414 :     if( std::fabs(e) >= tol1 && std::fabs(fa) > std::fabs(fb) ) {
+      93        7350 :       s=fb/fa;
+      94        7350 :       if( ax==cx ) {
+      95        5194 :         p=2.0*xm*s; q=1.0-s;
+      96             :       } else {
+      97        2156 :         q=fa/fc; r=fb/fc; p=s*(2.0*xm*q*(q-r)-(bx-ax)*(r-1.0)); q=(q-1.0)*(r-1.0)*(s-1.0);
+      98             :       }
+      99        7350 :       if (p > 0.0) q = -q;
+     100        7350 :       p=std::fabs(p); min1=3.0*xm*q-std::fabs(tol1*q); min2=std::fabs(e*q);
+     101       14276 :       if (2.0*p < (min1 < min2 ? min1 : min2)) {
+     102        7091 :         e=d; d=p/q;
+     103             :       } else {
+     104             :         d=xm; e=d;
+     105             :       }
+     106             :     } else {
+     107             :       d=xm; e=d;
+     108             :     }
+     109        7414 :     ax=bx; fa=fb;
+     110        7414 :     if( std::fabs(d) > tol1 ) bx+=d;
+     111        1427 :     else if(xm<0 ) bx -= std::fabs(tol1); // SIGN(tol1,xm);
+     112         699 :     else bx += tol1;
+     113        7414 :     fb = (myclass_func.*eng)(bx);
+     114             :   }
+     115             : 
+     116           0 :   plumed_merror("Too many interactions in zbrent");
+     117             : }
+     118             : 
+     119             : }
+     120             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.cpp.func-sort-c.html b/coverage/tools/Citations.cpp.func-sort-c.html new file mode 100644 index 000000000000..6c9739df31c3 --- /dev/null +++ b/coverage/tools/Citations.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsERSoRKNS_9CitationsE1013
_ZN4PLMD9Citations4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3802
_ZNK4PLMD9Citations5emptyEv7868
_ZN4PLMD9Citations5clearEv7908
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.cpp.func.html b/coverage/tools/Citations.cpp.func.html new file mode 100644 index 000000000000..87fe0f10ef2f --- /dev/null +++ b/coverage/tools/Citations.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Citations4citeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3802
_ZN4PLMD9Citations5clearEv7908
_ZN4PLMDlsERSoRKNS_9CitationsE1013
_ZNK4PLMD9Citations5emptyEv7868
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.cpp.gcov.html b/coverage/tools/Citations.cpp.gcov.html new file mode 100644 index 000000000000..bc910545145e --- /dev/null +++ b/coverage/tools/Citations.cpp.gcov.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Citations.h"
+      23             : #include "Exception.h"
+      24             : #include "Tools.h"
+      25             : #include <iostream>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29        3802 : std::string Citations::cite(const std::string & item) {
+      30             :   unsigned i;
+      31       10466 :   for(i=0; i<items.size(); ++i) if(items[i]==item) break;
+      32        3802 :   if(i==items.size()) items.push_back(item);
+      33        3802 :   plumed_assert(i<items.size());
+      34             :   std::string ret;
+      35        3802 :   Tools::convert(i+1,ret);
+      36        7604 :   ret="["+ret+"]";
+      37        3802 :   return ret;
+      38             : }
+      39             : 
+      40        1013 : std::ostream & operator<<(std::ostream &log,const Citations&cit) {
+      41        4155 :   for(unsigned i=0; i<cit.items.size(); ++i)
+      42        6284 :     log<<"  ["<<i+1<<"] "<<cit.items[i]<<"\n";
+      43        1013 :   return log;
+      44             : }
+      45             : 
+      46        7908 : void Citations::clear() {
+      47        7908 :   items.clear();
+      48        7908 : }
+      49             : 
+      50        7868 : bool Citations::empty()const {
+      51        7868 :   return items.empty();
+      52             : }
+      53             : 
+      54             : }
+      55             : 
+      56             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.h.func-sort-c.html b/coverage/tools/Citations.h.func-sort-c.html new file mode 100644 index 000000000000..f97590b838ae --- /dev/null +++ b/coverage/tools/Citations.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.h.func.html b/coverage/tools/Citations.h.func.html new file mode 100644 index 000000000000..0fc4de009b2d --- /dev/null +++ b/coverage/tools/Citations.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Citations.h.gcov.html b/coverage/tools/Citations.h.gcov.html new file mode 100644 index 000000000000..a62844e9bceb --- /dev/null +++ b/coverage/tools/Citations.h.gcov.html @@ -0,0 +1,151 @@ + + + + + + + + LCOV - plumed test coverage - tools/Citations.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Citations.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Citations_h
+      23             : #define __PLUMED_tools_Citations_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <string>
+      27             : #include <iosfwd>
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : /**
+      32             : \ingroup TOOLBOX
+      33             : Class taking care of bibliography.
+      34             : 
+      35             : This class contains a vector of citations. To add a new citations, use cite(). To print
+      36             : the entire bibliography, just dump on a ostream. Everytime cite is used, a string
+      37             : containing the number of the citation is returned. If the same citation is added twice,
+      38             : the same string is returned, so that this example will produce only two bibliographic items:
+      39             : \verbatim
+      40             : #include "Citations.h"
+      41             : #include <iostream>
+      42             : int main(int argc,char**argv){
+      43             :   PLMD::Citations citations;
+      44             :   std::cout << citations.cite("Pinco e Pallino, Il Piccolo 33, 444 (2012)") << "\n";
+      45             :   std::cout << citations.cite("Other cite") << "\n";
+      46             :   std::cout << citations.cite("Pinco e Pallino, Il Piccolo 33, 444 (2012)") << "\n";
+      47             : 
+      48             :   std::cout << "Bibliography\n"<< citations;
+      49             :   return 0;
+      50             : }
+      51             : \endverbatim
+      52             : */
+      53             : 
+      54      805283 : class Citations {
+      55             :   std::vector<std::string> items;
+      56             : public:
+      57             : /// Add a citation.
+      58             : /// It returns a string containing the reference number, something like "[10]"
+      59             :   std::string cite(const std::string &);
+      60             : /// Dumps the bibliography.
+      61             : /// It writes on the ostream the list of all the bibliographic items
+      62             : /// prefixed with their reference number
+      63             :   friend std::ostream &operator<<(std::ostream &,const Citations&);
+      64             : /// Delete all references
+      65             :   void clear();
+      66             : /// Check if bibliography is empty
+      67             :   bool empty()const;
+      68             : };
+      69             : 
+      70             : std::ostream & operator<<(std::ostream &,const Citations&);
+      71             : 
+      72             : }
+      73             : 
+      74             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.cpp.func-sort-c.html b/coverage/tools/Communicator.cpp.func-sort-c.html new file mode 100644 index 000000000000..fbc0edf6ab9f --- /dev/null +++ b/coverage/tools/Communicator.cpp.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-02-22 21:58:45Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator10getMPITypeIeEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIfEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator5AbortEi0
_ZN4PLMD12Communicator9Set_fcommERKNS_11TypesafePtrE0
_ZN4PLMD12CommunicatorC2ERKS0_0
_ZN4PLMD12CommunicatoraSERKS0_0
_ZN4PLMD12Communicator3MinENS0_4DataE3
_ZN4PLMD12Communicator4ProdENS0_4DataE3
_ZN4PLMD12Communicator10getMPITypeIyEEP15ompi_datatype_tv6
_ZN4PLMD12Communicator10getMPITypeINS_10AtomNumberEEEP15ompi_datatype_tv8
_ZN4PLMD12Communicator12plumedHasMPIEv54
_ZN4PLMD12Communicator3MaxENS0_4DataE155
_ZN4PLMD12Communicator10getMPITypeIcEEP15ompi_datatype_tv295
_ZNK4PLMD12Communicator5SplitEiiRS0_406
_ZN4PLMD12Communicator8Set_commERKNS_11TypesafePtrE1203
_ZN4PLMD12Communicator8Get_commEv1722
_ZN4PLMD12Communicator8Set_commEP19ompi_communicator_t2222
_ZN4PLMD12Communicator9AllgatherENS0_9ConstDataENS0_4DataE5838
_ZNK4PLMD12Communicator6Status9Get_countEP15ompi_datatype_t7587
_ZN4PLMD12Communicator7Request4waitERNS0_6StatusE14898
_ZN4PLMD12Communicator4RecvENS0_4DataEiiRNS0_6StatusE15298
_ZN4PLMD12Communicator5IsendENS0_9ConstDataEii15298
_ZN4PLMD12Communicator10AllgathervENS0_9ConstDataENS0_4DataEPKiS4_19063
_ZN4PLMD12Communicator10getMPITypeIjEEP15ompi_datatype_tv43109
_ZN4PLMD12Communicator10getMPITypeIiEEP15ompi_datatype_tv67196
_ZN4PLMD12CommunicatorD0Ev1615202
_ZN4PLMD12CommunicatorC2Ev1617913
_ZN4PLMD12CommunicatorD2Ev1617913
_ZNK4PLMD12Communicator8Get_sizeEv2337533
_ZN4PLMD12Communicator3SumENS0_4DataE4280794
_ZN4PLMD12Communicator10getMPITypeIdEEP15ompi_datatype_tv4552423
_ZN4PLMD12Communicator10getMPITypeImEEP15ompi_datatype_tv4666369
_ZNK4PLMD12Communicator7BarrierEv4671787
_ZN4PLMD12Communicator5BcastENS0_4DataEi4960466
_ZNK4PLMD12Communicator8Get_rankEv6815455
_ZN4PLMD12Communicator11initializedEv24771376
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.cpp.func.html b/coverage/tools/Communicator.cpp.func.html new file mode 100644 index 000000000000..0639b71cccfd --- /dev/null +++ b/coverage/tools/Communicator.cpp.func.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-02-22 21:58:45Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator10AllgathervENS0_9ConstDataENS0_4DataEPKiS4_19063
_ZN4PLMD12Communicator10getMPITypeINS_10AtomNumberEEEP15ompi_datatype_tv8
_ZN4PLMD12Communicator10getMPITypeIcEEP15ompi_datatype_tv295
_ZN4PLMD12Communicator10getMPITypeIdEEP15ompi_datatype_tv4552423
_ZN4PLMD12Communicator10getMPITypeIeEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIfEEP15ompi_datatype_tv0
_ZN4PLMD12Communicator10getMPITypeIiEEP15ompi_datatype_tv67196
_ZN4PLMD12Communicator10getMPITypeIjEEP15ompi_datatype_tv43109
_ZN4PLMD12Communicator10getMPITypeImEEP15ompi_datatype_tv4666369
_ZN4PLMD12Communicator10getMPITypeIyEEP15ompi_datatype_tv6
_ZN4PLMD12Communicator11initializedEv24771376
_ZN4PLMD12Communicator12plumedHasMPIEv54
_ZN4PLMD12Communicator3MaxENS0_4DataE155
_ZN4PLMD12Communicator3MinENS0_4DataE3
_ZN4PLMD12Communicator3SumENS0_4DataE4280794
_ZN4PLMD12Communicator4ProdENS0_4DataE3
_ZN4PLMD12Communicator4RecvENS0_4DataEiiRNS0_6StatusE15298
_ZN4PLMD12Communicator5AbortEi0
_ZN4PLMD12Communicator5BcastENS0_4DataEi4960466
_ZN4PLMD12Communicator5IsendENS0_9ConstDataEii15298
_ZN4PLMD12Communicator7Request4waitERNS0_6StatusE14898
_ZN4PLMD12Communicator8Get_commEv1722
_ZN4PLMD12Communicator8Set_commEP19ompi_communicator_t2222
_ZN4PLMD12Communicator8Set_commERKNS_11TypesafePtrE1203
_ZN4PLMD12Communicator9AllgatherENS0_9ConstDataENS0_4DataE5838
_ZN4PLMD12Communicator9Set_fcommERKNS_11TypesafePtrE0
_ZN4PLMD12CommunicatorC2ERKS0_0
_ZN4PLMD12CommunicatorC2Ev1617913
_ZN4PLMD12CommunicatorD0Ev1615202
_ZN4PLMD12CommunicatorD2Ev1617913
_ZN4PLMD12CommunicatoraSERKS0_0
_ZNK4PLMD12Communicator5SplitEiiRS0_406
_ZNK4PLMD12Communicator6Status9Get_countEP15ompi_datatype_t7587
_ZNK4PLMD12Communicator7BarrierEv4671787
_ZNK4PLMD12Communicator8Get_rankEv6815455
_ZNK4PLMD12Communicator8Get_sizeEv2337533
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.cpp.gcov.html b/coverage/tools/Communicator.cpp.gcov.html new file mode 100644 index 000000000000..945550119b3b --- /dev/null +++ b/coverage/tools/Communicator.cpp.gcov.html @@ -0,0 +1,395 @@ + + + + + + + + LCOV - plumed test coverage - tools/Communicator.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212283.6 %
Date:2024-02-22 21:58:45Functions:303683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Communicator.h"
+      23             : #include "Exception.h"
+      24             : #include "AtomNumber.h"
+      25             : #include <cstdlib>
+      26             : #include <cstring>
+      27             : #include <cstdio>
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31          54 : bool Communicator::plumedHasMPI() {
+      32             : #ifdef __PLUMED_HAS_MPI
+      33          54 :   return true;
+      34             : #else
+      35             :   return false;
+      36             : #endif
+      37             : }
+      38             : 
+      39     1617913 : Communicator::Communicator()
+      40             : #ifdef __PLUMED_HAS_MPI
+      41     1617913 :   : communicator(MPI_COMM_SELF)
+      42             : #endif
+      43             : {
+      44     1617913 : }
+      45             : 
+      46           0 : Communicator::Communicator(const Communicator&pc) {
+      47           0 :   Set_comm(pc.communicator);
+      48           0 : }
+      49             : 
+      50             : Communicator::Status Communicator::StatusIgnore;
+      51             : 
+      52           0 : Communicator& Communicator::operator=(const Communicator&pc) {
+      53           0 :   if (this != &pc) {
+      54           0 :     Set_comm(pc.communicator);
+      55             :   }
+      56           0 :   return *this;
+      57             : }
+      58             : 
+      59     6815455 : int Communicator::Get_rank()const {
+      60     6815455 :   int r=0;
+      61             : #ifdef __PLUMED_HAS_MPI
+      62     6815455 :   if(initialized()) MPI_Comm_rank(communicator,&r);
+      63             : #endif
+      64     6815455 :   return r;
+      65             : }
+      66             : 
+      67     2337533 : int Communicator::Get_size()const {
+      68     2337533 :   int s=1;
+      69             : #ifdef __PLUMED_HAS_MPI
+      70     2337533 :   if(initialized()) MPI_Comm_size(communicator,&s);
+      71             : #endif
+      72     2337533 :   return s;
+      73             : }
+      74             : 
+      75        2222 : void Communicator::Set_comm(MPI_Comm c) {
+      76             : #ifdef __PLUMED_HAS_MPI
+      77        2222 :   if(initialized()) {
+      78        1721 :     if(communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
+      79        1721 :     if(c!=MPI_COMM_SELF) MPI_Comm_dup(c,&communicator);
+      80             :   }
+      81             : #else
+      82             :   (void) c;
+      83             : #endif
+      84        2222 : }
+      85             : 
+      86     3233115 : Communicator::~Communicator() {
+      87             : #ifdef __PLUMED_HAS_MPI
+      88     1617913 :   if(initialized() && communicator!=MPI_COMM_SELF && communicator!=MPI_COMM_WORLD) MPI_Comm_free(&communicator);
+      89             : #endif
+      90     3233115 : }
+      91             : 
+      92        1203 : void Communicator::Set_comm(const TypesafePtr & val) {
+      93             : #ifdef __PLUMED_HAS_MPI
+      94        1203 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+      95        2406 :   if(val) Set_comm(*(const MPI_Comm*)val.get<const void*>());
+      96             : #else
+      97             :   (void) val;
+      98             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+      99             : #endif
+     100        1203 : }
+     101             : 
+     102           0 : void Communicator::Set_fcomm(const TypesafePtr & val) {
+     103             : #ifdef __PLUMED_HAS_MPI
+     104           0 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     105           0 :   if(val) {
+     106           0 :     MPI_Comm comm=MPI_Comm_f2c(*(const MPI_Fint*)val.get<const void*>());
+     107           0 :     Set_comm(comm);
+     108             :   }
+     109             : #else
+     110             :   (void) val;
+     111             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     112             : #endif
+     113           0 : }
+     114             : 
+     115           0 : void Communicator::Abort(int errorcode) {
+     116             : #ifdef __PLUMED_HAS_MPI
+     117           0 :   if(initialized()) {
+     118           0 :     MPI_Abort(communicator,errorcode);
+     119             :   }
+     120             : #endif
+     121           0 :   std::fprintf(stderr,"aborting with error code %d\n",errorcode);
+     122           0 :   std::abort();
+     123             : }
+     124             : 
+     125     4960466 : void Communicator::Bcast(Data data,int root) {
+     126             : #if defined(__PLUMED_HAS_MPI)
+     127     4960466 :   if(initialized()) MPI_Bcast(data.pointer,data.size,data.type,root,communicator);
+     128             : #else
+     129             :   (void) data;
+     130             :   (void) root;
+     131             : #endif
+     132     4960466 : }
+     133             : 
+     134     4280794 : void Communicator::Sum(Data data) {
+     135             : #if defined(__PLUMED_HAS_MPI)
+     136     4280794 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_SUM,communicator);
+     137             : #else
+     138             :   (void) data;
+     139             : #endif
+     140     4280794 : }
+     141             : 
+     142           3 : void Communicator::Prod(Data data) {
+     143             : #if defined(__PLUMED_HAS_MPI)
+     144           3 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_PROD,communicator);
+     145             : #else
+     146             :   (void) data;
+     147             : #endif
+     148           3 : }
+     149             : 
+     150         155 : void Communicator::Max(Data data) {
+     151             : #if defined(__PLUMED_HAS_MPI)
+     152         155 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_MAX,communicator);
+     153             : #else
+     154             :   (void) data;
+     155             : #endif
+     156         155 : }
+     157             : 
+     158           3 : void Communicator::Min(Data data) {
+     159             : #if defined(__PLUMED_HAS_MPI)
+     160           3 :   if(initialized()) MPI_Allreduce(MPI_IN_PLACE,data.pointer,data.size,data.type,MPI_MIN,communicator);
+     161             : #else
+     162             :   (void) data;
+     163             : #endif
+     164           3 : }
+     165             : 
+     166       15298 : Communicator::Request Communicator::Isend(ConstData data,int source,int tag) {
+     167             :   Request req;
+     168             : #ifdef __PLUMED_HAS_MPI
+     169       15298 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     170       15298 :   void*s=const_cast<void*>((const void*)data.pointer);
+     171       15298 :   MPI_Isend(s,data.size,data.type,source,tag,communicator,&req.r);
+     172             : #else
+     173             :   (void) data;
+     174             :   (void) source;
+     175             :   (void) tag;
+     176             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     177             : #endif
+     178       15298 :   return req;
+     179             : }
+     180             : 
+     181       19063 : void Communicator::Allgatherv(ConstData in,Data out,const int*recvcounts,const int*displs) {
+     182       19063 :   void*s=const_cast<void*>((const void*)in.pointer);
+     183       19063 :   void*r=const_cast<void*>((const void*)out.pointer);
+     184             :   int*rc=const_cast<int*>(recvcounts);
+     185             :   int*di=const_cast<int*>(displs);
+     186             : #if defined(__PLUMED_HAS_MPI)
+     187       19063 :   if(initialized()) {
+     188       19062 :     if(s==NULL)s=MPI_IN_PLACE;
+     189       19062 :     MPI_Allgatherv(s,in.size,in.type,r,rc,di,out.type,communicator);
+     190             :   } else {
+     191           1 :     plumed_assert(in.nbytes==out.nbytes);
+     192           1 :     plumed_assert(in.size==out.size);
+     193           1 :     plumed_assert(rc);
+     194           1 :     plumed_assert(rc[0]==in.size);
+     195           1 :     plumed_assert(di);
+     196           1 :     if(s) std::memcpy(static_cast<char*>(r)+displs[0]*in.nbytes,s,size_t(in.size)*in.nbytes);
+     197             :   }
+     198             : #else
+     199             :   plumed_assert(in.nbytes==out.nbytes);
+     200             :   plumed_assert(in.size==out.size);
+     201             :   plumed_assert(rc);
+     202             :   plumed_assert(rc[0]==in.size);
+     203             :   plumed_assert(di);
+     204             :   if(s) std::memcpy(static_cast<char*>(r)+displs[0]*in.nbytes,s,size_t(in.size)*in.nbytes);
+     205             : #endif
+     206       19063 : }
+     207             : 
+     208        5838 : void Communicator::Allgather(ConstData in,Data out) {
+     209        5838 :   void*s=const_cast<void*>((const void*)in.pointer);
+     210        5838 :   void*r=const_cast<void*>((const void*)out.pointer);
+     211             : #if defined(__PLUMED_HAS_MPI)
+     212        5838 :   if(initialized()) {
+     213        5837 :     if(s==NULL)s=MPI_IN_PLACE;
+     214        5837 :     MPI_Allgather(s,in.size,in.type,r,out.size/Get_size(),out.type,communicator);
+     215             :   } else {
+     216           1 :     plumed_assert(in.nbytes==out.nbytes);
+     217           1 :     plumed_assert(in.size==out.size);
+     218           1 :     if(s) std::memcpy(r,s,size_t(in.size)*in.nbytes);
+     219             :   }
+     220             : #else
+     221             :   plumed_assert(in.nbytes==out.nbytes);
+     222             :   plumed_assert(in.size==out.size);
+     223             :   if(s) std::memcpy(r,s,size_t(in.size)*in.nbytes);
+     224             : #endif
+     225        5838 : }
+     226             : 
+     227       15298 : void Communicator::Recv(Data data,int source,int tag,Status&status) {
+     228             : #ifdef __PLUMED_HAS_MPI
+     229       15298 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     230       15298 :   if(&status==&StatusIgnore) MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,MPI_STATUS_IGNORE);
+     231        7587 :   else                       MPI_Recv(data.pointer,data.size,data.type,source,tag,communicator,&status.s);
+     232             : #else
+     233             :   (void) data;
+     234             :   (void) source;
+     235             :   (void) tag;
+     236             :   (void) status;
+     237             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     238             : #endif
+     239       15298 : }
+     240             : 
+     241     4671787 : void Communicator::Barrier()const {
+     242             : #ifdef __PLUMED_HAS_MPI
+     243     4671787 :   if(initialized()) MPI_Barrier(communicator);
+     244             : #endif
+     245     4671787 : }
+     246             : 
+     247        1722 : MPI_Comm & Communicator::Get_comm() {
+     248        1722 :   return communicator;
+     249             : }
+     250             : 
+     251    24771376 : bool Communicator::initialized() {
+     252             : #if defined(__PLUMED_HAS_MPI)
+     253    24771376 :   int flag=0;
+     254    24771376 :   MPI_Initialized(&flag);
+     255    24771376 :   if(flag) return true;
+     256    15364521 :   else return false;
+     257             : #endif
+     258             :   return false;
+     259             : }
+     260             : 
+     261       14898 : void Communicator::Request::wait(Status&s) {
+     262             : #ifdef __PLUMED_HAS_MPI
+     263       14898 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     264       14898 :   if(&s==&StatusIgnore) MPI_Wait(&r,MPI_STATUS_IGNORE);
+     265           1 :   else MPI_Wait(&r,&s.s);
+     266             : #else
+     267             :   (void) s;
+     268             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     269             : #endif
+     270       14898 : }
+     271             : 
+     272             : #ifdef __PLUMED_HAS_MPI
+     273           0 : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_FLOAT;}
+     274     4552423 : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_DOUBLE;}
+     275       67196 : template<> MPI_Datatype Communicator::getMPIType<int>()   { return MPI_INT;}
+     276         295 : template<> MPI_Datatype Communicator::getMPIType<char>()   { return MPI_CHAR;}
+     277       43109 : template<> MPI_Datatype Communicator::getMPIType<unsigned>()   { return MPI_UNSIGNED;}
+     278           8 : template<> MPI_Datatype Communicator::getMPIType<AtomNumber>()   { return MPI_UNSIGNED;}
+     279     4666369 : template<> MPI_Datatype Communicator::getMPIType<long unsigned>()   { return MPI_UNSIGNED_LONG;}
+     280           6 : template<> MPI_Datatype Communicator::getMPIType<long long unsigned>() { return MPI_UNSIGNED_LONG_LONG;}
+     281           0 : template<> MPI_Datatype Communicator::getMPIType<long double>()   { return MPI_LONG_DOUBLE;}
+     282             : #else
+     283             : template<> MPI_Datatype Communicator::getMPIType<float>() { return MPI_Datatype();}
+     284             : template<> MPI_Datatype Communicator::getMPIType<double>() { return MPI_Datatype();}
+     285             : template<> MPI_Datatype Communicator::getMPIType<int>() { return MPI_Datatype();}
+     286             : template<> MPI_Datatype Communicator::getMPIType<char>() { return MPI_Datatype();}
+     287             : template<> MPI_Datatype Communicator::getMPIType<unsigned>() { return MPI_Datatype();}
+     288             : template<> MPI_Datatype Communicator::getMPIType<AtomNumber>()   { return MPI_Datatype();}
+     289             : template<> MPI_Datatype Communicator::getMPIType<long unsigned>() { return MPI_Datatype();}
+     290             : template<> MPI_Datatype Communicator::getMPIType<long long unsigned>() { return MPI_Datatype();}
+     291             : template<> MPI_Datatype Communicator::getMPIType<long double>() { return MPI_Datatype();}
+     292             : #endif
+     293             : 
+     294         406 : void Communicator::Split(int color,int key,Communicator&pc)const {
+     295             : #ifdef __PLUMED_HAS_MPI
+     296         406 :   MPI_Comm_split(communicator,color,key,&pc.communicator);
+     297             : #else
+     298             :   (void) color;
+     299             :   (void) key;
+     300             :   (void) pc;
+     301             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     302             : #endif
+     303         406 : }
+     304             : 
+     305        7587 : int Communicator::Status::Get_count(MPI_Datatype type)const {
+     306             :   int i;
+     307             : #ifdef __PLUMED_HAS_MPI
+     308        7587 :   plumed_massert(initialized(),"you are trying to use an MPI function, but MPI is not initialized");
+     309        7587 :   MPI_Get_count(const_cast<MPI_Status*>(&s),type,&i);
+     310             : #else
+     311             :   i=0;
+     312             :   plumed_merror("you are trying to use an MPI function, but PLUMED has been compiled without MPI support");
+     313             : #endif
+     314        7587 :   return i;
+     315             : }
+     316             : 
+     317             : }
+     318             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.h.func-sort-c.html b/coverage/tools/Communicator.h.func-sort-c.html new file mode 100644 index 000000000000..31061595afc9 --- /dev/null +++ b/coverage/tools/Communicator.h.func-sort-c.html @@ -0,0 +1,321 @@ + + + + + + + + LCOV - plumed test coverage - tools/Communicator.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434791.5 %
Date:2024-02-22 21:58:45Functions:586293.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator3MinIdEEvRT_0
_ZN4PLMD12Communicator3SumISt6vectorIfSaIfEEEEvRT_0
_ZN4PLMD12Communicator4DataC2IfEERSt6vectorIT_SaIS4_EE0
_ZN4PLMD12Communicator5BcastISt6vectorIfSaIfEEEEvRT_i0
_ZN4PLMD12Communicator10AllgathervISt6vectorIdSaIdEES4_EEvRKT_RT0_PKiSB_2
_ZN4PLMD12Communicator5BcastISt6vectorIySaIyEEEEvRT_i2
_ZN4PLMD12Communicator9AllgatherIySt6vectorIySaIyEEEEvRKT_RT0_2
_ZN4PLMD12Communicator4DataC2IyEERSt6vectorIT_SaIS4_EE4
_ZN4PLMD12Communicator4DataC2INS_10AtomNumberEEERSt6vectorIT_SaIS5_EE8
_ZN4PLMD12Communicator5BcastISt6vectorINS_10AtomNumberESaIS3_EEEEvRT_i8
_ZN4PLMD12Communicator3SumISt6vectorINS_13TensorGenericILj3ELj3EEESaIS4_EEEEvRT_16
_ZN4PLMD12Communicator4DataC2INS_13TensorGenericILj3ELj3EEEEERSt6vectorIT_SaIS6_EE16
_ZN4PLMD12Communicator3SumINS_6MatrixIdEEEEvRT_17
_ZN4PLMD12Communicator4DataC2IdEERNS_6MatrixIT_EE17
_ZN4PLMD12Communicator5BcastISt6vectorIjSaIjEEEEvRT_i56
_ZN4PLMD12Communicator4RecvISt6vectorIcSaIcEEEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIdEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator5IsendINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator9ConstDataC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE57
_ZN4PLMD12Communicator4DataC2ERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE61
_ZN4PLMD12Communicator5BcastINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRT_i61
_ZN4PLMD12Communicator5BcastISt6vectorIcSaIcEEEEvRT_i114
_ZN4PLMD12Communicator9AllgatherIiSt6vectorIiSaIiEEEEvRKT_RT0_131
_ZN4PLMD12Communicator5BcastINS_13TensorGenericILj3ELj3EEEEEvRT_i134
_ZN4PLMD12Communicator9AllgatherIjSt6vectorIjSaIjEEEEvRKT_RT0_140
_ZN4PLMD12Communicator10AllgathervISt6vectorIjSaIjEES4_EEvRKT_RT0_PKiSB_150
_ZN4PLMD12Communicator3SumISt6vectorIiSaIiEEEEvRT_150
_ZN4PLMD12Communicator9ConstDataC2IjEERKSt6vectorIT_SaIS4_EE150
_ZN4PLMD12Communicator3MaxIdEEvRT_152
_ZN4PLMD12Communicator3SumIiEEvRT_204
_ZN4PLMD12Communicator9AllgatherIiiEEvPKT_iPT0_i204
_ZN4PLMD12Communicator10AllgathervIddEEvPKT_iPT0_PKiS8_224
_ZN4PLMD12Communicator10AllgathervIiiEEvPKT_iPT0_PKiS8_224
_ZN4PLMD12Communicator5BcastIjEEvRT_i430
_ZN4PLMD12Communicator5BcastIdEEvRT_i500
_ZN4PLMD12Communicator3SumIjEEvPT_i561
_ZN4PLMD12Communicator5BcastISt6vectorIiSaIiEEEEvRT_i580
_ZN4PLMD12Communicator9AllgatherISt6vectorIdSaIdEES4_EEvRKT_RT0_580
_ZN4PLMD12Communicator9ConstDataC2IdEERKSt6vectorIT_SaIS4_EE582
_ZN4PLMD12Communicator4DataC2IiEERSt6vectorIT_SaIS4_EE861
_ZN4PLMD12Communicator3SumIjEEvRT_1074
_ZN4PLMD12Communicator3SumISt6vectorIjSaIjEEEEvRT_3490
_ZN4PLMD12Communicator4DataC2IjEERSt6vectorIT_SaIS4_EE3836
_ZN4PLMD12Communicator9AllgatherIdSt6vectorIdSaIdEEEEvRKT_RT0_4777
_ZN4PLMD12Communicator4RecvIdEEvPT_iiiRNS0_6StatusE7586
_ZN4PLMD12Communicator4RecvIiEEvPT_iiiRNS0_6StatusE7586
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestEPKT_iii7586
_ZN4PLMD12Communicator5IsendIiEENS0_7RequestEPKT_iii7586
_ZNK4PLMD12Communicator6Status9Get_countIiEEiv7586
_ZN4PLMD12Communicator3SumISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEEvRT_11179
_ZN4PLMD12Communicator4DataC2INS_13VectorGenericILj3EEEEERSt6vectorIT_SaIS6_EE11179
_ZN4PLMD12Communicator10AllgathervIjjEEvPKT_iPT0_PKiS8_18459
_ZN4PLMD12Communicator3SumIiEEvPT_i19481
_ZN4PLMD12Communicator3SumINS_13TensorGenericILj3ELj3EEEEEvRT_19926
_ZN4PLMD12Communicator5BcastIiEEvRT_i22868
_ZN4PLMD12Communicator3SumIdEEvPT_i65292
_ZN4PLMD12Communicator5BcastISt6vectorIdSaIdEEEEvRT_i269335
_ZN4PLMD12Communicator3SumIdEEvRT_2033648
_ZN4PLMD12Communicator3SumISt6vectorIdSaIdEEEEvRT_2125752
_ZN4PLMD12Communicator4DataC2IdEERSt6vectorIT_SaIS4_EE2400446
_ZN4PLMD12Communicator5BcastImEEvRT_i4666369
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.h.func.html b/coverage/tools/Communicator.h.func.html new file mode 100644 index 000000000000..636448f2113e --- /dev/null +++ b/coverage/tools/Communicator.h.func.html @@ -0,0 +1,321 @@ + + + + + + + + LCOV - plumed test coverage - tools/Communicator.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434791.5 %
Date:2024-02-22 21:58:45Functions:586293.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12Communicator10AllgathervISt6vectorIdSaIdEES4_EEvRKT_RT0_PKiSB_2
_ZN4PLMD12Communicator10AllgathervISt6vectorIjSaIjEES4_EEvRKT_RT0_PKiSB_150
_ZN4PLMD12Communicator10AllgathervIddEEvPKT_iPT0_PKiS8_224
_ZN4PLMD12Communicator10AllgathervIiiEEvPKT_iPT0_PKiS8_224
_ZN4PLMD12Communicator10AllgathervIjjEEvPKT_iPT0_PKiS8_18459
_ZN4PLMD12Communicator3MaxIdEEvRT_152
_ZN4PLMD12Communicator3MinIdEEvRT_0
_ZN4PLMD12Communicator3SumINS_13TensorGenericILj3ELj3EEEEEvRT_19926
_ZN4PLMD12Communicator3SumINS_6MatrixIdEEEEvRT_17
_ZN4PLMD12Communicator3SumISt6vectorINS_13TensorGenericILj3ELj3EEESaIS4_EEEEvRT_16
_ZN4PLMD12Communicator3SumISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEEvRT_11179
_ZN4PLMD12Communicator3SumISt6vectorIdSaIdEEEEvRT_2125752
_ZN4PLMD12Communicator3SumISt6vectorIfSaIfEEEEvRT_0
_ZN4PLMD12Communicator3SumISt6vectorIiSaIiEEEEvRT_150
_ZN4PLMD12Communicator3SumISt6vectorIjSaIjEEEEvRT_3490
_ZN4PLMD12Communicator3SumIdEEvPT_i65292
_ZN4PLMD12Communicator3SumIdEEvRT_2033648
_ZN4PLMD12Communicator3SumIiEEvPT_i19481
_ZN4PLMD12Communicator3SumIiEEvRT_204
_ZN4PLMD12Communicator3SumIjEEvPT_i561
_ZN4PLMD12Communicator3SumIjEEvRT_1074
_ZN4PLMD12Communicator4DataC2ERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE61
_ZN4PLMD12Communicator4DataC2INS_10AtomNumberEEERSt6vectorIT_SaIS5_EE8
_ZN4PLMD12Communicator4DataC2INS_13TensorGenericILj3ELj3EEEEERSt6vectorIT_SaIS6_EE16
_ZN4PLMD12Communicator4DataC2INS_13VectorGenericILj3EEEEERSt6vectorIT_SaIS6_EE11179
_ZN4PLMD12Communicator4DataC2IdEERNS_6MatrixIT_EE17
_ZN4PLMD12Communicator4DataC2IdEERSt6vectorIT_SaIS4_EE2400446
_ZN4PLMD12Communicator4DataC2IfEERSt6vectorIT_SaIS4_EE0
_ZN4PLMD12Communicator4DataC2IiEERSt6vectorIT_SaIS4_EE861
_ZN4PLMD12Communicator4DataC2IjEERSt6vectorIT_SaIS4_EE3836
_ZN4PLMD12Communicator4DataC2IyEERSt6vectorIT_SaIS4_EE4
_ZN4PLMD12Communicator4RecvISt6vectorIcSaIcEEEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIdEEvPT_iiiRNS0_6StatusE7586
_ZN4PLMD12Communicator4RecvIdEEvRT_iiRNS0_6StatusE57
_ZN4PLMD12Communicator4RecvIiEEvPT_iiiRNS0_6StatusE7586
_ZN4PLMD12Communicator5BcastINS_13TensorGenericILj3ELj3EEEEEvRT_i134
_ZN4PLMD12Communicator5BcastINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRT_i61
_ZN4PLMD12Communicator5BcastISt6vectorINS_10AtomNumberESaIS3_EEEEvRT_i8
_ZN4PLMD12Communicator5BcastISt6vectorIcSaIcEEEEvRT_i114
_ZN4PLMD12Communicator5BcastISt6vectorIdSaIdEEEEvRT_i269335
_ZN4PLMD12Communicator5BcastISt6vectorIfSaIfEEEEvRT_i0
_ZN4PLMD12Communicator5BcastISt6vectorIiSaIiEEEEvRT_i580
_ZN4PLMD12Communicator5BcastISt6vectorIjSaIjEEEEvRT_i56
_ZN4PLMD12Communicator5BcastISt6vectorIySaIyEEEEvRT_i2
_ZN4PLMD12Communicator5BcastIdEEvRT_i500
_ZN4PLMD12Communicator5BcastIiEEvRT_i22868
_ZN4PLMD12Communicator5BcastIjEEvRT_i430
_ZN4PLMD12Communicator5BcastImEEvRT_i4666369
_ZN4PLMD12Communicator5IsendINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestEPKT_iii7586
_ZN4PLMD12Communicator5IsendIdEENS0_7RequestERKT_ii57
_ZN4PLMD12Communicator5IsendIiEENS0_7RequestEPKT_iii7586
_ZN4PLMD12Communicator9AllgatherISt6vectorIdSaIdEES4_EEvRKT_RT0_580
_ZN4PLMD12Communicator9AllgatherIdSt6vectorIdSaIdEEEEvRKT_RT0_4777
_ZN4PLMD12Communicator9AllgatherIiSt6vectorIiSaIiEEEEvRKT_RT0_131
_ZN4PLMD12Communicator9AllgatherIiiEEvPKT_iPT0_i204
_ZN4PLMD12Communicator9AllgatherIjSt6vectorIjSaIjEEEEvRKT_RT0_140
_ZN4PLMD12Communicator9AllgatherIySt6vectorIySaIyEEEEvRKT_RT0_2
_ZN4PLMD12Communicator9ConstDataC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE57
_ZN4PLMD12Communicator9ConstDataC2IdEERKSt6vectorIT_SaIS4_EE582
_ZN4PLMD12Communicator9ConstDataC2IjEERKSt6vectorIT_SaIS4_EE150
_ZNK4PLMD12Communicator6Status9Get_countIiEEiv7586
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Communicator.h.gcov.html b/coverage/tools/Communicator.h.gcov.html new file mode 100644 index 000000000000..af6d8b54ed0b --- /dev/null +++ b/coverage/tools/Communicator.h.gcov.html @@ -0,0 +1,329 @@ + + + + + + + + LCOV - plumed test coverage - tools/Communicator.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Communicator.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:434791.5 %
Date:2024-02-22 21:58:45Functions:586293.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Communicator_h
+      23             : #define __PLUMED_tools_Communicator_h
+      24             : #ifdef __PLUMED_HAS_MPI
+      25             : #include <mpi.h>
+      26             : #endif
+      27             : #include <cstdlib>
+      28             : #include "Exception.h"
+      29             : #include "TypesafePtr.h"
+      30             : #include <vector>
+      31             : #include <string>
+      32             : #include "Vector.h"
+      33             : #include "Tensor.h"
+      34             : #include "Matrix.h"
+      35             : 
+      36             : namespace PLMD {
+      37             : 
+      38             : #ifndef  __PLUMED_HAS_MPI
+      39             : /// Surrogate of MPI_Comm when MPI library is not available
+      40             : class MPI_Comm {};
+      41             : /// Surrogate of MPI_Datatype when MPI library is not available
+      42             : class MPI_Datatype {};
+      43             : /// Surrogate of MPI_Status when MPI library is not available
+      44             : class MPI_Status {};
+      45             : /// Surrogate of MPI_Request when MPI library is not available
+      46             : class MPI_Request {};
+      47             : #endif
+      48             : 
+      49             : /// \ingroup TOOLBOX
+      50             : /// Class containing wrappers to MPI.
+      51             : /// All the MPI related stuff is relegated here.
+      52             : class Communicator {
+      53             : /// Communicator
+      54             :   MPI_Comm communicator;
+      55             : /// Function returning the MPI type.
+      56             : /// You can use it to access to the MPI type of a C++ type, e.g.
+      57             : /// `MPI_Datatype type=getMPIType<double>();`
+      58             :   template <class T>
+      59             :   static MPI_Datatype getMPIType();
+      60             : /// Structure defining a buffer for MPI.
+      61             : /// It contains info on the pointed data and its type and size. It is useful to
+      62             : /// allow wrapper of MPI functions where the triplet (buffer,type,size)
+      63             : /// is grouped into a single object. It can be built starting from
+      64             : /// different kinds of data. To implement compatibility of MPI wrappers
+      65             : /// with e.g. vectors, add constructors here.
+      66             :   struct Data {
+      67             :     void*pointer;
+      68             :     int size;
+      69             :     int nbytes=0;
+      70             :     MPI_Datatype type;
+      71             : /// Init from pointer and size
+      72     2636427 :     template <typename T> Data(T*p,int s): pointer(p), size(s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
+      73             : /// Init from reference
+      74    13450604 :     template <typename T> explicit Data(T&p): pointer(&p), size(1), nbytes(sizeof(T)), type(getMPIType<T>()) {}
+      75             : /// Init from pointer to VectorGeneric
+      76       11179 :     template <unsigned n> explicit Data(VectorGeneric<n> *p,int s): pointer(p), size(n*s), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+      77             : /// Init from reference to VectorGeneric
+      78             :     template <unsigned n> explicit Data(VectorGeneric<n> &p): pointer(&p), size(n), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+      79             : /// Init from pointer to TensorGeneric
+      80          16 :     template <unsigned n,unsigned m> explicit Data(TensorGeneric<n,m> *p,int s): pointer(p), size(n*m*s), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+      81             : /// Init from reference to TensorGeneric
+      82       40120 :     template <unsigned n,unsigned m> explicit Data(TensorGeneric<n,m> &p): pointer(&p), size(n*m), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+      83             : /// Init from reference to std::vector
+      84     2416350 :     template <typename T> explicit Data(std::vector<T>&v) {
+      85     2416521 :       Data d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type;
+      86     2416350 :     }
+      87             : /// Init from reference to PLMD::Matrix
+      88          17 :     template <typename T> explicit Data(Matrix<T>&m ) {
+      89          17 :       if(m.nrows()*m.ncols()>0) { Data d(&m(0,0),m.nrows()*m.ncols()); pointer=d.pointer; size=d.size; type=d.type; }
+      90           0 :       else { pointer=NULL; size=0; }
+      91          17 :     }
+      92             : /// Init from reference to std::string
+      93          61 :     explicit Data(std::string&s) {
+      94          61 :       if(s.size()>0) { Data d(&s[0],s.size()); pointer=d.pointer; size=d.size; type=d.type; }
+      95           0 :       else { pointer=NULL; size=0; }
+      96          61 :     }
+      97             :   };
+      98             : /// Const version of Communicator::Data
+      99             : /// See Communicator::Data documentation
+     100             :   struct ConstData {
+     101             :     const void*pointer;
+     102             :     int size;
+     103             :     int nbytes=0;
+     104             :     MPI_Datatype type;
+     105       19900 :     template <typename T> explicit ConstData(const T*p,int s): pointer(p), size(s), nbytes(sizeof(T)), type(getMPIType<T>()) {}
+     106        5164 :     template <typename T> explicit ConstData(const T&p): pointer(&p), size(1), nbytes(sizeof(T)), type(getMPIType<T>()) {}
+     107             :     template <unsigned n> explicit ConstData(const VectorGeneric<n> *p,int s): pointer(p), size(n*s), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+     108             :     template <unsigned n> explicit ConstData(const VectorGeneric<n> &p): pointer(&p), size(n), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+     109             :     template <unsigned n,unsigned m> explicit ConstData(const TensorGeneric<n,m> *p,int s): pointer(p), size(n*m*s), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+     110             :     template <unsigned n,unsigned m> explicit ConstData(const TensorGeneric<n,m> &p): pointer(&p), size(n*m), nbytes(sizeof(double)), type(getMPIType<double>()) {}
+     111         732 :     template <typename T> explicit ConstData(const std::vector<T>&v) {
+     112         732 :       ConstData d(v.data(),v.size()); pointer=d.pointer; size=d.size; type=d.type;
+     113         732 :     }
+     114             :     template <typename T> explicit ConstData(const Matrix<T>&m ) {
+     115             :       if(m.nrows()*m.ncols()>0) { ConstData d(&m(0,0),m.nrows()*m.ncols()); pointer=d.pointer; size=d.size; type=d.type; }
+     116             :       else { pointer=NULL; size=0; }
+     117             :     }
+     118          57 :     explicit ConstData(const std::string&s) {
+     119          57 :       if(s.size()>0) { ConstData d(&s[0],s.size()); pointer=d.pointer; size=d.size; type=d.type; }
+     120           0 :       else { pointer=NULL; size=0; }
+     121          57 :     }
+     122             :   };
+     123             : public:
+     124             :   ///Runtime acces to the __PLUMED_HAS_MPI definition
+     125             :   static bool plumedHasMPI();
+     126             : 
+     127             : /// Wrapper class for MPI_Status
+     128             :   class Status {
+     129             :     int Get_count(MPI_Datatype)const;
+     130             :   public:
+     131             :     MPI_Status s;
+     132             :     template <class T>
+     133        7586 :     int Get_count()const {return Get_count(getMPIType<T>());}
+     134             :   };
+     135             : /// Special status used when status should be ignored.
+     136             : /// E.g. `Recv(a,0,1,Communicator::StatusIgnore);`
+     137             : /// Notice that this is the default for Recv, so this is equivalent to
+     138             : /// `Recv(a,0,1);`
+     139             :   static Status StatusIgnore;
+     140             : /// Wrapper class for MPI_Request
+     141             :   class Request {
+     142             :   public:
+     143             :     MPI_Request r;
+     144             :     void wait(Status&s=StatusIgnore);
+     145             :   };
+     146             : /// Default constructor
+     147             :   Communicator();
+     148             : /// Copy constructor.
+     149             : /// It effectively "clones" the communicator, providing a new one acting on the same group
+     150             :   Communicator(const Communicator&);
+     151             : /// Assignment operator.
+     152             : /// It effectively "clones" the communicator, providing a new one acting on the same group
+     153             :   Communicator& operator=(const Communicator&);
+     154             : /// Destructor
+     155             :   virtual ~Communicator();
+     156             : /// Obtain the rank of the present process
+     157             :   int Get_rank()const;
+     158             : /// Obtain the number of processes
+     159             :   int Get_size()const;
+     160             : /// Set from a real MPI communicator.
+     161             : /// \param comm MPI communicator
+     162             :   void Set_comm(MPI_Comm comm);
+     163             : /// Reference to MPI communicator
+     164             :   MPI_Comm & Get_comm();
+     165             : /// Set from a pointer to a real MPI communicator (C).
+     166             : /// \param comm Pointer to a C MPI communicator
+     167             :   void Set_comm(const TypesafePtr & comm);
+     168             : /// Set from a pointer to a real MPI communicator (FORTRAN).
+     169             : /// \param comm Pointer to a FORTRAN MPI communicator (INTEGER)
+     170             :   void Set_fcomm(const TypesafePtr & comm);
+     171             : /// Wrapper to MPI_Abort.
+     172             : /// \param code Error code
+     173             :   void Abort(int code);
+     174             : /// Wrapper to MPI_Barrier
+     175             :   void Barrier()const;
+     176             : /// Tests if MPI library is initialized
+     177             :   static bool initialized();
+     178             : /// Wrapper for MPI_Allreduce with MPI_SUM (data struct)
+     179             :   void Sum(Data);
+     180             : /// Wrapper for MPI_Allreduce with MPI_SUM (pointer)
+     181       85334 :   template <class T> void Sum(T*buf,int count) {Sum(Data(buf,count));}
+     182             : /// Wrapper for MPI_Allreduce with MPI_SUM (reference)
+     183     4195456 :   template <class T> void Sum(T&buf) {Sum(Data(buf));}
+     184             : /// Wrapper for MPI_Allreduce with MPI_PROD (data struct)
+     185             :   void Prod(Data);
+     186             : /// Wrapper for MPI_Allreduce with MPI_PROD (pointer)
+     187             :   template <class T> void Prod(T*buf,int count) {Prod(Data(buf,count));}
+     188             : /// Wrapper for MPI_Allreduce with MPI_PROD (reference)
+     189             :   template <class T> void Prod(T&buf) {Prod(Data(buf));}
+     190             : /// Wrapper for MPI_Allreduce with MPI_MAX (data struct)
+     191             :   void Max(Data);
+     192             : /// Wrapper for MPI_Allreduce with MPI_MAX (pointer)
+     193             :   template <class T> void Max(T*buf,int count) {Max(Data(buf,count));}
+     194             : /// Wrapper for MPI_Allreduce with MPI_MAX (reference)
+     195         152 :   template <class T> void Max(T&buf) {Max(Data(buf));}
+     196             : /// Wrapper for MPI_Allreduce with MPI_MIN (data struct)
+     197             :   void Min(Data);
+     198             : /// Wrapper for MPI_Allreduce with MPI_MIN (pointer)
+     199             :   template <class T> void Min(T*buf,int count) {Min(Data(buf,count));}
+     200             : /// Wrapper for MPI_Allreduce with MPI_MIN (reference)
+     201           0 :   template <class T> void Min(T&buf) {Min(Data(buf));}
+     202             : 
+     203             : /// Wrapper for MPI_Bcast (data struct)
+     204             :   void Bcast(Data,int);
+     205             : /// Wrapper for MPI_Bcast (pointer)
+     206             :   template <class T> void Bcast(T*buf,int count,int root) {Bcast(Data(buf,count),root);}
+     207             : /// Wrapper for MPI_Bcast (reference)
+     208     4960457 :   template <class T> void Bcast(T&buf,int root) {Bcast(Data(buf),root);}
+     209             : 
+     210             : /// Wrapper for MPI_Isend (data struct)
+     211             :   Request Isend(ConstData,int,int);
+     212             : /// Wrapper for MPI_Isend (pointer)
+     213       15172 :   template <class T> Request Isend(const T*buf,int count,int source,int tag) {return Isend(ConstData(buf,count),source,tag);}
+     214             : /// Wrapper for MPI_Isend (reference)
+     215         114 :   template <class T> Request Isend(const T&buf,int source,int tag) {return Isend(ConstData(buf),source,tag);}
+     216             : 
+     217             : /// Wrapper for MPI_Allgatherv (data struct)
+     218             :   void Allgatherv(ConstData in,Data out,const int*,const int*);
+     219             : /// Wrapper for MPI_Allgatherv (pointer)
+     220       18907 :   template <class T,class S> void Allgatherv(const T*sendbuf,int sendcount,S*recvbuf,const int*recvcounts,const int*displs) {
+     221       18907 :     Allgatherv(ConstData(sendbuf,sendcount),Data(recvbuf,0),recvcounts,displs);
+     222       18907 :   }
+     223             : /// Wrapper for MPI_Allgatherv (reference)
+     224         152 :   template <class T,class S> void Allgatherv(const T&sendbuf,S&recvbuf,const int*recvcounts,const int*displs) {
+     225         152 :     Allgatherv(ConstData(sendbuf),Data(recvbuf),recvcounts,displs);
+     226         152 :   }
+     227             : 
+     228             : /// Wrapper for MPI_Allgather (data struct)
+     229             :   void Allgather(ConstData in,Data out);
+     230             : /// Wrapper for MPI_Allgatherv (pointer)
+     231         204 :   template <class T,class S> void Allgather(const T*sendbuf,int sendcount,S*recvbuf,int recvcount) {
+     232         408 :     Allgather(ConstData(sendbuf,sendcount),Data(recvbuf,recvcount*Get_size()));
+     233         204 :   }
+     234             : /// Wrapper for MPI_Allgatherv (reference)
+     235        5630 :   template <class T,class S> void Allgather(const T&sendbuf,S&recvbuf) {
+     236       10680 :     Allgather(ConstData(sendbuf),Data(recvbuf));
+     237        5630 :   }
+     238             : 
+     239             : /// Wrapper for MPI_Recv (data struct)
+     240             :   void Recv(Data,int,int,Status&s=StatusIgnore);
+     241             : /// Wrapper for MPI_Recv (pointer)
+     242       15172 :   template <class T> void Recv(T*buf,int count,int source,int tag,Status&s=StatusIgnore) {Recv(Data(buf,count),source,tag,s);}
+     243             : /// Wrapper for MPI_Recv (reference)
+     244         114 :   template <class T> void Recv(T&buf,int source,int tag,Status&s=StatusIgnore) {Recv(Data(buf),source,tag,s);}
+     245             : 
+     246             : /// Wrapper to MPI_Comm_split
+     247             :   void Split(int,int,Communicator&)const;
+     248             : };
+     249             : 
+     250             : }
+     251             : 
+     252             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ConjugateGradient.h.func-sort-c.html b/coverage/tools/ConjugateGradient.h.func-sort-c.html new file mode 100644 index 000000000000..5982791d39dc --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/ConjugateGradient.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ConjugateGradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17ConjugateGradientINS_6dimred17SketchMapConjGradEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E4
_ZN4PLMD17ConjugateGradientINS_6dimred18SketchMapPointwiseEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E22
_ZN4PLMD17ConjugateGradientINS_6dimred24ProjectNonLandmarkPointsEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E500
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ConjugateGradient.h.func.html b/coverage/tools/ConjugateGradient.h.func.html new file mode 100644 index 000000000000..620f25070d8d --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/ConjugateGradient.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ConjugateGradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17ConjugateGradientINS_6dimred17SketchMapConjGradEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E4
_ZN4PLMD17ConjugateGradientINS_6dimred18SketchMapPointwiseEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E22
_ZN4PLMD17ConjugateGradientINS_6dimred24ProjectNonLandmarkPointsEE8minimiseERKdRSt6vectorIdSaIdEEMS2_FdRKS8_S9_E500
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ConjugateGradient.h.gcov.html b/coverage/tools/ConjugateGradient.h.gcov.html new file mode 100644 index 000000000000..29ef6c08d255 --- /dev/null +++ b/coverage/tools/ConjugateGradient.h.gcov.html @@ -0,0 +1,143 @@ + + + + + + + + LCOV - plumed test coverage - tools/ConjugateGradient.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ConjugateGradient.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:131492.9 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_ConjugateGradient_h
+      23             : #define __PLUMED_tools_ConjugateGradient_h
+      24             : 
+      25             : #include "MinimiseBase.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : template <class FCLASS>
+      30             : class ConjugateGradient : public MinimiseBase<FCLASS> {
+      31             : private:
+      32             : /// This is the pointer to the member function in the energy
+      33             : /// calculating class that calculates the energy
+      34             :   typedef double(FCLASS::*engf_pointer)( const std::vector<double>& p, std::vector<double>& der );
+      35             :   const unsigned ITMAX;
+      36             :   const double EPS;
+      37             : public:
+      38         505 :   explicit ConjugateGradient( FCLASS* funcc ) : MinimiseBase<FCLASS>(funcc), ITMAX(200), EPS(1E-10) {}
+      39             :   void minimise( const double& ftol, std::vector<double>& p, engf_pointer myfunc );
+      40             : };
+      41             : 
+      42             : template <class FCLASS>
+      43         526 : void ConjugateGradient<FCLASS>::minimise( const double& ftol, std::vector<double>& p, engf_pointer myfunc ) {
+      44         526 :   std::vector<double> xi( p.size() ), g( p.size() ), h( p.size() );
+      45         526 :   double fp = this->calcDerivatives( p, xi, myfunc );
+      46        6826 :   for(unsigned j=0; j<p.size(); ++j) { g[j] = -xi[j]; xi[j]=h[j]=g[j]; }
+      47             : 
+      48         897 :   for(unsigned its=0; its<ITMAX; ++its) {
+      49         897 :     double fret=this->linemin( xi, p, myfunc );
+      50             :     // The exit condition
+      51         897 :     if( 2.0*std::fabs(fret-fp) <= ftol*(std::fabs(fret)+std::fabs(fp)+EPS)) { return; }
+      52         371 :     fp = fret; this->calcDerivatives( p, xi, myfunc );
+      53             :     double ddg=0., gg=0.;
+      54       12899 :     for(unsigned j=0; j<p.size(); ++j) { gg += g[j]*g[j]; ddg += (xi[j]+g[j])*xi[j]; }
+      55             : 
+      56         371 :     if( gg==0.0 ) return;
+      57             : 
+      58         371 :     double gam=ddg/gg;
+      59       12899 :     for(unsigned j=0; j<p.size(); ++j) { g[j] = -xi[j]; xi[j]=h[j]=g[j]+gam*h[j]; }
+      60             :   }
+      61           0 :   plumed_merror("Too many interactions in conjugate gradient");
+      62             : }
+      63             : 
+      64             : }
+      65             : 
+      66             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DLLoader.cpp.func-sort-c.html b/coverage/tools/DLLoader.cpp.func-sort-c.html new file mode 100644 index 000000000000..8aaee97bd828 --- /dev/null +++ b/coverage/tools/DLLoader.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - tools/DLLoader.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - DLLoader.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:173154.8 %
Date:2024-02-22 21:58:45Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenC2EPKv0
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenD2Ev0
_ZN4PLMD8DLLoader5errorB5cxx11Ev0
_ZN4PLMD8DLLoader4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD8DLLoader9installedEv4
_ZN4PLMD8DLLoaderC2Ev809511
_ZN4PLMD8DLLoaderD2Ev809511
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DLLoader.cpp.func.html b/coverage/tools/DLLoader.cpp.func.html new file mode 100644 index 000000000000..0a3e6b54be20 --- /dev/null +++ b/coverage/tools/DLLoader.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - tools/DLLoader.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - DLLoader.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:173154.8 %
Date:2024-02-22 21:58:45Functions:4757.1 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenC2EPKv0
_ZN4PLMD8DLLoader18EnsureGlobalDLOpenD2Ev0
_ZN4PLMD8DLLoader4loadERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD8DLLoader5errorB5cxx11Ev0
_ZN4PLMD8DLLoader9installedEv4
_ZN4PLMD8DLLoaderC2Ev809511
_ZN4PLMD8DLLoaderD2Ev809511
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DLLoader.cpp.gcov.html b/coverage/tools/DLLoader.cpp.gcov.html new file mode 100644 index 000000000000..82d7c7ac7679 --- /dev/null +++ b/coverage/tools/DLLoader.cpp.gcov.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - tools/DLLoader.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - DLLoader.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:173154.8 %
Date:2024-02-22 21:58:45Functions:4757.1 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "DLLoader.h"
+      23             : 
+      24             : #include <cstdlib>
+      25             : 
+      26             : #ifdef __PLUMED_HAS_DLOPEN
+      27             : #include <dlfcn.h>
+      28             : #endif
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32           4 : bool DLLoader::installed() {
+      33             : #ifdef __PLUMED_HAS_DLOPEN
+      34           4 :   return true;
+      35             : #else
+      36             :   return false;
+      37             : #endif
+      38             : }
+      39             : 
+      40             : 
+      41           3 : void* DLLoader::load(const std::string&s) {
+      42             : #ifdef __PLUMED_HAS_DLOPEN
+      43           3 :   void* p=dlopen(s.c_str(),RTLD_NOW|RTLD_LOCAL);
+      44           3 :   if(!p) {
+      45           0 :     lastError=dlerror();
+      46             :   } else {
+      47           3 :     lastError="";
+      48             :     handles.push(p);
+      49             :   }
+      50           3 :   return p;
+      51             : #else
+      52             :   return NULL;
+      53             : #endif
+      54             : }
+      55             : 
+      56           0 : const std::string & DLLoader::error() {
+      57           0 :   return lastError;
+      58             : }
+      59             : 
+      60      809511 : DLLoader::~DLLoader() {
+      61      809511 :   auto debug=std::getenv("PLUMED_LOAD_DEBUG");
+      62             : #ifdef __PLUMED_HAS_DLOPEN
+      63      809511 :   if(debug) std::fprintf(stderr,"delete dlloader\n");
+      64      809514 :   while(!handles.empty()) {
+      65           3 :     int ret=dlclose(handles.top());
+      66           3 :     if(ret) {
+      67           0 :       std::fprintf(stderr,"+++ error reported by dlclose: %s\n",dlerror());
+      68             :     }
+      69             :     handles.pop();
+      70             :   }
+      71      809511 :   if(debug) std::fprintf(stderr,"end delete dlloader\n");
+      72             : #endif
+      73      809511 : }
+      74             : 
+      75      809511 : DLLoader::DLLoader() {
+      76             :   // do nothing
+      77      809511 : }
+      78             : 
+      79           0 : DLLoader::EnsureGlobalDLOpen::EnsureGlobalDLOpen(const void *symbol) noexcept {
+      80             : #ifdef __PLUMED_HAS_DLOPEN
+      81             : #ifdef __PLUMED_HAS_DLADDR
+      82             :   Dl_info info;
+      83             :   // from the manual:
+      84             :   // If the address specified in addr could not be matched to a shared
+      85             :   //      object, then these functions return 0.  In this case, an error
+      86             :   //      message is not available via dlerror(3).
+      87           0 :   int zeroIsError=dladdr(symbol, &info);
+      88           0 :   if(zeroIsError!=0) {
+      89             :     //This "promotes" to GLOBAL the object with the symbol pointed by ptr
+      90           0 :     handle_ = dlopen(info.dli_fname, RTLD_GLOBAL | RTLD_NOW);
+      91             :   } else {
+      92           0 :     std::fprintf(stderr,
+      93             :                  "+++WARNING+++"
+      94             :                  "Failure in finding any object that contains the symbol %p.\n",
+      95             :                  symbol);
+      96             : 
+      97             :   }
+      98             : #else
+      99             :   std::fprintf(stderr,
+     100             :                "+++WARNING+++"
+     101             :                "I can't use dladdr for promoting the library containing the symbol %p.\n"
+     102             :                "This system seems not to support dladdr",
+     103             :                symbol);
+     104             : #endif //__PLUMED_HAS_DLADDR
+     105             : #endif //__PLUMED_HAS_DLOPEN
+     106           0 : }
+     107             : 
+     108           0 : DLLoader::EnsureGlobalDLOpen::~EnsureGlobalDLOpen() {
+     109             : #ifdef __PLUMED_HAS_DLOPEN
+     110           0 :   if (handle_) {
+     111           0 :     dlclose(handle_);
+     112             :   }
+     113             : #endif //__PLUMED_HAS_DLOPEN
+     114           0 : }
+     115             : 
+     116             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DynamicList.h.func-sort-c.html b/coverage/tools/DynamicList.h.func-sort-c.html new file mode 100644 index 000000000000..27695962eb6e --- /dev/null +++ b/coverage/tools/DynamicList.h.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - tools/DynamicList.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - DynamicList.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4747100.0 %
Date:2024-02-22 21:58:45Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11DynamicListIjE14addIndexToListERKj91
_ZN4PLMD11DynamicListIjE5clearEv41860
_ZN4PLMD11DynamicListIjE14sortActiveListEv56305
_ZN4PLMD11DynamicListIjE19updateActiveMembersEv62072
_ZN4PLMD11DynamicListIjE25createIndexListFromVectorERKSt6vectorIjSaIjEE402103
_ZN4PLMD11DynamicListIjE14completeUpdateEv877983
_ZN4PLMD11DynamicListIjE18emptyActiveMembersEv934288
_ZN4PLMD11DynamicListIjE13deactivateAllEv2102018
_ZNK4PLMD11DynamicListIjE14updateCompleteEv4920287
_ZNK4PLMD11DynamicListIjE15getNumberActiveEv54828228
_ZN4PLMD11DynamicListIjE21putIndexInActiveArrayERKj77517572
_ZNK4PLMD11DynamicListIjE8isActiveERKj422013086
_ZN4PLMD11DynamicListIjE8activateEj1565261833
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DynamicList.h.func.html b/coverage/tools/DynamicList.h.func.html new file mode 100644 index 000000000000..9caaf33a5209 --- /dev/null +++ b/coverage/tools/DynamicList.h.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - tools/DynamicList.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - DynamicList.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4747100.0 %
Date:2024-02-22 21:58:45Functions:1313100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11DynamicListIjE13deactivateAllEv2102018
_ZN4PLMD11DynamicListIjE14addIndexToListERKj91
_ZN4PLMD11DynamicListIjE14completeUpdateEv877983
_ZN4PLMD11DynamicListIjE14sortActiveListEv56305
_ZN4PLMD11DynamicListIjE18emptyActiveMembersEv934288
_ZN4PLMD11DynamicListIjE19updateActiveMembersEv62072
_ZN4PLMD11DynamicListIjE21putIndexInActiveArrayERKj77517572
_ZN4PLMD11DynamicListIjE25createIndexListFromVectorERKSt6vectorIjSaIjEE402103
_ZN4PLMD11DynamicListIjE5clearEv41860
_ZN4PLMD11DynamicListIjE8activateEj1565261833
_ZNK4PLMD11DynamicListIjE14updateCompleteEv4920287
_ZNK4PLMD11DynamicListIjE15getNumberActiveEv54828228
_ZNK4PLMD11DynamicListIjE8isActiveERKj422013086
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/DynamicList.h.gcov.html b/coverage/tools/DynamicList.h.gcov.html new file mode 100644 index 000000000000..b9dbfe766f4e --- /dev/null +++ b/coverage/tools/DynamicList.h.gcov.html @@ -0,0 +1,456 @@ + + + + + + + + LCOV - plumed test coverage - tools/DynamicList.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - DynamicList.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4747100.0 %
Date:2024-02-22 21:58:45Functions:1313100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_DynamicList_h
+      23             : #define __PLUMED_tools_DynamicList_h
+      24             : 
+      25             : #include <vector>
+      26             : #include "Communicator.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : /**
+      31             : \ingroup TOOLBOX
+      32             : A class for storing a list that changes which members are active as a function of time.  It also
+      33             : contains friends method that allows you to link two dynamic lists so that you can request
+      34             : stuff from list2 in list1
+      35             : A PLMD::DynamicList can be used to change what elements in a list should be looped over at any given
+      36             : time. This class is, for the most part, used in tandem with PLMD::NeighbourList.  For complex reasons
+      37             : related to the PLMD::MultiColvar object the dynamic list class is separate from PLMD::NeighbourList.
+      38             : This is no bad thing though as there may be occasions where one needs to change the elements currently
+      39             : involved in a calculation using some non neighbour list based method.  To be clear though PLMD::NeighbourList
+      40             : will look after everything connected with PLMD::DynamicList other than the initial setup of PLMD::DynamicList
+      41             : and the loops over the active elements of the list.
+      42             : 
+      43             : The essence of a dynamic list is as follows.  Consider the following loop:
+      44             : 
+      45             : \verbatim
+      46             : std::vector<something> aa;
+      47             : for(unsigned i=0;i<aa.size();++i){ aa[i].doSomething(); }
+      48             : \endverbatim
+      49             : 
+      50             : This takes all the members in aa and does something or other to them - simple.  Now it may well
+      51             : be that the precise set of things from aa that you want to do in any given time or place is not
+      52             : always the same.  We can thus use dynamic lists to control what particular things are done are done
+      53             : at a given time.  That is to say we can use PLMD::DynamicList to specify a subset of things from
+      54             : aa to do at a given time.  This is done by:
+      55             : 
+      56             : \verbatim
+      57             : DynamicList list; std::vector<something> aa; unsigned kk;
+      58             : for(unsigned i=0;i<list.getNumberActive();++i){ kk=list[i]; aa[kk].doSomething(); }
+      59             : \endverbatim
+      60             : 
+      61             : where we somewhere set up the list and make some decisions (in PLMD::NeighbourList for example) as to what elements
+      62             : from aa are currently active.
+      63             : 
+      64             : \section Setup
+      65             : 
+      66             : Setting up a dynamic list is a matter of declaring it and passing a set of indices to it.  For the example
+      67             : above with aa one can do this using:
+      68             : 
+      69             : \verbatim
+      70             : DynamicList list;
+      71             : for(unsigned i=0;i<aa.size();++i) list.addIndexToList( i );
+      72             : \endverbatim
+      73             : 
+      74             : Doing this creates the list of all members.
+      75             : 
+      76             : \section arse1 Cycling over the full set of members
+      77             : 
+      78             : To cycle over the full set of members in the list one should do:
+      79             : 
+      80             : \verbatim
+      81             : for(unsigned i=0;i<list.fullSize();++i){ kk=list(i); aa[kk].doSomething(); }
+      82             : \endverbatim
+      83             : 
+      84             : If the DynamicList was set up as per the example above then this code is equivalent to:
+      85             : 
+      86             : \verbatim
+      87             : for(unsigned i=0;i<aa.size();++i){ aa[i].doSomething(); }
+      88             : \endverbatim
+      89             : 
+      90             : \section arse2 Activating and deactivating members
+      91             : 
+      92             : The important business comes when we start activating and deactivating members.  When we create
+      93             : a dynamic list none of the members are active for business.  Hence, getNumberActive() returns 0.
+      94             : There are four routines that we can use to change this situation.
+      95             : 
+      96             : <table align="center" frame="void" width="95%" cellpadding="5%">
+      97             : <tr>
+      98             : <td width="5%"> activateAll() </td> <td> make all members active </td>
+      99             : </tr><tr>
+     100             : <td> activate(i) </td> <td> make the ith element of the list active (in the example above this mean we doSomething() for element i of aa) </td>
+     101             : </tr><tr>
+     102             : <td> deactivateAll() </td> <td> make all members inactive </td>
+     103             : </tr><tr>
+     104             : <td> deactivate(i) </td> <td> make th ith element of the list active (in the example above this mean we dont doSomething() for element i of aa) </td>
+     105             : </tr>
+     106             : </table>
+     107             : 
+     108             : Once you have activated and deactivated members to your hearts content you can then update the dynamic list using
+     109             : PLMD::DynamicList::updateActiveMembers().  Once this is done you can loop over only the members you have specifically
+     110             : made active using:
+     111             : 
+     112             : \verbatim
+     113             : DynamicList list;
+     114             : for(unsigned i=0;i<list.getNumberActive();++i){ kk=list[i]; aa[kk].doSomething(); }
+     115             : \endverbatim
+     116             : 
+     117             : as was described above.
+     118             : 
+     119             : \section arse3 Using MPI
+     120             : 
+     121             : If your loop is distributed over processesors you can still use dynamic lists to activate and deactivate members.
+     122             : When running with mpi however you must call PLMD::DynamicList::setupMPICommunication during initialization.  To
+     123             : gather the members that have been activated/deactivated during the running of all the processes on all the nodes
+     124             : you must call PLMD::DynamicList::mpi_gatherActiveMembers in place of PLMD::DynamicList::updateActiveMembers.
+     125             : 
+     126             : \section arse4 A final note
+     127             : 
+     128             : When using dynamic_lists we strongly recommend that you first compile without the -DNDEBUG flag.  When this
+     129             : flag is not present many checks are performed inside the dynamic list class, which will help you ensure that
+     130             : the dynamic list is used correctly.
+     131             : 
+     132             : */
+     133             : 
+     134             : template <typename T>
+     135             : class DynamicList {
+     136             : /// This gathers data split across nodes list of Dynamic lists
+     137             :   template <typename U>
+     138             :   friend void mpi_gatherActiveMembers(Communicator&, std::vector< DynamicList<U> >& );
+     139             : private:
+     140             : /// This is the list of all the relevant members
+     141             :   std::vector<T> all;
+     142             : /// This tells us what members of all are on/off at any given time
+     143             :   std::vector<unsigned> onoff;
+     144             : /// The current number of active members
+     145             :   unsigned nactive;
+     146             : /// This is the list of active members
+     147             :   std::vector<unsigned> active;
+     148             : /// the number of processors the jobs in the Dynamic list are distributed across
+     149             :   unsigned nprocessors;
+     150             : /// The rank of the node we are on
+     151             :   unsigned rank;
+     152             : /// These are flags that are used internally to ensure that dynamic lists are being used properly
+     153             :   bool allWereActivated, allWereDeactivated;
+     154             : public:
+     155             : /// Constructor
+     156      360244 :   DynamicList():nactive(0),nprocessors(1),rank(0),allWereActivated(false),allWereDeactivated(false) {}
+     157             : /// An operator that returns the element from the current active list
+     158             :   inline T operator [] (const unsigned& i) const {
+     159             :     plumed_dbg_assert( i<nactive );
+     160   651012274 :     return all[ active[i] ];
+     161             :   }
+     162             : /// An operator that returns the element from the full list (used in neighbour lists)
+     163             :   inline T operator () (const unsigned& i) const {
+     164             :     plumed_dbg_assert( i<all.size() );
+     165             :     return all[i];
+     166             :   }
+     167             : /// Clear the list
+     168             :   void clear();
+     169             : /// Return the total number of elements in the list
+     170             :   unsigned fullSize() const;
+     171             : /// Return the number of elements that are currently active
+     172             :   unsigned getNumberActive() const;
+     173             : /// Find out if a member is active
+     174             :   bool isActive(const unsigned& ) const;
+     175             : /// Setup MPI communication if things are activated/deactivated on different nodes
+     176             :   void setupMPICommunication( Communicator& comm );
+     177             : /// Add something to the active list
+     178             :   void addIndexToList( const T & ii );
+     179             : /// Create the list from a vector
+     180             :   void createIndexListFromVector( const std::vector<T>& myind );
+     181             : /// Find the index of in the list which has value t
+     182             :   int getIndexOfElement( const T& t ) const ;
+     183             : /// Make a particular element inactive
+     184             :   void deactivate( const T& t );
+     185             : /// Make everything in the list inactive
+     186             :   void deactivateAll();
+     187             : /// Make something active
+     188             :   void activate( const unsigned ii );
+     189             : /// Make everything in the list active
+     190             :   void activateAll();
+     191             : /// Do updateActiveMembers for a loop that has been distributed over multiple nodes
+     192             :   void mpi_gatherActiveMembers(Communicator& comm);
+     193             : /// Get the list of active members
+     194             :   void updateActiveMembers();
+     195             : /// Empty the list of active members
+     196             :   void emptyActiveMembers();
+     197             : /// This can be used for a fast version of updateActiveMembers in which only a subset of the
+     198             : /// indexes are checked
+     199             :   void putIndexInActiveArray( const unsigned& ii );
+     200             : /// This can be called on once update is complete
+     201             :   void completeUpdate();
+     202             : /// This tells one if an update has been completed
+     203             :   bool updateComplete() const ;
+     204             : /// This sorts the elements in the active list
+     205             :   void sortActiveList();
+     206             : /// Retriee the list of active objects
+     207             :   std::vector<T> retrieveActiveList();
+     208             : };
+     209             : 
+     210             : template <typename T>
+     211             : std::vector<T> DynamicList<T>::retrieveActiveList() {
+     212             :   std::vector<T> this_active(nactive);
+     213             :   for(unsigned k=0; k<nactive; ++k) this_active[k]=all[ active[k] ];
+     214             :   return this_active;
+     215             : }
+     216             : 
+     217             : template <typename T>
+     218       41860 : void DynamicList<T>::clear() {
+     219       41860 :   all.resize(0);
+     220       41860 :   onoff.resize(0); active.resize(0);
+     221       41860 : }
+     222             : 
+     223             : template <typename T>
+     224   422013086 : bool DynamicList<T>::isActive( const unsigned& i ) const {
+     225   422013086 :   return (onoff[i]>0 && onoff[i]%nprocessors==0);
+     226             : }
+     227             : 
+     228             : template <typename T>
+     229             : unsigned DynamicList<T>::fullSize() const {
+     230             :   return all.size();
+     231             : }
+     232             : 
+     233             : template <typename T>
+     234    54828228 : unsigned DynamicList<T>::getNumberActive() const {
+     235    54828228 :   return nactive;
+     236             : }
+     237             : 
+     238             : template <typename T>
+     239          91 : void DynamicList<T>::addIndexToList( const T & ii ) {
+     240          91 :   all.push_back(ii); active.resize( all.size() ); onoff.push_back(0);
+     241          91 : }
+     242             : 
+     243             : template <typename T>
+     244      402103 : void DynamicList<T>::createIndexListFromVector( const std::vector<T>& myind ) {
+     245      402103 :   plumed_dbg_assert( all.size()==0 ); onoff.resize( myind.size(), 0 );
+     246      402103 :   active.resize( myind.size() );
+     247      402103 :   all.insert( all.end(), myind.begin(), myind.end() );
+     248      402103 : }
+     249             : 
+     250             : template <typename T>
+     251             : void DynamicList<T>::setupMPICommunication( Communicator& comm ) {
+     252             :   nprocessors=comm.Get_size(); rank=comm.Get_rank();
+     253             : }
+     254             : 
+     255             : template <typename T>
+     256             : int DynamicList<T>::getIndexOfElement( const T& t ) const {
+     257             :   for(unsigned i=0; i<all.size(); ++i) {
+     258             :     if( t==all[i] ) {return i; }
+     259             :   }
+     260             :   plumed_merror("Could not find an element in the dynamic list");
+     261             : }
+     262             : 
+     263             : template <typename T>
+     264             : void DynamicList<T>::deactivate( const T& t ) {
+     265             :   plumed_dbg_assert( allWereActivated );
+     266             :   unsigned ii=getIndexOfElement( t );
+     267             :   if( onoff[ii]==0 || onoff[ii]%nprocessors!=0 ) return;
+     268             :   // Deactivates the component
+     269             :   if( rank==0 ) onoff[ii]=nprocessors-1;
+     270             :   else onoff[ii]=nprocessors-rank;
+     271             : }
+     272             : 
+     273             : template <typename T>
+     274     2102018 : void DynamicList<T>::deactivateAll() {
+     275     2102018 :   allWereDeactivated=true; allWereActivated=false;
+     276    82217940 :   for(unsigned i=0; i<nactive; ++i) onoff[ active[i] ]= 0;
+     277     2102018 :   nactive=0;
+     278             : #ifndef NDEBUG
+     279             :   for(unsigned i=0; i<onoff.size(); ++i) plumed_dbg_assert( onoff[i]==0 );
+     280             : #endif
+     281     2102018 : }
+     282             : 
+     283             : template <typename T>
+     284  1565261833 : void DynamicList<T>::activate( const unsigned ii ) {
+     285             :   plumed_dbg_massert(ii<all.size(),"ii is out of bounds");
+     286             :   plumed_dbg_assert( !allWereActivated );
+     287  1565261833 :   onoff[ii]=nprocessors;
+     288  1565261833 : }
+     289             : 
+     290             : template <typename T>
+     291             : void DynamicList<T>::activateAll() {
+     292             :   for(unsigned i=0; i<onoff.size(); ++i) onoff[i]=nprocessors;
+     293             :   allWereActivated=true; updateActiveMembers(); allWereActivated=true;
+     294             : 
+     295             : }
+     296             : 
+     297             : template <typename T>
+     298             : void DynamicList<T>::mpi_gatherActiveMembers(Communicator& comm) {
+     299             :   plumed_massert( comm.Get_size()==nprocessors, "error missing a call to DynamicList::setupMPICommunication");
+     300             :   comm.Sum(&onoff[0],onoff.size());
+     301             :   // When we mpi gather onoff to be on it should be active on ALL nodes
+     302             :   for(unsigned i=0; i<all.size(); ++i) if( onoff[i]>0 && onoff[i]%nprocessors==0 ) { onoff[i]=nprocessors; }
+     303             :   updateActiveMembers();
+     304             : }
+     305             : 
+     306             : template <typename T>
+     307       62072 : void DynamicList<T>::updateActiveMembers() {
+     308             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     309       62072 :   unsigned kk=0; allWereActivated=allWereDeactivated=false;
+     310    19025522 :   for(unsigned i=0; i<all.size(); ++i) {
+     311    18963450 :     if( onoff[i]>0 && onoff[i]%nprocessors==0 ) { active[kk]=i; kk++; }
+     312             :   }
+     313       62072 :   nactive=kk;
+     314       62072 : }
+     315             : 
+     316             : template <typename T>
+     317      934288 : void DynamicList<T>::emptyActiveMembers() {
+     318             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     319      934288 :   nactive=0;
+     320      934288 : }
+     321             : 
+     322             : template <typename T>
+     323    77517572 : void DynamicList<T>::putIndexInActiveArray( const unsigned& ii ) {
+     324             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     325             :   plumed_dbg_assert( onoff[ii]>0 && onoff[ii]%nprocessors==0 );
+     326    77517572 :   active[nactive]=ii; nactive++;
+     327    77517572 : }
+     328             : 
+     329             : template <typename T>
+     330      877983 : void DynamicList<T>::completeUpdate() {
+     331             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     332      877983 :   allWereActivated=allWereDeactivated=false;
+     333      877983 : }
+     334             : 
+     335             : template <typename T>
+     336       56305 : void DynamicList<T>::sortActiveList() {
+     337             :   plumed_dbg_assert( allWereActivated || allWereDeactivated );
+     338       56305 :   allWereActivated=allWereDeactivated=false;
+     339       56305 :   std::sort( active.begin(), active.begin()+nactive );
+     340       56305 : }
+     341             : 
+     342             : template <typename T>
+     343     4920287 : bool DynamicList<T>::updateComplete() const {
+     344     4920287 :   if( !allWereActivated && !allWereDeactivated ) return true;
+     345             :   return false;
+     346             : }
+     347             : 
+     348             : template <typename U>
+     349             : void mpi_gatherActiveMembers(Communicator& comm, std::vector< DynamicList<U> >& ll ) {
+     350             :   // Setup an array to hold all data
+     351             :   unsigned bufsize=0; unsigned size=comm.Get_size();
+     352             :   for(unsigned i=0; i<ll.size(); ++i) {
+     353             :     plumed_dbg_massert( ll[i].nprocessors==size, "missing a call to DynamicList::setupMPICommunication" );
+     354             :     bufsize+=ll[i].onoff.size();
+     355             :   }
+     356             :   std::vector<unsigned> buffer( bufsize );
+     357             :   // Gather all onoff data into a single array
+     358             :   bufsize=0;
+     359             :   for(unsigned i=0; i<ll.size(); ++i) {
+     360             :     for(unsigned j=0; j<ll[i].onoff.size(); ++j) { buffer[bufsize]=ll[i].onoff[j]; bufsize++; }
+     361             :   }
+     362             :   // GATHER from all nodes
+     363             :   comm.Sum(&buffer[0],buffer.size());
+     364             :   // distribute back to original lists
+     365             :   bufsize=0;
+     366             :   for(unsigned i=0; i<ll.size(); ++i) {
+     367             :     for(unsigned j=0; j<ll[i].onoff.size(); ++j) {
+     368             :       if( buffer[bufsize]>0 && buffer[bufsize]%size==0 ) ll[i].onoff[j]=size;
+     369             :       else ll[i].onoff[j]=size-1;
+     370             :       bufsize++;
+     371             :     }
+     372             :   }
+     373             :   for(unsigned i=0; i<ll.size(); ++i) ll[i].updateActiveMembers();
+     374             : }
+     375             : 
+     376             : }
+     377             : 
+     378             : #endif
+     379             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.cpp.func-sort-c.html b/coverage/tools/ERMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..f800c827e5a4 --- /dev/null +++ b/coverage/tools/ERMSD.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12012298.4 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5ERMSD5clearEv0
_ZN4PLMD5ERMSD12setReferenceERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEEd4
_ZN4PLMD5ERMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERS5_RNS_13TensorGenericILj3ELj3EEE222
_ZN4PLMD5ERMSD7calcMatERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERS1_INS2_ILj4EEESaISB_EERS1_INS_13TensorGenericILj4ELj3EEESaISG_EE226
_ZN4PLMD5ERMSD6inPairEjj1139266
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.cpp.func.html b/coverage/tools/ERMSD.cpp.func.html new file mode 100644 index 000000000000..c51da8f985c8 --- /dev/null +++ b/coverage/tools/ERMSD.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12012298.4 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5ERMSD12setReferenceERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEEd4
_ZN4PLMD5ERMSD5clearEv0
_ZN4PLMD5ERMSD6inPairEjj1139266
_ZN4PLMD5ERMSD7calcMatERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERS1_INS2_ILj4EEESaISB_EERS1_INS_13TensorGenericILj4ELj3EEESaISG_EE226
_ZN4PLMD5ERMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKNS_3PbcERS5_RNS_13TensorGenericILj3ELj3EEE222
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.cpp.gcov.html b/coverage/tools/ERMSD.cpp.gcov.html new file mode 100644 index 000000000000..052cd11e626e --- /dev/null +++ b/coverage/tools/ERMSD.cpp.gcov.html @@ -0,0 +1,380 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12012298.4 %
Date:2024-02-22 21:58:45Functions:4580.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : /*
+      24             :  This vast majority of the source code in this file was writting by
+      25             :  Sandro Bottaro with some help from Giovanni Bussi
+      26             : */
+      27             : 
+      28             : #include "ERMSD.h"
+      29             : #include "PDB.h"
+      30             : #include "Matrix.h"
+      31             : #include "Tensor.h"
+      32             : 
+      33             : #include "Pbc.h"
+      34             : #include <cmath>
+      35             : #include <iostream>
+      36             : 
+      37             : 
+      38             : namespace PLMD {
+      39             : 
+      40           0 : void ERMSD::clear() {
+      41             :   reference_mat.clear();
+      42           0 : }
+      43             : 
+      44             : //void ERMSD::calcLcs(const vector<Vector> & positions, vector<Vector> &)
+      45             : 
+      46           4 : void ERMSD::setReference(const std::vector<Vector> & reference, const std::vector<unsigned> & pairs_vec, double mycutoff) {
+      47             : 
+      48           4 :   natoms = reference.size();
+      49           4 :   nresidues = natoms/3;
+      50           4 :   unsigned npairs = pairs_vec.size()/2;
+      51           4 :   pairs.resize(npairs);
+      52          16 :   for(unsigned i=0; i<npairs; ++i) {
+      53             : 
+      54          12 :     pairs[i].first = pairs_vec[2*i];
+      55          12 :     pairs[i].second = pairs_vec[2*i+1];
+      56             :   }
+      57             : 
+      58           4 :   cutoff = mycutoff;
+      59             :   std::vector<TensorGeneric<4,3> > deri;
+      60           4 :   deri.resize(natoms*natoms);
+      61           4 :   reference_mat.resize(nresidues*nresidues);
+      62           4 :   Pbc fake_pbc;
+      63             : 
+      64           4 :   calcMat(reference,fake_pbc,reference_mat,deri);
+      65             : 
+      66           4 : }
+      67             : 
+      68     1139266 : bool ERMSD::inPair(unsigned i, unsigned j) {
+      69             : 
+      70     1139266 :   if(pairs.size()==0) return true;
+      71     3982685 :   for(unsigned idx=0; idx<pairs.size(); idx++) {
+      72     3414408 :     if(pairs[idx].first == i && pairs[idx].second == j) return true;
+      73     3413730 :     if(pairs[idx].second == i && pairs[idx].first == j) return true;
+      74             :   }
+      75             :   return false;
+      76             : }
+      77             : 
+      78         226 : void ERMSD::calcMat(const std::vector<Vector> & positions,const Pbc& pbc, std::vector<Vector4d> &mat, std::vector<TensorGeneric<4,3> > &Gderi) {
+      79             : 
+      80             :   std::vector<Vector3d> pos;
+      81         226 :   pos.resize(3*nresidues);
+      82             : 
+      83             :   std::vector<Tensor3d> deri;
+      84         226 :   deri.resize(nresidues*9);
+      85             : 
+      86             :   std::vector<Vector> centers;
+      87         226 :   centers.resize(nresidues);
+      88             : 
+      89             :   unsigned idx_deri = 0;
+      90             : 
+      91         226 :   Tensor da_dxa = (2./3.)*Tensor::identity();
+      92         226 :   Tensor da_dxb = -(1./3.)*Tensor::identity();
+      93         226 :   Tensor da_dxc = -(1./3.)*Tensor::identity();
+      94             : 
+      95         226 :   Tensor db_dxa = -(1./3.)*Tensor::identity();
+      96         226 :   Tensor db_dxb = (2./3.)*Tensor::identity();
+      97         226 :   Tensor db_dxc = -(1./3.)*Tensor::identity();
+      98             : 
+      99             :   // Form factors - should this be somewhere else?
+     100             : 
+     101             :   double w = 1./3.;
+     102         226 :   Vector form_factor = Vector(2.0,2.0,1.0/0.3);
+     103             : 
+     104       16272 :   for(unsigned res_idx=0; res_idx<natoms/3; res_idx++) {
+     105             : 
+     106             : 
+     107       16046 :     const unsigned at_idx = 3*res_idx;
+     108             :     //center
+     109       64184 :     for (unsigned j=0; j<3; j++) {
+     110       48138 :       centers[res_idx] += w*positions[at_idx+j];
+     111             :     }
+     112             : 
+     113       16046 :     Vector3d a = delta(centers[res_idx],positions[at_idx]);
+     114       16046 :     Vector3d b = delta(centers[res_idx],positions[at_idx+1]);
+     115       16046 :     Vector3d d = crossProduct(a,b);
+     116       16046 :     double ianorm = 1./a.modulo();
+     117       16046 :     double idnorm = 1./d.modulo();
+     118             : 
+     119             :     // X vector: COM-C2
+     120       16046 :     pos[at_idx] = a*ianorm;
+     121             :     // Z versor: C2 x (COM-C4/C6)
+     122       16046 :     pos[at_idx+2] = d*idnorm;
+     123             :     // Y versor: Z x Y
+     124       16046 :     pos[at_idx+1] = crossProduct(pos[at_idx+2],pos[at_idx]);
+     125             : 
+     126             :     // Derivatives ////////
+     127       16046 :     Tensor3d t1 = ianorm*(Tensor::identity()-extProduct(pos[at_idx],pos[at_idx]));
+     128             :     // dv1/dxa
+     129       16046 :     deri[idx_deri] = (2./3. )*t1;
+     130             :     // dv1/dxb
+     131       16046 :     deri[idx_deri+3] = -(1./3.)*t1;
+     132             :     // dv1/dxc
+     133       16046 :     deri[idx_deri+6] = -(1./3.)*t1;
+     134             : 
+     135       16046 :     Tensor dd_dxa =  VcrossTensor(a,db_dxa) -VcrossTensor(b,da_dxa);
+     136       16046 :     Tensor dd_dxb =  VcrossTensor(a,db_dxb)-VcrossTensor(b,da_dxb);
+     137       16046 :     Tensor dd_dxc =  VcrossTensor(a,db_dxc)-VcrossTensor(b,da_dxc);
+     138             : 
+     139             :     // dv3/dxa
+     140       16046 :     deri[idx_deri+2] = deriNorm(d,dd_dxa);
+     141             :     // dv3/dxb
+     142       16046 :     deri[idx_deri+5] = deriNorm(d,dd_dxb);
+     143             :     // dv3/dxc
+     144       16046 :     deri[idx_deri+8] = deriNorm(d,dd_dxc);
+     145             : 
+     146             :     // dv2/dxa = dv3/dxa cross v1 + v3 cross dv1/dxa
+     147       32092 :     deri[idx_deri+1] =  (VcrossTensor(deri[idx_deri+2],pos[at_idx]) + \
+     148       32092 :                          VcrossTensor(pos[at_idx+2],deri[idx_deri]));
+     149             :     // dv2/dxb
+     150       32092 :     deri[idx_deri+4] =  (VcrossTensor(deri[idx_deri+5],pos[at_idx]) + \
+     151       32092 :                          VcrossTensor(pos[at_idx+2],deri[idx_deri+3]));
+     152             :     // dv2/dxc
+     153       32092 :     deri[idx_deri+7] =  (VcrossTensor(deri[idx_deri+8],pos[at_idx]) + \
+     154       32092 :                          VcrossTensor(pos[at_idx+2],deri[idx_deri+6]));
+     155             : 
+     156       16046 :     idx_deri += 9;
+     157             :     // End derivatives ///////
+     158             : 
+     159             :   }
+     160             : 
+     161             : 
+     162             :   // Initialization (unnecessary?)
+     163     1139492 :   for (unsigned i1=0; i1<nresidues*nresidues; i1++) {
+     164     5696330 :     for (unsigned i2=0; i2<4; i2++) {
+     165     4557064 :       mat[i1][i2] = 0.0;
+     166             :     }
+     167             :   }
+     168             : 
+     169         226 :   double maxdist = cutoff/form_factor[0];
+     170         226 :   double gamma = pi/cutoff;
+     171             :   unsigned idx;
+     172             :   unsigned idx1 = 0;
+     173             :   // Calculate mat
+     174       16272 :   for (unsigned i=0; i<nresidues; i++) {
+     175     1155312 :     for (unsigned j=0; j<nresidues; j++) {
+     176             : 
+     177             :       // skip i==j
+     178     1139266 :       if(inPair(i,j) and i != j) {
+     179             :         //if(i!=j){
+     180             : 
+     181             : 
+     182             :         // Calculate normal distance first
+     183      562966 :         Vector diff = delta(centers[i],centers[j]);
+     184      562966 :         double d1 = diff.modulo();
+     185      562966 :         if(d1<maxdist) {
+     186             : 
+     187             :           // calculate r_tilde_ij
+     188       85382 :           Vector3d rtilde;
+     189      341528 :           for (unsigned k=0; k<3; k++) {
+     190     1024584 :             for (unsigned l=0; l<3; l++) {
+     191      768438 :               rtilde[l] += pos[3*i+l][k]*diff[k]*form_factor[l];
+     192             :             }
+     193             :           }
+     194       85382 :           double rtilde_norm = rtilde.modulo();
+     195             : 
+     196       85382 :           double irnorm = 1./rtilde_norm;
+     197             : 
+     198             :           // ellipsoidal cutoff
+     199       85382 :           if(rtilde_norm < cutoff) {
+     200       53822 :             idx = i*nresidues + j;
+     201             : 
+     202             : 
+     203             :             // fill 4d matrix
+     204       53822 :             double dummy = std::sin(gamma*rtilde_norm)/(rtilde_norm*gamma);
+     205       53822 :             mat[idx][0] = dummy*rtilde[0];
+     206       53822 :             mat[idx][1] = dummy*rtilde[1];
+     207       53822 :             mat[idx][2] = dummy*rtilde[2];
+     208       53822 :             mat[idx][3] = (1.+ std::cos(gamma*rtilde_norm))/gamma;
+     209             : 
+     210             :             // Derivative (drtilde_dx)
+     211             :             std::vector<Tensor3d> drtilde_dx;
+     212       53822 :             drtilde_dx.resize(6);
+     213       53822 :             unsigned pos_idx = 3*i;
+     214       53822 :             unsigned deri_idx = 9*i;
+     215      215288 :             for (unsigned at=0; at<3; at++) {
+     216      645864 :               for (unsigned l=0; l<3; l++) {
+     217      484398 :                 Vector3d rvec = form_factor[l]*((pos[pos_idx+l])/3.);
+     218      484398 :                 Vector3d vvec = form_factor[l]*(matmul(deri[deri_idx+3*at+l],diff));
+     219      484398 :                 drtilde_dx[at].setRow(l,vvec-rvec);
+     220      484398 :                 drtilde_dx[at+3].setRow(l,rvec);
+     221             :               }
+     222             :             }
+     223             : 
+     224       53822 :             double dummy1 = (std::cos(gamma*rtilde_norm) - dummy);
+     225             : 
+     226       53822 :             idx1 = i*nresidues*6 + j*6;
+     227             : 
+     228      376754 :             for (unsigned l=0; l<6; l++) {
+     229             :               //std::cout << i << " " << j << " " << idx1 << " " << idx1+l << "\n";
+     230             : 
+     231             :               // components 1,2,3
+     232             :               // std::sin(gamma*|rtilde|)/gamma*|rtilde|*d_rtilde +
+     233             :               // + ((d_rtilde*r_tilde/r_tilde^2) out r_tilde)*
+     234             :               // (std::cos(gamma*|rtilde| - std::sin(gamma*|rtilde|)/gamma*|rtilde|))
+     235      322932 :               Vector3d rdr = matmul(rtilde,drtilde_dx[l]);
+     236      322932 :               Tensor tt = dummy*drtilde_dx[l] + (dummy1*irnorm*irnorm)*Tensor(rtilde,rdr);
+     237     1291728 :               for (unsigned m=0; m<3; m++) {
+     238             :                 // Transpose here
+     239             :                 //dG_dx[l].setRow(m,tt.getRow(m));
+     240      968796 :                 Gderi[idx1+l].setRow(m,tt.getRow(m));
+     241             :               }
+     242             :               // component 4
+     243             :               // - std::sin(gamma*|rtilde|)/|rtilde|*(r_tilde*d_rtilde)
+     244             :               //dG_dx[l].setRow(3,-dummy*gamma*rdr);
+     245      322932 :               Gderi[idx1+l].setRow(3,-dummy*gamma*rdr);
+     246             :             }
+     247             : 
+     248             : 
+     249             : 
+     250             : 
+     251             :           }
+     252             :         }
+     253             :       }
+     254             : 
+     255             :     }
+     256             :   }
+     257             : 
+     258         226 : }
+     259             : 
+     260             : 
+     261         222 : double ERMSD::calculate(const std::vector<Vector> & positions,const Pbc& pbc,\
+     262             :                         std::vector<Vector> &derivatives, Tensor& virial) {
+     263             : 
+     264             : 
+     265             :   double ermsd=0.;
+     266             :   std::vector<Vector4d> mat;
+     267         222 :   mat.resize(nresidues*nresidues);
+     268             : 
+     269             :   std::vector<TensorGeneric<4,3> > Gderi;
+     270         222 :   Gderi.resize(natoms*natoms);
+     271             : 
+     272         222 :   calcMat(positions,pbc,mat,Gderi);
+     273             : 
+     274             :   unsigned idx1 = 0;
+     275       15984 :   for(unsigned i=0; i<nresidues; i++) {
+     276     1134864 :     for(unsigned j=0; j<nresidues; j++) {
+     277     1119102 :       unsigned ii = i*nresidues + j;
+     278             : 
+     279     1119102 :       Vector4d dd = delta(reference_mat[ii],mat[ii]);
+     280     1119102 :       double val = dd.modulo2();
+     281             : 
+     282     1119102 :       if(val>0.0 && i!=j) {
+     283             : 
+     284      256596 :         for(unsigned k=0; k<3; k++) {
+     285      192447 :           idx1 = i*nresidues*6 + j*6 + k;
+     286             : 
+     287      192447 :           derivatives[3*i+k] += matmul(dd,Gderi[idx1]);
+     288      192447 :           derivatives[3*j+k] += matmul(dd,Gderi[idx1+3]);
+     289             :         }
+     290       64149 :         ermsd += val;
+     291             :       }
+     292             :     }
+     293             :   }
+     294             : 
+     295         222 :   ermsd = std::sqrt(ermsd/nresidues);
+     296         222 :   double iermsd = 1.0/(ermsd*nresidues);
+     297       47508 :   for(unsigned i=0; i<natoms; ++i) {derivatives[i] *= iermsd;}
+     298             : 
+     299         222 :   return ermsd;
+     300             : }
+     301             : 
+     302             : 
+     303             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.h.func-sort-c.html b/coverage/tools/ERMSD.h.func-sort-c.html new file mode 100644 index 000000000000..d0deba6acf49 --- /dev/null +++ b/coverage/tools/ERMSD.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.h.func.html b/coverage/tools/ERMSD.h.func.html new file mode 100644 index 000000000000..0bd4c15da088 --- /dev/null +++ b/coverage/tools/ERMSD.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ERMSD.h.gcov.html b/coverage/tools/ERMSD.h.gcov.html new file mode 100644 index 000000000000..de6b0882a207 --- /dev/null +++ b/coverage/tools/ERMSD.h.gcov.html @@ -0,0 +1,150 @@ + + + + + + + + LCOV - plumed test coverage - tools/ERMSD.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ERMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1250.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_ERMSD_h
+      23             : #define __PLUMED_tools_ERMSD_h
+      24             : 
+      25             : #include "Tensor.h"
+      26             : #include "Vector.h"
+      27             : #include <vector>
+      28             : #include <limits>
+      29             : #include <string>
+      30             : #include <map>
+      31             : #include <utility>
+      32             : #include <cstddef>
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : class PDB;
+      37             : class Pbc;
+      38             : 
+      39             : /// A class that implements ERMSD calculations
+      40           0 : class ERMSD {
+      41             :   //std::map< std::pair <unsigned,unsigned> , double> targets;
+      42             :   //unsigned natoms;
+      43             :   std::vector<Vector4d> reference_mat;
+      44             :   std::size_t natoms;
+      45             :   std::size_t nresidues;
+      46             :   std::vector<std::pair <unsigned,unsigned> > pairs;
+      47             :   double cutoff;
+      48             : 
+      49             : public:
+      50             : /// Constructor
+      51           4 :   ERMSD(): natoms(0),nresidues(0), cutoff(0.0) {}
+      52             : 
+      53             : /// clear the structure
+      54             :   void clear();
+      55             : 
+      56             :   bool inPair(unsigned i, unsigned j);
+      57             : 
+      58             : /// set reference coordinates
+      59             :   void setReference(const std::vector<Vector> & reference, const std::vector<unsigned> & pairs_vec,double mycutoff=0.24);
+      60             : 
+      61             :   void calcMat(const std::vector<Vector> & positions, const Pbc& pbc,std::vector<Vector4d> &mat,std::vector<TensorGeneric<4,3> > & Gderivatives);
+      62             : 
+      63             : /// Compute ermsd ( no pbc )
+      64             : //  double calculate(const std::vector<Vector> & positions,
+      65             : //                   std::vector<Vector> &derivatives, Tensor& virial) const ;
+      66             : /// Compute ermsd ( with pbc )
+      67             :   double calculate(const std::vector<Vector>& positions, const Pbc& pbc,std::vector<Vector> &derivatives, Tensor& virial);
+      68             : };
+      69             : 
+      70             : }
+      71             : 
+      72             : #endif
+      73             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.cpp.func-sort-c.html b/coverage/tools/Exception.cpp.func-sort-c.html new file mode 100644 index 000000000000..e931982e583e --- /dev/null +++ b/coverage/tools/Exception.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9Exception5stackEv4
_ZN4PLMD9ExceptionlsERKNS0_9AssertionE10
_ZN4PLMD12_GLOBAL__N_18simplifyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE57
_ZN4PLMD9ExceptionlsERKNS0_8LocationE57
_ZN4PLMD9ExceptionC2Ev96
_ZN4PLMD9ExceptionlsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE149
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.cpp.func.html b/coverage/tools/Exception.cpp.func.html new file mode 100644 index 000000000000..9172c6b11cd1 --- /dev/null +++ b/coverage/tools/Exception.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_18simplifyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE57
_ZN4PLMD9ExceptionC2Ev96
_ZN4PLMD9ExceptionlsERKNS0_8LocationE57
_ZN4PLMD9ExceptionlsERKNS0_9AssertionE10
_ZN4PLMD9ExceptionlsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE149
_ZNK4PLMD9Exception5stackEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.cpp.gcov.html b/coverage/tools/Exception.cpp.gcov.html new file mode 100644 index 000000000000..69b313e9fdf7 --- /dev/null +++ b/coverage/tools/Exception.cpp.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:485194.1 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Exception.h"
+      23             : 
+      24             : #if defined(__PLUMED_HAS_EXECINFO)
+      25             : #include <execinfo.h>
+      26             : #endif
+      27             : 
+      28             : #include <cstdio>
+      29             : #include <cstring>
+      30             : #include <cstdlib>
+      31             : #include <vector>
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : namespace {
+      36             : // see https://www.geeksforgeeks.org/simplify-directory-path-unix-like/
+      37             : 
+      38             : // function to simplify a Unix - styled
+      39             : // absolute path
+      40          57 : std::string simplify(const std::string & path)
+      41             : {
+      42             :   // using vector in place of stack
+      43             :   std::vector<std::string> v;
+      44          57 :   int n = path.length();
+      45             :   std::string ans;
+      46         189 :   for (int i = 0; i < n; i++) {
+      47         132 :     std::string dir = "";
+      48             :     // forming the current directory.
+      49        1155 :     while (i < n && path[i] != '/') {
+      50        1023 :       dir += path[i];
+      51        1023 :       i++;
+      52             :     }
+      53             : 
+      54             :     // if ".." , we pop.
+      55         132 :     if (dir == "..") {
+      56           6 :       if (!v.empty())
+      57             :         v.pop_back();
+      58             :     }
+      59         252 :     else if (dir == "." || dir == "") {
+      60             :       // do nothing (added for better understanding.)
+      61             :     }
+      62             :     else {
+      63             :       // push the current directory into the vector.
+      64         125 :       v.push_back(dir);
+      65             :     }
+      66             :   }
+      67             : 
+      68             :   // forming the ans
+      69             :   bool first=true;
+      70         176 :   for (const auto & i : v) {
+      71         119 :     if(!first) ans += "/";
+      72             :     first=false;
+      73             :     ans += i;
+      74             :   }
+      75             : 
+      76             :   // vector is empty
+      77          57 :   if (ans == "")
+      78           0 :     return "/";
+      79             : 
+      80             :   return ans;
+      81          57 : }
+      82             : 
+      83             : }
+      84             : 
+      85          96 : Exception::Exception()
+      86             : {
+      87             :   callstack.fill(nullptr);
+      88             : #ifdef __PLUMED_HAS_EXECINFO
+      89          96 :   callstack_n = backtrace(&callstack[0], callstack.size()-1);
+      90          96 :   const char* env=std::getenv("PLUMED_STACK_TRACE");
+      91          96 :   if(env && !std::strcmp(env,"yes")) {
+      92             :     msg+="\n\n********** STACK DUMP **********\n";
+      93           4 :     msg+=stack();
+      94             :     msg+="\n********** END STACK DUMP **********\n";
+      95             :   }
+      96             : #endif
+      97          96 : }
+      98             : 
+      99         149 : Exception& Exception::operator<<(const std::string&msg)
+     100             : {
+     101         149 :   if(msg.length()>0) {
+     102         149 :     if(note) this->msg +="\n";
+     103         149 :     this->msg +=msg;
+     104         149 :     note=false;
+     105             :   }
+     106         149 :   return *this;
+     107             : }
+     108             : 
+     109          57 : Exception& Exception::operator<<(const Location&loc)
+     110             : {
+     111          57 :   if(loc.file) {
+     112             :     const std::size_t clinelen=1000;
+     113             :     char cline[clinelen];
+     114          57 :     std::snprintf(cline,clinelen,"%u",loc.line);
+     115          57 :     this->msg += "\n(";
+     116             :     try {
+     117         114 :       this->msg += simplify(loc.file);
+     118           0 :     } catch(...) {
+     119             :       // ignore
+     120           0 :     }
+     121             :     this->msg += ":";
+     122             :     this->msg += cline;
+     123             :     this->msg += ")";
+     124          57 :     if(loc.pretty && loc.pretty[0]) {
+     125             :       this->msg += " ";
+     126          57 :       this->msg += loc.pretty;
+     127             :     }
+     128             :   }
+     129          57 :   note=true;
+     130          57 :   return *this;
+     131             : }
+     132             : 
+     133          10 : Exception& Exception::operator<<(const Assertion&as)
+     134             : {
+     135          10 :   if(as.assertion) {
+     136          10 :     this->msg += "\n+++ assertion failed: ";
+     137          10 :     this->msg += as.assertion;
+     138             :   }
+     139          10 :   note=true;
+     140          10 :   return *this;
+     141             : }
+     142             : 
+     143           4 : const char* Exception::stack() const {
+     144             : #ifdef __PLUMED_HAS_EXECINFO
+     145           4 :   if(stackTrace.length()==0) {
+     146           4 :     char** strs = backtrace_symbols(&callstack[0], callstack_n);
+     147          39 :     for (int i = 0; i < callstack_n; ++i) {stackTrace+=strs[i]; stackTrace+="\n";}
+     148           4 :     free(strs);
+     149             :   }
+     150             : #endif
+     151           4 :   return stackTrace.c_str();
+     152             : }
+     153             : 
+     154             : }
+     155             : 
+     156             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.h.func-sort-c.html b/coverage/tools/Exception.h.func-sort-c.html new file mode 100644 index 000000000000..5cad9efb2a47 --- /dev/null +++ b/coverage/tools/Exception.h.func-sort-c.html @@ -0,0 +1,621 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333691.7 %
Date:2024-02-22 21:58:45Functions:2513718.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9ExceptionD0Ev0
_ZN4PLMD9ExceptionlsIA100_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA102_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA103_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA104_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA108_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA10_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA110_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA111_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA113_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA115_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA116_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA118_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA119_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA120_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA124_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA129_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA12_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA130_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA131_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA133_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA134_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA13_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA140_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA145_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA148_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA14_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA155_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA156_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA15_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA165_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA166_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA171_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA17_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA20_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA21_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA22_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA24_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA256_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA25_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA26_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA28_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA29_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA32_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA33_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA34_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA36_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA37_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA38_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA39_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA40_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA41_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA42_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA44_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA45_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA46_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA47_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA48_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA49_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA500_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA51_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA52_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA53_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA54_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA55_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA56_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA57_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA59_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA60_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA61_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA62_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA63_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA64_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA65_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA67_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA69_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA6_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA70_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA71_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA72_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA73_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA74_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA75_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA76_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA77_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA78_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA79_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA7_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA80_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA81_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA82_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA84_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA85_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA86_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA87_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA8_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA90_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA91_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA92_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA93_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA94_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA96_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA98_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj3ELj3EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj4ELj4EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsIPKcEERS0_RKT_0
_ZN4PLMD9ExceptionlsIPcEERS0_RKT_0
_ZN4PLMD9ExceptionlsIdEERS0_RKT_0
_ZN4PLMD9ExceptionlsIiEERS0_RKT_0
_ZN4PLMD9ExceptionlsIjEERS0_RKT_0
_ZN4PLMD9ExceptionlsIlEERS0_RKT_0
_ZN4PLMD9ExceptionlsIxEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA105_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA2_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA35_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA43_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA58_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA68_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA83_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA89_cEERS0_RKT_1
_ZN4PLMD9Exception5ThrowlSIRNS_14ExceptionErrorEEEvOT_2
_ZN4PLMD9ExceptionlsIA18_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA19_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA95_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA31_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA3_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA30_cEERS0_RKT_4
_ZN4PLMD9ExceptionlsImEERS0_RKT_4
_ZN4PLMD9ExceptionlsIA50_cEERS0_RKT_5
_ZN4PLMD9ExceptionlsIA9_cEERS0_RKT_5
_ZN4PLMD9ExceptionlsIA23_cEERS0_RKT_6
_ZN4PLMD9ExceptionlsIA66_cEERS0_RKT_7
_ZN4PLMD9ExceptionlsISt17basic_string_viewIcSt11char_traitsIcEEEERS0_RKT_10
_ZN4PLMD9ExceptionC2ERKS0_26
_ZN4PLMD9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31
_ZNK4PLMD9Exception4whatEv39
_ZN4PLMD9ExceptionD2Ev56
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.h.func.html b/coverage/tools/Exception.h.func.html new file mode 100644 index 000000000000..7237c49a5b5c --- /dev/null +++ b/coverage/tools/Exception.h.func.html @@ -0,0 +1,621 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333691.7 %
Date:2024-02-22 21:58:45Functions:2513718.2 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Exception5ThrowlSIRNS_14ExceptionErrorEEEvOT_2
_ZN4PLMD9ExceptionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE31
_ZN4PLMD9ExceptionC2ERKS0_26
_ZN4PLMD9ExceptionD0Ev0
_ZN4PLMD9ExceptionD2Ev56
_ZN4PLMD9ExceptionlsIA100_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA102_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA103_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA104_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA105_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA108_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA10_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA110_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA111_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA113_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA115_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA116_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA118_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA119_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA120_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA124_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA129_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA12_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA130_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA131_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA133_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA134_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA13_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA140_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA145_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA148_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA14_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA155_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA156_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA15_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA165_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA166_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA171_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA17_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA18_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA19_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA20_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA21_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA22_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA23_cEERS0_RKT_6
_ZN4PLMD9ExceptionlsIA24_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA256_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA25_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA26_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA28_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA29_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA2_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA30_cEERS0_RKT_4
_ZN4PLMD9ExceptionlsIA31_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA32_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA33_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA34_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA35_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA36_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA37_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA38_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA39_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA3_cEERS0_RKT_3
_ZN4PLMD9ExceptionlsIA40_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA41_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA42_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA43_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA44_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA45_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA46_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA47_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA48_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA49_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA500_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA50_cEERS0_RKT_5
_ZN4PLMD9ExceptionlsIA51_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA52_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA53_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA54_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA55_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA56_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA57_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA58_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA59_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA60_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA61_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA62_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA63_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA64_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA65_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA66_cEERS0_RKT_7
_ZN4PLMD9ExceptionlsIA67_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA68_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA69_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA6_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA70_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA71_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA72_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA73_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA74_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA75_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA76_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA77_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA78_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA79_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA7_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA80_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA81_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA82_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA83_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA84_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA85_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA86_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA87_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA89_cEERS0_RKT_1
_ZN4PLMD9ExceptionlsIA8_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA90_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA91_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA92_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA93_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA94_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA95_cEERS0_RKT_2
_ZN4PLMD9ExceptionlsIA96_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA98_cEERS0_RKT_0
_ZN4PLMD9ExceptionlsIA9_cEERS0_RKT_5
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj3ELj3EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsINS_13TensorGenericILj4ELj4EEEEERS0_RKT_0
_ZN4PLMD9ExceptionlsIPKcEERS0_RKT_0
_ZN4PLMD9ExceptionlsIPcEERS0_RKT_0
_ZN4PLMD9ExceptionlsISt17basic_string_viewIcSt11char_traitsIcEEEERS0_RKT_10
_ZN4PLMD9ExceptionlsIdEERS0_RKT_0
_ZN4PLMD9ExceptionlsIiEERS0_RKT_0
_ZN4PLMD9ExceptionlsIjEERS0_RKT_0
_ZN4PLMD9ExceptionlsIlEERS0_RKT_0
_ZN4PLMD9ExceptionlsImEERS0_RKT_4
_ZN4PLMD9ExceptionlsIxEERS0_RKT_0
_ZNK4PLMD9Exception4whatEv39
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Exception.h.gcov.html b/coverage/tools/Exception.h.gcov.html new file mode 100644 index 000000000000..b9daf36a1421 --- /dev/null +++ b/coverage/tools/Exception.h.gcov.html @@ -0,0 +1,480 @@ + + + + + + + + LCOV - plumed test coverage - tools/Exception.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Exception.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333691.7 %
Date:2024-02-22 21:58:45Functions:2513718.2 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Exception_h
+      23             : #define __PLUMED_tools_Exception_h
+      24             : 
+      25             : #include <exception>
+      26             : #include <string>
+      27             : #include <stdexcept>
+      28             : #include <sstream>
+      29             : #include <array>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /**
+      34             : \ingroup TOOLBOX
+      35             : Class to deal with Plumed runtime errors.
+      36             : 
+      37             : This class and the related macros can be used to detect programming
+      38             : errors. Typical cases are internal inconsistencies or errors in the plumed<->MD
+      39             : interface. Mistakes made by final users (i.e. in the `plumed.dat` file)
+      40             : should probably be documented in some better way (e.g. printing parts of the manual in the output).
+      41             : However, also this class allows for significant information to be attached.
+      42             : Let's try to make error messages as informative as possible!
+      43             : 
+      44             : \note This class has been rewritten in PLUMED 2.5. It works in a backward compatible manner,
+      45             : but is much more flexible. The main novelty is that we can use insertion operators to
+      46             : add arbitrary messages, as in `plumed_error()<<"check this vector "<<v;`
+      47             : See below for more details.
+      48             : 
+      49             : To throw an error, just throw a c++ exception
+      50             : \verbatim
+      51             :   if(something_bad) throw Exception();
+      52             : \endverbatim
+      53             : or better add an error message to that
+      54             : \verbatim
+      55             :   if(something_bad) throw Exception("describe the error here");
+      56             : \endverbatim
+      57             : 
+      58             : As of PLUMED 2.5 you can add multiple messages, they will just be concatenated,
+      59             : but to do se you should use the insertion operator. Notice that anything that
+      60             : can be formatted with an insertion operator can go to the exception, even a \ref Vector
+      61             : \verbatim
+      62             :   Vector v;
+      63             :   if(something_bad) throw Exception()<<"problem with this "<<v;
+      64             : \endverbatim
+      65             : In principle you can mix the two syntax (add a message as an argument and insert others with `<<`),
+      66             : however it is not very clear and should be avoided.
+      67             : We only allow using arguments in parenthesis in order to keep backward compatibility.
+      68             : 
+      69             : \par Using macros
+      70             : 
+      71             : In order to provide more context, especially for debugging, it might be useful to know where the exception
+      72             : originated from. The macros below add information about the exact location of the error in the file (filename, line
+      73             : and, when available, function name). Macros ending in "error" unconditionally throw
+      74             : the exception, whereas macros ending in "assert" first perform a conditional check
+      75             : (similarly to standard assert()).
+      76             : An extra `m` in the name (e.g. `plumed_merror`) indicates a macro that provides a message as its argument.
+      77             : However, as of PLUMED 2.5 we should prefer adding messages using insertion operators.
+      78             : \verbatim
+      79             : // this is correct but not recommended. add a message please!
+      80             :   plumed_assert(a>0);
+      81             : 
+      82             : // this is the old syntax (with argument).
+      83             : // this syntax is basically available for backward compatibility.
+      84             :   plumed_massert(a>0,"a should be larger than zero);
+      85             : 
+      86             : // this is the recommended syntax, with insertion operators.
+      87             : // it allows to easily insert multiple objects
+      88             :   plumed_assert(a>0)<<"a should be larger than zero. a="<<a;
+      89             : 
+      90             : // same as above, but the test is made explicitly:
+      91             :   if(a<=0) plumed_error();
+      92             :   if(a<=0) plumed_error("a should be larger than zero);
+      93             :   if(a<=0) plumed_error()<<"a should be larger than zero. a="<<a;
+      94             : \endverbatim
+      95             : 
+      96             : The additional macros
+      97             : plumed_dbg_assert() and plumed_dbg_massert() are similar
+      98             : to plumed_assert() and plumed_massert() respectively, but the corresponding
+      99             : check is only performed when NDEBUG macro is not defined. They should
+     100             : be used when the check is expensive and should be skipped in production
+     101             : code. So, for instance, in the following case:
+     102             : \verbatim
+     103             :   plumed_dbg_assert(expensive_function(i)>0)<<"message";
+     104             : \endverbatim
+     105             : `expensive_function()` is not called in the production code.
+     106             : Notice that the compiler should be able to completely optimize away the
+     107             : whole statement including functions used to produce the message as in this example:
+     108             : \verbatim
+     109             :   plumed_dbg_assert(expensive_function(i)>0)<<"I did this check "<<other_expensive_function(i);
+     110             : \endverbatim
+     111             : 
+     112             : Finally, notice that there is another macro available, \ref plumed_here.
+     113             : In can be used in order to create an exception with information about the
+     114             : line/file coordinates without trowing it. That is, the two following syntaxes
+     115             : are equivalent
+     116             : \verbatim
+     117             : // First way, all at once
+     118             : plumed_error()<<"some message";
+     119             : /////////////////////////////////
+     120             : // Second way, one step at a time
+     121             : // Create exception
+     122             : Exception e;
+     123             : // Append information about line and file
+     124             : e<<plumed_here;
+     125             : // Append some other message
+     126             : e<<"some message";
+     127             : // Throw the resulting exception
+     128             : throw e;
+     129             : \endverbatim
+     130             : 
+     131             : Exceptions can be caught within plumed or outside of it.
+     132             : E.g., in an external c++ code using PLUMED as a library, one can type
+     133             : \verbatim
+     134             :   try{
+     135             :     plumed.cmd("setPrecision",n);
+     136             :   } catch (const std::exception & e) {
+     137             :     std::printf("ee %s",e.what());
+     138             :     exit(1);
+     139             :   }
+     140             : \endverbatim
+     141             : This can be useful if an external code wants to exit in a controlled manner
+     142             : (e.g. flushing files, printing the error message in a specific file, etc.)
+     143             : but is anyway limited to c++ codes. Moreover,
+     144             : since these errors are expected to be unrecoverable, the MD code will
+     145             : usually not be able to do something more clever than exiting.
+     146             : 
+     147             : \note
+     148             : We store message and stack trace in growing strings. This is in
+     149             : principle not recommended, since copying the exception might fail if
+     150             : copying the string throw another exception. However, this has been like
+     151             : this in all previous PLUMED versions. In case it is necessary, we can replace
+     152             : it later with a fixed size array placed on the stack.
+     153             : 
+     154             : */
+     155             : class Exception : public std::exception
+     156             : {
+     157             : /// Reported message. Can be updated.
+     158             :   std::string msg;
+     159             : /// Flag to remember if we have to write the `+++ message follows +++` string.
+     160             : /// Needed so that the string appears only at the beginning of the message.
+     161             :   bool note=true;
+     162             : /// Stream used to insert objects.
+     163             : /// It is not copied when the Exception is copied.
+     164             :   std::stringstream stream;
+     165             : /// Stack trace, computed at construction
+     166             :   std::array<void*,128> callstack;
+     167             : /// Number of frames in stack, computed at construction
+     168             :   int callstack_n=0;
+     169             : /// Parsed stack trace. Built at first use, thus mutable.
+     170             :   mutable std::string stackTrace;
+     171             : 
+     172             : public:
+     173             : 
+     174             : /// Auxiliary containing the location of the exception in the file.
+     175             : /// Typically used from the macros below.
+     176             :   class Location {
+     177             :   public:
+     178             :     const char*file;
+     179             :     const unsigned line;
+     180             :     const char* pretty;
+     181          56 :     explicit Location(const char*file,unsigned line,const char* pretty=nullptr):
+     182          56 :       file(file),
+     183          56 :       line(line),
+     184          56 :       pretty(pretty)
+     185             :     {}
+     186             :   };
+     187             : 
+     188             : /// Auxiliary containing the failed assertion.
+     189             : /// Typically used from the macros below.
+     190             :   class Assertion {
+     191             :   public:
+     192             :     const char*assertion;
+     193           9 :     explicit Assertion(const char*assertion=nullptr):
+     194           9 :       assertion(assertion)
+     195             :     {}
+     196             :   };
+     197             : 
+     198             : /// Auxiliary class used to throw exceptions.
+     199             : /// It just defines <<= operator so that:
+     200             : /// - exceptions can be thrown calling std::throw_with_nested
+     201             : ///   with a "throw like" syntax
+     202             : /// - precedence is the same as the throw operator
+     203             : /// (see https://en.cppreference.com/w/cpp/language/operator_precedence)
+     204             :   class Throw {
+     205             :   public:
+     206             :     template <typename E>
+     207           2 :     [[noreturn]] void operator <<=(E&&e) {
+     208           4 :       if(std::current_exception()) {
+     209           2 :         std::throw_with_nested(e);
+     210             :       } else {
+     211             :         // if not nested, avoid modifying the exception type
+     212           0 :         throw e;
+     213             :       }
+     214             :     }
+     215             :   };
+     216             : 
+     217             : /// Default constructor with no message.
+     218             : /// Only records the stack trace.
+     219             :   Exception();
+     220             : 
+     221             : /// Constructor compatible with PLUMED <=2.4.
+     222          31 :   explicit Exception(const std::string & msg):
+     223          31 :     Exception()
+     224             :   {
+     225          31 :     *this << msg;
+     226          31 :   }
+     227             : 
+     228             : /// Copy constructor.
+     229             : /// Needed to make sure stream is not copied
+     230          26 :   Exception(const Exception & e):
+     231          26 :     msg(e.msg),
+     232          26 :     note(e.note),
+     233          26 :     callstack(e.callstack),
+     234          26 :     callstack_n(e.callstack_n),
+     235          26 :     stackTrace(e.stackTrace)
+     236             :   {
+     237          26 :   }
+     238             : 
+     239             : /// Assignment.
+     240             : /// Needed to make sure stream is not copied
+     241             :   Exception & operator=(const Exception & e) {
+     242             :     msg=e.msg;
+     243             :     note=e.note;
+     244             :     callstack=e.callstack;
+     245             :     callstack_n=e.callstack_n;
+     246             :     stackTrace=e.stackTrace;
+     247             :     stream.str("");
+     248             :     return *this;
+     249             :   }
+     250             : 
+     251             : /// Returns the error message.
+     252             : /// In case the environment variable PLUMED_STACK_TRACE was defined
+     253             : /// and equal to `yes` when the exception was raised,
+     254             : /// the error message will contain the stack trace as well.
+     255          39 :   const char* what() const noexcept override {return msg.c_str();}
+     256             : 
+     257             : /// Returns the stack trace as a string.
+     258             : /// This function is slow as it requires building a parsed string.
+     259             : /// If storing the stack for later usage, you might prefer to use trace().
+     260             :   const char* stack() const;
+     261             : 
+     262             : /// Returns the callstack.
+     263             :   const std::array<void*,128> & trace() const noexcept {return callstack;}
+     264             : 
+     265             : /// Returns the number of elements in the trace array
+     266             :   int trace_n() const noexcept {return callstack_n;}
+     267             : 
+     268             : /// Destructor should be defined and should not throw other exceptions
+     269          56 :   ~Exception() noexcept override {}
+     270             : 
+     271             : /// Insert location.
+     272             : /// Format the location properly.
+     273             :   Exception& operator<<(const Location&);
+     274             : 
+     275             : /// Insert assertion.
+     276             : /// Format the assertion properly
+     277             :   Exception& operator<<(const Assertion&);
+     278             : 
+     279             : /// Insert string.
+     280             : /// Append this string to the message.
+     281             :   Exception& operator<<(const std::string&);
+     282             : 
+     283             : /// Insert anything else.
+     284             : /// This allows to dump also other types (e.g. double, or even Vector).
+     285             : /// Anything that can be written on a stream can go here.
+     286             :   template<typename T>
+     287          61 :   Exception& operator<<(const T & x) {
+     288          61 :     stream<<x;
+     289          61 :     (*this)<<stream.str();
+     290          61 :     stream.str("");
+     291          61 :     return *this;
+     292             :   }
+     293             : };
+     294             : 
+     295             : /// Class representing a generic error
+     296         148 : class ExceptionError :
+     297             :   public Exception {
+     298             : public:
+     299           1 :   using Exception::Exception;
+     300             :   template<typename T>
+     301             :   ExceptionError& operator<<(const T & x) {
+     302          91 :     *static_cast<Exception*>(this) <<x;
+     303             :     return *this;
+     304             :   }
+     305             : };
+     306             : 
+     307             : /// Class representing a debug error (can only be thrown when using debug options)
+     308           0 : class ExceptionDebug :
+     309             :   public Exception {
+     310             : public:
+     311           1 :   using Exception::Exception;
+     312             :   template<typename T>
+     313             :   ExceptionDebug& operator<<(const T & x) {
+     314             :     *static_cast<Exception*>(this) <<x;
+     315             :     return *this;
+     316             :   }
+     317             : };
+     318             : 
+     319             : /// Class representing a type error in the PLMD::Plumed interface
+     320          23 : class ExceptionTypeError :
+     321             :   public Exception {
+     322             : public:
+     323           0 :   using Exception::Exception;
+     324             :   template<typename T>
+     325             :   ExceptionTypeError& operator<<(const T & x) {
+     326          21 :     *static_cast<Exception*>(this) <<x;
+     327             :     return *this;
+     328             :   }
+     329             : };
+     330             : 
+     331             : #ifdef __GNUG__
+     332             : // With GNU compiler, we can use __PRETTY_FUNCTION__ to get the function name
+     333             : #define __PLUMED_FUNCNAME __PRETTY_FUNCTION__
+     334             : #else
+     335             : // Otherwise, we use the standard C++11 variable
+     336             : #define __PLUMED_FUNCNAME __func__
+     337             : #endif
+     338             : 
+     339             : #ifndef PLUMED_MODULE_DIR
+     340             : #define PLUMED_MODULE_DIR ""
+     341             : #endif
+     342             : 
+     343             : /// \relates PLMD::Exception
+     344             : /// Auxiliary macro that generates a PLMD::Exception::Location object.
+     345             : /// Might be useful if we want to use derived exceptions that could
+     346             : /// be thrown using `throw DerivedException()<<plumed_here<<" "<<other stuff"`.
+     347             : /// It is used in the macros below to throw PLMD::Exception.
+     348             : #define plumed_here PLMD::Exception::Location(PLUMED_MODULE_DIR __FILE__,__LINE__,__PLUMED_FUNCNAME)
+     349             : 
+     350             : /// \relates PLMD::Exception
+     351             : /// Throw an exception with information about the position in the file.
+     352             : /// Messages can be inserted with `plumed_error()<<"message"`.
+     353             : #define plumed_error() throw PLMD::ExceptionError() << plumed_here
+     354             : 
+     355             : /// \relates PLMD::Exception
+     356             : /// Throw a nested exception with information about the position in the file.
+     357             : /// It preliminary checks if we are in a catch block. If so, the caught exception
+     358             : /// is rethrown as nested. If not, it throws a normal ExceptionError.
+     359             : /// NB in theory we could have just redefined plumed_error to this, but
+     360             : /// for some reason cppcheck does not understand that the <<= operator used here is
+     361             : /// [[noreturn]] and thus gives many false warnings
+     362             : #define plumed_error_nested() PLMD::Exception::Throw() <<= PLMD::ExceptionError() << plumed_here
+     363             : 
+     364             : /// \relates PLMD::Exception
+     365             : /// Throw an exception with information about the position in the file
+     366             : /// and a message. Mostly available for backward compatibility
+     367             : #define plumed_merror(msg) plumed_error() << msg
+     368             : 
+     369             : /// \relates PLMD::Exception
+     370             : /// Launches plumed_merror only if test evaluates to false.
+     371             : /// The string describing the test is also reported.
+     372             : /// Further messages can be inserted with `<<`.
+     373             : #define plumed_assert(test) if(!(test)) plumed_error() << PLMD::Exception::Assertion(#test)
+     374             : 
+     375             : /// \relates PLMD::Exception
+     376             : /// Launches plumed_merror only if test evaluates to false.
+     377             : /// The string describing the test is also reported, in addition to
+     378             : /// messages reported in the extra argument. Mostly available for backward compatibility.
+     379             : #define plumed_massert(test,msg) plumed_assert(test) << msg
+     380             : 
+     381             : #ifdef NDEBUG
+     382             : 
+     383             : // These are the versions used when compiling with NDEBUG flag.
+     384             : // The if constexpr(false) gurarantees that the compiler will optimize away the assertion
+     385             : // We are not using an empty macro becasue the user may want to use the << operator
+     386             : 
+     387             : #define plumed_dbg_assert(test) if constexpr(false) plumed_assert(true)
+     388             : #define plumed_dbg_massert(test,msg) if constexpr(false) plumed_massert(true,msg)
+     389             : 
+     390             : #else
+     391             : 
+     392             : /// \relates PLMD::Exception
+     393             : /// Same as \ref plumed_assert, but only evaluates the condition if NDEBUG is not defined.
+     394             : #define plumed_dbg_assert(test) if(!(test)) PLMD::Exception::Throw() <<= PLMD::ExceptionDebug() << plumed_here << PLMD::Exception::Assertion(#test) << "(this check is enabled only in debug builds)\n"
+     395             : 
+     396             : /// \relates PLMD::Exception
+     397             : /// Same as \ref plumed_massert, but only evaluates the condition if NDEBUG is not defined.
+     398             : #define plumed_dbg_massert(test,msg) plumed_dbg_assert(test) << msg
+     399             : 
+     400             : #endif
+     401             : 
+     402             : }
+     403             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.cpp.func-sort-c.html b/coverage/tools/FileBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..02135591e78d --- /dev/null +++ b/coverage/tools/FileBase.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-02-22 21:58:45Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8FileBaseD0Ev0
_ZN4PLMD8FileBase13enforceSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE258
_ZN4PLMD8FileBase4linkEP8_IO_FILE961
_ZN4PLMD8FileBase5closeEv982
_ZN4PLMD8FileBase9FileExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1900
_ZN4PLMD8FileBase4linkERNS_6ActionE3943
_ZN4PLMD8FileBase4linkERNS_10PlumedMainE4831
_ZN4PLMD8FileBase5flushEv5022
_ZNK4PLMD8FileBase9getSuffixB5cxx11Ev5540
_ZN4PLMD8FileBase12appendSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_6735
_ZN4PLMD8FileBase4linkERNS_12CommunicatorE810329
_ZN4PLMD8FileBaseC2Ev811525
_ZN4PLMD8FileBaseD2Ev811525
_ZN4PLMD8FileBase6isOpenEv812568
_ZNK4PLMD8FileBasecvbEv29232142
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.cpp.func.html b/coverage/tools/FileBase.cpp.func.html new file mode 100644 index 000000000000..c7bda8e2451c --- /dev/null +++ b/coverage/tools/FileBase.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-02-22 21:58:45Functions:141593.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8FileBase12appendSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_6735
_ZN4PLMD8FileBase13enforceSuffixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE258
_ZN4PLMD8FileBase4linkEP8_IO_FILE961
_ZN4PLMD8FileBase4linkERNS_10PlumedMainE4831
_ZN4PLMD8FileBase4linkERNS_12CommunicatorE810329
_ZN4PLMD8FileBase4linkERNS_6ActionE3943
_ZN4PLMD8FileBase5closeEv982
_ZN4PLMD8FileBase5flushEv5022
_ZN4PLMD8FileBase6isOpenEv812568
_ZN4PLMD8FileBase9FileExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1900
_ZN4PLMD8FileBaseC2Ev811525
_ZN4PLMD8FileBaseD0Ev0
_ZN4PLMD8FileBaseD2Ev811525
_ZNK4PLMD8FileBase9getSuffixB5cxx11Ev5540
_ZNK4PLMD8FileBasecvbEv29232142
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.cpp.gcov.html b/coverage/tools/FileBase.cpp.gcov.html new file mode 100644 index 000000000000..7becc805a2c7 --- /dev/null +++ b/coverage/tools/FileBase.cpp.gcov.html @@ -0,0 +1,252 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8080100.0 %
Date:2024-02-22 21:58:45Functions:141593.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "FileBase.h"
+      23             : #include "Exception.h"
+      24             : #include "core/Action.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Value.h"
+      27             : #include "Communicator.h"
+      28             : #include "Tools.h"
+      29             : #include <cstdarg>
+      30             : #include <cstring>
+      31             : #include <cstdlib>
+      32             : 
+      33             : #include <iostream>
+      34             : #include <string>
+      35             : 
+      36             : #ifdef __PLUMED_HAS_ZLIB
+      37             : #include <zlib.h>
+      38             : #endif
+      39             : 
+      40             : namespace PLMD {
+      41             : 
+      42         961 : FileBase& FileBase::link(FILE*fp) {
+      43         961 :   plumed_massert(!this->fp,"cannot link an already open file");
+      44         961 :   this->fp=fp;
+      45         961 :   cloned=true;
+      46         961 :   return *this;
+      47             : }
+      48             : 
+      49        5022 : FileBase& FileBase::flush() {
+      50        5022 :   if(fp) fflush(fp);
+      51        5022 :   return *this;
+      52             : }
+      53             : 
+      54      810329 : FileBase& FileBase::link(Communicator&comm) {
+      55      810329 :   plumed_massert(!fp,"cannot link an already open file");
+      56      810329 :   this->comm=&comm;
+      57      810329 :   return *this;
+      58             : }
+      59             : 
+      60        4831 : FileBase& FileBase::link(PlumedMain&plumed) {
+      61        4831 :   plumed_massert(!fp,"cannot link an already open file");
+      62        4831 :   this->plumed=&plumed;
+      63        4831 :   link(plumed.comm);
+      64        4831 :   return *this;
+      65             : }
+      66             : 
+      67        3943 : FileBase& FileBase::link(Action&action) {
+      68        3943 :   plumed_massert(!fp,"cannot link an already open file");
+      69        3943 :   this->action=&action;
+      70        3943 :   link(action.plumed);
+      71        3943 :   return *this;
+      72             : }
+      73             : 
+      74        1900 : bool FileBase::FileExist(const std::string& path) {
+      75             :   bool do_exist=false;
+      76        3800 :   this->path=appendSuffix(path,getSuffix());
+      77        1900 :   mode="r";
+      78             :   // first try with suffix
+      79        1900 :   FILE *ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+      80             : // call fclose when ff goes out of scope
+      81        1329 :   auto deleter=[](auto f) { if(f) std::fclose(f); };
+      82             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(ff,deleter);
+      83             : 
+      84        1900 :   if(!ff) {
+      85             :     this->path=path;
+      86             :     // then try without suffic
+      87         571 :     ff=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+      88             :     mode="r";
+      89             :   }
+      90        1900 :   if(ff) do_exist=true;
+      91        1900 :   if(comm) comm->Barrier();
+      92        1900 :   return do_exist;
+      93             : }
+      94             : 
+      95      812568 : bool FileBase::isOpen() {
+      96             :   bool isopen=false;
+      97      812568 :   if(fp) isopen=true;
+      98      812568 :   return isopen;
+      99             : }
+     100             : 
+     101         982 : void        FileBase::close() {
+     102         982 :   plumed_assert(!cloned);
+     103         982 :   eof=false;
+     104         982 :   err=false;
+     105         982 :   if(fp)   std::fclose(fp);
+     106             : #ifdef __PLUMED_HAS_ZLIB
+     107         982 :   if(gzfp) gzclose(gzFile(gzfp));
+     108             : #endif
+     109         982 :   fp=NULL;
+     110         982 :   gzfp=NULL;
+     111         982 : }
+     112             : 
+     113      811525 : FileBase::FileBase():
+     114      811525 :   fp(NULL),
+     115      811525 :   gzfp(NULL),
+     116      811525 :   comm(NULL),
+     117      811525 :   plumed(NULL),
+     118      811525 :   action(NULL),
+     119      811525 :   cloned(false),
+     120      811525 :   eof(false),
+     121      811525 :   err(false),
+     122      811525 :   heavyFlush(false),
+     123      811525 :   enforcedSuffix_(false)
+     124             : {
+     125      811525 : }
+     126             : 
+     127      811525 : FileBase::~FileBase()
+     128             : {
+     129      811525 :   if(plumed) plumed->eraseFile(*this);
+     130      811525 :   if(!cloned && fp)   std::fclose(fp);
+     131             : #ifdef __PLUMED_HAS_ZLIB
+     132      811525 :   if(!cloned && gzfp) gzclose(gzFile(gzfp));
+     133             : #endif
+     134      811525 : }
+     135             : 
+     136    29232142 : FileBase::operator bool()const {
+     137    29232142 :   return !eof;
+     138             : }
+     139             : 
+     140        6735 : std::string FileBase::appendSuffix(const std::string&path,const std::string&suffix) {
+     141        6735 :   if(path=="/dev/null") return path; // do not append a suffix to /dev/null
+     142        6560 :   std::string ret=path;
+     143        6560 :   std::string ext=Tools::extension(path);
+     144             : 
+     145             : // These are the recognized extensions so far:
+     146             : // gz xtc trr
+     147             : // If a file name ends with one of these extensions, the suffix is added *before*
+     148             : // the extension. This is useful when extensions are conventionally used
+     149             : // to detect file type, so as to allow easier file manipulation.
+     150             : // Removing this line, any extension recognized by Tools::extension() would be considered
+     151             : //  if(ext!="gz" && ext!="xtc" && ext!="trr") ext="";
+     152             : 
+     153        6560 :   if(ext.length()>0) {
+     154        4770 :     int l=path.length()-(ext.length()+1);
+     155        4770 :     plumed_assert(l>=0);
+     156        4770 :     ret.resize(l);
+     157             :   }
+     158             :   ret+=suffix;
+     159       11330 :   if(ext.length()>0)ret+="."+ext;
+     160             :   return ret;
+     161             : }
+     162             : 
+     163         258 : FileBase& FileBase::enforceSuffix(const std::string&suffix) {
+     164         258 :   enforcedSuffix_=true;
+     165         258 :   enforcedSuffix=suffix;
+     166         258 :   return *this;
+     167             : }
+     168             : 
+     169        5540 : std::string FileBase::getSuffix()const {
+     170        5540 :   if(enforcedSuffix_) return enforcedSuffix;
+     171        5276 :   if(plumed) return plumed->getSuffix();
+     172         507 :   return "";
+     173             : }
+     174             : 
+     175             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.h.func-sort-c.html b/coverage/tools/FileBase.h.func-sort-c.html new file mode 100644 index 000000000000..5f1829198c11 --- /dev/null +++ b/coverage/tools/FileBase.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.h.func.html b/coverage/tools/FileBase.h.func.html new file mode 100644 index 000000000000..34c826b13c6f --- /dev/null +++ b/coverage/tools/FileBase.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/FileBase.h.gcov.html b/coverage/tools/FileBase.h.gcov.html new file mode 100644 index 000000000000..00c35c7b0f00 --- /dev/null +++ b/coverage/tools/FileBase.h.gcov.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - tools/FileBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - FileBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_FileBase_h
+      23             : #define __PLUMED_tools_FileBase_h
+      24             : 
+      25             : #include <string>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : class Communicator;
+      30             : class PlumedMain;
+      31             : class Action;
+      32             : 
+      33             : /**
+      34             : Base class for dealing with files.
+      35             : 
+      36             : This class just provides things which are common among OFile and IFile
+      37             : */
+      38             : 
+      39             : class FileBase {
+      40             : /// Copy constructor is disabled
+      41             :   FileBase(const FileBase&) = delete;
+      42             : /// Assignment operator is disabled
+      43             :   FileBase& operator=(const FileBase&) = delete;
+      44             : protected:
+      45             : /// Internal tool.
+      46             : /// Base for IFile::Field and OFile::Field
+      47    16871041 :   class FieldBase {
+      48             : // everything is public to simplify usage
+      49             :   public:
+      50             :     std::string name;
+      51             :     std::string value;
+      52             :     bool constant;
+      53    16736203 :     FieldBase(): constant(false) {}
+      54             :   };
+      55             : 
+      56             : /// file pointer
+      57             :   FILE* fp;
+      58             : /// zip file pointer.
+      59             :   void* gzfp;
+      60             : /// communicator. NULL if not set
+      61             :   Communicator* comm;
+      62             : /// pointer to main plumed object. NULL if not linked
+      63             :   PlumedMain* plumed;
+      64             : /// pointer to corresponding action. NULL if not linked
+      65             :   Action* action;
+      66             : /// Control closing on destructor.
+      67             : /// If true, file will not be closed in destructor
+      68             :   bool cloned;
+      69             : /// Private constructor.
+      70             : /// In this manner one cannot instantiate a FileBase object
+      71             :   FileBase();
+      72             : /// Set to true when end of file is encountered
+      73             :   bool eof;
+      74             : /// Set to true when error is encountered
+      75             :   bool err;
+      76             : /// path of the opened file
+      77             :   std::string path;
+      78             : /// mode of the opened file
+      79             :   std::string mode;
+      80             : /// Set to true if you want flush to be heavy (close/reopen)
+      81             :   bool heavyFlush;
+      82             : public:
+      83             : /// Append suffix.
+      84             : /// It appends the desired suffix to the string. Notice that
+      85             : /// it conserves some suffix (e.g. gz/xtc/trr).
+      86             :   static std::string appendSuffix(const std::string&path,const std::string&suffix);
+      87             : private:
+      88             : /// Enforced suffix:
+      89             :   std::string enforcedSuffix;
+      90             : /// If true, use enforcedSuffix, else get it from PlumedMain
+      91             :   bool enforcedSuffix_;
+      92             : public:
+      93             : /// Link to an already open filed
+      94             :   FileBase& link(FILE*);
+      95             : /// Link to a PlumedMain object
+      96             : /// Automatically links also the corresponding Communicator.
+      97             :   FileBase& link(PlumedMain&);
+      98             : /// Link to a Communicator object
+      99             :   FileBase& link(Communicator&);
+     100             : /// Link to an Action object.
+     101             : /// Automatically links also the corresponding PlumedMain and Communicator.
+     102             :   FileBase& link(Action&);
+     103             : /// Enforce suffix.
+     104             : /// Overrides the one set in PlumedMain&
+     105             :   FileBase& enforceSuffix(const std::string&suffix);
+     106             : /// Flushes the file to disk
+     107             :   virtual FileBase& flush();
+     108             : /// Closes the file
+     109             : /// Should be used only for explicitely opened files.
+     110             :   void        close();
+     111             : /// Virtual destructor (allows inheritance)
+     112             :   virtual ~FileBase();
+     113             : /// Check for error/eof.
+     114             :   operator bool () const;
+     115             : /// Set heavyFlush flag
+     116         634 :   void setHeavyFlush() { heavyFlush=true;}
+     117             : /// Opens the file
+     118             :   virtual FileBase& open(const std::string&name)=0;
+     119             : /// Check if the file exists
+     120             :   bool FileExist(const std::string& path);
+     121             : /// Check if a file is open
+     122             :   bool isOpen();
+     123             : /// Retrieve the path
+     124             :   std::string getPath()const;
+     125             : /// Retrieve the mode
+     126             :   std::string getMode()const;
+     127             : /// Get the file suffix
+     128             :   std::string getSuffix()const;
+     129             : /// Get the underlying file pointer.
+     130             : /// It might be null even if the file is open, e.g. when the file
+     131             : /// was open as a gzipped file.
+     132             :   FILE* getFILE()const;
+     133             : };
+     134             : 
+     135             : inline
+     136             : std::string FileBase::getPath()const {
+     137         811 :   return path;
+     138             : }
+     139             : 
+     140             : inline
+     141             : std::string FileBase::getMode()const {
+     142         160 :   return mode;
+     143             : }
+     144             : 
+     145             : inline
+     146             : FILE* FileBase::getFILE()const {
+     147          18 :   return fp;
+     148             : }
+     149             : 
+     150             : }
+     151             : 
+     152             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ForwardDecl.h.func-sort-c.html b/coverage/tools/ForwardDecl.h.func-sort-c.html new file mode 100644 index 000000000000..5a5464d78bf2 --- /dev/null +++ b/coverage/tools/ForwardDecl.h.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - tools/ForwardDecl.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ForwardDecl.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ForwardDeclINS_3PDBEEC2IJEEEDpOT_87
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJEEEDpOT_583
_ZN4PLMD11ForwardDeclINS_3PbcEEC2IJEEEDpOT_11134
_ZN4PLMD11ForwardDeclINS_11TypesafePtrEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_16ExchangePatternsEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_3LogEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_6RandomEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_8DLLoaderEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_9ActionSetEEC2IJRNS_10PlumedMainEEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_9CitationsEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJRNS_3LogEEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_12CommunicatorEEC2IJEEEDpOT_1615202
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ForwardDecl.h.func.html b/coverage/tools/ForwardDecl.h.func.html new file mode 100644 index 000000000000..12c5fb115728 --- /dev/null +++ b/coverage/tools/ForwardDecl.h.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - tools/ForwardDecl.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ForwardDecl.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11ForwardDeclINS_11TypesafePtrEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_12CommunicatorEEC2IJEEEDpOT_1615202
_ZN4PLMD11ForwardDeclINS_16ExchangePatternsEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_3LogEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_3PDBEEC2IJEEEDpOT_87
_ZN4PLMD11ForwardDeclINS_3PbcEEC2IJEEEDpOT_11134
_ZN4PLMD11ForwardDeclINS_6RandomEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_8DLLoaderEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_9ActionSetEEC2IJRNS_10PlumedMainEEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_9CitationsEEC2IJEEEDpOT_805283
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJEEEDpOT_583
_ZN4PLMD11ForwardDeclINS_9StopwatchEEC2IJRNS_3LogEEEEDpOT_805283
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/ForwardDecl.h.gcov.html b/coverage/tools/ForwardDecl.h.gcov.html new file mode 100644 index 000000000000..8af41bc09bd1 --- /dev/null +++ b/coverage/tools/ForwardDecl.h.gcov.html @@ -0,0 +1,132 @@ + + + + + + + + LCOV - plumed test coverage - tools/ForwardDecl.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - ForwardDecl.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2017-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_ForwardDecl_h
+      23             : #define __PLUMED_tools_ForwardDecl_h
+      24             : 
+      25             : #include <memory>
+      26             : #include <utility>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : /**
+      31             :   Utility class for forward declaration of references.
+      32             : 
+      33             : */
+      34             : template <class T>
+      35     3236420 : class ForwardDecl:
+      36             :   std::unique_ptr<T>
+      37             : {
+      38             : public:
+      39             : // Construction with arbitrary argument.
+      40             :   template<typename ...Args>
+      41             :   explicit ForwardDecl(Args &&...args);
+      42             : // Dereference operator is inherited from std::unique_ptr<T>
+      43             :   using std::unique_ptr<T>::operator *;
+      44             : };
+      45             : 
+      46             : template <class T>
+      47             : template<typename ...Args>
+      48     8069270 : ForwardDecl<T>::ForwardDecl(Args &&...args):
+      49     8069270 :   std::unique_ptr<T>(new T(std::forward<Args>(args)...))
+      50     8069270 : {}
+      51             : 
+      52             : 
+      53             : }
+      54             : 
+      55             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.cpp.func-sort-c.html b/coverage/tools/Grid.cpp.func-sort-c.html new file mode 100644 index 000000000000..3787b77a2a53 --- /dev/null +++ b/coverage/tools/Grid.cpp.func-sort-c.html @@ -0,0 +1,381 @@ + + + + + + + + LCOV - plumed test coverage - tools/Grid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44061971.1 %
Date:2024-02-22 21:58:45Functions:557771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10SparseGrid11writeToFileERNS_5OFileE0
_ZN4PLMD10SparseGrid22setValueAndDerivativesEmdRSt6vectorIdSaIdEE0
_ZN4PLMD10SparseGrid8addValueEmd0
_ZN4PLMD10SparseGrid8setValueEmd0
_ZN4PLMD4Grid24findSetOfPointsOnContourERKdRKSt6vectorIbSaIbEERjRS3_IS3_IdSaIdEESaISA_EE0
_ZN4PLMD4Grid26logAllValuesAndDerivativesERKd0
_ZN4PLMD4Grid26mpiSumValuesAndDerivativesERNS_12CommunicatorE0
_ZN4PLMD4Grid9integrateERSt6vectorIjSaIjEE0
_ZN4PLMD8GridBase13writeCubeFileERNS_5OFileERKd0
_ZN4PLMD8GridBase22addValueAndDerivativesERKSt6vectorIjSaIjEEdRS1_IdSaIdEE0
_ZN4PLMD8GridBase22setValueAndDerivativesERKSt6vectorIjSaIjEEdRS1_IdSaIdEE0
_ZN4PLMD8GridBase8addValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD8GridBase8setValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD8GridBase9addKernelERKNS_15KernelFunctionsE0
_ZNK4PLMD10SparseGrid10getMaxSizeEv0
_ZNK4PLMD10SparseGrid11getMinValueEv0
_ZNK4PLMD10SparseGrid7getSizeEv0
_ZNK4PLMD10SparseGrid8getValueEm0
_ZNK4PLMD4Grid24getDifferenceFromContourERKSt6vectorIdSaIdEERS3_0
_ZNK4PLMD8GridBase19getNearestNeighborsERKSt6vectorIjSaIjEE0
_ZNK4PLMD8GridBase8getPointERKSt6vectorIdSaIdEE0
_ZNK4PLMD8GridBase8getPointERKSt6vectorIdSaIdEERS3_0
_ZN4PLMD4Grid36applyFunctionAllValuesAndDerivativesEPFddES2_1
_ZN4PLMD4Grid5clearEv1
_ZN4PLMD4Grid8addValueEmd1
_ZNK4PLMD10SparseGrid11getMaxValueEv9
_ZN4PLMD8GridBase6createERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERNS_5IFileERKS9_IS6_SaIS6_EESL_RKS9_IjSaIjEEbbb20
_ZNK4PLMD8GridBase12getBinVolumeEv37
_ZN4PLMD8GridBase6createERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERNS_5IFileEbbb70
_ZN4PLMD4Grid7projectERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEPNS_10WeightBaseE81
_ZN4PLMD8GridBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_128
_ZNK4PLMD10SparseGrid22getValueAndDerivativesEmRSt6vectorIdSaIdEE200
_ZN4PLMD8GridBase22findMaximalPathMinimumERKSt6vectorIdSaIdEES5_273
_ZNK4PLMD8GridBase6getMaxB5cxx11Ev343
_ZNK4PLMD8GridBase8getValueERKSt6vectorIdSaIdEE345
_ZN4PLMD4Grid28scaleAllValuesAndDerivativesERKd594
_ZNK4PLMD4Grid11getMaxValueEv629
_ZNK4PLMD4Grid11getMinValueEv861
_ZN4PLMD4Grid11writeToFileERNS_5OFileE1147
_ZN4PLMD8GridBase11writeHeaderERNS_5OFileE1147
_ZN4PLMD8GridBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERKS9_IS6_SaIS6_EESJ_RKS9_IjSaIjEEbb1327
_ZN4PLMD4Grid12setMinToZeroEv1329
_ZN4PLMD8GridBase4InitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_1455
_ZNK4PLMD8GridBase13getIsPeriodicEv2240
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEERS1_IjSaIjEE3711
_ZNK4PLMD8GridBase18getSplineNeighborsERKSt6vectorIjSaIjEERS1_ImSaImEERj3711
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIdSaIdEERS3_3711
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIdSaIdEERKS1_IjSaIjEE4211
_ZNK4PLMD8GridBase10getIndicesEmRSt6vectorIjSaIjEE8910
_ZNK4PLMD8GridBase11getArgNamesB5cxx11Ev9436
_ZNK4PLMD8GridBase19getNearestNeighborsEm9577
_ZNK4PLMD8GridBase5getDxEm11890
_ZNK4PLMD8GridBase12getNeighborsEmRKSt6vectorIjSaIjEE19153
_ZN4PLMD10SparseGrid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE19999
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIjSaIjEES5_23364
_ZN4PLMD10indexed_ltERKSt4pairImdES3_59573
_ZN4PLMD4Grid21projectOnLowDimensionERdRSt6vectorIiSaIiEEPNS_10WeightBaseE1010062
_ZNK4PLMD8GridBase7getNbinEv1012510
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIdSaIdEE1100069
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEE1104281
_ZNK4PLMD8GridBase8getPointEmRSt6vectorIdSaIdEE1110281
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEERS1_IdSaIdEE1113992
_ZN4PLMD4Grid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE1171742
_ZNK4PLMD8GridBase8getValueERKSt6vectorIjSaIjEE1193613
_ZNK4PLMD8GridBase5getDxEv1319573
_ZNK4PLMD8GridBase6getMinB5cxx11Ev1360394
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIjSaIjEERS1_IdSaIdEE2527708
_ZN4PLMD4Grid22setValueAndDerivativesEmdRSt6vectorIdSaIdEE2552369
_ZNK4PLMD4Grid22getValueAndDerivativesEmRSt6vectorIdSaIdEE3079776
_ZN4PLMD4Grid8setValueEmd6444104
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIjSaIjEE7145799
_ZNK4PLMD8GridBase12getDimensionEv18321217
_ZNK4PLMD4Grid8getValueEm27284983
_ZNK4PLMD8GridBase8getPointEm28822338
_ZNK4PLMD4Grid7getSizeEv28865222
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEE31542440
_ZNK4PLMD8GridBase10getIndicesEm37829485
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.cpp.func.html b/coverage/tools/Grid.cpp.func.html new file mode 100644 index 000000000000..352f6a7933b4 --- /dev/null +++ b/coverage/tools/Grid.cpp.func.html @@ -0,0 +1,381 @@ + + + + + + + + LCOV - plumed test coverage - tools/Grid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44061971.1 %
Date:2024-02-22 21:58:45Functions:557771.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10SparseGrid11writeToFileERNS_5OFileE0
_ZN4PLMD10SparseGrid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE19999
_ZN4PLMD10SparseGrid22setValueAndDerivativesEmdRSt6vectorIdSaIdEE0
_ZN4PLMD10SparseGrid8addValueEmd0
_ZN4PLMD10SparseGrid8setValueEmd0
_ZN4PLMD10indexed_ltERKSt4pairImdES3_59573
_ZN4PLMD4Grid11writeToFileERNS_5OFileE1147
_ZN4PLMD4Grid12setMinToZeroEv1329
_ZN4PLMD4Grid21projectOnLowDimensionERdRSt6vectorIiSaIiEEPNS_10WeightBaseE1010062
_ZN4PLMD4Grid22addValueAndDerivativesEmdRSt6vectorIdSaIdEE1171742
_ZN4PLMD4Grid22setValueAndDerivativesEmdRSt6vectorIdSaIdEE2552369
_ZN4PLMD4Grid24findSetOfPointsOnContourERKdRKSt6vectorIbSaIbEERjRS3_IS3_IdSaIdEESaISA_EE0
_ZN4PLMD4Grid26logAllValuesAndDerivativesERKd0
_ZN4PLMD4Grid26mpiSumValuesAndDerivativesERNS_12CommunicatorE0
_ZN4PLMD4Grid28scaleAllValuesAndDerivativesERKd594
_ZN4PLMD4Grid36applyFunctionAllValuesAndDerivativesEPFddES2_1
_ZN4PLMD4Grid5clearEv1
_ZN4PLMD4Grid7projectERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EEPNS_10WeightBaseE81
_ZN4PLMD4Grid8addValueEmd1
_ZN4PLMD4Grid8setValueEmd6444104
_ZN4PLMD4Grid9integrateERSt6vectorIjSaIjEE0
_ZN4PLMD8GridBase11writeHeaderERNS_5OFileE1147
_ZN4PLMD8GridBase13writeCubeFileERNS_5OFileERKd0
_ZN4PLMD8GridBase22addValueAndDerivativesERKSt6vectorIjSaIjEEdRS1_IdSaIdEE0
_ZN4PLMD8GridBase22findMaximalPathMinimumERKSt6vectorIdSaIdEES5_273
_ZN4PLMD8GridBase22setValueAndDerivativesERKSt6vectorIjSaIjEEdRS1_IdSaIdEE0
_ZN4PLMD8GridBase4InitERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_1455
_ZN4PLMD8GridBase6createERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERNS_5IFileERKS9_IS6_SaIS6_EESL_RKS9_IjSaIjEEbbb20
_ZN4PLMD8GridBase6createERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERNS_5IFileEbbb70
_ZN4PLMD8GridBase8addValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD8GridBase8setValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD8GridBase9addKernelERKNS_15KernelFunctionsE0
_ZN4PLMD8GridBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERKS9_IS6_SaIS6_EESJ_RKS9_IjSaIjEEbb1327
_ZN4PLMD8GridBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_128
_ZNK4PLMD10SparseGrid10getMaxSizeEv0
_ZNK4PLMD10SparseGrid11getMaxValueEv9
_ZNK4PLMD10SparseGrid11getMinValueEv0
_ZNK4PLMD10SparseGrid22getValueAndDerivativesEmRSt6vectorIdSaIdEE200
_ZNK4PLMD10SparseGrid7getSizeEv0
_ZNK4PLMD10SparseGrid8getValueEm0
_ZNK4PLMD4Grid11getMaxValueEv629
_ZNK4PLMD4Grid11getMinValueEv861
_ZNK4PLMD4Grid22getValueAndDerivativesEmRSt6vectorIdSaIdEE3079776
_ZNK4PLMD4Grid24getDifferenceFromContourERKSt6vectorIdSaIdEERS3_0
_ZNK4PLMD4Grid7getSizeEv28865222
_ZNK4PLMD4Grid8getValueEm27284983
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEE1104281
_ZNK4PLMD8GridBase10getIndicesERKSt6vectorIdSaIdEERS1_IjSaIjEE3711
_ZNK4PLMD8GridBase10getIndicesEm37829485
_ZNK4PLMD8GridBase10getIndicesEmRSt6vectorIjSaIjEE8910
_ZNK4PLMD8GridBase11getArgNamesB5cxx11Ev9436
_ZNK4PLMD8GridBase12getBinVolumeEv37
_ZNK4PLMD8GridBase12getDimensionEv18321217
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIdSaIdEERKS1_IjSaIjEE4211
_ZNK4PLMD8GridBase12getNeighborsERKSt6vectorIjSaIjEES5_23364
_ZNK4PLMD8GridBase12getNeighborsEmRKSt6vectorIjSaIjEE19153
_ZNK4PLMD8GridBase13getIsPeriodicEv2240
_ZNK4PLMD8GridBase18getSplineNeighborsERKSt6vectorIjSaIjEERS1_ImSaImEERj3711
_ZNK4PLMD8GridBase19getNearestNeighborsERKSt6vectorIjSaIjEE0
_ZNK4PLMD8GridBase19getNearestNeighborsEm9577
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIdSaIdEERS3_3711
_ZNK4PLMD8GridBase22getValueAndDerivativesERKSt6vectorIjSaIjEERS1_IdSaIdEE2527708
_ZNK4PLMD8GridBase5getDxEm11890
_ZNK4PLMD8GridBase5getDxEv1319573
_ZNK4PLMD8GridBase6getMaxB5cxx11Ev343
_ZNK4PLMD8GridBase6getMinB5cxx11Ev1360394
_ZNK4PLMD8GridBase7getNbinEv1012510
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIdSaIdEE1100069
_ZNK4PLMD8GridBase8getIndexERKSt6vectorIjSaIjEE7145799
_ZNK4PLMD8GridBase8getPointERKSt6vectorIdSaIdEE0
_ZNK4PLMD8GridBase8getPointERKSt6vectorIdSaIdEERS3_0
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEE31542440
_ZNK4PLMD8GridBase8getPointERKSt6vectorIjSaIjEERS1_IdSaIdEE1113992
_ZNK4PLMD8GridBase8getPointEm28822338
_ZNK4PLMD8GridBase8getPointEmRSt6vectorIdSaIdEE1110281
_ZNK4PLMD8GridBase8getValueERKSt6vectorIdSaIdEE345
_ZNK4PLMD8GridBase8getValueERKSt6vectorIjSaIjEE1193613
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.cpp.gcov.html b/coverage/tools/Grid.cpp.gcov.html new file mode 100644 index 000000000000..25ba199fdca8 --- /dev/null +++ b/coverage/tools/Grid.cpp.gcov.html @@ -0,0 +1,1205 @@ + + + + + + + + LCOV - plumed test coverage - tools/Grid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44061971.1 %
Date:2024-02-22 21:58:45Functions:557771.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Grid.h"
+      24             : #include "Tools.h"
+      25             : #include "core/Value.h"
+      26             : #include "File.h"
+      27             : #include "Exception.h"
+      28             : #include "KernelFunctions.h"
+      29             : #include "RootFindingBase.h"
+      30             : #include "Communicator.h"
+      31             : 
+      32             : #include <vector>
+      33             : #include <cmath>
+      34             : #include <iostream>
+      35             : #include <sstream>
+      36             : #include <cstdio>
+      37             : #include <cfloat>
+      38             : #include <array>
+      39             : 
+      40             : namespace PLMD {
+      41             : 
+      42             : constexpr std::size_t GridBase::maxdim;
+      43             : 
+      44        1327 : GridBase::GridBase(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+      45        1327 :                    const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv) {
+      46             : // various checks
+      47        1327 :   plumed_assert(args.size()<=maxdim) << "grid dim cannot exceed "<<maxdim;
+      48        1327 :   plumed_massert(args.size()==gmin.size(),"grid min dimensions in input do not match number of arguments");
+      49        1327 :   plumed_massert(args.size()==nbin.size(),"number of bins on input do not match number of arguments");
+      50        1327 :   plumed_massert(args.size()==gmax.size(),"grid max dimensions in input do not match number of arguments");
+      51        1327 :   unsigned dim=gmax.size();
+      52             :   std::vector<std::string> names;
+      53             :   std::vector<bool> isperiodic;
+      54             :   std::vector<std::string> pmin,pmax;
+      55        1327 :   names.resize( dim );
+      56        1327 :   isperiodic.resize( dim );
+      57        1327 :   pmin.resize( dim );
+      58        1327 :   pmax.resize( dim );
+      59        2933 :   for(unsigned int i=0; i<dim; ++i) {
+      60        1606 :     names[i]=args[i]->getName();
+      61        1606 :     if( args[i]->isPeriodic() ) {
+      62             :       isperiodic[i]=true;
+      63         502 :       args[i]->getDomain( pmin[i], pmax[i] );
+      64             :     } else {
+      65             :       isperiodic[i]=false;
+      66             :       pmin[i]="0.";
+      67             :       pmax[i]="0.";
+      68             :     }
+      69             :   }
+      70             : // this is a value-independent initializator
+      71        1327 :   Init(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax);
+      72        2654 : }
+      73             : 
+      74         128 : GridBase::GridBase(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+      75             :                    const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
+      76         128 :                    const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax ) {
+      77             : // this calls the initializator
+      78         128 :   Init(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax);
+      79         128 : }
+      80             : 
+      81        1455 : void GridBase::Init(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+      82             :                     const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
+      83             :                     const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax ) {
+      84        1455 :   fmt_="%14.9f";
+      85             : // various checks
+      86        1455 :   plumed_assert(names.size()<=maxdim) << "grid size cannot exceed "<<maxdim;
+      87        1455 :   plumed_massert(names.size()==gmin.size(),"grid dimensions in input do not match number of arguments");
+      88        1455 :   plumed_massert(names.size()==nbin.size(),"grid dimensions in input do not match number of arguments");
+      89        1455 :   plumed_massert(names.size()==gmax.size(),"grid dimensions in input do not match number of arguments");
+      90        1455 :   dimension_=gmax.size();
+      91        1455 :   str_min_=gmin; str_max_=gmax;
+      92        1455 :   argnames.resize( dimension_ );
+      93        1455 :   min_.resize( dimension_ );
+      94        1455 :   max_.resize( dimension_ );
+      95        1455 :   pbc_.resize( dimension_ );
+      96        3189 :   for(unsigned int i=0; i<dimension_; ++i) {
+      97        1734 :     argnames[i]=names[i];
+      98        1734 :     if( isperiodic[i] ) {
+      99             :       pbc_[i]=true;
+     100             :       str_min_[i]=pmin[i];
+     101             :       str_max_[i]=pmax[i];
+     102             :     } else {
+     103             :       pbc_[i]=false;
+     104             :     }
+     105        1734 :     Tools::convert(str_min_[i],min_[i]);
+     106        1734 :     Tools::convert(str_max_[i],max_[i]);
+     107        1734 :     funcname=funcl;
+     108        1734 :     plumed_massert(max_[i]>min_[i],"maximum in grid must be larger than minimum");
+     109        1734 :     plumed_massert(nbin[i]>0,"number of grid points must be greater than zero");
+     110             :   }
+     111        1455 :   nbin_=nbin;
+     112        1455 :   dospline_=dospline;
+     113        1455 :   usederiv_=usederiv;
+     114        1455 :   if(dospline_) plumed_assert(dospline_==usederiv_);
+     115        1455 :   maxsize_=1;
+     116        3189 :   for(unsigned int i=0; i<dimension_; ++i) {
+     117        1734 :     dx_.push_back( (max_[i]-min_[i])/static_cast<double>( nbin_[i] ) );
+     118        1734 :     if( !pbc_[i] ) { max_[i] += dx_[i]; nbin_[i] += 1; }
+     119        1734 :     maxsize_*=nbin_[i];
+     120             :   }
+     121        1455 : }
+     122             : 
+     123     1360394 : std::vector<std::string> GridBase::getMin() const {
+     124     1360394 :   return str_min_;
+     125             : }
+     126             : 
+     127         343 : std::vector<std::string> GridBase::getMax() const {
+     128         343 :   return str_max_;
+     129             : }
+     130             : 
+     131     1319573 : std::vector<double> GridBase::getDx() const {
+     132     1319573 :   return dx_;
+     133             : }
+     134             : 
+     135       11890 : double GridBase::getDx(index_t j) const {
+     136       11890 :   return dx_[j];
+     137             : }
+     138             : 
+     139          37 : double GridBase::getBinVolume() const {
+     140             :   double vol=1.;
+     141         102 :   for(unsigned i=0; i<dx_.size(); ++i) vol*=dx_[i];
+     142          37 :   return vol;
+     143             : }
+     144             : 
+     145        2240 : std::vector<bool> GridBase::getIsPeriodic() const {
+     146        2240 :   return pbc_;
+     147             : }
+     148             : 
+     149     1012510 : std::vector<unsigned> GridBase::getNbin() const {
+     150     1012510 :   return nbin_;
+     151             : }
+     152             : 
+     153        9436 : std::vector<std::string> GridBase::getArgNames() const {
+     154        9436 :   return argnames;
+     155             : }
+     156             : 
+     157    18321217 : unsigned GridBase::getDimension() const {
+     158    18321217 :   return dimension_;
+     159             : }
+     160             : 
+     161             : // we are flattening arrays using a column-major order
+     162     7145799 : GridBase::index_t GridBase::getIndex(const std::vector<unsigned> & indices) const {
+     163             :   plumed_dbg_assert(indices.size()==dimension_);
+     164    19319332 :   for(unsigned int i=0; i<dimension_; i++)
+     165    12173533 :     if(indices[i]>=nbin_[i]) {
+     166             :       std::string is;
+     167           0 :       Tools::convert(i,is);
+     168           0 :       plumed_error() << "Looking for a value outside the grid along the " << is << " dimension (arg name: "<<getArgNames()[i]<<")";
+     169             :     }
+     170     7145799 :   index_t index=indices[dimension_-1];
+     171    12173533 :   for(unsigned int i=dimension_-1; i>0; --i) {
+     172     5027734 :     index=index*nbin_[i-1]+indices[i-1];
+     173             :   }
+     174     7145799 :   return index;
+     175             : }
+     176             : 
+     177     1100069 : GridBase::index_t GridBase::getIndex(const std::vector<double> & x) const {
+     178             :   plumed_dbg_assert(x.size()==dimension_);
+     179     2200138 :   return getIndex(getIndices(x));
+     180             : }
+     181             : 
+     182             : // we are flattening arrays using a column-major order
+     183    37829485 : std::vector<unsigned> GridBase::getIndices(index_t index) const {
+     184    37829485 :   std::vector<unsigned> indices(dimension_);
+     185             :   index_t kk=index;
+     186    37829485 :   indices[0]=(index%nbin_[0]);
+     187    54778194 :   for(unsigned int i=1; i<dimension_-1; ++i) {
+     188    16948709 :     kk=(kk-indices[i-1])/nbin_[i-1];
+     189    16948709 :     indices[i]=(kk%nbin_[i]);
+     190             :   }
+     191    37829485 :   if(dimension_>=2) {
+     192    36999987 :     indices[dimension_-1]=((kk-indices[dimension_-2])/nbin_[dimension_-2]);
+     193             :   }
+     194    37829485 :   return indices;
+     195             : }
+     196             : 
+     197        8910 : void GridBase::getIndices(index_t index, std::vector<unsigned>& indices) const {
+     198        8910 :   if (indices.size()!=dimension_) indices.resize(dimension_);
+     199             :   index_t kk=index;
+     200        8910 :   indices[0]=(index%nbin_[0]);
+     201        8910 :   for(unsigned int i=1; i<dimension_-1; ++i) {
+     202           0 :     kk=(kk-indices[i-1])/nbin_[i-1];
+     203           0 :     indices[i]=(kk%nbin_[i]);
+     204             :   }
+     205        8910 :   if(dimension_>=2) {
+     206        2980 :     indices[dimension_-1]=((kk-indices[dimension_-2])/nbin_[dimension_-2]);
+     207             :   }
+     208        8910 : }
+     209             : 
+     210     1104281 : std::vector<unsigned> GridBase::getIndices(const std::vector<double> & x) const {
+     211             :   plumed_dbg_assert(x.size()==dimension_);
+     212     1104281 :   std::vector<unsigned> indices(dimension_);
+     213     3308069 :   for(unsigned int i=0; i<dimension_; ++i) {
+     214     2203788 :     indices[i] = unsigned(std::floor((x[i]-min_[i])/dx_[i]));
+     215             :   }
+     216     1104281 :   return indices;
+     217             : }
+     218             : 
+     219        3711 : void GridBase::getIndices(const std::vector<double> & x, std::vector<unsigned>& indices) const {
+     220             :   plumed_dbg_assert(x.size()==dimension_);
+     221        3711 :   if (indices.size()!=dimension_) indices.resize(dimension_);
+     222        8167 :   for(unsigned int i=0; i<dimension_; ++i) {
+     223        4456 :     indices[i] = unsigned(std::floor((x[i]-min_[i])/dx_[i]));
+     224             :   }
+     225        3711 : }
+     226             : 
+     227    31542440 : std::vector<double> GridBase::getPoint(const std::vector<unsigned> & indices) const {
+     228             :   plumed_dbg_assert(indices.size()==dimension_);
+     229    31542440 :   std::vector<double> x(dimension_);
+     230   108460905 :   for(unsigned int i=0; i<dimension_; ++i) {
+     231    76918465 :     x[i]=min_[i]+(double)(indices[i])*dx_[i];
+     232             :   }
+     233    31542440 :   return x;
+     234             : }
+     235             : 
+     236    28822338 : std::vector<double> GridBase::getPoint(index_t index) const {
+     237             :   plumed_dbg_assert(index<maxsize_);
+     238    57644676 :   return getPoint(getIndices(index));
+     239             : }
+     240             : 
+     241           0 : std::vector<double> GridBase::getPoint(const std::vector<double> & x) const {
+     242             :   plumed_dbg_assert(x.size()==dimension_);
+     243           0 :   return getPoint(getIndices(x));
+     244             : }
+     245             : 
+     246     1110281 : void GridBase::getPoint(index_t index,std::vector<double> & point) const {
+     247             :   plumed_dbg_assert(index<maxsize_);
+     248     1110281 :   getPoint(getIndices(index),point);
+     249     1110281 : }
+     250             : 
+     251     1113992 : void GridBase::getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const {
+     252             :   plumed_dbg_assert(indices.size()==dimension_);
+     253             :   plumed_dbg_assert(point.size()==dimension_);
+     254     3329356 :   for(unsigned int i=0; i<dimension_; ++i) {
+     255     2215364 :     point[i]=min_[i]+(double)(indices[i])*dx_[i];
+     256             :   }
+     257     1113992 : }
+     258             : 
+     259           0 : void GridBase::getPoint(const std::vector<double> & x,std::vector<double> & point) const {
+     260             :   plumed_dbg_assert(x.size()==dimension_);
+     261           0 :   getPoint(getIndices(x),point);
+     262           0 : }
+     263             : 
+     264       23364 : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<unsigned> &indices,const std::vector<unsigned> &nneigh)const {
+     265             :   plumed_dbg_assert(indices.size()==dimension_ && nneigh.size()==dimension_);
+     266             : 
+     267             :   std::vector<index_t> neighbors;
+     268       23364 :   std::vector<unsigned> small_bin(dimension_);
+     269             : 
+     270             :   unsigned small_nbin=1;
+     271       69592 :   for(unsigned j=0; j<dimension_; ++j) {
+     272       46228 :     small_bin[j]=(2*nneigh[j]+1);
+     273       46228 :     small_nbin*=small_bin[j];
+     274             :   }
+     275             : 
+     276       23364 :   std::vector<unsigned> small_indices(dimension_);
+     277             :   std::vector<unsigned> tmp_indices;
+     278     1291958 :   for(unsigned index=0; index<small_nbin; ++index) {
+     279     1268594 :     tmp_indices.resize(dimension_);
+     280             :     unsigned kk=index;
+     281     1268594 :     small_indices[0]=(index%small_bin[0]);
+     282     1268594 :     for(unsigned i=1; i<dimension_-1; ++i) {
+     283           0 :       kk=(kk-small_indices[i-1])/small_bin[i-1];
+     284           0 :       small_indices[i]=(kk%small_bin[i]);
+     285             :     }
+     286     1268594 :     if(dimension_>=2) {
+     287     1255566 :       small_indices[dimension_-1]=((kk-small_indices[dimension_-2])/small_bin[dimension_-2]);
+     288             :     }
+     289             :     unsigned ll=0;
+     290     3792754 :     for(unsigned i=0; i<dimension_; ++i) {
+     291     2524160 :       int i0=small_indices[i]-nneigh[i]+indices[i];
+     292     2524160 :       if(!pbc_[i] && i0<0)         continue;
+     293     2504438 :       if(!pbc_[i] && i0>=static_cast<int>(nbin_[i])) continue;
+     294     2483466 :       if( pbc_[i] && i0<0)         i0=nbin_[i]-(-i0)%nbin_[i];
+     295     2483466 :       if( pbc_[i] && i0>=static_cast<int>(nbin_[i])) i0%=nbin_[i];
+     296     2483466 :       tmp_indices[ll]=static_cast<unsigned>(i0);
+     297     2483466 :       ll++;
+     298             :     }
+     299     1268594 :     tmp_indices.resize(ll);
+     300     1268594 :     if(tmp_indices.size()==dimension_) {neighbors.push_back(getIndex(tmp_indices));}
+     301             :   }
+     302       23364 :   return neighbors;
+     303             : }
+     304             : 
+     305        4211 : std::vector<GridBase::index_t> GridBase::getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & nneigh)const {
+     306             :   plumed_dbg_assert(x.size()==dimension_ && nneigh.size()==dimension_);
+     307        8422 :   return getNeighbors(getIndices(x),nneigh);
+     308             : }
+     309             : 
+     310       19153 : std::vector<GridBase::index_t> GridBase::getNeighbors(index_t index,const std::vector<unsigned> & nneigh)const {
+     311             :   plumed_dbg_assert(index<maxsize_ && nneigh.size()==dimension_);
+     312       38306 :   return getNeighbors(getIndices(index),nneigh);
+     313             : }
+     314             : 
+     315        3711 : void GridBase::getSplineNeighbors(const std::vector<unsigned> & indices, std::vector<GridBase::index_t>& neighbors, unsigned& nneighbors)const {
+     316             :   plumed_dbg_assert(indices.size()==dimension_);
+     317        3711 :   unsigned nneigh=unsigned(std::pow(2.0,int(dimension_)));
+     318        3711 :   if (neighbors.size()!=nneigh) neighbors.resize(nneigh);
+     319             : 
+     320        3711 :   std::vector<unsigned> nindices(dimension_);
+     321        3711 :   unsigned inind; nneighbors = 0;
+     322       12623 :   for(unsigned int i=0; i<nneigh; ++i) {
+     323             :     unsigned tmp=i; inind=0;
+     324       20804 :     for(unsigned int j=0; j<dimension_; ++j) {
+     325       11892 :       unsigned i0=tmp%2+indices[j];
+     326       11892 :       tmp/=2;
+     327       11892 :       if(!pbc_[j] && i0==nbin_[j]) continue;
+     328       11890 :       if( pbc_[j] && i0==nbin_[j]) i0=0;
+     329       11890 :       nindices[inind++]=i0;
+     330             :     }
+     331        8912 :     if(inind==dimension_) neighbors[nneighbors++]=getIndex(nindices);
+     332             :   }
+     333        3711 : }
+     334             : 
+     335        9577 : std::vector<GridBase::index_t> GridBase::getNearestNeighbors(const index_t index) const {
+     336        9577 :   std::vector<index_t> nearest_neighs = std::vector<index_t>();
+     337       28730 :   for (unsigned i = 0; i < dimension_; i++) {
+     338       19153 :     std::vector<unsigned> neighsneeded = std::vector<unsigned>(dimension_, 0);
+     339       19153 :     neighsneeded[i] = 1;
+     340       19153 :     std::vector<index_t> singledim_nearest_neighs = getNeighbors(index, neighsneeded);
+     341       74978 :     for (unsigned j = 0; j < singledim_nearest_neighs.size(); j++) {
+     342       55825 :       index_t neigh = singledim_nearest_neighs[j];
+     343       55825 :       if (neigh != index) {
+     344       36672 :         nearest_neighs.push_back(neigh);
+     345             :       }
+     346             :     }
+     347             :   }
+     348        9577 :   return nearest_neighs;
+     349             : }
+     350             : 
+     351           0 : std::vector<GridBase::index_t> GridBase::getNearestNeighbors(const std::vector<unsigned> &indices) const {
+     352             :   plumed_dbg_assert(indices.size() == dimension_);
+     353           0 :   return getNearestNeighbors(getIndex(indices));
+     354             : }
+     355             : 
+     356           0 : void GridBase::addKernel( const KernelFunctions& kernel ) {
+     357             :   plumed_dbg_assert( kernel.ndim()==dimension_ );
+     358           0 :   std::vector<unsigned> nneighb=kernel.getSupport( dx_ );
+     359           0 :   std::vector<index_t> neighbors=getNeighbors( kernel.getCenter(), nneighb );
+     360           0 :   std::vector<double> xx( dimension_ );
+     361           0 :   std::vector<std::unique_ptr<Value>> vv( dimension_ );
+     362             :   std::string str_min, str_max;
+     363           0 :   for(unsigned i=0; i<dimension_; ++i) {
+     364           0 :     vv[i]=Tools::make_unique<Value>();
+     365           0 :     if( pbc_[i] ) {
+     366           0 :       Tools::convert(min_[i],str_min);
+     367           0 :       Tools::convert(max_[i],str_max);
+     368           0 :       vv[i]->setDomain( str_min, str_max );
+     369             :     } else {
+     370           0 :       vv[i]->setNotPeriodic();
+     371             :     }
+     372             :   }
+     373             : 
+     374             : // vv_ptr contains plain pointers obtained from vv.
+     375             : // this is the simplest way to replace a unique_ptr here.
+     376             : // perhaps the interface of kernel.evaluate() should be changed
+     377             : // in order to accept a std::vector<std::unique_ptr<Value>>
+     378           0 :   auto vv_ptr=Tools::unique2raw(vv);
+     379             : 
+     380           0 :   std::vector<double> der( dimension_ );
+     381           0 :   for(unsigned i=0; i<neighbors.size(); ++i) {
+     382           0 :     index_t ineigh=neighbors[i];
+     383           0 :     getPoint( ineigh, xx );
+     384           0 :     for(unsigned j=0; j<dimension_; ++j) vv[j]->set(xx[j]);
+     385           0 :     double newval = kernel.evaluate( vv_ptr, der, usederiv_ );
+     386           0 :     if( usederiv_ ) addValueAndDerivatives( ineigh, newval, der );
+     387           0 :     else addValue( ineigh, newval );
+     388             :   }
+     389           0 : }
+     390             : 
+     391     1193613 : double GridBase::getValue(const std::vector<unsigned> & indices) const {
+     392     1193613 :   return getValue(getIndex(indices));
+     393             : }
+     394             : 
+     395         345 : double GridBase::getValue(const std::vector<double> & x) const {
+     396         345 :   if(!dospline_) {
+     397          18 :     return getValue(getIndex(x));
+     398             :   } else {
+     399         327 :     std::vector<double> der(dimension_);
+     400         327 :     return getValueAndDerivatives(x,der);
+     401             :   }
+     402             : }
+     403             : 
+     404     2527708 : double GridBase::getValueAndDerivatives(const std::vector<unsigned> & indices, std::vector<double>& der) const {
+     405     2527708 :   return getValueAndDerivatives(getIndex(indices),der);
+     406             : }
+     407             : 
+     408        3711 : double GridBase::getValueAndDerivatives(const std::vector<double> & x, std::vector<double>& der) const {
+     409             :   plumed_dbg_assert(der.size()==dimension_ && usederiv_);
+     410             : 
+     411        3711 :   if(dospline_) {
+     412             :     double X,X2,X3,value;
+     413             :     std::array<double,maxdim> fd, C, D;
+     414        3711 :     std::vector<double> dder(dimension_);
+     415             : // reset
+     416             :     value=0.0;
+     417        8167 :     for(unsigned int i=0; i<dimension_; ++i) der[i]=0.0;
+     418             : 
+     419        3711 :     std::vector<unsigned> indices(dimension_);
+     420        3711 :     getIndices(x, indices);
+     421        3711 :     std::vector<double> xfloor(dimension_);
+     422        3711 :     getPoint(indices, xfloor);
+     423        3711 :     std::vector<index_t> neigh; unsigned nneigh; getSplineNeighbors(indices, neigh, nneigh);
+     424             : 
+     425             : // loop over neighbors
+     426             :     std::vector<unsigned> nindices;
+     427       12621 :     for(unsigned int ipoint=0; ipoint<nneigh; ++ipoint) {
+     428        8910 :       double grid=getValueAndDerivatives(neigh[ipoint],dder);
+     429        8910 :       getIndices(neigh[ipoint], nindices);
+     430             :       double ff=1.0;
+     431             : 
+     432       20800 :       for(unsigned j=0; j<dimension_; ++j) {
+     433             :         int x0=1;
+     434       11890 :         if(nindices[j]==indices[j]) x0=0;
+     435       11890 :         double dx=getDx(j);
+     436       11890 :         X=std::abs((x[j]-xfloor[j])/dx-(double)x0);
+     437       11890 :         X2=X*X;
+     438       11890 :         X3=X2*X;
+     439             :         double yy;
+     440       11890 :         if(std::abs(grid)<0.0000001) yy=0.0;
+     441        8996 :         else yy=-dder[j]/grid;
+     442       11890 :         C[j]=(1.0-3.0*X2+2.0*X3) - (x0?-1.0:1.0)*yy*(X-2.0*X2+X3)*dx;
+     443       11890 :         D[j]=( -6.0*X +6.0*X2) - (x0?-1.0:1.0)*yy*(1.0-4.0*X +3.0*X2)*dx;
+     444       11890 :         D[j]*=(x0?-1.0:1.0)/dx;
+     445       11890 :         ff*=C[j];
+     446             :       }
+     447       20800 :       for(unsigned j=0; j<dimension_; ++j) {
+     448       11890 :         fd[j]=D[j];
+     449       29740 :         for(unsigned i=0; i<dimension_; ++i) if(i!=j) fd[j]*=C[i];
+     450             :       }
+     451        8910 :       value+=grid*ff;
+     452       20800 :       for(unsigned j=0; j<dimension_; ++j) der[j]+=grid*fd[j];
+     453             :     }
+     454             :     return value;
+     455             :   } else {
+     456           0 :     return getValueAndDerivatives(getIndex(x),der);
+     457             :   }
+     458             : }
+     459             : 
+     460           0 : void GridBase::setValue(const std::vector<unsigned> & indices, double value) {
+     461           0 :   setValue(getIndex(indices),value);
+     462           0 : }
+     463             : 
+     464           0 : void GridBase::setValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der) {
+     465           0 :   setValueAndDerivatives(getIndex(indices),value,der);
+     466           0 : }
+     467             : 
+     468           0 : void GridBase::addValue(const std::vector<unsigned> & indices, double value) {
+     469           0 :   addValue(getIndex(indices),value);
+     470           0 : }
+     471             : 
+     472           0 : void GridBase::addValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der) {
+     473           0 :   addValueAndDerivatives(getIndex(indices),value,der);
+     474           0 : }
+     475             : 
+     476        1147 : void GridBase::writeHeader(OFile& ofile) {
+     477        2611 :   for(unsigned i=0; i<dimension_; ++i) {
+     478        2928 :     ofile.addConstantField("min_" + argnames[i]);
+     479        2928 :     ofile.addConstantField("max_" + argnames[i]);
+     480        2928 :     ofile.addConstantField("nbins_" + argnames[i]);
+     481        2928 :     ofile.addConstantField("periodic_" + argnames[i]);
+     482             :   }
+     483        1147 : }
+     484             : 
+     485           1 : void Grid::clear() {
+     486           1 :   grid_.assign(maxsize_,0.0);
+     487           1 :   if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
+     488           1 : }
+     489             : 
+     490        1147 : void Grid::writeToFile(OFile& ofile) {
+     491        1147 :   std::vector<double> xx(dimension_);
+     492        1147 :   std::vector<double> der(dimension_);
+     493             :   double f;
+     494        1147 :   writeHeader(ofile);
+     495     2533412 :   for(index_t i=0; i<getSize(); ++i) {
+     496     2532265 :     xx=getPoint(i);
+     497     2532265 :     if(usederiv_) {f=getValueAndDerivatives(i,der);}
+     498     1989707 :     else {f=getValue(i);}
+     499     4914902 :     if(i>0 && dimension_>1 && getIndices(i)[dimension_-2]==0) ofile.printf("\n");
+     500     7484524 :     for(unsigned j=0; j<dimension_; ++j) {
+     501     9904518 :       ofile.printField("min_" + argnames[j], str_min_[j] );
+     502     9904518 :       ofile.printField("max_" + argnames[j], str_max_[j] );
+     503     9904518 :       ofile.printField("nbins_" + argnames[j], static_cast<int>(nbin_[j]) );
+     504     6986607 :       if( pbc_[j] ) ofile.printField("periodic_" + argnames[j], "true" );
+     505     5835822 :       else          ofile.printField("periodic_" + argnames[j], "false" );
+     506             :     }
+     507     7484524 :     for(unsigned j=0; j<dimension_; ++j) { ofile.fmtField(" "+fmt_); ofile.printField(argnames[j],xx[j]); }
+     508     5064530 :     ofile.fmtField(" "+fmt_); ofile.printField(funcname,f);
+     509     5194297 :     if(usederiv_) for(unsigned j=0; j<dimension_; ++j) { ofile.fmtField(" "+fmt_); ofile.printField("der_" + argnames[j],der[j]); }
+     510     2532265 :     ofile.printField();
+     511             :   }
+     512        1147 : }
+     513             : 
+     514           0 : void GridBase::writeCubeFile(OFile& ofile, const double& lunit) {
+     515           0 :   plumed_assert( dimension_==3 );
+     516           0 :   ofile.printf("PLUMED CUBE FILE\n");
+     517           0 :   ofile.printf("OUTER LOOP: X, MIDDLE LOOP: Y, INNER LOOP: Z\n");
+     518             :   // Number of atoms followed by position of origin (origin set so that center of grid is in center of cell)
+     519           0 :   ofile.printf("%d %f %f %f\n",1,-0.5*lunit*(max_[0]-min_[0]),-0.5*lunit*(max_[1]-min_[1]),-0.5*lunit*(max_[2]-min_[2]));
+     520           0 :   ofile.printf("%u %f %f %f\n",nbin_[0],lunit*dx_[0],0.0,0.0);  // Number of bins in each direction followed by
+     521           0 :   ofile.printf("%u %f %f %f\n",nbin_[1],0.0,lunit*dx_[1],0.0);  // shape of voxel
+     522           0 :   ofile.printf("%u %f %f %f\n",nbin_[2],0.0,0.0,lunit*dx_[2]);
+     523           0 :   ofile.printf("%d %f %f %f\n",1,0.0,0.0,0.0); // Fake atom otherwise VMD doesn't work
+     524           0 :   std::vector<unsigned> pp(3);
+     525           0 :   for(pp[0]=0; pp[0]<nbin_[0]; ++pp[0]) {
+     526           0 :     for(pp[1]=0; pp[1]<nbin_[1]; ++pp[1]) {
+     527           0 :       for(pp[2]=0; pp[2]<nbin_[2]; ++pp[2]) {
+     528           0 :         ofile.printf("%f ",getValue(pp) );
+     529           0 :         if(pp[2]%6==5) ofile.printf("\n");
+     530             :       }
+     531           0 :       ofile.printf("\n");
+     532             :     }
+     533             :   }
+     534           0 : }
+     535             : 
+     536          20 : std::unique_ptr<GridBase> GridBase::create(const std::string& funcl, const std::vector<Value*> & args, IFile& ifile,
+     537             :     const std::vector<std::string> & gmin,const std::vector<std::string> & gmax,
+     538             :     const std::vector<unsigned> & nbin,bool dosparse, bool dospline, bool doder) {
+     539          20 :   std::unique_ptr<GridBase> grid=GridBase::create(funcl,args,ifile,dosparse,dospline,doder);
+     540          20 :   std::vector<unsigned> cbin( grid->getNbin() );
+     541          20 :   std::vector<std::string> cmin( grid->getMin() ), cmax( grid->getMax() );
+     542          49 :   for(unsigned i=0; i<args.size(); ++i) {
+     543          29 :     plumed_massert( cmin[i]==gmin[i], "mismatched grid min" );
+     544          29 :     plumed_massert( cmax[i]==gmax[i], "mismatched grid max" );
+     545          29 :     if( args[i]->isPeriodic() ) {
+     546           8 :       plumed_massert( cbin[i]==nbin[i], "mismatched grid nbins" );
+     547             :     } else {
+     548          21 :       plumed_massert( (cbin[i]-1)==nbin[i], "mismatched grid nbins");
+     549             :     }
+     550             :   }
+     551          20 :   return grid;
+     552          20 : }
+     553             : 
+     554          70 : std::unique_ptr<GridBase> GridBase::create(const std::string& funcl, const std::vector<Value*> & args, IFile& ifile, bool dosparse, bool dospline, bool doder)
+     555             : {
+     556          70 :   std::unique_ptr<GridBase> grid;
+     557          70 :   unsigned nvar=args.size(); bool hasder=false; std::string pstring;
+     558          70 :   std::vector<int> gbin1(nvar); std::vector<unsigned> gbin(nvar);
+     559          70 :   std::vector<std::string> labels(nvar),gmin(nvar),gmax(nvar);
+     560          70 :   std::vector<std::string> fieldnames; ifile.scanFieldList( fieldnames );
+     561             : // Retrieve names for fields
+     562         158 :   for(unsigned i=0; i<args.size(); ++i) labels[i]=args[i]->getName();
+     563             : // And read the stuff from the header
+     564          70 :   plumed_massert( ifile.FieldExist( funcl ), "no column labelled " + funcl + " in in grid input");
+     565         158 :   for(unsigned i=0; i<args.size(); ++i) {
+     566         176 :     ifile.scanField( "min_" + labels[i], gmin[i]);
+     567         176 :     ifile.scanField( "max_" + labels[i], gmax[i]);
+     568         176 :     ifile.scanField( "periodic_" + labels[i], pstring );
+     569         176 :     ifile.scanField( "nbins_" + labels[i], gbin1[i]);
+     570          88 :     plumed_assert( gbin1[i]>0 );
+     571          88 :     if( args[i]->isPeriodic() ) {
+     572          26 :       plumed_massert( pstring=="true", "input value is periodic but grid is not");
+     573             :       std::string pmin, pmax;
+     574          26 :       args[i]->getDomain( pmin, pmax ); gbin[i]=gbin1[i];
+     575          26 :       if( pmin!=gmin[i] || pmax!=gmax[i] ) plumed_merror("mismatch between grid boundaries and periods of values");
+     576             :     } else {
+     577          62 :       gbin[i]=gbin1[i]-1;  // Note header in grid file indicates one more bin that there should be when data is not periodic
+     578          62 :       plumed_massert( pstring=="false", "input value is not periodic but grid is");
+     579             :     }
+     580          88 :     hasder=ifile.FieldExist( "der_" + args[i]->getName() );
+     581          88 :     if( doder && !hasder ) plumed_merror("missing derivatives from grid file");
+     582         106 :     for(unsigned j=0; j<fieldnames.size(); ++j) {
+     583         124 :       for(unsigned k=i+1; k<args.size(); ++k) {
+     584          18 :         if( fieldnames[j]==labels[k] ) plumed_merror("arguments in input are not in same order as in grid file");
+     585             :       }
+     586         106 :       if( fieldnames[j]==labels[i] ) break;
+     587             :     }
+     588             :   }
+     589             : 
+     590         140 :   if(!dosparse) {grid=Tools::make_unique<Grid>(funcl,args,gmin,gmax,gbin,dospline,doder);}
+     591           0 :   else {grid=Tools::make_unique<SparseGrid>(funcl,args,gmin,gmax,gbin,dospline,doder);}
+     592             : 
+     593          70 :   std::vector<double> xx(nvar),dder(nvar);
+     594          70 :   std::vector<double> dx=grid->getDx();
+     595             :   double f,x;
+     596     1099575 :   while( ifile.scanField(funcl,f) ) {
+     597     3294553 :     for(unsigned i=0; i<nvar; ++i) {
+     598     2195048 :       ifile.scanField(labels[i],x); xx[i]=x+dx[i]/2.0;
+     599     4390096 :       ifile.scanField( "min_" + labels[i], gmin[i]);
+     600     4390096 :       ifile.scanField( "max_" + labels[i], gmax[i]);
+     601     4390096 :       ifile.scanField( "nbins_" + labels[i], gbin1[i]);
+     602     4390096 :       ifile.scanField( "periodic_" + labels[i], pstring );
+     603             :     }
+     604     3211140 :     if(hasder) { for(unsigned i=0; i<nvar; ++i) { ifile.scanField( "der_" + args[i]->getName(), dder[i] ); } }
+     605     1099505 :     index_t index=grid->getIndex(xx);
+     606     1099505 :     if(doder) {grid->setValueAndDerivatives(index,f,dder);}
+     607       42717 :     else {grid->setValue(index,f);}
+     608     1099505 :     ifile.scanField();
+     609             :   }
+     610          70 :   return grid;
+     611          70 : }
+     612             : 
+     613         861 : double Grid::getMinValue() const {
+     614             :   double minval;
+     615             :   minval=DBL_MAX;
+     616     2258311 :   for(index_t i=0; i<grid_.size(); ++i) {
+     617     2257450 :     if(grid_[i]<minval)minval=grid_[i];
+     618             :   }
+     619         861 :   return minval;
+     620             : }
+     621             : 
+     622         629 : double Grid::getMaxValue() const {
+     623             :   double maxval;
+     624             :   maxval=DBL_MIN;
+     625     3755246 :   for(index_t i=0; i<grid_.size(); ++i) {
+     626     3754617 :     if(grid_[i]>maxval)maxval=grid_[i];
+     627             :   }
+     628         629 :   return maxval;
+     629             : }
+     630             : 
+     631         594 : void Grid::scaleAllValuesAndDerivatives( const double& scalef ) {
+     632         594 :   if(usederiv_) {
+     633       21474 :     for(index_t i=0; i<grid_.size(); ++i) {
+     634       21463 :       grid_[i]*=scalef;
+     635       63888 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j]*=scalef;
+     636             :     }
+     637             :   } else {
+     638     1572834 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i]*=scalef;
+     639             :   }
+     640         594 : }
+     641             : 
+     642           0 : void Grid::logAllValuesAndDerivatives( const double& scalef ) {
+     643           0 :   if(usederiv_) {
+     644           0 :     for(index_t i=0; i<grid_.size(); ++i) {
+     645           0 :       grid_[i] = scalef*std::log(grid_[i]);
+     646           0 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j] = scalef/der_[i*dimension_+j];
+     647             :     }
+     648             :   } else {
+     649           0 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i] = scalef*std::log(grid_[i]);
+     650             :   }
+     651           0 : }
+     652             : 
+     653        1329 : void Grid::setMinToZero() {
+     654        1329 :   double min=grid_[0];
+     655     3518541 :   for(index_t i=1; i<grid_.size(); ++i) if(grid_[i]<min) min=grid_[i];
+     656     3519870 :   for(index_t i=0; i<grid_.size(); ++i) grid_[i] -= min;
+     657        1329 : }
+     658             : 
+     659           1 : void Grid::applyFunctionAllValuesAndDerivatives( double (*func)(double val), double (*funcder)(double valder) ) {
+     660           1 :   if(usederiv_) {
+     661         901 :     for(index_t i=0; i<grid_.size(); ++i) {
+     662         900 :       grid_[i]=func(grid_[i]);
+     663        2700 :       for(unsigned j=0; j<dimension_; ++j) der_[i*dimension_+j]=funcder(der_[i*dimension_+j]);
+     664             :     }
+     665             :   } else {
+     666           0 :     for(index_t i=0; i<grid_.size(); ++i) grid_[i]=func(grid_[i]);
+     667             :   }
+     668           1 : }
+     669             : 
+     670           0 : double Grid::getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ) const {
+     671           0 :   return getValueAndDerivatives( x, der ) - contour_location;
+     672             : }
+     673             : 
+     674           0 : void Grid::findSetOfPointsOnContour(const double& target, const std::vector<bool>& nosearch,
+     675             :                                     unsigned& npoints, std::vector<std::vector<double> >& points ) {
+     676             : // Set contour location for function
+     677           0 :   contour_location=target;
+     678             : // Resize points to maximum possible value
+     679           0 :   points.resize( dimension_*maxsize_ );
+     680             : 
+     681             : // Two points for search
+     682           0 :   std::vector<unsigned> ind(dimension_);
+     683           0 :   std::vector<double> direction( dimension_, 0 );
+     684             : 
+     685             : // Run over whole grid
+     686           0 :   npoints=0; RootFindingBase<Grid> mymin( this );
+     687           0 :   for(unsigned i=0; i<maxsize_; ++i) {
+     688           0 :     for(unsigned j=0; j<dimension_; ++j) ind[j]=getIndices(i)[j];
+     689             : 
+     690             :     // Get the value of a point on the grid
+     691           0 :     double val1=getValue(i) - target;
+     692             : 
+     693             :     // Now search for contour in each direction
+     694             :     bool edge=false;
+     695           0 :     for(unsigned j=0; j<dimension_; ++j) {
+     696           0 :       if( nosearch[j] ) continue ;
+     697             :       // Make sure we don't search at the edge of the grid
+     698           0 :       if( !pbc_[j] && (ind[j]+1)==nbin_[j] ) continue;
+     699           0 :       else if( (ind[j]+1)==nbin_[j] ) { edge=true; ind[j]=0; }
+     700           0 :       else ind[j]+=1;
+     701           0 :       double val2=getValue(ind) - target;
+     702           0 :       if( val1*val2<0 ) {
+     703             :         // Use initial point location as first guess for search
+     704           0 :         points[npoints].resize(dimension_); for(unsigned k=0; k<dimension_; ++k) points[npoints][k]=getPoint(i)[k];
+     705             :         // Setup direction vector
+     706           0 :         direction[j]=0.999999999*dx_[j];
+     707             :         // And do proper search for contour point
+     708           0 :         mymin.linesearch( direction, points[npoints], &Grid::getDifferenceFromContour );
+     709           0 :         direction[j]=0.0; npoints++;
+     710             :       }
+     711           0 :       if( pbc_[j] && edge ) { edge=false; ind[j]=nbin_[j]-1; }
+     712           0 :       else ind[j]-=1;
+     713             :     }
+     714             :   }
+     715           0 : }
+     716             : 
+     717             : /// OVERRIDES ARE BELOW
+     718             : 
+     719    28865222 : Grid::index_t Grid::getSize() const {
+     720    28865222 :   return maxsize_;
+     721             : }
+     722             : 
+     723    27284983 : double Grid::getValue(index_t index) const {
+     724             :   plumed_dbg_assert(index<maxsize_);
+     725    27284983 :   return grid_[index];
+     726             : }
+     727             : 
+     728     3079776 : double Grid::getValueAndDerivatives(index_t index, std::vector<double>& der) const {
+     729             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     730     3079776 :   der.resize(dimension_);
+     731     6679531 :   for(unsigned i=0; i<dimension_; i++) der[i]=der_[dimension_*index+i];
+     732     3079776 :   return grid_[index];
+     733             : }
+     734             : 
+     735     6444104 : void Grid::setValue(index_t index, double value) {
+     736             :   plumed_dbg_assert(index<maxsize_ && !usederiv_);
+     737     6444104 :   grid_[index]=value;
+     738     6444104 : }
+     739             : 
+     740     2552369 : void Grid::setValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     741             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     742     2552369 :   grid_[index]=value;
+     743     7609163 :   for(unsigned i=0; i<dimension_; i++) der_[dimension_*index+i]=der[i];
+     744     2552369 : }
+     745             : 
+     746           1 : void Grid::addValue(index_t index, double value) {
+     747             :   plumed_dbg_assert(index<maxsize_ && !usederiv_);
+     748           1 :   grid_[index]+=value;
+     749           1 : }
+     750             : 
+     751     1171742 : void Grid::addValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     752             :   plumed_dbg_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     753     1171742 :   grid_[index]+=value;
+     754     3500479 :   for(unsigned int i=0; i<dimension_; ++i) der_[index*dimension_+i]+=der[i];
+     755     1171742 : }
+     756             : 
+     757           0 : Grid::index_t SparseGrid::getSize() const {
+     758           0 :   return map_.size();
+     759             : }
+     760             : 
+     761           0 : Grid::index_t SparseGrid::getMaxSize() const {
+     762           0 :   return maxsize_;
+     763             : }
+     764             : 
+     765           0 : double SparseGrid::getValue(index_t index)const {
+     766           0 :   plumed_assert(index<maxsize_);
+     767             :   double value=0.0;
+     768             :   const auto it=map_.find(index);
+     769           0 :   if(it!=map_.end()) value=it->second;
+     770           0 :   return value;
+     771             : }
+     772             : 
+     773         200 : double SparseGrid::getValueAndDerivatives(index_t index, std::vector<double>& der)const {
+     774         200 :   plumed_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     775             :   double value=0.0;
+     776         580 :   for(unsigned int i=0; i<dimension_; ++i) der[i]=0.0;
+     777             :   const auto it=map_.find(index);
+     778         200 :   if(it!=map_.end()) value=it->second;
+     779             :   const auto itder=der_.find(index);
+     780         200 :   if(itder!=der_.end()) der=itder->second;
+     781         200 :   return value;
+     782             : }
+     783             : 
+     784           0 : void SparseGrid::setValue(index_t index, double value) {
+     785           0 :   plumed_assert(index<maxsize_ && !usederiv_);
+     786           0 :   map_[index]=value;
+     787           0 : }
+     788             : 
+     789           0 : void SparseGrid::setValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     790           0 :   plumed_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     791           0 :   map_[index]=value;
+     792           0 :   der_[index]=der;
+     793           0 : }
+     794             : 
+     795           0 : void SparseGrid::addValue(index_t index, double value) {
+     796           0 :   plumed_assert(index<maxsize_ && !usederiv_);
+     797           0 :   map_[index]+=value;
+     798           0 : }
+     799             : 
+     800       19999 : void SparseGrid::addValueAndDerivatives(index_t index, double value, std::vector<double>& der) {
+     801       19999 :   plumed_assert(index<maxsize_ && usederiv_ && der.size()==dimension_);
+     802       19999 :   map_[index]+=value;
+     803       19999 :   der_[index].resize(dimension_);
+     804       59682 :   for(unsigned int i=0; i<dimension_; ++i) der_[index][i]+=der[i];
+     805       19999 : }
+     806             : 
+     807           0 : void SparseGrid::writeToFile(OFile& ofile) {
+     808           0 :   std::vector<double> xx(dimension_);
+     809           0 :   std::vector<double> der(dimension_);
+     810             :   double f;
+     811           0 :   writeHeader(ofile);
+     812           0 :   ofile.fmtField(" "+fmt_);
+     813           0 :   for(const auto & it : map_) {
+     814           0 :     index_t i=it.first;
+     815           0 :     xx=getPoint(i);
+     816           0 :     if(usederiv_) {f=getValueAndDerivatives(i,der);}
+     817           0 :     else {f=getValue(i);}
+     818           0 :     if(i>0 && dimension_>1 && getIndices(i)[dimension_-2]==0) ofile.printf("\n");
+     819           0 :     for(unsigned j=0; j<dimension_; ++j) {
+     820           0 :       ofile.printField("min_" + argnames[j], str_min_[j] );
+     821           0 :       ofile.printField("max_" + argnames[j], str_max_[j] );
+     822           0 :       ofile.printField("nbins_" + argnames[j], static_cast<int>(nbin_[j]) );
+     823           0 :       if( pbc_[j] ) ofile.printField("periodic_" + argnames[j], "true" );
+     824           0 :       else          ofile.printField("periodic_" + argnames[j], "false" );
+     825             :     }
+     826           0 :     for(unsigned j=0; j<dimension_; ++j) ofile.printField(argnames[j],xx[j]);
+     827           0 :     ofile.printField(funcname, f);
+     828           0 :     if(usederiv_) { for(unsigned j=0; j<dimension_; ++j) ofile.printField("der_" + argnames[j],der[j]); }
+     829           0 :     ofile.printField();
+     830             :   }
+     831           0 : }
+     832             : 
+     833           0 : double SparseGrid::getMinValue() const {
+     834             :   double minval;
+     835             :   minval=0.0;
+     836           0 :   for(auto const & i : map_) {
+     837           0 :     if(i.second<minval) minval=i.second;
+     838             :   }
+     839           0 :   return minval;
+     840             : }
+     841             : 
+     842           9 : double SparseGrid::getMaxValue() const {
+     843             :   double maxval;
+     844             :   maxval=0.0;
+     845         590 :   for(auto const & i : map_) {
+     846         581 :     if(i.second>maxval) maxval=i.second;
+     847             :   }
+     848           9 :   return maxval;
+     849             : }
+     850             : 
+     851     1010062 : void Grid::projectOnLowDimension(double &val, std::vector<int> &vHigh, WeightBase * ptr2obj ) {
+     852             :   unsigned i=0;
+     853     3016945 :   for(i=0; i<vHigh.size(); i++) {
+     854     2015726 :     if(vHigh[i]<0) { // this bin needs to be integrated out
+     855             :       // parallelize here???
+     856     1010062 :       for(unsigned j=0; j<(getNbin())[i]; j++) {
+     857     1001219 :         vHigh[i]=int(j);
+     858     1001219 :         projectOnLowDimension(val,vHigh,ptr2obj); // recursive function: this is the core of the mechanism
+     859     1001219 :         vHigh[i]=-1;
+     860             :       }
+     861             :       return; //
+     862             :     }
+     863             :   }
+     864             :   // when there are no more bin to dig in then retrieve the value
+     865     1001219 :   if(i==vHigh.size()) {
+     866             :     //std::cerr<<"POINT: ";
+     867             :     //for(unsigned j=0;j<vHigh.size();j++){
+     868             :     //   std::cerr<<vHigh[j]<<" ";
+     869             :     //}
+     870     1001219 :     std::vector<unsigned> vv(vHigh.size());
+     871     3003657 :     for(unsigned j=0; j<vHigh.size(); j++)vv[j]=unsigned(vHigh[j]);
+     872             :     //
+     873             :     // this is the real assignment !!!!! (hack this to have bias or other stuff)
+     874             :     //
+     875             : 
+     876             :     // this case: produce fes
+     877             :     //val+=exp(beta*getValue(vv)) ;
+     878     1001219 :     double myv=getValue(vv);
+     879     1001219 :     val=ptr2obj->projectInnerLoop(val,myv) ;
+     880             :     // to be added: bias (same as before without negative sign)
+     881             :     //std::cerr<<" VAL: "<<val <<endl;
+     882             :   }
+     883             : }
+     884             : 
+     885          81 : Grid Grid::project(const std::vector<std::string> & proj, WeightBase *ptr2obj ) {
+     886             :   // find extrema only for the projection
+     887             :   std::vector<std::string>   smallMin,smallMax;
+     888             :   std::vector<unsigned> smallBin;
+     889             :   std::vector<unsigned> dimMapping;
+     890             :   std::vector<bool> smallIsPeriodic;
+     891             :   std::vector<std::string> smallName;
+     892             : 
+     893             :   // check if the two key methods are there
+     894             :   WeightBase* pp = dynamic_cast<WeightBase*>(ptr2obj);
+     895          81 :   if (!pp)plumed_merror("This WeightBase is not complete: you need a projectInnerLoop and projectOuterLoop ");
+     896             : 
+     897         162 :   for(unsigned j=0; j<proj.size(); j++) {
+     898         120 :     for(unsigned i=0; i<getArgNames().size(); i++) {
+     899         120 :       if(proj[j]==getArgNames()[i]) {
+     900             :         unsigned offset;
+     901             :         // note that at sizetime the non periodic dimension get a bin more
+     902         162 :         if(getIsPeriodic()[i]) {offset=0;} else {offset=1;}
+     903          81 :         smallMax.push_back(getMax()[i]);
+     904          81 :         smallMin.push_back(getMin()[i]);
+     905          81 :         smallBin.push_back(getNbin()[i]-offset);
+     906         162 :         smallIsPeriodic.push_back(getIsPeriodic()[i]);
+     907          81 :         dimMapping.push_back(i);
+     908          81 :         smallName.push_back(getArgNames()[i]);
+     909          81 :         break;
+     910             :       }
+     911             :     }
+     912             :   }
+     913          81 :   Grid smallgrid("projection",smallName,smallMin,smallMax,smallBin,false,false,smallIsPeriodic,smallMin,smallMax);
+     914             :   // check that the two grids are commensurate
+     915         162 :   for(unsigned i=0; i<dimMapping.size(); i++) {
+     916          81 :     plumed_massert(  (smallgrid.getMax())[i] == (getMax())[dimMapping[i]],  "the two input grids are not compatible in max"   );
+     917          81 :     plumed_massert(  (smallgrid.getMin())[i] == (getMin())[dimMapping[i]],  "the two input grids are not compatible in min"   );
+     918          81 :     plumed_massert(  (smallgrid.getNbin())[i]== (getNbin())[dimMapping[i]], "the two input grids are not compatible in bin"   );
+     919             :   }
+     920             :   std::vector<unsigned> toBeIntegrated;
+     921         243 :   for(unsigned i=0; i<getArgNames().size(); i++) {
+     922             :     bool doappend=true;
+     923         243 :     for(unsigned j=0; j<dimMapping.size(); j++) {
+     924         162 :       if(dimMapping[j]==i) {doappend=false; break;}
+     925             :     }
+     926         162 :     if(doappend)toBeIntegrated.push_back(i);
+     927             :   }
+     928             : 
+     929             :   // loop over all the points in the Grid, find the corresponding fixed index, rotate over all the other ones
+     930        8924 :   for(unsigned i=0; i<smallgrid.getSize(); i++) {
+     931             :     std::vector<unsigned> v;
+     932        8843 :     v=smallgrid.getIndices(i);
+     933        8843 :     std::vector<int> vHigh((getArgNames()).size(),-1);
+     934       17686 :     for(unsigned j=0; j<dimMapping.size(); j++)vHigh[dimMapping[j]]=int(v[j]);
+     935             :     // the vector vhigh now contains at the beginning the index of the low dimension and -1 for the values that need to be integrated
+     936        8843 :     double initval=0.;
+     937        8843 :     projectOnLowDimension(initval,vHigh, ptr2obj);
+     938        8843 :     smallgrid.setValue(i,ptr2obj->projectOuterLoop(initval));
+     939             :   }
+     940             : 
+     941          81 :   return smallgrid;
+     942         162 : }
+     943             : 
+     944           0 : double Grid::integrate( std::vector<unsigned>& npoints ) {
+     945           0 :   plumed_dbg_assert( npoints.size()==dimension_ ); plumed_assert( dospline_ );
+     946             : 
+     947             :   unsigned ntotgrid=1; double box_vol=1.0;
+     948           0 :   std::vector<double> ispacing( npoints.size() );
+     949           0 :   for(unsigned j=0; j<dimension_; ++j) {
+     950           0 :     if( !pbc_[j] ) {
+     951           0 :       ispacing[j] = ( max_[j] - dx_[j] - min_[j] ) / static_cast<double>( npoints[j] );
+     952           0 :       npoints[j]+=1;
+     953             :     } else {
+     954           0 :       ispacing[j] = ( max_[j] - min_[j] ) / static_cast<double>( npoints[j] );
+     955             :     }
+     956           0 :     ntotgrid*=npoints[j]; box_vol*=ispacing[j];
+     957             :   }
+     958             : 
+     959           0 :   std::vector<double> vals( dimension_ );
+     960           0 :   std::vector<unsigned> t_index( dimension_ ); double integral=0.0;
+     961           0 :   for(unsigned i=0; i<ntotgrid; ++i) {
+     962           0 :     t_index[0]=(i%npoints[0]);
+     963             :     unsigned kk=i;
+     964           0 :     for(unsigned j=1; j<dimension_-1; ++j) { kk=(kk-t_index[j-1])/npoints[j-1]; t_index[j]=(kk%npoints[j]); }
+     965           0 :     if( dimension_>=2 ) t_index[dimension_-1]=((kk-t_index[dimension_-2])/npoints[dimension_-2]);
+     966             : 
+     967           0 :     for(unsigned j=0; j<dimension_; ++j) vals[j]=min_[j] + t_index[j]*ispacing[j];
+     968             : 
+     969           0 :     integral += getValue( vals );
+     970             :   }
+     971             : 
+     972           0 :   return box_vol*integral;
+     973             : }
+     974             : 
+     975           0 : void Grid::mpiSumValuesAndDerivatives( Communicator& comm ) {
+     976           0 :   comm.Sum( grid_ ); for(unsigned i=0; i<der_.size(); ++i) comm.Sum( der_[i] );
+     977           0 : }
+     978             : 
+     979             : 
+     980       59573 : bool indexed_lt(std::pair<Grid::index_t, double> const &x, std::pair<Grid::index_t, double> const   &y) {
+     981       59573 :   return x.second < y.second;
+     982             : }
+     983             : 
+     984         273 : double GridBase::findMaximalPathMinimum(const std::vector<double> &source, const std::vector<double> &sink) {
+     985             :   plumed_dbg_assert(source.size() == dimension_);
+     986             :   plumed_dbg_assert(sink.size() == dimension_);
+     987             :   // Start and end indices
+     988         273 :   index_t source_idx = getIndex(source);
+     989         273 :   index_t sink_idx = getIndex(sink);
+     990             :   // Path cost
+     991             :   double maximal_minimum = 0;
+     992             :   // In one dimension, path searching is very easy--either go one way if it's not periodic,
+     993             :   // or go both ways if it is periodic. There's no reason to pay the cost of Dijkstra.
+     994         273 :   if (dimension_ == 1) {
+     995             :     // Do a search from the grid source to grid sink that does not
+     996             :     // cross the grid boundary.
+     997         147 :     double curr_min_bias = getValue(source_idx);
+     998             :     // Either search from a high source to a low sink.
+     999         147 :     if (source_idx > sink_idx) {
+    1000         735 :       for (index_t i = source_idx; i >= sink_idx; i--) {
+    1001         588 :         if (curr_min_bias == 0.0) {
+    1002             :           break;
+    1003             :         }
+    1004         588 :         curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1005             :       }
+    1006             :       // Or search from a low source to a high sink.
+    1007           0 :     } else if (source_idx < sink_idx) {
+    1008           0 :       for (index_t i = source_idx; i <= sink_idx; i++) {
+    1009           0 :         if (curr_min_bias == 0.0) {
+    1010             :           break;
+    1011             :         }
+    1012           0 :         curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1013             :       }
+    1014             :     }
+    1015             :     maximal_minimum = curr_min_bias;
+    1016             :     // If the grid is periodic, also do the search that crosses
+    1017             :     // the grid boundary.
+    1018         147 :     if (pbc_[0]) {
+    1019          42 :       double curr_min_bias = getValue(source_idx);
+    1020             :       // Either go from a high source to the upper boundary and
+    1021             :       // then from the bottom boundary to the sink
+    1022          42 :       if (source_idx > sink_idx) {
+    1023         210 :         for (index_t i = source_idx; i < maxsize_; i++) {
+    1024         168 :           if (curr_min_bias == 0.0) {
+    1025             :             break;
+    1026             :           }
+    1027         168 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1028             :         }
+    1029         210 :         for (index_t i = 0; i <= sink_idx; i++) {
+    1030         168 :           if (curr_min_bias == 0.0) {
+    1031             :             break;
+    1032             :           }
+    1033         168 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1034             :         }
+    1035             :         // Or go from a low source to the bottom boundary and
+    1036             :         // then from the high boundary to the sink
+    1037           0 :       } else if (source_idx < sink_idx) {
+    1038           0 :         for (index_t i = source_idx; i > 0; i--) {
+    1039           0 :           if (curr_min_bias == 0.0) {
+    1040             :             break;
+    1041             :           }
+    1042           0 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1043             :         }
+    1044           0 :         curr_min_bias = fmin(curr_min_bias, getValue(0));
+    1045           0 :         for (index_t i = maxsize_ - 1; i <= sink_idx; i--) {
+    1046           0 :           if (curr_min_bias == 0.0) {
+    1047             :             break;
+    1048             :           }
+    1049           0 :           curr_min_bias = fmin(curr_min_bias, getValue(i));
+    1050             :         }
+    1051             :       }
+    1052             :       // If the boundary crossing paths was more biased, it's
+    1053             :       // minimal bias replaces the non-boundary-crossing path's
+    1054             :       // minimum.
+    1055          42 :       maximal_minimum = fmax(maximal_minimum, curr_min_bias);
+    1056             :     }
+    1057             :     // The one dimensional path search is complete.
+    1058         147 :     return maximal_minimum;
+    1059             :     // In two or more dimensions, path searching isn't trivial and we really
+    1060             :     // do need to use a path search algorithm. Dijkstra is the simplest decent
+    1061             :     // one. Using it we've never found the path search to be performance
+    1062             :     // limiting in any solvated biomolecule test system, but faster options are
+    1063             :     // easy to imagine if they become necessary. NB-In this case, we're actually
+    1064             :     // using a greedy variant of Dijkstra's algorithm where the first possible
+    1065             :     // path to a point always controls the path cost to that point. The structure
+    1066             :     // of the cost function in this case guarantees that the calculated costs will
+    1067             :     // be correct using this variant even though fine details of the paths may not
+    1068             :     // match a normal Dijkstra search.
+    1069         126 :   } else if (dimension_ > 1) {
+    1070             :     // Prepare calculation temporaries for Dijkstra's algorithm.
+    1071             :     // Minimal path costs from source to a given grid point
+    1072         126 :     std::vector<double> mins_from_source = std::vector<double>(maxsize_, -1.0);
+    1073             :     // Heap for tracking available steps, steps are recorded as std::pairs of
+    1074             :     // an index and a value.
+    1075             :     std::vector< std::pair<index_t, double> > next_steps;
+    1076             :     std::pair<index_t, double> curr_indexed_val;
+    1077         126 :     std::make_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1078             :     // The search begins at the source index.
+    1079         252 :     next_steps.push_back(std::pair<index_t, double>(source_idx, getValue(source_idx)));
+    1080         126 :     std::push_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1081             :     // At first no points have been examined and the optimal path has not been found.
+    1082             :     index_t n_examined = 0;
+    1083             :     bool path_not_found = true;
+    1084             :     // Until a path is found,
+    1085             :     while (path_not_found) {
+    1086             :       // Examine the grid point currently most accessible from
+    1087             :       // the set of all previously explored grid points by popping
+    1088             :       // it from the top of the heap.
+    1089        9702 :       std::pop_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1090             :       curr_indexed_val = next_steps.back();
+    1091             :       next_steps.pop_back();
+    1092             :       n_examined++;
+    1093             :       // Check if this point is the sink point, and if so
+    1094             :       // finish the loop.
+    1095        9702 :       if (curr_indexed_val.first == sink_idx) {
+    1096             :         path_not_found = false;
+    1097             :         maximal_minimum = curr_indexed_val.second;
+    1098         126 :         break;
+    1099             :         // Check if this point has reached the worst possible
+    1100             :         // value, and if so stop looking for paths.
+    1101        9576 :       } else if (curr_indexed_val.second == 0.0) {
+    1102             :         maximal_minimum = 0.0;
+    1103             :         break;
+    1104             :       }
+    1105             :       // If the search is not over, add this grid point's neighbors to the
+    1106             :       // possible next points to search for the sink.
+    1107        9576 :       std::vector<index_t> neighs = getNearestNeighbors(curr_indexed_val.first);
+    1108       46246 :       for (unsigned k = 0; k < neighs.size(); k++) {
+    1109       36670 :         index_t i = neighs[k];
+    1110             :         // If the neighbor has not already been added to the list of possible next steps,
+    1111       36670 :         if (mins_from_source[i] == -1.0) {
+    1112             :           // Set the cost to reach it via a path through the current point being examined.
+    1113       12284 :           mins_from_source[i] = fmin(curr_indexed_val.second, getValue(i));
+    1114             :           // Add the neighboring point to the heap of potential next steps.
+    1115       12284 :           next_steps.push_back(std::pair<index_t, double>(i, mins_from_source[i]));
+    1116       12284 :           std::push_heap(next_steps.begin(), next_steps.end(), indexed_lt);
+    1117             :         }
+    1118             :       }
+    1119             :       // Move on to the next best looking step along any of the paths
+    1120             :       // growing from the source.
+    1121             :     }
+    1122             :     // The multidimensional path search is now complete.
+    1123             :     return maximal_minimum;
+    1124             :   }
+    1125             :   return 0.0;
+    1126             : }
+    1127             : 
+    1128             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.h.func-sort-c.html b/coverage/tools/Grid.h.func-sort-c.html new file mode 100644 index 000000000000..cb31ccdea671 --- /dev/null +++ b/coverage/tools/Grid.h.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/Grid.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Grid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8GridBaseD0Ev0
_ZN4PLMD10SparseGridC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERKS9_IS6_SaIS6_EESJ_RKS9_IjSaIjEEbb6
_ZN4PLMD10SparseGridD0Ev6
_ZN4PLMD10SparseGridD2Ev6
_ZN4PLMD4GridC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_128
_ZN4PLMD10BiasWeight16projectOuterLoopERd187
_ZN4PLMD4GridC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERKS9_IS6_SaIS6_EESJ_RKS9_IjSaIjEEbb1321
_ZN4PLMD8GridBaseD2Ev1504
_ZN4PLMD10BiasWeight16projectInnerLoopERdS1_13603
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.h.func.html b/coverage/tools/Grid.h.func.html new file mode 100644 index 000000000000..e7b2e40a717d --- /dev/null +++ b/coverage/tools/Grid.h.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/Grid.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Grid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:8988.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10BiasWeight16projectInnerLoopERdS1_13603
_ZN4PLMD10BiasWeight16projectOuterLoopERd187
_ZN4PLMD10SparseGridC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERKS9_IS6_SaIS6_EESJ_RKS9_IjSaIjEEbb6
_ZN4PLMD10SparseGridD0Ev6
_ZN4PLMD10SparseGridD2Ev6
_ZN4PLMD4GridC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISB_EERKS9_IS6_SaIS6_EESJ_RKS9_IjSaIjEEbb1321
_ZN4PLMD4GridC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS6_SaIS6_EESD_SD_RKS9_IjSaIjEEbbRKS9_IbSaIbEESD_SD_128
_ZN4PLMD8GridBaseD0Ev0
_ZN4PLMD8GridBaseD2Ev1504
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Grid.h.gcov.html b/coverage/tools/Grid.h.gcov.html new file mode 100644 index 000000000000..127bd2395a91 --- /dev/null +++ b/coverage/tools/Grid.h.gcov.html @@ -0,0 +1,432 @@ + + + + + + + + LCOV - plumed test coverage - tools/Grid.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Grid.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:8988.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Grid_h
+      23             : #define __PLUMED_tools_Grid_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <string>
+      27             : #include <map>
+      28             : #include <cmath>
+      29             : #include <memory>
+      30             : #include <cstddef>
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : 
+      35             : // simple function to enable various weighting
+      36             : 
+      37             : class WeightBase {
+      38             : public:
+      39             :   virtual double projectInnerLoop(double &input, double &v)=0;
+      40             :   virtual double projectOuterLoop(double &v)=0;
+      41             :   virtual ~WeightBase() {}
+      42             : };
+      43             : 
+      44           3 : class BiasWeight:public WeightBase {
+      45             : public:
+      46             :   double beta,invbeta;
+      47             :   double shift=0.0;
+      48           3 :   explicit BiasWeight(double v) {beta=v; invbeta=1./beta;}
+      49             :   //double projectInnerLoop(double &input, double &v) override {return  input+exp(beta*v);}
+      50             :   //double projectOuterLoop(double &v) override {return -invbeta*std::log(v);}
+      51       13603 :   double projectInnerLoop(double &input, double &v) override {
+      52       13603 :     auto betav=beta*v;
+      53       13603 :     auto x=betav-shift;
+      54       13603 :     if(x>0) {
+      55        1187 :       shift=betav;
+      56        1187 :       return input*std::exp(-x)+1;
+      57             :     } else {
+      58       12416 :       return input+std::exp(x);
+      59             :     }
+      60             :   }
+      61         187 :   double projectOuterLoop(double &v) override {
+      62         187 :     auto res=-invbeta*(std::log(v)+shift);
+      63         187 :     shift=0.0;
+      64         187 :     return res;
+      65             :   }
+      66             : };
+      67             : 
+      68             : class ProbWeight:public WeightBase {
+      69             : public:
+      70             :   double beta,invbeta;
+      71             :   explicit ProbWeight(double v) {beta=v; invbeta=1./beta;}
+      72             :   double projectInnerLoop(double &input, double &v) override {return  input+v;}
+      73             :   double projectOuterLoop(double &v) override {return -invbeta*std::log(v);}
+      74             : };
+      75             : 
+      76             : 
+      77             : 
+      78             : 
+      79             : 
+      80             : 
+      81             : class Value;
+      82             : class IFile;
+      83             : class OFile;
+      84             : class KernelFunctions;
+      85             : class Communicator;
+      86             : 
+      87             : /// \ingroup TOOLBOX
+      88             : class GridBase
+      89             : {
+      90             : public:
+      91             : // we use a size_t here
+      92             : // should be 8 bytes on all 64-bit machines
+      93             : // and more portable than "unsigned long long"
+      94             :   typedef std::size_t index_t;
+      95             : // to restore old implementation (unsigned) use the following instead:
+      96             : // typedef unsigned index_t;
+      97             : /// Maximum dimension (exaggerated value).
+      98             : /// Can be used to replace local std::vectors with std::arrays (allocated on stack).
+      99             :   static constexpr std::size_t maxdim=64;
+     100             : protected:
+     101             :   std::string funcname;
+     102             :   std::vector<std::string> argnames;
+     103             :   std::vector<std::string> str_min_, str_max_;
+     104             :   std::vector<double> min_,max_,dx_;
+     105             :   std::vector<unsigned> nbin_;
+     106             :   std::vector<bool> pbc_;
+     107             :   index_t maxsize_;
+     108             :   unsigned dimension_;
+     109             :   bool dospline_, usederiv_;
+     110             :   std::string fmt_; // format for output
+     111             : /// get "neighbors" for spline
+     112             :   void getSplineNeighbors(const std::vector<unsigned> & indices, std::vector<index_t>& neigh, unsigned& nneigh )const;
+     113             : // std::vector<index_t> getSplineNeighbors(const std::vector<unsigned> & indices)const;
+     114             : 
+     115             : 
+     116             : public:
+     117             : /// this constructor here is Value-aware
+     118             :   GridBase(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+     119             :            const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
+     120             :            bool usederiv);
+     121             : /// this constructor here is not Value-aware
+     122             :   GridBase(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+     123             :            const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
+     124             :            bool usederiv, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
+     125             :            const std::vector<std::string> &pmax );
+     126             : /// this is the real initializator
+     127             :   void Init(const std::string & funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+     128             :             const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline, bool usederiv,
+     129             :             const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin, const std::vector<std::string> &pmax);
+     130             : /// get lower boundary
+     131             :   std::vector<std::string> getMin() const;
+     132             : /// get upper boundary
+     133             :   std::vector<std::string> getMax() const;
+     134             : /// get bin size
+     135             :   std::vector<double> getDx() const;
+     136             :   double getDx(index_t j) const ;
+     137             : /// get bin volume
+     138             :   double getBinVolume() const;
+     139             : /// get number of bins
+     140             :   std::vector<unsigned> getNbin() const;
+     141             : /// get if periodic
+     142             :   std::vector<bool> getIsPeriodic() const;
+     143             : /// get grid dimension
+     144             :   unsigned getDimension() const;
+     145             : /// get argument names  of this grid
+     146             :   std::vector<std::string> getArgNames() const;
+     147             : /// get if the grid has derivatives
+     148     1986398 :   bool hasDerivatives() const {return usederiv_;}
+     149             : 
+     150             : /// methods to handle grid indices
+     151             :   void getIndices(index_t index, std::vector<unsigned>& rindex) const;
+     152             :   void getIndices(const std::vector<double> & x, std::vector<unsigned>& rindex) const;
+     153             :   std::vector<unsigned> getIndices(index_t index) const;
+     154             :   std::vector<unsigned> getIndices(const std::vector<double> & x) const;
+     155             :   index_t getIndex(const std::vector<unsigned> & indices) const;
+     156             :   index_t getIndex(const std::vector<double> & x) const;
+     157             :   std::vector<double> getPoint(index_t index) const;
+     158             :   std::vector<double> getPoint(const std::vector<unsigned> & indices) const;
+     159             :   std::vector<double> getPoint(const std::vector<double> & x) const;
+     160             : /// faster versions relying on preallocated vectors
+     161             :   void getPoint(index_t index,std::vector<double> & point) const;
+     162             :   void getPoint(const std::vector<unsigned> & indices,std::vector<double> & point) const;
+     163             :   void getPoint(const std::vector<double> & x,std::vector<double> & point) const;
+     164             : 
+     165             : /// get neighbors
+     166             :   std::vector<index_t> getNeighbors(index_t index,const std::vector<unsigned> & neigh) const;
+     167             :   std::vector<index_t> getNeighbors(const std::vector<unsigned> & indices,const std::vector<unsigned> & neigh) const;
+     168             :   std::vector<index_t> getNeighbors(const std::vector<double> & x,const std::vector<unsigned> & neigh) const;
+     169             : /// get nearest neighbors (those separated by exactly one lattice unit)
+     170             :   std::vector<index_t> getNearestNeighbors(const index_t index) const;
+     171             :   std::vector<index_t> getNearestNeighbors(const std::vector<unsigned> &indices) const;
+     172             : 
+     173             : /// write header for grid file
+     174             :   void writeHeader(OFile& file);
+     175             : 
+     176             : /// read grid from file
+     177             :   static std::unique_ptr<GridBase> create(const std::string&,const std::vector<Value*>&,IFile&,bool,bool,bool);
+     178             : /// read grid from file and check boundaries are what is expected from input
+     179             :   static std::unique_ptr<GridBase> create(const std::string&,const std::vector<Value*>&, IFile&,
+     180             :                                           const std::vector<std::string>&,const std::vector<std::string>&,
+     181             :                                           const std::vector<unsigned>&,bool,bool,bool);
+     182             : /// get grid size
+     183             :   virtual index_t getSize() const=0;
+     184             : /// get grid value
+     185             :   virtual double getValue(index_t index) const=0;
+     186             :   double getValue(const std::vector<unsigned> & indices) const;
+     187             :   double getValue(const std::vector<double> & x) const;
+     188             : /// get grid value and derivatives
+     189             :   virtual double getValueAndDerivatives(index_t index, std::vector<double>& der) const=0;
+     190             :   double getValueAndDerivatives(const std::vector<unsigned> & indices, std::vector<double>& der) const;
+     191             :   double getValueAndDerivatives(const std::vector<double> & x, std::vector<double>& der) const;
+     192             : 
+     193             : /// set grid value
+     194             :   virtual void setValue(index_t index, double value)=0;
+     195             :   void setValue(const std::vector<unsigned> & indices, double value);
+     196             : /// set grid value and derivatives
+     197             :   virtual void setValueAndDerivatives(index_t index, double value, std::vector<double>& der)=0;
+     198             :   void setValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
+     199             : /// add to grid value
+     200             :   virtual void addValue(index_t index, double value)=0;
+     201             :   void addValue(const std::vector<unsigned> & indices, double value);
+     202             : /// add to grid value and derivatives
+     203             :   virtual void addValueAndDerivatives(index_t index, double value, std::vector<double>& der)=0;
+     204             :   void addValueAndDerivatives(const std::vector<unsigned> & indices, double value, std::vector<double>& der);
+     205             : /// add a kernel function to the grid
+     206             :   void addKernel( const KernelFunctions& kernel );
+     207             : 
+     208             : /// get minimum value
+     209             :   virtual double getMinValue() const = 0;
+     210             : /// get maximum value
+     211             :   virtual double getMaxValue() const = 0;
+     212             : 
+     213             : /// dump grid on file
+     214             :   virtual void writeToFile(OFile&)=0;
+     215             : /// dump grid to gaussian cube file
+     216             :   void writeCubeFile(OFile&, const double& lunit);
+     217             : 
+     218        3008 :   virtual ~GridBase() {}
+     219             : 
+     220             : /// set output format
+     221         197 :   void setOutputFmt(const std::string & ss) {fmt_=ss;}
+     222             : /// reset output format to the default %14.9f format
+     223             :   void resetToDefaultOutputFmt() {fmt_="%14.9f";}
+     224             : ///
+     225             : /// Find the maximum over paths of the minimum value of the gridded function along the paths
+     226             : /// for all paths of neighboring grid lattice points from a source point to a sink point.
+     227             :   double findMaximalPathMinimum(const std::vector<double> &source, const std::vector<double> &sink);
+     228             : };
+     229             : 
+     230             : class Grid : public GridBase
+     231             : {
+     232             :   std::vector<double> grid_;
+     233             :   std::vector<double> der_;
+     234             :   double contour_location=0.0;
+     235             : public:
+     236        1321 :   Grid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+     237             :        const std::vector<std::string> & gmax,
+     238        1321 :        const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
+     239        1321 :     GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv)
+     240             :   {
+     241        1321 :     grid_.assign(maxsize_,0.0);
+     242        1321 :     if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
+     243        1321 :   }
+     244             : /// this constructor here is not Value-aware
+     245         128 :   Grid(const std::string& funcl, const std::vector<std::string> &names, const std::vector<std::string> & gmin,
+     246             :        const std::vector<std::string> & gmax, const std::vector<unsigned> & nbin, bool dospline,
+     247             :        bool usederiv, const std::vector<bool> &isperiodic, const std::vector<std::string> &pmin,
+     248         128 :        const std::vector<std::string> &pmax ):
+     249         128 :     GridBase(funcl,names,gmin,gmax,nbin,dospline,usederiv,isperiodic,pmin,pmax)
+     250             :   {
+     251         128 :     grid_.assign(maxsize_,0.0);
+     252         128 :     if(usederiv_) der_.assign(maxsize_*dimension_,0.0);
+     253         128 :   }
+     254             :   index_t getSize() const override;
+     255             : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
+     256             :   using GridBase::getValue;
+     257             :   using GridBase::getValueAndDerivatives;
+     258             :   using GridBase::setValue;
+     259             :   using GridBase::setValueAndDerivatives;
+     260             :   using GridBase::addValue;
+     261             :   using GridBase::addValueAndDerivatives;
+     262             : /// get grid value
+     263             :   double getValue(index_t index) const override;
+     264             : /// get grid value and derivatives
+     265             :   double getValueAndDerivatives(index_t index, std::vector<double>& der) const override;
+     266             : 
+     267             : /// set grid value
+     268             :   void setValue(index_t index, double value) override;
+     269             : /// set grid value and derivatives
+     270             :   void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     271             : /// add to grid value
+     272             :   void addValue(index_t index, double value) override;
+     273             : /// add to grid value and derivatives
+     274             :   void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     275             : 
+     276             : /// get minimum value
+     277             :   double getMinValue() const override;
+     278             : /// get maximum value
+     279             :   double getMaxValue() const override;
+     280             : /// Scale all grid values and derivatives by a constant factor
+     281             :   void scaleAllValuesAndDerivatives( const double& scalef );
+     282             : /// Takes the scalef times the logarithm of all grid values and derivatives
+     283             :   void logAllValuesAndDerivatives( const double& scalef );
+     284             : /// dump grid on file
+     285             :   void writeToFile(OFile&) override;
+     286             : 
+     287             : /// Set the minimum value of the grid to zero and translates accordingly
+     288             :   void setMinToZero();
+     289             : /// apply function: takes  pointer to  function that accepts a double and apply
+     290             :   void applyFunctionAllValuesAndDerivatives( double (*func)(double val), double (*funcder)(double valder) );
+     291             : /// Get the difference from the contour
+     292             :   double getDifferenceFromContour(const std::vector<double> & x, std::vector<double>& der) const ;
+     293             : /// Find a set of points on a contour in the function
+     294             :   void findSetOfPointsOnContour(const double& target, const std::vector<bool>& nosearch, unsigned& npoints, std::vector<std::vector<double> >& points );
+     295             : /// Since this method returns a concrete Grid, it should be here and not in GridBase - GB
+     296             : /// project a high dimensional grid onto a low dimensional one: this should be changed at some time
+     297             : /// to enable many types of weighting
+     298             :   Grid project( const std::vector<std::string> & proj, WeightBase *ptr2obj  );
+     299             :   void projectOnLowDimension(double &val, std::vector<int> &varHigh, WeightBase* ptr2obj );
+     300             :   void mpiSumValuesAndDerivatives( Communicator& comm );
+     301             : /// Integrate the function calculated on the grid
+     302             :   double integrate( std::vector<unsigned>& npoints );
+     303             :   void clear();
+     304             : };
+     305             : 
+     306             : 
+     307             : class SparseGrid : public GridBase
+     308             : {
+     309             : 
+     310             :   std::map<index_t,double> map_;
+     311             :   std::map< index_t,std::vector<double> > der_;
+     312             : 
+     313             : public:
+     314           6 :   SparseGrid(const std::string& funcl, const std::vector<Value*> & args, const std::vector<std::string> & gmin,
+     315             :              const std::vector<std::string> & gmax,
+     316           6 :              const std::vector<unsigned> & nbin, bool dospline, bool usederiv):
+     317           6 :     GridBase(funcl,args,gmin,gmax,nbin,dospline,usederiv) {}
+     318             : 
+     319             :   index_t getSize() const override;
+     320             :   index_t getMaxSize() const;
+     321             : 
+     322             : /// this is to access to Grid:: version of these methods (allowing overloading of virtual methods)
+     323             :   using GridBase::getValue;
+     324             :   using GridBase::getValueAndDerivatives;
+     325             :   using GridBase::setValue;
+     326             :   using GridBase::setValueAndDerivatives;
+     327             :   using GridBase::addValue;
+     328             :   using GridBase::addValueAndDerivatives;
+     329             : 
+     330             : /// get grid value
+     331             :   double getValue(index_t index) const override;
+     332             : /// get grid value and derivatives
+     333             :   double getValueAndDerivatives(index_t index, std::vector<double>& der) const override;
+     334             : 
+     335             : /// set grid value
+     336             :   void setValue(index_t index, double value) override;
+     337             : /// set grid value and derivatives
+     338             :   void setValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     339             : /// add to grid value
+     340             :   void addValue(index_t index, double value) override;
+     341             : /// add to grid value and derivatives
+     342             :   void addValueAndDerivatives(index_t index, double value, std::vector<double>& der) override;
+     343             : 
+     344             : /// get minimum value
+     345             :   double getMinValue() const override;
+     346             : /// get maximum value
+     347             :   double getMaxValue() const override;
+     348             : /// dump grid on file
+     349             :   void writeToFile(OFile&) override;
+     350             : 
+     351          18 :   virtual ~SparseGrid() {}
+     352             : };
+     353             : }
+     354             : 
+     355             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.cpp.func-sort-c.html b/coverage/tools/HistogramBead.cpp.func-sort-c.html new file mode 100644 index 000000000000..bd97483d4a72 --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9311878.8 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead12generateBinsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS6_SaIS6_EE11
_ZN4PLMD13HistogramBead3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_68
_ZNK4PLMD13HistogramBead11descriptionB5cxx11Ev68
_ZN4PLMD13HistogramBead16registerKeywordsERNS_8KeywordsE76
_ZNK4PLMD13HistogramBead16lboundDerivativeERKd4860
_ZNK4PLMD13HistogramBead16uboundDerivativeERKd4860
_ZN4PLMD13HistogramBead13setKernelTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE79236
_ZN4PLMD13HistogramBeadC2Ev79304
_ZNK4PLMD13HistogramBead19calculateWithCutoffEdRd132418
_ZNK4PLMD13HistogramBead9calculateEdRd160612
_ZN4PLMD13HistogramBead3setEddd573574
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.cpp.func.html b/coverage/tools/HistogramBead.cpp.func.html new file mode 100644 index 000000000000..2009c650f8a3 --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9311878.8 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead12generateBinsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS6_SaIS6_EE11
_ZN4PLMD13HistogramBead13setKernelTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE79236
_ZN4PLMD13HistogramBead16registerKeywordsERNS_8KeywordsE76
_ZN4PLMD13HistogramBead3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_68
_ZN4PLMD13HistogramBead3setEddd573574
_ZN4PLMD13HistogramBeadC2Ev79304
_ZNK4PLMD13HistogramBead11descriptionB5cxx11Ev68
_ZNK4PLMD13HistogramBead16lboundDerivativeERKd4860
_ZNK4PLMD13HistogramBead16uboundDerivativeERKd4860
_ZNK4PLMD13HistogramBead19calculateWithCutoffEdRd132418
_ZNK4PLMD13HistogramBead9calculateEdRd160612
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.cpp.gcov.html b/coverage/tools/HistogramBead.cpp.gcov.html new file mode 100644 index 000000000000..f08c6c2fa2dc --- /dev/null +++ b/coverage/tools/HistogramBead.cpp.gcov.html @@ -0,0 +1,342 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:9311878.8 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "HistogramBead.h"
+      23             : #include <vector>
+      24             : #include <limits>
+      25             : #include "Tools.h"
+      26             : #include "Keywords.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : //+PLUMEDOC INTERNAL histogrambead
+      31             : /*
+      32             : A function that can be used to calculate whether quantities are between fixed upper and lower bounds.
+      33             : 
+      34             : If we have multiple instances of a variable we can estimate the probability density function
+      35             : for that variable using a process called kernel density estimation:
+      36             : 
+      37             : \f[
+      38             : P(s) = \sum_i K\left( \frac{s - s_i}{w} \right)
+      39             : \f]
+      40             : 
+      41             : In this equation \f$K\f$ is a symmetric function that must integrate to one that is often
+      42             : called a kernel function and \f$w\f$ is a smearing parameter.  From a probability density function calculated using
+      43             : kernel density estimation we can calculate the number/fraction of values between an upper and lower
+      44             : bound using:
+      45             : 
+      46             : \f[
+      47             : w(s) = \int_a^b \sum_i K\left( \frac{s - s_i}{w} \right)
+      48             : \f]
+      49             : 
+      50             : All the input to calculate a quantity like \f$w(s)\f$ is generally provided through a single
+      51             : keyword that will have the following form:
+      52             : 
+      53             : KEYWORD={TYPE UPPER=\f$a\f$ LOWER=\f$b\f$ SMEAR=\f$\frac{w}{b-a}\f$}
+      54             : 
+      55             : This will calculate the number of values between \f$a\f$ and \f$b\f$.  To calculate
+      56             : the fraction of values you add the word NORM to the input specification.  If the
+      57             : function keyword SMEAR is not present \f$w\f$ is set equal to \f$0.5(b-a)\f$. Finally,
+      58             : type should specify one of the kernel types that is present in plumed. These are listed
+      59             : in the table below:
+      60             : 
+      61             : <table align=center frame=void width=95%% cellpadding=5%%>
+      62             : <tr>
+      63             : <td> TYPE </td> <td> FUNCTION </td>
+      64             : </tr> <tr>
+      65             : <td> GAUSSIAN </td> <td> \f$\frac{1}{\sqrt{2\pi}w} \exp\left( -\frac{(s-s_i)^2}{2w^2} \right)\f$ </td>
+      66             : </tr> <tr>
+      67             : <td> TRIANGULAR </td> <td> \f$ \frac{1}{2w} \left( 1. - \left| \frac{s-s_i}{w} \right| \right) \quad \frac{s-s_i}{w}<1 \f$ </td>
+      68             : </tr>
+      69             : </table>
+      70             : 
+      71             : Some keywords can also be used to calculate a discrete version of the histogram.  That
+      72             : is to say the number of values between \f$a\f$ and \f$b\f$, the number of values between
+      73             : \f$b\f$ and \f$c\f$ and so on.  A keyword that specifies this sort of calculation would look
+      74             : something like
+      75             : 
+      76             : KEYWORD={TYPE UPPER=\f$a\f$ LOWER=\f$b\f$ NBINS=\f$n\f$ SMEAR=\f$\frac{w}{n(b-a)}\f$}
+      77             : 
+      78             : This specification would calculate the following vector of quantities:
+      79             : 
+      80             : \f[
+      81             : w_j(s) = \int_{a + \frac{j-1}{n}(b-a)}^{a + \frac{j}{n}(b-a)} \sum_i K\left( \frac{s - s_i}{w} \right)
+      82             : \f]
+      83             : 
+      84             : */
+      85             : //+ENDPLUMEDOC
+      86             : 
+      87          76 : void HistogramBead::registerKeywords( Keywords& keys ) {
+      88         152 :   keys.add("compulsory","LOWER","the lower boundary for this particular bin");
+      89         152 :   keys.add("compulsory","UPPER","the upper boundary for this particular bin");
+      90         152 :   keys.add("compulsory","SMEAR","0.5","the amount to smear the Gaussian for each value in the distribution");
+      91          76 : }
+      92             : 
+      93       79304 : HistogramBead::HistogramBead():
+      94       79304 :   init(false),
+      95       79304 :   lowb(0.0),
+      96       79304 :   highb(0.0),
+      97       79304 :   width(0.0),
+      98       79304 :   cutoff(std::numeric_limits<double>::max()),
+      99       79304 :   type(gaussian),
+     100       79304 :   periodicity(unset),
+     101       79304 :   min(0.0),
+     102       79304 :   max(0.0),
+     103       79304 :   max_minus_min(0.0),
+     104       79304 :   inv_max_minus_min(0.0)
+     105             : {
+     106       79304 : }
+     107             : 
+     108          68 : std::string HistogramBead::description() const {
+     109          68 :   std::ostringstream ostr;
+     110          68 :   ostr<<"between "<<lowb<<" and "<<highb<<" width of gaussian window equals "<<width;
+     111          68 :   return ostr.str();
+     112          68 : }
+     113             : 
+     114          11 : void HistogramBead::generateBins( const std::string& params, std::vector<std::string>& bins ) {
+     115          11 :   std::vector<std::string> data=Tools::getWords(params);
+     116          11 :   plumed_massert(data.size()>=1,"There is no input for this keyword");
+     117             : 
+     118          11 :   std::string name=data[0];
+     119             : 
+     120          11 :   unsigned nbins; std::vector<double> range(2); std::string smear;
+     121          11 :   bool found_nb=Tools::parse(data,"NBINS",nbins);
+     122          11 :   plumed_massert(found_nb,"Number of bins in histogram not found");
+     123          11 :   bool found_r=Tools::parse(data,"LOWER",range[0]);
+     124          11 :   plumed_massert(found_r,"Lower bound for histogram not specified");
+     125          11 :   found_r=Tools::parse(data,"UPPER",range[1]);
+     126          11 :   plumed_massert(found_r,"Upper bound for histogram not specified");
+     127          11 :   plumed_massert(range[0]<range[1],"Range specification is dubious");
+     128          11 :   bool found_b=Tools::parse(data,"SMEAR",smear);
+     129          11 :   if(!found_b) { Tools::convert(0.5,smear); }
+     130             : 
+     131          11 :   std::string lb,ub; double delr = ( range[1]-range[0] ) / static_cast<double>( nbins );
+     132          43 :   for(unsigned i=0; i<nbins; ++i) {
+     133          32 :     Tools::convert( range[0]+i*delr, lb );
+     134          32 :     Tools::convert( range[0]+(i+1)*delr, ub );
+     135          64 :     bins.push_back( name + " " +  "LOWER=" + lb + " " + "UPPER=" + ub + " " + "SMEAR=" + smear );
+     136             :   }
+     137          11 :   plumed_assert(bins.size()==nbins);
+     138          11 : }
+     139             : 
+     140          68 : void HistogramBead::set( const std::string& params, std::string& errormsg ) {
+     141          68 :   std::vector<std::string> data=Tools::getWords(params);
+     142          68 :   if(data.size()<1) {
+     143             :     errormsg="No input has been specified";
+     144             :     return;
+     145             :   }
+     146             : 
+     147          68 :   std::string name=data[0]; const double DP2CUTOFF=6.25;
+     148          68 :   if(name=="GAUSSIAN") { type=gaussian; cutoff=std::sqrt(2.0*DP2CUTOFF); }
+     149           0 :   else if(name=="TRIANGULAR") { type=triangular; cutoff=1.; }
+     150           0 :   else plumed_merror("cannot understand kernel type " + name );
+     151             : 
+     152             :   double smear;
+     153          68 :   bool found_r=Tools::parse(data,"LOWER",lowb);
+     154          68 :   if( !found_r ) errormsg="Lower bound has not been specified use LOWER";
+     155          68 :   found_r=Tools::parse(data,"UPPER",highb);
+     156          68 :   if( !found_r ) errormsg="Upper bound has not been specified use UPPER";
+     157          68 :   if( lowb>=highb ) errormsg="Lower bound is higher than upper bound";
+     158             : 
+     159          68 :   smear=0.5; Tools::parse(data,"SMEAR",smear);
+     160          68 :   width=smear*(highb-lowb); init=true;
+     161          68 : }
+     162             : 
+     163      573574 : void HistogramBead::set( double l, double h, double w) {
+     164      573574 :   init=true; lowb=l; highb=h; width=w;
+     165             :   const double DP2CUTOFF=6.25;
+     166      573574 :   if( type==gaussian ) cutoff=std::sqrt(2.0*DP2CUTOFF);
+     167      425920 :   else if( type==triangular ) cutoff=1.;
+     168           0 :   else plumed_error();
+     169      573574 : }
+     170             : 
+     171       79236 : void HistogramBead::setKernelType( const std::string& ktype ) {
+     172       79236 :   if(ktype=="gaussian") type=gaussian;
+     173        9622 :   else if(ktype=="triangular") type=triangular;
+     174           0 :   else plumed_merror("cannot understand kernel type " + ktype );
+     175       79236 : }
+     176             : 
+     177      160612 : double HistogramBead::calculate( double x, double& df ) const {
+     178             :   plumed_dbg_assert(init && periodicity!=unset );
+     179             :   double lowB, upperB, f;
+     180      160612 :   if( type==gaussian ) {
+     181      160612 :     lowB = difference( x, lowb ) / ( std::sqrt(2.0) * width );
+     182      160612 :     upperB = difference( x, highb ) / ( std::sqrt(2.0) * width );
+     183      160612 :     df = ( exp( -lowB*lowB ) - exp( -upperB*upperB ) ) / ( std::sqrt(2*pi)*width );
+     184      160612 :     f = 0.5*( erf( upperB ) - erf( lowB ) );
+     185           0 :   } else if( type==triangular ) {
+     186           0 :     lowB = ( difference( x, lowb ) / width );
+     187           0 :     upperB = ( difference( x, highb ) / width );
+     188           0 :     df=0;
+     189           0 :     if( std::fabs(lowB)<1. ) df = (1 - std::fabs(lowB)) / width;
+     190           0 :     if( std::fabs(upperB)<1. ) df -= (1 - std::fabs(upperB)) / width;
+     191           0 :     if (upperB<=-1. || lowB >=1.) {
+     192             :       f=0.;
+     193             :     } else {
+     194             :       double ia, ib;
+     195           0 :       if( lowB>-1.0 ) { ia=lowB; } else { ia=-1.0; }
+     196           0 :       if( upperB<1.0 ) { ib=upperB; } else { ib=1.0; }
+     197           0 :       f = (ib*(2.-std::fabs(ib))-ia*(2.-std::fabs(ia)))*0.5;
+     198             :     }
+     199             :   } else {
+     200           0 :     plumed_merror("function type does not exist");
+     201             :   }
+     202      160612 :   return f;
+     203             : }
+     204             : 
+     205      132418 : double HistogramBead::calculateWithCutoff( double x, double& df ) const {
+     206             :   plumed_dbg_assert(init && periodicity!=unset );
+     207             : 
+     208             :   double lowB, upperB, f;
+     209      132418 :   lowB = difference( x, lowb ) / width ; upperB = difference( x, highb ) / width;
+     210      132418 :   if( upperB<=-cutoff || lowB>=cutoff ) { df=0; return 0; }
+     211             : 
+     212      132418 :   if( type==gaussian ) {
+     213           0 :     lowB /= std::sqrt(2.0); upperB /= std::sqrt(2.0);
+     214           0 :     df = ( exp( -lowB*lowB ) - exp( -upperB*upperB ) ) / ( std::sqrt(2*pi)*width );
+     215           0 :     f = 0.5*( erf( upperB ) - erf( lowB ) );
+     216      132418 :   } else if( type==triangular ) {
+     217      132418 :     df=0;
+     218      132418 :     if( std::fabs(lowB)<1. ) df = (1 - std::fabs(lowB)) / width;
+     219      132418 :     if( std::fabs(upperB)<1. ) df -= (1 - std::fabs(upperB)) / width;
+     220      132418 :     if (upperB<=-1. || lowB >=1.) {
+     221             :       f=0.;
+     222             :     } else {
+     223             :       double ia, ib;
+     224      132418 :       if( lowB>-1.0 ) { ia=lowB; } else { ia=-1.0; }
+     225      132418 :       if( upperB<1.0 ) { ib=upperB; } else { ib=1.0; }
+     226      132418 :       f = (ib*(2.-std::fabs(ib))-ia*(2.-std::fabs(ia)))*0.5;
+     227             :     }
+     228             :   } else {
+     229           0 :     plumed_merror("function type does not exist");
+     230             :   }
+     231             :   return f;
+     232             : }
+     233             : 
+     234        4860 : double HistogramBead::lboundDerivative( const double& x ) const {
+     235        4860 :   if( type==gaussian ) {
+     236        4860 :     double lowB = difference( x, lowb ) / ( std::sqrt(2.0) * width );
+     237        4860 :     return exp( -lowB*lowB ) / ( std::sqrt(2*pi)*width );
+     238           0 :   } else if ( type==triangular ) {
+     239           0 :     plumed_error();
+     240             : //      lowB = fabs( difference( x, lowb ) / width );
+     241             : //      if( lowB<1 ) return ( 1 - (lowB) ) / 2*width;
+     242             : //      else return 0;
+     243             :   } else {
+     244           0 :     plumed_merror("function type does not exist");
+     245             :   }
+     246             :   return 0;
+     247             : }
+     248             : 
+     249        4860 : double HistogramBead::uboundDerivative( const double& x ) const {
+     250             :   plumed_dbg_assert(init && periodicity!=unset );
+     251        4860 :   if( type==gaussian ) {
+     252        4860 :     double upperB = difference( x, highb ) / ( std::sqrt(2.0) * width );
+     253        4860 :     return exp( -upperB*upperB ) / ( std::sqrt(2*pi)*width );
+     254           0 :   } else if ( type==triangular ) {
+     255           0 :     plumed_error();
+     256             : //      upperB = fabs( difference( x, highb ) / width );
+     257             : //      if( upperB<1 ) return ( 1 - (upperB) ) / 2*width;
+     258             : //      else return 0;
+     259             :   } else {
+     260           0 :     plumed_merror("function type does not exist");
+     261             :   }
+     262             :   return 0;
+     263             : }
+     264             : 
+     265             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.h.func-sort-c.html b/coverage/tools/HistogramBead.h.func-sort-c.html new file mode 100644 index 000000000000..86ad7b1495d2 --- /dev/null +++ b/coverage/tools/HistogramBead.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead10isPeriodicERKdS2_1
_ZNK4PLMD13HistogramBead10differenceERKdS2_595780
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.h.func.html b/coverage/tools/HistogramBead.h.func.html new file mode 100644 index 000000000000..4efcb1dfd413 --- /dev/null +++ b/coverage/tools/HistogramBead.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13HistogramBead10isPeriodicERKdS2_1
_ZNK4PLMD13HistogramBead10differenceERKdS2_595780
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/HistogramBead.h.gcov.html b/coverage/tools/HistogramBead.h.gcov.html new file mode 100644 index 000000000000..a94d46e11a84 --- /dev/null +++ b/coverage/tools/HistogramBead.h.gcov.html @@ -0,0 +1,191 @@ + + + + + + + + LCOV - plumed test coverage - tools/HistogramBead.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - HistogramBead.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:171894.4 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_HistogramBead_h
+      23             : #define __PLUMED_tools_HistogramBead_h
+      24             : 
+      25             : #include <string>
+      26             : #include <vector>
+      27             : #include "Exception.h"
+      28             : #include "Tools.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : class Keywords;
+      33             : class Log;
+      34             : 
+      35             : /**
+      36             : \ingroup TOOLBOX
+      37             : A class for calculating whether or not values are within a given range using : \f$ \sum_i \int_a^b G( s_i, \sigma*(b-a) ) \f$
+      38             : */
+      39             : 
+      40             : class HistogramBead {
+      41             : private:
+      42             :   bool init;
+      43             :   double lowb;
+      44             :   double highb;
+      45             :   double width;
+      46             :   double cutoff;
+      47             :   enum {gaussian,triangular} type;
+      48             :   enum {unset,periodic,notperiodic} periodicity;
+      49             :   double min, max, max_minus_min, inv_max_minus_min;
+      50             :   double difference( const double& d1, const double& d2 ) const ;
+      51             : public:
+      52             :   static void registerKeywords( Keywords& keys );
+      53             :   static void generateBins( const std::string& params, std::vector<std::string>& bins );
+      54             :   HistogramBead();
+      55             :   std::string description() const ;
+      56             :   bool hasBeenSet() const;
+      57             :   void isNotPeriodic();
+      58             :   void isPeriodic( const double& mlow, const double& mhigh );
+      59             :   void setKernelType( const std::string& ktype );
+      60             :   void set(const std::string& params, std::string& errormsg);
+      61             :   void set(double l, double h, double w);
+      62             :   double calculate(double x, double&df) const;
+      63             :   double calculateWithCutoff( double x, double& df ) const;
+      64             :   double lboundDerivative( const double& x ) const;
+      65             :   double uboundDerivative( const double& x ) const;
+      66             :   double getlowb() const ;
+      67             :   double getbigb() const ;
+      68             :   double getCutoff() const ;
+      69             : };
+      70             : 
+      71             : inline
+      72             : bool HistogramBead::hasBeenSet() const {
+      73             :   return init;
+      74             : }
+      75             : 
+      76             : inline
+      77             : void HistogramBead::isNotPeriodic() {
+      78       79303 :   periodicity=notperiodic;
+      79          67 : }
+      80             : 
+      81             : inline
+      82           1 : void HistogramBead::isPeriodic( const double& mlow, const double& mhigh ) {
+      83           1 :   periodicity=periodic; min=mlow; max=mhigh;
+      84           1 :   max_minus_min=max-min;
+      85           1 :   plumed_massert(max_minus_min>0, "your function has a very strange domain?");
+      86           1 :   inv_max_minus_min=1.0/max_minus_min;
+      87           1 : }
+      88             : 
+      89             : inline
+      90             : double HistogramBead::getlowb() const { return lowb; }
+      91             : 
+      92             : inline
+      93             : double HistogramBead::getbigb() const { return highb; }
+      94             : 
+      95             : inline
+      96    82228271 : double HistogramBead::getCutoff() const { return cutoff*width; }
+      97             : 
+      98             : inline
+      99      595780 : double HistogramBead::difference( const double& d1, const double& d2 ) const {
+     100      595780 :   if(periodicity==notperiodic) {
+     101      595760 :     return d2-d1;
+     102          20 :   } else if(periodicity==periodic) {
+     103             :     // Make sure the point is in the target range
+     104          20 :     double newx=d1*inv_max_minus_min;
+     105          20 :     newx=Tools::pbc(newx);
+     106          20 :     newx*=max_minus_min;
+     107          20 :     return d2-newx;
+     108           0 :   } else plumed_merror("periodicty was not set");
+     109             :   return 0;
+     110             : }
+     111             : 
+     112             : }
+     113             : 
+     114             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.cpp.func-sort-c.html b/coverage/tools/IFile.cpp.func-sort-c.html new file mode 100644 index 000000000000..3c9d38dbbc9e --- /dev/null +++ b/coverage/tools/IFile.cpp.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-02-22 21:58:45Functions:222588.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx0
_ZN4PLMD5IFileC2Ev0
_ZN4PLMD5IFileD2Ev0
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy14
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj17
_ZN4PLMD5IFileD0Ev348
_ZN4PLMD5IFile10allowNoEOLEv888
_ZN4PLMD5IFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1328
_ZN4PLMD5IFileC1Ev1591
_ZN4PLMD5IFileD1Ev1591
_ZN4PLMD5IFile18allowIgnoredFieldsEv5778
_ZN4PLMD5IFile5resetEb6136
_ZN4PLMD5IFile9scanFieldEPNS_5ValueE1102398
_ZN4PLMD5IFile10FieldExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1140091
_ZN4PLMD5IFile13scanFieldListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1140188
_ZN4PLMD5IFile9scanFieldEv1319607
_ZN4PLMD5IFile12advanceFieldEv1326015
_ZN4PLMD5IFile7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1472259
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2213283
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd7011806
_ZNK4PLMD5IFile9findFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15852529
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_15858864
_ZN4PLMD5IFile6llreadEPcm100069459
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.cpp.func.html b/coverage/tools/IFile.cpp.func.html new file mode 100644 index 000000000000..f750693ce575 --- /dev/null +++ b/coverage/tools/IFile.cpp.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-02-22 21:58:45Functions:222588.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5IFile10FieldExistERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1140091
_ZN4PLMD5IFile10allowNoEOLEv888
_ZN4PLMD5IFile12advanceFieldEv1326015
_ZN4PLMD5IFile13scanFieldListERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1140188
_ZN4PLMD5IFile18allowIgnoredFieldsEv5778
_ZN4PLMD5IFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1328
_ZN4PLMD5IFile5resetEb6136
_ZN4PLMD5IFile6llreadEPcm100069459
_ZN4PLMD5IFile7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1472259
_ZN4PLMD5IFile9scanFieldEPNS_5ValueE1102398
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_15858864
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd7011806
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2213283
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj17
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm1
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx0
_ZN4PLMD5IFile9scanFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy14
_ZN4PLMD5IFile9scanFieldEv1319607
_ZN4PLMD5IFileC1Ev1591
_ZN4PLMD5IFileC2Ev0
_ZN4PLMD5IFileD0Ev348
_ZN4PLMD5IFileD1Ev1591
_ZN4PLMD5IFileD2Ev0
_ZNK4PLMD5IFile9findFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15852529
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.cpp.gcov.html b/coverage/tools/IFile.cpp.gcov.html new file mode 100644 index 000000000000..99a6136d1bd4 --- /dev/null +++ b/coverage/tools/IFile.cpp.gcov.html @@ -0,0 +1,372 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515196.0 %
Date:2024-02-22 21:58:45Functions:222588.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "IFile.h"
+      23             : #include "Exception.h"
+      24             : #include "core/Action.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Value.h"
+      27             : #include "Communicator.h"
+      28             : #include "Tools.h"
+      29             : #include <cstdarg>
+      30             : #include <cstring>
+      31             : #include <cmath>
+      32             : 
+      33             : #include <iostream>
+      34             : #include <string>
+      35             : #ifdef __PLUMED_HAS_ZLIB
+      36             : #include <zlib.h>
+      37             : #endif
+      38             : 
+      39             : namespace PLMD {
+      40             : 
+      41   100069459 : size_t IFile::llread(char*ptr,size_t s) {
+      42   100069459 :   plumed_assert(fp);
+      43             :   size_t r;
+      44   100069459 :   if(gzfp) {
+      45             : #ifdef __PLUMED_HAS_ZLIB
+      46        3522 :     int rr=gzread(gzFile(gzfp),ptr,s);
+      47        3522 :     if(rr==0)   eof=true;
+      48        3522 :     if(rr<0)    err=true;
+      49        3522 :     r=rr;
+      50             : #else
+      51             :     plumed_merror("file " + getPath() + ": trying to use a gz file without zlib being linked");
+      52             : #endif
+      53             :   } else {
+      54             :     r=std::fread(ptr,1,s,fp);
+      55   100065937 :     if(std::feof(fp))   eof=true;
+      56   100065937 :     if(std::ferror(fp)) err=true;
+      57             :   }
+      58   100069459 :   return r;
+      59             : }
+      60             : 
+      61     1326015 : IFile& IFile::advanceField() {
+      62     1326015 :   plumed_assert(!inMiddleOfField);
+      63             :   std::string line;
+      64             :   bool done=false;
+      65     2653843 :   while(!done) {
+      66     1334239 :     getline(line);
+      67             : // using explicit conversion not to confuse cppcheck 1.86
+      68     1334239 :     if(!bool(*this)) {return *this;}
+      69     1327828 :     std::vector<std::string> words=Tools::getWords(line);
+      70     2655417 :     if(words.size()>=2 && words[0]=="#!" && words[1]=="FIELDS") {
+      71         713 :       fields.clear();
+      72        4730 :       for(unsigned i=2; i<words.size(); i++) {
+      73             :         Field field;
+      74             :         field.name=words[i];
+      75        4017 :         fields.push_back(field);
+      76             :       }
+      77     1348799 :     } else if(words.size()==4 && words[0]=="#!" && words[1]=="SET") {
+      78             :       Field field;
+      79             :       field.name=words[2];
+      80             :       field.value=words[3];
+      81        3256 :       field.constant=true;
+      82        3256 :       fields.push_back(field);
+      83             :     } else {
+      84             :       unsigned nf=0;
+      85    17104080 :       for(unsigned i=0; i<fields.size(); i++) if(!fields[i].constant) nf++;
+      86     1323859 :       Tools::trimComments(line);
+      87     2647718 :       words=Tools::getWords(line);
+      88     1323859 :       if( words.size()==nf ) {
+      89             :         unsigned j=0;
+      90    17049468 :         for(unsigned i=0; i<fields.size(); i++) {
+      91    15729864 :           if(fields[i].constant) continue;
+      92     6862629 :           fields[i].value=words[j];
+      93     6862629 :           fields[i].read=false;
+      94     6862629 :           j++;
+      95             :         }
+      96             :         done=true;
+      97        4255 :       } else if( !words.empty() ) {
+      98           0 :         plumed_merror("file " + getPath() + ": mismatch between number of fields in file and expected number\n this is the faulty line:\n"+line);
+      99             :       }
+     100             :     }
+     101     1327828 :   }
+     102     1319604 :   inMiddleOfField=true;
+     103     1319604 :   return *this;
+     104             : }
+     105             : 
+     106        1328 : IFile& IFile::open(const std::string&path) {
+     107        1328 :   plumed_massert(!cloned,"file "+path+" appears to be cloned");
+     108        1328 :   eof=false;
+     109        1328 :   err=false;
+     110        1328 :   fp=NULL;
+     111        1328 :   gzfp=NULL;
+     112        1328 :   bool do_exist=FileExist(path);
+     113        1330 :   plumed_massert(do_exist,"file " + path + " cannot be found");
+     114        1327 :   fp=std::fopen(const_cast<char*>(this->path.c_str()),"r");
+     115        2654 :   if(Tools::extension(this->path)=="gz") {
+     116             : #ifdef __PLUMED_HAS_ZLIB
+     117           6 :     gzfp=(void*)gzopen(const_cast<char*>(this->path.c_str()),"r");
+     118             : #else
+     119             :     plumed_merror("file " + getPath() + ": trying to use a gz file without zlib being linked");
+     120             : #endif
+     121             :   }
+     122        1327 :   if(plumed) plumed->insertFile(*this);
+     123        1327 :   return *this;
+     124             : }
+     125             : 
+     126     1140188 : IFile& IFile::scanFieldList(std::vector<std::string>&s) {
+     127     1140188 :   if(!inMiddleOfField) advanceField();
+     128             : // using explicit conversion not to confuse cppcheck 1.86
+     129     1140188 :   if(!bool(*this)) return *this;
+     130             :   s.clear();
+     131     9211249 :   for(unsigned i=0; i<fields.size(); i++)
+     132     8071137 :     s.push_back(fields[i].name);
+     133             :   return *this;
+     134             : }
+     135             : 
+     136     1140091 : bool IFile::FieldExist(const std::string& s) {
+     137             :   std::vector<std::string> slist;
+     138     1140091 :   scanFieldList(slist);
+     139     1140091 :   int mycount = (int) std::count(slist.begin(), slist.end(), s);
+     140     1140091 :   if(mycount>0) return true;
+     141     1116129 :   else return false;
+     142     1140091 : }
+     143             : 
+     144    15858864 : IFile& IFile::scanField(const std::string&name,std::string&str) {
+     145    15858864 :   if(!inMiddleOfField) advanceField();
+     146             : // using explicit conversion not to confuse cppcheck 1.86
+     147    15858864 :   if(!bool(*this)) return *this;
+     148    15852529 :   unsigned i=findField(name);
+     149    15852529 :   str=fields[i].value;
+     150    15852529 :   fields[i].read=true;
+     151    15852529 :   return *this;
+     152             : }
+     153             : 
+     154     7011806 : IFile& IFile::scanField(const std::string&name,double &x) {
+     155             :   std::string str;
+     156     7011806 :   scanField(name,str);
+     157     7011806 :   if(*this) Tools::convert(str,x);
+     158     7011806 :   return *this;
+     159             : }
+     160             : 
+     161     2213283 : IFile& IFile::scanField(const std::string&name,int &x) {
+     162             :   std::string str;
+     163     2213283 :   scanField(name,str);
+     164     2213283 :   if(*this) Tools::convert(str,x);
+     165     2213283 :   return *this;
+     166             : }
+     167             : 
+     168           1 : IFile& IFile::scanField(const std::string&name,long int &x) {
+     169             :   std::string str;
+     170           1 :   scanField(name,str);
+     171           1 :   if(*this) Tools::convert(str,x);
+     172           1 :   return *this;
+     173             : }
+     174             : 
+     175           0 : IFile& IFile::scanField(const std::string&name,long long int &x) {
+     176             :   std::string str;
+     177           0 :   scanField(name,str);
+     178           0 :   if(*this) Tools::convert(str,x);
+     179           0 :   return *this;
+     180             : }
+     181             : 
+     182          17 : IFile& IFile::scanField(const std::string&name,unsigned &x) {
+     183             :   std::string str;
+     184          17 :   scanField(name,str);
+     185          17 :   if(*this) Tools::convert(str,x);
+     186          17 :   return *this;
+     187             : }
+     188             : 
+     189           1 : IFile& IFile::scanField(const std::string&name,long unsigned &x) {
+     190             :   std::string str;
+     191           1 :   scanField(name,str);
+     192           1 :   if(*this) Tools::convert(str,x);
+     193           1 :   return *this;
+     194             : }
+     195             : 
+     196          14 : IFile& IFile::scanField(const std::string&name,long long unsigned &x) {
+     197             :   std::string str;
+     198          14 :   scanField(name,str);
+     199          14 :   if(*this) Tools::convert(str,x);
+     200          14 :   return *this;
+     201             : }
+     202             : 
+     203     1102398 : IFile& IFile::scanField(Value* val) {
+     204     1102398 :   double ff=std::numeric_limits<double>::quiet_NaN(); // this is to be sure a NaN value is replaced upon failure
+     205     1102398 :   scanField(  val->getName(), ff );
+     206     1102398 :   val->set( ff );
+     207     2204796 :   if( FieldExist("min_" + val->getName() ) ) {
+     208             :     std::string min, max;
+     209        3309 :     scanField("min_" + val->getName(), min );
+     210        3309 :     scanField("max_" + val->getName(), max );
+     211        3309 :     val->setDomain( min, max );
+     212             :   } else {
+     213     1099089 :     val->setNotPeriodic();
+     214             :   }
+     215     1102398 :   return *this;
+     216             : }
+     217             : 
+     218     1319607 : IFile& IFile::scanField() {
+     219     1319607 :   if(!ignoreFields) {
+     220    15347112 :     for(unsigned i=0; i<fields.size(); i++) {
+     221    14242078 :       plumed_massert(fields[i].read,"field "+fields[i].name+" was not read: all the fields need to be read otherwise you could miss important infos" );
+     222             :     }
+     223             :   }
+     224     1319607 :   inMiddleOfField=false;
+     225     1319607 :   return *this;
+     226             : }
+     227             : 
+     228        1591 : IFile::IFile():
+     229        1591 :   inMiddleOfField(false),
+     230        1591 :   ignoreFields(false),
+     231        1591 :   noEOL(false)
+     232             : {
+     233        1591 : }
+     234             : 
+     235        1939 : IFile::~IFile() {
+     236        1591 :   if(inMiddleOfField) std::cerr<<"WARNING: IFile closed in the middle of reading. seems strange!\n";
+     237        1939 : }
+     238             : 
+     239     1472259 : IFile& IFile::getline(std::string &str) {
+     240     1472259 :   char tmp=0;
+     241             :   str="";
+     242             :   fpos_t pos;
+     243     1472259 :   fgetpos(fp,&pos);
+     244   100069406 :   while(llread(&tmp,1)==1 && tmp && tmp!='\n' && tmp!='\r' && !eof && !err) {
+     245    98597147 :     str+=tmp;
+     246             :   }
+     247     1472259 :   if(tmp=='\r') {
+     248          53 :     llread(&tmp,1);
+     249          53 :     plumed_massert(tmp=='\n',"plumed only accepts \\n (unix) or \\r\\n (dos) new lines");
+     250             :   }
+     251     1472259 :   if(eof && noEOL) {
+     252         873 :     if(str.length()>0) eof=false;
+     253     1471386 :   } else if(eof || err || tmp!='\n') {
+     254        6442 :     eof = true;
+     255             :     str="";
+     256        6442 :     if(!err) fsetpos(fp,&pos);
+     257             : // there was a fsetpos here that apparently is not necessary
+     258             : //  fsetpos(fp,&pos);
+     259             : // I think it was necessary to have rewind working correctly
+     260             : // after end of file. Since rewind is not used now anywhere,
+     261             : // it should be ok not to reset position.
+     262             : // This is necessary so that eof works properly for emacs files
+     263             : // with no endline at end of file.
+     264             :   }
+     265     1472259 :   return *this;
+     266             : }
+     267             : 
+     268    15852529 : unsigned IFile::findField(const std::string&name)const {
+     269             :   unsigned i;
+     270   105155691 :   for(i=0; i<fields.size(); i++) if(fields[i].name==name) break;
+     271    15852529 :   if(i>=fields.size()) {
+     272           0 :     plumed_merror("file " + getPath() + ": field " + name + " cannot be found");
+     273             :   }
+     274    15852529 :   return i;
+     275             : }
+     276             : 
+     277        6136 : void IFile::reset(bool reset) {
+     278        6136 :   eof = reset;
+     279        6136 :   err = reset;
+     280        6136 :   if(!reset && fp) clearerr(fp);
+     281             : #ifdef __PLUMED_HAS_ZLIB
+     282        6136 :   if(!reset && gzfp) gzclearerr(gzFile(gzfp));
+     283             : #endif
+     284        6136 :   return;
+     285             : }
+     286             : 
+     287        5778 : void IFile::allowIgnoredFields() {
+     288        5778 :   ignoreFields=true;
+     289        5778 : }
+     290             : 
+     291         888 : void IFile::allowNoEOL() {
+     292         888 :   noEOL=true;
+     293         888 : }
+     294             : 
+     295             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.h.func-sort-c.html b/coverage/tools/IFile.h.func-sort-c.html new file mode 100644 index 000000000000..1727db3b6dc9 --- /dev/null +++ b/coverage/tools/IFile.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.h.func.html b/coverage/tools/IFile.h.func.html new file mode 100644 index 000000000000..5d2d14cbd63c --- /dev/null +++ b/coverage/tools/IFile.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/IFile.h.gcov.html b/coverage/tools/IFile.h.gcov.html new file mode 100644 index 000000000000..3e915a19da15 --- /dev/null +++ b/coverage/tools/IFile.h.gcov.html @@ -0,0 +1,194 @@ + + + + + + + + LCOV - plumed test coverage - tools/IFile.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - IFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_IFile_h
+      23             : #define __PLUMED_tools_IFile_h
+      24             : 
+      25             : #include "FileBase.h"
+      26             : #include <vector>
+      27             : #include <cstddef>
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : class Value;
+      32             : 
+      33             : /**
+      34             : \ingroup TOOLBOX
+      35             : Class for input files
+      36             : 
+      37             : This class provides features similar to those in the standard C "FILE*" type,
+      38             : but only for sequential input. See OFile for sequential output.
+      39             : 
+      40             : */
+      41             : class IFile:
+      42             : /// Class identifying a single field for fielded output
+      43             :   public virtual FileBase {
+      44       18874 :   class Field:
+      45             :     public FieldBase {
+      46             :   public:
+      47             :     bool read;
+      48        7273 :     Field(): read(false) {}
+      49             :   };
+      50             : /// Low-level read.
+      51             : /// Note: in parallel, all processes read
+      52             :   std::size_t llread(char*,std::size_t);
+      53             : /// All the defined fields
+      54             :   std::vector<Field> fields;
+      55             : /// Flag set in the middle of a field reading
+      56             :   bool inMiddleOfField;
+      57             : /// Set to true if you want to allow fields to be ignored in the read in file
+      58             :   bool ignoreFields;
+      59             : /// Set to true to allow files without end-of-line at the end
+      60             :   bool noEOL;
+      61             : /// Advance to next field (= read one line)
+      62             :   IFile& advanceField();
+      63             : /// Find field index by name
+      64             :   unsigned findField(const std::string&name)const;
+      65             : public:
+      66             : /// Constructor
+      67             :   IFile();
+      68             : /// Destructor
+      69             :   ~IFile();
+      70             : /// Opens the file
+      71             :   IFile& open(const std::string&name) override;
+      72             : /// Gets the list of all fields
+      73             :   IFile& scanFieldList(std::vector<std::string>&);
+      74             : /// Read a double field
+      75             :   IFile& scanField(const std::string&,double&);
+      76             : /// Read a int field
+      77             :   IFile& scanField(const std::string&,int&);
+      78             : /// Read a long int field
+      79             :   IFile& scanField(const std::string&,long int&);
+      80             : /// Read a long long int field
+      81             :   IFile& scanField(const std::string&,long long int&);
+      82             : /// Read a unsigned field
+      83             :   IFile& scanField(const std::string&,unsigned&);
+      84             : /// Read a long unsigned field
+      85             :   IFile& scanField(const std::string&,long unsigned&);
+      86             : /// Read a long long unsigned field
+      87             :   IFile& scanField(const std::string&,long long unsigned&);
+      88             : /// Read a string field
+      89             :   IFile& scanField(const std::string&,std::string&);
+      90             :   /**
+      91             :    Ends a field-formatted line.
+      92             : 
+      93             :   Typically used as
+      94             :   \verbatim
+      95             :     if.scanField("a",a).scanField("b",b).scanField();
+      96             :   \endverbatim
+      97             :   */
+      98             :   IFile& scanField();
+      99             : /// Get a full line as a string
+     100             :   IFile& getline(std::string&);
+     101             : /// Reset end of file
+     102             :   void reset(bool);
+     103             : /// Check if a field exist
+     104             :   bool FieldExist(const std::string& s);
+     105             : /// Read in a value
+     106             :   IFile& scanField(Value* val);
+     107             : /// Allow some of the fields in the input to be ignored
+     108             :   void allowIgnoredFields();
+     109             : /// Allow files without EOL at the end.
+     110             : /// This in practice should be only used when opening
+     111             : /// plumed input files
+     112             :   void allowNoEOL();
+     113             : };
+     114             : 
+     115             : }
+     116             : 
+     117             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.cpp.func-sort-c.html b/coverage/tools/KernelFunctions.cpp.func-sort-c.html new file mode 100644 index 000000000000..69b49b0c498e --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18722284.2 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15KernelFunctionsC2EPKS0_0
_ZN4PLMD15KernelFunctionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE12
_ZNK4PLMD15KernelFunctions10getSupportERKSt6vectorIdSaIdEE3415
_ZN4PLMD15KernelFunctions4readEPNS_5IFileERKbRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EE4530
_ZNK4PLMD15KernelFunctions20getContinuousSupportEv5141
_ZNK4PLMD15KernelFunctions9getCutoffERKd10294
_ZN4PLMD15KernelFunctions9normalizeERKSt6vectorIPNS_5ValueESaIS3_EE24625
_ZN4PLMD15KernelFunctionsC2ERKSt6vectorIdSaIdEES5_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_RKd30229
_ZN4PLMD15KernelFunctions7setDataERKSt6vectorIdSaIdEES5_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_RKd30241
_ZNK4PLMD15KernelFunctions8evaluateERKSt6vectorIPNS_5ValueESaIS3_EERS1_IdSaIdEEbbdd23606894
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.cpp.func.html b/coverage/tools/KernelFunctions.cpp.func.html new file mode 100644 index 000000000000..04be5c5a948b --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18722284.2 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15KernelFunctions4readEPNS_5IFileERKbRKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISB_EE4530
_ZN4PLMD15KernelFunctions7setDataERKSt6vectorIdSaIdEES5_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_RKd30241
_ZN4PLMD15KernelFunctions9normalizeERKSt6vectorIPNS_5ValueESaIS3_EE24625
_ZN4PLMD15KernelFunctionsC2EPKS0_0
_ZN4PLMD15KernelFunctionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE12
_ZN4PLMD15KernelFunctionsC2ERKSt6vectorIdSaIdEES5_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESD_RKd30229
_ZNK4PLMD15KernelFunctions10getSupportERKSt6vectorIdSaIdEE3415
_ZNK4PLMD15KernelFunctions20getContinuousSupportEv5141
_ZNK4PLMD15KernelFunctions8evaluateERKSt6vectorIPNS_5ValueESaIS3_EERS1_IdSaIdEEbbdd23606894
_ZNK4PLMD15KernelFunctions9getCutoffERKd10294
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.cpp.gcov.html b/coverage/tools/KernelFunctions.cpp.gcov.html new file mode 100644 index 000000000000..c8e6a473634e --- /dev/null +++ b/coverage/tools/KernelFunctions.cpp.gcov.html @@ -0,0 +1,532 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18722284.2 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "KernelFunctions.h"
+      23             : #include "IFile.h"
+      24             : #include <iostream>
+      25             : #include <cmath>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : //+PLUMEDOC INTERNAL kernelfunctions
+      30             : /*
+      31             : Functions that are used to construct histograms
+      32             : 
+      33             : Constructing histograms is something you learned to do relatively early in life. You perform an experiment a number of times,
+      34             : count the number of times each result comes up and then draw a bar graph that describes how often each of the results came up.
+      35             : This only works when there are a finite number of possible results.  If the result a number between 0 and 1 the bar chart is
+      36             : less easy to draw as there are as many possible results as there are numbers between zero and one - an infinite number.
+      37             : To resolve this problem we replace probability, \f$P\f$ with probability density, \f$\pi\f$, and write the probability of getting
+      38             : a number between \f$a\f$ and \f$b\f$ as:
+      39             : 
+      40             : \f[
+      41             : P = \int_{a}^b \textrm{d}x \pi(x)
+      42             : \f]
+      43             : 
+      44             : To calculate probability densities from a set of results we use a process called kernel density estimation.
+      45             : Histograms are accumulated by adding up kernel functions, \f$K\f$, with finite spatial extent, that integrate to one.
+      46             : These functions are centered on each of the \f$n\f$-dimensional data points, \f$\mathbf{x}_i\f$. The overall effect of this
+      47             : is that each result we obtain in our experiments contributes to the probability density in a finite sized region of the space.
+      48             : 
+      49             : Expressing all this mathematically in kernel density estimation we write the probability density as:
+      50             : 
+      51             : \f[
+      52             : \pi(\mathbf{x}) =  \sum_i K\left[ (\mathbf{x} - \mathbf{x}_i)^T \Sigma (\mathbf{x} - \mathbf{x}_i) \right]
+      53             : \f]
+      54             : 
+      55             : where \f$\Sigma\f$ is an \f$n \times n\f$ matrix called the bandwidth that controls the spatial extent of
+      56             : the kernel. Whenever we accumulate a histogram (e.g. in \ref HISTOGRAM or in \ref METAD) we use this
+      57             : technique.
+      58             : 
+      59             : There is thus some flexibility in the particular function we use for \f$K[\mathbf{r}]\f$ in the above.
+      60             : The following variants are available.
+      61             : 
+      62             : <table align=center frame=void width=95%% cellpadding=5%%>
+      63             : <tr>
+      64             : <td> TYPE </td> <td> FUNCTION </td>
+      65             : </tr> <tr>
+      66             : <td> gaussian </td> <td> \f$f(r) = \frac{1}{(2 \pi)^{n} \sqrt{|\Sigma^{-1}|}} \exp\left(-0.5 r^2 \right)\f$ </td>
+      67             : </tr> <tr>
+      68             : <td> truncated-gaussian </td> <td> \f$f(r) = \frac{1}{(2 \pi)^{n} \sqrt{|\Sigma^{-1}|} \left(\frac{\mathrm{erf}(-6.25/sqrt{2}) - \mathrm{erf}(-6.25/sqrt{2})}{2}\right)^n} \exp\left(-0.5 r^2 \right)\f$ </td>
+      69             : </tr> <tr>
+      70             : <td> triangular </td> <td> \f$f(r) = \frac{3}{V} ( 1 - | r | )H(1-|r|) \f$ </td>
+      71             : </tr> <tr>
+      72             : <td> uniform </td> <td> \f$f(r) = \frac{1}{V}H(1-|r|)\f$ </td>
+      73             : </tr>
+      74             : </table>
+      75             : 
+      76             : In the above \f$H(y)\f$ is a function that is equal to one when \f$y>0\f$ and zero when \f$y \le 0\f$. \f$n\f$ is
+      77             : the dimensionality of the vector \f$\mathbf{x}\f$ and \f$V\f$ is the volume of an ellipse in an \f$n\f$ dimensional
+      78             : space which is given by:
+      79             : 
+      80             : \f{eqnarray*}{
+      81             : V &=& | \Sigma^{-1} | \frac{ \pi^{\frac{n}{2}} }{\left( \frac{n}{2} \right)! } \qquad \textrm{for even} \quad n \\
+      82             : V &=& | \Sigma^{-1} | \frac{ 2^{\frac{n+1}{2}} \pi^{\frac{n-1}{2}} }{ n!! }
+      83             : \f}
+      84             : 
+      85             : In \ref METAD the normalization constants are ignored so that the value of the function at \f$r=0\f$ is equal
+      86             : to one.  In addition in \ref METAD we must be able to differentiate the bias in order to get forces.  This limits
+      87             : the kernels we can use in this method.  Notice also that Gaussian kernels should have infinite support.  When used
+      88             : with grids, however, they are assumed to only be non-zero over a finite range.  The difference between the
+      89             : truncated-gaussian and regular gaussian is that the truncated gaussian is scaled so that its integral over the grid
+      90             : is equal to one when it is normalized.  The integral of a regular gaussian when it is evaluated on a grid will be
+      91             : slightly less that one because of the truncation of a function that should have infinite support.
+      92             : */
+      93             : //+ENDPLUMEDOC
+      94             : 
+      95          12 : KernelFunctions::KernelFunctions( const std::string& input ) {
+      96             : 
+      97          12 :   if(!dp2cutoffNoStretch()) {
+      98          12 :     stretchA=dp2cutoffA;
+      99          12 :     stretchB=dp2cutoffB;
+     100             :   }
+     101             : 
+     102          12 :   std::vector<std::string> data=Tools::getWords(input);
+     103          12 :   std::string name=data[0];
+     104             :   data.erase(data.begin());
+     105             : 
+     106             :   std::vector<double> at;
+     107          12 :   bool foundc = Tools::parseVector(data,"CENTER",at);
+     108          12 :   if(!foundc) plumed_merror("failed to find center keyword in definition of kernel");
+     109             :   std::vector<double> sig;
+     110          12 :   bool founds = Tools::parseVector(data,"SIGMA",sig);
+     111          12 :   if(!founds) plumed_merror("failed to find sigma keyword in definition of kernel");
+     112             : 
+     113          12 :   bool multi=false; Tools::parseFlag(data,"MULTIVARIATE",multi);
+     114          24 :   bool vonmises=false; Tools::parseFlag(data,"VON-MISSES",vonmises);
+     115          12 :   if( center.size()==1 && multi ) plumed_merror("one dimensional kernel cannot be multivariate");
+     116          12 :   if( center.size()==1 && vonmises ) plumed_merror("one dimensional kernal cannot be von-misses");
+     117          12 :   if( center.size()==1 && sig.size()!=1 ) plumed_merror("size mismatch between center size and sigma size");
+     118          12 :   if( multi && center.size()>1 && sig.size()!=0.5*center.size()*(center.size()-1) ) plumed_merror("size mismatch between center size and sigma size");
+     119          12 :   if( !multi && center.size()>1 && sig.size()!=center.size() ) plumed_merror("size mismatch between center size and sigma size");
+     120             : 
+     121             :   double h;
+     122          12 :   bool foundh = Tools::parse(data,"HEIGHT",h);
+     123          12 :   if( !foundh) h=1.0;
+     124             : 
+     125          12 :   if( multi ) setData( at, sig, name, "MULTIVARIATE", h );
+     126          12 :   else if( vonmises ) setData( at, sig, name, "VON-MISSES", h );
+     127          24 :   else setData( at, sig, name, "DIAGONAL", h );
+     128          12 : }
+     129             : 
+     130       30229 : KernelFunctions::KernelFunctions( const std::vector<double>& at, const std::vector<double>& sig, const std::string& type, const std::string& mtype, const double& w ) {
+     131             : 
+     132       30229 :   if(!dp2cutoffNoStretch()) {
+     133       30229 :     stretchA=dp2cutoffA;
+     134       30229 :     stretchB=dp2cutoffB;
+     135             :   }
+     136             : 
+     137       30229 :   setData( at, sig, type, mtype, w );
+     138       30229 : }
+     139             : 
+     140           0 : KernelFunctions::KernelFunctions( const KernelFunctions* in ):
+     141           0 :   dtype(in->dtype),
+     142           0 :   ktype(in->ktype),
+     143           0 :   center(in->center),
+     144           0 :   width(in->width),
+     145           0 :   height(in->height)
+     146             : {
+     147           0 :   if(!dp2cutoffNoStretch()) {
+     148           0 :     stretchA=dp2cutoffA;
+     149           0 :     stretchB=dp2cutoffB;
+     150             :   }
+     151           0 : }
+     152             : 
+     153       30241 : void KernelFunctions::setData( const std::vector<double>& at, const std::vector<double>& sig, const std::string& type, const std::string& mtype, const double& w ) {
+     154             : 
+     155       30241 :   height=w;
+     156      114820 :   center.resize( at.size() ); for(unsigned i=0; i<at.size(); ++i) center[i]=at[i];
+     157      119327 :   width.resize( sig.size() ); for(unsigned i=0; i<sig.size(); ++i) width[i]=sig[i];
+     158       30241 :   if( mtype=="MULTIVARIATE" ) dtype=multi;
+     159       25829 :   else if( mtype=="VON-MISSES" ) dtype=vonmises;
+     160       25820 :   else if( mtype=="DIAGONAL" ) dtype=diagonal;
+     161           0 :   else plumed_merror(mtype + " is not a valid metric type");
+     162             : 
+     163             :   // Setup the kernel type
+     164       60474 :   if(type=="GAUSSIAN" || type=="gaussian" ) {
+     165       24674 :     ktype=gaussian;
+     166       11134 :   } else if(type=="STRETCHED-GAUSSIAN" || type=="stretched-gaussian" ) {
+     167        5563 :     ktype=stretchedgaussian;
+     168           8 :   } else if(type=="TRUNCATED-GAUSSIAN" || type=="truncated-gaussian" ) {
+     169           0 :     ktype=truncatedgaussian;
+     170           8 :   } else if(type=="UNIFORM" || type=="uniform") {
+     171           0 :     ktype=uniform;
+     172           4 :   } else if(type=="TRIANGULAR" || type=="triangular") {
+     173           4 :     ktype=triangular;
+     174             :   } else {
+     175           0 :     plumed_merror(type+" is an invalid kernel type\n");
+     176             :   }
+     177       30241 : }
+     178             : 
+     179       24625 : void KernelFunctions::normalize( const std::vector<Value*>& myvals ) {
+     180             : 
+     181             :   double det=1.;
+     182             :   unsigned ncv=ndim();
+     183       24625 :   if(dtype==diagonal) {
+     184       97800 :     for(unsigned i=0; i<width.size(); ++i) det*=width[i]*width[i];
+     185          53 :   } else if(dtype==multi) {
+     186          44 :     Matrix<double> mymatrix( getMatrix() ), myinv( ncv, ncv );
+     187          44 :     Invert(mymatrix,myinv); double logd;
+     188          44 :     logdet( myinv, logd );
+     189          44 :     det=std::exp(logd);
+     190             :   }
+     191       24625 :   if( dtype==diagonal || dtype==multi ) {
+     192             :     double volume;
+     193       24616 :     if( ktype==gaussian || ktype==stretchedgaussian ) {
+     194       24616 :       volume=pow( 2*pi, 0.5*ncv ) * pow( det, 0.5 );
+     195           0 :     } else if( ktype==truncatedgaussian ) {
+     196             :       // This makes it so the gaussian integrates to one over the range over which it has support
+     197             :       const double DP2CUTOFF=std::sqrt(6.25);
+     198           0 :       volume=pow( 2*pi, 0.5*ncv ) * pow( det, 0.5 ) * pow( 0.5 * ( erf(DP2CUTOFF) - erf(-DP2CUTOFF) ), ncv);
+     199           0 :     } else if( ktype==uniform || ktype==triangular ) {
+     200           0 :       if( ncv%2==1 ) {
+     201             :         double dfact=1;
+     202           0 :         for(unsigned i=1; i<ncv; i+=2) dfact*=static_cast<double>(i);
+     203           0 :         volume=( pow( pi, (ncv-1)/2 ) ) * ( pow( 2., (ncv+1)/2 ) ) / dfact;
+     204             :       } else {
+     205             :         double fact=1.;
+     206           0 :         for(unsigned i=1; i<ncv/2; ++i) fact*=static_cast<double>(i);
+     207           0 :         volume=pow( pi,ncv/2 ) / fact;
+     208             :       }
+     209           0 :       if(ktype==uniform) volume*=det;
+     210           0 :       else if(ktype==triangular) volume*=det / 3.;
+     211             :     } else {
+     212           0 :       plumed_merror("not a valid kernel type");
+     213             :     }
+     214       24616 :     height /= volume;
+     215       24616 :     return;
+     216             :   }
+     217           9 :   plumed_assert( dtype==vonmises && ktype==gaussian );
+     218             :   // Now calculate determinant for aperiodic variables
+     219             :   unsigned naper=0;
+     220          25 :   for(unsigned i=0; i<ncv; ++i) {
+     221          16 :     if( !myvals[i]->isPeriodic() ) naper++;
+     222             :   }
+     223             :   // Now construct sub matrix
+     224             :   double volume=1;
+     225           9 :   if( naper>0 ) {
+     226             :     unsigned isub=0;
+     227           2 :     Matrix<double> mymatrix( getMatrix() ), mysub( naper, naper );
+     228           4 :     for(unsigned i=0; i<ncv; ++i) {
+     229           2 :       if( myvals[i]->isPeriodic() ) continue;
+     230             :       unsigned jsub=0;
+     231           4 :       for(unsigned j=0; j<ncv; ++j) {
+     232           2 :         if( myvals[j]->isPeriodic() ) continue;
+     233           2 :         mysub( isub, jsub ) = mymatrix( i, j ); jsub++;
+     234             :       }
+     235           2 :       isub++;
+     236             :     }
+     237             :     Matrix<double> myisub( naper, naper ); double logd;
+     238           2 :     Invert( mysub, myisub ); logdet( myisub, logd );
+     239           2 :     det=std::exp(logd);
+     240           2 :     volume=pow( 2*pi, 0.5*ncv ) * pow( det, 0.5 );
+     241             :   }
+     242             : 
+     243             :   // Calculate volume of periodic variables
+     244             :   unsigned nper=0;
+     245          25 :   for(unsigned i=0; i<ncv; ++i) {
+     246          16 :     if( myvals[i]->isPeriodic() ) nper++;
+     247             :   }
+     248             : 
+     249             :   // Now construct sub matrix
+     250           9 :   if( nper>0 ) {
+     251             :     unsigned isub=0;
+     252           7 :     Matrix<double> mymatrix( getMatrix() ),  mysub( nper, nper );
+     253          21 :     for(unsigned i=0; i<ncv; ++i) {
+     254          14 :       if( !myvals[i]->isPeriodic() ) continue;
+     255             :       unsigned jsub=0;
+     256          42 :       for(unsigned j=0; j<ncv; ++j) {
+     257          28 :         if( !myvals[j]->isPeriodic() ) continue;
+     258          28 :         mysub( isub, jsub ) = mymatrix( i, j ); jsub++;
+     259             :       }
+     260          14 :       isub++;
+     261             :     }
+     262             :     Matrix<double>  eigvec( nper, nper );
+     263           7 :     std::vector<double> eigval( nper );
+     264           7 :     diagMat( mysub, eigval, eigvec );
+     265             :     unsigned iper=0; volume=1;
+     266          21 :     for(unsigned i=0; i<ncv; ++i) {
+     267          14 :       if( myvals[i]->isPeriodic() ) {
+     268          14 :         volume *= myvals[i]->getMaxMinusMin()*Tools::bessel0(eigval[iper])*std::exp(-eigval[iper]);
+     269          14 :         iper++;
+     270             :       }
+     271             :     }
+     272             :   }
+     273           9 :   height /= volume;
+     274             : }
+     275             : 
+     276       10294 : double KernelFunctions::getCutoff( const double& width ) const {
+     277             :   const double DP2CUTOFF=6.25;
+     278       10294 :   if( ktype==gaussian || ktype==truncatedgaussian || ktype==stretchedgaussian ) return std::sqrt(2.0*DP2CUTOFF)*width;
+     279           0 :   else if(ktype==triangular ) return width;
+     280           0 :   else if(ktype==uniform) return width;
+     281           0 :   else plumed_merror("No valid kernel type");
+     282             :   return 0.0;
+     283             : }
+     284             : 
+     285        5141 : std::vector<double> KernelFunctions::getContinuousSupport( ) const {
+     286             :   unsigned ncv=ndim();
+     287        5141 :   std::vector<double> support( ncv );
+     288        5141 :   if(dtype==diagonal) {
+     289        2152 :     for(unsigned i=0; i<ncv; ++i) support[i]=getCutoff(width[i]);
+     290        4412 :   } else if(dtype==multi) {
+     291        4412 :     Matrix<double> mymatrix( getMatrix() ), myinv( ncv,ncv );
+     292        4412 :     Invert(mymatrix,myinv);
+     293        4412 :     Matrix<double> myautovec(ncv,ncv); std::vector<double> myautoval(ncv);
+     294        4412 :     diagMat(myinv,myautoval,myautovec);
+     295             :     double maxautoval=0.;
+     296             :     unsigned ind_maxautoval=0;
+     297       13280 :     for (unsigned i=0; i<ncv; i++) {
+     298        8868 :       if(myautoval[i]>maxautoval) {maxautoval=myautoval[i]; ind_maxautoval=i;}
+     299             :     }
+     300       13280 :     for(unsigned i=0; i<ncv; ++i) {
+     301        8868 :       double extent=std::fabs(std::sqrt(maxautoval)*myautovec(i,ind_maxautoval));
+     302        8868 :       support[i]=getCutoff( extent );
+     303             :     }
+     304             :   } else {
+     305           0 :     plumed_merror("cannot find support if metric is not multi or diagonal type");
+     306             :   }
+     307        5141 :   return support;
+     308             : }
+     309             : 
+     310        3415 : std::vector<unsigned> KernelFunctions::getSupport( const std::vector<double>& dx ) const {
+     311        3415 :   plumed_assert( ndim()==dx.size() );
+     312        3415 :   std::vector<unsigned> support( dx.size() );
+     313        3415 :   std::vector<double> vv=getContinuousSupport( );
+     314       10227 :   for(unsigned i=0; i<dx.size(); ++i) support[i]=static_cast<unsigned>(ceil( vv[i]/dx[i] ));
+     315        3415 :   return support;
+     316             : }
+     317             : 
+     318    23606894 : double KernelFunctions::evaluate( const std::vector<Value*>& pos, std::vector<double>& derivatives, bool usederiv, bool doInt, double lowI_, double uppI_) const {
+     319             :   plumed_dbg_assert( pos.size()==ndim() && derivatives.size()==ndim() );
+     320             : #ifndef NDEBUG
+     321             :   if( usederiv ) plumed_massert( ktype!=uniform, "step function can not be differentiated" );
+     322             : #endif
+     323    23606894 :   if(doInt) {
+     324             :     plumed_dbg_assert(center.size()==1);
+     325           0 :     if(pos[0]->get()<lowI_) pos[0]->set(lowI_);
+     326           0 :     if(pos[0]->get()>uppI_) pos[0]->set(uppI_);
+     327             :   }
+     328             :   double r2=0;
+     329    23606894 :   if(dtype==diagonal) {
+     330    51709439 :     for(unsigned i=0; i<ndim(); ++i) {
+     331    37730371 :       derivatives[i]=-pos[i]->difference( center[i] ) / width[i];
+     332    37730371 :       r2+=derivatives[i]*derivatives[i];
+     333    37730371 :       derivatives[i] /= width[i];
+     334             :     }
+     335     9627826 :   } else if(dtype==multi) {
+     336     9627680 :     Matrix<double> mymatrix( getMatrix() );
+     337    37540216 :     for(unsigned i=0; i<mymatrix.nrows(); ++i) {
+     338    27912536 :       double dp_i, dp_j; derivatives[i]=0;
+     339    27912536 :       dp_i=-pos[i]->difference( center[i] );
+     340   109709136 :       for(unsigned j=0; j<mymatrix.ncols(); ++j) {
+     341    81796600 :         if(i==j) dp_j=dp_i;
+     342    53884064 :         else dp_j=-pos[j]->difference( center[j] );
+     343             : 
+     344    81796600 :         derivatives[i]+=mymatrix(i,j)*dp_j;
+     345    81796600 :         r2+=dp_i*dp_j*mymatrix(i,j);
+     346             :       }
+     347             :     }
+     348         146 :   } else if(dtype==vonmises) {
+     349         146 :     std::vector<double> costmp( ndim() ), sintmp( ndim() ), sinout( ndim(), 0.0 );
+     350         418 :     for(unsigned i=0; i<ndim(); ++i) {
+     351         272 :       if( pos[i]->isPeriodic() ) {
+     352         252 :         sintmp[i]=std::sin( 2.*pi*(pos[i]->get() - center[i])/pos[i]->getMaxMinusMin() );
+     353         252 :         costmp[i]=std::cos( 2.*pi*(pos[i]->get() - center[i])/pos[i]->getMaxMinusMin() );
+     354             :       } else {
+     355          20 :         sintmp[i]=pos[i]->get() - center[i];
+     356          20 :         costmp[i]=1.0;
+     357             :       }
+     358             :     }
+     359             : 
+     360         146 :     Matrix<double> mymatrix( getMatrix() );
+     361         418 :     for(unsigned i=0; i<mymatrix.nrows(); ++i) {
+     362         272 :       derivatives[i]=0;
+     363         272 :       if( pos[i]->isPeriodic() ) {
+     364         252 :         r2+=2*( 1 - costmp[i] )*mymatrix(i,i);
+     365             :       } else {
+     366          20 :         r2+=sintmp[i]*sintmp[i]*mymatrix(i,i);
+     367             :       }
+     368         796 :       for(unsigned j=0; j<mymatrix.ncols(); ++j) {
+     369         524 :         if( i!=j ) sinout[i]+=mymatrix(i,j)*sintmp[j];
+     370             :       }
+     371         272 :       derivatives[i] = mymatrix(i,i)*sintmp[i] + sinout[i]*costmp[i];
+     372         272 :       if( pos[i]->isPeriodic() ) derivatives[i] *= (2*pi/pos[i]->getMaxMinusMin());
+     373             :     }
+     374         418 :     for(unsigned i=0; i<sinout.size(); ++i) r2+=sintmp[i]*sinout[i];
+     375             :   }
+     376             :   double kderiv, kval;
+     377    23606894 :   if(ktype==gaussian || ktype==truncatedgaussian) {
+     378    22547753 :     kval=height*std::exp(-0.5*r2); kderiv=-kval;
+     379     1059141 :   } else if(ktype==stretchedgaussian) {
+     380     1024305 :     auto dp=0.5*r2;
+     381     1024305 :     if(dp<dp2cutoff) {
+     382      630478 :       auto ee=std::exp(-0.5*r2);
+     383      630478 :       kval=height*(stretchA*ee+stretchB);
+     384      630478 :       kderiv=-height*stretchA*ee;
+     385             :     } else {
+     386             :       kval=0.0;
+     387             :       kderiv=0.0;
+     388             :     }
+     389             :   } else {
+     390       34836 :     double r=std::sqrt(r2);
+     391       34836 :     if(ktype==triangular) {
+     392       34836 :       if( r<1.0 ) {
+     393             :         if(r==0) kderiv=0;
+     394        9753 :         kderiv=-1; kval=height*( 1. - std::fabs(r) );
+     395             :       } else {
+     396             :         kval=0.; kderiv=0.;
+     397             :       }
+     398           0 :     } else if(ktype==uniform) {
+     399             :       kderiv=0.;
+     400           0 :       if(r<1.0) kval=height;
+     401             :       else kval=0;
+     402             :     } else {
+     403           0 :       plumed_merror("Not a valid kernel type");
+     404             :     }
+     405       34836 :     kderiv*=height / r ;
+     406             :   }
+     407    89250073 :   for(unsigned i=0; i<ndim(); ++i) derivatives[i]*=kderiv;
+     408    23606894 :   if(doInt) {
+     409           0 :     if((pos[0]->get() <= lowI_ || pos[0]->get() >= uppI_) && usederiv ) for(unsigned i=0; i<ndim(); ++i)derivatives[i]=0;
+     410             :   }
+     411    23606894 :   return kval;
+     412             : }
+     413             : 
+     414        4530 : std::unique_ptr<KernelFunctions> KernelFunctions::read( IFile* ifile, const bool& cholesky, const std::vector<std::string>& valnames ) {
+     415             :   double h;
+     416        9060 :   if( !ifile->scanField("height",h) ) return NULL;;
+     417             : 
+     418        4524 :   std::string sss; ifile->scanField("multivariate",sss);
+     419       12480 :   std::string ktype="stretched-gaussian"; if( ifile->FieldExist("kerneltype") ) ifile->scanField("kerneltype",ktype);
+     420        8954 :   plumed_massert( sss=="false" || sss=="true" || sss=="von-misses", "multivariate flag must be either false, true or von-misses");
+     421             : 
+     422             :   // Read the position of the center
+     423        4524 :   std::vector<double> cc( valnames.size() );
+     424       13613 :   for(unsigned i=0; i<valnames.size(); ++i) ifile->scanField(valnames[i],cc[i]);
+     425             : 
+     426             :   std::vector<double> sig;
+     427        4524 :   if( sss=="false" ) {
+     428         103 :     sig.resize( valnames.size() );
+     429         308 :     for(unsigned i=0; i<valnames.size(); ++i) {
+     430         205 :       ifile->scanField("sigma_"+valnames[i],sig[i]);
+     431         205 :       if( !cholesky ) sig[i]=std::sqrt(sig[i]);
+     432             :     }
+     433             :     return Tools::make_unique<KernelFunctions>(cc, sig, ktype, "DIAGONAL", h);
+     434             :   }
+     435             : 
+     436        4421 :   unsigned ncv=valnames.size();
+     437        4421 :   sig.resize( (ncv*(ncv+1))/2 );
+     438             :   Matrix<double> upper(ncv,ncv), lower(ncv,ncv), mymult( ncv, ncv ), invmatrix(ncv,ncv);
+     439       13305 :   for(unsigned i=0; i<ncv; ++i) {
+     440       22275 :     for(unsigned j=0; j<ncv-i; j++) {
+     441       26782 :       ifile->scanField("sigma_" +valnames[j+i] + "_" + valnames[j], lower(j+i,j) );
+     442       13391 :       upper(j,j+i)=lower(j+i,j); mymult(j+i,j)=mymult(j,j+i)=lower(j+i,j);
+     443             :     }
+     444             :   }
+     445        4421 :   if( cholesky ) mult(lower,upper,mymult);
+     446        4421 :   Invert( mymult, invmatrix );
+     447             :   unsigned k=0;
+     448       13305 :   for(unsigned i=0; i<ncv; i++) {
+     449       22275 :     for(unsigned j=i; j<ncv; j++) { sig[k]=invmatrix(i,j); k++; }
+     450             :   }
+     451        4421 :   if( sss=="true" ) return Tools::make_unique<KernelFunctions>(cc, sig, ktype, "MULTIVARIATE", h);
+     452             :   return Tools::make_unique<KernelFunctions>( cc, sig, ktype, "VON-MISSES", h );
+     453             : }
+     454             : 
+     455             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.h.func-sort-c.html b/coverage/tools/KernelFunctions.h.func-sort-c.html new file mode 100644 index 000000000000..8e27397b60da --- /dev/null +++ b/coverage/tools/KernelFunctions.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15KernelFunctions9getMatrixEv9632291
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.h.func.html b/coverage/tools/KernelFunctions.h.func.html new file mode 100644 index 000000000000..1c6de80575c0 --- /dev/null +++ b/coverage/tools/KernelFunctions.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15KernelFunctions9getMatrixEv9632291
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/KernelFunctions.h.gcov.html b/coverage/tools/KernelFunctions.h.gcov.html new file mode 100644 index 000000000000..07cfbc136a54 --- /dev/null +++ b/coverage/tools/KernelFunctions.h.gcov.html @@ -0,0 +1,174 @@ + + + + + + + + LCOV - plumed test coverage - tools/KernelFunctions.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - KernelFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:99100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_KernelFunctions_h
+      23             : #define __PLUMED_tools_KernelFunctions_h
+      24             : 
+      25             : #include "Matrix.h"
+      26             : #include "core/Value.h"
+      27             : #include <vector>
+      28             : #include <memory>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32       30253 : class KernelFunctions {
+      33             : private:
+      34             : /// Is the metric matrix diagonal
+      35             :   enum {diagonal,multi,vonmises} dtype;
+      36             : /// What type of kernel are we using
+      37             :   enum {gaussian,truncatedgaussian,stretchedgaussian,uniform,triangular} ktype;
+      38             : /// The center of the kernel function
+      39             :   std::vector<double> center;
+      40             : /// The width of the kernel
+      41             :   std::vector<double> width;
+      42             : /// The height of the kernel
+      43             :   double height;
+      44             : 
+      45             :   double stretchA=1.0;
+      46             :   double stretchB=0.0;
+      47             : 
+      48             : /// Used to set all the data in the kernel during construction - avoids double coding as this has two constructors
+      49             :   void setData( const std::vector<double>& at, const std::vector<double>& sig, const std::string& type, const std::string& mtype, const double& w );
+      50             : /// Convert the width into matrix form
+      51             :   Matrix<double> getMatrix() const;
+      52             : public:
+      53             :   explicit KernelFunctions( const std::string& input );
+      54             :   KernelFunctions( const std::vector<double>& at, const std::vector<double>& sig, const std::string& type, const std::string& mtype, const double& w );
+      55             :   explicit KernelFunctions( const KernelFunctions* in );
+      56             : /// Normalise the function and scale the height accordingly
+      57             :   void normalize( const std::vector<Value*>& myvals );
+      58             : /// Get the dimensionality of the kernel
+      59             :   unsigned ndim() const;
+      60             : /// Get the cutoff for a kernel
+      61             :   double getCutoff( const double& width ) const ;
+      62             : /// Get the position of the center
+      63             :   std::vector<double> getCenter() const;
+      64             : /// Get the support
+      65             :   std::vector<unsigned> getSupport( const std::vector<double>& dx ) const;
+      66             : /// get it in continuous form
+      67             :   std::vector<double> getContinuousSupport( ) const;
+      68             : /// Evaluate the kernel function with constant intervals
+      69             :   double evaluate( const std::vector<Value*>& pos, std::vector<double>& derivatives, bool usederiv=true, bool doInt=false, double lowI_=-1, double uppI_=-1 ) const;
+      70             : /// Read a kernel function from a file
+      71             :   static std::unique_ptr<KernelFunctions> read( IFile* ifile, const bool& cholesky, const std::vector<std::string>& valnames );
+      72             : };
+      73             : 
+      74             : inline
+      75     9632291 : Matrix<double> KernelFunctions::getMatrix() const {
+      76             :   unsigned k=0, ncv=ndim(); Matrix<double> mymatrix(ncv,ncv);
+      77    37554115 :   for(unsigned i=0; i<ncv; i++) {
+      78    82790445 :     for(unsigned j=i; j<ncv; j++) {
+      79    54868621 :       mymatrix(i,j)=mymatrix(j,i)=width[k]; // recompose the full inverse matrix
+      80    54868621 :       k++;
+      81             :     }
+      82             :   }
+      83     9632291 :   return mymatrix;
+      84             : }
+      85             : 
+      86             : inline
+      87             : unsigned KernelFunctions::ndim() const {
+      88   150621987 :   return center.size();
+      89             : }
+      90             : 
+      91             : inline
+      92             : std::vector<double> KernelFunctions::getCenter() const {
+      93       27064 :   return center;
+      94             : }
+      95             : 
+      96             : }
+      97             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.cpp.func-sort-c.html b/coverage/tools/Keywords.cpp.func-sort-c.html new file mode 100644 index 000000000000..bad9f3a25b5c --- /dev/null +++ b/coverage/tools/Keywords.cpp.func-sort-c.html @@ -0,0 +1,237 @@ + + + + + + + + LCOV - plumed test coverage - tools/Keywords.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24039560.8 %
Date:2024-02-22 21:58:45Functions:324178.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8Keywords11destroyDataEv0
_ZN4PLMD8Keywords15removeComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10getTooltipERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10print_htmlEv0
_ZNK4PLMD8Keywords14print_spellingEv0
_ZNK4PLMD8Keywords14print_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZNK4PLMD8Keywords15print_html_itemERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords5printEP8_IO_FILE0
_ZNK4PLMD8Keywords5printERNS_3LogE0
_ZNK4PLMD8Keywords19getOutputComponentsB5cxx11Ev224
_ZNK4PLMD8Keywords9print_vimEv298
_ZNK4PLMD8Keywords13getHelpStringB5cxx11Ev596
_ZN4PLMD8Keywords3addERKS0_797
_ZNK4PLMD8Keywords8copyDataERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EESA_RSt3mapIS7_NS0_7KeyTypeESt4lessIS7_ESaISt4pairIKS7_SC_EEERSB_IS7_bSE_SaISF_ISG_bEEERSB_IS7_S7_SE_SaISF_ISG_S7_EEESO_SS_SS_SA_SS_SS_797
_ZN4PLMD8Keywords11reserveFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_2119
_ZNK4PLMD8Keywords29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2404
_ZN4PLMD8Keywords6removeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2478
_ZNK4PLMD8Keywords22getOutputComponentFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4530
_ZNK4PLMD8Keywords21getKeywordDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4559
_ZN4PLMD8Keywords11reset_styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_4698
_ZN4PLMD8Keywords7KeyType8setStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4698
_ZNK4PLMD8Keywords14getKeywordDocsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7186
_ZN4PLMD8Keywords25setComponentsIntroductionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13281
_ZN4PLMD8Keywords3useERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15763
_ZNK4PLMD8Keywords15getDefaultValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_17869
_ZNK4PLMD8Keywords10getKeywordB5cxx11Ej27981
_ZNK4PLMD8Keywords8numberedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE37411
_ZNK4PLMD8Keywords17getLogicalDefaultERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb52864
_ZN4PLMD8Keywords18addOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_121975
_ZN4PLMD8Keywords7reserveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_150448
_ZNK4PLMD8Keywords21outputComponentExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb191805
_ZN4PLMD8Keywords7addFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_252164
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_S8_255588
_ZNK4PLMD8Keywords3getB5cxx11Ej420895
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_589357
_ZNK4PLMD8Keywords4sizeEv928455
_ZNK4PLMD8Keywords5styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_984104
_ZNK4PLMD8Keywords8getStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE988663
_ZN4PLMD8Keywords7KeyTypeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1249676
_ZNK4PLMD8Keywords8reservedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1269762
_ZNK4PLMD8Keywords6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1773423
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.cpp.func.html b/coverage/tools/Keywords.cpp.func.html new file mode 100644 index 000000000000..4155f221f53f --- /dev/null +++ b/coverage/tools/Keywords.cpp.func.html @@ -0,0 +1,237 @@ + + + + + + + + LCOV - plumed test coverage - tools/Keywords.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24039560.8 %
Date:2024-02-22 21:58:45Functions:324178.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8Keywords11destroyDataEv0
_ZN4PLMD8Keywords11reserveFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_2119
_ZN4PLMD8Keywords11reset_styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_4698
_ZN4PLMD8Keywords15removeComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD8Keywords18addOutputComponentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_121975
_ZN4PLMD8Keywords25setComponentsIntroductionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13281
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_589357
_ZN4PLMD8Keywords3addERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_S8_255588
_ZN4PLMD8Keywords3addERKS0_797
_ZN4PLMD8Keywords3useERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE15763
_ZN4PLMD8Keywords6removeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2478
_ZN4PLMD8Keywords7KeyType8setStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4698
_ZN4PLMD8Keywords7KeyTypeC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1249676
_ZN4PLMD8Keywords7addFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbS8_252164
_ZN4PLMD8Keywords7reserveERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_S8_150448
_ZNK4PLMD8Keywords10getKeywordB5cxx11Ej27981
_ZNK4PLMD8Keywords10getTooltipERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords10print_htmlEv0
_ZNK4PLMD8Keywords13getHelpStringB5cxx11Ev596
_ZNK4PLMD8Keywords14getKeywordDocsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7186
_ZNK4PLMD8Keywords14print_spellingEv0
_ZNK4PLMD8Keywords14print_templateERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb0
_ZNK4PLMD8Keywords15getDefaultValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_17869
_ZNK4PLMD8Keywords15print_html_itemERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD8Keywords17getLogicalDefaultERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb52864
_ZNK4PLMD8Keywords19getOutputComponentsB5cxx11Ev224
_ZNK4PLMD8Keywords21getKeywordDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4559
_ZNK4PLMD8Keywords21outputComponentExistsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKb191805
_ZNK4PLMD8Keywords22getOutputComponentFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4530
_ZNK4PLMD8Keywords29getOutputComponentDescriptionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2404
_ZNK4PLMD8Keywords3getB5cxx11Ej420895
_ZNK4PLMD8Keywords4sizeEv928455
_ZNK4PLMD8Keywords5printEP8_IO_FILE0
_ZNK4PLMD8Keywords5printERNS_3LogE0
_ZNK4PLMD8Keywords5styleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_984104
_ZNK4PLMD8Keywords6existsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1773423
_ZNK4PLMD8Keywords8copyDataERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EESA_RSt3mapIS7_NS0_7KeyTypeESt4lessIS7_ESaISt4pairIKS7_SC_EEERSB_IS7_bSE_SaISF_ISG_bEEERSB_IS7_S7_SE_SaISF_ISG_S7_EEESO_SS_SS_SA_SS_SS_797
_ZNK4PLMD8Keywords8getStyleERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE988663
_ZNK4PLMD8Keywords8numberedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE37411
_ZNK4PLMD8Keywords8reservedERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1269762
_ZNK4PLMD8Keywords9print_vimEv298
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.cpp.gcov.html b/coverage/tools/Keywords.cpp.gcov.html new file mode 100644 index 000000000000..6cde65b6dce2 --- /dev/null +++ b/coverage/tools/Keywords.cpp.gcov.html @@ -0,0 +1,740 @@ + + + + + + + + LCOV - plumed test coverage - tools/Keywords.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:24039560.8 %
Date:2024-02-22 21:58:45Functions:324178.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Keywords.h"
+      23             : #include "Log.h"
+      24             : #include "Tools.h"
+      25             : #include <iostream>
+      26             : #include <iomanip>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30     1249676 : Keywords::KeyType::KeyType( const std::string& type ) {
+      31     1249676 :   if( type=="compulsory" ) {
+      32      334682 :     style=compulsory;
+      33      914994 :   } else if( type=="flag" ) {
+      34      254283 :     style=flag;
+      35      660711 :   } else if( type=="optional" ) {
+      36      357202 :     style=optional;
+      37      303509 :   } else if( type.find("atoms")!=std::string::npos || type.find("residues")!=std::string::npos ) {
+      38      143945 :     style=atoms;
+      39      159564 :   } else if( type=="hidden" ) {
+      40       88385 :     style=hidden;
+      41       71179 :   } else if( type=="vessel" ) {
+      42       71179 :     style=vessel;
+      43             :   } else {
+      44           0 :     plumed_massert(false,"invalid keyword specifier " + type);
+      45             :   }
+      46     1249676 : }
+      47             : 
+      48        4698 : void Keywords::KeyType::setStyle( const std::string& type ) {
+      49        4698 :   if( type=="compulsory" ) {
+      50          93 :     style=compulsory;
+      51        4605 :   } else if( type=="flag" ) {
+      52           0 :     style=flag;
+      53        4605 :   } else if( type=="optional" ) {
+      54          30 :     style=optional;
+      55        4575 :   } else if( type.find("atoms")!=std::string::npos || type.find("residues")!=std::string::npos ) {
+      56         239 :     style=atoms;
+      57        4336 :   } else if( type=="hidden" ) {
+      58         149 :     style=hidden;
+      59        4187 :   } else if( type=="vessel" ) {
+      60        4187 :     style=vessel;
+      61             :   } else {
+      62           0 :     plumed_massert(false,"invalid keyword specifier " + type);
+      63             :   }
+      64        4698 : }
+      65             : 
+      66      988663 : std::string Keywords::getStyle( const std::string & k ) const {
+      67           0 :   plumed_massert( types.count(k), "Did not find keyword " + k );
+      68      988663 :   return (types.find(k)->second).toString();
+      69             : }
+      70             : 
+      71         797 : void Keywords::add( const Keywords& newkeys ) {
+      72         797 :   newkeys.copyData( keys, reserved_keys, types, allowmultiple, documentation, booldefs, numdefs, atomtags, cnames, ckey, cdocs  );
+      73         797 : }
+      74             : 
+      75         797 : void Keywords::copyData( std::vector<std::string>& kk, std::vector<std::string>& rk, std::map<std::string,KeyType>& tt, std::map<std::string,bool>& am,
+      76             :                          std::map<std::string,std::string>& docs, std::map<std::string,bool>& bools, std::map<std::string,std::string>& nums,
+      77             :                          std::map<std::string,std::string>& atags, std::vector<std::string>& cnam, std::map<std::string,std::string>& ck,
+      78             :                          std::map<std::string,std::string>& cd ) const {
+      79         797 :   for(unsigned i=0; i<keys.size(); ++i) {
+      80           0 :     std::string thiskey=keys[i];
+      81           0 :     for(unsigned j=0; j<kk.size(); ++j) plumed_massert( thiskey!=kk[j], "keyword " + thiskey + " is in twice" );
+      82           0 :     for(unsigned j=0; j<rk.size(); ++j) plumed_massert( thiskey!=rk[j], "keyword " + thiskey + " is in twice" );
+      83           0 :     kk.push_back( thiskey );
+      84           0 :     plumed_massert( types.count( thiskey ), "no type data on keyword " + thiskey + " to copy" );
+      85           0 :     tt.insert( std::pair<std::string,KeyType>( thiskey,types.find(thiskey)->second) );
+      86           0 :     if( (types.find(thiskey)->second).isAtomList() ) atags.insert( std::pair<std::string,std::string>( thiskey,atomtags.find(thiskey)->second) );
+      87           0 :     plumed_massert( allowmultiple.count( thiskey ), "no numbered data on keyword " + thiskey + " to copy" );
+      88           0 :     am.insert( std::pair<std::string,bool>(thiskey,allowmultiple.find(thiskey)->second) );
+      89           0 :     plumed_massert( documentation.count( thiskey ), "no documentation for keyword " + thiskey + " to copy" );
+      90           0 :     docs.insert( std::pair<std::string,std::string>(thiskey,documentation.find(thiskey)->second) );
+      91           0 :     if( booldefs.count( thiskey ) ) bools.insert( std::pair<std::string,bool>( thiskey,booldefs.find(thiskey)->second) );
+      92           0 :     if( numdefs.count( thiskey ) ) nums.insert( std::pair<std::string,std::string>( thiskey,numdefs.find(thiskey)->second) );
+      93             :   }
+      94       15143 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+      95       14346 :     std::string thiskey=reserved_keys[i];
+      96      140490 :     for(unsigned j=0; j<kk.size(); ++j) plumed_massert( thiskey!=kk[j], "keyword " + thiskey + " is in twice" );
+      97      198873 :     for(unsigned j=0; j<rk.size(); ++j) plumed_massert( thiskey!=rk[j], "keyword " + thiskey + " is in twice" );
+      98       14346 :     rk.push_back( thiskey );
+      99           0 :     plumed_massert( types.count( thiskey ), "no type data on keyword " + thiskey + " to copy" );
+     100       14346 :     tt.insert( std::pair<std::string,KeyType>( thiskey,types.find(thiskey)->second) );
+     101       14346 :     if( (types.find(thiskey)->second).isAtomList() ) atags.insert( std::pair<std::string,std::string>( thiskey,atomtags.find(thiskey)->second) );
+     102           0 :     plumed_massert( allowmultiple.count( thiskey ), "no numbered data on keyword " + thiskey + " to copy" );
+     103       14346 :     am.insert( std::pair<std::string,bool>(thiskey,allowmultiple.find(thiskey)->second) );
+     104           0 :     plumed_massert( documentation.count( thiskey ), "no documentation for keyword " + thiskey + " to copy" );
+     105       28692 :     docs.insert( std::pair<std::string,std::string>(thiskey,documentation.find(thiskey)->second) );
+     106           0 :     if( booldefs.count( thiskey ) ) bools.insert( std::pair<std::string,bool>( thiskey,booldefs.find(thiskey)->second) );
+     107           0 :     if( numdefs.count( thiskey ) ) nums.insert( std::pair<std::string,std::string>( thiskey,numdefs.find(thiskey)->second) );
+     108             :   }
+     109       15143 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     110       14346 :     std::string thisnam=cnames[i];
+     111      136287 :     for(unsigned j=0; j<cnam.size(); ++j) plumed_massert( thisnam!=cnam[j], "component " + thisnam + " is in twice" );
+     112       14346 :     cnam.push_back( thisnam );
+     113           0 :     plumed_massert( ckey.count( thisnam ), "no keyword data on component " + thisnam + " to copy" );
+     114       28692 :     ck.insert( std::pair<std::string,std::string>( thisnam, ckey.find(thisnam)->second) );
+     115           0 :     plumed_massert( cdocs.count( thisnam ), "no documentation on component " + thisnam + " to copy" );
+     116       28692 :     cd.insert( std::pair<std::string,std::string>( thisnam, cdocs.find(thisnam)->second) );
+     117             :   }
+     118         797 : }
+     119             : 
+     120      150448 : void Keywords::reserve( const std::string & t, const std::string & k, const std::string & d ) {
+     121      150448 :   plumed_assert( !exists(k) && !reserved(k) );
+     122      150448 :   std::string fd, lowkey=k;
+     123             :   // Convert to lower case
+     124     1330993 :   std::transform(lowkey.begin(),lowkey.end(),lowkey.begin(),[](unsigned char c) { return std::tolower(c); });
+     125             : // Remove any underscore characters
+     126             :   for(unsigned i=0;; ++i) {
+     127      210768 :     std::size_t num=lowkey.find_first_of("_");
+     128      210768 :     if( num==std::string::npos ) break;
+     129       60320 :     lowkey.erase( lowkey.begin() + num, lowkey.begin() + num + 1 );
+     130       60320 :   }
+     131      150448 :   if( t=="vessel" ) {
+     132      142358 :     fd = d + " The final value can be referenced using <em>label</em>." + lowkey;
+     133      133984 :     if(d.find("flag")==std::string::npos) fd += ".  You can use multiple instances of this keyword i.e. " +
+     134      125610 :           k +"1, " + k + "2, " + k + "3...  The corresponding values are then "
+     135      125610 :           "referenced using <em>label</em>."+ lowkey +"-1,  <em>label</em>." + lowkey +
+     136      125610 :           "-2,  <em>label</em>." + lowkey + "-3...";
+     137       71179 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     138      142358 :     types.insert( std::pair<std::string,KeyType>(k,KeyType("vessel")) );
+     139       79269 :   } else if( t=="numbered" ) {
+     140        6482 :     fd = d + ". You can use multiple instances of this keyword i.e. " + k +"1, " + k + "2, " + k + "3...";
+     141        3241 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     142        6482 :     types.insert( std::pair<std::string,KeyType>(k,KeyType("optional")) );
+     143             :   } else {
+     144             :     fd = d;
+     145       76028 :     if( t=="atoms" && isaction ) fd = d + ".  For more information on how to specify lists of atoms see \\ref Group";
+     146       76028 :     allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     147      152056 :     types.insert( std::pair<std::string,KeyType>(k,KeyType(t)) );
+     148       77534 :     if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,t) );
+     149             :   }
+     150      150448 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     151      150448 :   reserved_keys.push_back(k);
+     152      150448 : }
+     153             : 
+     154        2119 : void Keywords::reserveFlag( const std::string & k, const bool def, const std::string & d ) {
+     155        2119 :   plumed_assert( !exists(k) && !reserved(k) );
+     156             :   std::string defstr;
+     157        2119 :   if( def ) { defstr="( default=on ) "; } else { defstr="( default=off ) "; }
+     158        4238 :   types.insert( std::pair<std::string,KeyType>(k,KeyType("flag")) );
+     159       25939 :   std::string fd,lowkey=k; std::transform(lowkey.begin(),lowkey.end(),lowkey.begin(),[](unsigned char c) { return std::tolower(c); });
+     160        2119 :   fd=defstr + d;
+     161        4238 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     162        2119 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     163           0 :   booldefs.insert( std::pair<std::string,bool>(k,def) );
+     164        2119 :   reserved_keys.push_back(k);
+     165        2119 : }
+     166             : 
+     167       15763 : void Keywords::use( const std::string & k ) {
+     168       15763 :   plumed_massert( reserved(k), "the " + k + " keyword is not reserved");
+     169      200019 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+     170      184256 :     if(reserved_keys[i]==k) keys.push_back( reserved_keys[i] );
+     171             :   }
+     172       15763 : }
+     173             : 
+     174        4698 : void Keywords::reset_style( const std::string & k, const std::string & style ) {
+     175        4698 :   plumed_massert( exists(k) || reserved(k), "no " + k + " keyword" );
+     176        4698 :   (types.find(k)->second).setStyle(style);
+     177        4698 :   if( (types.find(k)->second).isVessel() ) allowmultiple[k]=true;
+     178        4937 :   if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,style) );
+     179        4698 : }
+     180             : 
+     181      589357 : void Keywords::add( const std::string & t, const std::string & k, const std::string & d ) {
+     182     1768071 :   plumed_massert( !exists(k) && t!="flag" && !reserved(k) && t!="vessel", "keyword " + k + " has already been registered");
+     183             :   std::string fd;
+     184      589357 :   if( t=="numbered" ) {
+     185       12582 :     fd=d + ". You can use multiple instances of this keyword i.e. " + k +"1, " + k + "2, " + k + "3...";
+     186        6291 :     allowmultiple.insert( std::pair<std::string,bool>(k,true) );
+     187       12582 :     types.insert( std::pair<std::string,KeyType>(k, KeyType("optional")) );
+     188             :   } else {
+     189             :     fd=d;
+     190      583066 :     allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     191     1166132 :     types.insert( std::pair<std::string,KeyType>(k,KeyType(t)) );
+     192      725505 :     if( (types.find(k)->second).isAtomList() ) atomtags.insert( std::pair<std::string,std::string>(k,t) );
+     193             :   }
+     194      607080 :   if( t=="atoms" && isaction ) fd = d + ".  For more information on how to specify lists of atoms see \\ref Group";
+     195      589357 :   documentation.insert( std::pair<std::string,std::string>(k,fd) );
+     196      589357 :   keys.push_back(k);
+     197      589357 : }
+     198             : 
+     199      255588 : void Keywords::add( const std::string & t, const std::string & k, const std::string &  def, const std::string & d ) {
+     200      511176 :   plumed_assert( !exists(k) && !reserved(k) &&  (t=="compulsory" || t=="hidden" )); // An optional keyword can't have a default
+     201      255588 :   types.insert(  std::pair<std::string,KeyType>(k, KeyType(t)) );
+     202      511176 :   documentation.insert( std::pair<std::string,std::string>(k,"( default=" + def + " ) " + d) );
+     203      255588 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     204      255588 :   numdefs.insert( std::pair<std::string,std::string>(k,def) );
+     205      255588 :   keys.push_back(k);
+     206      255588 : }
+     207             : 
+     208      252164 : void Keywords::addFlag( const std::string & k, const bool def, const std::string & d ) {
+     209      252164 :   plumed_massert( !exists(k) && !reserved(k), "keyword " + k + " has already been registered");
+     210      252164 :   std::string defstr; plumed_massert( !def, "the second argument to addFlag must be false " + k );
+     211             :   defstr="( default=off ) ";
+     212      504328 :   types.insert( std::pair<std::string,KeyType>(k,KeyType("flag")) );
+     213      504328 :   documentation.insert( std::pair<std::string,std::string>(k,defstr + d) );
+     214      252164 :   allowmultiple.insert( std::pair<std::string,bool>(k,false) );
+     215           0 :   booldefs.insert( std::pair<std::string,bool>(k,def) );
+     216      252164 :   keys.push_back(k);
+     217      252164 : }
+     218             : 
+     219        2478 : void Keywords::remove( const std::string & k ) {
+     220             :   bool found=false; unsigned j=0, n=0;
+     221             : 
+     222             :   while(true) {
+     223       27129 :     for(j=0; j<keys.size(); j++) if(keys[j]==k)break;
+     224       44764 :     for(n=0; n<reserved_keys.size(); n++) if(reserved_keys[n]==k)break;
+     225        4956 :     if(j<keys.size()) {
+     226        2384 :       keys.erase(keys.begin()+j);
+     227             :       found=true;
+     228        2572 :     } else if(n<reserved_keys.size()) {
+     229          94 :       reserved_keys.erase(reserved_keys.begin()+n);
+     230             :       found=true;
+     231             :     } else break;
+     232             :   }
+     233             :   // Delete documentation, type and so on from the description
+     234             :   types.erase(k); documentation.erase(k); allowmultiple.erase(k); booldefs.erase(k); numdefs.erase(k);
+     235        2478 :   plumed_massert(found,"You are trying to forbid " + k + " a keyword that isn't there"); // You have tried to forbid a keyword that isn't there
+     236        2478 : }
+     237             : 
+     238       37411 : bool Keywords::numbered( const std::string & k ) const {
+     239       74822 :   if( style( k,"atoms") ) return true;
+     240           0 :   plumed_massert( allowmultiple.count(k), "Did not find keyword " + k );
+     241       35153 :   return allowmultiple.find(k)->second;
+     242             : }
+     243             : 
+     244      984104 : bool Keywords::style( const std::string & k, const std::string & t ) const {
+     245      984104 :   if( getStyle(k)==t ) return true;
+     246             :   return false;
+     247             : }
+     248             : 
+     249      928455 : unsigned Keywords::size() const {
+     250      928455 :   return keys.size();
+     251             : }
+     252             : 
+     253       27981 : std::string Keywords::getKeyword( const unsigned i ) const {
+     254       27981 :   plumed_assert( i<size() );
+     255       27981 :   return keys[i];
+     256             : }
+     257             : 
+     258     1773423 : bool Keywords::exists( const std::string & k ) const {
+     259    17634294 :   for(unsigned i=0; i<keys.size(); ++i) {
+     260    16237875 :     if( keys[i]==k ) return true;
+     261             :   }
+     262             :   return false;
+     263             : }
+     264             : 
+     265     1269762 : bool Keywords::reserved( const std::string & k ) const {
+     266     2969223 :   for(unsigned i=0; i<reserved_keys.size(); ++i) {
+     267     1719547 :     if( reserved_keys[i]==k ) return true;
+     268             :   }
+     269             :   return false;
+     270             : }
+     271             : 
+     272           0 : void Keywords::print_template(const std::string& actionname, bool include_optional) const {
+     273             :   unsigned nkeys=0;
+     274             :   std::printf("%s",actionname.c_str());
+     275           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     276           0 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     277             :   }
+     278           0 :   if( nkeys>0 ) {
+     279           0 :     std::string prevtag="start";
+     280           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     281           0 :       if( (types.find(keys[i])->second).isAtomList() ) {
+     282           0 :         plumed_massert( atomtags.count(keys[i]), "keyword " + keys[i] + " allegedly specifies atoms but no tag has been specified. Please email Gareth Tribello");
+     283           0 :         if( prevtag!="start" && prevtag!=atomtags.find(keys[i])->second ) break;
+     284           0 :         if( (atomtags.find(keys[i])->second).find("residues")!=std::string::npos) std::printf(" %s=<residue selection>", keys[i].c_str() );
+     285             :         else std::printf(" %s=<atom selection>", keys[i].c_str() );
+     286           0 :         prevtag=atomtags.find(keys[i])->second;
+     287             :       }
+     288             :     }
+     289             :   }
+     290             :   nkeys=0;
+     291           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     292           0 :     if ( include_optional || \
+     293           0 :          (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     294             :   }
+     295           0 :   if( nkeys>0 ) {
+     296           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     297           0 :       if ( (types.find(keys[i])->second).isCompulsory() ) {
+     298             :         std::string def;
+     299           0 :         if( getDefaultValue( keys[i], def) ) {
+     300             :           std::printf(" %s=%s ", keys[i].c_str(), def.c_str() );
+     301             :         } else {
+     302             :           std::printf(" %s=    ", keys[i].c_str() );
+     303             :         }
+     304           0 :       } else if (include_optional) {
+     305             :         // TG no defaults for optional keywords?
+     306             :         std::printf(" [%s]", keys[i].c_str() );
+     307             :       }
+     308             :     }
+     309             :   }
+     310             :   std::printf("\n");
+     311             :   std::flush(std::cout);
+     312           0 : }
+     313             : 
+     314         298 : void Keywords::print_vim() const {
+     315        4857 :   for(unsigned i=0; i<keys.size(); ++i) {
+     316        4559 :     if( (types.find(keys[i])->second).isFlag() ) {
+     317             :       std::printf( ",flag:%s", keys[i].c_str() );
+     318             :     } else {
+     319        3589 :       if( allowmultiple.find(keys[i])->second ) std::printf(",numbered:%s",keys[i].c_str() );
+     320             :       else std::printf(",option:%s",keys[i].c_str() );
+     321             :     }
+     322             :   }
+     323         298 :   std::fprintf(stdout, "\n%s", getHelpString().c_str() );
+     324         298 : }
+     325             : 
+     326           0 : void Keywords::print_html() const {
+     327             : 
+     328             : // This is the part that outputs the details of the components
+     329           0 :   if( cnames.size()>0 ) {
+     330             :     unsigned ndef=0;
+     331           0 :     for(unsigned i=0; i<cnames.size(); ++i) {
+     332           0 :       if(ckey.find(cnames[i])->second=="default") ndef++;
+     333             :     }
+     334             : 
+     335           0 :     if( ndef>0 ) {
+     336           0 :       std::cout<<"\\par Description of components\n\n";
+     337           0 :       std::cout<<cstring<<"\n\n";
+     338           0 :       std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     339             :       std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     340             :       unsigned nndef=0;
+     341           0 :       for(unsigned i=0; i<cnames.size(); ++i) {
+     342             :         //plumed_assert( ckey.find(cnames[i])->second=="default" );
+     343           0 :         if( ckey.find(cnames[i])->second!="default" ) { nndef++; continue; }
+     344             :         std::printf("<tr>\n");
+     345             :         std::printf("<td width=15%%> <b> %s </b></td>\n",cnames[i].c_str() );
+     346             :         std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     347             :         std::printf("</tr>\n");
+     348             :       }
+     349           0 :       std::cout<<"</table>\n\n";
+     350           0 :       if( nndef>0 ) {
+     351           0 :         std::cout<<"In addition the following quantities can be calculated by employing the keywords listed below"<<std::endl;
+     352           0 :         std::cout<<"\n\n";
+     353           0 :         std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     354             :         std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Keyword </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     355           0 :         for(unsigned i=0; i<cnames.size(); ++i) {
+     356           0 :           if( ckey.find(cnames[i])->second!="default") {
+     357             :             std::printf("<tr>\n");
+     358             :             std::printf("<td width=5%%> <b> %s </b></td> <td width=10%%> <b> %s </b> </td> \n",
+     359             :                         cnames[i].c_str(),(ckey.find(cnames[i])->second).c_str() );
+     360             :             std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     361             :             std::printf("</tr>\n");
+     362             :           }
+     363             :         }
+     364           0 :         std::cout<<"</table>\n\n";
+     365             :       }
+     366             :     } else {
+     367             :       unsigned nregs=0;
+     368           0 :       for(unsigned i=0; i<cnames.size(); ++i) {
+     369           0 :         if( exists(ckey.find(cnames[i])->second) ) nregs++;
+     370             :       }
+     371           0 :       if( nregs>0 ) {
+     372           0 :         std::cout<<"\\par Description of components\n\n";
+     373           0 :         std::cout<<cstring<<"\n\n";
+     374           0 :         std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     375             :         std::printf("<tr> <td width=5%%> <b> Quantity </b> </td> <td> <b> Keyword </b> </td> <td> <b> Description </b> </td> </tr>\n");
+     376           0 :         for(unsigned i=0; i<cnames.size(); ++i) {
+     377           0 :           if( exists(ckey.find(cnames[i])->second) ) {
+     378             :             std::printf("<tr>\n");
+     379             :             std::printf("<td width=5%%> <b> %s </b></td> <td width=10%%> <b> %s </b> </td> \n",
+     380             :                         cnames[i].c_str(),(ckey.find(cnames[i])->second).c_str() );
+     381             :             std::printf("<td> %s </td>\n",(cdocs.find(cnames[i])->second).c_str() );
+     382             :             std::printf("</tr>\n");
+     383             :           }
+     384             :         }
+     385           0 :         std::cout<<"</table>\n\n";
+     386             :       }
+     387             :     }
+     388             :   }
+     389             : 
+     390             :   unsigned nkeys=0;
+     391           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     392           0 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     393             :   }
+     394           0 :   if( nkeys>0 ) {
+     395           0 :     if(isaction && isatoms) std::cout<<"\\par The atoms involved can be specified using\n\n";
+     396           0 :     else if(isaction) std::cout<<"\\par The data to analyze can be the output from another analysis algorithm\n\n";
+     397           0 :     else std::cout<<"\\par The input trajectory is specified using one of the following\n\n";
+     398           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     399           0 :     std::string prevtag="start"; unsigned counter=0;
+     400           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     401           0 :       if ( (types.find(keys[i])->second).isAtomList() ) {
+     402           0 :         plumed_massert( atomtags.count(keys[i]), "keyword " + keys[i] + " allegedly specifies atoms but no tag has been specified. Please email Gareth Tribello");
+     403           0 :         if( prevtag!="start" && prevtag!=atomtags.find(keys[i])->second && isaction ) {
+     404           0 :           std::cout<<"</table>\n\n";
+     405           0 :           if( isatoms ) std::cout<<"\\par Or alternatively by using\n\n";
+     406           0 :           else if( counter==0 ) { std::cout<<"\\par Alternatively data can be collected from the trajectory using \n\n"; counter++; }
+     407           0 :           else std::cout<<"\\par Lastly data collected in a previous analysis action can be reanalyzed by using the keyword \n\n";
+     408           0 :           std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     409             :         }
+     410           0 :         print_html_item( keys[i] );
+     411           0 :         prevtag=atomtags.find(keys[i])->second;
+     412             :       }
+     413             :     }
+     414           0 :     std::cout<<"</table>\n\n";
+     415             :   }
+     416             :   nkeys=0;
+     417           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     418           0 :     if ( (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     419             :   }
+     420           0 :   if( nkeys>0 ) {
+     421           0 :     if(isaction) std::cout<< "\\par Compulsory keywords\n\n";
+     422           0 :     else std::cout<<"\\par The following must be present\n\n";
+     423           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     424           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     425           0 :       if ( (types.find(keys[i])->second).isCompulsory() ) print_html_item( keys[i] );
+     426             :     }
+     427           0 :     std::cout<<"</table>\n\n";
+     428             :   }
+     429             :   nkeys=0;
+     430           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     431           0 :     if ( (types.find(keys[i])->second).isFlag() || (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     432             :   }
+     433           0 :   if( nkeys>0 ) {
+     434           0 :     if(isaction) std::cout<<"\\par Options\n\n";
+     435           0 :     else std::cout<<"\\par The following options are available\n\n";
+     436           0 :     std::cout<<" <table align=center frame=void width=95%% cellpadding=5%%> \n";
+     437           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     438           0 :       if ( (types.find(keys[i])->second).isFlag() ) print_html_item( keys[i] );
+     439             :     }
+     440           0 :     std::cout<<"\n";
+     441             :   }
+     442             :   nkeys=0;
+     443           0 :   for(unsigned i=0; i<keys.size(); ++i) {
+     444           0 :     if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     445             :   }
+     446           0 :   if( nkeys>0 ) {
+     447           0 :     for(unsigned i=0; i<keys.size(); ++i) {
+     448           0 :       if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) print_html_item( keys[i] );
+     449             :     }
+     450             :   }
+     451           0 :   std::cout<<"</table>\n\n";
+     452           0 : }
+     453             : 
+     454           0 : void Keywords::print_spelling() const {
+     455           0 :   for(unsigned i=0; i<keys.size(); ++i) std::printf("%s\n", keys[i].c_str() );
+     456           0 :   for(unsigned i=0; i<cnames.size(); ++i) std::printf("%s\n",cnames[i].c_str() );
+     457           0 : }
+     458             : 
+     459        7186 : std::string Keywords::getKeywordDocs( const std::string& key ) const {
+     460        7186 :   bool killdot=( (documentation.find(key)->second).find("\\f$")!=std::string::npos ); // Check for latex
+     461        7186 :   std::vector<std::string> w=Tools::getWords( documentation.find(key)->second );
+     462       14372 :   std::stringstream sstr; sstr<<std::setw(23)<<key<<" - ";
+     463        7186 :   unsigned nl=0; std::string blank=" ";
+     464      151990 :   for(unsigned i=0; i<w.size(); ++i) {
+     465      145342 :     nl+=w[i].length() + 1;
+     466      145342 :     if( nl>60 ) {
+     467       33486 :       sstr<<"\n"<<std::setw(23)<<blank<<"   "<<w[i]<<" "; nl=0;
+     468      134180 :     } else sstr<<w[i]<<" ";
+     469      145342 :     if( killdot && w[i].find(".")!=std::string::npos ) break; // If there is latex only write up to first dot
+     470             :   }
+     471       14372 :   sstr<<"\n"; return sstr.str();
+     472        7186 : }
+     473             : 
+     474         596 : std::string Keywords::getHelpString() const {
+     475             :   std::string helpstr; unsigned nkeys=0;
+     476        9714 :   for(unsigned i=0; i<keys.size(); ++i) {
+     477        9118 :     if ( (types.find(keys[i])->second).isAtomList() ) nkeys++;
+     478             :   }
+     479         596 :   if( nkeys>0 ) {
+     480             :     helpstr += "The input trajectory can be in any of the following formats: \n\n";
+     481        5348 :     for(unsigned i=0; i<keys.size(); ++i) {
+     482        5628 :       if ( (types.find(keys[i])->second).isAtomList() ) helpstr += getKeywordDocs( keys[i] );
+     483             :     }
+     484             :   }
+     485             :   nkeys=0;
+     486        9714 :   for(unsigned i=0; i<keys.size(); ++i) {
+     487        9118 :     if ( (types.find(keys[i])->second).isCompulsory() ) nkeys++;
+     488             :   }
+     489             :   unsigned ncompulsory=nkeys;
+     490         596 :   if( nkeys>0 ) {
+     491             :     helpstr += "\nThe following arguments are compulsory: \n\n";
+     492        7978 :     for(unsigned i=0; i<keys.size(); ++i) {
+     493        9290 :       if ( (types.find(keys[i])->second).isCompulsory() ) helpstr += getKeywordDocs( keys[i] );
+     494             :     }
+     495             :   }
+     496             :   nkeys=0;
+     497        9714 :   for(unsigned i=0; i<keys.size(); ++i) {
+     498        9118 :     if ( (types.find(keys[i])->second).isFlag() ) nkeys++;
+     499             :   }
+     500         596 :   if( nkeys>0 ) {
+     501         526 :     if(ncompulsory>0) helpstr += "\nIn addition you may use the following options: \n\n";
+     502             :     else helpstr += "\nThe following options are available\n\n";
+     503        9270 :     for(unsigned i=0; i<keys.size(); ++i) {
+     504       10684 :       if ( (types.find(keys[i])->second).isFlag() ) helpstr += getKeywordDocs( keys[i] ).c_str();
+     505             :     }
+     506             :   }
+     507             :   nkeys=0;
+     508        9714 :   for(unsigned i=0; i<keys.size(); ++i) {
+     509       16374 :     if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) nkeys++;
+     510             :   }
+     511         596 :   if( nkeys>0 ) {
+     512        8456 :     for(unsigned i=0; i<keys.size(); ++i) {
+     513       17062 :       if ( (types.find(keys[i])->second).isOptional() || (types.find(keys[i])->second).isVessel() ) helpstr += getKeywordDocs( keys[i] );
+     514             :     }
+     515             :     helpstr += "\n";
+     516             :   }
+     517         596 :   return helpstr;
+     518             : }
+     519             : 
+     520           0 : void Keywords::print( Log& log ) const {
+     521           0 :   log.printf("%s", getHelpString().c_str() );
+     522           0 : }
+     523             : 
+     524           0 : void Keywords::print( FILE* out ) const {
+     525           0 :   fprintf( out,"%s", getHelpString().c_str() );
+     526           0 : }
+     527             : 
+     528           0 : std::string Keywords::getTooltip( const std::string& name ) const {
+     529           0 :   std::size_t dd=name.find_first_of("0123456789"); std::string kname=name.substr(0,dd);
+     530           0 :   if( !exists(kname) ) return "<b> could not find this keyword </b>";
+     531           0 :   std::string mystring, docstr = documentation.find(kname)->second;
+     532           0 :   if( types.find(kname)->second.isCompulsory() ) {
+     533             :     mystring += "<b>compulsory keyword ";
+     534           0 :     if( docstr.find("default")!=std::string::npos ) {
+     535           0 :       std::size_t bra = docstr.find_first_of(")"); mystring += docstr.substr(0,bra+1); docstr = docstr.substr(bra+1);
+     536             :     }
+     537             :     mystring += "</b>\n";
+     538             :   }
+     539           0 :   std::vector<std::string> w=Tools::getWords( docstr ); unsigned nl=0;
+     540           0 :   for(unsigned i=0; i<w.size(); ++i) {
+     541           0 :     nl+=w[i].length() + 1;
+     542           0 :     if( nl>80 ) { mystring += w[i] + "\n"; nl=0; }
+     543           0 :     else { mystring += w[i] + " "; }
+     544           0 :     if( w[i].find(".")!=std::string::npos ) break; // Only write up the the first dot
+     545             :   }
+     546             :   return mystring;
+     547           0 : }
+     548             : 
+     549           0 : void Keywords::print_html_item( const std::string& key ) const {
+     550             :   std::printf("<tr>\n");
+     551             :   std::printf("<td width=15%%> <b> %s </b></td>\n",key.c_str() );
+     552             :   std::printf("<td> %s </td>\n",(documentation.find(key)->second).c_str() );
+     553             :   std::printf("</tr>\n");
+     554           0 : }
+     555             : 
+     556      420895 : std::string Keywords::get( const unsigned k ) const {
+     557      420895 :   plumed_assert( k<size() );
+     558      420895 :   return keys[k];
+     559             : }
+     560             : 
+     561       52864 : bool Keywords::getLogicalDefault(const std::string & key, bool& def ) const {
+     562       52864 :   if( booldefs.find(key)!=booldefs.end() ) {
+     563       52864 :     def=booldefs.find(key)->second;
+     564       52864 :     return true;
+     565             :   } else {
+     566             :     return false;
+     567             :   }
+     568             : }
+     569             : 
+     570       17869 : bool Keywords::getDefaultValue(const std::string & key, std::string& def ) const {
+     571       28649 :   plumed_assert( style(key,"compulsory") || style(key,"hidden") );
+     572             : 
+     573       17869 :   if( numdefs.find(key)!=numdefs.end() ) {
+     574       12479 :     def=numdefs.find(key)->second;
+     575       12479 :     return true;
+     576             :   } else {
+     577             :     return false;
+     578             :   }
+     579             : }
+     580             : 
+     581           0 : void Keywords::destroyData() {
+     582           0 :   keys.clear(); reserved_keys.clear(); types.clear();
+     583             :   allowmultiple.clear(); documentation.clear();
+     584             :   booldefs.clear(); numdefs.clear(); atomtags.clear();
+     585             :   ckey.clear(); cdocs.clear(); ckey.clear();
+     586           0 : }
+     587             : 
+     588       13281 : void Keywords::setComponentsIntroduction( const std::string& instr ) {
+     589       13281 :   cstring = instr;
+     590       13281 : }
+     591             : 
+     592      121975 : void Keywords::addOutputComponent( const std::string& name, const std::string& key, const std::string& descr ) {
+     593      121975 :   plumed_assert( !outputComponentExists( name, false ) );
+     594      121975 :   plumed_massert( name.find("-")==std::string::npos,"dash is reseved character in component names" );
+     595             : 
+     596      121975 :   std::size_t num2=name.find_first_of("_");
+     597      121975 :   if( num2!=std::string::npos ) {
+     598         319 :     char uu = '_'; plumed_massert( std::count(name.begin(),name.end(), uu)==1, "underscore is reserved character in component names and there should only be one");
+     599         319 :     plumed_massert( num2==0, "underscore is reserved character in component names that has special meaning");
+     600             :   }
+     601             : 
+     602      121975 :   ckey.insert( std::pair<std::string,std::string>(name,key) );
+     603      121975 :   cdocs.insert( std::pair<std::string,std::string>(name,descr) );
+     604      121975 :   cnames.push_back(name);
+     605      121975 : }
+     606             : 
+     607      191805 : bool Keywords::outputComponentExists( const std::string& name, const bool& custom ) const {
+     608      191805 :   if( custom && cstring.find("customize")!=std::string::npos ) return true;
+     609             : 
+     610             :   std::string sname;
+     611      188340 :   std::size_t num=name.find_first_of("-");
+     612      188340 :   std::size_t num2=name.find_last_of("_");
+     613             : 
+     614      190280 :   if( num2!=std::string::npos ) sname=name.substr(num2);
+     615      212455 :   else if( num!=std::string::npos ) sname=name.substr(0,num);
+     616             :   else sname=name;
+     617             : 
+     618     1322018 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     619     1200043 :     if( sname==cnames[i] ) return true;
+     620             :   }
+     621             :   return false;
+     622             : }
+     623             : 
+     624        4530 : std::string Keywords::getOutputComponentFlag( const std::string& name ) const {
+     625        4530 :   return ckey.find(name)->second;
+     626             : }
+     627             : 
+     628        2404 : std::string Keywords::getOutputComponentDescription( const std::string& name ) const {
+     629        2404 :   if( cstring.find("customized")!=std::string::npos ) return "the label of this action is set by user in the input. See documentation above.";
+     630             : 
+     631             :   bool found=false;
+     632       42180 :   for(unsigned i=0; i<cnames.size(); ++i) {
+     633       39832 :     if( name==cnames[i] ) found=true;
+     634             :   }
+     635        2348 :   if( !found ) plumed_merror("could not find output component named " + name );
+     636        2348 :   return cdocs.find(name)->second;
+     637             : }
+     638             : 
+     639           0 : void Keywords::removeComponent( const std::string& name ) {
+     640             :   bool found=false;
+     641             : 
+     642             :   while(true) {
+     643             :     unsigned j;
+     644           0 :     for(j=0; j<cnames.size(); j++) if(cnames[j]==name)break;
+     645           0 :     if(j<cnames.size()) {
+     646           0 :       cnames.erase(cnames.begin()+j);
+     647             :       found=true;
+     648             :     } else break;
+     649           0 :   }
+     650             :   // Delete documentation, type and so on from the description
+     651             :   cdocs.erase(name); ckey.erase(name);
+     652           0 :   plumed_massert(found,"You are trying to remove " + name + " a component that isn't there");
+     653           0 : }
+     654             : 
+     655         224 : std::vector<std::string> Keywords::getOutputComponents() const {
+     656         224 :   return cnames;
+     657             : }
+     658             : 
+     659        4559 : std::string Keywords::getKeywordDescription( const std::string& key ) const {
+     660        9118 :   plumed_assert( exists( key ) ); return documentation.find(key)->second;
+     661             : }
+     662             : 
+     663             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.h.func-sort-c.html b/coverage/tools/Keywords.h.func-sort-c.html new file mode 100644 index 000000000000..8025159fb5b3 --- /dev/null +++ b/coverage/tools/Keywords.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Keywords.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:151788.2 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8KeywordsC2Ev110831
_ZNK4PLMD8Keywords7KeyType8toStringB5cxx11Ev988663
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.h.func.html b/coverage/tools/Keywords.h.func.html new file mode 100644 index 000000000000..8c59d015f3e0 --- /dev/null +++ b/coverage/tools/Keywords.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Keywords.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:151788.2 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD8KeywordsC2Ev110831
_ZNK4PLMD8Keywords7KeyType8toStringB5cxx11Ev988663
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Keywords.h.gcov.html b/coverage/tools/Keywords.h.gcov.html new file mode 100644 index 000000000000..e094da71745b --- /dev/null +++ b/coverage/tools/Keywords.h.gcov.html @@ -0,0 +1,261 @@ + + + + + + + + LCOV - plumed test coverage - tools/Keywords.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Keywords.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:151788.2 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Keywords_h
+      23             : #define __PLUMED_tools_Keywords_h
+      24             : #include <vector>
+      25             : #include <string>
+      26             : #include <set>
+      27             : #include <map>
+      28             : 
+      29             : #include "Exception.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : class Log;
+      34             : 
+      35             : /// This class holds the keywords and their documentation
+      36             : class Keywords {
+      37             : /// This class lets me pass keyword types easily
+      38             :   class KeyType {
+      39             :   public:
+      40             :     enum {hidden,compulsory,flag,optional,atoms,vessel} style;
+      41             :     explicit KeyType( const std::string& type );
+      42             :     void setStyle( const std::string& type );
+      43       16622 :     bool isCompulsory() const { return (style==compulsory); }
+      44       22421 :     bool isFlag() const { return (style==flag); }
+      45       17122 :     bool isOptional() const { return (style==optional); }
+      46      692340 :     bool isAtomList() const { return (style==atoms); }
+      47       18096 :     bool isVessel() const { return (style==vessel); }
+      48      988663 :     std::string toString() const {
+      49      988663 :       if(style==compulsory) return "compulsory";
+      50      227065 :       else if(style==optional) return "optional";
+      51      159522 :       else if(style==atoms) return "atoms";
+      52      422593 :       else if(style==flag) return "flag";
+      53       74281 :       else if(style==hidden) return "hidden";
+      54       22647 :       else if(style==vessel) return "vessel";
+      55           0 :       else plumed_assert(0);
+      56             :       return "";
+      57             :     }
+      58             :   };
+      59             :   friend class Action;
+      60             : private:
+      61             : /// Is this an action or driver (this bool affects what style==atoms does in print)
+      62             :   bool isaction;
+      63             : /// This allows us to overwrite the behavior of the atoms type in analysis actions
+      64             :   bool isatoms;
+      65             : /// The names of the allowed keywords
+      66             :   std::vector<std::string> keys;
+      67             : /// The names of the reserved keywords
+      68             :   std::vector<std::string> reserved_keys;
+      69             : /// Whether the keyword is compulsory, optional...
+      70             :   std::map<std::string,KeyType> types;
+      71             : /// Do we allow stuff like key1, key2 etc
+      72             :   std::map<std::string,bool> allowmultiple;
+      73             : /// The documentation for the keywords
+      74             :   std::map<std::string,std::string> documentation;
+      75             : /// The default values for the flags (are they on or of)
+      76             :   std::map<std::string,bool> booldefs;
+      77             : /// The default values (if there are default values) for compulsory keywords
+      78             :   std::map<std::string,std::string> numdefs;
+      79             : /// The tags for atoms - we use this so the manual can differentiate between different ways of specifying atoms
+      80             :   std::map<std::string,std::string> atomtags;
+      81             : /// The string that should be printed out to describe how the components work for this particular action
+      82             :   std::string cstring;
+      83             : /// The names of all the possible components for an action
+      84             :   std::vector<std::string> cnames;
+      85             : /// The keyword that turns on a particular component
+      86             :   std::map<std::string,std::string> ckey;
+      87             : /// The documentation for a particular component
+      88             :   std::map<std::string,std::string> cdocs;
+      89             : /// Print the documentation for the jth keyword in html
+      90             :   void print_html_item( const std::string& ) const;
+      91             : public:
+      92             : /// Constructor
+      93      110831 :   Keywords() : isaction(true), isatoms(true) {}
+      94             : ///
+      95        8374 :   void isDriver() { isaction=false; }
+      96             : ///
+      97         149 :   void isAnalysis() { isatoms=false; }
+      98             : /// find out whether flag key is on or off by default.
+      99             :   bool getLogicalDefault(const std::string & key, bool& def ) const ;
+     100             : /// Get the value of the default for the keyword named key
+     101             :   bool getDefaultValue(const std::string & key, std::string& def ) const ;
+     102             : /// Return the number of defined keywords
+     103             :   unsigned size() const;
+     104             : /// Check if numbered keywords are allowed for this action
+     105             :   bool numbered( const std::string & k ) const ;
+     106             : /// Return the ith keyword
+     107             :   std::string getKeyword( const unsigned i ) const ;
+     108             : /// Get the documentation for a particular keyword
+     109             :   std::string getKeywordDocs( const std::string& key ) const ;
+     110             : /// Print the documentation to the log file (used by PLMD::Action::error)
+     111             :   void print( Log& log ) const ;
+     112             : /// Print the documentation to a file (use by PLUMED::CLTool::readCommandLineArgs)
+     113             :   void print( FILE* out ) const ;
+     114             : /// Get the help string
+     115             :   std::string getHelpString() const ;
+     116             : /// Print a file containing the list of keywords for a particular action (used for spell checking)
+     117             :   void print_spelling() const ;
+     118             : /// Reserve a keyword
+     119             :   void reserve( const std::string & t, const std::string & k, const std::string & d );
+     120             : /// Reserve a flag
+     121             :   void reserveFlag( const std::string & k, const bool def, const std::string & d );
+     122             : /// Use one of the reserved keywords
+     123             :   void use( const std::string  & k );
+     124             : /// Get the ith keyword
+     125             :   std::string get( const unsigned k ) const ;
+     126             : /// Add a new keyword of type t with name k and description d
+     127             :   void add( const std::string & t, const std::string & k, const std::string & d );
+     128             : /// Add a new compulsory keyword (t must equal compulsory) with name k, default value def and description d
+     129             :   void add( const std::string & t, const std::string & k, const std::string & def, const std::string & d );
+     130             : /// Add a falg with name k that is by default on if def is true and off if def is false.  d should provide a description of the flag
+     131             :   void addFlag( const std::string & k, const bool def, const std::string & d );
+     132             : /// Remove the keyword with name k
+     133             :   void remove( const std::string & k );
+     134             : /// Check if there is a keyword with name k
+     135             :   bool exists( const std::string & k ) const ;
+     136             : /// Check the keyword k has been reserved
+     137             :   bool reserved( const std::string & k ) const ;
+     138             : /// Get the type for the keyword with string k
+     139             :   std::string getStyle( const std::string & k ) const ;
+     140             : /// Check if the keyword with name k has style t
+     141             :   bool style( const std::string & k, const std::string & t ) const ;
+     142             : /// Print an html version of the documentation
+     143             :   void print_html() const ;
+     144             : /// Print keywords in form readable by vim
+     145             :   void print_vim() const ;
+     146             : /// Print the template version for the documentation
+     147             :   void print_template( const std::string& actionname, bool include_optional) const ;
+     148             : /// Change the style of a keyword
+     149             :   void reset_style( const std::string & k, const std::string & style );
+     150             : /// Add keywords from one keyword object to another
+     151             :   void add( const Keywords& keys );
+     152             : /// Copy the keywords data
+     153             :   void copyData( std::vector<std::string>& kk, std::vector<std::string>& rk, std::map<std::string,KeyType>& tt, std::map<std::string,bool>& am,
+     154             :                  std::map<std::string,std::string>& docs, std::map<std::string,bool>& bools, std::map<std::string,std::string>& nums,
+     155             :                  std::map<std::string,std::string>& atags, std::vector<std::string>& cnam, std::map<std::string,std::string>& ck,
+     156             :                  std::map<std::string,std::string>& cd ) const ;
+     157             : /// Clear everything from the keywords object.
+     158             : /// Not actually needed if your Keywords object is going out of scope.
+     159             :   void destroyData();
+     160             : /// Set the text that introduces how the components for this action are introduced
+     161             :   void setComponentsIntroduction( const std::string& instr );
+     162             : /// Add a potential component which can be output by this particular action
+     163             :   void addOutputComponent( const std::string& name, const std::string& key, const std::string& descr );
+     164             : /// Has a component with this name been added?
+     165             :   bool outputComponentExists( const std::string& name, const bool& custom ) const ;
+     166             : /// Get the flag that forces this component to be calculated
+     167             :   std::string getOutputComponentFlag( const std::string& name ) const ;
+     168             : /// Get the description of this component
+     169             :   std::string getOutputComponentDescription( const std::string& name ) const ;
+     170             : /// Get the full list of output components
+     171             :   std::vector<std::string> getOutputComponents() const ;
+     172             : /// Get the description of a particular keyword
+     173             :   std::string getKeywordDescription( const std::string& name ) const ;
+     174             : /// Remove a component with a particular name from the keywords
+     175             :   void removeComponent( const std::string& name );
+     176             : /// Reference to keys
+     177           0 :   std::vector<std::string> getKeys() const { return keys; }
+     178             : /// Get the description of a particular keyword
+     179             :   std::string getTooltip( const std::string& name ) const ;
+     180             : };
+     181             : 
+     182             : }
+     183             : 
+     184             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LatticeReduction.cpp.func-sort-c.html b/coverage/tools/LatticeReduction.cpp.func-sort-c.html new file mode 100644 index 000000000000..fca601e4a22a --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/LatticeReduction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LatticeReduction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212382.9 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16LatticeReduction10isReduced2ERKNS_13VectorGenericILj3EEES4_S4_0
_ZN4PLMD16LatticeReduction7reduce2ERNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD16LatticeReduction10reduceSlowERNS_13TensorGenericILj3ELj3EEE1
_ZN4PLMD16LatticeReduction7reduce2ERNS_13VectorGenericILj3EEES3_S3_1
_ZN4PLMD16LatticeReduction9isReducedERKNS_13TensorGenericILj3ELj3EEE2
_ZN4PLMD16LatticeReduction9isReducedERKNS_13VectorGenericILj3EEES4_11
_ZN4PLMD16LatticeReduction6reduceERNS_13TensorGenericILj3ELj3EEE20623
_ZN4PLMD16LatticeReduction10reduceFastERNS_13TensorGenericILj3ELj3EEE20624
_ZN4PLMD16LatticeReduction6reduceERNS_13VectorGenericILj3EEES3_35366
_ZN4PLMD16LatticeReduction4sortEPNS_13VectorGenericILj3EEE55984
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LatticeReduction.cpp.func.html b/coverage/tools/LatticeReduction.cpp.func.html new file mode 100644 index 000000000000..98df97fe2f24 --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/LatticeReduction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LatticeReduction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212382.9 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16LatticeReduction10isReduced2ERKNS_13VectorGenericILj3EEES4_S4_0
_ZN4PLMD16LatticeReduction10reduceFastERNS_13TensorGenericILj3ELj3EEE20624
_ZN4PLMD16LatticeReduction10reduceSlowERNS_13TensorGenericILj3ELj3EEE1
_ZN4PLMD16LatticeReduction4sortEPNS_13VectorGenericILj3EEE55984
_ZN4PLMD16LatticeReduction6reduceERNS_13TensorGenericILj3ELj3EEE20623
_ZN4PLMD16LatticeReduction6reduceERNS_13VectorGenericILj3EEES3_35366
_ZN4PLMD16LatticeReduction7reduce2ERNS_13TensorGenericILj3ELj3EEE0
_ZN4PLMD16LatticeReduction7reduce2ERNS_13VectorGenericILj3EEES3_S3_1
_ZN4PLMD16LatticeReduction9isReducedERKNS_13TensorGenericILj3ELj3EEE2
_ZN4PLMD16LatticeReduction9isReducedERKNS_13VectorGenericILj3EEES4_11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LatticeReduction.cpp.gcov.html b/coverage/tools/LatticeReduction.cpp.gcov.html new file mode 100644 index 000000000000..180e68e434f0 --- /dev/null +++ b/coverage/tools/LatticeReduction.cpp.gcov.html @@ -0,0 +1,292 @@ + + + + + + + + LCOV - plumed test coverage - tools/LatticeReduction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LatticeReduction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10212382.9 %
Date:2024-02-22 21:58:45Functions:81080.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "LatticeReduction.h"
+      23             : #include "Exception.h"
+      24             : #include <cstdio>
+      25             : #include <cmath>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : const double epsilon=1e-14;
+      30             : 
+      31       55984 : void LatticeReduction::sort(Vector v[3]) {
+      32             :   const double onePlusEpsilon=(1.0+epsilon);
+      33             :   double m[3];
+      34       55984 :   m[0]=modulo2(v[0]);
+      35       55984 :   m[1]=modulo2(v[1]);
+      36       55984 :   m[2]=modulo2(v[2]);
+      37      391888 :   for(int i=0; i<3; i++) for(int j=i+1; j<3; j++) if(m[i]>m[j]) {
+      38       11757 :         std::swap(v[i],v[j]);
+      39             :         std::swap(m[i],m[j]);
+      40             :       }
+      41       55984 :   plumed_assert(m[0]<=m[1]*onePlusEpsilon);
+      42       55984 :   plumed_assert(m[1]<=m[2]*onePlusEpsilon);
+      43       55984 : }
+      44             : 
+      45       35366 : void LatticeReduction::reduce(Vector&a,Vector&b) {
+      46             :   const double onePlusEpsilon=(1.0+epsilon);
+      47       35366 :   double ma=modulo2(a);
+      48       35366 :   double mb=modulo2(b);
+      49             :   unsigned counter=0;
+      50             :   while(true) {
+      51       35927 :     if(mb>ma) {
+      52             :       std::swap(a,b);
+      53             :       std::swap(ma,mb);
+      54             :     }
+      55       35927 :     a-=b*floor(dotProduct(a,b)/mb+0.5);
+      56       35927 :     ma=modulo2(a);
+      57       35927 :     if(mb<=ma*onePlusEpsilon) break;
+      58         561 :     counter++;
+      59         561 :     if(counter%100==0) { // only test rarely since this might be expensive
+      60           0 :       plumed_assert(!std::isnan(ma));
+      61           0 :       plumed_assert(!std::isnan(mb));
+      62             :     }
+      63         561 :     if(counter%10000==0) std::fprintf(stderr,"WARNING: LatticeReduction::reduce stuck after %u iterations\n",counter);
+      64             :   }
+      65             : 
+      66             :   std::swap(a,b);
+      67       35366 : }
+      68             : 
+      69           1 : void LatticeReduction::reduce2(Vector&a,Vector&b,Vector&c) {
+      70           4 :   Vector v[3];
+      71           1 :   v[0]=a; v[1]=b; v[2]=c;
+      72             :   int iter=0;
+      73             :   int ok=0;
+      74          12 :   while(ok<3) {
+      75             :     int i,j;
+      76          11 :     if(iter%3==0) {
+      77             :       i=0; j=1;
+      78           7 :     } else if(iter%3==1) {
+      79             :       i=0; j=2;
+      80             :     } else {
+      81             :       i=1; j=2;
+      82             :     }
+      83          11 :     if(isReduced(v[i],v[j])) ok++;
+      84             :     else {
+      85           7 :       reduce(v[i],v[j]);
+      86             :       ok=1;
+      87             :     }
+      88          11 :     iter++;
+      89             :   }
+      90           1 :   a=v[0]; b=v[1]; c=v[2];
+      91           1 : }
+      92             : 
+      93          11 : bool LatticeReduction::isReduced(const Vector&a,const Vector&b) {
+      94             :   const int cut=5;
+      95          84 :   for(int i=-cut; i<=cut; i++) {
+      96          79 :     if(modulo2(b+i*a)<modulo2(b)) return false;
+      97             :   }
+      98           5 :   return modulo2(a)<=modulo2(b) && 2.0*dotProduct(a,b)<=modulo2(a);
+      99             : }
+     100             : 
+     101           0 : void LatticeReduction::reduce2(Tensor&t) {
+     102           0 :   Vector a=t.getRow(0);
+     103           0 :   Vector b=t.getRow(1);
+     104           0 :   Vector c=t.getRow(2);
+     105           0 :   reduce2(a,b,c);
+     106           0 :   t.setRow(0,a);
+     107           0 :   t.setRow(1,b);
+     108           0 :   t.setRow(2,c);
+     109           0 : }
+     110             : 
+     111       20623 : void LatticeReduction::reduce(Tensor&t) {
+     112       20623 :   reduceFast(t);
+     113       20623 : }
+     114             : 
+     115       20624 : void LatticeReduction::reduceFast(Tensor&t) {
+     116             :   const double onePlusEpsilon=(1.0+epsilon);
+     117       82496 :   Vector v[3];
+     118       20624 :   v[0]=t.getRow(0);
+     119       20624 :   v[1]=t.getRow(1);
+     120       20624 :   v[2]=t.getRow(2);
+     121             :   unsigned counter=0;
+     122             :   while(true) {
+     123       35359 :     sort(v);
+     124       35359 :     reduce(v[0],v[1]);
+     125       35359 :     double b11=modulo2(v[0]);
+     126       35359 :     double b22=modulo2(v[1]);
+     127       35359 :     double b12=dotProduct(v[0],v[1]);
+     128       35359 :     double b13=dotProduct(v[0],v[2]);
+     129       35359 :     double b23=dotProduct(v[1],v[2]);
+     130       35359 :     double z=b11*b22-b12*b12;
+     131       35359 :     double y2=-(b11*b23-b12*b13)/z;
+     132       35359 :     double y1=-(b22*b13-b12*b23)/z;
+     133       35359 :     int x1min=floor(y1);
+     134       35359 :     int x1max=x1min+1;
+     135       35359 :     int x2min=floor(y2);
+     136       35359 :     int x2max=x2min+1;
+     137             :     bool first=true;
+     138             :     double mbest,mtrial;
+     139       35359 :     Vector trial,best;
+     140      106077 :     for(int x1=x1min; x1<=x1max; x1++)
+     141      212154 :       for(int x2=x2min; x2<=x2max; x2++) {
+     142      141436 :         trial=v[2]+x2*v[1]+x1*v[0];
+     143      141436 :         mtrial=modulo2(trial);
+     144      141436 :         if(first || mtrial<mbest) {
+     145             :           mbest=mtrial;
+     146       42888 :           best=trial;
+     147             :           first=false;
+     148             :         }
+     149             :       }
+     150       35359 :     if(modulo2(best)*onePlusEpsilon>=modulo2(v[2])) break;
+     151       14735 :     counter++;
+     152       14735 :     if(counter%10000==0) std::fprintf(stderr,"WARNING: LatticeReduction::reduceFast stuck after %u iterations\n",counter);
+     153       14735 :     v[2]=best;
+     154       14735 :   }
+     155       20624 :   sort(v);
+     156       20624 :   t.setRow(0,v[0]);
+     157       20624 :   t.setRow(1,v[1]);
+     158       20624 :   t.setRow(2,v[2]);
+     159       20624 : }
+     160             : 
+     161             : 
+     162           1 : void LatticeReduction::reduceSlow(Tensor&t) {
+     163           4 :   Vector v[3];
+     164           1 :   v[0]=t.getRow(0);
+     165           1 :   v[1]=t.getRow(1);
+     166           1 :   v[2]=t.getRow(2);
+     167           1 :   reduce2(v[0],v[1],v[2]);
+     168           1 :   double e01=dotProduct(v[0],v[1]);
+     169           1 :   double e02=dotProduct(v[0],v[2]);
+     170           1 :   double e12=dotProduct(v[1],v[2]);
+     171           1 :   if(e01*e02*e12<0) {
+     172           0 :     int eps01=0; if(e01>0.0) eps01=1; else if(e01<0.0) eps01=-1;
+     173           0 :     int eps02=0; if(e02>0.0) eps02=1; else if(e02<0.0) eps02=-1;
+     174           0 :     Vector n=v[0]-eps01*v[1]-eps02*v[2];
+     175           0 :     int i=0; double mx=modulo2(v[i]);
+     176           0 :     for(int j=1; j<3; j++) {
+     177           0 :       double f=modulo2(v[j]);
+     178           0 :       if(f>mx) {
+     179             :         i=j;
+     180             :         mx=f;
+     181             :       }
+     182             :     }
+     183           0 :     if(modulo2(n)<mx) v[i]=n;
+     184             :   }
+     185           1 :   sort(v);
+     186           1 :   t.setRow(0,v[0]);
+     187           1 :   t.setRow(1,v[1]);
+     188           1 :   t.setRow(2,v[2]);
+     189           1 : }
+     190             : 
+     191           0 : bool LatticeReduction::isReduced2(const Vector&a,const Vector&b,const Vector &c) {
+     192           0 :   return isReduced(a,b) && isReduced(a,b) && isReduced(b,c);
+     193             : }
+     194             : 
+     195           2 : bool LatticeReduction::isReduced(const Tensor&t) {
+     196           8 :   Vector v[3];
+     197             :   double m[3];
+     198           2 :   v[0]=t.getRow(0);
+     199           2 :   v[1]=t.getRow(1);
+     200           2 :   v[2]=t.getRow(2);
+     201           8 :   for(int i=0; i<3; i++) m[i]=modulo2(v[i]);
+     202           2 :   if(!((m[0]<=m[1]) && m[1]<=m[2])) return false;
+     203             :   const int cut=5;
+     204          13 :   for(int i=-cut; i<=cut; i++) {
+     205          12 :     double mm=modulo2(v[1]+i*v[0]);
+     206          12 :     if(mm<m[1]) return false;
+     207         142 :     for(int j=-cut; j<=cut; j++) {
+     208         131 :       double mx=modulo2(v[2]+i*v[1]+j*v[0]);
+     209         131 :       if(mx<m[2])return false;
+     210             :     }
+     211             :   }
+     212             :   return true;
+     213             : }
+     214             : 
+     215             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.cpp.func-sort-c.html b/coverage/tools/LinkCells.cpp.func-sort-c.html new file mode 100644 index 000000000000..c5244250afe9 --- /dev/null +++ b/coverage/tools/LinkCells.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/LinkCells.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LinkCells.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838498.8 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD9LinkCells9getCutoffEv8
_ZN4PLMD9LinkCells9setCutoffERKd385
_ZN4PLMD9LinkCellsC2ERNS_12CommunicatorE705
_ZN4PLMD9LinkCells14buildCellListsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEERKNS_3PbcE1295
_ZNK4PLMD9LinkCells24retrieveNeighboringAtomsERKNS_13VectorGenericILj3EEERSt6vectorIjSaIjEERjS8_6576
_ZNK4PLMD9LinkCells16addRequiredCellsERKSt5arrayIjLm3EERjRSt6vectorIjSaIjEE228625
_ZNK4PLMD9LinkCells20retrieveAtomsInCellsERKjRKSt6vectorIjSaIjEERjRS5_228625
_ZNK4PLMD9LinkCells21convertIndicesToIndexERKjS2_S2_409838
_ZNK4PLMD9LinkCells8findCellERKNS_13VectorGenericILj3EEE409838
_ZNK4PLMD9LinkCells10findMyCellERKNS_13VectorGenericILj3EEE638463
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.cpp.func.html b/coverage/tools/LinkCells.cpp.func.html new file mode 100644 index 000000000000..a68a13c66b4a --- /dev/null +++ b/coverage/tools/LinkCells.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/LinkCells.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LinkCells.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838498.8 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9LinkCells14buildCellListsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IjSaIjEERKNS_3PbcE1295
_ZN4PLMD9LinkCells9setCutoffERKd385
_ZN4PLMD9LinkCellsC2ERNS_12CommunicatorE705
_ZNK4PLMD9LinkCells10findMyCellERKNS_13VectorGenericILj3EEE638463
_ZNK4PLMD9LinkCells16addRequiredCellsERKSt5arrayIjLm3EERjRSt6vectorIjSaIjEE228625
_ZNK4PLMD9LinkCells20retrieveAtomsInCellsERKjRKSt6vectorIjSaIjEERjRS5_228625
_ZNK4PLMD9LinkCells21convertIndicesToIndexERKjS2_S2_409838
_ZNK4PLMD9LinkCells24retrieveNeighboringAtomsERKNS_13VectorGenericILj3EEERSt6vectorIjSaIjEERjS8_6576
_ZNK4PLMD9LinkCells8findCellERKNS_13VectorGenericILj3EEE409838
_ZNK4PLMD9LinkCells9getCutoffEv8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.cpp.gcov.html b/coverage/tools/LinkCells.cpp.gcov.html new file mode 100644 index 000000000000..205630195670 --- /dev/null +++ b/coverage/tools/LinkCells.cpp.gcov.html @@ -0,0 +1,253 @@ + + + + + + + + LCOV - plumed test coverage - tools/LinkCells.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LinkCells.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838498.8 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "LinkCells.h"
+      23             : #include "Communicator.h"
+      24             : #include "Tools.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28         705 : LinkCells::LinkCells( Communicator& cc ) :
+      29         705 :   comm(cc),
+      30         705 :   cutoffwasset(false),
+      31         705 :   link_cutoff(0.0),
+      32         705 :   ncells(3),
+      33        1410 :   nstride(3)
+      34             : {
+      35         705 : }
+      36             : 
+      37         385 : void LinkCells::setCutoff( const double& lcut ) {
+      38         385 :   cutoffwasset=true; link_cutoff=lcut;
+      39         385 : }
+      40             : 
+      41           8 : double LinkCells::getCutoff() const {
+      42           8 :   plumed_assert( cutoffwasset ); return link_cutoff;
+      43             : }
+      44             : 
+      45        1295 : void LinkCells::buildCellLists( const std::vector<Vector>& pos, const std::vector<unsigned>& indices, const Pbc& pbc ) {
+      46        1295 :   plumed_assert( cutoffwasset && pos.size()==indices.size() );
+      47             : 
+      48             :   // Must be able to check that pbcs are not nonsensical in some way?? -- GAT
+      49             : 
+      50             :   // Setup the pbc object by copying it from action
+      51        1295 :   mypbc.setBox( pbc.getBox() );
+      52             : 
+      53             :   // Setup the lists
+      54        1295 :   if( pos.size()!=allcells.size() ) {
+      55         313 :     allcells.resize( pos.size() ); lcell_lists.resize( pos.size() );
+      56             :   }
+      57             : 
+      58             :   {
+      59             : // This is the reciprocal lattice
+      60             : // notice that reciprocal.getRow(0) is a vector that is orthogonal to b and c
+      61             : // This allows to use linked cells in non orthorhomic boxes
+      62        1295 :     Tensor reciprocal(transpose(mypbc.getInvBox()));
+      63        1295 :     ncells[0] = std::floor( 1.0/ reciprocal.getRow(0).modulo() / link_cutoff );
+      64        1295 :     if( ncells[0]==0 ) ncells[0]=1;
+      65        1295 :     ncells[1] = std::floor( 1.0/ reciprocal.getRow(1).modulo() / link_cutoff );
+      66        1295 :     if( ncells[1]==0 ) ncells[1]=1;
+      67        1295 :     ncells[2] = std::floor( 1.0/ reciprocal.getRow(2).modulo() / link_cutoff );
+      68        1295 :     if( ncells[2]==0 ) ncells[2]=1;
+      69             :   }
+      70             :   // Setup the strides
+      71        1295 :   nstride[0]=1; nstride[1]=ncells[0]; nstride[2]=ncells[0]*ncells[1];
+      72             : 
+      73             :   // Setup the storage for link cells
+      74        1295 :   unsigned ncellstot=ncells[0]*ncells[1]*ncells[2];
+      75        1295 :   if( lcell_tots.size()!=ncellstot ) {
+      76         303 :     lcell_tots.resize( ncellstot ); lcell_starts.resize( ncellstot );
+      77             :   }
+      78             :   // Clear nlcells
+      79      299783 :   for(unsigned i=0; i<ncellstot; ++i) lcell_tots[i]=0;
+      80             :   // Clear allcells
+      81        1295 :   allcells.assign( allcells.size(), 0 );
+      82             : 
+      83             :   // Find out what cell everyone is in
+      84        1295 :   unsigned rank=comm.Get_rank(), size=comm.Get_size();
+      85      411133 :   for(unsigned i=rank; i<pos.size(); i+=size) {
+      86      409838 :     allcells[i]=findCell( pos[i] );
+      87      409838 :     lcell_tots[allcells[i]]++;
+      88             :   }
+      89             :   // And gather all this information on every node
+      90        1295 :   comm.Sum( allcells ); comm.Sum( lcell_tots );
+      91             : 
+      92             :   // Now prepare the link cell lists
+      93             :   unsigned tot=0;
+      94      299783 :   for(unsigned i=0; i<lcell_tots.size(); ++i) { lcell_starts[i]=tot; tot+=lcell_tots[i]; lcell_tots[i]=0; }
+      95        1295 :   plumed_assert( tot==pos.size() );
+      96             : 
+      97             :   // And setup the link cells properly
+      98      456412 :   for(unsigned j=0; j<pos.size(); ++j) {
+      99      455117 :     unsigned myind = lcell_starts[ allcells[j] ] + lcell_tots[ allcells[j] ];
+     100      455117 :     lcell_lists[ myind ] = indices[j];
+     101      455117 :     lcell_tots[allcells[j]]++;
+     102             :   }
+     103        1295 : }
+     104             : 
+     105             : #define LINKC_MIN(n) ((n<2)? 0 : -1)
+     106             : #define LINKC_MAX(n) ((n<3)? 1 : 2)
+     107             : #define LINKC_PBC(n,num) ((n<0)? num-1 : n%num )
+     108             : 
+     109      228625 : void LinkCells::addRequiredCells( const std::array<unsigned,3>& celn, unsigned& ncells_required,
+     110             :                                   std::vector<unsigned>& cells_required ) const {
+     111             :   unsigned nnew_cells=0;
+     112     1349319 :   for(int nx=LINKC_MIN(ncells[0]); nx<LINKC_MAX(ncells[0]); ++nx) {
+     113      450285 :     int xval = celn[0] + nx;
+     114      450285 :     xval=LINKC_PBC(xval,ncells[0])*nstride[0];
+     115     3335829 :     for(int ny=LINKC_MIN(ncells[1]); ny<LINKC_MAX(ncells[1]); ++ny) {
+     116     1113267 :       int yval = celn[1] + ny;
+     117     1113267 :       yval=LINKC_PBC(yval,ncells[1])*nstride[1];
+     118     9262274 :       for(int nz=LINKC_MIN(ncells[2]); nz<LINKC_MAX(ncells[2]); ++nz) {
+     119     3090884 :         int zval = celn[2] + nz;
+     120     3090884 :         zval=LINKC_PBC(zval,ncells[2])*nstride[2];
+     121             : 
+     122     3090884 :         unsigned mybox=xval+yval+zval; bool added=false;
+     123     3090884 :         for(unsigned k=0; k<ncells_required; ++k) {
+     124           0 :           if( mybox==cells_required[k] ) { added=true; break; }
+     125             :         }
+     126     3090884 :         if( !added ) { cells_required[ncells_required+nnew_cells]=mybox; nnew_cells++; }
+     127             :       }
+     128             :     }
+     129             :   }
+     130      228625 :   ncells_required += nnew_cells;
+     131      228625 : }
+     132             : 
+     133        6576 : void LinkCells::retrieveNeighboringAtoms( const Vector& pos, std::vector<unsigned>& cell_list,
+     134             :     unsigned& natomsper, std::vector<unsigned>& atoms ) const {
+     135        6576 :   if( cell_list.size()!=getNumberOfCells() ) cell_list.resize( getNumberOfCells() );
+     136        6576 :   unsigned ncellt=0; addRequiredCells( findMyCell( pos ), ncellt, cell_list );
+     137        6576 :   retrieveAtomsInCells( ncellt, cell_list, natomsper, atoms );
+     138        6576 : }
+     139             : 
+     140      228625 : void LinkCells::retrieveAtomsInCells( const unsigned& ncells_required,
+     141             :                                       const std::vector<unsigned>& cells_required,
+     142             :                                       unsigned& natomsper, std::vector<unsigned>& atoms ) const {
+     143      228625 :   plumed_assert( natomsper==1 || natomsper==2 );  // This is really a bug. If you are trying to reuse this ask GAT for help
+     144     3319509 :   for(unsigned i=0; i<ncells_required; ++i) {
+     145     3090884 :     unsigned mybox=cells_required[i];
+     146   405181068 :     for(unsigned k=0; k<lcell_tots[mybox]; ++k) {
+     147   402090184 :       unsigned myatom = lcell_lists[lcell_starts[mybox]+k];
+     148   402090184 :       if( myatom!=atoms[0] ) { // Ideally would provide an option to not do this
+     149   401907298 :         atoms[natomsper]=myatom;
+     150   401907298 :         natomsper++;
+     151             :       }
+     152             :     }
+     153             :   }
+     154      228625 : }
+     155             : 
+     156      638463 : std::array<unsigned,3> LinkCells::findMyCell( const Vector& pos ) const {
+     157      638463 :   Vector fpos=mypbc.realToScaled( pos );
+     158             :   std::array<unsigned,3> celn;
+     159     2553852 :   for(unsigned j=0; j<3; ++j) {
+     160     1915389 :     celn[j] = std::floor( ( Tools::pbc(fpos[j]) + 0.5 ) * ncells[j] );
+     161     1915389 :     plumed_assert( celn[j]>=0 && celn[j]<ncells[j] ); // Check that atom is in box
+     162             :   }
+     163      638463 :   return celn;
+     164             : }
+     165             : 
+     166      409838 : unsigned LinkCells::convertIndicesToIndex( const unsigned& nx, const unsigned& ny, const unsigned& nz ) const {
+     167      409838 :   return nx*nstride[0] + ny*nstride[1] + nz*nstride[2];
+     168             : }
+     169             : 
+     170      409838 : unsigned LinkCells::findCell( const Vector& pos ) const {
+     171      409838 :   std::array<unsigned,3> celn( findMyCell(pos ) );
+     172      409838 :   return convertIndicesToIndex( celn[0], celn[1], celn[2] );
+     173             : }
+     174             : 
+     175             : 
+     176             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.h.func-sort-c.html b/coverage/tools/LinkCells.h.func-sort-c.html new file mode 100644 index 000000000000..3f476951110e --- /dev/null +++ b/coverage/tools/LinkCells.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/LinkCells.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LinkCells.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.h.func.html b/coverage/tools/LinkCells.h.func.html new file mode 100644 index 000000000000..aed2bd6e7dec --- /dev/null +++ b/coverage/tools/LinkCells.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/LinkCells.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LinkCells.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LinkCells.h.gcov.html b/coverage/tools/LinkCells.h.gcov.html new file mode 100644 index 000000000000..86df6dd3af00 --- /dev/null +++ b/coverage/tools/LinkCells.h.gcov.html @@ -0,0 +1,176 @@ + + + + + + + + LCOV - plumed test coverage - tools/LinkCells.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LinkCells.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_LinkCells_h
+      23             : #define __PLUMED_tools_LinkCells_h
+      24             : 
+      25             : #include <vector>
+      26             : #include "Vector.h"
+      27             : #include "Pbc.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : class Communicator;
+      32             : 
+      33             : /// \ingroup TOOLBOX
+      34             : /// A class for doing link cells
+      35             : class LinkCells {
+      36             : private:
+      37             : /// Symbolic link to plumed communicator
+      38             :   Communicator & comm;
+      39             : /// Check that the link cells were set up correctly
+      40             :   bool cutoffwasset;
+      41             : /// The cutoff to use for the sizes of the cells
+      42             :   double link_cutoff;
+      43             : /// The pbc we are using for link cells
+      44             :   Pbc mypbc;
+      45             : /// The number of cells in each direction
+      46             :   std::vector<unsigned> ncells;
+      47             : /// The number of cells to stride through to get the link cells
+      48             :   std::vector<unsigned> nstride;
+      49             : /// The list of cells each atom is inside
+      50             :   std::vector<unsigned> allcells;
+      51             : /// The start of each block corresponding to each link cell
+      52             :   std::vector<unsigned> lcell_starts;
+      53             : /// The number of atoms in each link cell
+      54             :   std::vector<unsigned> lcell_tots;
+      55             : /// The atoms ordered by link cells
+      56             :   std::vector<unsigned> lcell_lists;
+      57             : public:
+      58             : ///
+      59             :   explicit LinkCells( Communicator& comm );
+      60             : /// Have the link cells been enabled
+      61             :   bool enabled() const ;
+      62             : /// Set the value of the cutoff
+      63             :   void setCutoff( const double& lcut );
+      64             : /// Get the value of the cutoff
+      65             :   double getCutoff() const ;
+      66             : /// Get the total number of link cells
+      67             :   unsigned getNumberOfCells() const ;
+      68             : /// Build the link cell lists
+      69             :   void buildCellLists( const std::vector<Vector>& pos, const std::vector<unsigned>& indices, const Pbc& pbc );
+      70             : /// Take three indices and return the index of the corresponding cell
+      71             :   unsigned convertIndicesToIndex( const unsigned& nx, const unsigned& ny, const unsigned& nz ) const ;
+      72             : /// Find the cell index in which this position is contained
+      73             :   unsigned findCell( const Vector& pos ) const ;
+      74             : /// Find the cell in which this position is contained
+      75             :   std::array<unsigned,3> findMyCell( const Vector& pos ) const ;
+      76             : /// Get the list of cells we need to surround the a particular cell
+      77             :   void addRequiredCells( const std::array<unsigned,3>& celn, unsigned& ncells_required,
+      78             :                          std::vector<unsigned>& cells_required ) const ;
+      79             : /// Retrieve the atoms in a list of cells
+      80             :   void retrieveAtomsInCells( const unsigned& ncells_required,
+      81             :                              const std::vector<unsigned>& cells_required,
+      82             :                              unsigned& natomsper, std::vector<unsigned>& atoms ) const ;
+      83             : /// Retrieve the atoms we need to consider
+      84             :   void retrieveNeighboringAtoms( const Vector& pos, std::vector<unsigned>& cell_list, unsigned& natomsper, std::vector<unsigned>& atoms ) const ;
+      85             : };
+      86             : 
+      87             : inline
+      88             : bool LinkCells::enabled() const {
+      89        1940 :   return cutoffwasset;
+      90             : }
+      91             : 
+      92             : inline
+      93             : unsigned LinkCells::getNumberOfCells() const {
+      94      228625 :   return ncells[0]*ncells[1]*ncells[2];
+      95             : }
+      96             : 
+      97             : }
+      98             : 
+      99             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LoopUnroller.h.func-sort-c.html b/coverage/tools/LoopUnroller.h.func-sort-c.html new file mode 100644 index 000000000000..b37b1f9981d4 --- /dev/null +++ b/coverage/tools/LoopUnroller.h.func-sort-c.html @@ -0,0 +1,281 @@ + + + + + + + + LCOV - plumed test coverage - tools/LoopUnroller.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LoopUnroller.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-02-22 21:58:45Functions:5252100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12LoopUnrollerILj4EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj5EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj6EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj7EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj8EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj9EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj13EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj14EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj15EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj16EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj4EE5_sum2EPKd1119102
_ZN4PLMD12LoopUnrollerILj10EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj11EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj12EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj4EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj5EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj6EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj7EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj8EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj9EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj5EE4_subEPdPKd47074857
_ZN4PLMD12LoopUnrollerILj6EE4_subEPdPKd47074857
_ZN4PLMD12LoopUnrollerILj7EE4_subEPdPKd47074857
_ZN4PLMD12LoopUnrollerILj8EE4_subEPdPKd47074857
_ZN4PLMD12LoopUnrollerILj9EE4_subEPdPKd47074857
_ZN4PLMD12LoopUnrollerILj4EE4_subEPdPKd48193959
_ZN4PLMD12LoopUnrollerILj7EE5_zeroEPd52220918
_ZN4PLMD12LoopUnrollerILj8EE5_zeroEPd52220918
_ZN4PLMD12LoopUnrollerILj9EE5_zeroEPd52220918
_ZN4PLMD12LoopUnrollerILj5EE5_zeroEPd52224922
_ZN4PLMD12LoopUnrollerILj6EE5_zeroEPd52224922
_ZN4PLMD12LoopUnrollerILj4EE5_zeroEPd54521368
_ZN4PLMD12LoopUnrollerILj2EE4_negEPdPKd107493248
_ZN4PLMD12LoopUnrollerILj3EE4_negEPdPKd107493248
_ZN4PLMD12LoopUnrollerILj4EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj5EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj6EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj7EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj8EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj9EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj2EE4_dotEPKdS3_166523689
_ZN4PLMD12LoopUnrollerILj3EE4_dotEPKdS3_166523689
_ZN4PLMD12LoopUnrollerILj2EE5_zeroEPd542181367
_ZN4PLMD12LoopUnrollerILj3EE5_zeroEPd542181367
_ZN4PLMD12LoopUnrollerILj2EE5_sum2EPKd784204072
_ZN4PLMD12LoopUnrollerILj3EE5_sum2EPKd784204072
_ZN4PLMD12LoopUnrollerILj2EE4_subEPdPKd1263618990
_ZN4PLMD12LoopUnrollerILj3EE4_subEPdPKd1263618990
_ZN4PLMD12LoopUnrollerILj2EE4_addEPdPKd1783763131
_ZN4PLMD12LoopUnrollerILj3EE4_addEPdPKd1783763131
_ZN4PLMD12LoopUnrollerILj2EE4_mulEPdd1983268160
_ZN4PLMD12LoopUnrollerILj3EE4_mulEPdd1983268160
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LoopUnroller.h.func.html b/coverage/tools/LoopUnroller.h.func.html new file mode 100644 index 000000000000..781ed276c44b --- /dev/null +++ b/coverage/tools/LoopUnroller.h.func.html @@ -0,0 +1,281 @@ + + + + + + + + LCOV - plumed test coverage - tools/LoopUnroller.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LoopUnroller.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-02-22 21:58:45Functions:5252100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12LoopUnrollerILj10EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj11EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj12EE5_zeroEPd10861654
_ZN4PLMD12LoopUnrollerILj13EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj14EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj15EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj16EE5_zeroEPd608260
_ZN4PLMD12LoopUnrollerILj2EE4_addEPdPKd1783763131
_ZN4PLMD12LoopUnrollerILj2EE4_dotEPKdS3_166523689
_ZN4PLMD12LoopUnrollerILj2EE4_mulEPdd1983268160
_ZN4PLMD12LoopUnrollerILj2EE4_negEPdPKd107493248
_ZN4PLMD12LoopUnrollerILj2EE4_subEPdPKd1263618990
_ZN4PLMD12LoopUnrollerILj2EE5_sum2EPKd784204072
_ZN4PLMD12LoopUnrollerILj2EE5_zeroEPd542181367
_ZN4PLMD12LoopUnrollerILj3EE4_addEPdPKd1783763131
_ZN4PLMD12LoopUnrollerILj3EE4_dotEPKdS3_166523689
_ZN4PLMD12LoopUnrollerILj3EE4_mulEPdd1983268160
_ZN4PLMD12LoopUnrollerILj3EE4_negEPdPKd107493248
_ZN4PLMD12LoopUnrollerILj3EE4_subEPdPKd1263618990
_ZN4PLMD12LoopUnrollerILj3EE5_sum2EPKd784204072
_ZN4PLMD12LoopUnrollerILj3EE5_zeroEPd542181367
_ZN4PLMD12LoopUnrollerILj4EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj4EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj4EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj4EE4_subEPdPKd48193959
_ZN4PLMD12LoopUnrollerILj4EE5_sum2EPKd1119102
_ZN4PLMD12LoopUnrollerILj4EE5_zeroEPd54521368
_ZN4PLMD12LoopUnrollerILj5EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj5EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj5EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj5EE4_subEPdPKd47074857
_ZN4PLMD12LoopUnrollerILj5EE5_zeroEPd52224922
_ZN4PLMD12LoopUnrollerILj6EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj6EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj6EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj6EE4_subEPdPKd47074857
_ZN4PLMD12LoopUnrollerILj6EE5_zeroEPd52224922
_ZN4PLMD12LoopUnrollerILj7EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj7EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj7EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj7EE4_subEPdPKd47074857
_ZN4PLMD12LoopUnrollerILj7EE5_zeroEPd52220918
_ZN4PLMD12LoopUnrollerILj8EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj8EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj8EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj8EE4_subEPdPKd47074857
_ZN4PLMD12LoopUnrollerILj8EE5_zeroEPd52220918
_ZN4PLMD12LoopUnrollerILj9EE4_addEPdPKd42578202
_ZN4PLMD12LoopUnrollerILj9EE4_mulEPdd155360273
_ZN4PLMD12LoopUnrollerILj9EE4_negEPdPKd63485
_ZN4PLMD12LoopUnrollerILj9EE4_subEPdPKd47074857
_ZN4PLMD12LoopUnrollerILj9EE5_zeroEPd52220918
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/LoopUnroller.h.gcov.html b/coverage/tools/LoopUnroller.h.gcov.html new file mode 100644 index 000000000000..2f4f9700bd44 --- /dev/null +++ b/coverage/tools/LoopUnroller.h.gcov.html @@ -0,0 +1,237 @@ + + + + + + + + LCOV - plumed test coverage - tools/LoopUnroller.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - LoopUnroller.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3131100.0 %
Date:2024-02-22 21:58:45Functions:5252100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_LoopUnroller_h
+      23             : #define __PLUMED_tools_LoopUnroller_h
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27             : /**
+      28             : \ingroup TOOLBOX
+      29             : Utiliy class for loop unrolling.
+      30             : 
+      31             : Many c++ compilers do not unroll small loops such as those
+      32             : used in the PLMD::Vector and PLMD::Tensor classes.
+      33             : This class provides methods to perform basic vector
+      34             : operations with unrolled loops. The methods work on double*
+      35             : so that they can be used in principles in other places of the code,
+      36             : but they are designed to be used in PLMD::Vector and PLMD::Tensor .
+      37             : 
+      38             : In case in the future we see that some compiler better optimize explicit loops,
+      39             : it should be easy to replace the methods here with loops. Alternatively,
+      40             : we could provide two paths using a cpp macro (e.g. __PLUMED_UNROLL_LOOPS or so).
+      41             : 
+      42             : All the methods for class LoopUnroller<n> act on n elements.
+      43             : Implementation is made using template metaprogramming, that is:
+      44             : - LoopUnroller<1>::xxx acts on the element [0] of the array.
+      45             : - LoopUnroller<n>::xxx calls LoopUnroller<n-1>::xxx then acts on element [n-1] of the array.
+      46             : 
+      47             : Here xxx is any of the methods of the class.
+      48             : 
+      49             : */
+      50             : template<unsigned n>
+      51             : class LoopUnroller {
+      52             : public:
+      53             : /// Set to zero.
+      54             : /// Same as `for(unsigned i=0;i<n;i++) d[i]=0.0;`
+      55             :   static void _zero(double*d);
+      56             : /// Add v to d.
+      57             : /// Same as `for(unsigned i=0;i<n;i++) d[i]+=v[i];`
+      58             :   static void _add(double*d,const double*v);
+      59             : /// Subtract v from d.
+      60             : /// Same as `for(unsigned i=0;i<n;i++) d[i]-=v[i];`
+      61             :   static void _sub(double*d,const double*v);
+      62             : /// Multiply d by s.
+      63             : /// Same as `for(unsigned i=0;i<n;i++) d[i]*=s;`
+      64             :   static void _mul(double*d,const double s);
+      65             : /// Set d to -v.
+      66             : /// Same as `for(unsigned i=0;i<n;i++) d[i]=-v[i];`
+      67             :   static void _neg(double*d,const double*v);
+      68             : /// Squared modulo of d;
+      69             : /// Same as `r=0.0; for(unsigned i=0;i<n;i++) r+=d[i]*d[i]; return r;`
+      70             :   static double _sum2(const double*d);
+      71             : /// Dot product of d and v
+      72             : /// Same as `r=0.0; for(unsigned i=0;i<n;i++) r+=d[i]*v[i]; return r;`
+      73             :   static double _dot(const double*d,const double*v);
+      74             : };
+      75             : 
+      76             : template<unsigned n>
+      77  1435014702 : void LoopUnroller<n>::_zero(double*d) {
+      78   892833335 :   LoopUnroller<n-1>::_zero(d);
+      79  1435014702 :   d[n-1]=0.0;
+      80  1435014702 : }
+      81             : 
+      82             : template<>
+      83             : inline
+      84             : void LoopUnroller<1>::_zero(double*d) {
+      85   542730287 :   d[0]=0.0;
+      86             : }
+      87             : 
+      88             : template<unsigned n>
+      89  3822995474 : void LoopUnroller<n>::_add(double*d,const double*a) {
+      90  2039232343 :   LoopUnroller<n-1>::_add(d,a);
+      91  3822995474 :   d[n-1]+=a[n-1];
+      92  3822995474 : }
+      93             : 
+      94             : template<>
+      95             : inline
+      96             : void LoopUnroller<1>::_add(double*d,const double*a) {
+      97  1783763131 :   d[0]+=a[0];
+      98             : }
+      99             : 
+     100             : template<unsigned n>
+     101  2810806224 : void LoopUnroller<n>::_sub(double*d,const double*a) {
+     102  1547187234 :   LoopUnroller<n-1>::_sub(d,a);
+     103  2810806224 :   d[n-1]-=a[n-1];
+     104  2810806224 : }
+     105             : 
+     106             : template<>
+     107             : inline
+     108             : void LoopUnroller<1>::_sub(double*d,const double*a) {
+     109  1263618990 :   d[0]-=a[0];
+     110             : }
+     111             : 
+     112             : template<unsigned n>
+     113  4898697958 : void LoopUnroller<n>::_mul(double*d,const double s) {
+     114  2915429798 :   LoopUnroller<n-1>::_mul(d,s);
+     115  4898697958 :   d[n-1]*=s;
+     116  4898697958 : }
+     117             : 
+     118             : template<>
+     119             : inline
+     120             : void LoopUnroller<1>::_mul(double*d,const double s) {
+     121  1983268160 :   d[0]*=s;
+     122             : }
+     123             : 
+     124             : template<unsigned n>
+     125   215367406 : void LoopUnroller<n>::_neg(double*d,const double*a ) {
+     126   107874158 :   LoopUnroller<n-1>::_neg(d,a);
+     127   215367406 :   d[n-1]=-a[n-1];
+     128   215367406 : }
+     129             : 
+     130             : template<>
+     131             : inline
+     132             : void LoopUnroller<1>::_neg(double*d,const double*a) {
+     133   107493248 :   d[0]=-a[0];
+     134             : }
+     135             : 
+     136             : template<unsigned n>
+     137  1569527246 : double LoopUnroller<n>::_sum2(const double*d) {
+     138  1569527246 :   return LoopUnroller<n-1>::_sum2(d)+d[n-1]*d[n-1];
+     139             : }
+     140             : 
+     141             : template<>
+     142             : inline
+     143             : double LoopUnroller<1>::_sum2(const double*d) {
+     144   784204072 :   return d[0]*d[0];
+     145             : }
+     146             : 
+     147             : template<unsigned n>
+     148   333047378 : double LoopUnroller<n>::_dot(const double*d,const double*v) {
+     149   333047378 :   return LoopUnroller<n-1>::_dot(d,v)+d[n-1]*v[n-1];
+     150             : }
+     151             : 
+     152             : template<>
+     153             : inline
+     154             : double LoopUnroller<1>::_dot(const double*d,const double*v) {
+     155   166523689 :   return d[0]*v[0];
+     156             : }
+     157             : 
+     158             : }
+     159             : 
+     160             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Matrix.h.func-sort-c.html b/coverage/tools/Matrix.h.func-sort-c.html new file mode 100644 index 000000000000..bd300c04a355 --- /dev/null +++ b/coverage/tools/Matrix.h.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/Matrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Matrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:140140100.0 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12pseudoInvertIdEEiRKNS_6MatrixIT_EERNS1_IdEE1
_ZN4PLMD6MatrixIdE13setFromVectorERKSt6vectorIdSaIdEE4
_ZN4PLMDmlIdEENS_6MatrixIT_EERS2_RKS3_12
_ZN4PLMD6logdetIdEEiRKNS_6MatrixIT_EERd46
_ZN4PLMD6MatrixIdEmLERKd112
_ZN4PLMD8choleskyIdEEvRKNS_6MatrixIT_EERS3_446
_ZN4PLMD4multIdEEvRKNS_6MatrixIT_EERKSt6vectorIS2_SaIS2_EERS8_2141
_ZN4PLMD6InvertIdEEiRKNS_6MatrixIT_EERNS1_IdEE9383
_ZN4PLMD4multIdEEvRKNS_6MatrixIT_EES5_RS3_13725
_ZN4PLMD7diagMatIdEEiRKNS_6MatrixIT_EERSt6vectorIdSaIdEERNS1_IdEE14151
_ZNK4PLMD6MatrixIdE11isSymmetricEv23980
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Matrix.h.func.html b/coverage/tools/Matrix.h.func.html new file mode 100644 index 000000000000..21d8b4f84731 --- /dev/null +++ b/coverage/tools/Matrix.h.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/Matrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Matrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:140140100.0 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12pseudoInvertIdEEiRKNS_6MatrixIT_EERNS1_IdEE1
_ZN4PLMD4multIdEEvRKNS_6MatrixIT_EERKSt6vectorIS2_SaIS2_EERS8_2141
_ZN4PLMD4multIdEEvRKNS_6MatrixIT_EES5_RS3_13725
_ZN4PLMD6InvertIdEEiRKNS_6MatrixIT_EERNS1_IdEE9383
_ZN4PLMD6MatrixIdE13setFromVectorERKSt6vectorIdSaIdEE4
_ZN4PLMD6MatrixIdEmLERKd112
_ZN4PLMD6logdetIdEEiRKNS_6MatrixIT_EERd46
_ZN4PLMD7diagMatIdEEiRKNS_6MatrixIT_EERSt6vectorIdSaIdEERNS1_IdEE14151
_ZN4PLMD8choleskyIdEEvRKNS_6MatrixIT_EERS3_446
_ZN4PLMDmlIdEENS_6MatrixIT_EERS2_RKS3_12
_ZNK4PLMD6MatrixIdE11isSymmetricEv23980
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Matrix.h.gcov.html b/coverage/tools/Matrix.h.gcov.html new file mode 100644 index 000000000000..11bff3fc00ca --- /dev/null +++ b/coverage/tools/Matrix.h.gcov.html @@ -0,0 +1,491 @@ + + + + + + + + LCOV - plumed test coverage - tools/Matrix.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Matrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:140140100.0 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Matrix_h
+      23             : #define __PLUMED_tools_Matrix_h
+      24             : #include <vector>
+      25             : #include <string>
+      26             : #include <set>
+      27             : #include <cmath>
+      28             : #include "Exception.h"
+      29             : #include "MatrixSquareBracketsAccess.h"
+      30             : #include "Tools.h"
+      31             : #include "Log.h"
+      32             : #include "lapack/lapack.h"
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : /// Calculate the dot product between two vectors
+      37             : template <typename T> T dotProduct( const std::vector<T>& A, const std::vector<T>& B ) {
+      38             :   plumed_assert( A.size()==B.size() );
+      39             :   T val; for(unsigned i=0; i<A.size(); ++i) { val+=A[i]*B[i]; }
+      40             :   return val;
+      41             : }
+      42             : 
+      43             : /// Calculate the dot product between a vector and itself
+      44             : template <typename T> T norm( const std::vector<T>& A ) {
+      45             :   T val; for(unsigned i=0; i<A.size(); ++i) { val+=A[i]*A[i]; }
+      46             :   return val;
+      47             : }
+      48             : 
+      49             : /// This class stores a full matrix and allows one to do some simple matrix operations
+      50             : template <typename T>
+      51     9736587 : class Matrix:
+      52             :   public MatrixSquareBracketsAccess<Matrix<T>,T>
+      53             : {
+      54             :   /// Multiply matrix by scalar
+      55             :   template <typename U> friend Matrix<U> operator*(U&, const Matrix<U>& );
+      56             :   /// Matrix matrix multiply
+      57             :   template <typename U> friend void mult( const Matrix<U>&, const Matrix<U>&, Matrix<U>& );
+      58             :   /// Matrix times a std::vector
+      59             :   template <typename U> friend void mult( const Matrix<U>&, const std::vector<U>&, std::vector<U>& );
+      60             :   /// std::vector times a Matrix
+      61             :   template <typename U> friend void mult( const std::vector<U>&, const Matrix<U>&, std::vector<U>& );
+      62             :   /// Matrix transpose
+      63             :   template <typename U> friend void transpose( const Matrix<U>&, Matrix<U>& );
+      64             :   /// Output the entire matrix on a single line
+      65             :   template <typename U> friend Log& operator<<(Log&, const Matrix<U>& );
+      66             :   /// Output the Matrix in matrix form
+      67             :   template <typename U> friend void matrixOut( Log&, const Matrix<U>& );
+      68             :   /// Diagonalize a symmetric matrix - returns zero if diagonalization worked
+      69             :   template <typename U> friend int diagMat( const Matrix<U>&, std::vector<double>&, Matrix<double>& );
+      70             :   /// Calculate the Moore-Penrose Pseudoinverse of a matrix
+      71             :   template <typename U> friend int pseudoInvert( const Matrix<U>&, Matrix<double>& );
+      72             :   /// Calculate the logarithm of the determinant of a symmetric matrix - returns zero if succesfull
+      73             :   template <typename U> friend int logdet( const Matrix<U>&, double& );
+      74             :   /// Invert a matrix (works for both symmetric and asymmetric matrices) - returns zero if sucesfull
+      75             :   template <typename U> friend int Invert( const Matrix<U>&, Matrix<double>& );
+      76             :   /// Do a cholesky decomposition of a matrix
+      77             :   template <typename U> friend void cholesky( const Matrix<U>&, Matrix<U>& );
+      78             :   /// Solve a system of equations using the cholesky decomposition
+      79             :   template <typename U> friend void chol_elsolve( const Matrix<U>&, const std::vector<U>&, std::vector<U>& );
+      80             : private:
+      81             :   /// Number of elements in matrix (nrows*ncols)
+      82             :   unsigned sz;
+      83             :   /// Number of rows in matrix
+      84             :   unsigned rw;
+      85             :   /// Number of columns in matrix
+      86             :   unsigned cl;
+      87             :   /// The data in the matrix
+      88             :   std::vector<T> data;
+      89             : public:
+      90    10723153 :   explicit Matrix(const unsigned nr=0, const unsigned nc=0 )  : sz(nr*nc), rw(nr), cl(nc), data(nr*nc) {}
+      91         259 :   Matrix(const Matrix<T>& t) : sz(t.sz), rw(t.rw), cl(t.cl), data(t.data) {}
+      92             :   /// Resize the matrix
+      93         332 :   void resize( const unsigned nr, const unsigned nc ) { rw=nr; cl=nc; sz=nr*nc; data.resize(sz); }
+      94             :   /// Return the number of rows
+      95    37740101 :   inline unsigned nrows() const { return rw; }
+      96             :   /// Return the number of columns
+      97   116551156 :   inline unsigned ncols() const { return cl; }
+      98             :   /// Return the contents of the matrix as a vector of length rw*cl
+      99          26 :   inline std::vector<T>& getVector() { return data; }
+     100             :   /// Set the matrix from a vector input
+     101         908 :   inline void setFromVector( const std::vector<T>& vecin ) { plumed_assert( vecin.size()==sz ); for(unsigned i=0; i<sz; ++i) data[i]=vecin[i]; }
+     102             :   /// Return element i,j of the matrix
+     103  2267477073 :   inline const T& operator () (const unsigned& i, const unsigned& j) const { return data[j+i*cl]; }
+     104             :   /// Return a referenre to element i,j of the matrix
+     105   231234462 :   inline T& operator () (const unsigned& i, const unsigned& j)      { return data[j+i*cl]; }
+     106             :   /// Set all elements of the matrix equal to the value of v
+     107             :   Matrix<T>& operator=(const T& v) {
+     108     6748667 :     for(unsigned i=0; i<sz; ++i) { data[i]=v; }
+     109             :     return *this;
+     110             :   }
+     111             :   /// Set the Matrix equal to another Matrix
+     112             :   Matrix<T>& operator=(const Matrix<T>& m) {
+     113        5208 :     sz=m.sz;
+     114        5208 :     rw=m.rw;
+     115        5208 :     cl=m.cl;
+     116        5208 :     data=m.data;
+     117        5208 :     return *this;
+     118             :   }
+     119             :   /// Set the Matrix equal to the value of a standard vector - used for readin
+     120             :   Matrix<T>& operator=(const std::vector<T>& v) {
+     121             :     plumed_dbg_assert( v.size()==sz );
+     122             :     for(unsigned i=0; i<sz; ++i) { data[i]=v[i]; }
+     123             :     return *this;
+     124             :   }
+     125             :   /// Add v to all elements of the Matrix
+     126             :   Matrix<T> operator+=(const T& v) {
+     127             :     for(unsigned i=0; i<sz; ++i) { data[i]+=v; }
+     128             :     return *this;
+     129             :   }
+     130             :   /// Multiply all elements by v
+     131         112 :   Matrix<T> operator*=(const T& v) {
+     132      440804 :     for(unsigned i=0; i<sz; ++i) { data[i]*=v; }
+     133         112 :     return *this;
+     134             :   }
+     135             :   /// Matrix addition
+     136             :   Matrix<T>& operator+=(const Matrix<T>& m) {
+     137             :     plumed_dbg_assert( m.rw==rw && m.cl==cl );
+     138             :     data+=m.data;
+     139             :     return *this;
+     140             :   }
+     141             :   /// Subtract v from all elements of the Matrix
+     142             :   Matrix<T> operator-=(const T& v) {
+     143             :     for(unsigned i=0; i<sz; ++i) { data-=v; }
+     144             :     return *this;
+     145             :   }
+     146             :   /// Matrix subtraction
+     147             :   Matrix<T>& operator-=(const Matrix<T>& m) {
+     148             :     plumed_dbg_assert( m.rw==rw && m.cl==cl );
+     149             :     data-=m.data;
+     150             :     return *this;
+     151             :   }
+     152             :   /// Test if the matrix is symmetric or not
+     153       23980 :   unsigned isSymmetric() const {
+     154       23980 :     if (rw!=cl) { return 0; }
+     155             :     unsigned sym=1;
+     156      268903 :     for(unsigned i=1; i<rw; ++i) for(unsigned j=0; j<i; ++j) if( std::fabs(data[i+j*cl]-data[j+i*cl])>1.e-10 ) { sym=0; break; }
+     157             :     return sym;
+     158             :   }
+     159             : };
+     160             : 
+     161             : /// Multiply matrix by scalar
+     162          12 : template <typename T> Matrix<T> operator*(T& v, const Matrix<T>& m ) {
+     163             :   Matrix<T> new_m(m);
+     164          12 :   new_m*=v;
+     165          12 :   return new_m;
+     166             : }
+     167             : 
+     168       13725 : template <typename T> void mult( const Matrix<T>& A, const Matrix<T>& B, Matrix<T>& C ) {
+     169       13725 :   plumed_assert(A.cl==B.rw);
+     170       13725 :   if( A.rw !=C.rw  || B.cl !=C.cl ) { C.resize( A.rw, B.cl ); } C=static_cast<T>( 0 );
+     171  2011234560 :   for(unsigned i=0; i<A.rw; ++i) for(unsigned j=0; j<B.cl; ++j) for (unsigned k=0; k<A.cl; ++k) C(i,j)+=A(i,k)*B(k,j);
+     172       13725 : }
+     173             : 
+     174        2141 : template <typename T> void mult( const Matrix<T>& A, const std::vector<T>& B, std::vector<T>& C) {
+     175        2141 :   plumed_assert( A.cl==B.size() );
+     176        2141 :   if( C.size()!=A.rw  ) { C.resize(A.rw); }
+     177       37323 :   for(unsigned i=0; i<A.rw; ++i) { C[i]= static_cast<T>( 0 ); }
+     178      681459 :   for(unsigned i=0; i<A.rw; ++i) for(unsigned k=0; k<A.cl; ++k) C[i]+=A(i,k)*B[k] ;
+     179        2141 : }
+     180             : 
+     181             : template <typename T> void mult( const std::vector<T>& A, const Matrix<T>& B, std::vector<T>& C) {
+     182             :   plumed_assert( B.rw==A.size() );
+     183             :   if( C.size()!=B.cl ) {C.resize( B.cl );}
+     184             :   for(unsigned i=0; i<B.cl; ++i) { C[i]=static_cast<T>( 0 ); }
+     185             :   for(unsigned i=0; i<B.cl; ++i) for(unsigned k=0; k<B.rw; ++k) C[i]+=A[k]*B(k,i);
+     186             : }
+     187             : 
+     188             : template <typename T> void transpose( const Matrix<T>& A, Matrix<T>& AT ) {
+     189             :   if( A.rw!=AT.cl || A.cl!=AT.rw ) AT.resize( A.cl, A.rw );
+     190             :   for(unsigned i=0; i<A.cl; ++i) for(unsigned j=0; j<A.rw; ++j) AT(i,j)=A(j,i);
+     191             : }
+     192             : 
+     193             : template <typename T> Log& operator<<(Log& ostr, const Matrix<T>& mat) {
+     194             :   for(unsigned i=0; i<mat.sz; ++i) ostr<<mat.data[i]<<" ";
+     195             :   return ostr;
+     196             : }
+     197             : 
+     198             : template <typename T> void matrixOut( Log& ostr, const Matrix<T>& mat) {
+     199             :   for(unsigned i=0; i<mat.rw; ++i) {
+     200             :     for(unsigned j=0; j<mat.cl; ++j) { ostr<<mat(i,j)<<" "; }
+     201             :     ostr<<"\n";
+     202             :   }
+     203             :   return;
+     204             : }
+     205             : 
+     206       14151 : template <typename T> int diagMat( const Matrix<T>& A, std::vector<double>& eigenvals, Matrix<double>& eigenvecs ) {
+     207             : 
+     208             :   // Check matrix is square and symmetric
+     209       14151 :   plumed_assert( A.rw==A.cl ); plumed_assert( A.isSymmetric()==1 );
+     210       14151 :   std::vector<double> da(A.sz);
+     211             :   unsigned k=0;
+     212       14151 :   std::vector<double> evals(A.cl);
+     213             :   // Transfer the matrix to the local array
+     214      494643 :   for (unsigned i=0; i<A.cl; ++i) for (unsigned j=0; j<A.rw; ++j) da[k++]=static_cast<double>( A(j,i) );
+     215             : 
+     216       14151 :   int n=A.cl; int lwork=-1, liwork=-1, m, info, one=1;
+     217       14151 :   std::vector<double> work(A.cl);
+     218       14151 :   std::vector<int> iwork(A.cl);
+     219       14151 :   double vl, vu, abstol=0.0;
+     220       14151 :   std::vector<int> isup(2*A.cl);
+     221       14151 :   std::vector<double> evecs(A.sz);
+     222             : 
+     223       14151 :   plumed_lapack_dsyevr("V", "I", "U", &n, da.data(), &n, &vl, &vu, &one, &n,
+     224             :                        &abstol, &m, evals.data(), evecs.data(), &n,
+     225             :                        isup.data(), work.data(), &lwork, iwork.data(), &liwork, &info);
+     226       14151 :   if (info!=0) return info;
+     227             : 
+     228             :   // Retrieve correct sizes for work and iwork then reallocate
+     229       14151 :   liwork=iwork[0]; iwork.resize(liwork);
+     230       14151 :   lwork=static_cast<int>( work[0] ); work.resize(lwork);
+     231             : 
+     232       14151 :   plumed_lapack_dsyevr("V", "I", "U", &n, da.data(), &n, &vl, &vu, &one, &n,
+     233             :                        &abstol, &m, evals.data(), evecs.data(), &n,
+     234             :                        isup.data(), work.data(), &lwork, iwork.data(), &liwork, &info);
+     235       14151 :   if (info!=0) return info;
+     236             : 
+     237       14151 :   if( eigenvals.size()!=A.cl ) { eigenvals.resize( A.cl ); }
+     238       14151 :   if( eigenvecs.rw!=A.rw || eigenvecs.cl!=A.cl ) { eigenvecs.resize( A.rw, A.cl ); }
+     239             :   k=0;
+     240       43840 :   for(unsigned i=0; i<A.cl; ++i) {
+     241       29689 :     eigenvals[i]=evals[i];
+     242             :     // N.B. For ease of producing projectors we store the eigenvectors
+     243             :     // ROW-WISE in the eigenvectors matrix.  The first index is the
+     244             :     // eigenvector number and the second the component
+     245      480492 :     for(unsigned j=0; j<A.rw; ++j) { eigenvecs(i,j)=evecs[k++]; }
+     246             :   }
+     247             : 
+     248             :   // This changes eigenvectors so that the first non-null element
+     249             :   // of each of them is positive
+     250             :   // We can do it because the phase is arbitrary, and helps making
+     251             :   // the result reproducible
+     252       43840 :   for(int i=0; i<n; ++i) {
+     253             :     int j;
+     254       29689 :     for(j=0; j<n; j++) if(eigenvecs(i,j)*eigenvecs(i,j)>1e-14) break;
+     255      232782 :     if(j<n) if(eigenvecs(i,j)<0.0) for(j=0; j<n; j++) eigenvecs(i,j)*=-1;
+     256             :   }
+     257             :   return 0;
+     258             : }
+     259             : 
+     260           1 : template <typename T> int pseudoInvert( const Matrix<T>& A, Matrix<double>& pseudoinverse ) {
+     261           1 :   std::vector<double> da(A.sz);
+     262             :   unsigned k=0;
+     263             :   // Transfer the matrix to the local array
+     264      250501 :   for (unsigned i=0; i<A.cl; ++i) for (unsigned j=0; j<A.rw; ++j) da[k++]=static_cast<double>( A(j,i) );
+     265             : 
+     266           1 :   int nsv, info, nrows=A.rw, ncols=A.cl;
+     267           1 :   if(A.rw>A.cl) {nsv=A.cl;} else {nsv=A.rw;}
+     268             : 
+     269             :   // Create some containers for stuff from single value decomposition
+     270           1 :   std::vector<double> S(nsv);
+     271           1 :   std::vector<double> U(nrows*nrows);
+     272           1 :   std::vector<double> VT(ncols*ncols);
+     273           1 :   std::vector<int> iwork(8*nsv);
+     274             : 
+     275             :   // This optimizes the size of the work array used in lapack singular value decomposition
+     276           1 :   int lwork=-1;
+     277           1 :   std::vector<double> work(1);
+     278           1 :   plumed_lapack_dgesdd( "A", &nrows, &ncols, da.data(), &nrows, S.data(), U.data(), &nrows, VT.data(), &ncols, work.data(), &lwork, iwork.data(), &info );
+     279           1 :   if(info!=0) return info;
+     280             : 
+     281             :   // Retrieve correct sizes for work and rellocate
+     282           1 :   lwork=(int) work[0]; work.resize(lwork);
+     283             : 
+     284             :   // This does the singular value decomposition
+     285           1 :   plumed_lapack_dgesdd( "A", &nrows, &ncols, da.data(), &nrows, S.data(), U.data(), &nrows, VT.data(), &ncols, work.data(), &lwork, iwork.data(), &info );
+     286           1 :   if(info!=0) return info;
+     287             : 
+     288             :   // Compute the tolerance on the singular values ( machine epsilon * number of singular values * maximum singular value )
+     289         500 :   double tol; tol=S[0]; for(int i=1; i<nsv; ++i) { if( S[i]>tol ) { tol=S[i]; } } tol*=nsv*epsilon;
+     290             : 
+     291             :   // Get the inverses of the singlular values
+     292           1 :   Matrix<double> Si( ncols, nrows ); Si=0.0;
+     293         501 :   for(int i=0; i<nsv; ++i) { if( S[i]>tol ) { Si(i,i)=1./S[i]; } else { Si(i,i)=0.0; } }
+     294             : 
+     295             :   // Now extract matrices for pseudoinverse
+     296           1 :   Matrix<double> V( ncols, ncols ), UT( nrows, nrows ), tmp( ncols, nrows );
+     297      250501 :   k=0; for(int i=0; i<nrows; ++i) { for(int j=0; j<nrows; ++j) { UT(i,j)=U[k++]; } }
+     298      250501 :   k=0; for(int i=0; i<ncols; ++i) { for(int j=0; j<ncols; ++j) { V(i,j)=VT[k++]; } }
+     299             : 
+     300             :   // And do matrix algebra to construct the pseudoinverse
+     301           1 :   if( pseudoinverse.rw!=ncols || pseudoinverse.cl!=nrows ) pseudoinverse.resize( ncols, nrows );
+     302           1 :   mult( V, Si, tmp ); mult( tmp, UT, pseudoinverse );
+     303             : 
+     304             :   return 0;
+     305             : }
+     306             : 
+     307        9383 : template <typename T> int Invert( const Matrix<T>& A, Matrix<double>& inverse ) {
+     308             : 
+     309        9383 :   if( A.isSymmetric()==1 ) {
+     310             :     // GAT -- I only ever use symmetric matrices so I can invert them like this.
+     311             :     // I choose to do this as I have had problems with the more general way of doing this that
+     312             :     // is implemented below.
+     313        9326 :     std::vector<double> eval(A.rw); Matrix<double> evec(A.rw,A.cl), tevec(A.rw,A.cl);
+     314        9326 :     int err; err=diagMat( A, eval, evec );
+     315        9326 :     if(err!=0) return err;
+     316       64900 :     for (unsigned i=0; i<A.rw; ++i) for (unsigned j=0; j<A.cl; ++j) tevec(i,j)=evec(j,i)/eval[j];
+     317        9326 :     mult(tevec,evec,inverse);
+     318             :   } else {
+     319          57 :     std::vector<double> da(A.sz);
+     320          57 :     std::vector<int> ipiv(A.cl);
+     321          57 :     unsigned k=0; int n=A.rw, info;
+     322         399 :     for(unsigned i=0; i<A.cl; ++i) for(unsigned j=0; j<A.rw; ++j) da[k++]=static_cast<double>( A(j,i) );
+     323             : 
+     324          57 :     plumed_lapack_dgetrf(&n,&n,da.data(),&n,ipiv.data(),&info);
+     325          57 :     if(info!=0) return info;
+     326             : 
+     327          57 :     int lwork=-1;
+     328          57 :     std::vector<double> work(A.cl);
+     329          57 :     plumed_lapack_dgetri(&n,da.data(),&n,ipiv.data(),work.data(),&lwork,&info);
+     330          57 :     if(info!=0) return info;
+     331             : 
+     332          57 :     lwork=static_cast<int>( work[0] ); work.resize(lwork);
+     333          57 :     plumed_lapack_dgetri(&n,da.data(),&n,ipiv.data(),work.data(),&lwork,&info);
+     334          57 :     if(info!=0) return info;
+     335             : 
+     336          57 :     if( inverse.cl!=A.cl || inverse.rw!=A.rw ) { inverse.resize(A.rw,A.cl); }
+     337         399 :     k=0; for(unsigned i=0; i<A.rw; ++i) for(unsigned j=0; j<A.cl; ++j) inverse(j,i)=da[k++];
+     338             :   }
+     339             : 
+     340             :   return 0;
+     341             : }
+     342             : 
+     343         446 : template <typename T> void cholesky( const Matrix<T>& A, Matrix<T>& B ) {
+     344             : 
+     345         446 :   plumed_assert( A.rw==A.cl && A.isSymmetric() );
+     346             :   Matrix<T> L(A.rw,A.cl); L=0.;
+     347         446 :   std::vector<T> D(A.rw,0.);
+     348        1047 :   for(unsigned i=0; i<A.rw; ++i) {
+     349         601 :     L(i,i)=static_cast<T>( 1 );
+     350         756 :     for (unsigned j=0; j<i; ++j) {
+     351         155 :       L(i,j)=A(i,j);
+     352         155 :       for (unsigned k=0; k<j; ++k) L(i,j)-=L(i,k)*L(j,k)*D[k];
+     353         155 :       if (D[j]!=0.) L(i,j)/=D[j]; else L(i,j)=static_cast<T>( 0 );
+     354             :     }
+     355         601 :     D[i]=A(i,i);
+     356         756 :     for (unsigned k=0; k<i; ++k) D[i]-=L(i,k)*L(i,k)*D[k];
+     357             :   }
+     358             : 
+     359        1047 :   for(unsigned i=0; i<A.rw; ++i) D[i]=(D[i]>0.?std::sqrt(D[i]):0.);
+     360         446 :   if( B.rw!=A.rw || B.cl!=A.cl ) { B.resize( A.rw, A.cl); }
+     361        1803 :   B=0.; for(unsigned i=0; i<A.rw; ++i) for(unsigned j=0; j<=i; ++j) B(i,j)+=L(i,j)*D[j];
+     362         446 : }
+     363             : 
+     364             : template <typename T> void chol_elsolve( const Matrix<T>& M, const std::vector<T>& b, std::vector<T>& y ) {
+     365             : 
+     366             :   plumed_assert( M.rw==M.cl && M(0,1)==0.0 && b.size()==M.rw );
+     367             :   if( y.size()!=M.rw ) { y.resize( M.rw ); }
+     368             :   for(unsigned i=0; i<M.rw; ++i) {
+     369             :     y[i]=b[i];
+     370             :     for(unsigned j=0; j<i; ++j) y[i]-=M(i,j)*y[j];
+     371             :     y[i]*=1.0/M(i,i);
+     372             :   }
+     373             : }
+     374             : 
+     375          46 : template <typename T> int logdet( const Matrix<T>& M, double& ldet ) {
+     376             :   // Check matrix is square and symmetric
+     377          46 :   plumed_assert( M.rw==M.cl || M.isSymmetric() );
+     378             : 
+     379          46 :   std::vector<double> da(M.sz);
+     380             :   unsigned k=0;
+     381          46 :   std::vector<double> evals(M.cl);
+     382             :   // Transfer the matrix to the local array
+     383         578 :   for (unsigned i=0; i<M.rw; ++i) for (unsigned j=0; j<M.cl; ++j) da[k++]=static_cast<double>( M(j,i) );
+     384             : 
+     385          46 :   int n=M.cl; int lwork=-1, liwork=-1, info, m, one=1;
+     386          46 :   std::vector<double> work(M.rw);
+     387          46 :   std::vector<int> iwork(M.rw);
+     388          46 :   double vl, vu, abstol=0.0;
+     389          46 :   std::vector<int> isup(2*M.rw);
+     390          46 :   std::vector<double> evecs(M.sz);
+     391          46 :   plumed_lapack_dsyevr("N", "I", "U", &n, da.data(), &n, &vl, &vu, &one, &n,
+     392             :                        &abstol, &m, evals.data(), evecs.data(), &n,
+     393             :                        isup.data(), work.data(), &lwork, iwork.data(), &liwork, &info);
+     394          46 :   if (info!=0) return info;
+     395             : 
+     396             :   // Retrieve correct sizes for work and iwork then reallocate
+     397          46 :   lwork=static_cast<int>( work[0] ); work.resize(lwork);
+     398          46 :   liwork=iwork[0]; iwork.resize(liwork);
+     399             : 
+     400          46 :   plumed_lapack_dsyevr("N", "I", "U", &n, da.data(), &n, &vl, &vu, &one, &n,
+     401             :                        &abstol, &m, evals.data(), evecs.data(), &n,
+     402             :                        isup.data(), work.data(), &lwork, iwork.data(), &liwork, &info);
+     403          46 :   if (info!=0) return info;
+     404             : 
+     405             :   // Transfer the eigenvalues and eigenvectors to the output
+     406         180 :   ldet=0; for(unsigned i=0; i<M.cl; i++) { ldet+=log(evals[i]); }
+     407             : 
+     408             :   return 0;
+     409             : }
+     410             : 
+     411             : 
+     412             : 
+     413             : }
+     414             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html b/coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html new file mode 100644 index 000000000000..d871fb7527e7 --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.func-sort-c.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - tools/MatrixSquareBracketsAccess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MatrixSquareBracketsAccess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-02-22 21:58:45Functions:2121100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowC2ERS3_j30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjEixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE9Const_rowC2ERKS3_j555994
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE9Const_rowixEj555994
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjEixEj555994
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowC2ERKS3_j756226
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowixEj756226
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj756226
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowC2ERS3_j2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjEixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowC2ERS3_j16341862
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowixEj16341862
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjEixEj16341862
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowC2ERS3_j27664170
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowixEj27664170
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj27664170
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowC2ERS8_j35212356
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowixEj35212356
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjEixEj35212356
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MatrixSquareBracketsAccess.h.func.html b/coverage/tools/MatrixSquareBracketsAccess.h.func.html new file mode 100644 index 000000000000..36feab01aa7a --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.func.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - tools/MatrixSquareBracketsAccess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MatrixSquareBracketsAccess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-02-22 21:58:45Functions:2121100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowC2ERS3_j2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjE3RowixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj1ELj4EEEdjjEixEj2744600
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowC2ERS3_j27664170
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE3RowixEj27664170
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowC2ERKS3_j756226
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj27664170
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowC2ERS3_j16341862
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE3RowixEj16341862
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE9Const_rowC2ERKS3_j555994
_ZN4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjEixEj16341862
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowC2ERS8_j35212356
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjE3RowixEj35212356
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEES6_jjEixEj35212356
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowC2ERS3_j30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjE3RowixEj30474
_ZN4PLMD26MatrixSquareBracketsAccessINS_6MatrixIdEEdjjEixEj30474
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjE9Const_rowixEj756226
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj3ELj3EEEdjjEixEj756226
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjE9Const_rowixEj555994
_ZNK4PLMD26MatrixSquareBracketsAccessINS_13TensorGenericILj4ELj4EEEdjjEixEj555994
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html b/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html new file mode 100644 index 000000000000..f543a5a98da8 --- /dev/null +++ b/coverage/tools/MatrixSquareBracketsAccess.h.gcov.html @@ -0,0 +1,215 @@ + + + + + + + + LCOV - plumed test coverage - tools/MatrixSquareBracketsAccess.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MatrixSquareBracketsAccess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-02-22 21:58:45Functions:2121100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_MatrixSquareBracketsAccess_h
+      23             : #define __PLUMED_tools_MatrixSquareBracketsAccess_h
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27             : /**
+      28             : Utility class to add [][] access
+      29             : 
+      30             : \tparam T The type of the matrix class.
+      31             : \tparam C The type of the returned value.
+      32             : \tparam I The type of the first index (default unsigned).
+      33             : \tparam J The type of the second index (default unsigned).
+      34             : 
+      35             : It implements the trick described in C++ FAQ 13.12 to allow [][] access
+      36             : to matrix-like classes, based on the (,) syntax, thus translating
+      37             : [i][j] into (i,j).  In practice, one only needs to implement the (,) syntax and to inherit from
+      38             : MatrixSquareBracketsAccess.
+      39             : The first template parameter (T) should be the
+      40             : class itself, the second (C) is the type of the returned value,
+      41             : and the third (I) and fourth (J) are the types of the two indexes (unsigned by default).
+      42             : As everything is inlined, no overhead is expected.
+      43             : 
+      44             : \verbatim
+      45             : 
+      46             : class MyMatrixClass:
+      47             :   public MatrixSquareBracketsAccess<MyMatrixClass,double>
+      48             : {
+      49             :   double data[16];
+      50             : public:
+      51             :   double & operator ()(unsigned i,unsigned j){
+      52             :     return data[4*i+j];
+      53             :   }
+      54             :   const double & operator ()(unsigned i,unsigned j)const{
+      55             :     return data[4*i+j];
+      56             :   }
+      57             : };
+      58             : 
+      59             : int main(){
+      60             :   MyMatrixClass m;
+      61             :   m[0][1]=3.0;
+      62             :   return 0;
+      63             : }
+      64             : \endverbatim
+      65             : 
+      66             : */
+      67             : 
+      68             : template<class T,class C,class I=unsigned,class J=unsigned>
+      69             : class MatrixSquareBracketsAccess {
+      70             : /// Small utility class which just contains a pointer to the T and the row number
+      71             :   class Const_row {
+      72             :     friend class MatrixSquareBracketsAccess; // this so as to allow only T to instantiate Const_row
+      73             :     // the user should not manipulate it directly
+      74             :     const MatrixSquareBracketsAccess& t;
+      75             :     const I i;
+      76             :     Const_row(const MatrixSquareBracketsAccess&t,I i); // constructor is private and cannot be manipulated by the user
+      77             :   public:
+      78             :     /// access element
+      79             :     const C & operator[] (J j)const;
+      80             :   };
+      81             : /// Small utility class which just contains a pointer to the T and the row number
+      82             :   class Row {
+      83             :     friend class MatrixSquareBracketsAccess; // this so as to allow only T to instantiate Const_row
+      84             :     // the user should not manipulate it directly
+      85             :     MatrixSquareBracketsAccess& t;
+      86             :     const I i;
+      87             :     Row(MatrixSquareBracketsAccess&t,I i); // constructor is private and cannot be manipulated by the user
+      88             :   public:
+      89             :     /// access element
+      90             :     C & operator[] (J j);
+      91             :   };
+      92             : public:
+      93             : /// access element (with [][] syntax)
+      94             :   Row operator[] (I i);
+      95             : /// access element (with [][] syntax)
+      96             :   Const_row operator[] (I i)const;
+      97             : };
+      98             : 
+      99             : template<class T,class C,class I,class J>
+     100     1312220 : MatrixSquareBracketsAccess<T,C,I,J>::Const_row::Const_row(const MatrixSquareBracketsAccess&t,I i):
+     101     1312220 :   t(t),i(i) {}
+     102             : 
+     103             : template<class T,class C,class I,class J>
+     104    81993462 : MatrixSquareBracketsAccess<T,C,I,J>::Row::Row(MatrixSquareBracketsAccess&t,I i):
+     105    81993462 :   t(t),i(i) {}
+     106             : 
+     107             : template<class T,class C,class I,class J>
+     108     1312220 : const C & MatrixSquareBracketsAccess<T,C,I,J>::Const_row::operator[] (J j)const {
+     109             : // This appears as a reference to a temporary object
+     110             : // however, in reality we know it is a reference to an object that is stored in the
+     111             : // t object. We thus suppress the warning raised by cppcheck
+     112     1312220 :   return (*static_cast<const T*>(&t))(i,j);
+     113             : }
+     114             : 
+     115             : template<class T,class C,class I,class J>
+     116    81993462 : C & MatrixSquareBracketsAccess<T,C,I,J>::Row::operator[] (J j) {
+     117             : // This appears as a reference to a temporary object
+     118             : // however, in reality we know it is a reference to an object that is stored in the
+     119             : // t object. We thus suppress the warning raised by cppcheck
+     120    81993462 :   return (*static_cast<T*>(&t))(i,j);
+     121             : }
+     122             : 
+     123             : template<class T,class C,class I,class J>
+     124    81993462 : typename MatrixSquareBracketsAccess<T,C,I,J>::Row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i) {
+     125    81993462 :   return Row(*this,i);
+     126             : }
+     127             : 
+     128             : template<class T,class C,class I,class J>
+     129     1312220 : typename MatrixSquareBracketsAccess<T,C,I,J>::Const_row MatrixSquareBracketsAccess<T,C,I,J>::operator[] (I i)const {
+     130     1312220 :   return Const_row(*this,i);
+     131             : }
+     132             : 
+     133             : }
+     134             : 
+     135             : 
+     136             : #endif
+     137             : 
+     138             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Minimise1DBrent.h.func-sort-c.html b/coverage/tools/Minimise1DBrent.h.func-sort-c.html new file mode 100644 index 000000000000..94622ec6a986 --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - tools/Minimise1DBrent.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Minimise1DBrent.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:818397.6 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred18SketchMapPointwiseEEEE7bracketERKdS7_MS4_FdS7_E22
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred18SketchMapPointwiseEEEE8minimiseEMS4_FdRKdE22
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred18SketchMapPointwiseEEEEC2ERKS4_RKd22
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred18SketchMapPointwiseEEEE15getMinimumValueEv22
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred17SketchMapConjGradEEEE7bracketERKdS7_MS4_FdS7_E61
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred17SketchMapConjGradEEEE8minimiseEMS4_FdRKdE61
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred17SketchMapConjGradEEEEC2ERKS4_RKd61
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred17SketchMapConjGradEEEE15getMinimumValueEv61
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred24ProjectNonLandmarkPointsEEEE7bracketERKdS7_MS4_FdS7_E814
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred24ProjectNonLandmarkPointsEEEE8minimiseEMS4_FdRKdE814
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred24ProjectNonLandmarkPointsEEEEC2ERKS4_RKd814
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred24ProjectNonLandmarkPointsEEEE15getMinimumValueEv814
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Minimise1DBrent.h.func.html b/coverage/tools/Minimise1DBrent.h.func.html new file mode 100644 index 000000000000..94170108014a --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - tools/Minimise1DBrent.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Minimise1DBrent.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:818397.6 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred17SketchMapConjGradEEEE7bracketERKdS7_MS4_FdS7_E61
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred17SketchMapConjGradEEEE8minimiseEMS4_FdRKdE61
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred17SketchMapConjGradEEEEC2ERKS4_RKd61
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred18SketchMapPointwiseEEEE7bracketERKdS7_MS4_FdS7_E22
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred18SketchMapPointwiseEEEE8minimiseEMS4_FdRKdE22
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred18SketchMapPointwiseEEEEC2ERKS4_RKd22
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred24ProjectNonLandmarkPointsEEEE7bracketERKdS7_MS4_FdS7_E814
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred24ProjectNonLandmarkPointsEEEE8minimiseEMS4_FdRKdE814
_ZN4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred24ProjectNonLandmarkPointsEEEEC2ERKS4_RKd814
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred17SketchMapConjGradEEEE15getMinimumValueEv61
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred18SketchMapPointwiseEEEE15getMinimumValueEv22
_ZNK4PLMD15Minimise1DBrentINS_5F1dimINS_6dimred24ProjectNonLandmarkPointsEEEE15getMinimumValueEv814
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Minimise1DBrent.h.gcov.html b/coverage/tools/Minimise1DBrent.h.gcov.html new file mode 100644 index 000000000000..cec88e7ad7b4 --- /dev/null +++ b/coverage/tools/Minimise1DBrent.h.gcov.html @@ -0,0 +1,272 @@ + + + + + + + + LCOV - plumed test coverage - tools/Minimise1DBrent.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Minimise1DBrent.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:818397.6 %
Date:2024-02-22 21:58:45Functions:1212100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Minimise1DBrent_h
+      23             : #define __PLUMED_tools_Minimise1DBrent_h
+      24             : 
+      25             : #include "Tools.h"
+      26             : 
+      27             : #include <vector>
+      28             : #include <string>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : /// A class for doing parabolic interpolation and minimisation of
+      33             : /// 1D functions using Brent's method.
+      34             : template <class FCLASS>
+      35         897 : class Minimise1DBrent {
+      36             : private:
+      37             : /// Has the minimum been bracketed
+      38             :   bool bracketed;
+      39             : /// Has the function been minimised
+      40             :   bool minimised;
+      41             : /// The tolerance for the line minimiser
+      42             :   double tol;
+      43             : /// The default ration by which successive intervals are magnified
+      44             :   const double GOLD;
+      45             : /// The maximum magnification allowed for a parabolic fit step
+      46             :   const double GLIMIT;
+      47             : /// Use to prevent any possible division by zero
+      48             :   const double TINY;
+      49             : /// Maximum number of interactions in line minimiser
+      50             :   const unsigned ITMAX;
+      51             : /// The value of the golden ratio
+      52             :   const double CGOLD;
+      53             : /// A small number that protects against trying to achieve fractional
+      54             : /// accuracy for a minimum that happens to be exactly zero
+      55             :   const double ZEPS;
+      56             : /// This is the type specifier for the function to minimise
+      57             :   typedef double(FCLASS::*eng_pointer)( const double& val );
+      58             : /// Three points bracketting the minimum and the corresponding function values
+      59             :   double ax,bx,cx,fa,fb,fc,fmin;
+      60             : /// The class containing the function we are trying to minimise
+      61             :   FCLASS myclass_func;
+      62             : public:
+      63         897 :   explicit Minimise1DBrent( const FCLASS& pf,  const double& t=3.0E-8 );
+      64             : /// Bracket the minium
+      65             :   void bracket( const double& ax, const double& xx, eng_pointer eng );
+      66             : /// Find the minimum between two brackets
+      67             :   double minimise( eng_pointer eng );
+      68             : /// Return the value of the function at the minimum
+      69             :   double getMinimumValue() const ;
+      70             : };
+      71             : 
+      72             : template <class FCLASS>
+      73         897 : Minimise1DBrent<FCLASS>::Minimise1DBrent( const FCLASS& pf, const double& t ):
+      74         897 :   bracketed(false),
+      75         897 :   minimised(false),
+      76         897 :   tol(t),
+      77         897 :   GOLD(1.618034),
+      78         897 :   GLIMIT(100.0),
+      79         897 :   TINY(1.0E-20),
+      80         897 :   ITMAX(100),
+      81         897 :   CGOLD(0.3819660),
+      82         897 :   ZEPS(epsilon*1.0E-3),
+      83         897 :   ax(0),bx(0),cx(0),
+      84         897 :   fa(0),fb(0),fc(0),
+      85         897 :   fmin(0),
+      86         897 :   myclass_func(pf)
+      87             : {
+      88         897 : }
+      89             : 
+      90             : template <class FCLASS>
+      91         897 : void Minimise1DBrent<FCLASS>::bracket( const double& a, const double& b, eng_pointer eng ) {
+      92         897 :   ax=a; bx=b; double fu;
+      93         897 :   fa=(myclass_func.*eng)(ax); fb=(myclass_func.*eng)(bx);
+      94         897 :   if( fb>fa ) {
+      95             :     double tmp;
+      96         809 :     tmp=ax; ax=bx; bx=tmp;
+      97         809 :     tmp=fa; fa=fb; fb=tmp;
+      98             :   }
+      99         897 :   cx=bx+GOLD*(bx-ax);
+     100         897 :   fc=(myclass_func.*eng)(cx);
+     101        1113 :   while ( fb > fc ) {
+     102         220 :     double r=(bx-ax)*(fb-fc);
+     103         220 :     double q=(bx-cx)*(fb-fa);
+     104         220 :     double u=bx-((bx-cx)*q-(bx-ax)*r)/(2.0*(std::fabs(q-r)>TINY?std::fabs(q-r):TINY)*(q-r>=0?1:-1));
+     105         220 :     double ulim=bx+GLIMIT*(cx-bx);
+     106         220 :     if((bx-u)*(u-cx) > 0.0 ) {
+     107           5 :       fu=(myclass_func.*eng)(u);
+     108           5 :       if( fu < fc ) {
+     109           4 :         ax=bx; bx=u; fa=fb; fb=fu; bracketed=true; return;
+     110           1 :       } else if( fu > fb ) {
+     111           0 :         cx=u; fc=fu; bracketed=true; return;
+     112             :       }
+     113           1 :       u=cx+GOLD*(cx-bx); fu=(myclass_func.*eng)(u);
+     114         215 :     } else if((cx-u)*(u-ulim) > 0.0 ) {
+     115          81 :       fu=(myclass_func.*eng)(u);
+     116          81 :       if( fu<fc ) {
+     117          80 :         bx=cx; cx=u; u+=GOLD*(u-bx);
+     118          80 :         fb=fc; fc=fu; fu=(myclass_func.*eng)(u);
+     119             :       }
+     120         134 :     } else if( (u-ulim)*(ulim-cx) >= 0.0 ) {
+     121         124 :       u=ulim;
+     122         124 :       fu=(myclass_func.*eng)(u);
+     123             :     } else {
+     124          10 :       u=cx+GOLD*(cx-bx);
+     125          10 :       fu=(myclass_func.*eng)(u);
+     126             :     }
+     127         216 :     ax=bx; bx=cx; cx=u;
+     128         216 :     fa=fb; fb=fc; fc=fu;
+     129             :   }
+     130         893 :   bracketed=true;
+     131             : }
+     132             : 
+     133             : template <class FCLASS>
+     134         897 : double Minimise1DBrent<FCLASS>::minimise( eng_pointer eng ) {
+     135             :   plumed_dbg_assert( bracketed );
+     136             : 
+     137             :   double a,b,d=0.0,etemp,fu,fv,fw,fx;
+     138             :   double p,q,r,tol1,tol2,u,v,w,x,xm;
+     139             :   double e=0.0;
+     140             : 
+     141         897 :   a=(ax < cx ? ax : cx );
+     142         897 :   b=(ax >= cx ? ax : cx );
+     143         897 :   x=w=v=bx;
+     144         897 :   fw=fv=fx=(myclass_func.*eng)(x);
+     145       14768 :   for(unsigned iter=0; iter<ITMAX; ++iter) {
+     146       14768 :     xm=0.5*(a+b);
+     147       14768 :     tol2=2.0*(tol1=tol*std::fabs(x)+ZEPS);
+     148       14768 :     if( std::fabs(x-xm) <= (tol2-0.5*(b-a))) {
+     149         897 :       fmin=fx; minimised=true; return x;
+     150             :     }
+     151       13871 :     if( std::fabs(e) > tol1 ) {
+     152       12810 :       r=(x-w)*(fx-fv);
+     153       12810 :       q=(x-v)*(fx-fw);
+     154       12810 :       p=(x-v)*q-(x-w)*r;
+     155       12810 :       q=2.0*(q-r);
+     156       12810 :       if( q > 0.0 ) p = -p;
+     157       12810 :       q=std::fabs(q);
+     158             :       etemp=e;
+     159             :       e=d;
+     160       12810 :       if( std::fabs(p) >= std::fabs(0.5*q*etemp) || p <= q*(a-x) || p >= q*(b-x) ) {
+     161        5079 :         d = CGOLD*(e=(x >= xm ? a-x : b-x ));
+     162             :       } else {
+     163        7731 :         d=p/q; u=x+d;
+     164        7731 :         if(u-a < tol2 || b-u < tol2 ) d=(xm-x>=0?std::fabs(tol1):-std::fabs(tol1));
+     165             :       }
+     166             :     } else {
+     167        1061 :       d=CGOLD*(e=( x >= xm ? a-x : b-x ));
+     168             :     }
+     169       13871 :     if( std::fabs(d)>=tol1) u=x+d; else u=x+(d>=0?std::fabs(tol1):-std::fabs(tol1));
+     170       13871 :     fu=(myclass_func.*eng)(u);
+     171       13871 :     if( fu <= fx ) {
+     172        5411 :       if( u >= x ) a=x; else b=x;
+     173             :       v=w; fv=fw;
+     174             :       w=x; fw=fx;
+     175        5411 :       x=u; fx=fu;
+     176             :     } else {
+     177        8460 :       if( u < x ) a=u; else b=u;
+     178        8460 :       if( fu <=fw || w==x ) {
+     179             :         v=w; w=u; fv=fw; fw=fu;
+     180        5096 :       } else if( fu <= fv || v==x || v==w ) {
+     181             :         v=u; fv=fu;
+     182             :       }
+     183             :     }
+     184             :   }
+     185           0 :   plumed_merror("Too many interactions in brent");
+     186             : }
+     187             : 
+     188             : template <class FCLASS>
+     189         897 : double Minimise1DBrent<FCLASS>::getMinimumValue() const {
+     190             :   plumed_dbg_assert( minimised );
+     191         897 :   return fmin;
+     192             : }
+     193             : 
+     194             : }
+     195             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MinimiseBase.h.func-sort-c.html b/coverage/tools/MinimiseBase.h.func-sort-c.html new file mode 100644 index 000000000000..626edf789851 --- /dev/null +++ b/coverage/tools/MinimiseBase.h.func-sort-c.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - tools/MinimiseBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MinimiseBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:161888.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5F1dimINS_4GridEE6getEngERKd0
_ZN4PLMD5F1dimINS_4GridEEC2ERKSt6vectorIdSaIdEES7_PS1_MS1_KFdS7_RS5_EMS1_FdS7_S9_E0
_ZN4PLMD12MinimiseBaseINS_6dimred18SketchMapPointwiseEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E22
_ZN4PLMD12MinimiseBaseINS_6dimred18SketchMapPointwiseEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E22
_ZN4PLMD5F1dimINS_6dimred18SketchMapPointwiseEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E22
_ZN4PLMD12MinimiseBaseINS_6dimred17SketchMapConjGradEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E61
_ZN4PLMD12MinimiseBaseINS_6dimred17SketchMapConjGradEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E61
_ZN4PLMD5F1dimINS_6dimred17SketchMapConjGradEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E61
_ZN4PLMD5F1dimINS_11multicolvar19DistanceFromContourEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E274
_ZN4PLMD5F1dimINS_6dimred18SketchMapPointwiseEE6getEngERKd478
_ZN4PLMD12MinimiseBaseINS_6dimred24ProjectNonLandmarkPointsEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E814
_ZN4PLMD12MinimiseBaseINS_6dimred24ProjectNonLandmarkPointsEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E814
_ZN4PLMD5F1dimINS_6dimred24ProjectNonLandmarkPointsEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E814
_ZN4PLMD5F1dimINS_9gridtools18ContourFindingBaseEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E1242
_ZN4PLMD5F1dimINS_6dimred17SketchMapConjGradEE6getEngERKd1352
_ZN4PLMD5F1dimINS_11multicolvar19DistanceFromContourEE6getEngERKd2200
_ZN4PLMD5F1dimINS_9gridtools18ContourFindingBaseEE6getEngERKd8246
_ZN4PLMD5F1dimINS_6dimred24ProjectNonLandmarkPointsEE6getEngERKd15930
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MinimiseBase.h.func.html b/coverage/tools/MinimiseBase.h.func.html new file mode 100644 index 000000000000..6f07eece42e7 --- /dev/null +++ b/coverage/tools/MinimiseBase.h.func.html @@ -0,0 +1,145 @@ + + + + + + + + LCOV - plumed test coverage - tools/MinimiseBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MinimiseBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:161888.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12MinimiseBaseINS_6dimred17SketchMapConjGradEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E61
_ZN4PLMD12MinimiseBaseINS_6dimred17SketchMapConjGradEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E61
_ZN4PLMD12MinimiseBaseINS_6dimred18SketchMapPointwiseEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E22
_ZN4PLMD12MinimiseBaseINS_6dimred18SketchMapPointwiseEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E22
_ZN4PLMD12MinimiseBaseINS_6dimred24ProjectNonLandmarkPointsEE15calcDerivativesERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E814
_ZN4PLMD12MinimiseBaseINS_6dimred24ProjectNonLandmarkPointsEE7lineminERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E814
_ZN4PLMD5F1dimINS_11multicolvar19DistanceFromContourEE6getEngERKd2200
_ZN4PLMD5F1dimINS_11multicolvar19DistanceFromContourEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E274
_ZN4PLMD5F1dimINS_4GridEE6getEngERKd0
_ZN4PLMD5F1dimINS_4GridEEC2ERKSt6vectorIdSaIdEES7_PS1_MS1_KFdS7_RS5_EMS1_FdS7_S9_E0
_ZN4PLMD5F1dimINS_6dimred17SketchMapConjGradEE6getEngERKd1352
_ZN4PLMD5F1dimINS_6dimred17SketchMapConjGradEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E61
_ZN4PLMD5F1dimINS_6dimred18SketchMapPointwiseEE6getEngERKd478
_ZN4PLMD5F1dimINS_6dimred18SketchMapPointwiseEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E22
_ZN4PLMD5F1dimINS_6dimred24ProjectNonLandmarkPointsEE6getEngERKd15930
_ZN4PLMD5F1dimINS_6dimred24ProjectNonLandmarkPointsEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E814
_ZN4PLMD5F1dimINS_9gridtools18ContourFindingBaseEE6getEngERKd8246
_ZN4PLMD5F1dimINS_9gridtools18ContourFindingBaseEEC2ERKSt6vectorIdSaIdEES8_PS2_MS2_KFdS8_RS6_EMS2_FdS8_SA_E1242
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MinimiseBase.h.gcov.html b/coverage/tools/MinimiseBase.h.gcov.html new file mode 100644 index 000000000000..2f01aa1e062b --- /dev/null +++ b/coverage/tools/MinimiseBase.h.gcov.html @@ -0,0 +1,192 @@ + + + + + + + + LCOV - plumed test coverage - tools/MinimiseBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MinimiseBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:161888.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_MinimiseBase_h
+      23             : #define __PLUMED_tools_MinimiseBase_h
+      24             : 
+      25             : #include "Minimise1DBrent.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : template <class FCLASS>
+      30        2413 : class F1dim {
+      31             : private:
+      32             : /// This is the pointer to the member function in the energy
+      33             : /// calculating class that calculates the energy
+      34             :   typedef double(FCLASS::*engf_pointer)( const std::vector<double>& p, std::vector<double>& der ) const ;
+      35             :   typedef double(FCLASS::*engfnc_pointer)( const std::vector<double>& p, std::vector<double>& der ) ;
+      36             : /// Pointer to the vector containing an initial position on the vector
+      37             :   const std::vector<double>& p;
+      38             : /// The direction of the vector we are minimising along
+      39             :   const std::vector<double>& dir;
+      40             : /// Tempory vector that holds a point at which we want to calculate the energy
+      41             :   std::vector<double> pt;
+      42             : /// Vector that holds the derivatives at the point at which we calculate the energy (these are not used)
+      43             :   std::vector<double> fake_der;
+      44             : /// Class containging the function in the class
+      45             :   FCLASS* func;
+      46             : /// Member of class that calculates the energy we are trying to mnimise
+      47             :   engf_pointer calc;
+      48             : /// Member of class that calcualtes the energy we are trying to minimise
+      49             :   engfnc_pointer calc2;
+      50             : public:
+      51             :   explicit F1dim( const std::vector<double>& pp, const std::vector<double>& dd, FCLASS* ff, engf_pointer cc, engfnc_pointer cc2 );
+      52             : /// Calculate the energy at \f$\mathbf{p} + xt*\mathbf{dir}\f$
+      53             :   double getEng( const double& xt );
+      54             : };
+      55             : 
+      56             : template <class FCLASS>
+      57        2413 : F1dim<FCLASS>::F1dim( const std::vector<double>& pp, const std::vector<double>& dd, FCLASS* ff, engf_pointer cc, engfnc_pointer cc2 ):
+      58        2413 :   p(pp),
+      59        2413 :   dir(dd),
+      60        2413 :   pt(pp.size()),
+      61        2413 :   fake_der(pp.size()),
+      62        2413 :   func(ff),
+      63        2413 :   calc(cc),
+      64        2413 :   calc2(cc2)
+      65             : {
+      66        2413 :   plumed_assert( calc || calc2 );
+      67        2413 : }
+      68             : 
+      69             : template <class FCLASS>
+      70       28206 : double F1dim<FCLASS>::getEng( const double& xt ) {
+      71      465504 :   for(unsigned j=0; j<pt.size(); ++j) pt[j] = p[j] + xt*dir[j];
+      72       28206 :   if( calc ) return (func->*calc)(pt,fake_der);
+      73       19960 :   return (func->*calc2)(pt,fake_der);
+      74             : }
+      75             : 
+      76             : template <class FCLASS>
+      77             : class MinimiseBase {
+      78             : private:
+      79             : /// This is the pointer to the member function in the energy
+      80             : /// calculating class that calculates the energy
+      81             :   typedef double(FCLASS::*engf_pointer)( const std::vector<double>& p, std::vector<double>& der );
+      82             : /// The class that calculates the energy given a position
+      83             :   FCLASS* myclass_func;
+      84             : protected:
+      85             : /// This calculates the derivatives at a point
+      86             :   double calcDerivatives( const std::vector<double>& p, std::vector<double>& der, engf_pointer myfunc );
+      87             : public:
+      88         505 :   explicit MinimiseBase( FCLASS* funcc ) : myclass_func(funcc) {}
+      89             : /// This is the line minimiser
+      90             :   double linemin( const std::vector<double>& dir, std::vector<double>& p, engf_pointer myfunc );
+      91             : };
+      92             : 
+      93             : template <class FCLASS>
+      94         897 : double MinimiseBase<FCLASS>::linemin( const std::vector<double>& dir, std::vector<double>& p, engf_pointer myfunc ) {
+      95             :   // Construct the object that turns points on a line into vectors
+      96         897 :   F1dim<FCLASS> f1dim( p, dir, myclass_func, NULL, myfunc );
+      97             : 
+      98             :   // Construct an object that will do the line search for the minimum
+      99         897 :   Minimise1DBrent<F1dim<FCLASS> > bb(f1dim);
+     100             : 
+     101             :   // This does the actual line minimisation
+     102         897 :   double ax=0.0, xx=1.0;
+     103         897 :   bb.bracket( ax, xx, &F1dim<FCLASS>::getEng );
+     104         897 :   double xmin=bb.minimise( &F1dim<FCLASS>::getEng );
+     105       19725 :   for(unsigned i=0; i<p.size(); ++i) p[i] += xmin*dir[i];
+     106        1794 :   return bb.getMinimumValue();
+     107             : }
+     108             : 
+     109             : template <class FCLASS>
+     110         897 : double MinimiseBase<FCLASS>::calcDerivatives( const std::vector<double>& p, std::vector<double>& der, engf_pointer myfunc ) {
+     111         897 :   return (myclass_func->*myfunc)( p, der );
+     112             : }
+     113             : 
+     114             : }
+     115             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MolDataClass.cpp.func-sort-c.html b/coverage/tools/MolDataClass.cpp.func-sort-c.html new file mode 100644 index 000000000000..bb071a038bd5 --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - tools/MolDataClass.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MolDataClass.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40647785.1 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12MolDataClass33numberOfAtomsPerResidueInBackboneERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE25
_ZN4PLMD12MolDataClass13specialSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_RKNS_3PDBERSt6vectorINS_10AtomNumberESaISD_EE589
_ZN4PLMD12MolDataClass21getBackboneForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjRKNS_3PDBERSt6vectorINS_10AtomNumberESaISF_EE2652
_ZN4PLMD12MolDataClass15isTerminalGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3413
_ZN4PLMD12MolDataClass14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_8125
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MolDataClass.cpp.func.html b/coverage/tools/MolDataClass.cpp.func.html new file mode 100644 index 000000000000..472c42f5044d --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - tools/MolDataClass.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MolDataClass.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40647785.1 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12MolDataClass13specialSymbolERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_RKNS_3PDBERSt6vectorINS_10AtomNumberESaISD_EE589
_ZN4PLMD12MolDataClass14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_8125
_ZN4PLMD12MolDataClass15isTerminalGroupERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3413
_ZN4PLMD12MolDataClass21getBackboneForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjRKNS_3PDBERSt6vectorINS_10AtomNumberESaISF_EE2652
_ZN4PLMD12MolDataClass33numberOfAtomsPerResidueInBackboneERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE25
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MolDataClass.cpp.gcov.html b/coverage/tools/MolDataClass.cpp.gcov.html new file mode 100644 index 000000000000..d5d0f2b93952 --- /dev/null +++ b/coverage/tools/MolDataClass.cpp.gcov.html @@ -0,0 +1,664 @@ + + + + + + + + LCOV - plumed test coverage - tools/MolDataClass.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MolDataClass.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:40647785.1 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MolDataClass.h"
+      23             : #include "Exception.h"
+      24             : #include "Tools.h"
+      25             : #include "PDB.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29          25 : unsigned MolDataClass::numberOfAtomsPerResidueInBackbone( const std::string& type ) {
+      30          25 :   if( type=="protein" ) return 5;
+      31           0 :   else if( type=="dna" ) return 6;
+      32           0 :   else if( type=="rna" ) return 6;
+      33           0 :   else return 0;
+      34             : }
+      35             : 
+      36        8125 : bool MolDataClass::allowedResidue( const std::string& type, const std::string& residuename ) {
+      37        8125 :   if( type=="protein" ) {
+      38        6018 :     if(residuename=="ALA") return true;
+      39        5756 :     else if(residuename=="ARG") return true;
+      40        5756 :     else if(residuename=="ASN") return true;
+      41        5756 :     else if(residuename=="ASP") return true;
+      42        5748 :     else if(residuename=="CYS") return true;
+      43        5748 :     else if(residuename=="GLN") return true;
+      44        5748 :     else if(residuename=="GLU") return true;
+      45        5740 :     else if(residuename=="GLY") return true;
+      46        5732 :     else if(residuename=="HIS") return true;
+      47        5732 :     else if(residuename=="ILE") return true;
+      48        5730 :     else if(residuename=="LEU") return true;
+      49        5730 :     else if(residuename=="LYS") return true;
+      50        5726 :     else if(residuename=="MET") return true;
+      51        5726 :     else if(residuename=="PHE") return true;
+      52        5722 :     else if(residuename=="PRO") return true;
+      53        5715 :     else if(residuename=="SER") return true;
+      54        5711 :     else if(residuename=="THR") return true;
+      55        5691 :     else if(residuename=="TRP") return true;
+      56        5681 :     else if(residuename=="TYR") return true;
+      57        5677 :     else if(residuename=="VAL") return true;
+      58             : // Terminal groups
+      59         489 :     else if(residuename=="ACE") return true;
+      60         483 :     else if(residuename=="NME") return true;
+      61         477 :     else if(residuename=="NH2") return true;
+      62             : // Alternative residue names in common force fields
+      63         477 :     else if(residuename=="GLH") return true; // neutral GLU
+      64         477 :     else if(residuename=="ASH") return true; // neutral ASP
+      65         477 :     else if(residuename=="HID") return true; // HIS-D amber
+      66         477 :     else if(residuename=="HSD") return true; // HIS-D charmm
+      67         477 :     else if(residuename=="HIE") return true; // HIS-E amber
+      68         477 :     else if(residuename=="HSE") return true; // HIS-E charmm
+      69         477 :     else if(residuename=="HIP") return true; // HIS-P amber
+      70         477 :     else if(residuename=="HSP") return true; // HIS-P charmm
+      71             : // Weird amino acids
+      72         477 :     else if(residuename=="NLE") return true;
+      73         475 :     else if(residuename=="SFO") return true;
+      74         475 :     else return false;
+      75        2107 :   } else if( type=="dna" ) {
+      76         462 :     if(residuename=="A") return true;
+      77         397 :     else if(residuename=="A5") return true;
+      78         397 :     else if(residuename=="A3") return true;
+      79         397 :     else if(residuename=="AN") return true;
+      80         397 :     else if(residuename=="G") return true;
+      81         397 :     else if(residuename=="G5") return true;
+      82         397 :     else if(residuename=="G3") return true;
+      83         397 :     else if(residuename=="GN") return true;
+      84         397 :     else if(residuename=="T") return true;
+      85         393 :     else if(residuename=="T5") return true;
+      86         393 :     else if(residuename=="T3") return true;
+      87         393 :     else if(residuename=="TN") return true;
+      88         393 :     else if(residuename=="C") return true;
+      89         393 :     else if(residuename=="C5") return true;
+      90         393 :     else if(residuename=="C3") return true;
+      91         393 :     else if(residuename=="CN") return true;
+      92         393 :     else if(residuename=="DA") return true;
+      93         393 :     else if(residuename=="DA5") return true;
+      94         393 :     else if(residuename=="DA3") return true;
+      95         393 :     else if(residuename=="DAN") return true;
+      96         393 :     else if(residuename=="DG") return true;
+      97         392 :     else if(residuename=="DG5") return true;
+      98         392 :     else if(residuename=="DG3") return true;
+      99         392 :     else if(residuename=="DGN") return true;
+     100         392 :     else if(residuename=="DT") return true;
+     101         392 :     else if(residuename=="DT5") return true;
+     102         392 :     else if(residuename=="DT3") return true;
+     103         392 :     else if(residuename=="DTN") return true;
+     104         392 :     else if(residuename=="DC") return true;
+     105         391 :     else if(residuename=="DC5") return true;
+     106         391 :     else if(residuename=="DC3") return true;
+     107         391 :     else if(residuename=="DCN") return true;
+     108         391 :     else return false;
+     109        1645 :   } else if( type=="rna" ) {
+     110         865 :     if(residuename=="A") return true;
+     111         808 :     else if(residuename=="A5") return true;
+     112         808 :     else if(residuename=="A3") return true;
+     113         808 :     else if(residuename=="AN") return true;
+     114         808 :     else if(residuename=="G") return true;
+     115         786 :     else if(residuename=="G5") return true;
+     116         782 :     else if(residuename=="G3") return true;
+     117         782 :     else if(residuename=="GN") return true;
+     118         782 :     else if(residuename=="U") return true;
+     119         759 :     else if(residuename=="U5") return true;
+     120         759 :     else if(residuename=="U3") return true;
+     121         759 :     else if(residuename=="UN") return true;
+     122         759 :     else if(residuename=="C") return true;
+     123         744 :     else if(residuename=="C5") return true;
+     124         744 :     else if(residuename=="C3") return true;
+     125         740 :     else if(residuename=="CN") return true;
+     126         740 :     else if(residuename=="RA") return true;
+     127         632 :     else if(residuename=="RA5") return true;
+     128         601 :     else if(residuename=="RA3") return true;
+     129         601 :     else if(residuename=="RAN") return true;
+     130         601 :     else if(residuename=="RG") return true;
+     131         481 :     else if(residuename=="RG5") return true;
+     132         481 :     else if(residuename=="RG3") return true;
+     133         442 :     else if(residuename=="RGN") return true;
+     134         442 :     else if(residuename=="RU") return true;
+     135         342 :     else if(residuename=="RU5") return true;
+     136         342 :     else if(residuename=="RU3") return true;
+     137         311 :     else if(residuename=="RUN") return true;
+     138         311 :     else if(residuename=="RC") return true;
+     139         177 :     else if(residuename=="RC5") return true;
+     140         144 :     else if(residuename=="RC3") return true;
+     141         144 :     else if(residuename=="RCN") return true;
+     142         141 :     else return false;
+     143         780 :   } else if( type=="water" ) {
+     144         390 :     if(residuename=="SOL") return true;
+     145         274 :     if(residuename=="WAT") return true;
+     146         274 :     return false;
+     147         390 :   } else if( type=="ion" ) {
+     148         390 :     if(residuename=="IB+") return true;
+     149         390 :     if(residuename=="CA") return true;
+     150         390 :     if(residuename=="CL") return true;
+     151         384 :     if(residuename=="NA") return true;
+     152         372 :     if(residuename=="MG") return true;
+     153         372 :     if(residuename=="K") return true;
+     154         372 :     if(residuename=="RB") return true;
+     155         372 :     if(residuename=="CS") return true;
+     156         372 :     if(residuename=="LI") return true;
+     157         372 :     if(residuename=="ZN") return true;
+     158         372 :     return false;
+     159             :   }
+     160             :   return false;
+     161             : }
+     162             : 
+     163        2652 : void MolDataClass::getBackboneForResidue( const std::string& type, const unsigned& residuenum, const PDB& mypdb, std::vector<AtomNumber>& atoms ) {
+     164        2652 :   std::string residuename=mypdb.getResidueName( residuenum );
+     165        2652 :   plumed_massert( MolDataClass::allowedResidue( type, residuename ), "residue " + residuename + " unrecognized for molecule type " + type );
+     166        2652 :   if( type=="protein" ) {
+     167        2652 :     if( residuename=="GLY") {
+     168           0 :       atoms.resize(5);
+     169           0 :       atoms[0]=mypdb.getNamedAtomFromResidue("N",residuenum);
+     170           0 :       atoms[1]=mypdb.getNamedAtomFromResidue("CA",residuenum);
+     171           0 :       atoms[2]=mypdb.getNamedAtomFromResidue("HA2",residuenum);
+     172           0 :       atoms[3]=mypdb.getNamedAtomFromResidue("C",residuenum);
+     173           0 :       atoms[4]=mypdb.getNamedAtomFromResidue("O",residuenum);
+     174        2652 :     } else if( residuename=="ACE") {
+     175           0 :       atoms.resize(1);
+     176           0 :       atoms[0]=mypdb.getNamedAtomFromResidue("C",residuenum);
+     177        5304 :     } else if( residuename=="NME"||residuename=="NH2") {
+     178           0 :       atoms.resize(1);
+     179           0 :       atoms[0]=mypdb.getNamedAtomFromResidue("N",residuenum);
+     180             :     } else {
+     181        2652 :       atoms.resize(5);
+     182        2652 :       atoms[0]=mypdb.getNamedAtomFromResidue("N",residuenum);
+     183        2652 :       atoms[1]=mypdb.getNamedAtomFromResidue("CA",residuenum);
+     184        2652 :       atoms[2]=mypdb.getNamedAtomFromResidue("CB",residuenum);
+     185        2652 :       atoms[3]=mypdb.getNamedAtomFromResidue("C",residuenum);
+     186        2652 :       atoms[4]=mypdb.getNamedAtomFromResidue("O",residuenum);
+     187             :     }
+     188           0 :   } else if( type=="dna" || type=="rna" ) {
+     189           0 :     atoms.resize(6);
+     190           0 :     atoms[0]=mypdb.getNamedAtomFromResidue("P",residuenum);
+     191           0 :     atoms[1]=mypdb.getNamedAtomFromResidue("O5\'",residuenum);
+     192           0 :     atoms[2]=mypdb.getNamedAtomFromResidue("C5\'",residuenum);
+     193           0 :     atoms[3]=mypdb.getNamedAtomFromResidue("C4\'",residuenum);
+     194           0 :     atoms[4]=mypdb.getNamedAtomFromResidue("C3\'",residuenum);
+     195           0 :     atoms[5]=mypdb.getNamedAtomFromResidue("O3\'",residuenum);
+     196             :   }
+     197             :   else {
+     198           0 :     plumed_merror(type + " is not a valid molecule type");
+     199             :   }
+     200        2652 : }
+     201             : 
+     202        3413 : bool MolDataClass::isTerminalGroup( const std::string& type, const std::string& residuename ) {
+     203        3413 :   if( type=="protein" ) {
+     204        3413 :     if( residuename=="ACE" ) return true;
+     205        3086 :     else if( residuename=="NME" ) return true;
+     206        2759 :     else if( residuename=="NH2" ) return true;
+     207        2759 :     else return false;
+     208             :   } else {
+     209           0 :     plumed_merror(type + " is not a valid molecule type");
+     210             :   }
+     211             :   return false;
+     212             : }
+     213             : 
+     214         589 : void MolDataClass::specialSymbol( const std::string& type, const std::string& symbol, const PDB& mypdb, std::vector<AtomNumber>& numbers ) {
+     215         819 :   if(type=="protein" || type=="rna" || type=="dna") {
+     216             : // symbol should be something like
+     217             : // phi-123 i.e. phi torsion of residue 123 of first chain
+     218             : // psi-A321 i.e. psi torsion of residue 321 of chain A
+     219             : // psi-4_321 is psi torsion of residue 321 of chain 4
+     220             : // psi-A_321 is equivalent to psi-A321
+     221         589 :     numbers.resize(0);
+     222             : 
+     223             : // special cases:
+     224         589 :     if(symbol=="protein") {
+     225           1 :       const auto & all = mypdb.getAtomNumbers();
+     226         133 :       for(auto a : all) {
+     227         132 :         auto resname=mypdb.getResidueName(a);
+     228         132 :         Tools::stripLeadingAndTrailingBlanks(resname);
+     229         264 :         if(allowedResidue("protein",resname)) numbers.push_back(a);
+     230             :       }
+     231           7 :       return;
+     232             :     }
+     233             : 
+     234         588 :     if(symbol=="nucleic") {
+     235           2 :       const auto & all = mypdb.getAtomNumbers();
+     236         457 :       for(auto a : all) {
+     237         455 :         auto resname=mypdb.getResidueName(a);
+     238         455 :         Tools::stripLeadingAndTrailingBlanks(resname);
+     239        1101 :         if(allowedResidue("dna",resname) || allowedResidue("rna",resname)) numbers.push_back(a);
+     240             :       }
+     241           2 :       return;
+     242             :     }
+     243             : 
+     244         586 :     if(symbol=="ions") {
+     245           1 :       const auto & all = mypdb.getAtomNumbers();
+     246         391 :       for(auto a : all) {
+     247         390 :         auto resname=mypdb.getResidueName(a);
+     248         390 :         Tools::stripLeadingAndTrailingBlanks(resname);
+     249         780 :         if(allowedResidue("ion",resname)) numbers.push_back(a);
+     250             :       }
+     251           1 :       return;
+     252             :     }
+     253             : 
+     254         585 :     if(symbol=="water") {
+     255           1 :       const auto & all = mypdb.getAtomNumbers();
+     256         391 :       for(auto a : all) {
+     257         390 :         auto resname=mypdb.getResidueName(a);
+     258         390 :         Tools::stripLeadingAndTrailingBlanks(resname);
+     259         780 :         if(allowedResidue("water",resname)) numbers.push_back(a);
+     260             :       }
+     261           1 :       return;
+     262             :     }
+     263             : 
+     264         584 :     if(symbol=="hydrogens") {
+     265           1 :       const auto & all = mypdb.getAtomNumbers();
+     266         391 :       for(auto a : all) {
+     267         390 :         auto atomname=mypdb.getAtomName(a);
+     268         390 :         Tools::stripLeadingAndTrailingBlanks(atomname);
+     269         390 :         auto notnumber=atomname.find_first_not_of("0123456789");
+     270         390 :         if(notnumber!=std::string::npos && atomname[notnumber]=='H') numbers.push_back(a);
+     271             :       }
+     272           1 :       return;
+     273             :     }
+     274             : 
+     275         583 :     if(symbol=="nonhydrogens") {
+     276           1 :       const auto & all = mypdb.getAtomNumbers();
+     277         391 :       for(auto a : all) {
+     278         390 :         auto atomname=mypdb.getAtomName(a);
+     279         390 :         Tools::stripLeadingAndTrailingBlanks(atomname);
+     280         390 :         auto notnumber=atomname.find_first_not_of("0123456789");
+     281         390 :         if(!(notnumber!=std::string::npos && atomname[notnumber]=='H')) numbers.push_back(a);
+     282             :       }
+     283           1 :       return;
+     284             :     }
+     285             : 
+     286             : 
+     287             :     std::size_t dash=symbol.find_first_of('-');
+     288         582 :     if(dash==std::string::npos) plumed_error() << "Unrecognized symbol "<<symbol;
+     289             : 
+     290         582 :     std::size_t firstunderscore=symbol.find_first_of('_',dash+1);
+     291         582 :     std::size_t firstnum=symbol.find_first_of("0123456789",dash+1);
+     292         582 :     std::string name=symbol.substr(0,dash);
+     293             :     unsigned resnum;
+     294             :     std::string resname;
+     295             :     std::string chainid;
+     296         582 :     if(firstunderscore != std::string::npos) {
+     297           6 :       Tools::convert( symbol.substr(firstunderscore+1), resnum );
+     298          12 :       chainid=symbol.substr(dash+1,firstunderscore-(dash+1));
+     299         576 :     } else if(firstnum==dash+1) {
+     300        1132 :       Tools::convert( symbol.substr(dash+1), resnum );
+     301             :       chainid="*"; // this is going to match the first chain
+     302             :     } else {
+     303             :       // if chain id is provided:
+     304          10 :       Tools::convert( symbol.substr(firstnum), resnum );
+     305          20 :       chainid=symbol.substr(dash+1,firstnum-(dash+1)); // this is going to match the proper chain
+     306             :     }
+     307         582 :     resname= mypdb.getResidueName(resnum,chainid);
+     308         582 :     Tools::stripLeadingAndTrailingBlanks(resname);
+     309        1164 :     if(allowedResidue("protein",resname)) {
+     310         145 :       if( name=="phi" && !isTerminalGroup("protein",resname) ) {
+     311          76 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum-1,chainid));
+     312          76 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     313          76 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     314          76 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum,chainid));
+     315         133 :       } else if( name=="psi" && !isTerminalGroup("protein",resname) ) {
+     316         128 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     317         128 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     318         128 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum,chainid));
+     319         128 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum+1,chainid));
+     320           6 :       } else if( name=="omega" && !isTerminalGroup("protein",resname) ) {
+     321           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum-1,chainid));
+     322           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C",resnum-1,chainid));
+     323           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     324           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     325           5 :       } else if( name=="chi1" && !isTerminalGroup("protein",resname) ) {
+     326           3 :         if ( resname=="GLY" || resname=="ALA" || resname=="SFO" ) plumed_merror("chi-1 is not defined for ALA, GLY and SFO");
+     327           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N",resnum,chainid));
+     328           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     329           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CB",resnum,chainid));
+     330           2 :         if(resname=="ILE"||resname=="VAL") {
+     331           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG1",resnum,chainid));
+     332           1 :         } else if(resname=="CYS") {
+     333           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("SG",resnum,chainid));
+     334           1 :         } else if(resname=="THR") {
+     335           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OG1",resnum,chainid));
+     336           1 :         } else if(resname=="SER") {
+     337           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OG",resnum,chainid));
+     338             :         } else {
+     339           2 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+     340             :         }
+     341           4 :       } else if( name=="chi2" && !isTerminalGroup("protein",resname) ) {
+     342           5 :         if ( resname=="GLY" || resname=="ALA" || resname=="SFO" || resname=="CYS" || resname=="SER" ||
+     343           2 :              resname=="THR" || resname=="VAL" ) plumed_merror("chi-2 is not defined for ALA, GLY, CYS, SER, THR, VAL and SFO");
+     344           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CA",resnum,chainid));
+     345           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CB",resnum,chainid));
+     346             : 
+     347           1 :         if(resname=="ILE") {
+     348           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG1",resnum,chainid));
+     349             :         } else {
+     350           2 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+     351             :         }
+     352           2 :         if(resname=="ASN" || resname=="ASP") {
+     353           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OD1",resnum,chainid));
+     354           1 :         } else if(resname=="HIS") {
+     355           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("ND1",resnum,chainid));
+     356           4 :         } else if(resname=="LEU" || resname=="PHE" || resname=="TRP" || resname=="TYR") {
+     357           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD1",resnum,chainid));
+     358           1 :         } else if(resname=="MET") {
+     359           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("SD",resnum,chainid));
+     360             :         } else {
+     361           2 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+     362             :         }
+     363           2 :       } else if( name=="chi3" && !isTerminalGroup("protein",resname) ) {
+     364           0 :         if (!( resname=="ARG" || resname=="GLN" || resname=="GLU" || resname=="LYS" ||
+     365           0 :                resname=="MET" )) plumed_merror("chi-3 is defined only for ARG, GLN, GLU, LYS and MET");
+     366           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CB",resnum,chainid));
+     367           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+     368             : 
+     369           0 :         if(resname=="MET") {
+     370           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("SD",resnum,chainid));
+     371             :         } else {
+     372           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+     373             :         }
+     374           0 :         if(resname=="GLN" || resname=="GLU") {
+     375           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("OE1",resnum,chainid));
+     376           0 :         } else if(resname=="LYS" || resname=="MET") {
+     377           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CE",resnum,chainid));
+     378             :         } else {
+     379           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NE",resnum,chainid));
+     380             :         }
+     381           2 :       } else if( name=="chi4" && !isTerminalGroup("protein",resname) ) {
+     382           0 :         if (!( resname=="ARG" || resname=="LYS" )) plumed_merror("chi-4 is defined only for ARG and LYS");
+     383           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CG",resnum,chainid));
+     384           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+     385             : 
+     386           0 :         if(resname=="ARG") {
+     387           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NE",resnum,chainid));
+     388           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CZ",resnum,chainid));
+     389             :         } else {
+     390           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CE",resnum,chainid));
+     391           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NZ",resnum,chainid));
+     392             :         }
+     393           2 :       } else if( name=="chi5" && !isTerminalGroup("protein",resname) ) {
+     394           0 :         if (!( resname=="ARG" )) plumed_merror("chi-5 is defined only for ARG");
+     395           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CD",resnum,chainid));
+     396           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NE",resnum,chainid));
+     397           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("CZ",resnum,chainid));
+     398           0 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("NH1",resnum,chainid));
+     399           3 :       } else if( name=="sidechain" && !isTerminalGroup("protein",resname) ) {
+     400           1 :         if(resname=="GLY") plumed_merror("sidechain is not defined for GLY");
+     401           1 :         std::vector<AtomNumber> tmpnum1(mypdb.getAtomsInResidue(resnum,chainid));
+     402          15 :         for(unsigned i=0; i<tmpnum1.size(); i++) {
+     403          66 :           if(mypdb.getAtomName(tmpnum1[i])!="N"&&mypdb.getAtomName(tmpnum1[i])!="CA"&&
+     404          70 :               mypdb.getAtomName(tmpnum1[i])!="C"&&mypdb.getAtomName(tmpnum1[i])!="O"&&
+     405          61 :               mypdb.getAtomName(tmpnum1[i])!="HA"&&mypdb.getAtomName(tmpnum1[i])!="H"&&
+     406          59 :               mypdb.getAtomName(tmpnum1[i])!="HN"&&mypdb.getAtomName(tmpnum1[i])!="H1"&&
+     407          59 :               mypdb.getAtomName(tmpnum1[i])!="H2"&&mypdb.getAtomName(tmpnum1[i])!="H3"&&
+     408          59 :               mypdb.getAtomName(tmpnum1[i])!="OXT"&&mypdb.getAtomName(tmpnum1[i])!="OT1"&&
+     409          73 :               mypdb.getAtomName(tmpnum1[i])!="OT2"&&mypdb.getAtomName(tmpnum1[i])!="OC1"&&
+     410          32 :               mypdb.getAtomName(tmpnum1[i])!="OC2") {
+     411           9 :             numbers.push_back( tmpnum1[i] );
+     412             :           }
+     413             :         }
+     414           2 :       } else if( name=="back" && !isTerminalGroup("protein",resname) ) {
+     415           1 :         std::vector<AtomNumber> tmpnum1(mypdb.getAtomsInResidue(resnum,chainid));
+     416          15 :         for(unsigned i=0; i<tmpnum1.size(); i++) {
+     417          66 :           if(mypdb.getAtomName(tmpnum1[i])=="N"||mypdb.getAtomName(tmpnum1[i])=="CA"||
+     418          70 :               mypdb.getAtomName(tmpnum1[i])=="C"||mypdb.getAtomName(tmpnum1[i])=="O"||
+     419          61 :               mypdb.getAtomName(tmpnum1[i])=="HA"||mypdb.getAtomName(tmpnum1[i])=="H"||
+     420          59 :               mypdb.getAtomName(tmpnum1[i])=="HN"||mypdb.getAtomName(tmpnum1[i])=="H1"||
+     421          59 :               mypdb.getAtomName(tmpnum1[i])=="H2"||mypdb.getAtomName(tmpnum1[i])=="H3"||
+     422          59 :               mypdb.getAtomName(tmpnum1[i])=="OXT"||mypdb.getAtomName(tmpnum1[i])=="OT1"||
+     423          59 :               mypdb.getAtomName(tmpnum1[i])=="OT2"||mypdb.getAtomName(tmpnum1[i])=="OC1"||
+     424          59 :               mypdb.getAtomName(tmpnum1[i])=="OC2"||mypdb.getAtomName(tmpnum1[i])=="HA1"||
+     425          63 :               mypdb.getAtomName(tmpnum1[i])=="HA2"||mypdb.getAtomName(tmpnum1[i])=="HA3") {
+     426           5 :             numbers.push_back( tmpnum1[i] );
+     427             :           }
+     428             :         }
+     429           0 :       } else numbers.push_back(mypdb.getNamedAtomFromResidueAndChain(name,resnum,chainid));
+     430             : 
+     431         488 :     } else if( allowedResidue("rna",resname) || allowedResidue("dna",resname)) {
+     432             :       std::string basetype;
+     433         474 :       if(resname.find_first_of("A")!=std::string::npos) basetype+="A";
+     434         474 :       if(resname.find_first_of("U")!=std::string::npos) basetype+="U";
+     435         474 :       if(resname.find_first_of("T")!=std::string::npos) basetype+="T";
+     436         474 :       if(resname.find_first_of("C")!=std::string::npos) basetype+="C";
+     437         474 :       if(resname.find_first_of("G")!=std::string::npos) basetype+="G";
+     438         474 :       plumed_massert(basetype.length()==1,"cannot find type of rna/dna residue "+resname+" "+basetype);
+     439         474 :       if( name=="chi" ) {
+     440          68 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     441          68 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     442          99 :         if(basetype=="T" || basetype=="U" || basetype=="C") {
+     443          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     444          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     445          47 :         } else if(basetype=="G" || basetype=="A") {
+     446          50 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N9",resnum,chainid));
+     447          50 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     448           0 :         } else plumed_error();
+     449         440 :       } else if( name=="alpha" ) {
+     450          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O3\'",resnum-1,chainid));
+     451          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("P",resnum,chainid));
+     452          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O5\'",resnum,chainid));
+     453          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5\'",resnum,chainid));
+     454         433 :       } else if( name=="beta" ) {
+     455          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("P",resnum,chainid));
+     456          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O5\'",resnum,chainid));
+     457          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5\'",resnum,chainid));
+     458          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     459         426 :       } else if( name=="gamma" ) {
+     460          54 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O5\'",resnum,chainid));
+     461          54 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5\'",resnum,chainid));
+     462          54 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     463          54 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     464         399 :       } else if( name=="delta" ) {
+     465           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5\'",resnum,chainid));
+     466           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     467           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     468           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O3\'",resnum,chainid));
+     469         398 :       } else if( name=="epsilon" ) {
+     470          16 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     471          16 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     472          16 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O3\'",resnum,chainid));
+     473          16 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("P",resnum+1,chainid));
+     474         390 :       } else if( name=="zeta" ) {
+     475          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     476          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O3\'",resnum,chainid));
+     477          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("P",resnum+1,chainid));
+     478          14 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O5\'",resnum+1,chainid));
+     479         383 :       } else if( name=="v0" ) {
+     480           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     481           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     482           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     483           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2\'",resnum,chainid));
+     484         380 :       } else if( name=="v1" ) {
+     485           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     486           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     487           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2\'",resnum,chainid));
+     488           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     489         377 :       } else if( name=="v2" ) {
+     490           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     491           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2\'",resnum,chainid));
+     492           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     493           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     494         374 :       } else if( name=="v3" ) {
+     495           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2\'",resnum,chainid));
+     496           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     497           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     498           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     499         371 :       } else if( name=="v4" ) {
+     500           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     501           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     502           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     503           6 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     504         368 :       } else if( name=="back" ) {
+     505           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("P",resnum,chainid));
+     506           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O5\'",resnum,chainid));
+     507           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5\'",resnum,chainid));
+     508           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     509           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     510           2 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O3\'",resnum,chainid));
+     511         367 :       } else if( name=="sugar" ) {
+     512         104 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4\'",resnum,chainid));
+     513         104 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4\'",resnum,chainid));
+     514         104 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C1\'",resnum,chainid));
+     515         104 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2\'",resnum,chainid));
+     516         104 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C3\'",resnum,chainid));
+     517         315 :       } else if( name=="base" ) {
+     518          25 :         if(basetype=="C") {
+     519          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     520          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     521          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O2",resnum,chainid));
+     522          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N3",resnum,chainid));
+     523          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     524          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N4",resnum,chainid));
+     525          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5",resnum,chainid));
+     526          18 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     527          16 :         } else if(basetype=="U") {
+     528           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     529           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     530           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O2",resnum,chainid));
+     531           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N3",resnum,chainid));
+     532           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     533           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4",resnum,chainid));
+     534           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5",resnum,chainid));
+     535           4 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     536          14 :         } else if(basetype=="T") {
+     537           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     538           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     539           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O2",resnum,chainid));
+     540           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N3",resnum,chainid));
+     541           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     542           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O4",resnum,chainid));
+     543           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5",resnum,chainid));
+     544           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C7",resnum,chainid));
+     545           0 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     546          14 :         } else if(basetype=="G") {
+     547           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N9",resnum,chainid));
+     548           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     549           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N3",resnum,chainid));
+     550           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     551           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N2",resnum,chainid));
+     552           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     553           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     554           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("O6",resnum,chainid));
+     555           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5",resnum,chainid));
+     556           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N7",resnum,chainid));
+     557           6 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C8",resnum,chainid));
+     558          11 :         } else if(basetype=="A") {
+     559          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N9",resnum,chainid));
+     560          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     561          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N1",resnum,chainid));
+     562          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     563          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N3",resnum,chainid));
+     564          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     565          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N6",resnum,chainid));
+     566          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C5",resnum,chainid));
+     567          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("N7",resnum,chainid));
+     568          22 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C8",resnum,chainid));
+     569           0 :         } else plumed_error();
+     570         290 :       } else if( name=="lcs" ) {
+     571         568 :         numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C2",resnum,chainid));
+     572         752 :         if(basetype=="T" || basetype=="U" || basetype=="C") {
+     573         296 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     574         296 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     575         216 :         } else if(basetype=="G" || basetype=="A") {
+     576         272 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C6",resnum,chainid));
+     577         272 :           numbers.push_back(mypdb.getNamedAtomFromResidueAndChain("C4",resnum,chainid));
+     578           0 :         } else plumed_error();
+     579          12 :       } else numbers.push_back(mypdb.getNamedAtomFromResidueAndChain(name,resnum,chainid));
+     580           2 :     } else numbers.push_back(mypdb.getNamedAtomFromResidueAndChain(name,resnum,chainid));
+     581             :   }
+     582             :   else {
+     583           0 :     plumed_merror(type + " is not a valid molecule type");
+     584             :   }
+     585             : }
+     586             : 
+     587             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.cpp.func-sort-c.html b/coverage/tools/MultiValue.cpp.func-sort-c.html new file mode 100644 index 000000000000..7151fe625647 --- /dev/null +++ b/coverage/tools/MultiValue.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/MultiValue.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MultiValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6262100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue6resizeERKmS2_41860
_ZN4PLMD10MultiValue15copyDerivativesERS0_50656
_ZNK4PLMD10MultiValue10copyValuesERS0_57565
_ZN4PLMD10MultiValueC2ERKmS2_360243
_ZN4PLMD10MultiValue9chainRuleERKjS2_S2_S2_RKdS2_RSt6vectorIdSaIdEE502660
_ZN4PLMD10MultiValue12quotientRuleERKjS2_1905928
_ZN4PLMD10MultiValue23clearTemporyDerivativesEv2102001
_ZN4PLMD10MultiValue8clearAllEv2102001
_ZN4PLMD10MultiValue5clearERKj8420653
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.cpp.func.html b/coverage/tools/MultiValue.cpp.func.html new file mode 100644 index 000000000000..557fb1745c4a --- /dev/null +++ b/coverage/tools/MultiValue.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/MultiValue.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MultiValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6262100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue12quotientRuleERKjS2_1905928
_ZN4PLMD10MultiValue15copyDerivativesERS0_50656
_ZN4PLMD10MultiValue23clearTemporyDerivativesEv2102001
_ZN4PLMD10MultiValue5clearERKj8420653
_ZN4PLMD10MultiValue6resizeERKmS2_41860
_ZN4PLMD10MultiValue8clearAllEv2102001
_ZN4PLMD10MultiValue9chainRuleERKjS2_S2_S2_RKdS2_RSt6vectorIdSaIdEE502660
_ZN4PLMD10MultiValueC2ERKmS2_360243
_ZNK4PLMD10MultiValue10copyValuesERS0_57565
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.cpp.gcov.html b/coverage/tools/MultiValue.cpp.gcov.html new file mode 100644 index 000000000000..1fb556b4e40e --- /dev/null +++ b/coverage/tools/MultiValue.cpp.gcov.html @@ -0,0 +1,197 @@ + + + + + + + + LCOV - plumed test coverage - tools/MultiValue.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MultiValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6262100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "MultiValue.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : 
+      26      360243 : MultiValue::MultiValue( const size_t& nvals, const size_t& nder ):
+      27      360243 :   values(nvals),
+      28      360243 :   nderivatives(nder),
+      29      360243 :   derivatives(nvals*nder),
+      30      360243 :   tmpval(0),
+      31      360243 :   tmpder(nder),
+      32      720486 :   atLeastOneSet(false)
+      33             : {
+      34      360243 :   std::vector<unsigned> myind( nder );
+      35    10704392 :   for(unsigned i=0; i<nder; ++i) myind[i]=i;
+      36      360243 :   hasDerivatives.createIndexListFromVector( myind );
+      37      360243 : }
+      38             : 
+      39       41860 : void MultiValue::resize( const size_t& nvals, const size_t& nder ) {
+      40       41860 :   values.resize(nvals); nderivatives=nder; derivatives.resize( nvals*nder );
+      41       41860 :   tmpder.resize( nder ); hasDerivatives.clear(); std::vector<unsigned> myind( nder );
+      42    10858510 :   for(unsigned i=0; i<nder; ++i) myind[i]=i;
+      43       41860 :   hasDerivatives.createIndexListFromVector( myind );
+      44       41860 :   atLeastOneSet=false;
+      45       41860 : }
+      46             : 
+      47     2102001 : void MultiValue::clearAll() {
+      48     2102001 :   if( atLeastOneSet && !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+      49    10522654 :   for(unsigned i=0; i<values.size(); ++i) clear(i);
+      50     2102001 :   clearTemporyDerivatives(); hasDerivatives.deactivateAll(); atLeastOneSet=false;
+      51     2102001 : }
+      52             : 
+      53     8420653 : void MultiValue::clear( const unsigned& ival ) {
+      54     8420653 :   values[ival]=0;
+      55     8420653 :   unsigned base=ival*nderivatives, ndert=hasDerivatives.getNumberActive();
+      56   315735373 :   for(unsigned i=0; i<ndert; ++i) derivatives[ base+hasDerivatives[i] ]=0.;
+      57     8420653 : }
+      58             : 
+      59     2102001 : void MultiValue::clearTemporyDerivatives() {
+      60     2102001 :   unsigned ndert=hasDerivatives.getNumberActive(); tmpval=0.;
+      61    82216467 :   for(unsigned i=0; i<ndert; ++i) tmpder[ hasDerivatives[i] ]=0.;
+      62     2102001 : }
+      63             : 
+      64      502660 : void MultiValue::chainRule( const unsigned& ival, const unsigned& iout, const unsigned& stride, const unsigned& off,
+      65             :                             const double& df, const unsigned& bufstart, std::vector<double>& buffer ) {
+      66      502660 :   if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+      67             : 
+      68             :   plumed_dbg_assert( off<stride );
+      69      502660 :   unsigned base=nderivatives*ival, ndert=hasDerivatives.getNumberActive();
+      70      502660 :   unsigned start=bufstart+stride*(nderivatives+1)*iout + stride;
+      71    29262405 :   for(unsigned i=0; i<ndert; ++i) {
+      72             :     unsigned jder=hasDerivatives[i];
+      73    28759745 :     buffer[start+jder*stride] += df*derivatives[base+jder];
+      74             :   }
+      75      502660 : }
+      76             : 
+      77       57565 : void MultiValue::copyValues( MultiValue& outvals ) const {
+      78             :   plumed_dbg_assert( values.size()<=outvals.getNumberOfValues() );
+      79      183225 :   for(unsigned i=0; i<values.size(); ++i) outvals.setValue( i, values[i] );
+      80             : 
+      81       57565 : }
+      82             : 
+      83       50656 : void MultiValue::copyDerivatives( MultiValue& outvals ) {
+      84             :   plumed_dbg_assert( values.size()<=outvals.getNumberOfValues() && nderivatives<=outvals.getNumberOfDerivatives() );
+      85       50656 :   if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+      86             : 
+      87       50656 :   outvals.atLeastOneSet=true; unsigned ndert=hasDerivatives.getNumberActive();
+      88     3766585 :   for(unsigned j=0; j<ndert; ++j) {
+      89     3715929 :     unsigned jder=hasDerivatives[j]; outvals.hasDerivatives.activate(jder);
+      90             :   }
+      91             : 
+      92             :   unsigned base=0, obase=0;
+      93      162498 :   for(unsigned i=0; i<values.size(); ++i) {
+      94     8330096 :     for(unsigned j=0; j<ndert; ++j) {
+      95             :       unsigned jder=hasDerivatives[j];
+      96     8218254 :       outvals.derivatives[obase+jder] += derivatives[base+jder];
+      97             :     }
+      98      111842 :     obase+=outvals.nderivatives; base+=nderivatives;
+      99             :   }
+     100       50656 : }
+     101             : 
+     102     1905928 : void MultiValue::quotientRule( const unsigned& nder, const unsigned& oder ) {
+     103             :   plumed_dbg_assert( nder<values.size() && oder<values.size() );
+     104     1905928 :   if( !hasDerivatives.updateComplete() ) hasDerivatives.updateActiveMembers();
+     105             : 
+     106     1905928 :   unsigned ndert=hasDerivatives.getNumberActive(); double wpref;
+     107     1905928 :   unsigned obase=oder*nderivatives, nbase=nder*nderivatives;
+     108             : 
+     109     1905928 :   if( std::fabs(tmpval)>epsilon ) { wpref=1.0/tmpval; }
+     110             :   else { wpref=1.0; }
+     111             : 
+     112     1905928 :   double pref = values[nder]*wpref*wpref;
+     113   183543652 :   for(unsigned j=0; j<ndert; ++j) {
+     114             :     unsigned jder=hasDerivatives[j];
+     115   181637724 :     derivatives[obase+jder] = wpref*derivatives[nbase+jder]  - pref*tmpder[jder];
+     116             :   }
+     117     1905928 :   values[oder] = wpref*values[nder];
+     118     1905928 : }
+     119             : 
+     120             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.h.func-sort-c.html b/coverage/tools/MultiValue.h.func-sort-c.html new file mode 100644 index 000000000000..8e6112f1c0ba --- /dev/null +++ b/coverage/tools/MultiValue.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/MultiValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MultiValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue11updateIndexERKj222000
_ZN4PLMD10MultiValue20addTemporyDerivativeERKjRKd36287202
_ZN4PLMD10MultiValue13setDerivativeERKjS2_RKd145616121
_ZN4PLMD10MultiValue13addDerivativeERKjS2_RKd1379641034
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.h.func.html b/coverage/tools/MultiValue.h.func.html new file mode 100644 index 000000000000..7f1ab4ffc51e --- /dev/null +++ b/coverage/tools/MultiValue.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/MultiValue.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MultiValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10MultiValue11updateIndexERKj222000
_ZN4PLMD10MultiValue13addDerivativeERKjS2_RKd1379641034
_ZN4PLMD10MultiValue13setDerivativeERKjS2_RKd145616121
_ZN4PLMD10MultiValue20addTemporyDerivativeERKjRKd36287202
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/MultiValue.h.gcov.html b/coverage/tools/MultiValue.h.gcov.html new file mode 100644 index 000000000000..de3b7ccfce24 --- /dev/null +++ b/coverage/tools/MultiValue.h.gcov.html @@ -0,0 +1,318 @@ + + + + + + + + LCOV - plumed test coverage - tools/MultiValue.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - MultiValue.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3636100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_MultiValue_h
+      23             : #define __PLUMED_tools_MultiValue_h
+      24             : 
+      25             : #include "Exception.h"
+      26             : #include "DynamicList.h"
+      27             : #include <vector>
+      28             : #include <cstddef>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : class MultiValue {
+      33             : private:
+      34             : /// Used to ensure rapid accumulation of derivatives
+      35             :   DynamicList<unsigned> hasDerivatives;
+      36             : /// Values of quantities
+      37             :   std::vector<double> values;
+      38             : /// Number of derivatives per value
+      39             :   unsigned nderivatives;
+      40             : /// Derivatives
+      41             :   std::vector<double> derivatives;
+      42             : /// Tempory value
+      43             :   double tmpval;
+      44             : /// Tempory vector of derivatives (used for calculating quotients
+      45             :   std::vector<double> tmpder;
+      46             : /// Logical to check if any derivatives were set
+      47             :   bool atLeastOneSet;
+      48             : /// This is a fudge to save on vector resizing in MultiColvar
+      49             :   std::vector<unsigned> indices, sort_indices;
+      50             :   std::vector<Vector> tmp_atoms;
+      51             : public:
+      52             :   MultiValue( const std::size_t&, const std::size_t& );
+      53             :   void resize( const std::size_t&, const std::size_t& );
+      54             : ///
+      55             :   std::vector<unsigned>& getIndices();
+      56             :   std::vector<unsigned>& getSortIndices();
+      57             :   std::vector<Vector>& getAtomVector();
+      58             : /// Get the number of values in the stash
+      59             :   unsigned getNumberOfValues() const ;
+      60             : /// Get the number of derivatives in the stash
+      61             :   unsigned getNumberOfDerivatives() const ;
+      62             : /// Set value numbered
+      63             :   void setValue( const unsigned&,  const double& );
+      64             : /// Add value numbered
+      65             :   void addValue( const unsigned&,  const double& );
+      66             : /// Add derivative
+      67             :   void addDerivative( const unsigned&, const unsigned&, const double& );
+      68             : /// Add to the tempory value
+      69             :   void addTemporyValue( const double& val );
+      70             : /// Add tempory derivatives - this is used for calculating quotients
+      71             :   void addTemporyDerivative( const unsigned& jder, const double& der );
+      72             : /// Set the value of the derivative
+      73             :   void setDerivative( const unsigned& ival, const unsigned& jder, const double& der);
+      74             : /// Return the ith value
+      75             :   double get( const unsigned& ) const ;
+      76             : /// Return a derivative value
+      77             :   double getDerivative( const unsigned&, const unsigned& ) const ;
+      78             : /// Get one of the tempory derivatives
+      79             :   double getTemporyDerivative( const unsigned& jder ) const ;
+      80             : /// Clear all values
+      81             :   void clearAll();
+      82             : /// Clear the tempory derivatives
+      83             :   void clearTemporyDerivatives();
+      84             : /// Clear a value
+      85             :   void clear( const unsigned& );
+      86             : /// Functions for accessing active list
+      87             :   bool updateComplete();
+      88             :   void emptyActiveMembers();
+      89             :   void putIndexInActiveArray( const unsigned & );
+      90             :   void updateIndex( const unsigned& );
+      91             :   void sortActiveList();
+      92             :   void completeUpdate();
+      93             :   void updateDynamicList();
+      94             :   bool isActive( const unsigned& ind ) const ;
+      95             : ///
+      96             :   unsigned getNumberActive() const ;
+      97             : ///
+      98             :   unsigned getActiveIndex( const unsigned& ) const ;
+      99             : /// Transfer derivatives to buffer
+     100             :   void chainRule( const unsigned&, const unsigned&, const unsigned&, const unsigned&, const double&, const unsigned&, std::vector<double>& buffer );
+     101             : ///
+     102             :   void copyValues( MultiValue& ) const ;
+     103             : ///
+     104             :   void copyDerivatives( MultiValue& );
+     105             : ///
+     106             :   void quotientRule( const unsigned& nder, const unsigned& oder );
+     107             : };
+     108             : 
+     109             : inline
+     110             : unsigned MultiValue::getNumberOfValues() const {
+     111   172405381 :   return values.size();
+     112             : }
+     113             : 
+     114             : inline
+     115             : unsigned MultiValue::getNumberOfDerivatives() const {
+     116    30916509 :   return nderivatives; //derivatives.ncols();
+     117             : }
+     118             : 
+     119             : inline
+     120             : double MultiValue::get( const unsigned& ival ) const {
+     121             :   plumed_dbg_assert( ival<=values.size() );
+     122   174379975 :   return values[ival];
+     123             : }
+     124             : 
+     125             : inline
+     126             : void MultiValue::setValue( const unsigned& ival,  const double& val) {
+     127             :   plumed_dbg_assert( ival<=values.size() );
+     128     1832439 :   values[ival]=val;
+     129             : }
+     130             : 
+     131             : inline
+     132             : void MultiValue::addValue( const unsigned& ival,  const double& val) {
+     133             :   plumed_dbg_assert( ival<=values.size() );
+     134    63014961 :   values[ival]+=val;
+     135             : }
+     136             : 
+     137             : inline
+     138  1379641034 : void MultiValue::addDerivative( const unsigned& ival, const unsigned& jder, const double& der) {
+     139  1379641034 :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
+     140  1379641034 :   hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder] += der;
+     141  1379641034 : }
+     142             : 
+     143             : inline
+     144             : void MultiValue::addTemporyValue( const double& val ) {
+     145     2783657 :   tmpval += val;
+     146             : }
+     147             : 
+     148             : inline
+     149    36287202 : void MultiValue::addTemporyDerivative( const unsigned& jder, const double& der ) {
+     150    36287202 :   plumed_dbg_assert( jder<nderivatives ); atLeastOneSet=true;
+     151    36287202 :   hasDerivatives.activate(jder); tmpder[jder] += der;
+     152    36287202 : }
+     153             : 
+     154             : 
+     155             : inline
+     156   145616121 : void MultiValue::setDerivative( const unsigned& ival, const unsigned& jder, const double& der) {
+     157   145616121 :   plumed_dbg_assert( ival<=values.size() && jder<nderivatives ); atLeastOneSet=true;
+     158   145616121 :   hasDerivatives.activate(jder); derivatives[nderivatives*ival+jder]=der;
+     159   145616121 : }
+     160             : 
+     161             : 
+     162             : inline
+     163             : double MultiValue::getDerivative( const unsigned& ival, const unsigned& jder ) const {
+     164             :   plumed_dbg_assert( jder<nderivatives && hasDerivatives.isActive(jder) );
+     165   542151807 :   return derivatives[nderivatives*ival+jder];
+     166             : }
+     167             : 
+     168             : inline
+     169             : double MultiValue::getTemporyDerivative( const unsigned& jder ) const {
+     170             :   plumed_dbg_assert( jder<nderivatives && hasDerivatives.isActive(jder) );
+     171       49704 :   return tmpder[jder];
+     172             : }
+     173             : 
+     174             : inline
+     175             : bool MultiValue::updateComplete() {
+     176     1625475 :   return hasDerivatives.updateComplete();
+     177             : }
+     178             : 
+     179             : inline
+     180             : void MultiValue::emptyActiveMembers() {
+     181      934288 :   hasDerivatives.emptyActiveMembers();
+     182             : }
+     183             : 
+     184             : inline
+     185             : void MultiValue::putIndexInActiveArray( const unsigned& ind ) {
+     186    32705270 :   hasDerivatives.putIndexInActiveArray( ind );
+     187             : }
+     188             : 
+     189             : inline
+     190      222000 : void MultiValue::updateIndex( const unsigned& ind ) {
+     191      222000 :   if( hasDerivatives.isActive(ind) ) hasDerivatives.putIndexInActiveArray( ind );
+     192      222000 : }
+     193             : 
+     194             : inline
+     195             : void MultiValue::sortActiveList() {
+     196       56305 :   hasDerivatives.sortActiveList();
+     197       56305 : }
+     198             : 
+     199             : inline
+     200             : void MultiValue::completeUpdate() {
+     201      877983 :   hasDerivatives.completeUpdate();
+     202       94076 : }
+     203             : 
+     204             : inline
+     205             : unsigned MultiValue::getNumberActive() const {
+     206    41844766 :   return hasDerivatives.getNumberActive();
+     207             : }
+     208             : 
+     209             : inline
+     210             : unsigned MultiValue::getActiveIndex( const unsigned& ind ) const {
+     211             :   plumed_dbg_assert( ind<hasDerivatives.getNumberActive() );
+     212             :   return hasDerivatives[ind];
+     213             : }
+     214             : 
+     215             : inline
+     216             : void MultiValue::updateDynamicList() {
+     217      140764 :   if( atLeastOneSet ) hasDerivatives.updateActiveMembers();
+     218             : }
+     219             : 
+     220             : inline
+     221             : std::vector<unsigned>& MultiValue::getIndices() {
+     222      920853 :   return indices;
+     223             : }
+     224             : 
+     225             : inline
+     226             : std::vector<unsigned>& MultiValue::getSortIndices() {
+     227      449465 :   return sort_indices;
+     228             : }
+     229             : 
+     230             : inline
+     231             : std::vector<Vector>& MultiValue::getAtomVector() {
+     232      680211 :   return tmp_atoms;
+     233             : }
+     234             : 
+     235             : inline
+     236             : bool MultiValue::isActive( const unsigned& ind ) const {
+     237   421791086 :   return hasDerivatives.isActive( ind );
+     238             : }
+     239             : 
+     240             : }
+     241             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.cpp.func-sort-c.html b/coverage/tools/NeighborList.cpp.func-sort-c.html new file mode 100644 index 000000000000..f05464c93aa0 --- /dev/null +++ b/coverage/tools/NeighborList.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812991.5 %
Date:2024-02-22 21:58:45Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12NeighborList12getNeighborsEj0
_ZN4PLMD12NeighborList13setLastUpdateEj0
_ZNK4PLMD12NeighborList13getLastUpdateEv24
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EERKbS8_RKNS_3PbcERNS_12CommunicatorERKdRKj44
_ZN4PLMD12NeighborList18getReducedAtomListEv240
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EES6_RKbS8_S8_RKNS_3PbcERNS_12CommunicatorERKdRKj263
_ZN4PLMD12NeighborListD2Ev305
_ZN4PLMD12NeighborList10initializeEv307
_ZN4PLMD12NeighborList14setRequestListEv3138
_ZN4PLMD12NeighborList6updateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE3138
_ZNK4PLMD12NeighborList9getStrideEv13520
_ZN4PLMD12NeighborList15getFullAtomListEv69971
_ZNK4PLMD12NeighborList4sizeEv23715874
_ZNK4PLMD12NeighborList22getClosePairAtomNumberEj34665936
_ZN4PLMD12NeighborList12getIndexPairEj234387348
_ZNK4PLMD12NeighborList12getClosePairEj259842524
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.cpp.func.html b/coverage/tools/NeighborList.cpp.func.html new file mode 100644 index 000000000000..7e5c7f0afd4d --- /dev/null +++ b/coverage/tools/NeighborList.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812991.5 %
Date:2024-02-22 21:58:45Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12NeighborList10initializeEv307
_ZN4PLMD12NeighborList12getIndexPairEj234387348
_ZN4PLMD12NeighborList12getNeighborsEj0
_ZN4PLMD12NeighborList13setLastUpdateEj0
_ZN4PLMD12NeighborList14setRequestListEv3138
_ZN4PLMD12NeighborList15getFullAtomListEv69971
_ZN4PLMD12NeighborList18getReducedAtomListEv240
_ZN4PLMD12NeighborList6updateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE3138
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EERKbS8_RKNS_3PbcERNS_12CommunicatorERKdRKj44
_ZN4PLMD12NeighborListC2ERKSt6vectorINS_10AtomNumberESaIS2_EES6_RKbS8_S8_RKNS_3PbcERNS_12CommunicatorERKdRKj263
_ZN4PLMD12NeighborListD2Ev305
_ZNK4PLMD12NeighborList12getClosePairEj259842524
_ZNK4PLMD12NeighborList13getLastUpdateEv24
_ZNK4PLMD12NeighborList22getClosePairAtomNumberEj34665936
_ZNK4PLMD12NeighborList4sizeEv23715874
_ZNK4PLMD12NeighborList9getStrideEv13520
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.cpp.gcov.html b/coverage/tools/NeighborList.cpp.gcov.html new file mode 100644 index 000000000000..99b75defea8a --- /dev/null +++ b/coverage/tools/NeighborList.cpp.gcov.html @@ -0,0 +1,371 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11812991.5 %
Date:2024-02-22 21:58:45Functions:141687.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "NeighborList.h"
+      23             : #include "Vector.h"
+      24             : #include "Pbc.h"
+      25             : #include "AtomNumber.h"
+      26             : #include "Communicator.h"
+      27             : #include "OpenMP.h"
+      28             : #include "Tools.h"
+      29             : #include <vector>
+      30             : #include <algorithm>
+      31             : #include <numeric>
+      32             : 
+      33             : #ifdef __APPLE__
+      34             : //we are using getenv to give the user the opporunity of suppressing
+      35             : //the too many memory killswitch while compiling on mac
+      36             : #include <cstdlib>
+      37             : #endif //__APPLE__
+      38             : namespace PLMD {
+      39             : 
+      40         263 : NeighborList::NeighborList(const std::vector<AtomNumber>& list0,
+      41             :                            const std::vector<AtomNumber>& list1,
+      42             :                            const bool& serial,
+      43             :                            const bool& do_pair,
+      44             :                            const bool& do_pbc,
+      45             :                            const Pbc& pbc,
+      46             :                            Communicator& cm,
+      47             :                            const double& distance,
+      48         263 :                            const unsigned& stride)
+      49         263 :   : reduced(false),
+      50         263 :     serial_(serial),
+      51         263 :     do_pair_(do_pair),
+      52         263 :     do_pbc_(do_pbc),
+      53         263 :     twolists_(true),
+      54         263 :     pbc_(&pbc),
+      55         263 :     comm(cm),
+      56             :     //copy-initialize fullatomlist_
+      57         263 :     fullatomlist_(list0),
+      58         263 :     distance_(distance),
+      59         263 :     nlist0_(list0.size()),
+      60         263 :     nlist1_(list1.size()),
+      61         263 :     stride_(stride) {
+      62             :   // store the rest of the atoms into fullatomlist_
+      63         264 :   fullatomlist_.insert(fullatomlist_.end(),list1.begin(),list1.end());
+      64         263 :   if(!do_pair) {
+      65         234 :     nallpairs_=nlist0_*nlist1_;
+      66             :   } else {
+      67          29 :     plumed_assert(nlist0_==nlist1_)
+      68             :         << "when using PAIR option, the two groups should have the same number"
+      69             :         " of elements\n" << "the groups you specified have size "
+      70           0 :         <<nlist0_<<" and "<<nlist1_;
+      71          29 :     nallpairs_=nlist0_;
+      72             :   }
+      73         263 :   initialize();
+      74         262 : }
+      75             : 
+      76          44 : NeighborList::NeighborList(const std::vector<AtomNumber>& list0,
+      77             :                            const bool& serial, const bool& do_pbc,
+      78             :                            const Pbc& pbc,
+      79             :                            Communicator& cm,
+      80             :                            const double& distance,
+      81          44 :                            const unsigned& stride)
+      82          44 :   : reduced(false),
+      83          44 :     serial_(serial),
+      84          44 :     do_pbc_(do_pbc),
+      85          44 :     twolists_(false),
+      86          44 :     pbc_(&pbc),
+      87          44 :     comm(cm),
+      88             :     //copy-initialize fullatomlist_
+      89          44 :     fullatomlist_(list0),
+      90          44 :     distance_(distance),
+      91          44 :     nlist0_(list0.size()),
+      92          44 :     nallpairs_(nlist0_*(nlist0_-1)/2),
+      93          44 :     stride_(stride) {
+      94          44 :   initialize();
+      95          43 : }
+      96             : 
+      97         305 : NeighborList::~NeighborList()=default;
+      98             : 
+      99         307 : void NeighborList::initialize() {
+     100             : #ifdef __APPLE__
+     101             :   //this mac-only error is here because on my experience the mac tries to page
+     102             :   //the memory on the hdd instead of throwing a memory error
+     103             :   if(!std::getenv("PLUMED_IGNORE_NL_MEMORY_ERROR")) {
+     104             :     //blocking memory allocation on slightly more than 10 GB of memory
+     105             :     //that is about 1296000000 pairs (36000 atoms)
+     106             :     //36000 * 36000= 1296000000
+     107             :     //each pairIDs occupies 64 bit (where unsigned are 32bit integers)
+     108             :     //4294967296 is max(uint32)+1 and is more than 34 GB (correspond to a system of 65536 atoms)
+     109             :     if(nallpairs_ > 1296000000 )
+     110             :       plumed_merror("An error happened while allocating the neighbor "
+     111             :                     "list, please decrease the number of atoms used");
+     112             :   }
+     113             : #endif // __APPLE__
+     114             :   try {
+     115         307 :     neighbors_.resize(nallpairs_);
+     116           2 :   } catch (...) {
+     117           4 :     plumed_error_nested() << "An error happened while allocating the neighbor "
+     118             :                           "list, please decrease the number of atoms used";
+     119           2 :   }
+     120             :   //TODO: test if this is feasible for accelerating the loop
+     121             :   //#pragma omp parallel for default(shared)
+     122   228149933 :   for(unsigned int i=0; i<nallpairs_; ++i)
+     123   228149628 :     neighbors_[i]=getIndexPair(i);
+     124         305 : }
+     125             : 
+     126       69971 : std::vector<AtomNumber>& NeighborList::getFullAtomList() {
+     127       69971 :   return fullatomlist_;
+     128             : }
+     129             : 
+     130   234387348 : NeighborList::pairIDs NeighborList::getIndexPair(const unsigned ipair) {
+     131             :   pairIDs index;
+     132   234387348 :   if(twolists_ && do_pair_)
+     133       12236 :     index=pairIDs(ipair,ipair+nlist0_);
+     134   234375112 :   else if (twolists_ && !do_pair_)
+     135   143426466 :     index=pairIDs(ipair/nlist1_,ipair%nlist1_+nlist0_);
+     136    90948646 :   else if (!twolists_) {
+     137    90948646 :     unsigned ii = nallpairs_-1-ipair;
+     138    90948646 :     unsigned  K = unsigned(std::floor((std::sqrt(double(8*ii+1))+1)/2));
+     139    90948646 :     unsigned jj = ii-K*(K-1)/2;
+     140    90948646 :     index=pairIDs(nlist0_-1-K,nlist0_-1-jj);
+     141             :   }
+     142   234387348 :   return index;
+     143             : }
+     144             : 
+     145        3138 : void NeighborList::update(const std::vector<Vector>& positions) {
+     146        3138 :   neighbors_.clear();
+     147        3138 :   const double d2=distance_*distance_;
+     148             :   // check if positions array has the correct length
+     149        3138 :   plumed_assert(positions.size()==fullatomlist_.size());
+     150             : 
+     151        3138 :   unsigned stride=comm.Get_size();
+     152        3138 :   unsigned rank=comm.Get_rank();
+     153        3138 :   unsigned nt=OpenMP::getNumThreads();
+     154        3138 :   if(serial_) {
+     155             :     stride=1;
+     156             :     rank=0;
+     157             :     nt=1;
+     158             :   }
+     159             :   std::vector<unsigned> local_flat_nl;
+     160             : 
+     161        3138 :   #pragma omp parallel num_threads(nt)
+     162             :   {
+     163             :     std::vector<unsigned> private_flat_nl;
+     164             :     #pragma omp for nowait
+     165             :     for(unsigned int i=rank; i<nallpairs_; i+=stride) {
+     166             :       pairIDs index=getIndexPair(i);
+     167             :       unsigned index0=index.first;
+     168             :       unsigned index1=index.second;
+     169             :       Vector distance;
+     170             :       if(do_pbc_) {
+     171             :         distance=pbc_->distance(positions[index0],positions[index1]);
+     172             :       } else {
+     173             :         distance=delta(positions[index0],positions[index1]);
+     174             :       }
+     175             :       double value=modulo2(distance);
+     176             :       if(value<=d2) {
+     177             :         private_flat_nl.push_back(index0);
+     178             :         private_flat_nl.push_back(index1);
+     179             :       }
+     180             :     }
+     181             :     #pragma omp critical
+     182             :     local_flat_nl.insert(local_flat_nl.end(),
+     183             :                          private_flat_nl.begin(),
+     184             :                          private_flat_nl.end());
+     185             :   }
+     186             : 
+     187             :   // find total dimension of neighborlist
+     188        3138 :   std::vector <int> local_nl_size(stride, 0);
+     189        3138 :   local_nl_size[rank] = local_flat_nl.size();
+     190        3138 :   if(!serial_)
+     191        3126 :     comm.Sum(&local_nl_size[0], stride);
+     192             :   int tot_size = std::accumulate(local_nl_size.begin(), local_nl_size.end(), 0);
+     193        3138 :   if(tot_size==0) {
+     194          18 :     setRequestList();
+     195             :     return;
+     196             :   }
+     197             :   // merge
+     198        3120 :   std::vector<unsigned> merge_nl(tot_size, 0);
+     199             :   // calculate vector of displacement
+     200        3120 :   std::vector<int> disp(stride);
+     201        3120 :   disp[0] = 0;
+     202             :   int rank_size = 0;
+     203        9216 :   for(unsigned i=0; i<stride-1; ++i) {
+     204        6096 :     rank_size += local_nl_size[i];
+     205        6096 :     disp[i+1] = rank_size;
+     206             :   }
+     207             :   // Allgather neighbor list
+     208        3120 :   if(comm.initialized()&&!serial_) {
+     209        4181 :     comm.Allgatherv((!local_flat_nl.empty()?&local_flat_nl[0]:NULL),
+     210             :                     local_nl_size[rank],
+     211             :                     &merge_nl[0],
+     212             :                     &local_nl_size[0],
+     213             :                     &disp[0]);
+     214             :   } else
+     215        1016 :     merge_nl = local_flat_nl;
+     216             :   // resize neighbor stuff
+     217        3120 :   neighbors_.resize(tot_size/2);
+     218     6114036 :   for(unsigned i=0; i<tot_size/2; i++) {
+     219     6110916 :     unsigned j=2*i;
+     220     6110916 :     neighbors_[i] = std::make_pair(merge_nl[j],merge_nl[j+1]);
+     221             :   }
+     222             : 
+     223        3120 :   setRequestList();
+     224             : }
+     225             : 
+     226        3138 : void NeighborList::setRequestList() {
+     227        3138 :   requestlist_.clear();
+     228     6114054 :   for(unsigned int i=0; i<size(); ++i) {
+     229     6110916 :     requestlist_.push_back(fullatomlist_[neighbors_[i].first]);
+     230     6110916 :     requestlist_.push_back(fullatomlist_[neighbors_[i].second]);
+     231             :   }
+     232        3138 :   Tools::removeDuplicates(requestlist_);
+     233        3138 :   reduced=false;
+     234        3138 : }
+     235             : 
+     236         240 : std::vector<AtomNumber>& NeighborList::getReducedAtomList() {
+     237         240 :   if(!reduced) {
+     238      168162 :     for(unsigned int i=0; i<size(); ++i) {
+     239      168119 :       AtomNumber index0=fullatomlist_[neighbors_[i].first];
+     240      168119 :       AtomNumber index1=fullatomlist_[neighbors_[i].second];
+     241             : // I exploit the fact that requestlist_ is an ordered vector
+     242      168119 :       auto p = std::find(requestlist_.begin(), requestlist_.end(), index0);
+     243             :       plumed_dbg_assert(p!=requestlist_.end());
+     244      168119 :       unsigned newindex0=p-requestlist_.begin();
+     245      168119 :       p = std::find(requestlist_.begin(), requestlist_.end(), index1);
+     246             :       plumed_dbg_assert(p!=requestlist_.end());
+     247      168119 :       unsigned newindex1=p-requestlist_.begin();
+     248             :       neighbors_[i]=pairIDs(newindex0,newindex1);
+     249             :     }
+     250             :   }
+     251         240 :   reduced=true;
+     252         240 :   return requestlist_;
+     253             : }
+     254             : 
+     255       13520 : unsigned NeighborList::getStride() const {
+     256       13520 :   return stride_;
+     257             : }
+     258             : 
+     259          24 : unsigned NeighborList::getLastUpdate() const {
+     260          24 :   return lastupdate_;
+     261             : }
+     262             : 
+     263           0 : void NeighborList::setLastUpdate(const unsigned step) {
+     264           0 :   lastupdate_=step;
+     265           0 : }
+     266             : 
+     267    23715874 : unsigned NeighborList::size() const {
+     268    23715874 :   return neighbors_.size();
+     269             : }
+     270             : 
+     271   259842524 : NeighborList::pairIDs NeighborList::getClosePair(const unsigned i) const {
+     272   259842524 :   return neighbors_[i];
+     273             : }
+     274             : 
+     275             : NeighborList::pairAtomNumbers
+     276    34665936 : NeighborList::getClosePairAtomNumber(const unsigned i) const {
+     277             :   pairAtomNumbers Aneigh=pairAtomNumbers(
+     278    34665936 :                            fullatomlist_[neighbors_[i].first],
+     279    34665936 :                            fullatomlist_[neighbors_[i].second]);
+     280    34665936 :   return Aneigh;
+     281             : }
+     282             : 
+     283           0 : std::vector<unsigned> NeighborList::getNeighbors(const unsigned index) {
+     284             :   std::vector<unsigned> neighbors;
+     285           0 :   for(unsigned int i=0; i<size(); ++i) {
+     286           0 :     if(neighbors_[i].first==index)
+     287           0 :       neighbors.push_back(neighbors_[i].second);
+     288           0 :     if(neighbors_[i].second==index)
+     289           0 :       neighbors.push_back(neighbors_[i].first);
+     290             :   }
+     291           0 :   return neighbors;
+     292             : }
+     293             : 
+     294             : } // namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.h.func-sort-c.html b/coverage/tools/NeighborList.h.func-sort-c.html new file mode 100644 index 000000000000..3d8ac632d8d0 --- /dev/null +++ b/coverage/tools/NeighborList.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.h.func.html b/coverage/tools/NeighborList.h.func.html new file mode 100644 index 000000000000..7734407733a1 --- /dev/null +++ b/coverage/tools/NeighborList.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/NeighborList.h.gcov.html b/coverage/tools/NeighborList.h.gcov.html new file mode 100644 index 000000000000..d5c8ec9a718f --- /dev/null +++ b/coverage/tools/NeighborList.h.gcov.html @@ -0,0 +1,189 @@ + + + + + + + + LCOV - plumed test coverage - tools/NeighborList.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - NeighborList.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_NeighborList_h //{
+      23             : #define __PLUMED_tools_NeighborList_h
+      24             : 
+      25             : #include "Vector.h"
+      26             : #include "AtomNumber.h"
+      27             : 
+      28             : #include <vector>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : class Pbc;
+      33             : class Communicator;
+      34             : 
+      35             : /// \ingroup TOOLBOX
+      36             : /// A class that implements neighbor lists from two lists or a single list of atoms
+      37             : class NeighborList {
+      38             : public:
+      39             :   using pairIDs=std::pair<unsigned,unsigned>;
+      40             :   using pairAtomNumbers=std::pair<PLMD::AtomNumber,PLMD::AtomNumber>;
+      41             : private:
+      42             :   bool reduced=false;
+      43             :   bool serial_;
+      44             :   bool do_pair_;
+      45             :   bool do_pbc_;
+      46             :   bool twolists_;
+      47             :   const PLMD::Pbc* pbc_;
+      48             :   Communicator& comm;
+      49             :   std::vector<PLMD::AtomNumber> fullatomlist_{};
+      50             :   std::vector<PLMD::AtomNumber> requestlist_{};
+      51             :   std::vector<pairIDs > neighbors_{};
+      52             :   double distance_;
+      53             :   size_t nlist0_=0;
+      54             :   size_t nlist1_=0;
+      55             :   size_t nallpairs_;
+      56             :   unsigned stride_=0;
+      57             :   unsigned lastupdate_=0;
+      58             : /// Initialize the neighbor list with all possible pairs
+      59             :   void initialize();
+      60             : /// Return the pair of indexes in the positions array
+      61             : /// of the two atoms forming the i-th pair among all possible pairs
+      62             :   pairIDs getIndexPair(unsigned i);
+      63             : /// Extract the list of atoms from the current list of close pairs
+      64             :   void setRequestList();
+      65             : public:
+      66             :   NeighborList(const std::vector<PLMD::AtomNumber>& list0,
+      67             :                const std::vector<PLMD::AtomNumber>& list1,
+      68             :                const bool& serial,
+      69             :                const bool& do_pair,
+      70             :                const bool& do_pbc,
+      71             :                const PLMD::Pbc& pbc,
+      72             :                Communicator &cm,
+      73         382 :                const double& distance=1.0e+30,
+      74         382 :                const unsigned& stride=0);
+      75             :   NeighborList(const std::vector<PLMD::AtomNumber>& list0,
+      76             :                const bool& serial,
+      77             :                const bool& do_pbc,
+      78             :                const PLMD::Pbc& pbc,
+      79             :                Communicator &cm,
+      80          22 :                const double& distance=1.0e+30,
+      81          22 :                const unsigned& stride=0);
+      82             :   ~NeighborList();
+      83             : /// Return the list of all atoms. These are needed to rebuild the neighbor list.
+      84             :   std::vector<PLMD::AtomNumber>& getFullAtomList();
+      85             : /// Update the indexes in the neighbor list to match the
+      86             : /// ordering in the new positions array
+      87             : /// and return the new list of atoms that must be requested to the main code
+      88             :   std::vector<PLMD::AtomNumber>& getReducedAtomList();
+      89             : /// Update the neighbor list and prepare the new
+      90             : /// list of atoms that will be requested to the main code
+      91             :   void update(const std::vector<PLMD::Vector>& positions);
+      92             : /// Get the update stride of the neighbor list
+      93             :   unsigned getStride() const;
+      94             : /// Get the last step in which the neighbor list was updated
+      95             :   unsigned getLastUpdate() const;
+      96             : /// Set the step of the last update
+      97             :   void setLastUpdate(unsigned step);
+      98             : /// Get the size of the neighbor list
+      99             :   unsigned size() const;
+     100             : /// Get the distance used to create the neighbor list
+     101             :   double distance() const;
+     102             : /// Get the i-th pair of the neighbor list
+     103             :   pairIDs getClosePair(unsigned i) const;
+     104             : /// Get the list of neighbors of the i-th atom
+     105             :   std::vector<unsigned> getNeighbors(unsigned i);
+     106             : /// Get the i-th pair of AtomNumbers from the neighbor list
+     107             :   pairAtomNumbers getClosePairAtomNumber(unsigned i) const;
+     108             : };
+     109             : 
+     110             : } // namespace PLMD
+     111             : 
+     112             : #endif //__PLUMED_tools_NeighborList_h }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.cpp.func-sort-c.html b/coverage/tools/OFile.cpp.func-sort-c.html new file mode 100644 index 000000000000..9ab75ad7d477 --- /dev/null +++ b/coverage/tools/OFile.cpp.func-sort-c.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22022796.9 %
Date:2024-02-22 21:58:45Functions:293096.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx0
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEl1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm1
_ZN4PLMD5OFile14enforceRestartEv1
_ZN4PLMD5OFile4linkERS0_11
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj31
_ZN4PLMD5OFile14backupAllFilesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEy47
_ZN4PLMD5OFile15setBackupStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE121
_ZN4PLMD5OFile6rewindEv135
_ZN4PLMD5OFile13enforceBackupEv1144
_ZN4PLMD5OFile11clearFieldsEv3202
_ZN4PLMD5OFile10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3321
_ZN4PLMD5OFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3604
_ZNK4PLMD5OFile12checkRestartEv3640
_ZN4PLMD5OFileC1Ev4651
_ZN4PLMD5OFile15setupPrintValueEPNS_5ValueE6025
_ZN4PLMD5OFile5flushEv8747
_ZN4PLMD5OFile16addConstantFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE27840
_ZN4PLMD5OFile10printFieldEPNS_5ValueERKd538368
_ZN4PLMD5OFile13setLinePrefixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE805283
_ZN4PLMD5OFileC2Ev805283
_ZN4PLMD5OFile8fmtFieldEv815805
_ZN4PLMD5OFile10printFieldEv3932623
_ZN4PLMD5OFile7llwriteEPKcm5523390
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi6077354
_ZN4PLMD5OFile8fmtFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14652988
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd15582629
_ZN4PLMD5OFile6printfEPKcz23656647
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_37477712
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.cpp.func.html b/coverage/tools/OFile.cpp.func.html new file mode 100644 index 000000000000..34dd6e628975 --- /dev/null +++ b/coverage/tools/OFile.cpp.func.html @@ -0,0 +1,193 @@ + + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22022796.9 %
Date:2024-02-22 21:58:45Functions:293096.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5OFile10backupFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_3321
_ZN4PLMD5OFile10printFieldEPNS_5ValueERKd538368
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_37477712
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEd15582629
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEi6077354
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj31
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEl1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEm1
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEx0
_ZN4PLMD5OFile10printFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEy47
_ZN4PLMD5OFile10printFieldEv3932623
_ZN4PLMD5OFile11clearFieldsEv3202
_ZN4PLMD5OFile13enforceBackupEv1144
_ZN4PLMD5OFile13setLinePrefixERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE805283
_ZN4PLMD5OFile14backupAllFilesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE36
_ZN4PLMD5OFile14enforceRestartEv1
_ZN4PLMD5OFile15setBackupStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE121
_ZN4PLMD5OFile15setupPrintValueEPNS_5ValueE6025
_ZN4PLMD5OFile16addConstantFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE27840
_ZN4PLMD5OFile4linkERS0_11
_ZN4PLMD5OFile4openERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3604
_ZN4PLMD5OFile5flushEv8747
_ZN4PLMD5OFile6printfEPKcz23656647
_ZN4PLMD5OFile6rewindEv135
_ZN4PLMD5OFile7llwriteEPKcm5523390
_ZN4PLMD5OFile8fmtFieldERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE14652988
_ZN4PLMD5OFile8fmtFieldEv815805
_ZN4PLMD5OFileC1Ev4651
_ZN4PLMD5OFileC2Ev805283
_ZNK4PLMD5OFile12checkRestartEv3640
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.cpp.gcov.html b/coverage/tools/OFile.cpp.gcov.html new file mode 100644 index 000000000000..1e6b9025cb2d --- /dev/null +++ b/coverage/tools/OFile.cpp.gcov.html @@ -0,0 +1,513 @@ + + + + + + + + LCOV - plumed test coverage - tools/OFile.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22022796.9 %
Date:2024-02-22 21:58:45Functions:293096.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "OFile.h"
+      23             : #include "Exception.h"
+      24             : #include "core/Action.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/Value.h"
+      27             : #include "Communicator.h"
+      28             : #include "Tools.h"
+      29             : #include <cstdarg>
+      30             : #include <cstring>
+      31             : 
+      32             : #include <iostream>
+      33             : #include <string>
+      34             : #include <cstdlib>
+      35             : #include <cerrno>
+      36             : 
+      37             : #include <memory>
+      38             : #include <utility>
+      39             : 
+      40             : #ifdef __PLUMED_HAS_ZLIB
+      41             : #include <zlib.h>
+      42             : #endif
+      43             : 
+      44             : namespace PLMD {
+      45             : 
+      46     5523390 : size_t OFile::llwrite(const char*ptr,size_t s) {
+      47             :   size_t r;
+      48     5523390 :   if(linked) return linked->llwrite(ptr,s);
+      49     5523338 :   if(! (comm && comm->Get_rank()>0)) {
+      50     4657967 :     if(!fp) plumed_merror("writing on uninitialized File");
+      51     4657967 :     if(gzfp) {
+      52             : #ifdef __PLUMED_HAS_ZLIB
+      53        1263 :       r=gzwrite(gzFile(gzfp),ptr,s);
+      54             : #else
+      55             :       plumed_merror("file " + getPath() + ": trying to use a gz file without zlib being linked");
+      56             : #endif
+      57             :     } else {
+      58     4656704 :       r=std::fwrite(ptr,1,s,fp);
+      59             :     }
+      60             :   }
+      61     5523338 :   if(comm) {
+      62             : //  This barrier is apparently useless since it comes
+      63             : //  just before a Bcast.
+      64             : //
+      65             : //  Anyway, it looks like it is solving an issue that appeared on
+      66             : //  TRAVIS (at least on my laptop) so I add it here.
+      67             : //  GB
+      68     4666327 :     comm->Barrier();
+      69     4666327 :     comm->Bcast(r,0);
+      70             :   }
+      71             : 
+      72     5523338 :   return r;
+      73             : }
+      74             : 
+      75      809934 : OFile::OFile():
+      76      809934 :   linked(NULL),
+      77      809934 :   fieldChanged(false),
+      78      809934 :   backstring("bck"),
+      79      809934 :   enforceRestart_(false),
+      80      809934 :   enforceBackup_(false)
+      81             : {
+      82      809934 :   fmtField();
+      83      809934 :   buflen=1;
+      84      809934 :   actual_buffer_length=0;
+      85      809934 :   buffer.resize(buflen);
+      86             : // these are set to zero to avoid valgrind errors
+      87     1619868 :   for(int i=0; i<buflen; ++i) buffer[i]=0;
+      88             : // these are set to zero to avoid valgrind errors
+      89      809934 :   buffer_string.resize(1000,0);
+      90      809934 : }
+      91             : 
+      92          11 : OFile& OFile::link(OFile&l) {
+      93          11 :   fp=NULL;
+      94          11 :   gzfp=NULL;
+      95          11 :   linked=&l;
+      96          11 :   return *this;
+      97             : }
+      98             : 
+      99      805283 : OFile& OFile::setLinePrefix(const std::string&l) {
+     100      805283 :   linePrefix=l;
+     101      805283 :   return *this;
+     102             : }
+     103             : 
+     104    23656647 : int OFile::printf(const char*fmt,...) {
+     105             :   va_list arg;
+     106    23656647 :   va_start(arg, fmt);
+     107    23656647 :   int r=std::vsnprintf(&buffer[actual_buffer_length],buflen-actual_buffer_length,fmt,arg);
+     108    23656647 :   va_end(arg);
+     109    23656647 :   if(r>=buflen-actual_buffer_length) {
+     110             :     int newlen=buflen;
+     111       47814 :     while(newlen<=r+actual_buffer_length) newlen*=2;
+     112       16039 :     std::vector<char> newbuf(newlen);
+     113       16039 :     std::memmove(newbuf.data(),buffer.data(),buflen);
+     114     3306098 :     for(int k=buflen; k<newlen; k++) newbuf[k]=0;
+     115             :     std::swap(buffer,newbuf);
+     116       16039 :     buflen=newlen;
+     117             :     va_list arg;
+     118       16039 :     va_start(arg, fmt);
+     119       16039 :     r=std::vsnprintf(&buffer[actual_buffer_length],buflen-actual_buffer_length,fmt,arg);
+     120       16039 :     va_end(arg);
+     121             :   }
+     122    23656647 :   plumed_massert(r>-1 && r<buflen-actual_buffer_length,"error using fmt string " + std::string(fmt));
+     123             : 
+     124             : // Line is buffered until newline, then written with a PLUMED: prefix
+     125             :   char*p1=buffer.data();
+     126             :   char*p2;
+     127             : // newline is only searched in the just added portion:
+     128    23656647 :   char*psearch=p1+actual_buffer_length;
+     129    23656647 :   actual_buffer_length+=r;
+     130    28908634 :   while((p2=std::strchr(psearch,'\n'))) {
+     131     5251987 :     if(linePrefix.length()>0) llwrite(linePrefix.c_str(),linePrefix.length());
+     132     5251987 :     llwrite(p1,p2-p1+1);
+     133     5251987 :     actual_buffer_length-=(p2-p1)+1;
+     134     5251987 :     p1=p2+1;
+     135             :     psearch=p1;
+     136             :   };
+     137    23656647 :   if(buffer.data()!=p1) std::memmove(buffer.data(),p1,actual_buffer_length);
+     138    23656647 :   return r;
+     139             : }
+     140             : 
+     141       27840 : OFile& OFile::addConstantField(const std::string&name) {
+     142             :   Field f;
+     143             :   f.name=name;
+     144       27840 :   const_fields.push_back(f);
+     145       27840 :   return *this;
+     146             : }
+     147             : 
+     148             : 
+     149        3202 : OFile& OFile::clearFields() {
+     150        3202 :   fields.clear();
+     151        3202 :   const_fields.clear();
+     152        3202 :   previous_fields.clear();
+     153        3202 :   return *this;
+     154             : }
+     155             : 
+     156    14652988 : OFile& OFile::fmtField(const std::string&fmt) {
+     157    14652988 :   this->fieldFmt=fmt;
+     158    14652988 :   return *this;
+     159             : }
+     160             : 
+     161      815805 : OFile& OFile::fmtField() {
+     162      815805 :   this->fieldFmt="%23.16lg";
+     163      815805 :   return *this;
+     164             : }
+     165             : 
+     166    15582629 : OFile& OFile::printField(const std::string&name,double v) {
+     167             : // When one tries to print -nan we print nan instead.
+     168             : // The distinction between +nan and -nan is not well defined
+     169             : // Always printing nan simplifies some regtest (special functions computed our of range).
+     170    15582629 :   if(std::isnan(v)) v=std::numeric_limits<double>::quiet_NaN();
+     171             :   std::snprintf(buffer_string.data(),buffer_string.size(),fieldFmt.c_str(),v);
+     172    15582629 :   printField(name,buffer_string.data());
+     173    15582629 :   return *this;
+     174             : }
+     175             : 
+     176     6077354 : OFile& OFile::printField(const std::string&name,int v) {
+     177             :   std::snprintf(buffer_string.data(),buffer_string.size()," %d",v);
+     178     6077354 :   printField(name,buffer_string.data());
+     179     6077354 :   return *this;
+     180             : }
+     181             : 
+     182           1 : OFile& OFile::printField(const std::string&name,long int v) {
+     183             :   std::snprintf(buffer_string.data(),buffer_string.size()," %ld",v);
+     184           1 :   printField(name,buffer_string.data());
+     185           1 :   return *this;
+     186             : }
+     187             : 
+     188           0 : OFile& OFile::printField(const std::string&name,long long int v) {
+     189             :   std::snprintf(buffer_string.data(),buffer_string.size()," %lld",v);
+     190           0 :   printField(name,buffer_string.data());
+     191           0 :   return *this;
+     192             : }
+     193             : 
+     194          31 : OFile& OFile::printField(const std::string&name,unsigned v) {
+     195             :   std::snprintf(buffer_string.data(),buffer_string.size()," %u",v);
+     196          31 :   printField(name,buffer_string.data());
+     197          31 :   return *this;
+     198             : }
+     199             : 
+     200           1 : OFile& OFile::printField(const std::string&name,long unsigned v) {
+     201             :   std::snprintf(buffer_string.data(),buffer_string.size()," %lu",v);
+     202           1 :   printField(name,buffer_string.data());
+     203           1 :   return *this;
+     204             : }
+     205             : 
+     206          47 : OFile& OFile::printField(const std::string&name,long long unsigned v) {
+     207             :   std::snprintf(buffer_string.data(),buffer_string.size()," %llu",v);
+     208          47 :   printField(name,buffer_string.data());
+     209          47 :   return *this;
+     210             : }
+     211             : 
+     212    37477712 : OFile& OFile::printField(const std::string&name,const std::string & v) {
+     213             :   unsigned i;
+     214   190227654 :   for(i=0; i<const_fields.size(); i++) if(const_fields[i].name==name) break;
+     215    37477712 :   if(i>=const_fields.size()) {
+     216             :     Field field;
+     217             :     field.name=name;
+     218             :     field.value=v;
+     219    16701090 :     fields.push_back(field);
+     220             :   } else {
+     221    20776622 :     if(const_fields[i].value!=v) fieldChanged=true;
+     222             :     const_fields[i].value=v;
+     223             :   }
+     224    37477712 :   return *this;
+     225             : }
+     226             : 
+     227        6025 : OFile& OFile::setupPrintValue( Value *val ) {
+     228        6025 :   if( val->isPeriodic() ) {
+     229         476 :     addConstantField("min_" + val->getName() );
+     230         952 :     addConstantField("max_" + val->getName() );
+     231             :   }
+     232        6025 :   return *this;
+     233             : }
+     234             : 
+     235      538368 : OFile& OFile::printField( Value* val, const double& v ) {
+     236      538368 :   printField( val->getName(), v );
+     237      538368 :   if( val->isPeriodic() ) {
+     238       12925 :     std::string min, max; val->getDomain( min, max );
+     239       12925 :     printField( "min_" + val->getName(), min );
+     240       25850 :     printField("max_" + val->getName(), max );
+     241             :   }
+     242      538368 :   return *this;
+     243             : }
+     244             : 
+     245     3932623 : OFile& OFile::printField() {
+     246             :   bool reprint=false;
+     247     3932623 :   if(fieldChanged || fields.size()!=previous_fields.size()) {
+     248             :     reprint=true;
+     249    20569350 :   } else for(unsigned i=0; i<fields.size(); i++) {
+     250    16642703 :       if( previous_fields[i].name!=fields[i].name ||
+     251    16642701 :           (fields[i].constant && fields[i].value!=previous_fields[i].value) ) {
+     252             :         reprint=true;
+     253             :         break;
+     254             :       }
+     255             :     }
+     256     3932623 :   if(reprint) {
+     257        5976 :     printf("#! FIELDS");
+     258       64367 :     for(unsigned i=0; i<fields.size(); i++) printf(" %s",fields[i].name.c_str());
+     259        5976 :     printf("\n");
+     260       33752 :     for(unsigned i=0; i<const_fields.size(); i++) {
+     261       27776 :       printf("#! SET %s %s",const_fields[i].name.c_str(),const_fields[i].value.c_str());
+     262       27776 :       printf("\n");
+     263             :     }
+     264             :   }
+     265    20633713 :   for(unsigned i=0; i<fields.size(); i++) printf("%s",fields[i].value.c_str());
+     266     3932623 :   printf("\n");
+     267     3932623 :   previous_fields=fields;
+     268     3932623 :   fields.clear();
+     269     3932623 :   fieldChanged=false;
+     270     3932623 :   return *this;
+     271             : }
+     272             : 
+     273         121 : void OFile::setBackupString( const std::string& str ) {
+     274         121 :   backstring=str;
+     275         121 : }
+     276             : 
+     277          36 : void OFile::backupAllFiles( const std::string& str ) {
+     278          36 :   if(str=="/dev/null") return;
+     279          36 :   plumed_assert( backstring!="bck" && !checkRestart());
+     280          36 :   size_t found=str.find_last_of("/\\");
+     281          36 :   std::string filename = appendSuffix(str,getSuffix());
+     282          36 :   std::string directory=filename.substr(0,found+1);
+     283          36 :   std::string file=filename.substr(found+1);
+     284          36 :   if( FileExist(filename) ) backupFile("bck", filename);
+     285          36 :   for(int i=0;; i++) {
+     286          36 :     std::string num; Tools::convert(i,num);
+     287          72 :     std::string filestr = directory + backstring + "." + num + "." + file;
+     288          36 :     if( !FileExist(filestr) ) break;
+     289           0 :     backupFile( "bck", filestr);
+     290           0 :   }
+     291             : }
+     292             : 
+     293        3321 : void OFile::backupFile( const std::string& bstring, const std::string& fname ) {
+     294        3321 :   if(fname=="/dev/null") return;
+     295        3167 :   int maxbackup=100;
+     296        3167 :   if(std::getenv("PLUMED_MAXBACKUP")) Tools::convert(std::getenv("PLUMED_MAXBACKUP"),maxbackup);
+     297        3167 :   if(maxbackup>0 && (!comm || comm->Get_rank()==0)) {
+     298        2696 :     FILE* ff=std::fopen(const_cast<char*>(fname.c_str()),"r");
+     299        2696 :     if(ff) {
+     300             :       // no exception here
+     301          65 :       std::fclose(ff);
+     302             :       std::string backup;
+     303          65 :       size_t found=fname.find_last_of("/\\");
+     304          65 :       std::string directory=fname.substr(0,found+1);
+     305          65 :       std::string file=fname.substr(found+1);
+     306          65 :       for(int i=0;; i++) {
+     307             :         std::string num;
+     308          65 :         Tools::convert(i,num);
+     309          65 :         if(i>maxbackup) plumed_merror("cannot backup file "+file+" maximum number of backup is "+num+"\n");
+     310         130 :         backup=directory+bstring +"."+num+"."+file;
+     311          65 :         FILE* fff=std::fopen(backup.c_str(),"r");
+     312             :         // no exception here
+     313          65 :         if(!fff) break;
+     314           0 :         else std::fclose(fff);
+     315           0 :       }
+     316          65 :       int check=rename(fname.c_str(),backup.c_str());
+     317          65 :       plumed_massert(check==0,"renaming "+fname+" into "+backup+" failed for reason: "+std::strerror(errno));
+     318             :     }
+     319             :   }
+     320             : }
+     321             : 
+     322        3604 : OFile& OFile::open(const std::string&path) {
+     323        3604 :   plumed_assert(!cloned);
+     324        3604 :   eof=false;
+     325        3604 :   err=false;
+     326        3604 :   fp=NULL;
+     327        3604 :   gzfp=NULL;
+     328        3604 :   this->path=path;
+     329        7208 :   this->path=appendSuffix(path,getSuffix());
+     330        3604 :   if(checkRestart()) {
+     331         283 :     fp=std::fopen(const_cast<char*>(this->path.c_str()),"a");
+     332         283 :     mode="a";
+     333         566 :     if(Tools::extension(this->path)=="gz") {
+     334             : #ifdef __PLUMED_HAS_ZLIB
+     335          12 :       gzfp=(void*)gzopen(const_cast<char*>(this->path.c_str()),"a9");
+     336             : #else
+     337             :       plumed_merror("file " + getPath() + ": trying to use a gz file without zlib being linked");
+     338             : #endif
+     339             :     }
+     340             :   } else {
+     341        3321 :     backupFile( backstring, this->path );
+     342        3321 :     if(comm)comm->Barrier();
+     343        3321 :     fp=std::fopen(const_cast<char*>(this->path.c_str()),"w");
+     344        3321 :     mode="w";
+     345        6642 :     if(Tools::extension(this->path)=="gz") {
+     346             : #ifdef __PLUMED_HAS_ZLIB
+     347          13 :       gzfp=(void*)gzopen(const_cast<char*>(this->path.c_str()),"w9");
+     348             : #else
+     349             :       plumed_merror("file " + getPath() + ": trying to use a gz file without zlib being linked");
+     350             : #endif
+     351             :     }
+     352             :   }
+     353        3604 :   if(plumed) plumed->insertFile(*this);
+     354        3604 :   return *this;
+     355             : }
+     356             : 
+     357         135 : OFile& OFile::rewind() {
+     358             : // we use here "hard" rewind, which means close/reopen
+     359             : // the reason is that normal rewind does not work when in append mode
+     360             : // moreover, we can take a backup of the file
+     361         135 :   plumed_assert(fp);
+     362         135 :   clearFields();
+     363             : 
+     364         135 :   if(!comm || comm->Get_rank()==0) {
+     365         104 :     std::string fname=this->path;
+     366         104 :     size_t found=fname.find_last_of("/\\");
+     367         104 :     std::string directory=fname.substr(0,found+1);
+     368         104 :     std::string file=fname.substr(found+1);
+     369         208 :     std::string backup=directory+backstring +".last."+file;
+     370         104 :     int check=rename(fname.c_str(),backup.c_str());
+     371         104 :     plumed_massert(check==0,"renaming "+fname+" into "+backup+" failed for reason: "+std::strerror(errno));
+     372             :   }
+     373             : 
+     374         135 :   if(comm) comm->Barrier();
+     375             : 
+     376         135 :   if(gzfp) {
+     377             : #ifdef __PLUMED_HAS_ZLIB
+     378          15 :     gzclose((gzFile)gzfp);
+     379             :     // no exception here
+     380          15 :     gzfp=(void*)gzopen(const_cast<char*>(this->path.c_str()),"w9");
+     381             : #endif
+     382             :   } else {
+     383         120 :     std::fclose(fp);
+     384             :     // no exception here
+     385         120 :     fp=std::fopen(const_cast<char*>(path.c_str()),"w");
+     386             :   }
+     387         135 :   return *this;
+     388             : }
+     389             : 
+     390        8747 : FileBase& OFile::flush() {
+     391        8747 :   if(heavyFlush) {
+     392        3909 :     if(gzfp) {
+     393             : #ifdef __PLUMED_HAS_ZLIB
+     394           9 :       gzclose(gzFile(gzfp));
+     395             :       // no exception here
+     396           9 :       gzfp=(void*)gzopen(const_cast<char*>(path.c_str()),"a");
+     397             : #endif
+     398             :     } else {
+     399        3900 :       std::fclose(fp);
+     400             :       // no exception here
+     401        3900 :       fp=std::fopen(const_cast<char*>(path.c_str()),"a");
+     402             :     }
+     403             :   } else {
+     404        4838 :     FileBase::flush();
+     405             :     // if(gzfp) gzflush(gzFile(gzfp),Z_FINISH);
+     406             :     // for some reason flushing with Z_FINISH has problems on linux
+     407             :     // I thus use this (incomplete) flush
+     408             : #ifdef __PLUMED_HAS_ZLIB
+     409        4838 :     if(gzfp) gzflush(gzFile(gzfp),Z_FULL_FLUSH);
+     410             : #endif
+     411             :   }
+     412        8747 :   return *this;
+     413             : }
+     414             : 
+     415        3640 : bool OFile::checkRestart()const {
+     416        3640 :   if(enforceRestart_) return true;
+     417        3639 :   else if(enforceBackup_) return false;
+     418        2495 :   else if(action) return action->getRestart();
+     419         219 :   else if(plumed) return plumed->getRestart();
+     420             :   else return false;
+     421             : }
+     422             : 
+     423           1 : OFile& OFile::enforceRestart() {
+     424           1 :   enforceRestart_=true;
+     425           1 :   enforceBackup_=false;
+     426           1 :   return *this;
+     427             : }
+     428             : 
+     429        1144 : OFile& OFile::enforceBackup() {
+     430        1144 :   enforceBackup_=true;
+     431        1144 :   enforceRestart_=false;
+     432        1144 :   return *this;
+     433             : }
+     434             : 
+     435             : 
+     436             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.h.func-sort-c.html b/coverage/tools/OFile.h.func-sort-c.html new file mode 100644 index 000000000000..d700801b6952 --- /dev/null +++ b/coverage/tools/OFile.h.func-sort-c.html @@ -0,0 +1,501 @@ + + + + + + + + LCOV - plumed test coverage - tools/OFile.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:9610789.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsIA1000_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA103_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA110_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA120_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA129_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA47_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA52_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA67_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA72_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA88_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA90_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA50_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA54_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA63_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA65_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA81_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA34_cEERNS_5OFileES3_RKT_3
_ZN4PLMDlsINS_14ActionRegisterEEERNS_5OFileES3_RKT_3
_ZN4PLMDlsIA48_cEERNS_5OFileES3_RKT_4
_ZN4PLMDlsIA58_cEERNS_5OFileES3_RKT_4
_ZN4PLMDlsIA62_cEERNS_5OFileES3_RKT_7
_ZN4PLMDlsIA42_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA56_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA61_cEERNS_5OFileES3_RKT_9
_ZN4PLMDlsIA59_cEERNS_5OFileES3_RKT_10
_ZN4PLMDlsIA53_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA77_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA92_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA100_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA127_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA134_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA57_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA66_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA68_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA69_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA78_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA85_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA96_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA99_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA37_cEERNS_5OFileES3_RKT_17
_ZN4PLMDlsIA39_cEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIFRSt8ios_baseS2_EEERNS_5OFileES5_RKT_19
_ZN4PLMDlsISt13_SetprecisionEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIA79_cEERNS_5OFileES3_RKT_21
_ZN4PLMDlsIA26_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA82_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA108_cEERNS_5OFileES3_RKT_30
_ZN4PLMDlsIA9_cEERNS_5OFileES3_RKT_31
_ZN4PLMDlsIA40_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA55_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA25_cEERNS_5OFileES3_RKT_34
_ZN4PLMDlsIA32_cEERNS_5OFileES3_RKT_37
_ZN4PLMDlsIA116_cEERNS_5OFileES3_RKT_38
_ZN4PLMDlsIA21_cEERNS_5OFileES3_RKT_39
_ZN4PLMDlsIA43_cEERNS_5OFileES3_RKT_39
_ZN4PLMDlsIA31_cEERNS_5OFileES3_RKT_47
_ZN4PLMDlsIA49_cEERNS_5OFileES3_RKT_55
_ZN4PLMDlsIA23_cEERNS_5OFileES3_RKT_80
_ZN4PLMDlsIA45_cEERNS_5OFileES3_RKT_96
_ZN4PLMDlsIA17_cEERNS_5OFileES3_RKT_105
_ZN4PLMDlsIA83_cEERNS_5OFileES3_RKT_108
_ZN4PLMDlsIA73_cEERNS_5OFileES3_RKT_113
_ZN4PLMDlsIA29_cEERNS_5OFileES3_RKT_119
_ZN4PLMDlsIA22_cEERNS_5OFileES3_RKT_130
_ZN4PLMDlsIA27_cEERNS_5OFileES3_RKT_145
_ZN4PLMDlsIA6_cEERNS_5OFileES3_RKT_160
_ZN4PLMDlsIPKcEERNS_5OFileES4_RKT_171
_ZN4PLMDlsIiEERNS_5OFileES2_RKT_175
_ZN4PLMDlsIA36_cEERNS_5OFileES3_RKT_199
_ZN4PLMDlsIA19_cEERNS_5OFileES3_RKT_230
_ZN4PLMDlsIA30_cEERNS_5OFileES3_RKT_237
_ZN4PLMDlsIA38_cEERNS_5OFileES3_RKT_438
_ZN4PLMDlsIcEERNS_5OFileES2_RKT_510
_ZN4PLMDlsIA33_cEERNS_5OFileES3_RKT_529
_ZN4PLMDlsIA11_cEERNS_5OFileES3_RKT_963
_ZN4PLMDlsINS_6lepton16ParsedExpressionEEERNS_5OFileES4_RKT_984
_ZN4PLMDlsIA74_cEERNS_5OFileES3_RKT_1012
_ZN4PLMDlsINS_9CitationsEEERNS_5OFileES3_RKT_1013
_ZN4PLMDlsIA10_cEERNS_5OFileES3_RKT_1015
_ZN4PLMDlsINS_9StopwatchEEERNS_5OFileES3_RKT_1021
_ZN4PLMDlsIA44_cEERNS_5OFileES3_RKT_1026
_ZN4PLMDlsIA28_cEERNS_5OFileES3_RKT_1038
_ZN4PLMDlsIA51_cEERNS_5OFileES3_RKT_1092
_ZN4PLMDlsIA24_cEERNS_5OFileES3_RKT_1116
_ZN4PLMDlsIA12_cEERNS_5OFileES3_RKT_1126
_ZN4PLMDlsIA13_cEERNS_5OFileES3_RKT_1238
_ZN4PLMDlsIA3_cEERNS_5OFileES3_RKT_1369
_ZN4PLMDlsIA41_cEERNS_5OFileES3_RKT_1431
_ZN4PLMDlsImEERNS_5OFileES2_RKT_1452
_ZN4PLMDlsIA16_cEERNS_5OFileES3_RKT_1685
_ZN4PLMDlsIA20_cEERNS_5OFileES3_RKT_2035
_ZN4PLMDlsIA14_cEERNS_5OFileES3_RKT_2225
_ZN4PLMDlsIA7_cEERNS_5OFileES3_RKT_2395
_ZN4PLMDlsIA75_cEERNS_5OFileES3_RKT_7147
_ZN4PLMDlsIfEERNS_5OFileES2_RKT_45192
_ZN4PLMDlsIA4_cEERNS_5OFileES3_RKT_45204
_ZN4PLMDlsIA35_cEERNS_5OFileES3_RKT_45222
_ZN4PLMDlsIxEERNS_5OFileES2_RKT_45554
_ZN4PLMDlsIA18_cEERNS_5OFileES3_RKT_46436
_ZN4PLMDlsIA5_cEERNS_5OFileES3_RKT_46755
_ZN4PLMDlsIA8_cEERNS_5OFileES3_RKT_47477
_ZN4PLMDlsIA15_cEERNS_5OFileES3_RKT_52400
_ZN4PLMDlsIdEERNS_5OFileES2_RKT_91744
_ZN4PLMDlsIPcEERNS_5OFileES3_RKT_100109
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_5OFileES8_RKT_213980
_ZN4PLMDlsIjEERNS_5OFileES2_RKT_276768
_ZN4PLMDlsIA2_cEERNS_5OFileES3_RKT_368817
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.h.func.html b/coverage/tools/OFile.h.func.html new file mode 100644 index 000000000000..47155c983113 --- /dev/null +++ b/coverage/tools/OFile.h.func.html @@ -0,0 +1,501 @@ + + + + + + + + LCOV - plumed test coverage - tools/OFile.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:9610789.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsIA1000_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA100_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA103_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA108_cEERNS_5OFileES3_RKT_30
_ZN4PLMDlsIA10_cEERNS_5OFileES3_RKT_1015
_ZN4PLMDlsIA110_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA116_cEERNS_5OFileES3_RKT_38
_ZN4PLMDlsIA11_cEERNS_5OFileES3_RKT_963
_ZN4PLMDlsIA120_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA127_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA129_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA12_cEERNS_5OFileES3_RKT_1126
_ZN4PLMDlsIA134_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA13_cEERNS_5OFileES3_RKT_1238
_ZN4PLMDlsIA14_cEERNS_5OFileES3_RKT_2225
_ZN4PLMDlsIA15_cEERNS_5OFileES3_RKT_52400
_ZN4PLMDlsIA16_cEERNS_5OFileES3_RKT_1685
_ZN4PLMDlsIA17_cEERNS_5OFileES3_RKT_105
_ZN4PLMDlsIA18_cEERNS_5OFileES3_RKT_46436
_ZN4PLMDlsIA19_cEERNS_5OFileES3_RKT_230
_ZN4PLMDlsIA20_cEERNS_5OFileES3_RKT_2035
_ZN4PLMDlsIA21_cEERNS_5OFileES3_RKT_39
_ZN4PLMDlsIA22_cEERNS_5OFileES3_RKT_130
_ZN4PLMDlsIA23_cEERNS_5OFileES3_RKT_80
_ZN4PLMDlsIA24_cEERNS_5OFileES3_RKT_1116
_ZN4PLMDlsIA25_cEERNS_5OFileES3_RKT_34
_ZN4PLMDlsIA26_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA27_cEERNS_5OFileES3_RKT_145
_ZN4PLMDlsIA28_cEERNS_5OFileES3_RKT_1038
_ZN4PLMDlsIA29_cEERNS_5OFileES3_RKT_119
_ZN4PLMDlsIA2_cEERNS_5OFileES3_RKT_368817
_ZN4PLMDlsIA30_cEERNS_5OFileES3_RKT_237
_ZN4PLMDlsIA31_cEERNS_5OFileES3_RKT_47
_ZN4PLMDlsIA32_cEERNS_5OFileES3_RKT_37
_ZN4PLMDlsIA33_cEERNS_5OFileES3_RKT_529
_ZN4PLMDlsIA34_cEERNS_5OFileES3_RKT_3
_ZN4PLMDlsIA35_cEERNS_5OFileES3_RKT_45222
_ZN4PLMDlsIA36_cEERNS_5OFileES3_RKT_199
_ZN4PLMDlsIA37_cEERNS_5OFileES3_RKT_17
_ZN4PLMDlsIA38_cEERNS_5OFileES3_RKT_438
_ZN4PLMDlsIA39_cEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIA3_cEERNS_5OFileES3_RKT_1369
_ZN4PLMDlsIA40_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA41_cEERNS_5OFileES3_RKT_1431
_ZN4PLMDlsIA42_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA43_cEERNS_5OFileES3_RKT_39
_ZN4PLMDlsIA44_cEERNS_5OFileES3_RKT_1026
_ZN4PLMDlsIA45_cEERNS_5OFileES3_RKT_96
_ZN4PLMDlsIA47_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA48_cEERNS_5OFileES3_RKT_4
_ZN4PLMDlsIA49_cEERNS_5OFileES3_RKT_55
_ZN4PLMDlsIA4_cEERNS_5OFileES3_RKT_45204
_ZN4PLMDlsIA50_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA51_cEERNS_5OFileES3_RKT_1092
_ZN4PLMDlsIA52_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA53_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA54_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA55_cEERNS_5OFileES3_RKT_33
_ZN4PLMDlsIA56_cEERNS_5OFileES3_RKT_8
_ZN4PLMDlsIA57_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA58_cEERNS_5OFileES3_RKT_4
_ZN4PLMDlsIA59_cEERNS_5OFileES3_RKT_10
_ZN4PLMDlsIA5_cEERNS_5OFileES3_RKT_46755
_ZN4PLMDlsIA61_cEERNS_5OFileES3_RKT_9
_ZN4PLMDlsIA62_cEERNS_5OFileES3_RKT_7
_ZN4PLMDlsIA63_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA65_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA66_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA67_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA68_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA69_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA6_cEERNS_5OFileES3_RKT_160
_ZN4PLMDlsIA72_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA73_cEERNS_5OFileES3_RKT_113
_ZN4PLMDlsIA74_cEERNS_5OFileES3_RKT_1012
_ZN4PLMDlsIA75_cEERNS_5OFileES3_RKT_7147
_ZN4PLMDlsIA77_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA78_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA79_cEERNS_5OFileES3_RKT_21
_ZN4PLMDlsIA7_cEERNS_5OFileES3_RKT_2395
_ZN4PLMDlsIA81_cEERNS_5OFileES3_RKT_1
_ZN4PLMDlsIA82_cEERNS_5OFileES3_RKT_24
_ZN4PLMDlsIA83_cEERNS_5OFileES3_RKT_108
_ZN4PLMDlsIA85_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA88_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA8_cEERNS_5OFileES3_RKT_47477
_ZN4PLMDlsIA90_cEERNS_5OFileES3_RKT_0
_ZN4PLMDlsIA92_cEERNS_5OFileES3_RKT_11
_ZN4PLMDlsIA96_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA99_cEERNS_5OFileES3_RKT_12
_ZN4PLMDlsIA9_cEERNS_5OFileES3_RKT_31
_ZN4PLMDlsIFRSt8ios_baseS2_EEERNS_5OFileES5_RKT_19
_ZN4PLMDlsINS_14ActionRegisterEEERNS_5OFileES3_RKT_3
_ZN4PLMDlsINS_6lepton16ParsedExpressionEEERNS_5OFileES4_RKT_984
_ZN4PLMDlsINS_9CitationsEEERNS_5OFileES3_RKT_1013
_ZN4PLMDlsINS_9StopwatchEEERNS_5OFileES3_RKT_1021
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_5OFileES8_RKT_213980
_ZN4PLMDlsIPKcEERNS_5OFileES4_RKT_171
_ZN4PLMDlsIPcEERNS_5OFileES3_RKT_100109
_ZN4PLMDlsISt13_SetprecisionEERNS_5OFileES3_RKT_19
_ZN4PLMDlsIcEERNS_5OFileES2_RKT_510
_ZN4PLMDlsIdEERNS_5OFileES2_RKT_91744
_ZN4PLMDlsIfEERNS_5OFileES2_RKT_45192
_ZN4PLMDlsIiEERNS_5OFileES2_RKT_175
_ZN4PLMDlsIjEERNS_5OFileES2_RKT_276768
_ZN4PLMDlsImEERNS_5OFileES2_RKT_1452
_ZN4PLMDlsIxEERNS_5OFileES2_RKT_45554
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OFile.h.gcov.html b/coverage/tools/OFile.h.gcov.html new file mode 100644 index 000000000000..e57837575302 --- /dev/null +++ b/coverage/tools/OFile.h.gcov.html @@ -0,0 +1,363 @@ + + + + + + + + LCOV - plumed test coverage - tools/OFile.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OFile.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:9610789.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_OFile_h
+      23             : #define __PLUMED_tools_OFile_h
+      24             : 
+      25             : #include "FileBase.h"
+      26             : #include <vector>
+      27             : #include <sstream>
+      28             : #include <memory>
+      29             : #include <cstddef>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : class Value;
+      34             : 
+      35             : /**
+      36             : \ingroup TOOLBOX
+      37             : Class for output files
+      38             : 
+      39             : This class provides features similar to those in the standard C "FILE*" type,
+      40             : but only for sequential output. See IFile for sequential input.
+      41             : 
+      42             : See the example here for a possible use:
+      43             : \verbatim
+      44             : #include "File.h"
+      45             : 
+      46             : int main(){
+      47             :   PLMD::OFile pof;
+      48             :   pof.open("ciao");
+      49             :   pof.printf("%s\n","test1");
+      50             :   pof.setLinePrefix("plumed: ");
+      51             :   pof.printf("%s\n","test2");
+      52             :   pof.setLinePrefix("");
+      53             :   pof.addConstantField("x2").printField("x2",67.0);
+      54             :   pof.printField("x1",10.0).printField("x3",20.12345678901234567890).printField();
+      55             :   pof.printField("x1",10.0).printField("x3",-1e70*20.12345678901234567890).printField();
+      56             :   pof.printField("x3",10.0).printField("x2",777.0).printField("x1",-1e70*20.12345678901234567890).printField();
+      57             :   pof.printField("x3",67.0).printField("x1",18.0).printField();
+      58             :   return 0;
+      59             : }
+      60             : \endverbatim
+      61             : 
+      62             : This program is expected to produce a file "ciao" which reads
+      63             : \verbatim
+      64             : test1
+      65             : plumed: test2
+      66             : #! FIELDS x1 x3
+      67             : #! SET x2                      67
+      68             :                      10      20.12345678901234
+      69             :                      10 -2.012345678901235e+71
+      70             : #! FIELDS x1 x3
+      71             : #! SET x2                     777
+      72             :  -2.012345678901235e+71                     10
+      73             :                      18                     67
+      74             : \endverbatim
+      75             : 
+      76             : Notes
+      77             : - "x2" is declared as "constant", which means that it is written using the "SET"
+      78             : keyword. Thus, everytime it is modified, all the headers are repeated in the output file.
+      79             : - printField() without arguments is used as a "newline".
+      80             : - most methods return a reference to the OFile itself, to allow chaining many calls on the same line
+      81             : (this is similar to << operator in std::ostream)
+      82             : 
+      83             : \section using-correctly-ofile Using correctly OFile in PLUMED
+      84             : 
+      85             : When a OFile object is used in PLUMED it can be convenient to link() it
+      86             : to the Action object where it is defined, or to the PlumedMain object.
+      87             : This will save in the OFile a pointer to the linked object and will
+      88             : allow to have some extra information. E.g., if PLUMED is restarting,
+      89             : files will be appended. Notice that one can enforce this behavior using
+      90             : the enforceRestart() method before opening a file.
+      91             : 
+      92             : To have all files managed consistently, it is important to use OFile in the proper way.
+      93             : This should allow multi-replica plumed, restart and backups to work in
+      94             : the expected way. For this reason all the operations in OFile and IFile
+      95             : are synchronizing all the processors of the group, so call to OFile functions
+      96             : should always be performed by all processes; for this reason is also not useful
+      97             : to use Log for debugging because only master threads will actually write.
+      98             : For debugging is better to use the standard stderr.
+      99             : 
+     100             : \verbatim
+     101             : int main(){
+     102             : // this is a growing file, containing a full history
+     103             : // (frames are appended, as in traditional HILLS and COLVAR)
+     104             :   OFile grw;
+     105             : // this is a single-snapshopt file used e.g. for checkpointing
+     106             : // (rewritten every time)
+     107             :   OFile snp;
+     108             : 
+     109             : // open both files at the beginning
+     110             : // (will go in \ref Action constructor)
+     111             :   grw.open("growing");
+     112             :   snp.open("snapshot");
+     113             : 
+     114             : // trajectory loop
+     115             :   for(int i=0;i<nsteps;i++){
+     116             : 
+     117             : // files should be written in the update() method of an \ref Action
+     118             : 
+     119             : // write on growing file
+     120             :     grw<<"data at step "<<i<<\n";
+     121             : 
+     122             : // flushing
+     123             : // it takes time, so do it only if data is critical
+     124             : // better to leave this choice to the user with the FLUSH keyword
+     125             : //    grw.flush();
+     126             : 
+     127             : // write on snapshot file
+     128             :     snp.rewind();
+     129             :     snp<<"snapshot at step "<<i<<"\n";
+     130             :     snp.flush();
+     131             : // the only difference is that snp is rewound
+     132             : // notice that it should be rewound just before writing
+     133             : // because rewind is going to move the file out of the way
+     134             : // to have a safe copy of the file ("bck.last.filename")
+     135             : // Also notice that snapshots should be flushed
+     136             : // for this reason, it is better to write them only
+     137             : // rarely to avoid excessive slow down
+     138             : 
+     139             :   }
+     140             : }
+     141             : 
+     142             : \notice
+     143             : Notice that it is not necessary to explicitely close files, since they are closed implicitly
+     144             : when the object goes out of scope. In case you need to explicitly close the file before it is
+     145             : destroyed, please check it the procedure is exception safe and, if necessary, add some `try/catch`
+     146             : statement.
+     147             : 
+     148             : \endverbatim
+     149             : */
+     150             : 
+     151             : class OFile:
+     152             :   public virtual FileBase {
+     153             : /// Pointer to a linked OFile.
+     154             : /// see link(OFile&)
+     155             :   OFile* linked;
+     156             : /// Internal buffer for printf
+     157             :   std::vector<char> buffer_string;
+     158             : /// Internal buffer (generic use)
+     159             :   std::vector<char> buffer;
+     160             : /// Internal buffer length
+     161             :   int buflen;
+     162             : /// This variables stores the actual buffer length
+     163             :   int actual_buffer_length;
+     164             : /// Class identifying a single field for fielded output
+     165    50289460 :   class Field:
+     166             :     public FieldBase {
+     167             :   };
+     168             : /// Low-level write
+     169             :   std::size_t llwrite(const char*,std::size_t);
+     170             : /// True if fields has changed.
+     171             : /// This could be due to a change in the list of fields or a reset
+     172             : /// of a nominally constant field
+     173             :   bool fieldChanged;
+     174             : /// Format for fields writing
+     175             :   std::string fieldFmt;
+     176             : /// All the previously defined variable fields
+     177             :   std::vector<Field> previous_fields;
+     178             : /// All the defined variable fields
+     179             :   std::vector<Field> fields;
+     180             : /// All the defined constant fields
+     181             :   std::vector<Field> const_fields;
+     182             : /// Prefix for line (e.g. "PLUMED: ")
+     183             :   std::string linePrefix;
+     184             : /// Temporary ostringstream for << output
+     185             :   std::ostringstream oss;
+     186             : /// The string used for backing up files
+     187             :   std::string backstring;
+     188             : /// Find field index given name
+     189             :   unsigned findField(const std::string&name)const;
+     190             : /// check if we are restarting
+     191             :   bool checkRestart()const;
+     192             : /// True if restart behavior should be forced
+     193             :   bool enforceRestart_;
+     194             : /// True if backup behavior (i.e. non restart) should be forced
+     195             :   bool enforceBackup_;
+     196             : public:
+     197             : /// Constructor
+     198             :   OFile();
+     199             : /// Allows overloading of link
+     200             :   using FileBase::link;
+     201             : /// Allows overloading of open
+     202             :   using FileBase::open;
+     203             : /// Allows linking this OFile to another one.
+     204             : /// In this way, everything written to this OFile will be immediately
+     205             : /// written on the linked OFile. Notice that a OFile should
+     206             : /// be either opened explicitly, linked to a FILE or linked to a OFile
+     207             :   OFile& link(OFile&);
+     208             : /// Set the string name to be used for automatic backup
+     209             :   void setBackupString( const std::string& );
+     210             : /// Backup a file by giving it a different name
+     211             :   void backupFile( const std::string& bstring, const std::string& fname );
+     212             : /// This backs up all the files that would have been created with the
+     213             : /// name str.  It is used in analysis when you are not restarting.  Analysis
+     214             : /// output files at different times, which are names analysis.0.<filename>,
+     215             : /// analysis.1.<filename> and <filename>, are backed up to bck.0.analysis.0.<filename>,
+     216             : /// bck.0.analysis.1.<filename> and bck.0.<filename>
+     217             :   void backupAllFiles( const std::string& str );
+     218             : /// Opens the file using automatic append/backup
+     219             :   OFile& open(const std::string&name) override;
+     220             : /// Set the prefix for output.
+     221             : /// Typically "PLUMED: ". Notice that lines with a prefix cannot
+     222             : /// be parsed using fields in a IFile.
+     223             :   OFile& setLinePrefix(const std::string&);
+     224             : /// Set the format for writing double precision fields
+     225             :   OFile& fmtField(const std::string&);
+     226             : /// Reset the format for writing double precision fields to its default
+     227             :   OFile& fmtField();
+     228             : /// Set the value of a double precision field
+     229             :   OFile& printField(const std::string&,double);
+     230             : /// Set the value of a int type field
+     231             :   OFile& printField(const std::string&,int);
+     232             :   OFile& printField(const std::string&,long int);
+     233             :   OFile& printField(const std::string&,long long int);
+     234             :   OFile& printField(const std::string&,unsigned);
+     235             :   OFile& printField(const std::string&,long unsigned);
+     236             :   OFile& printField(const std::string&,long long unsigned);
+     237             : /// Set the value of a string field
+     238             :   OFile& printField(const std::string&,const std::string&);
+     239             : ///
+     240             :   OFile& addConstantField(const std::string&);
+     241             : /// Used to setup printing of values
+     242             :   OFile& setupPrintValue( Value *val );
+     243             : /// Print a value
+     244             :   OFile& printField( Value* val, const double& v );
+     245             :   /** Close a line.
+     246             :   Typically used as
+     247             :   \verbatim
+     248             :     of.printField("a",a).printField("b",b).printField();
+     249             :   \endverbatim
+     250             :   */
+     251             :   OFile& printField();
+     252             :   /**
+     253             :   Resets the list of fields.
+     254             :   As it is only possible to add new constant fields (addConstantField()),
+     255             :   this method can be used to clean the field list.
+     256             :   */
+     257             :   OFile& clearFields();
+     258             : /// Formatted output with explicit format - a la printf
+     259             :   int printf(const char*fmt,...);
+     260             : /// Formatted output with << operator
+     261             :   template <class T>
+     262             :   friend OFile& operator<<(OFile&,const T &);
+     263             : /// Rewind a file
+     264             :   OFile&rewind();
+     265             : /// Flush a file
+     266             :   FileBase&flush() override;
+     267             : /// Enforce restart, also if the attached plumed object is not restarting.
+     268             : /// Useful for tests
+     269             :   OFile&enforceRestart();
+     270             : /// Enforce backup, even if the attached plumed object is restarting.
+     271             :   OFile&enforceBackup();
+     272             : };
+     273             : 
+     274             : /// Write using << syntax
+     275             : template <class T>
+     276     1462371 : OFile& operator<<(OFile&of,const T &t) {
+     277     1462371 :   of.oss<<t;
+     278     1462371 :   of.printf("%s",of.oss.str().c_str());
+     279     1462371 :   of.oss.str("");
+     280     1462371 :   return of;
+     281             : }
+     282             : 
+     283             : 
+     284             : }
+     285             : 
+     286             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.cpp.func-sort-c.html b/coverage/tools/OpenMP.cpp.func-sort-c.html new file mode 100644 index 000000000000..063e731ba93f --- /dev/null +++ b/coverage/tools/OpenMP.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP13setNumThreadsEj1
_ZN4PLMD6OpenMP16getCachelineSizeEv210487
_ZN4PLMD6OpenMP13getNumThreadsEv1768155
_ZN4PLMD6OpenMP12getThreadNumEv6263516
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.cpp.func.html b/coverage/tools/OpenMP.cpp.func.html new file mode 100644 index 000000000000..19f003e44d13 --- /dev/null +++ b/coverage/tools/OpenMP.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP12getThreadNumEv6263516
_ZN4PLMD6OpenMP13getNumThreadsEv1768155
_ZN4PLMD6OpenMP13setNumThreadsEj1
_ZN4PLMD6OpenMP16getCachelineSizeEv210487
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.cpp.gcov.html b/coverage/tools/OpenMP.cpp.gcov.html new file mode 100644 index 000000000000..a595a7368f18 --- /dev/null +++ b/coverage/tools/OpenMP.cpp.gcov.html @@ -0,0 +1,159 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "OpenMP.h"
+      24             : #include "Tools.h"
+      25             : #include <cstdlib>
+      26             : #if defined(_OPENMP)
+      27             : #include <omp.h>
+      28             : #endif
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : namespace OpenMP {
+      33             : ///singleton struct to treat the openMP setting as a global variables, but with a layer of encapsulation
+      34             : struct OpenMPVars {
+      35             :   unsigned cacheline_size=512;
+      36             :   bool cache_set=false;
+      37             :   unsigned num_threads=1;
+      38             :   bool nt_env_set=false;
+      39             :   static OpenMPVars & get() {
+      40             :     static OpenMPVars vars;
+      41             :     return vars;
+      42             :   }
+      43             : private:
+      44             :   OpenMPVars()=default;
+      45             :   OpenMPVars(OpenMPVars&)=delete;
+      46             :   OpenMPVars& operator=(OpenMPVars&&)=delete;
+      47             : };
+      48             : 
+      49           1 : void setNumThreads(const unsigned nt) {
+      50           1 :   OpenMPVars::get().num_threads=nt;
+      51           1 : }
+      52             : 
+      53      210487 : unsigned getCachelineSize() {
+      54      210487 :   if(!OpenMPVars::get().cache_set) {
+      55         812 :     if(std::getenv("PLUMED_CACHELINE_SIZE")) {
+      56           1 :       Tools::convert(std::getenv("PLUMED_CACHELINE_SIZE"),OpenMPVars::get().cacheline_size);
+      57             :     }
+      58         812 :     OpenMPVars::get().cache_set = true;
+      59             :   }
+      60      210487 :   return OpenMPVars::get().cacheline_size;
+      61             : }
+      62             : 
+      63     1768155 : unsigned getNumThreads() {
+      64     1768155 :   if(!OpenMPVars::get().nt_env_set) {
+      65         812 :     if(std::getenv("PLUMED_NUM_THREADS")) {
+      66         812 :       Tools::convert(std::getenv("PLUMED_NUM_THREADS"),OpenMPVars::get().num_threads);
+      67             :     }
+      68         812 :     OpenMPVars::get().nt_env_set = true;
+      69             :   }
+      70     1768155 :   return OpenMPVars::get().num_threads;
+      71             : }
+      72             : 
+      73     6263516 : unsigned getThreadNum() {
+      74             : #if defined(_OPENMP)
+      75     6263516 :   return omp_get_thread_num();
+      76             : #else
+      77             :   return 0;
+      78             : #endif
+      79             : }
+      80             : 
+      81             : }//namespace OpenMP
+      82             : }//namespace PLMD
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.h.func-sort-c.html b/coverage/tools/OpenMP.h.func-sort-c.html new file mode 100644 index 000000000000..7cd54081a086 --- /dev/null +++ b/coverage/tools/OpenMP.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP17getGoodNumThreadsIfEEjPKT_j0
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjRKSt6vectorIT_SaIS3_EE1350
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjPKT_j209471
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.h.func.html b/coverage/tools/OpenMP.h.func.html new file mode 100644 index 000000000000..79e1b11de09a --- /dev/null +++ b/coverage/tools/OpenMP.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjPKT_j209471
_ZN4PLMD6OpenMP17getGoodNumThreadsIdEEjRKSt6vectorIT_SaIS3_EE1350
_ZN4PLMD6OpenMP17getGoodNumThreadsIfEEjPKT_j0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/OpenMP.h.gcov.html b/coverage/tools/OpenMP.h.gcov.html new file mode 100644 index 000000000000..a0b5b3f158b4 --- /dev/null +++ b/coverage/tools/OpenMP.h.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - tools/OpenMP.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - OpenMP.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:88100.0 %
Date:2024-02-22 21:58:45Functions:2366.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_OpenMP_h
+      23             : #define __PLUMED_tools_OpenMP_h
+      24             : 
+      25             : #include <vector>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : namespace OpenMP {
+      30             : 
+      31             : /// Set number of threads that can be used by openMP
+      32             : void setNumThreads(const unsigned nt);
+      33             : 
+      34             : /// Get number of threads that can be used by openMP
+      35             : unsigned getNumThreads();
+      36             : 
+      37             : /// Returns a unique thread identification number within the current team
+      38             : unsigned getThreadNum();
+      39             : 
+      40             : /// get cacheline size
+      41             : unsigned getCachelineSize();
+      42             : 
+      43             : /// Get a reasonable number of threads so as to access to an array of size s located at x
+      44             : template<typename T>
+      45      209471 : unsigned getGoodNumThreads(const T* /*getTheType*/,unsigned n) {
+      46             :   // this is more or less the equivalent of writing "unsigned getGoodNumThreads<T>(unsigned n)"
+      47             : 
+      48             :   // a factor two is necessary since there is no guarantee that x is aligned
+      49             :   // to cache line boundary
+      50      209471 :   unsigned m=n*sizeof(T)/(2*getCachelineSize());
+      51      209471 :   unsigned numThreads=getNumThreads();
+      52      209471 :   if(m>=numThreads) {
+      53             :     m=numThreads;
+      54             :   } else {
+      55             :     //it is better to use either all the active threads or only one
+      56             :     //this solves a performance problem as explained in issue #415
+      57             :     m=1;
+      58             :   }
+      59      209471 :   return m;
+      60             : }
+      61             : 
+      62             : /// Get a reasonable number of threads so as to access to vector v
+      63             : template<typename T>
+      64        1350 : unsigned getGoodNumThreads(const std::vector<T> & v) {
+      65        1350 :   if(v.size()==0) return 1;
+      66        1314 :   else return getGoodNumThreads(&v[0],v.size());
+      67             : }
+      68             : 
+      69             : }//namespace OpenMP
+      70             : }//namespace PLMD
+      71             : 
+      72             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PDB.cpp.func-sort-c.html b/coverage/tools/PDB.cpp.func-sort-c.html new file mode 100644 index 000000000000..27217612f004 --- /dev/null +++ b/coverage/tools/PDB.cpp.func-sort-c.html @@ -0,0 +1,249 @@ + + + + + + + + LCOV - plumed test coverage - tools/PDB.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:27441166.7 %
Date:2024-02-22 21:58:45Functions:364481.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3PDB12setPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZN4PLMDlsERNS_3LogERKNS_3PDBE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD3PDB12checkForAtomERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15checkForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getAtomsInChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB9getBoxAngEv0
_ZNK4PLMD3PDB9getBoxAxsEv0
_ZNK4PLMD3PDB7hasFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD3PDB8getMtypeB5cxx11Ev10
_ZNK4PLMD3PDB9getBoxVecEv12
_ZNK4PLMD3PDB16getAtomBlockEndsEv14
_ZN4PLMD3PDB11addBlockEndERKj17
_ZN4PLMD3PDB14setAtomNumbersERKSt6vectorINS_10AtomNumberESaIS2_EE27
_ZN4PLMD3PDB16setArgumentNamesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE34
_ZNK4PLMD3PDB12checkForAtomENS_10AtomNumberE127
_ZNK4PLMD3PDB12getAtomRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberESA_RS6_161
_ZNK4PLMD3PDB13getChainNamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE244
_ZN4PLMD3PDB4readERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd323
_ZNK4PLMD3PDB21getNumberOfAtomBlocksEv474
_ZN4PLMD3PDB5printERKdPNS_14GenericMolInfoERNS_5OFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE497
_ZN4PLMD3PDB9addRemarkERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1345
_ZN4PLMD3PDB19readFromFilepointerEP8_IO_FILEbd2069
_ZNK4PLMD3PDB31getNamedAtomFromResidueAndChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjS8_2200
_ZNK4PLMD3PDB10getChainIDB5cxx11ERKj4638
_ZNK4PLMD3PDB14getResidueNameB5cxx11ERKj5958
_ZNK4PLMD3PDB15getResidueRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_RS6_11608
_ZNK4PLMD3PDB23getNamedAtomFromResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj13260
_ZNK4PLMD3PDB11getPositionENS_10AtomNumberE31112
_ZNK4PLMD3PDB17getAtomsInResidueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE34246
_ZNK4PLMD3PDB14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_37562
_ZNK4PLMD3PDB12getOccupancyEv38558
_ZNK4PLMD3PDB7getBetaEv38558
_ZNK4PLMD3PDB14getResidueNameERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE48686
_ZNK4PLMD3PDB14getResidueNameB5cxx11ENS_10AtomNumberE151103
_ZNK4PLMD3PDB16getResidueNumberENS_10AtomNumberE165420
_ZN4PLMD3PDB16setAtomPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE493287
_ZNK4PLMD3PDB14getAtomNumbersEv722721
_ZN4PLMD3PDB16setArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKd1502798
_ZNK4PLMD3PDB16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd1504260
_ZNK4PLMD3PDB16getArgumentNamesB5cxx11Ev2539432
_ZNK4PLMD3PDB11getAtomNameB5cxx11ENS_10AtomNumberE6869435
_ZNK4PLMD3PDB12getPositionsEv23534547
_ZNK4PLMD3PDB4sizeEv216514857
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PDB.cpp.func.html b/coverage/tools/PDB.cpp.func.html new file mode 100644 index 000000000000..fec63802e899 --- /dev/null +++ b/coverage/tools/PDB.cpp.func.html @@ -0,0 +1,249 @@ + + + + + + + + LCOV - plumed test coverage - tools/PDB.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:27441166.7 %
Date:2024-02-22 21:58:45Functions:364481.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3PDB11addBlockEndERKj17
_ZN4PLMD3PDB12setPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE0
_ZN4PLMD3PDB14setAtomNumbersERKSt6vectorINS_10AtomNumberESaIS2_EE27
_ZN4PLMD3PDB16setArgumentNamesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE34
_ZN4PLMD3PDB16setArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKd1502798
_ZN4PLMD3PDB16setAtomPositionsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE493287
_ZN4PLMD3PDB19readFromFilepointerEP8_IO_FILEbd2069
_ZN4PLMD3PDB4readERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbd323
_ZN4PLMD3PDB5printERKdPNS_14GenericMolInfoERNS_5OFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE497
_ZN4PLMD3PDB9addRemarkERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE1345
_ZN4PLMDlsERNS_3LogERKNS_3PDBE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ENS_10AtomNumberE0
_ZNK4PLMD3PDB10getChainIDB5cxx11ERKj4638
_ZNK4PLMD3PDB11getAtomNameB5cxx11ENS_10AtomNumberE6869435
_ZNK4PLMD3PDB11getPositionENS_10AtomNumberE31112
_ZNK4PLMD3PDB12checkForAtomENS_10AtomNumberE127
_ZNK4PLMD3PDB12checkForAtomERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB12getAtomRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberESA_RS6_161
_ZNK4PLMD3PDB12getOccupancyEv38558
_ZNK4PLMD3PDB12getPositionsEv23534547
_ZNK4PLMD3PDB13getChainNamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE244
_ZNK4PLMD3PDB14allowedResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_37562
_ZNK4PLMD3PDB14getAtomNumbersEv722721
_ZNK4PLMD3PDB14getResidueNameB5cxx11ENS_10AtomNumberE151103
_ZNK4PLMD3PDB14getResidueNameB5cxx11ERKj5958
_ZNK4PLMD3PDB14getResidueNameERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE48686
_ZNK4PLMD3PDB15checkForResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getAtomsInChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3PDB15getResidueRangeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERjS9_RS6_11608
_ZNK4PLMD3PDB16getArgumentNamesB5cxx11Ev2539432
_ZNK4PLMD3PDB16getArgumentValueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd1504260
_ZNK4PLMD3PDB16getAtomBlockEndsEv14
_ZNK4PLMD3PDB16getResidueNumberENS_10AtomNumberE165420
_ZNK4PLMD3PDB17getAtomsInResidueERKjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE34246
_ZNK4PLMD3PDB21getNumberOfAtomBlocksEv474
_ZNK4PLMD3PDB23getNamedAtomFromResidueERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKj13260
_ZNK4PLMD3PDB31getNamedAtomFromResidueAndChainERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKjS8_2200
_ZNK4PLMD3PDB4sizeEv216514857
_ZNK4PLMD3PDB7getBetaEv38558
_ZNK4PLMD3PDB7hasFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD3PDB8getMtypeB5cxx11Ev10
_ZNK4PLMD3PDB9getBoxAngEv0
_ZNK4PLMD3PDB9getBoxAxsEv0
_ZNK4PLMD3PDB9getBoxVecEv12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PDB.cpp.gcov.html b/coverage/tools/PDB.cpp.gcov.html new file mode 100644 index 000000000000..47d15c0e4c9b --- /dev/null +++ b/coverage/tools/PDB.cpp.gcov.html @@ -0,0 +1,827 @@ + + + + + + + + LCOV - plumed test coverage - tools/PDB.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PDB.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:27441166.7 %
Date:2024-02-22 21:58:45Functions:364481.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PDB.h"
+      23             : #include "Tools.h"
+      24             : #include "Log.h"
+      25             : #include "h36.h"
+      26             : #include <cstdio>
+      27             : #include <iostream>
+      28             : #include "core/GenericMolInfo.h"
+      29             : #include "Tensor.h"
+      30             : 
+      31             : //+PLUMEDOC INTERNAL pdbreader
+      32             : /*
+      33             : PLUMED can use the PDB format in several places
+      34             : 
+      35             : - To read molecular structure (\ref MOLINFO).
+      36             : - To read reference conformations (\ref RMSD, but also many other methods in \ref dists, \ref FIT_TO_TEMPLATE, etc).
+      37             : 
+      38             : The implemented PDB reader expects a file formatted correctly according to the
+      39             : [PDB standard](http://www.wwpdb.org/documentation/file-format-content/format33/v3.3.html).
+      40             : In particular, the following columns are read from ATOM records
+      41             : \verbatim
+      42             : columns | content
+      43             : 1-6     | record name (ATOM or HETATM)
+      44             : 7-11    | serial number of the atom (starting from 1)
+      45             : 13-16   | atom name
+      46             : 18-20   | residue name
+      47             : 22      | chain id
+      48             : 23-26   | residue number
+      49             : 31-38   | x coordinate
+      50             : 39-46   | y coordinate
+      51             : 47-54   | z coordinate
+      52             : 55-60   | occupancy
+      53             : 61-66   | beta factor
+      54             : \endverbatim
+      55             : PLUMED parser is slightly more permissive than the official PDB format
+      56             : in the fact that the format of real numbers is not fixed. In other words,
+      57             : any real number that can be parsed is OK and the dot can be placed anywhere. However,
+      58             : __columns are interpret strictly__. A sample PDB should look like the following
+      59             : \verbatim
+      60             : ATOM      2  CH3 ACE     1      12.932 -14.718  -6.016  1.00  1.00
+      61             : ATOM      5  C   ACE     1      21.312  -9.928  -5.946  1.00  1.00
+      62             : ATOM      9  CA  ALA     2      19.462 -11.088  -8.986  1.00  1.00
+      63             : \endverbatim
+      64             : 
+      65             : Notice that serial numbers need not to be consecutive. In the three-line example above,
+      66             : only the coordinates of three atoms are provided. This is perfectly legal and indicates PLUMED
+      67             : that information about these atoms only is available. This could be both for structural
+      68             : information in \ref MOLINFO, where the other atoms would have no name assigned, and for
+      69             : reference structures used in \ref RMSD, where only the provided atoms would be used to compute RMSD.
+      70             : 
+      71             : \par Occupancy and beta factors
+      72             : 
+      73             : PLUMED reads also occupancy and beta factors that however are given a very special meaning.
+      74             : In cases where the PDB structure is used as a reference for an alignment (that's the case
+      75             : for instance in \ref RMSD and in \ref FIT_TO_TEMPLATE), the occupancy column is used
+      76             : to provide the weight of each atom in the alignment. In cases where, perhaps after alignment,
+      77             : the displacement between running coordinates and the provided PDB is computed, the beta factors
+      78             : are used as weight for the displacement.
+      79             : Since setting the weights to zero is the same as __not__ including an atom in the alignment or
+      80             : displacement calculation, the two following reference files would be equivalent when used in an \ref RMSD
+      81             : calculation. First file:
+      82             : \verbatim
+      83             : ATOM      2  CH3 ACE     1      12.932 -14.718  -6.016  1.00  1.00
+      84             : ATOM      5  C   ACE     1      21.312  -9.928  -5.946  1.00  1.00
+      85             : ATOM      9  CA  ALA     2      19.462 -11.088  -8.986  0.00  0.00
+      86             : \endverbatim
+      87             : Second file:
+      88             : \verbatim
+      89             : ATOM      2  CH3 ACE     1      12.932 -14.718  -6.016  1.00  1.00
+      90             : ATOM      5  C   ACE     1      21.312  -9.928  -5.946  1.00  1.00
+      91             : \endverbatim
+      92             : However notice that many extra atoms with zero weight might slow down the calculation, so
+      93             : removing lines is better than setting their weights to zero.
+      94             : In addition, weights for alignment need not to be equivalent to weights for displacement.
+      95             : Starting with PLUMED 2.7, if all the weights are set to zero they will be normalized to be equal to the
+      96             : inverse of the number of involved atoms. This means that it will be possible to use files with
+      97             : the weight columns set to zero obtaining a meaningful result. In previous PLUMED versions,
+      98             : setting all weights to zero was resulting in an error instead.
+      99             : 
+     100             : 
+     101             : \par Systems with more than 100k atoms
+     102             : 
+     103             : Notice that it very likely does not make any sense to compute the \ref RMSD or any other structural
+     104             : deviation __using__ so many atoms. However, if the protein for which you want to compute \ref RMSD
+     105             : has atoms with large serial numbers (e.g. because it is located __after__ solvent in the sorted list of atoms)
+     106             : you might end up with troubles with the limitations of the PDB format. Indeed, since there are 5
+     107             : columns available for atom serial number, this number cannot be larger than 99999.
+     108             : In addition, providing \ref MOLINFO with names associated to atoms with a serial larger than 99999 would be impossible.
+     109             : 
+     110             : Since PLUMED 2.4 we allow [hybrid 36](http://cci.lbl.gov/hybrid_36/) format to be used to specify atom numbers.
+     111             : This format is not particularly widespread, but has the nice feature that it provides a one-to-one mapping
+     112             : between numbers up to approximately 80 millions and strings with 5 characters, plus it is backward compatible
+     113             : for numbers smaller than 100000. This is not true for notations like the hex notation exported by VMD.
+     114             : Using the hybrid 36 format, the ATOM records for atom ranging from 99997 to 100002 would read like these:
+     115             : \verbatim
+     116             : ATOM  99997  Ar      X   1      45.349  38.631  15.116  1.00  1.00
+     117             : ATOM  99998  Ar      X   1      46.189  38.631  15.956  1.00  1.00
+     118             : ATOM  99999  Ar      X   1      46.189  39.471  15.116  1.00  1.00
+     119             : ATOM  A0000  Ar      X   1      45.349  39.471  15.956  1.00  1.00
+     120             : ATOM  A0000  Ar      X   1      45.349  38.631  16.796  1.00  1.00
+     121             : ATOM  A0001  Ar      X   1      46.189  38.631  17.636  1.00  1.00
+     122             : \endverbatim
+     123             : There are tools that can be found to translate from integers to strings and back using hybrid 36 format
+     124             : (a simple python script can be found [here](https://sourceforge.net/p/cctbx/code/HEAD/tree/trunk/iotbx/pdb/hybrid_36.py)).
+     125             : In addition, as of PLUMED 2.5, we provide a \ref pdbrenumber "command line tool" that can be used to renumber atoms in a PDB file.
+     126             : 
+     127             : */
+     128             : //+ENDPLUMEDOC
+     129             : 
+     130             : 
+     131             : namespace PLMD {
+     132             : 
+     133          27 : void PDB::setAtomNumbers( const std::vector<AtomNumber>& atoms ) {
+     134          27 :   positions.resize( atoms.size() ); occupancy.resize( atoms.size() );
+     135          27 :   beta.resize( atoms.size() ); numbers.resize( atoms.size() );
+     136         210 :   for(unsigned i=0; i<atoms.size(); ++i) { numbers[i]=atoms[i]; beta[i]=1.0; occupancy[i]=1.0; }
+     137          27 : }
+     138             : 
+     139          34 : void PDB::setArgumentNames( const std::vector<std::string>& argument_names ) {
+     140          34 :   argnames.resize( argument_names.size() );
+     141          98 :   for(unsigned i=0; i<argument_names.size(); ++i) {
+     142             :     argnames[i]=argument_names[i];
+     143          64 :     arg_data.insert( std::pair<std::string,double>( argnames[i], 0.0 ) );
+     144             :   }
+     145          34 : }
+     146             : 
+     147     1504260 : bool PDB::getArgumentValue( const std::string& name, double& value ) const {
+     148             :   std::map<std::string,double>::const_iterator it = arg_data.find(name);
+     149     1504260 :   if( it!=arg_data.end() ) { value = it->second; return true; }
+     150             :   return false;
+     151             : }
+     152             : 
+     153      493287 : void PDB::setAtomPositions( const std::vector<Vector>& pos ) {
+     154      493287 :   plumed_assert( pos.size()==positions.size() );
+     155      519464 :   for(unsigned i=0; i<positions.size(); ++i) positions[i]=pos[i];
+     156      493287 : }
+     157             : 
+     158     1502798 : void PDB::setArgumentValue( const std::string& argname, const double& val ) {
+     159             :   // First set the value of the value of the argument in the map
+     160     1502798 :   arg_data.find(argname)->second = val;
+     161     1502798 : }
+     162             : 
+     163             : // bool PDB::hasRequiredProperties( const std::vector<std::string>& inproperties ){
+     164             : //   bool hasprop=false;
+     165             : //   for(unsigned i=0;i<remark.size();++i){
+     166             : //       if( remark[i].find("PROPERTIES=")!=std::string::npos){ hasprop=true; break; }
+     167             : //   }
+     168             : //   if( !hasprop ){
+     169             : //       std::string mypropstr="PROPERTIES=" + inproperties[0];
+     170             : //       for(unsigned i=1;i<inproperties.size();++i) mypropstr += "," + inproperties[i];
+     171             : //       remark.push_back( mypropstr );
+     172             : //   }
+     173             : //   // Now check that all required properties are there
+     174             : //   for(unsigned i=0;i<inproperties.size();++i){
+     175             : //       hasprop=false;
+     176             : //       for(unsigned j=0;j<remark.size();++j){
+     177             : //           if( remark[j].find(inproperties[i]+"=")!=std::string::npos){ hasprop=true; break; }
+     178             : //       }
+     179             : //       if( !hasprop ) return false;
+     180             : //   }
+     181             : //   return true;
+     182             : // }
+     183             : 
+     184          17 : void PDB::addBlockEnd( const unsigned& end ) {
+     185          17 :   block_ends.push_back( end );
+     186          17 : }
+     187             : 
+     188         474 : unsigned PDB::getNumberOfAtomBlocks()const {
+     189         474 :   return block_ends.size();
+     190             : }
+     191             : 
+     192          14 : const std::vector<unsigned> & PDB::getAtomBlockEnds()const {
+     193          14 :   return block_ends;
+     194             : }
+     195             : 
+     196    23534547 : const std::vector<Vector> & PDB::getPositions()const {
+     197    23534547 :   return positions;
+     198             : }
+     199             : 
+     200           0 : void PDB::setPositions(const std::vector<Vector> &v ) {
+     201           0 :   plumed_assert( v.size()==positions.size() );
+     202           0 :   positions=v;
+     203           0 : }
+     204             : 
+     205       38558 : const std::vector<double> & PDB::getOccupancy()const {
+     206       38558 :   return occupancy;
+     207             : }
+     208             : 
+     209       38558 : const std::vector<double> & PDB::getBeta()const {
+     210       38558 :   return beta;
+     211             : }
+     212             : 
+     213        1345 : void PDB::addRemark( std::vector<std::string>& v1 ) {
+     214        1345 :   Tools::parse(v1,"TYPE",mtype);
+     215        1345 :   Tools::parseVector(v1,"ARG",argnames);
+     216        3787 :   for(unsigned i=0; i<v1.size(); ++i) {
+     217        2442 :     if( v1[i].find("=")!=std::string::npos ) {
+     218             :       std::size_t eq=v1[i].find_first_of('=');
+     219        1864 :       std::string name=v1[i].substr(0,eq);
+     220        1864 :       std::string sval=v1[i].substr(eq+1);
+     221        1864 :       double val; Tools::convert( sval, val );
+     222        1864 :       arg_data.insert( std::pair<std::string,double>( name, val ) );
+     223             :     } else {
+     224         578 :       flags.push_back(v1[i]);
+     225             :     }
+     226             :   }
+     227        1345 : }
+     228             : 
+     229           8 : bool PDB::hasFlag( const std::string& fname ) const {
+     230           8 :   for(unsigned i=0; i<flags.size(); ++i) {
+     231           0 :     if( flags[i]==fname ) return true;
+     232             :   }
+     233             :   return false;
+     234             : }
+     235             : 
+     236             : 
+     237      722721 : const std::vector<AtomNumber> & PDB::getAtomNumbers()const {
+     238      722721 :   return numbers;
+     239             : }
+     240             : 
+     241           0 : const Vector & PDB::getBoxAxs()const {
+     242           0 :   return BoxXYZ;
+     243             : }
+     244             : 
+     245           0 : const Vector & PDB::getBoxAng()const {
+     246           0 :   return BoxABG;
+     247             : }
+     248             : 
+     249          12 : const Tensor & PDB::getBoxVec()const {
+     250          12 :   return Box;
+     251             : }
+     252             : 
+     253     6869435 : std::string PDB::getAtomName(AtomNumber a)const {
+     254             :   const auto p=number2index.find(a);
+     255     6869435 :   if(p==number2index.end()) {
+     256           0 :     std::string num; Tools::convert( a.serial(), num );
+     257           0 :     plumed_merror("Name of atom " + num + " not found" );
+     258     6869435 :   } else return atomsymb[p->second];
+     259             : }
+     260             : 
+     261      165420 : unsigned PDB::getResidueNumber(AtomNumber a)const {
+     262             :   const auto p=number2index.find(a);
+     263      165420 :   if(p==number2index.end()) {
+     264           0 :     std::string num; Tools::convert( a.serial(), num );
+     265           0 :     plumed_merror("Residue for atom " + num + " not found" );
+     266      165420 :   } else return residue[p->second];
+     267             : }
+     268             : 
+     269      151103 : std::string PDB::getResidueName(AtomNumber a) const {
+     270             :   const auto p=number2index.find(a);
+     271      151103 :   if(p==number2index.end()) {
+     272           0 :     std::string num; Tools::convert( a.serial(), num );
+     273           0 :     plumed_merror("Residue for atom " + num + " not found" );
+     274      151103 :   } else return residuenames[p->second];
+     275             : }
+     276             : 
+     277   216514857 : unsigned PDB::size()const {
+     278   216514857 :   return positions.size();
+     279             : }
+     280             : 
+     281        2069 : bool PDB::readFromFilepointer(FILE *fp,bool naturalUnits,double scale) {
+     282             :   //cerr<<file<<endl;
+     283             :   bool file_is_alive=false;
+     284        2069 :   if(naturalUnits) scale=1.0;
+     285             :   std::string line;
+     286             :   fpos_t pos; bool between_ters=true;
+     287      275940 :   while(Tools::getline(fp,line)) {
+     288             :     //cerr<<line<<"\n";
+     289      275724 :     fgetpos (fp,&pos);
+     290     1972639 :     while(line.length()<80) line.push_back(' ');
+     291      275724 :     std::string record=line.substr(0,6);
+     292      275724 :     std::string serial=line.substr(6,5);
+     293      275724 :     std::string atomname=line.substr(12,4);
+     294      275724 :     std::string residuename=line.substr(17,3);
+     295      275724 :     std::string chainID=line.substr(21,1);
+     296      275724 :     std::string resnum=line.substr(22,4);
+     297      275724 :     std::string x=line.substr(30,8);
+     298      275724 :     std::string y=line.substr(38,8);
+     299      275724 :     std::string z=line.substr(46,8);
+     300      275724 :     std::string occ=line.substr(54,6);
+     301      275724 :     std::string bet=line.substr(60,6);
+     302      275724 :     std::string BoxX=line.substr(6,9);
+     303      275724 :     std::string BoxY=line.substr(15,9);
+     304      275724 :     std::string BoxZ=line.substr(24,9);
+     305      275724 :     std::string BoxA=line.substr(33,7);
+     306      275724 :     std::string BoxB=line.substr(40,7);
+     307      275724 :     std::string BoxG=line.substr(47,7);
+     308      275724 :     Tools::trim(record);
+     309      275724 :     if(record=="TER") { between_ters=false; block_ends.push_back( positions.size() ); }
+     310      275724 :     if(record=="END") { file_is_alive=true;  break;}
+     311      274012 :     if(record=="ENDMDL") { file_is_alive=true;  break;}
+     312      273871 :     if(record=="REMARK") {
+     313        2690 :       std::vector<std::string> v1;  v1=Tools::getWords(line.substr(6));
+     314        1345 :       addRemark( v1 );
+     315        1345 :     }
+     316      273871 :     if(record=="CRYST1") {
+     317          72 :       Tools::convert(BoxX,BoxXYZ[0]);
+     318          72 :       Tools::convert(BoxY,BoxXYZ[1]);
+     319          72 :       Tools::convert(BoxZ,BoxXYZ[2]);
+     320          72 :       Tools::convert(BoxA,BoxABG[0]);
+     321          72 :       Tools::convert(BoxB,BoxABG[1]);
+     322          72 :       Tools::convert(BoxG,BoxABG[2]);
+     323          72 :       BoxXYZ*=scale;
+     324          72 :       double cosA=std::cos(BoxABG[0]*pi/180.);
+     325          72 :       double cosB=std::cos(BoxABG[1]*pi/180.);
+     326          72 :       double cosG=std::cos(BoxABG[2]*pi/180.);
+     327          72 :       double sinG=std::sin(BoxABG[2]*pi/180.);
+     328         288 :       for (unsigned i=0; i<3; i++) {Box[i][0]=0.; Box[i][1]=0.; Box[i][2]=0.;}
+     329          72 :       Box[0][0]=BoxXYZ[0];
+     330          72 :       Box[1][0]=BoxXYZ[1]*cosG;
+     331          72 :       Box[1][1]=BoxXYZ[1]*sinG;
+     332          72 :       Box[2][0]=BoxXYZ[2]*cosB;
+     333          72 :       Box[2][1]=(BoxXYZ[2]*BoxXYZ[1]*cosA-Box[2][0]*Box[1][0])/Box[1][1];
+     334          72 :       Box[2][2]=std::sqrt(BoxXYZ[2]*BoxXYZ[2]-Box[2][0]*Box[2][0]-Box[2][1]*Box[2][1]);
+     335             :     }
+     336      275941 :     if(record=="ATOM" || record=="HETATM") {
+     337             :       between_ters=true;
+     338             :       AtomNumber a;
+     339      271801 :       unsigned resno=0; // GB: when resnum string is not present, we set res number to zero
+     340             :       double o,b;
+     341      271801 :       Vector p;
+     342             :       {
+     343             :         int result;
+     344      271801 :         auto trimmed=serial;
+     345      271801 :         Tools::trim(trimmed);
+     346      271863 :         while(trimmed.length()<5) trimmed = std::string(" ") + trimmed;
+     347      271801 :         const char* errmsg = h36::hy36decode(5, trimmed.c_str(),trimmed.length(), &result);
+     348      271801 :         if(errmsg) {
+     349           0 :           std::string msg(errmsg);
+     350           0 :           plumed_merror(msg);
+     351             :         }
+     352      271801 :         a.setSerial(result);
+     353             :       }
+     354             : 
+     355             :       // allow skipping residue number
+     356             :       {
+     357      271801 :         auto trimmed=resnum;
+     358      271801 :         Tools::trim(trimmed);
+     359      271801 :         if(trimmed.length()>0) {
+     360             :           int result;
+     361      271801 :           while(trimmed.length()<4) trimmed = std::string(" ") + trimmed;
+     362      271801 :           const char* errmsg = h36::hy36decode(4, trimmed.c_str(),trimmed.length(), &result);
+     363      271801 :           if(errmsg) {
+     364           0 :             std::string msg(errmsg);
+     365           0 :             plumed_merror(msg);
+     366             :           }
+     367      271801 :           resno=result;
+     368             :         }
+     369             :       }
+     370             : 
+     371      271801 :       Tools::convert(occ,o);
+     372      271801 :       Tools::convert(bet,b);
+     373      271801 :       Tools::convert(x,p[0]);
+     374      271801 :       Tools::convert(y,p[1]);
+     375      271801 :       Tools::convert(z,p[2]);
+     376             :       // scale into nm
+     377      271801 :       p*=scale;
+     378      271801 :       numbers.push_back(a);
+     379      271801 :       number2index[a]=positions.size();
+     380      271801 :       std::size_t startpos=atomname.find_first_not_of(" \t");
+     381      271801 :       std::size_t endpos=atomname.find_last_not_of(" \t");
+     382      271801 :       atomsymb.push_back( atomname.substr(startpos, endpos-startpos+1) );
+     383      271801 :       residue.push_back(resno);
+     384      271801 :       chain.push_back(chainID);
+     385      271801 :       occupancy.push_back(o);
+     386      271801 :       beta.push_back(b);
+     387      271801 :       positions.push_back(p);
+     388      271801 :       residuenames.push_back(residuename);
+     389             :     }
+     390             :   }
+     391        2069 :   if( between_ters ) block_ends.push_back( positions.size() );
+     392        2069 :   return file_is_alive;
+     393             : }
+     394             : 
+     395         323 : bool PDB::read(const std::string&file,bool naturalUnits,double scale) {
+     396         323 :   FILE* fp=std::fopen(file.c_str(),"r");
+     397         323 :   if(!fp) return false;
+     398             : // call fclose when exiting this function
+     399         321 :   auto deleter=[](auto f) { std::fclose(f); };
+     400             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     401         321 :   readFromFilepointer(fp,naturalUnits,scale);
+     402             :   return true;
+     403             : }
+     404             : 
+     405         244 : void PDB::getChainNames( std::vector<std::string>& chains ) const {
+     406         244 :   chains.resize(0);
+     407         244 :   chains.push_back( chain[0] );
+     408      501609 :   for(unsigned i=1; i<size(); ++i) {
+     409      501365 :     if( chains[chains.size()-1]!=chain[i] ) chains.push_back( chain[i] );
+     410             :   }
+     411         244 : }
+     412             : 
+     413       11608 : void PDB::getResidueRange( const std::string& chainname, unsigned& res_start, unsigned& res_end, std::string& errmsg ) const {
+     414             :   bool inres=false, foundchain=false;
+     415    30322143 :   for(unsigned i=0; i<size(); ++i) {
+     416    30310535 :     if( chain[i]==chainname ) {
+     417    26641173 :       if(!inres) {
+     418       11608 :         if(foundchain) errmsg="found second start of chain named " + chainname;
+     419       11608 :         res_start=residue[i];
+     420             :       }
+     421             :       inres=true; foundchain=true;
+     422     3669362 :     } else if( inres && chain[i]!=chainname ) {
+     423             :       inres=false;
+     424       11094 :       res_end=residue[i-1];
+     425             :     }
+     426             :   }
+     427       11608 :   if(inres) res_end=residue[size()-1];
+     428       11608 : }
+     429             : 
+     430         161 : void PDB::getAtomRange( const std::string& chainname, AtomNumber& a_start, AtomNumber& a_end, std::string& errmsg ) const {
+     431             :   bool inres=false, foundchain=false;
+     432      434650 :   for(unsigned i=0; i<size(); ++i) {
+     433      434489 :     if( chain[i]==chainname ) {
+     434       91275 :       if(!inres) {
+     435         161 :         if(foundchain) errmsg="found second start of chain named " + chainname;
+     436         161 :         a_start=numbers[i];
+     437             :       }
+     438             :       inres=true; foundchain=true;
+     439      343214 :     } else if( inres && chain[i]!=chainname ) {
+     440             :       inres=false;
+     441          74 :       a_end=numbers[i-1];
+     442             :     }
+     443             :   }
+     444         161 :   if(inres) a_end=numbers[size()-1];
+     445         161 : }
+     446             : 
+     447        5958 : std::string PDB::getResidueName( const unsigned& resnum ) const {
+     448     7317600 :   for(unsigned i=0; i<size(); ++i) {
+     449     7317600 :     if( residue[i]==resnum ) return residuenames[i];
+     450             :   }
+     451           0 :   std::string num; Tools::convert( resnum, num );
+     452           0 :   plumed_merror("residue " + num + " not found" );
+     453             : }
+     454             : 
+     455       48686 : std::string PDB::getResidueName(const unsigned& resnum,const std::string& chainid ) const {
+     456    62791791 :   for(unsigned i=0; i<size(); ++i) {
+     457    62840657 :     if( residue[i]==resnum && ( chainid=="*" || chain[i]==chainid) ) return residuenames[i];
+     458             :   }
+     459           0 :   std::string num; Tools::convert( resnum, num );
+     460           0 :   plumed_merror("residue " + num + " not found in chain " + chainid );
+     461             : }
+     462             : 
+     463             : 
+     464       13260 : AtomNumber PDB::getNamedAtomFromResidue( const std::string& aname, const unsigned& resnum ) const {
+     465    16347180 :   for(unsigned i=0; i<size(); ++i) {
+     466    16347180 :     if( residue[i]==resnum && atomsymb[i]==aname ) return numbers[i];
+     467             :   }
+     468           0 :   std::string num; Tools::convert( resnum, num );
+     469           0 :   plumed_merror("residue " + num + " does not contain an atom named " + aname );
+     470             : }
+     471             : 
+     472        2200 : AtomNumber PDB::getNamedAtomFromResidueAndChain( const std::string& aname, const unsigned& resnum, const std::string& chainid ) const {
+     473     1069936 :   for(unsigned i=0; i<size(); ++i) {
+     474     1072136 :     if( residue[i]==resnum && atomsymb[i]==aname && ( chainid=="*" || chain[i]==chainid) ) return numbers[i];
+     475             :   }
+     476           0 :   std::string num; Tools::convert( resnum, num );
+     477           0 :   plumed_merror("residue " + num + " from chain " + chainid + " does not contain an atom named " + aname );
+     478             : }
+     479             : 
+     480       34246 : std::vector<AtomNumber> PDB::getAtomsInResidue(const unsigned& resnum,const std::string& chainid)const {
+     481             :   std::vector<AtomNumber> tmp;
+     482    91444766 :   for(unsigned i=0; i<size(); ++i) {
+     483    91931870 :     if( residue[i]==resnum && ( chainid=="*" || chain[i]==chainid) ) tmp.push_back(numbers[i]);
+     484             :   }
+     485       34246 :   if(tmp.size()==0) {
+     486           0 :     std::string num; Tools::convert( resnum, num );
+     487           0 :     plumed_merror("Cannot find residue " + num + " from chain " + chainid  );
+     488             :   }
+     489       34246 :   return tmp;
+     490             : }
+     491             : 
+     492           0 : std::vector<AtomNumber> PDB::getAtomsInChain(const std::string& chainid)const {
+     493             :   std::vector<AtomNumber> tmp;
+     494           0 :   for(unsigned i=0; i<size(); ++i) {
+     495           0 :     if( chainid=="*" || chain[i]==chainid ) tmp.push_back(numbers[i]);
+     496             :   }
+     497           0 :   if(tmp.size()==0) {
+     498           0 :     plumed_merror("Cannot find atoms from chain " + chainid  );
+     499             :   }
+     500           0 :   return tmp;
+     501             : }
+     502             : 
+     503        4638 : std::string PDB::getChainID(const unsigned& resnumber) const {
+     504     5689172 :   for(unsigned i=0; i<size(); ++i) {
+     505     5689172 :     if(resnumber==residue[i]) return chain[i];
+     506             :   }
+     507           0 :   plumed_merror("Not enough residues in pdb input file");
+     508             : }
+     509             : 
+     510           0 : std::string PDB::getChainID(AtomNumber a) const {
+     511             :   const auto p=number2index.find(a);
+     512           0 :   if(p==number2index.end()) {
+     513           0 :     std::string num; Tools::convert( a.serial(), num );
+     514           0 :     plumed_merror("Chain for atom " + num + " not found" );
+     515             :   }
+     516           0 :   return chain[p->second];
+     517             : }
+     518             : 
+     519           0 : bool PDB::checkForResidue( const std::string& name ) const {
+     520           0 :   for(unsigned i=0; i<size(); ++i) {
+     521           0 :     if( residuenames[i]==name ) return true;
+     522             :   }
+     523             :   return false;
+     524             : }
+     525             : 
+     526           0 : bool PDB::checkForAtom( const std::string& name ) const {
+     527           0 :   for(unsigned i=0; i<size(); ++i) {
+     528           0 :     if( atomsymb[i]==name ) return true;
+     529             :   }
+     530             :   return false;
+     531             : }
+     532             : 
+     533         127 : bool PDB::checkForAtom( AtomNumber a ) const {
+     534             :   const auto p=number2index.find(a);
+     535         127 :   return (p!=number2index.end());
+     536             : }
+     537             : 
+     538           0 : Log& operator<<(Log& ostr, const PDB&  pdb) {
+     539             :   const std::size_t bufferlen=1000;
+     540             :   char buffer[bufferlen];
+     541           0 :   for(unsigned i=0; i<pdb.positions.size(); i++) {
+     542           0 :     std::snprintf(buffer,bufferlen,"ATOM %3u %8.3f %8.3f %8.3f\n",pdb.numbers[i].serial(),pdb.positions[i][0],pdb.positions[i][1],pdb.positions[i][2]);
+     543           0 :     ostr<<buffer;
+     544             :   }
+     545           0 :   return ostr;
+     546             : }
+     547             : 
+     548       31112 : Vector PDB::getPosition(AtomNumber a)const {
+     549             :   const auto p=number2index.find(a);
+     550       31112 :   if(p==number2index.end()) plumed_merror("atom not available");
+     551       31112 :   else return positions[p->second];
+     552             : }
+     553             : 
+     554     2539432 : std::vector<std::string> PDB::getArgumentNames()const {
+     555     2539432 :   return argnames;
+     556             : }
+     557             : 
+     558          10 : std::string PDB::getMtype() const {
+     559          10 :   return mtype;
+     560             : }
+     561             : 
+     562         497 : void PDB::print( const double& lunits, GenericMolInfo* mymoldat, OFile& ofile, const std::string& fmt ) {
+     563         497 :   if( argnames.size()>0 ) {
+     564         476 :     ofile.printf("REMARK ARG=%s", argnames[0].c_str() );
+     565        1744 :     for(unsigned i=1; i<argnames.size(); ++i) ofile.printf(",%s",argnames[i].c_str() );
+     566         476 :     ofile.printf("\n"); ofile.printf("REMARK ");
+     567             :   }
+     568             :   std::string descr2;
+     569         497 :   if(fmt.find("-")!=std::string::npos) {
+     570           0 :     descr2="%s=" + fmt + " ";
+     571             :   } else {
+     572             :     // This ensures numbers are left justified (i.e. next to the equals sign
+     573         497 :     std::size_t psign=fmt.find("%");
+     574         497 :     plumed_assert( psign!=std::string::npos );
+     575         994 :     descr2="%s=%-" + fmt.substr(psign+1) + " ";
+     576             :   }
+     577        2241 :   for(std::map<std::string,double>::iterator it=arg_data.begin(); it!=arg_data.end(); ++it) ofile.printf( descr2.c_str(),it->first.c_str(), it->second );
+     578         497 :   if( argnames.size()>0 ) ofile.printf("\n");
+     579         497 :   if( !mymoldat ) {
+     580        2263 :     for(unsigned i=0; i<positions.size(); ++i) {
+     581             :       std::array<char,6> at;
+     582             :       {
+     583        1769 :         const char* msg = h36::hy36encode(5,numbers[i].serial(),&at[0]);
+     584        1769 :         plumed_assert(msg==nullptr) << msg;
+     585        1769 :         at[5]=0;
+     586             :       }
+     587             :       std::array<char,5> res;
+     588             :       {
+     589        1769 :         const char* msg = h36::hy36encode(4,i,&res[0]);
+     590        1769 :         plumed_assert(msg==nullptr) << msg;
+     591        1769 :         res[4]=0;
+     592             :       }
+     593        1769 :       ofile.printf("ATOM  %s  X   RES  %s    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+     594             :                    &at[0], &res[0],
+     595        1769 :                    lunits*positions[i][0], lunits*positions[i][1], lunits*positions[i][2],
+     596             :                    occupancy[i], beta[i] );
+     597             :     }
+     598             :   } else {
+     599          69 :     for(unsigned i=0; i<positions.size(); ++i) {
+     600             :       std::array<char,6> at;
+     601             :       {
+     602          66 :         const char* msg = h36::hy36encode(5,numbers[i].serial(),&at[0]);
+     603          66 :         plumed_assert(msg==nullptr) << msg;
+     604          66 :         at[5]=0;
+     605             :       }
+     606             :       std::array<char,5> res;
+     607             :       {
+     608          66 :         const char* msg = h36::hy36encode(4,mymoldat->getResidueNumber(numbers[i]),&res[0]);
+     609          66 :         plumed_assert(msg==nullptr) << msg;
+     610          66 :         res[4]=0;
+     611             :       }
+     612          66 :       ofile.printf("ATOM  %s %-4s %3s  %s    %8.3f%8.3f%8.3f%6.2f%6.2f\n",
+     613         132 :                    &at[0], mymoldat->getAtomName(numbers[i]).c_str(),
+     614          66 :                    mymoldat->getResidueName(numbers[i]).c_str(), &res[0],
+     615          66 :                    lunits*positions[i][0], lunits*positions[i][1], lunits*positions[i][2],
+     616             :                    occupancy[i], beta[i] );
+     617             :     }
+     618             :   }
+     619         497 :   ofile.printf("END\n");
+     620         497 : }
+     621             : 
+     622       37562 : bool PDB::allowedResidue( const std::string& type, const std::string& residuename ) const {
+     623       37562 :   if( type=="protein" ) {
+     624       37562 :     if(residuename=="ALA") return true;
+     625       35552 :     else if(residuename=="ARG") return true;
+     626       33312 :     else if(residuename=="ASN") return true;
+     627       31392 :     else if(residuename=="ASP") return true;
+     628       29712 :     else if(residuename=="CYS") return true;
+     629       29582 :     else if(residuename=="GLN") return true;
+     630       26782 :     else if(residuename=="GLU") return true;
+     631       25522 :     else if(residuename=="GLY") return true;
+     632       23702 :     else if(residuename=="HIS") return true;
+     633       23702 :     else if(residuename=="ILE") return true;
+     634       21452 :     else if(residuename=="LEU") return true;
+     635       17462 :     else if(residuename=="LYS") return true;
+     636       14762 :     else if(residuename=="MET") return true;
+     637       13162 :     else if(residuename=="PHE") return true;
+     638       10522 :     else if(residuename=="PRO") return true;
+     639        8542 :     else if(residuename=="SER") return true;
+     640        7112 :     else if(residuename=="THR") return true;
+     641        5762 :     else if(residuename=="TRP") return true;
+     642        5762 :     else if(residuename=="TYR") return true;
+     643        4382 :     else if(residuename=="VAL") return true;
+     644             : // Terminal groups
+     645        1492 :     else if(residuename=="ACE") return true;
+     646        1492 :     else if(residuename=="NME") return true;
+     647        1492 :     else if(residuename=="NH2") return true;
+     648             : // Alternative residue names in common force fields
+     649        1492 :     else if(residuename=="GLH") return true; // neutral GLU
+     650        1492 :     else if(residuename=="ASH") return true; // neutral ASP
+     651        1492 :     else if(residuename=="HID") return true; // HIS-D amber
+     652        1492 :     else if(residuename=="HSD") return true; // HIS-D charmm
+     653        1492 :     else if(residuename=="HIE") return true; // HIS-E amber
+     654        1112 :     else if(residuename=="HSE") return true; // HIS-E charmm
+     655        1112 :     else if(residuename=="HIP") return true; // HIS-P amber
+     656        1112 :     else if(residuename=="HSP") return true; // HIS-P charmm
+     657             : // Weird amino acids
+     658        1112 :     else if(residuename=="NLE") return true;
+     659        1112 :     else if(residuename=="SFO") return true;
+     660        1112 :     else return false;
+     661           0 :   } else if( type=="dna" ) {
+     662           0 :     if(residuename=="A") return true;
+     663           0 :     else if(residuename=="A5") return true;
+     664           0 :     else if(residuename=="A3") return true;
+     665           0 :     else if(residuename=="AN") return true;
+     666           0 :     else if(residuename=="G") return true;
+     667           0 :     else if(residuename=="G5") return true;
+     668           0 :     else if(residuename=="G3") return true;
+     669           0 :     else if(residuename=="GN") return true;
+     670           0 :     else if(residuename=="T") return true;
+     671           0 :     else if(residuename=="T5") return true;
+     672           0 :     else if(residuename=="T3") return true;
+     673           0 :     else if(residuename=="TN") return true;
+     674           0 :     else if(residuename=="C") return true;
+     675           0 :     else if(residuename=="C5") return true;
+     676           0 :     else if(residuename=="C3") return true;
+     677           0 :     else if(residuename=="CN") return true;
+     678           0 :     else if(residuename=="DA") return true;
+     679           0 :     else if(residuename=="DA5") return true;
+     680           0 :     else if(residuename=="DA3") return true;
+     681           0 :     else if(residuename=="DAN") return true;
+     682           0 :     else if(residuename=="DG") return true;
+     683           0 :     else if(residuename=="DG5") return true;
+     684           0 :     else if(residuename=="DG3") return true;
+     685           0 :     else if(residuename=="DGN") return true;
+     686           0 :     else if(residuename=="DT") return true;
+     687           0 :     else if(residuename=="DT5") return true;
+     688           0 :     else if(residuename=="DT3") return true;
+     689           0 :     else if(residuename=="DTN") return true;
+     690           0 :     else if(residuename=="DC") return true;
+     691           0 :     else if(residuename=="DC5") return true;
+     692           0 :     else if(residuename=="DC3") return true;
+     693           0 :     else if(residuename=="DCN") return true;
+     694           0 :     else return false;
+     695           0 :   } else if( type=="rna" ) {
+     696           0 :     if(residuename=="A") return true;
+     697           0 :     else if(residuename=="A5") return true;
+     698           0 :     else if(residuename=="A3") return true;
+     699           0 :     else if(residuename=="AN") return true;
+     700           0 :     else if(residuename=="G") return true;
+     701           0 :     else if(residuename=="G5") return true;
+     702           0 :     else if(residuename=="G3") return true;
+     703           0 :     else if(residuename=="GN") return true;
+     704           0 :     else if(residuename=="U") return true;
+     705           0 :     else if(residuename=="U5") return true;
+     706           0 :     else if(residuename=="U3") return true;
+     707           0 :     else if(residuename=="UN") return true;
+     708           0 :     else if(residuename=="C") return true;
+     709           0 :     else if(residuename=="C5") return true;
+     710           0 :     else if(residuename=="C3") return true;
+     711           0 :     else if(residuename=="CN") return true;
+     712           0 :     else if(residuename=="RA") return true;
+     713           0 :     else if(residuename=="RA5") return true;
+     714           0 :     else if(residuename=="RA3") return true;
+     715           0 :     else if(residuename=="RAN") return true;
+     716           0 :     else if(residuename=="RG") return true;
+     717           0 :     else if(residuename=="RG5") return true;
+     718           0 :     else if(residuename=="RG3") return true;
+     719           0 :     else if(residuename=="RGN") return true;
+     720           0 :     else if(residuename=="RU") return true;
+     721           0 :     else if(residuename=="RU5") return true;
+     722           0 :     else if(residuename=="RU3") return true;
+     723           0 :     else if(residuename=="RUN") return true;
+     724           0 :     else if(residuename=="RC") return true;
+     725           0 :     else if(residuename=="RC5") return true;
+     726           0 :     else if(residuename=="RC3") return true;
+     727           0 :     else if(residuename=="RCN") return true;
+     728           0 :     else return false;
+     729           0 :   } else if( type=="water" ) {
+     730           0 :     if(residuename=="SOL") return true;
+     731           0 :     if(residuename=="WAT") return true;
+     732           0 :     return false;
+     733           0 :   } else if( type=="ion" ) {
+     734           0 :     if(residuename=="IB+") return true;
+     735           0 :     if(residuename=="CA") return true;
+     736           0 :     if(residuename=="CL") return true;
+     737           0 :     if(residuename=="NA") return true;
+     738           0 :     if(residuename=="MG") return true;
+     739           0 :     if(residuename=="K") return true;
+     740           0 :     if(residuename=="RB") return true;
+     741           0 :     if(residuename=="CS") return true;
+     742           0 :     if(residuename=="LI") return true;
+     743           0 :     if(residuename=="ZN") return true;
+     744           0 :     return false;
+     745             :   }
+     746             :   return false;
+     747             : }
+     748             : 
+     749             : }
+     750             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.cpp.func-sort-c.html b/coverage/tools/Pbc.cpp.func-sort-c.html new file mode 100644 index 000000000000..5eec14232720 --- /dev/null +++ b/coverage/tools/Pbc.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12312995.3 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3Pbc8distanceEbRKNS_13VectorGenericILj3EEES4_0
_ZNK4PLMD3Pbc9getInvBoxEv2174
_ZNK4PLMD3Pbc13isOrthorombicEv8524
_ZN4PLMD3PbcC2Ev18109
_ZNK4PLMD3Pbc11buildShiftsEPA2_A2_NS_3gch12small_vectorINS_13VectorGenericILj3EEELj6ESaIS4_EEE20621
_ZNK4PLMD3Pbc6getBoxEv42189
_ZN4PLMD3Pbc6setBoxERKNS_13TensorGenericILj3ELj3EEE65478
_ZNK4PLMD3Pbc5applyENS_12mdMemoryViewILm18446744073709551615ELm3EEEj222049
_ZNK4PLMD3Pbc5applyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj222049
_ZNK4PLMD3Pbc12scaledToRealERKNS_13VectorGenericILj3EEE223368
_ZNK4PLMD3Pbc10fullSearchERNS_13VectorGenericILj3EEE600000
_ZNK4PLMD3Pbc12realToScaledERKNS_13VectorGenericILj3EEE1221349
_ZNK4PLMD3Pbc8distanceERKNS_13VectorGenericILj3EEES4_Pi207406879
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.cpp.func.html b/coverage/tools/Pbc.cpp.func.html new file mode 100644 index 000000000000..a777f71873c8 --- /dev/null +++ b/coverage/tools/Pbc.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12312995.3 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3Pbc6setBoxERKNS_13TensorGenericILj3ELj3EEE65478
_ZN4PLMD3PbcC2Ev18109
_ZNK4PLMD3Pbc10fullSearchERNS_13VectorGenericILj3EEE600000
_ZNK4PLMD3Pbc11buildShiftsEPA2_A2_NS_3gch12small_vectorINS_13VectorGenericILj3EEELj6ESaIS4_EEE20621
_ZNK4PLMD3Pbc12realToScaledERKNS_13VectorGenericILj3EEE1221349
_ZNK4PLMD3Pbc12scaledToRealERKNS_13VectorGenericILj3EEE223368
_ZNK4PLMD3Pbc13isOrthorombicEv8524
_ZNK4PLMD3Pbc5applyENS_12mdMemoryViewILm18446744073709551615ELm3EEEj222049
_ZNK4PLMD3Pbc5applyERSt6vectorINS_13VectorGenericILj3EEESaIS3_EEj222049
_ZNK4PLMD3Pbc6getBoxEv42189
_ZNK4PLMD3Pbc8distanceERKNS_13VectorGenericILj3EEES4_Pi207406879
_ZNK4PLMD3Pbc8distanceEbRKNS_13VectorGenericILj3EEES4_0
_ZNK4PLMD3Pbc9getInvBoxEv2174
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.cpp.gcov.html b/coverage/tools/Pbc.cpp.gcov.html new file mode 100644 index 000000000000..6fdff7d4c8fd --- /dev/null +++ b/coverage/tools/Pbc.cpp.gcov.html @@ -0,0 +1,368 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12312995.3 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Pbc.h"
+      23             : #include "Tools.h"
+      24             : #include "Exception.h"
+      25             : #include "LatticeReduction.h"
+      26             : #include <iostream>
+      27             : #include "Random.h"
+      28             : #include <cmath>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32       18109 : Pbc::Pbc():
+      33      271635 :   type(unset)
+      34             : {
+      35       18109 :   box.zero();
+      36       18109 :   invBox.zero();
+      37       18109 : }
+      38             : 
+      39       20621 : void Pbc::buildShifts(gch::small_vector<Vector,maxshiftsize> shifts[2][2][2])const {
+      40             :   const double small=1e-28;
+      41             : 
+      42             : // clear all shifts
+      43      309315 :   for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) shifts[i][j][k].clear();
+      44             : 
+      45             : // enumerate all possible shifts
+      46             : // since box is reduced, only 27 shifts have to be attempted
+      47      824840 :   for(int l=-1; l<=1; l++) for(int m=-1; m<=1; m++) for(int n=-1; n<=1; n++) {
+      48             : 
+      49             : // int/double shift vectors
+      50      556767 :         const int ishift[3]= {l,m,n};
+      51      556767 :         Vector dshift(l,m,n);
+      52             : 
+      53             : // count how many components are != 0
+      54             :         unsigned count=0;
+      55     2227068 :         for(int s=0; s<3; s++) if(ishift[s]!=0) count++;
+      56             : 
+      57             : // skips trivial (0,0,0) and cases with three shifts
+      58             : // only 18 shifts survive past this point
+      59      647643 :         if(count==0 || count==3) continue;
+      60             : 
+      61             : // check if that Wigner-Seitz face is perpendicular to the axis.
+      62             : // this allows to eliminate shifts in symmetric cells.
+      63             : // e.g., if one lactice vector is orthogonal to the plane spanned
+      64             : // by the other two vectors, that shift should never be tried
+      65      371178 :         Vector cosdir=matmul(reduced,transpose(reduced),dshift);
+      66      371178 :         double dp=dotProduct(dshift,cosdir);
+      67      371178 :         double ref=modulo2(dshift)*modulo2(cosdir);
+      68      371178 :         if(std::fabs(ref-dp*dp)<small) continue;
+      69             : 
+      70             : // here we start pruning depending on the sign of the scaled coordinate
+      71     4204530 :         for(int i=0; i<2; i++) for(int j=0; j<2; j++) for(int k=0; k<2; k++) {
+      72             : 
+      73     2242416 :               const int block[3]= {2*i-1,2*j-1,2*k-1};
+      74             : 
+      75             : // skip cases where shift would bring too far from origin
+      76             :               bool skip=false;
+      77     8969664 :               for(int s=0; s<3; s++) if(ishift[s]*block[s]>0) skip=true;
+      78     2533360 :               if(skip) continue;
+      79             :               skip=true;
+      80     3064976 :               for(int s=0; s<3; s++) {
+      81             : // check that the components of cosdir along the non-shifted directions
+      82             : // have the proper sign
+      83     2298732 :                 if(((1-ishift[s]*ishift[s])*block[s])*cosdir[s]<-small) skip=false;
+      84             :               }
+      85      766244 :               if(skip)continue;
+      86             : 
+      87             : // if we arrive to this point, shift is eligible and is added to the list
+      88      950600 :               shifts[i][j][k].push_back(matmul(transpose(reduced),dshift));
+      89             :             }
+      90             :       }
+      91       20621 : }
+      92             : 
+      93      600000 : void Pbc::fullSearch(Vector&d)const {
+      94      600000 :   if(type==unset) return;
+      95      528100 :   Vector s=matmul(invReduced.transpose(),d);
+      96     2112400 :   for(int i=0; i<3; i++) s[i]=Tools::pbc(s[i]);
+      97      528100 :   d=matmul(reduced.transpose(),s);
+      98             :   const int smax=4;
+      99      528100 :   Vector a0(reduced.getRow(0));
+     100      528100 :   Vector a1(reduced.getRow(1));
+     101      528100 :   Vector a2(reduced.getRow(2));
+     102      528100 :   Vector best(d);
+     103      528100 :   double lbest=d.modulo2();
+     104   433042000 :   for(int i=-smax; i<=smax; i++) for(int j=-smax; j<=smax; j++) for(int k=-smax; k<=smax; k++) {
+     105   384984900 :         Vector trial=d+i*a0+j*a1+k*a2;
+     106   384984900 :         double ltrial=trial.modulo2();
+     107   384984900 :         if(ltrial<lbest) {
+     108       29897 :           best=trial;
+     109             :           lbest=ltrial;
+     110             :         }
+     111             :       }
+     112      528100 :   d=best;
+     113             : }
+     114             : 
+     115       65478 : void Pbc::setBox(const Tensor&b) {
+     116       65478 :   box=b;
+     117             : // detect type:
+     118             :   const double epsilon=1e-28;
+     119             : 
+     120       65478 :   type=unset;
+     121       65478 :   double det=box.determinant();
+     122       65478 :   if(det*det<epsilon) return;
+     123             : 
+     124             :   bool cxy=false;
+     125             :   bool cxz=false;
+     126             :   bool cyz=false;
+     127       63483 :   if(box(0,1)*box(0,1)<epsilon && box(1,0)*box(1,0)<epsilon) cxy=true;
+     128       63483 :   if(box(0,2)*box(0,2)<epsilon && box(2,0)*box(2,0)<epsilon) cxz=true;
+     129       63483 :   if(box(1,2)*box(1,2)<epsilon && box(2,1)*box(2,1)<epsilon) cyz=true;
+     130             : 
+     131       63483 :   invBox=box.inverse();
+     132             : 
+     133       63483 :   if(cxy && cxz && cyz) type=orthorombic;
+     134       20621 :   else type=generic;
+     135             : 
+     136       63483 :   if(type==orthorombic) {
+     137       42862 :     reduced=box;
+     138       42862 :     invReduced=inverse(reduced);
+     139      171448 :     for(unsigned i=0; i<3; i++) {
+     140      128586 :       diag[i]=box[i][i];
+     141      128586 :       hdiag[i]=0.5*box[i][i];
+     142      128586 :       mdiag[i]=-0.5*box[i][i];
+     143             :     }
+     144             :   } else {
+     145       20621 :     reduced=box;
+     146       20621 :     LatticeReduction::reduce(reduced);
+     147       20621 :     invReduced=inverse(reduced);
+     148       20621 :     buildShifts(shifts);
+     149             :   }
+     150             : 
+     151             : }
+     152             : 
+     153           0 : double Pbc::distance( const bool pbc, const Vector& v1, const Vector& v2 ) const {
+     154           0 :   if(pbc) { return ( distance(v1,v2) ).modulo(); }
+     155           0 :   else { return ( delta(v1,v2) ).modulo(); }
+     156             : }
+     157             : 
+     158      222049 : void Pbc::apply(std::vector<Vector>& dlist, unsigned max_index) const {
+     159      222049 :   apply(VectorView(&dlist[0][0],dlist.size()),max_index);
+     160      222049 : }
+     161             : 
+     162      222049 : void Pbc::apply(VectorView dlist, unsigned max_index) const {
+     163      222049 :   if (max_index==0) max_index=dlist.size();
+     164      222049 :   if(type==unset) {
+     165             :     // do nothing
+     166      222045 :   } else if(type==orthorombic) {
+     167             : #ifdef __PLUMED_PBC_WHILE
+     168             :     for(unsigned k=0; k<max_index; ++k) {
+     169             :       while(dlist[k][0]>hdiag[0])   dlist[k][0]-=diag[0];
+     170             :       while(dlist[k][0]<=mdiag[0])  dlist[k][0]+=diag[0];
+     171             :       while(dlist[k][1]>hdiag[1])   dlist[k][1]-=diag[1];
+     172             :       while(dlist[k][1]<=mdiag[1])  dlist[k][1]+=diag[1];
+     173             :       while(dlist[k][2]>hdiag[2])   dlist[k][2]-=diag[2];
+     174             :       while(dlist[k][2]<=mdiag[2])  dlist[k][2]+=diag[2];
+     175             :     }
+     176             : #else
+     177   401914451 :     for(unsigned k=0; k<max_index; ++k) {
+     178  1606776864 :       for(int i=0; i<3; i++) {
+     179  1205082648 :         dlist[k][i]=Tools::pbc(dlist[k][i]*invBox(i,i))*box(i,i);
+     180             :       }
+     181             :     }
+     182             : #endif
+     183        1810 :   } else if(type==generic) {
+     184       67768 :     for(unsigned k=0; k<max_index; ++k) {
+     185             :       //Inlining by hand this part of function from distance speeds up by about 20-30%
+     186             :       //against the previos version, and 60-80% agains this version non inlined.
+     187             :       //I do not think is the `if(nshifts) *nshifts+=myshifts.size();`,
+     188             :       //but that the compiler now see how we are juggling with the memory and it
+     189             :       //does its magic
+     190             : 
+     191             :       //I tried writing VectorGeneric<3> matmul(const MemoryView<3UL> a,const TensorGeneric<3,3>&b)
+     192             :       // by copy-pasting the original vector-tensor, but slows down this method by 10%... (on gcc9)
+     193       65958 :       Vector s=matmul(Vector{dlist[k][0],dlist[k][1],dlist[k][2]},invReduced);
+     194             :       // bring to -0.5,+0.5 region in scaled coordinates:
+     195      263832 :       for(int i=0; i<3; ++i) {
+     196      197874 :         s[i]=Tools::pbc(s[i]);
+     197             :       }
+     198       65958 :       Vector best(matmul(s,reduced));
+     199             :       // check if shifts have to be attempted:
+     200       65958 :       if((std::fabs(s[0])+std::fabs(s[1])+std::fabs(s[2])>0.5)) {
+     201             :         // list of shifts is specific for that "octant" (depends on signs of s[i]):
+     202       97104 :         const auto & myshifts(shifts[(s[0]>0?1:0)][(s[1]>0?1:0)][(s[2]>0?1:0)]);
+     203       48552 :         Vector reference = best;
+     204       48552 :         double lbest(modulo2(best));
+     205             :         // loop over possible shifts:
+     206      174004 :         for(unsigned i=0; i<myshifts.size(); ++i) {
+     207      125452 :           Vector trial=reference+myshifts[i];
+     208      125452 :           double ltrial=modulo2(trial);
+     209      125452 :           if(ltrial<lbest) {
+     210             :             lbest=ltrial;
+     211           0 :             best=trial;
+     212             :           }
+     213             :         }
+     214             :       }
+     215       65958 :       dlist[k][0]  = best[0];
+     216       65958 :       dlist[k][1]  = best[1];
+     217       65958 :       dlist[k][2]  = best[2];
+     218             :     }
+     219           0 :   } else plumed_merror("unknown pbc type");
+     220      222049 : }
+     221             : 
+     222   207406879 : Vector Pbc::distance(const Vector&v1,const Vector&v2,int*nshifts)const {
+     223   207406879 :   Vector d=delta(v1,v2);
+     224   207406879 :   if(type==unset) {
+     225             :     // do nothing
+     226   184775336 :   } else if(type==orthorombic) {
+     227             : #ifdef __PLUMED_PBC_WHILE
+     228             :     for(unsigned i=0; i<3; i++) {
+     229             :       while(d[i]>hdiag[i]) d[i]-=diag[i];
+     230             :       while(d[i]<=mdiag[i]) d[i]+=diag[i];
+     231             :     }
+     232             : #else
+     233   546061020 :     for(int i=0; i<3; i++) d[i]=Tools::pbc(d[i]*invBox(i,i))*box(i,i);
+     234             : #endif
+     235    48260081 :   } else if(type==generic) {
+     236    48260081 :     Vector s=matmul(d,invReduced);
+     237             : // check if images have to be computed:
+     238             : //    if((std::fabs(s[0])+std::fabs(s[1])+std::fabs(s[2])>0.5)){
+     239             : // NOTICE: the check in the previous line, albeit correct, is breaking many regtest
+     240             : //         since it does not apply Tools::pbc in many cases. Moreover, it does not
+     241             : //         introduce a significant gain. I thus leave it out for the moment.
+     242             :     if constexpr (true) {
+     243             : // bring to -0.5,+0.5 region in scaled coordinates:
+     244   193040324 :       for(int i=0; i<3; i++) {
+     245   144780243 :         s[i]=Tools::pbc(s[i]);
+     246             :       }
+     247    48260081 :       d=matmul(s,reduced);
+     248             : // check if shifts have to be attempted:
+     249    48260081 :       if((std::fabs(s[0])+std::fabs(s[1])+std::fabs(s[2])>0.5)) {
+     250             : // list of shifts is specific for that "octant" (depends on signs of s[i]):
+     251    78667914 :         const auto & myshifts(shifts[(s[0]>0?1:0)][(s[1]>0?1:0)][(s[2]>0?1:0)]);
+     252    39818679 :         Vector best(d);
+     253    39818679 :         double lbest(modulo2(best));
+     254             : // loop over possible shifts:
+     255    39818679 :         if(nshifts) *nshifts+=myshifts.size();
+     256   179246107 :         for(unsigned i=0; i<myshifts.size(); i++) {
+     257   139427428 :           Vector trial=d+myshifts[i];
+     258   139427428 :           double ltrial=modulo2(trial);
+     259   139427428 :           if(ltrial<lbest) {
+     260             :             lbest=ltrial;
+     261     3759325 :             best=trial;
+     262             :           }
+     263             :         }
+     264    39818679 :         d=best;
+     265             :       }
+     266             :     }
+     267           0 :   } else plumed_merror("unknown pbc type");
+     268   207406879 :   return d;
+     269             : }
+     270             : 
+     271     1221349 : Vector Pbc::realToScaled(const Vector&d)const {
+     272     1221349 :   return matmul(invBox.transpose(),d);
+     273             : }
+     274             : 
+     275      223368 : Vector Pbc::scaledToReal(const Vector&d)const {
+     276      223368 :   return matmul(box.transpose(),d);
+     277             : }
+     278             : 
+     279        8524 : bool Pbc::isOrthorombic()const {
+     280        8524 :   return type==orthorombic;
+     281             : }
+     282             : 
+     283       42189 : const Tensor& Pbc::getBox()const {
+     284       42189 :   return box;
+     285             : }
+     286             : 
+     287        2174 : const Tensor& Pbc::getInvBox()const {
+     288        2174 :   return invBox;
+     289             : }
+     290             : 
+     291             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.h.func-sort-c.html b/coverage/tools/Pbc.h.func-sort-c.html new file mode 100644 index 000000000000..f358012db127 --- /dev/null +++ b/coverage/tools/Pbc.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.h.func.html b/coverage/tools/Pbc.h.func.html new file mode 100644 index 000000000000..30f917912c1c --- /dev/null +++ b/coverage/tools/Pbc.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Pbc.h.gcov.html b/coverage/tools/Pbc.h.gcov.html new file mode 100644 index 000000000000..3a09a0237b69 --- /dev/null +++ b/coverage/tools/Pbc.h.gcov.html @@ -0,0 +1,225 @@ + + + + + + + + LCOV - plumed test coverage - tools/Pbc.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Pbc.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5683.3 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Pbc_h
+      23             : #define __PLUMED_tools_Pbc_h
+      24             : 
+      25             : #include "Vector.h"
+      26             : #include "Tensor.h"
+      27             : #include "small_vector/small_vector.h"
+      28             : #include <vector>
+      29             : #include <cstddef>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : //this more or less mocks c++20 span with fixed size
+      34             : template < std::size_t N=3>
+      35             : class MemoryView {
+      36             :   double *ptr_;
+      37             : public:
+      38             :   MemoryView(double* p) :ptr_(p) {}
+      39             :   constexpr size_t size()const {return N;}
+      40             :   static constexpr size_t extent = N;
+      41  1205082648 :   double & operator[](size_t i) { return ptr_[i];}
+      42             :   const double & operator[](size_t i) const { return ptr_[i];}
+      43             : };
+      44             : 
+      45             : namespace helpers {
+      46             : inline constexpr std::size_t dynamic_extent = -1;
+      47             : }
+      48             : //this more or less mocks c++23 mdspan without the fancy multi-indexed operator[]
+      49             : //the idea is to take an address that you know to be strided in a certain way and
+      50             : //make it avaiable to any interface (like using the data from a nunmpy.ndarray in
+      51             : //a function thought for a std::vector<PLMD::Vector> )
+      52             : //the N=-1 is there for mocking the run time size from the span (where a
+      53             : //dynamic extent is size_t(-))
+      54             : template < std::size_t N=helpers::dynamic_extent, std::size_t STRIDE=3>
+      55             : class mdMemoryView {
+      56             :   double *ptr_;
+      57             :   size_t size_;
+      58             : public:
+      59      222049 :   mdMemoryView(double* p, size_t s) :ptr_(p), size_(s) {}
+      60           0 :   size_t size()const {return size_;}
+      61             :   static constexpr size_t extent = N;
+      62             :   static constexpr size_t stride = STRIDE;
+      63  1205148606 :   MemoryView<STRIDE> operator[](size_t i) { return MemoryView<STRIDE>(ptr_ + i * STRIDE);}
+      64             : };
+      65             : 
+      66             : using VectorView = mdMemoryView<helpers::dynamic_extent, 3>;
+      67             : 
+      68             : /*
+      69             : Tool to deal with periodic boundary conditions.
+      70             : 
+      71             : This class is useful to apply periodic boundary conditions on interatomic
+      72             : distances. It stores privately information about reduced lattice vectors
+      73             : */
+      74        2403 : class Pbc {
+      75             : /// Type of box
+      76             :   enum {unset,orthorombic,generic} type;
+      77             : /// This is the maximum expected size for general boxes.
+      78             : /// I found this empirically by manually modifying regtest basic/rt-make-1
+      79             : /// Since it uses randomly generated boxes it should be correct.
+      80             : /// In any case, this is just used as a hint for small_vector,
+      81             : /// which will then switch to heap allocations if more shifts are needed
+      82             :   static constexpr unsigned maxshiftsize=6;
+      83             : /// Box
+      84             :   Tensor box;
+      85             : /// Inverse box
+      86             :   Tensor invBox;
+      87             : /// Reduced box.
+      88             : /// This is a set of lattice vectors generating the same lattice
+      89             : /// but "minimally skewed". Useful to optimize image search.
+      90             :   Tensor reduced;
+      91             : /// Inverse of the reduced box
+      92             :   Tensor invReduced;
+      93             : /// List of shifts that should be attempted.
+      94             : /// Depending on the sign of the scaled coordinates representing
+      95             : /// a distance vector, a different set of shifts must be tried.
+      96             :   gch::small_vector<Vector,maxshiftsize> shifts[2][2][2];
+      97             : /// Alternative representation for orthorombic cells.
+      98             : /// Not really used, but could be used to optimize search in
+      99             : /// orthorombic cells.
+     100             :   Vector diag,hdiag,mdiag;
+     101             : /// Build list of shifts.
+     102             : /// This is expensive, and must be called only when box is
+     103             : /// reset. It allows building a minimal set of shifts
+     104             : /// depending on the sign of the scaled coordinates representing
+     105             : /// a distance vector.
+     106             :   void buildShifts(gch::small_vector<Vector,maxshiftsize> shifts[2][2][2])const;
+     107             : public:
+     108             : /// Constructor
+     109             :   Pbc();
+     110             : /// Compute modulo of (v2-v1), using or not pbc depending on bool pbc.
+     111             :   double distance( const bool pbc, const Vector& v1, const Vector& v2 ) const;
+     112             : /// Computes v2-v1, using minimal image convention
+     113             : /// if specified, also returns the number of attempted shifts
+     114             :   Vector distance(const Vector&, const Vector&,int*nshifts=nullptr)const;
+     115             : /// Apply PBC to a set of positions or distance vectors
+     116             :   void apply(VectorView dlist, unsigned max_index=0) const;
+     117             :   void apply(std::vector<Vector>&dlist, unsigned max_index=0) const;
+     118             : /// Set the lattice vectors.
+     119             : /// b[i][j] is the j-th component of the i-th vector
+     120             :   void setBox(const Tensor&b);
+     121             : /// Returns the box
+     122             :   const Tensor& getBox()const;
+     123             : /// Returns the inverse matrix of box.
+     124             : /// Thus: pbc.getInvBox() == inverse(pbc.getBox()).
+     125             :   const Tensor& getInvBox()const;
+     126             : /// Transform a vector in real space to a vector in scaled coordinates.
+     127             : /// Thus:pbc.realToScaled(v) == matmul(transpose(inverse(pbc.getBox(),v)));
+     128             :   Vector realToScaled(const Vector&)const;
+     129             : /// Transform a vector in scaled coordinates to a vector in real space.
+     130             : /// Thus:pbc.scaledToRead(v) == matmul(transpose(pbc.getBox()),v);
+     131             :   Vector scaledToReal(const Vector&)const;
+     132             : /// Returns true if the box vectors are orthogonal
+     133             :   bool isOrthorombic()const;
+     134             : /// Full search (for testing).
+     135             : /// Perform a full search on vector
+     136             :   void fullSearch(Vector&)const;
+     137             : /// Returns true if box is set and non zero
+     138             :   bool isSet()const;
+     139             : };
+     140             : 
+     141             : inline
+     142             : bool Pbc::isSet()const {
+     143       14258 :   return type!=unset;
+     144             : }
+     145             : 
+     146             : }
+     147             : 
+     148             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PlumedHandle.cpp.func-sort-c.html b/coverage/tools/PlumedHandle.cpp.func-sort-c.html new file mode 100644 index 000000000000..f7948f76538e --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - tools/PlumedHandle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PlumedHandle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:233663.9 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12PlumedHandleC2EOS0_0
_ZN4PLMD12PlumedHandleD0Ev0
_ZN4PLMD12PlumedHandleaSEOS0_0
_ZN4PLMD12PlumedHandle6dlopenEPKc1
_ZN4PLMD12PlumedHandleC2EPKc1
_ZN4PLMD12PlumedHandleC2Ev11
_ZN4PLMD12PlumedHandleD2Ev12
_ZN4PLMD12PlumedHandle3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE1476
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PlumedHandle.cpp.func.html b/coverage/tools/PlumedHandle.cpp.func.html new file mode 100644 index 000000000000..42fc3175eb65 --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - tools/PlumedHandle.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PlumedHandle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:233663.9 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12PlumedHandle3cmdESt17basic_string_viewIcSt11char_traitsIcEERKNS_11TypesafePtrE1476
_ZN4PLMD12PlumedHandle6dlopenEPKc1
_ZN4PLMD12PlumedHandleC2EOS0_0
_ZN4PLMD12PlumedHandleC2EPKc1
_ZN4PLMD12PlumedHandleC2Ev11
_ZN4PLMD12PlumedHandleD0Ev0
_ZN4PLMD12PlumedHandleD2Ev12
_ZN4PLMD12PlumedHandleaSEOS0_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/PlumedHandle.cpp.gcov.html b/coverage/tools/PlumedHandle.cpp.gcov.html new file mode 100644 index 000000000000..66a3b3e71cca --- /dev/null +++ b/coverage/tools/PlumedHandle.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - tools/PlumedHandle.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - PlumedHandle.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:233663.9 %
Date:2024-02-22 21:58:45Functions:5862.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "PlumedHandle.h"
+      23             : #include "core/PlumedMain.h"
+      24             : #include "Tools.h"
+      25             : #include "lepton/Exception.h"
+      26             : #include <cstring>
+      27             : #ifdef __PLUMED_HAS_DLOPEN
+      28             : #include <dlfcn.h>
+      29             : #endif
+      30             : 
+      31             : // Including Plumed.h in this manner allows to create a local
+      32             : // implementation of the wrapper in an anonymous namespace.
+      33             : // This allows to avoid recoding all the Plumed.h stuff here
+      34             : // and at the same time avoids possible conflicts.
+      35             : #define __PLUMED_WRAPPER_IMPLEMENTATION 1
+      36             : #define __PLUMED_WRAPPER_EXTERN 0
+      37             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE 1
+      38             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS 1
+      39             : #include "../wrapper/Plumed.h"
+      40             : 
+      41             : namespace PLMD
+      42             : {
+      43             : 
+      44             : 
+      45          11 : PlumedHandle::PlumedHandle():
+      46          11 :   local(Tools::make_unique<PlumedMain>())
+      47             : {
+      48          11 : }
+      49             : 
+      50           1 : PlumedHandle::PlumedHandle(const char* kernel)
+      51             : #ifdef __PLUMED_HAS_DLOPEN
+      52             :   :
+      53           1 :   loaded(plumed_c2v(plumed_create_dlopen(kernel)))
+      54             : {
+      55             :   if(!plumed_valid(plumed_v2c(loaded))) {
+      56             :     // this is necessary to make sure loaded is properly destroyed
+      57           0 :     plumed_finalize(plumed_v2c(loaded));
+      58           0 :     plumed_error() << "You are trying to dynamically load a kernel, but the path " << kernel <<" could not be opened";
+      59             :   }
+      60           1 : }
+      61             : #else
+      62             : {
+      63             :   plumed_error() << "You are trying to dynamically load a kernel, but PLUMED was compiled without dlopen";
+      64             : }
+      65             : #endif
+      66             : 
+      67          12 : PlumedHandle::~PlumedHandle() {
+      68          12 :   if(loaded) plumed_finalize(plumed_v2c(loaded));
+      69          12 : }
+      70             : 
+      71           1 : PlumedHandle PlumedHandle::dlopen(const char* path) {
+      72           1 :   return PlumedHandle(path);
+      73             : }
+      74             : 
+      75        1476 : void PlumedHandle::cmd(std::string_view key,const TypesafePtr & ptr) {
+      76        1476 :   if(local) {
+      77        1254 :     local->cmd(key,ptr);
+      78         222 :   } else if(loaded) {
+      79             :     plumed_safeptr safe;
+      80         222 :     safe.ptr=ptr.getRaw();
+      81         222 :     safe.nelem=ptr.getNelem();
+      82         222 :     safe.shape=const_cast<std::size_t*>(ptr.getShape());
+      83         222 :     safe.flags=ptr.getFlags();
+      84         222 :     safe.opt=nullptr;
+      85             :     // this is to ensure the string_view is null terminated
+      86         222 :     auto key_string=std::string(key);
+      87         222 :     plumed_cmd(plumed_v2c(loaded),key_string.c_str(),safe);
+      88           0 :   } else plumed_error() << "should never arrive here (either one or the other should work)";
+      89        1476 : }
+      90             : 
+      91           0 : PlumedHandle::PlumedHandle(PlumedHandle && other) noexcept:
+      92             :   local(std::move(other.local)),
+      93           0 :   loaded(other.loaded)
+      94             : {
+      95           0 :   other.loaded=nullptr;
+      96           0 : }
+      97             : 
+      98           0 : PlumedHandle & PlumedHandle::operator=(PlumedHandle && other) noexcept {
+      99           0 :   if(this!=&other) {
+     100           0 :     if(loaded) plumed_finalize(plumed_v2c(loaded));
+     101             :     local=std::move(other.local);
+     102           0 :     loaded=other.loaded;
+     103           0 :     other.loaded=nullptr;
+     104             :   }
+     105           0 :   return *this;
+     106             : }
+     107             : 
+     108             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.cpp.func-sort-c.html b/coverage/tools/RMSD.cpp.func-sort-c.html new file mode 100644 index 000000000000..37aa44e67bf6 --- /dev/null +++ b/coverage/tools/RMSD.cpp.func-sort-c.html @@ -0,0 +1,393 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:54073573.5 %
Date:2024-02-22 21:58:45Functions:428052.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12RMSDCoreData18getReferenceCenterEv0
_ZN4PLMD12RMSDCoreData22getDRotationDReferenceEb0
_ZN4PLMD12RMSDCoreData26getDDistanceDReferenceSOMAEv0
_ZN4PLMD12RMSDCoreData30getAlignedReferenceToPositionsEv0
_ZN4PLMD4RMSD11getDisplaceEv0
_ZN4PLMD4RMSD20optimalAlignment_FitILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EERSA_RS8_b0
_ZN4PLMD4RMSD20optimalAlignment_FitILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EERSA_RS8_b0
_ZN4PLMD4RMSD27calc_DDistDRef_Rot_DRotDPosERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_S8_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EEb0
_ZN4PLMD4RMSD36calc_DDistDRef_Rot_DRotDPos_DRotDRefERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_S8_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EESE_b0
_ZN4PLMD4RMSD8getAlignEv0
_ZN4PLMD4RMSD9calc_SOMAERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_S8_b0
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD20optimalAlignment_RotILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb0
_ZNK4PLMD4RMSD20optimalAlignment_RotILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb0
_ZNK4PLMD4RMSD20optimalAlignment_RotILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb0
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb0
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb0
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb0
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb0
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb0
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb0
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZN4PLMD12RMSDCoreData22getDDistanceDReferenceEv1
_ZN4PLMD4RMSD14calc_DDistDRefERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_S8_b1
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b1
_ZNK4PLMD4RMSD16optimalAlignmentILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b2
_ZN4PLMD4RMSD9getMethodB5cxx11Ev5
_ZN4PLMD4RMSD20optimalAlignment_FitILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EERSA_RS8_b60
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b112
_ZN4PLMD4RMSD20optimalAlignment_FitILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EERSA_RS8_b150
_ZNK4PLMD4RMSD15simpleAlignmentERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EESB_RS9_SC_b172
_ZN4PLMD12RMSDCoreData18getPositionsCenterEv210
_ZN4PLMD4RMSD16calc_FitElementsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EERS5_RS3_RKb210
_ZN4PLMD4RMSD5clearEv471
_ZN4PLMD4RMSD8calc_RotERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEEb672
_ZNK4PLMD4RMSD20optimalAlignment_RotILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb672
_ZN4PLMD4RMSD18calc_Rot_DRotDRr01ERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_13TensorGenericILj3ELj3EEERSt5arrayISB_IS9_Lm3EELm3EEb1092
_ZNK4PLMD12RMSDCoreData17getDRotationDRr01Ev1092
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb1092
_ZN4PLMD4RMSD3setERKNS_3PDBERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb1108
_ZN4PLMD4RMSD11setDisplaceERKSt6vectorIdSaIdEEb1575
_ZN4PLMD4RMSD3setERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb1575
_ZN4PLMD4RMSD8setAlignERKSt6vectorIdSaIdEEbb1575
_ZN4PLMD12RMSDCoreData37getRotationMatrixReferenceToPositionsEv1764
_ZN4PLMD12RMSDCoreData20getCenteredReferenceEv4985
_ZN4PLMD12RMSDCoreData30getAlignedPositionsToReferenceEv4985
_ZNK4PLMD4RMSD16calc_PCAelementsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EES8_S8_S8_RKb4985
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb4985
_ZN4PLMD12RMSDCoreData20getCenteredPositionsEv5195
_ZN4PLMD12RMSDCoreData22getDRotationDPositionsEb5195
_ZN4PLMD12RMSDCoreData37getRotationMatrixPositionsToReferenceEv5195
_ZN4PLMD12RMSDCoreData10doCoreCalcEbbb6960
_ZN4PLMD12RMSDCoreData28doCoreCalcWithCloseStructureEbbRKNS_13TensorGenericILj3ELj3EEES4_RSt5arrayIS5_IS2_Lm3EELm3EE45192
_ZN4PLMD4RMSD12getReferenceEv45192
_ZN4PLMD4RMSD27calculateWithCloseStructureERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RKNS_13TensorGenericILj3ELj3EEESC_RSt5arrayISD_ISA_Lm3EELm3EEb45192
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb45192
_ZN4PLMD4RMSD7setTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE46767
_ZN4PLMD4RMSD12setReferenceERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE46783
_ZN4PLMD4RMSDC2Ev46809
_ZN4PLMD12RMSDCoreData22getDDistanceDPositionsEv50850
_ZN4PLMD12RMSDCoreData11getDistanceEb52152
_ZNK4PLMD4RMSD16optimalAlignmentILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b192638
_ZNK4PLMD4RMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_b332887
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b356282
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.cpp.func.html b/coverage/tools/RMSD.cpp.func.html new file mode 100644 index 000000000000..643e6da5f105 --- /dev/null +++ b/coverage/tools/RMSD.cpp.func.html @@ -0,0 +1,393 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:54073573.5 %
Date:2024-02-22 21:58:45Functions:428052.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12RMSDCoreData10doCoreCalcEbbb6960
_ZN4PLMD12RMSDCoreData11getDistanceEb52152
_ZN4PLMD12RMSDCoreData18getPositionsCenterEv210
_ZN4PLMD12RMSDCoreData18getReferenceCenterEv0
_ZN4PLMD12RMSDCoreData20getCenteredPositionsEv5195
_ZN4PLMD12RMSDCoreData20getCenteredReferenceEv4985
_ZN4PLMD12RMSDCoreData22getDDistanceDPositionsEv50850
_ZN4PLMD12RMSDCoreData22getDDistanceDReferenceEv1
_ZN4PLMD12RMSDCoreData22getDRotationDPositionsEb5195
_ZN4PLMD12RMSDCoreData22getDRotationDReferenceEb0
_ZN4PLMD12RMSDCoreData26getDDistanceDReferenceSOMAEv0
_ZN4PLMD12RMSDCoreData28doCoreCalcWithCloseStructureEbbRKNS_13TensorGenericILj3ELj3EEES4_RSt5arrayIS5_IS2_Lm3EELm3EE45192
_ZN4PLMD12RMSDCoreData30getAlignedPositionsToReferenceEv4985
_ZN4PLMD12RMSDCoreData30getAlignedReferenceToPositionsEv0
_ZN4PLMD12RMSDCoreData37getRotationMatrixPositionsToReferenceEv5195
_ZN4PLMD12RMSDCoreData37getRotationMatrixReferenceToPositionsEv1764
_ZN4PLMD4RMSD11getDisplaceEv0
_ZN4PLMD4RMSD11setDisplaceERKSt6vectorIdSaIdEEb1575
_ZN4PLMD4RMSD12getReferenceEv45192
_ZN4PLMD4RMSD12setReferenceERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EE46783
_ZN4PLMD4RMSD14calc_DDistDRefERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_S8_b1
_ZN4PLMD4RMSD16calc_FitElementsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EERS5_RS3_RKb210
_ZN4PLMD4RMSD18calc_Rot_DRotDRr01ERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERNS_13TensorGenericILj3ELj3EEERSt5arrayISB_IS9_Lm3EELm3EEb1092
_ZN4PLMD4RMSD20optimalAlignment_FitILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EERSA_RS8_b0
_ZN4PLMD4RMSD20optimalAlignment_FitILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EERSA_RS8_b0
_ZN4PLMD4RMSD20optimalAlignment_FitILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EERSA_RS8_b60
_ZN4PLMD4RMSD20optimalAlignment_FitILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EERSA_RS8_b150
_ZN4PLMD4RMSD27calc_DDistDRef_Rot_DRotDPosERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_S8_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EEb0
_ZN4PLMD4RMSD27calculateWithCloseStructureERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RKNS_13TensorGenericILj3ELj3EEESC_RSt5arrayISD_ISA_Lm3EELm3EEb45192
_ZN4PLMD4RMSD36calc_DDistDRef_Rot_DRotDPos_DRotDRefERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_S8_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EESE_b0
_ZN4PLMD4RMSD3setERKNS_3PDBERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb1108
_ZN4PLMD4RMSD3setERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb1575
_ZN4PLMD4RMSD5clearEv471
_ZN4PLMD4RMSD7setTypeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE46767
_ZN4PLMD4RMSD8calc_RotERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEEb672
_ZN4PLMD4RMSD8getAlignEv0
_ZN4PLMD4RMSD8setAlignERKSt6vectorIdSaIdEEbb1575
_ZN4PLMD4RMSD9calc_SOMAERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_S8_b0
_ZN4PLMD4RMSD9getMethodB5cxx11Ev5
_ZN4PLMD4RMSDC2Ev46809
_ZNK4PLMD12RMSDCoreData17getDRotationDRr01Ev1092
_ZNK4PLMD4RMSD15simpleAlignmentERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EESB_RS9_SC_b172
_ZNK4PLMD4RMSD16calc_PCAelementsERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixIS5_EES8_S8_S8_RKb4985
_ZNK4PLMD4RMSD16optimalAlignmentILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b2
_ZNK4PLMD4RMSD16optimalAlignmentILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b192638
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b112
_ZNK4PLMD4RMSD16optimalAlignmentILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_b356282
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD20optimalAlignment_PCAILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_SD_RNS_13TensorGenericILj3ELj3EEESD_RNS_6MatrixISA_EEb4985
_ZNK4PLMD4RMSD20optimalAlignment_RotILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb0
_ZNK4PLMD4RMSD20optimalAlignment_RotILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb0
_ZNK4PLMD4RMSD20optimalAlignment_RotILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb0
_ZNK4PLMD4RMSD20optimalAlignment_RotILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RNS_13TensorGenericILj3ELj3EEEb672
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD21optimalAlignment_SOMAILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b1
_ZNK4PLMD4RMSD26optimalAlignment_DDistDRefILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_b0
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb0
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb0
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb0
_ZNK4PLMD4RMSD30optimalAlignment_Rot_DRotDRr01ILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RNS_13TensorGenericILj3ELj3EEERSt5arrayISG_ISE_Lm3EELm3EEb1092
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb0
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb0
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb0
_ZNK4PLMD4RMSD34optimalAlignmentWithCloseStructureILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_RKNS_13TensorGenericILj3ELj3EEESH_RSt5arrayISI_ISF_Lm3EELm3EEb45192
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD39optimalAlignment_DDistDRef_Rot_DRotDPosILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EEb0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb0ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb0ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb1ELb0EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZNK4PLMD4RMSD48optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRefILb1ELb1EEEdRKSt6vectorIdSaIdEES6_RKS2_INS_13VectorGenericILj3EEESaIS8_EESC_RSA_SD_RNS_13TensorGenericILj3ELj3EEERNS_6MatrixISA_EESJ_b0
_ZNK4PLMD4RMSD9calculateERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERS5_b332887
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.cpp.gcov.html b/coverage/tools/RMSD.cpp.gcov.html new file mode 100644 index 000000000000..de1143bd3695 --- /dev/null +++ b/coverage/tools/RMSD.cpp.gcov.html @@ -0,0 +1,1549 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:54073573.5 %
Date:2024-02-22 21:58:45Functions:428052.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "RMSD.h"
+      23             : #include "PDB.h"
+      24             : #include "Log.h"
+      25             : #include "Exception.h"
+      26             : #include <cmath>
+      27             : #include <iostream>
+      28             : #include "Tools.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32       46809 : RMSD::RMSD() : alignmentMethod(SIMPLE),reference_center_is_calculated(false),reference_center_is_removed(false),positions_center_is_calculated(false),positions_center_is_removed(false) {}
+      33             : 
+      34             : ///
+      35             : /// general method to set all the rmsd property at once by using a pdb where occupancy column sets the weights for the atoms involved in the
+      36             : /// alignment and beta sets the weight that are used for calculating the displacement.
+      37             : ///
+      38        1108 : void RMSD::set(const PDB&pdb, const std::string & mytype, bool remove_center, bool normalize_weights ) {
+      39             : 
+      40        1108 :   set(pdb.getOccupancy(),pdb.getBeta(),pdb.getPositions(),mytype,remove_center,normalize_weights);
+      41             : 
+      42        1108 : }
+      43        1575 : void RMSD::set(const std::vector<double> & align, const std::vector<double> & displace, const std::vector<Vector> & reference, const std::string & mytype, bool remove_center, bool normalize_weights ) {
+      44             : 
+      45        1575 :   setReference(reference); // this by default remove the com and assumes uniform weights
+      46        1575 :   setAlign(align, normalize_weights, remove_center); // this recalculates the com with weights. If remove_center=false then it restore the center back
+      47        1575 :   setDisplace(displace, normalize_weights);  // this is does not affect any calculation of the weights
+      48        1575 :   setType(mytype);
+      49             : 
+      50        1575 : }
+      51             : 
+      52       46767 : void RMSD::setType(const std::string & mytype) {
+      53             : 
+      54       46767 :   alignmentMethod=SIMPLE; // initialize with the simplest case: no rotation
+      55       46767 :   if (mytype=="SIMPLE") {
+      56           0 :     alignmentMethod=SIMPLE;
+      57             :   }
+      58       46767 :   else if (mytype=="OPTIMAL") {
+      59       46767 :     alignmentMethod=OPTIMAL;
+      60             :   }
+      61           0 :   else if (mytype=="OPTIMAL-FAST") {
+      62           0 :     alignmentMethod=OPTIMAL_FAST;
+      63             :   }
+      64           0 :   else plumed_merror("unknown RMSD type" + mytype);
+      65             : 
+      66       46767 : }
+      67             : 
+      68         471 : void RMSD::clear() {
+      69             :   reference.clear();
+      70         471 :   reference_center.zero();
+      71         471 :   reference_center_is_calculated=false;
+      72         471 :   reference_center_is_removed=false;
+      73             :   align.clear();
+      74             :   displace.clear();
+      75         471 :   positions_center.zero();
+      76         471 :   positions_center_is_calculated=false;
+      77         471 :   positions_center_is_removed=false;
+      78         471 : }
+      79             : 
+      80           5 : std::string RMSD::getMethod() {
+      81             :   std::string mystring;
+      82           5 :   switch(alignmentMethod) {
+      83           0 :   case SIMPLE: mystring.assign("SIMPLE"); break;
+      84           5 :   case OPTIMAL: mystring.assign("OPTIMAL"); break;
+      85           0 :   case OPTIMAL_FAST: mystring.assign("OPTIMAL-FAST"); break;
+      86             :   }
+      87           5 :   return mystring;
+      88             : }
+      89             : ///
+      90             : /// this calculates the center of mass for the reference and removes it from the reference itself
+      91             : /// considering uniform weights for alignment
+      92             : ///
+      93       46783 : void RMSD::setReference(const std::vector<Vector> & reference) {
+      94       46783 :   unsigned n=reference.size();
+      95       46783 :   this->reference=reference;
+      96       46783 :   plumed_massert(align.empty(),"you should first clear() an RMSD object, then set a new reference");
+      97       46783 :   plumed_massert(displace.empty(),"you should first clear() an RMSD object, then set a new reference");
+      98       46783 :   align.resize(n,1.0/n);
+      99       46783 :   displace.resize(n,1.0/n);
+     100      673845 :   for(unsigned i=0; i<n; i++) reference_center+=this->reference[i]*align[i];
+     101             :   #pragma omp simd
+     102      627062 :   for(unsigned i=0; i<n; i++) this->reference[i]-=reference_center;
+     103       46783 :   reference_center_is_calculated=true;
+     104       46783 :   reference_center_is_removed=true;
+     105       46783 : }
+     106       45192 : std::vector<Vector> RMSD::getReference() {
+     107       45192 :   return reference;
+     108             : }
+     109             : ///
+     110             : /// the alignment weights are here normalized to 1 and  the center of the reference is removed accordingly
+     111             : ///
+     112        1575 : void RMSD::setAlign(const std::vector<double> & align, bool normalize_weights, bool remove_center) {
+     113        1575 :   unsigned n=reference.size();
+     114        1575 :   plumed_massert(this->align.size()==align.size(),"mismatch in dimension of align/displace arrays");
+     115        1575 :   this->align=align;
+     116        1575 :   if(normalize_weights) {
+     117             :     double w=0.0;
+     118        3140 :     #pragma omp simd reduction(+:w)
+     119       39333 :     for(unsigned i=0; i<n; i++) w+=this->align[i];
+     120        1570 :     if(w>epsilon) {
+     121        1570 :       double inv=1.0/w;
+     122             :       #pragma omp simd
+     123       39333 :       for(unsigned i=0; i<n; i++) this->align[i]*=inv;
+     124             :     } else {
+     125           0 :       double inv=1.0/n;
+     126             :       #pragma omp simd
+     127           0 :       for(unsigned i=0; i<n; i++) this->align[i]=inv;
+     128             :     }
+     129             :   }
+     130             :   // recalculate the center anyway
+     131             :   // just remove the center if that is asked
+     132             :   // if the center was removed before, then add it and store the new one
+     133        1575 :   if(reference_center_is_removed) {
+     134        1575 :     plumed_massert(reference_center_is_calculated," seems that the reference center has been removed but not calculated and stored!");
+     135        1575 :     addCenter(reference,reference_center);
+     136             :   }
+     137        1575 :   reference_center=calculateCenter(reference,this->align);
+     138        1575 :   reference_center_is_calculated=true;
+     139        1575 :   if(remove_center) {
+     140        1570 :     removeCenter(reference,reference_center);
+     141        1570 :     reference_center_is_removed=true;
+     142             :   } else {
+     143           5 :     reference_center_is_removed=false;
+     144             :   }
+     145        1575 : }
+     146           0 : std::vector<double> RMSD::getAlign() {
+     147           0 :   return align;
+     148             : }
+     149             : ///
+     150             : /// here the weigth for normalized weighths are normalized and set
+     151             : ///
+     152        1575 : void RMSD::setDisplace(const std::vector<double> & displace, bool normalize_weights) {
+     153        1575 :   unsigned n=reference.size();
+     154        1575 :   plumed_massert(this->displace.size()==displace.size(),"mismatch in dimension of align/displace arrays");
+     155        1575 :   this->displace=displace;
+     156        1575 :   if(normalize_weights) {
+     157             :     double w=0.0;
+     158        3140 :     #pragma omp simd reduction(+:w)
+     159       39333 :     for(unsigned i=0; i<n; i++) w+=this->displace[i];
+     160        1570 :     if(w>epsilon) {
+     161        1570 :       double inv=1.0/w;
+     162             :       #pragma omp simd
+     163       39333 :       for(unsigned i=0; i<n; i++) this->displace[i]*=inv;
+     164             :     } else {
+     165           0 :       double inv=1.0/n;
+     166             :       #pragma omp simd
+     167           0 :       for(unsigned i=0; i<n; i++) this->displace[i]=inv;
+     168             :     }
+     169             :   }
+     170        1575 : }
+     171           0 : std::vector<double> RMSD::getDisplace() {
+     172           0 :   return displace;
+     173             : }
+     174             : ///
+     175             : /// This is the main workhorse for rmsd that decides to use specific optimal alignment versions
+     176             : ///
+     177      332887 : double RMSD::calculate(const std::vector<Vector> & positions,std::vector<Vector> &derivatives, bool squared)const {
+     178             : 
+     179             :   double ret=0.;
+     180             : 
+     181      332887 :   switch(alignmentMethod) {
+     182             :   case SIMPLE : {
+     183             :     //  do a simple alignment without rotation
+     184           0 :     std::vector<Vector> displacement( derivatives.size() );
+     185           0 :     ret=simpleAlignment(align,displace,positions,reference,derivatives,displacement,squared);
+     186             :     break;
+     187           0 :   } case OPTIMAL_FAST : {
+     188             :     // this is calling the fastest option:
+     189           0 :     if(align==displace) ret=optimalAlignment<false,true>(align,displace,positions,reference,derivatives,squared);
+     190           0 :     else                ret=optimalAlignment<false,false>(align,displace,positions,reference,derivatives,squared);
+     191             :     break;
+     192             : 
+     193      332887 :   } case OPTIMAL : {
+     194             :     // this is the fast routine but in the "safe" mode, which gives less numerical error:
+     195      332887 :     if(align==displace) ret=optimalAlignment<true,true>(align,displace,positions,reference,derivatives,squared);
+     196           1 :     else ret=optimalAlignment<true,false>(align,displace,positions,reference,derivatives,squared);
+     197             :     break;
+     198             :   }
+     199             :   }
+     200             : 
+     201      332887 :   return ret;
+     202             : 
+     203             : }
+     204             : 
+     205             : 
+     206             : /// convenience method for calculating the standard derivatives and the derivative of the rmsd respect to the reference position
+     207           1 : double RMSD::calc_DDistDRef( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, std::vector<Vector>& DDistDRef, const bool squared  ) {
+     208             :   double ret=0.;
+     209           1 :   switch(alignmentMethod) {
+     210           0 :   case SIMPLE:
+     211           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     212             :     break;
+     213           0 :   case OPTIMAL_FAST:
+     214           0 :     if(align==displace) ret=optimalAlignment_DDistDRef<false,true>(align,displace,positions,reference,derivatives,DDistDRef, squared);
+     215           0 :     else                ret=optimalAlignment_DDistDRef<false,false>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     216             :     break;
+     217           1 :   case OPTIMAL:
+     218           1 :     if(align==displace) ret=optimalAlignment_DDistDRef<true,true>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     219           1 :     else                ret=optimalAlignment_DDistDRef<true,false>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     220             :     break;
+     221             :   }
+     222           1 :   return ret;
+     223             : 
+     224             : }
+     225             : 
+     226             : /// convenience method for calculating the standard derivatives and the derivative of the rmsd respect to the reference position without the matrix contribution
+     227             : /// as required by SOMA
+     228           0 : double RMSD::calc_SOMA( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, std::vector<Vector>& DDistDRef, const bool squared  ) {
+     229             :   double ret=0.;
+     230           0 :   switch(alignmentMethod) {
+     231           0 :   case SIMPLE:
+     232           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     233             :     break;
+     234           0 :   case OPTIMAL_FAST:
+     235           0 :     if(align==displace) ret=optimalAlignment_SOMA<false,true>(align,displace,positions,reference,derivatives,DDistDRef, squared);
+     236           0 :     else                ret=optimalAlignment_SOMA<false,false>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     237             :     break;
+     238           0 :   case OPTIMAL:
+     239           0 :     if(align==displace) ret=optimalAlignment_SOMA<true,true>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     240           0 :     else                ret=optimalAlignment_SOMA<true,false>(align,displace,positions,reference,derivatives,DDistDRef,squared);
+     241             :     break;
+     242             :   }
+     243           0 :   return ret;
+     244             : 
+     245             : }
+     246             : 
+     247           0 : double RMSD::calc_DDistDRef_Rot_DRotDPos( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, std::vector<Vector>& DDistDRef, Tensor & Rot, Matrix<std::vector<Vector> > &DRotDPos, const bool squared  ) {
+     248             :   double ret=0.;
+     249           0 :   switch(alignmentMethod) {
+     250           0 :   case SIMPLE:
+     251           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     252             :     break;
+     253           0 :   case OPTIMAL_FAST:
+     254           0 :     if(align==displace) ret=optimalAlignment_DDistDRef_Rot_DRotDPos<false,true>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos,  squared);
+     255           0 :     else                ret=optimalAlignment_DDistDRef_Rot_DRotDPos<false,false>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, squared);
+     256             :     break;
+     257           0 :   case OPTIMAL:
+     258           0 :     if(align==displace) ret=optimalAlignment_DDistDRef_Rot_DRotDPos<true,true>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, squared);
+     259           0 :     else                ret=optimalAlignment_DDistDRef_Rot_DRotDPos<true,false>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, squared);
+     260             :     break;
+     261             :   }
+     262           0 :   return ret;
+     263             : }
+     264             : 
+     265           0 : double RMSD::calc_DDistDRef_Rot_DRotDPos_DRotDRef( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, std::vector<Vector>& DDistDRef, Tensor & Rot, Matrix<std::vector<Vector> > &DRotDPos,  Matrix<std::vector<Vector> > &DRotDRef, const bool squared  ) {
+     266             :   double ret=0.;
+     267           0 :   switch(alignmentMethod) {
+     268           0 :   case SIMPLE:
+     269           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     270             :     break;
+     271           0 :   case OPTIMAL_FAST:
+     272           0 :     if(align==displace) ret=optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRef<false,true>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, DRotDRef,   squared);
+     273           0 :     else                ret=optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRef<false,false>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, DRotDRef,  squared);
+     274             :     break;
+     275           0 :   case OPTIMAL:
+     276           0 :     if(align==displace) ret=optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRef<true,true>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, DRotDRef, squared);
+     277           0 :     else                ret=optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRef<true,false>(align,displace,positions,reference,derivatives,DDistDRef, Rot, DRotDPos, DRotDRef, squared);
+     278             :     break;
+     279             :   }
+     280           0 :   return ret;
+     281             : }
+     282             : 
+     283        1092 : double RMSD::calc_Rot_DRotDRr01( const std::vector<Vector>& positions, Tensor & Rotation, std::array<std::array<Tensor,3>,3> & DRotDRr01, const bool squared) {
+     284             :   double ret=0.;
+     285        1092 :   switch(alignmentMethod) {
+     286           0 :   case SIMPLE:
+     287           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     288             :     break;
+     289           0 :   case OPTIMAL_FAST:
+     290           0 :     if(align==displace) ret=optimalAlignment_Rot_DRotDRr01<false,true>(align,displace,positions,reference, Rotation, DRotDRr01,   squared);
+     291           0 :     else                ret=optimalAlignment_Rot_DRotDRr01<false,false>(align,displace,positions,reference, Rotation, DRotDRr01,  squared);
+     292             :     break;
+     293        1092 :   case OPTIMAL:
+     294        1092 :     if(align==displace) ret=optimalAlignment_Rot_DRotDRr01<true,true>(align,displace,positions,reference, Rotation, DRotDRr01, squared);
+     295           0 :     else                ret=optimalAlignment_Rot_DRotDRr01<true,false>(align,displace,positions,reference, Rotation, DRotDRr01, squared);
+     296             :     break;
+     297             :   }
+     298        1092 :   return ret;
+     299             : }
+     300             : 
+     301         672 : double RMSD::calc_Rot( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, Tensor & Rotation, const bool squared) {
+     302             :   double ret=0.;
+     303         672 :   switch(alignmentMethod) {
+     304           0 :   case SIMPLE:
+     305           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     306             :     break;
+     307           0 :   case OPTIMAL_FAST:
+     308           0 :     if(align==displace) ret=optimalAlignment_Rot<false,true>(align,displace,positions,reference,derivatives, Rotation, squared);
+     309           0 :     else                ret=optimalAlignment_Rot<false,false>(align,displace,positions,reference,derivatives, Rotation, squared);
+     310             :     break;
+     311         672 :   case OPTIMAL:
+     312         672 :     if(align==displace) ret=optimalAlignment_Rot<true,true>(align,displace,positions,reference,derivatives, Rotation, squared);
+     313           0 :     else                ret=optimalAlignment_Rot<true,false>(align,displace,positions,reference,derivatives, Rotation, squared);
+     314             :     break;
+     315             :   }
+     316         672 :   return ret;
+     317             : }
+     318             : 
+     319       45192 : double RMSD::calculateWithCloseStructure( const std::vector<Vector>& positions, std::vector<Vector> &derivatives, const Tensor & rotationPosClose, const Tensor & rotationRefClose, std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01, const bool squared) {
+     320             :   double ret=0.;
+     321       45192 :   switch(alignmentMethod) {
+     322           0 :   case SIMPLE:
+     323           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     324             :     break;
+     325           0 :   case OPTIMAL_FAST:
+     326           0 :     if(align==displace) ret=optimalAlignmentWithCloseStructure<false,true>(align,displace,positions,reference,derivatives, rotationPosClose, rotationRefClose, drotationPosCloseDrr01, squared);
+     327           0 :     else                ret=optimalAlignmentWithCloseStructure<false,false>(align,displace,positions,reference,derivatives, rotationPosClose, rotationRefClose, drotationPosCloseDrr01, squared);
+     328             :     break;
+     329       45192 :   case OPTIMAL:
+     330       45192 :     if(align==displace) ret=optimalAlignmentWithCloseStructure<true,true>(align,displace,positions,reference,derivatives, rotationPosClose, rotationRefClose, drotationPosCloseDrr01, squared);
+     331           0 :     else                ret=optimalAlignmentWithCloseStructure<true,false>(align,displace,positions,reference,derivatives, rotationPosClose, rotationRefClose, drotationPosCloseDrr01, squared);
+     332             :     break;
+     333             :   }
+     334       45192 :   return ret;
+     335             : }
+     336             : 
+     337        4985 : double RMSD::calc_PCAelements( const std::vector<Vector>& positions, std::vector<Vector> &DDistDPos, Tensor & Rotation, Matrix<std::vector<Vector> > & DRotDPos,std::vector<Vector>  & alignedpositions, std::vector<Vector> & centeredpositions, std::vector<Vector> &centeredreference, const bool& squared  ) const {
+     338             :   double ret=0.;
+     339        4985 :   switch(alignmentMethod) {
+     340           0 :   case SIMPLE:
+     341           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     342             :     break;
+     343           0 :   case OPTIMAL_FAST:
+     344           0 :     if(align==displace) ret=optimalAlignment_PCA<false,true>(align,displace,positions,reference, alignedpositions, centeredpositions,centeredreference,Rotation,DDistDPos,DRotDPos,squared);
+     345           0 :     else                ret=optimalAlignment_PCA<false,false>(align,displace,positions,reference, alignedpositions, centeredpositions,centeredreference,Rotation,DDistDPos,DRotDPos,squared);
+     346             :     break;
+     347        4985 :   case OPTIMAL:
+     348        4985 :     if(align==displace) ret=optimalAlignment_PCA<true,true>(align,displace,positions,reference, alignedpositions, centeredpositions,centeredreference,Rotation,DDistDPos,DRotDPos,squared);
+     349           0 :     else                ret=optimalAlignment_PCA<true,false>(align,displace,positions,reference, alignedpositions, centeredpositions,centeredreference,Rotation,DDistDPos,DRotDPos,squared);
+     350             :     break;
+     351             :   }
+     352        4985 :   return ret;
+     353             : }
+     354             : 
+     355             : 
+     356         210 : double RMSD::calc_FitElements( const std::vector<Vector>& positions, Tensor & Rotation, Matrix<std::vector<Vector> > & DRotDPos, std::vector<Vector> & centeredpositions, Vector &center_positions, const bool& squared  ) {
+     357             :   double ret=0.;
+     358         210 :   switch(alignmentMethod) {
+     359           0 :   case SIMPLE:
+     360           0 :     plumed_merror("derivative of the refreence frame not implemented for SIMPLE alignmentMethod \n");
+     361             :     break;
+     362           0 :   case OPTIMAL_FAST:
+     363           0 :     if(align==displace)ret=optimalAlignment_Fit<false,true>(align,displace,positions,reference, Rotation,DRotDPos,centeredpositions,center_positions,squared);
+     364           0 :     else               ret=optimalAlignment_Fit<false,false>(align,displace,positions,reference, Rotation,DRotDPos,centeredpositions,center_positions,squared);
+     365             :     break;
+     366         210 :   case OPTIMAL:
+     367         210 :     if(align==displace)ret=optimalAlignment_Fit<true,true>(align,displace,positions,reference,Rotation,DRotDPos,centeredpositions,center_positions,squared);
+     368          60 :     else               ret=optimalAlignment_Fit<true,false>(align,displace,positions,reference,Rotation,DRotDPos,centeredpositions,center_positions,squared);
+     369             :     break;
+     370             :   }
+     371         210 :   return ret;
+     372             : }
+     373             : 
+     374             : 
+     375             : 
+     376             : 
+     377             : 
+     378             : 
+     379         172 : double RMSD::simpleAlignment(const  std::vector<double>  & align,
+     380             :                              const  std::vector<double>  & displace,
+     381             :                              const std::vector<Vector> & positions,
+     382             :                              const std::vector<Vector> & reference,
+     383             :                              std::vector<Vector>  & derivatives,
+     384             :                              std::vector<Vector>  & displacement,
+     385             :                              bool squared)const {
+     386             : 
+     387             :   double dist(0);
+     388         172 :   unsigned n=reference.size();
+     389             : 
+     390         172 :   Vector apositions;
+     391         172 :   Vector areference;
+     392         172 :   Vector dpositions;
+     393         172 :   Vector dreference;
+     394             : 
+     395        3997 :   for(unsigned i=0; i<n; i++) {
+     396        3825 :     double aw=align[i];
+     397        3825 :     double dw=displace[i];
+     398        3825 :     apositions+=positions[i]*aw;
+     399        3825 :     areference+=reference[i]*aw;
+     400        3825 :     dpositions+=positions[i]*dw;
+     401        3825 :     dreference+=reference[i]*dw;
+     402             :   }
+     403             : 
+     404         172 :   Vector shift=((apositions-areference)-(dpositions-dreference));
+     405        3997 :   for(unsigned i=0; i<n; i++) {
+     406        3825 :     displacement[i]=(positions[i]-apositions)-(reference[i]-areference);
+     407        3825 :     dist+=displace[i]*displacement[i].modulo2();
+     408        3825 :     derivatives[i]=2*(displace[i]*displacement[i]+align[i]*shift);
+     409             :   }
+     410             : 
+     411         172 :   if(!squared) {
+     412             :     // sqrt
+     413         118 :     dist=std::sqrt(dist);
+     414             :     ///// sqrt on derivatives
+     415        3637 :     for(unsigned i=0; i<n; i++) {derivatives[i]*=(0.5/dist);}
+     416             :   }
+     417         172 :   return dist;
+     418             : }
+     419             : 
+     420             : // this below enable the standard case for rmsd where the rmsd is calculated and the derivative of rmsd respect to positions is retrieved
+     421             : // additionally this assumes that the com of the reference is already subtracted.
+     422             : #define OLDRMSD
+     423             : #ifdef OLDRMSD
+     424             : // notice that in the current implementation the safe argument only makes sense for
+     425             : // align==displace
+     426             : template <bool safe,bool alEqDis>
+     427      549034 : double RMSD::optimalAlignment(const  std::vector<double>  & align,
+     428             :                               const  std::vector<double>  & displace,
+     429             :                               const std::vector<Vector> & positions,
+     430             :                               const std::vector<Vector> & reference,
+     431             :                               std::vector<Vector>  & derivatives, bool squared)const {
+     432      549034 :   const unsigned n=reference.size();
+     433             : // This is the trace of positions*positions + reference*reference
+     434             :   double rr00(0);
+     435             :   double rr11(0);
+     436             : // This is positions*reference
+     437      549034 :   Tensor rr01;
+     438             : 
+     439      549034 :   derivatives.resize(n);
+     440             : 
+     441      549034 :   Vector cpositions;
+     442             : 
+     443             : // first expensive loop: compute centers
+     444    22365073 :   for(unsigned iat=0; iat<n; iat++) {
+     445    21816039 :     double w=align[iat];
+     446    21816039 :     cpositions+=positions[iat]*w;
+     447             :   }
+     448             : 
+     449             : // second expensive loop: compute second moments wrt centers
+     450    22365073 :   for(unsigned iat=0; iat<n; iat++) {
+     451    21816039 :     double w=align[iat];
+     452    21816039 :     rr00+=dotProduct(positions[iat]-cpositions,positions[iat]-cpositions)*w;
+     453    21813863 :     rr11+=dotProduct(reference[iat],reference[iat])*w;
+     454    21816039 :     rr01+=Tensor(positions[iat]-cpositions,reference[iat])*w;
+     455             :   }
+     456             : 
+     457      549034 :   Tensor4d m;
+     458             : 
+     459      549034 :   m[0][0]=2.0*(-rr01[0][0]-rr01[1][1]-rr01[2][2]);
+     460      549034 :   m[1][1]=2.0*(-rr01[0][0]+rr01[1][1]+rr01[2][2]);
+     461      549034 :   m[2][2]=2.0*(+rr01[0][0]-rr01[1][1]+rr01[2][2]);
+     462      549034 :   m[3][3]=2.0*(+rr01[0][0]+rr01[1][1]-rr01[2][2]);
+     463      549034 :   m[0][1]=2.0*(-rr01[1][2]+rr01[2][1]);
+     464      549034 :   m[0][2]=2.0*(+rr01[0][2]-rr01[2][0]);
+     465      549034 :   m[0][3]=2.0*(-rr01[0][1]+rr01[1][0]);
+     466      549034 :   m[1][2]=2.0*(-rr01[0][1]-rr01[1][0]);
+     467      549034 :   m[1][3]=2.0*(-rr01[0][2]-rr01[2][0]);
+     468      549034 :   m[2][3]=2.0*(-rr01[1][2]-rr01[2][1]);
+     469      549034 :   m[1][0] = m[0][1];
+     470      549034 :   m[2][0] = m[0][2];
+     471      549034 :   m[2][1] = m[1][2];
+     472      549034 :   m[3][0] = m[0][3];
+     473      549034 :   m[3][1] = m[1][3];
+     474      549034 :   m[3][2] = m[2][3];
+     475             : 
+     476    11529714 :   Tensor dm_drr01[4][4];
+     477             :   if(!alEqDis) {
+     478         114 :     dm_drr01[0][0] = 2.0*Tensor(-1.0, 0.0, 0.0,  0.0,-1.0, 0.0,  0.0, 0.0,-1.0);
+     479         114 :     dm_drr01[1][1] = 2.0*Tensor(-1.0, 0.0, 0.0,  0.0,+1.0, 0.0,  0.0, 0.0,+1.0);
+     480         114 :     dm_drr01[2][2] = 2.0*Tensor(+1.0, 0.0, 0.0,  0.0,-1.0, 0.0,  0.0, 0.0,+1.0);
+     481         114 :     dm_drr01[3][3] = 2.0*Tensor(+1.0, 0.0, 0.0,  0.0,+1.0, 0.0,  0.0, 0.0,-1.0);
+     482         114 :     dm_drr01[0][1] = 2.0*Tensor( 0.0, 0.0, 0.0,  0.0, 0.0,-1.0,  0.0,+1.0, 0.0);
+     483         114 :     dm_drr01[0][2] = 2.0*Tensor( 0.0, 0.0,+1.0,  0.0, 0.0, 0.0, -1.0, 0.0, 0.0);
+     484         114 :     dm_drr01[0][3] = 2.0*Tensor( 0.0,-1.0, 0.0, +1.0, 0.0, 0.0,  0.0, 0.0, 0.0);
+     485         114 :     dm_drr01[1][2] = 2.0*Tensor( 0.0,-1.0, 0.0, -1.0, 0.0, 0.0,  0.0, 0.0, 0.0);
+     486         114 :     dm_drr01[1][3] = 2.0*Tensor( 0.0, 0.0,-1.0,  0.0, 0.0, 0.0, -1.0, 0.0, 0.0);
+     487         114 :     dm_drr01[2][3] = 2.0*Tensor( 0.0, 0.0, 0.0,  0.0, 0.0,-1.0,  0.0,-1.0, 0.0);
+     488         114 :     dm_drr01[1][0] = dm_drr01[0][1];
+     489         114 :     dm_drr01[2][0] = dm_drr01[0][2];
+     490         114 :     dm_drr01[2][1] = dm_drr01[1][2];
+     491         114 :     dm_drr01[3][0] = dm_drr01[0][3];
+     492         114 :     dm_drr01[3][1] = dm_drr01[1][3];
+     493         114 :     dm_drr01[3][2] = dm_drr01[2][3];
+     494             :   }
+     495             : 
+     496             :   double dist=0.0;
+     497      549034 :   Vector4d q;
+     498             : 
+     499     2745170 :   Tensor dq_drr01[4];
+     500             :   if(!alEqDis) {
+     501         114 :     Vector4d eigenvals;
+     502         114 :     Tensor4d eigenvecs;
+     503         114 :     diagMatSym(m, eigenvals, eigenvecs );
+     504             :     dist=eigenvals[0]+rr00+rr11;
+     505         114 :     q=Vector4d(eigenvecs[0][0],eigenvecs[0][1],eigenvecs[0][2],eigenvecs[0][3]);
+     506             :     double dq_dm[4][4][4];
+     507        9690 :     for(unsigned i=0; i<4; i++) for(unsigned j=0; j<4; j++) for(unsigned k=0; k<4; k++) {
+     508             :           double tmp=0.0;
+     509             : // perturbation theory for matrix m
+     510       29184 :           for(unsigned l=1; l<4; l++) tmp+=eigenvecs[l][j]*eigenvecs[l][i]/(eigenvals[0]-eigenvals[l])*eigenvecs[0][k];
+     511        7296 :           dq_dm[i][j][k]=tmp;
+     512             :         }
+     513             : // propagation to _drr01
+     514         570 :     for(unsigned i=0; i<4; i++) {
+     515         456 :       Tensor tmp;
+     516        9576 :       for(unsigned j=0; j<4; j++) for(unsigned k=0; k<4; k++) {
+     517        7296 :           tmp+=dq_dm[i][j][k]*dm_drr01[j][k];
+     518             :         }
+     519         456 :       dq_drr01[i]=tmp;
+     520             :     }
+     521             :   } else {
+     522      548920 :     VectorGeneric<1> eigenvals;
+     523      548920 :     TensorGeneric<1,4> eigenvecs;
+     524      548920 :     diagMatSym(m, eigenvals, eigenvecs );
+     525      548920 :     dist=eigenvals[0]+rr00+rr11;
+     526      548920 :     q=Vector4d(eigenvecs[0][0],eigenvecs[0][1],eigenvecs[0][2],eigenvecs[0][3]);
+     527             :   }
+     528             : 
+     529             : 
+     530             : // This is the rotation matrix that brings reference to positions
+     531             : // i.e. matmul(rotation,reference[iat])+shift is fitted to positions[iat]
+     532             : 
+     533      549034 :   Tensor rotation;
+     534      549034 :   rotation[0][0]=q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3];
+     535      549034 :   rotation[1][1]=q[0]*q[0]-q[1]*q[1]+q[2]*q[2]-q[3]*q[3];
+     536      549034 :   rotation[2][2]=q[0]*q[0]-q[1]*q[1]-q[2]*q[2]+q[3]*q[3];
+     537      549034 :   rotation[0][1]=2*(+q[0]*q[3]+q[1]*q[2]);
+     538      549034 :   rotation[0][2]=2*(-q[0]*q[2]+q[1]*q[3]);
+     539      549034 :   rotation[1][2]=2*(+q[0]*q[1]+q[2]*q[3]);
+     540      549034 :   rotation[1][0]=2*(-q[0]*q[3]+q[1]*q[2]);
+     541      549034 :   rotation[2][0]=2*(+q[0]*q[2]+q[1]*q[3]);
+     542      549034 :   rotation[2][1]=2*(-q[0]*q[1]+q[2]*q[3]);
+     543             : 
+     544             : 
+     545      549034 :   std::array<std::array<Tensor,3>,3> drotation_drr01;
+     546             :   if(!alEqDis) {
+     547         114 :     drotation_drr01[0][0]=2*q[0]*dq_drr01[0]+2*q[1]*dq_drr01[1]-2*q[2]*dq_drr01[2]-2*q[3]*dq_drr01[3];
+     548         114 :     drotation_drr01[1][1]=2*q[0]*dq_drr01[0]-2*q[1]*dq_drr01[1]+2*q[2]*dq_drr01[2]-2*q[3]*dq_drr01[3];
+     549         114 :     drotation_drr01[2][2]=2*q[0]*dq_drr01[0]-2*q[1]*dq_drr01[1]-2*q[2]*dq_drr01[2]+2*q[3]*dq_drr01[3];
+     550         114 :     drotation_drr01[0][1]=2*(+(q[0]*dq_drr01[3]+dq_drr01[0]*q[3])+(q[1]*dq_drr01[2]+dq_drr01[1]*q[2]));
+     551         114 :     drotation_drr01[0][2]=2*(-(q[0]*dq_drr01[2]+dq_drr01[0]*q[2])+(q[1]*dq_drr01[3]+dq_drr01[1]*q[3]));
+     552         114 :     drotation_drr01[1][2]=2*(+(q[0]*dq_drr01[1]+dq_drr01[0]*q[1])+(q[2]*dq_drr01[3]+dq_drr01[2]*q[3]));
+     553         114 :     drotation_drr01[1][0]=2*(-(q[0]*dq_drr01[3]+dq_drr01[0]*q[3])+(q[1]*dq_drr01[2]+dq_drr01[1]*q[2]));
+     554         114 :     drotation_drr01[2][0]=2*(+(q[0]*dq_drr01[2]+dq_drr01[0]*q[2])+(q[1]*dq_drr01[3]+dq_drr01[1]*q[3]));
+     555         114 :     drotation_drr01[2][1]=2*(-(q[0]*dq_drr01[1]+dq_drr01[0]*q[1])+(q[2]*dq_drr01[3]+dq_drr01[2]*q[3]));
+     556             :   }
+     557             : 
+     558             :   double prefactor=2.0;
+     559             : 
+     560      548920 :   if(!squared && alEqDis) prefactor*=0.5/std::sqrt(dist);
+     561             : 
+     562             : // if "safe", recompute dist here to a better accuracy
+     563             :   if(safe || !alEqDis) dist=0.0;
+     564             : 
+     565             : // If safe is set to "false", MSD is taken from the eigenvalue of the M matrix
+     566             : // If safe is set to "true", MSD is recomputed from the rotational matrix
+     567             : // For some reason, this last approach leads to less numerical noise but adds an overhead
+     568             : 
+     569      549034 :   Tensor ddist_drotation;
+     570      549034 :   Vector ddist_dcpositions;
+     571             : 
+     572             : // third expensive loop: derivatives
+     573    22365073 :   for(unsigned iat=0; iat<n; iat++) {
+     574    21816039 :     Vector d(positions[iat]-cpositions - matmul(rotation,reference[iat]));
+     575             :     if(alEqDis) {
+     576             : // there is no need for derivatives of rotation and shift here as it is by construction zero
+     577             : // (similar to Hellman-Feynman forces)
+     578    21813863 :       derivatives[iat]= prefactor*align[iat]*d;
+     579     4952157 :       if(safe) dist+=align[iat]*modulo2(d);
+     580             :     } else {
+     581             : // the case for align != displace is different, sob:
+     582        2176 :       dist+=displace[iat]*modulo2(d);
+     583             : // these are the derivatives assuming the roto-translation as frozen
+     584        2176 :       derivatives[iat]=2*displace[iat]*d;
+     585             : // here I accumulate derivatives wrt rotation matrix ..
+     586        2176 :       ddist_drotation+=-2*displace[iat]*extProduct(d,reference[iat]);
+     587             : // .. and cpositions
+     588        2176 :       ddist_dcpositions+=-2*displace[iat]*d;
+     589             :     }
+     590             :   }
+     591             : 
+     592             :   if(!alEqDis) {
+     593         114 :     Tensor ddist_drr01;
+     594        1482 :     for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++) ddist_drr01+=ddist_drotation[i][j]*drotation_drr01[i][j];
+     595        2290 :     for(unsigned iat=0; iat<n; iat++) {
+     596             : // this is propagating to positions.
+     597             : // I am implicitly using the derivative of rr01 wrt positions here
+     598        2176 :       derivatives[iat]+=matmul(ddist_drr01,reference[iat])*align[iat];
+     599        2176 :       derivatives[iat]+=ddist_dcpositions*align[iat];
+     600             :     }
+     601             :   }
+     602      549034 :   if(!squared) {
+     603       74171 :     dist=std::sqrt(dist);
+     604             :     if(!alEqDis) {
+     605         114 :       double xx=0.5/dist;
+     606        2290 :       for(unsigned iat=0; iat<n; iat++) derivatives[iat]*=xx;
+     607             :     }
+     608             :   }
+     609             : 
+     610      549034 :   return dist;
+     611             : }
+     612             : #else
+     613             : /// note that this method is intended to be repeatedly invoked
+     614             : /// when the reference does already have the center subtracted
+     615             : /// but the position has not calculated center and not subtracted
+     616             : template <bool safe,bool alEqDis>
+     617             : double RMSD::optimalAlignment(const  std::vector<double>  & align,
+     618             :                               const  std::vector<double>  & displace,
+     619             :                               const std::vector<Vector> & positions,
+     620             :                               const std::vector<Vector> & reference,
+     621             :                               std::vector<Vector>  & derivatives,
+     622             :                               bool squared) const {
+     623             :   //std::cerr<<"setting up the core data \n";
+     624             :   RMSDCoreData cd(align,displace,positions,reference);
+     625             : 
+     626             :   // transfer the settings for the center to let the CoreCalc deal with it
+     627             :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     628             :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     629             :   else {cd.calcPositionsCenter();};
+     630             : 
+     631             :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     632             :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     633             :   else {cd.setReferenceCenter(reference_center);}
+     634             : 
+     635             :   // Perform the diagonalization and all the needed stuff
+     636             :   cd.doCoreCalc(safe,alEqDis);
+     637             :   // make the core calc distance
+     638             :   double dist=cd.getDistance(squared);
+     639             : //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     640             :   derivatives=cd.getDDistanceDPositions();
+     641             :   return dist;
+     642             : }
+     643             : #endif
+     644             : template <bool safe,bool alEqDis>
+     645           1 : double RMSD::optimalAlignment_DDistDRef(const  std::vector<double>  & align,
+     646             :                                         const  std::vector<double>  & displace,
+     647             :                                         const std::vector<Vector> & positions,
+     648             :                                         const std::vector<Vector> & reference,
+     649             :                                         std::vector<Vector>  & derivatives,
+     650             :                                         std::vector<Vector> & ddistdref,
+     651             :                                         bool squared) const {
+     652             :   //initialize the data into the structure
+     653             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     654           1 :   RMSDCoreData cd(align,displace,positions,reference);
+     655             :   // transfer the settings for the center to let the CoreCalc deal with it
+     656             :   // transfer the settings for the center to let the CoreCalc deal with it
+     657           1 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     658           1 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     659           1 :   else {cd.calcPositionsCenter();};
+     660             : 
+     661           1 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     662           1 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     663           1 :   else {cd.setReferenceCenter(reference_center);}
+     664             : 
+     665             :   // Perform the diagonalization and all the needed stuff
+     666           1 :   cd.doCoreCalc(safe,alEqDis);
+     667             :   // make the core calc distance
+     668           1 :   double dist=cd.getDistance(squared);
+     669             : //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     670           1 :   derivatives=cd.getDDistanceDPositions();
+     671           2 :   ddistdref=cd.getDDistanceDReference();
+     672           1 :   return dist;
+     673             : }
+     674             : 
+     675             : template <bool safe,bool alEqDis>
+     676           0 : double RMSD::optimalAlignment_SOMA(const  std::vector<double>  & align,
+     677             :                                    const  std::vector<double>  & displace,
+     678             :                                    const std::vector<Vector> & positions,
+     679             :                                    const std::vector<Vector> & reference,
+     680             :                                    std::vector<Vector>  & derivatives,
+     681             :                                    std::vector<Vector> & ddistdref,
+     682             :                                    bool squared) const {
+     683             :   //initialize the data into the structure
+     684             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     685           0 :   RMSDCoreData cd(align,displace,positions,reference);
+     686             :   // transfer the settings for the center to let the CoreCalc deal with it
+     687             :   // transfer the settings for the center to let the CoreCalc deal with it
+     688           0 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     689           0 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     690           0 :   else {cd.calcPositionsCenter();};
+     691             : 
+     692           0 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     693           0 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     694           0 :   else {cd.setReferenceCenter(reference_center);}
+     695             : 
+     696             :   // Perform the diagonalization and all the needed stuff
+     697           0 :   cd.doCoreCalc(safe,alEqDis);
+     698             :   // make the core calc distance
+     699           0 :   double dist=cd.getDistance(squared);
+     700             : //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     701           0 :   derivatives=cd.getDDistanceDPositions();
+     702           0 :   ddistdref=cd.getDDistanceDReferenceSOMA();
+     703           0 :   return dist;
+     704             : }
+     705             : 
+     706             : 
+     707             : template <bool safe,bool alEqDis>
+     708           0 : double RMSD::optimalAlignment_DDistDRef_Rot_DRotDPos(const  std::vector<double>  & align,
+     709             :     const  std::vector<double>  & displace,
+     710             :     const std::vector<Vector> & positions,
+     711             :     const std::vector<Vector> & reference,
+     712             :     std::vector<Vector>  & derivatives,
+     713             :     std::vector<Vector> & ddistdref,
+     714             :     Tensor & Rotation,
+     715             :     Matrix<std::vector<Vector> > &DRotDPos,
+     716             :     bool squared) const {
+     717             :   //initialize the data into the structure
+     718             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     719           0 :   RMSDCoreData cd(align,displace,positions,reference);
+     720             :   // transfer the settings for the center to let the CoreCalc deal with it
+     721             :   // transfer the settings for the center to let the CoreCalc deal with it
+     722           0 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     723           0 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     724           0 :   else {cd.calcPositionsCenter();};
+     725             : 
+     726           0 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     727           0 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     728           0 :   else {cd.setReferenceCenter(reference_center);}
+     729             : 
+     730             :   // Perform the diagonalization and all the needed stuff
+     731           0 :   cd.doCoreCalc(safe,alEqDis);
+     732             :   // make the core calc distance
+     733           0 :   double dist=cd.getDistance(squared);
+     734             : //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     735           0 :   derivatives=cd.getDDistanceDPositions();
+     736           0 :   ddistdref=cd.getDDistanceDReference();
+     737             :   // get the rotation matrix
+     738           0 :   Rotation=cd.getRotationMatrixReferenceToPositions();
+     739             :   // get its derivative
+     740           0 :   DRotDPos=cd.getDRotationDPositions();
+     741           0 :   return dist;
+     742             : }
+     743             : 
+     744             : template <bool safe,bool alEqDis>
+     745           0 : double RMSD::optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRef(const  std::vector<double>  & align,
+     746             :     const  std::vector<double>  & displace,
+     747             :     const std::vector<Vector> & positions,
+     748             :     const std::vector<Vector> & reference,
+     749             :     std::vector<Vector>  & derivatives,
+     750             :     std::vector<Vector> & ddistdref,
+     751             :     Tensor & Rotation,
+     752             :     Matrix<std::vector<Vector> > &DRotDPos,
+     753             :     Matrix<std::vector<Vector> > &DRotDRef,
+     754             :     bool squared) const {
+     755             :   //initialize the data into the structure
+     756             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     757           0 :   RMSDCoreData cd(align,displace,positions,reference);
+     758             :   // transfer the settings for the center to let the CoreCalc deal with it
+     759             :   // transfer the settings for the center to let the CoreCalc deal with it
+     760           0 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     761           0 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     762           0 :   else {cd.calcPositionsCenter();};
+     763             : 
+     764           0 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     765           0 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     766           0 :   else {cd.setReferenceCenter(reference_center);}
+     767             : 
+     768             :   // Perform the diagonalization and all the needed stuff
+     769           0 :   cd.doCoreCalc(safe,alEqDis);
+     770             :   // make the core calc distance
+     771           0 :   double dist=cd.getDistance(squared);
+     772             : //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     773           0 :   derivatives=cd.getDDistanceDPositions();
+     774           0 :   ddistdref=cd.getDDistanceDReference();
+     775             :   // get the rotation matrix
+     776           0 :   Rotation=cd.getRotationMatrixReferenceToPositions();
+     777             :   // get its derivative
+     778           0 :   DRotDPos=cd.getDRotationDPositions();
+     779           0 :   DRotDRef=cd.getDRotationDReference();
+     780           0 :   return dist;
+     781             : }
+     782             : 
+     783             : template <bool safe,bool alEqDis>
+     784        1092 : double RMSD::optimalAlignment_Rot_DRotDRr01(const  std::vector<double>  & align,
+     785             :     const  std::vector<double>  & displace,
+     786             :     const std::vector<Vector> & positions,
+     787             :     const std::vector<Vector> & reference,
+     788             :     Tensor & Rotation,
+     789             :     std::array<std::array<Tensor,3>,3> & DRotDRr01,
+     790             :     bool squared) const {
+     791             :   //initialize the data into the structure
+     792             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     793        1092 :   RMSDCoreData cd(align,displace,positions,reference);
+     794             :   // transfer the settings for the center to let the CoreCalc deal with it
+     795        1092 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     796        1092 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     797        1092 :   else {cd.calcPositionsCenter();};
+     798             : 
+     799        1092 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     800        1092 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     801        1092 :   else {cd.setReferenceCenter(reference_center);}
+     802             : 
+     803             :   // Perform the diagonalization and all the needed stuff
+     804        1092 :   cd.doCoreCalc(safe,alEqDis);
+     805             :   // make the core calc distance
+     806        1092 :   double dist=cd.getDistance(squared);
+     807             :   // get the rotation matrix
+     808        1092 :   Rotation=cd.getRotationMatrixReferenceToPositions();
+     809             :   //get detivative w.r.t. rr01
+     810        1092 :   DRotDRr01=cd.getDRotationDRr01();
+     811        1092 :   return dist;
+     812             : }
+     813             : 
+     814             : template <bool safe,bool alEqDis>
+     815         672 : double RMSD::optimalAlignment_Rot(const  std::vector<double>  & align,
+     816             :                                   const  std::vector<double>  & displace,
+     817             :                                   const std::vector<Vector> & positions,
+     818             :                                   const std::vector<Vector> & reference,
+     819             :                                   std::vector<Vector>  & derivatives,
+     820             :                                   Tensor & Rotation,
+     821             :                                   bool squared) const {
+     822             :   //initialize the data into the structure
+     823             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     824         672 :   RMSDCoreData cd(align,displace,positions,reference);
+     825             :   // transfer the settings for the center to let the CoreCalc deal with it
+     826         672 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     827         672 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     828         672 :   else {cd.calcPositionsCenter();};
+     829             : 
+     830         672 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     831         672 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     832         672 :   else {cd.setReferenceCenter(reference_center);}
+     833             : 
+     834             :   // Perform the diagonalization and all the needed stuff
+     835         672 :   cd.doCoreCalc(safe,alEqDis);
+     836             :   // make the core calc distance
+     837         672 :   double dist=cd.getDistance(squared);
+     838             :   //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     839         672 :   derivatives=cd.getDDistanceDPositions();
+     840             :   // get the rotation matrix
+     841         672 :   Rotation=cd.getRotationMatrixReferenceToPositions();
+     842         672 :   return dist;
+     843             : }
+     844             : 
+     845             : template <bool safe,bool alEqDis>
+     846       45192 : double RMSD::optimalAlignmentWithCloseStructure(const  std::vector<double>  & align,
+     847             :     const  std::vector<double>  & displace,
+     848             :     const std::vector<Vector> & positions,
+     849             :     const std::vector<Vector> & reference,
+     850             :     std::vector<Vector>  & derivatives,
+     851             :     const Tensor & rotationPosClose,
+     852             :     const Tensor & rotationRefClose,
+     853             :     std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01,
+     854             :     bool squared) const {
+     855             :   //initialize the data into the structure
+     856             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     857       45192 :   RMSDCoreData cd(align,displace,positions,reference);
+     858             :   // transfer the settings for the center to let the CoreCalc deal with it
+     859       45192 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     860       45192 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     861       45192 :   else {cd.calcPositionsCenter();};
+     862             : 
+     863       45192 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     864       45192 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     865       45192 :   else {cd.setReferenceCenter(reference_center);}
+     866             : 
+     867             :   // instead of diagonalization, approximate with saved rotation matrix
+     868       45192 :   cd.doCoreCalcWithCloseStructure(safe,alEqDis, rotationPosClose, rotationRefClose, drotationPosCloseDrr01);
+     869             :   // make the core calc distance
+     870       45192 :   double dist=cd.getDistance(squared);
+     871             :   //  make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     872       90384 :   derivatives=cd.getDDistanceDPositions();
+     873       45192 :   return dist;
+     874             : }
+     875             : 
+     876             : 
+     877             : template <bool safe,bool alEqDis>
+     878        4985 : double RMSD::optimalAlignment_PCA(const  std::vector<double>  & align,
+     879             :                                   const  std::vector<double>  & displace,
+     880             :                                   const std::vector<Vector> & positions,
+     881             :                                   const std::vector<Vector> & reference,
+     882             :                                   std::vector<Vector> & alignedpositions,
+     883             :                                   std::vector<Vector> & centeredpositions,
+     884             :                                   std::vector<Vector> & centeredreference,
+     885             :                                   Tensor & Rotation,
+     886             :                                   std::vector<Vector> & DDistDPos,
+     887             :                                   Matrix<std::vector<Vector> > & DRotDPos,
+     888             :                                   bool squared) const {
+     889             :   //initialize the data into the structure
+     890             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     891        4985 :   RMSDCoreData cd(align,displace,positions,reference);
+     892             :   // transfer the settings for the center to let the CoreCalc deal with it
+     893        4985 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     894        4985 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     895        4985 :   else {cd.calcPositionsCenter();};
+     896             : 
+     897        4985 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     898        4985 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     899        4985 :   else {cd.setReferenceCenter(reference_center);}
+     900             : 
+     901             :   // Perform the diagonalization and all the needed stuff
+     902        4985 :   cd.doCoreCalc(safe,alEqDis);
+     903             :   // make the core calc distance
+     904        4985 :   double dist=cd.getDistance(squared);
+     905             :   // make the derivatives by using pieces calculated in coreCalc (probably the best is just to copy the vector...)
+     906        4985 :   DDistDPos=cd.getDDistanceDPositions();
+     907             :   // get the rotation matrix
+     908        4985 :   Rotation=cd.getRotationMatrixPositionsToReference();
+     909             :   // get its derivative
+     910        4985 :   DRotDPos=cd.getDRotationDPositions(true); // this gives back the inverse
+     911             :   // get aligned positions
+     912        4985 :   alignedpositions=cd.getAlignedPositionsToReference();
+     913             :   // get centered positions
+     914        4985 :   centeredpositions=cd.getCenteredPositions();
+     915             :   // get centered reference
+     916        9970 :   centeredreference=cd.getCenteredReference();
+     917        4985 :   return dist;
+     918             : }
+     919             : 
+     920             : 
+     921             : template <bool safe,bool alEqDis>
+     922         210 : double RMSD::optimalAlignment_Fit(const  std::vector<double>  & align,
+     923             :                                   const  std::vector<double>  & displace,
+     924             :                                   const std::vector<Vector> & positions,
+     925             :                                   const std::vector<Vector> & reference,
+     926             :                                   Tensor & Rotation,
+     927             :                                   Matrix<std::vector<Vector> > & DRotDPos,
+     928             :                                   std::vector<Vector> & centeredpositions,
+     929             :                                   Vector & center_positions,
+     930             :                                   bool squared) {
+     931             :   //initialize the data into the structure
+     932             :   // typically the positions do not have the com neither calculated nor subtracted. This layer takes care of this business
+     933         210 :   RMSDCoreData cd(align,displace,positions,reference);
+     934             :   // transfer the settings for the center to let the CoreCalc deal with it
+     935         210 :   cd.setPositionsCenterIsRemoved(positions_center_is_removed);
+     936         210 :   if(positions_center_is_calculated) {cd.setPositionsCenter(positions_center);}
+     937         210 :   else {cd.calcPositionsCenter();};
+     938             : 
+     939         210 :   cd.setReferenceCenterIsRemoved(reference_center_is_removed);
+     940         210 :   if(!reference_center_is_calculated) {cd.calcReferenceCenter();}
+     941         210 :   else {cd.setReferenceCenter(reference_center);}
+     942             : 
+     943             :   // Perform the diagonalization and all the needed stuff
+     944         210 :   cd.doCoreCalc(safe,alEqDis);
+     945             :   // make the core calc distance
+     946         210 :   double dist=cd.getDistance(squared);
+     947             :   // get the rotation matrix
+     948         210 :   Rotation=cd.getRotationMatrixPositionsToReference();
+     949             :   // get its derivative
+     950         210 :   DRotDPos=cd.getDRotationDPositions(true); // this gives back the inverse
+     951             :   // get centered positions
+     952         210 :   centeredpositions=cd.getCenteredPositions();
+     953             :   // get center
+     954         210 :   center_positions=cd.getPositionsCenter();
+     955         210 :   return dist;
+     956             : }
+     957             : 
+     958             : 
+     959             : 
+     960             : 
+     961             : 
+     962             : 
+     963             : /// This calculates the elements needed by the quaternion to calculate everything that is needed
+     964             : /// additional calls retrieve different components
+     965             : /// note that this considers that the centers of both reference and positions are already setted
+     966             : /// but automatically should properly account for non removed components: if not removed then it
+     967             : /// removes prior to calculation of the alignment
+     968        6960 : void RMSDCoreData::doCoreCalc(bool safe,bool alEqDis, bool only_rotation) {
+     969             : 
+     970        6960 :   retrieve_only_rotation=only_rotation;
+     971        6960 :   const unsigned n=static_cast<unsigned int>(reference.size());
+     972             : 
+     973        6960 :   plumed_massert(creference_is_calculated,"the center of the reference frame must be already provided at this stage");
+     974        6960 :   plumed_massert(cpositions_is_calculated,"the center of the positions frame must be already provided at this stage");
+     975             : 
+     976             : // This is the trace of positions*positions + reference*reference
+     977        6960 :   rr00=0.;
+     978        6960 :   rr11=0.;
+     979             : // This is positions*reference
+     980        6960 :   Tensor rr01;
+     981             : // center of mass managing: must subtract the center from the position or not?
+     982        6960 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+     983        6960 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+     984             : // second expensive loop: compute second moments wrt centers
+     985      588912 :   for(unsigned iat=0; iat<n; iat++) {
+     986      581952 :     double w=align[iat];
+     987      581952 :     rr00+=dotProduct(positions[iat]-cp,positions[iat]-cp)*w;
+     988      581952 :     rr11+=dotProduct(reference[iat]-cr,reference[iat]-cr)*w;
+     989      581952 :     rr01+=Tensor(positions[iat]-cp,reference[iat]-cr)*w;
+     990             :   }
+     991             : 
+     992             : // the quaternion matrix: this is internal
+     993        6960 :   Tensor4d m;
+     994             : 
+     995        6960 :   m[0][0]=2.0*(-rr01[0][0]-rr01[1][1]-rr01[2][2]);
+     996        6960 :   m[1][1]=2.0*(-rr01[0][0]+rr01[1][1]+rr01[2][2]);
+     997        6960 :   m[2][2]=2.0*(+rr01[0][0]-rr01[1][1]+rr01[2][2]);
+     998        6960 :   m[3][3]=2.0*(+rr01[0][0]+rr01[1][1]-rr01[2][2]);
+     999        6960 :   m[0][1]=2.0*(-rr01[1][2]+rr01[2][1]);
+    1000        6960 :   m[0][2]=2.0*(+rr01[0][2]-rr01[2][0]);
+    1001        6960 :   m[0][3]=2.0*(-rr01[0][1]+rr01[1][0]);
+    1002        6960 :   m[1][2]=2.0*(-rr01[0][1]-rr01[1][0]);
+    1003        6960 :   m[1][3]=2.0*(-rr01[0][2]-rr01[2][0]);
+    1004        6960 :   m[2][3]=2.0*(-rr01[1][2]-rr01[2][1]);
+    1005        6960 :   m[1][0] = m[0][1];
+    1006        6960 :   m[2][0] = m[0][2];
+    1007        6960 :   m[2][1] = m[1][2];
+    1008        6960 :   m[3][0] = m[0][3];
+    1009        6960 :   m[3][1] = m[1][3];
+    1010        6960 :   m[3][2] = m[2][3];
+    1011             : 
+    1012             : 
+    1013      146160 :   Tensor dm_drr01[4][4];
+    1014        6960 :   if(!alEqDis or !retrieve_only_rotation) {
+    1015        6960 :     dm_drr01[0][0] = 2.0*Tensor(-1.0, 0.0, 0.0,  0.0,-1.0, 0.0,  0.0, 0.0,-1.0);
+    1016        6960 :     dm_drr01[1][1] = 2.0*Tensor(-1.0, 0.0, 0.0,  0.0,+1.0, 0.0,  0.0, 0.0,+1.0);
+    1017        6960 :     dm_drr01[2][2] = 2.0*Tensor(+1.0, 0.0, 0.0,  0.0,-1.0, 0.0,  0.0, 0.0,+1.0);
+    1018        6960 :     dm_drr01[3][3] = 2.0*Tensor(+1.0, 0.0, 0.0,  0.0,+1.0, 0.0,  0.0, 0.0,-1.0);
+    1019        6960 :     dm_drr01[0][1] = 2.0*Tensor( 0.0, 0.0, 0.0,  0.0, 0.0,-1.0,  0.0,+1.0, 0.0);
+    1020        6960 :     dm_drr01[0][2] = 2.0*Tensor( 0.0, 0.0,+1.0,  0.0, 0.0, 0.0, -1.0, 0.0, 0.0);
+    1021        6960 :     dm_drr01[0][3] = 2.0*Tensor( 0.0,-1.0, 0.0, +1.0, 0.0, 0.0,  0.0, 0.0, 0.0);
+    1022        6960 :     dm_drr01[1][2] = 2.0*Tensor( 0.0,-1.0, 0.0, -1.0, 0.0, 0.0,  0.0, 0.0, 0.0);
+    1023        6960 :     dm_drr01[1][3] = 2.0*Tensor( 0.0, 0.0,-1.0,  0.0, 0.0, 0.0, -1.0, 0.0, 0.0);
+    1024        6960 :     dm_drr01[2][3] = 2.0*Tensor( 0.0, 0.0, 0.0,  0.0, 0.0,-1.0,  0.0,-1.0, 0.0);
+    1025        6960 :     dm_drr01[1][0] = dm_drr01[0][1];
+    1026        6960 :     dm_drr01[2][0] = dm_drr01[0][2];
+    1027        6960 :     dm_drr01[2][1] = dm_drr01[1][2];
+    1028        6960 :     dm_drr01[3][0] = dm_drr01[0][3];
+    1029        6960 :     dm_drr01[3][1] = dm_drr01[1][3];
+    1030        6960 :     dm_drr01[3][2] = dm_drr01[2][3];
+    1031             :   }
+    1032             : 
+    1033             : 
+    1034        6960 :   Vector4d q;
+    1035             : 
+    1036       34800 :   Tensor dq_drr01[4];
+    1037        6960 :   if(!alEqDis or !only_rotation) {
+    1038        6960 :     diagMatSym(m, eigenvals, eigenvecs );
+    1039        6960 :     q=Vector4d(eigenvecs[0][0],eigenvecs[0][1],eigenvecs[0][2],eigenvecs[0][3]);
+    1040             :     double dq_dm[4][4][4];
+    1041      591600 :     for(unsigned i=0; i<4; i++) for(unsigned j=0; j<4; j++) for(unsigned k=0; k<4; k++) {
+    1042             :           double tmp=0.0;
+    1043             : // perturbation theory for matrix m
+    1044     1781760 :           for(unsigned l=1; l<4; l++) tmp+=eigenvecs[l][j]*eigenvecs[l][i]/(eigenvals[0]-eigenvals[l])*eigenvecs[0][k];
+    1045      445440 :           dq_dm[i][j][k]=tmp;
+    1046             :         }
+    1047             : // propagation to _drr01
+    1048       34800 :     for(unsigned i=0; i<4; i++) {
+    1049       27840 :       Tensor tmp;
+    1050      584640 :       for(unsigned j=0; j<4; j++) for(unsigned k=0; k<4; k++) {
+    1051      445440 :           tmp+=dq_dm[i][j][k]*dm_drr01[j][k];
+    1052             :         }
+    1053       27840 :       dq_drr01[i]=tmp;
+    1054             :     }
+    1055             :   } else {
+    1056           0 :     TensorGeneric<1,4> here_eigenvecs;
+    1057           0 :     VectorGeneric<1> here_eigenvals;
+    1058           0 :     diagMatSym(m, here_eigenvals, here_eigenvecs );
+    1059           0 :     for(unsigned i=0; i<4; i++) eigenvecs[0][i]=here_eigenvecs[0][i];
+    1060           0 :     eigenvals[0]=here_eigenvals[0];
+    1061           0 :     q=Vector4d(eigenvecs[0][0],eigenvecs[0][1],eigenvecs[0][2],eigenvecs[0][3]);
+    1062             :   }
+    1063             : 
+    1064             : // This is the rotation matrix that brings reference to positions
+    1065             : // i.e. matmul(rotation,reference[iat])+shift is fitted to positions[iat]
+    1066             : 
+    1067        6960 :   rotation[0][0]=q[0]*q[0]+q[1]*q[1]-q[2]*q[2]-q[3]*q[3];
+    1068        6960 :   rotation[1][1]=q[0]*q[0]-q[1]*q[1]+q[2]*q[2]-q[3]*q[3];
+    1069        6960 :   rotation[2][2]=q[0]*q[0]-q[1]*q[1]-q[2]*q[2]+q[3]*q[3];
+    1070        6960 :   rotation[0][1]=2*(+q[0]*q[3]+q[1]*q[2]);
+    1071        6960 :   rotation[0][2]=2*(-q[0]*q[2]+q[1]*q[3]);
+    1072        6960 :   rotation[1][2]=2*(+q[0]*q[1]+q[2]*q[3]);
+    1073        6960 :   rotation[1][0]=2*(-q[0]*q[3]+q[1]*q[2]);
+    1074        6960 :   rotation[2][0]=2*(+q[0]*q[2]+q[1]*q[3]);
+    1075        6960 :   rotation[2][1]=2*(-q[0]*q[1]+q[2]*q[3]);
+    1076             : 
+    1077             : 
+    1078        6960 :   if(!alEqDis or !only_rotation) {
+    1079        6960 :     drotation_drr01[0][0]=2*q[0]*dq_drr01[0]+2*q[1]*dq_drr01[1]-2*q[2]*dq_drr01[2]-2*q[3]*dq_drr01[3];
+    1080        6960 :     drotation_drr01[1][1]=2*q[0]*dq_drr01[0]-2*q[1]*dq_drr01[1]+2*q[2]*dq_drr01[2]-2*q[3]*dq_drr01[3];
+    1081        6960 :     drotation_drr01[2][2]=2*q[0]*dq_drr01[0]-2*q[1]*dq_drr01[1]-2*q[2]*dq_drr01[2]+2*q[3]*dq_drr01[3];
+    1082        6960 :     drotation_drr01[0][1]=2*(+(q[0]*dq_drr01[3]+dq_drr01[0]*q[3])+(q[1]*dq_drr01[2]+dq_drr01[1]*q[2]));
+    1083        6960 :     drotation_drr01[0][2]=2*(-(q[0]*dq_drr01[2]+dq_drr01[0]*q[2])+(q[1]*dq_drr01[3]+dq_drr01[1]*q[3]));
+    1084        6960 :     drotation_drr01[1][2]=2*(+(q[0]*dq_drr01[1]+dq_drr01[0]*q[1])+(q[2]*dq_drr01[3]+dq_drr01[2]*q[3]));
+    1085        6960 :     drotation_drr01[1][0]=2*(-(q[0]*dq_drr01[3]+dq_drr01[0]*q[3])+(q[1]*dq_drr01[2]+dq_drr01[1]*q[2]));
+    1086        6960 :     drotation_drr01[2][0]=2*(+(q[0]*dq_drr01[2]+dq_drr01[0]*q[2])+(q[1]*dq_drr01[3]+dq_drr01[1]*q[3]));
+    1087        6960 :     drotation_drr01[2][1]=2*(-(q[0]*dq_drr01[1]+dq_drr01[0]*q[1])+(q[2]*dq_drr01[3]+dq_drr01[2]*q[3]));
+    1088             :   }
+    1089             : 
+    1090        6960 :   d.resize(n);
+    1091             : 
+    1092             :   // calculate rotation matrix derivatives and components distances needed for components only when align!=displacement
+    1093        6960 :   if(!alEqDis)ddist_drotation.zero();
+    1094             :   // This pragma leads to incorrect results with INTEL compiler.
+    1095             :   // Failures are seen in rt65-rmsd2, rt-close-structure, rt64-pca, and others.
+    1096             :   // Not really clear why. GB
+    1097             :   // #pragma omp simd
+    1098      588912 :   for(unsigned iat=0; iat<n; iat++) {
+    1099             :     // components differences: this is useful externally
+    1100      581952 :     d[iat]=positions[iat]-cp - matmul(rotation,reference[iat]-cr);
+    1101             :     //cerr<<"D "<<iat<<" "<<d[iat][0]<<" "<<d[iat][1]<<" "<<d[iat][2]<<"\n";
+    1102             :   }
+    1103             :   // ddist_drotation if needed
+    1104        6960 :   if(!alEqDis or !only_rotation) {
+    1105      588912 :     for (unsigned iat=0; iat<n; iat++)
+    1106      581952 :       ddist_drotation+=-2*displace[iat]*extProduct(d[iat],reference[iat]-cr);
+    1107             : 
+    1108        6960 :     ddist_drr01.zero();
+    1109       90480 :     for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++) ddist_drr01+=ddist_drotation[i][j]*drotation_drr01[i][j];
+    1110             :   }
+    1111             :   // transfer this bools to the cd so that this settings will be reflected in the other calls
+    1112        6960 :   this->alEqDis=alEqDis;
+    1113        6960 :   this->safe=safe;
+    1114        6960 :   isInitialized=true;
+    1115             : 
+    1116        6960 : }
+    1117             : /// just retrieve the distance already calculated
+    1118       52152 : double RMSDCoreData::getDistance( bool squared) {
+    1119             : 
+    1120       52152 :   if(!isInitialized)plumed_merror("getDistance cannot calculate the distance without being initialized first by doCoreCalc ");
+    1121             : 
+    1122             :   double localDist=0.0;
+    1123       52152 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1124       52152 :   if(safe || !alEqDis) localDist=0.0;
+    1125             :   else
+    1126           0 :     localDist=eigenvals[0]+rr00+rr11;
+    1127      104304 :   #pragma omp simd reduction(+:localDist)
+    1128             :   for(unsigned iat=0; iat<n; iat++) {
+    1129     1169448 :     if(alEqDis) {
+    1130     1168293 :       if(safe) localDist+=align[iat]*modulo2(d[iat]);
+    1131             :     } else {
+    1132        1155 :       localDist+=displace[iat]*modulo2(d[iat]);
+    1133             :     }
+    1134             :   }
+    1135       52152 :   if(!squared) {
+    1136          85 :     dist=std::sqrt(localDist);
+    1137          85 :     distanceIsMSD=false;
+    1138             :   } else {
+    1139       52067 :     dist=localDist;
+    1140       52067 :     distanceIsMSD=true;
+    1141             :   }
+    1142       52152 :   hasDistance=true;
+    1143       52152 :   return dist;
+    1144             : }
+    1145             : 
+    1146       45192 : void RMSDCoreData::doCoreCalcWithCloseStructure(bool safe,bool alEqDis, const Tensor & rotationPosClose, const Tensor & rotationRefClose, std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01) {
+    1147             : 
+    1148       45192 :   unsigned natoms = reference.size();
+    1149       45192 :   Tensor ddist_drxy;
+    1150       45192 :   ddist_drr01.zero();
+    1151       45192 :   d.resize(natoms);
+    1152             : 
+    1153             :   // center of mass managing: must subtract the center from the position or not?
+    1154       45192 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+    1155       45192 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+    1156             :   //distance = \sum_{n=0}^{N} w_n(x_n-cpos-R_{XY} R_{AY} a_n)^2
+    1157             : 
+    1158       45192 :   Tensor rotation = matmul(rotationPosClose, rotationRefClose);
+    1159             : 
+    1160             :   // This pragma leads to incorrect results with INTEL compiler.
+    1161             :   // Failures are seen in rt65-rmsd2, rt-close-structure, rt64-pca, and others.
+    1162             :   // Not really clear why. GB
+    1163             :   // #pragma omp simd
+    1164      632688 :   for (unsigned iat=0; iat<natoms; iat++) {
+    1165      587496 :     d[iat] = positions[iat] - cp - matmul(rotation, reference[iat]-cr);
+    1166             :   }
+    1167       45192 :   if (!alEqDis) {
+    1168           0 :     for (unsigned iat=0; iat<natoms; iat++) {
+    1169             :       //dist = \sum w_i(x_i - cpos - R_xy * R_ay * a_i)
+    1170           0 :       ddist_drxy += -2*displace[iat]*extProduct(matmul(d[iat], rotationRefClose), reference[iat]-cr);
+    1171             :     }
+    1172           0 :     for(unsigned i=0; i<3; i++)
+    1173           0 :       for(unsigned j=0; j<3; j++)
+    1174           0 :         ddist_drr01+=ddist_drxy[i][j]*drotationPosCloseDrr01[i][j];
+    1175             :   }
+    1176       45192 :   this->alEqDis=alEqDis;
+    1177       45192 :   this->safe=safe;
+    1178       45192 :   isInitialized=true;
+    1179       45192 : }
+    1180             : 
+    1181       50850 : std::vector<Vector> RMSDCoreData::getDDistanceDPositions() {
+    1182             :   std::vector<Vector>  derivatives;
+    1183       50850 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1184       50850 :   Vector ddist_dcpositions;
+    1185       50850 :   derivatives.resize(n);
+    1186             :   double prefactor=1.0;
+    1187       50850 :   if(!distanceIsMSD) prefactor*=0.5/dist;
+    1188       50850 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1189       50850 :   if(!hasDistance)plumed_merror("getDPositionsDerivatives needs to calculate the distance via getDistance first !");
+    1190       50850 :   if(!isInitialized)plumed_merror("getDPositionsDerivatives needs to initialize the coreData first!");
+    1191       50850 :   Vector csum;
+    1192      720102 :   for(unsigned iat=0; iat<n; iat++) {
+    1193      669252 :     if(alEqDis) {
+    1194             : // there is no need for derivatives of rotation and shift here as it is by construction zero
+    1195             : // (similar to Hellman-Feynman forces)
+    1196      668397 :       derivatives[iat]= 2*prefactor*align[iat]*d[iat];
+    1197             :     } else {
+    1198             : // these are the derivatives assuming the roto-translation as frozen
+    1199         855 :       Vector tmp1=2*displace[iat]*d[iat];
+    1200         855 :       derivatives[iat]=tmp1;
+    1201             : // derivative of cpositions
+    1202         855 :       ddist_dcpositions+=-tmp1;
+    1203             :       // these needed for com corrections
+    1204         855 :       Vector tmp2=matmul(ddist_drr01,reference[iat]-creference)*align[iat];
+    1205         855 :       derivatives[iat]+=tmp2;
+    1206         855 :       csum+=tmp2;
+    1207             :     }
+    1208             :   }
+    1209             : 
+    1210       50850 :   if(!alEqDis)
+    1211             :     #pragma omp simd
+    1212         855 :     for(unsigned iat=0; iat<n; iat++) {derivatives[iat]= prefactor*(derivatives[iat]+(ddist_dcpositions-csum)*align[iat]); }
+    1213             : 
+    1214       50850 :   return derivatives;
+    1215             : }
+    1216             : 
+    1217           1 : std::vector<Vector>  RMSDCoreData::getDDistanceDReference() {
+    1218             :   std::vector<Vector>  derivatives;
+    1219           1 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1220           1 :   Vector ddist_dcreference;
+    1221           1 :   derivatives.resize(n);
+    1222             :   double prefactor=1.0;
+    1223           1 :   if(!distanceIsMSD) prefactor*=0.5/dist;
+    1224           1 :   Vector csum;
+    1225             : 
+    1226           1 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1227           1 :   if(!hasDistance)plumed_merror("getDDistanceDReference needs to calculate the distance via getDistance first !");
+    1228           1 :   if(!isInitialized)plumed_merror("getDDistanceDReference to initialize the coreData first!");
+    1229             :   // get the transpose rotation
+    1230           1 :   Tensor t_rotation=rotation.transpose();
+    1231           1 :   Tensor t_ddist_drr01=ddist_drr01.transpose();
+    1232             : 
+    1233             : // third expensive loop: derivatives
+    1234         856 :   for(unsigned iat=0; iat<n; iat++) {
+    1235         855 :     if(alEqDis) {
+    1236             : // there is no need for derivatives of rotation and shift here as it is by construction zero
+    1237             : // (similar to Hellman-Feynman forces)
+    1238             :       //TODO: check this derivative down here
+    1239           0 :       derivatives[iat]= -2*prefactor*align[iat]*matmul(t_rotation,d[iat]);
+    1240             :     } else {
+    1241             : // these are the derivatives assuming the roto-translation as frozen
+    1242         855 :       Vector tmp1=2*displace[iat]*matmul(t_rotation,d[iat]);
+    1243         855 :       derivatives[iat]= -tmp1;
+    1244             : // derivative of cpositions
+    1245         855 :       ddist_dcreference+=tmp1;
+    1246             :       // these below are needed for com correction
+    1247         855 :       Vector tmp2=matmul(t_ddist_drr01,positions[iat]-cpositions)*align[iat];
+    1248         855 :       derivatives[iat]+=tmp2;
+    1249         855 :       csum+=tmp2;
+    1250             :     }
+    1251             :   }
+    1252             : 
+    1253           1 :   if(!alEqDis)
+    1254             :     #pragma omp simd
+    1255         855 :     for(unsigned iat=0; iat<n; iat++) {derivatives[iat]= prefactor*(derivatives[iat]+(ddist_dcreference-csum)*align[iat]);}
+    1256             : 
+    1257           1 :   return derivatives;
+    1258             : }
+    1259             : 
+    1260             : /// this version does not calculate the derivative of rotation matrix as needed for SOMA
+    1261           0 : std::vector<Vector>  RMSDCoreData::getDDistanceDReferenceSOMA() {
+    1262             :   std::vector<Vector>  derivatives;
+    1263           0 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1264           0 :   Vector ddist_dcreference;
+    1265           0 :   derivatives.resize(n);
+    1266             :   double prefactor=1.0;
+    1267           0 :   if(!distanceIsMSD) prefactor*=0.5/dist;
+    1268           0 :   Vector csum,tmp1,tmp2;
+    1269             : 
+    1270           0 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1271           0 :   if(!hasDistance)plumed_merror("getDDistanceDReference needs to calculate the distance via getDistance first !");
+    1272           0 :   if(!isInitialized)plumed_merror("getDDistanceDReference to initialize the coreData first!");
+    1273             :   // get the transpose rotation
+    1274           0 :   Tensor t_rotation=rotation.transpose();
+    1275             : 
+    1276             : // third expensive loop: derivatives
+    1277           0 :   for(unsigned iat=0; iat<n; iat++) {
+    1278           0 :     if(alEqDis) {
+    1279             : // there is no need for derivatives of rotation and shift here as it is by construction zero
+    1280             : // (similar to Hellman-Feynman forces)
+    1281             :       //TODO: check this derivative down here
+    1282           0 :       derivatives[iat]= -2*prefactor*align[iat]*matmul(t_rotation,d[iat]);
+    1283             :     } else {
+    1284             : // these are the derivatives assuming the roto-translation as frozen
+    1285           0 :       tmp1=2*displace[iat]*matmul(t_rotation,d[iat]);
+    1286           0 :       derivatives[iat]= -tmp1;
+    1287             : // derivative of cpositions
+    1288           0 :       ddist_dcreference+=tmp1;
+    1289             :     }
+    1290             :   }
+    1291             : 
+    1292           0 :   if(!alEqDis) for(unsigned iat=0; iat<n; iat++)derivatives[iat]=prefactor*(derivatives[iat]+ddist_dcreference*align[iat]);
+    1293             : 
+    1294           0 :   return derivatives;
+    1295             : }
+    1296             : 
+    1297             : 
+    1298             : 
+    1299             : /*
+    1300             : This below is the derivative of the rotation matrix that aligns the reference onto the positions
+    1301             : respect to positions
+    1302             : note that the this transformation overlap the  reference onto position
+    1303             : if inverseTransform=true then aligns the positions onto reference
+    1304             : */
+    1305        5195 : Matrix<std::vector<Vector> >  RMSDCoreData::getDRotationDPositions( bool inverseTransform ) {
+    1306        5195 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1307        5195 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1308        5195 :   if(!isInitialized)plumed_merror("getDRotationDPosition to initialize the coreData first!");
+    1309             :   Matrix<std::vector<Vector> > DRotDPos=Matrix<std::vector<Vector> >(3,3);
+    1310             :   // remember drotation_drr01 is Tensor drotation_drr01[3][3]
+    1311             :   //           (3x3 rot) (3x3 components of rr01)
+    1312        5195 :   std::vector<Vector> v(n);
+    1313        5195 :   Vector csum;
+    1314             :   // these below could probably be calculated in the main routine
+    1315        5195 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+    1316        5195 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+    1317      563360 :   for(unsigned iat=0; iat<n; iat++) csum+=(reference[iat]-cr)*align[iat];
+    1318      563360 :   for(unsigned iat=0; iat<n; iat++) v[iat]=(reference[iat]-cr-csum)*align[iat];
+    1319       20780 :   for(unsigned a=0; a<3; a++) {
+    1320       62340 :     for(unsigned b=0; b<3; b++) {
+    1321       46755 :       if(inverseTransform) {
+    1322       46755 :         DRotDPos[b][a].resize(n);
+    1323     5070240 :         for(unsigned iat=0; iat<n; iat++) {
+    1324     5023485 :           DRotDPos[b][a][iat]=matmul(drotation_drr01[a][b],v[iat]);
+    1325             :         }
+    1326             :       } else {
+    1327           0 :         DRotDPos[a][b].resize(n);
+    1328           0 :         for(unsigned iat=0; iat<n; iat++) {
+    1329           0 :           DRotDPos[a][b][iat]=matmul(drotation_drr01[a][b],v[iat]);
+    1330             :         }
+    1331             :       }
+    1332             :     }
+    1333             :   }
+    1334        5195 :   return DRotDPos;
+    1335             : }
+    1336             : 
+    1337             : /*
+    1338             : This below is the derivative of the rotation matrix that aligns the reference onto the positions
+    1339             : respect to reference
+    1340             : note that the this transformation overlap the  reference onto position
+    1341             : if inverseTransform=true then aligns the positions onto reference
+    1342             : */
+    1343           0 : Matrix<std::vector<Vector> >  RMSDCoreData::getDRotationDReference( bool inverseTransform ) {
+    1344           0 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1345           0 :   plumed_massert(!retrieve_only_rotation,"You used  only_rotation=true in doCoreCalc therefore you cannot retrieve this information now");
+    1346           0 :   if(!isInitialized)plumed_merror("getDRotationDPositions to initialize the coreData first!");
+    1347             :   Matrix<std::vector<Vector> > DRotDRef=Matrix<std::vector<Vector> >(3,3);
+    1348             :   // remember drotation_drr01 is Tensor drotation_drr01[3][3]
+    1349             :   //           (3x3 rot) (3x3 components of rr01)
+    1350           0 :   std::vector<Vector> v(n);
+    1351           0 :   Vector csum;
+    1352             :   // these below could probably be calculated in the main routine
+    1353           0 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+    1354           0 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+    1355           0 :   for(unsigned iat=0; iat<n; iat++) csum+=(positions[iat]-cp)*align[iat];
+    1356           0 :   for(unsigned iat=0; iat<n; iat++) v[iat]=(positions[iat]-cp-csum)*align[iat];
+    1357             : 
+    1358           0 :   for(unsigned a=0; a<3; a++) {
+    1359           0 :     for(unsigned b=0; b<3; b++) {
+    1360           0 :       Tensor t_drotation_drr01=drotation_drr01[a][b].transpose();
+    1361           0 :       if(inverseTransform) {
+    1362           0 :         DRotDRef[b][a].resize(n);
+    1363           0 :         for(unsigned iat=0; iat<n; iat++) {
+    1364           0 :           DRotDRef[b][a][iat]=matmul(t_drotation_drr01,v[iat]);
+    1365             :         }
+    1366             :       } else {
+    1367           0 :         DRotDRef[a][b].resize(n);
+    1368           0 :         for(unsigned iat=0; iat<n; iat++) {
+    1369           0 :           DRotDRef[a][b][iat]=matmul(t_drotation_drr01,v[iat]);
+    1370             :         }
+    1371             :       }
+    1372             :     }
+    1373             :   }
+    1374           0 :   return DRotDRef;
+    1375             : }
+    1376             : 
+    1377             : 
+    1378           0 : std::vector<Vector> RMSDCoreData::getAlignedReferenceToPositions() {
+    1379             :   std::vector<Vector> alignedref;
+    1380           0 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1381           0 :   alignedref.resize(n);
+    1382           0 :   if(!isInitialized)plumed_merror("getAlignedReferenceToPostions needs to initialize the coreData first!");
+    1383             :   // avoid to calculate matrix element but use the sum of what you have
+    1384           0 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+    1385           0 :   for(unsigned iat=0; iat<n; iat++)alignedref[iat]=-d[iat]+positions[iat]-cp;
+    1386           0 :   return alignedref;
+    1387             : }
+    1388        4985 : std::vector<Vector> RMSDCoreData::getAlignedPositionsToReference() {
+    1389             :   std::vector<Vector> alignedpos;
+    1390        4985 :   if(!isInitialized)plumed_merror("getAlignedPostionsToReference needs to initialize the coreData first!");
+    1391        4985 :   const unsigned n=static_cast<unsigned int>(positions.size());
+    1392        4985 :   alignedpos.resize(n);
+    1393        4985 :   Vector cp; cp.zero(); if(!cpositions_is_removed)cp=cpositions;
+    1394             :   // avoid to calculate matrix element but use the sum of what you have
+    1395       77150 :   for(unsigned iat=0; iat<n; iat++)alignedpos[iat]=matmul(rotation.transpose(),positions[iat]-cp);
+    1396        4985 :   return alignedpos;
+    1397             : }
+    1398             : 
+    1399             : 
+    1400        5195 : std::vector<Vector> RMSDCoreData::getCenteredPositions() {
+    1401             :   std::vector<Vector> centeredpos;
+    1402        5195 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1403        5195 :   centeredpos.resize(n);
+    1404        5195 :   if(!isInitialized)plumed_merror("getCenteredPositions needs to initialize the coreData first!");
+    1405             :   // avoid to calculate matrix element but use the sum of what you have
+    1406      563360 :   for(unsigned iat=0; iat<n; iat++)centeredpos[iat]=positions[iat]-cpositions;
+    1407        5195 :   return centeredpos;
+    1408             : }
+    1409             : 
+    1410        4985 : std::vector<Vector> RMSDCoreData::getCenteredReference() {
+    1411             :   std::vector<Vector> centeredref;
+    1412        4985 :   const unsigned n=static_cast<unsigned int>(reference.size());
+    1413        4985 :   centeredref.resize(n);
+    1414        4985 :   if(!isInitialized)plumed_merror("getCenteredReference needs to initialize the coreData first!");
+    1415             :   // avoid to calculate matrix element but use the sum of what you have
+    1416        4985 :   Vector cr; cr.zero(); if(!creference_is_removed)cr=creference;
+    1417       77150 :   for(unsigned iat=0; iat<n; iat++)centeredref[iat]=reference[iat]-cr;
+    1418        4985 :   return centeredref;
+    1419             : }
+    1420             : 
+    1421             : 
+    1422         210 : Vector RMSDCoreData::getPositionsCenter() {
+    1423         210 :   if(!isInitialized)plumed_merror("getCenteredPositions needs to initialize the coreData first!");
+    1424         210 :   return cpositions;
+    1425             : }
+    1426             : 
+    1427           0 : Vector RMSDCoreData::getReferenceCenter() {
+    1428           0 :   if(!isInitialized)plumed_merror("getCenteredPositions needs to initialize the coreData first!");
+    1429           0 :   return creference;
+    1430             : }
+    1431             : 
+    1432        1764 : Tensor RMSDCoreData::getRotationMatrixReferenceToPositions() {
+    1433        1764 :   if(!isInitialized)plumed_merror("getRotationMatrixReferenceToPositions needs to initialize the coreData first!");
+    1434        1764 :   return rotation;
+    1435             : }
+    1436             : 
+    1437        5195 : Tensor RMSDCoreData::getRotationMatrixPositionsToReference() {
+    1438        5195 :   if(!isInitialized)plumed_merror("getRotationMatrixReferenceToPositions needs to initialize the coreData first!");
+    1439        5195 :   return rotation.transpose();
+    1440             : }
+    1441             : 
+    1442        1092 : const std::array<std::array<Tensor,3>,3> &  RMSDCoreData::getDRotationDRr01() const {
+    1443        1092 :   if(!isInitialized)plumed_merror("getDRotationDRr01 needs to initialize the coreData first!");
+    1444        1092 :   return drotation_drr01;
+    1445             : }
+    1446             : 
+    1447             : 
+    1448             : 
+    1449             : template double RMSD::optimalAlignment<true,true>(const  std::vector<double>  & align,
+    1450             :     const  std::vector<double>  & displace,
+    1451             :     const std::vector<Vector> & positions,
+    1452             :     const std::vector<Vector> & reference,
+    1453             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1454             : template double RMSD::optimalAlignment<true,false>(const  std::vector<double>  & align,
+    1455             :     const  std::vector<double>  & displace,
+    1456             :     const std::vector<Vector> & positions,
+    1457             :     const std::vector<Vector> & reference,
+    1458             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1459             : template double RMSD::optimalAlignment<false,true>(const  std::vector<double>  & align,
+    1460             :     const  std::vector<double>  & displace,
+    1461             :     const std::vector<Vector> & positions,
+    1462             :     const std::vector<Vector> & reference,
+    1463             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1464             : template double RMSD::optimalAlignment<false,false>(const  std::vector<double>  & align,
+    1465             :     const  std::vector<double>  & displace,
+    1466             :     const std::vector<Vector> & positions,
+    1467             :     const std::vector<Vector> & reference,
+    1468             :     std::vector<Vector>  & derivatives, bool squared)const;
+    1469             : 
+    1470             : 
+    1471             : 
+    1472             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.h.func-sort-c.html b/coverage/tools/RMSD.h.func-sort-c.html new file mode 100644 index 000000000000..19dae3922537 --- /dev/null +++ b/coverage/tools/RMSD.h.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303585.7 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12RMSDCoreData18setPositionsCenterENS_13VectorGenericILj3EEE0
_ZN4PLMD12RMSDCoreData19calcReferenceCenterEv0
_ZN4PLMD4RMSD17getMatrixFromDRotERKNS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEERKjSB_900
_ZN4PLMD4RMSD15calculateCenterERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEE1575
_ZN4PLMD4RMSD9addCenterERSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS3_1575
_ZN4PLMD4RMSD12removeCenterERSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS3_3145
_ZN4PLMD12RMSDCoreData18setReferenceCenterENS_13VectorGenericILj3EEE52152
_ZN4PLMD12RMSDCoreData19calcPositionsCenterEv52152
_ZN4PLMD12RMSDCoreDataC2ERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EESB_52152
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.h.func.html b/coverage/tools/RMSD.h.func.html new file mode 100644 index 000000000000..89b6b40a46f5 --- /dev/null +++ b/coverage/tools/RMSD.h.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303585.7 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12RMSDCoreData18setPositionsCenterENS_13VectorGenericILj3EEE0
_ZN4PLMD12RMSDCoreData18setReferenceCenterENS_13VectorGenericILj3EEE52152
_ZN4PLMD12RMSDCoreData19calcPositionsCenterEv52152
_ZN4PLMD12RMSDCoreData19calcReferenceCenterEv0
_ZN4PLMD12RMSDCoreDataC2ERKSt6vectorIdSaIdEES5_RKS1_INS_13VectorGenericILj3EEESaIS7_EESB_52152
_ZN4PLMD4RMSD12removeCenterERSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS3_3145
_ZN4PLMD4RMSD15calculateCenterERKSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS1_IdSaIdEE1575
_ZN4PLMD4RMSD17getMatrixFromDRotERKNS_6MatrixISt6vectorINS_13VectorGenericILj3EEESaIS4_EEEERKjSB_900
_ZN4PLMD4RMSD9addCenterERSt6vectorINS_13VectorGenericILj3EEESaIS3_EERKS3_1575
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RMSD.h.gcov.html b/coverage/tools/RMSD.h.gcov.html new file mode 100644 index 000000000000..a7d7ebd0de33 --- /dev/null +++ b/coverage/tools/RMSD.h.gcov.html @@ -0,0 +1,453 @@ + + + + + + + + LCOV - plumed test coverage - tools/RMSD.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RMSD.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:303585.7 %
Date:2024-02-22 21:58:45Functions:7977.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_RMSD_h
+      23             : #define __PLUMED_tools_RMSD_h
+      24             : 
+      25             : #include "Vector.h"
+      26             : #include "Matrix.h"
+      27             : #include "Tensor.h"
+      28             : #include <vector>
+      29             : #include <string>
+      30             : #include <array>
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : class Log;
+      35             : class PDB;
+      36             : 
+      37             : /** \ingroup TOOLBOX
+      38             : A class that implements RMSD calculations
+      39             : This is a class that implements the various infrastructure to calculate the
+      40             : RMSD or MSD respect a given frame. It can be done through an optimal alignment scheme
+      41             : as Kearsley or, more simply, by resetting the center of mass.
+      42             : This is the class that decides this. A very simple use is
+      43             : \verbatim
+      44             : #include "tools/PDB.h"
+      45             : #include "tools/RMSD.h"
+      46             : #include "tools/Vector.h"
+      47             : using namespace PLMD;
+      48             : RMSD rmsd;
+      49             : PDB pdb;
+      50             : // get the pdb (see PDB documentation)
+      51             : pdb.read("file.pdb",true,1.0);
+      52             : string type;
+      53             : type.assign("OPTIMAL");
+      54             : // set the reference and the type
+      55             : rmsd.set(pdb,type);
+      56             : // this calculates the rmsd and the derivatives
+      57             : vector<Vector> derivs;
+      58             : double val;
+      59             : val=rmsd.calculate(getPositions(),derivs,true);
+      60             : \endverbatim
+      61             : 
+      62             : **/
+      63             : 
+      64             : class RMSD
+      65             : {
+      66             :   enum AlignmentMethod {SIMPLE, OPTIMAL, OPTIMAL_FAST};
+      67             :   AlignmentMethod alignmentMethod;
+      68             : // Reference coordinates
+      69             :   std::vector<Vector> reference;
+      70             : // Weights for alignment
+      71             :   std::vector<double> align;
+      72             : // Weights for deviation
+      73             :   std::vector<double> displace;
+      74             : // Center for reference and flag for its calculation
+      75             :   Vector reference_center;
+      76             :   bool reference_center_is_calculated;
+      77             :   bool reference_center_is_removed;
+      78             : // Center for running position (not used in principle but here to reflect reference/positio symmetry
+      79             :   Vector positions_center;
+      80             :   bool positions_center_is_calculated;
+      81             :   bool positions_center_is_removed;
+      82             : // calculates the center from the position provided
+      83        1575 :   Vector calculateCenter(const std::vector<Vector> &p,const std::vector<double> &w) {
+      84        1575 :     plumed_massert(p.size()==w.size(),"mismatch in dimension of position/align arrays while calculating the center");
+      85        1575 :     unsigned n; n=p.size();
+      86        1575 :     Vector c; c.zero();
+      87       40933 :     for(unsigned i=0; i<n; i++)c+=p[i]*w[i];
+      88        1575 :     return c;
+      89             :   };
+      90             : // removes the center for the position provided
+      91        3145 :   void removeCenter(std::vector<Vector> &p, const Vector &c) {
+      92        3145 :     unsigned n; n=p.size();
+      93       81836 :     for(unsigned i=0; i<n; i++)p[i]-=c;
+      94        3145 :   };
+      95             : // add center
+      96        1575 :   void addCenter(std::vector<Vector> &p, const Vector &c) {Vector cc=c*-1.; removeCenter(p,cc);};
+      97             : 
+      98             : public:
+      99             : /// Constructor
+     100             :   RMSD();
+     101             : /// clear the structure
+     102             :   void clear();
+     103             : /// set reference, align and displace from input pdb structure: evtl remove com from the initial structure and normalize the input weights from the pdb
+     104             :   void set(const PDB&,const std::string & mytype, bool remove_center=true, bool normalize_weights=true);
+     105             : /// set align displace reference and type from input vectors
+     106             :   void set(const std::vector<double> & align, const std::vector<double> & displace, const std::vector<Vector> & reference,const std::string & mytype, bool remove_center=true, bool normalize_weights=true );
+     107             : /// set the type of alignment we are doing
+     108             :   void setType(const std::string & mytype);
+     109             : /// set reference coordinates, remove the com by using uniform weights
+     110             :   void setReference(const std::vector<Vector> & reference);
+     111             :   std::vector<Vector> getReference();
+     112             : /// set weights and remove the center from reference with normalized weights. If the com has been removed, it resets to the new value
+     113             :   void setAlign(const std::vector<double> & align, bool normalize_weights=true, bool remove_center=true);
+     114             :   std::vector<double> getAlign();
+     115             : /// set align
+     116             :   void setDisplace(const std::vector<double> & displace, bool normalize_weights=true);
+     117             :   std::vector<double> getDisplace();
+     118             : ///
+     119             :   std::string getMethod();
+     120             : /// workhorses
+     121             :   double simpleAlignment(const  std::vector<double>  & align,
+     122             :                          const  std::vector<double>  & displace,
+     123             :                          const std::vector<Vector> & positions,
+     124             :                          const std::vector<Vector> & reference,
+     125             :                          std::vector<Vector>  & derivatives,
+     126             :                          std::vector<Vector>  & displacement,
+     127             :                          bool squared=false)const;
+     128             :   template <bool safe,bool alEqDis>
+     129             :   double optimalAlignment(const  std::vector<double>  & align,
+     130             :                           const  std::vector<double>  & displace,
+     131             :                           const std::vector<Vector> & positions,
+     132             :                           const std::vector<Vector> & reference,
+     133             :                           std::vector<Vector>  & DDistDPos, bool squared=false)const;
+     134             : 
+     135             :   template <bool safe, bool alEqDis>
+     136             :   double optimalAlignmentWithCloseStructure(const  std::vector<double>  & align,
+     137             :       const  std::vector<double>  & displace,
+     138             :       const std::vector<Vector> & positions,
+     139             :       const std::vector<Vector> & reference,
+     140             :       std::vector<Vector>  & derivatives,
+     141             :       const Tensor & rotationPosClose,
+     142             :       const Tensor & rotationRefClose,
+     143             :       std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01,
+     144             :       bool squared=false)const;
+     145             : 
+     146             :   template <bool safe, bool alEqDis>
+     147             :   double optimalAlignment_Rot_DRotDRr01(const  std::vector<double>  & align,
+     148             :                                         const  std::vector<double>  & displace,
+     149             :                                         const std::vector<Vector> & positions,
+     150             :                                         const std::vector<Vector> & reference,
+     151             :                                         Tensor & Rotation,
+     152             :                                         std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01,
+     153             :                                         bool squared=false)const;
+     154             : 
+     155             :   template <bool safe, bool alEqDis>
+     156             :   double optimalAlignment_Rot(const  std::vector<double>  & align,
+     157             :                               const  std::vector<double>  & displace,
+     158             :                               const std::vector<Vector> & positions,
+     159             :                               const std::vector<Vector> & reference,
+     160             :                               std::vector<Vector>  & derivatives,
+     161             :                               Tensor & Rotation,
+     162             :                               bool squared=false)const;
+     163             : 
+     164             :   template <bool safe,bool alEqDis>
+     165             :   double optimalAlignment_DDistDRef(const  std::vector<double>  & align,
+     166             :                                     const  std::vector<double>  & displace,
+     167             :                                     const std::vector<Vector> & positions,
+     168             :                                     const std::vector<Vector> & reference,
+     169             :                                     std::vector<Vector>  & DDistDPos,
+     170             :                                     std::vector<Vector> &  DDistDRef,
+     171             :                                     bool squared=false) const;
+     172             : 
+     173             :   template <bool safe,bool alEqDis>
+     174             :   double optimalAlignment_SOMA(const  std::vector<double>  & align,
+     175             :                                const  std::vector<double>  & displace,
+     176             :                                const std::vector<Vector> & positions,
+     177             :                                const std::vector<Vector> & reference,
+     178             :                                std::vector<Vector>  & DDistDPos,
+     179             :                                std::vector<Vector> &  DDistDRef,
+     180             :                                bool squared=false) const;
+     181             : 
+     182             :   template <bool safe,bool alEqDis>
+     183             :   double optimalAlignment_DDistDRef_Rot_DRotDPos(const  std::vector<double>  & align,
+     184             :       const  std::vector<double>  & displace,
+     185             :       const std::vector<Vector> & positions,
+     186             :       const std::vector<Vector> & reference,
+     187             :       std::vector<Vector>  & DDistDPos,
+     188             :       std::vector<Vector> &  DDistDRef,
+     189             :       Tensor & Rotation,
+     190             :       Matrix<std::vector<Vector> > &DRotDPos,
+     191             :       bool squared=false) const;
+     192             : 
+     193             :   template <bool safe,bool alEqDis>
+     194             :   double optimalAlignment_DDistDRef_Rot_DRotDPos_DRotDRef(const  std::vector<double>  & align,
+     195             :       const  std::vector<double>  & displace,
+     196             :       const std::vector<Vector> & positions,
+     197             :       const std::vector<Vector> & reference,
+     198             :       std::vector<Vector>  & DDistDPos,
+     199             :       std::vector<Vector> &  DDistDRef,
+     200             :       Tensor & Rotation,
+     201             :       Matrix<std::vector<Vector> > &DRotDPos,
+     202             :       Matrix<std::vector<Vector> > &DRotDRef,
+     203             :       bool squared=false) const;
+     204             : 
+     205             :   template <bool safe,bool alEqDis>
+     206             :   double optimalAlignment_PCA(const  std::vector<double>  & align,
+     207             :                               const  std::vector<double>  & displace,
+     208             :                               const std::vector<Vector> & positions,
+     209             :                               const std::vector<Vector> & reference,
+     210             :                               std::vector<Vector> & alignedpositions,
+     211             :                               std::vector<Vector> & centeredpositions,
+     212             :                               std::vector<Vector> & centeredreference,
+     213             :                               Tensor & Rotation,
+     214             :                               std::vector<Vector> & DDistDPos,
+     215             :                               Matrix<std::vector<Vector> > & DRotDPos,
+     216             :                               bool squared=false) const ;
+     217             : 
+     218             :   template <bool safe,bool alEqDis>
+     219             :   double optimalAlignment_Fit(const  std::vector<double>  & align,
+     220             :                               const  std::vector<double>  & displace,
+     221             :                               const std::vector<Vector> & positions,
+     222             :                               const std::vector<Vector> & reference,
+     223             :                               Tensor & Rotation,
+     224             :                               Matrix<std::vector<Vector> > & DRotDPos,
+     225             :                               std::vector<Vector> & centeredpositions,
+     226             :                               Vector & center_positions,
+     227             :                               bool squared=false);
+     228             : 
+     229             : 
+     230             : /// Compute rmsd: note that this is an intermediate layer which is kept in order to evtl expand with more alignment types/user options to be called while keeping the workhorses separated
+     231             :   double calculate(const std::vector<Vector> & positions,std::vector<Vector> &derivatives, bool squared=false)const;
+     232             : /// Other convenience methods:
+     233             : /// calculate the derivative of distance respect to position(DDistDPos) and reference (DDistDPos)
+     234             :   double calc_DDistDRef( const std::vector<Vector>& positions, std::vector<Vector> &DDistDPos, std::vector<Vector>& DDistDRef, const bool squared=false   );
+     235             : /// calculate the derivative for SOMA (i.e. derivative respect to reference frame without the matrix derivative)
+     236             :   double calc_SOMA( const std::vector<Vector>& positions, std::vector<Vector> &DDistDPos, std::vector<Vector>& DDistDRef, const bool squared=false   );
+     237             : ///
+     238             :   double calc_DDistDRef_Rot_DRotDPos( const std::vector<Vector>& positions, std::vector<Vector> &DDistDPos, std::vector<Vector>& DDistDRef, Tensor & Rotation,Matrix<std::vector<Vector> > &DRotDPos, const bool squared=false   );
+     239             :   double calc_DDistDRef_Rot_DRotDPos_DRotDRef( const std::vector<Vector>& positions, std::vector<Vector> &DDistDPos, std::vector<Vector>& DDistDRef, Tensor & Rotation,Matrix<std::vector<Vector> > &DRotDPos,Matrix<std::vector<Vector> > &DRotDRef, const bool squared=false   );
+     240             : /// convenience method to retrieve all the bits and pieces for PCA
+     241             :   double calc_PCAelements( const std::vector<Vector>& pos, std::vector<Vector> &DDistDPos, Tensor & Rotation, Matrix<std::vector<Vector> > & DRotDPos,std::vector<Vector>  & alignedpositions, std::vector<Vector> & centeredpositions, std::vector<Vector> &centeredreference, const bool& squared=false) const ;
+     242             : /// convenience method to retrieve all the bits and pieces needed by FitToTemplate
+     243             :   double calc_FitElements( const std::vector<Vector>& pos, Tensor & Rotation, Matrix<std::vector<Vector> > & DRotDPos,std::vector<Vector> & centeredpositions,Vector & center_positions, const bool& squared=false );
+     244             : ///calculate rotation matrix, derivative of rotation matrix w.r.t. positions, derivative of rotation matrix w.r.t. rr01
+     245             :   double calc_Rot_DRotDRr01( const std::vector<Vector>& positions, Tensor & Rotation, std::array<std::array<Tensor,3>,3> & DRotDRr01, const bool squared=false   );
+     246             : ///calculate rotation matrix, derivative of rotation matrix w.r.t. positions
+     247             :   double calc_Rot( const std::vector<Vector>& positions, std::vector<Vector> &DDistDPos, Tensor & Rotation, const bool squared=false   );
+     248             : ///calculate with close structure, i.e. approximate the RMSD without expensive computation of rotation matrix by reusing saved rotation matrices from previous iterations
+     249             :   double calculateWithCloseStructure( const std::vector<Vector>& positions, std::vector<Vector> &DDistDPos, const Tensor & rotationPosClose, const Tensor & rotationRefClose, std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01, const bool squared=false   );
+     250             : /// static convenience method to get the matrix i,a from drotdpos (which is a bit tricky)
+     251         900 :   static  Tensor getMatrixFromDRot(const Matrix< std::vector<Vector> > &drotdpos, const unsigned &i, const unsigned &a) {
+     252         900 :     Tensor t;
+     253         900 :     t[0][0]=drotdpos(0,0)[i][a]; t[0][1]=drotdpos(0,1)[i][a]; t[0][2]=drotdpos(0,2)[i][a];
+     254         900 :     t[1][0]=drotdpos(1,0)[i][a]; t[1][1]=drotdpos(1,1)[i][a]; t[1][2]=drotdpos(1,2)[i][a];
+     255         900 :     t[2][0]=drotdpos(2,0)[i][a]; t[2][1]=drotdpos(2,1)[i][a]; t[2][2]=drotdpos(2,2)[i][a];
+     256         900 :     return t;
+     257             :   };
+     258             : };
+     259             : 
+     260             : /// this is a class which is needed to share information across the various non-threadsafe routines
+     261             : /// so that the public function of rmsd are threadsafe while the inner core can safely share information
+     262       52152 : class RMSDCoreData
+     263             : {
+     264             : private:
+     265             :   bool alEqDis;
+     266             :   bool distanceIsMSD; // default is RMSD but can deliver the MSD
+     267             :   bool hasDistance;  // distance is already calculated
+     268             :   bool isInitialized;
+     269             :   bool safe;
+     270             : 
+     271             :   // this need to be copied and they are small, should not affect the performance
+     272             :   Vector creference;
+     273             :   bool creference_is_calculated;
+     274             :   bool creference_is_removed;
+     275             :   Vector cpositions;
+     276             :   bool cpositions_is_calculated;
+     277             :   bool cpositions_is_removed;
+     278             :   bool retrieve_only_rotation;
+     279             : 
+     280             :   // use reference assignment to speed up instead of copying
+     281             :   const std::vector<Vector> &positions;
+     282             :   const std::vector<Vector> &reference;
+     283             :   const std::vector<double> &align;
+     284             :   const std::vector<double> &displace;
+     285             : 
+     286             :   // the needed stuff for distance and more (one could use eigenvecs components and eigenvals for some reason)
+     287             :   double dist;
+     288             :   Vector4d eigenvals;
+     289             :   Tensor4d eigenvecs;
+     290             :   double rr00; //  sum of positions squared (needed for dist calc)
+     291             :   double rr11; //  sum of reference squared (needed for dist calc)
+     292             :   Tensor rotation; // rotation derived from the eigenvector having the smallest eigenvalue
+     293             :   std::array<std::array<Tensor,3>,3> drotation_drr01; // derivative of the rotation only available when align!=displace
+     294             :   Tensor ddist_drr01;
+     295             :   Tensor ddist_drotation;
+     296             :   std::vector<Vector> d; // difference of components
+     297             : public:
+     298             :   /// the constructor (note: only references are passed, therefore is rather fast)
+     299             :   /// note: this aligns the reference onto the positions
+     300             :   ///
+     301             :   /// this method assumes that the centers are already calculated and subtracted
+     302             :   RMSDCoreData(const std::vector<double> &a,const std::vector<double> &d,const std::vector<Vector> &p, const std::vector<Vector> &r, Vector &cp, Vector &cr ):
+     303             :     alEqDis(false),distanceIsMSD(false),hasDistance(false),isInitialized(false),safe(false),
+     304             :     creference(cr),creference_is_calculated(true),creference_is_removed(true),
+     305             :     cpositions(cp),cpositions_is_calculated(true),cpositions_is_removed(true),retrieve_only_rotation(false),positions(p),reference(r),align(a),displace(d),dist(0.0),rr00(0.0),rr11(0.0) {};
+     306             : 
+     307             :   // this constructor does not assume that the positions and reference have the center subtracted
+     308       52152 :   RMSDCoreData(const std::vector<double> &a,const std::vector<double> &d,const std::vector<Vector> &p, const std::vector<Vector> &r):
+     309       52152 :     alEqDis(false),distanceIsMSD(false),hasDistance(false),isInitialized(false),safe(false),
+     310       52152 :     creference_is_calculated(false),creference_is_removed(false),
+     311       52152 :     cpositions_is_calculated(false),cpositions_is_removed(false),retrieve_only_rotation(false),positions(p),reference(r),align(a),displace(d),dist(0.0),rr00(0.0),rr11(0.0)
+     312       52152 :   {cpositions.zero(); creference.zero();};
+     313             : 
+     314             :   // set the center on the fly without subtracting
+     315       52152 :   void calcPositionsCenter() {
+     316       52152 :     plumed_massert(!cpositions_is_calculated,"the center was already calculated");
+     317     1221600 :     cpositions.zero(); for(unsigned i=0; i<positions.size(); i++) {cpositions+=positions[i]*align[i];} cpositions_is_calculated=true;
+     318       52152 :   }
+     319           0 :   void calcReferenceCenter() {
+     320           0 :     plumed_massert(!creference_is_calculated,"the center was already calculated");
+     321           0 :     creference.zero(); for(unsigned i=0; i<reference.size(); i++) {creference+=reference[i]*align[i];} creference_is_calculated=true;
+     322           0 :   };
+     323             :   // assume the center is given externally
+     324             :   // cppcheck-suppress passedByValue
+     325           0 :   void setPositionsCenter(Vector v) {plumed_massert(!cpositions_is_calculated,"You are setting the center two times!"); cpositions=v; cpositions_is_calculated=true;};
+     326             :   // cppcheck-suppress passedByValue
+     327       52152 :   void setReferenceCenter(Vector v) {plumed_massert(!creference_is_calculated,"You are setting the center two times!"); creference=v; creference_is_calculated=true;};
+     328             :   // the center is already removed
+     329       52152 :   void setPositionsCenterIsRemoved(bool t) {cpositions_is_removed=t;};
+     330       52152 :   void setReferenceCenterIsRemoved(bool t) {creference_is_removed=t;};
+     331             :   bool getPositionsCenterIsRemoved() {return cpositions_is_removed;};
+     332             :   bool getReferenceCenterIsRemoved() {return creference_is_removed;};
+     333             :   //  does the core calc : first thing to call after the constructor:
+     334             :   // only_rotation=true does not retrieve the derivatives, just retrieve the optimal rotation (the same calc cannot be exploit further)
+     335             :   void doCoreCalc(bool safe,bool alEqDis, bool only_rotation=false);
+     336             :   // do calculation with close structure data structures
+     337             :   void doCoreCalcWithCloseStructure(bool safe,bool alEqDis, const Tensor & rotationPosClose, const Tensor & rotationRefClose, std::array<std::array<Tensor,3>,3> & drotationPosCloseDrr01);
+     338             :   // retrieve the distance if required after doCoreCalc
+     339             :   double getDistance(bool squared);
+     340             :   // retrieve the derivative of the distance respect to the position
+     341             :   std::vector<Vector> getDDistanceDPositions();
+     342             :   // retrieve the derivative of the distance respect to the reference
+     343             :   std::vector<Vector> getDDistanceDReference();
+     344             :   // specific version for SOMA calculation (i.e. does not need derivative respect to rotation matrix)
+     345             :   std::vector<Vector> getDDistanceDReferenceSOMA();
+     346             :   // get aligned reference onto position
+     347             :   std::vector<Vector> getAlignedReferenceToPositions();
+     348             :   // get aligned position onto reference
+     349             :   std::vector<Vector> getAlignedPositionsToReference();
+     350             :   // get centered positions
+     351             :   std::vector<Vector> getCenteredPositions();
+     352             :   // get centered reference
+     353             :   std::vector<Vector> getCenteredReference();
+     354             :   // get center of positions
+     355             :   Vector getPositionsCenter();
+     356             :   // get center of reference
+     357             :   Vector getReferenceCenter();
+     358             :   // get rotation matrix (reference ->positions)
+     359             :   Tensor getRotationMatrixReferenceToPositions();
+     360             :   // get rotation matrix (positions -> reference)
+     361             :   Tensor getRotationMatrixPositionsToReference();
+     362             :   // get the derivative of the rotation matrix respect to positions
+     363             :   // note that the this transformation overlap the  reference onto position
+     364             :   // if inverseTransform=true then aligns the positions onto reference
+     365             :   Matrix<std::vector<Vector> > getDRotationDPositions( bool inverseTransform=false );
+     366             :   // get the derivative of the rotation matrix respect to reference
+     367             :   // note that the this transformation overlap the  reference onto position
+     368             :   // if inverseTransform=true then aligns the positions onto reference
+     369             :   Matrix<std::vector<Vector> >  getDRotationDReference(bool inverseTransform=false );
+     370             :   const std::array<std::array<Tensor,3>,3> & getDRotationDRr01() const;
+     371             : };
+     372             : 
+     373             : }
+     374             : 
+     375             : #endif
+     376             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.cpp.func-sort-c.html b/coverage/tools/Random.cpp.func-sort-c.html new file mode 100644 index 000000000000..ae994b86afe5 --- /dev/null +++ b/coverage/tools/Random.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Random13ReadStateFullERSi0
_ZNK4PLMD6Random14WriteStateFullERSo1
_ZN4PLMD6Random10fromStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD6Random4U01dEv2
_ZN4PLMD6Random7ShuffleERSt6vectorIjSaIjEE2
_ZNK4PLMD6Random8toStringERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD6RandomC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE807062
_ZN4PLMD6Random7setSeedEi807909
_ZN4PLMD6Random8GaussianEv1242377
_ZN4PLMD6Random7RandU01Ev1582605
_ZN4PLMD6Random3U01Ev5582206
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.cpp.func.html b/coverage/tools/Random.cpp.func.html new file mode 100644 index 000000000000..4445a4cf4f96 --- /dev/null +++ b/coverage/tools/Random.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD6Random10fromStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
_ZN4PLMD6Random13ReadStateFullERSi0
_ZN4PLMD6Random3U01Ev5582206
_ZN4PLMD6Random4U01dEv2
_ZN4PLMD6Random7RandU01Ev1582605
_ZN4PLMD6Random7ShuffleERSt6vectorIjSaIjEE2
_ZN4PLMD6Random7setSeedEi807909
_ZN4PLMD6Random8GaussianEv1242377
_ZN4PLMD6RandomC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE807062
_ZNK4PLMD6Random14WriteStateFullERSo1
_ZNK4PLMD6Random8toStringERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.cpp.gcov.html b/coverage/tools/Random.cpp.gcov.html new file mode 100644 index 000000000000..bee34723e20e --- /dev/null +++ b/coverage/tools/Random.cpp.gcov.html @@ -0,0 +1,246 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768391.6 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Random.h"
+      23             : #include <cmath>
+      24             : #include <cstdlib>
+      25             : #include <sstream>
+      26             : #include <iostream>
+      27             : #include <iterator>
+      28             : #include <functional>
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : const double Random::fact=5.9604644775390625e-8;     /* 1 / 2^24  */
+      33             : const double Random::EPS=3.0e-16;
+      34             : const double Random::AM=1.0/IM;
+      35             : const double Random::RNMX=(1.0-EPS); // 1.0-EPS;
+      36             : const std::string Random::noname="noname";
+      37             : 
+      38      807062 : Random::Random(const std::string & name):
+      39      807062 :   switchGaussian(false),
+      40      807062 :   saveGaussian(0.0),
+      41             : // this is required because if a Random object is created during
+      42             : // initialization than Random::noname could still be initialized.
+      43             : // In practice: without this it is not possible to declare
+      44             : // a static Random object without enforcing the order of the
+      45             : // static constructors.
+      46      807062 :   name(&name!=&noname?name:"noname")
+      47             : {
+      48      807062 :   iy=0;
+      49    26633046 :   for(unsigned i=0; i<NTAB; i++) iv[i]=0;
+      50      807062 :   setSeed(0);
+      51      807062 : }
+      52             : 
+      53      807909 : void Random::setSeed(int idum_) {
+      54      807909 :   if(idum_>0) idum_=-idum_;
+      55      807909 :   idum=idum_;
+      56      807909 :   incPrec=false;
+      57      807909 : }
+      58             : 
+      59     1582605 : double Random::RandU01 ()
+      60             : {
+      61     1582605 :   if (incPrec)
+      62           1 :     return U01d();
+      63             :   else
+      64     1582604 :     return U01();
+      65             : }
+      66             : 
+      67             : 
+      68           2 : double Random::U01d ()
+      69             : {
+      70             :   double u;
+      71           2 :   u = U01();
+      72           2 :   u += U01() * fact;
+      73           2 :   return (u < 1.0) ? u : (u - 1.0);
+      74             : }
+      75             : 
+      76     5582206 : double Random::U01() {
+      77             :   int j,k;
+      78             :   double temp;
+      79     5582206 :   if (idum <= 0 || !iy) {
+      80        1375 :     if (-idum < 1) idum=1;
+      81         626 :     else idum = -idum;
+      82       56375 :     for (j=NTAB+7; j>=0; j--) {
+      83       55000 :       k=idum/IQ;
+      84       55000 :       idum=IA*(idum-k*IQ)-IR*k;
+      85       55000 :       if (idum < 0) idum += IM;
+      86       55000 :       if (j < NTAB) iv[j] = idum;
+      87             :     }
+      88        1375 :     iy=iv[0];
+      89             :   }
+      90     5582206 :   k=idum/IQ;
+      91     5582206 :   idum=IA*(idum-k*IQ)-IR*k;
+      92     5582206 :   if (idum < 0) idum += IM;
+      93     5582206 :   j=iy/NDIV;
+      94     5582206 :   iy=iv[j];
+      95     5582206 :   iv[j] = idum;
+      96     5582206 :   if ((temp=AM*iy) > RNMX) return RNMX;
+      97     5582206 :   else return temp;
+      98             : }
+      99             : 
+     100           1 : void Random::WriteStateFull(std::ostream & out)const {
+     101             :   out<<name<<std::endl;
+     102           1 :   out<<idum<<" "<<iy;
+     103          33 :   for(int i=0; i<NTAB; i++) {
+     104          32 :     out<<" "<<iv[i];
+     105             :   };
+     106           1 :   out<<" "<<switchGaussian;
+     107           1 :   out<<" "<<saveGaussian;
+     108             :   out<<std::endl;
+     109           1 : }
+     110             : 
+     111           0 : void Random::ReadStateFull (std::istream & in) {
+     112           0 :   getline(in,name);
+     113           0 :   in>>idum>>iy;
+     114           0 :   for (int i = 0; i < NTAB; i++) in>>iv[i];
+     115           0 :   in>>switchGaussian;
+     116           0 :   in>>saveGaussian;
+     117           0 : }
+     118             : 
+     119           2 : void Random::toString(std::string & str)const {
+     120           2 :   std::ostringstream ostr;
+     121           2 :   ostr<<idum<<"|"<<iy;
+     122          66 :   for(int i=0; i<NTAB; i++) {
+     123          64 :     ostr<<"|"<<iv[i];
+     124             :   };
+     125           2 :   str=ostr.str();
+     126           2 : }
+     127             : 
+     128           2 : void Random::fromString(const std::string & str) {
+     129           2 :   std::string s=str;
+     130         425 :   for(unsigned i=0; i<s.length(); i++) if(s[i]=='|') s[i]=' ';
+     131           2 :   std::istringstream istr(s.c_str());
+     132           2 :   istr>>idum>>iy;
+     133          66 :   for (int i = 0; i < NTAB; i++) istr>>iv[i];
+     134           4 : }
+     135             : 
+     136             : // This allows to have the same stream of random numbers
+     137             : // with different compilers:
+     138             : #ifdef __INTEL_COMPILER
+     139             : #pragma intel optimization_level 0
+     140             : #endif
+     141             : 
+     142     1242377 : double Random::Gaussian() {
+     143             :   double v1,v2,rsq;
+     144     1242377 :   if(switchGaussian) {
+     145      621162 :     switchGaussian=false;
+     146      621162 :     return saveGaussian;
+     147             :   }
+     148             :   while(true) {
+     149      790796 :     v1=2.0*RandU01()-1.0;
+     150      790796 :     v2=2.0*RandU01()-1.0;
+     151      790796 :     rsq=v1*v1+v2*v2;
+     152      790796 :     if(rsq<1.0 && rsq>0.0) break;
+     153             :   }
+     154      621215 :   double fac=std::sqrt(-2.*std::log(rsq)/rsq);
+     155      621215 :   saveGaussian=v1*fac;
+     156      621215 :   switchGaussian=true;
+     157      621215 :   return v2*fac;
+     158             : }
+     159             : 
+     160           2 : void Random::Shuffle(std::vector<unsigned>& vec) {
+     161             :   std::iterator_traits<std::vector<unsigned>::iterator >::difference_type i, n;
+     162             :   n = vec.end() - vec.begin();
+     163           6 :   for(i=n-1; i>0; --i) {
+     164           4 :     std::swap(vec[i], vec[(int)round(RandU01() * IM) % i]);
+     165             :   }
+     166           2 : }
+     167             : 
+     168             : 
+     169             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.h.func-sort-c.html b/coverage/tools/Random.h.func-sort-c.html new file mode 100644 index 000000000000..5a7c6af326d1 --- /dev/null +++ b/coverage/tools/Random.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.h.func.html b/coverage/tools/Random.h.func.html new file mode 100644 index 000000000000..cc4df600f50d --- /dev/null +++ b/coverage/tools/Random.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Random.h.gcov.html b/coverage/tools/Random.h.gcov.html new file mode 100644 index 000000000000..2b927b293a2a --- /dev/null +++ b/coverage/tools/Random.h.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - tools/Random.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Random.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Random_h
+      23             : #define __PLUMED_tools_Random_h
+      24             : 
+      25             : #include <string>
+      26             : #include <vector>
+      27             : #include <iosfwd>
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : /// \ingroup TOOLBOX
+      32      807012 : class Random {
+      33             :   static const int IA=16807,IM=2147483647,IQ=127773,IR=2836,NTAB=32;
+      34             :   static const int NDIV=(1+(IM-1)/NTAB);
+      35             :   static const double EPS;
+      36             :   static const double AM;
+      37             :   static const double RNMX;
+      38             :   static const double fact;
+      39             :   static const std::string noname;
+      40             :   bool incPrec;
+      41             :   bool switchGaussian;
+      42             :   double saveGaussian;
+      43             :   int iy;
+      44             :   int iv[NTAB];
+      45             :   int idum;
+      46             :   std::string name;
+      47             : public:
+      48             :   explicit Random(const std::string & name=noname);
+      49             :   void setSeed(int idum);
+      50             :   double RandU01();
+      51             :   double U01();
+      52             :   double U01d();
+      53             :   int RandInt(int i);
+      54             :   void Shuffle(std::vector<unsigned>& vec);
+      55             :   void WriteStateFull(std::ostream &)const;
+      56             :   void ReadStateFull (std::istream &);
+      57             :   void fromString(const std::string & str);
+      58             :   void toString(std::string & str)const;
+      59             :   friend std::ostream & operator<<(std::ostream & out,const Random & rng) {
+      60             :     rng.WriteStateFull(out); return out;
+      61             :   }
+      62             :   friend std::istream & operator>>(std::istream & in,Random & rng) {
+      63             :     rng.ReadStateFull(in); return in;
+      64             :   }
+      65             :   double Gaussian();
+      66             :   void IncreasedPrecis(bool i) {incPrec=i;}
+      67             : };
+      68             : 
+      69             : }
+      70             : 
+      71             : #endif
+      72             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RootFindingBase.h.func-sort-c.html b/coverage/tools/RootFindingBase.h.func-sort-c.html new file mode 100644 index 000000000000..1e79b3b7d059 --- /dev/null +++ b/coverage/tools/RootFindingBase.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - tools/RootFindingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RootFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15RootFindingBaseINS_4GridEE10linesearchERKSt6vectorIdSaIdEERS5_MS1_KFdS7_S8_E0
_ZNK4PLMD15RootFindingBaseINS_4GridEE8doSearchERKSt6vectorIdSaIdEERS5_RNS_5F1dimIS1_EE0
_ZNK4PLMD15RootFindingBaseINS_11multicolvar19DistanceFromContourEE7lsearchERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E274
_ZNK4PLMD15RootFindingBaseINS_11multicolvar19DistanceFromContourEE8doSearchERKSt6vectorIdSaIdEERS6_RNS_5F1dimIS2_EE274
_ZNK4PLMD15RootFindingBaseINS_9gridtools18ContourFindingBaseEE10linesearchERKSt6vectorIdSaIdEERS6_MS2_KFdS8_S9_E1242
_ZNK4PLMD15RootFindingBaseINS_9gridtools18ContourFindingBaseEE8doSearchERKSt6vectorIdSaIdEERS6_RNS_5F1dimIS2_EE1242
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RootFindingBase.h.func.html b/coverage/tools/RootFindingBase.h.func.html new file mode 100644 index 000000000000..93911e82b075 --- /dev/null +++ b/coverage/tools/RootFindingBase.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - tools/RootFindingBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RootFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD15RootFindingBaseINS_11multicolvar19DistanceFromContourEE7lsearchERKSt6vectorIdSaIdEERS6_MS2_FdS8_S9_E274
_ZNK4PLMD15RootFindingBaseINS_11multicolvar19DistanceFromContourEE8doSearchERKSt6vectorIdSaIdEERS6_RNS_5F1dimIS2_EE274
_ZNK4PLMD15RootFindingBaseINS_4GridEE10linesearchERKSt6vectorIdSaIdEERS5_MS1_KFdS7_S8_E0
_ZNK4PLMD15RootFindingBaseINS_4GridEE8doSearchERKSt6vectorIdSaIdEERS5_RNS_5F1dimIS1_EE0
_ZNK4PLMD15RootFindingBaseINS_9gridtools18ContourFindingBaseEE10linesearchERKSt6vectorIdSaIdEERS6_MS2_KFdS8_S9_E1242
_ZNK4PLMD15RootFindingBaseINS_9gridtools18ContourFindingBaseEE8doSearchERKSt6vectorIdSaIdEERS6_RNS_5F1dimIS2_EE1242
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/RootFindingBase.h.gcov.html b/coverage/tools/RootFindingBase.h.gcov.html new file mode 100644 index 000000000000..e3c8b297273b --- /dev/null +++ b/coverage/tools/RootFindingBase.h.gcov.html @@ -0,0 +1,154 @@ + + + + + + + + LCOV - plumed test coverage - tools/RootFindingBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - RootFindingBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1616100.0 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_RootFindingBase_h
+      23             : #define __PLUMED_tools_RootFindingBase_h
+      24             : 
+      25             : #include "MinimiseBase.h"
+      26             : #include "Brent1DRootSearch.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : template <class FCLASS>
+      31             : class RootFindingBase {
+      32             : private:
+      33             : /// This is the pointer to the member function in the energy
+      34             : /// calculating class that calculates the energy
+      35             :   typedef double(FCLASS::*engf_pointer)( const std::vector<double>& p, std::vector<double>& der ) const ;
+      36             :   typedef double(FCLASS::*engfnc_pointer)( const std::vector<double>& p, std::vector<double>& der ) ;
+      37             : /// The class that calculates the energy given a position
+      38             :   FCLASS* myclass_func;
+      39             : /// This actually does the search for a root
+      40             :   void doSearch( const std::vector<double>& dir, std::vector<double>& p, F1dim<FCLASS>& f1dim  ) const ;
+      41             : public:
+      42           4 :   explicit RootFindingBase( FCLASS* funcc ) : myclass_func(funcc) {}
+      43             : /// This is the line minimiser
+      44             :   void linesearch( const std::vector<double>& dir, std::vector<double>& p, engf_pointer myfunc ) const ;
+      45             :   void lsearch( const std::vector<double>& dir, std::vector<double>& p, engfnc_pointer myfunc ) const ;
+      46             : };
+      47             : 
+      48             : template <class FCLASS>
+      49        1516 : void RootFindingBase<FCLASS>::doSearch( const std::vector<double>& dir, std::vector<double>& p, F1dim<FCLASS>& f1dim ) const {
+      50             :   // Construct an object that will do the line search for the minimum
+      51        1516 :   Brent1DRootSearch<F1dim<FCLASS> > bb(f1dim);
+      52             : 
+      53             :   // This does the actual search for the root
+      54        1516 :   double ax=0.0, xx=1.0;
+      55        1516 :   bb.bracket( ax, xx, &F1dim<FCLASS>::getEng );
+      56        1516 :   double xmin=bb.search( &F1dim<FCLASS>::getEng );
+      57        6064 :   for(unsigned i=0; i<p.size(); ++i) p[i] += xmin*dir[i];
+      58        1516 : }
+      59             : 
+      60             : template <class FCLASS>
+      61        1242 : void RootFindingBase<FCLASS>::linesearch( const std::vector<double>& dir, std::vector<double>& p, engf_pointer myfunc ) const {
+      62             :   // Construct the object that turns points on a line into vectors
+      63        1242 :   F1dim<FCLASS> f1dim( p, dir, myclass_func, myfunc, NULL );
+      64             :   // Actually do the search
+      65        1242 :   doSearch( dir, p, f1dim );
+      66        1242 : }
+      67             : 
+      68             : template <class FCLASS>
+      69         274 : void RootFindingBase<FCLASS>::lsearch( const std::vector<double>& dir, std::vector<double>& p, engfnc_pointer myfunc ) const {
+      70             :   // Construct the object that turns points on a line into vectors
+      71         274 :   F1dim<FCLASS> f1dim( p, dir, myclass_func, NULL, myfunc );
+      72             :   // Actually do the search
+      73         274 :   doSearch( dir, p, f1dim );
+      74         274 : }
+      75             : 
+      76             : }
+      77             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.cpp.func-sort-c.html b/coverage/tools/Stopwatch.cpp.func-sort-c.html new file mode 100644 index 000000000000..5274c0ec3690 --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsERSoRKNS_9StopwatchE1023
_ZNK4PLMD9Stopwatch3logERSo1023
_ZN4PLMD9StopwatchD2Ev805878
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.cpp.func.html b/coverage/tools/Stopwatch.cpp.func.html new file mode 100644 index 000000000000..6776cb0ce646 --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9StopwatchD2Ev805878
_ZN4PLMDlsERSoRKNS_9StopwatchE1023
_ZNK4PLMD9Stopwatch3logERSo1023
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.cpp.gcov.html b/coverage/tools/Stopwatch.cpp.gcov.html new file mode 100644 index 000000000000..9b6502226f49 --- /dev/null +++ b/coverage/tools/Stopwatch.cpp.gcov.html @@ -0,0 +1,155 @@ + + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Stopwatch.h"
+      24             : #include "Exception.h"
+      25             : #include "Log.h"
+      26             : 
+      27             : #include <cstdio>
+      28             : #include <iostream>
+      29             : #include <vector>
+      30             : #include <algorithm>
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : // this is needed for friend operators
+      35        1023 : std::ostream& operator<<(std::ostream&os,const Stopwatch&sw) {
+      36        1023 :   return sw.log(os);
+      37             : }
+      38             : 
+      39      805878 : Stopwatch::~Stopwatch() {
+      40      805878 :   if(mylog && mylog->isOpen()) {
+      41             : // Make sure paused watches are stopped.
+      42             : // this is necessary e.g. to make sure the main watch present in PlumedMain
+      43             : // is stopped correctly.
+      44        7733 :     for(auto & w : watches) {
+      45        6713 :       if(w.second.state==Watch::State::paused) w.second.start().stop();
+      46             :     }
+      47        1020 :     *mylog << *this;
+      48             :   }
+      49      805878 : }
+      50             : 
+      51        1023 : std::ostream& Stopwatch::log(std::ostream&os)const {
+      52             :   const std::size_t bufferlen=1000;
+      53             :   char buffer[bufferlen];
+      54        1023 :   buffer[0]=0;
+      55       41943 :   for(unsigned i=0; i<40; i++) os<<" ";
+      56        1023 :   os<<"      Cycles        Total      Average      Minimum      Maximum\n";
+      57             : 
+      58             :   std::vector<std::string> names;
+      59        7742 :   for(const auto & it : watches) names.emplace_back(it.first);
+      60        1023 :   std::sort(names.begin(),names.end());
+      61             : 
+      62             :   const double frac=1.0/1000000000.0;
+      63             : 
+      64        7742 :   for(const auto & name : names) {
+      65        6719 :     const Watch&t(watches.find(name)->second);
+      66             :     os<<name;
+      67      166056 :     for(unsigned i=name.length(); i<40; i++) os<<" ";
+      68        6719 :     std::snprintf(buffer,bufferlen,"%12u %12.6f %12.6f %12.6f %12.6f\n", t.cycles, frac*t.total, frac*t.total/t.cycles, frac*t.min,frac*t.max);
+      69        6719 :     os<<buffer;
+      70             :   }
+      71        1023 :   return os;
+      72        1023 : }
+      73             : 
+      74             : }
+      75             : 
+      76             : 
+      77             : 
+      78             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.h.func-sort-c.html b/coverage/tools/Stopwatch.h.func-sort-c.html new file mode 100644 index 000000000000..9f6197b45294 --- /dev/null +++ b/coverage/tools/Stopwatch.h.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525692.9 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Stopwatch5pauseERKSt17basic_string_viewIcSt11char_traitsIcEE572
_ZN4PLMD9Stopwatch4stopERKSt17basic_string_viewIcSt11char_traitsIcEE575
_ZN4PLMD9Stopwatch5startERKSt17basic_string_viewIcSt11char_traitsIcEE1150
_ZN4PLMD9Stopwatch7HandleraSEOS1_5075
_ZN4PLMD9Stopwatch10startPauseERKSt17basic_string_viewIcSt11char_traitsIcEE1118633
_ZN4PLMDL20StopwatchEmptyStringEv1120919
_ZN4PLMD9Stopwatch9startStopERKSt17basic_string_viewIcSt11char_traitsIcEE1532068
_ZN4PLMD9Stopwatch5Watch4stopEv1533654
_ZN4PLMD9Stopwatch5Watch5pauseEv2652705
_ZN4PLMD9Stopwatch7HandlerD2Ev6939037
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.h.func.html b/coverage/tools/Stopwatch.h.func.html new file mode 100644 index 000000000000..8e2e9a83b739 --- /dev/null +++ b/coverage/tools/Stopwatch.h.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525692.9 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD9Stopwatch10startPauseERKSt17basic_string_viewIcSt11char_traitsIcEE1118633
_ZN4PLMD9Stopwatch4stopERKSt17basic_string_viewIcSt11char_traitsIcEE575
_ZN4PLMD9Stopwatch5Watch4stopEv1533654
_ZN4PLMD9Stopwatch5Watch5pauseEv2652705
_ZN4PLMD9Stopwatch5pauseERKSt17basic_string_viewIcSt11char_traitsIcEE572
_ZN4PLMD9Stopwatch5startERKSt17basic_string_viewIcSt11char_traitsIcEE1150
_ZN4PLMD9Stopwatch7HandlerD2Ev6939037
_ZN4PLMD9Stopwatch7HandleraSEOS1_5075
_ZN4PLMD9Stopwatch9startStopERKSt17basic_string_viewIcSt11char_traitsIcEE1532068
_ZN4PLMDL20StopwatchEmptyStringEv1120919
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Stopwatch.h.gcov.html b/coverage/tools/Stopwatch.h.gcov.html new file mode 100644 index 000000000000..bf8aaa3fc577 --- /dev/null +++ b/coverage/tools/Stopwatch.h.gcov.html @@ -0,0 +1,486 @@ + + + + + + + + LCOV - plumed test coverage - tools/Stopwatch.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Stopwatch.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:525692.9 %
Date:2024-02-22 21:58:45Functions:1010100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Stopwatch_h
+      23             : #define __PLUMED_tools_Stopwatch_h
+      24             : 
+      25             : #include "Exception.h"
+      26             : #include "Tools.h"
+      27             : #include <string>
+      28             : #include <iosfwd>
+      29             : #include <chrono>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /**
+      34             : \ingroup TOOLBOX
+      35             : Class implementing stopwatch to time execution.
+      36             : 
+      37             : Each instance of this class is a container which
+      38             : can keep track of several named stopwatches at
+      39             : the same time. Access to the stopwatches
+      40             : is obtained using start(), stop(), pause() methods,
+      41             : giving as a parameter the name of the specific stopwatch.
+      42             : Also an empty string can be used (un-named stopwatch).
+      43             : Finally, all the times can be logged using << operator
+      44             : 
+      45             : \verbatim
+      46             : #include "Stopwatch.h"
+      47             : 
+      48             : int main(){
+      49             :   Stopwatch sw;
+      50             :   sw.start();
+      51             : 
+      52             :   sw.start("initialization");
+      53             : // do initialization ...
+      54             :   sw.stop("initialization");
+      55             : 
+      56             :   for(int i=0;i<100;i++){
+      57             :     sw.start("loop");
+      58             : // do calculation
+      59             :     sw.stop("loop");
+      60             :   }
+      61             : 
+      62             :   sw.stop();
+      63             :   return 0;
+      64             : }
+      65             : 
+      66             : \endverbatim
+      67             : 
+      68             : Using pause a stopwatch can be put on hold until
+      69             : the next start:
+      70             : 
+      71             : \verbatim
+      72             : #include "Stopwatch.h"
+      73             : 
+      74             : int main(){
+      75             :   Stopwatch sw;
+      76             :   sw.start();
+      77             : 
+      78             :   sw.start("initialization");
+      79             : // do initialization ...
+      80             :   sw.stop("initialization");
+      81             : 
+      82             :   for(int i=0;i<100;i++){
+      83             :     sw.start("loop");
+      84             : // do calculation
+      85             :     sw.pause("loop");
+      86             : // here goes something that we do not want to include
+      87             :     sw.start("loop");
+      88             : // do calculation
+      89             :     sw.stop("loop");
+      90             :   }
+      91             : 
+      92             :   sw.stop();
+      93             :   return 0;
+      94             : }
+      95             : 
+      96             : \endverbatim
+      97             : 
+      98             : Notice that as of PLUMED 2.5 it is possible to use a slightly modified
+      99             : interface that allow for exception safety. In practice,
+     100             : one can replace a pair of calls to Stopwatch::start() and Stopwatch::stop()
+     101             : with a single call to Stopwatch::startStop(). This call will return an object
+     102             : that, when goes out of scope, will stop the timer.
+     103             : 
+     104             : \notice The exception safety interace is highly recommended since it allows
+     105             : to make sure that stopwatches are started and stopped consistently.
+     106             : 
+     107             : For instance the following
+     108             : code
+     109             : \verbatim
+     110             :   {
+     111             :     sw.start("A");
+     112             :   // any code
+     113             :     sw.stop("A");
+     114             :   }
+     115             : \endverbatim
+     116             : can be replaced with
+     117             : \verbatim
+     118             :   {
+     119             :     auto sww=sw.startStop("A");
+     120             :   // any code
+     121             : 
+     122             :   // stopwatch is stopped when sww goes out of scope
+     123             :   }
+     124             : \endverbatim
+     125             : Similarly, Stopwatch::startPause() can be used to replace a pair of
+     126             : Stopwatch::start() and Stopwatch::pause().
+     127             : 
+     128             : The older syntax (explicitly calling `Stopwatch::start()` and `Stopwatch::pause()`) is still
+     129             : allowed for backward compatibility.
+     130             : 
+     131             : Notice that the returned object is of type `Stopwatch::Handler`.
+     132             : You might be willing to explicitly declare a `Stopwatch::Handler` (instead of using `auto`)
+     133             : when you want to conditionally start the stopwatch. For instance:
+     134             : \verbatim
+     135             :   {
+     136             :     Stopwatch::Handler handler;
+     137             :     if(you_want_to_time_this) handler=sw.startStop();
+     138             :     ... do something ...
+     139             :   }
+     140             :   // in case it was started, the stopwatch will stop here, at the end of the block
+     141             :   // in case it was not started, nothing will happen
+     142             : \endverbatim
+     143             : 
+     144             : A `Stopwatch::Handler` can not be copied but it can be moved (it behaves like a unique_ptr).
+     145             : Moving it explicitly allows one to transfer it to another `Stopwatch::Handler` with a different scope.
+     146             : For instance, in case you want to conditionally stop the stopwatch you might use something like this:
+     147             : \verbatim
+     148             :   {
+     149             :     Stopwatch::Handler handler;
+     150             :     if(you_want_to_time_this) handler=sw.startStop();
+     151             :     ... do something ...
+     152             :     if(you_want_to_stop_here) auto h2=std::move(handler);
+     153             :     // the previous instruction moves handler to h2 that is then destroyed, stopping the watch
+     154             :     // notice that if the stop was not started it will not stop.
+     155             :     ... do something else ...
+     156             :   }
+     157             :   // in case it is running, the stopwatch will stop here, at the end of the block
+     158             : \endverbatim
+     159             : 
+     160             : Finally, notice that in order to write the timers on an output file when the
+     161             : Stopwatch is destroyed, one can store a reference to a PLMD::Log by passing it
+     162             : to the Stopwatch constructor.
+     163             : This will make sure timers are written also in case of a premature end.
+     164             : */
+     165             : 
+     166             : class Log;
+     167             : 
+     168             : /// Return an empty string.
+     169             : /// Inline static so that it can store a static variable (for quicker access)
+     170             : /// without adding a unique global symbol to a library including this header file.
+     171     1120919 : inline static const std::string & StopwatchEmptyString() noexcept {
+     172     1120919 :   const static std::string s;
+     173     1120919 :   return s;
+     174             : }
+     175             : 
+     176             : class Stopwatch {
+     177             : 
+     178             : public:
+     179             : /// Forward declaration
+     180             :   class Watch;
+     181             : /// Auxiliary class for handling exception-safe start/pause and start/stop.
+     182             :   class Handler {
+     183             :     Watch* watch=nullptr;
+     184             :     /// stop (true) or pause (false).
+     185             :     /// might be changed to an enum if clearer.
+     186             :     bool stop=false;
+     187             :     /// Private constructor.
+     188             :     /// This is kept private to avoid misuse. Handler objects should
+     189             :     /// only be created using startPause() or startStop().
+     190             :     /// stop is required to know if the destructor should stop or pause the watch.
+     191             :     Handler(Watch* watch,bool stop);
+     192             :     /// Allows usage of private constructor
+     193             :     friend class Stopwatch;
+     194             :   public:
+     195             :     /// Default constructor
+     196             :     Handler() = default;
+     197             :     /// Default copy constructor is deleted (not copyable)
+     198             :     Handler(const Handler & handler) = delete;
+     199             :     /// Default copy assignment is deleted (not copyable)
+     200             :     Handler & operator=(const Handler & handler) = delete;
+     201             :     /// Move constructor.
+     202             :     Handler(Handler && handler) noexcept;
+     203             :     /// Move assignment.
+     204             :     Handler & operator=(Handler && handler) noexcept;
+     205             :     /// Destructor either stops or pauses the watch
+     206             :     ~Handler();
+     207             :   };
+     208             : 
+     209             : /// Class to store a single stopwatch.
+     210             : /// Class Stopwatch contains a collection of them
+     211       11535 :   class Watch {
+     212             : /// Instant in time when Watch was started last time
+     213             :     std::chrono::time_point<std::chrono::high_resolution_clock> lastStart;
+     214             : /// Total accumulated time, in nanoseconds
+     215             :     long long int total = 0;
+     216             : /// Accumulated time for this lap, in nanoseconds
+     217             :     long long int lap = 0;
+     218             : /// Slowest lap so far, in nanoseconds
+     219             :     long long int max = 0;
+     220             : /// Fastest lap so far, in nanoseconds
+     221             :     long long int min = 0;
+     222             : /// Total number of cycles
+     223             :     unsigned cycles = 0;
+     224             : /// count how many times Watch was started (+1) or stopped/paused (-1).
+     225             :     unsigned running = 0;
+     226             :     enum class State {started, stopped, paused};
+     227             : /// keep track of state
+     228             :     State state = State::stopped;
+     229             : /// Allows access to internal data
+     230             :     friend class Stopwatch;
+     231             :   public:
+     232             : /// start the watch
+     233             :     Watch & start();
+     234             : /// stop the watch
+     235             :     Watch & stop();
+     236             : /// pause the watch
+     237             :     Watch & pause();
+     238             : /// returns a start-stop handler
+     239             :     Handler startStop();
+     240             : /// returns a start-pause handler
+     241             :     Handler startPause();
+     242             :   };
+     243             : 
+     244             : private:
+     245             : 
+     246             : /// Pointer to a log file.
+     247             : /// If set, the stopwatch is logged in its destructor.
+     248             :   Log*mylog=nullptr;
+     249             : 
+     250             : /// List of watches.
+     251             : /// Each watch is labeled with a string.
+     252             :   Tools::FastStringUnorderedMap<Watch> watches;
+     253             : 
+     254             : /// Log over stream os.
+     255             :   std::ostream& log(std::ostream& os)const;
+     256             : 
+     257             : public:
+     258             : // Constructor.
+     259             :   explicit Stopwatch() = default;
+     260             : // Constructor.
+     261             : // When destructing, stopwatch is logged.
+     262             : // Make sure that log survives stopwatch. Typically, it should be declared earlier, in order
+     263             : // to be destroyed later.
+     264      805292 :   explicit Stopwatch(Log&log): mylog(&log) {}
+     265             : // Destructor.
+     266             :   ~Stopwatch();
+     267             : /// Start timer named "name"
+     268             :   Stopwatch& start(const std::string_view&name=StopwatchEmptyString());
+     269             : /// Stop timer named "name"
+     270             :   Stopwatch& stop(const std::string_view&name=StopwatchEmptyString());
+     271             : /// Pause timer named "name"
+     272             :   Stopwatch& pause(const std::string_view&name=StopwatchEmptyString());
+     273             : /// Dump all timers on an ostream
+     274             :   friend std::ostream& operator<<(std::ostream&,const Stopwatch&);
+     275             : /// Start with exception safety, then stop.
+     276             : /// Starts the Stopwatch and returns an object that, when goes out of scope,
+     277             : /// stops the watch. This allows Stopwatch to be started and stopped in
+     278             : /// an exception safe manner.
+     279             :   Handler startStop(const std::string_view&name=StopwatchEmptyString());
+     280             : /// Start with exception safety, then pause.
+     281             : /// Starts the Stopwatch and returns an object that, when goes out of scope,
+     282             : /// pauses the watch. This allows Stopwatch to be started and paused in
+     283             : /// an exception safe manner.
+     284             :   Handler startPause(const std::string_view&name=StopwatchEmptyString());
+     285             : };
+     286             : 
+     287             : inline
+     288             : Stopwatch::Handler::Handler(Watch* watch,bool stop) :
+     289     2650701 :   watch(watch),
+     290     2650701 :   stop(stop)
+     291             : {
+     292             :   watch->start();
+     293             : }
+     294             : 
+     295             : inline
+     296     6939037 : Stopwatch::Handler::~Handler() {
+     297     6939037 :   if(watch) {
+     298     2650701 :     if(stop) watch->stop();
+     299     1118633 :     else watch->pause();
+     300             :   }
+     301     6939037 : }
+     302             : 
+     303             : inline
+     304        1150 : Stopwatch& Stopwatch::start(const std::string_view & name) {
+     305        1150 :   watches[name].start();
+     306        1150 :   return *this;
+     307             : }
+     308             : 
+     309             : inline
+     310         575 : Stopwatch& Stopwatch::stop(const std::string_view & name) {
+     311         575 :   watches[name].stop();
+     312         575 :   return *this;
+     313             : }
+     314             : 
+     315             : inline
+     316         572 : Stopwatch& Stopwatch::pause(const std::string_view & name) {
+     317         572 :   watches[name].pause();
+     318         572 :   return *this;
+     319             : }
+     320             : 
+     321             : inline
+     322     1532068 : Stopwatch::Handler Stopwatch::startStop(const std::string_view&name) {
+     323     1532068 :   return watches[name].startStop();
+     324             : }
+     325             : 
+     326             : inline
+     327     1118633 : Stopwatch::Handler Stopwatch::startPause(const std::string_view&name) {
+     328     1118633 :   return watches[name].startPause();
+     329             : }
+     330             : 
+     331             : inline
+     332             : Stopwatch::Handler::Handler(Handler && handler) noexcept :
+     333             :   watch(handler.watch),
+     334             :   stop(handler.stop)
+     335             : {
+     336             :   handler.watch=nullptr;
+     337             : }
+     338             : 
+     339             : inline
+     340        5075 : Stopwatch::Handler & Stopwatch::Handler::operator=(Handler && handler) noexcept {
+     341        5075 :   if(this!=&handler) {
+     342        5075 :     if(watch) {
+     343             :       try {
+     344           0 :         if(stop) watch->stop();
+     345           0 :         else watch->pause();
+     346           0 :       } catch(...) {
+     347             : // this is to avoid problems with cppcheck, given than this method is declared as
+     348             : // noexcept and stop and pause might throw in case of an internal bug
+     349           0 :         std::terminate();
+     350             :       }
+     351             :     }
+     352        5075 :     watch=handler.watch;
+     353        5075 :     stop=handler.stop;
+     354        5075 :     handler.watch=nullptr;
+     355             :   }
+     356        5075 :   return *this;
+     357             : }
+     358             : 
+     359             : inline
+     360             : Stopwatch::Watch & Stopwatch::Watch::start() {
+     361     2652862 :   state=State::started;
+     362     2652862 :   running++;
+     363     2652862 :   lastStart=std::chrono::high_resolution_clock::now();
+     364             :   return *this;
+     365             : }
+     366             : 
+     367             : inline
+     368     1533654 : Stopwatch::Watch & Stopwatch::Watch::stop() {
+     369     1533654 :   pause();
+     370     1533654 :   state=State::stopped;
+     371     1533654 :   cycles++;
+     372     1533654 :   total+=lap;
+     373     1533654 :   if(lap>max)max=lap;
+     374     1533654 :   if(min>lap || cycles==1)min=lap;
+     375     1533654 :   lap=0;
+     376     1533654 :   return *this;
+     377             : }
+     378             : 
+     379             : inline
+     380     2652705 : Stopwatch::Watch & Stopwatch::Watch::pause() {
+     381     2652705 :   state=State::paused;
+     382             : // In case of an internal bug (non matching start stop within the startStop or startPause interface)
+     383             : // this assertion could fail in a destructor.
+     384             : // If this happens, the program should crash immediately
+     385     2652705 :   plumed_assert(running>0) << "Non matching start/pause or start/stop commands in a Stopwatch";
+     386     2652705 :   running--;
+     387             : // notice: with exception safety the following might be converted to a plain error.
+     388             : // I leave it like this for now:
+     389     2652705 :   if(running!=0) return *this;
+     390     2652654 :   auto t=std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::high_resolution_clock::now()-lastStart);
+     391     2652654 :   lap+=t.count();
+     392     2652654 :   return *this;
+     393             : }
+     394             : 
+     395             : inline
+     396             : Stopwatch::Handler Stopwatch::Watch::startStop() {
+     397             :   return Handler( this,true );
+     398             : }
+     399             : 
+     400             : inline
+     401             : Stopwatch::Handler Stopwatch::Watch::startPause() {
+     402             :   return Handler( this,false );
+     403             : }
+     404             : 
+     405             : 
+     406             : }
+     407             : 
+     408             : 
+     409             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.func-sort-c.html b/coverage/tools/Subprocess.cpp.func-sort-c.html new file mode 100644 index 000000000000..4a257d409fe9 --- /dev/null +++ b/coverage/tools/Subprocess.cpp.func-sort-c.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:608174.1 %
Date:2024-02-22 21:58:45Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10Subprocess7HandlerC2EOS1_0
_ZN4PLMD10Subprocess7HandleraSEOS1_0
_ZN4PLMD10SubprocessC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD10SubprocessD2Ev1
_ZN4PLMD13SubprocessPidC2Ei1
_ZN4PLMD13SubprocessPidD2Ev1
_ZN4PLMD10Subprocess4contEv8
_ZN4PLMD10Subprocess5flushEv8
_ZN4PLMD10Subprocess7HandlerC2EPS0_8
_ZN4PLMD10Subprocess7HandlerD2Ev8
_ZN4PLMD10Subprocess7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD13SubprocessPid4contEv8
_ZN4PLMD10Subprocess4stopEv9
_ZN4PLMD13SubprocessPid4stopEv9
_ZN4PLMDL26SubprocessPidGetenvSignalsEv17
_ZN4PLMD10Subprocess9availableEv86
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.func.html b/coverage/tools/Subprocess.cpp.func.html new file mode 100644 index 000000000000..e93ab8cb1f6f --- /dev/null +++ b/coverage/tools/Subprocess.cpp.func.html @@ -0,0 +1,137 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:608174.1 %
Date:2024-02-22 21:58:45Functions:141687.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10Subprocess4contEv8
_ZN4PLMD10Subprocess4stopEv9
_ZN4PLMD10Subprocess5flushEv8
_ZN4PLMD10Subprocess7HandlerC2EOS1_0
_ZN4PLMD10Subprocess7HandlerC2EPS0_8
_ZN4PLMD10Subprocess7HandlerD2Ev8
_ZN4PLMD10Subprocess7HandleraSEOS1_0
_ZN4PLMD10Subprocess7getlineERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD10Subprocess9availableEv86
_ZN4PLMD10SubprocessC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1
_ZN4PLMD10SubprocessD2Ev1
_ZN4PLMD13SubprocessPid4contEv8
_ZN4PLMD13SubprocessPid4stopEv9
_ZN4PLMD13SubprocessPidC2Ei1
_ZN4PLMD13SubprocessPidD2Ev1
_ZN4PLMDL26SubprocessPidGetenvSignalsEv17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.cpp.gcov.html b/coverage/tools/Subprocess.cpp.gcov.html new file mode 100644 index 000000000000..ec702515e4af --- /dev/null +++ b/coverage/tools/Subprocess.cpp.gcov.html @@ -0,0 +1,257 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:608174.1 %
Date:2024-02-22 21:58:45Functions:141687.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Subprocess.h"
+      23             : #include "Exception.h"
+      24             : #include "Tools.h"
+      25             : #ifdef __PLUMED_HAS_SUBPROCESS
+      26             : #include <unistd.h>
+      27             : #include <csignal>
+      28             : #endif
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : /// Retrieve PLUMED_ENABLE_SIGNALS.
+      33             : /// Inline static so that it can store a static variable (for quicker access)
+      34             : /// without adding a unique global symbol to a library including this header file.
+      35          17 : inline static bool SubprocessPidGetenvSignals() noexcept {
+      36          17 :   static const bool res=std::getenv("PLUMED_ENABLE_SIGNALS");
+      37          17 :   return res;
+      38             : }
+      39             : 
+      40             : /// Small utility class, used to avoid inclusion of unistd.h> in a header file.
+      41             : class SubprocessPid {
+      42             : #ifdef __PLUMED_HAS_SUBPROCESS
+      43             : public:
+      44             :   pid_t pid;
+      45           1 :   explicit SubprocessPid(pid_t pid):
+      46           1 :     pid(pid)
+      47             :   {
+      48           1 :     plumed_assert(pid!=0 && pid!=-1);
+      49           1 :   }
+      50           9 :   void stop() noexcept {
+      51             :     // Signals give problems with MPI on Travis.
+      52             :     // I disable them for now.
+      53           9 :     if(SubprocessPidGetenvSignals()) if(pid!=0 && pid!=-1) kill(pid,SIGSTOP);
+      54           9 :   }
+      55           8 :   void cont() noexcept {
+      56             :     // Signals give problems with MPI on Travis.
+      57             :     // I disable them for now.
+      58           8 :     if(SubprocessPidGetenvSignals()) if(pid!=0 && pid!=-1) kill(pid,SIGCONT);
+      59           8 :   }
+      60           1 :   ~SubprocessPid() {
+      61             :     // this is apparently working also with MPI on Travis.
+      62           1 :     if(pid!=0 && pid!=-1) kill(pid,SIGINT);
+      63           1 :   }
+      64             : #endif
+      65             : };
+      66             : 
+      67           1 : Subprocess::Subprocess(const std::string & cmd) {
+      68             : #ifdef __PLUMED_HAS_SUBPROCESS
+      69           1 :   char* arr [] = {
+      70             :     // const_cast are necessary here due to the declaration of execv
+      71             :     const_cast<char*>("/bin/sh"),
+      72             :     const_cast<char*>("-c"),
+      73             :     const_cast<char*>(cmd.c_str()),
+      74             :     nullptr
+      75           1 :   };
+      76             :   int cp[2];
+      77             :   int pc[2];
+      78           1 :   if(pipe(pc)<0) plumed_error()<<"error creating parent to child pipe";
+      79           1 :   if(pipe(cp)<0) plumed_error()<<"error creating child to parent pipe";
+      80           1 :   pid_t pid=fork();
+      81           1 :   switch(pid) {
+      82           0 :   case -1:
+      83           0 :     plumed_error()<<"error forking";
+      84             :     break;
+      85             : // CHILD:
+      86           0 :   case 0:
+      87             :   {
+      88           0 :     if(close(1)<0) plumed_error()<<"error closing file";
+      89           0 :     if(dup(cp[1])<0) plumed_error()<<"error duplicating file";
+      90           0 :     if(close(0)<0) plumed_error()<<"error closing file";
+      91           0 :     if(dup(pc[0])<0) plumed_error()<<"error duplicating file";
+      92           0 :     if(close(pc[1])<0) plumed_error()<<"error closing file";
+      93           0 :     if(close(cp[0])<0) plumed_error()<<"error closing file";
+      94           0 :     execv(arr[0],arr);
+      95           0 :     plumed_error()<<"error in script file";
+      96             :   }
+      97             : // PARENT::
+      98           1 :   default:
+      99           1 :     this->pid=Tools::make_unique<SubprocessPid>(pid);
+     100           1 :     if(close(pc[0])<0) plumed_error()<<"error closing file";
+     101           1 :     if(close(cp[1])<0) plumed_error()<<"error closing file";
+     102           1 :     fpc=pc[1];
+     103           1 :     fcp=cp[0];
+     104           1 :     fppc=fdopen(fpc,"w");
+     105           1 :     parent_to_child.link(fppc);
+     106           1 :     fpcp=fdopen(fcp,"r");
+     107           1 :     child_to_parent.link(fpcp);
+     108             :   }
+     109             : #else
+     110             :   plumed_error()<<"Subprocess not supported";
+     111             : #endif
+     112           1 : }
+     113             : 
+     114           1 : Subprocess::~Subprocess() {
+     115             : #ifdef __PLUMED_HAS_SUBPROCESS
+     116             : // fpc should be closed to terminate the child executable
+     117           1 :   fclose(fppc);
+     118           1 :   close(fpc);
+     119             : // fcp should not be closed because it could make the child executable fail
+     120             : /// TODO: check if this is necessary and make this class exception safe!
+     121             : #endif
+     122           1 : }
+     123             : 
+     124          86 : bool Subprocess::available() noexcept {
+     125             : #ifdef __PLUMED_HAS_SUBPROCESS
+     126          86 :   return true;
+     127             : #else
+     128             :   return false;
+     129             : #endif
+     130             : }
+     131             : 
+     132           9 : void Subprocess::stop() noexcept {
+     133             : #ifdef __PLUMED_HAS_SUBPROCESS
+     134           9 :   pid->stop();
+     135             : #endif
+     136           9 : }
+     137             : 
+     138           8 : void Subprocess::cont() noexcept {
+     139             : #ifdef __PLUMED_HAS_SUBPROCESS
+     140           8 :   pid->cont();
+     141             : #endif
+     142           8 : }
+     143             : 
+     144           8 : void Subprocess::flush() {
+     145           8 :   parent_to_child.flush();
+     146           8 : }
+     147             : 
+     148           8 : Subprocess & Subprocess::getline(std::string & line) {
+     149           8 :   child_to_parent.getline(line);
+     150           8 :   if(!child_to_parent) plumed_error() <<"error reading subprocess";
+     151           8 :   return (*this);
+     152             : }
+     153             : 
+     154           8 : Subprocess::Handler::Handler(Subprocess *sp) noexcept:
+     155           8 :   sp(sp)
+     156             : {
+     157           8 :   sp->cont();
+     158           8 : }
+     159             : 
+     160           8 : Subprocess::Handler::~Handler() {
+     161           8 :   if(sp) sp->stop();
+     162           8 : }
+     163             : 
+     164           0 : Subprocess::Handler::Handler(Handler && handler) noexcept :
+     165           0 :   sp(handler.sp)
+     166             : {
+     167           0 :   handler.sp=nullptr;
+     168           0 : }
+     169             : 
+     170           0 : Subprocess::Handler & Subprocess::Handler::operator=(Handler && handler) noexcept {
+     171           0 :   if(this!=&handler) {
+     172           0 :     if(sp) sp->stop();
+     173           0 :     sp=handler.sp;
+     174           0 :     handler.sp=nullptr;
+     175             :   }
+     176           0 :   return *this;
+     177             : }
+     178             : 
+     179             : 
+     180             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.h.func-sort-c.html b/coverage/tools/Subprocess.h.func-sort-c.html new file mode 100644 index 000000000000..86322fb56add --- /dev/null +++ b/coverage/tools/Subprocess.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsIA2_cEERNS_10SubprocessES3_RKT_8
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_10SubprocessES8_RKT_8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.h.func.html b/coverage/tools/Subprocess.h.func.html new file mode 100644 index 000000000000..e7d31c7dff4c --- /dev/null +++ b/coverage/tools/Subprocess.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMDlsIA2_cEERNS_10SubprocessES3_RKT_8
_ZN4PLMDlsINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEERNS_10SubprocessES8_RKT_8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Subprocess.h.gcov.html b/coverage/tools/Subprocess.h.gcov.html new file mode 100644 index 000000000000..eeaebe8979e0 --- /dev/null +++ b/coverage/tools/Subprocess.h.gcov.html @@ -0,0 +1,219 @@ + + + + + + + + LCOV - plumed test coverage - tools/Subprocess.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Subprocess.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:44100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2019-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Subprocess_h
+      23             : #define __PLUMED_tools_Subprocess_h
+      24             : 
+      25             : #include "OFile.h"
+      26             : #include "IFile.h"
+      27             : #include <string>
+      28             : #include <cstdio>
+      29             : #include <memory>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33             : /// Small class to avoid including unistd.h here
+      34             : class SubprocessPid;
+      35             : 
+      36             : /**
+      37             : Class managing a subprocess.
+      38             : 
+      39             : The subprocess is launched and one can interact with it through a pipe.
+      40             : 
+      41             : In order not to consume resources, it might be possible to use this syntax:
+      42             : 
+      43             : \verbatim
+      44             : // at construction:
+      45             : Subprocess sp;
+      46             : sp.stop();
+      47             : 
+      48             : // when needed
+      49             : {
+      50             :   auto h=sp.contStop();
+      51             :   sp<<"command\n";
+      52             :   sp.flush();
+      53             :   sp.getline(answer);
+      54             : }
+      55             : // when h goes out of scope, subprocess is stopped again.
+      56             : // If an exception is raised in the block, the subprocess is stopped as well.
+      57             : \endverbatim
+      58             : 
+      59             : \warning
+      60             : Currently `stop` and `cont` are giving problems with some MPI implementation,
+      61             : In addition, notice that the stop signal is only sent to the child process and
+      62             : not to the subsequently spawn processes, so it might not work as intended.
+      63             : This feature is left here but is probably no a good idea to use it.
+      64             : It can be enabled with `export PLUMED_ENABLE_SIGNALS=1`.
+      65             : 
+      66             : */
+      67             : class Subprocess {
+      68             :   /// Process ID.
+      69             :   /// We store this rather than pid_t to avoid including <unistd.h> in this header file.
+      70             :   /// This remains nullptr in the child process.
+      71             :   std::unique_ptr<SubprocessPid> pid;
+      72             :   /// File descriptor, parent to child
+      73             :   int fpc=0;
+      74             :   /// File descriptor, child to parent
+      75             :   int fcp=0;
+      76             :   /// File pointer, parent to child
+      77             :   FILE* fppc=NULL;
+      78             :   /// File pointer, child to parent
+      79             :   FILE* fpcp=NULL;
+      80             :   /// PLUMED file object, parent to child.
+      81             :   /// Used to simplify formatting
+      82             :   OFile parent_to_child;
+      83             :   /// PLUMED file object, child to parent.
+      84             :   /// Used to simplify formatting
+      85             :   IFile child_to_parent;
+      86             : public:
+      87             :   /// Class used to cont/stop a Subprocess in an exception safe manner.
+      88             :   class Handler {
+      89             :     Subprocess* sp=nullptr;
+      90             :     /// Private constructor.
+      91             :     /// Only to be called by Subprocess::contStop()
+      92             :     explicit Handler(Subprocess* sp) noexcept;
+      93             :     friend class Subprocess;
+      94             :   public:
+      95             :     /// Default constructor
+      96             :     Handler() = default;
+      97             :     /// Destructor stops the subprocess.
+      98             :     ~Handler();
+      99             :     /// Default copy constructor is deleted (not copyable)
+     100             :     Handler(const Handler &) = delete;
+     101             :     /// Default copy assignment is deleted (not copyable)
+     102             :     Handler & operator=(const Handler & handler) = delete;
+     103             :     /// Move constructor.
+     104             :     Handler(Handler &&) noexcept;
+     105             :     /// Move assignment.
+     106             :     Handler & operator=(Handler && handler) noexcept;
+     107             :   };
+     108             : /// Constructor with a command line.
+     109             :   explicit Subprocess(const std::string & cmd);
+     110             : /// Destructor
+     111             :   ~Subprocess();
+     112             : /// Flush communication to process.
+     113             :   void flush();
+     114             : /// Check if subprocess facilities are available.
+     115             : /// If it returns false, any call to Subprocess constructor will raise an exception.
+     116             :   static bool available() noexcept;
+     117             : /// Get a line from the subprocess.
+     118             :   Subprocess & getline(std::string &);
+     119             : /// Write something to the subprocess.
+     120             :   template <class T> friend Subprocess& operator<<(Subprocess& ep,const T &t);
+     121             : /// Send a SIGCONT to the subprocess.
+     122             : /// Better used through contStop() method.
+     123             :   void cont() noexcept;
+     124             : /// Send a SIGSTOP to the subprocess.
+     125             : /// Better used through contStop() method.
+     126             :   void stop() noexcept;
+     127             : /// Returns a handler to temporarily resume the process.
+     128             :   Handler contStop() noexcept {
+     129           8 :     return Handler(this);
+     130             :   }
+     131             : };
+     132             : 
+     133             : template <class T>
+     134          16 : Subprocess& operator<<(Subprocess& ep,const T &t) {
+     135          16 :   ep.parent_to_child<<t;
+     136          16 :   return ep;
+     137             : }
+     138             : 
+     139             : }
+     140             : 
+     141             : #endif
+     142             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.func-sort-c.html b/coverage/tools/SwitchingFunction.cpp.func-sort-c.html new file mode 100644 index 000000000000..04dae7dd2628 --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/SwitchingFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - SwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25025996.5 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD17SwitchingFunction6get_d0Ev6
_ZNK4PLMD17SwitchingFunction6get_r0Ev30
_ZN4PLMD17SwitchingFunction3setEiidd61
_ZN4PLMD17SwitchingFunction16registerKeywordsERNS_8KeywordsE93
_ZN4PLMD17SwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_1018
_ZNK4PLMD17SwitchingFunction11descriptionB5cxx11Ev1068
_ZNK4PLMD17SwitchingFunction12calculateSqrEdRd19722781
_ZNK4PLMD17SwitchingFunction9get_dmax2Ev23893569
_ZNK4PLMD17SwitchingFunction11do_rationalEdRdii41288760
_ZNK4PLMD17SwitchingFunction9calculateEdRd88977037
_ZNK4PLMD17SwitchingFunction8get_dmaxEv117918073
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.func.html b/coverage/tools/SwitchingFunction.cpp.func.html new file mode 100644 index 000000000000..cc73a813eb60 --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/SwitchingFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - SwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25025996.5 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD17SwitchingFunction16registerKeywordsERNS_8KeywordsE93
_ZN4PLMD17SwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_1018
_ZN4PLMD17SwitchingFunction3setEiidd61
_ZNK4PLMD17SwitchingFunction11descriptionB5cxx11Ev1068
_ZNK4PLMD17SwitchingFunction11do_rationalEdRdii41288760
_ZNK4PLMD17SwitchingFunction12calculateSqrEdRd19722781
_ZNK4PLMD17SwitchingFunction6get_d0Ev6
_ZNK4PLMD17SwitchingFunction6get_r0Ev30
_ZNK4PLMD17SwitchingFunction8get_dmaxEv117918073
_ZNK4PLMD17SwitchingFunction9calculateEdRd88977037
_ZNK4PLMD17SwitchingFunction9get_dmax2Ev23893569
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/SwitchingFunction.cpp.gcov.html b/coverage/tools/SwitchingFunction.cpp.gcov.html new file mode 100644 index 000000000000..fd746edfb2b5 --- /dev/null +++ b/coverage/tools/SwitchingFunction.cpp.gcov.html @@ -0,0 +1,627 @@ + + + + + + + + LCOV - plumed test coverage - tools/SwitchingFunction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - SwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25025996.5 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "SwitchingFunction.h"
+      23             : #include "Tools.h"
+      24             : #include "Keywords.h"
+      25             : #include "OpenMP.h"
+      26             : #include <vector>
+      27             : #include <limits>
+      28             : #include <algorithm>
+      29             : 
+      30             : #define PI 3.14159265358979323846
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : //+PLUMEDOC INTERNAL switchingfunction
+      35             : /*
+      36             : Functions that measure whether values are less than a certain quantity.
+      37             : 
+      38             : Switching functions \f$s(r)\f$ take a minimum of one input parameter \f$r_0\f$.
+      39             : For \f$r \le d_0 \quad s(r)=1.0\f$ while for \f$r > d_0\f$ the function decays smoothly to 0.
+      40             : The various switching functions available in PLUMED differ in terms of how this decay is performed.
+      41             : 
+      42             : Where there is an accepted convention in the literature (e.g. \ref COORDINATION) on the form of the
+      43             : switching function we use the convention as the default.  However, the flexibility to use different
+      44             : switching functions is always present generally through a single keyword. This keyword generally
+      45             : takes an input with the following form:
+      46             : 
+      47             : \verbatim
+      48             : KEYWORD={TYPE <list of parameters>}
+      49             : \endverbatim
+      50             : 
+      51             : The following table contains a list of the various switching functions that are available in PLUMED 2
+      52             : together with an example input.
+      53             : 
+      54             : <table align=center frame=void width=95%% cellpadding=5%%>
+      55             : <tr>
+      56             : <td> TYPE </td> <td> FUNCTION </td> <td> EXAMPLE INPUT </td> <td> DEFAULT PARAMETERS </td>
+      57             : </tr> <tr> <td>RATIONAL </td> <td>
+      58             : \f$
+      59             : s(r)=\frac{ 1 - \left(\frac{ r - d_0 }{ r_0 }\right)^{n} }{ 1 - \left(\frac{ r - d_0 }{ r_0 }\right)^{m} }
+      60             : \f$
+      61             : </td> <td>
+      62             : {RATIONAL R_0=\f$r_0\f$ D_0=\f$d_0\f$ NN=\f$n\f$ MM=\f$m\f$}
+      63             : </td> <td> \f$d_0=0.0\f$, \f$n=6\f$, \f$m=2n\f$ </td>
+      64             : </tr> <tr>
+      65             : <td> EXP </td> <td>
+      66             : \f$
+      67             : s(r)=\exp\left(-\frac{ r - d_0 }{ r_0 }\right)
+      68             : \f$
+      69             : </td> <td>
+      70             : {EXP  R_0=\f$r_0\f$ D_0=\f$d_0\f$}
+      71             : </td> <td> \f$d_0=0.0\f$ </td>
+      72             : </tr> <tr>
+      73             : <td> GAUSSIAN </td> <td>
+      74             : \f$
+      75             : s(r)=\exp\left(-\frac{ (r - d_0)^2 }{ 2r_0^2 }\right)
+      76             : \f$
+      77             : </td> <td>
+      78             : {GAUSSIAN R_0=\f$r_0\f$ D_0=\f$d_0\f$}
+      79             : </td> <td> \f$d_0=0.0\f$ </td>
+      80             : </tr> <tr>
+      81             : <td> SMAP </td> <td>
+      82             : \f$
+      83             : s(r) = \left[ 1 + ( 2^{a/b} -1 )\left( \frac{r-d_0}{r_0} \right)^a \right]^{-b/a}
+      84             : \f$
+      85             : </td> <td>
+      86             : {SMAP R_0=\f$r_0\f$ D_0=\f$d_0\f$ A=\f$a\f$ B=\f$b\f$}
+      87             : </td> <td> \f$d_0=0.0\f$ </td>
+      88             : </tr> <tr>
+      89             : <td> Q </td> <td>
+      90             : \f$
+      91             : s(r) = \frac{1}{1 + \exp(\beta(r_{ij} - \lambda r_{ij}^0))}
+      92             : \f$
+      93             : </td> <td>
+      94             : {Q REF=\f$r_{ij}^0\f$ BETA=\f$\beta\f$ LAMBDA=\f$\lambda\f$ }
+      95             : </td> <td> \f$\lambda=1.8\f$,  \f$\beta=50 nm^-1\f$ (all-atom)<br/>\f$\lambda=1.5\f$,  \f$\beta=50 nm^-1\f$ (coarse-grained)  </td>
+      96             : </tr> <tr>
+      97             : <td> CUBIC </td> <td>
+      98             : \f$
+      99             : s(r) = (y-1)^2(1+2y) \qquad \textrm{where} \quad y = \frac{r - r_1}{r_0-r_1}
+     100             : \f$
+     101             : </td> <td>
+     102             : {CUBIC D_0=\f$r_1\f$ D_MAX=\f$r_0\f$}
+     103             : </td> <td> </td>
+     104             : </tr> <tr>
+     105             : <td> TANH </td> <td>
+     106             : \f$
+     107             : s(r) = 1 - \tanh\left( \frac{ r - d_0 }{ r_0 } \right)
+     108             : \f$
+     109             : </td> <td>
+     110             : {TANH R_0=\f$r_0\f$ D_0=\f$d_0\f$}
+     111             : </td> <td> </td>
+     112             : </tr> <tr>
+     113             : <td> COSINUS </td> <td>
+     114             : \f$s(r) =\left\{\begin{array}{ll}
+     115             :    1                                                           & \mathrm{if } r \leq d_0 \\
+     116             :    0.5 \left( \cos ( \frac{ r - d_0 }{ r_0 } \pi ) + 1 \right) & \mathrm{if } d_0 < r\leq d_0 + r_0 \\
+     117             :    0                                                           & \mathrm{if } r < d_0 + r_0
+     118             :   \end{array}\right.
+     119             : \f$
+     120             : </td> <td>
+     121             : {COSINUS R_0=\f$r_0\f$ D_0=\f$d_0\f$}
+     122             : </td> <td> </td>
+     123             : </tr> <tr>
+     124             : <td> CUSTOM </td> <td>
+     125             : \f$
+     126             : s(r) = FUNC
+     127             : \f$
+     128             : </td> <td>
+     129             : {CUSTOM FUNC=1/(1+x^6) R_0=\f$r_0\f$ D_0=\f$d_0\f$}
+     130             : </td> <td> </td>
+     131             : </tr>
+     132             : </table>
+     133             : 
+     134             : Notice that for backward compatibility we allow using `MATHEVAL` instead of `CUSTOM`.
+     135             : Also notice that if the a `CUSTOM` switching function only depends on even powers of `x` it can be
+     136             : made faster by using `x2` as a variable. For instance
+     137             : \verbatim
+     138             : {CUSTOM FUNC=1/(1+x2^3) R_0=0.3}
+     139             : \endverbatim
+     140             : is equivalent to
+     141             : \verbatim
+     142             : {CUSTOM FUNC=1/(1+x^6) R_0=0.3}
+     143             : \endverbatim
+     144             : but runs faster. The reason is that there is an expensive square root calculation that can be optimized out.
+     145             : 
+     146             : 
+     147             : \attention
+     148             : With the default implementation CUSTOM is slower than other functions
+     149             : (e.g., it is slower than an equivalent RATIONAL function by approximately a factor 2).
+     150             : Checkout page \ref Lepton to see how to improve its performance.
+     151             : 
+     152             : For all the switching functions in the above table one can also specify a further (optional) parameter using the parameter
+     153             : keyword D_MAX to assert that for \f$r>d_{\textrm{max}}\f$ the switching function can be assumed equal to zero.
+     154             : In this case the function is brought smoothly to zero by stretching and shifting it.
+     155             : \verbatim
+     156             : KEYWORD={RATIONAL R_0=1 D_MAX=3}
+     157             : \endverbatim
+     158             : the resulting switching function will be
+     159             : \f$
+     160             : s(r) = \frac{s'(r)-s'(d_{max})}{s'(0)-s'(d_{max})}
+     161             : \f$
+     162             : where
+     163             : \f$
+     164             : s'(r)=\frac{1-r^6}{1-r^{12}}
+     165             : \f$
+     166             : Since PLUMED 2.2 this is the default. The old behavior (no stretching) can be obtained with the
+     167             : NOSTRETCH flag. The NOSTRETCH keyword is only provided for backward compatibility and might be
+     168             : removed in the future. Similarly, the STRETCH keyword is still allowed but has no effect.
+     169             : 
+     170             : Notice that switching functions defined with the simplified syntax are never stretched
+     171             : for backward compatibility. This might change in the future.
+     172             : 
+     173             : */
+     174             : //+ENDPLUMEDOC
+     175             : 
+     176          93 : void SwitchingFunction::registerKeywords( Keywords& keys ) {
+     177         186 :   keys.add("compulsory","R_0","the value of R_0 in the switching function");
+     178         186 :   keys.add("compulsory","D_0","0.0","the value of D_0 in the switching function");
+     179         186 :   keys.add("optional","D_MAX","the value at which the switching function can be assumed equal to zero");
+     180         186 :   keys.add("compulsory","NN","6","the value of n in the switching function (only needed for TYPE=RATIONAL)");
+     181         186 :   keys.add("compulsory","MM","0","the value of m in the switching function (only needed for TYPE=RATIONAL); 0 implies 2*NN");
+     182         186 :   keys.add("compulsory","A","the value of a in the switching function (only needed for TYPE=SMAP)");
+     183         186 :   keys.add("compulsory","B","the value of b in the switching function (only needed for TYPE=SMAP)");
+     184          93 : }
+     185             : 
+     186        1018 : void SwitchingFunction::set(const std::string & definition,std::string& errormsg) {
+     187        1018 :   std::vector<std::string> data=Tools::getWords(definition);
+     188        1018 :   if( data.size()<1 ) {
+     189             :     errormsg="missing all input for switching function";
+     190             :     return;
+     191             :   }
+     192        1018 :   std::string name=data[0];
+     193             :   data.erase(data.begin());
+     194        1018 :   invr0=0.0;
+     195        1018 :   invr0_2=0.0;
+     196        1018 :   d0=0.0;
+     197        1018 :   dmax=std::numeric_limits<double>::max();
+     198        1018 :   dmax_2=std::numeric_limits<double>::max();
+     199        1018 :   stretch=1.0;
+     200        1018 :   shift=0.0;
+     201        1018 :   init=true;
+     202             : 
+     203             :   bool present;
+     204             : 
+     205        1018 :   present=Tools::findKeyword(data,"D_0");
+     206        1312 :   if(present && !Tools::parse(data,"D_0",d0)) errormsg="could not parse D_0";
+     207             : 
+     208        1018 :   present=Tools::findKeyword(data,"D_MAX");
+     209        1240 :   if(present && !Tools::parse(data,"D_MAX",dmax)) errormsg="could not parse D_MAX";
+     210        1018 :   if(dmax<std::sqrt(std::numeric_limits<double>::max())) dmax_2=dmax*dmax;
+     211        1018 :   bool dostretch=false;
+     212        1018 :   Tools::parseFlag(data,"STRETCH",dostretch); // this is ignored now
+     213        1018 :   dostretch=true;
+     214        1018 :   bool dontstretch=false;
+     215        1018 :   Tools::parseFlag(data,"NOSTRETCH",dontstretch); // this is ignored now
+     216        1018 :   if(dontstretch) dostretch=false;
+     217             :   double r0;
+     218        1018 :   if(name=="CUBIC") {
+     219          18 :     r0 = dmax - d0;
+     220             :   } else {
+     221        1000 :     bool found_r0=Tools::parse(data,"R_0",r0);
+     222        1000 :     if(!found_r0) errormsg="R_0 is required";
+     223             :   }
+     224        1018 :   invr0=1.0/r0;
+     225        1018 :   invr0_2=invr0*invr0;
+     226             : 
+     227        1018 :   if(name=="RATIONAL") {
+     228         290 :     type=rational;
+     229         290 :     nn=6;
+     230         290 :     mm=0;
+     231         290 :     present=Tools::findKeyword(data,"NN");
+     232         434 :     if(present && !Tools::parse(data,"NN",nn)) errormsg="could not parse NN";
+     233         290 :     present=Tools::findKeyword(data,"MM");
+     234         434 :     if(present && !Tools::parse(data,"MM",mm)) errormsg="could not parse MM";
+     235         290 :     if(mm==0) mm=2*nn;
+     236         353 :     fastrational=(nn%2==0 && mm%2==0 && d0==0.0);
+     237         728 :   } else if(name=="SMAP") {
+     238          10 :     type=smap;
+     239          10 :     present=Tools::findKeyword(data,"A");
+     240          30 :     if(present && !Tools::parse(data,"A",a)) errormsg="could not parse A";
+     241          10 :     present=Tools::findKeyword(data,"B");
+     242          30 :     if(present && !Tools::parse(data,"B",b)) errormsg="could not parse B";
+     243          10 :     c=std::pow(2., static_cast<double>(a)/static_cast<double>(b) ) - 1;
+     244          10 :     d = -static_cast<double>(b) / static_cast<double>(a);
+     245             :   }
+     246         718 :   else if(name=="Q") {
+     247         570 :     type=nativeq;
+     248         570 :     beta = 50.0;  // nm-1
+     249         570 :     lambda = 1.8; // unitless
+     250         570 :     present=Tools::findKeyword(data,"BETA");
+     251        1710 :     if(present && !Tools::parse(data, "BETA", beta)) errormsg="could not parse BETA";
+     252         570 :     present=Tools::findKeyword(data,"LAMBDA");
+     253        1710 :     if(present && !Tools::parse(data, "LAMBDA", lambda)) errormsg="could not parse LAMBDA";
+     254         570 :     bool found_ref=Tools::parse(data,"REF",ref); // nm
+     255         570 :     if(!found_ref) errormsg="REF (reference disatance) is required for native Q";
+     256             : 
+     257             :   }
+     258         148 :   else if(name=="EXP") type=exponential;
+     259          83 :   else if(name=="GAUSSIAN") type=gaussian;
+     260          35 :   else if(name=="CUBIC") type=cubic;
+     261          17 :   else if(name=="TANH") type=tanh;
+     262          15 :   else if(name=="COSINUS") type=cosinus;
+     263          25 :   else if((name=="MATHEVAL" || name=="CUSTOM")) {
+     264          13 :     type=leptontype;
+     265             :     std::string func;
+     266          13 :     Tools::parse(data,"FUNC",func);
+     267          15 :     lepton::ParsedExpression pe=lepton::Parser::parse(func).optimize(lepton::Constants());
+     268          13 :     lepton_func=func;
+     269          13 :     expression.resize(OpenMP::getNumThreads());
+     270          39 :     for(auto & e : expression) e=pe.createCompiledExpression();
+     271          13 :     lepton_ref.resize(expression.size());
+     272          35 :     for(unsigned t=0; t<lepton_ref.size(); t++) {
+     273          24 :       auto vars=expression[t].getVariables();
+     274          24 :       bool found_x=std::find(vars.begin(),vars.end(),"x")!=vars.end();
+     275          24 :       bool found_x2=std::find(vars.begin(),vars.end(),"x2")!=vars.end();
+     276          24 :       if (vars.size()==0) {
+     277             : // this is necessary since in some cases lepton thinks a variable is not present even though it is present
+     278             : // e.g. func=0*x
+     279           0 :         lepton_ref[t]=nullptr;
+     280          24 :       } else if(vars.size()==1 && found_x) {
+     281          16 :         lepton_ref[t]=&expression[t].getVariableReference("x");
+     282           8 :       } else if(vars.size()==1 && found_x2) {
+     283           8 :         lepton_ref[t]=&expression[t].getVariableReference("x2");
+     284           6 :         leptonx2=true;
+     285           2 :       } else if(vars.size()==2 && found_x && found_x2) {
+     286           2 :         plumed_error() << "Cannot use simultaneously x and x2 argument in switching function: "<<func;
+     287             :       } else {
+     288           2 :         plumed_error() << "Something wrong in the arguments for switching function: "<<func;
+     289             :       }
+     290             :     }
+     291          13 :     std::string arg="x";
+     292          11 :     if(leptonx2) arg="x2";
+     293          22 :     lepton::ParsedExpression ped=lepton::Parser::parse(func).differentiate(arg).optimize(lepton::Constants());
+     294          11 :     expression_deriv.resize(OpenMP::getNumThreads());
+     295          33 :     for(auto & e : expression_deriv) e=ped.createCompiledExpression();
+     296          11 :     lepton_ref_deriv.resize(expression_deriv.size());
+     297          33 :     for(unsigned t=0; t<lepton_ref_deriv.size(); t++) {
+     298             :       try {
+     299          22 :         lepton_ref_deriv[t]=&expression_deriv[t].getVariableReference(arg);
+     300           0 :       } catch(const PLMD::lepton::Exception& exc) {
+     301             : // this is necessary since in some cases lepton things a variable is not present even though it is present
+     302             : // e.g. func=3*x
+     303           0 :         lepton_ref_deriv[t]=nullptr;
+     304           0 :       }
+     305             :     }
+     306             : 
+     307             :   }
+     308           2 :   else errormsg="cannot understand switching function type '"+name+"'";
+     309        1016 :   if( !data.empty() ) {
+     310             :     errormsg="found the following rogue keywords in switching function input : ";
+     311           2 :     for(unsigned i=0; i<data.size(); ++i) errormsg = errormsg + data[i] + " ";
+     312             :   }
+     313             : 
+     314        1016 :   if(dostretch && dmax!=std::numeric_limits<double>::max()) {
+     315             :     double dummy;
+     316          93 :     double s0=calculate(0.0,dummy);
+     317          93 :     double sd=calculate(dmax,dummy);
+     318          93 :     stretch=1.0/(s0-sd);
+     319          93 :     shift=-sd*stretch;
+     320             :   }
+     321        1016 :   plumed_assert(!(leptonx2 && d0!=0.0)) << "You cannot use lepton x2 optimization with d0!=0.0 (d0=" << d0 <<")\n"
+     322           0 :                                         << "Please rewrite your function using x as a variable";
+     323        1018 : }
+     324             : 
+     325        1068 : std::string SwitchingFunction::description() const {
+     326        1068 :   std::ostringstream ostr;
+     327        1068 :   ostr<<1./invr0<<".  Using ";
+     328        1068 :   if(type==rational) {
+     329         347 :     ostr<<"rational";
+     330             :   } else if(type==exponential) {
+     331          61 :     ostr<<"exponential";
+     332             :   } else if(type==nativeq) {
+     333         570 :     ostr<<"nativeq";
+     334             :   } else if(type==gaussian) {
+     335          48 :     ostr<<"gaussian";
+     336             :   } else if(type==smap) {
+     337          10 :     ostr<<"smap";
+     338             :   } else if(type==cubic) {
+     339          18 :     ostr<<"cubic";
+     340             :   } else if(type==tanh) {
+     341           2 :     ostr<<"tanh";
+     342             :   } else if(type==cosinus) {
+     343           1 :     ostr<<"cosinus";
+     344             :   } else if(type==leptontype) {
+     345          11 :     ostr<<"lepton";
+     346             :   } else {
+     347           0 :     plumed_merror("Unknown switching function type");
+     348             :   }
+     349        1068 :   ostr<<" switching function with parameters d0="<<d0;
+     350        1068 :   if(type==rational) {
+     351         347 :     ostr<<" nn="<<nn<<" mm="<<mm;
+     352         721 :   } else if(type==nativeq) {
+     353         570 :     ostr<<" beta="<<beta<<" lambda="<<lambda<<" ref="<<ref;
+     354         151 :   } else if(type==smap) {
+     355          10 :     ostr<<" a="<<a<<" b="<<b;
+     356         141 :   } else if(type==cubic) {
+     357          18 :     ostr<<" dmax="<<dmax;
+     358         123 :   } else if(type==leptontype) {
+     359          11 :     ostr<<" func="<<lepton_func;
+     360             : 
+     361             :   }
+     362        1068 :   return ostr.str();
+     363        1068 : }
+     364             : 
+     365    41288760 : double SwitchingFunction::do_rational(double rdist,double&dfunc,int nn,int mm)const {
+     366             :   double result;
+     367    41288760 :   if(2*nn==mm) {
+     368             : // if 2*N==M, then (1.0-rdist^N)/(1.0-rdist^M) = 1.0/(1.0+rdist^N)
+     369    25193474 :     double rNdist=Tools::fastpow(rdist,nn-1);
+     370    25193474 :     double iden=1.0/(1+rNdist*rdist);
+     371    25193474 :     dfunc = -nn*rNdist*iden*iden;
+     372             :     result = iden;
+     373             :   } else {
+     374    16095286 :     if(rdist>(1.-100.0*epsilon) && rdist<(1+100.0*epsilon)) {
+     375           0 :       result=nn/mm;
+     376           0 :       dfunc=0.5*nn*(nn-mm)/mm;
+     377             :     } else {
+     378    16095286 :       double rNdist=Tools::fastpow(rdist,nn-1);
+     379    16095286 :       double rMdist=Tools::fastpow(rdist,mm-1);
+     380    16095286 :       double num = 1.-rNdist*rdist;
+     381    16095286 :       double iden = 1./(1.-rMdist*rdist);
+     382    16095286 :       double func = num*iden;
+     383             :       result = func;
+     384    16095286 :       dfunc = ((-nn*rNdist*iden)+(func*(iden*mm)*rMdist));
+     385             :     }
+     386             :   }
+     387    41288760 :   return result;
+     388             : }
+     389             : 
+     390    19722781 : double SwitchingFunction::calculateSqr(double distance2,double&dfunc)const {
+     391    19722781 :   if(fastrational) {
+     392     7657979 :     if(distance2>dmax_2) {
+     393      144482 :       dfunc=0.0;
+     394      144482 :       return 0.0;
+     395             :     }
+     396     7513497 :     const double rdist_2 = distance2*invr0_2;
+     397     7513497 :     double result=do_rational(rdist_2,dfunc,nn/2,mm/2);
+     398             : // chain rule:
+     399     7513497 :     dfunc*=2*invr0_2;
+     400             : // stretch:
+     401     7513497 :     result=result*stretch+shift;
+     402     7513497 :     dfunc*=stretch;
+     403     7513497 :     return result;
+     404    12064802 :   } else if(leptonx2) {
+     405     1248110 :     if(distance2>dmax_2) {
+     406           8 :       dfunc=0.0;
+     407           8 :       return 0.0;
+     408             :     }
+     409     1248102 :     const unsigned t=OpenMP::getThreadNum();
+     410     1248102 :     const double rdist_2 = distance2*invr0_2;
+     411     1248102 :     plumed_assert(t<expression.size());
+     412     1248102 :     if(lepton_ref[t]) *lepton_ref[t]=rdist_2;
+     413     1248102 :     if(lepton_ref_deriv[t]) *lepton_ref_deriv[t]=rdist_2;
+     414     1248102 :     double result=expression[t].evaluate();
+     415     1248102 :     dfunc=expression_deriv[t].evaluate();
+     416             : // chain rule:
+     417     1248102 :     dfunc*=2*invr0_2;
+     418             : // stretch:
+     419     1248102 :     result=result*stretch+shift;
+     420     1248102 :     dfunc*=stretch;
+     421     1248102 :     return result;
+     422             :   } else {
+     423    10816692 :     double distance=std::sqrt(distance2);
+     424    10816692 :     return calculate(distance,dfunc);
+     425             :   }
+     426             : }
+     427             : 
+     428    88977037 : double SwitchingFunction::calculate(double distance,double&dfunc)const {
+     429    88977037 :   plumed_massert(init,"you are trying to use an unset SwitchingFunction");
+     430    88977037 :   if(distance>dmax) {
+     431      450533 :     dfunc=0.0;
+     432      450533 :     return 0.0;
+     433             :   }
+     434             : // in this case, the lepton object stores only the calculateSqr function
+     435             : // so we have to implement calculate in terms of calculateSqr
+     436    88526504 :   if(leptonx2) {
+     437           2 :     return calculateSqr(distance*distance,dfunc);
+     438             :   }
+     439    88526502 :   const double rdist = (distance-d0)*invr0;
+     440             :   double result;
+     441             : 
+     442    88526502 :   if(rdist<=0.) {
+     443             :     result=1.;
+     444    24459938 :     dfunc=0.0;
+     445             :   } else {
+     446    64066564 :     if(type==smap) {
+     447    21789971 :       double sx=c*Tools::fastpow( rdist, a );
+     448    21789971 :       result=std::pow( 1.0 + sx, d );
+     449    21789971 :       dfunc=-b*sx/rdist*result/(1.0+sx);
+     450             :     } else if(type==rational) {
+     451    33775263 :       result=do_rational(rdist,dfunc,nn,mm);
+     452             :     } else if(type==exponential) {
+     453     2486478 :       result=std::exp(-rdist);
+     454     2486478 :       dfunc=-result;
+     455             :     } else if(type==nativeq) {
+     456      146570 :       double rdist2 = beta*(distance - lambda * ref);
+     457      146570 :       double exprdist=std::exp(rdist2);
+     458      146570 :       double exprmdist=1.0/exprdist;
+     459      146570 :       result=1./(1.+exprdist);
+     460      146570 :       dfunc=-beta/(exprmdist+1.0)/(1.+exprdist)/invr0;
+     461             :     } else if(type==gaussian) {
+     462      195683 :       result=std::exp(-0.5*rdist*rdist);
+     463      195683 :       dfunc=-rdist*result;
+     464             :     } else if(type==cubic) {
+     465      127132 :       double tmp1=rdist-1, tmp2=(1+2*rdist);
+     466      127132 :       result=tmp1*tmp1*tmp2;
+     467      127132 :       dfunc=2*tmp1*tmp2 + 2*tmp1*tmp1;
+     468             :     } else if(type==tanh) {
+     469        8000 :       double tmp1=std::tanh(rdist);
+     470        8000 :       result = 1.0 - tmp1;
+     471        8000 :       dfunc=-(1-tmp1*tmp1);
+     472             :     } else if(type==cosinus) {
+     473             :       if(rdist<=0.0) {
+     474             : // rdist = (r-r1)/(r2-r1) ; rdist<=0.0 if r <=r1
+     475             :         result=1.;
+     476             :         dfunc=0.0;
+     477      522053 :       } else if(rdist<=1.0) {
+     478             : // rdist = (r-r1)/(r2-r1) ; 0.0<=rdist<=1.0 if r1 <= r <=r2; (r2-r1)/(r2-r1)=1
+     479      226962 :         double tmpcos = std::cos ( rdist * PI );
+     480      226962 :         double tmpsin = std::sin ( rdist * PI );
+     481      226962 :         result = 0.5 * (tmpcos + 1.0);
+     482      226962 :         dfunc=-0.5 * PI * tmpsin * invr0;
+     483             :       } else {
+     484             :         result=0.;
+     485      295091 :         dfunc=0.0;
+     486             :       }
+     487             :     } else if(type==leptontype) {
+     488     5015414 :       const unsigned t=OpenMP::getThreadNum();
+     489     5015414 :       plumed_assert(t<expression.size());
+     490     5015414 :       if(lepton_ref[t]) *lepton_ref[t]=rdist;
+     491     5015414 :       if(lepton_ref_deriv[t]) *lepton_ref_deriv[t]=rdist;
+     492     5015414 :       result=expression[t].evaluate();
+     493     5015414 :       dfunc=expression_deriv[t].evaluate();
+     494           0 :     } else plumed_merror("Unknown switching function type");
+     495             : // this is for the chain rule (derivative of rdist):
+     496    64066564 :     dfunc*=invr0;
+     497             : // for any future switching functions, be aware that multiplying invr0 is only correct for functions of rdist = (r-d0)/r0.
+     498             : 
+     499             : // this is because calculate() sets dfunc to the derivative divided times the distance.
+     500             : // (I think this is misleading and I would like to modify it - GB)
+     501    64066564 :     dfunc/=distance;
+     502             :   }
+     503             : 
+     504    88526502 :   result=result*stretch+shift;
+     505    88526502 :   dfunc*=stretch;
+     506             : 
+     507    88526502 :   return result;
+     508             : }
+     509             : 
+     510          61 : void SwitchingFunction::set(int nn,int mm,double r0,double d0) {
+     511          61 :   init=true;
+     512          61 :   type=rational;
+     513          61 :   if(mm==0) mm=2*nn;
+     514          61 :   this->nn=nn;
+     515          61 :   this->mm=mm;
+     516          61 :   this->invr0=1.0/r0;
+     517          61 :   this->invr0_2=this->invr0*this->invr0;
+     518          61 :   this->d0=d0;
+     519          61 :   this->dmax=d0+r0*std::pow(0.00001,1./(nn-mm));
+     520          61 :   this->dmax_2=this->dmax*this->dmax;
+     521          61 :   this->leptonx2=false;
+     522          61 :   this->fastrational=(nn%2==0 && mm%2==0 && d0==0.0);
+     523             : 
+     524             :   double dummy;
+     525          61 :   double s0=calculate(0.0,dummy);
+     526          61 :   double sd=calculate(dmax,dummy);
+     527          61 :   stretch=1.0/(s0-sd);
+     528          61 :   shift=-sd*stretch;
+     529          61 : }
+     530             : 
+     531          30 : double SwitchingFunction::get_r0() const {
+     532          30 :   return 1./invr0;
+     533             : }
+     534             : 
+     535           6 : double SwitchingFunction::get_d0() const {
+     536           6 :   return d0;
+     537             : }
+     538             : 
+     539   117918073 : double SwitchingFunction::get_dmax() const {
+     540   117918073 :   return dmax;
+     541             : }
+     542             : 
+     543    23893569 : double SwitchingFunction::get_dmax2() const {
+     544    23893569 :   return dmax_2;
+     545             : }
+     546             : 
+     547             : }
+     548             : 
+     549             : 
+     550             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.cpp.func-sort-c.html b/coverage/tools/Tensor.cpp.func-sort-c.html new file mode 100644 index 000000000000..47de34723ead --- /dev/null +++ b/coverage/tools/Tensor.cpp.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tensor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16TensorGenericAux12local_dsyevrEPKcS2_S2_PiPdS3_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_556394
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.cpp.func.html b/coverage/tools/Tensor.cpp.func.html new file mode 100644 index 000000000000..8e9dc85023b9 --- /dev/null +++ b/coverage/tools/Tensor.cpp.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tensor.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD16TensorGenericAux12local_dsyevrEPKcS2_S2_PiPdS3_S4_S4_S3_S3_S4_S3_S4_S4_S3_S3_S4_S3_S3_S3_S3_556394
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.cpp.gcov.html b/coverage/tools/Tensor.cpp.gcov.html new file mode 100644 index 000000000000..a83a7fd9fdf4 --- /dev/null +++ b/coverage/tools/Tensor.cpp.gcov.html @@ -0,0 +1,116 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tensor.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Tensor.h"
+      23             : #include "Exception.h"
+      24             : 
+      25             : #include "lapack/lapack.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29      556394 : void TensorGenericAux::local_dsyevr(const char *jobz, const char *range, const char *uplo, int *n,
+      30             :                                     double *a, int *lda, double *vl, double *vu, int *
+      31             :                                     il, int *iu, double *abstol, int *m, double *w,
+      32             :                                     double *z__, int *ldz, int *isuppz, double *work,
+      33             :                                     int *lwork, int *iwork, int *liwork, int *info) {
+      34      556394 :   plumed_lapack_dsyevr(jobz,range,uplo,n,a,lda,vl,vu,il,iu,abstol,m,w,z__,ldz,isuppz,work,lwork,iwork,liwork,info);
+      35      556394 : }
+      36             : 
+      37             : 
+      38             : }
+      39             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.h.func-sort-c.html b/coverage/tools/Tensor.h.func-sort-c.html new file mode 100644 index 000000000000..121101ab3daf --- /dev/null +++ b/coverage/tools/Tensor.h.func-sort-c.html @@ -0,0 +1,345 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tensor.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14414996.6 %
Date:2024-02-22 21:58:45Functions:576883.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJffffffffEEEdDpT_0
_ZN4PLMDlsILj3ELj3EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDlsILj4ELj4EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDdvILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d254
_ZN4PLMD10diagMatSymILj3ELj3EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE400
_ZN4PLMD10diagMatSymILj4ELj4EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE7074
_ZNK4PLMD13TensorGenericILj3ELj3EEpsEv21229
_ZNK4PLMD13TensorGenericILj3ELj3EE6getColEj24300
_ZN4PLMD13TensorGenericILj3ELj3EE6setColEjRKNS_13VectorGenericILj3EEE29160
_ZN4PLMD12VcrossTensorERKNS_13TensorGenericILj3ELj3EEERKNS_13VectorGenericILj3EEE48138
_ZN4PLMD8deriNormERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE48138
_ZNK4PLMD13TensorGenericILj3ELj3EEngEv63485
_ZNK4PLMD13TensorGenericILj3ELj3EE7inverseEv127433
_ZN4PLMD12VcrossTensorERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE144414
_ZNK4PLMD13TensorGenericILj3ELj3EE11determinantEv195796
_ZN4PLMD13TensorGenericILj3ELj3EE4zeroEv259913
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS3_IXT0_EXT1_EEERKNS1_IXT1_EEE371178
_ZN4PLMD6matmulILj3ELj4EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE384894
_ZN4PLMD10diagMatSymILj4ELj1EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE548920
_ZN4PLMD13TensorGenericILj1ELj4EEC2Ev548920
_ZNK4PLMD13TensorGenericILj4ELj4EEclEjj555994
_ZN4PLMD13TensorGenericILj4ELj4EEC2Ev608260
_ZN4PLMD9transposeILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EXT_EEE858747
_ZN4PLMDmiILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1261608
_ZN4PLMD13TensorGenericILj4ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1291728
_ZN4PLMD13TensorGenericILj3ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1596498
_ZN4PLMDplILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1730026
_ZN4PLMD10extProductILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS_13VectorGenericIXT_EEERKNS3_IXT0_EEE1747497
_ZNK4PLMD13TensorGenericILj3ELj3EE6getRowEj3202107
_ZNK4PLMD13TensorGenericILj3ELj3EE9transposeEv3440107
_ZN4PLMD13TensorGenericILj4ELj3EEclEjj3875184
_ZN4PLMD13TensorGenericILj1ELj4EEclEjj4168056
_ZN4PLMD9dcrossDv1ERKNS_13VectorGenericILj3EEES3_4338811
_ZNK4PLMD13TensorGenericILj4ELj3EEclEjj4618728
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13TensorGenericIXT_EXT1_EEERKNS1_IXT_EXT0_EEERKNS1_IXT0_EXT1_EEE4758476
_ZN4PLMD9dcrossDv2ERKNS_13VectorGenericILj3EEES3_4916467
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJddddddddEEEdDpT_9326043
_ZN4PLMD13TensorGenericILj4ELj3EEC2Ev10253394
_ZN4PLMD13TensorGenericILj3ELj3EE8identityEv13433134
_ZN4PLMD13TensorGenericILj4ELj4EEclEjj16440322
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EEE33449372
_ZN4PLMD13TensorGenericILj3ELj3EEC2Ev42446859
_ZN4PLMD13TensorGenericILj3ELj3EEpLERKS1_42578202
_ZN4PLMD13TensorGenericILj3ELj3EEmIERKS1_47074857
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE105723978
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEEdRKS2_131787438
_ZN4PLMD13TensorGenericILj3ELj3EEC2ERKNS_13VectorGenericILj3EEES5_149725200
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d155355248
_ZN4PLMD13TensorGenericILj3ELj3EEmLEd155360273
_ZN4PLMD13TensorGenericILj3ELj3EEclEjj234587670
_ZNK4PLMD13TensorGenericILj3ELj3EEclEjj5407879073
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.h.func.html b/coverage/tools/Tensor.h.func.html new file mode 100644 index 000000000000..e376bfbc95ef --- /dev/null +++ b/coverage/tools/Tensor.h.func.html @@ -0,0 +1,345 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tensor.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14414996.6 %
Date:2024-02-22 21:58:45Functions:576883.8 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10diagMatSymILj3ELj3EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE400
_ZN4PLMD10diagMatSymILj4ELj1EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE548920
_ZN4PLMD10diagMatSymILj4ELj4EEEvRKNS_13TensorGenericIXT_EXT_EEERNS_13VectorGenericIXT0_EEERNS1_IXT0_EXT_EEE7074
_ZN4PLMD10extProductILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS_13VectorGenericIXT_EEERKNS3_IXT0_EEE1747497
_ZN4PLMD12VcrossTensorERKNS_13TensorGenericILj3ELj3EEERKNS_13VectorGenericILj3EEE48138
_ZN4PLMD12VcrossTensorERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE144414
_ZN4PLMD13TensorGenericILj1ELj4EEC2Ev548920
_ZN4PLMD13TensorGenericILj1ELj4EEclEjj4168056
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJdddddddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJddddddddEEEvdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJfffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE20auxiliaryConstructorIJffffffffEEEvdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EE4zeroEv259913
_ZN4PLMD13TensorGenericILj3ELj3EE6setColEjRKNS_13VectorGenericILj3EEE29160
_ZN4PLMD13TensorGenericILj3ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1596498
_ZN4PLMD13TensorGenericILj3ELj3EE8identityEv13433134
_ZN4PLMD13TensorGenericILj3ELj3EEC2ERKNS_13VectorGenericILj3EEES5_149725200
_ZN4PLMD13TensorGenericILj3ELj3EEC2Ev42446859
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJddddddddEEEdDpT_9326043
_ZN4PLMD13TensorGenericILj3ELj3EEC2IJffffffffEEEdDpT_0
_ZN4PLMD13TensorGenericILj3ELj3EEclEjj234587670
_ZN4PLMD13TensorGenericILj3ELj3EEmIERKS1_47074857
_ZN4PLMD13TensorGenericILj3ELj3EEmLEd155360273
_ZN4PLMD13TensorGenericILj3ELj3EEpLERKS1_42578202
_ZN4PLMD13TensorGenericILj4ELj3EE6setRowEjRKNS_13VectorGenericILj3EEE1291728
_ZN4PLMD13TensorGenericILj4ELj3EEC2Ev10253394
_ZN4PLMD13TensorGenericILj4ELj3EEclEjj3875184
_ZN4PLMD13TensorGenericILj4ELj4EEC2Ev608260
_ZN4PLMD13TensorGenericILj4ELj4EEclEjj16440322
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE105723978
_ZN4PLMD6matmulILj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EEE33449372
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13TensorGenericIXT_EXT1_EEERKNS1_IXT_EXT0_EEERKNS1_IXT0_EXT1_EEE4758476
_ZN4PLMD6matmulILj3ELj3ELj3EEENS_13VectorGenericIXT_EEERKNS_13TensorGenericIXT_EXT0_EEERKNS3_IXT0_EXT1_EEERKNS1_IXT1_EEE371178
_ZN4PLMD6matmulILj3ELj4EEENS_13VectorGenericIXT_EEERKNS1_IXT0_EEERKNS_13TensorGenericIXT0_EXT_EEE384894
_ZN4PLMD8deriNormERKNS_13VectorGenericILj3EEERKNS_13TensorGenericILj3ELj3EEE48138
_ZN4PLMD9dcrossDv1ERKNS_13VectorGenericILj3EEES3_4338811
_ZN4PLMD9dcrossDv2ERKNS_13VectorGenericILj3EEES3_4916467
_ZN4PLMD9transposeILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKNS1_IXT0_EXT_EEE858747
_ZN4PLMDdvILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d254
_ZN4PLMDlsILj3ELj3EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDlsILj4ELj4EEERSoS1_RKNS_13TensorGenericIXT_EXT0_EEE0
_ZN4PLMDmiILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1261608
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_d155355248
_ZN4PLMDmlILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEEdRKS2_131787438
_ZN4PLMDplILj3ELj3EEENS_13TensorGenericIXT_EXT0_EEERKS2_S4_1730026
_ZNK4PLMD13TensorGenericILj3ELj3EE11determinantEv195796
_ZNK4PLMD13TensorGenericILj3ELj3EE6getColEj24300
_ZNK4PLMD13TensorGenericILj3ELj3EE6getRowEj3202107
_ZNK4PLMD13TensorGenericILj3ELj3EE7inverseEv127433
_ZNK4PLMD13TensorGenericILj3ELj3EE9transposeEv3440107
_ZNK4PLMD13TensorGenericILj3ELj3EEclEjj5407879073
_ZNK4PLMD13TensorGenericILj3ELj3EEngEv63485
_ZNK4PLMD13TensorGenericILj3ELj3EEpsEv21229
_ZNK4PLMD13TensorGenericILj4ELj3EEclEjj4618728
_ZNK4PLMD13TensorGenericILj4ELj4EEclEjj555994
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tensor.h.gcov.html b/coverage/tools/Tensor.h.gcov.html new file mode 100644 index 000000000000..f26ca35b4082 --- /dev/null +++ b/coverage/tools/Tensor.h.gcov.html @@ -0,0 +1,646 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tensor.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tensor.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14414996.6 %
Date:2024-02-22 21:58:45Functions:576883.8 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Tensor_h
+      23             : #define __PLUMED_tools_Tensor_h
+      24             : 
+      25             : #include "MatrixSquareBracketsAccess.h"
+      26             : #include "Vector.h"
+      27             : #include "LoopUnroller.h"
+      28             : #include "Exception.h"
+      29             : 
+      30             : #include <array>
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : /// Small class to contain local utilities.
+      35             : /// Should not be used outside of the TensorGeneric class.
+      36             : class TensorGenericAux {
+      37             : public:
+      38             : // local redefinition, just to avoid including lapack.h here
+      39             :   static void local_dsyevr(const char *jobz, const char *range, const char *uplo, int *n,
+      40             :                            double *a, int *lda, double *vl, double *vu, int *
+      41             :                            il, int *iu, double *abstol, int *m, double *w,
+      42             :                            double *z__, int *ldz, int *isuppz, double *work,
+      43             :                            int *lwork, int *iwork, int *liwork, int *info);
+      44             : };
+      45             : 
+      46             : /**
+      47             : \ingroup TOOLBOX
+      48             : Class implementing fixed size matrices of doubles
+      49             : 
+      50             : \tparam n The number rows
+      51             : \tparam m The number columns
+      52             : 
+      53             : This class implements a matrix of doubles with size fixed at
+      54             : compile time. It is useful for small fixed size objects (e.g.
+      55             : 3x3 tensors) as it does not waste space to store the vector size.
+      56             : Moreover, as the compiler knows the size, it can be completely
+      57             : opimized inline.
+      58             : Most of the loops are explicitly unrolled using PLMD::LoopUnroller class
+      59             : Matrix elements are initialized to zero by default. Notice that
+      60             : this means that constructor is a bit slow. This point might change
+      61             : in future if we find performance issues.
+      62             : It takes advantage of MatrixSquareBracketsAccess to provide both
+      63             : () and [] syntax for access.
+      64             : Several functions are declared as friends even if not necessary so as to
+      65             : properly appear in Doxygen documentation.
+      66             : 
+      67             : Aliases are defined to simplify common declarations (Tensor, Tensor2d, Tensor3d, Tensor4d).
+      68             : Also notice that some operations are only available for 3x3 tensors.
+      69             : 
+      70             : Example of usage
+      71             : \verbatim
+      72             : 
+      73             : #include "Tensor.h"
+      74             : 
+      75             : using namespace PLMD;
+      76             : 
+      77             : int main(){
+      78             :   Tensor a;
+      79             :   TensorGeneric<3,2> b;
+      80             :   TensorGeneric<3,2> c=matmul(a,b);
+      81             :   return 0;
+      82             : }
+      83             : 
+      84             : \endverbatim
+      85             : */
+      86             : template <unsigned n,unsigned m>
+      87             : class TensorGeneric:
+      88             :   public MatrixSquareBracketsAccess<TensorGeneric<n,m>,double>
+      89             : {
+      90             :   std::array<double,n*m> d;
+      91             : /// Auxiliary private function for constructor
+      92             :   void auxiliaryConstructor();
+      93             : /// Auxiliary private function for constructor
+      94             :   template<typename... Args>
+      95             :   void auxiliaryConstructor(double first,Args... arg);
+      96             : public:
+      97             : /// Constructor accepting n*m double parameters.
+      98             : /// Can be used as Tensor<2,2>(1.0,2.0,3.0,4.0)
+      99             : /// In case a wrong number of parameters is given, a static assertion will fail.
+     100             :   template<typename... Args>
+     101             :   TensorGeneric(double first,Args... arg);
+     102             : /// initialize the tensor to zero
+     103             :   TensorGeneric();
+     104             : /// initialize a tensor as an external product of two Vector
+     105             :   TensorGeneric(const VectorGeneric<n>&v1,const VectorGeneric<m>&v2);
+     106             : /// set it to zero
+     107             :   void zero();
+     108             : /// access element
+     109             :   double & operator() (unsigned i,unsigned j);
+     110             : /// access element
+     111             :   const double & operator() (unsigned i,unsigned j)const;
+     112             : /// increment
+     113             :   TensorGeneric& operator +=(const TensorGeneric<n,m>& b);
+     114             : /// decrement
+     115             :   TensorGeneric& operator -=(const TensorGeneric<n,m>& b);
+     116             : /// multiply
+     117             :   TensorGeneric& operator *=(double);
+     118             : /// divide
+     119             :   TensorGeneric& operator /=(double);
+     120             : /// return +t
+     121             :   TensorGeneric operator +()const;
+     122             : /// return -t
+     123             :   TensorGeneric operator -()const;
+     124             : /// set j-th column
+     125             :   TensorGeneric& setCol(unsigned j,const VectorGeneric<n> & c);
+     126             : /// set i-th row
+     127             :   TensorGeneric& setRow(unsigned i,const VectorGeneric<m> & r);
+     128             : /// get j-th column
+     129             :   VectorGeneric<n> getCol(unsigned j)const;
+     130             : /// get i-th row
+     131             :   VectorGeneric<m> getRow(unsigned i)const;
+     132             : /// return t1+t2
+     133             :   template<unsigned n_,unsigned m_>
+     134             :   friend TensorGeneric<n_,m_> operator+(const TensorGeneric<n_,m_>&,const TensorGeneric<n_,m_>&);
+     135             : /// return t1+t2
+     136             :   template<unsigned n_,unsigned m_>
+     137             :   friend TensorGeneric<n_,m_> operator-(const TensorGeneric<n_,m_>&,const TensorGeneric<n_,m_>&);
+     138             : /// scale the tensor by a factor s
+     139             :   template<unsigned n_,unsigned m_>
+     140             :   friend TensorGeneric<n_,m_> operator*(double,const TensorGeneric<n_,m_>&);
+     141             : /// scale the tensor by a factor s
+     142             :   template<unsigned n_,unsigned m_>
+     143             :   friend TensorGeneric<n_,m_> operator*(const TensorGeneric<n_,m_>&,double s);
+     144             : /// scale the tensor by a factor 1/s
+     145             :   template<unsigned n_,unsigned m_>
+     146             :   friend TensorGeneric<n_,m_> operator/(const TensorGeneric<n_,m_>&,double s);
+     147             : /// returns the determinant
+     148             :   double determinant()const;
+     149             : /// return an identity tensor
+     150             :   static TensorGeneric<n,n> identity();
+     151             : /// return the matrix inverse
+     152             :   TensorGeneric inverse()const;
+     153             : /// return the transpose matrix
+     154             :   TensorGeneric<m,n> transpose()const;
+     155             : /// matrix-matrix multiplication
+     156             :   template<unsigned n_,unsigned m_,unsigned l_>
+     157             :   friend TensorGeneric<n_,l_> matmul(const TensorGeneric<n_,m_>&,const TensorGeneric<m_,l_>&);
+     158             : /// matrix-vector multiplication
+     159             :   template<unsigned n_,unsigned m_>
+     160             :   friend VectorGeneric<n_> matmul(const TensorGeneric<n_,m_>&,const VectorGeneric<m_>&);
+     161             : /// vector-matrix multiplication
+     162             :   template<unsigned n_,unsigned m_>
+     163             :   friend VectorGeneric<n_> matmul(const VectorGeneric<m_>&,const TensorGeneric<m_,n_>&);
+     164             : /// vector-vector multiplication (maps to dotProduct)
+     165             :   template<unsigned n_>
+     166             :   friend double matmul(const VectorGeneric<n_>&,const VectorGeneric<n_>&);
+     167             : /// matrix-matrix-matrix multiplication
+     168             :   template<unsigned n_,unsigned m_,unsigned l_,unsigned i_>
+     169             :   friend TensorGeneric<n_,i_> matmul(const TensorGeneric<n_,m_>&,const TensorGeneric<m_,l_>&,const TensorGeneric<l_,i_>&);
+     170             : /// matrix-matrix-vector multiplication
+     171             :   template<unsigned n_,unsigned m_,unsigned l_>
+     172             :   friend VectorGeneric<n_> matmul(const TensorGeneric<n_,m_>&,const TensorGeneric<m_,l_>&,const VectorGeneric<l_>&);
+     173             : /// vector-matrix-matrix multiplication
+     174             :   template<unsigned n_,unsigned m_,unsigned l_>
+     175             :   friend VectorGeneric<l_> matmul(const VectorGeneric<n_>&,const TensorGeneric<n_,m_>&,const TensorGeneric<m_,l_>&);
+     176             : /// vector-matrix-vector multiplication
+     177             :   template<unsigned n_,unsigned m_>
+     178             :   friend double matmul(const VectorGeneric<n_>&,const TensorGeneric<n_,m_>&,const VectorGeneric<m_>&);
+     179             : /// returns the determinant of a tensor
+     180             :   friend double determinant(const TensorGeneric<3,3>&);
+     181             : /// returns the inverse of a tensor (same as inverse())
+     182             :   friend TensorGeneric<3,3> inverse(const TensorGeneric<3,3>&);
+     183             : /// returns the transpose of a tensor (same as transpose())
+     184             :   template<unsigned n_,unsigned m_>
+     185             :   friend TensorGeneric<n_,m_> transpose(const TensorGeneric<m_,n_>&);
+     186             : /// returns the transpose of a tensor (same as TensorGeneric(const VectorGeneric&,const VectorGeneric&))
+     187             :   template<unsigned n_,unsigned m_>
+     188             :   friend TensorGeneric<n_,m_> extProduct(const VectorGeneric<n>&,const VectorGeneric<m>&);
+     189             :   friend TensorGeneric<3,3> dcrossDv1(const VectorGeneric<3>&,const VectorGeneric<3>&);
+     190             :   friend TensorGeneric<3,3> dcrossDv2(const VectorGeneric<3>&,const VectorGeneric<3>&);
+     191             :   friend TensorGeneric<3,3> VcrossTensor(const VectorGeneric<3>&,const TensorGeneric<3,3>&);
+     192             :   friend TensorGeneric<3,3> VcrossTensor(const TensorGeneric<3,3>&,const VectorGeneric<3>&);
+     193             : /// Derivative of a normalized vector
+     194             :   friend TensorGeneric<3,3> deriNorm(const VectorGeneric<3>&,const TensorGeneric<3,3>&);
+     195             : /// << operator.
+     196             : /// Allows printing tensor `t` with `std::cout<<t;`
+     197             :   template<unsigned n_,unsigned m_>
+     198             :   friend std::ostream & operator<<(std::ostream &os, const TensorGeneric<n_,m_>&);
+     199             : /// Diagonalize tensor.
+     200             : /// Syntax is the same as Matrix::diagMat.
+     201             : /// In addition, it is possible to call if with m_ smaller than n_. In this case,
+     202             : /// only the first (smaller) m_ eigenvalues and eigenvectors are retrieved.
+     203             : /// If case lapack fails (info!=0) it throws an exception.
+     204             : /// Notice that tensor is assumed to be symmetric!!!
+     205             :   template<unsigned n_,unsigned m_>
+     206             :   friend void diagMatSym(const TensorGeneric<n_,n_>&,VectorGeneric<m_>&evals,TensorGeneric<m_,n_>&evec);
+     207             : };
+     208             : 
+     209             : template <unsigned n,unsigned m>
+     210             : void TensorGeneric<n,m>::auxiliaryConstructor()
+     211             : {}
+     212             : 
+     213             : template <unsigned n,unsigned m>
+     214             : template<typename... Args>
+     215    83934387 : void TensorGeneric<n,m>::auxiliaryConstructor(double first,Args... arg)
+     216             : {
+     217    83934387 :   d[n*m-(sizeof...(Args))-1]=first;
+     218    74608344 :   auxiliaryConstructor(arg...);
+     219    83934387 : }
+     220             : 
+     221             : template <unsigned n,unsigned m>
+     222             : template<typename... Args>
+     223     9326043 : TensorGeneric<n,m>::TensorGeneric(double first,Args... arg)
+     224             : {
+     225             :   static_assert((sizeof...(Args))+1==n*m,"you are trying to initialize a Tensor with the wrong number of arguments");
+     226     9326043 :   auxiliaryConstructor(first,arg...);
+     227     9326043 : }
+     228             : 
+     229             : template<unsigned n,unsigned m>
+     230    53857433 : TensorGeneric<n,m>::TensorGeneric() {
+     231    53857433 :   LoopUnroller<n*m>::_zero(d.data());
+     232    53857433 : }
+     233             : 
+     234             : template<unsigned n,unsigned m>
+     235   149725200 : TensorGeneric<n,m>::TensorGeneric(const VectorGeneric<n>&v1,const VectorGeneric<m>&v2) {
+     236  1946427600 :   for(unsigned i=0; i<n; i++)for(unsigned j=0; j<m; j++)d[i*m+j]=v1[i]*v2[j];
+     237   149725200 : }
+     238             : 
+     239             : template<unsigned n,unsigned m>
+     240      259913 : void TensorGeneric<n,m>::zero() {
+     241      259913 :   LoopUnroller<n*m>::_zero(d.data());
+     242      259913 : }
+     243             : 
+     244             : template<unsigned n,unsigned m>
+     245   259071232 : double & TensorGeneric<n,m>::operator() (unsigned i,unsigned j) {
+     246             : #ifdef _GLIBCXX_DEBUG
+     247             : // index i is implicitly checked by the std::array class
+     248             :   plumed_assert(j<m);
+     249             : #endif
+     250   259071232 :   return d[m*i+j];
+     251             : }
+     252             : 
+     253             : template<unsigned n,unsigned m>
+     254  5413053795 : const double & TensorGeneric<n,m>::operator() (unsigned i,unsigned j)const {
+     255             : #ifdef _GLIBCXX_DEBUG
+     256             : // index i is implicitly checked by the std::array class
+     257             :   plumed_assert(j<m);
+     258             : #endif
+     259  5413053795 :   return d[m*i+j];
+     260             : }
+     261             : 
+     262             : template<unsigned n,unsigned m>
+     263    42578202 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator +=(const TensorGeneric<n,m>& b) {
+     264    42578202 :   LoopUnroller<n*m>::_add(d.data(),b.d.data());
+     265    42578202 :   return *this;
+     266             : }
+     267             : 
+     268             : template<unsigned n,unsigned m>
+     269    47074857 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator -=(const TensorGeneric<n,m>& b) {
+     270    47074857 :   LoopUnroller<n*m>::_sub(d.data(),b.d.data());
+     271    47074857 :   return *this;
+     272             : }
+     273             : 
+     274             : template<unsigned n,unsigned m>
+     275   155360273 : TensorGeneric<n,m>& TensorGeneric<n,m>::operator *=(double s) {
+     276   155360273 :   LoopUnroller<n*m>::_mul(d.data(),s);
+     277   155360273 :   return *this;
+     278             : }
+     279             : 
+     280             : template<unsigned n,unsigned m>
+     281             : TensorGeneric<n,m>& TensorGeneric<n,m>::operator /=(double s) {
+     282             :   LoopUnroller<n*m>::_mul(d.data(),1.0/s);
+     283             :   return *this;
+     284             : }
+     285             : 
+     286             : template<unsigned n,unsigned m>
+     287       21229 : TensorGeneric<n,m> TensorGeneric<n,m>::operator+()const {
+     288       21229 :   return *this;
+     289             : }
+     290             : 
+     291             : template<unsigned n,unsigned m>
+     292       63485 : TensorGeneric<n,m> TensorGeneric<n,m>::operator-()const {
+     293       63485 :   TensorGeneric<n,m> r;
+     294       63485 :   LoopUnroller<n*m>::_neg(r.d.data(),d.data());
+     295       63485 :   return r;
+     296             : }
+     297             : 
+     298             : template<unsigned n,unsigned m>
+     299       29160 : TensorGeneric<n,m>& TensorGeneric<n,m>::setCol(unsigned j,const VectorGeneric<n> & c) {
+     300      116640 :   for(unsigned i=0; i<n; ++i) (*this)(i,j)=c(i);
+     301       29160 :   return *this;
+     302             : }
+     303             : 
+     304             : template<unsigned n,unsigned m>
+     305     2888226 : TensorGeneric<n,m>& TensorGeneric<n,m>::setRow(unsigned i,const VectorGeneric<m> & r) {
+     306    11552904 :   for(unsigned j=0; j<m; ++j) (*this)(i,j)=r(j);
+     307     2888226 :   return *this;
+     308             : }
+     309             : 
+     310             : template<unsigned n,unsigned m>
+     311       24300 : VectorGeneric<n> TensorGeneric<n,m>::getCol(unsigned j)const {
+     312       24300 :   VectorGeneric<n> v;
+     313       97200 :   for(unsigned i=0; i<n; ++i) v(i)=(*this)(i,j);
+     314       24300 :   return v;
+     315             : }
+     316             : 
+     317             : template<unsigned n,unsigned m>
+     318     3202107 : VectorGeneric<m> TensorGeneric<n,m>::getRow(unsigned i)const {
+     319     3202107 :   VectorGeneric<m> v;
+     320    12808428 :   for(unsigned j=0; j<m; ++j) v(j)=(*this)(i,j);
+     321     3202107 :   return v;
+     322             : }
+     323             : 
+     324             : template<unsigned n,unsigned m>
+     325     1730026 : TensorGeneric<n,m> operator+(const TensorGeneric<n,m>&t1,const TensorGeneric<n,m>&t2) {
+     326     1730026 :   TensorGeneric<n,m> t(t1);
+     327     1730026 :   t+=t2;
+     328     1730026 :   return t;
+     329             : }
+     330             : 
+     331             : template<unsigned n,unsigned m>
+     332     1261608 : TensorGeneric<n,m> operator-(const TensorGeneric<n,m>&t1,const TensorGeneric<n,m>&t2) {
+     333     1261608 :   TensorGeneric<n,m> t(t1);
+     334     1261608 :   t-=t2;
+     335     1261608 :   return t;
+     336             : }
+     337             : 
+     338             : template<unsigned n,unsigned m>
+     339   155355248 : TensorGeneric<n,m> operator*(const TensorGeneric<n,m>&t1,double s) {
+     340   155355248 :   TensorGeneric<n,m> t(t1);
+     341   155355248 :   t*=s;
+     342   155355248 :   return t;
+     343             : }
+     344             : 
+     345             : template<unsigned n,unsigned m>
+     346   131787438 : TensorGeneric<n,m> operator*(double s,const TensorGeneric<n,m>&t1) {
+     347   131787438 :   return t1*s;
+     348             : }
+     349             : 
+     350             : template<unsigned n,unsigned m>
+     351         254 : TensorGeneric<n,m> operator/(const TensorGeneric<n,m>&t1,double s) {
+     352         254 :   return t1*(1.0/s);
+     353             : }
+     354             : 
+     355             : template<>
+     356             : inline
+     357      195796 : double TensorGeneric<3,3>::determinant()const {
+     358             :   return
+     359      195796 :     d[0]*d[4]*d[8]
+     360      195796 :     + d[1]*d[5]*d[6]
+     361      195796 :     + d[2]*d[3]*d[7]
+     362      195796 :     - d[0]*d[5]*d[7]
+     363      195796 :     - d[1]*d[3]*d[8]
+     364      195796 :     - d[2]*d[4]*d[6];
+     365             : }
+     366             : 
+     367             : template<unsigned n,unsigned m>
+     368             : inline
+     369    13433134 : TensorGeneric<n,n> TensorGeneric<n,m>::identity() {
+     370    13433134 :   TensorGeneric<n,n> t;
+     371    53732536 :   for(unsigned i=0; i<n; i++) t(i,i)=1.0;
+     372    13433134 :   return t;
+     373             : }
+     374             : 
+     375             : template<unsigned n,unsigned m>
+     376     3440107 : TensorGeneric<m,n> TensorGeneric<n,m>::transpose()const {
+     377     3440107 :   TensorGeneric<m,n> t;
+     378    44721391 :   for(unsigned i=0; i<m; i++)for(unsigned j=0; j<n; j++) t(i,j)=(*this)(j,i);
+     379     3440107 :   return t;
+     380             : }
+     381             : 
+     382             : template<>
+     383             : inline
+     384      127433 : TensorGeneric<3,3> TensorGeneric<3,3>::inverse()const {
+     385      127433 :   TensorGeneric t;
+     386      127433 :   double invdet=1.0/determinant();
+     387     1656629 :   for(unsigned i=0; i<3; i++) for(unsigned j=0; j<3; j++)
+     388     1146897 :       t(j,i)=invdet*(   (*this)((i+1)%3,(j+1)%3)*(*this)((i+2)%3,(j+2)%3)
+     389     1146897 :                         -(*this)((i+1)%3,(j+2)%3)*(*this)((i+2)%3,(j+1)%3));
+     390      127433 :   return t;
+     391             : }
+     392             : 
+     393             : template<unsigned n,unsigned m,unsigned l>
+     394     4758476 : TensorGeneric<n,l> matmul(const TensorGeneric<n,m>&a,const TensorGeneric<m,l>&b) {
+     395     4758476 :   TensorGeneric<n,l> t;
+     396   190339040 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<l; j++) for(unsigned k=0; k<m; k++) {
+     397   128478852 :         t(i,j)+=a(i,k)*b(k,j);
+     398             :       }
+     399     4758476 :   return t;
+     400             : }
+     401             : 
+     402             : template<unsigned n,unsigned m>
+     403    33449372 : VectorGeneric<n> matmul(const TensorGeneric<n,m>&a,const VectorGeneric<m>&b) {
+     404    33449372 :   VectorGeneric<n> t;
+     405   434841836 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<m; j++) t(i)+=a(i,j)*b(j);
+     406    33449372 :   return t;
+     407             : }
+     408             : 
+     409             : template<unsigned n,unsigned m>
+     410   106108872 : VectorGeneric<n> matmul(const VectorGeneric<m>&a,const TensorGeneric<m,n>&b) {
+     411   106108872 :   VectorGeneric<n> t;
+     412  1380570018 :   for(unsigned i=0; i<n; i++) for(unsigned j=0; j<m; j++) t(i)+=a(j)*b(j,i);
+     413   106108872 :   return t;
+     414             : }
+     415             : 
+     416             : template<unsigned n_>
+     417             : double matmul(const VectorGeneric<n_>&a,const VectorGeneric<n_>&b) {
+     418             :   return dotProduct(a,b);
+     419             : }
+     420             : 
+     421             : template<unsigned n,unsigned m,unsigned l,unsigned i>
+     422             : TensorGeneric<n,i> matmul(const TensorGeneric<n,m>&a,const TensorGeneric<m,l>&b,const TensorGeneric<l,i>&c) {
+     423             :   return matmul(matmul(a,b),c);
+     424             : }
+     425             : 
+     426             : template<unsigned n,unsigned m,unsigned l>
+     427      371178 : VectorGeneric<n> matmul(const TensorGeneric<n,m>&a,const TensorGeneric<m,l>&b,const VectorGeneric<l>&c) {
+     428      371178 :   return matmul(matmul(a,b),c);
+     429             : }
+     430             : 
+     431             : template<unsigned n,unsigned m,unsigned l>
+     432             : VectorGeneric<l> matmul(const VectorGeneric<n>&a,const TensorGeneric<n,m>&b,const TensorGeneric<m,l>&c) {
+     433             :   return matmul(matmul(a,b),c);
+     434             : }
+     435             : 
+     436             : template<unsigned n,unsigned m>
+     437             : double matmul(const VectorGeneric<n>&a,const TensorGeneric<n,m>&b,const VectorGeneric<m>&c) {
+     438             :   return matmul(matmul(a,b),c);
+     439             : }
+     440             : 
+     441             : inline
+     442             : double determinant(const TensorGeneric<3,3>&t) {
+     443         417 :   return t.determinant();
+     444             : }
+     445             : 
+     446             : inline
+     447             : TensorGeneric<3,3> inverse(const TensorGeneric<3,3>&t) {
+     448       63950 :   return t.inverse();
+     449             : }
+     450             : 
+     451             : template<unsigned n,unsigned m>
+     452      858747 : TensorGeneric<n,m> transpose(const TensorGeneric<m,n>&t) {
+     453      858747 :   return t.transpose();
+     454             : }
+     455             : 
+     456             : template<unsigned n,unsigned m>
+     457     1747497 : TensorGeneric<n,m> extProduct(const VectorGeneric<n>&v1,const VectorGeneric<m>&v2) {
+     458     1747497 :   return TensorGeneric<n,m>(v1,v2);
+     459             : }
+     460             : 
+     461             : inline
+     462     4338811 : TensorGeneric<3,3> dcrossDv1(const VectorGeneric<3>&v1,const VectorGeneric<3>&v2) {
+     463             :   (void) v1; // this is to avoid warnings. still the syntax of this function is a bit dummy...
+     464             :   return TensorGeneric<3,3>(
+     465             :            0.0, v2[2],-v2[1],
+     466     4338811 :            -v2[2],   0.0, v2[0],
+     467     4338811 :            v2[1],-v2[0],   0.0);
+     468             : }
+     469             : 
+     470             : inline
+     471     4916467 : TensorGeneric<3,3> dcrossDv2(const VectorGeneric<3>&v1,const VectorGeneric<3>&v2) {
+     472             :   (void) v2; // this is to avoid warnings. still the syntax of this function is a bit dummy...
+     473             :   return TensorGeneric<3,3>(
+     474             :            0.0,-v1[2],v1[1],
+     475     4916467 :            v1[2],0.0,-v1[0],
+     476     4916467 :            -v1[1],v1[0],0.0);
+     477             : }
+     478             : 
+     479             : template<unsigned n,unsigned m>
+     480           0 : std::ostream & operator<<(std::ostream &os, const TensorGeneric<n,m>& t) {
+     481           0 :   for(unsigned i=0; i<n; i++)for(unsigned j=0; j<m; j++) {
+     482           0 :       if(i!=(n-1) || j!=(m-1)) os<<t(i,j)<<" ";
+     483           0 :       else os<<t(i,j);
+     484             :     }
+     485           0 :   return os;
+     486             : }
+     487             : 
+     488             : /// \ingroup TOOLBOX
+     489             : typedef TensorGeneric<1,1> Tensor1d;
+     490             : /// \ingroup TOOLBOX
+     491             : typedef TensorGeneric<2,2> Tensor2d;
+     492             : /// \ingroup TOOLBOX
+     493             : typedef TensorGeneric<3,3> Tensor3d;
+     494             : /// \ingroup TOOLBOX
+     495             : typedef TensorGeneric<4,4> Tensor4d;
+     496             : /// \ingroup TOOLBOX
+     497             : typedef TensorGeneric<5,5> Tensor5d;
+     498             : /// \ingroup TOOLBOX
+     499             : typedef Tensor3d Tensor;
+     500             : 
+     501             : inline
+     502      144414 : TensorGeneric<3,3> VcrossTensor(const VectorGeneric<3>&v1,const TensorGeneric<3,3>&v2) {
+     503             : 
+     504      144414 :   TensorGeneric<3,3> t;
+     505      577656 :   for(unsigned i=0; i<3; i++) {
+     506      433242 :     t.setRow(i,matmul(dcrossDv2(v1,v1),v2.getRow(i)));
+     507             :   }
+     508      144414 :   return t;
+     509             : }
+     510             : 
+     511             : inline
+     512       48138 : TensorGeneric<3,3> VcrossTensor(const TensorGeneric<3,3>&v2,const VectorGeneric<3>&v1) {
+     513       48138 :   TensorGeneric<3,3> t;
+     514      192552 :   for(unsigned i=0; i<3; i++) {
+     515      144414 :     t.setRow(i,-matmul(dcrossDv2(v1,v1),v2.getRow(i)));
+     516             :   }
+     517       48138 :   return t;
+     518             : }
+     519             : 
+     520             : 
+     521             : inline
+     522       48138 : TensorGeneric<3,3> deriNorm(const VectorGeneric<3>&v1,const TensorGeneric<3,3>&v2) {
+     523             :   // delta(v) = delta(v1/v1.norm) = 1/v1.norm*(delta(v1) - (v.delta(v1))cross v;
+     524       48138 :   double over_norm = 1./v1.modulo();
+     525       48138 :   return over_norm*(v2 - over_norm*over_norm*(extProduct(matmul(v2,v1),v1)));
+     526             : }
+     527             : 
+     528             : template<unsigned n,unsigned m>
+     529      556394 : void diagMatSym(const TensorGeneric<n,n>&mat,VectorGeneric<m>&evals,TensorGeneric<m,n>&evec) {
+     530             :   // some guess number to make sure work is large enough.
+     531             :   // for correctness it should be >=20. However, it is recommended to be the block size.
+     532             :   // I put some likely exaggerated number
+     533             :   constexpr int bs=100;
+     534             :   // temporary data, on stack so as to avoid allocations
+     535             :   std::array<int,10*n> iwork;
+     536             :   std::array<double,(6+bs)*n> work;
+     537             :   std::array<int,2*m> isup;
+     538      556394 :   int nn=n;              // dimension of matrix
+     539      556394 :   double vl=0.0, vu=1.0; // ranges - not used
+     540      556394 :   int one=1,mm=m;        // minimum and maximum index
+     541      556394 :   double abstol=0.0;     // tolerance
+     542      556394 :   int mout=0;            // number of eigenvalues found (same as mm)
+     543      556394 :   int info=0;            // result
+     544      556394 :   int liwork=iwork.size();
+     545      556394 :   int lwork=work.size();
+     546      556394 :   TensorGenericAux::local_dsyevr("V", (n==m?"A":"I"), "U", &nn, const_cast<double*>(&mat[0][0]), &nn, &vl, &vu, &one, &mm,
+     547      556394 :                                  &abstol, &mout, &evals[0], &evec[0][0], &nn,
+     548             :                                  isup.data(), work.data(), &lwork, iwork.data(), &liwork, &info);
+     549      556394 :   if(info!=0) plumed_error()<<"Error diagonalizing matrix\n"
+     550             :                               <<"Matrix:\n"<<mat<<"\n"
+     551             :                               <<"Info: "<<info<<"\n";
+     552      556394 :   plumed_assert(mout==m);
+     553             :   // This changes eigenvectors so that the first non-null element
+     554             :   // of each of them is positive
+     555             :   // We can do it because the phase is arbitrary, and helps making
+     556             :   // the result reproducible
+     557     1134810 :   for(unsigned i=0; i<m; ++i) {
+     558             :     unsigned j=0;
+     559      578516 :     for(j=0; j<n; j++) if(evec(i,j)*evec(i,j)>1e-14) break;
+     560      946883 :     if(j<n) if(evec(i,j)<0.0) for(j=0; j<n; j++) evec(i,j)*=-1;
+     561             :   }
+     562      556394 : }
+     563             : 
+     564             : static_assert(sizeof(Tensor)==9*sizeof(double), "code cannot work if this is not satisfied");
+     565             : 
+     566             : }
+     567             : 
+     568             : #endif
+     569             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.cpp.func-sort-c.html b/coverage/tools/Tools.cpp.func-sort-c.html new file mode 100644 index 000000000000..ff4c0697b06b --- /dev/null +++ b/coverage/tools/Tools.cpp.func-sort-c.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:26529290.8 %
Date:2024-02-22 21:58:45Functions:535793.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools12convertToAnyIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools13convertToRealIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERf0
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclEPKc1
_ZN4PLMD5Tools12convertToAnyIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3
_ZN4PLMD5Tools12convertToIntIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl3
_ZN4PLMD12_GLOBAL__N_1L22process_all_exceptionsIRNS0_21process_one_exceptionEEEvOT_14
_ZN4PLMD5Tools7bessel0ERKd14
_ZN4PLMD5Tools12convertToAnyIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_54
_ZN4PLMD5Tools12convertToIntIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_54
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy54
_ZN4PLMD5Tools12convertToAnyIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_85
_ZN4PLMD5Tools12convertToIntIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_85
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx85
_ZN4PLMD5Tools12convertToAnyImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_97
_ZN4PLMD5Tools12convertToIntImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_97
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm97
_ZN4PLMD12_GLOBAL__N_1L22process_all_exceptionsINS0_21process_one_exceptionEEEvOT_120
_ZN4PLMD5Tools28concatenateExceptionMessagesB5cxx11Ev120
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKSt9exception133
_ZN4PLMD12_GLOBAL__N_121process_one_exception6updateEv134
_ZN4PLMD5Tools16DirectoryChangerD2Ev520
_ZN4PLMD5Tools16DirectoryChangerC2EPKc521
_ZN4PLMD5Tools5ltrimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1080
_ZN4PLMD5Tools12convertToAnyIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools13convertToRealIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERe1208
_ZN4PLMD5Tools29stripLeadingAndTrailingBlanksERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4316
_ZN4PLMD5Tools2lsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7178
_ZN4PLMD5Tools12convertToIntIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_10654
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj10654
_ZN4PLMD5Tools9extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11674
_ZN4PLMD5Tools15interpretRangesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE11840
_ZN4PLMD5Tools13getParsedLineERNS_5IFileERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEb15005
_ZN4PLMD5Tools12molfile_lockEv18842
_ZN4PLMD5Tools14interpretLabelERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE21855
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_131590
_ZN4PLMD5Tools11findKeywordERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_135729
_ZN4PLMD5Tools6getKeyERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS7_i169702
_ZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_456495
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberE646108
_ZN4PLMD5Tools12convertToAnyIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_656762
_ZN4PLMD5Tools4trimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE951210
_ZN4PLMD5Tools9startWithERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1064317
_ZZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_ENKUlccE_clEcc1096794
_ZN4PLMD5Tools14getWordsSimpleERNS_3gch12small_vectorISt17basic_string_viewIcSt11char_traitsIcEELj2ESaIS6_EEES6_1132651
_ZN4PLMD5Tools12trimCommentsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1356714
_ZN4PLMD5Tools12convertToIntIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2223526
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2223526
_ZN4PLMD5Tools12convertToAnyIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2226239
_ZN4PLMD5Tools7getlineEP8_IO_FILERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2737366
_ZN4PLMD5Tools8getWordsB5cxx11ESt17basic_string_viewIcSt11char_traitsIcEEPKcPiS6_RKb2761725
_ZN4PLMD5Tools12convertToAnyIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14301514
_ZN4PLMD5Tools13convertToRealIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14301514
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd14301514
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.cpp.func.html b/coverage/tools/Tools.cpp.func.html new file mode 100644 index 000000000000..126ce329b99a --- /dev/null +++ b/coverage/tools/Tools.cpp.func.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:26529290.8 %
Date:2024-02-22 21:58:45Functions:535793.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD12_GLOBAL__N_121process_one_exception6updateEv134
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclEPKc1
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD12_GLOBAL__N_121process_one_exceptionclERKSt9exception133
_ZN4PLMD12_GLOBAL__N_1L22process_all_exceptionsINS0_21process_one_exceptionEEEvOT_120
_ZN4PLMD12_GLOBAL__N_1L22process_all_exceptionsIRNS0_21process_one_exceptionEEEvOT_14
_ZN4PLMD5Tools11findKeywordERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_135729
_ZN4PLMD5Tools12convertToAnyIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14301514
_ZN4PLMD5Tools12convertToAnyIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools12convertToAnyIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools12convertToAnyIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2226239
_ZN4PLMD5Tools12convertToAnyIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_656762
_ZN4PLMD5Tools12convertToAnyIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3
_ZN4PLMD5Tools12convertToAnyImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_97
_ZN4PLMD5Tools12convertToAnyIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_85
_ZN4PLMD5Tools12convertToAnyIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_54
_ZN4PLMD5Tools12convertToIntIiEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_2223526
_ZN4PLMD5Tools12convertToIntIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_10654
_ZN4PLMD5Tools12convertToIntIlEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_3
_ZN4PLMD5Tools12convertToIntImEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_97
_ZN4PLMD5Tools12convertToIntIxEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_85
_ZN4PLMD5Tools12convertToIntIyEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_54
_ZN4PLMD5Tools12molfile_lockEv18842
_ZN4PLMD5Tools12trimCommentsERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1356714
_ZN4PLMD5Tools13convertToRealIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_14301514
_ZN4PLMD5Tools13convertToRealIeEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_1208
_ZN4PLMD5Tools13convertToRealIfEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_0
_ZN4PLMD5Tools13getParsedLineERNS_5IFileERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS9_EEb15005
_ZN4PLMD5Tools14getWordsSimpleERNS_3gch12small_vectorISt17basic_string_viewIcSt11char_traitsIcEELj2ESaIS6_EEES6_1132651
_ZN4PLMD5Tools14interpretLabelERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE21855
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERNS_10AtomNumberE646108
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS6_131590
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERd14301514
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERe1208
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERf0
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERi2223526
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERj10654
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERl3
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERm97
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERx85
_ZN4PLMD5Tools15convertNoexceptERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERy54
_ZN4PLMD5Tools15interpretRangesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EE11840
_ZN4PLMD5Tools16DirectoryChangerC2EPKc521
_ZN4PLMD5Tools16DirectoryChangerD2Ev520
_ZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_456495
_ZN4PLMD5Tools28concatenateExceptionMessagesB5cxx11Ev120
_ZN4PLMD5Tools29stripLeadingAndTrailingBlanksERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4316
_ZN4PLMD5Tools2lsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7178
_ZN4PLMD5Tools4trimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE951210
_ZN4PLMD5Tools5ltrimERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE1080
_ZN4PLMD5Tools6getKeyERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_RS7_i169702
_ZN4PLMD5Tools7bessel0ERKd14
_ZN4PLMD5Tools7getlineEP8_IO_FILERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2737366
_ZN4PLMD5Tools8getWordsB5cxx11ESt17basic_string_viewIcSt11char_traitsIcEEPKcPiS6_RKb2761725
_ZN4PLMD5Tools9extensionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE11674
_ZN4PLMD5Tools9startWithERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_1064317
_ZZN4PLMD5Tools23caseInSensStringCompareERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_ENKUlccE_clEcc1096794
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.cpp.gcov.html b/coverage/tools/Tools.cpp.gcov.html new file mode 100644 index 000000000000..eb1d67bb0171 --- /dev/null +++ b/coverage/tools/Tools.cpp.gcov.html @@ -0,0 +1,597 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tools.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:26529290.8 %
Date:2024-02-22 21:58:45Functions:535793.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Tools.h"
+      23             : #include "AtomNumber.h"
+      24             : #include "Exception.h"
+      25             : #include "IFile.h"
+      26             : #include "lepton/Lepton.h"
+      27             : #include <cstring>
+      28             : #include <iostream>
+      29             : #include <map>
+      30             : #include <iomanip>
+      31             : #include <filesystem>
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : template<class T>
+      36    17185962 : bool Tools::convertToAny(const std::string & str,T & t) {
+      37    32145685 :   std::istringstream istr(str.c_str());
+      38    17185962 :   bool ok=static_cast<bool>(istr>>t);
+      39    17185962 :   if(!ok) return false;
+      40             :   std::string remaining;
+      41    15075593 :   istr>>remaining;
+      42    15075593 :   return remaining.length()==0;
+      43    17185962 : }
+      44             : 
+      45     2223526 : bool Tools::convertNoexcept(const std::string & str,int & t) {
+      46     2223526 :   return convertToInt(str,t);
+      47             : }
+      48             : 
+      49           3 : bool Tools::convertNoexcept(const std::string & str,long int & t) {
+      50           3 :   return convertToInt(str,t);
+      51             : }
+      52             : 
+      53          85 : bool Tools::convertNoexcept(const std::string & str,long long int & t) {
+      54          85 :   return convertToInt(str,t);
+      55             : }
+      56             : 
+      57       10654 : bool Tools::convertNoexcept(const std::string & str,unsigned & t) {
+      58       10654 :   return convertToInt(str,t);
+      59             : }
+      60             : 
+      61          97 : bool Tools::convertNoexcept(const std::string & str,long unsigned & t) {
+      62          97 :   return convertToInt(str,t);
+      63             : }
+      64             : 
+      65          54 : bool Tools::convertNoexcept(const std::string & str,long long unsigned & t) {
+      66          54 :   return convertToInt(str,t);
+      67             : }
+      68             : 
+      69      646108 : bool Tools::convertNoexcept(const std::string & str,AtomNumber &a) {
+      70             :   // Note: AtomNumber's are NOT converted as int, so as to
+      71             :   // avoid using lepton conversions.
+      72             :   unsigned i;
+      73      646108 :   bool r=convertToAny(str,i);
+      74      646108 :   if(r) a.setSerial(i);
+      75      646108 :   return r;
+      76             : }
+      77             : 
+      78             : template<class T>
+      79     2234419 : bool Tools::convertToInt(const std::string & str,T & t) {
+      80             :   // First try standard conversion
+      81     2234419 :   if(convertToAny(str,t)) return true;
+      82             :   // Then use lepton
+      83             :   try {
+      84     2008031 :     double r=lepton::Parser::parse(str).evaluate(lepton::Constants());
+      85             : 
+      86             :     // now sanity checks on the resulting number
+      87             : 
+      88             :     // it should not overflow the requested int type:
+      89             :     // (see https://stackoverflow.com/a/526092)
+      90     2008031 :     if(r>std::nextafter(std::numeric_limits<T>::max(), 0)) return false;
+      91     2008031 :     if(r<std::nextafter(std::numeric_limits<T>::min(), 0)) return false;
+      92             : 
+      93             :     // do the actual conversion
+      94     2008031 :     auto tmp=static_cast<T>(std::round(r));
+      95             : 
+      96             :     // it should be *very close* to itself if converted back to double
+      97     2008031 :     double diff= r-static_cast<double>(tmp);
+      98     2008031 :     if(diff*diff > 1e-20) return false;
+      99             :     // this is to accomodate small numerical errors and allow e.g. exp(log(7)) to be integer
+     100             : 
+     101             :     // it should be change if incremented or decremented by one (see https://stackoverflow.com/a/43656140)
+     102     2008027 :     if(r == static_cast<double>(tmp-1)) return false;
+     103     2008026 :     if(r == static_cast<double>(tmp+1)) return false;
+     104             : 
+     105             :     // everything is fine, then store in t
+     106     2008026 :     t=tmp;
+     107     2008026 :     return true;
+     108           0 :   } catch(const PLMD::lepton::Exception& exc) {
+     109             :   }
+     110           0 :   return false;
+     111             : }
+     112             : 
+     113             : 
+     114             : template<class T>
+     115    14302722 : bool Tools::convertToReal(const std::string & str,T & t) {
+     116    14302722 :   if(convertToAny(str,t)) return true;
+     117     8378062 :   if(str=="PI" || str=="+PI" || str=="+pi" || str=="pi") {
+     118     1047297 :     t=pi; return true;
+     119     2094562 :   } else if(str=="-PI" || str=="-pi") {
+     120     1047216 :     t=-pi; return true;
+     121             :   }
+     122             :   try {
+     123          65 :     t=lepton::Parser::parse(str).evaluate(lepton::Constants());
+     124          24 :     return true;
+     125          41 :   } catch(const PLMD::lepton::Exception& exc) {
+     126             :   }
+     127          41 :   if( str.find("PI")!=std::string::npos ) {
+     128           0 :     std::size_t pi_start=str.find_first_of("PI");
+     129           0 :     if(str.substr(pi_start)!="PI") return false;
+     130           0 :     std::istringstream nstr(str.substr(0,pi_start));
+     131           0 :     T ff=0.0; bool ok=static_cast<bool>(nstr>>ff);
+     132           0 :     if(!ok) return false;
+     133           0 :     t=ff*pi;
+     134           0 :     std::string remains; nstr>>remains;
+     135           0 :     return remains.length()==0;
+     136          41 :   } else if( str.find("pi")!=std::string::npos ) {
+     137          15 :     std::size_t pi_start=str.find_first_of("pi");
+     138          30 :     if(str.substr(pi_start)!="pi") return false;
+     139          15 :     std::istringstream nstr(str.substr(0,pi_start));
+     140          15 :     T ff=0.0; bool ok=static_cast<bool>(nstr>>ff);
+     141          15 :     if(!ok) return false;
+     142          15 :     t=ff*pi;
+     143          15 :     std::string remains; nstr>>remains;
+     144          15 :     return remains.length()==0;
+     145          41 :   } else if(str=="NAN") {
+     146           0 :     t=std::numeric_limits<double>::quiet_NaN();
+     147           0 :     return true;
+     148             :   }
+     149             :   return false;
+     150             : }
+     151             : 
+     152           0 : bool Tools::convertNoexcept(const std::string & str,float & t) {
+     153           0 :   return convertToReal(str,t);
+     154             : }
+     155             : 
+     156    14301514 : bool Tools::convertNoexcept(const std::string & str,double & t) {
+     157    14301514 :   return convertToReal(str,t);
+     158             : }
+     159             : 
+     160        1208 : bool Tools::convertNoexcept(const std::string & str,long double & t) {
+     161        1208 :   return convertToReal(str,t);
+     162             : }
+     163             : 
+     164      131590 : bool Tools::convertNoexcept(const std::string & str,std::string & t) {
+     165             :   t=str;
+     166      131590 :   return true;
+     167             : }
+     168             : 
+     169     2761725 : std::vector<std::string> Tools::getWords(std::string_view line,const char* separators,int * parlevel,const char* parenthesis, const bool& delete_parenthesis) {
+     170     2761725 :   plumed_massert(std::strlen(parenthesis)==1,"multiple parenthesis type not available");
+     171     2761725 :   plumed_massert(parenthesis[0]=='(' || parenthesis[0]=='[' || parenthesis[0]=='{',
+     172             :                  "only ( [ { allowed as parenthesis");
+     173     2761725 :   if(!separators) separators=" \t\n";
+     174     2761725 :   const std::string sep(separators);
+     175     2761725 :   char openpar=parenthesis[0];
+     176             :   char closepar;
+     177             :   if(openpar=='(') closepar=')';
+     178     2761725 :   if(openpar=='[') closepar=']';
+     179     2761725 :   if(openpar=='{') closepar='}';
+     180             :   std::vector<std::string> words;
+     181             :   std::string word;
+     182             :   int parenthesisLevel=0;
+     183     2761725 :   if(parlevel) parenthesisLevel=*parlevel;
+     184   187917804 :   for(unsigned i=0; i<line.length(); i++) {
+     185             :     bool found=false;
+     186             :     bool onParenthesis=false;
+     187   185156079 :     if( (line[i]==openpar || line[i]==closepar) && delete_parenthesis ) onParenthesis=true;
+     188   185156079 :     if(line[i]==closepar) {
+     189        2729 :       parenthesisLevel--;
+     190        2729 :       plumed_assert(parenthesisLevel>=0) << "Extra closed parenthesis in '" << line << "'";
+     191             :     }
+     192   740864855 :     if(parenthesisLevel==0) for(unsigned j=0; j<sep.length(); j++) if(line[i]==sep[j]) found=true;
+     193             : // If at parenthesis level zero (outer)
+     194   185156079 :     if(!(parenthesisLevel==0 && (found||onParenthesis))) word.push_back(line[i]);
+     195             :     //if(onParenthesis) word.push_back(' ');
+     196   185156079 :     if(line[i]==openpar) parenthesisLevel++;
+     197   185156079 :     if(found && word.length()>0) {
+     198    11659685 :       if(!parlevel) plumed_assert(parenthesisLevel==0) << "Unmatching parenthesis in '" << line << "'";
+     199    11659685 :       words.push_back(word);
+     200             :       word.clear();
+     201             :     }
+     202             :   }
+     203     2761725 :   if(word.length()>0) {
+     204     2644261 :     if(!parlevel) plumed_assert(parenthesisLevel==0) << "Unmatching parenthesis in '" << line << "'";
+     205     2644261 :     words.push_back(word);
+     206             :   }
+     207     2761725 :   if(parlevel) *parlevel=parenthesisLevel;
+     208     2761725 :   return words;
+     209           0 : }
+     210             : 
+     211     1132651 : void Tools::getWordsSimple(gch::small_vector<std::string_view> & words,std::string_view line) {
+     212             :   words.clear();
+     213     1132651 :   auto ptr=line.data();
+     214     1132651 :   std::size_t size=0;
+     215    12193517 :   for(unsigned i=0; i<line.length(); i++) {
+     216    11060866 :     const bool is_separator=(line[i]==' ');
+     217    11060866 :     if(!is_separator) {
+     218    11046244 :       size++;
+     219       14622 :     } else if(size==0) {
+     220           0 :       ptr++;
+     221             :     } else {
+     222             :       words.emplace_back(ptr,size);
+     223       14622 :       ptr=&line[i]+1;
+     224       14622 :       size=0;
+     225             :     }
+     226             :   }
+     227     1132651 :   if(size>0) {
+     228             :     words.emplace_back(ptr,size);
+     229             :   }
+     230     1132651 : }
+     231             : 
+     232       15005 : bool Tools::getParsedLine(IFile& ifile,std::vector<std::string> & words, bool trimcomments) {
+     233       15005 :   std::string line("");
+     234             :   words.clear();
+     235             :   bool stat;
+     236             :   bool inside=false;
+     237       15005 :   int parlevel=0;
+     238             :   bool mergenext=false;
+     239       32649 :   while((stat=ifile.getline(line))) {
+     240       31775 :     if(trimcomments) trimComments(line);
+     241       31775 :     trim(line);
+     242       31775 :     if(line.length()==0) continue;
+     243       25834 :     std::vector<std::string> w=getWords(line,NULL,&parlevel,"{",trimcomments);
+     244       25834 :     if(!w.empty()) {
+     245       37147 :       if(inside && *(w.begin())=="...") {
+     246             :         inside=false;
+     247        1224 :         if(w.size()==2) plumed_massert(w[1]==words[0],"second word in terminating \"...\" "+w[1]+" line, if present, should be equal to first word of directive: "+words[0]);
+     248        1224 :         plumed_massert(w.size()<=2,"terminating \"...\" lines cannot consist of more than two words");
+     249        1224 :         w.clear(); if(!trimcomments) words.push_back("...");
+     250       24337 :       } else if(*(w.end()-1)=="...") {
+     251             :         inside=true;
+     252             :         w.erase(w.end()-1);
+     253             :       };
+     254             :       int i0=0;
+     255       25561 :       if(mergenext && words.size()>0 && w.size()>0) {
+     256         128 :         words[words.size()-1]+=" "+w[0];
+     257             :         i0=1;
+     258             :       }
+     259       91372 :       for(unsigned i=i0; i<w.size(); ++i) words.push_back(w[i]);
+     260             :     }
+     261       25834 :     mergenext=(parlevel>0);
+     262       25834 :     if(!inside)break;
+     263       11703 :     if(!trimcomments && parlevel==0) words.push_back("@newline");
+     264       11703 :     else if(!trimcomments) words[words.size()-1] += " @newline";
+     265       25834 :   }
+     266       15005 :   plumed_massert(parlevel==0,"non matching parenthesis");
+     267       15005 :   if(words.size()>0) return true;
+     268             :   return stat;
+     269             : }
+     270             : 
+     271             : 
+     272     2737366 : bool Tools::getline(FILE* fp,std::string & line) {
+     273             :   line="";
+     274             :   const int bufferlength=1024;
+     275             :   char buffer[bufferlength];
+     276             :   bool ret;
+     277  2805800150 :   for(int i=0; i<bufferlength; i++) buffer[i]='\0';
+     278     2737366 :   while((ret=fgets(buffer,bufferlength,fp))) {
+     279     2736628 :     line.append(buffer);
+     280     2736628 :     unsigned ss=std::strlen(buffer);
+     281     2736628 :     if(ss>0) if(buffer[ss-1]=='\n') break;
+     282             :   };
+     283     2737366 :   if(line.length()>0) if(*(line.end()-1)=='\n') line.erase(line.end()-1);
+     284     2737366 :   if(line.length()>0) if(*(line.end()-1)=='\r') line.erase(line.end()-1);
+     285     2737366 :   return ret;
+     286             : }
+     287             : 
+     288      951210 : void Tools::trim(std::string & s) {
+     289      951210 :   auto n=s.find_last_not_of(" \t");
+     290      951210 :   if(n!=std::string::npos) s.resize(n+1);
+     291      951210 : }
+     292             : 
+     293        1080 : void Tools::ltrim(std::string & s) {
+     294        1080 :   auto n=s.find_first_not_of(" \t");
+     295        1080 :   if(n!=std::string::npos) {
+     296        2160 :     s = s.substr(n, s.length()-n);
+     297             :     s.shrink_to_fit();
+     298             :   }
+     299        1080 : }
+     300             : 
+     301     1356714 : void Tools::trimComments(std::string & s) {
+     302     1356714 :   auto n=s.find_first_of("#");
+     303     1356714 :   if(n!=std::string::npos) s.resize(n);
+     304     1356714 : }
+     305             : 
+     306      456495 : bool Tools::caseInSensStringCompare(const std::string & str1, const std::string &str2)
+     307             : {
+     308      456495 :   return ((str1.size() == str2.size()) && std::equal(str1.begin(), str1.end(), str2.begin(), [](char c1, char c2) {
+     309     1096794 :     return (c1 == c2 || std::toupper(c1) == std::toupper(c2));
+     310      456495 :   }));
+     311             : }
+     312             : 
+     313      169702 : bool Tools::getKey(std::vector<std::string>& line,const std::string & key,std::string & s,int rep) {
+     314             :   s.clear();
+     315      517575 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     316      456445 :     if((*p).length()==0) continue;
+     317      456445 :     std::string x=(*p).substr(0,key.length());
+     318      456445 :     if(caseInSensStringCompare(x,key)) {
+     319      108572 :       if((*p).length()==key.length())return false;
+     320      108571 :       std::string tmp=(*p).substr(key.length(),(*p).length());
+     321             :       line.erase(p);
+     322             :       s=tmp;
+     323      108571 :       const std::string multi("@replicas:");
+     324      108571 :       if(rep>=0 && startWith(s,multi)) {
+     325          24 :         s=s.substr(multi.length(),s.length());
+     326          24 :         std::vector<std::string> words=getWords(s,"\t\n ,");
+     327          24 :         plumed_massert(rep<static_cast<int>(words.size()),"Number of fields in " + s + " not consistent with number of replicas");
+     328          24 :         s=words[rep];
+     329          24 :       }
+     330             :       return true;
+     331             :     }
+     332             :   };
+     333             :   return false;
+     334             : }
+     335             : 
+     336       11840 : void Tools::interpretRanges(std::vector<std::string>&s) {
+     337             :   std::vector<std::string> news;
+     338      252567 :   for(const auto & p :s) {
+     339      240727 :     news.push_back(p);
+     340      240727 :     size_t dash=p.find("-");
+     341      241334 :     if(dash==std::string::npos) continue;
+     342             :     int first;
+     343        3284 :     if(!Tools::convertToAny(p.substr(0,dash),first)) continue;
+     344        1035 :     int stride=1;
+     345             :     int second;
+     346        1035 :     size_t colon=p.substr(dash+1).find(":");
+     347        1035 :     if(colon!=std::string::npos) {
+     348         108 :       if(!Tools::convertToAny(p.substr(dash+1).substr(0,colon),second) ||
+     349         144 :           !Tools::convertToAny(p.substr(dash+1).substr(colon+1),stride)) continue;
+     350             :     } else {
+     351        1998 :       if(!Tools::convertToAny(p.substr(dash+1),second)) continue;
+     352             :     }
+     353        1035 :     news.resize(news.size()-1);
+     354        1035 :     if(first<=second) {
+     355        1034 :       plumed_massert(stride>0,"interpreting ranges "+ p + ", stride should be positive");
+     356      404352 :       for(int i=first; i<=second; i+=stride) {
+     357             :         std::string ss;
+     358      403318 :         convert(i,ss);
+     359      403318 :         news.push_back(ss);
+     360             :       }
+     361             :     } else {
+     362           1 :       plumed_massert(stride<0,"interpreting ranges "+ p + ", stride should be positive");
+     363           3 :       for(int i=first; i>=second; i+=stride) {
+     364             :         std::string ss;
+     365           2 :         convert(i,ss);
+     366           2 :         news.push_back(ss);
+     367             :       }
+     368             :     }
+     369             :   }
+     370       11840 :   s=news;
+     371       11840 : }
+     372             : 
+     373       21855 : void Tools::interpretLabel(std::vector<std::string>&s) {
+     374       21855 :   if(s.size()<2)return;
+     375       21530 :   std::string s0=s[0];
+     376       21530 :   unsigned l=s0.length();
+     377       21530 :   if(l<1) return;
+     378       21530 :   if(s0[l-1]==':') {
+     379             :     s[0]=s[1];
+     380       36698 :     s[1]="LABEL="+s0.substr(0,l-1);
+     381             :   }
+     382       21530 :   std::transform(s[0].begin(), s[0].end(), s[0].begin(), ::toupper);
+     383             : }
+     384             : 
+     385        7178 : std::vector<std::string> Tools::ls(const std::string&d) {
+     386             :   std::vector<std::string> result;
+     387      114230 :   for (auto const& dir_entry : std::filesystem::directory_iterator{d}) {
+     388      278088 :     result.push_back(dir_entry.path().filename());
+     389             :   }
+     390        7178 :   return result;
+     391           0 : }
+     392             : 
+     393        4316 : void Tools::stripLeadingAndTrailingBlanks( std::string& str ) {
+     394        4316 :   std::size_t first=str.find_first_not_of(' ');
+     395        4316 :   std::size_t last=str.find_last_not_of(' ');
+     396        8595 :   if( first<=last && first!=std::string::npos) str=str.substr(first,last+1);
+     397        4316 : }
+     398             : 
+     399       11674 : std::string Tools::extension(const std::string&s) {
+     400       11674 :   size_t n=s.find_last_of(".");
+     401             :   std::string ext;
+     402       11674 :   if(n!=std::string::npos && n+1<s.length() && n+5>=s.length()) {
+     403        8588 :     ext=s.substr(n+1);
+     404        8588 :     if(ext.find("/")!=std::string::npos) ext="";
+     405        8588 :     std::string base=s.substr(0,n);
+     406        8588 :     if(base.length()==0) ext="";
+     407        8588 :     if(base.length()>0 && base[base.length()-1]=='/') ext="";
+     408             :   }
+     409       11674 :   return ext;
+     410             : }
+     411             : 
+     412          14 : double Tools::bessel0( const double& val ) {
+     413          14 :   if (std::abs(val)<3.75) {
+     414           2 :     double y = Tools::fastpow( val/3.75, 2 );
+     415           2 :     return 1 + y*(3.5156229 +y*(3.0899424 + y*(1.2067492+y*(0.2659732+y*(0.0360768+y*0.0045813)))));
+     416             :   }
+     417          12 :   double ax=std::abs(val), y=3.75/ax, bx=std::exp(ax)/std::sqrt(ax);
+     418          12 :   ax=0.39894228+y*(0.01328592+y*(0.00225319+y*(-0.00157565+y*(0.00916281+y*(-0.02057706+y*(0.02635537+y*(-0.01647633+y*0.00392377)))))));
+     419          12 :   return ax*bx;
+     420             : }
+     421             : 
+     422     1064317 : bool Tools::startWith(const std::string & full,const std::string &start) {
+     423     1064317 :   return (full.substr(0,start.length())==start);
+     424             : }
+     425             : 
+     426      135729 : bool Tools::findKeyword(const std::vector<std::string>&line,const std::string&key) {
+     427      135729 :   const std::string search(key+"=");
+     428      684357 :   for(const auto & p : line) {
+     429      625592 :     if(startWith(p,search)) return true;
+     430             :   }
+     431             :   return false;
+     432             : }
+     433             : 
+     434         521 : Tools::DirectoryChanger::DirectoryChanger(const char*path):
+     435         521 :   path(std::filesystem::current_path())
+     436             : {
+     437         521 :   if(!path) return;
+     438         521 :   if(std::strlen(path)==0) return;
+     439           4 :   std::filesystem::current_path(path);
+     440             : }
+     441             : 
+     442         520 : Tools::DirectoryChanger::~DirectoryChanger() {
+     443             :   try {
+     444         520 :     std::filesystem::current_path(path);
+     445           0 :   } catch(std::filesystem::filesystem_error & e) {
+     446           0 :     std::fprintf(stderr,"+++ WARNING: cannot cd back to directory %s\n",path.c_str());
+     447           0 :   }
+     448         520 : }
+     449             : 
+     450       18842 : std::unique_ptr<std::lock_guard<std::mutex>> Tools::molfile_lock() {
+     451             :   static std::mutex mtx;
+     452       18842 :   return Tools::make_unique<std::lock_guard<std::mutex>>(mtx);
+     453             : }
+     454             : 
+     455             : /// Internal tool, I am keeping it private for now
+     456             : namespace {
+     457             : 
+     458             : class process_one_exception {
+     459             :   std::string & msg;
+     460             :   bool first=true;
+     461         134 :   void update() {
+     462         134 :     if(!first) msg+="\n\nThe above exception was the direct cause of the following exception:\n";
+     463         134 :     first=false;
+     464         134 :   }
+     465             : public:
+     466         120 :   process_one_exception(std::string & msg):
+     467         120 :     msg(msg)
+     468             :   {}
+     469         133 :   void operator()(const std::exception & e) {
+     470         133 :     update();
+     471         133 :     msg+=e.what();
+     472         133 :   }
+     473           0 :   void operator()(const std::string & e) {
+     474           0 :     update();
+     475           0 :     msg+=e;
+     476           0 :   }
+     477           1 :   void operator()(const char* e) {
+     478           1 :     update();
+     479           1 :     msg+=e;
+     480           1 :   }
+     481             : };
+     482             : 
+     483             : template<class T>
+     484         134 : static void process_all_exceptions(T&& f) {
+     485             :   try {
+     486             :     // First throw the current exception
+     487         134 :     throw;
+     488         148 :   } catch(const std::nested_exception & e) {
+     489             :     // If nested, we go recursive
+     490             :     // notice that we apply function f only if exception is also a std::exception
+     491             :     try {
+     492          14 :       e.rethrow_nested();
+     493          28 :     } catch(...) {
+     494          14 :       process_all_exceptions(f);
+     495             :     }
+     496          14 :     auto d=dynamic_cast<const std::exception*>(&e);
+     497          14 :     if(d) f(*d);
+     498         238 :   } catch(const std::exception &e) {
+     499             :     // If not nested, we end recursion
+     500         119 :     f(e);
+     501           0 :   } catch(const std::string &e) {
+     502             :     // If not nested, we end recursion
+     503           0 :     f(e);
+     504           2 :   } catch(const char* e) {
+     505             :     // If not nested, we end recursion
+     506           1 :     f(e);
+     507           0 :   } catch(...) {
+     508             :     // If not nested and of unknown type, we stop the chain
+     509             :   }
+     510         134 : }
+     511             : 
+     512             : }
+     513             : 
+     514         120 : std::string Tools::concatenateExceptionMessages() {
+     515             :   std::string msg;
+     516         120 :   process_all_exceptions(process_one_exception(msg));
+     517         120 :   return msg;
+     518             : }
+     519             : 
+     520             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.h.func-sort-c.html b/coverage/tools/Tools.h.func-sort-c.html new file mode 100644 index 000000000000..b20825895b02 --- /dev/null +++ b/coverage/tools/Tools.h.func-sort-c.html @@ -0,0 +1,281 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8510184.2 %
Date:2024-02-22 21:58:45Functions:465288.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Tools15convertNoexceptIlEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools15convertNoexceptIxEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEfEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIPciEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIxNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElEEvRKT_RT0_1
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEmEEvRKT_RT0_1
_ZN4PLMD5Tools11parseVectorIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi14
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEyEEvRKT_RT0_14
_ZN4PLMD5Tools5parseImEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i16
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEExEEvRKT_RT0_16
_ZN4PLMD5Tools11parseVectorIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi31
_ZN4PLMD5Tools11parseVectorIeEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi32
_ZN4PLMD5Tools10unique2rawINS_3ves12CoeffsMatrixEEESt6vectorIPT_SaIS6_EERKS4_ISt10unique_ptrIS5_St14default_deleteIS5_EESaISC_EE82
_ZN4PLMD5Tools5parseIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i109
_ZN4PLMD5Tools10unique2rawINS_3ves12CoeffsVectorEEESt6vectorIPT_SaIS6_EERKS4_ISt10unique_ptrIS5_St14default_deleteIS5_EESaISC_EE437
_ZN4PLMD5Tools7convertIPcjEEvRKT_RT0_811
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEvRKT_RT0_942
_ZN4PLMD5Tools5parseIeEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i1080
_ZN4PLMD5Tools15convertNoexceptImEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2436
_ZN4PLMD5Tools7convertImNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_2436
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_EEvRKT_RT0_2580
_ZN4PLMD5Tools5parseIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i4068
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_10AtomNumberEEEvRKT_RT0_5760
_ZN4PLMD5Tools11parseVectorIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi6130
_ZN4PLMD5Tools5parseIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i6467
_ZN4PLMD5Tools22FastStringUnorderedMapIiEC2ESt16initializer_listISt4pairIKSt17basic_string_viewIcSt11char_traitsIcEEiEE8514
_ZN4PLMD5Tools22FastStringUnorderedMapINS_9Stopwatch5WatchEE4convESt17basic_string_viewIcSt11char_traitsIcEE11535
_ZN4PLMD5Tools11parseVectorIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi12581
_ZN4PLMD5Tools16removeDuplicatesINS_10AtomNumberEEEvRSt6vectorIT_SaIS4_EE13447
_ZN4PLMD5Tools15convertNoexceptIdEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20865
_ZN4PLMD5Tools7convertIdNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_20865
_ZN4PLMD5Tools18mergeSortedVectorsIKSt6vectorINS_10AtomNumberESaIS3_EEEEvRKS2_IPT_SaIS8_EERS2_INS7_10value_typeESaISD_EEb21153
_ZN4PLMD5Tools5parseIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i27123
_ZN4PLMD5Tools11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RS8_IT_SaISE_EEi27973
_ZN4PLMD5Tools11set_to_zeroILj3EEEvRSt6vectorINS_13VectorGenericIXT_EEESaIS4_EE28739
_ZN4PLMDL18dp2cutoffNoStretchEv30397
_ZN4PLMD5Tools9parseFlagERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_Rb66538
_ZN4PLMD5Tools5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RT_i84045
_ZN4PLMD5Tools15convertNoexceptIjEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE279974
_ZN4PLMD5Tools7convertIjNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_279974
_ZN4PLMD5Tools22FastStringUnorderedMapIiE4convESt17basic_string_viewIcSt11char_traitsIcEE378004
_ZN4PLMD5Tools22FastStringUnorderedMapIiEixERKSt17basic_string_viewIcSt11char_traitsIcEE378004
_ZN4PLMD5Tools15convertNoexceptIiEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE439990
_ZN4PLMD5Tools7convertIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_439990
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiEEvRKT_RT0_2219089
_ZN4PLMD5Tools22FastStringUnorderedMapINS_9Stopwatch5WatchEEixERKSt17basic_string_viewIcSt11char_traitsIcEE2652845
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdEEvRKT_RT0_11956235
_ZN4PLMD5Tools10unique2rawINS_5ValueEEESt6vectorIPT_SaIS5_EERKS3_ISt10unique_ptrIS4_St14default_deleteIS4_EESaISB_EE13702951
_ZN4PLMD5Tools7fastpowEdi79178463
_ZN4PLMD5Tools3pbcEd1828652049
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.h.func.html b/coverage/tools/Tools.h.func.html new file mode 100644 index 000000000000..0d6f8da79298 --- /dev/null +++ b/coverage/tools/Tools.h.func.html @@ -0,0 +1,281 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8510184.2 %
Date:2024-02-22 21:58:45Functions:465288.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Tools10unique2rawINS_3ves12CoeffsMatrixEEESt6vectorIPT_SaIS6_EERKS4_ISt10unique_ptrIS5_St14default_deleteIS5_EESaISC_EE82
_ZN4PLMD5Tools10unique2rawINS_3ves12CoeffsVectorEEESt6vectorIPT_SaIS6_EERKS4_ISt10unique_ptrIS5_St14default_deleteIS5_EESaISC_EE437
_ZN4PLMD5Tools10unique2rawINS_5ValueEEESt6vectorIPT_SaIS5_EERKS3_ISt10unique_ptrIS4_St14default_deleteIS4_EESaISB_EE13702951
_ZN4PLMD5Tools11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RS8_IT_SaISE_EEi27973
_ZN4PLMD5Tools11parseVectorIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi12581
_ZN4PLMD5Tools11parseVectorIeEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi32
_ZN4PLMD5Tools11parseVectorIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi31
_ZN4PLMD5Tools11parseVectorIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi6130
_ZN4PLMD5Tools11parseVectorIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RS2_IT_SaISE_EEi14
_ZN4PLMD5Tools11set_to_zeroILj3EEEvRSt6vectorINS_13VectorGenericIXT_EEESaIS4_EE28739
_ZN4PLMD5Tools15convertNoexceptIdEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE20865
_ZN4PLMD5Tools15convertNoexceptIiEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE439990
_ZN4PLMD5Tools15convertNoexceptIjEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE279974
_ZN4PLMD5Tools15convertNoexceptIlEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools15convertNoexceptImEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE2436
_ZN4PLMD5Tools15convertNoexceptIxEEbT_RNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD5Tools16removeDuplicatesINS_10AtomNumberEEEvRSt6vectorIT_SaIS4_EE13447
_ZN4PLMD5Tools18mergeSortedVectorsIKSt6vectorINS_10AtomNumberESaIS3_EEEEvRKS2_IPT_SaIS8_EERS2_INS7_10value_typeESaISD_EEb21153
_ZN4PLMD5Tools22FastStringUnorderedMapINS_9Stopwatch5WatchEE4convESt17basic_string_viewIcSt11char_traitsIcEE11535
_ZN4PLMD5Tools22FastStringUnorderedMapINS_9Stopwatch5WatchEEixERKSt17basic_string_viewIcSt11char_traitsIcEE2652845
_ZN4PLMD5Tools22FastStringUnorderedMapIiE4convESt17basic_string_viewIcSt11char_traitsIcEE378004
_ZN4PLMD5Tools22FastStringUnorderedMapIiEC2ESt16initializer_listISt4pairIKSt17basic_string_viewIcSt11char_traitsIcEEiEE8514
_ZN4PLMD5Tools22FastStringUnorderedMapIiEixERKSt17basic_string_viewIcSt11char_traitsIcEE378004
_ZN4PLMD5Tools3pbcEd1828652049
_ZN4PLMD5Tools5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRSt6vectorIS7_SaIS7_EERKS7_RT_i84045
_ZN4PLMD5Tools5parseIdEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i27123
_ZN4PLMD5Tools5parseIeEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i1080
_ZN4PLMD5Tools5parseIiEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i6467
_ZN4PLMD5Tools5parseIjEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i4068
_ZN4PLMD5Tools5parseImEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i16
_ZN4PLMD5Tools5parseIxEEbRSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS8_RT_i109
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEENS_10AtomNumberEEEvRKT_RT0_5760
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES7_EEvRKT_RT0_2580
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdEEvRKT_RT0_11956235
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEfEEvRKT_RT0_0
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEiEEvRKT_RT0_2219089
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEjEEvRKT_RT0_942
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEElEEvRKT_RT0_1
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEmEEvRKT_RT0_1
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEExEEvRKT_RT0_16
_ZN4PLMD5Tools7convertINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEyEEvRKT_RT0_14
_ZN4PLMD5Tools7convertIPciEEvRKT_RT0_0
_ZN4PLMD5Tools7convertIPcjEEvRKT_RT0_811
_ZN4PLMD5Tools7convertIdNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_20865
_ZN4PLMD5Tools7convertIiNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_439990
_ZN4PLMD5Tools7convertIjNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_279974
_ZN4PLMD5Tools7convertIlNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7convertImNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_2436
_ZN4PLMD5Tools7convertIxNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKT_RT0_0
_ZN4PLMD5Tools7fastpowEdi79178463
_ZN4PLMD5Tools9parseFlagERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS7_EERKS7_Rb66538
_ZN4PLMDL18dp2cutoffNoStretchEv30397
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tools.h.gcov.html b/coverage/tools/Tools.h.gcov.html new file mode 100644 index 000000000000..d70f8fd214d0 --- /dev/null +++ b/coverage/tools/Tools.h.gcov.html @@ -0,0 +1,587 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tools.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8510184.2 %
Date:2024-02-22 21:58:45Functions:465288.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Tools_h
+      23             : #define __PLUMED_tools_Tools_h
+      24             : 
+      25             : #include "AtomNumber.h"
+      26             : #include "Vector.h"
+      27             : #include "Tensor.h"
+      28             : #include "small_vector/small_vector.h"
+      29             : #include <vector>
+      30             : #include <string>
+      31             : #include <cctype>
+      32             : #include <cstdio>
+      33             : #include <cmath>
+      34             : #include <limits>
+      35             : #include <algorithm>
+      36             : #include <sstream>
+      37             : #include <memory>
+      38             : #include <cstddef>
+      39             : #include <queue>
+      40             : #include <mutex>
+      41             : #include <filesystem>
+      42             : #include <utility>
+      43             : #include <unordered_map>
+      44             : 
+      45             : namespace PLMD {
+      46             : 
+      47             : class IFile;
+      48             : 
+      49             : /// \ingroup TOOLBOX
+      50             : /// Very small non-zero number
+      51             : const double epsilon(std::numeric_limits<double>::epsilon());
+      52             : 
+      53             : /// \ingroup TOOLBOX
+      54             : /// Boltzman constant in kj/K
+      55             : const double kBoltzmann(0.0083144621);
+      56             : 
+      57             : /// \ingroup TOOLBOX
+      58             : /// PI
+      59             : const double pi(3.141592653589793238462643383279502884197169399375105820974944592307);
+      60             : 
+      61             : const double dp2cutoff(6.25);
+      62             : 
+      63             : const double dp2cutoffA=1.00193418799744762399; // 1.0/(1-std::exp(-dp2cutoff));
+      64             : const double dp2cutoffB=-.00193418799744762399; // -std::exp(-dp2cutoff)/(1-std::exp(-dp2cutoff));
+      65             : 
+      66       30397 : inline static bool dp2cutoffNoStretch() {
+      67       30397 :   static const auto* res=std::getenv("PLUMED_DP2CUTOFF_NOSTRETCH");
+      68       30397 :   return res;
+      69             : }
+      70             : 
+      71             : /// \ingroup TOOLBOX
+      72             : /// Empty class which just contains several (static) tools
+      73             : class Tools {
+      74             : /// class to convert a string to a generic type T
+      75             :   template<class T>
+      76             :   static bool convertToAny(const std::string & str,T &t);
+      77             : /// class to convert a string to a real type T.
+      78             : /// T should be either float, double, or long double
+      79             :   template<class T>
+      80             :   static bool convertToReal(const std::string & str,T &t);
+      81             : /// class to convert a string to a int type T
+      82             :   template<class T>
+      83             :   static bool convertToInt(const std::string & str,T &t);
+      84             : public:
+      85             : /// Split the line in words using separators.
+      86             : /// It also take into account parenthesis. Outer parenthesis found are removed from
+      87             : /// output, and the text between them is considered as a single word. Only the
+      88             : /// outer parenthesis are processed, to allow nesting them.
+      89             : /// parlevel, if not NULL, is increased or decreased according to the number of opened/closed parenthesis
+      90             :   static std::vector<std::string> getWords(std::string_view line,const char* sep=NULL,int* parlevel=NULL,const char* parenthesis="{", const bool& delete_parenthesis=true);
+      91             : /// Faster version
+      92             : /// This version does not parse parenthesis and operates on a preallocated small_vector of string_view's
+      93             :   static void getWordsSimple(gch::small_vector<std::string_view> & words,std::string_view line);
+      94             : /// Get a line from the file pointer ifile
+      95             :   static bool getline(FILE*,std::string & line);
+      96             : /// Get a parsed line from the file pointer ifile
+      97             : /// This function already takes care of joining continued lines and splitting the
+      98             : /// resulting line into an array of words
+      99             :   static bool getParsedLine(IFile&ifile,std::vector<std::string> & line, const bool trimcomments=true);
+     100             : /// compare two string in a case insensitive manner
+     101             :   static bool caseInSensStringCompare(const std::string & str1, const std::string &str2);
+     102             : /// Convert a string to a double, reading it
+     103             :   static bool convertNoexcept(const std::string & str,double & t);
+     104             : /// Convert a string to a long double, reading it
+     105             :   static bool convertNoexcept(const std::string & str,long double & t);
+     106             : /// Convert a string to a float, reading it
+     107             :   static bool convertNoexcept(const std::string & str,float & t);
+     108             : /// Convert a string to a int, reading it
+     109             :   static bool convertNoexcept(const std::string & str,int & t);
+     110             : /// Convert a string to a long int, reading it
+     111             :   static bool convertNoexcept(const std::string & str,long int & t);
+     112             : /// Convert a string to a long long int, reading it
+     113             :   static bool convertNoexcept(const std::string & str,long long int & t);
+     114             : /// Convert a string to an unsigned int, reading it
+     115             :   static bool convertNoexcept(const std::string & str,unsigned & t);
+     116             : /// Convert a string to a long unsigned int, reading it
+     117             :   static bool convertNoexcept(const std::string & str,long unsigned & t);
+     118             : /// Convert a string to a long long unsigned int, reading it
+     119             :   static bool convertNoexcept(const std::string & str,long long unsigned & t);
+     120             : /// Convert a string to a atom number, reading it
+     121             :   static bool convertNoexcept(const std::string & str,AtomNumber & t);
+     122             : /// Convert a string to a string (i.e. copy)
+     123             :   static bool convertNoexcept(const std::string & str,std::string & t);
+     124             : /// Convert anything into a string
+     125             :   template<typename T>
+     126             :   static bool convertNoexcept(T i,std::string & str);
+     127             : /// Convert anything into anything, throwing an exception in case there is an error
+     128             : /// Remove trailing blanks
+     129             :   static void trim(std::string & s);
+     130             : /// Remove leading blanks
+     131             :   static void ltrim(std::string & s);
+     132             : /// Remove trailing comments
+     133             :   static void trimComments(std::string & s);
+     134             : /// Apply pbc for a unitary cell
+     135             :   static double pbc(double);
+     136             : /// Retrieve a key from a vector of options.
+     137             : /// It finds a key starting with "key=" or equal to "key" and copy the
+     138             : /// part after the = on s. E.g.:
+     139             : /// line.push_back("aa=xx");
+     140             : /// getKey(line,"aa",s);
+     141             : /// will set s="xx"
+     142             :   static bool getKey(std::vector<std::string>& line,const std::string & key,std::string & s,int rep=-1);
+     143             : /// Find a keyword on the input line, eventually deleting it, and saving its value to val
+     144             :   template <typename T,typename U>
+     145    14928714 :   static void convert(const T & t,U & u) {
+     146    14929526 :     plumed_assert(convertNoexcept(t,u)) <<"Error converting  "<<t;
+     147    14928713 :   }
+     148             :   template <typename T>
+     149             :   static bool parse(std::vector<std::string>&line,const std::string&key,T&val,int rep=-1);
+     150             : /// Find a keyword on the input line, eventually deleting it, and saving its value to a vector
+     151             :   template <class T>
+     152             :   static bool parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val,int rep=-1);
+     153             : /// Find a keyword without arguments on the input line
+     154             :   static bool parseFlag(std::vector<std::string>&line,const std::string&key,bool&val);
+     155             : /// Find a keyword on the input line, just reporting if it exists or not
+     156             :   static bool findKeyword(const std::vector<std::string>&line,const std::string&key);
+     157             : /// Interpret atom ranges
+     158             :   static void interpretRanges(std::vector<std::string>&);
+     159             : /// Remove duplicates from a vector of type T
+     160             :   template <typename T>
+     161             :   static void removeDuplicates(std::vector<T>& vec);
+     162             : /// interpret ":" syntax for labels
+     163             :   static void interpretLabel(std::vector<std::string>&s);
+     164             : /// list files in a directory
+     165             :   static std::vector<std::string> ls(const std::string&);
+     166             : /// removes leading and trailing blanks from a string
+     167             :   static void stripLeadingAndTrailingBlanks( std::string& str );
+     168             : /// Extract the extensions from a file name.
+     169             : /// E.g.: extension("pippo.xyz")="xyz".
+     170             : /// It only returns extensions with a length between 1 and 4
+     171             : /// E.g.: extension("pippo.12345")="" whereas extenion("pippo.1234")="1234";
+     172             : /// It is also smart enough to detect "/", so that
+     173             : /// extension("pippo/.t")="" whereas extension("pippo/a.t")="t"
+     174             :   static std::string extension(const std::string&);
+     175             : /// Fast int power
+     176             :   static double fastpow(double base,int exp);
+     177             : /// Modified 0th-order Bessel function of the first kind
+     178             :   static double bessel0(const double& val);
+     179             : /// Check if a string full starts with string start.
+     180             : /// Same as full.find(start)==0
+     181             :   static bool startWith(const std::string & full,const std::string &start);
+     182             :   /**
+     183             :     Tool to create a vector of raw pointers from a vector of unique_pointers (const version).
+     184             :   Returning a vector is fast in C++11. It can be used in order to feed a vector<unique_ptr<T>>
+     185             :   to a function that takes a vector<T*>.
+     186             :   \verbatim
+     187             :   // some function that takes a vec
+     188             :   void func(std::vector<Data*> & vec);
+     189             :   std::vector<std::unique_ptr<Data>> vec;
+     190             :   // func(vec); // does not compile
+     191             :   func(Tools::unique2raw(vec)); // compiles
+     192             :   \endverbatim
+     193             :   Notice that the conversion is fast but takes
+     194             :   some time to allocate the new vector and copy the pointers. In case the function
+     195             :   acting on the vector<T*> is very fast and we do not want to add significant overhead,
+     196             :   it might be convenient to store a separate set of raw pointers.
+     197             :   \verbatim
+     198             :   // some function that takes a vec
+     199             :   void func(std::vector<Data*> & vec);
+     200             :   std::vector<std::unique_ptr<Data>> vec;
+     201             : 
+     202             :   // conversion done only once:
+     203             :   auto vec_ptr=Tools::unique2raw(vec);
+     204             : 
+     205             :   for(int i=0;i<1000;i++){
+     206             :     func(vec_ptr);
+     207             :   }
+     208             :   \endverbatim
+     209             :   */
+     210             :   template <typename T>
+     211             :   static std::vector<T*> unique2raw(const std::vector<std::unique_ptr<T>>&);
+     212             : /// Tool to create a vector of raw pointers from a vector of unique_pointers.
+     213             : /// See the non const version.
+     214             :   template <typename T>
+     215             :   static std::vector<const T*> unique2raw(const std::vector<std::unique_ptr<const T>>&);
+     216             : /// Tiny class that changes directory and comes back when going out of scope.
+     217             : /// In case system calls to change dir are not available it throws an exception.
+     218             : /// \warning By construction, changing directory breaks thread safety! Use with care.
+     219             :   class DirectoryChanger {
+     220             :     const std::filesystem::path path;
+     221             :   public:
+     222             :     explicit DirectoryChanger(const char*path);
+     223             :     ~DirectoryChanger();
+     224             :   };
+     225             : 
+     226             :   template<class T, class... Args>
+     227             :   static auto make_unique(Args&&... args) {
+     228     4216309 :     return std::make_unique<T>(std::forward<Args>(args)...);
+     229             :   }
+     230             : 
+     231             :   static void set_to_zero(double*ptr,unsigned n) {
+     232     1276640 :     for(unsigned i=0; i<n; i++) ptr[i]=0.0;
+     233             :   }
+     234             : 
+     235             :   template<unsigned n>
+     236       28739 :   static void set_to_zero(std::vector<VectorGeneric<n>> & vec) {
+     237       28739 :     unsigned s=vec.size();
+     238       28739 :     if(s==0) return;
+     239       28739 :     set_to_zero(&vec[0][0],s*n);
+     240             :   }
+     241             : 
+     242             :   template<unsigned n,unsigned m>
+     243             :   static void set_to_zero(std::vector<TensorGeneric<n,m>> & vec) {
+     244             :     unsigned s=vec.size();
+     245             :     if(s==0) return;
+     246             :     set_to_zero(&vec[0](0,0),s*n*m);
+     247             :   }
+     248             : 
+     249             : 
+     250             : 
+     251             : 
+     252             :   /// Merge sorted vectors.
+     253             :   /// Takes a vector of pointers to containers and merge them.
+     254             :   /// Containers should be already sorted.
+     255             :   /// The content is appended to the result vector.
+     256             :   /// Optionally, uses a priority_queue implementation.
+     257             :   template<class C>
+     258       21153 :   static void mergeSortedVectors(const std::vector<C*> & vecs, std::vector<typename C::value_type> & result,bool priority_queue=false) {
+     259             : 
+     260             :     /// local class storing the range of remaining objects to be pushed
+     261             :     struct Entry
+     262             :     {
+     263             :       typename C::const_iterator fwdIt,endIt;
+     264             : 
+     265       55538 :       explicit Entry(C const& v) : fwdIt(v.begin()), endIt(v.end()) {}
+     266             :       /// check if this vector still contains something to be pushed
+     267             :       explicit operator bool () const { return fwdIt != endIt; }
+     268             :       /// to allow using a priority_queu, which selects the highest element.
+     269             :       /// we here (counterintuitively) define < as >
+     270             :       bool operator< (Entry const& rhs) const { return *fwdIt > *rhs.fwdIt; }
+     271             :     };
+     272             : 
+     273       21153 :     if(priority_queue) {
+     274             :       std::priority_queue<Entry> queue;
+     275             :       // note: queue does not have reserve() method
+     276             : 
+     277             :       // add vectors to the queue
+     278             :       {
+     279             :         std::size_t maxsize=0;
+     280           0 :         for(unsigned i=0; i<vecs.size(); i++) {
+     281           0 :           if(vecs[i]->size()>maxsize) maxsize=vecs[i]->size();
+     282           0 :           if(!vecs[i]->empty())queue.push(Entry(*vecs[i]));
+     283             :         }
+     284             :         // this is just to save multiple reallocations on push_back
+     285           0 :         result.reserve(maxsize);
+     286             :       }
+     287             : 
+     288             :       // first iteration (to avoid a if in the main loop)
+     289           0 :       if(queue.empty()) return;
+     290           0 :       auto tmp=queue.top();
+     291           0 :       queue.pop();
+     292           0 :       result.push_back(*tmp.fwdIt);
+     293             :       tmp.fwdIt++;
+     294           0 :       if(tmp) queue.push(tmp);
+     295             : 
+     296             :       // main loop
+     297           0 :       while(!queue.empty()) {
+     298           0 :         auto tmp=queue.top();
+     299           0 :         queue.pop();
+     300           0 :         if(result.back() < *tmp.fwdIt) result.push_back(*tmp.fwdIt);
+     301             :         tmp.fwdIt++;
+     302           0 :         if(tmp) queue.push(tmp);
+     303             :       }
+     304             :     } else {
+     305             : 
+     306             :       std::vector<Entry> entries;
+     307       21153 :       entries.reserve(vecs.size());
+     308             : 
+     309             :       {
+     310             :         std::size_t maxsize=0;
+     311       79427 :         for(int i=0; i<vecs.size(); i++) {
+     312       58274 :           if(vecs[i]->size()>maxsize) maxsize=vecs[i]->size();
+     313      113812 :           if(!vecs[i]->empty())entries.push_back(Entry(*vecs[i]));
+     314             :         }
+     315             :         // this is just to save multiple reallocations on push_back
+     316       21153 :         result.reserve(maxsize);
+     317             :       }
+     318             : 
+     319      437798 :       while(!entries.empty()) {
+     320             :         // find smallest pending element
+     321             :         // we use max_element instead of min_element because we are defining < as > (see above)
+     322      416645 :         const auto minval=*std::max_element(entries.begin(),entries.end())->fwdIt;
+     323             : 
+     324             :         // push it
+     325      416645 :         result.push_back(minval);
+     326             : 
+     327             :         // fast forward vectors with elements equal to minval (to avoid duplicates)
+     328     2448122 :         for(auto & e : entries) while(e && *e.fwdIt==minval) ++e.fwdIt;
+     329             : 
+     330             :         // remove from the entries vector all exhausted vectors
+     331      416645 :         auto erase=std::remove_if(entries.begin(),entries.end(),[](const Entry & e) {return !e;});
+     332             :         entries.erase(erase,entries.end());
+     333             :       }
+     334             :     }
+     335             : 
+     336             :   }
+     337             :   static std::unique_ptr<std::lock_guard<std::mutex>> molfile_lock();
+     338             :   /// Build a concatenated exception message.
+     339             :   /// Should be called with an in-flight exception.
+     340             :   static std::string concatenateExceptionMessages();
+     341             : 
+     342             : 
+     343             :   /// Tiny class implementing faster std::string_view access to an unordered_map
+     344             :   /// It exposes a limited number of methods of std::unordered_map. Others could be added.
+     345             :   /// Importantly, when it is accessed via a std::string_view, the access does not
+     346             :   /// require constructing a std::string and is thus faster.
+     347             :   /// Deletion would be slower instead. It's not even implemented yet.
+     348             :   template<class T>
+     349      805878 :   class FastStringUnorderedMap {
+     350             :     std::unordered_map<std::string_view,T> map;
+     351             :     std::vector<std::unique_ptr<const char[]>> keys;
+     352             : 
+     353             :     // see https://stackoverflow.com/questions/34596768/stdunordered-mapfind-using-a-type-different-than-the-key-type
+     354      389539 :     std::unique_ptr<const char[]> conv(std::string_view str) {
+     355      389539 :       std::unique_ptr<char[]> p (new char [str.size()+1]);
+     356             :       std::memcpy(p.get(), str.data(), str.size()+1);
+     357      389539 :       return p;
+     358             :     }
+     359             : 
+     360             :   public:
+     361             : 
+     362             :     FastStringUnorderedMap() = default;
+     363        8514 :     FastStringUnorderedMap(std::initializer_list<std::pair<const std::string_view,T>> init) {
+     364      386518 :       for(const auto & c : init) {
+     365      378004 :         (*this)[c.first]=c.second;
+     366             :       }
+     367        8514 :     }
+     368             : 
+     369     3030849 :     T& operator[]( const std::string_view & key ) {
+     370             :       auto f=map.find(key);
+     371     3030849 :       if(f!=map.end()) return f->second;
+     372      779078 :       keys.push_back(conv(key));
+     373      389539 :       return map[keys.back().get()];
+     374             :     }
+     375             : 
+     376             :     auto begin() {
+     377             :       return map.begin();
+     378             :     }
+     379             :     auto end() {
+     380             :       return map.end();
+     381             :     }
+     382             :     auto begin() const {
+     383             :       return map.begin();
+     384             :     }
+     385             :     auto end() const {
+     386             :       return map.end();
+     387             :     }
+     388             :     auto find(const std::string_view & key) {
+     389             :       return map.find(key);
+     390             :     }
+     391             :     auto find(const std::string_view & key) const {
+     392             :       return map.find(key);
+     393             :     }
+     394             :   };
+     395             : 
+     396             : };
+     397             : 
+     398             : template <class T>
+     399      122908 : bool Tools::parse(std::vector<std::string>&line,const std::string&key,T&val,int rep) {
+     400             :   std::string s;
+     401      245816 :   if(!getKey(line,key+"=",s,rep)) return false;
+     402       72008 :   if(s.length()>0 && !convertNoexcept(s,val))return false;
+     403             :   return true;
+     404             : }
+     405             : 
+     406             : template <class T>
+     407       46761 : bool Tools::parseVector(std::vector<std::string>&line,const std::string&key,std::vector<T>&val,int rep) {
+     408             :   std::string s;
+     409       93522 :   if(!getKey(line,key+"=",s,rep)) return false;
+     410             :   val.clear();
+     411       36530 :   std::vector<std::string> words=getWords(s,"\t\n ,");
+     412      134395 :   for(unsigned i=0; i<words.size(); ++i) {
+     413             :     T v;
+     414       97865 :     std::string s=words[i];
+     415       97865 :     const std::string multi("@replicas:");
+     416       97865 :     if(rep>=0 && startWith(s,multi)) {
+     417           6 :       s=s.substr(multi.length(),s.length());
+     418           6 :       std::vector<std::string> words=getWords(s,"\t\n ,");
+     419           6 :       plumed_assert(rep<static_cast<int>(words.size()));
+     420           6 :       s=words[rep];
+     421           6 :     }
+     422       97865 :     if(!convertNoexcept(s,v))return false;
+     423       97865 :     val.push_back(v);
+     424             :   }
+     425             :   return true;
+     426       36530 : }
+     427             : 
+     428             : template<typename T>
+     429       13447 : void Tools::removeDuplicates(std::vector<T>& vec)
+     430             : {
+     431       13447 :   std::sort(vec.begin(), vec.end());
+     432       13447 :   vec.erase(std::unique(vec.begin(), vec.end()), vec.end());
+     433       13447 : }
+     434             : 
+     435             : inline
+     436       66538 : bool Tools::parseFlag(std::vector<std::string>&line,const std::string&key,bool&val) {
+     437      190377 :   for(auto p=line.begin(); p!=line.end(); ++p) {
+     438      132843 :     if(key==*p) {
+     439        9004 :       val=true;
+     440             :       line.erase(p);
+     441             :       return true;
+     442             :     }
+     443             :   }
+     444             :   return false;
+     445             : }
+     446             : 
+     447             : /// beware: this brings any number into a pbc that ranges from -0.5 to 0.5
+     448             : inline
+     449  1828652049 : double Tools::pbc(double x) {
+     450             : #ifdef __PLUMED_PBC_WHILE
+     451             :   while (x>0.5) x-=1.0;
+     452             :   while (x<-0.5) x+=1.0;
+     453             :   return x;
+     454             : #else
+     455             :   if constexpr (std::numeric_limits<int>::round_style == std::round_toward_zero) {
+     456             :     constexpr double offset=100.0;
+     457  1828652049 :     const double y=x+offset;
+     458  1828652049 :     if(y>=0) return y-int(y+0.5);
+     459        4577 :     else     return y-int(y-0.5);
+     460             :   } else if constexpr (std::numeric_limits<int>::round_style == std::round_to_nearest) {
+     461             :     return x-int(x);
+     462             :   } else return x-floor(x+0.5);
+     463             : #endif
+     464             : }
+     465             : 
+     466             : template<typename T>
+     467      743265 : bool Tools::convertNoexcept(T i,std::string & str) {
+     468      743265 :   std::ostringstream ostr;
+     469      439990 :   ostr<<i;
+     470      743265 :   str=ostr.str();
+     471      743265 :   return true;
+     472      743265 : }
+     473             : 
+     474             : inline
+     475    79178463 : double Tools::fastpow(double base, int exp)
+     476             : {
+     477    79178463 :   if(exp<0) {
+     478           0 :     exp=-exp;
+     479           0 :     base=1.0/base;
+     480             :   }
+     481             :   double result = 1.0;
+     482   375025611 :   while (exp)
+     483             :   {
+     484   262246954 :     if (exp & 1)
+     485   181142800 :       result *= base;
+     486   262246954 :     exp >>= 1;
+     487   262246954 :     base *= base;
+     488             :   }
+     489             : 
+     490    79178463 :   return result;
+     491             : }
+     492             : 
+     493             : template<typename T>
+     494    13703470 : std::vector<T*> Tools::unique2raw(const std::vector<std::unique_ptr<T>> & x) {
+     495    13703470 :   std::vector<T*> v(x.size());
+     496    52721172 :   for(unsigned i=0; i<x.size(); i++) v[i]=x[i].get();
+     497    13703470 :   return v;
+     498             : }
+     499             : 
+     500             : template<typename T>
+     501             : std::vector<const T*> Tools::unique2raw(const std::vector<std::unique_ptr<const T>> & x) {
+     502             :   std::vector<const T*> v(x.size());
+     503             :   for(unsigned i=0; i<x.size(); i++) v[i]=x[i].get();
+     504             :   return v;
+     505             : }
+     506             : 
+     507             : }
+     508             : 
+     509             : #endif
+     510             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Torsion.cpp.func-sort-c.html b/coverage/tools/Torsion.cpp.func-sort-c.html new file mode 100644 index 000000000000..4a0d7899134b --- /dev/null +++ b/coverage/tools/Torsion.cpp.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Torsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283580.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_0
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_RS2_S5_S5_1084677
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Torsion.cpp.func.html b/coverage/tools/Torsion.cpp.func.html new file mode 100644 index 000000000000..79a663487a66 --- /dev/null +++ b/coverage/tools/Torsion.cpp.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - tools/Torsion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283580.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_0
_ZNK4PLMD7Torsion7computeERKNS_13VectorGenericILj3EEES4_S4_RS2_S5_S5_1084677
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Torsion.cpp.gcov.html b/coverage/tools/Torsion.cpp.gcov.html new file mode 100644 index 000000000000..f2649c0425d4 --- /dev/null +++ b/coverage/tools/Torsion.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - tools/Torsion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Torsion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283580.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Torsion.h"
+      23             : #include "Tensor.h"
+      24             : 
+      25             : #include <cmath>
+      26             : #include <iostream>
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30           0 : double Torsion::compute(const Vector& v1,const Vector& v2,const Vector& v3)const {
+      31           0 :   const Vector nv2(v2*(1.0/v2.modulo()));
+      32           0 :   const Vector a(crossProduct(nv2,v1));
+      33           0 :   const Vector b(crossProduct(v3,nv2));
+      34           0 :   const double cosangle=dotProduct(a,b);
+      35           0 :   const double sinangle=dotProduct(crossProduct(a,b),nv2);
+      36           0 :   return std::atan2(-sinangle,cosangle);
+      37             : }
+      38             : 
+      39     1084677 : double Torsion::compute(const Vector& v1,const Vector& v2,const Vector& v3,Vector& d1,Vector& d2,Vector& d3)const {
+      40             : 
+      41     1084677 :   const double modv2(1./v2.modulo());
+      42     1084677 :   const Vector nv2(v2*modv2);
+      43     1084677 :   const Tensor dnv2_v2((Tensor::identity()-extProduct(nv2,nv2))*modv2);
+      44             : 
+      45     1084677 :   const Vector a(crossProduct(v2,v1));
+      46     1084677 :   const Tensor da_dv2(dcrossDv1(v2,v1));
+      47     1084677 :   const Tensor da_dv1(dcrossDv2(v2,v1));
+      48     1084677 :   const Vector b(crossProduct(v3,v2));
+      49     1084677 :   const Tensor db_dv3(dcrossDv1(v3,v2));
+      50     1084677 :   const Tensor db_dv2(dcrossDv2(v3,v2));
+      51     1084677 :   const double cosangle=dotProduct(a,b);
+      52     1084677 :   const Vector dcosangle_dv1=matmul(b,da_dv1);
+      53     1084677 :   const Vector dcosangle_dv2=matmul(b,da_dv2) + matmul(a,db_dv2);
+      54     1084677 :   const Vector dcosangle_dv3=matmul(a,db_dv3);
+      55             : 
+      56     1084677 :   const Vector cab(crossProduct(a,b));
+      57     1084677 :   const Tensor dcab_dv1(matmul(dcrossDv1(a,b),da_dv1));
+      58     1084677 :   const Tensor dcab_dv2(matmul(dcrossDv1(a,b),da_dv2) + matmul(dcrossDv2(a,b),db_dv2));
+      59     1084677 :   const Tensor dcab_dv3(matmul(dcrossDv2(a,b),db_dv3));
+      60             : 
+      61     1084677 :   const double sinangle=dotProduct(cab,nv2);
+      62     1084677 :   const Vector dsinangle_dv1=matmul(nv2,dcab_dv1);
+      63     1084677 :   const Vector dsinangle_dv2=matmul(nv2,dcab_dv2)+matmul(cab,dnv2_v2);
+      64     1084677 :   const Vector dsinangle_dv3=matmul(nv2,dcab_dv3);
+      65             : 
+      66     1084677 :   const double torsion=std::atan2(-sinangle,cosangle);
+      67             : // this is required since v1 and v3 are not normalized:
+      68     1084677 :   const double invR2=1.0/(cosangle*cosangle+sinangle*sinangle);
+      69             : 
+      70     1084677 :   d1= ( -dsinangle_dv1*cosangle + sinangle * dcosangle_dv1 ) *invR2;
+      71     1084677 :   d2= ( -dsinangle_dv2*cosangle + sinangle * dcosangle_dv2 ) *invR2;
+      72     1084677 :   d3= ( -dsinangle_dv3*cosangle + sinangle * dcosangle_dv3 ) *invR2;
+      73             : 
+      74     1084677 :   return torsion;
+      75             : }
+      76             : 
+      77             : }
+      78             : 
+      79             : 
+      80             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.cpp.func-sort-c.html b/coverage/tools/Tree.cpp.func-sort-c.html new file mode 100644 index 000000000000..1a33b8998224 --- /dev/null +++ b/coverage/tools/Tree.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tree.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333789.2 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4Tree7getTreeESt6vectorINS_10AtomNumberESaIS2_EE1
_ZN4PLMD4TreeC2EPNS_14GenericMolInfoE1
_ZNK4PLMD4Tree7getRootEv1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.cpp.func.html b/coverage/tools/Tree.cpp.func.html new file mode 100644 index 000000000000..1e9526a044b3 --- /dev/null +++ b/coverage/tools/Tree.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tree.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333789.2 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD4Tree7getTreeESt6vectorINS_10AtomNumberESaIS2_EE1
_ZN4PLMD4TreeC2EPNS_14GenericMolInfoE1
_ZNK4PLMD4Tree7getRootEv1
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.cpp.gcov.html b/coverage/tools/Tree.cpp.gcov.html new file mode 100644 index 000000000000..f38ff3194a8e --- /dev/null +++ b/coverage/tools/Tree.cpp.gcov.html @@ -0,0 +1,194 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tree.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:333789.2 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2021-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Tree.h"
+      24             : #include "Tools.h"
+      25             : #include "Vector.h"
+      26             : #include "AtomNumber.h"
+      27             : #include "core/GenericMolInfo.h"
+      28             : #include <vector>
+      29             : #include <limits>
+      30             : 
+      31             : namespace PLMD {
+      32             : 
+      33           1 : Tree::Tree(GenericMolInfo* moldat) {
+      34             : // initialize class
+      35           1 :   moldat_ = moldat;
+      36             : // check if molinfo present
+      37           1 :   if(!moldat_) plumed_merror("MOLINFO DATA not found");
+      38             : // check if reference structure is whole
+      39           1 :   if(!moldat_->isWhole()) plumed_merror("Check that reference structure in PDB file is not broken by pbc and set WHOLE in MOLINFO line");
+      40           1 : }
+      41             : 
+      42           1 : std::vector<AtomNumber> Tree::getTree(std::vector<AtomNumber> atoms)
+      43             : {
+      44             :   // Implementation inspired from:
+      45             :   // https://mayanknatani.wordpress.com/2013/05/31/euclidean-minimummaximum-spanning-tree-emst/
+      46             :   //
+      47             :   // list of AtomNumbers ordered by proximity in PDB file
+      48             :   std::vector<AtomNumber> tree;
+      49             :   // clear root_ vector
+      50           1 :   root_.clear();
+      51             : 
+      52             :   // remove atoms not in PDB file
+      53             :   std::vector<AtomNumber> addtotree, addtoroot;
+      54             :   std::vector<AtomNumber> newatoms;
+      55           1 :   newatoms.reserve(atoms.size());
+      56           1 :   if(!moldat_->checkForAtom(atoms[0])) plumed_merror("The first atom in the list should be present in the PDB file");
+      57             :   // store first atom
+      58           1 :   newatoms.push_back(atoms[0]);
+      59         123 :   for(unsigned i=1; i<atoms.size(); ++i) {
+      60         122 :     if(!moldat_->checkForAtom(atoms[i])) {
+      61             :       // store this atom for later
+      62           0 :       addtotree.push_back(atoms[i]);
+      63             :       // along with its root (the previous atom)
+      64           0 :       addtoroot.push_back(atoms[i-1]);
+      65             :     } else {
+      66         122 :       newatoms.push_back(atoms[i]);
+      67             :     }
+      68             :   }
+      69             :   // reassign atoms
+      70           1 :   atoms=newatoms;
+      71             :   // start EMST
+      72           1 :   std::vector<bool> intree(atoms.size(), false);
+      73           1 :   std::vector<double> mindist(atoms.size(), std::numeric_limits<double>::max());
+      74             :   // initialize tree with first atom
+      75           1 :   mindist[0] = 0.0;
+      76             :   // loops
+      77         124 :   for(unsigned i=0; i<atoms.size(); ++i) {
+      78             :     int selected_vertex = -1;
+      79       15252 :     for(unsigned j=0; j<atoms.size(); ++j) {
+      80       15129 :       if( !intree[j] && (selected_vertex==-1 || mindist[j] < mindist[selected_vertex]) )
+      81         933 :         selected_vertex = j;
+      82             :     }
+      83             :     // add to tree
+      84         123 :     plumed_assert(selected_vertex>=0);
+      85         123 :     tree.push_back(atoms[selected_vertex]);
+      86             :     intree[selected_vertex] = true;
+      87             :     // update distances
+      88             :     double minroot = std::numeric_limits<double>::max();
+      89             :     int iroot = -1;
+      90       15252 :     for(unsigned j=0; j<atoms.size(); ++j) {
+      91       15129 :       double dist = delta(moldat_->getPosition(atoms[selected_vertex]), moldat_->getPosition(atoms[j])).modulo2();
+      92       15129 :       if(dist < mindist[j]) mindist[j] = dist;
+      93       17771 :       if(dist < minroot && intree[j] && dist>0.0) {
+      94             :         minroot = dist;
+      95        2082 :         iroot = j;
+      96             :       }
+      97             :     }
+      98             :     // add to root vector
+      99         123 :     if(iroot>=0) root_.push_back(atoms[iroot]);
+     100             :   }
+     101             : 
+     102             :   // now re-add atoms not present in the PDB
+     103           1 :   for(unsigned i=0; i<addtotree.size(); ++i) {
+     104           0 :     tree.push_back(addtotree[i]);
+     105           0 :     root_.push_back(addtoroot[i]);
+     106             :   }
+     107             : 
+     108             :   // return
+     109           1 :   return tree;
+     110             : }
+     111             : 
+     112           1 : std::vector<AtomNumber> Tree::getRoot() const
+     113             : {
+     114           1 :   return root_;
+     115             : }
+     116             : 
+     117             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.h.func-sort-c.html b/coverage/tools/Tree.h.func-sort-c.html new file mode 100644 index 000000000000..a95e0c4bf148 --- /dev/null +++ b/coverage/tools/Tree.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tree.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.h.func.html b/coverage/tools/Tree.h.func.html new file mode 100644 index 000000000000..e3079b75b3ea --- /dev/null +++ b/coverage/tools/Tree.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tree.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Tree.h.gcov.html b/coverage/tools/Tree.h.gcov.html new file mode 100644 index 000000000000..d1a999c96537 --- /dev/null +++ b/coverage/tools/Tree.h.gcov.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - tools/Tree.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Tree.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2021-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Tree_h
+      23             : #define __PLUMED_tools_Tree_h
+      24             : 
+      25             : #include <vector>
+      26             : #include "Vector.h"
+      27             : #include "core/GenericMolInfo.h"
+      28             : #include "AtomNumber.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : 
+      33             : /// \ingroup TOOLBOX
+      34           1 : class Tree
+      35             : {
+      36             : 
+      37             : private:
+      38             :   GenericMolInfo* moldat_;
+      39             :   std::vector<AtomNumber> root_;
+      40             : 
+      41             : public:
+      42             : /// constructor
+      43             :   explicit Tree(GenericMolInfo* moldat);
+      44             : /// build a tree
+      45             :   std::vector<AtomNumber> getTree(std::vector<AtomNumber> atoms);
+      46             : /// get root
+      47             :   std::vector<AtomNumber> getRoot() const;
+      48             : };
+      49             : 
+      50             : }
+      51             : 
+      52             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.cpp.func-sort-c.html b/coverage/tools/TypesafePtr.cpp.func-sort-c.html new file mode 100644 index 000000000000..510b73ec0c65 --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr9extra_msgB5cxx11Ev8
_ZN4PLMD11TypesafePtr11fromSafePtrEPv14942
_ZNK4PLMD11TypesafePtr4copyEv787625
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.cpp.func.html b/coverage/tools/TypesafePtr.cpp.func.html new file mode 100644 index 000000000000..238453fb048c --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr11fromSafePtrEPv14942
_ZN4PLMD11TypesafePtr9extra_msgB5cxx11Ev8
_ZNK4PLMD11TypesafePtr4copyEv787625
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.cpp.gcov.html b/coverage/tools/TypesafePtr.cpp.gcov.html new file mode 100644 index 000000000000..639ced76e34e --- /dev/null +++ b/coverage/tools/TypesafePtr.cpp.gcov.html @@ -0,0 +1,134 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1414100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "TypesafePtr.h"
+      23             : #include "core/PlumedMainInitializer.h"
+      24             : 
+      25             : #include <iostream>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29       14942 : TypesafePtr TypesafePtr::fromSafePtr(void* safe) {
+      30             :   auto s=(plumed_safeptr_x*)safe;
+      31       14942 :   return TypesafePtr(const_cast<void*>(s->ptr), s->nelem, s->shape, s->flags);
+      32             : }
+      33             : 
+      34      787625 : TypesafePtr TypesafePtr::copy() const {
+      35      787625 :   auto passbyvalue=((flags>>25)&0x7)==1;
+      36      787625 :   if(passbyvalue) throw ExceptionTypeError()<<"PLUMED is trying to copy the pointer of an object passed by value";
+      37      787625 :   auto forbidstore=flags&0x10000000;
+      38      787625 :   if(forbidstore) throw ExceptionTypeError()<<"PLUMED is trying to copy the pointer of an object for which this was forbidden";
+      39             :   TypesafePtr ret;
+      40      787625 :   ret.ptr=ptr;
+      41      787625 :   ret.flags=flags;
+      42      787625 :   ret.nelem=nelem;
+      43      787625 :   ret.shape=shape;
+      44      787625 :   return ret;
+      45             : }
+      46             : 
+      47           8 : std::string TypesafePtr::extra_msg() {
+      48             :   const char *text = "\n"
+      49             :                      "If you are sure your code is correct you can disable this check with export PLUMED_TYPESAFE_IGNORE=yes\n"
+      50             :                      "In case this is necessary, please report an issue to developers of PLUMED and of the MD code\n"
+      51             :                      "See also https://github.com/plumed/plumed2/pull/653";
+      52           8 :   return std::string(text);
+      53             : }
+      54             : 
+      55             : }
+      56             : 
+      57             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.h.func-sort-c.html b/coverage/tools/TypesafePtr.h.func-sort-c.html new file mode 100644 index 000000000000..70f8c586e4c0 --- /dev/null +++ b/coverage/tools/TypesafePtr.h.func-sort-c.html @@ -0,0 +1,293 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10612187.6 %
Date:2024-02-22 21:58:45Functions:395570.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtrC2EfmPKm0
_ZN4PLMD11TypesafePtrC2EjmPKm0
_ZN4PLMD17typesafePtrSizeofI8_IO_FILEEEmv0
_ZN4PLMD17typesafePtrSizeofIKfEEmv0
_ZN4PLMD17typesafePtrSizeofIKjEEmv0
_ZN4PLMD17typesafePtrSizeofIKlEEmv0
_ZNK4PLMD11TypesafePtr3getIPKfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPKfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIPfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIfEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIjEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIlEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr8get_privIKfEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKjEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKlEEPT_mPKmb0
_ZN4PLMD17typesafePtrSizeofIfEEmv1
_ZNK4PLMD11TypesafePtr3setIfEEvT_1
_ZNK4PLMD11TypesafePtr8get_privIfEEPT_mPKmb1
_ZNK4PLMD11TypesafePtr8type_strB5cxx11Ev5
_ZN4PLMD17typesafePtrSizeofIlEEmv66
_ZNK4PLMD11TypesafePtr3setIlEEvT_66
_ZNK4PLMD11TypesafePtr8get_privIlEEPT_mPKmb66
_ZNK4PLMD11TypesafePtr8get_privIPKiEEPT_mPKmb116
_ZNK4PLMD11TypesafePtr8get_privI8_IO_FILEEEPT_mPKmb855
_ZNK4PLMD11TypesafePtr8get_privIKvEEPT_mPKmb1719
_ZNK4PLMD11TypesafePtr8get_privIKcEEPT_mPKmb2209
_ZNK4PLMD11TypesafePtr3setIdEEvT_2389
_ZNK4PLMD11TypesafePtr8get_privIKPKcEEPT_mPKmb4144
_ZNK4PLMD11TypesafePtr3setIiEEvT_4563
_ZN4PLMD17typesafePtrSizeofIKcEEmv6278
_ZNK4PLMD11TypesafePtr3getIdEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv7483
_ZN4PLMD11TypesafePtrC2EimPKm8643
_ZN4PLMD11TypesafePtrC2EdmPKm8955
_ZNK4PLMD11TypesafePtr3getIiEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv13479
_ZNK4PLMD11TypesafePtr8get_privIKiEEPT_mPKmb14457
_ZN4PLMD17typesafePtrSizeofIKiEEmv14499
_ZNK4PLMD11TypesafePtr3getIPdEET_St16initializer_listImE144403
_ZNK4PLMD11TypesafePtr3getIPdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv167357
_ZN4PLMD11TypesafePtrC2ExmPKm246073
_ZN4PLMD17typesafePtrSizeofIKxEEmv250012
_ZNK4PLMD11TypesafePtr3getIxEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv250012
_ZNK4PLMD11TypesafePtr8get_privIKxEEPT_mPKmb250012
_ZNK4PLMD11TypesafePtr3getIPiEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv253911
_ZN4PLMD17typesafePtrSizeofIiEEmv258467
_ZNK4PLMD11TypesafePtr8get_privIiEEPT_mPKmb258474
_ZNK4PLMD11TypesafePtr3getIPKdEET_St16initializer_listImE260534
_ZNK4PLMD11TypesafePtr3getIPKdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv268814
_ZN4PLMD17typesafePtrSizeofIdEEmv314715
_ZNK4PLMD11TypesafePtr8get_privIdEEPT_mPKmb314862
_ZN4PLMD17typesafePtrSizeofIKdEEmv538201
_ZNK4PLMD11TypesafePtr8get_privIKdEEPT_mPKmb538477
_ZN4PLMD11TypesafePtraSEOS0_787625
_ZN4PLMD11TypesafePtr10init_shapeEPKm1134650
_ZN4PLMDL20typesafePtrSkipCheckEv1385392
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.h.func.html b/coverage/tools/TypesafePtr.h.func.html new file mode 100644 index 000000000000..d6673d75f9d4 --- /dev/null +++ b/coverage/tools/TypesafePtr.h.func.html @@ -0,0 +1,293 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10612187.6 %
Date:2024-02-22 21:58:45Functions:395570.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD11TypesafePtr10init_shapeEPKm1134650
_ZN4PLMD11TypesafePtrC2EdmPKm8955
_ZN4PLMD11TypesafePtrC2EfmPKm0
_ZN4PLMD11TypesafePtrC2EimPKm8643
_ZN4PLMD11TypesafePtrC2EjmPKm0
_ZN4PLMD11TypesafePtrC2ExmPKm246073
_ZN4PLMD11TypesafePtraSEOS0_787625
_ZN4PLMD17typesafePtrSizeofI8_IO_FILEEEmv0
_ZN4PLMD17typesafePtrSizeofIKcEEmv6278
_ZN4PLMD17typesafePtrSizeofIKdEEmv538201
_ZN4PLMD17typesafePtrSizeofIKfEEmv0
_ZN4PLMD17typesafePtrSizeofIKiEEmv14499
_ZN4PLMD17typesafePtrSizeofIKjEEmv0
_ZN4PLMD17typesafePtrSizeofIKlEEmv0
_ZN4PLMD17typesafePtrSizeofIKxEEmv250012
_ZN4PLMD17typesafePtrSizeofIdEEmv314715
_ZN4PLMD17typesafePtrSizeofIfEEmv1
_ZN4PLMD17typesafePtrSizeofIiEEmv258467
_ZN4PLMD17typesafePtrSizeofIlEEmv66
_ZN4PLMDL20typesafePtrSkipCheckEv1385392
_ZNK4PLMD11TypesafePtr3getIPKdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv268814
_ZNK4PLMD11TypesafePtr3getIPKdEET_St16initializer_listImE260534
_ZNK4PLMD11TypesafePtr3getIPKfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES6_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPKfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIPdEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv167357
_ZNK4PLMD11TypesafePtr3getIPdEET_St16initializer_listImE144403
_ZNK4PLMD11TypesafePtr3getIPfEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIPfEET_St16initializer_listImE0
_ZNK4PLMD11TypesafePtr3getIPiEENSt9enable_ifIXsrSt10is_pointerIT_E5valueES5_E4typeEv253911
_ZNK4PLMD11TypesafePtr3getIdEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv7483
_ZNK4PLMD11TypesafePtr3getIfEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIiEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv13479
_ZNK4PLMD11TypesafePtr3getIjEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIlEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv0
_ZNK4PLMD11TypesafePtr3getIxEENSt9enable_ifIXntsrSt10is_pointerIT_E5valueES4_E4typeEv250012
_ZNK4PLMD11TypesafePtr3setIdEEvT_2389
_ZNK4PLMD11TypesafePtr3setIfEEvT_1
_ZNK4PLMD11TypesafePtr3setIiEEvT_4563
_ZNK4PLMD11TypesafePtr3setIlEEvT_66
_ZNK4PLMD11TypesafePtr8get_privI8_IO_FILEEEPT_mPKmb855
_ZNK4PLMD11TypesafePtr8get_privIKPKcEEPT_mPKmb4144
_ZNK4PLMD11TypesafePtr8get_privIKcEEPT_mPKmb2209
_ZNK4PLMD11TypesafePtr8get_privIKdEEPT_mPKmb538477
_ZNK4PLMD11TypesafePtr8get_privIKfEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKiEEPT_mPKmb14457
_ZNK4PLMD11TypesafePtr8get_privIKjEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKlEEPT_mPKmb0
_ZNK4PLMD11TypesafePtr8get_privIKvEEPT_mPKmb1719
_ZNK4PLMD11TypesafePtr8get_privIKxEEPT_mPKmb250012
_ZNK4PLMD11TypesafePtr8get_privIPKiEEPT_mPKmb116
_ZNK4PLMD11TypesafePtr8get_privIdEEPT_mPKmb314862
_ZNK4PLMD11TypesafePtr8get_privIfEEPT_mPKmb1
_ZNK4PLMD11TypesafePtr8get_privIiEEPT_mPKmb258474
_ZNK4PLMD11TypesafePtr8get_privIlEEPT_mPKmb66
_ZNK4PLMD11TypesafePtr8type_strB5cxx11Ev5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/TypesafePtr.h.gcov.html b/coverage/tools/TypesafePtr.h.gcov.html new file mode 100644 index 000000000000..f48c770f4d04 --- /dev/null +++ b/coverage/tools/TypesafePtr.h.gcov.html @@ -0,0 +1,473 @@ + + + + + + + + LCOV - plumed test coverage - tools/TypesafePtr.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - TypesafePtr.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10612187.6 %
Date:2024-02-22 21:58:45Functions:395570.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_TypesafePtr_h
+      23             : #define __PLUMED_tools_TypesafePtr_h
+      24             : 
+      25             : #include "Exception.h"
+      26             : 
+      27             : #include <memory>
+      28             : #include <iosfwd>
+      29             : #include <map>
+      30             : #include <utility>
+      31             : #include <mutex>
+      32             : #include <cstdio>
+      33             : #include <array>
+      34             : #include <cstring>
+      35             : #include <type_traits>
+      36             : #include <climits>
+      37             : #include <initializer_list>
+      38             : 
+      39             : namespace PLMD {
+      40             : 
+      41     1385392 : static inline bool typesafePtrSkipCheck() {
+      42     1385392 :   static const bool ret=std::getenv("PLUMED_TYPESAFE_IGNORE");
+      43     1385392 :   return ret;
+      44             : }
+      45             : 
+      46             : template<class T>
+      47     1382239 : std::size_t typesafePtrSizeof() {
+      48     1382239 :   return sizeof(T);
+      49             : }
+      50             : 
+      51             : template<>
+      52             : inline
+      53             : std::size_t typesafePtrSizeof<void>() {
+      54             :   return 0;
+      55             : }
+      56             : 
+      57             : template<>
+      58             : inline
+      59             : std::size_t typesafePtrSizeof<const void>() {
+      60             :   return 0;
+      61             : }
+      62             : 
+      63             : /**
+      64             : \ingroup TOOLBOX
+      65             : Class to deal with propoagation of typesafe pointers.
+      66             : 
+      67             : */
+      68             : class TypesafePtr {
+      69     1134650 :   inline void init_shape(const std::size_t* shape) {
+      70     1134650 :     this->shape[0]=0;
+      71     1134650 :     if(shape && *shape>0) {
+      72             :       std::size_t nelem_=1;
+      73             :       unsigned i=0;
+      74         820 :       for(i=0; i<this->shape.size(); i++) {
+      75         820 :         this->shape[i]=*shape;
+      76         820 :         if(*shape==0) break;
+      77         468 :         nelem_*=*shape;
+      78         468 :         shape++;
+      79             :       }
+      80         352 :       plumed_assert(i<this->shape.size()); // check that last element is actually zero
+      81         352 :       if(nelem==0) nelem=nelem_;
+      82         352 :       plumed_assert(nelem==nelem_) << "Inconsistent shape/nelem";
+      83             :     }
+      84     1134650 :   }
+      85             : 
+      86             :   static std::string extra_msg();
+      87             : 
+      88             : public:
+      89             : 
+      90             :   TypesafePtr(void* ptr, std::size_t nelem, const std::size_t* shape, std::size_t flags):
+      91      291109 :     ptr(ptr),
+      92      291109 :     nelem(nelem),
+      93      291109 :     flags(flags)
+      94             :   {
+      95      291109 :     buffer[0]='\0';
+      96      291109 :     init_shape(shape);
+      97             :   }
+      98             : 
+      99             :   static const unsigned maxrank=4;
+     100             :   static TypesafePtr fromSafePtr(void* safe);
+     101             :   static TypesafePtr setNelemAndShape(const TypesafePtr &other, std::size_t nelem, const std::size_t* shape) {
+     102      275810 :     return TypesafePtr(other.ptr,nelem,shape,other.flags);
+     103             :   }
+     104             :   static TypesafePtr unchecked(const void* ptr) {
+     105             :     return TypesafePtr(const_cast<void*>(ptr),0,nullptr,0);
+     106             :   }
+     107             :   static constexpr unsigned short is_integral=3;
+     108             :   static constexpr unsigned short is_floating_point=4;
+     109             :   static constexpr unsigned short is_file=5;
+     110             : 
+     111     1592908 :   TypesafePtr() {
+     112     1592908 :     shape[0]=0;
+     113     1592908 :     buffer[0]='\0';
+     114             :   }
+     115             : 
+     116             :   TypesafePtr(std::nullptr_t)
+     117      260534 :   {
+     118      260534 :     shape[0]=0;
+     119      258457 :     buffer[0]='\0';
+     120             :   }
+     121             : 
+     122             : /// Macro that generate a constructor with given type and flags
+     123             : #define __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type,type_,flags_) \
+     124             :   TypesafePtr(type_*ptr, std::size_t nelem=0, const std::size_t* shape=nullptr) : \
+     125             :     ptr((void*)const_cast<type*>(ptr)), \
+     126             :     nelem(nelem), \
+     127             :     flags(flags_) \
+     128             :   { \
+     129             :     init_shape(shape); \
+     130             :     buffer[0]='\0'; \
+     131             :   }
+     132             : 
+     133             : /// Macro that uses __PLUMED_WRAPPER_TYPESAFEPTR_INNER to generate constructors with
+     134             : /// all possible pointer-const combinations
+     135             : #define __PLUMED_WRAPPER_TYPESAFEPTR(type, code,size) \
+     136             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type, type,             size | (0x10000*(code)) | (0x2000000*2)) \
+     137             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type, type const,       size | (0x10000*(code)) | (0x2000000*3)) \
+     138             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type*,type*,            size | (0x10000*(code)) | (0x2000000*4)) \
+     139             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type*,type*const,       size | (0x10000*(code)) | (0x2000000*5)) \
+     140             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type*,type const*,      size | (0x10000*(code)) | (0x2000000*6)) \
+     141             :   __PLUMED_WRAPPER_TYPESAFEPTR_INNER(type*,type const*const, size | (0x10000*(code)) | (0x2000000*7))
+     142             : 
+     143             : /// Macro that generates the constructors from empy types (those of which sizeof cannot be computed)
+     144             : #define __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(type,code) __PLUMED_WRAPPER_TYPESAFEPTR(type,code,0)
+     145             : 
+     146             : /// Macro that generates the constructors from sized types (those of which sizeof can be computed).
+     147             : /// In addition to generating constructors with all pointer types, it generates a constructor to
+     148             : /// allow pass-by-value
+     149             : #define __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(type,code) \
+     150             :   __PLUMED_WRAPPER_TYPESAFEPTR(type,code,sizeof(type)) \
+     151             :   TypesafePtr(type val, std::size_t nelem=0, const std::size_t* shape=nullptr): \
+     152             :       nelem(1), \
+     153             :       flags(sizeof(type) | (0x10000*(code)) | (0x2000000*1)) \
+     154             :     { \
+     155             :     plumed_assert(sizeof(type)<=32); \
+     156             :     ptr=&buffer[0]; \
+     157             :     flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+     158             :     std::memcpy(&buffer[0],&val,sizeof(type)); \
+     159             :     init_shape(shape); \
+     160             :   }
+     161             : 
+     162             : /// Here we create all the required instances
+     163             : /// 1: void
+     164             : /// 3: integral
+     165             : /// 4: floating
+     166             : /// 5: FILE
+     167             : /// 0x100: unsigned
+     168        1219 :   __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(void,1)
+     169        1730 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(char,(CHAR_MIN==0)*0x100+3)
+     170             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(signed char,3)
+     171             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned char,0x100+3)
+     172             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(short,3)
+     173             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned short,0x100+3)
+     174      264156 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(int,3)
+     175          98 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned int,0x100+3)
+     176             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long,3)
+     177             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned long,0x100+3)
+     178      246073 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long long,3)
+     179        3939 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(unsigned long long,0x100+3)
+     180           0 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(float,4)
+     181      242830 :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(double,4)
+     182             :   __PLUMED_WRAPPER_TYPESAFEPTR_SIZED(long double,4)
+     183         854 :   __PLUMED_WRAPPER_TYPESAFEPTR_EMPTY(FILE,5)
+     184             : 
+     185             :   ~TypesafePtr() {
+     186     2697409 :   }
+     187             : 
+     188             : 
+     189             :   TypesafePtr(const TypesafePtr&other) = delete;
+     190             : 
+     191             :   TypesafePtr & operator=(const TypesafePtr & other) = delete;
+     192             : 
+     193             :   TypesafePtr(TypesafePtr&&other):
+     194             :     buffer(other.buffer),
+     195             :     ptr(other.ptr==&other.buffer[0] ? &buffer[0] : other.ptr),
+     196             :     nelem(other.nelem),
+     197             :     shape(other.shape),
+     198             :     flags(other.flags)
+     199             :   {
+     200             :     other.ptr=nullptr;
+     201             :   }
+     202             : 
+     203             :   TypesafePtr copy() const;
+     204             : 
+     205      787625 :   TypesafePtr & operator=(TypesafePtr && other) {
+     206      787625 :     ptr=(other.ptr==&other.buffer[0] ? &buffer[0] : other.ptr);
+     207      787625 :     flags=other.flags;
+     208      787625 :     nelem=other.nelem;
+     209      787625 :     shape=other.shape;
+     210      787625 :     buffer=other.buffer;
+     211      787625 :     other.ptr=nullptr;
+     212      787625 :     return *this;
+     213             :   }
+     214             : 
+     215           5 :   std::string type_str() const {
+     216           5 :     auto type=(flags>>16)&0xff;
+     217           5 :     if(type==0) return "wildcard";
+     218           1 :     if(type==1) return "void";
+     219           0 :     if(type==2) return "integral";
+     220           0 :     if(type==3) return "integral";
+     221           4 :     if(type==4) return "floating point";
+     222           0 :     if(type==5) return "FILE";
+     223           0 :     return "unknown";
+     224             :   }
+     225             : 
+     226             : private:
+     227             : 
+     228             :   template<typename T>
+     229     1385392 :   T* get_priv(std::size_t nelem, const std::size_t* shape, bool byvalue) const {
+     230             : 
+     231     1385392 :     if(typesafePtrSkipCheck()) return (T*) ptr;
+     232             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     233     1385392 :     if(flags==0) return (T*) ptr; // no check
+     234     1383100 :     auto size=flags&0xffff;
+     235     1383100 :     auto type=(flags>>16)&0xff;
+     236             :     // auto unsi=(flags>>24)&0x1; // ignored
+     237     1384819 :     auto cons=(flags>>25)&0x7;
+     238             : 
+     239             :     // type=0: ignore check
+     240             :     // type>5: undefined yet
+     241     1383100 :     if(type!=0 && type<=5) {
+     242      529327 :       if(std::is_integral<T_noptr>::value && (type!=is_integral)) {
+     243          20 :         throw ExceptionTypeError() <<"This command expects an integer type. Received a " << type_str() << " instead"<<extra_msg();
+     244             :       }
+     245      852917 :       if(std::is_floating_point<T_noptr>::value && (type!=is_floating_point)) {
+     246           0 :         throw ExceptionTypeError() <<"This command expects a floating point type. Received a " << type_str() << " instead"<<extra_msg();
+     247             :       }
+     248         855 :       if(std::is_same<FILE,typename std::remove_const<T_noptr>::type>::value && (type!=is_file)) {
+     249           0 :         throw ExceptionTypeError() <<"This command expects a FILE. Received a " << type_str() << " instead"<<extra_msg();
+     250             :       }
+     251             :     }
+     252             : 
+     253     1383095 :     if(size>0 && typesafePtrSizeof<T_noptr>() >0 && typesafePtrSizeof<T_noptr>()!=size) {
+     254           0 :       throw ExceptionTypeError() << "This command expects a type with size " << typesafePtrSizeof<T_noptr>() << ". Received type has size " << size << " instead"<<extra_msg();
+     255             :     }
+     256             : 
+     257     1384814 :     if(!byvalue) if(cons==1) {
+     258           3 :         throw ExceptionTypeError() << "This command is trying to take the address of an argument that was passed by value"<<extra_msg();
+     259             :       }
+     260             : 
+     261             :     // cons==1 (by value) is here treated as cons==3 (const type*)
+     262     1380669 :     if(cons>0) {
+     263             :       if(!std::is_pointer<T>::value) {
+     264             :         if(std::is_void<T>::value) {
+     265        1719 :           if(cons==1) {
+     266           0 :             throw ExceptionTypeError() << "This command expects a void pointer. It received a value instead"<<extra_msg();
+     267             :           }
+     268             :         } else {
+     269     1378834 :           if(cons!=1 && cons!=2 && cons!=3) {
+     270           0 :             throw ExceptionTypeError() << "This command expects a pointer or a value. It received a pointer-to-pointer instead"<<extra_msg();
+     271             :           }
+     272             :         }
+     273             :         if(!std::is_const<T>::value) {
+     274      574103 :           if(cons==3) {
+     275           0 :             throw ExceptionTypeError() << "This command expects a modifiable pointer (T*). It received a non modifiable pointer instead (const T*)"<<extra_msg();
+     276      574103 :           } else if(cons==1) {
+     277           0 :             throw ExceptionTypeError() << "This command expects a modifiable pointer (T*). It received a value instead (T)"<<extra_msg();
+     278             :           }
+     279             :         }
+     280             :       } else {
+     281             :         if(!std::is_const<T>::value) {
+     282         116 :           if(cons==1) throw ExceptionTypeError() << "This command expects a pointer-to-pointer. It received a value intead"<<extra_msg();
+     283         116 :           if(cons==2 || cons==3) throw ExceptionTypeError() << "This command expects a pointer-to-pointer. It received a pointer intead"<<extra_msg();
+     284             :           if(!std::is_const<T_noptr>::value) {
+     285             :             if(cons!=4) throw ExceptionTypeError() << "This command expects a modifiable pointer-to-pointer (T**)"<<extra_msg();
+     286             :           } else {
+     287         116 :             if(cons!=6) throw ExceptionTypeError() << "This command expects a modifiable pointer to unmodifiable pointer (const T**)"<<extra_msg();
+     288             :           }
+     289             :         } else {
+     290             :           if(!std::is_const<T_noptr>::value) {
+     291             :             if(cons!=4 && cons!=5) throw ExceptionTypeError() << "This command expects T*const* pointer, and can only receive T**  or T*const* pointers"<<extra_msg();
+     292             :           }
+     293             :         }
+     294             :       }
+     295             :     }
+     296             :     // check full shape, if possible
+     297     1384813 :     if(shape && shape[0] && this->shape[0]) {
+     298         423 :       for(unsigned i=0; i<this->shape.size(); i++) {
+     299         423 :         if(shape[i]==0 && this->shape[i]!=0) {
+     300           0 :           throw ExceptionTypeError() << "Incorrect number of axis (passed greater than requested)"<<extra_msg();
+     301             :         }
+     302         423 :         if(shape[i]!=0 && this->shape[i]==0) {
+     303           0 :           throw ExceptionTypeError() << "Incorrect number of axis (requested greater than passed)"<<extra_msg();
+     304             :         }
+     305         423 :         if(shape[i]==0) break;
+     306         282 :         if(!(shape[i]<=this->shape[i])) {
+     307           0 :           throw ExceptionTypeError() << "This command wants to access " << shape[i] << " on axis " << i <<" of this pointer, but only " << this->shape[i] << " have been passed"<<extra_msg();
+     308             :         }
+     309             :       }
+     310             :     }
+     311     1384813 :     if(nelem==0 && shape && shape[0]>0) {
+     312      305360 :       nelem=1;
+     313      916080 :       for(unsigned i=0; i<this->shape.size(); i++) {
+     314      916080 :         if(shape[i]==0) break;
+     315      610720 :         nelem*=shape[i];
+     316             :       }
+     317             :     }
+     318             :     // check number of elements
+     319     1384813 :     if(nelem>0 && this->nelem>0) if(!(nelem<=this->nelem)) {
+     320          10 :         throw ExceptionTypeError() << "This command wants to access " << nelem << " from this pointer, but only " << this->nelem << " have been passed"<<extra_msg();
+     321             :       }
+     322     1384811 :     return (T*) ptr;
+     323             :   }
+     324             : 
+     325             : public:
+     326             : 
+     327             :   template<typename T>
+     328        7019 :   void set(T val) const {
+     329        7019 :     *get_priv<T>(0,nullptr,false)=val;
+     330        7019 :   }
+     331             : 
+     332             :   template<typename T>
+     333      690082 :   typename std::enable_if<std::is_pointer<T>::value,T>::type get() const {
+     334             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     335      695691 :     return get_priv<T_noptr>(0,nullptr,false);
+     336             :   }
+     337             : 
+     338             :   template<typename T>
+     339      270974 :   typename std::enable_if<!std::is_pointer<T>::value,T>::type get() const {
+     340      270974 :     return *get_priv<const T>(1,nullptr,true);
+     341             :   }
+     342             : 
+     343             :   template<typename T>
+     344             :   T get(std::size_t nelem) const {
+     345             :     static_assert(std::is_pointer<T>::value,"only pointer types allowed here");
+     346             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     347        6771 :     return get_priv<T_noptr>(nelem,nullptr,false);
+     348             :   }
+     349             : 
+     350             :   template<typename T>
+     351      404937 :   T get(std::initializer_list<std::size_t> shape) const {
+     352             :     static_assert(std::is_pointer<T>::value,"only pointer types allowed here");
+     353      404937 :     plumed_assert(shape.size()<=maxrank);
+     354             :     std::array<std::size_t,maxrank+1> shape_;
+     355             :     typedef typename std::remove_pointer<T>::type T_noptr;
+     356             :     unsigned j=0;
+     357     1214811 :     for(auto i : shape) {
+     358      809874 :       shape_[j]=i;
+     359      809874 :       j++;
+     360             :     }
+     361      404937 :     shape_[j]=0;
+     362      404937 :     return get_priv<T_noptr>(0,&shape_[0],false);
+     363             :   }
+     364             : 
+     365             :   operator bool() const noexcept {
+     366      643721 :     return ptr;
+     367             :   }
+     368             : 
+     369             :   void* getRaw() const noexcept {
+     370         222 :     return ptr;
+     371             :   }
+     372             : 
+     373             :   std::size_t getNelem() const noexcept {
+     374         222 :     return nelem;
+     375             :   }
+     376             : 
+     377             :   const std::size_t* getShape() const noexcept {
+     378             :     return shape.data();
+     379             :   }
+     380             : 
+     381             :   std::size_t getFlags() const noexcept {
+     382         222 :     return flags;
+     383             :   }
+     384             : 
+     385             : private:
+     386             :   std::array<char,32> buffer;
+     387             :   void* ptr=nullptr;
+     388             :   std::size_t nelem=0;
+     389             :   std::array<std::size_t,maxrank+1> shape; // make sure to initialize this!
+     390             :   std::size_t flags=0;
+     391             : };
+     392             : 
+     393             : }
+     394             : 
+     395             : 
+     396             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.cpp.func-sort-c.html b/coverage/tools/Units.cpp.func-sort-c.html new file mode 100644 index 000000000000..f6693db16a94 --- /dev/null +++ b/coverage/tools/Units.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:889790.7 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Units7setMassERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD5Units9setChargeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZN4PLMD5Units7setTimeEd6
_ZN4PLMD5Units7setTimeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZN4PLMD5Units9setEnergyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13
_ZN4PLMD5Units9setLengthERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE35
_ZN4PLMD5Units9setEnergyEd45
_ZN4PLMD5Units7setMassEd814
_ZN4PLMD5Units9setChargeEd814
_ZN4PLMD5Units9setLengthEd814
_ZN4PLMD5UnitsC2Ev1613173
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.cpp.func.html b/coverage/tools/Units.cpp.func.html new file mode 100644 index 000000000000..79d920d8bf01 --- /dev/null +++ b/coverage/tools/Units.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:889790.7 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5Units7setMassERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE3
_ZN4PLMD5Units7setMassEd814
_ZN4PLMD5Units7setTimeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE7
_ZN4PLMD5Units7setTimeEd6
_ZN4PLMD5Units9setChargeERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE4
_ZN4PLMD5Units9setChargeEd814
_ZN4PLMD5Units9setEnergyERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE13
_ZN4PLMD5Units9setEnergyEd45
_ZN4PLMD5Units9setLengthERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE35
_ZN4PLMD5Units9setLengthEd814
_ZN4PLMD5UnitsC2Ev1613173
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.cpp.gcov.html b/coverage/tools/Units.cpp.gcov.html new file mode 100644 index 000000000000..e987374d948f --- /dev/null +++ b/coverage/tools/Units.cpp.gcov.html @@ -0,0 +1,235 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:889790.7 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Units.h"
+      23             : #include "Tools.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : 
+      27     1613173 : Units::Units():
+      28     1613173 :   energy(1.0),
+      29     1613173 :   energyString("kj/mol"),
+      30     1613173 :   length(1.0),
+      31     1613173 :   lengthString("nm"),
+      32     1613173 :   time(1.0),
+      33     1613173 :   timeString("ps"),
+      34     1613173 :   charge(1.0),
+      35     1613173 :   chargeString("e"),
+      36     1613173 :   mass(1.0),
+      37     1613173 :   massString("amu")
+      38             : {
+      39     1613173 : }
+      40             : 
+      41          13 : void Units::setEnergy(const std::string &s) {
+      42          13 :   energyString=s;
+      43          13 :   if(s=="kj/mol") {
+      44           5 :     energy=1.0;
+      45           8 :   } else if(s=="kcal/mol") {
+      46           5 :     energy=4.184;
+      47           3 :   } else if(s=="j/mol") {
+      48           0 :     energy=0.001;
+      49           3 :   } else if(s=="eV") {
+      50           0 :     energy=96.48530749925792;
+      51           3 :   } else if(s =="Ha") {
+      52           1 :     energy=2625.499638;
+      53             :   } else {
+      54           2 :     energy=-1.0;
+      55             :     energyString="";
+      56           2 :     if(!Tools::convertNoexcept(s,energy)) {
+      57           0 :       plumed_merror("problem with setting the energy unit, either use give an numerical value or use one of the defined units: kj/mol, kcal/mol, j/mol, eV, Ha (case sensitive)");
+      58             :     }
+      59           2 :     plumed_massert(energy>0.0,"energy unit should be positive");
+      60             :   }
+      61          13 : }
+      62             : 
+      63          35 : void Units::setLength(const std::string &s) {
+      64          35 :   lengthString=s;
+      65          35 :   if(s=="nm") {
+      66           2 :     length=1.0;
+      67          33 :   } else if(s=="A") {
+      68          26 :     length=0.1;
+      69           7 :   } else if(s=="um") {
+      70           0 :     length=1000.0;
+      71           7 :   } else if(s=="Bohr") {
+      72           1 :     length=0.052917721067;
+      73             :   } else {
+      74           6 :     length=-1.0;
+      75             :     lengthString="";
+      76           6 :     if(!Tools::convertNoexcept(s,length)) {
+      77           0 :       plumed_merror("problem with setting the length unit, either use a numerical value or use one of the defined units: nm, A, um, Bohr (case sensitive)");
+      78             :     }
+      79           6 :     plumed_massert(length>0.0,"length unit should be positive");
+      80             :   }
+      81          35 : }
+      82             : 
+      83           7 : void Units::setTime(const std::string &s) {
+      84           7 :   timeString=s;
+      85           7 :   if(s=="ps") {
+      86           2 :     time=1.0;
+      87           5 :   } else if(s=="ns") {
+      88           0 :     time=1000.0;
+      89           5 :   } else if(s=="fs") {
+      90           2 :     time=0.001;
+      91           3 :   } else if(s=="atomic") {
+      92           1 :     time=2.418884326509e-5;
+      93             :   } else {
+      94           2 :     time=-1.0;
+      95             :     timeString="";
+      96           2 :     if(!Tools::convertNoexcept(s,time)) {
+      97           0 :       plumed_merror("problem with setting the time unit, either use a numerical value or use one of the defined units: ps, fs, atomic (case sensitive)");
+      98             :     }
+      99           2 :     plumed_massert(time>0.0,"time unit should be positive");
+     100             :   }
+     101           7 : }
+     102             : 
+     103           4 : void Units::setCharge(const std::string &s) {
+     104           4 :   chargeString=s;
+     105           4 :   if(s=="e") {
+     106           1 :     charge=1.0;
+     107             :   } else {
+     108           3 :     charge=-1.0;
+     109             :     chargeString="";
+     110           3 :     if(!Tools::convertNoexcept(s,charge)) {
+     111           0 :       plumed_merror("problem with setting the charge unit, either use a numerical value or use one of the defined units: e (case sensitive)");
+     112             :     }
+     113           3 :     plumed_massert(charge>0.0,"charge unit should be positive");
+     114             :   }
+     115           4 : }
+     116             : 
+     117           3 : void Units::setMass(const std::string &s) {
+     118           3 :   massString=s;
+     119           3 :   if(s=="amu") {
+     120           1 :     mass=1.0;
+     121             :   } else {
+     122           2 :     mass=-1.0;
+     123             :     massString="";
+     124           2 :     if(!Tools::convertNoexcept(s,mass)) {
+     125           0 :       plumed_merror("problem with setting the mass unit, either use a numerical value or use one of the defined units: amu (case sensitive)");
+     126             :     }
+     127           2 :     plumed_massert(mass>0.0,"mass unit should be positive");
+     128             :   }
+     129           3 : }
+     130             : 
+     131          45 : void Units::setEnergy(const double s) {
+     132          45 :   energyString="";
+     133          45 :   energy=s;
+     134          45 : }
+     135             : 
+     136         814 : void Units::setLength(const double s) {
+     137         814 :   lengthString="";
+     138         814 :   length=s;
+     139         814 : }
+     140             : 
+     141           6 : void Units::setTime(const double s) {
+     142           6 :   timeString="";
+     143           6 :   time=s;
+     144           6 : }
+     145             : 
+     146         814 : void Units::setCharge(const double s) {
+     147         814 :   chargeString="";
+     148         814 :   charge=s;
+     149         814 : }
+     150             : 
+     151         814 : void Units::setMass(const double s) {
+     152         814 :   massString="";
+     153         814 :   mass=s;
+     154         814 : }
+     155             : 
+     156             : 
+     157             : 
+     158             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.h.func-sort-c.html b/coverage/tools/Units.h.func-sort-c.html new file mode 100644 index 000000000000..b6966965d364 --- /dev/null +++ b/coverage/tools/Units.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.h.func.html b/coverage/tools/Units.h.func.html new file mode 100644 index 000000000000..db6641623aa0 --- /dev/null +++ b/coverage/tools/Units.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Units.h.gcov.html b/coverage/tools/Units.h.gcov.html new file mode 100644 index 000000000000..3d2172df286f --- /dev/null +++ b/coverage/tools/Units.h.gcov.html @@ -0,0 +1,244 @@ + + + + + + + + LCOV - plumed test coverage - tools/Units.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Units.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Units_h
+      23             : #define __PLUMED_tools_Units_h
+      24             : 
+      25             : #include <string>
+      26             : 
+      27             : namespace PLMD {
+      28             : 
+      29             : /**
+      30             : \ingroup TOOLBOX
+      31             : Small utility class that contains information about units.
+      32             : 
+      33             : This class can be used to contain in a single place all the
+      34             : information about units. Units are expressed in terms of
+      35             : standard PLUMED units, i.e. kj/mol, nm, and ps.
+      36             : Units can be set as double or as string. In the latter case,
+      37             : one can also use strings such as kcal/mol.
+      38             : 
+      39             : 
+      40             : */
+      41             : class Units {
+      42             : /// Units for energy, expressed in kj/mol (e.g. 4.184 means kcal/mol)
+      43             :   double energy;
+      44             :   std::string energyString;
+      45             : /// Units for length, expressed in nm (e.g. 0.1 means A)
+      46             :   double length;
+      47             :   std::string lengthString;
+      48             : /// Units for time, expressed in ps (e.g. 0.001 means fs)
+      49             :   double time;
+      50             :   std::string timeString;
+      51             : /// Units for charges, expressed in proton charge (e.g. 1./18.2223 are sqrt(kcal/mol*A), as used in Amber)
+      52             :   double charge;
+      53             :   std::string chargeString;
+      54             : /// Units for masses, expressed in amu
+      55             :   double mass;
+      56             :   std::string massString;
+      57             : public:
+      58             : /// Constructor, setting default values (1.0)
+      59             :   Units();
+      60             : /// Set energy units from string.
+      61             : /// Also understands the following strings:
+      62             : /// kj/mol, kcal/mol, j/mol, eV, and Ha.
+      63             :   void setEnergy(const std::string &);
+      64             : /// Set time units from string.
+      65             : /// Also understands the following strings:
+      66             : /// ps, ns, fs, and atomic.
+      67             :   void setTime(const std::string &);
+      68             : /// Set length units from string.
+      69             : /// Also understands the following strings:
+      70             : /// nm, A, um, and Bohr.
+      71             :   void setLength(const std::string &);
+      72             : /// Set charge units from string.
+      73             :   void setCharge(const std::string &);
+      74             : /// Set mass units from string.
+      75             :   void setMass(const std::string &);
+      76             : /// Set energy units from double.
+      77             : /// Should be specified in units of kj/mol (e.g. 4.184 means kcal/mol)
+      78             :   void setEnergy(double);
+      79             : /// Set time units from double.
+      80             : /// Should be specified in units of ps (e.g. 0.001 means fs)
+      81             :   void setTime(double);
+      82             : /// Set length units from double.
+      83             : /// Should be specified in units of nm (e.g. 0.1 means A)
+      84             :   void setLength(double);
+      85             : /// Set charge units from double.
+      86             : /// Should be specified in units of proton charge.
+      87             :   void setCharge(double);
+      88             : /// Set mass units from double.
+      89             : /// Should be specified in units of amu.
+      90             :   void setMass(double);
+      91             : /// Get energy units as double.
+      92             :   const double & getEnergy()const;
+      93             : /// Get length units as double.
+      94             :   const double & getLength()const;
+      95             : /// Get time units as double.
+      96             :   const double & getTime()const;
+      97             : /// Get charge units as double.
+      98             :   const double & getCharge()const;
+      99             : /// Get mass units as double.
+     100             :   const double & getMass()const;
+     101             : /// Get energy units as string.
+     102             :   const std::string & getEnergyString()const;
+     103             : /// Get length units as string.
+     104             :   const std::string & getLengthString()const;
+     105             : /// Get time units as string.
+     106             :   const std::string & getTimeString()const;
+     107             : /// Get charge units as string.
+     108             :   const std::string & getChargeString()const;
+     109             : /// Get mass units as string.
+     110             :   const std::string & getMassString()const;
+     111             : };
+     112             : 
+     113             : inline
+     114             : const double & Units::getEnergy()const {
+     115             :   return energy;
+     116             : }
+     117             : 
+     118             : inline
+     119             : const double & Units::getLength()const {
+     120             :   return length;
+     121             : }
+     122             : 
+     123             : inline
+     124             : const double & Units::getTime()const {
+     125             :   return time;
+     126             : }
+     127             : 
+     128             : inline
+     129             : const double & Units::getCharge()const {
+     130             :   return charge;
+     131             : }
+     132             : 
+     133             : inline
+     134             : const double & Units::getMass()const {
+     135             :   return mass;
+     136             : }
+     137             : 
+     138             : inline
+     139             : const std::string & Units::getEnergyString()const {
+     140             :   return energyString;
+     141             : }
+     142             : 
+     143             : inline
+     144             : const std::string & Units::getLengthString()const {
+     145    14342730 :   return lengthString;
+     146             : }
+     147             : 
+     148             : inline
+     149             : const std::string & Units::getTimeString()const {
+     150             :   return timeString;
+     151             : }
+     152             : 
+     153             : inline
+     154             : const std::string & Units::getChargeString()const {
+     155             :   return chargeString;
+     156             : }
+     157             : 
+     158             : inline
+     159             : const std::string & Units::getMassString()const {
+     160             :   return massString;
+     161             : }
+     162             : 
+     163             : 
+     164             : 
+     165             : }
+     166             : 
+     167             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Vector.h.func-sort-c.html b/coverage/tools/Vector.h.func-sort-c.html new file mode 100644 index 000000000000..8c264f8d74db --- /dev/null +++ b/coverage/tools/Vector.h.func-sort-c.html @@ -0,0 +1,333 @@ + + + + + + + + LCOV - plumed test coverage - tools/Vector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Vector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6666100.0 %
Date:2024-02-22 21:58:45Functions:516578.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJjEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJjjEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EEC2IJjjEEEdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJdEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJdddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJddddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EEC2Ev0
_ZN4PLMD13VectorGenericILj5EEC2IJddddEEEdDpT_0
_ZN4PLMD13VectorGenericILj5EEixEj0
_ZN4PLMD13VectorGenericILj5EEmLEd0
_ZN4PLMDmlILj5EEENS_13VectorGenericIXT_EEEdRKS2_0
_ZNK4PLMD13VectorGenericILj5EEixEj0
_ZN4PLMD13VectorGenericILj6EEC2Ev4004
_ZN4PLMD13VectorGenericILj3EEdVEd43767
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdiEEEvdDpT_103260
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJidEEEvdDpT_103260
_ZN4PLMD13VectorGenericILj3EEC2IJdiEEEdDpT_103260
_ZN4PLMD13VectorGenericILj3EEC2IJidEEEdDpT_103260
_ZN4PLMD13VectorGenericILj1EEC2Ev548920
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJddEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdddEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EEC2IJdddEEEdDpT_555994
_ZN4PLMD13VectorGenericILj1EEixEj1097840
_ZN4PLMD13VectorGenericILj4EEmIERKS1_1119102
_ZN4PLMD5deltaILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMDmiILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZNK4PLMD13VectorGenericILj4EE7modulo2Ev1119102
_ZN4PLMD13VectorGenericILj4EEC2Ev1747526
_ZN4PLMD13VectorGenericILj3EE4zeroEv4205664
_ZNK4PLMD13VectorGenericILj4EEclEj4618728
_ZN4PLMD12crossProductERKNS_13VectorGenericILj3EEES3_4881138
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiiEEEvdDpT_13711248
_ZN4PLMD13VectorGenericILj3EEC2IJiiEEEdDpT_13711248
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiEEEvdDpT_13814508
_ZN4PLMD6moduloILj3EEEdRKNS_13VectorGenericIXT_EEE22918220
_ZN4PLMD13VectorGenericILj4EEixEj27766290
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJddEEEvdDpT_28902118
_ZN4PLMD13VectorGenericILj3EEC2IJddEEEdDpT_28902118
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdEEEvdDpT_29005378
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJEEEvdDpT_42819886
_ZN4PLMD13VectorGenericILj6EEixEj63649362
_ZN4PLMDdvILj3EEENS_13VectorGenericIXT_EEERKS2_d72642027
_ZNK4PLMD13VectorGenericILj3EEngEv107429763
_ZNK4PLMD13VectorGenericILj3EE6moduloEv117886856
_ZN4PLMD10dotProductILj3EEEdRKNS_13VectorGenericIXT_EEES4_166523689
_ZN4PLMD7modulo2ILj3EEEdRKNS_13VectorGenericIXT_EEE202830009
_ZN4PLMD5deltaILj3EEENS_13VectorGenericIXT_EEERKS2_S4_352728852
_ZNK4PLMD13VectorGenericILj6EEixEj396376380
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEERKS2_d442973670
_ZN4PLMD13VectorGenericILj3EEC2Ev483454351
_ZNK4PLMD13VectorGenericILj3EE7modulo2Ev783084970
_ZN4PLMDmiILj3EEENS_13VectorGenericIXT_EEERKS2_S4_896738557
_ZN4PLMD13VectorGenericILj3EEmIERKS1_1215425031
_ZNK4PLMD13VectorGenericILj3EEclEj1261549938
_ZN4PLMD13VectorGenericILj3EEclEj1266858099
_ZN4PLMDplILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1368521864
_ZN4PLMD13VectorGenericILj3EEixEj1448847257
_ZN4PLMD13VectorGenericILj3EEpLERKS1_1741184929
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEEdRKS2_1827477525
_ZN4PLMD13VectorGenericILj3EEmLEd1827864120
_ZNK4PLMD13VectorGenericILj3EEixEj3353834660
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Vector.h.func.html b/coverage/tools/Vector.h.func.html new file mode 100644 index 000000000000..d36e851c2bcd --- /dev/null +++ b/coverage/tools/Vector.h.func.html @@ -0,0 +1,333 @@ + + + + + + + + LCOV - plumed test coverage - tools/Vector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Vector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6666100.0 %
Date:2024-02-22 21:58:45Functions:516578.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10dotProductILj3EEEdRKNS_13VectorGenericIXT_EEES4_166523689
_ZN4PLMD12crossProductERKNS_13VectorGenericILj3EEES3_4881138
_ZN4PLMD13VectorGenericILj1EEC2Ev548920
_ZN4PLMD13VectorGenericILj1EEixEj1097840
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJEEEvdDpT_42819886
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdEEEvdDpT_29005378
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJddEEEvdDpT_28902118
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJdiEEEvdDpT_103260
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiEEEvdDpT_13814508
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJidEEEvdDpT_103260
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJiiEEEvdDpT_13711248
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJjEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE20auxiliaryConstructorIJjjEEEvdDpT_0
_ZN4PLMD13VectorGenericILj3EE4zeroEv4205664
_ZN4PLMD13VectorGenericILj3EEC2Ev483454351
_ZN4PLMD13VectorGenericILj3EEC2IJddEEEdDpT_28902118
_ZN4PLMD13VectorGenericILj3EEC2IJdiEEEdDpT_103260
_ZN4PLMD13VectorGenericILj3EEC2IJidEEEdDpT_103260
_ZN4PLMD13VectorGenericILj3EEC2IJiiEEEdDpT_13711248
_ZN4PLMD13VectorGenericILj3EEC2IJjjEEEdDpT_0
_ZN4PLMD13VectorGenericILj3EEclEj1266858099
_ZN4PLMD13VectorGenericILj3EEdVEd43767
_ZN4PLMD13VectorGenericILj3EEixEj1448847257
_ZN4PLMD13VectorGenericILj3EEmIERKS1_1215425031
_ZN4PLMD13VectorGenericILj3EEmLEd1827864120
_ZN4PLMD13VectorGenericILj3EEpLERKS1_1741184929
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJddEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EE20auxiliaryConstructorIJdddEEEvdDpT_555994
_ZN4PLMD13VectorGenericILj4EEC2Ev1747526
_ZN4PLMD13VectorGenericILj4EEC2IJdddEEEdDpT_555994
_ZN4PLMD13VectorGenericILj4EEixEj27766290
_ZN4PLMD13VectorGenericILj4EEmIERKS1_1119102
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJdEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJdddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EE20auxiliaryConstructorIJddddEEEvdDpT_0
_ZN4PLMD13VectorGenericILj5EEC2Ev0
_ZN4PLMD13VectorGenericILj5EEC2IJddddEEEdDpT_0
_ZN4PLMD13VectorGenericILj5EEixEj0
_ZN4PLMD13VectorGenericILj5EEmLEd0
_ZN4PLMD13VectorGenericILj6EEC2Ev4004
_ZN4PLMD13VectorGenericILj6EEixEj63649362
_ZN4PLMD5deltaILj3EEENS_13VectorGenericIXT_EEERKS2_S4_352728852
_ZN4PLMD5deltaILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMD6moduloILj3EEEdRKNS_13VectorGenericIXT_EEE22918220
_ZN4PLMD7modulo2ILj3EEEdRKNS_13VectorGenericIXT_EEE202830009
_ZN4PLMDdvILj3EEENS_13VectorGenericIXT_EEERKS2_d72642027
_ZN4PLMDmiILj3EEENS_13VectorGenericIXT_EEERKS2_S4_896738557
_ZN4PLMDmiILj4EEENS_13VectorGenericIXT_EEERKS2_S4_1119102
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEERKS2_d442973670
_ZN4PLMDmlILj3EEENS_13VectorGenericIXT_EEEdRKS2_1827477525
_ZN4PLMDmlILj5EEENS_13VectorGenericIXT_EEEdRKS2_0
_ZN4PLMDplILj3EEENS_13VectorGenericIXT_EEERKS2_S4_1368521864
_ZNK4PLMD13VectorGenericILj3EE6moduloEv117886856
_ZNK4PLMD13VectorGenericILj3EE7modulo2Ev783084970
_ZNK4PLMD13VectorGenericILj3EEclEj1261549938
_ZNK4PLMD13VectorGenericILj3EEixEj3353834660
_ZNK4PLMD13VectorGenericILj3EEngEv107429763
_ZNK4PLMD13VectorGenericILj4EE7modulo2Ev1119102
_ZNK4PLMD13VectorGenericILj4EEclEj4618728
_ZNK4PLMD13VectorGenericILj5EEixEj0
_ZNK4PLMD13VectorGenericILj6EEixEj396376380
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/Vector.h.gcov.html b/coverage/tools/Vector.h.gcov.html new file mode 100644 index 000000000000..166f0ef4ae58 --- /dev/null +++ b/coverage/tools/Vector.h.gcov.html @@ -0,0 +1,420 @@ + + + + + + + + LCOV - plumed test coverage - tools/Vector.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - Vector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6666100.0 %
Date:2024-02-22 21:58:45Functions:516578.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_tools_Vector_h
+      23             : #define __PLUMED_tools_Vector_h
+      24             : 
+      25             : #include <cmath>
+      26             : #include <iosfwd>
+      27             : #include <array>
+      28             : #include "LoopUnroller.h"
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : /**
+      33             : \ingroup TOOLBOX
+      34             : Class implementing fixed size vectors of doubles
+      35             : 
+      36             : \tparam n The number of elements of the vector.
+      37             : 
+      38             : This class implements a vector of doubles with size fixed at
+      39             : compile time. It is useful for small fixed size objects (e.g.
+      40             : 3d vectors) as it does not waste space to store the vector size.
+      41             : Moreover, as the compiler knows the size, it can be completely
+      42             : opimized inline.
+      43             : All the methods are inlined for better optimization and
+      44             : all the loops are explicitly unrolled using PLMD::LoopUnroller class.
+      45             : Vector elements are initialized to zero by default. Notice that
+      46             : this means that constructor is a bit slow. This point might change
+      47             : in future if we find performance issues.
+      48             : Accepts both [] and () syntax for access.
+      49             : Several functions are declared as friends even if not necessary so as to
+      50             : properly appear in Doxygen documentation.
+      51             : 
+      52             : Aliases are defined to simplify common declarations (Vector, Vector2d, Vector3d, Vector4d).
+      53             : Also notice that some operations are only available for 3 dimensional vectors.
+      54             : 
+      55             : Example of usage
+      56             : \verbatim
+      57             : #include "Vector.h"
+      58             : 
+      59             : using namespace PLMD;
+      60             : 
+      61             : int main(){
+      62             :   VectorGeneric<3> v1;
+      63             :   v1[0]=3.0;
+      64             : // use equivalently () and [] syntax:
+      65             :   v1(1)=5.0;
+      66             : // initialize with components
+      67             :   VectorGeneric<3> v2=VectorGeneric<3>(1.0,2.0,3.0);
+      68             :   VectorGeneric<3> v3=crossProduct(v1,v2);
+      69             :   double d=dotProduct(v1,v2);
+      70             :   v3+=v1;
+      71             :   v2=v1+2.0*v3;
+      72             : }
+      73             : \endverbatim
+      74             : 
+      75             : */
+      76             : 
+      77             : 
+      78             : template <unsigned n>
+      79             : class VectorGeneric {
+      80             :   std::array<double,n> d;
+      81             : /// Auxiliary private function for constructor
+      82             :   void auxiliaryConstructor();
+      83             : /// Auxiliary private function for constructor
+      84             :   template<typename... Args>
+      85             :   void auxiliaryConstructor(double first,Args... arg);
+      86             : public:
+      87             : /// Constructor accepting n double parameters.
+      88             : /// Can be used as Vector<3>(1.0,2.0,3.0) or Vector<2>(2.0,3.0).
+      89             : /// In case a wrong number of parameters is given, a static assertion will fail.
+      90             :   template<typename... Args>
+      91             :   VectorGeneric(double first,Args... arg);
+      92             : /// create it null
+      93             :   VectorGeneric();
+      94             : /// set it to zero
+      95             :   void zero();
+      96             : /// array-like access [i]
+      97             :   double & operator[](unsigned i);
+      98             : /// array-like access [i]
+      99             :   const double & operator[](unsigned i)const;
+     100             : /// parenthesis access (i)
+     101             :   double & operator()(unsigned i);
+     102             : /// parenthesis access (i)
+     103             :   const double & operator()(unsigned i)const;
+     104             : /// increment
+     105             :   VectorGeneric& operator +=(const VectorGeneric& b);
+     106             : /// decrement
+     107             :   VectorGeneric& operator -=(const VectorGeneric& b);
+     108             : /// multiply
+     109             :   VectorGeneric& operator *=(double s);
+     110             : /// divide
+     111             :   VectorGeneric& operator /=(double s);
+     112             : /// sign +
+     113             :   VectorGeneric operator +()const;
+     114             : /// sign -
+     115             :   VectorGeneric operator -()const;
+     116             : /// return v1+v2
+     117             :   template<unsigned m>
+     118             :   friend VectorGeneric<m> operator+(const VectorGeneric<m>&,const VectorGeneric<m>&);
+     119             : /// return v1-v2
+     120             :   template<unsigned m>
+     121             :   friend VectorGeneric<m> operator-(const VectorGeneric<m>&,const VectorGeneric<m>&);
+     122             : /// return s*v
+     123             :   template<unsigned m>
+     124             :   friend VectorGeneric<m> operator*(double,const VectorGeneric<m>&);
+     125             : /// return v*s
+     126             :   template<unsigned m>
+     127             :   friend VectorGeneric<m> operator*(const VectorGeneric<m>&,double);
+     128             : /// return v/s
+     129             :   template<unsigned m>
+     130             :   friend VectorGeneric<m> operator/(const VectorGeneric<m>&,double);
+     131             : /// return v2-v1
+     132             :   template<unsigned m>
+     133             :   friend VectorGeneric<m> delta(const VectorGeneric<m>&v1,const VectorGeneric<m>&v2);
+     134             : /// return v1 .scalar. v2
+     135             :   template<unsigned m>
+     136             :   friend double dotProduct(const VectorGeneric<m>&,const VectorGeneric<m>&);
+     137             : /// return v1 .vector. v2
+     138             : /// Only available for size 3
+     139             :   friend VectorGeneric<3> crossProduct(const VectorGeneric<3>&,const VectorGeneric<3>&);
+     140             : /// compute the squared modulo
+     141             :   double modulo2()const;
+     142             : /// Compute the modulo.
+     143             : /// Shortcut for sqrt(v.modulo2())
+     144             :   double modulo()const;
+     145             : /// friend version of modulo2 (to simplify some syntax)
+     146             :   template<unsigned m>
+     147             :   friend double modulo2(const VectorGeneric<m>&);
+     148             : /// friend version of modulo (to simplify some syntax)
+     149             :   template<unsigned m>
+     150             :   friend double modulo(const VectorGeneric<m>&);
+     151             : /// << operator.
+     152             : /// Allows printing vector `v` with `std::cout<<v;`
+     153             :   template<unsigned m>
+     154             :   friend std::ostream & operator<<(std::ostream &os, const VectorGeneric<m>&);
+     155             : };
+     156             : 
+     157             : template <unsigned n>
+     158             : void VectorGeneric<n>::auxiliaryConstructor()
+     159             : {}
+     160             : 
+     161             : template <unsigned n>
+     162             : template<typename... Args>
+     163   130683634 : void VectorGeneric<n>::auxiliaryConstructor(double first,Args... arg)
+     164             : {
+     165   130683634 :   d[n-(sizeof...(Args))-1]=first;
+     166    87307754 :   auxiliaryConstructor(arg...);
+     167   130683634 : }
+     168             : 
+     169             : template <unsigned n>
+     170             : template<typename... Args>
+     171    43375880 : VectorGeneric<n>::VectorGeneric(double first,Args... arg)
+     172             : {
+     173             :   static_assert((sizeof...(Args))+1==n,"you are trying to initialize a Vector with the wrong number of arguments");
+     174    43375880 :   auxiliaryConstructor(first,arg...);
+     175    43375880 : }
+     176             : 
+     177             : template <unsigned n>
+     178     4205664 : void VectorGeneric<n>::zero() {
+     179     4205664 :   LoopUnroller<n>::_zero(d.data());
+     180     4205664 : }
+     181             : 
+     182             : template <unsigned n>
+     183   485754801 : VectorGeneric<n>::VectorGeneric() {
+     184   485205881 :   LoopUnroller<n>::_zero(d.data());
+     185   485754801 : }
+     186             : 
+     187             : template <unsigned n>
+     188  1541360749 : double & VectorGeneric<n>::operator[](unsigned i) {
+     189  1541360749 :   return d[i];
+     190             : }
+     191             : 
+     192             : template <unsigned n>
+     193  3750211040 : const double & VectorGeneric<n>::operator[](unsigned i)const {
+     194  3750211040 :   return d[i];
+     195             : }
+     196             : 
+     197             : template <unsigned n>
+     198  1266858099 : double & VectorGeneric<n>::operator()(unsigned i) {
+     199  1266858099 :   return d[i];
+     200             : }
+     201             : 
+     202             : template <unsigned n>
+     203  1266168666 : const double & VectorGeneric<n>::operator()(unsigned i)const {
+     204  1266168666 :   return d[i];
+     205             : }
+     206             : 
+     207             : template <unsigned n>
+     208  1741184929 : VectorGeneric<n>& VectorGeneric<n>::operator +=(const VectorGeneric<n>& b) {
+     209  1741184929 :   LoopUnroller<n>::_add(d.data(),b.d.data());
+     210  1741184929 :   return *this;
+     211             : }
+     212             : 
+     213             : template <unsigned n>
+     214  1216544133 : VectorGeneric<n>& VectorGeneric<n>::operator -=(const VectorGeneric<n>& b) {
+     215  1216544133 :   LoopUnroller<n>::_sub(d.data(),b.d.data());
+     216  1216544133 :   return *this;
+     217             : }
+     218             : 
+     219             : template <unsigned n>
+     220  1827864120 : VectorGeneric<n>& VectorGeneric<n>::operator *=(double s) {
+     221  1827864120 :   LoopUnroller<n>::_mul(d.data(),s);
+     222  1827864120 :   return *this;
+     223             : }
+     224             : 
+     225             : template <unsigned n>
+     226       43767 : VectorGeneric<n>& VectorGeneric<n>::operator /=(double s) {
+     227       43767 :   LoopUnroller<n>::_mul(d.data(),1.0/s);
+     228       43767 :   return *this;
+     229             : }
+     230             : 
+     231             : template <unsigned n>
+     232             : VectorGeneric<n>  VectorGeneric<n>::operator +()const {
+     233             :   return *this;
+     234             : }
+     235             : 
+     236             : template <unsigned n>
+     237   107429763 : VectorGeneric<n> VectorGeneric<n>::operator -()const {
+     238   107429763 :   VectorGeneric<n> r;
+     239   107429763 :   LoopUnroller<n>::_neg(r.d.data(),d.data());
+     240   107429763 :   return r;
+     241             : }
+     242             : 
+     243             : template <unsigned n>
+     244  1368521864 : VectorGeneric<n> operator+(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     245  1368521864 :   VectorGeneric<n> v(v1);
+     246  1368521864 :   return v+=v2;
+     247             : }
+     248             : 
+     249             : template <unsigned n>
+     250   897857659 : VectorGeneric<n> operator-(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     251   897857659 :   VectorGeneric<n> v(v1);
+     252   897857659 :   return v-=v2;
+     253             : }
+     254             : 
+     255             : template <unsigned n>
+     256  1827477525 : VectorGeneric<n> operator*(double s,const VectorGeneric<n>&v) {
+     257  1827477525 :   VectorGeneric<n> vv(v);
+     258  1827477525 :   return vv*=s;
+     259             : }
+     260             : 
+     261             : template <unsigned n>
+     262   442973670 : VectorGeneric<n> operator*(const VectorGeneric<n>&v,double s) {
+     263   442973670 :   return s*v;
+     264             : }
+     265             : 
+     266             : template <unsigned n>
+     267    72642027 : VectorGeneric<n> operator/(const VectorGeneric<n>&v,double s) {
+     268    72642027 :   return v*(1.0/s);
+     269             : }
+     270             : 
+     271             : template <unsigned n>
+     272   353847954 : VectorGeneric<n> delta(const VectorGeneric<n>&v1,const VectorGeneric<n>&v2) {
+     273   353847954 :   return v2-v1;
+     274             : }
+     275             : 
+     276             : template <unsigned n>
+     277   784204072 : double VectorGeneric<n>::modulo2()const {
+     278   784204072 :   return LoopUnroller<n>::_sum2(d.data());
+     279             : }
+     280             : 
+     281             : template <unsigned n>
+     282   166523689 : double dotProduct(const VectorGeneric<n>& v1,const VectorGeneric<n>& v2) {
+     283   166523689 :   return LoopUnroller<n>::_dot(v1.d.data(),v2.d.data());
+     284             : }
+     285             : 
+     286             : inline
+     287     4881138 : VectorGeneric<3> crossProduct(const VectorGeneric<3>& v1,const VectorGeneric<3>& v2) {
+     288             :   return VectorGeneric<3>(
+     289     4881138 :            v1[1]*v2[2]-v1[2]*v2[1],
+     290     4881138 :            v1[2]*v2[0]-v1[0]*v2[2],
+     291     4881138 :            v1[0]*v2[1]-v1[1]*v2[0]);
+     292             : }
+     293             : 
+     294             : template<unsigned n>
+     295   117886856 : double VectorGeneric<n>::modulo()const {
+     296   117886856 :   return sqrt(modulo2());
+     297             : }
+     298             : 
+     299             : template<unsigned n>
+     300   202830009 : double modulo2(const VectorGeneric<n>&v) {
+     301   202830009 :   return v.modulo2();
+     302             : }
+     303             : 
+     304             : template<unsigned n>
+     305    22918220 : double modulo(const VectorGeneric<n>&v) {
+     306    22918220 :   return v.modulo();
+     307             : }
+     308             : 
+     309             : template<unsigned n>
+     310             : std::ostream & operator<<(std::ostream &os, const VectorGeneric<n>& v) {
+     311             :   for(unsigned i=0; i<n-1; i++) os<<v(i)<<" ";
+     312             :   os<<v(n-1);
+     313             :   return os;
+     314             : }
+     315             : 
+     316             : 
+     317             : /// \ingroup TOOLBOX
+     318             : /// Alias for one dimensional vectors
+     319             : typedef VectorGeneric<1> Vector1d;
+     320             : /// \ingroup TOOLBOX
+     321             : /// Alias for two dimensional vectors
+     322             : typedef VectorGeneric<2> Vector2d;
+     323             : /// \ingroup TOOLBOX
+     324             : /// Alias for three dimensional vectors
+     325             : typedef VectorGeneric<3> Vector3d;
+     326             : /// \ingroup TOOLBOX
+     327             : /// Alias for four dimensional vectors
+     328             : typedef VectorGeneric<4> Vector4d;
+     329             : /// \ingroup TOOLBOX
+     330             : /// Alias for five dimensional vectors
+     331             : typedef VectorGeneric<5> Vector5d;
+     332             : /// \ingroup TOOLBOX
+     333             : /// Alias for three dimensional vectors
+     334             : typedef Vector3d Vector;
+     335             : 
+     336             : static_assert(sizeof(VectorGeneric<2>)==2*sizeof(double), "code cannot work if this is not satisfied");
+     337             : static_assert(sizeof(VectorGeneric<3>)==3*sizeof(double), "code cannot work if this is not satisfied");
+     338             : static_assert(sizeof(VectorGeneric<4>)==4*sizeof(double), "code cannot work if this is not satisfied");
+     339             : 
+     340             : }
+     341             : 
+     342             : #endif
+     343             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/h36.cpp.func-sort-c.html b/coverage/tools/h36.cpp.func-sort-c.html new file mode 100644 index 000000000000..0740fd022cc1 --- /dev/null +++ b/coverage/tools/h36.cpp.func-sort-c.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - tools/h36.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - h36.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8912770.1 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3h36L15fill_with_starsEjPc0
_ZN4PLMD3h36L17unsupported_widthEv0
_ZN4PLMD3h36L18value_out_of_rangeEv0
_ZN4PLMD3h36L22invalid_number_literalEv2
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE0_clEv221
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE_clEv221
_ZN4PLMD3h36L12digits_lowerEv7957
_ZN4PLMD3h3610hy36encodeEjiPc103780
_ZN4PLMD3h36L11encode_pureEPKcjjiPc103780
_ZN4PLMD3h36L12digits_upperEv111735
_ZN4PLMD3h3610hy36decodeEjPKcjPi543604
_ZN4PLMD3h36L11decode_pureEPKijPKcjPi543604
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/h36.cpp.func.html b/coverage/tools/h36.cpp.func.html new file mode 100644 index 000000000000..50d3c9136cdd --- /dev/null +++ b/coverage/tools/h36.cpp.func.html @@ -0,0 +1,121 @@ + + + + + + + + LCOV - plumed test coverage - tools/h36.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - h36.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8912770.1 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3h3610hy36decodeEjPKcjPi543604
_ZN4PLMD3h3610hy36encodeEjiPc103780
_ZN4PLMD3h36L11decode_pureEPKijPKcjPi543604
_ZN4PLMD3h36L11encode_pureEPKcjjiPc103780
_ZN4PLMD3h36L12digits_lowerEv7957
_ZN4PLMD3h36L12digits_upperEv111735
_ZN4PLMD3h36L15fill_with_starsEjPc0
_ZN4PLMD3h36L17unsupported_widthEv0
_ZN4PLMD3h36L18value_out_of_rangeEv0
_ZN4PLMD3h36L22invalid_number_literalEv2
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE0_clEv221
_ZZN4PLMD3h3610hy36decodeEjPKcjPiENKUlvE_clEv221
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/h36.cpp.gcov.html b/coverage/tools/h36.cpp.gcov.html new file mode 100644 index 000000000000..484cb935e72a --- /dev/null +++ b/coverage/tools/h36.cpp.gcov.html @@ -0,0 +1,412 @@ + + + + + + + + LCOV - plumed test coverage - tools/h36.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - tools - h36.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:8912770.1 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2018-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "h36.h"
+      23             : #include <vector>
+      24             : #include "Exception.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : 
+      28             : /// Tiny namespace for hybrid36 format.
+      29             : /// This namespace includes freely available tools for h36 format.
+      30             : namespace h36 {
+      31             : 
+      32             : 
+      33             : /*! C port of the hy36encode() and hy36decode() functions in the
+      34             :     hybrid_36.py Python prototype/reference implementation.
+      35             :     See the Python script for more information.
+      36             : 
+      37             :     This file has no external dependencies, NOT even standard C headers.
+      38             :     Optionally, use hybrid_36_c.h, or simply copy the declarations
+      39             :     into your code.
+      40             : 
+      41             :     This file is unrestricted Open Source (cctbx.sf.net).
+      42             :     Please send corrections and enhancements to cctbx@cci.lbl.gov .
+      43             : 
+      44             :     See also: http://cci.lbl.gov/hybrid_36/
+      45             : 
+      46             :     Ralf W. Grosse-Kunstleve, Feb 2007.
+      47             :  */
+      48             : 
+      49             : /* The following #include may be commented out.
+      50             :    It is here only to enforce consistency of the declarations
+      51             :    and the definitions.
+      52             :  */
+      53             : // #include <iotbx/pdb/hybrid_36_c.h>
+      54             : 
+      55             : /* All static functions below are implementation details
+      56             :    (and not accessible from other translation units).
+      57             :  */
+      58             : 
+      59             : static
+      60             : const char*
+      61      111735 : digits_upper() { return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; }
+      62             : 
+      63             : static
+      64             : const char*
+      65        7957 : digits_lower() { return "0123456789abcdefghijklmnopqrstuvwxyz"; }
+      66             : 
+      67             : static
+      68             : const char*
+      69           0 : value_out_of_range() { return "value out of range."; }
+      70             : 
+      71             : static
+      72           2 : const char* invalid_number_literal() { return "invalid number literal."; }
+      73             : 
+      74             : static
+      75           0 : const char* unsupported_width() { return "unsupported width."; }
+      76             : 
+      77             : static
+      78             : void
+      79           0 : fill_with_stars(unsigned width, char* result)
+      80             : {
+      81           0 :   while (width) {
+      82           0 :     *result++ = '*';
+      83           0 :     width--;
+      84             :   }
+      85           0 :   *result = '\0';
+      86           0 : }
+      87             : 
+      88             : static
+      89             : void
+      90      103780 : encode_pure(
+      91             :   const char* digits,
+      92             :   unsigned digits_size,
+      93             :   unsigned width,
+      94             :   int value,
+      95             :   char* result)
+      96             : {
+      97             :   char buf[16];
+      98             :   int rest;
+      99             :   unsigned i, j;
+     100             :   i = 0;
+     101             :   j = 0;
+     102      103780 :   if (value < 0) {
+     103             :     j = 1;
+     104           0 :     value = -value;
+     105             :   }
+     106             :   while (1) {
+     107      493492 :     rest = value / digits_size;
+     108      493492 :     buf[i++] = digits[value - rest * digits_size];
+     109      493492 :     if (rest == 0) break;
+     110             :     value = rest;
+     111             :   }
+     112      103780 :   if (j) buf[i++] = '-';
+     113      127352 :   for(j=i; j<width; j++) *result++ = ' ';
+     114      597272 :   while (i != 0) *result++ = buf[--i];
+     115      103780 :   *result = '\0';
+     116      103780 : }
+     117             : 
+     118             : static
+     119             : const char*
+     120      543604 : decode_pure(
+     121             :   const int* digits_values,
+     122             :   unsigned digits_size,
+     123             :   const char* s,
+     124             :   unsigned s_size,
+     125             :   int* result)
+     126             : {
+     127             :   int si, dv;
+     128             :   int have_minus = 0;
+     129             :   int have_non_blank = 0;
+     130             :   int value = 0;
+     131             :   unsigned i = 0;
+     132     2989821 :   for(; i<s_size; i++) {
+     133     2446218 :     si = s[i];
+     134     2446218 :     if (si < 0 || si > 127) {
+     135           0 :       *result = 0;
+     136           0 :       return invalid_number_literal();
+     137             :     }
+     138     2446218 :     if (si == ' ') {
+     139      911029 :       if (!have_non_blank) continue;
+     140           0 :       value *= digits_size;
+     141             :     }
+     142     1535189 :     else if (si == '-') {
+     143           0 :       if (have_non_blank) {
+     144           0 :         *result = 0;
+     145           0 :         return invalid_number_literal();
+     146             :       }
+     147             :       have_non_blank = 1;
+     148             :       have_minus = 1;
+     149           0 :       continue;
+     150             :     }
+     151             :     else {
+     152             :       have_non_blank = 1;
+     153     1535189 :       dv = digits_values[si];
+     154     1535189 :       if (dv < 0 || dv >= digits_size) {
+     155           1 :         *result = 0;
+     156           1 :         return invalid_number_literal();
+     157             :       }
+     158     1535188 :       value *= digits_size;
+     159     1535188 :       value += dv;
+     160             :     }
+     161             :   }
+     162      543603 :   if (have_minus) value = -value;
+     163      543603 :   *result = value;
+     164      543603 :   return 0;
+     165             : }
+     166             : 
+     167             : /*! hybrid-36 encoder: converts integer value to string result
+     168             : 
+     169             :       width: must be 4 (e.g. for residue sequence numbers)
+     170             :                   or 5 (e.g. for atom serial numbers)
+     171             : 
+     172             :       value: integer value to be converted
+     173             : 
+     174             :       result: pointer to char array of size width+1 or greater
+     175             :               on return result is null-terminated
+     176             : 
+     177             :       return value: pointer to error message, if any,
+     178             :                     or 0 on success
+     179             : 
+     180             :     Example usage (from C++):
+     181             :       char result[4+1];
+     182             :       const char* errmsg = hy36encode(4, 12345, result);
+     183             :       if (errmsg) throw std::runtime_error(errmsg);
+     184             :  */
+     185             : const char*
+     186      103780 : hy36encode(unsigned width, int value, char* result)
+     187             : {
+     188             :   int i = value;
+     189      103780 :   if (width == 4U) {
+     190        1836 :     if (i >= -999) {
+     191        1836 :       if (i < 10000) {
+     192        1835 :         encode_pure(digits_upper(), 10U, 4U, i, result);
+     193        1835 :         return 0;
+     194             :       }
+     195           1 :       i -= 10000;
+     196           1 :       if (i < 1213056 /* 26*36**3 */) {
+     197           1 :         i += 466560 /* 10*36**3 */;
+     198           1 :         encode_pure(digits_upper(), 36U, 0U, i, result);
+     199           1 :         return 0;
+     200             :       }
+     201           0 :       i -= 1213056;
+     202           0 :       if (i < 1213056) {
+     203           0 :         i += 466560;
+     204           0 :         encode_pure(digits_lower(), 36U, 0U, i, result);
+     205           0 :         return 0;
+     206             :       }
+     207             :     }
+     208             :   }
+     209      101944 :   else if (width == 5U) {
+     210      101944 :     if (i >= -9999) {
+     211      101944 :       if (i < 100000) {
+     212      101835 :         encode_pure(digits_upper(), 10U, 5U, i, result);
+     213      101835 :         return 0;
+     214             :       }
+     215         109 :       i -= 100000;
+     216         109 :       if (i < 43670016 /* 26*36**4 */) {
+     217         108 :         i += 16796160 /* 10*36**4 */;
+     218         108 :         encode_pure(digits_upper(), 36U, 0U, i, result);
+     219         108 :         return 0;
+     220             :       }
+     221           1 :       i -= 43670016;
+     222           1 :       if (i < 43670016) {
+     223           1 :         i += 16796160;
+     224           1 :         encode_pure(digits_lower(), 36U, 0U, i, result);
+     225           1 :         return 0;
+     226             :       }
+     227             :     }
+     228             :   }
+     229             :   else {
+     230           0 :     fill_with_stars(width, result);
+     231           0 :     return unsupported_width();
+     232             :   }
+     233           0 :   fill_with_stars(width, result);
+     234           0 :   return value_out_of_range();
+     235             : }
+     236             : 
+     237             : /*! hybrid-36 decoder: converts string s to integer result
+     238             : 
+     239             :       width: must be 4 (e.g. for residue sequence numbers)
+     240             :                   or 5 (e.g. for atom serial numbers)
+     241             : 
+     242             :       s: string to be converted
+     243             :          does not have to be null-terminated
+     244             : 
+     245             :       s_size: size of s
+     246             :               must be equal to width, or an error message is
+     247             :               returned otherwise
+     248             : 
+     249             :       result: integer holding the conversion result
+     250             : 
+     251             :       return value: pointer to error message, if any,
+     252             :                     or 0 on success
+     253             : 
+     254             :     Example usage (from C++):
+     255             :       int result;
+     256             :       const char* errmsg = hy36decode(width, "A1T5", 4, &result);
+     257             :       if (errmsg) throw std::runtime_error(errmsg);
+     258             :  */
+     259             : const char*
+     260      543604 : hy36decode(unsigned width, const char* s, unsigned s_size, int* result)
+     261             : {
+     262         221 :   static const std::vector<int> digits_values_upper_vector([]() {
+     263         221 :     std::vector<int> ret(128U,-1);
+     264        8177 :     for(unsigned i=0; i<36U; i++) {
+     265        7956 :       int di = digits_upper()[i];
+     266        7956 :       if (di < 0 || di > 127) {
+     267           0 :         plumed_error()<<"internal error hy36decode: integer value out of range";
+     268             :       }
+     269        7956 :       ret[di] = i;
+     270             :     }
+     271         221 :     return ret;
+     272      543604 :   }());
+     273      543604 :   static const int* digits_values_upper=digits_values_upper_vector.data();
+     274         221 :   static const std::vector<int> digits_values_lower_vector([]() {
+     275         221 :     std::vector<int> ret(128U,-1);
+     276        8177 :     for(unsigned i=0; i<36U; i++) {
+     277        7956 :       int di = digits_lower()[i];
+     278        7956 :       if (di < 0 || di > 127) {
+     279           0 :         plumed_error()<<"internal error hy36decode: integer value out of range";
+     280             :       }
+     281        7956 :       ret[di] = i;
+     282             :     }
+     283         221 :     return ret;
+     284      543604 :   }());
+     285      543604 :   static const int* digits_values_lower=digits_values_lower_vector.data();
+     286             :   int di;
+     287             :   const char* errmsg;
+     288      543604 :   if (s_size == width) {
+     289      543604 :     di = s[0];
+     290      543604 :     if (di >= 0 && di <= 127) {
+     291      543604 :       if (digits_values_upper[di] >= 10) {
+     292           6 :         errmsg = decode_pure(digits_values_upper, 36U, s, s_size, result);
+     293           6 :         if (errmsg == 0) {
+     294             :           /* result - 10*36**(width-1) + 10**width */
+     295           5 :           if      (width == 4U) (*result) -= 456560;
+     296           2 :           else if (width == 5U) (*result) -= 16696160;
+     297             :           else {
+     298           0 :             *result = 0;
+     299           0 :             return unsupported_width();
+     300             :           }
+     301           5 :           return 0;
+     302             :         }
+     303             :       }
+     304      543598 :       else if (digits_values_lower[di] >= 10) {
+     305           0 :         errmsg = decode_pure(digits_values_lower, 36U, s, s_size, result);
+     306           0 :         if (errmsg == 0) {
+     307             :           /* result + 16*36**(width-1) + 10**width */
+     308           0 :           if      (width == 4U) (*result) += 756496;
+     309           0 :           else if (width == 5U) (*result) += 26973856;
+     310             :           else {
+     311           0 :             *result = 0;
+     312           0 :             return unsupported_width();
+     313             :           }
+     314           0 :           return 0;
+     315             :         }
+     316             :       }
+     317             :       else {
+     318      543598 :         errmsg = decode_pure(digits_values_upper, 10U, s, s_size, result);
+     319      543598 :         if (errmsg) return errmsg;
+     320      543598 :         if (!(width == 4U || width == 5U)) {
+     321           0 :           *result = 0;
+     322           0 :           return unsupported_width();
+     323             :         }
+     324             :         return 0;
+     325             :       }
+     326             :     }
+     327             :   }
+     328           1 :   *result = 0;
+     329           1 :   return invalid_number_literal();
+     330             : }
+     331             : 
+     332             : }
+     333             : 
+     334             : }
+     335             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/index-sort-f.html b/coverage/tools/index-sort-f.html new file mode 100644 index 000000000000..4c63602090d7 --- /dev/null +++ b/coverage/tools/index-sort-f.html @@ -0,0 +1,804 @@ + + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5674679983.5 %
Date:2024-02-22 21:58:45Functions:1060136477.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Exception.h +
91.7%91.7%
+
91.7 %33 / 3618.2 %25 / 137
Torsion.cpp +
80.0%80.0%
+
80.0 %28 / 3550.0 %1 / 2
RMSD.cpp +
73.5%73.5%
+
73.5 %540 / 73552.5 %42 / 80
DLLoader.cpp +
54.8%54.8%
+
54.8 %17 / 3157.1 %4 / 7
PlumedHandle.cpp +
63.9%63.9%
+
63.9 %23 / 3662.5 %5 / 8
BiasRepresentation.cpp +
75.9%75.9%
+
75.9 %129 / 17063.2 %12 / 19
OpenMP.h +
100.0%
+
100.0 %8 / 866.7 %2 / 3
RootFindingBase.h +
100.0%
+
100.0 %16 / 1666.7 %4 / 6
Brent1DRootSearch.h +
97.4%97.4%
+
97.4 %38 / 3966.7 %6 / 9
TypesafePtr.h +
87.6%87.6%
+
87.6 %106 / 12170.9 %39 / 55
Grid.cpp +
71.1%71.1%
+
71.1 %440 / 61971.4 %55 / 77
h36.cpp +
70.1%70.1%
+
70.1 %89 / 12775.0 %9 / 12
RMSD.h +
85.7%85.7%
+
85.7 %30 / 3577.8 %7 / 9
Keywords.cpp +
60.8%60.8%
+
60.8 %240 / 39578.0 %32 / 41
Vector.h +
100.0%
+
100.0 %66 / 6678.5 %51 / 65
ERMSD.cpp +
98.4%98.4%
+
98.4 %120 / 12280.0 %4 / 5
LatticeReduction.cpp +
82.9%82.9%
+
82.9 %102 / 12380.0 %8 / 10
PDB.cpp +
66.7%66.7%
+
66.7 %274 / 41181.8 %36 / 44
Communicator.cpp +
83.6%83.6%
+
83.6 %102 / 12283.3 %30 / 36
Tensor.h +
96.6%96.6%
+
96.6 %144 / 14983.8 %57 / 68
Subprocess.cpp +
74.1%74.1%
+
74.1 %60 / 8187.5 %14 / 16
NeighborList.cpp +
91.5%91.5%
+
91.5 %118 / 12987.5 %14 / 16
IFile.cpp +
96.0%96.0%
+
96.0 %145 / 15188.0 %22 / 25
Tools.h +
84.2%84.2%
+
84.2 %85 / 10188.5 %46 / 52
Grid.h +
100.0%
+
100.0 %32 / 3288.9 %8 / 9
MinimiseBase.h +
100.0%
+
100.0 %26 / 2688.9 %16 / 18
OFile.h +
100.0%
+
100.0 %6 / 689.7 %96 / 107
KernelFunctions.cpp +
84.2%84.2%
+
84.2 %187 / 22290.0 %9 / 10
Random.cpp +
91.6%91.6%
+
91.6 %76 / 8390.9 %10 / 11
Pbc.cpp +
95.3%95.3%
+
95.3 %123 / 12992.3 %12 / 13
Tools.cpp +
90.8%90.8%
+
90.8 %265 / 29293.0 %53 / 57
FileBase.cpp +
100.0%
+
100.0 %80 / 8093.3 %14 / 15
Communicator.h +
91.5%91.5%
+
91.5 %43 / 4793.5 %58 / 62
OFile.cpp +
96.9%96.9%
+
96.9 %220 / 22796.7 %29 / 30
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
FileBase.h +
100.0%
+
100.0 %6 / 6-0 / 0
Tree.h +
100.0%
+
100.0 %1 / 1-0 / 0
LinkCells.h +
100.0%
+
100.0 %2 / 2-0 / 0
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
Pbc.h +
83.3%83.3%
+
83.3 %5 / 6-0 / 0
ERMSD.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
NeighborList.h +
100.0%
+
100.0 %4 / 4-0 / 0
Random.h +
100.0%
+
100.0 %1 / 1-0 / 0
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
KernelFunctions.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
Angle.cpp +
100.0%
+
100.0 %26 / 26100.0 %2 / 2
HistogramBead.h +
94.4%94.4%
+
94.4 %17 / 18100.0 %2 / 2
Subprocess.h +
100.0%
+
100.0 %4 / 4100.0 %2 / 2
Keywords.h +
88.2%88.2%
+
88.2 %15 / 17100.0 %2 / 2
AtomNumber.h +
100.0%
+
100.0 %18 / 18100.0 %2 / 2
Stopwatch.cpp +
100.0%
+
100.0 %21 / 21100.0 %3 / 3
Tree.cpp +
89.2%89.2%
+
89.2 %33 / 37100.0 %3 / 3
TypesafePtr.cpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
ConjugateGradient.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %3 / 3
MultiValue.h +
100.0%
+
100.0 %36 / 36100.0 %4 / 4
Citations.cpp +
100.0%
+
100.0 %16 / 16100.0 %4 / 4
OpenMP.cpp +
100.0%
+
100.0 %17 / 17100.0 %4 / 4
MolDataClass.cpp +
85.1%85.1%
+
85.1 %406 / 477100.0 %5 / 5
Exception.cpp +
94.1%94.1%
+
94.1 %48 / 51100.0 %6 / 6
MultiValue.cpp +
100.0%
+
100.0 %62 / 62100.0 %9 / 9
LinkCells.cpp +
98.8%98.8%
+
98.8 %83 / 84100.0 %10 / 10
Stopwatch.h +
92.9%92.9%
+
92.9 %52 / 56100.0 %10 / 10
SwitchingFunction.cpp +
96.5%96.5%
+
96.5 %250 / 259100.0 %11 / 11
Units.cpp +
90.7%90.7%
+
90.7 %88 / 97100.0 %11 / 11
HistogramBead.cpp +
78.8%78.8%
+
78.8 %93 / 118100.0 %11 / 11
Matrix.h +
100.0%
+
100.0 %140 / 140100.0 %11 / 11
ForwardDecl.h +
100.0%
+
100.0 %4 / 4100.0 %12 / 12
Minimise1DBrent.h +
97.6%97.6%
+
97.6 %81 / 83100.0 %12 / 12
DynamicList.h +
100.0%
+
100.0 %47 / 47100.0 %13 / 13
MatrixSquareBracketsAccess.h +
100.0%
+
100.0 %12 / 12100.0 %21 / 21
LoopUnroller.h +
100.0%
+
100.0 %31 / 31100.0 %52 / 52
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/index-sort-l.html b/coverage/tools/index-sort-l.html new file mode 100644 index 000000000000..ef0b8c2edf45 --- /dev/null +++ b/coverage/tools/index-sort-l.html @@ -0,0 +1,804 @@ + + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5674679983.5 %
Date:2024-02-22 21:58:45Functions:1060136477.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ERMSD.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
DLLoader.cpp +
54.8%54.8%
+
54.8 %17 / 3157.1 %4 / 7
Keywords.cpp +
60.8%60.8%
+
60.8 %240 / 39578.0 %32 / 41
PlumedHandle.cpp +
63.9%63.9%
+
63.9 %23 / 3662.5 %5 / 8
PDB.cpp +
66.7%66.7%
+
66.7 %274 / 41181.8 %36 / 44
h36.cpp +
70.1%70.1%
+
70.1 %89 / 12775.0 %9 / 12
Grid.cpp +
71.1%71.1%
+
71.1 %440 / 61971.4 %55 / 77
RMSD.cpp +
73.5%73.5%
+
73.5 %540 / 73552.5 %42 / 80
Subprocess.cpp +
74.1%74.1%
+
74.1 %60 / 8187.5 %14 / 16
BiasRepresentation.cpp +
75.9%75.9%
+
75.9 %129 / 17063.2 %12 / 19
HistogramBead.cpp +
78.8%78.8%
+
78.8 %93 / 118100.0 %11 / 11
Torsion.cpp +
80.0%80.0%
+
80.0 %28 / 3550.0 %1 / 2
LatticeReduction.cpp +
82.9%82.9%
+
82.9 %102 / 12380.0 %8 / 10
Pbc.h +
83.3%83.3%
+
83.3 %5 / 6-0 / 0
Communicator.cpp +
83.6%83.6%
+
83.6 %102 / 12283.3 %30 / 36
Tools.h +
84.2%84.2%
+
84.2 %85 / 10188.5 %46 / 52
KernelFunctions.cpp +
84.2%84.2%
+
84.2 %187 / 22290.0 %9 / 10
MolDataClass.cpp +
85.1%85.1%
+
85.1 %406 / 477100.0 %5 / 5
RMSD.h +
85.7%85.7%
+
85.7 %30 / 3577.8 %7 / 9
TypesafePtr.h +
87.6%87.6%
+
87.6 %106 / 12170.9 %39 / 55
Keywords.h +
88.2%88.2%
+
88.2 %15 / 17100.0 %2 / 2
Tree.cpp +
89.2%89.2%
+
89.2 %33 / 37100.0 %3 / 3
Units.cpp +
90.7%90.7%
+
90.7 %88 / 97100.0 %11 / 11
Tools.cpp +
90.8%90.8%
+
90.8 %265 / 29293.0 %53 / 57
Communicator.h +
91.5%91.5%
+
91.5 %43 / 4793.5 %58 / 62
NeighborList.cpp +
91.5%91.5%
+
91.5 %118 / 12987.5 %14 / 16
Random.cpp +
91.6%91.6%
+
91.6 %76 / 8390.9 %10 / 11
Exception.h +
91.7%91.7%
+
91.7 %33 / 3618.2 %25 / 137
ConjugateGradient.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %3 / 3
Stopwatch.h +
92.9%92.9%
+
92.9 %52 / 56100.0 %10 / 10
Exception.cpp +
94.1%94.1%
+
94.1 %48 / 51100.0 %6 / 6
HistogramBead.h +
94.4%94.4%
+
94.4 %17 / 18100.0 %2 / 2
Pbc.cpp +
95.3%95.3%
+
95.3 %123 / 12992.3 %12 / 13
IFile.cpp +
96.0%96.0%
+
96.0 %145 / 15188.0 %22 / 25
SwitchingFunction.cpp +
96.5%96.5%
+
96.5 %250 / 259100.0 %11 / 11
Tensor.h +
96.6%96.6%
+
96.6 %144 / 14983.8 %57 / 68
OFile.cpp +
96.9%96.9%
+
96.9 %220 / 22796.7 %29 / 30
Brent1DRootSearch.h +
97.4%97.4%
+
97.4 %38 / 3966.7 %6 / 9
Minimise1DBrent.h +
97.6%97.6%
+
97.6 %81 / 83100.0 %12 / 12
ERMSD.cpp +
98.4%98.4%
+
98.4 %120 / 12280.0 %4 / 5
LinkCells.cpp +
98.8%98.8%
+
98.8 %83 / 84100.0 %10 / 10
Tree.h +
100.0%
+
100.0 %1 / 1-0 / 0
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
Random.h +
100.0%
+
100.0 %1 / 1-0 / 0
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
LinkCells.h +
100.0%
+
100.0 %2 / 2-0 / 0
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
ForwardDecl.h +
100.0%
+
100.0 %4 / 4100.0 %12 / 12
NeighborList.h +
100.0%
+
100.0 %4 / 4-0 / 0
Subprocess.h +
100.0%
+
100.0 %4 / 4100.0 %2 / 2
FileBase.h +
100.0%
+
100.0 %6 / 6-0 / 0
OFile.h +
100.0%
+
100.0 %6 / 689.7 %96 / 107
OpenMP.h +
100.0%
+
100.0 %8 / 866.7 %2 / 3
KernelFunctions.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
MatrixSquareBracketsAccess.h +
100.0%
+
100.0 %12 / 12100.0 %21 / 21
TypesafePtr.cpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
RootFindingBase.h +
100.0%
+
100.0 %16 / 1666.7 %4 / 6
Citations.cpp +
100.0%
+
100.0 %16 / 16100.0 %4 / 4
OpenMP.cpp +
100.0%
+
100.0 %17 / 17100.0 %4 / 4
AtomNumber.h +
100.0%
+
100.0 %18 / 18100.0 %2 / 2
Stopwatch.cpp +
100.0%
+
100.0 %21 / 21100.0 %3 / 3
Angle.cpp +
100.0%
+
100.0 %26 / 26100.0 %2 / 2
MinimiseBase.h +
100.0%
+
100.0 %26 / 2688.9 %16 / 18
LoopUnroller.h +
100.0%
+
100.0 %31 / 31100.0 %52 / 52
Grid.h +
100.0%
+
100.0 %32 / 3288.9 %8 / 9
MultiValue.h +
100.0%
+
100.0 %36 / 36100.0 %4 / 4
DynamicList.h +
100.0%
+
100.0 %47 / 47100.0 %13 / 13
MultiValue.cpp +
100.0%
+
100.0 %62 / 62100.0 %9 / 9
Vector.h +
100.0%
+
100.0 %66 / 6678.5 %51 / 65
FileBase.cpp +
100.0%
+
100.0 %80 / 8093.3 %14 / 15
Matrix.h +
100.0%
+
100.0 %140 / 140100.0 %11 / 11
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/tools/index.html b/coverage/tools/index.html new file mode 100644 index 000000000000..1c0b8072338e --- /dev/null +++ b/coverage/tools/index.html @@ -0,0 +1,804 @@ + + + + + + + + LCOV - plumed test coverage - tools + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - toolsHitTotalCoverage
Test:plumed test coverageLines:5674679983.5 %
Date:2024-02-22 21:58:45Functions:1060136477.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Angle.cpp +
100.0%
+
100.0 %26 / 26100.0 %2 / 2
AtomNumber.h +
100.0%
+
100.0 %18 / 18100.0 %2 / 2
BiasRepresentation.cpp +
75.9%75.9%
+
75.9 %129 / 17063.2 %12 / 19
Brent1DRootSearch.h +
97.4%97.4%
+
97.4 %38 / 3966.7 %6 / 9
Citations.cpp +
100.0%
+
100.0 %16 / 16100.0 %4 / 4
Citations.h +
100.0%
+
100.0 %1 / 1-0 / 0
Communicator.cpp +
83.6%83.6%
+
83.6 %102 / 12283.3 %30 / 36
Communicator.h +
91.5%91.5%
+
91.5 %43 / 4793.5 %58 / 62
ConjugateGradient.h +
92.9%92.9%
+
92.9 %13 / 14100.0 %3 / 3
DLLoader.cpp +
54.8%54.8%
+
54.8 %17 / 3157.1 %4 / 7
DynamicList.h +
100.0%
+
100.0 %47 / 47100.0 %13 / 13
ERMSD.cpp +
98.4%98.4%
+
98.4 %120 / 12280.0 %4 / 5
ERMSD.h +
50.0%50.0%
+
50.0 %1 / 2-0 / 0
Exception.cpp +
94.1%94.1%
+
94.1 %48 / 51100.0 %6 / 6
Exception.h +
91.7%91.7%
+
91.7 %33 / 3618.2 %25 / 137
FileBase.cpp +
100.0%
+
100.0 %80 / 8093.3 %14 / 15
FileBase.h +
100.0%
+
100.0 %6 / 6-0 / 0
ForwardDecl.h +
100.0%
+
100.0 %4 / 4100.0 %12 / 12
Grid.cpp +
71.1%71.1%
+
71.1 %440 / 61971.4 %55 / 77
Grid.h +
100.0%
+
100.0 %32 / 3288.9 %8 / 9
HistogramBead.cpp +
78.8%78.8%
+
78.8 %93 / 118100.0 %11 / 11
HistogramBead.h +
94.4%94.4%
+
94.4 %17 / 18100.0 %2 / 2
IFile.cpp +
96.0%96.0%
+
96.0 %145 / 15188.0 %22 / 25
IFile.h +
100.0%
+
100.0 %2 / 2-0 / 0
KernelFunctions.cpp +
84.2%84.2%
+
84.2 %187 / 22290.0 %9 / 10
KernelFunctions.h +
100.0%
+
100.0 %9 / 9100.0 %1 / 1
Keywords.cpp +
60.8%60.8%
+
60.8 %240 / 39578.0 %32 / 41
Keywords.h +
88.2%88.2%
+
88.2 %15 / 17100.0 %2 / 2
LatticeReduction.cpp +
82.9%82.9%
+
82.9 %102 / 12380.0 %8 / 10
LinkCells.cpp +
98.8%98.8%
+
98.8 %83 / 84100.0 %10 / 10
LinkCells.h +
100.0%
+
100.0 %2 / 2-0 / 0
LoopUnroller.h +
100.0%
+
100.0 %31 / 31100.0 %52 / 52
Matrix.h +
100.0%
+
100.0 %140 / 140100.0 %11 / 11
MatrixSquareBracketsAccess.h +
100.0%
+
100.0 %12 / 12100.0 %21 / 21
Minimise1DBrent.h +
97.6%97.6%
+
97.6 %81 / 83100.0 %12 / 12
MinimiseBase.h +
100.0%
+
100.0 %26 / 2688.9 %16 / 18
MolDataClass.cpp +
85.1%85.1%
+
85.1 %406 / 477100.0 %5 / 5
MultiValue.cpp +
100.0%
+
100.0 %62 / 62100.0 %9 / 9
MultiValue.h +
100.0%
+
100.0 %36 / 36100.0 %4 / 4
NeighborList.cpp +
91.5%91.5%
+
91.5 %118 / 12987.5 %14 / 16
NeighborList.h +
100.0%
+
100.0 %4 / 4-0 / 0
OFile.cpp +
96.9%96.9%
+
96.9 %220 / 22796.7 %29 / 30
OFile.h +
100.0%
+
100.0 %6 / 689.7 %96 / 107
OpenMP.cpp +
100.0%
+
100.0 %17 / 17100.0 %4 / 4
OpenMP.h +
100.0%
+
100.0 %8 / 866.7 %2 / 3
PDB.cpp +
66.7%66.7%
+
66.7 %274 / 41181.8 %36 / 44
Pbc.cpp +
95.3%95.3%
+
95.3 %123 / 12992.3 %12 / 13
Pbc.h +
83.3%83.3%
+
83.3 %5 / 6-0 / 0
PlumedHandle.cpp +
63.9%63.9%
+
63.9 %23 / 3662.5 %5 / 8
RMSD.cpp +
73.5%73.5%
+
73.5 %540 / 73552.5 %42 / 80
RMSD.h +
85.7%85.7%
+
85.7 %30 / 3577.8 %7 / 9
Random.cpp +
91.6%91.6%
+
91.6 %76 / 8390.9 %10 / 11
Random.h +
100.0%
+
100.0 %1 / 1-0 / 0
RootFindingBase.h +
100.0%
+
100.0 %16 / 1666.7 %4 / 6
Stopwatch.cpp +
100.0%
+
100.0 %21 / 21100.0 %3 / 3
Stopwatch.h +
92.9%92.9%
+
92.9 %52 / 56100.0 %10 / 10
Subprocess.cpp +
74.1%74.1%
+
74.1 %60 / 8187.5 %14 / 16
Subprocess.h +
100.0%
+
100.0 %4 / 4100.0 %2 / 2
SwitchingFunction.cpp +
96.5%96.5%
+
96.5 %250 / 259100.0 %11 / 11
Tensor.cpp +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
Tensor.h +
96.6%96.6%
+
96.6 %144 / 14983.8 %57 / 68
Tools.cpp +
90.8%90.8%
+
90.8 %265 / 29293.0 %53 / 57
Tools.h +
84.2%84.2%
+
84.2 %85 / 10188.5 %46 / 52
Torsion.cpp +
80.0%80.0%
+
80.0 %28 / 3550.0 %1 / 2
Tree.cpp +
89.2%89.2%
+
89.2 %33 / 37100.0 %3 / 3
Tree.h +
100.0%
+
100.0 %1 / 1-0 / 0
TypesafePtr.cpp +
100.0%
+
100.0 %14 / 14100.0 %3 / 3
TypesafePtr.h +
87.6%87.6%
+
87.6 %106 / 12170.9 %39 / 55
Units.cpp +
90.7%90.7%
+
90.7 %88 / 97100.0 %11 / 11
Units.h +
100.0%
+
100.0 %1 / 1-0 / 0
Vector.h +
100.0%
+
100.0 %66 / 6678.5 %51 / 65
h36.cpp +
70.1%70.1%
+
70.1 %89 / 12775.0 %9 / 12
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/updown.png b/coverage/updown.png new file mode 100644 index 0000000000000000000000000000000000000000..aa56a238b3e6c435265250f9266cd1b8caba0f20 GIT binary patch literal 117 zcmeAS@N?(olHy`uVBq!ia0vp^AT}Qd8;}%R+`Ae`*?77*hG?8mPH5^{)z4*}Q$iB}huR`+ literal 0 HcmV?d00001 diff --git a/coverage/vatom/Center.cpp.func-sort-c.html b/coverage/vatom/Center.cpp.func-sort-c.html new file mode 100644 index 000000000000..cd84370a7a05 --- /dev/null +++ b/coverage/vatom/Center.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Center.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Center.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12112299.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom6CenterC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom6CenterC1ERKNS_13ActionOptionsE7163
_ZN4PLMD5vatom6Center16registerKeywordsERNS_8KeywordsE7167
_ZN4PLMD5vatom6Center9calculateEv13808
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Center.cpp.func.html b/coverage/vatom/Center.cpp.func.html new file mode 100644 index 000000000000..77ca630db414 --- /dev/null +++ b/coverage/vatom/Center.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Center.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Center.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12112299.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom6Center16registerKeywordsERNS_8KeywordsE7167
_ZN4PLMD5vatom6Center9calculateEv13808
_ZN4PLMD5vatom6CenterC1ERKNS_13ActionOptionsE7163
_ZN4PLMD5vatom6CenterC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Center.cpp.gcov.html b/coverage/vatom/Center.cpp.gcov.html new file mode 100644 index 000000000000..efa61c129c39 --- /dev/null +++ b/coverage/vatom/Center.cpp.gcov.html @@ -0,0 +1,396 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Center.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Center.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12112299.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithVirtualAtom.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include <cmath>
+      26             : #include <limits>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace vatom {
+      30             : 
+      31             : //+PLUMEDOC VATOM CENTER
+      32             : /*
+      33             : Calculate the center for a group of atoms, with arbitrary weights.
+      34             : 
+      35             : The computed
+      36             : center is stored as a virtual atom that can be accessed in
+      37             : an atom list through the label for the CENTER action that creates it.
+      38             : Notice that the generated virtual atom has charge equal to the sum of the
+      39             : charges and mass equal to the sum of the masses. If used with the MASS flag,
+      40             : then it provides a result identical to \ref COM.
+      41             : 
+      42             : When running with periodic boundary conditions, the atoms should be
+      43             : in the proper periodic image. This is done automatically since PLUMED 2.2,
+      44             : by considering the ordered list of atoms and rebuilding the molecule using a procedure
+      45             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+      46             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+      47             : which actually modifies the coordinates stored in PLUMED.
+      48             : 
+      49             : In case you want to recover the old behavior you should use the NOPBC flag.
+      50             : In that case you need to take care that atoms are in the correct
+      51             : periodic image.
+      52             : 
+      53             : \note As an experimental feature, CENTER also supports a keyword PHASES.
+      54             : This keyword finds the center of mass for sets of atoms that have been split by the period boundaries by computing scaled coordinates and average
+      55             : trigonometric functions, similarly to \ref CENTER_OF_MULTICOLVAR.
+      56             : Notice that by construction this center position is
+      57             : not invariant with respect to rotations of the atoms at fixed cell lattice.
+      58             : In addition, for symmetric Bravais lattices, it is not invariant with respect
+      59             : to special symmetries. E.g., if you have an hexagonal cell, the center will
+      60             : not be invariant with respect to rotations of 120 degrees.
+      61             : On the other hand, it might make the treatment of PBC easier in difficult cases.
+      62             : 
+      63             : \par Examples
+      64             : 
+      65             : \plumedfile
+      66             : # a point which is on the line connecting atoms 1 and 10, so that its distance
+      67             : # from 10 is twice its distance from 1:
+      68             : c1: CENTER ATOMS=1,1,10
+      69             : # this is another way of stating the same:
+      70             : c1bis: CENTER ATOMS=1,10 WEIGHTS=2,1
+      71             : 
+      72             : # center of mass among these atoms:
+      73             : c2: CENTER ATOMS=2,3,4,5 MASS
+      74             : 
+      75             : d1: DISTANCE ATOMS=c1,c2
+      76             : 
+      77             : PRINT ARG=d1
+      78             : \endplumedfile
+      79             : 
+      80             : */
+      81             : //+ENDPLUMEDOC
+      82             : 
+      83             : //+PLUMEDOC VATOM COM
+      84             : /*
+      85             : Calculate the center of mass for a group of atoms.
+      86             : 
+      87             : The computed
+      88             : center of mass is stored as a virtual atom that can be accessed in
+      89             : an atom list through the label for the COM action that creates it.
+      90             : 
+      91             : For arbitrary weights (e.g. geometric center) see \ref CENTER.
+      92             : 
+      93             : When running with periodic boundary conditions, the atoms should be
+      94             : in the proper periodic image. This is done automatically since PLUMED 2.2,
+      95             : by considering the ordered list of atoms and rebuilding the molecule using a procedure
+      96             : that is equivalent to that done in \ref WHOLEMOLECULES . Notice that
+      97             : rebuilding is local to this action. This is different from \ref WHOLEMOLECULES
+      98             : which actually modifies the coordinates stored in PLUMED.
+      99             : 
+     100             : In case you want to recover the old behavior you should use the NOPBC flag.
+     101             : In that case you need to take care that atoms are in the correct
+     102             : periodic image.
+     103             : 
+     104             : \par Examples
+     105             : 
+     106             : The following input instructs plumed to print the distance between the
+     107             : center of mass for atoms 1,2,3,4,5,6,7 and that for atoms 15,20:
+     108             : \plumedfile
+     109             : c1: COM ATOMS=1-7
+     110             : c2: COM ATOMS=15,20
+     111             : d1: DISTANCE ATOMS=c1,c2
+     112             : PRINT ARG=d1
+     113             : \endplumedfile
+     114             : 
+     115             : */
+     116             : //+ENDPLUMEDOC
+     117             : 
+     118             : 
+     119             : class Center:
+     120             :   public ActionWithVirtualAtom
+     121             : {
+     122             :   std::vector<double> weights;
+     123             :   std::vector<Tensor> dcenter_sin;
+     124             :   std::vector<Tensor> dcenter_cos;
+     125             :   std::vector<Tensor> deriv;
+     126             :   bool isChargeSet_;
+     127             :   bool isMassSet_;
+     128             :   bool weight_mass;
+     129             :   bool nopbc;
+     130             :   bool first;
+     131             :   bool phases;
+     132             : public:
+     133             :   explicit Center(const ActionOptions&ao);
+     134             :   void calculate() override;
+     135             :   static void registerKeywords( Keywords& keys );
+     136             : };
+     137             : 
+     138             : PLUMED_REGISTER_ACTION(Center,"CENTER")
+     139             : PLUMED_REGISTER_ACTION(Center,"COM")
+     140             : 
+     141        7167 : void Center::registerKeywords(Keywords& keys) {
+     142        7167 :   ActionWithVirtualAtom::registerKeywords(keys);
+     143       14334 :   keys.add("optional","WEIGHTS","Center is computed as a weighted average.");
+     144       14334 :   keys.add("optional","SET_CHARGE","Set the charge of the virtual atom to a given value.");
+     145       14334 :   keys.add("optional","SET_MASS","Set the mass of the virtual atom to a given value.");
+     146       14334 :   keys.addFlag("NOPBC",false,"ignore the periodic boundary conditions when calculating distances");
+     147       14334 :   keys.addFlag("MASS",false,"If set center is mass weighted");
+     148       14334 :   keys.addFlag("PHASES",false,"Compute center using trigonometric phases");
+     149        7167 : }
+     150             : 
+     151        7163 : Center::Center(const ActionOptions&ao):
+     152             :   Action(ao),
+     153             :   ActionWithVirtualAtom(ao),
+     154        7163 :   isChargeSet_(false),
+     155        7163 :   isMassSet_(false),
+     156        7163 :   weight_mass(false),
+     157        7163 :   nopbc(false),
+     158        7163 :   first(true),
+     159        7163 :   phases(false)
+     160             : {
+     161             :   std::vector<AtomNumber> atoms;
+     162       14326 :   parseAtomList("ATOMS",atoms);
+     163        7163 :   if(atoms.size()==0) error("at least one atom should be specified");
+     164        7163 :   parseVector("WEIGHTS",weights);
+     165        7163 :   parseFlag("MASS",weight_mass);
+     166        7163 :   parseFlag("NOPBC",nopbc);
+     167        7163 :   parseFlag("PHASES",phases);
+     168       14326 :   double charge_=std::numeric_limits<double>::lowest(); parse("SET_CHARGE",charge_); setCharge(charge_);
+     169        7163 :   if(charge_!=std::numeric_limits<double>::lowest()) isChargeSet_=true;
+     170       14326 :   double mass_=-1; parse("SET_MASS",mass_); setMass(mass_);
+     171        7163 :   if(mass_>0.) isMassSet_=true;
+     172        7163 :   if(mass_==0.) error("SETMASS must be greater than 0");
+     173        7163 :   if( getName()=="COM") weight_mass=true;
+     174        7163 :   checkRead();
+     175        7163 :   log.printf("  of atoms:");
+     176       37425 :   for(unsigned i=0; i<atoms.size(); ++i) {
+     177       30262 :     if(i%25==0) log<<"\n";
+     178       30262 :     log.printf(" %d",atoms[i].serial());
+     179             :   }
+     180        7163 :   log<<"\n";
+     181        7163 :   if(weight_mass) {
+     182          77 :     log<<"  mass weighted\n";
+     183          77 :     if(weights.size()!=0) error("WEIGHTS and MASS keywords cannot not be used simultaneously");
+     184             :   } else {
+     185        7086 :     if( weights.size()==0) {
+     186         109 :       log<<" using the geometric center\n";
+     187         109 :       weights.resize( atoms.size() );
+     188        1330 :       for(unsigned i=0; i<atoms.size(); i++) weights[i] = 1.;
+     189             :     } else {
+     190        6977 :       log<<" with weights:";
+     191        6979 :       if( weights.size()!=atoms.size() ) error("number of elements in weight vector does not match the number of atoms");
+     192       35074 :       for(unsigned i=0; i<weights.size(); ++i) {
+     193       28098 :         if(i%25==0) log<<"\n";
+     194       28098 :         log.printf(" %f",weights[i]);
+     195             :       }
+     196        6976 :       log.printf("\n");
+     197             :     }
+     198             :   }
+     199        7161 :   if(phases) {
+     200           3 :     log<<"  Phases will be used to take into account PBC\n";
+     201        7158 :   } else if(nopbc) {
+     202          45 :     log<<"  PBC will be ignored\n";
+     203             :   } else {
+     204        7113 :     log<<"  broken molecules will be rebuilt assuming atoms are in the proper order\n";
+     205             :   }
+     206        7161 :   requestAtoms(atoms);
+     207        7165 : }
+     208             : 
+     209       13808 : void Center::calculate() {
+     210       13808 :   Vector pos;
+     211       13808 :   const bool dophases=(getPbc().isSet() ? phases : false);
+     212             : 
+     213       13808 :   if(!nopbc && !dophases) makeWhole();
+     214             : 
+     215       13808 :   if( first ) {
+     216       11800 :     if( weight_mass ) {
+     217       40063 :       for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     218       35334 :         if(std::isnan(getMass(i))) {
+     219           0 :           error(
+     220             :             "You are trying to compute a CENTER or COM but masses are not known.\n"
+     221             :             "        If you are using plumed driver, please use the --mc option"
+     222             :           );
+     223             :         }
+     224             :       }
+     225             :     }
+     226             :     double mass(0.0);
+     227       76315 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) mass+=getMass(i);
+     228       11800 :     if( chargesWereSet && !isChargeSet_) {
+     229             :       double charge(0.0);
+     230       43683 :       for(unsigned i=0; i<getNumberOfAtoms(); i++) charge+=getCharge(i);
+     231        7742 :       setCharge(charge);
+     232        4058 :     } else if( !isChargeSet_ ) {
+     233        4056 :       setCharge(0.0);
+     234             :     }
+     235       11800 :     if(!isMassSet_) setMass(mass);
+     236             : 
+     237       11800 :     if( weight_mass ) {
+     238        4729 :       weights.resize( getNumberOfAtoms() );
+     239       40063 :       for(unsigned i=0; i<weights.size(); i++) weights[i] = getMass(i) / mass;
+     240             :     } else {
+     241             :       double wtot=0.0;
+     242       36252 :       for(unsigned i=0; i<weights.size(); i++) wtot+=weights[i];
+     243       36252 :       for(unsigned i=0; i<weights.size(); i++) weights[i]=weights[i]/wtot;
+     244        7071 :       first=false;
+     245             :     }
+     246             :   }
+     247             : 
+     248       13808 :   deriv.resize(getNumberOfAtoms());
+     249             : 
+     250       13808 :   if(dophases) {
+     251         240 :     dcenter_sin.resize(getNumberOfAtoms());
+     252         240 :     dcenter_cos.resize(getNumberOfAtoms());
+     253         240 :     Vector center_sin;
+     254         240 :     Vector center_cos;
+     255         240 :     Tensor invbox2pi=2*pi*getPbc().getInvBox();
+     256         240 :     Tensor box2pi=getPbc().getBox() / (2*pi);
+     257         960 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     258         720 :       double w=weights[i];
+     259             : 
+     260             :       // real to scaled
+     261         720 :       const Vector scaled=matmul(getPosition(i),invbox2pi);
+     262             :       const Vector ccos(
+     263         720 :         w*std::cos(scaled[0]),
+     264         720 :         w*std::cos(scaled[1]),
+     265         720 :         w*std::cos(scaled[2])
+     266         720 :       );
+     267             :       const Vector csin(
+     268         720 :         w*std::sin(scaled[0]),
+     269         720 :         w*std::sin(scaled[1]),
+     270         720 :         w*std::sin(scaled[2])
+     271         720 :       );
+     272         720 :       center_cos+=ccos;
+     273         720 :       center_sin+=csin;
+     274        9360 :       for(unsigned l=0; l<3; l++) for(unsigned k=0; k<3; k++) {
+     275             :           // k over real coordinates
+     276             :           // l over scaled coordinates
+     277        6480 :           dcenter_sin[i][l][k]=ccos[l]*invbox2pi[k][l];
+     278        6480 :           dcenter_cos[i][l][k]=-csin[l]*invbox2pi[k][l];
+     279             :         }
+     280             :     }
+     281             :     const Vector c(
+     282         240 :       std::atan2(center_sin[0],center_cos[0]),
+     283         240 :       std::atan2(center_sin[1],center_cos[1]),
+     284         240 :       std::atan2(center_sin[2],center_cos[2])
+     285         240 :     );
+     286             : 
+     287             :     // normalization is convenient for doing derivatives later
+     288         960 :     for(unsigned l=0; l<3; l++) {
+     289         720 :       double norm=1.0/(center_sin[l]*center_sin[l]+center_cos[l]*center_cos[l]);
+     290         720 :       center_sin[l]*=norm;
+     291         720 :       center_cos[l]*=norm;
+     292             :     }
+     293             : 
+     294         960 :     for(unsigned i=0; i<getNumberOfAtoms(); ++i) {
+     295         720 :       Tensor dd;
+     296        9360 :       for(unsigned l=0; l<3; l++) for(unsigned k=0; k<3; k++) {
+     297             :           // k over real coordinates
+     298             :           // l over scaled coordinates
+     299        6480 :           dd[l][k]= (center_cos[l]*dcenter_sin[i][l][k] - center_sin[l]*dcenter_cos[i][l][k]);
+     300             :         }
+     301             :       // scaled to real
+     302         720 :       deriv[i]=matmul(dd,box2pi);
+     303             :     }
+     304         240 :     setAtomsDerivatives(deriv);
+     305             :     // scaled to real
+     306         240 :     setPosition(matmul(c,box2pi));
+     307             :   } else {
+     308       92341 :     for(unsigned i=0; i<getNumberOfAtoms(); i++) {
+     309       78773 :       double w=weights[i];
+     310       78773 :       pos+=w*getPosition(i);
+     311       78773 :       deriv[i]=w*Tensor::identity();
+     312             :     }
+     313       13568 :     setPosition(pos);
+     314       13568 :     setAtomsDerivatives(deriv);
+     315             :   }
+     316       13808 : }
+     317             : 
+     318             : }
+     319             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/FixedAtom.cpp.func-sort-c.html b/coverage/vatom/FixedAtom.cpp.func-sort-c.html new file mode 100644 index 000000000000..21d9bc688bb1 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/FixedAtom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - FixedAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom9FixedAtomC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom9FixedAtomC1ERKNS_13ActionOptionsE9
_ZN4PLMD5vatom9FixedAtom16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD5vatom9FixedAtom9calculateEv603
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/FixedAtom.cpp.func.html b/coverage/vatom/FixedAtom.cpp.func.html new file mode 100644 index 000000000000..404487b88bf6 --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/FixedAtom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - FixedAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom9FixedAtom16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD5vatom9FixedAtom9calculateEv603
_ZN4PLMD5vatom9FixedAtomC1ERKNS_13ActionOptionsE9
_ZN4PLMD5vatom9FixedAtomC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/FixedAtom.cpp.gcov.html b/coverage/vatom/FixedAtom.cpp.gcov.html new file mode 100644 index 000000000000..5361c90f8a8b --- /dev/null +++ b/coverage/vatom/FixedAtom.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + LCOV - plumed test coverage - vatom/FixedAtom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - FixedAtom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithVirtualAtom.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Vector.h"
+      25             : #include "tools/Exception.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace vatom {
+      29             : 
+      30             : //+PLUMEDOC VATOM FIXEDATOM
+      31             : /*
+      32             : Add a virtual atom in a fixed position.
+      33             : 
+      34             : This action creates a virtual atom at a fixed position.
+      35             : The coordinates can be specified in Cartesian components (by default)
+      36             : or in scaled coordinates (SCALED_COMPONENTS).
+      37             : It is also possible to assign a predefined charge or mass to the atom.
+      38             : 
+      39             : \attention
+      40             : Similar to \ref POSITION this variable is not invariant for translation
+      41             : of the system. Adding a force on it can create serious troubles.
+      42             : 
+      43             : Notice that the distance between two atoms created
+      44             : using FIXEDATOM is invariant for translation.
+      45             : Additionally, if one first align atoms to a reference using \ref FIT_TO_TEMPLATE,
+      46             : then it is safe to add further fixed atoms without breaking translational invariance.
+      47             : 
+      48             : \par Examples
+      49             : 
+      50             : The following input instructs plumed to compute the angle between
+      51             : distance of atoms 15 and 20 and the z axis and keeping it close to zero.
+      52             : \plumedfile
+      53             : a: FIXEDATOM AT=0,0,0
+      54             : b: FIXEDATOM AT=0,0,1
+      55             : an: ANGLE ATOMS=a,b,15,20
+      56             : RESTRAINT ARG=an AT=0.0 KAPPA=100.0
+      57             : \endplumedfile
+      58             : 
+      59             : The following input instructs plumed to align a protein to a template
+      60             : and to then compute the distance between one of the atoms in the protein and the point
+      61             : (10,20,30).
+      62             : \plumedfile
+      63             : FIT_TO_TEMPLATE STRIDE=1 REFERENCE=ref.pdb TYPE=SIMPLE
+      64             : a: FIXEDATOM AT=10,20,30
+      65             : d: DISTANCE ATOMS=a,20
+      66             : PRINT ARG=d FILE=colvar
+      67             : \endplumedfile
+      68             : 
+      69             : The reference structure to align to is provided in a pdb file called ref.pdb as shown below:
+      70             : 
+      71             : \auxfile{ref.pdb}
+      72             : ATOM      8  HT3 ALA     2      -1.480  -1.560   1.212  1.00  1.00      DIA  H
+      73             : ATOM      9  CAY ALA     2      -0.096   2.144  -0.669  1.00  1.00      DIA  C
+      74             : ATOM     10  HY1 ALA     2       0.871   2.385  -0.588  1.00  1.00      DIA  H
+      75             : ATOM     12  HY3 ALA     2      -0.520   2.679  -1.400  1.00  1.00      DIA  H
+      76             : ATOM     14  OY  ALA     2      -1.139   0.931  -0.973  1.00  1.00      DIA  O
+      77             : END
+      78             : \endauxfile
+      79             : 
+      80             : 
+      81             : */
+      82             : //+ENDPLUMEDOC
+      83             : 
+      84             : 
+      85             : class FixedAtom:
+      86             :   public ActionWithVirtualAtom
+      87             : {
+      88             :   Vector coord;
+      89             :   std::vector<Tensor> deriv;
+      90             :   double mass,charge;
+      91             :   bool scaled_components;
+      92             : public:
+      93             :   explicit FixedAtom(const ActionOptions&ao);
+      94             :   void calculate() override;
+      95             :   static void registerKeywords( Keywords& keys );
+      96             : };
+      97             : 
+      98             : PLUMED_REGISTER_ACTION(FixedAtom,"FIXEDATOM")
+      99             : 
+     100          11 : void FixedAtom::registerKeywords(Keywords& keys) {
+     101          11 :   ActionWithVirtualAtom::registerKeywords(keys);
+     102          22 :   keys.add("compulsory","AT","coordinates of the virtual atom");
+     103          22 :   keys.add("compulsory","SET_MASS","1","mass of the virtual atom");
+     104          22 :   keys.add("compulsory","SET_CHARGE","0","charge of the virtual atom");
+     105          22 :   keys.addFlag("SCALED_COMPONENTS",false,"use scaled components");
+     106          11 : }
+     107             : 
+     108           9 : FixedAtom::FixedAtom(const ActionOptions&ao):
+     109             :   Action(ao),
+     110           9 :   ActionWithVirtualAtom(ao)
+     111             : {
+     112             :   std::vector<AtomNumber> atoms;
+     113          18 :   parseAtomList("ATOMS",atoms);
+     114           9 :   if(atoms.size()!=0) error("ATOMS should be empty");
+     115             : 
+     116          18 :   parseFlag("SCALED_COMPONENTS",scaled_components);
+     117             : 
+     118             :   std::vector<double> at;
+     119          18 :   parseVector("AT",at);
+     120           9 :   if(at.size()!=3) error("AT should be a list of three real numbers");
+     121             : 
+     122           9 :   parse("SET_MASS",mass);
+     123          18 :   parse("SET_CHARGE",charge);
+     124             : 
+     125           9 :   coord[0]=at[0];
+     126           9 :   coord[1]=at[1];
+     127           9 :   coord[2]=at[2];
+     128             : 
+     129           9 :   checkRead();
+     130           9 :   log<<"  AT position "<<coord[0]<<" "<<coord[1]<<" "<<coord[2]<<"\n";
+     131           9 :   if(scaled_components) log<<"  position is in scaled components\n";
+     132           9 : }
+     133             : 
+     134         603 : void FixedAtom::calculate() {
+     135         603 :   deriv.resize(getNumberOfAtoms());
+     136         603 :   if(scaled_components) {
+     137           5 :     setPosition(getPbc().scaledToReal(coord));
+     138             :   } else {
+     139         598 :     setPosition(coord);
+     140             :   }
+     141         603 :   setMass(mass);
+     142         603 :   setCharge(charge);
+     143         603 :   setAtomsDerivatives(deriv);
+     144             : // Virial contribution
+     145         603 :   if(!scaled_components) setBoxDerivativesNoPbc();
+     146             : // notice that with scaled components there is no additional virial contribution
+     147         603 : }
+     148             : 
+     149             : }
+     150             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Ghost.cpp.func-sort-c.html b/coverage/vatom/Ghost.cpp.func-sort-c.html new file mode 100644 index 000000000000..d25125bc0745 --- /dev/null +++ b/coverage/vatom/Ghost.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Ghost.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Ghost.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom5GhostC2ERKNS_13ActionOptionsE0
_ZN4PLMD5vatom5GhostC1ERKNS_13ActionOptionsE3
_ZN4PLMD5vatom5Ghost16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD5vatom5Ghost9calculateEv7
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Ghost.cpp.func.html b/coverage/vatom/Ghost.cpp.func.html new file mode 100644 index 000000000000..155071b39413 --- /dev/null +++ b/coverage/vatom/Ghost.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Ghost.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Ghost.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD5vatom5Ghost16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD5vatom5Ghost9calculateEv7
_ZN4PLMD5vatom5GhostC1ERKNS_13ActionOptionsE3
_ZN4PLMD5vatom5GhostC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/Ghost.cpp.gcov.html b/coverage/vatom/Ghost.cpp.gcov.html new file mode 100644 index 000000000000..0fb020f3a852 --- /dev/null +++ b/coverage/vatom/Ghost.cpp.gcov.html @@ -0,0 +1,263 @@ + + + + + + + + LCOV - plumed test coverage - vatom/Ghost.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatom - Ghost.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:7373100.0 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithVirtualAtom.h"
+      23             : #include "core/ActionRegister.h"
+      24             : #include "tools/Vector.h"
+      25             : #include "tools/Exception.h"
+      26             : #include <array>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace vatom {
+      30             : 
+      31             : //+PLUMEDOC VATOM GHOST
+      32             : /*
+      33             : Calculate the absolute position of a ghost atom with fixed coordinates in the local reference frame formed by three atoms.
+      34             : 
+      35             : The computed ghost atom is stored as a virtual atom that can be accessed in
+      36             :  an atom list through the the label for the GHOST action that creates it.
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : The following input instructs plumed to print the distance between the
+      41             : ghost atom and the center of mass for atoms 15,20:
+      42             : \plumedfile
+      43             : c1: GHOST ATOMS=1,5,10 COORDINATES=10.0,10.0,10.0
+      44             : c2: COM ATOMS=15,20
+      45             : d1: DISTANCE ATOMS=c1,c2
+      46             : PRINT ARG=d1
+      47             : \endplumedfile
+      48             : 
+      49             : */
+      50             : //+ENDPLUMEDOC
+      51             : 
+      52             : 
+      53             : class Ghost:
+      54             :   public ActionWithVirtualAtom
+      55             : {
+      56             :   std::vector<double> coord;
+      57             :   std::vector<Tensor> deriv;
+      58             : public:
+      59             :   explicit Ghost(const ActionOptions&ao);
+      60             :   void calculate() override;
+      61             :   static void registerKeywords( Keywords& keys );
+      62             : };
+      63             : 
+      64             : PLUMED_REGISTER_ACTION(Ghost,"GHOST")
+      65             : 
+      66           5 : void Ghost::registerKeywords(Keywords& keys) {
+      67           5 :   ActionWithVirtualAtom::registerKeywords(keys);
+      68          10 :   keys.add("atoms","COORDINATES","coordinates of the ghost atom in the local reference frame");
+      69           5 : }
+      70             : 
+      71           3 : Ghost::Ghost(const ActionOptions&ao):
+      72             :   Action(ao),
+      73           3 :   ActionWithVirtualAtom(ao)
+      74             : {
+      75             :   std::vector<AtomNumber> atoms;
+      76           6 :   parseAtomList("ATOMS",atoms);
+      77           3 :   if(atoms.size()!=3) error("ATOMS should contain a list of three atoms");
+      78             : 
+      79           6 :   parseVector("COORDINATES",coord);
+      80           3 :   if(coord.size()!=3) error("COORDINATES should be a list of three real numbers");
+      81             : 
+      82           3 :   checkRead();
+      83           3 :   log.printf("  of atoms");
+      84          12 :   for(unsigned i=0; i<atoms.size(); ++i) log.printf(" %d",atoms[i].serial());
+      85           3 :   log.printf("\n");
+      86           3 :   requestAtoms(atoms);
+      87           3 : }
+      88             : 
+      89           7 : void Ghost::calculate() {
+      90           7 :   Vector pos;
+      91           7 :   deriv.resize(getNumberOfAtoms());
+      92           7 :   std::array<Vector,3> n;
+      93             : 
+      94             : // first versor
+      95           7 :   Vector n01 = delta(getPosition(0), getPosition(1));
+      96           7 :   n[0]=n01/n01.modulo();
+      97             : 
+      98             : // auxiliary vector
+      99           7 :   Vector n02 = delta(getPosition(0), getPosition(2));
+     100             : 
+     101             : // second versor
+     102           7 :   Vector n03 = crossProduct(n[0],n02);
+     103           7 :   double n03_norm = n03.modulo();
+     104           7 :   n[1]=n03/n03_norm;
+     105             : 
+     106             : // third versor
+     107           7 :   n[2]=crossProduct(n[0],n[1]);
+     108             : 
+     109             : // origin of the reference system
+     110           7 :   pos = getPosition(0);
+     111             : 
+     112          28 :   for(unsigned i=0; i<3; ++i) {
+     113          21 :     pos += coord[i] * n[i];
+     114             :   }
+     115             : 
+     116           7 :   setPosition(pos);
+     117           7 :   setMass(1.0);
+     118           7 :   setCharge(0.0);
+     119             : 
+     120             : // some useful tensors for derivatives
+     121           7 :   Tensor dn0d0  = (-Tensor::identity()+Tensor(n[0],n[0]))/n01.modulo();
+     122           7 :   Tensor dn0d1  = (+Tensor::identity()-Tensor(n[0],n[0]))/n01.modulo();
+     123           7 :   Tensor dn02d0 = -Tensor::identity();
+     124           7 :   Tensor dn02d2 =  Tensor::identity();
+     125             : 
+     126             : // derivative of n1 = n0 x n02
+     127           7 :   Tensor dn1d0, dn1d1, dn1d2;
+     128           7 :   Vector aux0, aux1, aux2;
+     129             : 
+     130          28 :   for(unsigned j=0; j<3; ++j) {
+     131             : // derivative of n0 x n02 with respect to point 0, coordinate j
+     132          21 :     Vector tmp00  = Vector( dn0d0(j,0),  dn0d0(j,1),  dn0d0(j,2));
+     133          21 :     Vector tmp020 = Vector(dn02d0(j,0), dn02d0(j,1), dn02d0(j,2));
+     134          21 :     Vector tmp0   = crossProduct(tmp00,n02) + crossProduct(n[0],tmp020);
+     135          21 :     aux0[j]       = dotProduct(tmp0,n[1]);
+     136             : // derivative of n0 x n02 with respect to point 1, coordinate j
+     137          21 :     Vector tmp01  = Vector( dn0d1(j,0),  dn0d1(j,1),  dn0d1(j,2));
+     138          21 :     Vector tmp1   = crossProduct(tmp01,n02);
+     139          21 :     aux1[j]       = dotProduct(tmp1,n[1]);
+     140             : // derivative of n0 x n02 with respect to point 2, coordinate j
+     141          21 :     Vector tmp022 = Vector(dn02d2(j,0), dn02d2(j,1), dn02d2(j,2));
+     142          21 :     Vector tmp2   = crossProduct(n[0],tmp022);
+     143          21 :     aux2[j]       = dotProduct(tmp2,n[1]);
+     144             : // derivative of n1 = (n0 x n02) / || (n0 x n02) ||
+     145          84 :     for(unsigned i=0; i<3; ++i) {
+     146          63 :       dn1d0(j,i) = ( tmp0[i] - aux0[j] * n[1][i] ) / n03_norm;
+     147          63 :       dn1d1(j,i) = ( tmp1[i] - aux1[j] * n[1][i] ) / n03_norm;
+     148          63 :       dn1d2(j,i) = ( tmp2[i] - aux2[j] * n[1][i] ) / n03_norm;
+     149             :     }
+     150             :   }
+     151             : 
+     152             : // Derivative of the last versor n2 = n0 x n1 =  ( n0( n0 n02 ) - n02 ) / || n0 x n02 ||
+     153             : // Scalar product and derivatives
+     154           7 :   double n0_n02 = dotProduct(n[0],n02);
+     155           7 :   Vector dn0_n02d0, dn0_n02d1, dn0_n02d2;
+     156             : 
+     157          28 :   for(unsigned j=0; j<3; ++j) {
+     158          84 :     for(unsigned i=0; i<3; ++i) {
+     159          63 :       dn0_n02d0[j] += dn0d0(j,i)*n02[i] + n[0][i]*dn02d0(j,i);
+     160          63 :       dn0_n02d1[j] += dn0d1(j,i)*n02[i];
+     161          63 :       dn0_n02d2[j] +=                     n[0][i]*dn02d2(j,i);
+     162             :     }
+     163             :   }
+     164             : 
+     165           7 :   Tensor dn2d0, dn2d1, dn2d2;
+     166          28 :   for(unsigned j=0; j<3; ++j) {
+     167          84 :     for(unsigned i=0; i<3; ++i) {
+     168          63 :       dn2d0(j,i) = ( dn0d0(j,i) * n0_n02 + n[0][i] * dn0_n02d0[j] - dn02d0(j,i) - ( n[0][i] * n0_n02 - n02[i] ) * aux0[j] / n03_norm ) / n03_norm;
+     169          63 :       dn2d1(j,i) = ( dn0d1(j,i) * n0_n02 + n[0][i] * dn0_n02d1[j]               - ( n[0][i] * n0_n02 - n02[i] ) * aux1[j] / n03_norm ) / n03_norm;
+     170          63 :       dn2d2(j,i) = (                       n[0][i] * dn0_n02d2[j] - dn02d2(j,i) - ( n[0][i] * n0_n02 - n02[i] ) * aux2[j] / n03_norm ) / n03_norm;
+     171             :     }
+     172             :   }
+     173             : 
+     174             : // Finally, the derivative tensor
+     175           7 :   deriv[0] = Tensor::identity() + coord[0]*dn0d0 + coord[1]*dn1d0 + coord[2]*dn2d0;
+     176           7 :   deriv[1] =                      coord[0]*dn0d1 + coord[1]*dn1d1 + coord[2]*dn2d1;
+     177           7 :   deriv[2] =                                       coord[1]*dn1d2 + coord[2]*dn2d2;
+     178             : 
+     179           7 :   setAtomsDerivatives(deriv);
+     180             : 
+     181             : // Virial contribution
+     182           7 :   setBoxDerivativesNoPbc();
+     183           7 : }
+     184             : 
+     185             : }
+     186             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/index-sort-f.html b/coverage/vatom/index-sort-f.html new file mode 100644 index 000000000000..8cd989c40bc0 --- /dev/null +++ b/coverage/vatom/index-sort-f.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:22722899.6 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Center.cpp +
99.2%99.2%
+
99.2 %121 / 12275.0 %3 / 4
FixedAtom.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
Ghost.cpp +
100.0%
+
100.0 %73 / 7375.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/index-sort-l.html b/coverage/vatom/index-sort-l.html new file mode 100644 index 000000000000..2e6cdae6e698 --- /dev/null +++ b/coverage/vatom/index-sort-l.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:22722899.6 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Center.cpp +
99.2%99.2%
+
99.2 %121 / 12275.0 %3 / 4
FixedAtom.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
Ghost.cpp +
100.0%
+
100.0 %73 / 7375.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vatom/index.html b/coverage/vatom/index.html new file mode 100644 index 000000000000..9bf0d5594b8a --- /dev/null +++ b/coverage/vatom/index.html @@ -0,0 +1,114 @@ + + + + + + + + LCOV - plumed test coverage - vatom + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vatomHitTotalCoverage
Test:plumed test coverageLines:22722899.6 %
Date:2024-02-22 21:58:45Functions:91275.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Center.cpp +
99.2%99.2%
+
99.2 %121 / 12275.0 %3 / 4
FixedAtom.cpp +
100.0%
+
100.0 %33 / 3375.0 %3 / 4
Ghost.cpp +
100.0%
+
100.0 %73 / 7375.0 %3 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Chebyshev.cpp.func-sort-c.html b/coverage/ves/BF_Chebyshev.cpp.func-sort-c.html new file mode 100644 index 000000000000..3920e24ea015 --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Chebyshev.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Chebyshev.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Chebyshev21setupUniformIntegralsEv3
_ZN4PLMD3ves12BF_ChebyshevC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves12BF_Chebyshev16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD3ves12BF_Chebyshev12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_7882
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Chebyshev.cpp.func.html b/coverage/ves/BF_Chebyshev.cpp.func.html new file mode 100644 index 000000000000..d59cf34d8fe3 --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Chebyshev.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Chebyshev.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Chebyshev16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves12BF_Chebyshev21setupUniformIntegralsEv3
_ZN4PLMD3ves12BF_ChebyshevC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves12BF_Chebyshev12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_7882
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Chebyshev.cpp.gcov.html b/coverage/ves/BF_Chebyshev.cpp.gcov.html new file mode 100644 index 000000000000..db86ffc49ca5 --- /dev/null +++ b/coverage/ves/BF_Chebyshev.cpp.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Chebyshev.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Chebyshev.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_CHEBYSHEV
+      32             : /*
+      33             : Chebyshev polynomial basis functions.
+      34             : 
+      35             : Use as basis functions [Chebyshev polynomials](https://en.wikipedia.org/wiki/Chebyshev_polynomials)
+      36             : of the first kind \f$T_{n}(x)\f$ defined on a bounded interval.
+      37             : You need to provide the interval \f$[a,b]\f$
+      38             : on which the basis functions are to be used, and the order of the
+      39             : expansion \f$N\f$ (i.e. the highest order polynomial used).
+      40             : The total number of basis functions is \f$N+1\f$ as the constant \f$T_{0}(x)=1\f$
+      41             : is also included.
+      42             : These basis functions should not be used for periodic CVs.
+      43             : 
+      44             : Intrinsically the Chebyshev polynomials are defined on the interval \f$[-1,1]\f$.
+      45             : A variable \f$t\f$ in the interval \f$[a,b]\f$ is transformed to a variable \f$x\f$
+      46             : in the intrinsic interval \f$[-1,1]\f$ by using the transform function
+      47             : \f[
+      48             : x(t) = \frac{t-(a+b)/2}
+      49             : {(b-a)/2}
+      50             : \f]
+      51             : 
+      52             : The Chebyshev polynomials are given by the recurrence relation
+      53             : \f{align}{
+      54             : T_{0}(x)    &= 1 \\
+      55             : T_{1}(x)    &= x \\
+      56             : T_{n+1}(x)  &= 2 \, x \, T_{n}(x) - T_{n-1}(x)
+      57             : \f}
+      58             : 
+      59             : The first 6 polynomials are shown below
+      60             : \image html ves_basisf-chebyshev.png
+      61             : 
+      62             : The Chebyshev polynomial are orthogonal over the interval \f$[-1,1]\f$
+      63             : with respect to the weight \f$\frac{1}{\sqrt{1-x^2}}\f$
+      64             : \f[
+      65             : \int_{-1}^{1} dx \, T_{n}(x)\, T_{m}(x) \, \frac{1}{\sqrt{1-x^2}} =
+      66             : \begin{cases}
+      67             : 0 & n \neq m \\
+      68             : \pi & n = m = 0 \\
+      69             : \pi/2 & n = m \neq 0
+      70             : \end{cases}
+      71             : \f]
+      72             : 
+      73             : For further mathematical properties of the Chebyshev polynomials see for example
+      74             : the [Wikipedia page](https://en.wikipedia.org/wiki/Chebyshev_polynomials).
+      75             : 
+      76             : \par Examples
+      77             : 
+      78             : Here we employ a Chebyshev expansion of order 20 over the interval 0.0 to 10.0.
+      79             : This results in a total number of 21 basis functions.
+      80             : The label used to identify  the basis function action can then be
+      81             : referenced later on in the input file.
+      82             : \plumedfile
+      83             : bfC: BF_CHEBYSHEV MINIMUM=0.0 MAXIMUM=10.0 ORDER=20
+      84             : \endplumedfile
+      85             : 
+      86             : */
+      87             : //+ENDPLUMEDOC
+      88             : 
+      89             : 
+      90             : class BF_Chebyshev : public BasisFunctions {
+      91             :   void setupUniformIntegrals() override;
+      92             : public:
+      93             :   static void registerKeywords(Keywords&);
+      94             :   explicit BF_Chebyshev(const ActionOptions&);
+      95             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      96             : };
+      97             : 
+      98             : 
+      99             : PLUMED_REGISTER_ACTION(BF_Chebyshev,"BF_CHEBYSHEV")
+     100             : 
+     101             : 
+     102           6 : void BF_Chebyshev::registerKeywords(Keywords& keys) {
+     103           6 :   BasisFunctions::registerKeywords(keys);
+     104           6 : }
+     105             : 
+     106           4 : BF_Chebyshev::BF_Chebyshev(const ActionOptions&ao):
+     107           4 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     108             : {
+     109           4 :   setNumberOfBasisFunctions(getOrder()+1);
+     110           8 :   setIntrinsicInterval("-1.0","+1.0");
+     111             :   setNonPeriodic();
+     112             :   setIntervalBounded();
+     113           4 :   setType("chebyshev-1st-kind");
+     114           4 :   setDescription("Chebyshev polynomials of the first kind");
+     115           4 :   setLabelPrefix("T");
+     116           4 :   setupBF();
+     117           4 :   checkRead();
+     118           4 : }
+     119             : 
+     120             : 
+     121        7882 : void BF_Chebyshev::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     122             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     123             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     124        7882 :   inside_range=true;
+     125        7882 :   argT=translateArgument(arg, inside_range);
+     126        7882 :   std::vector<double> derivsT(derivs.size());
+     127             :   //
+     128        7882 :   values[0]=1.0;
+     129        7882 :   derivsT[0]=0.0;
+     130        7882 :   derivs[0]=0.0;
+     131        7882 :   values[1]=argT;
+     132        7882 :   derivsT[1]=1.0;
+     133        7882 :   derivs[1]=intervalDerivf();
+     134      135100 :   for(unsigned int i=1; i < getOrder(); i++) {
+     135      127218 :     values[i+1]  = 2.0*argT*values[i]-values[i-1];
+     136      127218 :     derivsT[i+1] = 2.0*values[i]+2.0*argT*derivsT[i]-derivsT[i-1];
+     137      127218 :     derivs[i+1]  = intervalDerivf()*derivsT[i+1];
+     138             :   }
+     139        9906 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     140        7882 : }
+     141             : 
+     142             : 
+     143           3 : void BF_Chebyshev::setupUniformIntegrals() {
+     144          56 :   for(unsigned int i=0; i<numberOfBasisFunctions(); i++) {
+     145          53 :     double io = i;
+     146             :     double value = 0.0;
+     147          53 :     if(i % 2 == 0) {
+     148          28 :       value = -2.0/( pow(io,2.0)-1.0)*0.5;
+     149             :     }
+     150             :     setUniformIntegral(i,value);
+     151             :   }
+     152           3 : }
+     153             : 
+     154             : 
+     155             : }
+     156             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Combined.cpp.func-sort-c.html b/coverage/ves/BF_Combined.cpp.func-sort-c.html new file mode 100644 index 000000000000..20cafcd1626d --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Combined.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Combined.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636596.9 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Combined11setupLabelsEv2
_ZN4PLMD3ves11BF_Combined21setupUniformIntegralsEv2
_ZN4PLMD3ves11BF_CombinedC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves11BF_Combined16registerKeywordsERNS_8KeywordsE4
_ZNK4PLMD3ves11BF_Combined12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3616
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Combined.cpp.func.html b/coverage/ves/BF_Combined.cpp.func.html new file mode 100644 index 000000000000..edcfd6bbf582 --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Combined.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Combined.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636596.9 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Combined11setupLabelsEv2
_ZN4PLMD3ves11BF_Combined16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves11BF_Combined21setupUniformIntegralsEv2
_ZN4PLMD3ves11BF_CombinedC2ERKNS_13ActionOptionsE2
_ZNK4PLMD3ves11BF_Combined12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3616
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Combined.cpp.gcov.html b/coverage/ves/BF_Combined.cpp.gcov.html new file mode 100644 index 000000000000..1c5f058fe091 --- /dev/null +++ b/coverage/ves/BF_Combined.cpp.gcov.html @@ -0,0 +1,279 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Combined.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Combined.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636596.9 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : #include "VesTools.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/PlumedMain.h"
+      29             : 
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace ves {
+      33             : 
+      34             : //+PLUMEDOC VES_BASISF BF_COMBINED
+      35             : /*
+      36             : Combining other basis functions types
+      37             : 
+      38             : \par Examples
+      39             : 
+      40             : Here we define both Fourier cosine and sine expansions of order 10,
+      41             : each with 11 basis functions, which are combined. This results
+      42             : in a total number of 21 basis functions as only the constant from
+      43             : is bf_cos is used.
+      44             : \plumedfile
+      45             : bf_cos: BF_COSINE MINIMUM=-pi MAXIMUM=+pi ORDER=10
+      46             : bf_sin: BF_SINE   MINIMUM=-pi MAXIMUM=+pi ORDER=10
+      47             : bf_comb: BF_COMBINED BASIS_FUNCTIONS=bf_cos,bf_sin
+      48             : \endplumedfile
+      49             : In principle this is the same as using BF_FOURIER with
+      50             : ORDER=10 but with different ordering of the basis functions.
+      51             : Note that the order used in BASIS_FUNCTIONS matters for the ordering
+      52             : of the basis functions, using BASIS_FUNCTIONS=bf_sin,bf_cos would
+      53             : results in a different order of the basis functions.
+      54             : This should be kept in mind when restarting from previous
+      55             : coefficients.
+      56             : 
+      57             : 
+      58             : 
+      59             : 
+      60             : 
+      61             : 
+      62             : */
+      63             : //+ENDPLUMEDOC
+      64             : 
+      65             : class BF_Combined : public BasisFunctions {
+      66             :   std::vector<BasisFunctions*> basisf_pntrs_;
+      67             :   void setupLabels() override;
+      68             :   void setupUniformIntegrals() override;
+      69             :   // void getBFandValueIndices(const unsigned int, unsigned int&, unsigned int&) const;
+      70             : public:
+      71             :   static void registerKeywords(Keywords&);
+      72             :   explicit BF_Combined(const ActionOptions&);
+      73             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      74             : };
+      75             : 
+      76             : 
+      77             : PLUMED_REGISTER_ACTION(BF_Combined,"BF_COMBINED")
+      78             : 
+      79             : 
+      80           4 : void BF_Combined::registerKeywords(Keywords& keys) {
+      81           4 :   BasisFunctions::registerKeywords(keys);
+      82           4 :   keys.remove("ORDER");
+      83           4 :   keys.remove("MAXIMUM");
+      84           4 :   keys.remove("MINIMUM");
+      85           4 :   keys.remove("NUMERICAL_INTEGRALS");
+      86           4 :   keys.remove("NGRID_POINTS");
+      87           8 :   keys.add("compulsory","BASIS_FUNCTIONS","Labels of the basis functions that should be combined. Note that the order used matters for the ordering of the basis functions. This needs to be kept in mind when restarting from previous coefficients.");
+      88           4 : }
+      89             : 
+      90             : 
+      91           2 : BF_Combined::BF_Combined(const ActionOptions&ao):
+      92             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+      93           2 :   basisf_pntrs_(0)
+      94             : {
+      95             :   std::vector<std::string> basisf_labels;
+      96           6 :   parseVector("BASIS_FUNCTIONS",basisf_labels); addKeywordToList("BASIS_FUNCTIONS",basisf_labels);
+      97           2 :   if(basisf_labels.size()==1) {
+      98           0 :     plumed_merror("using only one basis function in BF_COMBINED does not make sense");
+      99             :   }
+     100           2 :   std::string error_msg = "";
+     101           4 :   basisf_pntrs_ = VesTools::getPointersFromLabels<BasisFunctions*>(basisf_labels,plumed.getActionSet(),error_msg);
+     102           2 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BASIS_FUNCTIONS of "+getName()+": "+error_msg);}
+     103             : 
+     104             :   unsigned int nbasisf_total_ = 1;
+     105             :   bool periodic = true;
+     106           7 :   for(unsigned int i=0; i<basisf_pntrs_.size(); i++) {
+     107           5 :     nbasisf_total_ += basisf_pntrs_[i]->getNumberOfBasisFunctions() - 1;
+     108          15 :     if(basisf_pntrs_[i]->intervalMinStr()!=basisf_pntrs_[0]->intervalMinStr() || basisf_pntrs_[i]->intervalMaxStr()!=basisf_pntrs_[0]->intervalMaxStr()) {
+     109           0 :       plumed_merror("all the basis functions to be combined should have same MINIMUM and MAXIMUM");
+     110             :     }
+     111           5 :     if(!basisf_pntrs_[i]->arePeriodic()) {periodic=false;}
+     112             :   }
+     113           2 :   setOrder(nbasisf_total_-1);
+     114           2 :   setNumberOfBasisFunctions(nbasisf_total_);
+     115           4 :   setInterval(basisf_pntrs_[0]->intervalMinStr(),basisf_pntrs_[0]->intervalMaxStr());
+     116           4 :   setIntrinsicInterval("-1.0","+1.0");
+     117           2 :   if(periodic) {setPeriodic();}
+     118             :   else {setNonPeriodic();}
+     119             :   setIntervalBounded();
+     120           2 :   setType("combined");
+     121           2 :   setDescription("Combined");
+     122           2 :   setupBF();
+     123           2 :   checkRead();
+     124           2 : }
+     125             : 
+     126             : 
+     127             : // void BF_Combined::getBFandValueIndices(const unsigned int n, unsigned int& bf_index, unsigned int& value_index) const {
+     128             : //   bf_index = 0; value_index = 0;
+     129             : //   if(n==0){
+     130             : //     bf_index = 0;
+     131             : //     value_index = 0;
+     132             : //     return;
+     133             : //   }
+     134             : //   else{
+     135             : //     unsigned int r=1;
+     136             : //     for(unsigned int i=0; i<basisf_pntrs_.size(); i++){
+     137             : //       for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++){
+     138             : //         if(r==n){
+     139             : //           bf_index = i;
+     140             : //           value_index = l;
+     141             : //           return;
+     142             : //         }
+     143             : //         r++;
+     144             : //       }
+     145             : //     }
+     146             : //   }
+     147             : // }
+     148             : 
+     149             : 
+     150        3616 : void BF_Combined::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     151             :   // first BF, constant, argT, and inside_range taken from here
+     152             :   unsigned int r=0;
+     153        3616 :   std::vector<double> values_tmp(basisf_pntrs_[0]->numberOfBasisFunctions(),0.0);
+     154        3616 :   std::vector<double> derivs_tmp(basisf_pntrs_[0]->numberOfBasisFunctions(),0.0);
+     155        3616 :   basisf_pntrs_[0]->getAllValues(arg,argT,inside_range,values_tmp,derivs_tmp);
+     156       43392 :   for(unsigned int l=0; l<basisf_pntrs_[0]->numberOfBasisFunctions(); l++) {
+     157       39776 :     values[r] = values_tmp[l];
+     158       39776 :     derivs[r] = derivs_tmp[l];
+     159       39776 :     r++;
+     160             :   }
+     161             :   // other BF
+     162        9043 :   for(unsigned int i=1; i<basisf_pntrs_.size(); i++) {
+     163        5427 :     values_tmp.assign(basisf_pntrs_[i]->numberOfBasisFunctions(),0.0);
+     164        5427 :     derivs_tmp.assign(basisf_pntrs_[i]->numberOfBasisFunctions(),0.0);
+     165        5427 :     double dummy_dbl; bool dummy_bool=true;
+     166        5427 :     basisf_pntrs_[i]->getAllValues(arg,dummy_dbl,dummy_bool,values_tmp,derivs_tmp);
+     167       59697 :     for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++) {
+     168       54270 :       values[r] = values_tmp[l];
+     169       54270 :       derivs[r] = derivs_tmp[l];
+     170       54270 :       r++;
+     171             :     }
+     172             :   }
+     173        3616 : }
+     174             : 
+     175             : 
+     176           2 : void BF_Combined::setupLabels() {
+     177           2 :   setLabel(0,basisf_pntrs_[0]->getBasisFunctionLabel(0));
+     178             :   unsigned int r=1;
+     179           7 :   for(unsigned int i=0; i<basisf_pntrs_.size(); i++) {
+     180          55 :     for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++) {
+     181          50 :       setLabel(r,basisf_pntrs_[i]->getBasisFunctionLabel(l));
+     182          50 :       r++;
+     183             :     }
+     184             :   }
+     185           2 : }
+     186             : 
+     187             : 
+     188           2 : void BF_Combined::setupUniformIntegrals() {
+     189           2 :   setUniformIntegral(0,basisf_pntrs_[0]->getUniformIntegrals()[0]);
+     190             :   unsigned int r=1;
+     191           7 :   for(unsigned int i=0; i<basisf_pntrs_.size(); i++) {
+     192           5 :     std::vector<double> uniform_tmp = basisf_pntrs_[i]->getUniformIntegrals();
+     193          55 :     for(unsigned int l=1; l<basisf_pntrs_[i]->numberOfBasisFunctions(); l++) {
+     194          50 :       setUniformIntegral(r,uniform_tmp[l]);
+     195          50 :       r++;
+     196             :     }
+     197             :   }
+     198           2 : }
+     199             : 
+     200             : 
+     201             : }
+     202             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Cosine.cpp.func-sort-c.html b/coverage/ves/BF_Cosine.cpp.func-sort-c.html new file mode 100644 index 000000000000..34b82cf8bbf5 --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Cosine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Cosine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_Cosine21setupUniformIntegralsEv3
_ZN4PLMD3ves9BF_Cosine11setupLabelsEv4
_ZN4PLMD3ves9BF_CosineC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves9BF_Cosine16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD3ves9BF_Cosine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Cosine.cpp.func.html b/coverage/ves/BF_Cosine.cpp.func.html new file mode 100644 index 000000000000..d4dbe79783f6 --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Cosine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Cosine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_Cosine11setupLabelsEv4
_ZN4PLMD3ves9BF_Cosine16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves9BF_Cosine21setupUniformIntegralsEv3
_ZN4PLMD3ves9BF_CosineC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves9BF_Cosine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Cosine.cpp.gcov.html b/coverage/ves/BF_Cosine.cpp.gcov.html new file mode 100644 index 000000000000..5832694ed469 --- /dev/null +++ b/coverage/ves/BF_Cosine.cpp.gcov.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Cosine.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Cosine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_COSINE
+      32             : /*
+      33             : Fourier cosine basis functions.
+      34             : 
+      35             : Use as basis functions Fourier cosine series defined on a periodic interval.
+      36             : You need to provide the periodic interval \f$[a,b]\f$
+      37             : on which the basis functions are to be used, and the order of the
+      38             : expansion \f$N\f$ (i.e. the highest Fourier cosine mode used).
+      39             : The total number of basis functions is \f$N+1\f$ as
+      40             : the constant \f$f_{0}(x)=1\f$ is also included.
+      41             : These basis functions should only be used for periodic CVs.
+      42             : They can be useful if the periodic function being expanded is an
+      43             : even function, i.e. \f$F(-x)=F(x)\f$.
+      44             : 
+      45             : The Fourier cosine basis functions are given by
+      46             : \f{align}{
+      47             : f_{0}(x)    &= 1 \\
+      48             : f_{1}(x)    &= cos(\frac{2\pi }{P} x) \\
+      49             : f_{2}(x)    &= cos(2 \cdot \frac{2\pi}{P} x) \\
+      50             : f_{3}(x)    &= cos(3 \cdot \frac{2\pi}{P} x) \\
+      51             : & \vdots \\
+      52             : f_{n}(x) &= cos(n \cdot \frac{2\pi}{P} x) \\
+      53             : & \vdots \\
+      54             : f_{N}(x)   &= cos(N \cdot \frac{2\pi}{P} x) \\
+      55             : \f}
+      56             : where \f$P=(b-a)\f$ is the periodicity of the interval.
+      57             : They are orthogonal over the interval \f$[a,b]\f$
+      58             : \f[
+      59             : \int_{a}^{b} dx \, f_{n}(x)\, f_{m}(x)  =
+      60             : \begin{cases}
+      61             : 0 & n \neq m \\
+      62             : (b-a) & n = m = 0 \\
+      63             : (b-a)/2 & n = m \neq 0
+      64             : \end{cases}.
+      65             : \f]
+      66             : 
+      67             : \par Examples
+      68             : 
+      69             : Here we employ a Fourier cosine expansion of order 10 over the periodic interval
+      70             : \f$-\pi\f$ to \f$+\pi\f$.
+      71             : This results in a total number of 11 basis functions.
+      72             : The label used to identify  the basis function action can then be
+      73             : referenced later on in the input file.
+      74             : \plumedfile
+      75             : BF_COSINE MINIMUM=-pi MAXIMUM=+pi ORDER=10 LABEL=bf1
+      76             : \endplumedfile
+      77             : 
+      78             : 
+      79             : 
+      80             : */
+      81             : //+ENDPLUMEDOC
+      82             : 
+      83             : 
+      84             : class BF_Cosine : public BasisFunctions {
+      85             :   void setupLabels() override;
+      86             :   void setupUniformIntegrals() override;
+      87             : public:
+      88             :   static void registerKeywords(Keywords&);
+      89             :   explicit BF_Cosine(const ActionOptions&);
+      90             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      91             : };
+      92             : 
+      93             : 
+      94             : PLUMED_REGISTER_ACTION(BF_Cosine,"BF_COSINE")
+      95             : 
+      96             : 
+      97           6 : void BF_Cosine::registerKeywords(Keywords& keys) {
+      98           6 :   BasisFunctions::registerKeywords(keys);
+      99           6 : }
+     100             : 
+     101             : 
+     102           4 : BF_Cosine::BF_Cosine(const ActionOptions&ao):
+     103           4 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     104             : {
+     105           4 :   setNumberOfBasisFunctions(getOrder()+1);
+     106           8 :   setIntrinsicInterval("-pi","+pi");
+     107             :   setPeriodic();
+     108             :   setIntervalBounded();
+     109           4 :   setType("trigonometric_cos");
+     110           4 :   setDescription("Cosine");
+     111           4 :   setupBF();
+     112           4 :   checkRead();
+     113           4 : }
+     114             : 
+     115             : 
+     116        9229 : void BF_Cosine::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     117             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     118             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     119        9229 :   inside_range=true;
+     120        9229 :   argT=translateArgument(arg, inside_range);
+     121        9229 :   values[0]=1.0;
+     122        9229 :   derivs[0]=0.0;
+     123      101519 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     124       92290 :     double io = i;
+     125       92290 :     double cos_tmp = cos(io*argT);
+     126       92290 :     double sin_tmp = sin(io*argT);
+     127       92290 :     values[i] = cos_tmp;
+     128       92290 :     derivs[i] = -io*sin_tmp*intervalDerivf();
+     129             :   }
+     130        9229 :   if(!inside_range) {
+     131         960 :     for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}
+     132             :   }
+     133        9229 : }
+     134             : 
+     135             : 
+     136           4 : void BF_Cosine::setupLabels() {
+     137           4 :   setLabel(0,"1");
+     138          44 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     139          40 :     std::string is; Tools::convert(i,is);
+     140          80 :     setLabel(i,"cos("+is+"*s)");
+     141             :   }
+     142           4 : }
+     143             : 
+     144             : 
+     145           3 : void BF_Cosine::setupUniformIntegrals() {
+     146           3 :   setAllUniformIntegralsToZero();
+     147             :   setUniformIntegral(0,1.0);
+     148           3 : }
+     149             : 
+     150             : 
+     151             : }
+     152             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html b/coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html new file mode 100644 index 000000000000..28387fdeef9a --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_CubicBsplines.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_CubicBsplines.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5858100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves16BF_CubicBsplinesC2ERKNS_13ActionOptionsE3
_ZN4PLMD3ves16BF_CubicBsplines16registerKeywordsERNS_8KeywordsE5
_ZNK4PLMD3ves16BF_CubicBsplines12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
_ZNK4PLMD3ves16BF_CubicBsplines6splineEdRd202807
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_CubicBsplines.cpp.func.html b/coverage/ves/BF_CubicBsplines.cpp.func.html new file mode 100644 index 000000000000..ef07f4d238f5 --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_CubicBsplines.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_CubicBsplines.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5858100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves16BF_CubicBsplines16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves16BF_CubicBsplinesC2ERKNS_13ActionOptionsE3
_ZNK4PLMD3ves16BF_CubicBsplines12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
_ZNK4PLMD3ves16BF_CubicBsplines6splineEdRd202807
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_CubicBsplines.cpp.gcov.html b/coverage/ves/BF_CubicBsplines.cpp.gcov.html new file mode 100644 index 000000000000..1f9db49b90dd --- /dev/null +++ b/coverage/ves/BF_CubicBsplines.cpp.gcov.html @@ -0,0 +1,278 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_CubicBsplines.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_CubicBsplines.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5858100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace ves {
+      31             : 
+      32             : //+PLUMEDOC VES_BASISF BF_CUBIC_B_SPLINES
+      33             : /*
+      34             : Cubic B spline basis functions.
+      35             : 
+      36             : \attention
+      37             : __These basis functions do not form orthogonal bases. We recommend using wavelets (\ref BF_WAVELETS) instead that do for orthogonal bases__.
+      38             : 
+      39             : A basis using cubic B spline functions according to \cite habermann_multidimensional_2007. See \cite ValssonPampel_Wavelets_2022 for full details.
+      40             : 
+      41             : The mathematical expression of the individual splines is given by
+      42             : \f{align*}{
+      43             :   h\left(x\right) =
+      44             :   \begin{cases}
+      45             :     \left(2 - \lvert x \rvert\right)^3, & 1 \leq \lvert x \rvert \leq 2\\
+      46             :     4 - 6\lvert x \rvert^2 + 3 \lvert x \rvert^3,\qquad & \lvert x \rvert \leq 1\\
+      47             :     0, & \text{elsewhere}.
+      48             :   \end{cases}
+      49             : \f}
+      50             : 
+      51             : The full basis consists of equidistant splines at positions \f$\mu_i\f$ which are optimized in their height:
+      52             : \f{align*}{
+      53             :   f_i\left(x\right) = h\left(\frac{x-\mu_i}{\sigma}\right)
+      54             : \f}
+      55             : 
+      56             : Note that the distance between individual splines cannot be chosen freely but is equal to the width: \f$\mu_{i+1} = \mu_{i} + \sigma\f$.
+      57             : 
+      58             : 
+      59             : The ORDER keyword of the basis set determines the number of equally sized sub-intervalls to be used.
+      60             : On the borders of each of these sub-intervalls the mean \f$\mu_i\f$ of a spline function is placed.
+      61             : 
+      62             : The total number of basis functions is \f$\text{ORDER}+4\f$ as the constant \f$f_{0}(x)=1\f$, as well as the two splines with means just outside the interval are also included.
+      63             : 
+      64             : As an example two adjacent basis functions can be seen below.
+      65             : The full basis consists of shifted splines in the full specified interval.
+      66             : 
+      67             : \image html ves_basisf-splines.png
+      68             : 
+      69             : When the splines are used for a periodic CV (with the PERIODIC keyword),
+      70             : the sub-intervals are chosen in the same way, but only \f$\text{ORDER}+1\f$ functions
+      71             : are required to fill it (the ones at the boundary coincide and the ones outside
+      72             : can be omitted).
+      73             : 
+      74             : To avoid 'blind' optimization of the basis functions outside the currently sampled area, it is often beneficial to use the OPTIMIZATION_THRESHOLD keyword of the VES_LINEAR_EXPANSION (set it to a small value, e.g. 1e-6)
+      75             : 
+      76             : \par Examples
+      77             : The bias is expanded with cubic B splines in the intervall from 0.0 to 10.0 specifying an order of 20.
+      78             : This results in 24 basis functions.
+      79             : 
+      80             : \plumedfile
+      81             : bf: BF_CUBIC_B_SPLINES MINIMUM=0.0 MAXIMUM=10.0 ORDER=20
+      82             : \endplumedfile
+      83             : 
+      84             : */
+      85             : //+ENDPLUMEDOC
+      86             : 
+      87             : class BF_CubicBsplines : public BasisFunctions {
+      88             :   double spacing_;
+      89             :   double inv_spacing_;
+      90             :   double inv_normfactor_;
+      91             :   double spline(const double, double&) const;
+      92             : public:
+      93             :   static void registerKeywords( Keywords&);
+      94             :   explicit BF_CubicBsplines(const ActionOptions&);
+      95             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const;
+      96             : };
+      97             : 
+      98             : 
+      99             : PLUMED_REGISTER_ACTION(BF_CubicBsplines,"BF_CUBIC_B_SPLINES")
+     100             : 
+     101             : // See DOI 10.1007/s10614-007-9092-4 for more information;
+     102             : 
+     103             : 
+     104           5 : void BF_CubicBsplines::registerKeywords(Keywords& keys) {
+     105           5 :   BasisFunctions::registerKeywords(keys);
+     106          10 :   keys.add("optional","NORMALIZATION","the normalization factor that is used to normalize the basis functions by dividing the values. By default it is 2.");
+     107          10 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     108           5 :   keys.remove("NUMERICAL_INTEGRALS");
+     109           5 : }
+     110             : 
+     111           3 : BF_CubicBsplines::BF_CubicBsplines(const ActionOptions&ao):
+     112           3 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     113             : {
+     114           3 :   log.printf("  Cubic B spline basis functions, see and cite ");
+     115           6 :   log << plumed.cite("Pampel and Valsson, J. Chem. Theory Comput. 18, 4127-4141 (2022) - DOI:10.1021/acs.jctc.2c00197");
+     116             : 
+     117           3 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     118           3 :   spacing_=(intervalMax()-intervalMin())/static_cast<double>(getOrder());
+     119           3 :   inv_spacing_ = 1.0/spacing_;
+     120             : 
+     121           3 :   bool periodic = false;
+     122           3 :   parseFlag("PERIODIC",periodic);
+     123           4 :   if (periodic) {addKeywordToList("PERIODIC",periodic);}
+     124             : 
+     125             :   // 1 constant, getOrder() on interval, 1 (left) + 2 (right) at boundaries if not periodic
+     126           3 :   unsigned int num_BFs = periodic ? getOrder()+1U : getOrder()+4U;
+     127           3 :   setNumberOfBasisFunctions(num_BFs);
+     128             : 
+     129           3 :   double normfactor_=2.0;
+     130           3 :   parse("NORMALIZATION",normfactor_);
+     131           3 :   if(normfactor_!=2.0) {addKeywordToList("NORMALIZATION",normfactor_);}
+     132           3 :   inv_normfactor_=1.0/normfactor_;
+     133             : 
+     134           3 :   periodic ? setPeriodic() : setNonPeriodic();
+     135             :   setIntervalBounded();
+     136           3 :   setType("splines_2nd-order");
+     137           3 :   setDescription("Cubic B-splines (2nd order splines)");
+     138           3 :   setLabelPrefix("S");
+     139           3 :   setupBF();
+     140           3 :   log.printf("   normalization factor: %f\n",normfactor_);
+     141           3 :   checkRead();
+     142           3 : }
+     143             : 
+     144             : 
+     145        9236 : void BF_CubicBsplines::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     146             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     147             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     148        9236 :   inside_range=true;
+     149        9236 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     150             :   //
+     151        9236 :   values[0]=1.0;
+     152        9236 :   derivs[0]=0.0;
+     153             :   //
+     154      212043 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     155      202807 :     double argx = ((argT-intervalMin())*inv_spacing_) - (static_cast<double>(i) - 2.0);
+     156      202807 :     if(arePeriodic()) { // periodic range of argx is [-intervalRange/spacing,+intervalRange/spacing]
+     157       64140 :       argx /= intervalRange()*inv_spacing_;
+     158       64140 :       argx = Tools::pbc(argx);
+     159       64140 :       argx *= (intervalRange()*inv_spacing_);
+     160             :     }
+     161      202807 :     values[i] = spline(argx, derivs[i]);
+     162      202807 :     derivs[i] *= inv_spacing_;
+     163             :   }
+     164       11156 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     165        9236 : }
+     166             : 
+     167             : 
+     168      202807 : double BF_CubicBsplines::spline(const double arg, double& deriv) const {
+     169             :   double value=0.0;
+     170             :   double x=arg;
+     171             :   // derivative of abs(x);
+     172             :   double dx = 1.0;
+     173      202807 :   if(x < 0) {
+     174      101208 :     x=-x;
+     175             :     dx = -1.0;
+     176             :   }
+     177             :   //
+     178      202807 :   if(x > 2) {
+     179             :     value=0.0;
+     180      165556 :     deriv=0.0;
+     181             :   }
+     182       37251 :   else if(x >= 1) {
+     183       18896 :     value = ((2.0-x)*(2.0-x)*(2.0-x));
+     184       18896 :     deriv = dx*(-3.0*(2.0-x)*(2.0-x));
+     185             :     // value=((2.0-x)*(2.0-x)*(2.0-x))/6.0;
+     186             :     // deriv=-x*x*(2.0-x)*(2.0-x);
+     187             :   }
+     188             :   else {
+     189       18355 :     value = 4.0-6.0*x*x+3.0*x*x*x;
+     190       18355 :     deriv = dx*(-12.0*x+9.0*x*x);
+     191             :     // value=x*x*x*0.5-x*x+2.0/3.0;
+     192             :     // deriv=(3.0/2.0)*x*x-2.0*x;
+     193             :   }
+     194      202807 :   value *= inv_normfactor_;
+     195      202807 :   deriv *= inv_normfactor_;
+     196      202807 :   return value;
+     197             : }
+     198             : 
+     199             : 
+     200             : }
+     201             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Custom.cpp.func-sort-c.html b/coverage/ves/BF_Custom.cpp.func-sort-c.html new file mode 100644 index 000000000000..4687f421b065 --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Custom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12515282.2 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_CustomC2ERKNS_13ActionOptionsE10
_ZN4PLMD3ves9BF_CustomD0Ev10
_ZN4PLMD3ves9BF_CustomD2Ev10
_ZN4PLMD3ves9BF_Custom16registerKeywordsERNS_8KeywordsE12
_ZNK4PLMD3ves9BF_Custom12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_24204
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Custom.cpp.func.html b/coverage/ves/BF_Custom.cpp.func.html new file mode 100644 index 000000000000..364fe346e078 --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Custom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12515282.2 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_Custom16registerKeywordsERNS_8KeywordsE12
_ZN4PLMD3ves9BF_CustomC2ERKNS_13ActionOptionsE10
_ZN4PLMD3ves9BF_CustomD0Ev10
_ZN4PLMD3ves9BF_CustomD2Ev10
_ZNK4PLMD3ves9BF_Custom12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_24204
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Custom.cpp.gcov.html b/coverage/ves/BF_Custom.cpp.gcov.html new file mode 100644 index 000000000000..e5b4ccbc3a66 --- /dev/null +++ b/coverage/ves/BF_Custom.cpp.gcov.html @@ -0,0 +1,446 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Custom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12515282.2 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : #include "lepton/Lepton.h"
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace ves {
+      31             : 
+      32             : //+PLUMEDOC VES_BASISF BF_CUSTOM
+      33             : /*
+      34             : Basis functions given by arbitrary mathematical expressions.
+      35             : 
+      36             : This allows you to define basis functions using arbitrary mathematical expressions
+      37             : that are parsed using the lepton library.
+      38             : The basis functions
+      39             : \f$f_{i}(x)\f$ are given in mathematical expressions with _x_ as a variable using
+      40             : the numbered FUNC keywords that start from
+      41             : FUNC1. Consistent with other basis functions is \f$f_{0}(x)=1\f$ defined as
+      42             : the constant. The interval on which the basis functions are defined is
+      43             : given using the MINIMUM and MAXIMUM keywords.
+      44             : 
+      45             : Using the TRANSFORM keyword it is possible to define a function \f$x(t)\f$ that
+      46             : is used to transform the argument before calculating the basis functions
+      47             : values. The variables _min_ and _max_ can be used to indicate the minimum
+      48             : and the maximum of the interval. By default the arguments are not transformed,
+      49             : i.e. \f$x(t)=t\f$.
+      50             : 
+      51             : For periodic basis functions you should use the PERIODIC flag to indicate
+      52             : that they are periodic.
+      53             : 
+      54             : The basis functions \f$f_{i}(x)\f$ and the transform function \f$x(t)\f$ need
+      55             : to be well behaved in the interval on which the basis functions are defined,
+      56             : e.g. not result in a not a number (nan) or infinity (inf).
+      57             : The code will not perform checks to make sure that this is the case unless the
+      58             : flag CHECK_NAN_INF is enabled.
+      59             : 
+      60             : \par Examples
+      61             : 
+      62             : Defining Legendre polynomial basis functions of order 6 using BF_CUSTOM
+      63             : where the appropriate transform function is given by the TRANSFORM keyword.
+      64             : This is just an example of what can be done, in practice you should use
+      65             : \ref BF_LEGENDRE for Legendre polynomial basis functions.
+      66             : \plumedfile
+      67             : BF_CUSTOM ...
+      68             :  TRANSFORM=(t-(min+max)/2)/((max-min)/2)
+      69             :  FUNC1=x
+      70             :  FUNC2=(1/2)*(3*x^2-1)
+      71             :  FUNC3=(1/2)*(5*x^3-3*x)
+      72             :  FUNC4=(1/8)*(35*x^4-30*x^2+3)
+      73             :  FUNC5=(1/8)*(63*x^5-70*x^3+15*x)
+      74             :  FUNC6=(1/16)*(231*x^6-315*x^4+105*x^2-5)
+      75             :  MINIMUM=-4.0
+      76             :  MAXIMUM=4.0
+      77             :  LABEL=bf1
+      78             : ... BF_CUSTOM
+      79             : \endplumedfile
+      80             : 
+      81             : 
+      82             : Defining Fourier basis functions of order 3 using BF_CUSTOM where the
+      83             : periodicity is indicated using the PERIODIC flag. This is just an example
+      84             : of what can be done, in practice you should use \ref BF_FOURIER
+      85             : for Fourier basis functions.
+      86             : \plumedfile
+      87             : BF_CUSTOM ...
+      88             :  FUNC1=cos(x)
+      89             :  FUNC2=sin(x)
+      90             :  FUNC3=cos(2*x)
+      91             :  FUNC4=sin(2*x)
+      92             :  FUNC5=cos(3*x)
+      93             :  FUNC6=sin(3*x)
+      94             :  MINIMUM=-pi
+      95             :  MAXIMUM=+pi
+      96             :  LABEL=bf1
+      97             :  PERIODIC
+      98             : ... BF_CUSTOM
+      99             : \endplumedfile
+     100             : 
+     101             : 
+     102             : */
+     103             : //+ENDPLUMEDOC
+     104             : 
+     105             : class BF_Custom : public BasisFunctions {
+     106             : private:
+     107             :   lepton::CompiledExpression transf_value_expression_;
+     108             :   lepton::CompiledExpression transf_deriv_expression_;
+     109             :   double* transf_value_lepton_ref_;
+     110             :   double* transf_deriv_lepton_ref_;
+     111             :   std::vector<lepton::CompiledExpression> bf_values_expressions_;
+     112             :   std::vector<lepton::CompiledExpression> bf_derivs_expressions_;
+     113             :   std::vector<double*> bf_values_lepton_ref_;
+     114             :   std::vector<double*> bf_derivs_lepton_ref_;
+     115             :   std::string variable_str_;
+     116             :   std::string transf_variable_str_;
+     117             :   bool do_transf_;
+     118             :   bool check_nan_inf_;
+     119             : public:
+     120             :   static void registerKeywords( Keywords&);
+     121             :   explicit BF_Custom(const ActionOptions&);
+     122          30 :   ~BF_Custom() {};
+     123             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+     124             : };
+     125             : 
+     126             : PLUMED_REGISTER_ACTION(BF_Custom,"BF_CUSTOM")
+     127             : 
+     128          12 : void BF_Custom::registerKeywords(Keywords& keys) {
+     129          12 :   BasisFunctions::registerKeywords(keys);
+     130          12 :   keys.remove("ORDER");
+     131          24 :   keys.add("numbered","FUNC","The basis functions f_i(x) given in mathematical expressions using _x_ as a variable.");
+     132          24 :   keys.add("optional","TRANSFORM","An optional function that can be used to transform the argument before calculating the basis function values. You should use _t_ as a variable. You can use the variables _min_ and _max_ to give the minimum and the maximum of the interval.");
+     133          24 :   keys.addFlag("PERIODIC",false,"Indicate that the basis functions are periodic.");
+     134          24 :   keys.addFlag("CHECK_NAN_INF",false,"Check that the basis functions do not result in a not a number (nan) or infinity (inf).");
+     135          12 :   keys.remove("NUMERICAL_INTEGRALS");
+     136          12 : }
+     137             : 
+     138             : 
+     139          10 : BF_Custom::BF_Custom(const ActionOptions&ao):
+     140             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+     141          10 :   transf_value_lepton_ref_(nullptr),
+     142          10 :   transf_deriv_lepton_ref_(nullptr),
+     143          10 :   bf_values_expressions_(0),
+     144          10 :   bf_derivs_expressions_(0),
+     145          10 :   bf_values_lepton_ref_(0,nullptr),
+     146          10 :   bf_derivs_lepton_ref_(0,nullptr),
+     147          10 :   variable_str_("x"),
+     148          10 :   transf_variable_str_("t"),
+     149          10 :   do_transf_(false),
+     150          20 :   check_nan_inf_(false)
+     151             : {
+     152             :   std::vector<std::string> bf_str;
+     153          10 :   std::string str_t1="1";
+     154          10 :   bf_str.push_back(str_t1);
+     155          10 :   for(int i=1;; i++) {
+     156             :     std::string str_t2;
+     157         112 :     if(!parseNumbered("FUNC",i,str_t2)) {break;}
+     158          46 :     std::string is; Tools::convert(i,is);
+     159          92 :     addKeywordToList("FUNC"+is,str_t2);
+     160          46 :     bf_str.push_back(str_t2);
+     161          46 :   }
+     162             :   //
+     163          10 :   if(bf_str.size()==1) {plumed_merror(getName()+" with label "+getLabel()+": No FUNC keywords given");}
+     164             : 
+     165          10 :   setOrder(bf_str.size()-1);
+     166          10 :   setNumberOfBasisFunctions(getOrder()+1);
+     167          10 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     168          10 :   bool periodic = false;
+     169          20 :   parseFlag("PERIODIC",periodic); addKeywordToList("PERIODIC",periodic);
+     170          10 :   if(periodic) {setPeriodic();}
+     171             :   else {setNonPeriodic();}
+     172             :   setIntervalBounded();
+     173          10 :   setType("custom_functions");
+     174          20 :   setDescription("Custom Functions");
+     175             :   //
+     176          10 :   std::vector<std::string> bf_values_parsed(getNumberOfBasisFunctions());
+     177          10 :   std::vector<std::string> bf_derivs_parsed(getNumberOfBasisFunctions());
+     178             :   bf_values_parsed[0] = "1";
+     179             :   bf_derivs_parsed[0] = "0";
+     180             :   //
+     181          10 :   bf_values_expressions_.resize(getNumberOfBasisFunctions());
+     182          10 :   bf_derivs_expressions_.resize(getNumberOfBasisFunctions());
+     183          10 :   bf_values_lepton_ref_.resize(getNumberOfBasisFunctions());
+     184          10 :   bf_derivs_lepton_ref_.resize(getNumberOfBasisFunctions());
+     185             :   //
+     186          56 :   for(unsigned int i=1; i<getNumberOfBasisFunctions(); i++) {
+     187          46 :     std::string is; Tools::convert(i,is);
+     188             :     try {
+     189          46 :       lepton::ParsedExpression pe_value = lepton::Parser::parse(bf_str[i]).optimize(lepton::Constants());
+     190          46 :       std::ostringstream tmp_stream; tmp_stream << pe_value;
+     191          46 :       bf_values_parsed[i] = tmp_stream.str();
+     192          46 :       bf_values_expressions_[i] = pe_value.createCompiledExpression();
+     193          46 :     }
+     194           0 :     catch(PLMD::lepton::Exception& exc) {
+     195           0 :       plumed_merror("There was some problem in parsing the function "+bf_str[i]+" given in FUNC"+is + " with lepton");
+     196           0 :     }
+     197             : 
+     198             :     std::vector<std::string> var_str;
+     199          92 :     for(auto &p: bf_values_expressions_[i].getVariables()) {
+     200          46 :       var_str.push_back(p);
+     201             :     }
+     202          46 :     if(var_str.size()!=1) {
+     203           0 :       plumed_merror("Problem with function "+bf_str[i]+" given in FUNC"+is+": there should only be one variable");
+     204             :     }
+     205          46 :     if(var_str[0]!=variable_str_) {
+     206           0 :       plumed_merror("Problem with function "+bf_str[i]+" given in FUNC"+is+": you should use "+variable_str_+" as a variable");
+     207             :     }
+     208             : 
+     209             :     try {
+     210          92 :       lepton::ParsedExpression pe_deriv = lepton::Parser::parse(bf_str[i]).differentiate(variable_str_).optimize(lepton::Constants());
+     211          46 :       std::ostringstream tmp_stream2; tmp_stream2 << pe_deriv;
+     212          46 :       bf_derivs_parsed[i] = tmp_stream2.str();
+     213          46 :       bf_derivs_expressions_[i] = pe_deriv.createCompiledExpression();
+     214          46 :     }
+     215           0 :     catch(PLMD::lepton::Exception& exc) {
+     216           0 :       plumed_merror("There was some problem in parsing the derivative of the function "+bf_str[i]+" given in FUNC"+is + " with lepton");
+     217           0 :     }
+     218             : 
+     219             :     try {
+     220          46 :       bf_values_lepton_ref_[i] = &bf_values_expressions_[i].getVariableReference(variable_str_);
+     221           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     222             : 
+     223             :     try {
+     224          46 :       bf_derivs_lepton_ref_[i] = &bf_derivs_expressions_[i].getVariableReference(variable_str_);
+     225           8 :     } catch(PLMD::lepton::Exception& exc) {}
+     226             : 
+     227          46 :   }
+     228             : 
+     229             :   std::string transf_value_parsed;
+     230             :   std::string transf_deriv_parsed;
+     231             :   std::string transf_str;
+     232          20 :   parse("TRANSFORM",transf_str);
+     233          10 :   if(transf_str.size()>0) {
+     234           6 :     do_transf_ = true;
+     235          12 :     addKeywordToList("TRANSFORM",transf_str);
+     236             :     for(unsigned int k=0;; k++) {
+     237          14 :       if(transf_str.find("min")!=std::string::npos) {transf_str.replace(transf_str.find("min"), std::string("min").length(),intervalMinStr());}
+     238             :       else {break;}
+     239             :     }
+     240             :     for(unsigned int k=0;; k++) {
+     241          14 :       if(transf_str.find("max")!=std::string::npos) {transf_str.replace(transf_str.find("max"), std::string("max").length(),intervalMaxStr());}
+     242             :       else {break;}
+     243             :     }
+     244             : 
+     245             :     try {
+     246           6 :       lepton::ParsedExpression pe_value = lepton::Parser::parse(transf_str).optimize(lepton::Constants());;
+     247           6 :       std::ostringstream tmp_stream; tmp_stream << pe_value;
+     248           6 :       transf_value_parsed = tmp_stream.str();
+     249           6 :       transf_value_expression_ = pe_value.createCompiledExpression();
+     250           6 :     }
+     251           0 :     catch(PLMD::lepton::Exception& exc) {
+     252           0 :       plumed_merror("There was some problem in parsing the function "+transf_str+" given in TRANSFORM with lepton");
+     253           0 :     }
+     254             : 
+     255             :     std::vector<std::string> var_str;
+     256          12 :     for(auto &p: transf_value_expression_.getVariables()) {
+     257           6 :       var_str.push_back(p);
+     258             :     }
+     259           6 :     if(var_str.size()!=1) {
+     260           0 :       plumed_merror("Problem with function "+transf_str+" given in TRANSFORM: there should only be one variable");
+     261             :     }
+     262           6 :     if(var_str[0]!=transf_variable_str_) {
+     263           0 :       plumed_merror("Problem with function "+transf_str+" given in TRANSFORM: you should use "+transf_variable_str_+" as a variable");
+     264             :     }
+     265             : 
+     266             :     try {
+     267          12 :       lepton::ParsedExpression pe_deriv = lepton::Parser::parse(transf_str).differentiate(transf_variable_str_).optimize(lepton::Constants());;
+     268           6 :       std::ostringstream tmp_stream2; tmp_stream2 << pe_deriv;
+     269           6 :       transf_deriv_parsed = tmp_stream2.str();
+     270           6 :       transf_deriv_expression_ = pe_deriv.createCompiledExpression();
+     271           6 :     }
+     272           0 :     catch(PLMD::lepton::Exception& exc) {
+     273           0 :       plumed_merror("There was some problem in parsing the derivative of the function "+transf_str+" given in TRANSFORM with lepton");
+     274           0 :     }
+     275             : 
+     276             :     try {
+     277           6 :       transf_value_lepton_ref_ = &transf_value_expression_.getVariableReference(transf_variable_str_);
+     278           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     279             : 
+     280             :     try {
+     281           6 :       transf_deriv_lepton_ref_ = &transf_deriv_expression_.getVariableReference(transf_variable_str_);
+     282           3 :     } catch(PLMD::lepton::Exception& exc) {}
+     283             : 
+     284           6 :   }
+     285             :   //
+     286          10 :   log.printf("  Using the following functions [lepton parsed function and derivative]:\n");
+     287          66 :   for(unsigned int i=0; i<getNumberOfBasisFunctions(); i++) {
+     288          56 :     log.printf("   %u:  %s   [   %s   |   %s   ] \n",i,bf_str[i].c_str(),bf_values_parsed[i].c_str(),bf_derivs_parsed[i].c_str());
+     289             : 
+     290             :   }
+     291             :   //
+     292          10 :   if(do_transf_) {
+     293           6 :     log.printf("  Arguments are transformed using the following function [lepton parsed function and derivative]:\n");
+     294           6 :     log.printf("   %s   [   %s   |   %s   ] \n",transf_str.c_str(),transf_value_parsed.c_str(),transf_deriv_parsed.c_str());
+     295             :   }
+     296             :   else {
+     297           4 :     log.printf("  Arguments are not transformed\n");
+     298             :   }
+     299             :   //
+     300             : 
+     301          20 :   parseFlag("CHECK_NAN_INF",check_nan_inf_); addKeywordToList("CHECK_NAN_INF",check_nan_inf_);
+     302          10 :   if(check_nan_inf_) {
+     303           6 :     log.printf("  The code will check that values given are numercially stable, e.g. do not result in a not a number (nan) or infinity (inf).\n");
+     304             :   }
+     305             :   else {
+     306           4 :     log.printf("  The code will NOT check that values given are numercially stable, e.g. do not result in a not a number (nan) or infinity (inf).\n");
+     307             :   }
+     308             : 
+     309          10 :   setupBF();
+     310          10 :   checkRead();
+     311          20 : }
+     312             : 
+     313             : 
+     314       24204 : void BF_Custom::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     315       24204 :   inside_range=true;
+     316       24204 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     317       24204 :   double transf_derivf=1.0;
+     318             :   //
+     319       24204 :   if(do_transf_) {
+     320             : 
+     321       14062 :     if(transf_value_lepton_ref_) {*transf_value_lepton_ref_ = argT;}
+     322       14062 :     if(transf_deriv_lepton_ref_) {*transf_deriv_lepton_ref_ = argT;}
+     323             : 
+     324       14062 :     argT = transf_value_expression_.evaluate();
+     325       14062 :     transf_derivf = transf_deriv_expression_.evaluate();
+     326             : 
+     327       14062 :     if(check_nan_inf_ && (std::isnan(argT) || std::isinf(argT)) ) {
+     328           0 :       std::string vs; Tools::convert(argT,vs);
+     329           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with the transform function, it gives " + vs);
+     330             :     }
+     331             : 
+     332       14062 :     if(check_nan_inf_ && (std::isnan(transf_derivf) || std::isinf(transf_derivf)) ) {
+     333           0 :       std::string vs; Tools::convert(transf_derivf,vs);
+     334           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with the transform function, its derivative gives " + vs);
+     335             :     }
+     336             :   }
+     337             :   //
+     338       24204 :   values[0]=1.0;
+     339       24204 :   derivs[0]=0.0;
+     340      137488 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     341             : 
+     342      113284 :     if(bf_values_lepton_ref_[i]) {*bf_values_lepton_ref_[i] = argT;}
+     343      113284 :     if(bf_derivs_lepton_ref_[i]) {*bf_derivs_lepton_ref_[i] = argT;}
+     344             : 
+     345      113284 :     values[i] = bf_values_expressions_[i].evaluate();
+     346      113284 :     derivs[i] = bf_derivs_expressions_[i].evaluate();
+     347             : 
+     348      113284 :     if(do_transf_) {derivs[i]*=transf_derivf;}
+     349             :     // NaN checks
+     350      113284 :     if(check_nan_inf_ && (std::isnan(values[i]) || std::isinf(values[i])) ) {
+     351           0 :       std::string vs; Tools::convert(values[i],vs);
+     352           0 :       std::string is; Tools::convert(i,is);
+     353           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with the basis function given in FUNC"+is+", it gives "+vs);
+     354             :     }
+     355             :     //
+     356      113284 :     if(check_nan_inf_ && (std::isnan(derivs[i])|| std::isinf(derivs[i])) ) {
+     357             :       std::string vs; Tools::convert(derivs[i],vs);
+     358           0 :       std::string is; Tools::convert(i,is);
+     359           0 :       plumed_merror(getName()+" with label "+getLabel()+": problem with derivative of the basis function given in FUNC"+is+", it gives "+vs);
+     360             :     }
+     361             :   }
+     362       26218 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     363       24204 : }
+     364             : 
+     365             : 
+     366             : 
+     367             : 
+     368             : }
+     369             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Fourier.cpp.func-sort-c.html b/coverage/ves/BF_Fourier.cpp.func-sort-c.html new file mode 100644 index 000000000000..0d422657a026 --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Fourier.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Fourier.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10BF_Fourier21setupUniformIntegralsEv94
_ZN4PLMD3ves10BF_Fourier11setupLabelsEv95
_ZN4PLMD3ves10BF_FourierC2ERKNS_13ActionOptionsE95
_ZN4PLMD3ves10BF_Fourier16registerKeywordsERNS_8KeywordsE97
_ZNK4PLMD3ves10BF_Fourier12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3244265
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Fourier.cpp.func.html b/coverage/ves/BF_Fourier.cpp.func.html new file mode 100644 index 000000000000..2eadc0baa50c --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Fourier.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Fourier.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10BF_Fourier11setupLabelsEv95
_ZN4PLMD3ves10BF_Fourier16registerKeywordsERNS_8KeywordsE97
_ZN4PLMD3ves10BF_Fourier21setupUniformIntegralsEv94
_ZN4PLMD3ves10BF_FourierC2ERKNS_13ActionOptionsE95
_ZNK4PLMD3ves10BF_Fourier12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_3244265
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Fourier.cpp.gcov.html b/coverage/ves/BF_Fourier.cpp.gcov.html new file mode 100644 index 000000000000..3e0b57880dfa --- /dev/null +++ b/coverage/ves/BF_Fourier.cpp.gcov.html @@ -0,0 +1,233 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Fourier.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Fourier.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_FOURIER
+      32             : /*
+      33             : Fourier basis functions.
+      34             : 
+      35             : Use as basis functions Fourier series defined on a periodic interval.
+      36             : You need to provide the periodic interval \f$[a,b]\f$
+      37             : on which the basis functions are to be used, and the order of the
+      38             : expansion \f$N\f$ (i.e. the highest Fourier mode used).
+      39             : The total number of basis functions is \f$2N+1\f$ as for each Fourier
+      40             : mode there is both the cosine and sine term,
+      41             : and the constant \f$f_{0}(x)=1\f$ is also included.
+      42             : These basis functions should only be used for periodic CVs.
+      43             : 
+      44             : The Fourier series basis functions are given by
+      45             : \f{align}{
+      46             : f_{0}(x)    &= 1 \\
+      47             : f_{1}(x)    &= cos(\frac{2\pi }{P} x) \\
+      48             : f_{2}(x)    &= sin(\frac{2\pi }{P} x) \\
+      49             : f_{3}(x)    &= cos(2 \cdot \frac{2\pi}{P} x) \\
+      50             : f_{4}(x)    &= sin(2 \cdot \frac{2\pi}{P} x) \\
+      51             : & \vdots \\
+      52             : f_{2k-1}(x) &= cos(k \cdot \frac{2\pi}{P} x) \\
+      53             : f_{2k}(x)   &= sin(k \cdot \frac{2\pi}{P} x) \\
+      54             : & \vdots \\
+      55             : f_{2N-1}(x) &= cos(N \cdot \frac{2\pi}{P} x) \\
+      56             : f_{2N}(x)   &= sin(N \cdot \frac{2\pi}{P} x) \\
+      57             : \f}
+      58             : where \f$P=(b-a)\f$ is the periodicity of the interval.
+      59             : They are orthogonal over the interval \f$[a,b]\f$
+      60             : \f[
+      61             : \int_{a}^{b} dx \, f_{n}(x)\, f_{m}(x)  =
+      62             : \begin{cases}
+      63             : 0 & n \neq m \\
+      64             : (b-a) & n = m = 0 \\
+      65             : (b-a)/2 & n = m \neq 0
+      66             : \end{cases}.
+      67             : \f]
+      68             : 
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : Here we employ a Fourier expansion of order 10 over the periodic interval
+      73             : \f$-\pi\f$ to \f$+\pi\f$.
+      74             : This results in a total number of 21 basis functions.
+      75             : The label used to identify  the basis function action can then be
+      76             : referenced later on in the input file.
+      77             : \plumedfile
+      78             : BF_FOURIER MINIMUM=-pi MAXIMUM=+pi ORDER=10 LABEL=bf_fourier
+      79             : \endplumedfile
+      80             : 
+      81             : 
+      82             : */
+      83             : //+ENDPLUMEDOC
+      84             : 
+      85             : class BF_Fourier : public BasisFunctions {
+      86             :   void setupLabels() override;
+      87             :   void setupUniformIntegrals() override;
+      88             : public:
+      89             :   static void registerKeywords(Keywords&);
+      90             :   explicit BF_Fourier(const ActionOptions&);
+      91             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      92             : };
+      93             : 
+      94             : 
+      95             : PLUMED_REGISTER_ACTION(BF_Fourier,"BF_FOURIER")
+      96             : 
+      97             : 
+      98          97 : void BF_Fourier::registerKeywords(Keywords& keys) {
+      99          97 :   BasisFunctions::registerKeywords(keys);
+     100          97 : }
+     101             : 
+     102             : 
+     103          95 : BF_Fourier::BF_Fourier(const ActionOptions&ao):
+     104          95 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     105             : {
+     106          95 :   setNumberOfBasisFunctions(2*getOrder()+1);
+     107         190 :   setIntrinsicInterval("-pi","+pi");
+     108             :   setPeriodic();
+     109             :   setIntervalBounded();
+     110          95 :   setType("trigonometric_cos-sin");
+     111          95 :   setDescription("Trigonometric (cos/sin)");
+     112          95 :   setupBF();
+     113          95 :   checkRead();
+     114          95 : }
+     115             : 
+     116             : 
+     117     3244265 : void BF_Fourier::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     118             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     119             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     120     3244265 :   inside_range=true;
+     121     3244265 :   argT=translateArgument(arg, inside_range);
+     122     3244265 :   values[0]=1.0;
+     123     3244265 :   derivs[0]=0.0;
+     124    17806383 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     125    14562118 :     double io = i;
+     126    14562118 :     double cos_tmp = cos(io*argT);
+     127    14562118 :     double sin_tmp = sin(io*argT);
+     128    14562118 :     values[2*i-1] = cos_tmp;
+     129    14562118 :     derivs[2*i-1] = -io*sin_tmp*intervalDerivf();
+     130    14562118 :     values[2*i] = sin_tmp;
+     131    14562118 :     derivs[2*i] = io*cos_tmp*intervalDerivf();
+     132             :   }
+     133     3244265 :   if(!inside_range) {
+     134       23980 :     for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}
+     135             :   }
+     136     3244265 : }
+     137             : 
+     138             : 
+     139          95 : void BF_Fourier::setupLabels() {
+     140          95 :   setLabel(0,"1");
+     141         568 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     142         473 :     std::string is; Tools::convert(i,is);
+     143         946 :     setLabel(2*i-1,"cos("+is+"*s)");
+     144         946 :     setLabel(2*i,"sin("+is+"*s)");
+     145             :   }
+     146          95 : }
+     147             : 
+     148             : 
+     149          94 : void BF_Fourier::setupUniformIntegrals() {
+     150          94 :   setAllUniformIntegralsToZero();
+     151             :   setUniformIntegral(0,1.0);
+     152          94 : }
+     153             : 
+     154             : 
+     155             : }
+     156             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Gaussians.cpp.func-sort-c.html b/coverage/ves/BF_Gaussians.cpp.func-sort-c.html new file mode 100644 index 000000000000..51c0154b13d8 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Gaussians.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Gaussians.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5252100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Gaussians11setupLabelsEv3
_ZN4PLMD3ves12BF_GaussiansC2ERKNS_13ActionOptionsE3
_ZN4PLMD3ves12BF_Gaussians16registerKeywordsERNS_8KeywordsE5
_ZNK4PLMD3ves12BF_Gaussians12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Gaussians.cpp.func.html b/coverage/ves/BF_Gaussians.cpp.func.html new file mode 100644 index 000000000000..64fc14b63cb8 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Gaussians.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Gaussians.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5252100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12BF_Gaussians11setupLabelsEv3
_ZN4PLMD3ves12BF_Gaussians16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves12BF_GaussiansC2ERKNS_13ActionOptionsE3
_ZNK4PLMD3ves12BF_Gaussians12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9236
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Gaussians.cpp.gcov.html b/coverage/ves/BF_Gaussians.cpp.gcov.html new file mode 100644 index 000000000000..047db82c7832 --- /dev/null +++ b/coverage/ves/BF_Gaussians.cpp.gcov.html @@ -0,0 +1,266 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Gaussians.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Gaussians.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:5252100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : #include "core/PlumedMain.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_GAUSSIANS
+      32             : /*
+      33             : Gaussian basis functions.
+      34             : 
+      35             : \attention
+      36             : __These basis functions do not form orthogonal bases. We recommend using wavelets (\ref BF_WAVELETS) instead that do form orthogonal bases__.
+      37             : 
+      38             : Basis functions given by Gaussian distributions with shifted centers defined on a
+      39             : bounded interval. See \cite ValssonPampel_Wavelets_2022 for full details.
+      40             : 
+      41             : You need to provide the interval \f$[a,b]\f$ on which the bias is to be
+      42             : expanded.
+      43             : The ORDER keyword of the basis set \f$N\f$ determines the number of equally sized
+      44             : sub-intervalls to be used.
+      45             : On the borders of each of these sub-intervalls the mean \f$\mu\f$ of a Gaussian
+      46             : basis function is placed:
+      47             : \f{align}{
+      48             :   \mu_i = a + (i-1) \frac{b-a}{N}
+      49             : \f}
+      50             : 
+      51             : The total number of basis functions is \f$N+4\f$ as the constant
+      52             : \f$f_{0}(x)=1\f$, as well as two additional Gaussians at the Boundaries are also included.
+      53             : 
+      54             : The basis functions are given by
+      55             : \f{align}{
+      56             :   f_0(x) &= 1 \\
+      57             :   f_i(x) &= \exp\left(-\frac{{\left(x-\mu_i\right)}^2}{2\sigma^2}\right)
+      58             : \f}
+      59             : 
+      60             : When the Gaussians are used for a periodic CV (with the PERIODIC keyword),
+      61             : the sub-intervals are chosen in the same way, but only \f$N+1\f$ functions
+      62             : are required to fill it (the ones at the boundary coincide and the ones outside
+      63             : can be omitted).
+      64             : 
+      65             : It is possible to specify the width \f$\sigma\f$ (i.e. the standard deviation)
+      66             : of the Gaussians using the WIDTH keyword.
+      67             : By default it is set to the sub-intervall length.
+      68             : It was found that performance can be typically improved with a smaller value (around 75 % of the sub-interval length), although a too small overlap will prevent the basis set from working correctly at all.
+      69             : 
+      70             : The optimization procedure then adjusts the heigths of the individual Gaussians.
+      71             : To avoid 'blind' optimization of the basis functions outside the currently sampled area, it is often beneficial to use the OPTIMIZATION_THRESHOLD keyword of the VES_LINEAR_EXPANSION (set it to a small value, e.g. 1e-6)
+      72             : 
+      73             : As an example two adjacent basis functions (with the mentioned width choice of 75% of the sub-interval length) can be seen below.
+      74             : The full basis consists of shifted Gaussians in the full specified interval.
+      75             : 
+      76             : \image html ves_basisf-gaussians.png
+      77             : 
+      78             : 
+      79             : \par Examples
+      80             : 
+      81             : The bias is expanded with Gaussian functions in the intervall from 0.0 to
+      82             : 10.0 using order 20.
+      83             : This results in 24 basis functions.
+      84             : 
+      85             : \plumedfile
+      86             : bfG: BF_GAUSSIANS MINIMUM=0.0 MAXIMUM=10.0 ORDER=20
+      87             : \endplumedfile
+      88             : 
+      89             : Because it was not specified, the width of the Gaussians is by default
+      90             : set to the sub-intervall length, i.e.\ \f$\sigma=0.5\f$.
+      91             : To e.g. enhance the overlap between neighbouring basis functions, it can be
+      92             : specified explicitely:
+      93             : 
+      94             : \plumedfile
+      95             : bfG: BF_GAUSSIANS MINIMUM=0.0 MAXIMUM=10.0 ORDER=20 WIDTH=0.7
+      96             : \endplumedfile
+      97             : 
+      98             : */
+      99             : //+ENDPLUMEDOC
+     100             : 
+     101             : class BF_Gaussians : public BasisFunctions {
+     102             :   /// one over width of the Gaussians
+     103             :   double inv_sigma_;
+     104             :   /// positions of the centers
+     105             :   std::vector<double> centers_;
+     106             :   void setupLabels() override;
+     107             : public:
+     108             :   static void registerKeywords( Keywords&);
+     109             :   explicit BF_Gaussians(const ActionOptions&);
+     110             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+     111             : };
+     112             : 
+     113             : 
+     114             : PLUMED_REGISTER_ACTION(BF_Gaussians,"BF_GAUSSIANS")
+     115             : 
+     116             : 
+     117           5 : void BF_Gaussians::registerKeywords(Keywords& keys) {
+     118           5 :   BasisFunctions::registerKeywords(keys);
+     119          10 :   keys.add("optional","WIDTH","The width (i.e. standart deviation) of the Gaussian functions. By default it is equal to the sub-intervall size.");
+     120          10 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     121           5 :   keys.remove("NUMERICAL_INTEGRALS");
+     122           5 : }
+     123             : 
+     124           3 : BF_Gaussians::BF_Gaussians(const ActionOptions&ao):
+     125           3 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     126             : {
+     127           3 :   log.printf("  Gaussian basis functions, see and cite ");
+     128           6 :   log << plumed.cite("Pampel and Valsson, J. Chem. Theory Comput. 18, 4127-4141 (2022) - DOI:10.1021/acs.jctc.2c00197");
+     129             : 
+     130           3 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     131             : 
+     132           3 :   double width = (intervalMax()-intervalMin()) / getOrder();
+     133           3 :   parse("WIDTH",width);
+     134           3 :   if(width <= 0.0) {plumed_merror("WIDTH should be larger than 0");}
+     135           4 :   if(width != (intervalMax()-intervalMin())/getOrder()) {addKeywordToList("WIDTH",width);}
+     136           3 :   inv_sigma_ = 1/(width);
+     137             : 
+     138           3 :   bool periodic = false;
+     139           3 :   parseFlag("PERIODIC",periodic);
+     140           4 :   if (periodic) {addKeywordToList("PERIODIC",periodic);}
+     141             : 
+     142             :   // 1 constant, getOrder() on interval, 1 (left) + 2 (right) at boundaries if not periodic
+     143           3 :   unsigned int num_BFs = periodic ? getOrder()+1U : getOrder()+4U;
+     144           3 :   setNumberOfBasisFunctions(num_BFs);
+     145             : 
+     146           3 :   centers_.push_back(0.0); // constant one
+     147          69 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     148          66 :     centers_.push_back(intervalMin()+(static_cast<int>(i) - 1 - static_cast<int>(!periodic))*(intervalMax()-intervalMin())/getOrder());
+     149             :   }
+     150           3 :   periodic ? setPeriodic() : setNonPeriodic();
+     151             :   setIntervalBounded();
+     152           3 :   setType("gaussian_functions");
+     153           3 :   setDescription("Gaussian functions with shifted centers that are being optimized in their height");
+     154           3 :   setupBF();
+     155           3 :   log.printf("   width: %f\n",width);
+     156           3 :   checkRead();
+     157           3 : }
+     158             : 
+     159             : 
+     160        9236 : void BF_Gaussians::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     161        9236 :   inside_range=true;
+     162        9236 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     163        9236 :   values[0]=1.0;
+     164        9236 :   derivs[0]=0.0;
+     165      212043 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     166      202807 :     double dist = argT - centers_[i];
+     167      202807 :     if(arePeriodic()) { // wrap around similar to MetaD
+     168       64140 :       dist /= intervalRange();
+     169       64140 :       dist = Tools::pbc(dist);
+     170       64140 :       dist *= intervalRange();
+     171             :     }
+     172      202807 :     values[i] = exp(-0.5*pow(dist*inv_sigma_,2.0));
+     173      202807 :     derivs[i] = -values[i] * (dist)*pow(inv_sigma_,2.0);
+     174             :   }
+     175       11156 :   if(!inside_range) {for (auto& d: derivs) {d=0.0;}}
+     176        9236 : }
+     177             : 
+     178             : 
+     179             : // label according to position of mean
+     180           3 : void BF_Gaussians::setupLabels() {
+     181           3 :   setLabel(0,"const");
+     182          69 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     183          66 :     std::string is; Tools::convert(centers_[i],is);
+     184         132 :     setLabel(i,"m="+is);
+     185             :   }
+     186           3 : }
+     187             : 
+     188             : }
+     189             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Legendre.cpp.func-sort-c.html b/coverage/ves/BF_Legendre.cpp.func-sort-c.html new file mode 100644 index 000000000000..86a135638706 --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Legendre.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Legendre.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Legendre21setupUniformIntegralsEv59
_ZN4PLMD3ves11BF_LegendreC2ERKNS_13ActionOptionsE61
_ZN4PLMD3ves11BF_Legendre16registerKeywordsERNS_8KeywordsE63
_ZNK4PLMD3ves11BF_Legendre12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_1625057
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Legendre.cpp.func.html b/coverage/ves/BF_Legendre.cpp.func.html new file mode 100644 index 000000000000..cffa42c00e00 --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Legendre.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Legendre.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Legendre16registerKeywordsERNS_8KeywordsE63
_ZN4PLMD3ves11BF_Legendre21setupUniformIntegralsEv59
_ZN4PLMD3ves11BF_LegendreC2ERKNS_13ActionOptionsE61
_ZNK4PLMD3ves11BF_Legendre12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_1625057
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Legendre.cpp.gcov.html b/coverage/ves/BF_Legendre.cpp.gcov.html new file mode 100644 index 000000000000..a4def6dc3078 --- /dev/null +++ b/coverage/ves/BF_Legendre.cpp.gcov.html @@ -0,0 +1,249 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Legendre.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Legendre.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4242100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_LEGENDRE
+      32             : /*
+      33             : Legendre polynomials basis functions.
+      34             : 
+      35             : Use as basis functions [Legendre polynomials](https://en.wikipedia.org/wiki/Legendre_polynomials)
+      36             : \f$P_{n}(x)\f$ defined on a bounded interval.
+      37             : You need to provide the interval \f$[a,b]\f$
+      38             : on which the basis functions are to be used, and the order of the
+      39             : expansion \f$N\f$ (i.e. the highest order polynomial used).
+      40             : The total number of basis functions is \f$N+1\f$ as the constant \f$P_{0}(x)=1\f$
+      41             : is also included.
+      42             : These basis functions should not be used for periodic CVs.
+      43             : 
+      44             : Intrinsically the Legendre polynomials are defined on the interval \f$[-1,1]\f$.
+      45             : A variable \f$t\f$ in the interval \f$[a,b]\f$ is transformed to a variable \f$x\f$
+      46             : in the intrinsic interval \f$[-1,1]\f$ by using the transform function
+      47             : \f[
+      48             : x(t) = \frac{t-(a+b)/2}
+      49             : {(b-a)/2}
+      50             : \f]
+      51             : 
+      52             : The Legendre polynomials are given by the recurrence relation
+      53             : \f{align}{
+      54             : P_{0}(x)    &= 1 \\
+      55             : P_{1}(x)    &= x \\
+      56             : P_{n+1}(x)  &= \frac{2n+1}{n+1} \, x \, P_{n}(x) -  \frac{n}{n+1} \, P_{n-1}(x)
+      57             : \f}
+      58             : 
+      59             : The first 6 polynomials are shown below
+      60             : \image html ves_basisf-legendre.png
+      61             : 
+      62             : The Legendre polynomial are orthogonal over the interval \f$[-1,1]\f$
+      63             : \f[
+      64             : \int_{-1}^{1} dx \, P_{n}(x)\, P_{m}(x)  =  \frac{2}{2n+1} \delta_{n,m}
+      65             : \f]
+      66             : By using the SCALED keyword the polynomials are scaled by a factor of
+      67             : \f$ \sqrt{\frac{2n+1}{2}}\f$ such that they are orthonormal to 1.
+      68             : 
+      69             : 
+      70             : From the above equation it follows that integral of the basis functions
+      71             : over the uniform target distribution \f$p_{\mathrm{u}}(x)\f$ are given by
+      72             : \f[
+      73             : \int_{-1}^{1} dx \, P_{n}(x) p_{\mathrm{u}}(x) =  \delta_{n,0},
+      74             : \f]
+      75             : and thus always zero except for the constant \f$P_{0}(x)=1\f$.
+      76             : 
+      77             : 
+      78             : For further mathematical properties of the Legendre polynomials see for example
+      79             : the [Wikipedia page](https://en.wikipedia.org/wiki/Legendre_polynomials).
+      80             : 
+      81             : \par Examples
+      82             : 
+      83             : Here we employ a Legendre expansion of order 20 over the interval -4.0 to 8.0.
+      84             : This results in a total number of 21 basis functions.
+      85             : The label used to identify  the basis function action can then be
+      86             : referenced later on in the input file.
+      87             : \plumedfile
+      88             : bf_leg: BF_LEGENDRE MINIMUM=-4.0 MAXIMUM=8.0 ORDER=20
+      89             : \endplumedfile
+      90             : 
+      91             : \par Examples
+      92             : 
+      93             : */
+      94             : //+ENDPLUMEDOC
+      95             : 
+      96             : class BF_Legendre : public BasisFunctions {
+      97             :   bool scaled_;
+      98             :   void setupUniformIntegrals() override;
+      99             : public:
+     100             :   static void registerKeywords(Keywords&);
+     101             :   explicit BF_Legendre(const ActionOptions&);
+     102             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+     103             : };
+     104             : 
+     105             : 
+     106             : PLUMED_REGISTER_ACTION(BF_Legendre,"BF_LEGENDRE")
+     107             : 
+     108             : 
+     109          63 : void BF_Legendre::registerKeywords(Keywords& keys) {
+     110          63 :   BasisFunctions::registerKeywords(keys);
+     111         126 :   keys.addFlag("SCALED",false,"Scale the polynomials such that they are orthonormal to 1.");
+     112          63 : }
+     113             : 
+     114          61 : BF_Legendre::BF_Legendre(const ActionOptions&ao):
+     115             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+     116          61 :   scaled_(false)
+     117             : {
+     118         183 :   parseFlag("SCALED",scaled_); addKeywordToList("SCALED",scaled_);
+     119          61 :   setNumberOfBasisFunctions(getOrder()+1);
+     120         122 :   setIntrinsicInterval("-1.0","+1.0");
+     121             :   setNonPeriodic();
+     122             :   setIntervalBounded();
+     123          61 :   setType("Legendre");
+     124          61 :   setDescription("Legendre polynomials");
+     125          61 :   setLabelPrefix("L");
+     126          61 :   setupBF();
+     127          61 :   checkRead();
+     128          61 : }
+     129             : 
+     130             : 
+     131     1625057 : void BF_Legendre::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     132             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     133             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     134     1625057 :   inside_range=true;
+     135     1625057 :   argT=translateArgument(arg, inside_range);
+     136     1625057 :   std::vector<double> derivsT(derivs.size());
+     137             :   //
+     138     1625057 :   values[0]=1.0;
+     139     1625057 :   derivsT[0]=0.0;
+     140     1625057 :   derivs[0]=0.0;
+     141     1625057 :   values[1]=argT;
+     142     1625057 :   derivsT[1]=1.0;
+     143     1625057 :   derivs[1]=intervalDerivf();
+     144    15470320 :   for(unsigned int i=1; i < getOrder(); i++) {
+     145    13845263 :     double io = static_cast<double>(i);
+     146    13845263 :     values[i+1]  = ((2.0*io+1.0)/(io+1.0))*argT*values[i] - (io/(io+1.0))*values[i-1];
+     147    13845263 :     derivsT[i+1] = ((2.0*io+1.0)/(io+1.0))*(values[i]+argT*derivsT[i])-(io/(io+1.0))*derivsT[i-1];
+     148    13845263 :     derivs[i+1]  = intervalDerivf()*derivsT[i+1];
+     149             :   }
+     150     1625057 :   if(scaled_) {
+     151             :     // L0 is also scaled!
+     152     5088852 :     for(unsigned int i=0; i<values.size(); i++) {
+     153     4632062 :       double io = static_cast<double>(i);
+     154     4632062 :       double sf = sqrt(io+0.5);
+     155     4632062 :       values[i] *= sf;
+     156     4632062 :       derivs[i] *= sf;
+     157             :     }
+     158             :   }
+     159     1756541 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     160     1625057 : }
+     161             : 
+     162             : 
+     163          59 : void BF_Legendre::setupUniformIntegrals() {
+     164          59 :   setAllUniformIntegralsToZero();
+     165             :   double L0_int = 1.0;
+     166          59 :   if(scaled_) {L0_int = sqrt(0.5);}
+     167             :   setUniformIntegral(0,L0_int);
+     168          59 : }
+     169             : 
+     170             : 
+     171             : }
+     172             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Powers.cpp.func-sort-c.html b/coverage/ves/BF_Powers.cpp.func-sort-c.html new file mode 100644 index 000000000000..30512b04dd4d --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Powers.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Powers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_Powers11setupLabelsEv16
_ZN4PLMD3ves9BF_PowersC2ERKNS_13ActionOptionsE16
_ZN4PLMD3ves9BF_Powers16registerKeywordsERNS_8KeywordsE18
_ZNK4PLMD3ves9BF_Powers12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_842119
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Powers.cpp.func.html b/coverage/ves/BF_Powers.cpp.func.html new file mode 100644 index 000000000000..0c124d3ce7d0 --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Powers.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Powers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9BF_Powers11setupLabelsEv16
_ZN4PLMD3ves9BF_Powers16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD3ves9BF_PowersC2ERKNS_13ActionOptionsE16
_ZNK4PLMD3ves9BF_Powers12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_842119
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Powers.cpp.gcov.html b/coverage/ves/BF_Powers.cpp.gcov.html new file mode 100644 index 000000000000..455c7d4cec38 --- /dev/null +++ b/coverage/ves/BF_Powers.cpp.gcov.html @@ -0,0 +1,222 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Powers.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Powers.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_POWERS
+      32             : /*
+      33             : Polynomial power basis functions.
+      34             : 
+      35             : \attention
+      36             : __These basis functions should not be used in conventional biasing simulations__.
+      37             : Instead you should use orthogonal basis functions like Legendre or
+      38             : Chebyshev polynomials. They are only included for usage in \ref ves_md_linearexpansion
+      39             : and some special cases.
+      40             : 
+      41             : Basis functions given by polynomial powers defined on a bounded interval.
+      42             : You need to provide the interval \f$[a,b]\f$
+      43             : on which the basis functions are to be used, and the order of the
+      44             : expansion \f$N\f$ (i.e. the highest power used).
+      45             : The total number of basis functions is \f$N+1\f$ as the constant \f$f_{0}(x)=1\f$
+      46             : is also included.
+      47             : These basis functions should not be used for periodic CVs.
+      48             : 
+      49             : The basis functions are given by
+      50             : \f{align}{
+      51             : f_{0}(x)    &= 1 \\
+      52             : f_{1}(x)    &= x \\
+      53             : f_{2}(x)    &= x^2 \\
+      54             : & \vdots \\
+      55             : f_{n}(x)    &= x^n \\
+      56             : & \vdots \\
+      57             : f_{N}(x)    &= x^N \\
+      58             : \f}
+      59             : 
+      60             : Note that these basis functions are __not__ orthogonal. In fact the integral
+      61             : over the uniform target distribution blows up as the interval is increased.
+      62             : Therefore they should not be used in conventional biasing simulations.
+      63             : However, they can be useful for usage with \ref ves_md_linearexpansion.
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : Here we employ a polynomial power expansion of order 5
+      68             : over the interval -2.0 to 2.0.
+      69             : This results in a total number of 6 basis functions.
+      70             : The label used to identify  the basis function action can then be
+      71             : referenced later on in the input file.
+      72             : \plumedfile
+      73             : BF_POWERS MINIMUM=-2.0 MAXIMUM=2.0 ORDER=5 LABEL=bf_pow
+      74             : \endplumedfile
+      75             : 
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : class BF_Powers : public BasisFunctions {
+      81             :   double inv_normfactor_;
+      82             :   void setupLabels() override;
+      83             : public:
+      84             :   static void registerKeywords( Keywords&);
+      85             :   explicit BF_Powers(const ActionOptions&);
+      86             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      87             : };
+      88             : 
+      89             : 
+      90             : PLUMED_REGISTER_ACTION(BF_Powers,"BF_POWERS")
+      91             : 
+      92             : 
+      93          18 : void BF_Powers::registerKeywords(Keywords& keys) {
+      94          18 :   BasisFunctions::registerKeywords(keys);
+      95          36 :   keys.add("optional","NORMALIZATION","The normalization factor that is used to normalize the basis functions. By default it is 1.0.");
+      96          18 :   keys.remove("NUMERICAL_INTEGRALS");
+      97          18 : }
+      98             : 
+      99          16 : BF_Powers::BF_Powers(const ActionOptions&ao):
+     100          16 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     101             : {
+     102          16 :   setNumberOfBasisFunctions(getOrder()+1);
+     103          16 :   setIntrinsicInterval(intervalMin(),intervalMax());
+     104          16 :   double normfactor_=1.0;
+     105          16 :   parse("NORMALIZATION",normfactor_);
+     106          16 :   if(normfactor_!=1.0) {addKeywordToList("NORMALIZATION",normfactor_);}
+     107          16 :   inv_normfactor_=1.0/normfactor_;
+     108             :   setNonPeriodic();
+     109             :   setIntervalBounded();
+     110          16 :   setType("polynom_powers");
+     111          16 :   setDescription("Polynomial Powers");
+     112          16 :   setupBF();
+     113          16 :   log.printf("   normalization factor: %f\n",normfactor_);
+     114          16 :   checkRead();
+     115          16 : }
+     116             : 
+     117             : 
+     118      842119 : void BF_Powers::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     119      842119 :   inside_range=true;
+     120      842119 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     121             :   //
+     122      842119 :   values[0]=1.0;
+     123      842119 :   derivs[0]=0.0;
+     124             :   //
+     125     4210595 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     126             :     // double io = static_cast<double>(i);
+     127             :     // values[i] = pow(argT,io);
+     128             :     // derivs[i] = io*pow(argT,io-1.0);
+     129     3368476 :     values[i] = argT*values[i-1];
+     130     3368476 :     derivs[i]=values[i-1]+argT*derivs[i-1];
+     131             :   }
+     132      842599 :   if(!inside_range) {for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}}
+     133      842119 : }
+     134             : 
+     135             : 
+     136          16 : void BF_Powers::setupLabels() {
+     137          16 :   setLabel(0,"1");
+     138          80 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     139          64 :     std::string is; Tools::convert(i,is);
+     140         128 :     setLabel(i,"s^"+is);
+     141             :   }
+     142          16 : }
+     143             : 
+     144             : }
+     145             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Sine.cpp.func-sort-c.html b/coverage/ves/BF_Sine.cpp.func-sort-c.html new file mode 100644 index 000000000000..4bc10c2a266f --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Sine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Sine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7BF_Sine21setupUniformIntegralsEv3
_ZN4PLMD3ves7BF_Sine11setupLabelsEv4
_ZN4PLMD3ves7BF_SineC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves7BF_Sine16registerKeywordsERNS_8KeywordsE6
_ZNK4PLMD3ves7BF_Sine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Sine.cpp.func.html b/coverage/ves/BF_Sine.cpp.func.html new file mode 100644 index 000000000000..01bb9f5d2eae --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Sine.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Sine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7BF_Sine11setupLabelsEv4
_ZN4PLMD3ves7BF_Sine16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves7BF_Sine21setupUniformIntegralsEv3
_ZN4PLMD3ves7BF_SineC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves7BF_Sine12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_9229
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Sine.cpp.gcov.html b/coverage/ves/BF_Sine.cpp.gcov.html new file mode 100644 index 000000000000..fd5ee507a120 --- /dev/null +++ b/coverage/ves/BF_Sine.cpp.gcov.html @@ -0,0 +1,228 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Sine.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Sine.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3535100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_BASISF BF_SINE
+      32             : /*
+      33             : Fourier sine basis functions.
+      34             : 
+      35             : Use as basis functions Fourier sine series defined on a periodic interval.
+      36             : You need to provide the periodic interval \f$[a,b]\f$
+      37             : on which the basis functions are to be used, and the order of the
+      38             : expansion \f$N\f$ (i.e. the highest Fourier sine mode used).
+      39             : The total number of basis functions is \f$N+1\f$ as
+      40             : the constant \f$f_{0}(x)=1\f$ is also included.
+      41             : These basis functions should only be used for periodic CVs.
+      42             : They can be useful if the periodic function being expanded is an
+      43             : odd function, i.e. \f$F(-x)=-F(x)\f$.
+      44             : 
+      45             : The Fourier sine basis functions are given by
+      46             : \f{align}{
+      47             : f_{0}(x)    &= 1 \\
+      48             : f_{1}(x)    &= sin(\frac{2\pi }{P} x) \\
+      49             : f_{2}(x)    &= sin(2 \cdot \frac{2\pi}{P} x) \\
+      50             : f_{3}(x)    &= sin(3 \cdot \frac{2\pi}{P} x) \\
+      51             : & \vdots \\
+      52             : f_{n}(x) &= sin(n \cdot \frac{2\pi}{P} x) \\
+      53             : & \vdots \\
+      54             : f_{N}(x)   &= sin(N \cdot \frac{2\pi}{P} x) \\
+      55             : \f}
+      56             : where \f$P=(b-a)\f$ is the periodicity of the interval.
+      57             : They are orthogonal over the interval \f$[a,b]\f$
+      58             : \f[
+      59             : \int_{a}^{b} dx \, f_{n}(x)\, f_{m}(x)  =
+      60             : \begin{cases}
+      61             : 0 & n \neq m \\
+      62             : (b-a) & n = m = 0 \\
+      63             : (b-a)/2 & n = m \neq 0
+      64             : \end{cases}.
+      65             : \f]
+      66             : 
+      67             : \par Examples
+      68             : 
+      69             : Here we employ a Fourier sine expansion of order 10 over the periodic interval
+      70             : \f$-\pi\f$ to \f$+\pi\f$.
+      71             : This results in a total number of 11 basis functions.
+      72             : The label used to identify  the basis function action can then be
+      73             : referenced later on in the input file.
+      74             : \plumedfile
+      75             : BF_SINE MINIMUM=-pi MAXIMUM=+pi ORDER=10 LABEL=bfS
+      76             : \endplumedfile
+      77             : 
+      78             : \par Examples
+      79             : 
+      80             : */
+      81             : //+ENDPLUMEDOC
+      82             : 
+      83             : class BF_Sine : public BasisFunctions {
+      84             :   void setupLabels() override;
+      85             :   void setupUniformIntegrals() override;
+      86             : public:
+      87             :   static void registerKeywords(Keywords&);
+      88             :   explicit BF_Sine(const ActionOptions&);
+      89             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+      90             : };
+      91             : 
+      92             : 
+      93             : PLUMED_REGISTER_ACTION(BF_Sine,"BF_SINE")
+      94             : 
+      95             : 
+      96           6 : void BF_Sine::registerKeywords(Keywords& keys) {
+      97           6 :   BasisFunctions::registerKeywords(keys);
+      98           6 : }
+      99             : 
+     100             : 
+     101           4 : BF_Sine::BF_Sine(const ActionOptions&ao):
+     102           4 :   PLUMED_VES_BASISFUNCTIONS_INIT(ao)
+     103             : {
+     104           4 :   setNumberOfBasisFunctions(getOrder()+1);
+     105           8 :   setIntrinsicInterval("-pi","+pi");
+     106             :   setPeriodic();
+     107             :   setIntervalBounded();
+     108           4 :   setType("trigonometric_sin");
+     109           4 :   setDescription("Sine");
+     110           4 :   setupBF();
+     111           4 :   checkRead();
+     112           4 : }
+     113             : 
+     114             : 
+     115        9229 : void BF_Sine::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     116             :   // plumed_assert(values.size()==numberOfBasisFunctions());
+     117             :   // plumed_assert(derivs.size()==numberOfBasisFunctions());
+     118        9229 :   inside_range=true;
+     119        9229 :   argT=translateArgument(arg, inside_range);
+     120        9229 :   values[0]=1.0;
+     121        9229 :   derivs[0]=0.0;
+     122      101519 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     123       92290 :     double io = i;
+     124       92290 :     double cos_tmp = cos(io*argT);
+     125       92290 :     double sin_tmp = sin(io*argT);
+     126       92290 :     values[i] = sin_tmp;
+     127       92290 :     derivs[i] = io*cos_tmp*intervalDerivf();
+     128             :   }
+     129        9229 :   if(!inside_range) {
+     130         960 :     for(unsigned int i=0; i<derivs.size(); i++) {derivs[i]=0.0;}
+     131             :   }
+     132        9229 : }
+     133             : 
+     134             : 
+     135           4 : void BF_Sine::setupLabels() {
+     136           4 :   setLabel(0,"1");
+     137          44 :   for(unsigned int i=1; i < getOrder()+1; i++) {
+     138          40 :     std::string is; Tools::convert(i,is);
+     139          80 :     setLabel(i,"sin("+is+"*s)");
+     140             :   }
+     141           4 : }
+     142             : 
+     143             : 
+     144           3 : void BF_Sine::setupUniformIntegrals() {
+     145           3 :   setAllUniformIntegralsToZero();
+     146             :   setUniformIntegral(0,1.0);
+     147           3 : }
+     148             : 
+     149             : 
+     150             : }
+     151             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Wavelets.cpp.func-sort-c.html b/coverage/ves/BF_Wavelets.cpp.func-sort-c.html new file mode 100644 index 000000000000..2cdba2106fb8 --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Wavelets.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Wavelets.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:118118100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Wavelets15getCutoffPointsERKd2
_ZN4PLMD3ves11BF_Wavelets11setupLabelsEv47
_ZN4PLMD3ves11BF_WaveletsC2ERKNS_13ActionOptionsE47
_ZN4PLMD3ves11BF_Wavelets16registerKeywordsERNS_8KeywordsE49
_ZNK4PLMD3ves11BF_Wavelets12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_62249
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Wavelets.cpp.func.html b/coverage/ves/BF_Wavelets.cpp.func.html new file mode 100644 index 000000000000..e0633a82f234 --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Wavelets.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Wavelets.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:118118100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11BF_Wavelets11setupLabelsEv47
_ZN4PLMD3ves11BF_Wavelets15getCutoffPointsERKd2
_ZN4PLMD3ves11BF_Wavelets16registerKeywordsERNS_8KeywordsE49
_ZN4PLMD3ves11BF_WaveletsC2ERKNS_13ActionOptionsE47
_ZNK4PLMD3ves11BF_Wavelets12getAllValuesEdRdRbRSt6vectorIdSaIdEES7_62249
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BF_Wavelets.cpp.gcov.html b/coverage/ves/BF_Wavelets.cpp.gcov.html new file mode 100644 index 000000000000..4f03abf2bfac --- /dev/null +++ b/coverage/ves/BF_Wavelets.cpp.gcov.html @@ -0,0 +1,495 @@ + + + + + + + + LCOV - plumed test coverage - ves/BF_Wavelets.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BF_Wavelets.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:118118100.0 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : 
+      24             : #include "BasisFunctions.h"
+      25             : #include "GridLinearInterpolation.h"
+      26             : #include "tools/Grid.h"
+      27             : #include "VesTools.h"
+      28             : #include "WaveletGrid.h"
+      29             : #include "core/ActionRegister.h"
+      30             : #include "tools/Exception.h"
+      31             : #include "core/PlumedMain.h"
+      32             : 
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace ves {
+      36             : 
+      37             : 
+      38             : //+PLUMEDOC VES_BASISF BF_WAVELETS
+      39             : /*
+      40             : Daubechies Wavelets basis functions.
+      41             : 
+      42             : Note: at the moment only bases with a single level of scaling functions are usable, as multiscale optimization is not yet implemented.
+      43             : 
+      44             : This basis set uses Daubechies Wavelets \cite daubechies_ten_1992 to construct a complete and orthogonal basis. See \cite ValssonPampel_Wavelets_2022 for full details.
+      45             : 
+      46             : The basis set is based on using a pair of functions, the scaling function (or father wavelet) \f$\phi\f$ and the wavelet function (or mother wavelet) \f$\psi\f$.
+      47             : They are defined via the two-scale relations for scale \f$j\f$ and shift \f$k\f$:
+      48             : 
+      49             : \f{align*}{
+      50             :   \phi_k^j \left(x\right) = 2^{-j/2} \phi \left( 2^{-j} x - k\right)\\
+      51             :   \psi_k^j \left(x\right) = 2^{-j/2} \psi \left( 2^{-j} x - k\right)
+      52             : \f}
+      53             : 
+      54             : The exact properties are set by choosing filter coefficients, e.g. choosing \f$h_k\f$ for the father wavelet:
+      55             : 
+      56             : \f[
+      57             :   \phi\left(x\right) = \sqrt{2} \sum_k h_k\, \phi \left( 2 x - k\right)
+      58             : \f]
+      59             : 
+      60             : The filter coefficients by Daubechies result in an orthonormal basis of all integer shifted functions:
+      61             : \f[
+      62             :   \int \phi(x+i) \phi(x+j) \mathop{}\!\mathrm{d}x = \delta_{ij} \quad \text{for} \quad i,j \in \mathbb{Z}
+      63             : \f]
+      64             : 
+      65             : Because no analytic formula for these wavelets exist, they are instead constructed iteratively on a grid.
+      66             : The method of construction is close to the "Vector cascade algorithm" described in \cite strang_wavelets_1997 .
+      67             : The needed filter coefficients of the scaling function are hardcoded, and were previously generated via a python script.
+      68             : Currently the "maximum phase" type (Db) and the "least asymmetric" (Sym) type are implemented.
+      69             : We recommend to use Symlets.
+      70             : 
+      71             : As an example two adjacent basis functions of both Sym8 (ORDER=8, TYPE=SYMLET) and Db8 (ORDER=8, TYPE=DAUBECHIES) is shown in the figure.
+      72             : The full basis consists of shifted wavelets in the full specified interval.
+      73             : 
+      74             : \image html ves_basisf-wavelets.png
+      75             : 
+      76             : 
+      77             : \par Specify the wavelet type
+      78             : 
+      79             : The TYPE keyword sets the type of Wavelet, at the moment "DAUBECHIES" and "SYMLETS" are available.
+      80             : The specified ORDER of the basis corresponds to the number of vanishing moments of the wavelet, i.e. if TYPE was specified as "DAUBECHIES" an order of 8 results in Db8 wavelets.
+      81             : 
+      82             : 
+      83             : \par Specify the number of functions
+      84             : 
+      85             : The resulting basis set consists of integer shifts of the wavelet with some scaling \f$j\f$,
+      86             : \f[
+      87             :   V(x) = \sum_i \alpha_i * \phi_i (x) = \sum_i \alpha_i * \phi(\frac{x+i}{j})
+      88             : \f]
+      89             : with the variational parameters \f$ \alpha \f$.
+      90             : Additionally a constant basis function is included.
+      91             : 
+      92             : There are two different ways to specify the number of used basis functions implemented.
+      93             : You can either specify the scale or alternatively a fixed number of basis function.
+      94             : 
+      95             : Coming from the multiresolution aspect of wavelets, you can set the scale of the father wavelets, i.e. the largest scale used for approximation.
+      96             : This can be done with the FUNCTION_LENGTH keyword.
+      97             : It should be given in the same units as the used CV and specifies the length (of the domain interval) of the individual father wavelet functions.
+      98             : 
+      99             : Alternatively a fixed number of basis functions for the bias expansion can be specified with the NUM_BF keyword, which will set the scale automatically to match the desired number of functions.
+     100             : Note that this also includes the constant function.
+     101             : 
+     102             : If you do not specify anything, it is assumed that the range of the bias should match the scale of the wavelet functions.
+     103             : More precise, the basis functions are scaled to match the specified size of the CV space (MINIMUM and MAXIMUM keywords).
+     104             : This has so far been a good initial choice.
+     105             : 
+     106             : If the wavelets are scaled to match the CV range exactly there would be \f$4*\text{ORDER} -3\f$ basis functions whose domain is at least partially in this region.
+     107             : This number is adjusted if FUNCTION_LENGTH or NUM_BF is specified.
+     108             : Additionally, some of the shifted basis functions will not have significant contributions because of their function values being close to zero over the full range of the bias.
+     109             : These 'tail wavelets' can be omitted by using the TAILS_THRESHOLD keyword.
+     110             : This omits all shifted functions that have only function values smaller than a fraction of their maximum value inside the bias range.
+     111             : Using a value of e.g. 0.01 will already reduce the number of basis functions significantly.
+     112             : The default setting will not omit any tail wavelets (i.e. TAILS_THRESHOLD=0).
+     113             : 
+     114             : The number of basis functions is then not easily determinable a priori but will be given in the logfile.
+     115             : Additionally the starting point (leftmost defined point) of the individual basis functions is printed.
+     116             : 
+     117             : 
+     118             : With the PERIODIC keyword the basis set can also be used to bias periodic CVs.
+     119             : Then the shift between the functions will be chosen such that the function at the left border and right border coincide.
+     120             : If the FUNCTION_LENGTH keyword is used together with PERIODIC, a smaller length might be chosen to satisfy this requirement.
+     121             : 
+     122             : 
+     123             : \par Grid
+     124             : 
+     125             : The values of the wavelet function are generated on a grid.
+     126             : Using the cascade algorithm results in doubling the grid values for each iteration.
+     127             : This means that the grid size will always be a power of two multiplied by the number of coefficients (\f$ 2*\text{ORDER} -1\f$) for the specified wavelet.
+     128             : Using the MIN_GRID_SIZE keyword a lower bound for the number of grid points can be specified.
+     129             : By default at least 1,000 grid points are used.
+     130             : Function values in between grid points are calculated by linear interpolation.
+     131             : 
+     132             : \par Optimization notes
+     133             : 
+     134             : To avoid 'blind' optimization of the basis functions outside the currently sampled area, it is often beneficial to use the OPTIMIZATION_THRESHOLD keyword of the \ref VES_LINEAR_EXPANSION (set it to a small value, e.g. 1e-6)
+     135             : 
+     136             : \par Examples
+     137             : 
+     138             : 
+     139             : First a very simple example that relies on the default values.
+     140             : We want to bias some CV in the range of 0 to 4.
+     141             : The wavelets will therefore be scaled to match that range.
+     142             : Using Db8 wavelets this results in 30 basis functions (including the constant one), with their starting points given by \f$ -14*\frac{4}{15}, -13*\frac{4}{15}, \cdots , 0 , \cdots, 13*\frac{4}{15}, 14*\frac{4}{15} \f$.
+     143             : \plumedfile
+     144             : BF_WAVELETS ...
+     145             :  ORDER=8
+     146             :  TYPE=DAUBECHIES
+     147             :  MINIMUM=0.0
+     148             :  MAXIMUM=4.0
+     149             :  LABEL=bf
+     150             : ... BF_WAVELETS
+     151             : \endplumedfile
+     152             : 
+     153             : 
+     154             : By omitting wavelets with only insignificant parts, we can reduce the number of basis functions. Using a threshold of 0.01 will in this example remove the 8 leftmost shifts, which we can check in the logfile.
+     155             : \plumedfile
+     156             : BF_WAVELETS ...
+     157             :  ORDER=8
+     158             :  TYPE=DAUBECHIES
+     159             :  MINIMUM=0.0
+     160             :  MAXIMUM=4.0
+     161             :  TAILS_THRESHOLD=0.01
+     162             :  LABEL=bf
+     163             : ... BF_WAVELETS
+     164             : \endplumedfile
+     165             : 
+     166             : 
+     167             : The length of the individual basis functions can also be adjusted to fit the specific problem.
+     168             : If for example the wavelets are instead scaled to length 3, there will be 35 basis functions, with leftmost points at \f$ -14*\frac{3}{15}, -13*\frac{3}{15}, \cdots, 0, \cdots, 18*\frac{3}{15}, 19*\frac{3}{15} \f$.
+     169             : \plumedfile
+     170             : BF_WAVELETS ...
+     171             :  ORDER=8
+     172             :  TYPE=DAUBECHIES
+     173             :  MINIMUM=0.0
+     174             :  MAXIMUM=4.0
+     175             :  FUNCTION_LENGTH=3
+     176             :  LABEL=bf
+     177             : ... BF_WAVELETS
+     178             : \endplumedfile
+     179             : 
+     180             : 
+     181             : Alternatively you can also specify the number of basis functions. Here we specify the usage of 40 Sym10 wavelet functions. We also used a custom minimum size for the grid and want it to be printed to a file with a specific numerical format.
+     182             : \plumedfile
+     183             : BF_WAVELETS ...
+     184             :  ORDER=10
+     185             :  TYPE=SYMLETS
+     186             :  MINIMUM=0.0
+     187             :  MAXIMUM=4.0
+     188             :  NUM_BF=40
+     189             :  MIN_GRID_SIZE=500
+     190             :  DUMP_WAVELET_GRID
+     191             :  WAVELET_FILE_FMT=%11.4f
+     192             :  LABEL=bf
+     193             : ... BF_WAVELETS
+     194             : \endplumedfile
+     195             : 
+     196             : */
+     197             : //+ENDPLUMEDOC
+     198             : 
+     199             : 
+     200             : class BF_Wavelets : public BasisFunctions {
+     201             : private:
+     202             :   void setupLabels() override;
+     203             :   /// ptr to Grid that holds the Wavelet values and its derivative
+     204             :   std::unique_ptr<Grid> waveletGrid_;
+     205             :   /// calculate threshold for omitted tail wavelets
+     206             :   std::vector<double> getCutoffPoints(const double& threshold);
+     207             :   /// scale factor of the individual BFs to match specified length
+     208             :   double scale_;
+     209             :   /// shift of the individual BFs
+     210             :   std::vector<double> shifts_;
+     211             : public:
+     212             :   static void registerKeywords( Keywords&);
+     213             :   explicit BF_Wavelets(const ActionOptions&);
+     214             :   void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const override;
+     215             : };
+     216             : 
+     217             : 
+     218             : PLUMED_REGISTER_ACTION(BF_Wavelets,"BF_WAVELETS")
+     219             : 
+     220             : 
+     221          49 : void BF_Wavelets::registerKeywords(Keywords& keys) {
+     222          49 :   BasisFunctions::registerKeywords(keys);
+     223          98 :   keys.add("compulsory","TYPE","Specify the wavelet type. Currently available are DAUBECHIES Wavelets with minimum phase and the more symmetric SYMLETS");
+     224          98 :   keys.add("optional","FUNCTION_LENGTH","The domain size of the individual basis functions. (length) This is used to alter the scaling of the basis functions. By default it is set to the total size of the interval. This also influences the number of actually used basis functions, as all shifted functions that are partially supported in the CV space are used.");
+     225          98 :   keys.add("optional","NUM_BF","The number of basis functions that should be used. Includes the constant one and N-1 shifted wavelets within the specified range. Cannot be used together with FUNCTION_LENGTH.");
+     226          98 :   keys.add("optional","TAILS_THRESHOLD","The threshold for cutting off tail wavelets as a fraction of the maximum value. All shifted wavelet functions that only have values smaller than the threshold in the bias range will be excluded from the basis set. Defaults to 0 (include all).");
+     227          98 :   keys.addFlag("MOTHER_WAVELET", false, "If this flag is set mother wavelets will be used instead of the scaling function (father wavelet). Makes only sense for multiresolution, which is at the moment not usable.");
+     228          98 :   keys.add("optional","MIN_GRID_SIZE","The minimal number of grid bins of the Wavelet function. The true number depends also on the used wavelet type and will probably be larger. Defaults to 1000.");
+     229          98 :   keys.addFlag("DUMP_WAVELET_GRID", false, "If this flag is set the grid with the wavelet values will be written to a file.  This file is called wavelet_grid.data.");
+     230          98 :   keys.add("optional","WAVELET_FILE_FMT","The number format of the wavelet grid values and derivatives written to file. By default it is %15.8f.\n");
+     231          98 :   keys.addFlag("PERIODIC", false, "Use periodic version of basis set.");
+     232          49 :   keys.remove("NUMERICAL_INTEGRALS");
+     233          49 : }
+     234             : 
+     235             : 
+     236          47 : BF_Wavelets::BF_Wavelets(const ActionOptions& ao):
+     237             :   PLUMED_VES_BASISFUNCTIONS_INIT(ao),
+     238          47 :   waveletGrid_(nullptr),
+     239          47 :   scale_(0.0)
+     240             : {
+     241          47 :   log.printf("  Wavelet basis functions, see and cite ");
+     242          94 :   log << plumed.cite("Pampel and Valsson, J. Chem. Theory Comput. 18, 4127-4141 (2022) - DOI:10.1021/acs.jctc.2c00197");
+     243             : 
+     244             :   // parse properties for waveletGrid and set it up
+     245             :   bool use_mother_wavelet;
+     246          94 :   parseFlag("MOTHER_WAVELET", use_mother_wavelet);
+     247             : 
+     248             :   std::string wavelet_type_str;
+     249          47 :   parse("TYPE", wavelet_type_str);
+     250          94 :   addKeywordToList("TYPE", wavelet_type_str);
+     251             : 
+     252          47 :   unsigned min_grid_size = 1000;
+     253          47 :   parse("MIN_GRID_SIZE", min_grid_size);
+     254          83 :   if(min_grid_size != 1000) {addKeywordToList("MIN_GRID_SIZE",min_grid_size);}
+     255             : 
+     256          94 :   waveletGrid_ = WaveletGrid::setupGrid(getOrder(), min_grid_size, use_mother_wavelet, WaveletGrid::stringToType(wavelet_type_str));
+     257          47 :   bool dump_wavelet_grid=false;
+     258          47 :   parseFlag("DUMP_WAVELET_GRID", dump_wavelet_grid);
+     259          47 :   if (dump_wavelet_grid) {
+     260          36 :     OFile wavelet_gridfile;
+     261          36 :     std::string fmt = "%13.6f";
+     262          72 :     parse("WAVELET_FILE_FMT",fmt);
+     263             :     waveletGrid_->setOutputFmt(fmt); // property of grid not OFile determines fmt
+     264          36 :     wavelet_gridfile.link(*this);
+     265          36 :     wavelet_gridfile.enforceBackup();
+     266          72 :     wavelet_gridfile.open(getLabel()+".wavelet_grid.data");
+     267          36 :     waveletGrid_->writeToFile(wavelet_gridfile);
+     268          36 :   }
+     269             : 
+     270          47 :   bool periodic = false;
+     271          47 :   parseFlag("PERIODIC",periodic);
+     272          51 :   if (periodic) {addKeywordToList("PERIODIC",periodic);}
+     273             : 
+     274             :   // now set up properties of basis set
+     275          47 :   unsigned intrinsic_length = 2*getOrder() - 1; // length of unscaled wavelet
+     276          47 :   double bias_length = intervalMax() - intervalMin(); // intervalRange() is not yet set
+     277             : 
+     278             :   // parse threshold for tail wavelets and get respective cutoff points
+     279          47 :   double threshold = 0.0;
+     280          47 :   std::vector<double> cutoffpoints (2);
+     281          47 :   parse("TAILS_THRESHOLD",threshold);
+     282          47 :   plumed_massert(threshold < 1, "TAILS_THRESHOLD should be significantly smaller than 1.");
+     283          47 :   if(threshold == 0.0) {
+     284          45 :     cutoffpoints = {0.0, static_cast<double>(intrinsic_length)};
+     285             :   }
+     286             :   else {
+     287           2 :     plumed_massert(!periodic, "TAILS_THRESHOLD can't be used with the periodic wavelet variant");
+     288           2 :     addKeywordToList("TAILS_THRESHOLD",threshold);
+     289           4 :     cutoffpoints = getCutoffPoints(threshold);
+     290             :   };
+     291             : 
+     292          47 :   double function_length = bias_length;
+     293          47 :   parse("FUNCTION_LENGTH",function_length);
+     294          47 :   if(function_length != bias_length) {
+     295           4 :     if (periodic) {  // shifted functions need to fit into interval exactly -> reduce size if not
+     296           2 :       unsigned num_shifts = ceil(bias_length * intrinsic_length / function_length);
+     297           2 :       function_length = bias_length * intrinsic_length / num_shifts;
+     298             :     }
+     299           8 :     addKeywordToList("FUNCTION_LENGTH",function_length);
+     300             :   }
+     301             : 
+     302             :   // determine number of BFs and needed scaling
+     303          47 :   unsigned num_BFs = 0;
+     304          47 :   parse("NUM_BF",num_BFs);
+     305          47 :   if(num_BFs == 0) { // get from function length
+     306          43 :     scale_ = intrinsic_length / function_length;
+     307          43 :     if (periodic) {
+     308             :       // this is the same value as num_shifts above + constant
+     309           2 :       num_BFs = static_cast<unsigned>(bias_length * scale_) + 1;
+     310             :     }
+     311             :     else {
+     312          41 :       num_BFs = 1; // constant one
+     313             :       // left shifts (w/o left cutoff) + right shifts - right cutoff - 1
+     314          41 :       num_BFs += static_cast<unsigned>(ceil(cutoffpoints[1] + (bias_length)*scale_ - cutoffpoints[0]) - 1);
+     315             :     }
+     316             :   }
+     317             :   else {
+     318             :     plumed_massert(num_BFs > 0, "The number of basis functions has to be positive (NUM_BF > 0)");
+     319             :     // check does not work if function length was given as intrinsic length, but can't check for keyword use directly
+     320           4 :     plumed_massert(function_length==bias_length,"The keywords \"NUM_BF\" and \"FUNCTION_LENGTH\" cannot be used at the same time");
+     321           4 :     addKeywordToList("NUM_BF",num_BFs);
+     322             : 
+     323           4 :     if (periodic) {  // inverted num_BFs calculation from where FUNCTION_LENGTH is specified
+     324           2 :       scale_ = (num_BFs  - 1) / bias_length ;
+     325             :     }
+     326             :     else {
+     327           2 :       double cutoff_length = cutoffpoints[1] - cutoffpoints [0];
+     328           2 :       double intrinsic_bias_length = num_BFs - cutoff_length + 1; // length of bias in intrinsic scale of wavelets
+     329           2 :       scale_ = intrinsic_bias_length / bias_length;
+     330             :     }
+     331             :   }
+     332             : 
+     333          47 :   setNumberOfBasisFunctions(num_BFs);
+     334             : 
+     335             :   // now set up the starting points of the basis functions
+     336          47 :   shifts_.push_back(0.0); // constant BF – never used, just for clearer notation
+     337        1908 :   for(unsigned int i = 1; i < getNumberOfBasisFunctions(); ++i) {
+     338        1861 :     shifts_.push_back(-intervalMin()*scale_ + cutoffpoints[1] - i);
+     339             :   }
+     340             : 
+     341             :   // set some properties
+     342          47 :   setIntrinsicInterval(0.0,intrinsic_length);
+     343          47 :   periodic ? setPeriodic() : setNonPeriodic();
+     344             :   setIntervalBounded();
+     345             :   setType(wavelet_type_str);
+     346          47 :   setDescription("Wavelets as localized basis functions");
+     347          47 :   setupBF();
+     348          47 :   checkRead();
+     349             : 
+     350          47 :   log.printf("  Each basisfunction spans %f in CV space\n", intrinsic_length/scale_);
+     351          47 : }
+     352             : 
+     353             : 
+     354       62249 : void BF_Wavelets::getAllValues(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     355       62249 :   argT=checkIfArgumentInsideInterval(arg,inside_range);
+     356             :   //
+     357       62249 :   values[0]=1.0;
+     358       62249 :   derivs[0]=0.0;
+     359     2315762 :   for(unsigned int i = 1; i < getNumberOfBasisFunctions(); ++i) {
+     360             :     // scale and shift argument to match current wavelet
+     361     2253513 :     double x = shifts_[i] + argT*scale_;
+     362     2253513 :     if (arePeriodic()) { // periodic interval [0,intervalRange*scale]
+     363      171766 :       x = x - floor(x/(intervalRange()*scale_))*intervalRange()*scale_;
+     364             :     }
+     365             : 
+     366     2253513 :     if (x < 0 || x >= intrinsicIntervalMax()) { // Wavelets are 0 outside the defined range
+     367      989659 :       values[i] = 0.0; derivs[i] = 0.0;
+     368             :     }
+     369             :     else {
+     370     1263854 :       std::vector<double> temp_deriv (1);
+     371     1263854 :       values[i] = GridLinearInterpolation::getGridValueAndDerivativesWithLinearInterpolation(waveletGrid_.get(), {x}, temp_deriv);
+     372     1263854 :       derivs[i] = temp_deriv[0] * scale_; // scale derivative
+     373             :     }
+     374             :   }
+     375       67885 :   if(!inside_range) {for(auto& deriv : derivs) {deriv=0.0;}}
+     376       62249 : }
+     377             : 
+     378             : 
+     379             : // returns left and right cutoff point of Wavelet
+     380             : // threshold is a percent value of maximum
+     381           2 : std::vector<double> BF_Wavelets::getCutoffPoints(const double& threshold) {
+     382           2 :   double threshold_value = threshold * waveletGrid_->getMaxValue();
+     383             :   std::vector<double> cutoffpoints;
+     384             : 
+     385         475 :   for (size_t i = 0; i < waveletGrid_->getSize(); ++i) {
+     386         475 :     if (fabs(waveletGrid_->getValue(i)) >= threshold_value) {
+     387           2 :       cutoffpoints.push_back(waveletGrid_->getPoint(i)[0]);
+     388           2 :       break;
+     389             :     }
+     390             :   }
+     391             : 
+     392        1073 :   for (int i = waveletGrid_->getSize() - 1; i >= 0; --i) {
+     393        1073 :     if (fabs(waveletGrid_->getValue(i)) >= threshold_value) {
+     394           2 :       cutoffpoints.push_back(waveletGrid_->getPoint(i)[0]);
+     395           2 :       break;
+     396             :     }
+     397             :   }
+     398             : 
+     399           2 :   return cutoffpoints;
+     400             : }
+     401             : 
+     402             : 
+     403             : // labels according to minimum position in CV space
+     404          47 : void BF_Wavelets::setupLabels() {
+     405          47 :   setLabel(0,"const");
+     406        1908 :   for(unsigned int i=1; i < getNumberOfBasisFunctions(); i++) {
+     407        1861 :     double pos = -shifts_[i]/scale_;
+     408        1861 :     if (arePeriodic()) {
+     409          88 :       pos = pos - floor((pos-intervalMin())/intervalRange())*intervalRange();
+     410             :     }
+     411        1861 :     std::string is; Tools::convert(pos, is);
+     412        3722 :     setLabel(i,"i="+is);
+     413             :   }
+     414          47 : }
+     415             : 
+     416             : 
+     417             : }
+     418             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.cpp.func-sort-c.html b/coverage/ves/BasisFunctions.cpp.func-sort-c.html new file mode 100644 index 000000000000..5e0d9476ad09 --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.func-sort-c.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-02-22 21:58:45Functions:172181.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14BasisFunctions10linkActionEPNS_6ActionE0
_ZN4PLMD3ves14BasisFunctions11linkVesBiasEPNS0_7VesBiasE0
_ZN4PLMD3ves14BasisFunctions11setIntervalEdd0
_ZNK4PLMD3ves14BasisFunctions27getAllValuesNumericalDerivsEdRdRbRSt6vectorIdSaIdEES7_0
_ZN4PLMD3ves14BasisFunctions11setIntervalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_2
_ZNK4PLMD3ves14BasisFunctions16getMultipleValueERKSt6vectorIdSaIdEERS4_RS2_IS4_SaIS4_EESA_b71
_ZNK4PLMD3ves14BasisFunctions25writeBasisFunctionsToFileERNS_5OFileES3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_jbSB_SB_b71
_ZN4PLMD3ves14BasisFunctions11setupLabelsEv78
_ZN4PLMD3ves14BasisFunctions20setIntrinsicIntervalEdd79
_ZN4PLMD3ves14BasisFunctions21setupUniformIntegralsEv79
_ZN4PLMD3ves14BasisFunctions25numericalUniformIntegralsEv85
_ZNK4PLMD3ves14BasisFunctions16getKeywordStringB5cxx11Ev142
_ZN4PLMD3ves14BasisFunctions20setIntrinsicIntervalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_170
_ZNK4PLMD3ves14BasisFunctions30getTargetDistributionIntegralsEPKNS0_18TargetDistributionE247
_ZN4PLMD3ves14BasisFunctions13setupIntervalEv249
_ZN4PLMD3ves14BasisFunctions7setupBFEv249
_ZN4PLMD3ves14BasisFunctionsC2ERKNS_13ActionOptionsE249
_ZNK4PLMD3ves14BasisFunctions9printInfoEv249
_ZNK4PLMD3ves14BasisFunctions44numericalTargetDistributionIntegralsFromGridEPKNS_4GridE261
_ZNK4PLMD3ves14BasisFunctions8getValueEdjRdRb261
_ZN4PLMD3ves14BasisFunctions16registerKeywordsERNS_8KeywordsE271
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.cpp.func.html b/coverage/ves/BasisFunctions.cpp.func.html new file mode 100644 index 000000000000..9d3e20134bf1 --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.func.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-02-22 21:58:45Functions:172181.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14BasisFunctions10linkActionEPNS_6ActionE0
_ZN4PLMD3ves14BasisFunctions11linkVesBiasEPNS0_7VesBiasE0
_ZN4PLMD3ves14BasisFunctions11setIntervalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_2
_ZN4PLMD3ves14BasisFunctions11setIntervalEdd0
_ZN4PLMD3ves14BasisFunctions11setupLabelsEv78
_ZN4PLMD3ves14BasisFunctions13setupIntervalEv249
_ZN4PLMD3ves14BasisFunctions16registerKeywordsERNS_8KeywordsE271
_ZN4PLMD3ves14BasisFunctions20setIntrinsicIntervalERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_170
_ZN4PLMD3ves14BasisFunctions20setIntrinsicIntervalEdd79
_ZN4PLMD3ves14BasisFunctions21setupUniformIntegralsEv79
_ZN4PLMD3ves14BasisFunctions25numericalUniformIntegralsEv85
_ZN4PLMD3ves14BasisFunctions7setupBFEv249
_ZN4PLMD3ves14BasisFunctionsC2ERKNS_13ActionOptionsE249
_ZNK4PLMD3ves14BasisFunctions16getKeywordStringB5cxx11Ev142
_ZNK4PLMD3ves14BasisFunctions16getMultipleValueERKSt6vectorIdSaIdEERS4_RS2_IS4_SaIS4_EESA_b71
_ZNK4PLMD3ves14BasisFunctions25writeBasisFunctionsToFileERNS_5OFileES3_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESB_jbSB_SB_b71
_ZNK4PLMD3ves14BasisFunctions27getAllValuesNumericalDerivsEdRdRbRSt6vectorIdSaIdEES7_0
_ZNK4PLMD3ves14BasisFunctions30getTargetDistributionIntegralsEPKNS0_18TargetDistributionE247
_ZNK4PLMD3ves14BasisFunctions44numericalTargetDistributionIntegralsFromGridEPKNS_4GridE261
_ZNK4PLMD3ves14BasisFunctions8getValueEdjRdRb261
_ZNK4PLMD3ves14BasisFunctions9printInfoEv249
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.cpp.gcov.html b/coverage/ves/BasisFunctions.cpp.gcov.html new file mode 100644 index 000000000000..5eb6364148ad --- /dev/null +++ b/coverage/ves/BasisFunctions.cpp.gcov.html @@ -0,0 +1,482 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:22225387.7 %
Date:2024-02-22 21:58:45Functions:172181.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : #include "TargetDistribution.h"
+      25             : #include "VesBias.h"
+      26             : #include "VesTools.h"
+      27             : #include "GridIntegrationWeights.h"
+      28             : 
+      29             : #include "tools/Grid.h"
+      30             : #include "tools/Tools.h"
+      31             : 
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace ves {
+      35             : 
+      36         271 : void BasisFunctions::registerKeywords(Keywords& keys) {
+      37         271 :   Action::registerKeywords(keys);
+      38         542 :   keys.add("compulsory","ORDER","The order of the basis function expansion.");
+      39         542 :   keys.add("compulsory","MINIMUM","The minimum of the interval on which the basis functions are defined.");
+      40         542 :   keys.add("compulsory","MAXIMUM","The maximum of the interval on which the basis functions are defined.");
+      41         542 :   keys.add("hidden","NGRID_POINTS","The number of grid points used for numerical integrals");
+      42         542 :   keys.addFlag("DEBUG_INFO",false,"Print out more detailed information about the basis set. Useful for debugging.");
+      43         542 :   keys.addFlag("NUMERICAL_INTEGRALS",false,"Calculate basis function integral for the uniform distribution numerically. Useful for debugging.");
+      44         271 : }
+      45             : 
+      46             : 
+      47         249 : BasisFunctions::BasisFunctions(const ActionOptions&ao):
+      48             :   Action(ao),
+      49         249 :   print_debug_info_(false),
+      50         249 :   has_been_set(false),
+      51         498 :   description_("Undefined"),
+      52         249 :   type_("Undefined"),
+      53         249 :   norder_(0),
+      54         249 :   nbasis_(1),
+      55         249 :   bf_label_prefix_("f"),
+      56         249 :   bf_labels_(nbasis_,"f0"),
+      57         249 :   periodic_(false),
+      58         249 :   interval_bounded_(true),
+      59         249 :   interval_intrinsic_min_str_("1.0"),
+      60         249 :   interval_intrinsic_max_str_("-1.0"),
+      61         249 :   interval_intrinsic_min_(1.0),
+      62         249 :   interval_intrinsic_max_(-1.0),
+      63         249 :   interval_intrinsic_range_(0.0),
+      64         249 :   interval_intrinsic_mean_(0.0),
+      65         249 :   interval_min_str_(""),
+      66         249 :   interval_max_str_(""),
+      67         249 :   interval_min_(0.0),
+      68         249 :   interval_max_(0.0),
+      69         249 :   interval_range_(0.0),
+      70         249 :   interval_mean_(0.0),
+      71         249 :   argT_derivf_(1.0),
+      72         249 :   numerical_uniform_integrals_(false),
+      73         249 :   nbins_(1001),
+      74         249 :   uniform_integrals_(nbasis_,0.0),
+      75         249 :   vesbias_pntr_(NULL),
+      76         747 :   action_pntr_(NULL)
+      77             : {
+      78         249 :   bf_keywords_.push_back(getName());
+      79         498 :   if(keywords.exists("ORDER")) {
+      80         711 :     parse("ORDER",norder_); addKeywordToList("ORDER",norder_);
+      81             :   }
+      82         249 :   nbasis_=norder_+1;
+      83             :   //
+      84             :   std::string str_imin; std::string str_imax;
+      85         496 :   if(keywords.exists("MINIMUM") && keywords.exists("MAXIMUM")) {
+      86         741 :     parse("MINIMUM",str_imin); addKeywordToList("MINIMUM",str_imin);
+      87         741 :     parse("MAXIMUM",str_imax); addKeywordToList("MAXIMUM",str_imax);
+      88             :   }
+      89             :   else {
+      90             :     str_imin = "-1.0";
+      91             :     str_imax = "1.0";
+      92             :   }
+      93             :   interval_min_str_ = str_imin;
+      94             :   interval_max_str_ = str_imax;
+      95         249 :   if(!Tools::convertNoexcept(str_imin,interval_min_)) {
+      96           0 :     plumed_merror(getName()+": cannot convert the value given in MINIMUM to a double");
+      97             :   }
+      98         249 :   if(!Tools::convertNoexcept(str_imax,interval_max_)) {
+      99           0 :     plumed_merror(getName()+": cannot convert the value given in MAXIMUM to a double");
+     100             :   }
+     101         249 :   if(interval_min_>interval_max_) {plumed_merror(getName()+": MINIMUM and MAXIMUM are not correctly defined");}
+     102             :   //
+     103         249 :   parseFlag("DEBUG_INFO",print_debug_info_);
+     104         498 :   if(keywords.exists("NUMERICAL_INTEGRALS")) {
+     105         336 :     parseFlag("NUMERICAL_INTEGRALS",numerical_uniform_integrals_);
+     106             :   }
+     107         498 :   if(keywords.exists("NGRID_POINTS")) {
+     108         494 :     parse("NGRID_POINTS",nbins_);
+     109             :   }
+     110             :   // log.printf(" %s \n",getKeywordString().c_str());
+     111             : 
+     112         249 : }
+     113             : 
+     114             : 
+     115          79 : void BasisFunctions::setIntrinsicInterval(const double interval_intrinsic_min_in, const double interval_intrinsic_max_in) {
+     116          79 :   interval_intrinsic_min_ = interval_intrinsic_min_in;
+     117          79 :   interval_intrinsic_max_ = interval_intrinsic_max_in;
+     118          79 :   VesTools::convertDbl2Str(interval_intrinsic_min_,interval_intrinsic_min_str_);
+     119          79 :   VesTools::convertDbl2Str(interval_intrinsic_max_,interval_intrinsic_max_str_);
+     120          79 :   plumed_massert(interval_intrinsic_min_<interval_intrinsic_max_,"setIntrinsicInterval: intrinsic intervals are not defined correctly");
+     121          79 : }
+     122             : 
+     123             : 
+     124         170 : void BasisFunctions::setIntrinsicInterval(const std::string& interval_intrinsic_min_str_in, const std::string& interval_intrinsic_max_str_in) {
+     125         170 :   interval_intrinsic_min_str_ = interval_intrinsic_min_str_in;
+     126         170 :   interval_intrinsic_max_str_ = interval_intrinsic_max_str_in;
+     127         170 :   if(!Tools::convertNoexcept(interval_intrinsic_min_str_,interval_intrinsic_min_)) {
+     128           0 :     plumed_merror("setIntrinsicInterval: cannot convert string value given for the minimum of the intrinsic interval to a double");
+     129             :   }
+     130         170 :   if(!Tools::convertNoexcept(interval_intrinsic_max_str_,interval_intrinsic_max_)) {
+     131           0 :     plumed_merror("setIntrinsicInterval: cannot convert string value given for the maximum of the intrinsic interval to a double");
+     132             :   }
+     133         170 :   plumed_massert(interval_intrinsic_min_<interval_intrinsic_max_,"setIntrinsicInterval: intrinsic intervals are not defined correctly");
+     134         170 : }
+     135             : 
+     136             : 
+     137           0 : void BasisFunctions::setInterval(const double interval_min_in, const double interval_max_in) {
+     138           0 :   interval_min_ = interval_min_in;
+     139           0 :   interval_max_ = interval_max_in;
+     140           0 :   VesTools::convertDbl2Str(interval_min_,interval_min_str_);
+     141           0 :   VesTools::convertDbl2Str(interval_max_,interval_max_str_);
+     142           0 :   plumed_massert(interval_min_<interval_max_,"setInterval: intervals are not defined correctly");
+     143           0 : }
+     144             : 
+     145             : 
+     146           2 : void BasisFunctions::setInterval(const std::string& interval_min_str_in, const std::string& interval_max_str_in) {
+     147           2 :   interval_min_str_ = interval_min_str_in;
+     148           2 :   interval_max_str_ = interval_max_str_in;
+     149           2 :   if(!Tools::convertNoexcept(interval_min_str_,interval_min_)) {
+     150           0 :     plumed_merror("setInterval: cannot convert string value given for the minimum of the interval to a double");
+     151             :   }
+     152           2 :   if(!Tools::convertNoexcept(interval_max_str_,interval_max_)) {
+     153           0 :     plumed_merror("setInterval: cannot convert string value given for the maximum of the interval to a double");
+     154             :   }
+     155           2 :   plumed_massert(interval_min_<interval_max_,"setInterval: intervals are not defined correctly");
+     156           2 : }
+     157             : 
+     158             : 
+     159         249 : void BasisFunctions::setupInterval() {
+     160             :   // if(!intervalBounded()){plumed_merror("setupInterval() only works for bounded interval");}
+     161         249 :   interval_intrinsic_range_ = interval_intrinsic_max_-interval_intrinsic_min_;
+     162         249 :   interval_intrinsic_mean_  = 0.5*(interval_intrinsic_max_+interval_intrinsic_min_);
+     163         249 :   interval_range_ = interval_max_-interval_min_;
+     164         249 :   interval_mean_  = 0.5*(interval_max_+interval_min_);
+     165         249 :   argT_derivf_ = interval_intrinsic_range_/interval_range_;
+     166         249 : }
+     167             : 
+     168             : 
+     169          78 : void BasisFunctions::setupLabels() {
+     170         884 :   for(unsigned int i=0; i < nbasis_; i++) {
+     171         806 :     std::string is; Tools::convert(i,is);
+     172        1612 :     bf_labels_[i]=bf_label_prefix_+is+"(s)";
+     173             :   }
+     174          78 : }
+     175             : 
+     176             : 
+     177          79 : void BasisFunctions::setupUniformIntegrals() {
+     178          79 :   numerical_uniform_integrals_=true;
+     179          79 :   numericalUniformIntegrals();
+     180          79 : }
+     181             : 
+     182             : 
+     183         249 : void BasisFunctions::setupBF() {
+     184         249 :   if(interval_intrinsic_min_>interval_intrinsic_max_) {plumed_merror("setupBF: default intervals are not correctly set");}
+     185         249 :   setupInterval();
+     186         249 :   setupLabels();
+     187         249 :   if(bf_labels_.size()==1) {plumed_merror("setupBF: the labels of the basis functions are not correct.");}
+     188         249 :   if(!numerical_uniform_integrals_) {setupUniformIntegrals();}
+     189           6 :   else {numericalUniformIntegrals();}
+     190         249 :   if(uniform_integrals_.size()==1) {plumed_merror("setupBF: the integrals of the basis functions is not correct.");}
+     191         249 :   if(type_=="Undefined") {plumed_merror("setupBF: the type of the basis function is not defined.");}
+     192         249 :   if(description_=="Undefined") {plumed_merror("setupBF: the description of the basis function is not defined.");}
+     193         249 :   has_been_set=true;
+     194         249 :   printInfo();
+     195         249 : }
+     196             : 
+     197             : 
+     198         249 : void BasisFunctions::printInfo() const {
+     199         249 :   if(!has_been_set) {plumed_merror("the basis set has not be setup correctly");}
+     200         249 :   log.printf("  One-dimensional basis set\n");
+     201         249 :   log.printf("   Description: %s\n",description_.c_str());
+     202         249 :   log.printf("   Type: %s\n",type_.c_str());
+     203         249 :   if(periodic_) {log.printf("   The basis functions are periodic\n");}
+     204         249 :   log.printf("   Order of basis set: %u\n",norder_);
+     205         249 :   log.printf("   Number of basis functions: %u\n",nbasis_);
+     206             :   // log.printf("   Interval of basis set: %f to %f\n",interval_min_,interval_max_);
+     207         249 :   log.printf("   Interval of basis set: %s to %s\n",interval_min_str_.c_str(),interval_max_str_.c_str());
+     208         249 :   log.printf("   Description of basis functions:\n");
+     209        4293 :   for(unsigned int i=0; i < nbasis_; i++) {log.printf("    %2u       %10s\n",i,bf_labels_[i].c_str());}
+     210             :   //
+     211         249 :   if(print_debug_info_) {
+     212          38 :     log.printf("  Debug information:\n");
+     213             :     // log.printf("   Default interval of basis set: [%f,%f]\n",interval_intrinsic_min_,interval_intrinsic_max_);
+     214          38 :     log.printf("   Intrinsic interval of basis set: [%s,%s]\n",interval_intrinsic_min_str_.c_str(),interval_intrinsic_max_str_.c_str());
+     215          38 :     log.printf("   Intrinsic interval of basis set: range=%f,  mean=%f\n",interval_intrinsic_range_,interval_intrinsic_mean_);
+     216             :     // log.printf("   Defined interval of basis set: [%f,%f]\n",interval_min_,interval_max_);
+     217          38 :     log.printf("   Defined interval of basis set: [%s,%s]\n",interval_min_str_.c_str(),interval_max_str_.c_str());
+     218          38 :     log.printf("   Defined interval of basis set: range=%f,  mean=%f\n",interval_range_,interval_mean_);
+     219          38 :     log.printf("   Derivative factor due to interval translation: %f\n",argT_derivf_);
+     220          38 :     log.printf("   Integral of basis functions over the interval:\n");
+     221          38 :     if(numerical_uniform_integrals_) {log.printf("   Note: calculated numerically\n");}
+     222         558 :     for(unsigned int i=0; i < nbasis_; i++) {log.printf("    %2u       %16.10f\n",i,uniform_integrals_[i]);}
+     223          38 :     log.printf("   --------------------------\n");
+     224             :   }
+     225         249 : }
+     226             : 
+     227             : 
+     228           0 : void BasisFunctions::linkVesBias(VesBias* vesbias_pntr_in) {
+     229           0 :   vesbias_pntr_ = vesbias_pntr_in;
+     230           0 :   action_pntr_ = static_cast<Action*>(vesbias_pntr_in);
+     231           0 : }
+     232             : 
+     233             : 
+     234           0 : void BasisFunctions::linkAction(Action* action_pntr_in) {
+     235           0 :   action_pntr_ = action_pntr_in;
+     236           0 : }
+     237             : 
+     238             : 
+     239          85 : void BasisFunctions::numericalUniformIntegrals() {
+     240          85 :   std::vector<std::string> grid_min(1); grid_min[0]=intervalMinStr();
+     241          85 :   std::vector<std::string> grid_max(1); grid_max[0]=intervalMaxStr();
+     242          85 :   std::vector<unsigned int> grid_bins(1); grid_bins[0]=nbins_;
+     243         170 :   std::vector<std::unique_ptr<Value>> arguments(1); arguments[0]= Tools::make_unique<Value>(nullptr,"arg",false);
+     244         105 :   if(arePeriodic()) {arguments[0]->setDomain(intervalMinStr(),intervalMaxStr());}
+     245          75 :   else {arguments[0]->setNotPeriodic();}
+     246         170 :   auto uniform_grid = Tools::make_unique<Grid>("uniform",Tools::unique2raw(arguments),grid_min,grid_max,grid_bins,false,false);
+     247             :   //
+     248          85 :   double inverse_normalization = 1.0/(intervalMax()-intervalMin());
+     249       85245 :   for(Grid::index_t l=0; l<uniform_grid->getSize(); l++) {
+     250       85160 :     uniform_grid->setValue(l,inverse_normalization);
+     251             :   }
+     252          85 :   uniform_integrals_ = numericalTargetDistributionIntegralsFromGrid(uniform_grid.get());
+     253         170 : }
+     254             : 
+     255             : 
+     256         261 : std::vector<double> BasisFunctions::numericalTargetDistributionIntegralsFromGrid(const Grid* grid_pntr) const {
+     257         261 :   plumed_massert(grid_pntr!=NULL,"the grid is not defined");
+     258         261 :   plumed_massert(grid_pntr->getDimension()==1,"the target distribution grid should be one dimensional");
+     259             :   //
+     260         261 :   std::vector<double> targetdist_integrals(nbasis_,0.0);
+     261         522 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(grid_pntr);
+     262             : 
+     263      138336 :   for(Grid::index_t k=0; k < grid_pntr->getSize(); k++) {
+     264      138075 :     double arg = grid_pntr->getPoint(k)[0];
+     265      138075 :     std::vector<double> bf_values(nbasis_);
+     266      138075 :     std::vector<double> bf_derivs(nbasis_);
+     267      138075 :     bool inside=true;
+     268      138075 :     double argT=0.0;
+     269      138075 :     getAllValues(arg,argT,inside,bf_values,bf_derivs);
+     270     3336092 :     for(unsigned int i=0; i < nbasis_; i++) {
+     271     3198017 :       targetdist_integrals[i] += (integration_weights[k] * grid_pntr->getValue(k)) * bf_values[i];
+     272             :     }
+     273             :   }
+     274             :   // assume that the first function is the constant
+     275         261 :   bool inside=true;
+     276         261 :   double argT=0.0;
+     277         261 :   targetdist_integrals[0] = getValue(0.0,0,argT,inside);
+     278         261 :   return targetdist_integrals;
+     279             : }
+     280             : 
+     281             : 
+     282         247 : std::vector<double> BasisFunctions::getTargetDistributionIntegrals(const TargetDistribution* targetdist_pntr) const {
+     283         247 :   if(targetdist_pntr==NULL) {
+     284             :     return getUniformIntegrals();
+     285             :   }
+     286             :   else {
+     287             :     Grid* targetdist_grid = targetdist_pntr->getTargetDistGridPntr();
+     288         176 :     return numericalTargetDistributionIntegralsFromGrid(targetdist_grid);
+     289             :   }
+     290             : }
+     291             : 
+     292             : 
+     293         142 : std::string BasisFunctions::getKeywordString() const {
+     294         142 :   std::string str_keywords=bf_keywords_[0];
+     295         762 :   for(unsigned int i=1; i<bf_keywords_.size(); i++) {str_keywords+=" "+bf_keywords_[i];}
+     296         142 :   return str_keywords;
+     297             : }
+     298             : 
+     299             : 
+     300         261 : double BasisFunctions::getValue(const double arg, const unsigned int n, double& argT, bool& inside_range) const {
+     301         261 :   plumed_massert(n<numberOfBasisFunctions(),"getValue: n is outside range of the defined order of the basis set");
+     302         261 :   inside_range=true;
+     303         261 :   std::vector<double> tmp_values(numberOfBasisFunctions());
+     304         261 :   std::vector<double> tmp_derivs(numberOfBasisFunctions());
+     305         261 :   getAllValues(arg, argT, inside_range, tmp_values, tmp_derivs);
+     306         522 :   return tmp_values[n];
+     307             : }
+     308             : 
+     309             : 
+     310           0 : void BasisFunctions::getAllValuesNumericalDerivs(const double arg, double& argT, bool& inside_range, std::vector<double>& values, std::vector<double>& derivs) const {
+     311             :   // use forward difference, unless very close to the boundary
+     312             :   double delta = sqrt(epsilon);
+     313           0 :   if((arg+delta)>intervalMax()) {
+     314             :     delta *= -1.0;
+     315             :   }
+     316           0 :   inside_range=true;
+     317           0 :   std::vector<double> values_delta(numberOfBasisFunctions());
+     318           0 :   std::vector<double> derivs_dummy(numberOfBasisFunctions());
+     319           0 :   getAllValues(arg+delta, argT, inside_range, values_delta, derivs_dummy);
+     320           0 :   getAllValues(arg, argT, inside_range, values, derivs_dummy);
+     321           0 :   for(unsigned int i=0; i<numberOfBasisFunctions(); i++) {
+     322           0 :     derivs[i] = (values_delta[i]-values[i])/delta;
+     323             :   }
+     324           0 : }
+     325             : 
+     326             : 
+     327          71 : void BasisFunctions::getMultipleValue(const std::vector<double>& args, std::vector<double>& argsT, std::vector<std::vector<double> >& values, std::vector<std::vector<double> >& derivs, const bool numerical_deriv) const {
+     328          71 :   argsT.resize(args.size());
+     329             :   values.clear();
+     330             :   derivs.clear();
+     331       23019 :   for(unsigned int i=0; i<args.size(); i++) {
+     332       22948 :     std::vector<double> tmp_values(getNumberOfBasisFunctions());
+     333       22948 :     std::vector<double> tmp_derivs(getNumberOfBasisFunctions());
+     334       22948 :     bool inside_interval=true;
+     335       22948 :     if(!numerical_deriv) {
+     336       22948 :       getAllValues(args[i],argsT[i],inside_interval,tmp_values,tmp_derivs);
+     337             :     } else {
+     338           0 :       getAllValuesNumericalDerivs(args[i],argsT[i],inside_interval,tmp_values,tmp_derivs);
+     339             :     }
+     340       22948 :     values.push_back(tmp_values);
+     341       22948 :     derivs.push_back(tmp_derivs);
+     342             :   }
+     343          71 : }
+     344             : 
+     345             : 
+     346          71 : void BasisFunctions::writeBasisFunctionsToFile(OFile& ofile_values, OFile& ofile_derivs, const std::string& min_in, const std::string& max_in, unsigned int nbins_in, const bool ignore_periodicity, const std::string& output_fmt_values, const std::string& output_fmt_derivs, const bool numerical_deriv) const {
+     347          71 :   std::vector<std::string> min(1); min[0]=min_in;
+     348          71 :   std::vector<std::string> max(1); max[0]=max_in;
+     349          71 :   std::vector<unsigned int> nbins(1); nbins[0]=nbins_in;
+     350          71 :   std::vector<std::unique_ptr<Value>> value_pntr(1);
+     351         142 :   value_pntr[0]= Tools::make_unique<Value>(nullptr,"arg",false);
+     352         117 :   if(arePeriodic() && !ignore_periodicity) {value_pntr[0]->setDomain(intervalMinStr(),intervalMaxStr());}
+     353          48 :   else {value_pntr[0]->setNotPeriodic();}
+     354         142 :   Grid args_grid = Grid("grid",Tools::unique2raw(value_pntr),min,max,nbins,false,false);
+     355             : 
+     356          71 :   std::vector<double> args(args_grid.getSize(),0.0);
+     357       23019 :   for(unsigned int i=0; i<args.size(); i++) {
+     358       22948 :     args[i] = args_grid.getPoint(i)[0];
+     359             :   }
+     360             :   std::vector<double> argsT;
+     361             :   std::vector<std::vector<double> > values;
+     362             :   std::vector<std::vector<double> > derivs;
+     363             : 
+     364         142 :   ofile_values.addConstantField("bf_keywords").printField("bf_keywords","{"+getKeywordString()+"}");
+     365         142 :   ofile_derivs.addConstantField("bf_keywords").printField("bf_keywords","{"+getKeywordString()+"}");
+     366             : 
+     367         213 :   ofile_values.addConstantField("min").printField("min",intervalMinStr());
+     368         213 :   ofile_values.addConstantField("max").printField("max",intervalMaxStr());
+     369             : 
+     370         213 :   ofile_derivs.addConstantField("min").printField("min",intervalMinStr());
+     371         213 :   ofile_derivs.addConstantField("max").printField("max",intervalMaxStr());
+     372             : 
+     373         142 :   ofile_values.addConstantField("nbins").printField("nbins",static_cast<int>(args_grid.getNbin()[0]));
+     374         142 :   ofile_derivs.addConstantField("nbins").printField("nbins",static_cast<int>(args_grid.getNbin()[0]));
+     375             : 
+     376          71 :   if(arePeriodic()) {
+     377          52 :     ofile_values.addConstantField("periodic").printField("periodic","true");
+     378          52 :     ofile_derivs.addConstantField("periodic").printField("periodic","true");
+     379             :   }
+     380             :   else {
+     381          90 :     ofile_values.addConstantField("periodic").printField("periodic","false");
+     382          90 :     ofile_derivs.addConstantField("periodic").printField("periodic","false");
+     383             :   }
+     384             : 
+     385          71 :   getMultipleValue(args,argsT,values,derivs,numerical_deriv);
+     386          71 :   ofile_values.fmtField(output_fmt_values);
+     387          71 :   ofile_derivs.fmtField(output_fmt_derivs);
+     388       23019 :   for(unsigned int i=0; i<args.size(); i++) {
+     389       45896 :     ofile_values.printField("arg",args[i]);
+     390       22948 :     ofile_derivs.printField("arg",args[i]);
+     391      410060 :     for(unsigned int k=0; k<getNumberOfBasisFunctions(); k++) {
+     392      774224 :       ofile_values.printField(getBasisFunctionLabel(k),values[i][k]);
+     393      774224 :       ofile_derivs.printField("d_"+getBasisFunctionLabel(k),derivs[i][k]);
+     394             :     }
+     395       22948 :     ofile_values.printField();
+     396       22948 :     ofile_derivs.printField();
+     397             :   }
+     398          71 :   ofile_values.fmtField();
+     399          71 :   ofile_derivs.fmtField();
+     400             : 
+     401         213 : }
+     402             : 
+     403             : 
+     404             : }
+     405             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.h.func-sort-c.html b/coverage/ves/BasisFunctions.h.func-sort-c.html new file mode 100644 index 000000000000..b12256251e0c --- /dev/null +++ b/coverage/ves/BasisFunctions.h.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14BasisFunctions5applyEv0
_ZN4PLMD3ves14BasisFunctions9calculateEv0
_ZN4PLMD3ves14BasisFunctions16addKeywordToListINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RKSt6vectorIT_SaISC_EE2
_ZN4PLMD3ves14BasisFunctions16addKeywordToListIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEET_7
_ZN4PLMD3ves14BasisFunctions28setAllUniformIntegralsToZeroEv159
_ZN4PLMD3ves14BasisFunctions25setNumberOfBasisFunctionsEj249
_ZN4PLMD3ves14BasisFunctions16addKeywordToListIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEET_277
_ZN4PLMD3ves14BasisFunctions16addKeywordToListINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_T_593
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.h.func.html b/coverage/ves/BasisFunctions.h.func.html new file mode 100644 index 000000000000..021a95a46a02 --- /dev/null +++ b/coverage/ves/BasisFunctions.h.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14BasisFunctions16addKeywordToListINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RKSt6vectorIT_SaISC_EE2
_ZN4PLMD3ves14BasisFunctions16addKeywordToListINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_T_593
_ZN4PLMD3ves14BasisFunctions16addKeywordToListIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEET_7
_ZN4PLMD3ves14BasisFunctions16addKeywordToListIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEET_277
_ZN4PLMD3ves14BasisFunctions25setNumberOfBasisFunctionsEj249
_ZN4PLMD3ves14BasisFunctions28setAllUniformIntegralsToZeroEv159
_ZN4PLMD3ves14BasisFunctions5applyEv0
_ZN4PLMD3ves14BasisFunctions9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/BasisFunctions.h.gcov.html b/coverage/ves/BasisFunctions.h.gcov.html new file mode 100644 index 000000000000..2a0987eb6315 --- /dev/null +++ b/coverage/ves/BasisFunctions.h.gcov.html @@ -0,0 +1,394 @@ + + + + + + + + LCOV - plumed test coverage - ves/BasisFunctions.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - BasisFunctions.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596196.7 %
Date:2024-02-22 21:58:45Functions:6875.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_BasisFunctions_h
+      23             : #define __PLUMED_ves_BasisFunctions_h
+      24             : 
+      25             : #include "core/Action.h"
+      26             : 
+      27             : #include <vector>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : 
+      32             : #define PLUMED_VES_BASISFUNCTIONS_INIT(ao) BasisFunctions(ao)
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : /**
+      37             : \ingroup INHERIT
+      38             : Abstract base class for implenting new 1D basis sets.
+      39             : */
+      40             : 
+      41             : class Action;
+      42             : class Grid;
+      43             : 
+      44             : namespace ves {
+      45             : 
+      46             : class VesBias;
+      47             : class TargetDistribution;
+      48             : 
+      49             : class BasisFunctions :
+      50             :   public Action
+      51             : {
+      52             : private:
+      53             :   // print extra info about the basis set
+      54             :   bool print_debug_info_;
+      55             :   // to check if the basis set has been defined
+      56             :   bool has_been_set;
+      57             :   // description of the basis set
+      58             :   std::string description_;
+      59             :   // the type of the basis set
+      60             :   std::string type_;
+      61             :   // the maximum order of the basis functions
+      62             :   unsigned int norder_;
+      63             :   // the total number of basis functions
+      64             :   unsigned int nbasis_;
+      65             :   // the keywords used to invoke the basis set
+      66             :   std::vector<std::string> bf_keywords_;
+      67             :   // prefix for the basis function labels
+      68             :   std::string bf_label_prefix_;
+      69             :   // label of each basis function
+      70             :   std::vector<std::string> bf_labels_;
+      71             :   // if the basis functions are periodic or not
+      72             :   bool periodic_;
+      73             :   // if the basis functions are defined on a bounded interval or not
+      74             :   bool interval_bounded_;
+      75             :   // the intrinsic interval of the basis functions
+      76             :   std::string interval_intrinsic_min_str_;
+      77             :   std::string interval_intrinsic_max_str_;
+      78             :   double interval_intrinsic_min_;
+      79             :   double interval_intrinsic_max_;
+      80             :   double interval_intrinsic_range_;
+      81             :   double interval_intrinsic_mean_;
+      82             :   // the defined (translated) interval of the basis functions
+      83             :   std::string interval_min_str_;
+      84             :   std::string interval_max_str_;
+      85             :   double interval_min_;
+      86             :   double interval_max_;
+      87             :   double interval_range_;
+      88             :   double interval_mean_;
+      89             :   // the derivative term in the chain rule coming from the translation of the interval
+      90             :   double argT_derivf_;
+      91             :   // calculate numerically the integrals of the basis functions over the intervals
+      92             :   bool numerical_uniform_integrals_;
+      93             :   unsigned int nbins_;
+      94             :   // the integrals of the basis functions over the interval on which they are defined
+      95             :   std::vector <double> uniform_integrals_;
+      96             :   //
+      97             :   VesBias* vesbias_pntr_;
+      98             :   Action* action_pntr_;
+      99             :   //
+     100             :   void getAllValuesNumericalDerivs(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const;
+     101             : 
+     102             : protected:
+     103             :   // setup various stuff
+     104             :   void setupBF();
+     105             :   void setupInterval();
+     106             :   void setNumericalIntegrationBins(const unsigned int nbins) {nbins_=nbins;}
+     107             :   void numericalUniformIntegrals();
+     108             :   std::vector<double> numericalTargetDistributionIntegralsFromGrid(const Grid*) const ;
+     109             :   virtual void setupLabels();
+     110             :   virtual void setupUniformIntegrals();
+     111             :   template<typename T>
+     112             :   void addKeywordToList(const std::string&, const T);
+     113             :   template<typename T>
+     114             :   void addKeywordToList(const std::string&, const std::vector<T>&);
+     115             :   void addKeywordToList(const std::string&, const bool);
+     116             :   //
+     117         111 :   void setPeriodic() {periodic_=true;}
+     118         138 :   void setNonPeriodic() {periodic_=false;}
+     119         249 :   void setIntervalBounded() {interval_bounded_=true;}
+     120             :   void setIntervalNonBounded() {interval_bounded_=false;}
+     121         249 :   void setType(const std::string& type_in) {type_=type_in;}
+     122         249 :   void setDescription(const std::string& description_in) {description_=description_in;}
+     123             :   //
+     124             :   void setNumberOfBasisFunctions(const unsigned int);
+     125          12 :   void setOrder(const unsigned int norder_in) {norder_=norder_in;}
+     126             :   void setIntrinsicInterval(const double, const double);
+     127             :   void setIntrinsicInterval(const std::string&, const std::string&);
+     128             :   void setInterval(const double, const double);
+     129             :   void setInterval(const std::string&, const std::string&);
+     130             :   //
+     131             :   double intrinsicIntervalMin() const {return interval_intrinsic_min_;}
+     132     1752567 :   double intrinsicIntervalMax() const {return interval_intrinsic_max_;}
+     133             :   std::string intrinsicIntervalMinStr() const {return interval_intrinsic_min_str_;}
+     134             :   std::string intrinsicIntervalMaxStr() const {return interval_intrinsic_max_str_;}
+     135             :   //
+     136             :   void setUniformIntegral(const unsigned int, const double);
+     137             :   void setUniformIntegrals(const std::vector<double>&);
+     138             :   void setAllUniformIntegralsToZero();
+     139             :   //
+     140             :   void setLabelPrefix(const std::string&);
+     141             :   void setLabel(const unsigned int, const std::string&);
+     142             :   void setLabels(const std::vector<std::string>&);
+     143             : 
+     144             : public:
+     145             :   static void registerKeywords(Keywords&);
+     146             :   explicit BasisFunctions(const ActionOptions&ao);
+     147             :   bool hasBeenSet() const {return has_been_set;}
+     148             :   std::string getType() const {return type_;}
+     149             :   std::string getDescription() const {return description_;}
+     150    33615870 :   unsigned int getOrder() const {return norder_;}
+     151    13201612 :   unsigned int getNumberOfBasisFunctions() const {return nbasis_;}
+     152      112559 :   unsigned int numberOfBasisFunctions() const {return nbasis_;}
+     153             :   unsigned int getSize() const {return nbasis_;}
+     154     2661456 :   bool arePeriodic() const {return periodic_;}
+     155             :   bool intervalBounded() const {return interval_bounded_;}
+     156      204981 :   double intervalMin() const {return interval_min_;}
+     157         281 :   double intervalMax() const {return interval_max_;}
+     158      300134 :   double intervalRange() const {return interval_range_;}
+     159             :   double intervalMean() const {return interval_mean_;}
+     160    30352118 :   double intervalDerivf() const {return argT_derivf_;}
+     161         601 :   std::string intervalMinStr() const {return interval_min_str_;}
+     162         601 :   std::string intervalMaxStr() const {return interval_max_str_;}
+     163         133 :   std::vector<double> getUniformIntegrals() const {return uniform_integrals_;}
+     164             :   std::vector<double> getTargetDistributionIntegrals(const TargetDistribution*) const;
+     165             :   //
+     166             :   std::vector<std::string> getKeywordList() const {return bf_keywords_;}
+     167             :   std::string getKeywordString() const;
+     168             :   //
+     169      787685 :   std::string getBasisFunctionLabel(const unsigned int index) const {return bf_labels_[index];}
+     170             :   std::vector<std::string> getBasisFunctionLabels() const {return bf_labels_;}
+     171             :   //
+     172             :   void linkVesBias(VesBias*);
+     173             :   void linkAction(Action*);
+     174             :   VesBias* getPntrToVesBias() const;
+     175             :   Action* getPntrToAction() const;
+     176             :   //
+     177             :   double translateArgument(const double, bool&) const;
+     178             :   double checkIfArgumentInsideInterval(const double, bool&) const;
+     179             :   //
+     180           0 :   void apply() override {};
+     181           0 :   void calculate() override {};
+     182             :   // calculate the value for the n-th basis function
+     183             :   double getValue(const double, const unsigned int, double&, bool&) const;
+     184             :   // calculate the values for all basis functions
+     185             :   virtual void getAllValues(const double, double&, bool&, std::vector<double>&, std::vector<double>&) const = 0;
+     186             :   //virtual void get2ndDerivatives(const double, std::vector<double>&)=0;
+     187             :   void printInfo() const;
+     188             :   //
+     189             :   void getMultipleValue(const std::vector<double>&, std::vector<double>&, std::vector<std::vector<double> >&, std::vector<std::vector<double> >&, const bool numerical_deriv=false) const;
+     190             :   void writeBasisFunctionsToFile(OFile&, OFile&, const std::string& min_in, const std::string& max_in, unsigned int nbins=1000, const bool ignore_periodicity=false, const std::string& output_fmt_values="%15.8f", const std::string& output_fmt_derivs="%15.8f", const bool numerical_deriv=false) const;
+     191             : };
+     192             : 
+     193             : 
+     194             : inline
+     195         249 : void BasisFunctions::setNumberOfBasisFunctions(const unsigned int nbasis_in) {
+     196         249 :   nbasis_=nbasis_in;
+     197         249 :   bf_labels_.assign(nbasis_,"");
+     198         249 :   uniform_integrals_.assign(nbasis_,0.0);
+     199         249 : }
+     200             : 
+     201             : 
+     202             : inline
+     203             : VesBias* BasisFunctions::getPntrToVesBias() const {
+     204             :   plumed_massert(vesbias_pntr_!=NULL,"the VES bias has not been linked");
+     205             :   return vesbias_pntr_;
+     206             : }
+     207             : 
+     208             : 
+     209             : inline
+     210             : Action* BasisFunctions::getPntrToAction() const {
+     211             :   plumed_massert(action_pntr_!=NULL,"the action has not been linked");
+     212             :   return action_pntr_;
+     213             : }
+     214             : 
+     215             : 
+     216             : inline
+     217             : void BasisFunctions::setUniformIntegral(const unsigned index, const double value) {
+     218         264 :   uniform_integrals_[index] = value;
+     219             : }
+     220             : 
+     221             : 
+     222             : inline
+     223             : void BasisFunctions::setUniformIntegrals(const std::vector<double>& uniform_integrals_in) {
+     224             :   plumed_assert(uniform_integrals_in.size()==nbasis_);
+     225             :   uniform_integrals_ = uniform_integrals_in;
+     226             : }
+     227             : 
+     228             : 
+     229             : inline
+     230         159 : void BasisFunctions::setAllUniformIntegralsToZero() {
+     231         159 :   uniform_integrals_.assign(nbasis_,0.0);
+     232         159 : }
+     233             : 
+     234             : inline
+     235             : void BasisFunctions::setLabelPrefix(const std::string& bf_label_prefix_in) {
+     236          68 :   bf_label_prefix_ = bf_label_prefix_in;
+     237          68 : }
+     238             : 
+     239             : 
+     240             : inline
+     241             : void BasisFunctions::setLabel(const unsigned int index, const std::string& label) {
+     242        1140 :   bf_labels_[index] = label;
+     243        3238 : }
+     244             : 
+     245             : 
+     246             : inline
+     247             : void BasisFunctions::setLabels(const std::vector<std::string>& bf_labels_in) {
+     248             :   bf_labels_ = bf_labels_in;
+     249             : }
+     250             : 
+     251             : 
+     252             : inline
+     253             : double BasisFunctions::translateArgument(const double arg, bool& inside_interval) const {
+     254             :   // NOTE: only works for symmetric intrinsic intervals
+     255             :   inside_interval=true;
+     256     4895662 :   double argT = (arg-interval_mean_)*argT_derivf_;
+     257     4895662 :   if(argT < interval_intrinsic_min_) {
+     258         433 :     inside_interval=false;
+     259         433 :     argT=interval_intrinsic_min_;
+     260             :   }
+     261     4895229 :   else if(argT > interval_intrinsic_max_) {
+     262       13665 :     inside_interval=false;
+     263       13665 :     argT=interval_intrinsic_max_;
+     264             :   }
+     265             :   return argT;
+     266             : }
+     267             : 
+     268             : 
+     269             : inline
+     270             : double BasisFunctions::checkIfArgumentInsideInterval(const double arg, bool& inside_interval) const {
+     271       62249 :   inside_interval=true;
+     272             :   double argT = arg;
+     273      947044 :   if(arg < interval_min_) {
+     274         362 :     inside_interval=false;
+     275         362 :     argT=interval_min_;
+     276             :   }
+     277      946682 :   else if(arg > interval_max_) {
+     278         369 :     inside_interval=false;
+     279         369 :     argT=interval_max_;
+     280             :   }
+     281             :   return argT;
+     282             : }
+     283             : 
+     284             : 
+     285             : 
+     286             : template<typename T>
+     287         877 : void BasisFunctions::addKeywordToList(const std::string& keyword, const T value) {
+     288             :   std::string str_value;
+     289         877 :   Tools::convert(value,str_value);
+     290        1754 :   bf_keywords_.push_back(keyword+"="+str_value);
+     291         877 : }
+     292             : 
+     293             : 
+     294             : template<typename T>
+     295           2 : void BasisFunctions::addKeywordToList(const std::string& keyword, const std::vector<T>& values) {
+     296             :   std::string str_value;
+     297             :   std::string str_keywordvalues;
+     298           2 :   Tools::convert(values[0],str_value);
+     299           4 :   str_keywordvalues = keyword + "=" + str_value;
+     300           5 :   for(unsigned int i=1; i<values.size(); i++) {
+     301           3 :     Tools::convert(values[i],str_value);
+     302           6 :     str_keywordvalues += "," + str_value;
+     303             :   }
+     304           2 :   bf_keywords_.push_back(str_keywordvalues);
+     305           2 : }
+     306             : 
+     307             : 
+     308             : inline
+     309             : void BasisFunctions::addKeywordToList(const std::string& keyword, const bool value) {
+     310          87 :   if(value) {bf_keywords_.push_back(keyword);}
+     311             : }
+     312             : 
+     313             : 
+     314             : }
+     315             : }
+     316             : 
+     317             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.cpp.func-sort-c.html b/coverage/ves/CoeffsBase.cpp.func-sort-c.html new file mode 100644 index 000000000000..817da8bc68ac --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.func-sort-c.html @@ -0,0 +1,201 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12730142.2 %
Date:2024-02-22 21:58:45Functions:153246.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10CoeffsBase10linkActionEPNS_6ActionE0
_ZN4PLMD3ves10CoeffsBase12setDataLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase13resizeIndicesERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves10CoeffsBase13resizeIndicesERSt6vectorIPNS0_14BasisFunctionsESaIS4_EE0
_ZN4PLMD3ves10CoeffsBase17setDimensionLabelEjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase19reinitializeIndicesERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves10CoeffsBase19setCoeffDescriptionERKSt6vectorIjSaIjEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase21setAllDimensionLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase21setAllDimensionLabelsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE0
_ZN4PLMD3ves10CoeffsBase24setAllCoeffsDescriptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase24setAllCoeffsDescriptionsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE0
_ZN4PLMD3ves10CoeffsBase7setTypeENS1_10CoeffsTypeE0
_ZN4PLMD3ves10CoeffsBase8setLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase9setLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_0
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEEb0
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EEbS9_0
_ZNK4PLMD3ves10CoeffsBase12indicesExistERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves10CoeffsBase18replaceLabelStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_5
_ZNK4PLMD3ves10CoeffsBase9sameShapeERKS1_6
_ZN4PLMD3ves10CoeffsBase11linkVesBiasEPNS0_7VesBiasE90
_ZN4PLMD3ves10CoeffsBase15checkCoeffsInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_jmRKSt6vectorIjSaIjEE368
_ZN4PLMD3ves10CoeffsBase21getCoeffsInfoFromFileERNS_5IFileEb368
_ZN4PLMD3ves10CoeffsBase17initializeIndicesERKSt6vectorIjSaIjEERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISC_EE377
_ZN4PLMD3ves10CoeffsBase23setupBasisFunctionsInfoEv377
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISI_EEb377
_ZN4PLMD3ves10CoeffsBase34getIterationCounterAndTimeFromFileERNS_5IFileE406
_ZN4PLMD3ves10CoeffsBase9setLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE754
_ZNK4PLMD3ves10CoeffsBase34writeIterationCounterAndTimeToFileERNS_5OFileE2721
_ZNK4PLMD3ves10CoeffsBase21writeCoeffsInfoToFileERNS_5OFileE3008
_ZNK4PLMD3ves10CoeffsBase10getTypeStrB5cxx11Ev3376
_ZN4PLMD3ves10CoeffsBase19setCoeffDescriptionEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8928
_ZN4PLMD3ves10CoeffsBaseD2Ev342134
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.cpp.func.html b/coverage/ves/CoeffsBase.cpp.func.html new file mode 100644 index 000000000000..894afbedf751 --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.func.html @@ -0,0 +1,201 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12730142.2 %
Date:2024-02-22 21:58:45Functions:153246.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10CoeffsBase10linkActionEPNS_6ActionE0
_ZN4PLMD3ves10CoeffsBase11linkVesBiasEPNS0_7VesBiasE90
_ZN4PLMD3ves10CoeffsBase12setDataLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase13resizeIndicesERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves10CoeffsBase13resizeIndicesERSt6vectorIPNS0_14BasisFunctionsESaIS4_EE0
_ZN4PLMD3ves10CoeffsBase15checkCoeffsInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_jmRKSt6vectorIjSaIjEE368
_ZN4PLMD3ves10CoeffsBase17initializeIndicesERKSt6vectorIjSaIjEERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISC_EE377
_ZN4PLMD3ves10CoeffsBase17setDimensionLabelEjRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase18replaceLabelStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_5
_ZN4PLMD3ves10CoeffsBase19reinitializeIndicesERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves10CoeffsBase19setCoeffDescriptionERKSt6vectorIjSaIjEERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase19setCoeffDescriptionEmRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8928
_ZN4PLMD3ves10CoeffsBase21getCoeffsInfoFromFileERNS_5IFileEb368
_ZN4PLMD3ves10CoeffsBase21setAllDimensionLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase21setAllDimensionLabelsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE0
_ZN4PLMD3ves10CoeffsBase23setupBasisFunctionsInfoEv377
_ZN4PLMD3ves10CoeffsBase24setAllCoeffsDescriptionsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase24setAllCoeffsDescriptionsERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE0
_ZN4PLMD3ves10CoeffsBase34getIterationCounterAndTimeFromFileERNS_5IFileE406
_ZN4PLMD3ves10CoeffsBase7setTypeENS1_10CoeffsTypeE0
_ZN4PLMD3ves10CoeffsBase8setLabelERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD3ves10CoeffsBase9setLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE754
_ZN4PLMD3ves10CoeffsBase9setLabelsERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_0
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISI_EEb377
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEEb0
_ZN4PLMD3ves10CoeffsBaseC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EEbS9_0
_ZN4PLMD3ves10CoeffsBaseD2Ev342134
_ZNK4PLMD3ves10CoeffsBase10getTypeStrB5cxx11Ev3376
_ZNK4PLMD3ves10CoeffsBase12indicesExistERKSt6vectorIjSaIjEE0
_ZNK4PLMD3ves10CoeffsBase21writeCoeffsInfoToFileERNS_5OFileE3008
_ZNK4PLMD3ves10CoeffsBase34writeIterationCounterAndTimeToFileERNS_5OFileE2721
_ZNK4PLMD3ves10CoeffsBase9sameShapeERKS1_6
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.cpp.gcov.html b/coverage/ves/CoeffsBase.cpp.gcov.html new file mode 100644 index 000000000000..d2eb63956ded --- /dev/null +++ b/coverage/ves/CoeffsBase.cpp.gcov.html @@ -0,0 +1,594 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:12730142.2 %
Date:2024-02-22 21:58:45Functions:153246.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "CoeffsBase.h"
+      24             : #include "BasisFunctions.h"
+      25             : #include "VesBias.h"
+      26             : 
+      27             : #include "tools/Tools.h"
+      28             : #include "tools/File.h"
+      29             : #include "tools/Exception.h"
+      30             : #include "core/Value.h"
+      31             : 
+      32             : #include <vector>
+      33             : #include <string>
+      34             : 
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace ves {
+      38             : 
+      39           0 : CoeffsBase::CoeffsBase(
+      40             :   const std::string& label,
+      41             :   const std::vector<std::string>& dimension_labels,
+      42             :   const std::vector<unsigned int>& indices_shape,
+      43           0 :   const bool use_iteration_counter):
+      44           0 :   label_(label),
+      45           0 :   data_label_(label),
+      46           0 :   coeffs_type_(Generic),
+      47           0 :   iteration_and_time_active_(use_iteration_counter),
+      48           0 :   iteration_opt(0),
+      49           0 :   time_md(-1.0),
+      50           0 :   active(true),
+      51           0 :   action_pntr_(NULL),
+      52           0 :   vesbias_pntr_(NULL),
+      53           0 :   ndimensions_(0),
+      54           0 :   indices_shape_(0),
+      55           0 :   ncoeffs_(0),
+      56           0 :   coeffs_descriptions_(0),
+      57           0 :   dimension_labels_(0),
+      58           0 :   args_(0),
+      59           0 :   basisf_(0),
+      60           0 :   multicoeffs_(false),
+      61           0 :   multicoeffs_args_(0),
+      62           0 :   multicoeffs_basisf_(0),
+      63           0 :   field_type_("type"),
+      64           0 :   field_ndimensions_("ndimensions"),
+      65           0 :   field_ncoeffs_total_("ncoeffs_total"),
+      66           0 :   field_shape_prefix_("shape_"),
+      67           0 :   field_time_("time"),
+      68           0 :   field_iteration_("iteration"),
+      69           0 :   output_fmt_("%30.16e")
+      70             : {
+      71           0 :   initializeIndices(indices_shape,dimension_labels);
+      72           0 :   setAllCoeffsDescriptions();
+      73           0 : }
+      74             : 
+      75             : 
+      76         377 : CoeffsBase::CoeffsBase(
+      77             :   const std::string& label,
+      78             :   const std::vector<Value*>& args,
+      79             :   std::vector<BasisFunctions*>& basisf,
+      80         377 :   const bool use_iteration_counter):
+      81         377 :   label_(label),
+      82         377 :   data_label_(label),
+      83         377 :   coeffs_type_(LinearBasisSet),
+      84         377 :   iteration_and_time_active_(use_iteration_counter),
+      85         377 :   iteration_opt(0),
+      86         377 :   time_md(-1.0),
+      87         377 :   active(true),
+      88         377 :   action_pntr_(NULL),
+      89         377 :   vesbias_pntr_(NULL),
+      90         377 :   ndimensions_(0),
+      91         377 :   indices_shape_(0),
+      92         377 :   ncoeffs_(0),
+      93         377 :   coeffs_descriptions_(0),
+      94         377 :   dimension_labels_(0),
+      95         377 :   args_(args),
+      96         377 :   basisf_(basisf),
+      97         377 :   multicoeffs_(false),
+      98         377 :   multicoeffs_args_(0),
+      99         377 :   multicoeffs_basisf_(0),
+     100         377 :   field_type_("type"),
+     101         377 :   field_ndimensions_("ndimensions"),
+     102         377 :   field_ncoeffs_total_("ncoeffs_total"),
+     103         377 :   field_shape_prefix_("shape_"),
+     104         377 :   field_time_("time"),
+     105         377 :   field_iteration_("iteration"),
+     106         377 :   output_fmt_("%30.16e")
+     107             : {
+     108         377 :   plumed_massert(args_.size()==basisf_.size(),"CoeffsBase: number of arguments do not match number of basis functions");
+     109         377 :   std::vector<std::string> dimension_labels(args_.size());
+     110         377 :   std::vector<unsigned int> indices_shape(args_.size());
+     111         789 :   for(unsigned int i=0; i<args_.size(); i++) {
+     112         412 :     dimension_labels[i]=args_[i]->getName();
+     113         412 :     indices_shape[i]=basisf_[i]->getNumberOfBasisFunctions();
+     114             :   }
+     115         377 :   initializeIndices(indices_shape,dimension_labels);
+     116         377 :   setupBasisFunctionsInfo();
+     117         377 : }
+     118             : 
+     119             : 
+     120           0 : CoeffsBase::CoeffsBase(
+     121             :   const std::string& label,
+     122             :   std::vector<std::vector<Value*> >& multicoeffs_args,
+     123             :   std::vector<std::vector<BasisFunctions*> >& multicoeffs_basisf,
+     124             :   const bool use_iteration_counter,
+     125           0 :   const std::string& multicoeffs_label):
+     126           0 :   label_(label),
+     127           0 :   data_label_(label),
+     128           0 :   coeffs_type_(MultiCoeffs_LinearBasisSet),
+     129           0 :   iteration_and_time_active_(use_iteration_counter),
+     130           0 :   iteration_opt(0),
+     131           0 :   time_md(-1.0),
+     132           0 :   active(true),
+     133           0 :   action_pntr_(NULL),
+     134           0 :   vesbias_pntr_(NULL),
+     135           0 :   ndimensions_(0),
+     136           0 :   indices_shape_(0),
+     137           0 :   ncoeffs_(0),
+     138           0 :   coeffs_descriptions_(0),
+     139           0 :   dimension_labels_(0),
+     140           0 :   args_(0),
+     141           0 :   basisf_(0),
+     142           0 :   multicoeffs_(true),
+     143           0 :   multicoeffs_args_(multicoeffs_args),
+     144           0 :   multicoeffs_basisf_(multicoeffs_basisf),
+     145           0 :   field_type_("type"),
+     146           0 :   field_ndimensions_("ndimensions"),
+     147           0 :   field_ncoeffs_total_("ncoeffs_total"),
+     148           0 :   field_shape_prefix_("shape_"),
+     149           0 :   field_time_("time"),
+     150           0 :   field_iteration_("iteration"),
+     151           0 :   output_fmt_("%30.16e")
+     152             : {
+     153           0 :   plumed_massert(multicoeffs_args.size()==multicoeffs_basisf.size(),"Multi Coeffs: number of arguments vectors does not match number of basis functions vectors");
+     154           0 :   unsigned int num_args = multicoeffs_args[0].size();
+     155           0 :   unsigned int dim = num_args+1;
+     156           0 :   std::vector<std::string> dimension_labels(dim);
+     157           0 :   std::vector<unsigned int> indices_shape(dim);
+     158           0 :   for(unsigned int i=0; i<num_args; i++) {
+     159             :     std::string ip;
+     160           0 :     Tools::convert(i+1,ip);
+     161           0 :     dimension_labels[i] = "bf" + ip;
+     162           0 :     indices_shape[i] = multicoeffs_basisf[0][i]->getNumberOfBasisFunctions();
+     163             :   }
+     164           0 :   indices_shape[dim-1] = multicoeffs_args.size();
+     165             :   dimension_labels[dim-1] = multicoeffs_label;
+     166           0 :   for(unsigned int k=0; k<multicoeffs_args.size(); k++) {
+     167           0 :     plumed_massert(multicoeffs_args[k].size()==num_args && multicoeffs_basisf[k].size()==num_args,"Multi Coeffs: arguments and basis functions vectors for each bias should be of the same size");
+     168           0 :     for(unsigned int i=0; i<num_args; i++) {
+     169           0 :       plumed_massert(indices_shape[i]==multicoeffs_basisf[k][i]->getNumberOfBasisFunctions(),"Multi Coeffs: the coeffs shape for each bias should be identical");
+     170             :     }
+     171             :   }
+     172           0 :   initializeIndices(indices_shape,dimension_labels);
+     173           0 :   setupBasisFunctionsInfo();
+     174           0 : }
+     175             : 
+     176             : 
+     177     1026402 : CoeffsBase::~CoeffsBase() {}
+     178             : 
+     179             : 
+     180         377 : void CoeffsBase::initializeIndices(const std::vector<unsigned int>& indices_shape, const std::vector<std::string>& dimension_labels) {
+     181         377 :   plumed_massert(indices_shape.size()==dimension_labels.size(),"indices shape and dimension labels must be of the same size");
+     182         377 :   ndimensions_=indices_shape.size();
+     183         377 :   indices_shape_=indices_shape;
+     184         377 :   dimension_labels_=dimension_labels;
+     185         377 :   ncoeffs_=1;
+     186         789 :   for(unsigned int i=0; i<ndimensions_; i++) {
+     187         412 :     ncoeffs_*=indices_shape_[i];
+     188             :   }
+     189         377 :   coeffs_descriptions_.resize(ncoeffs_);
+     190         377 : }
+     191             : 
+     192             : 
+     193           0 : void CoeffsBase::reinitializeIndices(const std::vector<unsigned int>& indices_shape_new) {
+     194           0 :   plumed_massert(indices_shape_.size()>0,"indices must have been previously initialized before using this function");
+     195           0 :   plumed_massert(dimension_labels_.size()>0,"indices must have been previously initialized before using this function");
+     196           0 :   plumed_massert(indices_shape_new.size()==numberOfDimensions(),"when resizeing Coeffs the dimension must be constant");
+     197           0 :   indices_shape_=indices_shape_new;
+     198           0 :   ncoeffs_=1;
+     199           0 :   for(unsigned int i=0; i<ndimensions_; i++) {
+     200           0 :     ncoeffs_*=indices_shape_[i];
+     201             :   }
+     202           0 :   coeffs_descriptions_.clear();
+     203           0 :   coeffs_descriptions_.resize(ncoeffs_);
+     204           0 : }
+     205             : 
+     206             : 
+     207         377 : void CoeffsBase::setupBasisFunctionsInfo() {
+     208         377 :   plumed_massert(indices_shape_.size()>0,"indices must be initialized before running this function");
+     209         377 :   if(coeffs_type_==LinearBasisSet) {
+     210        9305 :     for(unsigned int i=0; i<numberOfCoeffs(); i++) {
+     211        8928 :       std::vector<unsigned int> indices=getIndices(i);
+     212             :       std::string desc;
+     213        8928 :       desc=basisf_[0]->getBasisFunctionLabel(indices[0]);
+     214       13409 :       for(unsigned int k=1; k<numberOfDimensions(); k++) {
+     215        8962 :         desc+="*"+basisf_[k]->getBasisFunctionLabel(indices[k]);
+     216             :       }
+     217        8928 :       setCoeffDescription(i,desc);
+     218             :     }
+     219             :   }
+     220           0 :   else if(coeffs_type_==MultiCoeffs_LinearBasisSet) {
+     221           0 :     for(unsigned int i=0; i<numberOfCoeffs(); i++) {
+     222           0 :       std::vector<unsigned int> indices=getIndices(i);
+     223           0 :       unsigned int mc_id = indices[ndimensions_-1];
+     224             :       std::string mc_idstr;
+     225           0 :       Tools::convert(mc_id,mc_idstr);
+     226             :       // std::string mc_label = getDimensionLabel(ndimensions_-1);
+     227           0 :       std::string postfix = ":" + mc_idstr;
+     228           0 :       std::string desc ="";
+     229           0 :       desc+=multicoeffs_basisf_[mc_id][0]->getBasisFunctionLabel(indices[0]);
+     230           0 :       for(unsigned int k=1; k<(numberOfDimensions()-1); k++) {
+     231           0 :         desc+="*"+multicoeffs_basisf_[mc_id][k]->getBasisFunctionLabel(indices[k]);
+     232             :       }
+     233             :       desc+=postfix;
+     234           0 :       setCoeffDescription(i,desc);
+     235             :     }
+     236             :   }
+     237         377 : }
+     238             : 
+     239             : 
+     240           0 : void CoeffsBase::resizeIndices(const std::vector<unsigned int>& indices_shape_new) {
+     241           0 :   plumed_massert(coeffs_type_==Generic,"Coeffs type must be Generic when resizeing based on a new indices shape vector");
+     242           0 :   reinitializeIndices(indices_shape_new);
+     243           0 :   setAllCoeffsDescriptions();
+     244           0 : }
+     245             : 
+     246             : 
+     247           0 : void CoeffsBase::resizeIndices(std::vector<BasisFunctions*>& basisf_new) {
+     248           0 :   plumed_massert(coeffs_type_==LinearBasisSet,"Coeffs type must be LinearBasisSet when resizeing based on a new basis function set");
+     249           0 :   basisf_=basisf_new;
+     250           0 :   std::vector<unsigned int> indices_shape_new(basisf_new.size());
+     251           0 :   for(unsigned int i=0; i<basisf_new.size(); i++) {
+     252           0 :     indices_shape_new[i]=basisf_new[i]->getNumberOfBasisFunctions();
+     253             :   }
+     254           0 :   reinitializeIndices(indices_shape_new);
+     255           0 :   setupBasisFunctionsInfo();
+     256           0 : }
+     257             : 
+     258             : 
+     259           6 : bool CoeffsBase::sameShape(const CoeffsBase& coeffsbase_in) const {
+     260           6 :   if(numberOfDimensions()!=coeffsbase_in.numberOfDimensions()) {
+     261             :     return false;
+     262             :   }
+     263           6 :   if(numberOfCoeffs()!=coeffsbase_in.numberOfCoeffs()) {
+     264             :     return false;
+     265             :   }
+     266          12 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     267           6 :     if(shapeOfIndices(k)!=coeffsbase_in.shapeOfIndices(k)) {
+     268             :       return false;
+     269             :     }
+     270             :   }
+     271             :   return true;
+     272             : }
+     273             : 
+     274             : 
+     275           0 : void CoeffsBase::setLabel(const std::string& label) {
+     276           0 :   label_=label;
+     277           0 : }
+     278             : 
+     279             : 
+     280           0 : void CoeffsBase::setDataLabel(const std::string& data_label) {
+     281           0 :   data_label_=data_label;
+     282           0 : }
+     283             : 
+     284             : 
+     285         754 : void CoeffsBase::setLabels(const std::string& label) {
+     286         754 :   label_=label;
+     287         754 :   data_label_=label;
+     288         754 : }
+     289             : 
+     290             : 
+     291           0 : void CoeffsBase::setLabels(const std::string& label, const std::string& data_label) {
+     292           0 :   label_=label;
+     293           0 :   data_label_=data_label;
+     294           0 : }
+     295             : 
+     296             : 
+     297        3376 : std::string CoeffsBase::getTypeStr() const {
+     298        3376 :   std::string type_str="";
+     299        3376 :   if(coeffs_type_==Generic) {
+     300             :     type_str = "Generic";
+     301             :   }
+     302        3376 :   else if(coeffs_type_==LinearBasisSet) {
+     303             :     type_str = "LinearBasisSet";
+     304             :   }
+     305           0 :   else if(coeffs_type_==MultiCoeffs_LinearBasisSet) {
+     306             :     type_str = "MultiCoeffs_LinearBasisSet";
+     307             :   }
+     308        3376 :   return type_str;
+     309             : }
+     310             : 
+     311             : 
+     312           0 : void CoeffsBase::setType(const CoeffsType coeffs_type) {
+     313           0 :   coeffs_type_=coeffs_type;
+     314           0 : }
+     315             : 
+     316             : 
+     317          90 : void CoeffsBase::linkVesBias(VesBias* vesbias_pntr_in) {
+     318          90 :   vesbias_pntr_ = vesbias_pntr_in;
+     319          90 :   action_pntr_ = static_cast<Action*>(vesbias_pntr_in);
+     320          90 : }
+     321             : 
+     322             : 
+     323           0 : void CoeffsBase::linkAction(Action* action_pntr_in) {
+     324           0 :   action_pntr_ = action_pntr_in;
+     325           0 : }
+     326             : 
+     327             : 
+     328           0 : bool CoeffsBase::indicesExist(const std::vector<unsigned int>& indices) const {
+     329             :   plumed_dbg_assert(indices.size()==ndimensions_);
+     330           0 :   for(unsigned int k=0; k<ndimensions_; k++) {
+     331           0 :     if(indices[k]>=indices_shape_[k]) {
+     332             :       return false;
+     333             :     }
+     334             :   }
+     335             :   return true;
+     336             : }
+     337             : 
+     338             : 
+     339        8928 : void CoeffsBase::setCoeffDescription(const size_t index, const std::string& description) {
+     340             :   coeffs_descriptions_[index]=description;
+     341        8928 : }
+     342             : 
+     343             : 
+     344           0 : void CoeffsBase::setCoeffDescription(const std::vector<unsigned int>& indices, const std::string& description) {
+     345           0 :   setCoeffDescription(getIndex(indices), description);
+     346           0 : }
+     347             : 
+     348             : 
+     349           0 : void CoeffsBase::setAllCoeffsDescriptions(const std::string& description_prefix) {
+     350           0 :   for(size_t i=0; i<numberOfCoeffs(); i++) {
+     351           0 :     std::vector<unsigned int> indices=getIndices(i);
+     352           0 :     std::string is; Tools::convert(indices[0],is);
+     353           0 :     std::string desc=description_prefix+"("+is;
+     354           0 :     for(unsigned int k=1; k<numberOfDimensions(); k++) {
+     355           0 :       Tools::convert(indices[k],is); desc+=","+is;
+     356             :     }
+     357             :     desc+=")";
+     358             :     coeffs_descriptions_[i]=desc;
+     359             :   }
+     360           0 : }
+     361             : 
+     362             : 
+     363           0 : void CoeffsBase::setAllCoeffsDescriptions(const std::vector<std::string>& coeffs_descriptions) {
+     364           0 :   plumed_massert(coeffs_descriptions.size()==numberOfCoeffs(),"The coeffs description vector doesn't match the number of coeffs");
+     365           0 :   for(size_t i=0; i<numberOfCoeffs(); i++) {
+     366             :     coeffs_descriptions_[i]=coeffs_descriptions[i];
+     367             :   }
+     368           0 : }
+     369             : 
+     370             : 
+     371           0 : void CoeffsBase::setDimensionLabel(const unsigned int dim_index, const std::string& label) {
+     372           0 :   plumed_massert(dim_index<numberOfDimensions(),"Trying to set the label of a dimension outside the number of dimensions");
+     373           0 :   dimension_labels_[dim_index]=label;
+     374           0 : }
+     375             : 
+     376             : 
+     377           0 : void CoeffsBase::setAllDimensionLabels(const std::string& label_prefix) {
+     378           0 :   for(unsigned int i=0; i<numberOfDimensions(); i++) {
+     379           0 :     std::string is; Tools::convert(i,is);
+     380           0 :     dimension_labels_[i]=label_prefix + is;
+     381             :   }
+     382           0 : }
+     383             : 
+     384             : 
+     385           0 : void CoeffsBase::setAllDimensionLabels(const std::vector<std::string>& labels) {
+     386           0 :   for(unsigned int i=0; i<numberOfDimensions(); i++) {
+     387           0 :     dimension_labels_[i]=labels[i];
+     388             :   }
+     389           0 : }
+     390             : 
+     391             : 
+     392        3008 : void CoeffsBase::writeCoeffsInfoToFile(OFile& ofile) const {
+     393        3008 :   ofile.addConstantField(field_type_).printField(field_type_,getTypeStr());
+     394        3008 :   ofile.addConstantField(field_ndimensions_).printField(field_ndimensions_,(int) numberOfDimensions());
+     395        3008 :   ofile.addConstantField(field_ncoeffs_total_).printField(field_ncoeffs_total_,(int) numberOfCoeffs());
+     396        6780 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     397        7544 :     ofile.addConstantField(field_shape_prefix_+getDimensionLabel(k));
+     398        7544 :     ofile.printField(field_shape_prefix_+getDimensionLabel(k),(int) shapeOfIndices(k));
+     399             :   }
+     400        3008 : }
+     401             : 
+     402             : 
+     403         368 : void CoeffsBase::getCoeffsInfoFromFile(IFile& ifile, const bool ignore_coeffs_info) {
+     404             :   int int_tmp;
+     405             :   // label
+     406             :   std::string coeffs_type_f;
+     407         368 :   if(ifile.scanField(field_type_,coeffs_type_f)) {
+     408             :     // empty for now
+     409             :   }
+     410             :   else {
+     411             :     return;
+     412             :   }
+     413             :   // number of dimensions
+     414             :   unsigned int ndimensions_f = 0;
+     415         368 :   if(ifile.scanField(field_ndimensions_,int_tmp)) {
+     416         368 :     ndimensions_f=(unsigned int) int_tmp;
+     417             :   }
+     418             :   else {
+     419             :     return;
+     420             :   }
+     421             :   // total number of coeffs
+     422             :   size_t ncoeffs_total_f = 0;
+     423         368 :   if(ifile.scanField(field_ncoeffs_total_,int_tmp)) {
+     424         368 :     ncoeffs_total_f=(size_t) int_tmp;
+     425             :   }
+     426             :   else {
+     427             :     return;
+     428             :   }
+     429             :   // shape of indices
+     430         368 :   std::vector<unsigned int> indices_shape_f(numberOfDimensions());
+     431         747 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     432         758 :     if(ifile.scanField(field_shape_prefix_+getDimensionLabel(k),int_tmp)) {
+     433         379 :       indices_shape_f[k]=(unsigned int) int_tmp;
+     434             :     }
+     435             :     else {
+     436             :       return;
+     437             :     }
+     438             :   }
+     439         368 :   if(!ignore_coeffs_info) {
+     440         736 :     std::string msg_header="Error when reading in coeffs from file " + ifile.getPath() + ": ";
+     441         368 :     checkCoeffsInfo(msg_header, coeffs_type_f, ndimensions_f, ncoeffs_total_f, indices_shape_f);
+     442             :   }
+     443             : }
+     444             : 
+     445             : 
+     446         368 : void CoeffsBase::checkCoeffsInfo(const std::string& msg_header, const std::string& coeffs_type_f, const unsigned int ndimensions_f, const size_t ncoeffs_total_f, const std::vector<unsigned int>& indices_shape_f) {
+     447             : 
+     448         736 :   if(coeffs_type_f != getTypeStr()) {
+     449           0 :     std::string msg = msg_header + " coeffs type " + coeffs_type_f + " from file doesn't match the defined value " + getTypeStr();
+     450           0 :     plumed_merror(msg);
+     451             :   }
+     452         368 :   if(ndimensions_f != numberOfDimensions() ) {
+     453           0 :     std::string s1; Tools::convert(ndimensions_f,s1);
+     454           0 :     std::string s2; Tools::convert(numberOfDimensions(),s2);
+     455           0 :     std::string msg = msg_header + " the number of dimensions " + s1 + " in file doesn't match the defined value " + s2;
+     456           0 :     plumed_merror(msg);
+     457             :   }
+     458         368 :   if(ncoeffs_total_f != numberOfCoeffs() ) {
+     459           0 :     std::string s1; Tools::convert(ncoeffs_total_f,s1);
+     460           0 :     std::string s2; Tools::convert(numberOfCoeffs(),s2);
+     461           0 :     std::string msg = msg_header + " the number of coeffs " + s1 + " in file doesn't match the defined value " + s2;
+     462           0 :     plumed_merror(msg);
+     463             :   }
+     464         747 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     465         379 :     if(indices_shape_f[k] != shapeOfIndices(k) ) {
+     466           0 :       std::string s1; Tools::convert(indices_shape_f[k],s1);
+     467           0 :       std::string s2; Tools::convert(shapeOfIndices(k),s2);
+     468           0 :       std::string msg = msg_header + " for dimension labeled " + getDimensionLabel(k) + " the shape of indices " + s1 + " in file doesn't match defined value " + s2;
+     469           0 :       plumed_merror(msg);
+     470             :     }
+     471             :   }
+     472         368 : }
+     473             : 
+     474             : 
+     475        2721 : void CoeffsBase::writeIterationCounterAndTimeToFile(OFile& ofile) const {
+     476        2721 :   if(time_md>=0.0) {
+     477        2721 :     ofile.fmtField("%f");
+     478        2721 :     ofile.addConstantField(field_time_).printField(field_time_,time_md);
+     479        2721 :     ofile.fmtField();
+     480             :   }
+     481        2721 :   ofile.addConstantField(field_iteration_).printField(field_iteration_,(int) iteration_opt);
+     482        2721 : }
+     483             : 
+     484             : 
+     485         406 : bool CoeffsBase::getIterationCounterAndTimeFromFile(IFile& ifile) {
+     486             :   bool field_found=false;
+     487         406 :   if(ifile.FieldExist(field_time_)) {
+     488             :     field_found=true;
+     489             :     double time_tmp;
+     490         368 :     ifile.scanField(field_time_,time_tmp);
+     491         368 :     time_md=time_tmp;
+     492             :   }
+     493         406 :   if(ifile.FieldExist(field_iteration_)) {
+     494             :     field_found=true;
+     495             :     int iter_tmp;
+     496         368 :     ifile.scanField(field_iteration_,iter_tmp);
+     497         368 :     iteration_opt=(unsigned int) iter_tmp;
+     498             :   }
+     499         406 :   return field_found;
+     500             : }
+     501             : 
+     502             : 
+     503             : // replace string in Label, if old string was not found simply add the new string to the label
+     504           5 : void CoeffsBase::replaceLabelString(const std::string& oldstring, const std::string& newstring) {
+     505             :   std::string label = getLabel();
+     506           5 :   if(label.find(oldstring)!=std::string::npos) {
+     507           8 :     label.replace(label.find(oldstring), std::string(oldstring).length(), newstring);
+     508             :   }
+     509             :   else {
+     510           2 :     label += "_" + newstring;
+     511             :   }
+     512           5 :   setLabels(label);
+     513           5 : }
+     514             : 
+     515             : 
+     516             : }
+     517             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.h.func-sort-c.html b/coverage/ves/CoeffsBase.h.func-sort-c.html new file mode 100644 index 000000000000..f1264a97b088 --- /dev/null +++ b/coverage/ves/CoeffsBase.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves10CoeffsBase8getIndexERKSt6vectorIjSaIjEE10870
_ZNK4PLMD3ves10CoeffsBase10getIndicesEm237974265
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.h.func.html b/coverage/ves/CoeffsBase.h.func.html new file mode 100644 index 000000000000..b8dbb998884a --- /dev/null +++ b/coverage/ves/CoeffsBase.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves10CoeffsBase10getIndicesEm237974265
_ZNK4PLMD3ves10CoeffsBase8getIndexERKSt6vectorIjSaIjEE10870
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsBase.h.gcov.html b/coverage/ves/CoeffsBase.h.gcov.html new file mode 100644 index 000000000000..af2f49a95880 --- /dev/null +++ b/coverage/ves/CoeffsBase.h.gcov.html @@ -0,0 +1,336 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsBase.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsBase.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3333100.0 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_CoeffsBase_h
+      23             : #define __PLUMED_ves_CoeffsBase_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <string>
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : 
+      31             : class Action;
+      32             : class Value;
+      33             : class IFile;
+      34             : class OFile;
+      35             : 
+      36             : namespace ves {
+      37             : 
+      38             : class BasisFunctions;
+      39             : class VesBias;
+      40             : 
+      41             : /// \ingroup TOOLBOX
+      42             : class CoeffsBase
+      43             : {
+      44             : public:
+      45             :   // the type of 1D index
+      46             :   // typedef size_t index_t;
+      47             :   // typedef unsigned int index_t;
+      48             : private:
+      49             :   std::string label_;
+      50             :   std::string data_label_;
+      51             :   enum CoeffsType {
+      52             :     Generic,
+      53             :     LinearBasisSet,
+      54             :     MultiCoeffs_LinearBasisSet
+      55             :   } coeffs_type_;
+      56             :   //
+      57             :   bool iteration_and_time_active_;
+      58             :   unsigned int iteration_opt;
+      59             :   double time_md;
+      60             :   //
+      61             :   bool active;
+      62             :   //
+      63             :   Action* action_pntr_;
+      64             :   VesBias* vesbias_pntr_;
+      65             :   //
+      66             :   unsigned int ndimensions_;
+      67             :   std::vector<unsigned int> indices_shape_;
+      68             :   size_t ncoeffs_;
+      69             :   std::vector<std::string> coeffs_descriptions_;
+      70             :   std::vector<std::string> dimension_labels_;
+      71             :   //
+      72             :   std::vector<Value*> args_;
+      73             :   std::vector<BasisFunctions*> basisf_;
+      74             :   //
+      75             :   bool multicoeffs_;
+      76             :   std::vector<std::vector<Value*> > multicoeffs_args_;
+      77             :   std::vector<std::vector<BasisFunctions*> >multicoeffs_basisf_;
+      78             :   // Labels for fields in output/input files
+      79             :   const std::string field_type_;
+      80             :   const std::string field_ndimensions_;
+      81             :   const std::string field_ncoeffs_total_;
+      82             :   const std::string field_shape_prefix_;
+      83             :   const std::string field_time_;
+      84             :   const std::string field_iteration_;
+      85             :   //
+      86             :   std::string output_fmt_;
+      87             :   //
+      88             :   void initializeIndices(const std::vector<unsigned int>&, const std::vector<std::string>&);
+      89             :   void reinitializeIndices(const std::vector<unsigned int>&);
+      90             : public:
+      91             :   explicit CoeffsBase();
+      92             :   //
+      93             :   explicit CoeffsBase(
+      94             :     const std::string&,
+      95             :     const std::vector<std::string>&,
+      96             :     const std::vector<unsigned int>&,
+      97             :     const bool use_iteration_counter=false);
+      98             :   //
+      99             :   explicit CoeffsBase(
+     100             :     const std::string&,
+     101             :     const std::vector<Value*>&,
+     102             :     std::vector<BasisFunctions*>&,
+     103             :     const bool use_iteration_counter=false);
+     104             :   //
+     105             :   explicit CoeffsBase(
+     106             :     const std::string&,
+     107             :     std::vector<std::vector<Value*> >&,
+     108             :     std::vector<std::vector<BasisFunctions*> >&,
+     109             :     const bool use_iteration_counter=false,
+     110             :     const std::string& multicoeffs_label="bias"
+     111             :   );
+     112             :   //
+     113             :   ~CoeffsBase();
+     114             :   //
+     115         228 :   std::string getLabel() const {return label_;}
+     116             :   void setLabel(const std::string&);
+     117        4366 :   std::string getDataLabel() const {return data_label_;};
+     118             :   void setDataLabel(const std::string&);
+     119             :   void setLabels(const std::string&);
+     120             :   void setLabels(const std::string&, const std::string&);
+     121             :   //
+     122             :   CoeffsType getType() const {return coeffs_type_;}
+     123             :   std::string getTypeStr() const;
+     124             :   void setType(const CoeffsType coeffs_type);
+     125             :   void linkVesBias(VesBias*);
+     126             :   void linkAction(Action*);
+     127             :   VesBias* getPntrToVesBias() const {return vesbias_pntr_;}
+     128           9 :   Action* getPntrToAction() const {return action_pntr_;}
+     129             :   bool isGenericCoeffs() const {return coeffs_type_==Generic;}
+     130             :   bool isLinearBasisSetCoeffs() const {return coeffs_type_==LinearBasisSet;}
+     131             :   bool isMultiLinearBasisSetCoeffs() const {return coeffs_type_==MultiCoeffs_LinearBasisSet;}
+     132             :   //
+     133             :   std::vector<unsigned int> shapeOfIndices() const {return indices_shape_;}
+     134        4157 :   unsigned int shapeOfIndices(const unsigned int dim_index) const {return indices_shape_[dim_index];}
+     135   243037069 :   size_t numberOfCoeffs() const {return ncoeffs_;}
+     136     2992522 :   unsigned int numberOfDimensions() const {return ndimensions_;}
+     137             :   //
+     138       22810 :   bool isActive() const {return active;}
+     139       22810 :   void activate() {active=true;}
+     140          95 :   void deactivate() {active=false;}
+     141             :   //
+     142             :   size_t getIndex(const std::vector<unsigned int>&) const;
+     143             :   std::vector<unsigned int> getIndices(const size_t) const;
+     144             :   bool indicesExist(const std::vector<unsigned int>&) const;
+     145             :   //
+     146             :   std::string getCoeffDescription(const size_t index) const {return coeffs_descriptions_[index];}
+     147             :   std::string getCoeffDescription(const std::vector<unsigned int>&) const;
+     148        2348 :   std::vector<std::string> getAllCoeffsDescriptions() const {return coeffs_descriptions_;}
+     149             :   void setCoeffDescription(const size_t, const std::string&);
+     150             :   void setCoeffDescription(const std::vector<unsigned int>&, const std::string&);
+     151             :   void setAllCoeffsDescriptions(const std::string& description_prefix="C");
+     152             :   void setAllCoeffsDescriptions(const std::vector<std::string>&);
+     153             :   //
+     154             :   std::string getDimensionLabel(const unsigned int) const;
+     155             :   std::vector<std::string> getAllDimensionLabels() const {return dimension_labels_;}
+     156             :   void setDimensionLabel(const unsigned int, const std::string&);
+     157             :   void setAllDimensionLabels(const std::string&);
+     158             :   void setAllDimensionLabels(const std::vector<std::string>&);
+     159             :   void writeCoeffsInfoToFile(OFile&) const;
+     160             :   void writeTimeInfoToFile(OFile&, const double) const;
+     161             :   void getCoeffsInfoFromFile(IFile&, const bool ignore_coeffs_info=false);
+     162             :   void checkCoeffsInfo(const std::string&, const std::string&, const unsigned int, const size_t, const std::vector<unsigned int>&);
+     163             :   //
+     164         167 :   void turnOnIterationCounter() {iteration_and_time_active_=true;}
+     165             :   void turnOffIterationCounter() {iteration_and_time_active_=false;}
+     166        3414 :   bool isIterationCounterActive() const {return iteration_and_time_active_;}
+     167             :   void setIterationCounter(const unsigned int);
+     168             :   void setTime(const double);
+     169             :   void setIterationCounterAndTime(const unsigned int, const double);
+     170         161 :   unsigned int getIterationCounter() const {return iteration_opt;}
+     171             :   double getTimeValue() const {return time_md;}
+     172             :   //
+     173         679 :   void setOutputFmt(const std::string& ss) { output_fmt_=ss; }
+     174             :   void resetOutputFmt() {output_fmt_="%30.16e";}
+     175       29978 :   std::string getOutputFmt() const {return output_fmt_;}
+     176             :   //
+     177             :   void replaceLabelString(const std::string&, const std::string&);
+     178             : protected:
+     179             :   void setupBasisFunctionsInfo();
+     180             :   void resizeIndices(const std::vector<unsigned int>&);
+     181             :   void resizeIndices(std::vector<BasisFunctions*>&);
+     182             :   bool sameShape(const CoeffsBase&) const;
+     183             :   //
+     184             :   void writeIterationCounterAndTimeToFile(OFile&) const;
+     185             :   bool getIterationCounterAndTimeFromFile(IFile&);
+     186             :   //
+     187             : 
+     188             : };
+     189             : 
+     190             : inline
+     191             : void CoeffsBase::setIterationCounter(const unsigned int iteration_opt_in) {
+     192             :   iteration_opt=iteration_opt_in;
+     193             : }
+     194             : 
+     195             : inline
+     196             : void CoeffsBase::setTime(const double time_md_in) {
+     197             :   time_md=time_md_in;
+     198             : }
+     199             : 
+     200             : inline
+     201             : void CoeffsBase::setIterationCounterAndTime(const unsigned int iteration_opt_in, const double time_md_in) {
+     202       46613 :   iteration_opt=iteration_opt_in;
+     203       23077 :   time_md=time_md_in;
+     204       22780 : }
+     205             : 
+     206             : inline
+     207             : std::string CoeffsBase::getCoeffDescription(const std::vector<unsigned int>& indices) const {
+     208             :   return getCoeffDescription(getIndex(indices));
+     209             : }
+     210             : 
+     211             : inline
+     212             : std::string CoeffsBase::getDimensionLabel(const unsigned int dim_index) const {
+     213             :   // plumed_massert(dim_index<numberOfDimensions(),"Trying to get the label of a dimension outside the number of dimensions");
+     214       12156 :   return dimension_labels_[dim_index];
+     215             : }
+     216             : 
+     217             : 
+     218             : // we are flattening arrays using a column-major order
+     219             : inline
+     220       10870 : size_t CoeffsBase::getIndex(const std::vector<unsigned int>& indices) const {
+     221             :   // plumed_dbg_assert(indices.size()==ndimensions_);
+     222             :   // for(unsigned int i=0; i<ndimensions_; i++){
+     223             :   //   if(indices[i]>=indices_shape_[i]){
+     224             :   //     std::string is;
+     225             :   //     Tools::convert(i,is);
+     226             :   //     std::string msg="ERROR: the system is looking for a value outside the indices along the " + is + "dimension!";
+     227             :   //     plumed_merror(msg);
+     228             :   //   }
+     229             :   // }
+     230       10870 :   size_t index=indices[ndimensions_-1];
+     231       13392 :   for(unsigned int i=ndimensions_-1; i>0; --i) {
+     232        2522 :     index=index*indices_shape_[i-1]+indices[i-1];
+     233             :   }
+     234       10870 :   return index;
+     235             : }
+     236             : 
+     237             : // we are flattening arrays using a column-major order
+     238             : inline
+     239   237974265 : std::vector<unsigned int> CoeffsBase::getIndices(const size_t index) const {
+     240   237974265 :   std::vector<unsigned int> indices(ndimensions_);
+     241             :   size_t kk=index;
+     242   237974265 :   indices[0]=(index%indices_shape_[0]);
+     243   258960719 :   for(unsigned int i=1; i<ndimensions_-1; ++i) {
+     244    20986454 :     kk=(kk-indices[i-1])/indices_shape_[i-1];
+     245    20986454 :     indices[i]=(kk%indices_shape_[i]);
+     246             :   }
+     247   237974265 :   if(ndimensions_>=2) {
+     248   236955949 :     indices[ndimensions_-1]=((kk-indices[ndimensions_-2])/indices_shape_[ndimensions_-2]);
+     249             :   }
+     250   237974265 :   return indices;
+     251             : }
+     252             : 
+     253             : 
+     254             : 
+     255             : 
+     256             : }
+     257             : }
+     258             : 
+     259             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.cpp.func-sort-c.html b/coverage/ves/CoeffsMatrix.cpp.func-sort-c.html new file mode 100644 index 000000000000..e414a456544e --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.func-sort-c.html @@ -0,0 +1,389 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10535629.5 %
Date:2024-02-22 21:58:45Functions:207925.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12CoeffsMatrix10addToValueERKSt6vectorIjSaIjEES6_d0
_ZN4PLMD3ves12CoeffsMatrix10addToValueEmmd0
_ZN4PLMD3ves12CoeffsMatrix10sumCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsMatrix10sumCommMPIEv0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesEd0
_ZN4PLMD3ves12CoeffsMatrix11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsMatrix12addToAverageERKS1_0
_ZN4PLMD3ves12CoeffsMatrix14resetAveragingEv0
_ZN4PLMD3ves12CoeffsMatrix15averageMatricesERKSt6vectorIPS1_SaIS3_EE0
_ZN4PLMD3ves12CoeffsMatrix15averageMatricesERS1_S2_0
_ZN4PLMD3ves12CoeffsMatrix18setAllValuesToZeroEv0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesEd0
_ZN4PLMD3ves12CoeffsMatrix18sumMultiSimCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsMatrix19writeDataFullToFileERNS_5OFileE0
_ZN4PLMD3ves12CoeffsMatrix23randomizeValuesGaussianEi0
_ZN4PLMD3ves12CoeffsMatrix8setValueERKSt6vectorIjSaIjEES6_d0
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERNS0_12CoeffsVectorERS1_0
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERS1_RNS0_12CoeffsVectorE0
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERS1_S2_0
_ZN4PLMD3ves12CoeffsMatrix9setValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix9setValuesEd0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEERNS_12CommunicatorEbb0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISH_EERNS_12CommunicatorEbb0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EERNS_12CommunicatorEbbS9_0
_ZN4PLMD3ves12CoeffsMatrixaSEd0
_ZN4PLMD3ves12CoeffsMatrixclERKSt6vectorIjSaIjEES6_0
_ZN4PLMD3ves12CoeffsMatrixclEmm0
_ZN4PLMD3ves12CoeffsMatrixmIERKS1_0
_ZN4PLMD3ves12CoeffsMatrixmIERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrixmIEd0
_ZN4PLMD3ves12CoeffsMatrixmLERKS1_0
_ZN4PLMD3ves12CoeffsMatrixpLERKS1_0
_ZN4PLMD3ves12CoeffsMatrixpLERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrixpLEd0
_ZN4PLMD3vesmiERKNS0_12CoeffsMatrixERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesmiERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesmiERKSt6vectorIdSaIdEERKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesmiEdRKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesmlERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesmlEdRKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesplERKNS0_12CoeffsMatrixERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesplERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesplERKSt6vectorIdSaIdEERKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesplEdRKNS0_12CoeffsMatrixE0
_ZNK4PLMD3ves12CoeffsMatrix11getMaxValueEv0
_ZNK4PLMD3ves12CoeffsMatrix11getMinValueEv0
_ZNK4PLMD3ves12CoeffsMatrix8getValueERKSt6vectorIjSaIjEES6_0
_ZNK4PLMD3ves12CoeffsMatrix9sameShapeERNS0_12CoeffsVectorE0
_ZNK4PLMD3ves12CoeffsMatrix9sameShapeERS1_0
_ZNK4PLMD3ves12CoeffsMatrixclERKSt6vectorIjSaIjEES6_0
_ZNK4PLMD3ves12CoeffsMatrixmiERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixmlERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixngEv0
_ZNK4PLMD3ves12CoeffsMatrixplERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixpsEv0
_ZN4PLMD3ves12CoeffsMatrix11setupMatrixEv172
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_12CoeffsVectorERNS_12CommunicatorEb172
_ZN4PLMD3ves12CoeffsMatrixD2Ev172
_ZN4PLMD3ves12CoeffsMatrix8setValueEmmd219
_ZN4PLMD3ves12CoeffsMatrix5clearEv267
_ZNK4PLMD3ves12CoeffsMatrix7getSizeEv439
_ZN4PLMD3ves12CoeffsMatrix11writeToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix15writeDataToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix17writeHeaderToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix21writeMatrixInfoToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix23writeDataDiagonalToFileERNS_5OFileE660
_ZN4PLMD3vesmlERKNS0_12CoeffsMatrixERKNS0_12CoeffsVectorE22735
_ZN4PLMD3ves12CoeffsMatrix14scaleAllValuesEd22810
_ZN4PLMD3ves12CoeffsMatrix9setValuesERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsMatrixaSERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsMatrixmLEd22810
_ZNK4PLMD3ves12CoeffsMatrix10isDiagonalEv23395
_ZNK4PLMD3ves12CoeffsMatrix8getValueEmm27630
_ZNK4PLMD3ves12CoeffsMatrixclEmm1790345
_ZNK4PLMD3ves12CoeffsMatrix14getMatrixIndexEmm5425906
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.cpp.func.html b/coverage/ves/CoeffsMatrix.cpp.func.html new file mode 100644 index 000000000000..c05722c6b3db --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.func.html @@ -0,0 +1,389 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10535629.5 %
Date:2024-02-22 21:58:45Functions:207925.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12CoeffsMatrix10addToValueERKSt6vectorIjSaIjEES6_d0
_ZN4PLMD3ves12CoeffsMatrix10addToValueEmmd0
_ZN4PLMD3ves12CoeffsMatrix10sumCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsMatrix10sumCommMPIEv0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrix11addToValuesEd0
_ZN4PLMD3ves12CoeffsMatrix11setupMatrixEv172
_ZN4PLMD3ves12CoeffsMatrix11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsMatrix11writeToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix12addToAverageERKS1_0
_ZN4PLMD3ves12CoeffsMatrix14resetAveragingEv0
_ZN4PLMD3ves12CoeffsMatrix14scaleAllValuesEd22810
_ZN4PLMD3ves12CoeffsMatrix15averageMatricesERKSt6vectorIPS1_SaIS3_EE0
_ZN4PLMD3ves12CoeffsMatrix15averageMatricesERS1_S2_0
_ZN4PLMD3ves12CoeffsMatrix15writeDataToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix17writeHeaderToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix18setAllValuesToZeroEv0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrix18subtractFromValuesEd0
_ZN4PLMD3ves12CoeffsMatrix18sumMultiSimCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsMatrix19writeDataFullToFileERNS_5OFileE0
_ZN4PLMD3ves12CoeffsMatrix21writeMatrixInfoToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix23randomizeValuesGaussianEi0
_ZN4PLMD3ves12CoeffsMatrix23writeDataDiagonalToFileERNS_5OFileE660
_ZN4PLMD3ves12CoeffsMatrix5clearEv267
_ZN4PLMD3ves12CoeffsMatrix8setValueERKSt6vectorIjSaIjEES6_d0
_ZN4PLMD3ves12CoeffsMatrix8setValueEmmd219
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERNS0_12CoeffsVectorERS1_0
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERS1_RNS0_12CoeffsVectorE0
_ZN4PLMD3ves12CoeffsMatrix9sameShapeERS1_S2_0
_ZN4PLMD3ves12CoeffsMatrix9setValuesERKS1_0
_ZN4PLMD3ves12CoeffsMatrix9setValuesERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsMatrix9setValuesEd0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_12CoeffsVectorERNS_12CommunicatorEb172
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEERNS_12CommunicatorEbb0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISH_EERNS_12CommunicatorEbb0
_ZN4PLMD3ves12CoeffsMatrixC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EERNS_12CommunicatorEbbS9_0
_ZN4PLMD3ves12CoeffsMatrixD2Ev172
_ZN4PLMD3ves12CoeffsMatrixaSERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsMatrixaSEd0
_ZN4PLMD3ves12CoeffsMatrixclERKSt6vectorIjSaIjEES6_0
_ZN4PLMD3ves12CoeffsMatrixclEmm0
_ZN4PLMD3ves12CoeffsMatrixmIERKS1_0
_ZN4PLMD3ves12CoeffsMatrixmIERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrixmIEd0
_ZN4PLMD3ves12CoeffsMatrixmLERKS1_0
_ZN4PLMD3ves12CoeffsMatrixmLEd22810
_ZN4PLMD3ves12CoeffsMatrixpLERKS1_0
_ZN4PLMD3ves12CoeffsMatrixpLERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsMatrixpLEd0
_ZN4PLMD3vesmiERKNS0_12CoeffsMatrixERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesmiERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesmiERKSt6vectorIdSaIdEERKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesmiEdRKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesmlERKNS0_12CoeffsMatrixERKNS0_12CoeffsVectorE22735
_ZN4PLMD3vesmlERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesmlEdRKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesplERKNS0_12CoeffsMatrixERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesplERKNS0_12CoeffsMatrixEd0
_ZN4PLMD3vesplERKSt6vectorIdSaIdEERKNS0_12CoeffsMatrixE0
_ZN4PLMD3vesplEdRKNS0_12CoeffsMatrixE0
_ZNK4PLMD3ves12CoeffsMatrix10isDiagonalEv23395
_ZNK4PLMD3ves12CoeffsMatrix11getMaxValueEv0
_ZNK4PLMD3ves12CoeffsMatrix11getMinValueEv0
_ZNK4PLMD3ves12CoeffsMatrix14getMatrixIndexEmm5425906
_ZNK4PLMD3ves12CoeffsMatrix7getSizeEv439
_ZNK4PLMD3ves12CoeffsMatrix8getValueERKSt6vectorIjSaIjEES6_0
_ZNK4PLMD3ves12CoeffsMatrix8getValueEmm27630
_ZNK4PLMD3ves12CoeffsMatrix9sameShapeERNS0_12CoeffsVectorE0
_ZNK4PLMD3ves12CoeffsMatrix9sameShapeERS1_0
_ZNK4PLMD3ves12CoeffsMatrixclERKSt6vectorIjSaIjEES6_0
_ZNK4PLMD3ves12CoeffsMatrixclEmm1790345
_ZNK4PLMD3ves12CoeffsMatrixmiERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixmlERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixngEv0
_ZNK4PLMD3ves12CoeffsMatrixplERKS1_0
_ZNK4PLMD3ves12CoeffsMatrixpsEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.cpp.gcov.html b/coverage/ves/CoeffsMatrix.cpp.gcov.html new file mode 100644 index 000000000000..7fe31bef1dce --- /dev/null +++ b/coverage/ves/CoeffsMatrix.cpp.gcov.html @@ -0,0 +1,792 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10535629.5 %
Date:2024-02-22 21:58:45Functions:207925.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "CoeffsMatrix.h"
+      24             : #include "CoeffsVector.h"
+      25             : #include "BasisFunctions.h"
+      26             : 
+      27             : #include "tools/Tools.h"
+      28             : #include "core/Value.h"
+      29             : #include "tools/File.h"
+      30             : #include "tools/Exception.h"
+      31             : #include "tools/Random.h"
+      32             : #include "tools/Communicator.h"
+      33             : 
+      34             : #include <vector>
+      35             : #include <cmath>
+      36             : #include <iostream>
+      37             : #include <sstream>
+      38             : #include <cstdio>
+      39             : #include <cfloat>
+      40             : 
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace ves {
+      44             : 
+      45           0 : CoeffsMatrix::CoeffsMatrix(
+      46             :   const std::string& label,
+      47             :   const std::vector<std::string>& dimension_labels,
+      48             :   const std::vector<unsigned int>& indices_shape,
+      49             :   Communicator& cc,
+      50             :   const bool diagonal,
+      51           0 :   const bool use_iteration_counter):
+      52             :   CoeffsBase(label,dimension_labels,indices_shape,use_iteration_counter),
+      53           0 :   data(0),
+      54           0 :   size_(0),
+      55           0 :   nrows_(0),
+      56           0 :   ncolumns_(0),
+      57           0 :   diagonal_(diagonal),
+      58           0 :   averaging_counter(0),
+      59           0 :   averaging_exp_decay_(0),
+      60           0 :   mycomm(cc)
+      61             : {
+      62           0 :   setupMatrix();
+      63           0 : }
+      64             : 
+      65             : 
+      66           0 : CoeffsMatrix::CoeffsMatrix(
+      67             :   const std::string& label,
+      68             :   std::vector<Value*>& args,
+      69             :   std::vector<BasisFunctions*>& basisf,
+      70             :   Communicator& cc,
+      71             :   const bool diagonal,
+      72           0 :   const bool use_iteration_counter):
+      73             :   CoeffsBase(label,args,basisf,use_iteration_counter),
+      74           0 :   data(0),
+      75           0 :   size_(0),
+      76           0 :   nrows_(0),
+      77           0 :   ncolumns_(0),
+      78           0 :   diagonal_(diagonal),
+      79           0 :   averaging_counter(0),
+      80           0 :   averaging_exp_decay_(0),
+      81           0 :   mycomm(cc)
+      82             : {
+      83           0 :   setupMatrix();
+      84           0 : }
+      85             : 
+      86             : 
+      87           0 : CoeffsMatrix::CoeffsMatrix(
+      88             :   const std::string& label,
+      89             :   std::vector<std::vector<Value*> >& argsv,
+      90             :   std::vector<std::vector<BasisFunctions*> >& basisfv,
+      91             :   Communicator& cc,
+      92             :   const bool diagonal,
+      93             :   const bool use_iteration_counter,
+      94           0 :   const std::string& multicoeffs_label):
+      95             :   CoeffsBase(label,argsv,basisfv,use_iteration_counter,multicoeffs_label),
+      96           0 :   data(0),
+      97           0 :   size_(0),
+      98           0 :   nrows_(0),
+      99           0 :   ncolumns_(0),
+     100           0 :   diagonal_(diagonal),
+     101           0 :   averaging_counter(0),
+     102           0 :   averaging_exp_decay_(0),
+     103           0 :   mycomm(cc)
+     104             : {
+     105           0 :   setupMatrix();
+     106           0 : }
+     107             : 
+     108             : 
+     109         172 : CoeffsMatrix::CoeffsMatrix(
+     110             :   const std::string& label,
+     111             :   CoeffsVector* coeffsVec,
+     112             :   Communicator& cc,
+     113         172 :   const bool diagonal):
+     114             :   CoeffsBase( *(static_cast<CoeffsBase*>(coeffsVec)) ),
+     115         172 :   data(0),
+     116         172 :   size_(0),
+     117         172 :   nrows_(0),
+     118         172 :   ncolumns_(0),
+     119         172 :   diagonal_(diagonal),
+     120         172 :   averaging_counter(0),
+     121         172 :   averaging_exp_decay_(0),
+     122         172 :   mycomm(cc)
+     123             : {
+     124         172 :   setLabels(label);
+     125         172 :   setupMatrix();
+     126         172 : }
+     127             : 
+     128             : 
+     129         172 : CoeffsMatrix::~CoeffsMatrix() {}
+     130             : 
+     131             : 
+     132         172 : void CoeffsMatrix::setupMatrix() {
+     133         172 :   nrows_=numberOfCoeffs();
+     134         172 :   ncolumns_=nrows_;
+     135         172 :   if(diagonal_) {
+     136         172 :     size_=nrows_;
+     137             :   }
+     138             :   else {
+     139           0 :     size_=(nrows_*nrows_-nrows_)/2+nrows_;
+     140             :   }
+     141         172 :   clear();
+     142         172 : }
+     143             : 
+     144             : 
+     145         439 : size_t CoeffsMatrix::getSize() const {
+     146         439 :   return size_;
+     147             : }
+     148             : 
+     149             : 
+     150       23395 : bool CoeffsMatrix::isDiagonal() const {
+     151       23395 :   return diagonal_;
+     152             : }
+     153             : 
+     154             : 
+     155           0 : bool CoeffsMatrix::sameShape(CoeffsVector& coeffsvector_in) const {
+     156           0 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsvector_in)) );
+     157             : }
+     158             : 
+     159             : 
+     160           0 : bool CoeffsMatrix::sameShape(CoeffsMatrix& coeffsmat_in) const {
+     161           0 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsmat_in)) );
+     162             : }
+     163             : 
+     164             : 
+     165           0 : bool CoeffsMatrix::sameShape(CoeffsMatrix& coeffsmat0, CoeffsMatrix& coeffsmat1) {
+     166           0 :   return coeffsmat0.sameShape(coeffsmat1);
+     167             : }
+     168             : 
+     169             : 
+     170           0 : bool CoeffsMatrix::sameShape(CoeffsVector& coeffsvec, CoeffsMatrix& coeffsmat) {
+     171           0 :   return coeffsmat.sameShape(coeffsvec);
+     172             : }
+     173             : 
+     174             : 
+     175           0 : bool CoeffsMatrix::sameShape(CoeffsMatrix& coeffsmat, CoeffsVector& coeffsvec) {
+     176           0 :   return coeffsmat.sameShape(coeffsvec);
+     177             : }
+     178             : 
+     179             : 
+     180           0 : void CoeffsMatrix::sumCommMPI() {
+     181           0 :   mycomm.Sum(data);
+     182           0 : }
+     183             : 
+     184             : 
+     185           0 : void CoeffsMatrix::sumCommMPI(Communicator& cc) {
+     186           0 :   cc.Sum(data);
+     187           0 : }
+     188             : 
+     189             : 
+     190           0 : void CoeffsMatrix::sumMultiSimCommMPI(Communicator& multi_sim_cc) {
+     191           0 :   if(mycomm.Get_rank()==0) {
+     192           0 :     double nwalkers = static_cast<double>(multi_sim_cc.Get_size());
+     193           0 :     multi_sim_cc.Sum(data);
+     194           0 :     scaleAllValues(1.0/nwalkers);
+     195             :   }
+     196           0 :   mycomm.Bcast(data,0);
+     197           0 : }
+     198             : 
+     199             : 
+     200     5425906 : size_t CoeffsMatrix::getMatrixIndex(const size_t index1, const size_t index2) const {
+     201             :   size_t matrix_idx;
+     202             :   plumed_dbg_assert(index1<nrows_);
+     203             :   plumed_dbg_assert(index2<ncolumns_);
+     204     5425906 :   if(diagonal_) {
+     205             :     // plumed_massert(index1==index2,"CoeffsMatrix: you trying to access a off-diagonal element of a diagonal coeffs matrix");
+     206             :     matrix_idx=index1;
+     207             :   }
+     208           0 :   else if (index1<=index2) {
+     209           0 :     matrix_idx=index2+index1*(nrows_-1)-index1*(index1-1)/2;
+     210             :   }
+     211             :   else {
+     212           0 :     matrix_idx=index1+index2*(nrows_-1)-index2*(index2-1)/2;
+     213             :   }
+     214     5425906 :   return matrix_idx;
+     215             : }
+     216             : 
+     217             : 
+     218         267 : void CoeffsMatrix::clear() {
+     219         267 :   data.resize(getSize());
+     220       19388 :   for(size_t i=0; i<data.size(); i++) {
+     221       19121 :     data[i]=0.0;
+     222             :   }
+     223         267 : }
+     224             : 
+     225             : 
+     226           0 : void CoeffsMatrix::setAllValuesToZero() {
+     227           0 :   for(size_t i=0; i<data.size(); i++) {
+     228           0 :     data[i]=0.0;
+     229             :   }
+     230           0 : }
+     231             : 
+     232             : 
+     233       27630 : double CoeffsMatrix::getValue(const size_t index1, const size_t index2) const {
+     234       27630 :   return data[getMatrixIndex(index1,index2)];
+     235             : }
+     236             : 
+     237             : 
+     238           0 : double CoeffsMatrix::getValue(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2) const {
+     239           0 :   return getValue(getIndex(indices1),getIndex(indices2));
+     240             : }
+     241             : 
+     242             : 
+     243         219 : void CoeffsMatrix::setValue(const size_t index1, const size_t index2, const double value) {
+     244         219 :   data[getMatrixIndex(index1,index2)]=value;
+     245         219 : }
+     246             : 
+     247             : 
+     248           0 : void CoeffsMatrix::setValue(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2, const double value) {
+     249           0 :   setValue(getIndex(indices1),getIndex(indices2),value);
+     250           0 : }
+     251             : 
+     252             : 
+     253           0 : double& CoeffsMatrix::operator()(const size_t index1, const size_t index2) {
+     254           0 :   return data[getMatrixIndex(index1,index2)];
+     255             : }
+     256             : 
+     257             : 
+     258     1790345 : const double& CoeffsMatrix::operator()(const size_t index1, const size_t index2) const {
+     259     1790345 :   return data[getMatrixIndex(index1,index2)];
+     260             : }
+     261             : 
+     262             : 
+     263           0 : double& CoeffsMatrix::operator()(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2) {
+     264           0 :   return data[getMatrixIndex(getIndex(indices1),getIndex(indices2))];
+     265             : }
+     266             : 
+     267             : 
+     268           0 : const double& CoeffsMatrix::operator()(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2) const {
+     269           0 :   return data[getMatrixIndex(getIndex(indices1),getIndex(indices2))];
+     270             : }
+     271             : 
+     272             : 
+     273       22735 : CoeffsVector operator*(const CoeffsMatrix& coeffs_matrix, const CoeffsVector& coeffs_vector) {
+     274       22735 :   CoeffsVector new_coeffs_vector(coeffs_vector);
+     275       22735 :   new_coeffs_vector.clear();
+     276       22735 :   plumed_massert(coeffs_vector.numberOfCoeffs()==coeffs_matrix.numberOfCoeffs(),"CoeffsMatrix and CoeffsVector are of the wrong size");
+     277             :   size_t numcoeffs = coeffs_vector.numberOfCoeffs();
+     278       22735 :   if(coeffs_matrix.isDiagonal()) {
+     279     1813080 :     for(size_t i=0; i<numcoeffs; i++) {
+     280     1790345 :       new_coeffs_vector(i) = coeffs_matrix(i,i)*coeffs_vector(i);
+     281             :     }
+     282             :   }
+     283             :   else {
+     284           0 :     for(size_t i=0; i<numcoeffs; i++) {
+     285           0 :       for(size_t j=0; j<numcoeffs; j++) {
+     286           0 :         new_coeffs_vector(i) += coeffs_matrix(i,j)*coeffs_vector(j);
+     287             :       }
+     288             :     }
+     289             :   }
+     290       22735 :   return new_coeffs_vector;
+     291           0 : }
+     292             : 
+     293             : 
+     294           0 : void CoeffsMatrix::addToValue(const size_t index1, const size_t index2, const double value) {
+     295           0 :   data[getMatrixIndex(index1,index2)]+=value;
+     296           0 : }
+     297             : 
+     298             : 
+     299           0 : void CoeffsMatrix::addToValue(const std::vector<unsigned int>& indices1, const std::vector<unsigned int>& indices2, const double value) {
+     300           0 :   addToValue(getIndex(indices1),getIndex(indices2),value);
+     301           0 : }
+     302             : 
+     303             : 
+     304       22810 : void CoeffsMatrix::scaleAllValues(const double scalef) {
+     305     1823850 :   for(size_t i=0; i<data.size(); i++) {
+     306     1801040 :     data[i]*=scalef;
+     307             :   }
+     308       22810 : }
+     309             : 
+     310             : 
+     311       22810 : CoeffsMatrix& CoeffsMatrix::operator*=(const double scalef) {
+     312       22810 :   scaleAllValues(scalef);
+     313       22810 :   return *this;
+     314             : }
+     315             : 
+     316             : 
+     317           0 : CoeffsMatrix operator*(const double scalef, const CoeffsMatrix& coeffsmatrix) {
+     318           0 :   return CoeffsMatrix(coeffsmatrix)*=scalef;
+     319             : }
+     320             : 
+     321             : 
+     322           0 : CoeffsMatrix operator*(const CoeffsMatrix& coeffsmatrix, const double scalef) {
+     323           0 :   return scalef*coeffsmatrix;
+     324             : }
+     325             : 
+     326             : 
+     327           0 : CoeffsMatrix& CoeffsMatrix::operator*=(const CoeffsMatrix& other_coeffsmatrix) {
+     328           0 :   plumed_massert(data.size()==other_coeffsmatrix.getSize(),"Coeffs matrices do not have the same size");
+     329           0 :   for(size_t i=0; i<data.size(); i++) {
+     330           0 :     data[i]*=other_coeffsmatrix.data[i];
+     331             :   }
+     332           0 :   return *this;
+     333             : }
+     334             : 
+     335             : 
+     336           0 : CoeffsMatrix CoeffsMatrix::operator*(const CoeffsMatrix& other_coeffsmatrix) const {
+     337           0 :   return CoeffsMatrix(*this)*=other_coeffsmatrix;
+     338             : }
+     339             : 
+     340             : 
+     341           0 : void CoeffsMatrix::setValues(const double value) {
+     342           0 :   for(size_t i=0; i<data.size(); i++) {
+     343           0 :     data[i]=value;
+     344             :   }
+     345           0 : }
+     346             : 
+     347             : 
+     348       22810 : void CoeffsMatrix::setValues(const std::vector<double>& values) {
+     349       22810 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     350     1823850 :   for(size_t i=0; i<data.size(); i++) {
+     351     1801040 :     data[i]=values[i];
+     352             :   }
+     353       22810 : }
+     354             : 
+     355             : 
+     356           0 : void CoeffsMatrix::setValues(const CoeffsMatrix& other_coeffsmatrix) {
+     357           0 :   plumed_massert( data.size()==other_coeffsmatrix.getSize(), "Incorrect size");
+     358           0 :   for(size_t i=0; i<data.size(); i++) {
+     359           0 :     data[i]=other_coeffsmatrix.data[i];
+     360             :   }
+     361           0 : }
+     362             : 
+     363             : 
+     364           0 : CoeffsMatrix& CoeffsMatrix::operator=(const double value) {
+     365           0 :   setValues(value);
+     366           0 :   return *this;
+     367             : }
+     368             : 
+     369             : 
+     370       22810 : CoeffsMatrix& CoeffsMatrix::operator=(const std::vector<double>& values) {
+     371       22810 :   setValues(values);
+     372       22810 :   return *this;
+     373             : }
+     374             : 
+     375             : 
+     376             : // CoeffsMatrix& CoeffsMatrix::operator=(const CoeffsMatrix& other_coeffsmatrix) {
+     377             : //   setValues(other_coeffsmatrix);
+     378             : //   return *this;
+     379             : // }
+     380             : 
+     381             : 
+     382           0 : CoeffsMatrix CoeffsMatrix::operator+() const {
+     383           0 :   return *this;
+     384             : }
+     385             : 
+     386             : 
+     387           0 : CoeffsMatrix CoeffsMatrix::operator-() const {
+     388           0 :   return CoeffsMatrix(*this)*=-1.0;
+     389             : }
+     390             : 
+     391             : 
+     392           0 : void CoeffsMatrix::addToValues(const double value) {
+     393           0 :   for(size_t i=0; i<data.size(); i++) {
+     394           0 :     data[i]+=value;
+     395             :   }
+     396           0 : }
+     397             : 
+     398             : 
+     399           0 : void CoeffsMatrix::addToValues(const std::vector<double>& values) {
+     400           0 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     401           0 :   for(size_t i=0; i<data.size(); i++) {
+     402           0 :     data[i]+=values[i];
+     403             :   }
+     404           0 : }
+     405             : 
+     406             : 
+     407           0 : void CoeffsMatrix::addToValues(const CoeffsMatrix& other_coeffsmatrix) {
+     408           0 :   plumed_massert( data.size()==other_coeffsmatrix.getSize(), "Incorrect size");
+     409           0 :   for(size_t i=0; i<data.size(); i++) {
+     410           0 :     data[i]+=other_coeffsmatrix.data[i];
+     411             :   }
+     412           0 : }
+     413             : 
+     414             : 
+     415           0 : void CoeffsMatrix::subtractFromValues(const double value) {
+     416           0 :   for(size_t i=0; i<data.size(); i++) {
+     417           0 :     data[i]-=value;
+     418             :   }
+     419           0 : }
+     420             : 
+     421             : 
+     422           0 : void CoeffsMatrix::subtractFromValues(const std::vector<double>& values) {
+     423           0 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     424           0 :   for(size_t i=0; i<data.size(); i++) {
+     425           0 :     data[i]-=values[i];
+     426             :   }
+     427           0 : }
+     428             : 
+     429             : 
+     430           0 : void CoeffsMatrix::subtractFromValues(const CoeffsMatrix& other_coeffsmatrix) {
+     431           0 :   plumed_massert( data.size()==other_coeffsmatrix.getSize(), "Incorrect size");
+     432           0 :   for(size_t i=0; i<data.size(); i++) {
+     433           0 :     data[i]-=other_coeffsmatrix.data[i];
+     434             :   }
+     435           0 : }
+     436             : 
+     437             : 
+     438           0 : CoeffsMatrix& CoeffsMatrix::operator+=(const double value) {
+     439           0 :   addToValues(value);
+     440           0 :   return *this;
+     441             : }
+     442             : 
+     443             : 
+     444           0 : CoeffsMatrix operator+(const double value, const CoeffsMatrix& coeffsmatrix) {
+     445           0 :   return coeffsmatrix+value;
+     446             : }
+     447             : 
+     448             : 
+     449           0 : CoeffsMatrix operator+(const CoeffsMatrix& coeffsmatrix, const double value) {
+     450           0 :   return CoeffsMatrix(coeffsmatrix)+=value;
+     451             : }
+     452             : 
+     453             : 
+     454           0 : CoeffsMatrix& CoeffsMatrix::operator+=(const std::vector<double>& values) {
+     455           0 :   addToValues(values);
+     456           0 :   return *this;
+     457             : }
+     458             : 
+     459             : 
+     460           0 : CoeffsMatrix operator+(const std::vector<double>& values, const CoeffsMatrix& coeffsmatrix) {
+     461           0 :   return coeffsmatrix+values;
+     462             : }
+     463             : 
+     464             : 
+     465           0 : CoeffsMatrix operator+(const CoeffsMatrix& coeffsmatrix, const std::vector<double>& values) {
+     466           0 :   return CoeffsMatrix(coeffsmatrix)+=values;
+     467             : }
+     468             : 
+     469             : 
+     470           0 : CoeffsMatrix& CoeffsMatrix::operator-=(const double value) {
+     471           0 :   subtractFromValues(value);
+     472           0 :   return *this;
+     473             : }
+     474             : 
+     475             : 
+     476           0 : CoeffsMatrix operator-(const double value, const CoeffsMatrix& coeffsmatrix) {
+     477           0 :   return -1.0*coeffsmatrix+value;
+     478             : }
+     479             : 
+     480             : 
+     481           0 : CoeffsMatrix operator-(const CoeffsMatrix& coeffsmatrix, const double value) {
+     482           0 :   return CoeffsMatrix(coeffsmatrix)-=value;
+     483             : }
+     484             : 
+     485             : 
+     486           0 : CoeffsMatrix& CoeffsMatrix::operator-=(const std::vector<double>& values) {
+     487           0 :   subtractFromValues(values);
+     488           0 :   return *this;
+     489             : }
+     490             : 
+     491             : 
+     492           0 : CoeffsMatrix operator-(const std::vector<double>& values, const CoeffsMatrix& coeffsmatrix) {
+     493           0 :   return -1.0*coeffsmatrix+values;
+     494             : }
+     495             : 
+     496             : 
+     497           0 : CoeffsMatrix operator-(const CoeffsMatrix& coeffsmatrix, const std::vector<double>& values) {
+     498           0 :   return CoeffsMatrix(coeffsmatrix)-=values;
+     499             : }
+     500             : 
+     501             : 
+     502           0 : CoeffsMatrix& CoeffsMatrix::operator+=(const CoeffsMatrix& other_coeffsmatrix) {
+     503           0 :   addToValues(other_coeffsmatrix);
+     504           0 :   return *this;
+     505             : }
+     506             : 
+     507             : 
+     508           0 : CoeffsMatrix CoeffsMatrix::operator+(const CoeffsMatrix& other_coeffsmatrix) const {
+     509           0 :   return CoeffsMatrix(*this)+=other_coeffsmatrix;
+     510             : }
+     511             : 
+     512             : 
+     513           0 : CoeffsMatrix& CoeffsMatrix::operator-=(const CoeffsMatrix& other_coeffsmatrix) {
+     514           0 :   subtractFromValues(other_coeffsmatrix);
+     515           0 :   return *this;
+     516             : }
+     517             : 
+     518             : 
+     519           0 : CoeffsMatrix CoeffsMatrix::operator-(const CoeffsMatrix& other_coeffsmatrix) const {
+     520           0 :   return CoeffsMatrix(*this)-=other_coeffsmatrix;
+     521             : }
+     522             : 
+     523             : 
+     524           0 : void CoeffsMatrix::averageMatrices(CoeffsMatrix& coeffsmat0, CoeffsMatrix& coeffsmat1) {
+     525           0 :   plumed_massert(sameShape(coeffsmat0,coeffsmat1),"both CoeffsMatrix objects need to have the same shape");
+     526           0 :   for(size_t i=0; i<coeffsmat0.getSize(); i++) {
+     527           0 :     coeffsmat0.data[i] = coeffsmat1.data[i] = 0.5 * (coeffsmat0.data[i]+coeffsmat1.data[i]);
+     528             :   }
+     529           0 : }
+     530             : 
+     531             : 
+     532           0 : void CoeffsMatrix::averageMatrices(const std::vector<CoeffsMatrix*>& coeffsmatSet) {
+     533           0 :   double norm_factor = 1.0/static_cast<double>(coeffsmatSet.size());
+     534           0 :   for(unsigned int k=1; k<coeffsmatSet.size(); k++) {
+     535           0 :     plumed_massert(coeffsmatSet[0]->sameShape(*coeffsmatSet[k]),"All CoeffsMatrix objects need to have the same shape");
+     536             :   }
+     537           0 :   for(size_t i=0; i<coeffsmatSet[0]->getSize(); i++) {
+     538             :     double value = 0.0;
+     539           0 :     for(unsigned int k=0; k<coeffsmatSet.size(); k++) {
+     540           0 :       value += coeffsmatSet[k]->data[i];
+     541             :     }
+     542           0 :     value *= norm_factor;
+     543           0 :     for(unsigned int k=0; k<coeffsmatSet.size(); k++) {
+     544           0 :       coeffsmatSet[k]->data[i] = value;
+     545             :     }
+     546             :   }
+     547           0 : }
+     548             : 
+     549             : 
+     550             : 
+     551           0 : double CoeffsMatrix::getMinValue() const {
+     552             :   double min_value=DBL_MAX;
+     553           0 :   for(size_t i=0; i<data.size(); i++) {
+     554           0 :     if(data[i]<min_value) {
+     555             :       min_value=data[i];
+     556             :     }
+     557             :   }
+     558           0 :   return min_value;
+     559             : }
+     560             : 
+     561             : 
+     562           0 : double CoeffsMatrix::getMaxValue() const {
+     563             :   double max_value=DBL_MIN;
+     564           0 :   for(size_t i=0; i<data.size(); i++) {
+     565           0 :     if(data[i]>max_value) {
+     566             :       max_value=data[i];
+     567             :     }
+     568             :   }
+     569           0 :   return max_value;
+     570             : }
+     571             : 
+     572             : 
+     573           0 : void CoeffsMatrix::randomizeValuesGaussian(int randomSeed) {
+     574           0 :   Random rnd;
+     575             :   if (randomSeed<0) {randomSeed = -randomSeed;}
+     576           0 :   rnd.setSeed(-randomSeed);
+     577           0 :   for(size_t i=0; i<data.size(); i++) {
+     578           0 :     data[i]=rnd.Gaussian();
+     579             :   }
+     580           0 : }
+     581             : 
+     582             : 
+     583           0 : void CoeffsMatrix::resetAveraging() {
+     584           0 :   clear();
+     585             :   resetAveragingCounter();
+     586           0 : }
+     587             : 
+     588             : 
+     589           0 : void CoeffsMatrix::addToAverage(const CoeffsMatrix& coeffsmat) {
+     590           0 :   plumed_massert( data.size()==coeffsmat.getSize(), "Incorrect size");
+     591             :   //
+     592           0 :   double aver_decay = 1.0 / ( static_cast<double>(averaging_counter) + 1.0 );
+     593           0 :   if(averaging_exp_decay_>0 &&  (averaging_counter+1 > averaging_exp_decay_) ) {
+     594           0 :     aver_decay = 1.0 / static_cast<double>(averaging_exp_decay_);
+     595             :   }
+     596             :   //
+     597           0 :   for(size_t i=0; i<data.size(); i++) {
+     598           0 :     data[i]+=(coeffsmat.data[i]-data[i])*aver_decay;
+     599             :   }
+     600           0 :   averaging_counter++;
+     601           0 : }
+     602             : 
+     603             : 
+     604         660 : void CoeffsMatrix::writeToFile(OFile& ofile) {
+     605         660 :   writeHeaderToFile(ofile);
+     606         660 :   writeDataToFile(ofile);
+     607         660 : }
+     608             : 
+     609             : 
+     610           0 : void CoeffsMatrix::writeToFile(const std::string& filepath, const bool append_file, Action* action_pntr) {
+     611           0 :   OFile file;
+     612           0 :   if(action_pntr!=NULL) {
+     613           0 :     file.link(*action_pntr);
+     614             :   }
+     615             :   else {
+     616           0 :     file.link(mycomm);
+     617             :   }
+     618           0 :   if(append_file) { file.enforceRestart(); }
+     619           0 :   file.open(filepath);
+     620           0 :   writeToFile(file);
+     621           0 :   file.close();
+     622           0 : }
+     623             : 
+     624             : 
+     625         660 : void CoeffsMatrix::writeMatrixInfoToFile(OFile& ofile) {
+     626         660 :   std::string field_diagonal = "diagonal_matrix";
+     627         660 :   ofile.addConstantField(field_diagonal).printField(field_diagonal,isDiagonal());
+     628         660 : }
+     629             : 
+     630             : 
+     631         660 : void CoeffsMatrix::writeHeaderToFile(OFile& ofile) {
+     632         660 :   ofile.clearFields();
+     633         660 :   if(isIterationCounterActive()) {
+     634         660 :     writeIterationCounterAndTimeToFile(ofile);
+     635             :   }
+     636         660 :   writeCoeffsInfoToFile(ofile);
+     637         660 :   writeMatrixInfoToFile(ofile);
+     638         660 : }
+     639             : 
+     640             : 
+     641         660 : void CoeffsMatrix::writeDataToFile(OFile& ofile) {
+     642         660 :   if(diagonal_) {
+     643         660 :     writeDataDiagonalToFile(ofile);
+     644             :   }
+     645             :   else {
+     646           0 :     writeDataFullToFile(ofile);
+     647             :   }
+     648         660 : }
+     649             : 
+     650             : 
+     651         660 : void CoeffsMatrix::writeDataDiagonalToFile(OFile& ofile) {
+     652             :   //
+     653         660 :   std::string field_indices_prefix = "idx_";
+     654             :   std::string field_coeffs = getDataLabel();
+     655         660 :   std::string field_index = "index";
+     656             :   //
+     657         660 :   std::string int_fmt = "%8d";
+     658         660 :   std::string str_separate = "#!-------------------";
+     659             :   //
+     660         660 :   std::vector<char> s1(20);
+     661         660 :   std::vector<unsigned int> indices(numberOfDimensions());
+     662         660 :   std::vector<std::string> ilabels(numberOfDimensions());
+     663        1520 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     664        1720 :     ilabels[k]=field_indices_prefix+getDimensionLabel(k);
+     665             :   }
+     666             :   //
+     667       28290 :   for(size_t i=0; i<numberOfCoeffs(); i++) {
+     668       27630 :     indices=getIndices(i);
+     669       77540 :     for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     670       49910 :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),indices[k]);
+     671       99820 :       ofile.printField(ilabels[k],s1.data());
+     672             :     }
+     673       55260 :     ofile.fmtField(" "+getOutputFmt()).printField(field_coeffs,getValue(i,i));
+     674       27630 :     std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),i); ofile.printField(field_index,s1.data());
+     675       27630 :     ofile.printField();
+     676             :   }
+     677         660 :   ofile.fmtField();
+     678             :   // blank line between iterations to allow proper plotting with gnuplot
+     679         660 :   ofile.printf("%s\n",str_separate.c_str());
+     680         660 :   ofile.printf("\n");
+     681         660 :   ofile.printf("\n");
+     682        1320 : }
+     683             : 
+     684             : 
+     685           0 : void CoeffsMatrix::writeDataFullToFile(OFile& ofile) {
+     686             :   //
+     687           0 :   std::string field_index_row = "idx_row";
+     688           0 :   std::string field_index_column = "idx_column";
+     689             :   std::string field_coeffs = getDataLabel();
+     690             :   //
+     691           0 :   std::string int_fmt = "%8d";
+     692           0 :   std::string str_separate = "#!-------------------";
+     693             :   //
+     694           0 :   std::vector<char> s1(20);
+     695             :   //
+     696           0 :   for(size_t i=0; i<nrows_; i++) {
+     697           0 :     for(size_t j=0; j<ncolumns_; j++) {
+     698             :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),i);
+     699           0 :       ofile.printField(field_index_row,s1.data());
+     700             :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),j);
+     701           0 :       ofile.printField(field_index_column,s1.data());
+     702           0 :       ofile.fmtField(" "+getOutputFmt()).printField(field_coeffs,getValue(i,j));
+     703           0 :       ofile.printField();
+     704             :     }
+     705             :   }
+     706           0 :   ofile.fmtField();
+     707             :   // blank line between iterations to allow proper plotting with gnuplot
+     708           0 :   ofile.printf("%s\n",str_separate.c_str());
+     709           0 :   ofile.printf("\n");
+     710           0 :   ofile.printf("\n");
+     711           0 : }
+     712             : 
+     713             : 
+     714             : }
+     715             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.h.func-sort-c.html b/coverage/ves/CoeffsMatrix.h.func-sort-c.html new file mode 100644 index 000000000000..b2a7a1b32d21 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.h.func.html b/coverage/ves/CoeffsMatrix.h.func.html new file mode 100644 index 000000000000..a77996aaf95d --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsMatrix.h.gcov.html b/coverage/ves/CoeffsMatrix.h.gcov.html new file mode 100644 index 000000000000..38673208b343 --- /dev/null +++ b/coverage/ves/CoeffsMatrix.h.gcov.html @@ -0,0 +1,288 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsMatrix.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsMatrix.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_CoeffsMatrix_h
+      23             : #define __PLUMED_ves_CoeffsMatrix_h
+      24             : 
+      25             : #include "CoeffsBase.h"
+      26             : 
+      27             : #include <vector>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : 
+      34             : class Action;
+      35             : class Value;
+      36             : class IFile;
+      37             : class OFile;
+      38             : class Communicator;
+      39             : 
+      40             : namespace ves {
+      41             : 
+      42             : class BasisFunctions;
+      43             : class CoeffsVector;
+      44             : 
+      45             : 
+      46             : class CoeffsMatrix:
+      47             :   public CoeffsBase
+      48             : {
+      49             : public:
+      50             : private:
+      51             :   std::vector<double> data;
+      52             :   //
+      53             :   size_t size_;
+      54             :   size_t nrows_;
+      55             :   size_t ncolumns_;
+      56             :   //
+      57             :   bool diagonal_;
+      58             :   //
+      59             :   unsigned int averaging_counter;
+      60             :   unsigned int averaging_exp_decay_;
+      61             :   //
+      62             :   Communicator& mycomm;
+      63             :   //
+      64             :   void setupMatrix();
+      65             :   //
+      66             :   CoeffsMatrix& operator=(const CoeffsMatrix&);
+      67             : public:
+      68             :   explicit CoeffsMatrix(
+      69             :     const std::string&,
+      70             :     const std::vector<std::string>&,
+      71             :     const std::vector<unsigned int>&,
+      72             :     Communicator& cc,
+      73             :     const bool diagonal=true,
+      74             :     const bool use_iteration_counter=false);
+      75             :   //
+      76             :   explicit CoeffsMatrix(
+      77             :     const std::string&,
+      78             :     std::vector<Value*>&,
+      79             :     std::vector<BasisFunctions*>&,
+      80             :     Communicator& cc,
+      81             :     const bool diagonal=true,
+      82             :     const bool use_iteration_counter=false);
+      83             :   //
+      84             :   explicit CoeffsMatrix(
+      85             :     const std::string&,
+      86             :     std::vector<std::vector<Value*> >& argsv,
+      87             :     std::vector<std::vector<BasisFunctions*> >& basisfv,
+      88             :     Communicator& cc,
+      89             :     const bool diagonal=true,
+      90             :     const bool use_iteration_counter=false,
+      91             :     const std::string& multicoeffs_label="bias");
+      92             :   //
+      93             :   explicit CoeffsMatrix(
+      94             :     const std::string&,
+      95             :     CoeffsVector*,
+      96             :     Communicator& cc,
+      97             :     const bool diagonal=true);
+      98             :   //
+      99             :   ~CoeffsMatrix();
+     100             :   //
+     101             :   size_t getSize() const;
+     102             :   //
+     103             :   bool isSymmetric() const;
+     104             :   bool isDiagonal() const;
+     105             :   //
+     106             :   bool sameShape(CoeffsVector&) const;
+     107             :   bool sameShape(CoeffsMatrix&) const;
+     108             :   static bool sameShape(CoeffsMatrix&, CoeffsMatrix&);
+     109             :   static bool sameShape(CoeffsVector&, CoeffsMatrix&);
+     110             :   static bool sameShape(CoeffsMatrix&, CoeffsVector&);
+     111             :   //
+     112             :   void sumCommMPI();
+     113             :   void sumCommMPI(Communicator&);
+     114             :   //
+     115             :   void sumMultiSimCommMPI(Communicator&);
+     116             :   //
+     117             :   size_t getMatrixIndex(const size_t, const size_t) const;
+     118             :   //
+     119             :   // clear coeffs
+     120             :   void clear();
+     121             :   void setAllValuesToZero();
+     122             :   //
+     123             :   std::vector<double> getDataAsVector() const {return data;}
+     124             :   // get value
+     125             :   double getValue(const size_t, const size_t) const;
+     126             :   double getValue(const std::vector<unsigned int>&, const std::vector<unsigned int>&) const;
+     127             :   // set value
+     128             :   void setValue(const size_t, const size_t, const double);
+     129             :   void setValue(const std::vector<unsigned int>&, const std::vector<unsigned int>&, const double);
+     130             :   double& operator()(const size_t, const size_t);
+     131             :   const double& operator()(const size_t, const size_t) const;
+     132             :   double& operator()(const std::vector<unsigned int>&, const std::vector<unsigned int>&);
+     133             :   const double& operator()(const std::vector<unsigned int>&, const std::vector<unsigned int>&) const;
+     134             :   //
+     135             :   friend CoeffsVector operator*(const CoeffsMatrix&, const CoeffsVector&);
+     136             :   // add to value
+     137             :   void addToValue(const size_t, const size_t, const double);
+     138             :   void addToValue(const std::vector<unsigned int>&, const std::vector<unsigned int>&, const double);
+     139             :   // scale all values
+     140             :   void scaleAllValues(const double);
+     141             :   CoeffsMatrix& operator*=(const double);
+     142             :   friend CoeffsMatrix operator*(const double, const CoeffsMatrix&);
+     143             :   friend CoeffsMatrix operator*(const CoeffsMatrix&, const double);
+     144             :   CoeffsMatrix& operator*=(const CoeffsMatrix&);
+     145             :   CoeffsMatrix operator*(const CoeffsMatrix&) const;
+     146             :   // set all values
+     147             :   void setValues(const double);
+     148             :   void setValues(const std::vector<double>&);
+     149             :   void setValues(const CoeffsMatrix&);
+     150             :   CoeffsMatrix& operator=(const double);
+     151             :   CoeffsMatrix& operator=(const std::vector<double>&);
+     152             :   // CoeffsMatrix& operator=(const CoeffsMatrix&);
+     153             :   // add to all values
+     154             :   CoeffsMatrix operator+() const;
+     155             :   CoeffsMatrix operator-() const;
+     156             :   void addToValues(const double);
+     157             :   void addToValues(const std::vector<double>&);
+     158             :   void addToValues(const CoeffsMatrix&);
+     159             :   void subtractFromValues(const double);
+     160             :   void subtractFromValues(const std::vector<double>&);
+     161             :   void subtractFromValues(const CoeffsMatrix&);
+     162             :   CoeffsMatrix& operator+=(const double);
+     163             :   friend CoeffsMatrix operator+(const double, const CoeffsMatrix&);
+     164             :   friend CoeffsMatrix operator+(const CoeffsMatrix&, const double);
+     165             :   CoeffsMatrix& operator+=(const std::vector<double>&);
+     166             :   friend CoeffsMatrix operator+(const std::vector<double>&, const CoeffsMatrix&);
+     167             :   friend CoeffsMatrix operator+(const CoeffsMatrix&, const std::vector<double>&);
+     168             :   CoeffsMatrix& operator-=(const double);
+     169             :   friend CoeffsMatrix operator-(const double, const CoeffsMatrix&);
+     170             :   friend CoeffsMatrix operator-(const CoeffsMatrix&, const double);
+     171             :   CoeffsMatrix& operator-=(const std::vector<double>&);
+     172             :   friend CoeffsMatrix operator-(const std::vector<double>&, const CoeffsMatrix&);
+     173             :   friend CoeffsMatrix operator-(const CoeffsMatrix&, const std::vector<double>&);
+     174             :   CoeffsMatrix& operator+=(const CoeffsMatrix&);
+     175             :   CoeffsMatrix operator+(const CoeffsMatrix&) const;
+     176             :   CoeffsMatrix& operator-=(const CoeffsMatrix&);
+     177             :   CoeffsMatrix operator-(const CoeffsMatrix&) const;
+     178             :   //
+     179             :   static void averageMatrices(CoeffsMatrix&, CoeffsMatrix&);
+     180             :   static void averageMatrices(const std::vector<CoeffsMatrix*>&);
+     181             :   //
+     182             :   double getMinValue() const;
+     183             :   double getMaxValue() const;
+     184             :   //
+     185             :   void randomizeValuesGaussian(int);
+     186             :   //
+     187           0 :   void resetAveragingCounter() {averaging_counter=0;}
+     188             :   void setupExponentiallyDecayingAveraging(const unsigned int averaging_exp_decay_in) {averaging_exp_decay_=averaging_exp_decay_in;}
+     189             :   void turnOffExponentiallyDecayingAveraging() { averaging_exp_decay_=0;}
+     190             :   void resetAveraging();
+     191             :   void addToAverage(const CoeffsMatrix&);
+     192             :   void addToAverage(const CoeffsMatrix&, const unsigned int);
+     193             :   //
+     194             :   // file input/output stuff
+     195             :   void writeToFile(OFile&);
+     196             :   void writeToFile(const std::string&, const bool append_file=false, Action* action_pntr=NULL);
+     197             : private:
+     198             :   void writeDataToFile(OFile&);
+     199             :   void writeMatrixInfoToFile(OFile&);
+     200             :   void writeHeaderToFile(OFile&);
+     201             :   void writeDataDiagonalToFile(OFile&);
+     202             :   void writeDataFullToFile(OFile&);
+     203             : public:
+     204             :   Communicator& getCommunicator() const {return mycomm;}
+     205             : 
+     206             : };
+     207             : }
+     208             : }
+     209             : 
+     210             : 
+     211             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.cpp.func-sort-c.html b/coverage/ves/CoeffsVector.cpp.func-sort-c.html new file mode 100644 index 000000000000..a31585266467 --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.func-sort-c.html @@ -0,0 +1,469 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:23245850.7 %
Date:2024-02-22 21:58:45Functions:459945.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12CoeffsVector10addToValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD3ves12CoeffsVector10addToValueEmd0
_ZN4PLMD3ves12CoeffsVector10sumCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVector10sumCommMPIEv0
_ZN4PLMD3ves12CoeffsVector11addToValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsVector11addToValuesEd0
_ZN4PLMD3ves12CoeffsVector11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPS1_SaISB_EEbbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsVector11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileERKSt6vectorIPS1_SaIS5_EEb0
_ZN4PLMD3ves12CoeffsVector12resizeCoeffsERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVector12resizeCoeffsERSt6vectorIPNS0_14BasisFunctionsESaIS4_EE0
_ZN4PLMD3ves12CoeffsVector14averageVectorsERKSt6vectorIPS1_SaIS3_EE0
_ZN4PLMD3ves12CoeffsVector14averageVectorsERS1_S2_0
_ZN4PLMD3ves12CoeffsVector14resetAveragingEv0
_ZN4PLMD3ves12CoeffsVector15normalizeCoeffsEv0
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesEd0
_ZN4PLMD3ves12CoeffsVector18sumMultiSimCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVector23randomizeValuesGaussianEi0
_ZN4PLMD3ves12CoeffsVector27setValuesFromDifferentShapeERKS1_0
_ZN4PLMD3ves12CoeffsVector8setValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD3ves12CoeffsVector9sameShapeERS1_S2_0
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_12CoeffsMatrixERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEERNS_12CommunicatorEb0
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EERNS_12CommunicatorEbS9_0
_ZN4PLMD3ves12CoeffsVectoraSEd0
_ZN4PLMD3ves12CoeffsVectorclERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVectorixERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVectormIEd0
_ZN4PLMD3ves12CoeffsVectorpLERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsVectorpLEd0
_ZN4PLMD3vesmiERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesmiERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesmiEdRKNS0_12CoeffsVectorE0
_ZN4PLMD3vesmlERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesmlERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesplERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesplERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesplERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesplEdRKNS0_12CoeffsVectorE0
_ZNK4PLMD3ves12CoeffsVector11getMaxValueERm0
_ZNK4PLMD3ves12CoeffsVector11getMaxValueEv0
_ZNK4PLMD3ves12CoeffsVector11getMinValueERm0
_ZNK4PLMD3ves12CoeffsVector11getMinValueEv0
_ZNK4PLMD3ves12CoeffsVector14getMaxAbsValueEv0
_ZNK4PLMD3ves12CoeffsVector14getMinAbsValueERm0
_ZNK4PLMD3ves12CoeffsVector14getMinAbsValueEv0
_ZNK4PLMD3ves12CoeffsVector9getL1NormEv0
_ZNK4PLMD3ves12CoeffsVector9getLpNormEd0
_ZNK4PLMD3ves12CoeffsVector9sameShapeERNS0_12CoeffsMatrixE0
_ZNK4PLMD3ves12CoeffsVectorclERKSt6vectorIjSaIjEE0
_ZNK4PLMD3ves12CoeffsVectorixERKSt6vectorIjSaIjEE0
_ZNK4PLMD3ves12CoeffsVectorixEm0
_ZNK4PLMD3ves12CoeffsVectorngEv0
_ZNK4PLMD3ves12CoeffsVectorpsEv0
_ZNK4PLMD3ves12CoeffsVector11countValuesEd1
_ZN4PLMD3ves12CoeffsVector18setAllValuesToZeroEv2
_ZNK4PLMD3ves12CoeffsVector9sameShapeERS1_6
_ZN4PLMD3ves12CoeffsVector12addToAverageERKS1_20
_ZN4PLMD3ves12CoeffsVector18multiplyWithValuesERKSt6vectorIdSaIdEE20
_ZN4PLMD3ves12CoeffsVectormLERKSt6vectorIdSaIdEE20
_ZN4PLMD3vesmlERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE20
_ZN4PLMD3ves12CoeffsVector18readOneSetFromFileERNS_5IFileEb36
_ZN4PLMD3ves12CoeffsVector12readFromFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb40
_ZN4PLMD3ves12CoeffsVector12readFromFileERNS_5IFileEbb75
_ZNK4PLMD3ves12CoeffsVector14getMaxAbsValueERm80
_ZNK4PLMD3ves12CoeffsVector6getRMSEv80
_ZNK4PLMD3ves12CoeffsVector7getNormEv80
_ZNK4PLMD3ves12CoeffsVector9getL2NormEv80
_ZN4PLMD3ves12CoeffsVector9setValuesEd174
_ZN4PLMD3ves12CoeffsVectorixEm178
_ZN4PLMD3ves12CoeffsVector8setValueEmd219
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISI_EERNS_12CommunicatorEb377
_ZN4PLMD3ves12CoeffsVector18readHeaderFromFileERNS_5IFileEb406
_ZN4PLMD3ves12CoeffsVector16readDataFromFileERNS_5IFileEb442
_ZN4PLMD3ves12CoeffsVectoraSERKSt6vectorIdSaIdEE453
_ZN4PLMD3ves12CoeffsVector9setValuesERKSt6vectorIdSaIdEE700
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileEPS1_b881
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileEb1467
_ZN4PLMD3ves12CoeffsVector15writeDataToFileERNS_5OFileERKSt6vectorIPS1_SaIS5_EEb2348
_ZNK4PLMD3ves12CoeffsVector17writeHeaderToFileERNS_5OFileE2348
_ZNK4PLMD3ves12CoeffsVectorplERKS1_22735
_ZN4PLMD3ves12CoeffsVectormLERKS1_22765
_ZNK4PLMD3ves12CoeffsVectormlERKS1_22765
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsVectormIERKSt6vectorIdSaIdEE22810
_ZN4PLMD3vesmiERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsVector5clearEv23209
_ZN4PLMD3ves12CoeffsVector9setValuesERKS1_23410
_ZNK4PLMD3ves12CoeffsVectormiERKS1_45420
_ZN4PLMD3vesmlEdRKNS0_12CoeffsVectorE45430
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesERKS1_45440
_ZN4PLMD3ves12CoeffsVectormIERKS1_45440
_ZN4PLMD3ves12CoeffsVectormLEd45470
_ZN4PLMD3ves12CoeffsVector14scaleAllValuesEd45477
_ZN4PLMD3ves12CoeffsVector11addToValuesERKS1_68145
_ZN4PLMD3ves12CoeffsVectorpLERKS1_68145
_ZN4PLMD3ves12CoeffsVectorD2Ev341962
_ZN4PLMD3ves12CoeffsVectorclEm1790345
_ZNK4PLMD3ves12CoeffsVectorclEm1790345
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.cpp.func.html b/coverage/ves/CoeffsVector.cpp.func.html new file mode 100644 index 000000000000..a1c36e5a88c6 --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.func.html @@ -0,0 +1,469 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:23245850.7 %
Date:2024-02-22 21:58:45Functions:459945.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12CoeffsVector10addToValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD3ves12CoeffsVector10addToValueEmd0
_ZN4PLMD3ves12CoeffsVector10sumCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVector10sumCommMPIEv0
_ZN4PLMD3ves12CoeffsVector11addToValuesERKS1_68145
_ZN4PLMD3ves12CoeffsVector11addToValuesERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsVector11addToValuesEd0
_ZN4PLMD3ves12CoeffsVector11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPS1_SaISB_EEbbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsVector11writeToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbbPNS_6ActionE0
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileEPS1_b881
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileERKSt6vectorIPS1_SaIS5_EEb0
_ZN4PLMD3ves12CoeffsVector11writeToFileERNS_5OFileEb1467
_ZN4PLMD3ves12CoeffsVector12addToAverageERKS1_20
_ZN4PLMD3ves12CoeffsVector12readFromFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb40
_ZN4PLMD3ves12CoeffsVector12readFromFileERNS_5IFileEbb75
_ZN4PLMD3ves12CoeffsVector12resizeCoeffsERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVector12resizeCoeffsERSt6vectorIPNS0_14BasisFunctionsESaIS4_EE0
_ZN4PLMD3ves12CoeffsVector14averageVectorsERKSt6vectorIPS1_SaIS3_EE0
_ZN4PLMD3ves12CoeffsVector14averageVectorsERS1_S2_0
_ZN4PLMD3ves12CoeffsVector14resetAveragingEv0
_ZN4PLMD3ves12CoeffsVector14scaleAllValuesEd45477
_ZN4PLMD3ves12CoeffsVector15normalizeCoeffsEv0
_ZN4PLMD3ves12CoeffsVector15writeDataToFileERNS_5OFileERKSt6vectorIPS1_SaIS5_EEb2348
_ZN4PLMD3ves12CoeffsVector16readDataFromFileERNS_5IFileEb442
_ZN4PLMD3ves12CoeffsVector18multiplyWithValuesERKSt6vectorIdSaIdEE20
_ZN4PLMD3ves12CoeffsVector18readHeaderFromFileERNS_5IFileEb406
_ZN4PLMD3ves12CoeffsVector18readOneSetFromFileERNS_5IFileEb36
_ZN4PLMD3ves12CoeffsVector18setAllValuesToZeroEv2
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesERKS1_45440
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsVector18subtractFromValuesEd0
_ZN4PLMD3ves12CoeffsVector18sumMultiSimCommMPIERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVector23randomizeValuesGaussianEi0
_ZN4PLMD3ves12CoeffsVector27setValuesFromDifferentShapeERKS1_0
_ZN4PLMD3ves12CoeffsVector5clearEv23209
_ZN4PLMD3ves12CoeffsVector8setValueERKSt6vectorIjSaIjEEd0
_ZN4PLMD3ves12CoeffsVector8setValueEmd219
_ZN4PLMD3ves12CoeffsVector9sameShapeERS1_S2_0
_ZN4PLMD3ves12CoeffsVector9setValuesERKS1_23410
_ZN4PLMD3ves12CoeffsVector9setValuesERKSt6vectorIdSaIdEE700
_ZN4PLMD3ves12CoeffsVector9setValuesEd174
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPNS0_12CoeffsMatrixERNS_12CommunicatorE0
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIPNS_5ValueESaISC_EERSA_IPNS0_14BasisFunctionsESaISI_EERNS_12CommunicatorEb377
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKSt6vectorIS7_SaIS7_EERKSA_IjSaIjEERNS_12CommunicatorEb0
_ZN4PLMD3ves12CoeffsVectorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorISA_IPNS_5ValueESaISC_EESaISE_EERSA_ISA_IPNS0_14BasisFunctionsESaISJ_EESaISL_EERNS_12CommunicatorEbS9_0
_ZN4PLMD3ves12CoeffsVectorD2Ev341962
_ZN4PLMD3ves12CoeffsVectoraSERKSt6vectorIdSaIdEE453
_ZN4PLMD3ves12CoeffsVectoraSEd0
_ZN4PLMD3ves12CoeffsVectorclERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVectorclEm1790345
_ZN4PLMD3ves12CoeffsVectorixERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves12CoeffsVectorixEm178
_ZN4PLMD3ves12CoeffsVectormIERKS1_45440
_ZN4PLMD3ves12CoeffsVectormIERKSt6vectorIdSaIdEE22810
_ZN4PLMD3ves12CoeffsVectormIEd0
_ZN4PLMD3ves12CoeffsVectormLERKS1_22765
_ZN4PLMD3ves12CoeffsVectormLERKSt6vectorIdSaIdEE20
_ZN4PLMD3ves12CoeffsVectormLEd45470
_ZN4PLMD3ves12CoeffsVectorpLERKS1_68145
_ZN4PLMD3ves12CoeffsVectorpLERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves12CoeffsVectorpLEd0
_ZN4PLMD3vesmiERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE22810
_ZN4PLMD3vesmiERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesmiERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesmiEdRKNS0_12CoeffsVectorE0
_ZN4PLMD3vesmlERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE20
_ZN4PLMD3vesmlERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesmlERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesmlEdRKNS0_12CoeffsVectorE45430
_ZN4PLMD3vesplERKNS0_12CoeffsVectorERKSt6vectorIdSaIdEE0
_ZN4PLMD3vesplERKNS0_12CoeffsVectorEd0
_ZN4PLMD3vesplERKSt6vectorIdSaIdEERKNS0_12CoeffsVectorE0
_ZN4PLMD3vesplEdRKNS0_12CoeffsVectorE0
_ZNK4PLMD3ves12CoeffsVector11countValuesEd1
_ZNK4PLMD3ves12CoeffsVector11getMaxValueERm0
_ZNK4PLMD3ves12CoeffsVector11getMaxValueEv0
_ZNK4PLMD3ves12CoeffsVector11getMinValueERm0
_ZNK4PLMD3ves12CoeffsVector11getMinValueEv0
_ZNK4PLMD3ves12CoeffsVector14getMaxAbsValueERm80
_ZNK4PLMD3ves12CoeffsVector14getMaxAbsValueEv0
_ZNK4PLMD3ves12CoeffsVector14getMinAbsValueERm0
_ZNK4PLMD3ves12CoeffsVector14getMinAbsValueEv0
_ZNK4PLMD3ves12CoeffsVector17writeHeaderToFileERNS_5OFileE2348
_ZNK4PLMD3ves12CoeffsVector6getRMSEv80
_ZNK4PLMD3ves12CoeffsVector7getNormEv80
_ZNK4PLMD3ves12CoeffsVector9getL1NormEv0
_ZNK4PLMD3ves12CoeffsVector9getL2NormEv80
_ZNK4PLMD3ves12CoeffsVector9getLpNormEd0
_ZNK4PLMD3ves12CoeffsVector9sameShapeERNS0_12CoeffsMatrixE0
_ZNK4PLMD3ves12CoeffsVector9sameShapeERS1_6
_ZNK4PLMD3ves12CoeffsVectorclERKSt6vectorIjSaIjEE0
_ZNK4PLMD3ves12CoeffsVectorclEm1790345
_ZNK4PLMD3ves12CoeffsVectorixERKSt6vectorIjSaIjEE0
_ZNK4PLMD3ves12CoeffsVectorixEm0
_ZNK4PLMD3ves12CoeffsVectormiERKS1_45420
_ZNK4PLMD3ves12CoeffsVectormlERKS1_22765
_ZNK4PLMD3ves12CoeffsVectorngEv0
_ZNK4PLMD3ves12CoeffsVectorplERKS1_22735
_ZNK4PLMD3ves12CoeffsVectorpsEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.cpp.gcov.html b/coverage/ves/CoeffsVector.cpp.gcov.html new file mode 100644 index 000000000000..0936608af38d --- /dev/null +++ b/coverage/ves/CoeffsVector.cpp.gcov.html @@ -0,0 +1,972 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:23245850.7 %
Date:2024-02-22 21:58:45Functions:459945.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "CoeffsVector.h"
+      24             : #include "CoeffsMatrix.h"
+      25             : #include "BasisFunctions.h"
+      26             : 
+      27             : #include "tools/Tools.h"
+      28             : #include "core/Value.h"
+      29             : #include "tools/File.h"
+      30             : #include "tools/Exception.h"
+      31             : #include "tools/Random.h"
+      32             : #include "tools/Communicator.h"
+      33             : 
+      34             : #include <vector>
+      35             : #include <cmath>
+      36             : #include <iostream>
+      37             : #include <sstream>
+      38             : #include <cstdio>
+      39             : #include <cfloat>
+      40             : 
+      41             : 
+      42             : namespace PLMD {
+      43             : namespace ves {
+      44             : 
+      45           0 : CoeffsVector::CoeffsVector(
+      46             :   const std::string& label,
+      47             :   const std::vector<std::string>& dimension_labels,
+      48             :   const std::vector<unsigned int>& indices_shape,
+      49             :   Communicator& cc,
+      50           0 :   const bool use_iteration_counter):
+      51             :   CoeffsBase(label,dimension_labels,indices_shape,use_iteration_counter),
+      52           0 :   data(0),
+      53           0 :   averaging_counter(0),
+      54           0 :   averaging_exp_decay_(0),
+      55           0 :   mycomm(cc)
+      56             : {
+      57           0 :   clear();
+      58           0 : }
+      59             : 
+      60             : 
+      61         377 : CoeffsVector::CoeffsVector(
+      62             :   const std::string& label,
+      63             :   const std::vector<Value*>& args,
+      64             :   std::vector<BasisFunctions*>& basisf,
+      65             :   Communicator& cc,
+      66         377 :   const bool use_iteration_counter):
+      67             :   CoeffsBase(label,args,basisf,use_iteration_counter),
+      68         377 :   data(0),
+      69         377 :   averaging_counter(0),
+      70         377 :   averaging_exp_decay_(0),
+      71         377 :   mycomm(cc)
+      72             : {
+      73         377 :   clear();
+      74         377 : }
+      75             : 
+      76             : 
+      77           0 : CoeffsVector::CoeffsVector(
+      78             :   const std::string& label,
+      79             :   std::vector<std::vector<Value*> >& argsv,
+      80             :   std::vector<std::vector<BasisFunctions*> >& basisfv,
+      81             :   Communicator& cc,
+      82             :   const bool use_iteration_counter,
+      83           0 :   const std::string& multicoeffs_label):
+      84             :   CoeffsBase(label,argsv,basisfv,use_iteration_counter,multicoeffs_label),
+      85           0 :   data(0),
+      86           0 :   averaging_counter(0),
+      87           0 :   averaging_exp_decay_(0),
+      88           0 :   mycomm(cc)
+      89             : {
+      90           0 :   clear();
+      91           0 : }
+      92             : 
+      93             : 
+      94           0 : CoeffsVector::CoeffsVector(
+      95             :   const std::string& label,
+      96             :   CoeffsMatrix* coeffsMat,
+      97           0 :   Communicator& cc):
+      98             :   CoeffsBase( *(static_cast<CoeffsBase*>(coeffsMat)) ),
+      99           0 :   data(0),
+     100           0 :   averaging_counter(0),
+     101           0 :   averaging_exp_decay_(0),
+     102           0 :   mycomm(cc)
+     103             : {
+     104           0 :   clear();
+     105           0 : }
+     106             : 
+     107             : 
+     108      341962 : CoeffsVector::~CoeffsVector() {}
+     109             : 
+     110             : 
+     111       23209 : void CoeffsVector::clear() {
+     112       23209 :   data.resize(getSize());
+     113     1833419 :   for(size_t i=0; i<data.size(); i++) {
+     114     1810210 :     data[i]=0.0;
+     115             :   }
+     116       23209 : }
+     117             : 
+     118             : 
+     119           2 : void CoeffsVector::setAllValuesToZero() {
+     120          24 :   for(size_t i=0; i<data.size(); i++) {
+     121          22 :     data[i]=0.0;
+     122             :   }
+     123           2 : }
+     124             : 
+     125             : 
+     126           6 : bool CoeffsVector::sameShape(CoeffsVector& coeffsvector_in) const {
+     127           6 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsvector_in)) );
+     128             : }
+     129             : 
+     130             : 
+     131           0 : bool CoeffsVector::sameShape(CoeffsMatrix& coeffsmat_in) const {
+     132           0 :   return CoeffsBase::sameShape( *(static_cast<CoeffsBase*>(&coeffsmat_in)) );
+     133             : }
+     134             : 
+     135             : 
+     136           0 : bool CoeffsVector::sameShape(CoeffsVector& coeffsvec0, CoeffsVector& coeffsvec1) {
+     137           0 :   return coeffsvec0.sameShape(coeffsvec1);
+     138             : }
+     139             : 
+     140             : 
+     141           0 : void CoeffsVector::resizeCoeffs(const std::vector<unsigned int>& indices_shape_new) {
+     142           0 :   CoeffsVector coeffsVecOld(*this);
+     143           0 :   resizeIndices(indices_shape_new);
+     144           0 :   clear();
+     145           0 :   setValuesFromDifferentShape(coeffsVecOld);
+     146           0 : }
+     147             : 
+     148             : 
+     149           0 : void CoeffsVector::resizeCoeffs(std::vector<BasisFunctions*>& basisf_new) {
+     150           0 :   CoeffsVector coeffsVecOld(*this);
+     151           0 :   resizeIndices(basisf_new);
+     152           0 :   clear();
+     153           0 :   setValuesFromDifferentShape(coeffsVecOld);
+     154           0 : }
+     155             : 
+     156             : 
+     157           0 : void CoeffsVector::sumCommMPI() {
+     158           0 :   mycomm.Sum(data);
+     159           0 : }
+     160             : 
+     161             : 
+     162           0 : void CoeffsVector::sumCommMPI(Communicator& cc) {
+     163           0 :   cc.Sum(data);
+     164           0 : }
+     165             : 
+     166             : 
+     167           0 : void CoeffsVector::sumMultiSimCommMPI(Communicator& multi_sim_cc) {
+     168           0 :   if(mycomm.Get_rank()==0) {
+     169           0 :     double nwalkers = static_cast<double>(multi_sim_cc.Get_size());
+     170           0 :     multi_sim_cc.Sum(data);
+     171           0 :     scaleAllValues(1.0/nwalkers);
+     172             :   }
+     173           0 :   mycomm.Bcast(data,0);
+     174           0 : }
+     175             : 
+     176             : 
+     177         178 : double& CoeffsVector::operator[](const size_t index) {
+     178             :   plumed_dbg_assert(index<data.size());
+     179         178 :   return data[index];
+     180             : }
+     181             : 
+     182             : 
+     183           0 : const double& CoeffsVector::operator[](const size_t index) const {
+     184             :   plumed_dbg_assert(index<data.size());
+     185           0 :   return data[index];
+     186             : }
+     187             : 
+     188             : 
+     189           0 : double& CoeffsVector::operator[](const std::vector<unsigned int>& indices) {
+     190           0 :   return data[getIndex(indices)];
+     191             : }
+     192             : 
+     193             : 
+     194           0 : const double& CoeffsVector::operator[](const std::vector<unsigned int>& indices) const {
+     195           0 :   return data[getIndex(indices)];
+     196             : }
+     197             : 
+     198             : 
+     199     1790345 : double& CoeffsVector::operator()(const size_t index) {
+     200             :   plumed_dbg_assert(index<data.size());
+     201     1790345 :   return data[index];
+     202             : }
+     203             : 
+     204             : 
+     205     1790345 : const double& CoeffsVector::operator()(const size_t index) const {
+     206             :   plumed_dbg_assert(index<data.size());
+     207     1790345 :   return data[index];
+     208             : }
+     209             : 
+     210             : 
+     211           0 : double& CoeffsVector::operator()(const std::vector<unsigned int>& indices) {
+     212           0 :   return data[getIndex(indices)];
+     213             : }
+     214             : 
+     215             : 
+     216           0 : const double& CoeffsVector::operator()(const std::vector<unsigned int>& indices) const {
+     217           0 :   return data[getIndex(indices)];
+     218             : }
+     219             : 
+     220             : 
+     221         219 : void CoeffsVector::setValue(const size_t index, const double value) {
+     222             :   plumed_dbg_assert(index<data.size());
+     223         219 :   data[index]=value;
+     224         219 : }
+     225             : 
+     226             : 
+     227           0 : void CoeffsVector::setValue(const std::vector<unsigned int>& indices, const double value) {
+     228           0 :   setValue(getIndex(indices),value);
+     229           0 : }
+     230             : 
+     231             : 
+     232           0 : void CoeffsVector::addToValue(const size_t index, const double value) {
+     233             :   plumed_dbg_assert(index<data.size());
+     234           0 :   data[index]+=value;
+     235           0 : }
+     236             : 
+     237             : 
+     238           0 : void CoeffsVector::addToValue(const std::vector<unsigned int>& indices, const double value) {
+     239           0 :   addToValue(getIndex(indices),value);
+     240           0 : }
+     241             : 
+     242             : 
+     243       45477 : void CoeffsVector::scaleAllValues(const double scalef) {
+     244     3626338 :   for(size_t i=0; i<data.size(); i++) {
+     245     3580861 :     data[i]*=scalef;
+     246             :   }
+     247       45477 : }
+     248             : 
+     249             : 
+     250       45470 : CoeffsVector& CoeffsVector::operator*=(const double scalef) {
+     251       45470 :   scaleAllValues(scalef);
+     252       45470 :   return *this;
+     253             : }
+     254             : 
+     255             : 
+     256       45430 : CoeffsVector operator*(const double scalef, const CoeffsVector& coeffsvector) {
+     257       45430 :   return CoeffsVector(coeffsvector)*=scalef;
+     258             : }
+     259             : 
+     260             : 
+     261           0 : CoeffsVector operator*(const CoeffsVector& coeffsvector, const double scalef) {
+     262           0 :   return scalef*coeffsvector;
+     263             : }
+     264             : 
+     265             : 
+     266          20 : void CoeffsVector::multiplyWithValues(const std::vector<double>& values) {
+     267          20 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     268         240 :   for(size_t i=0; i<data.size(); i++) {
+     269         220 :     data[i]*=values[i];
+     270             :   }
+     271          20 : }
+     272             : 
+     273             : 
+     274       22765 : CoeffsVector& CoeffsVector::operator*=(const CoeffsVector& other_coeffsvector) {
+     275       22765 :   plumed_massert(data.size()==other_coeffsvector.getSize(),"Coeffs vectors do not have the same size");
+     276     1813440 :   for(size_t i=0; i<data.size(); i++) {
+     277     1790675 :     data[i]*=other_coeffsvector.data[i];
+     278             :   }
+     279       22765 :   return *this;
+     280             : }
+     281             : 
+     282             : 
+     283       22765 : CoeffsVector CoeffsVector::operator*(const CoeffsVector& other_coeffsvector) const {
+     284       22765 :   return CoeffsVector(*this)*=other_coeffsvector;
+     285             : }
+     286             : 
+     287             : 
+     288           0 : CoeffsVector operator*(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
+     289           0 :   return coeffsvector*values;
+     290             : }
+     291             : 
+     292             : 
+     293          20 : CoeffsVector& CoeffsVector::operator*=(const std::vector<double>& values) {
+     294          20 :   multiplyWithValues(values);
+     295          20 :   return *this;
+     296             : }
+     297             : 
+     298             : 
+     299          20 : CoeffsVector operator*(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
+     300          20 :   return CoeffsVector(coeffsvector)*=values;
+     301             : }
+     302             : 
+     303             : 
+     304         174 : void CoeffsVector::setValues(const double value) {
+     305        8402 :   for(size_t i=0; i<data.size(); i++) {
+     306        8228 :     data[i]=value;
+     307             :   }
+     308         174 : }
+     309             : 
+     310             : 
+     311         700 : void CoeffsVector::setValues(const std::vector<double>& values) {
+     312         700 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     313       23133 :   for(size_t i=0; i<data.size(); i++) {
+     314       22433 :     data[i]=values[i];
+     315             :   }
+     316         700 : }
+     317             : 
+     318             : 
+     319       23410 : void CoeffsVector::setValues(const CoeffsVector& other_coeffsvector) {
+     320       23410 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
+     321     1847404 :   for(size_t i=0; i<data.size(); i++) {
+     322     1823994 :     data[i]=other_coeffsvector.data[i];
+     323             :   }
+     324       23410 : }
+     325             : 
+     326             : 
+     327           0 : CoeffsVector& CoeffsVector::operator=(const double value) {
+     328           0 :   setValues(value);
+     329           0 :   return *this;
+     330             : }
+     331             : 
+     332             : 
+     333         453 : CoeffsVector& CoeffsVector::operator=(const std::vector<double>& values) {
+     334         453 :   setValues(values);
+     335         453 :   return *this;
+     336             : }
+     337             : 
+     338             : 
+     339             : // CoeffsVector& CoeffsVector::operator=(const CoeffsVector& other_coeffsvector) {
+     340             : //   setValues(other_coeffsvector);
+     341             : //   return *this;
+     342             : // }
+     343             : 
+     344             : 
+     345           0 : CoeffsVector CoeffsVector::operator+() const {
+     346           0 :   return *this;
+     347             : }
+     348             : 
+     349             : 
+     350           0 : CoeffsVector CoeffsVector::operator-() const {
+     351           0 :   return CoeffsVector(*this)*=-1.0;
+     352             : }
+     353             : 
+     354             : 
+     355           0 : void CoeffsVector::addToValues(const double value) {
+     356           0 :   for(size_t i=0; i<data.size(); i++) {
+     357           0 :     data[i]+=value;
+     358             :   }
+     359           0 : }
+     360             : 
+     361             : 
+     362           0 : void CoeffsVector::addToValues(const std::vector<double>& values) {
+     363           0 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     364           0 :   for(size_t i=0; i<data.size(); i++) {
+     365           0 :     data[i]+=values[i];
+     366             :   }
+     367           0 : }
+     368             : 
+     369             : 
+     370       68145 : void CoeffsVector::addToValues(const CoeffsVector& other_coeffsvector) {
+     371       68145 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
+     372     5438520 :   for(size_t i=0; i<data.size(); i++) {
+     373     5370375 :     data[i]+=other_coeffsvector.data[i];
+     374             :   }
+     375       68145 : }
+     376             : 
+     377             : 
+     378           0 : void CoeffsVector::subtractFromValues(const double value) {
+     379           0 :   for(size_t i=0; i<data.size(); i++) {
+     380           0 :     data[i]-=value;
+     381             :   }
+     382           0 : }
+     383             : 
+     384             : 
+     385       22810 : void CoeffsVector::subtractFromValues(const std::vector<double>& values) {
+     386       22810 :   plumed_massert( data.size()==values.size(), "Incorrect size");
+     387     1823850 :   for(size_t i=0; i<data.size(); i++) {
+     388     1801040 :     data[i]-=values[i];
+     389             :   }
+     390       22810 : }
+     391             : 
+     392             : 
+     393       45440 : void CoeffsVector::subtractFromValues(const CoeffsVector& other_coeffsvector) {
+     394       45440 :   plumed_massert( data.size()==other_coeffsvector.getSize(), "Incorrect size");
+     395     3625800 :   for(size_t i=0; i<data.size(); i++) {
+     396     3580360 :     data[i]-=other_coeffsvector.data[i];
+     397             :   }
+     398       45440 : }
+     399             : 
+     400             : 
+     401           0 : CoeffsVector& CoeffsVector::operator+=(const double value) {
+     402           0 :   addToValues(value);
+     403           0 :   return *this;
+     404             : }
+     405             : 
+     406             : 
+     407           0 : CoeffsVector operator+(const double value, const CoeffsVector& coeffsvector) {
+     408           0 :   return coeffsvector+value;
+     409             : }
+     410             : 
+     411             : 
+     412           0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const double value) {
+     413           0 :   return CoeffsVector(coeffsvector)+=value;
+     414             : }
+     415             : 
+     416             : 
+     417           0 : CoeffsVector& CoeffsVector::operator+=(const std::vector<double>& values) {
+     418           0 :   addToValues(values);
+     419           0 :   return *this;
+     420             : }
+     421             : 
+     422             : 
+     423           0 : CoeffsVector operator+(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
+     424           0 :   return coeffsvector+values;
+     425             : }
+     426             : 
+     427             : 
+     428           0 : CoeffsVector operator+(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
+     429           0 :   return CoeffsVector(coeffsvector)+=values;
+     430             : }
+     431             : 
+     432             : 
+     433           0 : CoeffsVector& CoeffsVector::operator-=(const double value) {
+     434           0 :   subtractFromValues(value);
+     435           0 :   return *this;
+     436             : }
+     437             : 
+     438             : 
+     439           0 : CoeffsVector operator-(const double value, const CoeffsVector& coeffsvector) {
+     440           0 :   return -1.0*coeffsvector+value;
+     441             : }
+     442             : 
+     443             : 
+     444           0 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const double value) {
+     445           0 :   return CoeffsVector(coeffsvector)-=value;
+     446             : }
+     447             : 
+     448             : 
+     449       22810 : CoeffsVector& CoeffsVector::operator-=(const std::vector<double>& values) {
+     450       22810 :   subtractFromValues(values);
+     451       22810 :   return *this;
+     452             : }
+     453             : 
+     454             : 
+     455           0 : CoeffsVector operator-(const std::vector<double>& values, const CoeffsVector& coeffsvector) {
+     456           0 :   return -1.0*coeffsvector+values;
+     457             : }
+     458             : 
+     459             : 
+     460       22810 : CoeffsVector operator-(const CoeffsVector& coeffsvector, const std::vector<double>& values) {
+     461       22810 :   return CoeffsVector(coeffsvector)-=values;
+     462             : }
+     463             : 
+     464             : 
+     465       68145 : CoeffsVector& CoeffsVector::operator+=(const CoeffsVector& other_coeffsvector) {
+     466       68145 :   addToValues(other_coeffsvector);
+     467       68145 :   return *this;
+     468             : }
+     469             : 
+     470             : 
+     471       22735 : CoeffsVector CoeffsVector::operator+(const CoeffsVector& other_coeffsvector) const {
+     472       22735 :   return CoeffsVector(*this)+=other_coeffsvector;
+     473             : }
+     474             : 
+     475             : 
+     476       45440 : CoeffsVector& CoeffsVector::operator-=(const CoeffsVector& other_coeffsvector) {
+     477       45440 :   subtractFromValues(other_coeffsvector);
+     478       45440 :   return *this;
+     479             : }
+     480             : 
+     481             : 
+     482       45420 : CoeffsVector CoeffsVector::operator-(const CoeffsVector& other_coeffsvector) const {
+     483       45420 :   return CoeffsVector(*this)-=other_coeffsvector;
+     484             : }
+     485             : 
+     486             : 
+     487           0 : void CoeffsVector::setValuesFromDifferentShape(const CoeffsVector& other_coeffsvector) {
+     488           0 :   plumed_massert(numberOfDimensions()==other_coeffsvector.numberOfDimensions(),"both coeffs vector need to have the same dimension");
+     489           0 :   for(size_t i=0; i<data.size(); i++) {
+     490           0 :     std::vector<unsigned int> indices=getIndices(i);
+     491           0 :     if(other_coeffsvector.indicesExist(indices)) {
+     492           0 :       size_t oidx = other_coeffsvector.getIndex(indices);
+     493           0 :       data[i] = other_coeffsvector.data[oidx];
+     494             :     }
+     495             :   }
+     496           0 : }
+     497             : 
+     498             : 
+     499           0 : void CoeffsVector::averageVectors(CoeffsVector& coeffsvec0, CoeffsVector& coeffsvec1) {
+     500           0 :   plumed_massert(sameShape(coeffsvec0,coeffsvec1),"both CoeffsVector objects need to have the same shape");
+     501           0 :   for(size_t i=0; i<coeffsvec0.getSize(); i++) {
+     502           0 :     coeffsvec0.data[i] = coeffsvec1.data[i] = 0.5 * (coeffsvec0.data[i]+coeffsvec1.data[i]);
+     503             :   }
+     504           0 : }
+     505             : 
+     506             : 
+     507           0 : void CoeffsVector::averageVectors(const std::vector<CoeffsVector*>& coeffsvecSet) {
+     508           0 :   const double norm_factor = 1.0/static_cast<double>(coeffsvecSet.size());
+     509           0 :   for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
+     510           0 :     plumed_massert(coeffsvecSet[0]->sameShape(*coeffsvecSet[k]),"All CoeffsVector objects need to have the same shape");
+     511             :   }
+     512           0 :   for(size_t i=0; i<coeffsvecSet[0]->getSize(); i++) {
+     513             :     double value = 0.0;
+     514           0 :     for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
+     515           0 :       value += coeffsvecSet[k]->data[i];
+     516             :     }
+     517           0 :     value *= norm_factor;
+     518           0 :     for(unsigned int k=0; k<coeffsvecSet.size(); k++) {
+     519           0 :       coeffsvecSet[k]->data[i] = value;
+     520             :     }
+     521             :   }
+     522           0 : }
+     523             : 
+     524             : 
+     525           0 : double CoeffsVector::getMinValue() const {
+     526           0 :   size_t min_index=0;
+     527           0 :   return getMinValue(min_index);
+     528             : }
+     529             : 
+     530             : 
+     531           0 : double CoeffsVector::getMinValue(size_t& min_index) const {
+     532           0 :   min_index=0;
+     533             :   double min_value=DBL_MAX;
+     534           0 :   for(size_t i=0; i<data.size(); i++) {
+     535           0 :     if(data[i]<min_value) {
+     536             :       min_value=data[i];
+     537           0 :       min_index=i;
+     538             :     }
+     539             :   }
+     540           0 :   return min_value;
+     541             : }
+     542             : 
+     543             : 
+     544           0 : double CoeffsVector::getMinAbsValue() const {
+     545           0 :   size_t min_index=0;
+     546           0 :   return getMinAbsValue(min_index);
+     547             : }
+     548             : 
+     549             : 
+     550           0 : double CoeffsVector::getMinAbsValue(size_t& min_index) const {
+     551           0 :   min_index=0;
+     552             :   double min_value=DBL_MAX;
+     553           0 :   for(size_t i=0; i<data.size(); i++) {
+     554           0 :     if(std::abs(data[i])<min_value) {
+     555             :       min_value=std::abs(data[i]);
+     556           0 :       min_index=i;
+     557             :     }
+     558             :   }
+     559           0 :   return min_value;
+     560             : }
+     561             : 
+     562             : 
+     563           0 : double CoeffsVector::getMaxValue() const {
+     564           0 :   size_t max_index=0;
+     565           0 :   return getMaxValue(max_index);
+     566             : }
+     567             : 
+     568             : 
+     569           0 : double CoeffsVector::getMaxValue(size_t& max_index) const {
+     570           0 :   max_index=0;
+     571             :   double max_value=DBL_MIN;
+     572           0 :   for(size_t i=0; i<data.size(); i++) {
+     573           0 :     if(data[i]>max_value) {
+     574             :       max_value=data[i];
+     575           0 :       max_index=i;
+     576             :     }
+     577             :   }
+     578           0 :   return max_value;
+     579             : }
+     580             : 
+     581             : 
+     582           0 : double CoeffsVector::getMaxAbsValue() const {
+     583           0 :   size_t max_index=0;
+     584           0 :   return getMaxAbsValue(max_index);
+     585             : }
+     586             : 
+     587             : 
+     588          80 : double CoeffsVector::getMaxAbsValue(size_t& max_index) const {
+     589          80 :   max_index=0;
+     590             :   double max_value=0.0;
+     591         960 :   for(size_t i=0; i<data.size(); i++) {
+     592         880 :     if(std::abs(data[i])>max_value) {
+     593             :       max_value=std::abs(data[i]);
+     594         180 :       max_index=i;
+     595             :     }
+     596             :   }
+     597          80 :   return max_value;
+     598             : }
+     599             : 
+     600             : 
+     601          80 : double CoeffsVector::getNorm() const {
+     602          80 :   return getL2Norm();
+     603             : }
+     604             : 
+     605             : 
+     606           0 : double CoeffsVector::getL1Norm() const {
+     607             :   double norm=0.0;
+     608           0 :   for(size_t i=0; i<data.size(); i++) {
+     609           0 :     norm+=std::abs(data[i]);
+     610             :   }
+     611           0 :   return norm;
+     612             : }
+     613             : 
+     614             : 
+     615          80 : double CoeffsVector::getL2Norm() const {
+     616             :   double norm=0.0;
+     617         960 :   for(size_t i=0; i<data.size(); i++) {
+     618         880 :     norm+=data[i]*data[i];
+     619             :   }
+     620          80 :   norm=sqrt(norm);
+     621          80 :   return norm;
+     622             : }
+     623             : 
+     624             : 
+     625           0 : double CoeffsVector::getLpNorm(const double p) const {
+     626             :   double norm=0.0;
+     627           0 :   for(size_t i=0; i<data.size(); i++) {
+     628           0 :     norm+=pow(data[i],p);
+     629             :   }
+     630           0 :   norm=pow(norm,(1.0/p));
+     631           0 :   return norm;
+     632             : }
+     633             : 
+     634             : 
+     635          80 : double CoeffsVector::getRMS() const {
+     636          80 :   return getNorm()/sqrt(numberOfCoeffs());
+     637             : }
+     638             : 
+     639             : 
+     640           0 : void CoeffsVector::normalizeCoeffs() {
+     641           0 :   double norm=getNorm();
+     642           0 :   scaleAllValues(norm);
+     643           0 : }
+     644             : 
+     645             : 
+     646           0 : void CoeffsVector::randomizeValuesGaussian(int randomSeed) {
+     647           0 :   Random rnd;
+     648             :   if (randomSeed<0) {randomSeed = -randomSeed;}
+     649           0 :   rnd.setSeed(-randomSeed);
+     650           0 :   for(size_t i=0; i<data.size(); i++) {
+     651           0 :     data[i]=rnd.Gaussian();
+     652             :   }
+     653           0 : }
+     654             : 
+     655             : 
+     656           0 : void CoeffsVector::resetAveraging() {
+     657           0 :   clear();
+     658             :   resetAveragingCounter();
+     659           0 : }
+     660             : 
+     661             : 
+     662          20 : void CoeffsVector::addToAverage(const CoeffsVector& coeffsvec) {
+     663          20 :   plumed_massert( data.size()==coeffsvec.getSize(), "Incorrect size");
+     664             :   //
+     665          20 :   double aver_decay = 1.0 / ( static_cast<double>(averaging_counter) + 1.0 );
+     666          20 :   if(averaging_exp_decay_>0 &&  (averaging_counter+1 > averaging_exp_decay_) ) {
+     667           9 :     aver_decay = 1.0 / static_cast<double>(averaging_exp_decay_);
+     668             :   }
+     669             :   //
+     670         240 :   for(size_t i=0; i<data.size(); i++) {
+     671         220 :     data[i]+=(coeffsvec.data[i]-data[i])*aver_decay;
+     672             :   }
+     673          20 :   averaging_counter++;
+     674          20 : }
+     675             : 
+     676             : 
+     677           1 : size_t CoeffsVector::countValues(const double value) const {
+     678             :   size_t numvalues=0;
+     679          12 :   for(size_t i=0; i<data.size(); i++) {
+     680          11 :     if(data[i]==value) {
+     681           2 :       numvalues++;
+     682             :     }
+     683             :   }
+     684           1 :   return numvalues;
+     685             : }
+     686             : 
+     687             : 
+     688           0 : void CoeffsVector::writeToFile(const std::string& filepath, const bool print_coeffs_descriptions, const bool append_file, Action* action_pntr) {
+     689           0 :   OFile file;
+     690           0 :   if(action_pntr!=NULL) {
+     691           0 :     file.link(*action_pntr);
+     692             :   }
+     693             :   else {
+     694           0 :     file.link(mycomm);
+     695             :   }
+     696           0 :   if(append_file) { file.enforceRestart(); }
+     697           0 :   file.open(filepath);
+     698           0 :   writeToFile(file,print_coeffs_descriptions);
+     699           0 :   file.close();
+     700           0 : }
+     701             : 
+     702             : 
+     703        1467 : void CoeffsVector::writeToFile(OFile& ofile, const bool print_coeffs_descriptions) {
+     704             :   std::vector<CoeffsVector*> CoeffsSetTmp;
+     705        1467 :   CoeffsSetTmp.push_back(this);
+     706        1467 :   writeHeaderToFile(ofile);
+     707        1467 :   writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
+     708        1467 : }
+     709             : 
+     710             : 
+     711         881 : void CoeffsVector::writeToFile(OFile& ofile, CoeffsVector* aux_coeffsvector, const bool print_coeffs_descriptions) {
+     712             :   std::vector<CoeffsVector*> CoeffsSetTmp;
+     713         881 :   CoeffsSetTmp.push_back(this);
+     714         881 :   CoeffsSetTmp.push_back(aux_coeffsvector);
+     715         881 :   writeHeaderToFile(ofile);
+     716         881 :   writeDataToFile(ofile,CoeffsSetTmp,print_coeffs_descriptions);
+     717         881 : }
+     718             : 
+     719             : 
+     720           0 : void CoeffsVector::writeToFile(const std::string& filepath, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions, const bool append_file, Action* action_pntr) {
+     721           0 :   OFile file;
+     722           0 :   if(action_pntr!=NULL) {
+     723           0 :     file.link(*action_pntr);
+     724             :   }
+     725             :   else {
+     726           0 :     file.link(coeffsvecSet[0]->getCommunicator());
+     727             :   }
+     728           0 :   if(append_file) { file.enforceRestart(); }
+     729           0 :   file.open(filepath);
+     730           0 :   writeToFile(file,coeffsvecSet,print_coeffs_descriptions);
+     731           0 :   file.close();
+     732           0 : }
+     733             : 
+     734             : 
+     735           0 : void CoeffsVector::writeToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
+     736           0 :   for(unsigned int k=1; k<coeffsvecSet.size(); k++) {
+     737           0 :     plumed_massert(coeffsvecSet[k]->sameShape(*coeffsvecSet[0]),"Error in writing a set of coeffs to file: The coeffs do not have the same shape and size");
+     738             :   }
+     739           0 :   coeffsvecSet[0]->writeHeaderToFile(ofile);
+     740           0 :   writeDataToFile(ofile,coeffsvecSet, print_coeffs_descriptions);
+     741           0 : }
+     742             : 
+     743             : 
+     744        2348 : void CoeffsVector::writeHeaderToFile(OFile& ofile) const {
+     745        2348 :   ofile.clearFields();
+     746        2348 :   if(isIterationCounterActive()) {
+     747        2061 :     writeIterationCounterAndTimeToFile(ofile);
+     748             :   }
+     749        2348 :   writeCoeffsInfoToFile(ofile);
+     750        2348 : }
+     751             : 
+     752             : 
+     753        2348 : void CoeffsVector::writeDataToFile(OFile& ofile, const std::vector<CoeffsVector*>& coeffsvecSet, const bool print_coeffs_descriptions) {
+     754             :   //
+     755        2348 :   std::string field_indices_prefix = "idx_";
+     756        2348 :   std::string field_index = "index";
+     757        2348 :   std::string field_description = "description";
+     758             :   //
+     759        2348 :   std::string int_fmt = "%8d";
+     760        2348 :   std::string str_separate = "#!-------------------";
+     761             :   //
+     762        2348 :   unsigned int numvec = coeffsvecSet.size();
+     763        2348 :   unsigned int numdim = coeffsvecSet[0]->numberOfDimensions();
+     764             :   unsigned int numcoeffs = coeffsvecSet[0]->getSize();
+     765             :   std::vector<std::string> coeffs_descriptions = coeffsvecSet[0]->getAllCoeffsDescriptions();
+     766        2348 :   std::string output_fmt = coeffsvecSet[0]->getOutputFmt();
+     767        2348 :   std::vector<std::string> coeffs_datalabels(numvec);
+     768        5577 :   for(unsigned int k=0; k<numvec; k++) {
+     769        6458 :     coeffs_datalabels[k] = coeffsvecSet[k]->getDataLabel();
+     770             :   }
+     771             :   //
+     772        2348 :   std::vector<char> s1(20);
+     773        2348 :   std::vector<unsigned int> indices(numdim);
+     774        2348 :   std::vector<std::string> ilabels(numdim);
+     775        5260 :   for(unsigned int k=0; k<numdim; k++) {
+     776        5824 :     ilabels[k]=field_indices_prefix+coeffsvecSet[0]->getDimensionLabel(k);
+     777             :   }
+     778             :   //
+     779       86666 :   for(size_t i=0; i<numcoeffs; i++) {
+     780       84318 :     indices=coeffsvecSet[0]->getIndices(i);
+     781      233206 :     for(unsigned int k=0; k<numdim; k++) {
+     782      148888 :       std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),indices[k]);
+     783      297776 :       ofile.printField(ilabels[k],s1.data());
+     784             :     }
+     785      203216 :     for(unsigned int l=0; l<numvec; l++) {
+     786      237796 :       ofile.fmtField(" "+output_fmt).printField(coeffs_datalabels[l],coeffsvecSet[l]->getValue(i));
+     787             :     }
+     788       84318 :     std::snprintf(s1.data(),s1.size(),int_fmt.c_str(),i); ofile.printField(field_index,s1.data());
+     789       89064 :     if(print_coeffs_descriptions) { ofile.printField(field_description,"  "+coeffs_descriptions[i]);}
+     790       84318 :     ofile.printField();
+     791             :   }
+     792        2348 :   ofile.fmtField();
+     793             :   // blank line between iterations to allow proper plotting with gnuplot
+     794        2348 :   ofile.printf("%s\n",str_separate.c_str());
+     795        2348 :   ofile.printf("\n");
+     796        2348 :   ofile.printf("\n");
+     797        9392 : }
+     798             : 
+     799             : 
+     800          75 : size_t CoeffsVector::readFromFile(IFile& ifile, const bool ignore_missing_coeffs, const bool ignore_header) {
+     801          75 :   ifile.allowIgnoredFields();
+     802             :   size_t ncoeffs_read=0;
+     803         594 :   while(ifile) {
+     804         444 :     if(!ignore_header) {readHeaderFromFile(ifile);}
+     805         444 :     if(ifile) {
+     806         409 :       ncoeffs_read=readDataFromFile(ifile,ignore_missing_coeffs);
+     807             :     }
+     808             :   }
+     809          75 :   return ncoeffs_read;
+     810             : }
+     811             : 
+     812             : 
+     813          36 : size_t CoeffsVector::readOneSetFromFile(IFile& ifile, const bool ignore_header) {
+     814          36 :   ifile.allowIgnoredFields();
+     815             :   size_t ncoeffs_read=0;
+     816          36 :   if(ifile) {
+     817          36 :     if(!ignore_header) {readHeaderFromFile(ifile);}
+     818          36 :     if(ifile) {ncoeffs_read=readDataFromFile(ifile,false);}
+     819             :   }
+     820          36 :   return ncoeffs_read;
+     821             : }
+     822             : 
+     823             : 
+     824          40 : size_t CoeffsVector::readFromFile(const std::string& filepath, const bool ignore_missing_coeffs, const bool ignore_header) {
+     825          40 :   IFile file;
+     826          40 :   file.link(mycomm);
+     827          40 :   file.open(filepath);
+     828          40 :   size_t ncoeffs_read=readFromFile(file,ignore_missing_coeffs, ignore_header);
+     829          40 :   file.close();
+     830          40 :   return ncoeffs_read;
+     831          40 : }
+     832             : 
+     833             : 
+     834         406 : void CoeffsVector::readHeaderFromFile(IFile& ifile, const bool ignore_coeffs_info) {
+     835         406 :   if(ifile && isIterationCounterActive()) {
+     836         406 :     getIterationCounterAndTimeFromFile(ifile);
+     837             :   }
+     838         406 :   if(ifile) {
+     839         368 :     getCoeffsInfoFromFile(ifile,ignore_coeffs_info);
+     840             :   }
+     841         406 : }
+     842             : 
+     843             : 
+     844         442 : size_t CoeffsVector::readDataFromFile(IFile& ifile, const bool ignore_missing_coeffs) {
+     845             :   //
+     846         442 :   std::string field_indices_prefix = "idx_";
+     847             :   std::string field_coeffs = getDataLabel();
+     848         442 :   std::string field_index = "index";
+     849         442 :   std::string field_description = "description";
+     850             :   //
+     851         442 :   std::vector<std::string> ilabels(numberOfDimensions());
+     852         903 :   for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     853         922 :     ilabels[k]=field_indices_prefix+getDimensionLabel(k);
+     854             :   }
+     855             :   //
+     856         442 :   std::vector<unsigned int> indices(numberOfDimensions());
+     857         442 :   double coeff_tmp=0.0;
+     858             :   std::string str_tmp;
+     859             :   size_t ncoeffs_read=0;
+     860             :   //
+     861        5475 :   while(ifile.scanField(field_coeffs,coeff_tmp)) {
+     862             :     int idx_tmp;
+     863       12131 :     for(unsigned int k=0; k<numberOfDimensions(); k++) {
+     864        6696 :       ifile.scanField(ilabels[k],idx_tmp);
+     865        6696 :       indices[k] = static_cast<unsigned int>(idx_tmp);
+     866             :     }
+     867        5435 :     data[getIndex(indices)] = coeff_tmp;
+     868        5435 :     ifile.scanField(field_index,idx_tmp);
+     869        5435 :     if(getIndex(indices)!=static_cast<unsigned int>(idx_tmp)) {
+     870           0 :       std::string is1; Tools::convert(idx_tmp,is1);
+     871           0 :       std::string msg="ERROR: problem with indices at index " + is1 + " when reading coefficients from file";
+     872           0 :       plumed_merror(msg);
+     873             :     }
+     874        5435 :     if(ifile.FieldExist(field_description)) { ifile.scanField(field_description,str_tmp); }
+     875             :     //
+     876        5435 :     ifile.scanField();
+     877        5435 :     ncoeffs_read++;
+     878        5435 :     if(ncoeffs_read==numberOfCoeffs()) {
+     879         402 :       if((static_cast<unsigned int>(idx_tmp)+1)!=numberOfCoeffs()) {
+     880           0 :         plumed_merror("something strange about the coefficient file that is being read in, perhaps multiple entries or missing values");
+     881             :       }
+     882         402 :       break;
+     883             :     }
+     884             :   }
+     885             :   // checks on the coeffs read
+     886         442 :   if(ncoeffs_read>0 &&!ignore_missing_coeffs && ncoeffs_read < numberOfCoeffs()) {
+     887           0 :     plumed_merror("ERROR: missing coefficients when reading from file");
+     888             :   }
+     889             :   //
+     890         442 :   return ncoeffs_read;
+     891         442 : }
+     892             : 
+     893             : 
+     894             : }
+     895             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.h.func-sort-c.html b/coverage/ves/CoeffsVector.h.func-sort-c.html new file mode 100644 index 000000000000..5e95b122f145 --- /dev/null +++ b/coverage/ves/CoeffsVector.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2450.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.h.func.html b/coverage/ves/CoeffsVector.h.func.html new file mode 100644 index 000000000000..a56068a4f042 --- /dev/null +++ b/coverage/ves/CoeffsVector.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2450.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/CoeffsVector.h.gcov.html b/coverage/ves/CoeffsVector.h.gcov.html new file mode 100644 index 000000000000..4baef4899239 --- /dev/null +++ b/coverage/ves/CoeffsVector.h.gcov.html @@ -0,0 +1,317 @@ + + + + + + + + LCOV - plumed test coverage - ves/CoeffsVector.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - CoeffsVector.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2450.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_CoeffsVector_h
+      23             : #define __PLUMED_ves_CoeffsVector_h
+      24             : 
+      25             : #include "CoeffsBase.h"
+      26             : 
+      27             : #include <vector>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : #include <memory>
+      31             : 
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : class Action;
+      36             : class Value;
+      37             : class IFile;
+      38             : class OFile;
+      39             : class Communicator;
+      40             : 
+      41             : namespace ves {
+      42             : 
+      43             : class BasisFunctions;
+      44             : class CoeffsMatrix;
+      45             : 
+      46             : 
+      47             : class CoeffsVector:
+      48             :   public CoeffsBase
+      49             : {
+      50             : public:
+      51             : private:
+      52             :   std::vector<double> data;
+      53             :   //
+      54             :   unsigned int averaging_counter;
+      55             :   unsigned int averaging_exp_decay_;
+      56             :   //
+      57             :   Communicator& mycomm;
+      58             :   //
+      59             :   CoeffsVector& operator=(const CoeffsVector&);
+      60             : public:
+      61             :   explicit CoeffsVector(
+      62             :     const std::string&,
+      63             :     const std::vector<std::string>&,
+      64             :     const std::vector<unsigned int>&,
+      65             :     Communicator&,
+      66             :     const bool use_counter=false);
+      67             :   //
+      68             :   explicit CoeffsVector(
+      69             :     const std::string&,
+      70             :     const std::vector<Value*>&,
+      71             :     std::vector<BasisFunctions*>&,
+      72             :     Communicator&,
+      73             :     const bool use_counter=false);
+      74             :   //
+      75             :   explicit CoeffsVector(
+      76             :     const std::string&,
+      77             :     std::vector<std::vector<Value*> >&,
+      78             :     std::vector<std::vector<BasisFunctions*> >&,
+      79             :     Communicator&,
+      80             :     const bool use_counter=false,
+      81             :     const std::string& multicoeffs_label="bias");
+      82             :   //
+      83             :   explicit CoeffsVector(
+      84             :     const std::string&,
+      85             :     CoeffsMatrix*,
+      86             :     Communicator&);
+      87             :   //
+      88             :   ~CoeffsVector();
+      89             :   //
+      90             :   size_t getSize() const {return numberOfCoeffs();}
+      91             :   // clear coeffs
+      92             :   void clear();
+      93             :   void setAllValuesToZero();
+      94             :   //
+      95             :   std::vector<double> getDataAsVector() const {return data;}
+      96             :   //
+      97             :   bool sameShape(CoeffsVector&) const;
+      98             :   bool sameShape(CoeffsMatrix&) const;
+      99             :   static bool sameShape(CoeffsVector&, CoeffsVector&);
+     100             :   //
+     101             :   void resizeCoeffs(const std::vector<unsigned int>&);
+     102             :   void resizeCoeffs(std::vector<BasisFunctions*>&);
+     103             :   //
+     104             :   void sumCommMPI();
+     105             :   void sumCommMPI(Communicator& cc);
+     106             :   //
+     107             :   void sumMultiSimCommMPI(Communicator&);
+     108             :   // get value
+     109             :   double getValue(const size_t) const;
+     110             :   double getValue(const std::vector<unsigned int>&) const;
+     111             :   double& operator[](const size_t index);
+     112             :   const double& operator[](const size_t index) const;
+     113             :   double& operator[](const std::vector<unsigned int>&);
+     114             :   const double& operator[](const std::vector<unsigned int>&) const;
+     115             :   double& operator()(const size_t index);
+     116             :   const double& operator()(const size_t index) const;
+     117             :   double& operator()(const std::vector<unsigned int>&);
+     118             :   const double& operator()(const std::vector<unsigned int>&) const;
+     119             :   // set value
+     120             :   void setValue(const size_t, const double);
+     121             :   void setValue(const std::vector<unsigned int>&, const double);
+     122             :   // add to value
+     123             :   void addToValue(const size_t, const double);
+     124             :   void addToValue(const std::vector<unsigned int>&, const double);
+     125             :   // scale all values
+     126             :   void scaleAllValues(const double);
+     127             :   void multiplyWithValues(const std::vector<double>&);
+     128             :   CoeffsVector& operator*=(const double);
+     129             :   friend CoeffsVector operator*(const double, const CoeffsVector&);
+     130             :   friend CoeffsVector operator*(const CoeffsVector&, const double);
+     131             :   CoeffsVector& operator*=(const std::vector<double>&);
+     132             :   friend CoeffsVector operator*(const std::vector<double>&, const CoeffsVector&);
+     133             :   friend CoeffsVector operator*(const CoeffsVector&, const std::vector<double>&);
+     134             :   CoeffsVector& operator*=(const CoeffsVector&);
+     135             :   CoeffsVector operator*(const CoeffsVector&) const;
+     136             :   // set all values
+     137             :   void setValues(const double);
+     138             :   void setValues(const std::vector<double>&);
+     139             :   void setValues(const CoeffsVector&);
+     140             :   CoeffsVector& operator=(const double);
+     141             :   CoeffsVector& operator=(const std::vector<double>&);
+     142             :   // CoeffsVector& operator=(const CoeffsVector&);
+     143             :   // add to all values
+     144             :   CoeffsVector operator+() const;
+     145             :   CoeffsVector operator-() const;
+     146             :   void addToValues(const double);
+     147             :   void addToValues(const std::vector<double>&);
+     148             :   void addToValues(const CoeffsVector&);
+     149             :   void subtractFromValues(const double);
+     150             :   void subtractFromValues(const std::vector<double>&);
+     151             :   void subtractFromValues(const CoeffsVector&);
+     152             :   CoeffsVector& operator+=(const double);
+     153             :   friend CoeffsVector operator+(const double, const CoeffsVector&);
+     154             :   friend CoeffsVector operator+(const CoeffsVector&, const double);
+     155             :   CoeffsVector& operator+=(const std::vector<double>&);
+     156             :   friend CoeffsVector operator+(const std::vector<double>&, const CoeffsVector&);
+     157             :   friend CoeffsVector operator+(const CoeffsVector&, const std::vector<double>&);
+     158             :   CoeffsVector& operator-=(const double);
+     159             :   friend CoeffsVector operator-(const double, const CoeffsVector&);
+     160             :   friend CoeffsVector operator-(const CoeffsVector&, const double);
+     161             :   CoeffsVector& operator-=(const std::vector<double>&);
+     162             :   friend CoeffsVector operator-(const std::vector<double>&, const CoeffsVector&);
+     163             :   friend CoeffsVector operator-(const CoeffsVector&, const std::vector<double>&);
+     164             :   CoeffsVector& operator+=(const CoeffsVector&);
+     165             :   CoeffsVector operator+(const CoeffsVector&) const;
+     166             :   CoeffsVector& operator-=(const CoeffsVector&);
+     167             :   CoeffsVector operator-(const CoeffsVector&) const;
+     168             :   //
+     169             :   void setValuesFromDifferentShape(const CoeffsVector&);
+     170             :   //
+     171             :   static void averageVectors(CoeffsVector&, CoeffsVector&);
+     172             :   static void averageVectors(const std::vector<CoeffsVector*>&);
+     173             :   //
+     174             :   double getMinValue() const;
+     175             :   double getMinValue(size_t&) const;
+     176             :   double getMinAbsValue() const;
+     177             :   double getMinAbsValue(size_t&) const;
+     178             :   //
+     179             :   double getMaxValue() const;
+     180             :   double getMaxValue(size_t&) const;
+     181             :   double getMaxAbsValue() const;
+     182             :   double getMaxAbsValue(size_t&) const;
+     183             :   //
+     184             :   double getNorm() const;
+     185             :   double getL1Norm() const;
+     186             :   double getL2Norm() const;
+     187             :   double getLpNorm(const double) const;
+     188             :   double getRMS() const;
+     189             :   //
+     190             :   void normalizeCoeffs();
+     191             :   // Random values
+     192             :   void randomizeValuesGaussian(int);
+     193             :   //
+     194           0 :   void resetAveragingCounter() {averaging_counter=0;}
+     195           1 :   void setupExponentiallyDecayingAveraging(const unsigned int averaging_exp_decay_in) {averaging_exp_decay_=averaging_exp_decay_in;}
+     196             :   void turnOffExponentiallyDecayingAveraging() {averaging_exp_decay_=0;}
+     197             :   void resetAveraging();
+     198             :   void addToAverage(const CoeffsVector&);
+     199             :   //
+     200             :   size_t countValues(const double) const;
+     201             : 
+     202             :   // file input/output stuff
+     203             :   void writeToFile(const std::string&, const bool print_description=false, const bool append_file=false, Action* action_pntr=NULL);
+     204             :   void writeToFile(OFile&, const bool print_description=false);
+     205             :   void writeToFile(OFile& ofile, CoeffsVector*, const bool print_coeffs_descriptions=false);
+     206             :   static void writeToFile(const std::string&, const std::vector<CoeffsVector*>&, const bool print_description=false, const bool append_file=false, Action* action_pntr=NULL);
+     207             :   static void writeToFile(OFile&, const std::vector<CoeffsVector*>&, const bool print_description=false);
+     208             : private:
+     209             :   void writeHeaderToFile(OFile&) const;
+     210             :   static void writeDataToFile(OFile&, const std::vector<CoeffsVector*>&, const bool print_description=false);
+     211             : public:
+     212             :   size_t readFromFile(IFile&, const bool ignore_missing_coeffs=false, const bool ignore_header=false);
+     213             :   size_t readFromFile(const std::string&, const bool ignore_missing_coeffs=false, const bool ignore_header=false);
+     214             :   size_t readOneSetFromFile(IFile& ifile, const bool ignore_header=false);
+     215             : private:
+     216             :   void readHeaderFromFile(IFile&, const bool ignore_coeffs_info=false);
+     217             :   size_t readDataFromFile(IFile&, const bool ignore_missing_coeffs=false);
+     218             : public:
+     219           0 :   Communicator& getCommunicator() const {return mycomm;}
+     220             : };
+     221             : 
+     222             : 
+     223             : inline
+     224             : double CoeffsVector::getValue(const size_t index) const {
+     225   142877390 :   return data[index];
+     226             : }
+     227             : 
+     228             : 
+     229             : inline
+     230             : double CoeffsVector::getValue(const std::vector<unsigned int>& indices) const {
+     231             :   return data[getIndex(indices)];
+     232             : }
+     233             : 
+     234             : 
+     235             : }
+     236             : 
+     237             : }
+     238             : 
+     239             : 
+     240             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/FermiSwitchingFunction.cpp.func-sort-c.html b/coverage/ves/FermiSwitchingFunction.cpp.func-sort-c.html new file mode 100644 index 000000000000..7d781ac87bb3 --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/FermiSwitchingFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - FermiSwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:336749.3 %
Date:2024-02-22 21:58:45Functions:4944.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22FermiSwitchingFunction16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves22FermiSwitchingFunction3setEddd0
_ZN4PLMD3ves22FermiSwitchingFunctionC2ERKS1_0
_ZNK4PLMD3ves22FermiSwitchingFunction11descriptionB5cxx11Ev0
_ZNK4PLMD3ves22FermiSwitchingFunction6get_r0Ev0
_ZN4PLMD3ves22FermiSwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS7_3
_ZN4PLMD3ves22FermiSwitchingFunctionC2Ev3
_ZN4PLMD3ves22FermiSwitchingFunctionD2Ev3
_ZNK4PLMD3ves22FermiSwitchingFunction9calculateEdRd3263
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/FermiSwitchingFunction.cpp.func.html b/coverage/ves/FermiSwitchingFunction.cpp.func.html new file mode 100644 index 000000000000..bb741888ffb0 --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/FermiSwitchingFunction.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - FermiSwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:336749.3 %
Date:2024-02-22 21:58:45Functions:4944.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22FermiSwitchingFunction16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves22FermiSwitchingFunction3setERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS7_3
_ZN4PLMD3ves22FermiSwitchingFunction3setEddd0
_ZN4PLMD3ves22FermiSwitchingFunctionC2ERKS1_0
_ZN4PLMD3ves22FermiSwitchingFunctionC2Ev3
_ZN4PLMD3ves22FermiSwitchingFunctionD2Ev3
_ZNK4PLMD3ves22FermiSwitchingFunction11descriptionB5cxx11Ev0
_ZNK4PLMD3ves22FermiSwitchingFunction6get_r0Ev0
_ZNK4PLMD3ves22FermiSwitchingFunction9calculateEdRd3263
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/FermiSwitchingFunction.cpp.gcov.html b/coverage/ves/FermiSwitchingFunction.cpp.gcov.html new file mode 100644 index 000000000000..4a19a864db4a --- /dev/null +++ b/coverage/ves/FermiSwitchingFunction.cpp.gcov.html @@ -0,0 +1,219 @@ + + + + + + + + LCOV - plumed test coverage - ves/FermiSwitchingFunction.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - FermiSwitchingFunction.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:336749.3 %
Date:2024-02-22 21:58:45Functions:4944.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "FermiSwitchingFunction.h"
+      24             : 
+      25             : #include "tools/Tools.h"
+      26             : #include "tools/Keywords.h"
+      27             : 
+      28             : #include <vector>
+      29             : #include <limits>
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : 
+      36           0 : void FermiSwitchingFunction::registerKeywords( Keywords& keys ) {
+      37           0 :   keys.add("compulsory","R_0","the value of R_0 in the switching function");
+      38           0 :   keys.add("compulsory","FERMI_LAMBDA","the value of lambda in the Fermi-type switching function (only needed for TYPE=FERMI).");
+      39           0 :   keys.add("optional","FERMI_EXP_MAX","only needed for TYPE=FERMI");
+      40           0 : }
+      41             : 
+      42           3 : void FermiSwitchingFunction::set(const std::string& definition,std::string& errormsg) {
+      43           3 :   std::vector<std::string> data=Tools::getWords(definition);
+      44           3 :   if( data.size()<1 ) {
+      45             :     errormsg="missing all input for switching function";
+      46             :     return;
+      47             :   }
+      48           3 :   std::string name=data[0];
+      49             :   data.erase(data.begin());
+      50           3 :   if(name!="FERMI") {errormsg="only FERMI is supported";}
+      51           3 :   type=fermi;
+      52             :   //
+      53           3 :   bool found_r0=Tools::parse(data,"R_0",r0_);
+      54           3 :   if(!found_r0) {errormsg="R_0 is required";}
+      55             : 
+      56             :   //
+      57           3 :   fermi_exp_max_=std::numeric_limits<double>::max();
+      58           3 :   Tools::parse(data,"FERMI_EXP_MAX",fermi_exp_max_);
+      59             :   //
+      60           3 :   bool found_lambda=Tools::parse(data,"FERMI_LAMBDA",fermi_lambda_);
+      61           3 :   if(!found_lambda) {errormsg="FERMI_LAMBDA is required for FERMI";}
+      62           3 :   if( !data.empty() ) {
+      63             :     errormsg="found the following rogue keywords in switching function input : ";
+      64           0 :     for(unsigned i=0; i<data.size(); ++i) errormsg = errormsg + data[i] + " ";
+      65             :   }
+      66           3 :   init=true;
+      67           3 :   if(errormsg.size()>0) {init=false;}
+      68           3 : }
+      69             : 
+      70           0 : std::string FermiSwitchingFunction::description() const {
+      71           0 :   std::ostringstream ostr;
+      72           0 :   ostr<<1./invr0_<<".  Using ";
+      73           0 :   if(type==fermi) {
+      74           0 :     ostr<< "fermi switching function with parameter";
+      75           0 :     ostr<< " lambda="<<fermi_lambda_;
+      76             :   }
+      77             :   else {
+      78           0 :     plumed_merror("Unknown switching function type");
+      79             :   }
+      80           0 :   return ostr.str();
+      81           0 : }
+      82             : 
+      83             : 
+      84        3263 : double FermiSwitchingFunction::calculate(double distance, double& dfunc) const {
+      85        3263 :   plumed_massert(init,"you are trying to use an unset FermiSwitchingFunction");
+      86        3263 :   double rdist=fermi_lambda_*(distance-r0_);
+      87        3263 :   if(rdist >= fermi_exp_max_) {rdist = fermi_exp_max_;}
+      88        3263 :   double result = 1.0/(1.0+exp(rdist));
+      89        3263 :   dfunc=-fermi_lambda_*exp(rdist)*result*result;
+      90             :   // this is because calculate() sets dfunc to the derivative divided times the distance.
+      91             :   // (I think this is misleading and I would like to modify it - GB)
+      92             :   // dfunc/=distance;
+      93             :   //
+      94        3263 :   return result;
+      95             : }
+      96             : 
+      97             : 
+      98           3 : FermiSwitchingFunction::FermiSwitchingFunction():
+      99           3 :   init(false),
+     100           3 :   type(fermi),
+     101           3 :   r0_(0.0),
+     102           3 :   invr0_(0.0),
+     103           3 :   fermi_lambda_(1.0),
+     104           3 :   fermi_exp_max_(100.0)
+     105             : {
+     106           3 : }
+     107             : 
+     108           0 : FermiSwitchingFunction::FermiSwitchingFunction(const FermiSwitchingFunction&sf):
+     109           0 :   init(sf.init),
+     110           0 :   type(sf.type),
+     111           0 :   r0_(sf.r0_),
+     112           0 :   invr0_(sf.invr0_),
+     113           0 :   fermi_lambda_(sf.fermi_lambda_),
+     114           0 :   fermi_exp_max_(sf.fermi_exp_max_)
+     115             : {
+     116           0 : }
+     117             : 
+     118           0 : void FermiSwitchingFunction::set(const double r0, const double fermi_lambda, const double fermi_exp_max) {
+     119           0 :   init=true;
+     120           0 :   type=fermi;
+     121           0 :   r0_=r0;
+     122           0 :   fermi_lambda_=fermi_lambda;
+     123           0 :   if(fermi_exp_max>0.0) {
+     124           0 :     fermi_exp_max_=fermi_exp_max;
+     125             :   }
+     126             :   else {
+     127           0 :     fermi_exp_max_=100.0;
+     128             :   }
+     129             : 
+     130           0 : }
+     131             : 
+     132           0 : double FermiSwitchingFunction::get_r0() const {
+     133           0 :   return r0_;
+     134             : }
+     135             : 
+     136             : 
+     137           3 : FermiSwitchingFunction::~FermiSwitchingFunction() {
+     138           3 : }
+     139             : 
+     140             : 
+     141             : }
+     142             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridIntegrationWeights.cpp.func-sort-c.html b/coverage/ves/GridIntegrationWeights.cpp.func-sort-c.html new file mode 100644 index 000000000000..ee82065b9e71 --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridIntegrationWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridIntegrationWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344575.6 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22GridIntegrationWeights44getOneDimensionalIntegrationPointsAndWeightsERSt6vectorIdSaIdEES5_jddRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE19
_ZN4PLMD3ves22GridIntegrationWeights21getIntegrationWeightsEPKNS_4GridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESC_2036
_ZN4PLMD3ves22GridIntegrationWeights35getOneDimensionalTrapezoidalWeightsEjdb2563
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridIntegrationWeights.cpp.func.html b/coverage/ves/GridIntegrationWeights.cpp.func.html new file mode 100644 index 000000000000..6bbafbc14b50 --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridIntegrationWeights.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridIntegrationWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344575.6 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22GridIntegrationWeights21getIntegrationWeightsEPKNS_4GridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESC_2036
_ZN4PLMD3ves22GridIntegrationWeights35getOneDimensionalTrapezoidalWeightsEjdb2563
_ZN4PLMD3ves22GridIntegrationWeights44getOneDimensionalIntegrationPointsAndWeightsERSt6vectorIdSaIdEES5_jddRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE19
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridIntegrationWeights.cpp.gcov.html b/coverage/ves/GridIntegrationWeights.cpp.gcov.html new file mode 100644 index 000000000000..7d81c5944f1d --- /dev/null +++ b/coverage/ves/GridIntegrationWeights.cpp.gcov.html @@ -0,0 +1,185 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridIntegrationWeights.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridIntegrationWeights.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:344575.6 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "GridIntegrationWeights.h"
+      24             : 
+      25             : #include "tools/Grid.h"
+      26             : #include "tools/File.h"
+      27             : #include "tools/Exception.h"
+      28             : 
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace ves {
+      32             : 
+      33        2036 : std::vector<double> GridIntegrationWeights::getIntegrationWeights(const Grid* grid_pntr, const std::string& fname_weights_grid, const std::string& weights_type) {
+      34        2036 :   std::vector<double> dx = grid_pntr->getDx();
+      35        2036 :   std::vector<bool> isPeriodic = grid_pntr->getIsPeriodic();
+      36        2036 :   std::vector<unsigned int> nbins = grid_pntr->getNbin();
+      37             :   std::vector<std::vector<double> > weights_perdim;
+      38        4580 :   for(unsigned int k=0; k<grid_pntr->getDimension(); k++) {
+      39             :     std::vector<double> weights_tmp;
+      40        2544 :     if(weights_type=="trapezoidal") {
+      41        2544 :       weights_tmp = getOneDimensionalTrapezoidalWeights(nbins[k],dx[k],isPeriodic[k]);
+      42             :     }
+      43             :     else {
+      44           0 :       plumed_merror("getIntegrationWeights: unknown weight type, the available type is trapezoidal");
+      45             :     }
+      46        2544 :     weights_perdim.push_back(weights_tmp);
+      47             :   }
+      48             : 
+      49        2036 :   std::vector<double> weights_vector(grid_pntr->getSize(),0.0);
+      50     5323391 :   for(Grid::index_t l=0; l<grid_pntr->getSize(); l++) {
+      51     5321355 :     std::vector<unsigned int> ind = grid_pntr->getIndices(l);
+      52             :     double value = 1.0;
+      53    15690443 :     for(unsigned int k=0; k<grid_pntr->getDimension(); k++) {
+      54    10369088 :       value *= weights_perdim[k][ind[k]];
+      55             :     }
+      56     5321355 :     weights_vector[l] = value;
+      57             :   }
+      58             : 
+      59        2036 :   if(fname_weights_grid.size()>0) {
+      60           0 :     Grid weights_grid = Grid(*grid_pntr);
+      61           0 :     for(Grid::index_t l=0; l<weights_grid.getSize(); l++) {
+      62           0 :       weights_grid.setValue(l,weights_vector[l]);
+      63             :     }
+      64           0 :     OFile ofile;
+      65           0 :     ofile.enforceBackup();
+      66           0 :     ofile.open(fname_weights_grid);
+      67           0 :     weights_grid.writeToFile(ofile);
+      68           0 :     ofile.close();
+      69           0 :   }
+      70             :   //
+      71        2036 :   return weights_vector;
+      72        2036 : }
+      73             : 
+      74             : 
+      75          19 : void GridIntegrationWeights::getOneDimensionalIntegrationPointsAndWeights(std::vector<double>& points, std::vector<double>& weights, const unsigned int nbins, const double min, const double max, const std::string& weights_type) {
+      76          19 :   double dx = (max-min)/(static_cast<double>(nbins)-1.0);
+      77          19 :   points.resize(nbins);
+      78       19038 :   for(unsigned int i=0; i<nbins; i++) {points[i] = min + i*dx;}
+      79          19 :   if(weights_type=="trapezoidal") {
+      80          19 :     weights = getOneDimensionalTrapezoidalWeights(nbins,dx,false);
+      81             :   }
+      82             :   else {
+      83           0 :     plumed_merror("getOneDimensionalIntegrationWeights: unknown weight type, the available type is trapezoidal");
+      84             :   }
+      85          19 : }
+      86             : 
+      87             : 
+      88        2563 : std::vector<double> GridIntegrationWeights::getOneDimensionalTrapezoidalWeights(const unsigned int nbins, const double dx, const bool periodic) {
+      89        2563 :   std::vector<double> weights_1d(nbins);
+      90      444294 :   for(unsigned int i=1; i<(nbins-1); i++) {
+      91      441731 :     weights_1d[i] = dx;
+      92             :   }
+      93        2563 :   if(!periodic) {
+      94        1202 :     weights_1d[0]= 0.5*dx;
+      95        1202 :     weights_1d[(nbins-1)]= 0.5*dx;
+      96             :   }
+      97             :   else {
+      98             :     // as for periodic arguments the first point should be counted twice as the
+      99             :     // grid doesn't include its periodic copy
+     100        1361 :     weights_1d[0]= dx;
+     101        1361 :     weights_1d[(nbins-1)]= dx;
+     102             :   }
+     103        2563 :   return weights_1d;
+     104             : }
+     105             : 
+     106             : 
+     107             : }
+     108             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.cpp.func-sort-c.html b/coverage/ves/GridLinearInterpolation.cpp.func-sort-c.html new file mode 100644 index 000000000000..1bf714221386 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6612055.0 %
Date:2024-02-22 21:58:45Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation17getAdjacentPointsEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation18getAdjacentIndicesEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_NDEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation52getGridValueAndDerivativesWithLinearInterpolation_NDEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_0
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_1DEPNS_8GridBaseERKSt6vectorIdSaIdEE1869
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_2DEPNS_8GridBaseERKSt6vectorIdSaIdEE47164
_ZN4PLMD3ves23GridLinearInterpolation35getGridValueWithLinearInterpolationEPNS_8GridBaseERKSt6vectorIdSaIdEE49033
_ZN4PLMD3ves23GridLinearInterpolation49getGridValueAndDerivativesWithLinearInterpolationEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_1263854
_ZN4PLMD3ves23GridLinearInterpolation52getGridValueAndDerivativesWithLinearInterpolation_1DEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_1263854
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.cpp.func.html b/coverage/ves/GridLinearInterpolation.cpp.func.html new file mode 100644 index 000000000000..fcd84d5fde87 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6612055.0 %
Date:2024-02-22 21:58:45Functions:5955.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation17getAdjacentPointsEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation18getAdjacentIndicesEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation35getGridValueWithLinearInterpolationEPNS_8GridBaseERKSt6vectorIdSaIdEE49033
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_1DEPNS_8GridBaseERKSt6vectorIdSaIdEE1869
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_2DEPNS_8GridBaseERKSt6vectorIdSaIdEE47164
_ZN4PLMD3ves23GridLinearInterpolation38getGridValueWithLinearInterpolation_NDEPNS_8GridBaseERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves23GridLinearInterpolation49getGridValueAndDerivativesWithLinearInterpolationEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_1263854
_ZN4PLMD3ves23GridLinearInterpolation52getGridValueAndDerivativesWithLinearInterpolation_1DEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_1263854
_ZN4PLMD3ves23GridLinearInterpolation52getGridValueAndDerivativesWithLinearInterpolation_NDEPNS_8GridBaseERKSt6vectorIdSaIdEERS6_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.cpp.gcov.html b/coverage/ves/GridLinearInterpolation.cpp.gcov.html new file mode 100644 index 000000000000..8eb804b803c8 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.cpp.gcov.html @@ -0,0 +1,312 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:6612055.0 %
Date:2024-02-22 21:58:45Functions:5955.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "GridLinearInterpolation.h"
+      24             : 
+      25             : #include "tools/Grid.h"
+      26             : #include "tools/Exception.h"
+      27             : #include "tools/Tools.h"
+      28             : 
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace ves {
+      32             : 
+      33             : 
+      34        1869 : double GridLinearInterpolation::getGridValueWithLinearInterpolation_1D(GridBase* grid_pntr, const std::vector<double>& arg) {
+      35             : 
+      36        1869 :   plumed_massert(grid_pntr->getDimension()==1,"The grid is of the wrong dimension, should be one-dimensional");
+      37        1869 :   plumed_massert(arg.size()==1,"input value is of the wrong size");
+      38             : 
+      39        1869 :   double x = arg[0];
+      40        1869 :   double grid_dx = grid_pntr->getDx()[0];
+      41        1869 :   double grid_min; Tools::convert( grid_pntr->getMin()[0], grid_min);
+      42        1869 :   std::vector<unsigned int> i0(1); i0[0] = unsigned( std::floor( (x-grid_min)/grid_dx ) );
+      43        1869 :   std::vector<unsigned int> i1(1); i1[0] = unsigned( std::ceil(  (x-grid_min)/grid_dx ) );
+      44             :   //
+      45        1869 :   double x0 = grid_pntr->getPoint(i0)[0];
+      46        1869 :   double x1 = grid_pntr->getPoint(i1)[0];
+      47        1869 :   double y0 = grid_pntr->getValue(i0);
+      48        1869 :   double y1 = grid_pntr->getValue(i1);
+      49             :   //
+      50        1869 :   return linearInterpolation(x,x0,x1,y0,y1);
+      51             : }
+      52             : 
+      53             : 
+      54       47164 : double GridLinearInterpolation::getGridValueWithLinearInterpolation_2D(GridBase* grid_pntr, const std::vector<double>& arg) {
+      55       47164 :   plumed_massert(grid_pntr->getDimension()==2,"The grid is of the wrong dimension, should be two-dimensional");
+      56       47164 :   plumed_massert(arg.size()==2,"input value is of the wrong size");
+      57             : 
+      58       47164 :   std::vector<double> grid_delta = grid_pntr->getDx();
+      59       47164 :   std::vector<double> grid_min(2);
+      60       47164 :   Tools::convert( grid_pntr->getMin()[0], grid_min[0]);
+      61       47164 :   Tools::convert( grid_pntr->getMin()[1], grid_min[1]);
+      62             : 
+      63       47164 :   std::vector<unsigned int> i00(2);
+      64       47164 :   std::vector<unsigned int> i01(2);
+      65       47164 :   std::vector<unsigned int> i10(2);
+      66       47164 :   std::vector<unsigned int> i11(2);
+      67             : 
+      68       47164 :   i00[0] = i01[0] = unsigned( std::floor( (arg[0]-grid_min[0])/grid_delta[0] ) );
+      69       47164 :   i10[0] = i11[0] = unsigned( std::ceil(  (arg[0]-grid_min[0])/grid_delta[0] ) );
+      70             : 
+      71       47164 :   i00[1] = i10[1] = unsigned( std::floor( (arg[1]-grid_min[1])/grid_delta[1] ) );
+      72       47164 :   i01[1] = i11[1] = unsigned( std::ceil(  (arg[1]-grid_min[1])/grid_delta[1] ) );
+      73             : 
+      74             :   // https://en.wikipedia.org/wiki/Bilinear_interpolation
+      75       47164 :   double x = arg[0];
+      76       47164 :   double y = arg[1];
+      77             : 
+      78       47164 :   double x0 = grid_pntr->getPoint(i00)[0];
+      79       47164 :   double x1 = grid_pntr->getPoint(i10)[0];
+      80       47164 :   double y0 = grid_pntr->getPoint(i00)[1];
+      81       47164 :   double y1 = grid_pntr->getPoint(i11)[1];
+      82             : 
+      83       47164 :   double f00 = grid_pntr->getValue(i00);
+      84       47164 :   double f01 = grid_pntr->getValue(i01);
+      85       47164 :   double f10 = grid_pntr->getValue(i10);
+      86       47164 :   double f11 = grid_pntr->getValue(i11);
+      87             : 
+      88             :   // linear interpolation in x-direction
+      89             :   double fx0 = linearInterpolation(x,x0,x1,f00,f10);
+      90             :   double fx1 = linearInterpolation(x,x0,x1,f01,f11);
+      91             :   // linear interpolation in y-direction
+      92             :   double fxy = linearInterpolation(y,y0,y1,fx0,fx1);
+      93             :   //
+      94       47164 :   return fxy;
+      95             : }
+      96             : 
+      97             : 
+      98           0 : double GridLinearInterpolation::getGridValueWithLinearInterpolation_ND(GridBase* grid_pntr, const std::vector<double>& arg) {
+      99           0 :   unsigned int dimension = grid_pntr->getDimension();
+     100           0 :   plumed_massert(dimension==arg.size(),"The grid dimensions do not match the the given arguments.");
+     101             :   // get points first
+     102           0 :   std::vector<std::vector<unsigned>> point_indices = GridLinearInterpolation::getAdjacentPoints(grid_pntr, arg);
+     103             : 
+     104           0 :   unsigned npoints = point_indices.size();
+     105             :   // reserve space for the point vectors and values
+     106           0 :   std::vector<std::vector<double>> points(npoints, std::vector<double>(dimension));
+     107           0 :   std::vector<double> values(npoints);
+     108             : 
+     109             :   // fill point and value vectors for all the grid points
+     110           0 :   for (unsigned i = 0; i < npoints; ++i) {
+     111           0 :     points[i] = grid_pntr->getPoint(point_indices[i]);
+     112           0 :     values[i] = grid_pntr->getValue(point_indices[i]);
+     113             :   }
+     114             : 
+     115           0 :   return multiLinearInterpolation(arg, points, values, dimension);
+     116           0 : }
+     117             : 
+     118             : 
+     119     1263854 : double GridLinearInterpolation::getGridValueAndDerivativesWithLinearInterpolation_1D(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der) {
+     120     1263854 :   plumed_massert(grid_pntr->getDimension()==1,"The grid is of the wrong dimension, should be one-dimensional");
+     121     1263854 :   plumed_massert(arg.size()==1,"input value is of the wrong size");
+     122             : 
+     123     1263854 :   double x = arg[0];
+     124     1263854 :   double grid_dx = grid_pntr->getDx()[0];
+     125     1263854 :   double grid_min; Tools::convert( grid_pntr->getMin()[0], grid_min);
+     126             : 
+     127     1263854 :   double xtoindex = (x-grid_min)/grid_dx;
+     128     1263854 :   std::vector<unsigned int> i0(1); i0[0] = unsigned(std::floor(xtoindex));
+     129     1263854 :   std::vector<unsigned int> i1(1); i1[0] = unsigned(std::ceil(xtoindex));
+     130             :   //
+     131     1263854 :   std::vector<double> d0 (1), d1 (1);
+     132     1263854 :   double x0 = grid_pntr->getPoint(i0)[0];
+     133     1263854 :   double x1 = grid_pntr->getPoint(i1)[0];
+     134     1263854 :   double y0 = grid_pntr->getValueAndDerivatives(i0, d0);
+     135     1263854 :   double y1 = grid_pntr->getValueAndDerivatives(i1, d1);
+     136             :   //
+     137     1263854 :   der.resize(1);
+     138     2500429 :   der[0] = linearInterpolation(arg[0],x0,x1,d0[0],d1[0]);
+     139     2527708 :   return linearInterpolation(arg[0],x0,x1,y0,y1);
+     140             : }
+     141             : 
+     142             : 
+     143           0 : double GridLinearInterpolation::getGridValueAndDerivativesWithLinearInterpolation_ND(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der) {
+     144           0 :   unsigned int dimension = grid_pntr->getDimension();
+     145           0 :   plumed_massert(dimension==arg.size(),"The grid dimensions do not match the given arguments");
+     146             :   // get points first
+     147           0 :   std::vector<std::vector<unsigned>> point_indices = getAdjacentPoints(grid_pntr, arg);
+     148             : 
+     149           0 :   unsigned npoints = point_indices.size();
+     150             :   // allocate space for the point vectors and values
+     151           0 :   std::vector<std::vector<double>> points(npoints, std::vector<double>(dimension));
+     152           0 :   std::vector<double> values(npoints);
+     153           0 :   std::vector<std::vector<double>> derivs(npoints, std::vector<double>(dimension));
+     154             : 
+     155             :   // fill point, value and deriv vectors for all the grid points
+     156           0 :   for (unsigned i = 0; i < npoints; ++i) {
+     157           0 :     points[i] = grid_pntr->getPoint(point_indices[i]);
+     158           0 :     values[i] = grid_pntr->getValueAndDerivatives(point_indices[i], derivs[i]);
+     159             :   }
+     160             : 
+     161           0 :   for (size_t i = 0; i < derivs.size(); ++i) {
+     162           0 :     der[i] = multiLinearInterpolation(arg, points, derivs[i], dimension);
+     163             :   }
+     164           0 :   return multiLinearInterpolation(arg, points, values, dimension);
+     165           0 : }
+     166             : 
+     167             : 
+     168       49033 : double GridLinearInterpolation::getGridValueWithLinearInterpolation(GridBase* grid_pntr, const std::vector<double>& arg) {
+     169       49033 :   unsigned int dim = grid_pntr->getDimension();
+     170       49033 :   if(dim==1) {
+     171        1869 :     return getGridValueWithLinearInterpolation_1D(grid_pntr,arg);
+     172             :   }
+     173       47164 :   else if(dim==2) {
+     174       47164 :     return getGridValueWithLinearInterpolation_2D(grid_pntr,arg);
+     175             :   }
+     176             :   else {
+     177           0 :     return getGridValueWithLinearInterpolation_ND(grid_pntr,arg);
+     178             :   }
+     179             : }
+     180             : 
+     181             : 
+     182     1263854 : double GridLinearInterpolation::getGridValueAndDerivativesWithLinearInterpolation(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der) {
+     183     1263854 :   unsigned int dim = grid_pntr->getDimension();
+     184     1263854 :   if(dim==1) {
+     185     1263854 :     return getGridValueAndDerivativesWithLinearInterpolation_1D(grid_pntr,arg,der);
+     186             :   }
+     187           0 :   return getGridValueAndDerivativesWithLinearInterpolation_ND(grid_pntr,arg,der);
+     188             : }
+     189             : 
+     190             : 
+     191             : // returns the adjacent Grid indices of all double arg as vector of vectors
+     192           0 : std::vector<std::vector<unsigned>> GridLinearInterpolation::getAdjacentIndices(GridBase* grid_pntr, const std::vector<double>& arg) {
+     193           0 :   unsigned int dimension = grid_pntr->getDimension();
+     194             : 
+     195           0 :   std::vector<std::vector<unsigned>> indices(dimension, std::vector<unsigned>(2));
+     196           0 :   for (unsigned i=0; i<dimension; ++i) {
+     197           0 :     std::vector<unsigned> temp_indices(2);
+     198             :     //
+     199           0 :     double grid_dx = grid_pntr->getDx()[i];
+     200           0 :     double grid_min; Tools::convert( grid_pntr->getMin()[i], grid_min);
+     201           0 :     double xtoindex = (arg[i]-grid_min)/grid_dx;
+     202           0 :     temp_indices[0] = static_cast<unsigned>(std::floor(xtoindex));
+     203           0 :     temp_indices[1] = static_cast<unsigned>(std::ceil(xtoindex));
+     204           0 :     indices[i] = temp_indices;
+     205             :   }
+     206           0 :   return indices;
+     207           0 : }
+     208             : 
+     209             : 
+     210           0 : std::vector<std::vector<unsigned>> GridLinearInterpolation::getAdjacentPoints(GridBase* grid_pntr, const std::vector<double>& arg) {
+     211             :   // upper and lower grid indices as vectors for each dimension
+     212           0 :   std::vector<std::vector<unsigned>> grid_indices = getAdjacentIndices(grid_pntr, arg);
+     213           0 :   unsigned npoints = 1U << grid_pntr->getDimension();
+     214             : 
+     215             :   // generate combination of grid indices if multidimensional to match the actual points
+     216             :   // the retrieved combinations will be in column-major order
+     217           0 :   std::vector<std::vector<unsigned>> point_indices(npoints);
+     218           0 :   for (unsigned i = 0; i < npoints; ++i) {
+     219             :     unsigned temp = i;
+     220             :     std::vector<unsigned> current_indices;
+     221           0 :     for (const auto& vec: grid_indices) {
+     222           0 :       unsigned j = temp % 2;
+     223           0 :       current_indices.push_back(vec[j]);
+     224           0 :       temp /= 2;
+     225             :     }
+     226           0 :     point_indices[i] = current_indices;
+     227             :   }
+     228           0 :   return point_indices;
+     229           0 : }
+     230             : 
+     231             : 
+     232             : 
+     233             : 
+     234             : }
+     235             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.h.func-sort-c.html b/coverage/ves/GridLinearInterpolation.h.func-sort-c.html new file mode 100644 index 000000000000..a93c4cc9bd4b --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2922.2 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation24multiLinearInterpolationERKSt6vectorIdSaIdEERKS2_IS4_SaIS4_EERS4_d0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.h.func.html b/coverage/ves/GridLinearInterpolation.h.func.html new file mode 100644 index 000000000000..1cdf156c86e4 --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2922.2 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23GridLinearInterpolation24multiLinearInterpolationERKSt6vectorIdSaIdEERKS2_IS4_SaIS4_EERS4_d0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridLinearInterpolation.h.gcov.html b/coverage/ves/GridLinearInterpolation.h.gcov.html new file mode 100644 index 000000000000..e15e22cc8a1c --- /dev/null +++ b/coverage/ves/GridLinearInterpolation.h.gcov.html @@ -0,0 +1,159 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridLinearInterpolation.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridLinearInterpolation.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2922.2 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_GridLinearInterpolation_h
+      23             : #define __PLUMED_ves_GridLinearInterpolation_h
+      24             : 
+      25             : #include <vector>
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : 
+      30             : 
+      31             : class GridBase;
+      32             : 
+      33             : 
+      34             : namespace ves {
+      35             : 
+      36             : class GridLinearInterpolation {
+      37             : private:
+      38             :   static double getGridValueWithLinearInterpolation_1D(GridBase* grid_pntr, const std::vector<double>& arg);
+      39             :   static double getGridValueWithLinearInterpolation_2D(GridBase* grid_pntr, const std::vector<double>& arg);
+      40             :   static double getGridValueWithLinearInterpolation_ND(GridBase* grid_pntr, const std::vector<double>& arg);
+      41             :   static double getGridValueAndDerivativesWithLinearInterpolation_1D(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der);
+      42             :   static double getGridValueAndDerivativesWithLinearInterpolation_ND(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der);
+      43             :   static double linearInterpolation(const double x, const double x0, const double x1, const double y0, const double y1);
+      44             :   static double multiLinearInterpolation(const std::vector<double>& x, const std::vector<std::vector<double>>& points, std::vector<double>& values, const double dim);
+      45             : public:
+      46             :   static double getGridValueWithLinearInterpolation(GridBase* grid_pntr, const std::vector<double>& arg);
+      47             :   static double getGridValueAndDerivativesWithLinearInterpolation(GridBase* grid_pntr, const std::vector<double>& arg, std::vector<double>& der);
+      48             :   static std::vector<std::vector<unsigned>> getAdjacentIndices(GridBase* grid_pntr, const std::vector<double>& arg);
+      49             :   static std::vector<std::vector<unsigned>> getAdjacentPoints(GridBase* grid_pntr, const std::vector<double>& arg);
+      50             : };
+      51             : 
+      52             : 
+      53             : inline
+      54             : double GridLinearInterpolation::linearInterpolation(const double x, const double x0, const double x1, const double y0, const double y1) {
+      55             :   // https://en.wikipedia.org/wiki/Linear_interpolation
+      56     2624038 :   if(x1!=x0) {
+      57     2586242 :     return y0 + (x-x0) * ((y1-y0)/(x1-x0));
+      58             :   }
+      59             :   else {
+      60             :     return y0;
+      61             :   }
+      62             : }
+      63             : 
+      64             : 
+      65             : inline
+      66           0 : double GridLinearInterpolation::multiLinearInterpolation(const std::vector<double>& x, const std::vector<std::vector<double>>& points, std::vector<double>& values, const double dim) {
+      67           0 :   for (unsigned direction = 0; direction < dim; ++direction) {
+      68           0 :     unsigned shift = 1<<(direction+1); // shift by 2, then 4, then 8 etc
+      69           0 :     for (unsigned i = 0; i < points.size(); i += shift) {
+      70             :       // replace every second value with interpolated ones
+      71           0 :       values[i] = linearInterpolation(
+      72           0 :                     x[direction], points[i][direction], points[i+shift/2][direction], values[i], values[i+shift/2]);
+      73             :     }
+      74             :   }
+      75           0 :   return values[0];
+      76             : }
+      77             : 
+      78             : 
+      79             : }
+      80             : }
+      81             : 
+      82             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridProjWeights.h.func-sort-c.html b/coverage/ves/GridProjWeights.h.func-sort-c.html new file mode 100644 index 000000000000..a8c324fcec82 --- /dev/null +++ b/coverage/ves/GridProjWeights.h.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridProjWeights.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridProjWeights.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14MarginalWeight16projectOuterLoopERd2822
_ZN4PLMD3ves9FesWeight16projectOuterLoopERd5834
_ZN4PLMD3ves14MarginalWeight16projectInnerLoopERdS2_284402
_ZN4PLMD3ves9FesWeight16projectInnerLoopERdS2_703214
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridProjWeights.h.func.html b/coverage/ves/GridProjWeights.h.func.html new file mode 100644 index 000000000000..6563990d016e --- /dev/null +++ b/coverage/ves/GridProjWeights.h.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridProjWeights.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridProjWeights.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14MarginalWeight16projectInnerLoopERdS2_284402
_ZN4PLMD3ves14MarginalWeight16projectOuterLoopERd2822
_ZN4PLMD3ves9FesWeight16projectInnerLoopERdS2_703214
_ZN4PLMD3ves9FesWeight16projectOuterLoopERd5834
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/GridProjWeights.h.gcov.html b/coverage/ves/GridProjWeights.h.gcov.html new file mode 100644 index 000000000000..ade97e1b9398 --- /dev/null +++ b/coverage/ves/GridProjWeights.h.gcov.html @@ -0,0 +1,127 @@ + + + + + + + + LCOV - plumed test coverage - ves/GridProjWeights.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - GridProjWeights.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:66100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_GridProjWeights_h
+      23             : #define __PLUMED_ves_GridProjWeights_h
+      24             : 
+      25             : #include "tools/Grid.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : 
+      32             : class MarginalWeight:public WeightBase {
+      33             : public:
+      34          28 :   explicit MarginalWeight() {}
+      35      284402 :   double projectInnerLoop(double &input, double &v) {return  input+v;}
+      36        2822 :   double projectOuterLoop(double &v) {return v;}
+      37             : };
+      38             : 
+      39             : class FesWeight:public WeightBase {
+      40             : public:
+      41             :   double beta,invbeta;
+      42          50 :   explicit FesWeight(double v) {beta=v; invbeta=1./beta;}
+      43      703214 :   double projectInnerLoop(double &input, double &v) {return  input+exp(-beta*v);}
+      44        5834 :   double projectOuterLoop(double &v) {return -invbeta*std::log(v);}
+      45             : };
+      46             : 
+      47             : }
+      48             : }
+      49             : 
+      50             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.cpp.func-sort-c.html b/coverage/ves/LinearBasisSetExpansion.cpp.func-sort-c.html new file mode 100644 index 000000000000..601de9cb0464 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.func-sort-c.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31335388.7 %
Date:2024-02-22 21:58:45Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion10linkActionEPNS_6ActionE0
_ZN4PLMD3ves23LinearBasisSetExpansion16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves23LinearBasisSetExpansion20setBiasMaximumToZeroEv0
_ZNK4PLMD3ves23LinearBasisSetExpansion23calculateReweightFactorEv0
_ZNK4PLMD3ves23LinearBasisSetExpansion29writeTargetDistributionToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3ves23LinearBasisSetExpansion34isStaticTargetDistFileOutputActiveEv0
_ZNK4PLMD3ves23LinearBasisSetExpansion32writeBiasWithoutCutoffGridToFileERNS_5OFileEb5
_ZN4PLMD3ves23LinearBasisSetExpansion16setupFesProjGridEv8
_ZN4PLMD3ves23LinearBasisSetExpansion25restartTargetDistributionEv8
_ZN4PLMD3ves23LinearBasisSetExpansion31readInRestartTargetDistributionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZNK4PLMD3ves23LinearBasisSetExpansion29writeTargetDistProjGridToFileERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERNS_5OFileEb20
_ZN4PLMD3ves23LinearBasisSetExpansion27updateBiasWithoutCutoffGridEv27
_ZNK4PLMD3ves23LinearBasisSetExpansion22writeFesProjGridToFileERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERNS_5OFileEb36
_ZN4PLMD3ves23LinearBasisSetExpansion11setGridBinsEj39
_ZN4PLMD3ves23LinearBasisSetExpansion20setBiasMinimumToZeroEv39
_ZN4PLMD3ves23LinearBasisSetExpansion23setupTargetDistributionEPNS0_18TargetDistributionE45
_ZN4PLMD3ves23LinearBasisSetExpansion30setupUniformTargetDistributionEv45
_ZNK4PLMD3ves23LinearBasisSetExpansion25writeTargetDistGridToFileERNS_5OFileEb82
_ZNK4PLMD3ves23LinearBasisSetExpansion28writeLogTargetDistGridToFileERNS_5OFileEb82
_ZN4PLMD3ves23LinearBasisSetExpansion11linkVesBiasEPNS0_7VesBiasE90
_ZN4PLMD3ves23LinearBasisSetExpansion12setupFesGridEv120
_ZN4PLMD3ves23LinearBasisSetExpansion11setGridBinsERKSt6vectorIjSaIjEE129
_ZN4PLMD3ves23LinearBasisSetExpansionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdRNS_12CommunicatorERKSt6vectorIPNS_5ValueESaISE_EERSC_IPNS0_14BasisFunctionsESaISK_EEPNS0_12CoeffsVectorE130
_ZN4PLMD3ves23LinearBasisSetExpansionD2Ev130
_ZN4PLMD3ves23LinearBasisSetExpansion13setupBiasGridEb166
_ZNK4PLMD3ves23LinearBasisSetExpansion18writeFesGridToFileERNS_5OFileEb169
_ZNK4PLMD3ves23LinearBasisSetExpansion19writeBiasGridToFileERNS_5OFileEb212
_ZN4PLMD3ves23LinearBasisSetExpansion16setupGeneralGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb220
_ZN4PLMD3ves23LinearBasisSetExpansion24updateTargetDistributionEv355
_ZN4PLMD3ves23LinearBasisSetExpansion16getBasisSetValueERKSt6vectorIdSaIdEEmRS2_IPNS0_14BasisFunctionsESaIS8_EEPNS0_12CoeffsVectorE408
_ZN4PLMD3ves23LinearBasisSetExpansion35calculateTargetDistAveragesFromGridEPKNS_4GridE408
_ZN4PLMD3ves23LinearBasisSetExpansion13updateFesGridEv539
_ZN4PLMD3ves23LinearBasisSetExpansion14updateBiasGridEv829
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_RS2_IPNS0_14BasisFunctionsESaIS9_EEPNS0_12CoeffsVectorEPNS_12CommunicatorE862315
_ZNK4PLMD3ves23LinearBasisSetExpansion16biasCutoffActiveEv1982225
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_S8_RS2_IPNS0_14BasisFunctionsESaISA_EEPNS0_12CoeffsVectorEPNS_12CommunicatorE2011787
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.cpp.func.html b/coverage/ves/LinearBasisSetExpansion.cpp.func.html new file mode 100644 index 000000000000..535701df9610 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.func.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31335388.7 %
Date:2024-02-22 21:58:45Functions:303683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion10linkActionEPNS_6ActionE0
_ZN4PLMD3ves23LinearBasisSetExpansion11linkVesBiasEPNS0_7VesBiasE90
_ZN4PLMD3ves23LinearBasisSetExpansion11setGridBinsERKSt6vectorIjSaIjEE129
_ZN4PLMD3ves23LinearBasisSetExpansion11setGridBinsEj39
_ZN4PLMD3ves23LinearBasisSetExpansion12setupFesGridEv120
_ZN4PLMD3ves23LinearBasisSetExpansion13setupBiasGridEb166
_ZN4PLMD3ves23LinearBasisSetExpansion13updateFesGridEv539
_ZN4PLMD3ves23LinearBasisSetExpansion14updateBiasGridEv829
_ZN4PLMD3ves23LinearBasisSetExpansion16getBasisSetValueERKSt6vectorIdSaIdEEmRS2_IPNS0_14BasisFunctionsESaIS8_EEPNS0_12CoeffsVectorE408
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_S8_RS2_IPNS0_14BasisFunctionsESaISA_EEPNS0_12CoeffsVectorEPNS_12CommunicatorE2011787
_ZN4PLMD3ves23LinearBasisSetExpansion16registerKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves23LinearBasisSetExpansion16setupFesProjGridEv8
_ZN4PLMD3ves23LinearBasisSetExpansion16setupGeneralGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEb220
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_RS2_IPNS0_14BasisFunctionsESaIS9_EEPNS0_12CoeffsVectorEPNS_12CommunicatorE862315
_ZN4PLMD3ves23LinearBasisSetExpansion20setBiasMaximumToZeroEv0
_ZN4PLMD3ves23LinearBasisSetExpansion20setBiasMinimumToZeroEv39
_ZN4PLMD3ves23LinearBasisSetExpansion23setupTargetDistributionEPNS0_18TargetDistributionE45
_ZN4PLMD3ves23LinearBasisSetExpansion24updateTargetDistributionEv355
_ZN4PLMD3ves23LinearBasisSetExpansion25restartTargetDistributionEv8
_ZN4PLMD3ves23LinearBasisSetExpansion27updateBiasWithoutCutoffGridEv27
_ZN4PLMD3ves23LinearBasisSetExpansion30setupUniformTargetDistributionEv45
_ZN4PLMD3ves23LinearBasisSetExpansion31readInRestartTargetDistributionERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD3ves23LinearBasisSetExpansion35calculateTargetDistAveragesFromGridEPKNS_4GridE408
_ZN4PLMD3ves23LinearBasisSetExpansionC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEdRNS_12CommunicatorERKSt6vectorIPNS_5ValueESaISE_EERSC_IPNS0_14BasisFunctionsESaISK_EEPNS0_12CoeffsVectorE130
_ZN4PLMD3ves23LinearBasisSetExpansionD2Ev130
_ZNK4PLMD3ves23LinearBasisSetExpansion16biasCutoffActiveEv1982225
_ZNK4PLMD3ves23LinearBasisSetExpansion18writeFesGridToFileERNS_5OFileEb169
_ZNK4PLMD3ves23LinearBasisSetExpansion19writeBiasGridToFileERNS_5OFileEb212
_ZNK4PLMD3ves23LinearBasisSetExpansion22writeFesProjGridToFileERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERNS_5OFileEb36
_ZNK4PLMD3ves23LinearBasisSetExpansion23calculateReweightFactorEv0
_ZNK4PLMD3ves23LinearBasisSetExpansion25writeTargetDistGridToFileERNS_5OFileEb82
_ZNK4PLMD3ves23LinearBasisSetExpansion28writeLogTargetDistGridToFileERNS_5OFileEb82
_ZNK4PLMD3ves23LinearBasisSetExpansion29writeTargetDistProjGridToFileERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERNS_5OFileEb20
_ZNK4PLMD3ves23LinearBasisSetExpansion29writeTargetDistributionToFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD3ves23LinearBasisSetExpansion32writeBiasWithoutCutoffGridToFileERNS_5OFileEb5
_ZNK4PLMD3ves23LinearBasisSetExpansion34isStaticTargetDistFileOutputActiveEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html b/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html new file mode 100644 index 000000000000..490a01a426ab --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.cpp.gcov.html @@ -0,0 +1,694 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:31335388.7 %
Date:2024-02-22 21:58:45Functions:303683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "LinearBasisSetExpansion.h"
+      24             : #include "VesBias.h"
+      25             : #include "CoeffsVector.h"
+      26             : #include "VesTools.h"
+      27             : #include "GridIntegrationWeights.h"
+      28             : #include "BasisFunctions.h"
+      29             : #include "TargetDistribution.h"
+      30             : 
+      31             : 
+      32             : #include "tools/Keywords.h"
+      33             : #include "tools/Grid.h"
+      34             : #include "tools/Communicator.h"
+      35             : 
+      36             : #include "GridProjWeights.h"
+      37             : 
+      38             : #include <limits>
+      39             : 
+      40             : namespace PLMD {
+      41             : namespace ves {
+      42             : 
+      43           0 : void LinearBasisSetExpansion::registerKeywords(Keywords& keys) {
+      44           0 : }
+      45             : 
+      46             : 
+      47         130 : LinearBasisSetExpansion::LinearBasisSetExpansion(
+      48             :   const std::string& label,
+      49             :   const double beta_in,
+      50             :   Communicator& cc,
+      51             :   const std::vector<Value*>& args_pntrs_in,
+      52             :   std::vector<BasisFunctions*>& basisf_pntrs_in,
+      53         130 :   CoeffsVector* bias_coeffs_pntr_in):
+      54         130 :   label_(label),
+      55         130 :   action_pntr_(NULL),
+      56         130 :   vesbias_pntr_(NULL),
+      57         130 :   mycomm_(cc),
+      58         130 :   serial_(false),
+      59         130 :   beta_(beta_in),
+      60         130 :   kbt_(1.0/beta_),
+      61         130 :   args_pntrs_(args_pntrs_in),
+      62         130 :   nargs_(args_pntrs_.size()),
+      63         130 :   basisf_pntrs_(basisf_pntrs_in),
+      64         130 :   nbasisf_(basisf_pntrs_.size()),
+      65         130 :   bias_coeffs_pntr_(bias_coeffs_pntr_in),
+      66         130 :   ncoeffs_(0),
+      67         130 :   grid_min_(nargs_),
+      68         130 :   grid_max_(nargs_),
+      69         130 :   grid_bins_(nargs_,100),
+      70         130 :   targetdist_grid_label_("targetdist"),
+      71         130 :   step_of_last_biasgrid_update(-1000),
+      72         130 :   step_of_last_biaswithoutcutoffgrid_update(-1000),
+      73         130 :   step_of_last_fesgrid_update(-1000),
+      74         130 :   log_targetdist_grid_pntr_(NULL),
+      75         130 :   targetdist_grid_pntr_(NULL),
+      76         260 :   targetdist_pntr_(NULL)
+      77             : {
+      78         130 :   plumed_massert(args_pntrs_.size()==basisf_pntrs_.size(),"number of arguments and basis functions do not match");
+      79         295 :   for(unsigned int k=0; k<nargs_; k++) {nbasisf_[k]=basisf_pntrs_[k]->getNumberOfBasisFunctions();}
+      80             :   //
+      81         130 :   if(bias_coeffs_pntr_==NULL) {
+      82           0 :     bias_coeffs_pntr_ = new CoeffsVector(label_+".coeffs",args_pntrs_,basisf_pntrs_,mycomm_,true);
+      83             :   }
+      84         130 :   plumed_massert(bias_coeffs_pntr_->numberOfDimensions()==basisf_pntrs_.size(),"dimension of coeffs does not match with number of basis functions ");
+      85             :   //
+      86         130 :   ncoeffs_ = bias_coeffs_pntr_->numberOfCoeffs();
+      87         130 :   targetdist_averages_pntr_ = Tools::make_unique<CoeffsVector>(*bias_coeffs_pntr_);
+      88             : 
+      89         130 :   std::string targetdist_averages_label = bias_coeffs_pntr_->getLabel();
+      90         130 :   if(targetdist_averages_label.find("coeffs")!=std::string::npos) {
+      91         260 :     targetdist_averages_label.replace(targetdist_averages_label.find("coeffs"), std::string("coeffs").length(), "targetdist_averages");
+      92             :   }
+      93             :   else {
+      94             :     targetdist_averages_label += "_targetdist_averages";
+      95             :   }
+      96         130 :   targetdist_averages_pntr_->setLabels(targetdist_averages_label);
+      97             :   //
+      98         295 :   for(unsigned int k=0; k<nargs_; k++) {
+      99         330 :     grid_min_[k] = basisf_pntrs_[k]->intervalMinStr();
+     100         330 :     grid_max_[k] = basisf_pntrs_[k]->intervalMaxStr();
+     101             :   }
+     102         130 : }
+     103             : 
+     104         130 : LinearBasisSetExpansion::~LinearBasisSetExpansion() {
+     105         390 : }
+     106             : 
+     107             : 
+     108           0 : bool LinearBasisSetExpansion::isStaticTargetDistFileOutputActive() const {
+     109             :   bool output_static_targetdist_files=true;
+     110           0 :   if(vesbias_pntr_!=NULL) {
+     111             :     output_static_targetdist_files = vesbias_pntr_->isStaticTargetDistFileOutputActive();
+     112             :   }
+     113           0 :   return output_static_targetdist_files;
+     114             : }
+     115             : 
+     116             : 
+     117          90 : void LinearBasisSetExpansion::linkVesBias(VesBias* vesbias_pntr_in) {
+     118          90 :   vesbias_pntr_ = vesbias_pntr_in;
+     119          90 :   action_pntr_ = static_cast<Action*>(vesbias_pntr_in);
+     120             : 
+     121          90 : }
+     122             : 
+     123             : 
+     124           0 : void LinearBasisSetExpansion::linkAction(Action* action_pntr_in) {
+     125           0 :   action_pntr_ = action_pntr_in;
+     126           0 : }
+     127             : 
+     128             : 
+     129         129 : void LinearBasisSetExpansion::setGridBins(const std::vector<unsigned int>& grid_bins_in) {
+     130         129 :   plumed_massert(grid_bins_in.size()==nargs_,"the number of grid bins given doesn't match the number of arguments");
+     131         129 :   plumed_massert(!bias_grid_pntr_,"setGridBins should be used before setting up the grids, otherwise it doesn't work");
+     132         129 :   plumed_massert(!fes_grid_pntr_,"setGridBins should be used before setting up the grids, otherwise it doesn't work");
+     133         129 :   grid_bins_=grid_bins_in;
+     134         129 : }
+     135             : 
+     136             : 
+     137          39 : void LinearBasisSetExpansion::setGridBins(const unsigned int nbins) {
+     138          39 :   std::vector<unsigned int> grid_bins_in(nargs_,nbins);
+     139          39 :   setGridBins(grid_bins_in);
+     140          39 : }
+     141             : 
+     142             : 
+     143         220 : std::unique_ptr<Grid> LinearBasisSetExpansion::setupGeneralGrid(const std::string& label_suffix, const bool usederiv) {
+     144         220 :   bool use_spline = false;
+     145         440 :   auto grid_pntr = Tools::make_unique<Grid>(label_+"."+label_suffix,args_pntrs_,grid_min_,grid_max_,grid_bins_,use_spline,usederiv);
+     146         220 :   return grid_pntr;
+     147             : }
+     148             : 
+     149             : 
+     150         166 : void LinearBasisSetExpansion::setupBiasGrid(const bool usederiv) {
+     151         166 :   if(bias_grid_pntr_) {return;}
+     152         258 :   bias_grid_pntr_ = setupGeneralGrid("bias",usederiv);
+     153         129 :   if(biasCutoffActive()) {
+     154           6 :     bias_withoutcutoff_grid_pntr_ = setupGeneralGrid("bias_withoutcutoff",usederiv);
+     155             :   }
+     156             : }
+     157             : 
+     158             : 
+     159         120 : void LinearBasisSetExpansion::setupFesGrid() {
+     160         120 :   if(fes_grid_pntr_) {return;}
+     161          88 :   if(!bias_grid_pntr_) {
+     162          37 :     setupBiasGrid(true);
+     163             :   }
+     164         176 :   fes_grid_pntr_ = setupGeneralGrid("fes",false);
+     165             : }
+     166             : 
+     167             : 
+     168           8 : void LinearBasisSetExpansion::setupFesProjGrid() {
+     169           8 :   if(!fes_grid_pntr_) {
+     170           1 :     setupFesGrid();
+     171             :   }
+     172           8 : }
+     173             : 
+     174             : 
+     175         829 : void LinearBasisSetExpansion::updateBiasGrid() {
+     176         829 :   plumed_massert(bias_grid_pntr_,"the bias grid is not defined");
+     177         829 :   if(action_pntr_!=NULL &&  getStepOfLastBiasGridUpdate()==action_pntr_->getStep()) {
+     178             :     return;
+     179             :   }
+     180     1982290 :   for(Grid::index_t l=0; l<bias_grid_pntr_->getSize(); l++) {
+     181     1981698 :     std::vector<double> forces(nargs_);
+     182     1981698 :     std::vector<double> args = bias_grid_pntr_->getPoint(l);
+     183     1981698 :     bool all_inside=true;
+     184     1981698 :     double bias=getBiasAndForces(args,all_inside,forces);
+     185             :     //
+     186     1981698 :     if(biasCutoffActive()) {
+     187         600 :       vesbias_pntr_->applyBiasCutoff(bias,forces);
+     188             :     }
+     189             :     //
+     190     1981698 :     if(bias_grid_pntr_->hasDerivatives()) {
+     191     1473981 :       bias_grid_pntr_->setValueAndDerivatives(l,bias,forces);
+     192             :     }
+     193             :     else {
+     194      507717 :       bias_grid_pntr_->setValue(l,bias);
+     195             :     }
+     196             :     //
+     197             :   }
+     198         592 :   if(vesbias_pntr_!=NULL) {
+     199         475 :     vesbias_pntr_->setCurrentBiasMaxValue(bias_grid_pntr_->getMaxValue());
+     200             :   }
+     201         592 :   if(action_pntr_!=NULL) {
+     202         475 :     setStepOfLastBiasGridUpdate(action_pntr_->getStep());
+     203             :   }
+     204             : }
+     205             : 
+     206             : 
+     207          27 : void LinearBasisSetExpansion::updateBiasWithoutCutoffGrid() {
+     208          27 :   plumed_massert(bias_withoutcutoff_grid_pntr_,"the bias without cutoff grid is not defined");
+     209          27 :   plumed_massert(biasCutoffActive(),"the bias cutoff has to be active");
+     210          27 :   plumed_massert(vesbias_pntr_!=NULL,"has to be linked to a VesBias to work");
+     211          27 :   if(action_pntr_!=NULL &&  getStepOfLastBiasWithoutCutoffGridUpdate()==action_pntr_->getStep()) {
+     212             :     return;
+     213             :   }
+     214             :   //
+     215        2423 :   for(Grid::index_t l=0; l<bias_withoutcutoff_grid_pntr_->getSize(); l++) {
+     216        2400 :     std::vector<double> forces(nargs_);
+     217        2400 :     std::vector<double> args = bias_withoutcutoff_grid_pntr_->getPoint(l);
+     218        2400 :     bool all_inside=true;
+     219        2400 :     double bias=getBiasAndForces(args,all_inside,forces);
+     220        2400 :     if(bias_withoutcutoff_grid_pntr_->hasDerivatives()) {
+     221        2400 :       bias_withoutcutoff_grid_pntr_->setValueAndDerivatives(l,bias,forces);
+     222             :     }
+     223             :     else {
+     224           0 :       bias_withoutcutoff_grid_pntr_->setValue(l,bias);
+     225             :     }
+     226             :   }
+     227             :   //
+     228          23 :   double bias_max = bias_withoutcutoff_grid_pntr_->getMaxValue();
+     229          23 :   double bias_min = bias_withoutcutoff_grid_pntr_->getMinValue();
+     230             :   double shift = 0.0;
+     231             :   bool bias_shifted=false;
+     232          23 :   if(bias_min < 0.0) {
+     233          22 :     shift += -bias_min;
+     234             :     bias_shifted=true;
+     235          22 :     BiasCoeffs()[0] -= bias_min;
+     236          22 :     bias_max -= bias_min;
+     237             :   }
+     238          23 :   if(bias_max > vesbias_pntr_->getBiasCutoffValue()) {
+     239          22 :     shift += -(bias_max-vesbias_pntr_->getBiasCutoffValue());
+     240             :     bias_shifted=true;
+     241          22 :     BiasCoeffs()[0] -= (bias_max-vesbias_pntr_->getBiasCutoffValue());
+     242          22 :     bias_max -= (bias_max-vesbias_pntr_->getBiasCutoffValue());
+     243             :   }
+     244          23 :   if(bias_shifted) {
+     245             :     // this should be done inside a grid function really,
+     246             :     // need to define my grid class for that
+     247        2322 :     for(Grid::index_t l=0; l<bias_withoutcutoff_grid_pntr_->getSize(); l++) {
+     248        2300 :       if(bias_withoutcutoff_grid_pntr_->hasDerivatives()) {
+     249        2300 :         std::vector<double> zeros(nargs_,0.0);
+     250        2300 :         bias_withoutcutoff_grid_pntr_->addValueAndDerivatives(l,shift,zeros);
+     251             :       }
+     252             :       else {
+     253           0 :         bias_withoutcutoff_grid_pntr_->addValue(l,shift);
+     254             :       }
+     255             :     }
+     256             :   }
+     257          23 :   if(vesbias_pntr_!=NULL) {
+     258             :     vesbias_pntr_->setCurrentBiasMaxValue(bias_max);
+     259             :   }
+     260          23 :   if(action_pntr_!=NULL) {
+     261          23 :     setStepOfLastBiasWithoutCutoffGridUpdate(action_pntr_->getStep());
+     262             :   }
+     263             : }
+     264             : 
+     265             : 
+     266         539 : void LinearBasisSetExpansion::updateFesGrid() {
+     267         539 :   plumed_massert(fes_grid_pntr_,"the FES grid is not defined");
+     268         539 :   updateBiasGrid();
+     269         539 :   if(action_pntr_!=NULL && getStepOfLastFesGridUpdate() == action_pntr_->getStep()) {
+     270             :     return;
+     271             :   }
+     272             :   //
+     273             :   double bias2fes_scalingf = -1.0;
+     274     1474154 :   for(Grid::index_t l=0; l<fes_grid_pntr_->getSize(); l++) {
+     275     1473681 :     double fes_value = bias2fes_scalingf*bias_grid_pntr_->getValue(l);
+     276     1473681 :     if(log_targetdist_grid_pntr_!=NULL) {
+     277     1224051 :       fes_value += kBT()*log_targetdist_grid_pntr_->getValue(l);
+     278             :     }
+     279     1473681 :     fes_grid_pntr_->setValue(l,fes_value);
+     280             :   }
+     281         473 :   fes_grid_pntr_->setMinToZero();
+     282         473 :   if(action_pntr_!=NULL) {
+     283         473 :     setStepOfLastFesGridUpdate(action_pntr_->getStep());
+     284             :   }
+     285             : }
+     286             : 
+     287             : 
+     288         212 : void LinearBasisSetExpansion::writeBiasGridToFile(OFile& ofile, const bool append_file) const {
+     289         212 :   plumed_massert(bias_grid_pntr_,"the bias grid is not defined");
+     290         212 :   if(append_file) {ofile.enforceRestart();}
+     291         212 :   bias_grid_pntr_->writeToFile(ofile);
+     292         212 : }
+     293             : 
+     294             : 
+     295           5 : void LinearBasisSetExpansion::writeBiasWithoutCutoffGridToFile(OFile& ofile, const bool append_file) const {
+     296           5 :   plumed_massert(bias_withoutcutoff_grid_pntr_,"the bias without cutoff grid is not defined");
+     297           5 :   if(append_file) {ofile.enforceRestart();}
+     298           5 :   bias_withoutcutoff_grid_pntr_->writeToFile(ofile);
+     299           5 : }
+     300             : 
+     301             : 
+     302         169 : void LinearBasisSetExpansion::writeFesGridToFile(OFile& ofile, const bool append_file) const {
+     303         169 :   plumed_massert(fes_grid_pntr_!=NULL,"the FES grid is not defined");
+     304         169 :   if(append_file) {ofile.enforceRestart();}
+     305         169 :   fes_grid_pntr_->writeToFile(ofile);
+     306         169 : }
+     307             : 
+     308             : 
+     309          36 : void LinearBasisSetExpansion::writeFesProjGridToFile(const std::vector<std::string>& proj_arg, OFile& ofile, const bool append_file) const {
+     310          36 :   plumed_massert(fes_grid_pntr_,"the FES grid is not defined");
+     311          36 :   auto Fw = Tools::make_unique<FesWeight>(beta_);
+     312          36 :   Grid proj_grid = fes_grid_pntr_->project(proj_arg,Fw.get());
+     313          36 :   proj_grid.setMinToZero();
+     314          36 :   if(append_file) {ofile.enforceRestart();}
+     315          36 :   proj_grid.writeToFile(ofile);
+     316          36 : }
+     317             : 
+     318             : 
+     319          82 : void LinearBasisSetExpansion::writeTargetDistGridToFile(OFile& ofile, const bool append_file) const {
+     320          82 :   if(targetdist_grid_pntr_==NULL) {return;}
+     321          82 :   if(append_file) {ofile.enforceRestart();}
+     322          82 :   targetdist_grid_pntr_->writeToFile(ofile);
+     323             : }
+     324             : 
+     325             : 
+     326          82 : void LinearBasisSetExpansion::writeLogTargetDistGridToFile(OFile& ofile, const bool append_file) const {
+     327          82 :   if(log_targetdist_grid_pntr_==NULL) {return;}
+     328          82 :   if(append_file) {ofile.enforceRestart();}
+     329          82 :   log_targetdist_grid_pntr_->writeToFile(ofile);
+     330             : }
+     331             : 
+     332             : 
+     333          20 : void LinearBasisSetExpansion::writeTargetDistProjGridToFile(const std::vector<std::string>& proj_arg, OFile& ofile, const bool append_file) const {
+     334          20 :   if(targetdist_grid_pntr_==NULL) {return;}
+     335          20 :   if(append_file) {ofile.enforceRestart();}
+     336          20 :   Grid proj_grid = TargetDistribution::getMarginalDistributionGrid(targetdist_grid_pntr_,proj_arg);
+     337          20 :   proj_grid.writeToFile(ofile);
+     338          20 : }
+     339             : 
+     340             : 
+     341           0 : void LinearBasisSetExpansion::writeTargetDistributionToFile(const std::string& filename) const {
+     342           0 :   OFile of1; OFile of2;
+     343           0 :   if(action_pntr_!=NULL) {
+     344           0 :     of1.link(*action_pntr_); of2.link(*action_pntr_);
+     345             :   }
+     346           0 :   of1.enforceBackup(); of2.enforceBackup();
+     347           0 :   of1.open(filename);
+     348           0 :   of2.open(FileBase::appendSuffix(filename,".log"));
+     349           0 :   writeTargetDistGridToFile(of1);
+     350           0 :   writeLogTargetDistGridToFile(of2);
+     351           0 :   of1.close(); of2.close();
+     352           0 : }
+     353             : 
+     354             : 
+     355     2011787 : double LinearBasisSetExpansion::getBiasAndForces(const std::vector<double>& args_values, bool& all_inside, std::vector<double>& forces, std::vector<double>& coeffsderivs_values, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in, Communicator* comm_in) {
+     356     2011787 :   unsigned int nargs = args_values.size();
+     357     2011787 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
+     358     2011787 :   plumed_assert(basisf_pntrs_in.size()==nargs);
+     359     2011787 :   plumed_assert(forces.size()==nargs);
+     360     2011787 :   plumed_assert(coeffsderivs_values.size()==coeffs_pntr_in->numberOfCoeffs());
+     361             : 
+     362     2011787 :   std::vector<double> args_values_trsfrm(nargs);
+     363             :   // std::vector<bool>   inside_interval(nargs,true);
+     364     2011787 :   all_inside = true;
+     365             :   //
+     366     2011787 :   std::vector< std::vector <double> > bf_values(nargs);
+     367     2011787 :   std::vector< std::vector <double> > bf_derivs(nargs);
+     368             :   //
+     369     5966255 :   for(unsigned int k=0; k<nargs; k++) {
+     370     3954468 :     bf_values[k].assign(basisf_pntrs_in[k]->getNumberOfBasisFunctions(),0.0);
+     371     3954468 :     bf_derivs[k].assign(basisf_pntrs_in[k]->getNumberOfBasisFunctions(),0.0);
+     372     3954468 :     bool curr_inside=true;
+     373     3954468 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],curr_inside,bf_values[k],bf_derivs[k]);
+     374             :     // inside_interval[k]=curr_inside;
+     375     3954468 :     if(!curr_inside) {all_inside=false;}
+     376     3954468 :     forces[k]=0.0;
+     377             :   }
+     378             :   //
+     379             :   size_t stride=1;
+     380             :   size_t rank=0;
+     381     2011787 :   if(comm_in!=NULL)
+     382             :   {
+     383     2011787 :     stride=comm_in->Get_size();
+     384     2011787 :     rank=comm_in->Get_rank();
+     385             :   }
+     386             :   // loop over coeffs
+     387     2011787 :   double bias=0.0;
+     388   144769949 :   for(size_t i=rank; i<coeffs_pntr_in->numberOfCoeffs(); i+=stride) {
+     389   142758162 :     std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(i);
+     390             :     double coeff = coeffs_pntr_in->getValue(i);
+     391             :     double bf_curr=1.0;
+     392   435044808 :     for(unsigned int k=0; k<nargs; k++) {
+     393   292286646 :       bf_curr*=bf_values[k][indices[k]];
+     394             :     }
+     395   142758162 :     bias+=coeff*bf_curr;
+     396   142758162 :     coeffsderivs_values[i] = bf_curr;
+     397   435044808 :     for(unsigned int k=0; k<nargs; k++) {
+     398             :       double der = 1.0;
+     399   898592256 :       for(unsigned int l=0; l<nargs; l++) {
+     400   606305610 :         if(l!=k) {der*=bf_values[l][indices[l]];}
+     401   292286646 :         else {der*=bf_derivs[l][indices[l]];}
+     402             :       }
+     403   292286646 :       forces[k]-=coeff*der;
+     404             :       // maybe faster but dangerous
+     405             :       // forces[k]-=coeff*bf_curr*(bf_derivs[k][indices[k]]/bf_values[k][indices[k]]);
+     406             :     }
+     407             :   }
+     408             :   //
+     409     2011787 :   if(comm_in!=NULL) {
+     410             :     // coeffsderivs_values is not summed as the mpi Sum is done later on for the averages
+     411     2011787 :     comm_in->Sum(bias);
+     412     2011787 :     comm_in->Sum(forces);
+     413             :   }
+     414     2011787 :   return bias;
+     415     2011787 : }
+     416             : 
+     417             : 
+     418      862315 : void LinearBasisSetExpansion::getBasisSetValues(const std::vector<double>& args_values, std::vector<double>& basisset_values, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in, Communicator* comm_in) {
+     419      862315 :   unsigned int nargs = args_values.size();
+     420      862315 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
+     421      862315 :   plumed_assert(basisf_pntrs_in.size()==nargs);
+     422             : 
+     423      862315 :   std::vector<double> args_values_trsfrm(nargs);
+     424             :   std::vector< std::vector <double> > bf_values;
+     425             :   //
+     426     2583312 :   for(unsigned int k=0; k<nargs; k++) {
+     427     1720997 :     std::vector<double> tmp_val(basisf_pntrs_in[k]->getNumberOfBasisFunctions());
+     428     1720997 :     std::vector<double> tmp_der(tmp_val.size());
+     429     1720997 :     bool inside=true;
+     430     1720997 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],inside,tmp_val,tmp_der);
+     431     1720997 :     bf_values.push_back(tmp_val);
+     432             :   }
+     433             :   //
+     434             :   size_t stride=1;
+     435             :   size_t rank=0;
+     436      862315 :   if(comm_in!=NULL)
+     437             :   {
+     438           0 :     stride=comm_in->Get_size();
+     439           0 :     rank=comm_in->Get_rank();
+     440             :   }
+     441             :   // loop over basis set
+     442    95955507 :   for(size_t i=rank; i<coeffs_pntr_in->numberOfCoeffs(); i+=stride) {
+     443    95093192 :     std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(i);
+     444             :     double bf_curr=1.0;
+     445   298507612 :     for(unsigned int k=0; k<nargs; k++) {
+     446   203414420 :       bf_curr*=bf_values[k][indices[k]];
+     447             :     }
+     448    95093192 :     basisset_values[i] = bf_curr;
+     449             :   }
+     450             :   //
+     451      862315 :   if(comm_in!=NULL) {
+     452           0 :     comm_in->Sum(basisset_values);
+     453             :   }
+     454     1724630 : }
+     455             : 
+     456             : 
+     457         408 : double LinearBasisSetExpansion::getBasisSetValue(const std::vector<double>& args_values, const size_t index, std::vector<BasisFunctions*>& basisf_pntrs_in, CoeffsVector* coeffs_pntr_in) {
+     458         408 :   unsigned int nargs = args_values.size();
+     459         408 :   plumed_assert(coeffs_pntr_in->numberOfDimensions()==nargs);
+     460         408 :   plumed_assert(basisf_pntrs_in.size()==nargs);
+     461             : 
+     462         408 :   std::vector<double> args_values_trsfrm(nargs);
+     463             :   std::vector< std::vector <double> > bf_values;
+     464             :   //
+     465         938 :   for(unsigned int k=0; k<nargs; k++) {
+     466         530 :     std::vector<double> tmp_val(basisf_pntrs_in[k]->getNumberOfBasisFunctions());
+     467         530 :     std::vector<double> tmp_der(tmp_val.size());
+     468         530 :     bool inside=true;
+     469         530 :     basisf_pntrs_in[k]->getAllValues(args_values[k],args_values_trsfrm[k],inside,tmp_val,tmp_der);
+     470         530 :     bf_values.push_back(tmp_val);
+     471             :   }
+     472             :   //
+     473         408 :   std::vector<unsigned int> indices=coeffs_pntr_in->getIndices(index);
+     474             :   double bf_value=1.0;
+     475         938 :   for(unsigned int k=0; k<nargs; k++) {
+     476         530 :     bf_value*=bf_values[k][indices[k]];
+     477             :   }
+     478         408 :   return bf_value;
+     479         408 : }
+     480             : 
+     481             : 
+     482          45 : void LinearBasisSetExpansion::setupUniformTargetDistribution() {
+     483          45 :   std::vector< std::vector <double> > bf_integrals(0);
+     484          45 :   std::vector<double> targetdist_averages(ncoeffs_,0.0);
+     485             :   //
+     486         100 :   for(unsigned int k=0; k<nargs_; k++) {
+     487         110 :     bf_integrals.push_back(basisf_pntrs_[k]->getUniformIntegrals());
+     488             :   }
+     489             :   //
+     490        1672 :   for(size_t i=0; i<ncoeffs_; i++) {
+     491        1627 :     std::vector<unsigned int> indices=bias_coeffs_pntr_->getIndices(i);
+     492             :     double value = 1.0;
+     493        4492 :     for(unsigned int k=0; k<nargs_; k++) {
+     494        2865 :       value*=bf_integrals[k][indices[k]];
+     495             :     }
+     496        1627 :     targetdist_averages[i]=value;
+     497             :   }
+     498          45 :   TargetDistAverages() = targetdist_averages;
+     499          45 : }
+     500             : 
+     501             : 
+     502          45 : void LinearBasisSetExpansion::setupTargetDistribution(TargetDistribution* targetdist_pntr_in) {
+     503          45 :   targetdist_pntr_ = targetdist_pntr_in;
+     504             :   //
+     505          45 :   targetdist_pntr_->setupGrids(args_pntrs_,grid_min_,grid_max_,grid_bins_);
+     506          45 :   targetdist_grid_pntr_      = targetdist_pntr_->getTargetDistGridPntr();
+     507          45 :   log_targetdist_grid_pntr_  = targetdist_pntr_->getLogTargetDistGridPntr();
+     508             :   //
+     509          45 :   if(targetdist_pntr_->isDynamic()) {
+     510          39 :     vesbias_pntr_->enableDynamicTargetDistribution();
+     511             :   }
+     512             :   //
+     513          45 :   if(targetdist_pntr_->biasGridNeeded()) {
+     514           0 :     setupBiasGrid(true);
+     515           0 :     targetdist_pntr_->linkBiasGrid(bias_grid_pntr_.get());
+     516             :   }
+     517          45 :   if(targetdist_pntr_->biasWithoutCutoffGridNeeded()) {
+     518           3 :     setupBiasGrid(true);
+     519           3 :     targetdist_pntr_->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_.get());
+     520             :   }
+     521          45 :   if(targetdist_pntr_->fesGridNeeded()) {
+     522          36 :     setupFesGrid();
+     523          36 :     targetdist_pntr_->linkFesGrid(fes_grid_pntr_.get());
+     524             :   }
+     525             :   //
+     526          45 :   targetdist_pntr_->updateTargetDist();
+     527          45 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
+     528          45 : }
+     529             : 
+     530             : 
+     531         355 : void LinearBasisSetExpansion::updateTargetDistribution() {
+     532         355 :   plumed_massert(targetdist_pntr_!=NULL,"the target distribution hasn't been setup!");
+     533         355 :   plumed_massert(targetdist_pntr_->isDynamic(),"this should only be used for dynamically updated target distributions!");
+     534         355 :   if(targetdist_pntr_->biasGridNeeded()) {updateBiasGrid();}
+     535         355 :   if(biasCutoffActive()) {updateBiasWithoutCutoffGrid();}
+     536         355 :   if(targetdist_pntr_->fesGridNeeded()) {updateFesGrid();}
+     537         355 :   targetdist_pntr_->updateTargetDist();
+     538         355 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
+     539         355 : }
+     540             : 
+     541             : 
+     542           8 : void LinearBasisSetExpansion::readInRestartTargetDistribution(const std::string& grid_fname) {
+     543           8 :   targetdist_pntr_->readInRestartTargetDistGrid(grid_fname);
+     544           8 :   if(biasCutoffActive()) {targetdist_pntr_->clearLogTargetDistGrid();}
+     545           8 : }
+     546             : 
+     547             : 
+     548           8 : void LinearBasisSetExpansion::restartTargetDistribution() {
+     549           8 :   plumed_massert(targetdist_pntr_!=NULL,"the target distribution hasn't been setup!");
+     550           8 :   plumed_massert(targetdist_pntr_->isDynamic(),"this should only be used for dynamically updated target distributions!");
+     551           8 :   if(biasCutoffActive()) {updateBiasWithoutCutoffGrid();}
+     552           8 :   calculateTargetDistAveragesFromGrid(targetdist_grid_pntr_);
+     553           8 : }
+     554             : 
+     555             : 
+     556         408 : void LinearBasisSetExpansion::calculateTargetDistAveragesFromGrid(const Grid* targetdist_grid_pntr) {
+     557         408 :   plumed_assert(targetdist_grid_pntr!=NULL);
+     558         408 :   std::vector<double> targetdist_averages(ncoeffs_,0.0);
+     559         816 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr);
+     560         408 :   Grid::index_t stride=mycomm_.Get_size();
+     561         408 :   Grid::index_t rank=mycomm_.Get_rank();
+     562      862723 :   for(Grid::index_t l=rank; l<targetdist_grid_pntr->getSize(); l+=stride) {
+     563      862315 :     std::vector<double> args_values = targetdist_grid_pntr->getPoint(l);
+     564      862315 :     std::vector<double> basisset_values(ncoeffs_);
+     565             :     // parallelization done over the grid -> should NOT use parallel in getBasisSetValues!!
+     566      862315 :     getBasisSetValues(args_values,basisset_values,false);
+     567      862315 :     double weight = integration_weights[l]*targetdist_grid_pntr->getValue(l);
+     568    95955507 :     for(unsigned int i=0; i<ncoeffs_; i++) {
+     569    95093192 :       targetdist_averages[i] += weight*basisset_values[i];
+     570             :     }
+     571             :   }
+     572         408 :   mycomm_.Sum(targetdist_averages);
+     573             :   // the overall constant;
+     574         408 :   targetdist_averages[0] = getBasisSetConstant();
+     575         408 :   TargetDistAverages() = targetdist_averages;
+     576         408 : }
+     577             : 
+     578             : 
+     579          39 : void LinearBasisSetExpansion::setBiasMinimumToZero() {
+     580          39 :   plumed_massert(bias_grid_pntr_,"setBiasMinimumToZero can only be used if the bias grid is defined");
+     581          39 :   updateBiasGrid();
+     582          39 :   BiasCoeffs()[0]-=bias_grid_pntr_->getMinValue();
+     583          39 : }
+     584             : 
+     585             : 
+     586           0 : void LinearBasisSetExpansion::setBiasMaximumToZero() {
+     587           0 :   plumed_massert(bias_grid_pntr_,"setBiasMaximumToZero can only be used if the bias grid is defined");
+     588           0 :   updateBiasGrid();
+     589           0 :   BiasCoeffs()[0]-=bias_grid_pntr_->getMaxValue();
+     590           0 : }
+     591             : 
+     592             : 
+     593     1982225 : bool LinearBasisSetExpansion::biasCutoffActive() const {
+     594     1982225 :   if(vesbias_pntr_!=NULL) {return vesbias_pntr_->biasCutoffActive();}
+     595             :   else {return false;}
+     596             : }
+     597             : 
+     598             : 
+     599           0 : double LinearBasisSetExpansion::calculateReweightFactor() const {
+     600           0 :   plumed_massert(targetdist_grid_pntr_!=NULL,"calculateReweightFactor only be used if the target distribution grid is defined");
+     601           0 :   plumed_massert(bias_grid_pntr_,"calculateReweightFactor only be used if the bias grid is defined");
+     602             :   double sum = 0.0;
+     603           0 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr_);
+     604             :   //
+     605           0 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++) {
+     606           0 :     sum += integration_weights[l] * targetdist_grid_pntr_->getValue(l) * exp(+beta_*bias_grid_pntr_->getValue(l));
+     607             :   }
+     608           0 :   if(sum==0.0) sum=std::numeric_limits<double>::min();
+     609           0 :   return (1.0/beta_)*std::log(sum);
+     610             : }
+     611             : 
+     612             : 
+     613             : 
+     614             : 
+     615             : }
+     616             : 
+     617             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.h.func-sort-c.html b/coverage/ves/LinearBasisSetExpansion.h.func-sort-c.html new file mode 100644 index 000000000000..a5931ec21d90 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion19getBasisSetConstantEv408
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_b862315
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_1988037
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.h.func.html b/coverage/ves/LinearBasisSetExpansion.h.func.html new file mode 100644 index 000000000000..8a9641589590 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves23LinearBasisSetExpansion16getBiasAndForcesERKSt6vectorIdSaIdEERbRS4_1988037
_ZN4PLMD3ves23LinearBasisSetExpansion17getBasisSetValuesERKSt6vectorIdSaIdEERS4_b862315
_ZN4PLMD3ves23LinearBasisSetExpansion19getBasisSetConstantEv408
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/LinearBasisSetExpansion.h.gcov.html b/coverage/ves/LinearBasisSetExpansion.h.gcov.html new file mode 100644 index 000000000000..06076d579f41 --- /dev/null +++ b/coverage/ves/LinearBasisSetExpansion.h.gcov.html @@ -0,0 +1,327 @@ + + + + + + + + LCOV - plumed test coverage - ves/LinearBasisSetExpansion.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - LinearBasisSetExpansion.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:212295.5 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_LinearBasisSetExpansion_h
+      23             : #define __PLUMED_ves_LinearBasisSetExpansion_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <string>
+      27             : #include <memory>
+      28             : 
+      29             : 
+      30             : namespace PLMD {
+      31             : 
+      32             : class Action;
+      33             : class Keywords;
+      34             : class Value;
+      35             : class Communicator;
+      36             : class Grid;
+      37             : class OFile;
+      38             : 
+      39             : 
+      40             : namespace ves {
+      41             : 
+      42             : class CoeffsVector;
+      43             : class BasisFunctions;
+      44             : class TargetDistribution;
+      45             : class VesBias;
+      46             : 
+      47             : 
+      48             : class LinearBasisSetExpansion {
+      49             :   LinearBasisSetExpansion& operator=(const LinearBasisSetExpansion&) = delete;
+      50             : private:
+      51             :   std::string label_;
+      52             :   //
+      53             :   Action* action_pntr_;
+      54             :   VesBias* vesbias_pntr_;
+      55             :   Communicator& mycomm_;
+      56             :   bool serial_;
+      57             :   //
+      58             :   double beta_;
+      59             :   double kbt_;
+      60             :   //
+      61             :   std::vector<Value*> args_pntrs_;
+      62             :   unsigned int nargs_;
+      63             :   //
+      64             :   std::vector<BasisFunctions*> basisf_pntrs_;
+      65             :   std::vector<unsigned int> nbasisf_;
+      66             :   //
+      67             :   CoeffsVector* bias_coeffs_pntr_;
+      68             :   size_t ncoeffs_;
+      69             :   std::unique_ptr<CoeffsVector> targetdist_averages_pntr_;
+      70             :   //
+      71             :   std::vector<std::string> grid_min_;
+      72             :   std::vector<std::string> grid_max_;
+      73             :   std::vector<unsigned int> grid_bins_;
+      74             :   //
+      75             :   std::string targetdist_grid_label_;
+      76             :   //
+      77             :   long long int step_of_last_biasgrid_update;
+      78             :   long long int step_of_last_biaswithoutcutoffgrid_update;
+      79             :   long long int step_of_last_fesgrid_update;
+      80             :   //
+      81             :   std::unique_ptr<Grid> bias_grid_pntr_;
+      82             :   std::unique_ptr<Grid> bias_withoutcutoff_grid_pntr_;
+      83             :   std::unique_ptr<Grid> fes_grid_pntr_;
+      84             :   Grid* log_targetdist_grid_pntr_;
+      85             :   Grid* targetdist_grid_pntr_;
+      86             :   //
+      87             :   TargetDistribution* targetdist_pntr_;
+      88             : public:
+      89             :   static void registerKeywords( Keywords& keys );
+      90             :   // Constructor
+      91             :   explicit LinearBasisSetExpansion(
+      92             :     const std::string&,
+      93             :     const double,
+      94             :     Communicator&,
+      95             :     const std::vector<Value*>&,
+      96             :     std::vector<BasisFunctions*>&,
+      97             :     CoeffsVector* bias_coeffs_pntr_in=NULL);
+      98             :   //
+      99             : private:
+     100             :   // copy constructor is disabled (private and unimplemented)
+     101             :   explicit LinearBasisSetExpansion(const LinearBasisSetExpansion&);
+     102             : public:
+     103             :   ~LinearBasisSetExpansion();
+     104             :   //
+     105             :   std::vector<Value*> getPntrsToArguments() const {return args_pntrs_;}
+     106             :   std::vector<BasisFunctions*> getPntrsToBasisFunctions() const {return basisf_pntrs_;}
+     107             :   CoeffsVector* getPntrToBiasCoeffs() const {return bias_coeffs_pntr_;}
+     108             :   Grid* getPntrToBiasGrid() const {return bias_grid_pntr_.get();};
+     109             :   //
+     110             :   unsigned int getNumberOfArguments() const {return nargs_;};
+     111             :   std::vector<unsigned int> getNumberOfBasisFunctions() const {return nbasisf_;};
+     112             :   size_t getNumberOfCoeffs() const {return ncoeffs_;};
+     113             :   //
+     114          83 :   CoeffsVector& BiasCoeffs() const {return *bias_coeffs_pntr_;};
+     115             :   CoeffsVector& TargetDistAverages() const {return *targetdist_averages_pntr_;};
+     116             :   //
+     117             :   void setSerial() {serial_=true;}
+     118             :   void setParallel() {serial_=false;}
+     119             :   //
+     120             :   void linkVesBias(VesBias*);
+     121             :   void linkAction(Action*);
+     122             :   // calculate bias and derivatives
+     123             :   static double getBiasAndForces(const std::vector<double>&, bool&, std::vector<double>&, std::vector<double>&, std::vector<BasisFunctions*>&, CoeffsVector*, Communicator* comm_in=NULL);
+     124             :   double getBiasAndForces(const std::vector<double>&, bool&, std::vector<double>&, std::vector<double>&);
+     125             :   double getBiasAndForces(const std::vector<double>&, bool&, std::vector<double>&);
+     126             :   double getBias(const std::vector<double>&, bool&, const bool parallel=true);
+     127             :   //
+     128             :   static void getBasisSetValues(const std::vector<double>&, std::vector<double>&, std::vector<BasisFunctions*>&, CoeffsVector*, Communicator* comm_in=NULL);
+     129             :   void getBasisSetValues(const std::vector<double>&, std::vector<double>&, const bool parallel=true);
+     130             :   //
+     131             :   static double getBasisSetValue(const std::vector<double>&, const size_t, std::vector<BasisFunctions*>&, CoeffsVector*);
+     132             :   double getBasisSetValue(const std::vector<double>&, const size_t);
+     133             :   double getBasisSetConstant();
+     134             :   // Bias grid and output stuff
+     135             :   void setupBiasGrid(const bool usederiv=false);
+     136             :   void updateBiasGrid();
+     137          36 :   void resetStepOfLastBiasGridUpdate() {step_of_last_biasgrid_update = -1000;}
+     138         475 :   void setStepOfLastBiasGridUpdate(long long int step) {step_of_last_biasgrid_update = step;}
+     139         712 :   long long int getStepOfLastBiasGridUpdate() const {return step_of_last_biasgrid_update;}
+     140             :   void writeBiasGridToFile(OFile&, const bool append=false) const;
+     141             :   //
+     142             :   void updateBiasWithoutCutoffGrid();
+     143             :   void resetStepOfLastBiasWithoutCutoffGridUpdate() {step_of_last_biaswithoutcutoffgrid_update = -1000;}
+     144          23 :   void setStepOfLastBiasWithoutCutoffGridUpdate(long long int step) {step_of_last_biaswithoutcutoffgrid_update = step;}
+     145          27 :   long long int getStepOfLastBiasWithoutCutoffGridUpdate() const {return step_of_last_biaswithoutcutoffgrid_update;}
+     146             :   void writeBiasWithoutCutoffGridToFile(OFile&, const bool append=false) const;
+     147             :   //
+     148             :   void setBiasMinimumToZero();
+     149             :   void setBiasMaximumToZero();
+     150             :   //
+     151             :   void setupFesGrid();
+     152             :   void updateFesGrid();
+     153          36 :   void resetStepOfLastFesGridUpdate() {step_of_last_fesgrid_update = -1000;}
+     154         473 :   void setStepOfLastFesGridUpdate(long long int step) {step_of_last_fesgrid_update = step;}
+     155         539 :   long long int getStepOfLastFesGridUpdate() const {return step_of_last_fesgrid_update;}
+     156             :   void writeFesGridToFile(OFile&, const bool append=false) const;
+     157             :   //
+     158             :   void setupFesProjGrid();
+     159             :   void writeFesProjGridToFile(const std::vector<std::string>&, OFile&, const bool append=false) const;
+     160             :   //
+     161             :   void writeTargetDistGridToFile(OFile&, const bool append=false) const;
+     162             :   void writeLogTargetDistGridToFile(OFile&, const bool append=false) const;
+     163             :   void writeTargetDistProjGridToFile(const std::vector<std::string>&, OFile&, const bool append=false) const;
+     164             :   void writeTargetDistributionToFile(const std::string&) const;
+     165             :   //
+     166             :   std::vector<unsigned int> getGridBins() const {return grid_bins_;}
+     167             :   void setGridBins(const std::vector<unsigned int>&);
+     168             :   void setGridBins(const unsigned int);
+     169             :   //
+     170             :   double getBeta() const {return beta_;}
+     171             :   double getKbT() const {return kbt_;}
+     172             :   double beta() const {return beta_;}
+     173     1224051 :   double kBT() const {return kbt_;}
+     174             :   //
+     175             :   void setupUniformTargetDistribution();
+     176             :   void setupTargetDistribution(TargetDistribution*);
+     177             :   void updateTargetDistribution();
+     178             :   //
+     179             :   void readInRestartTargetDistribution(const std::string&);
+     180             :   void restartTargetDistribution();
+     181             :   //
+     182             :   bool biasCutoffActive() const;
+     183             :   //
+     184             :   double calculateReweightFactor() const;
+     185             :   //
+     186             : private:
+     187             :   //
+     188             :   std::unique_ptr<Grid> setupGeneralGrid(const std::string&, const bool usederiv=false);
+     189             :   //
+     190             :   void calculateTargetDistAveragesFromGrid(const Grid*);
+     191             :   //
+     192             :   bool isStaticTargetDistFileOutputActive() const;
+     193             : };
+     194             : 
+     195             : 
+     196             : inline
+     197             : double LinearBasisSetExpansion::getBiasAndForces(const std::vector<double>& args_values, bool& all_inside, std::vector<double>& forces, std::vector<double>& coeffsderivs_values) {
+     198       23750 :   return getBiasAndForces(args_values,all_inside,forces,coeffsderivs_values,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     199             : }
+     200             : 
+     201             : 
+     202             : inline
+     203     1988037 : double LinearBasisSetExpansion::getBiasAndForces(const std::vector<double>& args_values, bool& all_inside, std::vector<double>& forces) {
+     204     1988037 :   std::vector<double> coeffsderivs_values_dummy(ncoeffs_);
+     205     3976074 :   return getBiasAndForces(args_values,all_inside,forces,coeffsderivs_values_dummy,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     206             : }
+     207             : 
+     208             : 
+     209             : inline
+     210             : double LinearBasisSetExpansion::getBias(const std::vector<double>& args_values, bool& all_inside, const bool parallel) {
+     211             :   std::vector<double> forces_dummy(nargs_);
+     212             :   std::vector<double> coeffsderivs_values_dummy(ncoeffs_);
+     213             :   if(parallel) {
+     214             :     return getBiasAndForces(args_values,all_inside,forces_dummy,coeffsderivs_values_dummy,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     215             :   }
+     216             :   else {
+     217             :     return getBiasAndForces(args_values,all_inside,forces_dummy,coeffsderivs_values_dummy,basisf_pntrs_, bias_coeffs_pntr_, NULL);
+     218             :   }
+     219             : }
+     220             : 
+     221             : 
+     222             : inline
+     223      862315 : void LinearBasisSetExpansion::getBasisSetValues(const std::vector<double>& args_values, std::vector<double>& basisset_values, const bool parallel) {
+     224      862315 :   if(parallel) {
+     225           0 :     getBasisSetValues(args_values,basisset_values,basisf_pntrs_, bias_coeffs_pntr_, &mycomm_);
+     226             :   }
+     227             :   else {
+     228      862315 :     getBasisSetValues(args_values,basisset_values,basisf_pntrs_, bias_coeffs_pntr_, NULL);
+     229             :   }
+     230      862315 : }
+     231             : 
+     232             : 
+     233             : inline
+     234             : double LinearBasisSetExpansion::getBasisSetValue(const std::vector<double>& args_values, const size_t basisset_index) {
+     235             :   return getBasisSetValue(args_values,basisset_index,basisf_pntrs_, bias_coeffs_pntr_);
+     236             : }
+     237             : 
+     238             : 
+     239             : inline
+     240         408 : double LinearBasisSetExpansion::getBasisSetConstant() {
+     241         408 :   std::vector<double> args_dummy(nargs_,0.0);
+     242         816 :   return getBasisSetValue(args_dummy,0,basisf_pntrs_, bias_coeffs_pntr_);
+     243             : }
+     244             : 
+     245             : 
+     246             : }
+     247             : 
+     248             : }
+     249             : 
+     250             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/MD_LinearExpansionPES.cpp.func-sort-c.html b/coverage/ves/MD_LinearExpansionPES.cpp.func-sort-c.html new file mode 100644 index 000000000000..0264c7e8c135 --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/MD_LinearExpansionPES.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - MD_LinearExpansionPES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32533597.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves21MD_LinearExpansionPES11descriptionB5cxx11Ev4
_ZN4PLMD3ves21MD_LinearExpansionPES4mainEP8_IO_FILES3_RNS_12CommunicatorE40
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMe6createERKNS_13CLToolOptionsE44
_ZN4PLMD3ves21MD_LinearExpansionPESC2ERKNS_13CLToolOptionsE44
_ZN4PLMD3ves21MD_LinearExpansionPES11calc_energyERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EERS6_3939
_ZN4PLMD3ves21MD_LinearExpansionPES9calc_tempERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EE3939
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeC2Ev4187
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeD2Ev4187
_ZN4PLMD3ves21MD_LinearExpansionPES16registerKeywordsERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/MD_LinearExpansionPES.cpp.func.html b/coverage/ves/MD_LinearExpansionPES.cpp.func.html new file mode 100644 index 000000000000..3a736ece3786 --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - ves/MD_LinearExpansionPES.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - MD_LinearExpansionPES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32533597.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMe6createERKNS_13CLToolOptionsE44
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeC2Ev4187
_ZN4PLMD3ves12_GLOBAL__N_131MD_LinearExpansionPESRegisterMeD2Ev4187
_ZN4PLMD3ves21MD_LinearExpansionPES11calc_energyERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EERS6_3939
_ZN4PLMD3ves21MD_LinearExpansionPES16registerKeywordsERNS_8KeywordsE4187
_ZN4PLMD3ves21MD_LinearExpansionPES4mainEP8_IO_FILES3_RNS_12CommunicatorE40
_ZN4PLMD3ves21MD_LinearExpansionPES9calc_tempERKSt6vectorINS_13VectorGenericILj3EEESaIS4_EE3939
_ZN4PLMD3ves21MD_LinearExpansionPESC2ERKNS_13CLToolOptionsE44
_ZNK4PLMD3ves21MD_LinearExpansionPES11descriptionB5cxx11Ev4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html b/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html new file mode 100644 index 000000000000..3cda1bc2c28a --- /dev/null +++ b/coverage/ves/MD_LinearExpansionPES.cpp.gcov.html @@ -0,0 +1,758 @@ + + + + + + + + LCOV - plumed test coverage - ves/MD_LinearExpansionPES.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - MD_LinearExpansionPES.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32533597.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : #include "LinearBasisSetExpansion.h"
+      25             : #include "CoeffsVector.h"
+      26             : #include "GridIntegrationWeights.h"
+      27             : #include "GridProjWeights.h"
+      28             : 
+      29             : #include "cltools/CLTool.h"
+      30             : #include "core/CLToolRegister.h"
+      31             : #include "tools/Vector.h"
+      32             : #include "tools/Random.h"
+      33             : #include "tools/Grid.h"
+      34             : #include "tools/Communicator.h"
+      35             : #include "tools/FileBase.h"
+      36             : #include "core/PlumedMain.h"
+      37             : #include "core/ActionRegister.h"
+      38             : #include "core/ActionSet.h"
+      39             : #include "core/Value.h"
+      40             : 
+      41             : #include <string>
+      42             : #include <cstdio>
+      43             : #include <cmath>
+      44             : #include <vector>
+      45             : #include <iostream>
+      46             : 
+      47             : #ifdef __PLUMED_HAS_MPI
+      48             : #include <mpi.h>
+      49             : #endif
+      50             : 
+      51             : 
+      52             : namespace PLMD {
+      53             : namespace ves {
+      54             : 
+      55             : //+PLUMEDOC VES_TOOLS ves_md_linearexpansion
+      56             : /*
+      57             : Simple MD code for dynamics on a potential energy surface given by a linear basis set expansion.
+      58             : 
+      59             : This is simple MD code that allows running dynamics of a single particle on a
+      60             : potential energy surface given by some linear basis set expansion in one to three
+      61             : dimensions.
+      62             : 
+      63             : It is possible to run more than one replica of the system in parallel.
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : In the following example we perform dynamics on the
+      68             : Wolfe-Quapp potential that is defined as
+      69             : \f[
+      70             : U(x,y) = x^4 + y^4 - 2 x^2 - 4 y^2 + xy + 0.3 x + 0.1 y
+      71             : \f]
+      72             : To define the potential we employ polynomial power basis
+      73             : functions (\ref BF_POWERS). The input file is given as
+      74             : \verbatim
+      75             : nstep             10000
+      76             : tstep             0.005
+      77             : temperature       1.0
+      78             : friction          10.0
+      79             : random_seed       4525
+      80             : plumed_input      plumed.dat
+      81             : dimension         2
+      82             : replicas          1
+      83             : basis_functions_1 BF_POWERS ORDER=4 MINIMUM=-3.0 MAXIMUM=+3.0
+      84             : basis_functions_2 BF_POWERS ORDER=4 MINIMUM=-3.0 MAXIMUM=+3.0
+      85             : input_coeffs       pot_coeffs_input.data
+      86             : initial_position   -1.174,+1.477
+      87             : output_potential        potential.data
+      88             : output_potential_grid   150
+      89             : output_histogram        histogram.data
+      90             : 
+      91             : # Wolfe-Quapp potential given by the equation
+      92             : # U(x,y) = x**4 + y**4 - 2.0*x**2 - 4.0*y**2 + x*y + 0.3*x + 0.1*y
+      93             : # Minima around (-1.174,1.477); (-0.831,-1.366); (1.124,-1.486)
+      94             : # Maxima around (0.100,0.050)
+      95             : # Saddle points around (-1.013,-0.036); (0.093,0.174); (-0.208,-1.407)
+      96             : \endverbatim
+      97             : 
+      98             : This input is then run by using the following command.
+      99             : \verbatim
+     100             : plumed ves_md_linearexpansion input
+     101             : \endverbatim
+     102             : 
+     103             : The corresponding pot_coeffs_input.data file is
+     104             : \verbatim
+     105             : #! FIELDS idx_dim1 idx_dim2 pot.coeffs index description
+     106             : #! SET type LinearBasisSet
+     107             : #! SET ndimensions  2
+     108             : #! SET ncoeffs_total  25
+     109             : #! SET shape_dim1  5
+     110             : #! SET shape_dim2  5
+     111             :        0       0         0.0000000000000000e+00       0  1*1
+     112             :        1       0         0.3000000000000000e+00       1  s^1*1
+     113             :        2       0        -2.0000000000000000e+00       2  s^2*1
+     114             :        4       0         1.0000000000000000e+00       4  s^4*1
+     115             :        0       1         0.1000000000000000e+00       5  1*s^1
+     116             :        1       1        +1.0000000000000000e+00       6  s^1*s^1
+     117             :        0       2        -4.0000000000000000e+00      10  1*s^2
+     118             :        0       4         1.0000000000000000e+00      20  1*s^4
+     119             : #!-------------------
+     120             : \endverbatim
+     121             : 
+     122             : One then uses the (x,y) position of the particle as CVs by using the \ref POSITION
+     123             : action as shown in the following PLUMED input
+     124             : \plumedfile
+     125             : p: POSITION ATOM=1
+     126             : ene: ENERGY
+     127             : PRINT ARG=p.x,p.y,ene FILE=colvar.data FMT=%8.4f
+     128             : \endplumedfile
+     129             : 
+     130             : 
+     131             : 
+     132             : */
+     133             : //+ENDPLUMEDOC
+     134             : 
+     135             : class MD_LinearExpansionPES : public PLMD::CLTool {
+     136             : public:
+     137           4 :   std::string description() const override {return "MD of a one particle on a linear expansion PES";}
+     138             :   static void registerKeywords( Keywords& keys );
+     139             :   explicit MD_LinearExpansionPES( const CLToolOptions& co );
+     140             :   int main( FILE* in, FILE* out, PLMD::Communicator& pc) override;
+     141             : private:
+     142             :   size_t dim;
+     143             :   std::string dim_string_prefix;
+     144             :   std::unique_ptr<LinearBasisSetExpansion> potential_expansion_pntr;
+     145             :   //
+     146             :   double calc_energy( const std::vector<Vector>&, std::vector<Vector>& );
+     147             :   double calc_temp( const std::vector<Vector>& );
+     148             : };
+     149             : 
+     150       12605 : PLUMED_REGISTER_CLTOOL(MD_LinearExpansionPES,"ves_md_linearexpansion")
+     151             : 
+     152        4187 : void MD_LinearExpansionPES::registerKeywords( Keywords& keys ) {
+     153        4187 :   CLTool::registerKeywords( keys );
+     154        8374 :   keys.add("compulsory","nstep","10","The number of steps of dynamics you want to run.");
+     155        8374 :   keys.add("compulsory","tstep","0.005","The integration timestep.");
+     156        8374 :   keys.add("compulsory","temperature","1.0","The temperature to perform the simulation at. For multiple replica you can give a separate value for each replica.");
+     157        8374 :   keys.add("compulsory","friction","10.","The friction of the Langevin thermostat. For multiple replica you can give a separate value for each replica.");
+     158        8374 :   keys.add("compulsory","random_seed","5293818","Value of random number seed.");
+     159        8374 :   keys.add("compulsory","plumed_input","plumed.dat","The name of the plumed input file(s). For multiple replica you can give a separate value for each replica.");
+     160        8374 :   keys.add("compulsory","dimension","1","Number of dimensions, supports 1 to 3.");
+     161        8374 :   keys.add("compulsory","initial_position","Initial position of the particle. For multiple replica you can give a separate value for each replica.");
+     162        8374 :   keys.add("compulsory","replicas","1","Number of replicas.");
+     163        8374 :   keys.add("compulsory","basis_functions_1","Basis functions for dimension 1.");
+     164        8374 :   keys.add("optional","basis_functions_2","Basis functions for dimension 2 if needed.");
+     165        8374 :   keys.add("optional","basis_functions_3","Basis functions for dimension 3 if needed.");
+     166        8374 :   keys.add("compulsory","input_coeffs","potential-coeffs.in.data","Filename of the input coefficient file for the potential. For multiple replica you can give a separate value for each replica.");
+     167        8374 :   keys.add("compulsory","output_coeffs","potential-coeffs.out.data","Filename of the output coefficient file for the potential.");
+     168        8374 :   keys.add("compulsory","output_coeffs_fmt","%30.16e","Format of the output coefficient file for the potential. Useful for regtests.");
+     169        8374 :   keys.add("optional","coeffs_prefactor","prefactor for multiplying the coefficients with. For multiple replica you can give a separate value for each replica.");
+     170        8374 :   keys.add("optional","template_coeffs_file","only generate a template coefficient file with the filename given and exit.");
+     171        8374 :   keys.add("compulsory","output_potential_grid","100","The number of grid points used for the potential and histogram output files.");
+     172        8374 :   keys.add("compulsory","output_potential","potential.data","Filename of the potential output file.");
+     173        8374 :   keys.add("compulsory","output_histogram","histogram.data","Filename of the histogram output file.");
+     174        4187 : }
+     175             : 
+     176             : 
+     177          44 : MD_LinearExpansionPES::MD_LinearExpansionPES( const CLToolOptions& co ):
+     178             :   CLTool(co),
+     179          44 :   dim(0),
+     180          44 :   dim_string_prefix("dim")
+     181             : {
+     182          44 :   inputdata=ifile; //commandline;
+     183          44 : }
+     184             : 
+     185             : inline
+     186        3939 : double MD_LinearExpansionPES::calc_energy( const std::vector<Vector>& pos, std::vector<Vector>& forces) {
+     187        3939 :   std::vector<double> pos_tmp(dim);
+     188        3939 :   std::vector<double> forces_tmp(dim,0.0);
+     189        8585 :   for(unsigned int j=0; j<dim; ++j) {
+     190        4646 :     pos_tmp[j]=pos[0][j];
+     191             :   }
+     192        3939 :   bool all_inside = true;
+     193        3939 :   double potential = potential_expansion_pntr->getBiasAndForces(pos_tmp,all_inside,forces_tmp);
+     194        8585 :   for(unsigned int j=0; j<dim; ++j) {
+     195        4646 :     forces[0][j] = forces_tmp[j];
+     196             :   }
+     197        3939 :   return potential;
+     198             : }
+     199             : 
+     200             : 
+     201             : inline
+     202        3939 : double MD_LinearExpansionPES::calc_temp( const std::vector<Vector>& vel) {
+     203             :   double total_KE=0.0;
+     204             :   //! Double the total kinetic energy of the system
+     205        8585 :   for(unsigned int j=0; j<dim; ++j) {
+     206        4646 :     total_KE+=vel[0][j]*vel[0][j];
+     207             :   }
+     208        3939 :   return total_KE / (double) dim; // total_KE is actually 2*KE
+     209             : }
+     210             : 
+     211          40 : int MD_LinearExpansionPES::main( FILE* in, FILE* out, PLMD::Communicator& pc) {
+     212             :   int plumedWantsToStop;
+     213          40 :   Random random;
+     214             :   unsigned int stepWrite=1000;
+     215             : 
+     216          40 :   std::unique_ptr<PLMD::PlumedMain> plumed;
+     217             : 
+     218             :   size_t replicas;
+     219             :   unsigned int coresPerReplica;
+     220          40 :   parse("replicas",replicas);
+     221          40 :   if(replicas==1) {
+     222           9 :     coresPerReplica = pc.Get_size();
+     223             :   } else {
+     224          31 :     if(pc.Get_size()%replicas!=0) {
+     225           0 :       error("the number of MPI processes is not a multiple of the number of replicas.");
+     226             :     }
+     227          31 :     coresPerReplica = pc.Get_size()/replicas;
+     228             :   }
+     229             :   // create intra and inter communicators
+     230          40 :   Communicator intra, inter;
+     231          40 :   if(Communicator::initialized()) {
+     232          33 :     int iworld=(pc.Get_rank() / coresPerReplica);
+     233          33 :     pc.Split(iworld,0,intra);
+     234          33 :     pc.Split(intra.Get_rank(),0,inter);
+     235             :   }
+     236             : 
+     237             :   long long unsigned int nsteps;
+     238          40 :   parse("nstep",nsteps);
+     239             :   double tstep;
+     240          40 :   parse("tstep",tstep);
+     241             :   // initialize to solve a cppcheck 1.86 warning
+     242          40 :   double temp=0.0;
+     243          40 :   std::vector<double> temps_vec(0);
+     244          80 :   parseVector("temperature",temps_vec);
+     245          40 :   if(temps_vec.size()==1) {
+     246          36 :     temp = temps_vec[0];
+     247             :   }
+     248           4 :   else if(replicas > 1 && temps_vec.size()==replicas) {
+     249           4 :     temp = temps_vec[inter.Get_rank()];
+     250             :   }
+     251             :   else {
+     252           0 :     error("problem with temperature keyword, you need to give either one value or a value for each replica.");
+     253             :   }
+     254             :   //
+     255             :   double friction;
+     256          40 :   std::vector<double> frictions_vec(0);
+     257          80 :   parseVector("friction",frictions_vec);
+     258          40 :   if(frictions_vec.size()==1) {
+     259          36 :     friction = frictions_vec[0];
+     260             :   }
+     261           4 :   else if(frictions_vec.size()==replicas) {
+     262           4 :     friction = frictions_vec[inter.Get_rank()];
+     263             :   }
+     264             :   else {
+     265           0 :     error("problem with friction keyword, you need to give either one value or a value for each replica.");
+     266             :   }
+     267             :   //
+     268             :   int seed;
+     269          40 :   std::vector<int> seeds_vec(0);
+     270          40 :   parseVector("random_seed",seeds_vec);
+     271          92 :   for(unsigned int i=0; i<seeds_vec.size(); i++) {
+     272          52 :     if(seeds_vec[i]>0) {seeds_vec[i] = -seeds_vec[i];}
+     273             :   }
+     274          40 :   if(replicas==1) {
+     275           9 :     if(seeds_vec.size()>1) {error("problem with random_seed keyword, for a single replica you should only give one value");}
+     276           9 :     seed = seeds_vec[0];
+     277             :   }
+     278             :   else {
+     279          31 :     if(seeds_vec.size()!=1 && seeds_vec.size()!=replicas) {
+     280           0 :       error("problem with random_seed keyword, for multiple replicas you should give either one value or a separate value for each replica");
+     281             :     }
+     282          31 :     if(seeds_vec.size()==1) {
+     283          27 :       seeds_vec.resize(replicas);
+     284         109 :       for(unsigned int i=1; i<seeds_vec.size(); i++) {seeds_vec[i] = seeds_vec[0] + i;}
+     285             :     }
+     286          31 :     seed = seeds_vec[inter.Get_rank()];
+     287             :   }
+     288             : 
+     289             :   //
+     290          80 :   parse("dimension",dim);
+     291             : 
+     292             :   std::vector<std::string> plumed_inputfiles;
+     293          80 :   parseVector("plumed_input",plumed_inputfiles);
+     294          40 :   if(plumed_inputfiles.size()!=1 && plumed_inputfiles.size()!=replicas) {
+     295           0 :     error("in plumed_input you should either give one file or separate files for each replica.");
+     296             :   }
+     297             : 
+     298          40 :   std::vector<Vector> initPos(replicas);
+     299             :   std::vector<double> initPosTmp;
+     300          80 :   parseVector("initial_position",initPosTmp);
+     301          40 :   if(initPosTmp.size()==dim) {
+     302          48 :     for(unsigned int i=0; i<replicas; i++) {
+     303          72 :       for(unsigned int k=0; k<dim; k++) {
+     304          38 :         initPos[i][k]=initPosTmp[k];
+     305             :       }
+     306             :     }
+     307             :   }
+     308          26 :   else if(initPosTmp.size()==dim*replicas) {
+     309         126 :     for(unsigned int i=0; i<replicas; i++) {
+     310         216 :       for(unsigned int k=0; k<dim; k++) {
+     311         116 :         initPos[i][k]=initPosTmp[i*dim+k];
+     312             :       }
+     313             :     }
+     314             :   }
+     315             :   else {
+     316           0 :     error("problem with initial_position keyword, you need to give either one value or a value for each replica.");
+     317             :   }
+     318             : 
+     319          79 :   auto deleter=[](FILE* f) { fclose(f); };
+     320          40 :   FILE* file_dummy = fopen("/dev/null","w+");
+     321          40 :   plumed_assert(file_dummy);
+     322             :   // call fclose when file_dummy_deleter goes out of scope
+     323             :   std::unique_ptr<FILE,decltype(deleter)> file_dummy_deleter(file_dummy,deleter);
+     324             :   // Note: this should be declared before plumed_bf to make sure the file is closed after plumed_bf has been destroyed
+     325             : 
+     326             :   auto plumed_bf = Tools::make_unique<PLMD::PlumedMain>();
+     327          40 :   unsigned int nn=1;
+     328          40 :   plumed_bf->cmd("setNatoms",&nn);
+     329          40 :   plumed_bf->cmd("setLog",file_dummy);
+     330          40 :   plumed_bf->cmd("init",&nn);
+     331          40 :   std::vector<BasisFunctions*> basisf_pntrs(dim);
+     332          40 :   std::vector<std::string> basisf_keywords(dim);
+     333          40 :   std::vector<std::unique_ptr<Value>> args(dim);
+     334          40 :   std::vector<bool> periodic(dim);
+     335          40 :   std::vector<double> interval_min(dim);
+     336          40 :   std::vector<double> interval_max(dim);
+     337          40 :   std::vector<double> interval_range(dim);
+     338          88 :   for(unsigned int i=0; i<dim; i++) {
+     339             :     std::string bf_keyword;
+     340          48 :     std::string is; Tools::convert(i+1,is);
+     341          96 :     parse("basis_functions_"+is,bf_keyword);
+     342          48 :     if(bf_keyword.size()==0) {
+     343           0 :       error("basis_functions_"+is+" is needed");
+     344             :     }
+     345          48 :     if(bf_keyword.at(0)=='{' && bf_keyword.at(bf_keyword.size()-1)=='}') {
+     346           4 :       bf_keyword = bf_keyword.substr(1,bf_keyword.size()-2);
+     347             :     }
+     348             :     basisf_keywords[i] = bf_keyword;
+     349          96 :     plumed_bf->readInputLine(bf_keyword+" LABEL="+dim_string_prefix+is);
+     350          48 :     basisf_pntrs[i] = plumed_bf->getActionSet().selectWithLabel<BasisFunctions*>(dim_string_prefix+is);
+     351          96 :     args[i] = Tools::make_unique<Value>(nullptr,dim_string_prefix+is,false);
+     352          48 :     args[i]->setNotPeriodic();
+     353          48 :     periodic[i] = basisf_pntrs[i]->arePeriodic();
+     354          48 :     interval_min[i] = basisf_pntrs[i]->intervalMin();
+     355          48 :     interval_max[i] = basisf_pntrs[i]->intervalMax();
+     356          48 :     interval_range[i] = basisf_pntrs[i]->intervalMax()-basisf_pntrs[i]->intervalMin();
+     357             :   }
+     358          40 :   Communicator comm_dummy;
+     359          80 :   auto coeffs_pntr = Tools::make_unique<CoeffsVector>("pot.coeffs",Tools::unique2raw(args),basisf_pntrs,comm_dummy,false);
+     360          80 :   potential_expansion_pntr = Tools::make_unique<LinearBasisSetExpansion>("potential",1.0/temp,comm_dummy,Tools::unique2raw(args),basisf_pntrs,coeffs_pntr.get());
+     361             : 
+     362          40 :   std::string template_coeffs_fname="";
+     363          80 :   parse("template_coeffs_file",template_coeffs_fname);
+     364          40 :   if(template_coeffs_fname.size()>0) {
+     365           1 :     OFile ofile_coeffstmpl;
+     366           1 :     ofile_coeffstmpl.link(pc);
+     367           1 :     ofile_coeffstmpl.open(template_coeffs_fname);
+     368           1 :     coeffs_pntr->writeToFile(ofile_coeffstmpl,true);
+     369           1 :     ofile_coeffstmpl.close();
+     370             :     std::printf("Only generating a template coefficient file - Should stop now.");
+     371             :     return 0;
+     372           1 :   }
+     373             : 
+     374          39 :   std::vector<std::string> input_coeffs_fnames(0);
+     375          78 :   parseVector("input_coeffs",input_coeffs_fnames);
+     376             :   std::string input_coeffs_fname;
+     377             :   bool diff_input_coeffs = false;
+     378          39 :   if(input_coeffs_fnames.size()==1) {
+     379             :     input_coeffs_fname = input_coeffs_fnames[0];
+     380             :   }
+     381           9 :   else if(replicas > 1 && input_coeffs_fnames.size()==replicas) {
+     382             :     diff_input_coeffs = true;
+     383           9 :     input_coeffs_fname = input_coeffs_fnames[inter.Get_rank()];
+     384             :   }
+     385             :   else {
+     386           0 :     error("problem with coeffs_file keyword, you need to give either one value or a value for each replica.");
+     387             :   }
+     388          39 :   coeffs_pntr->readFromFile(input_coeffs_fname,true,true);
+     389          39 :   std::vector<double> coeffs_prefactors(0);
+     390          78 :   parseVector("coeffs_prefactor",coeffs_prefactors);
+     391          39 :   if(coeffs_prefactors.size()>0) {
+     392             :     double coeffs_prefactor = 1.0;
+     393           7 :     if(coeffs_prefactors.size()==1) {
+     394           3 :       coeffs_prefactor = coeffs_prefactors[0];
+     395             :     }
+     396           4 :     else if(replicas > 1 && coeffs_prefactors.size()==replicas) {
+     397             :       diff_input_coeffs = true;
+     398           4 :       coeffs_prefactor = coeffs_prefactors[inter.Get_rank()];
+     399             :     }
+     400             :     else {
+     401           0 :       error("problem with coeffs_prefactor keyword, you need to give either one value or a value for each replica.");
+     402             :     }
+     403           7 :     coeffs_pntr->scaleAllValues(coeffs_prefactor);
+     404             :   }
+     405             :   unsigned int pot_grid_bins;
+     406          78 :   parse("output_potential_grid",pot_grid_bins);
+     407          39 :   potential_expansion_pntr->setGridBins(pot_grid_bins);
+     408          39 :   potential_expansion_pntr->setupBiasGrid(false);
+     409          39 :   potential_expansion_pntr->updateBiasGrid();
+     410          39 :   potential_expansion_pntr->setBiasMinimumToZero();
+     411          39 :   potential_expansion_pntr->updateBiasGrid();
+     412             : 
+     413          39 :   OFile ofile_potential;
+     414          39 :   ofile_potential.link(pc);
+     415             :   std::string output_potential_fname;
+     416          39 :   parse("output_potential",output_potential_fname);
+     417          39 :   if(diff_input_coeffs) {
+     418          13 :     ofile_potential.link(intra);
+     419             :     std::string suffix;
+     420          13 :     Tools::convert(inter.Get_rank(),suffix);
+     421          26 :     output_potential_fname = FileBase::appendSuffix(output_potential_fname,"."+suffix);
+     422             :   }
+     423          39 :   ofile_potential.open(output_potential_fname);
+     424          39 :   potential_expansion_pntr->writeBiasGridToFile(ofile_potential);
+     425          39 :   ofile_potential.close();
+     426          39 :   if(dim>1) {
+     427          21 :     for(unsigned int i=0; i<dim; i++) {
+     428          14 :       std::string is; Tools::convert(i+1,is);
+     429          14 :       std::vector<std::string> proj_arg(1);
+     430          14 :       proj_arg[0] = dim_string_prefix+is;
+     431          14 :       auto Fw = Tools::make_unique<FesWeight>(1/temp);
+     432          14 :       Grid proj_grid = (potential_expansion_pntr->getPntrToBiasGrid())->project(proj_arg,Fw.get());
+     433          14 :       proj_grid.setMinToZero();
+     434             : 
+     435          28 :       std::string output_potential_proj_fname = FileBase::appendSuffix(output_potential_fname,"."+dim_string_prefix+is);
+     436          14 :       OFile ofile_potential_proj;
+     437          14 :       ofile_potential_proj.link(pc);
+     438          14 :       ofile_potential_proj.open(output_potential_proj_fname);
+     439          14 :       proj_grid.writeToFile(ofile_potential_proj);
+     440          14 :       ofile_potential_proj.close();
+     441          28 :     }
+     442             :   }
+     443             : 
+     444             : 
+     445          39 :   Grid histo_grid(*potential_expansion_pntr->getPntrToBiasGrid());
+     446          78 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(&histo_grid);
+     447             :   double norm=0.0;
+     448      169278 :   for(Grid::index_t i=0; i<histo_grid.getSize(); i++) {
+     449      169239 :     double value = integration_weights[i]*exp(-histo_grid.getValue(i)/temp);
+     450      169239 :     norm += value;
+     451      169239 :     histo_grid.setValue(i,value);
+     452             :   }
+     453          39 :   histo_grid.scaleAllValuesAndDerivatives(1.0/norm);
+     454          39 :   OFile ofile_histogram;
+     455          39 :   ofile_histogram.link(pc);
+     456             :   std::string output_histogram_fname;
+     457          39 :   parse("output_histogram",output_histogram_fname);
+     458          39 :   if(diff_input_coeffs || temps_vec.size()>1) {
+     459          17 :     ofile_histogram.link(intra);
+     460             :     std::string suffix;
+     461          17 :     Tools::convert(inter.Get_rank(),suffix);
+     462          34 :     output_histogram_fname = FileBase::appendSuffix(output_histogram_fname,"."+suffix);
+     463             :   }
+     464          39 :   ofile_histogram.open(output_histogram_fname);
+     465          39 :   histo_grid.writeToFile(ofile_histogram);
+     466          39 :   ofile_histogram.close();
+     467             : 
+     468             :   std::string output_coeffs_fname;
+     469          78 :   parse("output_coeffs",output_coeffs_fname);
+     470             :   std::string output_coeffs_fmt;
+     471          78 :   parse("output_coeffs_fmt",output_coeffs_fmt);
+     472             :   coeffs_pntr->setOutputFmt(output_coeffs_fmt);
+     473          39 :   OFile ofile_coeffsout;
+     474          39 :   ofile_coeffsout.link(pc);
+     475          39 :   if(diff_input_coeffs) {
+     476          13 :     ofile_coeffsout.link(intra);
+     477             :     std::string suffix;
+     478          13 :     Tools::convert(inter.Get_rank(),suffix);
+     479          26 :     output_coeffs_fname = FileBase::appendSuffix(output_coeffs_fname,"."+suffix);
+     480             :   }
+     481          39 :   ofile_coeffsout.open(output_coeffs_fname);
+     482          39 :   coeffs_pntr->writeToFile(ofile_coeffsout,true);
+     483          39 :   ofile_coeffsout.close();
+     484             : 
+     485          39 :   if(pc.Get_rank() == 0) {
+     486          15 :     std::fprintf(out,"Replicas                              %zu\n",replicas);
+     487             :     std::fprintf(out,"Cores per replica                     %u\n",coresPerReplica);
+     488          15 :     std::fprintf(out,"Number of steps                       %llu\n",nsteps);
+     489          15 :     std::fprintf(out,"Timestep                              %f\n",tstep);
+     490          15 :     std::fprintf(out,"Temperature                           %f",temps_vec[0]);
+     491          18 :     for(unsigned int i=1; i<temps_vec.size(); i++) {std::fprintf(out,",%f",temps_vec[i]);}
+     492             :     std::fprintf(out,"\n");
+     493          15 :     std::fprintf(out,"Friction                              %f",frictions_vec[0]);
+     494          18 :     for(unsigned int i=1; i<frictions_vec.size(); i++) {std::fprintf(out,",%f",frictions_vec[i]);}
+     495             :     std::fprintf(out,"\n");
+     496          15 :     std::fprintf(out,"Random seed                           %d",seeds_vec[0]);
+     497          38 :     for(unsigned int i=1; i<seeds_vec.size(); i++) {std::fprintf(out,",%d",seeds_vec[i]);}
+     498             :     std::fprintf(out,"\n");
+     499          15 :     std::fprintf(out,"Dimensions                            %zu\n",dim);
+     500          34 :     for(unsigned int i=0; i<dim; i++) {
+     501          19 :       std::fprintf(out,"Basis Function %u                      %s\n",i+1,basisf_keywords[i].c_str());
+     502             :     }
+     503             :     std::fprintf(out,"PLUMED input                          %s",plumed_inputfiles[0].c_str());
+     504          16 :     for(unsigned int i=1; i<plumed_inputfiles.size(); i++) {std::fprintf(out,",%s",plumed_inputfiles[i].c_str());}
+     505             :     std::fprintf(out,"\n");
+     506             :     std::fprintf(out,"kBoltzmann taken as 1, use NATURAL_UNITS in the plumed input\n");
+     507          15 :     if(diff_input_coeffs) {std::fprintf(out,"using different coefficients for each replica\n");}
+     508             :   }
+     509             : 
+     510             : 
+     511          39 :   plumed=Tools::make_unique<PLMD::PlumedMain>();
+     512             : 
+     513             : 
+     514             : 
+     515          39 :   if(plumed) {
+     516          39 :     int s=sizeof(double);
+     517          39 :     plumed->cmd("setRealPrecision",&s);
+     518          39 :     if(replicas>1) {
+     519          31 :       if (Communicator::initialized()) {
+     520          62 :         plumed->cmd("GREX setMPIIntracomm",&intra.Get_comm());
+     521          31 :         if (intra.Get_rank()==0) {
+     522          62 :           plumed->cmd("GREX setMPIIntercomm",&inter.Get_comm());
+     523             :         }
+     524          31 :         plumed->cmd("GREX init");
+     525          62 :         plumed->cmd("setMPIComm",&intra.Get_comm());
+     526             :       } else {
+     527           0 :         error("More than 1 replica but no MPI");
+     528             :       }
+     529             :     } else {
+     530          10 :       if(Communicator::initialized()) plumed->cmd("setMPIComm",&pc.Get_comm());
+     531             :     }
+     532             :   }
+     533             : 
+     534          39 :   std::string plumed_logfile = "plumed.log";
+     535          39 :   std::string stats_filename = "stats.out";
+     536          39 :   std::string plumed_input = plumed_inputfiles[0];
+     537          39 :   if(inter.Get_size()>1) {
+     538             :     std::string suffix;
+     539          31 :     Tools::convert(inter.Get_rank(),suffix);
+     540          62 :     plumed_logfile = FileBase::appendSuffix(plumed_logfile,"."+suffix);
+     541          62 :     stats_filename = FileBase::appendSuffix(stats_filename,"."+suffix);
+     542          31 :     if(plumed_inputfiles.size()>1) {
+     543           2 :       plumed_input = plumed_inputfiles[inter.Get_rank()];
+     544             :     }
+     545             :   }
+     546             : 
+     547          39 :   if(plumed) {
+     548          39 :     int natoms=1;
+     549          39 :     plumed->cmd("setNatoms",&natoms);
+     550          39 :     plumed->cmd("setNoVirial");
+     551          39 :     plumed->cmd("setMDEngine","mdrunner_linearexpansion");
+     552          39 :     plumed->cmd("setTimestep",&tstep);
+     553          39 :     plumed->cmd("setPlumedDat",plumed_input.c_str());
+     554          39 :     plumed->cmd("setLogFile",plumed_logfile.c_str());
+     555          39 :     plumed->cmd("setKbT",&temp);
+     556          39 :     double energyunits=1.0;
+     557          39 :     plumed->cmd("setMDEnergyUnits",&energyunits);
+     558          39 :     plumed->cmd("init");
+     559             :   }
+     560             : 
+     561             :   // Setup random number generator
+     562          39 :   random.setSeed(seed);
+     563             : 
+     564          39 :   double potential, therm_eng=0; std::vector<double> masses(1,1);
+     565          39 :   std::vector<Vector> positions(1), velocities(1), forces(1);
+     566          85 :   for(unsigned int k=0; k<dim; k++) {
+     567          46 :     positions[0][k] = initPos[inter.Get_rank()][k];
+     568          46 :     if(periodic[k]) {
+     569           4 :       positions[0][k] = positions[0][k] - floor((positions[0][k]-interval_min[k])/interval_range[k])*interval_range[k];
+     570             :     }
+     571             :     else {
+     572          42 :       if(positions[0][k]>interval_max[k]) {positions[0][k]=interval_max[k];}
+     573          42 :       if(positions[0][k]<interval_min[k]) {positions[0][k]=interval_min[k];}
+     574             :     }
+     575             :   }
+     576             : 
+     577             : 
+     578          85 :   for(unsigned k=0; k<dim; ++k) {
+     579          46 :     velocities[0][k]=random.Gaussian() * sqrt( temp );
+     580             :   }
+     581             : 
+     582          39 :   potential=calc_energy(positions,forces); double ttt=calc_temp(velocities);
+     583             : 
+     584          39 :   FILE* fp=fopen(stats_filename.c_str(),"w+");
+     585             :   // call fclose when fp_deleter goes out of scope
+     586             :   std::unique_ptr<FILE,decltype(deleter)> fp_deleter(fp,deleter);
+     587             : 
+     588          39 :   double conserved = potential+1.5*ttt+therm_eng;
+     589             :   //std::fprintf(fp,"%d %f %f %f %f %f %f %f %f \n", 0, 0., positions[0][0], positions[0][1], positions[0][2], conserved, ttt, potential, therm_eng );
+     590          39 :   if( intra.Get_rank()==0 ) {
+     591          38 :     std::fprintf(fp,"%d %f %f %f %f %f %f %f %f \n", 0, 0., positions[0][0], positions[0][1], positions[0][2], conserved, ttt, potential, therm_eng );
+     592             :   }
+     593             : 
+     594          39 :   if(plumed) {
+     595          39 :     long long unsigned int step_tmp = 0;
+     596          39 :     plumed->cmd("setStepLongLong",&step_tmp);
+     597          39 :     plumed->cmd("setMasses",&masses[0]);
+     598          39 :     plumed->cmd("setForces",&forces[0][0]);
+     599          39 :     plumed->cmd("setEnergy",&potential);
+     600          39 :     plumed->cmd("setPositions",&positions[0][0]);
+     601          39 :     plumed->cmd("calc");
+     602             :   }
+     603             : 
+     604        3939 :   for(long long unsigned int istep=0; istep<nsteps; ++istep) {
+     605             :     //if( istep%20==0 && pc.Get_rank()==0 ) printf("Doing step %llu\n",istep);
+     606             : 
+     607             :     // Langevin thermostat
+     608        3900 :     double lscale=exp(-0.5*tstep*friction); //exp(-0.5*tstep/friction);
+     609        3900 :     double lrand=sqrt((1.-lscale*lscale)*temp);
+     610        8500 :     for(unsigned k=0; k<dim; ++k) {
+     611        4600 :       therm_eng=therm_eng+0.5*velocities[0][k]*velocities[0][k];
+     612        4600 :       velocities[0][k]=lscale*velocities[0][k]+lrand*random.Gaussian();
+     613        4600 :       therm_eng=therm_eng-0.5*velocities[0][k]*velocities[0][k];
+     614             :     }
+     615             : 
+     616             :     // First step of velocity verlet
+     617        8500 :     for(unsigned k=0; k<dim; ++k) {
+     618        4600 :       velocities[0][k] = velocities[0][k] + 0.5*tstep*forces[0][k];
+     619        4600 :       positions[0][k] = positions[0][k] + tstep*velocities[0][k];
+     620             : 
+     621        4600 :       if(periodic[k]) {
+     622         400 :         positions[0][k] = positions[0][k] - floor((positions[0][k]-interval_min[k])/interval_range[k])*interval_range[k];
+     623             :       }
+     624             :       else {
+     625        4200 :         if(positions[0][k]>interval_max[k]) {
+     626           7 :           positions[0][k]=interval_max[k];
+     627           7 :           velocities[0][k]=-std::abs(velocities[0][k]);
+     628             :         }
+     629        4200 :         if(positions[0][k]<interval_min[k]) {
+     630           2 :           positions[0][k]=interval_min[k];
+     631           2 :           velocities[0][k]=-std::abs(velocities[0][k]);
+     632             :         }
+     633             :       }
+     634             :     }
+     635             : 
+     636        3900 :     potential=calc_energy(positions,forces);
+     637             : 
+     638        3900 :     if(plumed) {
+     639        3900 :       long long unsigned int istepplusone=istep+1;
+     640        3900 :       plumedWantsToStop=0;
+     641        3900 :       plumed->cmd("setStepLongLong",&istepplusone);
+     642        3900 :       plumed->cmd("setMasses",&masses[0]);
+     643        3900 :       plumed->cmd("setForces",&forces[0][0]);
+     644        3900 :       plumed->cmd("setEnergy",&potential);
+     645        3900 :       plumed->cmd("setPositions",&positions[0][0]);
+     646        3900 :       plumed->cmd("setStopFlag",&plumedWantsToStop);
+     647        3900 :       plumed->cmd("calc");
+     648             :       //if(istep%2000==0) plumed->cmd("writeCheckPointFile");
+     649        3900 :       if(plumedWantsToStop) nsteps=istep;
+     650             :     }
+     651             : 
+     652             :     // Second step of velocity verlet
+     653        8500 :     for(unsigned k=0; k<dim; ++k) {
+     654        4600 :       velocities[0][k] = velocities[0][k] + 0.5*tstep*forces[0][k];
+     655             :     }
+     656             : 
+     657             :     // Langevin thermostat
+     658        3900 :     lscale=exp(-0.5*tstep*friction); //exp(-0.5*tstep/friction);
+     659        3900 :     lrand=sqrt((1.-lscale*lscale)*temp);
+     660        8500 :     for(unsigned k=0; k<dim; ++k) {
+     661        4600 :       therm_eng=therm_eng+0.5*velocities[0][k]*velocities[0][k];
+     662        4600 :       velocities[0][k]=lscale*velocities[0][k]+lrand*random.Gaussian();
+     663        4600 :       therm_eng=therm_eng-0.5*velocities[0][k]*velocities[0][k];
+     664             :     }
+     665             : 
+     666             :     // Print everything
+     667        3900 :     ttt = calc_temp( velocities );
+     668        3900 :     conserved = potential+1.5*ttt+therm_eng;
+     669        3900 :     if( (intra.Get_rank()==0) && ((istep % stepWrite)==0) ) {
+     670          38 :       std::fprintf(fp,"%llu %f %f %f %f %f %f %f %f \n", istep, istep*tstep, positions[0][0], positions[0][1], positions[0][2], conserved, ttt, potential, therm_eng );
+     671             :     }
+     672             :   }
+     673             : 
+     674             :   //printf("Rank: %d, Size: %d \n", pc.Get_rank(), pc.Get_size() );
+     675             :   //printf("Rank: %d, Size: %d, MultiSimCommRank: %d, MultiSimCommSize: %d \n", pc.Get_rank(), pc.Get_size(), multi_sim_comm.Get_rank(), multi_sim_comm.Get_size() );
+     676             : 
+     677             :   return 0;
+     678         395 : }
+     679             : 
+     680             : }
+     681             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Adam.cpp.func-sort-c.html b/coverage/ves/Opt_Adam.cpp.func-sort-c.html new file mode 100644 index 000000000000..2744551fe37c --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Adam.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Adam.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677293.1 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8Opt_AdamC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves8Opt_AdamC1ERKNS_13ActionOptionsE2
_ZN4PLMD3ves8Opt_Adam16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves8Opt_Adam12coeffsUpdateEj20
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Adam.cpp.func.html b/coverage/ves/Opt_Adam.cpp.func.html new file mode 100644 index 000000000000..25b63417ea6c --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Adam.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Adam.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677293.1 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8Opt_Adam12coeffsUpdateEj20
_ZN4PLMD3ves8Opt_Adam16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves8Opt_AdamC1ERKNS_13ActionOptionsE2
_ZN4PLMD3ves8Opt_AdamC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Adam.cpp.gcov.html b/coverage/ves/Opt_Adam.cpp.gcov.html new file mode 100644 index 000000000000..058b9a720d0f --- /dev/null +++ b/coverage/ves/Opt_Adam.cpp.gcov.html @@ -0,0 +1,273 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Adam.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Adam.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:677293.1 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Optimizer.h"
+      24             : #include "CoeffsVector.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/ActionSet.h"
+      28             : 
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace ves {
+      32             : 
+      33             : //+PLUMEDOC VES_OPTIMIZER OPT_ADAM
+      34             : /*
+      35             : Adaptive moment estimation (ADAM) optimizer.
+      36             : 
+      37             : \attention
+      38             : __This optimizer is still experimental and not fully documented. The syntax might change. Restarting does not work. We recommend to use the averaged stochastic gradient decent optimizer (\ref OPT_AVERAGED_SGD) for now__.
+      39             : 
+      40             : 
+      41             : \par Examples
+      42             : 
+      43             : */
+      44             : //+ENDPLUMEDOC
+      45             : 
+      46             : class Opt_Adam: public Optimizer {
+      47             : private:
+      48             :   unsigned int time_;
+      49             :   double beta_1_;
+      50             :   double beta_2_;
+      51             :   double epsilon_;
+      52             :   double one_minus_weight_decay_;
+      53             :   bool amsgrad_;
+      54             :   bool adamw_;
+      55             :   // 1st gradient moment uses the "AuxCoeffs", so only 2nd moment needs new CoeffVectors
+      56             :   std::vector<std::unique_ptr<CoeffsVector>> var_coeffs_pntrs_;
+      57             :   // used only for AMSGrad variant
+      58             :   std::vector<std::unique_ptr<CoeffsVector>> varmax_coeffs_pntrs_;
+      59             : protected:
+      60             :   CoeffsVector& VarCoeffs(const unsigned int coeffs_id = 0) const;
+      61             :   CoeffsVector& VarmaxCoeffs(const unsigned int coeffs_id = 0) const;
+      62             : public:
+      63             :   static void registerKeywords(Keywords&);
+      64             :   explicit Opt_Adam(const ActionOptions&);
+      65             :   void coeffsUpdate(const unsigned int c_id = 0) override;
+      66             : };
+      67             : 
+      68             : inline
+      69             : CoeffsVector& Opt_Adam::VarCoeffs(const unsigned int coeffs_id) const {return *var_coeffs_pntrs_[coeffs_id];}
+      70             : 
+      71             : inline
+      72             : CoeffsVector& Opt_Adam::VarmaxCoeffs(const unsigned int coeffs_id) const {return *varmax_coeffs_pntrs_[coeffs_id];}
+      73             : 
+      74             : 
+      75             : PLUMED_REGISTER_ACTION(Opt_Adam,"OPT_ADAM")
+      76             : 
+      77             : 
+      78           4 : void Opt_Adam::registerKeywords(Keywords& keys) {
+      79           4 :   Optimizer::registerKeywords(keys);
+      80           4 :   Optimizer::useFixedStepSizeKeywords(keys);
+      81           4 :   Optimizer::useMultipleWalkersKeywords(keys);
+      82           4 :   Optimizer::useMaskKeywords(keys);
+      83           4 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+      84           8 :   keys.add("optional","BETA_1","Parameter for the first moment estimate. Defaults to 0.9");
+      85           8 :   keys.add("optional","BETA_2","Parameter for the second moment estimate. Defaults to 0.999");
+      86           8 :   keys.add("optional","EPSILON","Small parameter to avoid division by zero. Defaults to 1e-8");
+      87           8 :   keys.add("optional","ADAMW_WEIGHT_DECAY","Weight decay parameter for the AdamW variant. Defaults to 0");
+      88           8 :   keys.addFlag("AMSGRAD", false, "Use the AMSGrad variant");
+      89           4 : }
+      90             : 
+      91             : 
+      92           2 : Opt_Adam::Opt_Adam(const ActionOptions&ao):
+      93             :   PLUMED_VES_OPTIMIZER_INIT(ao),
+      94           2 :   time_(0),
+      95           2 :   beta_1_(0.9),
+      96           2 :   beta_2_(0.999),
+      97           2 :   epsilon_(0.00000001),
+      98           2 :   one_minus_weight_decay_(1.0),
+      99           2 :   amsgrad_(false),
+     100           2 :   adamw_(false),
+     101           2 :   var_coeffs_pntrs_(0)
+     102             : {
+     103             :   // add citation and print it to log
+     104           2 :   log << "  Adam type stochastic gradient decent\n";
+     105           2 :   parseFlag("AMSGRAD",amsgrad_);
+     106           2 :   if (amsgrad_) {
+     107           1 :     log << "  Using the AMSGrad variant of the Adam algorithm, see and cite\n";
+     108             :   }
+     109             : 
+     110           2 :   double tmp_weight_decay = 0.0;
+     111           2 :   parse("ADAMW_WEIGHT_DECAY",tmp_weight_decay);
+     112           2 :   if (tmp_weight_decay != 0.0) {
+     113           0 :     adamw_ = true;
+     114           0 :     log << "  Using the AdamW variant (Adam with weight decay), see and cite\n";
+     115           0 :     one_minus_weight_decay_ = 1 - tmp_weight_decay;
+     116           0 :     log << "    weight decay parameter: " << tmp_weight_decay << "\n";
+     117             :   }
+     118             : 
+     119           2 :   log << "  Adam parameters:\n";
+     120           2 :   parse("BETA_1",beta_1_);
+     121           2 :   plumed_massert(beta_1_ > 0 && beta_1_ <= 1, "BETA_1 must be between 0 and 1");
+     122           2 :   log << "    beta_1: " << beta_1_ << "\n";
+     123             : 
+     124           2 :   parse("BETA_2",beta_2_);
+     125           2 :   plumed_massert(beta_2_ > 0 && beta_2_ <= 1, "BETA_2 must be between 0 and 1");
+     126           2 :   log << "    beta_2: " << beta_2_ << "\n";
+     127             : 
+     128           2 :   parse("EPSILON",epsilon_);
+     129           2 :   plumed_massert(epsilon_ > 0 && epsilon_ <= 1, "EPSILON must be between 0 and 1");
+     130           2 :   log << "    epsilon: " << epsilon_ << "\n";
+     131             : 
+     132             : 
+     133             :   // set up the coeff vector for the 2nd moment of the gradient (variance)
+     134           4 :   for (unsigned i = 0; i < numberOfCoeffsSets(); ++i) {
+     135           2 :     var_coeffs_pntrs_.emplace_back(std::unique_ptr<CoeffsVector>(new CoeffsVector(Coeffs(i))));
+     136           4 :     VarCoeffs(i).replaceLabelString("coeffs","grad_var");
+     137           2 :     VarCoeffs(i).setAllValuesToZero(); // can Coeffs(i) even be non-zero at this point?
+     138             : 
+     139             :     // add second set of coefficients to store the maximum values of the 2nd moment
+     140           2 :     if (amsgrad_) {
+     141           1 :       varmax_coeffs_pntrs_.emplace_back(std::unique_ptr<CoeffsVector>(new CoeffsVector(VarCoeffs(i))));
+     142           2 :       VarmaxCoeffs(i).replaceLabelString("coeffs","grad_varmax");
+     143             :     }
+     144             : 
+     145             :     // also rename the Coeffs used for the mean of the gradient
+     146           4 :     AuxCoeffs(i).replaceLabelString("coeffs","grad_mean");
+     147             :   }
+     148             : 
+     149           2 :   checkRead();
+     150           2 : }
+     151             : 
+     152             : 
+     153          20 : void Opt_Adam::coeffsUpdate(const unsigned int c_id) {
+     154          20 :   time_++;
+     155             :   // AuxCoeffs is used for first moment (mean)
+     156          20 :   AuxCoeffs(c_id) *= beta_1_;
+     157          20 :   AuxCoeffs(c_id) += (1 - beta_1_ ) * Gradient(c_id) * CoeffsMask(c_id);
+     158          20 :   VarCoeffs(c_id) *= beta_2_;
+     159          20 :   VarCoeffs(c_id) += (1 - beta_2_ ) * Gradient(c_id) * Gradient(c_id) * CoeffsMask(c_id);
+     160             : 
+     161          20 :   if (amsgrad_) {
+     162         120 :     for (size_t i = 0; i< VarCoeffs(c_id).getSize(); ++i) {
+     163         110 :       if (VarCoeffs(c_id).getValue(i) > VarmaxCoeffs(c_id).getValue(i)) {
+     164          95 :         VarmaxCoeffs(c_id)[i] = VarCoeffs(c_id).getValue(i);
+     165             :       }
+     166             :     }
+     167             :   }
+     168             : 
+     169             :   // store sqrt of VarCoeffs in vector, easier than writing a CoeffsVector::sqrt() function
+     170             :   // also directly add epsilon and invert to multiply with the Coeffs in last step
+     171             :   std::vector<double> var_coeffs_sqrt;
+     172          20 :   if (!amsgrad_) {
+     173         120 :     for (size_t i = 0; i< VarCoeffs(c_id).getSize(); ++i) {
+     174         110 :       var_coeffs_sqrt.push_back(1 / (sqrt(VarCoeffs(c_id).getValue(i)) + epsilon));
+     175             :     }
+     176             :   }
+     177             :   else { // use VarmaxCoffs instead of VarCoeffs
+     178         120 :     for (size_t i = 0; i< VarmaxCoeffs(c_id).getSize(); ++i) {
+     179         110 :       var_coeffs_sqrt.push_back(1 / (sqrt(VarmaxCoeffs(c_id).getValue(i)) + epsilon));
+     180             :     }
+     181             :   }
+     182             : 
+     183             :   // bias correction
+     184          20 :   double scalefactor = StepSize(c_id) * sqrt(1 - pow(beta_2_, time_)) / (1 - pow(beta_1_, time_));
+     185             : 
+     186          20 :   if (adamw_) { // check is not necessary but probably faster than always multiplying by 1
+     187           0 :     Coeffs(c_id) *= one_minus_weight_decay_ * CoeffsMask(c_id);
+     188             :   }
+     189             : 
+     190             :   // coeff update
+     191          20 :   Coeffs(c_id) -= scalefactor * AuxCoeffs(c_id) * var_coeffs_sqrt * CoeffsMask(c_id);
+     192          20 : }
+     193             : 
+     194             : 
+     195             : }
+     196             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html b/coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html new file mode 100644 index 000000000000..cecc4f09e1c3 --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_BachAveragedSGD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_BachAveragedSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596295.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves19Opt_BachAveragedSGDC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves19Opt_BachAveragedSGDC1ERKNS_13ActionOptionsE75
_ZN4PLMD3ves19Opt_BachAveragedSGD16registerKeywordsERNS_8KeywordsE77
_ZN4PLMD3ves19Opt_BachAveragedSGD12coeffsUpdateEj22675
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_BachAveragedSGD.cpp.func.html b/coverage/ves/Opt_BachAveragedSGD.cpp.func.html new file mode 100644 index 000000000000..d4969bd819a9 --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_BachAveragedSGD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_BachAveragedSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596295.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves19Opt_BachAveragedSGD12coeffsUpdateEj22675
_ZN4PLMD3ves19Opt_BachAveragedSGD16registerKeywordsERNS_8KeywordsE77
_ZN4PLMD3ves19Opt_BachAveragedSGDC1ERKNS_13ActionOptionsE75
_ZN4PLMD3ves19Opt_BachAveragedSGDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html b/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html new file mode 100644 index 000000000000..c9033c590423 --- /dev/null +++ b/coverage/ves/Opt_BachAveragedSGD.cpp.gcov.html @@ -0,0 +1,379 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_BachAveragedSGD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_BachAveragedSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:596295.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Optimizer.h"
+      24             : #include "CoeffsVector.h"
+      25             : #include "CoeffsMatrix.h"
+      26             : 
+      27             : #include "core/ActionRegister.h"
+      28             : #include "core/PlumedMain.h"
+      29             : 
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : //+PLUMEDOC VES_OPTIMIZER OPT_AVERAGED_SGD
+      36             : /*
+      37             : Averaged stochastic gradient decent with fixed step size.
+      38             : 
+      39             : \par Algorithm
+      40             : 
+      41             : This optimizer updates the coefficients according to the averaged stochastic gradient decent algorithm described in ref \cite Bach-NIPS-2013. This algorithm considers two sets of coefficients, the so-called instantaneous coefficients that are updated according to the recursion formula given by
+      42             : \f[
+      43             : \boldsymbol{\alpha}^{(n+1)} = \boldsymbol{\alpha}^{(n)} -
+      44             : \mu \left[
+      45             : \nabla \Omega(\bar{\boldsymbol{\alpha}}^{(n)}) +
+      46             : \mathbf{H}(\bar{\boldsymbol{\alpha}}^{(n)})
+      47             : [\boldsymbol{\alpha}^{(n)}-\bar{\boldsymbol{\alpha}}^{(n)}]
+      48             : \right],
+      49             : \f]
+      50             : where \f$\mu\f$ is a fixed step size and the gradient \f$ \nabla\Omega(\bar{\boldsymbol{\alpha}}^{(n)})\f$ and the Hessian \f$\mathbf{H}(\bar{\boldsymbol{\alpha}}^{(n)})\f$ depend on the averaged coefficients defined as
+      51             : \f[
+      52             : \bar{\boldsymbol{\alpha}}^{(n)} = \frac{1}{n+1} \sum_{k=0}^{n} \boldsymbol{\alpha}^{(k)}.
+      53             : \f]
+      54             : This means that the bias acting on the system depends on the averaged coefficients \f$\bar{\boldsymbol{\alpha}}^{(n)}\f$ which leads to a smooth convergence of the bias and the estimated free energy surface. Furthermore, this allows for a rather short sampling time for each iteration, for classical MD simulations typical sampling times are on the order of few ps (around 1000-4000 MD steps).
+      55             : 
+      56             : Currently it is only supported to employ the diagonal part of the Hessian which is generally sufficient. Support for employing the full Hessian will be added later on.
+      57             : 
+      58             : The VES bias that is to be optimized should be specified using the
+      59             : BIAS keyword.
+      60             : The fixed step size \f$\mu\f$ is given using the STEPSIZE keyword.
+      61             : The frequency of updating the coefficients is given using the
+      62             : STRIDE keyword where the value is given in the number of MD steps.
+      63             : For example, if the MD time step is 0.02 ps and STRIDE=2000 will the
+      64             : coefficients be updated every 4 ps.
+      65             : The coefficients will be outputted to the file given by the
+      66             : COEFFS_FILE keyword. How often the coefficients are written
+      67             : to this file is controlled by the COEFFS_OUTPUT keyword.
+      68             : 
+      69             : If the VES bias employs a dynamic target distribution that needs to be
+      70             : iteratively updated (e.g. \ref TD_WELLTEMPERED) \cite Valsson-JCTC-2015, you will need to specify
+      71             : the stride for updating the target distribution by using
+      72             : the TARGETDIST_STRIDE keyword where the stride
+      73             : is given in terms coefficient iterations. For example if the
+      74             : MD time step is 0.02 ps and STRIDE=1000, such that the coefficients
+      75             : are updated every 2 ps, will TARGETDIST_STRIDE=500 mean that the
+      76             : target distribution will be updated every 1000 ps.
+      77             : 
+      78             : The output of the free energy surfaces and biases is controlled by the FES_OUTPUT and the BIAS_OUTPUT
+      79             : keywords. It is also possible to output one-dimensional projections of the free energy surfaces
+      80             : by using the FES_PROJ_OUTPUT keyword but for that to work you will need to select
+      81             : for which argument to do the projections by using the numbered PROJ_ARG keyword in
+      82             : the VES bias that is optimized.
+      83             : You can also output dynamic target distributions by using the
+      84             : TARGETDIST_OUTPUT and TARGETDIST_PROJ_OUTPUT keywords.
+      85             : 
+      86             : It is possible to start the optimization from some initial set of
+      87             : coefficients that have been previously obtained by using the INITIAL_COEFFS
+      88             : keyword.
+      89             : 
+      90             : When restarting simulations it should be sufficient to put the \ref RESTART action
+      91             : in the beginning of the input files (or some MD codes the PLUMED should automatically
+      92             : detect if it is a restart run) and keep the same input as before The restarting of
+      93             : the optimization should be automatic as the optimizer will then read in the
+      94             : coefficients from the file given in COEFFS_FILE. For dynamic target
+      95             : distribution the code will also read in the final target distribution from the
+      96             : previous run (which is always outputted even if the TARGETDIST_OUTPUT keyword
+      97             : is not used).
+      98             : 
+      99             : This optimizer supports the usage of multiple walkers where different copies of the system share the same bias potential (i.e. coefficients) and cooperatively sample the averages needed for the gradient and Hessian. This can significantly help with convergence in difficult cases. It is of course best to start the different copies from different positions in CV space. To activate this option you just need to add the MULTIPLE_WALKERS flag. Note that this is only supported if the MD code support running multiple replicas connected via MPI.
+     100             : 
+     101             : The optimizer supports the usage of a so-called mask file that can be used to employ different step sizes for different coefficients and/or deactivate the optimization of certain coefficients (by putting values of 0.0). The mask file is read in by using the MASK_FILE keyword and should be in the same format as the coefficient file. It is possible to generate a template mask file by using the OUTPUT_MASK_FILE keyword.
+     102             : 
+     103             : \par Examples
+     104             : 
+     105             : In the following input we employ an averaged stochastic gradient decent with a
+     106             : fixed step size of 1.0 and update the coefficient every 1000 MD steps
+     107             : (e.g. every 2 ps if the MD time step is 0.02 ps). The coefficient are outputted
+     108             : to the coefficients.data every 50 iterations while the FES and bias is outputted
+     109             : to files every 500 iterations (e.g. every 1000 ps).
+     110             : \plumedfile
+     111             : phi:   TORSION ATOMS=5,7,9,15
+     112             : 
+     113             : bf1: BF_FOURIER ORDER=5 MINIMUM=-pi MAXIMUM=pi
+     114             : 
+     115             : VES_LINEAR_EXPANSION ...
+     116             :  ARG=phi
+     117             :  BASIS_FUNCTIONS=bf1
+     118             :  LABEL=ves1
+     119             :  TEMP=300.0
+     120             :  GRID_BINS=100
+     121             : ... VES_LINEAR_EXPANSION
+     122             : 
+     123             : OPT_AVERAGED_SGD ...
+     124             :   BIAS=ves1
+     125             :   STRIDE=1000
+     126             :   LABEL=o1
+     127             :   STEPSIZE=1.0
+     128             :   COEFFS_FILE=coefficients.data
+     129             :   COEFFS_OUTPUT=50
+     130             :   FES_OUTPUT=500
+     131             :   BIAS_OUTPUT=500
+     132             : ... OPT_AVERAGED_SGD
+     133             : \endplumedfile
+     134             : 
+     135             : 
+     136             : In the following example we employ a well-tempered target distribution that
+     137             : is updated every 500 iterations (e.g. every 1000 ps). The target distribution is
+     138             : also output to a file every 2000 iterations (the TARGETDIST_OUTPUT keyword).
+     139             : Here we also employ MULTIPLE_WALKERS flag to enable the usage of
+     140             : multiple walkers.
+     141             : \plumedfile
+     142             : #SETTINGS NREPLICAS=2
+     143             : phi:   TORSION ATOMS=5,7,9,15
+     144             : psi:   TORSION ATOMS=7,9,15,17
+     145             : 
+     146             : bf1: BF_FOURIER ORDER=5 MINIMUM=-pi MAXIMUM=pi
+     147             : bf2: BF_FOURIER ORDER=4 MINIMUM=-pi MAXIMUM=pi
+     148             : 
+     149             : td1: TD_WELLTEMPERED BIASFACTOR=10
+     150             : 
+     151             : VES_LINEAR_EXPANSION ...
+     152             :  ARG=phi,psi
+     153             :  BASIS_FUNCTIONS=bf1,bf2
+     154             :  LABEL=ves1
+     155             :  TEMP=300.0
+     156             :  GRID_BINS=100,100
+     157             :  TARGET_DISTRIBUTION=td1
+     158             :  PROJ_ARG1=phi
+     159             :  PROJ_ARG2=psi
+     160             : ... VES_LINEAR_EXPANSION
+     161             : 
+     162             : OPT_AVERAGED_SGD ...
+     163             :   BIAS=ves1
+     164             :   STRIDE=1000
+     165             :   LABEL=o1
+     166             :   STEPSIZE=1.0
+     167             :   MULTIPLE_WALKERS
+     168             :   COEFFS_FILE=coefficients.data
+     169             :   COEFFS_OUTPUT=50
+     170             :   FES_OUTPUT=500
+     171             :   FES_PROJ_OUTPUT=500
+     172             :   BIAS_OUTPUT=500
+     173             :   TARGETDIST_STRIDE=500
+     174             :   TARGETDIST_OUTPUT=2000
+     175             : ... OPT_AVERAGED_SGD
+     176             : \endplumedfile
+     177             : 
+     178             : 
+     179             : 
+     180             : */
+     181             : //+ENDPLUMEDOC
+     182             : 
+     183             : class Opt_BachAveragedSGD : public Optimizer {
+     184             : private:
+     185             :   std::vector<std::unique_ptr<CoeffsVector>> combinedgradient_pntrs_;
+     186             :   unsigned int combinedgradient_wstride_;
+     187             :   std::vector<std::unique_ptr<OFile>> combinedgradientOFiles_;
+     188             :   double decaying_aver_tau_;
+     189             : private:
+     190          60 :   CoeffsVector& CombinedGradient(const unsigned int c_id) const {return *combinedgradient_pntrs_[c_id];}
+     191             :   double getAverDecay() const;
+     192             : public:
+     193             :   static void registerKeywords(Keywords&);
+     194             :   explicit Opt_BachAveragedSGD(const ActionOptions&);
+     195             :   void coeffsUpdate(const unsigned int c_id = 0) override;
+     196             : };
+     197             : 
+     198             : 
+     199             : PLUMED_REGISTER_ACTION(Opt_BachAveragedSGD,"OPT_AVERAGED_SGD")
+     200             : 
+     201             : 
+     202          77 : void Opt_BachAveragedSGD::registerKeywords(Keywords& keys) {
+     203          77 :   Optimizer::registerKeywords(keys);
+     204          77 :   Optimizer::useFixedStepSizeKeywords(keys);
+     205          77 :   Optimizer::useMultipleWalkersKeywords(keys);
+     206          77 :   Optimizer::useHessianKeywords(keys);
+     207          77 :   Optimizer::useMaskKeywords(keys);
+     208          77 :   Optimizer::useRestartKeywords(keys);
+     209          77 :   Optimizer::useMonitorAverageGradientKeywords(keys);
+     210          77 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+     211         154 :   keys.add("hidden","COMBINED_GRADIENT_FILE","the name of output file for the combined gradient (gradient + Hessian term)");
+     212         154 :   keys.add("hidden","COMBINED_GRADIENT_OUTPUT","how often the combined gradient should be written to file. This parameter is given as the number of bias iterations. It is by default 100 if COMBINED_GRADIENT_FILE is specficed");
+     213         154 :   keys.add("hidden","COMBINED_GRADIENT_FMT","specify format for combined gradient file(s) (useful for decrease the number of digits in regtests)");
+     214         154 :   keys.add("optional","EXP_DECAYING_AVER","calculate the averaged coefficients using exponentially decaying averaging using the decaying constant given here in the number of iterations");
+     215          77 : }
+     216             : 
+     217             : 
+     218             : 
+     219          75 : Opt_BachAveragedSGD::Opt_BachAveragedSGD(const ActionOptions&ao):
+     220             :   PLUMED_VES_OPTIMIZER_INIT(ao),
+     221          75 :   combinedgradient_wstride_(100),
+     222          75 :   decaying_aver_tau_(0.0)
+     223             : {
+     224          75 :   log.printf("  Averaged stochastic gradient decent, see and cite ");
+     225         150 :   log << plumed.cite("Bach and Moulines, NIPS 26, 773-781 (2013)");
+     226          75 :   log.printf("\n");
+     227          75 :   unsigned int decaying_aver_tau_int=0;
+     228          75 :   parse("EXP_DECAYING_AVER",decaying_aver_tau_int);
+     229          75 :   if(decaying_aver_tau_int>0) {
+     230           2 :     decaying_aver_tau_ = static_cast<double>(decaying_aver_tau_int);
+     231           2 :     log.printf("  Coefficients calculated using an exponentially decaying average with a decaying constant of %u iterations, see and cite ",decaying_aver_tau_int);
+     232           4 :     log << plumed.cite("Invernizzi, Valsson, and Parrinello, Proc. Natl. Acad. Sci. USA 114, 3370-3374 (2017)");
+     233           2 :     log.printf("\n");
+     234             :   }
+     235             :   //
+     236             :   std::vector<std::string> combinedgradient_fnames;
+     237          75 :   parseFilenames("COMBINED_GRADIENT_FILE",combinedgradient_fnames);
+     238         150 :   parse("COMBINED_GRADIENT_OUTPUT",combinedgradient_wstride_);
+     239          75 :   setupOFiles(combinedgradient_fnames,combinedgradientOFiles_,useMultipleWalkers());
+     240          75 :   std::string combinedgradient_fmt="";
+     241         150 :   parse("COMBINED_GRADIENT_FMT",combinedgradient_fmt);
+     242          75 :   if(combinedgradient_fnames.size()>0) {
+     243          12 :     for(unsigned int i=0; i<numberOfCoeffsSets(); i++) {
+     244          12 :       auto combinedgradient_tmp = Tools::make_unique<CoeffsVector>(*getGradientPntrs()[i]);
+     245           6 :       std::string label = getGradientPntrs()[i]->getLabel();
+     246           6 :       if(label.find("gradient")!=std::string::npos) {
+     247          12 :         label.replace(label.find("gradient"), std::string("gradient").length(), "combined_gradient");
+     248             :       }
+     249             :       else {
+     250             :         label += "_combined";
+     251             :       }
+     252           6 :       combinedgradient_tmp->setLabels(label);
+     253           6 :       if(combinedgradient_fmt.size()>0) {
+     254             :         combinedgradient_tmp->setOutputFmt(combinedgradient_fmt);
+     255             :       }
+     256           6 :       combinedgradient_pntrs_.emplace_back(std::move(combinedgradient_tmp));
+     257           6 :     }
+     258             :     //
+     259           6 :     if(numberOfCoeffsSets()==1) {
+     260          12 :       log.printf("  Combined gradient (gradient + Hessian term) will be written out to file %s every %u iterations\n",combinedgradientOFiles_[0]->getPath().c_str(),combinedgradient_wstride_);
+     261             :     }
+     262             :     else {
+     263           0 :       log.printf("  Combined gradient (gradient + Hessian term) will be written out to the following files every %u iterations:\n",combinedgradient_wstride_);
+     264           0 :       for(unsigned int i=0; i<combinedgradientOFiles_.size(); i++) {
+     265           0 :         log.printf("   coefficient set %u: %s\n",i,combinedgradientOFiles_[i]->getPath().c_str());
+     266             :       }
+     267             :     }
+     268             :   }
+     269             :   //
+     270             : 
+     271          75 :   turnOnHessian();
+     272          75 :   checkRead();
+     273          75 : }
+     274             : 
+     275             : 
+     276       22675 : void Opt_BachAveragedSGD::coeffsUpdate(const unsigned int c_id) {
+     277             :   //
+     278       22675 :   if(combinedgradientOFiles_.size()>0 && (getIterationCounter()+1)%combinedgradient_wstride_==0) {
+     279          60 :     CombinedGradient(c_id).setValues( ( Gradient(c_id) + Hessian(c_id)*(AuxCoeffs(c_id)-Coeffs(c_id)) ) );
+     280          60 :     combinedgradient_pntrs_[c_id]->setIterationCounterAndTime(getIterationCounter()+1,getTime());
+     281          60 :     combinedgradient_pntrs_[c_id]->writeToFile(*combinedgradientOFiles_[c_id]);
+     282             :   }
+     283             :   //
+     284             :   double aver_decay = getAverDecay();
+     285       22675 :   AuxCoeffs(c_id) += - StepSize(c_id)*CoeffsMask(c_id) * ( Gradient(c_id) + Hessian(c_id)*(AuxCoeffs(c_id)-Coeffs(c_id)) );
+     286             :   //AuxCoeffs() = AuxCoeffs() - StepSize() * ( Gradient() + Hessian()*(AuxCoeffs()-Coeffs()) );
+     287       22675 :   Coeffs(c_id) += aver_decay * ( AuxCoeffs(c_id)-Coeffs(c_id) );
+     288       22675 : }
+     289             : 
+     290             : 
+     291             : inline
+     292             : double Opt_BachAveragedSGD::getAverDecay() const {
+     293       22675 :   double aver_decay = 1.0 / ( getIterationCounterDbl() + 1.0 );
+     294       22675 :   if(decaying_aver_tau_ > 0.0 && (getIterationCounterDbl() + 1.0) > decaying_aver_tau_) {
+     295          14 :     aver_decay = 1.0 / decaying_aver_tau_;
+     296             :   }
+     297             :   return aver_decay;
+     298             : }
+     299             : 
+     300             : 
+     301             : }
+     302             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Dummy.cpp.func-sort-c.html b/coverage/ves/Opt_Dummy.cpp.func-sort-c.html new file mode 100644 index 000000000000..3d93d7383661 --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Dummy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Dummy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202195.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Opt_DummyC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9Opt_DummyC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves9Opt_Dummy16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves9Opt_Dummy12coeffsUpdateEj10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Dummy.cpp.func.html b/coverage/ves/Opt_Dummy.cpp.func.html new file mode 100644 index 000000000000..0610db15dabb --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Dummy.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Dummy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202195.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Opt_Dummy12coeffsUpdateEj10
_ZN4PLMD3ves9Opt_Dummy16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves9Opt_DummyC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves9Opt_DummyC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_Dummy.cpp.gcov.html b/coverage/ves/Opt_Dummy.cpp.gcov.html new file mode 100644 index 000000000000..844768ea0b2b --- /dev/null +++ b/coverage/ves/Opt_Dummy.cpp.gcov.html @@ -0,0 +1,198 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_Dummy.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_Dummy.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202195.2 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Optimizer.h"
+      24             : #include "CoeffsVector.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace ves {
+      31             : 
+      32             : //+PLUMEDOC VES_OPTIMIZER OPT_DUMMY
+      33             : /*
+      34             : Dummy optimizer for debugging.
+      35             : 
+      36             : This is dummy optimizer that can be used for debugging. It will not update the
+      37             : coefficients but can be used to monitor the gradient and Hessian for a given
+      38             : VES bias.
+      39             : 
+      40             : \par Examples
+      41             : 
+      42             : In the following input we use the OPT_DUMMY to monitor the gradient and
+      43             : Hessian for a given VES bias every 1 iteration.
+      44             : \plumedfile
+      45             : phi:   TORSION ATOMS=5,7,9,15
+      46             : 
+      47             : bf1: BF_FOURIER ORDER=5 MINIMUM=-pi MAXIMUM=pi
+      48             : 
+      49             : VES_LINEAR_EXPANSION ...
+      50             :  ARG=phi
+      51             :  BASIS_FUNCTIONS=bf1
+      52             :  LABEL=ves1
+      53             :  TEMP=300.0
+      54             :  GRID_BINS=100
+      55             : ... VES_LINEAR_EXPANSION
+      56             : 
+      57             : OPT_DUMMY ...
+      58             :   BIAS=ves1
+      59             :   STRIDE=1000
+      60             :   LABEL=o1
+      61             :   MONITOR_HESSIAN
+      62             :   GRADIENT_FILE=gradient.data
+      63             :   GRADIENT_OUTPUT=1
+      64             :   GRADIENT_FMT=%12.6f
+      65             :   HESSIAN_FILE=hessian.data
+      66             :   HESSIAN_OUTPUT=1
+      67             :   HESSIAN_FMT=%12.6f
+      68             : ... OPT_DUMMY
+      69             : \endplumedfile
+      70             : 
+      71             : */
+      72             : //+ENDPLUMEDOC
+      73             : 
+      74             : 
+      75             : 
+      76             : class Opt_Dummy : public Optimizer {
+      77             : 
+      78             : public:
+      79             :   static void registerKeywords(Keywords&);
+      80             :   explicit Opt_Dummy(const ActionOptions&);
+      81             :   void coeffsUpdate(const unsigned int c_id = 0) override;
+      82             : };
+      83             : 
+      84             : 
+      85             : PLUMED_REGISTER_ACTION(Opt_Dummy,"OPT_DUMMY")
+      86             : 
+      87             : 
+      88           3 : void Opt_Dummy::registerKeywords(Keywords& keys) {
+      89           3 :   Optimizer::registerKeywords(keys);
+      90             :   //
+      91           3 :   Optimizer::useMultipleWalkersKeywords(keys);
+      92           3 :   Optimizer::useHessianKeywords(keys);
+      93           3 :   Optimizer::useMonitorAverageGradientKeywords(keys);
+      94           6 :   keys.addFlag("MONITOR_HESSIAN",false,"also monitor the Hessian");
+      95           3 : }
+      96             : 
+      97             : 
+      98           1 : Opt_Dummy::Opt_Dummy(const ActionOptions&ao):
+      99           1 :   PLUMED_VES_OPTIMIZER_INIT(ao)
+     100             : {
+     101           1 :   log.printf("  fake optimizer that does not update coefficients\n");
+     102           1 :   log.printf("  can be used to monitor gradient and Hessian for debugging purposes\n");
+     103           1 :   bool monitor_hessian = false;
+     104           1 :   parseFlag("MONITOR_HESSIAN",monitor_hessian);
+     105           1 :   if(monitor_hessian) {
+     106           1 :     turnOnHessian();
+     107           1 :     log.printf("  the Hessian will also be monitored\n");
+     108             :   }
+     109             :   else {
+     110           0 :     turnOffHessian();
+     111             :   }
+     112           1 :   turnOffCoeffsOutputFiles();
+     113           1 :   checkRead();
+     114           1 : }
+     115             : 
+     116             : 
+     117          10 : void Opt_Dummy::coeffsUpdate(const unsigned int c_id) {}
+     118             : 
+     119             : 
+     120             : }
+     121             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html new file mode 100644 index 000000000000..18059ec818ba --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_RobbinsMonroSGD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_RobbinsMonroSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves19Opt_RobbinsMonroSGD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves19Opt_RobbinsMonroSGD12coeffsUpdateEj10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html new file mode 100644 index 000000000000..c67ca70af893 --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_RobbinsMonroSGD.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_RobbinsMonroSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves19Opt_RobbinsMonroSGD12coeffsUpdateEj10
_ZN4PLMD3ves19Opt_RobbinsMonroSGD16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC1ERKNS_13ActionOptionsE1
_ZN4PLMD3ves19Opt_RobbinsMonroSGDC2ERKNS_13ActionOptionsE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html b/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html new file mode 100644 index 000000000000..3cf292506372 --- /dev/null +++ b/coverage/ves/Opt_RobbinsMonroSGD.cpp.gcov.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - ves/Opt_RobbinsMonroSGD.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Opt_RobbinsMonroSGD.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:232495.8 %
Date:2024-02-22 21:58:45Functions:3475.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Optimizer.h"
+      24             : #include "CoeffsVector.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : 
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace ves {
+      31             : 
+      32             : //+PLUMEDOC VES_OPTIMIZER OPT_ROBBINS_MONRO_SGD
+      33             : /*
+      34             : Robbins-Monro stochastic gradient decent.
+      35             : 
+      36             : \attention
+      37             : __This optimizer is only included for reference. We recommend to use the averaged stochastic gradient decent optimizer (\ref OPT_AVERAGED_SGD)__.
+      38             : 
+      39             : \par Examples
+      40             : 
+      41             : */
+      42             : //+ENDPLUMEDOC
+      43             : 
+      44             : class Opt_RobbinsMonroSGD : public Optimizer {
+      45             : private:
+      46             :   double decay_constant_;
+      47             : public:
+      48             :   static void registerKeywords(Keywords&);
+      49             :   explicit Opt_RobbinsMonroSGD(const ActionOptions&);
+      50             :   void coeffsUpdate(const unsigned int c_id = 0);
+      51             : };
+      52             : 
+      53             : 
+      54             : PLUMED_REGISTER_ACTION(Opt_RobbinsMonroSGD,"OPT_ROBBINS_MONRO_SGD")
+      55             : 
+      56             : 
+      57           3 : void Opt_RobbinsMonroSGD::registerKeywords(Keywords& keys) {
+      58           3 :   Optimizer::registerKeywords(keys);
+      59           3 :   Optimizer::useDynamicStepSizeKeywords(keys);
+      60           3 :   Optimizer::useMultipleWalkersKeywords(keys);
+      61           3 :   Optimizer::useMaskKeywords(keys);
+      62           3 :   Optimizer::useRestartKeywords(keys);
+      63             :   // Optimizer::useMonitorAveragesKeywords(keys);
+      64           3 :   Optimizer::useDynamicTargetDistributionKeywords(keys);
+      65           6 :   keys.add("optional","DECAY_CONSTANT","the decay constant used for the step size.");
+      66           3 : }
+      67             : 
+      68             : 
+      69           1 : Opt_RobbinsMonroSGD::Opt_RobbinsMonroSGD(const ActionOptions&ao):
+      70             :   PLUMED_VES_OPTIMIZER_INIT(ao),
+      71           1 :   decay_constant_(1.0)
+      72             : {
+      73           1 :   parse("DECAY_CONSTANT",decay_constant_);
+      74           1 :   if(decay_constant_<1.0) {
+      75           0 :     plumed_merror("the value given in DECAY_CONSTANT doesn't make sense, it should be larger than 1.0");
+      76             :   }
+      77           1 :   if(decay_constant_>1.0) {
+      78           1 :     log.printf("  using a decay constant of %f\n",decay_constant_);
+      79             :   }
+      80           1 :   checkRead();
+      81           1 : }
+      82             : 
+      83             : 
+      84          10 : void Opt_RobbinsMonroSGD::coeffsUpdate(const unsigned int c_id) {
+      85             :   // getIterationCounterDbl() gives n-1 as it is updated afterwards.
+      86          10 :   double current_stepsize =  StepSize(c_id) /(1.0 + getIterationCounterDbl()/decay_constant_);
+      87             :   setCurrentStepSize(current_stepsize,c_id);
+      88          10 :   Coeffs(c_id) += - current_stepsize * CoeffsMask(c_id) * Gradient(c_id);
+      89             :   //
+      90          10 :   double aver_decay = 1.0 / ( getIterationCounterDbl() + 1.0 );
+      91          10 :   AuxCoeffs(c_id) += aver_decay * ( Coeffs(c_id)-AuxCoeffs(c_id) );
+      92          10 : }
+      93             : 
+      94             : 
+      95             : }
+      96             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.cpp.func-sort-c.html b/coverage/ves/Optimizer.cpp.func-sort-c.html new file mode 100644 index 000000000000..36293a9ba6d6 --- /dev/null +++ b/coverage/ves/Optimizer.cpp.func-sort-c.html @@ -0,0 +1,201 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68276289.5 %
Date:2024-02-22 21:58:45Functions:273284.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Optimizer14turnOffHessianEv0
_ZN4PLMD3ves9Optimizer25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves9OptimizerC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9OptimizerD0Ev0
_ZN4PLMD3ves9OptimizerD1Ev0
_ZN4PLMD3ves9Optimizer24turnOffCoeffsOutputFilesEv1
_ZN4PLMD3ves9Optimizer26useDynamicStepSizeKeywordsERNS_8KeywordsE3
_ZNK4PLMD3ves9Optimizer30writeTargetDistProjOutputFilesEv4
_ZN4PLMD3ves9Optimizer19readCoeffsFromFilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEb14
_ZNK4PLMD3ves9Optimizer23writeFesProjOutputFilesEv17
_ZNK4PLMD3ves9Optimizer26writeTargetDistOutputFilesEv38
_ZNK4PLMD3ves9Optimizer19writeFesOutputFilesEv75
_ZNK4PLMD3ves9Optimizer20writeBiasOutputFilesEv75
_ZN4PLMD3ves9Optimizer13turnOnHessianEv76
_ZN4PLMD3ves9OptimizerC2ERKNS_13ActionOptionsE79
_ZN4PLMD3ves9OptimizerD2Ev79
_ZN4PLMD3ves9Optimizer18useHessianKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer18useRestartKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer33useMonitorAverageGradientKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer24useFixedStepSizeKeywordsERNS_8KeywordsE81
_ZN4PLMD3ves9Optimizer13enableHessianEPNS0_7VesBiasEb82
_ZN4PLMD3ves9Optimizer15useMaskKeywordsERNS_8KeywordsE84
_ZN4PLMD3ves9Optimizer36useDynamicTargetDistributionKeywordsERNS_8KeywordsE84
_ZN4PLMD3ves9Optimizer26addCoeffsSetIDsToFilenamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS8_85
_ZN4PLMD3ves9Optimizer16registerKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer26useMultipleWalkersKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer32setAllCoeffsSetIterationCountersEv93
_ZNK4PLMD3ves9Optimizer22getIterationCounterStrB5cxx11Ei95
_ZN4PLMD3ves9Optimizer11setupOFilesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS2_ISt10unique_ptrINS_5OFileESt14default_deleteISD_EESaISG_EEb388
_ZN4PLMD3ves9Optimizer22updateOutputComponentsEv22750
_ZN4PLMD3ves9Optimizer16writeOutputFilesEj22810
_ZN4PLMD3ves9Optimizer6updateEv22879
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.cpp.func.html b/coverage/ves/Optimizer.cpp.func.html new file mode 100644 index 000000000000..b3c43f06d7b6 --- /dev/null +++ b/coverage/ves/Optimizer.cpp.func.html @@ -0,0 +1,201 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68276289.5 %
Date:2024-02-22 21:58:45Functions:273284.4 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Optimizer11setupOFilesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS2_ISt10unique_ptrINS_5OFileESt14default_deleteISD_EESaISG_EEb388
_ZN4PLMD3ves9Optimizer13enableHessianEPNS0_7VesBiasEb82
_ZN4PLMD3ves9Optimizer13turnOnHessianEv76
_ZN4PLMD3ves9Optimizer14turnOffHessianEv0
_ZN4PLMD3ves9Optimizer15useMaskKeywordsERNS_8KeywordsE84
_ZN4PLMD3ves9Optimizer16registerKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer16writeOutputFilesEj22810
_ZN4PLMD3ves9Optimizer18useHessianKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer18useRestartKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer19readCoeffsFromFilesERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EEb14
_ZN4PLMD3ves9Optimizer22updateOutputComponentsEv22750
_ZN4PLMD3ves9Optimizer24turnOffCoeffsOutputFilesEv1
_ZN4PLMD3ves9Optimizer24useFixedStepSizeKeywordsERNS_8KeywordsE81
_ZN4PLMD3ves9Optimizer25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves9Optimizer26addCoeffsSetIDsToFilenamesERSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERS8_85
_ZN4PLMD3ves9Optimizer26useDynamicStepSizeKeywordsERNS_8KeywordsE3
_ZN4PLMD3ves9Optimizer26useMultipleWalkersKeywordsERNS_8KeywordsE87
_ZN4PLMD3ves9Optimizer32setAllCoeffsSetIterationCountersEv93
_ZN4PLMD3ves9Optimizer33useMonitorAverageGradientKeywordsERNS_8KeywordsE80
_ZN4PLMD3ves9Optimizer36useDynamicTargetDistributionKeywordsERNS_8KeywordsE84
_ZN4PLMD3ves9Optimizer6updateEv22879
_ZN4PLMD3ves9OptimizerC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9OptimizerC2ERKNS_13ActionOptionsE79
_ZN4PLMD3ves9OptimizerD0Ev0
_ZN4PLMD3ves9OptimizerD1Ev0
_ZN4PLMD3ves9OptimizerD2Ev79
_ZNK4PLMD3ves9Optimizer19writeFesOutputFilesEv75
_ZNK4PLMD3ves9Optimizer20writeBiasOutputFilesEv75
_ZNK4PLMD3ves9Optimizer22getIterationCounterStrB5cxx11Ei95
_ZNK4PLMD3ves9Optimizer23writeFesProjOutputFilesEv17
_ZNK4PLMD3ves9Optimizer26writeTargetDistOutputFilesEv38
_ZNK4PLMD3ves9Optimizer30writeTargetDistProjOutputFilesEv4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.cpp.gcov.html b/coverage/ves/Optimizer.cpp.gcov.html new file mode 100644 index 000000000000..373a3a000112 --- /dev/null +++ b/coverage/ves/Optimizer.cpp.gcov.html @@ -0,0 +1,1338 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:68276289.5 %
Date:2024-02-22 21:58:45Functions:273284.4 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Optimizer.h"
+      24             : #include "CoeffsVector.h"
+      25             : #include "CoeffsMatrix.h"
+      26             : #include "VesBias.h"
+      27             : #include "VesTools.h"
+      28             : 
+      29             : #include "tools/Exception.h"
+      30             : #include "core/PlumedMain.h"
+      31             : #include "core/ActionSet.h"
+      32             : #include "tools/Communicator.h"
+      33             : #include "tools/File.h"
+      34             : #include "tools/FileBase.h"
+      35             : 
+      36             : namespace PLMD {
+      37             : namespace ves {
+      38             : 
+      39          79 : Optimizer::Optimizer(const ActionOptions&ao):
+      40             :   Action(ao),
+      41             :   ActionPilot(ao),
+      42             :   ActionWithValue(ao),
+      43         158 :   description_("Undefined"),
+      44          79 :   type_("Undefined"),
+      45          79 :   stepsizes_(0),
+      46          79 :   current_stepsizes(0),
+      47          79 :   fixed_stepsize_(true),
+      48          79 :   iter_counter(0),
+      49          79 :   use_hessian_(false),
+      50          79 :   diagonal_hessian_(true),
+      51          79 :   monitor_instantaneous_gradient_(false),
+      52          79 :   use_mwalkers_mpi_(false),
+      53          79 :   mwalkers_mpi_single_files_(true),
+      54          79 :   dynamic_targetdists_(0),
+      55          79 :   ustride_targetdist_(0),
+      56          79 :   ustride_reweightfactor_(0),
+      57          79 :   coeffssetid_prefix_(""),
+      58          79 :   coeffs_wstride_(100),
+      59          79 :   coeffs_output_fmt_(""),
+      60          79 :   gradient_wstride_(100),
+      61          79 :   gradient_output_fmt_(""),
+      62          79 :   hessian_wstride_(100),
+      63          79 :   hessianOFiles_(0),
+      64          79 :   hessian_output_fmt_(""),
+      65          79 :   targetdist_averages_wstride_(0),
+      66          79 :   targetdist_averages_output_fmt_(""),
+      67          79 :   nbiases_(0),
+      68          79 :   bias_pntrs_(0),
+      69          79 :   ncoeffssets_(0),
+      70          79 :   coeffs_pntrs_(0),
+      71          79 :   gradient_pntrs_(0),
+      72          79 :   hessian_pntrs_(0),
+      73          79 :   targetdist_averages_pntrs_(0),
+      74          79 :   identical_coeffs_shape_(true),
+      75          79 :   bias_output_active_(false),
+      76          79 :   bias_output_stride_(0),
+      77          79 :   fes_output_active_(false),
+      78          79 :   fes_output_stride_(0),
+      79          79 :   fesproj_output_active_(false),
+      80          79 :   fesproj_output_stride_(0),
+      81          79 :   targetdist_output_active_(false),
+      82          79 :   targetdist_output_stride_(0),
+      83          79 :   targetdist_proj_output_active_(false),
+      84          79 :   targetdist_proj_output_stride_(0),
+      85         316 :   isFirstStep(true)
+      86             : {
+      87          79 :   std::vector<std::string> bias_labels(0);
+      88         158 :   parseVector("BIAS",bias_labels);
+      89          79 :   plumed_massert(bias_labels.size()>0,"problem with BIAS keyword");
+      90          79 :   nbiases_ = bias_labels.size();
+      91             :   //
+      92          79 :   std::string error_msg = "";
+      93         158 :   bias_pntrs_ = VesTools::getPointersFromLabels<VesBias*>(bias_labels,plumed.getActionSet(),error_msg);
+      94          79 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BIAS of "+getName()+": "+error_msg);}
+      95             : 
+      96         164 :   for(unsigned int i=0; i<bias_pntrs_.size(); i++) {
+      97          85 :     bias_pntrs_[i]->linkOptimizer(this);
+      98             :     //
+      99          85 :     std::vector<CoeffsVector*> pntrs_coeffs = bias_pntrs_[i]->getCoeffsPntrs();
+     100          85 :     std::vector<CoeffsVector*> pntrs_gradient = bias_pntrs_[i]->getGradientPntrs();
+     101          85 :     std::vector<CoeffsVector*> pntrs_targetdist_averages = bias_pntrs_[i]->getTargetDistAveragesPntrs();
+     102          85 :     plumed_massert(pntrs_coeffs.size()==pntrs_gradient.size(),"something wrong in the coefficients and gradient passed from VES bias");
+     103          85 :     plumed_massert(pntrs_coeffs.size()==pntrs_targetdist_averages.size(),"something wrong in the coefficients and target distribution averages passed from VES bias");
+     104         170 :     for(unsigned int k=0; k<pntrs_coeffs.size(); k++) {
+     105          85 :       plumed_massert(pntrs_coeffs[k] != NULL,"some coefficient is not linked correctly");
+     106          85 :       plumed_massert(pntrs_gradient[k] != NULL,"some gradient is not linked correctly");
+     107          85 :       plumed_massert(pntrs_targetdist_averages[k] != NULL,"some target distribution average is not linked correctly");
+     108             :       pntrs_coeffs[k]->turnOnIterationCounter();
+     109          85 :       coeffs_pntrs_.push_back(pntrs_coeffs[k]);
+     110          85 :       pntrs_gradient[k]->turnOnIterationCounter();
+     111          85 :       gradient_pntrs_.push_back(pntrs_gradient[k]);
+     112          85 :       pntrs_targetdist_averages[k]->turnOnIterationCounter();
+     113          85 :       targetdist_averages_pntrs_.push_back(pntrs_targetdist_averages[k]);
+     114             :       //
+     115          85 :       auto aux_coeffs_tmp = Tools::make_unique<CoeffsVector>(*pntrs_coeffs[k]);
+     116          85 :       std::string aux_label = pntrs_coeffs[k]->getLabel();
+     117          85 :       if(aux_label.find("coeffs")!=std::string::npos) {
+     118         170 :         aux_label.replace(aux_label.find("coeffs"), std::string("coeffs").length(), "aux_coeffs");
+     119             :       }
+     120             :       else {
+     121             :         aux_label += "_aux";
+     122             :       }
+     123          85 :       aux_coeffs_tmp->setLabels(aux_label);
+     124          85 :       aux_coeffs_pntrs_.emplace_back(std::move(aux_coeffs_tmp));
+     125          85 :       AuxCoeffs(i).setValues( Coeffs(i) );
+     126          85 :     }
+     127             :   }
+     128          79 :   ncoeffssets_ = coeffs_pntrs_.size();
+     129          79 :   plumed_massert(aux_coeffs_pntrs_.size()==ncoeffssets_,"problems in linking aux coefficients");
+     130          79 :   plumed_massert(gradient_pntrs_.size()==ncoeffssets_,"problems in linking gradients");
+     131          79 :   setAllCoeffsSetIterationCounters();
+     132             : 
+     133             : 
+     134             :   //
+     135          79 :   identical_coeffs_shape_ = true;
+     136          85 :   for(unsigned int i=1; i<ncoeffssets_; i++) {
+     137           6 :     if(!coeffs_pntrs_[0]->sameShape(*coeffs_pntrs_[i])) {
+     138           0 :       identical_coeffs_shape_ = false;
+     139           0 :       break;
+     140             :     }
+     141             :   }
+     142             :   //
+     143         158 :   if(keywords.exists("STEPSIZE")) {
+     144         154 :     plumed_assert(!keywords.exists("INITIAL_STEPSIZE"));
+     145          77 :     fixed_stepsize_=true;
+     146          77 :     parseMultipleValues("STEPSIZE",stepsizes_);
+     147          77 :     setCurrentStepSizes(stepsizes_);
+     148             :   }
+     149         158 :   if(keywords.exists("INITIAL_STEPSIZE")) {
+     150           2 :     plumed_assert(!keywords.exists("STEPSIZE"));
+     151           1 :     fixed_stepsize_=false;
+     152           1 :     parseMultipleValues("INITIAL_STEPSIZE",stepsizes_);
+     153           1 :     setCurrentStepSizes(stepsizes_);
+     154             :   }
+     155             :   //
+     156          79 :   if(ncoeffssets_==1) {
+     157          76 :     log.printf("  optimizing VES bias %s with label %s: \n",bias_pntrs_[0]->getName().c_str(),bias_pntrs_[0]->getLabel().c_str());
+     158          76 :     log.printf("   KbT: %f\n",bias_pntrs_[0]->getKbT());
+     159          76 :     log.printf("  number of coefficients: %zu\n",coeffs_pntrs_[0]->numberOfCoeffs());
+     160          76 :     if(stepsizes_.size()>0) {
+     161          75 :       if(fixed_stepsize_) {log.printf("  using a constant step size of %f\n",stepsizes_[0]);}
+     162           1 :       else {log.printf("  using an initial step size of %f\n",stepsizes_[0]);}
+     163             :     }
+     164             :   }
+     165             :   else {
+     166           3 :     log.printf("  optimizing %u coefficient sets from following %u VES biases:\n",ncoeffssets_,nbiases_);
+     167          12 :     for(unsigned int i=0; i<nbiases_; i++) {
+     168           9 :       log.printf("   %s of type %s (KbT: %f) \n",bias_pntrs_[i]->getLabel().c_str(),bias_pntrs_[i]->getName().c_str(),bias_pntrs_[i]->getKbT());
+     169             :     }
+     170             :     size_t tot_ncoeffs = 0;
+     171          12 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     172           9 :       log.printf("  coefficient set %u: \n",i);
+     173           9 :       log.printf("   used in bias %s (type %s)\n",coeffs_pntrs_[i]->getPntrToAction()->getLabel().c_str(),coeffs_pntrs_[i]->getPntrToAction()->getName().c_str());
+     174           9 :       log.printf("   number of coefficients: %zu\n",coeffs_pntrs_[i]->numberOfCoeffs());
+     175           9 :       if(stepsizes_.size()>0) {
+     176           9 :         if(fixed_stepsize_) {log.printf("   using a constant step size of %f\n",stepsizes_[i]);}
+     177           0 :         else {log.printf("   using an initial step size of %f\n",stepsizes_[i]);}
+     178             :       }
+     179           9 :       tot_ncoeffs += coeffs_pntrs_[i]->numberOfCoeffs();
+     180             :     }
+     181           3 :     log.printf("  total number of coefficients: %zu\n",tot_ncoeffs);
+     182           3 :     if(identical_coeffs_shape_) {
+     183           3 :       log.printf("  the indices shape is identical for all coefficient sets\n");
+     184             :     }
+     185             :     else {
+     186           0 :       log.printf("  the indices shape differs between coefficient sets\n");
+     187             :     }
+     188             :   }
+     189             : 
+     190             :   //
+     191         158 :   if(keywords.exists("FULL_HESSIAN")) {
+     192           0 :     bool full_hessian=false;
+     193           0 :     parseFlag("FULL_HESSIAN",full_hessian);
+     194           0 :     diagonal_hessian_ = !full_hessian;
+     195             :   }
+     196             :   //
+     197             :   bool mw_single_files = false;
+     198         158 :   if(keywords.exists("MULTIPLE_WALKERS")) {
+     199          79 :     parseFlag("MULTIPLE_WALKERS",use_mwalkers_mpi_);
+     200          79 :     if(use_mwalkers_mpi_) {
+     201             :       mw_single_files=true;
+     202             :     }
+     203             :   }
+     204             : 
+     205          79 :   int numwalkers=1;
+     206          79 :   int walker_rank=0;
+     207          79 :   if(comm.Get_rank()==0) {
+     208          70 :     numwalkers = multi_sim_comm.Get_size();
+     209          70 :     walker_rank = multi_sim_comm.Get_rank();
+     210             :   }
+     211          79 :   comm.Bcast(numwalkers,0);
+     212          79 :   comm.Bcast(walker_rank,0);
+     213          79 :   if(use_mwalkers_mpi_ && numwalkers==1) {
+     214           0 :     plumed_merror("using the MULTIPLE_WALKERS keyword does not make sense if running the MD code with a single replica");
+     215             :   }
+     216          79 :   if(use_mwalkers_mpi_) {
+     217          12 :     log.printf("  optimization performed using multiple walkers connected via MPI:\n");
+     218          12 :     log.printf("   number of walkers: %d\n",numwalkers);
+     219          12 :     log.printf("   walker number: %d\n",walker_rank);
+     220          12 :     log.printf("   please see and cite ");
+     221          24 :     log << plumed.cite("Raiteri, Laio, Gervasio, Micheletti, and Parrinello, J. Phys. Chem. B 110, 3533 (2006)");
+     222          12 :     log.printf("\n");
+     223             :   }
+     224             : 
+     225          79 :   dynamic_targetdists_.resize(nbiases_,false);
+     226         158 :   if(keywords.exists("TARGETDIST_STRIDE")) {
+     227             :     bool need_stride = false;
+     228         162 :     for(unsigned int i=0; i<nbiases_; i++) {
+     229          84 :       dynamic_targetdists_[i] = bias_pntrs_[i]->dynamicTargetDistribution();
+     230          84 :       if(dynamic_targetdists_[i]) {need_stride = true;}
+     231             :     }
+     232          78 :     parse("TARGETDIST_STRIDE",ustride_targetdist_);
+     233          78 :     if(need_stride && ustride_targetdist_==0) {
+     234           0 :       plumed_merror("one of the biases has a dynamic target distribution so you need to give stride for updating it by using the TARGETDIST_STRIDE keyword");
+     235             :     }
+     236          78 :     if(!need_stride && ustride_targetdist_!=0) {
+     237           0 :       plumed_merror("using the TARGETDIST_STRIDE keyword doesn't make sense as there is no dynamic target distribution to update");
+     238             :     }
+     239          78 :     if(ustride_targetdist_>0) {
+     240          38 :       if(nbiases_==1) {
+     241          38 :         log.printf("  the target distribution will be updated very %u coefficient iterations\n",ustride_targetdist_);
+     242             :       }
+     243             :       else {
+     244           0 :         log.printf("  the target distribution will be updated very %u coefficient iterations for the following biases\n   ",ustride_targetdist_);
+     245           0 :         for(unsigned int i=0; i<nbiases_; i++) {
+     246           0 :           log.printf("%s ",bias_pntrs_[i]->getLabel().c_str());
+     247             :         }
+     248           0 :         log.printf("\n");
+     249             :       }
+     250          38 :       log.printf("  See and cite ");
+     251          76 :       log << plumed.cite("Valsson and Parrinello, J. Chem. Theory Comput. 11, 1996-2002 (2015)");
+     252          38 :       log.printf("\n");
+     253             :     }
+     254             :   }
+     255             : 
+     256         158 :   if(keywords.exists("REWEIGHT_FACTOR_STRIDE")) {
+     257             :     bool reweightfactor_calculated = false;
+     258           0 :     for(unsigned int i=0; i<nbiases_; i++) {
+     259           0 :       reweightfactor_calculated = bias_pntrs_[i]->isReweightFactorCalculated();
+     260             :     }
+     261           0 :     parse("REWEIGHT_FACTOR_STRIDE",ustride_reweightfactor_);
+     262           0 :     if(ustride_reweightfactor_==0 && reweightfactor_calculated) {
+     263           0 :       plumed_merror("the calculation of the reweight factor is enabled, You need to use the REWEIGHT_FACTOR_STRIDE keyword to specfiy how often it should be updated.");
+     264             :     }
+     265           0 :     if(ustride_reweightfactor_>0) {
+     266           0 :       if(!reweightfactor_calculated) {
+     267           0 :         plumed_merror("In order to use the REWEIGHT_FACTOR_STRIDE keyword you need to enable the calculation of the reweight factor in the VES bias by using the CALC_REWEIGHT_FACTOR flag.");
+     268             :       }
+     269           0 :       log.printf("  the reweight factor c(t) will be updated very %u coefficient iterations\n",ustride_reweightfactor_);
+     270             :     }
+     271             :   }
+     272             : 
+     273         158 :   if(keywords.exists("MONITOR_INSTANTANEOUS_GRADIENT")) {
+     274         158 :     parseFlag("MONITOR_INSTANTANEOUS_GRADIENT",monitor_instantaneous_gradient_);
+     275             :   }
+     276             : 
+     277         158 :   if(keywords.exists("MONITOR_AVERAGE_GRADIENT")) {
+     278          76 :     bool monitor_aver_gradient = false;
+     279          76 :     parseFlag("MONITOR_AVERAGE_GRADIENT",monitor_aver_gradient);
+     280          76 :     if(monitor_aver_gradient) {
+     281           2 :       unsigned int averaging_exp_decay=0;
+     282           4 :       parse("MONITOR_AVERAGES_GRADIENT_EXP_DECAY",averaging_exp_decay);
+     283             :       aver_gradient_pntrs_.clear();
+     284           4 :       for(unsigned int i=0; i<ncoeffssets_; i++) {
+     285           2 :         auto aver_gradient_tmp = Tools::make_unique<CoeffsVector>(*gradient_pntrs_[i]);
+     286           2 :         aver_gradient_tmp->clear();
+     287             :         std::string aver_grad_label = aver_gradient_tmp->getLabel();
+     288           2 :         if(aver_grad_label.find("gradient")!=std::string::npos) {
+     289           4 :           aver_grad_label.replace(aver_grad_label.find("gradient"), std::string("gradient").length(), "aver_gradient");
+     290             :         }
+     291             :         else {
+     292             :           aver_grad_label += "_aver";
+     293             :         }
+     294           2 :         aver_gradient_tmp->setLabels(aver_grad_label);
+     295           2 :         if(averaging_exp_decay>0) {
+     296             :           aver_gradient_tmp->setupExponentiallyDecayingAveraging(averaging_exp_decay);
+     297             :         }
+     298           2 :         aver_gradient_pntrs_.emplace_back(std::move(aver_gradient_tmp));
+     299           2 :       }
+     300             :     }
+     301             :   }
+     302             : 
+     303             : 
+     304          79 :   if(ncoeffssets_>1) {
+     305             :     coeffssetid_prefix_="c-";
+     306           6 :     if(keywords.exists("COEFFS_SET_ID_PREFIX")) {
+     307           6 :       parse("COEFFS_SET_ID_PREFIX",coeffssetid_prefix_);
+     308             :     }
+     309             :   }
+     310             :   else {
+     311             :     coeffssetid_prefix_="";
+     312         152 :     if(keywords.exists("COEFFS_SET_ID_PREFIX")) {
+     313         152 :       parse("COEFFS_SET_ID_PREFIX",coeffssetid_prefix_);
+     314             :     }
+     315          76 :     if(coeffssetid_prefix_.size()>0) {
+     316           0 :       plumed_merror("COEFFS_SET_ID_PREFIX should only be given if optimizing multiple coefficient sets");
+     317             :     }
+     318             :   }
+     319             : 
+     320         158 :   if(keywords.exists("INITIAL_COEFFS")) {
+     321             :     std::vector<std::string> initial_coeffs_fnames;
+     322         158 :     parseFilenames("INITIAL_COEFFS",initial_coeffs_fnames);
+     323          79 :     if(initial_coeffs_fnames.size()>0) {
+     324           1 :       readCoeffsFromFiles(initial_coeffs_fnames,false);
+     325           1 :       comm.Barrier();
+     326           1 :       if(comm.Get_rank()==0 && use_mwalkers_mpi_) {
+     327           0 :         multi_sim_comm.Barrier();
+     328             :       }
+     329           1 :       setAllCoeffsSetIterationCounters();
+     330             :     }
+     331          79 :   }
+     332             :   //
+     333             : 
+     334             :   std::vector<std::string> coeffs_fnames;
+     335         158 :   if(keywords.exists("COEFFS_FILE")) {
+     336         158 :     parseFilenames("COEFFS_FILE",coeffs_fnames,"coeffs.data");
+     337          79 :     bool start_opt_afresh=false;
+     338         158 :     if(keywords.exists("START_OPTIMIZATION_AFRESH")) {
+     339          76 :       parseFlag("START_OPTIMIZATION_AFRESH",start_opt_afresh);
+     340          76 :       if(start_opt_afresh && !getRestart()) {
+     341           0 :         plumed_merror("the START_OPTIMIZATION_AFRESH keyword should only be used when a restart has been triggered by the RESTART keyword or the MD code");
+     342             :       }
+     343             :     }
+     344          79 :     if(getRestart()) {
+     345          28 :       for(unsigned int i=0; i<coeffs_fnames.size(); i++) {
+     346          15 :         IFile ifile;
+     347          15 :         ifile.link(*this);
+     348          19 :         if(use_mwalkers_mpi_) {ifile.enforceSuffix("");}
+     349          15 :         bool file_exist = ifile.FileExist(coeffs_fnames[i]);
+     350          15 :         if(!file_exist) {
+     351           0 :           std::string fname = FileBase::appendSuffix(coeffs_fnames[i],ifile.getSuffix());
+     352           0 :           plumed_merror("Cannot find coefficient file " + fname + " when trying to restart an optimzation. If you don't want to restart the optimzation please remove the RESTART keyword or use the RESTART=NO within the "+getName()+" action to locally disable the restart.");
+     353             :         }
+     354          15 :       }
+     355          13 :       readCoeffsFromFiles(coeffs_fnames,true);
+     356          13 :       comm.Barrier();
+     357          13 :       if(comm.Get_rank()==0 && use_mwalkers_mpi_) {
+     358           4 :         multi_sim_comm.Barrier();
+     359             :       }
+     360          13 :       unsigned int iter_opt_tmp = coeffs_pntrs_[0]->getIterationCounter();
+     361          15 :       for(unsigned int i=1; i<ncoeffssets_; i++) {
+     362           2 :         plumed_massert(coeffs_pntrs_[i]->getIterationCounter()==iter_opt_tmp,"the iteraton counter should be the same for all files when restarting from previous coefficient files\n");
+     363             :       }
+     364          13 :       if(start_opt_afresh) {
+     365             :         setIterationCounter(0);
+     366           1 :         log.printf("  Optimization started afresh at iteration %u\n",getIterationCounter());
+     367           2 :         for(unsigned int i=0; i<ncoeffssets_; i++) {
+     368           1 :           AuxCoeffs(i).setValues( Coeffs(i) );
+     369             :         }
+     370             :       }
+     371             :       else {
+     372             :         setIterationCounter(coeffs_pntrs_[0]->getIterationCounter());
+     373          12 :         log.printf("  Optimization restarted at iteration %u\n",getIterationCounter());
+     374             :       }
+     375          13 :       setAllCoeffsSetIterationCounters();
+     376             :     }
+     377             : 
+     378          79 :     std::string coeffs_wstride_tmpstr="";
+     379         158 :     parse("COEFFS_OUTPUT",coeffs_wstride_tmpstr);
+     380          79 :     if(coeffs_wstride_tmpstr!="OFF" && coeffs_wstride_tmpstr.size()>0) {
+     381          79 :       Tools::convert(coeffs_wstride_tmpstr,coeffs_wstride_);
+     382             :     }
+     383          79 :     if(coeffs_wstride_tmpstr=="OFF") {
+     384             :       coeffs_fnames.clear();
+     385             :     }
+     386          79 :     setupOFiles(coeffs_fnames,coeffsOFiles_,mw_single_files);
+     387         158 :     parse("COEFFS_FMT",coeffs_output_fmt_);
+     388          79 :     if(coeffs_output_fmt_.size()>0) {
+     389         162 :       for(unsigned int i=0; i<ncoeffssets_; i++) {
+     390          84 :         coeffs_pntrs_[i]->setOutputFmt(coeffs_output_fmt_);
+     391             :       }
+     392             :     }
+     393          79 :     if(!getRestart()) {
+     394         136 :       for(unsigned int i=0; i<coeffsOFiles_.size(); i++) {
+     395          70 :         coeffs_pntrs_[i]->writeToFile(*coeffsOFiles_[i],aux_coeffs_pntrs_[i].get(),false);
+     396             :       }
+     397             :     }
+     398          79 :     if(coeffs_fnames.size()>0) {
+     399          79 :       if(ncoeffssets_==1) {
+     400         152 :         log.printf("  Coefficients will be written out to file %s every %u iterations\n",coeffsOFiles_[0]->getPath().c_str(),coeffs_wstride_);
+     401             :       }
+     402             :       else {
+     403           3 :         log.printf("  Coefficients will be written out to the following files every %u iterations:\n",coeffs_wstride_);
+     404          12 :         for(unsigned int i=0; i<coeffs_fnames.size(); i++) {
+     405          18 :           log.printf("   coefficient set %u: %s\n",i,coeffsOFiles_[i]->getPath().c_str());
+     406             :         }
+     407             :       }
+     408             :     }
+     409             :     else {
+     410           0 :       log.printf("  Output of coefficients to file has been disabled\n");
+     411             :     }
+     412             :   }
+     413             : 
+     414             :   std::vector<std::string> gradient_fnames;
+     415         158 :   if(keywords.exists("GRADIENT_FILE")) {
+     416          79 :     parseFilenames("GRADIENT_FILE",gradient_fnames);
+     417         158 :     parse("GRADIENT_OUTPUT",gradient_wstride_);
+     418             : 
+     419          79 :     if(coeffs_fnames.size()>0) {
+     420         151 :       for(unsigned int i=0; i<gradient_fnames.size(); i++) {
+     421          72 :         plumed_massert(gradient_fnames[i]!=coeffs_fnames[i],"COEFFS_FILE and GRADIENT_FILE cannot be the same");
+     422             :       }
+     423             :     }
+     424          79 :     setupOFiles(gradient_fnames,gradientOFiles_,mw_single_files);
+     425         158 :     parse("GRADIENT_FMT",gradient_output_fmt_);
+     426          79 :     if(gradient_output_fmt_.size()>0) {
+     427         138 :       for(unsigned int i=0; i<ncoeffssets_; i++) {
+     428          72 :         gradient_pntrs_[i]->setOutputFmt(gradient_output_fmt_);
+     429             :       }
+     430             :     }
+     431             : 
+     432          79 :     if(gradient_fnames.size()>0) {
+     433          66 :       if(ncoeffssets_==1) {
+     434         126 :         log.printf("  Gradient will be written out to file %s every %u iterations\n",gradientOFiles_[0]->getPath().c_str(),gradient_wstride_);
+     435             :       }
+     436             :       else {
+     437           3 :         log.printf("  Gradient will be written out to the following files every %u iterations:\n",gradient_wstride_);
+     438          12 :         for(unsigned int i=0; i<gradient_fnames.size(); i++) {
+     439          18 :           log.printf("   coefficient set %u: %s\n",i,gradientOFiles_[i]->getPath().c_str());
+     440             :         }
+     441             :       }
+     442             :     }
+     443             :   }
+     444             : 
+     445             :   std::vector<std::string> hessian_fnames;
+     446         158 :   if(keywords.exists("HESSIAN_FILE")) {
+     447          76 :     parseFilenames("HESSIAN_FILE",hessian_fnames);
+     448         152 :     parse("HESSIAN_OUTPUT",hessian_wstride_);
+     449             : 
+     450          76 :     if(coeffs_fnames.size()>0) {
+     451         142 :       for(unsigned int i=0; i<hessian_fnames.size(); i++) {
+     452          66 :         plumed_massert(hessian_fnames[i]!=coeffs_fnames[i],"COEFFS_FILE and HESSIAN_FILE cannot be the same");
+     453             :       }
+     454             :     }
+     455          76 :     if(gradient_fnames.size()>0) {
+     456         131 :       for(unsigned int i=0; i<hessian_fnames.size(); i++) {
+     457          66 :         plumed_massert(hessian_fnames[i]!=gradient_fnames[i],"GRADIENT_FILE and HESSIAN_FILE cannot be the same");
+     458             :       }
+     459             :     }
+     460          76 :     setupOFiles(hessian_fnames,hessianOFiles_,mw_single_files);
+     461         152 :     parse("HESSIAN_FMT",hessian_output_fmt_);
+     462             : 
+     463          76 :     if(hessian_fnames.size()>0) {
+     464          62 :       if(ncoeffssets_==1) {
+     465         120 :         log.printf("  Hessian will be written out to file %s every %u iterations\n",hessianOFiles_[0]->getPath().c_str(),hessian_wstride_);
+     466             :       }
+     467             :       else {
+     468           2 :         log.printf("  Hessian will be written out to the following files every %u iterations:\n",hessian_wstride_);
+     469           8 :         for(unsigned int i=0; i<hessian_fnames.size(); i++) {
+     470          12 :           log.printf("   coefficient set %u: %s\n",i,hessianOFiles_[i]->getPath().c_str());
+     471             :         }
+     472             :       }
+     473             :     }
+     474             :   }
+     475             : 
+     476             : 
+     477             :   //
+     478         158 :   if(keywords.exists("MASK_FILE")) {
+     479             :     std::vector<std::string> mask_fnames_in;
+     480         156 :     parseVector("MASK_FILE",mask_fnames_in);
+     481          78 :     if(mask_fnames_in.size()==1 && ncoeffssets_>1) {
+     482           0 :       if(identical_coeffs_shape_) {mask_fnames_in.resize(ncoeffssets_,mask_fnames_in[0]);}
+     483           0 :       else {plumed_merror("the coefficients indices shape differs between biases so you need to give a separate file for each coefficient set\n");}
+     484             :     }
+     485          78 :     if(mask_fnames_in.size()>0 && mask_fnames_in.size()!=ncoeffssets_) {
+     486           0 :       plumed_merror("Error in MASK_FILE keyword: either give one value for all biases or a separate value for each coefficient set");
+     487             :     }
+     488             : 
+     489          78 :     coeffs_mask_pntrs_.resize(ncoeffssets_);
+     490         162 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     491         168 :       coeffs_mask_pntrs_[i] = Tools::make_unique<CoeffsVector>(*coeffs_pntrs_[i]);
+     492         168 :       coeffs_mask_pntrs_[i]->setLabels("mask");
+     493          84 :       coeffs_mask_pntrs_[i]->setValues(1.0);
+     494         168 :       coeffs_mask_pntrs_[i]->setOutputFmt("%f");
+     495             :     }
+     496             : 
+     497          78 :     if(mask_fnames_in.size()>0) {
+     498           1 :       if(ncoeffssets_==1) {
+     499           1 :         size_t nread = coeffs_mask_pntrs_[0]->readFromFile(mask_fnames_in[0],true,true);
+     500           1 :         log.printf("  read %zu values from mask file %s\n",nread,mask_fnames_in[0].c_str());
+     501           1 :         size_t ndeactived = coeffs_mask_pntrs_[0]->countValues(0.0);
+     502           1 :         log.printf("  deactived optimization of %zu coefficients\n",ndeactived);
+     503             :       }
+     504             :       else {
+     505           0 :         for(unsigned int i=0; i<ncoeffssets_; i++) {
+     506           0 :           size_t nread = coeffs_mask_pntrs_[i]->readFromFile(mask_fnames_in[i],true,true);
+     507           0 :           log.printf("  mask for coefficient set %u:\n",i);
+     508           0 :           log.printf("   read %zu values from file %s\n",nread,mask_fnames_in[i].c_str());
+     509           0 :           size_t ndeactived = coeffs_mask_pntrs_[0]->countValues(0.0);
+     510           0 :           log.printf("   deactived optimization of %zu coefficients\n",ndeactived);
+     511             :         }
+     512             :       }
+     513             :     }
+     514             : 
+     515             :     std::vector<std::string> mask_fnames_out;
+     516          78 :     parseFilenames("OUTPUT_MASK_FILE",mask_fnames_out);
+     517             : 
+     518          79 :     for(unsigned int i=0; i<mask_fnames_out.size(); i++) {
+     519           1 :       if(mask_fnames_in.size()>0) {
+     520           1 :         plumed_massert(mask_fnames_out[i]!=mask_fnames_in[i],"MASK_FILE and OUTPUT_MASK_FILE cannot be the same");
+     521             :       }
+     522           1 :       OFile maskOFile;
+     523           1 :       maskOFile.link(*this);
+     524           1 :       maskOFile.enforceBackup();
+     525           1 :       if(use_mwalkers_mpi_ && mwalkers_mpi_single_files_) {
+     526           0 :         unsigned int r=0;
+     527           0 :         if(comm.Get_rank()==0) {r=multi_sim_comm.Get_rank();}
+     528           0 :         comm.Bcast(r,0);
+     529           0 :         if(r>0) {mask_fnames_out[i]="/dev/null";}
+     530           0 :         maskOFile.enforceSuffix("");
+     531             :       }
+     532           1 :       maskOFile.open(mask_fnames_out[i]);
+     533           1 :       coeffs_mask_pntrs_[i]->writeToFile(maskOFile,true);
+     534           1 :       maskOFile.close();
+     535           1 :     }
+     536          78 :   }
+     537             : 
+     538          79 :   if(getRestart() && ustride_targetdist_>0) {
+     539          16 :     for(unsigned int i=0; i<nbiases_; i++) {
+     540           8 :       if(dynamic_targetdists_[i]) {
+     541           8 :         bias_pntrs_[i]->restartTargetDistributions();
+     542             :       }
+     543             :     }
+     544             :   }
+     545             : 
+     546             : 
+     547             :   std::vector<std::string> targetdist_averages_fnames;
+     548         158 :   if(keywords.exists("TARGETDIST_AVERAGES_FILE")) {
+     549         158 :     parseFilenames("TARGETDIST_AVERAGES_FILE",targetdist_averages_fnames,"targetdist-averages.data");
+     550         158 :     parse("TARGETDIST_AVERAGES_OUTPUT",targetdist_averages_wstride_);
+     551             : 
+     552          79 :     if(coeffs_fnames.size()>0) {
+     553         164 :       for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     554          85 :         plumed_massert(targetdist_averages_fnames[i]!=coeffs_fnames[i],"COEFFS_FILE and TARGETDIST_AVERAGES_FILE cannot be the same");
+     555             :       }
+     556             :     }
+     557          79 :     if(gradient_fnames.size()>0) {
+     558         138 :       for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     559          72 :         plumed_massert(targetdist_averages_fnames[i]!=gradient_fnames[i],"GRADIENT_FILE and TARGETDIST_AVERAGES_FILE cannot be the same");
+     560             :       }
+     561             :     }
+     562          79 :     if(hessian_fnames.size()>0) {
+     563         128 :       for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     564          66 :         plumed_massert(targetdist_averages_fnames[i]!=hessian_fnames[i],"HESSIAN_FILE and TARGETDIST_AVERAGES_FILE cannot be the same");
+     565             :       }
+     566             :     }
+     567          79 :     setupOFiles(targetdist_averages_fnames,targetdist_averagesOFiles_,mw_single_files);
+     568         158 :     parse("TARGETDIST_AVERAGES_FMT",targetdist_averages_output_fmt_);
+     569          79 :     if(targetdist_averages_output_fmt_.size()>0) {
+     570         156 :       for(unsigned int i=0; i<ncoeffssets_; i++) {
+     571          81 :         targetdist_averages_pntrs_[i]->setOutputFmt(targetdist_averages_output_fmt_);
+     572             :       }
+     573             :     }
+     574             : 
+     575         164 :     for(unsigned int i=0; i<targetdist_averagesOFiles_.size(); i++) {
+     576          85 :       targetdist_averages_pntrs_[i]->writeToFile(*targetdist_averagesOFiles_[i]);
+     577             :     }
+     578             : 
+     579          79 :     if(targetdist_averages_wstride_==0) {
+     580             :       targetdist_averagesOFiles_.clear();
+     581             :     }
+     582             : 
+     583          79 :     if(targetdist_averages_fnames.size()>0 && targetdist_averages_wstride_ > 0) {
+     584          34 :       if(ncoeffssets_==1) {
+     585          68 :         log.printf("  Target distribution averages will be written out to file %s every %u iterations\n",targetdist_averagesOFiles_[0]->getPath().c_str(),targetdist_averages_wstride_);
+     586             :       }
+     587             :       else {
+     588           0 :         log.printf("  Target distribution averages will be written out to the following files every %u iterations:\n",targetdist_averages_wstride_);
+     589           0 :         for(unsigned int i=0; i<targetdist_averages_fnames.size(); i++) {
+     590           0 :           log.printf("   coefficient set %u: %s\n",i,targetdist_averagesOFiles_[i]->getPath().c_str());
+     591             :         }
+     592             :       }
+     593             :     }
+     594             :   }
+     595             : 
+     596             : 
+     597         158 :   if(keywords.exists("BIAS_OUTPUT")) {
+     598          79 :     parse("BIAS_OUTPUT",bias_output_stride_);
+     599          79 :     if(bias_output_stride_>0) {
+     600          74 :       bias_output_active_=true;
+     601         154 :       for(unsigned int i=0; i<nbiases_; i++) {
+     602          80 :         bias_pntrs_[i]->enableBiasFileOutput();
+     603          80 :         bias_pntrs_[i]->setupBiasFileOutput();
+     604          80 :         bias_pntrs_[i]->writeBiasToFile();
+     605             :       }
+     606             :     }
+     607             :     else {
+     608           5 :       bias_output_active_=false;
+     609           5 :       bias_output_stride_=1000;
+     610             :     }
+     611             :   }
+     612             : 
+     613         158 :   if(keywords.exists("FES_OUTPUT")) {
+     614          79 :     parse("FES_OUTPUT",fes_output_stride_);
+     615          79 :     if(fes_output_stride_>0) {
+     616          74 :       fes_output_active_=true;
+     617         154 :       for(unsigned int i=0; i<nbiases_; i++) {
+     618          80 :         bias_pntrs_[i]->enableFesFileOutput();
+     619          80 :         bias_pntrs_[i]->setupFesFileOutput();
+     620          80 :         bias_pntrs_[i]->writeFesToFile();
+     621             :       }
+     622             :     }
+     623             :     else {
+     624           5 :       fes_output_active_=false;
+     625           5 :       fes_output_stride_=1000;
+     626             :     }
+     627             :   }
+     628             : 
+     629         158 :   if(keywords.exists("FES_PROJ_OUTPUT")) {
+     630          79 :     parse("FES_PROJ_OUTPUT",fesproj_output_stride_);
+     631          79 :     if(fesproj_output_stride_>0) {
+     632          16 :       fesproj_output_active_=true;
+     633          32 :       for(unsigned int i=0; i<nbiases_; i++) {
+     634          16 :         bias_pntrs_[i]->enableFesProjFileOutput();
+     635          16 :         bias_pntrs_[i]->setupFesProjFileOutput();
+     636          16 :         bias_pntrs_[i]->writeFesProjToFile();
+     637             :       }
+     638             :     }
+     639             :     else {
+     640          63 :       fesproj_output_active_=false;
+     641          63 :       fesproj_output_stride_=1000;
+     642             :     }
+     643             :   }
+     644             : 
+     645         164 :   for(unsigned int i=0; i<nbiases_; i++) {
+     646          85 :     if(!dynamic_targetdists_[i] && bias_pntrs_[i]->isStaticTargetDistFileOutputActive()) {
+     647           4 :       bias_pntrs_[i]->setupTargetDistFileOutput();
+     648           4 :       bias_pntrs_[i]->writeTargetDistToFile();
+     649           4 :       bias_pntrs_[i]->setupTargetDistProjFileOutput();
+     650           4 :       bias_pntrs_[i]->writeTargetDistProjToFile();
+     651             :     }
+     652             :   }
+     653             : 
+     654         158 :   if(keywords.exists("TARGETDIST_OUTPUT")) {
+     655          78 :     parse("TARGETDIST_OUTPUT",targetdist_output_stride_);
+     656          78 :     if(targetdist_output_stride_>0) {
+     657          37 :       if(ustride_targetdist_==0) {
+     658           0 :         plumed_merror("it doesn't make sense to use the TARGETDIST_OUTPUT keyword if you don't have a target distribution that needs to be updated");
+     659             :       }
+     660          37 :       if(targetdist_output_stride_%ustride_targetdist_!=0) {
+     661           0 :         plumed_merror("the value given in TARGETDIST_OUTPUT doesn't make sense, it should be multiple of TARGETDIST_STRIDE");
+     662             :       }
+     663          37 :       if(targetdist_output_stride_%coeffs_wstride_!=0) {
+     664           0 :         plumed_merror("the value given in TARGETDIST_OUTPUT doesn't make sense, it should be multiple of COEFFS_OUTPUT");
+     665             :       }
+     666             : 
+     667          37 :       targetdist_output_active_=true;
+     668          74 :       for(unsigned int i=0; i<nbiases_; i++) {
+     669          37 :         if(dynamic_targetdists_[i]) {
+     670          37 :           bias_pntrs_[i]->enableDynamicTargetDistFileOutput();
+     671          37 :           bias_pntrs_[i]->setupTargetDistFileOutput();
+     672          37 :           bias_pntrs_[i]->writeTargetDistToFile();
+     673             :         }
+     674             :       }
+     675             :     }
+     676             :     else {
+     677          41 :       targetdist_output_active_=false;
+     678          41 :       targetdist_output_stride_=1000;
+     679             :     }
+     680             :   }
+     681             : 
+     682         158 :   if(keywords.exists("TARGETDIST_PROJ_OUTPUT")) {
+     683          78 :     parse("TARGETDIST_PROJ_OUTPUT",targetdist_proj_output_stride_);
+     684          78 :     if(targetdist_proj_output_stride_>0) {
+     685           3 :       if(ustride_targetdist_==0) {
+     686           0 :         plumed_merror("it doesn't make sense to use the TARGETDIST_PROJ_OUTPUT keyword if you don't have a target distribution that needs to be updated");
+     687             :       }
+     688           3 :       if(targetdist_proj_output_stride_%ustride_targetdist_!=0) {
+     689           0 :         plumed_merror("the value given in TARGETDIST_PROJ_OUTPUT doesn't make sense, it should be multiple of TARGETDIST_STRIDE");
+     690             :       }
+     691             : 
+     692           3 :       targetdist_proj_output_active_=true;
+     693           6 :       for(unsigned int i=0; i<nbiases_; i++) {
+     694           3 :         if(dynamic_targetdists_[i]) {
+     695           3 :           bias_pntrs_[i]->enableDynamicTargetDistFileOutput();
+     696           3 :           bias_pntrs_[i]->setupTargetDistProjFileOutput();
+     697           3 :           bias_pntrs_[i]->writeTargetDistProjToFile();
+     698             :         }
+     699             :       }
+     700             :     }
+     701             :     else {
+     702          75 :       targetdist_proj_output_active_=false;
+     703          75 :       targetdist_proj_output_stride_=1000;
+     704             :     }
+     705             :   }
+     706             : 
+     707          79 :   if(ncoeffssets_==1) {
+     708          76 :     log.printf("  Output Components:\n");
+     709          76 :     log.printf(" ");
+     710          76 :     if(monitor_instantaneous_gradient_) {
+     711           6 :       addComponent("gradrms"); componentIsNotPeriodic("gradrms");
+     712           3 :       log.printf(" ");
+     713           9 :       addComponent("gradmax"); componentIsNotPeriodic("gradmax");
+     714             :     }
+     715          76 :     if(aver_gradient_pntrs_.size()>0) {
+     716           2 :       log.printf(" ");
+     717           4 :       addComponent("avergradrms"); componentIsNotPeriodic("avergradrms");
+     718           2 :       log.printf(" ");
+     719           6 :       addComponent("avergradmax"); componentIsNotPeriodic("avergradmax");
+     720             :     }
+     721          76 :     if(!fixed_stepsize_) {
+     722           1 :       log.printf(" ");
+     723           2 :       addComponent("stepsize"); componentIsNotPeriodic("stepsize");
+     724           2 :       getPntrToComponent("stepsize")->set( getCurrentStepSize(0) );
+     725             :     }
+     726             :   }
+     727             :   else {
+     728          12 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     729           9 :       log.printf("  Output Components for coefficient set %u:\n",i);
+     730          18 :       std::string is=""; Tools::convert(i,is); is = "-" + coeffssetid_prefix_ + is;
+     731           9 :       log.printf(" ");
+     732           9 :       if(monitor_instantaneous_gradient_) {
+     733           6 :         addComponent("gradrms"+is); componentIsNotPeriodic("gradrms"+is);
+     734           3 :         log.printf(" ");
+     735           9 :         addComponent("gradmax"+is); componentIsNotPeriodic("gradmax"+is);
+     736             :       }
+     737           9 :       if(aver_gradient_pntrs_.size()>0) {
+     738           0 :         log.printf(" ");
+     739           0 :         addComponent("avergradrms"+is); componentIsNotPeriodic("avergradrms"+is);
+     740           0 :         log.printf(" ");
+     741           0 :         addComponent("avergradmax"+is); componentIsNotPeriodic("avergradmax"+is);
+     742             :       }
+     743           9 :       if(!fixed_stepsize_) {
+     744           0 :         log.printf(" ");
+     745           0 :         addComponent("stepsize"+is); componentIsNotPeriodic("stepsize"+is);
+     746           0 :         getPntrToComponent("stepsize"+is)->set( getCurrentStepSize(i) );
+     747             :       }
+     748             :     }
+     749             :   }
+     750             : 
+     751         158 : }
+     752             : 
+     753             : 
+     754          79 : Optimizer::~Optimizer() {
+     755             :   //
+     756         164 :   for(unsigned int i=0; i<ncoeffssets_; i++) {
+     757          85 :     if(coeffsOFiles_.size()>0 && getIterationCounter()%coeffs_wstride_!=0) {
+     758           2 :       coeffs_pntrs_[i]->writeToFile(*coeffsOFiles_[i],aux_coeffs_pntrs_[i].get(),false);
+     759             :     }
+     760          85 :     if(targetdist_averagesOFiles_.size()>0 && iter_counter%targetdist_averages_wstride_!=0) {
+     761           1 :       targetdist_averages_pntrs_[i]->writeToFile(*targetdist_averagesOFiles_[i]);
+     762             :     }
+     763             :   }
+     764             :   //
+     765          79 :   if(!isTargetDistOutputActive()) {
+     766          90 :     for(unsigned int i=0; i<nbiases_; i++) {
+     767          48 :       if(dynamic_targetdists_[i]) {
+     768           1 :         bias_pntrs_[i]->enableDynamicTargetDistFileOutput();
+     769           1 :         bias_pntrs_[i]->setupTargetDistFileOutput();
+     770           1 :         bias_pntrs_[i]->writeTargetDistToFile();
+     771             :       }
+     772             :     }
+     773             :   }
+     774             :   //
+     775          79 :   if(isBiasOutputActive() && getIterationCounter()%getBiasOutputStride()!=0) {
+     776           1 :     writeBiasOutputFiles();
+     777             :   }
+     778          79 :   if(isFesOutputActive() && getIterationCounter()%getFesOutputStride()!=0) {
+     779           1 :     writeFesOutputFiles();
+     780             :   }
+     781          79 :   if(isFesProjOutputActive() && getIterationCounter()%getFesProjOutputStride()!=0) {
+     782           1 :     writeFesProjOutputFiles();
+     783             :   }
+     784          79 :   if(isTargetDistOutputActive() && getIterationCounter()%getTargetDistOutputStride()!=0) {
+     785           2 :     writeTargetDistOutputFiles();
+     786             :   }
+     787          79 :   if(isTargetDistProjOutputActive() && getIterationCounter()%getTargetDistProjOutputStride()!=0) {
+     788           1 :     writeTargetDistProjOutputFiles();
+     789             :   }
+     790         395 : }
+     791             : 
+     792             : 
+     793          87 : void Optimizer::registerKeywords( Keywords& keys ) {
+     794          87 :   Action::registerKeywords(keys);
+     795          87 :   ActionPilot::registerKeywords(keys);
+     796          87 :   ActionWithValue::registerKeywords(keys);
+     797             :   //
+     798          87 :   keys.remove("NUMERICAL_DERIVATIVES");
+     799             :   // Default always active keywords
+     800         174 :   keys.add("compulsory","BIAS","the label of the VES bias to be optimized");
+     801         174 :   keys.add("compulsory","STRIDE","the frequency of updating the coefficients given in the number of MD steps.");
+     802         174 :   keys.add("compulsory","COEFFS_FILE","coeffs.data","the name of output file for the coefficients");
+     803         174 :   keys.add("compulsory","COEFFS_OUTPUT","100","how often the coefficients should be written to file. This parameter is given as the number of iterations.");
+     804         174 :   keys.add("optional","COEFFS_FMT","specify format for coefficient file(s) (useful for decrease the number of digits in regtests)");
+     805         174 :   keys.add("optional","COEFFS_SET_ID_PREFIX","suffix to add to the filename given in FILE to identify the bias, should only be given if a single filename is given in FILE when optimizing multiple biases.");
+     806             :   //
+     807         174 :   keys.add("optional","INITIAL_COEFFS","the name(s) of file(s) with the initial coefficients");
+     808             :   // Hidden keywords to output the gradient to a file.
+     809         174 :   keys.add("hidden","GRADIENT_FILE","the name of output file for the gradient");
+     810         174 :   keys.add("hidden","GRADIENT_OUTPUT","how often the gradient should be written to file. This parameter is given as the number of bias iterations. It is by default 100 if GRADIENT_FILE is specficed");
+     811         174 :   keys.add("hidden","GRADIENT_FMT","specify format for gradient file(s) (useful for decrease the number of digits in regtests)");
+     812             :   // Either use a fixed stepsize (useFixedStepSizeKeywords) or changing stepsize (useDynamicsStepSizeKeywords)
+     813         174 :   keys.reserve("compulsory","STEPSIZE","the step size used for the optimization");
+     814         174 :   keys.reserve("compulsory","INITIAL_STEPSIZE","the initial step size used for the optimization");
+     815             :   // Keywords related to the Hessian, actived with the useHessianKeywords function
+     816         174 :   keys.reserveFlag("FULL_HESSIAN",false,"if the full Hessian matrix should be used for the optimization, otherwise only the diagonal part of the Hessian is used");
+     817         174 :   keys.reserve("hidden","HESSIAN_FILE","the name of output file for the Hessian");
+     818         174 :   keys.reserve("hidden","HESSIAN_OUTPUT","how often the Hessian should be written to file. This parameter is given as the number of bias iterations. It is by default 100 if HESSIAN_FILE is specficed");
+     819         174 :   keys.reserve("hidden","HESSIAN_FMT","specify format for hessian file(s) (useful for decrease the number of digits in regtests)");
+     820             :   // Keywords related to the multiple walkers, actived with the useMultipleWalkersKeywords function
+     821         174 :   keys.reserveFlag("MULTIPLE_WALKERS",false,"if optimization is to be performed using multiple walkers connected via MPI");
+     822             :   // Keywords related to the mask file, actived with the useMaskKeywords function
+     823         174 :   keys.reserve("optional","MASK_FILE","read in a mask file which allows one to employ different step sizes for different coefficients and/or deactivate the optimization of certain coefficients (by putting values of 0.0). One can write out the resulting mask by using the OUTPUT_MASK_FILE keyword.");
+     824         174 :   keys.reserve("optional","OUTPUT_MASK_FILE","Name of the file to write out the mask resulting from using the MASK_FILE keyword. Can also be used to generate a template mask file.");
+     825             :   //
+     826         174 :   keys.reserveFlag("START_OPTIMIZATION_AFRESH",false,"if the iterations should be started afresh when a restart has been triggered by the RESTART keyword or the MD code.");
+     827             :   //
+     828         174 :   keys.addFlag("MONITOR_INSTANTANEOUS_GRADIENT",false,"if quantities related to the instantaneous gradient should be outputted.");
+     829             :   //
+     830         174 :   keys.reserveFlag("MONITOR_AVERAGE_GRADIENT",false,"if the averaged gradient should be monitored and quantities related to it should be outputted.");
+     831         174 :   keys.reserve("optional","MONITOR_AVERAGES_GRADIENT_EXP_DECAY","use an exponentially decaying averaging with a given time constant when monitoring the averaged gradient");
+     832             :   //
+     833         174 :   keys.reserve("optional","TARGETDIST_STRIDE","stride for updating a target distribution that is iteratively updated during the optimization. Note that the value is given in terms of coefficient iterations.");
+     834         174 :   keys.reserve("optional","TARGETDIST_OUTPUT","how often the dynamic target distribution(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     835         174 :   keys.reserve("optional","TARGETDIST_PROJ_OUTPUT","how often the projections of the dynamic target distribution(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     836             :   //
+     837         174 :   keys.add("optional","TARGETDIST_AVERAGES_FILE","the name of output file for the target distribution averages. By default it is targetdist-averages.data.");
+     838         174 :   keys.add("optional","TARGETDIST_AVERAGES_OUTPUT","how often the target distribution averages should be written out to file. Note that the value is given in terms of coefficient iterations. If no value is given are the averages only written at the beginning of the optimization");
+     839         174 :   keys.add("hidden","TARGETDIST_AVERAGES_FMT","specify format for target distribution averages file(s) (useful for decrease the number of digits in regtests)");
+     840             :   //
+     841         174 :   keys.add("optional","BIAS_OUTPUT","how often the bias(es) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     842         174 :   keys.add("optional","FES_OUTPUT","how often the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     843         174 :   keys.add("optional","FES_PROJ_OUTPUT","how often the projections of the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     844             :   //
+     845         174 :   keys.reserve("optional","REWEIGHT_FACTOR_STRIDE","stride for updating the reweighting factor c(t). Note that the value is given in terms of coefficient iterations.");
+     846             :   //
+     847          87 :   keys.use("RESTART");
+     848             :   //
+     849          87 :   keys.use("UPDATE_FROM");
+     850          87 :   keys.use("UPDATE_UNTIL");
+     851             :   // Components that are always active
+     852         174 :   keys.addOutputComponent("gradrms","MONITOR_INSTANTANEOUS_GRADIENT","the root mean square value of the coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradrms-#.");
+     853         174 :   keys.addOutputComponent("gradmax","MONITOR_INSTANTANEOUS_GRADIENT","the largest absolute value of the coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradmax-#.");
+     854             :   // keys.addOutputComponent("gradmaxidx","default","the index of the maximum absolute value of the gradient");
+     855             : 
+     856          87 : }
+     857             : 
+     858             : 
+     859          80 : void Optimizer::useHessianKeywords(Keywords& keys) {
+     860             :   // keys.use("FULL_HESSIAN");
+     861          80 :   keys.use("HESSIAN_FILE");
+     862          80 :   keys.use("HESSIAN_OUTPUT");
+     863          80 :   keys.use("HESSIAN_FMT");
+     864          80 : }
+     865             : 
+     866             : 
+     867          87 : void Optimizer::useMultipleWalkersKeywords(Keywords& keys) {
+     868          87 :   keys.use("MULTIPLE_WALKERS");
+     869          87 : }
+     870             : 
+     871             : 
+     872          81 : void Optimizer::useFixedStepSizeKeywords(Keywords& keys) {
+     873          81 :   keys.use("STEPSIZE");
+     874          81 : }
+     875             : 
+     876             : 
+     877           3 : void Optimizer::useDynamicStepSizeKeywords(Keywords& keys) {
+     878           3 :   keys.use("INITIAL_STEPSIZE");
+     879           6 :   keys.addOutputComponent("stepsize","default","the current value of step size used to update the coefficients. For multiple biases this component is labeled using the number of the bias as stepsize-#.");
+     880           3 : }
+     881             : 
+     882             : 
+     883          84 : void Optimizer::useMaskKeywords(Keywords& keys) {
+     884          84 :   keys.use("MASK_FILE");
+     885          84 :   keys.use("OUTPUT_MASK_FILE");
+     886          84 : }
+     887             : 
+     888             : 
+     889          80 : void Optimizer::useRestartKeywords(Keywords& keys) {
+     890          80 :   keys.use("START_OPTIMIZATION_AFRESH");
+     891          80 : }
+     892             : 
+     893             : 
+     894          80 : void Optimizer::useMonitorAverageGradientKeywords(Keywords& keys) {
+     895          80 :   keys.use("MONITOR_AVERAGE_GRADIENT");
+     896          80 :   keys.use("MONITOR_AVERAGES_GRADIENT_EXP_DECAY");
+     897         160 :   keys.addOutputComponent("avergradrms","MONITOR_AVERAGE_GRADIENT","the root mean square value of the averaged coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradrms-#.");
+     898         160 :   keys.addOutputComponent("avergradmax","MONITOR_AVERAGE_GRADIENT","the largest absolute value of the averaged coefficient gradient. For multiple biases this component is labeled using the number of the bias as gradmax-#.");
+     899          80 : }
+     900             : 
+     901             : 
+     902          84 : void Optimizer::useDynamicTargetDistributionKeywords(Keywords& keys) {
+     903          84 :   keys.use("TARGETDIST_STRIDE");
+     904          84 :   keys.use("TARGETDIST_OUTPUT");
+     905          84 :   keys.use("TARGETDIST_PROJ_OUTPUT");
+     906          84 : }
+     907             : 
+     908             : 
+     909           0 : void Optimizer::useReweightFactorKeywords(Keywords& keys) {
+     910           0 :   keys.use("REWEIGHT_FACTOR_STRIDE");
+     911           0 : }
+     912             : 
+     913             : 
+     914          76 : void Optimizer::turnOnHessian() {
+     915          76 :   plumed_massert(hessian_pntrs_.size()==0,"turnOnHessian() should only be run during initialization");
+     916          76 :   use_hessian_=true;
+     917          76 :   hessian_pntrs_.clear();
+     918         158 :   for(unsigned int i=0; i<nbiases_; i++) {
+     919          82 :     std::vector<CoeffsMatrix*> pntrs_hessian = enableHessian(bias_pntrs_[i],diagonal_hessian_);
+     920         164 :     for(unsigned int k=0; k<pntrs_hessian.size(); k++) {
+     921          82 :       pntrs_hessian[k]->turnOnIterationCounter();
+     922          82 :       pntrs_hessian[k]->setIterationCounterAndTime(getIterationCounter(),getTime());
+     923          82 :       hessian_pntrs_.push_back(pntrs_hessian[k]);
+     924             :     }
+     925             :   }
+     926          76 :   plumed_massert(hessian_pntrs_.size()==ncoeffssets_,"problems in linking Hessians");
+     927          76 :   if(diagonal_hessian_) {
+     928          76 :     log.printf("  Optimization performed using diagonal Hessian matrix\n");
+     929             :   }
+     930             :   else {
+     931           0 :     log.printf("  Optimization performed using full Hessian matrix\n");
+     932             :   }
+     933             :   //
+     934          76 :   if(hessian_output_fmt_.size()>0) {
+     935         128 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     936          66 :       hessian_pntrs_[i]->setOutputFmt(hessian_output_fmt_);
+     937             :     }
+     938             :   }
+     939             : 
+     940          76 : }
+     941             : 
+     942             : 
+     943           0 : void Optimizer::turnOffHessian() {
+     944           0 :   use_hessian_=false;
+     945           0 :   for(unsigned int i=0; i<nbiases_; i++) {
+     946           0 :     bias_pntrs_[i]->disableHessian();
+     947             :   }
+     948             :   hessian_pntrs_.clear();
+     949           0 :   hessianOFiles_.clear();
+     950           0 : }
+     951             : 
+     952             : 
+     953          82 : std::vector<CoeffsMatrix*> Optimizer::enableHessian(VesBias* bias_pntr_in, const bool diagonal_hessian) {
+     954          82 :   plumed_massert(use_hessian_,"the Hessian should not be used");
+     955          82 :   bias_pntr_in->enableHessian(diagonal_hessian);
+     956             :   std::vector<CoeffsMatrix*> hessian_pntrs_out = bias_pntr_in->getHessianPntrs();
+     957         164 :   for(unsigned int k=0; k<hessian_pntrs_out.size(); k++) {
+     958          82 :     plumed_massert(hessian_pntrs_out[k] != NULL,"Hessian is needed but not linked correctly");
+     959             :   }
+     960          82 :   return hessian_pntrs_out;
+     961             : }
+     962             : 
+     963             : 
+     964             : // CoeffsMatrix* Optimizer::switchToDiagonalHessian(VesBias* bias_pntr_in) {
+     965             : //   plumed_massert(use_hessian_,"it does not make sense to switch to diagonal Hessian if it Hessian is not used");
+     966             : //   diagonal_hessian_=true;
+     967             : //   bias_pntr_in->enableHessian(diagonal_hessian_);
+     968             : //   CoeffsMatrix* hessian_pntr_out = bias_pntr_in->getHessianPntr();
+     969             : //   plumed_massert(hessian_pntr_out != NULL,"Hessian is needed but not linked correctly");
+     970             : //   //
+     971             : //   log.printf("  %s (with label %s): switching to a diagonal Hessian for VES bias %s (with label %s) at time  %f\n",getName().c_str(),getLabel().c_str(),bias_pntr_in->getName().c_str(),bias_pntr_in->getLabel().c_str(),getTime());
+     972             : //   return hessian_pntr_out;
+     973             : // }
+     974             : 
+     975             : 
+     976             : // CoeffsMatrix* Optimizer::switchToFullHessian(VesBias* bias_pntr_in) {
+     977             : //   plumed_massert(use_hessian_,"it does not make sense to switch to diagonal Hessian if it Hessian is not used");
+     978             : //   diagonal_hessian_=false;
+     979             : //   bias_pntr_in->enableHessian(diagonal_hessian_);
+     980             : //   CoeffsMatrix* hessian_pntr_out = bias_pntr_in->getHessianPntr();
+     981             : //   plumed_massert(hessian_pntr_out != NULL,"Hessian is needed but not linked correctly");
+     982             : //   //
+     983             : //   log.printf("  %s (with label %s): switching to a diagonal Hessian for VES bias %s (with label %s) at time  %f\n",getName().c_str(),getLabel().c_str(),bias_pntr_in->getName().c_str(),bias_pntr_in->getLabel().c_str(),getTime());
+     984             : //   return hessian_pntr_out;
+     985             : // }
+     986             : 
+     987             : 
+     988       22879 : void Optimizer::update() {
+     989       22879 :   if(onStep() && !isFirstStep) {
+     990       45560 :     for(unsigned int i=0; i<nbiases_; i++) {
+     991       22810 :       bias_pntrs_[i]->updateGradientAndHessian(use_mwalkers_mpi_);
+     992             :     }
+     993       45560 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     994       22810 :       if(gradient_pntrs_[i]->isActive()) {coeffsUpdate(i);}
+     995             :       else {
+     996         190 :         std::string msg = "iteration " + getIterationCounterStr(+1) +
+     997         285 :                           " for " + bias_pntrs_[i]->getLabel() +
+     998          95 :                           " - the coefficients are not updated as CV values are outside the bias intervals";
+     999          95 :         warning(msg);
+    1000             :       }
+    1001             : 
+    1002             :       // +1 as this is done before increaseIterationCounter() is used
+    1003       22810 :       unsigned int curr_iter = getIterationCounter()+1;
+    1004       22810 :       double curr_time = getTime();
+    1005       22810 :       coeffs_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1006             :       aux_coeffs_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1007       22810 :       gradient_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1008       22810 :       targetdist_averages_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1009       22810 :       if(use_hessian_) {
+    1010       22780 :         hessian_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1011             :       }
+    1012       22810 :       if(aver_gradient_pntrs_.size()>0) {
+    1013             :         aver_gradient_pntrs_[i]->setIterationCounterAndTime(curr_iter,curr_time);
+    1014          20 :         aver_gradient_pntrs_[i]->addToAverage(*gradient_pntrs_[i]);
+    1015             :       }
+    1016             :     }
+    1017             :     increaseIterationCounter();
+    1018             : 
+    1019       22750 :     if(ustride_targetdist_>0 && getIterationCounter()%ustride_targetdist_==0) {
+    1020         708 :       for(unsigned int i=0; i<nbiases_; i++) {
+    1021         354 :         if(dynamic_targetdists_[i]) {
+    1022         354 :           bias_pntrs_[i]->updateTargetDistributions();
+    1023             :         }
+    1024             :       }
+    1025             :     }
+    1026       22750 :     if(ustride_reweightfactor_>0 && getIterationCounter()%ustride_reweightfactor_==0) {
+    1027           0 :       for(unsigned int i=0; i<nbiases_; i++) {
+    1028           0 :         bias_pntrs_[i]->updateReweightFactor();
+    1029             :       }
+    1030             :     }
+    1031             : 
+    1032       22750 :     updateOutputComponents();
+    1033       45560 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1034       22810 :       writeOutputFiles(i);
+    1035             :     }
+    1036             :     //
+    1037       22750 :     if(isBiasOutputActive() && getIterationCounter()%getBiasOutputStride()==0) {
+    1038          74 :       writeBiasOutputFiles();
+    1039             :     }
+    1040       22750 :     if(isFesOutputActive() && getIterationCounter()%getFesOutputStride()==0) {
+    1041          74 :       writeFesOutputFiles();
+    1042             :     }
+    1043       22750 :     if(isFesProjOutputActive() && getIterationCounter()%getFesProjOutputStride()==0) {
+    1044          16 :       writeFesProjOutputFiles();
+    1045             :     }
+    1046       22750 :     if(isTargetDistOutputActive() && getIterationCounter()%getTargetDistOutputStride()==0) {
+    1047          36 :       writeTargetDistOutputFiles();
+    1048             :     }
+    1049       22750 :     if(isTargetDistProjOutputActive() && getIterationCounter()%getTargetDistProjOutputStride()==0) {
+    1050           3 :       writeTargetDistProjOutputFiles();
+    1051             :     }
+    1052             :   }
+    1053             :   else {
+    1054         129 :     isFirstStep=false;
+    1055             :   }
+    1056       22879 : }
+    1057             : 
+    1058             : 
+    1059       22750 : void Optimizer::updateOutputComponents() {
+    1060       22750 :   if(ncoeffssets_==1) {
+    1061       22720 :     if(!fixed_stepsize_) {
+    1062          20 :       getPntrToComponent("stepsize")->set( getCurrentStepSize(0) );
+    1063             :     }
+    1064       22720 :     if(monitor_instantaneous_gradient_) {
+    1065          30 :       getPntrToComponent("gradrms")->set( gradient_pntrs_[0]->getRMS() );
+    1066          30 :       size_t gradient_maxabs_idx=0;
+    1067          60 :       getPntrToComponent("gradmax")->set( gradient_pntrs_[0]->getMaxAbsValue(gradient_maxabs_idx) );
+    1068             :     }
+    1069       22720 :     if(aver_gradient_pntrs_.size()>0) {
+    1070          20 :       getPntrToComponent("avergradrms")->set( aver_gradient_pntrs_[0]->getRMS() );
+    1071          20 :       size_t avergradient_maxabs_idx=0;
+    1072          40 :       getPntrToComponent("avergradmax")->set( aver_gradient_pntrs_[0]->getMaxAbsValue(avergradient_maxabs_idx) );
+    1073             :     }
+    1074             :   }
+    1075             :   else {
+    1076         120 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1077         180 :       std::string is=""; Tools::convert(i,is); is = "-" + coeffssetid_prefix_ + is;
+    1078          90 :       if(!fixed_stepsize_) {
+    1079           0 :         getPntrToComponent("stepsize"+is)->set( getCurrentStepSize(i) );
+    1080             :       }
+    1081          90 :       if(monitor_instantaneous_gradient_) {
+    1082          30 :         getPntrToComponent("gradrms"+is)->set( gradient_pntrs_[i]->getRMS() );
+    1083          30 :         size_t gradient_maxabs_idx=0;
+    1084          60 :         getPntrToComponent("gradmax"+is)->set( gradient_pntrs_[i]->getMaxAbsValue(gradient_maxabs_idx) );
+    1085             :       }
+    1086          90 :       if(aver_gradient_pntrs_.size()>0) {
+    1087           0 :         getPntrToComponent("avergradrms"+is)->set( aver_gradient_pntrs_[0]->getRMS() );
+    1088           0 :         size_t avergradient_maxabs_idx=0;
+    1089           0 :         getPntrToComponent("avergradmax"+is)->set( aver_gradient_pntrs_[0]->getMaxAbsValue(avergradient_maxabs_idx) );
+    1090             :       }
+    1091             :     }
+    1092             :   }
+    1093       22750 : }
+    1094             : 
+    1095             : 
+    1096           1 : void Optimizer::turnOffCoeffsOutputFiles() {
+    1097           1 :   coeffsOFiles_.clear();
+    1098           1 : }
+    1099             : 
+    1100             : 
+    1101       22810 : void Optimizer::writeOutputFiles(const unsigned int coeffs_id) {
+    1102       22810 :   if(coeffsOFiles_.size()>0 && iter_counter%coeffs_wstride_==0) {
+    1103         789 :     coeffs_pntrs_[coeffs_id]->writeToFile(*coeffsOFiles_[coeffs_id],aux_coeffs_pntrs_[coeffs_id].get(),false);
+    1104             :   }
+    1105       22810 :   if(gradientOFiles_.size()>0 && iter_counter%gradient_wstride_==0) {
+    1106         720 :     if(aver_gradient_pntrs_.size()==0) {
+    1107         700 :       gradient_pntrs_[coeffs_id]->writeToFile(*gradientOFiles_[coeffs_id],false);
+    1108             :     }
+    1109             :     else {
+    1110          20 :       gradient_pntrs_[coeffs_id]->writeToFile(*gradientOFiles_[coeffs_id],aver_gradient_pntrs_[coeffs_id].get(),false);
+    1111             :     }
+    1112             :   }
+    1113       22810 :   if(hessianOFiles_.size()>0 && iter_counter%hessian_wstride_==0) {
+    1114         660 :     hessian_pntrs_[coeffs_id]->writeToFile(*hessianOFiles_[coeffs_id]);
+    1115             :   }
+    1116       22810 :   if(targetdist_averagesOFiles_.size()>0 && iter_counter%targetdist_averages_wstride_==0) {
+    1117         333 :     targetdist_averages_pntrs_[coeffs_id]->writeToFile(*targetdist_averagesOFiles_[coeffs_id]);
+    1118             :   }
+    1119       22810 : }
+    1120             : 
+    1121             : 
+    1122         388 : void Optimizer::setupOFiles(std::vector<std::string>& fnames, std::vector<std::unique_ptr<OFile>>& OFiles, const bool multi_sim_single_files) {
+    1123         388 :   plumed_assert(ncoeffssets_>0);
+    1124         388 :   OFiles.resize(fnames.size());
+    1125         702 :   for(unsigned int i=0; i<fnames.size(); i++) {
+    1126         314 :     OFiles[i] = Tools::make_unique<OFile>();
+    1127         314 :     OFiles[i]->link(*this);
+    1128         314 :     if(multi_sim_single_files) {
+    1129          48 :       unsigned int r=0;
+    1130          48 :       if(comm.Get_rank()==0) {r=multi_sim_comm.Get_rank();}
+    1131          48 :       comm.Bcast(r,0);
+    1132          48 :       if(r>0) {fnames[i]="/dev/null";}
+    1133          96 :       OFiles[i]->enforceSuffix("");
+    1134             :     }
+    1135         314 :     OFiles[i]->open(fnames[i]);
+    1136         314 :     OFiles[i]->setHeavyFlush();
+    1137             :   }
+    1138         388 : }
+    1139             : 
+    1140             : 
+    1141          14 : void Optimizer::readCoeffsFromFiles(const std::vector<std::string>& fnames, const bool read_aux_coeffs) {
+    1142          14 :   plumed_assert(ncoeffssets_>0);
+    1143          14 :   plumed_assert(fnames.size()==ncoeffssets_);
+    1144          14 :   if(ncoeffssets_==1) {
+    1145          13 :     log.printf("  Read in coefficients from file ");
+    1146             :   }
+    1147             :   else {
+    1148           1 :     log.printf("  Read in coefficients from files:\n");
+    1149             :   }
+    1150          30 :   for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1151          16 :     IFile ifile;
+    1152          16 :     ifile.link(*this);
+    1153          16 :     if(use_mwalkers_mpi_ && mwalkers_mpi_single_files_) {
+    1154           8 :       ifile.enforceSuffix("");
+    1155             :     }
+    1156          16 :     ifile.open(fnames[i]);
+    1157          32 :     if(!ifile.FieldExist(coeffs_pntrs_[i]->getDataLabel())) {
+    1158           0 :       std::string error_msg = "Problem with reading coefficients from file " + ifile.getPath() + ": no field with name " + coeffs_pntrs_[i]->getDataLabel() + "\n";
+    1159           0 :       plumed_merror(error_msg);
+    1160             :     }
+    1161          16 :     size_t ncoeffs_read = coeffs_pntrs_[i]->readFromFile(ifile,false,false);
+    1162          16 :     if(ncoeffssets_==1) {
+    1163          26 :       log.printf("%s (read %zu of %zu values)\n", ifile.getPath().c_str(),ncoeffs_read,coeffs_pntrs_[i]->numberOfCoeffs());
+    1164             :     }
+    1165             :     else {
+    1166           6 :       log.printf("   coefficient set %u: %s (read %zu of %zu values)\n",i,ifile.getPath().c_str(),ncoeffs_read,coeffs_pntrs_[i]->numberOfCoeffs());
+    1167             :     }
+    1168          16 :     ifile.close();
+    1169          16 :     if(read_aux_coeffs) {
+    1170          15 :       ifile.open(fnames[i]);
+    1171          30 :       if(!ifile.FieldExist(aux_coeffs_pntrs_[i]->getDataLabel())) {
+    1172           0 :         std::string error_msg = "Problem with reading coefficients from file " + ifile.getPath() + ": no field with name " + aux_coeffs_pntrs_[i]->getDataLabel() + "\n";
+    1173           0 :         plumed_merror(error_msg);
+    1174             :       }
+    1175          15 :       aux_coeffs_pntrs_[i]->readFromFile(ifile,false,false);
+    1176          15 :       ifile.close();
+    1177             :     }
+    1178             :     else {
+    1179           1 :       AuxCoeffs(i).setValues( Coeffs(i) );
+    1180             :     }
+    1181          16 :   }
+    1182          14 : }
+    1183             : 
+    1184             : 
+    1185          85 : void Optimizer::addCoeffsSetIDsToFilenames(std::vector<std::string>& fnames, std::string& coeffssetid_prefix) {
+    1186          85 :   if(ncoeffssets_==1) {return;}
+    1187             :   //
+    1188           9 :   if(fnames.size()==1) {
+    1189           0 :     fnames.resize(ncoeffssets_,fnames[0]);
+    1190             :   }
+    1191           9 :   plumed_assert(fnames.size()==ncoeffssets_);
+    1192             :   //
+    1193          36 :   for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1194          27 :     std::string is=""; Tools::convert(i,is);
+    1195          54 :     fnames[i] = FileBase::appendSuffix(fnames[i],"."+coeffssetid_prefix_+is);
+    1196             :   }
+    1197             : }
+    1198             : 
+    1199             : 
+    1200          93 : void Optimizer::setAllCoeffsSetIterationCounters() {
+    1201         194 :   for(unsigned int i=0; i<ncoeffssets_; i++) {
+    1202         101 :     coeffs_pntrs_[i]->setIterationCounterAndTime(getIterationCounter(),getTime());
+    1203         101 :     aux_coeffs_pntrs_[i]->setIterationCounterAndTime(getIterationCounter(),getTime());
+    1204         101 :     gradient_pntrs_[i]->setIterationCounterAndTime(getIterationCounter(),getTime());
+    1205         101 :     targetdist_averages_pntrs_[i]->setIterationCounterAndTime(getIterationCounter(),getTime());
+    1206         101 :     if(use_hessian_) {
+    1207           0 :       hessian_pntrs_[i]->setIterationCounterAndTime(getIterationCounter(),getTime());
+    1208             :     }
+    1209             :   }
+    1210          93 : }
+    1211             : 
+    1212             : 
+    1213          95 : std::string Optimizer::getIterationCounterStr(const int offset) const {
+    1214             :   std::string s;
+    1215          95 :   Tools::convert(getIterationCounter()+offset,s);
+    1216          95 :   return s;
+    1217             : }
+    1218             : 
+    1219             : 
+    1220          75 : void Optimizer::writeBiasOutputFiles() const {
+    1221         156 :   for(unsigned int i=0; i<nbiases_; i++) {
+    1222          81 :     bias_pntrs_[i]->writeBiasToFile();
+    1223             :   }
+    1224          75 : }
+    1225             : 
+    1226             : 
+    1227          75 : void Optimizer::writeFesOutputFiles() const {
+    1228         156 :   for(unsigned int i=0; i<nbiases_; i++) {
+    1229          81 :     bias_pntrs_[i]->writeFesToFile();
+    1230             :   }
+    1231          75 : }
+    1232             : 
+    1233             : 
+    1234          17 : void Optimizer::writeFesProjOutputFiles() const {
+    1235          34 :   for(unsigned int i=0; i<nbiases_; i++) {
+    1236          17 :     bias_pntrs_[i]->writeFesProjToFile();
+    1237             :   }
+    1238          17 : }
+    1239             : 
+    1240             : 
+    1241          38 : void Optimizer::writeTargetDistOutputFiles() const {
+    1242          76 :   for(unsigned int i=0; i<nbiases_; i++) {
+    1243          38 :     if(dynamic_targetdists_[i]) {
+    1244          38 :       bias_pntrs_[i]->writeTargetDistToFile();
+    1245             :     }
+    1246             :   }
+    1247          38 : }
+    1248             : 
+    1249             : 
+    1250           4 : void Optimizer::writeTargetDistProjOutputFiles() const {
+    1251           8 :   for(unsigned int i=0; i<nbiases_; i++) {
+    1252           4 :     if(dynamic_targetdists_[i]) {
+    1253           4 :       bias_pntrs_[i]->writeTargetDistProjToFile();
+    1254             :     }
+    1255             :   }
+    1256           4 : }
+    1257             : 
+    1258             : 
+    1259             : 
+    1260             : }
+    1261             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.h.func-sort-c.html b/coverage/ves/Optimizer.h.func-sort-c.html new file mode 100644 index 000000000000..33b4fbdcb9ec --- /dev/null +++ b/coverage/ves/Optimizer.h.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535694.6 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Optimizer22getNumberOfDerivativesEv0
_ZN4PLMD3ves9Optimizer19parseMultipleValuesIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EE78
_ZN4PLMD3ves9Optimizer19setCurrentStepSizesERKSt6vectorIdSaIdEE78
_ZN4PLMD3ves9Optimizer14parseFilenamesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EES9_158
_ZN4PLMD3ves9Optimizer19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EERKSC_158
_ZN4PLMD3ves9Optimizer14parseFilenamesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EE387
_ZN4PLMD3ves9Optimizer19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EE545
_ZNK4PLMD3ves9Optimizer7HessianEj22735
_ZN4PLMD3ves9Optimizer5applyEv22879
_ZN4PLMD3ves9Optimizer9calculateEv22879
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.h.func.html b/coverage/ves/Optimizer.h.func.html new file mode 100644 index 000000000000..2128b019c42b --- /dev/null +++ b/coverage/ves/Optimizer.h.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535694.6 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9Optimizer14parseFilenamesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EE387
_ZN4PLMD3ves9Optimizer14parseFilenamesERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIS7_SaIS7_EES9_158
_ZN4PLMD3ves9Optimizer19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EE545
_ZN4PLMD3ves9Optimizer19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EERKSC_158
_ZN4PLMD3ves9Optimizer19parseMultipleValuesIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EE78
_ZN4PLMD3ves9Optimizer19setCurrentStepSizesERKSt6vectorIdSaIdEE78
_ZN4PLMD3ves9Optimizer22getNumberOfDerivativesEv0
_ZN4PLMD3ves9Optimizer5applyEv22879
_ZN4PLMD3ves9Optimizer9calculateEv22879
_ZNK4PLMD3ves9Optimizer7HessianEj22735
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/Optimizer.h.gcov.html b/coverage/ves/Optimizer.h.gcov.html new file mode 100644 index 000000000000..2244c31bde16 --- /dev/null +++ b/coverage/ves/Optimizer.h.gcov.html @@ -0,0 +1,431 @@ + + + + + + + + LCOV - plumed test coverage - ves/Optimizer.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - Optimizer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:535694.6 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_Optimizer_h
+      23             : #define __PLUMED_ves_Optimizer_h
+      24             : 
+      25             : #include "VesBias.h"
+      26             : 
+      27             : #include "core/ActionPilot.h"
+      28             : #include "core/ActionWithValue.h"
+      29             : 
+      30             : #include <vector>
+      31             : #include <string>
+      32             : #include <cmath>
+      33             : #include <memory>
+      34             : 
+      35             : 
+      36             : #define PLUMED_VES_OPTIMIZER_INIT(ao) Action(ao),Optimizer(ao)
+      37             : 
+      38             : namespace PLMD {
+      39             : 
+      40             : /**
+      41             : \ingroup INHERIT
+      42             : Abstract base class for implenting new optimization methods
+      43             : */
+      44             : 
+      45             : class OFile;
+      46             : 
+      47             : namespace ves {
+      48             : 
+      49             : class CoeffsVector;
+      50             : class VesBias;
+      51             : 
+      52             : 
+      53             : class Optimizer :
+      54             :   public ActionPilot,
+      55             :   public ActionWithValue
+      56             : {
+      57             : private:
+      58             :   const std::string description_;
+      59             :   const std::string type_;
+      60             :   //
+      61             :   std::vector<double> stepsizes_;
+      62             :   std::vector<double> current_stepsizes;
+      63             :   bool fixed_stepsize_;
+      64             :   //
+      65             :   unsigned int iter_counter;
+      66             :   //
+      67             :   bool use_hessian_;
+      68             :   bool diagonal_hessian_;
+      69             :   bool hessian_covariance_from_averages_;
+      70             :   //
+      71             :   bool monitor_instantaneous_gradient_;
+      72             :   //
+      73             :   bool use_mwalkers_mpi_;
+      74             :   bool mwalkers_mpi_single_files_;
+      75             :   //
+      76             :   std::vector<bool> dynamic_targetdists_;
+      77             :   unsigned int ustride_targetdist_;
+      78             :   //
+      79             :   unsigned int ustride_reweightfactor_;
+      80             :   //
+      81             :   std::string coeffssetid_prefix_;
+      82             :   //
+      83             :   unsigned int coeffs_wstride_;
+      84             :   std::vector<std::unique_ptr<OFile>> coeffsOFiles_;
+      85             :   std::string coeffs_output_fmt_;
+      86             :   //
+      87             :   unsigned int gradient_wstride_;
+      88             :   std::vector<std::unique_ptr<OFile>> gradientOFiles_;
+      89             :   std::string gradient_output_fmt_;
+      90             :   //
+      91             :   unsigned int hessian_wstride_;
+      92             :   std::vector<std::unique_ptr<OFile>> hessianOFiles_;
+      93             :   std::string hessian_output_fmt_;
+      94             :   //
+      95             :   unsigned int targetdist_averages_wstride_;
+      96             :   std::vector<std::unique_ptr<OFile>> targetdist_averagesOFiles_;
+      97             :   std::string targetdist_averages_output_fmt_;
+      98             :   //
+      99             :   unsigned int nbiases_;
+     100             :   std::vector<VesBias*> bias_pntrs_;
+     101             :   //
+     102             :   unsigned int ncoeffssets_;
+     103             :   std::vector<CoeffsVector*> coeffs_pntrs_;
+     104             :   std::vector<std::unique_ptr<CoeffsVector>> aux_coeffs_pntrs_;
+     105             :   std::vector<CoeffsVector*> gradient_pntrs_;
+     106             :   std::vector<std::unique_ptr<CoeffsVector>> aver_gradient_pntrs_;
+     107             :   std::vector<CoeffsMatrix*> hessian_pntrs_;
+     108             :   std::vector<std::unique_ptr<CoeffsVector>> coeffs_mask_pntrs_;
+     109             :   std::vector<CoeffsVector*> targetdist_averages_pntrs_;
+     110             :   //
+     111             :   bool identical_coeffs_shape_;
+     112             :   //
+     113             :   bool bias_output_active_;
+     114             :   unsigned int bias_output_stride_;
+     115             :   bool fes_output_active_;
+     116             :   unsigned int fes_output_stride_;
+     117             :   bool fesproj_output_active_;
+     118             :   unsigned int fesproj_output_stride_;
+     119             :   bool targetdist_output_active_;
+     120             :   unsigned int targetdist_output_stride_;
+     121             :   bool targetdist_proj_output_active_;
+     122             :   unsigned int targetdist_proj_output_stride_;
+     123             :   //
+     124             :   bool isFirstStep;
+     125             :   //
+     126             : private:
+     127             :   void updateOutputComponents();
+     128             :   void writeOutputFiles(const unsigned int coeffs_id = 0);
+     129             :   void readCoeffsFromFiles(const std::vector<std::string>&, const bool);
+     130             :   void setAllCoeffsSetIterationCounters();
+     131             : protected:
+     132             :   void turnOnHessian();
+     133             :   void turnOffHessian();
+     134             :   std::vector<CoeffsMatrix*> enableHessian(VesBias*, const bool diagonal_hessian=false);
+     135             :   // CoeffsMatrix* switchToDiagonalHessian(VesBias*);
+     136             :   // CoeffsMatrix* switchToFullHessian(VesBias*);
+     137             :   //
+     138             :   CoeffsVector& Coeffs(const unsigned int coeffs_id = 0) const;
+     139             :   CoeffsVector& AuxCoeffs(const unsigned int coeffs_id = 0) const;
+     140             :   CoeffsVector& Gradient(const unsigned int coeffs_id = 0) const;
+     141             :   CoeffsMatrix& Hessian(const unsigned int coeffs_id = 0) const;
+     142             :   CoeffsVector& CoeffsMask(const unsigned int coeffs_id = 0) const;
+     143             :   CoeffsVector& TargetDistAverages(const unsigned int coeffs_id = 0) const;
+     144             :   double StepSize(const unsigned int coeffs_id = 0) const;
+     145             :   virtual void coeffsUpdate(const unsigned int coeffs_id = 0) = 0;
+     146             :   void setCurrentStepSize(const double,const unsigned int i = 0);
+     147             :   void setCurrentStepSizes(const std::vector<double>&);
+     148             :   //
+     149             :   void turnOffCoeffsOutputFiles();
+     150             :   //
+     151             :   template<class T>
+     152             :   bool parseMultipleValues(const std::string&, std::vector<T>&);
+     153             :   template<class T>
+     154             :   bool parseMultipleValues(const std::string&, std::vector<T>&, const T&);
+     155             :   void parseFilenames(const std::string&, std::vector<std::string>&, const std::string&);
+     156             :   void parseFilenames(const std::string&, std::vector<std::string>&);
+     157             :   void addCoeffsSetIDsToFilenames(std::vector<std::string>&, std::string&);
+     158             :   void setupOFiles(std::vector<std::string>&, std::vector<std::unique_ptr<OFile>>&, const bool multi_sim_single_files=false);
+     159             : public:
+     160             :   static void registerKeywords(Keywords&);
+     161             :   static void useMultipleWalkersKeywords(Keywords&);
+     162             :   static void useHessianKeywords(Keywords&);
+     163             :   static void useFixedStepSizeKeywords(Keywords&);
+     164             :   static void useDynamicStepSizeKeywords(Keywords&);
+     165             :   static void useMaskKeywords(Keywords&);
+     166             :   static void useRestartKeywords(Keywords&);
+     167             :   static void useMonitorAverageGradientKeywords(Keywords&);
+     168             :   static void useDynamicTargetDistributionKeywords(Keywords&);
+     169             :   static void useReweightFactorKeywords(Keywords&);
+     170             :   //
+     171             :   explicit Optimizer(const ActionOptions&ao);
+     172             :   ~Optimizer();
+     173             :   std::string getType() const {return type_;}
+     174             :   std::string getDescription() const {return description_;}
+     175             :   //
+     176             :   unsigned int numberOfBiases() const {return nbiases_;}
+     177          16 :   unsigned int numberOfCoeffsSets() const {return ncoeffssets_;}
+     178             :   //
+     179             :   std::vector<double> getStepSizes() const;
+     180             :   std::vector<double> getCurrentStepSizes() const;
+     181             :   double getStepSize(const unsigned int coeffs_id = 0) const;
+     182             :   double getCurrentStepSize(const unsigned int coeffs_id = 0) const;
+     183             :   void setStepSizes(const std::vector<double>&);
+     184             :   void setStepSize(const double, const unsigned int coeffs_id = 0);
+     185             :   //
+     186             :   unsigned int getIterationCounter() const;
+     187             :   double getIterationCounterDbl() const;
+     188             :   std::string getIterationCounterStr(const int offset=0) const;
+     189             :   void setIterationCounter(const unsigned int);
+     190             :   void increaseIterationCounter();
+     191             :   //
+     192       22879 :   void apply() override {};
+     193       22879 :   void calculate() override {};
+     194             :   void update() override;
+     195           0 :   unsigned int getNumberOfDerivatives() override {return 0;}
+     196             :   //
+     197             :   bool fixedStepSize() const {return fixed_stepsize_;}
+     198             :   bool dynamicStepSize() const {return !fixed_stepsize_;}
+     199             :   //
+     200             :   bool useHessian() const {return use_hessian_;}
+     201             :   bool diagonalHessian() const {return diagonal_hessian_;}
+     202             :   //
+     203         609 :   bool useMultipleWalkers() const {return use_mwalkers_mpi_;}
+     204             :   //
+     205             :   std::vector<VesBias*> getBiasPntrs() const {return bias_pntrs_;}
+     206             :   std::vector<CoeffsVector*> getCoeffsPntrs() const {return coeffs_pntrs_;}
+     207             :   std::vector<CoeffsVector*> getAuxCoeffsPntrs() const {return Tools::unique2raw(aux_coeffs_pntrs_);}
+     208          12 :   std::vector<CoeffsVector*> getGradientPntrs()const {return gradient_pntrs_;}
+     209             :   std::vector<CoeffsMatrix*> getHessianPntrs() const {return hessian_pntrs_;}
+     210             :   std::vector<CoeffsVector*> getCoeffsMaskPntrs() const {return Tools::unique2raw(coeffs_mask_pntrs_);}
+     211             :   std::vector<CoeffsVector*> getTargetDistAveragesPntrs() const {return targetdist_averages_pntrs_;}
+     212             :   //
+     213       22829 :   bool isBiasOutputActive() const {return bias_output_active_;}
+     214         814 :   unsigned int getBiasOutputStride() const {return bias_output_stride_;}
+     215             :   void setBiasOutputStride(unsigned int stride) {bias_output_stride_=stride;}
+     216             :   void writeBiasOutputFiles() const;
+     217             :   //
+     218       22829 :   bool isFesOutputActive() const {return fes_output_active_;}
+     219         814 :   unsigned int getFesOutputStride() const {return fes_output_stride_;}
+     220             :   void setFesOutputStride(unsigned int stride) {fes_output_stride_=stride;}
+     221             :   void writeFesOutputFiles() const;
+     222             :   //
+     223       22829 :   bool isFesProjOutputActive() const {return fesproj_output_active_;}
+     224         176 :   unsigned int getFesProjOutputStride() const {return fesproj_output_stride_;}
+     225             :   void setFesProjOutputStride(unsigned int stride) {fesproj_output_stride_=stride;}
+     226             :   void writeFesProjOutputFiles() const;
+     227             :   //
+     228       22908 :   bool isTargetDistOutputActive() const {return targetdist_output_active_;}
+     229       22367 :   unsigned int getTargetDistOutputStride() const {return targetdist_output_stride_;}
+     230             :   void setTargetDistOutputStride(unsigned int stride) {targetdist_output_stride_=stride;}
+     231             :   void writeTargetDistOutputFiles() const;
+     232             :   //
+     233       22829 :   bool isTargetDistProjOutputActive() const {return targetdist_proj_output_active_;}
+     234          33 :   unsigned int getTargetDistProjOutputStride() const {return targetdist_proj_output_stride_;}
+     235             :   void setTargetDistProjOutputStride(unsigned int stride) {targetdist_proj_output_stride_=stride;}
+     236             :   void writeTargetDistProjOutputFiles() const;
+     237             :   //
+     238             : };
+     239             : 
+     240             : inline
+     241       22705 : double Optimizer::StepSize(const unsigned int coeffs_id) const {return stepsizes_[coeffs_id];}
+     242             : 
+     243             : inline
+     244       68214 : CoeffsVector& Optimizer::Coeffs(const unsigned int coeffs_id) const {return *coeffs_pntrs_[coeffs_id];}
+     245             : 
+     246             : inline
+     247          21 : CoeffsVector& Optimizer::AuxCoeffs(const unsigned int coeffs_id) const {return *aux_coeffs_pntrs_[coeffs_id];}
+     248             : 
+     249             : inline
+     250       22785 : CoeffsVector& Optimizer::Gradient(const unsigned int coeffs_id) const {return *gradient_pntrs_[coeffs_id];}
+     251             : 
+     252             : inline
+     253       22735 : CoeffsMatrix& Optimizer::Hessian(const unsigned int coeffs_id) const {
+     254       22735 :   plumed_massert(use_hessian_,"You cannot use the Hessian without asking for before");
+     255       22735 :   return *hessian_pntrs_[coeffs_id];
+     256             : }
+     257             : 
+     258             : inline
+     259             : CoeffsVector& Optimizer::CoeffsMask(const unsigned int coeffs_id) const {return *coeffs_mask_pntrs_[coeffs_id];}
+     260             : 
+     261             : inline
+     262             : std::vector<double> Optimizer::getStepSizes() const {return stepsizes_;}
+     263             : 
+     264             : inline
+     265             : std::vector<double> Optimizer::getCurrentStepSizes() const {return current_stepsizes;}
+     266             : 
+     267             : inline
+     268             : double Optimizer::getStepSize(const unsigned int coeffs_id) const {return stepsizes_[coeffs_id];}
+     269             : 
+     270             : inline
+     271          11 : double Optimizer::getCurrentStepSize(const unsigned int coeffs_id) const {return current_stepsizes[coeffs_id];}
+     272             : 
+     273             : inline
+     274             : void Optimizer::setStepSizes(const std::vector<double>& stepsizes_in) {
+     275             :   plumed_assert(stepsizes_in.size()==ncoeffssets_);
+     276             :   stepsizes_ = stepsizes_in;
+     277             : }
+     278             : 
+     279             : inline
+     280             : void Optimizer::setStepSize(const double stepsize_in, const unsigned int coeffs_id) {
+     281             :   stepsizes_[coeffs_id] = stepsize_in;
+     282             : }
+     283             : 
+     284             : inline
+     285             : void Optimizer::setCurrentStepSize(const double current_stepsize_in, const unsigned int coeffs_id) {
+     286          10 :   current_stepsizes[coeffs_id] = current_stepsize_in;
+     287             : }
+     288             : 
+     289             : inline
+     290          78 : void Optimizer::setCurrentStepSizes(const std::vector<double>& current_stepsizes_in) {
+     291          78 :   plumed_assert(current_stepsizes_in.size()==ncoeffssets_);
+     292          78 :   current_stepsizes = current_stepsizes_in;
+     293          78 : }
+     294             : 
+     295             : inline
+     296       48388 : unsigned int Optimizer::getIterationCounter() const {return iter_counter;}
+     297             : 
+     298             : inline
+     299       22695 : double Optimizer::getIterationCounterDbl() const {return static_cast<double>(iter_counter);}
+     300             : 
+     301             : inline
+     302       22750 : void Optimizer::increaseIterationCounter() {iter_counter++;}
+     303             : 
+     304             : inline
+     305          13 : void Optimizer::setIterationCounter(const unsigned int iter_counter_in) {iter_counter = iter_counter_in;}
+     306             : 
+     307             : 
+     308             : template<class T>
+     309         623 : bool Optimizer::parseMultipleValues(const std::string& keyword, std::vector<T>& values) {
+     310         623 :   plumed_assert(ncoeffssets_>0);
+     311         623 :   plumed_assert(values.size()==0);
+     312             :   bool identical_values=false;
+     313             :   //
+     314         623 :   parseVector(keyword,values);
+     315         623 :   if(values.size()==1 && ncoeffssets_>1) {
+     316           9 :     values.resize(ncoeffssets_,values[0]);
+     317             :     identical_values=true;
+     318             :   }
+     319         623 :   if(values.size()>0 && values.size()!=ncoeffssets_) {
+     320           0 :     std::string s1; Tools::convert(ncoeffssets_,s1);
+     321           0 :     plumed_merror("Error in " + keyword + " keyword: either give 1 common value for all coefficient sets or " + s1 + " separate value for each set");
+     322             :   }
+     323         623 :   return identical_values;
+     324             : }
+     325             : 
+     326             : template<class T>
+     327         158 : bool Optimizer::parseMultipleValues(const std::string& keyword, std::vector<T>& values, const T& default_value) {
+     328         158 :   bool identical_values = parseMultipleValues(keyword,values);
+     329         158 :   if(values.size()==0) {
+     330          79 :     values.resize(ncoeffssets_,default_value);
+     331             :     identical_values=true;
+     332             :   }
+     333         158 :   return identical_values;
+     334             : }
+     335             : 
+     336             : inline
+     337         158 : void Optimizer::parseFilenames(const std::string& keyword, std::vector<std::string>& fnames, const std::string& default_fname) {
+     338         158 :   if(parseMultipleValues<std::string>(keyword,fnames,default_fname)) {
+     339          81 :     addCoeffsSetIDsToFilenames(fnames,coeffssetid_prefix_);
+     340             :   }
+     341         158 : }
+     342             : 
+     343             : inline
+     344         387 : void Optimizer::parseFilenames(const std::string& keyword, std::vector<std::string>& fnames) {
+     345         387 :   if(parseMultipleValues<std::string>(keyword,fnames)) {
+     346           4 :     addCoeffsSetIDsToFilenames(fnames,coeffssetid_prefix_);
+     347             :   }
+     348         387 : }
+     349             : 
+     350             : 
+     351             : }
+     352             : }
+     353             : 
+     354             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html b/coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html new file mode 100644 index 000000000000..e8dc50177695 --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputBasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputBasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10811098.2 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20OutputBasisFunctions5applyEv0
_ZN4PLMD3ves20OutputBasisFunctions9calculateEv0
_ZN4PLMD3ves20OutputBasisFunctionsC2ERKNS_13ActionOptionsE71
_ZN4PLMD3ves20OutputBasisFunctions16registerKeywordsERNS_8KeywordsE73
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputBasisFunctions.cpp.func.html b/coverage/ves/OutputBasisFunctions.cpp.func.html new file mode 100644 index 000000000000..127c6044f917 --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputBasisFunctions.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputBasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10811098.2 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20OutputBasisFunctions16registerKeywordsERNS_8KeywordsE73
_ZN4PLMD3ves20OutputBasisFunctions5applyEv0
_ZN4PLMD3ves20OutputBasisFunctions9calculateEv0
_ZN4PLMD3ves20OutputBasisFunctionsC2ERKNS_13ActionOptionsE71
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputBasisFunctions.cpp.gcov.html b/coverage/ves/OutputBasisFunctions.cpp.gcov.html new file mode 100644 index 000000000000..4f3db2d52ff1 --- /dev/null +++ b/coverage/ves/OutputBasisFunctions.cpp.gcov.html @@ -0,0 +1,313 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputBasisFunctions.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputBasisFunctions.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10811098.2 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "BasisFunctions.h"
+      24             : #include "TargetDistribution.h"
+      25             : 
+      26             : #include "CoeffsVector.h"
+      27             : #include "VesTools.h"
+      28             : 
+      29             : #include "core/ActionRegister.h"
+      30             : #include "core/ActionSet.h"
+      31             : #include "core/PlumedMain.h"
+      32             : #include "core/Value.h"
+      33             : #include "tools/File.h"
+      34             : #include "tools/Grid.h"
+      35             : 
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace ves {
+      39             : 
+      40             : //+PLUMEDOC VES_UTILS VES_OUTPUT_BASISFUNCTIONS
+      41             : /*
+      42             : Output basis functions to file.
+      43             : 
+      44             : This action can be used to write out to a grid file the values and derivatives of
+      45             : given basis functions. This is normally used for debugging when programming new
+      46             : types of basis functions. For example, it is possible to calculate the
+      47             : derivatives numerically and compare to the analytically calculated
+      48             : derivatives.
+      49             : 
+      50             : This action is normally used through the \ref driver.
+      51             : 
+      52             : \par Examples
+      53             : 
+      54             : In the following input we define a Legendre polynomials basis functions
+      55             : of order 14 over the interval -4.0 to 4.0 and output their values
+      56             : and derivatives to files called bfL.values.data and bfL.derivs.data.
+      57             : \plumedfile
+      58             : BF_LEGENDRE ...
+      59             :  ORDER=14
+      60             :  MINIMUM=-4.0
+      61             :  MAXIMUM=4.0
+      62             :  LABEL=bfL
+      63             : ... BF_LEGENDRE
+      64             : 
+      65             : VES_OUTPUT_BASISFUNCTIONS ...
+      66             :  BASIS_FUNCTIONS=bfL
+      67             :  GRID_BINS=200
+      68             :  FORMAT_VALUES_DERIVS=%13.6f
+      69             : ... VES_OUTPUT_BASISFUNCTIONS
+      70             : \endplumedfile
+      71             : 
+      72             : This input should be run through the driver by using a command similar to the
+      73             : following one where the trajectory/configuration file configuration.gro is needed to
+      74             : trick the code to exit correctly.
+      75             : \verbatim
+      76             : plumed driver --plumed plumed.dat --igro configuration.gro
+      77             : \endverbatim
+      78             : 
+      79             : */
+      80             : //+ENDPLUMEDOC
+      81             : 
+      82             : 
+      83             : class OutputBasisFunctions :
+      84             :   public Action
+      85             : {
+      86             :   std::vector<BasisFunctions*> bf_pntrs;
+      87             : public:
+      88             :   explicit OutputBasisFunctions(const ActionOptions&);
+      89             :   TargetDistribution* setupTargetDistPntr(std::string keyword) const;
+      90           0 :   void calculate() override {}
+      91           0 :   void apply() override {}
+      92             :   static void registerKeywords(Keywords& keys);
+      93             : };
+      94             : 
+      95             : 
+      96             : PLUMED_REGISTER_ACTION(OutputBasisFunctions,"VES_OUTPUT_BASISFUNCTIONS")
+      97             : 
+      98          73 : void OutputBasisFunctions::registerKeywords(Keywords& keys) {
+      99          73 :   Action::registerKeywords(keys);
+     100         146 :   keys.add("compulsory","BASIS_FUNCTIONS","the label of the basis functions that you want to use");
+     101         146 :   keys.add("optional","GRID_BINS","the number of bins used for the grid for writing the basis function values and derivatives. The default value is 1000.");
+     102         146 :   keys.add("optional","GRID_MIN","the minimum of the grid for writing the basis function values and derivatives. By default it is the minimum of the interval on which the basis functions are defined.");
+     103         146 :   keys.add("optional","GRID_MAX","the maximum of the grid for writing the basis function values and derivatives. By default it is the maximum of the interval on which the basis functions are defined.");
+     104         146 :   keys.add("optional","FILE_VALUES","filename of the file on which the basis function values are written. By default it is BF_LABEL.values.data.");
+     105         146 :   keys.add("optional","FILE_DERIVS","filename of the file on which the basis function derivatives are written. By default it is BF_LABEL.derivs.data.");
+     106         146 :   keys.add("optional","FORMAT_VALUES_DERIVS","the numerical format of the basis function values and derivatives written to file. By default it is %15.8f.\n. You can also use FORMAT_VALUES and FORMAT_DERIVS to give the numerical formats separately.");
+     107         146 :   keys.add("optional","FORMAT_VALUES","the numerical format of the basis function derivatives written to file. By default it is %15.8f.\n");
+     108         146 :   keys.add("optional","FORMAT_DERIVS","the numerical format of the basis function values written to file. By default it is %15.8f.\n");
+     109         146 :   keys.add("optional","FILE_TARGETDIST_AVERAGES","filename of the file on which the averages over the target distributions are written. By default it is BF_LABEL.targetdist-averages.data.");
+     110         146 :   keys.add("optional","FORMAT_TARGETDIST_AVERAGES","the numerical format of the target distribution averages written to file. By default it is %15.8f.\n");
+     111         146 :   keys.add("optional","FILE_TARGETDIST","filename of the files on which the target distributions are written. By default it is BF_LABEL.targetdist-#.data.");
+     112         146 :   keys.add("numbered","TARGET_DISTRIBUTION","the target distribution to be used.");
+     113         146 :   keys.addFlag("IGNORE_PERIODICITY",false,"if the periodicity of the basis functions should be ignored.");
+     114         146 :   keys.addFlag("NUMERICAL_DERIVATIVES",false,"if the derivatives of the basis functions should be calculated numerically.");
+     115          73 : }
+     116             : 
+     117          71 : OutputBasisFunctions::OutputBasisFunctions(const ActionOptions&ao):
+     118             :   Action(ao),
+     119          71 :   bf_pntrs(0)
+     120             : {
+     121          71 :   std::vector<std::string> basisset_labels(0);
+     122         142 :   parseVector("BASIS_FUNCTIONS",basisset_labels);
+     123          71 :   if(basisset_labels.size()>1) {plumed_merror("Only one basis set label allowed in keyword BASIS_FUNCTIONS of "+getName());}
+     124             : 
+     125          71 :   std::string error_msg = "";
+     126         142 :   bf_pntrs = VesTools::getPointersFromLabels<BasisFunctions*>(basisset_labels,plumed.getActionSet(),error_msg);
+     127          71 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BASIS_FUNCTIONS of "+getName()+": "+error_msg);}
+     128             : 
+     129          71 :   unsigned int nbins = 1000;
+     130         142 :   parse("GRID_BINS",nbins);
+     131             : 
+     132          71 :   std::string min_str = bf_pntrs[0]->intervalMinStr();
+     133          71 :   std::string max_str = bf_pntrs[0]->intervalMaxStr();
+     134          71 :   parse("GRID_MIN",min_str);
+     135         142 :   parse("GRID_MAX",max_str);
+     136             : 
+     137          71 :   std::string fname_values = bf_pntrs[0]->getLabel()+".values.data";
+     138         142 :   parse("FILE_VALUES",fname_values);
+     139          71 :   std::string fname_derives = bf_pntrs[0]->getLabel()+".derivs.data";
+     140         142 :   parse("FILE_DERIVS",fname_derives);
+     141          71 :   std::string fname_targetdist_aver = bf_pntrs[0]->getLabel()+".targetdist-averages.data";
+     142         142 :   parse("FILE_TARGETDIST_AVERAGES",fname_targetdist_aver);
+     143          71 :   std::string fname_targetdist = bf_pntrs[0]->getLabel()+".targetdist-.data";
+     144          71 :   parse("FILE_TARGETDIST",fname_targetdist);
+     145             : 
+     146          71 :   std::string fmt_values_derivs = "%15.8f";
+     147          71 :   parse("FORMAT_VALUES_DERIVS",fmt_values_derivs);
+     148          71 :   std::string fmt_values = fmt_values_derivs;
+     149          71 :   std::string fmt_derivs = fmt_values_derivs;
+     150          71 :   parse("FORMAT_VALUES",fmt_values);
+     151          71 :   parse("FORMAT_DERIVS",fmt_derivs);
+     152             : 
+     153          71 :   std::string fmt_targetdist_aver = "%15.8f";
+     154          71 :   parse("FORMAT_TARGETDIST_AVERAGES",fmt_targetdist_aver);
+     155             : 
+     156          71 :   bool ignore_periodicity = false;
+     157          71 :   parseFlag("IGNORE_PERIODICITY",ignore_periodicity);
+     158             : 
+     159          71 :   bool numerical_deriv = false;
+     160         142 :   parseFlag("NUMERICAL_DERIVATIVES",numerical_deriv);
+     161             : 
+     162             :   std::vector<TargetDistribution*> targetdist_pntrs;
+     163          71 :   targetdist_pntrs.push_back(NULL);
+     164          71 :   std::string targetdist_label="";
+     165         176 :   for(int i=1;; i++) {
+     166         494 :     if(!parseNumbered("TARGET_DISTRIBUTION",i,targetdist_label)) {break;}
+     167         176 :     std::string error_msg = "";
+     168         176 :     TargetDistribution* pntr_tmp = VesTools::getPointerFromLabel<TargetDistribution*>(targetdist_label,plumed.getActionSet(),error_msg);
+     169         176 :     if(error_msg.size()>0) {plumed_merror("Error in keyword TARGET_DISTRIBUTION of "+getName()+": "+error_msg);}
+     170         176 :     targetdist_pntrs.push_back(pntr_tmp);
+     171         176 :   }
+     172          71 :   checkRead();
+     173             :   //
+     174          71 :   OFile ofile_values;
+     175          71 :   ofile_values.link(*this);
+     176          71 :   ofile_values.enforceBackup();
+     177          71 :   ofile_values.open(fname_values);
+     178          71 :   OFile ofile_derivs;
+     179          71 :   ofile_derivs.link(*this);
+     180          71 :   ofile_derivs.enforceBackup();
+     181          71 :   ofile_derivs.open(fname_derives);
+     182          71 :   bf_pntrs[0]->writeBasisFunctionsToFile(ofile_values,ofile_derivs,min_str,max_str,nbins,ignore_periodicity,fmt_values,fmt_derivs,numerical_deriv);
+     183          71 :   ofile_values.close();
+     184          71 :   ofile_derivs.close();
+     185             :   //
+     186          71 :   std::vector<std::string> grid_min(1); grid_min[0]=bf_pntrs[0]->intervalMinStr();
+     187          71 :   std::vector<std::string> grid_max(1); grid_max[0]=bf_pntrs[0]->intervalMaxStr();
+     188          71 :   std::vector<unsigned int> grid_bins(1); grid_bins[0]=nbins;
+     189          71 :   std::vector<std::unique_ptr<Value>> arguments(1);
+     190         142 :   arguments[0]= Tools::make_unique<Value>(nullptr,"arg",false);
+     191          71 :   if(bf_pntrs[0]->arePeriodic() && !ignore_periodicity) {
+     192          46 :     arguments[0]->setDomain(bf_pntrs[0]->intervalMinStr(),bf_pntrs[0]->intervalMaxStr());
+     193             :   }
+     194             :   else {
+     195          48 :     arguments[0]->setNotPeriodic();
+     196             :   }
+     197             : 
+     198          71 :   OFile ofile_targetdist_aver;
+     199          71 :   ofile_targetdist_aver.link(*this);
+     200          71 :   ofile_targetdist_aver.enforceBackup();
+     201          71 :   ofile_targetdist_aver.open(fname_targetdist_aver);
+     202             : 
+     203         318 :   for(unsigned int i=0; i<targetdist_pntrs.size(); i++) {
+     204         247 :     std::string is; Tools::convert(i,is);
+     205             :     //
+     206         247 :     if(targetdist_pntrs[i]!=NULL) {
+     207         352 :       targetdist_pntrs[i]->setupGrids(Tools::unique2raw(arguments),grid_min,grid_max,grid_bins);
+     208         176 :       plumed_massert(targetdist_pntrs[i]->getDimension()==1,"the target distribution must be one dimensional");
+     209         176 :       targetdist_pntrs[i]->updateTargetDist();
+     210             :     }
+     211             :     //
+     212         247 :     std::vector<double> bf_integrals = bf_pntrs[0]->getTargetDistributionIntegrals(targetdist_pntrs[i]);
+     213         494 :     CoeffsVector targetdist_averages = CoeffsVector("aver.targetdist-"+is,Tools::unique2raw(arguments),bf_pntrs,comm,false);
+     214         247 :     targetdist_averages.setValues(bf_integrals);
+     215         247 :     if(fmt_targetdist_aver.size()>0) {targetdist_averages.setOutputFmt(fmt_targetdist_aver);}
+     216         247 :     targetdist_averages.writeToFile(ofile_targetdist_aver,true);
+     217         247 :     if(targetdist_pntrs[i]!=NULL) {
+     218             :       Grid* targetdist_grid_pntr = targetdist_pntrs[i]->getTargetDistGridPntr();
+     219         176 :       std::string fname = FileBase::appendSuffix(fname_targetdist,is);
+     220         176 :       OFile ofile;
+     221         176 :       ofile.link(*this);
+     222         176 :       ofile.enforceBackup();
+     223         176 :       ofile.open(fname);
+     224         176 :       targetdist_grid_pntr->writeToFile(ofile);
+     225         176 :       ofile.close();
+     226         176 :     }
+     227         247 :   }
+     228          71 :   ofile_targetdist_aver.close();
+     229             : 
+     230             : 
+     231         213 : }
+     232             : 
+     233             : 
+     234             : 
+     235             : }
+     236             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputFesBias.cpp.func-sort-c.html b/coverage/ves/OutputFesBias.cpp.func-sort-c.html new file mode 100644 index 000000000000..37a2f7d9d22a --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputFesBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputFesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606888.2 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves13OutputFesBias5applyEv0
_ZN4PLMD3ves13OutputFesBias6updateEv0
_ZN4PLMD3ves13OutputFesBias9calculateEv0
_ZN4PLMD3ves13OutputFesBiasC2ERKNS_13ActionOptionsE3
_ZN4PLMD3ves13OutputFesBias16registerKeywordsERNS_8KeywordsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputFesBias.cpp.func.html b/coverage/ves/OutputFesBias.cpp.func.html new file mode 100644 index 000000000000..36da65c07428 --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputFesBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputFesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606888.2 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves13OutputFesBias16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD3ves13OutputFesBias5applyEv0
_ZN4PLMD3ves13OutputFesBias6updateEv0
_ZN4PLMD3ves13OutputFesBias9calculateEv0
_ZN4PLMD3ves13OutputFesBiasC2ERKNS_13ActionOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputFesBias.cpp.gcov.html b/coverage/ves/OutputFesBias.cpp.gcov.html new file mode 100644 index 000000000000..8f0b6a7584a6 --- /dev/null +++ b/coverage/ves/OutputFesBias.cpp.gcov.html @@ -0,0 +1,307 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputFesBias.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputFesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:606888.2 %
Date:2024-02-22 21:58:45Functions:2540.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "CoeffsVector.h"
+      24             : #include "VesTools.h"
+      25             : #include "VesBias.h"
+      26             : 
+      27             : 
+      28             : #include "tools/File.h"
+      29             : #include "core/ActionRegister.h"
+      30             : #include "core/PlumedMain.h"
+      31             : 
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace ves {
+      35             : 
+      36             : //+PLUMEDOC VES_UTILS VES_OUTPUT_FES
+      37             : /*
+      38             : Tool to output biases and free energy surfaces for VES biases from previously obtained coefficients.
+      39             : 
+      40             : This action can be used to output to file biases and free energy surfaces for VES biases from
+      41             : previously obtained coefficients. It should be used through the \ref driver and
+      42             : can only be used in post processing. The VES bias needs to be defined in the
+      43             : exact same way as during the simulation. At the current moment this action does
+      44             : not support dynamic target distributions (e.g. well-tempered).
+      45             : 
+      46             : \par Examples
+      47             : 
+      48             : In the following input we define a VES bias and then read in the coefficient
+      49             : file coeffs.input.data and output the FES and bias every 500 iterations.
+      50             : 
+      51             : \plumedfile
+      52             : phi:   TORSION ATOMS=5,7,9,15
+      53             : psi:   TORSION ATOMS=7,9,15,17
+      54             : 
+      55             : bf1: BF_FOURIER ORDER=5 MINIMUM=-pi MAXIMUM=pi
+      56             : bf2: BF_FOURIER ORDER=5 MINIMUM=-pi MAXIMUM=pi
+      57             : 
+      58             : VES_LINEAR_EXPANSION ...
+      59             :  ARG=phi,psi
+      60             :  BASIS_FUNCTIONS=bf1,bf2
+      61             :  LABEL=ves1
+      62             :  GRID_BINS=100,100
+      63             :  PROJ_ARG1=phi
+      64             :  PROJ_ARG2=psi
+      65             : ... VES_LINEAR_EXPANSION
+      66             : 
+      67             : VES_OUTPUT_FES ...
+      68             :   BIAS=ves1
+      69             :   FES_OUTPUT=500
+      70             :   FES_PROJ_OUTPUT=500
+      71             :   BIAS_OUTPUT=500
+      72             :   COEFFS_INPUT=coeffs.input.data
+      73             : ... VES_OUTPUT_FES
+      74             : \endplumedfile
+      75             : 
+      76             : The header of coeffs.input.data should look like the following:
+      77             : 
+      78             : \auxfile{coeffs.input.data}
+      79             : #! FIELDS idx_phi idx_psi ves1.coeffs ves1.aux_coeffs index
+      80             : #! SET time 100.000000
+      81             : #! SET iteration  10
+      82             : #! SET type LinearBasisSet
+      83             : #! SET ndimensions  2
+      84             : #! SET ncoeffs_total  121
+      85             : #! SET shape_phi  11
+      86             : #! SET shape_psi  11
+      87             : \endauxfile
+      88             : 
+      89             : This input should be run through the driver by using a command similar to the
+      90             : following one where the trajectory/configuration file configuration.gro is needed to
+      91             : correctly define the CVs
+      92             : \verbatim
+      93             : plumed driver --plumed plumed.dat --igro configuration.gro
+      94             : \endverbatim
+      95             : 
+      96             : */
+      97             : //+ENDPLUMEDOC
+      98             : 
+      99             : class OutputFesBias : public Action {
+     100             : 
+     101             : public:
+     102             :   static void registerKeywords(Keywords&);
+     103             :   explicit OutputFesBias(const ActionOptions&);
+     104           0 :   void update() override {}
+     105           0 :   void calculate() override {}
+     106           0 :   void apply() override {}
+     107             : };
+     108             : 
+     109             : 
+     110             : PLUMED_REGISTER_ACTION(OutputFesBias,"VES_OUTPUT_FES")
+     111             : 
+     112             : 
+     113           5 : void OutputFesBias::registerKeywords(Keywords& keys) {
+     114          10 :   keys.add("compulsory","BIAS","the label of the VES bias for to output the free energy surfaces and the bias files");
+     115          10 :   keys.add("compulsory","COEFFS_INPUT","the name of input coefficient file");
+     116          10 :   keys.add("optional","BIAS_OUTPUT","how often the bias(es) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     117          10 :   keys.add("optional","FES_OUTPUT","how often the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     118          10 :   keys.add("optional","FES_PROJ_OUTPUT","how often the projections of the FES(s) should be written out to file. Note that the value is given in terms of coefficient iterations.");
+     119             :   //
+     120           5 : }
+     121             : 
+     122             : 
+     123           3 : OutputFesBias::OutputFesBias(const ActionOptions&ao):
+     124           3 :   Action(ao)
+     125             : {
+     126             : 
+     127             :   std::vector<std::string> bias_labels;
+     128           6 :   parseVector("BIAS",bias_labels);
+     129           3 :   if(bias_labels.size()>1) {
+     130           0 :     plumed_merror(getName()+" only support one VES bias");
+     131             :   }
+     132             : 
+     133           3 :   std::string error_msg = "";
+     134           3 :   std::vector<VesBias*> bias_pntrs = VesTools::getPointersFromLabels<VesBias*>(bias_labels,plumed.getActionSet(),error_msg);
+     135           3 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BIAS of "+getName()+": "+error_msg);}
+     136             : 
+     137           6 :   for(unsigned int i=0; i<bias_pntrs.size(); i++) {
+     138           3 :     if(bias_pntrs[i]->numberOfCoeffsSets()>1) {
+     139           0 :       plumed_merror(getName()+" at the moment supports only VES biases with a single coefficient set");
+     140             :     }
+     141             :   }
+     142             : 
+     143             :   std::vector<std::string> coeffs_fnames;
+     144           6 :   parseVector("COEFFS_INPUT",coeffs_fnames);
+     145           3 :   if(coeffs_fnames.size()!=bias_pntrs.size()) {
+     146           0 :     plumed_merror(getName()+": there have to be as many coefficient file given in COEFFS_INPUT as VES biases given in BIAS");
+     147             :   }
+     148             : 
+     149           3 :   unsigned int bias_output_stride = 0;
+     150           3 :   parse("BIAS_OUTPUT",bias_output_stride);
+     151             : 
+     152           3 :   unsigned int fes_output_stride = 0;
+     153           3 :   parse("FES_OUTPUT",fes_output_stride);
+     154             : 
+     155           3 :   unsigned int fesproj_output_stride = 0;
+     156           3 :   parse("FES_PROJ_OUTPUT",fesproj_output_stride);
+     157             : 
+     158           3 :   if(bias_output_stride == 0 && fes_output_stride == 0 && fesproj_output_stride == 0) {
+     159           0 :     plumed_merror(getName()+": you are not telling the action to do anything, you need to use one of the keywords BIAS_OUTPUT, FES_OUTPUT, or FES_PROJ_OUTPUT");
+     160             :   }
+     161             : 
+     162           3 :   checkRead();
+     163             : 
+     164           6 :   for(unsigned int i=0; i<bias_pntrs.size(); i++) {
+     165             : 
+     166           3 :     if(bias_pntrs[i]->dynamicTargetDistribution()) {
+     167           0 :       plumed_merror(getName()+" does not support dynamic target distributions at the moment");
+     168             :     }
+     169             : 
+     170           3 :     if(bias_pntrs[i]->isStaticTargetDistFileOutputActive()) {
+     171           2 :       bias_pntrs[i]->setupTargetDistFileOutput();
+     172           2 :       bias_pntrs[i]->writeTargetDistToFile();
+     173           2 :       bias_pntrs[i]->setupTargetDistProjFileOutput();
+     174           2 :       bias_pntrs[i]->writeTargetDistProjToFile();
+     175             :     }
+     176             : 
+     177             : 
+     178           3 :     if(bias_output_stride>0) {
+     179           3 :       bias_pntrs[i]->enableBiasFileOutput();
+     180           3 :       bias_pntrs[i]->setupBiasFileOutput();
+     181             :     }
+     182             : 
+     183           3 :     if(fes_output_stride>0) {
+     184           3 :       bias_pntrs[i]->enableFesFileOutput();
+     185           3 :       bias_pntrs[i]->setupFesFileOutput();
+     186             :     }
+     187             : 
+     188           3 :     if(fesproj_output_stride>0) {
+     189           1 :       bias_pntrs[i]->enableFesProjFileOutput();
+     190           1 :       bias_pntrs[i]->setupFesProjFileOutput();
+     191             :     }
+     192             : 
+     193           3 :     bias_pntrs[i]->enableIterationNumberInFilenames();
+     194             : 
+     195           3 :     IFile ifile;
+     196           3 :     ifile.open(coeffs_fnames[i]);
+     197             : 
+     198          39 :     while(ifile) {
+     199             : 
+     200          36 :       bias_pntrs[i]->resetBiasFileOutput();
+     201          36 :       bias_pntrs[i]->resetFesFileOutput();
+     202             : 
+     203          72 :       if(bias_pntrs[i]->getCoeffsPntrs()[0]->readOneSetFromFile(ifile)>0) {
+     204          33 :         unsigned int iteration = bias_pntrs[i]->getCoeffsPntrs()[0]->getIterationCounter();
+     205             : 
+     206          33 :         if(bias_output_stride>0 && iteration%bias_output_stride==0) {
+     207           8 :           bias_pntrs[i]->writeBiasToFile();
+     208             :         }
+     209             : 
+     210          33 :         if(fes_output_stride>0 && iteration%fes_output_stride==0) {
+     211           8 :           bias_pntrs[i]->writeFesToFile();
+     212             :         }
+     213             : 
+     214          33 :         if(fesproj_output_stride>0 && iteration%fesproj_output_stride==0) {
+     215           3 :           bias_pntrs[i]->writeFesProjToFile();
+     216             :         }
+     217             : 
+     218             :       }
+     219             : 
+     220             :     }
+     221             : 
+     222           3 :   }
+     223             : 
+     224           3 :   log.printf("Stopping");
+     225           3 :   plumed.stop();
+     226           6 : }
+     227             : 
+     228             : 
+     229             : }
+     230             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html b/coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html new file mode 100644 index 000000000000..8e670266c37d --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputTargetDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputTargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838993.3 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves24OutputTargetDistribution5applyEv0
_ZN4PLMD3ves24OutputTargetDistribution9calculateEv0
_ZN4PLMD3ves24OutputTargetDistributionC2ERKNS_13ActionOptionsE120
_ZN4PLMD3ves24OutputTargetDistribution16registerKeywordsERNS_8KeywordsE122
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputTargetDistribution.cpp.func.html b/coverage/ves/OutputTargetDistribution.cpp.func.html new file mode 100644 index 000000000000..3dc638857b99 --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputTargetDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputTargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838993.3 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves24OutputTargetDistribution16registerKeywordsERNS_8KeywordsE122
_ZN4PLMD3ves24OutputTargetDistribution5applyEv0
_ZN4PLMD3ves24OutputTargetDistribution9calculateEv0
_ZN4PLMD3ves24OutputTargetDistributionC2ERKNS_13ActionOptionsE120
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/OutputTargetDistribution.cpp.gcov.html b/coverage/ves/OutputTargetDistribution.cpp.gcov.html new file mode 100644 index 000000000000..bb941ed95f9f --- /dev/null +++ b/coverage/ves/OutputTargetDistribution.cpp.gcov.html @@ -0,0 +1,303 @@ + + + + + + + + LCOV - plumed test coverage - ves/OutputTargetDistribution.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - OutputTargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:838993.3 %
Date:2024-02-22 21:58:45Functions:2450.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "GridIntegrationWeights.h"
+      26             : #include "VesTools.h"
+      27             : 
+      28             : #include "core/ActionRegister.h"
+      29             : #include "core/PlumedMain.h"
+      30             : #include "core/Value.h"
+      31             : #include "tools/File.h"
+      32             : #include "tools/Grid.h"
+      33             : 
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace ves {
+      37             : 
+      38             : //+PLUMEDOC VES_UTILS VES_OUTPUT_TARGET_DISTRIBUTION
+      39             : /*
+      40             : Output target distribution to file.
+      41             : 
+      42             : This action can be used to output target distributions to a grid file,
+      43             : for example to see how they look like before using them in a VES bias.
+      44             : This action only support static target distributions.
+      45             : 
+      46             : This action is normally used through the \ref driver.
+      47             : 
+      48             : 
+      49             : \par Examples
+      50             : 
+      51             : In the following input we define a target distribution that is uniform for
+      52             : argument 1 and a Gaussian for argument 2 and then output it to a file
+      53             : called targetdist-1.data.
+      54             : \plumedfile
+      55             : t1_1: TD_UNIFORM  MINIMA=-4.0  MAXIMA=+4.0
+      56             : t1_2: TD_GAUSSIAN  CENTER1=-2.0  SIGMA1=0.5
+      57             : t1: TD_PRODUCT_DISTRIBUTION  DISTRIBUTIONS=t1_1,t1_2
+      58             : 
+      59             : VES_OUTPUT_TARGET_DISTRIBUTION ...
+      60             :  GRID_MIN=-4.0,-4.0
+      61             :  GRID_MAX=+4.0,+4.0
+      62             :  GRID_BINS=100,100
+      63             :  TARGET_DISTRIBUTION=t1
+      64             :  TARGETDIST_FILE=targetdist-1.data
+      65             :  LOG_TARGETDIST_FILE=targetdist-1.log.data
+      66             :  FMT_GRIDS=%11.6f
+      67             : ... VES_OUTPUT_TARGET_DISTRIBUTION
+      68             : \endplumedfile
+      69             : 
+      70             : This input should be run through the driver by using a command similar to the
+      71             : following one where the trajectory/configuration file configuration.gro is needed to
+      72             : trick the code to exit correctly.
+      73             : \verbatim
+      74             : plumed driver --plumed plumed.dat --igro configuration.gro
+      75             : \endverbatim
+      76             : 
+      77             : */
+      78             : //+ENDPLUMEDOC
+      79             : 
+      80             : 
+      81             : class OutputTargetDistribution :
+      82             :   public Action
+      83             : {
+      84             : public:
+      85             :   explicit OutputTargetDistribution(const ActionOptions&);
+      86           0 :   void calculate() override {}
+      87           0 :   void apply() override {}
+      88             :   static void registerKeywords(Keywords& keys);
+      89             : };
+      90             : 
+      91             : 
+      92             : PLUMED_REGISTER_ACTION(OutputTargetDistribution,"VES_OUTPUT_TARGET_DISTRIBUTION")
+      93             : 
+      94         122 : void OutputTargetDistribution::registerKeywords(Keywords& keys) {
+      95         122 :   Action::registerKeywords(keys);
+      96         244 :   keys.add("compulsory","GRID_MIN","the lower bounds for the grid");
+      97         244 :   keys.add("compulsory","GRID_MAX","the upper bounds for the grid");
+      98         244 :   keys.add("compulsory","GRID_BINS","the number of bins used for the grid.");
+      99         244 :   keys.add("optional","GRID_PERIODICITY","specify if the individual arguments should be made periodic (YES) or not (NO). By default all arguments are taken as not periodic.");
+     100         244 :   keys.add("compulsory","TARGETDIST_FILE","filename of the file for writing the target distribution");
+     101         244 :   keys.add("optional","LOG_TARGETDIST_FILE","filename of the file for writing the log of the target distribution");
+     102         244 :   keys.add("compulsory","TARGET_DISTRIBUTION","the target distribution to be used.");
+     103         244 :   keys.add("optional","FMT_GRIDS","the numerical format of the target distribution grids written to file. By default it is %14.9f");
+     104         244 :   keys.addFlag("DO_1D_PROJECTIONS",false,"Also output the one-dimensional marginal distributions for multi-dimensional target distribution.");
+     105         122 : }
+     106             : 
+     107         120 : OutputTargetDistribution::OutputTargetDistribution(const ActionOptions&ao):
+     108         120 :   Action(ao)
+     109             : {
+     110             : 
+     111             :   std::string targetdist_fname;
+     112         240 :   parse("TARGETDIST_FILE",targetdist_fname);
+     113             :   std::string log_targetdist_fname;
+     114         120 :   parse("LOG_TARGETDIST_FILE",log_targetdist_fname);
+     115         120 :   if(targetdist_fname==log_targetdist_fname) {
+     116           0 :     plumed_merror("error in " + getName() + ":TARGETDIST_FILE and LOG_TARGETDIST_FILE cannot be the same");
+     117             :   }
+     118             : 
+     119             :   std::vector<unsigned int> grid_bins;
+     120         240 :   parseVector("GRID_BINS",grid_bins);
+     121         120 :   unsigned int nargs = grid_bins.size();
+     122             : 
+     123         120 :   std::vector<std::string> grid_min(nargs);
+     124         120 :   parseVector("GRID_MIN",grid_min);
+     125         120 :   std::vector<std::string> grid_max(nargs);
+     126         120 :   parseVector("GRID_MAX",grid_max);
+     127             : 
+     128         120 :   std::vector<std::string> grid_periodicity(nargs);
+     129         240 :   parseVector("GRID_PERIODICITY",grid_periodicity);
+     130         232 :   if(grid_periodicity.size()==0) {grid_periodicity.assign(nargs,"NO");}
+     131             : 
+     132         120 :   std::string fmt_grids="%14.9f";
+     133         120 :   parse("FMT_GRIDS",fmt_grids);
+     134             : 
+     135         120 :   bool do_1d_proj = false;
+     136         120 :   parseFlag("DO_1D_PROJECTIONS",do_1d_proj);
+     137         120 :   if(do_1d_proj && nargs==1) {
+     138           0 :     plumed_merror("doesn't make sense to use the DO_1D_PROJECTIONS keyword for a one-dimensional distribution");
+     139             :   }
+     140             : 
+     141         120 :   plumed_massert(grid_min.size()==nargs,"mismatch between number of values given for grid parameters");
+     142         120 :   plumed_massert(grid_max.size()==nargs,"mismatch between number of values given for grid parameters");
+     143         120 :   plumed_massert(grid_periodicity.size()==nargs,"mismatch between number of values given for grid parameters");
+     144             : 
+     145             :   std::string targetdist_label;
+     146         120 :   parse("TARGET_DISTRIBUTION",targetdist_label);
+     147         120 :   checkRead();
+     148             :   //
+     149         120 :   std::vector<std::unique_ptr<Value>> arguments(nargs);
+     150         287 :   for(unsigned int i=0; i < nargs; i++) {
+     151         167 :     std::string is; Tools::convert(i+1,is);
+     152         167 :     if(nargs==1) {is="";}
+     153         167 :     arguments[i]= Tools::make_unique<Value>(nullptr,"arg"+is,false);
+     154         167 :     if(grid_periodicity[i]=="YES") {
+     155          11 :       arguments[i]->setDomain(grid_min[i],grid_max[i]);
+     156             :     }
+     157         156 :     else if(grid_periodicity[i]=="NO") {
+     158         156 :       arguments[i]->setNotPeriodic();
+     159             :     }
+     160             :     else {
+     161           0 :       plumed_merror("wrong value given in GRID_PERIODICITY, either specify YES or NO");
+     162             :     }
+     163             :   }
+     164             : 
+     165         120 :   std::string error_msg = "";
+     166         120 :   TargetDistribution* targetdist_pntr = VesTools::getPointerFromLabel<TargetDistribution*>(targetdist_label,plumed.getActionSet(),error_msg);
+     167         120 :   if(error_msg.size()>0) {plumed_merror("Error in keyword TARGET_DISTRIBUTION of "+getName()+": "+error_msg);}
+     168             :   //
+     169         120 :   if(targetdist_pntr->isDynamic()) {
+     170           0 :     plumed_merror(getName() + " only works for static target distributions");
+     171             :   }
+     172         120 :   targetdist_pntr->setupGrids(Tools::unique2raw(arguments),grid_min,grid_max,grid_bins);
+     173         120 :   targetdist_pntr->updateTargetDist();
+     174             :   Grid* targetdist_grid_pntr = targetdist_pntr->getTargetDistGridPntr();
+     175             :   Grid* log_targetdist_grid_pntr = targetdist_pntr->getLogTargetDistGridPntr();
+     176             : 
+     177             : 
+     178         120 :   double sum_grid = TargetDistribution::integrateGrid(targetdist_grid_pntr);
+     179         120 :   log.printf("  target distribution integrated over the grid: %16.12f\n",sum_grid);
+     180         120 :   log.printf("                                                (%30.16e)\n",sum_grid);
+     181             :   //
+     182         120 :   OFile ofile;
+     183         120 :   ofile.link(*this);
+     184         120 :   ofile.enforceBackup();
+     185         120 :   ofile.open(targetdist_fname);
+     186             :   targetdist_grid_pntr->setOutputFmt(fmt_grids);
+     187         120 :   targetdist_grid_pntr->writeToFile(ofile);
+     188         120 :   ofile.close();
+     189         120 :   if(log_targetdist_fname.size()>0) {
+     190          23 :     OFile ofile2;
+     191          23 :     ofile2.link(*this);
+     192          23 :     ofile2.enforceBackup();
+     193          23 :     ofile2.open(log_targetdist_fname);
+     194             :     log_targetdist_grid_pntr->setOutputFmt(fmt_grids);
+     195          23 :     log_targetdist_grid_pntr->writeToFile(ofile2);
+     196          23 :     ofile2.close();
+     197          23 :   }
+     198             : 
+     199         120 :   if(do_1d_proj) {
+     200          12 :     for(unsigned int i=0; i<nargs; i++) {
+     201           8 :       std::vector<std::string> arg1d(1);
+     202           8 :       arg1d[0] = arguments[i]->getName();
+     203           8 :       Grid marginal_grid = targetdist_pntr->getMarginal(arg1d);
+     204             :       //
+     205             :       std::string suffix;
+     206           8 :       Tools::convert(i+1,suffix);
+     207           8 :       suffix = "proj-" + suffix;
+     208           8 :       std::string marginal_fname = FileBase::appendSuffix(targetdist_fname,"."+suffix);
+     209             :       //
+     210           8 :       OFile ofile3;
+     211           8 :       ofile3.link(*this);
+     212           8 :       ofile3.enforceBackup();
+     213           8 :       ofile3.open(marginal_fname);
+     214             :       marginal_grid.setOutputFmt(fmt_grids);
+     215           8 :       marginal_grid.writeToFile(ofile3);
+     216          16 :     }
+     217             :   }
+     218             : 
+     219         480 : }
+     220             : 
+     221             : 
+     222             : 
+     223             : 
+     224             : 
+     225             : }
+     226             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Chi.cpp.func-sort-c.html b/coverage/ves/TD_Chi.cpp.func-sort-c.html new file mode 100644 index 000000000000..dcd838eb30e0 --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Chi.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Chi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves6TD_ChiC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves6TD_Chi16registerKeywordsERNS_8KeywordsE11
_ZNK4PLMD3ves6TD_Chi8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Chi.cpp.func.html b/coverage/ves/TD_Chi.cpp.func.html new file mode 100644 index 000000000000..1bcd6d52cce7 --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Chi.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Chi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves6TD_Chi16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves6TD_ChiC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves6TD_Chi8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Chi.cpp.gcov.html b/coverage/ves/TD_Chi.cpp.gcov.html new file mode 100644 index 000000000000..5dd272f32e5f --- /dev/null +++ b/coverage/ves/TD_Chi.cpp.gcov.html @@ -0,0 +1,230 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Chi.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Chi.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_CHI
+      32             : /*
+      33             : Chi distribution (static).
+      34             : 
+      35             : Employ a target distribution given by a
+      36             : [chi distribution](https://en.wikipedia.org/wiki/Chi_distribution)
+      37             : that is defined as
+      38             : \f[
+      39             : p(s) =
+      40             : \frac
+      41             : {2^{1-\frac{k}{2}}}
+      42             : {\sigma \, \Gamma\left(\frac{k}{2}\right) }
+      43             : \, \left(\frac{s-a}{\sigma}\right)^{k-1} \, \exp\left(- \frac{1}{2} \left(\frac{s-a}{\sigma}\right)^2\right),
+      44             : \f]
+      45             : where \f$a\f$ is the minimum of the distribution that is defined on the interval \f$[a,\infty)\f$,
+      46             : the parameter \f$k\f$ (given as a positive integer larger than 1) determines how far
+      47             : the peak of the distribution is from the minimum (known as the "degrees of freedom"),
+      48             : and the parameter \f$\sigma>0\f$ determines the broadness of the distribution.
+      49             : 
+      50             : The minimum \f$a\f$ is given using the MINIMUM keyword, the parameter \f$k\f$ is given
+      51             : using the KAPPA keyword, and the parameter \f$\sigma\f$ is given using the SIGMA keyword.
+      52             : 
+      53             : This target distribution action is only defined for one dimension, for multiple dimensions
+      54             : it should be used in combination with the \ref TD_PRODUCT_DISTRIBUTION action.
+      55             : 
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : Chi distribution with \f$a=10.0\f$, \f$\sigma=2.0\f$, and \f$k=2\f$
+      60             : \plumedfile
+      61             : td: TD_CHI  MINIMUM=10.0  SIGMA=2.0  KAPPA=2
+      62             : \endplumedfile
+      63             : 
+      64             : The Chi distribution is only defined for one dimension so for multiple
+      65             : dimensions we have to use it in combination with the \ref TD_PRODUCT_DISTRIBUTION action as shown in
+      66             : the following example where we have a uniform distribution for argument 1 and
+      67             : a Chi distribution for argument 1
+      68             : \plumedfile
+      69             : td_uni: TD_UNIFORM
+      70             : 
+      71             : td_chi: TD_CHI  MINIMUM=-10.0  SIGMA=2.0  KAPPA=2
+      72             : 
+      73             : td_pd: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=td_uni,td_chi
+      74             : \endplumedfile
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : class TD_Chi: public TargetDistribution {
+      80             :   std::vector<double> minima_;
+      81             :   std::vector<double> sigma_;
+      82             :   std::vector<double> kappa_;
+      83             :   std::vector<double> normalization_;
+      84             : public:
+      85             :   static void registerKeywords(Keywords&);
+      86             :   explicit TD_Chi(const ActionOptions& ao);
+      87             :   double getValue(const std::vector<double>&) const override;
+      88             : };
+      89             : 
+      90             : 
+      91             : PLUMED_REGISTER_ACTION(TD_Chi,"TD_CHI")
+      92             : 
+      93             : 
+      94          11 : void TD_Chi::registerKeywords(Keywords& keys) {
+      95          11 :   TargetDistribution::registerKeywords(keys);
+      96          22 :   keys.add("compulsory","MINIMUM","The minimum of the chi distribution.");
+      97          22 :   keys.add("compulsory","SIGMA","The sigma parameter of the chi distribution given as a positive number.");
+      98          22 :   keys.add("compulsory","KAPPA","The k parameter of the chi distribution given as positive integer larger than 1.");
+      99          11 :   keys.use("WELLTEMPERED_FACTOR");
+     100          11 :   keys.use("SHIFT_TO_ZERO");
+     101          11 :   keys.use("NORMALIZE");
+     102          11 : }
+     103             : 
+     104             : 
+     105           9 : TD_Chi::TD_Chi(const ActionOptions& ao):
+     106             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     107          18 :   minima_(0),
+     108           9 :   sigma_(0),
+     109           9 :   kappa_(0),
+     110          18 :   normalization_(0)
+     111             : {
+     112           9 :   parseVector("MINIMUM",minima_);
+     113           9 :   parseVector("SIGMA",sigma_);
+     114          18 :   for(unsigned int k=0; k<sigma_.size(); k++) {
+     115           9 :     if(sigma_[k] < 0.0) {plumed_merror(getName()+": the value given in SIGMA should be positive.");}
+     116             :   }
+     117             : 
+     118             : 
+     119           9 :   std::vector<unsigned int> kappa_int(0);
+     120          18 :   parseVector("KAPPA",kappa_int);
+     121           9 :   if(kappa_int.size()==0) {plumed_merror(getName()+": some problem with KAPPA keyword, should given as positive integer larger than 1");}
+     122           9 :   kappa_.resize(kappa_int.size());
+     123          18 :   for(unsigned int k=0; k<kappa_int.size(); k++) {
+     124           9 :     if(kappa_int[k] < 1) {plumed_merror(getName()+": KAPPA should be an integer 1 or higher");}
+     125           9 :     kappa_[k] = static_cast<double>(kappa_int[k]);
+     126             :   }
+     127             : 
+     128           9 :   setDimension(minima_.size());
+     129           9 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     130           9 :   if(sigma_.size()!=getDimension()) {plumed_merror(getName()+": the SIGMA keyword does not match the given dimension in MINIMUM");}
+     131           9 :   if(kappa_.size()!=getDimension()) {plumed_merror(getName()+": the KAPPA keyword does not match the given dimension in MINIMUM");}
+     132             : 
+     133           9 :   normalization_.resize(getDimension());
+     134          18 :   for(unsigned int k=0; k<getDimension(); k++) {
+     135           9 :     normalization_[k] = pow(2.0,(1.0-0.5*kappa_[k]))/(tgamma(0.5*kappa_[k])*sigma_[k]);
+     136             :   }
+     137           9 :   checkRead();
+     138           9 : }
+     139             : 
+     140             : 
+     141        1509 : double TD_Chi::getValue(const std::vector<double>& argument) const {
+     142             :   double value = 1.0;
+     143        3018 :   for(unsigned int k=0; k<argument.size(); k++) {
+     144        1509 :     double arg=(argument[k]-minima_[k])/sigma_[k];
+     145        1509 :     if(arg<0.0) {plumed_merror(getName()+": the chi distribution is not defined for values less that ones given in MINIMUM");}
+     146        1509 :     value *= normalization_[k] * pow(arg,kappa_[k]-1.0) * exp(-0.5*arg*arg);
+     147             :   }
+     148        1509 :   return value;
+     149             : }
+     150             : 
+     151             : 
+     152             : }
+     153             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ChiSquared.cpp.func-sort-c.html b/coverage/ves/TD_ChiSquared.cpp.func-sort-c.html new file mode 100644 index 000000000000..e939800a9425 --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ChiSquared.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ChiSquared.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves13TD_ChiSquaredC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves13TD_ChiSquared16registerKeywordsERNS_8KeywordsE11
_ZNK4PLMD3ves13TD_ChiSquared8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ChiSquared.cpp.func.html b/coverage/ves/TD_ChiSquared.cpp.func.html new file mode 100644 index 000000000000..df6befab129f --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ChiSquared.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ChiSquared.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves13TD_ChiSquared16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves13TD_ChiSquaredC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves13TD_ChiSquared8getValueERKSt6vectorIdSaIdEE1509
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ChiSquared.cpp.gcov.html b/coverage/ves/TD_ChiSquared.cpp.gcov.html new file mode 100644 index 000000000000..7e2c972a86cf --- /dev/null +++ b/coverage/ves/TD_ChiSquared.cpp.gcov.html @@ -0,0 +1,229 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ChiSquared.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ChiSquared.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:4040100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_CHISQUARED
+      32             : /*
+      33             : Chi-squared distribution (static).
+      34             : 
+      35             : Employ a target distribution given by a
+      36             : [chi-squared distribution](https://en.wikipedia.org/wiki/Chi-squared_distribution)
+      37             : that is defined as
+      38             : \f[
+      39             : p(s) =
+      40             : \frac
+      41             : {1}
+      42             : {\sigma \, 2^{\frac{k}{2}}  \,  \Gamma\left(\frac{k}{2}\right) }
+      43             : \, \left(\frac{s-a}{\sigma}\right)^{\frac{k}{2}-1} \, \exp\left(- \frac{1}{2}
+      44             : \left(\frac{s-a}{\sigma}\right) \right),
+      45             : \f]
+      46             : where \f$a\f$ is the minimum of the distribution that is defined on the interval \f$[a,\infty)\f$,
+      47             : the parameter \f$k\f$ (given as a positive integer larger than 2) determines how far
+      48             : the peak of the distribution is from the minimum (known as the "degrees of freedom"),
+      49             : and the parameter \f$\sigma>0\f$ determines the broadness of the distribution.
+      50             : 
+      51             : The minimum \f$a\f$ is given using the MINIMUM keyword, the parameter \f$k\f$ is given
+      52             : using the KAPPA keyword, and the parameter \f$\sigma\f$ is given using the SIGMA keyword.
+      53             : 
+      54             : This target distribution action is only defined for one dimension, for multiple dimensions
+      55             : it should be used in combination with the \ref TD_PRODUCT_DISTRIBUTION action.
+      56             : 
+      57             : \par Examples
+      58             : 
+      59             : Chi-squared distribution with \f$a=-10.0\f$, \f$\sigma=2.0\f$, and \f$k=2\f$
+      60             : \plumedfile
+      61             : td: TD_CHISQUARED  MINIMUM=-10.0  SIGMA=2.0  KAPPA=2
+      62             : \endplumedfile
+      63             : 
+      64             : The Chi-squared distribution is only defined for one dimension so for multiple
+      65             : dimensions we have to use it in combination with the \ref TD_PRODUCT_DISTRIBUTION action as shown in
+      66             : the following example where we have a Chi-squared distribution for argument 1
+      67             : and uniform distribution for argument 2
+      68             : \plumedfile
+      69             : td_chisq: TD_CHISQUARED  MINIMUM=10.0  SIGMA=2.0  KAPPA=2
+      70             : 
+      71             : td_uni: TD_UNIFORM
+      72             : 
+      73             : td_pd: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=td_chisq,td_uni
+      74             : \endplumedfile
+      75             : 
+      76             : */
+      77             : //+ENDPLUMEDOC
+      78             : 
+      79             : class TD_ChiSquared: public TargetDistribution {
+      80             :   std::vector<double> minima_;
+      81             :   std::vector<double> sigma_;
+      82             :   std::vector<double> kappa_;
+      83             :   std::vector<double> normalization_;
+      84             : public:
+      85             :   static void registerKeywords(Keywords&);
+      86             :   explicit TD_ChiSquared(const ActionOptions& ao);
+      87             :   double getValue(const std::vector<double>&) const override;
+      88             : };
+      89             : 
+      90             : 
+      91             : PLUMED_REGISTER_ACTION(TD_ChiSquared,"TD_CHISQUARED")
+      92             : 
+      93             : 
+      94          11 : void TD_ChiSquared::registerKeywords(Keywords& keys) {
+      95          11 :   TargetDistribution::registerKeywords(keys);
+      96          22 :   keys.add("compulsory","MINIMUM","The minimum of the chi-squared distribution.");
+      97          22 :   keys.add("compulsory","SIGMA","The sigma parameter of the chi-squared distribution given as a positive number.");
+      98          22 :   keys.add("compulsory","KAPPA","The k parameter of the chi-squared distribution given as positive integer larger than 2.");
+      99          11 :   keys.use("WELLTEMPERED_FACTOR");
+     100          11 :   keys.use("SHIFT_TO_ZERO");
+     101          11 :   keys.use("NORMALIZE");
+     102          11 : }
+     103             : 
+     104             : 
+     105           9 : TD_ChiSquared::TD_ChiSquared(const ActionOptions& ao):
+     106             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     107          18 :   minima_(0),
+     108           9 :   sigma_(0),
+     109           9 :   kappa_(0),
+     110          18 :   normalization_(0)
+     111             : {
+     112           9 :   parseVector("MINIMUM",minima_);
+     113           9 :   parseVector("SIGMA",sigma_);
+     114          18 :   for(unsigned int k=0; k<sigma_.size(); k++) {
+     115           9 :     if(sigma_[k] < 0.0) {plumed_merror(getName()+": the value given in SIGMA should be positive.");}
+     116             :   }
+     117             : 
+     118           9 :   std::vector<unsigned int> kappa_int(0);
+     119          18 :   parseVector("KAPPA",kappa_int);
+     120           9 :   if(kappa_int.size()==0) {plumed_merror(getName()+": some problem with KAPPA keyword, should given as positive integer larger than 2");}
+     121           9 :   kappa_.resize(kappa_int.size());
+     122          18 :   for(unsigned int k=0; k<kappa_int.size(); k++) {
+     123           9 :     if(kappa_int[k] < 2) {plumed_merror(getName()+": KAPPA should be an integer 2 or higher");}
+     124           9 :     kappa_[k] = static_cast<double>(kappa_int[k]);
+     125             :   }
+     126             : 
+     127           9 :   setDimension(minima_.size());
+     128           9 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     129           9 :   if(sigma_.size()!=getDimension()) {plumed_merror(getName()+": the SIGMA keyword does not match the given dimension in MINIMUM");}
+     130           9 :   if(kappa_.size()!=getDimension()) {plumed_merror(getName()+": the KAPPA keyword does not match the given dimension in MINIMUM");}
+     131             : 
+     132           9 :   normalization_.resize(getDimension());
+     133          18 :   for(unsigned int k=0; k<getDimension(); k++) {
+     134           9 :     normalization_[k] = 1.0/(pow(2.0,0.5*kappa_[k])*tgamma(0.5*kappa_[k])*sigma_[k]);
+     135             :   }
+     136           9 :   checkRead();
+     137           9 : }
+     138             : 
+     139             : 
+     140        1509 : double TD_ChiSquared::getValue(const std::vector<double>& argument) const {
+     141             :   double value = 1.0;
+     142        3018 :   for(unsigned int k=0; k<argument.size(); k++) {
+     143        1509 :     double arg=(argument[k]-minima_[k])/sigma_[k];
+     144        1509 :     if(arg<0.0) {plumed_merror(getName()+": the chi-squared istribution is not defined for values less that ones given in MINIMUM");}
+     145        1509 :     value *= normalization_[k] * pow(arg,0.5*kappa_[k]-1.0) * exp(-0.5*arg);
+     146             :   }
+     147        1509 :   return value;
+     148             : }
+     149             : 
+     150             : 
+     151             : }
+     152             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Custom.cpp.func-sort-c.html b/coverage/ves/TD_Custom.cpp.func-sort-c.html new file mode 100644 index 000000000000..ea70044db65a --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Custom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:778986.5 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves9TD_Custom8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves9TD_Custom20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE16
_ZN4PLMD3ves9TD_CustomC2ERKNS_13ActionOptionsE16
_ZN4PLMD3ves9TD_CustomD0Ev16
_ZN4PLMD3ves9TD_CustomD2Ev16
_ZN4PLMD3ves9TD_Custom16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD3ves9TD_Custom10updateGridEv46
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Custom.cpp.func.html b/coverage/ves/TD_Custom.cpp.func.html new file mode 100644 index 000000000000..50c204995d78 --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Custom.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:778986.5 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9TD_Custom10updateGridEv46
_ZN4PLMD3ves9TD_Custom16registerKeywordsERNS_8KeywordsE18
_ZN4PLMD3ves9TD_Custom20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE16
_ZN4PLMD3ves9TD_CustomC2ERKNS_13ActionOptionsE16
_ZN4PLMD3ves9TD_CustomD0Ev16
_ZN4PLMD3ves9TD_CustomD2Ev16
_ZNK4PLMD3ves9TD_Custom8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Custom.cpp.gcov.html b/coverage/ves/TD_Custom.cpp.gcov.html new file mode 100644 index 000000000000..ead40322b8ba --- /dev/null +++ b/coverage/ves/TD_Custom.cpp.gcov.html @@ -0,0 +1,372 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Custom.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Custom.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:778986.5 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "tools/Grid.h"
+      28             : 
+      29             : #include "lepton/Lepton.h"
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : //+PLUMEDOC VES_TARGETDIST TD_CUSTOM
+      36             : /*
+      37             : Target distribution given by an arbitrary mathematical expression (static or dynamic).
+      38             : 
+      39             : Use as a target distribution the distribution defined by
+      40             : \f[
+      41             : p(\mathbf{s}) =
+      42             : \frac{f(\mathbf{s})}{\int d\mathbf{s} \, f(\mathbf{s})}
+      43             : \f]
+      44             : where \f$f(\mathbf{s})\f$ is some arbitrary mathematical function that
+      45             : is parsed by the lepton library.
+      46             : 
+      47             : The function \f$f(\mathbf{s})\f$ is given by the FUNCTION keywords by
+      48             : using _s1_,_s2_,..., as variables for the arguments
+      49             : \f$\mathbf{s}=(s_1,s_2,\ldots,s_d)\f$.
+      50             : If one variable is not given the target distribution will be
+      51             : taken as uniform in that argument.
+      52             : 
+      53             : It is also possible to include the free energy surface \f$F(\mathbf{s})\f$
+      54             : in the target distribution by using the _FE_ variable. In this case the
+      55             : target distribution is dynamic and needs to be updated with current
+      56             : best estimate of \f$F(\mathbf{s})\f$, similarly as for the
+      57             : \ref TD_WELLTEMPERED "well-tempered target distribution".
+      58             : Furthermore, the inverse temperature \f$\beta = (k_{\mathrm{B}}T)^{-1}\f$ and
+      59             : the thermal energy \f$k_{\mathrm{B}}T\f$ can be included
+      60             : by using the _beta_ and \f$k_B T\f$ variables.
+      61             : 
+      62             : The target distribution will be automatically normalized over the region on
+      63             : which it is defined on. Therefore, the function given in
+      64             : FUNCTION needs to be non-negative and it must be possible to normalize the function. The
+      65             : code will perform checks to make sure that this is indeed the case.
+      66             : 
+      67             : 
+      68             : \par Examples
+      69             : 
+      70             : Here we use as shifted [Maxwell-Boltzmann distribution](https://en.wikipedia.org/wiki/Maxwell%E2%80%93Boltzmann_distribution)
+      71             : as a target distribution in one-dimension.
+      72             : Note that it is not need to include the normalization factor as the distribution will be
+      73             : automatically normalized.
+      74             : \plumedfile
+      75             : TD_CUSTOM ...
+      76             :  FUNCTION=(s1+20)^2*exp(-(s1+20)^2/(2*10.0^2))
+      77             :  LABEL=td
+      78             : ... TD_CUSTOM
+      79             : \endplumedfile
+      80             : 
+      81             : Here we have a two dimensional target distribution where we
+      82             : use a [generalized normal distribution](https://en.wikipedia.org/wiki/Generalized_normal_distribution)
+      83             : for argument \f$s_2\f$ while the distribution for \f$s_1\f$ is taken as
+      84             : uniform as the variable _s1_ is not included in the function.
+      85             : \plumedfile
+      86             : TD_CUSTOM ...
+      87             :  FUNCTION=exp(-(abs(s2-20.0)/5.0)^4.0)
+      88             :  LABEL=td
+      89             : ... TD_CUSTOM
+      90             : \endplumedfile
+      91             : 
+      92             : By using the _FE_ variable the target distribution can depend on
+      93             : the free energy surface \f$F(\mathbf{s})\f$. For example,
+      94             : the following input is identical to using \ref TD_WELLTEMPERED with
+      95             : a bias factor of 10.
+      96             : \plumedfile
+      97             : TD_CUSTOM ...
+      98             :  FUNCTION=exp(-(beta/10.0)*FE)
+      99             :  LABEL=td
+     100             : ... TD_CUSTOM
+     101             : \endplumedfile
+     102             : Here the inverse temperature is automatically obtained by using the _beta_
+     103             : variable. It is also possible to use the \f$k_B T\f$ variable. The following
+     104             : syntax will give the exact same results as the syntax above
+     105             : \plumedfile
+     106             : TD_CUSTOM ...
+     107             :  FUNCTION=exp(-(1.0/(kBT*10.0))*FE)
+     108             :  LABEL=td
+     109             : ... TD_CUSTOM
+     110             : \endplumedfile
+     111             : 
+     112             : 
+     113             : */
+     114             : //+ENDPLUMEDOC
+     115             : 
+     116             : class TD_Custom : public TargetDistribution {
+     117             : private:
+     118             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+     119             :   //
+     120             :   lepton::CompiledExpression expression;
+     121             :   //
+     122             :   std::vector<double*> cv_var_lepton_refs_;
+     123             :   double* kbt_var_lepton_ref_;
+     124             :   double* beta_var_lepton_ref_;
+     125             :   double* fes_var_lepton_ref_;
+     126             :   //
+     127             :   std::vector<unsigned int> cv_var_idx_;
+     128             :   std::vector<std::string> cv_var_str_;
+     129             :   //
+     130             :   std::string cv_var_prefix_str_;
+     131             :   std::string fes_var_str_;
+     132             :   std::string kbt_var_str_;
+     133             :   std::string beta_var_str_;
+     134             :   //
+     135             :   bool use_fes_;
+     136             :   bool use_kbt_;
+     137             :   bool use_beta_;
+     138             : public:
+     139             :   static void registerKeywords( Keywords&);
+     140             :   explicit TD_Custom(const ActionOptions& ao);
+     141             :   void updateGrid() override;
+     142             :   double getValue(const std::vector<double>&) const override;
+     143          48 :   ~TD_Custom() {};
+     144             : };
+     145             : 
+     146             : PLUMED_REGISTER_ACTION(TD_Custom,"TD_CUSTOM")
+     147             : 
+     148             : 
+     149          18 : void TD_Custom::registerKeywords(Keywords& keys) {
+     150          18 :   TargetDistribution::registerKeywords(keys);
+     151          36 :   keys.add("compulsory","FUNCTION","The function you wish to use for the target distribution where you should use the variables _s1_,_s2_,... for the arguments. You can also use the current estimate of the FES by using the variable _FE_ and the temperature by using the \\f$k_B T\\f$ and _beta_ variables.");
+     152          18 :   keys.use("WELLTEMPERED_FACTOR");
+     153          18 :   keys.use("SHIFT_TO_ZERO");
+     154          18 : }
+     155             : 
+     156             : 
+     157          16 : TD_Custom::TD_Custom(const ActionOptions& ao):
+     158             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     159             : //
+     160          16 :   cv_var_lepton_refs_(0,nullptr),
+     161          16 :   kbt_var_lepton_ref_(nullptr),
+     162          16 :   beta_var_lepton_ref_(nullptr),
+     163          16 :   fes_var_lepton_ref_(nullptr),
+     164             : //
+     165          16 :   cv_var_idx_(0),
+     166          16 :   cv_var_str_(0),
+     167             : //
+     168          16 :   cv_var_prefix_str_("s"),
+     169          16 :   fes_var_str_("FE"),
+     170          16 :   kbt_var_str_("kBT"),
+     171          16 :   beta_var_str_("beta"),
+     172             : //
+     173          16 :   use_fes_(false),
+     174          16 :   use_kbt_(false),
+     175          32 :   use_beta_(false)
+     176             : {
+     177             :   std::string func_str;
+     178          16 :   parse("FUNCTION",func_str);
+     179          16 :   checkRead();
+     180             :   //
+     181             :   try {
+     182          16 :     lepton::ParsedExpression pe=lepton::Parser::parse(func_str).optimize(lepton::Constants());
+     183          16 :     log<<"  function as parsed by lepton: "<<pe<<"\n";
+     184          16 :     expression=pe.createCompiledExpression();
+     185             :   }
+     186           0 :   catch(PLMD::lepton::Exception& exc) {
+     187           0 :     plumed_merror("There was some problem in parsing the function "+func_str+" given in FUNCTION with lepton");
+     188           0 :   }
+     189             : 
+     190          39 :   for(auto &p: expression.getVariables()) {
+     191          23 :     std::string curr_var = p;
+     192             :     unsigned int cv_idx;
+     193          39 :     if(curr_var.substr(0,cv_var_prefix_str_.size())==cv_var_prefix_str_ && Tools::convertNoexcept(curr_var.substr(cv_var_prefix_str_.size()),cv_idx) && cv_idx>0) {
+     194          16 :       cv_var_idx_.push_back(cv_idx-1);
+     195             :     }
+     196           7 :     else if(curr_var==fes_var_str_) {
+     197           3 :       use_fes_=true;
+     198             :       setDynamic();
+     199             :       setFesGridNeeded();
+     200             :     }
+     201           4 :     else if(curr_var==kbt_var_str_) {
+     202           2 :       use_kbt_=true;
+     203             :     }
+     204           2 :     else if(curr_var==beta_var_str_) {
+     205           2 :       use_beta_=true;
+     206             :     }
+     207             :     else {
+     208           0 :       plumed_merror(getName()+": problem with parsing formula with lepton, cannot recognise the variable "+curr_var);
+     209             :     }
+     210             :   }
+     211             :   //
+     212          16 :   std::sort(cv_var_idx_.begin(),cv_var_idx_.end());
+     213          16 :   cv_var_str_.resize(cv_var_idx_.size());
+     214          16 :   cv_var_lepton_refs_.resize(cv_var_str_.size());
+     215          32 :   for(unsigned int j=0; j<cv_var_idx_.size(); j++) {
+     216          16 :     std::string str1; Tools::convert(cv_var_idx_[j]+1,str1);
+     217          32 :     cv_var_str_[j] = cv_var_prefix_str_+str1;
+     218             :     try {
+     219          16 :       cv_var_lepton_refs_[j] = &expression.getVariableReference(cv_var_str_[j]);
+     220           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     221             :   }
+     222             : 
+     223          16 :   if(use_kbt_) {
+     224             :     try {
+     225           2 :       kbt_var_lepton_ref_ = &expression.getVariableReference(kbt_var_str_);
+     226           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     227             :   }
+     228          16 :   if(use_beta_) {
+     229             :     try {
+     230           2 :       beta_var_lepton_ref_ = &expression.getVariableReference(beta_var_str_);
+     231           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     232             :   }
+     233          16 :   if(use_fes_) {
+     234             :     try {
+     235           3 :       fes_var_lepton_ref_ = &expression.getVariableReference(fes_var_str_);
+     236           0 :     } catch(PLMD::lepton::Exception& exc) {}
+     237             :   }
+     238             : 
+     239          16 : }
+     240             : 
+     241             : 
+     242          16 : void TD_Custom::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     243          16 :   if(cv_var_idx_.size()>0 && cv_var_idx_[cv_var_idx_.size()-1]>getDimension()) {
+     244           0 :     plumed_merror(getName()+": mismatch between CVs given in FUNC and the dimension of the target distribution");
+     245             :   }
+     246          16 : }
+     247             : 
+     248             : 
+     249           0 : double TD_Custom::getValue(const std::vector<double>& argument) const {
+     250           0 :   plumed_merror("getValue not implemented for TD_Custom");
+     251             :   return 0.0;
+     252             : }
+     253             : 
+     254             : 
+     255          46 : void TD_Custom::updateGrid() {
+     256          46 :   if(use_fes_) {
+     257          33 :     plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to the free energy in the target distribution");
+     258             :   }
+     259          46 :   if(use_kbt_) {
+     260          22 :     if(kbt_var_lepton_ref_) {*kbt_var_lepton_ref_= 1.0/getBeta();}
+     261             :   }
+     262          46 :   if(use_beta_) {
+     263          22 :     if(beta_var_lepton_ref_) {*beta_var_lepton_ref_= getBeta();}
+     264             :   }
+     265             :   //
+     266          92 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     267             :   double norm = 0.0;
+     268             :   //
+     269       40909 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     270       40863 :     std::vector<double> point = targetDistGrid().getPoint(l);
+     271       99928 :     for(unsigned int k=0; k<cv_var_str_.size() ; k++) {
+     272       59065 :       if(cv_var_lepton_refs_[k]) {*cv_var_lepton_refs_[k] = point[cv_var_idx_[k]];}
+     273             :     }
+     274       40863 :     if(use_fes_) {
+     275        3300 :       if(fes_var_lepton_ref_) {*fes_var_lepton_ref_ = getFesGridPntr()->getValue(l);}
+     276             :     }
+     277       40863 :     double value = expression.evaluate();
+     278             : 
+     279       40863 :     if(value<0.0 && !isTargetDistGridShiftedToZero()) {plumed_merror(getName()+": The target distribution function gives negative values. You should change the definition of the function used for the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");}
+     280       40863 :     targetDistGrid().setValue(l,value);
+     281       40863 :     norm += integration_weights[l]*value;
+     282       40863 :     logTargetDistGrid().setValue(l,-std::log(value));
+     283             :   }
+     284          46 :   if(norm>0.0) {
+     285          45 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     286             :   }
+     287           1 :   else if(!isTargetDistGridShiftedToZero()) {
+     288           0 :     plumed_merror(getName()+": The target distribution function cannot be normalized proberly. You should change the definition of the function used for the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");
+     289             :   }
+     290          46 :   logTargetDistGrid().setMinToZero();
+     291          46 : }
+     292             : 
+     293             : 
+     294             : }
+     295             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Exponential.cpp.func-sort-c.html b/coverage/ves/TD_Exponential.cpp.func-sort-c.html new file mode 100644 index 000000000000..bc3186c726a6 --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Exponential.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Exponential.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14TD_ExponentialC2ERKNS_13ActionOptionsE8
_ZN4PLMD3ves14TD_Exponential16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD3ves14TD_Exponential8getValueERKSt6vectorIdSaIdEE1308
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Exponential.cpp.func.html b/coverage/ves/TD_Exponential.cpp.func.html new file mode 100644 index 000000000000..9143631ff0a6 --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Exponential.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Exponential.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves14TD_Exponential16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3ves14TD_ExponentialC2ERKNS_13ActionOptionsE8
_ZNK4PLMD3ves14TD_Exponential8getValueERKSt6vectorIdSaIdEE1308
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Exponential.cpp.gcov.html b/coverage/ves/TD_Exponential.cpp.gcov.html new file mode 100644 index 000000000000..511f77542afd --- /dev/null +++ b/coverage/ves/TD_Exponential.cpp.gcov.html @@ -0,0 +1,206 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Exponential.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Exponential.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2626100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_EXPONENTIAL
+      32             : /*
+      33             : Exponential distribution (static).
+      34             : 
+      35             : Employ a target distribution given by an
+      36             : [exponential distribution](https://en.wikipedia.org/wiki/Exponential_distribution)
+      37             : that is defined as
+      38             : \f[
+      39             : p(s) =
+      40             : \lambda e^{-\lambda(s-a)}
+      41             : \f]
+      42             : where \f$a\f$ is the minimum of the distribution that is defined on the interval \f$[a,\infty)\f$,
+      43             : and \f$\lambda>0\f$ is the so-called rate parameter.
+      44             : 
+      45             : The minimum \f$a\f$ is given using the MINIMUM keyword, and the rate parameter \f$\lambda\f$ is given
+      46             : using the LAMBDA keyword.
+      47             : 
+      48             : This target distribution action is only defined for one dimension, for multiple dimensions
+      49             : it should be used in combination with \ref TD_PRODUCT_DISTRIBUTION action.
+      50             : 
+      51             : \par Examples
+      52             : 
+      53             : Exponential distribution with \f$a=10.0\f$ and \f$\lambda=0.5\f$
+      54             : \plumedfile
+      55             : td: TD_EXPONENTIAL  MINIMUM=-10.0  LAMBDA=0.5
+      56             : \endplumedfile
+      57             : 
+      58             : The exponential distribution is only defined for one dimension so for multiple
+      59             : dimensions we have to use it in combination with the \ref TD_PRODUCT_DISTRIBUTION action as shown in
+      60             : the following example where we have a uniform distribution for argument 1 and
+      61             : and an exponential distribution for argument 2
+      62             : \plumedfile
+      63             : td_uni: TD_UNIFORM
+      64             : 
+      65             : td_exp: TD_EXPONENTIAL  MINIMUM=-10.0  LAMBDA=0.5
+      66             : 
+      67             : td_pd: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=td_uni,td_exp
+      68             : \endplumedfile
+      69             : 
+      70             : 
+      71             : */
+      72             : //+ENDPLUMEDOC
+      73             : 
+      74             : class TD_Exponential: public TargetDistribution {
+      75             :   std::vector<double> minima_;
+      76             :   std::vector<double> lambda_;
+      77             : public:
+      78             :   static void registerKeywords(Keywords&);
+      79             :   explicit TD_Exponential(const ActionOptions& ao);
+      80             :   double getValue(const std::vector<double>&) const override;
+      81             : };
+      82             : 
+      83             : 
+      84             : PLUMED_REGISTER_ACTION(TD_Exponential,"TD_EXPONENTIAL")
+      85             : 
+      86             : 
+      87          10 : void TD_Exponential::registerKeywords(Keywords& keys) {
+      88          10 :   TargetDistribution::registerKeywords(keys);
+      89          20 :   keys.add("compulsory","MINIMUM","The minimum of the exponential distribution.");
+      90          20 :   keys.add("compulsory","LAMBDA","The lambda parameter of the exponential distribution given as positive number.");
+      91          10 :   keys.use("WELLTEMPERED_FACTOR");
+      92          10 :   keys.use("SHIFT_TO_ZERO");
+      93          10 :   keys.use("NORMALIZE");
+      94          10 : }
+      95             : 
+      96             : 
+      97           8 : TD_Exponential::TD_Exponential(const ActionOptions& ao):
+      98             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+      99          16 :   minima_(0),
+     100           8 :   lambda_(0)
+     101             : {
+     102           8 :   parseVector("MINIMUM",minima_);
+     103           8 :   parseVector("LAMBDA",lambda_);
+     104          16 :   for(unsigned int k=0; k<lambda_.size(); k++) {
+     105           8 :     if(lambda_[k] < 0.0) {plumed_merror(getName()+": the value given in LAMBDA should be positive.");}
+     106             :   }
+     107             : 
+     108             : 
+     109           8 :   setDimension(minima_.size());
+     110           8 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     111           8 :   if(lambda_.size()!=getDimension()) {plumed_merror(getName()+": the LAMBDA keyword does not match the given dimension in MINIMUM");}
+     112           8 :   checkRead();
+     113           8 : }
+     114             : 
+     115             : 
+     116        1308 : double TD_Exponential::getValue(const std::vector<double>& argument) const {
+     117             :   double value = 1.0;
+     118        2616 :   for(unsigned int k=0; k<argument.size(); k++) {
+     119        1308 :     double arg = (argument[k]-minima_[k])*lambda_[k];
+     120        1308 :     if(arg<0.0) {plumed_merror(getName()+": the exponential distribution is not defined for values less that ones given in MINIMUM");}
+     121        1308 :     value *= lambda_[k]*exp(-arg);
+     122             :   }
+     123        1308 :   return value;
+     124             : }
+     125             : 
+     126             : 
+     127             : 
+     128             : }
+     129             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html new file mode 100644 index 000000000000..a7ebc56c3b87 --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ExponentiallyModifiedGaussian.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ExponentiallyModifiedGaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:576390.5 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussianC2ERKNS_13ActionOptionsE6
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussian16registerKeywordsERNS_8KeywordsE8
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian8getValueERKSt6vectorIdSaIdEE11206
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian37ExponentiallyModifiedGaussianDiagonalERKSt6vectorIdSaIdEES6_S6_S6_21809
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html new file mode 100644 index 000000000000..7e3827126b6f --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ExponentiallyModifiedGaussian.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ExponentiallyModifiedGaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:576390.5 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussian16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD3ves32TD_ExponentiallyModifiedGaussianC2ERKNS_13ActionOptionsE6
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian37ExponentiallyModifiedGaussianDiagonalERKSt6vectorIdSaIdEES6_S6_S6_21809
_ZNK4PLMD3ves32TD_ExponentiallyModifiedGaussian8getValueERKSt6vectorIdSaIdEE11206
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html new file mode 100644 index 000000000000..e296e41f0227 --- /dev/null +++ b/coverage/ves/TD_ExponentiallyModifiedGaussian.cpp.gcov.html @@ -0,0 +1,301 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ExponentiallyModifiedGaussian.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ExponentiallyModifiedGaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:576390.5 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_EXPONENTIALLY_MODIFIED_GAUSSIAN
+      32             : /*
+      33             : Target distribution given by a sum of exponentially modified Gaussian distributions (static).
+      34             : 
+      35             : Employ a target distribution that is given by a sum where each
+      36             : term is a product of one-dimensional
+      37             : [exponentially modified Gaussian distributions](http://en.wikipedia.org/wiki/Exponentially_modified_Gaussian_distribution),
+      38             : \f[
+      39             : p(\mathbf{s}) = \sum_{i} \, w_{i}
+      40             : \prod_{k}^{d}
+      41             : \frac{\lambda_{k,i}}{2}
+      42             : \,
+      43             : \exp\left[
+      44             : \frac{\lambda_{k,i}}{2}
+      45             : (2 \mu_{k,i} + \lambda_{k,i} \sigma_{k,i}^2 -2 s_{k})
+      46             : \right]
+      47             : \,
+      48             : \mathrm{erfc}\left[
+      49             : \frac{\mu_{k,i} + \lambda_{k,i} \sigma_{k,i}^2 - s_{k})}{\sqrt{2} \sigma_{k,i}}
+      50             : \right]
+      51             : \f]
+      52             : where \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$
+      53             : are the centers of the Gaussian component,
+      54             : \f$(\sigma_{1,i},\sigma_{2,i},\ldots,\sigma_{d,i})\f$ are the
+      55             : standard deviations of the Gaussian component,
+      56             : \f$(\lambda_{1,i},\lambda_{2,i},\ldots,\lambda_{d,i})\f$ are the
+      57             : rate parameters of the exponential component, and
+      58             : \f$\mathrm{erfc}(x)=1-\mathrm{erf}(x)\f$ is the
+      59             : complementary error function.
+      60             : The weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      61             : 
+      62             : The centers \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$ are
+      63             : given using the numbered CENTER keywords, the standard deviations
+      64             : \f$(\sigma_{1,i},\sigma_{2,i},\ldots,\sigma_{d,i})\f$ using the
+      65             : the numbered SIGMA keywords, and the rate parameters
+      66             : \f$(\lambda_{1,i},\lambda_{2,i},\ldots,\lambda_{d,i})\f$ using the
+      67             : numbered LAMBDA keywords.
+      68             : The weights are given using the WEIGHTS keywords, if no weights are
+      69             : given are all terms weighted equally.
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : An exponentially modified Gaussian distribution in one-dimension
+      74             : \plumedfile
+      75             : td1: TD_EXPONENTIALLY_MODIFIED_GAUSSIAN CENTER1=-10.0 SIGMA1=1.0 LAMBDA1=0.25
+      76             : \endplumedfile
+      77             : 
+      78             : A sum of two one-dimensional exponentially modified Gaussian distributions
+      79             : \plumedfile
+      80             : TD_EXPONENTIALLY_MODIFIED_GAUSSIAN ...
+      81             :  CENTER1=-10.0 SIGMA1=1.0 LAMBDA1=0.5
+      82             :  CENTER2=+10.0 SIGMA2=1.0 LAMBDA2=1.0
+      83             :  WEIGHTS=2.0,1.0
+      84             :  LABEL=td1
+      85             : ... TD_EXPONENTIALLY_MODIFIED_GAUSSIAN
+      86             : \endplumedfile
+      87             : 
+      88             : A sum of two two-dimensional exponentially modified Gaussian distributions
+      89             : \plumedfile
+      90             : TD_EXPONENTIALLY_MODIFIED_GAUSSIAN ...
+      91             :  CENTER1=-5.0,+5.0 SIGMA1=1.0,1.0 LAMBDA1=0.5,0.5
+      92             :  CENTER2=+5.0,+5.0 SIGMA2=1.0,1.0 LAMBDA2=1.0,1.0
+      93             :  WEIGHTS=1.0,1.0
+      94             :  LABEL=td1
+      95             : ... TD_EXPONENTIALLY_MODIFIED_GAUSSIAN
+      96             : \endplumedfile
+      97             : 
+      98             : 
+      99             : 
+     100             : 
+     101             : 
+     102             : */
+     103             : //+ENDPLUMEDOC
+     104             : 
+     105             : class TD_ExponentiallyModifiedGaussian: public TargetDistribution {
+     106             :   std::vector< std::vector<double> > centers_;
+     107             :   std::vector< std::vector<double> > sigmas_;
+     108             :   std::vector< std::vector<double> > lambdas_;
+     109             :   std::vector<double> weights_;
+     110             :   unsigned int ncenters_;
+     111             :   double ExponentiallyModifiedGaussianDiagonal(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&) const;
+     112             : public:
+     113             :   static void registerKeywords(Keywords&);
+     114             :   explicit TD_ExponentiallyModifiedGaussian(const ActionOptions& ao);
+     115             :   double getValue(const std::vector<double>&) const override;
+     116             : };
+     117             : 
+     118             : 
+     119             : PLUMED_REGISTER_ACTION(TD_ExponentiallyModifiedGaussian,"TD_EXPONENTIALLY_MODIFIED_GAUSSIAN")
+     120             : 
+     121             : 
+     122           8 : void TD_ExponentiallyModifiedGaussian::registerKeywords(Keywords& keys) {
+     123           8 :   TargetDistribution::registerKeywords(keys);
+     124          16 :   keys.add("numbered","CENTER","The center of each exponentially modified Gaussian distributions.");
+     125          16 :   keys.add("numbered","SIGMA","The sigma parameters for each exponentially modified Gaussian distributions.");
+     126          16 :   keys.add("numbered","LAMBDA","The lambda parameters for each exponentially modified Gaussian distributions");
+     127          16 :   keys.add("optional","WEIGHTS","The weights of the distributions. By default all are weighted equally.");
+     128           8 :   keys.use("WELLTEMPERED_FACTOR");
+     129           8 :   keys.use("SHIFT_TO_ZERO");
+     130           8 :   keys.use("NORMALIZE");
+     131           8 : }
+     132             : 
+     133             : 
+     134           6 : TD_ExponentiallyModifiedGaussian::TD_ExponentiallyModifiedGaussian(const ActionOptions& ao):
+     135             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     136          12 :   centers_(0),
+     137           6 :   sigmas_(0),
+     138           6 :   lambdas_(0),
+     139           6 :   weights_(0),
+     140          12 :   ncenters_(0)
+     141             : {
+     142           9 :   for(unsigned int i=1;; i++) {
+     143             :     std::vector<double> tmp_center;
+     144          30 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     145           9 :     centers_.push_back(tmp_center);
+     146           9 :   }
+     147           9 :   for(unsigned int i=1;; i++) {
+     148             :     std::vector<double> tmp_sigma;
+     149          30 :     if(!parseNumberedVector("SIGMA",i,tmp_sigma) ) {break;}
+     150          20 :     for(unsigned int k=0; k<tmp_sigma.size(); k++) {
+     151          11 :       if(tmp_sigma[k]<=0.0) {plumed_merror(getName()+": the values given in SIGMA should be positive");}
+     152             :     }
+     153           9 :     sigmas_.push_back(tmp_sigma);
+     154           9 :   }
+     155           9 :   for(unsigned int i=1;; i++) {
+     156             :     std::vector<double> tmp_lambda;
+     157          30 :     if(!parseNumberedVector("LAMBDA",i,tmp_lambda) ) {break;}
+     158          20 :     for(unsigned int k=0; k<tmp_lambda.size(); k++) {
+     159          11 :       if(tmp_lambda[k]<=0.0) {plumed_merror(getName()+": the values given in LAMBDA should be positive");}
+     160             :     }
+     161           9 :     lambdas_.push_back(tmp_lambda);
+     162           9 :   }
+     163             :   //
+     164           6 :   if(centers_.size()==0) {
+     165           0 :     plumed_merror(getName()+": CENTER keywords seem to be missing. Note that numbered keywords start at CENTER1.");
+     166             :   }
+     167             :   //
+     168           6 :   if(centers_.size()!=sigmas_.size() || centers_.size()!=lambdas_.size() ) {
+     169           0 :     plumed_merror(getName()+": there has to be an equal amount of CENTER, SIGMA, and LAMBDA keywords");
+     170             :   }
+     171             :   //
+     172           6 :   setDimension(centers_[0].size());
+     173           6 :   ncenters_ = centers_.size();
+     174             :   //
+     175             :   // check centers and sigmas
+     176          15 :   for(unsigned int i=0; i<ncenters_; i++) {
+     177           9 :     if(centers_[i].size()!=getDimension()) {
+     178           0 :       plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");
+     179             :     }
+     180           9 :     if(sigmas_[i].size()!=getDimension()) {
+     181           0 :       plumed_merror(getName()+": one of the SIGMA keyword does not match the given dimension");
+     182             :     }
+     183           9 :     if(lambdas_[i].size()!=getDimension()) {
+     184           0 :       plumed_merror(getName()+": one of the LAMBDA keyword does not match the given dimension");
+     185             :     }
+     186             :   }
+     187             :   //
+     188          12 :   parseVector("WEIGHTS",weights_);
+     189           6 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     190           6 :   if(centers_.size()!=weights_.size()) {
+     191           0 :     plumed_merror(getName()+": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");
+     192             :   }
+     193             :   //
+     194             :   double sum_weights=0.0;
+     195          15 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     196          15 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     197             :   //
+     198           6 :   checkRead();
+     199           6 : }
+     200             : 
+     201             : 
+     202       11206 : double TD_ExponentiallyModifiedGaussian::getValue(const std::vector<double>& argument) const {
+     203             :   double value=0.0;
+     204       33015 :   for(unsigned int i=0; i<ncenters_; i++) {
+     205       21809 :     value+=weights_[i]*ExponentiallyModifiedGaussianDiagonal(argument,centers_[i],sigmas_[i],lambdas_[i]);
+     206             :   }
+     207       11206 :   return value;
+     208             : }
+     209             : 
+     210             : 
+     211       21809 : double TD_ExponentiallyModifiedGaussian::ExponentiallyModifiedGaussianDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& sigma, const std::vector<double>& lambda) const {
+     212             :   double value = 1.0;
+     213       64020 :   for(unsigned int k=0; k<argument.size(); k++) {
+     214       42211 :     double arg1 = 0.5*lambda[k]*(2.0*center[k]+lambda[k]*sigma[k]*sigma[k]-2.0*argument[k]);
+     215       42211 :     double arg2 = (center[k]+lambda[k]*sigma[k]*sigma[k]-argument[k])/(sqrt(2.0)*sigma[k]);
+     216       42211 :     value *= 0.5*lambda[k]*exp(arg1)*erfc(arg2);
+     217             :   }
+     218       21809 :   return value;
+     219             : }
+     220             : 
+     221             : 
+     222             : 
+     223             : }
+     224             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Gaussian.cpp.func-sort-c.html b/coverage/ves/TD_Gaussian.cpp.func-sort-c.html new file mode 100644 index 000000000000..3809943249f0 --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Gaussian.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Gaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768490.5 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_GaussianC2ERKNS_13ActionOptionsE191
_ZN4PLMD3ves11TD_Gaussian16registerKeywordsERNS_8KeywordsE193
_ZNK4PLMD3ves11TD_Gaussian10Gaussian2DERKSt6vectorIdSaIdEES6_S6_S6_b40804
_ZNK4PLMD3ves11TD_Gaussian8getValueERKSt6vectorIdSaIdEE229739
_ZNK4PLMD3ves11TD_Gaussian16GaussianDiagonalERKSt6vectorIdSaIdEES6_S6_b292252
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Gaussian.cpp.func.html b/coverage/ves/TD_Gaussian.cpp.func.html new file mode 100644 index 000000000000..4085fac10d57 --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Gaussian.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Gaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768490.5 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_Gaussian16registerKeywordsERNS_8KeywordsE193
_ZN4PLMD3ves11TD_GaussianC2ERKNS_13ActionOptionsE191
_ZNK4PLMD3ves11TD_Gaussian10Gaussian2DERKSt6vectorIdSaIdEES6_S6_S6_b40804
_ZNK4PLMD3ves11TD_Gaussian16GaussianDiagonalERKSt6vectorIdSaIdEES6_S6_b292252
_ZNK4PLMD3ves11TD_Gaussian8getValueERKSt6vectorIdSaIdEE229739
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Gaussian.cpp.gcov.html b/coverage/ves/TD_Gaussian.cpp.gcov.html new file mode 100644 index 000000000000..601b714600d7 --- /dev/null +++ b/coverage/ves/TD_Gaussian.cpp.gcov.html @@ -0,0 +1,392 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Gaussian.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Gaussian.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:768490.5 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_GAUSSIAN
+      32             : /*
+      33             : Target distribution given by a sum of Gaussian kernels (static).
+      34             : 
+      35             : Employ a target distribution that is given by a sum of multivariate Gaussian (or normal)
+      36             : distributions, defined as
+      37             : \f[
+      38             : p(\mathbf{s}) = \sum_{i} \, w_{i} \, N(\mathbf{s};\mathbf{\mu}_{i},\mathbf{\Sigma}_{i})
+      39             : \f]
+      40             : where \f$\mathbf{\mu}_{i}=(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$
+      41             : and \f$\mathbf{\Sigma}_{i}\f$ are
+      42             : the center and the covariance matrix for the \f$i\f$-th Gaussian.
+      43             : The weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      44             : 
+      45             : By default the Gaussian distributions are considered as separable into
+      46             : independent one-dimensional Gaussian distributions. In other words,
+      47             : the covariance matrix is taken as diagonal
+      48             : \f$\mathbf{\Sigma}_{i}=(\sigma^2_{1,i},\sigma^2_{2,i},\ldots,\sigma^{2}_{d,i})\f$.
+      49             : The Gaussian distribution is then written as
+      50             : \f[
+      51             : N(\mathbf{s};\mathbf{\mu}_{i},\mathbf{\sigma}_{i}) =
+      52             : \prod^{d}_{k} \, \frac{1}{\sqrt{2\pi\sigma^2_{d,i}}} \,
+      53             : \exp\left(
+      54             : -\frac{(s_{d}-\mu_{d,i})^2}{2\sigma^2_{d,i}}
+      55             : \right)
+      56             : \f]
+      57             : where
+      58             : \f$\mathbf{\sigma}_{i}=(\sigma_{1,i},\sigma_{2,i},\ldots,\sigma_{d,i})\f$
+      59             : is the standard deviation.
+      60             : In this case you need to specify the centers \f$\mathbf{\mu}_{i}\f$ using the
+      61             : numbered CENTER keywords and the standard deviations \f$\mathbf{\sigma}_{i}\f$
+      62             : using the numbered SIGMA keywords.
+      63             : 
+      64             : For two arguments it is possible to employ
+      65             : [bivariate Gaussian kernels](https://en.wikipedia.org/wiki/Multivariate_normal_distribution)
+      66             : with correlation between arguments, defined as
+      67             : \f[
+      68             : N(\mathbf{s};\mathbf{\mu}_{i},\mathbf{\sigma}_{i},\rho_i) =
+      69             : \frac{1}{2 \pi \sigma_{1,i} \sigma_{2,i} \sqrt{1-\rho_i^2}}
+      70             : \,
+      71             : \exp\left(
+      72             : -\frac{1}{2(1-\rho_i^2)}
+      73             : \left[
+      74             : \frac{(s_{1}-\mu_{1,i})^2}{\sigma_{1,i}^2}+
+      75             : \frac{(s_{2}-\mu_{2,i})^2}{\sigma_{2,i}^2}-
+      76             : \frac{2 \rho_i (s_{1}-\mu_{1,i})(s_{2}-\mu_{2,i})}{\sigma_{1,i}\sigma_{2,i}}
+      77             : \right]
+      78             : \right)
+      79             : \f]
+      80             : where \f$\rho_i\f$ is the correlation between \f$s_{1}\f$ and \f$s_{2}\f$
+      81             : that goes from -1 to 1. In this case the covariance matrix is given as
+      82             : \f[
+      83             : \mathbf{\Sigma}=
+      84             : \left[
+      85             : \begin{array}{cc}
+      86             : \sigma^2_{1,i} & \rho_i \sigma_{1,i} \sigma_{2,i} \\
+      87             : \rho_i \sigma_{1,i} \sigma_{2,i} & \sigma^2_{2,i}
+      88             : \end{array}
+      89             : \right]
+      90             : \f]
+      91             : The correlation \f$\rho\f$ is given using
+      92             : the numbered CORRELATION keywords. A value of \f$\rho=0\f$ means
+      93             : that the arguments are considered as
+      94             : un-correlated, which is the default behavior.
+      95             : 
+      96             : The Gaussian distributions are always defined with the conventional
+      97             : normalization factor such that they are normalized to 1 over an unbounded
+      98             : region. However, in calculation within VES we normally consider bounded
+      99             : region on which the target distribution is defined. Thus, if the center of
+     100             : a Gaussian is close to the boundary of the region it can happen that the
+     101             : tails go outside the region. In that case it might be needed to use the
+     102             : NORMALIZE keyword to make sure that the target distribution is properly
+     103             : normalized to 1 over the bounded region. The code will issue a warning
+     104             : if that is needed.
+     105             : 
+     106             : For periodic CVs it is generally better to use \ref TD_VONMISES "Von Mises"
+     107             : distributions instead of Gaussian kernels as these distributions properly
+     108             : account for the periodicity of the CVs.
+     109             : 
+     110             : 
+     111             : \par Examples
+     112             : 
+     113             : One single Gaussian kernel in one-dimension.
+     114             : \plumedfile
+     115             : td: TD_GAUSSIAN CENTER1=-1.5 SIGMA1=0.8
+     116             : \endplumedfile
+     117             : 
+     118             : Sum of three Gaussian kernels in two-dimensions with equal weights as
+     119             : no weights are given.
+     120             : \plumedfile
+     121             : TD_GAUSSIAN ...
+     122             :  CENTER1=-1.5,+1.5 SIGMA1=0.8,0.3
+     123             :  CENTER2=+1.5,-1.5 SIGMA2=0.3,0.8
+     124             :  CENTER3=+1.5,+1.5 SIGMA3=0.4,0.4
+     125             :  LABEL=td
+     126             : ... TD_GAUSSIAN
+     127             : \endplumedfile
+     128             : 
+     129             : Sum of three Gaussian kernels in two-dimensions which
+     130             : are weighted unequally. Note that weights are automatically
+     131             : normalized to 1 so that WEIGHTS=1.0,2.0,1.0 is equal to
+     132             : specifying WEIGHTS=0.25,0.50,0.25.
+     133             : \plumedfile
+     134             : TD_GAUSSIAN ...
+     135             :  CENTER1=-1.5,+1.5 SIGMA1=0.8,0.3
+     136             :  CENTER2=+1.5,-1.5 SIGMA2=0.3,0.8
+     137             :  CENTER3=+1.5,+1.5 SIGMA3=0.4,0.4
+     138             :  WEIGHTS=1.0,2.0,1.0
+     139             :  LABEL=td
+     140             : ... TD_GAUSSIAN
+     141             : \endplumedfile
+     142             : 
+     143             : Sum of two bivariate Gaussian kernels where there is correlation of
+     144             : \f$\rho_{2}=0.75\f$ between the two arguments for the second Gaussian.
+     145             : \plumedfile
+     146             : TD_GAUSSIAN ...
+     147             :  CENTER1=-1.5,+1.5 SIGMA1=0.8,0.3
+     148             :  CENTER2=+1.5,-1.5 SIGMA2=0.3,0.8 CORRELATION2=0.75
+     149             :  LABEL=td
+     150             : ... TD_GAUSSIAN
+     151             : \endplumedfile
+     152             : 
+     153             : 
+     154             : 
+     155             : 
+     156             : 
+     157             : */
+     158             : //+ENDPLUMEDOC
+     159             : 
+     160             : class TD_Gaussian: public TargetDistribution {
+     161             :   std::vector< std::vector<double> > centers_;
+     162             :   std::vector< std::vector<double> > sigmas_;
+     163             :   std::vector< std::vector<double> > correlation_;
+     164             :   std::vector<double> weights_;
+     165             :   bool diagonal_;
+     166             :   unsigned int ncenters_;
+     167             :   double GaussianDiagonal(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const bool normalize=true) const;
+     168             :   double Gaussian2D(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const bool normalize=true) const;
+     169             : public:
+     170             :   static void registerKeywords(Keywords&);
+     171             :   explicit TD_Gaussian(const ActionOptions& ao);
+     172             :   double getValue(const std::vector<double>&) const override;
+     173             : };
+     174             : 
+     175             : 
+     176             : PLUMED_REGISTER_ACTION(TD_Gaussian,"TD_GAUSSIAN")
+     177             : 
+     178             : 
+     179         193 : void TD_Gaussian::registerKeywords(Keywords& keys) {
+     180         193 :   TargetDistribution::registerKeywords(keys);
+     181         386 :   keys.add("numbered","CENTER","The centers of the Gaussian distributions.");
+     182         386 :   keys.add("numbered","SIGMA","The standard deviations of the Gaussian distributions.");
+     183         386 :   keys.add("numbered","CORRELATION","The correlation for two-dimensional bivariate Gaussian distributions. Only works for two arguments. The value should be between -1 and 1. If no value is given the Gaussian kernels is considered as un-correlated (i.e. value of 0.0).");
+     184         386 :   keys.add("optional","WEIGHTS","The weights of the Gaussian distributions. Have to be as many as the number of centers given with the numbered CENTER keywords. If no weights are given the distributions are weighted equally. The weights are automatically normalized to 1.");
+     185         193 :   keys.use("WELLTEMPERED_FACTOR");
+     186         193 :   keys.use("SHIFT_TO_ZERO");
+     187         193 :   keys.use("NORMALIZE");
+     188         193 : }
+     189             : 
+     190             : 
+     191         191 : TD_Gaussian::TD_Gaussian(const ActionOptions& ao):
+     192             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     193         382 :   centers_(0),
+     194         191 :   sigmas_(0),
+     195         191 :   correlation_(0),
+     196         191 :   weights_(0),
+     197         191 :   diagonal_(true),
+     198         382 :   ncenters_(0)
+     199             : {
+     200         211 :   for(unsigned int i=1;; i++) {
+     201             :     std::vector<double> tmp_center;
+     202         804 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     203         211 :     centers_.push_back(tmp_center);
+     204         211 :   }
+     205         211 :   for(unsigned int i=1;; i++) {
+     206             :     std::vector<double> tmp_sigma;
+     207         804 :     if(!parseNumberedVector("SIGMA",i,tmp_sigma) ) {break;}
+     208         211 :     sigmas_.push_back(tmp_sigma);
+     209         211 :   }
+     210             : 
+     211         191 :   if(centers_.size()==0) {
+     212           0 :     plumed_merror(getName()+": CENTER keywords seem to be missing. Note that numbered keywords start at CENTER1.");
+     213             :   }
+     214             :   //
+     215         191 :   if(centers_.size()!=sigmas_.size()) {
+     216           0 :     plumed_merror(getName()+": there has to be an equal amount of CENTER and SIGMA keywords");
+     217             :   }
+     218             :   //
+     219         191 :   setDimension(centers_[0].size());
+     220         191 :   ncenters_ = centers_.size();
+     221             :   // check centers and sigmas
+     222         402 :   for(unsigned int i=0; i<ncenters_; i++) {
+     223         211 :     if(centers_[i].size()!=getDimension()) {
+     224           0 :       plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");
+     225             :     }
+     226         211 :     if(sigmas_[i].size()!=getDimension()) {
+     227           0 :       plumed_merror(getName()+": one of the SIGMA keyword does not match the given dimension");
+     228             :     }
+     229             :   }
+     230             :   //
+     231         191 :   correlation_.resize(ncenters_);
+     232             : 
+     233         402 :   for(unsigned int i=0; i<ncenters_; i++) {
+     234             :     std::vector<double> corr;
+     235         422 :     parseNumberedVector("CORRELATION",(i+1),corr);
+     236         211 :     if(corr.size()>0) {
+     237           3 :       diagonal_ = false;
+     238             :     }
+     239             :     else {
+     240         208 :       corr.assign(1,0.0);
+     241             :     }
+     242         211 :     correlation_[i] = corr;
+     243             :   }
+     244             : 
+     245         191 :   if(!diagonal_ && getDimension()!=2) {
+     246           0 :     plumed_merror(getName()+": CORRELATION is only defined for two-dimensional Gaussians for now.");
+     247             :   }
+     248         402 :   for(unsigned int i=0; i<correlation_.size(); i++) {
+     249         211 :     if(correlation_[i].size()!=1) {
+     250           0 :       plumed_merror(getName()+": only one value should be given in CORRELATION");
+     251             :     }
+     252         422 :     for(unsigned int k=0; k<correlation_[i].size(); k++) {
+     253         211 :       if(correlation_[i][k] <= -1.0 ||  correlation_[i][k] >= 1.0) {
+     254           0 :         plumed_merror(getName()+": values given in CORRELATION should be between -1.0 and 1.0" );
+     255             :       }
+     256             :     }
+     257             :   }
+     258             :   //
+     259         382 :   parseVector("WEIGHTS",weights_);
+     260         191 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     261         191 :   if(centers_.size()!=weights_.size()) {
+     262           0 :     plumed_merror(getName()+": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");
+     263             :   }
+     264             :   //
+     265             :   double sum_weights=0.0;
+     266         402 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     267         402 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     268             :   //
+     269         191 :   checkRead();
+     270         191 : }
+     271             : 
+     272             : 
+     273      229739 : double TD_Gaussian::getValue(const std::vector<double>& argument) const {
+     274             :   double value=0.0;
+     275      229739 :   if(diagonal_) {
+     276      501589 :     for(unsigned int i=0; i<ncenters_; i++) {
+     277      292252 :       value+=weights_[i]*GaussianDiagonal(argument, centers_[i], sigmas_[i]);
+     278             :     }
+     279             :   }
+     280       20402 :   else if(!diagonal_ && getDimension()==2) {
+     281       61206 :     for(unsigned int i=0; i<ncenters_; i++) {
+     282       40804 :       value+=weights_[i]*Gaussian2D(argument, centers_[i], sigmas_[i],correlation_[i]);
+     283             :     }
+     284             :   }
+     285      229739 :   return value;
+     286             : }
+     287             : 
+     288             : 
+     289      292252 : double TD_Gaussian::GaussianDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& sigma, bool normalize) const {
+     290             :   double value = 1.0;
+     291      828323 :   for(unsigned int k=0; k<argument.size(); k++) {
+     292      536071 :     double arg=(argument[k]-center[k])/sigma[k];
+     293      536071 :     double tmp_exp = exp(-0.5*arg*arg);
+     294      536071 :     if(normalize) {tmp_exp/=(sigma[k]*sqrt(2.0*pi));}
+     295      536071 :     value*=tmp_exp;
+     296             :   }
+     297      292252 :   return value;
+     298             : }
+     299             : 
+     300             : 
+     301       40804 : double TD_Gaussian::Gaussian2D(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& sigma, const std::vector<double>& correlation, bool normalize) const {
+     302       40804 :   double arg1 = (argument[0]-center[0])/sigma[0];
+     303       40804 :   double arg2 = (argument[1]-center[1])/sigma[1];
+     304       40804 :   double corr = correlation[0];
+     305       40804 :   double value = (arg1*arg1 + arg2*arg2 - 2.0*corr*arg1*arg2);
+     306       40804 :   value *= -1.0 / ( 2.0*(1.0-corr*corr) );
+     307       40804 :   value = exp(value);
+     308       40804 :   if(normalize) {
+     309       40804 :     value /=  2*pi*sigma[0]*sigma[1]*sqrt(1.0-corr*corr);
+     310             :   }
+     311       40804 :   return value;
+     312             : }
+     313             : 
+     314             : }
+     315             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html new file mode 100644 index 000000000000..beccf8ad16dd --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedExtremeValue.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedExtremeValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves26TD_GeneralizedExtremeValueC2ERKNS_13ActionOptionsE5
_ZN4PLMD3ves26TD_GeneralizedExtremeValue16registerKeywordsERNS_8KeywordsE7
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue11GEVdiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_1605
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue8getValueERKSt6vectorIdSaIdEE1605
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html new file mode 100644 index 000000000000..fbaa2a0d2be4 --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedExtremeValue.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedExtremeValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves26TD_GeneralizedExtremeValue16registerKeywordsERNS_8KeywordsE7
_ZN4PLMD3ves26TD_GeneralizedExtremeValueC2ERKNS_13ActionOptionsE5
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue11GEVdiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_1605
_ZNK4PLMD3ves26TD_GeneralizedExtremeValue8getValueERKSt6vectorIdSaIdEE1605
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html b/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html new file mode 100644 index 000000000000..12ce91836cf9 --- /dev/null +++ b/coverage/ves/TD_GeneralizedExtremeValue.cpp.gcov.html @@ -0,0 +1,254 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedExtremeValue.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedExtremeValue.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3838100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_GENERALIZED_EXTREME_VALUE
+      32             : /*
+      33             : Generalized extreme value distribution (static).
+      34             : 
+      35             : Employ a target distribution given by a
+      36             : [generalized extreme value distribution](https://en.wikipedia.org/wiki/Generalized_extreme_value_distribution)
+      37             : that is defined as
+      38             : \f[
+      39             : p(s) =
+      40             : \frac{1}{\sigma} \, t(s)^{\xi+1} \, e^{-t(s)},
+      41             : \f]
+      42             : where
+      43             : \f[
+      44             : t(s) =
+      45             : \begin{cases}
+      46             : \left( 1 + \xi \left( \frac{s-\mu}{\sigma} \right) \right)^{-1/\xi} & \mathrm{if\ }\xi \neq 0 \\
+      47             : \exp\left(- \frac{s-\mu}{\sigma} \right) & \mathrm{if\ } \xi = 0
+      48             : \end{cases},
+      49             : \f]
+      50             : and \f$\mu\f$ is the location parameter which approximately determines the location of the
+      51             : maximum of the distribution, \f$\sigma>0\f$ is the scale parameter that determines the
+      52             : broadness of the distribution, and \f$\xi\f$ is the shape parameter that determines
+      53             : the tail behavior of the distribution. For \f$\xi=0\f$, \f$\xi>0\f$, and \f$\xi<0\f$
+      54             : the Gumbel, Frechet, and Weibull families of distributions are obtained, respectively.
+      55             : 
+      56             : The location parameter \f$\mu\f$ is given using the LOCATION keyword, the scale parameter \f$\sigma\f$
+      57             : using the SCALE keyword, and the shape parameter \f$\xi\f$ using the SHAPE
+      58             : keyword.
+      59             : 
+      60             : This target distribution action is only defined for one dimension, for multiple dimensions
+      61             : it should be used in combination with \ref TD_PRODUCT_DISTRIBUTION action.
+      62             : 
+      63             : \par Examples
+      64             : 
+      65             : Generalized extreme value distribution with \f$\mu=0.0\f$, \f$\sigma=2.0\f$, and \f$\xi=0.0\f$ (Gumbel distribution)
+      66             : \plumedfile
+      67             : td: TD_GENERALIZED_EXTREME_VALUE  LOCATION=0.0  SCALE=2.0 SHAPE=0.0
+      68             : \endplumedfile
+      69             : 
+      70             : 
+      71             : Generalized extreme value distribution with \f$\mu=-5.0\f$, \f$\sigma=1.0\f$, and \f$\xi=0.5\f$ (Frechet distribution)
+      72             : \plumedfile
+      73             : td: TD_GENERALIZED_EXTREME_VALUE  LOCATION=-5.0  SCALE=1.0 SHAPE=0.5
+      74             : \endplumedfile
+      75             : 
+      76             : 
+      77             : Generalized extreme value distribution with \f$\mu=5.0\f$, \f$\sigma=2.0\f$, and \f$\xi=-0.5\f$ (Weibull distribution)
+      78             : \plumedfile
+      79             : td: TD_GENERALIZED_EXTREME_VALUE  LOCATION=5.0  SCALE=1.0 SHAPE=-0.5
+      80             : \endplumedfile
+      81             : 
+      82             : 
+      83             : The generalized extreme value distribution is only defined for one dimension so for multiple
+      84             : dimensions we have to use it in combination with the \ref TD_PRODUCT_DISTRIBUTION action as shown in
+      85             : the following example where we have a Generalized extreme value distribution for argument 1
+      86             : and uniform distribution for argument 2
+      87             : \plumedfile
+      88             : td_gev: TD_GENERALIZED_EXTREME_VALUE  LOCATION=-5.0  SCALE=1.0 SHAPE=0.5
+      89             : 
+      90             : td_uni: TD_UNIFORM
+      91             : 
+      92             : td_pd: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=td_gev,td_uni
+      93             : \endplumedfile
+      94             : 
+      95             : 
+      96             : */
+      97             : //+ENDPLUMEDOC
+      98             : 
+      99             : class TD_GeneralizedExtremeValue: public TargetDistribution {
+     100             :   std::vector<double> center_;
+     101             :   std::vector<double> scale_;
+     102             :   std::vector<double> shape_;
+     103             :   std::vector<double> normalization_;
+     104             :   double GEVdiagonal(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&) const;
+     105             : public:
+     106             :   static void registerKeywords(Keywords&);
+     107             :   explicit TD_GeneralizedExtremeValue(const ActionOptions& ao);
+     108             :   double getValue(const std::vector<double>&) const override;
+     109             : };
+     110             : 
+     111             : 
+     112             : PLUMED_REGISTER_ACTION(TD_GeneralizedExtremeValue,"TD_GENERALIZED_EXTREME_VALUE")
+     113             : 
+     114             : 
+     115           7 : void TD_GeneralizedExtremeValue::registerKeywords(Keywords& keys) {
+     116           7 :   TargetDistribution::registerKeywords(keys);
+     117          14 :   keys.add("compulsory","LOCATION","The mu parameter of the generalized extreme value distribution.");
+     118          14 :   keys.add("compulsory","SCALE","The sigma parameter for the generalized extreme value distribution given as a positive number.");
+     119          14 :   keys.add("compulsory","SHAPE","The xi parameter for the generalized extreme value distribution.");
+     120           7 :   keys.use("WELLTEMPERED_FACTOR");
+     121           7 :   keys.use("SHIFT_TO_ZERO");
+     122           7 :   keys.use("NORMALIZE");
+     123           7 : }
+     124             : 
+     125             : 
+     126           5 : TD_GeneralizedExtremeValue::TD_GeneralizedExtremeValue(const ActionOptions& ao):
+     127             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     128          10 :   center_(0),
+     129           5 :   scale_(0),
+     130           5 :   shape_(0),
+     131          10 :   normalization_(0)
+     132             : {
+     133           5 :   parseVector("LOCATION",center_);
+     134           5 :   parseVector("SCALE",scale_);
+     135          10 :   parseVector("SHAPE",shape_);
+     136             : 
+     137           5 :   setDimension(center_.size());
+     138           5 :   if(getDimension()>1) {plumed_merror(getName()+": only defined for one dimension, for multiple dimensions it should be used in combination with the TD_PRODUCT_DISTRIBUTION action.");}
+     139           5 :   if(scale_.size()!=getDimension()) {plumed_merror(getName()+": the SCALE keyword does not match the given dimension in MINIMA");}
+     140           5 :   if(shape_.size()!=getDimension()) {plumed_merror(getName()+": the SHAPE keyword does not match the given dimension in MINIMA");}
+     141             : 
+     142           5 :   normalization_.resize(getDimension());
+     143          10 :   for(unsigned int k=0; k<getDimension(); k++) {
+     144           5 :     if(scale_[k]<0.0) {plumed_merror(getName()+": the value given for the scale parameter in SCALE should be larger than 0.0");}
+     145           5 :     normalization_[k] = 1.0/scale_[k];
+     146             :   }
+     147           5 :   checkRead();
+     148           5 : }
+     149             : 
+     150             : 
+     151        1605 : double TD_GeneralizedExtremeValue::getValue(const std::vector<double>& argument) const {
+     152        1605 :   return GEVdiagonal(argument,center_,scale_,shape_,normalization_);
+     153             : }
+     154             : 
+     155             : 
+     156        1605 : double TD_GeneralizedExtremeValue::GEVdiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& scale, const std::vector<double>& shape, const std::vector<double>& normalization) const {
+     157             :   double value = 1.0;
+     158        2940 :   for(unsigned int k=0; k<argument.size(); k++) {
+     159        1605 :     double arg=(argument[k]-center[k])/scale[k];
+     160             :     double tx;
+     161        1605 :     if(shape_[k]!=0.0) {
+     162        1404 :       if( shape_[k]>0 && argument[k] <= (center[k]-scale[k]/shape[k]) ) {return 0.0;}
+     163        1214 :       if( shape_[k]<0 && argument[k] > (center[k]-scale[k]/shape[k]) ) {return 0.0;}
+     164        1134 :       tx = pow( (1.0+arg*shape[k]), -1.0/shape[k] );
+     165             :     }
+     166             :     else {
+     167         201 :       tx = exp(-arg);
+     168             :     }
+     169        1335 :     value *= normalization[k] * pow(tx,shape[k]+1.0) * exp(-tx);
+     170             :   }
+     171             :   return value;
+     172             : }
+     173             : 
+     174             : 
+     175             : 
+     176             : }
+     177             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html b/coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html new file mode 100644 index 000000000000..487ff14965e8 --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedNormal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedNormal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636991.3 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20TD_GeneralizedNormalC2ERKNS_13ActionOptionsE8
_ZN4PLMD3ves20TD_GeneralizedNormal16registerKeywordsERNS_8KeywordsE10
_ZNK4PLMD3ves20TD_GeneralizedNormal8getValueERKSt6vectorIdSaIdEE21608
_ZNK4PLMD3ves20TD_GeneralizedNormal24ExponentialPowerDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_53015
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedNormal.cpp.func.html b/coverage/ves/TD_GeneralizedNormal.cpp.func.html new file mode 100644 index 000000000000..122cd72e5fee --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedNormal.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedNormal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636991.3 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20TD_GeneralizedNormal16registerKeywordsERNS_8KeywordsE10
_ZN4PLMD3ves20TD_GeneralizedNormalC2ERKNS_13ActionOptionsE8
_ZNK4PLMD3ves20TD_GeneralizedNormal24ExponentialPowerDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_53015
_ZNK4PLMD3ves20TD_GeneralizedNormal8getValueERKSt6vectorIdSaIdEE21608
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html b/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html new file mode 100644 index 000000000000..450df8489403 --- /dev/null +++ b/coverage/ves/TD_GeneralizedNormal.cpp.gcov.html @@ -0,0 +1,304 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_GeneralizedNormal.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_GeneralizedNormal.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:636991.3 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_GENERALIZED_NORMAL
+      32             : /*
+      33             : Target distribution given by a sum of generalized normal distributions (static).
+      34             : 
+      35             : Employ a target distribution that is given by a sum where each
+      36             : term is a product of one-dimensional
+      37             : [generalized normal distributions](https://en.wikipedia.org/wiki/Generalized_normal_distribution)
+      38             : (version 1, also know as an exponential power distribution), defined as
+      39             : \f[
+      40             : p(\mathbf{s}) = \sum_{i} \, w_{i}
+      41             : \prod_{k}^{d}
+      42             : \frac{\beta_{k,i}}{2 \, \alpha_{k,i} \, \Gamma(1/\beta_{k,i})}
+      43             : \exp\left( -\left\vert \frac{s_{k}-\mu_{k,i}}{\alpha_{k,i}} \right\vert^{\beta_{k,i}} \right)
+      44             : \f]
+      45             : where \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$
+      46             : are the centers of the distributions,
+      47             : \f$(\alpha_{1,i},\alpha_{2,i},\ldots,\alpha_{d,i})\f$ are the scale
+      48             : parameters of the distributions,
+      49             : \f$(\beta_{1,i},\beta_{2,i},\ldots,\beta_{d,i})\f$ are the shape
+      50             : parameters of the distributions, and \f$\Gamma(x)\f$ is the
+      51             : gamma function.
+      52             : The weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      53             : 
+      54             : Employing \f$\beta=2\f$ results in a
+      55             : Gaussian (normal) distributions with mean
+      56             : \f$\mu\f$ and variance \f$\alpha^2/2\f$,
+      57             : \f$\beta=1\f$ gives the Laplace distribution, and
+      58             : the limit \f$\beta \to \infty\f$ results in a
+      59             : uniform  distribution on the interval \f$[\mu-\alpha,\mu+\alpha]\f$.
+      60             : 
+      61             : The centers \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$
+      62             : are given using the numbered CENTER keywords, the scale
+      63             : parameters \f$(\alpha_{1,i},\alpha_{2,i},\ldots,\alpha_{d,i})\f$
+      64             : using the numbered SCALE keywords, and the shape parameters
+      65             : \f$(\beta_{1,i},\beta_{2,i},\ldots,\beta_{d,i})\f$ using the
+      66             : numbered SHAPE keywords.
+      67             : The weights are given using the WEIGHTS keywords, if no weights are
+      68             : given are all terms weighted equally.
+      69             : 
+      70             : \par Examples
+      71             : 
+      72             : A generalized normal distribution in one-dimensional
+      73             : \plumedfile
+      74             : td1: TD_GENERALIZED_NORMAL CENTER1=+20.0  ALPHA1=5.0  BETA1=4.0
+      75             : \endplumedfile
+      76             : 
+      77             : A sum of two one-dimensional generalized normal distributions
+      78             : \plumedfile
+      79             : TD_GENERALIZED_NORMAL ...
+      80             :  CENTER1=+20.0  ALPHA1=5.0  BETA1=4.0
+      81             :  CENTER2=-20.0  ALPHA2=5.0  BETA2=3.0
+      82             :  LABEL=td1
+      83             : ... TD_GENERALIZED_NORMAL
+      84             : \endplumedfile
+      85             : 
+      86             : A sum of two two-dimensional generalized normal distributions
+      87             : \plumedfile
+      88             : TD_GENERALIZED_NORMAL ...
+      89             :  CENTER1=-20.0,-20.0 ALPHA1=5.0,3.0 BETA1=2.0,4.0
+      90             :  CENTER2=-20.0,+20.0 ALPHA2=3.0,5.0 BETA2=4.0,2.0
+      91             :  WEIGHTS=2.0,1.0
+      92             :  LABEL=td1
+      93             : ... TD_GENERALIZED_NORMAL
+      94             : \endplumedfile
+      95             : 
+      96             : */
+      97             : //+ENDPLUMEDOC
+      98             : 
+      99             : class TD_GeneralizedNormal: public TargetDistribution {
+     100             :   std::vector< std::vector<double> > centers_;
+     101             :   std::vector< std::vector<double> > alphas_;
+     102             :   std::vector< std::vector<double> > betas_;
+     103             :   std::vector< std::vector<double> > normalization_;
+     104             :   std::vector<double> weights_;
+     105             :   unsigned int ncenters_;
+     106             :   double ExponentialPowerDiagonal(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&) const;
+     107             : public:
+     108             :   static void registerKeywords(Keywords&);
+     109             :   explicit TD_GeneralizedNormal(const ActionOptions& ao);
+     110             :   double getValue(const std::vector<double>&) const override;
+     111             : };
+     112             : 
+     113             : 
+     114             : PLUMED_REGISTER_ACTION(TD_GeneralizedNormal,"TD_GENERALIZED_NORMAL")
+     115             : 
+     116             : 
+     117          10 : void TD_GeneralizedNormal::registerKeywords(Keywords& keys) {
+     118          10 :   TargetDistribution::registerKeywords(keys);
+     119          20 :   keys.add("numbered","CENTER","The center of each generalized normal distribution.");
+     120          20 :   keys.add("numbered","ALPHA","The alpha parameters for each generalized normal distribution.");
+     121          20 :   keys.add("numbered","BETA","The beta parameters for each generalized normal distribution.");
+     122          20 :   keys.add("optional","WEIGHTS","The weights of the generalized normal distribution. By default all are weighted equally.");
+     123          10 :   keys.use("WELLTEMPERED_FACTOR");
+     124          10 :   keys.use("SHIFT_TO_ZERO");
+     125          10 :   keys.use("NORMALIZE");
+     126          10 : }
+     127             : 
+     128             : 
+     129           8 : TD_GeneralizedNormal::TD_GeneralizedNormal(const ActionOptions& ao):
+     130             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     131          16 :   centers_(0),
+     132           8 :   alphas_(0),
+     133           8 :   betas_(0),
+     134           8 :   normalization_(0),
+     135           8 :   weights_(0),
+     136          16 :   ncenters_(0)
+     137             : {
+     138          15 :   for(unsigned int i=1;; i++) {
+     139             :     std::vector<double> tmp_center;
+     140          46 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     141          15 :     centers_.push_back(tmp_center);
+     142          15 :   }
+     143          15 :   for(unsigned int i=1;; i++) {
+     144             :     std::vector<double> tmp_alpha;
+     145          46 :     if(!parseNumberedVector("ALPHA",i,tmp_alpha) ) {break;}
+     146          35 :     for(unsigned int k=0; k<tmp_alpha.size(); k++) {
+     147          20 :       if(tmp_alpha[k]<=0.0) {plumed_merror(getName()+": the values given in ALPHA should be positive");}
+     148             :     }
+     149          15 :     alphas_.push_back(tmp_alpha);
+     150          15 :   }
+     151          15 :   for(unsigned int i=1;; i++) {
+     152             :     std::vector<double> tmp_beta;
+     153          46 :     if(!parseNumberedVector("BETA",i,tmp_beta) ) {break;}
+     154          35 :     for(unsigned int k=0; k<tmp_beta.size(); k++) {
+     155          20 :       if(tmp_beta[k]<=0.0) {plumed_merror(getName()+": the values given in BETA should be positive");}
+     156             :     }
+     157          15 :     betas_.push_back(tmp_beta);
+     158          15 :   }
+     159             :   //
+     160           8 :   if(centers_.size()==0) {
+     161           0 :     plumed_merror(getName()+": CENTER keywords seem to be missing. Note that numbered keywords start at CENTER1.");
+     162             :   }
+     163             :   //
+     164           8 :   if(centers_.size()!=alphas_.size() || centers_.size()!=betas_.size() ) {
+     165           0 :     plumed_merror(getName()+": there has to be an equal amount of CENTER, ALPHA, and BETA keywords");
+     166             :   }
+     167             :   //
+     168           8 :   setDimension(centers_[0].size());
+     169           8 :   ncenters_ = centers_.size();
+     170             :   //
+     171             :   // check centers and sigmas
+     172          23 :   for(unsigned int i=0; i<ncenters_; i++) {
+     173          15 :     if(centers_[i].size()!=getDimension()) {
+     174           0 :       plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");
+     175             :     }
+     176          15 :     if(alphas_[i].size()!=getDimension()) {
+     177           0 :       plumed_merror(getName()+": one of the ALPHA keyword does not match the given dimension");
+     178             :     }
+     179          15 :     if(betas_[i].size()!=getDimension()) {
+     180           0 :       plumed_merror(getName()+": one of the BETA keyword does not match the given dimension");
+     181             :     }
+     182             :   }
+     183             :   //
+     184          16 :   parseVector("WEIGHTS",weights_);
+     185           8 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     186           8 :   if(centers_.size()!=weights_.size()) {
+     187           0 :     plumed_merror(getName()+": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");
+     188             :   }
+     189             :   //
+     190             :   double sum_weights=0.0;
+     191          23 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     192          23 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     193             :   //
+     194           8 :   normalization_.resize(ncenters_);
+     195          23 :   for(unsigned int i=0; i<ncenters_; i++) {
+     196          15 :     normalization_[i].resize(getDimension());
+     197          35 :     for(unsigned int k=0; k<getDimension(); k++) {
+     198          20 :       normalization_[i][k] = 0.5*betas_[i][k]/(alphas_[i][k]*tgamma(1.0/betas_[i][k]));
+     199             :     }
+     200             :   }
+     201           8 :   checkRead();
+     202           8 : }
+     203             : 
+     204             : 
+     205       21608 : double TD_GeneralizedNormal::getValue(const std::vector<double>& argument) const {
+     206             :   double value=0.0;
+     207       74623 :   for(unsigned int i=0; i<ncenters_; i++) {
+     208       53015 :     value+=weights_[i]*ExponentialPowerDiagonal(argument,centers_[i],alphas_[i],betas_[i],normalization_[i]);
+     209             :   }
+     210       21608 :   return value;
+     211             : }
+     212             : 
+     213             : 
+     214       53015 : double TD_GeneralizedNormal::ExponentialPowerDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& alpha, const std::vector<double>& beta, const std::vector<double>& normalization) const {
+     215             :   double value = 1.0;
+     216      157035 :   for(unsigned int k=0; k<argument.size(); k++) {
+     217      104020 :     double arg=(std::abs(argument[k]-center[k]))/alpha[k];
+     218      104020 :     arg = pow(arg,beta[k]);
+     219      104020 :     value*=normalization[k]*exp(-arg);
+     220             :   }
+     221       53015 :   return value;
+     222             : }
+     223             : 
+     224             : 
+     225             : 
+     226             : }
+     227             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Grid.cpp.func-sort-c.html b/coverage/ves/TD_Grid.cpp.func-sort-c.html new file mode 100644 index 000000000000..a9958efece6b --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Grid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:555894.8 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7TD_GridC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves7TD_Grid16registerKeywordsERNS_8KeywordsE11
_ZNK4PLMD3ves7TD_Grid8getValueERKSt6vectorIdSaIdEE49369
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Grid.cpp.func.html b/coverage/ves/TD_Grid.cpp.func.html new file mode 100644 index 000000000000..94a771d5e096 --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Grid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:555894.8 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7TD_Grid16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves7TD_GridC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves7TD_Grid8getValueERKSt6vectorIdSaIdEE49369
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Grid.cpp.gcov.html b/coverage/ves/TD_Grid.cpp.gcov.html new file mode 100644 index 000000000000..904c95912b4c --- /dev/null +++ b/coverage/ves/TD_Grid.cpp.gcov.html @@ -0,0 +1,295 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Grid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Grid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:555894.8 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : #include "VesTools.h"
+      26             : #include "GridLinearInterpolation.h"
+      27             : 
+      28             : #include "core/ActionRegister.h"
+      29             : #include "tools/Grid.h"
+      30             : #include "core/Value.h"
+      31             : #include "tools/File.h"
+      32             : 
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace ves {
+      36             : 
+      37             : 
+      38             : //+PLUMEDOC VES_TARGETDIST TD_GRID
+      39             : /*
+      40             : Target distribution from an external grid file (static).
+      41             : 
+      42             : Using this keyword you can use a target distribution that is read from an
+      43             : external grid file that is in the proper PLUMED file format. You do not to
+      44             : give any information about the external grid file as all relevant information
+      45             : should be automatically detected. It is assumed that the distribution read in
+      46             : from the grid is a proper probability distribution, i.e. always non-negative
+      47             : and can be normalized.
+      48             : 
+      49             : By default the target distribution from the external grid is always normalized
+      50             : inside the code. You can disable this normalization by using DO_NOT_NORMALIZE
+      51             : keyword. However, be warned that this will generally lead to the wrong
+      52             : behavior if the distribution from the external grid is not properly
+      53             : normalized to 1.
+      54             : 
+      55             : If the distribution from the external grid file has for some reason
+      56             : negative values can you use the SHIFT keyword to shift the distribution
+      57             : by a given value. Another option is to use
+      58             : the SHIFT_TO_ZERO keyword to shift the minimum of the distribution to zero.
+      59             : 
+      60             : Note that the number of grid bins used in the external grid file do not have
+      61             : to be the same as used in the bias or action where the target distribution is
+      62             : employed as the code will employ a linear (or bilinear for two dimensions)
+      63             : interpolation to calculate values. Currently only one or two dimensional grids
+      64             : are supported.
+      65             : 
+      66             : It can happen that the intervals on which the target distribution is defined is
+      67             : larger than the intervals covered by the external grid file. In this case the
+      68             : default option is to consider the target distribution as continuous such that
+      69             : values outside the boundary of the external grid file are the same as at
+      70             : the boundary. This can be changed by using the ZERO_OUTSIDE keyword which
+      71             : will make values outside to be taken as zero.
+      72             : 
+      73             : \par Examples
+      74             : 
+      75             : Generally you only need to provide the the filename of the external grid
+      76             : file.
+      77             : \plumedfile
+      78             : td: TD_GRID FILE=input-grid.data
+      79             : \endplumedfile
+      80             : 
+      81             : The input grid is then specified using the usual format employed by PLUMED an example of which
+      82             : is shown below:
+      83             : 
+      84             : \auxfile{input-grid.data}
+      85             : #! FIELDS d1 external.bias der_d1
+      86             : #! SET min_d1 1.14
+      87             : #! SET max_d1 1.32
+      88             : #! SET nbins_d1 6
+      89             : #! SET periodic_d1 false
+      90             :    1.1400   0.0031   0.1101
+      91             :    1.1700   0.0086   0.2842
+      92             :    1.2000   0.0222   0.6648
+      93             :    1.2300   0.0521   1.4068
+      94             :    1.2600   0.1120   2.6873
+      95             :    1.2900   0.2199   4.6183
+      96             :    1.3200   0.3948   7.1055
+      97             : \endauxfile
+      98             : 
+      99             : */
+     100             : //+ENDPLUMEDOC
+     101             : 
+     102             : 
+     103             : class TD_Grid : public TargetDistribution {
+     104             :   std::unique_ptr<GridBase> distGrid_;
+     105             :   std::vector<double> minima_;
+     106             :   std::vector<double> maxima_;
+     107             :   std::vector<bool> periodic_;
+     108             :   bool zero_outside_;
+     109             :   double shift_;
+     110             : public:
+     111             :   static void registerKeywords( Keywords&);
+     112             :   explicit TD_Grid(const ActionOptions& ao);
+     113             :   double getValue(const std::vector<double>&) const override;
+     114             : };
+     115             : 
+     116             : 
+     117             : PLUMED_REGISTER_ACTION(TD_Grid,"TD_GRID")
+     118             : 
+     119             : 
+     120          11 : void TD_Grid::registerKeywords(Keywords& keys) {
+     121          11 :   TargetDistribution::registerKeywords(keys);
+     122          22 :   keys.add("compulsory","FILE","The name of the external grid file to be used as a target distribution.");
+     123          22 :   keys.add("optional","SHIFT","Shift the grid read in by some constant value. Due to normalization the final shift in the target distribution will generally not be the same as the value given here");
+     124          22 :   keys.addFlag("ZERO_OUTSIDE",false,"By default the target distribution is continuous such that values outside the boundary of the external grid file are the same as at the boundary. This can be changed by using this flag which will make values outside to be taken as zero.");
+     125          22 :   keys.addFlag("DO_NOT_NORMALIZE",false,"By default the target distribution from the external grid is always normalized inside the code. You can use this flag to disable this normalization. However, be warned that this will generally lead to the wrong behavior if the distribution from the external grid is not properly normalized to 1.");
+     126          11 :   keys.use("WELLTEMPERED_FACTOR");
+     127          11 :   keys.use("SHIFT_TO_ZERO");
+     128          11 : }
+     129             : 
+     130           9 : TD_Grid::TD_Grid(const ActionOptions& ao):
+     131             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     132           9 :   minima_(0),
+     133           9 :   maxima_(0),
+     134           9 :   zero_outside_(false),
+     135          18 :   shift_(0.0)
+     136             : {
+     137             :   std::string filename;
+     138           9 :   parse("FILE",filename);
+     139           9 :   parse("SHIFT",shift_);
+     140           9 :   if(shift_!=0.0) {
+     141           1 :     if(isTargetDistGridShiftedToZero()) {plumed_merror(getName() + ": using both SHIFT and SHIFT_TO_ZERO is not allowed.");}
+     142             :   }
+     143           9 :   parseFlag("ZERO_OUTSIDE",zero_outside_);
+     144             : 
+     145           9 :   bool do_not_normalize=false;
+     146           9 :   parseFlag("DO_NOT_NORMALIZE",do_not_normalize);
+     147           9 :   if(do_not_normalize && shift_!=0.0) {plumed_merror(getName() + ": using both SHIFT and DO_NOT_NORMALIZE is not allowed.");}
+     148           9 :   if(!do_not_normalize) {setForcedNormalization();}
+     149             : 
+     150           9 :   checkRead();
+     151             : 
+     152             :   std::string gridlabel;
+     153             :   std::vector<std::string> arglabels;
+     154             :   std::vector<std::string> argmin;
+     155             :   std::vector<std::string> argmax;
+     156             :   std::vector<bool> argperiodic;
+     157             :   std::vector<unsigned int> argnbins;
+     158           9 :   bool has_deriv = false;
+     159           9 :   unsigned int nargs = VesTools::getGridFileInfo(filename,gridlabel,arglabels,argmin,argmax,argperiodic,argnbins,has_deriv);
+     160           9 :   if(nargs==0) {
+     161           0 :     plumed_merror(getName() + ": problem in parsing information from grid file");
+     162             :   }
+     163             : 
+     164           9 :   setDimension(arglabels.size());
+     165           9 :   std::vector<std::unique_ptr<Value>> arguments(arglabels.size());
+     166          22 :   for(unsigned int i=0; i < arglabels.size(); i++) {
+     167          26 :     arguments[i]= Tools::make_unique<Value>(nullptr,arglabels[i],false);
+     168          13 :     if(argperiodic[i]) {
+     169           0 :       arguments[i]->setDomain(argmin[i],argmax[i]);
+     170             :     }
+     171             :     else {
+     172          13 :       arguments[i]->setNotPeriodic();
+     173             :     }
+     174             :   }
+     175             : 
+     176           9 :   IFile gridfile; gridfile.open(filename);
+     177           9 :   if(has_deriv) {
+     178           0 :     distGrid_=GridBase::create(gridlabel,Tools::unique2raw(arguments),gridfile,false,true,true);
+     179             :   }
+     180             :   else {
+     181          18 :     distGrid_=GridBase::create(gridlabel,Tools::unique2raw(arguments),gridfile,false,false,false);
+     182             :   }
+     183           9 :   gridfile.close();
+     184             : 
+     185             : 
+     186           9 :   minima_.resize(getDimension());
+     187           9 :   maxima_.resize(getDimension());
+     188           9 :   periodic_.resize(getDimension());
+     189          22 :   for (unsigned int i=0; i < getDimension(); i++) {
+     190          13 :     Tools::convert(distGrid_->getMin()[i],minima_[i]);
+     191          13 :     Tools::convert(distGrid_->getMax()[i],maxima_[i]);
+     192          13 :     periodic_[i] = argperiodic[i];
+     193          13 :     if(periodic_[i]) {maxima_[i]-=distGrid_->getDx()[i];}
+     194             :   }
+     195             : 
+     196          27 : }
+     197             : 
+     198             : 
+     199       49369 : double TD_Grid::getValue(const std::vector<double>& argument) const {
+     200             :   double outside = 0.0;
+     201       49369 :   std::vector<double> arg = argument;
+     202      145566 :   for(unsigned int k=0; k<getDimension(); k++) {
+     203       96533 :     if(zero_outside_ && (argument[k] < minima_[k] || argument[k] > maxima_[k])) {
+     204             :       return outside;
+     205             :     }
+     206       96197 :     else if(argument[k] < minima_[k]) {
+     207         168 :       arg[k] = minima_[k];
+     208             :     }
+     209       96029 :     else if(argument[k] > maxima_[k]) {
+     210         168 :       arg[k] =maxima_[k];
+     211             :     }
+     212             :   }
+     213       49033 :   return GridLinearInterpolation::getGridValueWithLinearInterpolation(distGrid_.get(),arg)+shift_;
+     214             : }
+     215             : 
+     216             : 
+     217             : }
+     218             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_LinearCombination.cpp.func-sort-c.html b/coverage/ves/TD_LinearCombination.cpp.func-sort-c.html new file mode 100644 index 000000000000..eb8e008b65e9 --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_LinearCombination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_LinearCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:587775.3 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20TD_LinearCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves20TD_LinearCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves20TD_LinearCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZNK4PLMD3ves20TD_LinearCombination8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves20TD_LinearCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves20TD_LinearCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves20TD_LinearCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE12
_ZN4PLMD3ves20TD_LinearCombinationC2ERKNS_13ActionOptionsE12
_ZN4PLMD3ves20TD_LinearCombination16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3ves20TD_LinearCombination10updateGridEv22
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_LinearCombination.cpp.func.html b/coverage/ves/TD_LinearCombination.cpp.func.html new file mode 100644 index 000000000000..1d4982de6090 --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_LinearCombination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_LinearCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:587775.3 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves20TD_LinearCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves20TD_LinearCombination10updateGridEv22
_ZN4PLMD3ves20TD_LinearCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves20TD_LinearCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves20TD_LinearCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves20TD_LinearCombination16registerKeywordsERNS_8KeywordsE14
_ZN4PLMD3ves20TD_LinearCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE12
_ZN4PLMD3ves20TD_LinearCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves20TD_LinearCombinationC2ERKNS_13ActionOptionsE12
_ZNK4PLMD3ves20TD_LinearCombination8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_LinearCombination.cpp.gcov.html b/coverage/ves/TD_LinearCombination.cpp.gcov.html new file mode 100644 index 000000000000..794dc9fc4757 --- /dev/null +++ b/coverage/ves/TD_LinearCombination.cpp.gcov.html @@ -0,0 +1,354 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_LinearCombination.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_LinearCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:587775.3 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "VesTools.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/PlumedMain.h"
+      29             : #include "tools/Grid.h"
+      30             : 
+      31             : #include <limits>
+      32             : 
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : // class Grid;
+      37             : class Action;
+      38             : 
+      39             : namespace ves {
+      40             : 
+      41             : //+PLUMEDOC VES_TARGETDIST TD_LINEAR_COMBINATION
+      42             : /*
+      43             : Target distribution given by linear combination of distributions (static or dynamic).
+      44             : 
+      45             : Employ a target distribution that is a linear combination of the other
+      46             : distributions, defined as
+      47             : \f[
+      48             : p(\mathbf{s}) = \sum_{i} w_{i} \, p_{i}(\mathbf{s})
+      49             : \f]
+      50             : where the weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      51             : 
+      52             : The labels of the distributions \f$p_{i}(\mathbf{s})\f$ to be used in the
+      53             : linear combination are given in the DISTRIBUTIONS keyword.
+      54             : 
+      55             : The weights \f$w_{i}\f$ can be given using
+      56             : the WEIGHTS keyword. The distributions are weighted equally if no weights are given.
+      57             : 
+      58             : It is assumed that all the distributions \f$p_{i}(\mathbf{s})\f$ are normalized.
+      59             : If that is not the case for some reason should you
+      60             : normalize each distribution separately by using the NORMALIZE
+      61             : keyword when defining them in the input file (i.e. before the
+      62             : TD_LINEAR_COMBINATION action).
+      63             : Note that normalizing the overall
+      64             : linear combination will generally lead to different results than normalizing
+      65             : each distribution separately.
+      66             : 
+      67             : The linear combination will be a dynamic target distribution if one or more
+      68             : of the distributions used is a dynamic distribution, otherwise it will be a
+      69             : static distribution.
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : Here we employ a linear combination of a uniform and a Gaussian distribution.
+      74             : No weights are given so the two distributions will be weighted equally.
+      75             : \plumedfile
+      76             : td_uni: TD_UNIFORM
+      77             : 
+      78             : td_gauss: TD_GAUSSIAN CENTER1=-2.0 SIGMA1=0.5
+      79             : 
+      80             : td_comb: TD_LINEAR_COMBINATION DISTRIBUTIONS=td_uni,td_gauss
+      81             : \endplumedfile
+      82             : 
+      83             : Here we employ a linear combination of a uniform and two Gaussian distribution.
+      84             : The weights are automatically normalized to 1 such that giving
+      85             : WEIGHTS=1.0,1.0,2.0 as we do here is equal to giving WEIGHTS=0.25,0.25,0.50.
+      86             : \plumedfile
+      87             : td_uni: TD_UNIFORM
+      88             : 
+      89             : td_gauss1: TD_GAUSSIAN CENTER1=-2.0,-2.0 SIGMA1=0.5,0.3
+      90             : 
+      91             : td_gauss2: TD_GAUSSIAN CENTER1=+2.0,+2.0 SIGMA1=0.3,0.5
+      92             : 
+      93             : TD_LINEAR_COMBINATION ...
+      94             :  DISTRIBUTIONS=td_uni,td_gauss1,td_gauss2
+      95             :  WEIGHTS=1.0,1.0,2.0
+      96             :  LABEL=td_comb
+      97             : ... TD_LINEAR_COMBINATION
+      98             : \endplumedfile
+      99             : 
+     100             : In the above example the two Gaussian kernels are given using two separate
+     101             : DISTRIBUTION keywords. As the \ref TD_GAUSSIAN target distribution allows multiple
+     102             : centers is it also possible to use just one DISTRIBUTION keyword for the two
+     103             : Gaussian kernels. This is shown in the following example which will give the
+     104             : exact same result as the one above as the weights have been appropriately
+     105             : adjusted
+     106             : \plumedfile
+     107             : td_uni: TD_UNIFORM
+     108             : 
+     109             : TD_GAUSSIAN ...
+     110             :  CENTER1=-2.0,-2.0  SIGMA1=0.5,0.3
+     111             :  CENTER2=+2.0,+2.0  SIGMA2=0.3,0.5
+     112             :  WEIGHTS=1.0,2.0
+     113             :  LABEL=td_gauss
+     114             : ... TD_GAUSSIAN
+     115             : 
+     116             : TD_LINEAR_COMBINATION ...
+     117             :  DISTRIBUTIONS=td_uni,td_gauss
+     118             :  WEIGHTS=0.25,0.75
+     119             :  LABEL=td_comb
+     120             : ... TD_LINEAR_COMBINATION
+     121             : \endplumedfile
+     122             : 
+     123             : */
+     124             : //+ENDPLUMEDOC
+     125             : 
+     126             : class VesBias;
+     127             : 
+     128             : class TD_LinearCombination: public TargetDistribution {
+     129             : private:
+     130             :   std::vector<TargetDistribution*> distribution_pntrs_;
+     131             :   std::vector<Grid*> grid_pntrs_;
+     132             :   std::vector<double> weights_;
+     133             :   unsigned int ndist_;
+     134             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+     135             : public:
+     136             :   static void registerKeywords(Keywords&);
+     137             :   explicit TD_LinearCombination(const ActionOptions& ao);
+     138             :   void updateGrid() override;
+     139             :   double getValue(const std::vector<double>&) const override;
+     140             :   //
+     141             :   void linkVesBias(VesBias*) override;
+     142             :   void linkAction(Action*) override;
+     143             :   //
+     144             :   void linkBiasGrid(Grid*) override;
+     145             :   void linkBiasWithoutCutoffGrid(Grid*) override;
+     146             :   void linkFesGrid(Grid*) override;
+     147             :   //
+     148             : };
+     149             : 
+     150             : 
+     151             : PLUMED_REGISTER_ACTION(TD_LinearCombination,"TD_LINEAR_COMBINATION")
+     152             : 
+     153             : 
+     154          14 : void TD_LinearCombination::registerKeywords(Keywords& keys) {
+     155          14 :   TargetDistribution::registerKeywords(keys);
+     156          28 :   keys.add("compulsory","DISTRIBUTIONS","The labels of the target distribution actions to be used in the linear combination.");
+     157          28 :   keys.add("optional","WEIGHTS","The weights of target distributions. Have to be as many as the number of target distribution labels given in DISTRIBUTIONS. If no weights are given the distributions are weighted equally. The weights are automatically normalized to 1.");
+     158          14 :   keys.use("WELLTEMPERED_FACTOR");
+     159             :   //keys.use("SHIFT_TO_ZERO");
+     160          14 :   keys.use("NORMALIZE");
+     161          14 : }
+     162             : 
+     163             : 
+     164          12 : TD_LinearCombination::TD_LinearCombination(const ActionOptions& ao):
+     165             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     166          24 :   distribution_pntrs_(0),
+     167          12 :   grid_pntrs_(0),
+     168          12 :   weights_(0),
+     169          24 :   ndist_(0)
+     170             : {
+     171             :   std::vector<std::string> targetdist_labels;
+     172          12 :   parseVector("DISTRIBUTIONS",targetdist_labels);
+     173             : 
+     174          12 :   std::string error_msg = "";
+     175          24 :   distribution_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     176          12 :   if(error_msg.size()>0) {plumed_merror("Error in keyword DISTRIBUTIONS of "+getName()+": "+error_msg);}
+     177             : 
+     178          40 :   for(unsigned int i=0; i<distribution_pntrs_.size(); i++) {
+     179          28 :     if(distribution_pntrs_[i]->isDynamic()) {setDynamic();}
+     180          28 :     if(distribution_pntrs_[i]->fesGridNeeded()) {setFesGridNeeded();}
+     181          28 :     if(distribution_pntrs_[i]->biasGridNeeded()) {setBiasGridNeeded();}
+     182             :   }
+     183             : 
+     184          12 :   ndist_ = distribution_pntrs_.size();
+     185          12 :   grid_pntrs_.assign(ndist_,NULL);
+     186          12 :   if(ndist_==0) {plumed_merror(getName()+ ": no distributions are given.");}
+     187          12 :   if(ndist_==1) {plumed_merror(getName()+ ": giving only one distribution does not make sense.");}
+     188             :   //
+     189          24 :   parseVector("WEIGHTS",weights_);
+     190          12 :   if(weights_.size()==0) {weights_.assign(distribution_pntrs_.size(),1.0);}
+     191          12 :   if(distribution_pntrs_.size()!=weights_.size()) {
+     192           0 :     plumed_merror(getName()+ ": there has to be as many weights given in WEIGHTS as the number of target distribution labels given in DISTRIBUTIONS");
+     193             :   }
+     194             :   //
+     195             :   double sum_weights=0.0;
+     196          40 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     197          40 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     198          12 :   checkRead();
+     199          12 : }
+     200             : 
+     201             : 
+     202           0 : double TD_LinearCombination::getValue(const std::vector<double>& argument) const {
+     203           0 :   plumed_merror("getValue not implemented for TD_LinearCombination");
+     204             :   return 0.0;
+     205             : }
+     206             : 
+     207             : 
+     208          12 : void TD_LinearCombination::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     209          40 :   for(unsigned int i=0; i<ndist_; i++) {
+     210          28 :     distribution_pntrs_[i]->setupGrids(arguments,min,max,nbins);
+     211          28 :     if(distribution_pntrs_[i]->getDimension()!=this->getDimension()) {
+     212           0 :       plumed_merror(getName() + ": all target distribution must have the same dimension");
+     213             :     }
+     214          28 :     grid_pntrs_[i]=distribution_pntrs_[i]->getTargetDistGridPntr();
+     215             :   }
+     216          12 : }
+     217             : 
+     218             : 
+     219          22 : void TD_LinearCombination::updateGrid() {
+     220          70 :   for(unsigned int i=0; i<ndist_; i++) {
+     221          48 :     distribution_pntrs_[i]->updateTargetDist();
+     222             :   }
+     223      162033 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     224             :     double value = 0.0;
+     225      506837 :     for(unsigned int i=0; i<ndist_; i++) {
+     226      344826 :       value += weights_[i]*grid_pntrs_[i]->getValue(l);
+     227             :     }
+     228      162011 :     if(value==0.0) value=std::numeric_limits<double>::denorm_min();
+     229      162011 :     targetDistGrid().setValue(l,value);
+     230      162011 :     logTargetDistGrid().setValue(l,-std::log(value));
+     231             :   }
+     232          22 :   logTargetDistGrid().setMinToZero();
+     233          22 : }
+     234             : 
+     235             : 
+     236           1 : void TD_LinearCombination::linkVesBias(VesBias* vesbias_pntr_in) {
+     237           1 :   TargetDistribution::linkVesBias(vesbias_pntr_in);
+     238           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     239           2 :     distribution_pntrs_[i]->linkVesBias(vesbias_pntr_in);
+     240             :   }
+     241           1 : }
+     242             : 
+     243             : 
+     244           0 : void TD_LinearCombination::linkAction(Action* action_pntr_in) {
+     245           0 :   TargetDistribution::linkAction(action_pntr_in);
+     246           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     247           0 :     distribution_pntrs_[i]->linkAction(action_pntr_in);
+     248             :   }
+     249           0 : }
+     250             : 
+     251             : 
+     252           0 : void TD_LinearCombination::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     253           0 :   TargetDistribution::linkBiasGrid(bias_grid_pntr_in);
+     254           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     255           0 :     distribution_pntrs_[i]->linkBiasGrid(bias_grid_pntr_in);
+     256             :   }
+     257           0 : }
+     258             : 
+     259             : 
+     260           0 : void TD_LinearCombination::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     261           0 :   TargetDistribution::linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     262           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     263           0 :     distribution_pntrs_[i]->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     264             :   }
+     265           0 : }
+     266             : 
+     267             : 
+     268           1 : void TD_LinearCombination::linkFesGrid(Grid* fes_grid_pntr_in) {
+     269           1 :   TargetDistribution::linkFesGrid(fes_grid_pntr_in);
+     270           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     271           2 :     distribution_pntrs_[i]->linkFesGrid(fes_grid_pntr_in);
+     272             :   }
+     273           1 : }
+     274             : 
+     275             : 
+     276             : }
+     277             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Multicanonical.cpp.func-sort-c.html b/coverage/ves/TD_Multicanonical.cpp.func-sort-c.html new file mode 100644 index 000000000000..a0dd0d0906f3 --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Multicanonical.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Multicanonical.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19720496.6 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves17TD_Multicanonical8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves17TD_MulticanonicalC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves17TD_MulticanonicalD0Ev2
_ZN4PLMD3ves17TD_MulticanonicalD2Ev2
_ZN4PLMD3ves17TD_Multicanonical16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves17TD_Multicanonical10updateGridEv14
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Multicanonical.cpp.func.html b/coverage/ves/TD_Multicanonical.cpp.func.html new file mode 100644 index 000000000000..d3cbe1d9fdd8 --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Multicanonical.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Multicanonical.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19720496.6 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves17TD_Multicanonical10updateGridEv14
_ZN4PLMD3ves17TD_Multicanonical16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves17TD_MulticanonicalC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves17TD_MulticanonicalD0Ev2
_ZN4PLMD3ves17TD_MulticanonicalD2Ev2
_ZNK4PLMD3ves17TD_Multicanonical8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Multicanonical.cpp.gcov.html b/coverage/ves/TD_Multicanonical.cpp.gcov.html new file mode 100644 index 000000000000..a4731dc9bdd0 --- /dev/null +++ b/coverage/ves/TD_Multicanonical.cpp.gcov.html @@ -0,0 +1,551 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Multicanonical.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Multicanonical.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:19720496.6 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Grid.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include <cfloat>
+      29             : 
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace ves {
+      33             : 
+      34             : //+PLUMEDOC VES_TARGETDIST TD_MULTICANONICAL
+      35             : /*
+      36             : Multicanonical target distribution (dynamic).
+      37             : 
+      38             : Use the target distribution to sample the multicanonical ensemble \cite Berg-PRL-1992 \cite Piaggi-PRL-2019.
+      39             : In this way, in a single molecular dynamics simulation one can obtain information about the system in a range of temperatures.
+      40             : This range is determined through the keywords MIN_TEMP and MAX_TEMP.
+      41             : 
+      42             : The collective variables (CVs) used to construct the bias potential must be:
+      43             :  1. the energy or,
+      44             :  2. the energy and an order parameter.
+      45             : 
+      46             : Other choices of CVs or a different order of the above mentioned CVs are nonsensical.
+      47             : The second CV, the order parameter, must be used when one aims at studying a first order phase transition in the chosen temperature interval \cite Piaggi-JCP-2019.
+      48             : 
+      49             : The algorithm will explore the free energy at each temperature up to a predefined free
+      50             :  energy threshold \f$\epsilon\f$ specified through the keyword THRESHOLD (in kT units).
+      51             : If only the energy is biased, i.e. no phase transition is considered, then THRESHOLD can be set to around 5.
+      52             : If also an order parameter is used then the THRESHOLD should be greater than the barrier for the transformation in kT.
+      53             : For small systems undergoing a freezing transition THRESHOLD is typically between 20 and 50.
+      54             : 
+      55             : When only the potential energy is used as CV the method is equivalent to the Wang-Landau algorithm \cite wanglandau.
+      56             : The advantage with respect to Wang-Landau is that instead of sampling the potential energy indiscriminately, an interval is chosen on the fly based on the minimum and maximum targeted temperatures.
+      57             : 
+      58             : The algorithm works as follows.
+      59             : The target distribution for the potential energy is chosen to be:
+      60             : 
+      61             : \f[
+      62             : p(E)= \left\{\begin{array}{ll}
+      63             :          \frac{1}{E_2-E_1} & \mathrm{if} \quad E_1<E<E_2 \\
+      64             :          0 & \mathrm{otherwise}
+      65             :       \end{array}\right.
+      66             : \f]
+      67             : 
+      68             : where the energy limits \f$E_1\f$ and \f$E_2\f$ are yet to be determined.
+      69             : Clearly the interval \f$E_1–E_2\f$ chosen is related to the interval of temperatures \f$T_1-T_2\f$.
+      70             : To link these two intervals we make use of the following relation:
+      71             : \f[
+      72             : \beta' F_{\beta'}(E) = \beta F_{\beta}(E) + (\beta' - \beta) E + C,
+      73             : \f]
+      74             : where \f$F_{\beta}(E)\f$ is determined during the optimization and we shall choose \f$C\f$ such that \f$F_{\beta'}(E_{m})=0\f$ with \f$E_{m}\f$ the position of the free energy minimum.
+      75             : Using this relation we employ an iterative procedure to find the energy interval.
+      76             : At iteration \f$k\f$ we have the estimates \f$E_1^k\f$ and \f$E_2^k\f$ for \f$E_1\f$ and \f$E_2\f$, and the target distribution is:
+      77             : \f[
+      78             : p^k(E)=\frac{1}{E_2^k-E_1^k} \quad \mathrm{for} \quad E_1^k<E<E_2^k.
+      79             : \f]
+      80             : \f$E_1^k\f$ and \f$E_2^k\f$ are obtained from the leftmost solution of \f$\beta_2 F_{\beta_2}^{k-1}(E_1^k)=\epsilon\f$ and the rightmost solution of \f$\beta_1 F_{\beta_1}^{k-1}(E_2^k)=\epsilon\f$.
+      81             : The procedure is repeated until convergence.
+      82             : This iterative approach is similar to that in \ref TD_WELLTEMPERED.
+      83             : 
+      84             : The version of this algorithm in which the energy and an order parameter are biased is similar to the one described in \ref TD_MULTITHERMAL_MULTIBARIC.
+      85             : 
+      86             : The output of these simulations can be reweighted in order to obtain information at all temperatures in the targeted temperature interval.
+      87             : The reweighting can be performed using the action \ref REWEIGHT_TEMP_PRESS.
+      88             : 
+      89             : \par Examples
+      90             : 
+      91             : The following input can be used to run a simulation in the multicanonical ensemble.
+      92             : The temperature interval to be explored is 400-600 K.
+      93             : The energy is used as collective variable.
+      94             : Legendre polynomials are used to construct the bias potential.
+      95             : The averaged stochastic gradient descent algorithm is chosen to optimize the VES functional.
+      96             : The target distribution is updated every 100 optimization steps (200 ps here) using the last estimation of the free energy.
+      97             : 
+      98             : \plumedfile
+      99             : # Use energy and volume as CVs
+     100             : energy: ENERGY
+     101             : 
+     102             : # Basis functions
+     103             : bf1: BF_LEGENDRE ORDER=20 MINIMUM=-25000 MAXIMUM=-23500
+     104             : 
+     105             : # Target distributions
+     106             : TD_MULTICANONICAL ...
+     107             :  LABEL=td_multi
+     108             :  MIN_TEMP=400
+     109             :  MAX_TEMP=600
+     110             : ... TD_MULTICANONICAL
+     111             : 
+     112             : # Expansion
+     113             : VES_LINEAR_EXPANSION ...
+     114             :  ARG=energy
+     115             :  BASIS_FUNCTIONS=bf1
+     116             :  TEMP=500.0
+     117             :  GRID_BINS=1000
+     118             :  TARGET_DISTRIBUTION=td_multi
+     119             :  LABEL=b1
+     120             : ... VES_LINEAR_EXPANSION
+     121             : 
+     122             : # Optimization algorithm
+     123             : OPT_AVERAGED_SGD ...
+     124             :   BIAS=b1
+     125             :   STRIDE=500
+     126             :   LABEL=o1
+     127             :   STEPSIZE=1.0
+     128             :   FES_OUTPUT=500
+     129             :   BIAS_OUTPUT=500
+     130             :   TARGETDIST_OUTPUT=500
+     131             :   COEFFS_OUTPUT=10
+     132             :   TARGETDIST_STRIDE=100
+     133             : ... OPT_AVERAGED_SGD
+     134             : 
+     135             : \endplumedfile
+     136             : 
+     137             : The multicanonical target distribution can also be used to explore a temperature interval in which a first order phase transitions is observed.
+     138             : 
+     139             : */
+     140             : //+ENDPLUMEDOC
+     141             : 
+     142             : class TD_Multicanonical: public TargetDistribution {
+     143             : private:
+     144             :   double threshold_, min_temp_, max_temp_;
+     145             :   std::vector<double> sigma_;
+     146             :   unsigned steps_temp_;
+     147             :   double epsilon_;
+     148             :   bool smoothening_;
+     149             : public:
+     150             :   static void registerKeywords(Keywords&);
+     151             :   explicit TD_Multicanonical(const ActionOptions& ao);
+     152             :   void updateGrid() override;
+     153             :   double getValue(const std::vector<double>&) const override;
+     154           4 :   ~TD_Multicanonical() {}
+     155             :   double GaussianSwitchingFunc(const double, const double, const double) const;
+     156             : };
+     157             : 
+     158             : 
+     159             : PLUMED_REGISTER_ACTION(TD_Multicanonical,"TD_MULTICANONICAL")
+     160             : 
+     161             : 
+     162           4 : void TD_Multicanonical::registerKeywords(Keywords& keys) {
+     163           4 :   TargetDistribution::registerKeywords(keys);
+     164           8 :   keys.add("compulsory","THRESHOLD","5","Maximum exploration free energy in kT.");
+     165           8 :   keys.add("compulsory","EPSILON","10","The zeros of the target distribution are changed to e^-EPSILON.");
+     166           8 :   keys.add("compulsory","MIN_TEMP","Minimum temperature.");
+     167           8 :   keys.add("compulsory","MAX_TEMP","Maximum temperature.");
+     168           8 :   keys.add("optional","STEPS_TEMP","Number of temperature steps. Only for the 2D version, i.e. energy and order parameter.");
+     169           8 :   keys.add("optional","SIGMA","The standard deviation parameters of the Gaussian kernels used for smoothing the target distribution. One value must be specified for each argument, i.e. one value per CV. A value of 0.0 means that no smoothing is performed, this is the default behavior.");
+     170           4 : }
+     171             : 
+     172             : 
+     173           2 : TD_Multicanonical::TD_Multicanonical(const ActionOptions& ao):
+     174             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     175           2 :   threshold_(5.0),
+     176           2 :   min_temp_(0.0),
+     177           2 :   max_temp_(1000.0),
+     178           4 :   sigma_(0.0),
+     179           2 :   steps_temp_(20),
+     180           2 :   epsilon_(10.0),
+     181           2 :   smoothening_(true)
+     182             : {
+     183           2 :   log.printf("  Multicanonical target distribution");
+     184           2 :   log.printf("\n");
+     185           2 :   log.printf("  Please read and cite ");
+     186           4 :   log << plumed.cite("Piaggi and Parrinello, Phys. Rev. Lett. 122 (5), 050601 (2019)");
+     187           2 :   log.printf(" and ");
+     188           4 :   log << plumed.cite("Piaggi and Parrinello, J. Chem. Phys. 150 (24), 244119 (2019)");
+     189           2 :   log.printf("\n");
+     190           2 :   parse("THRESHOLD",threshold_);
+     191           2 :   if(threshold_<=0.0) {
+     192           0 :     plumed_merror(getName()+": the value of the threshold should be positive.");
+     193             :   }
+     194           2 :   log.printf("  exploring free energy up to %f kT for each temperature \n",threshold_);
+     195             : 
+     196           2 :   parse("MIN_TEMP",min_temp_);
+     197           2 :   parse("MAX_TEMP",max_temp_);
+     198           2 :   log.printf("  temperatures between %f and %f will be explored \n",min_temp_,max_temp_);
+     199           4 :   parseVector("SIGMA",sigma_);
+     200           2 :   if(sigma_.size()==0) smoothening_=false;
+     201           2 :   if(smoothening_ && (sigma_.size()<1 || sigma_.size()>2) ) plumed_merror(getName()+": SIGMA takes 1 or 2 values as input.");
+     202           2 :   if (smoothening_) {
+     203           2 :     log.printf("  the target distribution will be smoothed using sigma values");
+     204           5 :     for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_[i]);
+     205           2 :     log.printf("\n");
+     206             :   }
+     207             : 
+     208           2 :   parse("STEPS_TEMP",steps_temp_); // Only used in the 2D version
+     209           2 :   steps_temp_ += 1;
+     210           2 :   log.printf("  %d steps in temperatures will be employed (if TD is two-dimensional) \n",steps_temp_);
+     211             : 
+     212           2 :   parse("EPSILON",epsilon_);
+     213           2 :   if(epsilon_<=1.0) {
+     214           0 :     plumed_merror(getName()+": the value of epsilon should be greater than 1.");
+     215             :   }
+     216           2 :   log.printf("  the non relevant regions of the target distribution are set to e^-%f \n",epsilon_);
+     217             : 
+     218             :   setDynamic();
+     219             :   setFesGridNeeded();
+     220           2 :   checkRead();
+     221           2 : }
+     222             : 
+     223             : 
+     224           0 : double TD_Multicanonical::getValue(const std::vector<double>& argument) const {
+     225           0 :   plumed_merror("getValue not implemented for TD_Multicanonical");
+     226             :   return 0.0;
+     227             : }
+     228             : 
+     229             : 
+     230          14 : void TD_Multicanonical::updateGrid() {
+     231          14 :   if (getStep() == 0) {
+     232           2 :     if(targetDistGrid().getDimension()>2 || targetDistGrid().getDimension()<1) plumed_merror(getName()+" works only with 1 or 2 arguments, i.e. energy, or energy and CV");
+     233           2 :     if(smoothening_ && sigma_.size()!=targetDistGrid().getDimension()) plumed_merror(getName()+": mismatch between SIGMA dimension and number of arguments");
+     234             :     // Use uniform TD
+     235           4 :     std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     236             :     double norm = 0.0;
+     237        2704 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     238             :       double value = 1.0;
+     239        2702 :       norm += integration_weights[l]*value;
+     240        2702 :       targetDistGrid().setValue(l,value);
+     241             :     }
+     242           2 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     243             :   } else {
+     244             :     // Two variants: 1D and 2D
+     245          12 :     if(targetDistGrid().getDimension()==1) {
+     246             :       // 1D variant: Multicanonical without order parameter
+     247             :       // In this variant we find the minimum and maximum relevant potential energies.
+     248             :       // Using this information we construct a uniform target distribution in between these two.
+     249          10 :       double beta = getBeta();
+     250          10 :       double beta_prime_min = 1./(getKBoltzmann()*min_temp_);
+     251          10 :       double beta_prime_max = 1./(getKBoltzmann()*max_temp_);
+     252          10 :       plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_Multicanonical!");
+     253             :       // Find minimum of F(U) at temperature min
+     254             :       double minval=DBL_MAX;
+     255          10 :       Grid::index_t minindex = (targetDistGrid().getSize())/2;
+     256          10 :       double minpos = targetDistGrid().getPoint(minindex)[0];
+     257        1020 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     258        1010 :         double value = getFesGridPntr()->getValue(l);
+     259        1010 :         double argument = targetDistGrid().getPoint(l)[0];
+     260        1010 :         value = beta*value + (beta_prime_min-beta)*argument;
+     261        1010 :         if(value<minval) {
+     262             :           minval=value;
+     263             :           minpos=argument;
+     264             :           minindex=l;
+     265             :         }
+     266             :       }
+     267             :       // Find minimum energy at low temperature
+     268          10 :       double minimum_low = minpos;
+     269          11 :       for(Grid::index_t l=minindex; l>1; l-=1) {
+     270          11 :         double argument = targetDistGrid().getPoint(l)[0];
+     271          11 :         double argument_next = targetDistGrid().getPoint(l-1)[0];
+     272          11 :         double value = getFesGridPntr()->getValue(l);
+     273          11 :         double value_next = getFesGridPntr()->getValue(l-1);
+     274          11 :         value = beta*value + (beta_prime_min-beta)*argument - minval;
+     275          11 :         value_next = beta*value_next + (beta_prime_min-beta)*argument_next - minval;
+     276          11 :         if (value<threshold_ && value_next>threshold_) {
+     277          10 :           minimum_low = argument_next;
+     278          10 :           break;
+     279             :         }
+     280             :       }
+     281             :       // Find maximum energy at low temperature
+     282          10 :       double maximum_low = minpos;
+     283          12 :       for(Grid::index_t l=minindex; l<(targetDistGrid().getSize()-1); l++) {
+     284          12 :         double argument = targetDistGrid().getPoint(l)[0];
+     285          12 :         double argument_next = targetDistGrid().getPoint(l+1)[0];
+     286          12 :         double value = getFesGridPntr()->getValue(l);
+     287          12 :         double value_next = getFesGridPntr()->getValue(l+1);
+     288          12 :         value = beta*value + (beta_prime_min-beta)*argument - minval;
+     289          12 :         value_next = beta*value_next + (beta_prime_min-beta)*argument_next - minval;
+     290          12 :         if (value<threshold_ && value_next>threshold_) {
+     291          10 :           maximum_low = argument_next;
+     292          10 :           break;
+     293             :         }
+     294             :       }
+     295             :       // Find minimum of F(U) at temperature max
+     296             :       minval=DBL_MAX;
+     297        1020 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     298        1010 :         double value = getFesGridPntr()->getValue(l);
+     299        1010 :         double argument = targetDistGrid().getPoint(l)[0];
+     300        1010 :         value = beta*value + (beta_prime_max-beta)*argument;
+     301        1010 :         if(value<minval) {
+     302             :           minval=value;
+     303             :           minpos=argument;
+     304             :           minindex=l;
+     305             :         }
+     306             :       }
+     307             :       // Find minimum energy at high temperature
+     308          10 :       double minimum_high = minpos;
+     309          13 :       for(Grid::index_t l=minindex; l>1; l-=1) {
+     310          13 :         double argument = targetDistGrid().getPoint(l)[0];
+     311          13 :         double argument_next = targetDistGrid().getPoint(l-1)[0];
+     312          13 :         double value = getFesGridPntr()->getValue(l);
+     313          13 :         double value_next = getFesGridPntr()->getValue(l-1);
+     314          13 :         value = beta*value + (beta_prime_max-beta)*argument - minval;
+     315          13 :         value_next = beta*value_next + (beta_prime_max-beta)*argument_next - minval;
+     316          13 :         if (value<threshold_ && value_next>threshold_) {
+     317          10 :           minimum_high = argument_next;
+     318          10 :           break;
+     319             :         }
+     320             :       }
+     321             :       // Find maximum energy at high temperature
+     322          10 :       double maximum_high = minpos;
+     323          11 :       for(Grid::index_t l=minindex; l<(targetDistGrid().getSize()-1); l++) {
+     324          11 :         double argument = targetDistGrid().getPoint(l)[0];
+     325          11 :         double argument_next = targetDistGrid().getPoint(l+1)[0];
+     326          11 :         double value = getFesGridPntr()->getValue(l);
+     327          11 :         double value_next = getFesGridPntr()->getValue(l+1);
+     328          11 :         value = beta*value + (beta_prime_max-beta)*argument - minval;
+     329          11 :         value_next = beta*value_next + (beta_prime_max-beta)*argument_next - minval;
+     330          11 :         if (value<threshold_ && value_next>threshold_) {
+     331          10 :           maximum_high = argument_next;
+     332          10 :           break;
+     333             :         }
+     334             :       }
+     335          10 :       double minimum = std::min(minimum_low,minimum_high);
+     336          10 :       double maximum = std::max(maximum_low,maximum_high);
+     337             :       // Construct uniform TD in the interval between minimum and maximum
+     338          20 :       std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     339             :       double norm = 0.0;
+     340        1020 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     341        1010 :         double argument = targetDistGrid().getPoint(l)[0];
+     342             :         double value = 1.0;
+     343             :         double tmp;
+     344        1010 :         if(argument < minimum) {
+     345         217 :           if (smoothening_) tmp = GaussianSwitchingFunc(argument,minimum,sigma_[0]);
+     346           0 :           else tmp = exp(-1.0*epsilon_);
+     347             :         }
+     348         793 :         else if(argument > maximum) {
+     349         199 :           if (smoothening_) tmp = GaussianSwitchingFunc(argument,maximum,sigma_[0]);
+     350           0 :           else tmp = exp(-1.0*epsilon_);
+     351             :         }
+     352             :         else {
+     353             :           tmp = 1.0;
+     354             :         }
+     355             :         value *= tmp;
+     356        1010 :         norm += integration_weights[l]*value;
+     357        1010 :         targetDistGrid().setValue(l,value);
+     358             :       }
+     359          10 :       targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     360           2 :     } else if(targetDistGrid().getDimension()==2) {
+     361             :       // 2D variant: Multicanonical with order parameter
+     362             :       // In this variant we find for each temperature the relevant region of potential energy and order parameter.
+     363             :       // The target distribution will be the union of the relevant regions at all temperatures in the temperature interval.
+     364           2 :       double beta = getBeta();
+     365           2 :       double beta_prime_min = 1./(getKBoltzmann()*min_temp_);
+     366           2 :       double beta_prime_max = 1./(getKBoltzmann()*max_temp_);
+     367           2 :       plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_Multicanonical!");
+     368             :       // Set all to zero
+     369        5204 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     370        5202 :         double value = exp(-1.0*epsilon_);
+     371        5202 :         targetDistGrid().setValue(l,value);
+     372             :       }
+     373             :       // Loop over temperatures
+     374          44 :       for(unsigned i=0; i<steps_temp_; i++) {
+     375          42 :         double beta_prime=beta_prime_min + (beta_prime_max-beta_prime_min)*i/(steps_temp_-1);
+     376             :         // Find minimum for this temperature
+     377             :         double minval=DBL_MAX;
+     378      109284 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     379      109242 :           double energy = targetDistGrid().getPoint(l)[0];
+     380      109242 :           double value = getFesGridPntr()->getValue(l);
+     381      109242 :           value = beta*value + (beta_prime-beta)*energy;
+     382      109242 :           if(value<minval) {
+     383             :             minval=value;
+     384             :           }
+     385             :         }
+     386             :         // Now check which energies and volumes are below X kt
+     387      109284 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     388      109242 :           double energy = targetDistGrid().getPoint(l)[0];
+     389      109242 :           double value = getFesGridPntr()->getValue(l);
+     390      109242 :           value = beta*value + (beta_prime-beta)*energy - minval;
+     391      109242 :           if (value<threshold_) {
+     392             :             double value = 1.0;
+     393        7076 :             targetDistGrid().setValue(l,value);
+     394             :           }
+     395             :         }
+     396             :       }
+     397           2 :       if (smoothening_) {
+     398           2 :         std::vector<unsigned> nbin=targetDistGrid().getNbin();
+     399           2 :         std::vector<double> dx=targetDistGrid().getDx();
+     400             :         // Smoothening
+     401         104 :         for(unsigned i=0; i<nbin[0]; i++) {
+     402        5304 :           for(unsigned j=0; j<nbin[1]; j++) {
+     403        5202 :             std::vector<unsigned> indices(2);
+     404        5202 :             indices[0]=i;
+     405        5202 :             indices[1]=j;
+     406        5202 :             Grid::index_t index = targetDistGrid().getIndex(indices);
+     407        5202 :             double energy = targetDistGrid().getPoint(index)[0];
+     408        5202 :             double volume = targetDistGrid().getPoint(index)[1];
+     409        5202 :             double value = targetDistGrid().getValue(index);
+     410        5202 :             if (value>(1-1.e-5)) { // Apply only if this grid point was 1.
+     411             :               // Apply gaussians around
+     412         773 :               std::vector<int> minBin(2), maxBin(2), deltaBin(2); // These cannot be unsigned
+     413             :               // Only consider contributions less than n*sigma bins apart from the actual distance
+     414         773 :               deltaBin[0]=std::floor(6*sigma_[0]/dx[0]);;
+     415         773 :               deltaBin[1]=std::floor(6*sigma_[1]/dx[1]);;
+     416             :               // For energy
+     417         773 :               minBin[0]=i - deltaBin[0];
+     418         773 :               if (minBin[0] < 0) minBin[0]=0;
+     419         773 :               if (minBin[0] > (nbin[0]-1)) minBin[0]=nbin[0]-1;
+     420         773 :               maxBin[0]=i +  deltaBin[0];
+     421         773 :               if (maxBin[0] > (nbin[0]-1)) maxBin[0]=nbin[0]-1;
+     422             :               // For volume
+     423         773 :               minBin[1]=j - deltaBin[1];
+     424         773 :               if (minBin[1] < 0) minBin[1]=0;
+     425         773 :               if (minBin[1] > (nbin[1]-1)) minBin[1]=nbin[1]-1;
+     426         773 :               maxBin[1]=j +  deltaBin[1];
+     427         773 :               if (maxBin[1] > (nbin[1]-1)) maxBin[1]=nbin[1]-1;
+     428       31273 :               for(unsigned l=minBin[0]; l<maxBin[0]+1; l++) {
+     429      549973 :                 for(unsigned m=minBin[1]; m<maxBin[1]+1; m++) {
+     430      519473 :                   std::vector<unsigned> indices_prime(2);
+     431      519473 :                   indices_prime[0]=l;
+     432      519473 :                   indices_prime[1]=m;
+     433      519473 :                   Grid::index_t index_prime = targetDistGrid().getIndex(indices_prime);
+     434      519473 :                   double energy_prime = targetDistGrid().getPoint(index_prime)[0];
+     435      519473 :                   double volume_prime = targetDistGrid().getPoint(index_prime)[1];
+     436      519473 :                   double value_prime = targetDistGrid().getValue(index_prime);
+     437             :                   // Apply gaussian
+     438     1558419 :                   double gaussian_value = GaussianSwitchingFunc(energy_prime,energy,sigma_[0])*GaussianSwitchingFunc(volume_prime,volume,sigma_[1]);
+     439      519473 :                   if (value_prime<gaussian_value) {
+     440       19817 :                     targetDistGrid().setValue(index_prime,gaussian_value);
+     441             :                   }
+     442             :                 }
+     443             :               }
+     444             :             }
+     445             :           }
+     446             :         }
+     447             :       }
+     448             :       // Normalize
+     449           4 :       std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     450             :       double norm = 0.0;
+     451        5204 :       for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     452        5202 :         double value = targetDistGrid().getValue(l);
+     453        5202 :         norm += integration_weights[l]*value;
+     454             :       }
+     455           2 :       targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     456           0 :     } else plumed_merror(getName()+": Number of arguments for this target distribution must be 1 or 2");
+     457             :   }
+     458          14 :   updateLogTargetDistGrid();
+     459          14 : }
+     460             : 
+     461             : inline
+     462             : double TD_Multicanonical::GaussianSwitchingFunc(const double argument, const double center, const double sigma) const {
+     463     1039362 :   if(sigma>0.0) {
+     464     1039362 :     double arg=(argument-center)/sigma;
+     465     1039362 :     return exp(-0.5*arg*arg);
+     466             :   }
+     467             :   else {
+     468             :     return 0.0;
+     469             :   }
+     470             : }
+     471             : 
+     472             : 
+     473             : }
+     474             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html b/coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html new file mode 100644 index 000000000000..f109ce1f9274 --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_MultithermalMultibaric.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_MultithermalMultibaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves25TD_MultithermalMultibaric8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves25TD_MultithermalMultibaricC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves25TD_MultithermalMultibaricD0Ev2
_ZN4PLMD3ves25TD_MultithermalMultibaricD2Ev2
_ZN4PLMD3ves25TD_MultithermalMultibaric10updateGridEv4
_ZN4PLMD3ves25TD_MultithermalMultibaric16registerKeywordsERNS_8KeywordsE4
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_MultithermalMultibaric.cpp.func.html b/coverage/ves/TD_MultithermalMultibaric.cpp.func.html new file mode 100644 index 000000000000..c9bbaaf85788 --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_MultithermalMultibaric.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_MultithermalMultibaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves25TD_MultithermalMultibaric10updateGridEv4
_ZN4PLMD3ves25TD_MultithermalMultibaric16registerKeywordsERNS_8KeywordsE4
_ZN4PLMD3ves25TD_MultithermalMultibaricC2ERKNS_13ActionOptionsE2
_ZN4PLMD3ves25TD_MultithermalMultibaricD0Ev2
_ZN4PLMD3ves25TD_MultithermalMultibaricD2Ev2
_ZNK4PLMD3ves25TD_MultithermalMultibaric8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html b/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html new file mode 100644 index 000000000000..945a2daa936d --- /dev/null +++ b/coverage/ves/TD_MultithermalMultibaric.cpp.gcov.html @@ -0,0 +1,534 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_MultithermalMultibaric.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_MultithermalMultibaric.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14715197.4 %
Date:2024-02-22 21:58:45Functions:5683.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Grid.h"
+      27             : #include "core/PlumedMain.h"
+      28             : #include <cfloat>
+      29             : 
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace ves {
+      33             : 
+      34             : //+PLUMEDOC VES_TARGETDIST TD_MULTITHERMAL_MULTIBARIC
+      35             : /*
+      36             : Multithermal-multibaric target distribution (dynamic).
+      37             : 
+      38             : Use the target distribution to sample the multithermal-multibaric ensemble \cite Piaggi-PRL-2019 \cite Okumura-CPL-2004.
+      39             : In this way, in a single molecular dynamics simulation one can obtain information
+      40             : about the simulated system in a range of temperatures and pressures.
+      41             : This range is determined through the keywords MIN_TEMP, MAX_TEMP, MIN_PRESSURE, and MAX_PRESSURE.
+      42             : One should also specified the target pressure of the barostat with the keyword PRESSURE.
+      43             : 
+      44             : The collective variables (CVs) used to construct the bias potential must be:
+      45             :   1. the potential energy and the volume or,
+      46             :   2. the potential energy, the volume, and an order parameter.
+      47             : 
+      48             : Other choices of CVs or a different order of the above mentioned CVs are nonsensical.
+      49             : The third CV, the order parameter, must be used when the region of the phase diagram under study is crossed by a first order phase transition \cite Piaggi-JCP-2019 .
+      50             : 
+      51             : The algorithm will explore the free energy at each temperature and pressure up to a predefined free
+      52             :  energy threshold \f$\epsilon\f$ specified through the keyword THRESHOLD (in kT units).
+      53             : If only the energy and the volume are being biased, i.e. no phase transition is considered, then THRESHOLD can be set to around 5.
+      54             : If also an order parameter is used then the THRESHOLD should be greater than the barrier for the transformation in kT.
+      55             : For small systems undergoing a freezing transition THRESHOLD is typically between 20 and 50.
+      56             : 
+      57             : It is also important to specify the number of intermediate temperatures and pressures to consider.
+      58             : This is done through the keywords STEPS_TEMP and STEPS_PRESSURE.
+      59             : If the number of intermediate temperature and pressures is too small, then holes might appear in the target distribution.
+      60             : If it is too large, the performance will deteriorate with no additional advantage.
+      61             : 
+      62             : We now describe the algorithm more rigorously.
+      63             : The target distribution is given by
+      64             : \f[
+      65             : p(E,\mathcal{V},s)=
+      66             :   \begin{cases}
+      67             :     1/\Omega_{E,\mathcal{V},s} & \text{if there is at least one } \beta',P' \text{ such} \\
+      68             :              & \text{that } \beta' F_{\beta',P'}(E,\mathcal{V},s)<\epsilon \text{ with}  \\
+      69             :              & \beta_1>\beta'>\beta_2 \text{ and } P_1<P'<P_2 \\
+      70             :     0 & \text{otherwise}
+      71             :   \end{cases}
+      72             : \f]
+      73             : with \f$F_{\beta',P'}(E,\mathcal{V},s)\f$ the free energy as a function of energy \f$E\f$ and volume \f$\mathcal{V}\f$ (and optionally the order parameter \f$s\f$) at temperature \f$\beta'\f$ and pressure \f$P'\f$, \f$\Omega_{E,\mathcal{V},s}\f$ is a normalization constant, and \f$\epsilon\f$ is the THRESHOLD.
+      74             : In practice the condition \f$\beta' F_{\beta',P'}(E,\mathcal{V},s)<\epsilon\f$  is checked in equally spaced points in each dimension \f$\beta'\f$ and \f$P'\f$.
+      75             : The number of points is determined with the keywords STEPS_TEMP and STEPS_PRESSURE.
+      76             : In practice the target distribution is never set to zero but rather to a small value controlled by the keyword EPSILON.
+      77             : The small value is e^-EPSILON.
+      78             : 
+      79             : Much like in the Wang-Landau algorithm \cite wanglandau or in the multicanonical ensemble \cite Berg-PRL-1992 , a flat histogram is targeted.
+      80             : The idea behind this choice of target distribution is that all regions of potential energy and volume (and optionally order parameter) that are relevant at all temperatures \f$\beta_1<\beta'<\beta_2\f$ and pressure \f$P_1<P'<P_2\f$ are included in the distribution.
+      81             : 
+      82             : The free energy at temperature \f$\beta'\f$ and pressure \f$P'\f$ is calculated from the free energy at \f$\beta\f$ and \f$P\f$ using:
+      83             : \f[
+      84             : \beta' F_{\beta',P'}(E,\mathcal{V},s) = \beta F_{\beta,P}(E,\mathcal{V},s) + (\beta' - \beta) E + (\beta' P' - \beta P ) \mathcal{V} + C
+      85             : \f]
+      86             : with \f$C\f$ such that \f$F_{\beta',P'}(E_m,\mathcal{V}_m,s_m)=0\f$ with \f$E_{m},\mathcal{V}_m,s_m\f$ the position of the free energy minimum.
+      87             : \f$ \beta F_{\beta,P}(E,\mathcal{V},s) \f$ is not know from the start and is instead found during the simulation.
+      88             : Therefore \f$ p(E,\mathcal{V},s) \f$ is determined iteratively as done in the well tempered target distribution \cite Valsson-JCTC-2015.
+      89             : 
+      90             : The output of these simulations can be reweighted in order to obtain information at all temperatures and pressures in the targeted region of Temperature-Pressure plane.
+      91             : The reweighting can be performed using the action \ref REWEIGHT_TEMP_PRESS.
+      92             : 
+      93             : The multicanonical ensemble (fixed volume) can be targeted using \ref TD_MULTICANONICAL.
+      94             : 
+      95             : \par Examples
+      96             : 
+      97             : The following input can be used to run a simulation in the multithermal-multibaric ensemble.
+      98             : The region of the temperature-pressure plane that will be explored is 260-350 K and 1 bar- 300 MPa.
+      99             : The energy and the volume are used as collective variables.
+     100             : Legendre polynomials are used to construct the two dimensional bias potential.
+     101             : The averaged stochastic gradient descent algorithm is chosen to optimize the VES functional.
+     102             : The target distribution is updated every 100 optimization steps (200 ps here) using the last estimation of the free energy.
+     103             : 
+     104             : \plumedfile
+     105             : # Use energy and volume as CVs
+     106             : energy: ENERGY
+     107             : vol: VOLUME
+     108             : 
+     109             : # Basis functions
+     110             : bf1: BF_LEGENDRE ORDER=10 MINIMUM=-14750 MAXIMUM=-12250
+     111             : bf2: BF_LEGENDRE ORDER=10 MINIMUM=6.5 MAXIMUM=8.25
+     112             : 
+     113             : # Target distribution - 1 bar = 0.06022140857 and 300 MPa = 180.66422571
+     114             : TD_MULTITHERMAL_MULTIBARIC ...
+     115             :  MIN_TEMP=260
+     116             :  MAX_TEMP=350
+     117             :  MAX_PRESSURE=180.66422571
+     118             :  MIN_PRESSURE=0.06022140857
+     119             :  PRESSURE=0.06022140857
+     120             :  LABEL=td_multi
+     121             : ... TD_MULTITHERMAL_MULTIBARIC
+     122             : 
+     123             : # Bias expansion
+     124             : VES_LINEAR_EXPANSION ...
+     125             :  ARG=energy,vol
+     126             :  BASIS_FUNCTIONS=bf1,bf2
+     127             :  TEMP=300.0
+     128             :  GRID_BINS=200,200
+     129             :  TARGET_DISTRIBUTION=td_multi
+     130             :  LABEL=b1
+     131             : ... VES_LINEAR_EXPANSION
+     132             : 
+     133             : # Optimization algorithm
+     134             : OPT_AVERAGED_SGD ...
+     135             :   BIAS=b1
+     136             :   STRIDE=500
+     137             :   LABEL=o1
+     138             :   STEPSIZE=1.0
+     139             :   FES_OUTPUT=500
+     140             :   BIAS_OUTPUT=500
+     141             :   TARGETDIST_OUTPUT=500
+     142             :   COEFFS_OUTPUT=100
+     143             :   TARGETDIST_STRIDE=100
+     144             : ... OPT_AVERAGED_SGD
+     145             : 
+     146             : \endplumedfile
+     147             : 
+     148             : 
+     149             : The multithermal-multibaric target distribution can also be used to explore regions of the phase diagram crossed by first order phase transitions.
+     150             : Consider a system of 250 atoms that crystallizes in the FCC crystal structure.
+     151             : The region of the temperature-pressure plane that will be explored is 350-450 K and 1bar-1GPa.
+     152             : We assume that inside this region we can find the liquid-FCC coexistence line that we would like to obtain.
+     153             : In this case in addition to the energy and volume, an order parameter must also be biased.
+     154             : The energy, volume, and an order parameter are used as collective variables to construct the bias potential.
+     155             : We choose as order parameter the \ref FCCUBIC.
+     156             : Legendre polynomials are used to construct the three dimensional bias potential.
+     157             : The averaged stochastic gradient descent algorithm is chosen to optimize the VES functional.
+     158             : The target distribution is updated every 100 optimization steps (200 ps here) using the last estimation of the free energy.
+     159             : 
+     160             : \plumedfile
+     161             : # Use energy, volume and FCCUBIC as CVs
+     162             : energy: ENERGY
+     163             : vol: VOLUME
+     164             : fcc: FCCUBIC SPECIES=1-256 SWITCH={CUBIC D_0=0.4 D_MAX=0.5} MORE_THAN={RATIONAL R_0=0.45 NN=12 MM=24}
+     165             : 
+     166             : # Basis functions
+     167             : bf1: BF_LEGENDRE ORDER=8 MINIMUM=-26500 MAXIMUM=-23500
+     168             : bf2: BF_LEGENDRE ORDER=8 MINIMUM=8.0 MAXIMUM=11.5
+     169             : bf3: BF_LEGENDRE ORDER=8 MINIMUM=0.0 MAXIMUM=256.0
+     170             : 
+     171             : # Target distribution
+     172             : TD_MULTITHERMAL_MULTIBARIC ...
+     173             :  LABEL=td_multitp
+     174             :  MIN_TEMP=350.0
+     175             :  MAX_TEMP=450.0
+     176             :  MIN_PRESSURE=0.06022140857
+     177             :  MAX_PRESSURE=602.2140857
+     178             :  PRESSURE=301.10704285
+     179             :  SIGMA=250.0,0.1,10.0
+     180             :  THRESHOLD=15
+     181             :  STEPS_TEMP=20
+     182             :  STEPS_PRESSURE=20
+     183             : ... TD_MULTITHERMAL_MULTIBARIC
+     184             : 
+     185             : # Expansion
+     186             : VES_LINEAR_EXPANSION ...
+     187             :  ARG=energy,vol,fcc.morethan
+     188             :  BASIS_FUNCTIONS=bf1,bf2,bf3
+     189             :  TEMP=400.0
+     190             :  GRID_BINS=40,40,40
+     191             :  TARGET_DISTRIBUTION=td_multitp
+     192             :  LABEL=b1
+     193             : ... VES_LINEAR_EXPANSION
+     194             : 
+     195             : # Optimization algorithm
+     196             : OPT_AVERAGED_SGD ...
+     197             :   BIAS=b1
+     198             :   STRIDE=500
+     199             :   LABEL=o1
+     200             :   STEPSIZE=1.0
+     201             :   FES_OUTPUT=500
+     202             :   BIAS_OUTPUT=500
+     203             :   TARGETDIST_OUTPUT=500
+     204             :   COEFFS_OUTPUT=100
+     205             :   TARGETDIST_STRIDE=500
+     206             : ... OPT_AVERAGED_SGD
+     207             : 
+     208             : \endplumedfile
+     209             : 
+     210             : */
+     211             : //+ENDPLUMEDOC
+     212             : 
+     213             : class TD_MultithermalMultibaric: public TargetDistribution {
+     214             : private:
+     215             :   double threshold_, min_temp_, max_temp_;
+     216             :   double min_press_, max_press_, press_;
+     217             :   double epsilon_;
+     218             :   bool smoothening_;
+     219             :   std::vector<double> sigma_;
+     220             :   unsigned steps_temp_, steps_pressure_;
+     221             : public:
+     222             :   static void registerKeywords(Keywords&);
+     223             :   explicit TD_MultithermalMultibaric(const ActionOptions& ao);
+     224             :   void updateGrid() override;
+     225             :   double getValue(const std::vector<double>&) const override;
+     226           4 :   ~TD_MultithermalMultibaric() {}
+     227             :   double GaussianSwitchingFunc(const double, const double, const double) const;
+     228             : };
+     229             : 
+     230             : 
+     231             : PLUMED_REGISTER_ACTION(TD_MultithermalMultibaric,"TD_MULTITHERMAL_MULTIBARIC")
+     232             : 
+     233             : 
+     234           4 : void TD_MultithermalMultibaric::registerKeywords(Keywords& keys) {
+     235           4 :   TargetDistribution::registerKeywords(keys);
+     236           8 :   keys.add("compulsory","THRESHOLD","5","Maximum exploration free energy in kT.");
+     237           8 :   keys.add("compulsory","EPSILON","10","The zeros of the target distribution are changed to e^-EPSILON.");
+     238           8 :   keys.add("compulsory","MIN_TEMP","Minimum energy.");
+     239           8 :   keys.add("compulsory","MAX_TEMP","Maximum energy.");
+     240           8 :   keys.add("compulsory","MIN_PRESSURE","Minimum pressure.");
+     241           8 :   keys.add("compulsory","MAX_PRESSURE","Maximum pressure.");
+     242           8 :   keys.add("compulsory","PRESSURE","Target pressure of the barostat used in the MD engine.");
+     243           8 :   keys.add("compulsory","STEPS_TEMP","20","Number of temperature steps.");
+     244           8 :   keys.add("compulsory","STEPS_PRESSURE","20","Number of pressure steps.");
+     245           8 :   keys.add("optional","SIGMA","The standard deviation parameters of the Gaussian kernels used for smoothing the target distribution. One value must be specified for each argument, i.e. one value per CV. A value of 0.0 means that no smoothing is performed, this is the default behavior.");
+     246           4 : }
+     247             : 
+     248             : 
+     249           2 : TD_MultithermalMultibaric::TD_MultithermalMultibaric(const ActionOptions& ao):
+     250             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     251           2 :   threshold_(5.0),
+     252           2 :   min_temp_(0.0),
+     253           2 :   max_temp_(1000.0),
+     254           2 :   min_press_(0.0),
+     255           2 :   max_press_(1000.0),
+     256           2 :   epsilon_(10.0),
+     257           2 :   smoothening_(true),
+     258           2 :   steps_temp_(20),
+     259           2 :   steps_pressure_(20)
+     260             : {
+     261           2 :   log.printf("  Multithermal-multibaric target distribution");
+     262           2 :   log.printf("\n");
+     263             : 
+     264           2 :   log.printf("  Please read and cite ");
+     265           4 :   log << plumed.cite("Piaggi and Parrinello, Phys. Rev. Lett. 122 (5), 050601 (2019)");
+     266           2 :   log.printf(" and ");
+     267           4 :   log << plumed.cite("Piaggi and Parrinello, J. Chem. Phys. 150 (24), 244119 (2019)");
+     268           2 :   log.printf("\n");
+     269             : 
+     270             : 
+     271           2 :   parse("THRESHOLD",threshold_);
+     272           2 :   if(threshold_<=0.0) {
+     273           0 :     plumed_merror(getName()+": the value of the threshold should be positive.");
+     274             :   }
+     275           2 :   log.printf("  exploring free energy up to %f kT for each temperature and pressure\n",threshold_);
+     276           2 :   parse("MIN_TEMP",min_temp_);
+     277           2 :   parse("MAX_TEMP",max_temp_);
+     278           2 :   log.printf("  temperatures between %f and %f will be explored \n",min_temp_,max_temp_);
+     279           2 :   parse("MIN_PRESSURE",min_press_);
+     280           2 :   parse("MAX_PRESSURE",max_press_);
+     281           2 :   log.printf("  pressures between %f and %f will be explored \n",min_press_,max_press_);
+     282           2 :   parse("PRESSURE",press_);
+     283           2 :   log.printf("  pressure of the barostat should have been set to %f. Please check this in the MD engine \n",press_);
+     284           4 :   parseVector("SIGMA",sigma_);
+     285           2 :   if(sigma_.size()==0) smoothening_=false;
+     286           2 :   if(smoothening_ && (sigma_.size()<2 || sigma_.size()>3) ) plumed_merror(getName()+": SIGMA takes 2 or 3 values as input.");
+     287           2 :   if (smoothening_) {
+     288           2 :     log.printf("  the target distribution will be smoothed using sigma values");
+     289           7 :     for(unsigned i=0; i<sigma_.size(); ++i) log.printf(" %f",sigma_[i]);
+     290           2 :     log.printf("\n");
+     291             :   }
+     292           2 :   parse("STEPS_TEMP",steps_temp_);
+     293           2 :   parse("STEPS_PRESSURE",steps_pressure_);
+     294           2 :   log.printf("  %d steps in temperatures and %d steps in pressure will be employed \n",steps_temp_,steps_pressure_);
+     295           2 :   steps_temp_ += 1;
+     296           2 :   steps_pressure_ += 1;
+     297           2 :   parse("EPSILON",epsilon_);
+     298           2 :   if(epsilon_<=1.0) {
+     299           0 :     plumed_merror(getName()+": the value of epsilon should be greater than 1.");
+     300             :   }
+     301           2 :   log.printf("  the non relevant regions of the target distribution are set to e^-%f \n",epsilon_);
+     302             :   setDynamic();
+     303             :   setFesGridNeeded();
+     304           2 :   checkRead();
+     305           2 : }
+     306             : 
+     307             : 
+     308           0 : double TD_MultithermalMultibaric::getValue(const std::vector<double>& argument) const {
+     309           0 :   plumed_merror("getValue not implemented for TD_MultithermalMultibaric");
+     310             :   return 0.0;
+     311             : }
+     312             : 
+     313             : 
+     314           4 : void TD_MultithermalMultibaric::updateGrid() {
+     315           4 :   if (getStep() == 0) {
+     316           2 :     if(targetDistGrid().getDimension()>3 || targetDistGrid().getDimension()<2) plumed_merror(getName()+" works only with 2 or 3 arguments, i.e. energy and volume, or energy, volume, and CV");
+     317           2 :     if(smoothening_ && sigma_.size()!=targetDistGrid().getDimension()) plumed_merror(getName()+": mismatch between SIGMA dimension and number of arguments");
+     318             :     // Use uniform TD
+     319           4 :     std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     320             :     double norm = 0.0;
+     321       11864 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     322             :       double value = 1.0;
+     323       11862 :       norm += integration_weights[l]*value;
+     324       11862 :       targetDistGrid().setValue(l,value);
+     325             :     }
+     326           2 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     327             :   } else {
+     328           2 :     double beta = getBeta();
+     329           2 :     double beta_prime_min = 1./(getKBoltzmann()*min_temp_);
+     330           2 :     double beta_prime_max = 1./(getKBoltzmann()*max_temp_);
+     331           2 :     plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_MultithermalMultibaric!");
+     332             :     // Set all to current epsilon value
+     333       11864 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     334       11862 :       double value = exp(-1.0*epsilon_);
+     335       11862 :       targetDistGrid().setValue(l,value);
+     336             :     }
+     337             :     // Loop over pressures and temperatures
+     338          44 :     for(unsigned i=0; i<steps_temp_; i++) {
+     339          42 :       double beta_prime=beta_prime_min + (beta_prime_max-beta_prime_min)*i/(steps_temp_-1);
+     340         924 :       for(unsigned j=0; j<steps_pressure_; j++) {
+     341         882 :         double pressure_prime=min_press_ + (max_press_-min_press_)*j/(steps_pressure_-1);
+     342             :         // Find minimum for this pressure and temperature
+     343             :         double minval=DBL_MAX;
+     344     5232024 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     345     5231142 :           double energy = targetDistGrid().getPoint(l)[0];
+     346     5231142 :           double volume = targetDistGrid().getPoint(l)[1];
+     347     5231142 :           double value = getFesGridPntr()->getValue(l);
+     348     5231142 :           value = beta*value + (beta_prime-beta)*energy + (beta_prime*pressure_prime-beta*press_)*volume;
+     349     5231142 :           if(value<minval) {
+     350             :             minval=value;
+     351             :           }
+     352             :         }
+     353             :         // Now check which energies and volumes are below X kt
+     354     5232024 :         for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     355     5231142 :           double energy = targetDistGrid().getPoint(l)[0];
+     356     5231142 :           double volume = targetDistGrid().getPoint(l)[1];
+     357     5231142 :           double value = getFesGridPntr()->getValue(l);
+     358     5231142 :           value = beta*value + (beta_prime-beta)*energy + (beta_prime*pressure_prime-beta*press_)*volume - minval;
+     359     5231142 :           if (value<threshold_) {
+     360             :             double value = 1.0;
+     361       65261 :             targetDistGrid().setValue(l,value);
+     362             :           }
+     363             :         }
+     364             :       }
+     365             :     }
+     366           2 :     if (smoothening_) {
+     367           2 :       std::vector<unsigned> nbin=targetDistGrid().getNbin();
+     368           2 :       std::vector<double> dx=targetDistGrid().getDx();
+     369           2 :       unsigned dim=targetDistGrid().getDimension();
+     370             :       // Smoothening
+     371       11864 :       for(Grid::index_t index=0; index<targetDistGrid().getSize(); index++) {
+     372       11862 :         std::vector<unsigned> indices = targetDistGrid().getIndices(index);
+     373       11862 :         std::vector<double> point = targetDistGrid().getPoint(index);
+     374       11862 :         double value = targetDistGrid().getValue(index);
+     375       11862 :         if (value>(1-1.e-5)) { // Apply only if this grid point was 1.
+     376             :           // Apply gaussians around
+     377        1242 :           std::vector<int> minBin(dim), maxBin(dim); // These cannot be unsigned
+     378             :           // Only consider contributions less than n*sigma bins apart from the actual distance
+     379        4384 :           for(unsigned k=0; k<dim; k++) {
+     380        3142 :             int deltaBin=std::floor(6*sigma_[k]/dx[k]);
+     381        3142 :             minBin[k]=indices[k] - deltaBin;
+     382        3142 :             if (minBin[k] < 0) minBin[k]=0;
+     383        3142 :             if (minBin[k] > (nbin[k]-1)) minBin[k]=nbin[k]-1;
+     384        3142 :             maxBin[k]=indices[k] + deltaBin;
+     385        3142 :             if (maxBin[k] > (nbin[k]-1)) maxBin[k]=nbin[k]-1;
+     386             :           }
+     387        1242 :           if (dim==2) {
+     388        7008 :             for(unsigned l=minBin[0]; l<maxBin[0]+1; l++) {
+     389      115632 :               for(unsigned m=minBin[1]; m<maxBin[1]+1; m++) {
+     390      109208 :                 std::vector<unsigned> indices_prime(dim);
+     391      109208 :                 indices_prime[0]=l;
+     392      109208 :                 indices_prime[1]=m;
+     393      109208 :                 Grid::index_t index_prime = targetDistGrid().getIndex(indices_prime);
+     394      109208 :                 std::vector<double> point_prime = targetDistGrid().getPoint(index_prime);
+     395      109208 :                 double value_prime = targetDistGrid().getValue(index_prime);
+     396             :                 // Apply gaussian
+     397             :                 double gaussian_value = 1;
+     398      327624 :                 for(unsigned k=0; k<dim; k++) {
+     399      436832 :                   gaussian_value *= GaussianSwitchingFunc(point_prime[k],point[k],sigma_[k]);
+     400             :                 }
+     401      109208 :                 if (value_prime<gaussian_value) {
+     402        2761 :                   targetDistGrid().setValue(index_prime,gaussian_value);
+     403             :                 }
+     404             :               }
+     405             :             }
+     406         658 :           } else if (dim==3) {
+     407       12352 :             for(unsigned l=minBin[0]; l<maxBin[0]+1; l++) {
+     408       84952 :               for(unsigned m=minBin[1]; m<maxBin[1]+1; m++) {
+     409      509608 :                 for(unsigned n=minBin[2]; n<maxBin[2]+1; n++) {
+     410      436350 :                   std::vector<unsigned> indices_prime(dim);
+     411      436350 :                   indices_prime[0]=l;
+     412      436350 :                   indices_prime[1]=m;
+     413      436350 :                   indices_prime[2]=n;
+     414      436350 :                   Grid::index_t index_prime = targetDistGrid().getIndex(indices_prime);
+     415      436350 :                   std::vector<double> point_prime = targetDistGrid().getPoint(index_prime);
+     416      436350 :                   double value_prime = targetDistGrid().getValue(index_prime);
+     417             :                   // Apply gaussian
+     418             :                   double gaussian_value = 1;
+     419     1745400 :                   for(unsigned k=0; k<dim; k++) {
+     420     2618100 :                     gaussian_value *= GaussianSwitchingFunc(point_prime[k],point[k],sigma_[k]);
+     421             :                   }
+     422      436350 :                   if (value_prime<gaussian_value) {
+     423       13789 :                     targetDistGrid().setValue(index_prime,gaussian_value);
+     424             :                   }
+     425             :                 }
+     426             :               }
+     427             :             }
+     428             :           }
+     429             :         }
+     430             :       }
+     431             :     }
+     432             :     // Normalize
+     433           4 :     std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     434             :     double norm = 0.0;
+     435       11864 :     for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     436       11862 :       double value = targetDistGrid().getValue(l);
+     437       11862 :       norm += integration_weights[l]*value;
+     438             :     }
+     439           2 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     440             :   }
+     441           4 :   updateLogTargetDistGrid();
+     442           4 : }
+     443             : 
+     444             : inline
+     445             : double TD_MultithermalMultibaric::GaussianSwitchingFunc(const double argument, const double center, const double sigma) const {
+     446     1527466 :   if(sigma>0.0) {
+     447     1527466 :     double arg=(argument-center)/sigma;
+     448     1527466 :     return exp(-0.5*arg*arg);
+     449             :   }
+     450             :   else {
+     451             :     return 0.0;
+     452             :   }
+     453             : }
+     454             : 
+     455             : 
+     456             : }
+     457             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductCombination.cpp.func-sort-c.html b/coverage/ves/TD_ProductCombination.cpp.func-sort-c.html new file mode 100644 index 000000000000..8f16147d95c1 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductCombination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:557573.3 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves21TD_ProductCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves21TD_ProductCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves21TD_ProductCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZNK4PLMD3ves21TD_ProductCombination8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves21TD_ProductCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves21TD_ProductCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves21TD_ProductCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE4
_ZN4PLMD3ves21TD_ProductCombinationC2ERKNS_13ActionOptionsE4
_ZN4PLMD3ves21TD_ProductCombination16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves21TD_ProductCombination10updateGridEv14
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductCombination.cpp.func.html b/coverage/ves/TD_ProductCombination.cpp.func.html new file mode 100644 index 000000000000..aa18e025ccb5 --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductCombination.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:557573.3 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves21TD_ProductCombination10linkActionEPNS_6ActionE0
_ZN4PLMD3ves21TD_ProductCombination10updateGridEv14
_ZN4PLMD3ves21TD_ProductCombination11linkFesGridEPNS_4GridE1
_ZN4PLMD3ves21TD_ProductCombination11linkVesBiasEPNS0_7VesBiasE1
_ZN4PLMD3ves21TD_ProductCombination12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves21TD_ProductCombination16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves21TD_ProductCombination20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE4
_ZN4PLMD3ves21TD_ProductCombination25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves21TD_ProductCombinationC2ERKNS_13ActionOptionsE4
_ZNK4PLMD3ves21TD_ProductCombination8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductCombination.cpp.gcov.html b/coverage/ves/TD_ProductCombination.cpp.gcov.html new file mode 100644 index 000000000000..7c50ce7af9dc --- /dev/null +++ b/coverage/ves/TD_ProductCombination.cpp.gcov.html @@ -0,0 +1,341 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductCombination.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductCombination.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:557573.3 %
Date:2024-02-22 21:58:45Functions:61060.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "VesTools.h"
+      25             : 
+      26             : 
+      27             : #include "core/ActionRegister.h"
+      28             : #include "core/ActionSet.h"
+      29             : #include "core/PlumedMain.h"
+      30             : #include "tools/Grid.h"
+      31             : 
+      32             : #include "GridIntegrationWeights.h"
+      33             : 
+      34             : 
+      35             : namespace PLMD {
+      36             : 
+      37             : // class Grid;
+      38             : class Action;
+      39             : 
+      40             : namespace ves {
+      41             : 
+      42             : //+PLUMEDOC VES_TARGETDIST TD_PRODUCT_COMBINATION
+      43             : /*
+      44             : Target distribution given by product combination of distributions (static or dynamic).
+      45             : 
+      46             : Employ a target distribution that is a product combination of the other
+      47             : distributions, defined as
+      48             : \f[
+      49             : p(\mathbf{s}) =
+      50             : \frac{\prod_{i} p_{i}(\mathbf{s})}
+      51             : {\int d \mathbf{s} \prod_{i} p_{i}(\mathbf{s})}
+      52             : \f]
+      53             : where the distributions \f$p_{i}(\mathbf{s})\f$ are in full dimensional space
+      54             : of the arguments used.
+      55             : 
+      56             : Note the difference between this target distribution and the one defined in
+      57             : \ref TD_PRODUCT_DISTRIBUTION. Here we have a non-separable distribution given
+      58             : as a product of distribution \f$p_{i}(\mathbf{s})\f$ which are in full dimensional
+      59             : space of the arguments used.
+      60             : 
+      61             : The labels of the distributions \f$p_{i}(\mathbf{s})\f$ to be used in the
+      62             : product combination are given in the DISTRIBUTIONS keyword.
+      63             : 
+      64             : The target distribution resulting from the product combination will be
+      65             : automatically normalized. Therefore, the product combination needs to
+      66             : be a proper distribution that is non-negative and that can be normalized. The
+      67             : code will perform checks to make sure that this is indeed the case.
+      68             : 
+      69             : The product combination will be a dynamic target distribution if one or more
+      70             : of the distributions used is a dynamic distribution. Otherwise it will be a
+      71             : static distribution.
+      72             : 
+      73             : \par Examples
+      74             : 
+      75             : In the following example the overall interval on which the
+      76             : target distribution is defined is from 0.23 to 0.8.
+      77             : We employ a product combination of a well-tempered
+      78             : distribution and a uniform distribution that decays to
+      79             : zero at 0.6. This results in a target distribution that
+      80             : is well-tempered from 0.23 to 0.6 and then decays to zero.
+      81             : In other words, we cut off the tail of the well-tempered
+      82             : distribution at 0.6
+      83             : \plumedfile
+      84             : td_welltemp: TD_WELLTEMPERED BIASFACTOR=5
+      85             : td_uniform: TD_UNIFORM MINIMA=0.23 MAXIMA=0.6 SIGMA_MAXIMA=0.05
+      86             : td_combination: TD_PRODUCT_COMBINATION DISTRIBUTIONS=td_uniform,td_welltemp
+      87             : \endplumedfile
+      88             : 
+      89             : 
+      90             : In the following example the overall interval on which the
+      91             : target distribution is defined is from -4 to 4.
+      92             : We employ a product of a Gaussian distribution with two centers
+      93             : and distribution that is uniform on the interval -3 to 3 and
+      94             : then smoothly decays to zero outside that interval.
+      95             : The overall effect will then be to cut off the tails of the
+      96             : Gaussian distribution
+      97             : \plumedfile
+      98             : TD_GAUSSIAN ...
+      99             :  CENTER1=-2.9 SIGMA1=1.0
+     100             :  CENTER2=+2.9 SIGMA2=0.4
+     101             :  LABEL=td_gauss
+     102             : ... TD_GAUSSIAN
+     103             : 
+     104             : TD_UNIFORM ...
+     105             :  MINIMA=-3.0 SIGMA_MINIMA=0.20
+     106             :  MAXIMA=+3.0 SIGMA_MAXIMA=0.15
+     107             :  LABEL=td_uni
+     108             : ... TD_UNIFORM
+     109             : 
+     110             : td_pc: TD_PRODUCT_COMBINATION DISTRIBUTIONS=td_gauss,td_uni
+     111             : \endplumedfile
+     112             : 
+     113             : */
+     114             : //+ENDPLUMEDOC
+     115             : 
+     116             : class VesBias;
+     117             : 
+     118             : class TD_ProductCombination: public TargetDistribution {
+     119             : private:
+     120             :   std::vector<TargetDistribution*> distribution_pntrs_;
+     121             :   std::vector<Grid*> grid_pntrs_;
+     122             :   unsigned int ndist_;
+     123             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+     124             : public:
+     125             :   static void registerKeywords(Keywords&);
+     126             :   explicit TD_ProductCombination(const ActionOptions& ao);
+     127             :   void updateGrid() override;
+     128             :   double getValue(const std::vector<double>&) const override;
+     129             :   //
+     130             :   void linkVesBias(VesBias*) override;
+     131             :   void linkAction(Action*) override;
+     132             :   //
+     133             :   void linkBiasGrid(Grid*) override;
+     134             :   void linkBiasWithoutCutoffGrid(Grid*) override;
+     135             :   void linkFesGrid(Grid*) override;
+     136             :   //
+     137             : };
+     138             : 
+     139             : 
+     140             : PLUMED_REGISTER_ACTION(TD_ProductCombination,"TD_PRODUCT_COMBINATION")
+     141             : 
+     142             : 
+     143           6 : void TD_ProductCombination::registerKeywords(Keywords& keys) {
+     144           6 :   TargetDistribution::registerKeywords(keys);
+     145          12 :   keys.add("compulsory","DISTRIBUTIONS","The labels of the target distribution actions to be used in the product combination.");
+     146           6 :   keys.use("WELLTEMPERED_FACTOR");
+     147           6 :   keys.use("SHIFT_TO_ZERO");
+     148           6 : }
+     149             : 
+     150             : 
+     151           4 : TD_ProductCombination::TD_ProductCombination(const ActionOptions& ao):
+     152             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     153           8 :   distribution_pntrs_(0),
+     154           4 :   grid_pntrs_(0),
+     155           8 :   ndist_(0)
+     156             : {
+     157             :   std::vector<std::string> targetdist_labels;
+     158           4 :   parseVector("DISTRIBUTIONS",targetdist_labels);
+     159             : 
+     160           4 :   std::string error_msg = "";
+     161           8 :   distribution_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     162           4 :   if(error_msg.size()>0) {plumed_merror("Error in keyword DISTRIBUTIONS of "+getName()+": "+error_msg);}
+     163             : 
+     164          12 :   for(unsigned int i=0; i<distribution_pntrs_.size(); i++) {
+     165           8 :     if(distribution_pntrs_[i]->isDynamic()) {setDynamic();}
+     166           8 :     if(distribution_pntrs_[i]->fesGridNeeded()) {setFesGridNeeded();}
+     167           8 :     if(distribution_pntrs_[i]->biasGridNeeded()) {setBiasGridNeeded();}
+     168             :   }
+     169             : 
+     170           4 :   ndist_ = distribution_pntrs_.size();
+     171           4 :   grid_pntrs_.assign(ndist_,NULL);
+     172           4 :   if(ndist_==0) {plumed_merror(getName()+ ": no distributions are given.");}
+     173           4 :   if(ndist_==1) {plumed_merror(getName()+ ": giving only one distribution does not make sense.");}
+     174             :   //
+     175           4 :   checkRead();
+     176           4 : }
+     177             : 
+     178             : 
+     179           0 : double TD_ProductCombination::getValue(const std::vector<double>& argument) const {
+     180           0 :   plumed_merror("getValue not implemented for TD_ProductCombination");
+     181             :   return 0.0;
+     182             : }
+     183             : 
+     184             : 
+     185           4 : void TD_ProductCombination::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     186          12 :   for(unsigned int i=0; i<ndist_; i++) {
+     187           8 :     distribution_pntrs_[i]->setupGrids(arguments,min,max,nbins);
+     188           8 :     if(distribution_pntrs_[i]->getDimension()!=this->getDimension()) {
+     189           0 :       plumed_merror(getName() + ": all target distribution must have the same dimension");
+     190             :     }
+     191           8 :     grid_pntrs_[i]=distribution_pntrs_[i]->getTargetDistGridPntr();
+     192             :   }
+     193           4 : }
+     194             : 
+     195             : 
+     196          14 : void TD_ProductCombination::updateGrid() {
+     197          42 :   for(unsigned int i=0; i<ndist_; i++) {
+     198          28 :     distribution_pntrs_[i]->updateTargetDist();
+     199             :   }
+     200          28 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     201             :   double norm = 0.0;
+     202       11717 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     203             :     double value = 1.0;
+     204       35109 :     for(unsigned int i=0; i<ndist_; i++) {
+     205       23406 :       value *= grid_pntrs_[i]->getValue(l);
+     206             :     }
+     207       11703 :     if(value<0.0 && !isTargetDistGridShiftedToZero()) {plumed_merror(getName()+": The target distribution function gives negative values. You should change the definition of the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");}
+     208       11703 :     norm += integration_weights[l]*value;
+     209       11703 :     targetDistGrid().setValue(l,value);
+     210       11703 :     logTargetDistGrid().setValue(l,-std::log(value));
+     211             :   }
+     212             : 
+     213          14 :   if(norm>0.0) {
+     214          14 :     targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     215             :   }
+     216           0 :   else if(!isTargetDistGridShiftedToZero()) {
+     217           0 :     plumed_merror(getName()+": The target distribution function cannot be normalized proberly. You should change the definition of the target distribution to avoid this. You can also use the SHIFT_TO_ZERO keyword to avoid this problem.");
+     218             :   }
+     219          14 :   logTargetDistGrid().setMinToZero();
+     220          14 : }
+     221             : 
+     222             : 
+     223           1 : void TD_ProductCombination::linkVesBias(VesBias* vesbias_pntr_in) {
+     224           1 :   TargetDistribution::linkVesBias(vesbias_pntr_in);
+     225           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     226           2 :     distribution_pntrs_[i]->linkVesBias(vesbias_pntr_in);
+     227             :   }
+     228           1 : }
+     229             : 
+     230             : 
+     231           0 : void TD_ProductCombination::linkAction(Action* action_pntr_in) {
+     232           0 :   TargetDistribution::linkAction(action_pntr_in);
+     233           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     234           0 :     distribution_pntrs_[i]->linkAction(action_pntr_in);
+     235             :   }
+     236           0 : }
+     237             : 
+     238             : 
+     239           0 : void TD_ProductCombination::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     240           0 :   TargetDistribution::linkBiasGrid(bias_grid_pntr_in);
+     241           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     242           0 :     distribution_pntrs_[i]->linkBiasGrid(bias_grid_pntr_in);
+     243             :   }
+     244           0 : }
+     245             : 
+     246             : 
+     247           0 : void TD_ProductCombination::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     248           0 :   TargetDistribution::linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     249           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     250           0 :     distribution_pntrs_[i]->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     251             :   }
+     252           0 : }
+     253             : 
+     254             : 
+     255           1 : void TD_ProductCombination::linkFesGrid(Grid* fes_grid_pntr_in) {
+     256           1 :   TargetDistribution::linkFesGrid(fes_grid_pntr_in);
+     257           3 :   for(unsigned int i=0; i<ndist_; i++) {
+     258           2 :     distribution_pntrs_[i]->linkFesGrid(fes_grid_pntr_in);
+     259             :   }
+     260           1 : }
+     261             : 
+     262             : 
+     263             : }
+     264             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html b/coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html new file mode 100644 index 000000000000..f77466959dbe --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:487663.2 %
Date:2024-02-22 21:58:45Functions:41040.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22TD_ProductDistribution10linkActionEPNS_6ActionE0
_ZN4PLMD3ves22TD_ProductDistribution11linkFesGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution11linkVesBiasEPNS0_7VesBiasE0
_ZN4PLMD3ves22TD_ProductDistribution12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZNK4PLMD3ves22TD_ProductDistribution8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves22TD_ProductDistribution10updateGridEv15
_ZN4PLMD3ves22TD_ProductDistribution20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE15
_ZN4PLMD3ves22TD_ProductDistributionC2ERKNS_13ActionOptionsE15
_ZN4PLMD3ves22TD_ProductDistribution16registerKeywordsERNS_8KeywordsE17
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductDistribution.cpp.func.html b/coverage/ves/TD_ProductDistribution.cpp.func.html new file mode 100644 index 000000000000..04dc6807d70f --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:487663.2 %
Date:2024-02-22 21:58:45Functions:41040.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves22TD_ProductDistribution10linkActionEPNS_6ActionE0
_ZN4PLMD3ves22TD_ProductDistribution10updateGridEv15
_ZN4PLMD3ves22TD_ProductDistribution11linkFesGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution11linkVesBiasEPNS0_7VesBiasE0
_ZN4PLMD3ves22TD_ProductDistribution12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistribution16registerKeywordsERNS_8KeywordsE17
_ZN4PLMD3ves22TD_ProductDistribution20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE15
_ZN4PLMD3ves22TD_ProductDistribution25linkBiasWithoutCutoffGridEPNS_4GridE0
_ZN4PLMD3ves22TD_ProductDistributionC2ERKNS_13ActionOptionsE15
_ZNK4PLMD3ves22TD_ProductDistribution8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_ProductDistribution.cpp.gcov.html b/coverage/ves/TD_ProductDistribution.cpp.gcov.html new file mode 100644 index 000000000000..2ae285520500 --- /dev/null +++ b/coverage/ves/TD_ProductDistribution.cpp.gcov.html @@ -0,0 +1,302 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_ProductDistribution.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_ProductDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:487663.2 %
Date:2024-02-22 21:58:45Functions:41040.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "VesTools.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "core/ActionSet.h"
+      28             : #include "core/PlumedMain.h"
+      29             : #include "tools/Grid.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace ves {
+      33             : 
+      34             : //+PLUMEDOC VES_TARGETDIST TD_PRODUCT_DISTRIBUTION
+      35             : /*
+      36             : Target distribution given by a separable product of one-dimensional distributions (static or dynamic).
+      37             : 
+      38             : Employ a target distribution that is a separable product
+      39             : of one-dimensional distributions, defined as
+      40             : \f[
+      41             : p(\mathbf{s}) =
+      42             : \prod_{k}^{d} p_{k}(s_{k})
+      43             : \f]
+      44             : where \f$d\f$ is the number of arguments used and \f$p_{k}(s_{k})\f$ is the
+      45             : one-dimensional distribution corresponding to the \f$k\f$-th argument.
+      46             : 
+      47             : Note the difference between this target distribution and the one defined in
+      48             : \ref TD_PRODUCT_COMBINATION. Here we have a separable distribution given as a
+      49             : product of one-dimensional distribution \f$p_{k}(s_{k})\f$.
+      50             : 
+      51             : The labels of the one-dimensional distributions \f$p_{k}(s_{k})\f$ to be
+      52             : used in the product distribution are given in the DISTRIBUTIONS keyword.
+      53             : Note that the order of the labels is very important.
+      54             : 
+      55             : It is assumed that all the distributions to be used in the product distribution
+      56             : are normalized. If that is not the case you need to
+      57             : normalize the distributions by using the NORMALIZE keyword.
+      58             : Here it does not matter if you normalize each distribution separately
+      59             : or the overall product, it will give the same results.
+      60             : 
+      61             : The product distribution will be a dynamic target distribution if one or more
+      62             : of the distributions used is a dynamic distribution. Otherwise it will be a
+      63             : static distribution.
+      64             : 
+      65             : \par Examples
+      66             : 
+      67             : In the following example we employ a uniform distribution for
+      68             : argument 1 and a Gaussian distribution for argument 2.
+      69             : \plumedfile
+      70             : target_uniform: TD_UNIFORM
+      71             : 
+      72             : target_Gaussian: TD_GAUSSIAN CENTER1=-2.0 SIGMA1=0.5
+      73             : 
+      74             : td_pd: TD_PRODUCT_DISTRIBUTION DISTRIBUTIONS=target_uniform,target_Gaussian
+      75             : \endplumedfile
+      76             : Note that order of the labels is important, using DISTRIBUTIONS=target_Gaussian,target_uniform
+      77             : would mean that we would employ a Gaussian distribution for argument 1 and a uniform
+      78             : distribution for argument 2, which would lead to completely different results.
+      79             : 
+      80             : */
+      81             : //+ENDPLUMEDOC
+      82             : 
+      83             : class TD_ProductDistribution: public TargetDistribution {
+      84             : private:
+      85             :   std::vector<TargetDistribution*> distribution_pntrs_;
+      86             :   std::vector<Grid*> grid_pntrs_;
+      87             :   unsigned int ndist_;
+      88             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+      89             : public:
+      90             :   static void registerKeywords(Keywords&);
+      91             :   explicit TD_ProductDistribution(const ActionOptions& ao);
+      92             :   void updateGrid() override;
+      93             :   double getValue(const std::vector<double>&) const override;
+      94             :   //
+      95             :   void linkVesBias(VesBias*) override;
+      96             :   void linkAction(Action*) override;
+      97             :   void linkBiasGrid(Grid*) override;
+      98             :   void linkBiasWithoutCutoffGrid(Grid*) override;
+      99             :   void linkFesGrid(Grid*) override;
+     100             : };
+     101             : 
+     102             : 
+     103             : PLUMED_REGISTER_ACTION(TD_ProductDistribution,"TD_PRODUCT_DISTRIBUTION")
+     104             : 
+     105             : 
+     106          17 : void TD_ProductDistribution::registerKeywords(Keywords& keys) {
+     107          17 :   TargetDistribution::registerKeywords(keys);
+     108          34 :   keys.add("compulsory","DISTRIBUTIONS","Labels of the one-dimensional target distribution actions for each argument to be used in the product distribution. Note that order of the labels is important.");
+     109          17 :   keys.use("WELLTEMPERED_FACTOR");
+     110          17 :   keys.use("SHIFT_TO_ZERO");
+     111          17 :   keys.use("NORMALIZE");
+     112          17 : }
+     113             : 
+     114             : 
+     115          15 : TD_ProductDistribution::TD_ProductDistribution(const ActionOptions& ao):
+     116             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     117          30 :   distribution_pntrs_(0),
+     118          15 :   grid_pntrs_(0),
+     119          30 :   ndist_(0)
+     120             : {
+     121             :   std::vector<std::string> targetdist_labels;
+     122          15 :   parseVector("DISTRIBUTIONS",targetdist_labels);
+     123             : 
+     124          15 :   std::string error_msg = "";
+     125          30 :   distribution_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     126          15 :   if(error_msg.size()>0) {plumed_merror("Error in keyword DISTRIBUTIONS of "+getName()+": "+error_msg);}
+     127             : 
+     128          45 :   for(unsigned int i=0; i<distribution_pntrs_.size(); i++) {
+     129          30 :     if(distribution_pntrs_[i]->isDynamic()) {setDynamic();}
+     130          30 :     if(distribution_pntrs_[i]->fesGridNeeded()) {setFesGridNeeded();}
+     131          30 :     if(distribution_pntrs_[i]->biasGridNeeded()) {setBiasGridNeeded();}
+     132             :   }
+     133             : 
+     134          15 :   ndist_ = distribution_pntrs_.size();
+     135          15 :   grid_pntrs_.assign(ndist_,NULL);
+     136          15 :   setDimension(ndist_);
+     137             : 
+     138          15 :   checkRead();
+     139          15 : }
+     140             : 
+     141             : 
+     142           0 : double TD_ProductDistribution::getValue(const std::vector<double>& argument) const {
+     143           0 :   plumed_merror("getValue not implemented for TD_ProductDistribution");
+     144             :   return 0.0;
+     145             : }
+     146             : 
+     147             : 
+     148          15 : void TD_ProductDistribution::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     149          45 :   for(unsigned int i=0; i<ndist_; i++) {
+     150          30 :     std::vector<Value*> arg1d(1);
+     151          30 :     std::vector<std::string> min1d(1);
+     152          30 :     std::vector<std::string> max1d(1);
+     153          30 :     std::vector<unsigned int> nbins1d(1);
+     154          30 :     arg1d[0]=arguments[i];
+     155             :     min1d[0]=min[i];
+     156             :     max1d[0]=max[i];
+     157          30 :     nbins1d[0]=nbins[i];
+     158          30 :     distribution_pntrs_[i]->setupGrids(arg1d,min1d,max1d,nbins1d);
+     159          30 :     grid_pntrs_[i]=distribution_pntrs_[i]->getTargetDistGridPntr();
+     160          30 :     if(distribution_pntrs_[i]->getDimension()!=1 || grid_pntrs_[i]->getDimension()!=1) {
+     161           0 :       plumed_merror(getName() + ": all target distributions must be one dimensional");
+     162             :     }
+     163          30 :   }
+     164          15 : }
+     165             : 
+     166             : 
+     167          15 : void TD_ProductDistribution::updateGrid() {
+     168          45 :   for(unsigned int i=0; i<ndist_; i++) {
+     169          30 :     distribution_pntrs_[i]->updateTargetDist();
+     170             :   }
+     171      153030 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     172      153015 :     std::vector<unsigned int> indices = targetDistGrid().getIndices(l);
+     173             :     double value = 1.0;
+     174      459045 :     for(unsigned int i=0; i<ndist_; i++) {
+     175      306030 :       value *= grid_pntrs_[i]->getValue(indices[i]);
+     176             :     }
+     177      153015 :     targetDistGrid().setValue(l,value);
+     178      153015 :     logTargetDistGrid().setValue(l,-std::log(value));
+     179             :   }
+     180          15 :   logTargetDistGrid().setMinToZero();
+     181          15 : }
+     182             : 
+     183             : 
+     184           0 : void TD_ProductDistribution::linkVesBias(VesBias* vesbias_pntr_in) {
+     185           0 :   TargetDistribution::linkVesBias(vesbias_pntr_in);
+     186           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     187           0 :     distribution_pntrs_[i]->linkVesBias(vesbias_pntr_in);
+     188             :   }
+     189           0 : }
+     190             : 
+     191             : 
+     192           0 : void TD_ProductDistribution::linkAction(Action* action_pntr_in) {
+     193           0 :   TargetDistribution::linkAction(action_pntr_in);
+     194           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     195           0 :     distribution_pntrs_[i]->linkAction(action_pntr_in);
+     196             :   }
+     197           0 : }
+     198             : 
+     199             : 
+     200           0 : void TD_ProductDistribution::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     201           0 :   TargetDistribution::linkBiasGrid(bias_grid_pntr_in);
+     202           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     203           0 :     distribution_pntrs_[i]->linkBiasGrid(bias_grid_pntr_in);
+     204             :   }
+     205           0 : }
+     206             : 
+     207             : 
+     208           0 : void TD_ProductDistribution::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     209           0 :   TargetDistribution::linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     210           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     211           0 :     distribution_pntrs_[i]->linkBiasWithoutCutoffGrid(bias_withoutcutoff_grid_pntr_in);
+     212             :   }
+     213           0 : }
+     214             : 
+     215             : 
+     216           0 : void TD_ProductDistribution::linkFesGrid(Grid* fes_grid_pntr_in) {
+     217           0 :   TargetDistribution::linkFesGrid(fes_grid_pntr_in);
+     218           0 :   for(unsigned int i=0; i<ndist_; i++) {
+     219           0 :     distribution_pntrs_[i]->linkFesGrid(fes_grid_pntr_in);
+     220             :   }
+     221           0 : }
+     222             : 
+     223             : 
+     224             : }
+     225             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Uniform.cpp.func-sort-c.html b/coverage/ves/TD_Uniform.cpp.func-sort-c.html new file mode 100644 index 000000000000..6810e7827551 --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Uniform.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Uniform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545598.2 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10TD_Uniform20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE73
_ZN4PLMD3ves10TD_UniformC2ERKNS_13ActionOptionsE73
_ZN4PLMD3ves10TD_Uniform16registerKeywordsERNS_8KeywordsE75
_ZNK4PLMD3ves10TD_Uniform8getValueERKSt6vectorIdSaIdEE118654
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Uniform.cpp.func.html b/coverage/ves/TD_Uniform.cpp.func.html new file mode 100644 index 000000000000..c21ea4a37e2e --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Uniform.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Uniform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545598.2 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves10TD_Uniform16registerKeywordsERNS_8KeywordsE75
_ZN4PLMD3ves10TD_Uniform20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE73
_ZN4PLMD3ves10TD_UniformC2ERKNS_13ActionOptionsE73
_ZNK4PLMD3ves10TD_Uniform8getValueERKSt6vectorIdSaIdEE118654
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_Uniform.cpp.gcov.html b/coverage/ves/TD_Uniform.cpp.gcov.html new file mode 100644 index 000000000000..6952e6782c45 --- /dev/null +++ b/coverage/ves/TD_Uniform.cpp.gcov.html @@ -0,0 +1,382 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_Uniform.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_Uniform.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:545598.2 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : 
+      25             : #include "core/ActionRegister.h"
+      26             : 
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : //+PLUMEDOC VES_TARGETDIST TD_UNIFORM
+      32             : /*
+      33             : Uniform target distribution (static).
+      34             : 
+      35             : Using this keyword you can define a uniform target distribution which is a
+      36             : product of one-dimensional distributions \f$p_{k}(s_{k})\f$ that are uniform
+      37             : over a given interval \f$[a_{k},b_{k}]\f$
+      38             : 
+      39             : \f[
+      40             : p_{k}(s_{k}) =
+      41             : \left \{\begin{array}{ll}
+      42             : \frac{1}{(b_{k}-a_{k})} & \mathrm{if} \ a_{k} \leq s_{k} \leq b_{k} \\
+      43             : &\\
+      44             : 0 & \mathrm{otherwise}
+      45             : \end{array}\right .
+      46             : \f]
+      47             : 
+      48             : The overall distribution is then given as
+      49             : \f[
+      50             : p(\mathbf{s}) =
+      51             : \prod^{d}_{k} p_{k}(s_{k}) =
+      52             : \left\{\begin{array}{ll}
+      53             : \prod^{d}_{k} \frac{1}{(b_{k}-a_{k})}
+      54             : & \mathrm{if} \ a_{k} \leq s_{k} \leq b_{k} \ \mathrm{for\ all}\ k \\
+      55             : \\
+      56             : 0 & \mathrm{otherwise}
+      57             : \end{array}\right.
+      58             : \f]
+      59             : The distribution is thus uniform inside a rectangular for two arguments
+      60             : and a cube for a three arguments.
+      61             : 
+      62             : The limits of the intervals \f$ a_{k}\f$ and \f$ b_{k}\f$ are given
+      63             : with the MINIMA and MAXIMA keywords, respectively. If one or both of
+      64             : these keywords are missing the code should automatically detect the limits.
+      65             : 
+      66             : 
+      67             : It is also possible to use one-dimensional distributions
+      68             : that go smoothly to zero at the boundaries.
+      69             : This is done by employing a function with
+      70             : Gaussian switching functions at the boundaries \f$a_{k}\f$ and \f$b_{k}\f$
+      71             : \f[
+      72             : f_{k}(s_{k}) =
+      73             : \begin{cases}
+      74             : \exp\left(-\frac{(s_{k}-a_{k})^2}{2 \sigma^2_{a,k}}\right)
+      75             : & \mathrm{if}\, s_{k} < a_{k} \\
+      76             : \\
+      77             : 1 & \mathrm{if}\, a_{k} \leq s_{k} \leq b_{k} \\
+      78             : \\
+      79             : \exp\left(-\frac{(s_{k}-b_{k})^2}{2 \sigma^2_{b,k}}\right)
+      80             : & \mathrm{if}\, s_{k} > b_{k}
+      81             : \end{cases}
+      82             : \f]
+      83             : where the standard deviation parameters \f$\sigma_{a,k}\f$
+      84             : and \f$\sigma_{b,k}\f$ determine how quickly the switching functions
+      85             : goes to zero.
+      86             : The overall distribution is then normalized
+      87             : \f[
+      88             : p(\mathbf{s}) =
+      89             : \prod^{d}_{k} p_{k}(s_{k}) =
+      90             : \prod^{d}_{k} \frac{f(s_{k})}{\int d s_{k} \, f(s_{k})}
+      91             : \f]
+      92             : To use this option you need to provide the standard deviation
+      93             : parameters \f$\sigma_{a,k}\f$ and \f$\sigma_{b,k}\f$ by using the
+      94             : SIGMA_MINIMA and SIGMA_MAXIMA keywords, respectively. Giving a value of
+      95             : 0.0 means that the boundary is sharp, which is the default behavior.
+      96             : 
+      97             : 
+      98             : 
+      99             : 
+     100             : 
+     101             : 
+     102             : \par Examples
+     103             : 
+     104             : If one or both of the MINIMA or MAXIMA keywords are missing
+     105             : the code should automatically detect the limits not given.
+     106             : Therefore, if we consider a target distribution that is
+     107             : defined over an interval from 0.0 to 10.0 for the first
+     108             : argument and from 0.2 to 1.0 for the second argument are
+     109             : the following example
+     110             : \plumedfile
+     111             : td: TD_UNIFORM
+     112             : \endplumedfile
+     113             : 
+     114             : is equivalent to this one
+     115             : 
+     116             : \plumedfile
+     117             : TD_UNIFORM ...
+     118             :  MINIMA=0.0,0.2
+     119             :  MAXIMA=10.0,1.0
+     120             :  LABEL=td
+     121             :  ... TD_UNIFORM
+     122             : \endplumedfile
+     123             : 
+     124             : and this one
+     125             : 
+     126             : \plumedfile
+     127             : td: TD_UNIFORM  MAXIMA=10.0,1.0
+     128             : \endplumedfile
+     129             : 
+     130             : and also this one
+     131             : 
+     132             : \plumedfile
+     133             : td: TD_UNIFORM MINIMA=0.0,0,2
+     134             : \endplumedfile
+     135             : 
+     136             : 
+     137             : We can also define a target distribution that goes smoothly to zero
+     138             : at the boundaries of the uniform distribution. In the following
+     139             : we consider an interval of 0 to 10 for the target distribution.
+     140             : The following input would result in a target distribution that
+     141             : would be uniform from 2 to 7 and then smoothly go to zero from
+     142             : 2 to 0 and from 7 to 10.
+     143             : \plumedfile
+     144             : TD_UNIFORM ...
+     145             :  MINIMA=2.0
+     146             :  MAXIMA=+7.0
+     147             :  SIGMA_MINIMA=0.5
+     148             :  SIGMA_MAXIMA=1.0
+     149             :  LABEL=td
+     150             : ... TD_UNIFORM
+     151             : \endplumedfile
+     152             : It is also possible to employ a smooth switching function for just one
+     153             : of the boundaries as shown here where the target distribution
+     154             : would be uniform from 0 to 7 and then smoothly go to zero from 7 to 10.
+     155             : \plumedfile
+     156             : TD_UNIFORM ...
+     157             :  MAXIMA=+7.0
+     158             :  SIGMA_MAXIMA=1.0
+     159             :  LABEL=td
+     160             : ... TD_UNIFORM
+     161             : \endplumedfile
+     162             : Furthermore, it is possible to employ a sharp boundary by
+     163             : using
+     164             : \plumedfile
+     165             : TD_UNIFORM ...
+     166             :  MAXIMA=+7.0
+     167             :  SIGMA_MAXIMA=0.0
+     168             :  LABEL=td
+     169             : ... TD_UNIFORM
+     170             : \endplumedfile
+     171             : or
+     172             : \plumedfile
+     173             : td: TD_UNIFORM MAXIMA=+7.0
+     174             : \endplumedfile
+     175             : 
+     176             : 
+     177             : */
+     178             : //+ENDPLUMEDOC
+     179             : 
+     180             : class TD_Uniform : public TargetDistribution {
+     181             :   std::vector<double> minima_;
+     182             :   std::vector<double> maxima_;
+     183             :   std::vector<double> sigma_min_;
+     184             :   std::vector<double> sigma_max_;
+     185             :   double GaussianSwitchingFunc(const double, const double, const double) const;
+     186             :   void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) override;
+     187             : public:
+     188             :   static void registerKeywords( Keywords&);
+     189             :   explicit TD_Uniform(const ActionOptions& ao);
+     190             :   double getValue(const std::vector<double>&) const override;
+     191             : };
+     192             : 
+     193             : 
+     194             : PLUMED_REGISTER_ACTION(TD_Uniform,"TD_UNIFORM")
+     195             : 
+     196             : 
+     197          75 : void TD_Uniform::registerKeywords(Keywords& keys) {
+     198          75 :   TargetDistribution::registerKeywords(keys);
+     199         150 :   keys.add("optional","MINIMA","The minimum of the intervals where the target distribution is taken as uniform. You should give one value for each argument.");
+     200         150 :   keys.add("optional","MAXIMA","The maximum of the intervals where the target distribution is taken as uniform. You should give one value for each argument.");
+     201         150 :   keys.add("optional","SIGMA_MINIMA","The standard deviation parameters of the Gaussian switching functions for the minima of the intervals. You should give one value for each argument. Value of 0.0 means that switch is done without a smooth switching function, this is the default behavior.");
+     202         150 :   keys.add("optional","SIGMA_MAXIMA","The standard deviation parameters of the Gaussian switching functions for the maximum of the intervals. You should give one value for each argument. Value of 0.0 means that switch is done without a smooth switching function, this is the default behavior.");
+     203          75 : }
+     204             : 
+     205             : 
+     206          73 : TD_Uniform::TD_Uniform(const ActionOptions& ao):
+     207             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     208         146 :   minima_(0),
+     209          73 :   maxima_(0),
+     210          73 :   sigma_min_(0),
+     211         146 :   sigma_max_(0)
+     212             : {
+     213          73 :   parseVector("MINIMA",minima_);
+     214          73 :   parseVector("MAXIMA",maxima_);
+     215             : 
+     216          73 :   parseVector("SIGMA_MINIMA",sigma_min_);
+     217         146 :   parseVector("SIGMA_MAXIMA",sigma_max_);
+     218          73 :   if(minima_.size()==0 && sigma_min_.size()>0) {plumed_merror(getName()+": you cannot give SIGMA_MINIMA if MINIMA is not given");}
+     219          73 :   if(maxima_.size()==0 && sigma_max_.size()>0) {plumed_merror(getName()+": you cannot give SIGMA_MAXIMA if MAXIMA is not given");}
+     220             : 
+     221          73 :   if(minima_.size()>0 && maxima_.size()>0) {
+     222             :     // both MINIMA and MAXIMA given, do all checks
+     223          58 :     if(minima_.size()!=maxima_.size()) {plumed_merror(getName()+": MINIMA and MAXIMA do not have the same number of values.");}
+     224          58 :     setDimension(minima_.size());
+     225         122 :     for(unsigned int k=0; k<getDimension(); k++) {
+     226          64 :       if(minima_[k]>maxima_[k]) {
+     227           0 :         plumed_merror(getName()+": error in MINIMA and MAXIMA keywords, one of the MINIMA values is larger than the corresponding MAXIMA values");
+     228             :       }
+     229             :     }
+     230             :   }
+     231          15 :   else if(minima_.size()>0 && maxima_.size()==0) {
+     232             :     // only MINIMA given, MAXIMA assigned later on.
+     233           1 :     setDimension(minima_.size());
+     234             :   }
+     235          14 :   else if(maxima_.size()>0 && minima_.size()==0) {
+     236             :     // only MAXIMA given, MINIMA assigned later on.
+     237           1 :     setDimension(maxima_.size());
+     238             :   }
+     239          13 :   else if(maxima_.size()==0 && minima_.size()==0) {
+     240             :     // neither MAXIMA nor MINIMA givenm, both assigned later on.
+     241          13 :     setDimension(0);
+     242             :   }
+     243             : 
+     244          73 :   if(sigma_min_.size()==0) {sigma_min_.assign(getDimension(),0.0);}
+     245          73 :   if(sigma_max_.size()==0) {sigma_max_.assign(getDimension(),0.0);}
+     246          73 :   if(sigma_min_.size()!=getDimension()) {plumed_merror(getName()+": SIGMA_MINIMA has the wrong number of values");}
+     247          73 :   if(sigma_max_.size()!=getDimension()) {plumed_merror(getName()+": SIGMA_MAXIMA has the wrong number of values");}
+     248             :   //
+     249             :   setForcedNormalization();
+     250          73 :   checkRead();
+     251          73 : }
+     252             : 
+     253             : 
+     254          73 : void TD_Uniform::setupAdditionalGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     255             : 
+     256          73 :   if(minima_.size()==0) {
+     257          14 :     minima_.assign(getDimension(),0.0);
+     258          33 :     for(unsigned int k=0; k<getDimension(); k++) {Tools::convert(min[k],minima_[k]);}
+     259             :   }
+     260             : 
+     261          73 :   if(maxima_.size()==0) {
+     262          14 :     maxima_.assign(getDimension(),0.0);
+     263          33 :     for(unsigned int k=0; k<getDimension(); k++) {Tools::convert(max[k],maxima_[k]);}
+     264             :   }
+     265             : 
+     266          73 : }
+     267             : 
+     268             : 
+     269      118654 : double TD_Uniform::getValue(const std::vector<double>& argument) const {
+     270             :   //
+     271             :   double value = 1.0;
+     272      338719 :   for(unsigned int k=0; k<getDimension(); k++) {
+     273             :     double tmp;
+     274      220065 :     if(argument[k] < minima_[k]) {
+     275       15379 :       tmp = GaussianSwitchingFunc(argument[k],minima_[k],sigma_min_[k]);
+     276             :     }
+     277      204686 :     else if(argument[k] > maxima_[k]) {
+     278       15566 :       tmp = GaussianSwitchingFunc(argument[k],maxima_[k],sigma_max_[k]);
+     279             :     }
+     280             :     else {
+     281             :       tmp = 1.0;
+     282             :     }
+     283      220065 :     value *= tmp;
+     284             :   }
+     285      118654 :   return value;
+     286             : }
+     287             : 
+     288             : inline
+     289             : double TD_Uniform::GaussianSwitchingFunc(const double argument, const double center, const double sigma) const {
+     290       30945 :   if(sigma>0.0) {
+     291       23278 :     double arg=(argument-center)/sigma;
+     292       23278 :     return exp(-0.5*arg*arg);
+     293             :   }
+     294             :   else {
+     295             :     return 0.0;
+     296             :   }
+     297             : }
+     298             : 
+     299             : 
+     300             : 
+     301             : 
+     302             : 
+     303             : 
+     304             : }
+     305             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_VonMises.cpp.func-sort-c.html b/coverage/ves/TD_VonMises.cpp.func-sort-c.html new file mode 100644 index 000000000000..a62e4f02b255 --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_VonMises.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_VonMises.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:747598.7 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_VonMisesC2ERKNS_13ActionOptionsE9
_ZN4PLMD3ves11TD_VonMises16registerKeywordsERNS_8KeywordsE11
_ZNK4PLMD3ves11TD_VonMises16getNormalizationEdd19
_ZNK4PLMD3ves11TD_VonMises8getValueERKSt6vectorIdSaIdEE31100
_ZNK4PLMD3ves11TD_VonMises16VonMisesDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_80319
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_VonMises.cpp.func.html b/coverage/ves/TD_VonMises.cpp.func.html new file mode 100644 index 000000000000..066a5956b00f --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_VonMises.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_VonMises.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:747598.7 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11TD_VonMises16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD3ves11TD_VonMisesC2ERKNS_13ActionOptionsE9
_ZNK4PLMD3ves11TD_VonMises16VonMisesDiagonalERKSt6vectorIdSaIdEES6_S6_S6_S6_80319
_ZNK4PLMD3ves11TD_VonMises16getNormalizationEdd19
_ZNK4PLMD3ves11TD_VonMises8getValueERKSt6vectorIdSaIdEE31100
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_VonMises.cpp.gcov.html b/coverage/ves/TD_VonMises.cpp.gcov.html new file mode 100644 index 000000000000..67d9e64cc0d0 --- /dev/null +++ b/coverage/ves/TD_VonMises.cpp.gcov.html @@ -0,0 +1,316 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_VonMises.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_VonMises.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:747598.7 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "tools/Tools.h"
+      28             : 
+      29             : #include <iostream>
+      30             : 
+      31             : 
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace ves {
+      35             : 
+      36             : //+PLUMEDOC VES_TARGETDIST TD_VONMISES
+      37             : /*
+      38             : Target distribution given by a sum of Von Mises distributions (static).
+      39             : 
+      40             : Employ a target distribution that is given by a sum where each
+      41             : term is a product of one-dimensional
+      42             : [Von Mises distributions](https://en.wikipedia.org/wiki/Von_Mises_distribution),
+      43             : \f[
+      44             : p(\mathbf{s}) = \sum_{i} \, w_{i}
+      45             : \prod_{k}^{d}
+      46             : \frac{\exp\left(\kappa_{k,i} \, \cos (s_{k}-\mu_{k,i}) \right)}
+      47             : {2\pi I_{0}(\kappa_{k,i})}
+      48             : \f]
+      49             : where \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$
+      50             : are the centers of the distributions,
+      51             : \f$(\kappa_{1,i},\kappa_{2,i},\ldots,\kappa_{d,i})\f$
+      52             : are parameters that determine the extend of each distribution,
+      53             : and \f$I_{0}(x)\f$ is the modified Bessel function of order 0.
+      54             : The weights \f$w_{i}\f$ are normalized to 1, \f$\sum_{i}w_{i}=1\f$.
+      55             : 
+      56             : The Von Mises distribution is defined for periodic variables with a
+      57             : periodicity of \f$2\pi\f$ and is analogous to the Gaussian distribution.
+      58             : The parameter \f$ \sqrt{1/\kappa}\f$ is comparable to the standard deviation
+      59             : \f$\sigma\f$ for the Gaussian distribution.
+      60             : 
+      61             : To use this target distribution you need to give the centers
+      62             : \f$(\mu_{1,i},\mu_{2,i},\ldots,\mu_{d,i})\f$ by
+      63             : using the numbered CENTER keywords and the "standard deviations"
+      64             : \f$(\sqrt{1/\kappa_{1,i}},\sqrt{1/\kappa_{2,i}},\ldots,\sqrt{1/\kappa_{d,i}})\f$ using the numbered SIGMA keywords.
+      65             : 
+      66             : 
+      67             : \par Examples
+      68             : 
+      69             : Sum of two Von Mises distribution in one dimension that have equal weights
+      70             : as no weights are given.
+      71             : \plumedfile
+      72             : TD_VONMISES ...
+      73             :  CENTER1=+2.0 SIGMA1=0.6
+      74             :  CENTER2=-2.0 SIGMA2=0.7
+      75             :  LABEL=td
+      76             : ... TD_VONMISES
+      77             : \endplumedfile
+      78             : 
+      79             : Sum of two Von Mises distribution in two dimensions that have different weights.
+      80             : Note that the weights are automatically normalized to 1 such that
+      81             : specifying WEIGHTS=1.0,2.0 is equal to specifying WEIGHTS=0.33333,0.66667.
+      82             : \plumedfile
+      83             : TD_VONMISES ...
+      84             :  CENTER1=+2.0,+2.0 SIGMA1=0.6,0.7
+      85             :  CENTER2=-2.0,+2.0 SIGMA2=0.7,0.6
+      86             :  WEIGHTS=1.0,2.0
+      87             :  LABEL=td
+      88             : ... TD_VONMISES
+      89             : \endplumedfile
+      90             : 
+      91             : */
+      92             : //+ENDPLUMEDOC
+      93             : 
+      94             : class TD_VonMises: public TargetDistribution {
+      95             :   // properties of the Gaussians
+      96             :   std::vector< std::vector<double> > sigmas_;
+      97             :   std::vector< std::vector<double> > kappas_;
+      98             :   std::vector< std::vector<double> > centers_;
+      99             :   std::vector< std::vector<double> > normalization_;
+     100             :   std::vector<double> weights_;
+     101             :   std::vector<double> periods_;
+     102             :   unsigned int ncenters_;
+     103             :   double VonMisesDiagonal(const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&, const std::vector<double>&) const;
+     104             :   double getNormalization(const double, const double) const;
+     105             : public:
+     106             :   static void registerKeywords(Keywords&);
+     107             :   explicit TD_VonMises(const ActionOptions& ao);
+     108             :   double getValue(const std::vector<double>&) const override;
+     109             : };
+     110             : 
+     111             : 
+     112             : PLUMED_REGISTER_ACTION(TD_VonMises,"TD_VONMISES")
+     113             : 
+     114             : 
+     115          11 : void TD_VonMises::registerKeywords(Keywords& keys) {
+     116          11 :   TargetDistribution::registerKeywords(keys);
+     117          22 :   keys.add("numbered","CENTER","The centers of the Von Mises distributions.");
+     118          22 :   keys.add("numbered","SIGMA","The standard deviations of the Von Mises distributions.");
+     119          22 :   keys.add("optional","WEIGHTS","The weights of the Von Mises distributions. Have to be as many as the number of centers given with the numbered CENTER keywords. If no weights are given the distributions are weighted equally. The weights are automatically normalized to 1.");
+     120          22 :   keys.add("hidden","PERIODS","The periods for each of the dimensions. By default they are 2*pi for each dimension.");
+     121          11 :   keys.use("WELLTEMPERED_FACTOR");
+     122          11 :   keys.use("SHIFT_TO_ZERO");
+     123             :   //keys.use("NORMALIZE");
+     124          11 : }
+     125             : 
+     126             : 
+     127           9 : TD_VonMises::TD_VonMises(const ActionOptions& ao):
+     128             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     129          18 :   sigmas_(0),
+     130           9 :   centers_(0),
+     131           9 :   normalization_(0),
+     132           9 :   weights_(0),
+     133           9 :   periods_(0),
+     134          18 :   ncenters_(0)
+     135             : {
+     136          13 :   for(unsigned int i=1;; i++) {
+     137             :     std::vector<double> tmp_center;
+     138          44 :     if(!parseNumberedVector("CENTER",i,tmp_center) ) {break;}
+     139          13 :     centers_.push_back(tmp_center);
+     140          13 :   }
+     141          13 :   for(unsigned int i=1;; i++) {
+     142             :     std::vector<double> tmp_sigma;
+     143          44 :     if(!parseNumberedVector("SIGMA",i,tmp_sigma) ) {break;}
+     144          13 :     sigmas_.push_back(tmp_sigma);
+     145          13 :   }
+     146             :   //
+     147           9 :   plumed_massert(centers_.size()==sigmas_.size(),"there has to be an equal amount of CENTER and SIGMA keywords");
+     148           9 :   if(centers_.size()==0) {
+     149           0 :     plumed_merror(getName()+": CENTER and SIGMA keywords seem to be missing. Note that numbered keywords start at CENTER1 and SIGMA1.");
+     150             :   }
+     151             :   //
+     152           9 :   setDimension(centers_[0].size());
+     153           9 :   ncenters_ = centers_.size();
+     154             :   //
+     155             :   // check centers and sigmas
+     156          22 :   for(unsigned int i=0; i<ncenters_; i++) {
+     157          13 :     if(centers_[i].size()!=getDimension()) {plumed_merror(getName()+": one of the CENTER keyword does not match the given dimension");}
+     158          13 :     if(sigmas_[i].size()!=getDimension()) {plumed_merror(getName()+": one of the SIGMA keyword does not match the given dimension");}
+     159             :   }
+     160             :   //
+     161           9 :   kappas_.resize(sigmas_.size());
+     162          22 :   for(unsigned int i=0; i<sigmas_.size(); i++) {
+     163          13 :     kappas_[i].resize(sigmas_[i].size());
+     164          32 :     for(unsigned int k=0; k<kappas_[i].size(); k++) {
+     165          19 :       kappas_[i][k] = 1.0/(sigmas_[i][k]*sigmas_[i][k]);
+     166             :     }
+     167             :   }
+     168             :   //
+     169          18 :   parseVector("WEIGHTS",weights_);
+     170           9 :   if(weights_.size()==0) {weights_.assign(centers_.size(),1.0);}
+     171           9 :   if(centers_.size()!=weights_.size()) {plumed_merror(getName() + ": there has to be as many weights given in WEIGHTS as numbered CENTER keywords");}
+     172             :   //
+     173           9 :   if(periods_.size()==0) {periods_.assign(getDimension(),2*pi);}
+     174          18 :   parseVector("PERIODS",periods_);
+     175           9 :   if(periods_.size()!=getDimension()) {plumed_merror(getName() + ": the number of values given in PERIODS does not match the dimension of the distribution");}
+     176             :   //
+     177             :   double sum_weights=0.0;
+     178          22 :   for(unsigned int i=0; i<weights_.size(); i++) {sum_weights+=weights_[i];}
+     179          22 :   for(unsigned int i=0; i<weights_.size(); i++) {weights_[i]/=sum_weights;}
+     180             :   //
+     181           9 :   normalization_.resize(ncenters_);
+     182          22 :   for(unsigned int i=0; i<ncenters_; i++) {
+     183          13 :     normalization_[i].resize(getDimension());
+     184          32 :     for(unsigned int k=0; k<getDimension(); k++) {
+     185          19 :       normalization_[i][k] = getNormalization(kappas_[i][k],periods_[k]);
+     186             :     }
+     187             :   }
+     188           9 :   checkRead();
+     189           9 : }
+     190             : 
+     191             : 
+     192       31100 : double TD_VonMises::getValue(const std::vector<double>& argument) const {
+     193             :   double value=0.0;
+     194       92400 :   for(unsigned int i=0; i<ncenters_; i++) {
+     195       61300 :     value+=weights_[i]*VonMisesDiagonal(argument, centers_[i], kappas_[i],periods_,normalization_[i]);
+     196             :   }
+     197       31100 :   return value;
+     198             : }
+     199             : 
+     200             : 
+     201       80319 : double TD_VonMises::VonMisesDiagonal(const std::vector<double>& argument, const std::vector<double>& center, const std::vector<double>& kappa, const std::vector<double>& periods, const std::vector<double>& normalization) const {
+     202             :   double value = 1.0;
+     203      220638 :   for(unsigned int k=0; k<argument.size(); k++) {
+     204      140319 :     double arg = kappa[k]*cos( ((2*pi)/periods[k])*(argument[k]-center[k]) );
+     205      140319 :     value*=normalization[k]*exp(arg);
+     206             :   }
+     207       80319 :   return value;
+     208             : }
+     209             : 
+     210             : 
+     211          19 : double TD_VonMises::getNormalization(const double kappa, const double period) const {
+     212             :   //
+     213          19 :   std::vector<double> centers(1);
+     214          19 :   centers[0] = 0.0;
+     215          19 :   std::vector<double> kappas(1);
+     216          19 :   kappas[0] = kappa;
+     217          19 :   std::vector<double> periods(1);
+     218          19 :   periods[0] = period;
+     219          19 :   std::vector<double> norm(1);
+     220          19 :   norm[0] = 1.0;
+     221             :   //
+     222             :   const unsigned int nbins = 1001;
+     223             :   std::vector<double> points;
+     224             :   std::vector<double> weights;
+     225             :   double min = 0.0;
+     226             :   double max = period;
+     227          19 :   GridIntegrationWeights::getOneDimensionalIntegrationPointsAndWeights(points,weights,nbins,min,max);
+     228             :   //
+     229             :   double sum = 0.0;
+     230       19038 :   for(unsigned int l=0; l<nbins; l++) {
+     231       19019 :     std::vector<double> arg(1); arg[0]= points[l];
+     232       19019 :     sum += weights[l] * VonMisesDiagonal(arg,centers,kappas,periods,norm);
+     233             :   }
+     234          38 :   return 1.0/sum;
+     235             : }
+     236             : 
+     237             : 
+     238             : }
+     239             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_WellTempered.cpp.func-sort-c.html b/coverage/ves/TD_WellTempered.cpp.func-sort-c.html new file mode 100644 index 000000000000..16bbd1f9417b --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_WellTempered.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_WellTempered.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves15TD_WellTemperedD2Ev0
_ZNK4PLMD3ves15TD_WellTempered8getValueERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves15TD_WellTemperedC2ERKNS_13ActionOptionsE29
_ZN4PLMD3ves15TD_WellTemperedD0Ev29
_ZN4PLMD3ves15TD_WellTempered16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD3ves15TD_WellTempered10updateGridEv319
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_WellTempered.cpp.func.html b/coverage/ves/TD_WellTempered.cpp.func.html new file mode 100644 index 000000000000..f35ef084761e --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_WellTempered.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_WellTempered.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves15TD_WellTempered10updateGridEv319
_ZN4PLMD3ves15TD_WellTempered16registerKeywordsERNS_8KeywordsE31
_ZN4PLMD3ves15TD_WellTemperedC2ERKNS_13ActionOptionsE29
_ZN4PLMD3ves15TD_WellTemperedD0Ev29
_ZN4PLMD3ves15TD_WellTemperedD2Ev0
_ZNK4PLMD3ves15TD_WellTempered8getValueERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TD_WellTempered.cpp.gcov.html b/coverage/ves/TD_WellTempered.cpp.gcov.html new file mode 100644 index 000000000000..a3a478e47007 --- /dev/null +++ b/coverage/ves/TD_WellTempered.cpp.gcov.html @@ -0,0 +1,241 @@ + + + + + + + + LCOV - plumed test coverage - ves/TD_WellTempered.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TD_WellTempered.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283190.3 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "GridIntegrationWeights.h"
+      25             : 
+      26             : #include "core/ActionRegister.h"
+      27             : #include "tools/Grid.h"
+      28             : #include "core/PlumedMain.h"
+      29             : 
+      30             : 
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : //+PLUMEDOC VES_TARGETDIST TD_WELLTEMPERED
+      36             : /*
+      37             : Well-tempered target distribution (dynamic).
+      38             : 
+      39             : Use as a target distribution the well-tempered distribution \cite Barducci:2008
+      40             : given by
+      41             : \f[
+      42             : p(\mathbf{s}) =
+      43             : \frac{e^{-(\beta/\gamma) F(\mathbf{s})}}
+      44             : {\int d\mathbf{s}\, e^{-(\beta/\gamma) F(\mathbf{s})}} =
+      45             : \frac{[P_{0}(\mathbf{s})]^{1/\gamma}}
+      46             : {\int d\mathbf{s}\, [P_{0}(\mathbf{s})]^{1/\gamma}}
+      47             : \f]
+      48             : where \f$\gamma\f$ is a so-called bias factor and \f$P_{0}(\mathbf{s})\f$ is the
+      49             : unbiased canonical distribution of the CVs. This target distribution thus
+      50             : corresponds to a biased ensemble where, as compared to the unbiased one,
+      51             : the probability peaks have been broaden and the fluctuations of the CVs are
+      52             : enhanced.
+      53             : The value of the bias factor \f$\gamma\f$ determines by how much the fluctuations
+      54             : are enhanced.
+      55             : 
+      56             : The well-tempered distribution can be view as sampling on
+      57             : an effective free energy surface \f$\tilde{F}(\mathbf{s}) = (1/\gamma) F(\mathbf{s})\f$
+      58             : which has largely the same metastable states as the original \f$F(\mathbf{s})\f$
+      59             : but with barriers that have been reduced by a factor of \f$\gamma\f$.
+      60             : Generally one should use a value of \f$\gamma\f$ that results in
+      61             : effective barriers on the order of few \f$k_{\mathrm{B}}T\f$
+      62             : such that thermal fluctuations can easily induce transitions
+      63             : between different metastable states.
+      64             : 
+      65             : At convergence the relationship between the bias potential and the free
+      66             : energy surface is given by
+      67             : \f[
+      68             : F(\mathbf{s}) = - \left(\frac{1}{1-\gamma^{-1}} \right) V(\mathbf{s})
+      69             : \f]
+      70             : 
+      71             : This target distribution depends directly on the free energy surface
+      72             : \f$F(\mathbf{s})\f$ which is quantity that we do not know a-priori and
+      73             : want to obtain. Therefore, this target distribution
+      74             : is iteratively updated \cite Valsson-JCTC-2015 according to
+      75             : \f[
+      76             : p^{(m+1)}(\mathbf{s}) =
+      77             : \frac{e^{-(\beta/\gamma) F^{(m+1)}(\mathbf{s})}}
+      78             : {\int d\mathbf{s}\, e^{-(\beta/\gamma) F^{(m+1)}(\mathbf{s})}}
+      79             : \f]
+      80             : where \f$F^{(m+1)}(\mathbf{s})\f$ is the current best estimate of the
+      81             : free energy surface obtained according to
+      82             : \f[
+      83             : F^{(m+1)}(\mathbf{s}) =
+      84             : - V^{(m+1)}(\mathbf{s}) - \frac{1}{\beta} \log p^{(m)}(\mathbf{s}) =
+      85             : - V^{(m+1)}(\mathbf{s}) + \frac{1}{\gamma} F^{(m)}(\mathbf{s})
+      86             : \f]
+      87             : The frequency of performing this update needs to be set in the
+      88             : optimizer used in the calculation. Normally it is sufficient
+      89             : to do it every 100-1000 bias update iterations.
+      90             : 
+      91             : \par Examples
+      92             : 
+      93             : Employ a well-tempered target distribution with a bias factor of 10
+      94             : \plumedfile
+      95             : td_welltemp: TD_WELLTEMPERED BIASFACTOR=10
+      96             : \endplumedfile
+      97             : 
+      98             : */
+      99             : //+ENDPLUMEDOC
+     100             : 
+     101             : class TD_WellTempered: public TargetDistribution {
+     102             : private:
+     103             :   double bias_factor_;
+     104             : public:
+     105             :   static void registerKeywords(Keywords&);
+     106             :   explicit TD_WellTempered(const ActionOptions& ao);
+     107             :   void updateGrid() override;
+     108             :   double getValue(const std::vector<double>&) const override;
+     109          29 :   ~TD_WellTempered() {}
+     110             : };
+     111             : 
+     112             : 
+     113             : PLUMED_REGISTER_ACTION(TD_WellTempered,"TD_WELLTEMPERED")
+     114             : 
+     115             : 
+     116          31 : void TD_WellTempered::registerKeywords(Keywords& keys) {
+     117          31 :   TargetDistribution::registerKeywords(keys);
+     118          62 :   keys.add("compulsory","BIASFACTOR","The bias factor used for the well-tempered distribution.");
+     119          31 : }
+     120             : 
+     121             : 
+     122          29 : TD_WellTempered::TD_WellTempered(const ActionOptions& ao):
+     123             :   PLUMED_VES_TARGETDISTRIBUTION_INIT(ao),
+     124          29 :   bias_factor_(0.0)
+     125             : {
+     126          29 :   log.printf("  Well-tempered target distribution, see and cite ");
+     127          58 :   log << plumed.cite("Valsson and Parrinello, J. Chem. Theory Comput. 11, 1996-2002 (2015)");
+     128          58 :   log << plumed.cite("Barducci, Bussi, and Parrinello, Phys. Rev. Lett. 100, 020603 (2008)");
+     129          29 :   log.printf("\n");
+     130          29 :   parse("BIASFACTOR",bias_factor_);
+     131          29 :   if(bias_factor_<=1.0) {
+     132           0 :     plumed_merror("TD_WELLTEMPERED target distribution: the value of the bias factor doesn't make sense, it should be larger than 1.0");
+     133             :   }
+     134             :   setDynamic();
+     135             :   setFesGridNeeded();
+     136          29 :   checkRead();
+     137          29 : }
+     138             : 
+     139             : 
+     140           0 : double TD_WellTempered::getValue(const std::vector<double>& argument) const {
+     141           0 :   plumed_merror("getValue not implemented for TD_WellTempered");
+     142             :   return 0.0;
+     143             : }
+     144             : 
+     145             : 
+     146         319 : void TD_WellTempered::updateGrid() {
+     147         319 :   double beta_prime = getBeta()/bias_factor_;
+     148         319 :   plumed_massert(getFesGridPntr()!=NULL,"the FES grid has to be linked to use TD_WellTempered!");
+     149         638 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(getTargetDistGridPntr());
+     150             :   double norm = 0.0;
+     151     1127896 :   for(Grid::index_t l=0; l<targetDistGrid().getSize(); l++) {
+     152     1127577 :     double value = beta_prime * getFesGridPntr()->getValue(l);
+     153     1127577 :     logTargetDistGrid().setValue(l,value);
+     154     1127577 :     value = exp(-value);
+     155     1127577 :     norm += integration_weights[l]*value;
+     156     1127577 :     targetDistGrid().setValue(l,value);
+     157             :   }
+     158         319 :   targetDistGrid().scaleAllValuesAndDerivatives(1.0/norm);
+     159         319 :   logTargetDistGrid().setMinToZero();
+     160         319 : }
+     161             : 
+     162             : 
+     163             : }
+     164             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistModifer.h.func-sort-c.html b/coverage/ves/TargetDistModifer.h.func-sort-c.html new file mode 100644 index 000000000000..b8f54a41d782 --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistModifer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistModifer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves19WellTemperedModifer25getModifedTargetDistValueEdRKSt6vectorIdSaIdEE21206
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistModifer.h.func.html b/coverage/ves/TargetDistModifer.h.func.html new file mode 100644 index 000000000000..612fa1015148 --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistModifer.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistModifer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD3ves19WellTemperedModifer25getModifedTargetDistValueEdRKSt6vectorIdSaIdEE21206
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistModifer.h.gcov.html b/coverage/ves/TargetDistModifer.h.gcov.html new file mode 100644 index 000000000000..8dca0078bd93 --- /dev/null +++ b/coverage/ves/TargetDistModifer.h.gcov.html @@ -0,0 +1,130 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistModifer.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistModifer.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:33100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_TargetDistModifer_h
+      23             : #define __PLUMED_ves_TargetDistModifer_h
+      24             : 
+      25             : #include <vector>
+      26             : #include <cmath>
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace ves {
+      30             : 
+      31             : class TargetDistModifer {
+      32             : public:
+      33             :   virtual double getModifedTargetDistValue(const double targetdist_value, const std::vector<double>& cv_values) const = 0;
+      34             :   virtual ~TargetDistModifer() {}
+      35             : };
+      36             : 
+      37             : class WellTemperedModifer:public TargetDistModifer {
+      38             : private:
+      39             :   double invbiasf_;
+      40             : public:
+      41           6 :   explicit WellTemperedModifer(double biasfactor):invbiasf_(1.0/biasfactor) {}
+      42       21206 :   double getModifedTargetDistValue(const double targetdist_value, const std::vector<double>& cv_values) const override {
+      43       21206 :     return std::pow(targetdist_value,invbiasf_);
+      44             :   }
+      45             : };
+      46             : 
+      47             : 
+      48             : 
+      49             : 
+      50             : }
+      51             : }
+      52             : 
+      53             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.cpp.func-sort-c.html b/coverage/ves/TargetDistribution.cpp.func-sort-c.html new file mode 100644 index 000000000000..7867a886da3f --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.func-sort-c.html @@ -0,0 +1,177 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18921787.1 %
Date:2024-02-22 21:58:45Functions:222684.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18TargetDistribution10linkActionEPNS_6ActionE0
_ZN4PLMD3ves18TargetDistribution12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves18TargetDistribution14checkNanAndInfEv0
_ZN4PLMD3ves18TargetDistributionD0Ev0
_ZN4PLMD3ves18TargetDistribution22clearLogTargetDistGridEv1
_ZN4PLMD3ves18TargetDistribution15setupBiasCutoffEv3
_ZN4PLMD3ves18TargetDistribution25linkBiasWithoutCutoffGridEPNS_4GridE3
_ZN4PLMD3ves18TargetDistribution32setMinimumOfTargetDistGridToZeroEv3
_ZN4PLMD3ves18TargetDistribution28applyTargetDistModiferToGridEPNS0_17TargetDistModiferE6
_ZN4PLMD3ves18TargetDistribution11getMarginalERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE8
_ZN4PLMD3ves18TargetDistribution27readInRestartTargetDistGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD3ves18TargetDistribution33updateBiasCutoffForTargetDistGridEv24
_ZN4PLMD3ves18TargetDistribution27getMarginalDistributionGridEPNS_4GridERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE28
_ZN4PLMD3ves18TargetDistribution23updateLogTargetDistGridEv29
_ZN4PLMD3ves18TargetDistribution11linkFesGridEPNS_4GridE40
_ZN4PLMD3ves18TargetDistribution11linkVesBiasEPNS0_7VesBiasE49
_ZN4PLMD3ves18TargetDistribution13normalizeGridEPNS_4GridE90
_ZN4PLMD3ves18TargetDistribution31calculateStaticDistributionGridEv368
_ZNK4PLMD3ves18TargetDistribution7getBetaEv377
_ZN4PLMD3ves18TargetDistribution10setupGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE407
_ZN4PLMD3ves18TargetDistributionC2ERKNS_13ActionOptionsE407
_ZN4PLMD3ves18TargetDistributionD2Ev407
_ZN4PLMD3ves18TargetDistribution12setDimensionEj420
_ZN4PLMD3ves18TargetDistribution16registerKeywordsERNS_8KeywordsE441
_ZN4PLMD3ves18TargetDistribution16updateTargetDistEv802
_ZN4PLMD3ves18TargetDistribution13integrateGridEPKNS_4GridE901
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.cpp.func.html b/coverage/ves/TargetDistribution.cpp.func.html new file mode 100644 index 000000000000..88b91f5b9ff1 --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.func.html @@ -0,0 +1,177 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18921787.1 %
Date:2024-02-22 21:58:45Functions:222684.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18TargetDistribution10linkActionEPNS_6ActionE0
_ZN4PLMD3ves18TargetDistribution10setupGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE407
_ZN4PLMD3ves18TargetDistribution11getMarginalERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EE8
_ZN4PLMD3ves18TargetDistribution11linkFesGridEPNS_4GridE40
_ZN4PLMD3ves18TargetDistribution11linkVesBiasEPNS0_7VesBiasE49
_ZN4PLMD3ves18TargetDistribution12linkBiasGridEPNS_4GridE0
_ZN4PLMD3ves18TargetDistribution12setDimensionEj420
_ZN4PLMD3ves18TargetDistribution13integrateGridEPKNS_4GridE901
_ZN4PLMD3ves18TargetDistribution13normalizeGridEPNS_4GridE90
_ZN4PLMD3ves18TargetDistribution14checkNanAndInfEv0
_ZN4PLMD3ves18TargetDistribution15setupBiasCutoffEv3
_ZN4PLMD3ves18TargetDistribution16registerKeywordsERNS_8KeywordsE441
_ZN4PLMD3ves18TargetDistribution16updateTargetDistEv802
_ZN4PLMD3ves18TargetDistribution22clearLogTargetDistGridEv1
_ZN4PLMD3ves18TargetDistribution23updateLogTargetDistGridEv29
_ZN4PLMD3ves18TargetDistribution25linkBiasWithoutCutoffGridEPNS_4GridE3
_ZN4PLMD3ves18TargetDistribution27getMarginalDistributionGridEPNS_4GridERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISA_EE28
_ZN4PLMD3ves18TargetDistribution27readInRestartTargetDistGridERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE8
_ZN4PLMD3ves18TargetDistribution28applyTargetDistModiferToGridEPNS0_17TargetDistModiferE6
_ZN4PLMD3ves18TargetDistribution31calculateStaticDistributionGridEv368
_ZN4PLMD3ves18TargetDistribution32setMinimumOfTargetDistGridToZeroEv3
_ZN4PLMD3ves18TargetDistribution33updateBiasCutoffForTargetDistGridEv24
_ZN4PLMD3ves18TargetDistributionC2ERKNS_13ActionOptionsE407
_ZN4PLMD3ves18TargetDistributionD0Ev0
_ZN4PLMD3ves18TargetDistributionD2Ev407
_ZNK4PLMD3ves18TargetDistribution7getBetaEv377
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.cpp.gcov.html b/coverage/ves/TargetDistribution.cpp.gcov.html new file mode 100644 index 000000000000..e33553a51907 --- /dev/null +++ b/coverage/ves/TargetDistribution.cpp.gcov.html @@ -0,0 +1,465 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18921787.1 %
Date:2024-02-22 21:58:45Functions:222684.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "TargetDistribution.h"
+      24             : #include "TargetDistModifer.h"
+      25             : 
+      26             : #include "VesBias.h"
+      27             : #include "GridIntegrationWeights.h"
+      28             : #include "VesTools.h"
+      29             : 
+      30             : #include "core/Value.h"
+      31             : #include "tools/Grid.h"
+      32             : #include "tools/File.h"
+      33             : #include "tools/Keywords.h"
+      34             : 
+      35             : #include "GridProjWeights.h"
+      36             : 
+      37             : namespace PLMD {
+      38             : namespace ves {
+      39             : 
+      40         441 : void TargetDistribution::registerKeywords( Keywords& keys ) {
+      41         441 :   Action::registerKeywords(keys);
+      42         882 :   keys.reserve("optional","WELLTEMPERED_FACTOR","Broaden the target distribution such that it is taken as [p(s)]^(1/gamma) where gamma is the well tempered factor given here. If this option is active the distribution will be automatically normalized.");
+      43         882 :   keys.reserveFlag("SHIFT_TO_ZERO",false,"Shift the minimum value of the target distribution to zero. This can for example be used to avoid negative values in the target distribution. If this option is active the distribution will be automatically normalized.");
+      44         882 :   keys.reserveFlag("NORMALIZE",false,"Renormalized the target distribution over the intervals on which it is defined to make sure that it is properly normalized to 1. In most cases this should not be needed as the target distributions should be normalized. The code will issue a warning (but still run) if this is needed for some reason.");
+      45         441 : }
+      46             : 
+      47             : 
+      48         407 : TargetDistribution::TargetDistribution(const ActionOptions&ao):
+      49             :   Action(ao),
+      50         407 :   type_(static_targetdist),
+      51         407 :   force_normalization_(false),
+      52         407 :   check_normalization_(true),
+      53         407 :   check_nonnegative_(true),
+      54         407 :   check_nan_inf_(false),
+      55         407 :   shift_targetdist_to_zero_(false),
+      56         407 :   dimension_(0),
+      57         814 :   grid_args_(0),
+      58         407 :   action_pntr_(NULL),
+      59         407 :   vesbias_pntr_(NULL),
+      60         407 :   needs_bias_grid_(false),
+      61         407 :   needs_bias_withoutcutoff_grid_(false),
+      62         407 :   needs_fes_grid_(false),
+      63         407 :   bias_grid_pntr_(NULL),
+      64         407 :   bias_withoutcutoff_grid_pntr_(NULL),
+      65         407 :   fes_grid_pntr_(NULL),
+      66         407 :   static_grid_calculated(false),
+      67         407 :   allow_bias_cutoff_(true),
+      68         407 :   bias_cutoff_active_(false)
+      69             : {
+      70             :   //
+      71         814 :   if(keywords.exists("WELLTEMPERED_FACTOR")) {
+      72         301 :     double welltempered_factor=0.0;
+      73         301 :     parse("WELLTEMPERED_FACTOR",welltempered_factor);
+      74             :     //
+      75         301 :     if(welltempered_factor>0.0) {
+      76             :       auto pntr = Tools::make_unique<WellTemperedModifer>(welltempered_factor);
+      77           6 :       targetdist_modifer_pntrs_.emplace_back(std::move(pntr));
+      78           6 :     }
+      79         295 :     else if(welltempered_factor<0.0) {
+      80           0 :       plumed_merror(getName()+": negative value in WELLTEMPERED_FACTOR does not make sense");
+      81             :     }
+      82             :   }
+      83             :   //
+      84         814 :   if(keywords.exists("SHIFT_TO_ZERO")) {
+      85         289 :     parseFlag("SHIFT_TO_ZERO",shift_targetdist_to_zero_);
+      86         289 :     if(shift_targetdist_to_zero_) {
+      87           3 :       if(bias_cutoff_active_) {plumed_merror(getName()+": using SHIFT_TO_ZERO with bias cutoff is not allowed.");}
+      88           3 :       check_nonnegative_=false;
+      89             :     }
+      90             :   }
+      91             :   //
+      92         814 :   if(keywords.exists("NORMALIZE")) {
+      93         263 :     bool force_normalization=false;
+      94         263 :     parseFlag("NORMALIZE",force_normalization);
+      95         263 :     if(force_normalization) {
+      96           3 :       if(shift_targetdist_to_zero_) {plumed_merror(getName()+" with label "+getLabel()+": using NORMALIZE with SHIFT_TO_ZERO is not needed, the target distribution will be automatically normalized.");}
+      97             :       setForcedNormalization();
+      98             :     }
+      99             :   }
+     100             : 
+     101         407 : }
+     102             : 
+     103             : 
+     104         407 : TargetDistribution::~TargetDistribution() {
+     105         814 : }
+     106         377 : double TargetDistribution::getBeta() const {
+     107         377 :   plumed_massert(vesbias_pntr_!=NULL,"The VesBias has to be linked to use TargetDistribution::getBeta()");
+     108         377 :   return vesbias_pntr_->getBeta();
+     109             : }
+     110             : 
+     111             : 
+     112         420 : void TargetDistribution::setDimension(const unsigned int dimension) {
+     113         420 :   plumed_massert(dimension_==0,"setDimension: the dimension of the target distribution has already been set");
+     114         420 :   dimension_=dimension;
+     115         420 : }
+     116             : 
+     117             : 
+     118          49 : void TargetDistribution::linkVesBias(VesBias* vesbias_pntr_in) {
+     119          49 :   vesbias_pntr_ = vesbias_pntr_in;
+     120          49 :   action_pntr_ = static_cast<Action*>(vesbias_pntr_in);
+     121          49 : }
+     122             : 
+     123             : 
+     124           0 : void TargetDistribution::linkAction(Action* action_pntr_in) {
+     125           0 :   action_pntr_ = action_pntr_in;
+     126           0 : }
+     127             : 
+     128             : 
+     129           0 : void TargetDistribution::linkBiasGrid(Grid* bias_grid_pntr_in) {
+     130           0 :   bias_grid_pntr_ = bias_grid_pntr_in;
+     131           0 : }
+     132             : 
+     133             : 
+     134           3 : void TargetDistribution::linkBiasWithoutCutoffGrid(Grid* bias_withoutcutoff_grid_pntr_in) {
+     135           3 :   bias_withoutcutoff_grid_pntr_ = bias_withoutcutoff_grid_pntr_in;
+     136           3 : }
+     137             : 
+     138             : 
+     139          40 : void TargetDistribution::linkFesGrid(Grid* fes_grid_pntr_in) {
+     140          40 :   fes_grid_pntr_ = fes_grid_pntr_in;
+     141          40 : }
+     142             : 
+     143             : 
+     144           3 : void TargetDistribution::setupBiasCutoff() {
+     145           3 :   if(!allow_bias_cutoff_) {
+     146           0 :     plumed_merror(getName()+" with label "+getLabel()+": this target distribution does not support a bias cutoff");
+     147             :   }
+     148           3 :   if(targetdist_modifer_pntrs_.size()>0) {
+     149           0 :     plumed_merror(getName()+" with label "+getLabel()+": using a bias cutoff with a target distribution modifer like WELLTEMPERED_FACTOR is not allowed");
+     150             :   }
+     151           3 :   bias_cutoff_active_=true;
+     152             :   setBiasWithoutCutoffGridNeeded();
+     153             :   setDynamic();
+     154             :   // as the p(s) includes the derivative factor so normalization
+     155             :   // check can be misleading
+     156           3 :   check_normalization_=false;
+     157           3 :   force_normalization_=false;
+     158           3 : }
+     159             : 
+     160             : 
+     161         407 : void TargetDistribution::setupGrids(const std::vector<Value*>& arguments, const std::vector<std::string>& min, const std::vector<std::string>& max, const std::vector<unsigned int>& nbins) {
+     162         407 :   if(getDimension()==0) {
+     163          78 :     setDimension(arguments.size());
+     164             :   }
+     165             :   unsigned int dimension = getDimension();
+     166         407 :   plumed_massert(arguments.size()==dimension,"TargetDistribution::setupGrids: mismatch between number of values given for grid parameters");
+     167         407 :   plumed_massert(min.size()==dimension,"TargetDistribution::setupGrids: mismatch between number of values given for grid parameters");
+     168         407 :   plumed_massert(max.size()==dimension,"TargetDistribution::setupGrids: mismatch between number of values given for grid parameters");
+     169         407 :   plumed_massert(nbins.size()==dimension,"TargetDistribution::setupGrids: mismatch between number of values given for grid parameters");
+     170         407 :   grid_args_=arguments;
+     171         814 :   targetdist_grid_pntr_ =     Tools::make_unique<Grid>("targetdist",arguments,min,max,nbins,false,false);
+     172         814 :   log_targetdist_grid_pntr_ = Tools::make_unique<Grid>("log_targetdist",arguments,min,max,nbins,false,false);
+     173         407 :   setupAdditionalGrids(arguments,min,max,nbins);
+     174         407 : }
+     175             : 
+     176             : 
+     177         368 : void TargetDistribution::calculateStaticDistributionGrid() {
+     178         368 :   if(static_grid_calculated && !bias_cutoff_active_) {return;}
+     179             :   // plumed_massert(isStatic(),"this should only be used for static distributions");
+     180         348 :   plumed_massert(targetdist_grid_pntr_,"the grids have not been setup using setupGrids");
+     181         348 :   plumed_massert(log_targetdist_grid_pntr_,"the grids have not been setup using setupGrids");
+     182      467955 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     183             :   {
+     184      467607 :     std::vector<double> argument = targetdist_grid_pntr_->getPoint(l);
+     185      467607 :     double value = getValue(argument);
+     186      467607 :     targetdist_grid_pntr_->setValue(l,value);
+     187      467607 :     log_targetdist_grid_pntr_->setValue(l,-std::log(value));
+     188             :   }
+     189         348 :   log_targetdist_grid_pntr_->setMinToZero();
+     190         348 :   static_grid_calculated = true;
+     191             : }
+     192             : 
+     193             : 
+     194         901 : double TargetDistribution::integrateGrid(const Grid* grid_pntr) {
+     195        1802 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(grid_pntr);
+     196             :   double sum = 0.0;
+     197     2579140 :   for(Grid::index_t l=0; l<grid_pntr->getSize(); l++) {
+     198     2578239 :     sum += integration_weights[l]*grid_pntr->getValue(l);
+     199             :   }
+     200         901 :   return sum;
+     201             : }
+     202             : 
+     203             : 
+     204          90 : double TargetDistribution::normalizeGrid(Grid* grid_pntr) {
+     205          90 :   double normalization = TargetDistribution::integrateGrid(grid_pntr);
+     206          90 :   grid_pntr->scaleAllValuesAndDerivatives(1.0/normalization);
+     207          90 :   return normalization;
+     208             : }
+     209             : 
+     210             : 
+     211          28 : Grid TargetDistribution::getMarginalDistributionGrid(Grid* grid_pntr, const std::vector<std::string>& args) {
+     212          28 :   plumed_massert(grid_pntr->getDimension()>1,"doesn't make sense calculating the marginal distribution for a one-dimensional distribution");
+     213          28 :   plumed_massert(args.size()<grid_pntr->getDimension(),"the number of arguments for the marginal distribution should be less than the dimension of the full distribution");
+     214             :   //
+     215          28 :   std::vector<std::string> argnames = grid_pntr->getArgNames();
+     216          28 :   std::vector<unsigned int> args_index(0);
+     217          84 :   for(unsigned int i=0; i<argnames.size(); i++) {
+     218         112 :     for(unsigned int l=0; l<args.size(); l++) {
+     219          56 :       if(argnames[i]==args[l]) {args_index.push_back(i);}
+     220             :     }
+     221             :   }
+     222          28 :   plumed_massert(args.size()==args_index.size(),"getMarginalDistributionGrid: problem with the arguments of the marginal");
+     223             :   //
+     224             :   auto Pw = Tools::make_unique<MarginalWeight>();
+     225          28 :   Grid proj_grid = grid_pntr->project(args,Pw.get());
+     226             :   Pw.reset();
+     227             :   //
+     228             :   // scale with the bin volume used for the integral such that the
+     229             :   // marginals are proberly normalized to 1.0
+     230          28 :   double intVol = grid_pntr->getBinVolume();
+     231          56 :   for(unsigned int l=0; l<args_index.size(); l++) {
+     232          28 :     intVol/=grid_pntr->getDx()[args_index[l]];
+     233             :   }
+     234          28 :   proj_grid.scaleAllValuesAndDerivatives(intVol);
+     235             :   //
+     236          28 :   return proj_grid;
+     237          56 : }
+     238             : 
+     239             : 
+     240           8 : Grid TargetDistribution::getMarginal(const std::vector<std::string>& args) {
+     241           8 :   return TargetDistribution::getMarginalDistributionGrid(targetdist_grid_pntr_.get(),args);
+     242             : }
+     243             : 
+     244             : 
+     245         802 : void TargetDistribution::updateTargetDist() {
+     246             :   //
+     247         802 :   updateGrid();
+     248             :   //
+     249         808 :   for(unsigned int i=0; i<targetdist_modifer_pntrs_.size(); i++) {
+     250           6 :     applyTargetDistModiferToGrid(targetdist_modifer_pntrs_[i].get());
+     251             :   }
+     252             :   //
+     253         802 :   if(bias_cutoff_active_) {updateBiasCutoffForTargetDistGrid();}
+     254             :   //
+     255         802 :   if(shift_targetdist_to_zero_ && !(bias_cutoff_active_)) {setMinimumOfTargetDistGridToZero();}
+     256         802 :   if(force_normalization_ && !(bias_cutoff_active_) ) {normalizeTargetDistGrid();}
+     257             :   //
+     258             :   // if(check_normalization_ && !force_normalization_ && !shift_targetdist_to_zero_){
+     259         802 :   if(check_normalization_ && !(bias_cutoff_active_)) {
+     260         691 :     double normalization = integrateGrid(targetdist_grid_pntr_.get());
+     261             :     const double normalization_thrshold = 0.1;
+     262         691 :     if(normalization < 1.0-normalization_thrshold || normalization > 1.0+normalization_thrshold) {
+     263           9 :       std::string norm_str; Tools::convert(normalization,norm_str);
+     264           9 :       std::string msg = "the target distribution grid is not proberly normalized, integrating over the grid gives: " + norm_str + " - You can avoid this problem by using the NORMALIZE keyword";
+     265           9 :       warning(msg);
+     266             :     }
+     267             :   }
+     268             :   //
+     269         802 :   if(check_nonnegative_) {
+     270             :     const double nonnegative_thrshold = -0.02;
+     271         799 :     double grid_min_value = targetdist_grid_pntr_->getMinValue();
+     272         799 :     if(grid_min_value<nonnegative_thrshold) {
+     273           0 :       std::string grid_min_value_str; Tools::convert(grid_min_value,grid_min_value_str);
+     274           0 :       std::string msg = "the target distribution grid has negative values, the lowest value is: " + grid_min_value_str + " - You can avoid this problem by using the SHIFT_TO_ZERO keyword";
+     275           0 :       warning(msg);
+     276             :     }
+     277             :   }
+     278             :   //
+     279         802 :   if(check_nan_inf_) {checkNanAndInf();}
+     280             :   //
+     281         802 : }
+     282             : 
+     283             : 
+     284          24 : void TargetDistribution::updateBiasCutoffForTargetDistGrid() {
+     285          24 :   plumed_massert(vesbias_pntr_!=NULL,"The VesBias has to be linked to use updateBiasCutoffForTargetDistGrid()");
+     286          24 :   plumed_massert(vesbias_pntr_->biasCutoffActive(),"updateBiasCutoffForTargetDistGrid() should only be used if the bias cutoff is active");
+     287             :   // plumed_massert(targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     288             :   // plumed_massert(log_targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     289          24 :   plumed_massert(getBiasWithoutCutoffGridPntr()!=NULL,"the bias without cutoff grid has to be linked");
+     290             :   //
+     291          48 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr_.get());
+     292             :   double norm = 0.0;
+     293        2624 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     294             :   {
+     295        2600 :     double value = targetdist_grid_pntr_->getValue(l);
+     296        2600 :     double bias = getBiasWithoutCutoffGridPntr()->getValue(l);
+     297        2600 :     double deriv_factor_swf = 0.0;
+     298        2600 :     double swf = vesbias_pntr_->getBiasCutoffSwitchingFunction(bias,deriv_factor_swf);
+     299             :     // this comes from the p(s)
+     300        2600 :     value *= swf;
+     301        2600 :     norm += integration_weights[l]*value;
+     302             :     // this comes from the derivative of V(s)
+     303        2600 :     value *= deriv_factor_swf;
+     304        2600 :     targetdist_grid_pntr_->setValue(l,value);
+     305             :     // double log_value = log_targetdist_grid_pntr_->getValue(l) - std::log(swf);
+     306             :     // log_targetdist_grid_pntr_->setValue(l,log_value);
+     307             :   }
+     308          24 :   targetdist_grid_pntr_->scaleAllValuesAndDerivatives(1.0/norm);
+     309             :   // log_targetdist_grid_pntr_->setMinToZero();
+     310          24 : }
+     311             : 
+     312           6 : void TargetDistribution::applyTargetDistModiferToGrid(TargetDistModifer* modifer_pntr) {
+     313             :   // plumed_massert(targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     314             :   // plumed_massert(log_targetdist_grid_pntr_!=NULL,"the grids have not been setup using setupGrids");
+     315             :   //
+     316          12 :   std::vector<double> integration_weights = GridIntegrationWeights::getIntegrationWeights(targetdist_grid_pntr_.get());
+     317             :   double norm = 0.0;
+     318       21212 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     319             :   {
+     320       21206 :     double value = targetdist_grid_pntr_->getValue(l);
+     321       21206 :     std::vector<double> cv_values = targetdist_grid_pntr_->getPoint(l);
+     322       21206 :     value = modifer_pntr->getModifedTargetDistValue(value,cv_values);
+     323       21206 :     norm += integration_weights[l]*value;
+     324       21206 :     targetdist_grid_pntr_->setValue(l,value);
+     325       21206 :     log_targetdist_grid_pntr_->setValue(l,-std::log(value));
+     326             :   }
+     327           6 :   targetdist_grid_pntr_->scaleAllValuesAndDerivatives(1.0/norm);
+     328           6 :   log_targetdist_grid_pntr_->setMinToZero();
+     329           6 : }
+     330             : 
+     331             : 
+     332          29 : void TargetDistribution::updateLogTargetDistGrid() {
+     333       44070 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     334             :   {
+     335       44041 :     log_targetdist_grid_pntr_->setValue(l,-std::log(targetdist_grid_pntr_->getValue(l)));
+     336             :   }
+     337          29 :   log_targetdist_grid_pntr_->setMinToZero();
+     338          29 : }
+     339             : 
+     340             : 
+     341           3 : void TargetDistribution::setMinimumOfTargetDistGridToZero() {
+     342           3 :   targetDistGrid().setMinToZero();
+     343           3 :   normalizeTargetDistGrid();
+     344           3 :   updateLogTargetDistGrid();
+     345           3 : }
+     346             : 
+     347             : 
+     348           8 : void TargetDistribution::readInRestartTargetDistGrid(const std::string& grid_fname) {
+     349           8 :   plumed_massert(isDynamic(),"this should only be used for dynamically updated target distributions!");
+     350           8 :   IFile gridfile;
+     351           8 :   if(!gridfile.FileExist(grid_fname)) {
+     352           0 :     plumed_merror(getName()+": problem with reading previous target distribution when restarting, cannot find file " + grid_fname);
+     353             :   }
+     354           8 :   gridfile.open(grid_fname);
+     355          16 :   std::unique_ptr<GridBase> restart_grid = GridBase::create("targetdist",grid_args_,gridfile,false,false,false);
+     356           8 :   if(restart_grid->getSize()!=targetdist_grid_pntr_->getSize()) {
+     357           0 :     plumed_merror(getName()+": problem with reading previous target distribution when restarting, the grid is not of the correct size!");
+     358             :   }
+     359           8 :   VesTools::copyGridValues(restart_grid.get(),targetdist_grid_pntr_.get());
+     360           8 :   updateLogTargetDistGrid();
+     361           8 : }
+     362             : 
+     363           1 : void TargetDistribution::clearLogTargetDistGrid() {
+     364           1 :   log_targetdist_grid_pntr_->clear();
+     365           1 : }
+     366             : 
+     367             : 
+     368           0 : void TargetDistribution::checkNanAndInf() {
+     369           0 :   for(Grid::index_t l=0; l<targetdist_grid_pntr_->getSize(); l++)
+     370             :   {
+     371           0 :     double value = targetdist_grid_pntr_->getValue(l);
+     372           0 :     if(std::isnan(value) || std::isinf(value)) {
+     373           0 :       std::string vs; Tools::convert(value,vs);
+     374           0 :       std::vector<double> p = targetdist_grid_pntr_->getPoint(l);
+     375           0 :       std::string ps; Tools::convert(p[0],ps);
+     376           0 :       ps = "(" + ps;
+     377           0 :       for(unsigned int k=1; k<p.size(); k++) {
+     378           0 :         std::string t1; Tools::convert(p[k],t1);
+     379           0 :         ps = ps + "," + t1;
+     380             :       }
+     381           0 :       ps = ps + ")";
+     382           0 :       plumed_merror(getName()+": problem with target distribution, the value at " + ps + " is " + vs);
+     383             :     }
+     384             :   }
+     385           0 : }
+     386             : 
+     387             : }
+     388             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.h.func-sort-c.html b/coverage/ves/TargetDistribution.h.func-sort-c.html new file mode 100644 index 000000000000..5138b2aff685 --- /dev/null +++ b/coverage/ves/TargetDistribution.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:182281.8 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18TargetDistribution5applyEv0
_ZN4PLMD3ves18TargetDistribution6updateEv0
_ZN4PLMD3ves18TargetDistribution9calculateEv0
_ZN4PLMD3ves18TargetDistribution23normalizeTargetDistGridEv90
_ZN4PLMD3ves18TargetDistribution20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE287
_ZN4PLMD3ves18TargetDistribution10updateGridEv368
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.h.func.html b/coverage/ves/TargetDistribution.h.func.html new file mode 100644 index 000000000000..da3ec7c4ba00 --- /dev/null +++ b/coverage/ves/TargetDistribution.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:182281.8 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18TargetDistribution10updateGridEv368
_ZN4PLMD3ves18TargetDistribution20setupAdditionalGridsERKSt6vectorIPNS_5ValueESaIS4_EERKS2_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EESI_RKS2_IjSaIjEE287
_ZN4PLMD3ves18TargetDistribution23normalizeTargetDistGridEv90
_ZN4PLMD3ves18TargetDistribution5applyEv0
_ZN4PLMD3ves18TargetDistribution6updateEv0
_ZN4PLMD3ves18TargetDistribution9calculateEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/TargetDistribution.h.gcov.html b/coverage/ves/TargetDistribution.h.gcov.html new file mode 100644 index 000000000000..f413a2004198 --- /dev/null +++ b/coverage/ves/TargetDistribution.h.gcov.html @@ -0,0 +1,286 @@ + + + + + + + + LCOV - plumed test coverage - ves/TargetDistribution.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - TargetDistribution.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:182281.8 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_TargetDistribution_h
+      23             : #define __PLUMED_ves_TargetDistribution_h
+      24             : 
+      25             : #include "core/Action.h"
+      26             : 
+      27             : #include <vector>
+      28             : #include <string>
+      29             : #include <cmath>
+      30             : #include <memory>
+      31             : 
+      32             : #define PLUMED_VES_TARGETDISTRIBUTION_INIT(ao) TargetDistribution(ao)
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : /**
+      37             : \ingroup INHERIT
+      38             : Abstract base class for implenting new target distributions.
+      39             : */
+      40             : 
+      41             : class Action;
+      42             : class Grid;
+      43             : class Value;
+      44             : class Keywords;
+      45             : 
+      46             : namespace ves {
+      47             : 
+      48             : class TargetDistModifer;
+      49             : class VesBias;
+      50             : 
+      51             : class TargetDistribution :
+      52             :   public Action
+      53             : {
+      54             : private:
+      55             :   enum TargetDistType {
+      56             :     static_targetdist,
+      57             :     dynamic_targetdist
+      58             :   } type_;
+      59             :   //
+      60             :   bool force_normalization_;
+      61             :   bool check_normalization_;
+      62             :   bool check_nonnegative_;
+      63             :   bool check_nan_inf_;
+      64             :   bool shift_targetdist_to_zero_;
+      65             :   // dimension of the distribution
+      66             :   unsigned int dimension_;
+      67             :   // grid parameters
+      68             :   std::vector<Value*> grid_args_;
+      69             :   //
+      70             :   std::unique_ptr<Grid> targetdist_grid_pntr_;
+      71             :   std::unique_ptr<Grid> log_targetdist_grid_pntr_;
+      72             :   //
+      73             :   std::vector<std::unique_ptr<TargetDistModifer>> targetdist_modifer_pntrs_;
+      74             :   //
+      75             :   Action* action_pntr_;
+      76             :   VesBias* vesbias_pntr_;
+      77             :   //
+      78             :   bool needs_bias_grid_;
+      79             :   bool needs_bias_withoutcutoff_grid_;
+      80             :   bool needs_fes_grid_;
+      81             :   //
+      82             :   Grid* bias_grid_pntr_;
+      83             :   Grid* bias_withoutcutoff_grid_pntr_;
+      84             :   Grid* fes_grid_pntr_;
+      85             :   //
+      86             :   bool static_grid_calculated;
+      87             :   //
+      88             :   bool allow_bias_cutoff_;
+      89             :   bool bias_cutoff_active_;
+      90             :   //
+      91             :   void calculateStaticDistributionGrid();
+      92             :   void updateBiasCutoffForTargetDistGrid();
+      93             :   void checkNanAndInf();
+      94             : protected:
+      95             :   void setStatic() {type_=static_targetdist;}
+      96          41 :   void setDynamic() {type_=dynamic_targetdist;}
+      97             :   // set the that target distribution is normalized
+      98          80 :   void setForcedNormalization() {force_normalization_=true; check_normalization_=false;}
+      99             :   void unsetForcedNormalization() {force_normalization_=false; check_normalization_=true;};
+     100             :   //
+     101           0 :   void setBiasGridNeeded() {needs_bias_grid_=true;}
+     102           3 :   void setBiasWithoutCutoffGridNeeded() {needs_bias_withoutcutoff_grid_=true;}
+     103          38 :   void setFesGridNeeded() {needs_fes_grid_=true;}
+     104             :   //
+     105             :   VesBias* getPntrToVesBias() const;
+     106             :   Action* getPntrToAction() const;
+     107             :   //
+     108         287 :   virtual void setupAdditionalGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&) {}
+     109             :   //
+     110             :   void normalizeTargetDistGrid();
+     111             :   //
+     112             :   Grid& targetDistGrid() const {return *targetdist_grid_pntr_;}
+     113             :   Grid& logTargetDistGrid() const {return *log_targetdist_grid_pntr_;}
+     114             :   //
+     115             :   Grid* getBiasGridPntr() const {return bias_grid_pntr_;}
+     116        2624 :   Grid* getBiasWithoutCutoffGridPntr() const {return bias_withoutcutoff_grid_pntr_;}
+     117    11814078 :   Grid* getFesGridPntr() const {return fes_grid_pntr_;}
+     118             :   //
+     119             :   double getBeta() const;
+     120             :   //
+     121             :   void applyTargetDistModiferToGrid(TargetDistModifer* modifer_pntr);
+     122             :   //
+     123             :   void setMinimumOfTargetDistGridToZero();
+     124             :   void updateLogTargetDistGrid();
+     125             :   //
+     126         368 :   virtual void updateGrid() {calculateStaticDistributionGrid();}
+     127             : public:
+     128             :   static void registerKeywords(Keywords&);
+     129             :   explicit TargetDistribution(const ActionOptions&);
+     130             :   ~TargetDistribution();
+     131             :   //
+     132             :   bool isStatic() const {return type_==static_targetdist;}
+     133         602 :   bool isDynamic() const {return type_==dynamic_targetdist;}
+     134             :   // is the target distribution normalize or not
+     135             :   bool forcedNormalization() const {return force_normalization_;};
+     136        5194 :   bool isTargetDistGridShiftedToZero() const {return shift_targetdist_to_zero_;}
+     137             :   //
+     138         466 :   bool biasGridNeeded() const {return needs_bias_grid_;}
+     139          45 :   bool biasWithoutCutoffGridNeeded() const {return needs_bias_withoutcutoff_grid_;}
+     140         466 :   bool fesGridNeeded()  const {return needs_fes_grid_;}
+     141             :   //
+     142             :   void allowBiasCutoff() {allow_bias_cutoff_=true;}
+     143             :   void doNotAllowBiasCutoff() {allow_bias_cutoff_=false;}
+     144             :   bool isBiasCutoffAllowed() const {return allow_bias_cutoff_;}
+     145             :   bool biasCutoffActive() const {return bias_cutoff_active_;}
+     146             :   //
+     147             :   void setDimension(const unsigned int dimension);
+     148      506318 :   unsigned getDimension() const {return dimension_;}
+     149             :   //
+     150             :   virtual void linkVesBias(VesBias*);
+     151             :   virtual void linkAction(Action*);
+     152             :   //
+     153             :   virtual void linkBiasGrid(Grid*);
+     154             :   virtual void linkBiasWithoutCutoffGrid(Grid*);
+     155             :   virtual void linkFesGrid(Grid*);
+     156             :   //
+     157             :   void setupBiasCutoff();
+     158             :   //
+     159             :   Grid* getTargetDistGridPntr() const {return targetdist_grid_pntr_.get();}
+     160             :   Grid* getLogTargetDistGridPntr() const {return log_targetdist_grid_pntr_.get();}
+     161             :   //
+     162             :   void clearLogTargetDistGrid();
+     163             :   // calculate the target distribution itself
+     164             :   virtual double getValue(const std::vector<double>&) const = 0;
+     165             :   //
+     166             :   void setupGrids(const std::vector<Value*>&, const std::vector<std::string>&, const std::vector<std::string>&, const std::vector<unsigned int>&);
+     167             :   //
+     168             :   Grid getMarginal(const std::vector<std::string>&);
+     169             :   //
+     170             :   void updateTargetDist();
+     171             :   //
+     172             :   void readInRestartTargetDistGrid(const std::string&);
+     173             :   //
+     174             :   static double integrateGrid(const Grid*);
+     175             :   static double normalizeGrid(Grid*);
+     176             :   static Grid getMarginalDistributionGrid(Grid*, const std::vector<std::string>&);
+     177             :   // empty standard action stuff
+     178           0 :   void update() override {};
+     179           0 :   void apply() override {};
+     180           0 :   void calculate() override {};
+     181             : };
+     182             : 
+     183             : 
+     184             : inline
+     185             : VesBias* TargetDistribution::getPntrToVesBias() const {
+     186             :   plumed_massert(vesbias_pntr_!=NULL,"the VES bias has not been linked");
+     187             :   return vesbias_pntr_;
+     188             : }
+     189             : 
+     190             : 
+     191             : inline
+     192             : Action* TargetDistribution::getPntrToAction() const {
+     193             :   plumed_massert(action_pntr_!=NULL,"the action has not been linked");
+     194             :   return action_pntr_;
+     195             : }
+     196             : 
+     197             : 
+     198             : inline
+     199          90 : void TargetDistribution::normalizeTargetDistGrid() {
+     200          90 :   double normalization = normalizeGrid(targetdist_grid_pntr_.get());
+     201          90 :   if(normalization<0.0) {plumed_merror(getName()+": something went wrong trying to normalize the target distribution, integrating over it gives a negative value.");}
+     202          90 : }
+     203             : 
+     204             : 
+     205             : 
+     206             : 
+     207             : }
+     208             : }
+     209             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.cpp.func-sort-c.html b/coverage/ves/VesBias.cpp.func-sort-c.html new file mode 100644 index 000000000000..84c2bc555f21 --- /dev/null +++ b/coverage/ves/VesBias.cpp.func-sort-c.html @@ -0,0 +1,253 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32442576.2 %
Date:2024-02-22 21:58:45Functions:274560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7VesBias10setGridMaxERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves7VesBias10setGridMinERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves7VesBias11setGridBinsERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves7VesBias11setGridBinsEj0
_ZN4PLMD3ves7VesBias12addCoeffsSetERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS2_IjSaIjEE0
_ZN4PLMD3ves7VesBias12addCoeffsSetESt10unique_ptrINS0_12CoeffsVectorESt14default_deleteIS3_EE0
_ZN4PLMD3ves7VesBias14disableHessianEv0
_ZN4PLMD3ves7VesBias20updateReweightFactorEv0
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKSt6vectorIdSaIdEEj0
_ZN4PLMD3ves7VesBias21useGridLimitsKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias27setTargetDistAveragesToZeroEj0
_ZN4PLMD3ves7VesBias37useMultipleTargetDistributionKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves7VesBiasD0Ev0
_ZN4PLMD3ves7VesBiasD1Ev0
_ZNK4PLMD3ves7VesBias23calculateReweightFactorEv0
_ZNK4PLMD3ves7VesBias26getCoeffsSetFilenameSuffixB5cxx11Ej0
_ZN4PLMD3ves7VesBias15setupBiasCutoffEdd3
_ZN4PLMD3ves7VesBias13enableHessianEb82
_ZN4PLMD3ves7VesBias13linkOptimizerEPNS0_9OptimizerE85
_ZN4PLMD3ves7VesBias12addCoeffsSetERSt6vectorIPNS_5ValueESaIS4_EERS2_IPNS0_14BasisFunctionsESaIS9_EE90
_ZN4PLMD3ves7VesBias16initializeCoeffsESt10unique_ptrINS0_12CoeffsVectorESt14default_deleteIS3_EE90
_ZN4PLMD3ves7VesBias19readCoeffsFromFilesEv90
_ZN4PLMD3ves7VesBiasC2ERKNS_13ActionOptionsE90
_ZN4PLMD3ves7VesBiasD2Ev90
_ZN4PLMD3ves7VesBias16registerKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias18useGridBinKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias21useBiasCutoffKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias24useInitialCoeffsKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias24useProjectionArgKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias29useTargetDistributionKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias19multiSimSumAveragesEjd120
_ZN4PLMD3ves7VesBias27checkThatTemperatureIsGivenEv175
_ZNK4PLMD3ves7VesBias34getCurrentTargetDistOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE192
_ZNK4PLMD3ves7VesBias24getCurrentOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_383
_ZNK4PLMD3ves7VesBias23getCoeffsSetLabelStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj442
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKNS0_12CoeffsVectorEj453
_ZNK4PLMD3ves7VesBias26getIterationFilenameSuffixB5cxx11Ev552
_ZN4PLMD3ves7VesBias8getOFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb567
_ZNK4PLMD3ves7VesBias18useMultipleWalkersEv567
_ZNK4PLMD3ves7VesBias19getIterationCounterEv1005
_ZNK4PLMD3ves7VesBias30getBiasCutoffSwitchingFunctionEdRd3263
_ZN4PLMD3ves7VesBias24updateGradientAndHessianEb22810
_ZN4PLMD3ves7VesBias20addToSampledAveragesERKSt6vectorIdSaIdEEj23556
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.cpp.func.html b/coverage/ves/VesBias.cpp.func.html new file mode 100644 index 000000000000..9b23aeebe7d9 --- /dev/null +++ b/coverage/ves/VesBias.cpp.func.html @@ -0,0 +1,253 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32442576.2 %
Date:2024-02-22 21:58:45Functions:274560.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7VesBias10setGridMaxERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves7VesBias10setGridMinERKSt6vectorIdSaIdEE0
_ZN4PLMD3ves7VesBias11setGridBinsERKSt6vectorIjSaIjEE0
_ZN4PLMD3ves7VesBias11setGridBinsEj0
_ZN4PLMD3ves7VesBias12addCoeffsSetERKSt6vectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaIS8_EERKS2_IjSaIjEE0
_ZN4PLMD3ves7VesBias12addCoeffsSetERSt6vectorIPNS_5ValueESaIS4_EERS2_IPNS0_14BasisFunctionsESaIS9_EE90
_ZN4PLMD3ves7VesBias12addCoeffsSetESt10unique_ptrINS0_12CoeffsVectorESt14default_deleteIS3_EE0
_ZN4PLMD3ves7VesBias13enableHessianEb82
_ZN4PLMD3ves7VesBias13linkOptimizerEPNS0_9OptimizerE85
_ZN4PLMD3ves7VesBias14disableHessianEv0
_ZN4PLMD3ves7VesBias15setupBiasCutoffEdd3
_ZN4PLMD3ves7VesBias16initializeCoeffsESt10unique_ptrINS0_12CoeffsVectorESt14default_deleteIS3_EE90
_ZN4PLMD3ves7VesBias16registerKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias18useGridBinKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias19multiSimSumAveragesEjd120
_ZN4PLMD3ves7VesBias19readCoeffsFromFilesEv90
_ZN4PLMD3ves7VesBias20addToSampledAveragesERKSt6vectorIdSaIdEEj23556
_ZN4PLMD3ves7VesBias20updateReweightFactorEv0
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKNS0_12CoeffsVectorEj453
_ZN4PLMD3ves7VesBias21setTargetDistAveragesERKSt6vectorIdSaIdEEj0
_ZN4PLMD3ves7VesBias21useBiasCutoffKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias21useGridLimitsKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias24updateGradientAndHessianEb22810
_ZN4PLMD3ves7VesBias24useInitialCoeffsKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias24useProjectionArgKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias25useReweightFactorKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias27checkThatTemperatureIsGivenEv175
_ZN4PLMD3ves7VesBias27setTargetDistAveragesToZeroEj0
_ZN4PLMD3ves7VesBias29useTargetDistributionKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves7VesBias37useMultipleTargetDistributionKeywordsERNS_8KeywordsE0
_ZN4PLMD3ves7VesBias8getOFileERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEbb567
_ZN4PLMD3ves7VesBiasC1ERKNS_13ActionOptionsE0
_ZN4PLMD3ves7VesBiasC2ERKNS_13ActionOptionsE90
_ZN4PLMD3ves7VesBiasD0Ev0
_ZN4PLMD3ves7VesBiasD1Ev0
_ZN4PLMD3ves7VesBiasD2Ev90
_ZNK4PLMD3ves7VesBias18useMultipleWalkersEv567
_ZNK4PLMD3ves7VesBias19getIterationCounterEv1005
_ZNK4PLMD3ves7VesBias23calculateReweightFactorEv0
_ZNK4PLMD3ves7VesBias23getCoeffsSetLabelStringERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj442
_ZNK4PLMD3ves7VesBias24getCurrentOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_383
_ZNK4PLMD3ves7VesBias26getCoeffsSetFilenameSuffixB5cxx11Ej0
_ZNK4PLMD3ves7VesBias26getIterationFilenameSuffixB5cxx11Ev552
_ZNK4PLMD3ves7VesBias30getBiasCutoffSwitchingFunctionEdRd3263
_ZNK4PLMD3ves7VesBias34getCurrentTargetDistOutputFilenameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE192
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.cpp.gcov.html b/coverage/ves/VesBias.cpp.gcov.html new file mode 100644 index 000000000000..ed3c6acfa7e8 --- /dev/null +++ b/coverage/ves/VesBias.cpp.gcov.html @@ -0,0 +1,830 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:32442576.2 %
Date:2024-02-22 21:58:45Functions:274560.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "VesBias.h"
+      24             : #include "BasisFunctions.h"
+      25             : #include "CoeffsVector.h"
+      26             : #include "CoeffsMatrix.h"
+      27             : #include "Optimizer.h"
+      28             : #include "FermiSwitchingFunction.h"
+      29             : #include "VesTools.h"
+      30             : #include "TargetDistribution.h"
+      31             : 
+      32             : #include "tools/Communicator.h"
+      33             : #include "core/ActionSet.h"
+      34             : #include "core/PlumedMain.h"
+      35             : #include "tools/File.h"
+      36             : 
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace ves {
+      40             : 
+      41          90 : VesBias::VesBias(const ActionOptions&ao):
+      42             :   Action(ao),
+      43             :   Bias(ao),
+      44          90 :   ncoeffssets_(0),
+      45          90 :   sampled_averages(0),
+      46          90 :   sampled_cross_averages(0),
+      47          90 :   use_multiple_coeffssets_(false),
+      48          90 :   coeffs_fnames(0),
+      49          90 :   ncoeffs_total_(0),
+      50          90 :   optimizer_pntr_(NULL),
+      51          90 :   optimize_coeffs_(false),
+      52          90 :   compute_hessian_(false),
+      53          90 :   diagonal_hessian_(true),
+      54          90 :   aver_counters(0),
+      55          90 :   kbt_(0.0),
+      56          90 :   targetdist_pntrs_(0),
+      57          90 :   dynamic_targetdist_(false),
+      58          90 :   grid_bins_(0),
+      59          90 :   grid_min_(0),
+      60          90 :   grid_max_(0),
+      61          90 :   bias_filename_(""),
+      62          90 :   fes_filename_(""),
+      63          90 :   targetdist_filename_(""),
+      64          90 :   coeffs_id_prefix_("c-"),
+      65          90 :   bias_file_fmt_("14.9f"),
+      66          90 :   fes_file_fmt_("14.9f"),
+      67          90 :   targetdist_file_fmt_("14.9f"),
+      68          90 :   targetdist_restart_file_fmt_("30.16e"),
+      69          90 :   filenames_have_iteration_number_(false),
+      70          90 :   bias_fileoutput_active_(false),
+      71          90 :   fes_fileoutput_active_(false),
+      72          90 :   fesproj_fileoutput_active_(false),
+      73          90 :   dynamic_targetdist_fileoutput_active_(false),
+      74          90 :   static_targetdist_fileoutput_active_(true),
+      75          90 :   bias_cutoff_active_(false),
+      76          90 :   bias_cutoff_value_(0.0),
+      77          90 :   bias_current_max_value(0.0),
+      78          90 :   calc_reweightfactor_(false),
+      79         270 :   optimization_threshold_(0.0)
+      80             : {
+      81          90 :   log.printf("  VES bias, please read and cite ");
+      82         180 :   log << plumed.cite("Valsson and Parrinello, Phys. Rev. Lett. 113, 090601 (2014)");
+      83          90 :   log.printf("\n");
+      84             : 
+      85          90 :   kbt_=getkBT();
+      86          90 :   if(kbt_>0.0) {
+      87          90 :     log.printf("  KbT: %f\n",kbt_);
+      88             :   }
+      89             :   // NOTE: the check for that the temperature is given is done when linking the optimizer later on.
+      90             : 
+      91         180 :   if(keywords.exists("COEFFS")) {
+      92         180 :     parseVector("COEFFS",coeffs_fnames);
+      93             :   }
+      94             : 
+      95         180 :   if(keywords.exists("GRID_BINS")) {
+      96         180 :     parseMultipleValues<unsigned int>("GRID_BINS",grid_bins_,getNumberOfArguments(),100);
+      97             :   }
+      98             : 
+      99          90 :   if(keywords.exists("GRID_MIN") && keywords.exists("GRID_MAX")) {
+     100           0 :     parseMultipleValues("GRID_MIN",grid_min_,getNumberOfArguments());
+     101           0 :     parseMultipleValues("GRID_MAX",grid_max_,getNumberOfArguments());
+     102             :   }
+     103             : 
+     104             :   std::vector<std::string> targetdist_labels;
+     105         180 :   if(keywords.exists("TARGET_DISTRIBUTION")) {
+     106         180 :     parseVector("TARGET_DISTRIBUTION",targetdist_labels);
+     107          90 :     if(targetdist_labels.size()>1) {
+     108           0 :       plumed_merror(getName()+" with label "+getLabel()+": multiple target distribution labels not allowed");
+     109             :     }
+     110             :   }
+     111           0 :   else if(keywords.exists("TARGET_DISTRIBUTIONS")) {
+     112           0 :     parseVector("TARGET_DISTRIBUTIONS",targetdist_labels);
+     113             :   }
+     114             : 
+     115          90 :   std::string error_msg = "";
+     116         180 :   targetdist_pntrs_ = VesTools::getPointersFromLabels<TargetDistribution*>(targetdist_labels,plumed.getActionSet(),error_msg);
+     117          90 :   if(error_msg.size()>0) {plumed_merror("Problem with target distribution in "+getName()+": "+error_msg);}
+     118             : 
+     119         135 :   for(unsigned int i=0; i<targetdist_pntrs_.size(); i++) {
+     120          45 :     targetdist_pntrs_[i]->linkVesBias(this);
+     121             :   }
+     122             : 
+     123             : 
+     124          90 :   if(getNumberOfArguments()>2) {
+     125             :     disableStaticTargetDistFileOutput();
+     126             :   }
+     127             : 
+     128             : 
+     129         180 :   if(keywords.exists("BIAS_FILE")) {
+     130         180 :     parse("BIAS_FILE",bias_filename_);
+     131          90 :     if(bias_filename_.size()==0) {
+     132         180 :       bias_filename_ = "bias." + getLabel() + ".data";
+     133             :     }
+     134             :   }
+     135         180 :   if(keywords.exists("FES_FILE")) {
+     136         180 :     parse("FES_FILE",fes_filename_);
+     137          90 :     if(fes_filename_.size()==0) {
+     138         180 :       fes_filename_ = "fes." + getLabel() + ".data";
+     139             :     }
+     140             :   }
+     141         180 :   if(keywords.exists("TARGETDIST_FILE")) {
+     142         180 :     parse("TARGETDIST_FILE",targetdist_filename_);
+     143          90 :     if(targetdist_filename_.size()==0) {
+     144         180 :       targetdist_filename_ = "targetdist." + getLabel() + ".data";
+     145             :     }
+     146             :   }
+     147             :   //
+     148         180 :   if(keywords.exists("BIAS_FILE_FMT")) {
+     149           0 :     parse("BIAS_FILE_FMT",bias_file_fmt_);
+     150             :   }
+     151         180 :   if(keywords.exists("FES_FILE_FMT")) {
+     152           0 :     parse("FES_FILE_FMT",fes_file_fmt_);
+     153             :   }
+     154         180 :   if(keywords.exists("TARGETDIST_FILE_FMT")) {
+     155           0 :     parse("TARGETDIST_FILE_FMT",targetdist_file_fmt_);
+     156             :   }
+     157         180 :   if(keywords.exists("TARGETDIST_RESTART_FILE_FMT")) {
+     158           0 :     parse("TARGETDIST_RESTART_FILE_FMT",targetdist_restart_file_fmt_);
+     159             :   }
+     160             : 
+     161             :   //
+     162         180 :   if(keywords.exists("BIAS_CUTOFF")) {
+     163          90 :     double cutoff_value=0.0;
+     164          90 :     parse("BIAS_CUTOFF",cutoff_value);
+     165          90 :     if(cutoff_value<0.0) {
+     166           0 :       plumed_merror("the value given in BIAS_CUTOFF doesn't make sense, it should be larger than 0.0");
+     167             :     }
+     168             :     //
+     169          90 :     if(cutoff_value>0.0) {
+     170           3 :       double fermi_lambda=10.0;
+     171           3 :       parse("BIAS_CUTOFF_FERMI_LAMBDA",fermi_lambda);
+     172           3 :       setupBiasCutoff(cutoff_value,fermi_lambda);
+     173           3 :       log.printf("  Employing a bias cutoff of %f (the lambda value for the Fermi switching function is %f), see and cite ",cutoff_value,fermi_lambda);
+     174           6 :       log << plumed.cite("McCarty, Valsson, Tiwary, and Parrinello, Phys. Rev. Lett. 115, 070601 (2015)");
+     175           3 :       log.printf("\n");
+     176             :     }
+     177             :   }
+     178             : 
+     179             : 
+     180         180 :   if(keywords.exists("PROJ_ARG")) {
+     181             :     std::vector<std::string> proj_arg;
+     182          90 :     for(int i=1;; i++) {
+     183         212 :       if(!parseNumberedVector("PROJ_ARG",i,proj_arg)) {break;}
+     184             :       // checks
+     185          16 :       if(proj_arg.size() > (getNumberOfArguments()-1) ) {
+     186           0 :         plumed_merror("PROJ_ARG must be a subset of ARG");
+     187             :       }
+     188             :       //
+     189          32 :       for(unsigned int k=0; k<proj_arg.size(); k++) {
+     190             :         bool found = false;
+     191          24 :         for(unsigned int l=0; l<getNumberOfArguments(); l++) {
+     192          24 :           if(proj_arg[k]==getPntrToArgument(l)->getName()) {
+     193             :             found = true;
+     194             :             break;
+     195             :           }
+     196             :         }
+     197          16 :         if(!found) {
+     198           0 :           std::string s1; Tools::convert(i,s1);
+     199           0 :           std::string error = "PROJ_ARG" + s1 + ": label " + proj_arg[k] + " is not among the arguments given in ARG";
+     200           0 :           plumed_merror(error);
+     201             :         }
+     202             :       }
+     203             :       //
+     204          16 :       projection_args_.push_back(proj_arg);
+     205          16 :     }
+     206          90 :   }
+     207             : 
+     208         180 :   if(keywords.exists("CALC_REWEIGHT_FACTOR")) {
+     209           0 :     parseFlag("CALC_REWEIGHT_FACTOR",calc_reweightfactor_);
+     210           0 :     if(calc_reweightfactor_) {
+     211           0 :       addComponent("rct"); componentIsNotPeriodic("rct");
+     212           0 :       updateReweightFactor();
+     213             :     }
+     214             :   }
+     215             : 
+     216         180 :   if(keywords.exists("OPTIMIZATION_THRESHOLD")) {
+     217          90 :     parse("OPTIMIZATION_THRESHOLD",optimization_threshold_);
+     218          90 :     if(optimization_threshold_ < 0.0) {
+     219           0 :       plumed_merror("OPTIMIZATION_THRESHOLD should be a postive value");
+     220             :     }
+     221          90 :     if(optimization_threshold_!=0.0) {
+     222           1 :       log.printf("  Employing a threshold value of %e for optimization of localized basis functions.\n",optimization_threshold_);
+     223             :     }
+     224             :   }
+     225             : 
+     226          90 : }
+     227             : 
+     228             : 
+     229          90 : VesBias::~VesBias() {
+     230         180 : }
+     231             : 
+     232             : 
+     233          92 : void VesBias::registerKeywords( Keywords& keys ) {
+     234          92 :   Bias::registerKeywords(keys);
+     235         184 :   keys.add("optional","TEMP","the system temperature - this is needed if the MD code does not pass the temperature to PLUMED.");
+     236             :   //
+     237         184 :   keys.reserve("optional","COEFFS","read in the coefficients from files.");
+     238             :   //
+     239         184 :   keys.reserve("optional","TARGET_DISTRIBUTION","the label of the target distribution to be used.");
+     240         184 :   keys.reserve("optional","TARGET_DISTRIBUTIONS","the label of the target distribution to be used. Here you are allows to use multiple labels.");
+     241             :   //
+     242         184 :   keys.reserve("optional","GRID_BINS","the number of bins used for the grid. The default value is 100 bins per dimension.");
+     243         184 :   keys.reserve("optional","GRID_MIN","the lower bounds used for the grid.");
+     244         184 :   keys.reserve("optional","GRID_MAX","the upper bounds used for the grid.");
+     245             :   //
+     246         184 :   keys.add("optional","BIAS_FILE","filename of the file on which the bias should be written out. By default it is bias.LABEL.data. Note that suffixes indicating the iteration number (iter-#) are added to the filename when optimizing coefficients.");
+     247         184 :   keys.add("optional","FES_FILE","filename of the file on which the FES should be written out. By default it is fes.LABEL.data. Note that suffixes indicating the iteration number (iter-#) are added to the filename when optimizing coefficients.");
+     248         184 :   keys.add("optional","TARGETDIST_FILE","filename of the file on which the target distribution should be written out. By default it is targetdist.LABEL.data. Note that suffixes indicating the iteration number (iter-#) are added to the filename when optimizing coefficients and the target distribution is dynamic.");
+     249             :   //
+     250             :   // keys.add("optional","BIAS_FILE_FMT","the format of the bias files, by default it is %14.9f.");
+     251             :   // keys.add("optional","FES_FILE_FMT","the format of the FES files, by default it is %14.9f.");
+     252             :   // keys.add("optional","TARGETDIST_FILE_FMT","the format of the target distribution files, by default it is %14.9f.");
+     253             :   // keys.add("hidden","TARGETDIST_RESTART_FILE_FMT","the format of the target distribution files that are used for restarting, by default it is %30.16e.");
+     254             :   //
+     255         184 :   keys.reserve("optional","BIAS_CUTOFF","cutoff the bias such that it only fills the free energy surface up to certain level F_cutoff, here you should give the value of the F_cutoff.");
+     256         184 :   keys.reserve("optional","BIAS_CUTOFF_FERMI_LAMBDA","the lambda value used in the Fermi switching function for the bias cutoff (BIAS_CUTOFF), the default value is 10.0.");
+     257             :   //
+     258         184 :   keys.reserve("numbered","PROJ_ARG","arguments for doing projections of the FES or the target distribution.");
+     259             :   //
+     260         184 :   keys.reserveFlag("CALC_REWEIGHT_FACTOR",false,"enable the calculation of the reweight factor c(t). You should also give a stride for updating the reweight factor in the optimizer by using the REWEIGHT_FACTOR_STRIDE keyword if the coefficients are updated.");
+     261         184 :   keys.add("optional","OPTIMIZATION_THRESHOLD","Threshold value to turn off optimization of localized basis functions.");
+     262             : 
+     263          92 : }
+     264             : 
+     265             : 
+     266          92 : void VesBias::useInitialCoeffsKeywords(Keywords& keys) {
+     267          92 :   keys.use("COEFFS");
+     268          92 : }
+     269             : 
+     270             : 
+     271          92 : void VesBias::useTargetDistributionKeywords(Keywords& keys) {
+     272         184 :   plumed_massert(!keys.exists("TARGET_DISTRIBUTIONS"),"you cannot use both useTargetDistributionKeywords and useMultipleTargetDistributionKeywords");
+     273          92 :   keys.use("TARGET_DISTRIBUTION");
+     274          92 : }
+     275             : 
+     276             : 
+     277           0 : void VesBias::useMultipleTargetDistributionKeywords(Keywords& keys) {
+     278           0 :   plumed_massert(!keys.exists("TARGET_DISTRIBUTION"),"you cannot use both useTargetDistributionKeywords and useMultipleTargetDistributionKeywords");
+     279           0 :   keys.use("TARGET_DISTRIBUTIONS");
+     280           0 : }
+     281             : 
+     282             : 
+     283          92 : void VesBias::useGridBinKeywords(Keywords& keys) {
+     284          92 :   keys.use("GRID_BINS");
+     285          92 : }
+     286             : 
+     287             : 
+     288           0 : void VesBias::useGridLimitsKeywords(Keywords& keys) {
+     289           0 :   keys.use("GRID_MIN");
+     290           0 :   keys.use("GRID_MAX");
+     291           0 : }
+     292             : 
+     293             : 
+     294          92 : void VesBias::useBiasCutoffKeywords(Keywords& keys) {
+     295          92 :   keys.use("BIAS_CUTOFF");
+     296          92 :   keys.use("BIAS_CUTOFF_FERMI_LAMBDA");
+     297          92 : }
+     298             : 
+     299             : 
+     300          92 : void VesBias::useProjectionArgKeywords(Keywords& keys) {
+     301          92 :   keys.use("PROJ_ARG");
+     302          92 : }
+     303             : 
+     304             : 
+     305           0 : void VesBias::useReweightFactorKeywords(Keywords& keys) {
+     306           0 :   keys.use("CALC_REWEIGHT_FACTOR");
+     307           0 :   keys.addOutputComponent("rct","CALC_REWEIGHT_FACTOR","the reweight factor c(t).");
+     308           0 : }
+     309             : 
+     310             : 
+     311           0 : void VesBias::addCoeffsSet(const std::vector<std::string>& dimension_labels,const std::vector<unsigned int>& indices_shape) {
+     312           0 :   auto coeffs_pntr_tmp = Tools::make_unique<CoeffsVector>("coeffs",dimension_labels,indices_shape,comm,true);
+     313           0 :   initializeCoeffs(std::move(coeffs_pntr_tmp));
+     314           0 : }
+     315             : 
+     316             : 
+     317          90 : void VesBias::addCoeffsSet(std::vector<Value*>& args,std::vector<BasisFunctions*>& basisf) {
+     318          90 :   auto coeffs_pntr_tmp = Tools::make_unique<CoeffsVector>("coeffs",args,basisf,comm,true);
+     319          90 :   initializeCoeffs(std::move(coeffs_pntr_tmp));
+     320          90 : }
+     321             : 
+     322             : 
+     323           0 : void VesBias::addCoeffsSet(std::unique_ptr<CoeffsVector> coeffs_pntr_in) {
+     324           0 :   initializeCoeffs(std::move(coeffs_pntr_in));
+     325           0 : }
+     326             : 
+     327             : 
+     328          90 : void VesBias::initializeCoeffs(std::unique_ptr<CoeffsVector> coeffs_pntr_in) {
+     329             :   //
+     330          90 :   coeffs_pntr_in->linkVesBias(this);
+     331             :   //
+     332             :   std::string label;
+     333          90 :   if(!use_multiple_coeffssets_ && ncoeffssets_==1) {
+     334           0 :     plumed_merror("you are not allowed to use multiple coefficient sets");
+     335             :   }
+     336             :   //
+     337         180 :   label = getCoeffsSetLabelString("coeffs",ncoeffssets_);
+     338          90 :   coeffs_pntr_in->setLabels(label);
+     339             : 
+     340          90 :   coeffs_pntrs_.emplace_back(std::move(coeffs_pntr_in));
+     341             :   auto aver_ps_tmp = Tools::make_unique<CoeffsVector>(*coeffs_pntrs_.back());
+     342         180 :   label = getCoeffsSetLabelString("targetdist_averages",ncoeffssets_);
+     343          90 :   aver_ps_tmp->setLabels(label);
+     344          90 :   aver_ps_tmp->setValues(0.0);
+     345          90 :   targetdist_averages_pntrs_.emplace_back(std::move(aver_ps_tmp));
+     346             :   //
+     347             :   auto gradient_tmp = Tools::make_unique<CoeffsVector>(*coeffs_pntrs_.back());
+     348         180 :   label = getCoeffsSetLabelString("gradient",ncoeffssets_);
+     349          90 :   gradient_tmp->setLabels(label);
+     350          90 :   gradient_pntrs_.emplace_back(std::move(gradient_tmp));
+     351             :   //
+     352         180 :   label = getCoeffsSetLabelString("hessian",ncoeffssets_);
+     353          90 :   auto hessian_tmp = Tools::make_unique<CoeffsMatrix>(label,coeffs_pntrs_.back().get(),comm,diagonal_hessian_);
+     354             : 
+     355          90 :   hessian_pntrs_.emplace_back(std::move(hessian_tmp));
+     356             :   //
+     357             :   std::vector<double> aver_sampled_tmp;
+     358          90 :   aver_sampled_tmp.assign(coeffs_pntrs_.back()->numberOfCoeffs(),0.0);
+     359          90 :   sampled_averages.push_back(aver_sampled_tmp);
+     360             :   //
+     361             :   std::vector<double> cross_aver_sampled_tmp;
+     362          90 :   cross_aver_sampled_tmp.assign(hessian_pntrs_.back()->getSize(),0.0);
+     363          90 :   sampled_cross_averages.push_back(cross_aver_sampled_tmp);
+     364             :   //
+     365          90 :   aver_counters.push_back(0);
+     366             :   //
+     367          90 :   ncoeffssets_++;
+     368         180 : }
+     369             : 
+     370             : 
+     371          90 : bool VesBias::readCoeffsFromFiles() {
+     372          90 :   plumed_assert(ncoeffssets_>0);
+     373         180 :   plumed_massert(keywords.exists("COEFFS"),"you are not allowed to use this function as the COEFFS keyword is not enabled");
+     374             :   bool read_coeffs = false;
+     375          90 :   if(coeffs_fnames.size()>0) {
+     376           4 :     plumed_massert(coeffs_fnames.size()==ncoeffssets_,"COEFFS keyword is of the wrong size");
+     377           4 :     if(ncoeffssets_==1) {
+     378           4 :       log.printf("  Read in coefficients from file ");
+     379             :     }
+     380             :     else {
+     381           0 :       log.printf("  Read in coefficients from files:\n");
+     382             :     }
+     383           8 :     for(unsigned int i=0; i<ncoeffssets_; i++) {
+     384           4 :       IFile ifile;
+     385           4 :       ifile.link(*this);
+     386           4 :       ifile.open(coeffs_fnames[i]);
+     387           8 :       if(!ifile.FieldExist(coeffs_pntrs_[i]->getDataLabel())) {
+     388           0 :         std::string error_msg = "Problem with reading coefficients from file " + ifile.getPath() + ": no field with name " + coeffs_pntrs_[i]->getDataLabel() + "\n";
+     389           0 :         plumed_merror(error_msg);
+     390             :       }
+     391           4 :       size_t ncoeffs_read = coeffs_pntrs_[i]->readFromFile(ifile,false,false);
+     392           4 :       coeffs_pntrs_[i]->setIterationCounterAndTime(0,getTime());
+     393           4 :       if(ncoeffssets_==1) {
+     394           8 :         log.printf("%s (read %zu of %zu values)\n", ifile.getPath().c_str(),ncoeffs_read,coeffs_pntrs_[i]->numberOfCoeffs());
+     395             :       }
+     396             :       else {
+     397           0 :         log.printf("   coefficient %u: %s (read %zu of %zu values)\n",i,ifile.getPath().c_str(),ncoeffs_read,coeffs_pntrs_[i]->numberOfCoeffs());
+     398             :       }
+     399           4 :       ifile.close();
+     400           4 :     }
+     401             :     read_coeffs = true;
+     402             :   }
+     403          90 :   return read_coeffs;
+     404             : }
+     405             : 
+     406             : 
+     407       22810 : void VesBias::updateGradientAndHessian(const bool use_mwalkers_mpi) {
+     408       45620 :   for(unsigned int k=0; k<ncoeffssets_; k++) {
+     409             :     //
+     410       22810 :     comm.Sum(sampled_averages[k]);
+     411       22810 :     comm.Sum(sampled_cross_averages[k]);
+     412       22810 :     if(use_mwalkers_mpi) {
+     413             :       double walker_weight=1.0;
+     414         120 :       if(aver_counters[k]==0) {walker_weight=0.0;}
+     415         120 :       multiSimSumAverages(k,walker_weight);
+     416             :     }
+     417             :     // NOTE: this assumes that all walkers have the same TargetDist, might change later on!!
+     418       22810 :     Gradient(k).setValues( TargetDistAverages(k) - sampled_averages[k] );
+     419       22810 :     Hessian(k) = computeCovarianceFromAverages(k);
+     420       22810 :     Hessian(k) *= getBeta();
+     421             : 
+     422       22810 :     if(optimization_threshold_ != 0.0) {
+     423         390 :       for(size_t c_id=0; c_id < sampled_averages[k].size(); ++c_id) {
+     424         380 :         if(fabs(sampled_averages[k][c_id]) < optimization_threshold_) {
+     425         219 :           Gradient(k).setValue(c_id, 0.0);
+     426         219 :           Hessian(k).setValue(c_id, c_id, 0.0);
+     427             :         }
+     428             :       }
+     429             :     }
+     430             :     //
+     431             :     Gradient(k).activate();
+     432             :     Hessian(k).activate();
+     433             :     //
+     434             :     // Check the total number of samples (from all walkers) and deactivate the Gradient and Hessian if it
+     435             :     // is zero
+     436       22810 :     unsigned int total_samples = aver_counters[k];
+     437       22810 :     if(use_mwalkers_mpi) {
+     438         120 :       if(comm.Get_rank()==0) {multi_sim_comm.Sum(total_samples);}
+     439         120 :       comm.Bcast(total_samples,0);
+     440             :     }
+     441       22810 :     if(total_samples==0) {
+     442             :       Gradient(k).deactivate();
+     443          95 :       Gradient(k).clear();
+     444             :       Hessian(k).deactivate();
+     445          95 :       Hessian(k).clear();
+     446             :     }
+     447             :     //
+     448             :     std::fill(sampled_averages[k].begin(), sampled_averages[k].end(), 0.0);
+     449             :     std::fill(sampled_cross_averages[k].begin(), sampled_cross_averages[k].end(), 0.0);
+     450       22810 :     aver_counters[k]=0;
+     451             :   }
+     452       22810 : }
+     453             : 
+     454             : 
+     455         120 : void VesBias::multiSimSumAverages(const unsigned int c_id, const double walker_weight) {
+     456         120 :   plumed_massert(walker_weight>=0.0,"the weight of the walker cannot be negative!");
+     457         120 :   if(walker_weight!=1.0) {
+     458        7860 :     for(size_t i=0; i<sampled_averages[c_id].size(); i++) {
+     459        7800 :       sampled_averages[c_id][i] *= walker_weight;
+     460             :     }
+     461        7860 :     for(size_t i=0; i<sampled_cross_averages[c_id].size(); i++) {
+     462        7800 :       sampled_cross_averages[c_id][i] *= walker_weight;
+     463             :     }
+     464             :   }
+     465             :   //
+     466         120 :   if(comm.Get_rank()==0) {
+     467         120 :     multi_sim_comm.Sum(sampled_averages[c_id]);
+     468         120 :     multi_sim_comm.Sum(sampled_cross_averages[c_id]);
+     469         120 :     double norm_weights = walker_weight;
+     470         120 :     multi_sim_comm.Sum(norm_weights);
+     471         120 :     if(norm_weights>0.0) {norm_weights=1.0/norm_weights;}
+     472        8580 :     for(size_t i=0; i<sampled_averages[c_id].size(); i++) {
+     473        8460 :       sampled_averages[c_id][i] *= norm_weights;
+     474             :     }
+     475        8580 :     for(size_t i=0; i<sampled_cross_averages[c_id].size(); i++) {
+     476        8460 :       sampled_cross_averages[c_id][i] *= norm_weights;
+     477             :     }
+     478             :   }
+     479         120 :   comm.Bcast(sampled_averages[c_id],0);
+     480         120 :   comm.Bcast(sampled_cross_averages[c_id],0);
+     481         120 : }
+     482             : 
+     483             : 
+     484       23556 : void VesBias::addToSampledAverages(const std::vector<double>& values, const unsigned int c_id) {
+     485             :   /*
+     486             :   use the following online equation to calculate the average and covariance
+     487             :   (see https://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#Covariance)
+     488             :       xm[n+1] = xm[n] + (x[n+1]-xm[n])/(n+1)
+     489             :   */
+     490       23556 :   double counter_dbl = static_cast<double>(aver_counters[c_id]);
+     491             :   size_t ncoeffs = numberOfCoeffs(c_id);
+     492       23556 :   std::vector<double> deltas(ncoeffs,0.0);
+     493       23556 :   size_t stride = comm.Get_size();
+     494       23556 :   size_t rank = comm.Get_rank();
+     495             :   // update average and diagonal part of Hessian
+     496     1830228 :   for(size_t i=rank; i<ncoeffs; i+=stride) {
+     497             :     size_t midx = getHessianIndex(i,i,c_id);
+     498     1806672 :     deltas[i] = (values[i]-sampled_averages[c_id][i])/(counter_dbl+1); // (x[n+1]-xm[n])/(n+1)
+     499     1806672 :     sampled_averages[c_id][i] += deltas[i];
+     500     1806672 :     sampled_cross_averages[c_id][midx] += (values[i]*values[i]-sampled_cross_averages[c_id][midx])/(counter_dbl+1);
+     501             :   }
+     502       23556 :   comm.Sum(deltas);
+     503             :   // update off-diagonal part of the Hessian
+     504       23556 :   if(!diagonal_hessian_) {
+     505           0 :     for(size_t i=rank; i<ncoeffs; i+=stride) {
+     506           0 :       for(size_t j=(i+1); j<ncoeffs; j++) {
+     507             :         size_t midx = getHessianIndex(i,j,c_id);
+     508           0 :         sampled_cross_averages[c_id][midx] += (values[i]*values[j]-sampled_cross_averages[c_id][midx])/(counter_dbl+1);
+     509             :       }
+     510             :     }
+     511             :   }
+     512             :   // NOTE: the MPI sum for sampled_averages and sampled_cross_averages is done later
+     513       23556 :   aver_counters[c_id] += 1;
+     514       23556 : }
+     515             : 
+     516             : 
+     517           0 : void VesBias::setTargetDistAverages(const std::vector<double>& coeffderivs_aver_ps, const unsigned int coeffs_id) {
+     518           0 :   TargetDistAverages(coeffs_id) = coeffderivs_aver_ps;
+     519           0 :   TargetDistAverages(coeffs_id).setIterationCounterAndTime(this->getIterationCounter(),this->getTime());
+     520           0 : }
+     521             : 
+     522             : 
+     523         453 : void VesBias::setTargetDistAverages(const CoeffsVector& coeffderivs_aver_ps, const unsigned int coeffs_id) {
+     524         453 :   TargetDistAverages(coeffs_id).setValues( coeffderivs_aver_ps );
+     525         453 :   TargetDistAverages(coeffs_id).setIterationCounterAndTime(this->getIterationCounter(),this->getTime());
+     526         453 : }
+     527             : 
+     528             : 
+     529           0 : void VesBias::setTargetDistAveragesToZero(const unsigned int coeffs_id) {
+     530           0 :   TargetDistAverages(coeffs_id).setAllValuesToZero();
+     531           0 :   TargetDistAverages(coeffs_id).setIterationCounterAndTime(this->getIterationCounter(),this->getTime());
+     532           0 : }
+     533             : 
+     534             : 
+     535         175 : void VesBias::checkThatTemperatureIsGiven() {
+     536         175 :   if(kbt_==0.0) {
+     537           0 :     std::string err_msg = "VES bias " + getLabel() + " of type " + getName() + ": the temperature is needed so you need to give it using the TEMP keyword as the MD engine does not pass it to PLUMED.";
+     538           0 :     plumed_merror(err_msg);
+     539             :   }
+     540         175 : }
+     541             : 
+     542             : 
+     543        1005 : unsigned int VesBias::getIterationCounter() const {
+     544             :   unsigned int iteration = 0;
+     545        1005 :   if(optimizeCoeffs()) {
+     546             :     iteration = getOptimizerPntr()->getIterationCounter();
+     547             :   }
+     548             :   else {
+     549         113 :     iteration = getCoeffsPntrs()[0]->getIterationCounter();
+     550             :   }
+     551        1005 :   return iteration;
+     552             : }
+     553             : 
+     554             : 
+     555          85 : void VesBias::linkOptimizer(Optimizer* optimizer_pntr_in) {
+     556             :   //
+     557          85 :   if(optimizer_pntr_==NULL) {
+     558          85 :     optimizer_pntr_ = optimizer_pntr_in;
+     559             :   }
+     560             :   else {
+     561           0 :     std::string err_msg = "VES bias " + getLabel() + " of type " + getName() + " has already been linked with optimizer " + optimizer_pntr_->getLabel() + " of type " + optimizer_pntr_->getName() + ". You cannot link two optimizer to the same VES bias.";
+     562           0 :     plumed_merror(err_msg);
+     563             :   }
+     564          85 :   checkThatTemperatureIsGiven();
+     565          85 :   optimize_coeffs_ = true;
+     566          85 :   filenames_have_iteration_number_ = true;
+     567          85 : }
+     568             : 
+     569             : 
+     570          82 : void VesBias::enableHessian(const bool diagonal_hessian) {
+     571          82 :   compute_hessian_=true;
+     572          82 :   diagonal_hessian_=diagonal_hessian;
+     573          82 :   sampled_cross_averages.clear();
+     574         164 :   for (unsigned int i=0; i<ncoeffssets_; i++) {
+     575          82 :     std::string label = getCoeffsSetLabelString("hessian",i);
+     576         164 :     hessian_pntrs_[i] = Tools::make_unique<CoeffsMatrix>(label,coeffs_pntrs_[i].get(),comm,diagonal_hessian_);
+     577             :     //
+     578             :     std::vector<double> cross_aver_sampled_tmp;
+     579          82 :     cross_aver_sampled_tmp.assign(hessian_pntrs_[i]->getSize(),0.0);
+     580          82 :     sampled_cross_averages.push_back(cross_aver_sampled_tmp);
+     581             :   }
+     582          82 : }
+     583             : 
+     584             : 
+     585           0 : void VesBias::disableHessian() {
+     586           0 :   compute_hessian_=false;
+     587           0 :   diagonal_hessian_=true;
+     588           0 :   sampled_cross_averages.clear();
+     589           0 :   for (unsigned int i=0; i<ncoeffssets_; i++) {
+     590           0 :     std::string label = getCoeffsSetLabelString("hessian",i);
+     591           0 :     hessian_pntrs_[i] = Tools::make_unique<CoeffsMatrix>(label,coeffs_pntrs_[i].get(),comm,diagonal_hessian_);
+     592             :     //
+     593             :     std::vector<double> cross_aver_sampled_tmp;
+     594           0 :     cross_aver_sampled_tmp.assign(hessian_pntrs_[i]->getSize(),0.0);
+     595           0 :     sampled_cross_averages.push_back(cross_aver_sampled_tmp);
+     596             :   }
+     597           0 : }
+     598             : 
+     599             : 
+     600         442 : std::string VesBias::getCoeffsSetLabelString(const std::string& type, const unsigned int coeffs_id) const {
+     601         442 :   std::string label_prefix = getLabel() + ".";
+     602         442 :   std::string label_postfix = "";
+     603         442 :   if(use_multiple_coeffssets_) {
+     604           0 :     Tools::convert(coeffs_id,label_postfix);
+     605           0 :     label_postfix = "-" + label_postfix;
+     606             :   }
+     607        1326 :   return label_prefix+type+label_postfix;
+     608             : }
+     609             : 
+     610             : 
+     611         567 : std::unique_ptr<OFile> VesBias::getOFile(const std::string& filepath, const bool multi_sim_single_file, const bool enforce_backup) {
+     612             :   auto ofile_pntr = Tools::make_unique<OFile>();
+     613         567 :   std::string fp = filepath;
+     614         567 :   ofile_pntr->link(*static_cast<Action*>(this));
+     615         567 :   if(enforce_backup) {ofile_pntr->enforceBackup();}
+     616         567 :   if(multi_sim_single_file) {
+     617          56 :     unsigned int r=0;
+     618          56 :     if(comm.Get_rank()==0) {r=multi_sim_comm.Get_rank();}
+     619          56 :     comm.Bcast(r,0);
+     620          56 :     if(r>0) {fp="/dev/null";}
+     621         112 :     ofile_pntr->enforceSuffix("");
+     622             :   }
+     623         567 :   ofile_pntr->open(fp);
+     624         567 :   return ofile_pntr;
+     625           0 : }
+     626             : 
+     627             : 
+     628           0 : void VesBias::setGridBins(const std::vector<unsigned int>& grid_bins_in) {
+     629           0 :   plumed_massert(grid_bins_in.size()==getNumberOfArguments(),"the number of grid bins given doesn't match the number of arguments");
+     630           0 :   grid_bins_=grid_bins_in;
+     631           0 : }
+     632             : 
+     633             : 
+     634           0 : void VesBias::setGridBins(const unsigned int nbins) {
+     635           0 :   std::vector<unsigned int> grid_bins_in(getNumberOfArguments(),nbins);
+     636           0 :   grid_bins_=grid_bins_in;
+     637           0 : }
+     638             : 
+     639             : 
+     640           0 : void VesBias::setGridMin(const std::vector<double>& grid_min_in) {
+     641           0 :   plumed_massert(grid_min_in.size()==getNumberOfArguments(),"the number of lower bounds given for the grid doesn't match the number of arguments");
+     642           0 :   grid_min_=grid_min_in;
+     643           0 : }
+     644             : 
+     645             : 
+     646           0 : void VesBias::setGridMax(const std::vector<double>& grid_max_in) {
+     647           0 :   plumed_massert(grid_max_in.size()==getNumberOfArguments(),"the number of upper bounds given for the grid doesn't match the number of arguments");
+     648           0 :   grid_max_=grid_max_in;
+     649           0 : }
+     650             : 
+     651             : 
+     652         383 : std::string VesBias::getCurrentOutputFilename(const std::string& base_filename, const std::string& suffix) const {
+     653         383 :   std::string filename = base_filename;
+     654         383 :   if(suffix.size()>0) {
+     655          82 :     filename = FileBase::appendSuffix(filename,"."+suffix);
+     656             :   }
+     657         383 :   if(filenamesIncludeIterationNumber()) {
+     658         756 :     filename = FileBase::appendSuffix(filename,"."+getIterationFilenameSuffix());
+     659             :   }
+     660         383 :   return filename;
+     661             : }
+     662             : 
+     663             : 
+     664         192 : std::string VesBias::getCurrentTargetDistOutputFilename(const std::string& suffix) const {
+     665         192 :   std::string filename = targetdist_filename_;
+     666         192 :   if(suffix.size()>0) {
+     667         204 :     filename = FileBase::appendSuffix(filename,"."+suffix);
+     668             :   }
+     669         192 :   if(filenamesIncludeIterationNumber() && dynamicTargetDistribution()) {
+     670         348 :     filename = FileBase::appendSuffix(filename,"."+getIterationFilenameSuffix());
+     671             :   }
+     672         192 :   return filename;
+     673             : }
+     674             : 
+     675             : 
+     676         552 : std::string VesBias::getIterationFilenameSuffix() const {
+     677             :   std::string iter_str;
+     678         552 :   Tools::convert(getIterationCounter(),iter_str);
+     679         552 :   iter_str = "iter-" + iter_str;
+     680         552 :   return iter_str;
+     681             : }
+     682             : 
+     683             : 
+     684           0 : std::string VesBias::getCoeffsSetFilenameSuffix(const unsigned int coeffs_id) const {
+     685           0 :   std::string suffix = "";
+     686           0 :   if(use_multiple_coeffssets_) {
+     687           0 :     Tools::convert(coeffs_id,suffix);
+     688           0 :     suffix = coeffs_id_prefix_ + suffix;
+     689             :   }
+     690           0 :   return suffix;
+     691             : }
+     692             : 
+     693             : 
+     694           3 : void VesBias::setupBiasCutoff(const double bias_cutoff_value, const double fermi_lambda) {
+     695             :   //
+     696             :   double fermi_exp_max = 100.0;
+     697             :   //
+     698             :   std::string str_bias_cutoff_value; VesTools::convertDbl2Str(bias_cutoff_value,str_bias_cutoff_value);
+     699             :   std::string str_fermi_lambda; VesTools::convertDbl2Str(fermi_lambda,str_fermi_lambda);
+     700             :   std::string str_fermi_exp_max; VesTools::convertDbl2Str(fermi_exp_max,str_fermi_exp_max);
+     701           6 :   std::string swfunc_keywords = "FERMI R_0=" + str_bias_cutoff_value + " FERMI_LAMBDA=" + str_fermi_lambda + " FERMI_EXP_MAX=" + str_fermi_exp_max;
+     702             :   //
+     703           3 :   std::string swfunc_errors="";
+     704           3 :   bias_cutoff_swfunc_pntr_ = Tools::make_unique<FermiSwitchingFunction>();
+     705           3 :   bias_cutoff_swfunc_pntr_->set(swfunc_keywords,swfunc_errors);
+     706           3 :   if(swfunc_errors.size()>0) {
+     707           0 :     plumed_merror("problem with setting up Fermi switching function: " + swfunc_errors);
+     708             :   }
+     709             :   //
+     710           3 :   bias_cutoff_value_=bias_cutoff_value;
+     711           3 :   bias_cutoff_active_=true;
+     712             :   enableDynamicTargetDistribution();
+     713           3 : }
+     714             : 
+     715             : 
+     716        3263 : double VesBias::getBiasCutoffSwitchingFunction(const double bias, double& deriv_factor) const {
+     717        3263 :   plumed_massert(bias_cutoff_active_,"The bias cutoff is not active so you cannot call this function");
+     718        3263 :   double arg = -(bias-bias_current_max_value);
+     719        3263 :   double deriv=0.0;
+     720        3263 :   double value = bias_cutoff_swfunc_pntr_->calculate(arg,deriv);
+     721             :   // as FermiSwitchingFunction class has different behavior from normal SwitchingFunction class
+     722             :   // I was having problems with NaN as it was dividing with zero
+     723             :   // deriv *= arg;
+     724        3263 :   deriv_factor = value-bias*deriv;
+     725        3263 :   return value;
+     726             : }
+     727             : 
+     728             : 
+     729         567 : bool VesBias::useMultipleWalkers() const {
+     730             :   bool use_mwalkers_mpi=false;
+     731         567 :   if(optimizeCoeffs() && getOptimizerPntr()->useMultipleWalkers()) {
+     732             :     use_mwalkers_mpi=true;
+     733             :   }
+     734         567 :   return use_mwalkers_mpi;
+     735             : }
+     736             : 
+     737             : 
+     738           0 : void VesBias::updateReweightFactor() {
+     739           0 :   if(calc_reweightfactor_) {
+     740           0 :     double value = calculateReweightFactor();
+     741           0 :     getPntrToComponent("rct")->set(value);
+     742             :   }
+     743           0 : }
+     744             : 
+     745             : 
+     746           0 : double VesBias::calculateReweightFactor() const {
+     747           0 :   plumed_merror(getName()+" with label "+getLabel()+": calculation of the reweight factor c(t) has not been implemented for this type of VES bias");
+     748             :   return 0.0;
+     749             : }
+     750             : 
+     751             : 
+     752             : }
+     753             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.h.func-sort-c.html b/coverage/ves/VesBias.h.func-sort-c.html new file mode 100644 index 000000000000..2752c9ce2077 --- /dev/null +++ b/coverage/ves/VesBias.h.func-sort-c.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:668974.2 %
Date:2024-02-22 21:58:45Functions:92536.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7VesBias14writeFesToFileEv0
_ZN4PLMD3ves7VesBias15writeBiasToFileEv0
_ZN4PLMD3ves7VesBias18resetFesFileOutputEv0
_ZN4PLMD3ves7VesBias18setupFesFileOutputEv0
_ZN4PLMD3ves7VesBias18writeFesProjToFileEv0
_ZN4PLMD3ves7VesBias19parseMultipleValuesIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEj0
_ZN4PLMD3ves7VesBias19resetBiasFileOutputEv0
_ZN4PLMD3ves7VesBias19setupBiasFileOutputEv0
_ZN4PLMD3ves7VesBias21writeTargetDistToFileEv0
_ZN4PLMD3ves7VesBias22resetFesProjFileOutputEv0
_ZN4PLMD3ves7VesBias22setupFesProjFileOutputEv0
_ZN4PLMD3ves7VesBias25resetTargetDistFileOutputEv0
_ZN4PLMD3ves7VesBias25updateTargetDistributionsEv0
_ZN4PLMD3ves7VesBias25writeTargetDistProjToFileEv0
_ZN4PLMD3ves7VesBias26restartTargetDistributionsEv0
_ZN4PLMD3ves7VesBias29resetTargetDistProjFileOutputEv0
_ZN4PLMD3ves7VesBias29setupTargetDistProjFileOutputEv9
_ZN4PLMD3ves7VesBias25setupTargetDistFileOutputEv44
_ZN4PLMD3ves7VesBias19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EEj90
_ZN4PLMD3ves7VesBias19parseMultipleValuesIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEj90
_ZN4PLMD3ves7VesBias19parseMultipleValuesIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEjRKSC_90
_ZNK4PLMD3ves7VesBias15applyBiasCutoffERdRSt6vectorIdSaIdEE600
_ZNK4PLMD3ves7VesBias15applyBiasCutoffERdRSt6vectorIdSaIdEES6_663
_ZNK4PLMD3ves7VesBias29computeCovarianceFromAveragesEj22810
_ZNK4PLMD3ves7VesBias7getBetaEv23277
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.h.func.html b/coverage/ves/VesBias.h.func.html new file mode 100644 index 000000000000..ca711d024b25 --- /dev/null +++ b/coverage/ves/VesBias.h.func.html @@ -0,0 +1,173 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:668974.2 %
Date:2024-02-22 21:58:45Functions:92536.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves7VesBias14writeFesToFileEv0
_ZN4PLMD3ves7VesBias15writeBiasToFileEv0
_ZN4PLMD3ves7VesBias18resetFesFileOutputEv0
_ZN4PLMD3ves7VesBias18setupFesFileOutputEv0
_ZN4PLMD3ves7VesBias18writeFesProjToFileEv0
_ZN4PLMD3ves7VesBias19parseMultipleValuesINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEbRKS8_RSt6vectorIT_SaISC_EEj90
_ZN4PLMD3ves7VesBias19parseMultipleValuesIdEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEj0
_ZN4PLMD3ves7VesBias19parseMultipleValuesIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEj90
_ZN4PLMD3ves7VesBias19parseMultipleValuesIjEEbRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EEjRKSC_90
_ZN4PLMD3ves7VesBias19resetBiasFileOutputEv0
_ZN4PLMD3ves7VesBias19setupBiasFileOutputEv0
_ZN4PLMD3ves7VesBias21writeTargetDistToFileEv0
_ZN4PLMD3ves7VesBias22resetFesProjFileOutputEv0
_ZN4PLMD3ves7VesBias22setupFesProjFileOutputEv0
_ZN4PLMD3ves7VesBias25resetTargetDistFileOutputEv0
_ZN4PLMD3ves7VesBias25setupTargetDistFileOutputEv44
_ZN4PLMD3ves7VesBias25updateTargetDistributionsEv0
_ZN4PLMD3ves7VesBias25writeTargetDistProjToFileEv0
_ZN4PLMD3ves7VesBias26restartTargetDistributionsEv0
_ZN4PLMD3ves7VesBias29resetTargetDistProjFileOutputEv0
_ZN4PLMD3ves7VesBias29setupTargetDistProjFileOutputEv9
_ZNK4PLMD3ves7VesBias15applyBiasCutoffERdRSt6vectorIdSaIdEE600
_ZNK4PLMD3ves7VesBias15applyBiasCutoffERdRSt6vectorIdSaIdEES6_663
_ZNK4PLMD3ves7VesBias29computeCovarianceFromAveragesEj22810
_ZNK4PLMD3ves7VesBias7getBetaEv23277
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesBias.h.gcov.html b/coverage/ves/VesBias.h.gcov.html new file mode 100644 index 000000000000..9c457ca2a28f --- /dev/null +++ b/coverage/ves/VesBias.h.gcov.html @@ -0,0 +1,492 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesBias.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesBias.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:668974.2 %
Date:2024-02-22 21:58:45Functions:92536.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_VesBias_h
+      23             : #define __PLUMED_ves_VesBias_h
+      24             : 
+      25             : #include "CoeffsVector.h"
+      26             : #include "CoeffsMatrix.h"
+      27             : 
+      28             : #include "core/ActionPilot.h"
+      29             : #include "core/ActionWithValue.h"
+      30             : #include "core/ActionWithArguments.h"
+      31             : #include "bias/Bias.h"
+      32             : 
+      33             : #include <vector>
+      34             : #include <string>
+      35             : #include <cmath>
+      36             : #include <memory>
+      37             : 
+      38             : 
+      39             : #define PLUMED_VES_VESBIAS_INIT(ao) Action(ao),VesBias(ao)
+      40             : 
+      41             : namespace PLMD {
+      42             : 
+      43             : class Value;
+      44             : 
+      45             : namespace ves {
+      46             : 
+      47             : class CoeffsVector;
+      48             : class CoeffsMatrix;
+      49             : class BasisFunctions;
+      50             : class Optimizer;
+      51             : class TargetDistribution;
+      52             : class FermiSwitchingFunction;
+      53             : 
+      54             : /**
+      55             : \ingroup INHERIT
+      56             : Abstract base class for implementing biases the extents the normal Bias.h class
+      57             : to include functions related to the variational approach.
+      58             : */
+      59             : 
+      60             : class VesBias:
+      61             :   public bias::Bias
+      62             : {
+      63             : private:
+      64             :   unsigned int ncoeffssets_;
+      65             :   std::vector<std::unique_ptr<CoeffsVector>> coeffs_pntrs_;
+      66             :   std::vector<std::unique_ptr<CoeffsVector>> targetdist_averages_pntrs_;
+      67             :   std::vector<std::unique_ptr<CoeffsVector>> gradient_pntrs_;
+      68             :   std::vector<std::unique_ptr<CoeffsMatrix>> hessian_pntrs_;
+      69             :   std::vector<std::vector<double> > sampled_averages;
+      70             :   std::vector<std::vector<double> > sampled_cross_averages;
+      71             :   bool use_multiple_coeffssets_;
+      72             :   //
+      73             :   std::vector<std::string> coeffs_fnames;
+      74             :   //
+      75             :   size_t ncoeffs_total_;
+      76             :   //
+      77             :   Optimizer* optimizer_pntr_;
+      78             :   bool optimize_coeffs_;
+      79             :   //
+      80             :   bool compute_hessian_;
+      81             :   bool diagonal_hessian_;
+      82             :   //
+      83             :   std::vector<unsigned int> aver_counters;
+      84             :   //
+      85             :   double kbt_;
+      86             :   //
+      87             :   std::vector<TargetDistribution*> targetdist_pntrs_;
+      88             :   bool dynamic_targetdist_;
+      89             :   //
+      90             :   std::vector<unsigned int> grid_bins_;
+      91             :   std::vector<double> grid_min_;
+      92             :   std::vector<double> grid_max_;
+      93             :   //
+      94             :   std::string bias_filename_;
+      95             :   std::string fes_filename_;
+      96             :   std::string targetdist_filename_;
+      97             :   std::string targetdist_averages_filename_;
+      98             :   std::string coeffs_id_prefix_;
+      99             :   //
+     100             :   std::string bias_file_fmt_;
+     101             :   std::string fes_file_fmt_;
+     102             :   std::string targetdist_file_fmt_;
+     103             :   std::string targetdist_restart_file_fmt_;
+     104             :   //
+     105             :   bool filenames_have_iteration_number_;
+     106             :   //
+     107             :   bool bias_fileoutput_active_;
+     108             :   bool fes_fileoutput_active_;
+     109             :   bool fesproj_fileoutput_active_;
+     110             :   bool dynamic_targetdist_fileoutput_active_;
+     111             :   bool static_targetdist_fileoutput_active_;
+     112             :   //
+     113             : 
+     114             :   bool bias_cutoff_active_;
+     115             :   double bias_cutoff_value_;
+     116             :   double bias_current_max_value;
+     117             :   std::unique_ptr<FermiSwitchingFunction> bias_cutoff_swfunc_pntr_;
+     118             :   //
+     119             :   std::vector< std::vector<std::string> > projection_args_;
+     120             :   //
+     121             :   bool calc_reweightfactor_;
+     122             :   //
+     123             :   double optimization_threshold_;
+     124             : private:
+     125             :   void initializeCoeffs(std::unique_ptr<CoeffsVector>);
+     126             :   std::vector<double> computeCovarianceFromAverages(const unsigned int) const;
+     127             :   void multiSimSumAverages(const unsigned int, const double walker_weight=1.0);
+     128             : protected:
+     129             :   //
+     130             :   void checkThatTemperatureIsGiven();
+     131             :   //
+     132             :   void addCoeffsSet(const std::vector<std::string>&,const std::vector<unsigned int>&);
+     133             :   void addCoeffsSet(std::vector<Value*>&,std::vector<BasisFunctions*>&);
+     134             :   void addCoeffsSet(std::unique_ptr<CoeffsVector>);
+     135             :   //
+     136             :   std::string getCoeffsSetLabelString(const std::string&, const unsigned int coeffs_id = 0) const;
+     137             :   void clearCoeffsPntrsVector() {coeffs_pntrs_.clear();}
+     138             :   void addToSampledAverages(const std::vector<double>&, const unsigned int c_id = 0);
+     139             :   void setTargetDistAverages(const std::vector<double>&, const unsigned int coeffs_id = 0);
+     140             :   void setTargetDistAverages(const CoeffsVector&, const unsigned int coeffs_id= 0);
+     141             :   void setTargetDistAveragesToZero(const unsigned int coeffs_id= 0);
+     142             :   //
+     143             :   bool readCoeffsFromFiles();
+     144             :   //
+     145             :   template<class T>
+     146             :   bool parseMultipleValues(const std::string&, std::vector<T>&, unsigned int);
+     147             :   template<class T>
+     148             :   bool parseMultipleValues(const std::string&, std::vector<T>&, unsigned int, const T&);
+     149             :   //
+     150             : public:
+     151             :   static void registerKeywords(Keywords&);
+     152             :   explicit VesBias(const ActionOptions&ao);
+     153             :   ~VesBias();
+     154             :   //
+     155             :   static void useInitialCoeffsKeywords(Keywords&);
+     156             :   static void useTargetDistributionKeywords(Keywords&);
+     157             :   static void useMultipleTargetDistributionKeywords(Keywords&);
+     158             :   static void useGridBinKeywords(Keywords&);
+     159             :   static void useGridLimitsKeywords(Keywords&);
+     160             :   static void useBiasCutoffKeywords(Keywords&);
+     161             :   static void useProjectionArgKeywords(Keywords&);
+     162             :   static void useReweightFactorKeywords(Keywords&);
+     163             :   //
+     164         267 :   std::vector<CoeffsVector*> getCoeffsPntrs() const {return Tools::unique2raw(coeffs_pntrs_);}
+     165          85 :   std::vector<CoeffsVector*> getTargetDistAveragesPntrs() const {return Tools::unique2raw(targetdist_averages_pntrs_);}
+     166          85 :   std::vector<CoeffsVector*> getGradientPntrs()const {return Tools::unique2raw(gradient_pntrs_);}
+     167          82 :   std::vector<CoeffsMatrix*> getHessianPntrs() const {return Tools::unique2raw(hessian_pntrs_);}
+     168          93 :   std::vector<TargetDistribution*> getTargetDistributionPntrs() const {return targetdist_pntrs_;}
+     169             :   //
+     170             :   CoeffsVector* getCoeffsPntr(const unsigned int coeffs_id = 0) const {return coeffs_pntrs_[coeffs_id].get();}
+     171             :   CoeffsVector* getTargetDistAveragesPntr(const unsigned int coeffs_id = 0) const {return targetdist_averages_pntrs_[coeffs_id].get();}
+     172             :   CoeffsVector* getGradientPntr(const unsigned int coeffs_id = 0)const {return gradient_pntrs_[coeffs_id].get();}
+     173             :   CoeffsMatrix* getHessianPntr(const unsigned int coeffs_id = 0) const {return hessian_pntrs_[coeffs_id].get();}
+     174             :   //
+     175          90 :   unsigned int getNumberOfTargetDistributionPntrs() const {return targetdist_pntrs_.size();}
+     176             :   //
+     177       22810 :   size_t numberOfCoeffs(const unsigned int coeffs_id = 0) const {return coeffs_pntrs_[coeffs_id]->numberOfCoeffs();}
+     178             :   size_t totalNumberOfCoeffs() const {return ncoeffs_total_;}
+     179           3 :   unsigned int numberOfCoeffsSets() const {return ncoeffssets_;}
+     180          85 :   double getKbT() const {return kbt_;}
+     181             :   double getBeta() const;
+     182             :   //
+     183             :   CoeffsVector& Coeffs(const unsigned int coeffs_id = 0) const {return *coeffs_pntrs_[coeffs_id];}
+     184         453 :   CoeffsVector& TargetDistAverages(const unsigned int coeffs_id = 0) const {return *targetdist_averages_pntrs_[coeffs_id];}
+     185             :   CoeffsVector& Gradient(const unsigned int coeffs_id = 0) const {return *gradient_pntrs_[coeffs_id];}
+     186             :   CoeffsMatrix& Hessian(const unsigned int coeffs_id = 0) const {return *hessian_pntrs_[coeffs_id];}
+     187             :   //
+     188             :   size_t getCoeffsIndex(const std::vector<unsigned int>& indices, const unsigned int coeffs_id = 0) const;
+     189             :   std::vector<unsigned int> getCoeffsIndices(const size_t index, const unsigned int coeffs_id = 0) const;
+     190             :   size_t getHessianIndex(const size_t index1, const size_t index2, const unsigned int coeffs_id = 0) const;
+     191             :   //
+     192             :   bool computeHessian() const {return compute_hessian_;}
+     193             :   bool diagonalHessian() const {return diagonal_hessian_;}
+     194             :   //
+     195        1572 :   bool optimizeCoeffs() const {return optimize_coeffs_;}
+     196        1426 :   Optimizer* getOptimizerPntr() const {return optimizer_pntr_;}
+     197             :   bool useMultipleWalkers() const;
+     198             :   //
+     199             :   unsigned int getIterationCounter() const;
+     200             :   //
+     201             :   void updateGradientAndHessian(const bool);
+     202             :   void clearGradientAndHessian() {};
+     203             :   //
+     204           0 :   virtual void updateTargetDistributions() {};
+     205           0 :   virtual void restartTargetDistributions() {};
+     206             :   //
+     207             :   void linkOptimizer(Optimizer*);
+     208             :   void enableHessian(const bool diagonal_hessian=true);
+     209             :   void disableHessian();
+     210             :   //
+     211             :   void enableMultipleCoeffsSets() {use_multiple_coeffssets_=true;}
+     212             :   //
+     213          42 :   void enableDynamicTargetDistribution() {dynamic_targetdist_=true;}
+     214             :   void disableDynamicTargetDistribution() {dynamic_targetdist_=false;}
+     215         273 :   bool dynamicTargetDistribution() const {return dynamic_targetdist_;}
+     216             :   //
+     217          90 :   std::vector<unsigned int> getGridBins() const {return grid_bins_;}
+     218             :   void setGridBins(const std::vector<unsigned int>&);
+     219             :   void setGridBins(const unsigned int);
+     220             :   std::vector<double> getGridMax() const {return grid_max_;}
+     221             :   void setGridMax(const std::vector<double>&);
+     222             :   std::vector<double> getGridMin() const {return grid_min_;}
+     223             :   void setGridMin(const std::vector<double>&);
+     224             :   //
+     225         575 :   bool filenamesIncludeIterationNumber() const {return filenames_have_iteration_number_;}
+     226           3 :   void enableIterationNumberInFilenames() {filenames_have_iteration_number_=true;}
+     227             :   //
+     228             :   std::string getIterationFilenameSuffix() const;
+     229             :   std::string getCoeffsSetFilenameSuffix(const unsigned int coeffs_id) const;
+     230             :   std::string getCurrentOutputFilename(const std::string&, const std::string& suffix="") const;
+     231             :   std::string getBiasOutputFilename() const {return bias_filename_;}
+     232             :   std::string getCurrentBiasOutputFilename(const std::string& suffix="") const;
+     233             :   std::string getFesOutputFilename() const {return fes_filename_;}
+     234             :   std::string getCurrentFesOutputFilename(const std::string& suffix="") const;
+     235             :   std::string getTargetDistOutputFilename() const {return targetdist_filename_;}
+     236             :   std::string getCurrentTargetDistOutputFilename(const std::string& suffix="") const;
+     237             :   //
+     238          83 :   void enableBiasFileOutput() {bias_fileoutput_active_=true;}
+     239             :   void disableBiasFileOutput() {bias_fileoutput_active_=false;}
+     240             :   bool isBiasFileOutputActive() const {return bias_fileoutput_active_;}
+     241             :   std::string getBiasFileFmt() const {return bias_file_fmt_;}
+     242             :   //
+     243          83 :   void enableFesFileOutput() {fes_fileoutput_active_=true;}
+     244             :   void disableFesFileOutput() {fes_fileoutput_active_=false;}
+     245             :   bool isFesFileOutputActive() const {return fes_fileoutput_active_;}
+     246             :   std::string getFesFileFmt() const {return fes_file_fmt_;}
+     247             :   //
+     248          17 :   void enableFesProjFileOutput() {fesproj_fileoutput_active_=true;}
+     249             :   void disableFesFileProjOutput() {fesproj_fileoutput_active_=false;}
+     250             :   bool isFesProjFileOutputActive() const {return fesproj_fileoutput_active_;}
+     251             :   //
+     252          41 :   void enableDynamicTargetDistFileOutput() {dynamic_targetdist_fileoutput_active_=true;}
+     253             :   void disableDynamicTargetDistFileOutput() {dynamic_targetdist_fileoutput_active_=false;}
+     254             :   bool isDynamicTargetDistFileOutputActive() const {return dynamic_targetdist_fileoutput_active_;}
+     255             :   std::string getTargetDistFileFmt() const {return targetdist_file_fmt_;}
+     256             :   std::string getTargetDistRestartFileFmt() const {return targetdist_restart_file_fmt_;}
+     257             :   //
+     258             :   void enableStaticTargetDistFileOutput() {static_targetdist_fileoutput_active_=true;}
+     259          46 :   void disableStaticTargetDistFileOutput() {static_targetdist_fileoutput_active_=false;}
+     260          50 :   bool isStaticTargetDistFileOutputActive() const {return static_targetdist_fileoutput_active_;}
+     261             :   //
+     262             :   std::vector< std::vector<std::string> > getProjectionArguments() const {return projection_args_;}
+     263          56 :   std::vector<std::string> getProjectionArgument(unsigned int i) const {return projection_args_[i];}
+     264         122 :   unsigned int getNumberOfProjectionArguments() const {return projection_args_.size();}
+     265             :   //
+     266             :   void setupBiasCutoff(const double, const double);
+     267     1498465 :   bool biasCutoffActive() const {return bias_cutoff_active_;}
+     268          45 :   double getBiasCutoffValue() const {return bias_cutoff_value_;}
+     269         498 :   void setCurrentBiasMaxValue(const double max_value) {bias_current_max_value=max_value;}
+     270             :   double getCurrentBiasMaxValue() const {return bias_current_max_value;}
+     271             :   double getBiasCutoffSwitchingFunction(const double, double&) const;
+     272             :   double getBiasCutoffSwitchingFunction(const double) const;
+     273             :   void applyBiasCutoff(double&, std::vector<double>&) const;
+     274             :   void applyBiasCutoff(double&, std::vector<double>&, std::vector<double>&) const;
+     275             :   //
+     276             :   std::unique_ptr<OFile> getOFile(const std::string& filename, const bool multi_sim_single_file=false, const bool enforce_backup=true);
+     277             :   //
+     278           0 :   virtual void setupBiasFileOutput() {};
+     279           0 :   virtual void writeBiasToFile() {};
+     280           0 :   virtual void resetBiasFileOutput() {};
+     281             :   //
+     282           0 :   virtual void setupFesFileOutput() {};
+     283           0 :   virtual void writeFesToFile() {};
+     284           0 :   virtual void resetFesFileOutput() {};
+     285             :   //
+     286           0 :   virtual void setupFesProjFileOutput() {};
+     287           0 :   virtual void writeFesProjToFile() {};
+     288           0 :   virtual void resetFesProjFileOutput() {};
+     289             :   //
+     290          44 :   virtual void setupTargetDistFileOutput() {};
+     291           0 :   virtual void writeTargetDistToFile() {};
+     292           0 :   virtual void resetTargetDistFileOutput() {};
+     293             :   //
+     294           9 :   virtual void setupTargetDistProjFileOutput() {};
+     295           0 :   virtual void writeTargetDistProjToFile() {};
+     296           0 :   virtual void resetTargetDistProjFileOutput() {};
+     297             :   //
+     298             :   void updateReweightFactor();
+     299             :   virtual double calculateReweightFactor() const;
+     300           0 :   bool isReweightFactorCalculated() const {return calc_reweightfactor_;}
+     301             : };
+     302             : 
+     303             : 
+     304             : inline
+     305             : size_t VesBias::getCoeffsIndex(const std::vector<unsigned int>& indices, const unsigned int coeffs_id) const {return coeffs_pntrs_[coeffs_id]->getIndex(indices);}
+     306             : 
+     307             : inline
+     308             : std::vector<unsigned int> VesBias::getCoeffsIndices(const size_t index, const unsigned int coeffs_id) const {return coeffs_pntrs_[coeffs_id]->getIndices(index);}
+     309             : 
+     310             : inline
+     311     3607712 : size_t VesBias::getHessianIndex(const size_t index1, const size_t index2, const unsigned int coeffs_id) const {return hessian_pntrs_[coeffs_id]->getMatrixIndex(index1,index2);}
+     312             : 
+     313             : 
+     314             : inline
+     315       23277 : double VesBias::getBeta() const {
+     316       23277 :   plumed_massert(kbt_!=0.0,"you are requesting beta=1/(kB*T) when kB*T has not been defined. You need to give the temperature using the TEMP keyword as the MD engine does not pass it to PLUMED.");
+     317       23277 :   return 1.0/kbt_;
+     318             : }
+     319             : 
+     320             : 
+     321             : inline
+     322             : std::string VesBias::getCurrentBiasOutputFilename(const std::string& suffix) const {
+     323         178 :   return getCurrentOutputFilename(bias_filename_,suffix);
+     324             : }
+     325             : 
+     326             : 
+     327             : inline
+     328             : std::string VesBias::getCurrentFesOutputFilename(const std::string& suffix) const {
+     329         205 :   return getCurrentOutputFilename(fes_filename_,suffix);
+     330             : }
+     331             : 
+     332             : 
+     333             : inline
+     334             : double VesBias::getBiasCutoffSwitchingFunction(const double bias) const {
+     335             :   double dummy=0.0;
+     336             :   return getBiasCutoffSwitchingFunction(bias,dummy);
+     337             : }
+     338             : 
+     339             : 
+     340             : inline
+     341         600 : void VesBias::applyBiasCutoff(double& bias, std::vector<double>& forces) const {
+     342         600 :   std::vector<double> dummy(0);
+     343         600 :   applyBiasCutoff(bias,forces,dummy);
+     344         600 : }
+     345             : 
+     346             : 
+     347             : inline
+     348         663 : void VesBias::applyBiasCutoff(double& bias, std::vector<double>& forces, std::vector<double>& coeffsderivs_values) const {
+     349         663 :   double deriv_factor_sf=0.0;
+     350         663 :   double value_sf = getBiasCutoffSwitchingFunction(bias,deriv_factor_sf);
+     351         663 :   bias *= value_sf;
+     352        1326 :   for(unsigned int i=0; i<forces.size(); i++) {
+     353         663 :     forces[i] *= deriv_factor_sf;
+     354             :   }
+     355             :   //
+     356        1398 :   for(unsigned int i=0; i<coeffsderivs_values.size(); i++) {
+     357         735 :     coeffsderivs_values[i] *= deriv_factor_sf;
+     358             :   }
+     359         663 : }
+     360             : 
+     361             : 
+     362             : inline
+     363       22810 : std::vector<double> VesBias::computeCovarianceFromAverages(const unsigned int c_id) const {
+     364             :   size_t ncoeffs = numberOfCoeffs(c_id);
+     365       22810 :   std::vector<double> covariance(sampled_cross_averages[c_id].size(),0.0);
+     366             :   // diagonal part
+     367     1823850 :   for(size_t i=0; i<ncoeffs; i++) {
+     368             :     size_t midx = getHessianIndex(i,i,c_id);
+     369     1801040 :     covariance[midx] = sampled_cross_averages[c_id][midx] - sampled_averages[c_id][i]*sampled_averages[c_id][i];
+     370             :   }
+     371       22810 :   if(!diagonal_hessian_) {
+     372           0 :     for(size_t i=0; i<ncoeffs; i++) {
+     373           0 :       for(size_t j=(i+1); j<ncoeffs; j++) {
+     374             :         size_t midx = getHessianIndex(i,j,c_id);
+     375           0 :         covariance[midx] = sampled_cross_averages[c_id][midx] - sampled_averages[c_id][i]*sampled_averages[c_id][j];
+     376             :       }
+     377             :     }
+     378             :   }
+     379       22810 :   return covariance;
+     380             : }
+     381             : 
+     382             : 
+     383             : template<class T>
+     384         180 : bool VesBias::parseMultipleValues(const std::string& keyword, std::vector<T>& values, unsigned int nvalues) {
+     385         180 :   plumed_assert(nvalues>0);
+     386         180 :   plumed_assert(values.size()==0);
+     387             :   bool identical_values=false;
+     388             :   //
+     389         180 :   parseVector(keyword,values);
+     390         180 :   if(values.size()==1 && nvalues>1) {
+     391           0 :     values.resize(nvalues,values[0]);
+     392             :     identical_values=true;
+     393             :   }
+     394         180 :   if(values.size()>0 && values.size()!=nvalues) {
+     395           0 :     std::string s1; Tools::convert(nvalues,s1);
+     396           0 :     plumed_merror("Error in " + keyword + " keyword: either give 1 common parameter value or " + s1 + " separate parameter values");
+     397             :   }
+     398         180 :   return identical_values;
+     399             : }
+     400             : 
+     401             : template<class T>
+     402          90 : bool VesBias::parseMultipleValues(const std::string& keyword, std::vector<T>& values, unsigned int nvalues, const T& default_value) {
+     403          90 :   bool identical_values = parseMultipleValues(keyword,values,nvalues);
+     404          90 :   if(values.size()==0) {
+     405           0 :     values.resize(nvalues,default_value);
+     406             :     identical_values=true;
+     407             :   }
+     408          90 :   return identical_values;
+     409             : }
+     410             : 
+     411             : 
+     412             : }
+     413             : }
+     414             : 
+     415             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesDeltaF.cpp.func-sort-c.html b/coverage/ves/VesDeltaF.cpp.func-sort-c.html new file mode 100644 index 000000000000..44605ff0a2da --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesDeltaF.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesDeltaF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:34335197.7 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9VesDeltaFC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves9VesDeltaFC1ERKNS_13ActionOptionsE4
_ZN4PLMD3ves9VesDeltaF16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves9VesDeltaF12update_alphaEv16
_ZN4PLMD3ves9VesDeltaF17update_tg_and_rctEv16
_ZN4PLMD3ves9VesDeltaF6updateEv804
_ZN4PLMD3ves9VesDeltaF9calculateEv804
_ZNK4PLMD3ves9VesDeltaF9get_indexEjj4632
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesDeltaF.cpp.func.html b/coverage/ves/VesDeltaF.cpp.func.html new file mode 100644 index 000000000000..34611425276e --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesDeltaF.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesDeltaF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:34335197.7 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves9VesDeltaF12update_alphaEv16
_ZN4PLMD3ves9VesDeltaF16registerKeywordsERNS_8KeywordsE6
_ZN4PLMD3ves9VesDeltaF17update_tg_and_rctEv16
_ZN4PLMD3ves9VesDeltaF6updateEv804
_ZN4PLMD3ves9VesDeltaF9calculateEv804
_ZN4PLMD3ves9VesDeltaFC1ERKNS_13ActionOptionsE4
_ZN4PLMD3ves9VesDeltaFC2ERKNS_13ActionOptionsE0
_ZNK4PLMD3ves9VesDeltaF9get_indexEjj4632
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesDeltaF.cpp.gcov.html b/coverage/ves/VesDeltaF.cpp.gcov.html new file mode 100644 index 000000000000..dad66fef7299 --- /dev/null +++ b/coverage/ves/VesDeltaF.cpp.gcov.html @@ -0,0 +1,792 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesDeltaF.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesDeltaF.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:34335197.7 %
Date:2024-02-22 21:58:45Functions:7887.5 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "bias/Bias.h"
+      24             : #include "core/PlumedMain.h"
+      25             : #include "core/ActionRegister.h"
+      26             : #include "tools/Communicator.h"
+      27             : #include "tools/Grid.h"
+      28             : #include "tools/File.h"
+      29             : //#include <algorithm> //std::fill
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace ves {
+      33             : 
+      34             : //+PLUMEDOC VES_BIAS VES_DELTA_F
+      35             : /*
+      36             : Implementation of VES Delta F method
+      37             : 
+      38             : Implementation of VES\f$\Delta F\f$ method \cite Invernizzi2019vesdeltaf (step two only).
+      39             : 
+      40             : \warning
+      41             :   Notice that this is a stand-alone bias Action, it does not need any of the other VES module components
+      42             : 
+      43             : First you should create some estimate of the local free energy basins of your system,
+      44             : using e.g. multiple \ref METAD short runs, and combining them with the \ref sum_hills utility.
+      45             : Once you have them, you can use this bias Action to perform the VES optimization part of the method.
+      46             : 
+      47             : These \f$N+1\f$ local basins are used to model the global free energy.
+      48             : In particular, given the conditional probabilities \f$P(\mathbf{s}|i)\propto e^{-\beta F_i(\mathbf{s})}\f$
+      49             : and the probabilities of being in a given basin \f$P_i\f$, we can write:
+      50             : \f[
+      51             :   e^{-\beta F(\mathbf{s})}\propto P(\mathbf{s})=\sum_{i=0}^N P(\mathbf{s}|i)P_i \, .
+      52             : \f]
+      53             : We use this free energy model and the chosen bias factor \f$\gamma\f$ to build the bias potential:
+      54             : \f$V(\mathbf{s})=-(1-1/\gamma)F(\mathbf{s})\f$.
+      55             : Or, more explicitly:
+      56             : \f[
+      57             :   V(\mathbf{s})=(1-1/\gamma)\frac{1}{\beta}\log\left[e^{-\beta F_0(\mathbf{s})}
+      58             :   +\sum_{i=1}^{N} e^{-\beta F_i(\mathbf{s})} e^{-\beta \alpha_i}\right] \, ,
+      59             : \f]
+      60             : where the parameters \f$\boldsymbol{\alpha}\f$ are the \f$N\f$ free energy differences (see below) from the \f$F_0\f$ basin.
+      61             : 
+      62             : By default the \f$F_i(\mathbf{s})\f$ are shifted so that \f$\min[F_i(\mathbf{s})]=0\f$ for all \f$i=\{0,...,N\}\f$.
+      63             : In this case the optimization parameters \f$\alpha_i\f$ are the difference in height between the minima of the basins.
+      64             : Using the keyword `NORMALIZE`, you can also decide to normalize the local free energies so that
+      65             : \f$\int d\mathbf{s}\, e^{-\beta F_i(\mathbf{s})}=1\f$.
+      66             : In this case the parameters will represent not the difference in height (which depends on the chosen CVs),
+      67             : but the actual free energy difference, \f$\alpha_i=\Delta F_i\f$.
+      68             : 
+      69             : However, as discussed in Ref. \cite Invernizzi2019vesdeltaf, a better estimate of \f$\Delta F_i\f$ should be obtained through the reweighting procedure.
+      70             : 
+      71             : \par Examples
+      72             : 
+      73             : The following performs the optimization of the free energy difference between two metastable basins:
+      74             : 
+      75             : \plumedfile
+      76             : cv: DISTANCE ATOMS=1,2
+      77             : ves: VES_DELTA_F ...
+      78             :   ARG=cv
+      79             :   TEMP=300
+      80             :   FILE_F0=fesA.data
+      81             :   FILE_F1=fesB.data
+      82             :   BIASFACTOR=10.0
+      83             :   M_STEP=0.1
+      84             :   AV_STRIDE=500
+      85             :   PRINT_STRIDE=100
+      86             : ...
+      87             : PRINT FMT=%g STRIDE=500 FILE=Colvar.data ARG=cv,ves.bias,ves.rct
+      88             : \endplumedfile
+      89             : 
+      90             : The local FES files can be obtained as described in Sec. 4.2 of Ref. \cite Invernizzi2019vesdeltaf, i.e. for example:
+      91             : - run 4 independent metad runs, all starting from basin A, and kill them as soon as they make the first transition (see e.g. \ref COMMITTOR)
+      92             : - \verbatim cat HILLS* > all_HILLS \endverbatim
+      93             : - \verbatim plumed sum_hills --hills all_HILLS --outfile all_fesA.dat --mintozero --min 0 --max 1 --bin 100 \endverbatim
+      94             : - \verbatim awk -v n_rep=4 '{if($1!="#!" && $1!="") {for(i=1+(NF-1)/2; i<=NF; i++) $i/=n_rep;} print $0}' all_fesA.dat > fesA.data \endverbatim
+      95             : 
+      96             : The header of both FES files must be identical, and should be similar to the following:
+      97             : 
+      98             : \auxfile{fesA.data}
+      99             : #! FIELDS cv file.free der_cv
+     100             : #! SET min_cv 0
+     101             : #! SET max_cv 1
+     102             : #! SET nbins_cv  100
+     103             : #! SET periodic_cv false
+     104             : 0 0 0
+     105             : \endauxfile
+     106             : \auxfile{fesB.data}
+     107             : #! FIELDS cv file.free der_cv
+     108             : #! SET min_cv 0
+     109             : #! SET max_cv 1
+     110             : #! SET nbins_cv  100
+     111             : #! SET periodic_cv false
+     112             : 0 0 0
+     113             : \endauxfile
+     114             : 
+     115             : */
+     116             : //+ENDPLUMEDOC
+     117             : 
+     118             : class VesDeltaF : public bias::Bias {
+     119             : 
+     120             : private:
+     121             :   double beta_;
+     122             :   unsigned NumParallel_;
+     123             :   unsigned rank_;
+     124             :   unsigned NumWalkers_;
+     125             :   bool isFirstStep_;
+     126             :   bool afterCalculate_;
+     127             : 
+     128             : //prob
+     129             :   double tot_prob_;
+     130             :   std::vector<double> prob_;
+     131             :   std::vector< std::vector<double> > der_prob_;
+     132             : 
+     133             : //local basins
+     134             :   std::vector< std::unique_ptr<Grid> > grid_p_; //pointers because of GridBase::create
+     135             :   std::vector<double> norm_;
+     136             : 
+     137             : //optimizer-related stuff
+     138             :   long long unsigned mean_counter_;
+     139             :   unsigned mean_weight_tau_;
+     140             :   unsigned alpha_size_;
+     141             :   unsigned sym_alpha_size_;
+     142             :   std::vector<double> mean_alpha_;
+     143             :   std::vector<double> inst_alpha_;
+     144             :   std::vector<double> past_increment2_;
+     145             :   double minimization_step_;
+     146             :   bool damping_off_;
+     147             : //'tg' -> 'target distribution'
+     148             :   double inv_gamma_;
+     149             :   unsigned tg_counter_;
+     150             :   unsigned tg_stride_;
+     151             :   std::vector<double> tg_dV_dAlpha_;
+     152             :   std::vector<double> tg_d2V_dAlpha2_;
+     153             : //'av' -> 'ensemble average'
+     154             :   unsigned av_counter_;
+     155             :   unsigned av_stride_;
+     156             :   std::vector<double> av_dV_dAlpha_;
+     157             :   std::vector<double> av_dV_dAlpha_prod_;
+     158             :   std::vector<double> av_d2V_dAlpha2_;
+     159             : //printing
+     160             :   unsigned print_stride_;
+     161             :   OFile alphaOfile_;
+     162             : //other
+     163             :   std::vector<double> exp_alpha_;
+     164             :   std::vector<double> prev_exp_alpha_;
+     165             :   double work_;
+     166             : 
+     167             : //functions
+     168             :   void update_alpha();
+     169             :   void update_tg_and_rct();
+     170             :   inline unsigned get_index(const unsigned, const unsigned) const;
+     171             : 
+     172             : public:
+     173             :   explicit VesDeltaF(const ActionOptions&);
+     174             :   void calculate() override;
+     175             :   void update() override;
+     176             :   static void registerKeywords(Keywords& keys);
+     177             : };
+     178             : 
+     179             : PLUMED_REGISTER_ACTION(VesDeltaF,"VES_DELTA_F")
+     180             : 
+     181           6 : void VesDeltaF::registerKeywords(Keywords& keys) {
+     182           6 :   Bias::registerKeywords(keys);
+     183           6 :   keys.use("ARG");
+     184          12 :   keys.add("optional","TEMP","temperature is compulsory, but it can be sometimes fetched from the MD engine");
+     185             : //local free energies
+     186          12 :   keys.add("numbered","FILE_F","names of files containing local free energies and derivatives. "
+     187             :            "The first one, FILE_F0, is used as reference for all the free energy differences.");
+     188          12 :   keys.reset_style("FILE_F","compulsory");
+     189          12 :   keys.addFlag("NORMALIZE",false,"normalize all local free energies so that alpha will be (approx) Delta F");
+     190          12 :   keys.addFlag("NO_MINTOZERO",false,"leave local free energies as provided, without shifting them to zero min");
+     191             : //target distribution
+     192          12 :   keys.add("compulsory","BIASFACTOR","0","the gamma bias factor used for well-tempered target p(s)."
+     193             :            " Set to 0 for non-tempered flat target");
+     194          12 :   keys.add("optional","TG_STRIDE","( default=1 ) number of AV_STRIDE between updates"
+     195             :            " of target p(s) and reweighing factor c(t)");
+     196             : //optimization
+     197          12 :   keys.add("compulsory","M_STEP","1.0","the mu step used for the Omega functional minimization");
+     198          12 :   keys.add("compulsory","AV_STRIDE","500","number of simulation steps between alpha updates");
+     199          12 :   keys.add("optional","TAU_MEAN","exponentially decaying average for alpha (rescaled using AV_STRIDE)."
+     200             :            " Should be used only in very specific cases");
+     201          12 :   keys.add("optional","INITIAL_ALPHA","( default=0 ) an initial guess for the bias potential parameter alpha");
+     202          12 :   keys.addFlag("DAMPING_OFF",false,"do not use an AdaGrad-like term to rescale M_STEP");
+     203             : //output parameters file
+     204          12 :   keys.add("compulsory","ALPHA_FILE","ALPHA","file name for output minimization parameters");
+     205          12 :   keys.add("optional","PRINT_STRIDE","( default=10 ) stride for printing to ALPHA_FILE");
+     206          12 :   keys.add("optional","FMT","specify format for ALPHA_FILE");
+     207             : //debug flags
+     208          12 :   keys.addFlag("SERIAL",false,"perform the calculation in serial even if multiple tasks are available");
+     209          12 :   keys.addFlag("MULTIPLE_WALKERS",false,"use multiple walkers connected via MPI for the optimization");
+     210           6 :   keys.use("RESTART");
+     211             : 
+     212             : //output components
+     213           6 :   componentsAreNotOptional(keys);
+     214          12 :   keys.addOutputComponent("rct","default","the reweighting factor c(t)");
+     215          12 :   keys.addOutputComponent("work","default","the work done by the bias in one AV_STRIDE");
+     216           6 : }
+     217             : 
+     218           4 : VesDeltaF::VesDeltaF(const ActionOptions&ao)
+     219             :   : PLUMED_BIAS_INIT(ao)
+     220           4 :   , isFirstStep_(true)
+     221           4 :   , afterCalculate_(false)
+     222           4 :   , mean_counter_(0)
+     223           4 :   , av_counter_(0)
+     224           4 :   , work_(0)
+     225             : {
+     226             : //set beta
+     227           4 :   const double Kb=getKBoltzmann();
+     228           4 :   double KbT=getkBT();
+     229           4 :   plumed_massert(KbT>0,"your MD engine does not pass the temperature to plumed, you must specify it using TEMP");
+     230           4 :   beta_=1.0/KbT;
+     231             : 
+     232             : //initialize probability grids using local free energies
+     233             :   bool spline=true;
+     234             :   bool sparsegrid=false;
+     235           4 :   std::string funcl="file.free"; //typical name given by sum_hills
+     236             : 
+     237             :   std::vector<std::string> fes_names;
+     238           8 :   for(unsigned n=0;; n++)//NB: here we start from FILE_F0 not from FILE_F1
+     239             :   {
+     240             :     std::string filename;
+     241          24 :     if(!parseNumbered("FILE_F",n,filename))
+     242             :       break;
+     243           8 :     fes_names.push_back(filename);
+     244           8 :     IFile gridfile;
+     245           8 :     gridfile.open(filename);
+     246           8 :     auto g=GridBase::create(funcl,getArguments(),gridfile,sparsegrid,spline,true);
+     247             : // we assume this cannot be sparse. in case we want it to be sparse, some of the methods
+     248             : // that are available only in Grid should be ported to GridBase
+     249           8 :     auto gg=dynamic_cast<Grid*>(g.get());
+     250             : // if this throws, g is deleted
+     251           8 :     plumed_assert(gg);
+     252             : // release ownership in order to transfer it to emplaced pointer
+     253             : // cppcheck-suppress ignoredReturnValue
+     254             :     g.release();
+     255           8 :     grid_p_.emplace_back(gg);
+     256          16 :   }
+     257           4 :   plumed_massert(grid_p_.size()>1,"at least 2 basins must be defined, starting from FILE_F0");
+     258           4 :   alpha_size_=grid_p_.size()-1;
+     259           4 :   sym_alpha_size_=alpha_size_*(alpha_size_+1)/2; //useful for symmetric matrix [alpha_size_]x[alpha_size_]
+     260             :   //check for consistency with first local free energy
+     261           8 :   for(unsigned n=1; n<grid_p_.size(); n++)
+     262             :   {
+     263           8 :     std::string error_tag="FILE_F"+std::to_string(n)+" '"+fes_names[n]+"' not compatible with reference one, FILE_F0";
+     264           4 :     plumed_massert(grid_p_[n]->getSize()==grid_p_[0]->getSize(),error_tag);
+     265           4 :     plumed_massert(grid_p_[n]->getMin()==grid_p_[0]->getMin(),error_tag);
+     266           4 :     plumed_massert(grid_p_[n]->getMax()==grid_p_[0]->getMax(),error_tag);
+     267           4 :     plumed_massert(grid_p_[n]->getBinVolume()==grid_p_[0]->getBinVolume(),error_tag);
+     268             :   }
+     269             : 
+     270           4 :   bool no_mintozero=false;
+     271           4 :   parseFlag("NO_MINTOZERO",no_mintozero);
+     272           4 :   if(!no_mintozero)
+     273             :   {
+     274           6 :     for(unsigned n=0; n<grid_p_.size(); n++)
+     275           4 :       grid_p_[n]->setMinToZero();
+     276             :   }
+     277           4 :   bool normalize=false;
+     278           4 :   parseFlag("NORMALIZE",normalize);
+     279           4 :   norm_.resize(grid_p_.size(),0);
+     280           4 :   std::vector<double> c_norm(grid_p_.size());
+     281             :   //convert the FESs to probability distributions
+     282             :   //NB: the spline interpolation will be done on the probability distributions, not on the given FESs
+     283             :   const unsigned ncv=getNumberOfArguments(); //just for ease
+     284          12 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     285             :   {
+     286         808 :     for(Grid::index_t t=0; t<grid_p_[n]->getSize(); t++)
+     287             :     {
+     288         800 :       std::vector<double> der(ncv);
+     289         800 :       const double val=std::exp(-beta_*grid_p_[n]->getValueAndDerivatives(t,der));
+     290        1600 :       for(unsigned s=0; s<ncv; s++)
+     291         800 :         der[s]*=-beta_*val;
+     292         800 :       grid_p_[n]->setValueAndDerivatives(t,val,der);
+     293         800 :       norm_[n]+=val;
+     294             :     }
+     295           8 :     c_norm[n]=1./beta_*std::log(norm_[n]);
+     296           8 :     if(normalize)
+     297             :     {
+     298           4 :       grid_p_[n]->scaleAllValuesAndDerivatives(1./norm_[n]);
+     299           4 :       norm_[n]=1;
+     300             :     }
+     301             :   }
+     302             : 
+     303             : //get target
+     304           4 :   double biasfactor=0;
+     305           4 :   parse("BIASFACTOR",biasfactor);
+     306           4 :   plumed_massert(biasfactor==0 || biasfactor>1,"BIASFACTOR must be zero (for uniform target) or greater than one");
+     307           4 :   if(biasfactor==0)
+     308           2 :     inv_gamma_=0;
+     309             :   else
+     310           2 :     inv_gamma_=1./biasfactor;
+     311           4 :   tg_counter_=0;
+     312           4 :   tg_stride_=1;
+     313           4 :   parse("TG_STRIDE",tg_stride_);
+     314           4 :   tg_dV_dAlpha_.resize(alpha_size_,0);
+     315           4 :   tg_d2V_dAlpha2_.resize(sym_alpha_size_,0);
+     316             : 
+     317             : //setup optimization stuff
+     318           4 :   minimization_step_=1;
+     319           4 :   parse("M_STEP",minimization_step_);
+     320             : 
+     321           4 :   av_stride_=500;
+     322           4 :   parse("AV_STRIDE",av_stride_);
+     323           4 :   av_dV_dAlpha_.resize(alpha_size_,0);
+     324           4 :   av_dV_dAlpha_prod_.resize(sym_alpha_size_,0);
+     325           4 :   av_d2V_dAlpha2_.resize(sym_alpha_size_,0);
+     326             : 
+     327           4 :   mean_weight_tau_=0;
+     328           4 :   parse("TAU_MEAN",mean_weight_tau_);
+     329           4 :   if(mean_weight_tau_!=1) //set it to 1 for basic SGD
+     330             :   {
+     331           4 :     plumed_massert((mean_weight_tau_==0 || mean_weight_tau_>av_stride_),"TAU_MEAN is rescaled with AV_STRIDE, so it has to be greater");
+     332           4 :     mean_weight_tau_/=av_stride_; //this way you can look at the number of simulation steps to choose TAU_MEAN
+     333             :   }
+     334             : 
+     335           8 :   parseVector("INITIAL_ALPHA",mean_alpha_);
+     336           4 :   if(mean_alpha_.size()>0)
+     337             :   {
+     338           2 :     plumed_massert(mean_alpha_.size()==alpha_size_,"provide one INITIAL_ALPHA for each basin beyond the first one");
+     339             :   }
+     340             :   else
+     341           2 :     mean_alpha_.resize(alpha_size_,0);
+     342           4 :   inst_alpha_=mean_alpha_;
+     343           4 :   exp_alpha_.resize(alpha_size_);
+     344           8 :   for(unsigned i=0; i<alpha_size_; i++)
+     345           4 :     exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     346           4 :   prev_exp_alpha_=exp_alpha_;
+     347             : 
+     348           4 :   damping_off_=false;
+     349           4 :   parseFlag("DAMPING_OFF",damping_off_);
+     350           4 :   if(damping_off_)
+     351           2 :     past_increment2_.resize(alpha_size_,1);
+     352             :   else
+     353           2 :     past_increment2_.resize(alpha_size_,0);
+     354             : 
+     355             : //file printing options
+     356           4 :   std::string alphaFileName("ALPHA");
+     357           4 :   parse("ALPHA_FILE",alphaFileName);
+     358           4 :   print_stride_=10;
+     359           8 :   parse("PRINT_STRIDE",print_stride_);
+     360             :   std::string fmt;
+     361           4 :   parse("FMT",fmt);
+     362             : 
+     363             : //other flags, mainly for debugging
+     364           4 :   NumParallel_=comm.Get_size();
+     365           4 :   rank_=comm.Get_rank();
+     366           4 :   bool serial=false;
+     367           4 :   parseFlag("SERIAL",serial);
+     368           4 :   if(serial)
+     369             :   {
+     370           2 :     log.printf(" -- SERIAL: running without loop parallelization\n");
+     371           2 :     NumParallel_=1;
+     372           2 :     rank_=0;
+     373             :   }
+     374             : 
+     375           4 :   bool multiple_walkers=false;
+     376           4 :   parseFlag("MULTIPLE_WALKERS",multiple_walkers);
+     377           4 :   if(!multiple_walkers)
+     378           2 :     NumWalkers_=1;
+     379             :   else
+     380             :   {
+     381           2 :     if(comm.Get_rank()==0)//multi_sim_comm works well on first rank only
+     382           2 :       NumWalkers_=multi_sim_comm.Get_size();
+     383           2 :     if(comm.Get_size()>1) //if each walker has more than one processor update them all
+     384           0 :       comm.Bcast(NumWalkers_,0);
+     385             :   }
+     386             : 
+     387           4 :   checkRead();
+     388             : 
+     389             : //restart if needed
+     390           4 :   if(getRestart())
+     391             :   {
+     392           2 :     IFile ifile;
+     393           2 :     ifile.link(*this);
+     394           2 :     if(NumWalkers_>1)
+     395           4 :       ifile.enforceSuffix("");
+     396           2 :     if(ifile.FileExist(alphaFileName))
+     397             :     {
+     398           2 :       log.printf("  Restarting from: %s\n",alphaFileName.c_str());
+     399           2 :       log.printf("    all options (also PRINT_STRIDE) must be consistent!\n");
+     400           2 :       log.printf("    any INITIAL_ALPHA will be overwritten\n");
+     401           2 :       ifile.open(alphaFileName);
+     402             :       double time;
+     403           2 :       std::vector<double> damping(alpha_size_);
+     404          20 :       while(ifile.scanField("time",time)) //room for improvements: only last line is important
+     405             :       {
+     406          16 :         for(unsigned i=0; i<alpha_size_; i++)
+     407             :         {
+     408           8 :           const std::string index(std::to_string(i+1));
+     409           8 :           prev_exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     410          16 :           ifile.scanField("alpha_"+index,mean_alpha_[i]);
+     411          16 :           ifile.scanField("auxiliary_"+index,inst_alpha_[i]);
+     412          16 :           ifile.scanField("damping_"+index,damping[i]);
+     413             :         }
+     414           8 :         ifile.scanField();
+     415           8 :         mean_counter_+=print_stride_;
+     416             :       }
+     417           4 :       for(unsigned i=0; i<alpha_size_; i++)
+     418             :       {
+     419           2 :         exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     420           2 :         past_increment2_[i]=damping[i]*damping[i];
+     421             :       }
+     422             :       //sync all walkers and treads. Not sure is mandatory but is no harm
+     423           2 :       comm.Barrier();
+     424           2 :       if(comm.Get_rank()==0)
+     425           2 :         multi_sim_comm.Barrier();
+     426             :     }
+     427             :     else
+     428           0 :       log.printf("  -- WARNING: restart requested, but no '%s' file found!\n",alphaFileName.c_str());
+     429           2 :   }
+     430             : 
+     431             : //setup output file with Alpha values
+     432           4 :   alphaOfile_.link(*this);
+     433           4 :   if(NumWalkers_>1)
+     434             :   {
+     435           2 :     if(comm.Get_rank()==0 && multi_sim_comm.Get_rank()>0)
+     436             :       alphaFileName="/dev/null"; //only first walker writes on file
+     437           4 :     alphaOfile_.enforceSuffix("");
+     438             :   }
+     439           4 :   alphaOfile_.open(alphaFileName);
+     440           4 :   if(fmt.length()>0)
+     441           8 :     alphaOfile_.fmtField(" "+fmt);
+     442             : 
+     443             : //add other output components
+     444          12 :   addComponent("rct"); componentIsNotPeriodic("rct");
+     445           8 :   addComponent("work"); componentIsNotPeriodic("work");
+     446             : 
+     447             : //print some info
+     448           4 :   log.printf("  Temperature T: %g\n",1./(Kb*beta_));
+     449           4 :   log.printf("  Beta (1/Kb*T): %g\n",beta_);
+     450           4 :   log.printf("  Local free energy basins files and normalization constants:\n");
+     451          12 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     452           8 :     log.printf("    F_%d filename: %s  c_%d=%g\n",n,fes_names[n].c_str(),n,c_norm[n]);
+     453           4 :   if(no_mintozero)
+     454           2 :     log.printf(" -- NO_MINTOZERO: local free energies are not shifted to be zero at minimum\n");
+     455           4 :   if(normalize)
+     456           2 :     log.printf(" -- NORMALIZE: F_n+=c_n, alpha=DeltaF\n");
+     457           4 :   log.printf("  Using target distribution with 1/gamma = %g\n",inv_gamma_);
+     458           4 :   log.printf("    and updated with stride %d\n",tg_stride_);
+     459           4 :   log.printf("  Step for the minimization algorithm: %g\n",minimization_step_);
+     460           4 :   log.printf("  Stride for the ensemble average: %d\n",av_stride_);
+     461           4 :   if(mean_weight_tau_>1)
+     462           2 :     log.printf("  Exponentially decaying average with weight=tau/av_stride=%d\n",mean_weight_tau_);
+     463           4 :   if(mean_weight_tau_==1)
+     464           0 :     log.printf(" +++ WARNING +++ setting TAU_MEAN=1 is equivalent to use simple SGD, without mean alpha nor hessian contribution\n");
+     465           4 :   log.printf("  Initial guess for alpha:\n");
+     466           8 :   for(unsigned i=0; i<alpha_size_; i++)
+     467           4 :     log.printf("    alpha_%d = %g\n",i+1,mean_alpha_[i]);
+     468           4 :   if(damping_off_)
+     469           2 :     log.printf(" -- DAMPING_OFF: the minimization step will NOT become smaller as the simulation goes on\n");
+     470           4 :   log.printf("  Printing on file %s with stride %d\n",alphaFileName.c_str(),print_stride_);
+     471           4 :   if(serial)
+     472           2 :     log.printf(" -- SERIAL: running without loop parallelization\n");
+     473           4 :   if(NumParallel_>1)
+     474           2 :     log.printf("  Using multiple threads per simulation: %d\n",NumParallel_);
+     475           4 :   if(multiple_walkers)
+     476             :   {
+     477           2 :     log.printf(" -- MULTIPLE_WALKERS: multiple simulations will combine statistics for the optimization\n");
+     478           2 :     if(NumWalkers_>1)
+     479             :     {
+     480           2 :       log.printf("    number of walkers: %d\n",NumWalkers_);
+     481           2 :       log.printf("    walker rank: %d\n",multi_sim_comm.Get_rank()); //only comm.Get_rank()=0 prints, so this is fine
+     482             :     }
+     483             :     else
+     484           0 :       log.printf(" +++ WARNING +++ only one replica found: are you sure you are running MPI-connected simulations?\n");
+     485             :   }
+     486           4 :   log.printf(" Bibliography ");
+     487           8 :   log<<plumed.cite("Invernizzi and Parrinello, J. Chem. Theory Comput. 15, 2187-2194 (2019)");
+     488           8 :   log<<plumed.cite("Valsson and Parrinello, Phys. Rev. Lett. 113, 090601 (2014)");
+     489           4 :   if(inv_gamma_>0)
+     490           4 :     log<<plumed.cite("Valsson and Parrinello, J. Chem. Theory Comput. 11, 1996-2002 (2015)");
+     491             : 
+     492             : //last initializations
+     493           4 :   prob_.resize(grid_p_.size());
+     494           4 :   der_prob_.resize(grid_p_.size(),std::vector<double>(getNumberOfArguments()));
+     495           4 :   update_tg_and_rct();
+     496           8 : }
+     497             : 
+     498         804 : void VesDeltaF::calculate()
+     499             : {
+     500             : //get CVs
+     501         804 :   const unsigned ncv=getNumberOfArguments(); //just for ease
+     502         804 :   std::vector<double> cv(ncv);
+     503        1608 :   for(unsigned s=0; s<ncv; s++)
+     504         804 :     cv[s]=getArgument(s);
+     505             : //get probabilities for each basin, and total one
+     506        2412 :   for(unsigned n=0; n<grid_p_.size(); n++)
+     507        1608 :     prob_[n]=grid_p_[n]->getValueAndDerivatives(cv,der_prob_[n]);
+     508         804 :   tot_prob_=prob_[0];
+     509        1608 :   for(unsigned i=0; i<alpha_size_; i++)
+     510         804 :     tot_prob_+=prob_[i+1]*exp_alpha_[i];
+     511             : 
+     512             : //update bias and forces: V=-(1-inv_gamma_)*fes
+     513         804 :   setBias((1-inv_gamma_)/beta_*std::log(tot_prob_));
+     514        1608 :   for(unsigned s=0; s<ncv; s++)
+     515             :   {
+     516         804 :     double dProb_dCV_s=der_prob_[0][s];
+     517        1608 :     for(unsigned i=0; i<alpha_size_; i++)
+     518         804 :       dProb_dCV_s+=der_prob_[i+1][s]*exp_alpha_[i];
+     519         804 :     setOutputForce(s,-(1-inv_gamma_)/beta_/tot_prob_*dProb_dCV_s);
+     520             :   }
+     521         804 :   afterCalculate_=true;
+     522         804 : }
+     523             : 
+     524         804 : void VesDeltaF::update()
+     525             : {
+     526             : //skip first step to sync getTime() and av_counter_, as in METAD
+     527         804 :   if(isFirstStep_)
+     528             :   {
+     529           4 :     isFirstStep_=false;
+     530           4 :     return;
+     531             :   }
+     532         800 :   plumed_massert(afterCalculate_,"VesDeltaF::update() must be called after VesDeltaF::calculate() to work properly");
+     533         800 :   afterCalculate_=false;
+     534             : 
+     535             : //calculate derivatives for ensemble averages
+     536         800 :   std::vector<double> dV_dAlpha(alpha_size_);
+     537         800 :   std::vector<double> d2V_dAlpha2(sym_alpha_size_);
+     538        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     539         800 :     dV_dAlpha[i]=-(1-inv_gamma_)/tot_prob_*prob_[i+1]*exp_alpha_[i];
+     540        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     541             :   {
+     542         800 :     d2V_dAlpha2[get_index(i,i)]=-beta_*dV_dAlpha[i];
+     543        1600 :     for(unsigned j=i; j<alpha_size_; j++)
+     544         800 :       d2V_dAlpha2[get_index(i,j)]-=beta_/(1-inv_gamma_)*dV_dAlpha[i]*dV_dAlpha[j];
+     545             :   }
+     546             : //update ensemble averages
+     547         800 :   av_counter_++;
+     548        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     549             :   {
+     550         800 :     av_dV_dAlpha_[i]+=(dV_dAlpha[i]-av_dV_dAlpha_[i])/av_counter_;
+     551        1600 :     for(unsigned j=i; j<alpha_size_; j++)
+     552             :     {
+     553         800 :       const unsigned ij=get_index(i,j);
+     554         800 :       av_dV_dAlpha_prod_[ij]+=(dV_dAlpha[i]*dV_dAlpha[j]-av_dV_dAlpha_prod_[ij])/av_counter_;
+     555         800 :       av_d2V_dAlpha2_[ij]+=(d2V_dAlpha2[ij]-av_d2V_dAlpha2_[ij])/av_counter_;
+     556             :     }
+     557             :   }
+     558             : //update work
+     559         800 :   double prev_tot_prob=prob_[0];
+     560        1600 :   for(unsigned i=0; i<alpha_size_; i++)
+     561         800 :     prev_tot_prob+=prob_[i+1]*prev_exp_alpha_[i];
+     562         800 :   work_+=(1-inv_gamma_)/beta_*std::log(tot_prob_/prev_tot_prob);
+     563             : 
+     564             : //update coefficients
+     565         800 :   if(av_counter_==av_stride_)
+     566             :   {
+     567          16 :     update_alpha();
+     568          16 :     tg_counter_++;
+     569          16 :     if(tg_counter_==tg_stride_)
+     570             :     {
+     571          12 :       update_tg_and_rct();
+     572          12 :       tg_counter_=0;
+     573             :     }
+     574             :     //reset the ensemble averages
+     575          16 :     av_counter_=0;
+     576             :     std::fill(av_dV_dAlpha_.begin(),av_dV_dAlpha_.end(),0);
+     577             :     std::fill(av_dV_dAlpha_prod_.begin(),av_dV_dAlpha_prod_.end(),0);
+     578             :     std::fill(av_d2V_dAlpha2_.begin(),av_d2V_dAlpha2_.end(),0);
+     579             :   }
+     580             : }
+     581             : 
+     582          16 : void VesDeltaF::update_tg_and_rct()
+     583             : {
+     584             : //calculate target averages
+     585          16 :   double Z_0=norm_[0];
+     586          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     587          16 :     Z_0+=norm_[i+1]*exp_alpha_[i];
+     588          16 :   double Z_tg=0;
+     589             :   std::fill(tg_dV_dAlpha_.begin(),tg_dV_dAlpha_.end(),0);
+     590             :   std::fill(tg_d2V_dAlpha2_.begin(),tg_d2V_dAlpha2_.end(),0);
+     591        1116 :   for(Grid::index_t t=rank_; t<grid_p_[0]->getSize(); t+=NumParallel_)
+     592             :   { //TODO can we recycle some code?
+     593        1100 :     std::vector<double> prob(grid_p_.size());
+     594        3300 :     for(unsigned n=0; n<grid_p_.size(); n++)
+     595        2200 :       prob[n]=grid_p_[n]->getValue(t);
+     596        1100 :     double tot_prob=prob[0];
+     597        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     598        1100 :       tot_prob+=prob[i+1]*exp_alpha_[i];
+     599        1100 :     std::vector<double> dV_dAlpha(alpha_size_);
+     600        1100 :     std::vector<double> d2V_dAlpha2(sym_alpha_size_);
+     601        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     602        1100 :       dV_dAlpha[i]=-(1-inv_gamma_)/tot_prob*prob[i+1]*exp_alpha_[i];
+     603        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     604             :     {
+     605        1100 :       d2V_dAlpha2[get_index(i,i)]=-beta_*dV_dAlpha[i];
+     606        2200 :       for(unsigned j=i; j<alpha_size_; j++)
+     607        1100 :         d2V_dAlpha2[get_index(i,j)]-=beta_/(1-inv_gamma_)*dV_dAlpha[i]*dV_dAlpha[j];
+     608             :     }
+     609        1100 :     const double unnorm_tg_p=std::pow(tot_prob,inv_gamma_);
+     610        1100 :     Z_tg+=unnorm_tg_p;
+     611        2200 :     for(unsigned i=0; i<alpha_size_; i++)
+     612        1100 :       tg_dV_dAlpha_[i]+=unnorm_tg_p*dV_dAlpha[i];
+     613        2200 :     for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     614        1100 :       tg_d2V_dAlpha2_[ij]+=unnorm_tg_p*d2V_dAlpha2[ij];
+     615             :   }
+     616          16 :   if(NumParallel_>1)
+     617             :   {
+     618          10 :     comm.Sum(Z_tg);
+     619          10 :     comm.Sum(tg_dV_dAlpha_);
+     620          10 :     comm.Sum(tg_d2V_dAlpha2_);
+     621             :   }
+     622          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     623          16 :     tg_dV_dAlpha_[i]/=Z_tg;
+     624          32 :   for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     625          16 :     tg_d2V_dAlpha2_[ij]/=Z_tg;
+     626          16 :   getPntrToComponent("rct")->set(-1./beta_*std::log(Z_tg/Z_0)); //Z_tg is the best available estimate of Z_V
+     627          16 : }
+     628             : 
+     629          16 : void VesDeltaF::update_alpha()
+     630             : {
+     631             : //combining the averages of multiple walkers
+     632          16 :   if(NumWalkers_>1)
+     633             :   {
+     634           8 :     if(comm.Get_rank()==0) //sum only once: in the first rank of each walker
+     635             :     {
+     636           8 :       multi_sim_comm.Sum(av_dV_dAlpha_);
+     637           8 :       multi_sim_comm.Sum(av_dV_dAlpha_prod_);
+     638           8 :       multi_sim_comm.Sum(av_d2V_dAlpha2_);
+     639          16 :       for(unsigned i=0; i<alpha_size_; i++)
+     640           8 :         av_dV_dAlpha_[i]/=NumWalkers_;
+     641          16 :       for(unsigned ij=0; ij<sym_alpha_size_; ij++)
+     642             :       {
+     643           8 :         av_dV_dAlpha_prod_[ij]/=NumWalkers_;
+     644           8 :         av_d2V_dAlpha2_[ij]/=NumWalkers_;
+     645             :       }
+     646             :     }
+     647           8 :     if(comm.Get_size()>1)//if there are more ranks for each walker, everybody has to know
+     648             :     {
+     649           0 :       comm.Bcast(av_dV_dAlpha_,0);
+     650           0 :       comm.Bcast(av_dV_dAlpha_prod_,0);
+     651           0 :       comm.Bcast(av_d2V_dAlpha2_,0);
+     652             :     }
+     653             :   }
+     654             :   //set work and reset it
+     655          16 :   getPntrToComponent("work")->set(work_);
+     656          16 :   work_=0;
+     657             : 
+     658             : //build the gradient and the Hessian of the functional
+     659          16 :   std::vector<double> grad_omega(alpha_size_);
+     660          16 :   std::vector<double> hess_omega(sym_alpha_size_);
+     661          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     662             :   {
+     663          16 :     grad_omega[i]=tg_dV_dAlpha_[i]-av_dV_dAlpha_[i];
+     664          32 :     for(unsigned j=i; j<alpha_size_; j++)
+     665             :     {
+     666          16 :       const unsigned ij=get_index(i,j);
+     667          16 :       hess_omega[ij]=beta_*(av_dV_dAlpha_prod_[ij]-av_dV_dAlpha_[i]*av_dV_dAlpha_[j])+tg_d2V_dAlpha2_[ij]-av_d2V_dAlpha2_[ij];
+     668             :     }
+     669             :   }
+     670             : //calculate the increment and update alpha
+     671          16 :   mean_counter_++;
+     672             :   long long unsigned mean_weight=mean_counter_;
+     673          16 :   if(mean_weight_tau_>0 && mean_weight_tau_<mean_counter_)
+     674             :     mean_weight=mean_weight_tau_;
+     675          16 :   std::vector<double> damping(alpha_size_);
+     676          32 :   for(unsigned i=0; i<alpha_size_; i++)
+     677             :   {
+     678          16 :     double increment_i=grad_omega[i];
+     679          32 :     for(unsigned j=0; j<alpha_size_; j++)
+     680          16 :       increment_i+=hess_omega[get_index(i,j)]*(inst_alpha_[j]-mean_alpha_[j]);
+     681          16 :     if(!damping_off_)
+     682           8 :       past_increment2_[i]+=increment_i*increment_i;
+     683          16 :     damping[i]=std::sqrt(past_increment2_[i]);
+     684          16 :     prev_exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     685          16 :     inst_alpha_[i]-=minimization_step_/damping[i]*increment_i;
+     686          16 :     mean_alpha_[i]+=(inst_alpha_[i]-mean_alpha_[i])/mean_weight;
+     687          16 :     exp_alpha_[i]=std::exp(-beta_*mean_alpha_[i]);
+     688             :   }
+     689             : 
+     690             : //update the Alpha file
+     691          16 :   if(mean_counter_%print_stride_==0)
+     692             :   {
+     693          16 :     alphaOfile_.printField("time",getTime());
+     694          32 :     for(unsigned i=0; i<alpha_size_; i++)
+     695             :     {
+     696          16 :       const std::string index(std::to_string(i+1));
+     697          32 :       alphaOfile_.printField("alpha_"+index,mean_alpha_[i]);
+     698          32 :       alphaOfile_.printField("auxiliary_"+index,inst_alpha_[i]);
+     699          32 :       alphaOfile_.printField("damping_"+index,damping[i]);
+     700             :     }
+     701          16 :     alphaOfile_.printField();
+     702             :   }
+     703          16 : }
+     704             : 
+     705             : //mapping of a [alpha_size_]x[alpha_size_] symmetric matrix into a vector of size sym_alpha_size_, useful for the communicator
+     706        4632 : inline unsigned VesDeltaF::get_index(const unsigned i, const unsigned j) const
+     707             : {
+     708        4632 :   if(i<=j)
+     709        4632 :     return j+i*(alpha_size_-1)-i*(i-1)/2;
+     710             :   else
+     711           0 :     return get_index(j,i);
+     712             : }
+     713             : 
+     714             : }
+     715             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesLinearExpansion.cpp.func-sort-c.html b/coverage/ves/VesLinearExpansion.cpp.func-sort-c.html new file mode 100644 index 000000000000..f17f6bf2df82 --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.func-sort-c.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesLinearExpansion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesLinearExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13914496.5 %
Date:2024-02-22 21:58:45Functions:182185.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18VesLinearExpansionC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves18VesLinearExpansionD2Ev0
_ZNK4PLMD3ves18VesLinearExpansion23calculateReweightFactorEv0
_ZN4PLMD3ves18VesLinearExpansion26restartTargetDistributionsEv8
_ZN4PLMD3ves18VesLinearExpansion25writeTargetDistProjToFileEv13
_ZN4PLMD3ves18VesLinearExpansion22setupFesProjFileOutputEv17
_ZN4PLMD3ves18VesLinearExpansion18resetFesFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion18writeFesProjToFileEv36
_ZN4PLMD3ves18VesLinearExpansion19resetBiasFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion21writeTargetDistToFileEv82
_ZN4PLMD3ves18VesLinearExpansion18setupFesFileOutputEv83
_ZN4PLMD3ves18VesLinearExpansion19setupBiasFileOutputEv87
_ZN4PLMD3ves18VesLinearExpansionC1ERKNS_13ActionOptionsE90
_ZN4PLMD3ves18VesLinearExpansionD0Ev90
_ZN4PLMD3ves18VesLinearExpansionD1Ev90
_ZN4PLMD3ves18VesLinearExpansion16registerKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves18VesLinearExpansion14writeFesToFileEv169
_ZN4PLMD3ves18VesLinearExpansion15writeBiasToFileEv173
_ZN4PLMD3ves18VesLinearExpansion25updateTargetDistributionsEv355
_ZN4PLMD3ves18VesLinearExpansion6updateEv23750
_ZN4PLMD3ves18VesLinearExpansion9calculateEv23750
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesLinearExpansion.cpp.func.html b/coverage/ves/VesLinearExpansion.cpp.func.html new file mode 100644 index 000000000000..3914efff1c01 --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.func.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesLinearExpansion.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesLinearExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13914496.5 %
Date:2024-02-22 21:58:45Functions:182185.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves18VesLinearExpansion14writeFesToFileEv169
_ZN4PLMD3ves18VesLinearExpansion15writeBiasToFileEv173
_ZN4PLMD3ves18VesLinearExpansion16registerKeywordsERNS_8KeywordsE92
_ZN4PLMD3ves18VesLinearExpansion18resetFesFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion18setupFesFileOutputEv83
_ZN4PLMD3ves18VesLinearExpansion18writeFesProjToFileEv36
_ZN4PLMD3ves18VesLinearExpansion19resetBiasFileOutputEv36
_ZN4PLMD3ves18VesLinearExpansion19setupBiasFileOutputEv87
_ZN4PLMD3ves18VesLinearExpansion21writeTargetDistToFileEv82
_ZN4PLMD3ves18VesLinearExpansion22setupFesProjFileOutputEv17
_ZN4PLMD3ves18VesLinearExpansion25updateTargetDistributionsEv355
_ZN4PLMD3ves18VesLinearExpansion25writeTargetDistProjToFileEv13
_ZN4PLMD3ves18VesLinearExpansion26restartTargetDistributionsEv8
_ZN4PLMD3ves18VesLinearExpansion6updateEv23750
_ZN4PLMD3ves18VesLinearExpansion9calculateEv23750
_ZN4PLMD3ves18VesLinearExpansionC1ERKNS_13ActionOptionsE90
_ZN4PLMD3ves18VesLinearExpansionC2ERKNS_13ActionOptionsE0
_ZN4PLMD3ves18VesLinearExpansionD0Ev90
_ZN4PLMD3ves18VesLinearExpansionD1Ev90
_ZN4PLMD3ves18VesLinearExpansionD2Ev0
_ZNK4PLMD3ves18VesLinearExpansion23calculateReweightFactorEv0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesLinearExpansion.cpp.gcov.html b/coverage/ves/VesLinearExpansion.cpp.gcov.html new file mode 100644 index 000000000000..d8a098646da8 --- /dev/null +++ b/coverage/ves/VesLinearExpansion.cpp.gcov.html @@ -0,0 +1,634 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesLinearExpansion.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesLinearExpansion.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:13914496.5 %
Date:2024-02-22 21:58:45Functions:182185.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "VesBias.h"
+      24             : #include "LinearBasisSetExpansion.h"
+      25             : #include "CoeffsVector.h"
+      26             : #include "CoeffsMatrix.h"
+      27             : #include "BasisFunctions.h"
+      28             : #include "Optimizer.h"
+      29             : #include "TargetDistribution.h"
+      30             : #include "VesTools.h"
+      31             : 
+      32             : #include "bias/Bias.h"
+      33             : #include "core/ActionRegister.h"
+      34             : #include "core/ActionSet.h"
+      35             : #include "core/PlumedMain.h"
+      36             : 
+      37             : 
+      38             : namespace PLMD {
+      39             : namespace ves {
+      40             : 
+      41             : //+PLUMEDOC VES_BIAS VES_LINEAR_EXPANSION
+      42             : /*
+      43             : Linear basis set expansion bias.
+      44             : 
+      45             : This VES bias action takes the bias potential to be a linear expansion
+      46             : in some basis set that is written as a product of one-dimensional basis functions.
+      47             : For example, for one CV the bias would be written as
+      48             : \f[
+      49             : V(s_{1};\boldsymbol{\alpha}) = \sum_{i_{1}} \alpha_{i_{1}} \, f_{i_{1}}(s_{1}),
+      50             : \f]
+      51             : while for two CVs it is written as
+      52             : \f[
+      53             : V(s_{1},s_{2};\boldsymbol{\alpha}) = \sum_{i_{1},i_{2}} \alpha_{i_{1},i_{2}} \, f_{i_{1}}(s_{1}) \, f_{i_{2}}(s_{2})
+      54             : \f]
+      55             : where \f$\boldsymbol{\alpha}\f$ is the set of expansion coefficients that
+      56             : are optimized within VES. With an appropriate choice of the basis functions
+      57             : it is possible to represent any generic free energy surface.
+      58             : The relationship between the bias and the free energy surface is given by
+      59             : \f[
+      60             : V(\mathbf{s}) = - F(\mathbf{s}) - \frac{1}{\beta} \log p(\mathbf{s}).
+      61             : \f]
+      62             : where \f$p(\mathbf{s})\f$ is the target distribution that is employed in the VES simulation.
+      63             : 
+      64             : \par Basis Functions
+      65             : 
+      66             : Various one-dimensional basis functions are available in the VES code,
+      67             : see the complete list \ref ves_basisf "here".
+      68             : At the current moment we recommend to use Legendre polynomials (\ref BF_LEGENDRE)
+      69             : for non-periodic CVs and Fourier basis functions (\ref BF_FOURIER)
+      70             : for periodic CV (e.g. dihedral angles).
+      71             : 
+      72             : To use basis functions within VES_LINEAR_EXPANSION you first need to
+      73             : define them in the input file before the VES_LINEAR_EXPANSION action and
+      74             : then give their labels using the BASIS_FUNCTIONS keyword.
+      75             : 
+      76             : 
+      77             : \par Target Distributions
+      78             : 
+      79             : Various target distributions \f$p(\mathbf{s})\f$ are available in the VES code,
+      80             : see the complete list \ref ves_targetdist "here".
+      81             : 
+      82             : To use a target distribution within VES_LINEAR_EXPANSION you first need to
+      83             : define it in the input file before the VES_LINEAR_EXPANSION action and
+      84             : then give its label using the TARGET_DISTRIBUTION keyword.
+      85             : The default behavior if no TARGET_DISTRIBUTION is given is to
+      86             : employ a uniform target distribution.
+      87             : 
+      88             : Some target distribution, like the well-tempered one (\ref TD_WELLTEMPERED),
+      89             : are dynamic and need to be iteratively updated during the optimization.
+      90             : 
+      91             : \par Optimizer
+      92             : 
+      93             : In order to optimize the coefficients you will need to use VES_LINEAR_EXPANSION
+      94             : in combination with an optimizer, see the list of optimizers available in the
+      95             : VES code \ref ves_optimizer "here". At the current moment we recommend to
+      96             : use the averaged stochastic gradient decent optimizer (\ref OPT_AVERAGED_SGD).
+      97             : 
+      98             : The optimizer should be defined after the VES_LINEAR_EXPANSION action.
+      99             : 
+     100             : \par Grid
+     101             : 
+     102             : Internally the code uses grids to calculate the basis set averages
+     103             : over the target distribution that is needed for the gradient. The same grid is
+     104             : also used for the output files (see next section).
+     105             : The size of the grid is determined by the GRID_BINS keyword. By default it has
+     106             : 100 grid points in each dimension, and generally this value should be sufficient.
+     107             : 
+     108             : \par Outputting Free Energy Surfaces and Other Files
+     109             : 
+     110             : It is possible to output on-the-fly during the simulation the free energy surface
+     111             : estimated from the bias potential. How often this is done is specified within
+     112             : the \ref ves_optimizer "optimizer" by using the FES_OUTPUT keyword. The filename
+     113             : is specified by the FES_FILE keyword, but by default is it fes.LABEL.data,
+     114             : with an added suffix indicating
+     115             : the iteration number (iter-#).
+     116             : 
+     117             : For multi-dimensional case is it possible to also output projections of the
+     118             : free energy surfaces. The arguments for which to do these projections is
+     119             : specified using the numbered PROJ_ARG keywords. For these files a suffix
+     120             : indicating the projection (proj-#) will be added to the filenames.
+     121             : You will also need to specify the frequency of the output by using the
+     122             : FES_PROJ_OUTPUT keyword within the optimizer.
+     123             : 
+     124             : It is also possible to output the bias potential itself, for this the relevant
+     125             : keyword is BIAS_OUTPUT within the optimizer. The filename
+     126             : is specified by the BIAS_FILE keyword, but by default is it bias.LABEL.data,
+     127             : with an added suffix indicating the iteration number (iter-#).
+     128             : 
+     129             : Furthermore is it possible to output the target distribution, and its projections
+     130             : (i.e. marginal distributions). The filenames of these files are specified with
+     131             : the TARGETDIST_FILE, but by default is it targetdist.LABEL.data. The
+     132             : logarithm of the target distribution will also be outputted to file that has the
+     133             : added suffix log. For static target distribution these files will be outputted in
+     134             : the beginning of the
+     135             : simulation while for dynamic ones you will need to specify the frequency
+     136             : of the output by using the TARGETDIST_OUTPUT and TARGETDIST_PROJ_OUTPUT
+     137             : keywords within the optimizer.
+     138             : 
+     139             : It is also possible to output free energy surfaces and bias in post processing
+     140             : by using the \ref VES_OUTPUT_FES action. However, be aware that this action
+     141             : does does not support dynamic target distribution (e.g. well-tempered).
+     142             : 
+     143             : \par Static Bias
+     144             : 
+     145             : It is also possible to use VES_LINEAR_EXPANSION as a static bias that uses
+     146             : previously obtained coefficients. In this case the coefficients should be
+     147             : read in from the coefficient file given in the COEFFS keyword.
+     148             : 
+     149             : \par Bias Cutoff
+     150             : 
+     151             : It is possible to impose a cutoff on the bias potential using the procedure
+     152             : introduced in \cite McCarty-PRL-2015 such that the free energy surface
+     153             : is only flooded up to a certain value. The bias that results from this procedure
+     154             : can then be used as a static bias for obtaining kinetic rates.
+     155             : The value of the cutoff is given by the BIAS_CUTOFF keyword.
+     156             : To impose the cutoff the code uses a Fermi switching function \f$1/(1+e^{\lambda x})\f$
+     157             : where the parameter \f$\lambda\f$ controls how sharply the switchingfunction goes to zero.
+     158             : The default value is \f$\lambda=10\f$ but this can be changed by using the
+     159             : BIAS_CUTOFF_FERMI_LAMBDA keyword.
+     160             : 
+     161             : \par Examples
+     162             : 
+     163             : In the following example we run a VES_LINEAR_EXPANSION for one CV using
+     164             : a Legendre basis functions (\ref BF_LEGENDRE) and a uniform target
+     165             : distribution as no target distribution is specified. The coefficients
+     166             : are optimized using averaged stochastic gradient descent optimizer
+     167             : (\ref OPT_AVERAGED_SGD). Within the optimizer we specify that the
+     168             : FES should be outputted to file every 500 coefficients iterations (the
+     169             : FES_OUTPUT keyword).
+     170             : Parameters that are very specific to the problem at hand, like the
+     171             : order of the basis functions, the interval on which the
+     172             : basis functions are defined, and the step size used
+     173             : in the optimizer, are left unfilled.
+     174             : \plumedfile
+     175             : bf1: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     176             : 
+     177             : VES_LINEAR_EXPANSION ...
+     178             :  ARG=d1
+     179             :  BASIS_FUNCTIONS=bf1
+     180             :  TEMP=__FILL__
+     181             :  GRID_BINS=200
+     182             :  LABEL=b1
+     183             : ... VES_LINEAR_EXPANSION
+     184             : 
+     185             : OPT_AVERAGED_SGD ...
+     186             :  BIAS=b1
+     187             :  STRIDE=1000
+     188             :  LABEL=o1
+     189             :  STEPSIZE=__FILL__
+     190             :  FES_OUTPUT=500
+     191             :  COEFFS_OUTPUT=10
+     192             : ... OPT_AVERAGED_SGD
+     193             : \endplumedfile
+     194             : 
+     195             : In the following example we employ VES_LINEAR_EXPANSION for two CVs,
+     196             : The first CV is periodic and therefore we employ a Fourier basis functions
+     197             : (\ref BF_LEGENDRE) while the second CV is non-periodic so we employ a
+     198             : Legendre polynomials as in the previous example. For the target distribution
+     199             : we employ a well-tempered target distribution (\ref TD_WELLTEMPERED), which is
+     200             : dynamic and needs to be iteratively updated with a stride that is given
+     201             : using the TARGETDIST_STRIDE within the optimizer.
+     202             : 
+     203             : \plumedfile
+     204             : bf1: BF_FOURIER  ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     205             : bf2: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     206             : 
+     207             : td_wt: TD_WELLTEMPERED BIASFACTOR=10.0
+     208             : 
+     209             : VES_LINEAR_EXPANSION ...
+     210             :  ARG=cv1,cv2
+     211             :  BASIS_FUNCTIONS=bf1,bf2
+     212             :  TEMP=__FILL__
+     213             :  GRID_BINS=100
+     214             :  LABEL=b1
+     215             :  TARGET_DISTRIBUTION=td_wt
+     216             : ... VES_LINEAR_EXPANSION
+     217             : 
+     218             : OPT_AVERAGED_SGD ...
+     219             :  BIAS=b1
+     220             :  STRIDE=1000
+     221             :  LABEL=o1
+     222             :  STEPSIZE=__FILL__
+     223             :  FES_OUTPUT=500
+     224             :  COEFFS_OUTPUT=10
+     225             :  TARGETDIST_STRIDE=500
+     226             : ... OPT_AVERAGED_SGD
+     227             : \endplumedfile
+     228             : 
+     229             : 
+     230             : In the following example we employ a bias cutoff such that the bias
+     231             : only fills the free energy landscape up a certain level. In this case
+     232             : the target distribution is also dynamic and needs to iteratively updated.
+     233             : 
+     234             : \plumedfile
+     235             : bf1: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     236             : bf2: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     237             : 
+     238             : VES_LINEAR_EXPANSION ...
+     239             :  ARG=cv1,cv2
+     240             :  BASIS_FUNCTIONS=bf1,bf2
+     241             :  TEMP=__FILL__
+     242             :  GRID_BINS=100
+     243             :  LABEL=b1
+     244             :  BIAS_CUTOFF=20.0
+     245             : ... VES_LINEAR_EXPANSION
+     246             : 
+     247             : OPT_AVERAGED_SGD ...
+     248             :  BIAS=b1
+     249             :  STRIDE=1000
+     250             :  LABEL=o1
+     251             :  STEPSIZE=__FILL__
+     252             :  FES_OUTPUT=500
+     253             :  COEFFS_OUTPUT=10
+     254             :  TARGETDIST_STRIDE=500
+     255             : ... OPT_AVERAGED_SGD
+     256             : \endplumedfile
+     257             : 
+     258             : The optimized bias potential can then be used as a static bias for obtaining
+     259             : kinetics. For this you need read in the final coefficients from file
+     260             : (e.g. coeffs_final.data in this case) by using the
+     261             : COEFFS keyword (also, no optimizer should be defined in the input)
+     262             : \plumedfile
+     263             : bf1: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     264             : bf2: BF_LEGENDRE ORDER=__FILL__ MINIMUM=__FILL__ MAXIMUM=__FILL__
+     265             : 
+     266             : VES_LINEAR_EXPANSION ...
+     267             :  ARG=cv1,cv2
+     268             :  BASIS_FUNCTIONS=bf1,bf2
+     269             :  TEMP=__FILL__
+     270             :  GRID_BINS=100
+     271             :  LABEL=b1
+     272             :  BIAS_CUTOFF=20.0
+     273             :  COEFFS=coeffs_final.data
+     274             : ... VES_LINEAR_EXPANSION
+     275             : \endplumedfile
+     276             : 
+     277             : 
+     278             : 
+     279             : */
+     280             : //+ENDPLUMEDOC
+     281             : 
+     282             : 
+     283             : class VesLinearExpansion : public VesBias {
+     284             : private:
+     285             :   unsigned int nargs_;
+     286             :   std::vector<BasisFunctions*> basisf_pntrs_;
+     287             :   std::unique_ptr<LinearBasisSetExpansion> bias_expansion_pntr_;
+     288             :   size_t ncoeffs_;
+     289             :   Value* valueForce2_;
+     290             :   bool all_values_inside;
+     291             :   std::vector<double> bf_values;
+     292             :   bool bf_values_set;
+     293             : public:
+     294             :   explicit VesLinearExpansion(const ActionOptions&);
+     295             :   ~VesLinearExpansion();
+     296             :   void calculate() override;
+     297             :   void update() override;
+     298             :   void updateTargetDistributions() override;
+     299             :   void restartTargetDistributions() override;
+     300             :   //
+     301             :   void setupBiasFileOutput() override;
+     302             :   void writeBiasToFile() override;
+     303             :   void resetBiasFileOutput() override;
+     304             :   //
+     305             :   void setupFesFileOutput() override;
+     306             :   void writeFesToFile() override;
+     307             :   void resetFesFileOutput() override;
+     308             :   //
+     309             :   void setupFesProjFileOutput() override;
+     310             :   void writeFesProjToFile() override;
+     311             :   //
+     312             :   void writeTargetDistToFile() override;
+     313             :   void writeTargetDistProjToFile() override;
+     314             :   //
+     315             :   double calculateReweightFactor() const override;
+     316             :   //
+     317             :   static void registerKeywords( Keywords& keys );
+     318             : };
+     319             : 
+     320             : PLUMED_REGISTER_ACTION(VesLinearExpansion,"VES_LINEAR_EXPANSION")
+     321             : 
+     322          92 : void VesLinearExpansion::registerKeywords( Keywords& keys ) {
+     323          92 :   VesBias::registerKeywords(keys);
+     324             :   //
+     325          92 :   VesBias::useInitialCoeffsKeywords(keys);
+     326          92 :   VesBias::useTargetDistributionKeywords(keys);
+     327          92 :   VesBias::useBiasCutoffKeywords(keys);
+     328          92 :   VesBias::useGridBinKeywords(keys);
+     329          92 :   VesBias::useProjectionArgKeywords(keys);
+     330             :   //
+     331          92 :   keys.use("ARG");
+     332         184 :   keys.add("compulsory","BASIS_FUNCTIONS","the label of the one dimensional basis functions that should be used.");
+     333         184 :   keys.addOutputComponent("force2","default","the instantaneous value of the squared force due to this bias potential.");
+     334          92 : }
+     335             : 
+     336          90 : VesLinearExpansion::VesLinearExpansion(const ActionOptions&ao):
+     337             :   PLUMED_VES_VESBIAS_INIT(ao),
+     338          90 :   nargs_(getNumberOfArguments()),
+     339          90 :   basisf_pntrs_(0),
+     340          90 :   valueForce2_(NULL),
+     341          90 :   all_values_inside(true),
+     342          90 :   bf_values(0),
+     343          90 :   bf_values_set(false)
+     344             : {
+     345             :   std::vector<std::string> basisf_labels;
+     346          90 :   parseMultipleValues("BASIS_FUNCTIONS",basisf_labels,nargs_);
+     347          90 :   checkRead();
+     348             : 
+     349          90 :   std::string error_msg = "";
+     350         180 :   basisf_pntrs_ = VesTools::getPointersFromLabels<BasisFunctions*>(basisf_labels,plumed.getActionSet(),error_msg);
+     351          90 :   if(error_msg.size()>0) {plumed_merror("Error in keyword BASIS_FUNCTIONS of "+getName()+": "+error_msg);}
+     352             :   //
+     353             : 
+     354          90 :   std::vector<Value*> args_pntrs = getArguments();
+     355             :   // check arguments and basis functions
+     356             :   // this is done to avoid some issues with integration of target distribution
+     357             :   // and periodic CVs, needs to be fixed later on.
+     358         207 :   for(unsigned int i=0; i<args_pntrs.size(); i++) {
+     359         117 :     if(args_pntrs[i]->isPeriodic() && !(basisf_pntrs_[i]->arePeriodic()) ) {
+     360           0 :       plumed_merror("argument "+args_pntrs[i]->getName()+" is periodic while the basis functions " + basisf_pntrs_[i]->getLabel()+ " are not. You need to use the COMBINE action to remove the periodicity of the argument if you want to use these basis functions");
+     361             :     }
+     362         117 :     else if(!(args_pntrs[i]->isPeriodic()) && basisf_pntrs_[i]->arePeriodic() ) {
+     363           1 :       log.printf("  warning: argument %s is not periodic while the basis functions %s used for it are periodic\n",args_pntrs[i]->getName().c_str(),basisf_pntrs_[i]->getLabel().c_str());
+     364             :     }
+     365             :   }
+     366             : 
+     367          90 :   addCoeffsSet(args_pntrs,basisf_pntrs_);
+     368          90 :   ncoeffs_ = numberOfCoeffs();
+     369          90 :   bool coeffs_read = readCoeffsFromFiles();
+     370             : 
+     371          90 :   checkThatTemperatureIsGiven();
+     372         180 :   bias_expansion_pntr_ = Tools::make_unique<LinearBasisSetExpansion>(getLabel(),getBeta(),comm,args_pntrs,basisf_pntrs_,getCoeffsPntr());
+     373          90 :   bias_expansion_pntr_->linkVesBias(this);
+     374          90 :   bias_expansion_pntr_->setGridBins(this->getGridBins());
+     375             :   //
+     376          90 :   bf_values.assign(ncoeffs_,0.0);
+     377             : 
+     378             : 
+     379             : 
+     380          90 :   if(getNumberOfTargetDistributionPntrs()==0) {
+     381          45 :     log.printf("  using an uniform target distribution: \n");
+     382          45 :     bias_expansion_pntr_->setupUniformTargetDistribution();
+     383             :     disableStaticTargetDistFileOutput();
+     384             :   }
+     385          45 :   else if(getNumberOfTargetDistributionPntrs()==1) {
+     386          51 :     if(biasCutoffActive()) {getTargetDistributionPntrs()[0]->setupBiasCutoff();}
+     387          45 :     bias_expansion_pntr_->setupTargetDistribution(getTargetDistributionPntrs()[0]);
+     388          90 :     log.printf("  using target distribution of type %s with label %s \n",getTargetDistributionPntrs()[0]->getName().c_str(),getTargetDistributionPntrs()[0]->getLabel().c_str());
+     389             :   }
+     390             :   else {
+     391           0 :     plumed_merror("problem with the TARGET_DISTRIBUTION keyword, either give no label or just one label.");
+     392             :   }
+     393          90 :   setTargetDistAverages(bias_expansion_pntr_->TargetDistAverages());
+     394             :   //
+     395          90 :   if(coeffs_read && biasCutoffActive()) {
+     396           1 :     VesLinearExpansion::updateTargetDistributions();
+     397             :   }
+     398             :   //
+     399          90 :   if(coeffs_read) {
+     400           4 :     VesLinearExpansion::setupBiasFileOutput();
+     401           4 :     VesLinearExpansion::writeBiasToFile();
+     402             :   }
+     403             : 
+     404         180 :   addComponent("force2"); componentIsNotPeriodic("force2");
+     405          90 :   valueForce2_=getPntrToComponent("force2");
+     406          90 : }
+     407             : 
+     408             : 
+     409         180 : VesLinearExpansion::~VesLinearExpansion() {
+     410         270 : }
+     411             : 
+     412             : 
+     413       23750 : void VesLinearExpansion::calculate() {
+     414             : 
+     415       23750 :   std::vector<double> cv_values(nargs_);
+     416       23750 :   std::vector<double> forces(nargs_);
+     417             : 
+     418       60967 :   for(unsigned int k=0; k<nargs_; k++) {
+     419       37217 :     cv_values[k]=getArgument(k);
+     420             :   }
+     421             : 
+     422       23750 :   all_values_inside = true;
+     423       23750 :   double bias = bias_expansion_pntr_->getBiasAndForces(cv_values,all_values_inside,forces,bf_values);
+     424       23750 :   if(biasCutoffActive()) {
+     425          63 :     applyBiasCutoff(bias,forces,bf_values);
+     426          63 :     bf_values[0]=1.0;
+     427             :   }
+     428             :   double totalForce2 = 0.0;
+     429       23750 :   if(all_values_inside) {
+     430       60408 :     for(unsigned int k=0; k<nargs_; k++) {
+     431       36852 :       setOutputForce(k,forces[k]);
+     432       36852 :       totalForce2 += forces[k]*forces[k];
+     433             :     }
+     434             :   }
+     435             : 
+     436       23750 :   setBias(bias);
+     437       23750 :   valueForce2_->set(totalForce2);
+     438             : 
+     439       23750 :   bf_values_set = true;
+     440       23750 : }
+     441             : 
+     442             : 
+     443       23750 : void VesLinearExpansion::update() {
+     444       23750 :   if(!bf_values_set) {
+     445           0 :     warning("VesLinearExpansion::update() is being called without calling VesLinearExpansion::calculate() first to calculate the basis function values. This can lead to incorrect behavior.");
+     446             :   }
+     447       23750 :   if(all_values_inside && bf_values_set) {
+     448       23556 :     addToSampledAverages(bf_values);
+     449             :   }
+     450             :   std::fill(bf_values.begin(), bf_values.end(), 0.0);
+     451       23750 :   bf_values_set = false;
+     452       23750 : }
+     453             : 
+     454             : 
+     455             : 
+     456             : 
+     457             : 
+     458             : 
+     459         355 : void VesLinearExpansion::updateTargetDistributions() {
+     460         355 :   bias_expansion_pntr_->updateTargetDistribution();
+     461         355 :   setTargetDistAverages(bias_expansion_pntr_->TargetDistAverages());
+     462         355 : }
+     463             : 
+     464             : 
+     465           8 : void VesLinearExpansion::restartTargetDistributions() {
+     466          16 :   bias_expansion_pntr_->readInRestartTargetDistribution(getCurrentTargetDistOutputFilename());
+     467           8 :   bias_expansion_pntr_->restartTargetDistribution();
+     468           8 :   setTargetDistAverages(bias_expansion_pntr_->TargetDistAverages());
+     469           8 : }
+     470             : 
+     471             : 
+     472          87 : void VesLinearExpansion::setupBiasFileOutput() {
+     473          87 :   bias_expansion_pntr_->setupBiasGrid(true);
+     474          87 : }
+     475             : 
+     476             : 
+     477         173 : void VesLinearExpansion::writeBiasToFile() {
+     478         173 :   bias_expansion_pntr_->updateBiasGrid();
+     479         519 :   auto ofile_pntr = getOFile(getCurrentBiasOutputFilename(),useMultipleWalkers());
+     480         173 :   bias_expansion_pntr_->writeBiasGridToFile(*ofile_pntr);
+     481         173 :   if(biasCutoffActive()) {
+     482           5 :     bias_expansion_pntr_->updateBiasWithoutCutoffGrid();
+     483          15 :     auto ofile_pntr2 = getOFile(getCurrentBiasOutputFilename("without-cutoff"),useMultipleWalkers());
+     484           5 :     bias_expansion_pntr_->writeBiasWithoutCutoffGridToFile(*ofile_pntr2);
+     485           5 :   }
+     486         173 : }
+     487             : 
+     488             : 
+     489          36 : void VesLinearExpansion::resetBiasFileOutput() {
+     490             :   bias_expansion_pntr_->resetStepOfLastBiasGridUpdate();
+     491          36 : }
+     492             : 
+     493             : 
+     494          83 : void VesLinearExpansion::setupFesFileOutput() {
+     495          83 :   bias_expansion_pntr_->setupFesGrid();
+     496          83 : }
+     497             : 
+     498             : 
+     499         169 : void VesLinearExpansion::writeFesToFile() {
+     500         169 :   bias_expansion_pntr_->updateFesGrid();
+     501         507 :   auto ofile_pntr = getOFile(getCurrentFesOutputFilename(),useMultipleWalkers());
+     502         169 :   bias_expansion_pntr_->writeFesGridToFile(*ofile_pntr);
+     503         169 : }
+     504             : 
+     505             : 
+     506          36 : void VesLinearExpansion::resetFesFileOutput() {
+     507             :   bias_expansion_pntr_->resetStepOfLastFesGridUpdate();
+     508          36 : }
+     509             : 
+     510             : 
+     511          17 : void VesLinearExpansion::setupFesProjFileOutput() {
+     512          17 :   if(getNumberOfProjectionArguments()>0) {
+     513           8 :     bias_expansion_pntr_->setupFesProjGrid();
+     514             :   }
+     515          17 : }
+     516             : 
+     517             : 
+     518          36 : void VesLinearExpansion::writeFesProjToFile() {
+     519          36 :   bias_expansion_pntr_->updateFesGrid();
+     520          72 :   for(unsigned int i=0; i<getNumberOfProjectionArguments(); i++) {
+     521             :     std::string suffix;
+     522          36 :     Tools::convert(i+1,suffix);
+     523          36 :     suffix = "proj-" + suffix;
+     524          72 :     auto ofile_pntr = getOFile(getCurrentFesOutputFilename(suffix),useMultipleWalkers());
+     525             :     std::vector<std::string> args = getProjectionArgument(i);
+     526          36 :     bias_expansion_pntr_->writeFesProjGridToFile(args,*ofile_pntr);
+     527          36 :   }
+     528          36 : }
+     529             : 
+     530             : 
+     531          82 : void VesLinearExpansion::writeTargetDistToFile() {
+     532         164 :   auto ofile1_pntr = getOFile(getCurrentTargetDistOutputFilename(),useMultipleWalkers());
+     533         164 :   auto ofile2_pntr = getOFile(getCurrentTargetDistOutputFilename("log"),useMultipleWalkers());
+     534          82 :   bias_expansion_pntr_->writeTargetDistGridToFile(*ofile1_pntr);
+     535          82 :   bias_expansion_pntr_->writeLogTargetDistGridToFile(*ofile2_pntr);
+     536          82 : }
+     537             : 
+     538             : 
+     539          13 : void VesLinearExpansion::writeTargetDistProjToFile() {
+     540          33 :   for(unsigned int i=0; i<getNumberOfProjectionArguments(); i++) {
+     541             :     std::string suffix;
+     542          20 :     Tools::convert(i+1,suffix);
+     543          20 :     suffix = "proj-" + suffix;
+     544          40 :     auto ofile_pntr = getOFile(getCurrentTargetDistOutputFilename(suffix),useMultipleWalkers());
+     545             :     std::vector<std::string> args = getProjectionArgument(i);
+     546          20 :     bias_expansion_pntr_->writeTargetDistProjGridToFile(args,*ofile_pntr);
+     547          20 :   }
+     548          13 : }
+     549             : 
+     550             : 
+     551           0 : double VesLinearExpansion::calculateReweightFactor() const {
+     552           0 :   return bias_expansion_pntr_->calculateReweightFactor();
+     553             : }
+     554             : 
+     555             : 
+     556             : }
+     557             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.cpp.func-sort-c.html b/coverage/ves/VesTools.cpp.func-sort-c.html new file mode 100644 index 000000000000..d8d84f1d1798 --- /dev/null +++ b/coverage/ves/VesTools.cpp.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353892.1 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8VesTools14copyGridValuesEPNS_8GridBaseES3_8
_ZN4PLMD3ves8VesTools15getGridFileInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS7_RSt6vectorIS7_SaIS7_EESE_SE_RSB_IbSaIbEERSB_IjSaIjEERb9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.cpp.func.html b/coverage/ves/VesTools.cpp.func.html new file mode 100644 index 000000000000..127a76be23ee --- /dev/null +++ b/coverage/ves/VesTools.cpp.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353892.1 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8VesTools14copyGridValuesEPNS_8GridBaseES3_8
_ZN4PLMD3ves8VesTools15getGridFileInfoERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERS7_RSt6vectorIS7_SaIS7_EESE_SE_RSB_IbSaIbEERSB_IjSaIjEERb9
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.cpp.gcov.html b/coverage/ves/VesTools.cpp.gcov.html new file mode 100644 index 000000000000..cdc4878a5cf5 --- /dev/null +++ b/coverage/ves/VesTools.cpp.gcov.html @@ -0,0 +1,171 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:353892.1 %
Date:2024-02-22 21:58:45Functions:22100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "VesTools.h"
+      24             : 
+      25             : #include "tools/Grid.h"
+      26             : #include "tools/IFile.h"
+      27             : #include "tools/Exception.h"
+      28             : 
+      29             : 
+      30             : namespace PLMD {
+      31             : namespace ves {
+      32             : 
+      33             : 
+      34           8 : void VesTools::copyGridValues(GridBase* grid_pntr_orig, GridBase* grid_pntr_copy) {
+      35             :   // plumed_massert(grid_pntr_orig!=NULL,"grid not defined");
+      36             :   // plumed_massert(grid_pntr_copy!=NULL,"grid not defined");
+      37           8 :   plumed_massert(grid_pntr_orig->getSize()==grid_pntr_copy->getSize(),"the two grids are not of the same size");
+      38           8 :   plumed_massert(grid_pntr_orig->getDimension()==grid_pntr_copy->getDimension(),"the two grids are not of the same dimension");
+      39             :   //
+      40         808 :   for(Grid::index_t i=0; i<grid_pntr_orig->getSize(); i++) {
+      41         800 :     double value = grid_pntr_orig->getValue(i);
+      42         800 :     grid_pntr_copy->setValue(i,value);
+      43             :   }
+      44           8 : }
+      45             : 
+      46             : 
+      47           9 : unsigned int VesTools::getGridFileInfo(const std::string& filepath, std::string& grid_label, std::vector<std::string>& arg_labels, std::vector<std::string>& arg_min, std::vector<std::string>& arg_max, std::vector<bool>& arg_periodic, std::vector<unsigned int>& arg_nbins, bool& derivatives) {
+      48             : 
+      49           9 :   IFile ifile; ifile.open(filepath);
+      50             :   std::vector<std::string> fields;
+      51           9 :   ifile.scanFieldList(fields);
+      52           9 :   ifile.allowIgnoredFields();
+      53           9 :   ifile.scanField();
+      54             : 
+      55             :   unsigned int nargs=0;
+      56          31 :   for(unsigned int i=0; i<fields.size(); i++) {
+      57          31 :     if(fields[i]=="min_"+fields[0]) {
+      58           9 :       derivatives = false;
+      59           9 :       nargs = i-1;
+      60           9 :       break;
+      61             :     }
+      62          22 :     else if(fields[i]=="der_"+fields[0]) {
+      63           0 :       derivatives = true;
+      64           0 :       nargs = i-1;
+      65           0 :       break;
+      66             :     }
+      67             :   }
+      68             : 
+      69           9 :   grid_label = fields[nargs];
+      70             : 
+      71           9 :   arg_labels.assign(nargs,"");
+      72           9 :   arg_min.assign(nargs,"");
+      73          18 :   arg_max.assign(nargs,"");
+      74             :   arg_periodic.assign(nargs,false);
+      75           9 :   arg_nbins.assign(nargs,0);
+      76          22 :   for(unsigned int i=0; i<nargs; i++) {
+      77          13 :     arg_labels[i] = fields[i];
+      78          26 :     ifile.scanField("min_"+arg_labels[i],arg_min[i]);
+      79          26 :     ifile.scanField("max_"+arg_labels[i],arg_max[i]);
+      80             :     std::string str_periodic;
+      81          26 :     ifile.scanField("periodic_"+arg_labels[i],str_periodic);
+      82          13 :     if(str_periodic=="true") {arg_periodic[i]=true;}
+      83             :     int nbins;
+      84          13 :     ifile.scanField("nbins_"+arg_labels[i],nbins);
+      85          13 :     arg_nbins[i] = static_cast<unsigned int>(nbins);
+      86             :   }
+      87           9 :   ifile.scanField();
+      88           9 :   ifile.close();
+      89           9 :   return nargs;
+      90           9 : }
+      91             : 
+      92             : 
+      93             : }
+      94             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.h.func-sort-c.html b/coverage/ves/VesTools.h.func-sort-c.html new file mode 100644 index 000000000000..108e57724207 --- /dev/null +++ b/coverage/ves/VesTools.h.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:213265.6 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_7VesBiasEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_82
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_14BasisFunctionsEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_163
_ZN4PLMD3ves8VesTools14convertDbl2StrEdRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj167
_ZN4PLMD3ves8VesTools19getPointerFromLabelIPNS0_18TargetDistributionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_9ActionSetERSB_296
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_18TargetDistributionEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_417
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.h.func.html b/coverage/ves/VesTools.h.func.html new file mode 100644 index 000000000000..1c5a310575f7 --- /dev/null +++ b/coverage/ves/VesTools.h.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:213265.6 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves8VesTools14convertDbl2StrEdRNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEj167
_ZN4PLMD3ves8VesTools19getPointerFromLabelIPNS0_18TargetDistributionEEET_RKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS_9ActionSetERSB_296
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_14BasisFunctionsEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_163
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_18TargetDistributionEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_417
_ZN4PLMD3ves8VesTools21getPointersFromLabelsIPNS0_7VesBiasEEESt6vectorIT_SaIS6_EERKS5_INSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESaISE_EERKNS_9ActionSetERSE_82
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/VesTools.h.gcov.html b/coverage/ves/VesTools.h.gcov.html new file mode 100644 index 000000000000..85cfe85d97a2 --- /dev/null +++ b/coverage/ves/VesTools.h.gcov.html @@ -0,0 +1,217 @@ + + + + + + + + LCOV - plumed test coverage - ves/VesTools.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - VesTools.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:213265.6 %
Date:2024-02-22 21:58:45Functions:55100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_ves_VesTools_h
+      23             : #define __PLUMED_ves_VesTools_h
+      24             : 
+      25             : #include <string>
+      26             : #include <sstream>
+      27             : #include <iomanip>
+      28             : #include <limits>
+      29             : #include <vector>
+      30             : 
+      31             : #include "core/ActionSet.h"
+      32             : 
+      33             : 
+      34             : namespace PLMD {
+      35             : 
+      36             : class GridBase;
+      37             : 
+      38             : namespace ves {
+      39             : 
+      40             : class VesTools {
+      41             : public:
+      42             :   // Convert double into a string with more digits
+      43             :   static void convertDbl2Str(const double value,std::string& str, unsigned int precision);
+      44             :   static void convertDbl2Str(const double value,std::string& str);
+      45             :   // get log2 of unsigned int
+      46             :   static unsigned int log2(unsigned value);
+      47             :   // copy grid values
+      48             :   static void copyGridValues(GridBase* grid_pntr_orig, GridBase* grid_pntr_copy);
+      49             :   static unsigned int getGridFileInfo(const std::string&, std::string&, std::vector<std::string>&, std::vector<std::string>&, std::vector<std::string>&, std::vector<bool>&, std::vector<unsigned int>&, bool&);
+      50             :   //
+      51             :   template<typename T> static std::vector<std::string> getLabelsOfAvailableActions(const ActionSet&);
+      52             :   template<typename T> static T getPointerFromLabel(const std::string&, const ActionSet&, std::string&);
+      53             :   template<typename T> static std::vector<T> getPointersFromLabels(const std::vector<std::string>&, const ActionSet&, std::string&);
+      54             : 
+      55             : };
+      56             : 
+      57             : inline
+      58         167 : void VesTools::convertDbl2Str(const double value,std::string& str, unsigned int precision) {
+      59         167 :   std::ostringstream ostr;
+      60         167 :   ostr<<std::setprecision(precision)<<value;
+      61         167 :   str=ostr.str();
+      62         167 : }
+      63             : 
+      64             : 
+      65             : inline
+      66             : void VesTools::convertDbl2Str(const double value,std::string& str) {
+      67             :   unsigned int precision = std::numeric_limits<double>::digits10 + 1;
+      68          88 :   convertDbl2Str(value,str,precision);
+      69           9 : }
+      70             : 
+      71             : 
+      72             : inline
+      73             : unsigned int log2(unsigned value) {
+      74             :   unsigned int result = 0;
+      75             :   while(value >>= 1) result++;
+      76             :   return result;
+      77             : }
+      78             : 
+      79             : 
+      80             : template<typename T>
+      81             : std::vector<std::string> VesTools::getLabelsOfAvailableActions(const ActionSet& actionset) {
+      82             :   std::vector<std::string> avail_action_str(0);
+      83             :   std::vector<T> avail_action_pntrs = actionset.select<T>();
+      84             :   for(unsigned int i=0; i<avail_action_pntrs.size(); i++) {
+      85             :     avail_action_str.push_back(avail_action_pntrs[i]->getLabel());
+      86             :   }
+      87             :   return avail_action_str;
+      88             : }
+      89             : 
+      90             : 
+      91             : template<typename T>
+      92         296 : T VesTools::getPointerFromLabel(const std::string& action_label, const ActionSet& actionset, std::string& error_msg) {
+      93         296 :   std::vector<std::string> action_labels(1);
+      94             :   action_labels[0] = action_label;
+      95         296 :   std::vector<T> action_pntrs = getPointersFromLabels<T>(action_labels,actionset,error_msg);
+      96         592 :   return action_pntrs[0];
+      97         296 : }
+      98             : 
+      99             : 
+     100             : template<typename T>
+     101         662 : std::vector<T> VesTools::getPointersFromLabels(const std::vector<std::string>& action_labels, const ActionSet& actionset, std::string& error_msg) {
+     102         662 :   std::vector<T> action_pntrs(action_labels.size(),NULL);
+     103             :   error_msg = "";
+     104         662 :   std::vector<std::string> missing(0);
+     105        1350 :   for(unsigned int i=0; i<action_labels.size(); i++) {
+     106         688 :     action_pntrs[i] = actionset.selectWithLabel<T>(action_labels[i]);
+     107         688 :     if(action_pntrs[i]==NULL) {
+     108           0 :       missing.push_back(action_labels[i]);
+     109             :     }
+     110             :   }
+     111             :   // error handling
+     112         662 :   if(missing.size()>0) {
+     113           0 :     if(missing.size()==1) {
+     114           0 :       error_msg = "label "+missing[0]+" does not exist\n";
+     115             :     }
+     116           0 :     else if(missing.size()>1) {
+     117           0 :       std::string tmp="";
+     118           0 :       for(unsigned int j=0; j<missing.size(); j++) {tmp +=missing[j]+" ";}
+     119           0 :       error_msg = "labels "+tmp+"do not exist\n";
+     120             :     }
+     121           0 :     std::vector<T> avail_action_pntrs = actionset.select<T>();
+     122           0 :     if(avail_action_pntrs.size()>0) {
+     123             :       error_msg += "             Hint! the actions defined in the input file that can be used here are: \n";
+     124           0 :       for(unsigned int i=0; i<avail_action_pntrs.size(); i++) {
+     125           0 :         error_msg += "             " + avail_action_pntrs[i]->getName() + " with label " + avail_action_pntrs[i]->getLabel() + "\n";
+     126             :       }
+     127             :     }
+     128             :     else {
+     129             :       error_msg += "             Hint! no actions defined in the input file that can be used here, they should be defined before this actions\n";
+     130             :     }
+     131             :   }
+     132         662 :   return action_pntrs;
+     133         662 : }
+     134             : 
+     135             : 
+     136             : 
+     137             : }
+     138             : }
+     139             : 
+     140             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletCoeffs.cpp.func-sort-c.html b/coverage/ves/WaveletCoeffs.cpp.func-sort-c.html new file mode 100644 index 000000000000..dd28c33ba740 --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletCoeffs.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletCoeffs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515096.7 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid21getFilterCoefficientsEjbNS1_4TypeE49
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletCoeffs.cpp.func.html b/coverage/ves/WaveletCoeffs.cpp.func.html new file mode 100644 index 000000000000..3f96320a0318 --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletCoeffs.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletCoeffs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515096.7 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid21getFilterCoefficientsEjbNS1_4TypeE49
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletCoeffs.cpp.gcov.html b/coverage/ves/WaveletCoeffs.cpp.gcov.html new file mode 100644 index 000000000000..282793358c27 --- /dev/null +++ b/coverage/ves/WaveletCoeffs.cpp.gcov.html @@ -0,0 +1,1059 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletCoeffs.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletCoeffs.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:14515096.7 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "WaveletGrid.h"
+      24             : #include "tools/Exception.h"
+      25             : 
+      26             : #include <algorithm>
+      27             : #include <vector>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace ves {
+      31             : 
+      32             : // returns the filter coefficients, at the moment simply a lookup table (calculated with python script)
+      33             : // the coefficients are normalized such that their sum equals 2
+      34             : // lowpass coefficients are for the scaling function, highpass for the actual wavelets
+      35          49 : std::vector<double> WaveletGrid::getFilterCoefficients(const unsigned order, const bool lowpass, const Type type) {
+      36             :   std::vector<double> h;
+      37          49 :   if (type == Type::db) {
+      38          24 :     switch(order) {
+      39           1 :     case 4:
+      40           2 :       h = { 3.2580342805129858252399799312116e-01,
+      41             :             1.0109457150918295109676137144561e+00,
+      42             :             8.9220013824675992175627925462322e-01,
+      43             :             -3.9575026235645245631378230655173e-02,
+      44             :             -2.6450716736904000825347793579567e-01,
+      45             :             4.3616300474177409352005696518972e-02,
+      46             :             4.6503601070981823162320267783798e-02,
+      47             :             -1.4986989330361497746446630685568e-02
+      48           1 :           };
+      49           1 :       break;
+      50           1 :     case 5:
+      51           2 :       h = { 2.2641898258355833140065271891217e-01,
+      52             :             8.5394354270502825787758638398373e-01,
+      53             :             1.0243269442591973472644895082340e+00,
+      54             :             1.9576696134780988134416190860065e-01,
+      55             :             -3.4265671538293490661075679781788e-01,
+      56             :             -4.5601131883547744994000794349631e-02,
+      57             :             1.0970265864213350759381881971422e-01,
+      58             :             -8.8268001083581463378502363070766e-03,
+      59             :             -1.7791870101954165156454834573196e-02,
+      60             :             4.7174279390678596629582486343679e-03
+      61           1 :           };
+      62           1 :       break;
+      63           2 :     case 6:
+      64           4 :       h = { 1.5774243200290161137644417976844e-01,
+      65             :             6.9950381407523654075930608087219e-01,
+      66             :             1.0622637598817388226990487964940e+00,
+      67             :             4.4583132293003513435536433462403e-01,
+      68             :             -3.1998659889212388574009082731209e-01,
+      69             :             -1.8351806406029547158453851807280e-01,
+      70             :             1.3788809297474488579915430364053e-01,
+      71             :             3.8923209708329416234295905496765e-02,
+      72             :             -4.4663748330189156909852954413509e-02,
+      73             :             7.8325115229715134342741711392932e-04,
+      74             :             6.7560623629278858393032436424619e-03,
+      75             :             -1.5235338056025088393496957905882e-03
+      76           2 :           };
+      77           2 :       break;
+      78           1 :     case 7:
+      79           2 :       h = { 1.1009943074562379694558700293783e-01,
+      80             :             5.6079128362552554953879280219553e-01,
+      81             :             1.0311484916361983721344586228952e+00,
+      82             :             6.6437248221107991774658785288921e-01,
+      83             :             -2.0351382246269289488793674536282e-01,
+      84             :             -3.1683501128066671181926494682557e-01,
+      85             :             1.0084646500938766744415175935501e-01,
+      86             :             1.1400344515974307479933003151018e-01,
+      87             :             -5.3782452589690873945293958513503e-02,
+      88             :             -2.3439941564206586560592526780056e-02,
+      89             :             1.7749792379361528649184265304939e-02,
+      90             :             6.0751499540213742267535934615807e-04,
+      91             :             -2.5479047181873734281842835969201e-03,
+      92             :             5.0022685312249071977463987792589e-04
+      93           1 :           };
+      94           1 :       break;
+      95           2 :     case 8:
+      96           4 :       h = { 7.6955622108152516025469935811998e-02,
+      97             :             4.4246724715225010937658112197823e-01,
+      98             :             9.5548615042774787120549717656104e-01,
+      99             :             8.2781653242239250367617842130130e-01,
+     100             :             -2.2385735333760647947087818465661e-02,
+     101             :             -4.0165863278097890809448244908708e-01,
+     102             :             6.6819409243975983261898399234724e-04,
+     103             :             1.8207635684731554581716750362830e-01,
+     104             :             -2.4563901045696636543658186724315e-02,
+     105             :             -6.2350206650278829079159237380736e-02,
+     106             :             1.9772159296701483782721098236834e-02,
+     107             :             1.2368844819631834991424668146465e-02,
+     108             :             -6.8877192568836120845077175545157e-03,
+     109             :             -5.5400454895877760883027285387925e-04,
+     110             :             9.5522971129925185115872032781681e-04,
+     111             :             -1.6613726137322542978150274883831e-04
+     112           2 :           };
+     113           2 :       break;
+     114           1 :     case 9:
+     115           2 :       h = { 5.3850349589325587074117862584899e-02,
+     116             :             3.4483430381395580033299097522104e-01,
+     117             :             8.5534906435941493452190798052470e-01,
+     118             :             9.2954571436629451763877796111046e-01,
+     119             :             1.8836954950636755623527562875097e-01,
+     120             :             -4.1475176180187667274168461517547e-01,
+     121             :             -1.3695354902476589153970110146474e-01,
+     122             :             2.1006834227901241551883515512600e-01,
+     123             :             4.3452675461228981723671438430756e-02,
+     124             :             -9.5647264120193975500683336576913e-02,
+     125             :             3.5489281323312395211022618468633e-04,
+     126             :             3.1624165852511730567808712066835e-02,
+     127             :             -6.6796202262771747770742081229400e-03,
+     128             :             -6.0549605750901376935435571624566e-03,
+     129             :             2.6129672804944947123173548675368e-03,
+     130             :             3.2581467135218489857700907563753e-04,
+     131             :             -3.5632975902155574095264700673624e-04,
+     132             :             5.5645514034309739761618301967516e-05
+     133           1 :           };
+     134           1 :       break;
+     135           4 :     case 10:
+     136           8 :       h = { 3.7717157592241430663637657971776e-02,
+     137             :             2.6612218279384214358884719331400e-01,
+     138             :             7.4557507148646740002817523418344e-01,
+     139             :             9.7362811073364052827372461251798e-01,
+     140             :             3.9763774176901656165483700533514e-01,
+     141             :             -3.5333620179411384665257855886011e-01,
+     142             :             -2.7710987872096615181050083265291e-01,
+     143             :             1.8012744853339432427041799655854e-01,
+     144             :             1.3160298710107026787241579768306e-01,
+     145             :             -1.0096657119677993064144061463594e-01,
+     146             :             -4.1659248087601748189445771686223e-02,
+     147             :             4.6969814097397283303436665846675e-02,
+     148             :             5.1004369678145037442229536850391e-03,
+     149             :             -1.5179002335856551370030231851160e-02,
+     150             :             1.9733253649632047886652852497491e-03,
+     151             :             2.8176865901946854600645941957282e-03,
+     152             :             -9.6994783985641268905103506980936e-04,
+     153             :             -1.6470900609077862271692471729523e-04,
+     154             :             1.3235436685110702815550143274237e-04,
+     155             :             -1.8758415627500432871534175038875e-05
+     156           4 :           };
+     157           4 :       break;
+     158           1 :     case 11:
+     159           2 :       h = { 2.6437729433313437304997606247525e-02,
+     160             :             2.0374153520190504962350530604454e-01,
+     161             :             6.3625434846077988382262446975801e-01,
+     162             :             9.6970753662635966740879212011350e-01,
+     163             :             5.8260559778060438951285959774395e-01,
+     164             :             -2.2949185235529601101234220550396e-01,
+     165             :             -3.8782098279100135629349210830696e-01,
+     166             :             9.3399738135533413863065277382702e-02,
+     167             :             2.1186617983636121809176700026001e-01,
+     168             :             -6.5732582904507175225461423906381e-02,
+     169             :             -9.3958631797504951754795854412805e-02,
+     170             :             4.4314509565959142589619546015456e-02,
+     171             :             2.9473489598288812874038455902337e-02,
+     172             :             -2.1729138108983869076551442844902e-02,
+     173             :             -4.7246879281915600545804778676029e-03,
+     174             :             6.9698350902376990032016657039549e-03,
+     175             :             -4.3641620618785245374129933004781e-04,
+     176             :             -1.2629255926067382322097731872645e-03,
+     177             :             3.5235487790788363191354926051702e-04,
+     178             :             7.6988477762888945306503363230632e-05,
+     179             :             -4.8981264369811758688493669167130e-05,
+     180             :             6.3558636358923973935959594872003e-06
+     181           1 :           };
+     182           1 :       break;
+     183           3 :     case 12:
+     184           6 :       h = { 1.8543533036448515277649917720737e-02,
+     185             :             1.5495010900239064577377234854794e-01,
+     186             :             5.3366075005107249662472668205737e-01,
+     187             :             9.2941934664592906756297452375293e-01,
+     188             :             7.2957365443751254208137879686547e-01,
+     189             :             -6.3305694196084630331888831733522e-02,
+     190             :             -4.4714385742734169548739942001703e-01,
+     191             :             -3.3628948114692740201103760000478e-02,
+     192             :             2.5806371934571636916899706193362e-01,
+     193             :             7.5795761219506355491071225571886e-03,
+     194             :             -1.3637561208887127861544286133721e-01,
+     195             :             1.5342987147736677697174023649040e-02,
+     196             :             5.8755309099664532190843146963743e-02,
+     197             :             -1.7279779228315594180598324669518e-02,
+     198             :             -1.8159669147498957303410449526382e-02,
+     199             :             9.4914929220922782115987814677283e-03,
+     200             :             3.1800108566658129814752609121342e-03,
+     201             :             -3.0822835767046288281412191878417e-03,
+     202             :             9.2562090856036967085468392113512e-06,
+     203             :             5.4963843249920504071409643742641e-04,
+     204             :             -1.2516371156799253796382265235820e-04,
+     205             :             -3.4282722782480915088738904206167e-05,
+     206             :             1.8069339114439924513354912560814e-05,
+     207             :             -2.1624340181021667700003892342853e-06
+     208           3 :           };
+     209           3 :       break;
+     210           1 :     case 13:
+     211           2 :       h = { 1.3013782053568881749705532513417e-02,
+     212             :             1.1718349488016345516516736324775e-01,
+     213             :             4.4122943020981653106105113693047e-01,
+     214             :             8.6416347207619259584987503330922e-01,
+     215             :             8.3281561724389663314838117003092e-01,
+     216             :             1.2301639369613130703395853515758e-01,
+     217             :             -4.4543895786553527882389857950329e-01,
+     218             :             -1.7617810218390753118633540452720e-01,
+     219             :             2.5381750565052108026264932050253e-01,
+     220             :             1.0316537133807110460104183857766e-01,
+     221             :             -1.4963456864376814547945571121090e-01,
+     222             :             -3.7460263683081813923525515974688e-02,
+     223             :             7.9393209899753916514164586715196e-02,
+     224             :             3.3657890397617833827537126012430e-03,
+     225             :             -3.3702718379158690120700470060910e-02,
+     226             :             5.5492912148471726374587831287499e-03,
+     227             :             1.0260952934778005268823264373168e-02,
+     228             :             -3.9059323261223279077913872470162e-03,
+     229             :             -1.8606438898585472407204433054062e-03,
+     230             :             1.3185082588273093311126427096269e-03,
+     231             :             6.9652174801158197692090012775878e-05,
+     232             :             -2.3352765515756047508440229609761e-04,
+     233             :             4.3386003918454429126392440929649e-05,
+     234             :             1.4767119831443566670332347146033e-05,
+     235             :             -6.6473927339140924229086634933417e-06,
+     236             :             7.3822444322983881586676402353220e-07
+     237           1 :           };
+     238           1 :       break;
+     239           1 :     case 14:
+     240           2 :       h = { 9.1374508518302227644269919437647e-03,
+     241             :             8.8197087778947372282978278690280e-02,
+     242             :             3.6041270508674011496808020638127e-01,
+     243             :             7.8390652259161064385750705696410e-01,
+     244             :             8.9263441660919018438846705976175e-01,
+     245             :             3.0924705232209759309114360803505e-01,
+     246             :             -3.8422563537411602574422886391403e-01,
+     247             :             -3.0834597516857004118051577279402e-01,
+     248             :             1.9572038841513531015614546504366e-01,
+     249             :             1.9797436583701560897097238012066e-01,
+     250             :             -1.2268078015402955616153235496313e-01,
+     251             :             -1.0118550324745094470824113841445e-01,
+     252             :             7.8117093102298987283838016537629e-02,
+     253             :             3.8157473560976581938852802977635e-02,
+     254             :             -4.2688533533420329468821563523306e-02,
+     255             :             -7.9408791992275871984841018047518e-03,
+     256             :             1.8087074833128147927086004642661e-02,
+     257             :             -1.0553130151236629532401911646389e-03,
+     258             :             -5.4442114973955908763247890647108e-03,
+     259             :             1.5014579323156973956338022802015e-03,
+     260             :             1.0012931187669377956078742286650e-03,
+     261             :             -5.4706298624917549557056251074982e-04,
+     262             :             -5.9081947567055248949751539155884e-05,
+     263             :             9.7234313623187232453887185457120e-05,
+     264             :             -1.4619021425907697688093174470669e-05,
+     265             :             -6.2079802069149134127572231545145e-06,
+     266             :             2.4395108649265364349071390920320e-06,
+     267             :             -2.5273975810449469030721054638167e-07
+     268           1 :           };
+     269           1 :       break;
+     270           1 :     case 15:
+     271           2 :       h = { 6.4184610900818745565787892815024e-03,
+     272             :             6.6105143008711259033916007865628e-02,
+     273             :             2.9136174262291886227771442463563e-01,
+     274             :             6.9668653280553660689378148163087e-01,
+     275             :             9.1331770185222738156483046623180e-01,
+     276             :             4.7942198331894603224867523749708e-01,
+     277             :             -2.7323191454187872873049514055310e-01,
+     278             :             -4.0854168599855755772409793280531e-01,
+     279             :             9.2324037310499082464865239217033e-02,
+     280             :             2.6890806178955328764601517832489e-01,
+     281             :             -5.6096444852683710613483469842322e-02,
+     282             :             -1.5714873480744581679680038632796e-01,
+     283             :             4.7909516391089444764528337827869e-02,
+     284             :             7.7471397590875790140074741429999e-02,
+     285             :             -3.6440051225646634402988155443381e-02,
+     286             :             -2.9429855183644534899478628631186e-02,
+     287             :             2.1331881448689315322608806013704e-02,
+     288             :             7.2139038913583038159504923214627e-03,
+     289             :             -9.1750422042750877371641848867512e-03,
+     290             :             -3.4189530802674857664497087839095e-04,
+     291             :             2.7482751291413886653158815676079e-03,
+     292             :             -5.2818381052845782188537304691067e-04,
+     293             :             -5.0850204513539821755269132452781e-04,
+     294             :             2.2047093037207382386355458692151e-04,
+     295             :             3.6476384955660787364189329151642e-05,
+     296             :             -3.9786489133705268018015993591874e-05,
+     297             :             4.7559820825002058672348846657396e-06,
+     298             :             2.5615231760346128998698331941108e-06,
+     299             :             -8.9334206571767810297517772161191e-07,
+     300             :             8.6738807723125058175416435962690e-08
+     301           1 :           };
+     302           1 :       break;
+     303           1 :     case 16:
+     304           2 :       h = { 4.5102394860307721408121395256785e-03,
+     305             :             4.9366963027983538914167382927189e-02,
+     306             :             2.3343614837332890554755238099460e-01,
+     307             :             6.0855408871050020724879914268968e-01,
+     308             :             9.0135796889724240088526130421087e-01,
+     309             :             6.2266445266940384506426653388189e-01,
+     310             :             -1.2692720787074832089480480590282e-01,
+     311             :             -4.6253736950318169451890071286471e-01,
+     312             :             -3.9482308578843897106658289430925e-02,
+     313             :             2.9866874362698586642395071066858e-01,
+     314             :             3.8664971797927487340285068739831e-02,
+     315             :             -1.8722533722795392518989388008777e-01,
+     316             :             -8.8243005420050348031058007336469e-03,
+     317             :             1.0737308432663163204612288836870e-01,
+     318             :             -1.0732430476938423918875642470994e-02,
+     319             :             -5.2168072309854519874594558359604e-02,
+     320             :             1.4563089924943300318416206096117e-02,
+     321             :             1.9790177710283740619701120522222e-02,
+     322             :             -9.8853733967658469899975060002362e-03,
+     323             :             -5.1537896658028692006836557482075e-03,
+     324             :             4.4236930891221213843489401540410e-03,
+     325             :             5.7685344236866427022891734566201e-04,
+     326             :             -1.3308057204323708866411379858619e-03,
+     327             :             1.6156190702488963770351582116547e-04,
+     328             :             2.4718649272750667844275596074510e-04,
+     329             :             -8.6317891212541529946146445784194e-05,
+     330             :             -1.9722154219490776696404113477179e-05,
+     331             :             1.6032385720093409830870612164944e-05,
+     332             :             -1.4758327456010213390660444285341e-06,
+     333             :             -1.0413783294645852350716365430916e-06,
+     334             :             3.2651137682251684123506938785264e-07,
+     335             :             -2.9830567125395646088604952733681e-08
+     336           1 :           };
+     337           1 :       break;
+     338           1 :     case 17:
+     339           2 :       h = { 3.1703938650899862738974377407430e-03,
+     340             :             3.6748896199244887594836939115339e-02,
+     341             :             1.8556589584340402176998452432599e-01,
+     342             :             5.2375501693137660463861493553850e-01,
+     343             :             8.6407970046528492780169017351000e-01,
+     344             :             7.3300918312113150232534053429845e-01,
+     345             :             3.8629201600176063524649805458466e-02,
+     346             :             -4.6431565514482092682513325598848e-01,
+     347             :             -1.7903908657682734983929151439952e-01,
+     348             :             2.7903931176262103397434088947193e-01,
+     349             :             1.4302718043199780240115615015384e-01,
+     350             :             -1.7934447123456620509784897876671e-01,
+     351             :             -8.0739459938227717272773986678658e-02,
+     352             :             1.1470118631597893410489774623784e-01,
+     353             :             3.1554408431299391102342610793130e-02,
+     354             :             -6.6358348749728263138436545887089e-02,
+     355             :             -4.6258296806782469787200362532076e-03,
+     356             :             3.2150273747621076203540013693782e-02,
+     357             :             -4.3034377017964172210118256600708e-03,
+     358             :             -1.2166368290071909522009896420514e-02,
+     359             :             4.1973811742346631842304205406435e-03,
+     360             :             3.2543956632576265426692874171977e-03,
+     361             :             -2.0320061170844903701560024700257e-03,
+     362             :             -4.6404945920505854227433584213713e-04,
+     363             :             6.2149796814451457871442130453943e-04,
+     364             :             -3.6218164282872656299389763079333e-05,
+     365             :             -1.1603343965511909259211154044067e-04,
+     366             :             3.2791106542406162017901788408025e-05,
+     367             :             9.8862027222343679003311450737002e-06,
+     368             :             -6.3723649625617885940229850882943e-06,
+     369             :             4.2660453700255329024138440524583e-07,
+     370             :             4.1828207733402810550264326779069e-07,
+     371             :             -1.1913262141068780269119692198643e-07,
+     372             :             1.0277787120590941886621601220574e-08
+     373           1 :           };
+     374           1 :       break;
+     375           1 :     case 18:
+     376           2 :       h = { 2.2292392894261341476647153569957e-03,
+     377             :             2.7278103162550408622433195660051e-02,
+     378             :             1.4649621327148704130749479190854e-01,
+     379             :             4.4502322663201776542507559497608e-01,
+     380             :             8.0868522687201060961115217651241e-01,
+     381             :             8.0864965533087529436784279823769e-01,
+     382             :             2.0820492164265561041425200983213e-01,
+     383             :             -4.1528952705523225485961802405654e-01,
+     384             :             -3.0615027286519064242398258102185e-01,
+     385             :             2.1147297628013594916751571872737e-01,
+     386             :             2.3628865852884980980341822487389e-01,
+     387             :             -1.3057700280563036554504208197613e-01,
+     388             :             -1.5097047504012414687046828021266e-01,
+     389             :             9.1764381191532157222567889220954e-02,
+     390             :             8.0682648302152173980239524553326e-02,
+     391             :             -6.2969473759350580444049683137564e-02,
+     392             :             -3.3563828020481217828674402881006e-02,
+     393             :             3.7718074039279007869662763141605e-02,
+     394             :             8.8560428508370828137863384199591e-03,
+     395             :             -1.8457581363752618985873965584688e-02,
+     396             :             1.6776820278716257444327764059011e-04,
+     397             :             6.9909435703212766469172301242452e-03,
+     398             :             -1.5821269103307486047355068237152e-03,
+     399             :             -1.8958894667740898605512445129762e-03,
+     400             :             8.8878469233540330178555688434017e-04,
+     401             :             3.0204994152642787499235543791087e-04,
+     402             :             -2.8093147682505936052477224507129e-04,
+     403             :             -2.1721148267625707617217104689056e-07,
+     404             :             5.2909093510065790795602463925107e-05,
+     405             :             -1.2049951668048177800575404550187e-05,
+     406             :             -4.7130568784725091659583255665478e-06,
+     407             :             2.5013378893915945502541674921870e-06,
+     408             :             -1.0877611266828616855187312041989e-07,
+     409             :             -1.6632548270216130592390321382701e-07,
+     410             :             4.3399892982154842698451632180406e-08,
+     411             :             -3.5467549197311356709477164192218e-09
+     412           1 :           };
+     413           1 :       break;
+     414           1 :     case 19:
+     415           2 :       h = { 1.5678958152846272748603961844083e-03,
+     416             :             2.0196523114657562170126681166948e-02,
+     417             :             1.1494461010411641255224424185144e-01,
+     418             :             3.7390170590255294991166579166020e-01,
+     419             :             7.4166503761237689840157827347866e-01,
+     420             :             8.5093873391779384363076133013237e-01,
+     421             :             3.6896118039375752628572513458494e-01,
+     422             :             -3.2256994316024734104075832874514e-01,
+     423             :             -4.0423686967938060599081495638529e-01,
+     424             :             1.0557425228315596432704381868461e-01,
+     425             :             3.0030788695033916457788336629164e-01,
+     426             :             -4.7402376549099775604467765788286e-02,
+     427             :             -2.0192946643669554274147515116056e-01,
+     428             :             3.9010162763916250705520383235125e-02,
+     429             :             1.2290471236884119299315187845423e-01,
+     430             :             -3.7478407724544741952410475960278e-02,
+     431             :             -6.4593110252131366588734806555294e-02,
+     432             :             3.0580625140236610687294316335283e-02,
+     433             :             2.7401165431703535663165993696566e-02,
+     434             :             -1.9782568984933180528118512597757e-02,
+     435             :             -8.2970810591973861297665493452769e-03,
+     436             :             9.9571204158029405495433650230552e-03,
+     437             :             1.0874656837087327745233755749155e-03,
+     438             :             -3.8007722061321243950393622412776e-03,
+     439             :             4.8339043345746983285429743126826e-04,
+     440             :             1.0405819037270433446984441161476e-03,
+     441             :             -3.6865172646368375578354581456608e-04,
+     442             :             -1.7621212955287076360778864003720e-04,
+     443             :             1.2319596840241719124843522426005e-04,
+     444             :             7.2209044276267830383855654552416e-06,
+     445             :             -2.3532762999714585322235879671915e-05,
+     446             :             4.2581465719275421569255460352288e-06,
+     447             :             2.1664782709628571646042708570556e-06,
+     448             :             -9.7054021264692123684527432642133e-07,
+     449             :             2.0464918981107693371393718402909e-08,
+     450             :             6.5576202903915930451975407466242e-08,
+     451             :             -1.5788309442633350191744509658648e-08,
+     452             :             1.2256775171147230574615288761797e-09
+     453           1 :           };
+     454           1 :       break;
+     455           1 :     case 20:
+     456           2 :       h = { 1.1030209784697370036660180048216e-03,
+     457             :             1.4919096953433321622872753664524e-02,
+     458             :             8.9694770502224324681961320493429e-02,
+     459             :             3.1104511992145722487634884600993e-01,
+     460             :             6.6849335614886884471275152463932e-01,
+     461             :             8.6336781824427866194326952609117e-01,
+     462             :             5.1124145370634632712381062447093e-01,
+     463             :             -1.9687562291233057232275882597605e-01,
+     464             :             -4.6214632517885934070989151223330e-01,
+     465             :             -2.3655675146157809085600831622287e-02,
+     466             :             3.2285230023796102072353164658125e-01,
+     467             :             5.6356759004892016673426979878059e-02,
+     468             :             -2.1985187363946029348582555940084e-01,
+     469             :             -3.4954872441050534315198916601730e-02,
+     470             :             1.4466233657484778296620220316981e-01,
+     471             :             7.9651998921310210310942068190343e-03,
+     472             :             -8.7289361758279004899208075585193e-02,
+     473             :             8.3080546928725445415819805816682e-03,
+     474             :             4.5671036383773788713824615115300e-02,
+     475             :             -1.2429982511459568284006849125944e-02,
+     476             :             -1.9531033366661638278616308639357e-02,
+     477             :             9.5058164920688980464857920082977e-03,
+     478             :             6.2515909968039852853682880606812e-03,
+     479             :             -5.0649977555009108656780547619292e-03,
+     480             :             -1.1760065027624948871126653315855e-03,
+     481             :             1.9693767000596028478309751363895e-03,
+     482             :             -7.5657029268068814531825183600233e-05,
+     483             :             -5.4462035854466845589266776883619e-04,
+     484             :             1.4358918969252962532894002389838e-04,
+     485             :             9.5802798228155261386213004115575e-05,
+     486             :             -5.2475613049099814925394641429435e-05,
+     487             :             -6.1888020007977826320456210540399e-06,
+     488             :             1.0240671536937550416246876794357e-05,
+     489             :             -1.4311756540085687366042942539335e-06,
+     490             :             -9.6832328287254565765814970368375e-07,
+     491             :             3.7249313630534454078768497216345e-07,
+     492             :             2.8486815247482631938422053924332e-10,
+     493             :             -2.5665759353263497063665855347538e-08,
+     494             :             5.7362298926689411330572237329717e-09,
+     495             :             -4.2409952349582263523522284550586e-10
+     496           1 :           };
+     497           1 :       break;
+     498           0 :     default:
+     499           0 :       plumed_merror("Specified order currently not implemented");
+     500             :     }
+     501             :   }
+     502             : 
+     503          25 :   else if (type == Type::sym) {
+     504          25 :     switch(order) {
+     505           1 :     case 4:
+     506           2 :       h = { 4.55703458959498611258176481442206e-02,
+     507             :             -1.78247014416803885306084254125381e-02,
+     508             :             -1.40317624178845662408221528494323e-01,
+     509             :             4.21234534203536570284853723933338e-01,
+     510             :             1.13665824340874954678781705297297e+00,
+     511             :             7.03739068655225841197875524812844e-01,
+     512             :             -4.19109651250538992051097864077747e-02,
+     513             :             -1.07148901417882122522051702162571e-01
+     514           1 :           };
+     515           1 :       break;
+     516           1 :     case 5:
+     517           2 :       h = { 2.76321529578600101617613660209827e-02,
+     518             :             -2.98424998687600064040115199759384e-02,
+     519             :             -2.47951362613500064790983401508129e-01,
+     520             :             2.34789231361400077546797149352642e-02,
+     521             :             8.96581648381840179418134084698977e-01,
+     522             :             1.02305296689210023508564972871682e+00,
+     523             :             2.81990696854580058516859253359144e-01,
+     524             :             -5.53441861167200052640247065482981e-02,
+     525             :             4.17468644215800155361506540430128e-02,
+     526             :             3.86547959548800140749946763207845e-02
+     527           1 :           };
+     528           1 :       break;
+     529           2 :     case 6:
+     530           4 :       h = { -1.10318675093800024761270250905909e-02,
+     531             :             2.49992209278000017055876291749428e-03,
+     532             :             6.32505626598800080317985816691362e-02,
+     533             :             -2.97837512984400025473075146464907e-02,
+     534             :             -1.02724969861800033421594946503319e-01,
+     535             :             4.77904371332100064151404694712255e-01,
+     536             :             1.11389278392792001604050255991751e+00,
+     537             :             6.94457972956700086974990426824661e-01,
+     538             :             -6.83231215864800039971882483769150e-02,
+     539             :             -1.66863215411680032573826792940963e-01,
+     540             :             4.93661237184000057515165238442023e-03,
+     541             :             2.17847003265600018540038007586190e-02
+     542           2 :           };
+     543           2 :       break;
+     544           1 :     case 7:
+     545           2 :       h = { 1.45213947620201448696075630095947e-02,
+     546             :             5.67134268576005746986812283694235e-03,
+     547             :             -1.52463871896281522033689270756440e-01,
+     548             :             -1.98056706807362009614692510695022e-01,
+     549             :             4.08183939725744127091644486426958e-01,
+     550             :             1.08578270981199098699221394781489e+00,
+     551             :             7.58162601965387539237894998223055e-01,
+     552             :             2.46656594886402458222107725305250e-02,
+     553             :             -7.00782912221206977232412782541360e-02,
+     554             :             9.60147679356809641282310963106283e-02,
+     555             :             4.31554525820804293911869820021820e-02,
+     556             :             -1.78704316511401790912305642677893e-02,
+     557             :             -1.48122591460001472307705938646905e-03,
+     558             :             3.79265853420003790433256973813059e-03
+     559           1 :           };
+     560           1 :       break;
+     561           2 :     case 8:
+     562           4 :       h = { 2.67279339279997366768393263214421e-03,
+     563             :             -4.28394300239995752879740287255572e-04,
+     564             :             -2.11456865283597902904766385745461e-02,
+     565             :             5.38638875375994745364760518668845e-03,
+     566             :             6.94904659111793138182022744331334e-02,
+     567             :             -3.84935212633396237058569511191308e-02,
+     568             :             -7.34625087607592708316417429159628e-02,
+     569             :             5.15398670373074963002579806925496e-01,
+     570             :             1.09910663053800905508694540912984e+00,
+     571             :             6.80745347188773330948663442541147e-01,
+     572             :             -8.66536154056391505484668869030429e-02,
+     573             :             -2.02648655285637996348313549788145e-01,
+     574             :             1.07586117504798947641653228401992e-02,
+     575             :             4.48236230436195592918835473028594e-02,
+     576             :             -7.66690896219992417716382337999903e-04,
+     577             :             -4.78345851149995348466914535379146e-03
+     578           2 :           };
+     579           2 :       break;
+     580           1 :     case 9:
+     581           2 :       h = { 1.51248730936219739386106031275858e-03,
+     582             :             -6.69141509131216294554989065801465e-04,
+     583             :             -1.45155785529446045012402777274474e-02,
+     584             :             1.25288962418580607921514413760633e-02,
+     585             :             8.77912515542808719049006072054908e-02,
+     586             :             -2.57864459294240427889022271301656e-02,
+     587             :             -2.70893783504461360678305936744437e-01,
+     588             :             4.98828309581242426706815251691296e-02,
+     589             :             8.73048407349484634210057265590876e-01,
+     590             :             1.01525979083351192144846208975650e+00,
+     591             :             3.37658923602252358797670694912085e-01,
+     592             :             -7.71721610974591964993152259921771e-02,
+     593             :             8.25140928710566164128170640879034e-04,
+     594             :             4.27444336024572976717728067796997e-02,
+     595             :             -1.63033512255879239893907595160272e-02,
+     596             :             -1.87693968364245344915275381936226e-02,
+     597             :             8.76502538903070420837904119792938e-04,
+     598             :             1.98119373648757883879523156167579e-03
+     599           1 :           };
+     600           1 :       break;
+     601           5 :     case 10:
+     602          10 :       h = { -6.49589896781769724452837433403829e-04,
+     603             :             8.06612029979205351478896424133325e-05,
+     604             :             6.49572837868184205234456385369413e-03,
+     605             :             -1.13753531067373615109916684673408e-03,
+     606             :             -2.87862319438586915232303198308728e-02,
+     607             :             8.15281678377939578172828305469011e-03,
+     608             :             7.07035675622903064807545092662622e-02,
+     609             :             -4.52407723042161716286990724711359e-02,
+     610             :             -5.02565403406056709911808866309002e-02,
+     611             :             5.42813011102809772623345452302601e-01,
+     612             :             1.08825153073747227239209678373300e+00,
+     613             :             6.67071338429151339255440689157695e-01,
+     614             :             -1.00240215012934938410005258901947e-01,
+     615             :             -2.25558972319967215858227405078651e-01,
+     616             :             1.64188694163413528848138867033413e-02,
+     617             :             6.49509246029642689501670815843681e-02,
+     618             :             -2.07236392054689850042437093691206e-03,
+     619             :             -1.22206426340899319132882183680522e-02,
+     620             :             1.35245019942278199434962382419201e-04,
+     621             :             1.08917044724438603908733824709998e-03
+     622           5 :           };
+     623           5 :       break;
+     624           1 :     case 11:
+     625           2 :       h = { 6.91923233208036969968390828000793e-04,
+     626             :             1.56320234204571122593394050248605e-04,
+     627             :             -9.03626416328936338251409665645042e-03,
+     628             :             -2.83333713296809227427663913090328e-03,
+     629             :             6.08114528464804224294759649183106e-02,
+     630             :             4.98747296770196690829379804199561e-02,
+     631             :             -2.04498595618993084244152669270989e-01,
+     632             :             -2.89425585980639887839771517974441e-01,
+     633             :             3.36144293016675366203571684309281e-01,
+     634             :             1.03286175231250965111939876805991e+00,
+     635             :             8.08962653490911898224169362947578e-01,
+     636             :             1.37459287684679687391309244048898e-01,
+     637             :             -3.22902447410400722516143900975294e-02,
+     638             :             9.89621390609645434910390804361668e-02,
+     639             :             5.23788159925569485331209307332756e-02,
+     640             :             -3.40554527782290436532797173185827e-02,
+     641             :             -1.39412251318646231851294814418907e-02,
+     642             :             9.21005970815790518668730868512284e-03,
+     643             :             8.32056417857734271180392138234083e-04,
+     644             :             -2.45276429733504728117332582826293e-03,
+     645             :             -5.48653425032330071273514726648557e-05,
+     646             :             2.42851511636182730569100129969229e-04
+     647           1 :           };
+     648           1 :       break;
+     649           3 :     case 12:
+     650           6 :       h = { -2.53238395868029360011308703803934e-04,
+     651             :             -2.56794013941539134206898387091655e-05,
+     652             :             3.32382276159138428939243681270455e-03,
+     653             :             4.35079685976638231084678842819358e-04,
+     654             :             -2.06331445793122500442784428287268e-02,
+     655             :             -3.68316511823289565938366330044573e-03,
+     656             :             8.17474545336821928342985188464809e-02,
+     657             :             2.16399291162249034214948295584691e-02,
+     658             :             -2.40940550666163183501922162577102e-01,
+     659             :             -1.10779056856021962396141589124454e-01,
+     660             :             6.54414642216806785590677009167848e-01,
+     661             :             1.07972249467402248157554822682869e+00,
+     662             :             5.64109951994629099658595805522054e-01,
+     663             :             -3.13422339595566742942445159769704e-02,
+     664             :             -5.06979026234183824395351791736175e-02,
+     665             :             6.95500589276436959051963526690088e-02,
+     666             :             1.06826589882294663985673466299886e-02,
+     667             :             -3.42532744974815631100462098856951e-02,
+     668             :             -1.99249856148396879348960730737872e-03,
+     669             :             1.04863447995954799790707667739298e-02,
+     670             :             2.54861210329473779345743622570808e-04,
+     671             :             -1.90884289542041446843811947076119e-03,
+     672             :             -1.60568790225561159679470990546690e-05,
+     673             :             1.58345524644348421491879541633807e-04
+     674           3 :           };
+     675           3 :       break;
+     676           1 :     case 13:
+     677           2 :       h = { 9.96028729759322644298977222909741e-05,
+     678             :             5.21920796195277043654989213017359e-05,
+     679             :             -1.02016329687258286949835817125631e-03,
+     680             :             5.84439592204865189864482211135055e-04,
+     681             :             8.02545515204910846207564389942490e-03,
+     682             :             -2.11063917638504251403364087025238e-03,
+     683             :             -2.93444878165318237539516132983408e-02,
+     684             :             2.49160343945351858696568569939700e-02,
+     685             :             1.31417253195061006776356293812569e-01,
+     686             :             1.24730209143528725235228193923831e-02,
+     687             :             -1.98682995060360217953743244834186e-01,
+     688             :             1.55889076380235497287785051412357e-01,
+     689             :             9.11551693535715079619308198743965e-01,
+     690             :             9.83923742598004968940017533896025e-01,
+     691             :             2.79596836052714847742350912085385e-01,
+     692             :             -1.75875078644905619151828091162315e-01,
+     693             :             -8.45001480790217585070678296688129e-02,
+     694             :             1.96045318821402025921685208231793e-02,
+     695             :             -2.43409385742523465268050131271593e-02,
+     696             :             -2.85908276815921014168964120472083e-02,
+     697             :             7.49018377371175360368571460867315e-03,
+     698             :             1.06436900199696239666113939392744e-02,
+     699             :             -2.41749708924265434154335374650202e-04,
+     700             :             -1.60663632304836349537491280159429e-03,
+     701             :             -5.05420462645238263775342157924086e-05,
+     702             :             9.64539648683696427926281824483112e-05
+     703           1 :           };
+     704           1 :       break;
+     705           1 :     case 14:
+     706           2 :       h = { 6.31007638147709694776549271821864e-05,
+     707             :             2.73353579399835730078405920950857e-05,
+     708             :             -8.56674265589630994088832238730902e-04,
+     709             :             -1.03540533784965597756920485661425e-04,
+     710             :             6.41017395468853039969259199892804e-03,
+     711             :             1.43279913888553589278174182908288e-03,
+     712             :             -2.74913418748536537983273575491694e-02,
+     713             :             -3.34468414059296489937445073792333e-03,
+     714             :             9.87511620870536871441558446349518e-02,
+     715             :             3.66261337327129302132711075046245e-02,
+     716             :             -2.26270508787995705546336466795765e-01,
+     717             :             -8.21825286701456242388630357709189e-02,
+     718             :             6.72226282198253310973257157456828e-01,
+     719             :             1.07476870846271177484254621958826e+00,
+     720             :             5.56070925104528490656718986429041e-01,
+     721             :             -4.99473531504178586137854267690273e-02,
+     722             :             -8.15074892290164332298019189693150e-02,
+     723             :             5.29383812442578288726124924323813e-02,
+     724             :             6.05357014372925363032695855736165e-03,
+     725             :             -4.12896871319010858036868683029752e-02,
+     726             :             -3.89442565747022016384160103541490e-03,
+     727             :             1.41954425904793363893974245115714e-02,
+     728             :             5.18276140762161932271090414303671e-04,
+     729             :             -3.64788147216562339339440690366700e-03,
+     730             :             -8.89051363774028501323759554608728e-05,
+     731             :             5.63473132455830365457327690847933e-04,
+     732             :             1.58545584728775700955431815497576e-05,
+     733             :             -3.65985604352032339978313679740296e-05
+     734           1 :           };
+     735           1 :       break;
+     736           1 :     case 15:
+     737           2 :       h = { 4.05323627037270219162362616671658e-05,
+     738             :             3.07137347973606144061961553681783e-05,
+     739             :             -5.68752200237824536398212327270585e-04,
+     740             :             -1.52953421693918361354627699633113e-04,
+     741             :             4.92291805096766160038113113728286e-03,
+     742             :             2.15828545106170558570690687361093e-03,
+     743             :             -2.42838185667302274006740248069036e-02,
+     744             :             -1.23669990433466353563218831368431e-02,
+     745             :             9.61238540674488606274650237537571e-02,
+     746             :             9.67227466631194188195763672410976e-02,
+     747             :             -1.89584235398369660430262229056098e-01,
+     748             :             -2.78071663287250692153662612327025e-01,
+     749             :             3.45015366735401951547856924662483e-01,
+     750             :             1.02084020241597150935319859854644e+00,
+     751             :             8.18321122934300926310413615283323e-01,
+     752             :             1.57732464332277610985499904927565e-01,
+     753             :             -5.80996643342105573148970165675564e-02,
+     754             :             5.76086678570035190527498514256877e-02,
+     755             :             3.10245118607714344405312800745378e-02,
+     756             :             -5.49799802677569254827361078241665e-02,
+     757             :             -2.74428303436324676212176854050995e-02,
+     758             :             1.42552403061262534383901723344934e-02,
+     759             :             4.84149046146408433555219374966327e-03,
+     760             :             -5.07726066683766071724326351954915e-03,
+     761             :             -3.78042544045809091653870259719383e-04,
+     762             :             1.51401068119577392884211874957145e-03,
+     763             :             7.79550547699306238926333922911738e-05,
+     764             :             -2.27210190383633081493211514079178e-04,
+     765             :             -1.04081406015788967609316320594992e-05,
+     766             :             1.37354357168879101134487813462570e-05
+     767           1 :           };
+     768           1 :       break;
+     769           1 :     case 16:
+     770           2 :       h = { -1.52706527381910275756142503222890e-05,
+     771             :             -7.63177970130589524008421498102450e-06,
+     772             :             2.33991244594547811736645614999475e-04,
+     773             :             5.17120268202257300760825431407142e-05,
+     774             :             -1.89323683821244256181293152963008e-03,
+     775             :             -3.14120133085196543993450335463535e-04,
+     776             :             9.81147588368609310793821975948958e-03,
+     777             :             1.92311087754286520745683475297483e-03,
+     778             :             -3.52885288476778719024551378424803e-02,
+     779             :             -4.96427860935466733899312785638358e-03,
+     780             :             1.10362189954493067345353551900189e-01,
+     781             :             4.34462515148709496615175851275126e-02,
+     782             :             -2.25697442637171785673189106091741e-01,
+     783             :             -7.64249514011508951361051344974840e-02,
+     784             :             6.72236243037978686842848219384905e-01,
+     785             :             1.06988789812795226374930734891677e+00,
+     786             :             5.61616638655705324723044213897083e-01,
+     787             :             -4.88953427358677847336387856103102e-02,
+     788             :             -9.47283364442045167086448032023327e-02,
+     789             :             4.57258966692524679298337275668018e-02,
+     790             :             6.88619390233227712805330611445243e-03,
+     791             :             -4.39130321893507619135377240127127e-02,
+     792             :             -4.42156298801803758491413276487947e-03,
+     793             :             1.79134637043109300191812138791647e-02,
+     794             :             1.01570512112273466515111053354303e-03,
+     795             :             -5.48843874201232484466572714154609e-03,
+     796             :             -1.53365269849333965166901516674614e-04,
+     797             :             1.20541159197261760899211324726821e-03,
+     798             :             3.97091116582507492704760820867449e-05,
+     799             :             -1.54759482169960371376535301912725e-04,
+     800             :             -4.40323369887264181395027801135811e-06,
+     801             :             8.81055997054166680230915392746383e-06
+     802           1 :           };
+     803           1 :       break;
+     804           1 :     case 17:
+     805           2 :       h = { 5.36164168581481346588513137163545e-06,
+     806             :             -3.46866471633543758739618573239127e-06,
+     807             :             -1.07580985050661424558618439739632e-04,
+     808             :             3.56494009271542727150354490373019e-05,
+     809             :             1.01798919677591626770096766563256e-03,
+     810             :             8.25906783075320302753979939680562e-05,
+     811             :             -5.56114774235276932562443974461530e-03,
+     812             :             -2.69465339683962841130226983921148e-03,
+     813             :             1.75319890806961142803999109673896e-02,
+     814             :             1.40756428708096667512528199495137e-02,
+     815             :             -2.55108531297768073575760183757666e-02,
+     816             :             -1.02695023497632355324871156199151e-02,
+     817             :             2.28520064519878510211903233084740e-02,
+     818             :             -1.21722598355376729339916153094237e-01,
+     819             :             -2.19310589964256619222027211435488e-01,
+     820             :             2.55321529059814311679588172410149e-01,
+     821             :             9.63770979824808082803144770878134e-01,
+     822             :             9.20252282282772893218236731627258e-01,
+     823             :             2.01381678415994358477547621077974e-01,
+     824             :             -1.67678964148070125395051377381606e-01,
+     825             :             2.44251344634779481157504932298252e-02,
+     826             :             1.48145397031054587566600844183995e-01,
+     827             :             2.53200120416010171497944725160778e-02,
+     828             :             -4.70811260450583399239654625034746e-02,
+     829             :             -6.81539610621377002497300878758324e-03,
+     830             :             1.48243054824644532319055656444107e-02,
+     831             :             1.21165585310027278283240281808730e-03,
+     832             :             -3.87731534844140950796242961473581e-03,
+     833             :             -1.96069824769335180822404929301683e-04,
+     834             :             6.73160536609661666086756870441832e-04,
+     835             :             -1.91009105827510641166869231888370e-05,
+     836             :             -8.90063957100391663296648503411745e-05,
+     837             :             3.93169287554600132558258254733552e-06,
+     838             :             6.07736121570621208446468658470607e-06
+     839           1 :           };
+     840           1 :       break;
+     841           1 :     case 18:
+     842           2 :       h = { -2.13992159246166473816484938919036e-06,
+     843             :             1.10977553385413026034323619173350e-06,
+     844             :             4.18005291525171048536493878522435e-05,
+     845             :             -1.39424713387653467029560910850350e-05,
+     846             :             -3.75940547191951806357129717284238e-04,
+     847             :             6.70565555942921202913289957514564e-05,
+     848             :             2.01961905200075380467650276727909e-03,
+     849             :             -2.66969918023956154402853702123366e-04,
+     850             :             -7.41018163371885089235613364166966e-03,
+     851             :             1.53836000238939262126092177851433e-03,
+     852             :             2.12306779452164293142679696302366e-02,
+     853             :             -4.61138867117545040580361970228296e-03,
+     854             :             -4.48485088469943032896125600927917e-02,
+     855             :             8.87835433253391509422769445336598e-03,
+     856             :             4.03469430616465660199843057398539e-02,
+     857             :             -1.04367839842760060098392216332286e-01,
+     858             :             -4.59344672605674214649340569849301e-02,
+     859             :             5.67783920692876864499964995047776e-01,
+     860             :             1.06579255093152891475938304211013e+00,
+     861             :             6.70293472647235155648104409920052e-01,
+     862             :             -7.35803422739719908962641170546704e-02,
+     863             :             -2.26186698989002510362666953369626e-01,
+     864             :             4.80771334803232336385647727183823e-02,
+     865             :             1.19104967186232965636882852322742e-01,
+     866             :             -7.18008269166581052089792791548462e-03,
+     867             :             -4.28861550987859954653380611944158e-02,
+     868             :             2.32353364582536326202188980971641e-03,
+     869             :             1.34380897535976585183137288481703e-02,
+     870             :             -5.81978733884339397529339432679762e-04,
+     871             :             -3.27230890166736818752690751921364e-03,
+     872             :             9.92958015089934567000418130788830e-05,
+     873             :             5.60266733289934543670030020479089e-04,
+     874             :             -1.98286778613536816145718894022210e-05,
+     875             :             -6.39885786401657284281838111716922e-05,
+     876             :             1.91614024625604985099780984414419e-06,
+     877             :             3.69479211060541101930730298330552e-06
+     878           1 :           };
+     879           1 :       break;
+     880           1 :     case 19:
+     881           2 :       h = { 2.47619856876035267576182871684942e-06,
+     882             :             2.91655676074685013668191455038503e-06,
+     883             :             -3.98117220914099361156295031616281e-05,
+     884             :             -2.37890336748671808665862859033524e-05,
+     885             :             3.90632340413758891075474144471968e-04,
+     886             :             1.82868669835172258141334222791841e-04,
+     887             :             -2.41117792464671338789616861220111e-03,
+     888             :             -8.73874136465524497564827388629283e-04,
+     889             :             1.16845675580482498412404623877592e-02,
+     890             :             6.10848600213812192166740189236407e-03,
+     891             :             -3.91877120522209840269844960403134e-02,
+     892             :             -2.39118550567039567233962316095131e-02,
+     893             :             1.18896719019111141157907240994973e-01,
+     894             :             1.32414008615193368179063782008598e-01,
+     895             :             -1.64390631231593420391590143481153e-01,
+     896             :             -2.49745683326209749752777611320198e-01,
+     897             :             3.65243519237511582442579083362943e-01,
+     898             :             1.01760518334862726241851760278223e+00,
+     899             :             8.17620422715306993666217749705538e-01,
+     900             :             1.54185800478859824647059895141865e-01,
+     901             :             -9.54948528806143087654945134090667e-02,
+     902             :             1.26637042824246960626144442585428e-02,
+     903             :             9.92151969664582453201084888405603e-03,
+     904             :             -6.59532404097190189107280389180232e-02,
+     905             :             -3.20347562503009650192176138716604e-02,
+     906             :             2.23409529027087383479255322527024e-02,
+     907             :             1.12690735439448276589136099801181e-02,
+     908             :             -7.24389178390821321384951403388186e-03,
+     909             :             -1.64148228823170379275797614582189e-03,
+     910             :             3.00014804641317691172308634861565e-03,
+     911             :             2.25083469591080945247998923441912e-04,
+     912             :             -8.99106799594682343235163557437772e-04,
+     913             :             -6.52240895281959979666239202167333e-05,
+     914             :             1.63397150769660883320999467116508e-04,
+     915             :             1.25487584192582468661661745934488e-05,
+     916             :             -1.68015900652064169079266675588258e-05,
+     917             :             -9.14098333564239404867173867386132e-07,
+     918             :             7.76082610749008778884821136562211e-07
+     919           1 :           };
+     920           1 :       break;
+     921           1 :     case 20:
+     922           0 :       h = { -8.95074013313225034112988621332052e-07,
+     923             :             -4.60567304495735576428397861289965e-07,
+     924             :             1.73767995228992186179835244264069e-05,
+     925             :             6.39991346364665771576834066292072e-06,
+     926             :             -1.66016418292479542555967197969835e-04,
+     927             :             -3.76400722545106348484143798938106e-05,
+     928             :             1.05728141728119568419630436295620e-03,
+     929             :             1.77400246424138069000625561599804e-04,
+     930             :             -4.90965140656484527736935774555604e-03,
+     931             :             -8.64263223121293565169576122997341e-04,
+     932             :             1.71926521880978698531006187977255e-02,
+     933             :             2.74159026446779826788335832077337e-03,
+     934             :             -5.00254525875804267887048126794980e-02,
+     935             :             -9.67845613584030449449979727205573e-03,
+     936             :             1.25751400487193104593686143743980e-01,
+     937             :             5.12665874779235433700286250768841e-02,
+     938             :             -2.27092007441644233578514899818401e-01,
+     939             :             -7.22498274381410260369662523771694e-02,
+     940             :             6.67496745413005965197328350768657e-01,
+     941             :             1.06230451808460291118763052509166e+00,
+     942             :             5.73932332635040842738760602514958e-01,
+     943             :             -4.21709558919741780980139367329684e-02,
+     944             :             -1.11714873948519005653068347783119e-01,
+     945             :             3.61746629928947835419528189504490e-02,
+     946             :             1.14879797113225934346303347410867e-02,
+     947             :             -4.47307789806269048837883417490957e-02,
+     948             :             -4.68650205569037543035237902699919e-03,
+     949             :             2.40473567441355992602147750858421e-02,
+     950             :             2.01254944419308181777217292562909e-03,
+     951             :             -9.34312323805295934231462950947389e-03,
+     952             :             -4.31706836813935599089092631786002e-04,
+     953             :             2.95428464804820467212720380700830e-03,
+     954             :             1.02049526041390444994726161009879e-04,
+     955             :             -6.99655419422072467026951780866284e-04,
+     956             :             -2.72718682941954995583092036248729e-05,
+     957             :             1.13037635169613691495625606986408e-04,
+     958             :             4.27893798113462174641198274005482e-06,
+     959             :             -1.11996683141520158823655969881905e-05,
+     960             :             -2.68922267421127013513505862526975e-07,
+     961             :             5.22627921716999034327578478598131e-07
+     962           1 :           };
+     963           1 :       break;
+     964           0 :     default:
+     965           0 :       plumed_merror("Wavelets: Specified order currently not implemented");
+     966             :     }
+     967             :   }
+     968             : 
+     969             :   // to get highpass: reverse order and inverse sign of every second
+     970          49 :   if (!lowpass) {
+     971           2 :     std::reverse(h.begin(), h.end());
+     972          22 :     for (unsigned i=1; i < h.size(); i += 2) {
+     973          20 :       h[i] = -h[i];
+     974             :     }
+     975             :   }
+     976             : 
+     977          49 :   return h;
+     978             : }
+     979             : 
+     980             : 
+     981             : }
+     982             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletGrid.cpp.func-sort-c.html b/coverage/ves/WaveletGrid.cpp.func-sort-c.html new file mode 100644 index 000000000000..1ecdcc49f661 --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410599.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid12stringToTypeERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE47
_ZN4PLMD3ves11WaveletGrid12typeToStringB5cxx11ENS1_4TypeEb47
_ZN4PLMD3ves11WaveletGrid16fillGridFromMapsERSt10unique_ptrINS_4GridESt14default_deleteIS3_EERKSt13unordered_mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIdSaIdEESt4hashISE_ESt8equal_toISE_ESaISt4pairIKSE_SH_EEESS_47
_ZN4PLMD3ves11WaveletGrid9setupGridEjjbNS1_4TypeE47
_ZN4PLMD3ves11WaveletGrid13setupMatricesERKSt6vectorIdSaIdEE49
_ZN4PLMD3ves11WaveletGrid14getEigenvectorERKNS_6MatrixIdEEd94
_ZN4PLMD3ves11WaveletGrid17calcIntegerValuesERKNS_6MatrixIdEEi94
_ZN4PLMD3ves11WaveletGrid7cascadeB5cxx11ERSt6vectorINS_6MatrixIdEESaIS4_EES7_RKS2_IdSaIdEEjjjb94
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletGrid.cpp.func.html b/coverage/ves/WaveletGrid.cpp.func.html new file mode 100644 index 000000000000..28380769cc5f --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletGrid.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410599.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD3ves11WaveletGrid12stringToTypeERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE47
_ZN4PLMD3ves11WaveletGrid12typeToStringB5cxx11ENS1_4TypeEb47
_ZN4PLMD3ves11WaveletGrid13setupMatricesERKSt6vectorIdSaIdEE49
_ZN4PLMD3ves11WaveletGrid14getEigenvectorERKNS_6MatrixIdEEd94
_ZN4PLMD3ves11WaveletGrid16fillGridFromMapsERSt10unique_ptrINS_4GridESt14default_deleteIS3_EERKSt13unordered_mapINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEESt6vectorIdSaIdEESt4hashISE_ESt8equal_toISE_ESaISt4pairIKSE_SH_EEESS_47
_ZN4PLMD3ves11WaveletGrid17calcIntegerValuesERKNS_6MatrixIdEEi94
_ZN4PLMD3ves11WaveletGrid7cascadeB5cxx11ERSt6vectorINS_6MatrixIdEESaIS4_EES7_RKS2_IdSaIdEEjjjb94
_ZN4PLMD3ves11WaveletGrid9setupGridEjjbNS1_4TypeE47
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/WaveletGrid.cpp.gcov.html b/coverage/ves/WaveletGrid.cpp.gcov.html new file mode 100644 index 000000000000..7dc58a08c526 --- /dev/null +++ b/coverage/ves/WaveletGrid.cpp.gcov.html @@ -0,0 +1,331 @@ + + + + + + + + LCOV - plumed test coverage - ves/WaveletGrid.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - ves - WaveletGrid.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410599.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2021 The VES code team
+       3             :    (see the PEOPLE-VES file at the root of this folder for a list of names)
+       4             : 
+       5             :    See http://www.ves-code.org for more information.
+       6             : 
+       7             :    This file is part of VES code module.
+       8             : 
+       9             :    The VES code module is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    The VES code module is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with the VES code module.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "WaveletGrid.h"
+      24             : #include "tools/Exception.h"
+      25             : #include "tools/Grid.h"
+      26             : #include "tools/Matrix.h"
+      27             : 
+      28             : #include <memory>
+      29             : #include <unordered_map>
+      30             : #include <vector>
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace ves {
+      34             : 
+      35             : 
+      36             : // construction of Wavelet grid according to the Daubechies-Lagarias method
+      37             : // see Strang, Nguyen "Wavelets and Filter Banks" chapter 6.3
+      38          47 : std::unique_ptr<Grid> WaveletGrid::setupGrid(const unsigned order, unsigned gridsize, const bool use_mother_wavelet, const Type type) {
+      39          47 :   plumed_assert(order>=1) << "Wavelet order has to be a positive integer";
+      40             :   // calculate the grid properties of the scaling grid
+      41             :   // the range of the grid is from 0 to maxsupport
+      42          47 :   unsigned maxsupport = order*2 -1;
+      43             :   // determine needed recursion depth for specified size
+      44             :   unsigned recursion_number = 0;
+      45         173 :   while (maxsupport*(1U<<recursion_number) < gridsize) { recursion_number++; }
+      46             :   // set "true" gridsize
+      47          47 :   unsigned bins_per_int = 1U<<recursion_number;
+      48             :   gridsize = maxsupport*bins_per_int;
+      49             : 
+      50             :   // Filter coefficients
+      51          47 :   std::vector<double> h_coeffs = getFilterCoefficients(order, true, type);
+      52             :   // Vector with the Matrices M0 and M1 for the cascade
+      53          47 :   std::vector<Matrix<double>> h_Matvec = setupMatrices(h_coeffs);
+      54             :   std::vector<Matrix<double>> g_Matvec; // only filled if needed for wavelet
+      55             : 
+      56             :   // get the values at integers
+      57          47 :   std::vector<double> values_at_integers = calcIntegerValues(h_Matvec[0], 0);
+      58          47 :   std::vector<double> derivs_at_integers = calcIntegerValues(h_Matvec[0], 1);
+      59             : 
+      60             :   std::string gridvarname; // stores the name of the grid variable
+      61          47 :   if (use_mother_wavelet) { // get the highpass filter coefficients as well
+      62           2 :     std::vector<double> g_coeffs = getFilterCoefficients(order, false, type);
+      63           4 :     g_Matvec = setupMatrices(g_coeffs);
+      64           4 :     gridvarname = typeToString(type,true)+std::to_string(order)+"_psi";
+      65             :   }
+      66             :   else {
+      67          90 :     gridvarname = typeToString(type,true)+std::to_string(order)+"_phi";
+      68             :   }
+      69             : 
+      70             :   // Set up the grid with correct properties
+      71             :   auto grid = std::unique_ptr<Grid>(new Grid(gridvarname, {"position"}, {"0"},
+      72         517 :   {std::to_string(maxsupport)}, {gridsize}, false, true, {false}, {"0."}, {"0."}));
+      73             : 
+      74          47 :   BinaryMap values = cascade(h_Matvec, g_Matvec, values_at_integers, recursion_number, bins_per_int, 0, use_mother_wavelet);
+      75          47 :   BinaryMap derivs = cascade(h_Matvec, g_Matvec, derivs_at_integers, recursion_number, bins_per_int, 1, use_mother_wavelet);
+      76             : 
+      77          47 :   fillGridFromMaps(grid, values, derivs);
+      78             : 
+      79          47 :   return grid;
+      80          47 : }
+      81             : 
+      82             : 
+      83             : 
+      84          49 : std::vector<Matrix<double>> WaveletGrid::setupMatrices(const std::vector<double>& coeffs) {
+      85             :   Matrix<double> M0, M1;
+      86          49 :   const int N = coeffs.size() -1;
+      87             :   M0.resize(N,N); M1.resize(N,N);
+      88        1108 :   for (int i = 0; i < N; ++i) {
+      89       27644 :     for (int j = 0; j < N; ++j) {
+      90       26585 :       int shift = 2*i -j;
+      91       26585 :       if (0 <= shift && shift <= N) {
+      92       13822 :         M0[i][j] = coeffs[2*i -j]; // normalization is already included in coeffs
+      93             :       }
+      94       26585 :       if (-1 <= shift && shift <= N -1) {
+      95       13822 :         M1[i][j] = coeffs[2*i -j + 1];
+      96             :       }
+      97             :     }
+      98             :   }
+      99         196 :   return std::vector<Matrix<double>> {M0, M1};
+     100             : }
+     101             : 
+     102             : 
+     103          94 : std::vector<double> WaveletGrid::calcIntegerValues(const Matrix<double> &M, const int deriv) {
+     104             :   // corresponding eigenvalue of the matrix
+     105             :   double eigenvalue = std::pow(0.5, deriv);
+     106          94 :   std::vector<double> values = getEigenvector(M, eigenvalue);
+     107             : 
+     108             :   // normalization of the eigenvector
+     109             :   double normfactor = 0.;
+     110             :   // i=0 is always 0; for derivs > 1 an additional factorial would have to be added
+     111        2042 :   for (unsigned i=1; i<values.size(); ++i) {
+     112        1948 :     normfactor += values[i] * std::pow(-i, deriv);
+     113             :   }
+     114          94 :   normfactor = 1/normfactor;
+     115        2136 :   for (auto& value : values) {
+     116        2042 :     value *= normfactor;
+     117             :   }
+     118             : 
+     119          94 :   return values;
+     120             : }
+     121             : 
+     122             : 
+     123             : // maybe move this to the tools/matrix.h file?
+     124             : // this works reliably only for singular eigenvalues
+     125             : //
+     126          94 : std::vector<double> WaveletGrid::getEigenvector(const Matrix<double> &A, const double eigenvalue) {
+     127             :   // mostly copied from tools/matrix.h
+     128          94 :   int info, N = A.ncols(); // ncols == nrows
+     129          94 :   std::vector<double> da(N*N);
+     130          94 :   std::vector<double> S(N);
+     131          94 :   std::vector<double> U(N*N);
+     132          94 :   std::vector<double> VT(N*N);
+     133          94 :   std::vector<int> iwork(8*N);
+     134             : 
+     135             :   // Transfer the matrix to the local array and substract eigenvalue
+     136       53862 :   for (int i=0; i<N; ++i) for (int j=0; j<N; ++j) {
+     137       51726 :       da[i*N+j]=static_cast<double>( A(j,i) );
+     138       51726 :       if (i==j) da[i*N+j] -= eigenvalue;
+     139             :     }
+     140             : 
+     141             :   // This optimizes the size of the work array used in lapack singular value decomposition
+     142          94 :   int lwork=-1;
+     143          94 :   std::vector<double> work(1);
+     144          94 :   plumed_lapack_dgesdd( "A", &N, &N, da.data(), &N, S.data(), U.data(), &N, VT.data(), &N, work.data(), &lwork, iwork.data(), &info );
+     145             : 
+     146             :   // Retrieve correct sizes for work and reallocate
+     147          94 :   lwork=static_cast<int>(work[0]); work.resize(lwork);
+     148             : 
+     149             :   // This does the singular value decomposition
+     150          94 :   plumed_lapack_dgesdd( "A", &N, &N, da.data(), &N, S.data(), U.data(), &N, VT.data(), &N, work.data(), &lwork, iwork.data(), &info );
+     151             : 
+     152             :   // fill eigenvector with last column of VT
+     153          94 :   std::vector<double> eigenvector(N);
+     154        2136 :   for (int i=0; i<N; ++i) eigenvector[i] = VT[N-1 + i*N];
+     155             : 
+     156          94 :   return eigenvector;
+     157             : }
+     158             : 
+     159             : 
+     160          94 : WaveletGrid::BinaryMap WaveletGrid::cascade(std::vector<Matrix<double>>& h_Matvec, std::vector<Matrix<double>>& g_Matvec, const std::vector<double>& values_at_integers, const unsigned recursion_number, const unsigned bins_per_int, const unsigned derivnum, const bool use_mother_wavelet) {
+     161             :   BinaryMap scaling_map, wavelet_map;
+     162          94 :   scaling_map.reserve(bins_per_int);
+     163             :   // vector to store the binary representation of all the decimal parts
+     164             :   std::vector<std::string> binary_vec;
+     165             :   // vector used as result of the matrix multiplications
+     166             :   std::vector<double> temp_values;
+     167             : 
+     168             :   // multiply matrices by 2 if derivatives are calculated (assumes ascending order)
+     169         188 :   if (derivnum != 0) for (auto& M : h_Matvec) M *= 2;
+     170             : 
+     171          94 :   if (use_mother_wavelet) {
+     172             :     wavelet_map.reserve(bins_per_int);
+     173           8 :     if (derivnum != 0) for (auto& M : g_Matvec) M *= 2;
+     174             :   }
+     175             : 
+     176             :   // fill the first two datasets by hand
+     177         282 :   scaling_map["0"] = values_at_integers;
+     178          94 :   mult(h_Matvec[1], values_at_integers, temp_values);
+     179         188 :   scaling_map["1"] = temp_values;
+     180             : 
+     181          94 :   if (use_mother_wavelet) {
+     182           4 :     mult(g_Matvec[0], values_at_integers, temp_values);
+     183          12 :     wavelet_map["0"] = temp_values;
+     184           4 :     mult(g_Matvec[1], values_at_integers, temp_values);
+     185          12 :     wavelet_map["1"] = temp_values;
+     186             :   }
+     187             : 
+     188             :   // now do the cascade
+     189          94 :   binary_vec.emplace_back("1");
+     190         252 :   for (unsigned i=1; i<recursion_number; ++i) {
+     191             :     std::vector<std::string> new_binary_vec;
+     192        1144 :     for (const auto& binary : binary_vec) {
+     193        2958 :       for (unsigned k=0; k<2; ++k) {
+     194             :         // prepend the new bit
+     195        3944 :         std::string new_binary = std::to_string(k) + binary;
+     196        1972 :         mult(h_Matvec[k], scaling_map[binary], temp_values);
+     197        1972 :         scaling_map.insert(std::pair<std::string, std::vector<double>>(new_binary, temp_values));
+     198        1972 :         if (use_mother_wavelet) {
+     199           8 :           mult(g_Matvec[k], scaling_map[binary], temp_values);
+     200          16 :           wavelet_map.insert(std::pair<std::string, std::vector<double>>(new_binary, temp_values));
+     201             :         }
+     202        1972 :         new_binary_vec.push_back(new_binary);
+     203             :       }
+     204             :     }
+     205         158 :     binary_vec = new_binary_vec;
+     206         158 :   }
+     207             : 
+     208         188 :   return use_mother_wavelet ? wavelet_map : scaling_map;
+     209          94 : }
+     210             : 
+     211             : 
+     212             : // Fill the Grid with the values of the unordered maps
+     213          47 : void WaveletGrid::fillGridFromMaps(std::unique_ptr<Grid>& grid, const BinaryMap& values_map, const BinaryMap& derivs_map) {
+     214          47 :   unsigned bins_per_int = values_map.size();
+     215             :   // this is somewhat complicated… not sure if the unordered_map way is the best way for c++
+     216        1127 :   for (const auto& value_iter : values_map) {
+     217             :     // get decimal of binary key
+     218        1080 :     unsigned decimal = std::stoi(value_iter.first, nullptr, 2);
+     219             :     // corresponding iterator of deriv
+     220        1080 :     auto deriv_iter = derivs_map.find(value_iter.first);
+     221             :     // calculate first grid element
+     222        1080 :     unsigned first_grid_element = decimal * (bins_per_int >> value_iter.first.length());
+     223       19480 :     for (unsigned i=0; i<value_iter.second.size(); ++i) {
+     224             :       // derivative has to be passed as vector
+     225       18400 :       std::vector<double> deriv {deriv_iter->second[i]};
+     226       18400 :       grid->setValueAndDerivatives(first_grid_element + bins_per_int*i, value_iter.second[i], deriv);
+     227             :     }
+     228             :   }
+     229          47 : }
+     230             : 
+     231             : 
+     232          47 : WaveletGrid::Type WaveletGrid::stringToType(std::string& type_str) {
+     233         188 :   std::unordered_map<std::string, Type> typemap = { {"DAUBECHIES", Type::db}, {"SYMLETS", Type::sym} };
+     234          47 :   try { return typemap.at(type_str); }
+     235           0 :   catch(const std::out_of_range& e) {plumed_merror("The specified wavelet type "+type_str+" is not implemented."); }
+     236             : }
+     237             : 
+     238             : 
+     239          47 : std::string WaveletGrid::typeToString(Type type, bool abbrev) {
+     240             :   std::string type_str;
+     241          47 :   switch(type) {
+     242          23 :   case Type::db:
+     243          23 :     type_str = abbrev ? "Db" : "DAUBECHIES";
+     244             :     break;
+     245          24 :   case Type::sym:
+     246          24 :     type_str = abbrev ? "Sym" : "SYMLETS";
+     247             :     break;
+     248             :   }
+     249          47 :   return type_str;
+     250             : }
+     251             : 
+     252             : 
+     253             : }
+     254             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/index-sort-f.html b/coverage/ves/index-sort-f.html new file mode 100644 index 000000000000..b07936d95789 --- /dev/null +++ b/coverage/ves/index-sort-f.html @@ -0,0 +1,724 @@ + + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5891718082.0 %
Date:2024-02-22 21:58:45Functions:44467765.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
GridLinearInterpolation.h +
22.2%22.2%
+
22.2 %2 / 90.0 %0 / 1
CoeffsMatrix.cpp +
29.5%29.5%
+
29.5 %105 / 35625.3 %20 / 79
VesBias.h +
74.2%74.2%
+
74.2 %66 / 8936.0 %9 / 25
OutputFesBias.cpp +
88.2%88.2%
+
88.2 %60 / 6840.0 %2 / 5
TD_ProductDistribution.cpp +
63.2%63.2%
+
63.2 %48 / 7640.0 %4 / 10
FermiSwitchingFunction.cpp +
49.3%49.3%
+
49.3 %33 / 6744.4 %4 / 9
CoeffsVector.cpp +
50.7%50.7%
+
50.7 %232 / 45845.5 %45 / 99
CoeffsBase.cpp +
42.2%42.2%
+
42.2 %127 / 30146.9 %15 / 32
OutputTargetDistribution.cpp +
93.3%93.3%
+
93.3 %83 / 8950.0 %2 / 4
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %108 / 11050.0 %2 / 4
TargetDistribution.h +
81.8%81.8%
+
81.8 %18 / 2250.0 %3 / 6
GridLinearInterpolation.cpp +
55.0%55.0%
+
55.0 %66 / 12055.6 %5 / 9
TD_ProductCombination.cpp +
73.3%73.3%
+
73.3 %55 / 7560.0 %6 / 10
TD_LinearCombination.cpp +
75.3%75.3%
+
75.3 %58 / 7760.0 %6 / 10
VesBias.cpp +
76.2%76.2%
+
76.2 %324 / 42560.0 %27 / 45
TD_WellTempered.cpp +
90.3%90.3%
+
90.3 %28 / 3166.7 %4 / 6
Opt_RobbinsMonroSGD.cpp +
95.8%95.8%
+
95.8 %23 / 2475.0 %3 / 4
Opt_Adam.cpp +
93.1%93.1%
+
93.1 %67 / 7275.0 %3 / 4
Opt_Dummy.cpp +
95.2%95.2%
+
95.2 %20 / 2175.0 %3 / 4
Opt_BachAveragedSGD.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
BasisFunctions.h +
96.7%96.7%
+
96.7 %59 / 6175.0 %6 / 8
BasisFunctions.cpp +
87.7%87.7%
+
87.7 %222 / 25381.0 %17 / 21
TD_Multicanonical.cpp +
96.6%96.6%
+
96.6 %197 / 20483.3 %5 / 6
TD_MultithermalMultibaric.cpp +
97.4%97.4%
+
97.4 %147 / 15183.3 %5 / 6
LinearBasisSetExpansion.cpp +
88.7%88.7%
+
88.7 %313 / 35383.3 %30 / 36
Optimizer.cpp +
89.5%89.5%
+
89.5 %682 / 76284.4 %27 / 32
TargetDistribution.cpp +
87.1%87.1%
+
87.1 %189 / 21784.6 %22 / 26
TD_Custom.cpp +
86.5%86.5%
+
86.5 %77 / 8985.7 %6 / 7
VesLinearExpansion.cpp +
96.5%96.5%
+
96.5 %139 / 14485.7 %18 / 21
VesDeltaF.cpp +
97.7%97.7%
+
97.7 %343 / 35187.5 %7 / 8
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
CoeffsMatrix.h +
0.0%
+
0.0 %0 / 1-0 / 0
CoeffsVector.h +
50.0%50.0%
+
50.0 %2 / 4-0 / 0
WaveletCoeffs.cpp +
96.7%96.7%
+
96.7 %145 / 150100.0 %1 / 1
TargetDistModifer.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
VesTools.cpp +
92.1%92.1%
+
92.1 %35 / 38100.0 %2 / 2
CoeffsBase.h +
100.0%
+
100.0 %33 / 33100.0 %2 / 2
TD_Exponential.cpp +
100.0%
+
100.0 %26 / 26100.0 %3 / 3
TD_Grid.cpp +
94.8%94.8%
+
94.8 %55 / 58100.0 %3 / 3
TD_ChiSquared.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
TD_Chi.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
LinearBasisSetExpansion.h +
95.5%95.5%
+
95.5 %21 / 22100.0 %3 / 3
GridIntegrationWeights.cpp +
75.6%75.6%
+
75.6 %34 / 45100.0 %3 / 3
BF_CubicBsplines.cpp +
100.0%
+
100.0 %58 / 58100.0 %4 / 4
TD_ExponentiallyModifiedGaussian.cpp +
90.5%90.5%
+
90.5 %57 / 63100.0 %4 / 4
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %54 / 55100.0 %4 / 4
BF_Powers.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Chebyshev.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Legendre.cpp +
100.0%
+
100.0 %42 / 42100.0 %4 / 4
BF_Gaussians.cpp +
100.0%
+
100.0 %52 / 52100.0 %4 / 4
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %38 / 38100.0 %4 / 4
TD_GeneralizedNormal.cpp +
91.3%91.3%
+
91.3 %63 / 69100.0 %4 / 4
GridProjWeights.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %74 / 75100.0 %5 / 5
BF_Sine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_Combined.cpp +
96.9%96.9%
+
96.9 %63 / 65100.0 %5 / 5
VesTools.h +
65.6%65.6%
+
65.6 %21 / 32100.0 %5 / 5
BF_Cosine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_Fourier.cpp +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
BF_Wavelets.cpp +
100.0%
+
100.0 %118 / 118100.0 %5 / 5
TD_Gaussian.cpp +
90.5%90.5%
+
90.5 %76 / 84100.0 %5 / 5
BF_Custom.cpp +
82.2%82.2%
+
82.2 %125 / 152100.0 %5 / 5
WaveletGrid.cpp +
99.0%99.0%
+
99.0 %104 / 105100.0 %8 / 8
MD_LinearExpansionPES.cpp +
97.0%97.0%
+
97.0 %325 / 335100.0 %9 / 9
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/index-sort-l.html b/coverage/ves/index-sort-l.html new file mode 100644 index 000000000000..9ce33a0ca0f3 --- /dev/null +++ b/coverage/ves/index-sort-l.html @@ -0,0 +1,724 @@ + + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5891718082.0 %
Date:2024-02-22 21:58:45Functions:44467765.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
CoeffsMatrix.h +
0.0%
+
0.0 %0 / 1-0 / 0
GridLinearInterpolation.h +
22.2%22.2%
+
22.2 %2 / 90.0 %0 / 1
CoeffsMatrix.cpp +
29.5%29.5%
+
29.5 %105 / 35625.3 %20 / 79
CoeffsBase.cpp +
42.2%42.2%
+
42.2 %127 / 30146.9 %15 / 32
FermiSwitchingFunction.cpp +
49.3%49.3%
+
49.3 %33 / 6744.4 %4 / 9
CoeffsVector.h +
50.0%50.0%
+
50.0 %2 / 4-0 / 0
CoeffsVector.cpp +
50.7%50.7%
+
50.7 %232 / 45845.5 %45 / 99
GridLinearInterpolation.cpp +
55.0%55.0%
+
55.0 %66 / 12055.6 %5 / 9
TD_ProductDistribution.cpp +
63.2%63.2%
+
63.2 %48 / 7640.0 %4 / 10
VesTools.h +
65.6%65.6%
+
65.6 %21 / 32100.0 %5 / 5
TD_ProductCombination.cpp +
73.3%73.3%
+
73.3 %55 / 7560.0 %6 / 10
VesBias.h +
74.2%74.2%
+
74.2 %66 / 8936.0 %9 / 25
TD_LinearCombination.cpp +
75.3%75.3%
+
75.3 %58 / 7760.0 %6 / 10
GridIntegrationWeights.cpp +
75.6%75.6%
+
75.6 %34 / 45100.0 %3 / 3
VesBias.cpp +
76.2%76.2%
+
76.2 %324 / 42560.0 %27 / 45
TargetDistribution.h +
81.8%81.8%
+
81.8 %18 / 2250.0 %3 / 6
BF_Custom.cpp +
82.2%82.2%
+
82.2 %125 / 152100.0 %5 / 5
TD_Custom.cpp +
86.5%86.5%
+
86.5 %77 / 8985.7 %6 / 7
TargetDistribution.cpp +
87.1%87.1%
+
87.1 %189 / 21784.6 %22 / 26
BasisFunctions.cpp +
87.7%87.7%
+
87.7 %222 / 25381.0 %17 / 21
OutputFesBias.cpp +
88.2%88.2%
+
88.2 %60 / 6840.0 %2 / 5
LinearBasisSetExpansion.cpp +
88.7%88.7%
+
88.7 %313 / 35383.3 %30 / 36
Optimizer.cpp +
89.5%89.5%
+
89.5 %682 / 76284.4 %27 / 32
TD_WellTempered.cpp +
90.3%90.3%
+
90.3 %28 / 3166.7 %4 / 6
TD_ExponentiallyModifiedGaussian.cpp +
90.5%90.5%
+
90.5 %57 / 63100.0 %4 / 4
TD_Gaussian.cpp +
90.5%90.5%
+
90.5 %76 / 84100.0 %5 / 5
TD_GeneralizedNormal.cpp +
91.3%91.3%
+
91.3 %63 / 69100.0 %4 / 4
VesTools.cpp +
92.1%92.1%
+
92.1 %35 / 38100.0 %2 / 2
Opt_Adam.cpp +
93.1%93.1%
+
93.1 %67 / 7275.0 %3 / 4
OutputTargetDistribution.cpp +
93.3%93.3%
+
93.3 %83 / 8950.0 %2 / 4
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
TD_Grid.cpp +
94.8%94.8%
+
94.8 %55 / 58100.0 %3 / 3
Opt_BachAveragedSGD.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
Opt_Dummy.cpp +
95.2%95.2%
+
95.2 %20 / 2175.0 %3 / 4
LinearBasisSetExpansion.h +
95.5%95.5%
+
95.5 %21 / 22100.0 %3 / 3
Opt_RobbinsMonroSGD.cpp +
95.8%95.8%
+
95.8 %23 / 2475.0 %3 / 4
VesLinearExpansion.cpp +
96.5%96.5%
+
96.5 %139 / 14485.7 %18 / 21
TD_Multicanonical.cpp +
96.6%96.6%
+
96.6 %197 / 20483.3 %5 / 6
WaveletCoeffs.cpp +
96.7%96.7%
+
96.7 %145 / 150100.0 %1 / 1
BasisFunctions.h +
96.7%96.7%
+
96.7 %59 / 6175.0 %6 / 8
BF_Combined.cpp +
96.9%96.9%
+
96.9 %63 / 65100.0 %5 / 5
MD_LinearExpansionPES.cpp +
97.0%97.0%
+
97.0 %325 / 335100.0 %9 / 9
TD_MultithermalMultibaric.cpp +
97.4%97.4%
+
97.4 %147 / 15183.3 %5 / 6
VesDeltaF.cpp +
97.7%97.7%
+
97.7 %343 / 35187.5 %7 / 8
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %54 / 55100.0 %4 / 4
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %108 / 11050.0 %2 / 4
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %74 / 75100.0 %5 / 5
WaveletGrid.cpp +
99.0%99.0%
+
99.0 %104 / 105100.0 %8 / 8
TargetDistModifer.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
GridProjWeights.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
TD_Exponential.cpp +
100.0%
+
100.0 %26 / 26100.0 %3 / 3
CoeffsBase.h +
100.0%
+
100.0 %33 / 33100.0 %2 / 2
BF_Sine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_Powers.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Chebyshev.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Cosine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %38 / 38100.0 %4 / 4
BF_Fourier.cpp +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
TD_ChiSquared.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
TD_Chi.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
BF_Legendre.cpp +
100.0%
+
100.0 %42 / 42100.0 %4 / 4
BF_Gaussians.cpp +
100.0%
+
100.0 %52 / 52100.0 %4 / 4
BF_CubicBsplines.cpp +
100.0%
+
100.0 %58 / 58100.0 %4 / 4
BF_Wavelets.cpp +
100.0%
+
100.0 %118 / 118100.0 %5 / 5
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/ves/index.html b/coverage/ves/index.html new file mode 100644 index 000000000000..161d3f3eb205 --- /dev/null +++ b/coverage/ves/index.html @@ -0,0 +1,724 @@ + + + + + + + + LCOV - plumed test coverage - ves + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesHitTotalCoverage
Test:plumed test coverageLines:5891718082.0 %
Date:2024-02-22 21:58:45Functions:44467765.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
BF_Chebyshev.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Combined.cpp +
96.9%96.9%
+
96.9 %63 / 65100.0 %5 / 5
BF_Cosine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_CubicBsplines.cpp +
100.0%
+
100.0 %58 / 58100.0 %4 / 4
BF_Custom.cpp +
82.2%82.2%
+
82.2 %125 / 152100.0 %5 / 5
BF_Fourier.cpp +
100.0%
+
100.0 %38 / 38100.0 %5 / 5
BF_Gaussians.cpp +
100.0%
+
100.0 %52 / 52100.0 %4 / 4
BF_Legendre.cpp +
100.0%
+
100.0 %42 / 42100.0 %4 / 4
BF_Powers.cpp +
100.0%
+
100.0 %35 / 35100.0 %4 / 4
BF_Sine.cpp +
100.0%
+
100.0 %35 / 35100.0 %5 / 5
BF_Wavelets.cpp +
100.0%
+
100.0 %118 / 118100.0 %5 / 5
BasisFunctions.cpp +
87.7%87.7%
+
87.7 %222 / 25381.0 %17 / 21
BasisFunctions.h +
96.7%96.7%
+
96.7 %59 / 6175.0 %6 / 8
CoeffsBase.cpp +
42.2%42.2%
+
42.2 %127 / 30146.9 %15 / 32
CoeffsBase.h +
100.0%
+
100.0 %33 / 33100.0 %2 / 2
CoeffsMatrix.cpp +
29.5%29.5%
+
29.5 %105 / 35625.3 %20 / 79
CoeffsMatrix.h +
0.0%
+
0.0 %0 / 1-0 / 0
CoeffsVector.cpp +
50.7%50.7%
+
50.7 %232 / 45845.5 %45 / 99
CoeffsVector.h +
50.0%50.0%
+
50.0 %2 / 4-0 / 0
FermiSwitchingFunction.cpp +
49.3%49.3%
+
49.3 %33 / 6744.4 %4 / 9
GridIntegrationWeights.cpp +
75.6%75.6%
+
75.6 %34 / 45100.0 %3 / 3
GridLinearInterpolation.cpp +
55.0%55.0%
+
55.0 %66 / 12055.6 %5 / 9
GridLinearInterpolation.h +
22.2%22.2%
+
22.2 %2 / 90.0 %0 / 1
GridProjWeights.h +
100.0%
+
100.0 %6 / 6100.0 %4 / 4
LinearBasisSetExpansion.cpp +
88.7%88.7%
+
88.7 %313 / 35383.3 %30 / 36
LinearBasisSetExpansion.h +
95.5%95.5%
+
95.5 %21 / 22100.0 %3 / 3
MD_LinearExpansionPES.cpp +
97.0%97.0%
+
97.0 %325 / 335100.0 %9 / 9
Opt_Adam.cpp +
93.1%93.1%
+
93.1 %67 / 7275.0 %3 / 4
Opt_BachAveragedSGD.cpp +
95.2%95.2%
+
95.2 %59 / 6275.0 %3 / 4
Opt_Dummy.cpp +
95.2%95.2%
+
95.2 %20 / 2175.0 %3 / 4
Opt_RobbinsMonroSGD.cpp +
95.8%95.8%
+
95.8 %23 / 2475.0 %3 / 4
Optimizer.cpp +
89.5%89.5%
+
89.5 %682 / 76284.4 %27 / 32
Optimizer.h +
94.6%94.6%
+
94.6 %53 / 5690.0 %9 / 10
OutputBasisFunctions.cpp +
98.2%98.2%
+
98.2 %108 / 11050.0 %2 / 4
OutputFesBias.cpp +
88.2%88.2%
+
88.2 %60 / 6840.0 %2 / 5
OutputTargetDistribution.cpp +
93.3%93.3%
+
93.3 %83 / 8950.0 %2 / 4
TD_Chi.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
TD_ChiSquared.cpp +
100.0%
+
100.0 %40 / 40100.0 %3 / 3
TD_Custom.cpp +
86.5%86.5%
+
86.5 %77 / 8985.7 %6 / 7
TD_Exponential.cpp +
100.0%
+
100.0 %26 / 26100.0 %3 / 3
TD_ExponentiallyModifiedGaussian.cpp +
90.5%90.5%
+
90.5 %57 / 63100.0 %4 / 4
TD_Gaussian.cpp +
90.5%90.5%
+
90.5 %76 / 84100.0 %5 / 5
TD_GeneralizedExtremeValue.cpp +
100.0%
+
100.0 %38 / 38100.0 %4 / 4
TD_GeneralizedNormal.cpp +
91.3%91.3%
+
91.3 %63 / 69100.0 %4 / 4
TD_Grid.cpp +
94.8%94.8%
+
94.8 %55 / 58100.0 %3 / 3
TD_LinearCombination.cpp +
75.3%75.3%
+
75.3 %58 / 7760.0 %6 / 10
TD_Multicanonical.cpp +
96.6%96.6%
+
96.6 %197 / 20483.3 %5 / 6
TD_MultithermalMultibaric.cpp +
97.4%97.4%
+
97.4 %147 / 15183.3 %5 / 6
TD_ProductCombination.cpp +
73.3%73.3%
+
73.3 %55 / 7560.0 %6 / 10
TD_ProductDistribution.cpp +
63.2%63.2%
+
63.2 %48 / 7640.0 %4 / 10
TD_Uniform.cpp +
98.2%98.2%
+
98.2 %54 / 55100.0 %4 / 4
TD_VonMises.cpp +
98.7%98.7%
+
98.7 %74 / 75100.0 %5 / 5
TD_WellTempered.cpp +
90.3%90.3%
+
90.3 %28 / 3166.7 %4 / 6
TargetDistModifer.h +
100.0%
+
100.0 %3 / 3100.0 %1 / 1
TargetDistribution.cpp +
87.1%87.1%
+
87.1 %189 / 21784.6 %22 / 26
TargetDistribution.h +
81.8%81.8%
+
81.8 %18 / 2250.0 %3 / 6
VesBias.cpp +
76.2%76.2%
+
76.2 %324 / 42560.0 %27 / 45
VesBias.h +
74.2%74.2%
+
74.2 %66 / 8936.0 %9 / 25
VesDeltaF.cpp +
97.7%97.7%
+
97.7 %343 / 35187.5 %7 / 8
VesLinearExpansion.cpp +
96.5%96.5%
+
96.5 %139 / 14485.7 %18 / 21
VesTools.cpp +
92.1%92.1%
+
92.1 %35 / 38100.0 %2 / 2
VesTools.h +
65.6%65.6%
+
65.6 %21 / 32100.0 %5 / 5
WaveletCoeffs.cpp +
96.7%96.7%
+
96.7 %145 / 150100.0 %1 / 1
WaveletGrid.cpp +
99.0%99.0%
+
99.0 %104 / 105100.0 %8 / 8
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.cpp.func-sort-c.html b/coverage/vesselbase/ActionWithAveraging.cpp.func-sort-c.html new file mode 100644 index 000000000000..3b9bf28e54a2 --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.cpp.func-sort-c.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithAveraging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithAveraging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410995.4 %
Date:2024-02-22 21:58:45Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase19ActionWithAveraging17performOperationsERKb0
_ZN4PLMD10vesselbase19ActionWithAveraging29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD10vesselbase19ActionWithAveragingC1ERKNS_13ActionOptionsE0
_ZNK4PLMD10vesselbase19ActionWithAveraging19ignoreNormalizationEv53
_ZN4PLMD10vesselbase19ActionWithAveraging12runFinalJobsEv58
_ZN4PLMD10vesselbase19ActionWithAveraging18setAveragingActionESt10unique_ptrINS0_15AveragingVesselESt14default_deleteIS3_EERKb68
_ZN4PLMD10vesselbase19ActionWithAveragingC2ERKNS_13ActionOptionsE73
_ZN4PLMD10vesselbase19ActionWithAveraging16registerKeywordsERNS_8KeywordsE93
_ZN4PLMD10vesselbase19ActionWithAveraging12clearAverageEv102
_ZNK4PLMD10vesselbase19ActionWithAveraging21getNumberOfQuantitiesEv374
_ZN4PLMD10vesselbase19ActionWithAveraging12lockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging14unlockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging6updateEv1258
_ZNK4PLMD10vesselbase19ActionWithAveraging11performTaskERKjS3_RNS_10MultiValueE60010
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.cpp.func.html b/coverage/vesselbase/ActionWithAveraging.cpp.func.html new file mode 100644 index 000000000000..68323126086f --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.cpp.func.html @@ -0,0 +1,129 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithAveraging.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithAveraging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410995.4 %
Date:2024-02-22 21:58:45Functions:111478.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase19ActionWithAveraging12clearAverageEv102
_ZN4PLMD10vesselbase19ActionWithAveraging12lockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging12runFinalJobsEv58
_ZN4PLMD10vesselbase19ActionWithAveraging14unlockRequestsEv1240
_ZN4PLMD10vesselbase19ActionWithAveraging16registerKeywordsERNS_8KeywordsE93
_ZN4PLMD10vesselbase19ActionWithAveraging17performOperationsERKb0
_ZN4PLMD10vesselbase19ActionWithAveraging18setAveragingActionESt10unique_ptrINS0_15AveragingVesselESt14default_deleteIS3_EERKb68
_ZN4PLMD10vesselbase19ActionWithAveraging29calculateNumericalDerivativesEPNS_15ActionWithValueE0
_ZN4PLMD10vesselbase19ActionWithAveraging6updateEv1258
_ZN4PLMD10vesselbase19ActionWithAveragingC1ERKNS_13ActionOptionsE0
_ZN4PLMD10vesselbase19ActionWithAveragingC2ERKNS_13ActionOptionsE73
_ZNK4PLMD10vesselbase19ActionWithAveraging11performTaskERKjS3_RNS_10MultiValueE60010
_ZNK4PLMD10vesselbase19ActionWithAveraging19ignoreNormalizationEv53
_ZNK4PLMD10vesselbase19ActionWithAveraging21getNumberOfQuantitiesEv374
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.cpp.gcov.html b/coverage/vesselbase/ActionWithAveraging.cpp.gcov.html new file mode 100644 index 000000000000..a1492d0f963f --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.cpp.gcov.html @@ -0,0 +1,278 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithAveraging.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithAveraging.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:10410995.4 %
Date:2024-02-22 21:58:45Functions:111478.6 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithAveraging.h"
+      23             : #include "analysis/DataCollectionObject.h"
+      24             : #include "analysis/ReadAnalysisFrames.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : #include "bias/ReweightBase.h"
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace vesselbase {
+      31             : 
+      32          93 : void ActionWithAveraging::registerKeywords( Keywords& keys ) {
+      33          93 :   Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys ); ActionAtomistic::registerKeywords( keys );
+      34          93 :   ActionWithArguments::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionWithVessel::registerKeywords( keys );
+      35         186 :   keys.add("compulsory","STRIDE","1","the frequency with which the data should be collected and added to the quantity being averaged");
+      36         186 :   keys.add("compulsory","CLEAR","0","the frequency with which to clear all the accumulated data.  The default value "
+      37             :            "of 0 implies that all the data will be used and that the grid will never be cleared");
+      38         186 :   keys.add("optional","LOGWEIGHTS","list of actions that calculates log weights that should be used to weight configurations when calculating averages");
+      39         186 :   keys.add("compulsory","NORMALIZATION","true","This controls how the data is normalized it can be set equal to true, false or ndata.  The differences between these options are explained in the manual page for \\ref HISTOGRAM");
+      40          93 :   keys.remove("NUMERICAL_DERIVATIVES");
+      41          93 : }
+      42             : 
+      43          73 : ActionWithAveraging::ActionWithAveraging( const ActionOptions& ao ):
+      44             :   Action(ao),
+      45             :   ActionPilot(ao),
+      46             :   ActionAtomistic(ao),
+      47             :   ActionWithArguments(ao),
+      48             :   ActionWithValue(ao),
+      49             :   ActionWithVessel(ao),
+      50          73 :   myaverage(NULL),
+      51          73 :   activated(false),
+      52          73 :   my_analysis_object(NULL),
+      53          73 :   normalization(t),
+      54          73 :   useRunAllTasks(false),
+      55          73 :   clearstride(0),
+      56          73 :   lweight(0),cweight(0)
+      57             : {
+      58         146 :   if( keywords.exists("CLEAR") ) {
+      59          58 :     parse("CLEAR",clearstride);
+      60          58 :     if( clearstride>0 ) {
+      61          12 :       if( clearstride%getStride()!=0 ) error("CLEAR parameter must be a multiple of STRIDE");
+      62          12 :       log.printf("  clearing grid every %u steps \n",clearstride);
+      63             :     }
+      64             :   }
+      65          73 :   if( ActionWithAveraging::getNumberOfArguments()>0 ) {
+      66          29 :     my_analysis_object=dynamic_cast<analysis::AnalysisBase*>( getPntrToArgument(0)->getPntrToAction() );
+      67          38 :     for(unsigned i=1; i<ActionWithAveraging::getNumberOfArguments(); i++) {
+      68           9 :       if( my_analysis_object && my_analysis_object->getLabel()!=(getPntrToArgument(i)->getPntrToAction())->getLabel() ) {
+      69           0 :         error("all arguments should be from one single analysis object");
+      70             :       }
+      71             :     }
+      72          29 :     if( my_analysis_object ) {
+      73           7 :       if( getStride()!=1 ) error("stride should not have been set when calculating average from analysis data");
+      74           7 :       setStride(0); addDependency( my_analysis_object );
+      75             :     }
+      76             :   }
+      77         146 :   if( keywords.exists("LOGWEIGHTS") ) {
+      78         116 :     std::vector<std::string> wwstr; parseVector("LOGWEIGHTS",wwstr);
+      79          58 :     if( wwstr.size()>0 ) log.printf("  reweighting using weights from ");
+      80          58 :     std::vector<Value*> arg( getArguments() );
+      81          66 :     for(unsigned i=0; i<wwstr.size(); ++i) {
+      82           8 :       ActionWithValue* val = plumed.getActionSet().selectWithLabel<ActionWithValue*>(wwstr[i]);
+      83           8 :       if( !val ) error("could not find value named");
+      84           8 :       bias::ReweightBase* iswham=dynamic_cast<bias::ReweightBase*>( val );
+      85           8 :       if( iswham && iswham->buildsWeightStore() ) error("to use wham you must gather data using COLLECT_FRAMES");
+      86           8 :       weights.push_back( val->copyOutput(val->getLabel()) );
+      87           8 :       arg.push_back( val->copyOutput(val->getLabel()) );
+      88           8 :       log.printf("%s ",wwstr[i].c_str() );
+      89             :     }
+      90          58 :     if( wwstr.size()>0 ) log.printf("\n");
+      91          51 :     else log.printf("  weights are all equal to one\n");
+      92          58 :     requestArguments( arg );
+      93          58 :   }
+      94         146 :   if( keywords.exists("NORMALIZATION") ) {
+      95         116 :     std::string normstr; parse("NORMALIZATION",normstr);
+      96          58 :     if( normstr=="true" ) normalization=t;
+      97          35 :     else if( normstr=="false" ) normalization=f;
+      98          26 :     else if( normstr=="ndata" ) normalization=ndata;
+      99           0 :     else error("invalid instruction for NORMALIZATION flag should be true, false, or ndata");
+     100             :   }
+     101          73 : }
+     102             : 
+     103          53 : bool ActionWithAveraging::ignoreNormalization() const {
+     104          53 :   if( normalization==f ) return true;
+     105             :   return false;
+     106             : }
+     107             : 
+     108          68 : void ActionWithAveraging::setAveragingAction( std::unique_ptr<AveragingVessel> av_vessel, const bool& usetasks ) {
+     109             :   // cppcheck-suppress danglingLifetime
+     110          68 :   myaverage=av_vessel.get();
+     111          68 :   addVessel( std::move(av_vessel) );
+     112          68 :   useRunAllTasks=usetasks; resizeFunctions();
+     113          68 : }
+     114             : 
+     115        1240 : void ActionWithAveraging::lockRequests() {
+     116             :   ActionAtomistic::lockRequests();
+     117             :   ActionWithArguments::lockRequests();
+     118        1240 : }
+     119             : 
+     120        1240 : void ActionWithAveraging::unlockRequests() {
+     121             :   ActionAtomistic::unlockRequests();
+     122             :   ActionWithArguments::unlockRequests();
+     123        1240 : }
+     124             : 
+     125         374 : unsigned ActionWithAveraging::getNumberOfQuantities() const {
+     126         374 :   if( my_analysis_object ) return getNumberOfArguments()+2;
+     127             :   return 2;
+     128             : }
+     129             : 
+     130           0 : void ActionWithAveraging::calculateNumericalDerivatives(PLMD::ActionWithValue*) {
+     131           0 :   error("not possible to compute numerical derivatives for this action");
+     132             : }
+     133             : 
+     134        1258 : void ActionWithAveraging::update() {
+     135        1258 :   if( (clearstride!=1 && getStep()==0) || (!onStep() && !my_analysis_object) ) return;
+     136        1177 :   if( my_analysis_object ) {
+     137           7 :     analysis::ReadAnalysisFrames* myfram = dynamic_cast<analysis::ReadAnalysisFrames*>( my_analysis_object );
+     138           7 :     if( !activated && !myfram && !onStep() ) return ;
+     139           7 :     else if( !activated && !my_analysis_object->onStep() ) return ;
+     140             :   }
+     141             : 
+     142             :   // Clear if it is time to reset
+     143        1177 :   if( myaverage ) {
+     144        1176 :     if( myaverage->wasreset() ) clearAverage();
+     145             :   }
+     146             :   // Calculate the weight for all reweighting
+     147        1177 :   if ( weights.size()>0 && !my_analysis_object ) {
+     148        3018 :     double sum=0; for(unsigned i=0; i<weights.size(); ++i) sum+=weights[i]->get();
+     149        1009 :     lweight=sum; cweight = exp( sum );
+     150             :   } else {
+     151         168 :     lweight=0; cweight=1.0;
+     152             :   }
+     153             :   // Prepare the task list for averaging
+     154        1177 :   if( my_analysis_object ) {
+     155        2115 :     for(unsigned i=getFullNumberOfTasks(); i<my_analysis_object->getNumberOfDataPoints(); ++i) addTaskToList(i);
+     156           7 :     deactivateAllTasks(); cweight=0;
+     157        2115 :     for(unsigned i=0; i<my_analysis_object->getNumberOfDataPoints(); ++i) {
+     158        2108 :       taskFlags[i]=1; cweight += my_analysis_object->getWeight(i);
+     159             :     }
+     160           7 :     lockContributors();
+     161             :   }
+     162             :   // Prepare to do the averaging
+     163        1177 :   prepareForAveraging();
+     164             :   // Run all the tasks (if required
+     165        1177 :   if( my_analysis_object || useRunAllTasks ) runAllTasks();
+     166             :   // This the averaging if it is not done using task list
+     167        1032 :   else performOperations( true );
+     168             :   // Update the norm
+     169        1177 :   double normt = cweight; if( !my_analysis_object && normalization==ndata ) normt = 1;
+     170        1177 :   if( myaverage && my_analysis_object ) myaverage->setNorm( normt );
+     171        1170 :   else if( myaverage ) myaverage->setNorm( normt + myaverage->getNorm() );
+     172             :   // Finish the averaging
+     173        1177 :   finishAveraging();
+     174             :   // By resetting here we are ensuring that the grid will be cleared at the start of the next step
+     175        1177 :   if( myaverage ) {
+     176        1176 :     if( getStride()==0 || (clearstride>0 && getStep()%clearstride==0) ) myaverage->reset();
+     177             :   }
+     178             : }
+     179             : 
+     180       60010 : void ActionWithAveraging::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
+     181       60010 :   if( my_analysis_object ) {
+     182        2108 :     const analysis::DataCollectionObject& mystore=my_analysis_object->getStoredData( current, false );
+     183        4216 :     for(unsigned i=0; i<getNumberOfArguments(); ++i) myvals.setValue( 1+i, mystore.getArgumentValue( ActionWithArguments::getArguments()[i]->getName() ) );
+     184        2108 :     myvals.setValue( 0, my_analysis_object->getWeight(current) );
+     185        2108 :     if( normalization==f ) myvals.setValue( 1+getNumberOfArguments(), 1.0 ); else myvals.setValue( 1+getNumberOfArguments(), 1.0 / cweight );
+     186        2108 :     accumulateAverage( myvals );
+     187             :   } else {
+     188       57902 :     runTask( current, myvals );
+     189             :   }
+     190       60010 : }
+     191             : 
+     192         102 : void ActionWithAveraging::clearAverage() { plumed_assert( myaverage->wasreset() ); myaverage->clear(); }
+     193             : 
+     194           0 : void ActionWithAveraging::performOperations( const bool& from_update ) { plumed_error(); }
+     195             : 
+     196          58 : void ActionWithAveraging::runFinalJobs() {
+     197          58 :   if( my_analysis_object && getStride()==0 ) { activated=true; update(); }
+     198          58 : }
+     199             : 
+     200             : }
+     201             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.h.func-sort-c.html b/coverage/vesselbase/ActionWithAveraging.h.func-sort-c.html new file mode 100644 index 000000000000..2e27b36a684c --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithAveraging.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithAveraging.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121392.3 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD10vesselbase19ActionWithAveraging7runTaskERKjRNS_10MultiValueE0
_ZN4PLMD10vesselbase19ActionWithAveraging12getArgumentsEv58
_ZN4PLMD10vesselbase19ActionWithAveraging15finishAveragingEv76
_ZN4PLMD10vesselbase19ActionWithAveraging22getNumberOfDerivativesEv271
_ZN4PLMD10vesselbase19ActionWithAveraging19prepareForAveragingEv1022
_ZNK4PLMD10vesselbase19ActionWithAveraging17accumulateAverageERNS_10MultiValueE2108
_ZNK4PLMD10vesselbase19ActionWithAveraging20getNumberOfArgumentsEv145728
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.h.func.html b/coverage/vesselbase/ActionWithAveraging.h.func.html new file mode 100644 index 000000000000..3712190fcbca --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithAveraging.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithAveraging.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121392.3 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase19ActionWithAveraging12getArgumentsEv58
_ZN4PLMD10vesselbase19ActionWithAveraging15finishAveragingEv76
_ZN4PLMD10vesselbase19ActionWithAveraging19prepareForAveragingEv1022
_ZN4PLMD10vesselbase19ActionWithAveraging22getNumberOfDerivativesEv271
_ZNK4PLMD10vesselbase19ActionWithAveraging17accumulateAverageERNS_10MultiValueE2108
_ZNK4PLMD10vesselbase19ActionWithAveraging20getNumberOfArgumentsEv145728
_ZNK4PLMD10vesselbase19ActionWithAveraging7runTaskERKjRNS_10MultiValueE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithAveraging.h.gcov.html b/coverage/vesselbase/ActionWithAveraging.h.gcov.html new file mode 100644 index 000000000000..1765584c8e5f --- /dev/null +++ b/coverage/vesselbase/ActionWithAveraging.h.gcov.html @@ -0,0 +1,213 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithAveraging.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithAveraging.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:121392.3 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_vesselbase_ActionWithAveraging_h
+      23             : #define __PLUMED_vesselbase_ActionWithAveraging_h
+      24             : 
+      25             : #include "core/ActionPilot.h"
+      26             : #include "core/ActionWithValue.h"
+      27             : #include "core/ActionAtomistic.h"
+      28             : #include "core/ActionWithValue.h"
+      29             : #include "core/ActionWithArguments.h"
+      30             : #include "tools/MultiValue.h"
+      31             : #include "analysis/AnalysisBase.h"
+      32             : #include "ActionWithVessel.h"
+      33             : #include "AveragingVessel.h"
+      34             : 
+      35             : namespace PLMD {
+      36             : namespace vesselbase {
+      37             : 
+      38             : /**
+      39             : \ingroup INHERIT
+      40             : This abstract base class should be used if you are writing some method that calculates an "average" from a set of
+      41             : trajectory frames.  Notice that we use the word average very broadly here and state that even dimensionality
+      42             : reduction algorithms calculate an "average."  In other words, what we mean by average is that the method is going
+      43             : to take in data from each trajectory frame and only calculate the final quantity once a certain amount of data has
+      44             : been collected.
+      45             : */
+      46             : 
+      47             : class ActionWithAveraging :
+      48             :   public ActionPilot,
+      49             :   public ActionAtomistic,
+      50             :   public ActionWithArguments,
+      51             :   public ActionWithValue,
+      52             :   public ActionWithVessel
+      53             : {
+      54             :   friend class AveragingVessel;
+      55             : private:
+      56             : /// The vessel which is used to compute averages
+      57             :   AveragingVessel* myaverage;
+      58             : /// The weights we are going to use for reweighting
+      59             :   std::vector<Value*> weights;
+      60             : /// Are we accumulated the unormalized quantity
+      61             :   bool activated;
+      62             : /// An object in which analysis data has been stored
+      63             :   analysis::AnalysisBase* my_analysis_object;
+      64             :   enum {t,f,ndata} normalization;
+      65             : protected:
+      66             : /// This ensures runAllTasks is used
+      67             :   bool useRunAllTasks;
+      68             : /// The frequency with which to clear the grid
+      69             :   unsigned clearstride;
+      70             : /// The current weight and its logarithm
+      71             :   double lweight, cweight;
+      72             : /// Set the averaging action
+      73             :   void setAveragingAction( std::unique_ptr<AveragingVessel> av_vessel, const bool& usetasks );
+      74             : /// Check if we are using the normalization condition when calculating this quantity
+      75             :   bool noNormalization() const ;
+      76             : /// Are we storing data then averaging
+      77             :   bool storeThenAverage() const ;
+      78             : public:
+      79             :   static void registerKeywords( Keywords& keys );
+      80             :   explicit ActionWithAveraging( const ActionOptions& );
+      81             :   void lockRequests() override;
+      82             :   void unlockRequests() override;
+      83             :   void calculateNumericalDerivatives(PLMD::ActionWithValue*) override;
+      84         271 :   unsigned getNumberOfDerivatives() override { return 0; }
+      85             :   unsigned getNumberOfQuantities() const override;
+      86             :   unsigned getNumberOfArguments() const override;
+      87             : /// Overwrite ActionWithArguments getArguments() so that we don't return the bias
+      88             :   using ActionWithArguments::getArguments;
+      89             :   std::vector<Value*> getArguments();
+      90             :   void update() override;
+      91             : /// This does the clearing of the action
+      92             :   virtual void clearAverage();
+      93             : /// This is done before the averaging comences
+      94        1022 :   virtual void prepareForAveraging() {}
+      95             : /// This does the averaging operation
+      96             :   virtual void performOperations( const bool& from_update );
+      97             : /// Does the calculation
+      98             :   void performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const override;
+      99             : ///
+     100           0 :   virtual void runTask( const unsigned& current, MultiValue& myvals ) const { plumed_error(); }
+     101             : ///
+     102        2108 :   virtual void accumulateAverage( MultiValue& myvals ) const {}
+     103             : /// This is done once the averaging is finished
+     104          76 :   virtual void finishAveraging() {}
+     105             : ///
+     106             :   void runFinalJobs() override;
+     107             : ///
+     108             :   virtual bool ignoreNormalization() const ;
+     109             : };
+     110             : 
+     111             : inline
+     112      145728 : unsigned ActionWithAveraging::getNumberOfArguments() const {
+     113         226 :   return ActionWithArguments::getNumberOfArguments() - weights.size();
+     114             : }
+     115             : 
+     116             : inline
+     117          58 : std::vector<Value*> ActionWithAveraging::getArguments() {
+     118          58 :   std::vector<Value*> arg_vals( ActionWithArguments::getArguments() );
+     119          58 :   for(unsigned i=0; i<weights.size(); ++i) arg_vals.erase(arg_vals.end()-1);
+     120          58 :   return arg_vals;
+     121             : }
+     122             : 
+     123             : inline
+     124             : bool ActionWithAveraging::noNormalization() const {
+     125          36 :   return normalization==f;
+     126             : }
+     127             : 
+     128             : inline
+     129             : bool ActionWithAveraging::storeThenAverage() const {
+     130         105 :   if( my_analysis_object ) return true;
+     131             :   return false;
+     132             : }
+     133             : 
+     134             : }
+     135             : }
+     136             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.cpp.func-sort-c.html b/coverage/vesselbase/ActionWithInputVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..59fb25a311db --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithInputVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithInputVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:323786.5 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase21ActionWithInputVessel17applyBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD10vesselbase21ActionWithInputVesselC1ERKNS_13ActionOptionsE0
_ZN4PLMD10vesselbase21ActionWithInputVessel29calculateNumericalDerivativesEPNS_15ActionWithValueE5
_ZN4PLMD10vesselbase21ActionWithInputVessel12readArgumentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE24
_ZN4PLMD10vesselbase21ActionWithInputVesselC2ERKNS_13ActionOptionsE24
_ZN4PLMD10vesselbase21ActionWithInputVessel16registerKeywordsERNS_8KeywordsE30
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.cpp.func.html b/coverage/vesselbase/ActionWithInputVessel.cpp.func.html new file mode 100644 index 000000000000..6d1c0e9c9fb2 --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithInputVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithInputVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:323786.5 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase21ActionWithInputVessel12readArgumentERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE24
_ZN4PLMD10vesselbase21ActionWithInputVessel16registerKeywordsERNS_8KeywordsE30
_ZN4PLMD10vesselbase21ActionWithInputVessel17applyBridgeForcesERKSt6vectorIdSaIdEE0
_ZN4PLMD10vesselbase21ActionWithInputVessel29calculateNumericalDerivativesEPNS_15ActionWithValueE5
_ZN4PLMD10vesselbase21ActionWithInputVesselC1ERKNS_13ActionOptionsE0
_ZN4PLMD10vesselbase21ActionWithInputVesselC2ERKNS_13ActionOptionsE24
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.cpp.gcov.html b/coverage/vesselbase/ActionWithInputVessel.cpp.gcov.html new file mode 100644 index 000000000000..1ae2825bd8a2 --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.cpp.gcov.html @@ -0,0 +1,165 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithInputVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithInputVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:323786.5 %
Date:2024-02-22 21:58:45Functions:4666.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithInputVessel.h"
+      23             : #include "StoreDataVessel.h"
+      24             : #include "BridgeVessel.h"
+      25             : #include "core/PlumedMain.h"
+      26             : #include "core/ActionSet.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace vesselbase {
+      30             : 
+      31          30 : void ActionWithInputVessel::registerKeywords(Keywords& keys) {
+      32          60 :   keys.add("compulsory","DATA","certain actions in plumed work by calculating a list of variables and summing over them. "
+      33             :            "This particular action can be used to calculate functions of these base variables or prints "
+      34             :            "them to a file. This keyword thus takes the label of one of those such variables as input.");
+      35          60 :   keys.reserve("compulsory","GRID","the action that creates the input grid you would like to use");
+      36          30 : }
+      37             : 
+      38          24 : ActionWithInputVessel::ActionWithInputVessel(const ActionOptions&ao):
+      39             :   Action(ao),
+      40          24 :   arguments(NULL),
+      41          24 :   myBridgeVessel(NULL)
+      42             : {
+      43          24 : }
+      44             : 
+      45          24 : void ActionWithInputVessel::readArgument( const std::string& type ) {
+      46             :   std::string mlab;
+      47          96 :   if( keywords.exists("DATA") && type!="grid" ) parse("DATA",mlab);
+      48          24 :   ActionWithVessel* mves= plumed.getActionSet().selectWithLabel<ActionWithVessel*>(mlab);
+      49          24 :   if(!mves) error("action labelled " +  mlab + " does not exist or does not have vessels");
+      50          24 :   addDependency(mves);
+      51             : 
+      52          24 :   ActionWithValue* aval=dynamic_cast<ActionWithValue*>( this );
+      53          24 :   if(aval) {
+      54           2 :     if( aval->checkNumericalDerivatives() ) {
+      55           1 :       ActionWithValue* aval2=dynamic_cast<ActionWithValue*>( mves );
+      56           1 :       plumed_assert( aval2 ); aval2->useNumericalDerivatives();
+      57             :     }
+      58             :   }
+      59             : 
+      60          24 :   if( type=="bridge" ) {
+      61           2 :     ActionWithVessel* aves=dynamic_cast<ActionWithVessel*>( this );
+      62           2 :     plumed_assert(aves); myBridgeVessel = mves->addBridgingVessel( aves );
+      63           2 :     arguments = dynamic_cast<Vessel*>( myBridgeVessel );
+      64          22 :   } else  if( type=="store" ) {
+      65          22 :     arguments = dynamic_cast<Vessel*>( mves->buildDataStashes( NULL ) );
+      66             :   } else {
+      67           0 :     plumed_error();
+      68             :   }
+      69          24 : }
+      70             : 
+      71           5 : void ActionWithInputVessel::calculateNumericalDerivatives( ActionWithValue* a ) {
+      72           5 :   if(!a) {
+      73           5 :     a=dynamic_cast<ActionWithValue*>(this);
+      74           5 :     plumed_massert(a,"cannot compute numerical derivatives for an action without values");
+      75             :   }
+      76           5 :   if( myBridgeVessel ) {
+      77           5 :     myBridgeVessel->completeNumericalDerivatives();
+      78             :   } else {
+      79           0 :     error("numerical derivatives are not implemented");
+      80             :   }
+      81           5 : }
+      82             : 
+      83           0 : void ActionWithInputVessel::applyBridgeForces( const std::vector<double>& bb ) {
+      84           0 :   plumed_dbg_assert( myBridgeVessel ); addBridgeForces( bb );
+      85           0 : }
+      86             : 
+      87             : }
+      88             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.h.func-sort-c.html b/coverage/vesselbase/ActionWithInputVessel.h.func-sort-c.html new file mode 100644 index 000000000000..b1c57ad8d227 --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithInputVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithInputVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2366.7 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase21ActionWithInputVessel15addBridgeForcesERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.h.func.html b/coverage/vesselbase/ActionWithInputVessel.h.func.html new file mode 100644 index 000000000000..e3daf76675dd --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithInputVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithInputVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2366.7 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase21ActionWithInputVessel15addBridgeForcesERKSt6vectorIdSaIdEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithInputVessel.h.gcov.html b/coverage/vesselbase/ActionWithInputVessel.h.gcov.html new file mode 100644 index 000000000000..f4f6504e5616 --- /dev/null +++ b/coverage/vesselbase/ActionWithInputVessel.h.gcov.html @@ -0,0 +1,147 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithInputVessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithInputVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2366.7 %
Date:2024-02-22 21:58:45Functions:010.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2014-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_vesselbase_ActionWithInputVessel_h
+      23             : #define __PLUMED_vesselbase_ActionWithInputVessel_h
+      24             : 
+      25             : #include "core/Action.h"
+      26             : #include "Vessel.h"
+      27             : #include <vector>
+      28             : 
+      29             : namespace PLMD {
+      30             : namespace vesselbase {
+      31             : 
+      32             : /**
+      33             : \ingroup MULTIINHERIT
+      34             : */
+      35             : 
+      36             : class ActionWithInputVessel : public virtual Action {
+      37             : private:
+      38             :   Vessel* arguments;
+      39             :   BridgeVessel* myBridgeVessel;
+      40             : protected:
+      41             : /// What type of arguments are we reading in
+      42             :   void readArgument( const std::string& type );
+      43             : /// Return a pointer to specific argument
+      44             :   Vessel* getPntrToArgument();
+      45             : /// Add forces to arguments (used in apply)
+      46             :   void addForcesOnArguments( const std::vector<double>& forces );
+      47             : public:
+      48             : /// Registers the list of keywords
+      49             :   static void registerKeywords( Keywords& keys );
+      50             :   explicit ActionWithInputVessel(const ActionOptions&);
+      51          22 :   virtual ~ActionWithInputVessel() {}
+      52             : /// Calculate the numerical derivatives
+      53             : /// N.B. only pass an ActionWithValue to this routine if you know exactly what you
+      54             : /// are doing.  The default will be correct for the vast majority of cases
+      55             :   virtual void calculateNumericalDerivatives( ActionWithValue* a=NULL );
+      56             : /// Apply forces from the bridge
+      57             :   void applyBridgeForces( const std::vector<double>& bb );
+      58             : /// Apply forces from the bridge
+      59           0 :   virtual void addBridgeForces( const std::vector<double>& bb ) {}
+      60             : };
+      61             : 
+      62             : inline
+      63             : Vessel* ActionWithInputVessel::getPntrToArgument() {
+      64          74 :   return arguments;
+      65             : }
+      66             : 
+      67             : }
+      68             : }
+      69             : 
+      70             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.cpp.func-sort-c.html b/coverage/vesselbase/ActionWithVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..e497fa10fdad --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.cpp.func-sort-c.html @@ -0,0 +1,177 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18619993.5 %
Date:2024-02-22 21:58:45Functions:202676.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase16ActionWithVessel14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_0
_ZN4PLMD10vesselbase16ActionWithVessel17getVesselWithNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD10vesselbase16ActionWithVesselC1ERKNS_13ActionOptionsE0
_ZN4PLMD10vesselbase16ActionWithVesselD0Ev0
_ZN4PLMD10vesselbase16ActionWithVesselD1Ev0
_ZNK4PLMD10vesselbase16ActionWithVessel27transformBridgedDerivativesERKjRNS_10MultiValueES5_0
_ZN4PLMD10vesselbase16ActionWithVessel17addBridgingVesselEPS1_46
_ZN4PLMD10vesselbase16ActionWithVessel16buildDataStashesEPS1_192
_ZN4PLMD10vesselbase16ActionWithVessel9addVesselERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_i363
_ZN4PLMD10vesselbase16ActionWithVessel18readVesselKeywordsEv418
_ZN4PLMD10vesselbase16ActionWithVessel9addVesselESt10unique_ptrINS0_6VesselESt14default_deleteIS3_EE559
_ZN4PLMD10vesselbase16ActionWithVesselC2ERKNS_13ActionOptionsE571
_ZN4PLMD10vesselbase16ActionWithVesselD2Ev571
_ZN4PLMD10vesselbase16ActionWithVessel16registerKeywordsERNS_8KeywordsE797
_ZN4PLMD10vesselbase16ActionWithVessel16needsDerivativesEv854
_ZN4PLMD10vesselbase16ActionWithVessel15resizeFunctionsEv1418
_ZN4PLMD10vesselbase16ActionWithVessel16lockContributorsEv3317
_ZN4PLMD10vesselbase16ActionWithVessel18deactivateAllTasksEv3317
_ZN4PLMD10vesselbase16ActionWithVessel20getForcesFromVesselsERSt6vectorIdSaIdEE7223
_ZN4PLMD10vesselbase16ActionWithVessel11runAllTasksEv19967
_ZN4PLMD10vesselbase16ActionWithVessel18finishComputationsERKSt6vectorIdSaIdEE22992
_ZN4PLMD10vesselbase16ActionWithVessel28doJobsRequiredBeforeTaskListEv22992
_ZN4PLMD10vesselbase16ActionWithVessel15getSizeOfBufferERj23525
_ZNK4PLMD10vesselbase16ActionWithVessel21taskIsCurrentlyActiveERKj213721
_ZN4PLMD10vesselbase16ActionWithVessel19calculateAllVesselsERKjRNS_10MultiValueES5_RSt6vectorIdSaIdEERS6_IjSaIjEE467196
_ZN4PLMD10vesselbase16ActionWithVessel13addTaskToListERKj12661371
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.cpp.func.html b/coverage/vesselbase/ActionWithVessel.cpp.func.html new file mode 100644 index 000000000000..7ec6200de9d1 --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.cpp.func.html @@ -0,0 +1,177 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18619993.5 %
Date:2024-02-22 21:58:45Functions:202676.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase16ActionWithVessel11runAllTasksEv19967
_ZN4PLMD10vesselbase16ActionWithVessel13addTaskToListERKj12661371
_ZN4PLMD10vesselbase16ActionWithVessel14retrieveDomainERNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES8_0
_ZN4PLMD10vesselbase16ActionWithVessel15getSizeOfBufferERj23525
_ZN4PLMD10vesselbase16ActionWithVessel15resizeFunctionsEv1418
_ZN4PLMD10vesselbase16ActionWithVessel16buildDataStashesEPS1_192
_ZN4PLMD10vesselbase16ActionWithVessel16lockContributorsEv3317
_ZN4PLMD10vesselbase16ActionWithVessel16needsDerivativesEv854
_ZN4PLMD10vesselbase16ActionWithVessel16registerKeywordsERNS_8KeywordsE797
_ZN4PLMD10vesselbase16ActionWithVessel17addBridgingVesselEPS1_46
_ZN4PLMD10vesselbase16ActionWithVessel17getVesselWithNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD10vesselbase16ActionWithVessel18deactivateAllTasksEv3317
_ZN4PLMD10vesselbase16ActionWithVessel18finishComputationsERKSt6vectorIdSaIdEE22992
_ZN4PLMD10vesselbase16ActionWithVessel18readVesselKeywordsEv418
_ZN4PLMD10vesselbase16ActionWithVessel19calculateAllVesselsERKjRNS_10MultiValueES5_RSt6vectorIdSaIdEERS6_IjSaIjEE467196
_ZN4PLMD10vesselbase16ActionWithVessel20getForcesFromVesselsERSt6vectorIdSaIdEE7223
_ZN4PLMD10vesselbase16ActionWithVessel28doJobsRequiredBeforeTaskListEv22992
_ZN4PLMD10vesselbase16ActionWithVessel9addVesselERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_i363
_ZN4PLMD10vesselbase16ActionWithVessel9addVesselESt10unique_ptrINS0_6VesselESt14default_deleteIS3_EE559
_ZN4PLMD10vesselbase16ActionWithVesselC1ERKNS_13ActionOptionsE0
_ZN4PLMD10vesselbase16ActionWithVesselC2ERKNS_13ActionOptionsE571
_ZN4PLMD10vesselbase16ActionWithVesselD0Ev0
_ZN4PLMD10vesselbase16ActionWithVesselD1Ev0
_ZN4PLMD10vesselbase16ActionWithVesselD2Ev571
_ZNK4PLMD10vesselbase16ActionWithVessel21taskIsCurrentlyActiveERKj213721
_ZNK4PLMD10vesselbase16ActionWithVessel27transformBridgedDerivativesERKjRNS_10MultiValueES5_0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.cpp.gcov.html b/coverage/vesselbase/ActionWithVessel.cpp.gcov.html new file mode 100644 index 000000000000..aeb76d7abed5 --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.cpp.gcov.html @@ -0,0 +1,472 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:18619993.5 %
Date:2024-02-22 21:58:45Functions:202676.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ActionWithVessel.h"
+      23             : #include "tools/Communicator.h"
+      24             : #include "Vessel.h"
+      25             : #include "ShortcutVessel.h"
+      26             : #include "StoreDataVessel.h"
+      27             : #include "VesselRegister.h"
+      28             : #include "BridgeVessel.h"
+      29             : #include "FunctionVessel.h"
+      30             : #include "StoreDataVessel.h"
+      31             : #include "tools/OpenMP.h"
+      32             : #include "tools/Stopwatch.h"
+      33             : 
+      34             : namespace PLMD {
+      35             : namespace vesselbase {
+      36             : 
+      37         797 : void ActionWithVessel::registerKeywords(Keywords& keys) {
+      38        1594 :   keys.add("hidden","TOL","this keyword can be used to speed up your calculation. When accumulating sums in which the individual "
+      39             :            "terms are numbers in between zero and one it is assumed that terms less than a certain tolerance "
+      40             :            "make only a small contribution to the sum.  They can thus be safely ignored as can the the derivatives "
+      41             :            "wrt these small quantities.");
+      42        1594 :   keys.add("hidden","MAXDERIVATIVES","The maximum number of derivatives that can be used when storing data.  This controls when "
+      43             :            "we have to start using lowmem");
+      44        1594 :   keys.addFlag("SERIAL",false,"do the calculation in serial.  Do not use MPI");
+      45        1594 :   keys.addFlag("LOWMEM",false,"lower the memory requirements");
+      46        1594 :   keys.addFlag("TIMINGS",false,"output information on the timings of the various parts of the calculation");
+      47        1594 :   keys.reserveFlag("HIGHMEM",false,"use a more memory intensive version of this collective variable");
+      48         797 :   keys.add( vesselRegister().getKeywords() );
+      49         797 : }
+      50             : 
+      51         571 : ActionWithVessel::ActionWithVessel(const ActionOptions&ao):
+      52             :   Action(ao),
+      53         571 :   serial(false),
+      54         571 :   lowmem(false),
+      55         571 :   noderiv(true),
+      56         571 :   actionIsBridged(false),
+      57         571 :   nactive_tasks(0),
+      58         571 :   dertime_can_be_off(false),
+      59         571 :   dertime(true),
+      60         571 :   contributorsAreUnlocked(false),
+      61         571 :   weightHasDerivatives(false),
+      62         571 :   mydata(NULL)
+      63             : {
+      64         571 :   maxderivatives=309; parse("MAXDERIVATIVES",maxderivatives);
+      65        1680 :   if( keywords.exists("SERIAL") ) parseFlag("SERIAL",serial);
+      66          33 :   else serial=true;
+      67         571 :   if(serial)log.printf("  doing calculation in serial\n");
+      68        1142 :   if( keywords.exists("LOWMEM") ) {
+      69        1078 :     plumed_assert( !keywords.exists("HIGHMEM") );
+      70         539 :     parseFlag("LOWMEM",lowmem);
+      71         539 :     if(lowmem) {
+      72          29 :       log.printf("  lowering memory requirements\n");
+      73          29 :       dertime_can_be_off=true;
+      74             :     }
+      75             :   }
+      76        1142 :   if( keywords.exists("HIGHMEM") ) {
+      77          46 :     plumed_assert( !keywords.exists("LOWMEM") );
+      78          23 :     bool highmem; parseFlag("HIGHMEM",highmem);
+      79          23 :     lowmem=!highmem;
+      80          23 :     if(!lowmem) log.printf("  increasing the memory requirements\n");
+      81             :   }
+      82         571 :   tolerance=nl_tolerance=epsilon;
+      83        1602 :   if( keywords.exists("TOL") ) parse("TOL",tolerance);
+      84         571 :   if( tolerance>epsilon) {
+      85           6 :     log.printf(" Ignoring contributions less than %f \n",tolerance);
+      86             :   }
+      87         571 :   parseFlag("TIMINGS",timers);
+      88         571 :   stopwatch.start(); stopwatch.pause();
+      89         571 : }
+      90             : 
+      91         571 : ActionWithVessel::~ActionWithVessel() {
+      92         571 :   stopwatch.start(); stopwatch.stop();
+      93         571 :   if(timers) {
+      94           0 :     log.printf("timings for action %s with label %s \n", getName().c_str(), getLabel().c_str() );
+      95           0 :     log<<stopwatch;
+      96             :   }
+      97         571 : }
+      98             : 
+      99         363 : void ActionWithVessel::addVessel( const std::string& name, const std::string& input, const int numlab ) {
+     100         363 :   VesselOptions da(name,"",numlab,input,this);
+     101         363 :   auto vv=vesselRegister().create(name,da);
+     102         363 :   FunctionVessel* fv=dynamic_cast<FunctionVessel*>(vv.get());
+     103         363 :   if( fv ) {
+     104         333 :     std::string mylabel=Vessel::transformName( name );
+     105         333 :     plumed_massert( keywords.outputComponentExists(mylabel,false), "a description of the value calculated by vessel " + name + " has not been added to the manual");
+     106             :   }
+     107         363 :   addVessel(std::move(vv));
+     108         363 : }
+     109             : 
+     110         559 : void ActionWithVessel::addVessel( std::unique_ptr<Vessel> vv_ptr ) {
+     111             : 
+     112             : // In the original code, the dynamically casted pointer was deleted here.
+     113             : // Now that vv_ptr is a unique_ptr, the object will be deleted automatically when
+     114             : // exiting this routine.
+     115         559 :   if(dynamic_cast<ShortcutVessel*>(vv_ptr.get())) return;
+     116             : 
+     117         548 :   vv_ptr->checkRead();
+     118             : 
+     119         548 :   StoreDataVessel* mm=dynamic_cast<StoreDataVessel*>( vv_ptr.get() );
+     120         548 :   if( mydata && mm ) error("cannot have more than one StoreDataVessel in one action");
+     121         548 :   else if( mm ) mydata=mm;
+     122         417 :   else dertime_can_be_off=false;
+     123             : 
+     124             : // Ownership is transferred to functions
+     125         548 :   functions.emplace_back(std::move(vv_ptr));
+     126             : }
+     127             : 
+     128          46 : BridgeVessel* ActionWithVessel::addBridgingVessel( ActionWithVessel* tome ) {
+     129          92 :   VesselOptions da("","",0,"",this);
+     130             :   auto bv=Tools::make_unique<BridgeVessel>(da);
+     131          46 :   bv->setOutputAction( tome );
+     132          46 :   tome->actionIsBridged=true; dertime_can_be_off=false;
+     133             : // store this pointer in order to return it later.
+     134             : // notice that I cannot access this with functions.tail().get()
+     135             : // since functions contains pointers to a different class (Vessel)
+     136             :   auto toBeReturned=bv.get();
+     137          46 :   functions.emplace_back( std::move(bv) );
+     138          46 :   resizeFunctions();
+     139          46 :   return toBeReturned;
+     140          46 : }
+     141             : 
+     142         192 : StoreDataVessel* ActionWithVessel::buildDataStashes( ActionWithVessel* actionThatUses ) {
+     143         192 :   if(mydata) {
+     144          87 :     if( actionThatUses ) mydata->addActionThatUses( actionThatUses );
+     145          87 :     return mydata;
+     146             :   }
+     147             : 
+     148         210 :   VesselOptions da("","",0,"",this);
+     149             :   auto mm=Tools::make_unique<StoreDataVessel>(da);
+     150         105 :   if( actionThatUses ) mm->addActionThatUses( actionThatUses );
+     151         105 :   addVessel(std::move(mm));
+     152             : 
+     153             :   // Make sure resizing of vessels is done
+     154         105 :   resizeFunctions();
+     155             : 
+     156         105 :   return mydata;
+     157         105 : }
+     158             : 
+     159    12661371 : void ActionWithVessel::addTaskToList( const unsigned& taskCode ) {
+     160    12661371 :   fullTaskList.push_back( taskCode ); taskFlags.push_back(0);
+     161    12661371 :   plumed_assert( fullTaskList.size()==taskFlags.size() );
+     162    12661371 : }
+     163             : 
+     164         418 : void ActionWithVessel::readVesselKeywords() {
+     165             :   // Set maxderivatives if it is too big
+     166         418 :   if( maxderivatives>getNumberOfDerivatives() ) maxderivatives=getNumberOfDerivatives();
+     167             : 
+     168             :   // Loop over all keywords find the vessels and create appropriate functions
+     169       10163 :   for(unsigned i=0; i<keywords.size(); ++i) {
+     170        9745 :     std::string thiskey,input; thiskey=keywords.getKeyword(i);
+     171             :     // Check if this is a key for a vessel
+     172        9745 :     if( vesselRegister().check(thiskey) ) {
+     173        5548 :       plumed_assert( keywords.style(thiskey,"vessel") );
+     174        2774 :       bool dothis=false; parseFlag(thiskey,dothis);
+     175        2774 :       if(dothis) addVessel( thiskey, input );
+     176             : 
+     177        2774 :       parse(thiskey,input);
+     178        2774 :       if(input.size()!=0) {
+     179         128 :         addVessel( thiskey, input );
+     180             :       } else {
+     181        2646 :         for(unsigned i=1;; ++i) {
+     182        2671 :           if( !parseNumbered(thiskey,i,input) ) break;
+     183          25 :           std::string ss; Tools::convert(i,ss);
+     184          25 :           addVessel( thiskey, input, i );
+     185             :           input.clear();
+     186          25 :         }
+     187             :       }
+     188             :     }
+     189             :   }
+     190             : 
+     191             :   // Make sure all vessels have had been resized at start
+     192         418 :   if( functions.size()>0 ) resizeFunctions();
+     193         418 : }
+     194             : 
+     195        1418 : void ActionWithVessel::resizeFunctions() {
+     196        3643 :   for(unsigned i=0; i<functions.size(); ++i) functions[i]->resize();
+     197        1418 : }
+     198             : 
+     199         854 : void ActionWithVessel::needsDerivatives() {
+     200             :   // Turn on the derivatives and resize
+     201         854 :   noderiv=false; resizeFunctions();
+     202             :   // Setting contributors unlocked here ensures that link cells are ignored
+     203         854 :   contributorsAreUnlocked=true; contributorsAreUnlocked=false;
+     204             :   // And turn on the derivatives in all actions on which we are dependent
+     205        6042 :   for(unsigned i=0; i<getDependencies().size(); ++i) {
+     206        5188 :     ActionWithVessel* vv=dynamic_cast<ActionWithVessel*>( getDependencies()[i] );
+     207        5188 :     if(vv) vv->needsDerivatives();
+     208             :   }
+     209         854 : }
+     210             : 
+     211        3317 : void ActionWithVessel::lockContributors() {
+     212        3317 :   nactive_tasks = 0;
+     213    18492794 :   for(unsigned i=0; i<fullTaskList.size(); ++i) {
+     214    18489477 :     if( taskFlags[i]>0 ) nactive_tasks++;
+     215             :   }
+     216             : 
+     217             :   unsigned n=0;
+     218        3317 :   partialTaskList.resize( nactive_tasks );
+     219        3317 :   indexOfTaskInFullList.resize( nactive_tasks );
+     220    18492794 :   for(unsigned i=0; i<fullTaskList.size(); ++i) {
+     221             :     // Deactivate sets inactive tasks to number not equal to zero
+     222    18489477 :     if( taskFlags[i]>0 ) {
+     223     5482476 :       partialTaskList[n] = fullTaskList[i];
+     224     5482476 :       indexOfTaskInFullList[n]=i;
+     225     5482476 :       n++;
+     226             :     }
+     227             :   }
+     228             :   plumed_dbg_assert( n==nactive_tasks );
+     229        8201 :   for(unsigned i=0; i<functions.size(); ++i) {
+     230        4884 :     BridgeVessel* bb = dynamic_cast<BridgeVessel*>( functions[i].get() );
+     231        4884 :     if( bb ) bb->copyTaskFlags();
+     232             :   }
+     233             :   // Resize mydata to accommodate all active tasks
+     234        3317 :   if( mydata ) mydata->resize();
+     235        3317 :   contributorsAreUnlocked=false;
+     236        3317 : }
+     237             : 
+     238        3317 : void ActionWithVessel::deactivateAllTasks() {
+     239        3317 :   contributorsAreUnlocked=true; nactive_tasks = 0;
+     240        3317 :   taskFlags.assign(taskFlags.size(),0);
+     241        3317 : }
+     242             : 
+     243      213721 : bool ActionWithVessel::taskIsCurrentlyActive( const unsigned& index ) const {
+     244      213721 :   plumed_dbg_assert( index<taskFlags.size() ); return (taskFlags[index]>0);
+     245             : }
+     246             : 
+     247       22992 : void ActionWithVessel::doJobsRequiredBeforeTaskList() {
+     248             :   // Do any preparatory stuff for functions
+     249       58265 :   for(unsigned j=0; j<functions.size(); ++j) functions[j]->prepare();
+     250       22992 : }
+     251             : 
+     252       23525 : unsigned ActionWithVessel::getSizeOfBuffer( unsigned& bufsize ) {
+     253       59494 :   for(unsigned i=0; i<functions.size(); ++i) functions[i]->setBufferStart( bufsize );
+     254       23525 :   if( buffer.size()!=bufsize ) buffer.resize( bufsize );
+     255       23525 :   if( mydata ) {
+     256             :     unsigned dsize=mydata->getSizeOfDerivativeList();
+     257        2574 :     if( der_list.size()!=dsize ) der_list.resize( dsize );
+     258             :   }
+     259       23525 :   return bufsize;
+     260             : }
+     261             : 
+     262       19967 : void ActionWithVessel::runAllTasks() {
+     263       19967 :   plumed_massert( !contributorsAreUnlocked && functions.size()>0, "you must have a call to readVesselKeywords somewhere" );
+     264       19967 :   unsigned stride=comm.Get_size();
+     265       19967 :   unsigned rank=comm.Get_rank();
+     266       19967 :   if(serial) { stride=1; rank=0; }
+     267             : 
+     268             :   // Make sure jobs are done
+     269       19967 :   if(timers) stopwatch.start("1 Prepare Tasks");
+     270       19967 :   doJobsRequiredBeforeTaskList();
+     271       19967 :   if(timers) stopwatch.stop("1 Prepare Tasks");
+     272             : 
+     273             :   // Get number of threads for OpenMP
+     274       19967 :   unsigned nt=OpenMP::getNumThreads();
+     275       19967 :   if( nt*stride*2>nactive_tasks || !threadSafe()) nt=1;
+     276             : 
+     277             :   // Get size for buffer
+     278       19967 :   unsigned bsize=0, bufsize=getSizeOfBuffer( bsize );
+     279             :   // Clear buffer
+     280       19967 :   buffer.assign( buffer.size(), 0.0 );
+     281             :   // Switch off calculation of derivatives in main loop
+     282       19967 :   if( dertime_can_be_off ) dertime=false;
+     283             : 
+     284       19967 :   if(timers) stopwatch.start("2 Loop over tasks");
+     285       19967 :   #pragma omp parallel num_threads(nt)
+     286             :   {
+     287             :     std::vector<double> omp_buffer;
+     288             :     if( nt>1 ) omp_buffer.resize( bufsize, 0.0 );
+     289             :     MultiValue myvals( getNumberOfQuantities(), getNumberOfDerivatives() );
+     290             :     MultiValue bvals( getNumberOfQuantities(), getNumberOfDerivatives() );
+     291             :     myvals.clearAll(); bvals.clearAll();
+     292             : 
+     293             :     #pragma omp for nowait schedule(dynamic)
+     294             :     for(unsigned i=rank; i<nactive_tasks; i+=stride) {
+     295             :       // Calculate the stuff in the loop for this action
+     296             :       performTask( indexOfTaskInFullList[i], partialTaskList[i], myvals );
+     297             : 
+     298             :       // Check for conditions that allow us to just to skip the calculation
+     299             :       // the condition is that the weight of the contribution is low
+     300             :       // N.B. Here weights are assumed to be between zero and one
+     301             :       if( myvals.get(0)<tolerance ) {
+     302             :         // Clear the derivatives
+     303             :         myvals.clearAll();
+     304             :         continue;
+     305             :       }
+     306             : 
+     307             :       // Now calculate all the functions
+     308             :       // If the contribution of this quantity is very small at neighbour list time ignore it
+     309             :       // until next neighbour list time
+     310             :       if( nt>1 ) {
+     311             :         calculateAllVessels( indexOfTaskInFullList[i], myvals, bvals, omp_buffer, der_list );
+     312             :       } else {
+     313             :         calculateAllVessels( indexOfTaskInFullList[i], myvals, bvals, buffer, der_list );
+     314             :       }
+     315             : 
+     316             :       // Clear the value
+     317             :       myvals.clearAll();
+     318             :     }
+     319             :     #pragma omp critical
+     320             :     if(nt>1) for(unsigned i=0; i<bufsize; ++i) buffer[i]+=omp_buffer[i];
+     321             :   }
+     322       19967 :   if(timers) stopwatch.stop("2 Loop over tasks");
+     323             :   // Turn back on derivative calculation
+     324       19967 :   dertime=true;
+     325             : 
+     326       19967 :   if(timers) stopwatch.start("3 MPI gather");
+     327             :   // MPI Gather everything
+     328       19967 :   if( !serial && buffer.size()>0 ) comm.Sum( buffer );
+     329             :   // MPI Gather index stores
+     330       19967 :   if( mydata && !lowmem && !noderiv ) {
+     331         690 :     comm.Sum( der_list ); mydata->setActiveValsAndDerivatives( der_list );
+     332             :   }
+     333             :   // Update the elements that are makign contributions to the sum here
+     334             :   // this causes problems if we do it in prepare
+     335       19967 :   if(timers) stopwatch.stop("3 MPI gather");
+     336             : 
+     337       19967 :   if(timers) stopwatch.start("4 Finishing computations");
+     338       19967 :   finishComputations( buffer );
+     339       19967 :   if(timers) stopwatch.stop("4 Finishing computations");
+     340       19967 : }
+     341             : 
+     342           0 : void ActionWithVessel::transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const {
+     343           0 :   plumed_error();
+     344             : }
+     345             : 
+     346      467196 : void ActionWithVessel::calculateAllVessels( const unsigned& taskCode, MultiValue& myvals, MultiValue& bvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) {
+     347     1079106 :   for(unsigned j=0; j<functions.size(); ++j) {
+     348             :     // Calculate returns a bool that tells us if this particular
+     349             :     // quantity is contributing more than the tolerance
+     350      611910 :     functions[j]->calculate( taskCode, functions[j]->transformDerivatives(taskCode, myvals, bvals), buffer, der_list );
+     351      611910 :     if( !actionIsBridged ) bvals.clearAll();
+     352             :   }
+     353      467196 :   return;
+     354             : }
+     355             : 
+     356       22992 : void ActionWithVessel::finishComputations( const std::vector<double>& buffer ) {
+     357             :   // Set the final value of the function
+     358       58265 :   for(unsigned j=0; j<functions.size(); ++j) functions[j]->finish( buffer );
+     359       22992 : }
+     360             : 
+     361        7223 : bool ActionWithVessel::getForcesFromVessels( std::vector<double>& forcesToApply ) {
+     362             : #ifndef NDEBUG
+     363             :   if( forcesToApply.size()>0 ) plumed_dbg_assert( forcesToApply.size()==getNumberOfDerivatives() );
+     364             : #endif
+     365        7223 :   if(tmpforces.size()!=forcesToApply.size() ) tmpforces.resize( forcesToApply.size() );
+     366             : 
+     367        7223 :   forcesToApply.assign( forcesToApply.size(),0.0 );
+     368             :   bool wasforced=false;
+     369       21115 :   for(unsigned i=0; i<getNumberOfVessels(); ++i) {
+     370       13892 :     if( (functions[i]->applyForce( tmpforces )) ) {
+     371             :       wasforced=true;
+     372      524277 :       for(unsigned j=0; j<forcesToApply.size(); ++j) forcesToApply[j]+=tmpforces[j];
+     373             :     }
+     374             :   }
+     375        7223 :   return wasforced;
+     376             : }
+     377             : 
+     378           0 : void ActionWithVessel::retrieveDomain( std::string& min, std::string& max ) {
+     379           0 :   plumed_merror("If your function is periodic you need to add a retrieveDomain function so that ActionWithVessel can retrieve the domain");
+     380             : }
+     381             : 
+     382           0 : Vessel* ActionWithVessel::getVesselWithName( const std::string& mynam ) {
+     383             :   int target=-1;
+     384           0 :   for(unsigned i=0; i<functions.size(); ++i) {
+     385           0 :     if( functions[i]->getName().find(mynam)!=std::string::npos ) {
+     386           0 :       if( target<0 ) target=i;
+     387           0 :       else error("found more than one " + mynam + " object in action");
+     388             :     }
+     389             :   }
+     390           0 :   plumed_assert(target>=0);
+     391           0 :   return functions[target].get();
+     392             : }
+     393             : 
+     394             : }
+     395             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.h.func-sort-c.html b/coverage/vesselbase/ActionWithVessel.h.func-sort-c.html new file mode 100644 index 000000000000..b04ba12a1084 --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.h.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202483.3 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase16ActionWithVessel17applyBridgeForcesERKSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel26normalizeVectorDerivativesERNS_10MultiValueE0
_ZNK4PLMD10vesselbase16ActionWithVessel10threadSafeEv5214
_ZNK4PLMD10vesselbase16ActionWithVessel21getNumberOfQuantitiesEv196813
_ZNK4PLMD10vesselbase16ActionWithVessel28getPositionInCurrentTaskListERKj224556
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.h.func.html b/coverage/vesselbase/ActionWithVessel.h.func.html new file mode 100644 index 000000000000..570a6418008e --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.h.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202483.3 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase16ActionWithVessel17applyBridgeForcesERKSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel10threadSafeEv5214
_ZNK4PLMD10vesselbase16ActionWithVessel15normalizeVectorERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase16ActionWithVessel21getNumberOfQuantitiesEv196813
_ZNK4PLMD10vesselbase16ActionWithVessel26normalizeVectorDerivativesERNS_10MultiValueE0
_ZNK4PLMD10vesselbase16ActionWithVessel28getPositionInCurrentTaskListERKj224556
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ActionWithVessel.h.gcov.html b/coverage/vesselbase/ActionWithVessel.h.gcov.html new file mode 100644 index 000000000000..a22e3ee7ee6c --- /dev/null +++ b/coverage/vesselbase/ActionWithVessel.h.gcov.html @@ -0,0 +1,368 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ActionWithVessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ActionWithVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:202483.3 %
Date:2024-02-22 21:58:45Functions:3650.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_vesselbase_ActionWithVessel_h
+      23             : #define __PLUMED_vesselbase_ActionWithVessel_h
+      24             : 
+      25             : #include "core/ActionWithValue.h"
+      26             : #include "core/ActionAtomistic.h"
+      27             : #include "tools/Exception.h"
+      28             : #include "tools/DynamicList.h"
+      29             : #include "tools/MultiValue.h"
+      30             : #include <vector>
+      31             : #include "tools/ForwardDecl.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : class Value;
+      35             : class Stopwatch;
+      36             : 
+      37             : namespace vesselbase {
+      38             : 
+      39             : class Vessel;
+      40             : class BridgeVessel;
+      41             : class StoreDataVessel;
+      42             : 
+      43             : /**
+      44             : \ingroup MULTIINHERIT
+      45             : This is used to create PLMD::Action objects that are computed by calculating the same function multiple
+      46             : times.  This is used in PLMD::MultiColvar.
+      47             : */
+      48             : 
+      49             : class ActionWithVessel : public virtual Action {
+      50             :   friend class Vessel;
+      51             :   friend class ShortcutVessel;
+      52             :   friend class FunctionVessel;
+      53             :   friend class StoreDataVessel;
+      54             :   friend class BridgeVessel;
+      55             :   friend class ActionWithInputVessel;
+      56             :   friend class OrderingVessel;
+      57             : private:
+      58             : /// Do all calculations in serial
+      59             :   bool serial;
+      60             : /// Lower memory requirements
+      61             :   bool lowmem;
+      62             : /// Are we skipping the calculation of the derivatives
+      63             :   bool noderiv;
+      64             : /// This tells plumed that this is used in a bridge
+      65             :   bool actionIsBridged;
+      66             : /// The maximum number of derivatives we can use before we need to invoke lowmem
+      67             :   unsigned maxderivatives;
+      68             : /// The tolerance on the accumulators
+      69             :   double tolerance;
+      70             : /// Tolerance for quantities being put in neighbor lists
+      71             :   double nl_tolerance;
+      72             : /// Pointers to the functions we are using on each value
+      73             :   std::vector<std::unique_ptr<Vessel>> functions;
+      74             : /// Tempory storage for forces
+      75             :   std::vector<double> tmpforces;
+      76             : /// Ths full list of tasks we have to perform
+      77             :   std::vector<unsigned> fullTaskList;
+      78             : /// The current number of active tasks
+      79             :   unsigned nactive_tasks;
+      80             : /// The indices of the tasks in the full list of tasks
+      81             :   std::vector<unsigned> indexOfTaskInFullList;
+      82             : /// The list of currently active tasks
+      83             :   std::vector<unsigned> partialTaskList;
+      84             : /// The list of atoms involved in derivatives (we keep a copy here to avoid resizing)
+      85             :   std::vector<unsigned> der_list;
+      86             : /// The buffer that we use (we keep a copy here to avoid resizing)
+      87             :   std::vector<double> buffer;
+      88             : /// Do we want to output information on the timings of different parts of the calculation
+      89             :   bool timers;
+      90             :   ForwardDecl<Stopwatch> stopwatch_fwd;
+      91             : /// The stopwatch that times the different parts of the calculation
+      92             :   Stopwatch& stopwatch=*stopwatch_fwd;
+      93             : /// These are used to minmise computational expense in complex functions
+      94             :   bool dertime_can_be_off;
+      95             : protected:
+      96             : /// This is also used to minimise computational expense in complex functions
+      97             :   bool dertime;
+      98             : /// The terms in the series are locked
+      99             :   bool contributorsAreUnlocked;
+     100             : /// Does the weight have derivatives
+     101             :   bool weightHasDerivatives;
+     102             : /// This is used for numerical derivatives of bridge variables
+     103             :   unsigned bridgeVariable;
+     104             : /// A pointer to the object that stores data
+     105             :   StoreDataVessel* mydata;
+     106             : /// This list is used to update the neighbor list
+     107             :   std::vector<unsigned> taskFlags;
+     108             : /// Add a vessel to the list of vessels
+     109             :   void addVessel( const std::string& name, const std::string& input, const int numlab=0 );
+     110             :   void addVessel( std::unique_ptr<Vessel> vv );
+     111             : /// Add a bridging vessel to the list of vessels
+     112             :   BridgeVessel* addBridgingVessel( ActionWithVessel* tome );
+     113             : /// Complete the setup of this object (this routine must be called after construction of ActionWithValue)
+     114             :   void readVesselKeywords();
+     115             : /// Turn on the derivatives in the vessel
+     116             :   void needsDerivatives();
+     117             : /// Return the value of the tolerance
+     118             :   double getTolerance() const ;
+     119             : /// Return the value for the neighbor list tolerance
+     120             :   double getNLTolerance() const ;
+     121             : /// Calculate the values of all the vessels
+     122             :   void runAllTasks();
+     123             : /// Resize all the functions when the number of derivatives change
+     124             :   void resizeFunctions();
+     125             : /// This loops over all the vessels calculating them and also
+     126             : /// sets all the element derivatives equal to zero
+     127             :   void calculateAllVessels( const unsigned& taskCode, MultiValue& myvals, MultiValue& bvals, std::vector<double>& buffer, std::vector<unsigned>& der_list );
+     128             : /// Retrieve the forces from all the vessels (used in apply)
+     129             :   bool getForcesFromVessels( std::vector<double>& forcesToApply );
+     130             : /// Is the calculation being done in serial
+     131             :   bool serialCalculation() const;
+     132             : /// Are we using low memory
+     133             :   bool usingLowMem() const ;
+     134             : /// Set that we are using low memory
+     135             :   void setLowMemOption(const bool& );
+     136             : /// Deactivate all the tasks in the task list
+     137             :   void deactivateAllTasks();
+     138             : /// Get the size of the buffer
+     139             :   unsigned getSizeOfBuffer( unsigned& bufsize );
+     140             : /// Add a task to the full list
+     141             :   void addTaskToList( const unsigned& taskCode );
+     142             : public:
+     143             :   static void registerKeywords(Keywords& keys);
+     144             :   explicit ActionWithVessel(const ActionOptions&ao);
+     145             :   ~ActionWithVessel();
+     146             :   void lockContributors();
+     147             : /// Get the number of tasks that are currently active
+     148             :   unsigned getCurrentNumberOfActiveTasks() const ;
+     149             : /// Check whether or not a particular task is currently active
+     150             :   bool taskIsCurrentlyActive( const unsigned& index ) const ;
+     151             : /// Are derivatives required for this quantity
+     152             :   bool derivativesAreRequired() const ;
+     153             : /// Is this action thread safe
+     154        5214 :   virtual bool threadSafe() const { return true; }
+     155             : /// Finish running all the calculations
+     156             :   virtual void finishComputations( const std::vector<double>& buffer );
+     157             : /// Are the base quantities periodic
+     158             :   virtual bool isPeriodic()=0;
+     159             : /// What are the domains of the base quantities
+     160             :   virtual void retrieveDomain( std::string& min, std::string& max);
+     161             : /// Get the number of derivatives for final calculated quantity
+     162             :   virtual unsigned getNumberOfDerivatives()=0;
+     163             : /// Get the number of quantities that are calculated during each task
+     164             :   virtual unsigned getNumberOfQuantities() const ;
+     165             : /// Get the number of vessels
+     166             :   unsigned getNumberOfVessels() const;
+     167             : /// Get a pointer to the ith vessel
+     168             :   Vessel* getPntrToVessel( const unsigned& i );
+     169             : /// Do any jobs that are required before the task list is undertaken
+     170             :   virtual void doJobsRequiredBeforeTaskList();
+     171             : /// Get the full size of the taskList dynamic list
+     172             :   unsigned getFullNumberOfTasks() const ;
+     173             : /// Get the position of the ith active task in the full list
+     174             :   unsigned getPositionInFullTaskList( const unsigned& ii ) const ;
+     175             : /// Get the code for the ii th task in the list
+     176             :   unsigned getTaskCode( const unsigned& ii ) const ;
+     177             : /// Get the ith of the currently active tasks
+     178             :   unsigned getActiveTask( const unsigned& ii ) const ;
+     179             : /// Calculate one of the functions in the distribution
+     180             :   virtual void performTask( const unsigned&, const unsigned&, MultiValue& ) const=0;
+     181             : /// Do the task if we have a bridge
+     182             :   virtual void transformBridgedDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) const;
+     183             : /// Ensure that data required in other vessels is stored
+     184             :   StoreDataVessel* buildDataStashes( ActionWithVessel* actionThatUses );
+     185             : /// Apply forces from bridge vessel - this is rarely used - currently only in ActionVolume
+     186           0 :   virtual void applyBridgeForces( const std::vector<double>& bb ) { plumed_error(); }
+     187             : /// These are overwritten in MultiColvarFunction
+     188             : //  virtual void activateIndexes( const unsigned&, const unsigned&, const std::vector<unsigned>& ){}
+     189             : /// Return a particular named vessel
+     190             :   Vessel* getVesselWithName( const std::string& mynam );
+     191             : /// Does the weight have derivatives
+     192             :   bool weightWithDerivatives() const ;
+     193             : /// Return the position in the current task list
+     194             :   unsigned getPositionInCurrentTaskList( const unsigned& myind ) const ;
+     195             : /// These normalizes vectors and is used in StoreDataVessel
+     196           0 :   virtual void normalizeVector( std::vector<double>& vals ) const { plumed_error(); }
+     197           0 :   virtual void normalizeVectorDerivatives( MultiValue& myvals ) const { plumed_error(); }
+     198             : };
+     199             : 
+     200             : inline
+     201             : double ActionWithVessel::getTolerance() const {
+     202      700114 :   return tolerance;
+     203             : }
+     204             : 
+     205             : inline
+     206             : double ActionWithVessel::getNLTolerance() const {
+     207             :   return nl_tolerance;
+     208             : }
+     209             : 
+     210             : inline
+     211             : unsigned ActionWithVessel::getNumberOfVessels() const {
+     212    12537469 :   return functions.size();
+     213             : }
+     214             : 
+     215             : inline
+     216      196813 : unsigned ActionWithVessel::getNumberOfQuantities() const {
+     217      196813 :   return 2;
+     218             : }
+     219             : 
+     220             : inline
+     221             : Vessel* ActionWithVessel::getPntrToVessel( const unsigned& i ) {
+     222             :   plumed_dbg_assert( i<functions.size() );
+     223        2502 :   return functions[i].get();
+     224             : }
+     225             : 
+     226             : inline
+     227             : unsigned ActionWithVessel::getFullNumberOfTasks() const {
+     228    15831715 :   return fullTaskList.size();
+     229             : }
+     230             : 
+     231             : inline
+     232             : unsigned ActionWithVessel::getTaskCode( const unsigned& ii ) const {
+     233             :   plumed_dbg_assert( ii<fullTaskList.size() );
+     234     3352757 :   return fullTaskList[ii];
+     235             : }
+     236             : 
+     237             : inline
+     238             : unsigned ActionWithVessel::getCurrentNumberOfActiveTasks() const {
+     239       29023 :   return nactive_tasks;
+     240             : }
+     241             : 
+     242             : inline
+     243             : unsigned ActionWithVessel::getActiveTask( const unsigned& ii ) const {
+     244             :   plumed_dbg_assert( ii<nactive_tasks );
+     245       54936 :   return partialTaskList[ii];
+     246             : }
+     247             : 
+     248             : inline
+     249             : unsigned ActionWithVessel::getPositionInFullTaskList( const unsigned& ii ) const {
+     250             :   plumed_dbg_assert( ii<nactive_tasks );
+     251       62238 :   return indexOfTaskInFullList[ii];
+     252             : }
+     253             : 
+     254             : inline
+     255             : bool ActionWithVessel::serialCalculation() const {
+     256         454 :   return serial;
+     257             : }
+     258             : 
+     259             : inline
+     260             : bool ActionWithVessel::usingLowMem() const {
+     261      867292 :   return lowmem;
+     262             : }
+     263             : 
+     264             : inline
+     265             : void ActionWithVessel::setLowMemOption(const bool& l) {
+     266          42 :   lowmem=l;
+     267             : }
+     268             : 
+     269             : inline
+     270             : bool ActionWithVessel::derivativesAreRequired() const {
+     271      714822 :   return !noderiv;
+     272             : }
+     273             : 
+     274             : inline
+     275             : bool ActionWithVessel::weightWithDerivatives() const {
+     276       13904 :   return weightHasDerivatives;
+     277             : }
+     278             : 
+     279             : inline
+     280      224556 : unsigned ActionWithVessel::getPositionInCurrentTaskList( const unsigned& myind ) const {
+     281      224556 :   if( nactive_tasks==fullTaskList.size() ) return myind;
+     282             : 
+     283   253764165 :   for(unsigned i=0; i<nactive_tasks; ++i) {
+     284   253764165 :     if( myind==indexOfTaskInFullList[i] ) return i;
+     285             :   }
+     286           0 :   plumed_merror("requested task is not active");
+     287             : }
+     288             : 
+     289             : }
+     290             : }
+     291             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AltMin.cpp.func-sort-c.html b/coverage/vesselbase/AltMin.cpp.func-sort-c.html new file mode 100644 index 000000000000..19316b0a82d3 --- /dev/null +++ b/coverage/vesselbase/AltMin.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/AltMin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - AltMin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMe6createERKNS0_13VesselOptionsE2
_ZN4PLMD10vesselbase6AltMin16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD10vesselbase6AltMin16value_descriptorB5cxx11Ev2
_ZN4PLMD10vesselbase6AltMinC2ERKNS0_13VesselOptionsE2
_ZN4PLMD10vesselbase6AltMin14finalTransformERKdRd5
_ZNK4PLMD10vesselbase6AltMin13calcTransformERKdRd10
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMeD2Ev4187
_ZN4PLMD10vesselbase6AltMin14reserveKeywordERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AltMin.cpp.func.html b/coverage/vesselbase/AltMin.cpp.func.html new file mode 100644 index 000000000000..0461e1bb26fc --- /dev/null +++ b/coverage/vesselbase/AltMin.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/AltMin.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - AltMin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMe6createERKNS0_13VesselOptionsE2
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_116AltMinRegisterMeD2Ev4187
_ZN4PLMD10vesselbase6AltMin14finalTransformERKdRd5
_ZN4PLMD10vesselbase6AltMin14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase6AltMin16registerKeywordsERNS_8KeywordsE2
_ZN4PLMD10vesselbase6AltMin16value_descriptorB5cxx11Ev2
_ZN4PLMD10vesselbase6AltMinC2ERKNS0_13VesselOptionsE2
_ZNK4PLMD10vesselbase6AltMin13calcTransformERKdRd10
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AltMin.cpp.gcov.html b/coverage/vesselbase/AltMin.cpp.gcov.html new file mode 100644 index 000000000000..790dce295a1d --- /dev/null +++ b/coverage/vesselbase/AltMin.cpp.gcov.html @@ -0,0 +1,154 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/AltMin.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - AltMin.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2121100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "VesselRegister.h"
+      23             : #include "FunctionVessel.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace vesselbase {
+      27             : 
+      28             : class AltMin : public vesselbase::FunctionVessel {
+      29             : private:
+      30             :   double beta;
+      31             : public:
+      32             :   static void registerKeywords( Keywords& keys );
+      33             :   static void reserveKeyword( Keywords& keys );
+      34             :   explicit AltMin( const vesselbase::VesselOptions& da );
+      35             :   std::string value_descriptor() override;
+      36             :   double calcTransform( const double& val, double& dv ) const override;
+      37             :   double finalTransform( const double& val, double& dv ) override;
+      38             : };
+      39             : 
+      40       12563 : PLUMED_REGISTER_VESSEL(AltMin,"ALT_MIN")
+      41             : 
+      42           2 : void AltMin::registerKeywords( Keywords& keys ) {
+      43           2 :   FunctionVessel::registerKeywords(keys);
+      44           4 :   keys.add("compulsory","BETA","the value of beta for the equation in the manual");
+      45           2 : }
+      46             : 
+      47        4187 : void AltMin::reserveKeyword( Keywords& keys ) {
+      48        8374 :   keys.reserve("vessel","ALT_MIN","calculate the minimum value. "
+      49             :                "To make this quantity continuous the minimum is calculated using "
+      50             :                "\\f$ \\textrm{min} = -\\frac{1}{\\beta} \\log \\sum_i \\exp\\left( -\\beta s_i \\right)  \\f$ "
+      51             :                "The value of \\f$\\beta\\f$ in this function is specified using (BETA=\\f$\\beta\\f$).");
+      52        8374 :   keys.addOutputComponent("altmin","ALT_MIN","the minimum value. This is calculated using the formula described in the description of the "
+      53             :                           "keyword so as to make it continuous.");
+      54        4187 : }
+      55             : 
+      56           2 : AltMin::AltMin( const vesselbase::VesselOptions& da ):
+      57           2 :   FunctionVessel(da)
+      58             : {
+      59           2 :   if( getAction()->isPeriodic() ) error("MIN is not a meaningful option for periodic variables");
+      60           2 :   parse("BETA",beta); usetol=true;
+      61           2 : }
+      62             : 
+      63           2 : std::string AltMin::value_descriptor() {
+      64           2 :   std::string str_beta; Tools::convert( beta, str_beta );
+      65           4 :   return "the minimum value. Beta is equal to " + str_beta;
+      66             : }
+      67             : 
+      68          10 : double AltMin::calcTransform( const double& val, double& dv ) const {
+      69          10 :   double f = exp( -beta*val ); dv = -beta*f; return f;
+      70             : }
+      71             : 
+      72           5 : double AltMin::finalTransform( const double& val, double& dv ) {
+      73           5 :   dv = - 1.0 /(beta*val); return -std::log( val ) / beta;
+      74             : }
+      75             : 
+      76             : }
+      77             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.cpp.func-sort-c.html b/coverage/vesselbase/AveragingVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..b99493bf1f0e --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/AveragingVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - AveragingVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15AveragingVessel16registerKeywordsERNS_8KeywordsE69
_ZN4PLMD10vesselbase15AveragingVessel5resetEv69
_ZN4PLMD10vesselbase15AveragingVesselC2ERKNS0_13VesselOptionsE70
_ZN4PLMD10vesselbase15AveragingVessel6finishERKSt6vectorIdSaIdEE98
_ZN4PLMD10vesselbase15AveragingVessel5clearEv102
_ZN4PLMD10vesselbase15AveragingVessel11setDataSizeERKj216
_ZNK4PLMD10vesselbase15AveragingVessel8wasresetEv1278
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.cpp.func.html b/coverage/vesselbase/AveragingVessel.cpp.func.html new file mode 100644 index 000000000000..e12d2a630ef3 --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/AveragingVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - AveragingVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15AveragingVessel11setDataSizeERKj216
_ZN4PLMD10vesselbase15AveragingVessel16registerKeywordsERNS_8KeywordsE69
_ZN4PLMD10vesselbase15AveragingVessel5clearEv102
_ZN4PLMD10vesselbase15AveragingVessel5resetEv69
_ZN4PLMD10vesselbase15AveragingVessel6finishERKSt6vectorIdSaIdEE98
_ZN4PLMD10vesselbase15AveragingVesselC2ERKNS0_13VesselOptionsE70
_ZNK4PLMD10vesselbase15AveragingVessel8wasresetEv1278
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.cpp.gcov.html b/coverage/vesselbase/AveragingVessel.cpp.gcov.html new file mode 100644 index 000000000000..24b921932d10 --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.cpp.gcov.html @@ -0,0 +1,141 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/AveragingVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - AveragingVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "AveragingVessel.h"
+      23             : #include "ActionWithAveraging.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace vesselbase {
+      27             : 
+      28          69 : void AveragingVessel::registerKeywords( Keywords& keys ) {
+      29          69 :   Vessel::registerKeywords( keys );
+      30          69 : }
+      31             : 
+      32          70 : AveragingVessel::AveragingVessel( const vesselbase::VesselOptions& vo ):
+      33             :   Vessel(vo),
+      34          70 :   wascleared(true)
+      35             : {
+      36          70 :   if( getAction() ) {
+      37          68 :     ActionWithAveraging* myav = dynamic_cast<ActionWithAveraging*>( getAction() );
+      38          68 :     plumed_assert( myav ); unormalised = myav->ignoreNormalization();
+      39             :   }
+      40          70 : }
+      41             : 
+      42          98 : void AveragingVessel::finish( const std::vector<double>& buffer ) {
+      43     1182011 :   wascleared=false; for(unsigned i=1; i<data.size(); ++i) data[i]+=buffer[bufstart + i - 1];
+      44          98 : }
+      45             : 
+      46        1278 : bool AveragingVessel::wasreset() const {
+      47        1278 :   return wascleared;
+      48             : }
+      49             : 
+      50         102 : void AveragingVessel::clear() {
+      51         102 :   plumed_assert( wascleared ); data.assign( data.size(), 0.0 );
+      52         102 : }
+      53             : 
+      54          69 : void AveragingVessel::reset() {
+      55          69 :   wascleared=true;
+      56          69 : }
+      57             : 
+      58         216 : void AveragingVessel::setDataSize( const unsigned& size ) {
+      59         216 :   if( data.size()!=(1+size) ) data.resize( 1+size, 0 );
+      60         216 : }
+      61             : 
+      62             : }
+      63             : }
+      64             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.h.func-sort-c.html b/coverage/vesselbase/AveragingVessel.h.func-sort-c.html new file mode 100644 index 000000000000..37dc259871fa --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.h.func-sort-c.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/AveragingVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - AveragingVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91090.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15AveragingVessel10applyForceERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase15AveragingVessel14getDataElementERKj7999531
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.h.func.html b/coverage/vesselbase/AveragingVessel.h.func.html new file mode 100644 index 000000000000..5ff0321ca612 --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.h.func.html @@ -0,0 +1,81 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/AveragingVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - AveragingVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91090.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ +
+ + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15AveragingVessel10applyForceERSt6vectorIdSaIdEE0
_ZNK4PLMD10vesselbase15AveragingVessel14getDataElementERKj7999531
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/AveragingVessel.h.gcov.html b/coverage/vesselbase/AveragingVessel.h.gcov.html new file mode 100644 index 000000000000..04a8177664c0 --- /dev/null +++ b/coverage/vesselbase/AveragingVessel.h.gcov.html @@ -0,0 +1,178 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/AveragingVessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - AveragingVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:91090.0 %
Date:2024-02-22 21:58:45Functions:1250.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2016-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_vesselbase_AveragingVessel_h
+      23             : #define __PLUMED_vesselbase_AveragingVessel_h
+      24             : 
+      25             : #include "Vessel.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace vesselbase {
+      29             : 
+      30             : class AveragingVessel : public Vessel {
+      31             : private:
+      32             : /// The grid was recently cleared and bounds can be set
+      33             :   bool wascleared;
+      34             : /// Are we outputting unormalised data
+      35             :   bool unormalised;
+      36             : /// The data that is being averaged
+      37             :   std::vector<double> data;
+      38             : protected:
+      39             : /// Set the size of the data vector
+      40             :   void setDataSize( const unsigned& size );
+      41             : /// Set an element of the data array
+      42             :   void setDataElement( const unsigned& myelem, const double& value );
+      43             : /// Add some value to an element of the data array
+      44             :   void addDataElement( const unsigned& myelem, const double& value );
+      45             : /// Get the value of one of the data element
+      46             :   double getDataElement( const unsigned& myelem ) const ;
+      47             : /// Are we averaging the data
+      48      361818 :   bool noAverage() const { return unormalised; }
+      49             : public:
+      50             : /// keywords
+      51             :   static void registerKeywords( Keywords& keys );
+      52             : /// Constructor
+      53             :   explicit AveragingVessel( const vesselbase::VesselOptions& );
+      54             : /// Copy data from an accumulated buffer into the grid
+      55             :   void finish( const std::vector<double>& ) override;
+      56             : /// Was the grid cleared on the last step
+      57             :   bool wasreset() const ;
+      58             : /// Clear all the data stored on the grid
+      59             :   virtual void clear();
+      60             : /// Reset the grid so that it is cleared at start of next time it is calculated
+      61             :   virtual void reset();
+      62             : /// Functions for dealing with normalisation constant
+      63             :   void setNorm( const double& snorm );
+      64             :   double getNorm() const ;
+      65           0 :   bool applyForce(  std::vector<double>& forces ) override { return false; }
+      66             : };
+      67             : 
+      68             : inline
+      69             : void AveragingVessel::setDataElement( const unsigned& myelem, const double& value ) {
+      70             :   plumed_dbg_assert( myelem<1+data.size() );
+      71      154208 :   wascleared=false; data[1+myelem]=value;
+      72             : }
+      73             : 
+      74             : inline
+      75             : void AveragingVessel::addDataElement( const unsigned& myelem, const double& value ) {
+      76             :   plumed_dbg_assert( myelem<1+data.size() );
+      77       58119 :   wascleared=false; data[1+myelem]+=value;
+      78             : }
+      79             : 
+      80             : inline
+      81     7999531 : double AveragingVessel::getDataElement( const unsigned& myelem ) const {
+      82             :   plumed_dbg_assert( myelem<data.size()-1 );
+      83     7999531 :   if( unormalised ) return data[1+myelem];
+      84     1851643 :   return data[1+myelem] / data[0];
+      85             : }
+      86             : 
+      87             : inline
+      88             : void AveragingVessel::setNorm( const double& snorm ) {
+      89             :   plumed_dbg_assert( data.size()>0 );
+      90        1389 :   data[0]=snorm;
+      91          27 : }
+      92             : 
+      93             : inline
+      94             : double AveragingVessel::getNorm() const {
+      95             :   plumed_dbg_assert( data.size()>0 );
+      96      104745 :   return data[0];
+      97             : }
+      98             : 
+      99             : }
+     100             : }
+     101             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Between.cpp.func-sort-c.html b/coverage/vesselbase/Between.cpp.func-sort-c.html new file mode 100644 index 000000000000..1539d338a097 --- /dev/null +++ b/coverage/vesselbase/Between.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Between.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Between.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase7Between9getCutoffEv60
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMe6createERKNS0_13VesselOptionsE65
_ZN4PLMD10vesselbase7Between16registerKeywordsERNS_8KeywordsE65
_ZN4PLMD10vesselbase7Between16value_descriptorB5cxx11Ev65
_ZN4PLMD10vesselbase7BetweenC2ERKNS0_13VesselOptionsE65
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMeD2Ev4187
_ZN4PLMD10vesselbase7Between14reserveKeywordERNS_8KeywordsE4187
_ZNK4PLMD10vesselbase7Between13calcTransformERKdRd8224
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Between.cpp.func.html b/coverage/vesselbase/Between.cpp.func.html new file mode 100644 index 000000000000..0761eaa9c07e --- /dev/null +++ b/coverage/vesselbase/Between.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Between.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Between.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMe6createERKNS0_13VesselOptionsE65
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_117BetweenRegisterMeD2Ev4187
_ZN4PLMD10vesselbase7Between14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase7Between16registerKeywordsERNS_8KeywordsE65
_ZN4PLMD10vesselbase7Between16value_descriptorB5cxx11Ev65
_ZN4PLMD10vesselbase7Between9getCutoffEv60
_ZN4PLMD10vesselbase7BetweenC2ERKNS0_13VesselOptionsE65
_ZNK4PLMD10vesselbase7Between13calcTransformERKdRd8224
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Between.cpp.gcov.html b/coverage/vesselbase/Between.cpp.gcov.html new file mode 100644 index 000000000000..adccb9262162 --- /dev/null +++ b/coverage/vesselbase/Between.cpp.gcov.html @@ -0,0 +1,156 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Between.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Between.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3030100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "Between.h"
+      24             : #include "VesselRegister.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace vesselbase {
+      28             : 
+      29       12626 : PLUMED_REGISTER_VESSEL(Between,"BETWEEN")
+      30             : 
+      31          65 : void Between::registerKeywords( Keywords& keys ) {
+      32          65 :   FunctionVessel::registerKeywords( keys );
+      33          65 :   HistogramBead::registerKeywords( keys );
+      34         130 :   keys.addFlag("NORM",false,"calculate the fraction of values rather than the number");
+      35          65 : }
+      36             : 
+      37        4187 : void Between::reserveKeyword( Keywords& keys ) {
+      38        8374 :   keys.reserve("vessel","BETWEEN","calculate the number of values that are within a certain range. "
+      39             :                "These quantities are calculated using kernel density estimation as described on "
+      40             :                "\\ref histogrambead.");
+      41        8374 :   keys.addOutputComponent("between","BETWEEN","the number/fraction of values within a certain range. This is calculated using one of the "
+      42             :                           "formula described in the description of the keyword so as to make it continuous. "
+      43             :                           "You can calculate this quantity multiple times using different parameters.");
+      44        4187 : }
+      45             : 
+      46          65 : Between::Between( const VesselOptions& da ) :
+      47          65 :   FunctionVessel(da)
+      48             : {
+      49          65 :   usetol=true;
+      50          65 :   bool isPeriodic=getAction()->isPeriodic();
+      51             :   double min, max; std::string str_min, str_max;
+      52          65 :   if( isPeriodic ) {
+      53           1 :     getAction()->retrieveDomain( str_min, str_max );
+      54           1 :     Tools::convert(str_min,min); Tools::convert(str_max,max);
+      55             :   }
+      56             : 
+      57         130 :   parseFlag("NORM",norm); std::string errormsg;
+      58             : 
+      59          65 :   hist.set( getAllInput(),errormsg );
+      60          65 :   if( !isPeriodic ) hist.isNotPeriodic();
+      61           1 :   else hist.isPeriodic( min, max );
+      62          65 :   if( errormsg.size()!=0 ) error( errormsg );
+      63          65 : }
+      64             : 
+      65          65 : std::string Between::value_descriptor() {
+      66          66 :   if(norm) return "the fraction of values " + hist.description();
+      67         128 :   return "the number of values " + hist.description();
+      68             : }
+      69             : 
+      70        8224 : double Between::calcTransform( const double& val, double& dv ) const {
+      71        8224 :   double f = hist.calculate(val, dv); return f;
+      72             : }
+      73             : 
+      74          60 : double Between::getCutoff() {
+      75          60 :   return std::numeric_limits<double>::max();
+      76             : }
+      77             : 
+      78             : }
+      79             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.cpp.func-sort-c.html b/coverage/vesselbase/BridgeVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..32c909013089 --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.cpp.func-sort-c.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/BridgeVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - BridgeVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:969997.0 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12BridgeVessel11descriptionB5cxx11Ev0
_ZN4PLMD10vesselbase12BridgeVessel15setOutputActionEPNS0_16ActionWithVesselE46
_ZN4PLMD10vesselbase12BridgeVesselC2ERKNS0_13VesselOptionsE46
_ZN4PLMD10vesselbase12BridgeVessel28completeNumericalDerivativesEv65
_ZN4PLMD10vesselbase12BridgeVessel6resizeEv533
_ZN4PLMD10vesselbase12BridgeVessel10applyForceERSt6vectorIdSaIdEE795
_ZN4PLMD10vesselbase12BridgeVessel13copyTaskFlagsEv795
_ZN4PLMD10vesselbase12BridgeVessel14setBufferStartERj3025
_ZN4PLMD10vesselbase12BridgeVessel6finishERKSt6vectorIdSaIdEE3025
_ZN4PLMD10vesselbase12BridgeVessel7prepareEv3025
_ZN4PLMD10vesselbase12BridgeVessel20getTemporyMultiValueEv13042
_ZN4PLMD10vesselbase12BridgeVessel20transformDerivativesERKjRNS_10MultiValueES5_102743
_ZNK4PLMD10vesselbase12BridgeVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE102743
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.cpp.func.html b/coverage/vesselbase/BridgeVessel.cpp.func.html new file mode 100644 index 000000000000..a2be94d2c48b --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.cpp.func.html @@ -0,0 +1,125 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/BridgeVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - BridgeVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:969997.0 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12BridgeVessel10applyForceERSt6vectorIdSaIdEE795
_ZN4PLMD10vesselbase12BridgeVessel11descriptionB5cxx11Ev0
_ZN4PLMD10vesselbase12BridgeVessel13copyTaskFlagsEv795
_ZN4PLMD10vesselbase12BridgeVessel14setBufferStartERj3025
_ZN4PLMD10vesselbase12BridgeVessel15setOutputActionEPNS0_16ActionWithVesselE46
_ZN4PLMD10vesselbase12BridgeVessel20getTemporyMultiValueEv13042
_ZN4PLMD10vesselbase12BridgeVessel20transformDerivativesERKjRNS_10MultiValueES5_102743
_ZN4PLMD10vesselbase12BridgeVessel28completeNumericalDerivativesEv65
_ZN4PLMD10vesselbase12BridgeVessel6finishERKSt6vectorIdSaIdEE3025
_ZN4PLMD10vesselbase12BridgeVessel6resizeEv533
_ZN4PLMD10vesselbase12BridgeVessel7prepareEv3025
_ZN4PLMD10vesselbase12BridgeVesselC2ERKNS0_13VesselOptionsE46
_ZNK4PLMD10vesselbase12BridgeVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE102743
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.cpp.gcov.html b/coverage/vesselbase/BridgeVessel.cpp.gcov.html new file mode 100644 index 000000000000..e128c8e94093 --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.cpp.gcov.html @@ -0,0 +1,270 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/BridgeVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - BridgeVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:969997.0 %
Date:2024-02-22 21:58:45Functions:121392.3 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "BridgeVessel.h"
+      23             : #include "tools/Matrix.h"
+      24             : #include "core/ActionWithArguments.h"
+      25             : #include "StoreDataVessel.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace vesselbase {
+      29             : 
+      30          46 : BridgeVessel::BridgeVessel( const VesselOptions& da ):
+      31             :   Vessel(da),
+      32          46 :   inum(0),
+      33             : // in_normal_calculate(false)
+      34          46 :   myOutputAction(NULL),
+      35          46 :   myOutputValues(NULL),
+      36          46 :   my_tmp_val(0,0)
+      37             : {
+      38          46 : }
+      39             : 
+      40         533 : void BridgeVessel::resize() {
+      41         533 :   if( myOutputAction->checkNumericalDerivatives() ) {
+      42          10 :     mynumerical_values.resize( getAction()->getNumberOfDerivatives()*myOutputValues->getNumberOfComponents() );
+      43          10 :     inum=0;
+      44             :   }
+      45             :   // This bit ensures that we can store data in a bridge function if needs be
+      46             :   // Notice we need to resize der_list in the underlying action as this is called
+      47             :   // from a bridge
+      48         533 :   if( myOutputAction->mydata ) {
+      49             :     unsigned dsize=(myOutputAction->mydata)->getSizeOfDerivativeList();
+      50          32 :     if( getAction()->der_list.size()!=dsize ) getAction()->der_list.resize( dsize );
+      51             :   }
+      52         533 :   unsigned tmp=0; resizeBuffer( myOutputAction->getSizeOfBuffer( tmp ) );
+      53         533 : }
+      54             : 
+      55          46 : void BridgeVessel::setOutputAction( ActionWithVessel* myact ) {
+      56          46 :   ActionWithValue* checkme=dynamic_cast<ActionWithValue*>( getAction() );
+      57          46 :   plumed_massert( checkme, "vessel in bridge must inherit from ActionWithValue");
+      58             : 
+      59          46 :   myOutputAction=myact;
+      60          46 :   myOutputValues=dynamic_cast<ActionWithValue*>( myact );
+      61          46 :   plumed_massert( myOutputValues, "bridging vessel must inherit from ActionWithValue");
+      62          46 : }
+      63             : 
+      64           0 : std::string BridgeVessel::description() {
+      65           0 :   plumed_merror("I shouldn't end up here");
+      66             : }
+      67             : 
+      68        3025 : void BridgeVessel::prepare() {
+      69        3025 :   myOutputAction->doJobsRequiredBeforeTaskList();
+      70        3025 : }
+      71             : 
+      72        3025 : void BridgeVessel::setBufferStart( unsigned& start ) {
+      73        3025 :   myOutputAction->getSizeOfBuffer( start );
+      74        3025 : }
+      75             : 
+      76      102743 : MultiValue& BridgeVessel::transformDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) {
+      77      205022 :   if( outvals.getNumberOfValues()!=myOutputAction->getNumberOfQuantities() ||
+      78      102279 :       outvals.getNumberOfDerivatives()!=myOutputAction->getNumberOfDerivatives() ) {
+      79        2287 :     outvals.resize( myOutputAction->getNumberOfQuantities(), myOutputAction->getNumberOfDerivatives() );
+      80             :   }
+      81      102743 :   myOutputAction->transformBridgedDerivatives( current, invals, outvals );
+      82      102743 :   return outvals;
+      83             : }
+      84             : 
+      85      102743 : void BridgeVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+      86             :   // in_normal_calculate=true;
+      87      102743 :   if( myvals.get(0)<myOutputAction->getTolerance() ) return;
+      88       62508 :   myOutputAction->calculateAllVessels( current, myvals, myvals, buffer, der_list );
+      89       62508 :   return;
+      90             : }
+      91             : 
+      92        3025 : void BridgeVessel::finish( const std::vector<double>& buffer ) {
+      93        3025 :   myOutputAction->finishComputations( buffer );
+      94        3025 :   if( myOutputAction->checkNumericalDerivatives() ) {
+      95        1930 :     if ( inum<mynumerical_values.size() ) {
+      96        2160 :       for(int i=0; i<myOutputValues->getNumberOfComponents(); ++i) {
+      97        1080 :         mynumerical_values[inum]=myOutputValues->getOutputQuantity(i);
+      98        1080 :         inum++;
+      99             :       }
+     100             :       plumed_dbg_assert( inum<=mynumerical_values.size() );
+     101             :     } else {
+     102         850 :       plumed_assert( inum==mynumerical_values.size() );
+     103             :     }
+     104             :   }
+     105        3025 : }
+     106             : 
+     107          65 : void BridgeVessel::completeNumericalDerivatives() {
+     108          65 :   unsigned nextra = myOutputAction->getNumberOfDerivatives() - getAction()->getNumberOfDerivatives();
+     109          65 :   Matrix<double> tmpder( myOutputValues->getNumberOfComponents(), nextra );
+     110          65 :   ActionWithVessel* vval=dynamic_cast<ActionWithVessel*>( myOutputAction );
+     111         785 :   for(unsigned i=0; i<nextra; ++i) {
+     112         720 :     vval->bridgeVariable=i; getAction()->calculate();
+     113        1440 :     for(int j=0; j<myOutputValues->getNumberOfComponents(); ++j) tmpder(j,i) = myOutputValues->getOutputQuantity(j);
+     114             :   }
+     115          65 :   vval->bridgeVariable=nextra; getAction()->calculate();
+     116          65 :   plumed_assert( inum==mynumerical_values.size() ); inum=0;  // Reset inum now that we have finished calling calculate
+     117          65 :   std::vector<double> base( myOutputValues->getNumberOfComponents() );
+     118         130 :   for(int j=0; j<myOutputValues->getNumberOfComponents(); ++j) base[j] = myOutputValues->getOutputQuantity(j);
+     119             : 
+     120             :   const double delta=std::sqrt(epsilon);
+     121          65 :   ActionAtomistic* aa=dynamic_cast<ActionAtomistic*>( getAction() );
+     122          65 :   unsigned nvals=myOutputValues->getNumberOfComponents();
+     123         130 :   for(unsigned j=0; j<nvals; ++j) ( myOutputValues->copyOutput(j) )->clearDerivatives();
+     124             : 
+     125          65 :   if( aa ) {
+     126          65 :     ActionWithArguments* aarg=dynamic_cast<ActionWithArguments*>( getAction() );
+     127         130 :     plumed_assert( !aarg ); Tensor box=aa->getBox();
+     128             :     unsigned natoms=aa->getNumberOfAtoms();
+     129         130 :     for(unsigned j=0; j<nvals; ++j) {
+     130          65 :       double ref=( myOutputValues->copyOutput(j) )->get();
+     131          65 :       if( ( myOutputValues->copyOutput(j) )->getNumberOfDerivatives()>0 ) {
+     132         560 :         for(unsigned i=0; i<3*natoms; ++i) {
+     133         495 :           double d=( mynumerical_values[i*nvals+j] - ref)/delta;
+     134         495 :           ( myOutputValues->copyOutput(j) )->addDerivative(i,d);
+     135             :         }
+     136          65 :         Tensor virial;
+     137         845 :         for(int i=0; i<3; i++) for(int k=0; k<3; k++) {
+     138         585 :             virial(i,k)=( mynumerical_values[ nvals*(3*natoms + 3*i + k) + j ]-ref)/delta;
+     139             :           }
+     140          65 :         virial=-matmul(box.transpose(),virial);
+     141         845 :         for(int i=0; i<3; i++) for(int k=0; k<3; k++) ( myOutputValues->copyOutput(j) )->addDerivative(3*natoms+3*k+i,virial(k,i));
+     142             :       }
+     143             :     }
+     144             :   } else {
+     145           0 :     plumed_merror("not implemented or tested yet");
+     146             : //      unsigned nder=myOutputAction->getNumberOfDerivatives();
+     147             : //      for(unsigned j=0;j<nvals;++j){
+     148             : //          double ref=( myOutputValues->copyOutput(j) )->get();
+     149             : //              for(unsigned i=0;i<nder;++i){
+     150             : //                  double d=( mynumerical_values[i*nvals+j] - ref)/delta;
+     151             : //                  ( myOutputValues->copyOutput(j) )->addDerivative(i,d);
+     152             : //              }
+     153             : //          }
+     154             : //      }
+     155             :   }
+     156             :   // Add the derivatives wrt to the local quantities we are working with
+     157         130 :   for(unsigned j=0; j<nvals; ++j) {
+     158             :     unsigned k=0;
+     159         785 :     for(unsigned i=getAction()->getNumberOfDerivatives(); i<myOutputAction->getNumberOfDerivatives(); ++i) {
+     160         720 :       ( myOutputValues->copyOutput(j) )->addDerivative( i, (tmpder(j,k)-base[j])/std::sqrt(epsilon) ); k++;
+     161             :     }
+     162             :   }
+     163          65 : }
+     164             : 
+     165         795 : bool BridgeVessel::applyForce( std::vector<double>& outforces ) {
+     166         795 :   bool hasforce=false; outforces.assign(outforces.size(),0.0);
+     167         795 :   unsigned ndertot = myOutputAction->getNumberOfDerivatives();
+     168         795 :   unsigned nextra = ndertot - getAction()->getNumberOfDerivatives();
+     169         795 :   std::vector<double> forces( ndertot ), eforces( nextra, 0.0 );
+     170        1730 :   for(unsigned i=0; i<myOutputAction->getNumberOfVessels(); ++i) {
+     171         935 :     if( ( myOutputAction->getPntrToVessel(i) )->applyForce( forces ) ) {
+     172             :       hasforce=true;
+     173      260815 :       for(unsigned j=0; j<outforces.size(); ++j) outforces[j]+=forces[j];
+     174          94 :       for(unsigned j=0; j<nextra; ++j) eforces[j]+=forces[ outforces.size()+j ];
+     175             :     }
+     176             :   }
+     177         795 :   if(hasforce) myOutputAction->applyBridgeForces( eforces );
+     178         795 :   return hasforce;
+     179             : }
+     180             : 
+     181         795 : void BridgeVessel::copyTaskFlags() {
+     182         795 :   myOutputAction->deactivateAllTasks();
+     183       89536 :   for(unsigned i=0; i<getAction()->nactive_tasks; ++i) myOutputAction->taskFlags[ getAction()->indexOfTaskInFullList[i] ] = 1;
+     184         795 :   myOutputAction->lockContributors();
+     185         795 : }
+     186             : 
+     187       13042 : MultiValue& BridgeVessel::getTemporyMultiValue() {
+     188       13042 :   return my_tmp_val;
+     189             : }
+     190             : 
+     191             : }
+     192             : }
+     193             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.h.func-sort-c.html b/coverage/vesselbase/BridgeVessel.h.func-sort-c.html new file mode 100644 index 000000000000..5937b0442dea --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/BridgeVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - BridgeVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.h.func.html b/coverage/vesselbase/BridgeVessel.h.func.html new file mode 100644 index 000000000000..aecd54c8b8ce --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/BridgeVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - BridgeVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/BridgeVessel.h.gcov.html b/coverage/vesselbase/BridgeVessel.h.gcov.html new file mode 100644 index 000000000000..1005cb40e3aa --- /dev/null +++ b/coverage/vesselbase/BridgeVessel.h.gcov.html @@ -0,0 +1,168 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/BridgeVessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - BridgeVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_vesselbase_BridgeVessel_h
+      23             : #define __PLUMED_vesselbase_BridgeVessel_h
+      24             : 
+      25             : #include <string>
+      26             : #include <cstring>
+      27             : #include <vector>
+      28             : #include "Vessel.h"
+      29             : #include "core/Value.h"
+      30             : #include "tools/MultiValue.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace vesselbase {
+      34             : 
+      35             : /**
+      36             : \ingroup TOOLBOX
+      37             : This class allows you to calculate the vessel in one ActionWithVessel.  The user thinks
+      38             : it is created in a different Action however.  At the moment this is used for region
+      39             : */
+      40             : 
+      41             : class BridgeVessel : public Vessel {
+      42             : private:
+      43             :   unsigned inum;
+      44             :   // bool in_normal_calculate;
+      45             :   std::vector<double> mynumerical_values;
+      46             :   ActionWithVessel* myOutputAction;
+      47             :   ActionWithValue* myOutputValues;
+      48             :   // We create a tempory multivalue here so as to avoid vector resizing
+      49             :   MultiValue my_tmp_val;
+      50             : public:
+      51             :   explicit BridgeVessel( const VesselOptions& );
+      52             : /// Does this have derivatives
+      53             :   bool hasDerivatives();
+      54             : /// Resize the quantities in the vessel
+      55             :   void resize() override;
+      56             : /// Get the action that reads the command in
+      57             :   ActionWithVessel* getOutputAction();
+      58             : /// Setup the action we are outputting to
+      59             :   void setOutputAction( ActionWithVessel* myOutputAction );
+      60             : /// Apply some force
+      61             :   bool applyForce( std::vector<double>& forces ) override;
+      62             : /// Should not be called
+      63             :   std::string description() override;
+      64             : /// Jobs to do before the task list starts
+      65             :   void prepare() override;
+      66             : /// Set the start of the buffer
+      67             :   void setBufferStart( unsigned& start ) override;
+      68             : /// This transforms the derivatives using the output value
+      69             :   MultiValue& transformDerivatives( const unsigned& current, MultiValue& invals, MultiValue& outvals ) override;
+      70             : /// Actually do the calculation
+      71             :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_index ) const override;
+      72             : /// Finish the calculation
+      73             :   void finish( const std::vector<double>& buffer ) override;
+      74             : /// Calculate numerical derivatives
+      75             :   void completeNumericalDerivatives();
+      76             : /// Set the task flags in the bridged class the same as in the original class
+      77             :   void copyTaskFlags();
+      78             : /// Return a tempory multi value - we do this so as to avoid vector resizing
+      79             :   MultiValue& getTemporyMultiValue();
+      80             : };
+      81             : 
+      82             : inline
+      83             : ActionWithVessel* BridgeVessel::getOutputAction() {
+      84          70 :   return myOutputAction;
+      85             : }
+      86             : 
+      87             : }
+      88             : }
+      89             : #endif
+      90             : 
+      91             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.cpp.func-sort-c.html b/coverage/vesselbase/FunctionVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..d9ee2be8dfe2 --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/FunctionVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - FunctionVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444695.7 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD10vesselbase14FunctionVessel13calcTransformERKdRd0
_ZN4PLMD10vesselbase14FunctionVessel16registerKeywordsERNS_8KeywordsE333
_ZN4PLMD10vesselbase14FunctionVesselC2ERKNS0_13VesselOptionsE333
_ZN4PLMD10vesselbase14FunctionVessel6resizeEv924
_ZN4PLMD10vesselbase14FunctionVessel14finalTransformERKdRd22781
_ZN4PLMD10vesselbase14FunctionVessel6finishERKSt6vectorIdSaIdEE26620
_ZNK4PLMD10vesselbase14FunctionVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE244840
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.cpp.func.html b/coverage/vesselbase/FunctionVessel.cpp.func.html new file mode 100644 index 000000000000..c6f2aa757b1c --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/FunctionVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - FunctionVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444695.7 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14FunctionVessel14finalTransformERKdRd22781
_ZN4PLMD10vesselbase14FunctionVessel16registerKeywordsERNS_8KeywordsE333
_ZN4PLMD10vesselbase14FunctionVessel6finishERKSt6vectorIdSaIdEE26620
_ZN4PLMD10vesselbase14FunctionVessel6resizeEv924
_ZN4PLMD10vesselbase14FunctionVesselC2ERKNS0_13VesselOptionsE333
_ZNK4PLMD10vesselbase14FunctionVessel13calcTransformERKdRd0
_ZNK4PLMD10vesselbase14FunctionVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE244840
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.cpp.gcov.html b/coverage/vesselbase/FunctionVessel.cpp.gcov.html new file mode 100644 index 000000000000..6be17e08fc11 --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.cpp.gcov.html @@ -0,0 +1,181 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/FunctionVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - FunctionVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:444695.7 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "FunctionVessel.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace vesselbase {
+      27             : 
+      28         333 : void FunctionVessel::registerKeywords( Keywords& keys ) {
+      29         333 :   ValueVessel::registerKeywords( keys );
+      30         333 : }
+      31             : 
+      32         333 : FunctionVessel::FunctionVessel( const VesselOptions& da ):
+      33             :   ValueVessel(da),
+      34         333 :   norm(false),
+      35         333 :   usetol(false)
+      36             : {
+      37         333 :   diffweight=getAction()->weightHasDerivatives;
+      38         333 : }
+      39             : 
+      40         924 : void FunctionVessel::resize() {
+      41         924 :   if( getAction()->derivativesAreRequired() ) {
+      42         548 :     unsigned nderivatives=getAction()->getNumberOfDerivatives();
+      43         548 :     getFinalValue()->resizeDerivatives( nderivatives );
+      44         548 :     resizeBuffer( (1+nderivatives)*2 );
+      45         548 :     diffweight=getAction()->weightHasDerivatives;
+      46             :   } else {
+      47             :     resizeBuffer(2);
+      48         376 :     diffweight=false;  // Don't need to worry about differentiable weights if no derivatives
+      49             :   }
+      50         924 : }
+      51             : 
+      52      244840 : void FunctionVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+      53      244840 :   unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
+      54             :   double weight=myvals.get(0);
+      55             :   plumed_dbg_assert( weight>=getTolerance() );
+      56             : 
+      57             :   // This deals with the value
+      58      244840 :   double dval, f=calcTransform( myvals.get(mycomp), dval );
+      59             : 
+      60      244840 :   if( norm ) {
+      61       82910 :     if( usetol && weight<getTolerance() ) return;
+      62       82910 :     buffer[bufstart+1+nderivatives] += weight;
+      63       82910 :     if( getAction()->derivativesAreRequired() && diffweight ) myvals.chainRule( 0, 1, 1, 0, 1.0, bufstart, buffer );
+      64             :   }
+      65             : 
+      66      244840 :   double contr=weight*f;
+      67      244840 :   if( usetol && contr<getTolerance() ) return;
+      68      239918 :   buffer[bufstart] += contr;
+      69             : 
+      70      239918 :   if( diffweight ) myvals.chainRule( 0, 0, 1, 0, f, bufstart, buffer );
+      71      239918 :   if( getAction()->derivativesAreRequired() && std::fabs(dval)>0.0 ) myvals.chainRule( mycomp, 0, 1, 0, weight*dval, bufstart, buffer );
+      72             : 
+      73             :   return;
+      74             : }
+      75             : 
+      76           0 : double FunctionVessel::calcTransform( const double&, double& ) const {
+      77           0 :   plumed_error();
+      78             : }
+      79             : 
+      80       26620 : void FunctionVessel::finish( const std::vector<double>& buffer ) {
+      81       26620 :   unsigned nderivatives=getFinalValue()->getNumberOfDerivatives();
+      82       26620 :   if( norm && diffweight ) {
+      83        5114 :     double dv, val=finalTransform( buffer[bufstart], dv), weight=buffer[bufstart+1+nderivatives];
+      84        5114 :     getFinalValue()->set( val / weight );
+      85      417911 :     for(unsigned i=0; i<nderivatives; ++i) {
+      86      412797 :       getFinalValue()->addDerivative( i, buffer[bufstart+1+i]/weight - val*buffer[bufstart+1+nderivatives+1+i]/(weight*weight) );
+      87             :     }
+      88       26620 :   } else if( norm ) {
+      89        1228 :     double dv, val=finalTransform( buffer[bufstart], dv), weight=buffer[bufstart+1+nderivatives];
+      90        1228 :     getFinalValue()->set( val / weight );
+      91      156805 :     for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, buffer[bufstart+1+i]/weight );
+      92             :   } else {
+      93       20278 :     double dv, val=finalTransform( buffer[bufstart], dv); getFinalValue()->set( val );
+      94     1530153 :     for(unsigned i=0; i<nderivatives; ++i) getFinalValue()->addDerivative( i, dv*buffer[bufstart+1+i] );
+      95             :   }
+      96       26620 : }
+      97             : 
+      98       22781 : double FunctionVessel::finalTransform( const double& val, double& dv ) {
+      99       22781 :   dv=1.0; return val;
+     100             : }
+     101             : 
+     102             : }
+     103             : }
+     104             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.h.func-sort-c.html b/coverage/vesselbase/FunctionVessel.h.func-sort-c.html new file mode 100644 index 000000000000..efa3d87d1c14 --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.h.func-sort-c.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/FunctionVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - FunctionVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.h.func.html b/coverage/vesselbase/FunctionVessel.h.func.html new file mode 100644 index 000000000000..2145a887b174 --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.h.func.html @@ -0,0 +1,73 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/FunctionVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - FunctionVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ +
+ + + + + + +

Function Name Sort by function nameHit count Sort by hit count
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/FunctionVessel.h.gcov.html b/coverage/vesselbase/FunctionVessel.h.gcov.html new file mode 100644 index 000000000000..59dafe297779 --- /dev/null +++ b/coverage/vesselbase/FunctionVessel.h.gcov.html @@ -0,0 +1,143 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/FunctionVessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - FunctionVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:010.0 %
Date:2024-02-22 21:58:45Functions:00-
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_vesselbase_FunctionVessel_h
+      23             : #define __PLUMED_vesselbase_FunctionVessel_h
+      24             : 
+      25             : #include <string>
+      26             : #include <cstring>
+      27             : #include <vector>
+      28             : #include "ValueVessel.h"
+      29             : #include "core/Value.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace vesselbase {
+      33             : 
+      34             : /**
+      35             : \ingroup TOOLBOX
+      36             : Objects that inherit from FunctionVessel can be used (in tandem with PLMD::vesselbase::ActionWithVessel) to calculate
+      37             : functions of the form \f$\prod_k H_k[ \sum_j \prod_i g_i(x) ]\f$.  They should take in a series of values
+      38             : and return one single value.
+      39             : */
+      40             : 
+      41           0 : class FunctionVessel : public ValueVessel {
+      42             : protected:
+      43             : /// Are the derivatives differentiable
+      44             :   bool diffweight;
+      45             : /// Are we normalising by the weight
+      46             :   bool norm;
+      47             : /// Are we using the tolerance
+      48             :   bool usetol;
+      49             : public:
+      50             :   static void registerKeywords( Keywords& keys );
+      51             :   explicit FunctionVessel( const VesselOptions& );
+      52             : /// This does the resizing of the buffer
+      53             :   void resize() override;
+      54             : /// Do the calcualtion
+      55             :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const override;
+      56             : /// Do any transformations of the value that are required
+      57             :   virtual double calcTransform( const double& val, double& df ) const ;
+      58             : /// Finish the calculation of the quantity
+      59             :   void finish( const std::vector<double>& buffer ) override;
+      60             : /// Finish with any transforms required
+      61             :   virtual double finalTransform( const double& val, double& dv );
+      62             : };
+      63             : 
+      64             : }
+      65             : }
+      66             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Highest.cpp.func-sort-c.html b/coverage/vesselbase/Highest.cpp.func-sort-c.html new file mode 100644 index 000000000000..f2eb713f3b40 --- /dev/null +++ b/coverage/vesselbase/Highest.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Highest.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Highest.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMe6createERKNS0_13VesselOptionsE5
_ZN4PLMD10vesselbase7Highest16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD10vesselbase7Highest16value_descriptorB5cxx11Ev5
_ZN4PLMD10vesselbase7HighestC2ERKNS0_13VesselOptionsE5
_ZN4PLMD10vesselbase7Highest7compareERKdS3_4047
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeD2Ev4187
_ZN4PLMD10vesselbase7Highest14reserveKeywordERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Highest.cpp.func.html b/coverage/vesselbase/Highest.cpp.func.html new file mode 100644 index 000000000000..49ba02d2d63f --- /dev/null +++ b/coverage/vesselbase/Highest.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Highest.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Highest.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMe6createERKNS0_13VesselOptionsE5
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_117HighestRegisterMeD2Ev4187
_ZN4PLMD10vesselbase7Highest14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase7Highest16registerKeywordsERNS_8KeywordsE5
_ZN4PLMD10vesselbase7Highest16value_descriptorB5cxx11Ev5
_ZN4PLMD10vesselbase7Highest7compareERKdS3_4047
_ZN4PLMD10vesselbase7HighestC2ERKNS0_13VesselOptionsE5
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Highest.cpp.gcov.html b/coverage/vesselbase/Highest.cpp.gcov.html new file mode 100644 index 000000000000..57f0277d0570 --- /dev/null +++ b/coverage/vesselbase/Highest.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Highest.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Highest.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "OrderingVessel.h"
+      23             : #include "VesselRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace vesselbase {
+      27             : 
+      28             : class Highest : public OrderingVessel {
+      29             : public:
+      30             :   static void registerKeywords( Keywords& keys );
+      31             :   static void reserveKeyword( Keywords& keys );
+      32             :   explicit Highest( const VesselOptions& da );
+      33             :   std::string value_descriptor() override;
+      34             :   bool compare( const double&, const double& ) override;
+      35             : };
+      36             : 
+      37       12566 : PLUMED_REGISTER_VESSEL(Highest,"HIGHEST")
+      38             : 
+      39           5 : void Highest::registerKeywords( Keywords& keys ) {
+      40           5 :   OrderingVessel::registerKeywords( keys );
+      41           5 : }
+      42             : 
+      43        4187 : void Highest::reserveKeyword( Keywords& keys ) {
+      44        8374 :   keys.reserve("vessel","HIGHEST","this flag allows you to recover the highest of these variables.");
+      45        8374 :   keys.addOutputComponent("highest","HIGHEST","the highest of the quantities calculated by this action");
+      46        4187 : }
+      47             : 
+      48           5 : Highest::Highest( const VesselOptions& da ) :
+      49           5 :   OrderingVessel(da)
+      50             : {
+      51           5 : }
+      52             : 
+      53           5 : std::string Highest::value_descriptor() {
+      54           5 :   return "the highest of the individual colvar values";
+      55             : }
+      56             : 
+      57        4047 : bool Highest::compare( const double& val1, const double& val2 ) {
+      58        4047 :   return val1>val2;
+      59             : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Histogram.cpp.func-sort-c.html b/coverage/vesselbase/Histogram.cpp.func-sort-c.html new file mode 100644 index 000000000000..cbf0785094f7 --- /dev/null +++ b/coverage/vesselbase/Histogram.cpp.func-sort-c.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Histogram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Histogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMe6createERKNS0_13VesselOptionsE11
_ZN4PLMD10vesselbase9Histogram16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD10vesselbase9HistogramC2ERKNS0_13VesselOptionsE11
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMeD2Ev4187
_ZN4PLMD10vesselbase9Histogram14reserveKeywordERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Histogram.cpp.func.html b/coverage/vesselbase/Histogram.cpp.func.html new file mode 100644 index 000000000000..e522d76c3dc6 --- /dev/null +++ b/coverage/vesselbase/Histogram.cpp.func.html @@ -0,0 +1,97 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Histogram.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Histogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMe6createERKNS0_13VesselOptionsE11
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_119HistogramRegisterMeD2Ev4187
_ZN4PLMD10vesselbase9Histogram14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase9Histogram16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD10vesselbase9HistogramC2ERKNS0_13VesselOptionsE11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Histogram.cpp.gcov.html b/coverage/vesselbase/Histogram.cpp.gcov.html new file mode 100644 index 000000000000..b7d2d17c3500 --- /dev/null +++ b/coverage/vesselbase/Histogram.cpp.gcov.html @@ -0,0 +1,140 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Histogram.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Histogram.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:66100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "tools/HistogramBead.h"
+      23             : #include "VesselRegister.h"
+      24             : #include "ShortcutVessel.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace vesselbase {
+      28             : 
+      29             : class Histogram : public ShortcutVessel {
+      30             : public:
+      31             :   static void registerKeywords( Keywords& keys );
+      32             :   static void reserveKeyword( Keywords& keys );
+      33             :   explicit Histogram( const VesselOptions& da );
+      34             : };
+      35             : 
+      36       12572 : PLUMED_REGISTER_VESSEL(Histogram,"HISTOGRAM")
+      37             : 
+      38          11 : void Histogram::registerKeywords( Keywords& keys ) {
+      39          11 :   ShortcutVessel::registerKeywords( keys );
+      40          11 :   HistogramBead::registerKeywords( keys );
+      41          22 :   keys.add("compulsory","NBINS","The number of equal width bins you want to divide the range into");
+      42          22 :   keys.addFlag("NORM",false,"calculate the fraction of values rather than the number");
+      43          22 :   keys.add("compulsory","COMPONENT","1","the component of the vector for which to calculate this quantity");
+      44          11 : }
+      45             : 
+      46        4187 : void Histogram::reserveKeyword( Keywords& keys ) {
+      47        8374 :   keys.reserve("vessel","HISTOGRAM","calculate how many of the values fall in each of the bins of a histogram. "
+      48             :                "This shortcut allows you to calculates NBIN quantities like BETWEEN.");
+      49        4187 : }
+      50             : 
+      51          11 : Histogram::Histogram( const VesselOptions& da ):
+      52          11 :   ShortcutVessel(da)
+      53             : {
+      54          22 :   bool norm; parseFlag("NORM",norm); std::string normstr="";
+      55          11 :   if(norm) normstr=" NORM";
+      56          11 :   std::string compstr; parse("COMPONENT",compstr);
+      57          22 :   normstr+=" COMPONENT=" + compstr;
+      58          11 :   std::vector<std::string> bins; HistogramBead::generateBins( getAllInput(), bins );
+      59          43 :   for(unsigned i=0; i<bins.size(); ++i) addVessel("BETWEEN",bins[i] + normstr);
+      60          22 : }
+      61             : 
+      62             : }
+      63             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/LessThan.cpp.func-sort-c.html b/coverage/vesselbase/LessThan.cpp.func-sort-c.html new file mode 100644 index 000000000000..73c75363b0e4 --- /dev/null +++ b/coverage/vesselbase/LessThan.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/LessThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - LessThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase8LessThan9getCutoffEv16
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMe6createERKNS0_13VesselOptionsE60
_ZN4PLMD10vesselbase8LessThan16registerKeywordsERNS_8KeywordsE60
_ZN4PLMD10vesselbase8LessThan16value_descriptorB5cxx11Ev60
_ZN4PLMD10vesselbase8LessThanC2ERKNS0_13VesselOptionsE60
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMeD2Ev4187
_ZN4PLMD10vesselbase8LessThan14reserveKeywordERNS_8KeywordsE4187
_ZNK4PLMD10vesselbase8LessThan13calcTransformERKdRd57357
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/LessThan.cpp.func.html b/coverage/vesselbase/LessThan.cpp.func.html new file mode 100644 index 000000000000..8a4f87b74b01 --- /dev/null +++ b/coverage/vesselbase/LessThan.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/LessThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - LessThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMe6createERKNS0_13VesselOptionsE60
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_118LessThanRegisterMeD2Ev4187
_ZN4PLMD10vesselbase8LessThan14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase8LessThan16registerKeywordsERNS_8KeywordsE60
_ZN4PLMD10vesselbase8LessThan16value_descriptorB5cxx11Ev60
_ZN4PLMD10vesselbase8LessThan9getCutoffEv16
_ZN4PLMD10vesselbase8LessThanC2ERKNS0_13VesselOptionsE60
_ZNK4PLMD10vesselbase8LessThan13calcTransformERKdRd57357
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/LessThan.cpp.gcov.html b/coverage/vesselbase/LessThan.cpp.gcov.html new file mode 100644 index 000000000000..bb60e750391a --- /dev/null +++ b/coverage/vesselbase/LessThan.cpp.gcov.html @@ -0,0 +1,143 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/LessThan.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - LessThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2222100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "LessThan.h"
+      23             : #include "VesselRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace vesselbase {
+      27             : 
+      28       12621 : PLUMED_REGISTER_VESSEL(LessThan,"LESS_THAN")
+      29             : 
+      30          60 : void LessThan::registerKeywords( Keywords& keys ) {
+      31          60 :   FunctionVessel::registerKeywords( keys );
+      32          60 :   SwitchingFunction::registerKeywords( keys );
+      33          60 : }
+      34             : 
+      35        4187 : void LessThan::reserveKeyword( Keywords& keys ) {
+      36        8374 :   keys.reserve("vessel","LESS_THAN","calculate the number of variables less than a certain target value. "
+      37             :                "This quantity is calculated using \\f$\\sum_i \\sigma(s_i)\\f$, where \\f$\\sigma(s)\\f$ "
+      38             :                "is a \\ref switchingfunction.");
+      39        8374 :   keys.addOutputComponent("lessthan","LESS_THAN","the number of values less than a target value. This is calculated using one of the "
+      40             :                           "formula described in the description of the keyword so as to make it continuous. "
+      41             :                           "You can calculate this quantity multiple times using different parameters.");
+      42        4187 : }
+      43             : 
+      44          60 : LessThan::LessThan( const VesselOptions& da ) :
+      45          60 :   FunctionVessel(da)
+      46             : {
+      47          60 :   usetol=true;
+      48          60 :   if( getAction()->isPeriodic() ) error("LESS_THAN is not a meaningful option for periodic variables");
+      49         120 :   std::string errormsg; sf.set( getAllInput(), errormsg );
+      50          60 :   if( errormsg.size()!=0 ) error( errormsg );
+      51          60 : }
+      52             : 
+      53          60 : std::string LessThan::value_descriptor() {
+      54         120 :   return "the number of values less than " + sf.description();
+      55             : }
+      56             : 
+      57       57357 : double LessThan::calcTransform( const double& val, double& dv ) const {
+      58       57357 :   double f = sf.calculate(val, dv); dv*=val; return f;
+      59             : }
+      60             : 
+      61          16 : double LessThan::getCutoff() {
+      62          16 :   return sf.get_dmax();
+      63             : }
+      64             : 
+      65             : }
+      66             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Lowest.cpp.func-sort-c.html b/coverage/vesselbase/Lowest.cpp.func-sort-c.html new file mode 100644 index 000000000000..acaeb5baec64 --- /dev/null +++ b/coverage/vesselbase/Lowest.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Lowest.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Lowest.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMe6createERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase6Lowest16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD10vesselbase6Lowest16value_descriptorB5cxx11Ev3
_ZN4PLMD10vesselbase6LowestC2ERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase6Lowest7compareERKdS3_68
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMeD2Ev4187
_ZN4PLMD10vesselbase6Lowest14reserveKeywordERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Lowest.cpp.func.html b/coverage/vesselbase/Lowest.cpp.func.html new file mode 100644 index 000000000000..8f40b65b9869 --- /dev/null +++ b/coverage/vesselbase/Lowest.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Lowest.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Lowest.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMe6createERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_116LowestRegisterMeD2Ev4187
_ZN4PLMD10vesselbase6Lowest14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase6Lowest16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD10vesselbase6Lowest16value_descriptorB5cxx11Ev3
_ZN4PLMD10vesselbase6Lowest7compareERKdS3_68
_ZN4PLMD10vesselbase6LowestC2ERKNS0_13VesselOptionsE3
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Lowest.cpp.gcov.html b/coverage/vesselbase/Lowest.cpp.gcov.html new file mode 100644 index 000000000000..d293dae82901 --- /dev/null +++ b/coverage/vesselbase/Lowest.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Lowest.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Lowest.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "OrderingVessel.h"
+      23             : #include "VesselRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace vesselbase {
+      27             : 
+      28             : class Lowest : public OrderingVessel {
+      29             : public:
+      30             :   static void registerKeywords( Keywords& keys );
+      31             :   static void reserveKeyword( Keywords& keys );
+      32             :   explicit Lowest( const VesselOptions& da );
+      33             :   std::string value_descriptor() override;
+      34             :   bool compare( const double&, const double& ) override;
+      35             : };
+      36             : 
+      37       12564 : PLUMED_REGISTER_VESSEL(Lowest,"LOWEST")
+      38             : 
+      39           3 : void Lowest::registerKeywords( Keywords& keys ) {
+      40           3 :   OrderingVessel::registerKeywords( keys );
+      41           3 : }
+      42             : 
+      43        4187 : void Lowest::reserveKeyword( Keywords& keys ) {
+      44        8374 :   keys.reserve("vessel","LOWEST","this flag allows you to recover the lowest of these variables.");
+      45        8374 :   keys.addOutputComponent("lowest","LOWEST","the lowest of the quantities calculated by this action");
+      46        4187 : }
+      47             : 
+      48           3 : Lowest::Lowest( const VesselOptions& da ) :
+      49           3 :   OrderingVessel(da)
+      50             : {
+      51           3 : }
+      52             : 
+      53           3 : std::string Lowest::value_descriptor() {
+      54           3 :   return "the lowest of the individual colvar values";
+      55             : }
+      56             : 
+      57          68 : bool Lowest::compare( const double& val1, const double& val2 ) {
+      58          68 :   return val1<val2;
+      59             : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Max.cpp.func-sort-c.html b/coverage/vesselbase/Max.cpp.func-sort-c.html new file mode 100644 index 000000000000..1acb8d89d120 --- /dev/null +++ b/coverage/vesselbase/Max.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Max.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Max.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMe6createERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase3Max16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD10vesselbase3Max16value_descriptorB5cxx11Ev3
_ZN4PLMD10vesselbase3MaxC2ERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase3Max14finalTransformERKdRd6
_ZNK4PLMD10vesselbase3Max13calcTransformERKdRd13
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMeD2Ev4187
_ZN4PLMD10vesselbase3Max14reserveKeywordERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Max.cpp.func.html b/coverage/vesselbase/Max.cpp.func.html new file mode 100644 index 000000000000..e0da6dbc9b1c --- /dev/null +++ b/coverage/vesselbase/Max.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Max.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Max.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMe6createERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_113MaxRegisterMeD2Ev4187
_ZN4PLMD10vesselbase3Max14finalTransformERKdRd6
_ZN4PLMD10vesselbase3Max14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase3Max16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD10vesselbase3Max16value_descriptorB5cxx11Ev3
_ZN4PLMD10vesselbase3MaxC2ERKNS0_13VesselOptionsE3
_ZNK4PLMD10vesselbase3Max13calcTransformERKdRd13
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Max.cpp.gcov.html b/coverage/vesselbase/Max.cpp.gcov.html new file mode 100644 index 000000000000..c015ef748720 --- /dev/null +++ b/coverage/vesselbase/Max.cpp.gcov.html @@ -0,0 +1,159 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Max.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Max.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2323100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "VesselRegister.h"
+      23             : #include "FunctionVessel.h"
+      24             : #include "ActionWithVessel.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace vesselbase {
+      28             : 
+      29             : class Max : public FunctionVessel {
+      30             : private:
+      31             :   double beta;
+      32             : public:
+      33             :   static void registerKeywords( Keywords& keys );
+      34             :   static void reserveKeyword( Keywords& keys );
+      35             :   explicit Max( const VesselOptions& da );
+      36             :   std::string value_descriptor() override;
+      37             :   double calcTransform( const double& val, double& dv ) const override;
+      38             :   double finalTransform( const double& val, double& dv ) override;
+      39             : };
+      40             : 
+      41       12564 : PLUMED_REGISTER_VESSEL(Max,"MAX")
+      42             : 
+      43           3 : void Max::registerKeywords( Keywords& keys ) {
+      44           3 :   FunctionVessel::registerKeywords( keys );
+      45           6 :   keys.add("compulsory","BETA","the value of beta for the equation in the manual");
+      46           3 : }
+      47             : 
+      48        4187 : void Max::reserveKeyword( Keywords& keys ) {
+      49        8374 :   keys.reserve("vessel","MAX","calculate the maximum value. "
+      50             :                "To make this quantity continuous the maximum is calculated using "
+      51             :                "\\f$ \\textrm{max} = \\beta \\log \\sum_i \\exp\\left( \\frac{s_i}{\\beta}\\right) \\f$ "
+      52             :                "The value of \\f$\\beta\\f$ in this function is specified using (BETA=\\f$\\beta\\f$)");
+      53        8374 :   keys.addOutputComponent("max","MAX","the maximum value. This is calculated using the formula described in the description of the "
+      54             :                           "keyword so as to make it continuous.");
+      55             : 
+      56        4187 : }
+      57             : 
+      58           3 : Max::Max( const VesselOptions& da ) :
+      59           3 :   FunctionVessel(da)
+      60             : {
+      61           3 :   if( getAction()->isPeriodic() ) error("max is not a meaningful option for periodic variables");
+      62           3 :   parse("BETA",beta);
+      63             : 
+      64           3 :   if( diffweight ) error("can't calculate max if weight is differentiable");
+      65           3 : }
+      66             : 
+      67           3 : std::string Max::value_descriptor() {
+      68           3 :   std::string str_beta; Tools::convert( beta, str_beta );
+      69           6 :   return "the maximum value. Beta is equal to " + str_beta;
+      70             : }
+      71             : 
+      72          13 : double Max::calcTransform( const double& val, double& dv ) const {
+      73          13 :   double f = exp(val/beta); dv=f/beta; return f;
+      74             : }
+      75             : 
+      76           6 : double Max::finalTransform( const double& val, double& dv ) {
+      77           6 :   double dist=beta*std::log( val );
+      78           6 :   dv = beta/val; return dist;
+      79             : }
+      80             : 
+      81             : }
+      82             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Mean.cpp.func-sort-c.html b/coverage/vesselbase/Mean.cpp.func-sort-c.html new file mode 100644 index 000000000000..c66be699c025 --- /dev/null +++ b/coverage/vesselbase/Mean.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Mean.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Mean.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMe6createERKNS0_13VesselOptionsE85
_ZN4PLMD10vesselbase4Mean16registerKeywordsERNS_8KeywordsE85
_ZN4PLMD10vesselbase4Mean16value_descriptorB5cxx11Ev85
_ZN4PLMD10vesselbase4MeanC2ERKNS0_13VesselOptionsE85
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeD2Ev4187
_ZN4PLMD10vesselbase4Mean14reserveKeywordERNS_8KeywordsE4187
_ZNK4PLMD10vesselbase4Mean13calcTransformERKdRd80201
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Mean.cpp.func.html b/coverage/vesselbase/Mean.cpp.func.html new file mode 100644 index 000000000000..a0c1a6f1b81a --- /dev/null +++ b/coverage/vesselbase/Mean.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Mean.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Mean.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMe6createERKNS0_13VesselOptionsE85
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_114MeanRegisterMeD2Ev4187
_ZN4PLMD10vesselbase4Mean14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase4Mean16registerKeywordsERNS_8KeywordsE85
_ZN4PLMD10vesselbase4Mean16value_descriptorB5cxx11Ev85
_ZN4PLMD10vesselbase4MeanC2ERKNS0_13VesselOptionsE85
_ZNK4PLMD10vesselbase4Mean13calcTransformERKdRd80201
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Mean.cpp.gcov.html b/coverage/vesselbase/Mean.cpp.gcov.html new file mode 100644 index 000000000000..dd56486da6b3 --- /dev/null +++ b/coverage/vesselbase/Mean.cpp.gcov.html @@ -0,0 +1,143 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Mean.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Mean.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1717100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "VesselRegister.h"
+      23             : #include "FunctionVessel.h"
+      24             : #include "ActionWithVessel.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace vesselbase {
+      28             : 
+      29             : class Mean : public FunctionVessel {
+      30             : public:
+      31             :   static void registerKeywords( Keywords& keys );
+      32             :   static void reserveKeyword( Keywords& keys );
+      33             :   explicit Mean( const vesselbase::VesselOptions& da );
+      34             :   std::string value_descriptor() override;
+      35             :   double calcTransform( const double& val, double& dv ) const override;
+      36             : };
+      37             : 
+      38       12646 : PLUMED_REGISTER_VESSEL(Mean,"MEAN")
+      39             : 
+      40          85 : void Mean::registerKeywords( Keywords& keys ) {
+      41          85 :   FunctionVessel::registerKeywords(keys);
+      42          85 : }
+      43             : 
+      44        4187 : void Mean::reserveKeyword( Keywords& keys ) {
+      45        8374 :   keys.reserve("vessel","MEAN","take the mean of these variables.");
+      46        8374 :   keys.addOutputComponent("mean","MEAN","the mean value. The output component can be referred to elsewhere in the input "
+      47             :                           "file by using the label.mean");
+      48        4187 : }
+      49             : 
+      50          85 : Mean::Mean( const vesselbase::VesselOptions& da ) :
+      51          85 :   FunctionVessel(da)
+      52             : {
+      53          85 :   if( getAction()->isPeriodic() ) error("MEAN cannot be used with periodic variables");
+      54          85 :   norm=true;   // Makes sure we calculate the average
+      55          85 : }
+      56             : 
+      57          85 : std::string Mean::value_descriptor() {
+      58          85 :   return "the mean value";
+      59             : }
+      60             : 
+      61       80201 : double Mean::calcTransform( const double& val, double& dv ) const {
+      62       80201 :   dv=1.0; return val;
+      63             : }
+      64             : 
+      65             : }
+      66             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Min.cpp.func-sort-c.html b/coverage/vesselbase/Min.cpp.func-sort-c.html new file mode 100644 index 000000000000..a66f19d133bd --- /dev/null +++ b/coverage/vesselbase/Min.cpp.func-sort-c.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Min.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Min.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMe6createERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase3Min16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD10vesselbase3Min16value_descriptorB5cxx11Ev3
_ZN4PLMD10vesselbase3MinC2ERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase3Min14finalTransformERKdRd6
_ZNK4PLMD10vesselbase3Min13calcTransformERKdRd12
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMeD2Ev4187
_ZN4PLMD10vesselbase3Min14reserveKeywordERNS_8KeywordsE4187
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Min.cpp.func.html b/coverage/vesselbase/Min.cpp.func.html new file mode 100644 index 000000000000..9f9e4f9356a0 --- /dev/null +++ b/coverage/vesselbase/Min.cpp.func.html @@ -0,0 +1,109 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Min.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Min.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMe6createERKNS0_13VesselOptionsE3
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_113MinRegisterMeD2Ev4187
_ZN4PLMD10vesselbase3Min14finalTransformERKdRd6
_ZN4PLMD10vesselbase3Min14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase3Min16registerKeywordsERNS_8KeywordsE3
_ZN4PLMD10vesselbase3Min16value_descriptorB5cxx11Ev3
_ZN4PLMD10vesselbase3MinC2ERKNS0_13VesselOptionsE3
_ZNK4PLMD10vesselbase3Min13calcTransformERKdRd12
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Min.cpp.gcov.html b/coverage/vesselbase/Min.cpp.gcov.html new file mode 100644 index 000000000000..926b73605663 --- /dev/null +++ b/coverage/vesselbase/Min.cpp.gcov.html @@ -0,0 +1,159 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Min.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Min.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2424100.0 %
Date:2024-02-22 21:58:45Functions:99100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "VesselRegister.h"
+      23             : #include "FunctionVessel.h"
+      24             : #include "ActionWithVessel.h"
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace vesselbase {
+      28             : 
+      29             : class Min : public FunctionVessel {
+      30             : private:
+      31             :   double beta;
+      32             : public:
+      33             :   static void registerKeywords( Keywords& keys );
+      34             :   static void reserveKeyword( Keywords& keys );
+      35             :   explicit Min( const VesselOptions& da );
+      36             :   std::string value_descriptor() override;
+      37             :   double calcTransform( const double& val, double& dv ) const override;
+      38             :   double finalTransform( const double& val, double& dv ) override;
+      39             : };
+      40             : 
+      41       12564 : PLUMED_REGISTER_VESSEL(Min,"MIN")
+      42             : 
+      43           3 : void Min::registerKeywords( Keywords& keys ) {
+      44           3 :   FunctionVessel::registerKeywords( keys );
+      45           6 :   keys.add("compulsory","BETA","the value of beta for the equation in the manual");
+      46           3 : }
+      47             : 
+      48        4187 : void Min::reserveKeyword( Keywords& keys ) {
+      49        8374 :   keys.reserve("vessel","MIN","calculate the minimum value. "
+      50             :                "To make this quantity continuous the minimum is calculated using "
+      51             :                "\\f$ \\textrm{min} = \\frac{\\beta}{ \\log \\sum_i \\exp\\left( \\frac{\\beta}{s_i} \\right) } \\f$ "
+      52             :                "The value of \\f$\\beta\\f$ in this function is specified using (BETA=\\f$\\beta\\f$)");
+      53        8374 :   keys.addOutputComponent("min","MIN","the minimum value. This is calculated using the formula described in the description of the "
+      54             :                           "keyword so as to make it continuous.");
+      55        4187 : }
+      56             : 
+      57           3 : Min::Min( const VesselOptions& da ) :
+      58           3 :   FunctionVessel(da)
+      59             : {
+      60           3 :   if( getAction()->isPeriodic() ) error("min is not a meaningful option for periodic variables");
+      61           3 :   parse("BETA",beta);
+      62             : 
+      63           3 :   if( diffweight ) error("can't calculate min if weight is differentiable");
+      64           3 : }
+      65             : 
+      66           3 : std::string Min::value_descriptor() {
+      67           3 :   std::string str_beta; Tools::convert( beta, str_beta );
+      68           6 :   return "the minimum value. Beta is equal to " + str_beta;
+      69             : }
+      70             : 
+      71          12 : double Min::calcTransform( const double& val, double& dv ) const {
+      72          12 :   double f = exp(beta/val); dv=f/(val*val);
+      73          12 :   return f;
+      74             : }
+      75             : 
+      76           6 : double Min::finalTransform( const double& val, double& dv ) {
+      77           6 :   double dist=beta/std::log( val );
+      78           6 :   dv = dist*dist/val; return dist;
+      79             : }
+      80             : 
+      81             : }
+      82             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Moments.cpp.func-sort-c.html b/coverage/vesselbase/Moments.cpp.func-sort-c.html new file mode 100644 index 000000000000..f587c4370420 --- /dev/null +++ b/coverage/vesselbase/Moments.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Moments.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Moments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:829289.1 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMe6createERKNS0_13VesselOptionsE8
_ZN4PLMD10vesselbase7Moments11descriptionB5cxx11Ev8
_ZN4PLMD10vesselbase7Moments16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD10vesselbase7MomentsC2ERKNS0_13VesselOptionsE8
_ZN4PLMD10vesselbase7Moments6resizeEv28
_ZN4PLMD10vesselbase7Moments10applyForceERSt6vectorIdSaIdEE432
_ZN4PLMD10vesselbase7Moments6finishERKSt6vectorIdSaIdEE822
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMeD2Ev4187
_ZN4PLMD10vesselbase7Moments14reserveKeywordERNS_8KeywordsE4187
_ZNK4PLMD10vesselbase7Moments9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE6936
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Moments.cpp.func.html b/coverage/vesselbase/Moments.cpp.func.html new file mode 100644 index 000000000000..5d0fda992920 --- /dev/null +++ b/coverage/vesselbase/Moments.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Moments.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Moments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:829289.1 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMe6createERKNS0_13VesselOptionsE8
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_117MomentsRegisterMeD2Ev4187
_ZN4PLMD10vesselbase7Moments10applyForceERSt6vectorIdSaIdEE432
_ZN4PLMD10vesselbase7Moments11descriptionB5cxx11Ev8
_ZN4PLMD10vesselbase7Moments14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase7Moments16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD10vesselbase7Moments6finishERKSt6vectorIdSaIdEE822
_ZN4PLMD10vesselbase7Moments6resizeEv28
_ZN4PLMD10vesselbase7MomentsC2ERKNS0_13VesselOptionsE8
_ZNK4PLMD10vesselbase7Moments9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE6936
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Moments.cpp.gcov.html b/coverage/vesselbase/Moments.cpp.gcov.html new file mode 100644 index 000000000000..ae24c7b40532 --- /dev/null +++ b/coverage/vesselbase/Moments.cpp.gcov.html @@ -0,0 +1,268 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Moments.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Moments.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:829289.1 %
Date:2024-02-22 21:58:45Functions:1111100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "VesselRegister.h"
+      23             : #include "Vessel.h"
+      24             : #include "StoreDataVessel.h"
+      25             : #include "ActionWithVessel.h"
+      26             : 
+      27             : namespace PLMD {
+      28             : namespace vesselbase {
+      29             : 
+      30             : // This is not the most efficient implementation
+      31             : // The calculation of all the colvars is parallelized
+      32             : // but the loops for calculating moments are not
+      33             : // Feel free to reimplement this if you know how
+      34             : class Moments : public Vessel {
+      35             : private:
+      36             :   unsigned mycomponent;
+      37             :   StoreDataVessel* mystash;
+      38             :   std::vector<unsigned> powers;
+      39             :   std::vector<Value*> value_out;
+      40             : public:
+      41             :   static void registerKeywords( Keywords& keys );
+      42             :   static void reserveKeyword( Keywords& keys );
+      43             :   explicit Moments( const vesselbase::VesselOptions& da );
+      44             :   std::string description() override;
+      45             :   void resize() override;
+      46        6936 :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const override {}
+      47             :   void finish( const std::vector<double>& buffer ) override;
+      48             :   bool applyForce( std::vector<double>& forces ) override;
+      49             : };
+      50             : 
+      51       12569 : PLUMED_REGISTER_VESSEL(Moments,"MOMENTS")
+      52             : 
+      53           8 : void Moments::registerKeywords( Keywords& keys ) {
+      54           8 :   Vessel::registerKeywords( keys );
+      55           8 :   keys.remove("LABEL");
+      56          16 :   keys.add("compulsory","COMPONENT","1","the component of the vector for which to calculate this quantity");
+      57          16 :   keys.add("optional","MOMENTS","the list of moments that you would like to calculate");
+      58           8 : }
+      59             : 
+      60        4187 : void Moments::reserveKeyword( Keywords& keys ) {
+      61        8374 :   keys.reserve("optional","MOMENTS","calculate the moments of the distribution of collective variables. "
+      62             :                "The mth moment of a distribution is calculated using \\f$\\frac{1}{N} \\sum_{i=1}^N ( s_i - \\overline{s} )^m \\f$, where \\f$\\overline{s}\\f$ is "
+      63             :                "the average for the distribution. The moments keyword takes a lists of integers as input or a range. Each integer is a value of \\f$m\\f$. The final "
+      64             :                "calculated values can be referenced using moment-\\f$m\\f$.  You can use the COMPONENT keyword in this action but the syntax is slightly different. "
+      65             :                "If you would like the second and third moments of the third component you would use MOMENTS={COMPONENT=3 MOMENTS=2-3}.  The moments would then be referred to "
+      66             :                "using the labels moment-3-2 and moment-3-3.  This syntax is also required if you are using numbered MOMENT keywords i.e. MOMENTS1, MOMENTS2...");
+      67        8374 :   keys.reset_style("MOMENTS","vessel");
+      68        8374 :   keys.addOutputComponent("moment","MOMENTS","the central moments of the distribution of values. The second moment "
+      69             :                           "would be referenced elsewhere in the input file using "
+      70             :                           "<em>label</em>.moment-2, the third as <em>label</em>.moment-3, etc.");
+      71        4187 : }
+      72             : 
+      73           8 : Moments::Moments( const vesselbase::VesselOptions& da) :
+      74           8 :   Vessel(da)
+      75             : {
+      76           8 :   mystash = getAction()->buildDataStashes( NULL );
+      77           8 :   ActionWithValue* a=dynamic_cast<ActionWithValue*>( getAction() );
+      78           8 :   plumed_massert(a,"cannot create passable values as base action does not inherit from ActionWithValue");
+      79             : 
+      80           8 :   std::vector<std::string> moments; std::string valstr = "moment-";
+      81          24 :   parse("COMPONENT",mycomponent); parseVector("MOMENTS",moments);
+      82          10 :   if( getNumericalLabel()!=0 ) { std::string numstr; Tools::convert( mycomponent, numstr); valstr = "moment-" + numstr + "-"; }
+      83          14 :   if( moments.size()==0 ) moments=Tools::getWords(getAllInput(),"\t\n ,");
+      84           8 :   Tools::interpretRanges(moments); unsigned nn;
+      85          20 :   for(unsigned i=0; i<moments.size(); ++i) {
+      86          24 :     a->addComponentWithDerivatives( valstr + moments[i] );
+      87          24 :     a->componentIsNotPeriodic( valstr + moments[i] );
+      88          12 :     value_out.push_back( a->copyOutput( a->getNumberOfComponents()-1 ) );
+      89          12 :     Tools::convert( moments[i], nn );
+      90          12 :     if( nn<2 ) error("moments are only possible for m>=2" );
+      91          12 :     powers.push_back( nn ); std::string num; Tools::convert(powers[i],num);
+      92             :   }
+      93           8 : }
+      94             : 
+      95          28 : void Moments::resize() {
+      96             :   resizeBuffer(0);
+      97          28 :   if( getAction()->derivativesAreRequired() ) {
+      98          56 :     for(unsigned i=0; i<value_out.size(); ++i) value_out[i]->resizeDerivatives( getAction()->getNumberOfDerivatives() );
+      99             :   }
+     100          28 : }
+     101             : 
+     102           8 : std::string Moments::description() {
+     103             :   std::string descri, num;
+     104           8 :   Tools::convert(powers[0],num);
+     105           8 :   if( getNumericalLabel()==0 ) {
+     106          12 :     descri = "value " + getAction()->getLabel() + "." + "moment-" + num + " contains the " + num + "th moment of the distribution";
+     107           8 :     for(unsigned i=1; i<powers.size(); ++i) {
+     108           2 :       Tools::convert(powers[i],num);
+     109           4 :       descri = descri + "\n  value " + getAction()->getLabel() + "." + "moment-" + num + " contains the " + num + "th moment of the distribution";
+     110             :     }
+     111             :   } else {
+     112           2 :     std::string numlab; Tools::convert( mycomponent, numlab );
+     113           4 :     descri = "value " + getAction()->getLabel() + "." + "moment-" + numlab + "-" + num + " contains the " + num + "th moment for the distribution of component " + numlab;
+     114           4 :     for(unsigned i=1; i<powers.size(); ++i) {
+     115           2 :       Tools::convert(powers[i],num);
+     116           4 :       descri = descri + "\n  value " + getAction()->getLabel() + "." + "moment-" + numlab + "-" + num + " contains the " + num + "th moment for the distribution of component " + numlab;
+     117             :     }
+     118             :   }
+     119           8 :   return descri;
+     120             : }
+     121             : 
+     122         822 : void Moments::finish( const std::vector<double>& buffer ) {
+     123             :   const double pi=3.141592653589793238462643383279502884197169399375105820974944592307;
+     124             :   unsigned nvals=getAction()->getFullNumberOfTasks();
+     125         822 :   std::vector<double>  myvalues( getAction()->getNumberOfQuantities() );
+     126             : 
+     127         822 :   double mean=0; Value myvalue;
+     128         822 :   if( getAction()->isPeriodic() ) {
+     129           0 :     std::string str_min, str_max; getAction()->retrieveDomain( str_min, str_max );
+     130           0 :     double pfactor, min, max; Tools::convert(str_min,min); Tools::convert(str_max,max);
+     131           0 :     pfactor = 2*pi / ( max-min ); myvalue.setDomain( str_min, str_max );
+     132             :     double sinsum=0, cossum=0, val;
+     133           0 :     for(unsigned i=0; i<mystash->getNumberOfStoredValues(); ++i) {
+     134           0 :       mystash->retrieveSequentialValue( i, false, myvalues );
+     135           0 :       val=pfactor*( myvalues[mycomponent] - min );
+     136           0 :       sinsum+=std::sin(val); cossum+=std::cos(val);
+     137             :     }
+     138           0 :     mean = 0.5 + std::atan2( sinsum / static_cast<double>( nvals ), cossum / static_cast<double>( nvals ) ) / (2*pi);
+     139           0 :     mean = min + (max-min)*mean;
+     140             :   } else {
+     141        7758 :     for(unsigned i=0; i<mystash->getNumberOfStoredValues(); ++i) {
+     142        6936 :       mystash->retrieveSequentialValue( i, false, myvalues ); mean+=myvalues[mycomponent];
+     143             :     }
+     144         822 :     mean/=static_cast<double>( nvals ); myvalue.setNotPeriodic();
+     145             :   }
+     146             : 
+     147        2056 :   for(unsigned npow=0; npow<powers.size(); ++npow) {
+     148             :     double dev1=0;
+     149        1234 :     if( value_out[0]->getNumberOfDerivatives()>0 ) {
+     150        4606 :       for(unsigned i=0; i<mystash->getNumberOfStoredValues(); ++i) {
+     151        4172 :         mystash->retrieveSequentialValue( i, false, myvalues );
+     152        4172 :         dev1+=pow( myvalue.difference( mean, myvalues[mycomponent] ), powers[npow] - 1 );
+     153             :       }
+     154         434 :       dev1/=static_cast<double>( nvals );
+     155             :     }
+     156             : 
+     157             :     double moment=0;
+     158        1234 :     MultiValue myvals( getAction()->getNumberOfQuantities(), getAction()->getNumberOfDerivatives() ); myvals.clearAll();
+     159       11006 :     for(unsigned i=0; i<mystash->getNumberOfStoredValues(); ++i) {
+     160        9772 :       mystash->retrieveSequentialValue( i, false, myvalues );
+     161        9772 :       double tmp=myvalue.difference( mean, myvalues[mycomponent] );
+     162        9772 :       moment+=pow( tmp, powers[npow] );
+     163        9772 :       if( value_out[npow]->getNumberOfDerivatives() ) {
+     164        4172 :         double pref=pow( tmp, powers[npow] - 1 ) - dev1;
+     165        4172 :         mystash->retrieveDerivatives( i, false, myvals );
+     166      166880 :         for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
+     167             :           unsigned jatom=myvals.getActiveIndex(j);
+     168      162708 :           value_out[npow]->addDerivative(jatom, pref*myvals.getDerivative( mycomponent, jatom ) );
+     169             :         }
+     170        4172 :         myvals.clearAll();
+     171             :       }
+     172             :     }
+     173        1234 :     if( value_out[npow]->getNumberOfDerivatives()>0 ) value_out[npow]->chainRule( powers[npow] / static_cast<double>( nvals ) );
+     174        1234 :     value_out[npow]->set( moment / static_cast<double>( nvals ) );
+     175        1234 :   }
+     176        1644 : }
+     177             : 
+     178         432 : bool Moments::applyForce( std::vector<double>& forces ) {
+     179         432 :   std::vector<double> tmpforce( forces.size() );
+     180         432 :   forces.assign(forces.size(),0.0); bool wasforced=false;
+     181        1276 :   for(unsigned i=0; i<value_out.size(); ++i) {
+     182         844 :     if( value_out[i]->applyForce( tmpforce ) ) {
+     183             :       wasforced=true;
+     184           0 :       for(unsigned j=0; j<forces.size(); ++j) forces[j]+=tmpforce[j];
+     185             :     }
+     186             :   }
+     187         432 :   return wasforced;
+     188             : }
+     189             : 
+     190             : }
+     191             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/MoreThan.cpp.func-sort-c.html b/coverage/vesselbase/MoreThan.cpp.func-sort-c.html new file mode 100644 index 000000000000..2a4ecc28d7db --- /dev/null +++ b/coverage/vesselbase/MoreThan.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/MoreThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - MoreThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMe6createERKNS0_13VesselOptionsE33
_ZN4PLMD10vesselbase8MoreThan16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD10vesselbase8MoreThan16value_descriptorB5cxx11Ev33
_ZN4PLMD10vesselbase8MoreThanC2ERKNS0_13VesselOptionsE33
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeD2Ev4187
_ZN4PLMD10vesselbase8MoreThan14reserveKeywordERNS_8KeywordsE4187
_ZNK4PLMD10vesselbase8MoreThan13calcTransformERKdRd19014
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/MoreThan.cpp.func.html b/coverage/vesselbase/MoreThan.cpp.func.html new file mode 100644 index 000000000000..a909783c125c --- /dev/null +++ b/coverage/vesselbase/MoreThan.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/MoreThan.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - MoreThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMe6createERKNS0_13VesselOptionsE33
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_118MoreThanRegisterMeD2Ev4187
_ZN4PLMD10vesselbase8MoreThan14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase8MoreThan16registerKeywordsERNS_8KeywordsE33
_ZN4PLMD10vesselbase8MoreThan16value_descriptorB5cxx11Ev33
_ZN4PLMD10vesselbase8MoreThanC2ERKNS0_13VesselOptionsE33
_ZNK4PLMD10vesselbase8MoreThan13calcTransformERKdRd19014
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/MoreThan.cpp.gcov.html b/coverage/vesselbase/MoreThan.cpp.gcov.html new file mode 100644 index 000000000000..a1308b85ecc5 --- /dev/null +++ b/coverage/vesselbase/MoreThan.cpp.gcov.html @@ -0,0 +1,153 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/MoreThan.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - MoreThan.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:2020100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : 
+      23             : #include "VesselRegister.h"
+      24             : #include "FunctionVessel.h"
+      25             : #include "tools/SwitchingFunction.h"
+      26             : #include "ActionWithVessel.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace vesselbase {
+      30             : 
+      31             : class MoreThan : public FunctionVessel {
+      32             : private:
+      33             :   SwitchingFunction sf;
+      34             : public:
+      35             :   static void registerKeywords( Keywords& keys );
+      36             :   static void reserveKeyword( Keywords& keys );
+      37             :   explicit MoreThan( const VesselOptions& da );
+      38             :   std::string value_descriptor() override;
+      39             :   double calcTransform( const double& val, double& dv ) const override;
+      40             : };
+      41             : 
+      42       12594 : PLUMED_REGISTER_VESSEL(MoreThan,"MORE_THAN")
+      43             : 
+      44          33 : void MoreThan::registerKeywords( Keywords& keys ) {
+      45          33 :   FunctionVessel::registerKeywords( keys );
+      46          33 :   SwitchingFunction::registerKeywords( keys );
+      47          33 : }
+      48             : 
+      49        4187 : void MoreThan::reserveKeyword( Keywords& keys ) {
+      50        8374 :   keys.reserve("vessel","MORE_THAN","calculate the number of variables more than a certain target value. "
+      51             :                "This quantity is calculated using \\f$\\sum_i 1.0 - \\sigma(s_i)\\f$, where \\f$\\sigma(s)\\f$ "
+      52             :                "is a \\ref switchingfunction.");
+      53        8374 :   keys.addOutputComponent("morethan","MORE_THAN","the number of values more than a target value. This is calculated using one of the "
+      54             :                           "formula described in the description of the keyword so as to make it continuous. "
+      55             :                           "You can calculate this quantity multiple times using different parameters.");
+      56        4187 : }
+      57             : 
+      58          33 : MoreThan::MoreThan( const VesselOptions& da ) :
+      59          33 :   FunctionVessel(da)
+      60             : {
+      61          33 :   usetol=true;
+      62          33 :   if( getAction()->isPeriodic() ) error("more than is not a meaningful option for periodic variables");
+      63          66 :   std::string errormsg; sf.set( getAllInput(), errormsg );
+      64          33 :   if( errormsg.size()!=0 ) error( errormsg );
+      65          33 : }
+      66             : 
+      67          33 : std::string MoreThan::value_descriptor() {
+      68          66 :   return "the number of values more than " + sf.description();
+      69             : }
+      70             : 
+      71       19014 : double MoreThan::calcTransform( const double& val, double& dv ) const {
+      72       19014 :   double f = 1.0 - sf.calculate(val, dv); dv*=-val; return f;
+      73             : }
+      74             : 
+      75             : }
+      76             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.cpp.func-sort-c.html b/coverage/vesselbase/OrderingVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..8b909ef6c17b --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/OrderingVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - OrderingVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:272896.4 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14OrderingVessel16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD10vesselbase14OrderingVesselC2ERKNS0_13VesselOptionsE8
_ZN4PLMD10vesselbase14OrderingVessel6finishERKSt6vectorIdSaIdEE19
_ZN4PLMD10vesselbase14OrderingVessel6resizeEv34
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.cpp.func.html b/coverage/vesselbase/OrderingVessel.cpp.func.html new file mode 100644 index 000000000000..30232485f9f3 --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/OrderingVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - OrderingVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:272896.4 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14OrderingVessel16registerKeywordsERNS_8KeywordsE8
_ZN4PLMD10vesselbase14OrderingVessel6finishERKSt6vectorIdSaIdEE19
_ZN4PLMD10vesselbase14OrderingVessel6resizeEv34
_ZN4PLMD10vesselbase14OrderingVesselC2ERKNS0_13VesselOptionsE8
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.cpp.gcov.html b/coverage/vesselbase/OrderingVessel.cpp.gcov.html new file mode 100644 index 000000000000..aaa31c90c865 --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.cpp.gcov.html @@ -0,0 +1,148 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/OrderingVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - OrderingVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:272896.4 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "OrderingVessel.h"
+      23             : #include "core/ActionWithValue.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace vesselbase {
+      27             : 
+      28             : 
+      29           8 : void OrderingVessel::registerKeywords( Keywords& keys ) {
+      30           8 :   ValueVessel::registerKeywords( keys );
+      31           8 : }
+      32             : 
+      33           8 : OrderingVessel::OrderingVessel( const VesselOptions& da ) :
+      34           8 :   ValueVessel(da)
+      35             : {
+      36           8 :   mydata = getAction()->buildDataStashes( NULL );
+      37          26 :   for(unsigned i=0; i<getAction()->getNumberOfVessels(); ++i) {
+      38          18 :     if( getAction()->getPntrToVessel(i)->getName()==getName() )
+      39           0 :       error("calculating lowest/highest value multiple times serves no purpose");
+      40             :   }
+      41           8 : }
+      42             : 
+      43          34 : void OrderingVessel::resize() {
+      44             :   resizeBuffer( 0 );
+      45          34 :   if( getAction()->derivativesAreRequired() ) getFinalValue()->resizeDerivatives( getAction()->getNumberOfDerivatives() );
+      46          34 : }
+      47             : 
+      48          19 : void OrderingVessel::finish( const std::vector<double>& buffer ) {
+      49          19 :   std::vector<double> values( getAction()->getNumberOfQuantities() );
+      50          19 :   mydata->retrieveSequentialValue( 0, false, values );
+      51             : 
+      52          19 :   double min=values[mycomp]; unsigned mini=getAction()->getPositionInFullTaskList(0);
+      53        4134 :   for(unsigned i=1; i<mydata->getNumberOfStoredValues(); ++i) {
+      54        4115 :     mydata->retrieveSequentialValue( i, false, values );
+      55        4115 :     double newval = values[mycomp];
+      56        4115 :     if( compare( newval, min ) ) { min=newval; mini=getAction()->getPositionInFullTaskList(i); }
+      57             :   }
+      58          19 :   setOutputValue( min );
+      59             : 
+      60          19 :   if( getAction()->derivativesAreRequired() ) {
+      61          17 :     MultiValue myvals( getAction()->getNumberOfQuantities(), getAction()->getNumberOfDerivatives() );
+      62          17 :     mydata->retrieveDerivatives( mini, false, myvals ); Value* fval=getFinalValue();
+      63         551 :     for(unsigned i=0; i<myvals.getNumberActive(); ++i) {
+      64             :       unsigned ider=myvals.getActiveIndex(i);
+      65             :       fval->setDerivative( ider, myvals.getDerivative(mycomp,ider) );
+      66             :     }
+      67          17 :   }
+      68          19 : }
+      69             : 
+      70             : }
+      71             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.h.func-sort-c.html b/coverage/vesselbase/OrderingVessel.h.func-sort-c.html new file mode 100644 index 000000000000..6d7cd886484e --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/OrderingVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - OrderingVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD10vesselbase14OrderingVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE2118
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.h.func.html b/coverage/vesselbase/OrderingVessel.h.func.html new file mode 100644 index 000000000000..b4ec140cd3f2 --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/OrderingVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - OrderingVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZNK4PLMD10vesselbase14OrderingVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE2118
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/OrderingVessel.h.gcov.html b/coverage/vesselbase/OrderingVessel.h.gcov.html new file mode 100644 index 000000000000..d2b501b71968 --- /dev/null +++ b/coverage/vesselbase/OrderingVessel.h.gcov.html @@ -0,0 +1,127 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/OrderingVessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - OrderingVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:11100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_vesselbase_OrderingVessel_h
+      23             : #define __PLUMED_vesselbase_OrderingVessel_h
+      24             : 
+      25             : #include <string>
+      26             : #include <cstring>
+      27             : #include <vector>
+      28             : #include "ValueVessel.h"
+      29             : #include "StoreDataVessel.h"
+      30             : #include "core/Value.h"
+      31             : 
+      32             : namespace PLMD {
+      33             : namespace vesselbase {
+      34             : 
+      35             : class OrderingVessel : public ValueVessel {
+      36             : private:
+      37             :   StoreDataVessel* mydata;
+      38             : public:
+      39             :   static void registerKeywords( Keywords& keys );
+      40             :   explicit OrderingVessel( const VesselOptions& da );
+      41             :   void resize() override;
+      42        2118 :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const override {}
+      43             :   void finish( const std::vector<double>& buffer ) override;
+      44             :   virtual bool compare( const double&, const double& )=0;
+      45             : };
+      46             : 
+      47             : }
+      48             : }
+      49             : #endif
+      50             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.cpp.func-sort-c.html b/coverage/vesselbase/ShortcutVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..3b61eb0c6cf0 --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.cpp.func-sort-c.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ShortcutVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ShortcutVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14ShortcutVessel16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD10vesselbase14ShortcutVesselC2ERKNS0_13VesselOptionsE11
_ZN4PLMD10vesselbase14ShortcutVessel9addVesselERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_32
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.cpp.func.html b/coverage/vesselbase/ShortcutVessel.cpp.func.html new file mode 100644 index 000000000000..e140dc6c99fb --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.cpp.func.html @@ -0,0 +1,85 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ShortcutVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ShortcutVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14ShortcutVessel16registerKeywordsERNS_8KeywordsE11
_ZN4PLMD10vesselbase14ShortcutVessel9addVesselERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_32
_ZN4PLMD10vesselbase14ShortcutVesselC2ERKNS0_13VesselOptionsE11
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.cpp.gcov.html b/coverage/vesselbase/ShortcutVessel.cpp.gcov.html new file mode 100644 index 000000000000..5d2ea090f018 --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.cpp.gcov.html @@ -0,0 +1,124 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ShortcutVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ShortcutVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1212100.0 %
Date:2024-02-22 21:58:45Functions:33100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ShortcutVessel.h"
+      23             : #include "ActionWithVessel.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace vesselbase {
+      27             : 
+      28          11 : void ShortcutVessel::registerKeywords( Keywords& keys ) {
+      29          11 :   Vessel::registerKeywords( keys ); keys.remove("LABEL");
+      30          11 :   plumed_assert( keys.size()==0 );
+      31          11 : }
+      32             : 
+      33          11 : ShortcutVessel::ShortcutVessel( const VesselOptions& da):
+      34          11 :   Vessel(da)
+      35             : {
+      36          11 : }
+      37             : 
+      38          32 : void ShortcutVessel::addVessel( const std::string& name, const std::string& input ) {
+      39             :   unsigned numlab=1;
+      40          65 :   for(unsigned i=0; i<(getAction()->functions).size(); ++i) {
+      41          33 :     if( (getAction()->functions[i])->getName()==name ) numlab++;
+      42             :   }
+      43          32 :   getAction()->addVessel( name, input, numlab );
+      44          32 : }
+      45             : 
+      46             : }
+      47             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.h.func-sort-c.html b/coverage/vesselbase/ShortcutVessel.h.func-sort-c.html new file mode 100644 index 000000000000..e4a7ee78b974 --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.h.func-sort-c.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ShortcutVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ShortcutVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:060.0 %
Date:2024-02-22 21:58:45Functions:050.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14ShortcutVessel10applyForceERSt6vectorIdSaIdEE0
_ZN4PLMD10vesselbase14ShortcutVessel11descriptionB5cxx11Ev0
_ZN4PLMD10vesselbase14ShortcutVessel6finishERKSt6vectorIdSaIdEE0
_ZN4PLMD10vesselbase14ShortcutVessel6resizeEv0
_ZNK4PLMD10vesselbase14ShortcutVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.h.func.html b/coverage/vesselbase/ShortcutVessel.h.func.html new file mode 100644 index 000000000000..fa0e73ad2ad1 --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.h.func.html @@ -0,0 +1,93 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ShortcutVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ShortcutVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:060.0 %
Date:2024-02-22 21:58:45Functions:050.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14ShortcutVessel10applyForceERSt6vectorIdSaIdEE0
_ZN4PLMD10vesselbase14ShortcutVessel11descriptionB5cxx11Ev0
_ZN4PLMD10vesselbase14ShortcutVessel6finishERKSt6vectorIdSaIdEE0
_ZN4PLMD10vesselbase14ShortcutVessel6resizeEv0
_ZNK4PLMD10vesselbase14ShortcutVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE0
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ShortcutVessel.h.gcov.html b/coverage/vesselbase/ShortcutVessel.h.gcov.html new file mode 100644 index 000000000000..30db1523b27a --- /dev/null +++ b/coverage/vesselbase/ShortcutVessel.h.gcov.html @@ -0,0 +1,127 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ShortcutVessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ShortcutVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:060.0 %
Date:2024-02-22 21:58:45Functions:050.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_vesselbase_ShortcutVessel_h
+      23             : #define __PLUMED_vesselbase_ShortcutVessel_h
+      24             : 
+      25             : #include <string>
+      26             : #include <cstring>
+      27             : #include <vector>
+      28             : #include "Vessel.h"
+      29             : #include "core/Value.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace vesselbase {
+      33             : 
+      34           0 : class ShortcutVessel : public Vessel {
+      35             : protected:
+      36             :   void addVessel( const std::string& name, const std::string& intput );
+      37             : public:
+      38             :   static void registerKeywords( Keywords& keys );
+      39             :   explicit ShortcutVessel( const VesselOptions& );
+      40           0 :   std::string description() override { return ""; }
+      41           0 :   void resize() override { plumed_error(); }
+      42           0 :   void calculate( const unsigned& taskCode, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_index ) const override { plumed_error(); }
+      43           0 :   void finish( const std::vector<double>& buffer ) override { plumed_error(); }
+      44           0 :   bool applyForce( std::vector<double>& forces ) override { plumed_error(); }
+      45             : };
+      46             : 
+      47             : }
+      48             : }
+      49             : #endif
+      50             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.cpp.func-sort-c.html b/coverage/vesselbase/StoreDataVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..b1257a167c99 --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.cpp.func-sort-c.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/StoreDataVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - StoreDataVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:869293.5 %
Date:2024-02-22 21:58:45Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15StoreDataVessel16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD10vesselbase15StoreDataVessel17addActionThatUsesEPNS0_16ActionWithVesselE127
_ZN4PLMD10vesselbase15StoreDataVesselC2ERKNS0_13VesselOptionsE131
_ZN4PLMD10vesselbase15StoreDataVessel24resizeTemporyMultiValuesERKj143
_ZN4PLMD10vesselbase15StoreDataVessel27setActiveValsAndDerivativesERKSt6vectorIjSaIjEE690
_ZN4PLMD10vesselbase15StoreDataVessel6resizeEv1663
_ZN4PLMD10vesselbase15StoreDataVessel6finishERKSt6vectorIdSaIdEE2542
_ZNK4PLMD10vesselbase15StoreDataVessel16storeDerivativesERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE5321
_ZN4PLMD10vesselbase15StoreDataVessel20getTemporyMultiValueERKj56449
_ZNK4PLMD10vesselbase15StoreDataVessel11storeValuesERKjRNS_10MultiValueERSt6vectorIdSaIdEE148022
_ZNK4PLMD10vesselbase15StoreDataVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE148022
_ZN4PLMD10vesselbase15StoreDataVessel19retrieveDerivativesERKjRKbRNS_10MultiValueE159369
_ZNK4PLMD10vesselbase15StoreDataVessel23retrieveWeightWithIndexERKj330385
_ZNK4PLMD10vesselbase15StoreDataVessel22retrieveValueWithIndexERKjRKbRSt6vectorIdSaIdEE1149404
_ZNK4PLMD10vesselbase15StoreDataVessel23retrieveSequentialValueERKjRKbRSt6vectorIdSaIdEE1611191
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.cpp.func.html b/coverage/vesselbase/StoreDataVessel.cpp.func.html new file mode 100644 index 000000000000..1c1d28eca385 --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.cpp.func.html @@ -0,0 +1,133 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/StoreDataVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - StoreDataVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:869293.5 %
Date:2024-02-22 21:58:45Functions:1515100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15StoreDataVessel16registerKeywordsERNS_8KeywordsE26
_ZN4PLMD10vesselbase15StoreDataVessel17addActionThatUsesEPNS0_16ActionWithVesselE127
_ZN4PLMD10vesselbase15StoreDataVessel19retrieveDerivativesERKjRKbRNS_10MultiValueE159369
_ZN4PLMD10vesselbase15StoreDataVessel20getTemporyMultiValueERKj56449
_ZN4PLMD10vesselbase15StoreDataVessel24resizeTemporyMultiValuesERKj143
_ZN4PLMD10vesselbase15StoreDataVessel27setActiveValsAndDerivativesERKSt6vectorIjSaIjEE690
_ZN4PLMD10vesselbase15StoreDataVessel6finishERKSt6vectorIdSaIdEE2542
_ZN4PLMD10vesselbase15StoreDataVessel6resizeEv1663
_ZN4PLMD10vesselbase15StoreDataVesselC2ERKNS0_13VesselOptionsE131
_ZNK4PLMD10vesselbase15StoreDataVessel11storeValuesERKjRNS_10MultiValueERSt6vectorIdSaIdEE148022
_ZNK4PLMD10vesselbase15StoreDataVessel16storeDerivativesERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE5321
_ZNK4PLMD10vesselbase15StoreDataVessel22retrieveValueWithIndexERKjRKbRSt6vectorIdSaIdEE1149404
_ZNK4PLMD10vesselbase15StoreDataVessel23retrieveSequentialValueERKjRKbRSt6vectorIdSaIdEE1611191
_ZNK4PLMD10vesselbase15StoreDataVessel23retrieveWeightWithIndexERKj330385
_ZNK4PLMD10vesselbase15StoreDataVessel9calculateERKjRNS_10MultiValueERSt6vectorIdSaIdEERS6_IjSaIjEE148022
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.cpp.gcov.html b/coverage/vesselbase/StoreDataVessel.cpp.gcov.html new file mode 100644 index 000000000000..7fc37a6713eb --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.cpp.gcov.html @@ -0,0 +1,256 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/StoreDataVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - StoreDataVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:869293.5 %
Date:2024-02-22 21:58:45Functions:1515100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "StoreDataVessel.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace vesselbase {
+      26             : 
+      27          26 : void StoreDataVessel::registerKeywords( Keywords& keys ) {
+      28          26 :   Vessel::registerKeywords(keys); keys.remove("LABEL");
+      29          26 : }
+      30             : 
+      31         131 : StoreDataVessel::StoreDataVessel( const VesselOptions& da ):
+      32             :   Vessel(da),
+      33         131 :   max_lowmem_stash(3),
+      34         131 :   vecsize(0),
+      35         131 :   nspace(0)
+      36             : {
+      37         131 :   ActionWithValue* myval=dynamic_cast<ActionWithValue*>( getAction() );
+      38         131 :   if( !myval ) hasderiv=false;
+      39         131 :   else hasderiv=!myval->doNotCalculateDerivatives();
+      40         131 : }
+      41             : 
+      42         127 : void StoreDataVessel::addActionThatUses( ActionWithVessel* actionThatUses ) {
+      43         127 :   userActions.push_back( actionThatUses );
+      44         127 : }
+      45             : 
+      46        1663 : void StoreDataVessel::resize() {
+      47        1663 :   if( getAction()->lowmem || !getAction()->derivativesAreRequired() ) {
+      48        1086 :     nspace = 1;
+      49        1086 :     active_der.resize( max_lowmem_stash * ( 1 + getAction()->getNumberOfDerivatives() ) );
+      50             :   } else {
+      51         577 :     if( getAction()->getNumberOfDerivatives()>getAction()->maxderivatives ) {
+      52           0 :       error("not enough memory to store derivatives for action " + getAction()->getLabel() + " use LOWMEM option");
+      53             :     }
+      54         577 :     nspace = 1 + getAction()->maxderivatives;
+      55         577 :     active_der.resize( getNumberOfStoredValues() * ( 1 + getAction()->maxderivatives ) );
+      56             :   }
+      57        1663 :   vecsize=getAction()->getNumberOfQuantities();
+      58             :   plumed_dbg_assert( vecsize>0 );
+      59        1663 :   resizeBuffer( getNumberOfStoredValues()*vecsize*nspace );
+      60        1663 :   local_buffer.resize( getNumberOfStoredValues()*vecsize*nspace );
+      61        1663 : }
+      62             : 
+      63      148022 : void StoreDataVessel::storeValues( const unsigned& myelem, MultiValue& myvals, std::vector<double>& buffer ) const {
+      64             :   plumed_dbg_assert( vecsize>0 );
+      65      148022 :   unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem ); plumed_dbg_assert( jelem<getNumberOfStoredValues() );
+      66      148022 :   unsigned ibuf = bufstart + jelem * vecsize * nspace;
+      67      898572 :   for(unsigned icomp=0; icomp<vecsize; ++icomp) {
+      68      750550 :     buffer[ibuf] += myvals.get(icomp); ibuf+=nspace;
+      69             :   }
+      70      148022 : }
+      71             : 
+      72        5321 : void StoreDataVessel::storeDerivatives( const unsigned& myelem, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+      73             :   plumed_dbg_assert( vecsize>0 && getAction()->derivativesAreRequired() && myelem<getAction()->getFullNumberOfTasks() );
+      74        5321 :   unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem );
+      75             : 
+      76        5321 :   if( getAction()->getFullNumberOfTasks()==getNumberOfStoredValues() ) {
+      77        5321 :     der_list[jelem]=myvals.getNumberActive();
+      78        5321 :     unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
+      79      193658 :     for(unsigned j=0; j<myvals.getNumberActive(); ++j) { der_list[kder] = myvals.getActiveIndex(j); kder++; }
+      80             :   } else {
+      81             :     // This ensures that active indices are gathered correctly if
+      82             :     // we have multiple tasks contributing to a stored quantity
+      83           0 :     unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
+      84           0 :     for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
+      85             :       bool found=false; unsigned jder = myvals.getActiveIndex(j);
+      86           0 :       for(unsigned k=0; k<der_list[jelem]; ++k) {
+      87           0 :         if( der_list[kder+k]==jder ) { found=true; break; }
+      88             :       }
+      89           0 :       if(!found) { der_list[kder+der_list[jelem]]=jder; der_list[jelem]++; }
+      90             :     }
+      91             :   }
+      92             : 
+      93             :   // Store the values of the components and the derivatives
+      94       16071 :   for(unsigned icomp=0; icomp<vecsize; ++icomp) {
+      95       10750 :     unsigned ibuf = bufstart + jelem * ( vecsize*nspace ) + icomp*nspace + 1;
+      96      391636 :     for(unsigned j=0; j<myvals.getNumberActive(); ++j) {
+      97             :       unsigned jder=myvals.getActiveIndex(j);
+      98      380886 :       buffer[ibuf] += myvals.getDerivative( icomp, jder ); ibuf++;
+      99             :     }
+     100             :   }
+     101        5321 : }
+     102             : 
+     103     1611191 : void StoreDataVessel::retrieveSequentialValue( const unsigned& jelem, const bool& normed, std::vector<double>& values ) const {
+     104             :   plumed_dbg_assert( values.size()==vecsize );
+     105     1611191 :   unsigned ibuf = jelem * vecsize * nspace;
+     106    11257662 :   for(unsigned i=0; i<vecsize; ++i) { values[i]=local_buffer[ibuf]; ibuf+=nspace; }
+     107     1611191 :   if( normed && values.size()>2 ) getAction()->normalizeVector( values );
+     108     1611191 : }
+     109             : 
+     110     1149404 : void StoreDataVessel::retrieveValueWithIndex( const unsigned& myelem, const bool& normed, std::vector<double>& values ) const {
+     111             :   plumed_dbg_assert( values.size()==vecsize );
+     112     1149404 :   unsigned jelem = getStoreIndex( myelem );
+     113     1149404 :   retrieveSequentialValue( jelem, normed, values );
+     114     1149404 : }
+     115             : 
+     116      330385 : double StoreDataVessel::retrieveWeightWithIndex( const unsigned& myelem ) const {
+     117             :   plumed_dbg_assert( vecsize>0 );
+     118      330385 :   unsigned jelem = getStoreIndex( myelem ); unsigned ibuf = jelem * vecsize * nspace; return local_buffer[ibuf];
+     119             : }
+     120             : 
+     121      159369 : void StoreDataVessel::retrieveDerivatives( const unsigned& myelem, const bool& normed, MultiValue& myvals ) {
+     122             :   plumed_dbg_assert( myvals.getNumberOfValues()==vecsize && myvals.getNumberOfDerivatives()==getAction()->getNumberOfDerivatives() );
+     123             : 
+     124      159369 :   myvals.clearAll();
+     125      159369 :   if( getAction()->lowmem ) {
+     126      103064 :     recalculateStoredQuantity( myelem, myvals );
+     127      103064 :     if( normed ) getAction()->normalizeVectorDerivatives( myvals );
+     128             :   } else {
+     129       56305 :     unsigned jelem = getAction()->getPositionInCurrentTaskList( myelem );
+     130             :     // Retrieve the derivatives for elements 0 and 1 - weight and norm
+     131      169383 :     for(unsigned icomp=0; icomp<vecsize; ++icomp) {
+     132      113078 :       unsigned ibuf = jelem * ( vecsize*nspace ) + icomp*nspace + 1;
+     133      113078 :       unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
+     134      580640 :       for(unsigned j=0; j<active_der[jelem]; ++j) {
+     135      467562 :         myvals.addDerivative( icomp, active_der[kder], local_buffer[ibuf] );
+     136      467562 :         kder++; ibuf++;
+     137             :       }
+     138             :     }
+     139       56305 :     if( normed ) getAction()->normalizeVectorDerivatives( myvals );
+     140             :     // Now ensure appropriate parts of list are activated
+     141             :     myvals.emptyActiveMembers();
+     142       56305 :     unsigned kder = getNumberOfStoredValues() + jelem * ( nspace - 1 );
+     143      280933 :     for(unsigned j=0; j<active_der[jelem]; ++j) { myvals.putIndexInActiveArray( active_der[kder] ); kder++; }
+     144             :     myvals.sortActiveList();
+     145             :   }
+     146      159369 : }
+     147             : 
+     148      148022 : void StoreDataVessel::calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const {
+     149             : 
+     150      148022 :   if( myvals.get(0)>epsilon ) {
+     151      148022 :     storeValues( current, myvals, buffer );
+     152      148022 :     if( !(getAction()->lowmem) && getAction()->derivativesAreRequired() ) storeDerivatives( current, myvals, buffer, der_list );
+     153             :   }
+     154             : 
+     155      148022 :   return;
+     156             : }
+     157             : 
+     158        2542 : void StoreDataVessel::finish( const std::vector<double>& buffer ) {
+     159             :   // Store the buffer locally
+     160     2186582 :   for(unsigned i=0; i<local_buffer.size(); ++i) local_buffer[i]=buffer[bufstart+i];
+     161        2542 : }
+     162             : 
+     163             : 
+     164         690 : void StoreDataVessel::setActiveValsAndDerivatives( const std::vector<unsigned>& der_index ) {
+     165         690 :   if( !getAction()->lowmem && getAction()->derivativesAreRequired() ) {
+     166      228266 :     for(unsigned i=0; i<der_index.size(); ++i) active_der[i]=der_index[i];
+     167             :   }
+     168         690 : }
+     169             : 
+     170         143 : void StoreDataVessel::resizeTemporyMultiValues( const unsigned& nvals ) {
+     171         416 :   for(unsigned i=0; i<nvals; ++i) my_tmp_vals.push_back( MultiValue(0,0) );
+     172         143 : }
+     173             : 
+     174       56449 : MultiValue& StoreDataVessel::getTemporyMultiValue( const unsigned& ind ) {
+     175       56449 :   plumed_dbg_assert( ind<my_tmp_vals.size() ); return my_tmp_vals[ind];
+     176             : }
+     177             : 
+     178             : }
+     179             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.h.func-sort-c.html b/coverage/vesselbase/StoreDataVessel.h.func-sort-c.html new file mode 100644 index 000000000000..58423b1bea82 --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.h.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/StoreDataVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - StoreDataVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242692.3 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15StoreDataVessel15activateIndicesEPNS0_16ActionWithVesselE0
_ZN4PLMD10vesselbase15StoreDataVessel11descriptionB5cxx11Ev128
_ZN4PLMD10vesselbase15StoreDataVessel10applyForceERSt6vectorIdSaIdEE958
_ZNK4PLMD10vesselbase15StoreDataVessel19storedValueIsActiveERKj65536
_ZN4PLMD10vesselbase15StoreDataVessel25recalculateStoredQuantityERKjRNS_10MultiValueE103064
_ZNK4PLMD10vesselbase15StoreDataVessel23getNumberOfStoredValuesEv632237
_ZNK4PLMD10vesselbase15StoreDataVessel13getStoreIndexERKj1558477
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.h.func.html b/coverage/vesselbase/StoreDataVessel.h.func.html new file mode 100644 index 000000000000..f4c58aec9c37 --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.h.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/StoreDataVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - StoreDataVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242692.3 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase15StoreDataVessel10applyForceERSt6vectorIdSaIdEE958
_ZN4PLMD10vesselbase15StoreDataVessel11descriptionB5cxx11Ev128
_ZN4PLMD10vesselbase15StoreDataVessel15activateIndicesEPNS0_16ActionWithVesselE0
_ZN4PLMD10vesselbase15StoreDataVessel25recalculateStoredQuantityERKjRNS_10MultiValueE103064
_ZNK4PLMD10vesselbase15StoreDataVessel13getStoreIndexERKj1558477
_ZNK4PLMD10vesselbase15StoreDataVessel19storedValueIsActiveERKj65536
_ZNK4PLMD10vesselbase15StoreDataVessel23getNumberOfStoredValuesEv632237
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/StoreDataVessel.h.gcov.html b/coverage/vesselbase/StoreDataVessel.h.gcov.html new file mode 100644 index 000000000000..bd90ef6bc7c6 --- /dev/null +++ b/coverage/vesselbase/StoreDataVessel.h.gcov.html @@ -0,0 +1,287 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/StoreDataVessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - StoreDataVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:242692.3 %
Date:2024-02-22 21:58:45Functions:6785.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_vesselbase_StoreDataVessel_h
+      23             : #define __PLUMED_vesselbase_StoreDataVessel_h
+      24             : 
+      25             : #include <string>
+      26             : #include <cstring>
+      27             : #include <vector>
+      28             : #include <cstddef>
+      29             : #include "Vessel.h"
+      30             : 
+      31             : namespace PLMD {
+      32             : namespace vesselbase {
+      33             : 
+      34             : /**
+      35             : \ingroup TOOLBOX
+      36             : Objects that inherit from FunctionVessel can be used (in tandem with PLMD::vesselbase::ActionWithVessel)
+      37             : to store values and derivatives for a set of scalars or vectors that are calculated by a
+      38             : PLMD::vesselbase::ActionWithVessel.  Functions of these stored quantities can then be calculated in a
+      39             : second step.
+      40             : */
+      41             : 
+      42             : class StoreDataVessel : public Vessel {
+      43             :   friend class Moments;
+      44             : private:
+      45             : /// Do the quantities being stored in here need derivatives
+      46             :   bool hasderiv;
+      47             : /// What is the maximum number of vectors we are going to
+      48             : /// have to store when using lowmem option
+      49             :   unsigned max_lowmem_stash;
+      50             : /// The size of the vector we are computing
+      51             :   std::size_t vecsize;
+      52             : /// The amount of data per vector element
+      53             :   std::size_t nspace;
+      54             : /// The currently active values
+      55             : //  std::vector<unsigned> active_val;
+      56             : /// The active derivative elements
+      57             :   std::vector<unsigned> active_der;
+      58             : /// The buffer
+      59             :   std::vector<double> local_buffer;
+      60             : /// The actions that are going to use the stored data
+      61             :   std::vector<ActionWithVessel*> userActions;
+      62             : /// We create a vector of tempory MultiValues here so as to avoid
+      63             : /// lots of vector resizing
+      64             :   unsigned tmp_index;
+      65             :   std::vector<MultiValue> my_tmp_vals;
+      66             : protected:
+      67             : /// Is the weight differentiable
+      68             :   bool weightHasDerivatives();
+      69             : /// Are we using low mem option
+      70             :   bool usingLowMem();
+      71             : /// Finish the setup of the storage object by setting how much
+      72             : /// data has to be stored
+      73             :   void completeSetup( const unsigned&, const unsigned& );
+      74             : /// Return value of nspace
+      75             :   unsigned getNumberOfDerivativeSpacesPerComponent() const ;
+      76             : /// Retrieve the values from the underlying ActionWithVessel
+      77             :   void storeValues( const unsigned&, MultiValue&, std::vector<double>& ) const ;
+      78             : /// This stores the data we get from the calculation
+      79             :   void storeDerivatives( const unsigned&, MultiValue& myvals, std::vector<double>&, std::vector<unsigned>& ) const ;
+      80             : /// Get the ibuf'th local derivative value
+      81             :   double getLocalDerivative( const unsigned& ibuf );
+      82             : /// Set the ibuf'th local derivative value
+      83             :   void setLocalDerivative( const unsigned& ibuf, const double& val );
+      84             : public:
+      85             :   static void registerKeywords( Keywords& keys );
+      86             :   explicit StoreDataVessel( const VesselOptions& );
+      87             : /// Get the number of values that have been stored
+      88             :   virtual unsigned getNumberOfStoredValues() const ;
+      89             : /// Get the index to store a particular index inside
+      90             :   unsigned getStoreIndex( const unsigned& ) const ;
+      91             : /// Get the true index of a quantity from the index it is stored in
+      92             :   unsigned getTrueIndex( const unsigned& ) const ;
+      93             : /// Recalculate one of the base quantities
+      94             :   void recalculateStoredQuantity( const unsigned& myelm, MultiValue& myvals );
+      95             : /// Set a hard cutoff on the weight of an element
+      96             :   void setHardCutoffOnWeight( const double& mytol );
+      97             : /// Add an action that uses this data
+      98             :   void addActionThatUses( ActionWithVessel* actionThatUses );
+      99             : /// Return the number of components in the vector
+     100        2094 :   unsigned getNumberOfComponents() const { return vecsize; }
+     101             : /// Get the values of all the components in the vector
+     102             :   void retrieveSequentialValue( const unsigned& myelem, const bool& normed, std::vector<double>& values ) const ;
+     103             :   void retrieveValueWithIndex( const unsigned& myelem, const bool& normed, std::vector<double>& values ) const ;
+     104             :   double retrieveWeightWithIndex( const unsigned& myelem ) const ;
+     105             : /// Get the derivatives for one of the components in the vector
+     106             :   void retrieveDerivatives( const unsigned& myelem, const bool& normed, MultiValue& myvals );
+     107             : /// Do all resizing of data
+     108             :   void resize() override;
+     109             : ///
+     110         128 :   std::string description() override { return ""; }
+     111             : /// Get the number of derivatives for the ith value
+     112             :   unsigned getNumberOfDerivatives( const unsigned& );
+     113             : /// Get the size of the derivative list
+     114             :   unsigned getSizeOfDerivativeList() const ;
+     115             : /// This stores the data when not using lowmem
+     116             :   void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_index ) const override;
+     117             : /// Final step in gathering data
+     118             :   void finish( const std::vector<double>& buffer ) override;
+     119             : /// Is a particular stored value active at the present time
+     120             :   bool storedValueIsActive( const unsigned& iatom ) const ;
+     121             : /// Set the active values
+     122             :   void setActiveValsAndDerivatives( const std::vector<unsigned>& der_index );
+     123             : /// Activate indexes (this is used at end of chain rule)
+     124           0 :   virtual void activateIndices( ActionWithVessel* ) {}
+     125             : /// Forces on vectors should always be applied elsewhere
+     126         958 :   bool applyForce(std::vector<double>&) override { return false; }
+     127             : ///  Get the number of data users
+     128             :   unsigned getNumberOfDataUsers() const ;
+     129             : /// Get one of the ith data user
+     130             :   ActionWithVessel* getDataUser( const unsigned& );
+     131             : /// Set the number of tempory multivalues we need
+     132             :   void resizeTemporyMultiValues( const unsigned& nvals );
+     133             : /// Return a tempory multi value - we do this so as to avoid vector resizing
+     134             :   MultiValue& getTemporyMultiValue( const unsigned& ind );
+     135             : };
+     136             : 
+     137             : inline
+     138             : bool StoreDataVessel::weightHasDerivatives() {
+     139             :   return getAction()->weightHasDerivatives;
+     140             : }
+     141             : 
+     142             : inline
+     143             : bool StoreDataVessel::usingLowMem() {
+     144             :   return getAction()->lowmem;
+     145             : }
+     146             : 
+     147             : inline
+     148             : unsigned StoreDataVessel::getNumberOfDerivativeSpacesPerComponent() const {
+     149             :   return nspace;
+     150             : }
+     151             : 
+     152             : inline
+     153       65536 : bool StoreDataVessel::storedValueIsActive( const unsigned& iatom ) const {
+     154       65536 :   if( !getAction()->taskIsCurrentlyActive( iatom ) ) return false;
+     155       53771 :   unsigned jatom = getStoreIndex( iatom );
+     156             :   plumed_dbg_assert( jatom<getNumberOfStoredValues() );
+     157       53771 :   return local_buffer[jatom*vecsize*nspace]>epsilon;
+     158             : }
+     159             : 
+     160             : inline
+     161             : unsigned StoreDataVessel::getSizeOfDerivativeList() const {
+     162             :   return active_der.size();
+     163             : }
+     164             : 
+     165             : inline
+     166      632237 : unsigned StoreDataVessel::getNumberOfStoredValues() const {
+     167      632237 :   return getAction()->nactive_tasks;
+     168             : }
+     169             : 
+     170             : inline
+     171     1558477 : unsigned StoreDataVessel::getStoreIndex( const unsigned& ind ) const {
+     172     1558477 :   if( getAction()->nactive_tasks==getAction()->getFullNumberOfTasks() ) return ind;
+     173             : 
+     174             :   // Binary search for required element - faster scaling than sequential search
+     175       64159 :   unsigned l=0, r=getAction()->nactive_tasks-1;
+     176      696300 :   for(unsigned i=0; i<getAction()->nactive_tasks; ++i) {
+     177      696300 :     plumed_assert( l<=r );
+     178      696300 :     unsigned m = std::floor( (l + r)/2 );
+     179      696300 :     if( ind==getAction()->indexOfTaskInFullList[m] ) return m;
+     180      632141 :     else if( getAction()->indexOfTaskInFullList[m]<ind ) l=m+1;
+     181      302100 :     else if( getAction()->indexOfTaskInFullList[m]>ind ) r=m-1;
+     182             :   }
+     183           0 :   plumed_merror("requested task is not active");
+     184             : }
+     185             : 
+     186             : inline
+     187             : unsigned StoreDataVessel::getTrueIndex( const unsigned& ind ) const {
+     188         300 :   return getAction()->indexOfTaskInFullList[ind];
+     189             : }
+     190             : 
+     191             : inline
+     192      103064 : void StoreDataVessel::recalculateStoredQuantity( const unsigned& myelem, MultiValue& myvals ) {
+     193      103064 :   getAction()->performTask( myelem, getAction()->getTaskCode(myelem), myvals );
+     194      103064 : }
+     195             : 
+     196             : inline
+     197             : unsigned StoreDataVessel::getNumberOfDataUsers() const {
+     198         225 :   return userActions.size();
+     199             : }
+     200             : 
+     201             : inline
+     202             : ActionWithVessel* StoreDataVessel::getDataUser( const unsigned& idata ) {
+     203          49 :   plumed_dbg_assert( idata<userActions.size() ); return userActions[idata];
+     204             : }
+     205             : 
+     206             : }
+     207             : }
+     208             : #endif
+     209             : 
+     210             : 
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Sum.cpp.func-sort-c.html b/coverage/vesselbase/Sum.cpp.func-sort-c.html new file mode 100644 index 000000000000..e15576be3d1c --- /dev/null +++ b/coverage/vesselbase/Sum.cpp.func-sort-c.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Sum.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Sum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMe6createERKNS0_13VesselOptionsE57
_ZN4PLMD10vesselbase3Sum16registerKeywordsERNS_8KeywordsE57
_ZN4PLMD10vesselbase3Sum16value_descriptorB5cxx11Ev57
_ZN4PLMD10vesselbase3SumC2ERKNS0_13VesselOptionsE57
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMeD2Ev4187
_ZN4PLMD10vesselbase3Sum14reserveKeywordERNS_8KeywordsE4187
_ZNK4PLMD10vesselbase3Sum13calcTransformERKdRd60444
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Sum.cpp.func.html b/coverage/vesselbase/Sum.cpp.func.html new file mode 100644 index 000000000000..d7656a8ef6df --- /dev/null +++ b/coverage/vesselbase/Sum.cpp.func.html @@ -0,0 +1,105 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Sum.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Sum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMe6createERKNS0_13VesselOptionsE57
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMeC2Ev4187
_ZN4PLMD10vesselbase12_GLOBAL__N_113SumRegisterMeD2Ev4187
_ZN4PLMD10vesselbase3Sum14reserveKeywordERNS_8KeywordsE4187
_ZN4PLMD10vesselbase3Sum16registerKeywordsERNS_8KeywordsE57
_ZN4PLMD10vesselbase3Sum16value_descriptorB5cxx11Ev57
_ZN4PLMD10vesselbase3SumC2ERKNS0_13VesselOptionsE57
_ZNK4PLMD10vesselbase3Sum13calcTransformERKdRd60444
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Sum.cpp.gcov.html b/coverage/vesselbase/Sum.cpp.gcov.html new file mode 100644 index 000000000000..44b4074cc3da --- /dev/null +++ b/coverage/vesselbase/Sum.cpp.gcov.html @@ -0,0 +1,139 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Sum.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Sum.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:1515100.0 %
Date:2024-02-22 21:58:45Functions:88100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2013-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "FunctionVessel.h"
+      23             : #include "VesselRegister.h"
+      24             : 
+      25             : namespace PLMD {
+      26             : namespace vesselbase {
+      27             : 
+      28             : class Sum : public FunctionVessel {
+      29             : public:
+      30             :   static void registerKeywords( Keywords& keys );
+      31             :   static void reserveKeyword( Keywords& keys );
+      32             :   explicit Sum( const VesselOptions& da );
+      33             :   std::string value_descriptor() override;
+      34             :   double calcTransform( const double& val, double& dv ) const override;
+      35             : };
+      36             : 
+      37       12618 : PLUMED_REGISTER_VESSEL(Sum,"SUM")
+      38             : 
+      39          57 : void Sum::registerKeywords( Keywords& keys ) {
+      40          57 :   FunctionVessel::registerKeywords( keys );
+      41          57 : }
+      42             : 
+      43        4187 : void Sum::reserveKeyword( Keywords& keys ) {
+      44        8374 :   keys.reserve("vessel","SUM","calculate the sum of all the quantities.");
+      45        8374 :   keys.addOutputComponent("sum","SUM","the sum of values");
+      46        4187 : }
+      47             : 
+      48          57 : Sum::Sum( const VesselOptions& da ) :
+      49          57 :   FunctionVessel(da)
+      50             : {
+      51          57 : }
+      52             : 
+      53          57 : std::string Sum::value_descriptor() {
+      54          57 :   return "the sum of all the values";
+      55             : }
+      56             : 
+      57       60444 : double Sum::calcTransform( const double& val, double& dv ) const {
+      58       60444 :   dv=1.0; return val;
+      59             : }
+      60             : 
+      61             : }
+      62             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.cpp.func-sort-c.html b/coverage/vesselbase/ValueVessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..41baea980c91 --- /dev/null +++ b/coverage/vesselbase/ValueVessel.cpp.func-sort-c.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ValueVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ValueVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase11ValueVessel11descriptionB5cxx11Ev341
_ZN4PLMD10vesselbase11ValueVessel16registerKeywordsERNS_8KeywordsE341
_ZN4PLMD10vesselbase11ValueVesselC2ERKNS0_13VesselOptionsE341
_ZN4PLMD10vesselbase11ValueVessel10applyForceERSt6vectorIdSaIdEE11449
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.cpp.func.html b/coverage/vesselbase/ValueVessel.cpp.func.html new file mode 100644 index 000000000000..ab072eb3ac3c --- /dev/null +++ b/coverage/vesselbase/ValueVessel.cpp.func.html @@ -0,0 +1,89 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ValueVessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ValueVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase11ValueVessel10applyForceERSt6vectorIdSaIdEE11449
_ZN4PLMD10vesselbase11ValueVessel11descriptionB5cxx11Ev341
_ZN4PLMD10vesselbase11ValueVessel16registerKeywordsERNS_8KeywordsE341
_ZN4PLMD10vesselbase11ValueVesselC2ERKNS0_13VesselOptionsE341
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.cpp.gcov.html b/coverage/vesselbase/ValueVessel.cpp.gcov.html new file mode 100644 index 000000000000..3102403b6026 --- /dev/null +++ b/coverage/vesselbase/ValueVessel.cpp.gcov.html @@ -0,0 +1,149 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ValueVessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ValueVessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:3232100.0 %
Date:2024-02-22 21:58:45Functions:44100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "ValueVessel.h"
+      23             : 
+      24             : namespace PLMD {
+      25             : namespace vesselbase {
+      26             : 
+      27         341 : void ValueVessel::registerKeywords( Keywords& keys ) {
+      28         341 :   Vessel::registerKeywords( keys );
+      29         682 :   keys.add("compulsory","COMPONENT","1","the component of the vector for which to calculate this quantity");
+      30         341 : }
+      31             : 
+      32         341 : ValueVessel::ValueVessel( const VesselOptions& da ):
+      33         341 :   Vessel(da)
+      34             : {
+      35         682 :   parse("COMPONENT",mycomp);
+      36         341 :   ActionWithValue* a=dynamic_cast<ActionWithValue*>( getAction() );
+      37         341 :   plumed_massert(a,"cannot create passable values as base action does not inherit from ActionWithValue");
+      38             :   int numval = getNumericalLabel();
+      39         341 :   if( numval<0 && a->getNumberOfComponents()==0 ) {  // This allows us to make multicolvars pretend to be colvars - this is used in AlphaRMSD etc
+      40          36 :     a->addValueWithDerivatives();
+      41          36 :     a->setNotPeriodic();
+      42          36 :     final_value=a->copyOutput( a->getNumberOfComponents()-1 );
+      43         305 :   } else if( numval<0 ) {
+      44           2 :     final_value_ptr=Tools::make_unique<Value>();
+      45           2 :     final_value=final_value_ptr.get();
+      46           2 :     final_value->setNotPeriodic();
+      47             :   } else {
+      48         606 :     plumed_massert( !a->exists(getAction()->getLabel() + "." + getLabel() ), "you can't create the name multiple times");
+      49         606 :     a->addComponentWithDerivatives( getLabel() );
+      50         606 :     a->componentIsNotPeriodic( getLabel() );
+      51         303 :     final_value=a->copyOutput( a->getNumberOfComponents()-1 );
+      52             :   }
+      53         341 : }
+      54             : 
+      55         341 : std::string ValueVessel::description() {
+      56         377 :   if( final_value->getName()==getAction()->getLabel() ) return "value " + getAction()->getLabel() + " contains " + value_descriptor();
+      57         305 :   std::string compstr; Tools::convert(mycomp,compstr);
+      58         610 :   return "value " + getAction()->getLabel() + "." + getLabel() + " is obtained by taking the " + compstr + "th component and finding " + value_descriptor();
+      59             : }
+      60             : 
+      61       11449 : bool ValueVessel::applyForce( std::vector<double>& forces ) {
+      62       11449 :   std::vector<double> tmpforce( forces.size() );
+      63       11449 :   forces.assign(forces.size(),0.0); bool wasforced=false;
+      64       11449 :   if( final_value->applyForce( tmpforce ) ) {
+      65             :     wasforced=true;
+      66      524340 :     for(unsigned j=0; j<forces.size(); ++j) forces[j]+=tmpforce[j];
+      67             :   }
+      68       11449 :   return wasforced;
+      69             : }
+      70             : 
+      71             : }
+      72             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.h.func-sort-c.html b/coverage/vesselbase/ValueVessel.h.func-sort-c.html new file mode 100644 index 000000000000..f89f0d02410a --- /dev/null +++ b/coverage/vesselbase/ValueVessel.h.func-sort-c.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ValueVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ValueVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase11ValueVessel14setOutputValueERKd2079
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.h.func.html b/coverage/vesselbase/ValueVessel.h.func.html new file mode 100644 index 000000000000..8f38c044d168 --- /dev/null +++ b/coverage/vesselbase/ValueVessel.h.func.html @@ -0,0 +1,77 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ValueVessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ValueVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ +
+ + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase11ValueVessel14setOutputValueERKd2079
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/ValueVessel.h.gcov.html b/coverage/vesselbase/ValueVessel.h.gcov.html new file mode 100644 index 000000000000..22cd6edee661 --- /dev/null +++ b/coverage/vesselbase/ValueVessel.h.gcov.html @@ -0,0 +1,151 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/ValueVessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - ValueVessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:55100.0 %
Date:2024-02-22 21:58:45Functions:11100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2015-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_vesselbase_ValueVessel_h
+      23             : #define __PLUMED_vesselbase_ValueVessel_h
+      24             : 
+      25             : #include <string>
+      26             : #include <cstring>
+      27             : #include <vector>
+      28             : #include <memory>
+      29             : 
+      30             : #include "Vessel.h"
+      31             : #include "core/Value.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : namespace vesselbase {
+      35             : 
+      36             : class ValueVessel : public Vessel {
+      37             : private:
+      38             : // unique pointer with the same scope as final_value
+      39             :   std::unique_ptr<Value> final_value_ptr;
+      40             : // this pointer either points to a non-owned Value or to final_value_ptr
+      41             :   Value* final_value;
+      42             : protected:
+      43             : /// The component that is being averaged/accumulated whatever
+      44             :   unsigned mycomp;
+      45             : /// Set the final value
+      46             :   void setOutputValue( const double& val );
+      47             : public:
+      48             :   static void registerKeywords( Keywords& keys );
+      49             :   explicit ValueVessel( const VesselOptions& da );
+      50             :   std::string description() override;
+      51             :   virtual std::string value_descriptor()=0;
+      52             :   bool applyForce( std::vector<double>& forces ) override;
+      53             :   double getOutputValue() const ;
+      54             :   Value* getFinalValue() const ;
+      55             : };
+      56             : 
+      57             : inline
+      58             : Value* ValueVessel::getFinalValue() const {
+      59     2406525 :   return final_value;
+      60             : }
+      61             : 
+      62             : inline
+      63             : double ValueVessel::getOutputValue() const {
+      64        3389 :   return final_value->get();
+      65             : }
+      66             : 
+      67             : inline
+      68        2079 : void ValueVessel::setOutputValue( const double& val ) {
+      69        2079 :   final_value->set( val );
+      70        2079 : }
+      71             : 
+      72             : }
+      73             : }
+      74             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.cpp.func-sort-c.html b/coverage/vesselbase/Vessel.cpp.func-sort-c.html new file mode 100644 index 000000000000..00c9cf44b4e4 --- /dev/null +++ b/coverage/vesselbase/Vessel.cpp.func-sort-c.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Vessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Vessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:647882.1 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase6Vessel5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZNK4PLMD10vesselbase6Vessel7getNameB5cxx11Ev89
_ZN4PLMD10vesselbase6Vessel9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb122
_ZN4PLMD10vesselbase6Vessel11getAllInputB5cxx11Ev175
_ZN4PLMD10vesselbase13VesselOptionsC2ERKS1_RKNS_8KeywordsE455
_ZN4PLMD10vesselbase6Vessel16registerKeywordsERNS_8KeywordsE455
_ZN4PLMD10vesselbase6Vessel9checkReadEv548
_ZN4PLMD10vesselbase13VesselOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKjS9_PNS0_16ActionWithVesselE606
_ZN4PLMD10vesselbase6VesselC2ERKNS0_13VesselOptionsE607
_ZN4PLMD10vesselbase6Vessel13transformNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE808
_ZNK4PLMD10vesselbase6Vessel8getLabelB5cxx11Ev28605
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.cpp.func.html b/coverage/vesselbase/Vessel.cpp.func.html new file mode 100644 index 000000000000..05ae897c231e --- /dev/null +++ b/coverage/vesselbase/Vessel.cpp.func.html @@ -0,0 +1,117 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Vessel.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Vessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:647882.1 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase13VesselOptionsC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEES9_RKjS9_PNS0_16ActionWithVesselE606
_ZN4PLMD10vesselbase13VesselOptionsC2ERKS1_RKNS_8KeywordsE455
_ZN4PLMD10vesselbase6Vessel11getAllInputB5cxx11Ev175
_ZN4PLMD10vesselbase6Vessel13transformNameERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE808
_ZN4PLMD10vesselbase6Vessel16registerKeywordsERNS_8KeywordsE455
_ZN4PLMD10vesselbase6Vessel5errorERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE0
_ZN4PLMD10vesselbase6Vessel9checkReadEv548
_ZN4PLMD10vesselbase6Vessel9parseFlagERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERb122
_ZN4PLMD10vesselbase6VesselC2ERKNS0_13VesselOptionsE607
_ZNK4PLMD10vesselbase6Vessel7getNameB5cxx11Ev89
_ZNK4PLMD10vesselbase6Vessel8getLabelB5cxx11Ev28605
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.cpp.gcov.html b/coverage/vesselbase/Vessel.cpp.gcov.html new file mode 100644 index 000000000000..de1be5ada4a6 --- /dev/null +++ b/coverage/vesselbase/Vessel.cpp.gcov.html @@ -0,0 +1,227 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Vessel.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Vessel.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:647882.1 %
Date:2024-02-22 21:58:45Functions:101190.9 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "Vessel.h"
+      23             : #include "ActionWithVessel.h"
+      24             : #include "tools/Exception.h"
+      25             : #include "tools/Communicator.h"
+      26             : #include "tools/Log.h"
+      27             : 
+      28             : namespace PLMD {
+      29             : namespace vesselbase {
+      30             : 
+      31             : Keywords VesselOptions::emptyKeys;
+      32             : 
+      33         606 : VesselOptions::VesselOptions(const std::string& thisname, const std::string& thislab, const unsigned& nlab, const std::string& params, ActionWithVessel* aa ):
+      34         606 :   myname(thisname),
+      35         606 :   mylabel(thislab),
+      36         606 :   numlab(nlab),
+      37         606 :   action(aa),
+      38         606 :   keywords(emptyKeys),
+      39         606 :   parameters(params)
+      40             : {
+      41         606 : }
+      42             : 
+      43         455 : VesselOptions::VesselOptions(const VesselOptions& da, const Keywords& keys ):
+      44         455 :   myname(da.myname),
+      45         455 :   mylabel(da.mylabel),
+      46         455 :   numlab(da.numlab),
+      47         455 :   action(da.action),
+      48         455 :   keywords(keys),
+      49         455 :   parameters(da.parameters)
+      50             : {
+      51         455 : }
+      52             : 
+      53         455 : void Vessel::registerKeywords( Keywords& keys ) {
+      54         455 :   plumed_assert( keys.size()==0 );
+      55         910 :   keys.add("optional","LABEL","the label used to reference this particular quantity");
+      56         455 : }
+      57             : 
+      58         808 : std::string Vessel::transformName( const std::string& name ) {
+      59         808 :   std::string tlabel=name;
+      60             :   // Convert to lower case
+      61        4695 :   std::transform( tlabel.begin(), tlabel.end(), tlabel.begin(), [](unsigned char c) { return std::tolower(c); } );
+      62             :   // Remove any underscore characters (as these are reserved)
+      63             :   for(unsigned i=0;; ++i) {
+      64         996 :     std::size_t num=tlabel.find_first_of("_");
+      65         996 :     if( num==std::string::npos ) break;
+      66         188 :     tlabel.erase( tlabel.begin() + num, tlabel.begin() + num + 1 );
+      67         188 :   }
+      68         808 :   return tlabel;
+      69             : }
+      70             : 
+      71         607 : Vessel::Vessel( const VesselOptions& da ):
+      72         607 :   myname(da.myname),
+      73         607 :   numlab(da.numlab),
+      74         607 :   action(da.action),
+      75         607 :   line(Tools::getWords( da.parameters )),
+      76         607 :   keywords(da.keywords),
+      77         607 :   finished_read(false)
+      78             : {
+      79         607 :   if( da.mylabel.length()>0) {
+      80           0 :     mylabel=da.mylabel;
+      81             :   } else {
+      82        1625 :     if( keywords.exists("LABEL") ) parse("LABEL",mylabel);
+      83         607 :     if( mylabel.length()==0 && numlab>=0 ) {
+      84         950 :       mylabel=transformName( myname ); std::string nn;
+      85         528 :       if(numlab>0) { Tools::convert( numlab, nn ); mylabel =  mylabel + "-" + nn; }
+      86             :     }
+      87             :   }
+      88         607 : }
+      89             : 
+      90          89 : std::string Vessel::getName() const {
+      91          89 :   return myname;
+      92             : }
+      93             : 
+      94       28605 : std::string Vessel::getLabel() const {
+      95       28605 :   return mylabel;
+      96             : }
+      97             : 
+      98         175 : std::string Vessel::getAllInput() {
+      99             :   std::string fullstring;
+     100         742 :   for(unsigned i=0; i<line.size(); ++i) {
+     101        1134 :     fullstring = fullstring + " " + line[i];
+     102             :   }
+     103         175 :   line.clear(); line.resize(0);
+     104         175 :   return fullstring;
+     105             : }
+     106             : 
+     107         122 : void Vessel::parseFlag(const std::string&key, bool & t) {
+     108             :   // Check keyword has been registered
+     109         122 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     110             :   // Check keyword is a flag
+     111         244 :   if(!keywords.style(key,"nohtml")) {
+     112         244 :     plumed_massert(keywords.style(key,"flag"), "keyword " + key + " is not a flag");
+     113             :   }
+     114             : 
+     115             :   // Read in the flag otherwise get the default value from the keywords object
+     116         122 :   if(!Tools::parseFlag(line,key,t)) {
+     117         198 :     if( keywords.style(key,"nohtml") ) {
+     118           0 :       t=false;
+     119          99 :     } else if ( !keywords.getLogicalDefault(key,t) ) {
+     120           0 :       plumed_merror("there is a flag with no logical default in a vessel - weird");
+     121             :     }
+     122             :   }
+     123         122 : }
+     124             : 
+     125         548 : void Vessel::checkRead() {
+     126         548 :   if(!line.empty()) {
+     127           0 :     std::string msg="cannot understand the following words from input : ";
+     128           0 :     for(unsigned i=0; i<line.size(); i++) {
+     129           0 :       if(i>0) msg = msg + ", ";
+     130           0 :       msg = msg + line[i];
+     131             :     }
+     132           0 :     error(msg);
+     133             :   }
+     134         548 :   finished_read=true;
+     135         548 :   std::string describe=description();
+     136         548 :   if( describe.length()>0 && action ) action->log.printf("  %s\n", describe.c_str() );
+     137         548 : }
+     138             : 
+     139           0 : [[noreturn]] void Vessel::error( const std::string& msg ) {
+     140           0 :   if( action ) {
+     141           0 :     action->log.printf("ERROR for keyword %s in action %s with label %s : %s \n \n",myname.c_str(), (action->getName()).c_str(), (action->getLabel()).c_str(), msg.c_str() );
+     142           0 :     if(finished_read) keywords.print( action->log );
+     143           0 :     plumed_merror("ERROR for keyword " + myname + " in action "  + action->getName() + " with label " + action->getLabel() + " : " + msg );
+     144             :   } else {
+     145           0 :     plumed_merror("ERROR: " + msg);
+     146             :   }
+     147             : }
+     148             : 
+     149             : }
+     150             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.h.func-sort-c.html b/coverage/vesselbase/Vessel.h.func-sort-c.html new file mode 100644 index 000000000000..a8ec6d03d8f0 --- /dev/null +++ b/coverage/vesselbase/Vessel.h.func-sort-c.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Vessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Vessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293680.6 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase6VesselD0Ev0
_ZN4PLMD10vesselbase6Vessel5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_10
_ZN4PLMD10vesselbase6Vessel11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EE36
_ZN4PLMD10vesselbase6Vessel11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RSt6vectorIT_SaISC_EE209
_ZN4PLMD10vesselbase6Vessel5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_349
_ZN4PLMD10vesselbase6Vessel5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RT_532
_ZN4PLMD10vesselbase6VesselD2Ev607
_ZN4PLMD10vesselbase6Vessel7prepareEv26788
_ZN4PLMD10vesselbase6Vessel14setBufferStartERj32944
_ZN4PLMD10vesselbase6Vessel20transformDerivativesERKjRNS_10MultiValueES5_509167
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.h.func.html b/coverage/vesselbase/Vessel.h.func.html new file mode 100644 index 000000000000..f3745c226ea5 --- /dev/null +++ b/coverage/vesselbase/Vessel.h.func.html @@ -0,0 +1,113 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Vessel.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Vessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293680.6 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase6Vessel11parseVectorINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RSt6vectorIT_SaISC_EE209
_ZN4PLMD10vesselbase6Vessel11parseVectorIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERSt6vectorIT_SaISC_EE36
_ZN4PLMD10vesselbase6Vessel14setBufferStartERj32944
_ZN4PLMD10vesselbase6Vessel20transformDerivativesERKjRNS_10MultiValueES5_509167
_ZN4PLMD10vesselbase6Vessel5parseINSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEEvRKS8_RT_532
_ZN4PLMD10vesselbase6Vessel5parseIdEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_10
_ZN4PLMD10vesselbase6Vessel5parseIjEEvRKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERT_349
_ZN4PLMD10vesselbase6Vessel7prepareEv26788
_ZN4PLMD10vesselbase6VesselD0Ev0
_ZN4PLMD10vesselbase6VesselD2Ev607
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/Vessel.h.gcov.html b/coverage/vesselbase/Vessel.h.gcov.html new file mode 100644 index 000000000000..5b24ac5e1670 --- /dev/null +++ b/coverage/vesselbase/Vessel.h.gcov.html @@ -0,0 +1,322 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/Vessel.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - Vessel.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:293680.6 %
Date:2024-02-22 21:58:45Functions:91090.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_vesselbase_Vessel_h
+      23             : #define __PLUMED_vesselbase_Vessel_h
+      24             : 
+      25             : #include <string>
+      26             : #include <cstring>
+      27             : #include <vector>
+      28             : #include <algorithm>
+      29             : #include "tools/Exception.h"
+      30             : #include "tools/Keywords.h"
+      31             : #include "ActionWithVessel.h"
+      32             : 
+      33             : namespace PLMD {
+      34             : 
+      35             : class Communicator;
+      36             : class Log;
+      37             : 
+      38             : namespace vesselbase {
+      39             : 
+      40             : /**
+      41             : \ingroup TOOLBOX
+      42             : Vessels are an important component of class PLMD::ActionWithVessel.  This class
+      43             : contains a large buffer array of doubles.  The various elements of this array
+      44             : can be accessed through vessels which are used to structure the elements of the
+      45             : double array.  As the buffer array is just a vector of doubles it can be easily
+      46             : mpi gathered or passed to another node.
+      47             : */
+      48             : 
+      49             : //class ActionWithVessel;
+      50             : class Vessel;
+      51             : 
+      52             : /// This class is used to pass the input to Vessels
+      53             : class VesselOptions {
+      54             :   friend class Vessel;
+      55             : private:
+      56             : /// The name of the particular vessel
+      57             :   std::string myname;
+      58             : /// The label for this particular vessel;
+      59             :   std::string mylabel;
+      60             : /// The numerical label for this vessel
+      61             :   int numlab;
+      62             : /// Pointer to ActionWithVessel that this if from
+      63             :   ActionWithVessel* action;
+      64             : /// The keywords
+      65             :   const Keywords& keywords;
+      66             :   static Keywords emptyKeys;
+      67             : public:
+      68             : /// The parameters that are read into the function
+      69             :   std::string parameters;
+      70             : /// The constructor
+      71             :   VesselOptions( const std::string& thisname, const std::string& thislab, const unsigned& nlab, const std::string& params, ActionWithVessel* aa );
+      72             :   VesselOptions(const VesselOptions& da, const Keywords& keys );
+      73             : };
+      74             : 
+      75             : class Vessel {
+      76             :   friend class ActionWithVessel;
+      77             : private:
+      78             : /// The keyword for the vessel in the input file
+      79             :   std::string myname;
+      80             : /// The label for the vessel for referencing
+      81             :   std::string mylabel;
+      82             : /// The numerical label for this object
+      83             :   const int numlab;
+      84             : /// The action that this vessel is created within
+      85             :   ActionWithVessel* action;
+      86             : /// The number of elements in this vessel's buffered data
+      87             :   unsigned bufsize;
+      88             : /// Directive line.
+      89             : /// This line is progressively erased during vessel construction
+      90             : /// so as to check if all the present keywords are correct.
+      91             :   std::vector<std::string> line;
+      92             : /// The keywords
+      93             :   const PLMD::Keywords& keywords;
+      94             : /// This just checks we have done checkRead
+      95             :   bool finished_read;
+      96             : protected:
+      97             : /// The start of this Vessel's buffer in buffer in the underlying ActionWithVessel
+      98             :   unsigned bufstart;
+      99             : /// Return the numerical label
+     100             :   int getNumericalLabel() const ;
+     101             : /// Report an error
+     102             :   [[noreturn]] void error(const std::string& errmsg);
+     103             : /// Parse something from the input
+     104             :   template<class T>
+     105             :   void parse(const std::string&key, T&t);
+     106             : /// Parse one keyword as std::vector
+     107             :   template<class T>
+     108             :   void parseVector(const std::string&key,std::vector<T>&t);
+     109             : /// Parse one keyword as boolean flag
+     110             :   void parseFlag(const std::string&key,bool&t);
+     111             : /// This returns the whole input line (it is used for less_than/more_than/between)
+     112             :   std::string getAllInput();
+     113             : /// Return a pointer to the action we are working in
+     114             :   ActionWithVessel* getAction() const ;
+     115             : /// Return the value of the tolerance
+     116             :   double getTolerance() const ;
+     117             : /// Return the value of the neighbor list tolerance
+     118             :   double getNLTolerance() const ;
+     119             : /// Return the size of the buffer
+     120             :   unsigned getSizeOfBuffer() const ;
+     121             : /// Set the size of the data buffer
+     122             :   void resizeBuffer( const unsigned& n );
+     123             : public:
+     124             : /// Reserve any keywords for this particular vessel
+     125             :   static void registerKeywords( Keywords& keys );
+     126             : /// Convert the name to the label of the component
+     127             :   static std::string transformName( const std::string& name );
+     128             : /// The constructor
+     129             :   explicit Vessel( const VesselOptions& da );
+     130             : /// Virtual destructor needed for proper inheritance
+     131         607 :   virtual ~Vessel() {}
+     132             : /// Return the name
+     133             :   std::string getName() const ;
+     134             : /// Return the label
+     135             :   std::string getLabel() const ;
+     136             : /// Check that readin was fine
+     137             :   void checkRead();
+     138             : /// Return a description of the vessel contents
+     139             :   virtual std::string description()=0;
+     140             : /// Set the start of the buffer
+     141             :   virtual void setBufferStart( unsigned& start );
+     142             : /// Do something before the loop
+     143       26788 :   virtual void prepare() {}
+     144             : /// This is replaced in bridges so we can transform the derivatives
+     145             :   virtual MultiValue& transformDerivatives( const unsigned& current, MultiValue& myvals, MultiValue& bvals );
+     146             : /// Calculate the part of the vessel that is done in the loop
+     147             :   virtual void calculate( const unsigned& current, MultiValue& myvals, std::vector<double>& buffer, std::vector<unsigned>& der_list ) const = 0;
+     148             : /// Complete the calculation once the loop is finished
+     149             :   virtual void finish( const std::vector<double>& )=0;
+     150             : /// Reset the size of the buffers
+     151             :   virtual void resize()=0;
+     152             : /// Retrieve the forces on the quantities in the vessel
+     153             :   virtual bool applyForce( std::vector<double>& forces )=0;
+     154             : };
+     155             : 
+     156             : template<class T>
+     157         891 : void Vessel::parse(const std::string&key, T&t ) {
+     158         891 :   plumed_massert(keywords.exists(key),"keyword " + key + " has not been registered");
+     159             : 
+     160             :   // Now try to read the keyword
+     161         891 :   bool found=Tools::parse(line,key,t); std::string def;
+     162        2036 :   if ( !found && keywords.style(key,"compulsory") ) {
+     163         369 :     if( keywords.getDefaultValue(key,def) ) {
+     164         369 :       plumed_massert( def.length()!=0 && Tools::convertNoexcept(def,t), "default value is dubious");
+     165             :     } else {
+     166           0 :       error("keyword " + key + " is comulsory for this vessel");
+     167             :     }
+     168             :   }
+     169         891 : }
+     170             : 
+     171             : template<class T>
+     172         245 : void Vessel::parseVector(const std::string&key,std::vector<T>&t) {
+     173             :   // Check keyword has been registered
+     174         245 :   plumed_massert(keywords.exists(key), "keyword " + key + " has not been registered");
+     175         245 :   unsigned size=t.size(); bool skipcheck=false;
+     176         245 :   if(size==0) skipcheck=true;
+     177             : 
+     178             :   // Now try to read the keyword
+     179             :   bool found; std::string def; T val;
+     180         245 :   found=Tools::parseVector(line,key,t);
+     181             : 
+     182             :   // Check vectors size is correct (not if this is atoms or ARG)
+     183         490 :   if( !keywords.style(key,"atoms") && found ) {
+     184         237 :     if( !skipcheck && t.size()!=size ) error("vector read in for keyword " + key + " has the wrong size");
+     185             :   }
+     186             : 
+     187             :   // If it isn't read and it is compulsory see if a default value was specified
+     188         261 :   if ( !found && keywords.style(key,"compulsory") ) {
+     189           0 :     if( keywords.getDefaultValue(key,def) ) {
+     190           0 :       if( def.length()==0 || !Tools::convertNoexcept(def,val) ) {
+     191           0 :         plumed_merror("weird default value for keyword " + key );
+     192             :       } else {
+     193           0 :         for(unsigned i=0; i<t.size(); ++i) t[i]=val;
+     194             :       }
+     195             :     } else {
+     196           0 :       error("keyword " + key + " is compulsory");
+     197             :     }
+     198         245 :   } else if ( !found ) {
+     199           8 :     t.resize(0);
+     200             :   }
+     201         245 : }
+     202             : 
+     203             : inline
+     204             : int Vessel::getNumericalLabel() const {
+     205         357 :   return numlab;
+     206             : }
+     207             : 
+     208             : inline
+     209       32944 : void Vessel::setBufferStart( unsigned& start ) {
+     210       32944 :   bufstart=start; start+=bufsize;
+     211       32944 : }
+     212             : 
+     213             : inline
+     214      509167 : MultiValue& Vessel::transformDerivatives( const unsigned& current, MultiValue& myvals, MultiValue& bvals ) {
+     215      509167 :   return myvals;
+     216             : }
+     217             : 
+     218             : inline
+     219             : void Vessel::resizeBuffer( const unsigned& n ) {
+     220        2874 :   bufsize=n;
+     221           0 : }
+     222             : 
+     223             : inline
+     224             : double Vessel::getTolerance() const {
+     225      134270 :   return action->tolerance;
+     226             : }
+     227             : 
+     228             : inline
+     229             : double Vessel::getNLTolerance() const {
+     230             :   return action->nl_tolerance;
+     231             : }
+     232             : 
+     233             : inline
+     234             : ActionWithVessel* Vessel::getAction() const {
+     235     3911561 :   return action;
+     236             : }
+     237             : 
+     238             : inline
+     239             : unsigned Vessel::getSizeOfBuffer() const {
+     240             :   return bufsize;
+     241             : }
+     242             : 
+     243             : }
+     244             : }
+     245             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/VesselRegister.cpp.func-sort-c.html b/coverage/vesselbase/VesselRegister.cpp.func-sort-c.html new file mode 100644 index 000000000000..4e338aad0462 --- /dev/null +++ b/coverage/vesselbase/VesselRegister.cpp.func-sort-c.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/VesselRegister.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - VesselRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283384.8 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14VesselRegister6createERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_13VesselOptionsE363
_ZN4PLMD10vesselbase14VesselRegister11getKeywordsEv797
_ZN4PLMD10vesselbase14VesselRegisterD2Ev4187
_ZN4PLMD10vesselbase14VesselRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10108
_ZN4PLMD10vesselbase14VesselRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS9_EERKNS0_13VesselOptionsEEPFvRNS_8KeywordsEESL_75366
_ZN4PLMD10vesselbase14VesselRegister6removeEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS3_EERKNS0_13VesselOptionsEE75366
_ZN4PLMD10vesselbase14vesselRegisterEv161637
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/VesselRegister.cpp.func.html b/coverage/vesselbase/VesselRegister.cpp.func.html new file mode 100644 index 000000000000..64e27ac42d94 --- /dev/null +++ b/coverage/vesselbase/VesselRegister.cpp.func.html @@ -0,0 +1,101 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/VesselRegister.cpp - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - VesselRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283384.8 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
_ZN4PLMD10vesselbase14VesselRegister11getKeywordsEv797
_ZN4PLMD10vesselbase14VesselRegister3addENSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS9_EERKNS0_13VesselOptionsEEPFvRNS_8KeywordsEESL_75366
_ZN4PLMD10vesselbase14VesselRegister5checkERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE10108
_ZN4PLMD10vesselbase14VesselRegister6createERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEERKNS0_13VesselOptionsE363
_ZN4PLMD10vesselbase14VesselRegister6removeEPFSt10unique_ptrINS0_6VesselESt14default_deleteIS3_EERKNS0_13VesselOptionsEE75366
_ZN4PLMD10vesselbase14VesselRegisterD2Ev4187
_ZN4PLMD10vesselbase14vesselRegisterEv161637
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/VesselRegister.cpp.gcov.html b/coverage/vesselbase/VesselRegister.cpp.gcov.html new file mode 100644 index 000000000000..29f067a1d887 --- /dev/null +++ b/coverage/vesselbase/VesselRegister.cpp.gcov.html @@ -0,0 +1,157 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase/VesselRegister.cpp + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbase - VesselRegister.cpp (source / functions)HitTotalCoverage
Test:plumed test coverageLines:283384.8 %
Date:2024-02-22 21:58:45Functions:77100.0 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2012-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #include "VesselRegister.h"
+      23             : #include "Vessel.h"
+      24             : #include <iostream>
+      25             : 
+      26             : namespace PLMD {
+      27             : namespace vesselbase {
+      28             : 
+      29        4187 : VesselRegister::~VesselRegister() {
+      30        4187 :   if(m.size()>0) {
+      31           0 :     std::string names="";
+      32           0 :     for(const auto & p : m) names+=p.first+" ";
+      33           0 :     std::cerr<<"WARNING: Vessel "+ names +" has not been properly unregistered. This might lead to memory leak!!\n";
+      34             :   }
+      35        4187 : }
+      36             : 
+      37      161637 : VesselRegister& vesselRegister() {
+      38      161637 :   static VesselRegister ans;
+      39      161637 :   return ans;
+      40             : }
+      41             : 
+      42       75366 : void VesselRegister::remove(creator_pointer f) {
+      43      477318 :   for(auto p=m.begin(); p!=m.end(); ++p) {
+      44      477318 :     if((*p).second==f) {
+      45       75366 :       m.erase(p); break;
+      46             :     }
+      47             :   }
+      48       75366 : }
+      49             : 
+      50       75366 : void VesselRegister::add(std::string keyword,creator_pointer f,keyword_pointer k,keyword_pointer ik) {
+      51           0 :   plumed_massert(m.count(keyword)==0,"keyword has already been registered");
+      52       75366 :   m.insert(std::pair<std::string,creator_pointer>(keyword,f));
+      53       75366 :   k( keywords );   // Store the keywords for all the things
+      54             :   // Store a pointer to the function that creates keywords
+      55             :   // A pointer is stored and not the keywords because all
+      56             :   // Vessels must be dynamically loaded before the actions.
+      57       75366 :   mk.insert(std::pair<std::string,keyword_pointer>(keyword,ik));
+      58       75366 : }
+      59             : 
+      60       10108 : bool VesselRegister::check(const std::string & key) {
+      61        3137 :   if( m.count(key)>0 ) return true;
+      62             :   return false;
+      63             : }
+      64             : 
+      65         363 : std::unique_ptr<Vessel> VesselRegister::create(const std::string & keyword, const VesselOptions&da) {
+      66         363 :   std::unique_ptr<Vessel> df;
+      67         363 :   if(check(keyword)) {
+      68         363 :     Keywords keys; mk[keyword](keys);
+      69         363 :     VesselOptions nda( da,keys );
+      70         726 :     df=m[keyword](nda);
+      71         363 :   }
+      72         363 :   return df;
+      73           0 : }
+      74             : 
+      75         797 : Keywords VesselRegister::getKeywords() {
+      76         797 :   return keywords;
+      77             : }
+      78             : 
+      79             : }
+      80             : }
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/index-sort-f.html b/coverage/vesselbase/index-sort-f.html new file mode 100644 index 000000000000..14b689ff68b6 --- /dev/null +++ b/coverage/vesselbase/index-sort-f.html @@ -0,0 +1,434 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbaseHitTotalCoverage
Test:plumed test coverageLines:1141122892.9 %
Date:2024-02-22 21:58:45Functions:23225989.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionWithInputVessel.h +
66.7%66.7%
+
66.7 %2 / 30.0 %0 / 1
ShortcutVessel.h +
0.0%
+
0.0 %0 / 60.0 %0 / 5
AveragingVessel.h +
90.0%90.0%
+
90.0 %9 / 1050.0 %1 / 2
ActionWithVessel.h +
83.3%83.3%
+
83.3 %20 / 2450.0 %3 / 6
ActionWithInputVessel.cpp +
86.5%86.5%
+
86.5 %32 / 3766.7 %4 / 6
ActionWithVessel.cpp +
93.5%93.5%
+
93.5 %186 / 19976.9 %20 / 26
ActionWithAveraging.cpp +
95.4%95.4%
+
95.4 %104 / 10978.6 %11 / 14
FunctionVessel.cpp +
95.7%95.7%
+
95.7 %44 / 4685.7 %6 / 7
ActionWithAveraging.h +
92.3%92.3%
+
92.3 %12 / 1385.7 %6 / 7
StoreDataVessel.h +
92.3%92.3%
+
92.3 %24 / 2685.7 %6 / 7
Vessel.h +
80.6%80.6%
+
80.6 %29 / 3690.0 %9 / 10
Vessel.cpp +
82.1%82.1%
+
82.1 %64 / 7890.9 %10 / 11
BridgeVessel.cpp +
97.0%97.0%
+
97.0 %96 / 9992.3 %12 / 13
FunctionVessel.h +
0.0%
+
0.0 %0 / 1-0 / 0
BridgeVessel.h +
100.0%
+
100.0 %1 / 1-0 / 0
ValueVessel.h +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
OrderingVessel.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
ShortcutVessel.cpp +
100.0%
+
100.0 %12 / 12100.0 %3 / 3
OrderingVessel.cpp +
96.4%96.4%
+
96.4 %27 / 28100.0 %4 / 4
ValueVessel.cpp +
100.0%
+
100.0 %32 / 32100.0 %4 / 4
Histogram.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
AveragingVessel.cpp +
100.0%
+
100.0 %23 / 23100.0 %7 / 7
VesselRegister.cpp +
84.8%84.8%
+
84.8 %28 / 33100.0 %7 / 7
Sum.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Lowest.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Mean.cpp +
100.0%
+
100.0 %17 / 17100.0 %8 / 8
MoreThan.cpp +
100.0%
+
100.0 %20 / 20100.0 %8 / 8
Highest.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Between.cpp +
100.0%
+
100.0 %30 / 30100.0 %9 / 9
LessThan.cpp +
100.0%
+
100.0 %22 / 22100.0 %9 / 9
Min.cpp +
100.0%
+
100.0 %24 / 24100.0 %9 / 9
Max.cpp +
100.0%
+
100.0 %23 / 23100.0 %9 / 9
AltMin.cpp +
100.0%
+
100.0 %21 / 21100.0 %9 / 9
Moments.cpp +
89.1%89.1%
+
89.1 %82 / 92100.0 %11 / 11
StoreDataVessel.cpp +
93.5%93.5%
+
93.5 %86 / 92100.0 %15 / 15
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/index-sort-l.html b/coverage/vesselbase/index-sort-l.html new file mode 100644 index 000000000000..1d82e527df69 --- /dev/null +++ b/coverage/vesselbase/index-sort-l.html @@ -0,0 +1,434 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbaseHitTotalCoverage
Test:plumed test coverageLines:1141122892.9 %
Date:2024-02-22 21:58:45Functions:23225989.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
FunctionVessel.h +
0.0%
+
0.0 %0 / 1-0 / 0
ShortcutVessel.h +
0.0%
+
0.0 %0 / 60.0 %0 / 5
ActionWithInputVessel.h +
66.7%66.7%
+
66.7 %2 / 30.0 %0 / 1
Vessel.h +
80.6%80.6%
+
80.6 %29 / 3690.0 %9 / 10
Vessel.cpp +
82.1%82.1%
+
82.1 %64 / 7890.9 %10 / 11
ActionWithVessel.h +
83.3%83.3%
+
83.3 %20 / 2450.0 %3 / 6
VesselRegister.cpp +
84.8%84.8%
+
84.8 %28 / 33100.0 %7 / 7
ActionWithInputVessel.cpp +
86.5%86.5%
+
86.5 %32 / 3766.7 %4 / 6
Moments.cpp +
89.1%89.1%
+
89.1 %82 / 92100.0 %11 / 11
AveragingVessel.h +
90.0%90.0%
+
90.0 %9 / 1050.0 %1 / 2
ActionWithAveraging.h +
92.3%92.3%
+
92.3 %12 / 1385.7 %6 / 7
StoreDataVessel.h +
92.3%92.3%
+
92.3 %24 / 2685.7 %6 / 7
StoreDataVessel.cpp +
93.5%93.5%
+
93.5 %86 / 92100.0 %15 / 15
ActionWithVessel.cpp +
93.5%93.5%
+
93.5 %186 / 19976.9 %20 / 26
ActionWithAveraging.cpp +
95.4%95.4%
+
95.4 %104 / 10978.6 %11 / 14
FunctionVessel.cpp +
95.7%95.7%
+
95.7 %44 / 4685.7 %6 / 7
OrderingVessel.cpp +
96.4%96.4%
+
96.4 %27 / 28100.0 %4 / 4
BridgeVessel.cpp +
97.0%97.0%
+
97.0 %96 / 9992.3 %12 / 13
OrderingVessel.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
BridgeVessel.h +
100.0%
+
100.0 %1 / 1-0 / 0
ValueVessel.h +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
ShortcutVessel.cpp +
100.0%
+
100.0 %12 / 12100.0 %3 / 3
Sum.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Lowest.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Highest.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Mean.cpp +
100.0%
+
100.0 %17 / 17100.0 %8 / 8
Histogram.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
MoreThan.cpp +
100.0%
+
100.0 %20 / 20100.0 %8 / 8
AltMin.cpp +
100.0%
+
100.0 %21 / 21100.0 %9 / 9
LessThan.cpp +
100.0%
+
100.0 %22 / 22100.0 %9 / 9
AveragingVessel.cpp +
100.0%
+
100.0 %23 / 23100.0 %7 / 7
Max.cpp +
100.0%
+
100.0 %23 / 23100.0 %9 / 9
Min.cpp +
100.0%
+
100.0 %24 / 24100.0 %9 / 9
Between.cpp +
100.0%
+
100.0 %30 / 30100.0 %9 / 9
ValueVessel.cpp +
100.0%
+
100.0 %32 / 32100.0 %4 / 4
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/vesselbase/index.html b/coverage/vesselbase/index.html new file mode 100644 index 000000000000..c070ebd835d9 --- /dev/null +++ b/coverage/vesselbase/index.html @@ -0,0 +1,434 @@ + + + + + + + + LCOV - plumed test coverage - vesselbase + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - vesselbaseHitTotalCoverage
Test:plumed test coverageLines:1141122892.9 %
Date:2024-02-22 21:58:45Functions:23225989.6 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
ActionWithAveraging.cpp +
95.4%95.4%
+
95.4 %104 / 10978.6 %11 / 14
ActionWithAveraging.h +
92.3%92.3%
+
92.3 %12 / 1385.7 %6 / 7
ActionWithInputVessel.cpp +
86.5%86.5%
+
86.5 %32 / 3766.7 %4 / 6
ActionWithInputVessel.h +
66.7%66.7%
+
66.7 %2 / 30.0 %0 / 1
ActionWithVessel.cpp +
93.5%93.5%
+
93.5 %186 / 19976.9 %20 / 26
ActionWithVessel.h +
83.3%83.3%
+
83.3 %20 / 2450.0 %3 / 6
AltMin.cpp +
100.0%
+
100.0 %21 / 21100.0 %9 / 9
AveragingVessel.cpp +
100.0%
+
100.0 %23 / 23100.0 %7 / 7
AveragingVessel.h +
90.0%90.0%
+
90.0 %9 / 1050.0 %1 / 2
Between.cpp +
100.0%
+
100.0 %30 / 30100.0 %9 / 9
BridgeVessel.cpp +
97.0%97.0%
+
97.0 %96 / 9992.3 %12 / 13
BridgeVessel.h +
100.0%
+
100.0 %1 / 1-0 / 0
FunctionVessel.cpp +
95.7%95.7%
+
95.7 %44 / 4685.7 %6 / 7
FunctionVessel.h +
0.0%
+
0.0 %0 / 1-0 / 0
Highest.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Histogram.cpp +
100.0%
+
100.0 %20 / 20100.0 %6 / 6
LessThan.cpp +
100.0%
+
100.0 %22 / 22100.0 %9 / 9
Lowest.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
Max.cpp +
100.0%
+
100.0 %23 / 23100.0 %9 / 9
Mean.cpp +
100.0%
+
100.0 %17 / 17100.0 %8 / 8
Min.cpp +
100.0%
+
100.0 %24 / 24100.0 %9 / 9
Moments.cpp +
89.1%89.1%
+
89.1 %82 / 92100.0 %11 / 11
MoreThan.cpp +
100.0%
+
100.0 %20 / 20100.0 %8 / 8
OrderingVessel.cpp +
96.4%96.4%
+
96.4 %27 / 28100.0 %4 / 4
OrderingVessel.h +
100.0%
+
100.0 %1 / 1100.0 %1 / 1
ShortcutVessel.cpp +
100.0%
+
100.0 %12 / 12100.0 %3 / 3
ShortcutVessel.h +
0.0%
+
0.0 %0 / 60.0 %0 / 5
StoreDataVessel.cpp +
93.5%93.5%
+
93.5 %86 / 92100.0 %15 / 15
StoreDataVessel.h +
92.3%92.3%
+
92.3 %24 / 2685.7 %6 / 7
Sum.cpp +
100.0%
+
100.0 %15 / 15100.0 %8 / 8
ValueVessel.cpp +
100.0%
+
100.0 %32 / 32100.0 %4 / 4
ValueVessel.h +
100.0%
+
100.0 %5 / 5100.0 %1 / 1
Vessel.cpp +
82.1%82.1%
+
82.1 %64 / 7890.9 %10 / 11
Vessel.h +
80.6%80.6%
+
80.6 %29 / 3690.0 %9 / 10
VesselRegister.cpp +
84.8%84.8%
+
84.8 %28 / 33100.0 %7 / 7
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/Plumed.h.func-sort-c.html b/coverage/wrapper/Plumed.h.func-sort-c.html new file mode 100644 index 000000000000..8030d952e5c2 --- /dev/null +++ b/coverage/wrapper/Plumed.h.func-sort-c.html @@ -0,0 +1,1089 @@ + + + + + + + + LCOV - plumed test coverage - wrapper/Plumed.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapper - Plumed.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-02-22 21:58:45Functions:14425456.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
PLUMED_F_CREATE_INVALID0
PLUMED_F_CREATE_INVALID_0
PLUMED_F_CREATE_INVALID__0
PLUMED_F_GVALID__0
PLUMED_F_VALID0
PLUMED_F_VALID_0
PLUMED_F_VALID__0
_ZL16plumed_error_setPviPKcPKv0
_ZL21plumed_error_finalize12plumed_error0
_ZL26plumed_error_set_bad_allocP12plumed_error0
_ZN12_GLOBAL__N_115plumed_cmd_safeE6plumedPKc14plumed_safeptr0
_ZN12_GLOBAL__N_118plumed_cmd_nothrowE6plumedPKcPKv22plumed_nothrow_handler0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt8bad_castE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9bad_allocE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9exceptionE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_7InvalidEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionDebugEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_6lepton9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed21finalize_plumed_errorD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed7InvalidC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowER12plumed_error0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowEv0
_ZN4PLMD12_GLOBAL__N_1L27PlumedGetenvExceptionsDebugEv0
_ZN4PLMD6Plumed13add_buffer_toISt10bad_typeidE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt8bad_castE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9bad_allocE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9exceptionE4initEPKc0
_ZN4PLMD6Plumed15LeptonExceptionC2EPKc0
_ZN4PLMD6Plumed18exception_dispatchINS0_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18exception_dispatchINS0_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionDebugEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_15LeptonExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_7InvalidEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_9ExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD6Plumed21finalize_plumed_errorD2Ev0
_ZN4PLMD6Plumed7rethrowER12plumed_error0
_ZN4PLMD6Plumed7rethrowEv0
_ZN4PLMD6Plumed9ExceptionC2EPKc0
_ZN4PLMDL27PlumedGetenvExceptionsDebugEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt8bad_castE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9bad_allocE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt8bad_castE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt9bad_allocE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt9exceptionE4whatEv0
_ZNK4PLMD6Plumed15LeptonException4whatEv0
_ZNK4PLMD6Plumed9Exception4whatEv0
plumed_cmd_nothrow0
plumed_f_create_invalid0
plumed_f_create_invalid_0
plumed_f_create_invalid__0
plumed_f_create_invalid_static0
plumed_f_safeptr_char_scalar0
plumed_f_safeptr_float_scalar0
plumed_f_safeptr_long0
plumed_f_safeptr_long_double0
plumed_f_safeptr_long_double_scalar0
plumed_f_safeptr_long_scalar0
plumed_f_safeptr_ptr_scalar0
plumed_f_safeptr_short0
plumed_f_safeptr_short_scalar0
plumed_f_valid0
plumed_f_valid_0
plumed_f_valid__0
plumed_f_valid_static0
plumed_gcmd_safe0
PLUMED_F_CREATE_DLOPEN1
PLUMED_F_CREATE_DLOPEN_1
PLUMED_F_CREATE_DLOPEN__1
PLUMED_F_CREATE_REFERENCE1
PLUMED_F_CREATE_REFERENCE_1
PLUMED_F_CREATE_REFERENCE__1
PLUMED_F_GLOBAL1
PLUMED_F_GLOBAL_1
PLUMED_F_GLOBAL__1
PLUMED_F_GVALID1
PLUMED_F_INSTALLED1
PLUMED_F_INSTALLED_1
PLUMED_F_INSTALLED__1
_ZN12_GLOBAL__N_115plumed_finalizeE6plumed1
_ZN12_GLOBAL__N_119plumed_create_dlsymEPv1
_ZN12_GLOBAL__N_119plumed_malloc_pimplEv1
_ZN12_GLOBAL__N_120plumed_create_dlopenEPKc1
_ZN12_GLOBAL__N_121plumed_attempt_dlopenEPKci1
_ZN12_GLOBAL__N_121plumed_create_dlopen2EPKci1
_ZN12_GLOBAL__N_121plumed_search_symbolsEPvP33plumed_plumedmain_function_holderPP24plumed_symbol_table_type1
plumed_f_create_dlopen1
plumed_f_create_dlopen_1
plumed_f_create_dlopen__1
plumed_f_create_reference1
plumed_f_create_reference_1
plumed_f_create_reference__1
plumed_f_global_1
plumed_f_global__1
plumed_f_gvalid1
plumed_f_gvalid_1
plumed_f_gvalid__1
plumed_f_installed1
plumed_f_installed_1
plumed_f_installed__1
plumed_f_safeptr_float1
PLUMED_F_CREATE2
PLUMED_F_CREATE_2
PLUMED_F_CREATE__2
PLUMED_F_GCREATE2
PLUMED_F_GCREATE_2
PLUMED_F_GCREATE__2
PLUMED_F_GFINALIZE2
PLUMED_F_GFINALIZE_2
PLUMED_F_GFINALIZE__2
PLUMED_F_GINITIALIZED__2
PLUMED_F_GVALID_2
plumed_c2v2
plumed_create_invalid2
plumed_create_reference_v2
plumed_f_create__2
plumed_f_gcreate__2
plumed_f_gfinalize__2
plumed_v2c2
PLUMED_F_GINITIALIZED3
PLUMED_F_USE_COUNT3
PLUMED_F_USE_COUNT_3
PLUMED_F_USE_COUNT__3
plumed_f_gcreate3
plumed_f_gcreate_3
plumed_f_gfinalize3
plumed_f_gfinalize_3
plumed_f_ginitialized3
plumed_f_ginitialized_3
plumed_f_ginitialized__3
plumed_f_safeptr_double_scalar3
plumed_f_use_count3
plumed_f_use_count_3
plumed_f_use_count__3
PLUMED_F_FINALIZE4
PLUMED_F_FINALIZE_4
PLUMED_F_FINALIZE__4
PLUMED_F_GINITIALIZED_4
plumed_f_create_4
plumed_f_finalize__4
plumed_f_create6
plumed_f_create_dlopen_static6
plumed_f_create_reference_static6
plumed_f_finalize_6
plumed_f_gvalid_static6
plumed_f_installed_static6
plumed_f_safeptr_int6
plumed_attempt_dlopen8
plumed_create_dlopen8
plumed_create_dlopen28
plumed_create_dlsym8
plumed_create_reference_f8
plumed_f_finalize8
plumed_gvalid8
plumed_search_symbols8
plumed_installed9
PLUMED_F_GCMD10
PLUMED_F_GCMD_10
PLUMED_F_GCMD__10
plumed_f_gcmd10
plumed_f_gcmd__10
plumed_f_safeptr_int_scalar13
plumed_f_gcreate_static14
plumed_f_gfinalize_static14
plumed_f_safeptr_double16
plumed_f_create_static18
plumed_f_ginitialized_static18
plumed_f_use_count_static18
plumed_f_global19
plumed_f_safeptr_char20
plumed_kernel_register20
plumed_gcreate22
plumed_gfinalize22
plumed_valid23
plumed_f_global_static24
plumed_f_safeptr_ptr24
plumed_ginitialized24
plumed_f_gcmd_28
plumed_f_finalize_static30
PLUMED_F_CMD40
PLUMED_F_CMD_40
PLUMED_F_CMD__40
plumed_f_cmd__40
plumed_global41
plumed_use_count42
plumed_c2f56
plumed_f_cmd_59
plumed_f_cmd60
plumed_f_gcmd_static78
plumed_gcmd78
plumed_cmd_safe95
_ZN12_GLOBAL__N_123plumed_cmd_safe_nothrowE6plumedPKc14plumed_safeptr22plumed_nothrow_handler222
_ZN4PLMD12_GLOBAL__N_16Plumed14plumed_cmd_cxxI14plumed_safeptrEEv6plumedPKcT_P12plumed_error222
_ZN4PLMD12_GLOBAL__N_16Plumed8cmd_privE6plumedPKcPNS1_7SafePtrEPKvP12plumed_error222
plumed_f_cmd_static279
_ZN4PLMD6Plumed14plumed_cmd_cxxIP19ompi_communicator_tEEv6plumedPKcPT_P12plumed_error340
plumed_cmd357
plumed_f2c373
_ZN4PLMD6Plumed14plumed_cmd_cxxIPcEEv6plumedPKcPT_P12plumed_error4144
_ZN4PLMD6Plumed14plumed_cmd_cxxIiEEv6plumedPKcPT_P12plumed_error8288
_ZN4PLMD6Plumed8cmd_privE6plumedPKcPNS0_7SafePtrEPKvP12plumed_error12772
plumed_cmd_safe_nothrow14135
plumed_symbol_table_reexport658609
plumed_retrieve_functions684064
plumed_malloc699554
plumed_malloc_pimpl699993
plumed_create700214
plumed_free720030
plumed_create_reference7504672
plumed_finalize8421090
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/Plumed.h.func.html b/coverage/wrapper/Plumed.h.func.html new file mode 100644 index 000000000000..29f2491aa6c3 --- /dev/null +++ b/coverage/wrapper/Plumed.h.func.html @@ -0,0 +1,1089 @@ + + + + + + + + LCOV - plumed test coverage - wrapper/Plumed.h - functions + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapper - Plumed.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-02-22 21:58:45Functions:14425456.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +

Function Name Sort by function nameHit count Sort by hit count
PLUMED_F_CMD40
PLUMED_F_CMD_40
PLUMED_F_CMD__40
PLUMED_F_CREATE2
PLUMED_F_CREATE_2
PLUMED_F_CREATE_DLOPEN1
PLUMED_F_CREATE_DLOPEN_1
PLUMED_F_CREATE_DLOPEN__1
PLUMED_F_CREATE_INVALID0
PLUMED_F_CREATE_INVALID_0
PLUMED_F_CREATE_INVALID__0
PLUMED_F_CREATE_REFERENCE1
PLUMED_F_CREATE_REFERENCE_1
PLUMED_F_CREATE_REFERENCE__1
PLUMED_F_CREATE__2
PLUMED_F_FINALIZE4
PLUMED_F_FINALIZE_4
PLUMED_F_FINALIZE__4
PLUMED_F_GCMD10
PLUMED_F_GCMD_10
PLUMED_F_GCMD__10
PLUMED_F_GCREATE2
PLUMED_F_GCREATE_2
PLUMED_F_GCREATE__2
PLUMED_F_GFINALIZE2
PLUMED_F_GFINALIZE_2
PLUMED_F_GFINALIZE__2
PLUMED_F_GINITIALIZED3
PLUMED_F_GINITIALIZED_4
PLUMED_F_GINITIALIZED__2
PLUMED_F_GLOBAL1
PLUMED_F_GLOBAL_1
PLUMED_F_GLOBAL__1
PLUMED_F_GVALID1
PLUMED_F_GVALID_2
PLUMED_F_GVALID__0
PLUMED_F_INSTALLED1
PLUMED_F_INSTALLED_1
PLUMED_F_INSTALLED__1
PLUMED_F_USE_COUNT3
PLUMED_F_USE_COUNT_3
PLUMED_F_USE_COUNT__3
PLUMED_F_VALID0
PLUMED_F_VALID_0
PLUMED_F_VALID__0
_ZL16plumed_error_setPviPKcPKv0
_ZL21plumed_error_finalize12plumed_error0
_ZL26plumed_error_set_bad_allocP12plumed_error0
_ZN12_GLOBAL__N_115plumed_cmd_safeE6plumedPKc14plumed_safeptr0
_ZN12_GLOBAL__N_115plumed_finalizeE6plumed1
_ZN12_GLOBAL__N_118plumed_cmd_nothrowE6plumedPKcPKv22plumed_nothrow_handler0
_ZN12_GLOBAL__N_119plumed_create_dlsymEPv1
_ZN12_GLOBAL__N_119plumed_malloc_pimplEv1
_ZN12_GLOBAL__N_120plumed_create_dlopenEPKc1
_ZN12_GLOBAL__N_121plumed_attempt_dlopenEPKci1
_ZN12_GLOBAL__N_121plumed_create_dlopen2EPKci1
_ZN12_GLOBAL__N_121plumed_search_symbolsEPvP33plumed_plumedmain_function_holderPP24plumed_symbol_table_type1
_ZN12_GLOBAL__N_123plumed_cmd_safe_nothrowE6plumedPKc14plumed_safeptr22plumed_nothrow_handler222
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt8bad_castE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9bad_allocE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9exceptionE4initEPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed14plumed_cmd_cxxI14plumed_safeptrEEv6plumedPKcT_P12plumed_error222
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18exception_dispatchINS1_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS1_7InvalidEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionDebugEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_14ExceptionErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_6lepton9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINS_9ExceptionEEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD12_GLOBAL__N_16Plumed21finalize_plumed_errorD2Ev0
_ZN4PLMD12_GLOBAL__N_16Plumed7InvalidC2EPKc0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowER12plumed_error0
_ZN4PLMD12_GLOBAL__N_16Plumed7rethrowEv0
_ZN4PLMD12_GLOBAL__N_16Plumed8cmd_privE6plumedPKcPNS1_7SafePtrEPKvP12plumed_error222
_ZN4PLMD12_GLOBAL__N_1L27PlumedGetenvExceptionsDebugEv0
_ZN4PLMD6Plumed13add_buffer_toISt10bad_typeidE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt8bad_castE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9bad_allocE4initEPKc0
_ZN4PLMD6Plumed13add_buffer_toISt9exceptionE4initEPKc0
_ZN4PLMD6Plumed14plumed_cmd_cxxIP19ompi_communicator_tEEv6plumedPKcPT_P12plumed_error340
_ZN4PLMD6Plumed14plumed_cmd_cxxIPcEEv6plumedPKcPT_P12plumed_error4144
_ZN4PLMD6Plumed14plumed_cmd_cxxIiEEv6plumedPKcPT_P12plumed_error8288
_ZN4PLMD6Plumed15LeptonExceptionC2EPKc0
_ZN4PLMD6Plumed18exception_dispatchINS0_14rethrow_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18exception_dispatchINS0_18rethrow_not_nestedEEEvR12plumed_errorT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt10bad_typeidEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt13bad_exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt8bad_castEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9bad_allocEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_13add_buffer_toISt9exceptionEEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionDebugEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_14ExceptionErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_15LeptonExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_18ExceptionTypeErrorEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_7InvalidEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINS0_9ExceptionEEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclINSt8ios_base7failureB5cxx11EEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11logic_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt11range_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12domain_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12length_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt12out_of_rangeEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt13runtime_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt14overflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt15underflow_errorEEvRKT_0
_ZN4PLMD6Plumed18rethrow_not_nestedclISt16invalid_argumentEEvRKT_0
_ZN4PLMD6Plumed21finalize_plumed_errorD2Ev0
_ZN4PLMD6Plumed7rethrowER12plumed_error0
_ZN4PLMD6Plumed7rethrowEv0
_ZN4PLMD6Plumed8cmd_privE6plumedPKcPNS0_7SafePtrEPKvP12plumed_error12772
_ZN4PLMD6Plumed9ExceptionC2EPKc0
_ZN4PLMDL27PlumedGetenvExceptionsDebugEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt8bad_castE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9bad_allocE4whatEv0
_ZNK4PLMD12_GLOBAL__N_16Plumed13add_buffer_toISt9exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt10bad_typeidE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt13bad_exceptionE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt8bad_castE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt9bad_allocE4whatEv0
_ZNK4PLMD6Plumed13add_buffer_toISt9exceptionE4whatEv0
_ZNK4PLMD6Plumed15LeptonException4whatEv0
_ZNK4PLMD6Plumed9Exception4whatEv0
plumed_attempt_dlopen8
plumed_c2f56
plumed_c2v2
plumed_cmd357
plumed_cmd_nothrow0
plumed_cmd_safe95
plumed_cmd_safe_nothrow14135
plumed_create700214
plumed_create_dlopen8
plumed_create_dlopen28
plumed_create_dlsym8
plumed_create_invalid2
plumed_create_reference7504672
plumed_create_reference_f8
plumed_create_reference_v2
plumed_f2c373
plumed_f_cmd60
plumed_f_cmd_59
plumed_f_cmd__40
plumed_f_cmd_static279
plumed_f_create6
plumed_f_create_4
plumed_f_create__2
plumed_f_create_dlopen1
plumed_f_create_dlopen_1
plumed_f_create_dlopen__1
plumed_f_create_dlopen_static6
plumed_f_create_invalid0
plumed_f_create_invalid_0
plumed_f_create_invalid__0
plumed_f_create_invalid_static0
plumed_f_create_reference1
plumed_f_create_reference_1
plumed_f_create_reference__1
plumed_f_create_reference_static6
plumed_f_create_static18
plumed_f_finalize8
plumed_f_finalize_6
plumed_f_finalize__4
plumed_f_finalize_static30
plumed_f_gcmd10
plumed_f_gcmd_28
plumed_f_gcmd__10
plumed_f_gcmd_static78
plumed_f_gcreate3
plumed_f_gcreate_3
plumed_f_gcreate__2
plumed_f_gcreate_static14
plumed_f_gfinalize3
plumed_f_gfinalize_3
plumed_f_gfinalize__2
plumed_f_gfinalize_static14
plumed_f_ginitialized3
plumed_f_ginitialized_3
plumed_f_ginitialized__3
plumed_f_ginitialized_static18
plumed_f_global19
plumed_f_global_1
plumed_f_global__1
plumed_f_global_static24
plumed_f_gvalid1
plumed_f_gvalid_1
plumed_f_gvalid__1
plumed_f_gvalid_static6
plumed_f_installed1
plumed_f_installed_1
plumed_f_installed__1
plumed_f_installed_static6
plumed_f_safeptr_char20
plumed_f_safeptr_char_scalar0
plumed_f_safeptr_double16
plumed_f_safeptr_double_scalar3
plumed_f_safeptr_float1
plumed_f_safeptr_float_scalar0
plumed_f_safeptr_int6
plumed_f_safeptr_int_scalar13
plumed_f_safeptr_long0
plumed_f_safeptr_long_double0
plumed_f_safeptr_long_double_scalar0
plumed_f_safeptr_long_scalar0
plumed_f_safeptr_ptr24
plumed_f_safeptr_ptr_scalar0
plumed_f_safeptr_short0
plumed_f_safeptr_short_scalar0
plumed_f_use_count3
plumed_f_use_count_3
plumed_f_use_count__3
plumed_f_use_count_static18
plumed_f_valid0
plumed_f_valid_0
plumed_f_valid__0
plumed_f_valid_static0
plumed_finalize8421090
plumed_free720030
plumed_gcmd78
plumed_gcmd_safe0
plumed_gcreate22
plumed_gfinalize22
plumed_ginitialized24
plumed_global41
plumed_gvalid8
plumed_installed9
plumed_kernel_register20
plumed_malloc699554
plumed_malloc_pimpl699993
plumed_retrieve_functions684064
plumed_search_symbols8
plumed_symbol_table_reexport658609
plumed_use_count42
plumed_v2c2
plumed_valid23
+
+
+ + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/Plumed.h.gcov.html b/coverage/wrapper/Plumed.h.gcov.html new file mode 100644 index 000000000000..3fc0527f4c74 --- /dev/null +++ b/coverage/wrapper/Plumed.h.gcov.html @@ -0,0 +1,4478 @@ + + + + + + + + LCOV - plumed test coverage - wrapper/Plumed.h + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapper - Plumed.h (source / functions)HitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-02-22 21:58:45Functions:14425456.7 %
+
+ + + + + + + + +

+
          Line data    Source code
+
+       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+       2             :    Copyright (c) 2011-2023 The plumed team
+       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
+       4             : 
+       5             :    See http://www.plumed.org for more information.
+       6             : 
+       7             :    This file is part of plumed, version 2.
+       8             : 
+       9             :    plumed is free software: you can redistribute it and/or modify
+      10             :    it under the terms of the GNU Lesser General Public License as published by
+      11             :    the Free Software Foundation, either version 3 of the License, or
+      12             :    (at your option) any later version.
+      13             : 
+      14             :    plumed is distributed in the hope that it will be useful,
+      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
+      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+      17             :    GNU Lesser General Public License for more details.
+      18             : 
+      19             :    You should have received a copy of the GNU Lesser General Public License
+      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
+      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
+      22             : #ifndef __PLUMED_wrapper_Plumed_h
+      23             : #define __PLUMED_wrapper_Plumed_h
+      24             : 
+      25             : /*
+      26             :   This header might be included more than once in order to provide
+      27             :   the declarations and the definitions. The guard is thus closed before the end of the file
+      28             :   (match this brace) {
+      29             :   and a new guard is added for the definitions.
+      30             : */
+      31             : 
+      32             : /**
+      33             : \page ReferencePlumedH Reference for interfacing MD codes with PLUMED
+      34             : 
+      35             :   Plumed.h and Plumed.c contain the external plumed interface, which is used to
+      36             :   integrate it with MD engines. This interface is very general, and is expected
+      37             :   not to change across plumed versions. Plumed.c also implements a dummy version
+      38             :   of the interface, so as to allow a code to be fully linked even if the plumed
+      39             :   library is not available yet. These files could be directly included in the official
+      40             :   host MD distribution. In this manner, it will be sufficient to link the plumed
+      41             :   library at link time (on all systems) or directly at runtime (on systems where
+      42             :   dynamic loading is enabled) to include plumed features.
+      43             : 
+      44             :   Notice that in PLUMED 2.5 this interface has been rewritten in order to allow
+      45             :   more debugging features and a better behavior in multithread environments.
+      46             :   The interface is almost perfectly backward compatible, although it implements
+      47             :   a few additional functions. See more details below.
+      48             : 
+      49             :   A further improvement has been made in PLUMED 2.8, where the interface has
+      50             :   been modified to allow dynamic type checking. See more details below.
+      51             : 
+      52             :   Why is Plumed.c written in C and not C++? The reason is that the resulting Plumed.o
+      53             :   needs to be linked with the host MD code immediately (whereas the rest of plumed
+      54             :   could be linked a posteriori). Imagine the MD code is written in FORTRAN: when we
+      55             :   link the Plumed.o file we would like not to need any C++ library linked. In this
+      56             :   manner, we do not need to know which C++ compiler will be used to compile plumed.
+      57             :   The C++ library is only linked to the "rest" of plumed, which actually uses it.
+      58             :   Anyway, Plumed.c is written in such a manner to allow its compilation also in C++
+      59             :   (C++ is a bit stricter than C). This will
+      60             :   allow e.g. MD codes written in C++ to just incorporate Plumed.c (maybe renamed into
+      61             :   Plumed.cpp), without the need of configuring a plain C compiler.
+      62             : 
+      63             :   Plumed interface can be used from C, C++ and FORTRAN. Everything concerning plumed
+      64             :   is hidden inside a single object type, which is described in C by a structure
+      65             :   (struct \ref plumed), in C++ by a class (PLMD::Plumed) and in FORTRAN by a
+      66             :   fixed-length string (CHARACTER(LEN=32)). Obviously C++ can use both struct
+      67             :   and class interfaces, but the second should be preferred since it will automatically take
+      68             :   care of objects constructions and destructions. The reference interface
+      69             :   is the C one, whereas FORTRAN and C++ interfaces are implemented as wrappers
+      70             :   around it.
+      71             :   In the C++ interface, all the routines are implemented as methods of PLMD::Plumed.
+      72             :   In the C and FORTRAN interfaces, all the routines are named plumed_*, to
+      73             :   avoid potential name clashes. Notice that the entire plumed library
+      74             :   is implemented in C++, and it is hidden inside the PLMD namespace.
+      75             : 
+      76             :   Handlers to the plumed object can be converted among different representations,
+      77             :   to allow inter-operability among languages. In C, there are tools to convert
+      78             :   to/from FORTRAN, whereas in C++ there are tools to convert to/from FORTRAN and C.
+      79             : 
+      80             :   These handlers only contain a pointer to the real structure, so that
+      81             :   when a plumed object is brought from one language to another,
+      82             :   it brings a reference to the same environment.
+      83             : 
+      84             :   Moreover, to simplify life in all cases where a single Plumed object is
+      85             :   required for the entire simulation (which covers many of the practical
+      86             :   applications with conventional MD codes) it is possible to take advantage
+      87             :   of a global interface, which is implicitly referring to a unique global instance.
+      88             :   The global object should still be initialized and finalized properly.
+      89             :   This global object is obviously not usable in a multithread context. In addition,
+      90             :   it is difficult to use it in an exception-safe manner, so its usage in C++ is
+      91             :   allowed but discouraged.
+      92             : 
+      93             :   As of PLUMED 2.5, the interface contains a reference counter that allows
+      94             :   for a better control of plumed initializations and deallocations.
+      95             :   This is particularly useful for the C++ interface that now
+      96             :   behaves similarly to a primitive shared pointer and can be thus copied.
+      97             :   In other languages, to use the reference counter correctly it is sufficient to
+      98             :   remember the following rule: for any `plumed_create*` call, there should be a corresponding
+      99             :   `plumed_finalize` call. More examples can be found below.
+     100             : 
+     101             :   Notice that up to PLUMED 2.8 the reference counter was not thread safe. This is fixed
+     102             :   when using PLUMED>=2.9 wrappers with a PLUMED>=2.9 kernel.
+     103             : 
+     104             :   The basic method to send a message to plumed is
+     105             : \verbatim
+     106             :   (C) plumed_cmd
+     107             :   (C++) PLMD::Plumed::cmd
+     108             :   (FORTRAN)  PLUMED_F_CMD
+     109             : \endverbatim
+     110             : 
+     111             :   To initialize a plumed object, use:
+     112             : \verbatim
+     113             :   (C)        plumed_create
+     114             :   (C++)      (constructor of PLMD::Plumed)
+     115             :   (FORTRAN)  PLUMED_F_CREATE
+     116             : \endverbatim
+     117             : 
+     118             :   As of PLUMED 2.5, you can also initialize a plumed object using the following functions,
+     119             :   that load a specific kernel. The function plumed_create_dlopen2 allows to specify options
+     120             :   for dlopen. The C++ version accepts an optional argument to this aim.
+     121             : \verbatim
+     122             :   (C)        plumed_create_dlopen or plumed_create_dlopen2
+     123             :   (C++)      PLMD::Plumed::dlopen
+     124             :   (FORTRAN)  PLUMED_F_CREATE_DLOPEN
+     125             : \endverbatim
+     126             : 
+     127             :   As of PLUMED 2.8, you can also initialize a plumed object using the following function,
+     128             :   that loads a kernel from an already loaded shared library. It accepts a handler
+     129             :   returned by `dlopen`:
+     130             : \verbatim
+     131             :   (C)        plumed_create_dlsym
+     132             :   (C++)      PLMD::Plumed::dlsym
+     133             :   (FORTRAN not allowed)
+     134             : \endverbatim
+     135             : 
+     136             :   To finalize a plumed object, use
+     137             : \verbatim
+     138             :   (C)        plumed_finalize
+     139             :   (C++)      (destructor of PLMD::Plumed)
+     140             :   (FORTRAN)  PLUMED_F_FINALIZE
+     141             : \endverbatim
+     142             : 
+     143             :   To access to the global-object, use
+     144             : \verbatim
+     145             :   (C)        plumed_gcreate, plumed_gfinalize, plumed_gcmd
+     146             :   (C++)      PLMD::Plumed::gcreate, PLMD::Plumed::gfinalize, PLMD::Plumed::gcmd
+     147             :   (FORTRAN)  PLUMED_F_GCREATE, PLUMED_F_GFINALIZE, PLUMED_F_GCMD
+     148             : \endverbatim
+     149             : 
+     150             :   To check if the global object has been initialized, use
+     151             : \verbatim
+     152             :   (C)        plumed_ginitialized
+     153             :   (C++)      PLMD::Plumed::ginitialized
+     154             :   (FORTRAN)  PLUMED_F_GINITIALIZED
+     155             : \endverbatim
+     156             : 
+     157             :   Notice that when using runtime binding the plumed library might be not available.
+     158             :   In this case, plumed_create (and plumed_gcreate) will still succeed, but a subsequent
+     159             :   call to plumed_cmd (or plumed_gcmd) would exit. In order to avoid this
+     160             :   unpleasant situation you have two options.
+     161             : 
+     162             :   First, you can check if plumed library is available before actually creating an object
+     163             :   using this function:
+     164             : \verbatim
+     165             :   (C)        plumed_installed
+     166             :   (C++)      PLMD::Plumed::installed
+     167             :   (FORTRAN)  PLUMED_F_INSTALLED
+     168             : \endverbatim
+     169             : 
+     170             :   Alternatively, as of PLUMED 2.5, you can interrogate the just created plumed
+     171             :   object using the following function:
+     172             : \verbatim
+     173             :   (C)        plumed_valid
+     174             :   (C++)      PLMD::Plumed::valid
+     175             :   (FORTRAN)  PLUMED_F_VALID
+     176             : \endverbatim
+     177             : 
+     178             :   If you want to create on purpose an invalid Plumed object (useful in C++ to postpone
+     179             :   the loading of the library) you can use `Plumed p(Plumed::makeInvalid());`.
+     180             : 
+     181             :   To know if the global object is valid instead you should use the following function:
+     182             : \verbatim
+     183             :   (C)        plumed_gvalid
+     184             :   (C++)      PLMD::Plumed::gvalid
+     185             :   (FORTRAN)  PLUMED_F_GVALID
+     186             : \endverbatim
+     187             : 
+     188             :   To convert handlers between different languages, use
+     189             : \verbatim
+     190             :   (C)        plumed_c2f                 (C to FORTRAN)
+     191             :   (C)        plumed_f2c                 (FORTRAN to C)
+     192             :   (C++)      Plumed(plumed) constructor (C to C++)
+     193             :   (C++)      operator plumed() cast     (C++ to C)
+     194             :   (C++)      Plumed(char*)  constructor (FORTRAN to C++)
+     195             :   (C++)      toFortran(char*)           (C++ to FORTRAN)
+     196             : \endverbatim
+     197             : 
+     198             :   As of PLUMED 2.5, when using C or C++ we allow a user to explicitly store a plumed object as
+     199             :   a void pointer (indeed: that's the only thing contained in a plumed object).
+     200             :   This might be useful in case you do not want to include the Plumed.h header in some
+     201             :   of your headers. In order to convert to/from void pointers you can use the following functions
+     202             : \verbatim
+     203             :   (C)        plumed_v2c                 (void* to C)
+     204             :   (C)        plumed_c2v                 (C to void*)
+     205             :   (C++)      Plumed(void*) constructor  (void* to C++)
+     206             :   (C++)      toVoid()                   (C++ to void*)
+     207             : \endverbatim
+     208             :   Using the functions above is much safer than accessing directly the pointer contained in the \ref plumed struct
+     209             :   since, when compiling with debug options, it will check if the void pointer actually points to a plumed object.
+     210             : 
+     211             :   As of PLUMED 2.5, we added a reference count. It is in practice possible
+     212             :   to create multiple `plumed` objects that refer to the same environment.
+     213             :   This is done using the following functions
+     214             : \verbatim
+     215             :   (C)        plumed_create_reference     (from a C object)
+     216             :   (C)        plumed_create_reference_f   (from a FORTRAN object)
+     217             :   (C)        plumed_create_reference_v   (from a void pointer)
+     218             :   (FORTRAN)  plumed_f_create_reference   (from a FORTRAN object)
+     219             : \endverbatim
+     220             :   In C++ references are managed automatically by constructors and destructor.
+     221             :   In addition, you can manually manage them (with care!) using incref() and decref().
+     222             : 
+     223             :   The interface of the FORTRAN functions is very similar to that of the C functions
+     224             :   and is listed below:
+     225             : 
+     226             : \verbatim
+     227             :   FORTRAN interface
+     228             :     SUBROUTINE PLUMED_F_CREATE(p)
+     229             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     230             :     SUBROUTINE PLUMED_F_CREATE_DLOPEN(p,path)
+     231             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     232             :       CHARACTER(LEN=*),  INTENT(IN)    :: path
+     233             :     SUBROUTINE PLUMED_F_CREATE_REFERENCE(p,r)
+     234             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     235             :       CHARACTER(LEN=32), INTENT(IN)    :: r
+     236             :     SUBROUTINE PLUMED_F_CREATE_INVALID(p)
+     237             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     238             :     SUBROUTINE PLUMED_F_CMD(p,key,val)
+     239             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     240             :       CHARACTER(LEN=*),  INTENT(IN)    :: key
+     241             :       UNSPECIFIED_TYPE,  INTENT(INOUT) :: val(*)
+     242             :     SUBROUTINE PLUMED_F_FINALIZE(p)
+     243             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     244             :     SUBROUTINE PLUMED_F_INSTALLED(i)
+     245             :       INTEGER,           INTENT(OUT)   :: i
+     246             :     SUBROUTINE PLUMED_F_VALID(p,i)
+     247             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     248             :       INTEGER,           INTENT(OUT)   :: i
+     249             :     SUBROUTINE PLUMED_F_USE_COUNT(p,i)
+     250             :       CHARACTER(LEN=32), INTENT(IN)    :: p
+     251             :       INTEGER,           INTENT(OUT)   :: i
+     252             :     SUBROUTINE PLUMED_F_GLOBAL(p)
+     253             :       CHARACTER(LEN=32), INTENT(OUT)   :: p
+     254             :     SUBROUTINE PLUMED_F_GINITIALIZED(i)
+     255             :       INTEGER,           INTENT(OUT)   :: i
+     256             :     SUBROUTINE PLUMED_F_GCREATE()
+     257             :     SUBROUTINE PLUMED_F_GCMD(key,val)
+     258             :       CHARACTER(LEN=*), INTENT(IN)     :: key
+     259             :       UNSPECIFIED_TYPE, INTENT(INOUT)  :: val(*)
+     260             :     SUBROUTINE PLUMED_F_GFINALIZE()
+     261             :     SUBROUTINE PLUMED_F_GVALID(i)
+     262             :       INTEGER,           INTENT(OUT)   :: i
+     263             : \endverbatim
+     264             : 
+     265             :   Almost all C functions have a corresponding FORTRAN function.
+     266             :   As a simple mnemonic, if you know the name of the C function you can obtain the
+     267             :   corresponding FORTRAN subroutine by adding `F_` after the `PLUMED_` prefix.
+     268             :   In addition, all `plumed` objects are replaced by `CHARACTER(LEN=32)` objects
+     269             :   holding the same information. These pointers basically contain a text representation
+     270             :   of the stored pointer, that is suitable to be contained in a string.
+     271             :   Finally, whenever a C function returns a value,
+     272             :   the corresponding FORTRAN subroutine will have an additional `INTENT(OUT)` parameter
+     273             :   passed as the its last argument.
+     274             : 
+     275             :   When you compile the FORTRAN interface, wrapper functions are added with several possible
+     276             :   name manglings, so you should not experience problems linking the plumed library with a FORTRAN file.
+     277             : 
+     278             : \section ReferencePlumedH-exceptions Error handling
+     279             : 
+     280             :   In case an error is detected by PLUMED, either because of some user error, some internal bug,
+     281             :   or some mistake in using the library, an exception will be thrown. The behavior is different depending if you use
+     282             :   PLUMED from C/FORTRAN or from C++.
+     283             : 
+     284             :   First of all, notice that access to PLUMED goes through three functions:
+     285             :   - plumed_create: this, as of PLUMED 2.5, is guaranteed not to throw any exception. If there is a problem, it will
+     286             :     just return a plumed object containing a NULL pointer
+     287             :   - plumed_cmd: this function might throw exceptions.
+     288             :   - plumed_finalize: this is a destructor and is guaranteed not to throw any exception.
+     289             : 
+     290             :   The following discussion concerns all the exceptions thrown by plumed_cmd.
+     291             : 
+     292             :   If you use C/FORTRAN, you will basically have no way to intercept the exception and the program will just terminate.
+     293             : 
+     294             :   If you use C++ and you are calling the C++ interface (e.g. \ref Plumed::cmd), as of PLUMED 2.5 we implemented a complete
+     295             :   remapping of the exceptions thrown by PLUMED.  This solves both the problems mentioned above. In particular:
+     296             :   - Instead of throwing an exception, PLUMED will return (using a \ref plumed_nothrow_handler) the details about the occurred error.
+     297             :   - An equivalent exception will be thrown within the inline PLUMED interface compiled with your MD code.
+     298             : 
+     299             :   As a consequence, you will be able to combine different compilers and avoid stack unwinding in the C layer.
+     300             : 
+     301             :   If you use C++ but you are calling the C interface (e.g. \ref plumed_cmd), then you might be
+     302             :   able to catch the exceptions thrown by PLUMED. Notice that all the exceptions thrown by PLUMED inherit from std::exception,
+     303             :   so you might want to catch it by reference. By default, as of PLUMED 2.8 \ref plumed_cmd is redefined as a macro and directly calls
+     304             :   the \ref Plumed::cmd interface, and thus behaves in an equivalent manner. With previous versions of this header
+     305             :   one could have encountered problems with stack unwinding performed during exception handling in the C layer.
+     306             : 
+     307             :   Notice that, even if you use \ref Plumed::cmd, if you are loading a kernel <=2.4 any exception generated by PLUMED will
+     308             :   leak through the C layer. This might lead to undefined behavior. If you are lucky (with some compiler it works!) and
+     309             :   the exception arrives to C, PLUMED will catch it and rethrow it as it would do if you were using a kernel >=2.5.
+     310             : 
+     311             :   The remapping of exceptions takes care of all the standard C++ exceptions plus all the exceptions raised within
+     312             :   PLUMED. Unexpected exceptions that are derived from std::exception will be rethrown as std::exception.
+     313             :   Notice that this implies some loss of information, since the original exception might have been of a different type.
+     314             :   However, it also implies that the virtual table of the original exception won't be needed anymore. This allows to
+     315             :   completely decouple the MD code from the PLUMED library.
+     316             : 
+     317             : \section ReferencePlumedH-typesafe Typesafe interface
+     318             : 
+     319             :   Starting with PLUMED 2.8, the `cmd` function of the C++ interface, and the similar function `gcmd`, can be called
+     320             :   with several interfaces and can perform a typechecking on the passed argument. In particular, the following
+     321             :   forms are now possible:
+     322             : \verbatim
+     323             :   cmd("string",value);        // by value
+     324             :   cmd("string",&value);       // by pointer
+     325             :   cmd("string",&value,nelem); // by pointer, specifying the number of elements of the passed array
+     326             :   cmd("string",&value,shape); // by pointer, specifying the shape of the passed array
+     327             : \endverbati
+     328             :   The `nelem` and `shape` arguments are used by PLUMED to check that the user
+     329             :   provided enough elements. If nelem is provided, the check is done on the flatten array, whereas if shape
+     330             :   is passed a more thorough check is performed controlling each of the dimensions of the array.
+     331             :   In addition to this, the type of the pointer (or of the value) is checked at runtime.
+     332             : 
+     333             :   All these checks are only implemented if the PLUMED library is recent (>=2.8). However, it will still be
+     334             :   possible to load at runtime an older PLUMED library (<=2.7). For this reason, it is still compulsory
+     335             :   to pass the correct types to the `cmd` function, also when the argument is passed by value.
+     336             :   Type conversions are only performed between pointers and only in ways compatible with
+     337             :   what is allowed in C++ (e.g., `const void*` cannot be converted to `void*`, but `void*` can
+     338             :   be converted to `const void*`).
+     339             : 
+     340             :   Type checkes can be disabled in two ways:
+     341             :   - By compiling `Plumed.h` with `-D__PLUMED_WRAPPER_CXX_TYPESAFE=0`
+     342             :   - By setting `export PLUMED_TYPESAFE_IGNORE=yes` at runtime.
+     343             : 
+     344             :   Typechecks are also enabled in the C interface (plumed_cmd). This function is replaced with a macro by default.
+     345             :   In particular:
+     346             :   - If the C interface is used in C++ code, it calls the C++ interface. Can be disabled with `-D__PLUMED_WRAPPER_CXX_BIND_C=0`.
+     347             :   - If the C interface is used in C code and compiled with a C11 compiler, it uses _Generic to pass type information.
+     348             :     Can be disabled using `-D__PLUMED_WRAPPER_C_TYPESAFE=0`.
+     349             : 
+     350             : \section ReferencePlumedH-2-5 New in PLUMED 2.5
+     351             : 
+     352             :   The wrappers in PLUMED 2.5 have been completely rewritten with several improvements.
+     353             :   The interface is almost perfectly backward compatible, although the behavior of C++ constructors
+     354             :   has been modified slightly.
+     355             :   In addition, a few new functions are introduced (explicitly marked in the documentation).
+     356             :   As a consequence, if your code uses some of the new functions, you will not be able
+     357             :   to link it directly with an older PLUMED library (though you will still be able to load
+     358             :   an older PLUMED library at runtime). In addition, the reference counter changes slightly
+     359             :   the behavior of the C++ methods used to interoperate with C and FORTRAN.
+     360             : 
+     361             :   An important novelty is in the way the runtime loader is implemented.
+     362             :   In particular, the loader works also if the symbols of the main executable are not exported.
+     363             :   The proper functions from the kernel are indeed searched explicitly now using `dlsym`.
+     364             : 
+     365             :   Some additional features can be enabled using suitable environment variables. In particular:
+     366             :   - `PLUMED_LOAD_DEBUG` can be set to report more information about the loading process.
+     367             :   - `PLUMED_LOAD_NAMESPACE` can be set to choose in which namespace PLUMED is loaded when using runtime
+     368             :     loading. As of version 2.10, PLUMED is loaded with RTLD_LOCAL by default. The behavior can be reverted
+     369             :     by exporting `PLUMED_LOAD_NAMESPACE=GLOBAL`. The default setting facilitates loading multiple
+     370             :     versions of PLUMED simultaneously.
+     371             :   - `PLUMED_LOAD_NODEEPBIND` can be set to load the PLUMED kernel in not-deepbind mode. Deepbind
+     372             :     mode implies that the symbols defined in the library are preferred to other symbols with the same name.
+     373             :     Only works on systems supporting `RTLD_DEEPBIND` and is mostly for debugging purposes.
+     374             : 
+     375             :   Another difference is that the implementation of the wrappers is now completely contained in the `Plumed.h`
+     376             :   file. You can see that the `Plumed.c` is much simpler now and just includes `Plumed.h`. With a similar
+     377             :   procedure you could compile the wrappers directly into your code making it unnecessary to link
+     378             :   the libplumedWrapper.a library. The corresponding macros are still subject to change and are not documented here.
+     379             : 
+     380             :   As written above, the plumed object now implements a reference counter.  Consider the following example
+     381             : \verbatim
+     382             :   plumed p=plumed_create();
+     383             :   plumed_cmd(p,"init",NULL);
+     384             :   plumed q=plumed_create_reference(p);
+     385             :   plumed_finalize(p);
+     386             : // at this stage, object q still exists
+     387             :   plumed_cmd(q,"whatever",NULL);
+     388             :   plumed_finalize(q);
+     389             : // now plumed has been really finalized
+     390             : \endverbatim
+     391             : 
+     392             :   In other words, every \ref plumed_create, \ref plumed_create_dlopen, \ref plumed_create_reference,
+     393             :   \ref plumed_create_reference_f, and \ref plumed_create_reference_v call must be matched by a \ref plumed_finalize.
+     394             :   Notice that in C++ whenever an object goes out of scope the reference counter
+     395             :   will be decreased. In addition, consider that conversion from C/FORTRAN/void* to C++ implies calling a C++ constructor, that
+     396             :   is increases the number of references by one. Converting from C++ to C/FORTRAN/void* instead does not call any constructor,
+     397             :   that is the number of references is unchanged.
+     398             : 
+     399             :   The change in the behavior of C++ constructors means that the following code will behave in a backward incompatible manner:
+     400             : \verbatim
+     401             :   plumed p=plumed_create();
+     402             :   plumed_cmd(p,"init",NULL);
+     403             :   Plumed q(p);
+     404             :   plumed_finalize(p);
+     405             : // at this stage, object q still exists with PLUMED 2.5
+     406             : // on the other hand, with PLUMED 2.4 object q refers to an
+     407             : // already finalized object
+     408             :   q.cmd("whatever",NULL);
+     409             : \endverbatim
+     410             : 
+     411             :   Another difference is that the value of the variable `PLUMED_KERNEL` is read every time a new
+     412             :   plumed object is instantiated. So, you might even use it to load different plumed versions
+     413             :   simultaneously, although the preferred way to do this is using the function \ref plumed_create_dlopen.
+     414             :   Notice that if you want to load multiple versions simultaneously you should load them in a local namespace.
+     415             :   \ref plumed_create_dlopen does it automatically, whereas loading through env var `PLUMED_KERNEL` only does it if
+     416             :   you also set env var `PLUMED_NAMESPACE=LOCAL`.
+     417             : 
+     418             :   Finally, a few functions have been added, namely:
+     419             :   - Functions to find if a plumed object is valid
+     420             :     (\ref plumed_valid(), \ref plumed_gvalid(), \ref PLMD::Plumed::valid(), and \ref PLMD::Plumed::gvalid()).
+     421             :   - Functions to create a plumed object based on the path of a specific kernel
+     422             :     (\ref plumed_create_dlopen() and \ref PLMD::Plumed::dlopen()).
+     423             :   - Functions to create a plumed object referencing to another one, implementing a reference counter
+     424             :     (\ref plumed_create_reference(), \ref plumed_create_reference_v(), \ref plumed_create_reference_f().
+     425             : 
+     426             : */
+     427             : 
+     428             : 
+     429             : /* BEGINNING OF DECLARATIONS */
+     430             : 
+     431             : /* SETTING DEFAULT VALUES FOR CONTROL MACROS */
+     432             : 
+     433             : /*
+     434             :   1: make the C wrapper functions extern (default)
+     435             :   0: make the C wrapper functions static (C) or inline (C++)
+     436             : 
+     437             :   If set to zero, it disables all functions that only make sense as extern, such as
+     438             :   Fortran wrappers, global objects, and plumed_kernel_register.
+     439             : 
+     440             :   It can be set to zero to include multiple copies of the wrapper implementation without worrying
+     441             :   about duplicated symbols.
+     442             : 
+     443             :   Notice that C++ wrappers are always inline. What this function controls is if the C wrappers
+     444             :   (called by the C++ wrappers) is inline or not. Also consider that if this header is compiled
+     445             :   with C++ and inline C wrappers, the C wrappers will be actually compiled with C++ linkage
+     446             :   in the root namespace.
+     447             : 
+     448             :   Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
+     449             : */
+     450             : 
+     451             : #ifndef __PLUMED_WRAPPER_EXTERN
+     452             : #define __PLUMED_WRAPPER_EXTERN 1
+     453             : #endif
+     454             : 
+     455             : /*
+     456             :   1: emit global plumed object and related functions (default)
+     457             :   0: do not emit global plumed object and related functions
+     458             : 
+     459             :   Used both in declarations (to know which functions to declare) and definitions (to know which functions to define).
+     460             : */
+     461             : 
+     462             : #ifndef __PLUMED_WRAPPER_GLOBAL
+     463             : #define __PLUMED_WRAPPER_GLOBAL 1
+     464             : #endif
+     465             : 
+     466             : /*
+     467             :   1: Enable typesafe C interface (default)
+     468             :   0: Disable typesafe C interface
+     469             : 
+     470             :   Only used in declarations. Requires C11 _Generic and variadic macros, and so it is
+     471             :   disabled by default with C++ and pre C11 compilers.
+     472             : 
+     473             :   https://mort.coffee/home/c-compiler-quirks/
+     474             : */
+     475             : 
+     476             : #ifndef __PLUMED_WRAPPER_C_TYPESAFE
+     477             : #  if defined(__STDC_VERSION__)
+     478             : #    if ! defined(__cplusplus) && __STDC_VERSION__ >= 201112L
+     479             : #      if defined(__GNUC__) && !defined(__clang__)
+     480             : #        if (__GNUC__ >= 5 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 9))
+     481             : #          define __PLUMED_WRAPPER_C_TYPESAFE 1
+     482             : #        endif
+     483             : #      else
+     484             : #        define __PLUMED_WRAPPER_C_TYPESAFE 1
+     485             : #      endif
+     486             : #    endif
+     487             : #  endif
+     488             : #  ifndef __PLUMED_WRAPPER_C_TYPESAFE
+     489             : #    define __PLUMED_WRAPPER_C_TYPESAFE 0
+     490             : #  endif
+     491             : #endif
+     492             : 
+     493             : /*
+     494             :   1: Enable RTLD_DEEPBIND when possible (default)
+     495             :   0: Disable RTLD_DEEPBIND
+     496             : */
+     497             : 
+     498             : #ifndef __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+     499             : #define __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND 1
+     500             : #endif
+     501             : 
+     502             : /*
+     503             :   1: enable C++ wrapper (default)
+     504             :   0: disable C++ wrapper
+     505             : 
+     506             :   Only used in declarations, but affects the scope of the C interface also in definitions.
+     507             : */
+     508             : 
+     509             : #ifndef __PLUMED_WRAPPER_CXX
+     510             : #define __PLUMED_WRAPPER_CXX 1
+     511             : #endif
+     512             : 
+     513             : /*
+     514             :   1: new headers such as cstdlib are included in C++ (default)
+     515             :   0: old headers such as stdlib.h are included in C++
+     516             : 
+     517             :   Should only be set to zero when including the Plumed.h file in a file using the
+     518             :   old (stdlib.h) convention.
+     519             : 
+     520             :   Used both in declarations and definitions.
+     521             : */
+     522             : 
+     523             : #ifndef __PLUMED_WRAPPER_CXX_STD
+     524             : #define __PLUMED_WRAPPER_CXX_STD 1
+     525             : #endif
+     526             : 
+     527             : /*
+     528             :   1: place C++ wrappers in an anonymous namespace
+     529             :   0: place C++ wrappers in the PLMD namespace (default)
+     530             : 
+     531             :   It will make PLMD::Plumed a different class (though with the same name)
+     532             :   in each of the translation units in which `Plumed.h` is included.
+     533             : 
+     534             :   Can be used to completey separate C++ implementations. However, it will make
+     535             :   it impossible to transfer Plumed objects between different translation units
+     536             :   without converting to a void* or plumed object.
+     537             : 
+     538             :   Only used in declarations, but affects the scope of the C interface also in definitions.
+     539             : */
+     540             : 
+     541             : #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE
+     542             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE 0
+     543             : #endif
+     544             : 
+     545             : 
+     546             : /*
+     547             :   1: throw exceptions such as PLMD::Exception
+     548             :   0: throw exceptions such as PLMD::Plumed::Exception (default)
+     549             : 
+     550             :   This is useful when including Plumed.h within the plumed library
+     551             :   in anonymous mode, to make sure that the exception types from the
+     552             :   library are used.
+     553             : */
+     554             : #ifndef __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+     555             : #define __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS 0
+     556             : #endif
+     557             : 
+     558             : /*
+     559             :   1: make PLMD::Plumed class polymorphic (default)
+     560             :   0: make PLMD::Plumed class non-polymorphic
+     561             : 
+     562             :   Only used in declarations.
+     563             : */
+     564             : 
+     565             : #ifndef __PLUMED_WRAPPER_CXX_POLYMORPHIC
+     566             : #define __PLUMED_WRAPPER_CXX_POLYMORPHIC 1
+     567             : #endif
+     568             : 
+     569             : /*
+     570             :   1: Enable typesafe interface (default)
+     571             :   0: Disable typesafe interface
+     572             : 
+     573             :   Only used in declarations.
+     574             : */
+     575             : 
+     576             : #ifndef __PLUMED_WRAPPER_CXX_TYPESAFE
+     577             : #define __PLUMED_WRAPPER_CXX_TYPESAFE 1
+     578             : #endif
+     579             : 
+     580             : /*
+     581             :   1: Define macros plumed_cmd and plumed_gcmd to use the C++ interface (default).
+     582             :   0: Don't define macros plumed_cmd and plumed_gcmd.
+     583             : 
+     584             :   Only used in declarations.
+     585             : */
+     586             : 
+     587             : #ifndef __PLUMED_WRAPPER_CXX_BIND_C
+     588             : #define __PLUMED_WRAPPER_CXX_BIND_C 1
+     589             : #endif
+     590             : 
+     591             : /*
+     592             :   1: Enable passing long long int
+     593             :   0: Disable passing long long int
+     594             : 
+     595             :   Only used in declarations. Default is 0 in C++<11 and 1 in C++>=11
+     596             : */
+     597             : 
+     598             : #ifndef __PLUMED_WRAPPER_CXX_LONGLONG
+     599             : #if __cplusplus > 199711L
+     600             : #define __PLUMED_WRAPPER_CXX_LONGLONG 1
+     601             : #else
+     602             : #define __PLUMED_WRAPPER_CXX_LONGLONG 0
+     603             : #endif
+     604             : #endif
+     605             : 
+     606             : /*
+     607             :   1: make the default constructor create an invalid object
+     608             :   0: make the default constructor create a valid object
+     609             : 
+     610             :   Only for internal usage.
+     611             : */
+     612             : #ifndef __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
+     613             : #define __PLUMED_WRAPPER_CXX_DEFAULT_INVALID 0
+     614             : #endif
+     615             : 
+     616             : /*
+     617             :   Size of a buffer used to store message for exceptions with noexcept constructor.
+     618             :   Should typically hold short messages. Anyway, as long as the stack size stays within the correct
+     619             :   limits it does not seem to affect efficiency. Notice that there cannot be recursive calls of
+     620             :   PLMD::Plumed::cmd, so that it should be in practice irrelevant.
+     621             : */
+     622             : #ifndef __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER
+     623             : #define __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER 512
+     624             : #endif
+     625             : 
+     626             : /*
+     627             :   1: enable nested exceptions (only with C++11) (default)
+     628             :   0: disable nested exceptions
+     629             : 
+     630             :   For internal testing, used to mimic pre C++11 behavior on
+     631             :   nested exception.
+     632             : 
+     633             :   Only used in declarations.
+     634             : */
+     635             : 
+     636             : #ifndef __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+     637             : #define __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS 1
+     638             : #endif
+     639             : 
+     640             : /*
+     641             :  By default, assume C++11 compliant library is not available.
+     642             : */
+     643             : 
+     644             : #ifndef __PLUMED_WRAPPER_LIBCXX11
+     645             : #define __PLUMED_WRAPPER_LIBCXX11 0
+     646             : #endif
+     647             : 
+     648             : /*
+     649             :  By default, assume C++17 compliant library is not available.
+     650             : */
+     651             : 
+     652             : #ifndef __PLUMED_WRAPPER_LIBCXX17
+     653             : #define __PLUMED_WRAPPER_LIBCXX17 0
+     654             : #endif
+     655             : 
+     656             : /* The following macros are just to define shortcuts */
+     657             : 
+     658             : /* Simplify addition of extern "C" blocks.  */
+     659             : #ifdef __cplusplus
+     660             : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN extern "C" {
+     661             : #define __PLUMED_WRAPPER_EXTERN_C_END }
+     662             : #else
+     663             : #define __PLUMED_WRAPPER_EXTERN_C_BEGIN
+     664             : #define __PLUMED_WRAPPER_EXTERN_C_END
+     665             : #endif
+     666             : 
+     667             : /* Without C++, stdlib functions should not be prepended with ::std:: */
+     668             : #ifndef __cplusplus
+     669             : #undef __PLUMED_WRAPPER_CXX_STD
+     670             : #define __PLUMED_WRAPPER_CXX_STD 0
+     671             : #endif
+     672             : 
+     673             : /* Set prefix for stdlib functions */
+     674             : #if __PLUMED_WRAPPER_CXX_STD
+     675             : #define __PLUMED_WRAPPER_STD ::std::
+     676             : #else
+     677             : #define __PLUMED_WRAPPER_STD
+     678             : #endif
+     679             : 
+     680             : /* Allow using noexcept, explicit, and override with C++11 compilers */
+     681             : #ifdef __cplusplus /*{*/
+     682             : #if __cplusplus > 199711L
+     683             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT noexcept
+     684             : #define __PLUMED_WRAPPER_CXX_NORETURN [[ noreturn ]]
+     685             : #define __PLUMED_WRAPPER_CXX_EXPLICIT explicit
+     686             : #define __PLUMED_WRAPPER_CXX_OVERRIDE override
+     687             : #define __PLUMED_WRAPPER_CXX_NULLPTR  nullptr
+     688             : #else
+     689             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT throw()
+     690             : #define __PLUMED_WRAPPER_CXX_NORETURN
+     691             : #define __PLUMED_WRAPPER_CXX_EXPLICIT
+     692             : #define __PLUMED_WRAPPER_CXX_OVERRIDE
+     693             : #define __PLUMED_WRAPPER_CXX_NULLPTR  NULL
+     694             : #endif
+     695             : #else
+     696             : #define __PLUMED_WRAPPER_CXX_NOEXCEPT
+     697             : #define __PLUMED_WRAPPER_CXX_NORETURN
+     698             : #define __PLUMED_WRAPPER_CXX_EXPLICIT
+     699             : #define __PLUMED_WRAPPER_CXX_OVERRIDE
+     700             : #define __PLUMED_WRAPPER_CXX_NULLPTR  NULL
+     701             : #endif /*}*/
+     702             : 
+     703             : /* static inline, for to avoid compiler warnings */
+     704             : #if defined(__cplusplus) || __STDC_VERSION__>=199901L
+     705             : #define __PLUMED_WRAPPER_STATIC_INLINE static inline
+     706             : #else
+     707             : #define __PLUMED_WRAPPER_STATIC_INLINE static
+     708             : #endif
+     709             : 
+     710             : /* Macros for anonymous namespace */
+     711             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE && defined(__cplusplus) /*{*/
+     712             : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN namespace {
+     713             : #define __PLUMED_WRAPPER_ANONYMOUS_END }
+     714             : #else
+     715             : #define __PLUMED_WRAPPER_ANONYMOUS_BEGIN
+     716             : #define __PLUMED_WRAPPER_ANONYMOUS_END
+     717             : #endif /*}*/
+     718             : 
+     719             : #if __PLUMED_WRAPPER_EXTERN /*{*/
+     720             : 
+     721             : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN extern
+     722             : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_EXTERN_C_END
+     723             : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_EXTERN_C_BEGIN static
+     724             : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_EXTERN_C_END
+     725             : 
+     726             : #else
+     727             : 
+     728             : #ifdef __cplusplus
+     729             : #define __PLUMED_WRAPPER_C_BEGIN  __PLUMED_WRAPPER_ANONYMOUS_BEGIN inline
+     730             : #define __PLUMED_WRAPPER_C_END __PLUMED_WRAPPER_ANONYMOUS_END
+     731             : #else
+     732             : #define __PLUMED_WRAPPER_C_BEGIN __PLUMED_WRAPPER_STATIC_INLINE
+     733             : #define __PLUMED_WRAPPER_C_END
+     734             : #endif
+     735             : 
+     736             : #define __PLUMED_WRAPPER_INTERNALS_BEGIN __PLUMED_WRAPPER_C_BEGIN
+     737             : #define __PLUMED_WRAPPER_INTERNALS_END __PLUMED_WRAPPER_C_END
+     738             : 
+     739             : /* with an not-external interface, it does not make sense to define global functions */
+     740             : #undef __PLUMED_WRAPPER_GLOBAL
+     741             : #define __PLUMED_WRAPPER_GLOBAL 0
+     742             : 
+     743             : #endif /*}*/
+     744             : 
+     745             : #if __PLUMED_WRAPPER_CXX_STD
+     746             : #include <cstddef> /* size_t */
+     747             : #include <cstring> /* memcpy */
+     748             : #include <cstdio> /* fprintf */
+     749             : #include <cstdlib> /* abort */
+     750             : #include <cassert> /* assert */
+     751             : #else
+     752             : #include <stddef.h>
+     753             : #include <string.h>
+     754             : #include <stdio.h> /* FILE and fprintf */
+     755             : #include <stdlib.h> /* abort */
+     756             : #include <limits.h> /* CHAR_MIN */
+     757             : #include <assert.h> /* assert */
+     758             : #endif
+     759             : 
+     760             : /**
+     761             :   This is an internal tool, to make sure that all malloc calls inside the
+     762             :   plumed library refer to the same implementation. When compiling with
+     763             :   __PLUMED_WRAPPER_DEBUG_REFCOUNT=1 it is possible to log
+     764             :   allocations and deallocations, so as to debug the wrappers.
+     765             : */
+     766             : __PLUMED_WRAPPER_C_BEGIN
+     767             : void* plumed_malloc(__PLUMED_WRAPPER_STD size_t size);
+     768             : __PLUMED_WRAPPER_C_END
+     769             : 
+     770             : /**
+     771             :   This is an internal tool, to make sure that all free calls inside the
+     772             :   plumed library refer to the same implementation. When compiling with
+     773             :   __PLUMED_WRAPPER_DEBUG_REFCOUNT=1 it is possible to log
+     774             :   allocations and deallocations, so as to debug the wrappers.
+     775             : */
+     776             : __PLUMED_WRAPPER_C_BEGIN
+     777             : void plumed_free(void* ptr);
+     778             : __PLUMED_WRAPPER_C_END
+     779             : 
+     780             : /**
+     781             :   \brief Main plumed object
+     782             : 
+     783             :   This is an object containing a Plumed instance, which should be used in
+     784             :   the MD engine. It should first be initialized with plumed_create(),
+     785             :   then it communicates with the MD engine using plumed_cmd(). Finally,
+     786             :   before the termination, it should be deallocated with plumed_finalize().
+     787             :   Its interface is very simple and general, and is expected
+     788             :   not to change across plumed versions. See \ref ReferencePlumedH.
+     789             : */
+     790             : typedef struct {
+     791             :   /**
+     792             :     \private
+     793             :     \brief Void pointer holding the real PlumedMain structure
+     794             : 
+     795             :     To maintain binary compatibility, we should not add members to this structure.
+     796             :     As of PLUMED 2.5, in order to add new components we do not store the pointer
+     797             :     to \ref PlumedMain here but rather a pointer to an intermediate private structure
+     798             :     that contains all the details.
+     799             :   */
+     800             :   void*p;
+     801             : } plumed;
+     802             : 
+     803             : typedef struct {
+     804             :   void* ptr;
+     805             :   void (*handler)(void*,int,const char*,const void*);
+     806             : } plumed_nothrow_handler;
+     807             : 
+     808             : /** \relates plumed
+     809             :     \brief Structure holding a typesafe pointer.
+     810             : */
+     811             : 
+     812             : typedef struct {
+     813             :   /** Pointer to data */
+     814             :   const void* ptr;
+     815             :   /** Number of elements (in case pointing to an array) */
+     816             :   __PLUMED_WRAPPER_STD size_t nelem;
+     817             :   /** Shape (scanned up to a zero value is found) */
+     818             :   const __PLUMED_WRAPPER_STD size_t* shape;
+     819             :   /**
+     820             :     sum of:
+     821             :     sizeof(pointed data), up to 0x10000 (65536). 0 means size not checked
+     822             :     0x10000    * data type, up to 0xff (255)
+     823             :                0 not typechecked
+     824             :                1 void
+     825             :                2 nullptr
+     826             :                3 integral
+     827             :                4 floating point
+     828             :                5 FILE (size will not be computed as it might be incomplete)
+     829             :                >5 not typechecked, reserved for future extensions
+     830             :     0x1000000  * 1 for unsigned (ignored)
+     831             :     0x2000000  * pointer/const type, up to 8
+     832             :                0 not typechecked
+     833             :                1 T (pass-by-value)
+     834             :                2 T       *
+     835             :                3 T const *
+     836             :                4 T       *       *
+     837             :                5 T       * const *
+     838             :                6 T const *       *
+     839             :                7 T const * const *
+     840             :     0x10000000 * 1 to forbid pointer copy (pointer copy is also forbidden for pass-by-value)
+     841             :     0x20000000 and higher bits are ignored, reserved for future extensions
+     842             :   */
+     843             :   __PLUMED_WRAPPER_STD size_t flags;
+     844             :   /** Optional information, not used yet  */
+     845             :   const void* opt;
+     846             : } plumed_safeptr;
+     847             : 
+     848             : /* local structure */
+     849             : typedef struct plumed_error_filesystem_path {
+     850             :   __PLUMED_WRAPPER_STD size_t numbytes;
+     851             :   void* ptr;
+     852             : } plumed_error_filesystem_path;
+     853             : 
+     854             : /**
+     855             :   Small structure that is only defined locally to retrieve errors.
+     856             : 
+     857             :   It is supposed to be used in the C11/C++ plumed_cmd interface as follows:
+     858             : \verbatim
+     859             :   plumed p;
+     860             :   plumed_error error;
+     861             : 
+     862             :   p=plumed_create();
+     863             : 
+     864             :   plumed_cmd(p,"setNatoms",10,&error);
+     865             :   if(error.code) {
+     866             :     fprintf(errors,"%d\n",error.code);
+     867             :     plumed_error_finalize(error); // make sure the error object is finalized!
+     868             :   }
+     869             :   // if no error was raised (error.code==0), it is not necessary to call plumed_error_finalize.
+     870             :   // but doing it is harmless
+     871             : 
+     872             :   // no need to initialize error, it is written in the plumed_cmd function
+     873             :   plumed_cmd(p,"init",&error);
+     874             :   if(error.code) {
+     875             :     fprintf(errors,"%d\n",error.code);
+     876             :     plumed_error_finalize(error); // make sure the error object is finalized!
+     877             :   }
+     878             : \endverbatim
+     879             : 
+     880             :   The layout of this structure is subject to change, thus all the functions manipulating it
+     881             :   are defined as inline/static functions. In the future, we might reach some form
+     882             :   of ABI stability, and these functions might be moved below to the implementation
+     883             :   file.
+     884             : 
+     885             :   Notice that there is a macro plumed_error() defined in the PLUMED source code
+     886             :   (at tools/Exception.h). There is no conflict with this type since C preprocessor
+     887             :   distinguishes macros and function-like macros.
+     888             : */
+     889             : typedef struct plumed_error {
+     890             :   /** code used for translating messages */
+     891             :   int code;
+     892             :   /** error code for system_error */
+     893             :   int error_code;
+     894             :   /** category - for errors */
+     895             :   int error_category;
+     896             :   /** path1 - for filesystem_error */
+     897             :   plumed_error_filesystem_path path1;
+     898             :   /** path2 - for filesystem_error */
+     899             :   plumed_error_filesystem_path path2;
+     900             :   /** message */
+     901             :   const char* what;
+     902             :   /** the buffer containing the message to be deallocated */
+     903             :   char* what_buffer;
+     904             :   /** pointer to nested exception */
+     905             :   struct plumed_error* nested;
+     906             : } plumed_error;
+     907             : 
+     908             : /** Initialize error (for internal usage) */
+     909             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_init(plumed_error* error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     910             :   assert(error);
+     911       12994 :   error->code=0;
+     912       12994 :   error->error_code=0;
+     913       12994 :   error->error_category=0;
+     914       12994 :   error->path1.numbytes=0;
+     915       12994 :   error->path1.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+     916       12994 :   error->path2.numbytes=0;
+     917       12994 :   error->path2.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+     918       12994 :   error->what=__PLUMED_WRAPPER_CXX_NULLPTR;
+     919       12994 :   error->what_buffer=__PLUMED_WRAPPER_CXX_NULLPTR;
+     920       12994 :   error->nested=__PLUMED_WRAPPER_CXX_NULLPTR;
+     921             : }
+     922             : 
+     923             : /** Finalize error - should be called when an error is raised to avoid leaks */
+     924             : /* cppcheck-suppress passedByValue */
+     925           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_finalize(plumed_error error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     926           0 :   if(!error.code) return;
+     927           0 :   if(error.nested) {
+     928           0 :     plumed_error_finalize(*error.nested);
+     929           0 :     plumed_free(error.nested);
+     930             :   }
+     931           0 :   if(error.path1.ptr) {
+     932           0 :     plumed_free(error.path1.ptr);
+     933             :   }
+     934           0 :   if(error.path2.ptr) {
+     935           0 :     plumed_free(error.path2.ptr);
+     936             :   }
+     937           0 :   if(error.what_buffer) {
+     938           0 :     plumed_free(error.what_buffer);
+     939             :   }
+     940             : }
+     941             : 
+     942             : /** Access message - more robust than directly accessing what ptr, for future extensibility */
+     943             : /* cppcheck-suppress passedByValue */
+     944             : __PLUMED_WRAPPER_STATIC_INLINE const char* plumed_error_what(plumed_error error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     945             :   return error.what;
+     946             : }
+     947             : 
+     948             : /** Set error to bad_alloc (for internal usage).
+     949             :     At variance with plumed_error_init, it also finalizes the error, possibly
+     950             :     deallocating any buffer.
+     951             : */
+     952           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_set_bad_alloc(plumed_error*error) {
+     953             :   assert(error);
+     954           0 :   plumed_error_finalize(*error);
+     955             :   plumed_error_init(error);
+     956           0 :   error->what="[msg erased due to allocation failure]";
+     957           0 :   error->code=11400;
+     958           0 : }
+     959             : 
+     960             : /** Recursive merge (for internal usage) */
+     961             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_recursive_merge(plumed_error* error,char*buffer,const char*join,__PLUMED_WRAPPER_STD size_t*len) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     962             :   if(error->nested) plumed_error_recursive_merge(error->nested,buffer,join,len);
+     963             :   __PLUMED_WRAPPER_STD strncat(buffer,plumed_error_what(*error),*len);
+     964             :   *len -= __PLUMED_WRAPPER_STD strlen(plumed_error_what(*error));
+     965             :   __PLUMED_WRAPPER_STD strncat(buffer,join,*len);
+     966             :   *len -= __PLUMED_WRAPPER_STD strlen(join);
+     967             : }
+     968             : 
+     969             : /** Merge with nested exceptions */
+     970             : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_merge_with_nested(plumed_error* error) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+     971             :   __PLUMED_WRAPPER_STD size_t len;
+     972             :   __PLUMED_WRAPPER_STD size_t len_join;
+     973             :   /* The is temporarily holding the new message */
+     974             :   char* new_buffer;
+     975             :   /* This is the string used to concatenate messages */
+     976             :   const char* join="\n\nThe above exception was the direct cause of the following exception:\n";
+     977             :   /* This is used to iterate over the linked list of nested exceptions */
+     978             :   plumed_error*e;
+     979             : 
+     980             :   /* If exception is not nested, nothing to do */
+     981             :   if(!error->nested) return;
+     982             : 
+     983             :   /* Accumulate the total length of the concatenated message */
+     984             :   len_join=__PLUMED_WRAPPER_STD strlen(join);
+     985             :   e=error;
+     986             :   len=__PLUMED_WRAPPER_STD strlen(plumed_error_what(*e));
+     987             :   while(e->nested) {
+     988             :     e=e->nested;
+     989             :     len+=len_join+__PLUMED_WRAPPER_STD strlen(plumed_error_what(*e));
+     990             :   }
+     991             : 
+     992             :   /* Allocate the new message */
+     993             :   new_buffer=(char*)plumed_malloc(len+1);
+     994             :   if(new_buffer) {
+     995             :     /* If allocation was successful, merge the messages */
+     996             :     new_buffer[0]='\0';
+     997             :     /* Notice that we have a forward linked list but we need to go through that in backward order
+     998             :        (inner to outer). To do that without allocating an additional array, we use a recursive
+     999             :        function.
+    1000             :     */
+    1001             :     assert(error->nested);
+    1002             :     plumed_error_recursive_merge(error->nested,new_buffer,join,&len);
+    1003             :     __PLUMED_WRAPPER_STD strncat(new_buffer,plumed_error_what(*error),len);
+    1004             :     len -= __PLUMED_WRAPPER_STD strlen(plumed_error_what(*error));
+    1005             :     /* we keep track of length of buffer for safety */
+    1006             :     assert(len==0);
+    1007             :   }
+    1008             :   error->what=new_buffer;
+    1009             : 
+    1010             :   /* Deallocate the previous message */
+    1011             :   if(error->what_buffer) plumed_free(error->what_buffer);
+    1012             :   error->what_buffer=new_buffer;
+    1013             : 
+    1014             :   /* Finalize the chain of nested exceptions */
+    1015             :   plumed_error_finalize(*error->nested);
+    1016             :   plumed_free(error->nested);
+    1017             :   error->nested=__PLUMED_WRAPPER_CXX_NULLPTR;
+    1018             : 
+    1019             :   if(!error->what) {
+    1020             :     /* If allocation was not successful, reset to bad_alloc */
+    1021             :     plumed_error_set_bad_alloc(error);
+    1022             :   }
+    1023             : }
+    1024             : 
+    1025             : /** Rethrow error (calling abort) */
+    1026             : __PLUMED_WRAPPER_CXX_NORETURN __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_rethrow(plumed_error h) {
+    1027             :   if(h.nested) plumed_error_merge_with_nested(&h);
+    1028             :   __PLUMED_WRAPPER_STD fprintf(stderr,"Terminate due to exception. Code: %d\n%s\n",h.code,plumed_error_what(h));
+    1029             :   __PLUMED_WRAPPER_STD abort();
+    1030             : }
+    1031             : 
+    1032             : /** Callback (for internal usage) */
+    1033           0 : __PLUMED_WRAPPER_STATIC_INLINE void plumed_error_set(void*ptr,int code,const char*what,const void* opt) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    1034             :   plumed_error* error;
+    1035             :   __PLUMED_WRAPPER_STD size_t len;
+    1036             :   void*const* options;
+    1037             :   plumed_error_filesystem_path path;
+    1038             : 
+    1039             :   error=(plumed_error*) ptr;
+    1040             : 
+    1041           0 :   error->code=code;
+    1042           0 :   error->error_code=0;
+    1043           0 :   len=__PLUMED_WRAPPER_STD strlen(what);
+    1044           0 :   error->what_buffer=(char*) plumed_malloc(len+1);
+    1045           0 :   if(!error->what_buffer) {
+    1046           0 :     plumed_error_set_bad_alloc(error);
+    1047           0 :     return;
+    1048             :   }
+    1049             : 
+    1050             :   __PLUMED_WRAPPER_STD strncpy(error->what_buffer,what,len+1);
+    1051           0 :   error->what=error->what_buffer;
+    1052             : 
+    1053             :   /* interpret optional arguments */
+    1054           0 :   if(opt) {
+    1055             :     options=(void*const*)opt;
+    1056           0 :     while(*options) {
+    1057             :       /* c: error code */
+    1058           0 :       if(*((const char*)*options)=='c' && *(options+1)) {
+    1059           0 :         error->error_code=*((const int*)*(options+1));
+    1060           0 :         break;
+    1061             :       }
+    1062           0 :       options+=2;
+    1063             :     }
+    1064             : 
+    1065             :     options=(void*const*)opt;
+    1066           0 :     while(*options) {
+    1067             :       /* C: error_category */
+    1068           0 :       if(*((const char*)*options)=='C' && *(options+1)) {
+    1069           0 :         error->error_category=*((const int*)*(options+1));
+    1070           0 :         break;
+    1071             :       }
+    1072           0 :       options+=2;
+    1073             :     }
+    1074             : 
+    1075             :     options=(void*const*)opt;
+    1076           0 :     while(*options) {
+    1077             :       /* path 1 */
+    1078           0 :       if(*((const char*)*options)=='p' && *(options+1)) {
+    1079           0 :         path=*(plumed_error_filesystem_path*)*(options+1);
+    1080           0 :         error->path1.ptr=plumed_malloc(path.numbytes);
+    1081           0 :         if(!error->path1.ptr) {
+    1082           0 :           plumed_error_set_bad_alloc(error);
+    1083           0 :           return;
+    1084             :         }
+    1085           0 :         error->path1.numbytes=path.numbytes;
+    1086             :         __PLUMED_WRAPPER_STD memcpy(error->path1.ptr,path.ptr,path.numbytes);
+    1087             :         break;
+    1088             :       }
+    1089           0 :       options+=2;
+    1090             :     }
+    1091             : 
+    1092             :     options=(void*const*)opt;
+    1093           0 :     while(*options) {
+    1094             :       /* path 2 */
+    1095           0 :       if(*((const char*)*options)=='q' && *(options+1)) {
+    1096           0 :         path=*(plumed_error_filesystem_path*)*(options+1);
+    1097           0 :         error->path2.ptr=plumed_malloc(path.numbytes);
+    1098           0 :         if(!error->path2.ptr) {
+    1099           0 :           plumed_error_set_bad_alloc(error);
+    1100           0 :           return;
+    1101             :         }
+    1102           0 :         error->path2.numbytes=path.numbytes;
+    1103             :         __PLUMED_WRAPPER_STD memcpy(error->path2.ptr,path.ptr,path.numbytes);
+    1104             :         break;
+    1105             :       }
+    1106           0 :       options+=2;
+    1107             :     }
+    1108             : 
+    1109             :     options=(void*const*)opt;
+    1110           0 :     while(*options) {
+    1111             :       /* n: nested exception */
+    1112           0 :       if(*((const char*)*options)=='n' && *(options+1)) {
+    1113             :         /* notice that once this is allocated it is guaranteed to be deallocated by the recursive destructor */
+    1114           0 :         error->nested=(plumed_error*) plumed_malloc(sizeof(plumed_error));
+    1115             :         /* this is if malloc fails */
+    1116           0 :         if(!error->nested) {
+    1117           0 :           plumed_error_set_bad_alloc(error);
+    1118           0 :           break;
+    1119             :         }
+    1120             :         plumed_error_init((plumed_error*)error->nested);
+    1121             :         /* plumed will make sure to only use this if it is not null */
+    1122           0 :         *(void**)*(options+1)=error->nested;
+    1123           0 :         break;
+    1124             :       }
+    1125           0 :       options+=2;
+    1126             :     }
+    1127             :   }
+    1128             : }
+    1129             : 
+    1130             : /** \relates plumed
+    1131             :     \brief Constructor
+    1132             : 
+    1133             :     Constructs a plumed object.
+    1134             : 
+    1135             :     Notice that if you are linking against libplumedWrapper.a, if you are
+    1136             :     using a code patched in runtime mode, or if you are including the `Plumed.c`
+    1137             :     file directly in your code, this constructor might return an invalid plumed
+    1138             :     object. In particular, this could happen if the `PLUMED_KERNEL` environment
+    1139             :     variable is not set or set incorrectly. In order to detect an incorrect
+    1140             :     plumed object you might use \ref plumed_valid() on the resulting object.
+    1141             :     Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
+    1142             :     Also notice that to avoid memory leaks you should call \ref plumed_finalize()
+    1143             :     to finalize a plumed object even if it is invalid:
+    1144             : \verbatim
+    1145             :   plumed p=plumed_create();
+    1146             :   if(!plumed_valid(p)) {
+    1147             : // this will happen if the PLUMED_KERNEL variable is not set correctly
+    1148             :     plumed_finalize(p);
+    1149             :     return whatever;
+    1150             :   }
+    1151             : \endverbatim
+    1152             : 
+    1153             :     \return The constructed plumed object
+    1154             : */
+    1155             : __PLUMED_WRAPPER_C_BEGIN
+    1156             : plumed plumed_create(void);
+    1157             : __PLUMED_WRAPPER_C_END
+    1158             : 
+    1159             : /** \relates plumed
+    1160             :     \brief Constructor from path. Available as of PLUMED 2.5
+    1161             : 
+    1162             :     It tries to construct a plumed object loading the kernel located at path.
+    1163             :     Notice that it could leave the resulting object in an invalid state.
+    1164             :     In order to detect an invalid
+    1165             :     plumed object you might use \ref plumed_valid() on the resulting object.
+    1166             :     Alternatively, if you use \ref plumed_cmd() on an invalid plumed object the code will exit.
+    1167             : 
+    1168             :     Also notice that to avoid memory leaks you should call \ref plumed_finalize()
+    1169             :     to finalize a plumed object even if it is invalid.
+    1170             : \verbatim
+    1171             :   plumed p=plumed_create(path);
+    1172             :   if(!plumed_valid(p)) {
+    1173             : // this will happen if the path argument is not set correctly
+    1174             :     plumed_finalize(p);
+    1175             :     return whatever;
+    1176             :   }
+    1177             : \endverbatim
+    1178             : 
+    1179             :     \return The constructed plumed object
+    1180             : */
+    1181             : __PLUMED_WRAPPER_C_BEGIN
+    1182             : plumed plumed_create_dlopen(const char*path);
+    1183             : __PLUMED_WRAPPER_C_END
+    1184             : 
+    1185             : 
+    1186             : /**
+    1187             :   \brief Constructor from path. Available as of PLUMED 2.5
+    1188             : 
+    1189             :   Same as \ref plumed_create_dlopen, but also allows to specify the mode for dlopen.
+    1190             : 
+    1191             :   \warning
+    1192             :   Use with care, since not all the possible modes work correctly with PLUMED.
+    1193             : */
+    1194             : __PLUMED_WRAPPER_C_BEGIN
+    1195             : plumed plumed_create_dlopen2(const char*path,int mode);
+    1196             : __PLUMED_WRAPPER_C_END
+    1197             : 
+    1198             : /**
+    1199             :   \brief Constructor from dlopen handle. Available as of PLUMED 2.8
+    1200             : 
+    1201             :   Same as  \ref plumed_create_dlopen, but it acts on an already loaded library.
+    1202             :   This allows to separate the library loading from the construction of the
+    1203             :   plumed object. By using this function, the caller takes the responsibility
+    1204             :   to later use dlclose on this handle.
+    1205             : */
+    1206             : __PLUMED_WRAPPER_C_BEGIN
+    1207             : plumed plumed_create_dlsym(void* dlhandle);
+    1208             : __PLUMED_WRAPPER_C_END
+    1209             : 
+    1210             : /** \relates plumed
+    1211             :     Create a new reference to an existing object, increasing its reference count. Available as of PLUMED 2.5
+    1212             : 
+    1213             :     Use it to increase by one the reference count of a plumed object.
+    1214             :     The resulting pointer might be identical to the one passed as an
+    1215             :     argument, but the reference count will be incremented by one.
+    1216             :     Notice that you should finalize the resulting object.
+    1217             : \verbatim
+    1218             :   plumed p1;
+    1219             :   plumed p2;
+    1220             :   p1=plumed_create();
+    1221             :   p2=plumed_create_reference(p1);
+    1222             :   plumed_finalize(p1);
+    1223             : // now you can still use p2
+    1224             :   plumed_cmd(p2,"init",NULL);
+    1225             :   plumed_finalize(p2);
+    1226             : // now the underlying object is destroyed.
+    1227             : \endverbatim
+    1228             : 
+    1229             :     If the `p` object is invalid, also the returned object will be invalid.
+    1230             : 
+    1231             :     \param p The plumed object that will be referenced to.
+    1232             :     \return The constructed plumed object
+    1233             : */
+    1234             : 
+    1235             : __PLUMED_WRAPPER_C_BEGIN
+    1236             : plumed plumed_create_reference(plumed p);
+    1237             : __PLUMED_WRAPPER_C_END
+    1238             : 
+    1239             : /** \relates plumed
+    1240             :     \brief Create a new reference to an existing object passed as a void pointer, increasing its reference count. Available as of PLUMED 2.5
+    1241             : 
+    1242             :   \return The constructed plumed object
+    1243             : */
+    1244             : 
+    1245             : __PLUMED_WRAPPER_C_BEGIN
+    1246             : plumed plumed_create_reference_v(void*v);
+    1247             : __PLUMED_WRAPPER_C_END
+    1248             : 
+    1249             : /** \relates plumed
+    1250             :     \brief Create a new reference to an existing object passed as a fortran string, increasing its reference count. Available as of PLUMED 2.5
+    1251             : 
+    1252             :   \return The constructed plumed object
+    1253             : */
+    1254             : 
+    1255             : __PLUMED_WRAPPER_C_BEGIN
+    1256             : plumed plumed_create_reference_f(const char*f);
+    1257             : __PLUMED_WRAPPER_C_END
+    1258             : 
+    1259             : /** \relates plumed
+    1260             :     \brief Constructor as invalid. Available as of PLUMED 2.5
+    1261             : 
+    1262             :    Can be used to create an object in the same state as if it was returned by
+    1263             :    plumed_create_dlopen with an incorrect path (or plumed_create using runtime binding
+    1264             :    and an incorrect PLUMED_KERNEL).
+    1265             : 
+    1266             :    Can be used to initialize a plumed object to a well-defined state without explicitly
+    1267             :    creating it. The resulting object can be checked later with \ref plumed_valid.
+    1268             :    Consider the following example
+    1269             : \verbatim
+    1270             :     plumed p;
+    1271             :     p=plumed_create_invalid();
+    1272             : // at this point p is initialized to a well-defined (invalid) state.
+    1273             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    1274             :     plumed_finalize(p);
+    1275             :     p=plumed_create();
+    1276             : \endverbatim
+    1277             : 
+    1278             :     \return The constructed plumed object
+    1279             : */
+    1280             : 
+    1281             : __PLUMED_WRAPPER_C_BEGIN
+    1282             : plumed plumed_create_invalid();
+    1283             : __PLUMED_WRAPPER_C_END
+    1284             : 
+    1285             : /** \relates plumed
+    1286             :     \brief Tells p to execute a command.
+    1287             : 
+    1288             :     If the object is not valid (see \ref plumed_valid), this command will exit.
+    1289             : 
+    1290             :     \param p The plumed object on which command is acting
+    1291             :     \param key The name of the command to be executed
+    1292             :     \param val The argument. It is declared as const to allow calls like plumed_cmd(p,"A","B"),
+    1293             :                but for some choice of key it can change the content.
+    1294             : 
+    1295             :     Notice that within PLUMED we use a const_cast to remove any const qualifier from the second
+    1296             :     argument of \ref plumed_cmd.
+    1297             : 
+    1298             :     In some cases val can be omitted: just pass a NULL pointer (in C++, val is optional and can be omitted,
+    1299             :     or you can equivalently pass NULL or nullptr).
+    1300             :     The set of possible keys is the real API of the plumed library, and will be expanded with time.
+    1301             :     New commands will be added, but backward compatibility will be retained as long as possible.
+    1302             : */
+    1303             : 
+    1304             : __PLUMED_WRAPPER_C_BEGIN
+    1305             : void plumed_cmd(plumed p,const char*key,const void*val);
+    1306             : __PLUMED_WRAPPER_C_END
+    1307             : 
+    1308             : /**
+    1309             :   \relates plumed
+    1310             :   \brief Same as \ref plumed_cmd, but does not throw exceptions.
+    1311             : 
+    1312             :   This function is meant to be used when errors should be handled explicitly.
+    1313             :   if an exception is raised within PLUMED, the function nothrow.handler() will
+    1314             :   be called with arguments (nothrow.ptr,code,message,opt). This allows the C++ interface
+    1315             :   to correctly rethrow exceptions, but might be used from C as well. opt can be used
+    1316             :   to pass further information (not used yet).
+    1317             : */
+    1318             : 
+    1319             : __PLUMED_WRAPPER_C_BEGIN
+    1320             : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow);
+    1321             : __PLUMED_WRAPPER_C_END
+    1322             : 
+    1323             : __PLUMED_WRAPPER_C_BEGIN
+    1324             : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr,plumed_nothrow_handler nothrow);
+    1325             : __PLUMED_WRAPPER_C_END
+    1326             : 
+    1327             : __PLUMED_WRAPPER_C_BEGIN
+    1328             : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr);
+    1329             : __PLUMED_WRAPPER_C_END
+    1330             : 
+    1331             : /** \relates plumed
+    1332             :     \brief Destructor.
+    1333             : 
+    1334             :     It must be used for any object created using \ref plumed_create(),
+    1335             :     even if the created object is not valid.
+    1336             : 
+    1337             :     \param p The plumed object to be deallocated
+    1338             : */
+    1339             : 
+    1340             : __PLUMED_WRAPPER_C_BEGIN
+    1341             : void plumed_finalize(plumed p);
+    1342             : __PLUMED_WRAPPER_C_END
+    1343             : 
+    1344             : /** \relates plumed
+    1345             :     \brief Check if plumed is installed (for runtime binding).
+    1346             : 
+    1347             :     Notice that this is equivalent to creating a dummy object and checking if it is valid.
+    1348             : 
+    1349             : \verbatim
+    1350             :   // this:
+    1351             :   //int a=plumed_installed();
+    1352             :   // is equivalent to this:
+    1353             : 
+    1354             :   plumed p=plumed_create();
+    1355             :   int a=plumed_valid(p);
+    1356             :   plumed_finalize(p);
+    1357             : 
+    1358             : \endverbatim
+    1359             : 
+    1360             :     This function is mostly provided for compatibility with PLUMED 2.4, where \ref plumed_valid()
+    1361             :     was not available. Using \ref plumed_valid() is now preferred since it creates a single object
+    1362             :     instead of creating a dummy object that is then discarded.
+    1363             : 
+    1364             :     \return 1 if plumed is installed, 0 otherwise
+    1365             : */
+    1366             : 
+    1367             : __PLUMED_WRAPPER_C_BEGIN
+    1368             : int plumed_installed(void);
+    1369             : __PLUMED_WRAPPER_C_END
+    1370             : 
+    1371             : /** \relates plumed
+    1372             :     \brief Check if plumed object is valid. Available as of PLUMED 2.5
+    1373             : 
+    1374             :     It might return false if plumed is not available at runtime.
+    1375             : 
+    1376             :     \return 1 if plumed is valid, 0 otherwise
+    1377             : */
+    1378             : 
+    1379             : __PLUMED_WRAPPER_C_BEGIN
+    1380             : int plumed_valid(plumed p);
+    1381             : __PLUMED_WRAPPER_C_END
+    1382             : 
+    1383             : /** \relates plumed
+    1384             :     \brief Returns the number of references to the underlying object. Available as of PLUMED 2.5.
+    1385             : */
+    1386             : 
+    1387             : __PLUMED_WRAPPER_C_BEGIN
+    1388             : int plumed_use_count(plumed p);
+    1389             : __PLUMED_WRAPPER_C_END
+    1390             : 
+    1391             : 
+    1392             : /* routines to convert char handler from/to plumed objects */
+    1393             : 
+    1394             : /** \related plumed
+    1395             :     \brief Converts a C handler to a FORTRAN handler
+    1396             : 
+    1397             :     \param p The C handler
+    1398             :     \param c The FORTRAN handler (a char[32])
+    1399             : 
+    1400             :     This function can be used to convert a plumed object created in C to
+    1401             :     a plumed handler that can be used in FORTRAN. Notice that the reference counter
+    1402             :     is not incremented. In other words, the FORTRAN object will be a weak reference.
+    1403             :     If you later finalize the C handler, the FORTRAN handler will be invalid.
+    1404             : \verbatim
+    1405             : #include <plumed/wrapper/Plumed.h>
+    1406             : int main(int argc,char*argv[]){
+    1407             :   plumed p;
+    1408             :   p=plumed_create();
+    1409             :   char fortran_handler[32];
+    1410             :   plumed_c2f(p,fortran_handler);
+    1411             :   printf("DEBUG: this is a string representation for the plumed handler: %s\n",fortran_handler);
+    1412             :   fortran_routine(fortran_handler);
+    1413             :   plumed_finalize(p);
+    1414             :   return 0;
+    1415             : }
+    1416             : \endverbatim
+    1417             :   Here `fortran_routine` is a routine implemented in FORTRAN that manipulates the
+    1418             :   fortran_handler.
+    1419             : */
+    1420             : 
+    1421             : __PLUMED_WRAPPER_C_BEGIN
+    1422             : void   plumed_c2f(plumed p,char* c);
+    1423             : __PLUMED_WRAPPER_C_END
+    1424             : 
+    1425             : /** \related plumed
+    1426             :     \brief Converts a FORTRAN handler to a C handler
+    1427             :     \param c The FORTRAN handler (a char[32])
+    1428             :     \return The C handler
+    1429             : 
+    1430             :     This function can be used to convert a plumed object created in FORTRAN
+    1431             :     to a plumed handler that can be used in C.  Notice that the reference counter
+    1432             :     is not incremented. In other words, the C object will be a weak reference.
+    1433             :     If you later finalize the FORTRAN handler, the C handler will be invalid.
+    1434             : \verbatim
+    1435             : void c_routine(char handler[32]){
+    1436             :   plumed p;
+    1437             :   p=plumed_f2c(handler);
+    1438             :   plumed_cmd(p,"init",NULL);
+    1439             : }
+    1440             : \endverbatim
+    1441             :   Here `c_routine` is a C function that can be called from FORTRAN
+    1442             :   and interact with the provided plumed handler.
+    1443             : */
+    1444             : 
+    1445             : __PLUMED_WRAPPER_C_BEGIN
+    1446             : plumed plumed_f2c(const char* c);
+    1447             : __PLUMED_WRAPPER_C_END
+    1448             : 
+    1449             : /** \related plumed
+    1450             :     \brief Converts a plumed object to a void pointer. Available as of PLUMED 2.5.
+    1451             : 
+    1452             :     It returns a void pointer that can be converted back to a plumed object using \ref plumed_v2c.
+    1453             :     When compiling without NDEBUG, it checks if the plumed object was properly created.
+    1454             :     Notice that an invalid object (see \ref plumed_valid) can be converted to void* and back.
+    1455             : 
+    1456             :     Can be used to store a reference to a plumed object without including the Plumed.h header.
+    1457             : */
+    1458             : 
+    1459             : __PLUMED_WRAPPER_C_BEGIN
+    1460             : void* plumed_c2v(plumed p);
+    1461             : __PLUMED_WRAPPER_C_END
+    1462             : 
+    1463             : 
+    1464             : /** \related plumed
+    1465             :     \brief Converts a void pointer to a plumed object. Available as of PLUMED 2.5.
+    1466             : 
+    1467             :     It returns a plumed object from a void pointer obtained with \ref plumed_c2v.
+    1468             :     When compiling without NDEBUG, it checks if the plumed object was properly created.
+    1469             : 
+    1470             :     Can be used to store a reference to a plumed object without including the Plumed.h header.
+    1471             : */
+    1472             : 
+    1473             : __PLUMED_WRAPPER_C_BEGIN
+    1474             : plumed plumed_v2c(void*);
+    1475             : __PLUMED_WRAPPER_C_END
+    1476             : 
+    1477             : #if ! defined( __cplusplus) /*{*/
+    1478             : 
+    1479             : #if __PLUMED_WRAPPER_C_TYPESAFE /*{*/
+    1480             : 
+    1481             : #define __PLUMED_WRAPPER_C_TYPESAFE_INNER(type_,typen_,flags_) \
+    1482             :   static inline void plumed_cmdnse_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, const size_t* shape,plumed_error* error) { \
+    1483             :     plumed_safeptr safe; \
+    1484             :     plumed_nothrow_handler nothrow; \
+    1485             :     safe.ptr=ptr; \
+    1486             :     safe.nelem=nelem; \
+    1487             :     safe.shape=(const size_t*)shape; \
+    1488             :     safe.flags=flags_; \
+    1489             :     safe.opt=NULL; \
+    1490             :     if(error) { \
+    1491             :       plumed_error_init(error); \
+    1492             :       nothrow.ptr=error; \
+    1493             :       nothrow.handler=plumed_error_set; \
+    1494             :       plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
+    1495             :     } else { \
+    1496             :       plumed_cmd_safe(p,key,safe); \
+    1497             :     } \
+    1498             :   } \
+    1499             :   static inline void plumed_cmdne_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem, plumed_error* error) { \
+    1500             :     plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,error); \
+    1501             :   } \
+    1502             :   static inline void plumed_cmdse_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape, plumed_error* error) { \
+    1503             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,error); \
+    1504             :   } \
+    1505             :   static inline void plumed_cmdn_ ## typen_(plumed p,const char*key,type_*ptr, size_t nelem) { \
+    1506             :     plumed_cmdnse_ ## typen_(p,key,ptr,nelem,NULL,NULL); \
+    1507             :   } \
+    1508             :   static inline void plumed_cmds_ ## typen_(plumed p,const char*key,type_*ptr, const size_t* shape) { \
+    1509             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,shape,NULL); \
+    1510             :   } \
+    1511             :   static inline void plumed_cmde_ ## typen_(plumed p,const char*key,type_*ptr, plumed_error* error) { \
+    1512             :     plumed_cmdnse_ ## typen_(p,key,ptr,0,NULL,error); \
+    1513             :   }
+    1514             : 
+    1515             : #define __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,size) \
+    1516             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type,             type_ ## _p,  size | (0x10000*(code)) | (0x2000000*2)) \
+    1517             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const,       type_ ## _c,  size | (0x10000*(code)) | (0x2000000*3)) \
+    1518             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*,            type_ ## _pp, size | (0x10000*(code)) | (0x2000000*4)) \
+    1519             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type*const,       type_ ## _pc, size | (0x10000*(code)) | (0x2000000*5)) \
+    1520             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*,      type_ ## _cp, size | (0x10000*(code)) | (0x2000000*6)) \
+    1521             :   __PLUMED_WRAPPER_C_TYPESAFE_INNER(type const*const, type_ ## _cc, size | (0x10000*(code)) | (0x2000000*7))
+    1522             : 
+    1523             : #define __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(type,type_,code) __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,0)
+    1524             : 
+    1525             : #define __PLUMED_WRAPPER_C_TYPESAFE_SIZED(type,type_,code) \
+    1526             :   __PLUMED_WRAPPER_C_TYPESAFE_OUTER(type,type_,code,sizeof(type)) \
+    1527             :   static inline void plumed_cmdnse_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, const size_t* shape, plumed_error* error) { \
+    1528             :     plumed_safeptr safe; \
+    1529             :     plumed_nothrow_handler nothrow; \
+    1530             :     (void) nelem; \
+    1531             :     (void) shape; \
+    1532             :     safe.ptr=&val; \
+    1533             :     safe.nelem=1; \
+    1534             :     safe.shape=NULL; \
+    1535             :     safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+    1536             :     safe.opt=NULL; \
+    1537             :     if(error) { \
+    1538             :       plumed_error_init(error); \
+    1539             :       nothrow.ptr=error; \
+    1540             :       nothrow.handler=plumed_error_set; \
+    1541             :       plumed_cmd_safe_nothrow(p,key,safe,nothrow); \
+    1542             :     } else { \
+    1543             :       plumed_cmd_safe(p,key,safe); \
+    1544             :     } \
+    1545             :   } \
+    1546             :   static inline void plumed_cmdne_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem, plumed_error* error) {  \
+    1547             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,error); \
+    1548             :   } \
+    1549             :   static inline void plumed_cmdse_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape, plumed_error* error) {  \
+    1550             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,error); \
+    1551             :   } \
+    1552             :   static inline void plumed_cmdn_ ## type_ ## _v(plumed p,const char*key,type val, size_t nelem) {  \
+    1553             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,nelem,NULL,NULL); \
+    1554             :   } \
+    1555             :   static inline void plumed_cmds_ ## type_ ## _v(plumed p,const char*key,type val, const size_t* shape) {  \
+    1556             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,shape,NULL); \
+    1557             :   } \
+    1558             :   static inline void plumed_cmde_ ## type_ ## _v(plumed p,const char*key,type val, plumed_error* error) {  \
+    1559             :     plumed_cmdnse_ ## type_ ## _v(p,key,val,0,NULL,error); \
+    1560             :   }
+    1561             : 
+    1562             : #define __PLUMED_WRAPPER_C_GENERIC1(flavor,type,typen_) \
+    1563             :     type: plumed_ ## flavor ## _ ## typen_,
+    1564             : 
+    1565             : #define __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
+    1566             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type*,             type_ ## _p) \
+    1567             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*,       type_ ## _c) \
+    1568             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type**,            type_ ## _pp) \
+    1569             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type*const*,       type_ ## _pc) \
+    1570             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const**,      type_ ## _cp) \
+    1571             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type const*const*, type_ ## _cc)
+    1572             : 
+    1573             : #define __PLUMED_WRAPPER_C_GENERIC2(flavor,type,type_) \
+    1574             :   __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,type,type_) \
+    1575             :   __PLUMED_WRAPPER_C_GENERIC1(flavor,type,             type_ ## _v)
+    1576             : 
+    1577             : /// Here we create all the required instances
+    1578             : /// 1: void
+    1579             : /// 3: integral
+    1580             : /// 4: floating
+    1581             : /// 5: FILE
+    1582             : /// 0x100: unsigned
+    1583             : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(void,void,1)
+    1584             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(char,char,(CHAR_MIN==0)*0x100+3)
+    1585             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned char,unsigned_char,0x100+3)
+    1586             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(signed char,signed_char,0x100+3)
+    1587             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(short,short,3)
+    1588             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned short,unsigned_short,0x100+3)
+    1589             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(int,int,3)
+    1590             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned int,unsigned_int,0x100+3)
+    1591             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long,long,3)
+    1592             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long,unsigned_long,0x100+3)
+    1593             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long long,long_long,3)
+    1594             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(unsigned long long,unsigned_long_long,0x100+3)
+    1595             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(float,float,4)
+    1596             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(double,double,4)
+    1597             : __PLUMED_WRAPPER_C_TYPESAFE_SIZED(long double,long_double,4)
+    1598             : __PLUMED_WRAPPER_C_TYPESAFE_EMPTY(FILE,FILE,5)
+    1599             : 
+    1600             : static inline void plumed_cmd_null_e(plumed p,const char*key,plumed_error* error,int ignore) {
+    1601             :   (void) ignore;
+    1602             :   plumed_cmde_void_p(p,key,NULL,error);
+    1603             : }
+    1604             : 
+    1605             : #define plumed_cmdnse_inner(flavor,val) _Generic((val), \
+    1606             :     __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,void,void) \
+    1607             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,char,char) \
+    1608             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned char,unsigned_char) \
+    1609             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,signed char,signed_char) \
+    1610             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,short,short) \
+    1611             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned short,unsigned_short) \
+    1612             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,int,int) \
+    1613             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned int,unsigned_int) \
+    1614             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long,long) \
+    1615             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long,unsigned_long) \
+    1616             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long long,long_long) \
+    1617             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,unsigned long long,unsigned_long_long) \
+    1618             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,float,float) \
+    1619             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,double,double) \
+    1620             :     __PLUMED_WRAPPER_C_GENERIC2(flavor,long double,long_double) \
+    1621             :     __PLUMED_WRAPPER_C_GENERIC_EMPTY(flavor,FILE,FILE) \
+    1622             :     default: plumed_ ## flavor ## _void_c)
+    1623             : 
+    1624             : #define plumed_cmd_2args(p,key) plumed_cmdnse_inner(cmdn,NULL) (p,key,NULL,0)
+    1625             : 
+    1626             : #define plumed_cmd_3args(p,key,X) _Generic((X), \
+    1627             :     plumed_error*: plumed_cmd_null_e, \
+    1628             :     default:       plumed_cmdnse_inner(cmdn,X)) (p,key,X,0)
+    1629             : 
+    1630             : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
+    1631             : #define plumed_cmd_4args(p,key,val,X) _Generic(((X)+(size_t)0), \
+    1632             :     const size_t *: plumed_cmdnse_inner(cmds,val), \
+    1633             :     size_t *: plumed_cmdnse_inner(cmds,val), \
+    1634             :     size_t: plumed_cmdnse_inner(cmdn,val), \
+    1635             :     plumed_error*: plumed_cmdnse_inner(cmde,val) \
+    1636             :     ) (p,key,val,X)
+    1637             : 
+    1638             : /* ((X)+(size_t)0): for pointers, no op; for integers, convert to size_t */
+    1639             : #define plumed_cmd_5args(p,key,val,X,error) _Generic(((X)+(size_t)0), \
+    1640             :     const size_t *: plumed_cmdnse_inner(cmdse,val), \
+    1641             :     size_t *: plumed_cmdnse_inner(cmdse,val), \
+    1642             :     size_t: plumed_cmdnse_inner(cmdne,val) \
+    1643             :     ) (p,key,val,X,error)
+    1644             : 
+    1645             : #define __PLUMED_WRAPPER_C_GET_MACRO(_1,_2,_3,_4,_5,NAME,...) NAME
+    1646             : #define plumed_cmd_c11(...) __PLUMED_WRAPPER_C_GET_MACRO(__VA_ARGS__, plumed_cmd_5args, plumed_cmd_4args, plumed_cmd_3args, plumed_cmd_2args)(__VA_ARGS__)
+    1647             : 
+    1648             : #define plumed_gcmd_c11(...) plumed_cmd(plumed_global(),__VA_ARGS__)
+    1649             : 
+    1650             : #define __PLUMED_WRAPPER_REDEFINE_CMD plumed_cmd_c11
+    1651             : #define __PLUMED_WRAPPER_REDEFINE_GCMD plumed_gcmd_c11
+    1652             : 
+    1653             : #endif /*}*/
+    1654             : 
+    1655             : #endif /*}*/
+    1656             : 
+    1657             : 
+    1658             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    1659             : 
+    1660             : /* Global C functions are always extern */
+    1661             : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
+    1662             : 
+    1663             : /** \relates plumed
+    1664             :     \brief Retrieves an handler to the global structure.
+    1665             : 
+    1666             :   You can use this if you work on a code that uses the global structure and you want to
+    1667             :   pass to a generic routine an handler to the same structure. E.g.
+    1668             : 
+    1669             : \verbatim
+    1670             :   plumed p=plumed_global();
+    1671             :   some_routine(p);
+    1672             : \endverbatim
+    1673             : */
+    1674             : extern
+    1675             : plumed plumed_global(void);
+    1676             : 
+    1677             : /** \relates plumed
+    1678             :     \brief Check if the global interface has been initialized.
+    1679             : 
+    1680             :     \return 1 if plumed has been initialized, 0 otherwise
+    1681             : */
+    1682             : extern
+    1683             : int plumed_ginitialized(void);
+    1684             : 
+    1685             : /** \relates plumed
+    1686             :     \brief Constructor for the global interface.
+    1687             : 
+    1688             :     \note Equivalent to plumed_create(), but initialize the static global plumed object
+    1689             : */
+    1690             : extern
+    1691             : void plumed_gcreate(void);
+    1692             : 
+    1693             : /** \relates plumed
+    1694             :     \brief Tells to the global interface to execute a command.
+    1695             : 
+    1696             :     \param key The name of the command to be executed
+    1697             :     \param val The argument. It is declared as const to allow calls like plumed_gcmd("A","B"),
+    1698             :                but for some choice of key it can change the content
+    1699             : 
+    1700             :     `plumed_gcmd(a,b);` is equivalent to `plumed_cmd(plumed_global(),a,b);`.
+    1701             : */
+    1702             : extern
+    1703             : void plumed_gcmd(const char* key,const void* val);
+    1704             : 
+    1705             : /** \relates plumed
+    1706             :     \brief Tells to the global interface to execute a command.
+    1707             : 
+    1708             :     \param key The name of the command to be executed
+    1709             :     \param safe A safe pointer
+    1710             : 
+    1711             :     `plumed_gcmd_safe(a,b);` is equivalent to `plumed_cmd_safe(plumed_global(),a,b);`.
+    1712             : */
+    1713             : extern
+    1714             : void plumed_gcmd_safe(const char* key,plumed_safeptr);
+    1715             : 
+    1716             : /** \relates plumed
+    1717             :     \brief Destructor for the global interface.
+    1718             : 
+    1719             :     `plumed_gfinalize(a,b);` is similar to `plumed_finalize(plumed_global(),a,b);`, but not completely
+    1720             :     equivalent. In particular, plumed_gfinalize() also makes sure that the global object
+    1721             :     is reset to its initial status. After calling it, \ref plumed_ginitialized() will thus return 0.
+    1722             : */
+    1723             : extern
+    1724             : void plumed_gfinalize(void);
+    1725             : 
+    1726             : /** \relates plumed
+    1727             :     \brief Check if global plumed object is valid. Available as of PLUMED 2.5
+    1728             : 
+    1729             :     It might return zero if plumed is not available at runtime.
+    1730             : 
+    1731             :     \return 1 if plumed is valid, 0 otherwise.
+    1732             : */
+    1733             : extern
+    1734             : int plumed_gvalid();
+    1735             : 
+    1736             : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
+    1737             : 
+    1738             : #endif /*}*/
+    1739             : 
+    1740             : #if defined( __cplusplus) && __PLUMED_WRAPPER_CXX /*{*/
+    1741             : 
+    1742             : #if __PLUMED_WRAPPER_CXX_STD
+    1743             : #include <cstdlib> /* NULL getenv */
+    1744             : #include <cstddef> /* nullptr_t */
+    1745             : #include <cstring> /* strncat strlen */
+    1746             : #include <cassert> /* assert */
+    1747             : #include <climits> /* CHAR_MIN */
+    1748             : #else
+    1749             : #include <stddef.h>
+    1750             : #include <stdlib.h>
+    1751             : #include <string.h>
+    1752             : #include <assert.h>
+    1753             : #include <limits.h>
+    1754             : #endif
+    1755             : 
+    1756             : #include <exception> /* exception bad_exception */
+    1757             : #include <stdexcept> /* runtime_error logic_error invalid_argument domain_error length_error out_of_range range_error overflow_error underflow_error */
+    1758             : #include <string> /* string */
+    1759             : #include <ios> /* iostream_category (C++11) ios_base::failure (C++11 and C++<11) */
+    1760             : #include <new> /* bad_alloc bad_array_new_length (C++11) */
+    1761             : #include <typeinfo> /* bad_typeid bad_cast */
+    1762             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1763             : #include <system_error> /* system_error generic_category system_category */
+    1764             : #include <future> /* future_category */
+    1765             : #include <memory> /* bad_weak_ptr */
+    1766             : #include <functional> /* bad_function_call */
+    1767             : #include <regex> /* regex_error */
+    1768             : #endif
+    1769             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1770             : #include <any> /* bad_any_cast */
+    1771             : #include <variant> /* bad_variant_access */
+    1772             : #include <optional> /* bad_optional_access */
+    1773             : #include <filesystem> /* filesystem_error */
+    1774             : #endif
+    1775             : 
+    1776             : #if __cplusplus > 199711L
+    1777             : #include <array> /* array */
+    1778             : #include <initializer_list> /* initializer_list */
+    1779             : #endif
+    1780             : 
+    1781             : /* C++ interface is hidden in PLMD namespace (same as plumed library) */
+    1782             : namespace PLMD {
+    1783             : 
+    1784             : /* Optionally, it is further hidden in an anonymous namespace */
+    1785             : 
+    1786             : __PLUMED_WRAPPER_ANONYMOUS_BEGIN /*{*/
+    1787             : 
+    1788             : /**
+    1789             :   Retrieve PLUMED_EXCEPTIONS_DEBUG (internal utility).
+    1790             : 
+    1791             :   This function should not be used by external programs. It is defined
+    1792             :   as inline static so that it can store a static variable (for quicker access)
+    1793             :   without adding a unique global symbol to a library including this header file.
+    1794             : */
+    1795           0 : inline static bool PlumedGetenvExceptionsDebug() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    1796           0 :   static const char* res=__PLUMED_WRAPPER_STD getenv("PLUMED_EXCEPTIONS_DEBUG");
+    1797           0 :   return res;
+    1798             : }
+    1799             : 
+    1800             : /**
+    1801             :   C++ wrapper for \ref plumed.
+    1802             : 
+    1803             :   This class provides a C++ interface to PLUMED.
+    1804             :   It only containts a \ref plumed object, but wraps it with a number of useful methods.
+    1805             :   All methods are inlined so as to avoid the compilation of an extra c++ file.
+    1806             : 
+    1807             : */
+    1808             : 
+    1809             : class Plumed {
+    1810             :   /**
+    1811             :     C structure.
+    1812             :   */
+    1813             :   plumed main;
+    1814             : 
+    1815             : private:
+    1816             : 
+    1817             :   /**
+    1818             :     This is an internal utility to dispatch exceptions based on the plumed_error object.
+    1819             : 
+    1820             :     It takes information about the exception to be thrown by the passed h object
+    1821             :     and use it to call function f() on the resulting exception. Notice that:
+    1822             :     - this function does not consider if the error is nested.
+    1823             :     - f should be a callable object, so that it can store information
+    1824             :     - f operator() should be a template function so as to act based on the
+    1825             :       type of its argument
+    1826             : 
+    1827             :     New exceptions added here should be kept in sync with core/PlumedMainInitializer.cpp
+    1828             : 
+    1829             :     Notice that this function also finalizes in place plumed_error h, so as to avoid
+    1830             :     memory leaks.
+    1831             :   */
+    1832             :   template<typename F>
+    1833           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void exception_dispatch(plumed_error&h,F f) {
+    1834             :     /* this is required to make sure h is finalized when leaving this function */
+    1835             :     finalize_plumed_error finalize(h);
+    1836             :     /* grab the message */
+    1837             :     const char* msg=plumed_error_what(h);
+    1838           0 :     if(h.code==1) f(Plumed::Invalid(msg));
+    1839             :     /* logic errors */
+    1840           0 :     if(h.code>=10100 && h.code<10200) {
+    1841           0 :       if(h.code>=10105 && h.code<10110) f(::std::invalid_argument(msg));
+    1842           0 :       if(h.code>=10110 && h.code<10115) f(::std::domain_error(msg));
+    1843           0 :       if(h.code>=10115 && h.code<10120) f(::std::length_error(msg));
+    1844           0 :       if(h.code>=10120 && h.code<10125) f(::std::out_of_range(msg));
+    1845             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1846             :       if(h.code==10125) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::broken_promise),msg));
+    1847             :       if(h.code==10126) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::future_already_retrieved),msg));
+    1848             :       if(h.code==10127) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::promise_already_satisfied),msg));
+    1849             :       if(h.code==10128) f(add_buffer_to< ::std::future_error>(::std::future_error(::std::future_errc::no_state),msg));
+    1850             : #endif
+    1851           0 :       f(::std::logic_error(msg));
+    1852             :     }
+    1853             :     /* runtime errors */
+    1854           0 :     if(h.code>=10200 && h.code<10300) {
+    1855           0 :       if(h.code>=10205 && h.code<10210) f(::std::range_error(msg));
+    1856           0 :       if(h.code>=10210 && h.code<10215) f(::std::overflow_error(msg));
+    1857           0 :       if(h.code>=10215 && h.code<10220) f(::std::underflow_error(msg));
+    1858             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1859             :       if(h.code==10220) f(::std::system_error(h.error_code,::std::generic_category(),msg));
+    1860             :       if(h.code==10221) f(::std::system_error(h.error_code,::std::system_category(),msg));
+    1861             :       if(h.code==10222) f(::std::system_error(h.error_code,::std::iostream_category(),msg));
+    1862             :       if(h.code==10223) f(::std::system_error(h.error_code,::std::future_category(),msg));
+    1863             : #endif
+    1864             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1865             :       if(h.code==10229) {
+    1866             :         ::std::error_code error_code;
+    1867             :         if(h.error_category==1) error_code=::std::error_code(h.error_code,::std::generic_category());
+    1868             :         if(h.error_category==2) error_code=::std::error_code(h.error_code,::std::system_category());
+    1869             :         if(h.error_category==3) error_code=::std::error_code(h.error_code,::std::iostream_category());
+    1870             :         if(h.error_category==4) error_code=::std::error_code(h.error_code,::std::future_category());
+    1871             : 
+    1872             :         if(!h.path1.ptr) {
+    1873             :           f(::std::filesystem::filesystem_error(msg,error_code));
+    1874             :         } else if(!h.path2.ptr) {
+    1875             :           /*
+    1876             :              In principle native_format is a possible value of an enum,
+    1877             :              so should be accessible as ::std::filesystem::path::native_format
+    1878             :              However, some clang versions declare it as enum class. Thus,
+    1879             :              ::std::filesystem::path::format::native_format is more portable.
+    1880             :           */
+    1881             :           f(::std::filesystem::filesystem_error(msg,
+    1882             :                                                 ::std::filesystem::path(::std::filesystem::path::string_type(
+    1883             :                                                     (::std::filesystem::path::value_type*) h.path1.ptr,h.path1.numbytes/sizeof(::std::filesystem::path::value_type)
+    1884             :                                                     ),::std::filesystem::path::format::native_format),
+    1885             :                                                 error_code));
+    1886             :         } else {
+    1887             :           f(::std::filesystem::filesystem_error(msg,
+    1888             :                                                 ::std::filesystem::path(::std::filesystem::path::string_type(
+    1889             :                                                     (::std::filesystem::path::value_type*) h.path1.ptr,h.path1.numbytes/sizeof(::std::filesystem::path::value_type)
+    1890             :                                                     ),::std::filesystem::path::format::native_format),
+    1891             :                                                 ::std::filesystem::path(::std::filesystem::path::string_type(
+    1892             :                                                     (::std::filesystem::path::value_type*) h.path2.ptr,h.path2.numbytes/sizeof(::std::filesystem::path::value_type)
+    1893             :                                                     ),::std::filesystem::path::format::native_format),
+    1894             :                                                 error_code));
+    1895             :         }
+    1896             :       }
+    1897             : #endif
+    1898           0 :       if(h.code>=10230 && h.code<10240) {
+    1899             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1900             : // These cases are probably useless as it looks like this should always be std::iostream_category
+    1901             :         if(h.code==10230) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::generic_category())));
+    1902             :         if(h.code==10231) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::system_category())));
+    1903             :         if(h.code==10232) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::iostream_category())));
+    1904             :         if(h.code==10233) f(::std::ios_base::failure(msg,::std::error_code(h.error_code,::std::future_category())));
+    1905             : #endif
+    1906           0 :         f(::std::ios_base::failure(msg));
+    1907             :       }
+    1908             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1909             :       if(h.code==10240) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_collate),msg));
+    1910             :       if(h.code==10241) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_ctype),msg));
+    1911             :       if(h.code==10242) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_escape),msg));
+    1912             :       if(h.code==10243) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_backref),msg));
+    1913             :       if(h.code==10244) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_brack),msg));
+    1914             :       if(h.code==10245) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_paren),msg));
+    1915             :       if(h.code==10246) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_brace),msg));
+    1916             :       if(h.code==10247) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_badbrace),msg));
+    1917             :       if(h.code==10248) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_range),msg));
+    1918             :       if(h.code==10249) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_space),msg));
+    1919             :       if(h.code==10250) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_badrepeat),msg));
+    1920             :       if(h.code==10251) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_complexity),msg));
+    1921             :       if(h.code==10252) f(add_buffer_to< ::std::regex_error>(::std::regex_error(::std::regex_constants::error_stack),msg));
+    1922             : #endif
+    1923           0 :       f(::std::runtime_error(msg));
+    1924             :     }
+    1925             :     /* "bad" errors */
+    1926             :     /* "< ::" space required in C++ < 11 */
+    1927           0 :     if(h.code>=11000 && h.code<11100) f(add_buffer_to< ::std::bad_typeid>(msg));
+    1928           0 :     if(h.code>=11100 && h.code<11200) {
+    1929             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1930             :       if(h.code>=11150) f(add_buffer_to< ::std::bad_any_cast>(msg));
+    1931             : #endif
+    1932           0 :       f(add_buffer_to< ::std::bad_cast>(msg));
+    1933             :     }
+    1934             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1935             :     if(h.code>=11200 && h.code<11300) f(add_buffer_to< ::std::bad_weak_ptr>(msg));
+    1936             :     if(h.code>=11300 && h.code<11400) f(add_buffer_to< ::std::bad_function_call>(msg));
+    1937             : #endif
+    1938           0 :     if(h.code>=11400 && h.code<11500) {
+    1939             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    1940             :       if(h.code>=11410 && h.code<11420) f(add_buffer_to< ::std::bad_array_new_length>(msg));
+    1941             : #endif
+    1942           0 :       f(add_buffer_to< ::std::bad_alloc>(msg));
+    1943             :     }
+    1944           0 :     if(h.code>=11500 && h.code<11600) f(add_buffer_to< ::std::bad_exception>(msg));
+    1945             : #if __cplusplus >= 201703L && __PLUMED_WRAPPER_LIBCXX17
+    1946             :     if(h.code>=11600 && h.code<11700) f(add_buffer_to< ::std::bad_optional_access>(msg));
+    1947             :     if(h.code>=11700 && h.code<11800) f(add_buffer_to< ::std::bad_variant_access>(msg));
+    1948             : #endif
+    1949             :     /* lepton error */
+    1950           0 :     if(h.code>=19900 && h.code<20000) f(Plumed::LeptonException(msg));
+    1951             :     /* plumed exceptions */
+    1952           0 :     if(h.code>=20000 && h.code<30000) {
+    1953             :       /* debug - only raised with debug options */
+    1954           0 :       if(h.code>=20100 && h.code<20200) f(Plumed::ExceptionDebug(msg));
+    1955             :       /* error - runtime check */
+    1956           0 :       if(h.code>=20200 && h.code<20300) f(Plumed::ExceptionError(msg));
+    1957             :       /* error - type error */
+    1958           0 :       if(h.code>=20300 && h.code<20400) f(Plumed::ExceptionTypeError(msg));
+    1959           0 :       f(Plumed::Exception(msg));
+    1960             :     }
+    1961             :     /* fallback for any other exception */
+    1962           0 :     f(add_buffer_to< ::std::exception>(msg));
+    1963           0 :   }
+    1964             : 
+    1965             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+    1966             :   /** Internal class used by exception_dispatch. */
+    1967             :   class rethrow_nested {
+    1968             :   public:
+    1969             :     template<typename E>
+    1970             :     __PLUMED_WRAPPER_CXX_NORETURN void operator()(const E&e) {
+    1971           0 :       std::throw_with_nested(e);
+    1972             :     }
+    1973             :   };
+    1974             : #endif
+    1975             : 
+    1976             :   /** Internal class used by exception_dispatch. */
+    1977             :   class rethrow_not_nested {
+    1978             :   public:
+    1979             :     template<typename E>
+    1980           0 :     __PLUMED_WRAPPER_CXX_NORETURN void operator()(const E&e) {
+    1981           0 :       throw e;
+    1982             :     }
+    1983             :   };
+    1984             : 
+    1985             :   /** Internal class to simplify plumed_error finalization */
+    1986             :   class finalize_plumed_error {
+    1987             :     plumed_error&e;
+    1988             :     finalize_plumed_error(const finalize_plumed_error&); //not implemented
+    1989             :   public:
+    1990           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT finalize_plumed_error(plumed_error&e):
+    1991           0 :       e(e)
+    1992             :     {}
+    1993           0 :     ~finalize_plumed_error() {
+    1994           0 :       plumed_error_finalize(e);
+    1995           0 :       e.code=0; // make sure it's not finalized again
+    1996           0 :     }
+    1997             :   };
+    1998             : 
+    1999             :   /**
+    2000             :     Recursive function that rethrows an exception with all the nested ones.
+    2001             : 
+    2002             :     In order to do so, we start throwing from the first exception that was originally thrown
+    2003             :     and recursively throw the others using throw_with_nested.
+    2004             : 
+    2005             :     plumed_error h is finalized at exit by the exception_dispatch function, to avoid memory leaks
+    2006             :   */
+    2007           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void rethrow(plumed_error&h) {
+    2008             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_CXX_ENABLE_NESTED_EXCEPTIONS
+    2009             :     /*
+    2010             :       When using C++11 nested exceptions, we need to rethrow recursively
+    2011             :     */
+    2012             :     try {
+    2013           0 :       if(h.nested) rethrow(*h.nested); /* recursive throw */
+    2014           0 :     } catch(...) {
+    2015           0 :       exception_dispatch(h,rethrow_nested());
+    2016           0 :     }
+    2017           0 :     exception_dispatch(h,rethrow_not_nested());
+    2018             : #else
+    2019             :     /*
+    2020             :       When using C++<11 exceptions, we merge the message and then throw the resulting exception
+    2021             :     */
+    2022             :     if(h.nested) plumed_error_merge_with_nested(&h);
+    2023             :     exception_dispatch(h,rethrow_not_nested());
+    2024             : #endif
+    2025             :   }
+    2026             : 
+    2027             : public:
+    2028             :   /**
+    2029             :     This is a tool to rethrow an error as an exception and finalize the error.
+    2030             : 
+    2031             :     In practice, this makes it possible to write a code like this:
+    2032             :     ```
+    2033             :     Plumed p;
+    2034             :     plumed_error e;
+    2035             :     // store error in e if something wrong happes
+    2036             :     // notice that Plumed (C++) is implicitly converted to plumed (C) when calling plumed_cmd
+    2037             :     plumed_cmd(p,"init",&e);
+    2038             :     // do other things here
+    2039             :     // then throw the exception
+    2040             :     if(e.code) plumed_error_rethrow(e);
+    2041             : 
+    2042             :     It should be used through the macro plumed_error_rethrow.
+    2043             :     ```
+    2044             :   */
+    2045             :   __PLUMED_WRAPPER_CXX_NORETURN static void plumed_error_rethrow_cxx(plumed_error h) {
+    2046           0 :     rethrow(h);
+    2047             :   }
+    2048             : 
+    2049             : private:
+    2050             :   /**
+    2051             :     Rethrow the current exception.
+    2052             : 
+    2053             :     This is useful in order to handle an exception thrown by a kernel <=2.4.
+    2054             :     Only std exceptions are handled, though some of them are thrown as special
+    2055             :     Plumed exceptions in order to be attached a message.
+    2056             :   */
+    2057           0 :   __PLUMED_WRAPPER_CXX_NORETURN static void rethrow() {
+    2058             :     try {
+    2059           0 :       throw;
+    2060           0 :     } catch(const ::std::bad_exception & e) {
+    2061           0 :       throw add_buffer_to< ::std::bad_exception>(e.what());
+    2062             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2063             :     } catch(const ::std::bad_array_new_length & e) {
+    2064             :       throw add_buffer_to< ::std::bad_array_new_length>(e.what());
+    2065             : #endif
+    2066           0 :     } catch(const ::std::bad_alloc & e) {
+    2067           0 :       throw add_buffer_to< ::std::bad_alloc>(e.what());
+    2068             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2069             :     } catch(const ::std::bad_function_call & e) {
+    2070             :       throw add_buffer_to< ::std::bad_function_call>(e.what());
+    2071             :     } catch(const ::std::bad_weak_ptr & e) {
+    2072             :       throw add_buffer_to< ::std::bad_weak_ptr>(e.what());
+    2073             : #endif
+    2074           0 :     } catch(const ::std::bad_cast & e) {
+    2075           0 :       throw add_buffer_to< ::std::bad_cast>(e.what());
+    2076           0 :     } catch(const ::std::bad_typeid & e) {
+    2077           0 :       throw add_buffer_to< ::std::bad_typeid>(e.what());
+    2078             :       // not implemented yet: std::regex_error
+    2079             :       // we do not allow regex yet due to portability problems with gcc 4.8
+    2080             :       // as soon as we transition to using <regex> it should be straightforward to add
+    2081           0 :     } catch(const ::std::ios_base::failure & e) {
+    2082             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2083             :       throw ::std::ios_base::failure(e.what(),e.code());
+    2084             : #else
+    2085           0 :       throw ::std::ios_base::failure(e.what());
+    2086             : #endif
+    2087             : #if __cplusplus > 199711L && __PLUMED_WRAPPER_LIBCXX11
+    2088             :     } catch(const ::std::system_error & e) {
+    2089             :       throw ::std::system_error(e.code(),e.what());
+    2090             : #endif
+    2091           0 :     } catch(const ::std::underflow_error &e) {
+    2092           0 :       throw ::std::underflow_error(e.what());
+    2093           0 :     } catch(const ::std::overflow_error &e) {
+    2094           0 :       throw ::std::overflow_error(e.what());
+    2095           0 :     } catch(const ::std::range_error &e) {
+    2096           0 :       throw ::std::range_error(e.what());
+    2097           0 :     } catch(const ::std::runtime_error & e) {
+    2098           0 :       throw ::std::runtime_error(e.what());
+    2099             :       // not implemented yet: std::future_error
+    2100             :       // not clear how useful it would be.
+    2101           0 :     } catch(const ::std::out_of_range & e) {
+    2102           0 :       throw ::std::out_of_range(e.what());
+    2103           0 :     } catch(const ::std::length_error & e) {
+    2104           0 :       throw ::std::length_error(e.what());
+    2105           0 :     } catch(const ::std::domain_error & e) {
+    2106           0 :       throw ::std::domain_error(e.what());
+    2107           0 :     } catch(const ::std::invalid_argument & e) {
+    2108           0 :       throw ::std::invalid_argument(e.what());
+    2109           0 :     } catch(const ::std::logic_error & e) {
+    2110           0 :       throw ::std::logic_error(e.what());
+    2111           0 :     } catch(const ::std::exception & e) {
+    2112           0 :       throw add_buffer_to< ::std::exception>(e.what());
+    2113           0 :     } catch(...) {
+    2114           0 :       throw add_buffer_to< ::std::bad_exception>("plumed could not translate exception");
+    2115           0 :     }
+    2116             :   }
+    2117             : 
+    2118             : public:
+    2119             : 
+    2120             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2121             :   using Exception = PLMD::Exception;
+    2122             : #else
+    2123             :   /**
+    2124             :     Base class used to rethrow PLUMED exceptions.
+    2125             :   */
+    2126             :   class Exception :
+    2127             :     public ::std::exception
+    2128             :   {
+    2129             :     ::std::string msg;
+    2130             :   public:
+    2131           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT Exception(const char* msg): msg(msg) {}
+    2132           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
+    2133             : #if ! (__cplusplus > 199711L)
+    2134             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2135             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2136             :     ~Exception() throw() {}
+    2137             : #endif
+    2138             :   };
+    2139             : #endif
+    2140             : 
+    2141             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2142             :   using ExceptionError = PLMD::ExceptionError;
+    2143             : #else
+    2144             :   /**
+    2145             :     Used to rethrow a PLMD::ExceptionError
+    2146             :   */
+    2147           0 :   class ExceptionError :
+    2148             :     public Exception {
+    2149             :   public:
+    2150           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionError(const char* msg): Exception(msg) {}
+    2151             : #if ! (__cplusplus > 199711L)
+    2152             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2153             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2154             :     ~ExceptionError() throw() {}
+    2155             : #endif
+    2156             :   };
+    2157             : #endif
+    2158             : 
+    2159             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2160             :   using ExceptionDebug = PLMD::ExceptionDebug;
+    2161             : #else
+    2162             :   /**
+    2163             :     Used to rethrow a PLMD::ExceptionDebug
+    2164             :   */
+    2165           0 :   class ExceptionDebug :
+    2166             :     public Exception {
+    2167             :   public:
+    2168           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionDebug(const char* msg): Exception(msg) {}
+    2169             : #if ! (__cplusplus > 199711L)
+    2170             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2171             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2172             :     ~ExceptionDebug() throw() {}
+    2173             : #endif
+    2174             :   };
+    2175             : #endif
+    2176             : 
+    2177             :   /**
+    2178             :     Thrown when trying to access an invalid plumed object
+    2179             :   */
+    2180             : 
+    2181           0 :   class Invalid :
+    2182             :     public Exception {
+    2183             :   public:
+    2184           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT Invalid(const char* msg): Exception(msg) {}
+    2185             : #if ! (__cplusplus > 199711L)
+    2186             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2187             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2188             :     ~Invalid() throw() {}
+    2189             : #endif
+    2190             :   };
+    2191             : 
+    2192             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2193             :   using ExceptionTypeError = PLMD::ExceptionTypeError;
+    2194             : #else
+    2195             :   /**
+    2196             :     Thrown when a wrong pointer is passed to the PLUMED interface.
+    2197             :   */
+    2198           0 :   class ExceptionTypeError:
+    2199             :     public Exception {
+    2200             :   public:
+    2201           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT ExceptionTypeError(const char* msg): Exception(msg) {}
+    2202             : #if ! (__cplusplus > 199711L)
+    2203             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2204             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2205             :     ~ExceptionTypeError() throw() {}
+    2206             : #endif
+    2207             :   };
+    2208             : #endif
+    2209             : 
+    2210             : #if __PLUMED_WRAPPER_CXX_ANONYMOUS_NAMESPACE_PLMD_EXCEPTIONS
+    2211             :   using LeptonException = PLMD::lepton::Exception;
+    2212             : #else
+    2213             :   /**
+    2214             :     Class used to rethrow Lepton exceptions.
+    2215             :   */
+    2216             : 
+    2217             :   class LeptonException :
+    2218             :     public ::std::exception
+    2219             :   {
+    2220             :     ::std::string msg;
+    2221             :   public:
+    2222           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT LeptonException(const char* msg): msg(msg) {}
+    2223           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {return msg.c_str();}
+    2224             : #if ! (__cplusplus > 199711L)
+    2225             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2226             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2227             :     ~LeptonException() throw() {}
+    2228             : #endif
+    2229             :   };
+    2230             : #endif
+    2231             : 
+    2232             : private:
+    2233             :   /*
+    2234             :     These exceptions are declared as private as they are not supposed to be
+    2235             :     catched by value. they only exist to allow a buffer to be attached to
+    2236             :     the std::exceptions that do not contain it already.
+    2237             :     Notice that these exceptions are those whose constructor should never throw, and as
+    2238             :     such they use a fixed size buffer.
+    2239             :   */
+    2240             : 
+    2241             :   template<typename T>
+    2242           0 :   class add_buffer_to:
+    2243             :     public T
+    2244             :   {
+    2245             :     char msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER];
+    2246           0 :     void init(const char* msg) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2247           0 :       this->msg[0]='\0';
+    2248           0 :       __PLUMED_WRAPPER_STD strncat(this->msg,msg,__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1);
+    2249           0 :       this->msg[__PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1]='\0';
+    2250           0 :       if(PlumedGetenvExceptionsDebug() && __PLUMED_WRAPPER_STD strlen(msg) > __PLUMED_WRAPPER_CXX_EXCEPTION_BUFFER-1) __PLUMED_WRAPPER_STD fprintf(stderr,"+++ WARNING: message will be truncated\n");
+    2251           0 :     }
+    2252             :   public:
+    2253           0 :     __PLUMED_WRAPPER_CXX_EXPLICIT add_buffer_to(const char * msg) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2254           0 :       init(msg);
+    2255             :     }
+    2256             :   add_buffer_to(const T& base,const char * msg) __PLUMED_WRAPPER_CXX_NOEXCEPT:
+    2257             :     T(base)
+    2258             :     {
+    2259             :       init(msg);
+    2260             :     }
+    2261           0 :   add_buffer_to(const add_buffer_to & other) __PLUMED_WRAPPER_CXX_NOEXCEPT:
+    2262           0 :     T(other)
+    2263             :     {
+    2264           0 :       init(other.msg);
+    2265             :     }
+    2266             :     add_buffer_to & operator=(const add_buffer_to & other) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2267             :       if(this==&other) return *this;
+    2268             :       init(other.msg);
+    2269             :       return *this;
+    2270             :     }
+    2271           0 :     const char* what() const __PLUMED_WRAPPER_CXX_NOEXCEPT __PLUMED_WRAPPER_CXX_OVERRIDE {
+    2272           0 :       return msg;
+    2273             :     }
+    2274             : #if ! (__cplusplus > 199711L)
+    2275             :     /* Destructor should be declared in order to have the correct throw() before C++11 */
+    2276             :     /* see https://stackoverflow.com/questions/50025862/why-is-the-stdexception-destructor-not-noexcept */
+    2277             :     ~add_buffer_to() throw() {}
+    2278             : #endif
+    2279             :   };
+    2280             : 
+    2281             : private:
+    2282             :   /// Small class that wraps plumed_safeptr in order to make its initialization easier
+    2283             :   class SafePtr {
+    2284             :     /// non copyable (copy would require managing buffer, could be added in the future if needed)
+    2285             :     SafePtr(const SafePtr&);
+    2286             :     /// non assignable (assignment would require managing buffer, could be added in the future if needed)
+    2287             :     SafePtr& operator=(SafePtr const&);
+    2288             :   public:
+    2289             :     plumed_safeptr safe;
+    2290             :     /// This buffer holds a copy of the data when they are passed by value.
+    2291             :     /// The size is sufficient to hold any primitive type.
+    2292             :     /// Notice that the buffer is required to enable conversions (e.g., passing a class that can be converted to int)
+    2293             :     /// and, at the same time, allow the object to exist after SafePtr constructor has completed.
+    2294             :     /// A perhaps cleaner implementation would require a base class containing
+    2295             :     /// the plumed_safeptr object, derived classes depending on the
+    2296             :     /// argument type as a template parameter, and overloaded functions
+    2297             :     /// returning this derived class.
+    2298             :     char buffer[32];
+    2299             :     /// Default constructor, nullptr
+    2300             :     SafePtr() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2301             :       safe.ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2302             :       safe.nelem=0;
+    2303             :       safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2304             :       safe.flags=0x10000*2;
+    2305             :       safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
+    2306             :       buffer[0]='\0';
+    2307             :     }
+    2308             : 
+    2309         222 :     __PLUMED_WRAPPER_CXX_EXPLICIT SafePtr(const plumed_safeptr & safe,__PLUMED_WRAPPER_STD size_t nelem=0, const __PLUMED_WRAPPER_STD size_t* shape=__PLUMED_WRAPPER_CXX_NULLPTR) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2310         222 :       this->safe=safe;
+    2311         222 :       buffer[0]='\0';
+    2312             :       if(nelem>0) this->safe.nelem=nelem;
+    2313             :       if(shape) this->safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape);
+    2314             :     }
+    2315             : 
+    2316             : #if __cplusplus > 199711L
+    2317             :     /// Construct from null
+    2318             :     SafePtr(__PLUMED_WRAPPER_STD nullptr_t,__PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) noexcept {
+    2319             :       safe.ptr=nullptr;
+    2320             :       safe.nelem=0;
+    2321             :       safe.shape=nullptr;
+    2322             :       safe.flags=0x10000*2;
+    2323             :       safe.opt=nullptr;
+    2324             :       buffer[0]='\0';
+    2325             :       (void) nelem;
+    2326             :       (void) shape;
+    2327             :     }
+    2328             : #endif
+    2329             : 
+    2330             : /// Macro that generate a constructor with given type and flags
+    2331             : #define __PLUMED_WRAPPER_SAFEPTR_INNER(type_,flags_) \
+    2332             :   SafePtr(type_*ptr, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    2333             :     safe.ptr=ptr; \
+    2334             :     safe.nelem=nelem; \
+    2335             :     safe.shape=const_cast<__PLUMED_WRAPPER_STD size_t*>(shape); \
+    2336             :     safe.flags=flags_; \
+    2337             :     safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2338             :     buffer[0]='\0'; \
+    2339             :   }
+    2340             : 
+    2341             : /// Macro that uses __PLUMED_WRAPPER_SAFEPTR_INNER to generate constructors with
+    2342             : /// all possible pointer-const combinations
+    2343             : #define __PLUMED_WRAPPER_SAFEPTR(type,code,size) \
+    2344             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type,             size | (0x10000*(code)) | (0x2000000*2)) \
+    2345             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const,       size | (0x10000*(code)) | (0x2000000*3)) \
+    2346             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type*,            size | (0x10000*(code)) | (0x2000000*4)) \
+    2347             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type*const,       size | (0x10000*(code)) | (0x2000000*5)) \
+    2348             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const*,      size | (0x10000*(code)) | (0x2000000*6)) \
+    2349             :   __PLUMED_WRAPPER_SAFEPTR_INNER(type const*const, size | (0x10000*(code)) | (0x2000000*7))
+    2350             : 
+    2351             : /// Macro that generates the constructors from empy types (those of which sizeof cannot be computed)
+    2352             : #define __PLUMED_WRAPPER_SAFEPTR_EMPTY(type,code) __PLUMED_WRAPPER_SAFEPTR(type,code,0)
+    2353             : 
+    2354             : /// Macro that generates the constructors from sized types (those of which sizeof can be computed).
+    2355             : /// In addition to generating constructors with all pointer types, it generates a constructor to
+    2356             : /// allow pass-by-value
+    2357             : #define __PLUMED_WRAPPER_SAFEPTR_SIZED(type,code) \
+    2358             :   __PLUMED_WRAPPER_SAFEPTR(type,code,sizeof(type)) \
+    2359             :   SafePtr(type val, __PLUMED_WRAPPER_STD size_t nelem, const __PLUMED_WRAPPER_STD size_t* shape) __PLUMED_WRAPPER_CXX_NOEXCEPT { \
+    2360             :     assert(sizeof(type)<=32); \
+    2361             :     (void) nelem; \
+    2362             :     (void) shape; \
+    2363             :     safe.ptr=buffer; \
+    2364             :     safe.nelem=1; \
+    2365             :     safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2366             :     safe.flags=sizeof(type) | (0x10000*(code)) | (0x2000000*1); \
+    2367             :     safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR; \
+    2368             :     __PLUMED_WRAPPER_STD memcpy(buffer,&val,sizeof(type)); \
+    2369             :   }
+    2370             : 
+    2371             : /// Here we create all the required instances
+    2372             : /// 1: void
+    2373             : /// 3: integral
+    2374             : /// 4: floating
+    2375             : /// 5: FILE
+    2376             : /// 0x100: unsigned
+    2377         340 :     __PLUMED_WRAPPER_SAFEPTR_EMPTY(void,1)
+    2378        4144 :     __PLUMED_WRAPPER_SAFEPTR_SIZED(char,(CHAR_MIN==0)*0x100+3)
+    2379             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned char,3)
+    2380             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(signed char,0x100+3)
+    2381             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(short,3)
+    2382             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned short,0x100+3)
+    2383        8288 :     __PLUMED_WRAPPER_SAFEPTR_SIZED(int,3)
+    2384             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned int,0x100+3)
+    2385             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long,3)
+    2386             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long,0x100+3)
+    2387             : #if __PLUMED_WRAPPER_CXX_LONGLONG
+    2388             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long long,3)
+    2389             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(unsigned long long,0x100+3)
+    2390             : #endif
+    2391             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(float,4)
+    2392             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(double,4)
+    2393             :     __PLUMED_WRAPPER_SAFEPTR_SIZED(long double,4)
+    2394             :     __PLUMED_WRAPPER_SAFEPTR_EMPTY(FILE,5)
+    2395             : 
+    2396             :     /// Return the contained plumed_safeptr
+    2397             :     plumed_safeptr get_safeptr() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2398       12994 :       return safe;
+    2399             :     }
+    2400             : 
+    2401             :   };
+    2402             : 
+    2403             : public:
+    2404             : 
+    2405             :   /**
+    2406             :      Check if plumed is installed (for runtime binding)
+    2407             :      \return true if plumed is installed, false otherwise
+    2408             :      \note Equivalent to plumed_installed() but returns a bool
+    2409             :   */
+    2410             :   static bool installed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2411             :     return plumed_installed();
+    2412             :   }
+    2413             :   /**
+    2414             :      Check if Plumed object is valid. Available as of PLUMED 2.5
+    2415             :      \return true if plumed is valid, false otherwise
+    2416             :      \note Equivalent to plumed_valid() but returns a bool
+    2417             :   */
+    2418             :   bool valid() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2419             :     return plumed_valid(main);
+    2420             :   }
+    2421             : #if __cplusplus > 199711L
+    2422             :   /**
+    2423             :      Same as \ref valid(). Available as of PLUMED 2.5.
+    2424             : 
+    2425             :   Allow code such as
+    2426             :   \verbatim
+    2427             :   Plumed p;
+    2428             :   if(!p) raise_error();
+    2429             :   p.cmd("init");
+    2430             :   \endverbatim
+    2431             : 
+    2432             :   In order to avoid ambiguous conversions, this is only allowed when compiling with C++11
+    2433             :   where it is marked as explicit.
+    2434             :   */
+    2435             :   explicit
+    2436             :   operator bool() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2437             :     return plumed_valid(main);
+    2438             :   }
+    2439             : #endif
+    2440             : 
+    2441             :   /**
+    2442             :      Returns the number of references to this object. Available as of PLUMED 2.5.
+    2443             :     \note Equivalent to plumed_use_count()
+    2444             :   */
+    2445             :   int useCount() const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2446             :     return plumed_use_count(main);
+    2447             :   }
+    2448             : 
+    2449             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    2450             :   /**
+    2451             :      Check if global-plumed has been initialized
+    2452             :      \return true if global plumed object (see global()) is initialized (i.e. if gcreate() has been
+    2453             :              called), false otherwise.
+    2454             :      \note Equivalent to plumed_ginitialized() but returns a bool
+    2455             :   */
+    2456             :   static bool ginitialized() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2457             :     return plumed_ginitialized();
+    2458             :   }
+    2459             :   /**
+    2460             :      Check if global-plumed is valid
+    2461             :      \return true if global plumed object (see global()) is valid.
+    2462             :      \note Equivalent to plumed_gvalid() but returns a bool
+    2463             :   */
+    2464             :   static bool gvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2465             :     return plumed_gvalid();
+    2466             :   }
+    2467             :   /**
+    2468             :      Initialize global-plumed.
+    2469             :      \warning Using the global objects in C++ is not recommended since they are difficult to use in
+    2470             :               an exception safe manner. In particular, one should explicitly catch exceptions to
+    2471             :               properly call gfinalize()
+    2472             :      \note Equivalent to plumed_gcreate()
+    2473             :   */
+    2474             :   static void gcreate() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2475             :     plumed_gcreate();
+    2476             :   }
+    2477             :   /**
+    2478             :      Send a command to global-plumed
+    2479             :       \param key The name of the command to be executed
+    2480             :      \note Equivalent to plumed_gcmd()
+    2481             :   */
+    2482             :   static void gcmd(const char*key) {
+    2483             :     global().cmd(key);
+    2484             :   }
+    2485             :   /**
+    2486             :      Send a command to global-plumed
+    2487             :       \param key The name of the command to be executed
+    2488             :       \param val The argument.
+    2489             :      \note Equivalent to plumed_gcmd()
+    2490             :   */
+    2491             :   template<typename T>
+    2492             :   static void gcmd(const char*key,T val) {
+    2493             :     global().cmd(key,val);
+    2494             :   }
+    2495             :   /**
+    2496             :      Send a command to global-plumed
+    2497             :       \param key The name of the command to be executed
+    2498             :       \param val The argument.
+    2499             :       \param nelem Number of elements in the passed array, for typechecking.
+    2500             :      \note Equivalent to plumed_gcmd()
+    2501             :   */
+    2502             :   template<typename T>
+    2503             :   static void gcmd(const char*key,T* val,__PLUMED_WRAPPER_STD size_t nelem) {
+    2504             :     global().cmd(key,val,nelem);
+    2505             :   }
+    2506             : 
+    2507             :   /**
+    2508             :      Send a command to global-plumed
+    2509             :       \param key The name of the command to be executed
+    2510             :       \param val The argument.
+    2511             :       \param shape The shape of the argument.
+    2512             :      \note Equivalent to plumed_gcmd()
+    2513             :   */
+    2514             :   template<typename T>
+    2515             :   static void gcmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
+    2516             :     global().cmd(key,val,shape);
+    2517             :   }
+    2518             : 
+    2519             : #if __cplusplus > 199711L
+    2520             :   /**
+    2521             :      Send a command to global-plumed
+    2522             :       \param key The name of the command to be executed
+    2523             :       \param val The argument.
+    2524             :       \param shape The shape of the argument, in the form of an initialier_list (e.g., {10,3}).
+    2525             :      \note Equivalent to plumed_gcmd()
+    2526             :   */
+    2527             :   template<typename T>
+    2528             :   static void gcmd(const char*key,T* val, std::initializer_list<std::size_t> shape) {
+    2529             :     global().cmd(key,val,shape);
+    2530             :   }
+    2531             : #endif
+    2532             : 
+    2533             :   /**
+    2534             :      Finalize global-plumed
+    2535             :   */
+    2536             :   static void gfinalize() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2537             :     plumed_gfinalize();
+    2538             :   }
+    2539             :   /**
+    2540             :      Returns the Plumed global object
+    2541             : 
+    2542             :      Notice that the object is copied, thus increasing the reference counter of the
+    2543             :      global object. In this manner, the global object will survive after a call to
+    2544             :      \ref gfinalize() if the resulting object is still in scope.
+    2545             : 
+    2546             :      \return The Plumed global object
+    2547             :   */
+    2548             :   static Plumed global() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2549             :     return Plumed(plumed_global());
+    2550             :   }
+    2551             : #endif /*}*/
+    2552             :   /**
+    2553             :      Constructor.
+    2554             : 
+    2555             :     Notice that when using runtime binding the constructed object might be
+    2556             :     invalid. One might check it using the \ref valid() method.
+    2557             : 
+    2558             :     \note Performs the same task a plumed_create()
+    2559             :   */
+    2560        4144 : Plumed()__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2561             : #if __PLUMED_WRAPPER_CXX_DEFAULT_INVALID
+    2562             :   main(plumed_create_invalid())
+    2563             : #else
+    2564        4144 :   main(plumed_create())
+    2565             : #endif
+    2566             :   {
+    2567             :   }
+    2568             : 
+    2569             :   /**
+    2570             :      Clone a Plumed object from a FORTRAN char* handler.
+    2571             : 
+    2572             :      \param c The FORTRAN handler (a char[32]).
+    2573             : 
+    2574             :      The reference counter for the corresponding object will be increased
+    2575             :      to make sure that the object will be available after plumed_f_finalize is called
+    2576             :      if the created object is still in scope.
+    2577             :   */
+    2578             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(const char*c)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2579             :   main(plumed_create_reference_f(c))
+    2580             :   {
+    2581             :   }
+    2582             : 
+    2583             :   /**
+    2584             :     Create a reference from a void* pointer. Available as of PLUMED 2.5.
+    2585             :   */
+    2586             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(void*v)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2587             :   main(plumed_create_reference_v(v))
+    2588             :   {
+    2589             :   }
+    2590             : 
+    2591             :   /**
+    2592             :      Clone a Plumed object from a C plumed structure
+    2593             : 
+    2594             :      \param p The C plumed structure.
+    2595             : 
+    2596             :      The reference counter for the corresponding object will be increased
+    2597             :      to make sure that the object will be available after plumed_finalize is called
+    2598             :      if the created object is still in scope.
+    2599             :   */
+    2600             : __PLUMED_WRAPPER_CXX_EXPLICIT Plumed(plumed p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2601             :   main(plumed_create_reference(p))
+    2602             :   {
+    2603             :   }
+    2604             : 
+    2605             :   /** Copy constructor.
+    2606             : 
+    2607             :     Takes a reference, incrementing the reference counter of the corresponding object.
+    2608             :   */
+    2609             : Plumed(const Plumed& p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2610             :   main(plumed_create_reference(p.main))
+    2611             :   {
+    2612             :   }
+    2613             : 
+    2614             :   /** Assignment operator. Available as of PLUMED 2.5.
+    2615             : 
+    2616             :     Takes a reference,incrementing the reference counter of the corresponding object.
+    2617             :   */
+    2618             :   Plumed&operator=(const Plumed&p) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2619             :     if(this != &p) {
+    2620             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2621             :       if(main.p) plumed_finalize(main);
+    2622             :       main=plumed_create_reference(p.main);
+    2623             :     }
+    2624             :     return *this;
+    2625             :   }
+    2626             : 
+    2627             :   /*
+    2628             :     PLUMED >= 2.4 requires a C++11 compiler.
+    2629             :     Anyway, since Plumed.h file might be redistributed with other codes
+    2630             :     and it should be possible to combine it with earlier PLUMED versions,
+    2631             :     we here explicitly check if C+11 is available before enabling move semantics.
+    2632             :   */
+    2633             : #if __cplusplus > 199711L
+    2634             :   /** Move constructor. Available as of PLUMED 2.5.
+    2635             :     Only if move semantics is enabled.
+    2636             :   */
+    2637             : Plumed(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT :
+    2638             :   main(p.main)
+    2639             :   {
+    2640             :     p.main.p=nullptr;
+    2641             :   }
+    2642             :   /** Move assignment. Available as of PLUMED 2.5.
+    2643             :     Only if move semantics is enabled.
+    2644             :   */
+    2645             :   Plumed& operator=(Plumed&&p)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2646             :     if(this != &p) {
+    2647             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2648             :       if(main.p) plumed_finalize(main);
+    2649             :       main=p.main;
+    2650             :       p.main.p=nullptr;
+    2651             :     }
+    2652             :     return *this;
+    2653             :   }
+    2654             : #endif
+    2655             :   /**
+    2656             :     Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
+    2657             : 
+    2658             :     It returns an object created with \ref plumed_create_dlopen. The object is owned and
+    2659             :     is then finalized in the destructor. It can be used as follows:
+    2660             :   \verbatim
+    2661             :     PLMD::Plumed p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
+    2662             :   // or, equivalenty:
+    2663             :   //    PLMD::Plumed p(PLMD::Plumed::dlopen("/path/to/libplumedKernel.so"));
+    2664             :     p.cmd("init");
+    2665             :   \endverbatim
+    2666             :     or, equivalently, as
+    2667             :   \verbatim
+    2668             :     auto p = PLMD::Plumed::dlopen("/path/to/libplumedKernel.so");
+    2669             :     p.cmd("init");
+    2670             :   \endverbatim
+    2671             :   */
+    2672             :   static Plumed dlopen(const char* path)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2673             :     plumed p=plumed_create_dlopen(path);
+    2674             :     Plumed pp(p);
+    2675             :     plumed_finalize(p);
+    2676             :     return pp;
+    2677             :   }
+    2678             : 
+    2679             :   /**
+    2680             :     Create a PLUMED object loading a specific kernel. Available as of PLUMED 2.5.
+    2681             : 
+    2682             :     Same as \ref dlopen(const char* path), but allows a dlopen mode to be chosen explicitly.
+    2683             :   */
+    2684             :   static Plumed dlopen(const char* path,int mode)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2685             :     plumed p=plumed_create_dlopen2(path,mode);
+    2686             :     Plumed pp(p);
+    2687             :     plumed_finalize(p);
+    2688             :     return pp;
+    2689             :   }
+    2690             :   /**
+    2691             :     Create a PLUMED object loading from an already opened shared library. Available as of PLUMED 2.8.
+    2692             : 
+    2693             :     Same as \ref dlopen(const char* path), but searches functions in an already loaded library.
+    2694             :     See \ref plumed_create_dlsym.
+    2695             :   */
+    2696             :   static Plumed dlsym(void* dlhandle)__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2697             :     plumed p=plumed_create_dlsym(dlhandle);
+    2698             :     Plumed pp(p);
+    2699             :     plumed_finalize(p);
+    2700             :     return pp;
+    2701             :   }
+    2702             : 
+    2703             :   /** Invalid constructor. Available as of PLUMED 2.5.
+    2704             : 
+    2705             :     Can be used to initialize an invalid object. It might be useful to postpone
+    2706             :     the initialization of a Plumed object. Consider the following case
+    2707             :   \verbatim
+    2708             :     Plumed p;
+    2709             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2710             :     p.cmd("init")
+    2711             :   \endverbatim
+    2712             :     Here the `p` object will be initialized *before* the `PLUMED_KERNEL` env var has been set.
+    2713             :     This can be particularly problematic if `p` is stored in some high level class.
+    2714             :     The following case would do the job
+    2715             :   \verbatim
+    2716             :     Plumed p;
+    2717             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2718             :     p=Plumed();
+    2719             :     p.cmd("init")
+    2720             :   \endverbatim
+    2721             :     However, there will be some error reported related to the attempt to load the kernel
+    2722             :     when `p` is initialized. The following solution is the optimal one:
+    2723             :   \verbatim
+    2724             :     Plumed p(Plumed::makeInvalid());
+    2725             :     setenv("PLUMED_KERNEL","/path/to/kernel/libplumedKernel.so",1);
+    2726             :     p=Plumed();
+    2727             :     p.cmd("init")
+    2728             :   \endverbatim
+    2729             :   */
+    2730             :   static Plumed makeInvalid() __PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2731             :     plumed p=plumed_create_invalid();
+    2732             :     Plumed pp(p);
+    2733             :     plumed_finalize(p);
+    2734             :     return pp;
+    2735             :   }
+    2736             : 
+    2737             :   /**
+    2738             :     Create a valid PLMD::Plumed object.
+    2739             : 
+    2740             :     Can be used to create a valid object e.g. when Plumed.h was compiled with
+    2741             :     `-D__PLUMED_WRAPPER_CXX_DEFAULT_INVALID`. For internal usage.
+    2742             :   */
+    2743             : 
+    2744             :   static Plumed makeValid()__PLUMED_WRAPPER_CXX_NOEXCEPT  {
+    2745             :     plumed p=plumed_create();
+    2746             :     Plumed pp(p);
+    2747             :     plumed_finalize(p);
+    2748             :     return pp;
+    2749             :   }
+    2750             : 
+    2751             : 
+    2752             :   /**
+    2753             :      Retrieve the C plumed structure for this object.
+    2754             : 
+    2755             :      Notice that the resulting plumed structure is a weak reference and
+    2756             :      should NOT be finalized, unless a new reference is explicitly added
+    2757             :   \verbatim
+    2758             :   Plumed p;
+    2759             :   plumed c=p;
+    2760             :   plumed_finalize(c); // <- this is wrong
+    2761             :   \endverbatim
+    2762             :   \verbatim
+    2763             :   Plumed p;
+    2764             :   plumed c=plumed_create_reference(p);
+    2765             :   plumed_finalize(c); // <- this is right
+    2766             :   \endverbatim
+    2767             :   */
+    2768             :   operator plumed()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2769             :     return main;
+    2770             :   }
+    2771             : 
+    2772             :   /**
+    2773             :      Retrieve a FORTRAN handler for this object
+    2774             :       \param c The FORTRAN handler (a char[32]).
+    2775             :     Notice that the resulting plumed structure is a weak reference and
+    2776             :     should NOT be finalized, unless a new reference is explicitly added.
+    2777             :   */
+    2778             :   void toFortran(char*c)const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2779             :     plumed_c2f(main,c);
+    2780             :   }
+    2781             : 
+    2782             :   /**
+    2783             :      Retrieve a void* handler for this object. Available as of PLUMED 2.5.
+    2784             :     Notice that the resulting plumed structure is a weak reference and
+    2785             :     should NOT be finalized, unless a new reference is explicitly added.
+    2786             :   */
+    2787             :   void* toVoid()const __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2788             :     return plumed_c2v(main);
+    2789             :   }
+    2790             : 
+    2791             :   /**
+    2792             :     Increase reference counter. Available as of PLUMED 2.5.
+    2793             : 
+    2794             :     Using this method improperly might interfere with correct object construction
+    2795             :     and destruction.
+    2796             :     If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
+    2797             : 
+    2798             :     A possible usage is to transfer the ownership of a temporary
+    2799             :     object when it is converted
+    2800             :   \verbatim
+    2801             :   plumed p=Plumed::dlopen(path).incref()
+    2802             :   // without incref(), the just constructed object will be destroyed
+    2803             :   // when the temporary object is deleted.
+    2804             :   ... do stuff ...
+    2805             :   plumed_finalize(p);
+    2806             :   \endverbatim
+    2807             : 
+    2808             :   */
+    2809             :   Plumed& incref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2810             :     plumed_create_reference(main);
+    2811             :     return *this;
+    2812             :   }
+    2813             : 
+    2814             :   /**
+    2815             :     Decrease reference counter. Available as of PLUMED 2.5.
+    2816             : 
+    2817             :     Using this method improperly might interfere with correct object construction
+    2818             :     and destruction.
+    2819             :     If you want to play with this, also try to compile using `-D__PLUMED_WRAPPER_DEBUG_REFCOUNT=1` and see what happens.
+    2820             :   */
+    2821             :   Plumed& decref() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2822             : // calling decref on a moved plumed object should give an error, so we do not check if main.p!=NULL here:
+    2823             :     plumed_finalize(main);
+    2824             :     return *this;
+    2825             :   }
+    2826             : 
+    2827             : private:
+    2828             : 
+    2829             :   /**
+    2830             :     Private version of cmd. It is used here to avoid duplication of code between typesafe and not-typesafe versions
+    2831             :   */
+    2832       12994 :   static void cmd_priv(plumed main,const char*key, SafePtr*safe=__PLUMED_WRAPPER_CXX_NULLPTR, const void* unsafe=__PLUMED_WRAPPER_CXX_NULLPTR,plumed_error*error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2833             : 
+    2834             :     plumed_error error_cxx;
+    2835             :     plumed_error_init(&error_cxx);
+    2836             : 
+    2837             :     plumed_nothrow_handler nothrow;
+    2838       12994 :     if(error) {
+    2839             :       plumed_error_init(error);
+    2840           0 :       nothrow.ptr=error;
+    2841             :     } else {
+    2842       12994 :       nothrow.ptr=&error_cxx;
+    2843             :     }
+    2844       12994 :     nothrow.handler=plumed_error_set;
+    2845             : 
+    2846             :     try {
+    2847       12994 :       if(safe) {
+    2848       12994 :         plumed_cmd_safe_nothrow(main,key,safe->get_safeptr(),nothrow);
+    2849             :       } else {
+    2850           0 :         plumed_cmd_nothrow(main,key,unsafe,nothrow);
+    2851             :       }
+    2852           0 :     } catch (...) {
+    2853             :       assert(error_cxx.code==0); /* no need to plumed_error_finalize here */
+    2854             :       /*
+    2855             :         When loading a kernel <=2.4, plumed_cmd_nothrow could throw an exception.
+    2856             :         If the exception is transmitted through the C interface and arrives here,
+    2857             :         we translate it so as to free the virtual tables of the loaded kernel.
+    2858             :       */
+    2859           0 :       rethrow();
+    2860           0 :     }
+    2861             :     /* plumed_error_rethrow is finalizing */
+    2862       12994 :     if(!error && error_cxx.code!=0) plumed_error_rethrow_cxx(error_cxx);
+    2863       12994 :   }
+    2864             : 
+    2865             : public:
+    2866             : 
+    2867             :   /**
+    2868             :      Send a command to this plumed object
+    2869             :       \param key The name of the command to be executed
+    2870             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2871             :             rethrow any exception raised within PLUMED.
+    2872             :   */
+    2873             :   void cmd(const char*key) {
+    2874             :     plumed_cmd_cxx(main,key);
+    2875             :   }
+    2876             : 
+    2877             :   /**
+    2878             :      Send a command to this plumed object
+    2879             :       \param key The name of the command to be executed
+    2880             :       \param val The argument, passed by value.
+    2881             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2882             :             rethrow any exception raised within PLUMED.
+    2883             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2884             :              the type of the argument is checked.
+    2885             :   */
+    2886             :   template<typename T>
+    2887             :   void cmd(const char*key,T val) {
+    2888       12772 :     plumed_cmd_cxx(main,key,val);
+    2889       12772 :   }
+    2890             : 
+    2891             :   /**
+    2892             :      Send a command to this plumed object
+    2893             :       \param key The name of the command to be executed
+    2894             :       \param val The argument, passed by pointer.
+    2895             :       \param shape A zero-terminated array containing the shape of the data.
+    2896             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2897             :             rethrow any exception raised within PLUMED.
+    2898             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2899             :              the type of the argument is checked. If shape is passed, it is also
+    2900             :              checked that PLUMED access only compatible indexes.
+    2901             :   */
+    2902             :   template<typename T>
+    2903             :   void cmd(const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape) {
+    2904             :     plumed_cmd_cxx(main,key,val,shape);
+    2905             :   }
+    2906             : 
+    2907             : #if __cplusplus > 199711L
+    2908             :   /**
+    2909             :      Send a command to this plumed object
+    2910             :       \param key The name of the command to be executed
+    2911             :       \param val The argument, passed by pointer.
+    2912             :       \param shape The shape of the argument, in the form of an initialier_list (e.g., {10,3}).
+    2913             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2914             :             rethrow any exception raised within PLUMED.
+    2915             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2916             :              the type of the argument is checked. If shape is passed, it is also
+    2917             :              checked that PLUMED access only compatible indexes.
+    2918             :   */
+    2919             :   template<typename T>
+    2920             :   void cmd(const char*key,T* val, std::initializer_list<std::size_t> shape) {
+    2921             :     if(shape.size()>4) throw Plumed::ExceptionTypeError("Maximum shape size is 4");
+    2922             :     std::array<std::size_t,5> shape_;
+    2923             :     unsigned j=0;
+    2924             :     for(auto i : shape) {
+    2925             :       shape_[j]=i;
+    2926             :       j++;
+    2927             :     }
+    2928             :     shape_[j]=0;
+    2929             :     plumed_cmd_cxx(main,key,val,&shape_[0]);
+    2930             :   }
+    2931             : #endif
+    2932             :   /**
+    2933             :      Send a command to this plumed object
+    2934             :       \param key The name of the command to be executed
+    2935             :       \param val The argument, passed by pointer.
+    2936             :       \param nelem The number of elements passed.
+    2937             :       \note Similar to \ref plumed_cmd(). It actually called \ref plumed_cmd_nothrow() and
+    2938             :             rethrow any exception raised within PLUMED.
+    2939             :       \note Unless one defines __PLUMED_WRAPPER_CXX_TYPESAFE=0 or PLUMED library is <=2.7,
+    2940             :              the type of the argument is checked.  nelem is used to check
+    2941             :              the maximum index interpreting the array as flattened.
+    2942             :   */
+    2943             :   template<typename T>
+    2944             :   void cmd(const char*key,T* val, __PLUMED_WRAPPER_STD size_t nelem) {
+    2945             :     plumed_cmd_cxx(main,key,val,nelem);
+    2946             :   }
+    2947             : 
+    2948             :   /**
+    2949             :      Destructor
+    2950             : 
+    2951             :      It calls \ref plumed_finalize(). Notice that this is done also if the
+    2952             :      constructor failed (that is, if it returned an invalid object). This allows
+    2953             :      declaring Plumed objects also if PLUMED is actually not available, provided
+    2954             :      one does not use the \ref cmd method.
+    2955             : 
+    2956             :      Destructor is virtual so as to allow correct inheritance from Plumed object.
+    2957             :   */
+    2958             : #if __PLUMED_WRAPPER_CXX_POLYMORPHIC
+    2959             :   virtual
+    2960             : #endif
+    2961             :   ~Plumed() __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    2962             : // the check is needed to avoid calling plumed_finalize on moved objects
+    2963        4144 :     if(main.p) plumed_finalize(main);
+    2964        4144 :   }
+    2965             : 
+    2966             :   /**
+    2967             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2968             :     namely implement typechecks and rethrowing exception.
+    2969             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2970             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2971             :     Available as of PLUMED 2.8.
+    2972             :   */
+    2973             :   static void plumed_cmd_cxx(plumed p,const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2974             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2975             :     SafePtr s;
+    2976             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2977             : #else
+    2978             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2979             : #endif
+    2980             :   }
+    2981             : 
+    2982             :   /**
+    2983             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    2984             :     namely implement typechecks and rethrowing exception.
+    2985             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    2986             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    2987             :     Available as of PLUMED 2.8.
+    2988             :   */
+    2989             :   template<typename T>
+    2990         222 :   static void plumed_cmd_cxx(plumed p,const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    2991             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    2992             :     SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
+    2993         222 :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    2994             : #else
+    2995             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,&val,error);
+    2996             : #endif
+    2997         222 :   }
+    2998             : 
+    2999             :   /**
+    3000             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3001             :     namely implement typechecks and rethrowing exception.
+    3002             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3003             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3004             :     Available as of PLUMED 2.8.
+    3005             :   */
+    3006             :   template<typename T>
+    3007       12772 :   static void plumed_cmd_cxx(plumed p,const char*key,T* val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3008             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    3009             :     SafePtr s(val,0,__PLUMED_WRAPPER_CXX_NULLPTR);
+    3010       12772 :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    3011             : #else
+    3012             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    3013             : #endif
+    3014       12772 :   }
+    3015             : 
+    3016             :   /**
+    3017             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3018             :     namely implement typechecks and rethrowing exception.
+    3019             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3020             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3021             :     Available as of PLUMED 2.8.
+    3022             :   */
+    3023             :   template<typename T>
+    3024             :   static void plumed_cmd_cxx(plumed p,const char*key,T* val, __PLUMED_WRAPPER_STD size_t nelem,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3025             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    3026             :     SafePtr s(val,nelem,__PLUMED_WRAPPER_CXX_NULLPTR);
+    3027             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    3028             : #else
+    3029             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    3030             : #endif
+    3031             :   }
+    3032             : 
+    3033             :   /**
+    3034             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3035             :     namely implement typechecks and rethrowing exception.
+    3036             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3037             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3038             :     Available as of PLUMED 2.8.
+    3039             :   */
+    3040             :   template<typename T>
+    3041             :   static void plumed_cmd_cxx(plumed p,const char*key,T* val, const __PLUMED_WRAPPER_STD size_t* shape,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3042             : #if __PLUMED_WRAPPER_CXX_TYPESAFE
+    3043             :     SafePtr s(val,0,shape);
+    3044             :     cmd_priv(p,key,&s,__PLUMED_WRAPPER_CXX_NULLPTR,error);
+    3045             : #else
+    3046             :     cmd_priv(p,key,__PLUMED_WRAPPER_CXX_NULLPTR,val,error);
+    3047             : #endif
+    3048             :   }
+    3049             : 
+    3050             : 
+    3051             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    3052             :   /**
+    3053             :     \related Plumed
+    3054             :     This function can be used to make plumed_gcmd behave as the C++ wrapper PLMD::Plumed::gcmd,
+    3055             :     namely implement typechecks and rethrowing exception.
+    3056             :     To be used through the macro plumed_gcmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3057             :     Available as of PLUMED 2.8.
+    3058             :   */
+    3059             : 
+    3060             :   /**
+    3061             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3062             :     namely implement typechecks and rethrowing exception.
+    3063             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3064             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3065             :     Available as of PLUMED 2.8.
+    3066             :   */
+    3067             :   static void plumed_gcmd_cxx(const char*key,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3068             :     plumed_cmd_cxx(plumed_global(),key,error);
+    3069             :   }
+    3070             : 
+    3071             :   /**
+    3072             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3073             :     namely implement typechecks and rethrowing exception.
+    3074             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3075             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3076             :     Available as of PLUMED 2.8.
+    3077             :   */
+    3078             :   template<typename T>
+    3079             :   static void plumed_gcmd_cxx(const char*key,T val,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3080             :     plumed_cmd_cxx(plumed_global(),key,val,error);
+    3081             :   }
+    3082             : 
+    3083             :   /**
+    3084             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3085             :     namely implement typechecks and rethrowing exception.
+    3086             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3087             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3088             :     Available as of PLUMED 2.8.
+    3089             :   */
+    3090             :   template<typename T>
+    3091             :   static void plumed_gcmd_cxx(const char*key,T val, __PLUMED_WRAPPER_STD size_t nelem,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3092             :     plumed_cmd_cxx(plumed_global(),key,val,nelem,error);
+    3093             :   }
+    3094             : 
+    3095             :   /**
+    3096             :     These functions can be used to make plumed_cmd behave as the C++ wrapper PLMD::Plumed::cmd,
+    3097             :     namely implement typechecks and rethrowing exception.
+    3098             :     To be used through the macro plumed_cmd (defined when __PLUMED_WRAPPER_CXX_BIND_C==1).
+    3099             :     They are also used by the Plumed::cmd functions to avoid code duplication.
+    3100             :     Available as of PLUMED 2.8.
+    3101             :   */
+    3102             :   template<typename T>
+    3103             :   static void plumed_gcmd_cxx(const char*key,T val, const __PLUMED_WRAPPER_STD size_t* shape,plumed_error* error=__PLUMED_WRAPPER_CXX_NULLPTR) {
+    3104             :     plumed_cmd_cxx(plumed_global(),key,val,shape,error);
+    3105             :   }
+    3106             : 
+    3107             : #endif /*}*/
+    3108             : 
+    3109             : #if __PLUMED_WRAPPER_CXX_BIND_C /*{*/
+    3110             : 
+    3111             : #define __PLUMED_WRAPPER_REDEFINE_CMD ::PLMD::Plumed::plumed_cmd_cxx
+    3112             : 
+    3113             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    3114             : #define __PLUMED_WRAPPER_REDEFINE_GCMD ::PLMD::Plumed::plumed_gcmd_cxx
+    3115             : #endif /*}*/
+    3116             : 
+    3117             : #define __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW ::PLMD::Plumed::plumed_error_rethrow_cxx
+    3118             : 
+    3119             : #endif /*}*/
+    3120             : 
+    3121             : };
+    3122             : 
+    3123             : /**
+    3124             :   \related Plumed
+    3125             :   Comparison operator. Available as of PLUMED 2.5.
+    3126             : */
+    3127             : inline
+    3128             : bool operator==(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3129             :   return a.toVoid()==b.toVoid();
+    3130             : }
+    3131             : 
+    3132             : /**
+    3133             :   \related Plumed
+    3134             :   Comparison operator. Available as of PLUMED 2.5.
+    3135             : */
+    3136             : inline
+    3137             : bool operator!=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3138             :   return a.toVoid()!=b.toVoid();
+    3139             : }
+    3140             : 
+    3141             : /**
+    3142             :   \related Plumed
+    3143             :   Comparison operator. Available as of PLUMED 2.5.
+    3144             : */
+    3145             : inline
+    3146             : bool operator<=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3147             :   return a.toVoid()<=b.toVoid();
+    3148             : }
+    3149             : 
+    3150             : /**
+    3151             :   \related Plumed
+    3152             :   Comparison operator. Available as of PLUMED 2.5.
+    3153             : */
+    3154             : inline
+    3155             : bool operator<(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3156             :   return a.toVoid()<b.toVoid();
+    3157             : }
+    3158             : 
+    3159             : /**
+    3160             :   \related Plumed
+    3161             :   Comparison operator. Available as of PLUMED 2.5.
+    3162             : */
+    3163             : inline
+    3164             : bool operator>=(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3165             :   return a.toVoid()>=b.toVoid();
+    3166             : }
+    3167             : 
+    3168             : /**
+    3169             :   \related Plumed
+    3170             :   Comparison operator. Available as of PLUMED 2.5.
+    3171             : */
+    3172             : inline
+    3173             : bool operator>(const Plumed&a,const Plumed&b) __PLUMED_WRAPPER_CXX_NOEXCEPT {
+    3174             :   return a.toVoid()>b.toVoid();
+    3175             : }
+    3176             : 
+    3177             : __PLUMED_WRAPPER_ANONYMOUS_END /*}*/
+    3178             : 
+    3179             : }
+    3180             : 
+    3181             : #endif /*}*/
+    3182             : 
+    3183             : #endif /*}*/
+    3184             : 
+    3185             : /* END OF DECLARATIONS */
+    3186             : 
+    3187             : /*
+    3188             : 
+    3189             :   1: emit implementation
+    3190             :   0: do not emit implementation
+    3191             : 
+    3192             :   Allows an implementation to be emitted together with the declarations.
+    3193             : 
+    3194             :   Used to decide if definitions should be emitted. This macro could have a different
+    3195             :   value when Plumed.h is reincluded. As a consequence, we map it to a local
+    3196             :   macro (__PLUMED_WRAPPER_IMPLEMENTATION_) that is reset at the end of this file.
+    3197             : */
+    3198             : 
+    3199             : #ifdef __PLUMED_WRAPPER_IMPLEMENTATION
+    3200             : #define __PLUMED_WRAPPER_IMPLEMENTATION_ __PLUMED_WRAPPER_IMPLEMENTATION
+    3201             : #else
+    3202             : #define __PLUMED_WRAPPER_IMPLEMENTATION_ 0
+    3203             : #endif
+    3204             : 
+    3205             : /* BEGINNING OF DEFINITIONS */
+    3206             : 
+    3207             : #if __PLUMED_WRAPPER_IMPLEMENTATION_  /*{*/
+    3208             : #ifndef __PLUMED_wrapper_Plumed_implementation /*{*/
+    3209             : #define __PLUMED_wrapper_Plumed_implementation
+    3210             : 
+    3211             : /*
+    3212             :   the following macros only control the implementation
+    3213             : */
+    3214             : 
+    3215             : /*
+    3216             :   1: enable the definition of plumed_symbol_table_reexport
+    3217             :   0: does not enable the definition of plumed_symbol_table_reexport
+    3218             : 
+    3219             :   This is only needed in the official plumed library to make
+    3220             :   the symbol table available. This is a hack to reexport the function table
+    3221             :   and is only needed when creating the library libplumed.so.
+    3222             : */
+    3223             : 
+    3224             : #ifndef __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
+    3225             : #define __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE 0
+    3226             : #endif
+    3227             : 
+    3228             : /*
+    3229             :   1: write on stderr changes in reference counters
+    3230             :   0: do not write changes in reference counters
+    3231             : 
+    3232             :   Used for debugging.
+    3233             : 
+    3234             :   Only used in definitions.
+    3235             : */
+    3236             : 
+    3237             : #ifndef __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3238             : #define __PLUMED_WRAPPER_DEBUG_REFCOUNT 0
+    3239             : #endif
+    3240             : 
+    3241             : /*
+    3242             :   1: emit plumed_kernel_register function (default)
+    3243             :   0: do not emit plumed_kernel_register function
+    3244             : 
+    3245             :   This function is only needed to avoid an extra warning when loading old (<=2.4) kernels.
+    3246             :   We might change its default in the future.
+    3247             : 
+    3248             :   Used only in definitions.
+    3249             : */
+    3250             : 
+    3251             : #ifndef __PLUMED_WRAPPER_KERNEL_REGISTER
+    3252             : #define __PLUMED_WRAPPER_KERNEL_REGISTER 1
+    3253             : #endif
+    3254             : 
+    3255             : /*
+    3256             :   1: emit Fortran wrappers
+    3257             :   0: do not emit Fortran wrappers (default)
+    3258             : 
+    3259             :   Used only in definitions.
+    3260             : */
+    3261             : 
+    3262             : #ifndef __PLUMED_WRAPPER_FORTRAN
+    3263             : #define __PLUMED_WRAPPER_FORTRAN 0
+    3264             : #endif
+    3265             : 
+    3266             : /*
+    3267             :   With internal interface, it does not make sense to emit kernel register or fortran interfaces
+    3268             : */
+    3269             : 
+    3270             : #if ! __PLUMED_WRAPPER_EXTERN /*{*/
+    3271             : #undef __PLUMED_WRAPPER_KERNEL_REGISTER
+    3272             : #define __PLUMED_WRAPPER_KERNEL_REGISTER 0
+    3273             : #undef __PLUMED_WRAPPER_FORTRAN
+    3274             : #define __PLUMED_WRAPPER_FORTRAN 0
+    3275             : #endif /*}*/
+    3276             : 
+    3277             : #ifdef __PLUMED_HAS_DLOPEN
+    3278             : #include <dlfcn.h> /* dlopen dlerror dlsym */
+    3279             : #endif
+    3280             : 
+    3281             : #if __PLUMED_WRAPPER_CXX_STD
+    3282             : #include <cstdio>  /* fprintf */
+    3283             : #include <cstring> /* memcpy strlen strncpy memcmp memmove strcmp memcpy */
+    3284             : #include <cassert> /* assert */
+    3285             : #include <cstdlib> /* getenv malloc free abort */
+    3286             : #include <climits> /* CHAR_BIT */
+    3287             : #else
+    3288             : #include <stdio.h>
+    3289             : #include <string.h>
+    3290             : #include <assert.h>
+    3291             : #include <stdlib.h>
+    3292             : #include <limits.h>
+    3293             : #endif
+    3294             : 
+    3295             : /**
+    3296             :   Function pointer to plumed_create
+    3297             : */
+    3298             : 
+    3299             : typedef void*(*plumed_create_pointer)(void);
+    3300             : /**
+    3301             :   Function pointer to plumed_cmd
+    3302             : */
+    3303             : typedef void(*plumed_cmd_pointer)(void*,const char*,const void*);
+    3304             : 
+    3305             : /**
+    3306             :   Function pointer to plumed_finalize
+    3307             : */
+    3308             : typedef void(*plumed_finalize_pointer)(void*);
+    3309             : 
+    3310             : /**
+    3311             :    Holder for plumedmain function pointers.
+    3312             : */
+    3313             : typedef struct {
+    3314             :   plumed_create_pointer create;
+    3315             :   plumed_cmd_pointer cmd;
+    3316             :   plumed_finalize_pointer finalize;
+    3317             : } plumed_plumedmain_function_holder;
+    3318             : 
+    3319             : /**
+    3320             :   Holder for plumed symbol table.
+    3321             : 
+    3322             :   The table contains pointers to function exported from plumed. Functions can be added increasing the version number.
+    3323             :   Notice that the default way to extend functionalities is by adding cmd strings. This is a last resort, and all new
+    3324             :   functions should be explicitly motivated. Here's the addition:
+    3325             : 
+    3326             :   version=2, cmd_nothrow.
+    3327             : 
+    3328             :   This function accepts an extra argument `plumed_nothrow_handler*handler`.
+    3329             :   In case an exception is thrown within plumed, it just calls `handler->handler(handler->ptr,code,message,opt)` and return.
+    3330             :   An alternative would have been to install an error handler (with a call to cmd("setErrorHandler")). However, the cost
+    3331             :   of doing it everytime Plumed::cmd is called is too high. On the other hand, installing it only at object construction
+    3332             :   is very risky since and object created in that way would not report any error if manipulated from the C interface.
+    3333             :   So, it looks like this is the only possibility.
+    3334             : 
+    3335             :   version=3, cmd_safe and cmd_safe_nothrow
+    3336             : 
+    3337             :   These are functions that accept a plumed_safeptr object, which can carry information about the passed type and size.
+    3338             :   Since new information should be passed at every cmd call, this can only be obtained by adding new cmd calls.
+    3339             : 
+    3340             :   version=4, thread-safe reference counter
+    3341             : 
+    3342             :   These functions allow to access a thread-safe reference counter that is stored within the PlumedMain object.
+    3343             :   This allows avoiding to enable atomic access also the C compiler used build Plumed.c. It's added here and not as a new
+    3344             :   cmd since this is a very low-level functionality.
+    3345             : */
+    3346             : typedef struct {
+    3347             :   /**
+    3348             :     Version number.
+    3349             : 
+    3350             :     Minimum value is 1.
+    3351             :   */
+    3352             :   int version;
+    3353             :   /**
+    3354             :     Pointers to standard plumed functions (create/cmd/finalize).
+    3355             : 
+    3356             :     Always available.
+    3357             :   */
+    3358             :   plumed_plumedmain_function_holder functions;
+    3359             :   /**
+    3360             :     Pointer to a cmd function guaranteed not to throw exceptions.
+    3361             : 
+    3362             :     Available with version>=2.
+    3363             :   */
+    3364             :   void (*cmd_nothrow)(void*plumed,const char*key,const void*val,plumed_nothrow_handler);
+    3365             :   /**
+    3366             :     Pointer to a cmd function that accepts typeinfos.
+    3367             : 
+    3368             :     Available with version>=3.
+    3369             :   */
+    3370             :   void (*cmd_safe)(void*plumed,const char*key,plumed_safeptr);
+    3371             : 
+    3372             :   /**
+    3373             :     Pointer to a cmd function guaranteed not to throw exceptions and that accepts typeinfos.
+    3374             : 
+    3375             :     Available with version>=3.
+    3376             :   */
+    3377             :   void (*cmd_safe_nothrow)(void*plumed,const char*key,plumed_safeptr,plumed_nothrow_handler);
+    3378             : 
+    3379             :   /**
+    3380             :     Pointer to a function that increments the internal reference counter.
+    3381             : 
+    3382             :     Available with version>=4.
+    3383             :   */
+    3384             :   unsigned (*create_reference)(void*);
+    3385             :   /**
+    3386             :     Pointer to a function that decrements the internal reference counter.
+    3387             : 
+    3388             :     Available with version>=4.
+    3389             :   */
+    3390             :   unsigned (*delete_reference)(void*);
+    3391             :   /**
+    3392             :     Pointer to a function that returns the internal reference counter.
+    3393             : 
+    3394             :     Available with version>=4.
+    3395             :   */
+    3396             :   unsigned (*use_count)(void*);
+    3397             : } plumed_symbol_table_type;
+    3398             : 
+    3399             : /* Utility to convert function pointers to pointers, just for the sake of printing them */
+    3400             : #define __PLUMED_CONVERT_FPTR(ptr,fptr) { ptr=__PLUMED_WRAPPER_CXX_NULLPTR; __PLUMED_WRAPPER_STD memcpy(&ptr,&fptr,(sizeof(fptr)>sizeof(ptr)?sizeof(ptr):sizeof(fptr))); }
+    3401             : 
+    3402             : #define __PLUMED_GETENV __PLUMED_WRAPPER_STD getenv
+    3403             : #define __PLUMED_FPRINTF __PLUMED_WRAPPER_STD fprintf
+    3404             : 
+    3405             : /**
+    3406             :   Historically (PLUMED<=2.4) register for plumedmain function pointers.
+    3407             :   As of PLUMED>=2.5, this function does not do anything except for reporting the attempt to register
+    3408             :   something. It always returns NULL. The function should be here anyway to allow an incomplete
+    3409             :   libplumedKernel (<=2.4), expecting this function to be present, to be loaded correctly.
+    3410             : */
+    3411             : #if __PLUMED_WRAPPER_KERNEL_REGISTER
+    3412             : /* Since it is only called from outside, it must be hardcoded to be extern */
+    3413             : __PLUMED_WRAPPER_EXTERN_C_BEGIN /*{*/
+    3414             : extern plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder*);
+    3415          20 : plumed_plumedmain_function_holder* plumed_kernel_register(const plumed_plumedmain_function_holder* f) {
+    3416             :   void* tmpptr;
+    3417          20 :   if(f) {
+    3418          20 :     if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) {
+    3419           0 :       __PLUMED_FPRINTF(stderr,"+++ Ignoring registration at %p (",(const void*)f);
+    3420             :       __PLUMED_CONVERT_FPTR(tmpptr,f->create);
+    3421           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3422             :       __PLUMED_CONVERT_FPTR(tmpptr,f->cmd);
+    3423           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3424             :       __PLUMED_CONVERT_FPTR(tmpptr,f->finalize);
+    3425           0 :       __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
+    3426             :     }
+    3427             :   }
+    3428          20 :   return __PLUMED_WRAPPER_CXX_NULLPTR;
+    3429             : }
+    3430             : __PLUMED_WRAPPER_EXTERN_C_END /*}*/
+    3431             : #endif
+    3432             : 
+    3433             : #if defined( __PLUMED_HAS_DLOPEN) /*{*/
+    3434             : /**
+    3435             : Try to dlopen a path with a given mode.
+    3436             : If the dlopen command fails, it tries to strip the `Kernel` part of the name.
+    3437             : 
+    3438             : This function is declared static (internal linkage) so that it is not visible from outside.
+    3439             : It is first declared then defined to make sure it is a regular C static function.
+    3440             : */
+    3441             : 
+    3442             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3443           9 : void* plumed_attempt_dlopen(const char*path,int mode) {
+    3444             :   char* pathcopy;
+    3445             :   void* p;
+    3446             :   char* pc;
+    3447             :   __PLUMED_WRAPPER_STD size_t strlenpath;
+    3448             :   pathcopy=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3449             :   p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3450             :   pc=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3451             :   strlenpath=0;
+    3452           9 :   dlerror();
+    3453           9 :   p=dlopen(path,mode);
+    3454           9 :   if(!p) {
+    3455             :     /*
+    3456             :       Something went wrong. We try to remove "Kernel" string from the PLUMED_KERNEL variable
+    3457             :       and load directly the shared library. Notice that this particular path is only expected
+    3458             :       to be necessary when using PLUMED<=2.4 and the symbols in the main executable are
+    3459             :       not visible. All the other cases (either PLUMED>=2.5 or symbols in the main executable visible)
+    3460             :       should work correctly without entering here.
+    3461             :     */
+    3462           0 :     __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
+    3463           0 :     strlenpath=__PLUMED_WRAPPER_STD strlen(path);
+    3464           0 :     pathcopy=(char*) plumed_malloc(strlenpath+1);
+    3465           0 :     if(!pathcopy) {
+    3466           0 :       __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
+    3467           0 :       __PLUMED_WRAPPER_STD abort();
+    3468             :     }
+    3469             :     __PLUMED_WRAPPER_STD strncpy(pathcopy,path,strlenpath+1);
+    3470           0 :     pc=pathcopy+strlenpath-6;
+    3471           0 :     while(pc>=pathcopy && __PLUMED_WRAPPER_STD memcmp(pc,"Kernel",6)) pc--;
+    3472           0 :     if(pc>=pathcopy) {
+    3473           0 :       __PLUMED_WRAPPER_STD memmove(pc, pc+6, __PLUMED_WRAPPER_STD strlen(pc)-5);
+    3474           0 :       __PLUMED_FPRINTF(stderr,"+++ This error is expected if you are trying to load a kernel <=2.4\n");
+    3475           0 :       __PLUMED_FPRINTF(stderr,"+++ Trying %s +++\n",pathcopy);
+    3476           0 :       dlerror();
+    3477           0 :       p=dlopen(pathcopy,mode);
+    3478           0 :       if(!p) __PLUMED_FPRINTF(stderr,"+++ An error occurred. Message from dlopen(): %s +++\n",dlerror());
+    3479             :     }
+    3480           0 :     plumed_free(pathcopy);
+    3481             :   }
+    3482           9 :   return p;
+    3483             : }
+    3484             : __PLUMED_WRAPPER_INTERNALS_END
+    3485             : 
+    3486             : /**
+    3487             :   Utility to search for a function.
+    3488             : */
+    3489             : #define __PLUMED_SEARCH_FUNCTION(tmpptr,handle,func,name,debug) \
+    3490             :   if(!func) { \
+    3491             :     tmpptr=dlsym(handle,name); \
+    3492             :     if(tmpptr) { \
+    3493             :       *(void **)(&func)=tmpptr; \
+    3494             :       if(debug) __PLUMED_FPRINTF(stderr,"+++ %s found at %p +++\n",name,tmpptr); \
+    3495             :     } else { \
+    3496             :       if(debug) __PLUMED_FPRINTF(stderr,"+++ Function %s not found\n",name); \
+    3497             :     } \
+    3498             :   }
+    3499             : 
+    3500             : /**
+    3501             : Search symbols in a dlopened library.
+    3502             : 
+    3503             : This function is declared static (internal linkage) so that it is not visible from outside.
+    3504             : */
+    3505             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3506           9 : void plumed_search_symbols(void* handle, plumed_plumedmain_function_holder* f,plumed_symbol_table_type** table) {
+    3507             :   plumed_plumedmain_function_holder functions;
+    3508             :   plumed_symbol_table_type* table_ptr;
+    3509             :   void* tmpptr;
+    3510             :   char* debug;
+    3511             :   functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3512             :   functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3513             :   functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3514             :   table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3515           9 :   tmpptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3516             :   /*
+    3517             :     Notice that as of PLUMED 2.5 we ignore self registrations.
+    3518             :     Pointers are searched in the form of a single pointer to a structure, which
+    3519             :     is the standard way in PLUMED 2.5, as well as using alternative names used in
+    3520             :     PLUMED 2.0 to 2.4 (e.g. plumedmain_create) and in some intermediate versions between
+    3521             :     PLUMED 2.4 and 2.5 (e.g. plumed_plumedmain_create). The last chance is probably
+    3522             :     unnecessary and might be removed at some point.
+    3523             :   */
+    3524           9 :   debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
+    3525           9 :   table_ptr=(plumed_symbol_table_type*) dlsym(handle,"plumed_symbol_table");
+    3526           9 :   if(table_ptr) functions=table_ptr->functions;
+    3527           9 :   if(debug) {
+    3528           0 :     if(table_ptr) {
+    3529           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table version %i found at %p +++\n",table_ptr->version,(void*)table_ptr);
+    3530           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_function_pointers found at %p (",(void*)&table_ptr->functions);
+    3531             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.create);
+    3532           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3533             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.cmd);
+    3534           0 :       __PLUMED_FPRINTF(stderr,"%p,",tmpptr);
+    3535             :       __PLUMED_CONVERT_FPTR(tmpptr,functions.finalize);
+    3536           0 :       __PLUMED_FPRINTF(stderr,"%p) +++\n",tmpptr);
+    3537             :     } else {
+    3538           0 :       __PLUMED_FPRINTF(stderr,"+++ plumed_symbol_table (available in PLUMED>=2.5) not found, perhaps kernel is older +++\n");
+    3539             :     }
+    3540             :   }
+    3541             :   /* only searches if they were not found already */
+    3542           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumedmain_create",debug);
+    3543           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.create,"plumed_plumedmain_create",debug);
+    3544           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumedmain_cmd",debug);
+    3545           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.cmd,"plumed_plumedmain_cmd",debug);
+    3546           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumedmain_finalize",debug);
+    3547           9 :   __PLUMED_SEARCH_FUNCTION(tmpptr,handle,functions.finalize,"plumed_plumedmain_finalize",debug);
+    3548           9 :   if(functions.create && functions.cmd && functions.finalize) {
+    3549           9 :     if(debug) __PLUMED_FPRINTF(stderr,"+++ PLUMED was loaded correctly +++\n");
+    3550           9 :     *f=functions;
+    3551           9 :     if(table) *table=table_ptr;
+    3552             :   } else {
+    3553           0 :     if(!functions.create) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_create not found +++\n");
+    3554           0 :     if(!functions.cmd) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_cmd not found +++\n");
+    3555           0 :     if(!functions.finalize) __PLUMED_FPRINTF(stderr,"+++ Pointer to (plumed_)plumedmain_finalize not found +++\n");
+    3556           0 :     f->create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3557           0 :     f->cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3558           0 :     f->finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3559           0 :     if(table) *table=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3560             :   }
+    3561           9 : }
+    3562             : __PLUMED_WRAPPER_INTERNALS_END
+    3563             : 
+    3564             : #endif /*}*/
+    3565             : 
+    3566             : 
+    3567             : #if __PLUMED_WRAPPER_REEXPORT_SYMBOL_TABLE
+    3568             : 
+    3569             : /*
+    3570             :   Here is the case where plumed_symbol_table is
+    3571             :   visible as extern. We first declare it (together with plumed_symbol_table_init) ...
+    3572             : */
+    3573             : 
+    3574             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3575             : extern
+    3576             : plumed_symbol_table_type plumed_symbol_table;
+    3577             : __PLUMED_WRAPPER_EXTERN_C_END
+    3578             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3579             : extern
+    3580             : void plumed_symbol_table_init(void);
+    3581             : __PLUMED_WRAPPER_EXTERN_C_END
+    3582             : 
+    3583             : /*
+    3584             :   ... and then make available a function that returns the address
+    3585             :   of the symbol table.
+    3586             : */
+    3587             : __PLUMED_WRAPPER_C_BEGIN
+    3588      658609 : plumed_symbol_table_type* plumed_symbol_table_reexport() {
+    3589             :   /* make sure the table is initialized */
+    3590      658609 :   plumed_symbol_table_init();
+    3591      719396 :   return &plumed_symbol_table;
+    3592             : }
+    3593             : __PLUMED_WRAPPER_C_END
+    3594             : 
+    3595             : #else
+    3596             : 
+    3597             : /*
+    3598             :   Here is the case where plumed_symbol_table is not
+    3599             :   visible as extern. We thus assume that plumed_symbol_table_reexport is
+    3600             :   available.
+    3601             : */
+    3602             : 
+    3603             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    3604             : extern plumed_symbol_table_type* plumed_symbol_table_reexport();
+    3605             : __PLUMED_WRAPPER_EXTERN_C_END
+    3606             : #endif
+    3607             : 
+    3608             : 
+    3609             : /*
+    3610             :   Returns the global pointers, either those available at link time or those
+    3611             :   found in the library loaded at PLUMED_KERNEL env var.
+    3612             :   If plumed_symbol_table_ptr is not NULL, it is used to return a pointer to the symbol table
+    3613             :   (if available).
+    3614             :   Notice that problems can be detected checking if the functions have a NULL ptr.
+    3615             :   On the other hand, the symbol table pointer might be NULL just because the plumed version is <=2.4.
+    3616             :   If handle is not NULL, it is used to return a dlopen handle that could be subsequently dlclosed.
+    3617             : */
+    3618             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3619      684064 : void plumed_retrieve_functions(plumed_plumedmain_function_holder* functions, plumed_symbol_table_type** plumed_symbol_table_ptr,void** handle) {
+    3620             : #if ! __PLUMED_WRAPPER_LINK_RUNTIME
+    3621             :   /*
+    3622             :     Real interface, constructed using the symbol table obtained with plumed_symbol_table_reexport.
+    3623             :     This makes the symbols hardcoded and independent of a mis-set PLUMED_KERNEL variable.
+    3624             :   */
+    3625      684064 :   plumed_symbol_table_type* ptr=plumed_symbol_table_reexport();
+    3626      722259 :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=ptr;
+    3627      722259 :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3628      722259 :   if(functions) *functions=ptr->functions;
+    3629             : #elif ! defined(__PLUMED_HAS_DLOPEN)
+    3630             :   /*
+    3631             :     When dlopen is not available, we hard code them to NULL
+    3632             :   */
+    3633             :   __PLUMED_FPRINTF(stderr,"+++ PLUMED has been compiled without dlopen and without a static kernel +++\n");
+    3634             :   plumed_plumedmain_function_holder g= {__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR,__PLUMED_WRAPPER_CXX_NULLPTR};
+    3635             :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3636             :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3637             :   if(functions) *functions=g;
+    3638             : #else
+    3639             :   /*
+    3640             :     On the other hand, for runtime binding, we use dlsym to find the relevant functions.
+    3641             :   */
+    3642             :   plumed_plumedmain_function_holder g;
+    3643             :   /* search is done once and only once */
+    3644             :   const char* path;
+    3645             :   void* p;
+    3646             :   char* debug;
+    3647             :   int dlopenmode;
+    3648             :   g.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3649             :   g.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3650             :   g.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3651             :   path=__PLUMED_GETENV("PLUMED_KERNEL");
+    3652             :   p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3653             :   debug=__PLUMED_GETENV("PLUMED_LOAD_DEBUG");
+    3654             :   dlopenmode=0;
+    3655             :   if(plumed_symbol_table_ptr) *plumed_symbol_table_ptr=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3656             :   if(handle) *handle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3657             : #ifdef __PLUMED_DEFAULT_KERNEL
+    3658             :   /*
+    3659             :     This variable allows a default path for the kernel to be hardcoded.
+    3660             :     Can be useful for hardcoding the predefined plumed location
+    3661             :     still allowing the user to override this choice setting PLUMED_KERNEL.
+    3662             :     The path should be chosen at compile time adding e.g.
+    3663             :     -D__PLUMED_DEFAULT_KERNEL=/opt/local/lib/libplumed.dylib
+    3664             :   */
+    3665             :   /* This is required to add quotes */
+    3666             : #define PLUMED_QUOTE_DIRECT(name) #name
+    3667             : #define PLUMED_QUOTE(macro) PLUMED_QUOTE_DIRECT(macro)
+    3668             :   if(! (path && (*path) )) path=PLUMED_QUOTE(__PLUMED_DEFAULT_KERNEL);
+    3669             : #endif
+    3670             : #if defined(__PLUMED_PROGRAM_NAME) && defined(__PLUMED_SOEXT)
+    3671             :   if(! (path && (*path) )) path="lib" __PLUMED_PROGRAM_NAME "Kernel." __PLUMED_SOEXT;
+    3672             : #endif
+    3673             :   if(path && (*path)) {
+    3674             :     __PLUMED_FPRINTF(stderr,"+++ Loading the PLUMED kernel runtime +++\n");
+    3675             :     __PLUMED_FPRINTF(stderr,"+++ PLUMED_KERNEL=\"%s\" +++\n",path);
+    3676             :     if(debug) __PLUMED_FPRINTF(stderr,"+++ Loading with mode RTLD_NOW");
+    3677             :     dlopenmode=RTLD_NOW;
+    3678             :     if(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_NAMESPACE"),"GLOBAL")) {
+    3679             :       dlopenmode=dlopenmode|RTLD_GLOBAL;
+    3680             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_GLOBAL");
+    3681             :     } else {
+    3682             :       dlopenmode=dlopenmode|RTLD_LOCAL;
+    3683             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_LOCAL");
+    3684             :     }
+    3685             : #ifdef RTLD_DEEPBIND
+    3686             : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+    3687             :     if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) {
+    3688             :       dlopenmode=dlopenmode|RTLD_DEEPBIND;
+    3689             :       if(debug) __PLUMED_FPRINTF(stderr,"|RTLD_DEEPBIND");
+    3690             :     }
+    3691             : #endif
+    3692             : #endif
+    3693             :     if(debug) __PLUMED_FPRINTF(stderr," +++\n");
+    3694             :     p=plumed_attempt_dlopen(path,dlopenmode);
+    3695             :     if(p) plumed_search_symbols(p,&g,plumed_symbol_table_ptr);
+    3696             :   }
+    3697             :   if(handle) *handle=p;
+    3698             :   if(functions) *functions=g;
+    3699             : #endif
+    3700      722259 : }
+    3701             : __PLUMED_WRAPPER_INTERNALS_END
+    3702             : 
+    3703             : /**
+    3704             :   Implementation.
+    3705             :   Small object used to store pointers directly into the plumed object defined in Plumed.h.
+    3706             :   This allows avoiding the extra function call to plumed_retrieve_functions at every cmd,
+    3707             :   at the cost of an extra indirection.
+    3708             : */
+    3709             : typedef struct {
+    3710             :   /* allows errors with pointers to be found when debugging */
+    3711             :   char magic[6];
+    3712             :   /* reference count. this is only used with PLUMED<=2.8. Later versions have an internal thread-safe reference counter. */
+    3713             :   int refcount;
+    3714             :   /* handler to dlopened library. NULL if there was no library opened */
+    3715             :   void* dlhandle;
+    3716             :   /* non zero if, upon destruction, the library should be dlclosed */
+    3717             :   int dlclose;
+    3718             :   /* 1 if path to kernel was taken from PLUMED_KERNEL var, 0 otherwise */
+    3719             :   int used_plumed_kernel;
+    3720             :   /* function pointers */
+    3721             :   plumed_plumedmain_function_holder functions;
+    3722             :   /* pointer to the symbol table. NULL if kernel <=2.4 */
+    3723             :   plumed_symbol_table_type* table;
+    3724             :   /* pointer to plumed object */
+    3725             :   void* p;
+    3726             : } plumed_implementation;
+    3727             : 
+    3728             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3729      699994 : plumed_implementation* plumed_malloc_pimpl() {
+    3730             :   plumed_implementation* pimpl;
+    3731             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3732      699993 :   pimpl=(plumed_implementation*) plumed_malloc(sizeof(plumed_implementation));
+    3733      697382 :   if(!pimpl) {
+    3734           0 :     __PLUMED_FPRINTF(stderr,"+++ Allocation error +++\n");
+    3735           0 :     __PLUMED_WRAPPER_STD abort();
+    3736             :   }
+    3737             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3738      697382 :   __PLUMED_WRAPPER_STD memcpy(pimpl->magic,"pLuMEd",6);
+    3739             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3740      697382 :   pimpl->refcount=1;
+    3741             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3742             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3743             :   __PLUMED_FPRINTF(stderr,"refcount: new at %p\n",(void*)pimpl);
+    3744             : #endif
+    3745             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3746      697382 :   pimpl->dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3747             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3748      697382 :   pimpl->dlclose=0;
+    3749             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3750      697382 :   pimpl->used_plumed_kernel=0;
+    3751             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3752      697382 :   pimpl->functions.create=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3753             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3754      697382 :   pimpl->functions.cmd=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3755             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3756      697382 :   pimpl->functions.finalize=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3757             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3758      697382 :   pimpl->table=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3759             :   /* cppcheck-suppress nullPointerRedundantCheck */
+    3760      697382 :   pimpl->p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3761      697382 :   return pimpl;
+    3762             : }
+    3763             : __PLUMED_WRAPPER_INTERNALS_END
+    3764             : 
+    3765             : #ifndef NDEBUG
+    3766             : 
+    3767             : __PLUMED_WRAPPER_INTERNALS_BEGIN
+    3768             : int plumed_check_pimpl(plumed_implementation*pimpl) {
+    3769             :   if(!pimpl) return 0;
+    3770             :   if(__PLUMED_WRAPPER_STD memcmp(pimpl->magic,"pLuMEd",6)) return 0;
+    3771             :   return 1;
+    3772             : }
+    3773             : __PLUMED_WRAPPER_INTERNALS_END
+    3774             : #endif
+    3775             : 
+    3776             : /* C wrappers: */
+    3777             : 
+    3778             : __PLUMED_WRAPPER_C_BEGIN
+    3779      700214 : plumed plumed_create(void) {
+    3780             :   /* returned object */
+    3781             :   plumed p;
+    3782             :   /* pointer to implementation */
+    3783             :   plumed_implementation* pimpl;
+    3784             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3785      700214 :   pimpl=plumed_malloc_pimpl();
+    3786             :   /* store pointers in pimpl */
+    3787      693829 :   plumed_retrieve_functions(&pimpl->functions,&pimpl->table,&pimpl->dlhandle);
+    3788             : #if __PLUMED_WRAPPER_LINK_RUNTIME
+    3789             :   /* note if PLUMED_KERNEL variable was used */
+    3790             :   pimpl->used_plumed_kernel=1;
+    3791             : #endif
+    3792             :   /* note if handle should not be dlclosed */
+    3793      722932 :   pimpl->dlclose=1;
+    3794      722932 :   if(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE") && !__PLUMED_WRAPPER_STD strcmp(__PLUMED_GETENV("PLUMED_LOAD_DLCLOSE"),"no")) pimpl->dlclose=0;
+    3795             :   /* in case of failure, return */
+    3796             :   /* the resulting object should be plumed_finalized, though you cannot use plumed_cmd */
+    3797      802122 :   if(!pimpl->functions.create) {
+    3798             :     /* store pimpl in returned object */
+    3799             :     p.p=pimpl;
+    3800           0 :     return p;
+    3801             :   }
+    3802             :   assert(pimpl->functions.cmd);
+    3803             :   assert(pimpl->functions.finalize);
+    3804             :   /* obtain object */
+    3805      802122 :   pimpl->p=(*(pimpl->functions.create))();
+    3806             :   /* notice: we do not assert pimpl->p since in principle it might be nullptr */
+    3807             :   /* user might identify this using plumed_valid() */
+    3808             :   /* store pimpl in returned object */
+    3809             :   p.p=pimpl;
+    3810      786383 :   return p;
+    3811             : }
+    3812             : __PLUMED_WRAPPER_C_END
+    3813             : 
+    3814             : __PLUMED_WRAPPER_C_BEGIN
+    3815           9 : plumed plumed_create_dlopen(const char*path) {
+    3816             :   int dlopenmode;
+    3817             :   /* plumed_create_dlopen always uses RTLD_LOCAL and, when possible, RTLD_DEEPBIND to allow multiple versions */
+    3818             : #ifdef __PLUMED_HAS_DLOPEN
+    3819             :   dlopenmode=RTLD_NOW|RTLD_LOCAL;
+    3820             : #ifdef RTLD_DEEPBIND
+    3821             : #if __PLUMED_WRAPPER_ENABLE_RTLD_DEEPBIND
+    3822           9 :   if(!__PLUMED_GETENV("PLUMED_LOAD_NODEEPBIND")) dlopenmode=dlopenmode|RTLD_DEEPBIND;
+    3823             : #endif
+    3824             : #endif
+    3825             : #else
+    3826             :   dlopenmode=0;
+    3827             : #endif
+    3828           9 :   return plumed_create_dlopen2(path,dlopenmode);
+    3829             : }
+    3830             : __PLUMED_WRAPPER_C_END
+    3831             : 
+    3832             : __PLUMED_WRAPPER_C_BEGIN
+    3833           9 : plumed plumed_create_dlsym(void* dlhandle) {
+    3834             :   /* returned object */
+    3835             :   plumed p;
+    3836             :   /* pointer to implementation */
+    3837             :   plumed_implementation* pimpl;
+    3838             :   /* allocate space for implementation object. this is free-ed in plumed_finalize(). */
+    3839           9 :   pimpl=plumed_malloc_pimpl();
+    3840             : #ifdef __PLUMED_HAS_DLOPEN
+    3841           9 :   pimpl->dlhandle=dlhandle;
+    3842           9 :   plumed_search_symbols(pimpl->dlhandle,&pimpl->functions,&pimpl->table);
+    3843             : #endif
+    3844           9 :   if(!pimpl->functions.create) {
+    3845             :     p.p=pimpl;
+    3846           0 :     return p;
+    3847             :   }
+    3848             :   assert(pimpl->functions.cmd);
+    3849             :   assert(pimpl->functions.finalize);
+    3850             :   /* obtain object */
+    3851           9 :   pimpl->p=(*(pimpl->functions.create))();
+    3852             :   /* notice: we do not assert pimpl->p since in principle it might be nullptr */
+    3853             :   /* user might identify this using plumed_valid() */
+    3854             :   /* store pimpl in returned object */
+    3855             :   p.p=pimpl;
+    3856           9 :   return p;
+    3857             : }
+    3858             : __PLUMED_WRAPPER_C_END
+    3859             : 
+    3860             : __PLUMED_WRAPPER_C_BEGIN
+    3861           9 : plumed plumed_create_dlopen2(const char*path,int mode) {
+    3862             : #ifdef __PLUMED_HAS_DLOPEN
+    3863             :   /* returned object */
+    3864             :   plumed p;
+    3865             :   /* pointer to implementation */
+    3866             :   plumed_implementation* pimpl;
+    3867             :   /* handler */
+    3868             :   void* dlhandle;
+    3869             :   dlhandle=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3870           9 :   if(path) dlhandle=plumed_attempt_dlopen(path,mode);
+    3871             :   /* a NULL handle implies the file could not be loaded */
+    3872           9 :   if(dlhandle) {
+    3873           9 :     p=plumed_create_dlsym(dlhandle);
+    3874             :     /* obtain pimpl */
+    3875           9 :     pimpl=(plumed_implementation*) p.p;
+    3876             :     /* make sure the handler is closed when plumed is finalized */
+    3877           9 :     pimpl->dlclose=1;
+    3878           9 :     return p;
+    3879             :   }
+    3880             : #else
+    3881             :   (void) path;
+    3882             :   (void) mode;
+    3883             : #endif
+    3884           0 :   return plumed_create_invalid();
+    3885             : }
+    3886             : __PLUMED_WRAPPER_C_END
+    3887             : 
+    3888             : __PLUMED_WRAPPER_C_BEGIN
+    3889     7504672 : plumed plumed_create_reference(plumed p) {
+    3890             :   plumed_implementation* pimpl;
+    3891             :   /* obtain pimpl */
+    3892     7504672 :   pimpl=(plumed_implementation*) p.p;
+    3893             :   assert(plumed_check_pimpl(pimpl));
+    3894             :   /* increase reference count */
+    3895             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    3896     7504672 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    3897     7453939 :     pimpl->table->create_reference(pimpl->p);
+    3898             :   } else {
+    3899       50733 :     pimpl->refcount++;
+    3900             :   }
+    3901             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    3902             :   __PLUMED_FPRINTF(stderr,"refcount: increase at %p\n",(void*)pimpl);
+    3903             : #endif
+    3904     7630256 :   return p;
+    3905             : }
+    3906             : __PLUMED_WRAPPER_C_END
+    3907             : 
+    3908             : __PLUMED_WRAPPER_C_BEGIN
+    3909           2 : plumed plumed_create_reference_v(void*v) {
+    3910           2 :   return plumed_create_reference(plumed_v2c(v));
+    3911             : }
+    3912             : __PLUMED_WRAPPER_C_END
+    3913             : 
+    3914             : __PLUMED_WRAPPER_C_BEGIN
+    3915           8 : plumed plumed_create_reference_f(const char*f) {
+    3916           8 :   return plumed_create_reference(plumed_f2c(f));
+    3917             : }
+    3918             : __PLUMED_WRAPPER_C_END
+    3919             : 
+    3920             : __PLUMED_WRAPPER_C_BEGIN
+    3921           2 : plumed plumed_create_invalid() {
+    3922             :   plumed p;
+    3923             :   plumed_implementation* pimpl;
+    3924           2 :   pimpl=plumed_malloc_pimpl();
+    3925             :   p.p=pimpl;
+    3926           2 :   return p;
+    3927             : }
+    3928             : __PLUMED_WRAPPER_C_END
+    3929             : 
+    3930             : __PLUMED_WRAPPER_C_BEGIN
+    3931         357 : void plumed_cmd(plumed p,const char*key,const void*val) {
+    3932             :   plumed_implementation* pimpl;
+    3933             :   /* obtain pimpl */
+    3934         357 :   pimpl=(plumed_implementation*) p.p;
+    3935             :   assert(plumed_check_pimpl(pimpl));
+    3936         357 :   if(!pimpl->p) {
+    3937           0 :     __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
+    3938           0 :     if(pimpl->used_plumed_kernel) __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
+    3939           0 :     __PLUMED_WRAPPER_STD abort();
+    3940             :   }
+    3941             :   assert(pimpl->functions.create);
+    3942             :   assert(pimpl->functions.cmd);
+    3943             :   assert(pimpl->functions.finalize);
+    3944             :   /* execute */
+    3945         357 :   (*(pimpl->functions.cmd))(pimpl->p,key,val);
+    3946         357 : }
+    3947             : __PLUMED_WRAPPER_C_END
+    3948             : 
+    3949             : __PLUMED_WRAPPER_C_BEGIN
+    3950       14357 : void plumed_cmd_safe_nothrow(plumed p,const char*key,plumed_safeptr safe,plumed_nothrow_handler nothrow) {
+    3951             :   plumed_implementation* pimpl;
+    3952             :   /* This is to allow caller to use a null handler to imply that handling is not done */
+    3953       14357 :   if(!nothrow.handler) {
+    3954          37 :     plumed_cmd_safe(p,key,safe);
+    3955          37 :     return;
+    3956             :   }
+    3957             :   /* obtain pimpl */
+    3958       14320 :   pimpl=(plumed_implementation*) p.p;
+    3959             :   assert(plumed_check_pimpl(pimpl));
+    3960       14320 :   if(!pimpl->p) {
+    3961           0 :     if(pimpl->used_plumed_kernel) {
+    3962           0 :       nothrow.handler(nothrow.ptr,1,"You are trying to use plumed, but it is not available.\nCheck your PLUMED_KERNEL environment variable.",__PLUMED_WRAPPER_CXX_NULLPTR);
+    3963             :     } else {
+    3964           0 :       nothrow.handler(nothrow.ptr,1,"You are trying to use plumed, but it is not available.",__PLUMED_WRAPPER_CXX_NULLPTR);
+    3965             :     }
+    3966           0 :     return;
+    3967             :   }
+    3968             :   assert(pimpl->functions.create);
+    3969             :   assert(pimpl->functions.cmd);
+    3970             :   assert(pimpl->functions.finalize);
+    3971             :   /* execute */
+    3972       14320 :   if(pimpl->table && pimpl->table->version>2) (*(pimpl->table->cmd_safe_nothrow))(pimpl->p,key,safe,nothrow);
+    3973           0 :   else if(pimpl->table && pimpl->table->version>1) (*(pimpl->table->cmd_nothrow))(pimpl->p,key,safe.ptr,nothrow);
+    3974           0 :   else (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
+    3975             : }
+    3976             : __PLUMED_WRAPPER_C_END
+    3977             : 
+    3978             : __PLUMED_WRAPPER_C_BEGIN
+    3979           0 : void plumed_cmd_nothrow(plumed p,const char*key,const void*val,plumed_nothrow_handler nothrow) {
+    3980             :   plumed_safeptr safe;
+    3981           0 :   safe.ptr=val;
+    3982           0 :   safe.flags=0;
+    3983           0 :   safe.nelem=0;
+    3984           0 :   safe.shape=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3985           0 :   safe.opt=__PLUMED_WRAPPER_CXX_NULLPTR;
+    3986           0 :   plumed_cmd_safe_nothrow(p,key,safe,nothrow);
+    3987           0 : }
+    3988             : __PLUMED_WRAPPER_C_END
+    3989             : 
+    3990             : __PLUMED_WRAPPER_C_BEGIN
+    3991          95 : void plumed_cmd_safe(plumed p,const char*key,plumed_safeptr safe) {
+    3992             :   plumed_implementation* pimpl;
+    3993             :   /* obtain pimpl */
+    3994          95 :   pimpl=(plumed_implementation*) p.p;
+    3995             :   assert(plumed_check_pimpl(pimpl));
+    3996          95 :   if(!pimpl->p) {
+    3997           0 :     __PLUMED_FPRINTF(stderr,"+++ ERROR: You are trying to use an invalid plumed object. +++\n");
+    3998           0 :     if(pimpl->used_plumed_kernel) __PLUMED_FPRINTF(stderr,"+++ Check your PLUMED_KERNEL environment variable. +++\n");
+    3999           0 :     __PLUMED_WRAPPER_STD abort();
+    4000             :   }
+    4001             :   assert(pimpl->functions.create);
+    4002             :   assert(pimpl->functions.cmd);
+    4003             :   assert(pimpl->functions.finalize);
+    4004             :   /* execute */
+    4005          95 :   if(pimpl->table && pimpl->table->version>2) (*(pimpl->table->cmd_safe))(pimpl->p,key,safe);
+    4006           0 :   else (*(pimpl->functions.cmd))(pimpl->p,key,safe.ptr);
+    4007          95 : }
+    4008             : __PLUMED_WRAPPER_C_END
+    4009             : 
+    4010             : 
+    4011             : __PLUMED_WRAPPER_C_BEGIN
+    4012     8421091 : void plumed_finalize(plumed p) {
+    4013             :   plumed_implementation* pimpl;
+    4014             :   /* obtain pimpl */
+    4015     8421091 :   pimpl=(plumed_implementation*) p.p;
+    4016             :   assert(plumed_check_pimpl(pimpl));
+    4017             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4018             :   __PLUMED_FPRINTF(stderr,"refcount: decrease at %p\n",(void*)pimpl);
+    4019             : #endif
+    4020             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    4021     8421091 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    4022     8369284 :     if(pimpl->table->delete_reference(pimpl->p)>0) return;
+    4023             :   } else {
+    4024       51807 :     if(--pimpl->refcount>0) return;
+    4025             :   }
+    4026             :   /* to allow finalizing an invalid plumed object, we only call
+    4027             :      finalize if the object is valid */
+    4028      786487 :   if(pimpl->p) {
+    4029             :     assert(pimpl->functions.create);
+    4030             :     assert(pimpl->functions.cmd);
+    4031             :     assert(pimpl->functions.finalize);
+    4032             :     /* finalize */
+    4033      786485 :     (*(pimpl->functions.finalize))(pimpl->p);
+    4034             :   }
+    4035             : #ifdef __PLUMED_HAS_DLOPEN
+    4036             :   /* dlclose library */
+    4037      748151 :   if(pimpl->dlhandle && pimpl->dlclose) {
+    4038           9 :     if(__PLUMED_GETENV("PLUMED_LOAD_DEBUG")) __PLUMED_FPRINTF(stderr,"+++ Unloading library\n");
+    4039           9 :     dlclose(pimpl->dlhandle);
+    4040             :   }
+    4041             : #endif
+    4042             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4043             :   __PLUMED_FPRINTF(stderr,"refcount: delete at %p\n",(void*)pimpl);
+    4044             : #endif
+    4045             :   /* free pimpl space */
+    4046      748150 :   plumed_free(pimpl);
+    4047             : }
+    4048             : __PLUMED_WRAPPER_C_END
+    4049             : 
+    4050             : __PLUMED_WRAPPER_C_BEGIN
+    4051          23 : int plumed_valid(plumed p) {
+    4052             :   plumed_implementation* pimpl;
+    4053             :   /* obtain pimpl */
+    4054          23 :   pimpl=(plumed_implementation*) p.p;
+    4055             :   assert(plumed_check_pimpl(pimpl));
+    4056          24 :   if(pimpl->p) return 1;
+    4057           2 :   else return 0;
+    4058             : }
+    4059             : __PLUMED_WRAPPER_C_END
+    4060             : 
+    4061             : __PLUMED_WRAPPER_C_BEGIN
+    4062          42 : int plumed_use_count(plumed p) {
+    4063             :   plumed_implementation* pimpl;
+    4064             :   /* obtain pimpl */
+    4065          42 :   pimpl=(plumed_implementation*) p.p;
+    4066             :   assert(plumed_check_pimpl(pimpl));
+    4067             :   /* with PLUMED > 2.8, we can use an internal reference counter which is thread safe */
+    4068          42 :   if(pimpl->p && pimpl->table && pimpl->table->version>3) {
+    4069          42 :     return pimpl->table->use_count(pimpl->p);
+    4070             :   } else {
+    4071           0 :     return pimpl->refcount;
+    4072             :   }
+    4073             : }
+    4074             : __PLUMED_WRAPPER_C_END
+    4075             : 
+    4076             : __PLUMED_WRAPPER_C_BEGIN
+    4077           9 : int plumed_installed(void) {
+    4078             :   plumed p;
+    4079             :   int result;
+    4080           9 :   p=plumed_create();
+    4081           9 :   result=plumed_valid(p);
+    4082           9 :   plumed_finalize(p);
+    4083           9 :   return result;
+    4084             : }
+    4085             : __PLUMED_WRAPPER_C_END
+    4086             : 
+    4087             : __PLUMED_WRAPPER_C_BEGIN
+    4088      699554 : void* plumed_malloc(__PLUMED_WRAPPER_STD size_t size) {
+    4089             :   void* ptr;
+    4090      699555 :   ptr=__PLUMED_WRAPPER_STD malloc(size);
+    4091             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4092             :   if(ptr) fprintf(stderr,"plumed_malloc: %p\n",ptr);
+    4093             : #endif
+    4094      699554 :   return ptr;
+    4095             : }
+    4096             : __PLUMED_WRAPPER_C_END
+    4097             : 
+    4098             : __PLUMED_WRAPPER_C_BEGIN
+    4099      720030 : void plumed_free(void* ptr) {
+    4100      720031 :   __PLUMED_WRAPPER_STD free(ptr);
+    4101             : #if __PLUMED_WRAPPER_DEBUG_REFCOUNT
+    4102             :   fprintf(stderr,"plumed_free: %p\n",ptr);
+    4103             : #endif
+    4104      720031 : }
+    4105             : __PLUMED_WRAPPER_C_END
+    4106             : 
+    4107             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    4108             : 
+    4109             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    4110             : 
+    4111             : /* we declare a Plumed_g_main object here, in such a way that it is always available */
+    4112             : 
+    4113             : static plumed plumed_gmain= {__PLUMED_WRAPPER_CXX_NULLPTR};
+    4114             : 
+    4115          41 : plumed plumed_global(void) {
+    4116          41 :   return plumed_gmain;
+    4117             : }
+    4118             : 
+    4119          22 : void plumed_gcreate(void) {
+    4120             :   /* should be created once */
+    4121             :   assert(plumed_gmain.p==__PLUMED_WRAPPER_CXX_NULLPTR);
+    4122          22 :   plumed_gmain=plumed_create();
+    4123          22 : }
+    4124             : 
+    4125          78 : void plumed_gcmd(const char*key,const void*val) {
+    4126          78 :   plumed_cmd(plumed_gmain,key,val);
+    4127          78 : }
+    4128             : 
+    4129             : /* cppcheck-suppress passedByValue */
+    4130           0 : void plumed_gcmd_safe(const char*key,plumed_safeptr safe) {
+    4131           0 :   plumed_cmd_safe(plumed_gmain,key,safe);
+    4132           0 : }
+    4133             : 
+    4134          22 : void plumed_gfinalize(void) {
+    4135          22 :   plumed_finalize(plumed_gmain);
+    4136          22 :   plumed_gmain.p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4137          22 : }
+    4138             : 
+    4139          24 : int plumed_ginitialized(void) {
+    4140          24 :   if(plumed_gmain.p) return 1;
+    4141          16 :   else        return 0;
+    4142             : }
+    4143             : 
+    4144           8 : int plumed_gvalid() {
+    4145             :   assert(plumed_gmain.p);
+    4146           8 :   return plumed_valid(plumed_gmain);
+    4147             : }
+    4148             : 
+    4149             : __PLUMED_WRAPPER_EXTERN_C_END
+    4150             : 
+    4151             : #endif /*}*/
+    4152             : 
+    4153             : __PLUMED_WRAPPER_C_BEGIN
+    4154          56 : void plumed_c2f(plumed p,char*c) {
+    4155             :   unsigned i;
+    4156             :   unsigned char* cc;
+    4157             :   /*
+    4158             :     Convert the address stored in p.p into a proper FORTRAN string
+    4159             :     made of only ASCII characters. For this to work, the two following
+    4160             :     assertions should be satisfied:
+    4161             :   */
+    4162             :   assert(CHAR_BIT<=12);
+    4163             :   assert(sizeof(p.p)<=16);
+    4164             : 
+    4165             :   assert(c);
+    4166             :   cc=(unsigned char*)&p.p;
+    4167         504 :   for(i=0; i<sizeof(p.p); i++) {
+    4168             :     /*
+    4169             :       characters will range between '0' (ASCII 48) and 'o' (ASCII 111=48+63)
+    4170             :     */
+    4171         448 :     c[2*i]=cc[i]/64+48;
+    4172         448 :     c[2*i+1]=cc[i]%64+48;
+    4173             :   }
+    4174         504 :   for(; i<16; i++) {
+    4175         448 :     c[2*i]=' ';
+    4176         448 :     c[2*i+1]=' ';
+    4177             :   }
+    4178          56 : }
+    4179             : __PLUMED_WRAPPER_C_END
+    4180             : 
+    4181             : __PLUMED_WRAPPER_C_BEGIN
+    4182         373 : plumed plumed_f2c(const char*c) {
+    4183             :   plumed p;
+    4184             :   unsigned i;
+    4185             :   unsigned char* cc;
+    4186             : 
+    4187             :   assert(CHAR_BIT<=12);
+    4188             :   assert(sizeof(p.p)<=16);
+    4189             : 
+    4190             :   assert(c);
+    4191             : 
+    4192             :   /*
+    4193             :      needed to avoid cppcheck warning on uninitialized p
+    4194             :   */
+    4195         373 :   p.p=__PLUMED_WRAPPER_CXX_NULLPTR;
+    4196             :   cc=(unsigned char*)&p.p;
+    4197        3357 :   for(i=0; i<sizeof(p.p); i++) {
+    4198             :     assert(c[2*i]>=48 && c[2*i]<48+64);
+    4199             :     assert(c[2*i+1]>=48 && c[2*i+1]<48+64);
+    4200             :     /*
+    4201             :       perform the reversed transform
+    4202             :     */
+    4203        2984 :     cc[i]=(c[2*i]-48)*64 + (c[2*i+1]-48);
+    4204             :   }
+    4205        3357 :   for(; i<16; i++) {
+    4206             :     assert(c[2*i]==' ');
+    4207             :     assert(c[2*i+1]==' ');
+    4208             :   }
+    4209         373 :   return p;
+    4210             : }
+    4211             : __PLUMED_WRAPPER_C_END
+    4212             : 
+    4213             : __PLUMED_WRAPPER_C_BEGIN
+    4214           2 : void* plumed_c2v(plumed p) {
+    4215             :   assert(plumed_check_pimpl((plumed_implementation*)p.p));
+    4216           2 :   return p.p;
+    4217             : }
+    4218             : __PLUMED_WRAPPER_C_END
+    4219             : 
+    4220             : __PLUMED_WRAPPER_C_BEGIN
+    4221           2 : plumed plumed_v2c(void* v) {
+    4222             :   assert(plumed_check_pimpl((plumed_implementation*)v));
+    4223             :   plumed p;
+    4224             :   p.p=v;
+    4225           2 :   return p;
+    4226             : }
+    4227             : __PLUMED_WRAPPER_C_END
+    4228             : 
+    4229             : #if __PLUMED_WRAPPER_FORTRAN /*{*/
+    4230             : 
+    4231             : /*
+    4232             :   Fortran wrappers
+    4233             :   These are just like the global C wrappers. They are
+    4234             :   just defined here and not declared since they
+    4235             :   should not be used from c/c++ anyway.
+    4236             : 
+    4237             :   We use a macro that does the following:
+    4238             :   - declare a static function named NAME_static
+    4239             :   - declare a number of functions named NAME_ etc, with all possible
+    4240             :     fortran mangling schemes (zero, one, or two underscores, lower and upper case)
+    4241             :   - define the NAME_static function.
+    4242             : 
+    4243             :   The static function is used basically as an inline function in a C-compatible manner.
+    4244             : */
+    4245             : 
+    4246             : #define __PLUMED_IMPLEMENT_FORTRAN(lower,upper,arg1,arg2) \
+    4247             :   static void lower ## _static arg1; \
+    4248             :   extern void lower      arg1 {lower ## _static arg2;} \
+    4249             :   extern void lower ##_  arg1 {lower ## _static arg2;} \
+    4250             :   extern void lower ##__ arg1 {lower ## _static arg2;} \
+    4251             :   extern void upper      arg1 {lower ## _static arg2;} \
+    4252             :   extern void upper ##_  arg1 {lower ## _static arg2;} \
+    4253             :   extern void upper ##__ arg1 {lower ## _static arg2;} \
+    4254             :   static void lower ## _static arg1
+    4255             : 
+    4256             : /* FORTRAN wrappers would only make sense as extern "C" */
+    4257             : 
+    4258             : __PLUMED_WRAPPER_EXTERN_C_BEGIN
+    4259             : 
+    4260          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create,PLUMED_F_CREATE,(char*c),(c)) {
+    4261          18 :   plumed_c2f(plumed_create(),c);
+    4262          18 : }
+    4263             : 
+    4264          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_dlopen,PLUMED_F_CREATE_DLOPEN,(char*path,char*c),(path,c)) {
+    4265           6 :   plumed_c2f(plumed_create_dlopen(path),c);
+    4266           6 : }
+    4267             : 
+    4268          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_reference,PLUMED_F_CREATE_REFERENCE,(char* r,char*c),(r,c)) {
+    4269           6 :   plumed_c2f(plumed_create_reference_f(r),c);
+    4270           6 : }
+    4271             : 
+    4272           0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_create_invalid,PLUMED_F_CREATE_INVALID,(char* c),(c)) {
+    4273           0 :   plumed_c2f(plumed_create_invalid(),c);
+    4274           0 : }
+    4275             : 
+    4276         558 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_cmd,PLUMED_F_CMD,(char*c,char*key,void*val),(c,key,val)) {
+    4277         279 :   plumed_cmd(plumed_f2c(c),key,val);
+    4278         279 : }
+    4279             : 
+    4280          60 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_finalize,PLUMED_F_FINALIZE,(char*c),(c)) {
+    4281          30 :   plumed_finalize(plumed_f2c(c));
+    4282          30 : }
+    4283             : 
+    4284          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_installed,PLUMED_F_INSTALLED,(int*i),(i)) {
+    4285             :   assert(i);
+    4286           6 :   *i=plumed_installed();
+    4287           6 : }
+    4288             : 
+    4289             : /* New in PLUMED 2.5 */
+    4290           0 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_valid,PLUMED_F_VALID,(char*c,int*i),(c,i)) {
+    4291             :   assert(i);
+    4292           0 :   *i=plumed_valid(plumed_f2c(c));
+    4293           0 : }
+    4294             : 
+    4295          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_use_count,PLUMED_F_USE_COUNT,(char*c,int*i),(c,i)) {
+    4296             :   assert(i);
+    4297          18 :   *i=plumed_use_count(plumed_f2c(c));
+    4298          18 : }
+    4299             : 
+    4300             : /* New in PLUMED 2.8 */
+    4301             : 
+    4302             : /* note: flags & (~0x1ffffff) removes bits that are set here (code and size) */
+    4303             : 
+    4304             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,suffix) \
+    4305             : plumed_safeptr plumed_f_safeptr_ ## type_ ## suffix(void*val,__PLUMED_WRAPPER_STD size_t nelem,__PLUMED_WRAPPER_STD size_t*shape,__PLUMED_WRAPPER_STD size_t flags,void*opt) {\
+    4306             :   plumed_safeptr safe; \
+    4307             :   safe.ptr=val; \
+    4308             :   safe.nelem=nelem; \
+    4309             :   safe.shape=shape; \
+    4310             :   safe.flags= (flags & (~0x1ffffffu)) + 0x10000*code + size; \
+    4311             :   safe.opt=opt; \
+    4312             :   return safe; \
+    4313             : }
+    4314             : 
+    4315             : #define __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,size,code) \
+    4316             :   __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,) \
+    4317             :   __PLUMED_IMPLEMENT_F_SAFEPTR_INNER(type,type_,size,code,_scalar)
+    4318             : 
+    4319             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(type,type_,code) \
+    4320             :         __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,0,code)
+    4321             : 
+    4322             : #define __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(type,type_,code) \
+    4323             :         __PLUMED_IMPLEMENT_F_SAFEPTR(type,type_,sizeof(type),code)
+    4324             : 
+    4325          24 : __PLUMED_IMPLEMENT_F_SAFEPTR_EMPTY(void,ptr,0)
+    4326           1 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(float,float,4)
+    4327          19 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(double,double,4)
+    4328           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long double,long_double,4)
+    4329          19 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(int,int,3)
+    4330           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(short,short,3)
+    4331           0 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(long,long,3)
+    4332          20 : __PLUMED_IMPLEMENT_F_SAFEPTR_SIZED(char,char,3)
+    4333             : 
+    4334             : #if __PLUMED_WRAPPER_GLOBAL /*{*/
+    4335             : 
+    4336          48 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_global,PLUMED_F_GLOBAL,(char*c),(c)) {
+    4337          24 :   plumed_c2f(plumed_gmain,c);
+    4338          24 : }
+    4339             : 
+    4340          36 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_ginitialized,PLUMED_F_GINITIALIZED,(int*i),(i)) {
+    4341             :   assert(i);
+    4342          18 :   *i=plumed_ginitialized();
+    4343          18 : }
+    4344             : 
+    4345          28 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcreate,PLUMED_F_GCREATE,(void),()) {
+    4346          14 :   plumed_gcreate();
+    4347          14 : }
+    4348             : 
+    4349         156 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gcmd,PLUMED_F_GCMD,(char*key,void*val),(key,val)) {
+    4350          78 :   plumed_gcmd(key,val);
+    4351          78 : }
+    4352             : 
+    4353          28 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gfinalize,PLUMED_F_GFINALIZE,(void),()) {
+    4354          14 :   plumed_gfinalize();
+    4355          14 : }
+    4356             : 
+    4357             : /* New in PLUMED 2.5 */
+    4358          12 : __PLUMED_IMPLEMENT_FORTRAN(plumed_f_gvalid,PLUMED_F_GVALID,(int*i),(i)) {
+    4359             :   assert(i);
+    4360           6 :   *i=plumed_gvalid();
+    4361           6 : }
+    4362             : 
+    4363             : #endif /*}*/
+    4364             : 
+    4365             : __PLUMED_WRAPPER_EXTERN_C_END
+    4366             : 
+    4367             : #endif /*}*/
+    4368             : 
+    4369             : #endif /*}*/
+    4370             : 
+    4371             : #endif /*}*/
+    4372             : 
+    4373             : /* END OF DEFINITIONS */
+    4374             : 
+    4375             : /* reset variable to allow it to be redefined upon re-inclusion */
+    4376             : 
+    4377             : #undef __PLUMED_WRAPPER_IMPLEMENTATION_
+    4378             : 
+    4379             : /* this macro is set in declarations */
+    4380             : #ifdef __PLUMED_WRAPPER_REDEFINE_CMD
+    4381             : #if defined(plumed_cmd)
+    4382             : #undef plumed_cmd
+    4383             : #endif
+    4384             : #define plumed_cmd __PLUMED_WRAPPER_REDEFINE_CMD
+    4385             : #endif
+    4386             : 
+    4387             : /* this macro is set in declarations */
+    4388             : #ifdef __PLUMED_WRAPPER_REDEFINE_GCMD
+    4389             : #if defined(plumed_gcmd)
+    4390             : #undef plumed_gcmd
+    4391             : #endif
+    4392             : #define plumed_gcmd __PLUMED_WRAPPER_REDEFINE_GCMD
+    4393             : #endif
+    4394             : 
+    4395             : /* this macro is set in declarations */
+    4396             : #ifdef __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW
+    4397             : #if defined(plumed_error_rethrow)
+    4398             : #undef plumed_error_rethrow
+    4399             : #endif
+    4400             : #define plumed_error_rethrow __PLUMED_WRAPPER_REDEFINE_ERROR_RETHROW
+    4401             : #endif
+
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/index-sort-f.html b/coverage/wrapper/index-sort-f.html new file mode 100644 index 000000000000..217b49950f3b --- /dev/null +++ b/coverage/wrapper/index-sort-f.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-02-22 21:58:45Functions:14425456.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/index-sort-l.html b/coverage/wrapper/index-sort-l.html new file mode 100644 index 000000000000..843a0ffc4fc9 --- /dev/null +++ b/coverage/wrapper/index-sort-l.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-02-22 21:58:45Functions:14425456.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/coverage/wrapper/index.html b/coverage/wrapper/index.html new file mode 100644 index 000000000000..d82d57e06919 --- /dev/null +++ b/coverage/wrapper/index.html @@ -0,0 +1,94 @@ + + + + + + + + LCOV - plumed test coverage - wrapper + + + + + + + + + + + + + + +
LCOV - code coverage report
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
Current view:top level - wrapperHitTotalCoverage
Test:plumed test coverageLines:25050050.0 %
Date:2024-02-22 21:58:45Functions:14425456.7 %
+
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + +

Filename Sort by nameLine Coverage Sort by line coverageFunctions Sort by function coverage
Plumed.h +
50.0%50.0%
+
50.0 %250 / 50056.7 %144 / 254
+
+
+ + + + +
Generated by: LCOV version 1.16
+
+ + + diff --git a/index.html b/index.html new file mode 100644 index 000000000000..cc4afdd80de5 --- /dev/null +++ b/index.html @@ -0,0 +1,14 @@ + + + + Coverage scan +

Coverage scan

+Here you can find coverage scan reports for PLUMED: + +The first one is equivalent to the one you will find on CodeCov (if enabled). +The second one only contains third-party libraries included in PLUMED. + +